[
  {
    "path": ".gitignore",
    "content": "# gdc specific    #\n###################\ndev/\ngcc/d/patches/series\n\n# libphobos specific #\n######################\nlibphobos/autom4te.cache/\nlibphobos/config.guess\nlibphobos/config.sub\nlibphobos/install-sh\nlibphobos/missing\n\n# from .hgignore  #\n###################\n.cproject\n.project\n.classpath\nDebug\n\n# OS generated files #\n######################\n.DS_Store*\nehthumbs.db\nIcon?\nThumbs.db\n"
  },
  {
    "path": "CHANGELOG-old.md",
    "content": "D Front End for GCC - Release 0.30\n\nLast update: Saturday, 23 June, 2012\n\nAuthors:\n---------------------\nThe GNU D Compiler (GDC) project was originally started by David Friedman in\n2004 until early 2007 when he disappeared from the D scene, and was no longer\nable to maintain GDC.  Following a revival attempt in 2008, GDC is now under\nthe lead of Iain Buclaw who has been steering the project since 2009 with the\nassistance of its contributors, without them the project would not have been\nnearly as successful as it has been.\n\n\nContributors:\n---------------------\nDavid Friedman for starting the GDC project.\nVincenzo Ampolo for his reviving development efforts.\nMichael Parrott for adding initial support for the D2 frontend.\nIain Buclaw for completing the port of GDC to GCC 4.2.x and later.\nAnders F Bjorklund for assistance in porting to OSX.\nDaniel Green for porting GDC to MinGW platform.\nJohannes Pfau for assistance in porting to Android and ARM.\nalexrp for standardising the platform identifiers in D.\n\n\nHistory:\n---------------------\nRelease Notes\n\n0.30:\n\n  * Support for GCC, 4.5.x and 4.6.x added\n  * Removed support for GCC 3.4.x, 4.0.x, 4.1.x\n  * Updated D1 to 1.069\n  * Updated D2 to 2.054\n  * Better D2 support for MinGW\n  * Added 'optlink' calling convention for D\n  * Added 64bit support for IASM (Work in Progress)\n  * Moved correct implementation of delegates from GCC backend to GDC frontend glue code\n  * Fixed Bugzilla 670, 4494, 4543, 5086, 5090, 5148, 5182, 5191, 5439, 5735, 5812\n  * Many other Bitbucket issues.\n\n0.25:\n\n  * Support for GCC, 4.2.x, 4.3.x, and 4.4.x added\n  * Updated D1 to 1.063\n  * Updated D2 to 2.020\n  * Added druntime support\n  * Fixed Bugzilla 1041, 1044, 1136, 1145, 1296, 1669, 1689,\n    1751, 1813, 1822, 1921, 1930, 2079, 2102, 2291, 2421\n  * Fixed Bitbucket issues too numerous to mention. :-)\n\n0.24:\n\n  * Removed support for GCC 3.3.x\n  * Updated to DMD 1.020\n  * Fixed Bugzilla 1037, 1038 (gdc specific), 1043, 1045, 1046,\n    1031, 1032, 1034, 1065, 1109, 1191, 1137, 1152, 1208, 1325,\n    1329, 1898, 1400\n  * Fixed SourceForge issues 1689634, 1749622, 1721496, 1721435\n\n0.23:\n\n  * Added support for 64-bit targets\n  * Added multilib support\n  * Updated to DMD 1.007\n  * Fixed Bugzilla 984, 1013\n\n0.22:\n\n  * Added support for GCC 4.1.x\n  * Support for GCC 3.3.x is deprecated\n  * Updated to DMD 1.004\n  * Fixed Bugzilla 836, 837, 838, 839, 841, 843, 844, 889, 896\n  * Fixed problems with missing debug information\n  * Added Rick Mann's -framework patch for gdmd\n\n0.21:\n\n  * Updated to DMD 1.00\n  * Fixed Bugzilla 695, 696, 737, 738, 739, 742, 743, 745\n  * Implemented GCC extended assembler\n  * Implemented basic support for GCC attributes\n\n0.20:\n\n  * Updated to DMD 0.177\n  * Fixes for synchronized code generation\n  * Better support for cross-hosted builds\n  * Fixed Bugzilla 307, 375, 403, 575, 578\n  * Applied Anders Bjorklund's MacOS X build patches\n\n0.19:\n\n  * Fixed D Bugzilla bugs 141(gdc), 157, 162, 164, 171, 174, 175, 192, 229\n  * Applied Dave Fladebo's suggestion for -O3 in gdmd\n  * Updated to DMD 0.162\n  * The version symbol for FreeBSD is now \"freebsd\"\n  * Enabled std.loader for FreeBSD\n  * Implement offsetof in assembler\n  * Support building with Apple's GCC (4.0 only)\n  * Fix parallel builds\n\n0.18:\n\n  *  Fixes\n    o ICE on assignment arithmetic\n    o Problems mixing D and assembler floating point operations\n    o Mac OS X 10.2 build problems\n    o The gdc driver no longer compiles C source as C++\n    o Many others...\n  * Improvements\n    o Updated to DMD 0.157\n    o Support for PowerPC Linux\n    o Partial support for SkyOS\n    o Compiler can be relocated to another directory.\n\n0.17:\n\n  *  Fixes\n    o Mixed complex/float operations on GCC 4.0 (D.gnu/1485)\n    o Applied Thomas Kuhne's HTML line number fix\n    o Foreach/nested functions in templates (D.gnu/1514)\n    o Use correct default initializer when allocating arrays of typedef'd types\n    o Recursive calls to nested functions (D.gnu/1525)\n  * Improvements\n    o Updated to DMD 0.140\n\n0.16:\n\n  * Fixes\n    o Concatenating a array and single element\n    o \"__arrayArg already defined\"\n    o ICE on nested foreach statements (D.gnu/1393)\n    o Inline assembler\n      * Functions returning floating point types\n      * Spurious error on scaled register without a base register\n      * Access to locals by var+ofs[EBP] now works with optimization.\n      * Can now guess operand size from referenced variables.\n    o Thunks errors with reimplemented interfaces (e.g., Mango)\n  * Improvements\n    o Support GCC 4.0.x\n    o Updated to DMD 0.132\n    o Support DW_LANG_D for DWARF debugging\n    o Support compiling multiple sources to a single object with GCC 3.4.x\n\n0.15:\n\n  * Updated to DMD 0.128\n\n0.14:\n\n  * Fixes\n    o Classes nested in functions actually work now.\n    o Fix for newest versions of the GNU assembler.\n  * Improvements\n    o Updated to DMD 0.127\n\n0.13:\n\n  * Fixes\n    o Cygwin/MinGW assembler problem\n  * Improvements\n    o Updated to DMD 0.126.\n    o Calling nested functions with delegates is faster.\n    o The \"check-target-libphobos\" builds a separate library to\n      enable runtime checks and unit tests.\n\n0.12.1:\n\n  *  Fixes\n    o Compilation errors and crashes with -fpic\n    o Crashes with interfaces on Cygwin/MinGW\n    o Support the -mno-cygwin option\n\n0.12:\n\n  * Fixes\n    o Various problems building MinGW in MSYS\n    o Mango \"endless output\"\n    o Build problems with gcc 3.4.1\n    o Various problems revealed by dmdscript\n    o Error message now go to standard error\n    o DStress catch_01, catch_02, new_04, switch_19, throw_02, and others.\n  * Improvements\n    o Updated to DMD 0.125\n    o New target: AIX\n    o GDC and DMD versions are reported with \"gcc --version\"\n    o Take advantage of DMD template improvements on\n  * Changes\n    o std.c.unix is now std.c.unix.unix\n    o The runtime library is now \"libgphobos\" to avoid conflicts with DMD.\n    o The dmd wrapper script...\n      + Is now named \"gdmd\".\n      + Looks for gdc in its own directory instead of searching the path\n      + Requires a comma after the \"-q\" option.\n\n0.11:\n\n  * Fixes\n    o Reversed structure compare\n    o Correct meaning of '-L' option in wrapper script\n    o Static data GC bug on Linux\n  * Improvements\n    o Updated to DMD 0.121\n    o New target: MingGW\n    o Included Anders F Bjorklund's man pages.\n    o It is now possible to build a cross-compiler.  Only MingGW\n      is supported out-of-the-box, however.\n\n0.11pre1:\n\n  * Fixes\n    o Incorrect/missing thunks\n    o Problems when the C char type is unsigned\n    o Side effects in void type return expressions\n    o Calling a particular static ancestor method.\n    o Install of /etc/c/zlib.d\n    o Support for built-in function security patch.\n    o More...\n  * Improvements\n    o Updated to DMD 0.113\n    o Phobos is now built as target library (i.e., no need for a\n      separate build step)\n    o Boehm-gc is no longer used and the Java package is no\n      longer required.\n    o Inline assembler for x86 (there are some limitations --\n      these need to be documented)\n    o Included Anders Bjorklund's patches to enable the use of\n      frameworks on Darwin.\n    o On Darwin, D object code can be linked with the system\n      gcc.  Likewise, gdc can link C++ object code built by the\n      system g++.\n    o Improved support for alternate C main functions (see\n      d/phobos/internal/{cmain.d,rundmain.d})\n  * Notes\n    o The gdc driver no longer accepts D source files without\n      the \".d\" extension.  The dmd wrapper script still supports\n      this.\n\n0.10:\n\n  * Fixes\n    o Complex number comparisons with NAN operands\n    o Cleaned up Phobos installation.\n    o Non-virtual method calls\n    o Code generation with -mpowerpc64\n    o Break in labeled switch statement\n  * Improvements\n    o Updated to DMD 0.110\n    o Applied Thomas Kohne's and Anders Bjorklund's HTML patches.\n    o Added Thomas Kohne's \"dump source\" code\n    o Phobos Makefile now supports the DESTDIR variable\n\n0.9:\n\n  * Fixes\n    o Detect use of non-static methods in a static context\n    o Enumerated types are signed by default\n    o Anders Bjorklund's patch for HTML infinite looping\n    o va_start is now a template.\n    o Delegate expressions for struct methods now work\n    o bswap uses unsigned right shift\n    o Fixed several problems with the dmd script\n    o Fixed crash when compiling with debug information\n    o Handle referenes to instance variables without \"this\"\n    o Fixed ICE for interfaces with multiple inheritence\n    o Fix id.h dependcy so concurrent make will work\n  * Improvements\n    o Updated to DMD 0.109\n  *  Notes\n    o The (undocumented) BitsPer{Pointer,Word} version\n      identifiers are now prefixed with \"GNU_\"\n    o Private declarations are now exported from object files\n\n0.8:\n\n  *  Fixes\n    o std.loader module is now enabled\n    o Proper casting from complex and imaginary types\n    o Diagnostics are now GCC-style\n    o Exceptions don't leak memory anymore\n    o The gdc command processes \".html\" as D source files.\n    o ICE for classes declared in a function\n    o ICE on empty \"if\" statement\n    o Test for existence of \"execvpe\", \"fwide\", and \"fputwc\" before\n      using them\n    o Corrected floating point \"min_10_exp\" properties\n    o std.date.getLocalTZA returns a correct values\n    o Using gdc to link with C++ should now just need \"-lstdc++\"\n  * Improvements\n    o Debugging information is vastly improved\n    o DLLs can be built on Cygwin\n  * Notes\n    o \"DigitalMars\" is not longer defined as a version symbol\n\n\nSupported Systems:\n---------------------\n  * GCC 4.8.x\n  * Linux (tested on Debian and Ubuntu x86, x86_64)\n  * Mac OS X 10.3.9 and 10.4.x\n  * FreeBSD 6.x, 7.x\n  * Cygwin\n  * MinGW\n  * AIX (tested on 5.1)\n\nSimilar versions of the above systems should work and other Unix\nplatforms may work.  Although the compiler will probably work on most\narchitectures, the D runtime library will still need to be\nupdated to support them.\n\n\nRequirements\n---------------------\n  * The base developer package for your system.  Generally, this\n    means binutils and a C runtime library.\n  * The gdmd wrapper script requires Perl.\n\n\nLinks\n---------------------\n  * This Project -- https://github.com/D-Programming-GDC/GDC/\n  * Previous home -- http://dgcc.sourceforge.net/\n  * The D Programming Language -- http://www.digitalmars.com/d/\n  * D Links Page -- http://digitalmars.com/d/dlinks.html\n  * The D.gnu newsgroup -- news://news.digitalmars.com/D.gnu\n  * For general D discussion, the digitalmars.D and\n    digitalmars.D.bugs newsgroups\n  * The GNU Compiler Collection -- http://gcc.gnu.org/\n  * Mac OS X binary distribution -- http://gdcmac.sourceforge.net/\n\n\nContact\n---------------------\nIain Buclaw\ne-mail: ibuclaw@gdcproject.org\n\n\nStatus\n---------------------\n\nKnown Issues\n\n  * See the DStress (http://svn.kuehne.cn/dstress/www/dstress.html)\n    page for known failing cases.\n  * Debugging information may have a few problems if you are using\n    a version of gdb that is not 7.2 or later.  To enable D name\n    mangling in gdb, apply this patch.\n    (http://dsource.org/projects/gdb-patches/)\n  * Some targets do not support once-only linking which is needed\n    for templates to work smoothly. A workaround is to manually\n    control template emission.  See the -femit-templates option\n    below.  For Darwin, Apple's GCC 3.x compiler supports one-only\n    linking, but GDC does not build with those sources.  There are\n    no problems with the stock GCC 4.x on Darwin.\n  * Complex floating point operations may not work the same as DMD.\n  * Some math functions behave differently due to different\n    implementations of the extended floating-point type.\n  * Volatile statements may not always do the right thing.\n  * Because of a problem on AIX, the linker will pull in more\n    modules than needed.\n    See: http://groups-beta.google.com/groups?hl=en&q=%22large+executables+on+AIX%22&qt_s=Search\n  * Some C libraries (Cygwin, MinGW, AIX) don't handle\n    floating-point formatting and parsing in a standard way.\n\nKnown Differences from DMD\n\n  * The type of _argptr in variadic functions is the target-specific\n    va_list type.  The only portable way to use _argptr is the\n    std.stdarg.va_arg template.  In particular, you cannot construct\n    a va_list from a pointer to data and expect it to work.\n  * The D Inline assembler is not supported by GDC.\n  * Similarly, naked functions are not supported by GDC either.\n  * Currently, GDC uses the C calling convention for all functions\n    except those declared extern (Windows).\n  * GDC allows catch statements in finally blocks.\n  * pragma(lib) is not supported.\n  * Some targets do not have a distinct extended floating-point\n    type.  On these targets, real and double are the same size.\n  * On Win32 targets, GDC allocates 12 bytes for the real type, while\n    DMD allocates 10 bytes. This also applies to the components of\n    the creal type.\n\n\nLicense\n---------------------\n  This program is free software; you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation; either version 3, or (at your option)\n  any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with GCC; see the file COPYING3.  If not see\n  <http://www.gnu.org/licenses/>.\n\n"
  },
  {
    "path": "README-MINGW.md",
    "content": "GDC should build for MINGW and MINGW64 targets, however not much\ntesting has been done.\n\n## Building ##\n\nThe following patches are required for binutils / gcc to fix TLS support:\n * https://github.com/venix1/MinGW-GDC/blob/master/patches/mingw-tls-binutils-2.23.1.patch\n * https://github.com/venix1/MinGW-GDC/blob/master/patches/mingw-tls-gcc-4.8.patch\n\nThis patch is required to fix a bug in GCC buildscripts:\n * https://github.com/venix1/MinGW-GDC/blob/master/patches/gcc/0001-Remove-fPIC-for-MinGW.patch\n\n## SEH ##\nSEH should work for 64 bit windows targets.\n"
  },
  {
    "path": "README.md",
    "content": "[![Build Status](https://semaphoreci.com/api/v1/d-programming-gdc/gdc/branches/master/badge.svg)](https://semaphoreci.com/d-programming-gdc/gdc)\n\n### What is GDC?\n\nGDC is a GPL implementation of the D compiler which integrates the open source D front end with GCC.\n\nThe GNU D Compiler (GDC) project was originally started by David Friedman in 2004 until early 2007 when he disappeared from the D scene, and was no longer able to maintain GDC. Following a revival attempt in 2008, GDC is now under the lead of Iain Buclaw who has been steering the project since 2009 with the assistance of its contributors, without them the project would not have been nearly as successful as it has been.\n\nDocumentation on GDC is available from [the wiki][wiki]. Any bugs or issues found with using GDC should be reported at [our bugzilla site][bugs]. For help with GDC, the [D.gnu][maillist] mailing list is the place to go with questions or problems.\n\nWork is currently under way to merge GDC into a future release of GCC. Assistance of any sort during this time would be invaluably appreciated. Feel free to contact via [email][email] or join in at #d.gdc on FreeNode.\n\n### Building\n\nThe master branch of this project closely follows [GCC development branch][gcc-devel], which if you intend to use GDC for production applications, is likely not the version of GCC you want to build against.  For versions of GDC compatible with GCC releases, checkout one of the following branches:\n\n* [GCC 5.x](https://github.com/D-Programming-GDC/GDC/tree/gdc-5)\n* [GCC 6.x](https://github.com/D-Programming-GDC/GDC/tree/gdc-6)\n* [GCC 7.x](https://github.com/D-Programming-GDC/GDC/tree/gdc-7)\n* [GCC 8.x](https://github.com/D-Programming-GDC/GDC/tree/gdc-8)\n\n[home]: http://gdcproject.org\n[wiki]: http://wiki.dlang.org/GDC\n[bugs]: http://bugzilla.gdcproject.org\n[maillist]: http://forum.dlang.org/group/D.gnu\n[email]: mailto:ibuclaw@gdcproject.org\n[gcc-devel]: http://gcc.gnu.org/git/?p=gcc.git;a=shortlog\n"
  },
  {
    "path": "gcc/d/ChangeLog",
    "content": "2018-10-26  Eugene Wissner  <belka@caraus.de>\n\n\t* Make-lang.in (selftest-d): New.\n\t* d-diagnostic.cc (vwarning): Fix warning emitting.\n\n2018-10-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-spec.cc (lang_specific_driver): Always link against phobos if any\n\tinput file is given.\n\n2018-10-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_get_alias_set): Always return zero.\n\n2018-10-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* intrinsics.cc (maybe_set_intrinsic): Don't set built-in flag on\n\tunsupported pow() overloads.\n\n2018-10-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::binop_assignment): Call stabilize_reference on\n\tLHS construct if it has side effects.\n\n2018-10-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* intrinsics.cc (clear_intrinsic_flag): Remove function.\n\t(maybe_expand_intrinsic): Remove clear_intrinsic_flag call.\n\n2018-10-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* intrinsics.cc (expand_intrinsic_copysign): Use mathfn_built_in to\n\tdetermine correct built-in to call.\n\t(expand_intrinsic_pow): Likewise.\n\n2018-10-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* intrinsics.cc (expand_intrinsic_sqrt): Remove implicit int to double\n\tconversion.\n\t(expand_intrinsic_pow): Likewise.\n\n2018-10-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (get_frame_for_symbol): Use error_at.\n\t(build_frame_type): Likewise.\n\t(get_framedecl): Likewise.\n\t* d-frontend.cc (getTypeInfoType): Likewise.\n\t* d-lang.cc (d_parse_file): Likewise.\n\t* decl.cc (apply_pragma_crt): Likewise.\n\t(DeclVisitor::visit(PragmaDeclaration)): Likewise.\n\t(DeclVisitor::visit(StructDeclaration)): Likewise.\n\t(DeclVisitor::visit(StructDeclaration)): Likewise.\n\t(DeclVisitor::finish_vtable): Likewise.\n\t(DeclVisitor::visit(ClassDeclaration)): Likewise.\n\t(DeclVisitor::visit(InterfaceDeclaration)): Likewise.\n\t(DeclVisitor::visit(EnumDeclaration)): Likewise.\n\t(DeclVisitor::visit(VarDeclaration)): Likewise.\n\t* toir.cc (IRVisitor::check_goto): Likewise.\n\t(IRVisitor::check_previous_goto): Likewise.\n\t(IRVisitor::visit(ThrowStatement)): Likewise.\n\t* typeinfo.cc (build_typeinfo): Likewise.\n\n2018-10-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (get_array_length): Use quoted format flag in message.\n\t(d_build_call): Likewise.\n\t* d-lang.cc (d_handle_option): Likewise.\n\t* decl.cc (apply_pragma_crt): Likewise.\n\t(DeclVisitor::finish_vtable): Likewise.\n\t* expr.cc (ExprVisitor::visit(CmpExp)): Likewise.\n\t(ExprVisitor::visit(ArrayLengthExp)): Likewise.\n\t(ExprVisitor::visit(DeleteExp)): Likewise.\n\t(ExprVisitor::visit(RemoveExp)): Likewise.\n\t(ExprVisitor::visit(RemoveExp)): Likewise.\n\t(ExprVisitor::visit(CallExp)): Likewise.\n\t(ExprVisitor::visit(DotVarExp)): Likewise.\n\t(ExprVisitor::visit(VarExp)): Likewise.\n\t(ExprVisitor::visit(ScopeExp)): Likewise.\n\t(ExprVisitor::visit(TypeExp)): Likewise.\n\t(build_expr): Likewise.\n\t* typeinfo.cc (build_typeinfo): Likewise.\n\n2018-10-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-diagnostic.cc (d_diagnostic_report_diagnostic): Skip translation\n\tby instead calling diagnostic_set_info_translated.\n\n2018-10-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-tree.h (bool_type_node): Rename to d_bool_type.\n\t(byte_type_node): Rename to d_byte_type.\n\t(ubyte_type_node): Rename to d_ubyte_type.\n\t(short_type_node): Rename to d_short_type.\n\t(ushort_type_node): Rename to d_ushort_type.\n\t(int_type_node): Rename to d_int_type.\n\t(uint_type_node): Rename to d_uint_type.\n\t(long_type_node): Rename to d_long_type.\n\t(ulong_type_node): Rename to d_ulong_type.\n\t(cent_type_node): Rename to d_cent_type.\n\t(ucent_type_node): Rename to d_ucent_type.\n\n2018-10-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(PowExp)): Remove function.\n\n2018-10-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-attribs.c: Rename to d-attribs.cc.\n\t* d-spec.c: Rename to d-spec.cc.\n\n2018-10-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_gimplify_expr): Don't handle TREE_THIS_VOLATILE.\n\n2018-10-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-diagnostic.cc (vwarning): Update to use Diagnostic enum.\n\t(vdeprecation): Likewise.\n\t(vdeprecationSupplemental): Likewise.\n\t* d-lang.cc (d_init_options): Explicitly set warnings and deprecations\n\tas DIAGNOSTICoff.\n\t(d_handle_option): Update to use Diagnostic enum.\n\t(d_post_options): Likewise.\n\n2018-10-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-diagnostic.cc (expand_format): Rename to expand_d_format.\n\tUpdated all callers.\n\n2018-10-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (get_linemap): Rename function to make_location_t.\n\tUpdated all callers.\n\t* d-tree.h (get_linemap): Rename declaration to make_location_t.\n\n2018-10-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::binary_op): Use POINTER_DIFF_EXPR.\n\n2018-10-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* intrinsics.cc (expand_intrinsic_bsf): Assert that built-in function\n\tcode is not END_BUILTINS.\n\t(expand_intrinsic_bsr): Likewise.\n\t(expand_intrinsic_bswap): Likewise.\n\t(expand_intrinsic_popcnt): Likewise.\n\n2018-10-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* config-lang.in (gtfiles): Add modules.cc.\n\t* modules.cc: Include gt-d-modules.h.\n\t(module_info): Mark with GTY.\n\t(static_ctor_list): Likewise.\n\t(static_dtor_list): Likewise.\n\n2018-10-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-spec.c (lang_specific_driver): Use strrchr and strcmp to check\n\tinput file suffix.\n\n2018-10-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-spec.c (phobos_action): New enum.\n\t(library): Rename to phobos_library.\n\t(lang_specific_driver): Update to use phobos_library.\n\t(lang_specific_pre_link): Likewise.\n\n2018-10-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-frontend.cc (Port::writelongLE): Remove function.\n\t(Port::writelongBE): Remove function.\n\n2018-10-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-convert.cc (convert): Remove goto maybe_fold.\n\n2018-10-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (warn_for_null_address): New function.\n\t(build_boolop): Warn about comparing address of decl to null.\n\t* d-convert.cc (decl_with_nonnull_addr_p): New function.\n\t(d_truthvalue_conversion): Warn about evaluating address as boolean.\n\t* d-tree.h (decl_with_nonnull_addr_p): Add declaration.\n\t* lang.opt (Waddress): New option.\n\n2018-10-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_array_length): Assert that argument type is a\n\tdynamic array.\n\t(d_array_ptr): Likewise.\n\t(d_array_value): Likewise.\n\t(delegate_method): Assert that argument type is a delegate.\n\t(delegate_object): Likewise.\n\n2018-10-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-attribs.c (handle_malloc_attribute): Use gcc_assert instead of\n\tgcc_unreachable.\n\t(handle_pure_attribute): Likewise.\n\t(handle_nothrow_attribute): Likewise.\n\n2018-10-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in: Rename compiler proper to d21.\n\t* config-lang.in (compilers): Rename compiler to d21.\n\t* d-spec.c (lang_specific_driver): Update comments.\n\t* lang-specs.h: Rename compiler to d21.\n\n2018-10-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* lang.opt: Add missing periods to the ends of sentences.\n\n2018-10-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Remove handling of -fdeps.\n\t(d_parse_file): Don't generate module dependencies.\n\t* lang.opt (fdeps, fdeps=): Remove options.\n\t(fintfc, fintfc-dir=, fintfc-file=): Remove options.\n\t(ftransition=safe): Remove option.\n\n2018-10-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_init_ts): Remove handling of IASM_EXPR.\n\t(d_gimplify_expr): Likewise.\n\t* d-tree.def (IASM_EXPR): Remove tree code.\n\n2018-10-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-attrib.c (attr_noreturn_exclusions): Attribute not mutually\n\texclusive with self.\n\t* typeinfo.cc (TypeInfoVisitor::layout_interfaces): Assert that\n\tbase class vtable is found in interface.\n\n2018-10-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-target.cc (Target::getTargetInfo): Handle floatAbi, objectFormat,\n\tand cppRuntimeLibrary traits.\n\t* d-target.def (d_float_abi_type): New hook.\n\t(d_object_format): New hook.\n\n2018-10-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (d-warn): Use strict warnings.\n\t* d-frontend.cc (Compiler::onImport): New function.\n\t* decl.cc (DeclVisitor): Add using Visitor::visit.\n\t* expr.cc (ExprVisitor): Likewise.\n\t* imports.cc (ImportVisitor): Likewise.\n\t* toir.cc (IRVisitor): Likewise.\n\t* typeinfo.cc (TypeInfoVisitor): Likewise.\n\t(TypeInfoDeclVisitor): Likewise.\n\t(SpeculativeTypeVisitor): Likewise.\n\t* types.cc (TypeVisitor): Likewise.\n\t* verstr.h: Update to 2.082.1-beta.1\n\n2018-10-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-frontend.cc: Include compiler.h, errors.h, expression.h.\n\t(genCmain): Rename function to Compiler::genCmain.\n\t(Compiler::paintAsType): New function.\n\t(Compiler::loadModule): New function.\n\t(getTypeInfoType): Call error function directly.\n\t* d-lang.cc (deps_write): Use hash_set for dependency tracking.\n\t(d_init_options): Handle -ftransition=dtorfields option.\n\t(d_parse_file): Call Compiler::loadModule.\n\t* d-target.cc: Remove include identifier.h, module.h.\n\t(Target::paintAsType): Remove function.\n\t(Target::loadModule): Remove function.\n\t(Target::getTargetInfo): New function.\n\t* lang.opt (ftransition=dtorfields): New option.\n\t* typeinfo.cc (build_typeinfo): Call error function directly.\n\n2018-10-01  Eugene Wissner  <belka@caraus.de>\n\n\t* decl.cc (finish_thunk): Adjust call to cgraph_node::create_thunk.\n\n2018-09-25  Eugene Wissner  <belka@caraus.de>\n\n\t* d-codegen.cc (d_assert_call): Don't make STRING_CSTs larger than they\n\tare.\n\t* expr.cc (ExprVisitor::visit(StringExp)): Likewise.\n\t* typeinfo.cc (TypeInfoVisitor::layout_string): Likewise.\n\n2018-09-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc: Include expression.h, identifier.h.\n\t* d-codegen.cc: Include identifier.h.\n\t* d-convert.cc: Include declaration.h.\n\t* d-frontend.cc: Include identifier.h.\n\t* d-lang.cc: Include declaration.h, expression.h, identifier.h.\n\t(d_parse_file): Call moduleToBuffer to get string dump of contents.\n\t* d-target.cc: Include declaration.h, expression.h, identifier.h.\n\t* expr.cc: Include identifier.h.\n\t* imports.cc: Include identifier.h.\n\t* intrinsics.cc: Include identifier.h.\n\t* modules.cc: Include identifier.h.\n\t* toir.cc: Include expression.h, identifier.h.\n\t* typeinfo.cc: Include expression.h, identifier.h.\n\t* types.cc: Include expression.h, identifier.h.\n\n2018-09-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (deps_write): Use toChars accessor to get module path.\n\t* decl.cc (get_symbol_decl): Use get_identifier_with_length to get\n\tmangle override identifier node.\n\n2018-09-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_init_options): Set-up global.params.argv0 as D array.\n\t(d_parse_file): Use global.params.argv0 pointer field as format value.\n\t* intrinsics.cc (maybe_expand_intrinsic): Handle INTRINSIC_EXP.\n\t* intrinsics.def (EXP): Add CTFE intrinsic.\n\n2018-09-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc: Include errors.h, mars.h.\n\t* decl.cc: Include errors.h.\n\t* typeinfo.cc: Include globals.h, errors.h.\n\t* verstr.h: Update to 2.082.0\n\n2018-09-05  Eugene Wissner  <belka@caraus.de>\n\n\t* d-frontend.cc (eval_builtin): Replace DECL_BUILT_IN with\n\tfndecl_built_in_p.\n\n2018-09-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-frontend.h: Remove file, and all sources that include it.\n\t* d-lang.cc: Include dmd/doc.h and dmd/mangle.h.\n\t* d-target.cc: Include dmd/mangle.h.\n\t* decl.cc: Include dmd/mangle.h.\n\n2018-08-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_FRONTEND_OBJS): Add iasm.o, iasmgcc.o\n\t(d.tags): Scan dmd/root/*.h\n\t* d-builtins.cc (build_frontend_type): Update callers for new\n\tfront-end signatures.\n\t(d_init_versions): Add D_ModuleInfo, D_Exceptions, D_TypeInfo.\n\t* d-diagnostic.cc (vwarning): Increment gagged warnings error if\n\tgagging turned on.\n\t(vdeprecation): Likewise.\n\t* d-frontend.cc (asmSemantic): Remove function.\n\t* d-lang.cc (d_handle_option): Remove case for OPT_fproperty.\n\t* d-target.cc (Target::_init): Remove int64Mangle and uint64Mangle.\n\t* lang.opt (fproperty): Remove option.\n\t* toir.cc (IRVisitor::visit(ExtAsmStatement)): Rename override to\n\tGccAsmStatement.\n\t* typeinfo.cc (TypeInfoVisitor::visit(TypeInfoClassDeclaration)): Use\n\tint for collecting ClassFlags.\n\t* (TypeInfoVisitor::visit(TypeInfoClassDeclaration)): Use int for\n\tcollecting StructFlags.\n\n2018-07-23  Eugene Wissner  <belka@caraus.de>\n\n\t* d-lang.cc (d_handle_option): Change function argument to HOST_WIDE_INT.\n\t* lang.opt (Walloca-larger-than=, Wno-alloca-larger-than): New options.\n\t* opt.texi (Walloca-larger-than=, Wno-alloca-larger-than): Likewise.\n\n2018-07-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* decl.cc (get_symbol_decl): Set all generated static symbols as\n\tDECL_EXTERNAL. Move logic for determining TREE_STATIC ...\n\t(start_function): ... here.\n\t(reset_decl_tls_model): New function.\n\t(d_finish_decl): Call it on finished variables.\n\n2018-07-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (d.tags): Rename dfrontend to dmd.\n\t* d-attribs.c: Rename dfrontend includes to dmd.\n\t* d-builtins.cc: Likewise.\n\t* d-codegen.cc: Likewise.\n\t* d-convert.cc: Likewise.\n\t* d-diagnostic.cc: Likewise.\n\t* d-frontend.cc: Likewise.\n\t* d-incpath.cc: Likewise.\n\t* d-lang.cc: Likewise.\n\t* d-longdouble.cc: Likewise.\n\t* d-target.cc: Likewise.\n\t* decl.cc: Likewise.\n\t* expr.cc: Likewise.\n\t* imports.cc: Likewise.\n\t* intrinsics.cc: Likewise.\n\t* modules.cc: Likewise.\n\t* runtime.cc: Likewise.\n\t* toir.cc: Likewise.\n\t* typeinfo.cc: Likewise.\n\t* types.cc: Likewise.\n\n2018-07-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* types.cc (same_type_p): Check type codes match before checking\n\tequivalence.\n\n2018-07-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(CmpExp)): Remove lowering of static and\n\tdynamic array comparisons.\n\t* runtime.def (ADCMP2): Remove define.\n\t(SWITCH_STRING): Likewise.\n\t(SWITCH_USTRING): Likewise.\n\t(SWITCH_DSTRING): Likewise.\n\t(SWITCH_ERROR): Likewise.\n\t* toir.cc (IRVisitor::visit(SwitchStatement)): Remove lowering of\n\tstring switch statements.\n\t(IRVisitor::visit(SwitchErrorStatement)): Remove lowering of throwing\n\tSwitchErrors.\n\n2018-07-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (CHECKING_DFLAGS): New variable.\n\t(ALL_DFLAGS): Add -frelease when front-end tree checking is disabled.\n\n2018-07-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* verstr.h: Update to 2.081.1\n\n2018-07-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc: Include id.h.\n\n2018-07-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (lower_struct_comparison): Evaluate side effects of\n\tempty struct.\n\t(build_struct_comparison): Likewise.\n\n2018-07-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* typeinfo.cc (TypeInfoVisitor::layout_interfaces): Only generate an\n\tinterface vtable for classes.\n\t(TypeInfoVisitor::visit(TypeInfoClassDeclaration)): Likewise.\n\n2018-07-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (deps_write): Ignore __main module.\n\t(d_handle_option): Handle -fmain option.\n\t(d_parse_file): Generate D main function if requested.\n\t* lang.opt (fmain): New option.\n\n2018-07-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Handle options -ftransition=dip1008 and\n\t-ftransition=intpromote.\n\t* lang.opt (ftransition=dip1008): New option.\n\t(ftransition=intpromote): New options.\n\n2018-07-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (d_build_builtins_module): Export __builtin_clonglong\n\tand __builtin_culonglong to gcc builtins module.\n\n2018-07-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (d_init_versions): Update condition for enabling\n\tversion assert.\n\t* d-lang.cc (d_init_options): Remove setting of flags that are default\n\tinitialized statically.\n\t(d_init_options_struct): Update condition for setting bounds check.\n\t(d_handle_option): Update condition for setting flags for enabling\n\tasserts and switch errors.\n\t(d_post_options): Likewise.\n\t* expr.cc (ExprVisitor::visit(AssertExp)): Update condition for\n\tgenerating assert code.\n\n2018-07-04  Eugene Wissner  <belka@caraus.de>\n\n\t* d-spec.c: Include opt-suggestions.h containing option_proposer used by\n\tgcc.h.\n\n2018-07-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* verstr.h: Update to 2.081.0-rc.1\n\n2018-07-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* decl.cc (walk_pragma_cdtor): New function.\n\t(DeclVisitor::visit(PragmaDeclaration)): Handle pragma crt_constructor\n\tand crt_destructor.\n\n2018-07-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* decl.cc (get_symbol_decl): Implicitly convert return type of 'void'\n\tmain to 'int' for both C and D entry functions.\n\t* toir.cc (IRVisitor::visit(ReturnStatement)): Likewise.\n\n2018-07-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-target.cc (Target::_init): Set int64Mangle, uint64Mangle,\n\ttwoDtorInVariable.\n\t* typeinfo.cc (TypeInfoVisitor::visit(TypeInfoClassDeclaration)): Use\n\ttidtor symbol for destructor.\n\t(TypeInfoVisitor::visit(TypeInfoClassDeclaration)): Likewise.\n\n2018-06-30  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(FuncExp)): Don't error about nested\n\tdelegate literals.\n\n2018-06-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-frontend.cc (eval_builtin): Allow both gcc and frontend builtins.\n\t* intrinsics.cc (call_builtin_fn): Use convert.\n\t(expand_intrinsic_sqrt): Use fold_convert.\n\t(expand_intrinsic_copysign): New function.\n\t(expand_intrinsic_pow): New function.\n\t(maybe_expand_intrinsic): Handle many math intrinsics.\n\t* intrinsics.def (EXPM1, EXP2, LOG, LOG2, LOG10, ROUND, FLOORF),\n\t(FLOOR, FLOORL, CEILF, CEIL, CEILL, TRUNC, FMIN, FMAX, COPYSIGN),\n\t(POW, FMA): Add math intrinsics.\n\n2018-06-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (WARN_DFLAGS): New variable.\n\t(ALL_DFLAGS): Use coverage and warn flags.\n\n2018-06-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (d_init_versions): Add version D_BetterC.\n\t* d-codegen.cc (find_aggregate_field): Move to decl.cc\n\t(build_class_instance): Move to decl.cc, make static.\n\t* d-frontend.cc (getTypeInfoType): Issue warning when -fno-rtti.\n\t* d-lang.cc (d_init): Check for global useExceptions.\n\t(d_handle_option): Handle OPT_fdruntime, OPT_fexceptions, OPT_frtti.\n\t(d_post_options): Set flags if -fno-druntime was given.\n\t* d-tree.h (build_class_instance): Remove declaration.\n\t(have_typeinfo_p): Add declaration.\n\t(build_typeinfo): Update signature.\n\t* decl.cc (DeclVisitor::finish_vtable): New function.\n\t(DeclVisitor::visit(StructDeclaration)): Generate typeinfo only if\n\tfound in library.\n\t(DeclVisitor::visit(EnumDeclaration)): Likewise.\n\t(DeclVisitor::visit(InterfaceDeclaration)): Likewise.\n\t(DeclVisitor::visit(ClassDeclaration)): Likewise.\n\tExit early if semantic error occurred during final semantic.\n\t* decl.cc: Update all callers of build_typeinfo.\n\t* lang.opt (fdruntime): New option.\n\t(fmoduleinfo): Add flag for option.\n\t(frtti): New option.\n\t* modules.cc (build_module_tree): Check for global useModuleInfo.\n\t* toir.cc (IRVisitor::visit(ThrowStatement)): Check for global\n\tuseExceptions.\n\t* typeinfo.cc: Include options.h.\n\t(make_frontend_typeinfo): Set members and storage class fields on\n\tcompiler-generated typeinfo.\n\t(have_typeinfo_p): New function.\n\t(TypeInfoVisitor::layout_base): Add reference to vtable only if\n\ttypeinfo found in library.\n\t(TypeInfoVisitor::visit): Update all callers of build_typeinfo.\n\t(TypeInfoVisitor::visit(TypeInfoClassDeclaration)): Always set RTInfo\n\tfield, even if null.\n\t(build_typeinfo): Add error if -fno-rtti passed on commandline.\n\n2018-06-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* types.cc (TypeVisitor::visit(TypeClass)): Handle get_symbol_decl\n\treturning an error_mark_node.\n\n2018-06-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-tree.h (lang_identifier): Add daggregate field.\n\t(IDENTIFIER_DAGGREGATE): New macro.\n\t(mangle_decl): Declare.\n\t* decl.cc (mangle_decl): Remove static linkage.\n\t* types.cc (TypeVisitor::visit(TypeStruct)): Handle duplicate\n\tdeclarations of type symbol.\n\t(TypeVisitor::visit(TypeClass)): Likewise.\n\n2018-06-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* verstr.h: Update to 2.081.0-beta.2\n\n2018-06-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* decl.cc (DeclVisitor::visit(FuncDeclaration)): Move function\n\tunnesting to...\n\t(get_symbol_decl): ... here.\n\n2018-06-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_post_options): Set global showColumns parameter.\n\n2018-06-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (d_init_versions): Replace BOUNDSCHECK enum values\n\twith CHECKENABLE.\n\t* d-codegen.cc (array_bounds_check): Likewise.\n\t* d-frontend.cc (Global::init_): Don't set params initialized by the\n\tfrontend.\n\t* d-lang.cc (d_init_options): Update initialization of global struct.\n\t(d_handle_option): Replace BOUNDSCHECK enum values with CHECKENABLE.\n\tUpdate handling of debug and version identifiers.\n\t(d_post_options): Replace BOUNDSCHECK enum values with CHECKENABLE.\n\tHandle debug and version identifiers given on the command line.\n\t(d_parse_file): Use global versionids to get full list of predefined\n\tidentifiers.\n\n2018-06-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-frontend.cc (Global::startGagging): Remove function.\n\t(Global::endGagging): Remove function.\n\t(Global::increaseErrorCount): Remove function.\n\t(Loc::equals): Remove function.\n\t(retStyle): Remove function.\n\t(getTypeInfoType): Update signature.\n\t* d-target.cc (Target::isVectorOpSupported): Don't handle unordered\n\texpressions.\n\t(Target::prefixName): Remove function.\n\t(Target::cppParameterType): New function.\n\t(Target::isReturnOnStack): New function.\n\n2018-06-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* decl.cc (DeclVisitor::visit(ClassDeclaration)): Use\n\tClassDeclaration::vtblSymbol to access vtable symbol.\n\t(get_vtable_decl): Likewise.\n\n2018-06-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-diagnostic.cc (expand_format): Handle whitespace format specifier.\n\t(d_diagnostic_report_diagnostic): Change signature, updated all\n\tcallers.  Handle writing messages verbatim.\n\t(vmessage): New function.\n\t* d-lang.cc (d_parse_file): Use message to emit verbose diagnostics.\n\t* decl.cc (DeclVisitor::visit(FuncDeclaration)): Likewise.\n\t(get_symbol_decl): Likewise.\n\n2018-06-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (build_frontend_type): Update call to\n\tTypeVector::create.  Use Type::merge2 to complete type.\n\t(maybe_set_builtin_1): Update call to AttribDeclaration::include.\n\t* d-codegen.cc (declaration_type): Use Type::merge2 to complete type.\n\t(type_passed_as): Likewise.\n\t* d-convert.cc (convert_expr): Use ClassDeclaration::isCPPclass.\n\t* d-frontend.cc (genCmain): Use new semantic entrypoints.\n\t* d-lang.cc (d_parse_file): Likewise.\n\t(d_build_eh_runtime_type): Use ClassDeclaration::isCPPclass.\n\t* decl.cc (DeclVisitor::visit(AttribDeclaration)): Update call to\n\tAttribDeclaration::include.\n\t(get_symbol_decl): Replace PROT enum values with Prot.\n\t* expr.cc (ExprVisitor::visit): Merge AndAndExp and OrOrExp into\n\tLogicalExp visitor method.\n\t* modules.cc (get_internal_fn): Replace PROT enum value with Prot.\n\t* toir.cc (IRVisitor::visit): Use ClassDecalration::isCPPclass.\n\t* typeinfo.cc (make_frontend_typeinfo): Use new semantic entrypoints.\n\t(TypeInfoVisitor::visit): Use Type::merge2 to complete type.\n\t* types.cc (layout_aggregate_members): Update call to\n\tAttribDeclaration::include.\n\t(layout_aggregate_type): Use ClassDeclaration::isCPPclass.\n\n2018-06-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Makefile.in (d.mostlyclean): Remove cleanup of verstr.h.\n\n2018-06-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Makefile.in (D_FRONTEND_OBJS): Add compiler.o, ctorflow.o,\n\tdsymbolsem.o, lambdacomp.o, longdouble.o, parsetimevisitor.o,\n\tpermissivevisitor.o, port.o, semantic2.o, semantic3.o,\n\ttemplateparamsem.o, transitivevisitor.o\n\t(D_INCLUDES): Rename ddmd to dmd.\n\t(d/%.o): Likewise.\n\n2018-06-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Makefile.in (DMD_WARN_CXXFLAGS, DMD_COMPILE)\n\t(DMDGEN_COMPILE): Remove variables.\n\t(ALL_DFLAGS, DCOMPILE.base, DCOMPILE, DPOSTCOMPILE, DLINKER)\n\t(DLLINKER): New variables.\n\t(D_FRONTEND_OBJS): Add new frontend objects.\n\t(D_GENERATED_SRCS, D_GENERATED_OBJS): Remove variables.\n\t(D_ALL_OBJS): Remove D_GENERATED_OBJS.\n\t(cc1d): Use DLLINKER command to produce compiler.\n\t(d.mostlyclean): Remove generated sources.\n\t(CFLAGS-d/id.o, CFLAGS-d/impcnvtab.o): Remove recipes.\n\t(d/%.o): Use DCOMPILE and DPOSTCOMPILE to build frontend.\n\t(d/idgen, d/impcvgen, d/id.c, d/id.h, d/impcnvtab.c)\n\t(d/verstr.h): Remove recipes.\n\t* config-lang.in (boot_language): New variable.\n\t* d-frontend.cc (inlineCopy): Remove function.\n\t(global): Remove variable.\n\t* d-diagnostics.cc (error, errorSupplemental): Remove functions.\n\t(warning, warningSupplemental): Likewise.\n\t(deprecation, deprecationSupplemental): Likewise.\n\t* d-lang.cc (d_init_options): Initialize D runtime.\n\t* d-longdouble.cc (CTFloat::zero, CTFloat::one, CTFloat::minusone)\n\t(CTFloat::half): Remove variables.\n\t* d-target.cc (Target::ptrsize, Target::c_longsize, Target::realsize)\n\t(Target::realpad, Target::realalignsize, Target::reverseCppOverloads)\n\t(Target::cppExceptions, Target::classinfosize)\n\t(Target::maxStaticDataSize): Remove variables.\n\t* verstr.h: New file.\n\n2018-05-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(StringExp)): Copy string literal from\n\tthe frontend to a null terminated string.\n\n2018-05-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::binary_op): Don't do complex conversions if\n\talready handling excess precision.\n\n2018-04-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (doing_semantic_analysis_p): New variable.\n\t(d_parse_file): Set when in semantic pass.\n\t* d-tree.h (doing_semantic_analysis_p): Add declaration.\n\t* intrinsics.cc (maybe_expand_intrinsic): Test for\n\tdoing_semantic_analysis_p.\n\n2018-03-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (stabilize_expr): Move modify expression rewrite...\n\t* expr.cc (ExprVisitor::binop_assignment): ... here.\n\n2018-03-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(StringExp)): Include null terminator\n\tin length when calling build_String.  Generate static array string\n\tliterals as array constructors.\n\n2018-03-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Rename OPT_fintfc cases to OPT_H.\n\t* gdc.texi (Code Generation): Rename -fintfc options to -H.\n\t* lang-specs.h: Add H, Hd, and Hf options.\n\t* lang.opt (H, Hd, Hf): New options.\n\t(fintfc, fintfc-dir=, fintfc-file=): Deprecate and alias new options.\n\n2018-03-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* lang.opt (fdeps, fdeps=): Deprecate options.\n\t* gdc.texi (Code Generation): Remove deprecated fdeps options.\n\n2018-02-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_FRONTEND_OBJS): Remove inline.o and inlinecost.o.\n\n2018-02-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-frontend.cc (CTFloat::fabs): Assign result to real_t directly.\n\t(CTFloat::ldexp): Likewise.\n\t* d-longdouble.cc (longdouble::from_int): Remove function.\n\t(longdouble::from_uint): Likewise.\n\t(longdouble::to_int): Update Signature.\n\t(longdouble::to_uint): Likewise.\n\t(longdouble::operator): Likewise.\n\t(longdouble::add): New function, move operator overload headers.\n\t(longdouble::sub, longdouble::mul, longdouble::div): Likewise.\n\t(longdouble::mod, longdouble::neg): Likewise.\n\t(longdouble::cmp, longdouble::equals): Likewise.\n\t* d-target.cc (Target::_init): Construct assignment into real_t\n\tdirectly.\n\n2018-02-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (DMD_WARN_CXXFLAGS): Only filter out\n\t-Wmissing-format-attribute from WARN_CXXFLAGS.\n\n2018-02-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (build_frontend_type): Set alignment of structs in\n\tfrontend.\n\n2018-02-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-incpath.cc (add_environment_paths): Remove function.\n\t* gdc.texi (Environment Variables): Remove section.\n\n2018-02-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::AssertExp): Use builtin expect to mark assert\n\tcondition as being likely true.\n\n2018-02-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* lang.opt (fd-vgc, fd-verbose, fd-vtls): Remove options.\n\t(femit-moduleinfo, femit-templates): Likewise.\n\t(fmake-deps, fmake-mdeps): Likewise.\n\t(fin, fout, fXf): Likewise.\n\n2018-01-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* gdc.texi (Runtime Options): Remove deprecated -fproperty option.\n\n2018-01-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_gimplify_expr): Gimplify all CALL_EXPR_ARGS_ORDERED\n\tcall arguments, not just non-constant.\n\n2018-01-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* decl.cc (DeclVisitor::visit(VarDeclaration)): Don't reuse existing\n\ttemporary for TARGET_EXPR.\n\t(declare_local_var): Push all variables to current binding level.\n\n2018-01-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* toir.cc (build_function_body): Set input_location.\n\n2018-01-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_frame_type): Don't add chain field for\n\tfunctions without context pointer.\n\t(build_closure): Don't set chain field for functions without context\n\tpointer.\n\n2018-01-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* decl.cc (DeclVisitor::visit(StructDeclaration)): Mark compiler\n\tgenerated symbols as DECL_ONE_ONLY instead of DECL_COMDAT.\n\t(DeclVisitor::visit(ClassDeclaration)): Likewise.\n\t(DeclVisitor::visit(InterfaceDeclaration)): Likewise.\n\t(DeclVisitor::visit(EnumDeclaration)): Likewise.\n\t(get_symbol_decl): Mark template instantiations as DECL_ONE_ONLY\n\tinstead of DECL_COMDAT.  Don't call mark_needed.\n\t(declare_extern_var): Don't call mark_needed.\n\t(d_finish_decl): Remove zero initializer for common symbols.\n\t(finish_thunk): Don't call d_comdat_linkage on generic thunk.\n\t(d_comdat_linkage): Don't set DECL_DECLARED_INLINE on functions.\n\t* typeinfo.cc (TypeInfoDeclVisitor::visit(TypeInfoDeclaration)): Mark\n\tbuilt-in typeinfo symbols as DECL_ONE_ONLY instead of DECL_COMDAT.\n\n2018-01-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_init): Disable flag_weak if not supported.\n\t* decl.cc (d_comdat_linkage): Use flag_weak to guard setting\n\tDECL_ONE_ONLY on decls.\n\t(d_linkonce_linkage): New function.\n\t* gdc.texi (Runtime Options): Document -fweak.\n\t* lang.opt (fweak): Declare.\n\n2018-01-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* decls.cc (get_symbol_decl): Use attribute to mark naked functions.\n\n2018-01-08  Eugene Wissner  <belka@caraus.de>\n\n\t* d-builtins.cc (d_eval_constant_expression): Handle polynomial\n\tVECTOR_CST_NELTS.\n\t(build_frontend_type): Handle polynomial TYPE_VECTOR_SUBPARTS.\n\n2018-01-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\tUpdate copyright years.\n\f\nCopyright (C) 2018 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2006",
    "content": "2006-12-27  DF  <dvdfrdmn@users.sf.net>\n\n\t* phobos/internal/fpmath.d: Support x86_64\n\n\t* phobos/configure.in: x86_64 can use fpmath.d\n\t* phobos/configure: update\n\n\t* target-ver-syms.sh: Add some CPU architectures\n\n2006-12-26  DF  <dvdfrdmn@users.sf.net>\n\n\t* phobos/configure.in: actually use value of\n\t--enable-phobos-config-dir\n\n2006-12-26  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tRest of 0.178 changes:\n\n\t* phobos/std/bitarray.d: revert previous changes\n\n\t* d-decls.cc (toSymbolX): update\n\n\t* d-glue.cc (TypeFunction::retStyle): implement\n\n\t* phobos/std/format.d: update for Mangle.Tenum\n\n\t-------------\n\n\tInitial merge of 0.178:\n\n\t* dmd/class.c, dmd/declaration.c, dmd/declaration.h, dmd/doc.c,\n\tdmd/expression.c, dmd/expression.h, dmd/func.c, dmd/init.c,\n\tdmd/lexer.c, dmd/mangle.c, dmd/mars.c, dmd/mars.h, dmd/mtype.c,\n\tdmd/optimize.c, dmd/parse.c, dmd/statement.c, dmd/statement.h,\n\tdmd/template.c, dmd/tocsym.c, dmd/toobj.c: Merge 0.178\n\n\t* phobos/internal/gc/win32.d, phobos/internal/object.d,\n\tphobos/std/c/linux/linux.d, phobos/std/date.d,\n\tphobos/std/dateparse.d, phobos/std/format.d, phobos/std/gc.d,\n\tphobos/std/regexp.d, phobos/std/socket.d, phobos/std.ddoc: Merge\n\t0.178\n\n\t---------------\n\n\t* dmd/constfold.c (CastExp::constFold): Fix Bugzilla 738.\n\n\t* dmd/todt.c (StructDeclaration::toDt): Fix Bugzilla 736.\n\n\t* d-decls.cc (VarDeclaration::toSymbol): Fix Bugzilla 737.\n\n\t* d-glue.cc (make_assign_math_op): Fix Bugzilla 739.\n\n\t* d-codegen.cc, d-decls.cc, d-glue.cc, symbol.cc, symbol.h:\n\tUse toParent2.  Handle nested template instance functions.\n\t(Bugzilla 742, 743)\n\n2006-12-25  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* dmd/mtype.c: Don't use '@' in mangled names\n\n\t* d-glue.cc (TypeFunction::toCtype): Handle recursive type\n\treference (Bugzilla 745)\n\n\t* d-codegen.cc, d-codegen.h, d-glue.cc, d-objfile.cc, d-objfile.h,\n\tdmd/aggregate.h, dmd/attrib.c, dmd/class.c, dmd/declaration.c,\n\tdmd/declaration.h, dmd/enum.c, dmd/enum.h, dmd/func.c,\n\tdmd/idgen.c, dmd/scope.c, dmd/scope.h, dmd/struct.c: Implement\n\tGCC attributes.\n\n\t* dmd/mtype.c (TypeDelegate::dotExp): Fix regression caused by\n\tlast fix.\n\n2006-12-24  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* dmd/parse.h, dmd/parse.c(parseStatement, parseExtAsm),\n\tdmd/statement.h, asmstmt.cc: Implement GCC extended assembler.\n\n2006-12-20  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* dmd/mars.h: format issues are due to newlib, not Cygwin\n\n\t* setup-gcc.sh: Fix sed patterns and options.\n\n\t* dmd/mtype.c (TypeDelegate::dotExp): Handle .ptr so that\n\tit can be an lvalue. (Bugzilla 696)\n\n\t* d-irstate.cc (getLoopForLabel): Handle labels pointing to\n\tScopeStatements. (Bugzilla 695)\n\n2006-12-16  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tRelease GDC 0.20\n\n\t* setup-gcc.sh: account for modified version strings\n\n\t* dmd/mtype.c (TypeTuple::toDecoBuffer): workaround newlib bug\n\n\t* dmd/mars.h: fix printf formats for Cygwin\n\n\t* d-builtins.c (d_init_builtins): Handle va_list type when it is\n\tan array.\n\n\t* gcc-mars.cc, gdc-version: update\n\n\t* d-decls.cc: warnings cleanup\n\n\t* dmd/expression.c (realToMangleBuffer): filter out 'x'\n\n2006-12-13  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* package/simple.sh: use MAKE environment variable\n\n2006-12-11  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* patch-build_gcc-4.0: don't disable Objective C\n\n2006-12-09  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/std/bitarray.d (unittest): workaround 0.177 breakage\n\n\t* phobos/std/format.d,\n\t* phobos/std/string.d,\n\t* phobos/std/loader.d: update\n\n\t* phobos/std/file.d: fix merge. update.\n\n\t* dmd/root.[ch] (writestring): make arg const\n\n\t* dmd/expression.c (toMangleBuffer): update\n\n\tInitial 0.177 merges\n\n\t* dmd/constfold.c, dmd/declaration.c, dmd/expression.[ch],\n\tdmd/func.c, dmd/idgen.c, dmd/manlge.c, dmd/mars.c, dmd/mtype.[ch],\n\tdmd/opover.c, dmd/tocsym.c, dmd/toobj.c, dmd/typinf.c: Merge 0.177\n\n\t* etc/c/zlib.d, phobos/internal/aaA.d, phobos/internal/adi.d,\n\tphobos/internal/arraycat.d, phobos/internal/gc/gc.d,\n\tphobos/internal/gc/testgc.d, phobos/internal/object.d,\n\tphobos/internal/qsort.d, phobos/internal/switch.d,\n\tphobos/internal/trace.d, phobos/object.d, phobos/std/array.d,\n\tphobos/std/boxer.d, phobos/std/conv.d, phobos/std/cover.d,\n\tphobos/std/cpuid.d, phobos/std/date.d, phobos/std/file.d,\n\tphobos/std/format.d, phobos/std/loader.d, phobos/std/math2.d,\n\tphobos/std/md5.d, phobos/std/mmfile.d, phobos/std/outbuffer.d,\n\tphobos/std/path.d, phobos/std/regexp.d, phobos/std/socket.d,\n\tphobos/std/stream.d, phobos/std/string.d, phobos/std/switcherr.d,\n\tphobos/std/syserror.d, phobos/std/typeinfo/ti_Acdouble.d,\n\tphobos/std/typeinfo/ti_Acfloat.d, phobos/std/typeinfo/ti_Acreal.d,\n\tphobos/std/typeinfo/ti_Adchar.d, phobos/std/typeinfo/ti_Adouble.d,\n\tphobos/std/typeinfo/ti_Afloat.d, phobos/std/typeinfo/ti_Ag.d,\n\tphobos/std/typeinfo/ti_Aint.d, phobos/std/typeinfo/ti_Along.d,\n\tphobos/std/typeinfo/ti_Areal.d, phobos/std/typeinfo/ti_Ashort.d,\n\tphobos/std/typeinfo/ti_Aubyte.d, phobos/std/typeinfo/ti_Auint.d,\n\tphobos/std/typeinfo/ti_Aulong.d, phobos/std/typeinfo/ti_Aushort.d,\n\tphobos/std/typeinfo/ti_Awchar.d, phobos/std/uri.d,\n\tphobos/std/utf.d, phobos/std/windows/charset.d,\n\tphobos/std/windows/registry.d, phobos/std/zlib.d: Merge 0.177\n\n\t--------------\n\n\t* patch-apple-gcc-4.0.x, patch-build_gcc-4.0: Support\n\tbuilding the Apple way on PowerPC machines.\n\n2006-12-06  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.cc (call): Fix for calling delegate literal.\n\n\t* setup-gcc.sh: fail if patching build_gcc fails\n\n\t* d-glue.cc (NewExp::toElem): expand stack vars\n\tfor GCC 3.x\n\n\t* phobos/std/cpuid.d: fix for cpuid kludge\n\n2006-12-05  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* dmd/mars.h: Handle msvcrt C99 printf incompatibility.\n\n\t* dmd/template.c, dmd/declaration.c, dmd/expression.c, dmd/func.c,\n\tdmd/init.c, dmd/lexer.c, dmd/mangle.c, dmd/mtype.c,\n\tdmd/optimize.c, dmd/root.c: ditto\n\n\t* phobos/config/unix-mid: fix compile error\n\n2006-12-04  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMore 0.176 merges\n\n\t* phobos/config/unix-mid: add reentrant funcs\n\n\t* d-glue.cc (DeleteExp::toElem): handle on-stack vars\n\n\t* d-glue.cc (FuncDeclaration::toObjFile): emit _arguments\n\n\t* dmd/declaration.h, dmd/func.c: save _arguments local var for\n\tbackend\n\n2006-12-03  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-glue.cc: New _arguments ABI.\n\n\t* gcc-mars.cc: Update for verror.\n\n\t* d-decls.cc, d-objfile.cc,\n\t* d-glue.cc (Module::genobjfile, d_gcc_aggregate_dtors): Update\n\tfor new toSymbolX.\n\n\t* d-glue.cc (TypeAArray::toCtype): Implement new AA ABI.\n\n\t* d-codegen.cc (convertTo): Don't allow conversion of dynamic\n\tarray to associated array and vice versa.\n\n\t* d-codegen.cc (getLibCallDecl, rawArray, convertForCondition),\n\td-glue.cc (NullExp::toElem): change AA type\n\n\t* gcc-mars.cc : printf corrections\n\n\t* phobos/Makefile.in (MAIN_OBJS): add bind.o\n\n\tInitial merge of DMD 0.176\n\n\t* attrib.c, dmd/cast.c, dmd/class.c, dmd/cond.c, dmd/constfold.c,\n\tdmd/declaration.c, dmd/doc.c, dmd/dsymbol.h, dmd/dump.c,\n\tdmd/expression.c, dmd/expression.h, dmd/func.c, dmd/idgen.c,\n\tdmd/init.c, dmd/init.h, dmd/lexer.c, dmd/link.c, dmd/mangle.c,\n\tdmd/mars.c, dmd/mars.h, dmd/module.c, dmd/mtype.c, dmd/optimize.c,\n\tdmd/parse.c, dmd/root.c, dmd/statement.c, dmd/template.c,\n\tdmd/tocsym.c, dmd/todt.c, dmd/toobj.c: Merge 0.176\n\n\t* internal/aaA.d, phobos/internal/cmath2.d, phobos/internal/deh.c,\n\tphobos/internal/object.d, phobos/linux.mak,\n\tphobos/std/c/linux/linux.d, phobos/std/c/linux/socket.d,\n\tphobos/std/compiler.d, phobos/std/math.d, phobos/std/socket.d,\n\tphobos/std/string.d, phobos/std/traits.d,\n\tphobos/std/typeinfo/ti_Aubyte.d, phobos/std/typeinfo/ti_ubyte.d,\n\tphobos/std.ddoc, phobos/win32.mak: Merge 0.176\n\n\t* phobos/std/bind.d: New file in 0.176\n\n\t* dmd/toir.[ch]: New files (from DMD 0.175)\n\n\t* phobos/phobos.d: New file (from DMD 0.160)\n\n\t--------------\n\n\t* phobos/std/boxer.d (unbox(T : void*).unbox): fix\n\n\t* d-glue.cc (NewExp::toElem): Support allocation on stack\n\n\tInitial merge of DMD 0.175\n\n\t* cast.c, dmd/class.c, dmd/dchar.c, dmd/dchar.h,\n\tdmd/declaration.c, dmd/declaration.h, dmd/delegatize.c,\n\tdmd/dsymbol.c, dmd/dump.c, dmd/enum.c, dmd/expression.c,\n\tdmd/expression.h, dmd/func.c, dmd/identifier.c, dmd/identifier.h,\n\tdmd/inifile.c, dmd/init.c, dmd/lexer.c, dmd/lstring.h,\n\tdmd/mangle.c, dmd/mars.c, dmd/mtype.c, dmd/mtype.h,\n\tdmd/optimize.c, dmd/parse.c, dmd/root.c, dmd/root.h, dmd/scope.c,\n\tdmd/scope.h, dmd/statement.c, dmd/statement.h, dmd/stringtable.c,\n\tdmd/todt.c, dmd/typinf.c: Merge 0.175\n\n\tdmd/html.c: not merged\n\n\t* phobos/internal/object.d, phobos/std/demangle.d,\n\tphobos/std/format.d, phobos/std/socket.d, phobos/std/stdio.d,\n\tphobos/std/traits.d, phobos/std/uni.d, phobos/std.ddoc:\n\tMerge 0.175\n\n\t------------\n\n\t* config/darwin8, config/mingw: update config fragments\n\n2006-11-26  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.cc, d-glue.cc: Fix missing continue label\n\texpansion for GCC < 4.0\n\n\t* d-glue.cc (make_math_op): Convert non-complex to complex\n\tin all version of GCC. (Buzilla 575)\n\n\t* d-codegen.cc: for tree code class for GCC < 4.0\n\n\t* phobos/Makefile.in: make test programs dependendent on\n\tlibgphobos.a as gdc will still try to find it\n\n\t* phobos/configure.in: conditionally build std/boxer.o\n\n\t* phobos/Makefile.in (MAIN_OBJS): remove std/boxer.o\n\n\t* phobos/internal/arraycat.d (_d_array_literal): disable\n\n\t* phobos/std/format.d: fix for PowerPC Linux\n\n2006-11-25  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-gcc-real.h: cleanup for warnings\n\n2006-11-24  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-glue.cc (DotVarExp::toElem): Handle const members.\n\n\t* d-codegen.cc (needs_temp): Return false for constants.\n\t(isFreeOfSideEffects): New function.\n\n\t* d-glue.cc (do_array_set): Evaluate the rvalue only once\n\t(Bugzilla 578).\n\n2006-11-18  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tRest of DMD 0.174 merge:\n\n\t* dmd/mtype.c (TypeDelegate::dotExp): Use cast-to-pointer\n\tfor .ptr property\n\n\t* d-decls.cc (VarDeclaration::toSymbol): Build CONST_DECLs\n\t* d-codegen.cc (IRState::emitLocalVar): Do nothing if CONST_DECL\n\n\t* d-codegen.cc (ArrayScope::setArrayExp): Handle tuple/constant\n\tlengths.\n\n\t* dmd/toobj.c (Dsymbol::toObjFile): emit local variables for\n\ttuples\n\n\t* svn: move traits.d and typetuple.d to the correct directory\n\n\t* gcc-mars.cc (error): add va_list form\n\n\t* dmd/mars.h (error): use va_list for 'error'\n\n\t* dmd/expression.c, dmd/lexer.c: fix compile errors\n\n\t* phobos/Makefile.in (MAIN_OBJS): add traits.o and typetuple.o\n\n\t* dmd-script: add -v1 option\n\n\t* dmd/root.c (FileName::ensurePathExists): fix conditions\n\tfor non-win32, non-linux.\n\n\t* dmd-script (printUsage): add missing options documentation\n\n\t* d-codegen.{h, cc}: use size_t\n\n\t* phobos/internal/dgccmain2.d: update\n\n\tInitial merge of DMD 0.174:\n\n\t* dmd/attrib.c, dmd/cast.c, dmd/class.c, dmd/declaration.c,\n\tdmd/declaration.h, dmd/doc.c, dmd/dsymbol.c, dmd/dsymbol.h,\n\tdmd/expression.c, dmd/expression.h, dmd/func.c, dmd/hdrgen.c,\n\tdmd/idgen.c, dmd/inline.c, dmd/lexer.c, dmd/mangle.c, dmd/mars.c,\n\tdmd/mars.h, dmd/module.c, dmd/mtype.c, dmd/mtype.h, dmd/parse.c,\n\tdmd/statement.c, dmd/template.c, dmd/template.h, dmd/tocsym.c,\n\tdmd/todt.c, dmd/toobj.c, dmd/typinf.c, dmd/utf.c, dmd/utf.h: Merge\n\t0.174\n\n\t* phobos/internal/aApplyR.d, phobos/internal/dmain2.d,\n\tphobos/internal/object.d, phobos/linux.mak, phobos/object.d,\n\tphobos/std/date.d, phobos/std/openrj.d, phobos/std/signals.d,\n\tphobos/win32.mak: Merge 0.174\n\n\t* phobos/std/traits.d, phobos/std/typetuple.d: New files in 0.174\n\n\n2006-11-17  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* package/simple.sh: enhancements\n\n\t* dmd/attrib.c: fix message\n\n2006-11-16  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.cc (continueHere): fix error\n\t* d-glue.cc (d_gcc_aggregate_dtors): \"\n\n2006-11-14  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-builtins2.cc, d-codegen.{cc, h}, d-decls.cc, d-glue.cc,\n\td-lang.h: remove D_TYPE_IS_NESTED.  Do not pull original\n\tTypeFunction from FUNCTION_TYPE.\n\n\t* d-codegen.cc: cleanup\n\n\t* d-codegen.cc, gdc-alloca.h, phobos/config/gen_unix.c: fixes for\n\tolder MacOS X builds\n\n2006-11-13  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/std/cpuid.d: fixes for PIC\n\n\t* d-asm-i386.h: Fix for referencing funcs (Bugzilla 307).\n\tCorrect clobbers for cpuid, but left out EBX as a kludge for\n\tstd.cpuid.\n\n\t* phobos/std/c/linux/linux.d: make imports public (Bugzilla 403)\n\n\t* d-decls.cc (uniqueName): Fixed logic error (Bugzilla 375). Then\n\tjust removed most of the code and comments because the workaround\n\tis no longer needed.\n\n2006-11-12  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* dmd/root.c (Object::hashCode): cast to pointer acceptable int type\n\n\tRest of DMD 0.173 merge:\n\n\t* d-glue.cc (UnrolledLoopStatement::toIR): implement\n\n\t* d-codegen.h (setContinueLabel): add interface for multiple continues\n\n\t* d-irstate.h (Flow), d-irstate.cc: add overrideContinueLabel for\n\tGCC < 4.0\n\n\t* d-builtins2.cc, d-glue.cc, d-codegen.cc: update for\n\tTypeFunction::arguments -> parameters and tuples\n\n\t* dmd/func.c: update\n\n\t* d-gcc-complex_t.h: update\n\n\t* phobos/Makefile.in (MAIN_OBJS): add signals.o and cpuid.o\n\n\tInitial merge of DMD 0.173:\n\n\t* dmd/arraytypes.h, dmd/cast.c, dmd/class.c, dmd/complex_t.h,\n\tdmd/constfold.c, dmd/declaration.c, declaration.h,\n\tdmd/delegatize.c, dmd/doc.c, dmd/dsymbol.c, dmd/dsymbol.h,\n\texpression.c, dmd/expression.h, dmd/func.c, dmd/html.c,\n\tdmd/html.h, dmd/inline.c, lexer.c, dmd/lexer.h, dmd/mars.c,\n\tdmd/mars.h, dmd/mem.h, dmd/mtype.c, dmd/mtype.h, opover.c,\n\tdmd/optimize.c, dmd/parse.c, dmd/parse.h, dmd/statement.c,\n\tdmd/statement.h, struct.c, dmd/template.c, dmd/template.h,\n\tdmd/tocsym.c, dmd/toobj.c, dmd/typinf.c: Merge 0.173\n\n\t* phobos/internal/object.d, phobos/linux.mak, phobos/std/stream.d,\n\tphobos/std/string.d, phobos/std/system.d, phobos/std.ddoc,\n\tphobos/unittest.d, phobos/win32.mak: Merge 0.173\n\n\t* phobos/std/c/locale.d, phobos/std/cpuid.d, phobos/std/signals.d:\n\tNew files in 0.173\n\n\t----\n\n\t* dmd/class.c, dmd/mars.c, dmd/opover.c, dmd/statement.c:\n\tMerge DMD 0.172\n\n\tMerge DMD 0.171:\n\n\t* dmd/func.c, dmd/optimize.c: Update comments\n\n\t* dmd/aggregate.h, dmd/class.c, dmd/func.c, dmd/mars.c:\n\tMerge 0.171\n\n\t* phobos/internal/aApplyR.d, phobos/internal/gc/gc/.d: Merge 0.171\n\n\t----\n\n\tRest of DMD 0.170 merge:\n\n\t* d-glue.cc (ArrayLiteralExp::toElem): Handle the case in which\n\tthe type of the expression is a pointer.\n\n\t* dmd/optimize.c (PtrExp::optimize): Don't change type\n\tof expression without cast\n\n\t* phobos/internal/aApplyR.d: turn off debug(apply)\n\n2006-11-11  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-glue.cc (ForeachStatement::toIR): support foreach_reverse\n\n\t* dmd/lexer.c: size_t -> unsigned\n\n\t* d-lang.cc (d_handle_option): update\n\n\t* phobos/Makefile.in: add aApplyR.o\n\n\t* phobos/internal/monitor.c: merged\n\n\tInitial merge of DMD 0.170:\n\n\t* dmd/attrib.c, dmd/cast.c, dmd/class.c, dmd/delegatize.c,\n\tdmd/dsymbol.c, dmd/expression.c, dmd/expression.h, dmd/func.c,\n\tdmd/identifier.c, dmd/idgen.c, dmd/import.c, dmd/lexer.c,\n\tdmd/lexer.h, dmd/mangle.c, dmd/mars.c, dmd/module.c, dmd/mtype.c,\n\tdmd/mtype.h, dmd/opover.c, dmd/parse.c, dmd/statement.c,\n\tdmd/statement.h, dmd/template.h, dmd/utf.h: Merge 0.170\n\n\t* phobos/internal/aApply, phobos/internal/cast.d,\n\tphobos/internal/gc/gc.d, phobos/internal/mars.h,\n\tphobos/internal/object.d, phobos/linux.mak, phobos/object.d,\n\tphobos/std/gc.d, phobos/std/math.d, phobos/std/outofmemory.d,\n\tphobos/std/path.d, phobos/std/zlib.d, phobos/std.ddoc,\n\tphobos/unittest.d, phobos/win32.mak: Merge 0.170\n\n\t* internal/monitor.c: not changed; merge deferred for now\n\n\t* phobos/internal/aApplyR.d: new file in 0.170\n\n\t----\n\n\tRest of 0.169 merge:\n\n\t* phobos/internal/object.d: fix merge error\n\n\t* d-asm-i386.h: update for DMD changes\n\n\t* dmd/mtype.c, phobos/internal/adi.d (_adSortChar, _adSortWchar):\n\tfix for calling conventions\n\n\t* d-gcc-complex_t.h: updated\n\n\tInitial merge of DMD 0.169:\n\n\t* dmd/aggregate.h, dmd/arraytypes.h, dmd/attrib.h, dmd/class.c,\n\tdmd/complex_t.h, dmd/cond.h, dmd/declaration.h, dmd/declaration.c,\n\tdmd/doc.h, dmd/dsymbol.c, dmd/dsymbol.h, dmd/enum.h,\n\tdmd/expression.c, dmd/expression.h, dmd/hdrgen.h, dmd/html.h,\n\tdmd/identifier.h, dmd/idgen.c, dmd/import.c, dmd/import.h,\n\tdmd/init.c, dmd/init.h, dmd/lexer.h, dmd/macro.h, dmd/macro.c,\n\tdmd/mars.c, dmd/mars.h, dmd/module.c, dmd/module.h, dmd/mtype.c,\n\tdmd/mtype.h, dmd/opover.c, dmd/optimize.c, dmd/parse.h,\n\tdmd/root.c, dmd/scope.c, dmd/scope.h, dmd/statement.c,\n\tdmd/statement.h, dmd/staticassert.h, dmd/struct.c, dmd/template.c,\n\tdmd/template.h, dmd/total.h, dmd/typinf.c, dmd/utf.h,\n\tdmd/version.h: Merge 0.169\n\n\t* phobos/internal/adi.d, phbobos/internal/critical.c,\n\tphbobos/internal/mars.h, phbobos/internal/monitor.c,\n\tphbobos/internal/object.d, phbobos/object.d, phbobos/std/regexp.d:\n\tMerge 0.169\n\n\t----\n\n\t* dmd-script: Create directories for output files\n\n\tRest of 0.168 changes:\n\n\t* d-dmd-gcc.h, d-glue.cc (d_gcc_aggregate_dtors): new function\n\t* dmd/toobj.c (ClassDeclaration::toObjFile): use d_gcc_aggregate_dtors\n\n\t* d-codegen.cc (convertTo): handle delegate .ptr property\n\n\t* lang-specs.h, dmd-script: handle .xhtml extension\n\n\tInitial merge of DMD 0.168\n\n\t* dmd/aggregate.h, dmd/arraytypes.h, dmd/cast.c, dmd/class.c,\n\tdmd/declaration.c, dmd/expression.h, dmd/func.c, dmd/html.[ch],\n\tdmd/idgen.c, dmd/init.c, dmd/lexer.c, dmd/lexer.h, dmd/link.c,\n\tdmd/mangle.c, dmd/mars.c, dmd/module.c, dmd/mtype.[ch],\n\tdmd/statement.c, dmd/toobj.c, dmd/typeinf.c: Merge 0.168\n\n\t* phobos/etc/gamma.d, phobos/internal/object.d,\n\tphobos/std/c/linux/linux.d.orig-dmd, phobos/std/date.d,\n\tphobos/std/math.d, phobos/std/socket.d, phobos/std/socketstream.d,\n\tphobos/std/stream.d, phobos/std/uni.d, phobos/win32.mak: Merge 0.168\n\n2006-11-10  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* Make-lang.in (d.install-common): cross install fix for gdmd\n\n\t* d-glue.cc (NewExp::toElem): uint -> unsigned\n\n\t* package/simple.sh: Don't depend on rsync\n\n\t* patch-toplev-3.4.x, patch-toplev-4.0.x: Modify top-level\n\tMakefile.in, configure.in, and configure to work with\n\ta Canadian cross build.\n\n\t* d-glue.cc (SynchronizedStatement::toIR): Remove uneeded\n\tstartBindings call.  Add missing _d_criticalenter call.\n\n2006-10-12  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/config/unix-mid: add sysconf\n\n2006-10-11  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/std/format.d (doFormat): support Mangle.Tstruct for p_args\n\n\t* phobos/config/unix-head: import tm from gcc.config\n\n\t* phobos/config/gen_unix.c (c_time): Moved out struct tm.\n\n\t* phobos/config/gen_config1.c: Support clock_t. Move struct tm here.\n\n\t* d-glue.cc (AssignExp::toElem): use _d_arraysetlength3p\n\t(FuncDeclaration::toObjFile): Fixed assert of class member if\n\tsynchronized.\n\n\t* d-codegen.{h, cc}: replace libcall _d_arraysetlength2p with\n\t_d_arraysetlength3p\n\n\t* phobos/internal/gc/gc.d (_d_arraysetlength3p): pointer version\n\tof _d_arraysetlength3.  GCC asm jump fix.\n\n2006-10-09  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.{h, cc}: new libcalls: _dnewmp, _d_newarraymip\n\n\t* phobos/internal/gc/gc.d (_dnewmp, _d_newarraymip): pointer version\n\tof _dnewm, _d_newarraymi\n\n\t* phobos/config/unix-mid: add utime\n\n\t* phobos/std/file.d: changes for GDC\n\n\t* phobos/config/gen_unix.c: support utimbuf\n\n2006-09-23  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tInitial merge of 0.167:\n\n\t* dmd/array.c, dmd/cast.c, dmd/declaration.c, dmd/delegatize.c,\n\tdmd/expression.[ch], dmd/func.c, dmd/idgen.c, dmd/import.c,\n\tdmd/init.c, dmd/inline.c, dmd/lexer.[ch], dmd/mars.c,\n\tdmd/mtype.[ch], dmd/optimize.c, dmd/parse.c, dmd/statement.c,\n\tdmd/template.c, dmd/typinf.c: Merge 0.167\n\n\t* phobos/internal/arraycat.d, phobos/internal/gc/gc.d,\n\tphobos/internal/gc/testgc.d, phobos/internal/object.d,\n\tphobos/linux.mak, phobos/object.d, phobos/std/asserterror.d,\n\tphobos/std/c/linux/linux.d.orig-dmd, phobos/std/c/time.d,\n\tphobos/std/file.d, phobos/std/format.d, phobos/std/math.d,\n\tphobos/std/string.d, phobos/std/thread.d, phobos/unittest.d,\n\tphobos/win32.mak: Merge 0.167\n\n\t* phobos/std/c/windows/stat.d: New 0.167\n\n2006-09-06  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-glue.cc (FuncDelaration::toObjFile):\n\tAssert isMember\tfor synchronized functions.\n\t(NewExp::toElem): Correct some cases for nested classes\n\n2006-09-04  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* gdc-version, gcc-mars.cc: update\n\n\t* d-codegen.cc (trueDeclarationType): support lazy arguments\n\t(trueArgumentType): ditto\n\n\t* d-codegen.{h, cc}: comment out convertForInitialization\n\n\t* Make-lang.in (D_DMD_OBJS): add delegatize\n\n\t* dmd/delegatize.c: new, DMD 0.166\n\n\t* dmd/cast.c, dmd/declaration.[ch], dmd/expression.[ch],\n\tdmd/func.c, dmd/inline.c, dmd/lexer.c, dmd/lexer.h, dmd/mars.c,\n\tdmd/mtype.c, dmd/mtype.h, dmd/opover.c, dmd/parse.c,\n\tdmd/statement.c, dmd/struct.c, dmd/template.c, dmd/tocsym.c,\n\tdmd/typinf.c: Merge DMD 0.166\n\n\t* phobos/etc/c/zlib/...: Merge 0.166\n\n\t* phobos/internal/aApply.d, phobos/internal/gc/linux.mak,\n\tphobos/linux.mak, phobos/std/cover.d, phobos/std/utf.d,\n\tphobos/win32.mak: Merge 0.166\n\n\t* phobos/etc/zlib/infblock.[ch], phobos/etc/zlib/infcodes.[ch],\n\tphobos/etc/zlib/infutil.[ch], phobos/etc/zlib/maketree.c,\n\tphobos/etc/zlib/zlib.html: remove, DMD 0.166\n\n\t* gdc-version: update\n\n\t* d-glue.cc (FuncDeclaration::toObjFile): update\n\n\t* dmd/cast.c, dmd/declaration.[ch], dmd/enum.c,\n\tdmd/expression.[ch], dmd/func.c, dmd/init.c, dmd/inline.c,\n\tdmd/mars.c, dmd/mtype.c, dmd/statement.c, dmd/template.c,\n\tdmd/typeinf.c: Merge DMD 0.165\n\n\t* phobos/internal/gc/gcx.d, phobos/std.ddoc: Merge DMD 0.165\n\n\t* gdc-version: updated\n\n\t* dmd/aggregate.h, dmd/declaration.[ch], dmd/doc.c, dmd/dsymbol.c,\n\tdmd/expression.c, dmd/import.c, dmd/inifile.c, dmd/mars.c,\n\tdmd/module.[ch], dmd/mtype.c, dmd/parse.c, dmd/statement.c,\n\tdmd/template.c: Merge DMD 0.164\n\n\t* phobos/std/socket.d: Merge DMD 0.164\n\t* phobos/std/thread.d: no change\n\n2006-07-22  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/internal/gc/testgc.d: add import\n\n\t* phobos/std/thread.d (Thread.thread_init, Thread.getESP): make\n\tpublic\n\n\t* phobos/std/c/unix/unix.d: use public import\n\n\t* dmd/access.c, dmd/aggregate.h, dmd/attrib.c, dmd/class.c,\n\tdmd/declaration.[ch], dmd/enum.c, dmd/expression.c, dmd/func.c,\n\tdmd/import.[ch], dmd/mars.c, dmd/module.c, dmd/mtype.[ch],\n\tdmd/parse.[ch], dmd/scope.[ch], dmd/struct.c, dmd/template.[ch],\n\tdmd/todt.c: Merge DMD 0.163\n\n\t* phobos/internal/object.d, phobos/std/c/linux/linux.d.orig-dmd,\n\tphobos/std/regexp.d, phobos/std/stdio.d, phobos/std/stream.d:\n\tMerge DMD 0.163\n\n2006-07-12  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tRelease GDC 0.19\n\n\t* dmd/template.c: don't use ehfilter\n\t* gdc-version: update\n\n2006-07-11  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tSupport for Apple GCC and other fixes\n\n\t* setup-gcc.sh: patch build_gcc\n\t* patch-build_gcc-4.0: new\n\n\t* dmd-script: Support -arch option and apple driver naming.\n\tUse absolute path to execute program with -run.\n\n2006-07-10  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/config/darwin8/{frag-gen,frag-math,frag-unix}: new\n\t* phobos/configure.in: support Darwin cross compiling\n\t* phobos/configure.in: updated\n\n\t* phobos/config/gen_unix.c (c_fcntl): added *_OK enums\n\t* phobos/config/skyos/frag-unix: updated\n\n2006-07-03  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* ../../gcc/tree.h, ../../gcc/tree-dump.c: machine readable dump\n\n\tMerge DMD 0.162\n\n\t* d-glue.cc (AssignExp::toElem): use _d_arraysetlength2p\n\n\t* phobos/internal/gc/gc.d: chanage _d_arraysetlength2 to\n\t_d_arraysetlength2p\n\n2006-07-02  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.{h, cc}: support _d_arraysetlength2\n\n\t* dmd/cast.c, dmd/declaration.c, dmd/doc.c, dmd/expression.c,\n\tdmd/func.c, dmd/mars.c, dmd/mtype.c, dmd/parse.c, dmd/struct.c,\n\tdmd/template.[ch], dmd/toobj.c: merged\n\n\t* phobos/internal/gc/gc.d, phobos/object.d,\n\tphobos/std/asserterror.d, phobos/std/moduleinit.d: merged\n\n\t---\n\n\t* phobos/std/regexp.d (RegExp.Range.setbitmax): fix for\n\tbig endian\n\n2006-06-28  DF  <dvdfrdmn@users.sf.net>\n\n\t* d-glue.cc (TypeStruct::toCtype, TypeEnum::toCtype): Move\n\tinitTypeDecl call to after size calculation.\n\n2006-06-24  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/Makefile.in: fix and clean up config.d dependencies\n\n\t* d-gcc-real.cc (real_t): fix assumptions about HOST_WIDE_INT\n\n2006-06-23  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* Make-lang.in, asmstmt.cc, d-convert.cc, d-gcc-includes.h,\n\t  d-lang.cc, setup-gcc.sh: update to support building with Apple\n\t  GCC\n\t* d-apple-gcc.cc, patch-apple-gcc-4.0.x: new\n\n\tMisc fixes\n\n\t* Make-lang.in: Add dependencies for DMD header files.\n\n\t* phobos/config/gen_unix.c (c_time): fix array bounds bug\n\n2006-06-22  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* Make-lang.in: use BUILD_LDFLAGS for generator progs\n\n2006-06-21  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-asm-i386.h: implement offset/offsetof\n\n2006-06-20  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD 0.161\n\n\t* gcc-mars.cc, gdc-version: updated\n\n\t* dmd/cast.c, dmd/class.c, dmd/declaration.[ch], dmd/dsymbol.c,\n\tdmd/expression.[ch], dmd/func.c, dmd/idegen.c, dmd/import.h,\n\tdmd/inline.c, dmd/lexer.[ch], dmd/mars.[ch], dmd/module.c,\n\tdmd/mtype.c, dmd/opover.c, dmd/parse.c, dmd/root.[ch],\n\tdmd/statement.c, dmd/struct.c, dmd/template.[ch], dmd/toobj.c:\n\tMerge DMD 0.161\n\n\t* phobos/internal/adi.d, phobos/internal/cast.d,\n\tphobos/internal/trace.d, phobos/linux.mak,\n\tphobos/std/asserterror.d, phobos/std/base64.d,\n\tphobos/std/bitarray.d, phobos/std/boxer.d,\n\tphobos/std/c/linux/socket.d, phobos/std/c/windows/windows.d,\n\tphobos/std/c/windows/winsock.d, phobos/std/conv.d,\n\tphobos/std/cstream.d, phobos/std/date.d, phobos/std/dateparse.d,\n\tphobos/std/demangle.d, phobos/std/file.d, phobos/std/format.d,\n\tphobos/std/math.d, phobos/std/math2.d, phobos/std/mmfile.d,\n\tphobos/std/random.d, phobos/std/regexp.d, phobos/std/socket.d,\n\tphobos/std/socketstream.d, phobos/std/stream.d,\n\tphobos/std/string.d, phobos/std/stream.d, phobos/std/thread.d,\n\tphobos/std/typeinfo/ti_Along.d, phobos/std/typeinfo/ti_Aulong.d,\n\tphobos/std/tyeinfo/ti_void.d, phobos/std/uni.d, phobos/std/uri.d,\n\tphobos/std/utf.d, phobos/std/windows/registry.d, phobos/std/zip.d,\n\tphobos/std/zlib.d, phobos/std.ddoc, phobos/unittest.d,\n\tphobos/win32.mak: Merge DMD 0.161\n\n\t* Make-lang.in, d-lang.cc: Possible workaround for MingGW path\n\tissues.  Create d-confdefs.h to contain the values of D_PHOBOS_DIR\n\tand D_PHOBOS_TARGET_DIR.\n\n2006-06-10  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* History: new file\n\t* package/install.sif: ditto\n\t* package/simple.sh:\n\n\t* phobos/std/zip.d (putUshort): fix for BigEndian case\n\n\t* phobos/internal/gc/gcgccextern.d: update for version(freebsd)\n\n\t* target-ver-syms.sh: Use \"freebsd\" for FreeBSD.\n\n\t* phobos/configure.in: Enable std.loader for FreeBSD.\n\t* phobos/std/loader.d: ditto\n\t* phobos/configure: updated\n\n\t* Make-lang.in: Support package building. Cleanup.\n\n2006-06-08  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* patch-gcc-4.0.x: updated with...\n\t* .../gcc/tree-nested.c: check if static chain is a PARM_DECL\n\t(Bugzilla 175)\n\n2006-06-07  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* Make-lang.in: use CXX_FOR_BUILD\n\n\t* phobos/std/format.d (unittest): Some C libraries do not support\n\tthe %A format.\n\n2006-06-06  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/config/skyos/frag-unix: update for SkyOS beta 10\n\n2006-06-05  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD 0.160\n\n\t* d-codegen.cc (arrayType): handle zero-length arrays for local\n\tvariables.\n\n\t* gdc-version, gcc-mars.cc: update\n\n\t* d-glue.cc (NewExp::toElem): support 'exp. new ...'\n\n\t* d-codegen.{h, cc}: support _d_assert_msg\n\n\t* dmd/attrib.c, dmd/enum.c, dmd/expression.[ch], dmd/idgen.c,\n\tdmd/inifile.c, dmd/inline.c, dmd/mars.c, dmd/module.c,\n\tdmd/mtype.c, dmd/opover.c, dmd/parse.[ch], dmd/statement.[ch],\n\tdmd/staticassert.[ch], dmd/struct.c: Merge DMD 0.160\n\n\t* phobos/std/asserterror.d, phobos/std/regexp.d,\n\tphobos/std/zlib.d, phobos/std.ddoc, phobos/win32.mak: Merge DMD\n\t0.160\n\n2006-06-04  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tVarious fixes\n\n\t* d-codegen.cc (twoFieldType): cleanup\n\n\t* phobos/internal/gc/gc_dyld.c: correct callback signature\n\n\t* phobos/std/format.d (unittest): Undo test change.\n\t(putreal): Handle the case where real is equivalent to double.\n\n\t* d-glue.cc (TypeClass::toCtype): use prepareTypeDecl instead of\n\tsetting an initial TYPE_NAME (Bugzilla 174)\n\t(TypeStruct::toCtype): ditto\n\t(TypeEnum::toCtype): ditto\n\n\t* d-objfile.{h, cc} (prepareTypeDecl): New: Create type\n\tdeclarations, but do not declare them to back end.\n\n\tMerge DMD 0.159 and more\n\n\t* d-asm-i386.h (parsePrimaryExp): handle floating point const\n\tdecls specially (Bugzilla 141)\n\n2006-06-03  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-glue.cc (AssertExp::toElem): handle interfaces\n\n\t* phobos/std/math.d (poly): fix for darwin x86\n\n\t* phobos/std/format.d (unittest): handle some variation in %a\n\tformats\n\n\t* gdc-version: updated\n\n\t* gcc-mars.cc: updated\n\n\t* dmd/attrib.c, dmd/attrib.h, dmd/class.c, dmd/declaration.c,\n\tdmd/doc.c, dmd/expression.c, dmd/expression.h, dmd/func.c,\n\tdmd/link.c, dmd/mars.c, dmd/module.c, dmd/module.h, dmd/parse.c,\n\tdmd/parse.h, dmd/statement.c, dmd/staticassert.c, dmd/struct.c,\n\tdmd/template.c, dmd/toobj.c: Merge DMD 0.159\n\n\t* phobos/std/c/linux/linux.d.orig-dmd,\n\tphobos/std/c/linux/linuxextern.d, phobos/std/c/windows/windows.d,\n\tphobos/std/regexp.d, phobos/std/string.d, phobos/std/uni.d,\n\tphobos/std.ddoc: Merge DMD 0.159\n\n\t* dmd-script: use -O3 for GCC if -O is passed\n\n\tFix bugs 157, 162, 164, 171\n\n\t* d-asm-i386.h: 'invlpg' instruction takes an operand (Bug 171)\n\n\t* patch-gcc-4.0.x: updated with...\n\t* .../gcc/tree-nested.c: use a VAR_DECL for custom static chain\n\t(Bug 162, Bug 164)\n\n\t* gdc-version: updated\n\n\t* d-glue.cc (FuncExp::toElem): Handle Tpointer case. (Bug 157)\n\n2006-06-01  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* Start of SourceForge repository\n\n\f\nCopyright (C) 2006 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2007",
    "content": "2007-12-15  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos*/Makefile.{am,in}, phobos*/aclocal.m4: Automake changes\n\n\t* setup-gcc.sh: Support Apple GCC build 5465\n\n\t* patch-apple-gcc-5465, patch-build_gcc-5465, patch-toplev-5465:\n\tnew files\n\n2007-12-01  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/config/unix.x3, phobos/config/x3.c, phobos/config/x3.h\n\tphobos/config/x3, phobos/config/x3main.c: better diagnostics\n\tand behavior\n\n2007-11-24  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* setup-gcc.sh: Ignore .svn directories when making symlink trees.\n\n\t* d-bi-attrs-34.h, d-bi-attrs-341.h, d-bi-attrs-40,h,\n\td-bi-attrs-41.h: Support attributes on declarations in\n\tother modules.\n\n\t* d-codegen.cc (IRState::attributes): Support constant declarations\n\tas string arguments.\n\n2007-11-08  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-cppmngl.cc: Use base-36 in substitutions.  Other fixes.\n\n2007-10-17  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-cppmngl.cc: More C++ mangling fixes and cleanups.\n\n2007-10-16  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-glue.cc (EqualExp::toElem): Convert result to libcall\n\tto expression type. (Bugzilla 1573)\n\n2007-10-15  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-cppmngl.cc: Improve C++ mangling.\n\n2007-10-14  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD 1.022, 2.005\n\n\t* dmd/..., dmd2/..., phobos/..., phobos2/...: Merge.\n\n\t* Make-lang.in: Add builtin.dmd.o and d-cppmngl.o for V2.\n\n\t* d-cppmngl.cc: New file\n\n\t* phobos/std/c/dirent.d, phobos/std/c/linux/linux.d: Update\n\t* phobs2/...: same\n\n\t* symbol.h, d-decls.cc: Remove references to Classym\n\n\t----\n\n\t* d-glue.cc (CatExp::toElem): Null check. (Bugzilla 1581)\n\n\tRemove carriage returns from files\n\n2007-10-13  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-glue.cc (CatExp::toElem): Flatten multiple CatExps into a\n\tsingle library call. (Bugzilla 1556)\n\n\t* phobos/std/boxer.d (box, boxArray), phobos2/...: Fix for\n\tpromoted types.\t(Bugzilla 1543)\n\n\t* d-codegen.cc (call): Catch a case in which a member function can\n\tbe called without 'this'. (Bugzilla 1568)\n\n\t* dmd/mtype.c (TypeArray::dotExp): Correct return type of\n\tsort and reverse functions. (SF 1809220 / Bugzilla 1554)\n\n\t* dmd2/mtype.c: Ditto.\n\n\t* patch-gcc-4.1.x: Add patch for ARM exception handling int nested\n\tfunctions.\n\n\t* d-objfile.cc: Make DT data TREE_CONSTANT\n\n\t* dmd2/optimize.c: Fix for infinite recursion on initializer\n\twhen an error has already occurred.\n\n\t-----\n\n\tAdd support for ARM EABI.  Fix some missing items from\n\tcross-compilation changes.\n\n\t* d-lang.cc: Add \"Arm\" and \"Thumb\" version identifiers\n\n\t* phobos/unwind.d: Move pointer encoding to deh_pe.d. Move generic\n\tunwinder interface to unwind_generic.d.  Import either generic or\n\tARM interfaces based on config value.\n\n\t* phobos/unwind_generic.d, phobos/unwind_pe.d: New file; old code.\n\n\t* phobos/unwind_arm.d: New file.\n\n\t* phobos/deh.d: Support ARM exception handling ABI.\n\n\t* phobos/configure.in, frag-ac.in: Add config for ARM unwinder\n\n\t* phobos/configure.in, phobos/internal.c, phobos/monitor.c: Support\n\t\"no system\" targets.\n\n\t* phobos/cbridge_math.c: Correct identifier names for earlier\n\tchanges.\n\n\t* phobos/Makefile.am, phobos/Makefile.in, phobos/config.h.in,\n\tphobos/configure : Update.\n\n\t* phobos2/...: Duplicate phobos/ changes\n\n2007-10-07  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge cross-compilation changes to phobos2\n\n\t* phobos2/....: Merge\n\n\t---\n\n\tEnhance cross-compilation support:\n\n\t* phobos/Makefile.am, phobos/Makefile.in, phobos/acinclude.m4,\n\tphobos/aclocal.m4, phobos/configure.in, phobos/configure,\n\tphobos/config.h.in: Replace \"fragment generation\" with \"X3\"\n\tsystem.  Remove obsolete tests.\n\n\t* phobos/config/{config-head, config-mid, config-tail}: Removed\n\t* phobos/config/{makestruct.h, unix-head, unix-mid}: Removed\n\t* phobos/{darwin8, mingw, skyos}: Removed\n\n\t* phobos/config/{errno.x3, fpcls.x3, libc.x3, unix.x3},\n\tphobos/config{x3, x3.c, x3.h, x3main.c}:  New files\n\n\t* phobos/frag-ac.in: Now only contains boolean constants.\n\t* phobos/frag-math.in: New file.  Contains old configured math\n\tfunctions.\n\n\t* phobos/gcc/configext.d: Removed\n\t* phobos/gcc/support.d: Move fallback strtold definition here.\n\n\t* phobos/Makefile.am: Do not compile std/c/stdio.o\n\t* phobos/std/c/stdio.c: Change function definitions to external\n\tdeclarations.\n\n\t* phobos/gcc/deh.d, phobos/gcc/fpcls.d, phobos/gcc/fpmath.d,\n\tphobos/gcc/support.d, phobos/gcc/threadsem.d,\n\tphobos/internal/dgccmain2.d, phobos/internal/fpmath.d,\n\tphobos/internal/gc/gcgcc.d, phobos/phobos-ver-syms.in,\n\tphobos/std/c/dirent.d, phobos/std/c/math.d, phobos/std/c/stddef.d,\n\tphobos/std/c/stdio.d, phobos/std/c/stdlib.d, phobos/std/c/time.d,\n\tphobos/std/c/unix/unix.d, phobos/std/date.d, phobos/std/math.d,\n\tphobos/std/math2.d, phobos/std/mmfile.d, phobos/std/random.d,\n\tphobos/std/stdio.d, phobos/std/stream.d, phobos/std/system.d,\n\tphobos/std/thread.d: Update.  Add some support for targets\n\twithouth an operation system.\n\n2007-09-24  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-glue.cc (IndeExp::toElem), d-codegen.cc (arrayElemRef):\n\tPut the BIND_EXPR \"inside the brackets\". (Bugzilla 1155)\n\n\t(StructLiteralExp::toElem): Handle NULL elements (for anonymous\n\tunions.)\n\n2007-09-23  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.{h,cc}, d-glue.cc: Add type to error_mark_node\n\tfor code that assumes the type of certain expressions.\n\t(Bugzilla 1051)\n\n\t* d-glue.cc (FuncDeclaration::toObjFile): Set DECL_IGNORED_P\n\ton the frame paramter.  (Bugzilla 1033)\n\n\t* d-glue.cc, d-codegen.cc, d-objfile.cc: Set DECL_IGNORED_P\n\tin most cases where DECL_ARTIFICIAL is set.\n\n\t* d-builtins2.cc (d_gcc_magic_builtins_module): Handle type\n\tdeclarations after converting functions.\n\n\t* d-glue.cc (make_assign_math_op): Special case for division\n\twhen lhs is imaginary. (Bugzilla 739)\n\n\t* dmd-script: Apply Ander's patch for implicit -H and -D\n\tbehavior.  (Bugzilla 1502)\n\n\tUse of -of argument does not depend on header generation.\n\t(Bugzilla 1501)\n\n\t* d-builtins2.cc,  dmd*/module.c: If the target va_list is a\n\tstruct, add the struct declaration to the object module.\n\t(Bugzilla 1507)\n\n\t* dmd2/parse.c: fix line endings\n\n\t----\n\n\tUpdate for D 2.0:\n\n\t* Make-lang.in: Support both DMD front end version 1 and 2.\n\tReplace gcc-mars.cc with  d/mars.c.\n\n\t* gcc-mars.cc: Remove file.\n\n\t* d-codegen.h, d-codegen.cc: Update for DMD 2.x.\n\tAdd _d_hidden_func libcall.\n\n\t* d-decls.cc, d-glue.cc: Update for DMD 2.x.\n\n\t* d-dmd-gcc.h: Add rtlsym, etc.\n\n\t* d-lange.cc: Include mars.h.  Implement rtlsym.\n\n\t* d-objfile.cc (ObjectFile::hasModule): Add checks to allow\n\tthis function to be called earlier.\n\n\t* dmd*/mars.c: Make changes for GDC.\n\n\t* dmd*/attrib.c: Use WANTinterpret for pragma(GNU_asm)\n\n\t* dmd2/parse.c (parseDeclarator): Fix aliasing bug.\n\n\t* rdmd.d: Update for D 2.0\n\n\t* gdc-version: now only contains the GDC version\n\n\t* setup-gcc.sh: Support building D version 1 or 2.  Take DMD\n\tversion from dmd*/mars.c.\n\n\t* dmd2/, phobos2/: New directories\n\n\t* phobos2/Makefile.am (MAIN_OBJS): add std.c.stdio module\n\tfor std{in,out,err} vars\n\n\t* phobos*/std/c/stdio.d: Make functions with definitions\n\textern(D).\n\n\t* phobos2/std/loader.d: Update for D 2.0.\n\n\t* phobos2/std/hiddenfunc.d: Use C calling conventions for GDC.\n\n2007-09-14  David Friedman  <dvdfrdmn@users.sf.net>\n\n\n\t* d-codegen.cc (convertTo, call): Prevent multiple re-evaluation\n\tof delgate. (Bugzilla 1492)\n\n2007-09-13  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-glue.cc, d-codegen.h, d-codegen.cc: Make it an error\n\tto reference a nested function without a body. (SF 1793594)\n\n2007-09-12  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/config/ldfuncs-ppclinux: Declare sqrt.\n\n\t* target-ver-syms.sh, phobos/acinclude.m4, phobos/configure.in:\n\tSupport kfreebsd.\n\n\t* d-codegen.{h, cc}, d-glue.cc: Change rawArray to toDArray. Do\n\tnot cast result to void[]. (Bugzilla 1490)\n\n2007-09-07  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/std/c/stdio.d: Define fpos_t correctly for Drawin\n\t(Bugzilla 1469)\n\n2007-09-05  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD 1.021\n\n\t* dmd-script, d-spec.c (lang_specific_driver): Support\n\t-debuglib= and -defaultlib= options.\n\n\t* dmd/cast.c, dmd/constfold.c, dmd/declaration.c, dmd/dsymbol.c,\n\tdmd/expression.c, dmd/expression.h, dmd/func.c, dmd/identifier.c,\n\tdmd/idgen.c, dmd/init.c, dmd/init.h, dmd/interpret.c, dmd/lexer.c,\n\tdmd/lexer.h, dmd/link.c, dmd/mars.c, dmd/mars.h, dmd/parse.c,\n\tdmd/statement.c, dmd/staticassert.c, dmd/template.c: Merge\n\n\t* internal/object.d, phobos/internal/trace.d, phobos/object.d,\n\tphobos/std/c/windows/windows.d, phobos/std/date.d,\n\tphobos/std/regexp.d, phobos/std/windows/registry.d: Merge\n\n\t---\n\n\t* phobos/std/stdio.d (readln): Use the result of getdelim\n\tcorrectly. (SF 1788195)\n\n\t* d-glue.cc (FuncDeclaration::toObjFile): Do not gimplify if\n\tthere were errors (Bugzilla 1415)\n\n2007-08-31  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-objfile.cc (outdata): Do not set TREE_CONSTANT on initializers\n\t(Bugzilla 1453)\n\n2007-08-29  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-decls.cc (uniqueName): Allow multiple static declaration with\n\tthe same name if in a function. (SF 1783085)\n\n2007-08-28  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.cc (call): Use CommaExp correctly. (Bugzilla 1443)\n\n\t* dmd/todt.c (createTsarrayDt): Don't take quadratic time to build\n\tthe initializer. (Bugzilla 1440)\n\n2007-08-22  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tRelease GDC 0.24\n\n\t---\n\n\t* rdmd.d: Fix for Windows\n\n2007-08-21  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* GDC.html, History, README, gcc-mars.cc, gdc-version:\n\tUpdate for 0.24\n\n\t* rdmd.d, rdmd.1: New files. (Bugzilla 1152)\n\n\t* patch-build_gcc-4.0: Build universal rdmd. (Bugzilla 1152)\n\n\t* package/simple.sh: Install rdmd. (Bugzilla 1152)\n\tInstall man pages for MacOS build.\n\n\t* dmd-script: Apply Ander's patch to make -op apply\n\tto interface files. (Bugzilla 1137)\n\n\t* d-lang.cc (d_parse_file): In -fall-sources mode,\n\tonly generate an interface file for the -fonly module.\n\n\t* phobos/internal/adi.d (_adReverseChar, _adReverseWchar):\n\tMake sure stride difference is signed.\n\n2007-08-20  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* patch-gcc-4.1.x, patch-gcc-4.0.x: Fix botched patches.\n\n2007-08-05  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.cc (convertForArgument): Recognize\n\tpointer arithmetic expression as reference.\n\t(Bugzilla 1400)\n\n\t* d-glue.cc (DotVarExp::toElem): Do not NOP_EXPR\n\tthe result. (Bugzilla 1398)\n\n2007-07-27  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/std/stdio: Fix breakage from last commit.\n\t(SF 1761989)\n\n2007-07-26  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/std/c/stdio.d: Change import for gcc.config\n\n\t* d-lang.cc: add flag_iso for target macros\n\n\t* patch-gcc-4.0.x:  (gcc/tree-sra.c): Do not use SRA\n\ton structs with aliased fields created for anonymous\n\tunions.  (Followup to Bugzilla 1034)\n\n2007-07-25  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-lang.cc: implement d_gcc_is_target_win32\n\n\t* dmd/parse.c (parseLinkage): use d_gcc_is_target_win32\n\n\t* d-dmd-gcc.h (d_gcc_is_target_win32): added\n\n2007-07-24  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD 1.019 - 1.020\n\n\t* dmd/attrib.c, dmd/cast.c, dmd/constfold.c, dmd/declaration.h,\n\tdmd/expression.c, dmd/expression.h, dmd/func.c, dmd/idgen.c,\n\tdmd/inline.c, dmd/interpret.c, dmd/mars.c, dmd/mars.h,\n\tdmd/mtype.c, dmd/mtype.h, dmd/opover.c, dmd/parse.c,\n\tdmd/template.c, dmd/template.h, dmd/tocsym.c, dmd/toir.c: Merge\n\n\t* phobos/internal/gc/gc.d, phobos/linux.mak,\n\tphobos/std/demangle.d, phobos/std/format.d, phobos/std/loader.d,\n\tphobos/std/socket.d, phobos/std/uni.d: Merge\n\n2007-07-22  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD 1.015 - 1.018:\n\n\t* dmd/lexer.c (escapeSequence): Change vendor string.\n\n\t* dmd-script: Update documentation link\n\n\t* dmd/attrib.c, dmd/cast.c, dmd/class.c, dmd/declaration.c,\n\tdmd/dsymbol.c, dmd/expression.c, dmd/expression.h, dmd/func.c,\n\tdmd/hdrgen.h, dmd/idgen.c, dmd/init.c, dmd/init.h, dmd/inline.c,\n\tdmd/interpret.c, dmd/lexer.c, dmd/mars.c, dmd/mars.h,\n\tdmd/module.c, dmd/mtype.c, dmd/mtype.h, dmd/optimize.c,\n\tdmd/parse.c, dmd/scope.c, dmd/scope.h, dmd/statement.c,\n\tdmd/statement.h, dmd/staticassert.c, dmd/template.c: Merge\n\n\t* phobos/internal/dmain2.d, phobos/internal/gc/gcx.d,\n\tphobos/internal/object.d, phobos/object.d, phobos/std/bind.d,\n\tphobos/std/compiler.d, phobos/std/date.d, phobos/std/dateparse.d,\n\tphobos/std/format.d, phobos/std/intrinsic.d, phobos/std/loader.d,\n\tphobos/std/math2.d, phobos/std/metastrings.d, phobos/std/mmfile.d,\n\tphobos/std/outbuffer.d, phobos/std/string.d,\n\tphobos/std/windows/registry.d, phobos/win32.mak: Merge\n\n\t----\n\n\t* gdc_alloca.h: Support OpenBSD. (Bugzilla 1065)\n\n\t* patch-gcc-4.1.x (gcc/tree-sra.c): Do not use SRA\n\ton structs with aliased fields created for anonymous\n\tunions.  (Bugzilla 1034)\n\n2007-07-19  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* patch-gcc-4.1.x (gcc/predict.c): Add null-pointer check.\n\t(Bugzilla 1035)\n\n\t---\n\n\t* phobos/std/format.d (doFormatPtr): Fix accidental\n\treversion from DMD merge.\n\n\t* d-codegen.cc (maybeSetUpBuiltin): Add some missing\n\tinstrinsics.\n\n\t* phobos/Makefile.am (MAIN_OBJS): Add gcc.builtins\n\tmodule to get built-instruct initializers.\n\n\t* phobos/Makefile.in: Regenerated\n\n\t* d-lang.cc (d_parse_file): Call d_gcc_magic_module\n\tfor each module on the command line.\n\n\t* d-builtins2.cc (d_gcc_magic_builtins_module): output\n\tdeclaration other than funcs\n\n2007-07-16  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* dmd/todt.c (StructLiteralExp::toDt): Use target_size_t\n\tas in StructInitializer::toDt.\n\n\tBugzilla 1032:\n\n\t* dmd/todt.c: Use DT_container for arrays, array elements,\n\tand structs\n\n\t* dt.h, d-objfile.cc: Add DT_container / dtcontainer\n\n2007-07-14  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.cc (ArrayScope::setArrayExp, finish): Handle\n\tconstant lengths.  (Bugzilla 1031)\n\n2007-07-13  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.cc (toElemLvalue): Use toElemLvalue recursively.\n\t(Bugzilla 1191)\n\n\t* d-codegen.cc (twoFieldCtor): Only set TREE_READONLY if\n\tTREE_CONSTANT\n\n\t* d-glue.cc (array_set_expr, AssocArrayLiteralExp::toElem,\n\t(StructLiteralExp::toElem, NullExp::toElem):\n\tDo not set TREE_READONLY.\n\n\t* d-glue.cc (NewExp::toElem): Do not set TREE_READONLY on\n\tnew array dimensions.\n\n\t* d-codegen.cc (darrayVal): Do not set TREE_READONLY.\n\t(Bugzilla 1329)\n\n\t(delegateVal): ditto\n\n\t* d-codegen.cc (FieldVisitor::visit): Handle classes that\n\tare forward references. (Bugzilla 1325)\n\n\t* dmd-script: Pass -J option correctly.\t(SF 1721435)\n\n\t* d-glue.cc (DeleteExp::toElem): Handle interfaces.\n\t(SF 1721496)\n\n\t* d-decls.cc (VarDeclaration::toSymbol): Handle void initializer.\n\t(SF 1749622)\n\n\t* d-glue.cc (AndAndExp, OrOrExp): Handle void second expression.\n\t(SF 1689634)\n\n\t* phobos/gcc/cbridge_time.c (_d_gnu_cbridge_tza): Remove\n\tdaylight saving time offset from tm_gmtoff (Bugzilla 1208)\n\n\t* phobos/std/format.d (doFormat): Use original signature.  Actual\n\twork is done by new doFormatPtr. (Bugzilla 1109)\n\n\t* phobos/std/boxer.d: Use doFormatPtr\n\n2007-07-11  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-convert.cc (default_conversion): make public\n\t(SF 1711324 and 1709602)\n\n\t* d-apple-gcc.c (build_function_call): re-enable some code\n\n2007-05-08  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-apple-gcc.c: Remove a variable that is now defined in d-lang.c\n\n\t* d-lang.cc: Fix for other GCC versions.\n\n\t* d-c-stubs.c: New file.\n\n\t* Make-lang.in (D_BORROWED_C_OBJS): Always use C_TARGET_OBJS.  Add\n\tstubs for C compiler to allow linking target-specific preprocessor\n\tdefines.\n\n2007-05-05  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.cc (hwi2toli, getTargetSizeConst): Fix 2x wide int to\n\tlong int conversion.\n\n\t* dmd/cast.c (implicitConvTo): Use GCC floating point\n\troutines instead of native.\n\n\t* d-gcc-real.cc (toInt): Correctly convert to long integer\n\n\t* Make-lang.in (D_DMD_H): Add d-gcc-real.h\n\n\t* phobos/internal/dgccmain2.d: Print newline after error message\n\n2007-04-29  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD 1.014:\n\n\t* dmd/aggregate.h, dmd/constfold.c, dmd/delegatize.c, dmd/enum.c,\n\tdmd/enum.h, dmd/expression.c, dmd/expression.h, dmd/idgen.c,\n\tdmd/inline.c, dmd/interpret.c, dmd/lexer.c, dmd/lexer.h,\n\tdmd/mars.c, dmd/mtype.c, dmd/optimize.c, dmd/struct.c,\n\tdmd/template.c, dmd/tocsym.c, dmd/todt.c, dmd/toobj.c,\n\tdmd/typinf.c: Merge.\n\n\t* phobos/internal/gc/gc.d, phobos/internal/gc/gcx.d,\n\tphobos/std/format.d, phobos/std.ddoc: Merge.\n\n\t* d-glue.d (StructLiteralExp::toElem): implement\n\t* d-decls.d (EnumDeclaration::toInitializer): copy from tocsym.c\n\n\t------------\n\n\tMerge DMD 1.013:\n\n\t* dmd/cast.c, dmd/constfold.c, dmd/declaration.c,\n\tdmd/expression.c, dmd/expression.h, dmd/interpret.c, dmd/link.c,\n\tdmd/mars.c, dmd/mtype.c, dmd/opover.c, dmd/optimize.c,\n\tdmd/parse.c, dmd/port.h, dmd/statement.c: Merge.\n\n\t* phobos/internal/aaA.d, phobos/internal/switch.d,\n\tphobos/std/date.d, phobos/std/file.d, phobos/std/format: Merge.\n\n\t* d-codegen.h, d-codegen.cc: add _d_assocarrayliteralTp\n\t* d-glue.cc (AssocArrayLiteralExp::toElem): Implement.\n\n\t* phobos/internal/aaA.d (_d_assocarrayliteralT): modified\n\tto use pointers to keys, values.\n\n\t--------------\n\n\tMerge DMD 1.012:\n\n\t* arraytypes.h, dmd/declaration.c, dmd/delegatize.c,\n\tdmd/expression.c, dmd/expression.h, dmd/init.c, dmd/init.h,\n\tdmd/inline.c, dmd/interpret.c, dmd/lexer.c, dmd/lexer.h,\n\tdmd/mangle.c, dmd/mars.c, dmd/optimize.c, dmd/template.c,\n\tdmd/template.h: Merge\n\n\t* phobos/internal/object.d: Merge\n\n\t* dmd/template.c (TemplateInstance::mangle): printf portability\n\n\t* d-glue.cc (AssocArrayLiteralExp::toElem): non-working implementation\n\n2007-04-28  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD 1.011:\n\n\t* dmd/access.c, dmd/aggregate.h, dmd/arraytypes.h, dmd/attrib.c,\n\tdmd/attrib.h, dmd/bit.c, dmd/cast.c, dmd/class.c, dmd/complex_t.h,\n\tdmd/cond.c, dmd/cond.h, dmd/constfold.c, dmd/declaration.c,\n\tdmd/declaration.h, dmd/delegatize.c, dmd/doc.c, dmd/doc.h,\n\tdmd/dsymbol.c, dmd/dsymbol.h, dmd/dump.c, dmd/entity.c,\n\tdmd/enum.c, dmd/enum.h, dmd/expression.c, dmd/expression.h,\n\tdmd/func.c, dmd/hdrgen.c, dmd/hdrgen.h, dmd/html.c, dmd/html.h,\n\tdmd/identifier.c, dmd/identifier.h, dmd/idgen.c, dmd/impcnvgen.c,\n\tdmd/import.c, dmd/import.h, dmd/inifile.c, dmd/init.c, dmd/init.h,\n\tdmd/inline.c, dmd/interpret.c, dmd/lexer.c, dmd/lexer.h,\n\tdmd/link.c, dmd/macro.c, dmd/macro.h, dmd/mangle.c, dmd/mars.c,\n\tdmd/mars.h, dmd/module.c, dmd/module.h, dmd/mtype.c, dmd/mtype.h,\n\tdmd/opover.c, dmd/optimize.c, dmd/parse.c, dmd/parse.h,\n\tdmd/scope.c, dmd/scope.h, dmd/statement.c, dmd/statement.h,\n\tdmd/staticassert.c, dmd/staticassert.h, dmd/struct.c,\n\tdmd/template.c, dmd/template.h, dmd/tocsym.c, dmd/todt.c,\n\tdmd/toir.c, dmd/toir.h, dmd/toobj.c, dmd/total.h, dmd/typinf.c,\n\tdmd/unialpha.c, dmd/utf.c, dmd/utf.h, dmd/version.c, dmd/version.h:\n\tMerge\n\n\t* phobos/internal/gc/gc.d, phobos/internal/gc/gcx.d,\n\tphobos/internal/object.d, phobos/std/c/locale.d,\n\tphobos/std/stdio.d, phobos/std/windows/registry.d: Merge\n\n\t* dmd/expression.c: Comment out some logging code.\n\t* d-builtins2.cc: Update and fix handling of built-in structs.\n\t* d-codegen.cc, d-glue.cc: Update\n\n\t----------------\n\n\tMerge DMD 1.010:\n\n\t* dmd/aggregate.h, dmd/class.c, dmd/declaration.c, dmd/doc.c,\n\tdmd/dsymbol.c, dmd/expression.c, dmd/expression.h, dmd/func.c,\n\tdmd/interpret.c, dmd/mars.c, dmd/scope.c, dmd/statement.c,\n\tdmd/template.c, dmd/template.h, dmd/todt.c: Merge.\n\n\t* phobos/internal/dmain2.d, phobos/internal/gc/gc.d,\n\tphobos/internal/gc/gcx.d, phobos/internal/gc/testgc.d,\n\tphobos/internal/object.d, phobos/object.d,\n\tphobos/std/c/linux/linux.d, phobos/std/c/stdio.d,\n\tphobos/std/file.d, phobos/std/gc.d, phobos/std/moduleinit.d,\n\tphobos/std/regexp.d, phobos/std/stdio.d, phobos/std/string.d,\n\tphobos/std.ddoc, phobos/win32.mak: Merge\n\n\t* dmd/mtype.c, phobos/internal/dgccmain2.d: Update.\n\t* d-glue.cc (gcc_d_backend_init): Update.\n\n\t* phobos/config/unix-mid, phobos/std/c/unix/unix.d: Moved dirent\n\tand stdio definitions out of configunix to std.c.unix.unix because\n\tof compilation problems.\n\n\t* phobos/internal/gc/gcx.d (GC.realloc, GC.extend, GC.free): Clear\n\tgcx.p_cache\n\n\t* phobos/std/stdio.d, phobos/frag-ac.in, phobos/configure.in:\n\t  Account for various configurations.\n\n\t* phobos/phobos-ver-syms.in: Remove GNU_Have_fwide\n\t* phobos/configure: Regenerate\n\n2007-04-22  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-gcc-includes.h, d-lang.cc: Add target-specific preprocessor\n\tsymbols to the list of D version symbols.\n\n\t* d-glue.cc (NewExp::toElem): Use NewExp::newtype (Bugzilla 1038)\n\n2007-04-16  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD 1.009 (from 1.007):\n\n\t* d-decls.c: Merge changes from dmd/tocsym.c\n\n\t* dmd/constfold.c, dmd/declaration.c, dmd/declaration.h,\n\tdmd/expression.c, dmd/expression.h, dmd/init.c, dmd/interpret.c,\n\tdmd/mangle.c, dmd/mars.c, dmd/mars.h, dmd/mtype.c,\n\tdmd/optimize.c, dmd/statement.c, dmd/staticassert.c,\n\tdmd/tocsym.c, dmd/todt.c: Merge changes.\n\n\t* phobos/std/path.d, phobos/std/string.d: Merge changes.\n\n\t----\n\n\t* d-builtins.c, d-builtins2.cc, d-lang.h: Reworked code to only\n\tconvert built-in functions when the gcc.builtins module is\n\timported.  RECORD_TYPE is now converted to a TypeStruct.  Fixed\n\tproblem that caused some functions to not be available.  Support\n\ttargets builtins.\n\n2007-03-11  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-decls.cc (ClassDeclaration::toSymbol): Do not set TREE_READONLY.\n\t(Bugzilla 1037)\n\n2007-03-10  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.cc (call): Handle CommaExp form of a delegate call\n\t(Bugzilla 1043)\n\n\t* d-decls.cc (VarDeclaration::toSymbol): Partial fix for Bugzilla 1044\n\n\t* dt.h, d-objfile.cc, dmd/typeinf.c: Only pad 32-bit words in RTTI if\n\tneeded. (Bugzilla 1045, 1046)\n\t* dmd/toobj.c: update\n\n\t* d-glue.cc, d-objfile.cc: Additional GCC 3.3.x cleanup\n\n\t----\n\n\t* ChangeLog, History, Make-lang.in, asmstmt.cc, d-builtins.c,\n\td-codegen.cc, d-convert.cc, d-decls.cc, d-gcc-includes.h,\n\td-gcc-real.cc, d-glue.cc, d-gt.c, d-irstate.cc, d-lang.cc,\n\td-lang.h, d-misc.c, d-objfile.cc, d-spec.c, phobos/configure.in,\n\tsetup-gcc.sh: Remove support for GCC 3.3.x\n\n\t* phobos/configure: Regenerated\n\n\t* gcc-3.3.5-framework-headers.patch,\n\tgcc-3.3.5-framework-linker.patch, patch-gcc-3.3.x,\n\tpatch-gcc-darwin-eh-3.3.x, patch-toplev-3.3.x,\n\tphobos/config/ldfuncs33, phobos/config/noldfuncs33,\n\td-bi-attrs-33.h: Removed.\n\n2007-03-05  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tRelease GDC 0.23\n\n\t* phobos/Makefile.am: Add all-local target to build libgphobos.a\n\t* phobos/Makefile.in: Regenrated\n\n\tPowerPC 64 fixes:\n\n\t* d-glue.cc (TypeStruct:toCtype): Add words at the end of a struct.\n\n\t* phobos/config/darwin8/frag-unix: More accurate struct definitions.\n\t* phobos/internal/gc/gc_dyld.c: Support Mach-O 64.\n\t* phobos/internal/gc/gcgcc.d: Correct stack for 64-bit Darwin.\n\t* phobos/std/thread.d (getESP): Align result.\n\n2007-03-04  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tRest of DMD 1.007 Merge:\n\n\t* package/simple.sh: Install GDC.html\n\n\t* Make-lang.in (D_DMD_OBJS): add interpret.dmd.o\n\n\t* gdc-version: update\n\n\t* GDC.html, d-lang.cc, dmd-script, lang-specs.h, lang.opt,\n\tpatch-gcc-4.0.x, patch-gcc-4.1.x, patch-apple-gcc-4.0.x,\n\tpatch-gcc-3.4.x, patch-gcc-3.3.x: Add -J option.\n\n\t* dmd/constfold.d, dmd/declaration.h, dmd/func.c: update\n\n\t* d-glue.c: update\n\n\tInitial merge of DMD 1.007 (from DMD 1.005):\n\n\t* dmd/arraytypes.h, dmd/attrib.c, dmd/cond.c, dmd/constfold.c,\n\tdmd/declaration.c, dmd/declaration.h, dmd/expression.c,\n\tdmd/expression.h, dmd/func.c, dmd/idgen.c, dmd/init.c,\n\tdmd/lexer.c, dmd/lexer.h, dmd/mars.c, dmd/mars.h, dmd/module.c,\n\tdmd/mtype.c, dmd/opover.c, dmd/optimize.c, dmd/parse.c,\n\tdmd/parse.h, dmd/statement.c, dmd/statement.h, dmd/template.c,\n\tdmd/typinf.c: Merge\n\n\t* phobos/internal/aApply.d, phobos/internal/aApplyR.d,\n\tphobos/internal/adi.d, phobos/internal/dmain2.d,\n\tphobos/internal/gc/gc.d, phobos/internal/gc/gcx.d,\n\tphobos/internal/gc/win32.d, phobos/internal/object.d,\n\tphobos/std/base64.d, phobos/std/c/string.d, phobos/std/c/time.d,\n\tphobos/std/c/windows/com.d, phobos/std/c/windows/windows.d,\n\tphobos/std/dateparse.d, phobos/std/demangle.d, phobos/std/file.d,\n\tphobos/std/format.d, phobos/std/regexp.d, phobos/std/stdio.d,\n\tphobos/std/stream.d, phobos/std/string.d, phobos/std/thread.d,\n\tphobos/std/utf.d: Merge\n\n\t* dmd/interpret.c: New file\n\n2007-03-03  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/std/c/darwin/darwin.d: Remove. (Bugzilla 984)\n\n\t* phobos/std/date.d: Cleanup\n\n\t* d-lang.cc: Evaluate BYTES_BIG_ENDIAN at runtime.\n\n\t* d-codegen.cc: Cleanup.\n\n\t* d-glue.cc: Initialize foreach key with zero, not default init.\n\n\t* patch-gcc-4.0.x, patch-gcc-4.1.x, patch-apple-gcc-4.0.x:\n\tPrevent emission of prologue and epilogue code for naked functions.\n\t(Bugzilla 1013)\n\n2007-03-02  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-lang.cc: Test BYTES_BIG_ENDIAN at runtime.\n\n\t* d-glue.cc (ForeachStatement::toIR): Initialize key to zero, not\n\tdefaultInit.\n\n\t* patch-build_gcc-4.0, phobos/acinclude.m4, phobos/configure.in,\n\tphobos/Makefile.am: Remove references to libgphobos.spec\n\n\t* phobos/Makefile.in, phobos/configure: Regenerate\n\n\t* patch-gcc-3.4.x, patch-gcc-3.3.x, patch-gcc-4.0.x,\n\tpatch-gcc-4.1.x, patch-apple-gcc-4.0.x: Support enabling\n\t-pthread option by default without 'unrecognized option'\n\terror message.\n\n\t* d-spec.c (lang_specific_driver): Enable -pthread option\n\n\t* phobos/libgphobos.spec.in: Remove\n\n2007-02-28  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/std/loader.d: Fix error\n\n2007-02-27  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* setup-gcc.sh: Create directory of links instead of a single\n\tlink.  No longer need to copy support files.\n\n\t* target-ver-syms.sh: Support targets with both 32-bit and\n\t64-bit modes.  Output preprocessor definitions instead of\n\tcommand line otions.\n\n\t* Make-lang.in: Put target-ver-syms.sh output in d-confdefs.h.\n\n\t* package/simple.sh: Handle multilib.\n\n\t* phobos/configure.in: Use Automake, multilib.\n\t* phobos/Makefile.am: New file.\n\t* phobos/acinclude.m4: Fix quoting.\n\n\t* phobos/Makefile.in, phobos/configure: regenerated\n\n\t* patch-gcc-3.3.x, patch-gcc-3.4.x, patch-gcc-4.0.x,\n\t  patch-gcc-4.1.x, lang-specs.h: Add %N spec code.\n\n\t* patch-build_gcc-4.0: Grab 64-bit libgphobos.a\n\n\t* dt.h, d-objfile.cc\n\t(dt_size): Change return type to target_size_t.  Use target_size_t.\n\t(dtnzeros, dtdword, dtxoff): Change count to target_size_t\n\t(dtabytes, dtnbytes, dtawords, dtnwords, dtnbits): Change count to size_t\n\t(dti32): added\n\n\t* d-todt.cc: Cleanup.\n\n\t* d-objfile.cc:\n\t(dt2node): use Type::tsize_t for DT_word and DT_xoff\n\n\t* d-glue.cc:\n\t(PtrExp::toElem): Use target_size_t for offset\n\t(gcc_d_backend_init): Set CLASSINFO_SIZE and Tindex.\n\t(AssignExp::toElem): Use tsize_t for _d_arraycopy arg\n\t(CaseStatement::toIR): (not really a 64-bit change) Use int32 for\n\tcase value to match libcall\n\t(CatAssignExp::toElem): cleanup (not 64-bit)\n\t(ForeachStatement::toIR): fix bug in key increment expression\n\n\t* d-codegen.{cc,h}\n\t(AggLayout::addField): use target_size_t for offset\n\n\t* d-codegen.cc:\n\t(...): LIBCALL_ARRAYCAST: Use size_t args (libcall already uses size_t)\n\tLIBCALL_ARRAYCOPY: ditto\n\t(convertTo): Use Type::tsize_t for _d_arraycat arguments\n\n\t* d-decls.cc\n\t(ClassDeclaration::toVtblSymbol): Use Type::tindex for array size.\n\t(FuncDeclaration::toThunkSymbol): Use target_ptrdiff_t\n\n\t* lang.opt: add -fmultilib-dir\n\n\t* d-lang.cc: Use -fmultilib-dir\n\n\t(d_init): Set global.params.isX86_64 if TARGET_64BIT.\n\tSet CPU version symbol according to TARGET_64BIT.\n\tRemove BitsPerPointer and BitsPerWord version symbols.\n\n\t* d-builtins2.cc\n\t(d_gcc_magic_builtins_module): Change \"abi\" integer types\n\tto \"C\".  Add \"pointer\" integer types.\n\t(gcc_type_to_d_type): Use Type::tindex for array types.  Use whole\n\tback-end size.\n\n\t* symbol.h\n\t(Thunk): Use target_ptrdiff_t for offset.\n\n\t* dmd/mars.h: Define target_size_t and target_ptrdiff_t to allow use of\n\t32-bit size-tracking variables when generating 32-bit code.\n\n\t* dmd/aggregate.h:\n\t(CLASSINFO_SIZE) change to 'extern int' %%....\n\t* dmd/cast.d: Use target_ptrdiff_t with isBaseOf.\n\n\t* dmd/class.c:\n\t(ClassDeclaration::semantic): use PTRSIZE\n\t(InterfaceDeclaration::semantic): Use sc->offset = PTRSIZE * 2 instead of\n\t8 -- not sure what this is for...\n\n\t* dmd/dsymbol.[ch]\n\t(Dsymbol::size): Change to target_size_t\n\n\t* dmd/init.h: ArrayInitializer::dim <- chg to target_size_t\n\n\t* dmd/aggregate.h: Use target_ptrdiff_t and target_size_t\n\n\t* dmd/typinf.c (TypeInfoStructDeclaration::toDt): Use dti32 for flags.\n\t* dmd/toobj.c (Module::genmoduleinfo, ClassDeclaration::toObjFile,\n\tInterfaceDeclaration::toObjFile): ditto\n\n\t* dmd/func.c: Use target_ptrdiff_t with isBaseOf.\n\t(NewDeclaration::semantic): Allow Type::tuns64 if 64-bit.\n\n\t* dmd/mtype.c\n\t(Type::init): set CLASSINFO_SIZE\n\t(Type::dotExp): use Type::tsize_t for .offsetof property\n\t(TypeArray::dotExp): use Type::tsize_t for _adReverse args\n\t(TypeAArray::dotExp): use PTRSIZE to align keysize\n\t(TypeStruct::dotExp): use Type::tsize_t for offset\n\t(TypeStruct::alignsize): use target_size_t\n\n\t* dmd/mtype.h: Add Tindex global variable.\n\t(Type): Change tindex to baseic[Tindex].\n\t(Type::isBaseOf): use target_ptrdiff_t\n\n\t* dmd/expression.[ch]:\n\t(SymOffExp): offset changed to target_size_t\n\t(NewExp::semantic): use size_t as argument\n\t(ArrayLiteralExp::toMangleBuffer, SymOffExp::toCBuffer): fix printf\n\n\t* dmd/declaration.c\n\t(VarDeclaration::semantic): use sinteger_t for dim\n\n\t* dmd/declaration.h:\n\t(Declaration::size): Use target_size_t\n\t(VarDeclaration): Use target_size_t for offset\n\n\t* dmd/schope.h:\n\t(Scope::offset) Use target_size_t.\n\n\t* dmd/statement.c:\n\t(ForeachStatement::semantic): Change return value of _a*Apply* to\n\tType::tint32.  Fix logic for allowed index variable types.\n\tUse PTRSIZE to align keysize.\n\n\t* dmd/struct.c\n\t(AggregateDeclaration::addField): use target_size_t\n\n\t* dmd/todt.c\n\t(StructInitializer::toDt): Use target_size_t for offsets\n\t(ClassDeclaration::toDt2): Use PTRSIZE\n\n\t* phobos/object.d, phobos/internal/object.d:\n\t(Interface): Use ptrdiff_t for offset.\n\t(*.toHash): cast pointer to size_t\n\n\t* phobos/internal/object.d: Use integer type definitions from\n\tphobos/object.d.  Split %.*s args.\n\n\t* phobos/internal/adi.d:\n\t(_adReverse): Use size_t for szelem.\n\t* phobos/configure.in: fix multilib dir\n\t* phobos/configure: updated\n\n\t* phobos/config/cb_unix.c: Removed.\n\n\t* phobos/config/gen_config1.c: Add ssize_t.\n\n\t* phobos/config/config-head: Use __builtin_Clong and __builtin_Culong.\n\t* phobos/config/config-mid: Support X86_64 and other 64-bit CPUs.\n\t* phobos/config/unix-mid: Some size_t and ssize_t arg/return type fixes.\n\n\t* phobos/config/darwin8/frag-gen, phobos/config/darwin8/frag-unix:\n\tSupport 32- and 64-bit.\n\t* phobos/config/mingw/frag-unix, phobos/config/skyos/frag-unix:\n\tAdd ssize_t.\n\n\t* phobos/gcc/builtins.d: Update documentation\n\n\t* phobos/gcc/unwind.d: Use different builtin integer types.\n\n\t* phobos/internal/arraycat.d (_d_arraycopy): use size_t arg\n\n\t* phobos/std/c/fenv.d: Add field for 64-bit Linux.\n\n\t* phobos/std/c/linuxextern.d: Use C long for timezone.\n\n\t* phobos/std/c/stdio.d,\n\t  phobos/std/c/stdlib.d, phobos/std/c/math.d,\n\t  phobos/std/c/time.d: use C long types\n\n\t* phobos/std/stdint.d: Add C long types.\n\tUse ptrdiff_t and size_t for *intptr_t types.\n\n\t* phobos/std/format.d: Formatting structs on X86_64 looses\n\n\t* phobos/internal/cast.d (_d_isbaseof2): change offset to size_t\n\n\t* phobos/internal/fpmath.d: Support 64-bit CPUs.\n\n\t* phobos/std/file.d: Type of stat.st_size may vary; use auto.\n\t(Unix read): Make sure file's size is within range.\n\n\t* phobos/crc32.d, phobos/gcstats.d,\n\tphobos/internal/qsortg.d:\n\tphobos/internal/gc/gc.d (_d_arraycatnT),\n\tphobos/internal/gc/gcold.d (_d_arraycatn),\n\tphobos/internal/gc/gcx.d,\n\tphobos/internal/mars.h,\n\tphobos/std/base64.d, phobos/std/bitarray.d, phobos/std/math.d,\n\tphobos/std/math2.d, phobos/std/md5sum.d, phobos/std/outbuffer.d,\n\tphobos/std/path.d, phobos/std/string.d, phobos/std/uri.d\n\tphobos/std/typeinfo/ti_AC.d,\n\tuse size_t, ptrdiff_t/ssize_t\n\n\t* phobos/std/loader.d: Add definitions for 64-bit Mach-O objects.\n\n\t* phobos/std/openrj.d, phobos/std/loader.d, phobos/std/moduleinit.d,\n\tphobos/std/socket.d, phobos/std/regexp.d, phobos/std/uri.\n\td, phobos/std/zip.d: split '%.*s' args\n\n\t* phobos/std/typeinfo/ti_A*.d, phobos/std/typeinfo/ti_ptr.d:\n\tfix compare methods\n\n\t* phobos/internal/gc/gc_dyld.c: use uintptr_t\n\n\t* phobos/std/c/stdio.d, phobos/internal/gc/gcgcc.d:\n\tDon't use old version symbols.\n\n\t* phobos/std/c/mach/mach.d (natural_t): always a uint\n\n\t* phobos/etc/c/zlib.d: use Culog_t\n\n2007-02-13  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* setup-gcc.sh: Copy the removed files from the top-level\n\tdirectory.\n\n2007-02-10  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/config.guess, phobos/config.sub, phobos/install-sh:\n\tRemove files.\n\n\t* phobos/std/format.d (putAArray): account for\n\talignment of the value\n\n\t* phobos/Makefile.in: fix metastrings.o\n\n2007-02-09  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/std/format.d (doFormat): use aligntsize\n\n\tRest of DMD 1.005 merge:\n\n\t* phobos/Makefile.in (MAIN_OBJS): add metastrings.o\n\n2007-02-08  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-lang.cc, lang.opt: support -v1 option\n\n\t* lang.opt (d_init_options): set global.params.Dversion\n\n\t* dmd-script: -v1 -> -fd-version=1\n\n\t* phobos/std/format.d (doFormat): Fix for var args differences\n\n\tInitial merge of DMD 1.005:\n\n\tdmd/attrib.c, dmd/attrib.h, dmd/cast.c, dmd/cond.c,\n\tdmd/constfold.c, dmd/dsymbol.c, dmd/dsymbol.h, dmd/expression.c,\n\tdmd/expression.h, dmd/func.c, dmd/idgen.c, dmd/inline.c,\n\tdmd/lexer.c, dmd/lexer.h, dmd/mars.c, dmd/module.c, dmd/mtype.c,\n\tdmd/mtype.h, dmd/optimize.c, dmd/parse.c, dmd/parse.h,\n\tdmd/scope.c, dmd/statement.c, dmd/statement.h, dmd/template.c,\n\tdmd/template.h, dmd/toobj.c, dmd/typinf.c: Merge.\n\n\tphobos/internal/aaA.d, phobos/internal/gc/gc.d,\n\tphobos/internal/object.d, phobos/linux.mak, phobos/std/c/stdlib.d,\n\tphobos/std/conv.d, phobos/std/ctype.d, phobos/std/format.d,\n\tphobos/std/regexp.d, phobos/std/zlib.d, phobos/std.ddoc,\n\tphobos/win32.mak: Merge.\n\n\tphobos/std/metastrings.d: New file\n\n2007-02-05  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tRelease GDC 0.22\n\n\t* d-codegen.cc (twoFieldType): Fix back end -> front end type\n\tmapping.\n\n\t* Make-lang.in: Enable ELFOBJ to put some RTTI in the read-only\n\tdata section.\n\n\t* GDC.html: Update\n\n2007-02-04  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/gcc/cbridge_time.c (_d_gnu_cbridge_tza),\n\tphobos/std/date.d: Fix timezone adjust sign\n\n2007-02-03  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* phobos/config/unix-mid: Correctly initialize sockaddr*\n\t(Bugzilla 818)\n\n\t* dmd-script: Fix -H* options (Bugzilla 896).\n\tSupport -framework. Fix error message.\n\n\t* d-lang.cc (d_write_global_declarations), patch-gcc-4.1.x:\n\tFixes for dwarf2out ICEs\n\n\t* d-objfile.cc (check_static_sym): Fix setting TREE_CONSTANT.\n\n\tRest of DMD 1.004 merge:\n\n\t* gcc-mars.cc, gdc-version: Update\n\n\t* phobos/std/regexp.d: update\n\n\t* phobos/internal/gc/gcold.d (_d_newarrayip):\n\n\t* phobos/internal/gc/gc.d: Fix argument and result types.\n\n\t* phobos/config/unix-head, phobos/config/unix-mid: Update\n\n\t* phobos/Makefile.in: Update for files removed in DMD 1.004\n\n\t* d-decls.cc (TypedefDeclaration::toInitializer): Copy\n\tfrom dmd/tocsym.c.  Create the Sdt here.\n\n\t* dmd/toobj.c (TypedefDeclaration::toObjFile): Update\n\tfor toInitializer change\n\n\t* dmd/mtype.c (TypeArray::dotExp): Fix library call decls\n\n\t* d-lang.cc: Update\n\n\t* d-codegen.[ch], d-glue.cc: Update memory allocation library\n\tcalls.\n\n\t* d-lang.cc (d_write_global_declarations): call\n\temit_debug_global_declarations only for GCC 4.0\n\n\t* dmd/mtype.c (TypeArray::dotExp): update\n\n\t* phobos/config/unix-head, phobos/config/unix-mid: update\n\n\t* phobos/internal/gc/gcold.d: Use old GDC modifications.\n\n2007-02-02  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tInitial merge DMD 1.004:\n\n\t* dmd/aggregate.h, dmd/attrib.c, dmd/attrib.h, dmd/declaration.c,\n\tdmd/declaration.h, dmd/dsymbol.c, dmd/dsymbol.h, dmd/expression.c,\n\tdmd/import.c, dmd/import.h, dmd/inline.c, dmd/mars.c, dmd/mars.h,\n\tdmd/module.c, dmd/module.h, dmd/mtype.c, dmd/mtype.h,\n\tdmd/struct.c, dmd/template.c, dmd/template.h, dmd/tocsym.c,\n\tdmd/todt.c, dmd/toobj.c, dmd/typinf.c: Merge DMD 1.004\n\n\t* phobos/internal/aaA.d, phobos/internal/adi.d,\n\tphobos/internal/arraycast.d, phobos/internal/arraycat.d,\n\tphobos/internal/gc/gc.d, phobos/internal/gc/gcx.d,\n\tphobos/internal/gc/linux.mak, phobos/internal/gc/win32.mak,\n\tphobos/internal/object.d, phobos/linux.mak, phobos/object.d,\n\tphobos/std/c/linux/linux.d, phobos/std/compiler.d,\n\tphobos/std/file.d, phobos/std/gc.d, phobos/std/outbuffer.d,\n\tphobos/std/random.d, phobos/std/regexp.d,\n\tphobos/std/typeinfo/ti_AC.d, phobos/std/typeinfo/ti_Acdouble.d,\n\tphobos/std/typeinfo/ti_Acfloat.d, phobos/std/typeinfo/ti_Acreal.d,\n\tphobos/std/typeinfo/ti_Adouble.d, phobos/std/typeinfo/ti_Afloat.d,\n\tphobos/std/typeinfo/ti_Ag.d, phobos/std/typeinfo/ti_Aint.d,\n\tphobos/std/typeinfo/ti_Along.d, phobos/std/typeinfo/ti_Areal.d,\n\tphobos/std/typeinfo/ti_Ashort.d, phobos/std/typeinfo/ti_C.d,\n\tphobos/std/typeinfo/ti_cdouble.d, phobos/std/typeinfo/ti_cfloat.d,\n\tphobos/std/typeinfo/ti_char.d, phobos/std/typeinfo/ti_creal.d,\n\tphobos/std/typeinfo/ti_dchar.d, phobos/std/typeinfo/ti_delegate.d,\n\tphobos/std/typeinfo/ti_double.d, phobos/std/typeinfo/ti_float.d,\n\tphobos/std/typeinfo/ti_ptr.d, phobos/std/typeinfo/ti_real.d,\n\tphobos/std/typeinfo/ti_void.d, phobos/std/typeinfo/ti_wchar.d,\n\tphobos/win32.mak: Merge DMD 1.004\n\n\t* phobos/std/typeinfo/ti_Aa.d, phobos/std/typeinfo/ti_Adchar.d,\n\tphobos/std/typeinfo/ti_Aubyte.d, phobos/std/typeinfo/ti_Auint.d,\n\tphobos/std/typeinfo/ti_Aulong.d, phobos/std/typeinfo/ti_Aushort.d,\n\tphobos/std/typeinfo/ti_Awchar.d: Removed in DMD 1.004\n\n\t* phobos/internal/gc/gcold.d: New in DMD 1.004\n\n2007-02-01  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-lang.cc (d_write_global_declarations): Emit debug info.\n\n\t* d-codegen.cc (twoFieldType): Fix debugging information.\n\t* d-objfile.cc (initTypeDecl): Ditto.\n\n\t* d-glue.cc (PtrExp::toElem): Don't wrap the result in\n\ta NOP_EXPR.\n\n\t* Make-lang.in: Add d-tree.def to dependencies\n\n2007-01-30  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tGCC 4.1.x changes:\n\n\t* GDC.html, INSTALL, INSTALL.html, README: update\n\n\t* dmd/idgen.c, dmd/impcnvgen.c, dmd/mtype.h: Change to allow\n\tcompilation as C.\n\n\t* patch-gcc-4.1.x, patch-toplev-4.1.x: New files\n\n\t* Make-lang.in: Use $(version) instead of $(gcc_version).\n\tAdd d-bi-attrs-41.h.  Use C for generator programs instead of C++.\n\n\t* d-bi-attrs-41.h: New file.\n\n\t* d-builtins.c: update\n\n\t* d-builtins2.cc: Do not associate d_gcc_builtin_va_list_d_type with\n\tva_list_type_node.  Do this for GCC 4.0 and 4.1.\n\n\t* d-codegen.cc: Use CtorEltMaker.\n\t(maybeExpandSpecialCall): Cast d_gcc_builtin_va_list_d_type to\n\tva_list_type_node.\n\t(hostToTargetString): Update.\n\n\t* d-codegen.h: Add CtorEltMaker class for before/after 4.1.x\n\tcompatibility.\n\n\t* d-convert.cc: Add special case for pointer/int comparison\n\n\t* d-decls.cc: Do not use SET_DECL_ASSEMBLER_NAME for CONST_DECLs\n\n\t* d-gcc-includes.h: Include vec.h\n\n\t* d-glue.cc: Use CtorEltMaker.\n\t(gcc_d_backend_init): Call default_init_unwind_resume_libfunc\n\n\t* d-lang.cc: Add d_types_compatible_p hook for va_list conversion\n\n\t* d-lang.h: Update\n\n\t* d-objfile.cc: CtorEltMaker.\n\n\t* phobos/std/conv.d: Do not assume signed integer wraparound.\n\n2007-01-28  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-asm-i386.h, d-codegen.cc, d-gcc-real.cc,\n\td-decls.cc, d-glue.cc, d-lanc.cc: various fixes\n\n\t* d-codegen.cc, d-codegen.h, d-glue.cc, d-lang.h:\n\tRemove bit array code\n\n2007-01-27  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-asm-i386.h: fix fistp, lmsw, lldt, mov[sz]x, setCC, smsw, and\n\tsldt instructions (Bugzilla 836, 837, 838, 839, 841, 843, 844).\n\tAlso r[co][lr].\n\n\t* d-glue.cc (StringExp::toElem): Correct termination of wchar\n\tand dchar (Bugzilla 889)\n\n2007-01-11  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* INSTALL.html: fix corruption\n\n2007-01-03  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tRelease GDC 0.21\n\n\t* GDC.html: New file.\n\n\t* README: Update, refer to GDC.html\n\n\tRest of DMD 1.00 merge:\n\n\t* d-codegen.cc: Patch from Anders Bjrklund for GCC 3.3\n\n\t* d-glue.cc (FuncDeclaration::toObjFile): Fix shouldDefer/outputStage\n\tlogic.\n\n\t* dmd/attrib.c (PragmaDeclaration::semantic): uint -> unsigned\n\n\t* dmd/module.c (load): output to stdmsg\n\n\t* dmd/mtype.c: revert '@' mangling changes\n\n\t* gdc-version, gcc-mars.cc: update\n\n\t* phobos/config/unix-mid: Support more functions\n\n\t* phobos/acinclude.m4, phobos/config/gen_unix.c (c_pthread):\n\tSupport more types\n\n\t* phobos/configure, phobos/config.h.in: update\n\n\t* phobos/config/darwin8/frag-unix: update\n\n\tInitial merge of DMD 1.00:\n\n\t* dmd/cond.c, dmd/constfold.c, dmd/delegatize.c, dmd/dsymbol.c,\n\tdmd/enum.c, dmd/expression.c, dmd/expression.h, dmd/init.c,\n\tdmd/inline.c, dmd/mars.c, dmd/module.c, dmd/module.h, dmd/mtype.c,\n\tdmd/parse.c, dmd/statement.c, dmd/struct.c, dmd/template.c,\n\tdmd/todt.c: Merge 1.00\n\n\t* internal/gc/gc.d, phobos/linux.mak,\n\tphobos/std/c/linux/linux.d.orig-dmd, phobos/std/c/stdlib.d,\n\tphobos/std/conv.d, phobos/win32.mak: Merge 1.00\n\n\t* phobos/std/c/linux/pthread.d.orig-dmd: New file (originally\n\tpthread.d DMD)\n\n\t------------------------\n\n\t* dmd/init.c (ArrayInitializer::semantic),\n\t* dmd/root.c (OutBuffer::write4): 64-bit host cleanup\n\n\t* d-asm-i386.h: cleanup, saftey\n\n2007-01-02  DF  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.cc (convertTo): Use 64-bit for Tarray, Tsarray conversion.\n\n\t* d-codegen.{h, cc} (darrayVal): use uinteger_t arg\n\n\f\nCopyright (C) 2007 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2008",
    "content": "2008-12-12  Arthur Loiret  <arthur.loiret@u-psud.fr>\n\n\tBugzilla 929:\n\n\t* dmd/mtype.c: Provide isZeroInit() overload in TypeAArray that\n\treturns TRUE.\n\t* dmd/mtype.h: Add prototype for TypeAArray::isZeroInit().\n\n\t* dmd2/mtype.c, dmd2/mtype.h: Ditto.\n\n2008-07-21  David Friedman  <David Friedman>\n\n\t* dmd/root.c, dmd2/root.c: Fix earlier patching error.\n\n\t* phobos/config/x3.c, phobos2/config/x3.c: Fix problem when\n\tbuilding under MSYS.\n\n\t* config-lang.in: Remove lang_requires.\n\n2008-07-20  David Friedman  <David Friedman>\n\n\t* dmd/expression.c, dmd2/expression.c: Make integer conversion\n\tfix work for other hosts/targets.\n\n2008-07-20  Arthur Loiret  <arthur.loiret@u-psud.fr>\n\n\t* dmd/expression.c: Fix integer conversion routines on x86_64.\n\tPatch from downs <default_357-line@yahoo.de>, thanks!\n\t* dmd2/expression.c: Likewise.\n\n\t* config-lang.in: Add lang_requires=\"c c++\".\n\n2008-07-19  David Friedman  <David Friedman>\n\n\t* patches/patch-gcc-4.0.x, patches/patch-gcc-4.1.x: Fix infinite\n\tloop bug in patch.\n\t* patches/patch-apple-gcc-4.0.x: Ditto.\n\n\t* d-lang.cc: Do not assume D_OS_VERSYM is defined.\n\tHandle TARGET_xxx_CPP_BUILTINS macros for more targets.\n\n2008-07-17  David Friedman  <dvdfrdmn@users.sf.net>\n\n        * dmd-script: Append an exe suffix to executables when the\n        target is Windows.\n\n\t* phobos/gcc/deh.d, phobos2/gcc/deh.d: Fix for sjlj exceptions.\n\n2008-06-16  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-decls.cc: Correct logic for output constanting vars for V1.\n\n2008-06-01  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD.1.30 and 2.014\n\n\t* dmd-script: Implement -man, -lib and single-object features.\n\n\t* phobos2/Makefile.am: add bigint\n\n\t* phobos2/config/{ldfuncs,ldfuncs-darwin,ldfuncs-ppclinux,noldfuncs},\n\tMerge nanl change from std/c/math.d\n\n\t* phobos2/gcc/support.d: Merge std/c/math.d changes.\n\n\t* d-objfile.cc (obj_append): Implement.\n\t* phobos2/std/c/unix/unix.d: Merge linux.d and socket.d changes\n\n\t* d-glue.cc, d-irstate.cc, d-lang.cc: Update\n\n\t* dmd/..., dmd2/..., phbobos/..., phobos2/...: Merge\n\n2008-05-26  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* asmstmt.cc, d-decls.cc, d-glue.cc, d-misc.c, d-objfile.{cc, h}:\n\tFix for -combine compilation.  Remove fileContext global and clean\n\tup generation of unique symbol names.\n\n\t* phobos/internal/object.d: Correct merge error\n\n\t----\n\n\t* dmd-script, lang.opt, d-lang.cc, : support -ignore\n\n\tMerge DMD 1.029 and 2.013\n\n\t* phobos2/std/perf.d: use std.c.unix.unix\n\n2008-05-22  Arthur Loiret  <arthur.loiret@u-psud.fr>\n\n\t* target-ver-syms.sh: Add missing CPUs and fix\n\td_cpu_versym/d_cpu_versym64 for each.\n\n\t* d-lang.cc: Fix build on non biarched 64-bit archs (alpha, ia64, ...)\n\tand fix 64-bit cpu detection.\n\n\t* Move patch-* to patches/\n\t* setup-gcc.sh: Update.\n\n2008-05-10  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* lang-specs.h: Support a \"cc1d\" spec. (Bugzilla 2068)\n\n\tMerge DMD 1.028 and 2.012\n\n\t* d-codegen.{h,cc}: Add postblitting array libcalls.\n\n\t* phobos2/internal/arrayassign.d\n\t(_d_arraysetassign, _d_arraysetctor): Use size_t.\n\n\t* d-glue.cc (AssignExp::toElem): Postblit-aware code\n\n\t* phobos2/Makefile.am: Add arrayssign.d. Remove math2.d.\n\n\t* dmd/..., dmd2/..., phbobos/..., phobos2/...: Merge\n\n2008-05-03  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-dmd-gcc.h, d-glue.cc, dmd*/toobj.c: Cleanup: Remove unused\n\td_gcc_aggregate_dtors.\n\n2008-05-02  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD 1.027 and 2.011\n\n\t* termios.d: Point to std.c.unix.unix.  Leave original\n\ttermios.d as termios.d.orig-dmd\n\n\t* asmstsmt.cc: Implement blockExit\n\n\t* phobos2/config/unix.x3: Add termios stuff\n\n\t* phobos2/std/c/unix/unix.d: Merge new funcs from std.c.linux.d\n\n\t* d-objfile.cc: Implement stub obj_startaddress\n\n\t* d-glue.cc (ForStatement::toIR): condition may be NULL\n\t(DeleteExp::toIR): Use libcalls for interfaces\n\n\t* dmd*/clone.c, dmd*/e2ir.c: New files.\n\n\t* Make-lang.in: Add new clone.c\n\n\t* d-codegen.{h, cc}, d-glue.cc: Use _d_callinterfacefinalizer.\n\tAlso use _d_delinterface instead of casting.\n\n\t* dmd/..., dmd2/..., phbobos/..., phobos2/...: Merge\n\n2008-04-27  David Friedman  <dvdfrdmn@users.sf.net>\n\n\tMerge DMD 1.026 and 2.010\n\n\t* dmd/..., dmd2/..., phbobos/..., phobos2/...: Merge\n\n\t---\n\n\t* d-lang.cc (d_write_global_declarations): Make earlier change\n\tregarding cgraph_optimize only apply to 4.0.x.\n\n\t---\n\n\t* d-decls.cc (VarDeclartion::toSymbol): Change for\n\tV2 STCmanifest.  Make more constant vars have\n\tstatic storage (instead of making CONST_DECLs) in\n\tboth V1 and V2.\n\n\t* dmd2/constfold.c (Cmp): Compare wchar\tand dchar\n\tstrings portably.\n\n\t* asmstmt.cc (ExtAsmStatement::semantic): Heuristic\n\tfor evaluating operands:  If an input operand, evaluate.\n\n\t* d-asm-i386.h: Make previous change apply to V1.\n\n\t* d-glue.cc (TypeEnum::toCtype): Update.\n\n\tPhobos changes (applies to V2 Phobos as well):\n\n\t* phobos/Makefile.am, phobos/configure.in:\n\tDeal with strerror_r portability.\n\n\t* phobos/Makefile.in, phobos/configure, phobos/config.h.in:\n\tUpdated.\n\n\t* phobos/gcc/cbridge_strerror.c: New file.\n\n\t* phobos/std/c/string.d: Replace non-portable strerror_r with\n\t_d_gnu_cbridge_strerror.\n\n\t* phobos/std/file.d, phobos/std/loader.d, phobos/std/process.d,\n\tphobos/std/socket.d, phobos/std/stdio.d: Use\n\t_d_gnu_cbridge_strerror.\n\n\tMerge DMD 2.009:\n\n\t* dmd2/..., phobos2/...: Merge.\n\n\tMerge DMD 1.025:\n\n\t* dmd/..., phobos/...: Merge.\n\n2008-04-25  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* asmstmt.cc, d-asm-i386.h: Handle some other cases\n\tfor constant floating point operands.\n\n2008-04-19  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* dmd/toobj.c, dmd2/toobj.c (EnumDeclaration::toObjFile):\n\tOutput initializer correctly.\n\n\t* d-decls.cc (EnumDeclaration::toInitializer): Correctly\n\tset up initializer symbol. (Bugzilla 1746)\n\n2008-04-17  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* dmd/toobj.c (InterfaceDeclaration::toObjFile): Fix error.\n\t(Bugzilla 1844)\n\n2008-04-16  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-codegen.{h, cc}: Clean up nested function / nested class /\n\tclosure code.\n\n\t* phobos/std/c/stdlib.d, phobos2/...: Remove comment that hides\n\tatof. (Bugzilla 1888)\n\n2008-03-11  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* d-glue.cc: cleanup\n\n\t* dmd/expression.c (DotVarExp::semantic): Apply fix from dmd2/\n\n\t* dmd2/expression.c (DotVarExp::semantic): Move fix to\n\tbetter location.\n\n2008-03-09  David Friedman  <dvdfrdmn@users.sf.net>\n\n\t* dmd2/func.c (FuncDeclaration::needsClosure): Closures fix:\n\tChange test from isVirtual to isThis.\n\n\t* dmd2/expression.c (DotVarExp::semantic): Note change from DMD.\n\n\t----\n\n\t* patch-build_gcc-5465: Correctly build driver-driver\n\n\t* phobos*/Makefile.am (MAIN_OBJS): Add std/cover.o\n\n\t* phobos2/std/file.d: use 'mkdir -p' in unittest\n\n\t* d-builtins2.cc: Fixes for pointer-to-function types (for V2)\n\n\t* d-codegen.cc: Add _d_allocmemory libcall.\n\t(emitLocalVar): Rework.\n\t(var): New function to handle static-frame/closure variables\n\t(convertTo): Use typesSame instead of typesCompatible\n\t(assignValue): New function to handle Exp(v=value) vs. Exp(value)\n\t(getFrameForFunction, getFrameForNestedClass): New interface\n\tto get frames for nested functions.\n\t(functionNeedsChain): Return false for nested functions that\n\ttake closures.\n\n\t* d-decls.cc: Changes for const/invariant/STCinit\n\n\t* d-glue.cc: Use new interface for nested functions.  Use\n\tIRState::var instead of v->toSymbol()->Stree.  Create\n\tclosures.\n\n\t* d-lang.cc: Implement CONVERT_PARM_FOR_INLINING hook\n\n\t* d-objfile.cc: Add case for closure-using function when\n\tsetting the link-once attribute.\n\n\t* package/simple.sh: install .../include/d2\n\n\t* patch-build_gcc-4.0, patch-build_gcc-5465: Support D 2.0\n\tincludes and libraries.\n\n\t* phobos2/std/bitmanip.d: Apply previous bitarray.d changes.\n\n\t* phobos*/std/typeinfo/ti_ptr.d (getHash): Cast to hash_t.\n\n\t* d-decls.cc (VarDeclaration::toSymbol): For D 2.0, use\n\tisInvariant() and STCinit as criteria for making CONST_DECLs and\n\tsetting TREE_READONLY.\n\n\t* phobos2/std/c/linux/linux.d: Do not import std.c.dirent.\n\n\t* phobos2/std/c/dirent.d: Deprecated std.c.dirent.\n\n\t* phobos2/std/c/unix/unix.d: Move dirent/DIR routines here.\n\n\t* phobos*/std/c/darwin/ldblcompat.d: declare constants as 'string'\n\n\tMerge DMD 2.008:\n\n\t* dmd2/..., phobos2/...: Merge.\n\n\tMerge DMD 1.024:\n\n\t* phobos*/config/unix.x3: ensure MSG_NOSIGNAL is defined\n\n\t* dmd/..., phobos/...: Merge.\n\n\t------\n\n\t* patch-apple-gcc-4.0.x, patch-apple-gcc-5465: Include patch\n\tfor SRA pass like the other 4.x patches.\n\n\t* d-codegen.cc (convertTo): Ensure pointers are cast to an\n\tunsigned type.\n\n\t* d-objfile.cc (dt2tree_list_of_elems): Always generate a\n\tCONSTRUCTOR for struct data.\n\t(ObjectFile::ObjectFile): Use NULL_TREE for file context instead\n\tof TRANSLATION_UNIT_DECL.\n\n\t* d-lang.cc (d_write_global_declarations): Call\n\tdebug_hooks->global_decl before cgraph_optimize so that nested\n\tclass functions do not get passed to dwarf2out before the\n\touter class functions.\n\n\t* Rename patch-build_gcc-4.0 to patch-build_gcc-4.0.x\n\n\f\nCopyright (C) 2008 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2009",
    "content": "2009-12-28  michaelp  <baseball.mjp@gmail.com>\n\n\tMerge with DMD 1.043\n\n\t* phobos/configure.in: Changed part of phobos configure.\n\n\t* samples/README, samples/samples.sh: Uploading the start of the some\n\tsmall tests to help in the testing of GDC/D components.\n\n\t* Make-lang.in,\td-lang.cc, dmd/machobj.c, phobos/config/unix.x3,\n\tphobos/std/file.d, phobos/std/moduleinit.d, phobos/std/socket.d: Fixed\n\tproblem when building on Mac OS X.\n\n2009-12-05  michaelp  <baseball.mjp@gmail.com>\n\n\tMerge with DMD 1.042\n\n\t* Make-lang.in: Added async.dmd.o\n\n\t* d-asm-i386.h, d-codegen.h: Merge changes from\tdmd/constfold.c.\n\n\t* d-codegen.h, phobos2/aclocal.m4, phobos2/configure.in: Fixed\n\tproblems with D2.\n\n2009-11-22  michaelp  <baseball.mjp@gmail.com>\n\n\tMerge with DMD 1.041\n\n\t* Make-lang.in: Update for files added in DMD 1.041.\n\n\t* d-backendfunctions.c: Added stubs for functions in the backend that\n\tcannot be included in the front end source.\n\n\t* dmd-script: Added Bitbucket page to display for gdmd wrapper script.\n\n2009-11-07  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\tChanges to GCC-4.4.x branch:\n\n\t* tools/makewebstatistics.d: Added d tool to generate webstats about\n\tdstress in D2.\n\n2009-10-25  michaelp  <baseball.mjp@gmail.com>\n\n\tMerge with DMD 1.040\n\n\t* dmd/..., phobos/...: Now working for D1 (Not on GCC 4.3.4?)\n\n\t* asmstmt.cc: Merge from dmd/statement.c\n\n\t* phobos/acinclude.m4, phobos/configure.in, phobos/phobos-ver-syms.in:\n\tPosix is now defined.\n\n2009-10-24  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\t* dmd/attrib.c, dmd/cast.c, dmd/class.c, dmd/constfold.c,\n\tdmd/declaration.c, dmd/dsymbol.c, dmd/expression.c, dmd/toobj.c: Fixes\n\tsome errors in the DMD v1 frontend. Trying to fix DMD 1.039, but still\n\tno fix. The problem may be in phobos then.\n\n\tChanges to GCC-4.4.x branch:\n\n\t* d-lang.cc, d-lang.h setup-gcc.sh, patches/patch-gcc-4.4.x,\n\tpatches/patch-toplev-4.4.x: Applied Eldar patches for gcc 4.4.0\n\n2009-10-07  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\t* dmd2/attrib.c, dmd2/class.c, dmd2/declaration.c, dmd2/doc.c,\n\tdmd2/dsymbol.h, dmd2/func.c, dmd2/parse.c, dmd2/statement.c,\n\tdmd2/template.c, dmd2/toir.c: 2.015 WORKING ;)\n\n\t* dmd2/parse.c: Fixed problem with static if.\n\n\t* dmd2/template.c: Fixed problem with tuples.\n\n\t* Makefile-lang.in: Update for files added in DMD 2.015.\n\n2009-10-01  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\tChanges to 2.032 branch:\n\n\t* dmd2/..., phobos2/...: Force merge with 2.032 - NOT WORKING AT ALL.\n\t- Adding new files.\n\n2009-10-04  michaelp  <baseball.mjp@gmail.com>\n\n\tMerge with DMD 1.039\n\n\t* d-decls.cc: Merge changes from dmd/mtype.h.\n\n\t* phobos/internal/aaA.d, phobos/std/stdio.d: Small Phobos fix.\n\n2009-09-30  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\t* phobos2/internal/aaA.d, phobos2/linux.mak, phobos2/std/algorithm.d,\n\tphobos2/std/functional.d, phobos2/std/math.d, phobos2/std/thread.d:\n\tDMD 2.015 Phobos changes.\n\n\t* Make-lang.in: Fixed a problem introduced by Michael modifying a\n\tcommon file between D1 and D2.\n\n\n2009-09-29  michaelp  <baseball.mjp@gmail.com>\n\n\tMerge with DMD 1.036\n\n2009-09-28  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\tMerge with DMD 2.015\n\n\t* dmd2/mtype.h, dmd2/parse.c: Fixed parser in D2.\n\n\t* dmd2/template.c, dmd2/toobj.c: Other fixes.\n\n2009-09-28  michaelp  <baseball.mjp@gmail.com>\n\n\tMerge with DMD 1.035\n\n\t* d-objfile.cc: Merge changes from dmd/attrib.c.\n\n\t* phobos/Makefile.in, phobos/internal/arraydouble.d,\n\tphobos/internal/arrayfloat.d: Included arraydouble, arrayfloat, and\n\tarrayreal in libphobos Makefile.\n\n\t* asmstmt.cc, dmd/statement.c, dmd/statement.h, phobos/std/math.d: Fixed\n\tPhobos std.math bug.\n\n2009-09-25  michaelp  <baseball.mjp@gmail.com>\n\n\tMerge with DMD 1.033\n\n2009-09-17  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\t* dmd2.032/...: Initial import of version 2.032.\n\n\t* setup-gcc.sh, dmd/.svn/...: Removed .svn directory.\n\n2009-09-13  michaelp  <baseball.mjp@gmail.com>\n\n\t* phobos/std/boxer.d phobos/std/dateparse.d: Fixed phobos build and\n\tpossible implicit conversion errors in boxer.d.\n\n\t* d-objfile.cc: Removed assert(0) line 926.\n\n2009-09-13  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\t* History gdc-version: Changed version.\n\n\t* phobos2/config/x3, setup-gcc.sh: Added support for DMD 2.\n\n\t* phobos2/std/c/string.d, phobos2/std/contracts.d: Fixed a std.string\n\tbug following these guidelines:\n\thttp://www.digitalmars.com/d/archives/D/gnu/strerror_r_3403.html\n\n\t* phobos2/std/contracts.d, phobos2/std/date.d, phobos2/std/dateparse.d,\n\tphobos2/std/file.d, phobos2/std/md5.d, phobos2/std/path.d,\n\tphobos2/std/random.d, phobos2/std/stdio.d: Fix DMD 2 for GCC-4.3.4\n\n2009-09-11  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\tSwitching to Mercurial branch system.\n\n\t* d/...: Setting up default branch with GCC-4.3.x support.\n\n\t* branches/gcc-4.1/...: Starting gcc-4.1.x stable branch.\n\n\t* setup-gcc.sh, target-ver-syms.sh: Fixed permission problems in\n\tbash scripts.\n\n2009-09-10  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\t* trunk/...: Import of gdc 0.24 stable into bitbucket.\n\n2009-01-31  Arthur Loiret  <arthur.loiret@u-psud.fr>\n\n\t* d-glue.cc, d-objfile.cc, d-codegen.cc, d-lang.h, d-builtins2.cc,\n\td-convert.cc, d-codegen.h: Replace calls to build macro by appropriate\n\tbuildN function (build is removed in GCC > 4.1).\n\n\f\nCopyright (C) 2009 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2010",
    "content": "2010-12-28  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-lang.cc, d/patches/patch-apple-gcc-5465,\n\td/patches/patch-apple-gcc-5664, d/patches/patch-gcc-4.0.x,\n\td/patches/patch-gcc-4.1.x, d/patches/patch-gcc-4.2.x,\n\td/patches/patch-gcc-4.3.x, d/patches/patch-gcc-4.4.x,\n\td/patches/patch-gcc-4.5.x: New function added to langhooks:\n\td_dump_tree\n\t[8a2198026630]\n\n\t* d/d-lang.cc, d/patches/patch-apple-gcc-5465,\n\td/patches/patch-apple-gcc-5664, d/patches/patch-gcc-4.0.x,\n\td/patches/patch-gcc-4.1.x, d/patches/patch-gcc-4.2.x,\n\td/patches/patch-gcc-4.3.x, d/patches/patch-gcc-4.4.x,\n\td/patches/patch-gcc-4.5.x, d/phobos2/Makefile.am,\n\td/phobos2/Makefile.in: New function added to langhooks:\n\td_gimplify_expr\n\t[0d43883dcc75]\n\n\t* d/d-builtins2.cc, d/druntime/core/stdc/complex.d,\n\td/druntime/rt/complex.c, d/phobos2/Makefile.am, d/phobos2/Makefile.in:\n\tD2 - Use GCC builtins in core.stdc.complex\n\t[d13bd5912295]\n\n\t* d/d-codegen.cc, d/d-glue.cc: Issue #109 - segfault in memcpy()\n\t[80c61a61f254]\n\n2010-12-23  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/asmstmt.cc, d/d-bi-attrs-45.h, d/d-c-stubs.c,\n\td/d-cppmngl.cc, d/d-gcc-includes.h, d/d-glue.cc, d/d-lang-45.h,\n\td/d-lang.cc, d/dmd2/*, d/druntime/*, d/phobos2/*: Updated to 2.051.\n\t[9d12fbe44d3]\n\n\t* d/phobos2/Makefile.am, d/phobos2/Makefile.in: D2 - Move generated\n\theaders out of the way so as they don't interfere with build process.\n\t[c52428bb97b]\n\n\t* /druntime/rt/aaA.d, d/druntime/rt/adi.d, d/druntime/rt/lifetime.d,\n\td/druntime/rt/memory.d, d/druntime/rt/qsort.d,\n\td/druntime/rt/switch_.d, d/druntime/rt/util/string.d: Merge\n\tdifferences between GDC and DMD Druntime. Should fix Issue #129\n\t[1d6e8e716ae3]\n\n\t* d/d-glue.cc, d/d-lang.cc, d/druntime/rt/dmain2.d,\n\td/phobos2/Makefile.am, d/phobos2/Makefile.in,\n\td/phobos2/gcc/bitmanip.d: Fix codegen in ArrayLiteralExp; Split cmain\n\tfrom dmain2 in druntime; Update gcc.bitmanip for 2.051.\n\t[b1393d6cc45a]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc, d/d-lang.cc,\n\td/d-objfile.cc, d/dt.cc: Use build_constructor to make constructor\n\tnodes.\n\t[bd721e198eff]\n\n2010-12-17  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.h, d/d-glue.cc, d/dmd/expression.c, d/dmd2/expression.c:\n\tFix handling of _argptr after commit 398.\n\t[95992bb703de]\n\n\t* d/d-lang.cc, d/patches/patch-gcc-4.4.x: Issue #104 revisited -\n\teasier to instead fix in GCC.\n\t[dedbc5dc14a9]\n\n\t* d/d-lang.cc: Issue #104 - ICE on inlining nested struct member\n\tfunctions\n\t[eb09c05188ea]\n\n\t* d/d-decls.cc: Issue #85 - template functions not inlined.\n\t[c9db2183900a]\n\n2010-12-12  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-builtins2.cc, d/d-lang.cc, d/dmd2/toobj.c: D2 - tighten up\n\tpurity set on builtins.\n\t[677ff59c566]\n\n\t* d/GDC.html, d/dmd/attrib.c, d/dmd/idgen.c, d/dmd2/attrib.c,\n\td/dmd2/idgen.c, d/phobos/gcc/unwind_arm.d, d/phobos2/gcc/unwind_arm.d:\n\tGNU_attribute and GNU_set_attribute deprecated for promoting attribute\n\tand set_attribute.\n\t[99b197365502]\n\n\t* d/d-glue.cc, d/d-objfile.cc, d/dmd2/expression.c, d/dmd2/todt.c:\n\tcleanup todt; testsuite fixes.\n\t[3ee0b55b9fcc]\n\n2010-12-10  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-builtins2.cc, d/d-dmd-gcc.h, d/dmd2/builtin.c,\n\td/dmd2/declaration.h, d/dmd2/expression.c, d/dmd2/interpret.c: Power\n\toperators ^^ now working in CTFE.\n\t[d804e40bb245]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc: Issue #121 - ICE in\n\tgimple_rhs_has_side_effects.\n\t[63a29e175dba]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-gcc-real.h, d/d-irstate.h,\n\td/d-lang.h, d/d-objfile.h, d/dt.h: Glue Header code cleanups.\n\t[42d36e6321f5]\n\n\t* d/phobos2/std/math.d: Issue #113 - std.math: cos/sin forward\n\tdeclaration issue.\n\t[089fa0826192]\n\n\t* d/d-asm-i386.h, d/phobos2/std/math.d: Add special case for fdiv/fsub\n\topcodes.\n\t[69b717b206e1]\n\n\t* d/asmstmt.cc, d/d-asm-i386.h, d/d-codegen.cc: Glue code cleanups.\n\t[03e46b45acfc]\n\n\t* d/d-asm-i386.h, d/dmd2/expression.c, d/phobos2/std/math.d:\n\toff-by-one Inline asm fix.\n\t[9f3bb8c3e1e4]\n\n\t* d/d-builtins2.cc, d/d-codegen.cc, d/dmd2/builtin.c,\n\td/dmd2/declaration.h, d/dmd2/interpret.c, d/phobos2/Makefile.in,\n\td/phobos2/configure: D2 - GCC builtins now CTFE'd.\n\t[46b8a2bb22f5]\n\n2010-12-04  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-lang.cc, d/druntime/gc/gcgccextern.d, d/phobos2/Makefile.am,\n\td/phobos2/Makefile.in, d/phobos2/std/math.d, d/setup-gcc.sh,\n\td/target-ver-syms.sh: Updated FreeBSD and Solaris version identifiers.\n\t[a52396ea0fa4]\n\n2010-12-03  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-asm-i386.h, d/d-spec.c, d/dmd2/root.c, d/dmd2/speller.c,\n\td/druntime/core/sys/posix/setjmp.d, d/phobos2/configure,\n\td/phobos2/configure.in, d/phobos2/std/math.d: Applied patches from\n\tIssue #100, some work on Phobos/Druntime ARM port.\n\t[8dbea571bd08]\n\n\t* d/d-asm-i386.h, d/d-builtins.c, d/d-lang.cc: Issue #118 - Segfault\n\ton string compare.\n\t[e2092db74028]\n\n2010-11-26  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-decls.cc: Issue #110 - Pure Nothrow Functions Not Called.\n\t[46680c366e68]\n\n\t* d/dmd/entity.c, d/dmd2/entity.c: Fixes to html entities.\n\t[954a116bc175]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc, d/d-irstate.h: D2 -\n\tsupport 'case var:' in switch statements.\n\t[af08a1a054c8]\n\n\t* d/d-glue.cc, d/d-objfile.cc, d/dmd/expression.c,\n\td/dmd2/expression.c: Check lwr <= upr in pointer array slices, fixed\n\tAA bug using const types.\n\t[0a0c8ff325da]\n\n\t* d/druntime/core/sys/osx/mach/kern_return.d,\n\td/druntime/core/sys/osx/mach/port.d,\n\td/druntime/core/sys/osx/mach/semaphore.d,\n\td/druntime/core/sys/osx/mach/thread_act.d: Add version(OSX) at top of\n\tsource files.\n\t[106a741599c6]\n\n\t* d/d-glue.cc: Fix ICE compiling empty with{} or volatile{}\n\tstatements.\n\t[e83350ff851b]\n\n\t* d/druntime/rt/aaA.d, d/phobos2/std/format.d, d/phobos2/std/string.d:\n\tFix bug in aaA.d, remove workaround in std.format.\n\t[6549ec58cf1c]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc,\n\td/druntime/rt/lifetime.d: Issue #108 - crash when compiling\n\tdeclaration of a big array.\n\t[38209ac30752]\n\n\t* d/d-builtins2.cc, d/d-glue.cc, d/dmd2/expression.c,\n\td/dmd2/expression.h, d/dmd2/optimize.c, d/druntime/core/atomic.d,\n\td/dt.cc, d/dt.h: Refs #108 - Prevent crash when compiling declaration\n\tof a big array.\n\t[bece6cdf81f8]\n\n2010-11-21  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-convert.cc, d/d-cppmngl.cc,\n\td/d-gcc-real.cc, d/d-glue.cc, d/druntime/core/stdc/stdarg.d,\n\td/druntime/rt/lifetime.d, d/dt.cc, d/symbol.cc: Add _d_arrayliteralT\n\tas libcall.\n\t[1d3d564d0bfc]\n\n\t* d/d-glue.cc, d/dmd2/expression.c, d/druntime/core/stdc/stdarg.d,\n\td/phobos2/std/algorithm.d: Issue #107 - compilation failed on\n\tassociated array.clear()\n\t[75733609b163]\n\n\t* d/d-decls.cc, d/d-lang.cc, d/gdc.1, d/lang.opt,\n\td/phobos2/Makefile.am, d/phobos2/Makefile.in: Issue #106 - compilation\n\tfailed on files importing std.xml.\n\t[3205e04db834]\n\n\t* d/d-objfile.cc, d/druntime/object.di, d/phobos2/Makefile.am,\n\td/phobos2/Makefile.in: Makefile now properly creates D interface files\n\tfor installing.\n\n2010-11-19  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-builtins2.cc, d/d-codegen.cc, d/d-decls.cc, d/d-glue.cc,\n\td/d-lang.cc, d/dmd2/*, d/druntime/*, d/phobos2/*: Updated D2 frontend\n\tto 2.050.\n\t[93726e7f3043]\n\n\t* d/d-glue.cc, d/dmd2/*, d/phobos2/*: Issue #95 - 'Hello World' for\n\t64bit not working.\n\t[f58b9a4c4827]\n\n\t* d/Make-lang.in, d/d-codegen.cc, d/d-decls.cc, d/d-irstate.cc,\n\td/druntime/gc/gcgccextern.d, d/dt.h, d/phobos2/Makefile.am: No more\n\tsegfaults from calling the moduleTlsDtor of a spawned thread.\n\t[7afee485d3ec]\n\n\t* d/druntime/core/atomic.d, d/druntime/rt/dmain2.d,\n\td/phobos2/Makefile.am, d/phobos2/Makefile.in: Fix makefile to generate\n\t& install .di headers for druntime.\n\t[8d8f3f8e346f]\n\n\t* d/d-codegen.cc, d/d-glue.cc, d/druntime/rt/memory.d: Passes the\n\tcompilable/fail_compilation testsuite. Fix off-by-one static assert in\n\trt.memory.\n\t[a05310b5bd39]\n\n\t* d/d-codegen.cc, d/druntime/core/atomic.d, d/druntime/rt/monitor.c:\n\tDon't make a libcall for _d_arraycast when converting void[] to\n\tarray[]. Fix a hang in the generic atomicOps.\n\t[d9555265c627]\n\n\t* d/Make-lang.in, d/d-apple-gcc.c, d/d-codegen.cc, d/d-glue.cc: Remove\n\tredundant tree checking. Fold in apple-gcc patches.\n\t[a62de16def16]\n\n\t* d/patches/patch-apple-gcc-5664, d/patches/patch-build_gcc-5664: New\n\tpatches for apple-gcc.\n\t[80db7b3f1bbc]\n\n\t* d/dmd/entity.c, d/dmd2/entity.c: Merge Walter's and Thomas' named\n\tentity lists.\n\t[8949157fe7b0]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc: Issue #98 - cannot\n\tperform floating-point modulo division on creal.\n\t[53c34b538c56]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc: Issue #102 - Fixed error\n\tusing overloaded <>= operator.\n\t[61db8ca7622c]\n\n\t* d/d-glue.c: Issue #89 - Error initialising struct with static array.\n\t[24f69762e9c3]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc: Issue #103 - destructor\n\tnot called on array of structs.  Postblit on struct now called when\n\treturned from a function.\n\t[cb7faae1f7b9]\n\n\t* d/druntime/object_.d: Merge workaround from Phobos1 library.\n\t[336c20f065e4]\n\n\t* d/phobos/std/math.d, d/phobos2/std/math.d: Add aliases for missing\n\trndtol and rndtonl functions.\n\t[86eb7cecbe6a]\n\n\t* d/d-codegen.cc, d/d-glue.cc: Properly handle return (void)value.  In\n\tslice expression [lwr .. upr], ensure lwr gets evaluated first.  Tree\n\tchecking fixes in NewExp and floatMod.\n\t[967482328f44]\n\n2010-11-13  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-c-stubs.c, d/d-codegen.cc, d/d-glue.cc, d/d-objfile.cc,\n\td/dmd2/*, d/druntime/*, d/phobos2/*: Updated D2 frontend to 2.049.\n\t[6c13728646ec]\n\n\t* d/druntime/core/sys/posix/sys/select.d: Issue #90 - select.d fails\n\tto compile on 64 bits Linux.\n\t[9cd6979d9a7d]\n\n\t* d/druntime/core/sys/posix/sys/select.d, d/druntime/rt/lifetime.d,\n\td/phobos2/gcc/bitmanip.d, d/phobos2/std/bitmanip.d,\n\td/phobos2/std/regexp.d: Issue #91, #92, #93 - various issues building\n\ton 64bit Linux.\n\t[c3ef6baccc9d]\n\n2010-11-12  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-asm-i386.h, d/d-builtins2.cc, d/d-codegen.cc, d/d-convert.cc,\n\td/d-cppmngl.cc, d/d-glue.cc, d/d-lang.cc, d/d-spec.c, d/dmd2/*,\n\td/druntime/*, d/phobos2/*: Updated D2 frontend to 2.048.\n\t[0d91f8245403]\n\n\t* d/druntime/core/sys/posix/sys/select.d: Fix some 64bit compat issues\n\twith druntime module.\n\t[05bb4c2b1f7d]\n\n2010-11-08  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-builtins2.cc, d/d-codegen.cc, d/d-glue.cc, d/d-lang.cc,\n\td/dmd-script, d/dmd2/*, d/druntime/*, d/phobos2/*: Updated D2 frontend\n\tto 2.047.\n\t[4bd4615c8a7e]\n\n2010-11-07  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc,\n\td/dmd-script, d/dmd-script.1, d/gdc.1, d/dmd2/*, d/druntime/*,\n\td/phobos2/*: Updated D2 frontend to 2.046. Removed tabs, trailing\n\tspaces.\n\t[5be9e0023b23]\n\n2010-11-05  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-glue.cc, d/d-irstate.cc, d/d-lang.cc, d/d-objfile.cc,\n\td/d-objfile.h, d/dmd2/*, d/druntime/*, d/phobos2/*: Updated D2\n\tfrontend to 2.040.\n\t[5beb7019c5e6]\n\n\n2010-11-03  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/phobos/Makefile.am, d/phobos/Makefile.in, d/phobos/etc/c/zlib.d,\n\td/phobos/std/zlib.d, d/phobos2/Makefile.am, d/phobos2/Makefile.in,\n\td/phobos2/etc/c/zlib.d, d/phobos2/std/zlib.d, d/zlib/*: Upgrade zlib\n\tsupport to zlib 1.2.5.\n\t[ea7e83019088]\n\n\t* d/d-gcc-real.cc: Issue #79 - Wrong decimal value in error message.\n\t[71d8713b0604]\n\n\t* d/phobos2/std/json.d, d/setup-gcc.sh: Added --update option for\n\tsetup-gcc.sh to rebuild directory of libphobos links.\n\n\t* d/dmd/typinf.c, d/dmd2/typinf.c: Issue #83 - wrong TypeInfo_Struct\n\tname outputted.\n\t[f9ddff9d5ed9]\n\n\t* d/d-lang.cc: Bugzilla 1911 - Link error when creating array of\n\ttypedefs with default initializer.\n\t[8667626321e7]\n\n2010-11-01  michaelp  <baseball.mjp@gmail.com>\n\n\t* d/d-codegen.cc: Issue #76 - odd error message when casting between\n\tnon-convertable types.\n\t[0c78536565d6]\n\n2010-11-01  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/asmstmt.cc, d/d-builtins2.cc, d/d-codegen.cc, d/d-codegen.h,\n\td/d-cppmngl.cc, d/d-decls.cc, d/d-glue.cc, d/d-lang.cc, d/dmd-script,\n\td/dmd2/*, d/druntime/*, d/phobos2/*: Updated D2 Frontend to 2.037.\n\t[e37f9fae0867]\n\n\t* d/druntime/compiler/gdc/object_.d, d/druntime/compiler/gdc/rt/aaA.d,\n\td/druntime/import/object.di: Issue #82 - undefined references in\n\tobject.d\n\t[0aff60753810]\n\n2010-10-31  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-decls.cc, d/d-glue.cc, d/dmd2/*, d/druntime/*,\n\td/phobos2/*: Updated D2 frontend to 2.036.\n\t[6bf237fb6ba6]\n\n\t* d/d-decls.cc, d/d-glue.cc: Issue #80 - Bad codegen for structs\n\tcontaining invariants.\n\t[2fe867d16c45]\n\n\t* d/d-codegen.cc, d/d-glue.cc: Issue #81 - Bad codegen and ICEs using\n\tenums.\n\t[3d028b2d1d30]\n\n\t* d/d-lang.cc: Issue #76 - Hide 'In file included from <builtin>'\n\tmessage in errors.\n\t[d590dd56696b]\n\n\t* d/phobos2/std/string.d, d/phobos2/std/zlib.d: Fix return result of\n\tcmp().\n\t[582cd1b0bff4]\n\n\t* d/d-builtins2.cc, d/druntime/import/core/stdc/math.d: All GCC\n\tbuiltins now marked pure and optionally nothrow. core.stdc.math\n\tfunctions made builtin.\n\t[dc2b50a4c0f6]\n\n2010-10-27  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/d-glue.cc, d/d-lang.cc, d/dmd2/*, d/druntime/*,\n\td/phobos2/*: Update D2 frontend to 2.035.\n\t[ef0d5e8ec06d]\n\n\t* d/d-glue.cc: Adjust Classinfo size for D2.\n\t[b8673983b46b]\n\n\t* d/patches/*, d/set-gcc.sh: Updated patches and setup-gcc.sh for\n\tApple GCC.\n\t[b25313940945]\n\n\t* d/d-asm-i386.h, d/phobos/std/cpuid.d, d/phobos2/std/cpuid.d: Tell\n\tbackend cpuid clobbers EBX; remove workaround in std.cpuid.\n\t[3cbf9b8108a2]\n\n2010-10-24  michaelp  <baseball.mjp@gmail.com>\n\n\t* d/d-glue.cc, d/druntime/*, d/phobos2/*: Issue #77 - porting D2\n\tPhobos to x86_64.\n\t[cf5f02e03fda]\n\n2010-10-23  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/phobos2/*: Issue #74 - New D2 Phobos source rebased from DMD.\n\t[98120f156997]\n\n\t* d/phobos/Makefile.am, d/phobos/Makefile.in, d/phobos/config.h.in\n\td/phobos/configure, d/phobos2/Makefile.am, d/phobos2/Makefile.in:\n\tFix building with --enable-multilib\n\t[67365c9f7b52]\n\n2010-10-21  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-asm-i386.h, d/d-decls.cc, d/d-glue.cc, d/d-lang.cc,\n\td/dmd-script, d/dmd2/*, d/druntime/*, d/phobos2/*: Updated D2 frontend\n\tto 2.032.\n\t[861e16b38529]\n\n\t* d/d-builtins2.cc, d/druntime/import/core/stdc/stdarg.d: D2 - Add\n\tcore.stdc.stdarg as an stdarg module. Patched core.stdc.stdarg to work\n\twith GDC compiler.\n\t[8b0a0deb8e7d]\n\n\t* d/d-codegen.cc: Issue #72 - 'this' in nested structs cannot access\n\tframe of outer function.\n\t[3422c59c130a]\n\n\t* d/phobos/std/intrinsic.d: D1 - Fix bt function on 64bit archs.\n\t[7445723aaedd]\n\n\t* d/d-codegen.cc, d/d-glue.cc: Issue #73 - ICE declaring string enums.\n\t[0865e6286775]\n\n\t* d/druntime/compiler/gdc/aaA.d: D2 - Fixed segfault getting AA\n\tkeys/values.\n\t[d049574ccd3f]\n\n\t* d/dmd/mars.h, d/dmd/mtype.c, d/phobos/acinclude.m4,\n\td/phobos/configure, d/phobos/configure.in, d/phobos2/acinclude.m4,\n\td/phobos2/configure, d/phobos2/configure.in, d/target-ver-syms.sh:\n\tSome updated to target OS detection.\n\t[7fecb2ef6432]\n\n2010-10-12  opticron  <nyphbl8d@gmail.com>\n\n\t* d/phobos/Makefile.am, d/phobos/Makefile.in, d/phobos2/Makefile.am\n\td/phobos2/Makefile.in: D1/D2: Fix type sizes in gcc/config/* when\n\tbuilding with multilib.\n\t[b9f7dd4e80a2]\n\n2010-10-11  michaelp  <baseball.mjp@gmail.com>\n\n\t* d/patches/patch-gcc-4.4.x, d/patches/patch-toplev-4.4.x: Updated\n\t4.4.x patches for 4.4.5\n\t[dd2f05ac4246]\n\n2010-10-08  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-glue.cc, d/dmd2/*, d/druntime/*: Updated D2 frontend to 2.029.\n\t[082c04bad0c3]\n\n2010-10-07  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/d-asm-i386.h, d/d-codegen.h, d/d-decls.cc\n\td/d-gcc-real.cc, d/d-gcc-real.h, d/d-glue.cc, d/dmd2/*, d/druntime/*,\n\td/phobos2/*: Update D2 frontend to 2.028.\n\t[141118223a79]\n\n\t* d/dmd/cast.c d/dmd/constfold.c d/dmd/identifier.c d/dmd/lexer.c\n\td/dmd/mars.h d/dmd/mtype.c d/dmd/opover.c d/dmd/optimize.c\n\td/dmd/template.h d/dmd/todt.c d/dmd/toobj.c: Cleaned up D1 folder\n\tafter D2 updates.\n\t[5c293d142e2d]\n\n\t* d/asmstmt.cc, d/d-asm-i386.h: Issue #70 - Inline Asm errors junk\n\t`(%ebp)+4' after expression.\n\t[21764cc50c3f]\n\n2010-10-06  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, dmd2/*, phobos2/*: Updated D2 frontend to 2.026.\n\t[7a1dfe79af05]\n\n\t* d/d-glue.cc: Issue #69 - ICE on typedef'd array\n\tconcatenation.\n\t[fe66fbb9e08e]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc: D2 - Fixed 'this.this'\n\tbeing null in a nested class.\n\t[d1dfd83df144]\n\n\t* d/d-decls.cc: Let backend know about functions marked as 'nothrow'\n\tand 'immutable'.\n\t[77df72e87dd0]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-decls.cc, d/d-glue.cc: D2 -\n\tImplemented nested structs.\n\t[8c901ab67b00]\n\n\t* d/d-codegen.cc d/d-codegen.h d/d-glue.cc: Move block of code\n\tinitialising structs from emitLocalVar to AssignExp.\n\t[32165d66c011]\n\n\t* d/Make-lang.in, d/d-lang.cc, d/dmd2/array.c, d/dmd2/async.c\n\td/dmd2/async.h, d/dmd2/root.c: D2 - Added AsyncRead sources.\n\t[3407bc0a9896]\n\n2010-10-03  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/phobos/std/regexp.d: Fix D1 phobos for 64bit systems.\n\t[2cc2741e0031]\n\n\t* d/d-decls.cc, d/d-lang.h: D2 - Let backend know about functions\n\tmarked as 'pure'.\n\t[e9eb758ba073]\n\n\t* d/druntime/compiler/gdc/lifetime.d: Issue #69 - arraycatnT not\n\tworking on 64bit.\n\t[1fb27285a969]\n\n2010-09-30  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/asmstmt.cc, d/d-codegen.cc, d/d-glue.cc, dmd2/*, druntime/*\n\tphobos2/*: Updated D2 frontend to 2.025.\n\t[4b8327c25e06]\n\n2010-09-29  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-glue.cc, d/dmd2/*, d/druntime/*, d/phobos2/*: Updated D2\n\tfrontend to 2.022\n\t[747409fe2b40]\n\n\t* d/d-codegen.cc, d/d-glue.cc, d/phobos2/Makefile.in: Fix building with\n\t--enable-checking.\n\t[364d892342c5]\n\n\t* d/d-codegen.cc, d/druntime/gc/basic/gcx.d: Issue #68 - Cannot cast to\n\tstructs of same type size.\n\t[8fd7216c74a7]\n\n\t* d/d-lang.cc, d/dmd-script, d/lang.opt: Added -safe switch.\n\t[a06f5919bd1c]\n\n\t* d/d-spec.c: Update D2 driver.\n\t[9e1b27a03458]\n\n2010-09-28  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* zlib/*: Moved zlib to it's own maintained directory.\n\t* d/phobos/etc/c/zlib, d/phobos2/etc/c/zlib: Removed.\n\t[46deecb698ea]\n\n\t* dmd/*, phobos/*: Updated D1 frontend to 1.064.\n\t[77f4acd15b72]\n\n\t* dmd2/*, druntime/*, phobos2/*: Updated D2 frontend to 2.021.\n\t[ed6460a378bc]\n\n\t* d/druntime/compiler/gdc/adi.d, d/druntime/compiler/gdc/alloca.d,\n\td/druntime/compiler/gdc/cover.d, d/druntime/compiler/gdc/memset.d,\n\td/druntime/compiler/gdc/qsort.d, d/druntime/compiler/gdc/qsort2.d,\n\td/phobos2/Makefile.am, d/phobos2/Makefile.in: D2 runtime segfault fixes.\n\t[7c9615da20cb]\n\n\t* d/d-builtins2.cc d/d-codegen.cc d/d-decls.cc d/d-glue.cc\n\td/dmd2/mars.h d/druntime/compiler/gdc/util/console.d\n\td/phobos2/std/bigint.d d/phobos2/std/bitmanip.d d/phobos2/std/boxer.d\n\td/phobos2/std/date.d d/phobos2/std/dateparse.d d/phobos2/std/md5.d: D2\n\t'this' parameter to struct member functions is now a reference type.\n\t[91fd4a667dc9]\n\n2010-09-25  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-glue.cc: D2 - rework return by ref.\n\t[ecd406de9575]\n\n\t* d-codegen.cc, d-glue.cc: Move check for ref function to better place.\n\t[9dc1edb1c332]\n\n\t* d-glue.cc: Issue #66 - Array setting causes OutOfMemoryException.\n\t[65f4cc943169]\n\n2010-09-20  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-builtins.c, d-codegen.cc, d-glue.cc:\n\tD2 updates - Return by reference now implemented (instead of ignored).\n\t[6e2ba321e290]\n\n\t* d-codegen.cc, d-convert.cc, d-decls.cc, d-glue.cc:\n\tGain back some compiler speed in release builds.\n\t[c8bdb254e8fc]\n\n2010-09-18  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* phobos2/config.h.in, phobos2/configure:\n\tRegenerate D2 configure scripts.\n\t[eed0b915018b]\n\n\t* druntime/compiler/gdc/dmain2.d:\n\tFix _d_hidden_func to work with GDC compiler\n\t[8c2f5a4e8805]\n\n\t* d-codegen.cc, d-convert.cc, d-glue.cc, d-lang.h:\n\tIssue #64 - enable-checking in configure fails on 4.4.x\n\t[7bfec5c437bb]\n\n\t* d-lang.h: Issue #28 - enable-checking in configure fails\n\t[3de9afb31bb7]\n\n\t* druntime/compiler/gdc/trace.d, phobos2/Makefile.am,\n\tphobos2/Makefile.in, phobos2/config.log:\n\tRemove trace.d from D2\n\t[253e781b9254]\n\n2010-09-15  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc d-glue.cc: Fix obscure memory bug in D2.\n\t[af9fbe154ba6]\n\n\t* d-codegen.cc, d-codegen.h, d-glue.cc, d-irstate.cc, d-irstate.h,\n\tdmd/statement.c, dmd2/statement.c:\n\tIssue #56 - goto into a try block doesn't produce an error.\n\t[960b54da053d]\n\n\t* dmd2/inifile.c, druntime/compiler/gdc/cmath2.d,\n\tdruntime/compiler/gdc/gccmemory.d, druntime/compiler/gdc/memory.d,\n\tphobos2/Makefile.am, phobos2/Makefile.in:\n\tSplit off rt.memory, remove useless sources.\n\t[08fac74f4074]\n\n\t* druntime/common/core/thread.d, druntime/compiler/gdc/util/cpuid.d:\n\tMerge getESP code from D2 phobos to druntime.\n\t[5e6ee66625e4]\n\n\t* druntime/compiler/gdc/llmath.d: Remove llmath.d\n\t[6b7397510e33]\n\n2010-09-09  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc:\n\tRevert part of commit 210, and fix integer representations on gdc-4.4.\n\t[844b25646834]\n\n\t* d-bi-attrs-34.h, d-bi-attrs-341.h, d-builtins.c, d-c-stubs.c,\n\tMake-lang.in: Merge d-bi-attrs-341 with d-bi-attrs-34.h.\n\t[c2f92387a049]\n\n\n2010-09-07  michaelp  <baseball.mjp@gmail.com>\n\n\t* gcc-mars.cc:\n\tRemoved gcc-mars.cc from top level d/ folder.\n\t[e4b1e3753bf5]\n\n\t* Make-lang.in:\n\tUpdated Make-lang.in for removal of gcc-mars.cc.\n\t[db7d6aae8ceb]\n\n\t* GDC.html, History, INSTALL, INSTALL.html, README, dmd-script,\n\tdmd-script.1, gdc.1:\n\tDocumentation updates.\n\t[e651ed00a16e]\n\n2010-09-03  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc, d-glue.cc, d-objfile.cc:\n\tIssue #59 and #60: ICE when goto undefined label and ICE in foreach over\n\tmember member array in static func\n\t[955dc7d43780]\n\n\t* d-codegen.cc, d-glue.cc, d-irstate.cc, d-lang.h, dmd/func.c,\n\tdmd/statement.c, dmd/statement.h:\n\tIssue #54: 1.063 changes in phobos versioning + dmd backend.\n\t[4c10fa4a539a]\n\n2010-09-01  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* dmd/cast.c, dmd/impcnvgen.c, dmd2/impcnvgen.c:\n\tBugzilla 1822 - String slicing in 64-bit gdc causes spurious\n\twarnings\n\t[5efc9014eef8]\n\n\t* patches/patch-gcc-4.0.x, patches/patch-gcc-4.1.x, d/patches\n\t/patch-gcc-4.2.x, patches/patch-gcc-4.3.x, patches/patch-\n\tgcc-4.4.x:\n\tIssue #50 - thanks venix1: SjLj expections fail when thrown from catch\n\tblock\n\t[d655a072bbb8]\n\n\t* d-builtins2.cc, d-lang.cc, d-spec.c:\n\tRemoved va_list hack, small change to D2 lang driver.\n\t[7a67e4973ace]\n\n2010-08-30  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc:\n\tIssue #14: STATIC_CHAIN_EXPR not caught in estimate_num_insns_1()\n\t[63c14701ccde]\n\n2010-08-29  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-c-stubs.c, d-glue.cc, d-lang.cc:\n\tAdd stubs for C_TARGET_OBJS on non-x86 archs.\n\t[b530fcd9baab]\n\n\t* d-glue.cc:\n\tBugzilla 1669 - this.outer in nested classes gives a bogus pointer\n\t[ebce488abf89]\n\n\t* d-lang.cc, phobos2/Makefile.am, phobos2/acinclude.m4:\n\tAdd D_Version2 version predicate.\n\t[9808b8987cce]\n\n2010-08-28  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-c-stubs.c, d-decls.cc, d-lang.cc,\n\tdruntime/compiler/gdc/aaA.d, druntime/compiler/gdc/util/cpuid.d,\n\tdruntime/gc/basic/gc_c.h, druntime/gc/basic/gc_dyld.c,\n\tdruntime/gc/basic/gc_freebsd.c, druntime/gc/basic/gcgccextern.d,\n\tphobos/internal/gc/gcgccextern.d, phobos/std/loader.d,\n\tphobos2/Makefile.am, phobos2/acinclude.m4,\n\tphobos2/std/cpuid.d:\n\tD2 updates.\n\t[ebe4ca2bd83a]\n\n2010-08-27  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d-spec.c, phobos2/Makefile.am:\n\tAdd druntime to the GDC driver.\n\t[3dbc1c4cd214]\n\n\t* druntime/Makefile, druntime/compiler/gdc/dgccmain2.d,\n\tdruntime/compiler/gdc/lifetime.d, phobos2/gcc/deh.d,\n\tphobos2/gcc/unwind_generic.d, phobos2/gcc/unwind_pe.d,\n\tphobos2/std/stream.d:\n\tRemove Makefile and fix module dependencies in Druntime\n\t[6fea2af61a0c]\n\n\t* phobos2/Makefile.am, phobos2/acinclude.m4, phobos2/aclocal.m4,\n\tphobos2/configure.in, d/setup-gcc.sh:\n\tReorganise D2 Makefile for Druntime\n\t[f888b572d19a]\n\n\t* d/Make-lang.in:\n\tUse BACKENDLIBS rather than GMPLIBS for gdc-4.4\n\t[bda0f5d37728]\n\n\t* d-glue.cc:\n\tFix ICE in D2 ForeachRange statements\n\t[7d35bcb69e7e]\n\n2010-08-26  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* patches/patch-gcc-4.4.x:\n\tRegenerate gcc-4.4.x patch\n\t[4dfe5494460a]\n\n2010-08-25  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.h:\n\tFix codegen for addressOf array types, resolves broken va_lists on\n\tgdc-4.4.\n\t[9463381e1daa]\n\n\t* druntime/compiler/gdc/fpmath.d, druntime/compiler/gdc/gcc/*,\n\tdruntime/druntimelicense.txt, druntime/druntimereadme.txt,\n\tdruntime/hello.d, druntime/license.txt, druntime/readme.txt:\n\tRe-add fpmath.d - previously from removed internal directory.\n\t[bf3e292d1a4c]\n\n\t* d-builtins2.cc:\n\tSlight alteration to va_list type generation on gdc-4.4\n\t[e005caeafced]\n\n\t* d-codegen.cc, d-glue.cc, d-irstate.cc, d-lang.h:\n\tUse own language flag for labels marked 'used'.\n\t[d7963235235c]\n\n\t* d-lang.cc:\n\tRework of previous commit for Issue #58.\n\t[025031c2e274]\n\n2010-08-24  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-lang.cc:\n\tIssue #58 - Fixed stack overflow in gdc-4.4\n\t[c02f5ac787a8]\n\n2010-08-23  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc:\n\tBugzilla 1813 - ICE on static function parametrized with alias.\n\t[2e06ca97b873]\n\n2010-08-22  michaelp  <baseball.mjp@gmail.com>\n\n\t* patches/patch-gcc-3.4.x, patches/patch-gcc-4.0.x, d/patches\n\t/patch-gcc-4.1.x, patches/patch-gcc-4.2.x, patches/patch-\n\tgcc-4.3.x, patches/patch-toplev-3.4.x, patches/patch-\n\ttoplev-4.0.x, patches/patch-toplev-4.1.x, patches/patch-\n\ttoplev-4.2.x, patches/patch-toplev-4.3.x:\n\tUpdated patches for D2/druntime\n\t[dc882e7537c0]\n\n2010-08-22  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d-bi-attrs-44.h, d-builtins.c, d-builtins2.cc,\n\td-codegen.cc, d-decls.cc, d-gcc-includes.h, d-lang.cc,\n\td-objfile.cc, patches/patch-gcc-4.4.x, patches/patch-\n\ttoplev-4.4.x, d/setup-gcc.sh:\n\tBuilding on GCC-4.4 now supported.\n\t[0616ebb4255b]\n\n\t* d-lang.cc:\n\tIssue #51: 1.062 outstanding issues\n\t[9663a271233b]\n\n2010-08-20  michaelp  <baseball.mjp@gmail.com>\n\n\t* phobos2/*:\n\tUpdated phobos2 to 2.020 (not working)\n\t[08d9a5b24ff4]\n\n2010-08-20  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-glue.cc:\n\tFix ICE on shorthand if statements.\n\t[ef2959fa8184]\n\n2010-08-20  michaelp  <baseball.mjp@gmail.com>\n\n\t* d-glue.cc:\n\tFixed problem with continue statements in D2\n\t[511f3176ec0d]\n\n2010-08-20  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-lang.cc, druntime/compiler/gdc/arraybyte.d,\n\tdruntime/compiler/gdc/arraydouble.d,\n\tdruntime/compiler/gdc/arrayfloat.d,\n\tdruntime/compiler/gdc/arrayint.d,\n\tdruntime/compiler/gdc/arrayshort.d, phobos/internal/arraybyte.d,\n\tphobos/internal/arraydouble.d, phobos/internal/arrayfloat.d,\n\tphobos/internal/arrayint.d, phobos/internal/arrayshort.d,\n\tphobos2/internal/arraybyte.d, phobos2/internal/arraydouble.d,\n\tphobos2/internal/arrayfloat.d, phobos2/internal/arrayint.d,\n\tphobos2/internal/arrayshort.d:\n\tIssue #30: D_InlineAsm updates\n\t[ce1833f9106a]\n\n2010-08-19  michaelp  <baseball.mjp@gmail.com>\n\n\t* d-lang.cc:\n\tFixed JSON option for D2\n\t[2118f4d1de83]\n\n\t* d/setup-gcc.sh:\n\tUpdated setup-gcc.sh for libdruntime building\n\t[6e7640bc2b3c]\n\n\t* patches/patch-toplev-4.1.x, patches/patch-toplev-4.2.x,\n\tpatches/patch-toplev-4.3.x:\n\tUpdated toplevel 4.1, 4.2, and 4.3 patches for libdruntime\n\t[1df5716f2b88]\n\n\t* patches/patch-toplev-3.4.x, patches/patch-toplev-4.0.x:\n\tUpdated 3.4 + 4.0 toplevel patches to include libdruntime\n\t[a74ceca3c239]\n\n\t* dmd/func.c:\n\tIssue #57: C-style variadic functions broken\n\t[ae817bd07dbf]\n\n2010-08-19  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* phobos/*:\n\tUpdated Phobos to 1.063 - expanded tabs.\n\t[bbe96bfd09dd]\n\n2010-08-17  michaelp  <baseball.mjp@gmail.com>\n\n\t* d-glue.cc:\n\tOne of Issue #56. Cannot goto into finally block\n\t[22792e6a6253]\n\n2010-08-17  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc, d-glue.cc, d-irstate.cc, d-irstate.h:\n\tBugzilla 1041 - incorrect code gen for scope(exit) inside switch\n\t[d472abadf847]\n\n2010-08-16  michaelp  <baseball.mjp@gmail.com>\n\n\t* d-glue.cc, dmd/func.c, dmd/statement.c, dmd/statement.h:\n\tTemporarily reverted 1.063 change\n\t[d89d1a46125d]\n\n2010-08-16  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/asmstmt.cc, d-apple-gcc.c, d-asm-i386.h, d-builtins.c,\n\td-builtins2.cc, d-c-stubs.c, d-codegen.cc, d-codegen.h,\n\td-convert.cc, d-cppmngl.cc, d-decls.cc, d-gcc-includes.h,\n\td-gcc-real.h, d-glue.cc, d-irstate.cc, d-lang.cc,\n\td-lang.h, d-objfile.cc, d-spec.c, d/dt.cc, d/dt.h,\n\td/gdc_alloca.h, d/symbol.cc:\n\tAdded GPL onto files missing it, attributed modifications.\n\t[4d41771eba7c]\n\n2010-08-15  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc:\n\tSome more type conversion updates in glue.\n\t[4567e417c0b3]\n\n2010-08-14  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-apple-gcc.c, d-codegen.cc, d-convert.cc, d-glue.cc,\n\td-lang.cc:\n\tRemove default_conversion, tighten up signed/unsigned conversions.\n\t[c1ae96f4e1a6]\n\n\t* d-builtins2.cc, d-codegen.cc, d-glue.cc, d-lang.cc,\n\td-lang.h:\n\tRemoved references to TREE_UNSIGNED.\n\t[4a59c1bbc04c]\n\n\t* d-gcc-includes.h:\n\tFixed previous glue commit.\n\t[9cac96f771a1]\n\n2010-08-14  michaelp  <baseball.mjp@gmail.com>\n\n\t* phobos/std/thread.d:\n\tUpdated thread_attach bug in Windows\n\t[de30c34ef79d]\n\n2010-08-14  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/asmstmt.cc, d-builtins2.cc, d-codegen.cc, d-gcc-includes.h,\n\td-glue.cc, d-lang.cc, d-objfile.cc:\n\tGlue touch-ups, now uses D_USE_MAPPED_LOCATION\n\t[6122f6d23a71]\n\n2010-08-13  michaelp  <baseball.mjp@gmail.com>\n\n\t* d-cppmngl.cc:\n\tUploaded missing fix from 1.063 merge\n\t[fc7de0a268ab]\n\n\t* dmd/template.c:\n\tFixed implicit conversion of template parameters\n\t[888e3cc8a31d]\n\n\t* d-glue.cc, dmd/async.c, dmd/declaration.c,\n\tdmd/declaration.h, dmd/dsymbol.c, dmd/dsymbol.h, dmd/enum.c,\n\tdmd/enum.h, dmd/expression.c, dmd/func.c, dmd/init.c,\n\tdmd/interpret.c, dmd/mars.c, dmd/mars.h, dmd/module.c,\n\tdmd/module.h, dmd/mtype.c, dmd/parse.c, dmd/parse.h,\n\tdmd/root.c, dmd/statement.c, dmd/statement.h, dmd/todt.c,\n\tphobos/internal/deh2.d, phobos/internal/object.d,\n\tphobos/std/math.d:\n\tUpdated to 1.063\n\t[f1e726cbcc98]\n\n2010-08-11  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d-bi-attrs-34.h, d-bi-attrs-341.h, d-bi-\n\tattrs-40.h, d-bi-attrs-41.h, d-bi-attrs-42.h, d-bi-attrs-43.h,\n\td-builtins.c:\n\tCleanup d-bi-attrs. Make includes slightly smarter.\n\t[349f85192e52]\n\n\t* d-codegen.cc:\n\tRemove useless trial/error comments in function.\n\t[89b4363653f8]\n\n2010-08-10  michaelp  <baseball.mjp@gmail.com>\n\n\t* d-codegen.cc:\n\tIssue 33 - Sefault with nested array allocation\n\t[be805cb4fb58]\n\n2010-08-09  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, patches/patch-gcc-4.2.x, patches/patch-\n\ttoplev-4.2.x, d/setup-gcc.sh:\n\tBuilding on GCC-4.2 now supported.\n\t[c1b55292cd94]\n\n\t* d-codegen.cc, d-glue.cc, d-irstate.cc:\n\tApply adaptation of feep's autovec patch (one big thanks!)\n\t[fbce9c0580d3]\n\n\t* d/asmstmt.cc, d-asm-i386.h:\n\tReplace tabs for space in ASM outbuffer.\n\t[659f6f38f6f4]\n\n2010-08-09  michaelp  <baseball.mjp@gmail.com>\n\n\t* d/dmd-script:\n\tWhitespace fix to previous commit.\n\t[0fee937d84d4]\n\n\t* d-lang.cc, d/dmd-script, d/lang.opt:\n\tAdded JSON support - Issue 52 + gdmd usage change\n\t[35f04cb2339c]\n\n\t* d/dmd-script:\n\tAdded -defaultlib= and -debuglib= into gdmd usage\n\t[e34a68f9c427]\n\n\t* d/dmd-script:\n\tUpdated -defaultlib and -debuglib switches for gdmd - Issue 46\n\t[181e89b3d8d6]\n\n2010-08-08  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-builtins.c, d-c-stubs.c, d-codegen.cc, d-glue.cc,\n\td-lang.h:\n\tBuild with GCC-3.4 working again.\n\t[58e9b23e110c]\n\n\t* d/Make-lang.in, dmd2/array.c, dmd2/mars.c, dmd2/root.c,\n\tdmd2/total.h:\n\tUpdates of previous commit\n\t[41657ecdc3fe]\n\n\t* d/Make-lang.in, d-decls.cc, dmd/expression.c, dmd2/arrayop.c,\n\tdmd2/bit.c, dmd2/complex_t.h, dmd2/e2ir.c, dmd2/lib.h,\n\tdmd2/libelf.c, dmd2/link.c, dmd2/man.c, dmd2/port.h,\n\tdmd2/template.c, dmd2/tocsym.c, dmd2/toir.c, dmd2/toir.h,\n\tdmd2/toobj.c, d/symbol.cc, d/symbol.h:\n\tIssue 29 - Remove unused D2 files\n\t[fdef7864146b]\n\n\t* d-decls.cc:\n\tBugzilla 1296 - ICE when object.d is missing things\n\t[e9bfccc01834]\n\n2010-08-06  michaelp  <baseball.mjp@gmail.com>\n\n\t* d/dmd-script:\n\tMore updates to gdmd\n\t[d77ee89f6174]\n\n2010-08-05  michaelp  <baseball.mjp@gmail.com>\n\n\t* d/dmd-script:\n\tSmall changes to gdmd; some fixes for Issue 46\n\t[9269acda0b86]\n\n2010-08-05  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-decls.cc, d-glue.cc:\n\tFix logic on array ops. Fixup comments for previous commits.\n\t[5792cfbf3ae7]\n\n\t* d-glue.cc:\n\tIssue 43: >>> and >>>= generate wrong code\n\t[56caae262c41]\n\n2010-08-02  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-lang.cc:\n\tRegression in D1 when building with --enable-checking\n\t[6f2adfcabae6]\n\n\t* d-spec.c:\n\tCheck missing argument for -defaultlib\n\t[8d59f275476b]\n\n\t* d-decls.cc:\n\tIssue 47: GDC improperly handles extern(System) and extern(Windows) on\n\tWindows\n\t[e5b50cb17c57]\n\n2010-07-31  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc, dmd/todt.c:\n\tIssue 51: 1.062 outstanding issues\n\t[f41ce1e8e5b2]\n\n\t* dmd/aav.c, dmd/aav.h, dmd/arrayop.c, dmd/attrib.c,\n\tdmd/cast.c, dmd/constfold.c, dmd/dsymbol.c,\n\tdmd/expression.c, dmd/imphint.c, dmd/interpret.c,\n\tdmd/lexer.c, dmd/mtype.c, dmd/parse.c, dmd/speller.h,\n\tdmd/statement.c, dmd/toobj.c, dmd/unittests.c, dmd/utf.c:\n\tLine endings, cleanups, and a missing ')'\n\t[84378e5ef655]\n\n\t* d-codegen.cc, d-glue.cc:\n\tGlue updates for previous merge.\n\t[a48e13277e67]\n\n2010-07-31  michaelp  <baseball.mjp@gmail.com>\n\n\t* d-glue.cc, dmd/*, phobos/std/date.d:\n\tUpdated to 1.062\n\t[9f7927e5f551]\n\n2010-07-30  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-spec.c:\n\tAdded -defaultlib and -debuglib to allow building with another\n\tlibrary other than libphobos.\n\t[f7a52f778a09]\n\n\t* druntime/*:\n\tInitial import of druntime into project.\n\t[2f052aaedd25]\n\n\t* d-glue.cc:\n\tFix generation of D array concatenation calls.\n\t[d70321dcd604]\n\n\t* phobos2/acinclude.m4, phobos2/configure, phobos2/configure.in,\n\tphobos2/internal/arrayassign.d, phobos2/phobos-ver-syms.in:\n\tD2 now defines Posix.\n\t[575ed6d347e0]\n\n\t* dmd/parse.c, dmd/speller.c:\n\tInclude header needed for MinGW to build.\n\t[5260cab6c448]\n\n2010-07-29  michaelp  <baseball.mjp@gmail.com>\n\n\t* phobos2/std/c/stdio.d:\n\tFixed accidentally reapplied Windows patch\n\t[d4356fb371ee]\n\n\t* d/Make-lang.in, dmd/aav.c, dmd/aav.h, dmd/class.c,\n\tdmd/declaration.c, dmd/dsymbol.c, dmd/dsymbol.h,\n\tdmd/expression.c, dmd/func.c, dmd/imphint.c, dmd/mars.c,\n\tdmd/mars.h, dmd/optimize.c, dmd/scope.c, dmd/speller.c,\n\tdmd/struct.c, dmd/template.c, phobos2/std/c/stdio.d:\n\tUpdated to 1.061\n\t[9038432ea1ff]\n\n\t* phobos/std/c/stdio.d, phobos2/std/c/stdio.d:\n\tRemove stdio.d patches from Issue 21 patch\n\t[a53c51fad1bd]\n\n\t* d-decls.cc, phobos/std/c/stdio.d, phobos2/std/c/stdio.d:\n\tIssue 21 - _iob undefined reference under Windows\n\t[ea913c7eec42]\n\n\t* d-glue.cc:\n\tFixed array ops bugs from 1.059\n\t[92c39c74433f]\n\n\t* d/Make-lang.in, dmd/cast.c, dmd/class.c, dmd/declaration.c,\n\tdmd/declaration.h, dmd/dsymbol.c, dmd/expression.c,\n\tdmd/expression.h, dmd/idgen.c, dmd/init.c, dmd/inline.c,\n\tdmd/interpret.c, dmd/json.c, dmd/mars.c, dmd/mtype.c,\n\tdmd/parse.c, dmd/speller.c, dmd/speller.h, dmd/statement.h,\n\tdmd/unittests.c:\n\tUpdated to 1.060\n\t[1c1cc97db718]\n\n2010-07-28  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/dmd-script, d/lang-specs.h:\n\tIssue 48: gdc/gdmd should be able to compile .di files\n\t[976a611f59f3]\n\n\t* d-lang.cc, dmd/*, phobos/*:\n\tUpdated to 1.058\n\t[9ac6a02138c2]\n\n\t* d/Make-lang.in, dmd/machobj.c:\n\tRemove machobj.c from D1\n\t[67d109f8fe79]\n\n\t* d-lang.cc, d/dmd-script, d/symbol.cc:\n\tIssue 42: -Wall should not error out compiler\n\t[7593822be7c0]\n\n2010-07-27  michaelp  <baseball.mjp@gmail.com>\n\n\t* d/Make-lang.in, d-lang.cc, d/dmd-script, dmd/dsymbol.c,\n\tdmd/dsymbol.h, dmd/expression.c, dmd/func.c, dmd/init.c,\n\tdmd/inline.c, dmd/interpret.c, dmd/machobj.c, dmd/mars.c,\n\tdmd/mars.h, dmd/module.c, dmd/module.h, dmd/mtype.c,\n\tdmd/root.c, dmd/root.h, dmd/scope.c, dmd/scope.h,\n\tdmd/speller.c, dmd/speller.h, dmd/statement.c,\n\tdmd/template.c, d/lang.opt, phobos/internal/aaA.d:\n\tUpdated to 1.057\n\t[b4fb93e94c29]\n\n2010-07-27  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, dmd/array.c, dmd/bit.c, dmd/complex_t.h,\n\tdmd/constfold.c, dmd/e2ir.c, dmd/elfobj.c, dmd/expression.c,\n\tdmd/irstate.c, dmd/irstate.h, dmd/lib.h, dmd/libelf.c,\n\tdmd/libmach.c, dmd/link.c, dmd/man.c, dmd/mars.c,\n\tdmd/mem.c, dmd/mem.h, dmd/mtype.c, dmd/port.c, dmd/port.h,\n\tdmd/root.c, dmd/tocsym.c, dmd/toir.c, dmd/toir.h:\n\tIssue 29 - Remove unused D1 files\n\t[d74291c4230b]\n\n\t* dmd/template.c, dmd2/template.c:\n\tIssue 36: duplicate symbols created for negatively initialized template\n\tarugments\n\t[1bd9793d8fc6]\n\n\t* d-builtins.c:\n\tPartial fix for Issue 28\n\t[7fb5519947d4]\n\n\t* d-lang.cc:\n\tIssue 44: strange code in d-asm-1386.h\n\t[73c379cc9714]\n\n2010-07-26  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc, d-glue.cc:\n\tD2 postblit on struct literals finished!\n\t[9ee37bd66bca]\n\n2010-07-25  michaelp  <baseball.mjp@gmail.com>\n\n\t* d-lang.cc, d/dmd-script, dmd/*,\n\tphobos/internal/arrayfloat.d:\n\tUpdated to 1.056\n\t[4ff162deda23]\n\n2010-07-24  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-glue.cc:\n\tD2 postblit updates.\n\t[d53a8be7c0ed]\n\n2010-07-23  michaelp  <baseball.mjp@gmail.com>\n\n\t* dmd/class.c, dmd/enum.c, dmd/enum.h, dmd/mars.c,\n\tdmd/struct.c:\n\tUpdated to 1.055\n\t[9c62fb9d0abf]\n\n\t* dmd/expression.c:\n\tFixed spot with wrong patch in it\n\t[172855a888e9]\n\n\t* dmd/*, phobos/internal/gc/gcx.d:\n\tUpdated to 1.054\n\t[64df5a74b2c4]\n\n2010-07-21  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-lang.cc:\n\tFixed warnings in d-lang.cc (thanks Trass3r)\n\t[7a3c1ae0b625]\n\n\t* d-asm-i386.h:\n\tFix cast warnings in d-asm-i386.h\n\t[fa9b66399a13]\n\n\t* dmd/lexer.c, dmd2/lexer.c:\n\tFix buffer overflow in certain error messages\n\t[b91574453f5e]\n\n\t* d-asm-i386.h:\n\tCorrectly check align value in asm.\n\t[d5a0f3619810]\n\n2010-07-20  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-glue.cc, dmd/root.c, dmd/statement.c, dmd/template.c,\n\tdmd/template.h, phobos/std/c/stddef.d:\n\tQuick updates to D1 and postblit code.\n\t[214fbfbf5f3f]\n\n\t* d-builtins2.cc, d-codegen.cc, d-codegen.h, d-glue.cc,\n\tdmd/expression.c, dmd/func.c, dmd/machobj.c, dmd/mtype.c,\n\tdmd/parse.c, dmd/statement.c, dmd/statement.h, dmd/toobj.c,\n\tphobos/internal/gc/gc.d:\n\tSome whitespace corrections.\n\t[c9c54a275526]\n\n2010-07-20  michaelp  <baseball.mjp@gmail.com>\n\n\t* d-builtins2.cc, d-codegen.cc, d-codegen.h, d-glue.cc,\n\tdmd/*, phobos/*:\n\tUpdated to 1.053\n\t[f02a96cfc1de]\n\n2010-07-20  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-glue.cc:\n\tQuick revision updates\n\t[c79811b4f1fc]\n\n2010-07-19  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-glue.cc, dmd2/attrib.c, dmd2/cast.c, dmd2/cond.c,\n\tdmd2/constfold.c, dmd2/declaration.c, dmd2/declaration.h,\n\tdmd2/e2ir.c, dmd2/expression.c, dmd2/func.c,\n\tdmd2/impcnvgen.c, dmd2/lexer.c, dmd2/lexer.h, dmd2/link.c,\n\tdmd2/mars.c, dmd2/mtype.c, dmd2/mtype.h, dmd2/parse.c,\n\tdmd2/parse.h, dmd2/statement.c, dmd2/toir.c:\n\tUpdated to 2.020 - Frontend Only\n\t[676f0aa79458]\n\n2010-07-17  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* phobos2/Makefile.in:\n\tlibgphobos2 Makefile fixes.\n\t[c4acdacfddd2]\n\n2010-07-16  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\tMerge with DMD 2.019\n\n\t* d-decls.cc: Merge changes from dmd2/tocsym.c\n\n\t* phobos/Makefile.am, phobos/Makefile.in, phobos2/Makefile.am,\n\tphobos2/Makefile.in: Fix build for check-target-libphobos tests.\n\n\t* d-decls.cc, d-objfile: Fixed ICE in gdc-4.3 [39825b8156a3]\n\n2010-07-14  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\tMerge with DMD 2.018\n\n\t* d-lang.cc: Added support for AsyncRead in D1.\n\n\t* dmd/constfold.c, dmd2/constfold.c: Fixed lost precision when casting\n\tfrom large floats to integral types.\n\n\t* dmd/todt.c, dmd2/todt.c: Fixed initialiased pointer array values\n\tbeing reset to null during compilation.\n\n\t* Make-lang.in, d-backendfunctions.c, dmd/template.c: Removed\n\tbackendfunctions.c from Makefile.\n\n2010-07-11  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-asm-i386.h: AMD Opcodes Supported.\n\n\t* Make-lang.in, dmd/mtype.c, dmd/struct.c, target-ver-syms.sh:\n\tstruct ABI fixes.\n\n\t* phobos/std/math.d, phobos2/std/math.d: Fix wrong return value in\n\texpi() function.\n\n2010-07-07  michaelp  <baseball.mjp@gmail.com>\n\n\t* dmd/arrayop.c: Fix problem with float array operations.\n\t- Added linear search for the array op library functions.\n\n2010-07-05  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* dmd2/..., phobos2/...: Resolved issues for DMD 2.017.\n\n\t* phobos2/configure, phobos2/configure.in: Re-add GNU_Need_execvpe for\n\tD2 libphobos.\n\n\t* dmd/mtype.h, phobos2/internal/object.d, phobos2/std/cpuid.d:\n\tQuick updates to previous revisions.\n\n2010-07-05  michaelp  <baseball.mjp@gmail.com>\n\n\tMerge DMD 2.017\n\n2010-07-04  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\tMerge DMD 1.052\n\n\t* d-glue.cc: Fix ICE when using type tuple as function argument.\n\n\t* phobos/..., phobos2/...: libphobos cleanup and updates.\n\n\t* d-codegen.cc, d-decls.cc: Fix problem when building with\n\t--enable-checking.\n\n2010-06-28  michaelp  <baseball.mjp@gmail.com>\n\n\t* setup-gcc.sh: D1 is default in setup-gcc.sh now.\n\n2010-06-27  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\tMerge with DMD 1.050\n\n\t* Make-lang.in: Update for files added in DMD 1.050.\n\n\t* phobos/etc/c/zlib.d, phobos/std/zlib.d, phobos2/etc/c/zlib.d:\n\tUpdated Zlib to 1.2.3.\n\n2010-06-22  michaelp  <baseball.mjp@gmail.com>\n\n\t* phobos/configure, phobos/configure.in, phobos/std/process.d,\n\tphobos2/configure, phobos2/configure.in, phobos2/std/process.d:\n\tFix problem when building with a version of GNU C that has execvpe()\n\timplemented (staring with glibc-2.11).\n\n\t* phobos/configure, phobos/configure.in, phobos/std/c/freebsd/freebsd.d:\n\tFix problem when linking on FreeBSD targets.\n\n2010-06-19  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\tMerge with DMD 1.049\n\n\t* d-lang.cc: Merge changes from dmd/mars.c.\n\n\t* d-codegen.cc, d-decls.cc: Fix ICEs in const array assignments.\n\n\t* d-lang.cc, dmd-script, lang.opt: Added -fdeps option to gdc and\n\t-deps to gdmd.\n\n\t* dmd/mem.c, dmd/mem.h, dmd/port.c, dmd/rmem.h, dt.cc, dt.h,\n\tphobos/internal/qsortg.d: Remove executable bit on source files.\n\n2010-06-12  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\tMerge with DMD 1.047\n\n\t* d-codegen.cc: Look for reference initializations in foreach\n\tstatement assignments.\n\n\t* dmd/..., dmd2/..., phobos/..., phobos2/...: Converted CR, CRLF line\n\tendings to LF (thanks to venix1).\n\n2010-06-04  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\t* d-asm-i386.h: Apply patch to compile tango (thanks to venix1).\n\n2010-04-05  michaelp  <baseball.mjp@gmail.com>\n\n\tMerge with DMD 1.046\n\n\t* d-decls.cc: Fix problem with struct declarations in GCC-4.3.x.\n\n\t* dmd-script: Added -pipe option to gdmd\n\n\t* d-lang.cc, phobos/...: Fix FreeBSD and Windows version issues.\n\n\t* dmd/root.c: Fix Windows template instantiating error.\n\n\t* dmd/func.c: Fix segfault on wrong arg type.\n\n2010-02-17  Vincenzo Ampolo  <vincenzo.ampolo@gmail.com>\n\n\t* d-glue.cc: Make d1 classinfo like d2 ones.\n\n\t* dmd/expression.c, phobos/std/process.d: Apply feep (downs) patch.\n\n2010-02-07  michaelp  <baseball.mjp@gmail.com>\n\n\tMerge with 1.045\n\n\t* phobos/linux.mak, phobos/win32.mak: Removed Phobos .mak files for\n\tD 1.045 update.\n\n\t* samples/hello.d, samples/samples.sh: Added 1 file to samples\n\tdirectory.\n\n2010-01-15  opticron  <nyphbl8d@gmail.com>\n\n\t* phobos/std/string.d: Fix a set of bugs in std.string.split which\n\tmade delemiters of length > 1 segfault.\n\n\f\nCopyright (C) 2010 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2011",
    "content": "2011-12-31  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-glue.cc, d/d-irstate.cc: Revert some prior code\n\tadditions.\n\t[a61a03e817c3]\n\n\t* d/d-decls.cc, d/d-glue.cc: Issue #301 - ref return funcs returning\n\twrong reference\n\t[2350d3a27ac8]\n\n2011-12-30  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-irstate.cc, d/d-lang.cc: Implicitly convert all statements to\n\tvoid, warn if statement has no side effects.\n\t[d73ff02f1131]\n\n\t* d/d-decls.cc, d/d-glue.cc: mark RESULT_DECL as artificial.\n\t[a2de4187caa4]\n\n\t* d/d-codegen.cc, d/d-glue.cc: Remove check for isref out of ::call\n\tand into CallExp::toElem\n\t[1b827c7df15c]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc: Use INIT_EXPR instead of\n\tMODIFY_EXPR where applicable, added vinit.\n\t[27c401e61169]\n\n\t* d/d-codegen.cc, d/d-codegen.h: Move functions written in d-codegen\n\theader to source file.\n\t[605c79094f14]\n\n\t* d/d-codegen.cc: Issue #302 - lazy arg causing ICE in\n\tgimple_expand_cfg, at cfgexpand.c:4063\n\t[786acc44a0ff]\n\n2011-12-28  Daniel Green  <venix1@gmail.com>\n\n\t* d/phobos2/Makefile.am, d/phobos2/Makefile.in: Add\n\tstd/internal/windows/advapi32.o to WINDOWS_OBJS.\n\t[e7639c523add]\n\n2011-12-28  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-gcc-includes.h, d/d-glue.cc: Emit pretty debug tree information\n\ton -fdump-tree-original\n\t[7631e902659e]\n\n\t* d/d-asm-i386.h, d/d-codegen.h, d/d-glue.cc, d/d-lang.cc,\n\td/d-objfile.cc: Remove some dead code.\n\t[e8ae51578e54]\n\n\t* d/d-codegen.cc, d/d-decls.cc, d/d-glue.cc, d/d-lang-45.h,\n\td/d-lang.cc, d/d-lang.h, d/d-objfile.cc: Issue #258 - cannot access\n\tframe with contract inheritance\n\t[0b470bc59251]\n\n\t* d/d-lang.cc, d/gdc.1, d/lang.opt: Add switches to control in(),\n\tout() and invariant() code generation.\n\t[e9904da308eb]\n\n\t* d/asmstmt.cc, d/d-builtins2.cc, d/d-decls.cc, d/d-glue.cc,\n\td/patches/patch-gcc-4.2.x, d/patches/patch-gcc-4.3.x,\n\td/patches/patch-gcc-4.4.x, d/patches/patch-gcc-4.5.x,\n\td/patches/patch-gcc-4.6.x: Remove gdc patch to cgraph.c - fix codegen.\n\t[fc5e3bddbf94]\n\n\t* d/d-decls.cc: Issue #298 - Array Range Functions Don't Get Inlined\n\t[f9217ce815ea]\n\n2011-12-25  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-glue.cc, d/dmd2/expression.c, d/dmd2/expression.h,\n\td/dmd2/optimize.c, d/phobos/configure, d/phobos2/configure: Fixup\n\tarrayliteral assignments.\n\t[d71656e55ad8]\n\n\t* d/phobos/configure, d/phobos2/configure: Rebuild configure for D1\n\t[bedf43669633]\n\n\t* d/d-glue.cc: Issue #297 - GDC Acquires Locks Twice in Synchronized\n\tMember Methods.\n\t[7470a20b2900]\n\n\t* d/d-objfile.cc, d/d-objfile.h: First attack at fixing issue #246\n\t[bd1f89846e93]\n\n2011-12-23  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc: Issue #287 - Casting between array types is broken.\n\t[63647d6f2b87]\n\n\t* d/phobos2/Makefile.in, d/phobos2/configure: Rebuild Makefile.in,\n\tconfigure for D2.\n\t[b3200b086277]\n\n\t* d/d-lang.cc: Issue #296 - -fproperty implies -frelease\n\t[4dfa4c11ccd7]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-lang.cc: Remove unused\n\twarnSignCompare.\n\t[60ea5d6b4173]\n\n\t* d/d-codegen.cc: Issue #289 - ICE: in extract_range_from_binary_expr,\n\tat tree-vrp.c:229\n\t[9076a0f27fd9]\n\n\t* d/dmd-script, d/dmd-script.1, d/gdc.1: Update manpages for new\n\tGDC/GDMD options.\n\t[9caec4bea289]\n\n\t* d/d-objfile.cc: Issue #279 - ICE: in gimple_expand_cfg\n\t[6778c7a1f79e]\n\n\t* d/d-builtins2.cc: Add CTFE support for builtins atan2, rndtol,\n\texpm1, exp2.\n\t[afe30f1b9435]\n\n2011-12-18  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc: D2 - Handle nulltype to D array conversions.\n\t[d7fe9fa5bb6c]\n\n\t* d/d-glue.cc, d/d-lang.cc: Match GCC logic for emitting D_LP64\n\tversion identifier.\n\t[7475431fe1bd]\n\n\t* d/d-codegen.cc, d/d-decls.cc, d/d-glue.cc: Better implementation of\n\tbt, btc, bts, btr functions, allowing constant folding.\n\t[caf2c8d4f036]\n\n\t* d/d-builtins2.cc: Implement CTFE for bswap, bsr, bsf.\n\t[730c51fcdd3e]\n\n\t* d/druntime/core/thread.d: Issue #290 - errno conflict in std.file\n\t[ecd60be7f89c]\n\n\t* d/d-lang.cc: Define D_LP64 if is64bit.\n\t[633ea9c9e5bf]\n\n\t* d/dmd-script: Issue #282 - gdmd multithreaded -lib implementation.\n\t[f1bd82f9bb5b]\n\n\t* d/dmd-script: Issue #283 - gdmd: libraries not put into -od dir.\n\t[75a7b584473a]\n\n\t* d/d-objfile.cc, d/dmd/attrib.c, d/dmd2/attrib.c, d/lang.opt: Issue\n\t#286 - -fignore-unknown-pragmas doesn't seem to work\n\t[f342fde254e2]\n\n2011-12-16  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-builtins2.cc, d/d-codegen.cc, d/d-decls.cc, d/d-glue.cc,\n\td/d-irstate.cc, d/d-irstate.h, d/d-lang.cc, d/dmd2/*, d/druntime/*,\n\td/phobos2/*: Updated D2 Frontend to 2.057\n\t[36c28efc6c88]\n\n2011-12-11  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/dmd/*: Updated D1 Frontend to 1.072\n\t[e83cac3b4109]\n\n\t* d/dmd/expression.c, d/dmd2/expression.c: Issue #279 - ICE: in\n\tgimple_expand_cfg\n\t[c501487a685a]\n\n2011-12-08  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/asmstmt.cc, d/d-asm-i386.h, d/d-builtins2.cc,\n\td/d-codegen.cc, d/d-cppmngl.cc, d/d-decls.cc, d/d-dmd-gcc.h,\n\td/d-glue.cc, d/d-irstate.cc, d/d-lang-45.h, d/d-lang-type-45.h,\n\td/d-lang-type.h, d/d-lang.cc, d/d-lang.h, d/d-objfile.cc,\n\td/dmd-script, d/dmd2/*, d/druntime/*, d/phobos2/*: Updated D2 Fronted\n\tto 2.056\n\t[fbe890ef4c1f]\n\n\t* d/d-codegen.cc, d/d-glue.cc: Relax conversion checking. Move getImpl\n\tto CastExp.\n\t[b0407ff2e57c]\n\n\t* d/dmd/optimize.c, d/dmd2/optimize.c: Remove old frontend ifdef'd\n\tcode.\n\t[8e0291212f46]\n\n2011-12-02  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-lang.cc, d/lang-specs.h, d/lang.opt: remove preprocessor options\n\tfrom spec and use own switches.\n\t[5f71b69d1494]\n\n\t* d/d-objfile.cc: Issue #275 - ICE with wrong interface implementation\n\t[e32c8fbe7343]\n\n\t* d/d-lang.cc, d/dmd/mars.h, d/dmd2/mars.h, d/lang-specs.h,\n\td/lang.opt: Issue #236 - -M, -MM, -MF options to generate dependencies\n\tlike gcc\n\t[3763796b9cbf]\n\n\t* d/d-lang.cc, d/lang.opt: ASCII collate lang switches.\n\t[951ff44f1035]\n\n2011-12-02  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-objfile.cc: Issue #268 - ICE with -flto and -g\n\t[3da453291dc3]\n\n2011-11-24  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in: Issue #266 - make install-strip fails to install\n\tgdmd.\n\t[d1005cb77a06]\n\n\t* d/d-glue.cc, d/d-lang.cc, d/dt.cc: Remove checks for\n\ttype_structural_equality for now.\n\t[5265f1318114]\n\n\t* d/d-glue.cc: Issue #261 - ICE: tree check: expected record_type or\n\tunion_type, have array_type in delegateVal\n\t[61ab289788a3]\n\n\t* d/d-glue.cc: Issue #264 - ICE: can't convert between bool and enum :\n\tbool\n\t[fcb2523b8ccd]\n\n\t* d/d-codegen.cc, d/d-glue.cc: Issue #263 - forward reference error\n\twith algorithm.find\n\t[75b7e1bca4d7]\n\n2011-11-19  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/asmstmt.cc, d/d-asm-i386.h, d/d-builtins2.cc, d/d-decls.cc,\n\td/d-glue.cc, d/d-irstate.cc, d/d-lang-45.h, d/d-lang.cc, d/d-lang.h,\n\td/d-objfile.cc: Add d_free, rename dkeep to d_keep.\n\t[a0e0fcfd913c]\n\n2011-11-18  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-builtins2.cc, d/d-codegen.cc, d/d-lang-45.h, d/d-lang.cc,\n\td/d-lang.h: Issue #262 - ICE: weird segfault when -o option is used\n\t[51d11a9bddf2]\n\n\t* d/d-lang.cc: Issue #255 - ICE: invalid conversion in gimple call\n\t[36ae9c015e86]\n\n\t* d/d-decls.cc: Issue #259 - ICE: constant not recomputed when\n\tADDR_EXPR changed\n\t[72c16f7ab674]\n\n\t* d/d-builtins2.cc, d/d-dmd-gcc.h, d/dmd/attrib.c,\n\td/dmd/declaration.c, d/dmd/declaration.h, d/dmd/mtype.c,\n\td/dmd/struct.c, d/dmd2/attrib.c, d/dmd2/declaration.c,\n\td/dmd2/declaration.h, d/dmd2/mtype.c, d/dmd2/struct.c: Issue #215 -\n\tAlignment of struct members wrong on ARM\n\t[2df7ca5fa4b6]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-decls.cc, d/d-glue.cc,\n\td/d-lang.cc: Issue #242 - Another lambda segfault\n\t[467d7fa518fc]\n\n2011-10-31  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-lang.cc: Arm -> ARM and darwin -> Darwin in d-lang.cc.\n\t[51e67c38af0c]\n\n2011-10-30  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/target-ver-syms.sh: Make some system and CPU version identifiers\n\tconsistent in casing.\n\t[5d11c2ded7b7]\n\n\t* d/d-codegen.cc, d/d-decls.cc, d/d-glue.cc: Use isMember2 when\n\tchecking member functions.\n\t[d89c3b7d495a]\n\n\t* d/d-codegen.cc, d/d-decls.cc, d/d-lang-45.h, d/d-lang.h,\n\td/d-objfile.cc: Issue #78 D1/D2 - in/out contract inheritance\n\t[736ae4b92f2]\n\n2011-10-26  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/asmstmt.cc, d/d-asm-i386.h, d/d-glue.cc, d/d-irstate.cc: Issue\n\t#252 - Error: suffix or operands invalid for `jc'\n\t[0d65aed46422]\n\n\t* d/lang-specs.h, d/patches/patch-apple-gcc-5465,\n\td/patches/patch-apple-gcc-5664, d/patches/patch-gcc-4.2.x,\n\td/patches/patch-gcc-4.3.x, d/patches/patch-gcc-4.4.x,\n\td/patches/patch-gcc-4.5.x, d/patches/patch-gcc-4.6.x: Issue #251 -\n\tRemove all references to fmultilib-dir usage in gdc spec and patches.\n\t[c72727fc3f13]\n\n2011-10-23  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/druntime/core/stdc/stdio.d, d/druntime/core/stdc/stdlib.d,\n\td/druntime/rt/critical_.d, d/druntime/rt/dmain2.d,\n\td/druntime/rt/monitor_.d, d/phobos/config/libc.x3,\n\td/phobos2/config/libc.x3, d/target-ver-syms.sh: Start on implementing\n\tplatform agnostic druntime for GDC D2.\n\t[c46d1009bd78]\n\n\t* d/d-lang.cc, d/target-ver-syms.sh: Add VENDOR_VERSYM to D version\n\tidentifiers if defined.\n\t[f7abc9009d0d]\n\n\t* d/d-lang.cc, d/d-objfile.cc: Issue #224 - Link time optimization\n\t[bf9d0ac53e9d]\n\n\t* d/d-decls.cc, d/d-glue.cc, d/d-irstate.cc, d/d-irstate.h,\n\td/d-lang.cc, d/d-objfile.cc, d/d-objfile.h, d/lang.opt: Merge changes\n\tfrom gcc-4.7 branch.\n\t[5992dd0f2f7e]\n\n\t* d/d-codegen.cc: Use gcc atomics for bt, btc, btr, bts intrinsics.\n\t[2cc2e8c5a778]\n\n\t* d/d-glue.cc: build_assign_math_op: Stabilize LHS expression.\n\t[031b711ce09]\n\n2011-10-21  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/asmstmt.cc, d/d-asm-i386.h, d/d-codegen.cc, d/d-glue.cc,\n\td/d-irstate.cc, d/d-lang-45.h, d/d-lang.h, d/dmd/mtype.c,\n\td/dmd2/mtype.c: Issue #247 - undefined reference to `.LDASM1'\n\t[19de20aec625]\n\n\t* d/asmstmt.cc, d/d-asm-i386.h: Fallback to 32bit instruct suffix when\n\t64bit not available, add special case for fild.\n\t[8789c97f84ac]\n\n\t* d/asmstmt.cc, d/d-asm-i386.h: Issue #248 - Inline assembler\n\tgenerates wrong argument size for FILD instruction.\n\t[8bd2a4ca84c0]\n\n2011-09-27  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/dmd-script: Issue #241 - dmd.conf DFLAGS doesn't work with\n\tDMD-style args.\n\t[4bf307759462]\n\n\t* d/d-codegen.cc, d/d-glue.cc: Issue #239 - Filter + Closure =\n\tSegfault.\n\t[23b24ffe94f2]\n\n\t* d/dmd-script: Properly handle -X and -map switches in gdmd.\n\t[f7c13cf55264]\n\n\t* d/asmstmt.cc, d/d-asm-i386.h, d/d-irstate.cc, d/d-irstate.h: Fixup\n\tsome build warnings.\n\t[891f65500765]\n\n\t* d/dmd-script: Issue #234 - add DFLAGS to the build command in gdmd.\n\t[3acdb17df213]\n\n2011-09-25  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/dmd-script: Issue #234 - dmd.conf equivalent\n\t[db9070d078a8]\n\n\t* d/druntime/core/thread.d, d/phobos2/std/path.d: Re-add fixes that\n\tgot removed in last D library merge.\n\t[a998cdff6e0f]\n\n\t* d/dmd/todt.c, d/dmd2/todt.c, d/dt.cc: size_t'ify toDt.\n\t[c1306d366f94]\n\n\t* d/d-glue.cc: CallExp - only call convert on basic return types.\n\t[bc7ad8e2569]\n\n\t* d/d-gcc-real.cc: real_t::convert - check base type\n\t[71eb59683499]\n\n\t* d/dmd/attrib.c, d/dmd2/attrib.c: Optimise attribute pragma\n\targuments.\n\t[dca4ddf21110]\n\n2011-09-23  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-glue.cc: Issue #235 - ICE in feep's tools library\n\t[17da3d28ba17]\n\n2011-09-15  Daniel Green  <venix1@gmail.com>\n\n\t* d/d-glue.cc: Make PowAssignExp::toElem only compile with D2.\n\t[fa6a47ddbd9c]\n\n\t* d/dt.h: Issue #231.  Use size_t for dt_size declaration in dt.h.\n\t[f9fee0fd57a2]\n\n2011-09-14  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-builtins2.cc, d/d-gcc-real.cc, d/d-gcc-real.h, d/d-glue.cc,\n\td/dmd2/constfold.c, d/dmd2/declaration.h, d/dmd2/expression.c,\n\td/dmd2/expression.h, d/dmd2/interpret.c, d/dmd2/optimize.c: Implement\n\tconstant folding of ^^ expressions.\n\t[06f5e7c038fa]\n\n\t* d/asmstmt.cc, d/d-asm-i386.h, d/d-builtins2.cc, d/d-codegen.cc,\n\td/d-cppmngl.cc, d/d-decls.cc, d/d-glue.cc, d/d-incpath.cc,\n\td/d-lang.cc, d/d-objfile.cc, d/dt.cc: Change unsigned for size_t in\n\tfor loops.\n\t[814fc99ff732]\n\n\t* d/d-lang.cc, d/dmd/mars.c, d/dmd2/mars.c: Re-enforce -Werror flag in\n\tgdc.\n\t[eced11f7d5b5]\n\n\t* d/d-glue.cc: Issue #232 - sqrt(3) == 2.15118e-4930\n\t[8994cef9271f]\n\n2011-09-12  Daniel Green  <venix1@gmail.com>\n\n\t* d/d-lang.cc: Convert Array to Strings required by DMD 1.070/2.055\n\t[fc0033715683]\n\n2011-09-12  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/druntime/rt/dmain2.d, d/druntime/rt/lifetime.d: Issue #214 -\n\tSegfault Allocating from Shared Static C'tor\n\t[41218d9f5f59]\n\n\t* d/asmstmt.cc, d/d-asm-i386.h, d/d-builtins2.cc, d/d-codegen.cc,\n\td/d-codegen.h, d/d-cppmngl.cc, d/d-decls.cc, d/d-dmd-gcc.h,\n\td/d-glue.cc, d/d-incpath.cc, d/d-irstate.cc, d/d-irstate.h,\n\td/d-lang.cc, d/d-objfile.cc, d/d-objfile.h, d/dmd2/*, d/druntime/*,\n\td/phobos2/*: Updated D2 Frontend to 2.055.\n\t[0ada920f6394]\n\n\t* d/dmd/*, d/phobos/*: Updated D1 Frontend to 1.070.\n\t[fad5f4cad72b]\n\n2011-09-10  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-spec.c: Issue #230 - Error building Cross Compiler under MinGW\n\t[b0a9ef534877]\n\n\t* d/d-lang.cc, d/druntime/core/thread.d: Issue #226 - GC from spawned\n\tthreads segfaults on 64-bit\n\t[3ea496446c7e]\n\n2011-09-03  Daniel Green  <venix1@gmail.com>\n\n\t* d/asmstmt.cc: Use of V1 is more correct.\n\t[748ce286f58f]\n\n\t* d/dmd/root.c d/dmd2/root.c: Enables MinGW32 to use ANSI STDIO.\n\t[e69b142048f0]\n\n\t* d/asmstmt.cc: Allow inline assembly to set return values.  Matches\n\tDMD functionality.\n\t[857c5645429c]\n\n2011-08-29  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-decls.cc, d/d-glue.cc, d/d-lang.cc,\n\td/d-objfile.cc, d/symbol.cc: Emit pretty identifier to the debugger.\n\t[ac87eb9db360]\n\n2011-08-23  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-glue.cc, d/d-objfile.cc: Don't warn about unused\n\tcompiler generated vars.\n\t[0a71a122ca29]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc, d/d-irstate.cc,\n\td/d-irstate.h, d/d-lang-45.h, d/d-lang.cc, d/d-lang.h: New functions\n\tbuild_d_decl_lang_specific, d_mark_exp_read. Added support for\n\t-Wunused-variable, WIP -Wunused-but-set-variable.\n\t[d23bab68266c]\n\n2011-08-19  Daniel Green  <venix1@gmail.com>\n\n\t* d/druntime/core/sys/windows/stacktrace.d: Issue #227.  build error\n\tlibphobos/core/sys/windows/stacktrace.d.\n\t[b1c34b7e7764]\n\n2011-08-15  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-decls.cc: Issue #225 - Array ops should be COMDAT.\n\t[dda1c10c8c7b]\n\n2011-08-12  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-glue.cc, d/d-irstate.cc: Re-add codegen which caused issue #205\n\tin correct place.\n\t[e26b2b67bffa]\n\n\t* d/d-codegen.cc, d/d-gcc-includes.h: Issue #191 - SEGV(gimple.c:2624)\n\tgetting array ref of incomplete type.\n\t[d0edf91c3fcf]\n\n2011-08-07  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-glue.cc: Issue #205 - ICE using phobos sort.\n\t[b3a5c764de90]\n\n\t* d/d-asm-i386.h, d/d-tree.def: Define tree code IASM_EXPR.\n\t[c7e7dc1c089b]\n\n\t* d/d-asm-i386.h: Handle zero and one operand forms of fcomi, fcomip.\n\tFixed db, ds, di, dl to output constants and strings properly.\n\t[e394c90a88fa]\n\n\t* d/d-decls.cc, d/d-glue.cc, d/d-lang-type-45.h, d/d-lang-type.h,\n\td/d-lang.cc, d/d-lang.h: Create TYPE_LANG_SPECIFIC type for arrays,\n\tfunctions, delegates.\n\t[1c25bfb71c05]\n\n\t* d/d-glue.cc, d/dt.cc: Use TYPE_STRUCTURAL_EQUALITY for conversions\n\tof records, should fix Issue #217.\n\t[04b8a399ddeb]\n\n\t* d/asmstmt.cc, d/d-asm-i386.h: Fix error using offsetoff for\n\tSymOffExp's in IASM.\n\t[933d2ca08770]\n\n\t* d/d-asm-i386.h: Added SSE4.1, SSE4.2 instructions\n\t[6a643f59ac86]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc, d/d-lang-45.h,\n\td/d-lang.cc, d/d-lang.h, d/d-objfile.cc, d/dt.cc: More 4.6.x gimple\n\tchecking issues.\n\t[148a5a16d432]\n\n2011-07-30  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-glue.cc, d/d-lang-45.h, d/d-lang.h,\n\td/d-objfile.cc, d/dt.cc: Fix gimplication checking issues in 4.6.x\n\t[d3cc96b0546f]\n\n\t* d/d-codegen.cc: Issue #220 - Segfault on nested mixin functions.\n\t[c3720dd1e4f6]\n\n\t* d/patches/patch-gcc-4.6.x: Issue #218 - segmentation fault when\n\tcompiling Hello World.\n\t[07bb061b2e4b]\n\n2011-07-28  Daniel Green  <venix1@gmail.com>\n\n\t* d/d-glue.cc: Backout untested solution to issue #217.\n\t[fd532d8a5181]\n\n\t* d/d-glue.cc, d/setup-gcc.sh: Fixes issue #219\n\t[949ab1610a42]\n\n\t* d/setup-gcc.sh: Updated -hg to reflect working directory revision\n\tand handle compiling outside a mercurial repository.\n\t[b3b60fdac583]\n\n2011-07-24  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/GDC.html, d/README, d/gdc-version: GDC version 0.30\n\t[a4f3d0470b7a]\n\n\t* d/Make-lang.in, d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc,\n\td/d-lang.cc, d/patches/patch-gcc-4.2.x, d/patches/patch-gcc-4.3.x,\n\td/patches/patch-gcc-4.4.x, d/patches/patch-gcc-4.5.x,\n\td/patches/patch-gcc-4.6.x, d/symbol.cc d/symbol.h: Re-implemented D\n\tcustom static chains into frontend - removed all belated backend\n\tpatches.\n\t[488e8c0f482f]\n\n\t* d/Make-lang.in, d/asmstmt.cc, d/d-asm-i386.h, d/d-codegen.cc,\n\td/d-codegen.h, d/d-decls.cc, d/d-glue.cc, d/d-lang.cc, d/d-objfile.cc,\n\td/d-objfile.h, d/dmd2/*, d/druntime/*, d/phobos2/*: Updated D2\n\tFrontend to 2.054\n\t[ca958eccbde0]\n\n\t* d/Make-lang.in, d/asmstmt.cc, d/d-builtins.c, d/d-builtins2.cc,\n\td/d-codegen.cc, d/d-codegen.h, d/d-convert.cc, d/d-decls.cc,\n\td/d-glue.cc, d/d-irstate.cc, d/dmd/*, d/phobos/*: Updated D1 Frontend\n\tto 1.069\n\t[c77c7af3dda0]\n\n2011-07-11  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-glue.cc, d/d-lang.h: Debug fixes: Give AAs a\n\tTYPE_NAME. Make closure vars visible to the debugger.\n\t[7cb42bd4eb94]\n\n2011-07-09  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-asm-i386.h: Issue #213 - ASM: Invalid absolute jmp/call address\n\t[e01697578501]\n\n\t* d/d-asm-i386.h, d/d-glue.cc, d/d-lang.cc: Asm 32/64bit generation\n\tfixes.\n\t[0a2261bde3e1]\n\n\t* d/d-codegen.h, d/d-decls.cc, d/d-lang.h, d/patches/patch-gcc-4.4.x,\n\td/patches/patch-gcc-4.5.x, d/patches/patch-gcc-4.6.x: Use\n\tTREE_NO_TRAMPOLINE macro - remove redundant patches.\n\t[b79169244c60]\n\n2011-07-04  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in: Fixes executable relocation issues with MinGW.\n\t[c272d49246c9]\n\n\t* d/d-decls.cc: Always mark struct/class members for inlining.\n\t[61c81c98d80c]\n\n2011-06-30  Daniel Green  <venix1@gmail.com>\n\n\t* d/d-asm-i386.h: Fixes issue #213.\n\t[71737ec293cb]\n\n2011-06-20  Daniel Green  <venix1@gmail.com>\n\n\t* d/phobos/internal/gc/win32.d, d/phobos/std/stream.d: Win64 support\n\tfor Phobos/D1.\n\t[b2b0dae5dec2]\n\n\t* d/Make-lang.in, d/dmd/root.c: Enables ANSI implemention of MinGW\n\tstdio.\n\t[fd0f112bfca8]\n\n\t* d/dmd-script: Added the ability to specify the name of output map\n\tfile.  Undocumented DMD feature.\n\t[d36a8b0e175]\n\n2011-06-19  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-glue.cc, d/d-objfile.cc, d/dmd2/arrayop.c,\n\td/druntime/core/stdc/math.d, d/phobos2/gcc/deh.d: Issue #212 - ICE\n\tWith Map, dotProduct\n\t[f333a7e70d3d]\n\n2011-06-08  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-asm-i386.h, d/d-builtins2.cc, d/d-codegen.cc, d/d-codegen.h,\n\td/d-decls.cc, d/d-glue.cc, d/dmd2/*, d/druntime/*, d/phobos2/*:\n\tUpdated D2 Frontend to 2.053\n\t[89eccdc0155e]\n\n\t* d/d-decls.cc, d/d-lang-45.h, d/d-lang.h, d/d-objfile.cc: gcc-4.6.x -\n\tFix imported static const optimizer bug (D2 now passes testsuite).\n\t[9ccc077422a8]\n\n2011-06-05  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/d-codegen.cc, d/dmd-script: gcc-4.6.x - -combine\n\tremoved, re-add d-gcc.o object, fix compilation on ARM.\n\t[dd43ade64753]\n\n\t* d/d-decls.cc, d/d-objfile.cc, d/patches/patch-gcc-4.6.x: gcc-4.6.x -\n\tFix undefined references to thunks.\n\t[6b13c1f980f4]\n\n\t* d/d-bi-attrs-40.h, d/d-bi-attrs-41.h: Remove d-bi-attrs.h for 4.0\n\tand 4.1\n\t[86169933de9c]\n\n2011-06-02  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/d-bi-attrs-45.h, d/d-lang.cc, d/d-spec.c,\n\td/lang.opt, d/patches/patch-gcc-4.6.x, d/setup-gcc.sh: Fix missing\n\tgcc-4.6 driver options, add to setup scripts.\n\t[937e3e68e003]\n\n2011-05-31  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/config-lang.in, d/d-builtins.c, d/d-builtins2.cc,\n\td/d-codegen.h, d/d-gcc-real.cc, d/d-glue.cc, d/d-incpath.cc,\n\td/d-lang-45.h, d/d-lang.cc, d/d-spec.c, d/lang.opt,\n\td/patches/patch-gcc-4.6.x, d/patches/patch-toplev-4.6.x: Add gcc-4.6.x\n\tsupport\n\t[94fdbcd3ae33]\n\n\t* d/Make-lang.in, d/d-bi-attrs-45.h, d/d-builtins.c, d/d-codegen.cc,\n\td/d-codegen.h, d/d-gcc-includes.h, d/d-lang.cc, d/d-lang.h,\n\td/d-objfile.cc, d/druntime/core/stdc/stdarg.d,\n\td/druntime/core/vararg.d, d/patches/patch-gcc-4.0.x,\n\td/patches/patch-gcc-4.1.x, d/patches/patch-toplev-4.0.x,\n\td/patches/patch-toplev-4.1.x, d/phobos/std/c/stdarg.d,\n\td/phobos/std/stdarg.d, d/symbol.h: Drop support for gcc-4.0.x;\n\tgcc-4.1.x\n\t[75f0bbfbdd5e]\n\n\t* d/d-asm-i386.h: Rename cmpxch8b to cmpxchg8b\n\t[21128c37d917]\n\n2011-04-29  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-glue.cc: Issue #203 - ArrayLiteralExp::toElem incorrectly sets\n\tTREE_STATIC\n\t[584a5f3a7dce]\n\n\t* d/druntime/core/stdc/wchar_.d: Use alias to make vswprintf and\n\tswprintf match ANSI signature.\n\t[344229e36805]\n\n\t* d/d-glue.cc: Issue #200 - Optimization breaks condition variables\n\t[b805b62dcdc8]\n\n\t* d/d-builtins2.cc, d/d-codegen.cc, d/d-glue.cc, d/dt.cc: Be less\n\ttrusting with GCC builtins.\n\t[194016d49ca]\n\n2011-04-23  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-asm-i386.h: Make SSE3 iasm opcodes available for 32bit.\n\t[7861f5acdf6b]\n\n\t* d/dmd/todt.c, d/dmd2/todt.c: speed up emission of large static array\n\tinitialisers.\n\t[9a840a37e508]\n\n\t* d-decls.cc, d/d-glue.cc, d/phobos/configure, d/phobos/configure.in,\n\td/phobos2/Makefile.am, d/phobos2/configure: D1 regression with static\n\tarray equality testing.\n\t[af07c3a2f08c]\n\n2011-04-18  Daniel Green  <venix1@gmail.com>\n\n\t* d/phobos2/Makefile.in: Added std/c/wcharh.d to list of compiled\n\tWindows objects.  Required by MinGW's stdio patch\n\t[3cf208768d86]\n\n2011-04-17  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/d-decls.cc, d/druntime/core/thread.d,\n\td/phobos/configure, d/phobos/configure.in, d/phobos2/Makefile.am,\n\td/phobos2/Makefile.in, d/phobos2/configure, d/phobos2/configure.in:\n\tEdit configure scripts so cross compilers install imports in gcc\n\tversion specific runtime directory\n\t[8fe76a59ba1e]\n\n\t* d/d-builtins2.cc: Issue #192 - ARM Compilation Fails When Including\n\tgcc.intrinsics\n\t[bf186179001b]\n\n\t* d/druntime/core/stdc/stdio.d: Change ctor in cstdio to 'shared\n\tstatic' - should fix Mingw IO in std.stdio\n\t[efb1b1ed90d8]\n\n\t* d/d-objfile.cc, d/druntime/core/stdc/stdio.d, d/phobos2/Makefile.am,\n\td/phobos2/Makefile.in, d/phobos2/std/stdio.d: Merge Daniel's MinGW\n\twork, put special case static ctor in core.stdio\n\t[71f10f204790]\n\n2011-04-15  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/dmd/func.c, d/dmd2/func.c: Remove __va_argsave definition from\n\t64bit GDC\n\t[997a9ec407fe]\n\n\t* testsuite/*: Upload D2 testsuite for GDC.\n\t[6e40c9c42f6e]\n\n\t* d/d-asm-i386.h, d/d-irstate.cc, d/d-objfile.cc,\n\td/druntime/core/thread.d: 64bit IASM fix, move tls definitions to\n\td-objfile, add _tls_index stub for MinGW.\n\t[ff35bec78100]\n\n\t* d/d-objfile.cc: Issue #187 - Multiple definition of TypeInfo with\n\tMinGW.\n\t[d52ae1bf8343]\n\n\t* d/d-lang.cc, d/dmd-script, d/druntime/rt/monitor_.d: Uncomment\n\timplementations in rt.monitor_ (for MinGW), code cleanups.\n\t[1cf36f68d061]\n\n\t* d/d-codegen.cc: Issue #189 - sqrt(integer) causes ICE in\n\tmaybeExpandSpecialCall\n\t[d46da356ca46]\n\n\t* d/d-incpath.cc: Issue #188 - -J option ignored.\n\t[875395c71f37]\n\n\t* d/Make-lang.in, d/d-asm-i386.h, d/d-builtins2.cc, d/d-codegen.cc,\n\td/d-glue.cc, d/d-irstate.cc, d/dt.cc: 64bit testsuite fixes - passes\n\tall tests 32bit linux passes.\n\t[62c8038af25a]\n\n\t* d/Make-lang.in, d/d-builtins.c, d/d-decls.cc, d/d-lang-45.h,\n\td/d-lang.cc, d/d-lang.h, d/d-misc.c, d/d-objfile.cc,\n\td/phobos/configure, d/phobos/configure.in, d/phobos2/configure,\n\td/phobos2/configure.in: Remove d-misc.c, fixed code that depended on\n\tit.\n\t[066ecfe85f1]\n\n\t* d/d-builtins2.cc, d/d-codegen.cc, d/d-codegen.h: Issue #185 -\n\tIntrinsics cause ICE on MinGW\n\t[c17a1cdfb868]\n\n2011-04-11  Daniel Green  <venix1@gmail.com>\n\n\t* d/Make-lang.in, d/d-incpath.cc, d/d-lang-45.h, d/d-lang.cc,\n\td/d-lang.h: Added d-incpath.c for handling import paths.\n\t[5a55df337408]\n\n\t* d/setup-gcc.sh: Added option '-hg' for replacing 'gdc-version' with\n\trepository revision.\n\t[32ed0cf6d419]\n\n2011-04-09  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-codegen.h: Implement math intrinsics into the\n\tcompiler.\n\t[431f375abaf1]\n\n\t* d/d-asm-i386.h, d/druntime/core/atomic.d: More 64bit IASM fixes,\n\tfavour ASM implementations in core.atomic.\n\t[8f5627ca0ba5]\n\n\t* d/phobos2/gcc/bitmanip.d: Really remove gcc.bitmanip.\n\t[c61617158bd8]\n\n\t* d/druntime/core/atomic.d, d/phobos/configure, d/phobos/configure.in,\n\td/phobos2/Makefile.am, d/phobos2/Makefile.in, d/phobos2/configure,\n\td/phobos2/configure.in, d/phobos2/gcc/atomics.d: First stab at\n\tgcc.atomics; Remove unused gcc.bitmanip; Add -inline as DFLAG for\n\tPhobos\n\t[1a74f184e2d8]\n\n2011-04-08  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-asm-i386.h, d/d-codegen.cc, d/d-glue.cc, d/d-lang.cc,\n\td/d-spec.c: Issue #164 - ICE:fold-const.c:2792.\n\t[c42297cf76c3]\n\n\t* d/d-asm-i386.h, d/druntime/core/thread.d: 64bit IASM fixes.\n\t[406daaa254ad]\n\n\t* d/d-builtins2.cc, d/d-glue.cc: Issue #164 - (ICE:fold-const.c:2792)\n\tusing std.range.zip\n\t[437b1cc2f607]\n\n\t* d/d-lang.cc, d/phobos/Makefile.am, d/phobos/Makefile.in,\n\td/phobos2/Makefile.am, d/phobos2/Makefile.in: Phobos: Issue #179 -\n\texplicitly include zlib directory when building.\n\t[37ba91ed454c]\n\n\t* d/d-convert.cc: Issue 143: non-determistic FPE in runtime code.\n\t[4ea171da4900]\n\n\t* d/d-codegen.cc: Issue #178 - ICE in hwi2toli.\n\t[9133d6873087]\n\n\t* d/Make-lang.in, d/d-codegen.cc: Tidy up Make-lang.in, remove old\n\tbits.\n\t[1d8b36b4bfb7]\n\n\t* d/d-codegen.cc, d/d-glue.cc, d/d-irstate.cc, d/d-objfile.cc: Remove\n\told-old workarounds for GCC < 4.0.x\n\t[b2ffdbb41245]\n\n\t* d/d-gcc-real.cc, d/d-gcc-real.h, d/dmd/cast.c, d/dmd2/cast.c,\n\td/dmd2/expression.c: D2: Fix precision bug in PowExp.\n\t[ab7782c68bb5]\n\n\t* d/d-codegen.cc, d/d-gcc-real.cc: Don't error when casting from\n\tstatic array -> struct of same type size.\n\t[90b0b0208d3f]\n\n2011-03-30  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/d-gcc-real.cc, d/d-gcc-real.h: Fix strict-aliasing\n\twarning.\n\t[79ed94287f94]\n\n2011-03-30  Daniel Green  <venix1@gmail.com>\n\n\t* d/asmstmt.cc: An unitialized array was forcing GDC to mark all\n\tregisters as clobbered.\n\t[007de89f7694]\n\n2011-03-27  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-lang.cc: Move cgraph finalize into d_write_global_decls.\n\t[b7da3f7426ac]\n\n\t* d/asmstmt.cc, d/d-asm-i386.h, d/d-codegen.h, d/d-dmd-gcc.h,\n\td/d-gcc-real.h, d/d-irstate.cc, d/d-irstate.h, d/d-objfile.cc,\n\td/d-objfile.h, d/druntime/core/thread.d, d/patches/patch-gcc-4.5.x,\n\td/symbol.h: _tlsstart/_tlsend compiler generated symbols.\n\t[d2dfed983fff]\n\n\t* d/Make-lang.in, d/d-builtins.c, d/d-builtins2.cc, d/d-codegen.cc,\n\td/d-glue.cc, d/d-lang-45.h, d/d-lang.cc, d/d-lang.h: New\n\td_global_trees array for gcc trees of commonly used D types/decls.\n\t[d553b62db8e6]\n\n2011-03-24  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-decls.cc, d/d-glue.cc, d/d-objfile.cc,\n\td/d-objfile.h, d/patches/patch-gcc-4.1.x, d/patches/patch-gcc-4.2.x,\n\td/patches/patch-gcc-4.3.x, d/patches/patch-gcc-4.4.x,\n\td/patches/patch-gcc-4.5.x: More WIP DMD calling convention - evaluate\n\targuments left to right, pass in reverse order\n\t[6949b05e21e4]\n\n\t* d/asmstmt.cc, d/d-asm-i386.h, d/d-codegen.cc, d/d-codegen.h,\n\td/d-irstate.cc, d/d-lang-45.h, d/d-lang.cc, d/d-lang.h, d/lang.opt:\n\tMore WIP - 64bit IASM.\n\t[a85a80c8732a]\n\n\t* d/patches/patch-gcc-4.1.x, d/patches/patch-gcc-4.2.x,\n\td/patches/patch-gcc-4.3.x, d/patches/patch-gcc-4.4.x,\n\td/patches/patch-gcc-4.5.x, d/patches/patch-toplev-4.1.x,\n\td/patches/patch-toplev-4.2.x, d/patches/patch-toplev-4.3.x,\n\td/patches/patch-toplev-4.4.x, d/patches/patch-toplev-4.5.x: Switch\n\tpatches to unified diff.\n\t[1738b301128b]\n\n\t* d/d-builtins2.cc, d/d-decls.cc, d/d-glue.cc, d/d-objfile.cc,\n\td/d-tree.def, d/patches/patch-gcc-4.1.x, d/patches/patch-gcc-4.2.x,\n\td/patches/patch-gcc-4.3.x, d/patches/patch-gcc-4.4.x,\n\td/patches/patch-gcc-4.5.x: More WIP DMD calling convention - Add\n\t'optlink' function attribute.\n\t[521dce459f71]\n\n2011-03-19  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc: WIP: Merge\n\tmake_bool_binop, make_math_op, make_assign_math_op into toElemBin.\n\t[886b0a5af18a]\n\n\t* d/asmstmt.cc, d/d-asm-i386.h, d/d-bi-attrs-44.h, d/d-bi-attrs-45.h,\n\td/d-builtins2.cc, d/d-codegen.cc, d/d-codegen.h, d/d-convert.cc,\n\td/d-cppmngl.cc, d/d-decls.cc, d/d-glue.cc, d/d-irstate.h,\n\td/d-lang-45.h, d/d-objfile.cc, d/d-spec.c: Use gcc_unreachable instead\n\tof abort, cleanup line endings.\n\t[3d6a01bd6e93]\n\n2011-03-18  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-lang.cc, d/d-objfile.cc, d/d-objfile.h, d/symbol.cc, d/symbol.h:\n\tIssue #167 - Assembler error: Already defined.\n\t[36a609d5155b]\n\n\t* d/d-glue.cc: IndexExp: call aaGetp if AA is modifiable.\n\t[d69227218b07]\n\n\t* d/d-codegen.cc, d/d-objfile.cc: Issue #165: Link failure with\n\ttemplates.\n\t[2221d9fb1dd9]\n\n\t* d/Make-lang.in, d/d-builtins2.cc, d/d-codegen.cc: Add experimental\n\tvoid* _argptr implementation switch in Makefile.\n\t[9a8cbe47da29]\n\n\t* d/Make-lang.in, d/d-builtins2.cc, d/d-codegen.cc, d/d-convert.cc,\n\td/d-gcc-real.cc, d/d-glue.cc, d/d-spec.c: Replace calls to\n\tfold(build()) with fold_build()\n\t[8eab661a9626]\n\n\t* d/d-convert.cc: Harden d_truthvalue_conversion, catches scalars\n\tpassed for conversion by buggy frontend.\n\t[ff5142f57beb]\n\n\t* d/Make-lang.in, d/d-decls.cc, d/d-glue.cc, d/d-lang.cc: Add\n\texperimental DMD calling convention switch in Makefile\n\t[c5153f67119a]\n\n\t* d/d-bi-attrs-44.h: Update d-bi-attrs-44.h for current 4.4.5 release.\n\t[e44747eee585]\n\n\t* d/d-glue.cc: Mark used parameters to prevent false warnings from\n\t-Wunused-parameter.\n\t[f0a6db429617]\n\n2011-03-12  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-glue.cc: Fix codegen bug in CatAssignExp.\n\t[15f72843d336]\n\n\t* d/d-builtins2.cc, d/d-codegen.cc, d/d-codegen.h, d/d-glue.cc,\n\td/d-lang.cc, d/d-objfile.cc: IRState::addTypeModifiers - Add D2 type\n\tmodifiers (const/shared) onto GCC types (const/volatile).\n\t[ef3c725214ec]\n\n2011-03-06  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-lang.cc, d/d-spec.c, d/gdc.1, d/lang-specs.h,\n\td/patches/patch-apple-gcc-5664, d/patches/patch-gcc-4.2.x,\n\td/patches/patch-gcc-4.3.x, d/patches/patch-gcc-4.4.x,\n\td/patches/patch-gcc-4.5.x: Remove lang_specific_spec_functions code.\n\t[da7dc4ae6277]\n\n\t* d/dmd-script: Issue #161 - noboundscheck doesn't work with GDMD.\n\t[9ad16376258f]\n\n2011-02-28  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-decls.cc, d/d-glue.cc, d/d-objfile.cc, d/d-objfile.h,\n\td/dmd/template.c, d/dmd2/template.c, d/symbol.h: Moved GCC code to\n\tprevent templates being emitted more than once to the backend.\n\t[585920b19963]\n\n\t* d/Make-lang.in, d/d-decls.cc, d/d-glue.cc, d/d-lang.h,\n\td/d-objfile.cc: Cleaned up ObjFile::makeDeclOneOnly implementation.\n\t[cbad6b2b6b42]\n\n2011-02-25  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-apple-gcc.c, d/d-builtins2.cc, d/d-c-stubs.c, d/d-codegen.cc,\n\td/d-gcc-includes.h, d/d-glue.cc, d/d-lang.cc, d/d-objfile.cc: Remove\n\tdependencies on CPP objects.\n\t[33967b4ff6e9]\n\n\t* d/d-gcc-includes.h, d/patches/patch-apple-gcc-5465,\n\td/patches/patch-apple-gcc-5664, d/patches/patch-gcc-4.0.x,\n\td/patches/patch-gcc-4.1.x, d/patches/patch-gcc-4.2.x,\n\td/patches/patch-gcc-4.3.x, d/patches/patch-gcc-4.4.x,\n\td/patches/patch-gcc-4.5.x: Remove old redundant code.\n\t[7b72e8118c29]\n\n\t* d/d-spec.c: Handle -pthread option in d-spec.c\n\t[b6062a158fdd]\n\n\t* d/d-glue.cc, d/phobos2/std/stdio.d, d/target-ver-syms.sh: Issue #151\n\t- MinGW-w64: recent GDC does not build w/ recent GCC\n\t[978bb5bc82cf]\n\n\t* d/druntime/core/sys/posix/sys/un.d, d/phobos2/Makefile.am,\n\td/phobos2/Makefile.in: Remove posix.sys.un from druntime.\n\t[bb92ab765845]\n\n2011-02-20  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/d-builtins2.cc, d/d-lang.cc, d/d-spec.c, d/dmd2/*,\n\td/druntime/*, d/phobos2/*: Updated D2 Frontend to 2.052.\n\t[c4980ba67971]\n\n\t* d/dmd/*, d/phobos/*: Updated D1 Frontend to 1.067.\n\t[343f35cc00c8]\n\n\t* d/d-objfile.cc: Put compiler-generated arrayops on comdat.\n\t[4d14649603c2]\n\n\t* d/d-gcc-includes.h, d/d-glue.cc: use totym to apply D type modifiers\n\ton GCC types.\n\t[d3b9d3188b68]\n\n\t* d/d-decls.cc: Issue #155 - ICE when using byte\n\t[7846c6471861]\n\n\t* d/d-bi-attrs-43.h, d/d-bi-attrs-44.h, d/d-bi-attrs-45.h: Remove\n\t'artificial' attribute from GDC.\n\t[4b8f90d1f6aa]\n\n\t* d/d-codegen.cc, d/d-glue.cc, d/d-irstate.cc, d/d-lang.cc: Conversion\n\tfixes for types with GCC attributes applied.\n\t[5e733844f91f]\n\n\t* d/d-codegen.cc, d/d-codegen.h, d/d-decls.cc, d/d-glue.cc,\n\td/d-objfile.cc, d/druntime/object.di, d/druntime/object_.d,\n\td/druntime/rt/aaA.d, d/phobos/Makefile.am, d/phobos/Makefile.in,\n\td/phobos/gcc/support.d, d/phobos/internal/aaA.d,\n\td/phobos/internal/gc/gc.d, d/phobos2/gcc/support.d: ABI update: New\n\tsignatures for _d_assocarrayliteralTp, _d_arrayliteralTp and\n\t_d_arrayappendcTp\n\t[b66226b53e71]\n\n\t* d/d-glue.cc: Update make_assign_math_op implementation\n\t[8390d07b450e]\n\n\t* d/d-builtins.c, d/d-builtins2.cc, d/d-codegen.cc,\n\td/d-gcc-includes.h, d/d-glue.cc, d/d-lang-45.h, d/d-lang.cc,\n\td/d-lang.h, d/d-objfile.cc: Fix cast-qual and unused parameter\n\twarnings in glue.\n\t[377c4f5505be]\n\n\t* d/Make-lang.in, d/d-c-stubs.c, d/d-lang.cc: Drop support for CPP\n\tBuiltins.\n\t[6dc9468f6789]\n\n2011-02-10  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-builtins.c, d/d-builtins2.cc, d/d-lang-45.h, d/d-lang.cc,\n\td/d-lang.h: New function added to langhooks: d_register_builtin_type.\n\t[9674e391725f]\n\n\t* d/d-bi-attrs-40.h, d/d-bi-attrs-41.h, d/d-bi-attrs-42.h,\n\td/d-bi-attrs-43.h, d/d-bi-attrs-44.h, d/d-bi-attrs-45.h: Only accept\n\tstring argument in mode attribute handler.\n\t[99764267b71b]\n\n\t* d/asmstmt.cc, d/d-builtins2.cc, d/d-codegen.cc, d/d-cppmngl.cc,\n\td/d-decls.cc, d/d-dmd-gcc.h, d/d-glue.cc, d/d-irstate.cc,\n\td/d-objfile.cc, d/d-todt.cc: Remove all references to total.h in glue.\n\t[30c8afda4902]\n\n\t* d/asmstmt.cc, d/d-apple-gcc.c, d/d-asm-i386.h, d/d-builtins2.cc,\n\td/d-codegen.cc, d/d-cppmngl.cc, d/d-decls.cc, d/d-gcc-real.cc,\n\td/d-glue.cc, d/d-irstate.cc, d/d-lang.cc, d/d-objfile.cc, d/dt.cc:\n\tRemove all references to assert.h in glue.\n\t[1d176d15d1e8]\n\n2011-02-02  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-bi-attrs-40.h, d/d-bi-attrs-41.h, d/d-bi-attrs-42.h,\n\td/d-bi-attrs-43.h, d/d-bi-attrs-44.h, d/d-bi-attrs-45.h,\n\td/dmd/attrib.c, d/dmd2/attrib.c: Fix mode attribute handler to accept\n\tstring argument.\n\t[4ab9f7b5de07]\n\n2011-01-29  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/druntime/core/stdc/config.d: D2 - import gcc.builtins in\n\tcore.stdc.config\n\t[1e41fd67396c]\n\n\t* d/d-codegen.cc, d/d-glue.cc, d/druntime/core/stdc/config.d,\n\td/druntime/core/stdc/stdint.d, d/druntime/core/thread.d,\n\td/druntime/gc/gc.d, d/druntime/gc/gcbits.d, d/druntime/gc/gcx.d,\n\td/druntime/gcstub/gc.d, d/druntime/rt/lifetime.d,\n\td/phobos2/std/intrinsic.d: 64bit TLS/GC fixes. Closes #109, #115.\n\t[0c10de583cd3]\n\n2011-01-28  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/Make-lang.in, d/d-codegen.cc, d/dmd/*, d/phobos/*: Updated D1\n\tFrontend to 1.066\n\t[06b390b6f86b]\n\n\t* d/d-codegen.cc, d/d-glue.cc, d/druntime/rt/mars.h,\n\td/phobos/std/c/stdarg.d: Remove redundant checks for Tbit in D1, add\n\t__va_argsave_t alias in phobos.\n\t[5a4481f10bce]\n\n\t* d/Make-lang.in: use new variable (ALL_CXXFLAGS)\n\t[a3ec7496100e]\n\n\t* d/d-c-stubs.c, d/d-codegen.cc, d/d-codegen.h, d/dmd/root.h,\n\td/dmd2/root.h: Implement frontend std.intrinsics into GDC.\n\t[330bd9e6077b]\n\n2011-01-18  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/asmstmt.cc, d/d-codegen.cc, d/dmd/statement.h, d/dmd2/statement.h:\n\tImplemented ExtAsmstatement::toCBuffer.\n\t[4163067c9831]\n\n\t* d/dmd/arrayop.c, d/dmd/root.c, d/dmd2/arrayop.c, d/dmd2/root.c: Add\n\tbinary implementation, use it in arrayops.\n\t[78358cd41c04]\n\n\t* d/dmd2/func.c, d/phobos/std/math.d, d/phobos2/std/intrinsic.d,\n\td/phobos2/std/math.d, d/phobos2/std/string.d: Fix log2 implementation\n\tfor systems requiring supplement.\n\t[961f4dd29944]\n\n2011-01-16  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-glue.cc: Pass static chain by reference for functions nested in\n\tclasses.\n\t[e37f417ab86f]\n\n\t* d/d-lang-45.h, d/dmd/todt.c, d/dmd2/todt.c: rework todt for GCC.\n\t[a15a367a189a]\n\n\t* d/druntime/core/sys/posix/config.d,\n\td/druntime/core/sys/posix/sys/stat.d,\n\td/druntime/core/sys/posix/sys/types.d, d/druntime/gc/gcx.d: rework\n\tsys.stat struct implementation.\n\t[dc8e70a01ccf]\n\n2011-01-13  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-glue.cc, d/d-lang.cc, d/d-lang.h: Improve type names of\n\tshared/const/immutable types in debugging.\n\t[95990b0754e6]\n\n\t* d/d-codegen.cc: Issue #147 - static arrays passed as parameter\n\tshould be value type.\n\t[59c59a459398]\n\n\t* d/patches/patch-gcc-4.4.x, d/patches/patch-gcc-4.5.x: Second fix for\n\tIssue #104.\n\t[1e4da57f4be4]\n\n2011-01-09  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/dmd/mtype.c, d/dmd2/mtype.c: Issue #134 - Fix 64bit double align.\n\t[ab3473b8ee56]\n\n\t* d/dmd-script, d/patches/patch-gcc-4.4.x, d/patches/patch-gcc-4.5.x:\n\tRemove -fomit-frame-pointer from gdmd, fixes Issue #141\n\t[191fd75f1716]\n\n2011-01-06  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-codegen.h, d/d-glue.cc, d/d-objfile.cc, d/lang-specs.h: Compiler\n\tsegfault when not Object class not defined.\n\t[44b6978e5f6c]\n\n\t* d/d-builtins2.ca,c d/d-codegen.h, d/d-decls.cc, d/d-glue.cc,\n\td/d-lang.cc, d/dmd/dchar.h, d/dmd/mars.c, d/dmd2/dchar.h: Fix some\n\twarnings in d-lang, ICE when object.d is empty.\n\t[48827ef72351]\n\n\t* d/d-asm-i386.h, d/d-codegen.h: Refs Issue #135 - turn ICE into a\n\ttemp error.\n\t[8f4b7ddb676e]\n\n\t* d/d-glue.cc: Call rest_of_type_compilation in toDebug for\n\tRecord/Union/Enums.\n\t[ca79068bcb60]\n\n\t* d/druntime/object.di, d/druntime/object_.d: Issue #133 - Segfault On\n\tAA Foreach\n\t[aba6c8857d64]\n\n\t*  d/druntime/core/thread.d, d/druntime/gc/gcx.d: Refs #115 - addRoot\n\tfor each call for malloc in the GC.\n\t[3721c1dc5aad]\n\n\t* d/phobos2/Makefile.am, d/phobos2/Makefile.in: D2 - emit templates\n\tonly for building phobos.\n\t[c2b8a3f7c35b]\n\n\t* d/d-decls.cc, d/d-objfile.cc: Issue #132 - unresolved symbol with\n\ttypedef initializers.\n\t[69ebdbbcd8c2]\n\n\t* d/druntime/core/sys/posix/config.d,\n\td/druntime/core/sys/posix/signal.d,\n\td/druntime/core/sys/posix/sys/stat.d, d/phobos2/std/file.d: Fix struct\n\tstat_t implementation for linux.\n\t[29c51189bf66]\n\n2011-01-02  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d/d-spec.c: Fix warning messages in d-spec.c.\n\t[da4c33277396]\n\n\t* d/d-codegen.cc,  d/d-glue.cc: Issue #105 - assertion failure\n\tcomparing structs for equality.\n\t[9a212ed12cec]\n\n\t* d/d-codegen.cc: Fix some diagnostic messages.\n\t[1447423e541a]\n\n\t* d/d-convert.cc: Update d_convert_basic for gcc-4.5\n\t[28166c71baad]\n\n\t* d/d-builtins.c, d/d-builtins2.cc, d/d-codegen.cc, d/d-decls.cc,\n\td/d-glue.cc, d/d-lang-45.h, d/d-lang.cc, d/d-lang.h, d/d-objfile.cc:\n\tDeclare d_build_decl as extern \"C\". Add function d_build_decl_loc.\n\t[29253025adb2]\n\n\f\nCopyright (C) 2011 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2012",
    "content": "2013-02-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (GDC_EXTENDED_ASM_SYNTAX): Remove macro.\n\n2013-02-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.h (D_DECL_IS_CONTRACT): Remove macro.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Likewise.\n\n2013-02-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_gcc_is_target_win32): Remove.\n\t(d_add_builtin_version): New function to handle define_builtin\n\tcallback from backend.\n\t* d-codegen.cc (IRState::maybeExpandSpecialCall): Remove intrinsic bt.\n\n\t* d-builtins.c: Merge with d-builtins2.cc.\n\t* d-builtins2.cc: Remove.\n\n2013-02-07  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-lang.cc (d_init): Use gcc's config system for predefined OS versions.\n\t* setup-gcc.sh: Likewise.\n\t* target-ver-syms.sh: Likewise.\n\n2013-02-05  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-builtins2.cc (gcc_type_to_d_type): Remove STRUCTTHISREF condition.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Likewise.\n\t* d-elem.cc (ThisExp::toElem): Likewise.\n\t* d-ctype.cc (TypeSArray::toCtype): Remove SARRAYVALUE condition.\n\t* d-codegen.cc (IRState::isDeclarationReferenceType): Likewise.\n\t(IRState::isArgumentReferenceType): Likewise.\n\n2013-02-01  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-lang.cc (d_init): Use gcc's config system for predefined CPU versions.\n\t(d_init): Fix definition of D_LP64 version.\n\t* setup-gcc.sh: Likewise.\n\t* target-ver-syms.sh: Likewise.\n\n2012-12-16  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-decls.cc (FuncDeclaration::toSymbol): Don't optimise PUREconst\n\tcalls.\n\n2012-10-27  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc (IRState::buildAssignOp): Handle case where LHS type is\n\tnot compatible with expression type.\n\n2012-10-26  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-decls.cc (ClassDeclaration::toSymbol): Use empty RECORD_TYPE to\n\tbuild internal symbol.\n\t(Module::toSymbol): Likewise.\n\t* d-objfile.cc (outdata): Set type size from constructor if not\n\tCOMPLETE_TYPE_P.  Assert that DECL_INITIAL is never bigger than\n\tTYPE_SIZE.\n\n2012-10-25  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc (IRState::getFrameInfo): Use vthis to determine whether\n\tfunction is nested.\n\n2012-10-21  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-builtins2.cc (gcc_type_to_d_type): Remove special case for\n\tdouble/long double types.\n\t(d_gcc_magic_builtins_module): Cleanup generation of builtin types.\n\tAdd __builtin_unwind_int and __builtin_unwind_uint.\n\n2012-10-16  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-objfile.cc (ObjectFile::outputThunk): Mark thunk as DECL_WEAK\n\trather than using weakref attribute.\n\n2012-10-14  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-bi-attrs.h: Remove file.\n\t* d-builtins.c (d_attribute_table): Define table of machine independant\n\tattributes for gcc builtins.\n\t(d_format_attribute_table): Define table of format attributes for gcc\n\tbuiltins.\n\t(handle_noreturn_attribute, handle_leaf_attribute,\n\thandle_const_attribute, handle_malloc_attribute,\n\thandle_returns_twice_attribute, handle_pure_attribute,\n\thandle_novops_attribute, get_nonnull_operand,\n\thandle_nonnull_attribute, handle_nothrow_attribute,\n\thandle_sentinel_attribute, handle_type_generic_attribute,\n\thandle_fnspec_attribute, handle_transaction_pure_attribute,\n\tignore_attribute): Moved common attribute handlers from d-bi-attrs.h.\n\t* d-lang.cc (LANG_HOOKS_ATTRIBUTE_TABLE): Use instead of\n\tLANG_HOOKS_COMMON_ATTRIBUTE_TABLE.\n\t(d_attribute_table): Renamed from d_common_attribute_table.\n\t(d_format_attribute_table): Renamed from\n\td_common_format_attribute_table.\n\t(d_init_ts): Renamed from d_common_init_ts.\n\n\t* d-builtins2.cc (d_bi_init): Determine D frontend type for size_t.\n\t* d-objfile.cc (ObjectFile::hasModule): Remove old compatibility\n\tmacros.\n\n2012-10-08  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-glue.cc (VectorExp::toElem): Handle non-constant array literals as\n\tvector expressions.\n\n2012-10-04  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-glue.cc (VectorExp::toElem): Handle both array literal as well as\n\tsingle element constructors for vector expressions.\n\n2012-09-27  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-convert.cc (convert): Remove assert.\n\n2012-09-22  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc (IRState::maybeCompound): Use IRState::compound.\n\t(IRState::maybeVoidCompound): Use IRState::voidCompound.\n\t(IRState::call): Check TREE_SIDE_EFFECTS to determine order of\n\tevaluation in function calls.  Evaluate callee before arguments if has\n\tside effects.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Don't set any pure/nothrow\n\tattributes if asserts are generated in code.\n\t* d-incpath (add_fileimp_path): Fix ICE using -J option.\n\t* d-objfile.cc (Obj::moduleinfo): Clean-up.\n\n2012-09-18  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-lang.cc (d_initialize_diagnostics): New function, disable unneeded\n\tdiagnostic options.\n\t(d_handle_option): Remove OPT_fdebug_c.\n\t* d-spec.c (lang_specific_driver): Remove OPT_fod_, OPT_fop.\n\t* lang.opt: Remove -fdebug-c, -fod, and -fop compiler options.\n\n2012-09-17  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.h (CtorEltMaker::cons): Adjust call to VEC_safe_push.\n\t* d-objfile.cc (ObjectFile::stripVarDecl): Clean-up.\n\n2012-09-16  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc (IRState::isCallByAlias): New function.\n\t(IRState::call): Use IRState::isCallByAlias.\n\t* d-objfile.cc (ObjectFile::setupSymbolStorage): Mark\n\tforce_static_public symbols as public.\n\n\t* d-spec.c (lang_specific_driver): Update for GCC-4.8.\n\t* lang.opt: Fix spelling of option -static-libphobos\n\n\t* d-codegen.cc (IRState::maybeExpandSpecialCall): Do not handle inp*\n\tand outp* port intrinsic functions.\n\t(IRState::maybeSetUpBuiltin): Likewise.\n\t(IRState::expandPortIntrinsic): Remove.\n\n2012-09-10  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc (AggLayout::doFields): Propagate volatile out of type.\n\t(AggLayout::addField): Likewise.\n\t* d-decls.cc (VarDeclaration::toSymbol): Likewise.\n\n2012-09-06  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.h (IRState::vconvert): Don't use VIEW_CONVERT_EXPR.\n\t* d-glue.cc (TypeEnum::toCtype): Mark TYPE_PACKED if flag_short_enums.\n\t(TypeClass::toCtype): Mark TREE_ADDRESSABLE to ensure class is always\n\tpassed in memory.\n\n\t* d-tree.def (UNSIGNED_RSHIFT_EXPR): Define new tree expression.\n\t(FLOAT_MOD_EXPR): Define new tree expression.\n\t* d-lang.cc (d_common_init_ts): New function.\n\t(d_write_global_declarations): Call check_global_declarations after\n\tfinalize_compilation_unit.\n\t(d_gimplify_expr): Handle UNSIGNED_RSHIFT_EXPR, IASM_EXPR.\n\t* d-codegen.cc (IRState::arrayOpNotImplemented): New function.\n\t(IRState::buildOp): New function.\n\t(IRState::buildAssignOp): New function.\n\t* d-glue.cc (build_bool_binop): Remove function, mostly move to\n\tCmpExp::toElem.\n\t(build_math_op): Remove function, mostly move to IRState::buildOp.\n\t(build_assign_math_op): Remove function, mostly move to\n\tIRState::buildAssignOp.\n\t(BinExp::toElemBin): Remove function.\n\t(IdentityExp::toElem, EqualExp::toElem, CmpExp::toElem)\n\t(AndAndExp::toElem, OrOrExp::toElem): Clean-up, use IRState::boolOp.\n\t(XorExp::toElem, OrExp::toElem, AndExp::toElem, UshrExp::toElem)\n\t(ShrExp::toElem, ShlExp::toElem, ModExp::toElem, DivExp::toElem)\n\t(MulExp::toElem, MinExp::toElem, AddExp::toElem):Use\n\tIRState::arrayOpNotImplemented,\tIRState::buildOp.\n\t(XorAssignExp::toElem, OrAssignExp::toElem, AndAssignExp::toElem)\n\t(UshrAssignExp::toElem, ShrAssignExp::toElem, ShlAssignExp::toElem)\n\t(ModAssignExp::toElem, DivAssignExp::toElem, MulAssignExp::toElem)\n\t(MinAssignExp::toElem, AddAssignExp::toElem): Use\n\tIRState::arrayOpNotImplemented, IRState::buildAssignOp.\n\n\t* d-codegen.cc (libcall_ids): Remove _adCmpChar.\n\t(IRState::getLibCallDecl): Remove LIBCALL_ADCMPCHAR.\n\t* d-glue.cc (CmpExp::toElem): Don't call LIBCALL_ADCMPCHAR.\n\n\t* lang.opt: Define Wcast-result.\n\t* d-codegen.cc (IRState::convertTo): Warn about null result, but only\n\tif -Wcast-result.\n\t(IRState::hwi2toli): Move to header.\n\t(IRState::realPart): Likewise.\n\t(IRState::imagPart): Likewise.\n\t(IRState::toElemLvalue): Clean-up tree args array.\n\t(IRState::doArraySet): New function.\n\t(IRState::arraySetExpr): New function.\n\t* d-glue.cc (EqualExp::toElem): Clean-up tree args array.\n\t(CatAssignExp::toElem): Likewise.\n\t(AssignExp::toElem): Likewise.\n\t(DeleteExp::toElem): Likewise.\n\t(NewExp::toElem): Use IRState::modify.\n\t(ArrayLiteralExp::toElem): Don't call ARRAYLITERALTX library function\n\tif assigning to static array.\n\t(StructLiteralExp::toElem): Use IRState::arraySetExpr.\n\t(do_array_set): Move to IRState::doArraySet.\n\t(array_set_expr): Move to IRState::arraySetExpr.\n\n\t* d-lang.h (D_TYPE_IMAGINARY_FLOAT): Define.\n\t(d_convert_basic): Remove.\n\t* d-builtins.c (d_init_builtins): Mark imaginary types as\n\tD_TYPE_IMAGINARY_FLOAT.\n\t* d-builtins2.cc (gcc_type_to_d_type): Use convert.\n\t* d-codegen.cc (IRState::emitLocalVar): Call pushdecl earlier so\n\tcatches CONST_DECLs.\n\t(IRState::convertTo): Remove handling of conversions between\n\timaginary/real, imaginary/complex, complex/imaginary types, use\n\tconvert.\n\t(IRState::convertForArgument): Use convert.\n\t(IRState::arrayElemRef): Likewise.\n\t(IRState::call): Likewise.\n\t(IRState::libCall): Likewise.\n\t(IRState::maybeExpandSpecialCall): Likewise.\n\t* d-convert.cc (d_convert_basic): Mark static.\n\t(convert): Handle correct conversions between imaginary/real,\n\timaginary/complex, complex/imaginary types.\n\t* d-glue.cc (InExp::toElem): Use convert.\n\t(BoolExp::toElem): Likewise.\n\t(FuncDeclaration::buildClosure): Likewise.\n\n\t* d-builtins.c (def_fn_type): Use build_varargs_function_type_array and\n\tbuild_function_type_array to create built-in functions.\n\t(d_init_builtins): Use lang_hooks.types.type_for_size.\n\t* d-builtins2.cc (d_gcc_magic_builtins_module): Use\n\tlang_hooks.types.type_for_mode.\n\t* d-codegen.cc (IRState::pointerIntSum): Use\n\tlang_hooks.types.type_for_size.\n\t(IRState::call): Use lang_hooks.types.type_promotes_to.\n\t(IRState::maybeExpandSpecialCall): Likewise.\n\t* d-glue.cc (build_math_op): Use lang_hooks.types.type_for_mode.\n\t* d-lang.cc (d_type_for_mode): Mark static.\n\t(d_type_for_size): Likewise.\n\t(d_type_promotes_to): Likewise.\n\n2012-08-31  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-glue.cc (FuncDeclaration::toObjFile): Flatten nested levels and\n\tloops in function, delay printing function name in verbose mode until\n\twe know the function is being compiled.\n\n\t* d-codegen.cc (IRState::buildFrameForFunction): New function.\n\t(IRState::buildChain): Use IRState::buildFrameForFunction to get the\n\tframe record type.\n\t(IRState::getFrameInfo): Likewise.\n\t* d-glue.cc (FuncDeclaration::buildClosure): Likewise.\n\n2012-08-30  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* asmstmt.cc (ExtAsmStatement::toCBuffer): Mark unused parameter as\n\tATTRIBUTE_UNUSED.\n\t* d-codegen.cc (WrappedExp::toCBuffer): Likewise.\n\t* d-objfile.cc (ObjectFile::setupSymbolStorage): Revert to previous\n\tbehaviour of setting symbol storage.\n\n\t* d-codegen.cc (IRState::expandDecl): Use IRState::vinit.\n\t(IRState::binding): Likewise.\n\t(IRState::var): Handle all declarations, not just vars.\n\t* d-glue.cc (PtrExp::toElem): Simplify use of IRState::var.\n\t(SymbolExp::toElem ): Likewise.\n\t(ThisExp::toElem): Likewise.\n\n\t* d-lang.cc (d_init): Remove 'Thumb' identifier for ARM as 16bit\n\tplatforms aren't supported.\n\t(GNU_LongDouble128): Remove identifier as long double size is\n\tdetermined from type information.\n\n\t* d-decls.cc (TypeInfoDeclaration::toSymbol): Mark all typeinfo decls\n\tas 'used'.\n\t* d-glue.cc (one_elem_array): Remove.\n\t(CatExp::toElem): Inline use of one_elem_array, clean-up.\n\t* d-objfile.cc (ObjectFile::setupSymbolStorage): Update to better\n\thandle use of declarations marked with comdat, extern or static.\n\t(ObjectFile::doSimpleFunction): Mark function as 'used'.\n\t* dt.cc (dt2node): Clean-up indentation.\n\n\t* Make-lang.in: Fix issue with cross-compiler configuration.\n\n2012-08-29  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* lang-specs.h: Remove special case for handled D source files.\n\t* Make-lang.in: Remove special case for building gcc.o, use\n\tGCC_EXTRA_LIBS to link against, rather than specific gcc object files.\n\t(D_DRIVER_NAME): Remove use of variable.\n\t(D_DRIVER_OBJS): Likewise.\n\t(D_COMPILER_NAME): Likewise.\n\n2012-08-23  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-builtins2.cc (eval_builtin): Use builtin_decl_explicit.\n\t* d-codegen.cc (IRState::emitLocalVar): Use warning.\n\t(IRState::convertTo): Likewise.\n\t(IRState::addressOf): Use IRState::markAddressable.\n\t(IRState::markAddressable): New function.\n\t(IRState::markUsed): New function.\n\t(IRState::markRead): New function.\n\t(IRState::maybeExpandSpecialCall): Use builtin_decl_explicit.\n\t(IRState::floatMod): Likewise.\n\t(IRState::exceptionObject): Likewise.\n\t* d-glue.cc (IdentityExp::toElem): Likewise.\n\t(EqualExp::toElem): Likewise.\n\t(PowExp::toElem): Likewise.\n\t(AssignExp::toElem): Likewise.\n\t(HaltExp::toElem): Likewise.\n\t(ArrayLiteralExp::toElem): Likewise.\n\t(FuncDeclaration::toObjFile): Likewise.\n\t* d-lang.cc (d_mark_addressable): Remove function.\n\t(d_mark_exp_read): Remove function.\n\t* d-lang.h (d_warning): Remove macro.\n\t(d_built_in_decls): Remove macro.\n\t* d-objfile.cc (Obj::includelib): Use warning.\n\t(Obj::startaddress): Likewise.\n\n2012-08-22  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-lang.cc (binary): Moved function from frontend.\n\t* d-codegen.cc (IRState::extractMethodCallExpr): Update for new C++ VEC\n\ttemplate in GCC.\n\t* d-bi-attrs.h (parse_optimize_options): Likewise.\n\t* d-dmd-gcc.h: Remove ifdef __cplusplus, use GCC_SAFE_DMD.\n\t* d-gcc-includes.h: Remove ifdef __cplusplus.\n\t* d-lang.h: Likewise.\n\t* Make-lang.in: Remove CC and CFLAGS from Makefile, add build rule for\n\tnew texi man pages.\n\t* gdc.texi: New documentation for GDC.\n\n2012-08-18  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc (IRState::convertTo): Fix to allow conversion between\n\tvoid* and associative arrays.\n\t(IRState::convertForArgument): Use d_convert_basic.\n\t(IRState::call): Don't use d_convert_basic, now handled by\n\tconvertForArgument.\n\t* d-gcc-real.cc (real_t::real_t): Increase real type mode to be greater\n\tthan integer type size to prevent overflow in conversions.\n\t* d-glue.cc (CastExp::toElem): Don't get implicit AA type.\n\n2012-08-17  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* dfrontend: Update to D frontend version 2.060\n\n\t* d-codegen.cc (libcall_ids): New library functions.\n\t(IRState::getLibCallDecl): Implement new library function signatures.\n\t* d-codegen.h (LibCall::LIBCALL_NEWITEMT): New enum value.\n\t(LibCall::LIBCALL_NEWITEMIT): Likewise.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Small readability cleanup.\n\t* d-glue.cc (NewExp::toElem): Use new library functions.\n\t(StructLiteralExp::toElem): Update for new frontend.\n\t(ReturnStatement::toIR): Likewise.\n\t* d-incpath.cc (add_import_path): New signature.\n\t(add_fileimp_path): Likewise.\n\t(add_import_paths): Pass split Strings to helper functions.\n\t* d-lang.cc (d_parse_file): Use Obj::init and Obj::term.\n\t* d-objfile.cc (objmod): New variable.\n\t(Obj::init): New function.\n\t(Obj::term): Likewise.\n\t(Obj::includelib): Likewise.\n\t(Obj::startaddress): Likewise.\n\t(Obj::allowZeroSize): Likewise.\n\t(Obj::moduleinfo): Likewise.\n\t(Obj::export_symbol): Likewise.\n\t* symbol.h (Obj): New struct to allow object oriented interface to glue\n\tcode from frontend.\n\n\t* d-builtins2.cc (d_gcc_magic_stdarg_check): Add new va_arg magic\n\tfunction that stores the next value through a passed parameter.\n\tRemove workaround for inout signature as va_list is always passed by\n\treference to intrinsic templates.\n\t(d_gcc_magic_module): Assign module directly to global IRState.\n\t* d-codegen.cc (IRState::builtinsModule): Remove static declaration.\n\t(IRState::intrinsicModule): Likewise.\n\t(IRState::intrinsicCoreModule): Likewise.\n\t(IRState::mathModule): Likewise.\n\t(IRState::mathCoreModule): Likewise.\n\t(IRState::cstdargTemplateDecl): Likewise.\n\t(IRState::cstdargStartTemplateDecl): Likewise.\n\t(IRState::varsInScope): Likewise.\n\t(IRState::call): Use flag_split_darrays.\n\t(IRState::maybeExpandSpecialCall): Clean-up va_start and va_arg\n\timplementations.\n\t(IRState::maybeSetUpBuiltin): Handle new va_arg function.\n\t* d-codegen.h (Intrinsic::INTRINSIC_VA_ARG): New enum definition.\n\t(IRState::setBuiltinsModule): Remove.\n\t(IRState::setIntrinsicModule): Likewise.\n\t(IRState::setMathModule): Likewise.\n\t(IRState::setCStdArg): Likewise.\n\t* d-glue.cc (CatExp::toElem): Use flag_split_darrays.\n\t* d-irstate.cc (IRBase::startFunction): Set varsInScope.\n\t* d-lang.cc (d_init_options): Set modules that require special\n\thandling.\n\t(d_handle_option): Don't handle OPT_fsplit_dynamic_arrays.\n\t* lang.opt: fsplit-dynamic-arrays mapped to variable\n\tflag_split_darrays.\n\n2012-08-16  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-glue.cc (IdentityExp::toElem): Re-order precendence of type\n\tchecking. Treat static arrays as D arrays in identity comparisons.\n\t(EqualExp::toElem): Use adEq2 over built-in memcmp for equality\n\tcomparisons for static and dynamic arrays.\n\t(TypeStruct::toCtype): Remove old platform specific workaround.\n\n\t* d-builtins2.cc (bi_lib_list): New decl to hold list of GCC library\n\tbuilt-ins.\n\t(d_bi_init): Add decls to bi_list_list if recognising built-ins.\n\t(d_gcc_magic_builtins_module): Rename built-in type C long to\n\t__builtin_clong, built-in type C ulong to __builtin_culong.\n\t(d_gcc_magic_libbuiltins_check): New function to assign internal\n\tsymbol for built-in library functions.\n\t(d_gcc_magic_libbuiltins_module): New function to scan modules that\n\tcontain GCC library built-ins.\n\t(d_gcc_magic_module): Search all core.stdc modules for possible GCC\n\tlibrary built-ins.\n\t* d-codegen.h (IRState::useBuiltins): Remove.\n\t* d-lang.cc (d_init_options): Don't set IRState::useBuiltins.\n\t(d_handle_option): Likewise.\n\t* lang.opt: Re-order D frontend compiler options.\n\n\t* d-codegen.cc (IRState::buildChain): Override chainLink and chainFunc\n\tfor function if static chain is passed via hidden 'this' and no frame\n\tis created.\n\t(IRState::getFrameInfo): Pass static chain around nested functions in\n\tthe same way as closures for better performance.\n\n\t* d-codegen.cc (libcall_ids): Re-order list in ascii collating order,\n\tadd new library routines to lookup, rename all non-vararg functions to\n\tmatch DMD ABI implementation.\n\t(LibCall): Re-order enum and rename values to match libcall_ids.\n\t(IRState::toElemLvalue): Use new LibCall name.\n\t(IRState::getLibCallDecl): Update to match current library signatures,\n\tadd implementation of new library routines.\n\t(IRState::maybeSetLibCallDecl): New function to set internal symbol\n\tfor special D RT library functions.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Use\n\tIRState::maybeSetLibCallDecl.\n\t* d-glue.cc (InExp::toElem): Use new LibCall name.\n\t(CatAssignExp::toElem): Likewise.\n\t(IndexExp::toElem): Likewise.\n\t(DeleteExp::toElem): Likewise.\n\t(RemoveExp::toElem): Likewise.\n\t(NewExp::toElem): Likewise.\n\t(ArrayLiteralExp::toElem): Likewise.\n\t(AssocArrayLiteralExp::toElem): Likewise.\n\t(NullExp::toElem): Use IRState::convertTo.\n\n\t* d-codegen.cc (needs_temp): Remove.\n\t(IRState::makeTemp): New function.\n\t(IRState::maybeMakeTemp): Re-implement to use isFreeOfSideEffects.\n\t(IRState::isFreeOfSideEffects): Re-implement to allow better CSE.\n\t(IRState::call): Use IRState::makeTemp.\n\n\t* d-builtins2.cc (gcc_type_to_d_type): Use d_convert_basic.\n\t* d-codegen.cc (IRState::emitLocalVar): Use IRState::vinit.\n\t(IRState::convertTo): New function for tree conversions.\n\t(IRState::convertTo): Use IRState::convertTo.\n\t(IRState::convertForCondition): Likewise.\n\t(IRState::darrayVal): Likewise.\n\t(IRState::pointerIntSum): Likewise.\n\t(IRState::pointerOffsetOp): Likewise.\n\t(IRState::pvoidOkay): Likewise.\n\t(IRState::boundsCond): Likewise.\n\t* d-convert.cc (convert): New function to be called from C.\n\t(d_build_truthvalue_op): Use d_convert_basic.\n\t* d-glue.cc (convert): Remove.\n\t(build_bool_binop): Use IRState::convertTo.\n\t(build_math_op): Likewise.\n\t(CmpExp::toElem): Likewise.\n\t(PowExp::toElem): Likewise.\n\t(do_array_set): Likewise.\n\t(AssignExp::toElem): Likewise.\n\t(VectorExp::toElem): Likewise.\n\t(NotExp::toElem): Likewise.\n\t(CallExp::toElem): Likewise.\n\t(SymbolExp::toElem): Likewise.\n\t* dt.cc (dt2tree_list_of_elems): Use d_convert_basic.\n\n2012-07-26  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-gcc-real.cc (real_t::real_t): Use d_float64 for constructor.\n\t(real_t::isConst0): Remove.\n\t(real_t::isConst1): Likewise.\n\t(real_t::isConst2): Likewise.\n\t(real_t::isConstMinus1): Likewise.\n\t(real_t::isConstHalf): Likewise.\n\t* d-gcc-real.h (longdouble): New typedef for real_t.\n\t(ldouble): New template for ldouble conversions.\n\t(ld_sprint): New function for ldouble to string formatting.\n\t* d-codegen.cc (IRState::hwi2toli): Handle maximum 64bit value case.\n\n2012-07-18  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc (IRState::delegateVal): Remove ENABLE_CHECKING code.\n\t(IRState::objectInstanceMethod): Remove special case to avoid calling\n\tDotTypeExp::toElem.\n\t* d-glue.cc (CommaExp::toElem): Likewise.\n\t(DotTypeExp::toElem): Implement function.\n\t(StructLiteralExp::toElem): Assert instead that basetype is a struct.\n\t* d-gcc-reah.cc (real_t::real_t): New overload for 'double' type.\n\t(real_t::format): Change function type to int, return size of buffer\n\tfrom function.\n\t(real_t::formatHex): Likewise.\n\t* d-builtins2.cc (d_gcc_magic_stdarg_check): Update signature, remove\n\tcheck for is_c_std_arg.\n\t(d_gcc_magic_stdarg_module): Likewise.\n\t(d_gcc_magic_module): Remove check for core.vararg.\n\t* d-codegen.cc (INTRINSIC_STD_VA_ARG): Remove.\n\t(IRState::maybeSetUpBuiltin): Don't handle INTRINSIC_STD_VA_ARG.\n\n2012-07-13  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-decls.cc (Dsymbol::toSymbolX): Remove use of PRIuSIZE format macro.\n\t(FuncDeclaration::toThunkSymbol): Likewise.\n\n2012-07-12  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-lang.h (D_DECL_IS_CONTRACT): New macro.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Mark in and out contracts as\n\tD_DECL_IS_CONTRACT.\n\t(FuncDeclaration::toThunkSymbol): D thunks no longer private by\n\tdesign. Alter mangling of thunk symbols to be unique across the entire\n\tcompilation unit.\n\t* d-objfile.cc (ObjectFile::makeDeclOneOnly): Catch public contracts to\n\tmark them as one-only.\n\t(ObjectFile::outputThunk): Mark weakref thunks as private.\n\n2012-07-10  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* Make-lang.in: Remove unused borrowed objects.\n\t* d-builtins2.cc (d_bi_builtin_func): Don't add builtin if\n\t-fno-builtin was given.\n\t* d-codegen.cc (IRState::emitTemplates): Remove static declaration.\n\t(IRState::splitDynArrayVarArgs): Likewise.\n\t(IRState::useInlineAsm): Likewise.\n\t(IRState::useBuiltins): Likewise.\n\t(d_gcc_force_templates): Update to use global gen.\n\t* d-codegen.h (emitTemplates): Remove static attribute.\n\t(splitDynArrayVarArgs): Likewise.\n\t(useBuiltins): Likewise.\n\t(useInlineAsm): Remove member.\n\t(stdInc): Define new member.\n\t* d-incpath.cc (std_inc): Remove global.\n\t(add_import_paths): Update function signature.\n\t* d-lang.cc (d_init_options): Default splitDynArrayVarArgs to false.\n\t(d_init): Update call to add_import_paths.\n\t(d_handle_option): Remove OPT_fd_inline_asm, add\n\tOPT_fsplit_dynamic_arrays.\n\t* lang.opt: Likewise.\n\n2012-07-08  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-builtins2.cc (d_gcc_type_align): Update function signature. Use\n\ttype align size to determine the known align size of a decl.\n\t* d-dmd-gcc.h (d_gcc_type_align): Update function signature.\n\t* symbol.h (Symbol): New member, Salignment.\n\t* symbol.cc (Symbol::Symbol): Initialise Salignment.\n\t* d-decls.cc (VarDeclaration::toSymbol): Set Salignment if there is an\n\talignment in effect on the decl.\n\t(AggregateDeclaration::toInitializer): Likewise.\n\t* d-objfile.cc (ObjectFile::outputStaticSymbol): Set DECL_ALIGN if\n\tSalignment was given for static decl.\n\n2012-07-07  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-builtins2.cc (d_gcc_magic_builtins_module): Add check for\n\tDECL_ASSEMBLER_NAME_SET_P when testing for builtins that can be\n\tmarkable as pure in the D frontend.\n\n\t* d-codegen.cc (IRState::integerConstant): Hide use of\n\tHOST_BITS_PER_WIDE_INT macros.\n\t(IRState::hwi2toli): Likewise.\n\t(IRState::getTargetSizeConst): Likewise.\n\n\t* d-builtins.c (d_global_trees): Move declaration here.\n\t(lookup_C_type_name): Rename to lookup_ctype_name.\n\t(d_init_builtins): Move set-up of d_global_trees here.\n\t(gcc_d_backend_init): Move function from d-glue.cc and refactored.\n\t(gcc_d_backend_term): Likewise.\n\t* d-builtins2.cc (d_bi_init): Set-up D frontend sizes here.\n\t* d-glue.cc (gcc_d_backend_init): Removed.\n\t(gcc_d_backend_term): Likewise.\n\n\t* d-incpath.cc (add_phobos_versyms): New function to scan\n\tphobos-vers-syms file.\n\t(register_import_chains): Renamed to add_import_paths.\n\t* d-lang.cc (d_init): Call add_phobos_versyms and add_import_paths.\n\t(d_parse_int): Don't use strtol to get number from argument string.\n\n\t* d-incpath.cc (maybe_fixup_phobos_target): Remove.\n\t(register_import_chains): Remove use of maybe_fixup_phobos_target.\n\t* d-lang.cc (maybe_fixup_os_versym): Remove\n\t(d_init): Remove use of maybe_fixup_os_versym.\n\n\t* d-lang.cc (saved_reg_names): Remove.\n\t(d_init): Remove use of saved_reg_names.\n\t(d_post_options): Likewise.\n\n2012-07-05  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-glue.cc (StructLiteralExp::toElem): Stop after first assignment for\n\tconstructors built for union types.\n\n2012-07-01  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* symbol.h (deferredNestedFuncs): Renamed from otherNestedFuncs, use as\n\tvalue type rather than pointer.\n\t(thunks): Use as value type rather than pointer.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Remove check for\n\tdeferredNestedFuncs being NULL.\n\t(FuncDeclaration::toThunkSymbol): Remove check for thunks being NULL.\n\t* d-glue.cc (DelegateExp::toElem): Remove check for deferredNestedFuncs\n\tbeing NULL.\n\t(FuncDeclaration::toObjFile): Likewise.\n\t* d-objfile.cc (ObjectFile::shouldEmit): Add nested functions to\n\tdeferredNestedFuncs of their parent function incase parent is actually\n\temitted later in during compilation.\n\t* d-builtins2.cc (d_gcc_type_align): Explicit alignment of variables\n\ttakes precedence over default alignment.\n\t* d-gcc-includes.h: Re-order list of includes.\n\n2012-06-26  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc (IRState::twoFieldType): Use rest_of_decl_compilation.\n\t* d-gcc-includes.h: Remove last of poisoned backend headers.\n\t* d-glue.cc (FuncDeclaration::toObjFile): Use fprintf for diagnostic\n\tmessage.  Use rest_of_decl_compilation directly.\n\t(SynchronizedStatement::toIR): Likewise.\n\t(TypeFunction::toCtype): Remove old version1 macro.\n\t* d-lang.cc (d_parse_file): Remove dependency on backend header. Use\n\tfprintf for diagnostic messages.\n\t(nametype): Use rest_of_decl_compilation directly.\n\t(d_handle_option): Remove version 1 option.\n\t* dmd-script: Likewise.\n\t* lang.opt: Likewise.\n\t* d-objfile.cc (ObjectFile::outputStaticSymbol): Use\n\trest_of_decl_compilation directly.\n\t(ObjectFile::declareType): Likewise.\n\t(obj_moduleinfo): Likewise.\n\t(obj_tlssections): Likewise.\n\t(ObjectFile::outputThunk): Implement new method of thunk generation\n\tfor external symbols using weakref.\n\t* d-objfile.h (rodc): Remove.\n\n2012-06-25  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-builtins.c (d_init_builtins): Use build_tree_list to initialise\n\tvoid_list_node.\n\t* d-glue.cc (ArrayLiteralExp::toElem): Always generate code for\n\tarrayliteralTp.\n\t(TypeFunction::toCtype): Chain on void_list_node to the end of the\n\tfunction type parameters.  Fixes function signatures in debugging.\n\n2012-06-23  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* Make-lang.in (d_OBJS): Add so IN_GCC_FRONTEND is defined when\n\tbuilding gdc sources.\n\t* d-builtins.c: Remove poisoned headers.\n\t* d-codegen.cc: Likewise.\n\t* d-gcc-includes.h: GCC system headers included first, removed\n\tinternally defined macros and poisoned headers.\n\t* d-gcc-tree.h: Use GCC system headers instead of defining tree_node.\n\t* d-lang.cc: GCC system headers included first.\n\t(pushdecl_top_level): Removed.\n\t* d-objfile.cc: Remove poisoned headers.\n\t* gdc_alloca.h: Use liberty.h instead of handling include of alloca.\n\n\t* d-decls.cc (Dsymbol::toSymbolX): Use snprintf rather than sprintf.\n\t(FuncDeclaration::toSymbol): Likewise.\n\t* d-gcc-real.cc (real_t::init): Likewise.\n\t* symbol.cc (Symbol::Symbol): Use NULL_TREE to initialise tree.\n\t(symbol_calloc): Use xstrdup to copy string.\n\n\t* Make-lang.in: Remove D language version 1 from build\n\t(_GNU_SOURCE): Removed macro from build.\n\t(ELFOBJ): Likewise.\n\t(D_VA_LIST_TYPE_VOIDPTR): Likewise.\n\t* asmstmt.cc (ExtAsmStatement::semantic): Removed use of V2 macro.\n\t* d-builtins2.cc (d_gcc_builtin_va_list_d_type): Removed use of\n\tD_VA_LIST_TYPE_VOIDPTR macro.\n\t(gcc_type_to_d_type): Likewise.\n\t(d_gcc_magic_stdarg_check): Likewise.\n\t(d_gcc_magic_builtins_module): Removed use of V2 macro, and V1\n\tencapsulated code.\n\t* d-codegen.cc (IRState::convertTo): Likewise.\n\t(IRState::toDArray): Likewise.\n\t(IRState::typesCompatible): Likewise.\n\t(IRState::arrayBoundsCheck): Likewise.\n\t(IRState::assertCall): Likewise.\n\t(libcall_ids): Likewise.\n\t(IRState::getLibCallDecl): Likewise.\n\t(IRState::getFrameForSymbol): Likewise.\n\t(IRState::isFuncNestedIn): Likewise.\n\t(IRState::buildChain): Likewise.\n\t(IRState::getFrameInfo): Likewise.\n\t(IRState::getFrameRef): Likewise.\n\t(IRState::functionNeedsChain): Likewise.\n\t(IRState::startCond): Likewise.\n\t(IRState::exitIfFalse): Likewise.\n\t(IRState::startCase): Likewise.\n\t(IRState::doCase): Likewise.\n\t(IRState::endCase): Likewise.\n\t* d-decls.cc (VarDeclaration::toSymbol): Likewise\n\t(FuncDeclaration::toSymbol): Likewise.\n\t* d-glue.cc (CondExp::toElem): Likewise.\n\t(build_bool_binop): Likewise.\n\t(EqualExp::toElem): Likewise.\n\t(CmpExp::toElem): Likewise.\n\t(AndAndExp::toElem): Likewise.\n\t(OrOrExp::toElem): Likewise.\n\t(AssignExp::toElem): Likewise.\n\t(CastExp::toElem): Likewise.\n\t(CallExp::toElem): Likewise.\n\t(AssertExp::toElem): Likewise.\n\t(AssocArrayLiteralExp::toElem): Likewise.\n\t(StructLiteralExp::toElem): Likewise.\n\t(FuncDeclaration::toObjFile): Likewise.\n\t(Module::genobjfile): Likewise.\n\t(TypeFunction::toCtype): Likewise.\n\t(ThrowStatement::toIR): Likewise.\n\t(TryCatchStatement::toIR): Likewise.\n\t(ReturnStatement::toIR): Likewise.\n\t(SwitchStatement::toIR): Likewise.\n\t(IfStatement::toIR): Likewise.\n\t(ForStatement::toIR): Likewise.\n\t(ExpStatement::toIR): Likewise.\n\t* d-irstate.cc (IRBase::startFunction): Likewise.\n\t* d-lang.cc (d_init_options_struct): Likewise.\n\t(d_handle_option): Likewise.\n\t(d_parse_file): Likewise.\n\n2012-06-21  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* Make-lang.in: Remove d-asm-i386.h\n\t* asmstmt.cc (d_build_asm_stmt): Update signature, use build5.\n\t(getFrameRelativeValue): Remove.\n\t(d_format_priv_asm_label): Likewise.\n\t(d_have_inline_asm): Likewise.\n\t(AsmProcessor): Likewise.\n\t(AsmStatement::toIR): Update sorry message.\n\t* d-codegen.cc (IRState::expandPortIntrinsic): Update call to\n\td_build_asm_stmt.\n\t(IRState::doAsm): Likewise.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Remove check for inline asm.\n\t* d-glue.cc (FuncDeclaration::toObjFile): Likewise.\n\t(LabelStatement::toIR): Likewise.\n\t* d-lang.cc (VersionCondition::addPredefinedGlobalIdent): Remove D\n\tInline Asm version identifiers.\n\t* d-lang.h (d_build_asm_stmt): Update signature.\n\n2012-06-19  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-decls.cc (FuncDeclaration::toSymbol): Mark in/out contracts as\n\tTREE_PUBLIC to allow calling cross-module.\n\t* d-lang.cc (d_parse_file): Update for 2.059.\n\n2012-06-16  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* dfrontend: Merged with DMD 2.059.\n\t* d-builtins2.cc (gcc_type_to_d_type): Use new frontend value.\n\t* d-codegen.cc (IRState::getLibCallDecl): Fix return type of _aaDelp.\n\t(IRState::getVThis): Use frontend provided member to determine if\n\tfunction has nested references.\n\t* d-decl.cc (FuncDeclaration::toSymbol): Weakly pure functions don't\n\tguarantee no vops.\n\t* d-gcc-real.cc (max_float_mode): Remove.\n\t(real_t::convert): Catch imaginary types in conversion.\n\t* d-glue.cc (EqualExp::toElem): Use memcmp for struct comparisons.\n\t(CatAssignExp::toElem): Rework order of logic to allow appending\n\tdelegates to an array.\n\t(DelegateExp::toElem): Implement handling of lambda functions.\n\t(FuncExp::toElem): Ditto.\n\t(AssocArrayLiteralExp::toElem): Implement handling of AssociativeArray\n\ttypes sent to backend.\n\t* d-objfile.cc (lmtab): Remove.\n\t(cvtLocToloc_t): Update implementation.\n\t(outdata): Now assert that we don't receive error nodes.\n\n2012-06-05  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-decls.cc (FuncDeclaration::toSymbol): Make better use of 'pure' and\n\t'pure const' functions in GCC codegen.\n\t* d-bi-attrs.h: Added TM_ATTR* masks.\n\t(handle_tm_wrap_attribute, handle_tm_attribute, tm_attr_to_mask,\n\tfind_tm_attribute): New.\n\t(struct d_common_attribute_table): Added transaction* attributes.\n\n2012-06-04  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-objfile.cc (ObjectFile::outputThunk): Output thunks moved back to\n\tthe frontend, as backend does not emit them for DECL_EXTERNAL functions.\n\n2012-05-29  Daniel Green  <venix1@gmail.com>\n\n\t* setup-gcc.sh: Add GCC 4.8 to list of supported GCC versions. Patch\n\tcourtesy of Calrama\n\thttps://bitbucket.org/goshawk/gdc/issue/345\n\n2012-05-29  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-codegen.cc (IRState::endCase): Remove parameter from function. Use\n\tcondition type as the SWITCH_EXPR type, rather than use of void.\n\t* d-codegen.h (IRState::endCase): Update signature.\n\t* d-glue.cc (SwitchStatement::toIR): Update call to endCase.\n\n2012-05-28  Daniel Green  <venix1@gmail.com>\n\n\t* d-builtins.c (DEF_ATTR_STRING): Define and undefine along with other\n\tmacros.\n\t* d-lang.cc (d_write_global_declartions): Use\n\tfinalize_compilation_unit. GCC 2012-04-30\n\t* d-objfile.cc (ObjectFile::outputThunk): Use\n\tsymtab_add_to_same_comdat_group. GCC 2012-04-30\n\t* lang.opt: Match help strings for duplicated options.\n\n2012-02-01  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* setup-gcc.sh: Remove -hg option.\n\t* dfrontend/func.c (FuncDeclaration::semantic): Remove code adding\n\tmethod to flat list.\n\t(FuncDeclaration::semantic3): Re-add here.\n\n2012-01-01  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-builtins2.cc (IRState::buildChain): Don't do nrvo if the\n\tvariable is put in a closure.\n\t* d-glue.cc (FuncDeclaration::buildClosure): Ditto.\n\t(ReturnStatement::toIR): Don't call postblit on nrvo returns.\n\t(DtorExpStatement::toIR): Don't call destructor if var is returned as\n\tthe nrvo variable.\n\n\f\nCopyright (C) 2012 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2013",
    "content": "2013-12-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_two_field_type): Declare builtin types as\n\ttoplevel declarations.\n\t* d-ctype.cc (EnumDeclaration::toDebug): Build type decl in debug code.\n\t* d-lang.cc (nametype): Rename to d_nametype.\n\n2013-12-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (EnumDeclaration::toDebug): Don't send array types to\n\trest_of_type_compilation.\n\n2013-12-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-spec.cc (lang_specific_driver): Require linking in library for all\n\tfiles except D interface files.\n\t* d-lang.cc (d_write_global_declarations): Call d_finish_compilation.\n\t* d-objfile.cc (mark_needed): Mark static.\n\t(d_finish_symbol): Don't call mark_needed.\n\t(d_finish_function): Likewise.\n\t(d_finish_compilation): New function to wrapup all global\n\tdeclarations, mark templates/comdats as needed if required, and start\n\tthe final compilation.\n\n2013-12-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-ctype.cc (TypeVector::toCtype): Treat void vectors as ubyte.\n\t* d-objfile.cc (VarDeclaration::toObjFile): Gag all errors compiling\n\tmanifest constants.\n\t* d-todt.cc (TypeVector::toDt): New function to generate correct static\n\tdata for vector initialisers.\n\n2013-12-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_init_options_struct): Don't define strict aliasing.\n\t(d_get_alias_set): New function to return language-specific alias set.\n\t* d-convert.cc (d_convert_basic): Always zero extend pointer to integer\n\tconversions.\n\n2013-12-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (maybe_set_builtin_frontend): Assert that all runtime\n\tlibrary functions have been set-up correctly.\n\t(libcall_ids): Remove unhandled library functions.\n\t(get_libcall): Likewise.\n\t* d-codegen.h (LibCall): Likewise.\n\t* d-objfile.cc (output_symbol_p): Remove.\n\n2013-12-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_init_options): Update for frontend changes.\n\t(d_handle_option): Set frontend allInst option if -femit-templates.\n\t* d-objfile.cc (output_template_p): Want to emit all instantiated\n\ttemplates if -femit-templates or -fdebug was passed to the compiler.\n\t* d-objfile.h (TemplateEmission): Define TEallinst.\n\t* d-todt.cc (StructDeclaration::toDt): Update for frontend changes.\n\t* d-spec.cc (THREAD_LIBRARY): Define default thread library to link if\n\tone is not already specified in the configuration process.\n\t(TIME_LIBRARY): Define default real time library to link if one is not\n\talready specified in the configuration process.\n\t(LIBSTDCXX): Define C++ library to link if compiling C++ and D sources.\n\t(lang_specific_driver): Update implementation to use new macros.\n\n2013-12-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (CatAssignExp::toElem): Don't call postblit after element\n\tappend to array.\n\t(NewExp::toElem): Handle calling 'new' on opaque types.\n\t(ArrayLiteralExp::toElem): Ensure array literal elements have no side\n\teffects by making temporaries as necessary.\n\t* d-todt.cc (StructLiteralExp::toDt): Update for frontend changes.\n\t* d-codegen.cc (build_frame_type): Check for scoped variables if\n\tbuilding a closure.\n\t* d-objfile.cc (d_finish_symbol): Relax toDt checking rule.\n\n2013-12-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-asmstmt.cc (ExtAsmStatement::ExtAsmStatement): Remove labels\n\tmember from class.\n\t* d-codegen.cc (d_gcc_force_templates): Remove.\n\t(convert_expr): Update for frontend changes.\n\t(convert_for_assignment): Likewise.\n\t(maybe_set_builtin_frontend): Update for changes to libdruntime\n\tcore.bitops signatures.\n\t* d-ctype.cc (TypeFunction::toCtype): Update for frontend changes.\n\t* d-decls.cc (Dsymbol::toSymbolX): Likewise.\n\t(VarDeclaration::toSymbol): Likewise.\n\t(FuncDeclaration::toSymbol): Don't defer nested functions here.\n\t* d-elem.cc (PowAssignExp::toElem): Update for frontend changes.\n\t(DeleteExp::toElem): Likewise.\n\t(AssertExp::toElem): Don't call invariant on an extern C++ class.\n\t* d-glue.cc (Global::init): Initialise new stdmsg member.\n\t* d-lang.cc (d_handle_option): Handle -fdeps switch.  Remove TEprivate\n\tfor -femit-templates switch.\n\t(genCmain): Update for frontend changes.\n\t(d_parse_file): Likewise.\n\t* d-longdouble.cc (longdouble::dump): Likewise.\n\t* d-objfile.cc (ClassDeclaration::toObjFile): Update for frontend\n\tchanges.\n\t(InterfaceDeclaration::toObjFile): Likewise.\n\t(EnumDeclaration::toObjFile): Likewise.\n\t(Symbol::Symbol): Remove outputSymbol member.\n\t(output_symbol_p): Mark static.\n\t(output_declaration_p): Determine symbol codegen status from\n\tsemanticRun.\n\t(output_template_p): New function to determine whether an instantiated\n\ttemplate is to be written to object file.\n\t(FuncDeclaration::toObjFile): Use semanticRun to update codegen status\n\tof function.\n\t(FuncDeclaration::buildClosure): Error if putting a scoped variable in\n\ta closure.\n\t(Module::genobjfile): Update for frontend changes.\n\t(d_comdat_linkage): Don't determine linkage from TE setting.  Mark all\n\tcomdat symbols as DECL_COMDAT.\n\t(setup_symbol_storage): Use output_template_p to determine whether the\n\tsymbol is being written to object file.\n\t(mark_needed): New function to mark decls that must be emitted.\n\t(d_finish_symbol): Mark finished symbols as needed.\n\t(d_finish_function): Mark finished functions as needed.\n\t(build_simple_function): Set semanticRun for glue changes.\n\t* d-objfile.h (OutputStage): Remove enum.\n\t* d-todt.cc (build_vptr_monitor): Update for frontend changes.\n\t(StructInitializer::toDt): Likewise.\n\t(StructDeclaration::toDt): Likewise.\n\t(TypeInfoEnumDeclaration::toDt): Likewise.\n\t(TypeInfoStructDeclaration::toDt): Likewise.\n\t(Type::getTypeInfo): Likewise.\n\n2013-11-30  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (genCmain): Implement code generation of __entrypoint\n\tmodule to provide the target C main function.\n\t(deps_write): Ignore the module __entrypoint when writing make deps.\n\t(d_parse_file): Handle writing __entrypoint module to object file.\n\t* d-objfile.cc (d_finish_symbol): Remove special handling of _tlsstart\n\tsymbol, but ensure _tlsend gets written to the thread common section.\n\t(d_finish_function): Remove call to build_tlssections.\n\t(build_tlssections): Remove.\n\n2013-11-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (ClassDeclaration::toVtblSymbol): Use TypeSArray::makeType\n\tto generate frontend static array type.\n\t* d-glue.cc (Dsymbol::ungagSpeculative): Define.\n\t* d-lang.cc (genCmain): Define as empty.\n\t(d_parse_file): Update for frontend changes.\n\t* d-objfile.cc (StructDeclaration::toObjFile): Likewise.\n\t* d-typinf.cc (TypeBasic::builtinTypeInfo): Likewise.\n\t* d-longdouble.cc (longdouble::isIdenticalTo): Remove.\n\t* d-port.cc (Port::fequal): Define.\n\n2013-11-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (gcc_type_to_d_type): Use TypeSArray::makeType to\n\tgenerate frontend static array types.\n\t* d-codegen.cc (build_attributes): Use optimize as don't want the\n\tctfeInterpret of TypeExp expressions.\n\t(get_object_method): Update for frontend changes.\n\t(get_libcall): Update to use Type::dtypeinfo.\n\t* d-elem.cc (IndexExp::toElem): Don't generate bounds checking codegen\n\tif frontend explictly requests it.\n\t(ArrayLiteralExp::toElem): Use TypeSArray::makeType to generate\n\tfrontend static array type.\n\t(StructLiteralExp::toElem): Update for frontend changes.\n\t* d-glue.cc (Global::increaseErrorCount): Define.\n\t* d-objfile.cc (Module::genmoduleinfo): Remove moduleinfo 'New'\n\timplementation for libdruntime changes.\n\t* d-todt.cc (StructLiteralExp::toDt): Literal initialisers override\n\tdefault initialisers.\n\t(TypeInfoDeclaration::toDt): Update to use Type::dtypeinfo.\n\t(TypeInfoStructDeclaration::toDt): Update for frontend changes.\n\t* d-typinf.c (Type::getInternalTypeInfo): Update to use\n\tType::dtypeinfo.\n\n2013-11-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-asmstmt.cc (ExtAsmStatement::comeFromImpl): Define for frontend\n\timplementation changes.\n\t* d-codegen.cc (get_libcall): Update to use Type::typeinfoclass.\n\t* d-codegen.cc (WrappedExp): Define as class.\n\t* d-convert.cc (d_convert_basic): Fix format warnings.\n\t* d-decls.cc (ModuleInfoDeclaration::toSymbol): Remove.\n\t(FuncDeclaration::toSymbol): Use mangleExact to get decl mangle.\n\t* d-elem.cc (ClassReferenceExp::toElem): Return reference to class.\n\t* d-glue.cc (verror): Fix format warnings.\n\t(verrorSupplemental): Likewise.\n\t(vwarning): Likewise.\n\t(vdeprecation): Likewise.\n\t(escapePath): Define for frontend implementation changes.\n\t* d-irstate.cc (IRState::getLoopForLabel): Implement breaking on named\n\tscope labels in for/while loops.\n\t* d-lang.cc (d_handle_option): Add handler for new -fdeps and\n\t-fmake-deps options.\n\t(d_parse_file): Handle new -fdeps and fmake-deps options.\n\t* d-objfile.cc (Dsymbol::toObjFile): Update to use RootObject.\n\t(Type::typeinfoclass): Update to use Type::typeinfoclass.\n\t(InterfaceDeclaration::toObjFile): Likewise.\n\t* d-objfile.h (Symbol): Remove inheritance from Object.\n\t* d-todt.cc (TypeInfoStructDeclaration::toDt): Update to use\n\tType::immutableOf.\n\n2013-11-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.c (gcc_type_to_d_type): Use TREE_INT_CST_LOW macro instead\n\tof tree_low_cst.\n\t(eval_builtin): Likewise.\n\t(gcc_cst_to_d_expr): Use tree_cst_hwi.\n\t* d-codegen.cc (tree_to_hwi): Remove call to deleted host_integerp.\n\t(maybe_expand_builtin): Use TREE_INT_CST_LOW macro.\n\t* d-lang.cc (d_parse_file): Update debug_hooks call for middle-end\n\tchanges.\n\t* d-system.h: Update includes for middle-end changes.\n\n2013-11-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (finish_thunk): Update for conversion of symtab types to\n\ta true class hierarchy.\n\n\t* d-ctype.cc (TypeClass::toCtype): Fix ABI to emit correct vtable and\n\tmonitor field names.\n\n\t* d-ctype.cc (TypeClass:toCtype): Set TYPE_LANG_SPECIFIC on record as\n\twell as reference type.\n\t* d-lang.cc (d_classify_record): New langhook to return appropriate\n\tclass/interface/struct type to the debugger.\n\n2013-10-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (ArrayLiteralExp::toElem): Build empty constructor for zero\n\tsized arrays.\n\n2013-10-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (AssignExp::toElem): Optimise assigning array literal to a\n\tstatic array.\n\t(ArrayLiteralExp::toElem): Do not allocate static or const array\n\tliterals on the heap using the GC.\n\n2013-10-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.c (DEF_FUNCTION_TYPE_8): Define.\n\n2013-10-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.c (gcc_cst_to_d_expr): Add support for VECTOR_CST to\n\tExpression conversion.\n\t(d_gcc_paint_type): Add support for painting to/from array literals.\n\n2013-10-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (cvtLocToloc_t): Rename to get_linemap.\n\t* d-glue.cc: New source to provide interface for defined globals and\n\terror handling called from the front-end.\n\n2013-09-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::call): Rename to d_build_call.\n\t(IRState::emitLocalVar): Rename to build_local_var.\n\t(IRState::buildAssignOp): Move to BinExp::toElemBin.\n\t(IRState::IRState): Remove IRState class.\n\t* d-irstate.cc (IRBase::IRBase): Rename to IRState, remove inheritance\n\tfrom Object class.\n\t* d-decls.cc (VarDeclaration::toSymbol): Remove redundant CONST_DECL\n\tcode as VarDeclaration::toObjFile does not emit manifest constants.\n\t* d-ctype.cc (TypeEnum::toCtype): Generate CONST_DECLs for enumeration\n\tmembers for correct debugging.\n\t* d-objfile.cc (build_type_decl): Use fully qualified type name in\n\tdebugging code.\n\t(VarDeclaration::toObjFile): Emit manifest constant values in debug\n\tcode generation.\n\n2013-09-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (SliceExp::toElem): Don't build D array for slices that\n\treturn a static array.\n\n2013-09-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::buildOp): Rename to build_binary_op.\n\n2013-09-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (binfo_for): Rename to build_class_binfo.\n\t(intfc_binfo_for): Rename to build_interface_binfo.\n\t(ClassDeclaration::toDebug): Move binfo generation into toCtype.\n\t* d-lang.cc (pushlevel): Rename to push_binding_level.\n\t(poplevel): Rename to pop_binding_level.\n\t(global_bindings_p): Rename to d_global_bindings_p, add langhook.\n\t(pushdecl): Rename to d_pushdecl, add langhook.\n\t(getdecls): Rename to d_getdecls, add langhook.\n\t(set_block): Remove function.\n\t(insert_block): Remove function.\n\t* d-irstate.cc (IRBase::startBindings): Inline set_block here.\n\t(IRBase::endBindings): Inline insert_block here.\n\n2013-08-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-spec.c (lang_specific_spec_functions): Remove.\n\n2013-08-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::doArraySet): Rename to IRBase::doArraySet.\n\t(IRState::arraySetExpr): Remove function.\n\t(IRState::expandDecl): Rename to expand_decl.\n\t(IRState::typeinfoReference): Rename to build_typeinfo.\n\t(IRState::buildChain): Merge into FuncDeclaration::buildClosure.\n\t(IRState::getVThis): Rename to build_vthis.\n\t(IRState::maybeExpandSpecialCall): Rename to maybe_expand_builtin.\n\t(IRState::toDArray): Rename to d_array_convert.\n\n2013-08-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (convert_expr): Check that the class type the codegen is\n\tcasting from is a base class of the class type the codegen is casting\n\tto, not the other way round.\n\n2013-08-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (ArrayLiteralExp::toElem): Return null for zero length\n\tarray literals.\n\n2013-08-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (finish_thunk): Don't emit thunks to external symbols as\n\tweakref declarations.\n\t* d-codegen.cc (IRState::maybeExpandSpecialCall): Remove intrinsic yl2x\n\tand yl2xp1 builtins.\n\t(maybe_set_builtin_frontend): Likewise.\n\n2013-07-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.c (d_gcc_magic_builtins_module): Set builtins solely\n\tprovided by the compiler as @safe, pure and nothrow.\n\t* d-codegen.cc (IRState::getVThis): Don't set outer 'this' of structs\n\tto be parent function chain if no frame has been created.\n\n2013-07-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (Expression::toElemDtor): Wrap temp variables destructor\n\tcalls in a try/finally expression.\n\n2013-07-05  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* patch-versym-os-4.8.x: Set versions on powerpc and alpha.\n\tRemove SysV4 support and therefore fix macro redefinition warnings.\n\t* patch-versym-os-4.9.x: Likewise.\n\n2013-07-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-longdouble.cc (longdouble::set): Intepret set values at higher\n\tprecision for min/max properties.\n\t* d-codegen.cc (maybe_set_builtin_frontend): Add yl2x and yl2xp1\n\tmath intrinsics.\n\t(IRState::maybeExpandSpecialCall): Likewise.\n\n2013-07-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (Module::genobjfile): Don't free current_module_info.\n\t* d-codegen.cc (IRState::buildAssignOp): Don't create a SAVE_EXPR\n\taround comma expressions used as lvalues.\n\t* d-todt.cc (TypeSArray::toDtElem): Get underlying vector basetype when\n\tlayouting out data in a static array.\n\n2013-06-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* complex_t.h: Move into dfrontend.\n\t* d-builtins.c (gcc_cst_to_d_expr): Explicitly create longdouble.\n\t* d-longdouble.cc (longdouble::parse): Remove function.\n\t(longdouble::longdouble): Remove constructors from longdouble.\n\tReplaced with operator= template and longdouble::set.\n\t(longdouble::rv): Update for new class layout.\n\t(longdouble::from_shwi): New function to create a longdouble value\n\tfrom a HOST_WIDE_INT.\n\t(longdouble::from_uhwi): Likewise, but from an unsigned HOST_WIDE_INT.\n\t(longdouble::to_shwi): New function to return a HOST_WIDE_INT value\n\tfrom a longdouble.\n\t(longdouble::to_uhwi): Likewise, but from an unsigedn HOST_WIDE_INT.\n\t(longdouble::set): New function to explicitly set longdouble value.\n\t(longdouble::toInt): Remove function.\n\t(longdouble::isZero): Remove function.\n\t(longdouble::isNegative): Remove function.\n\t* d-port.cc (Port::nan): Rename to Port::ldbl_nan.\n\t(Port::infinity): Rename to Port::ldbl_infinity.\n\t(Port::ldbl_max): New static field.\n\t(Port::init): Set ldbl_max to be maximimum value for long double type.\n\t(Port::strtof): New function to convert string to longdouble.\n\t(Port::strtod): Likewise.\n\t(Port::strtold): Likewise.\n\n2013-06-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (make_alias_for_thunk): Do not set\n\tTREE_SYMBOL_REFERENCED.\n\n2013-06-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_struct_memcmp): New function.\n\t* d-elem.cc (IdentityExp::toElem): Use build_struct_memcmp for field\n\tcomparisons of small structs.\n\n2013-06-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (make_temp): New function.\n\t* d-decls.cc (StructLiteralExp::toSymbol): Implement correctly to\n\tgenerate an anonymous symbol to reference to in the codegen.\n\t(ClassReferenceExp::toSymbol): Likewise, but also use an anonymous\n\ttype as size is not determined until the data has been layed out.\n\t* d-elem.cc (EqualExp::toElem): Optimise comparisons of arrays of basic\n\ttypes, also ensure left-to-right evaluation.\n\t(SliceExp::toElem): Handle returing slice as a static array type.\n\t(AddrExp::toElem): Handle taking the address of StructLiteralExp and\n\tClassReferenceExp symbols.\n\t(FuncExp::toElem): Relax type checking to allow returning function\n\taddresses as generic pointer types.\n\t(ArrayLiteralExp::toElem): Implicitly convert static arrays of void to\n\tstatic arrays of ubyte.\n\t(StructLiteralExp::toElem): Remove code generation of postblit calls,\n\tnow taken care of in the front end.\n\t* d-objfile.cc (Module::genmoduleinfo): Emit module name as a null\n\tterminated static array.\n\t* d-ctype.cc (TypeAArray::toCtype): Pass AA types around like pointers.\n\n2013-06-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* dfrontend: Update to D front-end version 2.063.\n\n\t* d-builtins.c (gcc_type_to_d_type): Use Loc for unknown locations.\n\t(d_gcc_magic_builtins_module): Likewise.\n\t(gcc_cst_to_d_expr): Likewise.\n\t* d-codegen.cc (get_libcall): Use FuncDeclaration::genCfunc to build\n\tD runtime library functions.\n\t* d-decl.cc (SymbolDeclaration::SymbolDeclaration): Remove function.\n\t(StructLiteralExp::toSymbol): New function.\n\t(ClassReferenceExp::toSymbol): New function.\n\t* d-elem.cc (AssertExp::toElem): Call struct/class invariants only if\n\tcompiler is generating invariant code.\n\t(TupleExp::toElem): Update for new front-end.\n\t(ClassReferenceExp::toElem): New function.\n\t* d-lang.cc (d_init_options): Set compiler.vendor front-end parameter.\n\t(d_init): Call Expression::init.\n\t* d-objfile.cc (InterfaceDeclaration::toObjFile): Correctly set the\n\txgetRTInfo field in the record layout.\n\t* d-todt.cc (CastExp::toDt): New function.\n\t(AddrExp::toDt): New function.\n\t(ClassReferenceExp::toDt): New function.\n\t(ClassReferenceExp::toDtI): New function.\n\t(ClassReferenceExp::toInstanceDt): New function.\n\t(ClassReferenceExp::toDt2): New function.\n\n2013-06-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Set 'this' parameter as\n\timplicitly read-only.\n\t* d-codegen.cc (declaration_type): Set 'this' declaration type as\n\timplicitly const.\n\t(build_frame_type): Set frame or closure type as implicitly const.\n\n2013-06-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.c (d_init_builtins): Make d_unknown_type_node a\n\tRECORD_TYPE.\n\t* d-lang.cc (d_build_eh_type_type): Cast the returned typeinfo decl to\n\tvoid pointer type.\n\n2013-06-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::var): Rename to get_decl_tree.\n\t(IRState::convertForArgument): Rename to convert_for_argument.\n\t(IRState::floatMod): Rename to build_float_modulus.\n\t(IRState::findThis): Rename to find_this_tree.\n\t(IRState::emitLocalVar): Update signature.\n\t(IRState::arrayElemRef): Remove function.\n\t* d-elem.cc (IndexExp::toElem): Move implementation of\n\tIRState::arrayElemRef here.\n\n2013-06-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (cmodule): Rename to current_module_decl.\n\t(object_file): Remove variable.\n\t* d-objfile.cc (ObjectFile::moduleInfo): Rename to current_module_info.\n\t(ObjectFile::modules): Rename to output_modules.\n\t(ObjectFile::staticCtorList): Rename to static_ctor_list.\n\t(ObjectFile::staticDtorList): Rename to static_dtor_list.\n\t(ObjectFile::emitTemplates): Rename to flag_emit_templates.\n\t(ObjectFile::beginModule): Remove function.\n\t(ObjectFile::endModule): Remove function.\n\t(ObjectFile::finish): Rename to d_finish_module.\n\t(ObjectFile::doLineNote): Remove function.\n\t(ObjectFile::setLoc): Rename to set_input_location.\n\t(ObjectFile::setDeclLoc): Rename to set_decl_location.\n\t(ObjectFile::setCfunEndLoc): Rename to set_function_end_locus.\n\t(ObjectFile::giveDeclUniqueName): Rename to get_unique_name.\n\t(ObjectFile::setupSymbolStorage): Rename to setup_symbol_storage.\n\t(ObjectFile::setupStaticStorage): Remove function.\n\t(ObjectFile::makeDeclOneOnly): Rename to d_comdat_linkage.\n\t(ObjectFile::outputStaticSymbol): Rename to d_finish_symbol.\n\t(ObjectFile::outputFunction): Rename to d_finish_function.\n\t(ObjectFile::addAggMethod): Remove function.\n\t(ObjectFile::initTypeDecl): Rename to build_type_decl.\n\t(ObjectFile::declareType): Remove function.\n\t(ObjectFile::shouldEmit): Rename to output_declaration_p.\n\t(ObjectFile::shouldEmit): Rename variant to output_symbol_p.\n\t(ObjectFile::doThunk): Rename to use_thunk.\n\t(ObjectFile::stripVarDecl): Remove function.\n\t(ObjectFile::doSimpleFunction): Rename to build_simple_function.\n\t(ObjectFile::doFunctionToCallFunctions): Rename to\n\tbuild_call_function.\n\t(ObjectFile::doCtorFunction): Rename to build_ctor_function.\n\t(ObjectFile::doDtorFunction): Rename to build_dtor_function.\n\t(ObjectFile::doUnittestFunction): Rename to build_unittest_function.\n\t(ObjectFile::hasModule): Rename to output_module_p.\n\t(ObjectFile::outputThunk): Rename to finish_thunk.\n\t(write_deferred_thunks): New function to emit deferred thunks.\n\n2013-06-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (VarDeclaration::toSymbol): Don't set default tls model.\n\t* d-objfile.cc (ObjectFile::setupSymbolStorage): Set default tls\n\tmodel for var decls before determining whether symbol is public.\n\t(build_tlssections): Likewise for TLS symbols.\n\n2013-06-01  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-codegen.cc (maybe_set_builtin_frontend): Check parameter and\n\treturn types of intrinsics.\n\n2013-06-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::var): Handle variables used for NRVO.\n\t* d-ir.cc (ReturnStatement::toIR): Return result decl directly if NRVO.\n\t* d-objfile.cc (Symbol::SnamedResult): New member to hold the named\n\tRESULT_DECL of the function.\n\t(FuncDeclaration::toObjFile): Set-up function for NRVO.\n\t(build_tlssections): Align _tlsstart and _tlsend symbols to target\n\taddress size.\n\t* d-ctype.cc (TypeFunction::toSymbol): Mark functions returning non-POD\n\tstructs as TREE_ADDRESSABLE to force return in memory.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Propagate TREE_ADDRESSABLE\n\tfrom the original function type.\n\n2013-05-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-target.cc: New source file to handle Target structure.\n\n\t* d-builtins.c (d_bi_init): Remove function.\n\t(d_gcc_type_align): Move to Target::alignsize.\n\t(d_gcc_field_align): Move to Target::fieldalign.\n\t(d_init_builtins): Build va_list type for D frontend.\n\t* d-lang.cc (d_init): Use isLP64 to determine LP64 targets.\n\t(d_add_builtin_version): Set is64bit if target is X86_64.\n\t* d-codegen.cc (convert_for_assignment): Use memset to implement front\n\tend code (struct = 0) here, rather than build an empty constructor.\n\t* d-elem.cc (AssignExp::toElem): Remove handling of (struct = 0) and\n\tcall convert_for_assignment.\n\n2013-05-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-gcc-complex_t.h: Rename to complex_t.h.\n\t* d-gcc-real.cc: Rename to d-longdouble.cc.\n\t* d-gcc-real.h: Rename to longdouble.h\n\t* d-port.cc: New source file to handle Port structure.\n\t* gdc_alloca.h: Remove source.\n\n\t* d-longdouble.cc (real_t): Rename to longdouble.\n\t(longdouble::getnan): Move to Port::nan.\n\t(longdouble::getsnan): Move to Port::snan.\n\t(longdouble::getinfinity): Move to Port::infinity.\n\t(longdouble::isInf): Move to Port::isInfinite.\n\t(longdouble::isNan): Move to Port::isNan.\n\t(longdouble::isSignallingNan): Move to Port::isSignallingNan.\n\t* d-builtins.c (gcc_d_backend_init): Rename to d_backend_init.\n\t(gcc_d_backend_term): Rename to d_backend_term.\n\t(gcc_type_to_d_type): Don't map 128bit integers to D front end.\n\n\t* d-elem.cc (AssignExp::toElem): Remove handling of fillHoles, use\n\tmemset to implement (struct = 0).\n\t(StructLiteralExp::toElem): Handle fillHoles here, creating a\n\ttemporary var that is zero init'd with memset and returned.\n\n2013-05-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::localVar): Rename to build_local_var.\n\t(IRState::exprVar): Rename to create_temporary_var.\n\t(IRState::maybeExprvar): Rename to maybe_temporary_var.\n\t(IRState::pointerIntSum): Rename to build_array_index.\n\t* d-lang.cc (d_handle_target_attribute): New function to handle D\n\ttarget attributes.\n\n2013-05-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-incpath.cc (prefixed_path): Add cpp_GCC_INCLUDE_DIR back in as\n\tsecond method for relocation.\n\t* d-elem.cc (IndexExp::toElem): Fix call to _aaGetX as from\n\tIRState::toElemLvalue.\n\t* d-codegen.cc (IRState::toElemLvalue): Remove function.\n\t(IRState::convertForAssignment): Rename to convert_for_assignment.\n\t(IRState::convertForCondition): Rename to convert_for_condition.\n\t(IRState::checkedIndex): Rename to d_checked_index.\n\t(IRState::boundsCond): Rename to d_bounds_condition.\n\t(IRState::arrayBoundsCheck): Rename to array_bounds_check.\n\t(IRState::assertCall): Rename to d_assert_call.\n\t(IRState::doLineNote): Move to irstate.h.\n\t* d-irstate.cc (IRBase::getLocalContext): Remove function.\n\t* d-decls.cc (VarDeclaration::toSymbol): Build decl lang specific for\n\tdecl to point back to D front end type.\n\t(FuncDeclaration::toSymbol): Likewise.\n\n2013-05-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (AggLayout::finish): Unset TYPE_SIZE before\n\tre-calculating.\n\t* d-ctype.cc (TypeStruct::toCtype): Don't call decl_attribute on the\n\ttype twice.\n\n2013-05-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_gcc_dump_source): Remove function.\n\t(d_post_options): Set flag_excess_precision_cmd as standard.\n\t* d-gcc-real.cc (real_t::convert): Remove function.\n\t(real_t::floatCompare): Remove function.\n\t(real_t::operator): Always perform floating point compilation at the\n\tprecision of the target real mode.\n\t* d-todt.cc (dt_last): Remove function.\n\t(dtlist_to_tree): Rename to dtvector_to_tree.\n\t(dt_cons): Replace TREE_CHAIN implementation for use of CONSTRUCTOR.\n\t(dt_chainon): Likewise.\n\t(dt_container): Likewise.\n\t(dt_container2): Likewise.\n\t(StructInitializer::toDt): Likewise.\n\t(StructLiteralExp::toDt): Likewise.\n\n2013-05-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::convertTo): Replace with d_convert and\n\tconvert_expr.\n\t(IRState::declContext): Replace with d_decl_context.\n\t(IRState::functionNeedsChain): Replace with needs_static_chain.\n\t(IRState::label): Replace with d_build_label.\n\t(IRState::emitTemplates): Move to ObjectFile.\n\t(functionDegenerateClosure): Replace with is_degenerate_closure.\n\t(get_object_method): Assert that function is a method.\n\t(IRState::startCond): Move to IRBase.\n\t(IRState::startElse): Likewise.\n\t(IRState::endCond): Likewise.\n\t(IRState::startLoop): Likewise.\n\t(IRState::continueHere): Likewise.\n\t(IRState::setContinueLabel): Likewise.\n\t(IRState::exitIfFalse): Likewise.\n\t(IRState::endLoop): Likewise.\n\t(IRState::startCase): Likewise.\n\t(IRState::doCase): Likewise.\n\t(IRState::endCase): Likewise.\n\t(IRState::continueLoop): Likewise.\n\t(IRState::exitLoop): Likewise.\n\t(IRState::startTry): Likewise.\n\t(IRState::startCatches): Likewise.\n\t(IRState::startCatch): Likewise.\n\t(IRState::endCatch): Likewise.\n\t(IRState::endCatches): Likewise.\n\t(IRState::startFinally): Likewise.\n\t(IRState::endFinally): Likewise.\n\t(IRState::doReturn): Likewise.\n\t(IRState::doJump): Likewise.\n\t(IRState::pushLabel): Likewise.\n\t(IRState::checkSwitchCase): Likewise.\n\t(IRState::checkGoto): Likewise.\n\t(IRState::checkPreviousGoto): Likewise.\n\n\t* d-elem.cc (CatAssignExp::toElem): Call postblit on appending array of\n\tstructs if required.\n\n2013-05-16  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-incpath.cc (prefixed_path): use cpp_PREFIX instead of\n\tcpp_GCC_INCLUDE_DIR for relocation.\n\n2013-05-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::convertForAssignment): Remove use of\n\tCtorEltMaker wrapper for vec<constructor_elt, va_gc>.\n\t(d_array_value): Likewise.\n\t(build_delegate_cst): Likewise.\n\t(extract_from_method_call): Likewise.\n\t* d-elem.cc (NewExp::toElem): Likewise.\n\t(ArrayLiteralExp::toElem): Likewise.\n\t(AssocArrayLiteralExp::toElem): Likewise.\n\t(StructLiteralExp::toElem): Likewise.\n\t(NullExp::toElem): Likewise.\n\t(VectorExp::toElem): Likewise.\n\t* d-objfile.cc (build_moduleinfo): Likewise.\n\t* d-todt.cc (dt_container): Likewise.\n\t(dt_container2): Likewise.\n\n\t* d-asmstmt.cc (ExtAsmStatement::toIR): Remove use of ListMaker\n\twrapper for tree chaining.\n\t* d-builtins.c (d_bi_builtin_func): Likewise.\n\t(d_bi_builtin_type): Likewise.\n\t(d_gcc_magic_builtins_module): Likewise.\n\t(d_gcc_magic_libbuiltins_module): Likewise.\n\t* d-codegen.cc (build_attributes): Likewise.\n\t(IRState::call): Likewise.\n\t(IRState::buildFrameForFunction): Likewise.\n\t(AggLayout::doFields): Likewise.\n\t(AggLayout::addField): Likewise.\n\t* d-ctype.cc (TypeEnum::toCtype): Likewise.\n\t(TypeFunction::toCtype): Likewise.\n\t* d-todt.cc (dt_container2): Likewise.\n\n\t* d-codegen.cc (IRState::getFrameInfo): Replace with get_frameinfo.\n\t(IRState::buildFrameForFunction): Replace with build_frame_type.\n\t(IRState::isClassNestedInFunction): Replace with d_nested_class.\n\t(IRState::isStructNestedInFunction): Replace with d_nested_struct.\n\t(IRState::getFrameForFunction): Fold into IRState::getFrameForSymbol.\n\t(IRState::getFrameForNestedClass): Likewise.\n\t(IRState::getFrameForNestedStruct): Likewise.\n\n2013-05-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::buildFrameForFunction): Also copy the\n\tparameters of functions with 'in' contracts to a local frame decl.\n\t* d-lang.cc (d_handle_flatten_attribute): New function to handle D\n\tflatten attributes.\n\n2013-05-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::chainLink): Remove function.\n\t(IRState::chainFunc): Remove function.\n\t(IRState::sthis): New member which holds the chain of function.\n\t(IRState::buildChain): Update to use new static chain decl.\n\t(IRState::getFrameInfo): Likewise.\n\t* d-objfile.cc (FuncDeclaration::buildClosure): Likewise.\n\t(FuncDeclaration::toObjFile): Default the function static chain decl\n\tto null unless vthis is given for the function.\n\n2013-05-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_noinline_attribute): New function to handle D\n\tnoinline attributes.\n\t(d_handle_forceinline_attribute): New function to handle D forceinline\n\tattributes.\n\t* d-elem.cc (StructLiteralExp::toElem): Return the struct initialiser\n\tsymbol directly if the tree has already been built.\n\t* d-decls.cc (Dsymbol::toSymbolX): Constify the mangling name to use.\n\n2013-05-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-typinf.cc: New file containing type info routines originally in\n\tthe D Front End.\n\n\t* d-todt.cc (dt_last): New helper function to retrieve last node in a\n\tdt_t tree list.\n\t(dt_cons): New helper function to append nodes to the end of a list.\n\t(dt_chainon): New helper function to concatenate two lists together.\n\t(dt_container): New helper function to build a ctor from a list.\n\t(build_vptr_monitor): New helper function to generate the class\n\tvtable, and put out __vptr and __monitor.\n\tsymbol default values in a class declaration.\n\t(dtlist_to_tree): New helper function to convert a dt_t list into a\n\tconstructor tree.\n\t(Type::toDt): Implement routines for new dt_t format.\n\t(TypeInfoDeclaration::toDt): Likewise.\n\t(Initializer::toDt): Likewise.\n\t(Expression::toDt): Likewise.\n\t(Declaration::toDt): Likewise.\n\n\t* d-objfile.cc (Dsymbol::toObjFile): Update for new dt_t format.\n\t(Module::genmoduleinfo): Likewise.\n\t(Symbol::Symbol): Moved from symbol.cc\n\t(Obj::objmod): Remove abstraction layer.\n\t(Obj::moduleinfo): Renamed to build_moduleinfo.\n\t(obj_tlssections): Renamed to build_tlssections.\n\t(outdata): Renamed to d_finish_symbol.\n\t(check_static_sym): Moved into d_finish_symbol.\n\n\t* d-codegen.cc (d_gcc_emit_local_variable): Remove.\n\n\t* d-decls.cc (Dsymbol::toSymbolX): Update to not call symbol_calloc.\n\t(FuncDeclaration::toThunkSymbol): Likewise.\n\t(ClassDeclaration::toSymbol): Build type as d_unknown_type_node.\n\t(InterfaceDeclaration::toSymbol): Likewise.\n\t(Module::toSymbol): Likewise.\n\t(ClassDeclaration::toVtblSymbol): Update call to toSymbolX.\n\t(AggregateDeclaration::toInitializer): Likewise.\n\t(TypedefDeclaration::toInitializer): Likewise.\n\t(EnumDeclaration::toInitializer): Likewise.\n\n\t* d-ir.cc (CaseStatement::toIR): Don't call static_sym.\n\n\t* d-lang.cc (rtlsym): Remove symbol.\n\t(D_DECL_READONLY_STATIC): Remove macro.\n\t(d_unknown_type_node): New LANG_TYPE node for marking TypeInfo_Class,\n\tInterface, and ModuleInfo types that are of a variable size determined\n\tat compile time.\n\n\t* d-elem.cc (StringExp::toElem): Clean up for new dt_t format.\n\n\t* symbol.cc: Remove file.\n\n2013-05-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::getFrameInfo): Don't create a frame/closure\n\tfor member functions, only required for nested.\n\t* d-elem.cc (Expression::toElemDtor): Call dtors in the correct order.\n\t(DeclarationExp::toElem): Don't call dtor on static, manifest, or\n\textern symbols upon declaration.\n\t(AssignExp::toElem): Only call postblit on lvalues in assignment.\n\t(ArrayLiteralExp::toElem): Always generate literals on heap.\n\n2013-05-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (StructLiteralExp::toElem): Return the default initialiser\n\tsymbol if one exists.\n\t* d-builtins.c (d_gcc_magic_libbuiltins_check): Override the function\n\ttype with the correct built-in function type as defined in backend.\n\n2013-04-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (IdentityExp::toElem): Remove special handling of class,\n\treference and array types.\n\n2013-04-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (maybe_make_temp): Save call expressions so aren't\n\tevaluated more than once.\n\t(d_has_side_effects): Remove check for exceptional class types.\n\n2013-04-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (FuncDeclaration::toSymbol): Harden logic for marking\n\tfunctions pure as in 'has no side effects'.\n\n2013-04-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (FuncDeclaration::toSymbol): Push deferred functions to\n\tFuncDeclaration::deferred.\n\t* d-elem.cc (DelegateExp::toElem): Likewise.\n\t(FuncExp::toElem): Likewise.\n\t* d-objfile.cc (ObjectFile::shouldEmit): Likewise.\n\t(FuncDeclaration::toObjFile): Process all deferred functions in\n\tFuncDeclaration::deferred.\n\t* symbol.cc (Symbol::deferredNestedFuncs): Remove.\n\n2013-04-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (FuncExp::toElem): Defer function literals and lambdas\n\tuntil parent function has finished processing.\n\n2013-04-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::buildChain): Use __frame decl directly when\n\tsetting up the function frame.\n\t(maybe_set_builtin_frontend): Exit early if symbol has no parent.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Defer all nested functions,\n\tnot just templated instances.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Delay processed deferred\n\tnested functions until function has finished being generated.\n\t(ObjectFile::shouldEmit): Don't emit nested functions if the parent\n\tfunction hasn't finished processing.\n\n2013-04-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (maybe_set_builtin_frontend): Merged from\n\tmaybe_set_builtin and maybe_set_libcall.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Use\n\tmaybe_set_builtin_frontend.\n\n2013-03-31  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_init_options): Default module info emission to on.\n\t(d_handle_option): New femit-moduleinfo switch.\n\t* d-objfile.cc (Module::genobjfile): Don't emit module if disabled\n\texplicitly.\n\t* d-builtins.cc (is_intrinsic_module_p): New function to test whether\n\tmodule is core.bitops.\n\t(is_math_module_p): New function to test whether module is std.math or\n\tcore.stdc.math.\n\t(is_builtin_va_arg_p): New function to test whether symbol is\n\tspecially handled va_arg template.\n\t(is_builtin_va_start_p): New function to test whether symbol is\n\tspecially handled va_start template.\n\t* d-codegen.cc (IRState::binding): Replace with bind_expr.\n\t(IRState::mathModule): Replace with std_math_module.\n\t(IRState::mathCoreModule): Replace with core_math_module.\n\t(IRState::intrinsicModule): Replace with std_intrinsic_module.\n\t(IRState::cstdargTemplateDecl): Replace with va_arg_template.\n\t(IRState::stdargTemplateDecl): Replace with va_arg2_template.\n\t(IRState::cstdargStartTemplateDecl): Replace with va_start_template.\n\t(IRState::getLibCallDecl): Replace with get_libcall.\n\t(IRState::maybeSetLibCallDecl): Replace with maybe_set_libcall.\n\t(IRState::libCall): Replace with build_libcall.\n\t(IRState::maybeSetUpBuiltin): Replace with maybe_set_builtin.\n\t(IRState::Intrinsic): Move enum out of IRState.\n\n2013-03-30  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::darrayPtrRef): Replace with d_array_ptr.\n\t(IRState::darrayLenRef): Replace with d_array_length.\n\t(IRState::darrayVal): Replace with d_array_value.\n\t(IRState::darrayString): Replace with d_array_string.\n\t(IRState::arrayLength): Replace with get_array_length.\n\t(get_object_method): Remove dependancy on irs parameter.\n\t* d-lang.cc (d_init): Use static bool std_inc to determine whether to\n\tinclude standard module paths.\n\t(d_post_options): Canonicalize the input filename.\n\t(d_parse_file): Correctly catch cases where input file is stdin.\n\n2013-03-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::getFrameInfo) Create a custom static chain for\n\tall nested functions.\n\t* d-gcc-includes.h: Rename to d-system.h\n\n2013-03-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.c (d_bi_init): Set REALPAD to be TYPE_PRECISION of\n\tlong_double_type_node.\n\t* d-codegen.cc (IRState::twoFieldType): Replace with\n\tbuild_two_field_type.\n\t(IRState::arrayOpNotImplemented): Replace with unhandled_arrayop_p.\n\t(IRState::delegateMethodRef): Replace with delegate_method.\n\t(IRState::delegateObjectRef): Replace with delegate_object.\n\t(IRState::delegateVal): Replace with build_delegate_cst.\n\t(IRState::methodCallExpr): Replace with build_method_call.\n\t(IRState::extractMethodCallExpr): Replace with\n\textract_from_method_call.\n\t(IRState::objectInstanceMethod): Replace with get_object_method.\n\t(IRState::twoFieldCtor): Remove.\n\t(IRState::call): Assert that if calling a normal FUNCTION_TYPE,\n\t'object' is not set.\n\t* d-ctype.cc (TypeDelegate::toCtype): Build a METHOD_TYPE for the .func\n\tfield type in delegates.\n\t* d-lang.h (D_IS_METHOD_CALL_EXPR): Rename to D_METHOD_CALL_EXPR.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Remove assert for chain\n\tfunction.\n\n2013-03-20  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-codegen.cc (IRState::objectInstanceMethod): Recursively check\n\tfor TOKsuper / TOKdottype. Do not ignore CastExp.\n\t* d-elem.cc (IdentityExp::toElem): Ignore padding in bitwise floating\n\tpoint comparisons.\n\t* testsuite: Cleanup. Remove invalid tests, adjust tests, etc. \n\n2013-03-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::objectInstanceMethod): Get function pointer\n\toff function TREE_TYPE.\n\t(build_deref): Handle cases where expression to dereference is an\n\taddress expression.\n\t(modify_expr): New function overload to set return type directly.\n\t* d-elem.cc (CatAssignExp::toElem): Use new modify_expr.\n\t(AssignExp::toElem): Likewise.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Don't build a method type for\n\tnested functions / delegates.  Just add on the hidden 'this' pointer\n\tcontaining the custom static chain/closure object.\n\n\t* d-codegen.cc (GlobalValues): Replace with current_module,\n\tcurrent_irs, object_file.\n\t(IRState::getFuncType): Replace with get_function_type.\n\t(IRState::isCallByAlias): Replace with call_by_alias_p.\n\t(IRState::isFuncType): Replace with function_type_p.\n\t(IRState::doExp): Remove.\n\n\t* d-asmstmt.cc (ExtAsmStatement::syntaxCopy): Use arraySyntaxCopy to\n\tcopy front end expressions.\n\n\t* d-codegen.cc (AssignExp::toElem): Call _d_arrayassign / _d_arrayctor\n\twhen assigning arrays of structs.\n\n2013-03-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::realPart): Replace with real_part.\n\t(IRState::imagPart): Replace with imaginary_part.\n\t(IRState::integerConstant): Replace with build_integer_cst.\n\t(IRState::floatConstant): Replace with build_float_cst.\n\t(IRState::hwi2toli): Replace with cst_to_hwi.\n\t(IRState::addressOf): Replace with build_address.\n\t(IRState::markAddressable): Replace with d_mark_addressable.\n\t(IRState::markUsed): Replace with d_mark_used.\n\t(IRState::markRead): Replace with d_mark_read.\n\t(IRState::indirect): Replace with indirect_ref.\n\t(IRState::pvoidOkay): Replace with void_okay_p.\n\t(IRState::maybeCompound): Replace with maybe_compound_expr.\n\t(IRState::maybeVoidCompound): Replace with maybe_vcompound_expr.\n\t(IRState::isErrorMark): Replace with error_mark_p.\n\t(IRState::getTargetSizeConst): Replace with tree_to_hwi.\n\t(IRState::modify): Replace with modify_expr.\n\t(IRState::vmodify): Replace with vmodify_expr.\n\t(IRState::vinit): Replace with build_vinit.\n\t(IRState::nop): Replace with build_nop.\n\t(IRState::vconvert): Replace with build_vconvert.\n\t(IRState::boolOp): Replace with build_boolop.\n\t(IRState::compound): Replace with compound_expr.\n\t(IRState::voidCompound): Replace with vcompound_expr.\n\t(IRState::component): Replace with component_ref.\n\t(IRState::errorMark): Replace with error_mark.\n\t(IRState::typesSame): Replace with d_types_same.\n\t(IRState::typesCompatible): Replace with d_types_compatible.\n\t(IRState::getDType): Replace with build_dtype.\n\t(IRState::getObjectType): Replace with build_object_type.\n\t(IRState::isDeclarationReferenceType): Replace with decl_reference_p.\n\t(IRState::trueDeclarationType): Replace with declaration_type.\n\t(IRState::isArgumentReferenceType): Replace with arg_reference_p.\n\t(IRState::trueArgumentType): Replace with type_passed_as.\n\t(IRState::arrayType): Replace with d_array_type.\n\t(IRState::addTypeAttribute): Replace with insert_type_attributes.\n\t(IRState::addDeclAttribute): Replace with insert_decl_attributes.\n\t(IRState::attributes): Replace with build_attributes.\n\t(IRState::addTypeModifiers): Replace with insert_type_modifiers.\n\t(IRState::maybeMakeTemp): Replace with maybe_make_temp.\n\t(IRState::isFreeOfSideEffects): Replace with d_has_side_effects.\n\t(IRState::pointerOffsetOp): Replace with build_offset_op.\n\t(IRState::pointerOffset): Replace with build_offset.\n\t(IRState::buildCall): Replace with d_build_call.\n\t(IRState::exceptionObject): Replace with build_exception_object.\n\n2013-03-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-asmstmt.cc (d_build_asm_stmt): Remove.\n\t(ExtAsmStatement::ExtAsmStatement): Update to match renamed members.\n\t(ExtAsmStatement::syntaxCopy): Likewise.\n\t(ExtAsmStatement::semantic): Likewise.\n\t(ExtAsmStatement::toCBuffer): Likewise.\n\t(ExtAsmStatement::comeFrom): New.\n\t(ExtAsmStatement::blockExit): Don't error if must not throw.\n\t(naturalString): Remove.\n\t(ExtAsmStatement::toIR): Inline IRState::doAsm implementation.\n\t* d-codegen.cc (IRState::doAsm): Remove.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Don't generate 'naked'\n\tattribute.\n\t(binfo_for): Move into d-decls.cc.\n\t(intfc_binfo_for): Likewise.\n\t(ClassDeclaration::toDebug): Likewise.\n\t(EnumDeclaration::toDebug): Likewise.\n\t(TypedefDeclaration::toDebug): Likewise.\n\t(StructDeclaration::toDebug): Likewise.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Move into d-objfile.cc.\n\t(FuncDeclaration::buildClosure): Likewise.\n\t(Module::genobjfile): Likewise.\n\t* d-glue.cc: Remove file.\n\n2013-03-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-ir.cc (SynchronizedStatement::toIR): Remove implementation as is\n\tnow handled by the frontend.\n\n2013-03-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (IRState::maybeExpandSpecialCall): Handle ref argptr\n\targuments.\n\n2013-03-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.c (handle_alias_attribute): New function to handle\n\tinternal 'alias' attribute.\n\t(handle_weakref_attribute): New function to handle internal 'weakref'\n\tattribute.\n\t* d-objfile.cc (ObjectFile::outputThunk): Define thunks to external\n\tsymbols as weakref, alias\n\n2013-03-12  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* patch-versym-os-4.8.x (mingw32.h): Fix typo\n\t* patch-versym-cpu-4.8.x (mips.h): Fix typo\n\tUpdate version symbols to latest dlang specification.\n\n2013-03-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (FuncDeclaration::toSymbol): Delay setting TREE_TYPE as\n\tfunction type could be hidden in a nested function not yet built.\n\t* d-codegen.cc (IRState::findThis): Don't get 'this' from outer\n\tfunction if it's a closure type.  This has already been handled by\n\tIRState::getFrameForSymbol.\n\t(IRState::buildChain): Give frame decl debug name '__frame'.\n\tAlways set '__chain' link field.\n\t(IRState::getFrameInfo): Don't build a frame for all nested functions.\n\tSearch through nested aggregates for static chain in outer functions.\n\t* d-codegen.h (IRState::useParentChain): Remove.\n\t* d-glue.cc (FuncDeclaration::toObjFile): Don't call useParentChain.\n\tDon't create a local var for the chain link for a function.\n\t(FuncDeclaration::buildClosure): Always set '__chain' link field.\n\n2013-03-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_gcc_force_templates): Only check for emitting\n\ttemplates as private.\n\t* d-lang.cc (d_handle_option): Remove -femit-templates= option.\n\t* d-objfile.cc (ObjectFile::makeDeclOneOnly): Fix code logic so\n\tfallback method could be reached.\n\t* d-objfile.h (TEall, TEauto): Remove.\n\n2013-03-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-ir.cc (ReturnStatement::toIR): Don't call postblit on return.\n\t* d-codegen.cc (IRState::trueDeclarationType): Don't set\n\tD_TYPE_ADDRESSABLE.\n\t(IRState::makeTemp): Remove.\n\t(IRState::maybeMakeTemp): Copy makeTemp into function.\n\t* d-glue.cc (d_genericize): Remove D_TYPE_ADDRESSABLE handling.\n\t* d-lang.h (D_TYPE_ADDRESSABLE): Remove macro.\n\n2013-03-04  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-ctype.cc (Type::toCtype): Always call gen.addTypeModifiers to\n\tmake sure TYPE_MAIN_VARIANT is set. Reuse tree from unqualified\n\tvariant for that. Also cache the resulting qualified tree.\n\t(TypeTypedef::toCtype): Likewise.\n\t(TypeEnum::toCtype): Likewise.\n\t(TypeStruct::toCtype): Likewise.\n\t(TypeFunction::toCtype): Likewise.\n\t(TypeVector::toCtype): Likewise.\n\t(TypeSArray::toCtype): Likewise.\n\t(TypeDArray::toCtype): Likewise.\n\t(TypeAArray::toCtype): Likewise.\n\t(TypeDelegate::toCtype): Likewise.\n\t(TypeClass::toCtype): Likewise.\n\t* d-objfile.cc (ObjectFile::giveDeclUniqueName): Make sure DECL_NAME is set\n\n2013-03-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (VarDeclaration::toSymbol): Remove use of c_ident.\n\t(FuncDeclaration::toSymbol): Likewise.\n\t* d-builtins.c (handle_noreturn_attribute): Assert that this is only\n\tused for internal purposes.\n\t(handle_const_attribute): Likewise.\n\t(handle_malloc_attribute): Likewise.\n\t(handle_pure_attribute): Likewise.\n\t(handle_nonnull_attribute): Likewise.\n\t(handle_nothrow_attribute): Likewise.\n\t(handle_sentinel_attribute): Likewise.\n\t(handle_transaction_pure_attribute): Likewise.\n\t(handle_returns_twice_attribute): Likewise.\n\t* d-glue.cc (FuncDeclaration::toObjFile): Result variables have no\n\tdefault initialiser.\n\t* d-codegen.cc (IRState::emitLocalVar): Add in assert that the local\n\tvariable has no initialiser if called with no_init = true.\n\t(IRState::getLibCallDecl): Mark exceptional library functions as\n\tnoreturn.\n\t(IRState::attributes): Gracefully handle @attribute, and\n\t@attribute(null).\n\n2013-02-28  Jernej Krempus  <jkrempus@gmail.com>\n\n\t* d-builtins.c (d_attribute_table): Renamed it to\n\td_builtins_attribute_table.\n\t* d-lang.cc (d_attribute_table): Added an empty table\n\t* d-lang.cc (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Defined it as\n\td_builtins_attribute_table.\n\t* d-lang.h (d_builtins_attribute_table): Added a declaration.\n\t* d-codegen.cc (IRState::attributes): Changed it so it goes through\n\tin_attrs and looks for any @gcc.attribute.attribute(\"attr_name\").\n\t* d-objfile.cc (ObjectFile::setupSymbolStorage): Pass userAttributes\n\tinstead of attributes in all calls to IRState::attributes.\n\t* d-ctype.cc (TypeTypedef::toCtype): Likewise.\n\t(TypeEnum::toCtype): Likewise.\n\t(TypeStruct::toCtype): Likewise.\n\t(TypeClass::toCtype): Likewise.\n\t* libphobos/libdruntime/gcc/attribute.d: New file.\n\n2013-02-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Remove OPT_fdeprecated and\n\tOPT_Wsign_compare, add handling for OPT_Wdeprecated.\n\t(d_post_options): Handle Wdeprecated and Werror switch combination.\n\n2013-02-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (ArrayScope::ArrayScope): Don't setup length var if its\n\tvalue is known at compile time.\n\t(ArrayScope::setArrayExp): Likewise.\n\t* d-decls.cc (uniqueName): Remove function.\n\t(VarDeclaration::toSymbol): Set decl assembler name directly.\n\t(FuncDeclaration::toSymbol): Likewise.\n\n2013-02-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (GDC_EXTENDED_ASM_SYNTAX): Remove macro.\n\n2013-02-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.h (D_DECL_IS_CONTRACT): Remove macro.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Likewise.\n\n2013-02-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_gcc_is_target_win32): Remove.\n\t(d_add_builtin_version): New function to handle define_builtin\n\tcallback from backend.\n\t* d-codegen.cc (IRState::maybeExpandSpecialCall): Remove intrinsic bt.\n\n\t* d-builtins.c: Merge with d-builtins2.cc.\n\t* d-builtins2.cc: Remove.\n\n2013-02-07  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-lang.cc (d_init): Use gcc's config system for predefined OS versions.\n\t* setup-gcc.sh: Likewise.\n\t* target-ver-syms.sh: Likewise.\n\n2013-02-05  Iain Buclaw  <ibuclaw@ubuntu.com>\n\n\t* d-builtins2.cc (gcc_type_to_d_type): Remove STRUCTTHISREF condition.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Likewise.\n\t* d-elem.cc (ThisExp::toElem): Likewise.\n\t* d-ctype.cc (TypeSArray::toCtype): Remove SARRAYVALUE condition.\n\t* d-codegen.cc (IRState::isDeclarationReferenceType): Likewise.\n\t(IRState::isArgumentReferenceType): Likewise.\n\n2013-02-01  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-lang.cc (d_init): Use gcc's config system for predefined CPU versions.\n\t(d_init): Fix definition of D_LP64 version.\n\t* setup-gcc.sh: Likewise.\n\t* target-ver-syms.sh: Likewise.\n\n\f\nCopyright (C) 2013 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2014",
    "content": "2014-12-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (check_gdc_parallelize): Update for testsuite changes.\n\t* d-convert.cc (d_convert_basic): Avoid stack overflow when converting\n\tfrom pointer to integer.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Emit correct frame\n\tinformation for closures rather than generic void pointers.\n\n2014-11-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (CatExp::toElem): Split dynamic arrays when passing as\n\tvarargs to arraycatT and arraycatnT.\n\n2014-11-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_vthis): Handle getting static chain for nested\n\ttemplated structs.\n\n2014-09-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (ArrayLiteralExp::toElem): Remove special handling for\n\timmutable arrays.\n\n2014-08-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-longdouble.cc (longdouble::formatHex): Convert buffer to uppercase\n\tfor use in mangling templates.\n\n2014-07-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (NewExp::toElem): Check for opaque structs before\n\tcontinuing to generate the new expression.\n\n\t* d-lang.h.cc (d_vtbl_ptr_type_node): Renamed to vtbl_ptr_type_node.\n\t(d_boolean_type_node): Renamed to bool_type_node.\n\t(d_char_type_node): Renamed to char8_type_node.\n\t(d_wchar_type_node): Renamed to char16_type_node.\n\t(d_dchar_type_node): Renamed to char32_type_node.\n\t(d_ifloat_type_node): Renamed to ifloat_type_node.\n\t(d_idouble_type_node): Renamed to idouble_type_node.\n\t(d_ireal_type_node): Renamed to ireal_type_node.\n\t(byte_type_node, ubyte_type_node): New macros for fixed integral\n\ttypes in D.\n\t(short_type_node, ushort_type_node): Likewise.\n\t(int_type_node, uint_type_node): Likewise.\n\t(long_type_node, ulong_type_node): Likewise.\n\t(cent_type_node, ucent_type_node): Likewise.\n\t* d-builtins.c (d_init_builtins): Initialise all D specific type nodes.\n\t* d-codegen.cc (d_bounds_condition): Use D-specific type macros instead\n\tof backend C types.\n\t(layout_aggregate_type): Likewise.\n\t(build_integer_cst): Likewise.\n\t(build_boolop): Likewise.\n\t* d-convert.cc (d_build_truthvalue_op): Likewise.\n\t(d_truthvalue_conversion): Likewise.\n\t* d-ctype.cc (Type::toCtype): Likewise.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Likewise.\n\t* d-elem.cc (CmpExp::toElem): Likewise.\n\t(OrOrExp::toElem): Likewise.\n\t(NotExp::toElem): Likewise.\n\t* d-lang.cc (d_type_for_mode): Likewise.\n\t(d_type_for_size): Likewise.\n\t(d_signed_or_unsigned_type): Likewise.\n\n2014-07-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-ctype.cc (TypeFunction::toCtype): Only check for ref return for\n\tfunctions returning non-void.\n\n2014-07-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (output_declaration_p): Don't emit any declarations from\n\tthe gcc.attribute module.\n\t(StructDeclaration::toObjFile): Call output_declaration_p.\n\t* d-glue.cc (verror): Only call vasprintf on the initial format string.\n\n2014-07-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_init_options_struct): Set flag_wrapv as on by default.\n\n2014-07-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (NewExp::toElem): Don't initialise a new'd struct at the\n\tcaller.  The callee ensures this is done.\n\n2014-07-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (d_finish_symbol): Always set TREE_STATIC for symbols\n\tbeing sent to the backend here.\n\n2014-07-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (d_finish_symbol): Don't set DECL_INITIAL if the\n\tinitialiser is all zeros.\n\n2014-07-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (lookup_ctype_name): Remove function.\n\t(string_type_node): Move to static declaration from d_global_trees.\n\t(const_string_type_node): Likewise.\n\t(wint_type_node): Likewise.\n\t(intmax_type_node): Likewise.\n\t(uintmax_type_node): Likewise.\n\t(signed_size_type_node): Likewise.\n\t(d_init_builtins): Update.\n\t* d-lang.cc (d_type_for_mode): Return only fixed size types.\n\t(d_type_for_size): Likewise.\n\t(d_signed_or_unsigned_type): Likewise.\n\t(d_unsigned_type): Remove duplicated code from\n\td_signed_or_unsigned_type.\n\t(d_signed_type): Likewise.\n\n2014-07-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (finish_thunk): Use set_decl_section_name, copy the\n\timplicit section flag.\n\t(setup_symbol_storage): Use decl_default_tls_model.\n\n2014-06-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.h (d_types_compatible): Remove function.\n\t(d_types_same): Use more conservative approach to type equality.\n\t* d-codegen.cc (get_libcall): Allow backend to be able to optimise\n\tclosure memory allocations.\n\t(convert_for_assignment): Use d_types_same.\n\t* d-elem.cc (CatExp::toElem): Likewise.\n\t(BinExp::toElemBin): Likewise.\n\t(CatAssignExp::toElem): Likewise.\n\t(StructLiteralExp::toElem): Likewise.\n\n2014-06-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (CondExp::toElem): Handle void type condition expressions.\n\t(AssignExp::toElem): Use ismemset to test for initialising arrays with\n\ta single value.\n\t(StructLiteralExp::toElem): Build static initialiser if a symbol was\n\tcreated by the front-end.\n\t* d-codegen.h (d_types_compatible): First check equality of types, then\n\timplicit compatibility.\n\t* d-convert.cc (d_default_conversion): Remove function, fold\n\timplementation into...\n\t(d_truthvalue_conversion): ... here.\n\n2014-06-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-convert.cc (d_scalar_conversion): Remove function.\n\t(d_build_truthvalue_op): Update.\n\t(d_truthvalue_conversion): Update.\n\n\t* d-codegen.cc (get_frame_for_symbol): Remove glue-specific error\n\tmessages and refactor.\n\t(build_vthis): Likewise.\n\t(get_framedecl): Likewise.\n\t* d-elem.cc (AssignExp::toElem): Update call to build_vthis.\n\t(NewExp::toElem): Likewise.\n\t(StructLiteralExp::toElem): Likewise.\n\t* d-objfile.cc (Dsymbol::toObjFile): Fix build warning.\n\n\t* d-codegen.cc (d_decl_context): Always return parent context for\n\tfunctions nested in functions.\n\t(is_degenerate_closure): Remove function.\n\t(needs_static_chain): Remove function.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Remove workaround for cgraph\n\tnesting structure, saving the original context decl.\n\t* d-lang.h (D_DECL_STATIC_CHAIN): Remove macro.\n\t* d-objfile.cc (Symbol::Symbol): Remove ScontextDecl field.\n\t(FuncDeclaration::toObjFile): Remove workaround for cgraph nesting\n\tstructure, restoring the original context decl.  Delay building the\n\tcgraph node until...\n\t(d_finish_function): ... here, where the function is unnested.\n\n2014-06-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (d_finish_function): Update the callgraph to reflect\n\tunnesting of the function, as unravelling has already been handled by\n\tthe frontend.  Do not delay calling cgraph_finalize_function.\n\n2014-06-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (d_comdat_group): Return a decl.\n\t* d-decl.cc (FuncDeclaration::toThunkSymbol): Don't set comdat group.\n\t* d-elem.cc (EqualExp::toElem): Always store temporaries when comparing\n\ttwo dynamic arrays.\n\n2014-06-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (TypeInfoDeclaration::toSymbol): Add assert that Error\n\ttypes never reach the backend.\n\t* d-typinf.cc (Type::getTypeInfo): Likewise.\n\n2014-06-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* dfrontend: Update to D front-end version 2.065.\n\n\t* d-codegen.cc (d_build_call): Evaluate side effects of the object\n\tparameter for method or delegate calls before passing.\n\t(libcall_ids): Rename _d_array_bounds to _d_arraybounds.\n\t(get_libcall): Update parameter types for _d_arraycopy.\n\t(finish_aggregate_type): Update for frontend UDA changes.\n\t* d-ctype.cc (TypeTypedef::toCtype): Update for frontend UDA changes.\n\t(TypeEnum::toCtype): Likewise.\n\t(TypeStruct::toCtype): Likewise.\n\t(TypeClass::toCtype): Likewise.\n\t* d-elem.cc (BoolExp::toElem): New function.\n\t* d-lang.cc (rootmodule): New declaration for frontend entrypoint\n\tchanges.\n\t(genCmain): Update for frontend entrypoint changes.\n\t(d_handle_option): Don't duplicate memory for argument values.\n\t(d_parse_file): Don't duplicate memory for source filenames.\n\t* d-objfile.cc (VarDeclaration::toObjFile): Don't emit instantiated\n\tmanifest constants to debug.\n\t(TemplateInstance::toObjFile): Update for frontend changes.\n\t(output_template_p): Remove function.\n\t(output_declaration_p): Update for frontend changes.\n\t(setup_symbol_storage): Update for frontend UDA changes.\n\t* d-target.cc (Target::reverseCppOverloads): New declaration.\n\t* d-typinf.cc (Type::getInternalTypeInfo): Update for frontend changes.\n\t(Type::getTypeInfo, Type::getTypeInfoDeclaration): Likewise.\n\t(TypeTypedef::getTypeInfoDeclaration): Likewise.\n\t(TypePointer::getTypeInfoDeclaration): Likewise.\n\t(TypeDArray::getTypeInfoDeclaration): Likewise.\n\t(TypeSArray::getTypeInfoDeclaration): Likewise.\n\t(TypeAArray::getTypeInfoDeclaration): Likewise.\n\t(TypeStruct::getTypeInfoDeclaration): Likewise.\n\t(TypeClass::getTypeInfoDeclaration): Likewise.\n\t(TypeVector::getTypeInfoDeclaration): Likewise.\n\t(TypeEnum::getTypeInfoDeclaration): Likewise.\n\t(TypeFunction::getTypeInfoDeclaration): Likewise.\n\t(TypeDelegate::getTypeInfoDeclaration): Likewise.\n\t(TypeTuple::getTypeInfoDeclaration): Likewise.\n\t(createTypeInfoArray): Likewise.\n\n\t* d-intrinsics.def: New file for declaring D intrinsics.\n\n\t* d-builtins.cc (std_intrinsic_module, std_math_module)\n\t(core_math_module, va_arg_template, va_arg2_template)\n\t(va_start_template): Remove declarations.\n\t(is_intrinsic_module_p, is_math_module_p, is_builtin_va_arg_p)\n\t(is_builtin_va_start_p, d_gcc_magic_stdarg_check)\n\t(d_gcc_magic_stdarg_module): Remove functions.\n\t(d_gcc_magic_builtins_module): Rename to d_build_builtins_module.\n\t(d_gcc_magic_libbuiltins_module): Rename to maybe_set_builtin.\n\t(d_gcc_magic_libbuiltins_check): Rename to maybe_set_builtin_1.\n\t(gcc_type_to_d_type): Rename to build_dtype.\n\t(gcc_cst_to_d_expr): Rename to build_expression.\n\t(d_gcc_eval_builtin): Remove function.\n\t(eval_builtin): Moved to...\n\t* d-glue.cc (eval_builtin): New function, updated for glue changes.\n\t(FuncDeclaration::isBuiltin): New function to determine whether a\n\tgiven function symbol is a compiler intrinsic.\n\t* d-codegen.cc (maybe_expand_builtin): Rename to expand_intrinsic.\n\t(Intrinsic): Remove enum declaration, replaced with...\n\t(intrinsic_code): New enum for compiler intrinsics.\n\t(intrinsic_decls): New declaration for store intrinsic information.\n\t(expand_intrinsic_bt): Update signature.\n\t(maybe_set_intrinsic): New function to replace...\n\t(maybe_set_builtin_frontend): Remove function.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Update for glue changes.\n\n\t* d-builtins.c: Rename to d-builtins.cc\n\t* d-gt.c: Rename to d-gt.cc\n\t* d-spec.c: Rename to d-spec.cc\n\n\t* d-toir.cc: Renamed to toir.cc\n\t* toir.cc: New file, re-implement toIR methods as a visitor.\n\n\t* d-codegen.cc (insert_type_modifiers): Handle MODwildconst modifiers.\n\t(build_ir): New function.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Use build_ir to walk\n\tfront-end IR trees.\n\t* d-decls.cc (VarDeclaration::toSymbol): Mark compiler temporaries as\n\tDECL_ARTIFICIAL.\n\t(ClassDeclaration::toVtblSymbol): Update for front-end changes.\n\t* d-builtins.c (gcc_type_to_d_type): Likewise.\n\t* d-elem.cc (CatAssignExp::toElem): Likewise.\n\t(ArrayLiteralExp::toElem): Likewise.\n\t(BoolExp::toElem): Remove function.\n\t(ComExp::toElem): Assert that unhandled array operations no longer\n\tleak from the front-end.\n\t(NegExp::toElem): Likewise.\n\t* d-glue.cc (Global::init): Initialise new member run_noext.\n\t* d-incpath (add_import_path): Update for front-end changes.\n\t* d-lang.cc (d_add_builtin_version): Likewise.\n\t* d-todt.cc (StructDeclaration::toDt): Likewise.\n\t* d-toir.cc (LabelStatement::toIR): Don't delete forward references.\n\t(GotoStatement::toIR): Assert that undefined labels no longer leak\n\tfrom the front-end.\n\n2014-05-31  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-todt.cc (dt_container): Properly handle zero length static arrays.\n\t* d-codegen.h (build_dtype): Rename to lang_dtype.\n\t(build_ddecl): Rename to lang_ddecl.\n\n2014-05-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.c (d_init_builtins): Use void_node instead of\n\td_void_zero_node.\n\t* d-lang.h (d_void_zero_node): Remove.\n\t* d-elem.cc (AndAndExp::toElem): Adjust.\n\t(OrOrExp::toElem): Likewise.\n\t(AssertExp::toElem): Likewise.\n\t(TupleExp::toElem): Likewise.\n\n\t* d-builtins.c (d_init_builtins): Use null_pointer_node instead of\n\td_null_pointer.\n\t* d-lang.h (d_null_pointer): Remove.\n\t* d-codegen.cc (convert_expr): Adjust.\n\t(get_frame_for_symbol): Likewise.\n\t(build_vthis): Likewise.\n\t(get_framedecl): Likewise.\n\t* d-elem.cc (DeleteExp::toElem): Likewise.\n\t(CallExp::toElem): Likewise.\n\t(AssertExp::toElem): Likewise.\n\t(NewExp::toElem): Likewise.\n\t(ArrayLiteralExp::toElem): Likewise.\n\t(NullExp::toElem): Likewise.\n\t* d-objfile.cc (ClassDeclaration::toObjFile): Likewise.\n\t(InterfaceDeclaration::toObjFile): Likewise.\n\t(FuncDeclaration::toObjFile): Likewise.\n\t(build_moduleinfo): Likewise.\n\t* d-todt.cc (TypeInfoTypedefDeclaration::toDt): Likewise.\n\t(TypeInfoEnumDeclaration::toDt): Likewise.\n\t(TypeInfoStructDeclaration::toDt): Likewise.\n\n2014-05-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-longdouble.cc (longdouble::from_shwi): Rename to from_int.\n\t(longdouble::from_uhwi): Rename to from_uint.\n\t(longdouble::to_shwi): Rename to to_int.\n\t(longdouble::to_uhwi): Rename to to_uint.\n\t(longdouble::set): Adjust.\n\t(longdouble::operator): Likewise.\n\n\t* d-lang.cc (alloc_binding_level): Adjust.\n\t(build_d_type_lang_specific): Likewise.\n\t(build_d_decl_lang_specific): Likewise.\n\t* d-lang.h (lang_type): Don't use variable_size gty attribute.\n\t* d-codegen.cc (cst_to_hwi): Remove function.\n\t* d-codegen.cc (tree_to_hwi): Remove function.\n\t* d-builtins.c (gcc_type_to_d_type): Adjust.\n\t(gcc_cst_to_d_expr): Likewise.\n\t* d-convert.cc (d_truthvalue_conversion): Use integer_zerop.\n\t(get_nonnull_operand): Use tree_fits_uhwi_p.\n\t* d-longdouble.cc (longdouble::from_int): Adjust.\n\t(longdouble::from_uint): Likewise.\n\t(longdouble::to_int): Likewise.\n\n2014-04-30  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-lang.cc (d_init): Define GNU_SEH_Exceptions and\n\tGNU_DWARF2_Exceptions versions.\n\n2014-04-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_init_options): Default deprecation warnings to off.\n\t* d-ctype.cc (TypeDelegate::toCtype): Propogate TREE_ADDRESSABLE from\n\tthe base function to the delegatised copy.\n\n2014-04-15  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-lang.cc (d_handle_noclone_attribute): New function to handle\n\tnoclone attribute. noclone is required by the naked attribute.\n\t* d-elem.cc (SymbolExp::toElem): Convert symbols to the expression\n\ttype.\n\n2014-04-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (get_frameinfo): Don't copy the node for frame record.\n\t* d-irstate.cc (IRState::endCatches): Rebuild the STATEMENT_LIST of\n\tcatches in a TRY_CATCH_EXPR if it gets optimised away by\n\tIRState::popStatement.\n\t* d-codegen.cc (d_attribute_p): Provide access to target attributes.\n\n2014-03-31  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (error_mark_p): Removed function, replace uses with\n\terror_operand_p.\n\t(error_mark): Removed function, replace uses with error_mark_node.\n\t* d-ctype.cc (Type::toCtype): Return d_unknown_type_node for frontend\n\terror types.\n\t* d-objfile.cc (VarDeclaration::toObjFile): Don't build CONST_DECLs for\n\tnon-scalar manifests.\n\n2014-03-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (Dsymbol::toImport): Prevent GC from collecting\n\tIMPORTED_DECL nodes whilst front-end compilation in progress.\n\n2014-03-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (AggLayout::visit): Rename to layout_aggregate_type.\n\t(AggLayout::doFields, AggLayout::doInterfaces): Remove function and\n\tmove implementation into layout_aggregate_type.\n\t(AggLayout::addField): Rename to insert_aggregate_field.\n\t(AggLayout::finish): Rename to finish_aggregate_type.\n\t* d-codegen.h (AggLayout): Update definition.\n\t* d-ctype.cc (TypeStruct::toCtype): Update for glue changes.\n\t(TypeFunction::toCtype): Fix ICE on generic function types.\n\t(TypeClass::toCtype): Move generation of vptr and monitor fields into\n\tlayout_aggregate_type.  Moved generation of TYPE_METHODS from ...\n\t* d-objfile.cc (FuncDeclaration::toObjFile): ... here into\n\tTypeClass::toCtype.  Don't build up TYPE_METHODS on a per-function\n\tbasis, generate the entire vtable.\n\n2014-03-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (Dsymbol::toSymbolX): Set the symbol prettyIdent.\n\t(Dsymbol::toImport): Emit packages as their fully qualified names.\n\t(ClassDeclaration::toSymbol): Distinguish between the classinfo\n\tassembler and decl name.\n\t(InterfaceDeclaration::toSymbol): Likewise for interface symbol.\n\t(Module::toSymbol): Likewise for moduleinfo symbol.\n\t(ClassDeclaration::toVtblSymbol): Likewise for class vtable symbol.\n\t(AggregateDeclaration::toInitializer)\n\t(TypedefDeclaration::toInitializer, EnumDeclaration::toInitializer):\n\tLikewise for default initialisers.\n\t* d-objfile.cc (Module::genobjfile): Don't set-up moduleinfo symbol\n\tstorage twice.\n\n2014-03-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_decl_context): Fix null pointer dereference.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Don't override the setting\n\tof DECL_CONTEXT on the declaration here.\n\t(d_finish_symbol): Likewise.\n\t* d-objfile.cc (VarDeclaration::toObjFile): Move the generation of\n\tmanifest constants to ...\n\t* d-decls.cc (VarDeclaration::toSymbol): ... here, and emit them as\n\tCONST_DECLs.  Set the DECL_CONTEXT for all variable symbols.\n\n\t* d-builtins.cc (d_gcc_magic_builtins_module): Don't store compiler\n\tgenerated builtins in Symbol::isym, use Symbol::csym instead.\n\t(d_gcc_magic_libbuiltins_check): Likewise.\n\t* d-codegen.cc (d_decl_context): Return the imported symbol tree of\n\tmodules where the NAMESPACE_DECL is now stored.\n\t(d_build_module): Remove function.  Move implementation to ...\n\t* d-decls.cc (Dsymbol::toImport): ... here.  Build an IMPORTED_DECL for\n\tall imported declarations.\n\t(FuncDeclaration::toSymbol): Remove special handling of Symbol::isym.\n\t(Module::toSymbol): Remove call to d_build_module.\n\t* d-objfile.cc (Dsymbol::toObjFile): Handle emission of IMPORTED_DECL\n\tsymbols to debug.\n\n2014-03-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_attributes): Ensure D-specific attributes have\n\ttheir value interpreted through CTFE.\n\n2014-02-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_build_module): Update signature to accept a Loc\n\tlocation to the module declaration.\n\t* d-decls.cc (Module::toSymbol): Update call to d_build_module.\n\tSet TREE_PUBLIC/DECL_EXTERNAL to distingush which modules are being\n\tcompiled.\n\t* d-objfile.cc (Dsymbol::toObjFile): Handle Import symbols, and emit\n\tdebug information for imported modules.\n\t(ImportStatement::toIR): Likewise.\n\t(set_input_location): New function to implement the equivalent of\n\tset_decl_location, but instead sets input_location.\n\n2014-02-19  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-objfile.cc (build_call_function): Call set_input_location\n\tto set debug info correctly\n\n2014-02-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (VarDeclaration::toObjFile): Remove toplevel check.\n\tDECL_CONTEXT is never set on manifest constants.\n\t(d_finish_compilation): Remove fancy check on force outputting\n\tsymbols to object file.\n\t(build_type_decl): Don't emit the qualified identifier in debug\n\tinformation.  The fully qualified name is now determined through the\n\tNAMESPACE_DECL context chain.\n\t* d-ctype.cc (TypeEnum::toCtype): Likewise for enum members.\n\t(VarDeclaration::toSymbol): Likewise for static variables.\n\t(FuncDeclaration::toSymbol): Likewise for functions.\n\n\t* d-decls.cc (FuncDeclaration::toSymbol): Don't emit the 'D main'\n\tsymbol to debug as plain 'main'.\n\t* d-objfile.cc (VarDeclaration::toObjFile): Don't emit the qualified\n\tidentifier of manifest constants in debug information.\n\n2014-02-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_build_module): New function.\n\t* d-decls.cc (Module::toSymbol): Use d_build_module to build up the\n\tqualified module namespace.\n\n\t* d-codegen.cc (expand_intrinsic_op, expand_intrinsic_op2): New\n\tfunctions to build a call to a builtin code.\n\t(expand_intrinsic_bsr, expand_intrinsic_bt): New functions to expand a\n\tBUILTIN_FRONTEND call to core.bitop intrinsics.\n\t(expand_intrinsic_vaarg, expand_intrinsic_vastart): New functions to\n\texpand a BUILTIN_FRONTEND call to core.vararg intrinsics.\n\t(maybe_expand_builtin): Update.\n\n2014-02-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (Module::toSymbol): Build a NAMESPACE_DECL to populate the\n\tDECL_CONTEXT of toplevel functions.\n\t* d-codegen.cc (d_decl_context): Return the enclosing module\n\tNAMESPACE_DECL as the decl context only when the symbol is extern(D)\n\tand not D main.\n\n2014-02-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (VarDeclaration::toSymbol): Don't call\n\tsetup_symbol_storage until after SET_DECL_ASSEMBLER_NAME has been set.\n\n\t* d-decls.cc (VarDeclaration::toSymbol): Give prettyIdent precedence\n\tfor the DECL_NAME over the simple identifier.\n\t(FuncDeclaration::toSymbol): Likewise.\n\t* d-objfile.cc (d_finish_symbol): Remove setting DECL_NAME as\n\tprettyIdent, this has already been done in Declaration::toSymbol.\n\t(d_finish_function): Likewise.\n\n\t* d-decls.cc (VarDeclaration::toSymbol): Call set_user_assembler_name\n\tif pragma(mangle) was seen.\n\t(FuncDeclaration::toSymbol): Likewise.\n\n2014-02-12  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-decls.cc (FuncDeclaration::toSymbol): Do not set TREE_NOTHROW on\n\tnothrow functions.\n\t* d-decls.cc (TypeInfoDeclaration::toSymbol): Call relayout_decl after\n\tchanging the type.\n\n2014-02-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\n\t* d-codegen.cc (d_build_call): Remove special handling of\n\tflag_split_darrays switch.\n\t(maybe_expand_builtin): Likewise.\n\t* d-elem.cc (CatExp::toElem): Likewise.\n\t* lang.opt (fsplit-dynamic-arrays): Remove.\n\n2014-02-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-glue.cc (readFile, writeFile, ensurePathToNameExists): Define.\n\t* d-incpath.cc (add_import_path): Update for frontend changes.\n\t(add_fileimp_path): Likewise.\n\t* d-lang.cc (deps_write): Likewise.\n\t(d_parse_file): Likewise.\n\t* d-todt.cc (Dts): Update define for frontend changes.\n\t* d-decls.cc (ClassDeclaration::toVtblSymbol): Don't mark __vtbl\n\tsymbols as virtual.  They are global static symbols.\n\n2014-01-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (EnumDeclaration::toDebug): Build TYPE_DECL only for\n\tenumeral types.\n\n2014-01-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-ctype.cc (TypeClass::toCtype): Don't add __monitor field for\n\textern(C++) classes.\n\n\t* d-builtins.c (d_gcc_magic_module): Remove tdata.\n\t* d-codegen.cc (build_interface_binfo): Likewise.\n\t* d-ctype.cc (TypeEnum::toCtype): Likewise.\n\t(TypeClass::toCtype): Likewise.\n\t* d-lang.cc (deps_write): Likewise.\n\n2014-01-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-ctype.cc (TypeEnum::toCtype): Don't push CONST_DECLs into current\n\tfunction.\n\t* d-decls.cc (FuncDeclaration::toThunkSymbol): Don't mark symbol as\n\tTREE_PRIVATE, just TREE_PUBLIC as false.\n\t(StructLiteralExp::toSymbol): Likewise.\n\t(ClassReferenceExp::toSymbol): Likewise.\n\t* d-objfile.cc (d_comdat_linkage): Likewise.\n\t(d_finish_symbol): Likewise.\n\t(build_moduleinfo): Likewise.\n\n\t* config-lang.in: Add d-lang.cc to gtfiles.\n\t* d-irstate.h (IRState::varsInScope): Change from Array to vec<> type.\n\t(IRState::statementList_): Likewise.\n\t(IRState::scopes_): Likewise.\n\t(IRState::loops_): Likewise.\n\t(IRState::labels_): Likewise.\n\t* d-lang.h (d_bi_builtin_func): Remove declaration.\n\t(d_bi_builtin_type): Likewise.\n\t(d_keep_list): Likewise.\n\t* d-objfile.h (Symbol::thunks): Change from Array to vec<> type.\n\t(ModuleInfo::classes): Likewise.\n\t(ModuleInfo::ctors): Likewise.\n\t(ModuleInfo::dtors): Likewise.\n\t(ModuleInfo::ctorgates): Likewise.\n\t(ModuleInfo::sharedctors): Likewise.\n\t(ModuleInfo::shareddtors): Likewise.\n\t(ModuleInfo::sharedctorgates): Likewise.\n\t(ModuleInfo::unitTests): Likewise.\n\t(build_simple_function): Remove declaration.\n\t(build_call_function): Likewise.\n\t(build_ctor_function): Likewise.\n\t(build_dtor_function): Likewise.\n\t(build_unittest_function): Likewise.\n\t* d-builtins.c (bi_fn_list): Rename to gcc_builtins_functions.\n\t(bi_lib_list): Rename to gcc_builtins_libfuncs.\n\t(bi_type_list): Rename to gcc_builtins_types.\n\t(builtin_converted_types): Remove.\n\t(builtin_converted_decls): Change from Array to vec<> type.\n\t(gcc_type_to_d_type): Update.\n\t(d_bi_builtin_func): Remove and move to d_builtin_function.\n\t(d_bi_builtin_type): Remove and move to d_register_builtin_type.\n\t(d_gcc_magic_builtins_module): Update.\n\t* d-ctype.cc (TypeClass::toCtype): Remove unused var.\n\t* d-decls.cc (FuncDeclaration::toThunkSymbol): Update for change to\n\tvec<> type.\n\t* d-elem.cc (CatExp::toElem): Change stashed vars from Array to vec<>.\n\t(Expression::toElemDtor): Update for change to vec<> type.\n\t* d-irstate.cc (IRState::startFunction): Likewise.\n\t(IRState::endFunction): Likewise.\n\t(IRState::addExp): Likewise.\n\t(IRState::pushStatementList): Likewise.\n\t(IRState::popStatementList): Likewise.\n\t(IRState::getLabelBlock): Likewise.\n\t(IRState::getLoopForLabel): Likewise.\n\t(IRState::beginFlow): Likewise.\n\t(IRState::endFlow): Likewise.\n\t(IRState::startScope): Likewise.\n\t(IRState::pushLabel): Likewise.\n\t(IRState::checkGoto): Likewise.\n\t(IRState::checkPreviousGoto): Change from Array to Blocks type.\n\t* d-lang.cc (global_declarations): Change from Array to vec<> type.\n\t(d_add_global_declaration): Update for change to vec<> type.\n\t(d_write_global_declarations): Likewise.\n\t(d_keep_list): Make static to source file.\n\t* d-objfile.cc (static_ctor_list): Change from Array to vec<> type.\n\t(static_dtor_list): Likewise.\n\t(Module::genobjfile): Update for change to vec<> type.\n\t(d_finish_module): Likewise.\n\t(d_finish_function): Likewise.\n\t(deferred_thunks): Change from ArrayBase<> to vec<> type.\n\t(write_deferred_thunks): Update for change to vec<> type.\n\t(use_thunk): Likewise.\n\t(build_simple_function): Make static to source file.\n\t(build_call_function): Likewise.\n\t(build_ctor_function): Likewise.\n\t(build_dtor_function): Likewise.\n\t(build_unittest_function): Likewise.\n\n2014-01-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (setup_symbol_storage): Use output_module_p on template\n\tinstantiating module to determine if symbol is externally compiled.\n\t(d_finish_function): Set function local if function body was compiled.\n\t* d-decls.cc (Dsymbol::toSymbolX): Use unsigned integer format for the\n\tprefix string length.\n\n\f\nCopyright (C) 2014 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2015",
    "content": "2015-10-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (StructLiteralExp::toSymbol): Use letter prefix for\n\tanonymous name.  Don't set TREE_READONLY.\n\t(ClassReferenceExp::toSymbol): Likewise.\n\n2015-10-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_struct_literal): New function.\n\t(layout_aggregate_members): Handle variables that are really tuples.\n\t* d-elem.cc (StructLiteralExp::toElem): Handle slicing void arrays.\n\tUse build_struct_literal to handle anonymous records.\n\t* d-lang.h (d_unknown_type_node): Rename to unknown_type_node, update\n\tin all files.\n\n2015-10-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_two_field_type): Use DECL_FIELD_CONTEXT to access\n\tfield context decl.\n\t(build_frame_type): Likewise.\n\t(lookup_anon_field): New function.\n\t(component_ref): Use it.\n\t(fixup_anonymous_offset): New function.\n\t(layout_aggregate_members): New function.\n\t(layout_aggregate_type): Move generation of fields into\n\tlayout_aggregate_members.\n\t(insert_aggregate_field): Update signature, update all callers.\n\t(finish_aggregate_type): Likewise.\n\t* d-todt.cc (dt_container2): Use DECL_FIELD_CONTEXT to access field\n\tcontext decl.\n\t* types.cc (TypeVisitor::visit (TypeStruct)): Likewise.\n\t(TypeVisitor::visit (TypeClass)): Likewise.\n\t* d-tree.h (ANON_AGGR_TYPE_P): New type macro.\n\n2015-08-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (maybe_set_builtin_1): Remove va_list handling.\n\t(d_init_builtins): Don't represent static array va_list as reference.\n\t* d-codegen.cc (convert_for_argument): Handle va_list as a static array.\n\t(declaration_type): Likewise.\n\t(type_passed_as): Likewise.\n\t(decl_reference_p): Renamed to declaration_type_kind, update to return\n\thow type is represented internally, updated all callers.\n\t(arg_reference_p): Renamed to argument_type_kind, update to return how\n\ttype is represented internally, updated all callers.\n\t* d-codegen.h (type_kind): Declare.\n\n2015-08-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* toir.cc (IRVisitor::visit (TryCatchStatement)): Always emit call to\n\tLIBCALL_BEGIN_CATCH at the start of the catch.\n\t* d-elem.cc (AssertExp::toElem): Stabilize reference to class object\n\tbefore passing it to _d_invariant.\n\n2015-08-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* toir.cc (IRVisitor::visit): Set input location in all visitors that\n\teither throw an ICE or sorry message.\n\n2015-08-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in: Replace uses of $(target_alias) with\n\t$(target_noncanonical).\n\n2015-08-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* types.cc (TypeVisitor::visit (TypeEnum)): Set ENUM_IS_SCOPED on all\n\tenumeral types.\n\t* d-lang.cc (d_init_options_struct): Remove setting\n\tflag_evaluation_order.\n\n2015-08-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (HaltExp::toElem): Use __builtin_trap to halt execution,\n\trather than the library abort() call.\n\n2015-08-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_closure): Update signature, update all callers.\n\t(build_vthis): Likewise.\n\t(get_frame_for_symbol): Likewise.\n\t(build_local_var): Likewise.\n\t(get_decl_tree): Likewise.\n\t(start_function): Likewise.\n\t* d-irstate.h (IRState): Move func, mod, sthis, deferred,\n\tstatementList, and varsInScope fields to...\n\t* d-tree.h (language_function): Here, updated all uses.\n\t* d-irstate.h: Remove file.\n\t(IRState): Remove all uses everywhere.\n\n2015-08-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_GLUE_OBJS): Remove d-irstate.o.\n\t* d-tree.h (d_label_use_entry): New structure.\n\t(d_label_entry): New structure.\n\t(binding_level): Add level_kind field.\n\t(language_function): Add hash table field for labels.\n\t(D_LABEL_VARIABLE_CASE): New macro.\n\t* d-codegen.cc (pop_binding_label): New function.\n\t(pop_label): New function.\n\t(push_binding_level): Update signature.\n\t(pop_binding_level): Update signature.  Handle declared or used labels.\n\t(build_array_set): Update for push/pop binding changes.\n\t(check_goto): New function.\n\t(check_previous_goto): New function.\n\t(d_lookup_label): Remove function.\n\t(lookup_label): New function.\n\t(lookup_bc_label): New function.\n\t(define_label): New function.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Update for push/pop binding\n\tchanges.\n\t* toir.cc (IRVisitor): Add break and continue label fields.\n\t(IRVisitor::IRVisitor): Initialize here.\n\t(IRVisitor::start_scope): Update signature.\n\t(IRVisitor::end_scope): Return the finished scope, updated all callers.\n\t(IRVisitor::push_break_label): New function.\n\t(IRVisitor::pop_break_label): New function.\n\t(IRVisitor::push_continue_label): New function.\n\t(IRVisitor::pop_continue_label): New function.\n\t(IRVisitor::start_condition): Remove function.\n\t(IRVisitor::start_else): Remove function.\n\t(IRVisitor::end_condition): Remove function.\n\t(IRVisitor::start_catches): Remove function.\n\t(IRVisitor::start_catch): Remove function.\n\t(IRVisitor::end_catch): Remove function.\n\t(IRVisitor::end_catches): Remove function.\n\t(IRVisitor::start_finally): Remove function.\n\t(IRVisitor::end_finally): Remove function.\n\t(IRVisitor::start_case): Remove function.\n\t(IRVisitor::end_case): Remove function.\n\t* d-irstate.cc: Remove.\n\n2015-08-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* config-lang.in (gtfiles): Replace d-lang.h for d-tree.h\n\t* d-lang.h: Move all GTY structures to d-tree.h, updated all source\n\theader dependencies.\n\t* d-tree.h: New file.\n\n2015-08-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* toir.cc (IRVisitor::start_condition): Don't cache condition.\n\t(IRVisitor::start_else): Return the then body, updated all callers.\n\t(IRVisitor::end_condition): Update signature.\n\t(IRVisitor::start_catches): Return the try body, updated all callers.\n\t(IRVisitor::start_catch): Don't cache catch type.\n\t(IRVisitor::end_catch): Update signature.\n\t(IRVisitor::end_catches): Update signature.\n\t(IRVisitor::start_finally): Return the try body, updated all callers.\n\t(IRVisitor::end_finally): Update signature.\n\t(IRVisitor::start_case): Don't cache the condition.\n\t(IRVisitor::end_case): Update signature.\n\t* d-codegen.cc (convert_for_assignment): Use size_type_node for index.\n\t* d-irstate.cc (IRState::beginFlow): Remove call to push_stmt_list.\n\n2015-08-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (push_stmt_list): New function.\n\t(pop_stmt_list): New function.\n\t(add_stmt): New function.\n\t(start_function): New function.\n\t(end_function): New function.\n\t(expand_decl): Update to use new interface.\n\t(build_closure): Likewise.\n\t(push_binding_level): Moved from d-lang.cc.\n\t(pop_binding_level): Likewise.\n\t* d-lang.cc (d_init): Inline call to init_global_binding_level.\n\t(alloc_binding_level): Remove function.\n\t(push_binding_level): Remove function.\n\t(pop_binding_level): Remove function.\n\t(init_global_binding_level): Remove function.\n\t(set_decl_binding_chain): Remove function.\n\t* d-elem.cc (DeclarationExp::toElem): Likewise.\n\t* d-objfile.cc (VarDeclaration::toObjFile): Likewise.\n\t(FuncDeclaration::toObjFile): Likewise.\n\t* toir.cc (IRVisitor::start_scope): Moved from d-irstate.cc, updated\n\tall callers in IRVisitor.\n\t(IRVisitor::end_scope): Likewise.\n\t(IRVisitor::is_return_label): Likewise.\n\t(IRVisitor::do_label): Likewise.\n\t(IRVisitor::do_jump): Likewise.\n\t(IRVisitor::start_condition): Likewise.\n\t(IRVisitor::start_else): Likewise.\n\t(IRVisitor::end_condition): Likewise.\n\t(IRVisitor::start_catches): Likewise.\n\t(IRVisitor::start_catch): Likewise.\n\t(IRVisitor::end_catch): Likewise.\n\t(IRVisitor::end_catches): Likewise.\n\t(IRVisitor::start_finally): Likewise.\n\t(IRVisitor::end_finally): Likewise.\n\t(IRVisitor::end_loop): Likewise.\n\t(IRVisitor::start_case): Likewise.\n\t(IRVisitor::end_case): Likewise.\n\t(build_ir): Update signature.\n\n2015-08-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (DMD_COMPILE): Declare as COMPILE with WARN_CXXFLAGS\n\treplaced with DMD_WARN_CXXFLAGS.\n\t(DMDGEN_COMPILE): Declare as DMD_COMPILE but with COMPILER replaced\n\twith COMPILER_FOR_BUILD.\n\t(d/idgen): Use LINKER_FOR_BUILD.\n\t(d/impcvgen): Likewise.\n\t(d/%.o): Use DMD_COMPILE and POSTCOMPILE.\n\t(d/%.dmdgen.o): Use DMDGEN_COMPILE and POSTCOMPILE.\n\n2015-07-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (current_irstate): Remove.\n\t(d_build_call): Check cfun before dereferencing.\n\t* d-codegen.h (current_irstate): Redefine as macro.\n\t* d-irstate.cc (IRState::IRState): Remove.\n\t(IRState::startFunction): Initialize language-specific cfun field.\n\t(IRState::endFunction): Free language-specific cfun field.\n\t* d-lang.cc (d_parse_file): Don't initialize current_irstate.\n\t* d-lang.h (language_function): Add irs field.\n\t* d-objfile.cc (Dsymbol::toObjFile): Check cfun.\n\t(FuncDeclaration::toObjFile): Adjust start and end calls.\n\n2015-07-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-irstate.cc (IRState::doArraySet): Remove function.\n\t* d-codegen.cc (build_array_set): New function.\n\t* d-elem.cc (AssignExp::toElem): Use build_array_set.\n\t(StructLiteralExp::toElem): Likewise.\n\n\t* d-codegen.cc (build_array_set): Don't set this_block, update call to\n\tpop_binding_level.\n\t* d-irstate.cc (IRState::endFunction): Update assert.\n\t(IRState::startScope): Move IRState::startBindings here, clean-up.\n\t(IRState::endScope): Move IRState::endBindings here, clean-up.\n\t(IRState::startBindings): Remove function.\n\t(IRState::endBindings): Likewise.\n\t(IRState::currentScope): Likewise.\n\t(IRState::scopes_): Remove.\n\t* d-lang.cc (pop_binding_level): Update signature, clean-up.\n\t(d_pushdecl): Don't set names_end.\n\t(binding_level::names_end): Remove.\n\t(binding_level::this_block): Remove.\n\t(FuncDeclaration::toObjFile): Clean-up.\n\n2015-07-24  Sebastien Alaiwan  <sebastien.alaiwan@gmail.com>\n\n\t* d-lang.cc (deps_write): Use StringTable instead of hash_set of string\n\tpointers.\n\n2015-07-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-attribs.h: Adjust includes.\n\t* d-builtins.cc: Likewise.\n\t* d-codegen.cc: Likewise.\n\t* d-convert.cc: Likewise.\n\t* d-decls.cc: Likewise.\n\t* d-elem.cc: Likewise.\n\t* d-glue.cc: Likewise.\n\t* d-incpath.cc: Likewise.\n\t* d-irstate.cc: Likewise.\n\t* d-lang.cc: Likewise.\n\t* d-longdouble.cc: Likewise.\n\t* d-objfile.cc: Likewise.\n\t* d-port.cc: Likewise.\n\t* d-target.cc: Likewise.\n\t* d-todt.cc: Likewise.\n\t* toir.cc: Likewise.\n\t* types.cc: Likewise.\n\n2015-07-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (convert_expr): Warn about casts between imaginary\n\tand non-imaginary types.\n\t* d-convert (d_convert_basic): Rename to convert, handle conversions\n\tbetween complex and imaginary types.\n\t(convert): Remove.\n\t(d_build_truthvalue_op): Update to call convert.\n\t(d_truthvalue_conversion): Likewise.\n\n\t* d-builtins.cc (d_init_builtins): Build imaginary types as distinct\n\tfloating point type nodes.\n\t* d-codegen.cc (build_float_modulus): Update to handle imaginary types.\n\t(d_array_type): Use the front-end equivalent of sizetype to represent\n\tthe index type of arrays.\n\t(build_array_index): Likewise.\n\t(build_offset_op): Likewise.\n\t(expand_intrinsic): Only get the inner callee if it's an address.\n\n\t* d-codegen.h (component_ref, modify_expr, vmodify_expr, build_vinit)\n\t(build_nop, build_vconvert, build_boolop, compound_expr)\n\t(vcompound_expr, real_part, imaginary_part): Move to d-codegen.cc,\n\tuse fold build functions for codegen.\n\t* d-codeden.cc (build_address): Use build_fold_addr_expr_with_type,\n\tremove special handling of taking an address of an indirect ref.\n\t(return_expr): New function.\n\t(complex_expr): New function.\n\t(indirect_ref): Use fold build functions for codegen.\n\t(build_deref): Likewise.\n\t(build_array_index): Likewise.\n\t(build_offset_op): Likewise.\n\t(void_okay_p): Likewise.\n\t(build_binary_op): Likewise.\n\t(build_float_modulus): Likewise.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Likewise.\n\t* d-elem.cc (MinExp::toElem): Likewise.\n\t(AddExp::toElem): Likewise.\n\t(NotExp::toElem): Likewise.\n\t(ComExp::toElem): Likwise.\n\t(NegExp::toElem): Likewise.\n\t* d-irstate.cc (IRState::doLabel): Likewise.\n\t(IRState::doReturn): Likewise.\n\t(IRState::doJump): Likewise.\n\n\t* d-attribs.c: Adjust includes for flags.h changes.\n\t* d-builtins.cc: Likewise.\n\t* d-codegen.cc: Likewise.\n\t* d-convert.cc: Likewise.\n\t* d-elem.cc: Likewise.\n\t* d-decls.cc: Likewise.\n\t* d-glue.cc: Likewise.\n\t* d-incpath.cc: Likewise.\n\t* d-irstate.cc: Likewise.\n\t* d-lang.cc: Likewise.\n\t* d-longdouble.cc: Likewise.\n\t* d-objfile.cc: Likewise.\n\t* d-port.cc: Likewise.\n\t* d-target.cc: Likewise.\n\t* d-todt.cc: Likewise.\n\t* toir.cc: Likewise.\n\t* types.cc: Likewise.\n\n2015-07-20  Sebastien Alaiwan  <sebastien.alaiwan@gmail.com>\n\n\t* d-lang.cc (is_system_module): Extract function.\n\t(write_one_dep): Extract function.\n\t(deps_write): Eliminate duplicated dependencies, include\n\tindirect and private dependencies.\n\n2015-07-19  Sebastien Alaiwan  <sebastien.alaiwan@gmail.com>\n\n\t* d-lang.cc (d_parse_file): Set ref flag on the module and make deps\n\tfile handle.\n\n2015-07-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (convert_for_assignment): Remove handling of zero\n\tinitialising a structure using memset.\n\t(d_build_call): Removing handling of setting of return slot\n\toptimisation on in call expression.\n\t* d-elem.cc (AssignExp::toElem): Emit a memset to zero initialise\n\tstructures here.  Set return slot optimisation on construction of\n\tstatic arrays and structs only.\n\n2015-07-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (expand_intrinsic_arith): Use build_deref to handle\n\tref parameters being used for the 'overflow' parameter.\n\n2015-07-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (StringExp::toElem): Zero-terminate all string literals\n\ttypes, except for static arrays.\n\t* d-objfile.cc (build_type_decl): Add TYPE_DECLs to global declarations,\n\tdon't call rest_of_decl_declaration.\n\t(d_finish_compilation): Call rest_of_decl_declaration on TYPE_DECLs.\n\t(Dsymbol::toObjFile): Don't try to handle tuples when emitting import\n\tdeclarations to debug.\n\t* d-builtins.cc (builtin_sym): Use StructDeclaration for decl field.\n\t(build_dtype): Don't handle anonymous structs.  Create a stub parent\n\tmodule for the declaration symbol.\n\t(d_build_builtins_module): Always override the parent module of\n\tconverted struct declarations.\n\t(maybe_set_builtin_1): Convert all static array parameters to ref\n\tparameters, not just va_list.\n\n2015-07-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-attribs.c (d_handle_section_attribute): Use VAR_P throughout.\n\t(d_handle_weak_attribute): Use VAR_OR_FUNCTION_DECL_P.\n\t* d-codegen.cc (convert_for_assignment): Use VAR_P.\n\t* d-lang.cc (pop_binding_level): Likewise.\n\t(d_types_compatible_p): Likewise.\n\t* d-objfile.cc (setup_symbol_storage): Likewise.\n\t(mark_needed): Likewise.\n\t(d_finish_compilation): Likewise.\n\n2015-06-30  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* intrinsics.def: Added ADDS, ADDSL, ADDU, ADDUL, SUBS, SUBSL, NEGS,\n\tNEGSL, MULS, MULSL, MULU, and MULUL intrinsic definitions.\n\t* d-codegen.cc (expand_intrinsic_arith): New function.\n\t(expand_intrinsic): Add cases for core.checkedint functions adds, addu,\n\tsubs, subu, negs, muls, and mulu intrinsics.\n\n2015-06-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_DMD_H): Remove.\n\t(D_TREE_H): Likewise.\n\t(CFLAGS-d/d-spec.o): Declare extra CFLAGS for building driver.\n\t(d-warn): Declare default warning flags for compiler.\n\t(D_DMD_OBJS): Remove 'dmd' from the object file suffix.\n\t(D_GLUE_OBJS): Remove 'cglue' and 'glue' from object file suffix.\n\t(D_GENERATED_OBJS): Remove 'gen' from the object file suffix.\n\t(D_BORROWED_C_OBJS): Remove.\n\t(CFLAGS-d/id.o): Declare extra CFLAGS for building generated sources.\n\t(CFLAGS-d/impcnvtab.o): Likewise.\n\t* types.cc (TypeVisitor::visit (TypeClass)): Build a pointer type for\n\tclasses, not a reference type.\n\t* types.cc (TypeVisitor::visit (TypeDelegate)): Don't build a\n\tMETHOD_TYPE for delegates, as that requires knowing the underlying\n\trecord type for the 'this' object parameter.\n\t(TypeVisitor::visit (TypeEnum): Don't call rest_of_type_compilation.\n\t(TypeVisitor::visit (TypeClass): Likewise.\n\t(TypeVisitor::visit (TypeStruct): Likewise.\n\t* d-decls.cc (TypeInfoDeclaration::toSymbol): Assert class is a pointer\n\ttype, not a reference type.\n\t(FuncDeclaration::toSymbol): Don't convert nested functions into a\n\tMETHOD_TYPE to be strictly compatible with delegates.\n\t* d-codegen.cc (convert_for_argument): Use correct accessors for array\n\t.ptr and .length properties.\n\t(expand_intrinsic_vaarg): Don't remove the va_list pointer reference,\n\tas the backend now assumes this is what the front-end sets up.\n\t(d_build_call): Remove assert as delegates and nested functions are no\n\tlonger represented as METHOD_TYPE.\n\t(build_vthis_type): New function.\n\t(d_decl_context): Don't set static/__gshared declaration context as\n\tanything other than the enclosing module of the declaration.\n\t* toir.cc (IRVisitor::visit (ExtAsmStatement)): Support named labels by\n\tcalling resolve_asm_operand_names.\n\t* d-builtins.cc (d_backend_init): Remove.\n\t(d_backend_term): Remove.\n\t* d-lang.cc (d_write_global_declarations): Remove langhook.\n\t(d_init): Move d_backend_init implementation here.\n\t(d_parse_file): Move d_write_global_declarations implementation here.\n\t(d_finish_compilation): Remove calls to finalize_compilation_unit,\n\tcheck_global_declarations, and emit_debug_global_declarations.\n\t(d-system.h): Remove file.  Move all includes into local sources.\n\n2015-06-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_build_call): Only apply CALL_EXPR_RETURN_SLOT_OPT to\n\tcalls returning an aggregate.\n\t(expand_intrinsic): Use CALL_EXPR_FN and CALL_EXPR_ARG directly.\n\t(layout_aggregate_type): Update signature.\n\t(insert_aggregate_field): Likewise.\n\t(finish_aggregate_type): Likewise.\n\t* d-codegen.h (AggLayout): Remove helper class.\n\t(AddrOfExpr): Remove helper class.\n\t(CallExpr): Remove helper class.\n\t* d-elem.cc (InExp::toElem): Use build_address directly.\n\t(CatAssignExp::toElem): Likewise.\n\t(IndexExp::toElem): Likewise.\n\t(RemoveExp::toElem): Likewise.\n\t* types.cc (TypeVisitor::visit (TypeFunction)): Only apply\n\tTREE_ADDRESSABLE to function types returning an aggregate.\n\t(TypeVisitor::visit (TypeStruct)): Update for layout_aggregate_type and\n\tfinish_aggregate_type changes.\n\t(TypeVisitor::visit (TypeClass)): Likewise.\n\n2015-06-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (setup_symbol_storage): Mark declarations as private or\n\tprotected for the benefit of debug code.\n\t* d-elem.cc (ArrayLiteralExp::toElem): Only set a value at the given\n\tindex in the array constructor if it is non-zero.\n\t(AssignExp::toElem): Use memset it assigning/initialising an array with\n\tall zeroes.\n\t(IndexExp::toElem): Simplify codegen to use a placeholder variable for\n\tthe dollar length.\n\t(SliceExp::toElem): Likewise.\n\t* d-codegen.cc (ArrayScope): Remove helper class.\n\t* Make-lang.in (cc1d$(exeext)): Use link mutex.\n\n2015-05-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_GLUE_OBJS): Rename d-ctype.cc to types.cc.\n\t(d-spec.o): Rename d-spec.cc to d-spec.c\n\t* types.cc (build_ctype): New function.\n\t(Type::toCtype): Convert toCtype methods to use Visitor interface.\n\n2015-04-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_GLUE_OBJS): Add d-attribs.o.  Remove d-gt.o.\n\t* d-attribs.c: New file.\n\t* d-builtins.cc: Move attribute handler functions to d-attribs.c\n\t* d-lang.cc: Likewise.  Added include for gtype-d.h from d-gt.cc.\n\t* d-gt.cc: Remove file.\n\n2015-04-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc, d-convert.cc, d-ctype.cc, d-decls.cc, d-elem.cc,\n\td-glue.cc, d-incpath.cc, d-irstate.cc, d-longdouble.cc, d-port.cc,\n\td-target.cc, d-typinf.cc, toir.cc: Re-order included headers.\n\t* d-codegen.h, d-dmd-gcc.h, d-irstate.h, d-lang.h, d-objfile.cc,\n\td-system.h: Remove all includes from headers.\n\t* d-codegen.cc: Re-order included headers.\n\t(build_attributes): Use ctfeInterpret instead of optimize.\n\t* d-lang.cc: Re-order included headers.\n\t(d_init_options): Don't use tristate enum for flag_emit_templates.\n\t(d_handle_option): Likewise.\n\t* d-objfile.cc: Re-order included headers.\n\t(output_declaration_p): Update check for flag_emit_templates.\n\t(setup_symbol_storage): Likewise.\n\t* d-todt.cc: Re-order included headers.\n\t(ExpInitializer::toDt): Use ctfeInterpret instead of optimize.\n\t(TypeInfoTupleDeclaration::toDt): Likewise.\n\n2015-04-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_exception_object): Remove.\n\t* runtime.def (BEGIN_CATCH): Declare runtime function __gdc_begin_catch.\n\t* toir.cc (IRVisitor::visit::TryCatchStatement): Use LIBCALL_BEGIN_CATCH\n\tto get the correct exception object for handler.\n\n2015-04-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_build_call): Set CALL_EXPR_RETURN_SLOT_OPT on calls to\n\tfunctions that return an aggregate or array that returns in memory.\n\t(build_memref): New function.\n\t(get_object_method): Use build_memref instead of building a\n\tPOINTER_PLUS_EXPR for vtable dereferences.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Support NRVO on\n\tARRAY_TYPE's that may not return in registers.\n\t* d-ctype.cc (TypeFunction::toCtype): Don't mark TREE_ADDRESSABLE when\n\treturning non-POD types by reference.\n\n2015-04-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (EnumDeclaration::toDebug): Remove.\n\t(ClassDeclaration::toDebug): Remove.\n\t(StructDeclaration::toDebug): Remove.\n\t* d-ctype.cc (TypeEnum::toCtype): Call rest_of_type_compilation here.\n\t(TypeClass::toCtype): Likewise.\n\t(TypeStruct::toCtype): Likewise.\n\n2015-04-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (get_decl_tree): Check and generate correct code for when\n\ta non-local 'this' is accessed through a closure pointer.\n\t(FuncDeclaration::toObjFile): Remove check for _arguments.\n\t* d-codegen.cc (build_local_var): Likewise.\n\n2015-04-11  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-objfile.cc (setup_symbol_storage): Mark functions without\n\tbody as DECL_EXTERNAL.\n\n2015-04-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (get_decl_tree): Get correct non-local 'this' decl by\n\tconstructing component reference through parent link of nested classes.\n\t* d-builtins.cc (DEF_FUNCTION_TYPE_VAR_8): Remove.\n\t(DEF_FUNCTION_TYPE_VAR_12): Likewise.\n\t(DEF_FUNCTION_TYPE_VAR_7, DEF_FUNCTION_TYPE_VAR_11): New macros.\n\n2015-04-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (output_declaration_p): Remove check for semanticRun.\n\t(FuncDeclaration::toObjFile): Name bool parameter force_p, allow it to\n\toverride the initial output_declaration_p check.  Force run all\n\tsemantic passes for symbols that it routine is generating code for.\n\t(d_finish_function): Don't mark TREE_STATIC on functions that are\n\treally DECL_EXTERN.\n\t(finish_thunk): Force thunks referencing external methods to be\n\texpanded to gimple.\n\t* d-decls.cc (FuncDeclaration::toThunkSymbol): Call toObjFile on all\n\tthunk target functions.\n\n2015-04-05  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-lang.cc (d_handle_section_attribute): New function.\n\t* d-builtins.cc (handle_alias_attribute): Move to d-lang.cc to\n\tsupport attribute(alias) in user code.\n\t* d-lang.cc (d_handle_alias_attribute): Ditto.\n\t* d-lang.cc (d_handle_weak_attribute): New function.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Do not set\n\tDECL_DECLARED_INLINE_P prematurely.\n\n2015-03-21  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-lang.cc (d_init): Add GNU_EMUTLS version.\n\t* d-objfile.cc (build_emutls_function): New function.\n\t* d-objfile.cc (VarDeclaration::toObjFile): Collect all TLS variables\n\tin a module into tlsVars array.\n\t* d-objfile.cc (genmoduleinfo): Add reference to __modtlsscan\n\tfunction generated by build_emutls_function to moduleinfo.\n\n2015-02-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* config-lang.in: Remove lang_requires_boot_languages.\n\t* d-incpath.cc (iprefix): Remove global variable.\n\t(multilib_dir): Ditto.\n\t(prefixed_path): Add iprefix parameter.\n\t(add_import_paths): Add iprefix and imultilib parameter.\n\tUse cpp_include_defaults to get list of import paths.\n\t* d-lang.cc (iprefix_dir): New static variable to cache -iprefix switch.\n\t(imultilib_dir): New static variable to cache -imultilib switch.\n\t(d_init): Pass iprefix_dir and imultilib_dir to add_import_paths.\n\t(d_handle_option): Use new static variables.\n\n2015-02-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc: Remove d-confdef.h header.\n\t* d-incpath.cc: Ditto.\n\t* d-spec.cc: Ditto.\n\n2015-01-31  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-incpath.cc (add_phobos_versyms): Remove function.\n\t* d-lang.cc (d_init): Remove call to add_phobos_versyms.\n\n2015-01-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (DEF_FUNCTION_TYPE_VAR_8)\n\t(DEF_FUNCTION_TYPE_VAR_12): New macros.\n\n2015-01-24  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-builtins.cc (d_build_builtins_module): Mark builtin functions\n\tas @nogc.\n\n2015-01-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in: Update for D frontend changes.\n\t* d-asmstmt.cc: Remove file.\n\t* d-builtins.cc (build_dtype): No longer set struct handle.\n\t(d_gcc_paint_type): Move to Target::paintAsType.\n\t* d-codegen.cc (convert_expr): No longer call getImpl on associative\n\tarray conversions.  Add case for converting void pointers to delegates.\n\t(unhandled_arrayop_p): Remove.\n\t(build_two_field_type): Use layout_type instead of building\n\tTYPE_STUB_DECL and calling rest_of_decl_compilation.\n\t(build_binop_assignment): New function.\n\t(libcall_ids): Remove static variable.\n\t(get_libcall): New function.\n\t(maybe_set_intrinsic): Remove druntime library call handling.\n\t(expand_intrinsic_vaarg): Dereference ref va_list parameters.\n\t(build_closure): New function.\n\t(WrappedExp::WrappedExp): Move to frontend sources.\n\t(WrappedExp::toCBuffer): Ditto.\n\t* d-codegen.h (LibCallFlag): New enum.\n\t(LibCall): Use runtime.def macro to define members.\n\t* d-ctype.cc (Type::toCParamtype): Remove function.\n\t(TypeTypedef::toCParamtype): Ditto.\n\t(TypeClass::toSymbol): Ditto.\n\t(TypeFunction::retStyle): Move to retStyle.\n\t(TypeSArray::toCParamtype): Ditto.\n\t(Type::toSymbol): Ditto.\n\t(Type::totym): Ditto.\n\t(TypeFunction::totym): Ditto.\n\t* d-decls.cc (Dsymbol::toSymbolX): Update for frontend changes.\n\t(Dsymbol::toImport): Ditto.\n\t(VarDeclaration::toSymbol): Ditto.\n\t(FuncDeclaration::toSymbol): Ditto.\n\t(InterfaceDeclaration::toSymbol): Use TREE_READONLY instead of\n\t(EnumDeclaration::toDebug): Only call rest_of_type_compilation on\n\tENUMERAL_TYPE types.\n\tTREE_CONSTANT to declare that the symbol cannot be modified.\n\t(ClassDeclaration::toVtblSymbol): Ditto.\n\t(AggregateDeclaration::toInitializer): Ditto.\n\t(EnumDeclaration::toInitializer): Ditto.\n\t(TypedefDeclaration::toInitializer): Remove function.\n\t(TypedefDeclaration::toDebug): Ditto.\n\t(Dsymbol::cvMember): Remove stub function.\n\t(EnumDeclaration::cvMember): Ditto.\n\t(FuncDeclaration::cvMember): Ditto.\n\t(VarDeclaration::cvMember): Ditto.\n\t(TypedefDeclaration::cvMember): Ditto.\n\t* d-elem.cc (XorExp::toElem): Remove call to unhandled_arrayop_p.\n\t(OrExp::toElem): Ditto.\n\t(AndExp::toElem): Ditto.\n\t(UshrExp::toElem): Ditto.\n\t(ShrExp::toElem): Ditto.\n\t(ShlExp::toElem): Ditto.\n\t(ModExp::toElem): Ditto.\n\t(DivExp::toElem): Ditto.\n\t(MulExp::toElem): Ditto.\n\t(MinExp::toElem): Ditto.\n\t(AddExp::toElem): Ditto.\n\t(XorAssignExp::toElem): Ditto.\n\t(OrAssignExp::toElem): Ditto.\n\t(AndAssignExp::toElem): Ditto.\n\t(UshrAssignExp::toElem): Ditto.\n\t(ShrAssignExp::toElem): Ditto.\n\t(ShlAssignExp::toElem): Ditto.\n\t(ModAssignExp::toElem): Ditto.\n\t(DivAssignExp::toElem): Ditto.\n\t(MulAssignExp::toElem): Ditto.\n\t(PowAssignExp::toElem): Ditto.\n\t(MinAssignExp::toElem): Ditto.\n\t(AddAssignExp::toElem): Ditto.\n\t(BinExp::toElemBin): Move to build_binop_assignment.\n\t(AssignExp::toElem): Update for frontend changes.\n\t(DelegatePtrExp::toElem): New function.\n\t(DelegateFuncptrExp::toElem): New function.\n\t(DelegateExp::toElem): Update for frontend changes.\n\t(FuncExp::toElem): Ditto.\n\t(NewExp::toElem): Ditto.\n\t(StringExp::toElem): Don't set TREE_READONLY on string literals.\n\t(AssocArrayLiteralExp::toElem): Remove codegen rewrite for new\n\tassociative array implementation.\n\t* d-glue.cc (Global::isSpeculativeGagging): Remove function.\n\t(Dsymbol::ungagSpeculative): Ditto.\n\t(Ungag::~Ungag): Ditto.\n\t(Loc::toChars): Update for new column diagnostic support.\n\t(Loc::Loc): Ditto.\n\t(Loc::equals): Ditto.\n\t(error): Ditto.\n\t(binary): Remove function.\n\t(asmSemantic): New function.\n\t(retStyle): New function.\n\t(FuncDeclaration::isBuiltin): Rename to isBuiltin.\n\t* d-intrinsics.def: Rename to intrinsics.def.\n\t* d-irstate.cc (IRState::addExp): Remove old warning to catch statements\n\twith no side effects.  Now handled in frontend.\n\t* d-lang.cc (d_init_options): Update for frontend changes.\n\t(d_initialize_diagnostics): Remove function.\n\t(d_add_builtin_version): Update for frontend changes.\n\t(d_init): Ditto.\n\t(d_handle_option): Ditto.\n\t(d_post_options): Ditto.\n\t(d_parse_file): Ditto.\n\t* d-objfile.cc (Nspace::toObjFile): New function.\n\t(StructDeclaration::toObjFile): Update for frontend changes.\n\t(TypedefDeclaration::toObjFile): Remove function.\n\t(TemplateInstance::toObjFile): Update for frontend changes.\n\t(TemplateMixin::toObjFile): Ditto.\n\t(unnest_function): New function.\n\t(output_declaration_p): Update for frontend changes.\n\t(FuncDeclaration::toObjFile): Ditto.\n\t(FuncDeclaration::buildClosure): Move to buildClosure.\n\t(get_linemap): Update for frontend changes.\n\t(build_simple_function): Ditto.\n\t(build_call_function): Ditto.\n\t* d-target.cc (Target::va_listType): New function.\n\t(Target::paintAsType): Ditto.\n\t* d-todt.cc (dt_container2): Do not set TREE_READONLY on initialisers.\n\t(dt_container): Ditto.\n\t(ClassReferenceExp::toDt2): Update for C++ class support.\n\t(ClassReferenceExp::toInstanceDt): Ditto.\n\t(TypeTypedef::toDt): Remove function.\n\t(TypeInfoTypedefDeclaration::toDt): Ditto.\n\t(TypeInfoAssociativeArrayDeclaration::toDt): Update typeinfo size.\n\t(TypeInfoAssociativeArrayDeclaration::toDt): Remove reference to impl\n\tfield in TypeInfo struct.\n\t(TypeInfoStructDeclaration::toDt): Update for frontend changes.\n\t* d-typinf.cc (Type::getTypeInfo): Update for frontend changes.\n\t(TypeTypedef::getTypeInfoDeclaration): Remove function.\n\t(createTypeInfoArray): Remove function.\n\t* runtime.def: New file.\n\t* toir.cc (IRVisitor::visit::DtorExpStatement): Remove function.\n\t(IRVisitor::visit::ExtAsmStatement): Update for frontend changes.\n\n2015-01-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (UshrAssignExp::toElem): Remove integer promotion on left\n\thand side of unsigned right shift expression.\n\n2015-01-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-system.h: Include hash-set.h, machmode.h, vec.h, double-int.h,\n\tinput.h, alias.h, symtab.h and inchash.h due to flattening of tree.h.\n\t* d-gt.cc: Ditto.\n\n2015-01-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.h (build_boolop): Don't eagerly fold comparison expressions.\n\n\f\nCopyright (C) 2015 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2016",
    "content": "2016-12-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(VarExp)): Remove type forced conversion.\n\n2016-12-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Handle -ftransition=safe.\n\t* lang.opt (ftransition=safe): Add compiler option.\n\n2016-12-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_init_options): Initialize hdrStripPlainFunctions.\n\t(d_post_options): Add post option handling of flag.\n\n2016-12-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (layout_aggregate_type): Adjust layout of D interfaces.\n\tOnly add a __vptr field if no base interfaces, don't add __monitor.\n\n2016-12-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_parse_file): Run runDeferredSemantic2 after semantic2.\n\n2016-12-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(ArrayLiteralExp)): Use getElement to\n\tindex elements array.\n\t(ExprVisitor::visit(VectorExp)): Likewise.\n\n2016-12-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_DMD_OBJS): Add d/objc.o\n\t* types.cc (TypeVisitor::visit(TypeFunction)): Handle ObjC linkage.\n\n2016-12-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (mangle_decl): New function.\n\t(make_internal_name): Update.\n\t(get_symbol_decl): Update.\n\n2016-12-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::needs_dtor): New function.\n\t(ExprVisitor::lvalue_p): New function.\n\t(ExprVisitor::visit(AssignExp)): Check both for postblit and dtors\n\twhen generating array assignments.\n\n2016-12-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (convert_expr): Allow upcasting C++ classes.\n\t(build_class_instance): Generate initial values of vtable interfaces\n\tbefore class fields.\n\t(layout_aggregate_type): Layout vtable interfaces before class fields.\n\t* d-decls.cc (get_symbol_decl): Build DECL_ARGUMENTS for functions\n\tthat have no body.\n\n2016-12-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-target.cc (Target::cppExceptions): New variable.\n\t(Target::init): Initialize it.\n\t(Target::prefixName): New function.\n\n2016-12-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (ClassDeclaration::toObjFile): Use layout_classinfo to\n\tgenerate TypeInfo for classes.\n\t(InterfaceDeclaration::toObjFile): Likewise.\n\t* d-todt.cc (build_vptr_monitor): Remove function.\n\t* typeinfo.cc (TypeInfoVisitor::set_field): New function.\n\t(TypeInfoVisitor::layout_interfaces): New function.\n\t(TypeInfoVisitor::layout_interface_vtables): New function.\n\t(TypeInfoVisitor::visit(TypeInfoClassDeclaration)): Implement.\n\t(layout_classinfo): New function.\n\n2016-12-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* typeinfo.cc (TypeInfoVisitor): Use build_typeinfo instead of\n\tget_typeinfo_decl.\n\t* d-objfile.cc (ClassDeclaration::toObjFile): Use build_constructor to\n\tbuild the vtable, instead of using dt_cons.\n\n2016-12-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (layout_moduleinfo_fields): Use finish_aggregate_type\n\tinstead of layout_type.\n\t(layout_classinfo_interfaces): Likewise.\n\n2016-12-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (build_dtype): Use static create method for allocating\n\tfrontend types.\n\t* d-codegen.cc (declaration_type): Likewise.\n\t(type_passed_as): Likewise.\n\t(get_libcall): Likewise.\n\t* d-lang.cc (d_parse_file): Likewise.\n\t* d-objfile.cc (build_simple_function_decl): Likewise.\n\t(build_emutls_function): Likewise.\n\t* d-todt.cc (StructDeclaration::toDt): Likewise.\n\t* typeinfo.cc (TypeInfoVisitor::visit(TypeInfoInterfaceDeclaration)):\n\tLikewise.\n\n2016-12-17  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-decls.cc (copy_struct): Also copy and update TYPE_METHODS.\n\t* d-spec.c (lang_specific_driver): Do not link in math, thread and\n\ttime libraries. Use a spec file instead to do this.\n\t(lang_specific_pre_link): Load libgphobos.spec to set up the link\n\tdependencies for libgphobos.\n\n2016-12-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (build_dtype): Cache all allocated frontend types.\n\t(builtin_sym): Update constructor.\n\t(builtin_converted_decls): Rename to builtin_converted_syms.\n\t(d_build_builtins_module): Check if decl set before assigning parent.\n\n2016-12-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (build_dtype): Set type modifiers on frontend type.\n\n2016-12-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (build_dtype): Don't set default parameter storage\n\tclass as const.\n\n2016-12-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (add_moduleinfo_field): New function.\n\t(layout_moduleinfo_fields): New function.\n\t(get_moduleinfo_decl): Use record type for moduleinfo decl.\n\t* d-objfile.cc (build_moduleinfo_symbol): Delay calling\n\tget_moduleinfo_decl until after ModuleInfo type is validated.\n\t(d_finish_symbol): Remove check for unknown_type_node.\n\n2016-12-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (copy_struct): New function.\n\t(layout_classinfo_interfaces): New function.\n\t(get_classinfo_decl): Use record type for classinfo decl.\n\t* d-codegen.cc (create_field_decl): New function.\n\tUse it instead of build_decl when creating a new FIELD_DECL.\n\n2016-12-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (build_dtype): Don't build generic function types.\n\t(d_build_builtins_module): Remove check.\n\n2016-12-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_vindex_ref): Move saving of object to callers.\n\t* expr.cc (ExprVisitor::visit(CallExp)): Save object reference before\n\tpassing to build_vindex_ref.\n\t(ExprVisitor::visit(DelegateExp)): Likewise.\n\n2016-12-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-spec.c (lang_specific_driver): Remove error handling.\n\t* d-lang.cc (d_parse_file): Don't error twice.\n\n2016-12-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-spec.c (lang_specific_driver): Remove 'added' variable.\n\n2016-12-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (get_symbol_decl): Use needsCodegen to determine whether\n\ttemplate instance is extern or not.\n\n2016-12-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-glue.cc (escapePath): Move to dfrontend.\n\t(readFile): Likewise.\n\t(writeFile): Likewise.\n\t(ensurePathToNameExists): Likewise.\n\n2016-12-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-target.cc: Include memmodel.h.\n\t* d-attrib.c (d_handle_section_attribute): No longer set\n\tuser_defined_section_attribute.\n\n2016-11-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* types.cc (TypeVisitor::visit(Type)): Update.\n\n2016-11-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_struct_literal): Stop after first field\n\tassignment in union constructor.\n\t(build_class_instance): Skip void initialized fields.\n\t* expr.cc (ExprVisitor::visit(StructLiteralExp)): Likewise.\n\n2016-11-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (get_symbol_decl): Don't set alignment if\n\tSTRUCTALIGN_DEFAULT.\n\n2016-11-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-todt.cc (ClassDeclaration::toDt): Update.\n\t(ClassDeclaration::toDt2): Remove function.\n\t(TypeSArray::toDtElem): Remove function.\n\t(dt_chainon): Remove function.\n\t(dt_zeropad): Remove function.\n\t(dt_container): Remove function.\n\t(dt_container2): Rename to dt_container.  All callers updated.\n\t* d-objfile.cc (VarDeclaration::toObjFile): Update.\n\n2016-11-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (copy_lang_decl): Rename to d_dup_lang_specific_decl.\n\t(LANG_HOOKS_DUP_LANG_SPECIFIC_DECL): Redefine.\n\t* d-decls.cc (make_alias_for_thunk): Call dup_lang_specific_decl.\n\t(make_thunk): Likewise.\n\n2016-11-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.h (FuncFrameInfo): Remove type.  All users updated to\n\tinterface with new frame macro accessors.\n\t(build_frame_type): Mark as static.\n\t(get_frameinfo): Update to return a tree type.\n\t* d-lang.cc (LANG_HOOKS_TREE_SIZE): Redefine.\n\t(LANG_HOOKS_PRINT_XNODE): Redefine.\n\t(d_tree_size): New function.\n\t(d_print_xnode): New function.\n\t(d_tree_node_structure): New function.\n\t* d-tree.def (FUNCFRAME_INFO): New tree_code.\n\t* d-tree.h (tree_frame_info): New type.\n\t(FRAMEINFO_CREATES_FRAME): New macro accessor.\n\t(FRAMEINFO_STATIC_CHAIN): New macro accessor.\n\t(FRAMEINFO_IS_CLOSURE): New macro accessor.\n\t(FRAMEINFO_TYPE): New macro accessor.\n\t(lang_decl): Replace frame_info field with a tree type.\n\t(d_tree_node_structure_enum): New type.\n\t(lang_tree_node): Update GTY tags.\n\n2016-11-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (setup_symbol_storage): Remove function.\n\t(Dsymbol::toSymbol): Remove function and all overrides.  All callers\n\tupdated to call ...\n\t(get_symbol_decl): ... New function.\n\n2016-11-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (output_modules): Remove variable.\n\t(output_module): Remove variable.\n\t(d_gcc_get_output_module): Remove function.  All callers updated to\n\tuse Module::rootModule.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Mark all functions being\n\tconstructed here as TREE_STATIC.\n\t(output_module_p): Remove function.  All callers updated to call\n\tModule::isRoot.\n\n2016-11-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (get_template_storage_info): Remove function.\n\t(setup_symbol_storage): Use Dsymbol::isInstantiated instead.\n\n2016-11-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_struct_literal): Handle anonymous fields.\n\t(build_class_instance): New functions.\n\t(find_aggregate_field): Update signature.  All callers updated.\n\t* d-todt.cc (dt_chainon): Mark as static.\n\t(dt_zeropad): Likewise.\n\t(dt_container): Likewise.\n\t(ClassReferenceExp::toInstanceDt): Remove function.\n\t(ClassReferenceExp::toDt2): Remove function.\n\n2016-11-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-tree.h (lang_decl): Remove readonly field.\n\t(DECL_LANG_READONLY): Remove macro.  All callers updated.\n\n2016-10-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (ClassReferenceExp::toSymbol): Use class record type for\n\tstatic symbol.\n\t* d-lang.cc (global_context): New static variable.\n\t(global_declarations): New static variable.\n\t(d_nametype): Pass built-in types to debug_hooks::type_decl.\n\t(d_add_global_declaration): Remove function, update all callers.\n\t(get_global_context): New function.\n\t(d_pushdecl): Push decls to global, or bindings list here.\n\t(StructDeclaration::toObjFile): Send type decl to d_pushdecl.\n\t(ClassDeclaration::toObjFile): Likewise.\n\t(InterfaceDeclaration::toObjFile): Likewise.\n\t(EnumDeclaration::toObjFile): Likewise.\n\t(FuncDeclaration::toObjFile): Send finished decl to d_pushdecl.\n\t(d_finish_symbol): Likewise.\n\t(emit_modref_hooks): Likewise.\n\t(d_comdat_linkage): Don't set DECL_COMDAT on non-public decls.\n\t(setup_symbol_storage): Don't set DECL_ABSTRACT_P on templates.\n\t(d_finish_compilation): Remove check for type decls.\n\t(build_type_decl): Don't add to global decl list, just call\n\trest_of_decl_compilation.\n\t* expr.cc (ExprVisitor::visit(ArrayLiteralExp)): Send finished decl to\n\td_pushdecl.\n\t* toir.cc (IRVisitor::visit(SwitchStatement)): Likewise.\n\t(IRVisitor::end_scope): Mark bind expr as having side effects.\n\t* typeinfo.cc (TypeInfoVisitor::visit(TypeInfoTupleDeclaration)): Send\n\tfinished decl to d_pushdecl.\n\n2016-10-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (layout_aggregate_type): Continue searching based on\n\taggregate members, not just fields.\n\t* types.cc (TypeVisitor::visit(TypeEnum)): Use void for opaque enums.\n\t(TypeVisitor::visit(TypeStruct)): Don't give opaque structs a size.\n\n2016-10-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(AssignExp)): Don't set TREE_ADDRESSABLE.\n\t* d-codegen.cc (build_assign): Handle setting up INIT_EXPR from a\n\tvalue returning via NRVO here instead.\n\n2016-10-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_build_call): Only convert CALL_EXPRs into a\n\tTARGET_EXPR if return type is TREE_ADDRESSABLE.\n\t(build_assign): Use TARGET_EXPR accessors.\n\t(compound_expr): Likewise.\n\n2016-10-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.h (d_types_same): Return early if types are identical.\n\n2016-10-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (FuncDeclaration::toThunkSymbol): Rename to make_thunk.\n\tAll callers updated.\n\t(finish_thunk): Update signature.\n\n2016-10-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.h (Thunk): Remove type, move offset field to ...\n\t* d-tree.h (lang_decl): ... here.  Replace Thunk field with a tree.\n\t(THUNK_LANG_OFFSET): New macro accessor.\n\t* d-lang.cc (copy_lang_decl): New function.\n\t* d-decls.cc (FuncDeclaration::toThunkSymbol): Use new thunk macros.\n\n2016-10-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (finish_thunk): Add assert that current_function_decl is\n\tnever set when function is called.\n\t(DeferredThunk): Remove type.\n\t(deferred_thunks): Remove variable.\n\t(write_deferred_thunks): Remove function.  All callers updated.\n\t(use_thunk): Remove function.\n\t(FuncDeclaration::toThunkSymbol): Call finish_thunk when done.\n\n2016-10-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (deferred_thunks): Move to d-decls.cc.\n\t(write_deferred_thunks): Likewise.\n\t(use_thunk): Likewise.  Mark as static.\n\t(thunk_labelno): Likewise.\n\t(make_alias_for_thunk): Likewise.\n\t(finish_thunk): Likewise.\n\n2016-10-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (setup_symbol_storage): Remove unused parameters.\n\n2016-10-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (ClassReferenceExp::toSymbol): Rename to\n\tbuild_new_class_expr.  All callers updated.\n\t(StructLiteralExp::toSymbol): Remove function.  Inline into caller ...\n\t* expr.cc (ExprVisitor::visit(AddrExpr)): ... here.\n\n2016-10-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (TypeInfoDeclaration::toSymbol): Rename to\n\tget_typeinfo_decl.  All callers updated.\n\t(TypeInfoDeclVisitor): New visitor helper for get_typeinfo_decl.\n\t* d-codegen.cc (get_decl_tree): Add check for building typeinfo decls.\n\n2016-10-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (AggregateDeclaration::toInitializer): Rename to\n\taggregate_initializer.  All callers updated.\n\t(EnumDeclaration::toInitializer): Rename to enum_initializer.\n\t(Module::toSymbol): Rename to get_moduleinfo_decl.\n\t(ClassDeclaration::toSymbol): Rename to get_classinfo_decl.\n\t(InterfaceDeclaration::toSymbol): Merge into get_classinfo_decl.\n\n2016-10-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (FuncDeclaration::toSymbol): Remove saving of current\n\tmodule decl before calling semantic.\n\t(StructLiteralExp::toSymbol): Don't handle sinit.\n\t(ClassReferenceExp::toSymbol): Likewise.\n\t(AggregateDeclaration::toInitializer): Likewise.\n\t(EnumDeclaration::toInitializer): Likewise.\n\t* d-glue.cc (toInitializer): Remove function.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Remove saving of current\n\tmodule decl before calling semantic.\n\t* expr.cc (ExprVisitor::visit(CallExpr)): Replace accesses of sinit\n\tfield with useStaticInit.\n\t(ExprVisitor::visit(StructLiteralExp)): Likewise.\n\n2016-10-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (ClassDeclaration::toVtblSymbol): Rename to\n\tget_vtable_decl.  All callers updated.\n\n2016-10-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (setup_symbol_storage): Move function to ...\n\t* d-decls.cc (setup_symbol_storage): ... here.  Mark as static.\n\t(get_template_storage_info): Likewise.\n\n2016-10-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (call_by_alias_p): Check whether caller and callee are\n\tnested in the same parent function.\n\t* expr.cc (ExprVisitor::visit(CallExp)): Set TREE_PUBLIC directly\n\tinstead of calling setup_symbol_storage.\n\n2016-10-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (VarDeclaration::toObjFile): Always generate\n\tDECL_INITIAL for all kinds of var decls.\n\t* d-codegen.cc (build_address): Use the DECL_INITIAL directly if\n\ttaking the address of a CONST_DECL.\n\n2016-10-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-tree.h (DECL_LANG_TREE): Remove macro.  All callers updated.\n\n2016-10-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.h (Symbol): Remove struct.  Update all functions to return\n\ta tree instead.  Remove all new allocations of Symbol.\n\t* d-tree.h (DECL_LANG_READONLY): Update accessor.\n\t(DECL_LANG_INITIAL): Likewise.\n\t(DECL_LANG_TREE): Likewise.\n\t(SET_DECL_LANG_FRAME_FIELD): Likewise.\n\t(DECL_LANG_FRAME_FIELD): Likewise.\n\t(SET_DECL_LANG_NRVO): Likewise.\n\t(DECL_LANG_NRVO): Likewise.\n\t(DECL_LANG_THUNKS): Likewise.\n\t(DECL_LANG_FRAMEINFO): Likewise.\n\n2016-10-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.h (Symbol): Remove symbol identifier field.\n\t* d-tree.h (DECL_LANG_IDENTIFIER): Remove macro.  Update callers to\n\tinstead use DECL_ASSEMBLER_NAME.\n\t(DECL_LANG_PRETTY_NAME): Remove macro.\n\n2016-09-26  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-objfile.cc (d_finish_function): Handle template mixins (issue 231).\n\n2016-09-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (Dsymbol::toSymbolX): Remove function, update all callers\n\tto use ...\n\t(make_internal_name): ... New function.\n\t* d-objfile.h (Symbol): Replace char* fields with tree.\n\t* d-tree.h (lang_identifier): Add pretty_ident field.\n\t(IDENTIFIER_PRETTY_NAME): New macro accessor.\n\t(DECL_LANG_PRETTY_NAME): Update to use IDENTIFIER_PRETTY_NAME.\n\n2016-09-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.h (Symbol): Move declaration-specific fields to ...\n\t* d-tree.h (lang_decl): ... here.\n\t(DECL_LANG_READONLY): Update to reference lang_decl field.\n\t(DECL_LANG_INITIAL): Likewise.\n\t(DECL_LANG_FRAME_FIELD): Likewise.\n\t(DECL_LANG_NRVO): Likewise.\n\t(DECL_LANG_THUNKS): Likewise.\n\t(DECL_LANG_FRAMEINFO): Likewise.\n\t(SET_DECL_LANG_FRAME_FIELD): New setter macro, update all callers.\n\t(SET_DECL_LANG_NRVO): Likewise.\n\n2016-09-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (d_build_builtins_module): Set DECL_LANG_SPECIFIC\n\tbefore using any DECL_LANG accessor macros.\n\t(maybe_set_builtin_1): Likewise.\n\t* d-codegen.cc (maybe_set_intrinsic): Likewise.\n\t(layout_aggregate_members): Likewise.\n\td-decls.cc (VarDeclaration::toSymbol): Likewise.\n\t(FuncDeclaration::toThunkSymbol): Likewise.\n\t(ClassDeclaration::toSymbol): Likewise.\n\t(InterfaceDeclaration::toSymbol): Likewise.\n\t(Module::toSymbol): Likewise.\n\t(StructLiteralExp::toSymbol): Likewise.\n\t(ClassReferenceExp::toSymbol): Likewise.\n\t(ClassDeclaration::toVtblSymbol): Likewise.\n\t(AggregateDeclaration::toInitializer): Likewise.\n\t(EnumDeclaration::toInitializer): Likewise.\n\n2016-09-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-tree.h (DECL_LANG_IDENTIFIER): New macro accessor, use instead of\n\tdirect field accesses.\n\t(DECL_LANG_PRETTY_NAME): Likewise.\n\t(DECL_LANG_READONLY): Likewise.\n\t(DECL_LANG_INITIAL): Likewise.\n\t(DECL_LANG_TREE): Likewise.\n\t(DECL_LANG_FRAME_FIELD): Likewise.\n\t(DECL_LANG_NRVO): Likewise.\n\t(DECL_LANG_THUNKS): Likewise.\n\t(DECL_LANG_FRAMEINFO): Likewise.\n\n2016-09-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* imports.cc (ImportVisitor::visit(ScopeDsymbol)): New visit method.\n\n2016-09-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-todt.cc (ArrayInitializer::toDt): Update to use build_expr.\n\t* d-codegen.cc (d_array_value): Don't override default const and\n\tstatic bits for array constructors.\n\n2016-09-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (lower_struct_comparison): Don't compare vectors in the\n\tsame way as integers.\n\n2016-09-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-todt.cc (Type::toDt): Remove function, inline into callers.\n\t(TypeVector::toDt): Likewise.\n\t(TypeSArray::toDt): Likewise.\n\t(TypeStruct::toDt): Likewise.\n\n2016-09-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (FuncDeclaration::toSymbol): Save current module decl\n\tbefore calling function semantic.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Likewise.\n\n2016-09-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* types.cc: Document and reformat file.\n\n2016-09-10  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-objfile.cc (setup_symbol_storage): Setup TREE_PUBLIC before\n\tcalling decl_default_tls_model.\n\t* d-typeinfo.cc (TypeInfoVisitor::find_field): Move method...\n\t* d-codegen.cc (find_aggregate_field): here.\n\t* d-objfile.cc (build_simple_function): Extract some code into new\n\tfunction.\n\t(build_simple_function_decl): Extracted from build_simple_function.\n\t* d-objfile.cc (build_moduleinfo): Split into emit_moduleinfo_hooks\n\tand emit_modref_hooks.\n\t(build_dso_registry_var): New function.\n\t(emit_dso_registry_cdtor): Likewise.\n\t(emit_dso_registry_helpers): Likewise.\n\t(emit_dso_registry_hooks): Likewise.\n\t(emit_moduleinfo_hooks): Only emit hooks if required druntime functions\n\tare available.\n\t* d-objfile.cc (Module::genmoduleinfo): Rename to\n\tbuild_moduleinfo_symbol.\n\t(emit_moduleinfo_hooks): rename to Module::genmoduleinfo.\n\t(Module::genmoduleinfo): only call build_moduleinfo_symbol when\n\temitting module info registry code.\n\t* d-spec.c (lang_specific_driver): Add -shared-libphobos option,\n\tdefault to static libphobos.\n\t* d-lang.opt: Likewise.\n\t* d-spec.c: Rename libgphobos2 to libgphobos.\n\n2016-07-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (get_frameinfo): Use hasNestedFrameRefs to determine\n\twhether a frame should be created.\n\n2016-07-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Always convert the\n\tDECL_RESULT of NRVO-capable functions into reference decls.\n\n2016-06-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-attribs.c (handle_nonnull_attribute): Accept the nonnull\n\tattribute in type-generic builtins.\n\t* d-codegen.cc (d_build_call): Check AGGREGATE_TYPE_P before testing\n\tfor aggregate_value_p.\n\n2016-06-20  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-lang.cc (d_handle_option): Add new -ftransition=dip25 and\n\t-fmax-error-messages switches.\n\t* lang.opt: Likewise.\n\n2016-06-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (get_decl_tree): Remove assert for RESULT_DECL.\n\t(convert_for_argument): Handle lazy arguments early.\n\t(argument_reference_p): Handle types marked TREE_ADDRESSABLE.\n\t(lvalue_p): Add case for TARGET_EXPR.\n\t(d_mark_addressable): Likewise.\n\t(build_assign): Likewise.\n\t(compound_expr): Likewise.\n\t(build_target_expr): New function.\n\t(d_build_call): Always set CALL_EXPR_RETURN_SLOT_OPT for all calls\n\tthat return an aggregate in memory.\n\t* d-decls.cc (VarDeclaration::toSymbol): Handle reference parameters.\n\t* d-lang.cc (d_gimplify_expr): Handle taking address of constructor.\n\t* d-objfile.cc (FuncDeclaration::toObjFile): Handle reference return.\n\t* expr.cc (ExprVisitor::visit(AssignExp)): Mark LHS as addressable if\n\tRHS assignment is a returned aggregate.\n\t* types.cc (TypeVisitor::visit(TypeStruct)): Mark the RECORD_TYPE of\n\tnon-trivial structs as TREE_ADDRESSABLE.\n\t(TypeVisitor::visit(TypeClass)): Mark all classes as TREE_ADDRESSABLE.\n\t(TypeVisitor::visit(TypeFunction)): Don't set TREE_ADDRESSABLE.\n\t(TypeVisitor::visit(TypeDelegate)): Likewise.\n\n2016-06-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (lvalue_p): Add more cases to look for.\n\t(build_address): Mark expression as addressable after stabilizing.\n\t(d_mark_addressable): Remove special cases.\n\t(d_mark_used): Add cases for other kinds of DECLs.\n\t(build_struct_comparison): Stabilize before saving.\n\t(modify_expr): Remove overload.  Updated all callers.\n\t(build_vinit): Remove function.  Updated all callers to use ...\n\t(build_assign): ... New function.\n\t(lvalue_p): Remove tests in default case.\n\t* expr.cc (build_expr_dtor): Rewrite assignments to elide a temporary.\n\n2016-06-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (make_temp): Rename to d_save_expr.\n\t(maybe_make_temp): Remove function.\n\tUpdated all callers to use d_save_expr().\n\t(vcompound_expr): Remove function.\n\tUpdated all callers to use compound_expr().\n\t(maybe_compound_expr): Likewise.\n\t(maybe_vcompound_expr): Likewise.\n\t(vmodify_expr): Remove function.\n\tUpdated all callers to use modify_expr().\n\t(lvalue_p): New function.\n\n2016-06-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (add_stmt): Don't add statements without side effects.\n\tPush each COMPOUND_EXPR as a separate statement.\n\t(build_local_temp): Use input_location.\n\t(create_temporary_var): Likewise.\n\t(d_has_side_effects): Remove function.\n\tUpdated all callers to use TREE_SIDE_EFFECTS.\n\t(stabilize_expr): New function.\n\tUpdated all routines that check for COMPOUND_EXPR to use it.\n\t* expr.cc (ExprVisitor::visit(EqualExp)): Use maybe_make_temp to save\n\texpressions.  Use build_boolop for constructed conditions.\n\t(ExprVisitor::visit(CatAssignExp)): Stabilize RHS before assignment.\n\t(ExprVisitor::visit(NewExp)): Don't always create SAVE_EXPR.\n\t(ExprVisitor::visit(AssocArrayLiteralExp)): Likewise.\n\t(ExprVisitor::visit(ArrayLiteralExp)): Evaluate elements before\n\tappending to constructor fields.\n\t(ExprVisitor::visit(StructLiteralExp)): Likewise.\n\n2016-06-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-convert.cc (d_build_truthvalue_op): Fold truthvalue operation.\n\t(d_truthvalue_conversion): Use zero constant of expression type.\n\n2016-06-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_address): Handle ERROR_MARK and COMPOUND_EXPR.\n\t(build_nop): Likewise.\n\t(indirect_ref): Likewise.\n\t(build_deref): Likewise.\n\t(d_build_call): Only create temporaries if more than one argument has\n\tside effects.\n\t* expr.cc (get_compound_value): Remove function.\n\t(build_expr_dtor): Wrap cleanups in a TRY_FINALLY_EXPR only if the\n\texpression has side effects.\n\n2016-06-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_GLUE_OBJS): Remove d-typinf.o, add typeinfo.o.\n\t* d-codegen.cc (build_typeinfo): Move to ...\n\t* typeinfo.cc: ... here.  New file.\n\t* d-objfile.cc (TypeInfoDeclaration::toObjFile): Use layout_typeinfo.\n\t* d-todt.cc (verify_structsize): Remove function.\n\t(TypeInfoDeclaration::toDt): Remove function and overrides.\n\t* d-typinf.cc: Remove file.  Contents moved to typeinfo.cc.\n\t* expr.cc (ExprVisitor::visit(DeleteExp)): Use build_typeinfo.\n\t(ExprVisitor::visit(NewExp)): Likewise.\n\n2016-06-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* dfrontend: Update to D front-end version 2.068.\n\t* d-codegen.cc (insert_type_modifiers): Don't build TYPE_QUAL_VOLATILE\n\ttypes.  Set TYPE_SHARED instead.\n\t(insert_aggregate_field): Propagate TYPE_SHARED to TREE_ADDRESSABLE.\n\t(array_bounds_check): Use BOUNDSCHECK interface.\n\t* d-lang.cc (d_init_options): Likewise.\n\t(d_init): Likewise.\n\t(d_handle_option): Likewise.\n\t(d_post_options): Likewise.\n\t* d-decls.cc (VarDeclaration::toSymbol): Propagate TYPE_SHARED_to\n\tTREE_ADDRESSABLE.\n\t* d-objfile.cc (ClassDeclaration::toObjFile): Make overload shadowing\n\tan error.  Remove call to _d_hidden_func.\n\t(TypeInfoDeclaration::toObjFile): Updated template emission rules.\n\t(FuncDeclaration::toObjFile): Likewise.\n\t* d-port.cc (Port::readwordLE): New function.\n\t(Port::readwordBE): New function.\n\t(Port::readlongLE): New function.\n\t(Port::readlongBE): New function.\n\t* d-todt.cc (dt_container2): Handle error_mark_node.\n\t(dt_container): Likewise.\n\t(TypeInfoStructDeclaration::toDt): Updated template emission rules.\n\t* d-typinf.cc (genTypeInfo): Likewise.\n\t(getTypeInfo): Remove function.\n\t(getTypeInfoType): New function.\n\t(isSpeculativeType): New function.\n\t* d-tree.h (TYPE_SHARED): New macro.\n\t* expr.cc (ExprVisitor::visit(CondExp)): Don't generate dtors in\n\tcondition expression.\n\t(ExprVisitor::visit(AssignExp)): Update for frontend changes.\n\t(ExprVisitor::visit(DeleteExp)): Likewise.\n\t(ExprVisitor::visit(CallExp)): Likewise.\n\t(ExprVisitor::visit(DelegateExp)): Likewise.\n\t(ExprVisitor::visit(TypeidExp)): New function.\n\t* lang.opt (bounds_check_set_manually): Remove variable.\n\t(ftransition=complex): New option.\n\t* runtime.def (HIDDEN_FUNC): Remove runtime function.\n\n2016-06-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_alignment_field): New function.\n\t(build_struct_literal): Update signature, updated all callers.\n\tAdd anonymous fields to fill alignment holes in constructor.\n\t(fill_alignment_field): Remove function.\n\t(fill_alignment_holes): Remove function.\n\t(finish_aggregate_type): Don't add anonymous fields.\n\n2016-06-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_build_call): Separate parameter to pass from it's\n\tconstruction expression.\n\t* expr.cc (build_dtor_list): New function.\n\t(get_compound_value): New function.\n\t(build_expr_dtor): Update to use helper functions.\n\t(build_return_dtor): New function.\n\t* toir.cc (IRVisitor::visit(ReturnStatement)): Use it.\n\n2016-06-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_deref): Handle ERROR_MARK nodes early.\n\t(build_array_index): Likewise.\n\n2016-05-29  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* toir.cc (IRVisitor::visit(SwitchStatement)): Set correct type for the\n\tstring table for switch(string) statements.\n\n2016-05-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (convert_expr): Return empty constructor for null to\n\tassociative array conversions.\n\t* expr.cc (ExprVisitor::visit(NullExp)): Likewise.\n\n2016-05-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_struct_literal): Don't set TREE_STATIC.\n\t(build_boolop): Remove side effects from aggregate types only.\n\t* expr.cc (ExprVisitor::visit(ArrayLiteralExp)): Don't check\n\tinitializer_constant_valid_p until after constructor is built.\n\t(ExprVisitor::visit(StructLiteralExp)): Likewise.\n\n2016-05-16  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(AssignExp)): Build the rhs constructor\n\tbefore the lhs declaration.\n\t(ExprVisitor::visit(DeclarationExp)): Compile the declaration and\n\tinitializer before pushing it to vars_in_scope.\n\t(build_expr_dtor): Compound all dtors in reverse.\n\n2016-05-16  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* expr.cc (ExprVisitor::visit(IdentityExp*)): Remove side-effects\n\tbefore comparing two floating point types.\n\t* d-codegen.cc (build_struct_comparison): Remove side-effects\n\tbefore comparing two values.\n\t(build_boolop): Likewise.\n\n2016-05-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-todt.cc (Expression::toDt): Remove function and all overrides.\n\tUpdate all callers to use build_expr.\n\t* expr.cc (ExprVisitor::visit(SymOffExp)): Move check for non-constant\n\texpressions in static initializer data to ...\n\t(build_expr): ... here.\n\t* toir.cc (IRVisitor::visit(SwitchStatement)): Build array of indexes\n\tdirectly using build_artificial_decl.\n\n2016-05-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(IdentityExp*)): Remove side-effects\n\tbefore comparing two dynamic arrays.\n\n2016-05-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (get_decl_tree): First check if cfun is set.\n\t* d-todt.cc (StructLiteralExp::toDt): Update call to build_expr.\n\t(SymOffExp::toDt): Likewise.\n\t(VarExp::toDt): Likewise.\n\t(FuncExp::toDt): Likewise.\n\t(VectorExp::toDt): Likewise.\n\t* expr.cc (ExprVisitor::visit(SymbolExp)): Remove function.\n\t(ExprVisitor::visit(SymOffExp)): New function.\n\t(ExprVisitor::visit(VarExp)): New function.\n\t(ExprVisitor::visit(StructLiteralExp)): Don't return static\n\tinitializer symbol if constant literal requested.\n\n2016-05-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_struct_literal): Maybe set TREE_CONSTANT or\n\tTREE_STATIC on the returned constructor.\n\tAllow building struct literals with initializer list out of order.\n\tAdd check and error when initializer overlaps previous field.\n\tDon't explicitly set empty initializers for anonymous aggregates or\n\tartificial fields.\n\n2016-05-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_array_from_val): New function.\n\t* expr.cc (ExprVisitor::visit(StructLiteralExp)): Use it.\n\n2016-05-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (convert_expr): Use build_nop to cast between two\n\tstatic arrays of the same size.\n\t* d-todt.cc (IntegerExp::toDt): Update call to build_expr.\n\t(RealExp::toDt): Likewise.\n\t(ComplexExp::toDt): Likewise.\n\t(StringExp::toDt): Likewise.\n\t(NullExp::toDt): Use build_expr to generate initializer.\n\t(ArrayLiteralExp::toDt): Likewise.\n\t(CastExp::toDt): Likewise.\n\t(ClassReferenceExp::toDt): Likewise.\n\t(ClassReferenceExp::toDtI): Remove function.\n\t* expr.cc (ExprVisitor::visit(CastExp)): Forward constp to the next\n\tleaf expression in the tree.\n\t(ExprVisitor::visit(AddrExp)): Likewise.\n\t(ExprVisitor::visit(FuncExp)): Likewise.\n\t(ExprVisitor::visit(ArrayLiteralExp)): Likewise.\n\t(ExprVisitor::visit(StructLiteralExp)): Likewise.\n\t(ExprVisitor::visit(VectorExp)): Likewise.\n\t(ExprVisitor::visit(ClassReferenceExp)): Adjust reference for constp.\n\n2016-05-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (get_unique_name): Remove function.\n\t(build_artificial_decl): New function.\n\t(d_finish_symbol): Use build_artificial_decl.\n\t(build_moduleinfo): Likewise.\n\t* d-decls.cc (StructLiteralExp::toSymbol): Likewise.\n\t(ClassReferenceExp::toSymbol): Likewise.\n\n2016-05-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(BinExp)): New function.\n\t(ExprVisitor::visit(XorExp)): Remove function.\n\t(ExprVisitor::visit(OrExp)): Likewise.\n\t(ExprVisitor::visit(AndExp)): Likewise.\n\t(ExprVisitor::visit(UshrExp)): Likewise.\n\t(ExprVisitor::visit(ShrExp)): Likewise.\n\t(ExprVisitor::visit(ShlExp)): Likewise.\n\t(ExprVisitor::visit(ModExp)): Likewise.\n\t(ExprVisitor::visit(DivExp)): Likewise.\n\t(ExprVisitor::visit(MulExp)): Likewise.\n\t(ExprVisitor::visit(MinExp)): Likewise.\n\t(ExprVisitor::visit(AddExp)): Likewise.\n\t(ExprVisitor::visit(BinAssignExp)): New function.\n\t(ExprVisitor::visit(XorAssignExp)): Remove function.\n\t(ExprVisitor::visit(OrAssignExp)): Likewise.\n\t(ExprVisitor::visit(AndAssignExp)): Likewise.\n\t(ExprVisitor::visit(ShrAssignExp)): Likewise.\n\t(ExprVisitor::visit(ShlAssignExp)): Likewise.\n\t(ExprVisitor::visit(ModAssignExp)): Likewise.\n\t(ExprVisitor::visit(DivAssignExp)): Likewise.\n\t(ExprVisitor::visit(MulAssignExp)): Likewise.\n\t(ExprVisitor::visit(PowAssignExp)): Likewise.\n\t(ExprVisitor::visit(MinAssignExp)): Likewise.\n\t(ExprVisitor::visit(AddAssignExp)): Likewise.\n\n2016-05-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::ExprVisitor): Update signature.\n\t(ExprVisitor::visit(AddrExp)): Handle constant expressions.\n\t(ExprVisitor::visit(FuncExp)): Likewise.\n\t(ExprVisitor::visit(ComplexExp)): Likewise.\n\t(ExprVisitor::visit(StringExp)): Likewise.\n\t(ExprVisitor::visit(ArrayLiteralExp)): Likewise.\n\t(ExprVisitor::visit(StructLiteralExp)): Likewise.\n\t(ExprVisitor::visit(NullExp)): Likewise.\n\t(ExprVisitor::visit(ClassReferenceExp)): Likewise.\n\t(build_expr): Update signature.\n\n2016-05-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_GLUE_OBJS): Add d/expr.o.\n\tRemove d/d-elem.o\n\t* d-codegen.cc (size_mult_expr): New function.\n\t* d-tree.h (build_expr): New function, update all callers to toElem.\n\t(build_expr_dtor): New function, update all callers to toElemDtor.\n\t* expr.cc: New file.\n\t* d-elem.cc: Remove file.\n\n2016-05-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-target.cc (Target::init): Target::realpad value should be size\n\tminus precision.\n\n2016-04-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (finish_aggregate_type): Use SET_TYPE_ALIGN.\n\t* types.cc (TypeVisitor::visit(TypeStruct)): Likewise.\n\t* d-decls.cc (ClassDeclaration::toVtblSymbol): Use SET_DECL_ALIGN.\n\t* d-objfile.cc (d_finish_symbol): Likewise.\n\t* d-target.cc (Target::fieldalign): Likewise.\n\n2016-04-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-todt.cc (TypeSArray::toDtElem): Remove special handling for\n\tarrays of vectors.\n\n2016-04-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (build_dtype): Make function static.\n\t* d-lang.cc (d_init_exceptions): Remove function.\n\t* d-codegen.h: Move visitor declarations to ...\n\t* d-tree.h: ... here.\n\t(lang_decl): Remove `d_` prefix from fields.\n\t(lang_type): Likewise.\n\t* d-lang.cc (build_d_type_lang_specific): Rename to build_lang_type.\n\t(build_d_decl_lang_specific): Rename to build_lang_decl.\n\t* imports.cc: Update includes.\n\n2016-03-29  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* d-objfile.cc (d_comdat_linkage): Rewrite template duplicate\n\thandling to generate only one backend tree for all duplicates.\n\t(FuncDeclaration::toObjFile): Likewise.\n\t(VarDeclaration::toObjFile): Likewise.\n\t* d-decls.cc (FuncDeclaration::toSymbol): Likewise.\n\t(VarDeclaration::toSymbol): Likewise.\n\t* d-objfile.cc (get_template_storage_info): Extract function from\n\tsetup_symbol_storage.\n\t(setup_symbol_storage): Likewise.\n\t* d-tree.h (lang_identifier): Add field for Dsymbol.\n\t(IDENTIFIER_LANG_SPECIFIC): New macro.\n\t(IDENTIFIER_DSYMBOL): Likewise.\n\n2016-03-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (fill_alignment_field): Call layout_decl on field.\n\t(finish_aggregate_type): Add assertion that TYPE_MODE is equal.\n\n2016-03-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (convert_expr): Replace call build_integer_cst with\n\tsize_int.\n\t(convert_for_assignment): Likewise.\n\t(build_struct_comparison): Likewise.\n\t(d_assert_call): Likewise.\n\t* d-elem.cc (IdentityExp::toElem): Likewise.\n\t(AssignExp::toElem): Likewise.\n\t(IndexExp::toElem): Likewise.\n\t(SymbolExp::toElem): Likewise.\n\t(NewExp::toElem): Likewise.\n\t(ArrayLiteralExp::toElem): Likewise.\n\t(AssocArrayLiteralExp::toElem): Likewise.\n\n2016-03-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-tree.h (CLASS_TYPE_P): New macro.\n\t* d-codegen.cc (build_struct_literal): Check RECORD_OR_UNION_TYPE_P\n\tbefore testing ANON_AGGR_TYPE_P.\n\t(fill_alignment_field): New function.\n\t(fill_alignment_holes): New function.\n\t(finish_aggregate_type): Call fill_alignment_holes before computing\n\tbackend type mode.\n\n2016-03-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-tree.h (D_METHOD_CALL_EXPR): Removed `D_' prefix from macro,\n\tupdated all callers.\n\t(D_TYPE_IMAGINARY_FLOAT): Likewise.\n\t(D_LABEL_VARIABLE_CASE): Likewise.\n\t* d-codegen.cc (build_delegate_cst): Always return valid constructor.\n\t(get_object_method): Remove function.\n\t(build_vindex_ref): New function.\n\t* d-elem.cc (FuncExp::toElem): Use the real function pointer type when\n\tconverting to delegate.\n\t(CallExp::toElem): Handle setting up virtual functions directly.\n\t(DelegateExp::toElem): Likewise.\n\t(DotVarExp::toElem): Remove handling of virtual functions.\n\n2016-03-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.h (lang_dtype): Remove function.\n\t(lang_ddecl): Remove function.\n\t* d-tree.h (TYPE_LANG_FRONTEND): New macro, replace all uses of\n\tlang_dtype function.\n\t(DECL_LANG_FRONTEND): New macro.\n\t* d-attribs.c: Update includes.\n\t* d-builtins.cc: Likewise.\n\t* d-codegen.cc: Likewise.\n\t* d-incpath.cc: Likewise.\n\t* d-lang.cc: Likewise.\n\t* d-objfile.cc: Likewise.\n\n2016-03-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.h (function_type_p): Remove function.\n\t* d-codegen.cc (d_build_call): Use FUNC_OR_METHOD_P macro.\n\t(build_bounds_condition): Update signature.\n\t(d_assert_call): Likewise.\n\t(insert_aggregate_field): Likewise.\n\t* d-objfile.cc (get_linemap): Likewise.\n\t* d-lang.h: Remove file, updated all includes.  Moved forward\n\tdeclarations of types and functions to ...\n\t* d-tree.h: ... here.\n\n2016-03-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_checked_index): Remove function.\n\t(d_bounds_condition): Remove function.\n\t(build_bounds_condition): New function.\n\t* d-elem.cc (IndexExp::toElem): Use build_bounds_condition.\n\t(SliceExp::toElem): Likewise.\n\t(EqualExp::toElem): Convert expressions to dynamic arrays when\n\tinlining comparison.  Don't pass zero length arrays to memcmp.\n\n2016-03-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_array_convert): New function overload.\n\t* d-elem.cc (CatExp::toElem): Call new runtime function _d_arraycatnTX\n\twhen flattening multiple concatenations.\n\t(NewExp::toElem): Update call construction for new signatures of\n\truntime functions _d_newarraymTX and _d_newarraymiTX.\n\t* runtime.def (NEWARRAYMTX): Update signature.\n\t(NEWARRAYMITX): Likewise,\n\t(ARRAYCATNT): Remove runtime function.\n\t(ARRAYCATNTX): New runtime function.\n\n2016-03-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* imports.cc (ImportVisitor::visit(Declaration)): Don't assume toSymbol\n\tmethod will cache it's result.\n\n2016-03-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* dfrontend: Update root library to 2.068.\n\t* Make-lang.in (D_DMD_OBJS): Add newdelete.o\n\t* d-target.cc (Target::classinfosize): New variable, replaces all uses\n\tof global CLASSINFO_SIZE.\n\t(Target::init): Initialize it.\n\t* d-decls.cc (ClassInfoDeclaration::toSymbol): Remove function.\n\n2016-03-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* dfrontend: Update to D front-end version 2.067.\n\t* Make-lang.in (D_DMD_OBJS): Add new frontend sources.\n\t* d-builtins.cc (d_build_builtins_module): Update signature.\n\t(maybe_set_builtin): Rename to d_maybe_set_builtin, update signature.\n\t(d_gcc_magic_module): Remove function.\n\t* d-codegen.cc (expand_volatile_load): New function.\n\t(expand_volatile_store): New function.\n\t(expand_intrinsic): Handle volatileLoad and volatileStore intrinsics.\n\t* d-decls.cc (Module::toModuleAssert): Remove function.\n\t(Module::toModuleUnittest): Remove function.\n\t(Module::toModuleArray): Remove function.\n\t(TypeAArray::aaGetSymbol): Remove function.\n\t* d-elem.cc (AssignExp::toElem): Call _d_arrayassign_{l,r} when\n\tgenerating dynamic array assignment.\n\t(IndexExp::toElem): Call _aaGetY when indexing an associative array.\n\t(SliceExp::toElem): Use known CTFE result to check whether bounds\n\tchecks are necessary.\n\t(DeleteExp::toElem): Call _d_delstruct when deleting a struct pointer.\n\t(Expression::toElemDtor): Don't run cleanup of temporary if it's\n\tconstructor thrown an exception.\n\t(NewExp::toElem): Handle special construction of new() arguments.\n\t* d-glue.cc (Loc::Loc): Update signature.\n\t(error): Likewise.\n\t(toInitializer): New function.\n\t* d-lang.cc (d_handle_option): Replace deprecated handlers.\n\t(d_post_options): Set flag_max_errors.\n\t(d_parse_file): Process any modules marked as builtin.\n\t* d-objfile.cc (ClassDeclaration::toObjFile): Don't write out ctors\n\tin the vtable marked @disable.\n\t* d-target.cc (Target::loadModule): New function.\n\t(Target::checkVectorType): New function.\n\t* d-specs.c (lang_specific_driver): Handle -v option.\n\t* lang-specs.h: Pass -v option to to frontend.\n\n2016-03-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* imports.cc: New file.\n\t* d-decls.cc (Dsymbol::toImport): Remove function, update all callers\n\tto use build_import_decl.\n\n2016-03-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (gcc_attribute_p): New function.\n\t(output_declaration_p): Inline into FuncDeclaration::ObjFile.\n\t(unnest_function): Likewise.\n\t(FuncDeclaration::toObjFile): Remove named parameter, update all\n\tcallers to ignore it.\n\t(d_comdat_group): Use DECL_ASSEMBLER_NAME for the comdat group.\n\t(d_comdat_linkage): Catch duplicate instantiations of templates, put\n\tthem in the same comdat group.\n\t(setup_symbol_storage): Mark templates not to be written as abstract.\n\t(d_finish_function): Don't send DECL_ABSTRACT_P functions to backend.\n\t(d_finish_compilation): Mark all symbols as needed.\n\n\t* d-objfile.cc: Remove redundant bool parameter from all lowering\n\troutines for symbols, update all callers.\n\n2016-02-22  Eugene Wissner <belka@caraus.de>\n\n\t* d-lang.cc (d_init): Remove short_double parameter from\n\tbuild_common_tree_nodes.\n\n2016-02-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* intrinsics.def: Split signature macros into three groups.\n\tAttributes, types, and helper generators.\n\t* d-elem.cc (needsPostblit): Change signature to return boolean,\n\tupdated all callers.\n\t(AssignExp::toElem): Don't assign destination to a temporary in\n\tarraycopy call.\n\t* toir.cc (IRVisior::visit(ThrowStatement)): Use NOP_EXPR cast to\n\tconvert thrown exception to Object.\n\t(IRVisitor::visit(TryCatchStatement)): Use NOP_EXPR cast to convert\n\tcaught Object to thrown exception.\n\t* d-codegen.cc (void_okay_p): Lazily build the convert to type.\n\t* d-lang.cc (parse_int): Remove function.\n\t(d_handle_option): Use integral_argument to parse numbers.\n\n\t* d-codegen.cc (lower_struct_comparison): Built custom type if\n\tlang_hooks.types.type_for_mode returns nothing.\n\t* d-lang.cc (d_type_for_mode): Always support cent/ucent modes.\n\t(d_type_for_size): Add support for cent/ucent precision types.\n\t(d_signed_or_unsigned_type): Always support cent/ucent precisions.\n\n\t* d-codegen.cc (d_build_call): Remove type promotion handling for\n\tvariadic arguments.\n\t(expand_intrinsic_vaarg): Likewise.\n\t* d-lang.cc (d_type_promotes_to): Likewise.\n\n\t* d-elem.cc (AddrExp::toElem): Take address of the static const symbol\n\tfor the struct literal,  not the const constructor.\n\t(CallExp::toElem): Don't pass generated static struct literal symbol\n\tas the object parameter for DotVar call expressions.\n\n\t* d-codegen.cc (type_va_array): New function.\n\t(declaration_type_kind): Remove function.\n\t(declaration_reference_p): New function, update all callers of\n\tdeclaration_type_kind.\n\t(argument_type_kind): Remove function.\n\t(argument_reference_p): New function, update all callers of\n\targument_type_kind.\n\t(build_address): Remove special handling of static array va_list.\n\t* d-codegen.h (type_kind): Remove enum.\n\n2016-02-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_condition): New function.  Update all callers\n\tthat generate a COND_EXPR that returns a value to use it.\n\t(build_vcondition): New function.  Update all callers that generate a\n\tvoid COND_EXPR to use it.\n\t* toir.cc (IRVisitor::visit(DoStatement)): Build a COND_EXPR instead\n\tof an EXIT_EXPR to break from the loop.\n\t(IRVisitor::visit(ForStatement)): Likewise.\n\n2016-02-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc: Remove redundant IRState parameter from all lowering\n\troutines for expressions, update all callers.\n\n2016-02-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_array_set): Use POSTINCREMENT_EXPR to adjust\n\tarray pointer.\n\t(identity_compare_p): New function.\n\t(build_struct_memcmp): Refactor into ...\n\t(lower_struct_comparison): ... New function.\n\t(build_struct_comparison): New function.\n\t(build_array_struct_comparison): New function.\n\t* d-elem.cc (IdentityExp::toElem): Use build_struct_comparison for\n\tRECORD_TYPE values.\n\t(EqualExp::toElem): Likewise.\n\tUse memcmp for array of structs that pass test for identity_compare_p,\n\tor fallback to build_array_struct_comparison.\n\t(NewExp::toElem): Remove setting of StructLiteralExp::fillHoles.\n\t(StructLiteralExp::toElem): Ignore StructLiteralExp::fillHoles, unless\n\tbuilding a union literal.\n\n2016-02-03  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-elem.cc (AssignExp::toElem): Pass parameters for arraycopy and\n\tarrayassign in the correct order.\n\n2016-01-31  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* longdouble.h (longdouble): Use one contiguous array for the\n\treal_value data payload.\n\n2016-01-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* toir.cc (IRVisitor::visit (ExtAsmStatement): Do validation of input\n\tand output constraints, marking operands as addressable if requested.\n\n2016-01-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (empty_aggregate_p): New function.\n\t(d_build_call): Don't pass empty aggregates by value.\n\t(build_struct_memcmp): Don't compare empty aggregates by value.\n\t* d-elem.cc (IdentityExp::toElem): Likewise.\n\t(EqualExp::toElem): Likewise.\n\t* (StructLiteralExp::toElem): Don't create temporaries or initialize\n\tholes for empty\taggregates.\n\t* d-lang.cc (empty_modify_p): New function.\n\t(d_gimplify_expr): Remove assignments that involve empty aggregates.\n\n2016-01-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (d_builtin_type): Define DEF_FUNCTION_TYPE_9,\n\tDEF_FUNCTION_TYPE_10, and DEF_FUNCTION_TYPE_11.\n\t(d_init_builtins): Likewise.\n\t* d-longdouble.cc (machineMode): Remove function.\n\t(longdouble::init): Don't use initialize real format by reference.\n\t(longdouble::operator+): Use real_arithmetic instead of\n\tREAL_ARITHMETIC.\n\t(longdouble::operator-): Likewise.\n\t(longdouble::operator*): Likewise.\n\t(longdouble::operator/): Likewise.\n\t(longdouble::operator%): Likewise.\n\t* d-port.cc (Port::isSignallingNan): Use REAL_VALUE_ISSIGNALING_NAN.\n\t(Port::fequal): Use real_identical instead of REAL_VALUES_IDENTICAL.\n\t* d-target.cc: Include stor-layout.h header.\n\t* lang.opt: Remove documentation for switches defined elsewhere.\n\n2016-01-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (get_libcall): Use set_call_expr_flags to apply runtime\n\tfunction attributes.\n\t* d-codegen.h (LibCallFlag): Remove type.\n\t* runtime.def: Replace LibCallFlag with ECF everywhere.\n\n\f\nCopyright (C) 2016 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/ChangeLog-2017",
    "content": "2017-12-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* intrinsics.def (INTRINSIC_MULUI): Declare.\n\n2017-12-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_target_expr): Update signature.\n\t(force_target_expr): New function.\n\t(build_address): Use force_target_expr to store temporary.\n\t(d_build_call): Likewise.\n\t* d-lang.cc (d_gimplify_expr): Likewise.\n\t* d-tree.h (language_function): Update type for vars_in_scope from\n\tvec<VarDeclaration*> to vec<tree>.\n\t(force_target_expr): Declare.\n\t* decl.cc (DeclVisitor::visit(VarDeclaration)): Put vars with scope\n\tdestructors into a TARGET_EXPR, setting its cleanup.\n\t(declare_local_var): Don't push vars with scope destructors into the\n\tfunction binding level.\n\t* expr.cc (ExprVisitor::visit(DeclarationExp)): Don't handle scope\n\tdestructors.\n\t(ExprVisitor::visit(CallExp)): Handle calling constructors using\n\ttemporary objects.\n\t(build_dtor_list): Remove function.\n\t(build_expr_dtor): Put result into a CLEANUP_POINT_EXPR if any new\n\ttemporaries needing destruction were added to scope.\n\t(build_return_dtor): Likewise.\n\t* toir.cc (add_stmt): Set CLEANUP_POINT_EXPR type as void.\n\n2017-12-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-attribs.c (attr_noreturn_exclusions): New array.\n\t(attr_returns_twice_exclusions, attr_const_pure_exclusions): Likewise.\n\t(attr_inline_exclusions, attr_noinline_exclusions): Likewise.\n\t(d_langhook_common_attribute_table): Swap affects_identity and handler\n\tfields.  Initialize new member of struct attribute_spec.\n\t(d_langhook_attribute_table): Likewise.\n\t(handle_weakref_attribute): Remove function.\n\n2017-12-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (stabilize_expr): Handle assignment expressions.\n\t(get_frame_for_symbol): Adjust the 'this' field of frames of\n\toverridden interface functions.\n\t* d-diagnostic.cc (expand_format): Rewrite '%X' format as '%x'.\n\t* decl.cc (DeclVisitor::visit(ClassDeclaration)): Handle future\n\tattribute.\n\t* expr.cc (ExprVisitor::binop_assignment): Ensure RHS is evaluated\n\tbefore LHS.\n\t(ExprVisitor::visit(SliceExp)): Always save lower bounds if upper has\n\tany side effects.\n\t* typeinfo.cc (TypeInfoVisitor::TypeInfoClassDeclaration): Use\n\tClassDeclaration::isAbstract.\n\t(TypeInfoVisitor::visit(TypeInfoTupleDeclaration)): Mark internal\n\treference as public and hidden.\n\n2017-12-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_alignment_field): Set DECL_PADDING_P and\n\tDECL_FIELD_CONTEXT on generated fields.\n\t(build_struct_literal): Use build_zero_cst to generate padding.\n\t* decl.cc (build_type_decl): Set public and decl assembler name.\n\n2017-12-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* types.cc (TypeVisitor::visit(TypeClass)): Check for duplicate\n\tdeclarations before adding method.\n\n2017-12-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(AddrExp)): Build internal struct literal\n\tsymbol before generating its initializer.\n\n2017-12-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_parse_file): Set first_global_object_name.\n\n2017-12-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* lang.opt (fmodule-filepath=): Rename to fmodule-file.\n\t* d-lang.cc (d_handle_option): Update case for OPT_fmodule_file_.\n\n2017-12-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-tree.h (CALL_EXPR_ARGS_ORDERED): Define.\n\t* d-codegen.cc (d_build_call): Set CALL_EXPR_ARGS_ORDERED for\n\tfunctions with D linkage.\n\t* d-lang.cc (d_gimplify_expr): Handle CALL_EXPR_ARGS_ORDERED.\n\n2017-12-09  Eugene Wissner  <belka@caraus.de>\n\n\t* toir.cc (IRVisitor::visit(SwitchStatement)): Set SWITCH_ALL_CASES_P on\n\tswitch statements. Set SWITCH_BREAK_LABEL_P on the artificial label\n\tcreated for break statements from a switch.\n\n2017-12-04  Eugene Wissner  <belka@caraus.de>\n\n\t* toir.cc (IRVisitor::visit(SwitchStatement)): Build SWITCH_EXPR using build2 instead\n\tof build3.\n\n2017-11-14  Eugene Wissner  <belka@caraus.de>\n\n\t* decl.cc (finish_thunk): Drop frequency argument from\n\tsymbol_table::create_edge.\n\t* d-lang.cc (d_post_options): Set default value of\n\t-Wreturn-type to false.\n\n2017-11-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_float_cst): Remove float rounding check.\n\t* d-longdouble.cc (longdouble::to_int): Don't round floats before int\n\tconversion.\n\t* expr.cc (ExprVisitor::binary_op): Handle excess precision.\n\t(ExprVisitor::visit(NegExp)): Likwise.\n\n2017-10-31  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_address): Store CST nodes into a TARGET_EXPR\n\tbefore taking its address.\n\n2017-10-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_FRONTEND_OBJS): Remove newdelete.o.\n\t* d-incpath.cc (add_globalpaths): Handle NULL target path.\n\n2017-10-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* typeinfo.cc (TypeInfoVisitor::visit(TypeInfoClassDeclaration)):\n\tProperly check base classes for pointers.\n\n2017-09-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(StringExp)): Add extra null terminator\n\tonto string type, not the literal.\n\n2017-09-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* types.cc (make_array_type): Move checking of void static arrays\n\there.\n\n2017-09-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-attribs.c: Add include for attribs.h.\n\t* d-codegen.cc (copy_aggregate_type): Remove TYPE_METHODS.\n\t(lower_struct_comparison): Use opt_scalar_int_mode.\n\t* d-target.cc (Target::_init): Use TYPE_MAX_VALUE instead of\n\tTYPE_MAXVAL.\n\t(Target::isVectorTypeSupported):  Update call to\n\tscalar_mode_supported_p.\n\t* decl.cc (DeclVisitor::visit(Import)): Pass false as new argument to\n\tthe imported_module_or_decl hook.\n\t* types.cc (TypeVisitor::visit(TypeClass)): Remove TYPE_METHODS.\n\n2017-09-14  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_FRONTEND_OBJS): Add blockexit.o, initsem.o,\n\tinlinecost.o, safe.o, staticcond.o, and typesem.o.\n\t* d-attribs.c (uda_attribute_p): Use get_identifier to compare\n\tstrings.\n\t(build_attributes): Handle empty string expressions.\n\t* d-builtins.cc (build_frontend_type): Use static create methods to\n\t'new' front-end types, expressions, and declarations.\n\t(d_eval_constant_expression): Likewise.\n\t(build_alias_declaration): Likewise.\n\t(d_build_builtins_module): Likewise.\n\t* d-codegen.cc (declaration_type): Likewise.\n\t(type_passed_as): Likewise.\n\t(get_frame_for_symbol): Remove dependency on id.h.\n\t(get_frameinfo): Don't overwrite FRAMEINFO_CREATES_FRAME if function\n\thas nested frame references.\n\t* d-convert.cc (convert_for_assignment): Allow static arrays to be\n\tinitialized with a zero integer value.\n\t* d-frontend.cc (genCmain): Remove dependency on id.h.\n\t* d-frontend.h (initializerToExpression): Add declaration.\n\t(gendocfile): Add declaration.\n\t(initTraitsStringTable): Remove.\n\t* d-lang.cc (deps_write): Remove dependency on id.h.\n\t(deps_add_target): Don't call StringTables's destructor.\n\t(d_init): Remove calls to deleted front-end initialize functions.\n\t* decl.cc (DeclVisitor::visit(PragmaDeclaration)): Remove dependency\n\ton id.h.\n\t(DeclVisitor::visit(VarDeclaration)): Call initializerToExpression to\n\tget the initializer of decl.\n\t(build_decl_tree): Remove dependency on id.h.\n\t(layout_class_initializer): Use static create method to 'new'\n\tfront-end expression.\n\t* expr.cc (ExprVisitor::visit(AssignExp)): Handle static array\n\tassignment where RHS is integer zero.\n\t(ExprVisitor::visit(VarExp)): Remove dependency on id.h.\n\t(ExprVisitor::visit(StringExp)): Handle empty string expressions.\n\t* modules.cc (get_internal_fn): Use FuncDeclaration::genCfunc to\n\tcreate function decl.\n\t(build_module_tree): Remove dependency on id.h.\n\t* toir.cc (IRVisitor::visit(ExtAsmStatement)): Handle empty string\n\texpressions.\n\t* typeinfo.cc (make_frontend_typeinfo): Use static create methods to\n\t'new' front-end declarations.\n\t(create_tinfo_types): Remove dependency on id.h.\n\t(get_cpp_typeinfo_decl): Likewise.\n\t(create_typeinfo): Likewise.\n\n2017-08-23  Johannes Pfau  <johannespfau@gmail.com>\n\n\t* typeinfo.cc (TypeInfoVisitor::visit(TypeInfoStructDeclaration)): Do\n\tnot send member functions to backend here.\n\n2017-08-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-convert.cc (convert_expr): Use build_zero_cst for casts from\n\ttypeof(null).\n\n2017-08-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-target.cc (Target::isVectorOpSupported): Disallow vectors in\n\tconditional and logical operators.\n\n2017-08-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* intrinsics.cc (maybe_expand_intrinsic): Handle isNaN(), isInfinity()\n\tand isFinite() intrinsics.\n\t* intrinsics.def: Add INTRINSIC_ISNAN, INTRINSIC_ISINFINITY, and\n\tINTRINSIC_ISFINITE.\n\n2017-08-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* intrinsics.cc (expand_intrinsic_popcnt): New function.\n\t(maybe_expand_intrinsic): Handle INTRINSIC_POPCNT.\n\t* intrinsics.def (INTRINSIC_POPCNT): Declare.\n\n2017-08-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-frontend.cc (isBuiltin): Remove restriction on builtins.\n\t(eval_builtin): Check DECL_INTRINSIC_CODE.\n\t* d-tree.h (intrinsic_code): Add enum declaration.\n\t(lang_decl): Add intrinsic field.\n\t(DECL_INTRINSIC_CODE): New macro.\n\t(DECL_BUILT_IN_CTFE): New macro.\n\t* decls.cc (get_symbol_decl): Initialize DECL_INTRINSIC_CODE.\n\t* intrinsics.cc (intrinsic_decl): Add ctfeonly field.\n\t(maybe_set_intrinsic): Set frontend builtin flag only if the function\n\tis CTFE-able.  Set BUILT_IN_FRONTEND if function has no body.\n\t(clear_intrinsic_flag): Clear DECL_INTRINSIC_CODE instead of frontend\n\tbuiltin flag.\n\t(maybe_expand_intrinsic): Handle INTRINSIC_TAN intrinsics.\n\tCall clear_intrinsic_flag on CTFE built-ins if semantic has finished.\n\t* intrinsics.def: Add INTRINSIC_TAN.\n\t(DEF_D_BUILTIN): New macro.\n\t(DEF_CTFE_BUILTIN): New macro.\n\n2017-08-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* decl.cc (DeclVisitor::visit): Don't set input_location.\n\t(build_decl_tree): Handle set and restore of input_location.\n\t(declare_local_var): Don't set input_location.\n\t* expr.cc (build_expr): Handle set and restore of input_location.\n\t* imports.cc (build_import_decl): Likewise.\n\t* modules.cc (get_dso_registry_fn): Use UNKNOWN_LOCATION for\n\tdeclaration of _d_dso_registry.\n\t* runtime.cc (build_libcall_decl): Use UNKNOWN_LOCATION for\n\tdeclaration of library functions.\n\t* toir.cc (IRVisitor::visit): Don't set input_location.\n\t(IRVisitor::build_stmt): New function.\n\t(IRVisitor::do_jump): Update signature.\n\t(build_function_body): Use IRVisitor::build_stmt.\n\t* typeinfo.cc (layout_classinfo_interfaces): Don't set input_location.\n\t* types.cc (layout_aggregate_members): Likewise.\n\t(layout_aggregate_type): Likewise.\n\n2017-08-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_boolop): Handle VECTOR_TYPE comparisons.\n\t* d-target.cc (Target::checkVectorType): Rename to\n\tTarget::isVectorTypeSupported.\n\t(Target::isVectorOpSupported): New function.\n\t* expr.cc (ExprVisitor::visit(IdentityExp)): Don't memcmp floating\n\tpoint vectors.\n\t(ExprVisitor::visit(CmpExp)): Handle always true or always false\n\tvector comparisons.\n\n2017-08-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* typeinfo.cc (SpeculativeTypeVisitor::visit(TypeClass)): Don't emit\n\ttypeinfo for speculative class types.\n\n2017-07-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (build_lang_decl): Handle compiler generated typeinfo that\n\talso appear in code.\n\t* d-tree.h (lang_identifier): Add decl_tree.\n\t(IDENTIFIER_DECL_TREE): New macro.\n\t* decl.cc (declare_extern_var): Re-use already generated decl if\n\tcalled with the same identifier twice.\n\n2017-07-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* decl.cc (d_finish_decl): Replace ENABLE_TREE_CHECKING macro with\n\tflag_checking.\n\n2017-07-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-tree.h (D_DECL_ONE_ONLY): Remove macro accessor.\n\t* decl.cc (DeclVisitor::visit(StructDeclaration)): Move call to\n\td_comdat_linkage here.\n\t(DeclVisitor::visit(ClassDeclaration)): Likewise.\n\t(DeclVisitor::visit(InterfaceDeclaration)): Likewise.\n\t(DeclVisitor::visit(EnumDeclaration)): Likewise.\n\t(get_symbol_decl): Move call to mark_needed here.\n\t(declare_extern_var): Mark compiler generated symbols as needed.\n\t(make_thunk): Remove copy of D_DECL_ONE_ONLY.\n\t(get_vtable_decl): Don't call d_comdat_linkage.\n\t(aggregate_initializer_decl): Likewise.\n\t(enum_initializer_decl): Likewise.\n\t* modules.cc (d_finish_compilation): Don't call mark_needed.\n\t* typeinfo.cc (get_classinfo_decl): Don't call d_comdat_linkage.\n\n2017-07-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-spec.c (lang_specific_driver): Always add `-o' option when\n\tcompiling D sources.\n\n2017-07-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-frontend.cc (genCmain): Don't error if entrypoint not found.\n\n2017-07-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_types_compatible_p): Check that both types are\n\tRECORD_TYPE before using record-specific flag comparison.\n\n2017-07-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (d_build_d_type_nodes): Set TYPE_DYNAMIC_ARRAY on\n\tarray_type_node.\n\t* d-codegen.cc (build_delegate_cst): Set TYPE_DELEGATE on internal\n\tdelegate constant types.\n\t* d-frontend.h (cppTypeInfoMangle): Remove declaration.\n\t(toCppMangleItanium): Add declaration.\n\t(cppTypeInfoMangleItanium): Add declaration.\n\t* d-lang.cc (d_types_compatible_p): Use type flags to determine\n\tcompatibility.  Return false instead of doing size comparison.\n\t* d-target.cc (Target::toCppMangle): New function.\n\t(Target::cppTypeInfoMangle): New function.\n\t(Target::cppTypeMangle): New function.\n\t(Target::systemLinkage): New function.\n\t* d-tree.h (TYPE_DYNAMIC_ARRAY): New macro.\n\t(TYPE_DELEGATE): New macro.\n\t(TYPE_ASSOCIATIVE_ARRAY): New macro.\n\t* typeinfo.cc (layout_cpp_typeinfo): Use Target::cppTypeInfoMangle.\n\t* types.cc (TypeVisitor::visit(TypeDArray)): Set TYPE_DYNAMIC_ARRAY.\n\t(TypeVisitor::visit(TypeAArray)): Set TYPE_ASSOCIATIVE_ARRAY.\n\t(TypeVisitor::visit(TypeDelegate)): Set TYPE_DELEGATE.\n\n2017-07-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-target.cc (Target::loadModule): Check module identifier if a\n\tdeclaration doesn't exist.\n\t* typeinfo.cc (make_frontend_typeinfo): Use module location instead if\n\ta declaration doesn't exist.\n\n2017-06-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-frontend.cc (CTFloat::hash): New function.\n\n2017-06-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_array_string): Remove function.\n\t(d_assert_call): Inline implementation of d_array_string here.\n\t* d-tree.h (d_array_string): Remove declaration.\n\t* typeinfo.cc (TypeInfoVisitor::layout_string): New function.\n\t(TypeInfoVisitor::visit): Update calls to d_array_string to use\n\tlayout_string instead.\n\n2017-06-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* toir.cc (IRVisitor::visit(ExtAsmStatement)): Set ASM_VOLATILE_P only\n\tif statement is not marked with pure attribute.\n\n2017-06-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_parse_file): Print all predefined version identifiers\n\tif verbose.\n\n2017-06-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-frontend.cc (Global::_init): Remove memset for global.params.\n\n2017-06-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_ALL_OBJS): Add D_TARGET_OBJS.\n\t* d-builtins.cc (d_add_builtin_version): Move here from d-lang.cc.\n\t(d_init_versions): New function.\n\t* d-lang.cc (d_init): Call d_init_versions.\n\t* d-target-def.h: New file.\n\t* d-target.cc (Target::critsecsize): Replace with call to\n\ttargetdm.critsec_size.\n\t* d-target.def: New file.\n\t* d-target.h: New file.\n\t* d-tree.h (d_init_versions): Add declaration.\n\n2017-06-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(BinAssignExp)): Strip promotions from\n\tboth signed and unsigned rshift assignments.\n\n2017-06-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-diagnostic.cc (expand_format): New function.\n\t(d_diagnostic_report_diagnostic): New function.\n\t(error, verror): Update format attributes.  Use function\n\td_diagnostic_report_diagnostic instead of xvasprintf.\n\t(errorSupplemental, verrorSupplemental): Likewise.\n\t(warning, vwarning): Likewise.\n\t(warningSupplemental, vwarningSupplemental): Likewise.\n\t(deprecation, vdeprecation): Likewise.\n\t(deprecationSupplemental, vdeprecationSupplemental): Likewise.\n\n2017-06-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(AssertExp)): Don't call invariant on\n\tinterface objects.\n\n2017-06-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(DelegateExp)): Convert object to right\n\ttype before using it.\n\n2017-06-12  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (get_decl_tree): Find the first parent member function\n\tbefore constructing non-local `this' decl.\n\n2017-06-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (build_frontend_type): Allow all vector types to be\n\tincluded in builtins module.\n\n2017-06-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* types.cc (TypeVisitor::visit(TypeStruct)): Let struct alignment\n\toverride the alignsize.\n\n2017-06-09  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_decl_context): Use origin template declaration as\n\tcontext for instantiated type symbols.\n\n2017-06-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-attribs.c (d_handle_weak_attribute): Use quoted string format.\n\t* decls.cc (finish_thunk): Update call to create_edge for new API.\n\n2017-06-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(StringExp)): Create string type that is\n\tsame length as string value literal.\n\n2017-05-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_FRONTEND_OBJS): Rename object.o to rootobject.o.\n\n2017-05-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* decl.cc: Remove include for dumpfile.h.\n\t(finish_function): Use dump_function to for dumping original ASTs.\n\n2017-05-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* config-lang.in (gtfiles): Add typeinfo.cc.\n\t* d-codegen.cc (d_build_call_list): Remove function.\n\t(d_build_call_nary): Remove function.\n\t(build_binary_op): Remove function.\n\t(build_binop_assignment): Remove function.\n\t(build_vthis_type): Rename to build_vthis_function.\n\t(create_field_decl): Move to decl.cc.\n\t* d-lang.cc (genCmain): Moved to d-frontend.cc.\n\t(builtin_modules): Declare static.\n\t(d_add_builtin_module): New function.\n\t(d_add_entrypoint_module): New function.\n\t* expr.cc (ExprVisitor::binary_op): New function.\n\t(ExprVisitor::binop_assignment): New function.\n\t* intrinsic.cc (expand_intrinsic): Rename to maybe_expand_intrinsic.\n\t* runtime.cc (build_libcall): Updated signature.\n\t* types.cc (make_two_field_type): Remove function.\n\t(make_struct_type): New function.\n\n2017-05-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_OBJS): Add intrinsics.o and runtime.o.\n\t* d-codegen.h: Remove file.\n\t* intrinsics.cc: New file.\n\t* runtime.cc: New file.\n\n2017-05-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc: Remove include for d-dmd-gcc.h.\n\t* d-dmd-gcc.h: Rename to d-frontend.h.  Update all includes.\n\t* d-frontend.cc (Global::_init): Remove unnecessary initialization.\n\t* expr.cc: Remove include for d-dmd-gcc.h.\n\n2017-05-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-attribs.c (handle_sentinel_attribute): Remove function.\n\t(ignore_attribute): Remove function.\n\t(d_langhook_common_attribute_table): Remove sentinel and tm regparm\n\tfrom common attribute table.\n\t(d_langhook_format_attribute_table): Remove variable.\n\t* d-lang.cc (LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE): Remove macro.\n\t(LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE): Remove macro.\n\t(d_post_options): Don't set flag_unit_at_a_time.\n\t(d_nametype): Remove function.\n\t* types.cc (TypeVisitor::visit(TypeBasic)): Set TYPE_NAME.\n\t(TypeVisitor::visit(TypeVector)): Likewise.\n\n2017-05-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_OBJS): Remove d-objfile.o.  Add modules.o.\n\t* d-codegen.cc (get_linemap): Move function here.\n\t* d-objfile.cc: Remove file.\n\t* d-objfile.h: Remove header.\n\t* d-tree.h (GDC_PREFIX): New macro.\n\t* decl.cc (make_internal_name): Rename to mangle_internal_decl.\n\t(DeclVisitor): Move class here.\n\t(gcc_attribute_p): Move function here.\n\t(build_decl_tree): Likewise.\n\t(d_finish_decl): Likewise.\n\t(start_function): Likewise.\n\t(finish_function): Likewise.\n\t(mark_needed): Likewise.\n\t(base_vtable_offset): Likewise.\n\t(build_artificial_decl): Likewise.\n\t(build_type_decl): Likewise.\n\t(d_comdat_group): Likewise.\n\t(d_comdat_linkage): Likewise.\n\t(add_moduleinfo_field): Move to modules.cc\n\t(layout_moduleinfo_fields): Likewise.\n\t(get_moduleinfo_decl): Likewise.\n\t* modules.cc: New file.\n\n2017-05-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* imports.cc (ImportVisitor::visit(Import)): New function.\n\n2017-05-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (DeclVisitor::visit(Module)): Set input_location before\n\twalking module members.\n\t(get_linemap): Return input_location if no filename set.\n\t(set_input_location): Remove function.  Update all callers to set\n\tinput_location directly.\n\t(set_decl_location): Remove function.  Update all callers to pass\n\tget_linemap to build_decl, or use input_location.\n\t* types.cc (insert_aggregate_field): Update signature.\n\n2017-04-30  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (start_function): Update signature.\n\t(finish_function): Update signature.\n\t(DeclVisitor::visit(FuncDeclaration)): Move function construction to\n\tstart_function.  Move function finalization to finish_function.\n\t(set_function_end_locus): Remove function.\n\t(d_finish_function): Remove function.\n\t(build_simple_function_decl): Don't set frontend body.\n\t(build_simple_function): Update signature.  Use start/finish function\n\tto compile the body.\n\t(emit_dso_registry_cdtor): Likewise.\n\t* expr.cc (ExprVisitor::visit(WrappedExp)): Remove function.\n\n2017-04-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-diagnostic.cc (verror): Use xvasprintf.\n\t(verrorSupplemental): Likewise.\n\t(vwarning): Likewise.\n\t(vwarningSupplemental): Likewise.\n\t(vdeprecation): Likewise.\n\t(vdeprecationSupplemental): Likewise.\n\n2017-04-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-tree.h (d_tree_index): Add DTI_VTABLE_ENTRY_TYPE,\n\tDTI_VTBL_INTERFACE_TYPE, DTI_ARRAY_TYPE, and DTI_NULL_ARRAY.\n\t(vtable_entry_type): New macro.\n\t(vtbl_interface_type_node): New macro.\n\t(array_type_node): New macro.\n\t(null_array_node): New macro.\n\t* d-builtins.cc (d_build_d_type_nodes): Initialize new trees.\n\t* d-codegen.cc (build_struct_literal): Allow NULL index when\n\tlooking for next field to initialize.\n\t(copy_aggregate_type): New function.\n\t* d-target.cc (Target::loadModule): Look for object module,\n\tcall create_tinfo_types.\n\t* decl.cc (TypeInfoDeclVisitor): Move to typeinfo.cc.\n\t(get_typeinfo_decl): Likewise.\n\t(copy_struct): Remove function.  Updated callers to use\n\tcopy_aggregate_type.\n\t(layout_classinfo_interfaces): Move to typeinfo.cc.\n\t(get_classinfo_decl): Likewise.\n\t(get_cpp_typeinfo_decl): Likewise.\n\t* typeinfo.cc (tinfo_kind): New enum.\n\t(tinfo_types): New static variable.\n\t(get_typeinfo_kind): New function.\n\t(make_internal_typeinfo): New function.\n\t(make_frontend_typeinfo): New function.\n\t(create_tinfo_types): New function.\n\t(TypeInfoVisitor::set_field): Remove function.\n\tUpdate all callers to use layout_field.\n\t(TypeInfoVisitor::layout_vtable): Remove function.\n\tUpdate all callers to use layout_base.\n\t(TypeInfoVisitor::layout_field): New function.\n\t(TypeInfoVisitor::layout_base): New function.\n\t(builtin_typeinfo_p): New function.\n\t(genTypeInfo): Rename to create_typeinfo.\n\t(isSpeculativeType): Rename to speculative_type_p.\n\n2017-04-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-tree.h (d_function_chain): Declare macro.  Update all uses of\n\t`cfun->language' to use it.\n\n2017-04-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc: Rename to decl.cc.\n\t(get_symbol_decl): Handle typeinfo declarations.\n\t(declare_extern_var): New function.\n\t(declare_local_var): New function.\n\t(get_moduleinfo_decl): Call declare_extern_var.\n\t(get_classinfo_decl): Likewise.\n\t(get_vtable_decl): Likewise.\n\t(get_cpp_typeinfo_decl): Likewise.\n\t(aggregate_initializer_decl): Likewise.\n\t(enum_initializer_decl): Likewise.\n\t* Make-lang.in (D_OBJS): Update.\n\t* d-codegen.cc (build_local_var): Remove function.\n\tUpdated all callers to use declare_local_var.\n\t(build_local_temp): Move to decl.cc.\n\t(get_decl_tree): Likewise.\n\t(expand_decl): Remove function.\n\t(build_closure): Inline expand_decl here.\n\n2017-04-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (pop_binding_label): Move to toir.cc.\n\t(pop_label): Likewise.\n\t(push_binding_level): Likewise\n\t(pop_binding_level): Likewise.\n\t(push_stmt_list): Likewise.\n\t(add_stmt): Likewise.\n\t(check_goto): Move to toir.cc, make it a member of IRVisitor.\n\t(check_previous_goto): Likewise.\n\t(lookup_label): Likewise.\n\t(lookup_bc_label): Likewise.\n\t(define_label): Likewise.\n\t* toir.cc (build_ir): Rename to build_function_body.\n\n2017-04-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-target.cc: Update includes.\n\n2017-04-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* lang-specs.h: Remove capitalized D source suffixes.\n\n2017-04-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* lang-specs.h: Add rule for forwarding -iprefix and -imultilib to the\n\tcompiler proper.\n\n2017-04-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* lang-specs.h: Remove cc1d spec.\n\n2017-04-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* lang-specs.h: Remove +e handling.\n\n2017-04-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-diagnostic.cc: New file.\n\t* d-frontend.cc: New file.\n\t* d-glue.cc: Remove file.\n\t* d-port.cc: Remove file.\n\t* d-longdouble.h (template<typename T> operator): Remove operators.\n\n2017-04-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-incpath.cc (add_env_var_paths): Rename to add_environment_paths.\n\t(make_absolute): Remove function.\n\t(add_import_path): Rename to add_globalpaths.\n\t(add_fileimp_path): Rename to add_filepaths.\n\n2017-04-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.h (d_types_same): Renamed to same_type_p.\n\tMoved to types.cc.\n\t(build_object_type): Renamed to get_object_type.  Moved to types.cc.\n\t* d-codegen.cc (type_va_array): Renamed to valist_array_p.\n\tMoved to types.cc.\n\t(d_array_type): Renamed to make_array_type.  Moved to types.cc.\n\t(insert_type_modifiers): Moved to types.cc.\n\t(build_two_field_type): Likewise.\n\t(empty_aggregate_p): Likewise.\n\t(fixup_anonymous_offset): Likewise.\n\t(layout_aggregate_members): Likewise.\n\t(layout_aggregate_type): Likewise.\n\t(insert_aggregate_field): Likewise.\n\t(finish_aggregate_type): Likewise.\n\n2017-04-17  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_FRONTEND_OBJS): Update to match new source names.\n\n2017-04-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* gdc.texi: Rewrite documentation for manpages.\n\n2017-04-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (DeclVisitor::visit(FuncDeclaration)): Remove logic\n\tthat parent needs to be compiled before nested.\n\n2017-04-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_post_options): Don't overwrite in_fnames.\n\t(d_parse_file): Don't error about not being able to use stdin.\n\tImplement support for reading source code from stdin.\n\n2017-04-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_parse_file): Remove invalid file name checks.\n\n2017-04-08  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-glue.cc (Global::_init): Set global.stdmsg to stderr.\n\n2017-04-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codgen.h (current_module_decl): Moved to d-objfile.cc.\n\t* d-objfile.h (current_module_info): Likewise.\n\t(ModuleInfoFlags): Likewise.\n\t(ModuleInfo): Likewise.\n\t* d-objfile.cc (start_function): Move updating ModuleInfo structure to\n\t...\n\t(DeclVisitor::visit(FuncDeclaration)): ... here.  Set it after\n\tfinishing off the function.\n\n2017-04-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (DeclVisitor::visit(FuncDeclaration)): Use\n\tpush_function_decl for storing current state when switching to nested\n\tfunctions.  Remove handling of deferred functions.\n\t* d-tree.h (language_function): Remove deferred_fns.\n\t* expr.cc (ExprVisitor::visit(DelegateExp)): Don't defer compiling\n\tthe delegate lambda.\n\t(ExprVisitor::visit(FuncExp)): Likewise for function literals.\n\t(ExprVisitor::visit(VarExp)): Likewise.\n\n2017-04-07  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (start_function): Move to d-objfile.cc, make it static.\n\t(end_function): Likewise.  Renamed to finish_function.\n\n2017-04-05  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (d_convert): Move to d-convert.cc.\n\t(convert_expr): Likewise.\n\t(convert_for_assignment): Likewise.\n\t(convert_for_argument): Likewise.\n\t(convert_for_condition): Likewise.\n\t(d_array_convert): Likewise.\n\n2017-04-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.c (d_global_trees): Move to d-lang.cc.\n\t(build_dtype): Rename to build_frontend_type.\n\tUpdated all callers.\n\t(build_expression): Rename to d_eval_constant_expression.\n\tUpdated all callers.\n\t(build_alias_declaration): New function.\n\t(d_build_c_type_nodes): New function.\n\t(d_build_d_type_nodes): New function.\n\t(d_define_builtins): New function.\n\n2017-04-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-attribs.c (insert_type_attribute): Use\n\tbuild_type_attribute_variant.\n\t(insert_decl_attribute): Use build_decl_attribute_variant.\n\t(uda_attribute_p): Remove string table, use Identifier comparison for\n\tlooking up table attributes.\n\t(build_attributes): Make unknown attribute a warning, use quoted\n\tstrings in diagnostic messages.\n\n2017-04-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Handle -fdump-d-original.\n\t(d_parse_file): Likewise.\n\t* d-target.cc (Target::maxStaticDataSize): New variable.\n\t(Target::_init): Initialize maxStaticDataSize.\n\t* lang.opt (fdump-d-original): Declare.\n\n2017-04-01  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* Make-lang.in (D_GLUE_OBJS): Remove d-todt.cc.\n\t* d-objfile.cc (build_moduleinfo_symbol): Build initializer for\n\tModuleInfo directly from inferred type fields.\n\t(d_finish_symbol): Remove handling of DECL_LANG_INITIAL.\n\t* d-todt.cc: Remove file.\n\t* d-tree.h (lang_decl): Remove initial field.\n\t(DECL_LANG_INITIAL): Remove macro.\n\n2017-03-31  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (DeclVisitor::visit(VarDeclaration)): Use build_expr to\n\tgenerate the static initializer.\n\t* d-todt.cc (Initializer::toDt): Remove function and all overrides.\n\t* expr.cc (ExprVisitor::visit(VarExp)): Use build_expr to get the\n\tconstant initializer of a constant variable.\n\n2017-03-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (aggregate_initializer): Renamed to\n\taggregate_initializer_decl.  Updated all callers.\n\t(enum_initializer): Renamed to enum_initializer_decl.\n\tUpdated all callers.\n\t(layout_class_initializer): New function.\n\t(layout_struct_initializer): New function.\n\t* d-todt.cc (ClassDeclaration::toDt): Remove function.\n\t(StructDeclaration::toDt): Remove function.\n\n2017-03-27  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (DeclVisitor::visit(Module)): New function.\n\t(Module::genobjfile): Remove function.\n\tUpdated all callers to use build_decl_tree.\n\t(layout_moduleinfo): New function.\n\t(Module::genmoduleinfo): Remove function.\n\tUpdate all callers to use layout_moduleinfo.\n\n2017-03-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (base_vtable_offset): New function.\n\t(ClassDeclaration::baseVtblOffset): Remove function.\n\tUpdated all callers to use base_vtable_offset.\n\n2017-03-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (DeclVisitor): New visitor interface to supercede the\n\ttoObjFile methods.\n\t(build_decl_tree): New function.\n\t(Dsymbol::toObjFile): Remove function and overrides.\n\tUpdated all callers to use build_decl_tree.\n\n2017-03-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (get_cpp_typeinfo_decl): New function.\n\t* d-lang.cc (d_build_eh_type_type): Return classinfo for\n\t__cpp_type_info_ptr when generating catch for C++ classes.\n\t* runtime.def (CXA_BEGIN_CATCH): Define.\n\t(CXA_END_CATCH): Define.\n\t* toir.cc (IRVisitor::visit(TryCatchStatement)): Support catching\n\tclasses thrown from C++.\n\t* typeinfo.cc (layout_cpp_typeinfo): New function.\n\n2017-03-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-builtins.cc (d_build_builtins_module): Always mark gcc builtins as\n\tnothrow functions.\n\n2017-03-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-longdouble.cc (CTFloat::zero): New variable.\n\t(CTFloat::one): New variable.\n\t(CTFloat::minusone): New variable.\n\t(CTFloat::half): New variable.\n\t(longdouble::set): Remove float and double overloads.\n\t(longdouble::operator float): Remove function.\n\t(longdouble::operator double): Remove function.\n\t* d-target.cc (Target::_init): Initialize floating point constants.\n\n2017-03-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_init): Replace calls to init with _init.\n\t* d-glue.cc (Global::init): Renamed to Global::_init.\n\t* d-target.cc (Target::init): Renamed to Target::_init.\n\n2017-03-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-longdouble.cc (longdouble::format): Remove function.\n\t(longdouble::formatHex): Remove function.\n\t(longdouble::dump): Remove function.\n\t(CTFloat::sprint): Inline implementation of format and formatHex here.\n\n2017-03-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_init): Remove calls to Port::init and longdouble::init.\n\t* d-longdouble.cc (real_limits): Remove variable.\n\t(longdouble::init): Remove function.\n\t(CTFloat::parse): Update to use Target::RealProperties.\n\t* d-port.cc (Port::ldbl_nan): Remove variable.\n\t(Port::snan): Remove variable.\n\t(Port::ldbl_infinity): Remove variable.\n\t(Port::ldbl_max): Remove variable.\n\t(Port::init): Remove function.\n\t(Port::isFloat32LiteralOutOfRange): Update to use\n\tTarget::RealProperties.\n\t(Port::isFloat64LiteralOutOfRange): Likewise.\n\t* d-target.cc (Target::FPTypeProperties<T>::max): Define.\n\t(Target::FPTypeProperties<T>::min_normal): Define.\n\t(Target::FPTypeProperties<T>::nan): Define.\n\t(Target::FPTypeProperties<T>::snan): Define.\n\t(Target::FPTypeProperties<T>::infinity): Define.\n\t(Target::FPTypeProperties<T>::epsilon): Define.\n\t(Target::FPTypeProperties<T>::dig): Define.\n\t(Target::FPTypeProperties<T>::mant_dig): Define.\n\t(Target::FPTypeProperties<T>::max_exp): Define.\n\t(Target::FPTypeProperties<T>::min_exp): Define.\n\t(Target::FPTypeProperties<T>::max_10_exp): Define.\n\t(Target::FPTypeProperties<T>::min_10_exp): Define.\n\t(define_float_constants): New function.\n\t(Target::init): Initialize compile-time floating point properties.\n\t* longdouble.h (Mode): Remove type declaration.\n\t(real_properties): Remove type declaration.\n\n2017-03-10  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-longdouble.cc (CTFloat::fabs): New function.\n\t(CTFloat::isIdentical): New function.\n\t(CTFloat::isNaN): New function.\n\t(CTFloat::isSNaN): New function.\n\t(CTFloat::isInfinity): New function.\n\t(CTFloat::parse): New function.\n\t(CTFloat::sprint): New function.\n\t* d-port.cc (Port::isNan): Remove function.\n\t(Port::isSignallingNan): Remove function.\n\t(Port::isInfinity): Remove function.\n\t(Port::fequal): Remove function.\n\t(Port::strtof): Remove function.\n\t(Port::strtod): Remove function.\n\t(Port::strtold): Remove function.\n\t(Port::isFloat32LiteralOutOfRange): New function.\n\t(Port::isFloat64LiteralOutOfRange): New function.\n\t* longdouble.h (ld_sprint): Remove function.\n\n2017-03-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-glue.cc (verror): Update to handle -Wspeculative.\n\t(verrorSupplemental): Likewise.\n\t* d-lang.cc (d_init_options): Initialize module alias array.\n\t(d_init_options): Handle -fmodule-filepath= and -Wspeculative.\n\t* d-port.cc (Port::stricmp): Remove function.\n\t(Port::writelongLE): New function.\n\t(Port::writelongBE): New function.\n\t* lang.opt (Wspeculative): Declare.\n\t(fmodule-filepath=): Declare.\n\n2017-03-06  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Handle -ftransition=dip1000\n\t* lang.opt (ftransition=dip1000): Declare.\n\t(ftransition=safe): Make alias for -ftransition=dip1000\n\n2017-03-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (get_decl_tree): Handle chaining over many levels of\n\tnesting functions to get to the right parent for the 'this' field.\n\n2017-03-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (get_symbol_decl): Move generation of DECL_ARGUMENTS for\n\tempty body declarations to ...\n\t(make_thunk): ... here.  Also set-up DECL_RESULT.\n\t(finish_thunk): Mark DECL_UNINLINEABLE on external functions.\n\n2017-03-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (make_thunk): Don't build thunks for functions that\n\tfailed to compile.\n\n2017-03-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (emit_dso_registry_hooks): Set DECL_PRESERVE_P.\n\n2017-02-26  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_frame_type): Update condition for scope\n\tdestruction error.\n\t* d-port.cc (Port::valcpy): New function.\n\t* expr.cc (ExprVisitor::visit(CallExp)): Generate cast of 'this'\n\tobject to the right handle type before indexing.\n\n2017-02-24  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-glue.cc (warningSupplemental): New function.\n\t(vwarningSupplemental): New function.\n\t(deprecationSupplemental): New function.\n\t(vdeprecationSupplemental): New function.\n\n2017-02-23  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* imports.cc (ImportVisitor::visit(OverDeclaration)): New function.\n\t(ImportVisitor::visit(FuncAliasDeclaration)): New function.\n\n2017-02-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Handle -X and -Xf options.\n\t(d_parse_file): Update.\n\t* lang-specs.h: Add rules for -X style options.\n\t* lang.opt (X): Declare.\n\t(Xf): Declare.\n\t(fXf=): Make alias for -Xf.\n\n2017-02-21  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* lang.opt (fd-vgc): Comment out help test.\n\t(fd-verbose): Likewise.\n\t(fd-vtls): Likewise.\n\t(femit-modules): Likewise.\n\n2017-02-20  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-target.cc (Target::fieldalign): Adjust.\n\n2017-02-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_option_data): Add fields to support other -M options.\n\t(d_init_options): Initialize them.\n\t(deps_add_target): New function.\n\t(deps_write): Support multiple targets and phony rules.\n\t(d_handle_option): Handle gcc -M style options.\n\t(d_parse_file): Likewise.\n\t* lang-specs.h: Add rules for -M style options.\n\t* lang.opt: Declare -M style options.\n\n2017-02-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (is_system_module): Remove.\n\t(deps_write): Always ignore entrypoint module.\n\n2017-02-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (write_one_dep): Remove.\n\t(deps_write): Update signature.\n\n2017-02-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (iprefix_dir): Remove.\n\t(imultilib_dir): Remove.\n\t(std_inc): Remove.\n\t(d_option_data): New struct.\n\t(d_option): Declare.\n\t(d_init_options): Initialize d_option.\n\t(d_init): Update to use d_option.\n\t(d_handle_option): Likewise.\n\t(d_parse_file): Likewise.\n\t(deps_write): Update signature.\n\n2017-02-19  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Call D_handle_option_auto.\n\t* lang.opt (Wunknown-pragmas): Turn on warning with -Wall.\n\n2017-02-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Replace -fin with -fpreconditions;\n\t-fout with -fpostconditions.  Handle -fswitch-errors.\n\t(d_post_options): Move setting of release code flags here.\n\t* lang.opt (fassert): Declare flag_assert.\n\t(fin): Make alias for -fpreconditions.\n\t(finvariants): Declare flag_invariants.\n\t(fout): Make alias for -fpostconditions.\n\t(fpostconditions): Declare.\n\t(fpreconditions): Declare.\n\t(fswitch-errors): Declare.\n\n2017-02-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (PragmaDeclaration::toObjFile): Warn about unknown\n\tpragmas only if -Wunknown-pragmas.\n\n2017-02-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-glue.cc (Global::init): Initialize errorLimit to flag_max_errors.\n\t(verror): Don't halt program after invocation limit.\n\t* d-lang.cc (d_handle_option): Remove handling -fmax-error-messages.\n\t* lang.opt (fmax-error-messages): Remove option.\n\n2017-02-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-decls.cc (get_symbol_decl): Handle -Wtemplates.\n\t* d-lang.cc (d_init_options): Remove setting flag_emit_templates.\n\t(d_handle_option): Replace handling -femit-templates with\n\t-fall-instantiations.\n\t(d_pushdecl): Remove checking for flag_emit_templates.\n\t* d-tree.h (D_DECL_IS_TEMPLATE): Remove macro.\n\t* lang.opt (flag_emit_templates): Remove variable.\n\t(fall-instantiations): Declare.\n\t(femit-templates): Make alias for -fall-instantiations.\n\t(Wtemplates): Declare.\n\n2017-02-18  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* lang.opt (fassert): Update help text.\n\t(fin): Likewise.\n\t(finvariants): Likewise.\n\t(fout): Likewise.\n\n2017-02-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (VarDeclaration::toObjFile): Error if a variable covers\n\tmore than half the address space.\n\n2017-02-04  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-objfile.cc (Module::genmoduleinfo): Ignore symbol visibility when\n\tlooking up module DSO symbols.\n\n2017-01-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Handle -ftransition=all.\n\t* lang.opt (ftransition=all): Add compiler option.\n\n2017-01-29  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Handle -ftransition=checkimports.\n\t* lang.opt (ftransition=checkimports): Add compiler option.\n\n2017-01-28  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-lang.cc (d_handle_option): Handle -ftransition=import.\n\t* lang.opt (ftransition=import): Add compiler option.\n\n2017-01-25  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* imports.cc (ImportVisitor::visit(EnumDeclaration)): New function.\n\t(ImportVisitor::visit(AggregateDeclaration)): New function.\n\t(ImportVisitor::visit(ClassDeclaration)): New function.\n\t(ImportVisitor::make_import): New function.\n\t(ImportVisitor::visit(AliasDeclaration)): Get decl for type alias.\n\n2017-01-22  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* expr.cc (ExprVisitor::visit(EqualExp)): Don't use memcmp on arrays\n\tof structs that define xopEquals.\n\n2017-01-15  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-spec.cc (lang_specific_driver): Add missing break.\n\n2017-01-13  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen.cc (build_class_instance): Don't check for void\n\tinitialized fields.\n\t* expr.cc (ExprVisitor::visit(StructLiteralExp)): Likewise.\n\n2017-01-11  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* typeinfo.cc (layout_classinfo): Use placement new to initialize\n\ttypeinfo class declaration.\n\n2017-01-02  Iain Buclaw  <ibuclaw@gdcproject.org>\n\n\t* d-codegen,cc (get_frame_for_symbol): Use fully qualified name in\n\terror message.\n\t(build_frame_type): Always add parameters to closure vars if the\n\tfunction has a contract function.\n\t(get_frameinfo): Likewise, always create a frame.\n\t* expr.cc (ExprVisitor::needs_dtor): New function.\n\t(ExprVisitor::lvalue_p): New function.\n\t(ExprVisitor::visit(AssignExp)): Check for dtor in array assignments.\n\t(ExprVisitor::visit(TypeidExp)): Cast result to expression type.\n\n\f\nCopyright (C) 2017 Free Software Foundation, Inc.\n\nCopying and distribution of this file, with or without modification,\nare permitted in any medium without royalty provided the copyright\nnotice and this notice are preserved.\n"
  },
  {
    "path": "gcc/d/Make-lang.in",
    "content": "# Make-lang.in -- Top level -*- makefile -*- fragment for the D frontend.\n# Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\n# GCC is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3, or (at your option)\n# any later version.\n\n# GCC is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\n# This file provides the language dependent support in the main Makefile.\n\n# Installation name.\n\nD_INSTALL_NAME = $(shell echo gdc|sed '$(program_transform_name)')\nD_TARGET_INSTALL_NAME = $(target_noncanonical)-$(shell echo gdc|sed '$(program_transform_name)')\n\n# Name of phobos library\nD_LIBPHOBOS = -DLIBPHOBOS=\\\"gphobos\\\"\n\n# The name for selecting d in LANGUAGES.\nd: d21$(exeext)\n\n# Tell GNU make to ignore these if they exist.\n.PHONY: d\n\n# Create the compiler driver for D.\nCFLAGS-d/d-spec.o += $(DRIVER_DEFINES) $(D_LIBPHOBOS)\n\nGDC_OBJS = $(GCC_OBJS) d/d-spec.o\ngdc$(exeext): $(GDC_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS)\n\t+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \\\n\t  $(GDC_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \\\n\t  $(EXTRA_GCC_LIBS) $(LIBS)\n\n# Create a version of the gdc driver which calls the cross-compiler.\ngdc-cross$(exeext): gdc$(exeext)\n\t-rm -f gdc-cross$(exeext)\n\tcp gdc$(exeext) gdc-cross$(exeext)\n\n# Use strict warnings.\nd-warn = $(STRICT_WARN)\n\n# D compiler and flags for building the front-end.\nifeq ($(TREECHECKING),)\nCHECKING_DFLAGS = -frelease\nelse\nCHECKING_DFLAGS =\nendif\nWARN_DFLAGS = -Wall -Wdeprecated $(NOCOMMON_FLAG)\n\nALL_DFLAGS = $(DFLAGS-$@) $(GDCFLAGS) -fversion=IN_GCC $(CHECKING_DFLAGS) \\\n\t$(PICFLAG) $(ALIASING_FLAGS) $(COVERAGE_FLAGS) $(WARN_DFLAGS)\n\nDCOMPILE.base = $(GDC) $(NO_PIE_CFLAGS) -c $(ALL_DFLAGS) -o $@\nDCOMPILE = $(DCOMPILE.base) -MT $@ -MMD -MP -MF $(@D)/$(DEPDIR)/$(*F).TPo\nDPOSTCOMPILE = @mv $(@D)/$(DEPDIR)/$(*F).TPo $(@D)/$(DEPDIR)/$(*F).Po\nDLINKER = $(GDC) $(NO_PIE_FLAG) -lstdc++\n\n# Like LINKER, but use a mutex for serializing front end links.\nifeq (@DO_LINK_MUTEX@,true)\nDLLINKER = $(SHELL) $(srcdir)/lock-and-run.sh linkfe.lck $(DLINKER)\nelse\nDLLINKER = $(DLINKER)\nendif\n\n# D Frontend object files.\nD_FRONTEND_OBJS = \\\n\td/aav.o \\\n\td/access.o \\\n\td/aggregate.o \\\n\td/aliasthis.o \\\n\td/apply.o \\\n\td/argtypes.o \\\n\td/array.o \\\n\td/arrayop.o \\\n\td/arraytypes.o \\\n\td/attrib.o \\\n\td/astcodegen.o \\\n\td/blockexit.o \\\n\td/builtin.o \\\n\td/canthrow.o \\\n\td/clone.o \\\n\td/compiler.o \\\n\td/complex.o \\\n\td/cond.o \\\n\td/constfold.o \\\n\td/cppmangle.o \\\n\td/ctfeexpr.o \\\n\td/ctfloat.o \\\n\td/ctorflow.o \\\n\td/dcast.o \\\n\td/dclass.o \\\n\td/declaration.o \\\n\td/delegatize.o \\\n\td/denum.o \\\n\td/dimport.o \\\n\td/dinterpret.o \\\n\td/dmacro.o \\\n\td/dmangle.o \\\n\td/dmodule.o \\\n\td/doc.o \\\n\td/dscope.o \\\n\td/dstruct.o \\\n\td/dsymbol.o \\\n\td/dsymbolsem.o \\\n\td/dtemplate.o \\\n\td/dversion.o \\\n\td/entity.o \\\n\td/errors.o \\\n\td/escape.o \\\n\td/expression.o \\\n\td/expressionsem.o \\\n\td/file.o \\\n\td/filename.o \\\n\td/func.o \\\n\td/globals.o \\\n\td/gluelayer.o \\\n\td/hash.o \\\n\td/hdrgen.o \\\n\td/iasm.o \\\n\td/iasmgcc.o \\\n\td/id.o \\\n\td/identifier.o \\\n\td/impcnvtab.o \\\n\td/imphint.o \\\n\td/init.o \\\n\td/initsem.o \\\n\td/inline.o \\\n\td/intrange.o \\\n\td/json.o \\\n\td/lambdacomp.o \\\n\td/lexer.o \\\n\td/longdouble.o \\\n\td/mtype.o \\\n\td/nogc.o \\\n\td/nspace.o \\\n\td/objc.o \\\n\td/opover.o \\\n\td/optimize.o \\\n\td/outbuffer.o \\\n\td/parse.o \\\n\td/parsetimevisitor.o \\\n\td/permissivevisitor.o \\\n\td/port.o \\\n\td/rmem.o \\\n\td/rootobject.o \\\n\td/safe.o \\\n\td/sapply.o \\\n\td/semantic2.o \\\n\td/semantic3.o \\\n\td/sideeffect.o \\\n\td/speller.o \\\n\td/statement.o \\\n\td/statement_rewrite_walker.o \\\n\td/statementsem.o \\\n\td/staticassert.o \\\n\td/staticcond.o \\\n\td/stringtable.o \\\n\td/target.o \\\n\td/templateparamsem.o \\\n\td/tokens.o \\\n\td/traits.o \\\n\td/transitivevisitor.o \\\n\td/typesem.o \\\n\td/typinf.o \\\n\td/utf.o \\\n\td/utils.o \\\n\td/visitor.o\n\n# Language-specific object files for D.\nD_OBJS = \\\n\td/d-attribs.o d/d-builtins.o d/d-codegen.o d/d-convert.o \\\n\td/d-diagnostic.o d/d-frontend.o d/d-incpath.o d/d-lang.o \\\n\td/d-longdouble.o d/d-target.o d/decl.o d/expr.o d/imports.o \\\n\td/intrinsics.o d/modules.o d/runtime.o d/toir.o d/typeinfo.o d/types.o\n\n# All language-specific object files for D.\nD_ALL_OBJS = $(D_FRONTEND_OBJS) $(D_OBJS) $(D_TARGET_OBJS)\n\nd_OBJS = $(D_ALL_OBJS) d/d-spec.o\n\nd21$(exeext): $(D_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS)\n\t+$(DLLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \\\n\t\t$(D_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) $(BACKENDLIBS)\n\n# Documentation.\n\nD_TEXI_FILES = \\\n\td/gdc.texi \\\n\t$(gcc_docdir)/include/fdl.texi \\\n\t$(gcc_docdir)/include/gpl_v3.texi \\\n\t$(gcc_docdir)/include/gcc-common.texi \\\n\tgcc-vers.texi\n\ndoc/gdc.info: $(D_TEXI_FILES)\n\tif test \"x$(BUILD_INFO)\" = xinfo; then \\\n\t  rm -f doc/gdc.info*; \\\n\t  $(MAKEINFO) $(MAKEINFOFLAGS) -I $(gcc_docdir) \\\n\t\t-I $(gcc_docdir)/include -o $@ $<; \\\n\telse true; fi\n\ndoc/gdc.dvi: $(D_TEXI_FILES)\n\t$(TEXI2DVI) -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $<\n\ndoc/gdc.pdf: $(D_TEXI_FILES)\n\t$(TEXI2PDF) -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $<\n\n$(build_htmldir)/d/index.html: $(D_TEXI_FILES)\n\t$(mkinstalldirs) $(@D)\n\trm -f $(@D)/*\n\t$(TEXI2HTML) -I $(gcc_docdir) -I $(gcc_docdir)/include \\\n\t\t-I $(srcdir)/d -o $(@D) $<\n\n.INTERMEDIATE: gdc.pod\n\ngdc.pod: d/gdc.texi\n\t-$(TEXI2POD) -D gdc < $< > $@\n\n# Build hooks.\n\nd.all.cross: gdc-cross$(exeext)\nd.start.encap: gdc$(exeext)\nd.rest.encap:\nd.info: doc/gdc.info\nd.dvi: doc/gdc.dvi\nd.pdf: doc/gdc.pdf\nd.html: $(build_htmldir)/d/index.html\nd.srcinfo: doc/gdc.info\n\t-cp -p $^ $(srcdir)/doc\nd.srcextra:\n\nd.tags: force\n\tcd $(srcdir)/d; \\\n\tetags -o TAGS.sub *.c *.cc *.h dmd/*.h dmd/root/*.h; \\\n\tetags --include TAGS.sub --include ../TAGS.sub\n\nd.man: doc/gdc.1\nd.srcman: doc/gdc.1\n\t-cp -p $^ $(srcdir)/doc\n\n# 'make check' in gcc/ looks for check-d, as do all toplevel D-related\n# check targets.  However, our DejaGNU framework requires 'check-gdc' as its\n# entry point.  We feed the former to the latter here.\ncheck-d: check-gdc\nlang_checks += check-gdc\nlang_checks_parallelized += check-gdc\ncheck_gdc_parallelize = 10\n\n# No D-specific selftests.\nselftest-d:\n\n# Install hooks.\n\nd.install-common: installdirs\n\t-rm -f $(DESTDIR)$(bindir)/$(D_INSTALL_NAME)$(exeext)\n\t$(INSTALL_PROGRAM) gdc$(exeext) $(DESTDIR)$(bindir)/$(D_INSTALL_NAME)$(exeext)\n\t-if test -f d21$(exeext); then \\\n\t  if test -f gdc-cross$(exeext); then \\\n\t    :; \\\n\t  else \\\n\t    rm -f $(DESTDIR)$(bindir)/$(D_TARGET_INSTALL_NAME)$(exeext); \\\n\t    ( cd $(DESTDIR)$(bindir) && \\\n\t      $(LN) $(D_INSTALL_NAME)$(exeext) $(D_TARGET_INSTALL_NAME)$(exeext) ); \\\n\t  fi; \\\n\tfi\n\nd.install-plugin:\n\nd.install-info: $(DESTDIR)$(infodir)/gdc.info\n\nd.install-pdf: doc/gdc.pdf\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(pdfdir)\" || $(mkinstalldirs) \"$(DESTDIR)$(pdfdir)/gcc\"\n\t@for p in doc/gdc.pdf; do \\\n\t  if test -f \"$$p\"; then d=; else d=\"$(srcdir)/\"; fi; \\\n\t  f=$(pdf__strip_dir) \\\n\t  echo \" $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(pdfdir)/gcc/$$f'\"; \\\n\t  $(INSTALL_DATA) \"$$d$$p\" \"$(DESTDIR)$(pdfdir)/gcc/$$f\"; \\\n\tdone\n\nd.install-html: $(build_htmldir)/d\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(htmldir)\" || $(mkinstalldirs) \"$(DESTDIR)$(htmldir)\"\n\t@for p in $(build_htmldir)/d; do \\\n\t  if test -f \"$$p\" || test -d \"$$p\"; then d=\"\"; else d=\"$(srcdir)/\"; fi; \\\n\t  f=$(html__strip_dir) \\\n\t  if test -d \"$$d$$p\"; then \\\n\t    echo \" $(mkinstalldirs) '$(DESTDIR)$(htmldir)/$$f'\"; \\\n\t    $(mkinstalldirs) \"$(DESTDIR)$(htmldir)/$$f\" || exit 1; \\\n\t    echo \" $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'\"; \\\n\t    $(INSTALL_DATA) \"$$d$$p\"/* \"$(DESTDIR)$(htmldir)/$$f\"; \\\n\t  else \\\n\t    echo \" $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'\"; \\\n\t    $(INSTALL_DATA) \"$$d$$p\" \"$(DESTDIR)$(htmldir)/$$f\"; \\\n\t  fi; \\\n\tdone\n\nd.install-man: $(DESTDIR)$(man1dir)/$(D_INSTALL_NAME)$(man1ext)\n\n$(DESTDIR)$(man1dir)/$(D_INSTALL_NAME)$(man1ext): doc/gdc.1 installdirs\n\t-rm -f $@\n\t-$(INSTALL_DATA) $< $@\n\t-chmod a-x $@\n\nd.uninstall:\n\t-rm -rf $(DESTDIR)$(bindir)/$(D_INSTALL_NAME)$(exeext)\n\t-rm -rf $(DESTDIR)$(man1dir)/$(D_INSTALL_NAME)$(man1ext)\n\t-rm -rf $(DESTDIR)$(bindir)/$(D_TARGET_INSTALL_NAME)$(exeext)\n\t-rm -rf $(DESTDIR)$(infodir)/gdc.info*\n\n# Clean hooks.\n\nd.mostlyclean:\n\t-rm -f d/*$(objext)\n\t-rm -f d/*$(coverageexts)\n\t-rm -f d/gdc$(exeext) gdc-cross$(exeext) d/d21$(exeext)\nd.clean:\nd.distclean:\nd.maintainer-clean:\n\t-rm -f $(docobjdir)/gdc.1\n\n# Stage hooks.\n\nd.stage1: stage1-start\n\t-mv d/*$(objext) stage1/d\nd.stage2: stage2-start\n\t-mv d/*$(objext) stage2/d\nd.stage3: stage3-start\n\t-mv d/*$(objext) stage3/d\nd.stage4: stage4-start\n\t-mv d/*$(objext) stage4/d\nd.stageprofile: stageprofile-start\n\t-mv d/*$(objext) stageprofile/d\nd.stagefeedback: stagefeedback-start\n\t-mv d/*$(objext) stagefeedback/d\n\n# Include the dfrontend and build directories for headers.\nD_INCLUDES = -I$(srcdir)/d -J$(srcdir)/d/dmd/ddoc\n\n# Override build rules for D frontend.\nd/%.o: d/dmd/%.d\n\t$(DCOMPILE) $(D_INCLUDES) $<\n\t$(DPOSTCOMPILE)\n\nd/%.o: d/dmd/root/%.d\n\t$(DCOMPILE) $(D_INCLUDES) $<\n\t$(DPOSTCOMPILE)\n"
  },
  {
    "path": "gcc/d/config-lang.in",
    "content": "# config-lang.in -- Top level configure fragment for gcc D frontend.\n# Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\n# GCC is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3, or (at your option)\n# any later version.\n\n# GCC is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\n# Configure looks for the existence of this file to auto-config each language.\n# We define several parameters used by configure:\n#\n# language\t- name of language as it would appear in $(LANGUAGES)\n# boot_language\t- \"yes\" if we need to build this language in stage1\n# compilers\t- value to add to $(COMPILERS)\n\nlanguage=\"d\"\n\nboot_language=yes\ncompilers=\"d21\\$(exeext)\"\n\ntarget_libs=\"target-libphobos target-zlib target-libbacktrace\"\n\ngtfiles=\"\\$(srcdir)/d/d-tree.h \\$(srcdir)/d/d-builtins.cc \\$(srcdir)/d/d-lang.cc \\$(srcdir)/d/modules.cc \\$(srcdir)/d/typeinfo.cc\"\n\n# Do not build by default.\nbuild_by_default=\"no\"\n"
  },
  {
    "path": "gcc/d/d-attribs.cc",
    "content": "/* d-attribs.c -- D attributes handling.\n   Copyright (C) 2015-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n/* Implementation of attribute handlers for user defined attributes and\n   internal built-in functions.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/declaration.h\"\n#include \"dmd/expression.h\"\n#include \"dmd/mtype.h\"\n\n#include \"tree.h\"\n#include \"diagnostic.h\"\n#include \"tm.h\"\n#include \"cgraph.h\"\n#include \"toplev.h\"\n#include \"target.h\"\n#include \"common/common-target.h\"\n#include \"stringpool.h\"\n#include \"attribs.h\"\n#include \"varasm.h\"\n\n#include \"d-tree.h\"\n\n\n/* Internal attribute handlers for built-in functions.  */\nstatic tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);\nstatic tree handle_leaf_attribute (tree *, tree, tree, int, bool *);\nstatic tree handle_const_attribute (tree *, tree, tree, int, bool *);\nstatic tree handle_malloc_attribute (tree *, tree, tree, int, bool *);\nstatic tree handle_pure_attribute (tree *, tree, tree, int, bool *);\nstatic tree handle_novops_attribute (tree *, tree, tree, int, bool *);\nstatic tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);\nstatic tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);\nstatic tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);\nstatic tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);\nstatic tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);\nstatic tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);\n\n/* D attribute handlers for user defined attributes.  */\nstatic tree d_handle_noinline_attribute (tree *, tree, tree, int, bool *);\nstatic tree d_handle_forceinline_attribute (tree *, tree, tree, int, bool *);\nstatic tree d_handle_flatten_attribute (tree *, tree, tree, int, bool *);\nstatic tree d_handle_target_attribute (tree *, tree, tree, int, bool *);\nstatic tree d_handle_noclone_attribute (tree *, tree, tree, int, bool *);\nstatic tree d_handle_section_attribute (tree *, tree, tree, int, bool *);\nstatic tree d_handle_alias_attribute (tree *, tree, tree, int, bool *);\nstatic tree d_handle_weak_attribute (tree *, tree, tree, int, bool *) ;\n\n/* Helper to define attribute exclusions.  */\n#define ATTR_EXCL(name, function, type, variable)\t\\\n  { name, function, type, variable }\n\n/* Define attributes that are mutually exclusive with one another.  */\nstatic const struct attribute_spec::exclusions attr_noreturn_exclusions[] =\n{\n  ATTR_EXCL (\"const\", true, true, true),\n  ATTR_EXCL (\"malloc\", true, true, true),\n  ATTR_EXCL (\"pure\", true, true, true),\n  ATTR_EXCL (\"returns_twice\", true, true, true),\n  ATTR_EXCL (NULL, false, false, false),\n};\n\nstatic const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =\n{\n  ATTR_EXCL (\"noreturn\", true, true, true),\n  ATTR_EXCL (NULL, false, false, false),\n};\n\nstatic const struct attribute_spec::exclusions attr_const_pure_exclusions[] =\n{\n  ATTR_EXCL (\"const\", true, true, true),\n  ATTR_EXCL (\"noreturn\", true, true, true),\n  ATTR_EXCL (\"pure\", true, true, true),\n  ATTR_EXCL (NULL, false, false, false)\n};\n\nstatic const struct attribute_spec::exclusions attr_inline_exclusions[] =\n{\n  ATTR_EXCL (\"noinline\", true, true, true),\n  ATTR_EXCL (NULL, false, false, false),\n};\n\nstatic const struct attribute_spec::exclusions attr_noinline_exclusions[] =\n{\n  ATTR_EXCL (\"forceinline\", true, true, true),\n  ATTR_EXCL (NULL, false, false, false),\n};\n\n/* Helper to define an attribute.  */\n#define ATTR_SPEC(name, min_len, max_len, decl_req, type_req, fn_type_req, \\\n\t\t  affects_type_identity, handler, exclude)\t\t   \\\n  { name, min_len, max_len, decl_req, type_req, fn_type_req,\t\t   \\\n    affects_type_identity, handler, exclude }\n\n/* Table of machine-independent attributes.\n   For internal use (marking of built-ins) only.  */\nconst attribute_spec d_langhook_common_attribute_table[] =\n{\n  ATTR_SPEC (\"noreturn\", 0, 0, true, false, false, false,\n\t     handle_noreturn_attribute, attr_noreturn_exclusions),\n  ATTR_SPEC (\"leaf\", 0, 0, true, false, false, false,\n\t     handle_leaf_attribute, NULL),\n  ATTR_SPEC (\"const\", 0, 0, true, false, false, false,\n\t     handle_const_attribute, attr_const_pure_exclusions),\n  ATTR_SPEC (\"malloc\", 0, 0, true, false, false, false,\n\t     handle_malloc_attribute, NULL),\n  ATTR_SPEC (\"returns_twice\", 0, 0, true, false, false, false,\n\t     handle_returns_twice_attribute, attr_returns_twice_exclusions),\n  ATTR_SPEC (\"pure\", 0, 0, true, false, false, false,\n\t     handle_pure_attribute, attr_const_pure_exclusions),\n  ATTR_SPEC (\"nonnull\", 0, -1, false, true, true, false,\n\t     handle_nonnull_attribute, NULL),\n  ATTR_SPEC (\"nothrow\", 0, 0, true, false, false, false,\n\t     handle_nothrow_attribute, NULL),\n  ATTR_SPEC (\"transaction_pure\", 0, 0, false, true, true, false,\n\t     handle_transaction_pure_attribute, NULL),\n  ATTR_SPEC (\"no vops\", 0, 0, true, false, false, false,\n\t     handle_novops_attribute, NULL),\n  ATTR_SPEC (\"type generic\", 0, 0, false, true, true, false,\n\t     handle_type_generic_attribute, NULL),\n  ATTR_SPEC (\"fn spec\", 1, 1, false, true, true, false,\n\t     handle_fnspec_attribute, NULL),\n  ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL),\n};\n\n/* Table of D language attributes exposed by `gcc.attribute' UDAs.  */\nconst attribute_spec d_langhook_attribute_table[] =\n{\n  ATTR_SPEC (\"noinline\", 0, 0, true, false, false, false,\n\t     d_handle_noinline_attribute, attr_noinline_exclusions),\n  ATTR_SPEC (\"forceinline\", 0, 0, true, false, false, false,\n\t     d_handle_forceinline_attribute, attr_inline_exclusions),\n  ATTR_SPEC (\"flatten\", 0, 0, true, false, false, false,\n\t     d_handle_flatten_attribute, NULL),\n  ATTR_SPEC (\"target\", 1, -1, true, false, false, false,\n\t     d_handle_target_attribute, NULL),\n  ATTR_SPEC (\"noclone\", 0, 0, true, false, false, false,\n\t     d_handle_noclone_attribute, NULL),\n  ATTR_SPEC (\"section\", 1, 1, true, false, false, false,\n\t     d_handle_section_attribute, NULL),\n  ATTR_SPEC (\"alias\", 1, 1, true, false, false, false,\n\t     d_handle_alias_attribute, NULL),\n  ATTR_SPEC (\"weak\", 0, 0, true, false, false, false,\n\t     d_handle_weak_attribute, NULL),\n  ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL),\n};\n\n\n/* Insert the type attribute ATTRNAME with value VALUE into TYPE.\n   Returns a new variant of the original type declaration.  */\n\ntree\ninsert_type_attribute (tree type, const char *attrname, tree value)\n{\n  tree ident = get_identifier (attrname);\n\n  if (value)\n    value = tree_cons (NULL_TREE, value, NULL_TREE);\n\n  tree attribs = merge_attributes (TYPE_ATTRIBUTES (type),\n\t\t\t\t   tree_cons (ident, value, NULL_TREE));\n\n  return build_type_attribute_variant (type, attribs);\n}\n\n/* Insert the decl attribute ATTRNAME with value VALUE into DECL.  */\n\ntree\ninsert_decl_attribute (tree decl, const char *attrname, tree value)\n{\n  tree ident = get_identifier (attrname);\n\n  if (value)\n    value = tree_cons (NULL_TREE, value, NULL_TREE);\n\n  tree attribs = merge_attributes (DECL_ATTRIBUTES (decl),\n\t\t\t\t   tree_cons (ident, value, NULL_TREE));\n\n  return build_decl_attribute_variant (decl, attribs);\n}\n\n/* Returns TRUE if NAME is an attribute recognized as being handled by\n   the `gcc.attribute' module.  */\n\nstatic bool\nuda_attribute_p (const char *name)\n{\n  tree ident = get_identifier (name);\n\n  /* Search both our language, and target attribute tables.\n     Common and format attributes are kept internal.  */\n  for (const attribute_spec *p = d_langhook_attribute_table; p->name; p++)\n    {\n      if (get_identifier (p->name) == ident)\n\treturn true;\n    }\n\n  for (const attribute_spec *p = targetm.attribute_table; p->name; p++)\n    {\n      if (get_identifier (p->name) == ident)\n\treturn true;\n    }\n\n  return false;\n}\n\n/* [attribute/uda]\n\n   User Defined Attributes (UDA) are compile time expressions that can be\n   attached to a declaration.  These attributes can then be queried, extracted,\n   and manipulated at compile-time.  There is no run-time component to them.\n\n   Expand and merge all UDAs found in the EATTRS list that are of type\n   `gcc.attribute.Attribute'.  This symbol is internally recognized by the\n   compiler and maps them to their equivalent GCC attribute.  */\n\ntree\nbuild_attributes (Expressions *eattrs)\n{\n  if (!eattrs)\n    return NULL_TREE;\n\n  expandTuples (eattrs);\n\n  tree attribs = NULL_TREE;\n\n  for (size_t i = 0; i < eattrs->dim; i++)\n    {\n      Expression *attr = (*eattrs)[i];\n      Dsymbol *sym = attr->type->toDsymbol (0);\n\n      if (!sym)\n\tcontinue;\n\n      /* Attribute symbol must come from the `gcc.attribute' module.  */\n      Dsymbol *mod = (Dsymbol*) sym->getModule ();\n      if (!(strcmp (mod->toChars (), \"attribute\") == 0\n\t    && mod->parent != NULL\n\t    && strcmp (mod->parent->toChars (), \"gcc\") == 0\n\t    && !mod->parent->parent))\n\tcontinue;\n\n      /* Get the result of the attribute if it hasn't already been folded.  */\n      if (attr->op == TOKcall)\n\tattr = attr->ctfeInterpret ();\n\n      /* Should now have a struct `Attribute(\"attrib\", \"value\", ...)'\n\t initializer list.  */\n      gcc_assert (attr->op == TOKstructliteral);\n      Expressions *elems = ((StructLiteralExp*) attr)->elements;\n      Expression *e0 = (*elems)[0];\n\n      if (e0->op != TOKstring)\n\t{\n\t  error (\"expected string attribute, not %qs\", e0->toChars ());\n\t  return error_mark_node;\n\t}\n\n      StringExp *se = (StringExp*) e0;\n      gcc_assert (se->sz == 1);\n\n      /* Empty string attribute, just ignore it.  */\n      if (se->len == 0)\n\tcontinue;\n\n      /* Check if the attribute is recognized and handled.\n\t Done here to report the diagnostic at the right location.  */\n      const char *name = (const char *)(se->len ? se->string : \"\");\n      if (!uda_attribute_p (name))\n\t{\n\t  warning_at (make_location_t (e0->loc), OPT_Wattributes,\n\t\t      \"unknown attribute %qs\", name);\n\t  return error_mark_node;\n\t}\n\n      /* Chain all attribute arguments together.  */\n      tree args = NULL_TREE;\n\n      for (size_t j = 1; j < elems->dim; j++)\n\t{\n\t  Expression *e = (*elems)[j];\n\t  tree t;\n\t  if (e->op == TOKstring && ((StringExp *) e)->sz == 1)\n\t    {\n\t      StringExp *s = (StringExp *) e;\n\t      const char *string = (const char *)(s->len ? s->string : \"\");\n\t      t = build_string (s->len, string);\n\t    }\n\t  else\n\t    t = build_expr (e);\n\n\t  args = chainon (args, build_tree_list (0, t));\n\t}\n\n      tree list = build_tree_list (get_identifier (name), args);\n      attribs = chainon (attribs, list);\n    }\n\n  return attribs;\n}\n\n/* Built-in attribute handlers.  */\n\n/* Handle a \"noreturn\" attribute; arguments as in\n   struct attribute_spec.handler.  */\n\nstatic tree\nhandle_noreturn_attribute (tree *node, tree ARG_UNUSED (name),\n\t\t\t   tree ARG_UNUSED (args), int ARG_UNUSED (flags),\n\t\t\t   bool * ARG_UNUSED (no_add_attrs))\n{\n  tree type = TREE_TYPE (*node);\n\n  if (TREE_CODE (*node) == FUNCTION_DECL)\n    TREE_THIS_VOLATILE (*node) = 1;\n  else if (TREE_CODE (type) == POINTER_TYPE\n\t   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)\n    TREE_TYPE (*node)\n      = build_pointer_type\n\t(build_type_variant (TREE_TYPE (type),\n\t\t\t     TYPE_READONLY (TREE_TYPE (type)), 1));\n  else\n    gcc_unreachable ();\n\n  return NULL_TREE;\n}\n\n/* Handle a \"leaf\" attribute; arguments as in\n   struct attribute_spec.handler.  */\n\nstatic tree\nhandle_leaf_attribute (tree *node, tree name,\n\t\t       tree ARG_UNUSED (args),\n\t\t       int ARG_UNUSED (flags), bool *no_add_attrs)\n{\n  if (TREE_CODE (*node) != FUNCTION_DECL)\n    {\n      warning (OPT_Wattributes, \"%qE attribute ignored\", name);\n      *no_add_attrs = true;\n    }\n  if (!TREE_PUBLIC (*node))\n    {\n      warning (OPT_Wattributes, \"%qE attribute has no effect\", name);\n      *no_add_attrs = true;\n    }\n\n  return NULL_TREE;\n}\n\n/* Handle a \"const\" attribute; arguments as in\n   struct attribute_spec.handler.  */\n\nstatic tree\nhandle_const_attribute (tree *node, tree ARG_UNUSED (name),\n\t\t\ttree ARG_UNUSED (args), int ARG_UNUSED (flags),\n\t\t\tbool * ARG_UNUSED (no_add_attrs))\n{\n  tree type = TREE_TYPE (*node);\n\n  if (TREE_CODE (*node) == FUNCTION_DECL)\n    TREE_READONLY (*node) = 1;\n  else if (TREE_CODE (type) == POINTER_TYPE\n\t   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)\n    TREE_TYPE (*node)\n      = build_pointer_type\n\t(build_type_variant (TREE_TYPE (type), 1,\n\t\t\t     TREE_THIS_VOLATILE (TREE_TYPE (type))));\n  else\n    gcc_unreachable ();\n\n  return NULL_TREE;\n}\n\n/* Handle a \"malloc\" attribute; arguments as in\n   struct attribute_spec.handler.  */\n\ntree\nhandle_malloc_attribute (tree *node, tree ARG_UNUSED (name),\n\t\t\t tree ARG_UNUSED (args), int ARG_UNUSED (flags),\n\t\t\t bool * ARG_UNUSED (no_add_attrs))\n{\n  gcc_assert (TREE_CODE (*node) == FUNCTION_DECL\n\t      && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))));\n  DECL_IS_MALLOC (*node) = 1;\n  return NULL_TREE;\n}\n\n/* Handle a \"pure\" attribute; arguments as in\n   struct attribute_spec.handler.  */\n\nstatic tree\nhandle_pure_attribute (tree *node, tree ARG_UNUSED (name),\n\t\t       tree ARG_UNUSED (args), int ARG_UNUSED (flags),\n\t\t       bool * ARG_UNUSED (no_add_attrs))\n{\n  gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);\n  DECL_PURE_P (*node) = 1;\n  return NULL_TREE;\n}\n\n/* Handle a \"no vops\" attribute; arguments as in\n   struct attribute_spec.handler.  */\n\nstatic tree\nhandle_novops_attribute (tree *node, tree ARG_UNUSED (name),\n\t\t\t tree ARG_UNUSED (args), int ARG_UNUSED (flags),\n\t\t\t bool * ARG_UNUSED (no_add_attrs))\n{\n  gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);\n  DECL_IS_NOVOPS (*node) = 1;\n  return NULL_TREE;\n}\n\n/* Helper for nonnull attribute handling; fetch the operand number\n   from the attribute argument list.  */\n\nstatic bool\nget_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)\n{\n  /* Verify the arg number is a constant.  */\n  if (!tree_fits_uhwi_p (arg_num_expr))\n    return false;\n\n  *valp = TREE_INT_CST_LOW (arg_num_expr);\n  return true;\n}\n\n/* Handle the \"nonnull\" attribute.  */\n\nstatic tree\nhandle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),\n\t\t\t  tree args, int ARG_UNUSED (flags),\n\t\t\t  bool * ARG_UNUSED (no_add_attrs))\n{\n  tree type = *node;\n\n  /* If no arguments are specified, all pointer arguments should be\n     non-null.  Verify a full prototype is given so that the arguments\n     will have the correct types when we actually check them later.\n     Avoid diagnosing type-generic built-ins since those have no\n     prototype.  */\n  if (!args)\n    {\n      gcc_assert (prototype_p (type)\n\t\t  || !TYPE_ATTRIBUTES (type)\n\t\t  || lookup_attribute (\"type generic\", TYPE_ATTRIBUTES (type)));\n\n      return NULL_TREE;\n    }\n\n  /* Argument list specified.  Verify that each argument number references\n     a pointer argument.  */\n  for (; args; args = TREE_CHAIN (args))\n    {\n      tree argument;\n      unsigned HOST_WIDE_INT arg_num = 0, ck_num;\n\n      if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))\n\tgcc_unreachable ();\n\n      argument = TYPE_ARG_TYPES (type);\n      if (argument)\n\t{\n\t  for (ck_num = 1; ; ck_num++)\n\t    {\n\t      if (!argument || ck_num == arg_num)\n\t\tbreak;\n\t      argument = TREE_CHAIN (argument);\n\t    }\n\n\t  gcc_assert (argument\n\t\t      && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE);\n\t}\n    }\n\n  return NULL_TREE;\n}\n\n/* Handle a \"nothrow\" attribute; arguments as in\n   struct attribute_spec.handler.  */\n\nstatic tree\nhandle_nothrow_attribute (tree *node, tree ARG_UNUSED (name),\n\t\t\t  tree ARG_UNUSED (args), int ARG_UNUSED (flags),\n\t\t\t  bool * ARG_UNUSED (no_add_attrs))\n{\n  gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);\n  TREE_NOTHROW (*node) = 1;\n  return NULL_TREE;\n}\n\n/* Handle a \"type_generic\" attribute.  */\n\nstatic tree\nhandle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),\n\t\t\t       tree ARG_UNUSED (args), int ARG_UNUSED (flags),\n\t\t\t       bool * ARG_UNUSED (no_add_attrs))\n{\n  /* Ensure we have a function type.  */\n  gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);\n\n  /* Ensure we have a variadic function.  */\n  gcc_assert (!prototype_p (*node) || stdarg_p (*node));\n\n  return NULL_TREE;\n}\n\n/* Handle a \"transaction_pure\" attribute.  */\n\nstatic tree\nhandle_transaction_pure_attribute (tree *node, tree ARG_UNUSED (name),\n\t\t\t\t   tree ARG_UNUSED (args),\n\t\t\t\t   int ARG_UNUSED (flags),\n\t\t\t\t   bool * ARG_UNUSED (no_add_attrs))\n{\n  /* Ensure we have a function type.  */\n  gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);\n\n  return NULL_TREE;\n}\n\n/* Handle a \"returns_twice\" attribute.  */\n\nstatic tree\nhandle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name),\n\t\t\t\ttree ARG_UNUSED (args),\n\t\t\t\tint ARG_UNUSED (flags),\n\t\t\t\tbool * ARG_UNUSED (no_add_attrs))\n{\n  gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);\n\n  DECL_IS_RETURNS_TWICE (*node) = 1;\n\n  return NULL_TREE;\n}\n\n/* Handle a \"fn spec\" attribute; arguments as in\n   struct attribute_spec.handler.  */\n\ntree\nhandle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),\n\t\t\t tree args, int ARG_UNUSED (flags),\n\t\t\t bool *no_add_attrs ATTRIBUTE_UNUSED)\n{\n  gcc_assert (args\n\t      && TREE_CODE (TREE_VALUE (args)) == STRING_CST\n\t      && !TREE_CHAIN (args));\n  return NULL_TREE;\n}\n\n/* Language specific attribute handlers.  */\n\n/* Handle a \"noinline\" attribute.  */\n\nstatic tree\nd_handle_noinline_attribute (tree *node, tree name,\n\t\t\t     tree ARG_UNUSED (args),\n\t\t\t     int ARG_UNUSED (flags), bool *no_add_attrs)\n{\n  Type *t = TYPE_LANG_FRONTEND (TREE_TYPE (*node));\n\n  if (t->ty == Tfunction)\n    DECL_UNINLINABLE (*node) = 1;\n  else\n    {\n      warning (OPT_Wattributes, \"%qE attribute ignored\", name);\n      *no_add_attrs = true;\n    }\n\n  return NULL_TREE;\n}\n\n/* Handle a \"forceinline\" attribute.  */\n\nstatic tree\nd_handle_forceinline_attribute (tree *node, tree name,\n\t\t\t\ttree ARG_UNUSED (args),\n\t\t\t\tint ARG_UNUSED (flags),\n\t\t\t\tbool *no_add_attrs)\n{\n  Type *t = TYPE_LANG_FRONTEND (TREE_TYPE (*node));\n\n  if (t->ty == Tfunction)\n    {\n      tree attributes = DECL_ATTRIBUTES (*node);\n\n      /* Push attribute always_inline.  */\n      if (! lookup_attribute (\"always_inline\", attributes))\n\tDECL_ATTRIBUTES (*node) = tree_cons (get_identifier (\"always_inline\"),\n\t\t\t\t\t     NULL_TREE, attributes);\n\n      DECL_DECLARED_INLINE_P (*node) = 1;\n      DECL_NO_INLINE_WARNING_P (*node) = 1;\n      DECL_DISREGARD_INLINE_LIMITS (*node) = 1;\n    }\n  else\n    {\n      warning (OPT_Wattributes, \"%qE attribute ignored\", name);\n      *no_add_attrs = true;\n    }\n\n  return NULL_TREE;\n}\n\n/* Handle a \"flatten\" attribute.  */\n\nstatic tree\nd_handle_flatten_attribute (tree *node, tree name,\n\t\t\t    tree args ATTRIBUTE_UNUSED,\n\t\t\t    int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)\n{\n  Type *t = TYPE_LANG_FRONTEND (TREE_TYPE (*node));\n\n  if (t->ty != Tfunction)\n    {\n      warning (OPT_Wattributes, \"%qE attribute ignored\", name);\n      *no_add_attrs = true;\n    }\n\n  return NULL_TREE;\n}\n\n/* Handle a \"target\" attribute.  */\n\nstatic tree\nd_handle_target_attribute (tree *node, tree name, tree args, int flags,\n\t\t\t   bool *no_add_attrs)\n{\n  Type *t = TYPE_LANG_FRONTEND (TREE_TYPE (*node));\n\n  /* Ensure we have a function type.  */\n  if (t->ty != Tfunction)\n    {\n      warning (OPT_Wattributes, \"%qE attribute ignored\", name);\n      *no_add_attrs = true;\n    }\n  else if (! targetm.target_option.valid_attribute_p (*node, name, args, flags))\n    *no_add_attrs = true;\n\n  return NULL_TREE;\n}\n\n/* Handle a \"noclone\" attribute.  */\n\nstatic tree\nd_handle_noclone_attribute (tree *node, tree name,\n\t\t\t\ttree ARG_UNUSED (args),\n\t\t\t\tint ARG_UNUSED (flags),\n\t\t\t\tbool *no_add_attrs)\n{\n  Type *t = TYPE_LANG_FRONTEND (TREE_TYPE (*node));\n\n  if (t->ty == Tfunction)\n    {\n      tree attributes = DECL_ATTRIBUTES (*node);\n\n      /* Push attribute noclone.  */\n      if (! lookup_attribute (\"noclone\", attributes))\n\tDECL_ATTRIBUTES (*node) = tree_cons (get_identifier (\"noclone\"),\n\t\t\t\t\t     NULL_TREE, attributes);\n    }\n  else\n    {\n      warning (OPT_Wattributes, \"%qE attribute ignored\", name);\n      *no_add_attrs = true;\n    }\n\n  return NULL_TREE;\n}\n\n/* Handle a \"section\" attribute; arguments as in\n   struct attribute_spec.handler.  */\n\nstatic tree\nd_handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args,\n\t\t\t    int ARG_UNUSED (flags), bool *no_add_attrs)\n{\n  tree decl = *node;\n\n  if (targetm_common.have_named_sections)\n    {\n      if (VAR_OR_FUNCTION_DECL_P (decl)\n\t  && TREE_CODE (TREE_VALUE (args)) == STRING_CST)\n\t{\n\t  if (VAR_P (decl)\n\t      && current_function_decl != NULL_TREE\n\t      && !TREE_STATIC (decl))\n\t    {\n\t      error_at (DECL_SOURCE_LOCATION (decl),\n\t\t\t\"section attribute cannot be specified for \"\n\t\t\t\"local variables\");\n\t      *no_add_attrs = true;\n\t    }\n\n\t  /* The decl may have already been given a section attribute\n\t     from a previous declaration.  Ensure they match.  */\n\t  else if (DECL_SECTION_NAME (decl) != NULL\n\t\t   && strcmp (DECL_SECTION_NAME (decl),\n\t\t\t      TREE_STRING_POINTER (TREE_VALUE (args))) != 0)\n\t    {\n\t      error (\"section of %q+D conflicts with previous declaration\",\n\t\t     *node);\n\t      *no_add_attrs = true;\n\t    }\n\t  else if (VAR_P (decl)\n\t\t   && !targetm.have_tls && targetm.emutls.tmpl_section\n\t\t   && DECL_THREAD_LOCAL_P (decl))\n\t    {\n\t      error (\"section of %q+D cannot be overridden\", *node);\n\t      *no_add_attrs = true;\n\t    }\n\t  else\n\t    set_decl_section_name (decl,\n\t\t\t\t   TREE_STRING_POINTER (TREE_VALUE (args)));\n\t}\n      else\n\t{\n\t  error (\"section attribute not allowed for %q+D\", *node);\n\t  *no_add_attrs = true;\n\t}\n    }\n  else\n    {\n      error_at (DECL_SOURCE_LOCATION (*node),\n\t\t\"section attributes are not supported for this target\");\n      *no_add_attrs = true;\n    }\n\n  return NULL_TREE;\n}\n\n/* Handle an \"alias\" attribute; arguments as in\n   struct attribute_spec.handler.  */\n\nstatic tree\nd_handle_alias_attribute (tree *node, tree ARG_UNUSED (name),\n\t\t\t  tree args, int ARG_UNUSED (flags),\n\t\t\t  bool *no_add_attrs ATTRIBUTE_UNUSED)\n{\n  tree decl = *node;\n\n  if (TREE_CODE (decl) != FUNCTION_DECL\n      && TREE_CODE (decl) != VAR_DECL)\n    {\n      warning (OPT_Wattributes, \"%qE attribute ignored\", name);\n      *no_add_attrs = true;\n      return NULL_TREE;\n    }\n  else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))\n      || (TREE_CODE (decl) != FUNCTION_DECL\n\t  && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))\n      /* A static variable declaration is always a tentative definition,\n\t but the alias is a non-tentative definition which overrides.  */\n      || (TREE_CODE (decl) != FUNCTION_DECL\n\t  && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl)))\n    {\n      error (\"%q+D defined both normally and as %qE attribute\", decl, name);\n      *no_add_attrs = true;\n      return NULL_TREE;\n    }\n  else if (decl_function_context (decl))\n    {\n      error (\"%q+D alias functions must be global\", name);\n      *no_add_attrs = true;\n      return NULL_TREE;\n    }\n  else\n    {\n      tree id;\n\n      id = TREE_VALUE (args);\n      if (TREE_CODE (id) != STRING_CST)\n\t{\n\t  error (\"attribute %qE argument not a string\", name);\n\t  *no_add_attrs = true;\n\t  return NULL_TREE;\n\t}\n      id = get_identifier (TREE_STRING_POINTER (id));\n      /* This counts as a use of the object pointed to.  */\n      TREE_USED (id) = 1;\n\n      if (TREE_CODE (decl) == FUNCTION_DECL)\n\tDECL_INITIAL (decl) = error_mark_node;\n      else\n\tTREE_STATIC (decl) = 1;\n\n      return NULL_TREE;\n    }\n}\n\n/* Handle a \"weak\" attribute; arguments as in\n   struct attribute_spec.handler.  */\n\nstatic tree\nd_handle_weak_attribute (tree *node, tree name,\n\t\t\t tree ARG_UNUSED (args),\n\t\t\t int ARG_UNUSED (flags),\n\t\t\t bool * ARG_UNUSED (no_add_attrs))\n{\n  if (TREE_CODE (*node) == FUNCTION_DECL\n      && DECL_DECLARED_INLINE_P (*node))\n    {\n      warning (OPT_Wattributes, \"inline function %q+D declared weak\", *node);\n      *no_add_attrs = true;\n    }\n  else if (VAR_OR_FUNCTION_DECL_P (*node))\n    {\n      struct symtab_node *n = symtab_node::get (*node);\n      if (n && n->refuse_visibility_changes)\n\terror (\"%q+D declared weak after being used\", *node);\n      declare_weak (*node);\n    }\n  else\n    warning (OPT_Wattributes, \"%qE attribute ignored\", name);\n\n  return NULL_TREE;\n}\n\n"
  },
  {
    "path": "gcc/d/d-builtins.cc",
    "content": "/* d-builtins.cc -- GCC builtins support for D.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/attrib.h\"\n#include \"dmd/aggregate.h\"\n#include \"dmd/cond.h\"\n#include \"dmd/declaration.h\"\n#include \"dmd/expression.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/module.h\"\n#include \"dmd/mtype.h\"\n\n#include \"tree.h\"\n#include \"fold-const.h\"\n#include \"diagnostic.h\"\n#include \"langhooks.h\"\n#include \"target.h\"\n#include \"common/common-target.h\"\n#include \"stringpool.h\"\n#include \"stor-layout.h\"\n\n#include \"d-tree.h\"\n#include \"d-target.h\"\n\n\nstatic GTY(()) vec<tree, va_gc> *gcc_builtins_functions = NULL;\nstatic GTY(()) vec<tree, va_gc> *gcc_builtins_libfuncs = NULL;\nstatic GTY(()) vec<tree, va_gc> *gcc_builtins_types = NULL;\n\n/* Record built-in types and their associated decls for re-use when\n   generating the `gcc.builtins' module.  */\n\nstruct builtin_data\n{\n  Type *dtype;\n  tree ctype;\n  Dsymbol *dsym;\n\n  builtin_data (Type *t, tree c, Dsymbol *d = NULL)\n    : dtype(t), ctype(c), dsym(d)\n  { }\n};\n\nstatic vec<builtin_data> builtin_converted_decls;\n\n/* Build D frontend type from tree TYPE type given.  This will set the\n   back-end type symbol directly for complex types to save build_ctype()\n   the work.  For other types, it is not useful or will cause errors, such\n   as casting from `C char' to `D char', which also means that `char *`\n   needs to be specially handled.  */\n\nstatic Type *\nbuild_frontend_type (tree type)\n{\n  Type *dtype;\n  MOD mod = 0;\n\n  if (TYPE_READONLY (type))\n    mod |= MODconst;\n  if (TYPE_VOLATILE (type))\n    mod |= MODshared;\n\n  /* If we've seen the type before, re-use the converted decl.  */\n  for (size_t i = 0; i < builtin_converted_decls.length (); ++i)\n    {\n      tree t = builtin_converted_decls[i].ctype;\n      if (TYPE_MAIN_VARIANT (t) == TYPE_MAIN_VARIANT (type))\n\treturn builtin_converted_decls[i].dtype;\n    }\n\n  switch (TREE_CODE (type))\n    {\n    case POINTER_TYPE:\n      dtype = build_frontend_type (TREE_TYPE (type));\n      if (dtype)\n\t{\n\t  /* Check for char * first.  Needs to be done for chars/string.  */\n\t  if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == char_type_node)\n\t    return Type::tchar->addMod (dtype->mod)->pointerTo ()->addMod (mod);\n\n\t  if (dtype->ty == Tfunction)\n\t    return (TypePointer::create (dtype))->addMod (mod);\n\n\t  return dtype->pointerTo ()->addMod (mod);\n\t}\n      break;\n\n    case REFERENCE_TYPE:\n      dtype = build_frontend_type (TREE_TYPE (type));\n      if (dtype)\n\t{\n\t  /* Want to assign ctype directly so that the REFERENCE_TYPE code\n\t     can be turned into as an `inout' argument.  Can't use pointerTo(),\n\t     because the returned Type is shared.  */\n\t  dtype = (TypePointer::create (dtype))->addMod (mod);\n\t  dtype->ctype = type;\n\t  builtin_converted_decls.safe_push (builtin_data (dtype, type));\n\t  return dtype;\n\t}\n      break;\n\n    case BOOLEAN_TYPE:\n      /* Should be no need for size checking.  */\n      return Type::tbool->addMod (mod);\n\n    case INTEGER_TYPE:\n    {\n      unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));\n      bool unsignedp = TYPE_UNSIGNED (type);\n\n      /* For now, skip support for cent/ucent until the frontend\n\t has better support for handling it.  */\n      for (size_t i = Tint8; i <= Tuns64; i++)\n\t{\n\t  dtype = Type::basic[i];\n\n\t  /* Search for type matching size and signedness.  */\n\t  if (unsignedp != dtype->isunsigned ()\n\t      || size != dtype->size ())\n\t    continue;\n\n\t  return dtype->addMod (mod);\n\t}\n      break;\n    }\n\n    case REAL_TYPE:\n    {\n      unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));\n\n      for (size_t i = Tfloat32; i <= Tfloat80; i++)\n\t{\n\t  dtype = Type::basic[i];\n\n\t  /* Search for type matching size.  */\n\t  if (dtype->size () != size)\n\t    continue;\n\n\t  return dtype->addMod (mod);\n\t}\n      break;\n    }\n\n    case COMPLEX_TYPE:\n    {\n      unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));\n      for (size_t i = Tcomplex32; i <= Tcomplex80; i++)\n\t{\n\t  dtype = Type::basic[i];\n\n\t  /* Search for type matching size.  */\n\t  if (dtype->size () != size)\n\t    continue;\n\n\t  return dtype->addMod (mod);\n\t}\n      break;\n    }\n\n    case VOID_TYPE:\n      return Type::tvoid->addMod (mod);\n\n    case ARRAY_TYPE:\n      dtype = build_frontend_type (TREE_TYPE (type));\n      if (dtype)\n\t{\n\t  tree index = TYPE_DOMAIN (type);\n\t  tree ub = TYPE_MAX_VALUE (index);\n\t  tree lb = TYPE_MIN_VALUE (index);\n\n\t  tree length = fold_build2 (MINUS_EXPR, TREE_TYPE (lb), ub, lb);\n\t  length = size_binop (PLUS_EXPR, size_one_node,\n\t\t\t       convert (sizetype, length));\n\n\t  dtype = dtype->sarrayOf (TREE_INT_CST_LOW (length))->addMod (mod);\n\t  builtin_converted_decls.safe_push (builtin_data (dtype, type));\n\t  return dtype;\n\t}\n      break;\n\n    case VECTOR_TYPE:\n      dtype = build_frontend_type (TREE_TYPE (type));\n      if (dtype)\n\t{\n\t  poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (type);\n\t  dtype = dtype->sarrayOf (nunits.to_constant ())->addMod (mod);\n\n\t  if (dtype->nextOf ()->isTypeBasic () == NULL)\n\t    break;\n\n\t  dtype = (TypeVector::create (dtype))->addMod (mod);\n\t  builtin_converted_decls.safe_push (builtin_data (dtype, type));\n\t  return dtype;\n\t}\n      break;\n\n    case RECORD_TYPE:\n      if (TYPE_NAME (type))\n\t{\n\t  tree structname = DECL_NAME (TYPE_NAME (type));\n\t  Identifier *ident\n\t    = Identifier::idPool (IDENTIFIER_POINTER (structname));\n\n\t  /* Neither the `object' and `gcc.builtins' modules will not exist when\n\t     this is called.  Use a stub 'object' module parent in the meantime.\n\t     If `gcc.builtins' is later imported, the parent will be overridden\n\t     with the correct module symbol.  */\n\t  static Identifier *object = Identifier::idPool (\"object\");\n\t  static Module *stubmod = Module::create (\"object.d\", object, 0, 0);\n\n\t  StructDeclaration *sdecl = StructDeclaration::create (Loc (), ident,\n\t\t\t\t\t\t\t\tfalse);\n\t  sdecl->parent = stubmod;\n\t  sdecl->structsize = int_size_in_bytes (type);\n\t  sdecl->alignsize = TYPE_ALIGN_UNIT (type);\n\t  sdecl->alignment = STRUCTALIGN_DEFAULT;\n\t  sdecl->sizeok = SIZEOKdone;\n\t  sdecl->type = (TypeStruct::create (sdecl))->addMod (mod);\n\t  sdecl->type->ctype = type;\n\t  sdecl->type->merge2 ();\n\n\t  /* Does not seem necessary to convert fields, but the members field\n\t     must be non-null for the above size setting to stick.  */\n\t  sdecl->members = new Dsymbols;\n\t  dtype = sdecl->type;\n\t  builtin_converted_decls.safe_push (builtin_data (dtype, type, sdecl));\n\t  return dtype;\n\t}\n      break;\n\n    case FUNCTION_TYPE:\n      dtype = build_frontend_type (TREE_TYPE (type));\n      if (dtype)\n\t{\n\t  tree parms = TYPE_ARG_TYPES (type);\n\t  int varargs_p = 1;\n\n\t  Parameters *args = new Parameters;\n\t  args->reserve (list_length (parms));\n\n\t  /* Attempt to convert all parameter types.  */\n\t  for (tree parm = parms; parm != NULL_TREE; parm = TREE_CHAIN (parm))\n\t    {\n\t      tree argtype = TREE_VALUE (parm);\n\t      if (argtype == void_type_node)\n\t\t{\n\t\t  varargs_p = 0;\n\t\t  break;\n\t\t}\n\n\t      StorageClass sc = STCundefined;\n\t      if (TREE_CODE (argtype) == REFERENCE_TYPE)\n\t\t{\n\t\t  argtype = TREE_TYPE (argtype);\n\t\t  sc |= STCref;\n\t\t}\n\n\t      Type *targ = build_frontend_type (argtype);\n\t      if (!targ)\n\t\t{\n\t\t  delete args;\n\t\t  return NULL;\n\t\t}\n\n\t      args->push (Parameter::create (sc, targ, NULL, NULL, NULL));\n\t    }\n\n\t  /* GCC generic and placeholder built-ins are marked as variadic, yet\n\t     have no named parameters, and so can't be represented in D.  */\n\t  if (args->dim != 0 || !varargs_p)\n\t    {\n\t      dtype = TypeFunction::create (args, dtype, varargs_p, LINKc);\n\t      return dtype->addMod (mod);\n\t    }\n\t}\n      break;\n\n    default:\n      break;\n    }\n\n  return NULL;\n}\n\n/* Attempt to convert GCC evaluated CST to a D Frontend Expression.\n   This is used for getting the CTFE value out of a const-folded builtin,\n   returns NULL if it cannot convert CST.  */\n\nExpression *\nd_eval_constant_expression (tree cst)\n{\n  STRIP_TYPE_NOPS (cst);\n  Type *type = build_frontend_type (TREE_TYPE (cst));\n\n  if (type)\n    {\n      /* Convert our GCC CST tree into a D Expression.  This seems like we are\n\t trying too hard, as these will only be converted back to a tree again\n\t later in the codegen pass, but satisfies the need to have GCC built-ins\n\t CTFE-able in the frontend.  */\n      tree_code code = TREE_CODE (cst);\n      if (code == COMPLEX_CST)\n\t{\n\t  real_value re = TREE_REAL_CST (TREE_REALPART (cst));\n\t  real_value im = TREE_REAL_CST (TREE_IMAGPART (cst));\n\t  complex_t value = complex_t (ldouble (re), ldouble (im));\n\t  return ComplexExp::create (Loc (), value, type);\n\t}\n      else if (code == INTEGER_CST)\n\t{\n\t  dinteger_t value = TREE_INT_CST_LOW (cst);\n\t  return IntegerExp::create (Loc (), value, type);\n\t}\n      else if (code == REAL_CST)\n\t{\n\t  real_value value = TREE_REAL_CST (cst);\n\t  return RealExp::create (Loc (), ldouble (value), type);\n\t}\n      else if (code == STRING_CST)\n\t{\n\t  const void *string = TREE_STRING_POINTER (cst);\n\t  size_t len = TREE_STRING_LENGTH (cst);\n\t  return StringExp::create (Loc (), CONST_CAST (void *, string), len);\n\t}\n      else if (code == VECTOR_CST)\n\t{\n\t  dinteger_t nunits = VECTOR_CST_NELTS (cst).to_constant ();\n\t  Expressions *elements = new Expressions;\n\t  elements->setDim (nunits);\n\n\t  for (size_t i = 0; i < nunits; i++)\n\t    {\n\t      Expression *elem\n\t\t= d_eval_constant_expression (VECTOR_CST_ELT (cst, i));\n\t      if (elem == NULL)\n\t\treturn NULL;\n\n\t      (*elements)[i] = elem;\n\t    }\n\n\t  Expression *e = ArrayLiteralExp::create (Loc (), elements);\n\t  e->type = ((TypeVector *) type)->basetype;\n\n\t  return VectorExp::create (Loc (), e, type);\n\t}\n    }\n\n  return NULL;\n}\n\n/* Callback for TARGET_D_CPU_VERSIONS and TARGET_D_OS_VERSIONS.\n   Adds IDENT to the list of predefined version identifiers.  */\n\nvoid\nd_add_builtin_version (const char* ident)\n{\n  /* For now, we need to tell the D frontend what platform is being targeted.\n     This should be removed once the frontend has been fixed.  */\n  if (strcmp (ident, \"linux\") == 0)\n    global.params.isLinux = true;\n  else if (strcmp (ident, \"OSX\") == 0)\n    global.params.isOSX = true;\n  else if (strcmp (ident, \"Windows\") == 0)\n    global.params.isWindows = true;\n  else if (strcmp (ident, \"FreeBSD\") == 0)\n    global.params.isFreeBSD = true;\n  else if (strcmp (ident, \"OpenBSD\") == 0)\n    global.params.isOpenBSD = true;\n  else if (strcmp (ident, \"Solaris\") == 0)\n    global.params.isSolaris = true;\n  /* The is64bit field only refers to x86_64 target.  */\n  else if (strcmp (ident, \"X86_64\") == 0)\n    global.params.is64bit = true;\n  /* No other fields are required to be set for the frontend.  */\n\n  VersionCondition::addPredefinedGlobalIdent (ident);\n}\n\n/* Initialize the list of all the predefined version identifiers.  */\n\nvoid\nd_init_versions (void)\n{\n  VersionCondition::addPredefinedGlobalIdent (\"GNU\");\n  VersionCondition::addPredefinedGlobalIdent (\"D_Version2\");\n\n  if (BYTES_BIG_ENDIAN)\n    VersionCondition::addPredefinedGlobalIdent (\"BigEndian\");\n  else\n    VersionCondition::addPredefinedGlobalIdent (\"LittleEndian\");\n\n  if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)\n    VersionCondition::addPredefinedGlobalIdent (\"GNU_SjLj_Exceptions\");\n  else if (targetm_common.except_unwind_info (&global_options) == UI_SEH)\n    VersionCondition::addPredefinedGlobalIdent (\"GNU_SEH_Exceptions\");\n  else if (targetm_common.except_unwind_info (&global_options) == UI_DWARF2)\n    VersionCondition::addPredefinedGlobalIdent (\"GNU_DWARF2_Exceptions\");\n\n  if (!targetm.have_tls)\n    VersionCondition::addPredefinedGlobalIdent (\"GNU_EMUTLS\");\n\n#ifdef STACK_GROWS_DOWNWARD\n  VersionCondition::addPredefinedGlobalIdent (\"GNU_StackGrowsDown\");\n#endif\n\n  /* Should define this anyway to set us apart from the competition.  */\n  VersionCondition::addPredefinedGlobalIdent (\"GNU_InlineAsm\");\n\n  /* LP64 only means 64bit pointers in D.  */\n  if (global.params.isLP64)\n    VersionCondition::addPredefinedGlobalIdent (\"D_LP64\");\n\n  /* Setting `global.params.cov' forces module info generation which is\n     not needed for the GCC coverage implementation.  Instead, just\n     test flag_test_coverage while leaving `global.params.cov' unset.  */\n  if (flag_test_coverage)\n    VersionCondition::addPredefinedGlobalIdent (\"D_Coverage\");\n  if (flag_pic)\n    VersionCondition::addPredefinedGlobalIdent (\"D_PIC\");\n\n  if (global.params.doDocComments)\n    VersionCondition::addPredefinedGlobalIdent (\"D_Ddoc\");\n\n  if (global.params.useUnitTests)\n    VersionCondition::addPredefinedGlobalIdent (\"unittest\");\n\n  if (global.params.useAssert == CHECKENABLEon)\n    VersionCondition::addPredefinedGlobalIdent (\"assert\");\n\n  if (global.params.useArrayBounds == CHECKENABLEoff)\n    VersionCondition::addPredefinedGlobalIdent (\"D_NoBoundsChecks\");\n\n  if (global.params.betterC)\n    VersionCondition::addPredefinedGlobalIdent (\"D_BetterC\");\n  else\n    {\n      VersionCondition::addPredefinedGlobalIdent (\"D_ModuleInfo\");\n      VersionCondition::addPredefinedGlobalIdent (\"D_Exceptions\");\n      VersionCondition::addPredefinedGlobalIdent (\"D_TypeInfo\");\n    }\n\n  VersionCondition::addPredefinedGlobalIdent (\"all\");\n\n  /* Emit all target-specific version identifiers.  */\n  targetdm.d_cpu_versions ();\n  targetdm.d_os_versions ();\n}\n\n/* A helper for d_build_builtins_module.  Return a new ALIAS for TYPE.\n   Analogous to `alias ALIAS = TYPE' in D code.  */\n\nstatic AliasDeclaration *\nbuild_alias_declaration (const char *alias, Type *type)\n{\n  return AliasDeclaration::create (Loc (), Identifier::idPool (alias), type);\n}\n\n/* A helper function for Target::loadModule.  Generates all code for the\n   `gcc.builtins' module, whose frontend symbol should be M.  */\n\nvoid\nd_build_builtins_module (Module *m)\n{\n  Dsymbols *members = new Dsymbols;\n  tree decl;\n\n  for (size_t i = 0; vec_safe_iterate (gcc_builtins_functions, i, &decl); ++i)\n    {\n      const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));\n      TypeFunction *tf\n\t= (TypeFunction *) build_frontend_type (TREE_TYPE (decl));\n\n      /* Cannot create built-in function type for DECL.  */\n      if (!tf)\n\tcontinue;\n\n      /* A few notes on D2 attributes applied to builtin functions:\n\t - It is assumed that built-ins solely provided by the compiler are\n\t   considered @safe and pure.\n\t - Built-ins that correspond to `extern(C)' functions in the standard\n\t   library that have `__attribute__(nothrow)' are considered `@trusted'.\n\t - The purity of a built-in can vary depending on compiler flags set\n\t   upon initialization, or by the `-foptions' passed, such as\n\t   flag_unsafe_math_optimizations.\n\t - Built-ins never use the GC or raise a D exception, and so are always\n\t   marked as `nothrow' and `@nogc'.  */\n      tf->purity = DECL_PURE_P (decl) ? PUREstrong\n\t: TREE_READONLY (decl) ? PUREconst\n\t: DECL_IS_NOVOPS (decl) ? PUREweak\n\t: !DECL_ASSEMBLER_NAME_SET_P (decl) ? PUREweak\n\t: PUREimpure;\n      tf->trust = !DECL_ASSEMBLER_NAME_SET_P (decl) ? TRUSTsafe\n\t: TREE_NOTHROW (decl) ? TRUSTtrusted\n\t: TRUSTsystem;\n      tf->isnothrow = true;\n      tf->isnogc = true;\n\n      FuncDeclaration *func\n\t= FuncDeclaration::create (Loc (), Loc (),\n\t\t\t\t   Identifier::idPool (name),\n\t\t\t\t   STCextern, tf);\n      DECL_LANG_SPECIFIC (decl) = build_lang_decl (func);\n      func->csym = decl;\n      func->builtin = BUILTINyes;\n\n      members->push (func);\n    }\n\n  for (size_t i = 0; vec_safe_iterate (gcc_builtins_types, i, &decl); ++i)\n    {\n      const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));\n      Type *t = build_frontend_type (TREE_TYPE (decl));\n\n      /* Cannot create built-in type for DECL.  */\n      if (!t)\n\tcontinue;\n\n      members->push (build_alias_declaration (name, t));\n    }\n\n  /* Iterate through the target-specific builtin types for va_list.  */\n  if (targetm.enum_va_list_p)\n    {\n      const char *name;\n      tree type;\n\n      for (int i = 0; targetm.enum_va_list_p (i, &name, &type); ++i)\n\t{\n\t  Type *t = build_frontend_type (type);\n\t  /* Cannot create built-in type.  */\n\t  if (!t)\n\t    continue;\n\n\t  members->push (build_alias_declaration (name, t));\n\t}\n    }\n\n  /* Push out declarations for any RECORD_TYPE types encountered when building\n     all builtin functions and types.  */\n  for (size_t i = 0; i < builtin_converted_decls.length (); ++i)\n    {\n      /* Currently, there is no need to run semantic, but we do want to output\n\t initializers, typeinfo, and others on demand.  */\n      Dsymbol *dsym = builtin_converted_decls[i].dsym;\n      if (dsym != NULL)\n\t{\n\t  dsym->parent = m;\n\t  members->push (dsym);\n\t}\n    }\n\n  /* va_list should already be built, so no need to convert to D type again.  */\n  members->push (build_alias_declaration (\"__builtin_va_list\", Type::tvalist));\n\n  /* Expose target-specific integer types to the builtins module.  */\n  {\n    Type *t = build_frontend_type (long_integer_type_node);\n    members->push (build_alias_declaration (\"__builtin_clong\", t));\n\n    t = build_frontend_type (long_unsigned_type_node);\n    members->push (build_alias_declaration (\"__builtin_culong\", t));\n\n    t = build_frontend_type (long_long_integer_type_node);\n    members->push (build_alias_declaration (\"__builtin_clonglong\", t));\n\n    t = build_frontend_type (long_long_unsigned_type_node);\n    members->push (build_alias_declaration (\"__builtin_culonglong\", t));\n\n    t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 0));\n    members->push (build_alias_declaration (\"__builtin_machine_byte\", t));\n\n    t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 1));\n    members->push (build_alias_declaration (\"__builtin_machine_ubyte\", t));\n\n    t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 0));\n    members->push (build_alias_declaration (\"__builtin_machine_int\", t));\n\n    t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 1));\n    members->push (build_alias_declaration (\"__builtin_machine_uint\", t));\n\n    t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 0));\n    members->push (build_alias_declaration (\"__builtin_pointer_int\", t));\n\n    t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 1));\n    members->push (build_alias_declaration (\"__builtin_pointer_uint\", t));\n\n    /* _Unwind_Word has its own target specific mode.  */\n    machine_mode mode = targetm.unwind_word_mode ();\n    t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 0));\n    members->push (build_alias_declaration (\"__builtin_unwind_int\", t));\n\n    t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 1));\n    members->push (build_alias_declaration (\"__builtin_unwind_uint\", t));\n  }\n\n  m->members->push (LinkDeclaration::create (LINKc, members));\n}\n\n/* Search for any `extern(C)' functions that match any known GCC library builtin\n   function in D and override its internal back-end symbol.  */\n\nstatic void\nmaybe_set_builtin_1 (Dsymbol *d)\n{\n  AttribDeclaration *ad = d->isAttribDeclaration ();\n  FuncDeclaration *fd = d->isFuncDeclaration ();\n\n  if (ad != NULL)\n    {\n      /* Recursively search through attribute decls.  */\n      Dsymbols *decls = ad->include (NULL);\n      if (decls && decls->dim)\n\t{\n\t  for (size_t i = 0; i < decls->dim; i++)\n\t    {\n\t      Dsymbol *sym = (*decls)[i];\n\t      maybe_set_builtin_1 (sym);\n\t    }\n\t}\n    }\n  else if (fd && !fd->fbody)\n    {\n      tree t;\n\n      for (size_t i = 0; vec_safe_iterate (gcc_builtins_libfuncs, i, &t); ++i)\n\t{\n\t  gcc_assert (DECL_ASSEMBLER_NAME_SET_P (t));\n\n\t  const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));\n\t  if (fd->ident != Identifier::idPool (name))\n\t    continue;\n\n\t  /* Found a match, tell the frontend this is a builtin.  */\n\t  DECL_LANG_SPECIFIC (t) = build_lang_decl (fd);\n\t  fd->csym = t;\n\t  fd->builtin = BUILTINyes;\n\t  return;\n\t}\n    }\n}\n\n/* A helper function for Target::loadModule.  Traverse all members in module M\n   to search for any functions that can be mapped to any GCC builtin.  */\n\nvoid\nd_maybe_set_builtin (Module *m)\n{\n  if (!m || !m->members)\n    return;\n\n  for (size_t i = 0; i < m->members->dim; i++)\n    {\n      Dsymbol *sym = (*m->members)[i];\n      maybe_set_builtin_1 (sym);\n    }\n}\n\n/* Used to help initialize the builtin-types.def table.  When a type of\n   the correct size doesn't exist, use error_mark_node instead of NULL.\n   The latter results in segfaults even when a decl using the type doesn't\n   get invoked.  */\n\nstatic tree\nbuiltin_type_for_size (int size, bool unsignedp)\n{\n  tree type = lang_hooks.types.type_for_size (size, unsignedp);\n  return type ? type : error_mark_node;\n}\n\n/* Support for DEF_BUILTIN.  */\n\nstatic void\ndo_build_builtin_fn (built_in_function fncode,\n\t\t     const char *name,\n\t\t     built_in_class fnclass,\n\t\t     tree fntype, bool both_p, bool fallback_p,\n\t\t     tree fnattrs, bool implicit_p)\n{\n  tree decl;\n  const char *libname;\n\n  if (fntype == error_mark_node)\n    return;\n\n  gcc_assert ((!both_p && !fallback_p)\n\t      || !strncmp (name, \"__builtin_\",\n\t\t\t   strlen (\"__builtin_\")));\n\n  libname = name + strlen (\"__builtin_\");\n\n  decl = add_builtin_function (name, fntype, fncode, fnclass,\n\t\t\t       fallback_p ? libname : NULL, fnattrs);\n\n  set_builtin_decl (fncode, decl, implicit_p);\n}\n\n/* Standard data types to be used in builtin argument declarations.  */\n\nstatic GTY(()) tree string_type_node;\nstatic GTY(()) tree const_string_type_node;\nstatic GTY(()) tree wint_type_node;\nstatic GTY(()) tree intmax_type_node;\nstatic GTY(()) tree uintmax_type_node;\nstatic GTY(()) tree signed_size_type_node;\n\n\n/* Build nodes that would have been created by the C front-end; necessary\n   for including builtin-types.def and ultimately builtins.def.  */\n\nstatic void\nd_build_c_type_nodes (void)\n{\n  void_list_node = build_tree_list (NULL_TREE, void_type_node);\n  string_type_node = build_pointer_type (char_type_node);\n  const_string_type_node\n    = build_pointer_type (build_qualified_type (char_type_node,\n\t\t\t\t\t\tTYPE_QUAL_CONST));\n\n  if (strcmp (SIZE_TYPE, \"unsigned int\") == 0)\n    {\n      intmax_type_node = integer_type_node;\n      uintmax_type_node = unsigned_type_node;\n      signed_size_type_node = integer_type_node;\n    }\n  else if (strcmp (SIZE_TYPE, \"long unsigned int\") == 0)\n    {\n      intmax_type_node = long_integer_type_node;\n      uintmax_type_node = long_unsigned_type_node;\n      signed_size_type_node = long_integer_type_node;\n    }\n  else if (strcmp (SIZE_TYPE, \"long long unsigned int\") == 0)\n    {\n      intmax_type_node = long_long_integer_type_node;\n      uintmax_type_node = long_long_unsigned_type_node;\n      signed_size_type_node = long_long_integer_type_node;\n    }\n  else\n    gcc_unreachable ();\n\n  wint_type_node = unsigned_type_node;\n  pid_type_node = integer_type_node;\n}\n\n/* Build nodes that are used by the D front-end.\n   These are distinct from C types.  */\n\nstatic void\nd_build_d_type_nodes (void)\n{\n  /* Integral types.  */\n  d_byte_type = make_signed_type (8);\n  d_ubyte_type = make_unsigned_type (8);\n\n  d_short_type = make_signed_type (16);\n  d_ushort_type = make_unsigned_type (16);\n\n  d_int_type = make_signed_type (32);\n  d_uint_type = make_unsigned_type (32);\n\n  d_long_type = make_signed_type (64);\n  d_ulong_type = make_unsigned_type (64);\n\n  d_cent_type = make_signed_type (128);\n  d_ucent_type = make_unsigned_type (128);\n\n  {\n    /* Re-define size_t as a D type.  */\n    machine_mode type_mode = TYPE_MODE (size_type_node);\n    size_type_node = lang_hooks.types.type_for_mode (type_mode, 1);\n  }\n\n  /* Bool and Character types.  */\n  d_bool_type = make_unsigned_type (1);\n  TREE_SET_CODE (d_bool_type, BOOLEAN_TYPE);\n\n  char8_type_node = make_unsigned_type (8);\n  TYPE_STRING_FLAG (char8_type_node) = 1;\n\n  char16_type_node = make_unsigned_type (16);\n  TYPE_STRING_FLAG (char16_type_node) = 1;\n\n  char32_type_node = make_unsigned_type (32);\n  TYPE_STRING_FLAG (char32_type_node) = 1;\n\n  /* Imaginary types.  */\n  ifloat_type_node = build_distinct_type_copy (float_type_node);\n  TYPE_IMAGINARY_FLOAT (ifloat_type_node) = 1;\n\n  idouble_type_node = build_distinct_type_copy (double_type_node);\n  TYPE_IMAGINARY_FLOAT (idouble_type_node) = 1;\n\n  ireal_type_node = build_distinct_type_copy (long_double_type_node);\n  TYPE_IMAGINARY_FLOAT (ireal_type_node) = 1;\n\n  /* Used for ModuleInfo, ClassInfo, and Interface decls.  */\n  unknown_type_node = make_node (RECORD_TYPE);\n\n  /* Make sure we get a unique function type, so we can give\n     its pointer type a name.  (This wins for gdb).  */\n  {\n    tree vfunc_type = make_node (FUNCTION_TYPE);\n    TREE_TYPE (vfunc_type) = d_int_type;\n    TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;\n    layout_type (vfunc_type);\n\n    vtable_entry_type = build_pointer_type (vfunc_type);\n  }\n\n  vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);\n  layout_type (vtbl_ptr_type_node);\n\n  /* When an object is accessed via an interface, this type appears\n     as the first entry in its vtable.  */\n  {\n    tree domain = build_index_type (size_int (3));\n    vtbl_interface_type_node = build_array_type (ptr_type_node, domain);\n  }\n\n  /* Use `void[]' as a generic dynamic array type.  */\n  array_type_node = make_struct_type (\"__builtin_void[]\", 2,\n\t\t\t\t      get_identifier (\"length\"), size_type_node,\n\t\t\t\t      get_identifier (\"ptr\"), ptr_type_node);\n  TYPE_DYNAMIC_ARRAY (array_type_node) = 1;\n\n  null_array_node = d_array_value (array_type_node, size_zero_node,\n\t\t\t\t   null_pointer_node);\n}\n\n/* Handle default attributes.  */\n\nenum built_in_attribute\n{\n#define DEF_ATTR_NULL_TREE(ENUM) ENUM,\n#define DEF_ATTR_INT(ENUM, VALUE) ENUM,\n#define DEF_ATTR_STRING(ENUM, VALUE) ENUM,\n#define DEF_ATTR_IDENT(ENUM, STRING) ENUM,\n#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,\n#include \"builtin-attrs.def\"\n#undef DEF_ATTR_NULL_TREE\n#undef DEF_ATTR_INT\n#undef DEF_ATTR_STRING\n#undef DEF_ATTR_IDENT\n#undef DEF_ATTR_TREE_LIST\n  ATTR_LAST\n};\n\nstatic GTY(()) tree built_in_attributes[(int) ATTR_LAST];\n\n/* Initialize the attribute table for all the supported builtins.  */\n\nstatic void\nd_init_attributes (void)\n{\n  /* Fill in the built_in_attributes array.  */\n#define DEF_ATTR_NULL_TREE(ENUM)\t\\\n  built_in_attributes[(int) ENUM] = NULL_TREE;\n# define DEF_ATTR_INT(ENUM, VALUE)\t\\\n  built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);\n#define DEF_ATTR_STRING(ENUM, VALUE)\t\\\n  built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);\n#define DEF_ATTR_IDENT(ENUM, STRING)\t\\\n  built_in_attributes[(int) ENUM] = get_identifier (STRING);\n#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN)\t\\\n  built_in_attributes[(int) ENUM]\t\t\t\\\n  = tree_cons (built_in_attributes[(int) PURPOSE],\t\\\n\t       built_in_attributes[(int) VALUE],\t\\\n\t       built_in_attributes[(int) CHAIN]);\n#include \"builtin-attrs.def\"\n#undef DEF_ATTR_NULL_TREE\n#undef DEF_ATTR_INT\n#undef DEF_ATTR_STRING\n#undef DEF_ATTR_IDENT\n#undef DEF_ATTR_TREE_LIST\n}\n\n/* Builtin types.  */\n\nenum d_builtin_type\n{\n#define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,\n#define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,\n#define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,\n#define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,\n#define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,\n#define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,\n#define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,\n#define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t    ARG6) NAME,\n#define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t    ARG6, ARG7) NAME,\n#define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t    ARG6, ARG7, ARG8) NAME,\n#define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t    ARG6, ARG7, ARG8, ARG9) NAME,\n#define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t     ARG6, ARG7, ARG8, ARG9, ARG10) NAME,\n#define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t     ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,\n#define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,\n#define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,\n#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,\n#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,\n#define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,\n#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \\\n\t\t\t\tNAME,\n#define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t\tARG6) NAME,\n#define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t\tARG6, ARG7) NAME,\n#define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t\t ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,\n#define DEF_POINTER_TYPE(NAME, TYPE) NAME,\n#include \"builtin-types.def\"\n#undef DEF_PRIMITIVE_TYPE\n#undef DEF_FUNCTION_TYPE_0\n#undef DEF_FUNCTION_TYPE_1\n#undef DEF_FUNCTION_TYPE_2\n#undef DEF_FUNCTION_TYPE_3\n#undef DEF_FUNCTION_TYPE_4\n#undef DEF_FUNCTION_TYPE_5\n#undef DEF_FUNCTION_TYPE_6\n#undef DEF_FUNCTION_TYPE_7\n#undef DEF_FUNCTION_TYPE_8\n#undef DEF_FUNCTION_TYPE_9\n#undef DEF_FUNCTION_TYPE_10\n#undef DEF_FUNCTION_TYPE_11\n#undef DEF_FUNCTION_TYPE_VAR_0\n#undef DEF_FUNCTION_TYPE_VAR_1\n#undef DEF_FUNCTION_TYPE_VAR_2\n#undef DEF_FUNCTION_TYPE_VAR_3\n#undef DEF_FUNCTION_TYPE_VAR_4\n#undef DEF_FUNCTION_TYPE_VAR_5\n#undef DEF_FUNCTION_TYPE_VAR_6\n#undef DEF_FUNCTION_TYPE_VAR_7\n#undef DEF_FUNCTION_TYPE_VAR_11\n#undef DEF_POINTER_TYPE\n  BT_LAST\n};\n\ntypedef enum d_builtin_type builtin_type;\n\n/* A temporary array used in communication with def_fn_type.  */\nstatic GTY(()) tree builtin_types[(int) BT_LAST + 1];\n\n/* A helper function for d_init_builtins.  Build function type for DEF with\n   return type RET and N arguments.  If VAR is true, then the function should\n   be variadic after those N arguments.\n\n   Takes special care not to ICE if any of the types involved are\n   error_mark_node, which indicates that said type is not in fact available\n   (see builtin_type_for_size).  In which case the function type as a whole\n   should be error_mark_node.  */\n\nstatic void\ndef_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)\n{\n  tree t;\n  tree *args = XALLOCAVEC (tree, n);\n  va_list list;\n  int i;\n\n  va_start (list, n);\n  for (i = 0; i < n; ++i)\n    {\n      builtin_type a = (builtin_type) va_arg (list, int);\n      t = builtin_types[a];\n      if (t == error_mark_node)\n\tgoto egress;\n      args[i] = t;\n    }\n\n  t = builtin_types[ret];\n  if (t == error_mark_node)\n    goto egress;\n  if (var)\n    t = build_varargs_function_type_array (t, n, args);\n  else\n    t = build_function_type_array (t, n, args);\n\n egress:\n  builtin_types[def] = t;\n  va_end (list);\n}\n\n/* Create builtin types and functions.  VA_LIST_REF_TYPE_NODE and\n   VA_LIST_ARG_TYPE_NODE are used in builtin-types.def.  */\n\nstatic void\nd_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,\n\t\t   tree va_list_arg_type_node ATTRIBUTE_UNUSED)\n{\n#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \\\n  builtin_types[(int) ENUM] = VALUE;\n#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \\\n  def_fn_type (ENUM, RETURN, 0, 0);\n#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \\\n  def_fn_type (ENUM, RETURN, 0, 1, ARG1);\n#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \\\n  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);\n#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \\\n  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);\n#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \\\n  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);\n#define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \\\n  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);\n#define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t    ARG6)\t\t\t\t\t\\\n  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);\n#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t    ARG6, ARG7)\t\t\t\t\t\\\n  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);\n#define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t    ARG6, ARG7, ARG8)\t\t\t\t\\\n  def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \\\n\t       ARG7, ARG8);\n#define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t    ARG6, ARG7, ARG8, ARG9)\t\t\t\\\n  def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \\\n\t       ARG7, ARG8, ARG9);\n#define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t    ARG6, ARG7, ARG8, ARG9, ARG10)\t\t \\\n  def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \\\n\t       ARG7, ARG8, ARG9, ARG10);\n#define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t    ARG6, ARG7, ARG8, ARG9, ARG10, ARG11)\t \\\n  def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \\\n\t       ARG7, ARG8, ARG9, ARG10, ARG11);\n#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \\\n  def_fn_type (ENUM, RETURN, 1, 0);\n#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \\\n  def_fn_type (ENUM, RETURN, 1, 1, ARG1);\n#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \\\n  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);\n#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \\\n  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);\n#define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \\\n  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);\n#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \\\n  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);\n#define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t\tARG6)\t\t\t\t\t    \\\n  def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);\n#define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t\tARG6, ARG7)\t\t\t\t    \\\n  def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);\n#define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \\\n\t\t\t\t ARG6, ARG7, ARG8, ARG9, ARG10, ARG11)       \\\n  def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,      \\\n\t       ARG7, ARG8, ARG9, ARG10, ARG11);\n#define DEF_POINTER_TYPE(ENUM, TYPE) \\\n  builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);\n\n#include \"builtin-types.def\"\n\n#undef DEF_PRIMITIVE_TYPE\n#undef DEF_FUNCTION_TYPE_1\n#undef DEF_FUNCTION_TYPE_2\n#undef DEF_FUNCTION_TYPE_3\n#undef DEF_FUNCTION_TYPE_4\n#undef DEF_FUNCTION_TYPE_5\n#undef DEF_FUNCTION_TYPE_6\n#undef DEF_FUNCTION_TYPE_7\n#undef DEF_FUNCTION_TYPE_8\n#undef DEF_FUNCTION_TYPE_9\n#undef DEF_FUNCTION_TYPE_10\n#undef DEF_FUNCTION_TYPE_11\n#undef DEF_FUNCTION_TYPE_VAR_0\n#undef DEF_FUNCTION_TYPE_VAR_1\n#undef DEF_FUNCTION_TYPE_VAR_2\n#undef DEF_FUNCTION_TYPE_VAR_3\n#undef DEF_FUNCTION_TYPE_VAR_4\n#undef DEF_FUNCTION_TYPE_VAR_5\n#undef DEF_FUNCTION_TYPE_VAR_6\n#undef DEF_FUNCTION_TYPE_VAR_7\n#undef DEF_FUNCTION_TYPE_VAR_11\n#undef DEF_POINTER_TYPE\n  builtin_types[(int) BT_LAST] = NULL_TREE;\n\n  d_init_attributes ();\n\n#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \\\n\t\t    NONANSI_P, ATTRS, IMPLICIT, COND)\t\t\t  \\\n  if (NAME && COND)\t\t\t\t\t\t\t  \\\n    do_build_builtin_fn (ENUM, NAME, CLASS,\t\t\t\t  \\\n\t\t\t builtin_types[(int) TYPE],\t\t\t  \\\n\t\t\t BOTH_P, FALLBACK_P,\t\t\t\t  \\\n\t\t\t built_in_attributes[(int) ATTRS], IMPLICIT);\n#include \"builtins.def\"\n#undef DEF_BUILTIN\n}\n\n/* Build builtin functions and types for the D language frontend.  */\n\nvoid\nd_init_builtins (void)\n{\n  /* Build the \"standard\" abi va_list.  */\n  Type::tvalist = build_frontend_type (va_list_type_node);\n  if (!Type::tvalist)\n    {\n      error (\"cannot represent built-in va_list type in D\");\n      gcc_unreachable ();\n    }\n\n  /* Map the va_list type to the D frontend Type.  This is to prevent both\n     errors in gimplification or an ICE in targetm.canonical_va_list_type.  */\n  Type::tvalist->ctype = va_list_type_node;\n  TYPE_LANG_SPECIFIC (va_list_type_node) = build_lang_type (Type::tvalist);\n\n  d_build_c_type_nodes ();\n  d_build_d_type_nodes ();\n\n  if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)\n    {\n      /* It might seem natural to make the argument type a pointer, but there\n\t is no implicit casting from arrays to pointers in D.  */\n      d_define_builtins (va_list_type_node, va_list_type_node);\n    }\n  else\n    {\n      d_define_builtins (build_reference_type (va_list_type_node),\n\t\t\t va_list_type_node);\n    }\n\n  targetm.init_builtins ();\n  build_common_builtin_nodes ();\n}\n\n/* Registration of machine- or os-specific builtin types.\n   Add to builtin types list for maybe processing later\n   if `gcc.builtins' was imported into the current module.  */\n\nvoid\nd_register_builtin_type (tree type, const char *name)\n{\n  tree decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL,\n\t\t\t  get_identifier (name), type);\n  DECL_ARTIFICIAL (decl) = 1;\n\n  if (!TYPE_NAME (type))\n    TYPE_NAME (type) = decl;\n\n  vec_safe_push (gcc_builtins_types, decl);\n}\n\n/* Add DECL to builtin functions list for maybe processing later\n   if `gcc.builtins' was imported into the current module.  */\n\ntree\nd_builtin_function (tree decl)\n{\n  if (!flag_no_builtin && DECL_ASSEMBLER_NAME_SET_P (decl))\n    vec_safe_push (gcc_builtins_libfuncs, decl);\n\n  vec_safe_push (gcc_builtins_functions, decl);\n  return decl;\n}\n\n\n#include \"gt-d-d-builtins.h\"\n"
  },
  {
    "path": "gcc/d/d-codegen.cc",
    "content": "/* d-codegen.cc --  Code generation and routines for manipulation of GCC trees.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/aggregate.h\"\n#include \"dmd/ctfe.h\"\n#include \"dmd/declaration.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/target.h\"\n#include \"dmd/template.h\"\n\n#include \"tree.h\"\n#include \"tree-iterator.h\"\n#include \"fold-const.h\"\n#include \"diagnostic.h\"\n#include \"langhooks.h\"\n#include \"target.h\"\n#include \"stringpool.h\"\n#include \"varasm.h\"\n#include \"stor-layout.h\"\n#include \"attribs.h\"\n#include \"function.h\"\n\n#include \"d-tree.h\"\n\n\n/* Return the GCC location for the D frontend location LOC.  */\n\nlocation_t\nmake_location_t (const Loc& loc)\n{\n  location_t gcc_location = input_location;\n\n  if (loc.filename)\n    {\n      linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum);\n      linemap_line_start (line_table, loc.linnum, 0);\n      gcc_location = linemap_position_for_column (line_table, loc.charnum);\n      linemap_add (line_table, LC_LEAVE, 0, NULL, 0);\n    }\n\n  return gcc_location;\n}\n\n/* Return the DECL_CONTEXT for symbol DSYM.  */\n\ntree\nd_decl_context (Dsymbol *dsym)\n{\n  Dsymbol *parent = dsym;\n  Declaration *decl = dsym->isDeclaration ();\n\n  while ((parent = parent->toParent ()))\n    {\n      /* We've reached the top-level module namespace.\n\t Set DECL_CONTEXT as the NAMESPACE_DECL of the enclosing module,\n\t but only for extern(D) symbols.  */\n      if (parent->isModule ())\n\t{\n\t  if (decl != NULL && decl->linkage != LINKd)\n\t    return NULL_TREE;\n\n\t  return build_import_decl (parent);\n\t}\n\n      /* Declarations marked as 'static' or '__gshared' are never\n\t part of any context except at module level.  */\n      if (decl != NULL && decl->isDataseg ())\n\tcontinue;\n\n      /* Nested functions.  */\n      FuncDeclaration *fd = parent->isFuncDeclaration ();\n      if (fd != NULL)\n\treturn get_symbol_decl (fd);\n\n      /* Methods of classes or structs.  */\n      AggregateDeclaration *ad = parent->isAggregateDeclaration ();\n      if (ad != NULL)\n\t{\n\t  tree context = build_ctype (ad->type);\n\t  /* Want the underlying RECORD_TYPE.  */\n\t  if (ad->isClassDeclaration ())\n\t    context = TREE_TYPE (context);\n\n\t  return context;\n\t}\n\n      /* Instantiated types are given the context of their template.  */\n      TemplateInstance *ti = parent->isTemplateInstance ();\n      if (ti != NULL && decl == NULL)\n\tparent = ti->tempdecl;\n    }\n\n  return NULL_TREE;\n}\n\n/* Return a copy of record TYPE but safe to modify in any way.  */\n\ntree\ncopy_aggregate_type (tree type)\n{\n  tree newtype = build_distinct_type_copy (type);\n  TYPE_FIELDS (newtype) = copy_list (TYPE_FIELDS (type));\n\n  for (tree f = TYPE_FIELDS (newtype); f; f = DECL_CHAIN (f))\n    DECL_FIELD_CONTEXT (f) = newtype;\n\n  return newtype;\n}\n\n/* Return TRUE if declaration DECL is a reference type.  */\n\nbool\ndeclaration_reference_p (Declaration *decl)\n{\n  Type *tb = decl->type->toBasetype ();\n\n  /* Declaration is a reference type.  */\n  if (tb->ty == Treference || decl->storage_class & (STCout | STCref))\n    return true;\n\n  return false;\n}\n\n/* Returns the real type for declaration DECL.  */\n\ntree\ndeclaration_type (Declaration *decl)\n{\n  /* Lazy declarations are converted to delegates.  */\n  if (decl->storage_class & STClazy)\n    {\n      TypeFunction *tf = TypeFunction::create (NULL, decl->type, false, LINKd);\n      TypeDelegate *t = TypeDelegate::create (tf);\n      return build_ctype (t->merge2 ());\n    }\n\n  /* Static array va_list have array->pointer conversions applied.  */\n  if (decl->isParameter () && valist_array_p (decl->type))\n    {\n      Type *valist = decl->type->nextOf ()->pointerTo ();\n      valist = valist->castMod (decl->type->mod);\n      return build_ctype (valist);\n    }\n\n  tree type = build_ctype (decl->type);\n\n  /* Parameter is passed by reference.  */\n  if (declaration_reference_p (decl))\n    return build_reference_type (type);\n\n  /* The 'this' parameter is always const.  */\n  if (decl->isThisDeclaration ())\n    return insert_type_modifiers (type, MODconst);\n\n  return type;\n}\n\n/* These should match the Declaration versions above\n   Return TRUE if parameter ARG is a reference type.  */\n\nbool\nargument_reference_p (Parameter *arg)\n{\n  Type *tb = arg->type->toBasetype ();\n\n  /* Parameter is a reference type.  */\n  if (tb->ty == Treference || arg->storageClass & (STCout | STCref))\n    return true;\n\n  tree type = build_ctype (arg->type);\n  if (TREE_ADDRESSABLE (type))\n    return true;\n\n  return false;\n}\n\n/* Returns the real type for parameter ARG.  */\n\ntree\ntype_passed_as (Parameter *arg)\n{\n  /* Lazy parameters are converted to delegates.  */\n  if (arg->storageClass & STClazy)\n    {\n      TypeFunction *tf = TypeFunction::create (NULL, arg->type, false, LINKd);\n      TypeDelegate *t = TypeDelegate::create (tf);\n      return build_ctype (t->merge2 ());\n    }\n\n  /* Static array va_list have array->pointer conversions applied.  */\n  if (valist_array_p (arg->type))\n    {\n      Type *valist = arg->type->nextOf ()->pointerTo ();\n      valist = valist->castMod (arg->type->mod);\n      return build_ctype (valist);\n    }\n\n  tree type = build_ctype (arg->type);\n\n  /* Parameter is passed by reference.  */\n  if (argument_reference_p (arg))\n    return build_reference_type (type);\n\n  return type;\n}\n\n/* Build INTEGER_CST of type TYPE with the value VALUE.  */\n\ntree\nbuild_integer_cst (dinteger_t value, tree type)\n{\n  /* The type is error_mark_node, we can't do anything.  */\n  if (error_operand_p (type))\n    return type;\n\n  return build_int_cst_type (type, value);\n}\n\n/* Build REAL_CST of type TOTYPE with the value VALUE.  */\n\ntree\nbuild_float_cst (const real_t& value, Type *totype)\n{\n  real_t new_value;\n  TypeBasic *tb = totype->isTypeBasic ();\n\n  gcc_assert (tb != NULL);\n\n  tree type_node = build_ctype (tb);\n  real_convert (&new_value.rv (), TYPE_MODE (type_node), &value.rv ());\n\n  return build_real (type_node, new_value.rv ());\n}\n\n/* Returns the .length component from the D dynamic array EXP.  */\n\ntree\nd_array_length (tree exp)\n{\n  if (error_operand_p (exp))\n    return exp;\n\n  gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp)));\n\n  /* Get the back-end type for the array and pick out the array\n     length field (assumed to be the first field).  */\n  tree len_field = TYPE_FIELDS (TREE_TYPE (exp));\n  return component_ref (exp, len_field);\n}\n\n/* Returns the .ptr component from the D dynamic array EXP.  */\n\ntree\nd_array_ptr (tree exp)\n{\n  if (error_operand_p (exp))\n    return exp;\n\n  gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp)));\n\n  /* Get the back-end type for the array and pick out the array\n     data pointer field (assumed to be the second field).  */\n  tree ptr_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp)));\n  return component_ref (exp, ptr_field);\n}\n\n/* Returns a constructor for D dynamic array type TYPE of .length LEN\n   and .ptr pointing to DATA.  */\n\ntree\nd_array_value (tree type, tree len, tree data)\n{\n  tree len_field, ptr_field;\n  vec<constructor_elt, va_gc> *ce = NULL;\n\n  gcc_assert (TYPE_DYNAMIC_ARRAY (type));\n  len_field = TYPE_FIELDS (type);\n  ptr_field = TREE_CHAIN (len_field);\n\n  len = convert (TREE_TYPE (len_field), len);\n  data = convert (TREE_TYPE (ptr_field), data);\n\n  CONSTRUCTOR_APPEND_ELT (ce, len_field, len);\n  CONSTRUCTOR_APPEND_ELT (ce, ptr_field, data);\n\n  return build_constructor (type, ce);\n}\n\n/* Returns value representing the array length of expression EXP.\n   TYPE could be a dynamic or static array.  */\n\ntree\nget_array_length (tree exp, Type *type)\n{\n  Type *tb = type->toBasetype ();\n\n  switch (tb->ty)\n    {\n    case Tsarray:\n      return size_int (((TypeSArray *) tb)->dim->toUInteger ());\n\n    case Tarray:\n      return d_array_length (exp);\n\n    default:\n      error (\"can't determine the length of a %qs\", type->toChars ());\n      return error_mark_node;\n    }\n}\n\n/* Create BINFO for a ClassDeclaration's inheritance tree.\n   InterfaceDeclaration's are not included.  */\n\ntree\nbuild_class_binfo (tree super, ClassDeclaration *cd)\n{\n  tree binfo = make_tree_binfo (1);\n  tree ctype = build_ctype (cd->type);\n\n  /* Want RECORD_TYPE, not POINTER_TYPE.  */\n  BINFO_TYPE (binfo) = TREE_TYPE (ctype);\n  BINFO_INHERITANCE_CHAIN (binfo) = super;\n  BINFO_OFFSET (binfo) = integer_zero_node;\n\n  if (cd->baseClass)\n    BINFO_BASE_APPEND (binfo, build_class_binfo (binfo, cd->baseClass));\n\n  return binfo;\n}\n\n/* Create BINFO for an InterfaceDeclaration's inheritance tree.\n   In order to access all inherited methods in the debugger,\n   the entire tree must be described.\n   This function makes assumptions about interface layout.  */\n\ntree\nbuild_interface_binfo (tree super, ClassDeclaration *cd, unsigned& offset)\n{\n  tree binfo = make_tree_binfo (cd->baseclasses->dim);\n  tree ctype = build_ctype (cd->type);\n\n  /* Want RECORD_TYPE, not POINTER_TYPE.  */\n  BINFO_TYPE (binfo) = TREE_TYPE (ctype);\n  BINFO_INHERITANCE_CHAIN (binfo) = super;\n  BINFO_OFFSET (binfo) = size_int (offset * Target::ptrsize);\n  BINFO_VIRTUAL_P (binfo) = 1;\n\n  for (size_t i = 0; i < cd->baseclasses->dim; i++, offset++)\n    {\n      BaseClass *bc = (*cd->baseclasses)[i];\n      BINFO_BASE_APPEND (binfo, build_interface_binfo (binfo, bc->sym, offset));\n    }\n\n  return binfo;\n}\n\n/* Returns the .funcptr component from the D delegate EXP.  */\n\ntree\ndelegate_method (tree exp)\n{\n  /* Get the back-end type for the delegate and pick out the funcptr field\n     (assumed to be the second field).  */\n  gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp)));\n  tree method_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp)));\n  return component_ref (exp, method_field);\n}\n\n/* Returns the .object component from the delegate EXP.  */\n\ntree\ndelegate_object (tree exp)\n{\n  /* Get the back-end type for the delegate and pick out the object field\n     (assumed to be the first field).  */\n  gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp)));\n  tree obj_field = TYPE_FIELDS (TREE_TYPE (exp));\n  return component_ref (exp, obj_field);\n}\n\n/* Build a delegate literal of type TYPE whose pointer function is\n   METHOD, and hidden object is OBJECT.  */\n\ntree\nbuild_delegate_cst (tree method, tree object, Type *type)\n{\n  tree ctor = make_node (CONSTRUCTOR);\n  tree ctype;\n\n  Type *tb = type->toBasetype ();\n  if (tb->ty == Tdelegate)\n    ctype = build_ctype (type);\n  else\n    {\n      /* Convert a function method into an anonymous delegate.  */\n      ctype = make_struct_type (\"delegate()\", 2,\n\t\t\t\tget_identifier (\"object\"), TREE_TYPE (object),\n\t\t\t\tget_identifier (\"func\"), TREE_TYPE (method));\n      TYPE_DELEGATE (ctype) = 1;\n    }\n\n  vec<constructor_elt, va_gc> *ce = NULL;\n  CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (ctype), object);\n  CONSTRUCTOR_APPEND_ELT (ce, TREE_CHAIN (TYPE_FIELDS (ctype)), method);\n\n  CONSTRUCTOR_ELTS (ctor) = ce;\n  TREE_TYPE (ctor) = ctype;\n\n  return ctor;\n}\n\n/* Builds a temporary tree to store the CALLEE and OBJECT\n   of a method call expression of type TYPE.  */\n\ntree\nbuild_method_call (tree callee, tree object, Type *type)\n{\n  tree t = build_delegate_cst (callee, object, type);\n  METHOD_CALL_EXPR (t) = 1;\n  return t;\n}\n\n/* Extract callee and object from T and return in to CALLEE and OBJECT.  */\n\nvoid\nextract_from_method_call (tree t, tree& callee, tree& object)\n{\n  gcc_assert (METHOD_CALL_EXPR (t));\n  object = CONSTRUCTOR_ELT (t, 0)->value;\n  callee = CONSTRUCTOR_ELT (t, 1)->value;\n}\n\n/* Build a dereference into the virtual table for OBJECT to retrieve\n   a function pointer of type FNTYPE at position INDEX.  */\n\ntree\nbuild_vindex_ref (tree object, tree fntype, size_t index)\n{\n  /* The vtable is the first field.  Interface methods are also in the class's\n     vtable, so we don't need to convert from a class to an interface.  */\n  tree result = build_deref (object);\n  result = component_ref (result, TYPE_FIELDS (TREE_TYPE (result)));\n\n  gcc_assert (POINTER_TYPE_P (fntype));\n\n  return build_memref (fntype, result, size_int (Target::ptrsize * index));\n}\n\n/* Return TRUE if EXP is a valid lvalue.  Lvalue references cannot be\n   made into temporaries, otherwise any assignments will be lost.  */\n\nstatic bool\nlvalue_p (tree exp)\n{\n  const enum tree_code code = TREE_CODE (exp);\n\n  switch (code)\n    {\n    case SAVE_EXPR:\n      return false;\n\n    case ARRAY_REF:\n    case INDIRECT_REF:\n    case VAR_DECL:\n    case PARM_DECL:\n    case RESULT_DECL:\n      return !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (exp));\n\n    case IMAGPART_EXPR:\n    case REALPART_EXPR:\n    case COMPONENT_REF:\n    CASE_CONVERT:\n      return lvalue_p (TREE_OPERAND (exp, 0));\n\n    case COND_EXPR:\n      return (lvalue_p (TREE_OPERAND (exp, 1)\n\t\t\t? TREE_OPERAND (exp, 1)\n\t\t\t: TREE_OPERAND (exp, 0))\n\t      && lvalue_p (TREE_OPERAND (exp, 2)));\n\n    case TARGET_EXPR:\n      return true;\n\n    case COMPOUND_EXPR:\n      return lvalue_p (TREE_OPERAND (exp, 1));\n\n    default:\n      return false;\n    }\n}\n\n/* Create a SAVE_EXPR if EXP might have unwanted side effects if referenced\n   more than once in an expression.  */\n\ntree\nd_save_expr (tree exp)\n{\n  if (TREE_SIDE_EFFECTS (exp))\n    {\n      if (lvalue_p (exp))\n\treturn stabilize_reference (exp);\n\n      return save_expr (exp);\n    }\n\n  return exp;\n}\n\n/* VALUEP is an expression we want to pre-evaluate or perform a computation on.\n   The expression returned by this function is the part whose value we don't\n   care about, storing the value in VALUEP.  Callers must ensure that the\n   returned expression is evaluated before VALUEP.  */\n\ntree\nstabilize_expr (tree *valuep)\n{\n  tree expr = *valuep;\n  const enum tree_code code = TREE_CODE (expr);\n  tree lhs;\n  tree rhs;\n\n  switch (code)\n    {\n    case COMPOUND_EXPR:\n      /* Given ((e1, ...), eN):\n\t Store the last RHS 'eN' expression in VALUEP.  */\n      lhs = TREE_OPERAND (expr, 0);\n      rhs = TREE_OPERAND (expr, 1);\n      lhs = compound_expr (lhs, stabilize_expr (&rhs));\n      *valuep = rhs;\n      return lhs;\n\n    default:\n      return NULL_TREE;\n    }\n}\n\n/* Return a TARGET_EXPR, initializing the DECL with EXP.  */\n\ntree\nbuild_target_expr (tree decl, tree exp)\n{\n  tree type = TREE_TYPE (decl);\n  tree result = build4 (TARGET_EXPR, type, decl, exp, NULL_TREE, NULL_TREE);\n\n  if (EXPR_HAS_LOCATION (exp))\n    SET_EXPR_LOCATION (result, EXPR_LOCATION (exp));\n\n  /* If decl must always reside in memory.  */\n  if (TREE_ADDRESSABLE (type))\n    d_mark_addressable (decl);\n\n  /* Always set TREE_SIDE_EFFECTS so that expand_expr does not ignore the\n     TARGET_EXPR.  If there really turn out to be no side effects, then the\n     optimizer should be able to remove it.  */\n  TREE_SIDE_EFFECTS (result) = 1;\n\n  return result;\n}\n\n/* Like the above function, but initializes a new temporary.  */\n\ntree\nforce_target_expr (tree exp)\n{\n  tree decl = create_temporary_var (TREE_TYPE (exp));\n\n  return build_target_expr (decl, exp);\n}\n\n/* Returns the address of the expression EXP.  */\n\ntree\nbuild_address (tree exp)\n{\n  if (error_operand_p (exp))\n    return exp;\n\n  tree ptrtype;\n  tree type = TREE_TYPE (exp);\n\n  if (TREE_CODE (exp) == STRING_CST)\n    {\n      /* Just convert string literals (char[]) to C-style strings (char *),\n\t otherwise the latter method (char[]*) causes conversion problems\n\t during gimplification.  */\n      ptrtype = build_pointer_type (TREE_TYPE (type));\n    }\n  else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node)\n\t   && TREE_CODE (TYPE_MAIN_VARIANT (type)) == ARRAY_TYPE)\n    {\n      /* Special case for va_list, allow arrays to decay to a pointer.  */\n      ptrtype = build_pointer_type (TREE_TYPE (type));\n    }\n  else\n    ptrtype = build_pointer_type (type);\n\n  /* Maybe rewrite: &(e1, e2) => (e1, &e2).  */\n  tree init = stabilize_expr (&exp);\n\n  /* Can't take the address of a manifest constant, instead use its value.  */\n  if (TREE_CODE (exp) == CONST_DECL)\n    exp = DECL_INITIAL (exp);\n\n  /* Some expression lowering may request an address of a compile-time constant.\n     Make sure it is assigned to a location we can reference.  */\n  if (CONSTANT_CLASS_P (exp) && TREE_CODE (exp) != STRING_CST)\n    exp = force_target_expr (exp);\n\n  d_mark_addressable (exp);\n  exp = build_fold_addr_expr_with_type_loc (input_location, exp, ptrtype);\n\n  if (TREE_CODE (exp) == ADDR_EXPR)\n    TREE_NO_TRAMPOLINE (exp) = 1;\n\n  return compound_expr (init, exp);\n}\n\n/* Mark EXP saying that we need to be able to take the\n   address of it; it should not be allocated in a register.  */\n\ntree\nd_mark_addressable (tree exp)\n{\n  switch (TREE_CODE (exp))\n    {\n    case ADDR_EXPR:\n    case COMPONENT_REF:\n    case ARRAY_REF:\n    case REALPART_EXPR:\n    case IMAGPART_EXPR:\n      d_mark_addressable (TREE_OPERAND (exp, 0));\n      break;\n\n    case PARM_DECL:\n    case VAR_DECL:\n    case RESULT_DECL:\n    case CONST_DECL:\n    case FUNCTION_DECL:\n      TREE_ADDRESSABLE (exp) = 1;\n      break;\n\n    case CONSTRUCTOR:\n      TREE_ADDRESSABLE (exp) = 1;\n      break;\n\n    case TARGET_EXPR:\n      TREE_ADDRESSABLE (exp) = 1;\n      d_mark_addressable (TREE_OPERAND (exp, 0));\n      break;\n\n    default:\n      break;\n    }\n\n  return exp;\n}\n\n/* Mark EXP as \"used\" in the program for the benefit of\n   -Wunused warning purposes.  */\n\ntree\nd_mark_used (tree exp)\n{\n  switch (TREE_CODE (exp))\n    {\n    case VAR_DECL:\n    case CONST_DECL:\n    case PARM_DECL:\n    case RESULT_DECL:\n    case FUNCTION_DECL:\n      TREE_USED (exp) = 1;\n      break;\n\n    case ARRAY_REF:\n    case COMPONENT_REF:\n    case MODIFY_EXPR:\n    case REALPART_EXPR:\n    case IMAGPART_EXPR:\n    case NOP_EXPR:\n    case CONVERT_EXPR:\n    case ADDR_EXPR:\n      d_mark_used (TREE_OPERAND (exp, 0));\n      break;\n\n    case COMPOUND_EXPR:\n      d_mark_used (TREE_OPERAND (exp, 0));\n      d_mark_used (TREE_OPERAND (exp, 1));\n      break;\n\n    default:\n      break;\n    }\n  return exp;\n}\n\n/* Mark EXP as read, not just set, for set but not used -Wunused\n   warning purposes.  */\n\ntree\nd_mark_read (tree exp)\n{\n  switch (TREE_CODE (exp))\n    {\n    case VAR_DECL:\n    case PARM_DECL:\n      TREE_USED (exp) = 1;\n      DECL_READ_P (exp) = 1;\n      break;\n\n    case ARRAY_REF:\n    case COMPONENT_REF:\n    case MODIFY_EXPR:\n    case REALPART_EXPR:\n    case IMAGPART_EXPR:\n    case NOP_EXPR:\n    case CONVERT_EXPR:\n    case ADDR_EXPR:\n      d_mark_read (TREE_OPERAND (exp, 0));\n      break;\n\n    case COMPOUND_EXPR:\n      d_mark_read (TREE_OPERAND (exp, 1));\n      break;\n\n    default:\n      break;\n    }\n  return exp;\n}\n\n/* Return TRUE if the struct SD is suitable for comparison using memcmp.\n   This is because we don't guarantee that padding is zero-initialized for\n   a stack variable, so we can't use memcmp to compare struct values.  */\n\nbool\nidentity_compare_p (StructDeclaration *sd)\n{\n  if (sd->isUnionDeclaration ())\n    return true;\n\n  unsigned offset = 0;\n\n  for (size_t i = 0; i < sd->fields.dim; i++)\n    {\n      VarDeclaration *vd = sd->fields[i];\n\n      /* Check inner data structures.  */\n      if (vd->type->ty == Tstruct)\n\t{\n\t  TypeStruct *ts = (TypeStruct *) vd->type;\n\t  if (!identity_compare_p (ts->sym))\n\t    return false;\n\t}\n\n      if (offset <= vd->offset)\n\t{\n\t  /* There's a hole in the struct.  */\n\t  if (offset != vd->offset)\n\t    return false;\n\n\t  offset += vd->type->size ();\n\t}\n    }\n\n  /* Any trailing padding may not be zero.  */\n  if (offset < sd->structsize)\n    return false;\n\n  return true;\n}\n\n/* Lower a field-by-field equality expression between T1 and T2 of type SD.\n   CODE is the EQ_EXPR or NE_EXPR comparison.  */\n\nstatic tree\nlower_struct_comparison (tree_code code, StructDeclaration *sd,\n\t\t\t tree t1, tree t2)\n{\n  tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;\n  tree tmemcmp = NULL_TREE;\n\n  /* We can skip the compare if the structs are empty.  */\n  if (sd->fields.dim == 0)\n    {\n      tmemcmp = build_boolop (code, integer_zero_node, integer_zero_node);\n      if (TREE_SIDE_EFFECTS (t2))\n\ttmemcmp = compound_expr (t2, tmemcmp);\n      if (TREE_SIDE_EFFECTS (t1))\n\ttmemcmp = compound_expr (t1, tmemcmp);\n\n      return tmemcmp;\n    }\n\n  /* Let back-end take care of union comparisons.  */\n  if (sd->isUnionDeclaration ())\n    {\n      tmemcmp = build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP), 3,\n\t\t\t\t build_address (t1), build_address (t2),\n\t\t\t\t size_int (sd->structsize));\n\n      return build_boolop (code, tmemcmp, integer_zero_node);\n    }\n\n  for (size_t i = 0; i < sd->fields.dim; i++)\n    {\n      VarDeclaration *vd = sd->fields[i];\n      tree sfield = get_symbol_decl (vd);\n\n      tree t1ref = component_ref (t1, sfield);\n      tree t2ref = component_ref (t2, sfield);\n      tree tcmp;\n\n      if (vd->type->ty == Tstruct)\n\t{\n\t  /* Compare inner data structures.  */\n\t  StructDeclaration *decl = ((TypeStruct *) vd->type)->sym;\n\t  tcmp = lower_struct_comparison (code, decl, t1ref, t2ref);\n\t}\n      else\n\t{\n\t  tree stype = build_ctype (vd->type);\n\t  opt_scalar_int_mode mode = int_mode_for_mode (TYPE_MODE (stype));\n\n\t  if (vd->type->ty != Tvector && vd->type->isintegral ())\n\t    {\n\t      /* Integer comparison, no special handling required.  */\n\t      tcmp = build_boolop (code, t1ref, t2ref);\n\t    }\n\t  else if (mode.exists ())\n\t    {\n\t      /* Compare field bits as their corresponding integer type.\n\t\t    *((T*) &t1) == *((T*) &t2)  */\n\t      tree tmode = lang_hooks.types.type_for_mode (mode.require (), 1);\n\n\t      if (tmode == NULL_TREE)\n\t\ttmode = make_unsigned_type (GET_MODE_BITSIZE (mode.require ()));\n\n\t      t1ref = build_vconvert (tmode, t1ref);\n\t      t2ref = build_vconvert (tmode, t2ref);\n\n\t      tcmp = build_boolop (code, t1ref, t2ref);\n\t    }\n\t  else\n\t    {\n\t      /* Simple memcmp between types.  */\n\t      tcmp = build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP),\n\t\t\t\t      3, build_address (t1ref),\n\t\t\t\t      build_address (t2ref),\n\t\t\t\t      TYPE_SIZE_UNIT (stype));\n\n\t      tcmp = build_boolop (code, tcmp, integer_zero_node);\n\t    }\n\t}\n\n      tmemcmp = (tmemcmp) ? build_boolop (tcode, tmemcmp, tcmp) : tcmp;\n    }\n\n  return tmemcmp;\n}\n\n\n/* Build an equality expression between two RECORD_TYPES T1 and T2 of type SD.\n   If possible, use memcmp, otherwise field-by-field comparison is done.\n   CODE is the EQ_EXPR or NE_EXPR comparison.  */\n\ntree\nbuild_struct_comparison (tree_code code, StructDeclaration *sd,\n\t\t\t tree t1, tree t2)\n{\n  /* We can skip the compare if the structs are empty.  */\n  if (sd->fields.dim == 0)\n    {\n      tree exp = build_boolop (code, integer_zero_node, integer_zero_node);\n      if (TREE_SIDE_EFFECTS (t2))\n\texp = compound_expr (t2, exp);\n      if (TREE_SIDE_EFFECTS (t1))\n\texp = compound_expr (t1, exp);\n\n      return exp;\n    }\n\n  /* Make temporaries to prevent multiple evaluations.  */\n  tree t1init = stabilize_expr (&t1);\n  tree t2init = stabilize_expr (&t2);\n  tree result;\n\n  t1 = d_save_expr (t1);\n  t2 = d_save_expr (t2);\n\n  /* Bitwise comparison of structs not returned in memory may not work\n     due to data holes loosing its zero padding upon return.\n     As a heuristic, small structs are not compared using memcmp either.  */\n  if (TYPE_MODE (TREE_TYPE (t1)) != BLKmode || !identity_compare_p (sd))\n    result = lower_struct_comparison (code, sd, t1, t2);\n  else\n    {\n      /* Do bit compare of structs.  */\n      tree size = size_int (sd->structsize);\n      tree tmemcmp = build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP),\n\t\t\t\t      3, build_address (t1),\n\t\t\t\t      build_address (t2), size);\n\n      result = build_boolop (code, tmemcmp, integer_zero_node);\n    }\n\n  return compound_expr (compound_expr (t1init, t2init), result);\n}\n\n/* Build an equality expression between two ARRAY_TYPES of size LENGTH.\n   The pointer references are T1 and T2, and the element type is SD.\n   CODE is the EQ_EXPR or NE_EXPR comparison.  */\n\ntree\nbuild_array_struct_comparison (tree_code code, StructDeclaration *sd,\n\t\t\t       tree length, tree t1, tree t2)\n{\n  tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;\n\n  /* Build temporary for the result of the comparison.\n     Initialize as either 0 or 1 depending on operation.  */\n  tree result = build_local_temp (d_bool_type);\n  tree init = build_boolop (code, integer_zero_node, integer_zero_node);\n  add_stmt (build_assign (INIT_EXPR, result, init));\n\n  /* Cast pointer-to-array to pointer-to-struct.  */\n  tree ptrtype = build_ctype (sd->type->pointerTo ());\n  tree lentype = TREE_TYPE (length);\n\n  push_binding_level (level_block);\n  push_stmt_list ();\n\n  /* Build temporary locals for length and pointers.  */\n  tree t = build_local_temp (size_type_node);\n  add_stmt (build_assign (INIT_EXPR, t, length));\n  length = t;\n\n  t = build_local_temp (ptrtype);\n  add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t1)));\n  t1 = t;\n\n  t = build_local_temp (ptrtype);\n  add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t2)));\n  t2 = t;\n\n  /* Build loop for comparing each element.  */\n  push_stmt_list ();\n\n  /* Exit logic for the loop.\n\tif (length == 0 || result OP 0) break;  */\n  t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));\n  t = build_boolop (TRUTH_ORIF_EXPR, t, build_boolop (code, result,\n\t\t\t\t\t\t      boolean_false_node));\n  t = build1 (EXIT_EXPR, void_type_node, t);\n  add_stmt (t);\n\n  /* Do comparison, caching the value.\n\tresult = result OP (*t1 == *t2);  */\n  t = build_struct_comparison (code, sd, build_deref (t1), build_deref (t2));\n  t = build_boolop (tcode, result, t);\n  t = modify_expr (result, t);\n  add_stmt (t);\n\n  /* Move both pointers to next element position.\n\tt1++, t2++;  */\n  tree size = d_convert (ptrtype, TYPE_SIZE_UNIT (TREE_TYPE (ptrtype)));\n  t = build2 (POSTINCREMENT_EXPR, ptrtype, t1, size);\n  add_stmt (t);\n  t = build2 (POSTINCREMENT_EXPR, ptrtype, t2, size);\n  add_stmt (t);\n\n  /* Decrease loop counter.\n\tlength -= 1;  */\n  t = build2 (POSTDECREMENT_EXPR, lentype, length,\n\t     d_convert (lentype, integer_one_node));\n  add_stmt (t);\n\n  /* Pop statements and finish loop.  */\n  tree body = pop_stmt_list ();\n  add_stmt (build1 (LOOP_EXPR, void_type_node, body));\n\n  /* Wrap it up into a bind expression.  */\n  tree stmt_list = pop_stmt_list ();\n  tree block = pop_binding_level ();\n\n  body = build3 (BIND_EXPR, void_type_node,\n\t\t BLOCK_VARS (block), stmt_list, block);\n\n  return compound_expr (body, result);\n}\n\n/* Create an anonymous field of type ubyte[T] at OFFSET to fill\n   the alignment hole between OFFSET and FIELDPOS.  */\n\nstatic tree\nbuild_alignment_field (tree type, HOST_WIDE_INT offset, HOST_WIDE_INT fieldpos)\n{\n  tree atype = make_array_type (Type::tuns8, fieldpos - offset);\n  tree field = create_field_decl (atype, NULL, 1, 1);\n\n  SET_DECL_OFFSET_ALIGN (field, TYPE_ALIGN (atype));\n  DECL_FIELD_OFFSET (field) = size_int (offset);\n  DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;\n  DECL_FIELD_CONTEXT (field) = type;\n  DECL_PADDING_P (field) = 1;\n\n  layout_decl (field, 0);\n\n  return field;\n}\n\n/* Build a constructor for a variable of aggregate type TYPE using the\n   initializer INIT, an ordered flat list of fields and values provided\n   by the frontend.  The returned constructor should be a value that\n   matches the layout of TYPE.  */\n\ntree\nbuild_struct_literal (tree type, vec<constructor_elt, va_gc> *init)\n{\n  /* If the initializer was empty, use default zero initialization.  */\n  if (vec_safe_is_empty (init))\n    return build_constructor (type, NULL);\n\n  vec<constructor_elt, va_gc> *ve = NULL;\n  HOST_WIDE_INT offset = 0;\n  bool constant_p = true;\n  bool fillholes = true;\n  bool finished = false;\n\n  /* Filling alignment holes this only applies to structs.  */\n  if (TREE_CODE (type) != RECORD_TYPE\n      || CLASS_TYPE_P (type) || TYPE_PACKED (type))\n    fillholes = false;\n\n  /* Walk through each field, matching our initializer list.  */\n  for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))\n    {\n      bool is_initialized = false;\n      tree value;\n\n      if (DECL_NAME (field) == NULL_TREE\n\t  && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))\n\t  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))\n\t{\n\t  /* Search all nesting aggregates, if nothing is found, then\n\t     this will return an empty initializer to fill the hole.  */\n\t  value = build_struct_literal (TREE_TYPE (field), init);\n\n\t  if (!initializer_zerop (value))\n\t    is_initialized = true;\n\t}\n      else\n\t{\n\t  /* Search for the value to initialize the next field.  Once found,\n\t     pop it from the init list so we don't look at it again.  */\n\t  unsigned HOST_WIDE_INT idx;\n\t  tree index;\n\n\t  FOR_EACH_CONSTRUCTOR_ELT (init, idx, index, value)\n\t    {\n\t      /* If the index is NULL, then just assign it to the next field.\n\t\t This comes from layout_typeinfo(), which generates a flat\n\t\t list of values that we must shape into the record type.  */\n\t      if (index == field || index == NULL_TREE)\n\t\t{\n\t\t  init->ordered_remove (idx);\n\t\t  if (!finished)\n\t\t    is_initialized = true;\n\t\t  break;\n\t\t}\n\t    }\n\t}\n\n      if (is_initialized)\n\t{\n\t  HOST_WIDE_INT fieldpos = int_byte_position (field);\n\t  gcc_assert (value != NULL_TREE);\n\n\t  /* Insert anonymous fields in the constructor for padding out\n\t     alignment holes in-place between fields.  */\n\t  if (fillholes && offset < fieldpos)\n\t    {\n\t      tree pfield = build_alignment_field (type, offset, fieldpos);\n\t      tree pvalue = build_zero_cst (TREE_TYPE (pfield));\n\t      CONSTRUCTOR_APPEND_ELT (ve, pfield, pvalue);\n\t    }\n\n\t  /* Must not initialize fields that overlap.  */\n\t  if (fieldpos < offset)\n\t    {\n\t      /* Find the nearest user defined type and field.  */\n\t      tree vtype = type;\n\t      while (ANON_AGGR_TYPE_P (vtype))\n\t\tvtype = TYPE_CONTEXT (vtype);\n\n\t      tree vfield = field;\n\t      if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (vfield))\n\t\t  && ANON_AGGR_TYPE_P (TREE_TYPE (vfield)))\n\t\tvfield = TYPE_FIELDS (TREE_TYPE (vfield));\n\n\t      /* Must not generate errors for compiler generated fields.  */\n\t      gcc_assert (TYPE_NAME (vtype) && DECL_NAME (vfield));\n\t      error (\"overlapping initializer for field %qT.%qD\",\n\t\t     TYPE_NAME (vtype), DECL_NAME (vfield));\n\t    }\n\n\t  if (!TREE_CONSTANT (value))\n\t    constant_p = false;\n\n\t  CONSTRUCTOR_APPEND_ELT (ve, field, value);\n\n\t  /* For unions, only the first field is initialized, any other field\n\t     initializers found for this union are drained and ignored.  */\n\t  if (TREE_CODE (type) == UNION_TYPE)\n\t    finished = true;\n\t}\n\n      /* Move offset to the next position in the struct.  */\n      if (TREE_CODE (type) == RECORD_TYPE)\n\t{\n\t  offset = int_byte_position (field)\n\t    + int_size_in_bytes (TREE_TYPE (field));\n\t}\n\n      /* If all initializers have been assigned, there's nothing else to do.  */\n      if (vec_safe_is_empty (init))\n\tbreak;\n    }\n\n  /* Finally pad out the end of the record.  */\n  if (fillholes && offset < int_size_in_bytes (type))\n    {\n      tree pfield = build_alignment_field (type, offset,\n\t\t\t\t\t   int_size_in_bytes (type));\n      tree pvalue = build_zero_cst (TREE_TYPE (pfield));\n      CONSTRUCTOR_APPEND_ELT (ve, pfield, pvalue);\n    }\n\n  /* Ensure that we have consumed all values.  */\n  gcc_assert (vec_safe_is_empty (init) || ANON_AGGR_TYPE_P (type));\n\n  tree ctor = build_constructor (type, ve);\n\n  if (constant_p)\n    TREE_CONSTANT (ctor) = 1;\n\n  return ctor;\n}\n\n/* Given the TYPE of an anonymous field inside T, return the\n   FIELD_DECL for the field.  If not found return NULL_TREE.\n   Because anonymous types can nest, we must also search all\n   anonymous fields that are directly reachable.  */\n\nstatic tree\nlookup_anon_field (tree t, tree type)\n{\n  t = TYPE_MAIN_VARIANT (t);\n\n  for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))\n    {\n      if (DECL_NAME (field) == NULL_TREE)\n\t{\n\t  /* If we find it directly, return the field.  */\n\t  if (type == TYPE_MAIN_VARIANT (TREE_TYPE (field)))\n\t    return field;\n\n\t  /* Otherwise, it could be nested, search harder.  */\n\t  if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))\n\t      && ANON_AGGR_TYPE_P (TREE_TYPE (field)))\n\t    {\n\t      tree subfield = lookup_anon_field (TREE_TYPE (field), type);\n\t      if (subfield)\n\t\treturn subfield;\n\t    }\n\t}\n    }\n\n  return NULL_TREE;\n}\n\n/* Builds OBJECT.FIELD component reference.  */\n\ntree\ncomponent_ref (tree object, tree field)\n{\n  if (error_operand_p (object) || error_operand_p (field))\n    return error_mark_node;\n\n  gcc_assert (TREE_CODE (field) == FIELD_DECL);\n\n  /* Maybe rewrite: (e1, e2).field => (e1, e2.field)  */\n  tree init = stabilize_expr (&object);\n\n  /* If the FIELD is from an anonymous aggregate, generate a reference\n     to the anonymous data member, and recur to find FIELD.  */\n  if (ANON_AGGR_TYPE_P (DECL_CONTEXT (field)))\n    {\n      tree anonymous_field = lookup_anon_field (TREE_TYPE (object),\n\t\t\t\t\t\tDECL_CONTEXT (field));\n      object = component_ref (object, anonymous_field);\n    }\n\n  tree result = fold_build3_loc (input_location, COMPONENT_REF,\n\t\t\t\t TREE_TYPE (field), object, field, NULL_TREE);\n\n  return compound_expr (init, result);\n}\n\n/* Build an assignment expression of lvalue LHS from value RHS.\n   CODE is the code for a binary operator that we use to combine\n   the old value of LHS with RHS to get the new value.  */\n\ntree\nbuild_assign (tree_code code, tree lhs, tree rhs)\n{\n  tree init = stabilize_expr (&lhs);\n  init = compound_expr (init, stabilize_expr (&rhs));\n\n  /* If initializing the LHS using a function that returns via NRVO.  */\n  if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR\n      && AGGREGATE_TYPE_P (TREE_TYPE (rhs))\n      && aggregate_value_p (TREE_TYPE (rhs), rhs))\n    {\n      /* Mark as addressable here, which should ensure the return slot is the\n\t address of the LHS expression, taken care of by back-end.  */\n      d_mark_addressable (lhs);\n      CALL_EXPR_RETURN_SLOT_OPT (rhs) = true;\n    }\n\n  /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT.  */\n  if (TREE_CODE (rhs) == TARGET_EXPR)\n    {\n      /* If CODE is not INIT_EXPR, can't initialize LHS directly,\n\t since that would cause the LHS to be constructed twice.\n\t So we force the TARGET_EXPR to be expanded without a target.  */\n      if (code != INIT_EXPR)\n\trhs = compound_expr (rhs, TARGET_EXPR_SLOT (rhs));\n      else\n\t{\n\t  d_mark_addressable (lhs);\n\t  rhs = TARGET_EXPR_INITIAL (rhs);\n\t}\n    }\n\n  tree result = fold_build2_loc (input_location, code,\n\t\t\t\t TREE_TYPE (lhs), lhs, rhs);\n  return compound_expr (init, result);\n}\n\n/* Build an assignment expression of lvalue LHS from value RHS.  */\n\ntree\nmodify_expr (tree lhs, tree rhs)\n{\n  return build_assign (MODIFY_EXPR, lhs, rhs);\n}\n\n/* Return EXP represented as TYPE.  */\n\ntree\nbuild_nop (tree type, tree exp)\n{\n  if (error_operand_p (exp))\n    return exp;\n\n  /* Maybe rewrite: cast(TYPE)(e1, e2) => (e1, cast(TYPE) e2)  */\n  tree init = stabilize_expr (&exp);\n  exp = fold_build1_loc (input_location, NOP_EXPR, type, exp);\n\n  return compound_expr (init, exp);\n}\n\n/* Return EXP to be viewed as being another type TYPE.  Same as build_nop,\n   except that EXP is type-punned, rather than a straight-forward cast.  */\n\ntree\nbuild_vconvert (tree type, tree exp)\n{\n  /* Building *(cast(TYPE *)&e1) directly rather then using VIEW_CONVERT_EXPR\n     makes sure this works for vector-to-array viewing, or if EXP ends up being\n     used as the LHS of a MODIFY_EXPR.  */\n  return indirect_ref (type, build_address (exp));\n}\n\n/* Maybe warn about ARG being an address that can never be null.  */\n\nstatic void\nwarn_for_null_address (tree arg)\n{\n  if (TREE_CODE (arg) == ADDR_EXPR\n      && decl_with_nonnull_addr_p (TREE_OPERAND (arg, 0)))\n    warning (OPT_Waddress,\n\t     \"the address of %qD will never be %<null%>\",\n\t     TREE_OPERAND (arg, 0));\n}\n\n/* Build a boolean ARG0 op ARG1 expression.  */\n\ntree\nbuild_boolop (tree_code code, tree arg0, tree arg1)\n{\n  /* Aggregate comparisons may get lowered to a call to builtin memcmp,\n     so need to remove all side effects incase its address is taken.  */\n  if (AGGREGATE_TYPE_P (TREE_TYPE (arg0)))\n    arg0 = d_save_expr (arg0);\n  if (AGGREGATE_TYPE_P (TREE_TYPE (arg1)))\n    arg1 = d_save_expr (arg1);\n\n  if (VECTOR_TYPE_P (TREE_TYPE (arg0)) && VECTOR_TYPE_P (TREE_TYPE (arg1)))\n    {\n      /* Build a vector comparison.\n\t VEC_COND_EXPR <e1 op e2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */\n      tree type = TREE_TYPE (arg0);\n      tree cmptype = build_same_sized_truth_vector_type (type);\n      tree cmp = fold_build2_loc (input_location, code, cmptype, arg0, arg1);\n\n      return fold_build3_loc (input_location, VEC_COND_EXPR, type, cmp,\n\t\t\t      build_minus_one_cst (type),\n\t\t\t      build_zero_cst (type));\n    }\n\n  if (code == EQ_EXPR || code == NE_EXPR)\n    {\n      /* Check if comparing the address of a variable to null.  */\n      if (POINTER_TYPE_P (TREE_TYPE (arg0)) && integer_zerop (arg1))\n\twarn_for_null_address (arg0);\n      if (POINTER_TYPE_P (TREE_TYPE (arg1)) && integer_zerop (arg0))\n\twarn_for_null_address (arg1);\n    }\n\n  return fold_build2_loc (input_location, code, d_bool_type,\n\t\t\t  arg0, d_convert (TREE_TYPE (arg0), arg1));\n}\n\n/* Return a COND_EXPR.  ARG0, ARG1, and ARG2 are the three\n   arguments to the conditional expression.  */\n\ntree\nbuild_condition (tree type, tree arg0, tree arg1, tree arg2)\n{\n  if (arg1 == void_node)\n    arg1 = build_empty_stmt (input_location);\n\n  if (arg2 == void_node)\n    arg2 = build_empty_stmt (input_location);\n\n  return fold_build3_loc (input_location, COND_EXPR,\n\t\t\t  type, arg0, arg1, arg2);\n}\n\ntree\nbuild_vcondition (tree arg0, tree arg1, tree arg2)\n{\n  return build_condition (void_type_node, arg0, arg1, arg2);\n}\n\n/* Build a compound expr to join ARG0 and ARG1 together.  */\n\ntree\ncompound_expr (tree arg0, tree arg1)\n{\n  if (arg1 == NULL_TREE)\n    return arg0;\n\n  if (arg0 == NULL_TREE || !TREE_SIDE_EFFECTS (arg0))\n    return arg1;\n\n  if (TREE_CODE (arg1) == TARGET_EXPR)\n    {\n      /* If the rhs is a TARGET_EXPR, then build the compound expression\n\t inside the target_expr's initializer.  This helps the compiler\n\t to eliminate unnecessary temporaries.  */\n      tree init = compound_expr (arg0, TARGET_EXPR_INITIAL (arg1));\n      TARGET_EXPR_INITIAL (arg1) = init;\n\n      return arg1;\n    }\n\n  return fold_build2_loc (input_location, COMPOUND_EXPR,\n\t\t\t  TREE_TYPE (arg1), arg0, arg1);\n}\n\n/* Build a return expression.  */\n\ntree\nreturn_expr (tree ret)\n{\n  return fold_build1_loc (input_location, RETURN_EXPR,\n\t\t\t  void_type_node, ret);\n}\n\n/* Return the product of ARG0 and ARG1 as a size_type_node.  */\n\ntree\nsize_mult_expr (tree arg0, tree arg1)\n{\n  return fold_build2_loc (input_location, MULT_EXPR, size_type_node,\n\t\t\t  d_convert (size_type_node, arg0),\n\t\t\t  d_convert (size_type_node, arg1));\n\n}\n\n/* Return the real part of CE, which should be a complex expression.  */\n\ntree\nreal_part (tree ce)\n{\n  return fold_build1_loc (input_location, REALPART_EXPR,\n\t\t\t  TREE_TYPE (TREE_TYPE (ce)), ce);\n}\n\n/* Return the imaginary part of CE, which should be a complex expression.  */\n\ntree\nimaginary_part (tree ce)\n{\n  return fold_build1_loc (input_location, IMAGPART_EXPR,\n\t\t\t  TREE_TYPE (TREE_TYPE (ce)), ce);\n}\n\n/* Build a complex expression of type TYPE using RE and IM.  */\n\ntree\ncomplex_expr (tree type, tree re, tree im)\n{\n  return fold_build2_loc (input_location, COMPLEX_EXPR,\n\t\t\t  type, re, im);\n}\n\n/* Cast EXP (which should be a pointer) to TYPE* and then indirect.\n   The back-end requires this cast in many cases.  */\n\ntree\nindirect_ref (tree type, tree exp)\n{\n  if (error_operand_p (exp))\n    return exp;\n\n  /* Maybe rewrite: *(e1, e2) => (e1, *e2)  */\n  tree init = stabilize_expr (&exp);\n\n  if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE)\n    exp = fold_build1 (INDIRECT_REF, type, exp);\n  else\n    {\n      exp = build_nop (build_pointer_type (type), exp);\n      exp = build_deref (exp);\n    }\n\n  return compound_expr (init, exp);\n}\n\n/* Returns indirect reference of EXP, which must be a pointer type.  */\n\ntree\nbuild_deref (tree exp)\n{\n  if (error_operand_p (exp))\n    return exp;\n\n  /* Maybe rewrite: *(e1, e2) => (e1, *e2)  */\n  tree init = stabilize_expr (&exp);\n\n  gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp)));\n\n  if (TREE_CODE (exp) == ADDR_EXPR)\n    exp = TREE_OPERAND (exp, 0);\n  else\n    exp = build_fold_indirect_ref (exp);\n\n  return compound_expr (init, exp);\n}\n\n/* Builds pointer offset expression PTR[INDEX].  */\n\ntree\nbuild_array_index (tree ptr, tree index)\n{\n  if (error_operand_p (ptr) || error_operand_p (index))\n    return error_mark_node;\n\n  tree ptr_type = TREE_TYPE (ptr);\n  tree target_type = TREE_TYPE (ptr_type);\n\n  tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),\n\t\t\t\t\t      TYPE_UNSIGNED (sizetype));\n\n  /* Array element size.  */\n  tree size_exp = size_in_bytes (target_type);\n\n  if (integer_zerop (size_exp))\n    {\n      /* Test for array of void.  */\n      if (TYPE_MODE (target_type) == TYPE_MODE (void_type_node))\n\tindex = fold_convert (type, index);\n      else\n\t{\n\t  /* Should catch this earlier.  */\n\t  error (\"invalid use of incomplete type %qD\", TYPE_NAME (target_type));\n\t  ptr_type = error_mark_node;\n\t}\n    }\n  else if (integer_onep (size_exp))\n    {\n      /* Array of bytes -- No need to multiply.  */\n      index = fold_convert (type, index);\n    }\n  else\n    {\n      index = d_convert (type, index);\n      index = fold_build2 (MULT_EXPR, TREE_TYPE (index),\n\t\t\t   index, d_convert (TREE_TYPE (index), size_exp));\n      index = fold_convert (type, index);\n    }\n\n  if (integer_zerop (index))\n    return ptr;\n\n  return fold_build2 (POINTER_PLUS_EXPR, ptr_type, ptr, index);\n}\n\n/* Builds pointer offset expression *(PTR OP OFFSET)\n   OP could be a plus or minus expression.  */\n\ntree\nbuild_offset_op (tree_code op, tree ptr, tree offset)\n{\n  gcc_assert (op == MINUS_EXPR || op == PLUS_EXPR);\n\n  tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),\n\t\t\t\t\t      TYPE_UNSIGNED (sizetype));\n  offset = fold_convert (type, offset);\n\n  if (op == MINUS_EXPR)\n    offset = fold_build1 (NEGATE_EXPR, type, offset);\n\n  return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, offset);\n}\n\n/* Builds pointer offset expression *(PTR + OFFSET).  */\n\ntree\nbuild_offset (tree ptr, tree offset)\n{\n  return build_offset_op (PLUS_EXPR, ptr, offset);\n}\n\ntree\nbuild_memref (tree type, tree ptr, tree offset)\n{\n  return fold_build2 (MEM_REF, type, ptr, fold_convert (type, offset));\n}\n\n/* Create a tree node to set multiple elements to a single value.  */\n\ntree\nbuild_array_set (tree ptr, tree length, tree value)\n{\n  tree ptrtype = TREE_TYPE (ptr);\n  tree lentype = TREE_TYPE (length);\n\n  push_binding_level (level_block);\n  push_stmt_list ();\n\n  /* Build temporary locals for length and ptr, and maybe value.  */\n  tree t = build_local_temp (size_type_node);\n  add_stmt (build_assign (INIT_EXPR, t, length));\n  length = t;\n\n  t = build_local_temp (ptrtype);\n  add_stmt (build_assign (INIT_EXPR, t, ptr));\n  ptr = t;\n\n  if (TREE_SIDE_EFFECTS (value))\n    {\n      t = build_local_temp (TREE_TYPE (value));\n      add_stmt (build_assign (INIT_EXPR, t, value));\n      value = t;\n    }\n\n  /* Build loop to initialize { .length=length, .ptr=ptr } with value.  */\n  push_stmt_list ();\n\n  /* Exit logic for the loop.\n\tif (length == 0) break;  */\n  t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));\n  t = build1 (EXIT_EXPR, void_type_node, t);\n  add_stmt (t);\n\n  /* Assign value to the current pointer position.\n\t*ptr = value;  */\n  t = modify_expr (build_deref (ptr), value);\n  add_stmt (t);\n\n  /* Move pointer to next element position.\n\tptr++;  */\n  tree size = TYPE_SIZE_UNIT (TREE_TYPE (ptrtype));\n  t = build2 (POSTINCREMENT_EXPR, ptrtype, ptr, d_convert (ptrtype, size));\n  add_stmt (t);\n\n  /* Decrease loop counter.\n\tlength -= 1;  */\n  t = build2 (POSTDECREMENT_EXPR, lentype, length,\n\t      d_convert (lentype, integer_one_node));\n  add_stmt (t);\n\n  /* Pop statements and finish loop.  */\n  tree loop_body = pop_stmt_list ();\n  add_stmt (build1 (LOOP_EXPR, void_type_node, loop_body));\n\n  /* Wrap it up into a bind expression.  */\n  tree stmt_list = pop_stmt_list ();\n  tree block = pop_binding_level ();\n\n  return build3 (BIND_EXPR, void_type_node,\n\t\t BLOCK_VARS (block), stmt_list, block);\n}\n\n\n/* Build an array of type TYPE where all the elements are VAL.  */\n\ntree\nbuild_array_from_val (Type *type, tree val)\n{\n  gcc_assert (type->ty == Tsarray);\n\n  tree etype = build_ctype (type->nextOf ());\n\n  /* Initializing a multidimensional array.  */\n  if (TREE_CODE (etype) == ARRAY_TYPE && TREE_TYPE (val) != etype)\n    val = build_array_from_val (type->nextOf (), val);\n\n  size_t dims = ((TypeSArray *) type)->dim->toInteger ();\n  vec<constructor_elt, va_gc> *elms = NULL;\n  vec_safe_reserve (elms, dims);\n\n  val = d_convert (etype, val);\n\n  for (size_t i = 0; i < dims; i++)\n    CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val);\n\n  return build_constructor (build_ctype (type), elms);\n}\n\n/* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; }  */\n\ntree\nvoid_okay_p (tree t)\n{\n  tree type = TREE_TYPE (t);\n\n  if (VOID_TYPE_P (TREE_TYPE (type)))\n    {\n      tree totype = build_ctype (Type::tuns8->pointerTo ());\n      return fold_convert (totype, t);\n    }\n\n  return t;\n}\n\n/* Builds a bounds condition checking that INDEX is between 0 and LEN.\n   The condition returns the INDEX if true, or throws a RangeError.\n   If INCLUSIVE, we allow INDEX == LEN to return true also.  */\n\ntree\nbuild_bounds_condition (const Loc& loc, tree index, tree len, bool inclusive)\n{\n  if (!array_bounds_check ())\n    return index;\n\n  /* Prevent multiple evaluations of the index.  */\n  index = d_save_expr (index);\n\n  /* Generate INDEX >= LEN && throw RangeError.\n     No need to check whether INDEX >= 0 as the front-end should\n     have already taken care of implicit casts to unsigned.  */\n  tree condition = fold_build2 (inclusive ? GT_EXPR : GE_EXPR,\n\t\t\t\td_bool_type, index, len);\n  /* Terminate the program with a trap if no D runtime present.  */\n  tree boundserr = (global.params.checkAction == CHECKACTION_C)\n    ? build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0)\n    : d_assert_call (loc, LIBCALL_ARRAY_BOUNDS);\n\n  return build_condition (TREE_TYPE (index), condition, boundserr, index);\n}\n\n/* Returns TRUE if array bounds checking code generation is turned on.  */\n\nbool\narray_bounds_check (void)\n{\n  FuncDeclaration *fd;\n\n  switch (global.params.useArrayBounds)\n    {\n    case CHECKENABLEoff:\n      return false;\n\n    case CHECKENABLEon:\n      return true;\n\n    case CHECKENABLEsafeonly:\n      /* For D2 safe functions only.  */\n      fd = d_function_chain->function;\n      if (fd && fd->type->ty == Tfunction)\n\t{\n\t  TypeFunction *tf = (TypeFunction *) fd->type;\n\t  if (tf->trust == TRUSTsafe)\n\t    return true;\n\t}\n      return false;\n\n    default:\n      gcc_unreachable ();\n    }\n}\n\n/* Return an undeclared local temporary of type TYPE\n   for use with BIND_EXPR.  */\n\ntree\ncreate_temporary_var (tree type)\n{\n  tree decl = build_decl (input_location, VAR_DECL, NULL_TREE, type);\n\n  DECL_CONTEXT (decl) = current_function_decl;\n  DECL_ARTIFICIAL (decl) = 1;\n  DECL_IGNORED_P (decl) = 1;\n  layout_decl (decl, 0);\n\n  return decl;\n}\n\n/* Return an undeclared local temporary OUT_VAR initialized\n   with result of expression EXP.  */\n\ntree\nmaybe_temporary_var (tree exp, tree *out_var)\n{\n  tree t = exp;\n\n  /* Get the base component.  */\n  while (TREE_CODE (t) == COMPONENT_REF)\n    t = TREE_OPERAND (t, 0);\n\n  if (!DECL_P (t) && !REFERENCE_CLASS_P (t))\n    {\n      *out_var = create_temporary_var (TREE_TYPE (exp));\n      DECL_INITIAL (*out_var) = exp;\n      return *out_var;\n    }\n  else\n    {\n      *out_var = NULL_TREE;\n      return exp;\n    }\n}\n\n/* Builds a BIND_EXPR around BODY for the variables VAR_CHAIN.  */\n\ntree\nbind_expr (tree var_chain, tree body)\n{\n  /* Only handles one var.  */\n  gcc_assert (TREE_CHAIN (var_chain) == NULL_TREE);\n\n  if (DECL_INITIAL (var_chain))\n    {\n      tree ini = build_assign (INIT_EXPR, var_chain, DECL_INITIAL (var_chain));\n      DECL_INITIAL (var_chain) = NULL_TREE;\n      body = compound_expr (ini, body);\n    }\n\n  return d_save_expr (build3 (BIND_EXPR, TREE_TYPE (body),\n\t\t\t      var_chain, body, NULL_TREE));\n}\n\n/* Returns the TypeFunction class for Type T.\n   Assumes T is already ->toBasetype().  */\n\nTypeFunction *\nget_function_type (Type *t)\n{\n  TypeFunction *tf = NULL;\n  if (t->ty == Tpointer)\n    t = t->nextOf ()->toBasetype ();\n  if (t->ty == Tfunction)\n    tf = (TypeFunction *) t;\n  else if (t->ty == Tdelegate)\n    tf = (TypeFunction *) ((TypeDelegate *) t)->next;\n  return tf;\n}\n\n/* Returns TRUE if CALLEE is a plain nested function outside the scope of\n   CALLER.  In which case, CALLEE is being called through an alias that was\n   passed to CALLER.  */\n\nbool\ncall_by_alias_p (FuncDeclaration *caller, FuncDeclaration *callee)\n{\n  if (!callee->isNested ())\n    return false;\n\n  if (caller->toParent () == callee->toParent ())\n    return false;\n\n  Dsymbol *dsym = callee;\n\n  while (dsym)\n    {\n      if (dsym->isTemplateInstance ())\n\treturn false;\n      else if (dsym->isFuncDeclaration () == caller)\n\treturn false;\n      dsym = dsym->toParent ();\n    }\n\n  return true;\n}\n\n/* Entry point for call routines.  Builds a function call to FD.\n   OBJECT is the 'this' reference passed and ARGS are the arguments to FD.  */\n\ntree\nd_build_call_expr (FuncDeclaration *fd, tree object, Expressions *arguments)\n{\n  return d_build_call (get_function_type (fd->type),\n\t\t       build_address (get_symbol_decl (fd)), object, arguments);\n}\n\n/* Builds a CALL_EXPR of type TF to CALLABLE.  OBJECT holds the 'this' pointer,\n   ARGUMENTS are evaluated in left to right order, saved and promoted\n   before passing.  */\n\ntree\nd_build_call (TypeFunction *tf, tree callable, tree object,\n\t      Expressions *arguments)\n{\n  tree ctype = TREE_TYPE (callable);\n  tree callee = callable;\n\n  if (POINTER_TYPE_P (ctype))\n    ctype = TREE_TYPE (ctype);\n  else\n    callee = build_address (callable);\n\n  gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype));\n  gcc_assert (tf != NULL);\n  gcc_assert (tf->ty == Tfunction);\n\n  if (TREE_CODE (ctype) != FUNCTION_TYPE && object == NULL_TREE)\n    {\n      /* Front-end apparently doesn't check this.  */\n      if (TREE_CODE (callable) == FUNCTION_DECL)\n\t{\n\t  error (\"need %<this%> to access member %qE\", DECL_NAME (callable));\n\t  return error_mark_node;\n\t}\n\n      /* Probably an internal error.  */\n      gcc_unreachable ();\n    }\n\n  /* Build the argument list for the call.  */\n  vec<tree, va_gc> *args = NULL;\n  tree saved_args = NULL_TREE;\n\n  /* If this is a delegate call or a nested function being called as\n     a delegate, the object should not be NULL.  */\n  if (object != NULL_TREE)\n    vec_safe_push (args, object);\n\n  if (arguments)\n    {\n      /* First pass, evaluated expanded tuples in function arguments.  */\n      for (size_t i = 0; i < arguments->dim; ++i)\n\t{\n\tLagain:\n\t  Expression *arg = (*arguments)[i];\n\t  gcc_assert (arg->op != TOKtuple);\n\n\t  if (arg->op == TOKcomma)\n\t    {\n\t      CommaExp *ce = (CommaExp *) arg;\n\t      tree tce = build_expr (ce->e1);\n\t      saved_args = compound_expr (saved_args, tce);\n\t      (*arguments)[i] = ce->e2;\n\t      goto Lagain;\n\t    }\n\t}\n\n      size_t nparams = Parameter::dim (tf->parameters);\n      /* if _arguments[] is the first argument.  */\n      size_t varargs = (tf->linkage == LINKd && tf->varargs == 1);\n\n      /* Assumes arguments->dim <= formal_args->dim if (!tf->varargs).  */\n      for (size_t i = 0; i < arguments->dim; ++i)\n\t{\n\t  Expression *arg = (*arguments)[i];\n\t  tree targ = build_expr (arg);\n\n\t  if (i - varargs < nparams && i >= varargs)\n\t    {\n\t      /* Actual arguments for declared formal arguments.  */\n\t      Parameter *parg = Parameter::getNth (tf->parameters, i - varargs);\n\t      targ = convert_for_argument (targ, parg);\n\t    }\n\n\t  /* Don't pass empty aggregates by value.  */\n\t  if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ)\n\t      && TREE_CODE (targ) != CONSTRUCTOR)\n\t    {\n\t      tree t = build_constructor (TREE_TYPE (targ), NULL);\n\t      targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);\n\t    }\n\n\t  vec_safe_push (args, targ);\n\t}\n    }\n\n  /* Evaluate the callee before calling it.  */\n  if (TREE_SIDE_EFFECTS (callee))\n    {\n      callee = d_save_expr (callee);\n      saved_args = compound_expr (callee, saved_args);\n    }\n\n  tree result = build_call_vec (TREE_TYPE (ctype), callee, args);\n\n  /* Enforce left to right evaluation.  */\n  if (tf->linkage == LINKd)\n    CALL_EXPR_ARGS_ORDERED (result) = 1;\n\n  result = maybe_expand_intrinsic (result);\n\n  /* Return the value in a temporary slot so that it can be evaluated\n     multiple times by the caller.  */\n  if (TREE_CODE (result) == CALL_EXPR\n      && AGGREGATE_TYPE_P (TREE_TYPE (result))\n      && TREE_ADDRESSABLE (TREE_TYPE (result)))\n    {\n      CALL_EXPR_RETURN_SLOT_OPT (result) = true;\n      result = force_target_expr (result);\n    }\n\n  return compound_expr (saved_args, result);\n}\n\n/* Builds a call to AssertError or AssertErrorMsg.  */\n\ntree\nd_assert_call (const Loc& loc, libcall_fn libcall, tree msg)\n{\n  tree file;\n  tree line = size_int (loc.linnum);\n\n  /* File location is passed as a D string.  */\n  if (loc.filename)\n    {\n      unsigned len = strlen (loc.filename);\n      tree str = build_string (len, loc.filename);\n      TREE_TYPE (str) = make_array_type (Type::tchar, len);\n\n      file = d_array_value (build_ctype (Type::tchar->arrayOf ()),\n\t\t\t    size_int (len), build_address (str));\n    }\n  else\n    file = null_array_node;\n\n  if (msg != NULL)\n    return build_libcall (libcall, Type::tvoid, 3, msg, file, line);\n  else\n    return build_libcall (libcall, Type::tvoid, 2, file, line);\n}\n\n/* Build and return the correct call to fmod depending on TYPE.\n   ARG0 and ARG1 are the arguments pass to the function.  */\n\ntree\nbuild_float_modulus (tree type, tree arg0, tree arg1)\n{\n  tree fmodfn = NULL_TREE;\n  tree basetype = type;\n\n  if (COMPLEX_FLOAT_TYPE_P (basetype))\n    basetype = TREE_TYPE (basetype);\n\n  if (TYPE_MAIN_VARIANT (basetype) == double_type_node\n      || TYPE_MAIN_VARIANT (basetype) == idouble_type_node)\n    fmodfn = builtin_decl_explicit (BUILT_IN_FMOD);\n  else if (TYPE_MAIN_VARIANT (basetype) == float_type_node\n\t   || TYPE_MAIN_VARIANT (basetype) == ifloat_type_node)\n    fmodfn = builtin_decl_explicit (BUILT_IN_FMODF);\n  else if (TYPE_MAIN_VARIANT (basetype) == long_double_type_node\n\t   || TYPE_MAIN_VARIANT (basetype) == ireal_type_node)\n    fmodfn = builtin_decl_explicit (BUILT_IN_FMODL);\n\n  if (!fmodfn)\n    {\n      error (\"tried to perform floating-point modulo division on %qT\", type);\n      return error_mark_node;\n    }\n\n  if (COMPLEX_FLOAT_TYPE_P (type))\n    {\n      tree re = build_call_expr (fmodfn, 2, real_part (arg0), arg1);\n      tree im = build_call_expr (fmodfn, 2, imaginary_part (arg0), arg1);\n\n      return complex_expr (type, re, im);\n    }\n\n  if (SCALAR_FLOAT_TYPE_P (type))\n    return build_call_expr (fmodfn, 2, arg0, arg1);\n\n  /* Should have caught this above.  */\n  gcc_unreachable ();\n}\n\n/* Build a function type whose first argument is a pointer to BASETYPE,\n   which is to be used for the 'vthis' context parameter for TYPE.\n   The base type may be a record for member functions, or a void for\n   nested functions and delegates.  */\n\ntree\nbuild_vthis_function (tree basetype, tree type)\n{\n  gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);\n\n  tree argtypes = tree_cons (NULL_TREE, build_pointer_type (basetype),\n\t\t\t     TYPE_ARG_TYPES (type));\n  tree fntype = build_function_type (TREE_TYPE (type), argtypes);\n\n  if (RECORD_OR_UNION_TYPE_P (basetype))\n    TYPE_METHOD_BASETYPE (fntype) = TYPE_MAIN_VARIANT (basetype);\n  else\n    gcc_assert (VOID_TYPE_P (basetype));\n\n  return fntype;\n}\n\n/* If SYM is a nested function, return the static chain to be\n   used when calling that function from the current function.\n\n   If SYM is a nested class or struct, return the static chain\n   to be used when creating an instance of the class from CFUN.  */\n\ntree\nget_frame_for_symbol (Dsymbol *sym)\n{\n  FuncDeclaration *thisfd\n    = d_function_chain ? d_function_chain->function : NULL;\n  FuncDeclaration *fd = sym->isFuncDeclaration ();\n  FuncDeclaration *fdparent = NULL;\n  FuncDeclaration *fdoverride = NULL;\n\n  if (fd != NULL)\n    {\n      /* Check that the nested function is properly defined.  */\n      if (!fd->fbody)\n\t{\n\t  /* Should instead error on line that references 'fd'.  */\n\t  error_at (make_location_t (fd->loc), \"nested function missing body\");\n\t  return null_pointer_node;\n\t}\n\n      fdparent = fd->toParent2 ()->isFuncDeclaration ();\n\n      /* Special case for __ensure and __require.  */\n      if ((fd->ident == Identifier::idPool (\"__ensure\")\n\t   || fd->ident == Identifier::idPool (\"__require\"))\n\t  && fdparent != thisfd)\n\t{\n\t  fdoverride = fdparent;\n\t  fdparent = thisfd;\n\t}\n    }\n  else\n    {\n      /* It's a class (or struct).  NewExp codegen has already determined its\n\t outer scope is not another class, so it must be a function.  */\n      while (sym && !sym->isFuncDeclaration ())\n\tsym = sym->toParent2 ();\n\n      fdparent = (FuncDeclaration *) sym;\n    }\n\n  gcc_assert (fdparent != NULL);\n\n  if (thisfd != fdparent)\n    {\n      /* If no frame pointer for this function.  */\n      if (!thisfd->vthis)\n\t{\n\t  error_at (make_location_t (sym->loc),\n\t\t    \"is a nested function and cannot be accessed from %qs\",\n\t\t    thisfd->toChars ());\n\t  return null_pointer_node;\n\t}\n\n      /* Make sure we can get the frame pointer to the outer function.\n\t Go up each nesting level until we find the enclosing function.  */\n      Dsymbol *dsym = thisfd;\n\n      while (fd != dsym)\n\t{\n\t  /* Check if enclosing function is a function.  */\n\t  FuncDeclaration *fd = dsym->isFuncDeclaration ();\n\n\t  if (fd != NULL)\n\t    {\n\t      if (fdparent == fd->toParent2 ())\n\t\tbreak;\n\n\t      gcc_assert (fd->isNested () || fd->vthis);\n\t      dsym = dsym->toParent2 ();\n\t      continue;\n\t    }\n\n\t  /* Check if enclosed by an aggregate.  That means the current\n\t     function must be a member function of that aggregate.  */\n\t  AggregateDeclaration *ad = dsym->isAggregateDeclaration ();\n\n\t  if (ad == NULL)\n\t    goto Lnoframe;\n\t  if (ad->isClassDeclaration () && fdparent == ad->toParent2 ())\n\t    break;\n\t  if (ad->isStructDeclaration () && fdparent == ad->toParent2 ())\n\t    break;\n\n\t  if (!ad->isNested () || !ad->vthis)\n\t    {\n\t    Lnoframe:\n\t      error_at (make_location_t (thisfd->loc),\n\t\t\t\"cannot get frame pointer to %qs\",\n\t\t\tsym->toPrettyChars ());\n\t      return null_pointer_node;\n\t    }\n\n\t  dsym = dsym->toParent2 ();\n\t}\n    }\n\n  tree ffo = get_frameinfo (fdparent);\n  if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo))\n    {\n      tree frame_ref = get_framedecl (thisfd, fdparent);\n\n      /* If 'thisfd' is a derived member function, then 'fdparent' is the\n\t overridden member function in the base class.  Even if there's a\n\t closure environment, we should give the original stack data as the\n\t nested function frame.  */\n      if (fdoverride)\n\t{\n\t  ClassDeclaration *cdo = fdoverride->isThis ()->isClassDeclaration ();\n\t  ClassDeclaration *cd = thisfd->isThis ()->isClassDeclaration ();\n\t  gcc_assert (cdo && cd);\n\n\t  int offset;\n\t  if (cdo->isBaseOf (cd, &offset) && offset != 0)\n\t    {\n\t      /* Generate a new frame to pass to the overriden function that\n\t\t has the 'this' pointer adjusted.  */\n\t      gcc_assert (offset != OFFSET_RUNTIME);\n\n\t      tree type = FRAMEINFO_TYPE (get_frameinfo (fdoverride));\n\t      tree fields = TYPE_FIELDS (type);\n\t      /* The 'this' field comes immediately after the '__chain'.  */\n\t      tree thisfield = chain_index (1, fields);\n\t      vec<constructor_elt, va_gc> *ve = NULL;\n\n\t      tree framefields = TYPE_FIELDS (FRAMEINFO_TYPE (ffo));\n\t      frame_ref = build_deref (frame_ref);\n\n\t      for (tree field = fields; field; field = DECL_CHAIN (field))\n\t\t{\n\t\t  tree value = component_ref (frame_ref, framefields);\n\t\t  if (field == thisfield)\n\t\t    value = build_offset (value, size_int (offset));\n\n\t\t  CONSTRUCTOR_APPEND_ELT (ve, field, value);\n\t\t  framefields = DECL_CHAIN (framefields);\n\t\t}\n\n\t      frame_ref = build_address (build_constructor (type, ve));\n\t    }\n\t}\n\n      return frame_ref;\n    }\n\n  return null_pointer_node;\n}\n\n/* Return the parent function of a nested class CD.  */\n\nstatic FuncDeclaration *\nd_nested_class (ClassDeclaration *cd)\n{\n  FuncDeclaration *fd = NULL;\n  while (cd && cd->isNested ())\n    {\n      Dsymbol *dsym = cd->toParent2 ();\n      if ((fd = dsym->isFuncDeclaration ()))\n\treturn fd;\n      else\n\tcd = dsym->isClassDeclaration ();\n    }\n  return NULL;\n}\n\n/* Return the parent function of a nested struct SD.  */\n\nstatic FuncDeclaration *\nd_nested_struct (StructDeclaration *sd)\n{\n  FuncDeclaration *fd = NULL;\n  while (sd && sd->isNested ())\n    {\n      Dsymbol *dsym = sd->toParent2 ();\n      if ((fd = dsym->isFuncDeclaration ()))\n\treturn fd;\n      else\n\tsd = dsym->isStructDeclaration ();\n    }\n  return NULL;\n}\n\n\n/* Starting from the current function FD, try to find a suitable value of\n   'this' in nested function instances.  A suitable 'this' value is an\n   instance of OCD or a class that has OCD as a base.  */\n\nstatic tree\nfind_this_tree (ClassDeclaration *ocd)\n{\n  FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;\n\n  while (fd)\n    {\n      AggregateDeclaration *ad = fd->isThis ();\n      ClassDeclaration *cd = ad ? ad->isClassDeclaration () : NULL;\n\n      if (cd != NULL)\n\t{\n\t  if (ocd == cd)\n\t    return get_decl_tree (fd->vthis);\n\t  else if (ocd->isBaseOf (cd, NULL))\n\t    return convert_expr (get_decl_tree (fd->vthis),\n\t\t\t\t cd->type, ocd->type);\n\n\t  fd = d_nested_class (cd);\n\t}\n      else\n\t{\n\t  if (fd->isNested ())\n\t    {\n\t      fd = fd->toParent2 ()->isFuncDeclaration ();\n\t      continue;\n\t    }\n\n\t  fd = NULL;\n\t}\n    }\n\n  return NULL_TREE;\n}\n\n/* Retrieve the outer class/struct 'this' value of DECL from\n   the current function.  */\n\ntree\nbuild_vthis (AggregateDeclaration *decl)\n{\n  ClassDeclaration *cd = decl->isClassDeclaration ();\n  StructDeclaration *sd = decl->isStructDeclaration ();\n\n  /* If an aggregate nested in a function has no methods and there are no\n     other nested functions, any static chain created here will never be\n     translated.  Use a null pointer for the link in this case.  */\n  tree vthis_value = null_pointer_node;\n\n  if (cd != NULL || sd != NULL)\n    {\n      Dsymbol *outer = decl->toParent2 ();\n\n      /* If the parent is a templated struct, the outer context is instead\n\t the enclosing symbol of where the instantiation happened.  */\n      if (outer->isStructDeclaration ())\n\t{\n\t  gcc_assert (outer->parent && outer->parent->isTemplateInstance ());\n\t  outer = ((TemplateInstance *) outer->parent)->enclosing;\n\t}\n\n      /* For outer classes, get a suitable 'this' value.\n\t For outer functions, get a suitable frame/closure pointer.  */\n      ClassDeclaration *cdo = outer->isClassDeclaration ();\n      FuncDeclaration *fdo = outer->isFuncDeclaration ();\n\n      if (cdo)\n\t{\n\t  vthis_value = find_this_tree (cdo);\n\t  gcc_assert (vthis_value != NULL_TREE);\n\t}\n      else if (fdo)\n\t{\n\t  tree ffo = get_frameinfo (fdo);\n\t  if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo)\n\t      || fdo->hasNestedFrameRefs ())\n\t    vthis_value = get_frame_for_symbol (decl);\n\t  else if (cd != NULL)\n\t    {\n\t      /* Classes nested in methods are allowed to access any outer\n\t\t class fields, use the function chain in this case.  */\n\t      if (fdo->vthis && fdo->vthis->type != Type::tvoidptr)\n\t\tvthis_value = get_decl_tree (fdo->vthis);\n\t    }\n\t}\n      else\n\tgcc_unreachable ();\n    }\n\n  return vthis_value;\n}\n\n/* Build the RECORD_TYPE that describes the function frame or closure type for\n   the function FD.  FFI is the tree holding all frame information.  */\n\nstatic tree\nbuild_frame_type (tree ffi, FuncDeclaration *fd)\n{\n  if (FRAMEINFO_TYPE (ffi))\n    return FRAMEINFO_TYPE (ffi);\n\n  tree frame_rec_type = make_node (RECORD_TYPE);\n  char *name = concat (FRAMEINFO_IS_CLOSURE (ffi) ? \"CLOSURE.\" : \"FRAME.\",\n\t\t       fd->toPrettyChars (), NULL);\n  TYPE_NAME (frame_rec_type) = get_identifier (name);\n  free (name);\n\n  tree fields = NULL_TREE;\n\n  /* Function is a member or nested, so must have field for outer context.  */\n  if (fd->vthis)\n    {\n      tree ptr_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,\n\t\t\t\t   get_identifier (\"__chain\"), ptr_type_node);\n      DECL_FIELD_CONTEXT (ptr_field) = frame_rec_type;\n      fields = chainon (NULL_TREE, ptr_field);\n      DECL_NONADDRESSABLE_P (ptr_field) = 1;\n    }\n\n  /* The __ensure and __require are called directly, so never make the outer\n     functions closure, but nevertheless could still be referencing parameters\n     of the calling function non-locally.  So we add all parameters with nested\n     refs to the function frame, this should also mean overriding methods will\n     have the same frame layout when inheriting a contract.  */\n  if ((global.params.useIn && fd->frequire)\n      || (global.params.useOut && fd->fensure))\n    {\n      if (fd->parameters)\n\t{\n\t  for (size_t i = 0; fd->parameters && i < fd->parameters->dim; i++)\n\t    {\n\t      VarDeclaration *v = (*fd->parameters)[i];\n\t      /* Remove if already in closureVars so can push to front.  */\n\t      for (size_t j = i; j < fd->closureVars.dim; j++)\n\t\t{\n\t\t  Dsymbol *s = fd->closureVars[j];\n\t\t  if (s == v)\n\t\t    {\n\t\t      fd->closureVars.remove (j);\n\t\t      break;\n\t\t    }\n\t\t}\n\t      fd->closureVars.insert (i, v);\n\t    }\n\t}\n\n      /* Also add hidden 'this' to outer context.  */\n      if (fd->vthis)\n\t{\n\t  for (size_t i = 0; i < fd->closureVars.dim; i++)\n\t    {\n\t      Dsymbol *s = fd->closureVars[i];\n\t      if (s == fd->vthis)\n\t\t{\n\t\t  fd->closureVars.remove (i);\n\t\t  break;\n\t\t}\n\t    }\n\t  fd->closureVars.insert (0, fd->vthis);\n\t}\n    }\n\n  for (size_t i = 0; i < fd->closureVars.dim; i++)\n    {\n      VarDeclaration *v = fd->closureVars[i];\n      tree vsym = get_symbol_decl (v);\n      tree ident = v->ident\n\t? get_identifier (v->ident->toChars ()) : NULL_TREE;\n\n      tree field = build_decl (make_location_t (v->loc), FIELD_DECL, ident,\n\t\t\t       TREE_TYPE (vsym));\n      SET_DECL_LANG_FRAME_FIELD (vsym, field);\n      DECL_FIELD_CONTEXT (field) = frame_rec_type;\n      fields = chainon (fields, field);\n      TREE_USED (vsym) = 1;\n\n      TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (vsym);\n      DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (vsym);\n      TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (vsym);\n\n      /* Can't do nrvo if the variable is put in a frame.  */\n      if (fd->nrvo_can && fd->nrvo_var == v)\n\tfd->nrvo_can = 0;\n\n      if (FRAMEINFO_IS_CLOSURE (ffi))\n\t{\n\t  /* Because the value needs to survive the end of the scope.  */\n\t  if ((v->edtor && (v->storage_class & STCparameter))\n\t      || v->needsScopeDtor ())\n\t    error_at (make_location_t (v->loc),\n\t\t      \"has scoped destruction, cannot build closure\");\n\t}\n    }\n\n  TYPE_FIELDS (frame_rec_type) = fields;\n  TYPE_READONLY (frame_rec_type) = 1;\n  layout_type (frame_rec_type);\n  d_keep (frame_rec_type);\n\n  return frame_rec_type;\n}\n\n/* Closures are implemented by taking the local variables that\n   need to survive the scope of the function, and copying them\n   into a GC allocated chuck of memory.  That chunk, called the\n   closure here, is inserted into the linked list of stack\n   frames instead of the usual stack frame.\n\n   If a closure is not required, but FD still needs a frame to lower\n   nested refs, then instead build custom static chain decl on stack.  */\n\nvoid\nbuild_closure (FuncDeclaration *fd)\n{\n  tree ffi = get_frameinfo (fd);\n\n  if (!FRAMEINFO_CREATES_FRAME (ffi))\n    return;\n\n  tree type = FRAMEINFO_TYPE (ffi);\n  gcc_assert (COMPLETE_TYPE_P (type));\n\n  tree decl, decl_ref;\n\n  if (FRAMEINFO_IS_CLOSURE (ffi))\n    {\n      decl = build_local_temp (build_pointer_type (type));\n      DECL_NAME (decl) = get_identifier (\"__closptr\");\n      decl_ref = build_deref (decl);\n\n      /* Allocate memory for closure.  */\n      tree arg = convert (build_ctype (Type::tsize_t), TYPE_SIZE_UNIT (type));\n      tree init = build_libcall (LIBCALL_ALLOCMEMORY, Type::tvoidptr, 1, arg);\n\n      tree init_exp = build_assign (INIT_EXPR, decl,\n\t\t\t\t    build_nop (TREE_TYPE (decl), init));\n      add_stmt (init_exp);\n    }\n  else\n    {\n      decl = build_local_temp (type);\n      DECL_NAME (decl) = get_identifier (\"__frame\");\n      decl_ref = decl;\n    }\n\n  /* Set the first entry to the parent closure/frame, if any.  */\n  if (fd->vthis)\n    {\n      tree chain_field = component_ref (decl_ref, TYPE_FIELDS (type));\n      tree chain_expr = modify_expr (chain_field,\n\t\t\t\t     d_function_chain->static_chain);\n      add_stmt (chain_expr);\n    }\n\n  /* Copy parameters that are referenced nonlocally.  */\n  for (size_t i = 0; i < fd->closureVars.dim; i++)\n    {\n      VarDeclaration *v = fd->closureVars[i];\n\n      if (!v->isParameter ())\n\tcontinue;\n\n      tree vsym = get_symbol_decl (v);\n\n      tree field = component_ref (decl_ref, DECL_LANG_FRAME_FIELD (vsym));\n      tree expr = modify_expr (field, vsym);\n      add_stmt (expr);\n    }\n\n  if (!FRAMEINFO_IS_CLOSURE (ffi))\n    decl = build_address (decl);\n\n  d_function_chain->static_chain = decl;\n}\n\n/* Return the frame of FD.  This could be a static chain or a closure\n   passed via the hidden 'this' pointer.  */\n\ntree\nget_frameinfo (FuncDeclaration *fd)\n{\n  tree fds = get_symbol_decl (fd);\n  if (DECL_LANG_FRAMEINFO (fds))\n    return DECL_LANG_FRAMEINFO (fds);\n\n  tree ffi = make_node (FUNCFRAME_INFO);\n\n  DECL_LANG_FRAMEINFO (fds) = ffi;\n\n  if (fd->needsClosure ())\n    {\n      /* Set-up a closure frame, this will be allocated on the heap.  */\n      FRAMEINFO_CREATES_FRAME (ffi) = 1;\n      FRAMEINFO_IS_CLOSURE (ffi) = 1;\n    }\n  else if (fd->hasNestedFrameRefs ())\n    {\n      /* Functions with nested refs must create a static frame for local\n\t variables to be referenced from.  */\n      FRAMEINFO_CREATES_FRAME (ffi) = 1;\n    }\n  else\n    {\n      /* For nested functions, default to creating a frame.  Even if there are\n\t no fields to populate the frame, create it anyway, as this will be\n\t used as the record type instead of `void*` for the this parameter.  */\n      if (fd->vthis && fd->vthis->type == Type::tvoidptr)\n\tFRAMEINFO_CREATES_FRAME (ffi) = 1;\n\n      /* In checkNestedReference, references from contracts are not added to the\n\t closureVars array, so assume all parameters referenced.  */\n      if ((global.params.useIn && fd->frequire)\n\t  || (global.params.useOut && fd->fensure))\n\tFRAMEINFO_CREATES_FRAME (ffi) = 1;\n\n      /* If however `fd` is nested (deeply) in a function that creates a\n\t closure, then `fd` instead inherits that closure via hidden vthis\n\t pointer, and doesn't create a stack frame at all.  */\n      FuncDeclaration *ff = fd;\n\n      while (ff)\n\t{\n\t  tree ffo = get_frameinfo (ff);\n\n\t  if (ff != fd && FRAMEINFO_CREATES_FRAME (ffo))\n\t    {\n\t      gcc_assert (FRAMEINFO_TYPE (ffo));\n\t      FRAMEINFO_CREATES_FRAME (ffi) = 0;\n\t      FRAMEINFO_STATIC_CHAIN (ffi) = 1;\n\t      FRAMEINFO_IS_CLOSURE (ffi) = FRAMEINFO_IS_CLOSURE (ffo);\n\t      gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo)));\n\t      FRAMEINFO_TYPE (ffi) = FRAMEINFO_TYPE (ffo);\n\t      break;\n\t    }\n\n\t  /* Stop looking if no frame pointer for this function.  */\n\t  if (ff->vthis == NULL)\n\t    break;\n\n\t  AggregateDeclaration *ad = ff->isThis ();\n\t  if (ad && ad->isNested ())\n\t    {\n\t      while (ad->isNested ())\n\t\t{\n\t\t  Dsymbol *d = ad->toParent2 ();\n\t\t  ad = d->isAggregateDeclaration ();\n\t\t  ff = d->isFuncDeclaration ();\n\n\t\t  if (ad == NULL)\n\t\t    break;\n\t\t}\n\t    }\n\t  else\n\t    ff = ff->toParent2 ()->isFuncDeclaration ();\n\t}\n    }\n\n  /* Build type now as may be referenced from another module.  */\n  if (FRAMEINFO_CREATES_FRAME (ffi))\n    FRAMEINFO_TYPE (ffi) = build_frame_type (ffi, fd);\n\n  return ffi;\n}\n\n/* Return a pointer to the frame/closure block of OUTER\n   so can be accessed from the function INNER.  */\n\ntree\nget_framedecl (FuncDeclaration *inner, FuncDeclaration *outer)\n{\n  tree result = d_function_chain->static_chain;\n  FuncDeclaration *fd = inner;\n\n  while (fd && fd != outer)\n    {\n      AggregateDeclaration *ad;\n      ClassDeclaration *cd;\n      StructDeclaration *sd;\n\n      /* Parent frame link is the first field.  */\n      if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd)))\n\tresult = indirect_ref (ptr_type_node, result);\n\n      if (fd->isNested ())\n\tfd = fd->toParent2 ()->isFuncDeclaration ();\n      /* The frame/closure record always points to the outer function's\n\t frame, even if there are intervening nested classes or structs.\n\t So, we can just skip over these.  */\n      else if ((ad = fd->isThis ()) && (cd = ad->isClassDeclaration ()))\n\tfd = d_nested_class (cd);\n      else if ((ad = fd->isThis ()) && (sd = ad->isStructDeclaration ()))\n\tfd = d_nested_struct (sd);\n      else\n\tbreak;\n    }\n\n  /* Go get our frame record.  */\n  gcc_assert (fd == outer);\n  tree frame_type = FRAMEINFO_TYPE (get_frameinfo (outer));\n\n  if (frame_type != NULL_TREE)\n    {\n      result = build_nop (build_pointer_type (frame_type), result);\n      return result;\n    }\n  else\n    {\n      error_at (make_location_t (inner->loc),\n\t\t\"forward reference to frame of %qs\", outer->toChars ());\n      return null_pointer_node;\n    }\n}\n"
  },
  {
    "path": "gcc/d/d-convert.cc",
    "content": "/* d-convert.cc -- Data type conversion routines.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/aggregate.h\"\n#include \"dmd/declaration.h\"\n#include \"dmd/expression.h\"\n#include \"dmd/mtype.h\"\n\n#include \"tree.h\"\n#include \"fold-const.h\"\n#include \"diagnostic.h\"\n#include \"langhooks.h\"\n#include \"target.h\"\n#include \"convert.h\"\n#include \"stor-layout.h\"\n\n#include \"d-tree.h\"\n\n\n/* Build CODE expression with operands OP0 and OP1.\n   Helper function for d_truthvalue_conversion, so assumes bool result.  */\n\nstatic tree\nd_build_truthvalue_op (tree_code code, tree op0, tree op1)\n{\n  tree type0, type1;\n\n  tree result_type = NULL_TREE;\n\n  type0 = TREE_TYPE (op0);\n  type1 = TREE_TYPE (op1);\n\n  /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */\n  STRIP_TYPE_NOPS (op0);\n  STRIP_TYPE_NOPS (op1);\n\n  /* Also need to convert pointer/int comparison.  */\n  if (POINTER_TYPE_P (type0) && TREE_CODE (op1) == INTEGER_CST\n      && integer_zerop (op1))\n    {\n      result_type = type0;\n    }\n  else if (POINTER_TYPE_P (type1) && TREE_CODE (op0) == INTEGER_CST\n\t   && integer_zerop (op0))\n    {\n      result_type = type1;\n    }\n  /* If integral, need to convert unsigned/signed comparison.\n     Will also need to convert if type precisions differ.  */\n  else if (INTEGRAL_TYPE_P (type0) && INTEGRAL_TYPE_P (type1))\n    {\n      if (TYPE_PRECISION (type0) > TYPE_PRECISION (type1))\n\tresult_type = type0;\n      else if (TYPE_PRECISION (type0) < TYPE_PRECISION (type1))\n\tresult_type = type1;\n      else if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))\n\tresult_type = TYPE_UNSIGNED (type0) ? type0 : type1;\n    }\n\n  if (result_type)\n    {\n      if (TREE_TYPE (op0) != result_type)\n\top0 = convert (result_type, op0);\n      if (TREE_TYPE (op1) != result_type)\n\top1 = convert (result_type, op1);\n    }\n\n  return fold_build2 (code, d_bool_type, op0, op1);\n}\n\n/* Return whether EXPR is a declaration whose address can never be NULL.  */\n\nbool\ndecl_with_nonnull_addr_p (const_tree expr)\n{\n  return (DECL_P (expr)\n\t  && (TREE_CODE (expr) == PARM_DECL\n\t      || TREE_CODE (expr) == LABEL_DECL\n\t      || !DECL_WEAK (expr)));\n}\n\n/* Convert EXPR to be a truth-value, validating its type for this purpose.  */\n\ntree\nd_truthvalue_conversion (tree expr)\n{\n  switch (TREE_CODE (expr))\n    {\n    case EQ_EXPR:   case NE_EXPR:   case LE_EXPR:\n    case GE_EXPR:   case LT_EXPR:   case GT_EXPR:\n      if (TREE_TYPE (expr) == d_bool_type)\n\treturn expr;\n      return build2 (TREE_CODE (expr), d_bool_type,\n\t\t     TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));\n\n    case TRUTH_ANDIF_EXPR:\n    case TRUTH_ORIF_EXPR:\n    case TRUTH_AND_EXPR:\n    case TRUTH_OR_EXPR:\n    case TRUTH_XOR_EXPR:\n      if (TREE_TYPE (expr) == d_bool_type)\n\treturn expr;\n      return build2 (TREE_CODE (expr), d_bool_type,\n\t\t     d_truthvalue_conversion (TREE_OPERAND (expr, 0)),\n\t\t     d_truthvalue_conversion (TREE_OPERAND (expr, 1)));\n\n    case TRUTH_NOT_EXPR:\n      if (TREE_TYPE (expr) == d_bool_type)\n\treturn expr;\n      return build1 (TREE_CODE (expr), d_bool_type,\n\t\t     d_truthvalue_conversion (TREE_OPERAND (expr, 0)));\n\n    case ERROR_MARK:\n      return expr;\n\n    case INTEGER_CST:\n      return integer_zerop (expr) ? boolean_false_node\n\t\t\t\t  : boolean_true_node;\n\n    case REAL_CST:\n      return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst0)\n\t     ? boolean_true_node\n\t     : boolean_false_node;\n\n    case ADDR_EXPR:\n      /* If we are taking the address of a decl that can never be null,\n\t then the return result is always true.  */\n      if (decl_with_nonnull_addr_p (TREE_OPERAND (expr, 0)))\n\t{\n\t  warning (OPT_Waddress,\n\t\t   \"the address of %qD will always evaluate as %<true%>\",\n\t\t   TREE_OPERAND (expr, 0));\n\t  return boolean_true_node;\n\t}\n      break;\n\n    case COMPLEX_EXPR:\n      return d_build_truthvalue_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))\n\t\t\t\t     ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),\n\t\t\td_truthvalue_conversion (TREE_OPERAND (expr, 0)),\n\t\t\td_truthvalue_conversion (TREE_OPERAND (expr, 1)));\n\n    case NEGATE_EXPR:\n    case ABS_EXPR:\n    case FLOAT_EXPR:\n      /* These don't change whether an object is nonzero or zero.  */\n      return d_truthvalue_conversion (TREE_OPERAND (expr, 0));\n\n    case LROTATE_EXPR:\n    case RROTATE_EXPR:\n      /* These don't change whether an object is zero or nonzero, but\n\t we can't ignore them if their second arg has side-effects.  */\n      if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))\n\t{\n\t  return build2 (COMPOUND_EXPR, d_bool_type, TREE_OPERAND (expr, 1),\n\t\t\t d_truthvalue_conversion (TREE_OPERAND (expr, 0)));\n\t}\n      else\n\treturn d_truthvalue_conversion (TREE_OPERAND (expr, 0));\n\n    case COND_EXPR:\n      /* Distribute the conversion into the arms of a COND_EXPR.  */\n      return fold_build3 (COND_EXPR, d_bool_type, TREE_OPERAND (expr, 0),\n\t\t\t  d_truthvalue_conversion (TREE_OPERAND (expr, 1)),\n\t\t\t  d_truthvalue_conversion (TREE_OPERAND (expr, 2)));\n\n    case CONVERT_EXPR:\n      /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,\n\t since that affects how `default_conversion' will behave.  */\n      if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE\n\t  || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)\n\tbreak;\n      /* Fall through.  */\n\n    case NOP_EXPR:\n      /* If this isn't narrowing the argument, we can ignore it.  */\n      if (TYPE_PRECISION (TREE_TYPE (expr))\n\t  >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))\n\treturn d_truthvalue_conversion (TREE_OPERAND (expr, 0));\n      break;\n\n    default:\n      break;\n    }\n\n  if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)\n    {\n      tree t = save_expr (expr);\n      return d_build_truthvalue_op ((TREE_SIDE_EFFECTS (expr)\n\t\t\t\t     ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),\n\t\t\td_truthvalue_conversion (real_part (t)),\n\t\t\td_truthvalue_conversion (imaginary_part (t)));\n    }\n  else\n    return d_build_truthvalue_op (NE_EXPR, expr,\n\t\t\t\t  build_zero_cst (TREE_TYPE (expr)));\n}\n\n\n/* Creates an expression whose value is that of EXPR, converted to type TYPE.\n   This function implements all reasonable scalar conversions.  */\n\ntree\nconvert (tree type, tree expr)\n{\n  tree e = expr;\n  tree_code code = TREE_CODE (type);\n\n  if (type == error_mark_node\n      || expr == error_mark_node\n      || TREE_TYPE (expr) == error_mark_node)\n    return error_mark_node;\n\n  const char *invalid_conv_diag\n    = targetm.invalid_conversion (TREE_TYPE (expr), type);\n\n  if (invalid_conv_diag)\n    {\n      error (\"%s\", invalid_conv_diag);\n      return error_mark_node;\n    }\n\n  if (type == TREE_TYPE (expr))\n    return expr;\n\n  if (TREE_CODE (type) == ARRAY_TYPE\n      && TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE\n      && TYPE_DOMAIN (type) == TYPE_DOMAIN (TREE_TYPE (expr)))\n    return expr;\n\n  tree ret = targetm.convert_to_type (type, expr);\n  if (ret)\n    return ret;\n\n  STRIP_TYPE_NOPS (e);\n  tree etype = TREE_TYPE (e);\n\n  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))\n    return fold_convert (type, expr);\n  if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)\n    return error_mark_node;\n  if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)\n    {\n      error (\"void value not ignored as it ought to be\");\n      return error_mark_node;\n    }\n\n  switch (code)\n    {\n    case VOID_TYPE:\n      return fold_convert (type, e);\n\n    case INTEGER_TYPE:\n    case ENUMERAL_TYPE:\n      if (TREE_CODE (etype) == POINTER_TYPE\n\t  || TREE_CODE (etype) == REFERENCE_TYPE)\n\t{\n\t  if (integer_zerop (e))\n\t    return build_int_cst (type, 0);\n\n\t  /* Convert to an unsigned integer of the correct width first, and\n\t     from there widen/truncate to the required type.  */\n\t  tree utype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),\n\t\t\t\t\t\t       1);\n\t  ret = fold_build1 (CONVERT_EXPR, utype, e);\n\t  return fold_convert (type, ret);\n\t}\n\n      return fold (convert_to_integer (type, e));\n\n    case BOOLEAN_TYPE:\n      return fold_convert (type, d_truthvalue_conversion (expr));\n\n    case POINTER_TYPE:\n    case REFERENCE_TYPE:\n      return fold (convert_to_pointer (type, e));\n\n    case REAL_TYPE:\n      if (TREE_CODE (etype) == COMPLEX_TYPE && TYPE_IMAGINARY_FLOAT (type))\n\te = build1 (IMAGPART_EXPR, TREE_TYPE (etype), e);\n\n      return fold (convert_to_real (type, e));\n\n    case COMPLEX_TYPE:\n      if (TREE_CODE (etype) == REAL_TYPE && TYPE_IMAGINARY_FLOAT (etype))\n\treturn fold_build2 (COMPLEX_EXPR, type,\n\t\t\t    build_zero_cst (TREE_TYPE (type)),\n\t\t\t    convert (TREE_TYPE (type), expr));\n\n      return fold (convert_to_complex (type, e));\n\n    case VECTOR_TYPE:\n      return fold (convert_to_vector (type, e));\n\n    case RECORD_TYPE:\n    case UNION_TYPE:\n      if (lang_hooks.types_compatible_p (type, TREE_TYPE (expr)))\n\treturn fold_build1 (VIEW_CONVERT_EXPR, type, expr);\n      break;\n\n    default:\n      break;\n    }\n\n  error (\"conversion to non-scalar type requested\");\n  return error_mark_node;\n}\n\n/* Return expression EXP, whose type has been converted to TYPE.  */\n\ntree\nd_convert (tree type, tree exp)\n{\n  /* Check this first before retrieving frontend type.  */\n  if (error_operand_p (type) || error_operand_p (exp))\n    return error_mark_node;\n\n  Type *totype = TYPE_LANG_FRONTEND (type);\n  Type *etype = TYPE_LANG_FRONTEND (TREE_TYPE (exp));\n\n  if (totype && etype)\n    return convert_expr (exp, etype, totype);\n\n  return convert (type, exp);\n}\n\n/* Return expression EXP, whose type has been convert from ETYPE to TOTYPE.  */\n\ntree\nconvert_expr (tree exp, Type *etype, Type *totype)\n{\n  tree result = NULL_TREE;\n\n  gcc_assert (etype && totype);\n  Type *ebtype = etype->toBasetype ();\n  Type *tbtype = totype->toBasetype ();\n\n  if (same_type_p (etype, totype))\n    return exp;\n\n  if (error_operand_p (exp))\n    return exp;\n\n  switch (ebtype->ty)\n    {\n    case Tdelegate:\n      if (tbtype->ty == Tdelegate)\n\t{\n\t  exp = d_save_expr (exp);\n\t  return build_delegate_cst (delegate_method (exp),\n\t\t\t\t     delegate_object (exp), totype);\n\t}\n      else if (tbtype->ty == Tpointer)\n\t{\n\t  /* The front-end converts <delegate>.ptr to cast (void *)<delegate>.\n\t     Maybe should only allow void* ?  */\n\t  exp = delegate_object (exp);\n\t}\n      else\n\t{\n\t  error (\"can't convert a delegate expression to %qs\",\n\t\t totype->toChars ());\n\t  return error_mark_node;\n\t}\n      break;\n\n    case Tstruct:\n      if (tbtype->ty == Tstruct)\n\t{\n\t  if (totype->size () == etype->size ())\n\t    {\n\t      /* Allowed to cast to structs with same type size.  */\n\t      result = build_vconvert (build_ctype (totype), exp);\n\t    }\n\t  else\n\t    {\n\t      error (\"can't convert struct %qs to %qs\",\n\t\t     etype->toChars (), totype->toChars ());\n\t      return error_mark_node;\n\t    }\n\t}\n      /* else, default conversion, which should produce an error.  */\n      break;\n\n    case Tclass:\n      if (tbtype->ty == Tclass)\n\t{\n\t  ClassDeclaration *cdfrom = ebtype->isClassHandle ();\n\t  ClassDeclaration *cdto = tbtype->isClassHandle ();\n\t  int offset;\n\n\t  if (cdto->isBaseOf (cdfrom, &offset) && offset != OFFSET_RUNTIME)\n\t    {\n\t      /* Casting up the inheritance tree: Don't do anything special.\n\t\t Cast to an implemented interface: Handle at compile-time.  */\n\t      if (offset)\n\t\t{\n\t\t  /* Forward references should not leak from the frontend.  */\n\t\t  gcc_assert (offset != OFFSET_FWDREF);\n\n\t\t  tree type = build_ctype (totype);\n\t\t  exp = d_save_expr (exp);\n\n\t\t  tree cond = build_boolop (NE_EXPR, exp, null_pointer_node);\n\t\t  tree object = build_offset (exp, size_int (offset));\n\n\t\t  return build_condition (build_ctype (totype), cond,\n\t\t\t\t\t  build_nop (type, object),\n\t\t\t\t\t  build_nop (type, null_pointer_node));\n\t\t}\n\n\t      /* d_convert will make a no-op cast.  */\n\t      break;\n\t    }\n\t  else if (cdfrom->isCPPclass ())\n\t    {\n\t      /* Downcasting in C++ is a no-op.  */\n\t      if (cdto->isCPPclass ())\n\t\tbreak;\n\n\t      /* Casting from a C++ interface to a class/non-C++ interface\n\t\t always results in null as there is no run-time information,\n\t\t and no way one can derive from the other.  */\n\t      warning (OPT_Wcast_result, \"cast to %qs will produce null result\",\n\t\t       totype->toChars ());\n\t      result = d_convert (build_ctype (totype), null_pointer_node);\n\n\t      /* Make sure the expression is still evaluated if necessary.  */\n\t      if (TREE_SIDE_EFFECTS (exp))\n\t\tresult = compound_expr (exp, result);\n\n\t      break;\n\t    }\n\n\t  /* The offset can only be determined at run-time, do dynamic cast.  */\n\t  libcall_fn libcall = cdfrom->isInterfaceDeclaration ()\n\t    ? LIBCALL_INTERFACE_CAST : LIBCALL_DYNAMIC_CAST;\n\n\t  return build_libcall (libcall, totype, 2, exp,\n\t\t\t\tbuild_address (get_classinfo_decl (cdto)));\n\t}\n      /* else default conversion.  */\n      break;\n\n    case Tsarray:\n      if (tbtype->ty == Tpointer)\n\t{\n\t  result = build_nop (build_ctype (totype), build_address (exp));\n\t}\n      else if (tbtype->ty == Tarray)\n\t{\n\t  dinteger_t dim = ((TypeSArray *) ebtype)->dim->toInteger ();\n\t  dinteger_t esize = ebtype->nextOf ()->size ();\n\t  dinteger_t tsize = tbtype->nextOf ()->size ();\n\n\t  tree ptrtype = build_ctype (tbtype->nextOf ()->pointerTo ());\n\n\t  if ((dim * esize) % tsize != 0)\n\t    {\n\t      error (\"cannot cast %qs to %qs since sizes don't line up\",\n\t\t     etype->toChars (), totype->toChars ());\n\t      return error_mark_node;\n\t    }\n\t  dim = (dim * esize) / tsize;\n\n\t  /* Assumes casting to dynamic array of same type or void.  */\n\t  return d_array_value (build_ctype (totype), size_int (dim),\n\t\t\t\tbuild_nop (ptrtype, build_address (exp)));\n\t}\n      else if (tbtype->ty == Tsarray)\n\t{\n\t  /* D allows casting a static array to any static array type.  */\n\t  return build_nop (build_ctype (totype), exp);\n\t}\n      else if (tbtype->ty == Tstruct)\n\t{\n\t  /* And allows casting a static array to any struct type too.\n\t     Type sizes should have already been checked by the frontend.  */\n\t  gcc_assert (totype->size () == etype->size ());\n\t  result = build_vconvert (build_ctype (totype), exp);\n\t}\n      else\n\t{\n\t  error (\"cannot cast expression of type %qs to type %qs\",\n\t\t etype->toChars (), totype->toChars ());\n\t  return error_mark_node;\n\t}\n      break;\n\n    case Tarray:\n      if (tbtype->ty == Tpointer)\n\t{\n\t  return d_convert (build_ctype (totype), d_array_ptr (exp));\n\t}\n      else if (tbtype->ty == Tarray)\n\t{\n\t  /* Assume tvoid->size() == 1.  */\n\t  d_uns64 fsize = ebtype->nextOf ()->toBasetype ()->size ();\n\t  d_uns64 tsize = tbtype->nextOf ()->toBasetype ()->size ();\n\n\t  if (fsize != tsize)\n\t    {\n\t      /* Conversion requires a reinterpret cast of array.  */\n\t      return build_libcall (LIBCALL_ARRAYCAST, totype, 3,\n\t\t\t\t    size_int (tsize), size_int (fsize), exp);\n\t    }\n\t  else\n\t    {\n\t      /* Convert from void[] or elements are the same size\n\t\t -- don't change length.  */\n\t      return build_vconvert (build_ctype (totype), exp);\n\t    }\n\t}\n      else if (tbtype->ty == Tsarray)\n\t{\n\t  /* Strings are treated as dynamic arrays in D2.  */\n\t  if (ebtype->isString () && tbtype->isString ())\n\t    return indirect_ref (build_ctype (totype), d_array_ptr (exp));\n\t}\n      else\n\t{\n\t  error (\"cannot cast expression of type %qs to %qs\",\n\t\t etype->toChars (), totype->toChars ());\n\t  return error_mark_node;\n\t}\n      break;\n\n    case Taarray:\n      if (tbtype->ty == Taarray)\n\treturn build_vconvert (build_ctype (totype), exp);\n      /* Can convert associative arrays to void pointers.  */\n      else if (tbtype->ty == Tpointer && tbtype->nextOf ()->ty == Tvoid)\n\treturn build_vconvert (build_ctype (totype), exp);\n      /* Else, default conversion, which should product an error.  */\n      break;\n\n    case Tpointer:\n      /* Can convert void pointers to associative arrays too.  */\n      if (tbtype->ty == Taarray && ebtype->nextOf ()->ty == Tvoid)\n\treturn build_vconvert (build_ctype (totype), exp);\n      break;\n\n    case Tnull:\n      /* Casting from typeof(null) is represented as all zeros.  */\n      if (tbtype->ty == Tarray)\n\t{\n\t  tree ptrtype = build_ctype (tbtype->nextOf ()->pointerTo ());\n\t  return d_array_value (build_ctype (totype), size_int (0),\n\t\t\t\tbuild_nop (ptrtype, exp));\n\t}\n      else if (tbtype->ty == Taarray)\n\treturn build_constructor (build_ctype (totype), NULL);\n      else if (tbtype->ty == Tdelegate)\n\treturn build_delegate_cst (exp, null_pointer_node, totype);\n\n      return build_zero_cst (build_ctype (totype));\n\n    case Tvector:\n      if (tbtype->ty == Tsarray)\n\t{\n\t  if (tbtype->size () == ebtype->size ())\n\t    return build_vconvert (build_ctype (totype), exp);\n\t}\n      break;\n\n    default:\n      /* All casts between imaginary and non-imaginary result in 0.0,\n\t except for casts between complex and imaginary types.  */\n      if (!ebtype->iscomplex () && !tbtype->iscomplex ()\n\t  && (ebtype->isimaginary () != tbtype->isimaginary ()))\n\t{\n\t  warning (OPT_Wcast_result,\n\t\t   \"cast from %qs to %qs will produce zero result\",\n\t\t   ebtype->toChars (), tbtype->toChars ());\n\n\t  return compound_expr (exp, build_zero_cst (build_ctype (tbtype)));\n\t}\n\n      exp = fold_convert (build_ctype (etype), exp);\n      gcc_assert (TREE_CODE (exp) != STRING_CST);\n      break;\n    }\n\n  return result ? result : convert (build_ctype (totype), exp);\n}\n\n\n/* Apply semantics of assignment to a value of type TOTYPE to EXPR\n   (e.g., pointer = array -> pointer = &array[0])\n\n   Return a TREE representation of EXPR implicitly converted to TOTYPE\n   for use in assignment expressions MODIFY_EXPR, INIT_EXPR.  */\n\ntree\nconvert_for_assignment (tree expr, Type *etype, Type *totype)\n{\n  Type *ebtype = etype->toBasetype ();\n  Type *tbtype = totype->toBasetype ();\n\n  /* Assuming this only has to handle converting a non Tsarray type to\n     arbitrarily dimensioned Tsarrays.  */\n  if (tbtype->ty == Tsarray)\n    {\n      Type *telem = tbtype->nextOf ()->baseElemOf ();\n\n      if (same_type_p (telem, ebtype))\n\t{\n\t  TypeSArray *sa_type = (TypeSArray *) tbtype;\n\t  uinteger_t count = sa_type->dim->toUInteger ();\n\n\t  tree ctor = build_constructor (build_ctype (totype), NULL);\n\t  if (count)\n\t    {\n\t      vec<constructor_elt, va_gc> *ce = NULL;\n\t      tree index = build2 (RANGE_EXPR, build_ctype (Type::tsize_t),\n\t\t\t\t   size_zero_node, size_int (count - 1));\n\t      tree value = convert_for_assignment (expr, etype, sa_type->next);\n\n\t      /* Can't use VAR_DECLs in CONSTRUCTORS.  */\n\t      if (VAR_P (value))\n\t\t{\n\t\t  value = DECL_INITIAL (value);\n\t\t  gcc_assert (value);\n\t\t}\n\n\t      CONSTRUCTOR_APPEND_ELT (ce, index, value);\n\t      CONSTRUCTOR_ELTS (ctor) = ce;\n\t    }\n\t  TREE_READONLY (ctor) = 1;\n\t  TREE_CONSTANT (ctor) = 1;\n\t  return ctor;\n\t}\n    }\n\n  /* D Front end uses IntegerExp(0) to mean zero-init an array or structure.  */\n  if ((tbtype->ty == Tsarray || tbtype->ty == Tstruct)\n      && ebtype->isintegral ())\n    {\n      if (!integer_zerop (expr))\n\tgcc_unreachable ();\n\n      return expr;\n    }\n\n  return convert_expr (expr, etype, totype);\n}\n\n/* Return a TREE representation of EXPR converted to represent\n   the parameter type ARG.  */\n\ntree\nconvert_for_argument (tree expr, Parameter *arg)\n{\n  /* Lazy arguments: expr should already be a delegate.  */\n  if (arg->storageClass & STClazy)\n    return expr;\n\n  if (valist_array_p (arg->type))\n    {\n      /* Do nothing if the va_list has already been decayed to a pointer.  */\n      if (!POINTER_TYPE_P (TREE_TYPE (expr)))\n\treturn build_address (expr);\n    }\n  else if (argument_reference_p (arg))\n    {\n      /* Front-end shouldn't automatically take the address.  */\n      return convert (type_passed_as (arg), build_address (expr));\n    }\n\n  return expr;\n}\n\n/* Perform default promotions for data used in expressions.\n   Arrays and functions are converted to pointers;\n   enumeral types or short or char, to int.\n   In addition, manifest constants symbols are replaced by their values.\n\n   Return truth-value conversion of expression EXPR from value type TYPE.  */\n\ntree\nconvert_for_condition (tree expr, Type *type)\n{\n  tree result = NULL_TREE;\n\n  switch (type->toBasetype ()->ty)\n    {\n    case Taarray:\n      /* Checks that aa.ptr !is null.  */\n      result = component_ref (expr, TYPE_FIELDS (TREE_TYPE (expr)));\n      break;\n\n    case Tarray:\n      {\n\t/* Checks (arr.length || arr.ptr) (i.e arr !is null).  */\n\texpr = d_save_expr (expr);\n\ttree len = d_array_length (expr);\n\ttree ptr = d_array_ptr (expr);\n\tif (TYPE_MODE (TREE_TYPE (len)) == TYPE_MODE (TREE_TYPE (ptr)))\n\t  {\n\t    result = build2 (BIT_IOR_EXPR, TREE_TYPE (len), len,\n\t\t\t     d_convert (TREE_TYPE (len), ptr));\n\t  }\n\telse\n\t  {\n\t    len = d_truthvalue_conversion (len);\n\t    ptr = d_truthvalue_conversion (ptr);\n\t    /* Probably not worth using TRUTH_OROR here.  */\n\t    result = build2 (TRUTH_OR_EXPR, TREE_TYPE (len), len, ptr);\n\t  }\n\tbreak;\n      }\n\n    case Tdelegate:\n      {\n\t/* Checks (function || object), but what good is it if there is\n\t   a null function pointer?  */\n\ttree obj, func;\n\tif (METHOD_CALL_EXPR (expr))\n\t  extract_from_method_call (expr, obj, func);\n\telse\n\t  {\n\t    expr = d_save_expr (expr);\n\t    obj = delegate_object (expr);\n\t    func = delegate_method (expr);\n\t  }\n\n\tobj = d_truthvalue_conversion (obj);\n\tfunc = d_truthvalue_conversion (func);\n\t/* Probably not worth using TRUTH_ORIF here.  */\n\tresult = build2 (BIT_IOR_EXPR, TREE_TYPE (obj), obj, func);\n\tbreak;\n      }\n\n    default:\n      result = expr;\n      break;\n    }\n\n  return d_truthvalue_conversion (result);\n}\n\n\n/* Convert EXP to a dynamic array.\n   EXP must be a static array or dynamic array.  */\n\ntree\nd_array_convert (Expression *exp)\n{\n  Type *tb = exp->type->toBasetype ();\n\n  if (tb->ty == Tarray)\n    return build_expr (exp);\n\n  if (tb->ty == Tsarray)\n    {\n      Type *totype = tb->nextOf ()->arrayOf ();\n      return convert_expr (build_expr (exp), exp->type, totype);\n    }\n\n  /* Invalid type passed.  */\n  gcc_unreachable ();\n}\n\n/* Convert EXP to a dynamic array, where ETYPE is the element type.\n   Similar to above, except that EXP is allowed to be an element of an array.\n   Temporary variables that need some kind of BIND_EXPR are pushed to VARS.  */\n\ntree\nd_array_convert (Type *etype, Expression *exp, vec<tree, va_gc> **vars)\n{\n  Type *tb = exp->type->toBasetype ();\n\n  if ((tb->ty != Tarray && tb->ty != Tsarray) || same_type_p (tb, etype))\n    {\n      /* Convert single element to an array.  */\n      tree var = NULL_TREE;\n      tree expr = maybe_temporary_var (build_expr (exp), &var);\n\n      if (var != NULL_TREE)\n\tvec_safe_push (*vars, var);\n\n      return d_array_value (build_ctype (exp->type->arrayOf ()),\n\t\t\t    size_int (1), build_address (expr));\n    }\n  else\n    return d_array_convert (exp);\n}\n"
  },
  {
    "path": "gcc/d/d-diagnostic.cc",
    "content": "/* d-diagnostics.cc -- D frontend interface to gcc diagnostics.\n   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/globals.h\"\n#include \"dmd/errors.h\"\n\n#include \"tree.h\"\n#include \"options.h\"\n#include \"diagnostic.h\"\n\n#include \"d-tree.h\"\n\n\n/* Rewrite the format string FORMAT to deal with any format extensions not\n   supported by pp_format().\n\n   The following format specifiers are handled:\n   `...`: text within backticks gets quoted as '%<...%>'.\n   %-10s: left-justify format flag is removed leaving '%s' remaining.\n   %02x: zero-padding format flag is removed leaving '%x' remaining.\n   %X: uppercase unsigned hexadecimals are rewritten as '%x'.\n\n   The result should be freed by the caller.  */\n\nstatic char *\nexpand_d_format (const char *format)\n{\n  OutBuffer buf;\n  bool inbacktick = false;\n\n  for (const char *p = format; *p;)\n    {\n      while (*p != '\\0' && *p != '%' && *p != '`')\n\t{\n\t  buf.writeByte (*p);\n\t  p++;\n\t}\n\n      if (*p == '\\0')\n\tbreak;\n\n      if (*p == '`')\n\t{\n\t  /* Text enclosed by `...` are translated as a quoted string.  */\n\t  if (inbacktick)\n\t    {\n\t      buf.writestring (\"%>\");\n\t      inbacktick = false;\n\t    }\n\t  else\n\t    {\n\t      buf.writestring (\"%<\");\n\t      inbacktick = true;\n\t    }\n\t  p++;\n\t  continue;\n\t}\n\n      /* Check the conversion specification for unhandled flags.  */\n      buf.writeByte (*p);\n      p++;\n\n    Lagain:\n      switch (*p)\n\t{\n\tcase '\\0':\n\t  /* Malformed format string.  */\n\t  gcc_unreachable ();\n\n\tcase '-':\n\t  /* Remove whitespace formatting.  */\n\t  p++;\n\t  while (ISDIGIT (*p))\n\t    p++;\n\t  goto Lagain;\n\n\tcase '0':\n\t  /* Remove zero padding from format string.  */\n\t  while (ISDIGIT (*p))\n\t    p++;\n\t  goto Lagain;\n\n\tcase 'X':\n\t  /* Hex format only supports lower-case.  */\n\t  buf.writeByte ('x');\n\t  p++;\n\t  break;\n\n\tdefault:\n\t  break;\n\t}\n    }\n\n  gcc_assert (!inbacktick);\n  return buf.extractString ();\n}\n\n/* Helper routine for all error routines.  Reports a diagnostic specified by\n   KIND at the explicit location LOC.  The message FORMAT comes from the dmd\n   front-end, which does not get translated by the gcc diagnostic routines.  */\n\nstatic void ATTRIBUTE_GCC_DIAG(3,0)\nd_diagnostic_report_diagnostic (const Loc& loc, int opt, const char *format,\n\t\t\t\tva_list ap, diagnostic_t kind, bool verbatim)\n{\n  va_list argp;\n  va_copy (argp, ap);\n\n  if (loc.filename || !verbatim)\n    {\n      rich_location rich_loc (line_table, make_location_t (loc));\n      diagnostic_info diagnostic;\n      char *xformat = expand_d_format (format);\n\n      diagnostic_set_info_translated (&diagnostic, xformat, &argp,\n\t\t\t\t      &rich_loc, kind);\n      if (opt != 0)\n\tdiagnostic.option_index = opt;\n\n      diagnostic_report_diagnostic (global_dc, &diagnostic);\n      free (xformat);\n    }\n  else\n    {\n      /* Write verbatim messages with no location direct to stream.  */\n      text_info text;\n      text.err_no = errno;\n      text.args_ptr = &argp;\n      text.format_spec = expand_d_format (format);\n      text.x_data = NULL;\n\n      pp_format_verbatim (global_dc->printer, &text);\n      pp_newline_and_flush (global_dc->printer);\n    }\n\n  va_end (argp);\n}\n\n/* Print a hard error message with explicit location LOC with an optional\n   message prefix PREFIX1 and PREFIX2, increasing the global or gagged\n   error count.  */\n\nvoid ATTRIBUTE_GCC_DIAG(2,0)\nverror (const Loc& loc, const char *format, va_list ap,\n\tconst char *prefix1, const char *prefix2, const char *)\n{\n  if (!global.gag || global.params.showGaggedErrors)\n    {\n      char *xformat;\n\n      /* Build string and emit.  */\n      if (prefix2 != NULL)\n\txformat = xasprintf (\"%s %s %s\", prefix1, prefix2, format);\n      else if (prefix1 != NULL)\n\txformat = xasprintf (\"%s %s\", prefix1, format);\n      else\n\txformat = xasprintf (\"%s\", format);\n\n      d_diagnostic_report_diagnostic (loc, 0, xformat, ap,\n\t\t\t\t      global.gag ? DK_ANACHRONISM : DK_ERROR,\n\t\t\t\t      false);\n      free (xformat);\n    }\n\n  if (global.gag)\n    global.gaggedErrors++;\n\n  global.errors++;\n}\n\n/* Print supplementary message about the last error with explicit location LOC.\n   This doesn't increase the global error count.  */\n\nvoid ATTRIBUTE_GCC_DIAG(2,0)\nverrorSupplemental (const Loc& loc, const char *format, va_list ap)\n{\n  if (global.gag && !global.params.showGaggedErrors)\n    return;\n\n  d_diagnostic_report_diagnostic (loc, 0, format, ap, DK_NOTE, false);\n}\n\n/* Print a warning message with explicit location LOC, increasing the\n   global warning count.  */\n\nvoid ATTRIBUTE_GCC_DIAG(2,0)\nvwarning (const Loc& loc, const char *format, va_list ap)\n{\n  if (!global.gag && global.params.warnings != DIAGNOSTICoff)\n    {\n      /* Warnings don't count if not treated as errors.  */\n      if (global.params.warnings == DIAGNOSTICerror)\n\tglobal.warnings++;\n\n      d_diagnostic_report_diagnostic (loc, 0, format, ap, DK_WARNING, false);\n    }\n  else if (global.gag)\n    global.gaggedWarnings++;\n}\n\n/* Print supplementary message about the last warning with explicit location\n   LOC.  This doesn't increase the global warning count.  */\n\nvoid ATTRIBUTE_GCC_DIAG(2,0)\nvwarningSupplemental (const Loc& loc, const char *format, va_list ap)\n{\n  if (global.params.warnings == DIAGNOSTICoff || global.gag)\n    return;\n\n  d_diagnostic_report_diagnostic (loc, 0, format, ap, DK_NOTE, false);\n}\n\n/* Print a deprecation message with explicit location LOC with an optional\n   message prefix PREFIX1 and PREFIX2, increasing the global warning or\n   error count depending on how deprecations are treated.  */\n\nvoid ATTRIBUTE_GCC_DIAG(2,0)\nvdeprecation (const Loc& loc, const char *format, va_list ap,\n\t      const char *prefix1, const char *prefix2)\n{\n  if (global.params.useDeprecated == DIAGNOSTICerror)\n    verror (loc, format, ap, prefix1, prefix2);\n  else if (global.params.useDeprecated == DIAGNOSTICinform && !global.gag)\n    {\n      char *xformat;\n\n      /* Build string and emit.  */\n      if (prefix2 != NULL)\n\txformat = xasprintf (\"%s %s %s\", prefix1, prefix2, format);\n      else if (prefix1 != NULL)\n\txformat = xasprintf (\"%s %s\", prefix1, format);\n      else\n\txformat = xasprintf (\"%s\", format);\n\n      d_diagnostic_report_diagnostic (loc, OPT_Wdeprecated, xformat, ap,\n\t\t\t\t      DK_WARNING, false);\n      free (xformat);\n    }\n  else if (global.gag)\n    global.gaggedWarnings++;\n}\n\n/* Print supplementary message about the last deprecation with explicit\n   location LOC.  This does not increase the global error count.  */\n\nvoid ATTRIBUTE_GCC_DIAG(2,0)\nvdeprecationSupplemental (const Loc& loc, const char *format, va_list ap)\n{\n  if (global.params.useDeprecated == DIAGNOSTICerror)\n    verrorSupplemental (loc, format, ap);\n  else if (global.params.useDeprecated == DIAGNOSTICinform && !global.gag)\n    d_diagnostic_report_diagnostic (loc, 0, format, ap, DK_NOTE, false);\n}\n\n/* Print a verbose message with explicit location LOC.  */\n\nvoid ATTRIBUTE_GCC_DIAG(2,0)\nvmessage (const Loc& loc, const char *format, va_list ap)\n{\n  d_diagnostic_report_diagnostic (loc, 0, format, ap, DK_NOTE, true);\n}\n\n/* Call this after printing out fatal error messages to clean up and\n   exit the compiler.  */\n\nvoid\nfatal (void)\n{\n  exit (FATAL_EXIT_CODE);\n}\n"
  },
  {
    "path": "gcc/d/d-frontend.cc",
    "content": "/* d-frontend.cc -- D frontend interface to the gcc back-end.\n   Copyright (C) 2013-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/aggregate.h\"\n#include \"dmd/compiler.h\"\n#include \"dmd/declaration.h\"\n#include \"dmd/errors.h\"\n#include \"dmd/expression.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/module.h\"\n#include \"dmd/mtype.h\"\n#include \"dmd/scope.h\"\n#include \"dmd/statement.h\"\n#include \"dmd/target.h\"\n\n#include \"tree.h\"\n#include \"options.h\"\n#include \"fold-const.h\"\n#include \"diagnostic.h\"\n#include \"stor-layout.h\"\n\n#include \"d-tree.h\"\n\n\n/* Implements the Global interface defined by the frontend.\n   Used for managing the state of the current compilation.  */\n\nvoid\nGlobal::_init (void)\n{\n  this->obj_ext = \"o\";\n\n  this->run_noext = true;\n  this->version = \"v\"\n#include \"verstr.h\"\n    ;\n}\n\n/* Implements the Loc interface defined by the frontend.\n   Used for keeping track of current file/line position in code.  */\n\nLoc::Loc (const char *filename, unsigned linnum, unsigned charnum)\n{\n  this->linnum = linnum;\n  this->charnum = charnum;\n  this->filename = filename;\n}\n\nconst char *\nLoc::toChars (void) const\n{\n  OutBuffer buf;\n\n  if (this->filename)\n    buf.printf (\"%s\", this->filename);\n\n  if (this->linnum)\n    {\n      buf.printf (\":%u\", this->linnum);\n      if (this->charnum)\n\tbuf.printf (\":%u\", this->charnum);\n    }\n\n  return buf.extractString ();\n}\n\n\n/* Implements the Port interface defined by the frontend.\n   A mini library for doing compiler/system specific things.  */\n\n/* Compare the first N bytes of S1 and S2 without regard to the case.  */\n\nint\nPort::memicmp (const char *s1, const char *s2, size_t n)\n{\n  int result = 0;\n\n  for (size_t i = 0; i < n; i++)\n    {\n      char c1 = s1[i];\n      char c2 = s2[i];\n\n      result = c1 - c2;\n      if (result)\n\t{\n\t  result = TOUPPER (c1) - TOUPPER (c2);\n\t  if (result)\n\t    break;\n\t}\n    }\n\n  return result;\n}\n\n/* Convert all characters in S to uppercase.  */\n\nchar *\nPort::strupr (char *s)\n{\n  char *t = s;\n\n  while (*s)\n    {\n      *s = TOUPPER (*s);\n      s++;\n    }\n\n  return t;\n}\n\n/* Return true if the real_t value from string BUFFER overflows\n   as a result of rounding down to float mode.  */\n\nbool\nPort::isFloat32LiteralOutOfRange (const char *buffer)\n{\n  real_t r;\n\n  real_from_string3 (&r.rv (), buffer, TYPE_MODE (float_type_node));\n\n  return r == Target::RealProperties::infinity;\n}\n\n/* Return true if the real_t value from string BUFFER overflows\n   as a result of rounding down to double mode.  */\n\nbool\nPort::isFloat64LiteralOutOfRange (const char *buffer)\n{\n  real_t r;\n\n  real_from_string3 (&r.rv (), buffer, TYPE_MODE (double_type_node));\n\n  return r == Target::RealProperties::infinity;\n}\n\n/* Fetch a little-endian 16-bit value from BUFFER.  */\n\nunsigned\nPort::readwordLE (void *buffer)\n{\n  unsigned char *p = (unsigned char*) buffer;\n\n  return ((unsigned) p[1] << 8) | (unsigned) p[0];\n}\n\n/* Fetch a big-endian 16-bit value from BUFFER.  */\n\nunsigned\nPort::readwordBE (void *buffer)\n{\n  unsigned char *p = (unsigned char*) buffer;\n\n  return ((unsigned) p[0] << 8) | (unsigned) p[1];\n}\n\n/* Fetch a little-endian 32-bit value from BUFFER.  */\n\nunsigned\nPort::readlongLE (void *buffer)\n{\n  unsigned char *p = (unsigned char*) buffer;\n\n  return (((unsigned) p[3] << 24)\n\t  | ((unsigned) p[2] << 16)\n\t  | ((unsigned) p[1] << 8)\n\t  | (unsigned) p[0]);\n}\n\n/* Fetch a big-endian 32-bit value from BUFFER.  */\n\nunsigned\nPort::readlongBE (void *buffer)\n{\n  unsigned char *p = (unsigned char*) buffer;\n\n  return (((unsigned) p[0] << 24)\n\t  | ((unsigned) p[1] << 16)\n\t  | ((unsigned) p[2] << 8)\n\t  | (unsigned) p[3]);\n}\n\n/* Write an SZ-byte sized VALUE to BUFFER, ignoring endian-ness.  */\n\nvoid\nPort::valcpy (void *buffer, uint64_t value, size_t sz)\n{\n  switch (sz)\n    {\n    case 1:\n      *(uint8_t *) buffer = (uint8_t) value;\n      break;\n\n    case 2:\n      *(uint16_t *) buffer = (uint16_t) value;\n      break;\n\n    case 4:\n      *(uint32_t *) buffer = (uint32_t) value;\n      break;\n\n    case 8:\n      *(uint64_t *) buffer = (uint64_t) value;\n      break;\n\n    default:\n      gcc_unreachable ();\n    }\n}\n\n\n/* Implements the CTFloat interface defined by the frontend.\n   Compile-time floating-pointer helper functions.  */\n\n/* Return the absolute value of R.  */\n\nreal_t\nCTFloat::fabs (real_t r)\n{\n  real_t x;\n  real_arithmetic (&x.rv (), ABS_EXPR, &r.rv (), NULL);\n  return x.normalize ();\n}\n\n/* Return the value of R * 2 ^^ EXP.  */\n\nreal_t\nCTFloat::ldexp (real_t r, int exp)\n{\n  real_t x;\n  real_ldexp (&x.rv (), &r.rv (), exp);\n  return x.normalize ();\n}\n\n/* Return true if longdouble value X is identical to Y.  */\n\nbool\nCTFloat::isIdentical (real_t x, real_t y)\n{\n  real_value rx = x.rv ();\n  real_value ry = y.rv ();\n  return (REAL_VALUE_ISNAN (rx) && REAL_VALUE_ISNAN (ry))\n    || real_identical (&rx, &ry);\n}\n\n/* Return true if real_t value R is NaN.  */\n\nbool\nCTFloat::isNaN (real_t r)\n{\n  return REAL_VALUE_ISNAN (r.rv ());\n}\n\n/* Same as isNaN, but also check if is signalling.  */\n\nbool\nCTFloat::isSNaN (real_t r)\n{\n  return REAL_VALUE_ISSIGNALING_NAN (r.rv ());\n}\n\n/* Return true if real_t value is +Inf.  */\n\nbool\nCTFloat::isInfinity (real_t r)\n{\n  return REAL_VALUE_ISINF (r.rv ());\n}\n\n/* Return a real_t value from string BUFFER rounded to long double mode.  */\n\nreal_t\nCTFloat::parse (const char *buffer, bool *overflow)\n{\n  real_t r;\n  real_from_string3 (&r.rv (), buffer, TYPE_MODE (long_double_type_node));\n\n  /* Front-end checks overflow to see if the value is representable.  */\n  if (overflow && r == Target::RealProperties::infinity)\n    *overflow = true;\n\n  return r;\n}\n\n/* Format the real_t value R to string BUFFER as a decimal or hexadecimal,\n   converting the result to uppercase if FMT requests it.  */\n\nint\nCTFloat::sprint (char *buffer, char fmt, real_t r)\n{\n  if (fmt == 'a' || fmt == 'A')\n    {\n      /* Converting to a hexadecimal string.  */\n      real_to_hexadecimal (buffer, &r.rv (), 32, 0, 1);\n      int buflen;\n\n      switch (fmt)\n\t{\n\tcase 'A':\n\t  buflen = strlen (buffer);\n\t  for (int i = 0; i < buflen; i++)\n\t    buffer[i] = TOUPPER (buffer[i]);\n\n\t  return buflen;\n\n\tcase 'a':\n\t  return strlen (buffer);\n\n\tdefault:\n\t  gcc_unreachable ();\n\t}\n    }\n  else\n    {\n      /* Note: restricting the precision of significant digits to 18.  */\n      real_to_decimal (buffer, &r.rv (), 32, 18, 1);\n      return strlen (buffer);\n    }\n}\n\n/* Return a hash value for real_t value R.  */\n\nsize_t\nCTFloat::hash (real_t r)\n{\n  return real_hash (&r.rv ());\n}\n\n/* Implements the Compiler interface used by the frontend.  */\n\n/* Generate C main() in response to seeing D main().  This used to be in\n   libdruntime, but contained a reference to _Dmain which didn't work when\n   druntime was made into a shared library and was linked to a program, such\n   as a C++ program, that didn't have a _Dmain.  */\n\nvoid\nCompiler::genCmain (Scope *sc)\n{\n  static bool initialized = false;\n\n  if (initialized)\n    return;\n\n  /* The D code to be generated is provided by __entrypoint.di, try to load it,\n     but don't fail if unfound.  */\n  unsigned errors = global.startGagging ();\n  Module *m = Module::load (Loc (), NULL, Identifier::idPool (\"__entrypoint\"));\n\n  if (global.endGagging (errors))\n    m = NULL;\n\n  if (m != NULL)\n    {\n      m->importedFrom = m;\n      m->importAll (NULL);\n      dsymbolSemantic (m, NULL);\n      semantic2 (m, NULL);\n      semantic3 (m, NULL);\n      d_add_entrypoint_module (m, sc->_module);\n    }\n\n  initialized = true;\n}\n\n/* Perform a reinterpret cast of EXPR to type TYPE for use in CTFE.\n   The front end should have already ensured that EXPR is a constant,\n   so we just lower the value to GCC and return the converted CST.  */\n\nExpression *\nCompiler::paintAsType (Expression *expr, Type *type)\n{\n  /* We support up to 512-bit values.  */\n  unsigned char buffer[64];\n  tree cst;\n\n  Type *tb = type->toBasetype ();\n\n  if (expr->type->isintegral ())\n    cst = build_integer_cst (expr->toInteger (), build_ctype (expr->type));\n  else if (expr->type->isfloating ())\n    cst = build_float_cst (expr->toReal (), expr->type);\n  else if (expr->op == TOKarrayliteral)\n    {\n      /* Build array as VECTOR_CST, assumes EXPR is constant.  */\n      Expressions *elements = ((ArrayLiteralExp *) expr)->elements;\n      vec<constructor_elt, va_gc> *elms = NULL;\n\n      vec_safe_reserve (elms, elements->dim);\n      for (size_t i = 0; i < elements->dim; i++)\n\t{\n\t  Expression *e = (*elements)[i];\n\t  if (e->type->isintegral ())\n\t    {\n\t      tree value = build_integer_cst (e->toInteger (),\n\t\t\t\t\t      build_ctype (e->type));\n\t      CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);\n\t    }\n\t  else if (e->type->isfloating ())\n\t    {\n\t      tree value = build_float_cst (e->toReal (), e->type);\n\t      CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);\n\t    }\n\t  else\n\t    gcc_unreachable ();\n\t}\n\n      /* Build vector type.  */\n      int nunits = ((TypeSArray *) expr->type)->dim->toUInteger ();\n      Type *telem = expr->type->nextOf ();\n      tree vectype = build_vector_type (build_ctype (telem), nunits);\n\n      cst = build_vector_from_ctor (vectype, elms);\n    }\n  else\n    gcc_unreachable ();\n\n  /* Encode CST to buffer.  */\n  int len = native_encode_expr (cst, buffer, sizeof (buffer));\n\n  if (tb->ty == Tsarray)\n    {\n      /* Interpret value as a vector of the same size,\n\t then return the array literal.  */\n      int nunits = ((TypeSArray *) type)->dim->toUInteger ();\n      Type *elem = type->nextOf ();\n      tree vectype = build_vector_type (build_ctype (elem), nunits);\n\n      cst = native_interpret_expr (vectype, buffer, len);\n\n      Expression *e = d_eval_constant_expression (cst);\n      gcc_assert (e != NULL && e->op == TOKvector);\n\n      return ((VectorExp *) e)->e1;\n    }\n  else\n    {\n      /* Normal interpret cast.  */\n      cst = native_interpret_expr (build_ctype (type), buffer, len);\n\n      Expression *e = d_eval_constant_expression (cst);\n      gcc_assert (e != NULL);\n\n      return e;\n    }\n}\n\n/* Check imported module M for any special processing.\n   Modules we look out for are:\n    - object: For D runtime type information.\n    - gcc.builtins: For all gcc builtins.\n    - core.stdc.*: For all gcc library builtins.  */\n\nvoid\nCompiler::loadModule (Module *m)\n{\n  ModuleDeclaration *md = m->md;\n\n  if (!md || !md->id || !md->packages)\n    {\n      Identifier *id = (md && md->id) ? md->id : m->ident;\n      if (!strcmp (id->toChars (), \"object\"))\n\tcreate_tinfo_types (m);\n    }\n  else if (md->packages->dim == 1)\n    {\n      if (!strcmp ((*md->packages)[0]->toChars (), \"gcc\")\n\t  && !strcmp (md->id->toChars (), \"builtins\"))\n\td_build_builtins_module (m);\n    }\n  else if (md->packages->dim == 2)\n    {\n      if (!strcmp ((*md->packages)[0]->toChars (), \"core\")\n\t  && !strcmp ((*md->packages)[1]->toChars (), \"stdc\"))\n\td_add_builtin_module (m);\n    }\n}\n\n/* A callback function that is called once an imported module is parsed.\n   If the callback returns true, then it tells the front-end that the\n   driver intends on compiling the import.  */\n\nbool\nCompiler::onImport (Module *)\n{\n  return false;\n}\n\n/* Implements back-end specific interfaces used by the frontend.  */\n\n/* Determine if function FD is a builtin one that we can evaluate in CTFE.  */\n\nBUILTIN\nisBuiltin (FuncDeclaration *fd)\n{\n  if (fd->builtin != BUILTINunknown)\n    return fd->builtin;\n\n  maybe_set_intrinsic (fd);\n\n  return fd->builtin;\n}\n\n/* Evaluate builtin D function FD whose argument list is ARGUMENTS.\n   Return result; NULL if cannot evaluate it.  */\n\nExpression *\neval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments)\n{\n  if (fd->builtin != BUILTINyes)\n    return NULL;\n\n  tree decl = get_symbol_decl (fd);\n  gcc_assert (fndecl_built_in_p (decl)\n\t      || DECL_INTRINSIC_CODE (decl) != INTRINSIC_NONE);\n\n  TypeFunction *tf = (TypeFunction *) fd->type;\n  Expression *e = NULL;\n  input_location = make_location_t (loc);\n\n  tree result = d_build_call (tf, decl, NULL, arguments);\n  result = fold (result);\n\n  /* Builtin should be successfully evaluated.\n     Will only return NULL if we can't convert it.  */\n  if (TREE_CONSTANT (result) && TREE_CODE (result) != CALL_EXPR)\n    e = d_eval_constant_expression (result);\n\n  return e;\n}\n\n/* Build and return typeinfo type for TYPE.  */\n\nType *\ngetTypeInfoType (Loc loc, Type *type, Scope *sc)\n{\n  if (!global.params.useTypeInfo)\n    {\n      /* Even when compiling without RTTI we should still be able to evaluate\n\t TypeInfo at compile-time, just not at run-time.  */\n      if (!sc || !(sc->flags & SCOPEctfe))\n\t{\n\t  static int warned = 0;\n\n\t  if (!warned)\n\t    {\n\t      error_at (make_location_t (loc),\n\t\t\t\"%<object.TypeInfo%> cannot be used with -fno-rtti\");\n\t      warned = 1;\n\t    }\n\t}\n    }\n\n  if (Type::dtypeinfo == NULL\n      || (Type::dtypeinfo->storage_class & STCtemp))\n    {\n      /* If TypeInfo has not been declared, warn about each location once.  */\n      static Loc warnloc;\n\n      if (!loc.equals (warnloc))\n\t{\n\t  error_at (make_location_t (loc),\n\t\t    \"%<object.TypeInfo%> could not be found, \"\n\t\t    \"but is implicitly used\");\n\t  warnloc = loc;\n\t}\n    }\n\n  gcc_assert (type->ty != Terror);\n  create_typeinfo (type, sc ? sc->_module->importedFrom : NULL);\n  return type->vtinfo->type;\n}\n"
  },
  {
    "path": "gcc/d/d-incpath.cc",
    "content": "/* d-incpath.cc -- Set up combined import paths for the D frontend.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/globals.h\"\n\n#include \"cppdefault.h\"\n\n/* Look for directories that start with the standard prefix.\n   \"Translate\" them, i.e: replace /usr/local/lib/gcc with\n   IPREFIX and search them first.  Based on incpath.c.  */\n\nstatic char *\nprefixed_path (const char *path, const char *iprefix)\n{\n  size_t len;\n\n  if (cpp_relocated () && (len = cpp_PREFIX_len) != 0)\n  {\n    if (!strncmp (path, cpp_PREFIX, len))\n      {\n\tstatic const char *relocated_prefix;\n\t/* If this path starts with the configure-time prefix,\n\t   but the compiler has been relocated, replace it\n\t   with the run-time prefix.  */\n\tif (!relocated_prefix)\n\t  {\n\t    /* Make relative prefix expects the first argument\n\t       to be a program, not a directory.  */\n\t    char *dummy = concat (gcc_exec_prefix, \"dummy\", NULL);\n\t    relocated_prefix\n\t      = make_relative_prefix (dummy,\n\t\t\t\t      cpp_EXEC_PREFIX,\n\t\t\t\t      cpp_PREFIX);\n\t    free (dummy);\n\t  }\n\n\treturn concat (relocated_prefix, path + len, NULL);\n      }\n  }\n\n  if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0)\n    {\n      if (!strncmp (path, cpp_GCC_INCLUDE_DIR, len))\n\treturn concat (iprefix, path + len, NULL);\n    }\n\n  return xstrdup (path);\n}\n\n/* Add PATHS to the global import lookup path.  */\n\nstatic void\nadd_globalpaths (Strings *paths)\n{\n  if (paths)\n    {\n      if (!global.path)\n\tglobal.path = new Strings ();\n\n      for (size_t i = 0; i < paths->dim; i++)\n\t{\n\t  const char *path = (*paths)[i];\n\t  const char *target = FileName::canonicalName (path);\n\n\t  if (target == NULL || !FileName::exists (target))\n\t    {\n\t      if (target)\n\t\tfree (CONST_CAST (char *, target));\n\t      continue;\n\t    }\n\n\t  global.path->push (target);\n\t}\n    }\n}\n\n/* Add PATHS to the global file import lookup path.  */\n\nstatic void\nadd_filepaths (Strings *paths)\n{\n  if (paths)\n    {\n      if (!global.filePath)\n\tglobal.filePath = new Strings ();\n\n      for (size_t i = 0; i < paths->dim; i++)\n\t{\n\t  const char *path = (*paths)[i];\n\t  const char *target = FileName::canonicalName (path);\n\n\t  if (!FileName::exists (target))\n\t    {\n\t      free (CONST_CAST (char *, target));\n\t      continue;\n\t    }\n\n\t  global.filePath->push (target);\n\t}\n    }\n}\n\n/* Add all search directories to compiler runtime.\n   if STDINC, also include standard library paths.  */\n\nvoid\nadd_import_paths (const char *iprefix, const char *imultilib, bool stdinc)\n{\n  if (stdinc)\n    {\n      for (const default_include *p = cpp_include_defaults; p->fname; p++)\n\t{\n\t  char *path;\n\n\t  /* Ignore C++ paths.  */\n\t  if (p->cplusplus)\n\t    continue;\n\n\t  if (!p->add_sysroot)\n\t    path = prefixed_path (p->fname, iprefix);\n\t  else\n\t    path = xstrdup (p->fname);\n\n\t  /* Add D-specific suffix.  */\n\t  path = concat (path, \"/d\", NULL);\n\n\t  /* Ignore duplicate entries.  */\n\t  bool found = false;\n\t  for (size_t i = 0; i < global.params.imppath->dim; i++)\n\t    {\n\t      if (strcmp (path, (*global.params.imppath)[i]) == 0)\n\t\t{\n\t\t  found = true;\n\t\t  break;\n\t\t}\n\t    }\n\n\t  if (found)\n\t    {\n\t      free (path);\n\t      continue;\n\t    }\n\n\t  /* Multilib support.  */\n\t  if (imultilib)\n\t    {\n\t      char *target_path = concat (path, \"/\", imultilib, NULL);\n\t      global.params.imppath->shift (target_path);\n\t    }\n\n\t  global.params.imppath->shift (path);\n\t}\n    }\n\n  /* Add import search paths.  */\n  if (global.params.imppath)\n    {\n      for (size_t i = 0; i < global.params.imppath->dim; i++)\n\t{\n\t  const char *path = (*global.params.imppath)[i];\n\t  if (path)\n\t    add_globalpaths (FileName::splitPath (path));\n\t}\n    }\n\n  /* Add string import search paths.  */\n  if (global.params.fileImppath)\n    {\n      for (size_t i = 0; i < global.params.fileImppath->dim; i++)\n\t{\n\t  const char *path = (*global.params.fileImppath)[i];\n\t  if (path)\n\t    add_filepaths (FileName::splitPath (path));\n\t}\n    }\n}\n\n"
  },
  {
    "path": "gcc/d/d-lang.cc",
    "content": "/* d-lang.cc -- Language-dependent hooks for D.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/aggregate.h\"\n#include \"dmd/cond.h\"\n#include \"dmd/declaration.h\"\n#include \"dmd/doc.h\"\n#include \"dmd/errors.h\"\n#include \"dmd/expression.h\"\n#include \"dmd/hdrgen.h\"\n#include \"dmd/id.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/json.h\"\n#include \"dmd/mangle.h\"\n#include \"dmd/mars.h\"\n#include \"dmd/module.h\"\n#include \"dmd/mtype.h\"\n#include \"dmd/target.h\"\n\n#include \"opts.h\"\n#include \"alias.h\"\n#include \"tree.h\"\n#include \"diagnostic.h\"\n#include \"fold-const.h\"\n#include \"toplev.h\"\n#include \"langhooks.h\"\n#include \"langhooks-def.h\"\n#include \"target.h\"\n#include \"stringpool.h\"\n#include \"stor-layout.h\"\n#include \"varasm.h\"\n#include \"output.h\"\n#include \"print-tree.h\"\n#include \"gimple-expr.h\"\n#include \"gimplify.h\"\n#include \"debug.h\"\n\n#include \"d-tree.h\"\n\n\n/* Array of D frontend type/decl nodes.  */\ntree d_global_trees[DTI_MAX];\n\n/* True if compilation is currently inside the D frontend semantic passes.  */\nbool doing_semantic_analysis_p = false;\n\n/* Options handled by the compiler that are separate from the frontend.  */\nstruct d_option_data\n{\n  const char *fonly;\t\t    /* -fonly=<arg>  */\n  const char *multilib;\t\t    /* -imultilib <dir>  */\n  const char *prefix;\t\t    /* -iprefix <dir>  */\n\n  bool deps;\t\t\t    /* -M  */\n  bool deps_skip_system;\t    /* -MM  */\n  const char *deps_filename;\t    /* -M[M]D  */\n  const char *deps_filename_user;   /* -MF <arg>  */\n  OutBuffer *deps_target;\t    /* -M[QT] <arg> */\n  bool deps_phony;\t\t    /* -MP  */\n\n  bool stdinc;\t\t\t    /* -nostdinc  */\n}\nd_option;\n\n/* List of modules being compiled.  */\nstatic Modules builtin_modules;\n\n/* Module where `C main' is defined, compiled in if needed.  */\nstatic Module *entrypoint_module = NULL;\nstatic Module *entrypoint_root_module = NULL;\n\n/* The current and global binding level in effect.  */\nstruct binding_level *current_binding_level;\nstruct binding_level *global_binding_level;\n\n/* The context to be used for global declarations.  */\nstatic GTY(()) tree global_context;\n\n/* Array of all global declarations to pass back to the middle-end.  */\nstatic GTY(()) vec<tree, va_gc> *global_declarations;\n\n/* Support for GCC-style command-line make dependency generation.\n   Adds TARGET to the make dependencies target buffer.\n   QUOTED is true if the string should be quoted.  */\n\nstatic void\ndeps_add_target (const char *target, bool quoted)\n{\n  if (!d_option.deps_target)\n    d_option.deps_target = new OutBuffer ();\n  else\n    d_option.deps_target->writeByte (' ');\n\n  d_option.deps_target->reserve (strlen (target));\n\n  if (!quoted)\n    {\n      d_option.deps_target->writestring (target);\n      return;\n    }\n\n  /* Quote characters in target which are significant to Make.  */\n  for (const char *p = target; *p != '\\0'; p++)\n    {\n      switch (*p)\n\t{\n\tcase ' ':\n\tcase '\\t':\n\t  for (const char *q = p - 1; target <= q && *q == '\\\\';  q--)\n\t    d_option.deps_target->writeByte ('\\\\');\n\t  d_option.deps_target->writeByte ('\\\\');\n\t  break;\n\n\tcase '$':\n\t  d_option.deps_target->writeByte ('$');\n\t  break;\n\n\tcase '#':\n\t  d_option.deps_target->writeByte ('\\\\');\n\t  break;\n\n\tdefault:\n\t  break;\n\t}\n\n      d_option.deps_target->writeByte (*p);\n    }\n}\n\n/* Write out all dependencies of a given MODULE to the specified BUFFER.\n   COLMAX is the number of columns to word-wrap at (0 means don't wrap).  */\n\nstatic void\ndeps_write (Module *module, OutBuffer *buffer, unsigned colmax = 72)\n{\n  hash_set <const char *> dependencies;\n\n  Modules modlist;\n  modlist.push (module);\n\n  Modules phonylist;\n\n  const char *str;\n  unsigned size;\n  unsigned column = 0;\n\n  /* Write out make target module name.  */\n  if (d_option.deps_target)\n    {\n      size = d_option.deps_target->offset;\n      str = d_option.deps_target->extractString ();\n    }\n  else\n    {\n      str = module->objfile->name.toChars ();\n      size = strlen (str);\n    }\n\n  buffer->writestring (str);\n  column = size;\n  buffer->writestring (\":\");\n  column++;\n\n  /* Write out all make dependencies.  */\n  while (modlist.dim > 0)\n    {\n      Module *depmod = modlist.pop ();\n\n      str = depmod->srcfile->name.toChars ();\n      size = strlen (str);\n\n      /* Skip dependencies that have already been written.  */\n      if (dependencies.add (str))\n\tcontinue;\n\n      column += size;\n\n      if (colmax && column > colmax)\n\t{\n\t  buffer->writestring (\" \\\\\\n \");\n\t  column = size + 1;\n\t}\n      else\n\t{\n\t  buffer->writestring (\" \");\n\t  column++;\n\t}\n\n      buffer->writestring (str);\n\n      /* Add to list of phony targets if is not being compile.  */\n      if (d_option.deps_phony && !depmod->isRoot ())\n\tphonylist.push (depmod);\n\n      /* Search all imports of the written dependency.  */\n      for (size_t i = 0; i < depmod->aimports.dim; i++)\n\t{\n\t  Module *m = depmod->aimports[i];\n\n\t  /* Ignore compiler-generated modules.  */\n\t  if ((m->ident == Identifier::idPool (\"__entrypoint\")\n\t       || m->ident == Identifier::idPool (\"__main\"))\n\t      && m->parent == NULL)\n\t    continue;\n\n\t  /* Don't search system installed modules, this includes\n\t     object, core.*, std.*, and gcc.* packages.  */\n\t  if (d_option.deps_skip_system)\n\t    {\n\t      if (m->ident == Identifier::idPool (\"object\")\n\t\t  && m->parent == NULL)\n\t\tcontinue;\n\n\t      if (m->md && m->md->packages)\n\t\t{\n\t\t  Identifier *package = (*m->md->packages)[0];\n\n\t\t  if (package == Identifier::idPool (\"core\")\n\t\t      || package == Identifier::idPool (\"std\")\n\t\t      || package == Identifier::idPool (\"gcc\"))\n\t\t    continue;\n\t\t}\n\t    }\n\n\t  modlist.push (m);\n\t}\n    }\n\n  buffer->writenl ();\n\n  /* Write out all phony targets.  */\n  for (size_t i = 0; i < phonylist.dim; i++)\n    {\n      Module *m = phonylist[i];\n\n      buffer->writenl ();\n      buffer->writestring (m->srcfile->name.toChars ());\n      buffer->writestring (\":\\n\");\n    }\n}\n\n/* These functions are defined in D runtime.  */\nextern \"C\" int rt_init (void);\nextern \"C\" void gc_disable (void);\n\n/* Implements the lang_hooks.init_options routine for language D.\n   This initializes the global state for the D frontend before calling\n   the option handlers.  */\n\nstatic void\nd_init_options (unsigned int, cl_decoded_option *decoded_options)\n{\n  /* Initialize the D runtime.  */\n  rt_init ();\n  gc_disable ();\n\n  /* Set default values.  */\n  global._init ();\n\n  global.vendor = lang_hooks.name;\n  global.params.argv0.ptr = xstrdup (decoded_options[0].arg);\n  global.params.argv0.length = strlen (decoded_options[0].arg);\n  global.params.errorLimit = flag_max_errors;\n\n  /* Warnings and deprecations are disabled by default.  */\n  global.params.useDeprecated = DIAGNOSTICoff;\n  global.params.warnings = DIAGNOSTICoff;\n\n  global.params.imppath = new Strings ();\n  global.params.fileImppath = new Strings ();\n  global.params.modFileAliasStrings = new Strings ();\n\n  /* Extra GDC-specific options.  */\n  d_option.fonly = NULL;\n  d_option.multilib = NULL;\n  d_option.prefix = NULL;\n  d_option.deps = false;\n  d_option.deps_skip_system = false;\n  d_option.deps_filename = NULL;\n  d_option.deps_filename_user = NULL;\n  d_option.deps_target = NULL;\n  d_option.deps_phony = false;\n  d_option.stdinc = true;\n}\n\n/* Implements the lang_hooks.init_options_struct routine for language D.\n   Initializes the options structure OPTS.  */\n\nstatic void\nd_init_options_struct (gcc_options *opts)\n{\n  /* GCC options.  */\n  opts->x_flag_exceptions = 1;\n\n  /* Avoid range issues for complex multiply and divide.  */\n  opts->x_flag_complex_method = 2;\n\n  /* Unlike C, there is no global 'errno' variable.  */\n  opts->x_flag_errno_math = 0;\n  opts->frontend_set_flag_errno_math = true;\n\n  /* Keep in sync with existing -fbounds-check flag.  */\n  opts->x_flag_bounds_check = (global.params.useArrayBounds == CHECKENABLEon);\n\n  /* D says that signed overflow is precisely defined.  */\n  opts->x_flag_wrapv = 1;\n}\n\n/* Implements the lang_hooks.lang_mask routine for language D.\n   Returns language mask for option parsing.  */\n\nstatic unsigned int\nd_option_lang_mask (void)\n{\n  return CL_D;\n}\n\n/* Implements the lang_hooks.init routine for language D.  */\n\nstatic bool\nd_init (void)\n{\n  Type::_init ();\n  Id::initialize ();\n  Module::_init ();\n  Expression::_init ();\n  Objc::_init ();\n\n  /* Back-end init.  */\n  global_binding_level = ggc_cleared_alloc<binding_level> ();\n  current_binding_level = global_binding_level;\n\n  /* This allows the code in d-builtins.cc to not have to worry about\n     converting (C signed char *) to (D char *) for string arguments of\n     built-in functions.  The parameter (signed_char = false) specifies\n     whether char is signed.  */\n  build_common_tree_nodes (false);\n\n  d_init_builtins ();\n\n  if (global.params.useExceptions)\n    using_eh_for_cleanups ();\n\n  if (!supports_one_only ())\n    flag_weak = 0;\n\n  /* This is the C main, not the D main.  */\n  main_identifier_node = get_identifier (\"main\");\n\n  Target::_init ();\n  d_init_versions ();\n\n  /* Insert all library-configured identifiers and import paths.  */\n  add_import_paths (d_option.prefix, d_option.multilib, d_option.stdinc);\n\n  return 1;\n}\n\n/* Implements the lang_hooks.init_ts routine for language D.  */\n\nstatic void\nd_init_ts (void)\n{\n  MARK_TS_TYPED (FLOAT_MOD_EXPR);\n  MARK_TS_TYPED (UNSIGNED_RSHIFT_EXPR);\n}\n\n/* Implements the lang_hooks.handle_option routine for language D.\n   Handles D specific options.  Return false if we didn't do anything.  */\n\nstatic bool\nd_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,\n\t\t int kind ATTRIBUTE_UNUSED,\n\t\t location_t loc ATTRIBUTE_UNUSED,\n\t\t const cl_option_handlers *handlers ATTRIBUTE_UNUSED)\n{\n  opt_code code = (opt_code) scode;\n  bool result = true;\n\n  switch (code)\n    {\n    case OPT_fall_instantiations:\n      global.params.allInst = value;\n      break;\n\n    case OPT_fassert:\n      global.params.useAssert = value\n\t? CHECKENABLEon : CHECKENABLEoff;\n      break;\n\n    case OPT_fbounds_check:\n      global.params.useArrayBounds = value\n\t? CHECKENABLEon : CHECKENABLEoff;\n      break;\n\n    case OPT_fbounds_check_:\n      global.params.useArrayBounds = (value == 2) ? CHECKENABLEon\n\t: (value == 1) ? CHECKENABLEsafeonly : CHECKENABLEoff;\n      break;\n\n    case OPT_fdebug:\n      global.params.debuglevel = value ? 1 : 0;\n      break;\n\n    case OPT_fdebug_:\n      if (ISDIGIT (arg[0]))\n\t{\n\t  int level = integral_argument (arg);\n\t  if (level != -1)\n\t    {\n\t      global.params.debuglevel = level;\n\t      break;\n\t    }\n\t}\n\n      if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))\n\t{\n\t  if (!global.params.debugids)\n\t    global.params.debugids = new Strings ();\n\t  global.params.debugids->push (arg);\n\t  break;\n\t}\n\n      error (\"bad argument for -fdebug %qs\", arg);\n      break;\n\n    case OPT_fdoc:\n      global.params.doDocComments = value;\n      break;\n\n    case OPT_fdoc_dir_:\n      global.params.doDocComments = true;\n      global.params.docdir = arg;\n      break;\n\n    case OPT_fdoc_file_:\n      global.params.doDocComments = true;\n      global.params.docname = arg;\n      break;\n\n    case OPT_fdoc_inc_:\n      global.params.ddocfiles.push (arg);\n      break;\n\n    case OPT_fdruntime:\n      global.params.betterC = !value;\n      break;\n\n    case OPT_fdump_d_original:\n      global.params.vcg_ast = value;\n      break;\n\n    case OPT_fexceptions:\n      global.params.useExceptions = value;\n      break;\n\n    case OPT_fignore_unknown_pragmas:\n      global.params.ignoreUnsupportedPragmas = value;\n      break;\n\n    case OPT_finvariants:\n      global.params.useInvariants = value;\n      break;\n\n    case OPT_fmain:\n      global.params.addMain = value;\n      break;\n\n    case OPT_fmodule_file_:\n      global.params.modFileAliasStrings->push (arg);\n      if (!strchr (arg, '='))\n\terror (\"bad argument for -fmodule-file %qs\", arg);\n      break;\n\n    case OPT_fmoduleinfo:\n      global.params.useModuleInfo = value;\n      break;\n\n    case OPT_fonly_:\n      d_option.fonly = arg;\n      break;\n\n    case OPT_fpostconditions:\n      global.params.useOut = value;\n      break;\n\n    case OPT_fpreconditions:\n      global.params.useIn = value;\n      break;\n\n    case OPT_frelease:\n      global.params.release = value;\n      break;\n\n    case OPT_frtti:\n      global.params.useTypeInfo = value;\n      break;\n\n    case OPT_fswitch_errors:\n      global.params.useSwitchError = value\n\t? CHECKENABLEon : CHECKENABLEoff;\n      break;\n\n    case OPT_ftransition_all:\n      global.params.vtls = value;\n      global.params.vfield = value;\n      global.params.vcomplex = value;\n      break;\n\n    case OPT_ftransition_checkimports:\n      global.params.check10378 = value;\n      break;\n\n    case OPT_ftransition_complex:\n      global.params.vcomplex = value;\n      break;\n\n    case OPT_ftransition_dip1000:\n      global.params.vsafe = value;\n      global.params.useDIP25 = value;\n      break;\n\n    case OPT_ftransition_dip1008:\n      global.params.ehnogc = value;\n      break;\n\n    case OPT_ftransition_dip25:\n      global.params.useDIP25 = value;\n      break;\n\n    case OPT_ftransition_dtorfields:\n      global.params.dtorFields = value;\n      break;\n\n    case OPT_ftransition_field:\n      global.params.vfield = value;\n      break;\n\n    case OPT_ftransition_import:\n      global.params.bug10378 = value;\n      break;\n\n    case OPT_ftransition_intpromote:\n      global.params.fix16997 = value;\n      break;\n\n    case OPT_ftransition_nogc:\n      global.params.vgc = value;\n      break;\n\n    case OPT_ftransition_tls:\n      global.params.vtls = value;\n      break;\n\n    case OPT_funittest:\n      global.params.useUnitTests = value;\n      break;\n\n    case OPT_fversion_:\n      if (ISDIGIT (arg[0]))\n\t{\n\t  int level = integral_argument (arg);\n\t  if (level != -1)\n\t    {\n\t      global.params.versionlevel = level;\n\t      break;\n\t    }\n\t}\n\n      if (Identifier::isValidIdentifier (CONST_CAST (char *, arg)))\n\t{\n\t  if (!global.params.versionids)\n\t    global.params.versionids = new Strings ();\n\t  global.params.versionids->push (arg);\n\t  break;\n\t}\n\n      error (\"bad argument for -fversion %qs\", arg);\n      break;\n\n    case OPT_H:\n      global.params.doHdrGeneration = true;\n      break;\n\n    case OPT_Hd:\n      global.params.doHdrGeneration = true;\n      global.params.hdrdir = arg;\n      break;\n\n    case OPT_Hf:\n      global.params.doHdrGeneration = true;\n      global.params.hdrname = arg;\n      break;\n\n    case OPT_imultilib:\n      d_option.multilib = arg;\n      break;\n\n    case OPT_iprefix:\n      d_option.prefix = arg;\n      break;\n\n    case OPT_I:\n      global.params.imppath->push (arg);\n      break;\n\n    case OPT_J:\n      global.params.fileImppath->push (arg);\n      break;\n\n    case OPT_MM:\n      d_option.deps_skip_system = true;\n      /* Fall through.  */\n\n    case OPT_M:\n      d_option.deps = true;\n      break;\n\n    case OPT_MMD:\n      d_option.deps_skip_system = true;\n      /* Fall through.  */\n\n    case OPT_MD:\n      d_option.deps = true;\n      d_option.deps_filename = arg;\n      break;\n\n    case OPT_MF:\n      /* If specified multiple times, last one wins.  */\n      d_option.deps_filename_user = arg;\n      break;\n\n    case OPT_MP:\n      d_option.deps_phony = true;\n      break;\n\n    case OPT_MQ:\n      deps_add_target (arg, true);\n      break;\n\n    case OPT_MT:\n      deps_add_target (arg, false);\n      break;\n\n    case OPT_nostdinc:\n      d_option.stdinc = false;\n      break;\n\n    case OPT_v:\n      global.params.verbose = value;\n      break;\n\n    case OPT_Wall:\n      if (value)\n\tglobal.params.warnings = DIAGNOSTICinform;\n      break;\n\n    case OPT_Wdeprecated:\n      global.params.useDeprecated = value ? DIAGNOSTICinform : DIAGNOSTICoff;\n      break;\n\n    case OPT_Werror:\n      if (value)\n\tglobal.params.warnings = DIAGNOSTICerror;\n      break;\n\n    case OPT_Wspeculative:\n      if (value)\n\tglobal.params.showGaggedErrors = 1;\n      break;\n\n    case OPT_Xf:\n      global.params.jsonfilename = arg;\n      /* Fall through.  */\n\n    case OPT_X:\n      global.params.doJsonGeneration = true;\n      break;\n\n    default:\n      break;\n    }\n\n  D_handle_option_auto (&global_options, &global_options_set,\n\t\t\tscode, arg, value,\n\t\t\td_option_lang_mask (), kind,\n\t\t\tloc, handlers, global_dc);\n\n  return result;\n}\n\n/* Implements the lang_hooks.post_options routine for language D.\n   Deal with any options that imply the turning on/off of features.\n   FN is the main input filename passed on the command line.  */\n\nstatic bool\nd_post_options (const char ** fn)\n{\n  /* Verify the input file name.  */\n  const char *filename = *fn;\n  if (!filename || strcmp (filename, \"-\") == 0)\n    filename = \"\";\n\n  /* The front end considers the first input file to be the main one.  */\n  *fn = filename;\n\n  /* Release mode doesn't turn off bounds checking for safe functions.  */\n  if (global.params.useArrayBounds == CHECKENABLEdefault)\n    {\n      global.params.useArrayBounds = global.params.release\n\t? CHECKENABLEsafeonly : CHECKENABLEon;\n      flag_bounds_check = !global.params.release;\n    }\n\n  /* Assert code is generated if unittests are being compiled also, even if\n     release mode is turned on.  */\n  if (global.params.useAssert == CHECKENABLEdefault)\n    {\n      if (global.params.useUnitTests || !global.params.release)\n\tglobal.params.useAssert = CHECKENABLEon;\n      else\n\tglobal.params.useAssert = CHECKENABLEoff;\n    }\n\n  /* Checks for switches without a default are turned off in release mode.  */\n  if (global.params.useSwitchError == CHECKENABLEdefault)\n    {\n      global.params.useSwitchError = global.params.release\n\t? CHECKENABLEoff : CHECKENABLEon;\n    }\n\n  if (global.params.release)\n    {\n      if (!global_options_set.x_flag_invariants)\n\tglobal.params.useInvariants = false;\n\n      if (!global_options_set.x_flag_preconditions)\n\tglobal.params.useIn = false;\n\n      if (!global_options_set.x_flag_postconditions)\n\tglobal.params.useOut = false;\n    }\n\n  if (global.params.betterC)\n    {\n      if (!global_options_set.x_flag_moduleinfo)\n\tglobal.params.useModuleInfo = false;\n\n      if (!global_options_set.x_flag_rtti)\n\tglobal.params.useTypeInfo = false;\n\n      if (!global_options_set.x_flag_exceptions)\n\tglobal.params.useExceptions = false;\n\n      global.params.checkAction = CHECKACTION_C;\n    }\n\n  /* Error about use of deprecated features.  */\n  if (global.params.useDeprecated == DIAGNOSTICinform\n      && global.params.warnings == DIAGNOSTICerror)\n    global.params.useDeprecated = DIAGNOSTICerror;\n\n  /* Make -fmax-errors visible to frontend's diagnostic machinery.  */\n  if (global_options_set.x_flag_max_errors)\n    global.params.errorLimit = flag_max_errors;\n\n  if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT)\n    flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD;\n\n  global.params.symdebug = write_symbols != NO_DEBUG;\n  global.params.useInline = flag_inline_functions;\n  global.params.showColumns = flag_show_column;\n\n  if (global.params.useInline)\n    global.params.hdrStripPlainFunctions = false;\n\n  global.params.obj = !flag_syntax_only;\n\n  /* Has no effect yet.  */\n  global.params.pic = flag_pic != 0;\n\n  /* Add in versions given on the command line.  */\n  if (global.params.versionids)\n    {\n      for (size_t i = 0; i < global.params.versionids->dim; i++)\n\t{\n\t  const char *s = (*global.params.versionids)[i];\n\t  VersionCondition::addGlobalIdent (s);\n\t}\n    }\n\n  if (global.params.debugids)\n    {\n      for (size_t i = 0; i < global.params.debugids->dim; i++)\n\t{\n\t  const char *s = (*global.params.debugids)[i];\n\t  DebugCondition::addGlobalIdent (s);\n\t}\n    }\n\n  if (warn_return_type == -1)\n    warn_return_type = 0;\n\n  return false;\n}\n\n/* Return TRUE if an operand OP of a given TYPE being copied has no data.\n   The middle-end does a similar check with zero sized types.  */\n\nstatic bool\nempty_modify_p (tree type, tree op)\n{\n  tree_code code = TREE_CODE (op);\n  switch (code)\n    {\n    case COMPOUND_EXPR:\n      return empty_modify_p (type, TREE_OPERAND (op, 1));\n\n    case CONSTRUCTOR:\n      /* Non-empty construcors are valid.  */\n      if (CONSTRUCTOR_NELTS (op) != 0 || TREE_CLOBBER_P (op))\n\treturn false;\n      break;\n\n    case CALL_EXPR:\n      /* Leave nrvo alone because it isn't a copy.  */\n      if (CALL_EXPR_RETURN_SLOT_OPT (op))\n\treturn false;\n      break;\n\n    default:\n      /* If the operand doesn't have a simple form.  */\n      if (!is_gimple_lvalue (op) && !INDIRECT_REF_P (op))\n\treturn false;\n      break;\n    }\n\n  return empty_aggregate_p (type);\n}\n\n/* Implements the lang_hooks.gimplify_expr routine for language D.\n   Do gimplification of D specific expression trees in EXPR_P.  */\n\nint\nd_gimplify_expr (tree *expr_p, gimple_seq *pre_p,\n\t\t gimple_seq *post_p ATTRIBUTE_UNUSED)\n{\n  tree_code code = TREE_CODE (*expr_p);\n  enum gimplify_status ret = GS_UNHANDLED;\n  tree op0, op1;\n  tree type;\n\n  switch (code)\n    {\n    case INIT_EXPR:\n    case MODIFY_EXPR:\n      op0 = TREE_OPERAND (*expr_p, 0);\n      op1 = TREE_OPERAND (*expr_p, 1);\n\n      if (!error_operand_p (op0) && !error_operand_p (op1)\n\t  && (AGGREGATE_TYPE_P (TREE_TYPE (op0))\n\t      || AGGREGATE_TYPE_P (TREE_TYPE (op1)))\n\t  && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))\n\t{\n\t  /* If the back end isn't clever enough to know that the lhs and rhs\n\t     types are the same, add an explicit conversion.  */\n\t  TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,\n\t\t\t\t\t      TREE_TYPE (op0), op1);\n\t  ret = GS_OK;\n\t}\n      else if (empty_modify_p (TREE_TYPE (op0), op1))\n\t{\n\t  /* Remove any copies of empty aggregates.  */\n\t  gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,\n\t\t\t is_gimple_lvalue, fb_lvalue);\n\n\t  if (TREE_SIDE_EFFECTS (op1))\n\t    gimplify_and_add (op1, pre_p);\n\n\t  *expr_p = TREE_OPERAND (*expr_p, 0);\n\t  ret = GS_OK;\n\t}\n      break;\n\n    case ADDR_EXPR:\n      op0 = TREE_OPERAND (*expr_p, 0);\n      /* Constructors are not lvalues, so make them one.  */\n      if (TREE_CODE (op0) == CONSTRUCTOR)\n\t{\n\t  TREE_OPERAND (*expr_p, 0) = force_target_expr (op0);\n\t  ret = GS_OK;\n\t}\n      break;\n\n    case CALL_EXPR:\n      if (CALL_EXPR_ARGS_ORDERED (*expr_p))\n\t{\n\t  /* Strictly evaluate all arguments from left to right.  */\n\t  int nargs = call_expr_nargs (*expr_p);\n\t  location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);\n\n\t  /* No need to enforce evaluation order if only one argument.  */\n\t  if (nargs < 2)\n\t    break;\n\n\t  /* Or if all arguments are already free of side-effects.  */\n\t  bool has_side_effects = false;\n\t  for (int i = 0; i < nargs; i++)\n\t    {\n\t      if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))\n\t\t{\n\t\t  has_side_effects = true;\n\t\t  break;\n\t\t}\n\t    }\n\n\t  if (!has_side_effects)\n\t    break;\n\n\t  /* Leave the last argument for gimplify_call_expr.  */\n\t  for (int i = 0; i < nargs - 1; i++)\n\t    {\n\t      tree new_arg = CALL_EXPR_ARG (*expr_p, i);\n\n\t      /* If argument has a side-effect, gimplify_arg will handle it.  */\n\t      if (gimplify_arg (&new_arg, pre_p, loc) == GS_ERROR)\n\t\tret = GS_ERROR;\n\n\t      /* Even if an argument itself doesn't have any side-effects, it\n\t\t might be altered by another argument in the list.  */\n\t      if (new_arg == CALL_EXPR_ARG (*expr_p, i)\n\t\t  && !really_constant_p (new_arg))\n\t\tnew_arg = get_formal_tmp_var (new_arg, pre_p);\n\n\t      CALL_EXPR_ARG (*expr_p, i) = new_arg;\n\t    }\n\n\t  if (ret != GS_ERROR)\n\t    ret = GS_OK;\n\t}\n      break;\n\n    case UNSIGNED_RSHIFT_EXPR:\n      /* Convert op0 to an unsigned type.  */\n      op0 = TREE_OPERAND (*expr_p, 0);\n      op1 = TREE_OPERAND (*expr_p, 1);\n\n      type = d_unsigned_type (TREE_TYPE (op0));\n\n      *expr_p = convert (TREE_TYPE (*expr_p),\n\t\t\t build2 (RSHIFT_EXPR, type, convert (type, op0), op1));\n      ret = GS_OK;\n      break;\n\n    case FLOAT_MOD_EXPR:\n      gcc_unreachable ();\n\n    default:\n      break;\n    }\n\n  return ret;\n}\n\n/* Add the module M to the list of modules that may declare GCC builtins.\n   These are scanned after first semantic and before codegen passes.\n   See d_maybe_set_builtin() for the implementation.  */\n\nvoid\nd_add_builtin_module (Module *m)\n{\n  builtin_modules.push (m);\n}\n\n/* Record the entrypoint module ENTRY which will be compiled in the current\n   compilation.  ROOT is the module scope where this was requested from.  */\n\nvoid\nd_add_entrypoint_module (Module *entry, Module *root)\n{\n  /* We are emitting this straight to object file.  */\n  entrypoint_module = entry;\n  entrypoint_root_module = root;\n}\n\n/* Implements the lang_hooks.parse_file routine for language D.  */\n\nvoid\nd_parse_file (void)\n{\n  if (global.params.verbose)\n    {\n      message (\"binary    %s\", global.params.argv0.ptr);\n      message (\"version   %s\", global.version);\n\n      if (global.versionids)\n\t{\n\t  OutBuffer buf;\n\t  buf.writestring (\"predefs  \");\n\t  for (size_t i = 0; i < global.versionids->dim; i++)\n\t    {\n\t      Identifier *id = (*global.versionids)[i];\n\t      buf.writestring (\" \");\n\t      buf.writestring (id->toChars ());\n\t    }\n\n\t  message (\"%.*s\", (int) buf.offset, (char *) buf.data);\n\t}\n    }\n\n  /* Start the main input file, if the debug writer wants it.  */\n  if (debug_hooks->start_end_main_source_file)\n    debug_hooks->start_source_file (0, main_input_filename);\n\n  /* Create Module's for all sources we will load.  */\n  Modules modules;\n  modules.reserve (num_in_fnames);\n\n  /* In this mode, the first file name is supposed to be a duplicate\n     of one of the input files.  */\n  if (d_option.fonly && strcmp (d_option.fonly, main_input_filename) != 0)\n    error (\"-fonly= argument is different from first input file name\");\n\n  for (size_t i = 0; i < num_in_fnames; i++)\n    {\n      if (strcmp (in_fnames[i], \"-\") == 0)\n\t{\n\t  /* Handling stdin, generate a unique name for the module.  */\n\t  obstack buffer;\n\t  gcc_obstack_init (&buffer);\n\t  int c;\n\n\t  Module *m = Module::create (in_fnames[i],\n\t\t\t\t      Identifier::generateId (\"__stdin\"),\n\t\t\t\t      global.params.doDocComments,\n\t\t\t\t      global.params.doHdrGeneration);\n\t  modules.push (m);\n\n\t  /* Load the entire contents of stdin into memory.  */\n\t  while ((c = getc (stdin)) != EOF)\n\t    obstack_1grow (&buffer, c);\n\n\t  if (!obstack_object_size (&buffer))\n\t    obstack_1grow (&buffer, '\\0');\n\n\t  /* Overwrite the source file for the module, the one created by\n\t     Module::create would have a forced a `.d' suffix.  */\n\t  m->srcfile = File::create (\"<stdin>\");\n\t  m->srcfile->len = obstack_object_size (&buffer);\n\t  m->srcfile->buffer = (unsigned char *) obstack_finish (&buffer);\n\n\t  /* Tell the front-end not to free the buffer after parsing.  */\n\t  m->srcfile->ref = 1;\n\t}\n      else\n\t{\n\t  /* Handling a D source file, strip off the path and extension.  */\n\t  const char *basename = FileName::name (in_fnames[i]);\n\t  const char *name = FileName::removeExt (basename);\n\n\t  Module *m = Module::create (in_fnames[i], Identifier::idPool (name),\n\t\t\t\t      global.params.doDocComments,\n\t\t\t\t      global.params.doHdrGeneration);\n\t  modules.push (m);\n\t  FileName::free (name);\n\t}\n    }\n\n  /* Read all D source files.  */\n  for (size_t i = 0; i < modules.dim; i++)\n    {\n      Module *m = modules[i];\n      m->read (Loc ());\n    }\n\n  /* Parse all D source files.  */\n  for (size_t i = 0; i < modules.dim; i++)\n    {\n      Module *m = modules[i];\n\n      if (global.params.verbose)\n\tmessage (\"parse     %s\", m->toChars ());\n\n      if (!Module::rootModule)\n\tModule::rootModule = m;\n\n      m->importedFrom = m;\n      m->parse ();\n      Compiler::loadModule (m);\n\n      if (m->isDocFile)\n\t{\n\t  gendocfile (m);\n\t  /* Remove M from list of modules.  */\n\t  modules.remove (i);\n\t  i--;\n\t}\n    }\n\n  /* Load the module containing D main.  */\n  if (global.params.addMain)\n    {\n      unsigned errors = global.startGagging ();\n      Module *m = Module::load (Loc (), NULL, Identifier::idPool (\"__main\"));\n\n      if (! global.endGagging (errors))\n\t{\n\t  m->importedFrom = m;\n\t  modules.push (m);\n\t}\n    }\n\n  if (global.errors)\n    goto had_errors;\n\n  if (global.params.doHdrGeneration)\n    {\n      /* Generate 'header' import files.  Since 'header' import files must be\n\t independent of command line switches and what else is imported, they\n\t are generated before any semantic analysis.  */\n      for (size_t i = 0; i < modules.dim; i++)\n\t{\n\t  Module *m = modules[i];\n\t  if (d_option.fonly && m != Module::rootModule)\n\t    continue;\n\n\t  if (global.params.verbose)\n\t    message (\"import    %s\", m->toChars ());\n\n\t  genhdrfile (m);\n\t}\n    }\n\n  if (global.errors)\n    goto had_errors;\n\n  /* Load all unconditional imports for better symbol resolving.  */\n  for (size_t i = 0; i < modules.dim; i++)\n    {\n      Module *m = modules[i];\n\n      if (global.params.verbose)\n\tmessage (\"importall %s\", m->toChars ());\n\n      m->importAll (NULL);\n    }\n\n  if (global.errors)\n    goto had_errors;\n\n  /* Do semantic analysis.  */\n  doing_semantic_analysis_p = true;\n\n  for (size_t i = 0; i < modules.dim; i++)\n    {\n      Module *m = modules[i];\n\n      if (global.params.verbose)\n\tmessage (\"semantic  %s\", m->toChars ());\n\n      dsymbolSemantic (m, NULL);\n    }\n\n  /* Do deferred semantic analysis.  */\n  Module::dprogress = 1;\n  Module::runDeferredSemantic ();\n\n  if (Module::deferred.dim)\n    {\n      for (size_t i = 0; i < Module::deferred.dim; i++)\n\t{\n\t  Dsymbol *sd = Module::deferred[i];\n\t  error_at (make_location_t (sd->loc),\n\t\t    \"unable to resolve forward reference in definition\");\n\t}\n    }\n\n  /* Process all built-in modules or functions now for CTFE.  */\n  while (builtin_modules.dim != 0)\n    {\n      Module *m = builtin_modules.pop ();\n      d_maybe_set_builtin (m);\n    }\n\n  /* Do pass 2 semantic analysis.  */\n  for (size_t i = 0; i < modules.dim; i++)\n    {\n      Module *m = modules[i];\n\n      if (global.params.verbose)\n\tmessage (\"semantic2 %s\", m->toChars ());\n\n      semantic2 (m, NULL);\n    }\n\n  Module::runDeferredSemantic2 ();\n\n  if (global.errors)\n    goto had_errors;\n\n  /* Do pass 3 semantic analysis.  */\n  for (size_t i = 0; i < modules.dim; i++)\n    {\n      Module *m = modules[i];\n\n      if (global.params.verbose)\n\tmessage (\"semantic3 %s\", m->toChars ());\n\n      semantic3 (m, NULL);\n    }\n\n  Module::runDeferredSemantic3 ();\n\n  /* Check again, incase semantic3 pass loaded any more modules.  */\n  while (builtin_modules.dim != 0)\n    {\n      Module *m = builtin_modules.pop ();\n      d_maybe_set_builtin (m);\n    }\n\n  /* Do not attempt to generate output files if errors or warnings occurred.  */\n  if (global.errors || global.warnings)\n    goto had_errors;\n\n  /* Generate output files.  */\n  doing_semantic_analysis_p = false;\n\n  if (Module::rootModule)\n    {\n      /* Declare the name of the root module as the first global name in order\n\t to make the middle-end fully deterministic.  */\n      OutBuffer buf;\n      mangleToBuffer (Module::rootModule, &buf);\n      first_global_object_name = buf.extractString ();\n    }\n\n  /* Make dependencies.  */\n  if (d_option.deps)\n    {\n      OutBuffer buf;\n\n      for (size_t i = 0; i < modules.dim; i++)\n\tdeps_write (modules[i], &buf);\n\n      /* -MF <arg> overrides -M[M]D.  */\n      if (d_option.deps_filename_user)\n\td_option.deps_filename = d_option.deps_filename_user;\n\n      if (d_option.deps_filename)\n\t{\n\t  File *fdeps = File::create (d_option.deps_filename);\n\t  fdeps->setbuffer ((void *) buf.data, buf.offset);\n\t  fdeps->ref = 1;\n\t  writeFile (Loc (), fdeps);\n\t}\n      else\n\tmessage (\"%.*s\", (int) buf.offset, (char *) buf.data);\n    }\n\n  /* Generate JSON files.  */\n  if (global.params.doJsonGeneration)\n    {\n      OutBuffer buf;\n      json_generate (&buf, &modules);\n\n      const char *name = global.params.jsonfilename;\n\n      if (name && (name[0] != '-' || name[1] != '\\0'))\n\t{\n\t  const char *nameext = FileName::defaultExt (name, global.json_ext);\n\t  File *fjson = File::create (nameext);\n\t  fjson->setbuffer ((void *) buf.data, buf.offset);\n\t  fjson->ref = 1;\n\t  writeFile (Loc (), fjson);\n\t}\n      else\n\tmessage (\"%.*s\", (int) buf.offset, (char *) buf.data);\n    }\n\n  /* Generate Ddoc files.  */\n  if (global.params.doDocComments && !global.errors && !errorcount)\n    {\n      for (size_t i = 0; i < modules.dim; i++)\n\t{\n\t  Module *m = modules[i];\n\t  gendocfile (m);\n\t}\n    }\n\n  /* Handle -fdump-d-original.  */\n  if (global.params.vcg_ast)\n    {\n      for (size_t i = 0; i < modules.dim; i++)\n\t{\n\t  Module *m = modules[i];\n\t  OutBuffer buf;\n\t  buf.doindent = 1;\n\n\t  moduleToBuffer (&buf, m);\n\t  message (\"%.*s\", (int) buf.offset, (char *) buf.data);\n\t}\n    }\n\n  for (size_t i = 0; i < modules.dim; i++)\n    {\n      Module *m = modules[i];\n      if (d_option.fonly && m != Module::rootModule)\n\tcontinue;\n\n      if (global.params.verbose)\n\tmessage (\"code      %s\", m->toChars ());\n\n      if (!flag_syntax_only)\n\t{\n\t  if ((entrypoint_module != NULL) && (m == entrypoint_root_module))\n\t    build_decl_tree (entrypoint_module);\n\n\t  build_decl_tree (m);\n\t}\n    }\n\n  /* And end the main input file, if the debug writer wants it.  */\n  if (debug_hooks->start_end_main_source_file)\n    debug_hooks->end_source_file (0);\n\n had_errors:\n  /* Add the D frontend error count to the GCC error count to correctly\n     exit with an error status.  */\n  errorcount += (global.errors + global.warnings);\n\n  /* Write out globals.  */\n  d_finish_compilation (vec_safe_address (global_declarations),\n\t\t\tvec_safe_length (global_declarations));\n}\n\n/* Implements the lang_hooks.types.type_for_mode routine for language D.  */\n\nstatic tree\nd_type_for_mode (machine_mode mode, int unsignedp)\n{\n  if (mode == QImode)\n    return unsignedp ? d_ubyte_type : d_byte_type;\n\n  if (mode == HImode)\n    return unsignedp ? d_ushort_type : d_short_type;\n\n  if (mode == SImode)\n    return unsignedp ? d_uint_type : d_int_type;\n\n  if (mode == DImode)\n    return unsignedp ? d_ulong_type : d_long_type;\n\n  if (mode == TYPE_MODE (d_cent_type))\n    return unsignedp ? d_ucent_type : d_cent_type;\n\n  if (mode == TYPE_MODE (float_type_node))\n    return float_type_node;\n\n  if (mode == TYPE_MODE (double_type_node))\n    return double_type_node;\n\n  if (mode == TYPE_MODE (long_double_type_node))\n    return long_double_type_node;\n\n  if (mode == TYPE_MODE (build_pointer_type (char8_type_node)))\n    return build_pointer_type (char8_type_node);\n\n  if (mode == TYPE_MODE (build_pointer_type (d_int_type)))\n    return build_pointer_type (d_int_type);\n\n  if (COMPLEX_MODE_P (mode))\n    {\n      machine_mode inner_mode;\n      tree inner_type;\n\n      if (mode == TYPE_MODE (complex_float_type_node))\n\treturn complex_float_type_node;\n      if (mode == TYPE_MODE (complex_double_type_node))\n\treturn complex_double_type_node;\n      if (mode == TYPE_MODE (complex_long_double_type_node))\n\treturn complex_long_double_type_node;\n\n      inner_mode = (machine_mode) GET_MODE_INNER (mode);\n      inner_type = d_type_for_mode (inner_mode, unsignedp);\n      if (inner_type != NULL_TREE)\n\treturn build_complex_type (inner_type);\n    }\n  else if (VECTOR_MODE_P (mode))\n    {\n      machine_mode inner_mode = (machine_mode) GET_MODE_INNER (mode);\n      tree inner_type = d_type_for_mode (inner_mode, unsignedp);\n      if (inner_type != NULL_TREE)\n\treturn build_vector_type_for_mode (inner_type, mode);\n    }\n\n  return 0;\n}\n\n/* Implements the lang_hooks.types.type_for_size routine for language D.  */\n\nstatic tree\nd_type_for_size (unsigned bits, int unsignedp)\n{\n  if (bits <= TYPE_PRECISION (d_byte_type))\n    return unsignedp ? d_ubyte_type : d_byte_type;\n\n  if (bits <= TYPE_PRECISION (d_short_type))\n    return unsignedp ? d_ushort_type : d_short_type;\n\n  if (bits <= TYPE_PRECISION (d_int_type))\n    return unsignedp ? d_uint_type : d_int_type;\n\n  if (bits <= TYPE_PRECISION (d_long_type))\n    return unsignedp ? d_ulong_type : d_long_type;\n\n  if (bits <= TYPE_PRECISION (d_cent_type))\n    return unsignedp ? d_ucent_type : d_cent_type;\n\n  return 0;\n}\n\n/* Return the signed or unsigned version of TYPE, an integral type, the\n   signedness being specified by UNSIGNEDP.  */\n\nstatic tree\nd_signed_or_unsigned_type (int unsignedp, tree type)\n{\n  if (TYPE_UNSIGNED (type) == (unsigned) unsignedp)\n    return type;\n\n  if (TYPE_PRECISION (type) == TYPE_PRECISION (d_cent_type))\n    return unsignedp ? d_ucent_type : d_cent_type;\n\n  if (TYPE_PRECISION (type) == TYPE_PRECISION (d_long_type))\n    return unsignedp ? d_ulong_type : d_long_type;\n\n  if (TYPE_PRECISION (type) == TYPE_PRECISION (d_int_type))\n    return unsignedp ? d_uint_type : d_int_type;\n\n  if (TYPE_PRECISION (type) == TYPE_PRECISION (d_short_type))\n    return unsignedp ? d_ushort_type : d_short_type;\n\n  if (TYPE_PRECISION (type) == TYPE_PRECISION (d_byte_type))\n    return unsignedp ? d_ubyte_type : d_byte_type;\n\n  return signed_or_unsigned_type_for (unsignedp, type);\n}\n\n/* Return the unsigned version of TYPE, an integral type.  */\n\ntree\nd_unsigned_type (tree type)\n{\n  return d_signed_or_unsigned_type (1, type);\n}\n\n/* Return the signed version of TYPE, an integral type.  */\n\ntree\nd_signed_type (tree type)\n{\n  return d_signed_or_unsigned_type (0, type);\n}\n\n/* Implements the lang_hooks.types.type_promotes_to routine for language D.\n   All promotions for variable arguments are handled by the D frontend.  */\n\nstatic tree\nd_type_promotes_to (tree type)\n{\n  return type;\n}\n\n/* Implements the lang_hooks.decls.global_bindings_p routine for language D.\n   Return true if we are in the global binding level.  */\n\nstatic bool\nd_global_bindings_p (void)\n{\n  return (current_binding_level == global_binding_level);\n}\n\n/* Return global_context, but create it first if need be.  */\n\nstatic tree\nget_global_context (void)\n{\n  if (!global_context)\n    {\n      global_context = build_translation_unit_decl (NULL_TREE);\n      debug_hooks->register_main_translation_unit (global_context);\n    }\n\n  return global_context;\n}\n\n/* Implements the lang_hooks.decls.pushdecl routine for language D.\n   Record DECL as belonging to the current lexical scope.  */\n\ntree\nd_pushdecl (tree decl)\n{\n  /* Set the context of the decl.  If current_function_decl did not help in\n     determining the context, use global scope.  */\n  if (!DECL_CONTEXT (decl))\n    {\n      if (current_function_decl)\n\tDECL_CONTEXT (decl) = current_function_decl;\n      else\n\tDECL_CONTEXT (decl) = get_global_context ();\n    }\n\n  /* Put decls on list in reverse order.  */\n  if (TREE_STATIC (decl) || d_global_bindings_p ())\n    vec_safe_push (global_declarations, decl);\n  else\n    {\n      TREE_CHAIN (decl) = current_binding_level->names;\n      current_binding_level->names = decl;\n    }\n\n  return decl;\n}\n\n/* Implements the lang_hooks.decls.getdecls routine for language D.\n   Return the list of declarations of the current level.  */\n\nstatic tree\nd_getdecls (void)\n{\n  if (current_binding_level)\n    return current_binding_level->names;\n\n  return NULL_TREE;\n}\n\n\n/* Implements the lang_hooks.get_alias_set routine for language D.\n   Get the alias set corresponding to type or expression T.\n   Return -1 if we don't do anything special.  */\n\nstatic alias_set_type\nd_get_alias_set (tree)\n{\n  /* For now in D, assume everything aliases everything else, until we define\n     some solid rules backed by a specification.  There are also some parts\n     of code generation routines that don't adhere to C alias rules, such as\n     build_vconvert.  In any case, a lot of user code already assumes there\n     is no strict aliasing and will break if we were to change that.  */\n  return 0;\n}\n\n/* Implements the lang_hooks.types_compatible_p routine for language D.\n   Compares two types for equivalence in the D programming language.\n   This routine should only return 1 if it is sure, even though the frontend\n   should have already ensured that all types are compatible before handing\n   over the parsed ASTs to the code generator.  */\n\nstatic int\nd_types_compatible_p (tree x, tree y)\n{\n  Type *tx = TYPE_LANG_FRONTEND (x);\n  Type *ty = TYPE_LANG_FRONTEND (y);\n\n  /* Try validating the types in the frontend.  */\n  if (tx != NULL && ty != NULL)\n    {\n      /* Types are equivalent.  */\n      if (same_type_p (tx, ty))\n\treturn true;\n\n      /* Type system allows implicit conversion between.  */\n      if (tx->implicitConvTo (ty) || ty->implicitConvTo (tx))\n\treturn true;\n    }\n\n  /* Fallback on using type flags for comparison.  E.g: all dynamic arrays\n     are distinct types in D, but are VIEW_CONVERT compatible.  */\n  if (TREE_CODE (x) == RECORD_TYPE && TREE_CODE (y) == RECORD_TYPE)\n    {\n      if (TYPE_DYNAMIC_ARRAY (x) && TYPE_DYNAMIC_ARRAY (y))\n\treturn true;\n\n      if (TYPE_DELEGATE (x) && TYPE_DELEGATE (y))\n\treturn true;\n\n      if (TYPE_ASSOCIATIVE_ARRAY (x) && TYPE_ASSOCIATIVE_ARRAY (y))\n\treturn true;\n    }\n\n  return false;\n}\n\n/* Implements the lang_hooks.finish_incomplete_decl routine for language D.  */\n\nstatic void\nd_finish_incomplete_decl (tree decl)\n{\n  if (VAR_P (decl))\n    {\n      /* D allows zero-length declarations.  Such a declaration ends up with\n\t DECL_SIZE (t) == NULL_TREE which is what the back-end function\n\t assembler_variable checks.  This could change in later versions, or\n\t maybe all of these variables should be aliased to one symbol.  */\n      if (DECL_SIZE (decl) == 0)\n\t{\n\t  DECL_SIZE (decl) = bitsize_zero_node;\n\t  DECL_SIZE_UNIT (decl) = size_zero_node;\n\t}\n    }\n}\n\n/* Implements the lang_hooks.types.classify_record routine for language D.\n   Return the true debug type for TYPE.  */\n\nstatic classify_record\nd_classify_record (tree type)\n{\n  Type *t = TYPE_LANG_FRONTEND (type);\n\n  if (t && t->ty == Tclass)\n    {\n      TypeClass *tc = (TypeClass *) t;\n\n      /* extern(C++) interfaces get emitted as classes.  */\n      if (tc->sym->isInterfaceDeclaration ()\n\t  && !tc->sym->isCPPinterface ())\n\treturn RECORD_IS_INTERFACE;\n\n      return RECORD_IS_CLASS;\n    }\n\n  return RECORD_IS_STRUCT;\n}\n\n/* Implements the lang_hooks.tree_size routine for language D.\n   Determine the size of our tcc_constant or tcc_exceptional nodes.  */\n\nstatic size_t\nd_tree_size (tree_code code)\n{\n  switch (code)\n    {\n    case FUNCFRAME_INFO:\n      return sizeof (tree_frame_info);\n\n    default:\n      gcc_unreachable ();\n    }\n}\n\n/* Implements the lang_hooks.print_xnode routine for language D.  */\n\nstatic void\nd_print_xnode (FILE *file, tree node, int indent)\n{\n  switch (TREE_CODE (node))\n    {\n    case FUNCFRAME_INFO:\n      print_node (file, \"frame_type\", FRAMEINFO_TYPE (node), indent + 4);\n      break;\n\n    default:\n      break;\n    }\n}\n\n/* Return which tree structure is used by NODE, or TS_D_GENERIC if NODE\n   is one of the language-independent trees.  */\n\nd_tree_node_structure_enum\nd_tree_node_structure (lang_tree_node *t)\n{\n  switch (TREE_CODE (&t->generic))\n    {\n    case IDENTIFIER_NODE:\n      return TS_D_IDENTIFIER;\n\n    case FUNCFRAME_INFO:\n      return TS_D_FRAMEINFO;\n\n    default:\n      return TS_D_GENERIC;\n    }\n}\n\n/* Allocate and return a lang specific structure for the frontend type.  */\n\nstruct lang_type *\nbuild_lang_type (Type *t)\n{\n  struct lang_type *lt = ggc_cleared_alloc<struct lang_type> ();\n  lt->type = t;\n  return lt;\n}\n\n/* Allocate and return a lang specific structure for the frontend decl.  */\n\nstruct lang_decl *\nbuild_lang_decl (Declaration *d)\n{\n  /* For compiler generated run-time typeinfo, a lang_decl is allocated even if\n     there's no associated frontend symbol to refer to (yet).  If the symbol\n     appears later in the compilation, then the slot will be re-used.  */\n  if (d == NULL)\n    return ggc_cleared_alloc<struct lang_decl> ();\n\n  struct lang_decl *ld = (d->csym) ? DECL_LANG_SPECIFIC (d->csym) : NULL;\n  if (ld == NULL)\n    ld = ggc_cleared_alloc<struct lang_decl> ();\n\n  if (ld->decl == NULL)\n    ld->decl = d;\n\n  return ld;\n}\n\n/* Implements the lang_hooks.dup_lang_specific_decl routine for language D.\n   Replace the DECL_LANG_SPECIFIC field of NODE with a copy.  */\n\nstatic void\nd_dup_lang_specific_decl (tree node)\n{\n  if (! DECL_LANG_SPECIFIC (node))\n    return;\n\n  struct lang_decl *ld = ggc_alloc<struct lang_decl> ();\n  memcpy (ld, DECL_LANG_SPECIFIC (node), sizeof (struct lang_decl));\n  DECL_LANG_SPECIFIC (node) = ld;\n}\n\n/* This preserves trees we create from the garbage collector.  */\n\nstatic GTY(()) tree d_keep_list = NULL_TREE;\n\nvoid\nd_keep (tree t)\n{\n  d_keep_list = tree_cons (NULL_TREE, t, d_keep_list);\n}\n\n/* Implements the lang_hooks.eh_personality routine for language D.\n   Return the GDC personality function decl.  */\n\nstatic GTY(()) tree d_eh_personality_decl;\n\nstatic tree\nd_eh_personality (void)\n{\n  if (!d_eh_personality_decl)\n    d_eh_personality_decl = build_personality_function (\"gdc\");\n\n  return d_eh_personality_decl;\n}\n\n/* Implements the lang_hooks.eh_runtime_type routine for language D.  */\n\nstatic tree\nd_build_eh_runtime_type (tree type)\n{\n  Type *t = TYPE_LANG_FRONTEND (type);\n\n  if (t != NULL)\n    t = t->toBasetype ();\n\n  gcc_assert (t != NULL && t->ty == Tclass);\n  ClassDeclaration *cd = ((TypeClass *) t)->sym;\n  tree decl;\n\n  if (cd->isCPPclass ())\n    decl = get_cpp_typeinfo_decl (cd);\n  else\n    decl = get_classinfo_decl (cd);\n\n  return convert (ptr_type_node, build_address (decl));\n}\n\n/* Definitions for our language-specific hooks.  */\n\n#undef LANG_HOOKS_NAME\n#undef LANG_HOOKS_INIT\n#undef LANG_HOOKS_INIT_TS\n#undef LANG_HOOKS_INIT_OPTIONS\n#undef LANG_HOOKS_INIT_OPTIONS_STRUCT\n#undef LANG_HOOKS_OPTION_LANG_MASK\n#undef LANG_HOOKS_HANDLE_OPTION\n#undef LANG_HOOKS_POST_OPTIONS\n#undef LANG_HOOKS_PARSE_FILE\n#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE\n#undef LANG_HOOKS_ATTRIBUTE_TABLE\n#undef LANG_HOOKS_GET_ALIAS_SET\n#undef LANG_HOOKS_TYPES_COMPATIBLE_P\n#undef LANG_HOOKS_BUILTIN_FUNCTION\n#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE\n#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL\n#undef LANG_HOOKS_GIMPLIFY_EXPR\n#undef LANG_HOOKS_CLASSIFY_RECORD\n#undef LANG_HOOKS_TREE_SIZE\n#undef LANG_HOOKS_PRINT_XNODE\n#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL\n#undef LANG_HOOKS_EH_PERSONALITY\n#undef LANG_HOOKS_EH_RUNTIME_TYPE\n#undef LANG_HOOKS_PUSHDECL\n#undef LANG_HOOKS_GETDECLS\n#undef LANG_HOOKS_GLOBAL_BINDINGS_P\n#undef LANG_HOOKS_TYPE_FOR_MODE\n#undef LANG_HOOKS_TYPE_FOR_SIZE\n#undef LANG_HOOKS_TYPE_PROMOTES_TO\n\n#define LANG_HOOKS_NAME\t\t\t    \"GNU D\"\n#define LANG_HOOKS_INIT\t\t\t    d_init\n#define LANG_HOOKS_INIT_TS\t\t    d_init_ts\n#define LANG_HOOKS_INIT_OPTIONS\t\t    d_init_options\n#define LANG_HOOKS_INIT_OPTIONS_STRUCT\t    d_init_options_struct\n#define LANG_HOOKS_OPTION_LANG_MASK\t    d_option_lang_mask\n#define LANG_HOOKS_HANDLE_OPTION\t    d_handle_option\n#define LANG_HOOKS_POST_OPTIONS\t\t    d_post_options\n#define LANG_HOOKS_PARSE_FILE\t\t    d_parse_file\n#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE   d_langhook_common_attribute_table\n#define LANG_HOOKS_ATTRIBUTE_TABLE\t    d_langhook_attribute_table\n#define LANG_HOOKS_GET_ALIAS_SET\t    d_get_alias_set\n#define LANG_HOOKS_TYPES_COMPATIBLE_P\t    d_types_compatible_p\n#define LANG_HOOKS_BUILTIN_FUNCTION\t    d_builtin_function\n#define LANG_HOOKS_REGISTER_BUILTIN_TYPE    d_register_builtin_type\n#define LANG_HOOKS_FINISH_INCOMPLETE_DECL   d_finish_incomplete_decl\n#define LANG_HOOKS_GIMPLIFY_EXPR\t    d_gimplify_expr\n#define LANG_HOOKS_CLASSIFY_RECORD\t    d_classify_record\n#define LANG_HOOKS_TREE_SIZE\t\t    d_tree_size\n#define LANG_HOOKS_PRINT_XNODE\t\t    d_print_xnode\n#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL   d_dup_lang_specific_decl\n#define LANG_HOOKS_EH_PERSONALITY\t    d_eh_personality\n#define LANG_HOOKS_EH_RUNTIME_TYPE\t    d_build_eh_runtime_type\n#define LANG_HOOKS_PUSHDECL\t\t    d_pushdecl\n#define LANG_HOOKS_GETDECLS\t\t    d_getdecls\n#define LANG_HOOKS_GLOBAL_BINDINGS_P\t    d_global_bindings_p\n#define LANG_HOOKS_TYPE_FOR_MODE\t    d_type_for_mode\n#define LANG_HOOKS_TYPE_FOR_SIZE\t    d_type_for_size\n#define LANG_HOOKS_TYPE_PROMOTES_TO\t    d_type_promotes_to\n\nstruct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;\n\n#include \"gt-d-d-lang.h\"\n#include \"gtype-d.h\"\n"
  },
  {
    "path": "gcc/d/d-longdouble.cc",
    "content": "/* d-longdouble.cc -- Software floating-point emulation for the frontend.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/mtype.h\"\n\n#include \"tree.h\"\n#include \"fold-const.h\"\n#include \"diagnostic.h\"\n#include \"stor-layout.h\"\n\n#include \"d-tree.h\"\n#include \"longdouble.h\"\n\n\n/* Truncate longdouble to the highest precision supported by target.  */\n\nlongdouble\nlongdouble::normalize (void)\n{\n  const machine_mode mode = TYPE_MODE (long_double_type_node);\n  real_convert (&this->rv (), mode, &this->rv ());\n  return *this;\n}\n\n/* Assign a real_value to a longdouble type.  */\n\nvoid\nlongdouble::set (real_value& d)\n{\n  real_convert (&this->rv (), TYPE_MODE (long_double_type_node), &d);\n}\n\n/* Conversion routines between longdouble and integer types.  */\n\nvoid\nlongdouble::set (int32_t d)\n{\n  real_from_integer (&this->rv (), TYPE_MODE (double_type_node), d, SIGNED);\n}\n\nvoid\nlongdouble::set (int64_t d)\n{\n  real_from_integer (&this->rv (), TYPE_MODE (long_double_type_node), d,\n\t\t     SIGNED);\n}\n\nint64_t\nlongdouble::to_int (void) const\n{\n  bool overflow;\n  wide_int wi = real_to_integer (&this->rv (), &overflow, 64);\n  return wi.to_shwi ();\n}\n\n/* Unsigned variants of the same conversion routines.  */\n\nvoid\nlongdouble::set (uint32_t d)\n{\n  real_from_integer (&this->rv (), TYPE_MODE (double_type_node), d, UNSIGNED);\n}\n\nvoid\nlongdouble::set (uint64_t d)\n{\n  real_from_integer (&this->rv (), TYPE_MODE (long_double_type_node), d,\n\t\t     UNSIGNED);\n}\n\nuint64_t\nlongdouble::to_uint (void) const\n{\n  bool overflow;\n  wide_int wi = real_to_integer (&this->rv (), &overflow, 64);\n  return wi.to_uhwi ();\n}\n\n/* For conversion between boolean, only need to check if is zero.  */\n\nvoid\nlongdouble::set (bool d)\n{\n  this->rv () = (d == false) ? dconst0 : dconst1;\n}\n\nbool\nlongdouble::to_bool (void) const\n{\n  return this->rv ().cl != rvc_zero;\n}\n\n/* Overload numeric operators for longdouble types.  */\n\nlongdouble\nlongdouble::add (const longdouble& r) const\n{\n  longdouble x;\n  real_arithmetic (&x.rv (), PLUS_EXPR, &this->rv (), &r.rv ());\n  return x.normalize ();\n}\n\nlongdouble\nlongdouble::sub (const longdouble& r) const\n{\n  longdouble x;\n  real_arithmetic (&x.rv (), MINUS_EXPR, &this->rv (), &r.rv ());\n  return x.normalize ();\n}\n\nlongdouble\nlongdouble::mul (const longdouble& r) const\n{\n  longdouble x;\n  real_arithmetic (&x.rv (), MULT_EXPR, &this->rv (), &r.rv ());\n  return x.normalize ();\n}\n\nlongdouble\nlongdouble::div (const longdouble& r) const\n{\n  longdouble x;\n  real_arithmetic (&x.rv (), RDIV_EXPR, &this->rv (), &r.rv ());\n  return x.normalize ();\n}\n\nlongdouble\nlongdouble::mod (const longdouble& r) const\n{\n  longdouble x;\n  real_value q;\n\n  if (r.rv ().cl == rvc_zero || REAL_VALUE_ISINF (this->rv ()))\n    {\n      real_nan (&x.rv (), \"\", 1, TYPE_MODE (long_double_type_node));\n      return x;\n    }\n\n  if (this->rv ().cl == rvc_zero)\n    return *this;\n\n  if (REAL_VALUE_ISINF (r.rv ()))\n    return *this;\n\n  /* Need to check for NaN?  */\n  real_arithmetic (&q, RDIV_EXPR, &this->rv (), &r.rv ());\n  real_arithmetic (&q, FIX_TRUNC_EXPR, &q, NULL);\n  real_arithmetic (&q, MULT_EXPR, &q, &r.rv ());\n  real_arithmetic (&x.rv (), MINUS_EXPR, &this->rv (), &q);\n\n  return x.normalize ();\n}\n\nlongdouble\nlongdouble::neg (void) const\n{\n  longdouble x;\n  real_arithmetic (&x.rv (), NEGATE_EXPR, &this->rv (), NULL);\n  return x.normalize ();\n}\n\n/* Overload equality operators for longdouble types.  */\n\nint\nlongdouble::cmp (const longdouble& r) const\n{\n  if (real_compare (LT_EXPR, &this->rv (), &r.rv ()))\n    return -1;\n\n  if (real_compare (GT_EXPR, &this->rv (), &r.rv ()))\n    return 1;\n\n  return 0;\n}\n\nint\nlongdouble::equals (const longdouble& r) const\n{\n  return real_compare (EQ_EXPR, &this->rv (), &r.rv ());\n}\n"
  },
  {
    "path": "gcc/d/d-spec.cc",
    "content": "/* d-spec.c -- Specific flags and argument handling of the D front end.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n#include \"opt-suggestions.h\"\n#include \"gcc.h\"\n#include \"tm.h\"\n#include \"opts.h\"\n\n/* This bit is set if the arguments is a D source file.  */\n#define DSOURCE\t\t(1<<1)\n/* This bit is set if they did `-lstdc++'.  */\n#define WITHLIBCXX\t(1<<2)\n/* Skip this option.  */\n#define SKIPOPT\t\t(1<<3)\n\n#ifndef LIBSTDCXX\n#define LIBSTDCXX \"stdc++\"\n#endif\n#ifndef LIBSTDCXX_PROFILE\n#define LIBSTDCXX_PROFILE LIBSTDCXX\n#endif\n\n#ifndef LIBPHOBOS\n#define LIBPHOBOS \"gphobos\"\n#endif\n#ifndef LIBPHOBOS_PROFILE\n#define LIBPHOBOS_PROFILE LIBPHOBOS\n#endif\n\n#ifndef LIBDRUNTIME\n#define LIBDRUNTIME \"gdruntime\"\n#endif\n#ifndef LIBDRUNTIME_PROFILE\n#define LIBDRUNTIME_PROFILE LIBDRUNTIME\n#endif\n\n/* What do with libgphobos.  */\nenum phobos_action\n{\n  /* libgphobos should not be linked in.  */\n  PHOBOS_NOLINK = -1,\n  /* libgphobos should be linked in if it is needed.  */\n  PHOBOS_DEFAULT = 0,\n  /* libgphobos is needed and should be linked in.  */\n  PHOBOS_LINK,\n  /* libgphobos is needed and should be linked statically.  */\n  PHOBOS_STATIC,\n  /* libgphobos is needed and should be linked dynamically.  */\n  PHOBOS_DYNAMIC,\n};\n\nstatic phobos_action phobos_library = PHOBOS_DEFAULT;\n\n/* If true, use the standard D runtime library when linking with\n   standard libraries.  */\nstatic bool need_phobos = true;\n\nvoid\nlang_specific_driver (cl_decoded_option **in_decoded_options,\n\t\t      unsigned int *in_decoded_options_count,\n\t\t      int *in_added_libraries)\n{\n  unsigned int i, j;\n\n  /* If nonzero, the user gave us the `-p' or `-pg' flag.  */\n  int saw_profile_flag = 0;\n\n  /* If true, the user gave `-g'.  Used by -debuglib.  */\n  bool saw_debug_flag = false;\n\n  /* The new argument list will be contained in this.  */\n  cl_decoded_option *new_decoded_options;\n\n  /* \"-lstdc++\" if it appears on the command line.  */\n  const cl_decoded_option *saw_libcxx = 0;\n\n  /* Whether we need the C++ STD library.  */\n  bool need_stdcxx = false;\n\n  /* True if we saw -static.  */\n  bool static_link = false;\n\n  /* True if we should add -shared-libgcc to the command-line.  */\n  bool shared_libgcc = true;\n\n  /* What default library to use instead of phobos.  */\n  const char *defaultlib = NULL;\n\n  /* What debug library to use instead of phobos.  */\n  const char *debuglib = NULL;\n\n  /* The total number of arguments with the new stuff.  */\n  unsigned int num_args = 1;\n\n  /* \"-fonly\" if it appears on the command line.  */\n  const char *only_source_option = 0;\n\n  /* Whether the -o option was used.  */\n  bool saw_opt_o = false;\n\n  /* Whether the -c option was used.  Also used for -E, -fsyntax-only,\n     in general anything which implies only compilation and not linking.  */\n  bool saw_opt_c = false;\n\n  /* Whether the -S option was used.  */\n  bool saw_opt_S = false;\n\n  /* The first input file with an extension of .d.  */\n  const char *first_d_file = NULL;\n\n  /* The total number of arguments with the new stuff.  */\n  unsigned int argc = *in_decoded_options_count;\n\n  /* The argument list.  */\n  cl_decoded_option *decoded_options = *in_decoded_options;\n\n  /* The number of libraries added in.  */\n  int added_libraries = *in_added_libraries;\n\n  /* An array used to flag each argument that needs a bit set for\n     DSOURCE, MATHLIB, WITHTHREAD, WITHLIBC or WITHLIBCXX.  */\n  int *args = XCNEWVEC (int, argc);\n\n  for (i = 1; i < argc; i++)\n    {\n      const char *arg = decoded_options[i].arg;\n\n      switch (decoded_options[i].opt_index)\n\t{\n\tcase OPT_nostdlib:\n\tcase OPT_nodefaultlibs:\n\t  phobos_library = PHOBOS_NOLINK;\n\t  break;\n\n\tcase OPT_nophoboslib:\n\t  need_phobos = false;\n\t  args[i] |= SKIPOPT;\n\t  break;\n\n\tcase OPT_defaultlib_:\n\t  if (defaultlib != NULL)\n\t    free (CONST_CAST (char *, defaultlib));\n\t  if (arg != NULL)\n\t    {\n\t      need_phobos = false;\n\t      args[i] |= SKIPOPT;\n\t      defaultlib = XNEWVEC (char, strlen (arg));\n\t      strcpy (CONST_CAST (char *, defaultlib), arg);\n\t    }\n\t  break;\n\n\tcase OPT_debuglib_:\n\t  if (debuglib != NULL)\n\t    free (CONST_CAST (char *, debuglib));\n\t  if (arg != NULL)\n\t    {\n\t      need_phobos = false;\n\t      args[i] |= SKIPOPT;\n\t      debuglib = XNEWVEC (char, strlen (arg));\n\t      strcpy (CONST_CAST (char *, debuglib), arg);\n\t    }\n\t  break;\n\n\tcase OPT_l:\n\t  if ((strcmp (arg, LIBSTDCXX) == 0)\n\t      || (strcmp (arg, LIBSTDCXX_PROFILE) == 0))\n\t    {\n\t      args[i] |= WITHLIBCXX;\n\t      need_stdcxx = false;\n\t    }\n\t  /* Unrecognized libraries (e.g. -ltango) may require libphobos.  */\n\t  else if (phobos_library == PHOBOS_DEFAULT)\n\t    phobos_library = PHOBOS_LINK;\n\t  break;\n\n\tcase OPT_pg:\n\tcase OPT_p:\n\t  saw_profile_flag++;\n\t  break;\n\n\tcase OPT_g:\n\t  saw_debug_flag = true;\n\t  break;\n\n\tcase OPT_v:\n\t  /* If they only gave us `-v', don't try to link in libphobos.  */\n\t  if (argc == 2)\n\t    phobos_library = PHOBOS_NOLINK;\n\t  break;\n\n\tcase OPT_x:\n\t  if (phobos_library == PHOBOS_DEFAULT && (strcmp (arg, \"d\") == 0))\n\t    phobos_library = PHOBOS_LINK;\n\t  break;\n\n\tcase OPT_Xlinker:\n\tcase OPT_Wl_:\n\t  /* Arguments that go directly to the linker might be .o files\n\t     or something, and so might cause libphobos to be needed.  */\n\t  if (phobos_library == PHOBOS_DEFAULT)\n\t    phobos_library = PHOBOS_LINK;\n\t  break;\n\n\tcase OPT_c:\n\tcase OPT_E:\n\tcase OPT_M:\n\tcase OPT_MM:\n\tcase OPT_fsyntax_only:\n\t  /* Don't specify libaries if we won't link, since that would\n\t     cause a warning.  */\n\t  saw_opt_c = true;\n\t  phobos_library = PHOBOS_NOLINK;\n\t  break;\n\n\tcase OPT_S:\n\t  saw_opt_S = true;\n\t  phobos_library = PHOBOS_NOLINK;\n\t  break;\n\n\tcase OPT_o:\n\t  saw_opt_o = true;\n\t  break;\n\n\tcase OPT_static:\n\t  static_link = true;\n\t  break;\n\n\tcase OPT_static_libgcc:\n\t  shared_libgcc = false;\n\t  break;\n\n\tcase OPT_static_libphobos:\n\t  if (phobos_library != PHOBOS_NOLINK)\n\t    phobos_library = PHOBOS_STATIC;\n\t  args[i] |= SKIPOPT;\n\t  break;\n\n\tcase OPT_shared_libphobos:\n\t  if (phobos_library != PHOBOS_NOLINK)\n\t    phobos_library = PHOBOS_DYNAMIC;\n\t  args[i] |= SKIPOPT;\n\t  break;\n\n\tcase OPT_fonly_:\n\t  args[i] |= SKIPOPT;\n\t  only_source_option = decoded_options[i].orig_option_with_args_text;\n\n\t  if (arg != NULL)\n\t    {\n\t      const char *suffix = strrchr (only_source_option, '.');\n\t      if (suffix == NULL || strcmp (suffix, \".d\") != 0)\n\t\tonly_source_option = concat (only_source_option, \".d\", NULL);\n\t    }\n\t  break;\n\n\tcase OPT_SPECIAL_input_file:\n\t  {\n\t    if (arg[0] == '\\0' || arg[1] == '\\0')\n\t      continue;\n\n\t    if (phobos_library == PHOBOS_DEFAULT)\n\t      phobos_library = PHOBOS_LINK;\n\n\t    /* Record that this is a D source file.  */\n\t    const char *suffix = strrchr (arg, '.');\n\t    if (suffix != NULL && strcmp (suffix, \".d\") == 0)\n\t      {\n\t\tif (first_d_file == NULL)\n\t\t  first_d_file = arg;\n\n\t\targs[i] |= DSOURCE;\n\t      }\n\n\t    /* If this is a C++ source file, we'll need to link\n\t       against libstdc++ library.  */\n\t    if (suffix != NULL\n\t\t&& (strcmp (suffix, \".cc\") == 0\n\t\t    || (strcmp (suffix, \".cpp\") == 0)\n\t\t    || (strcmp (suffix, \".c++\") == 0)))\n\t      need_stdcxx = true;\n\n\t    break;\n\t  }\n\t}\n    }\n\n  /* There's no point adding -shared-libgcc if we don't have a shared\n     libgcc.  */\n#ifndef ENABLE_SHARED_LIBGCC\n  shared_libgcc = false;\n#endif\n\n  /* Make sure to have room for the trailing NULL argument.\n     - needstdcxx might add `-lstdcxx'\n     - libphobos adds `-Bstatic -lphobos -ldruntime -Bdynamic'\n     - only_source adds 1 more arg, also maybe add `-o'.  */\n  num_args = argc + need_stdcxx + shared_libgcc + need_phobos * 4 + 2;\n  new_decoded_options = XNEWVEC (cl_decoded_option, num_args);\n\n  i = 0;\n  j = 0;\n\n  /* Copy the 0th argument, i.e., the name of the program itself.  */\n  new_decoded_options[j++] = decoded_options[i++];\n\n  /* NOTE: We start at 1 now, not 0.  */\n  while (i < argc)\n    {\n      if (args[i] & SKIPOPT)\n\t{\n\t  ++i;\n\t  continue;\n\t}\n\n      new_decoded_options[j] = decoded_options[i];\n\n      if (!saw_libcxx && (args[i] & WITHLIBCXX))\n\t{\n\t  --j;\n\t  saw_libcxx = &decoded_options[i];\n\t}\n\n      if (args[i] & DSOURCE)\n\t{\n\t  if (only_source_option)\n\t    --j;\n\t}\n\n      i++;\n      j++;\n    }\n\n  if (only_source_option)\n    {\n      const char *only_source_arg = only_source_option + 7;\n      generate_option (OPT_fonly_, only_source_arg, 1, CL_DRIVER,\n\t\t       &new_decoded_options[j]);\n      j++;\n\n      generate_option_input_file (only_source_arg,\n\t\t\t\t  &new_decoded_options[j++]);\n    }\n\n  /* If no reason to link against libphobos library, then don't add it.  */\n  if (phobos_library == PHOBOS_DEFAULT)\n    phobos_library = PHOBOS_NOLINK;\n\n  /* If we didn't see a -o option, add one.  This is because we need the\n     driver to pass all .d files to the D compiler.  Without a -o option\n     the driver will invoke the compiler separately for each input file.  */\n  if (first_d_file != NULL && !saw_opt_o)\n    {\n      if (saw_opt_c || saw_opt_S)\n\t{\n\t  const char *base = lbasename (first_d_file);\n\t  int baselen = strlen (base) - 2;\n\t  char *out = XNEWVEC (char, baselen + 3);\n\n\t  memcpy (out, base, baselen);\n\t  /* The driver will convert .o to some other suffix if appropriate.  */\n\t  out[baselen] = '.';\n\t  if (saw_opt_S)\n\t    out[baselen + 1] = 's';\n\t  else\n\t    out[baselen + 1] = 'o';\n\t  out[baselen + 2] = '\\0';\n\t  generate_option (OPT_o, out, 1, CL_DRIVER,\n\t\t\t   &new_decoded_options[j]);\n\t}\n      else\n\t{\n\t  /* Wouldn't be necessary if the driver converted .out also.  */\n\t  const char *out = NULL;\n\n#ifdef TARGET_EXECUTABLE_SUFFIX\n\t  if (TARGET_EXECUTABLE_SUFFIX[0] != 0)\n\t    out = \"a\" TARGET_EXECUTABLE_SUFFIX;\n#endif\n\t  if (out == NULL)\n\t    out = \"a.out\";\n\n\t  generate_option (OPT_o, out, 1, CL_DRIVER,\n\t\t\t   &new_decoded_options[j]);\n\t}\n      j++;\n    }\n\n  /* Add `-lgphobos' if we haven't already done so.  */\n  if (phobos_library != PHOBOS_NOLINK && need_phobos)\n    {\n      /* Default to static linking.  */\n      if (phobos_library != PHOBOS_DYNAMIC)\n\tphobos_library = PHOBOS_STATIC;\n\n#ifdef HAVE_LD_STATIC_DYNAMIC\n      if (phobos_library == PHOBOS_DYNAMIC && static_link)\n\t{\n\t  generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,\n\t\t\t   &new_decoded_options[j]);\n\t  j++;\n\t}\n      else if (phobos_library == PHOBOS_STATIC && !static_link)\n\t{\n\t  generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,\n\t\t\t   &new_decoded_options[j]);\n\t  j++;\n\t}\n#endif\n\n      generate_option (OPT_l,\n\t\t       saw_profile_flag ? LIBPHOBOS_PROFILE : LIBPHOBOS, 1,\n\t\t       CL_DRIVER, &new_decoded_options[j]);\n      added_libraries++;\n      j++;\n      generate_option (OPT_l,\n\t\t       saw_profile_flag ? LIBDRUNTIME_PROFILE : LIBDRUNTIME, 1,\n\t\t       CL_DRIVER, &new_decoded_options[j]);\n      added_libraries++;\n      j++;\n\n#ifdef HAVE_LD_STATIC_DYNAMIC\n      if (phobos_library == PHOBOS_DYNAMIC && static_link)\n\t{\n\t  generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,\n\t\t\t   &new_decoded_options[j]);\n\t  j++;\n\t}\n      else if (phobos_library == PHOBOS_STATIC && !static_link)\n\t{\n\t  generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,\n\t\t\t   &new_decoded_options[j]);\n\t  j++;\n\t}\n#endif\n    }\n  else if (saw_debug_flag && debuglib)\n    {\n      generate_option (OPT_l, debuglib, 1, CL_DRIVER,\n\t\t       &new_decoded_options[j++]);\n      added_libraries++;\n    }\n  else if (defaultlib)\n    {\n      generate_option (OPT_l, defaultlib, 1, CL_DRIVER,\n\t\t       &new_decoded_options[j++]);\n      added_libraries++;\n    }\n\n  if (saw_libcxx)\n    new_decoded_options[j++] = *saw_libcxx;\n  else if (need_stdcxx)\n    {\n      generate_option (OPT_l,\n\t\t       (saw_profile_flag\n\t\t\t? LIBSTDCXX_PROFILE\n\t\t\t: LIBSTDCXX),\n\t\t       1, CL_DRIVER, &new_decoded_options[j++]);\n      added_libraries++;\n    }\n\n  if (shared_libgcc && !static_link)\n    {\n      generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,\n\t\t       &new_decoded_options[j++]);\n    }\n\n  *in_decoded_options_count = j;\n  *in_decoded_options = new_decoded_options;\n  *in_added_libraries = added_libraries;\n}\n\n/* Called before linking.  Returns 0 on success and -1 on failure.  */\n\nint\nlang_specific_pre_link (void)\n{\n  if (phobos_library != PHOBOS_NOLINK && need_phobos)\n    do_spec (\"%:include(libgphobos.spec)\");\n\n  return 0;\n}\n\n/* Number of extra output files that lang_specific_pre_link may generate.  */\n\nint lang_specific_extra_outfiles = 0;  /* Not used for D.  */\n\n"
  },
  {
    "path": "gcc/d/d-target-def.h",
    "content": "/* d-target-def.h -- Default initializers for D target hooks.\n   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n\n   This program is free software; you can redistribute it and/or modify it\n   under the terms of the GNU General Public License as published by the\n   Free Software Foundation; either version 3, or (at your option) any\n   later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; see the file COPYING3.  If not see\n   <http://www.gnu.org/licenses/>.  */\n\n#include \"d/d-target-hooks-def.h\"\n#include \"tree.h\"\n#include \"hooks.h\"\n"
  },
  {
    "path": "gcc/d/d-target.cc",
    "content": "/* d-target.cc -- Target interface for the D front end.\n   Copyright (C) 2013-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/aggregate.h\"\n#include \"dmd/declaration.h\"\n#include \"dmd/expression.h\"\n#include \"dmd/mangle.h\"\n#include \"dmd/mtype.h\"\n#include \"dmd/tokens.h\"\n#include \"dmd/target.h\"\n\n#include \"tree.h\"\n#include \"memmodel.h\"\n#include \"fold-const.h\"\n#include \"stor-layout.h\"\n#include \"tm.h\"\n#include \"tm_p.h\"\n#include \"target.h\"\n\n#include \"d-tree.h\"\n#include \"d-target.h\"\n\n/* Implements the Target interface defined by the front end.\n   Used for retrieving target-specific information.  */\n\n/* Floating-point constants for for .max, .min, and other properties.  */\ntemplate <typename T> real_t Target::FPTypeProperties<T>::max;\ntemplate <typename T> real_t Target::FPTypeProperties<T>::min_normal;\ntemplate <typename T> real_t Target::FPTypeProperties<T>::nan;\ntemplate <typename T> real_t Target::FPTypeProperties<T>::snan;\ntemplate <typename T> real_t Target::FPTypeProperties<T>::infinity;\ntemplate <typename T> real_t Target::FPTypeProperties<T>::epsilon;\ntemplate <typename T> d_int64 Target::FPTypeProperties<T>::dig;\ntemplate <typename T> d_int64 Target::FPTypeProperties<T>::mant_dig;\ntemplate <typename T> d_int64 Target::FPTypeProperties<T>::max_exp;\ntemplate <typename T> d_int64 Target::FPTypeProperties<T>::min_exp;\ntemplate <typename T> d_int64 Target::FPTypeProperties<T>::max_10_exp;\ntemplate <typename T> d_int64 Target::FPTypeProperties<T>::min_10_exp;\n\n\n/* Initialize the floating-point constants for TYPE.  */\n\ntemplate <typename T>\nstatic void\ndefine_float_constants (tree type)\n{\n  const double log10_2 = 0.30102999566398119521;\n  char buf[128];\n\n  /* Get back-end real mode format.  */\n  const machine_mode mode = TYPE_MODE (type);\n  const real_format *fmt = REAL_MODE_FORMAT (mode);\n\n  /* The largest representable value that's not infinity.  */\n  get_max_float (fmt, buf, sizeof (buf));\n  real_from_string (&T::max.rv (), buf);\n\n  /* The smallest representable normalized value that's not 0.  */\n  snprintf (buf, sizeof (buf), \"0x1p%d\", fmt->emin - 1);\n  real_from_string (&T::min_normal.rv (), buf);\n\n  /* Floating-point NaN.  */\n  real_nan (&T::nan.rv (), \"\", 1, mode);\n\n  /* Signalling floating-point NaN.  */\n  real_nan (&T::snan.rv (), \"\", 0, mode);\n\n  /* Floating-point +Infinity if the target supports infinities.  */\n  real_inf (&T::infinity.rv ());\n\n  /* The smallest increment to the value 1.  */\n  if (fmt->pnan < fmt->p)\n    snprintf (buf, sizeof (buf), \"0x1p%d\", fmt->emin - fmt->p);\n  else\n    snprintf (buf, sizeof (buf), \"0x1p%d\", 1 - fmt->p);\n  real_from_string (&T::epsilon.rv (), buf);\n\n  /* The number of decimal digits of precision.  */\n  T::dig = (fmt->p - 1) * log10_2;\n\n  /* The number of bits in mantissa.  */\n  T::mant_dig = fmt->p;\n\n  /* The maximum int value such that 2** (value-1) is representable.  */\n  T::max_exp = fmt->emax;\n\n  /* The minimum int value such that 2** (value-1) is representable as a\n     normalized value.  */\n  T::min_exp = fmt->emin;\n\n  /* The maximum int value such that 10**value is representable.  */\n  T::max_10_exp = fmt->emax * log10_2;\n\n  /* The minimum int value such that 10**value is representable as a\n     normalized value.  */\n  T::min_10_exp = (fmt->emin - 1) * log10_2;\n}\n\n/* Initialize all variables of the Target structure.  */\n\nvoid\nTarget::_init (void)\n{\n  /* Map D frontend type and sizes to GCC back-end types.  */\n  Target::ptrsize = (POINTER_SIZE / BITS_PER_UNIT);\n  Target::realsize = int_size_in_bytes (long_double_type_node);\n  Target::realpad = (Target::realsize -\n\t\t     (TYPE_PRECISION (long_double_type_node) / BITS_PER_UNIT));\n  Target::realalignsize = TYPE_ALIGN_UNIT (long_double_type_node);\n\n  /* Size of run-time TypeInfo object.  */\n  Target::classinfosize = 19 * Target::ptrsize;\n\n  /* Allow data sizes up to half of the address space.  */\n  Target::maxStaticDataSize = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));\n\n  /* Define what type to use for size_t, ptrdiff_t.  */\n  if (POINTER_SIZE == 64)\n    {\n      global.params.isLP64 = true;\n      Tsize_t = Tuns64;\n      Tptrdiff_t = Tint64;\n    }\n  else\n    {\n      Tsize_t = Tuns32;\n      Tptrdiff_t = Tint32;\n    }\n\n  Type::tsize_t = Type::basic[Tsize_t];\n  Type::tptrdiff_t = Type::basic[Tptrdiff_t];\n  Type::thash_t = Type::tsize_t;\n\n  /* Set-up target C ABI.  */\n  Target::c_longsize = int_size_in_bytes (long_integer_type_node);\n  Target::c_long_doublesize = int_size_in_bytes (long_double_type_node);\n\n  /* Set-up target C++ ABI.  */\n  Target::reverseCppOverloads = false;\n  Target::cppExceptions = true;\n  Target::twoDtorInVtable = true;\n\n  /* Initialize all compile-time properties for floating-point types.\n     Should ensure that our real_t type is able to represent real_value.  */\n  gcc_assert (sizeof (real_t) >= sizeof (real_value));\n\n  define_float_constants <Target::FloatProperties> (float_type_node);\n  define_float_constants <Target::DoubleProperties> (double_type_node);\n  define_float_constants <Target::RealProperties> (long_double_type_node);\n\n  /* Commonly used floating-point constants.  */\n  const machine_mode mode = TYPE_MODE (long_double_type_node);\n  real_convert (&CTFloat::zero.rv (), mode, &dconst0);\n  real_convert (&CTFloat::one.rv (), mode, &dconst1);\n  real_convert (&CTFloat::minusone.rv (), mode, &dconstm1);\n  real_convert (&CTFloat::half.rv (), mode, &dconsthalf);\n}\n\n/* Return GCC memory alignment size for type TYPE.  */\n\nunsigned\nTarget::alignsize (Type *type)\n{\n  gcc_assert (type->isTypeBasic ());\n  return TYPE_ALIGN_UNIT (build_ctype (type));\n}\n\n/* Return GCC field alignment size for type TYPE.  */\n\nunsigned\nTarget::fieldalign (Type *type)\n{\n  /* Work out the correct alignment for the field decl.  */\n  unsigned int align = type->alignsize () * BITS_PER_UNIT;\n\n#ifdef BIGGEST_FIELD_ALIGNMENT\n  align = MIN (align, (unsigned) BIGGEST_FIELD_ALIGNMENT);\n#endif\n\n#ifdef ADJUST_FIELD_ALIGN\n  if (type->isTypeBasic ())\n    align = ADJUST_FIELD_ALIGN (NULL_TREE, build_ctype (type), align);\n#endif\n\n  /* Also controlled by -fpack-struct=  */\n  if (maximum_field_alignment)\n    align = MIN (align, maximum_field_alignment);\n\n  return align / BITS_PER_UNIT;\n}\n\n/* Return size of OS critical section.\n   Can't use the sizeof () calls directly since cross compiling is supported\n   and would end up using the host sizes rather than the target sizes.  */\n\nunsigned\nTarget::critsecsize (void)\n{\n  return targetdm.d_critsec_size ();\n}\n\n/* Returns a Type for the va_list type of the target.  */\n\nType *\nTarget::va_listType (void)\n{\n  return Type::tvalist;\n}\n\n/* Checks whether the target supports a vector type with total size SZ\n   (in bytes) and element type TYPE.  */\n\nint\nTarget::isVectorTypeSupported (int sz, Type *type)\n{\n  /* Size must be greater than zero, and a power of two.  */\n  if (sz <= 0 || sz & (sz - 1))\n    return 2;\n\n  /* __vector(void[]) is treated same as __vector(ubyte[])  */\n  if (type == Type::tvoid)\n    type = Type::tuns8;\n\n  /* No support for non-trivial types.  */\n  if (!type->isTypeBasic ())\n    return 3;\n\n  /* If there is no hardware support, check if we can safely emulate it.  */\n  tree ctype = build_ctype (type);\n  machine_mode mode = TYPE_MODE (ctype);\n\n  if (!targetm.vector_mode_supported_p (mode)\n      && !targetm.scalar_mode_supported_p (as_a <scalar_mode> (mode)))\n    return 3;\n\n  return 0;\n}\n\n/* Checks whether the target supports operation OP for vectors of type TYPE.\n   For binary ops T2 is the type of the right-hand operand.\n   Returns true if the operation is supported or type is not a vector.  */\n\nbool\nTarget::isVectorOpSupported (Type *type, TOK op, Type *)\n{\n  if (type->ty != Tvector)\n    return true;\n\n  /* Don't support if type is non-scalar, such as __vector(void[]).  */\n  if (!type->isscalar ())\n    return false;\n\n  /* Don't support if expression cannot be represented.  */\n  switch (op)\n    {\n    case TOKpow:\n    case TOKpowass:\n      /* pow() is lowered as a function call.  */\n      return false;\n\n    case TOKmod:\n    case TOKmodass:\n      /* fmod() is lowered as a function call.  */\n      if (type->isfloating ())\n\treturn false;\n      break;\n\n    case TOKandand:\n    case TOKoror:\n      /* Logical operators must have a result type of bool.  */\n      return false;\n\n    case TOKle:\n    case TOKlt:\n    case TOKge:\n    case TOKgt:\n    case TOKequal:\n    case TOKnotequal:\n    case TOKidentity:\n    case TOKnotidentity:\n      /* Comparison operators must have a result type of bool.  */\n      return false;\n\n    default:\n      break;\n    }\n\n  return true;\n}\n\n/* Return the symbol mangling of S for C++ linkage.  */\n\nconst char *\nTarget::toCppMangle (Dsymbol *s)\n{\n  return toCppMangleItanium (s);\n}\n\n/* Return the symbol mangling of CD for C++ linkage.  */\n\nconst char *\nTarget::cppTypeInfoMangle (ClassDeclaration *cd)\n{\n  return cppTypeInfoMangleItanium (cd);\n}\n\n/* For a vendor-specific type, return a string containing the C++ mangling.\n   In all other cases, return NULL.  */\n\nconst char *\nTarget::cppTypeMangle (Type *type)\n{\n  if (type->isTypeBasic () || type->ty == Tvector || type->ty == Tstruct)\n    {\n      tree ctype = build_ctype (type);\n      return targetm.mangle_type (ctype);\n    }\n\n  return NULL;\n}\n\n/* Return the type that will really be used for passing the given parameter\n   ARG to an extern(C++) function.  */\n\nType *\nTarget::cppParameterType (Parameter *arg)\n{\n  Type *t = arg->type->merge2 ();\n  if (arg->storageClass & (STCout | STCref))\n    t = t->referenceTo ();\n  else if (arg->storageClass & STClazy)\n    {\n      /* Mangle as delegate.  */\n      Type *td = TypeFunction::create (NULL, t, 0, LINKd);\n      td = TypeDelegate::create (td);\n      t = t->merge2 ();\n    }\n\n  /* Could be a va_list, which we mangle as a pointer.  */\n  if (t->ty == Tsarray && Type::tvalist->ty == Tsarray)\n    {\n      Type *tb = t->toBasetype ()->mutableOf ();\n      if (tb == Type::tvalist)\n\t{\n\t  tb = t->nextOf ()->pointerTo ();\n\t  t = tb->castMod (t->mod);\n\t}\n    }\n\n  return t;\n}\n\n/* Return the default system linkage for the target.  */\n\nLINK\nTarget::systemLinkage (void)\n{\n  return LINKc;\n}\n\n/* Determine return style of function, whether in registers or through a\n   hidden pointer to the caller's stack.  */\n\nbool\nTarget::isReturnOnStack (TypeFunction *, bool)\n{\n  /* Need the back-end type to determine this, but this is called from the\n     frontend before semantic processing is finished.  An accurate value\n     is not currently needed anyway.  */\n  return true;\n}\n\n/* Return the result of a __traits(getTargetInfo) query or NULL if it is\n   not information that's known at compile-time.  */\n\nExpression *\nTarget::getTargetInfo (const char *name, const Loc& loc)\n{\n  const char *result = NULL;\n\n  switch (strlen (name))\n    {\n    case 8:\n      if (strcmp (name, \"floatAbi\") == 0)\n\tresult = targetdm.d_float_abi_type ();\n      break;\n\n    case 12:\n      if (strcmp (name, \"objectFormat\") == 0)\n\tresult = targetdm.d_object_format ();\n      break;\n\n    case 17:\n      /* The driver only ever optionally links to libstdc++.  */\n      if (strcmp (name, \"cppRuntimeLibrary\") == 0)\n\tresult = \"libstdc++\";\n      break;\n    }\n\n  if (result != NULL)\n    return StringExp::create (loc, CONST_CAST (char *, result),\n\t\t\t      strlen (result));\n\n  return NULL;\n}\n"
  },
  {
    "path": "gcc/d/d-target.def",
    "content": "/* d-target.def -- Target hook definitions for the D front end.\n   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n\n   This program is free software; you can redistribute it and/or modify it\n   under the terms of the GNU General Public License as published by the\n   Free Software Foundation; either version 3, or (at your option) any\n   later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; see the file COPYING3.  If not see\n   <http://www.gnu.org/licenses/>.  */\n\n/* See target-hooks-macros.h for details of macros that should be\n   provided by the including file, and how to use them here.  */\n\n#include \"target-hooks-macros.h\"\n\n#undef HOOK_TYPE\n#define HOOK_TYPE \"D Target Hook\"\n\nHOOK_VECTOR (TARGETDM_INITIALIZER, gcc_targetdm)\n\n#undef HOOK_PREFIX\n#define HOOK_PREFIX \"TARGET_\"\n\n/* Environmental version identifiers relating to the target CPU.  */\nDEFHOOK\n(d_cpu_versions,\n \"Declare all environmental version identifiers relating to the target CPU\\n\\\nusing the function @code{builtin_version}, which takes a string representing\\n\\\nthe name of the version.  Version identifiers predefined by this hook apply\\n\\\nto all modules that are being compiled and imported.\",\n void, (void),\n hook_void_void)\n\n/* Environmental version identifiers relating to the target OS.  */\nDEFHOOK\n(d_os_versions,\n \"Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions\\n\\\nrelating to the target operating system.\",\n void, (void),\n hook_void_void)\n\n/* The sizeof CRITICAL_SECTION or pthread_mutex_t.  */\nDEFHOOK\n(d_critsec_size,\n \"Returns the size of the data structure used by the target operating system\\n\\\nfor critical sections and monitors.  For example, on Microsoft Windows this\\n\\\nwould return the @code{sizeof(CRITICAL_SECTION)}, while other platforms that\\n\\\nimplement pthreads would return @code{sizeof(pthread_mutex_t)}.\",\n unsigned, (void),\n hook_uint_void_0)\n\n/* The floating point ABI, may be \"hard\" or \"soft\".  */\nDEFHOOK\n(d_float_abi_type,\n \"Returns a string specifying which floating-point ABI is in use, or whether\\n\\\nfloating-point value types are passed in FPU registers.  For most targets,\\n\\\nthis would be described as either \\\"hard\\\" or \\\"soft\\\".\",\n const char *, (void),\n hook_constcharptr_void_null)\n\n/* The target object format.  */\nDEFHOOK\n(d_object_format,\n \"Returns a string specifying the executable object format of the platform\\n\\\nthe compiler is generating code for.\",\n const char *, (void),\n hook_constcharptr_void_null)\n\n/* Close the 'struct gcc_targetdm' definition.  */\nHOOK_VECTOR_END (C90_EMPTY_HACK)\n"
  },
  {
    "path": "gcc/d/d-target.h",
    "content": "/* d-target.h -- Data structure definitions for target-specific D behavior.\n   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n\n   This program is free software; you can redistribute it and/or modify it\n   under the terms of the GNU General Public License as published by the\n   Free Software Foundation; either version 3, or (at your option) any\n   later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; see the file COPYING3.  If not see\n   <http://www.gnu.org/licenses/>.  */\n\n#ifndef GCC_D_TARGET_H\n#define GCC_D_TARGET_H\n\n#define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME;\n#define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS;\n#define DEFHOOK_UNDOC DEFHOOK\n#define HOOKSTRUCT(FRAGMENT) FRAGMENT\n\n#include \"d-target.def\"\n\n/* Each target can provide their own.  */\nextern struct gcc_targetdm targetdm;\n\n/* Used by target to add predefined version idenditiers.  */\nextern void d_add_builtin_version (const char *);\n\n#endif /* GCC_D_TARGET_H  */\n"
  },
  {
    "path": "gcc/d/d-tree.def",
    "content": "/* d-tree.def -- Definitions and documentation for additional tree codes used\n   in the D compiler  (see tree.def for standard codes).\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n/* Logical shift done on an unsigned type.  If the first operand is\n   signed, it will be converted to the unsigned equivalent.  The second\n   operand is the number of bits to shift by; it need not be the same\n   type as the first operand and result.  */\nDEFTREECODE (UNSIGNED_RSHIFT_EXPR, \"unsigned_rshift_expr\", tcc_binary, 2)\n\n/* Floating point modulus that expands to a call to fmod.  */\nDEFTREECODE (FLOAT_MOD_EXPR, \"float_mod_expr\", tcc_binary, 2)\n\n/* Used to represent information associated with a function closure.  */\nDEFTREECODE (FUNCFRAME_INFO, \"funcframe_info\", tcc_exceptional, 0)\n"
  },
  {
    "path": "gcc/d/d-tree.h",
    "content": "/* d-tree.h -- Definitions and declarations for code generation.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#ifndef GCC_D_TREE_H\n#define GCC_D_TREE_H\n\n/* Forward type declarations to avoid including unnecessary headers.  */\n\nclass Dsymbol;\nclass Declaration;\nclass AggregateDeclaration;\nclass ClassDeclaration;\nclass EnumDeclaration;\nclass FuncDeclaration;\nclass StructDeclaration;\nclass TypeInfoDeclaration;\nclass VarDeclaration;\nclass UserAttributeDeclaration;\nclass Expression;\nclass ClassReferenceExp;\nclass Module;\nclass Statement;\nclass Type;\nclass TypeFunction;\nclass Parameter;\nstruct BaseClass;\nstruct Scope;\nstruct Loc;\n\ntemplate <typename TYPE> struct Array;\ntypedef Array<Expression *> Expressions;\n\n/* Usage of TREE_LANG_FLAG_?:\n   0: METHOD_CALL_EXPR\n   1: CALL_EXPR_ARGS_ORDERED (in CALL_EXPR).\n\n   Usage of TYPE_LANG_FLAG_?:\n   0: TYPE_SHARED\n   1: TYPE_IMAGINARY_FLOAT (in REAL_TYPE).\n      ANON_AGGR_TYPE_P (in RECORD_TYPE, UNION_TYPE).\n   2: CLASS_TYPE_P (in RECORD_TYPE).\n   3: TYPE_DYNAMIC_ARRAY (in RECORD_TYPE).\n   4: TYPE_DELEGATE (in RECORD_TYPE).\n   5: TYPE_ASSOCIATIVE_ARRAY (in RECORD_TYPE).\n\n   Usage of DECL_LANG_FLAG_?:\n   0: LABEL_VARIABLE_CASE (in LABEL_DECL).\n      DECL_BUILT_IN_CTFE (in FUNCTION_DECL).  */\n\n/* The kinds of scopes we recognize.  */\n\nenum level_kind\n{\n  level_block,\t\t/* An ordinary block scope.  */\n  level_try,\t\t/* A try-block.  */\n  level_catch,\t\t/* A catch-block.  */\n  level_finally,\t/* A finally-block.  */\n  level_cond,\t\t/* The scope for an if condition.  */\n  level_switch,\t\t/* The scope for a switch statement.  */\n  level_loop,\t\t/* A for, do-while, or unrolled-loop block.  */\n  level_with,\t\t/* The scope for a with statement.  */\n  level_function\t/* The block representing an entire function.  */\n};\n\n/* List of codes for internally recognised compiler intrinsics.  */\n\nenum intrinsic_code\n{\n#define DEF_D_INTRINSIC(CODE, A, N, M, D, C) INTRINSIC_ ## CODE,\n\n#include \"intrinsics.def\"\n\n#undef DEF_D_INTRINSIC\n  INTRINSIC_LAST\n};\n\n/* For use with break and continue statements.  */\n\nenum bc_kind\n{\n  bc_break    = 0,\n  bc_continue = 1\n};\n\n/* The datatype used to implement D scope.  It is needed primarily to support\n   the back-end, but also helps debugging information for local variables.  */\n\nstruct GTY((chain_next (\"%h.level_chain\"))) binding_level\n{\n  /* A chain of declarations for all variables, constants and functions.\n     These are in the reverse of the order supplied.  */\n  tree names;\n\n  /* For each level (except the global one), a chain of BLOCK nodes for\n     all the levels that were entered and exited one level down.  */\n  tree blocks;\n\n  /* The binding level this one is contained in.  */\n  binding_level *level_chain;\n\n  /* The kind of scope this object represents.  */\n  ENUM_BITFIELD (level_kind) kind : 4;\n};\n\n/* The binding level currently in effect.  */\nextern GTY(()) binding_level *current_binding_level;\nextern GTY(()) binding_level *global_binding_level;\n\n/* Used only for jumps to as-yet undefined labels, since jumps to\n   defined labels can have their validity checked immediately.  */\n\nstruct GTY((chain_next (\"%h.next\"))) d_label_use_entry\n{\n  d_label_use_entry *next;\n\n  /* The frontend Statement associated with the jump.  */\n  Statement * GTY((skip)) statement;\n\n  /* The binding level to which this entry is *currently* attached.\n     This is initially the binding level in which the goto appeared,\n     but is modified as scopes are closed.  */\n  binding_level *level;\n};\n\n/* A list of all LABEL_DECLs in the function that have names.  Here so\n   we can clear out their names' definitions at the end of the\n   function, and so we can check the validity of jumps to these labels.  */\n\nstruct GTY(()) d_label_entry\n{\n  /* The label decl itself.  */\n  tree label;\n\n  /* The frontend Statement associated with the label.  */\n  Statement * GTY((skip)) statement;\n\n  /* The binding level to which the label is *currently* attached.\n     This is initially set to the binding level in which the label\n     is defined, but is modified as scopes are closed.  */\n  binding_level *level;\n\n  /* A list of forward references of the label.  */\n  d_label_use_entry *fwdrefs;\n\n  /* The following bits are set after the label is defined, and are\n     updated as scopes are popped.  They indicate that a backward jump\n     to the label will illegally enter a scope of the given flavor.  */\n  bool in_try_scope;\n  bool in_catch_scope;\n\n  /* If set, the label we reference represents a break/continue pair.  */\n  bool bc_label;\n};\n\n/* Frame information for a function declaration.  */\n\nstruct GTY(()) tree_frame_info\n{\n  struct tree_common common;\n  tree frame_type;\n};\n\n/* True if the function creates a nested frame.  */\n#define FRAMEINFO_CREATES_FRAME(NODE) \\\n  (TREE_LANG_FLAG_0 (FUNCFRAME_INFO_CHECK (NODE)))\n\n/* True if the function has a static chain passed in its DECL_ARGUMENTS.  */\n#define FRAMEINFO_STATIC_CHAIN(NODE) \\\n  (TREE_LANG_FLAG_1 (FUNCFRAME_INFO_CHECK (NODE)))\n\n/* True if the function frame is a closure (initialized on the heap).  */\n#define FRAMEINFO_IS_CLOSURE(NODE) \\\n  (TREE_LANG_FLAG_2 (FUNCFRAME_INFO_CHECK (NODE)))\n\n#define FRAMEINFO_TYPE(NODE) \\\n  (((tree_frame_info *) FUNCFRAME_INFO_CHECK (NODE))->frame_type)\n\n/* Language-dependent contents of an identifier.  */\n\nstruct GTY(()) lang_identifier\n{\n  struct tree_identifier common;\n\n  /* The identifier as the user sees it.  */\n  tree pretty_ident;\n\n  /* The back-end tree associated with this identifier.  */\n  tree decl_tree;\n\n  /* The frontend Declaration associated with this identifier.  */\n  Declaration * GTY((skip)) dsymbol;\n  AggregateDeclaration * GTY((skip)) daggregate;\n};\n\n#define IDENTIFIER_LANG_SPECIFIC(NODE) \\\n  ((struct lang_identifier *) IDENTIFIER_NODE_CHECK (NODE))\n\n#define IDENTIFIER_PRETTY_NAME(NODE) \\\n  (IDENTIFIER_LANG_SPECIFIC (NODE)->pretty_ident)\n\n#define IDENTIFIER_DECL_TREE(NODE) \\\n  (IDENTIFIER_LANG_SPECIFIC (NODE)->decl_tree)\n\n#define IDENTIFIER_DSYMBOL(NODE) \\\n  (IDENTIFIER_LANG_SPECIFIC (NODE)->dsymbol)\n\n#define IDENTIFIER_DAGGREGATE(NODE) \\\n  (IDENTIFIER_LANG_SPECIFIC (NODE)->daggregate)\n\n/* Global state pertinent to the current function.  */\n\nstruct GTY(()) language_function\n{\n  /* Our function and enclosing module.  */\n  FuncDeclaration * GTY((skip)) function;\n  Module * GTY((skip)) module;\n\n  /* Static chain of function, for D2, this is a closure.  */\n  tree static_chain;\n\n  /* Stack of statement lists being collected while we are\n     compiling the function.  */\n  vec<tree, va_gc> *stmt_list;\n\n  /* Variables that are in scope that will need destruction later.  */\n  vec<tree, va_gc> *vars_in_scope;\n\n  /* Table of all used or defined labels in the function.  */\n  hash_map<Statement *, d_label_entry> *labels;\n};\n\n/* The D front end types have not been integrated into the GCC garbage\n   collection system.  Handle this by using the \"skip\" attribute.  */\n\nstruct GTY(()) lang_decl\n{\n  Declaration * GTY((skip)) decl;\n\n  /* FIELD_DECL in frame struct that this variable is allocated in.  */\n  tree frame_field;\n\n  /* RESULT_DECL in a function that returns by nrvo.  */\n  tree named_result;\n\n  /* Chain of DECL_LANG_THUNKS in a function.  */\n  tree thunks;\n\n  /* In a FUNCTION_DECL, this is the THUNK_LANG_OFFSET.  */\n  int offset;\n\n  /* In a FUNCTION_DECL, if this is an intrinsic, the code for it.  */\n  enum intrinsic_code intrinsic;\n\n  /* FUNCFRAME_INFO in a function that has non-local references.  */\n  tree frame_info;\n};\n\n/* The current D per-function global variables.  */\n\n#define d_function_chain (cfun ? cfun->language : NULL)\n\n/* The D frontend Declaration AST for GCC decl NODE.  */\n#define DECL_LANG_FRONTEND(NODE) \\\n  (DECL_LANG_SPECIFIC (NODE) \\\n   ? DECL_LANG_SPECIFIC (NODE)->decl : NULL)\n\n#define SET_DECL_LANG_FRAME_FIELD(NODE, VAL) \\\n  DECL_LANG_SPECIFIC (NODE)->frame_field = VAL\n\n#define DECL_LANG_FRAME_FIELD(NODE) \\\n  (DECL_P (NODE) \\\n   ? DECL_LANG_SPECIFIC (NODE)->frame_field : NULL)\n\n#define SET_DECL_LANG_NRVO(NODE, VAL) \\\n  DECL_LANG_SPECIFIC (NODE)->named_result = VAL\n\n#define DECL_LANG_NRVO(NODE) \\\n  (DECL_P (NODE) \\\n   ? DECL_LANG_SPECIFIC (NODE)->named_result : NULL)\n\n#define DECL_LANG_THUNKS(NODE) \\\n  DECL_LANG_SPECIFIC (NODE)->thunks\n\n#define THUNK_LANG_OFFSET(NODE) \\\n  DECL_LANG_SPECIFIC (NODE)->offset\n\n#define DECL_INTRINSIC_CODE(NODE) \\\n  DECL_LANG_SPECIFIC (NODE)->intrinsic\n\n#define DECL_LANG_FRAMEINFO(NODE) \\\n  DECL_LANG_SPECIFIC (NODE)->frame_info\n\n/* The lang_type field is not set for every GCC type.  */\n\nstruct GTY(()) lang_type\n{\n  Type * GTY((skip)) type;\n};\n\n/* The D frontend Type AST for GCC type NODE.  */\n#define TYPE_LANG_FRONTEND(NODE) \\\n  (TYPE_LANG_SPECIFIC (NODE) \\\n   ? TYPE_LANG_SPECIFIC (NODE)->type : NULL)\n\n\nenum d_tree_node_structure_enum\n{\n  TS_D_GENERIC,\n  TS_D_IDENTIFIER,\n  TS_D_FRAMEINFO,\n  LAST_TS_D_ENUM\n};\n\n/* The resulting tree type.  */\n\nunion GTY((desc (\"d_tree_node_structure (&%h)\"),\n\t   chain_next (\"CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON)\"\n\t\t       \" ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL\")))\nlang_tree_node\n{\n  union tree_node GTY ((tag (\"TS_D_GENERIC\"),\n\t\t\tdesc (\"tree_node_structure (&%h)\"))) generic;\n  lang_identifier GTY ((tag (\"TS_D_IDENTIFIER\"))) identifier;\n  tree_frame_info GTY ((tag (\"TS_D_FRAMEINFO\"))) frameinfo;\n};\n\n/* True if the Tdelegate typed expression is not really a variable,\n   but a literal function / method reference.  */\n#define METHOD_CALL_EXPR(NODE) \\\n  (TREE_LANG_FLAG_0 (NODE))\n\n/* True if all arguments in a call expression should be evaluated in the\n   order they are given (left to right).  */\n#define CALL_EXPR_ARGS_ORDERED(NODE) \\\n  (TREE_LANG_FLAG_1 (CALL_EXPR_CHECK (NODE)))\n\n/* True if the type was declared 'shared'.  */\n#define TYPE_SHARED(NODE) \\\n  (TYPE_LANG_FLAG_0 (NODE))\n\n/* True if the type is an imaginary float type.  */\n#define TYPE_IMAGINARY_FLOAT(NODE) \\\n  (TYPE_LANG_FLAG_1 (REAL_TYPE_CHECK (NODE)))\n\n/* True if the type is an anonymous record or union.  */\n#define ANON_AGGR_TYPE_P(NODE) \\\n  (TYPE_LANG_FLAG_1 (RECORD_OR_UNION_CHECK (NODE)))\n\n/* True if the type is the underlying record for a class.  */\n#define CLASS_TYPE_P(NODE) \\\n  (TYPE_LANG_FLAG_2 (RECORD_TYPE_CHECK (NODE)))\n\n/* True if the type is a D dynamic array.  */\n#define TYPE_DYNAMIC_ARRAY(NODE) \\\n  (TYPE_LANG_FLAG_3 (RECORD_TYPE_CHECK (NODE)))\n\n/* True if the type is a D delegate.  */\n#define TYPE_DELEGATE(NODE) \\\n  (TYPE_LANG_FLAG_4 (RECORD_TYPE_CHECK (NODE)))\n\n/* True if the type is a D associative array.  */\n#define TYPE_ASSOCIATIVE_ARRAY(NODE) \\\n  (TYPE_LANG_FLAG_5 (RECORD_TYPE_CHECK (NODE)))\n\n/* True if the decl is a variable case label decl.  */\n#define LABEL_VARIABLE_CASE(NODE) \\\n  (DECL_LANG_FLAG_0 (LABEL_DECL_CHECK (NODE)))\n\n/* True if the decl is a CTFE built-in.  */\n#define DECL_BUILT_IN_CTFE(NODE) \\\n  (DECL_LANG_FLAG_0 (FUNCTION_DECL_CHECK (NODE)))\n\nenum d_tree_index\n{\n  DTI_VTABLE_ENTRY_TYPE,\n  DTI_VTBL_PTR_TYPE,\n  DTI_VTBL_INTERFACE_TYPE,\n\n  DTI_BOOL_TYPE,\n  DTI_CHAR_TYPE,\n  DTI_WCHAR_TYPE,\n  DTI_DCHAR_TYPE,\n\n  DTI_BYTE_TYPE,\n  DTI_UBYTE_TYPE,\n  DTI_SHORT_TYPE,\n  DTI_USHORT_TYPE,\n  DTI_INT_TYPE,\n  DTI_UINT_TYPE,\n  DTI_LONG_TYPE,\n  DTI_ULONG_TYPE,\n  DTI_CENT_TYPE,\n  DTI_UCENT_TYPE,\n\n  DTI_IFLOAT_TYPE,\n  DTI_IDOUBLE_TYPE,\n  DTI_IREAL_TYPE,\n\n  DTI_UNKNOWN_TYPE,\n\n  DTI_ARRAY_TYPE,\n  DTI_NULL_ARRAY,\n\n  DTI_MAX\n};\n\nextern GTY(()) tree d_global_trees[DTI_MAX];\n\n#define vtable_entry_type\t\td_global_trees[DTI_VTABLE_ENTRY_TYPE]\n#define vtbl_ptr_type_node\t\td_global_trees[DTI_VTBL_PTR_TYPE]\n#define vtbl_interface_type_node\td_global_trees[DTI_VTBL_INTERFACE_TYPE]\n/* D built-in language types.  */\n#define d_bool_type\t\t\td_global_trees[DTI_BOOL_TYPE]\n#define d_byte_type\t\t\td_global_trees[DTI_BYTE_TYPE]\n#define d_ubyte_type\t\t\td_global_trees[DTI_UBYTE_TYPE]\n#define d_short_type\t\t\td_global_trees[DTI_SHORT_TYPE]\n#define d_ushort_type\t\t\td_global_trees[DTI_USHORT_TYPE]\n#define d_int_type\t\t\td_global_trees[DTI_INT_TYPE]\n#define d_uint_type\t\t\td_global_trees[DTI_UINT_TYPE]\n#define d_long_type\t\t\td_global_trees[DTI_LONG_TYPE]\n#define d_ulong_type\t\t\td_global_trees[DTI_ULONG_TYPE]\n#define d_cent_type\t\t\td_global_trees[DTI_CENT_TYPE]\n#define d_ucent_type\t\t\td_global_trees[DTI_UCENT_TYPE]\n/* Imaginary floating-point types.  */\n#define ifloat_type_node\t\td_global_trees[DTI_IFLOAT_TYPE]\n#define idouble_type_node\t\td_global_trees[DTI_IDOUBLE_TYPE]\n#define ireal_type_node\t\t\td_global_trees[DTI_IREAL_TYPE]\n/* UTF-8, 16 and 32 types.  */\n#define char8_type_node\t\t\td_global_trees[DTI_CHAR_TYPE]\n#define char16_type_node\t\td_global_trees[DTI_DCHAR_TYPE]\n#define char32_type_node\t\td_global_trees[DTI_WCHAR_TYPE]\n/* Empty record type used as placeholder when real type is unknown.  */\n#define unknown_type_node\t\td_global_trees[DTI_UNKNOWN_TYPE]\n/* Generic dynamic array type void[].  */\n#define array_type_node\t\t\td_global_trees[DTI_ARRAY_TYPE]\n/* Null initializer for dynamic arrays.  */\n#define null_array_node\t\t\td_global_trees[DTI_NULL_ARRAY]\n\n/* A prefix for internal variables, which are not user-visible.  */\n#if !defined (NO_DOT_IN_LABEL)\n# define GDC_PREFIX(x) \"gdc.\" x\n#elif !defined (NO_DOLLAR_IN_LABEL)\n# define GDC_PREFIX(x) \"gdc$\" x\n#else\n# define GDC_PREFIX(x) \"gdc_\" x\n#endif\n\n/* Internally recognised D runtime library functions.  */\n\nenum libcall_fn\n{\n#define DEF_D_RUNTIME(CODE, N, T, P, F) LIBCALL_ ## CODE,\n\n#include \"runtime.def\"\n\n#undef DEF_D_RUNTIME\n  LIBCALL_LAST\n};\n\n/* Gate for when the D frontend makes an early call into the codegen pass, such\n   as when it requires target information or CTFE evaluation.  As full semantic\n   may not be completed, we only want to build the superficial tree structure\n   without finishing any decls or types.  */\nextern bool doing_semantic_analysis_p;\n\n/* In d-attribs.c.  */\nextern tree insert_type_attribute (tree, const char *, tree = NULL_TREE);\nextern tree insert_decl_attribute (tree, const char *, tree = NULL_TREE);\nextern tree build_attributes (Expressions *);\n\n/* In d-builtins.cc.  */\nextern const attribute_spec d_langhook_attribute_table[];\nextern const attribute_spec d_langhook_common_attribute_table[];\n\nextern tree d_builtin_function (tree);\nextern void d_init_builtins (void);\nextern void d_register_builtin_type (tree, const char *);\nextern void d_build_builtins_module (Module *);\nextern void d_maybe_set_builtin (Module *);\nextern Expression *d_eval_constant_expression (tree);\nextern void d_init_versions (void);\n\n/* In d-codegen.cc.  */\nextern location_t make_location_t (const Loc &);\nextern tree d_decl_context (Dsymbol *);\nextern tree copy_aggregate_type (tree);\nextern bool declaration_reference_p (Declaration *);\nextern tree declaration_type (Declaration *);\nextern bool argument_reference_p (Parameter *);\nextern tree type_passed_as (Parameter *);\nextern tree build_integer_cst (dinteger_t, tree = d_int_type);\nextern tree build_float_cst (const real_t &, Type *);\nextern tree d_array_length (tree);\nextern tree d_array_ptr (tree);\nextern tree d_array_value (tree, tree, tree);\nextern tree get_array_length (tree, Type *);\nextern tree build_class_binfo (tree, ClassDeclaration *);\nextern tree build_interface_binfo (tree, ClassDeclaration *, unsigned &);\nextern tree delegate_method (tree);\nextern tree delegate_object (tree);\nextern tree build_delegate_cst (tree, tree, Type *);\nextern tree build_method_call (tree, tree, Type *);\nextern void extract_from_method_call (tree, tree &, tree &);\nextern tree build_vindex_ref (tree, tree, size_t);\nextern tree d_save_expr (tree);\nextern tree stabilize_expr (tree *);\nextern tree build_target_expr (tree, tree);\nextern tree force_target_expr (tree);\nextern tree build_address (tree);\nextern tree d_mark_addressable (tree);\nextern tree d_mark_used (tree);\nextern tree d_mark_read (tree);\nextern bool identity_compare_p (StructDeclaration *);\nextern tree build_struct_comparison (tree_code, StructDeclaration *,\n\t\t\t\t     tree, tree);\nextern tree build_array_struct_comparison (tree_code, StructDeclaration *,\n\t\t\t\t\t   tree, tree, tree);\nextern tree build_struct_literal (tree, vec<constructor_elt, va_gc> *);\nextern tree component_ref (tree, tree);\nextern tree build_assign (tree_code, tree, tree);\nextern tree modify_expr (tree, tree);\nextern tree build_nop (tree, tree);\nextern tree build_vconvert (tree, tree);\nextern tree build_boolop (tree_code, tree, tree);\nextern tree build_condition (tree, tree, tree, tree);\nextern tree build_vcondition (tree, tree, tree);\nextern tree compound_expr (tree, tree);\nextern tree return_expr (tree);\nextern tree size_mult_expr (tree, tree);\nextern tree real_part (tree);\nextern tree imaginary_part (tree);\nextern tree complex_expr (tree, tree, tree);\nextern tree indirect_ref (tree, tree);\nextern tree build_deref (tree);\nextern tree build_array_index (tree, tree);\nextern tree build_offset_op (tree_code, tree, tree);\nextern tree build_offset (tree, tree);\nextern tree build_memref (tree, tree, tree);\nextern tree build_array_set (tree, tree, tree);\nextern tree build_array_from_val (Type *, tree);\nextern tree void_okay_p (tree);\nextern tree build_bounds_condition (const Loc &, tree, tree, bool);\nextern bool array_bounds_check (void);\nextern tree create_temporary_var (tree);\nextern tree maybe_temporary_var (tree, tree *);\nextern tree bind_expr (tree, tree);\nextern TypeFunction *get_function_type (Type *);\nextern bool call_by_alias_p (FuncDeclaration *, FuncDeclaration *);\nextern tree d_build_call_expr (FuncDeclaration *, tree, Expressions *);\nextern tree d_build_call (TypeFunction *, tree, tree, Expressions *);\nextern tree d_assert_call (const Loc &, libcall_fn, tree = NULL_TREE);\nextern tree build_float_modulus (tree, tree, tree);\nextern tree build_vthis_function (tree, tree);\nextern tree get_frame_for_symbol (Dsymbol *);\nextern tree build_vthis (AggregateDeclaration *);\nextern void build_closure (FuncDeclaration *);\nextern tree get_frameinfo (FuncDeclaration *);\nextern tree get_framedecl (FuncDeclaration *, FuncDeclaration *);\n\n/* In d-convert.cc.  */\nextern bool decl_with_nonnull_addr_p (const_tree);\nextern tree d_truthvalue_conversion (tree);\nextern tree d_convert (tree, tree);\nextern tree convert_expr (tree, Type *, Type *);\nextern tree convert_for_assignment (tree, Type *, Type *);\nextern tree convert_for_argument (tree, Parameter *);\nextern tree convert_for_condition (tree, Type *);\nextern tree d_array_convert (Expression *);\nextern tree d_array_convert (Type *, Expression *, vec<tree, va_gc> **);\n\n/* In d-incpath.cc.  */\nextern void add_import_paths (const char *, const char *, bool);\n\n/* In d-lang.cc.  */\nextern void d_add_builtin_module (Module *);\nextern void d_add_entrypoint_module (Module *, Module *);\nextern d_tree_node_structure_enum d_tree_node_structure (lang_tree_node *);\nextern struct lang_type *build_lang_type (Type *);\nextern struct lang_decl *build_lang_decl (Declaration *);\nextern tree d_pushdecl (tree);\nextern tree d_unsigned_type (tree);\nextern tree d_signed_type (tree);\nextern void d_keep (tree);\n\n/* In decl.cc.  */\nconst char *mangle_decl (Dsymbol *);\nextern tree mangle_internal_decl (Dsymbol *, const char *, const char *);\nextern void build_decl_tree (Dsymbol *);\nextern tree get_symbol_decl (Declaration *);\nextern tree declare_extern_var (tree, tree);\nextern void declare_local_var (VarDeclaration *);\nextern tree build_local_temp (tree);\nextern tree get_decl_tree (Declaration *);\nextern void d_finish_decl (tree);\nextern tree make_thunk (FuncDeclaration *, int);\nextern tree start_function (FuncDeclaration *);\nextern void finish_function (tree);\nextern void mark_needed (tree);\nextern unsigned base_vtable_offset (ClassDeclaration *, BaseClass *);\nextern tree get_vtable_decl (ClassDeclaration *);\nextern tree build_new_class_expr (ClassReferenceExp *);\nextern tree aggregate_initializer_decl (AggregateDeclaration *);\nextern tree layout_struct_initializer (StructDeclaration *);\nextern tree layout_class_initializer (ClassDeclaration *);\nextern tree enum_initializer_decl (EnumDeclaration *);\nextern tree build_artificial_decl (tree, tree, const char * = NULL);\nextern tree create_field_decl (tree, const char *, int, int);\nextern void build_type_decl (tree, Dsymbol *);\nextern void d_comdat_linkage (tree);\nextern void d_linkonce_linkage (tree);\n\n/* In expr.cc.  */\nextern tree build_expr (Expression *, bool = false);\nextern tree build_expr_dtor (Expression *);\nextern tree build_return_dtor (Expression *, Type *, TypeFunction *);\n\n/* In imports.cc.  */\nextern tree build_import_decl (Dsymbol *);\n\n/* In intrinsics.cc.  */\nextern void maybe_set_intrinsic (FuncDeclaration *);\nextern tree maybe_expand_intrinsic (tree);\n\n/* In modules.cc.  */\nextern void build_module_tree (Module *);\nextern tree d_module_context (void);\nextern void register_module_decl (Declaration *);\nextern void d_finish_compilation (tree *, int);\n\n/* In runtime.cc.  */\nextern tree build_libcall (libcall_fn, Type *, int ...);\n\n/* In typeinfo.cc.  */\nextern bool have_typeinfo_p (ClassDeclaration *);\nextern tree layout_typeinfo (TypeInfoDeclaration *);\nextern tree layout_classinfo (ClassDeclaration *);\nextern tree get_typeinfo_decl (TypeInfoDeclaration *);\nextern tree get_classinfo_decl (ClassDeclaration *);\nextern tree build_typeinfo (const Loc &, Type *);\nextern void create_typeinfo (Type *, Module *);\nextern void create_tinfo_types (Module *);\nextern void layout_cpp_typeinfo (ClassDeclaration *);\nextern tree get_cpp_typeinfo_decl (ClassDeclaration *);\nextern bool speculative_type_p (Type *);\n\n/* In toir.cc.  */\nextern void push_binding_level (level_kind);\nextern tree pop_binding_level (void);\nextern void push_stmt_list (void);\nextern tree pop_stmt_list (void);\nextern void add_stmt (tree);\nextern void build_function_body (FuncDeclaration *);\n\n/* In types.cc.  */\nextern bool valist_array_p (Type *);\nextern bool empty_aggregate_p (tree);\nextern bool same_type_p (Type *, Type *);\nextern Type *get_object_type (void);\nextern tree make_array_type (Type *, unsigned HOST_WIDE_INT);\nextern tree make_struct_type (const char *, int n, ...);\nextern tree insert_type_modifiers (tree, unsigned);\nextern void insert_aggregate_field (tree, tree, size_t);\nextern void finish_aggregate_type (unsigned, unsigned, tree,\n\t\t\t\t   UserAttributeDeclaration *);\nextern tree build_ctype (Type *);\n\n#endif  /* GCC_D_TREE_H  */\n"
  },
  {
    "path": "gcc/d/decl.cc",
    "content": "/* decl.cc -- Lower D frontend declarations to GCC trees.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/aggregate.h\"\n#include \"dmd/attrib.h\"\n#include \"dmd/ctfe.h\"\n#include \"dmd/declaration.h\"\n#include \"dmd/enum.h\"\n#include \"dmd/errors.h\"\n#include \"dmd/globals.h\"\n#include \"dmd/hdrgen.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/import.h\"\n#include \"dmd/init.h\"\n#include \"dmd/mangle.h\"\n#include \"dmd/module.h\"\n#include \"dmd/nspace.h\"\n#include \"dmd/target.h\"\n#include \"dmd/template.h\"\n\n#include \"tree.h\"\n#include \"tree-iterator.h\"\n#include \"fold-const.h\"\n#include \"diagnostic.h\"\n#include \"langhooks.h\"\n#include \"target.h\"\n#include \"common/common-target.h\"\n#include \"cgraph.h\"\n#include \"toplev.h\"\n#include \"stringpool.h\"\n#include \"varasm.h\"\n#include \"stor-layout.h\"\n#include \"attribs.h\"\n#include \"function.h\"\n#include \"debug.h\"\n#include \"tree-pretty-print.h\"\n\n#include \"d-tree.h\"\n\n\n/* Return identifier for the external mangled name of DECL.  */\n\nconst char *\nmangle_decl (Dsymbol *decl)\n{\n  if (decl->isFuncDeclaration ())\n    return mangleExact ((FuncDeclaration *)decl);\n  else\n    {\n      OutBuffer buf;\n      mangleToBuffer (decl, &buf);\n      return buf.extractString ();\n    }\n}\n\n/* Generate a mangled identifier using NAME and SUFFIX, prefixed by the\n   assembler name for DECL.  */\n\ntree\nmangle_internal_decl (Dsymbol *decl, const char *name, const char *suffix)\n{\n  const char *prefix = mangle_decl (decl);\n  unsigned namelen = strlen (name);\n  unsigned buflen = (2 + strlen (prefix) + namelen + strlen (suffix)) * 2;\n  char *buf = (char *) alloca (buflen);\n\n  snprintf (buf, buflen, \"_D%s%u%s%s\", prefix, namelen, name, suffix);\n  tree ident = get_identifier (buf);\n\n  /* Symbol is not found in user code, but generate a readable name for it\n     anyway for debug and diagnostic reporting.  */\n  snprintf (buf, buflen, \"%s.%s\", decl->toPrettyChars (), name);\n  IDENTIFIER_PRETTY_NAME (ident) = get_identifier (buf);\n\n  return ident;\n}\n\n/* Returns true if DECL is from the gcc.attribute module.  */\n\nstatic bool\ngcc_attribute_p (Dsymbol *decl)\n{\n  ModuleDeclaration *md = decl->getModule ()->md;\n\n  if (md && md->packages && md->packages->dim == 1)\n    {\n      if (!strcmp ((*md->packages)[0]->toChars (), \"gcc\")\n\t  && !strcmp (md->id->toChars (), \"attribute\"))\n\treturn true;\n    }\n\n  return false;\n}\n\n/* Subroutine of pragma declaration visitor for marking the function in the\n   defined in SYM as a global constructor or destructor.  If ISCTOR is true,\n   then we're applying pragma(crt_constructor).  */\n\nstatic int\napply_pragma_crt (Dsymbol *sym, bool isctor)\n{\n  AttribDeclaration *ad = sym->isAttribDeclaration ();\n  if (ad != NULL)\n    {\n      int nested = 0;\n\n      /* Walk all declarations of the attribute scope.  */\n      Dsymbols *ds = ad->include (NULL);\n      if (ds)\n\t{\n\t  for (size_t i = 0; i < ds->dim; i++)\n\t    nested += apply_pragma_crt ((*ds)[i], isctor);\n\t}\n\n      return nested;\n    }\n\n  FuncDeclaration *fd = sym->isFuncDeclaration ();\n  if (fd != NULL)\n    {\n      tree decl = get_decl_tree (fd);\n\n      /* Apply flags to the function.  */\n      if (isctor)\n\t{\n\t  DECL_STATIC_CONSTRUCTOR (decl) = 1;\n\t  decl_init_priority_insert (decl, DEFAULT_INIT_PRIORITY);\n\t}\n      else\n\t{\n\t  DECL_STATIC_DESTRUCTOR (decl) = 1;\n\t  decl_fini_priority_insert (decl, DEFAULT_INIT_PRIORITY);\n\t}\n\n      if (fd->linkage != LINKc)\n\t{\n\t  error_at (make_location_t (fd->loc),\n\t\t    \"must be %<extern(C)%> for %<pragma(%s)%>\",\n\t\t    isctor ? \"crt_constructor\" : \"crt_destructor\");\n\t}\n\n      return 1;\n    }\n\n  return 0;\n}\n\n/* Implements the visitor interface to lower all Declaration AST classes\n   emitted from the D Front-end to GCC trees.\n   All visit methods accept one parameter D, which holds the frontend AST\n   of the declaration to compile.  These also don't return any value, instead\n   generated code are appened to global_declarations or added to the\n   current_binding_level by d_pushdecl().  */\n\nclass DeclVisitor : public Visitor\n{\n  using Visitor::visit;\n\npublic:\n  DeclVisitor (void)\n  {\n  }\n\n  /* This should be overridden by each declaration class.  */\n\n  void visit (Dsymbol *)\n  {\n  }\n\n  /* Compile a D module, and all members of it.  */\n\n  void visit (Module *d)\n  {\n    if (d->semanticRun >= PASSobj)\n      return;\n\n    build_module_tree (d);\n    d->semanticRun = PASSobj;\n  }\n\n  /* Write the imported symbol to debug.  */\n\n  void visit (Import *d)\n  {\n    /* Implements import declarations by telling the debug back-end we are\n       importing the NAMESPACE_DECL of the module or IMPORTED_DECL of the\n       declaration into the current lexical scope CONTEXT.  NAME is set if\n       this is a renamed import.  */\n    if (d->isstatic)\n      return;\n\n    /* Get the context of this import, this should never be null.  */\n    tree context = d_module_context ();\n\n    if (d->ident == NULL)\n      {\n\t/* Importing declaration list.  */\n\tfor (size_t i = 0; i < d->names.dim; i++)\n\t  {\n\t    AliasDeclaration *aliasdecl = d->aliasdecls[i];\n\t    tree decl = build_import_decl (aliasdecl);\n\n\t    /* Skip over unhandled imports.  */\n\t    if (decl == NULL_TREE)\n\t      continue;\n\n\t    Identifier *alias = d->aliases[i];\n\t    tree name = (alias != NULL)\n\t      ? get_identifier (alias->toChars ()) : NULL_TREE;\n\n\t    debug_hooks->imported_module_or_decl (decl, name, context,\n\t\t\t\t\t\t  false, false);\n\t  }\n      }\n    else\n      {\n\t/* Importing the entire module.  */\n\ttree decl = build_import_decl (d->mod);\n\n\ttree name = (d->aliasId != NULL)\n\t  ? get_identifier (d->aliasId->toChars ()) : NULL_TREE;\n\n\tdebug_hooks->imported_module_or_decl (decl, name, context,\n\t\t\t\t\t      false, false);\n      }\n  }\n\n  /* Expand any local variables found in tuples.  */\n\n  void visit (TupleDeclaration *d)\n  {\n    for (size_t i = 0; i < d->objects->dim; i++)\n      {\n\tRootObject *o = (*d->objects)[i];\n\tif ((o->dyncast () == DYNCAST_EXPRESSION)\n\t    && ((Expression *) o)->op == TOKdsymbol)\n\t  {\n\t    Declaration *d = ((DsymbolExp *) o)->s->isDeclaration ();\n\t    if (d)\n\t      d->accept (this);\n\t  }\n      }\n  }\n\n  /* Walk over all declarations in the attribute scope.  */\n\n  void visit (AttribDeclaration *d)\n  {\n    Dsymbols *ds = d->include (NULL);\n\n    if (!ds)\n      return;\n\n    for (size_t i = 0; i < ds->dim; i++)\n      {\n\tDsymbol *s = (*ds)[i];\n\ts->accept (this);\n      }\n  }\n\n  /* Pragmas are a way to pass special information to the compiler and to add\n     vendor specific extensions to D.  */\n\n  void visit (PragmaDeclaration *d)\n  {\n    if (!global.params.ignoreUnsupportedPragmas)\n      {\n\tif (d->ident == Identifier::idPool (\"lib\")\n\t    || d->ident == Identifier::idPool (\"startaddress\"))\n\t  {\n\t    warning_at (make_location_t (d->loc), OPT_Wunknown_pragmas,\n\t\t\t\"pragma(%s) not implemented\", d->ident->toChars ());\n\t  }\n      }\n\n    visit ((AttribDeclaration *) d);\n\n    /* Handle pragma(crt_constructor) and pragma(crt_destructor).  Apply flag\n       to indicate that the functions enclosed should run automatically at the\n       beginning or end of execution.  */\n    if (d->ident == Identifier::idPool (\"crt_constructor\")\n\t|| d->ident == Identifier::idPool (\"crt_destructor\"))\n      {\n\tbool isctor = (d->ident == Identifier::idPool (\"crt_constructor\"));\n\n\tif (apply_pragma_crt (d, isctor) > 1)\n\t  error_at (make_location_t (d->loc),\n\t\t    \"can only apply to a single declaration\");\n      }\n  }\n\n  /* Walk over all members in the namespace scope.  */\n\n  void visit (Nspace *d)\n  {\n    if (isError (d) || !d->members)\n      return;\n\n    for (size_t i = 0; i < d->members->dim; i++)\n      {\n\tDsymbol *s = (*d->members)[i];\n\ts->accept (this);\n      }\n  }\n\n  /* Walk over all members in the instantiated template.  */\n\n  void visit (TemplateInstance *d)\n  {\n    if (isError (d)|| !d->members)\n      return;\n\n    if (!d->needsCodegen ())\n      return;\n\n    for (size_t i = 0; i < d->members->dim; i++)\n      {\n\tDsymbol *s = (*d->members)[i];\n\ts->accept (this);\n      }\n  }\n\n  /* Walk over all members in the mixin template scope.  */\n\n  void visit (TemplateMixin *d)\n  {\n    if (isError (d)|| !d->members)\n      return;\n\n    for (size_t i = 0; i < d->members->dim; i++)\n      {\n\tDsymbol *s = (*d->members)[i];\n\ts->accept (this);\n      }\n  }\n\n  /* Write out compiler generated TypeInfo, initializer and functions for the\n     given struct declaration, walking over all static members.  */\n\n  void visit (StructDeclaration *d)\n  {\n    if (d->type->ty == Terror)\n      {\n\terror_at (make_location_t (d->loc),\n\t\t  \"had semantic errors when compiling\");\n\treturn;\n      }\n\n    /* Add this decl to the current binding level.  */\n    tree ctype = build_ctype (d->type);\n    if (TYPE_NAME (ctype))\n      d_pushdecl (TYPE_NAME (ctype));\n\n    /* Anonymous structs/unions only exist as part of others,\n       do not output forward referenced structs.  */\n    if (d->isAnonymous () || !d->members)\n      return;\n\n    /* Don't emit any symbols from gcc.attribute module.  */\n    if (gcc_attribute_p (d))\n      return;\n\n    /* Generate TypeInfo.  */\n    if (have_typeinfo_p (Type::dtypeinfo))\n      create_typeinfo (d->type, NULL);\n\n    /* Generate static initializer.  */\n    d->sinit = aggregate_initializer_decl (d);\n    DECL_INITIAL (d->sinit) = layout_struct_initializer (d);\n\n    if (d->isInstantiated ())\n      d_linkonce_linkage (d->sinit);\n\n    d_finish_decl (d->sinit);\n\n    /* Put out the members.  */\n    for (size_t i = 0; i < d->members->dim; i++)\n      {\n\tDsymbol *member = (*d->members)[i];\n\t/* There might be static ctors in the members, and they cannot\n\t   be put in separate object files.  */\n\tmember->accept (this);\n      }\n\n    /* Put out xopEquals, xopCmp and xopHash.  */\n    if (d->xeq && d->xeq != d->xerreq)\n      d->xeq->accept (this);\n\n    if (d->xcmp && d->xcmp != d->xerrcmp)\n      d->xcmp->accept (this);\n\n    if (d->xhash)\n      d->xhash->accept (this);\n  }\n\n  /* Finish semantic analysis of functions in vtbl for class CD.  */\n\n  bool finish_vtable (ClassDeclaration *d)\n  {\n    bool has_errors = false;\n\n    /* Finish semantic analysis of functions in vtbl[].  */\n    for (size_t i = d->vtblOffset (); i < d->vtbl.dim; i++)\n      {\n\tFuncDeclaration *fd = d->vtbl[i]->isFuncDeclaration ();\n\n\tif (!fd || (!fd->fbody && d->isAbstract ()))\n\t  continue;\n\n\t/* Ensure function has a return value.  */\n\tif (!fd->functionSemantic ())\n\t  has_errors = true;\n\n\t/* No name hiding to check for.  */\n\tif (!d->isFuncHidden (fd) || fd->isFuture ())\n\t  continue;\n\n\t/* The function fd is hidden from the view of the class.\n\t   If it overlaps with any function in the vtbl[], then\n\t   issue an error.  */\n\tfor (size_t j = 1; j < d->vtbl.dim; j++)\n\t  {\n\t    if (j == i)\n\t      continue;\n\n\t    FuncDeclaration *fd2 = d->vtbl[j]->isFuncDeclaration ();\n\t    if (!fd2->ident->equals (fd->ident))\n\t      continue;\n\n\t    /* The function is marked as @__future, a deprecation has\n\t       already been given by the frontend.  */\n\t    if (fd2->isFuture ())\n\t      continue;\n\n\t    if (fd->leastAsSpecialized (fd2) || fd2->leastAsSpecialized (fd))\n\t      {\n\t\tTypeFunction *tf = (TypeFunction *) fd->type;\n\t\tif (tf->ty == Tfunction)\n\t\t  {\n\t\t    error_at (make_location_t (fd->loc), \"use of %qs\",\n\t\t\t      fd->toPrettyChars ());\n\t\t    inform (make_location_t (fd2->loc), \"is hidden by %qs\",\n\t\t\t    fd2->toPrettyChars ());\n\t\t    inform (make_location_t (d->loc),\n\t\t\t    \"use %<alias %s = %s.%s;%> to introduce base class \"\n\t\t\t    \"overload set.\", fd->toChars (),\n\t\t\t    fd->parent->toChars (), fd->toChars ());\n\t\t  }\n\t\telse\n\t\t  {\n\t\t    error_at (make_location_t (fd->loc), \"use of %qs\",\n\t\t\t      fd->toPrettyChars ());\n\t\t    inform (make_location_t (fd2->loc), \"is hidden by %qs\",\n\t\t\t      fd2->toPrettyChars ());\n\t\t  }\n\n\t\thas_errors = true;\n\t\tbreak;\n\t      }\n\t  }\n      }\n\n    return !has_errors;\n  }\n\n  /* Write out compiler generated TypeInfo, initializer and vtables for the\n     given class declaration, walking over all static members.  */\n\n  void visit (ClassDeclaration *d)\n  {\n    if (d->type->ty == Terror)\n      {\n\terror_at (make_location_t (d->loc),\n\t\t  \"had semantic errors when compiling\");\n\treturn;\n      }\n\n    if (!d->members)\n      return;\n\n    /* Put out the members.  */\n    for (size_t i = 0; i < d->members->dim; i++)\n      {\n\tDsymbol *member = (*d->members)[i];\n\tmember->accept (this);\n      }\n\n    /* If something goes wrong during final semantic pass, don't bother with\n       the rest as we may have incomplete info.  */\n    if (!this->finish_vtable (d))\n      return;\n\n    /* Generate C symbols.  */\n    d->csym = get_classinfo_decl (d);\n    Dsymbol *vtblsym = d->vtblSymbol ();\n    vtblsym->csym = get_vtable_decl (d);\n    d->sinit = aggregate_initializer_decl (d);\n\n    /* Generate static initializer.  */\n    DECL_INITIAL (d->sinit) = layout_class_initializer (d);\n    d_linkonce_linkage (d->sinit);\n    d_finish_decl (d->sinit);\n\n    /* Put out the TypeInfo.  */\n    if (have_typeinfo_p (Type::dtypeinfo))\n      create_typeinfo (d->type, NULL);\n\n    DECL_INITIAL (d->csym) = layout_classinfo (d);\n    d_linkonce_linkage (d->csym);\n    d_finish_decl (d->csym);\n\n    /* Put out the vtbl[].  */\n    vec<constructor_elt, va_gc> *elms = NULL;\n\n    /* First entry is ClassInfo reference.  */\n    if (d->vtblOffset ())\n      CONSTRUCTOR_APPEND_ELT (elms, size_zero_node, build_address (d->csym));\n\n    for (size_t i = d->vtblOffset (); i < d->vtbl.dim; i++)\n      {\n\tFuncDeclaration *fd = d->vtbl[i]->isFuncDeclaration ();\n\n\tif (fd && (fd->fbody || !d->isAbstract ()))\n\t  {\n\t    CONSTRUCTOR_APPEND_ELT (elms, size_int (i),\n\t\t\t\t    build_address (get_symbol_decl (fd)));\n\t  }\n      }\n\n    DECL_INITIAL (vtblsym->csym)\n      = build_constructor (TREE_TYPE (vtblsym->csym), elms);\n    d_comdat_linkage (vtblsym->csym);\n    d_finish_decl (vtblsym->csym);\n\n    /* Add this decl to the current binding level.  */\n    tree ctype = TREE_TYPE (build_ctype (d->type));\n    if (TYPE_NAME (ctype))\n      d_pushdecl (TYPE_NAME (ctype));\n  }\n\n  /* Write out compiler generated TypeInfo and vtables for the given interface\n     declaration, walking over all static members.  */\n\n  void visit (InterfaceDeclaration *d)\n  {\n    if (d->type->ty == Terror)\n      {\n\terror_at (make_location_t (d->loc),\n\t\t  \"had semantic errors when compiling\");\n\treturn;\n      }\n\n    if (!d->members)\n      return;\n\n    /* Put out the members.  */\n    for (size_t i = 0; i < d->members->dim; i++)\n      {\n\tDsymbol *member = (*d->members)[i];\n\tmember->accept (this);\n      }\n\n    /* Generate C symbols.  */\n    d->csym = get_classinfo_decl (d);\n\n    /* Put out the TypeInfo.  */\n    if (have_typeinfo_p (Type::dtypeinfo))\n      {\n\tcreate_typeinfo (d->type, NULL);\n\td->type->vtinfo->accept (this);\n      }\n\n    DECL_INITIAL (d->csym) = layout_classinfo (d);\n    d_linkonce_linkage (d->csym);\n    d_finish_decl (d->csym);\n\n    /* Add this decl to the current binding level.  */\n    tree ctype = TREE_TYPE (build_ctype (d->type));\n    if (TYPE_NAME (ctype))\n      d_pushdecl (TYPE_NAME (ctype));\n  }\n\n  /* Write out compiler generated TypeInfo and initializer for the given\n     enum declaration.  */\n\n  void visit (EnumDeclaration *d)\n  {\n    if (d->semanticRun >= PASSobj)\n      return;\n\n    if (d->errors || d->type->ty == Terror)\n      {\n\terror_at (make_location_t (d->loc),\n\t\t  \"had semantic errors when compiling\");\n\treturn;\n      }\n\n    if (d->isAnonymous ())\n      return;\n\n    /* Generate TypeInfo.  */\n    if (have_typeinfo_p (Type::dtypeinfo))\n      create_typeinfo (d->type, NULL);\n\n    TypeEnum *tc = (TypeEnum *) d->type;\n    if (tc->sym->members && !d->type->isZeroInit ())\n      {\n\t/* Generate static initializer.  */\n\td->sinit = enum_initializer_decl (d);\n\tDECL_INITIAL (d->sinit) = build_expr (tc->sym->defaultval, true);\n\n\tif (d->isInstantiated ())\n\t  d_linkonce_linkage (d->sinit);\n\n\td_finish_decl (d->sinit);\n\n\t/* Add this decl to the current binding level.  */\n\ttree ctype = build_ctype (d->type);\n\tif (TREE_CODE (ctype) == ENUMERAL_TYPE && TYPE_NAME (ctype))\n\t  d_pushdecl (TYPE_NAME (ctype));\n      }\n\n    d->semanticRun = PASSobj;\n  }\n\n  /* Finish up a variable declaration and push it into the current scope.\n     This can either be a static, local or manifest constant.  */\n\n  void visit (VarDeclaration *d)\n  {\n    if (d->type->ty == Terror)\n      {\n\terror_at (make_location_t (d->loc),\n\t\t  \"had semantic errors when compiling\");\n\treturn;\n      }\n\n    if (d->aliassym)\n      {\n\td->toAlias ()->accept (this);\n\treturn;\n      }\n\n    /* Do not store variables we cannot take the address of,\n       but keep the values for purposes of debugging.  */\n    if (!d->canTakeAddressOf ())\n      {\n\t/* Don't know if there is a good way to handle instantiations.  */\n\tif (d->isInstantiated ())\n\t  return;\n\n\ttree decl = get_symbol_decl (d);\n\tgcc_assert (d->_init && !d->_init->isVoidInitializer ());\n\tExpression *ie = initializerToExpression (d->_init);\n\n\t/* CONST_DECL was initially intended for enumerals and may be used for\n\t   scalars in general, but not for aggregates.  Here a non-constant\n\t   value is generated anyway so as the CONST_DECL only serves as a\n\t   placeholder for the value, however the DECL itself should never be\n\t   referenced in any generated code, or passed to the back-end.  */\n\tif (!d->type->isscalar ())\n\t  DECL_INITIAL (decl) = build_expr (ie, false);\n\telse\n\t  {\n\t    DECL_INITIAL (decl) = build_expr (ie, true);\n\t    d_pushdecl (decl);\n\t    rest_of_decl_compilation (decl, 1, 0);\n\t  }\n      }\n    else if (d->isDataseg () && !(d->storage_class & STCextern))\n      {\n\ttree decl = get_symbol_decl (d);\n\n\t/* Duplicated VarDeclarations map to the same symbol.  Check if this\n\t   is the one declaration which will be emitted.  */\n\ttree ident = DECL_ASSEMBLER_NAME (decl);\n\tif (IDENTIFIER_DSYMBOL (ident) && IDENTIFIER_DSYMBOL (ident) != d)\n\t  return;\n\n\t/* How big a symbol can be should depend on back-end.  */\n\ttree size = build_integer_cst (d->type->size (d->loc),\n\t\t\t\t       build_ctype (Type::tsize_t));\n\tif (!valid_constant_size_p (size))\n\t  {\n\t    error_at (make_location_t (d->loc), \"size is too large\");\n\t    return;\n\t  }\n\n\tif (d->_init && !d->_init->isVoidInitializer ())\n\t  {\n\t    Expression *e = initializerToExpression (d->_init, d->type);\n\t    DECL_INITIAL (decl) = build_expr (e, true);\n\t  }\n\telse\n\t  {\n\t    if (d->type->ty == Tstruct)\n\t      {\n\t\tStructDeclaration *sd = ((TypeStruct *) d->type)->sym;\n\t\tDECL_INITIAL (decl) = layout_struct_initializer (sd);\n\t      }\n\t    else\n\t      {\n\t\tExpression *e = d->type->defaultInitLiteral (d->loc);\n\t\tDECL_INITIAL (decl) = build_expr (e, true);\n\t      }\n\t  }\n\n\t/* Frontend should have already caught this.  */\n\tgcc_assert (!integer_zerop (size)\n\t\t    || d->type->toBasetype ()->ty == Tsarray);\n\n\td_finish_decl (decl);\n\n\t/* Maybe record the var against the current module.  */\n\tregister_module_decl (d);\n      }\n    else if (!d->isDataseg () && !d->isMember ())\n      {\n\t/* This is needed for VarDeclarations in mixins that are to be local\n\t   variables of a function.  Otherwise, it would be enough to make\n\t   a check for isVarDeclaration() in DeclarationExp codegen.  */\n\tdeclare_local_var (d);\n\n\tif (d->_init)\n\t  {\n\t    tree decl = get_symbol_decl (d);\n\n\t    if (!d->_init->isVoidInitializer ())\n\t      {\n\t\tExpInitializer *vinit = d->_init->isExpInitializer ();\n\t\tExpression *ie = initializerToExpression (vinit);\n\t\ttree exp = build_expr (ie);\n\n\t\t/* Maybe put variable on list of things needing destruction.  */\n\t\tif (d->needsScopeDtor ())\n\t\t  {\n\t\t    vec_safe_push (d_function_chain->vars_in_scope, decl);\n\t\t    /* Force a TARGET_EXPR to add the corresponding cleanup.  */\n\t\t    exp = force_target_expr (compound_expr (exp, decl));\n\t\t    TARGET_EXPR_CLEANUP (exp) = build_expr (d->edtor);\n\t\t  }\n\n\t\tadd_stmt (exp);\n\t      }\n\t    else if (d->size (d->loc) != 0)\n\t      {\n\t\t/* Zero-length arrays do not have an initializer.  */\n\t\twarning (OPT_Wuninitialized, \"uninitialized variable '%s'\",\n\t\t\t d->ident ? d->ident->toChars () : \"(no name)\");\n\t      }\n\t  }\n      }\n  }\n\n  /* Generate and compile a static TypeInfo declaration, but only if it is\n     needed in the current compilation.  */\n\n  void visit (TypeInfoDeclaration *d)\n  {\n    if (speculative_type_p (d->tinfo))\n      return;\n\n    tree t = get_typeinfo_decl (d);\n    DECL_INITIAL (t) = layout_typeinfo (d);\n    d_finish_decl (t);\n  }\n\n  /* Finish up a function declaration and compile it all the way\n     down to assembler language output.  */\n\n  void visit (FuncDeclaration *d)\n  {\n    /* Already generated the function.  */\n    if (d->semanticRun >= PASSobj)\n      return;\n\n    /* Don't emit any symbols from gcc.attribute module.  */\n    if (gcc_attribute_p (d))\n      return;\n\n    /* Not emitting unittest functions.  */\n    if (!global.params.useUnitTests && d->isUnitTestDeclaration ())\n      return;\n\n    /* Check if any errors occurred when running semantic.  */\n    if (d->type->ty == Tfunction)\n      {\n\tTypeFunction *tf = (TypeFunction *) d->type;\n\tif (tf->next == NULL || tf->next->ty == Terror)\n\t  return;\n      }\n\n    if (d->semantic3Errors)\n      return;\n\n    if (d->isNested ())\n      {\n\tFuncDeclaration *fdp = d;\n\twhile (fdp && fdp->isNested ())\n\t  {\n\t    fdp = fdp->toParent2 ()->isFuncDeclaration ();\n\n\t    if (fdp == NULL)\n\t      break;\n\n\t    /* Parent failed to compile, but errors were gagged.  */\n\t    if (fdp->semantic3Errors)\n\t      return;\n\t  }\n      }\n\n    /* Ensure all semantic passes have run.  */\n    if (d->semanticRun < PASSsemantic3)\n      {\n\td->functionSemantic3 ();\n\tModule::runDeferredSemantic3 ();\n      }\n\n    if (global.errors)\n      return;\n\n    /* Duplicated FuncDeclarations map to the same symbol.  Check if this\n       is the one declaration which will be emitted.  */\n    tree fndecl = get_symbol_decl (d);\n    tree ident = DECL_ASSEMBLER_NAME (fndecl);\n    if (IDENTIFIER_DSYMBOL (ident) && IDENTIFIER_DSYMBOL (ident) != d)\n      return;\n\n    if (!d->fbody)\n      {\n\trest_of_decl_compilation (fndecl, 1, 0);\n\treturn;\n      }\n\n    if (global.params.verbose)\n      message (\"function  %s\", d->toPrettyChars ());\n\n    /* Start generating code for this function.  */\n    gcc_assert (d->semanticRun == PASSsemantic3done);\n    d->semanticRun = PASSobj;\n\n    tree old_context = start_function (d);\n\n    tree parm_decl = NULL_TREE;\n    tree param_list = NULL_TREE;\n\n    /* Special arguments...  */\n\n    /* 'this' parameter:\n       For nested functions, D still generates a vthis, but it\n       should not be referenced in any expression.  */\n    if (d->vthis)\n      {\n\tparm_decl = get_symbol_decl (d->vthis);\n\tDECL_ARTIFICIAL (parm_decl) = 1;\n\tTREE_READONLY (parm_decl) = 1;\n\n\tif (d->vthis->type == Type::tvoidptr)\n\t  {\n\t    /* Replace generic pointer with back-end closure type\n\t       (this wins for gdb).  */\n\t    tree frame_type = FRAMEINFO_TYPE (get_frameinfo (d));\n\t    gcc_assert (frame_type != NULL_TREE);\n\t    TREE_TYPE (parm_decl) = build_pointer_type (frame_type);\n\t  }\n\n\tparam_list = chainon (param_list, parm_decl);\n\td_function_chain->static_chain = parm_decl;\n      }\n\n    /* _arguments parameter.  */\n    if (d->v_arguments)\n      {\n\tparm_decl = get_symbol_decl (d->v_arguments);\n\tparam_list = chainon (param_list, parm_decl);\n      }\n\n    /* formal function parameters.  */\n    size_t n_parameters = d->parameters ? d->parameters->dim : 0;\n\n    for (size_t i = 0; i < n_parameters; i++)\n      {\n\tVarDeclaration *param = (*d->parameters)[i];\n\tparm_decl = get_symbol_decl (param);\n\t/* Chain them in the correct order.  */\n\tparam_list = chainon (param_list, parm_decl);\n      }\n\n    DECL_ARGUMENTS (fndecl) = param_list;\n    rest_of_decl_compilation (fndecl, 1, 0);\n\n    /* If this is a member function that nested (possibly indirectly) in another\n       function, construct an expession for this member function's static chain\n       by going through parent link of nested classes.  */\n    if (d->isThis ())\n      {\n\tAggregateDeclaration *ad = d->isThis ();\n\ttree this_tree = get_symbol_decl (d->vthis);\n\n\twhile (ad->isNested ())\n\t  {\n\t    Dsymbol *pd = ad->toParent2 ();\n\t    tree vthis_field = get_symbol_decl (ad->vthis);\n\t    this_tree = component_ref (build_deref (this_tree), vthis_field);\n\n\t    ad = pd->isAggregateDeclaration ();\n\t    if (ad == NULL)\n\t      {\n\t\tcfun->language->static_chain = this_tree;\n\t\tbreak;\n\t      }\n\t  }\n      }\n\n    /* May change cfun->static_chain.  */\n    build_closure (d);\n\n    if (d->vresult)\n      declare_local_var (d->vresult);\n\n    if (d->v_argptr)\n      push_stmt_list ();\n\n    /* Named return value optimisation support for D.\n       Implemented by overriding all the RETURN_EXPRs and replacing all\n       occurrences of VAR with the RESULT_DECL for the function.\n       This is only worth doing for functions that can return in memory.  */\n    if (d->nrvo_can)\n      {\n\ttree restype = TREE_TYPE (DECL_RESULT (fndecl));\n\n\tif (!AGGREGATE_TYPE_P (restype))\n\t  d->nrvo_can = 0;\n\telse\n\t  d->nrvo_can = aggregate_value_p (restype, fndecl);\n      }\n\n    if (d->nrvo_can)\n      {\n\ttree resdecl = DECL_RESULT (fndecl);\n\n\tTREE_TYPE (resdecl)\n\t  = build_reference_type (TREE_TYPE (resdecl));\n\tDECL_BY_REFERENCE (resdecl) = 1;\n\tTREE_ADDRESSABLE (resdecl) = 0;\n\trelayout_decl (resdecl);\n\n\tif (d->nrvo_var)\n\t  {\n\t    tree var = get_symbol_decl (d->nrvo_var);\n\n\t    /* Copy name from VAR to RESULT.  */\n\t    DECL_NAME (resdecl) = DECL_NAME (var);\n\t    /* Don't forget that we take its address.  */\n\t    TREE_ADDRESSABLE (var) = 1;\n\t    resdecl = build_deref (resdecl);\n\n\t    SET_DECL_VALUE_EXPR (var, resdecl);\n\t    DECL_HAS_VALUE_EXPR_P (var) = 1;\n\t    SET_DECL_LANG_NRVO (var, resdecl);\n\t  }\n      }\n\n    build_function_body (d);\n\n    /* Initialize the _argptr variable.  */\n    if (d->v_argptr)\n      {\n\ttree body = pop_stmt_list ();\n\ttree var = get_decl_tree (d->v_argptr);\n\tvar = build_address (var);\n\n\ttree init = build_call_expr (builtin_decl_explicit (BUILT_IN_VA_START),\n\t\t\t\t     2, var, parm_decl);\n\tdeclare_local_var (d->v_argptr);\n\tadd_stmt (init);\n\n\ttree cleanup = build_call_expr (builtin_decl_explicit (BUILT_IN_VA_END),\n\t\t\t\t\t1, var);\n\tadd_stmt (build2 (TRY_FINALLY_EXPR, void_type_node, body, cleanup));\n      }\n\n    finish_function (old_context);\n\n    /* Maybe record the function against the current module.  */\n    register_module_decl (d);\n  }\n};\n\n/* Main entry point for the DeclVisitor interface to send\n   the Declaration AST class D to GCC back-end.  */\n\nvoid\nbuild_decl_tree (Dsymbol *d)\n{\n  location_t saved_location = input_location;\n\n  /* Set input location, empty DECL_SOURCE_FILE can crash debug generator.  */\n  if (d->loc.filename)\n    input_location = make_location_t (d->loc);\n  else\n    input_location = make_location_t (Loc (\"<no_file>\", 1, 0));\n\n  DeclVisitor v = DeclVisitor ();\n  d->accept (&v);\n\n  input_location = saved_location;\n}\n\n/* Return the decl for the symbol, create it if it doesn't already exist.  */\n\ntree\nget_symbol_decl (Declaration *decl)\n{\n  if (decl->csym)\n    return decl->csym;\n\n  /* Deal with placeholder symbols immediately:\n     SymbolDeclaration is used as a shell around an initializer symbol.  */\n  SymbolDeclaration *sd = decl->isSymbolDeclaration ();\n  if (sd)\n    {\n      decl->csym = aggregate_initializer_decl (sd->dsym);\n      return decl->csym;\n    }\n\n  /* Global static TypeInfo declaration.  */\n  if (decl->isTypeInfoDeclaration ())\n    return get_typeinfo_decl ((TypeInfoDeclaration *) decl);\n\n  /* FuncAliasDeclaration is used to import functions from another scope.  */\n  FuncAliasDeclaration *fad = decl->isFuncAliasDeclaration ();\n  if (fad)\n    {\n      decl->csym = get_symbol_decl (fad->funcalias);\n      return decl->csym;\n    }\n\n  /* It is possible for a field declaration symbol to be requested\n     before the parent type has been built.  */\n  if (decl->isField ())\n    {\n      AggregateDeclaration *ad = decl->toParent ()->isAggregateDeclaration ();\n      gcc_assert (ad != NULL);\n\n      /* Finishing off the type should create the associated FIELD_DECL.  */\n      build_ctype (ad->type);\n      gcc_assert (decl->csym != NULL);\n\n      return decl->csym;\n    }\n\n  /* Build the tree for the symbol.  */\n  FuncDeclaration *fd = decl->isFuncDeclaration ();\n  if (fd)\n    {\n      /* Run full semantic on functions we need to know about.  */\n      if (!fd->functionSemantic ())\n\t{\n\t  decl->csym = error_mark_node;\n\t  return decl->csym;\n\t}\n\n      decl->csym = build_decl (make_location_t (decl->loc), FUNCTION_DECL,\n\t\t\t       get_identifier (decl->ident->toChars ()),\n\t\t\t       NULL_TREE);\n\n      /* Set function type afterwards as there could be self references.  */\n      TREE_TYPE (decl->csym) = build_ctype (fd->type);\n\n      if (!fd->fbody)\n\tDECL_EXTERNAL (decl->csym) = 1;\n    }\n  else\n    {\n      /* Build the variable declaration.  */\n      VarDeclaration *vd = decl->isVarDeclaration ();\n      gcc_assert (vd != NULL);\n\n      tree_code code = vd->isParameter () ? PARM_DECL\n\t: !vd->canTakeAddressOf () ? CONST_DECL\n\t: VAR_DECL;\n      decl->csym = build_decl (make_location_t (decl->loc), code,\n\t\t\t       get_identifier (decl->ident->toChars ()),\n\t\t\t       declaration_type (vd));\n\n      /* If any alignment was set on the declaration.  */\n      if (vd->alignment != STRUCTALIGN_DEFAULT)\n\t{\n\t  SET_DECL_ALIGN (decl->csym, vd->alignment * BITS_PER_UNIT);\n\t  DECL_USER_ALIGN (decl->csym) = 1;\n\t}\n\n      if (vd->storage_class & STCextern)\n\tDECL_EXTERNAL (decl->csym) = 1;\n    }\n\n  /* Set the declaration mangled identifier if static.  */\n  if (decl->isCodeseg () || decl->isDataseg ())\n    {\n      tree mangled_name;\n\n      if (decl->mangleOverride.length)\n\t{\n\t  mangled_name\n\t    = get_identifier_with_length (decl->mangleOverride.ptr,\n\t\t\t\t\t  decl->mangleOverride.length);\n\t}\n      else\n\tmangled_name = get_identifier (mangle_decl (decl));\n\n      mangled_name = targetm.mangle_decl_assembler_name (decl->csym,\n\t\t\t\t\t\t\t mangled_name);\n      /* The frontend doesn't handle duplicate definitions of unused symbols\n\t with the same mangle.  So a check is done here instead.  */\n      if (!DECL_EXTERNAL (decl->csym))\n\t{\n\t  if (IDENTIFIER_DSYMBOL (mangled_name))\n\t    {\n\t      Declaration *other = IDENTIFIER_DSYMBOL (mangled_name);\n\n\t      /* Non-templated variables shouldn't be defined twice.  */\n\t      if (!decl->isInstantiated ())\n\t\tScopeDsymbol::multiplyDefined (decl->loc, decl, other);\n\n\t      decl->csym = get_symbol_decl (other);\n\t      return decl->csym;\n\t    }\n\n\t  IDENTIFIER_PRETTY_NAME (mangled_name)\n\t    = get_identifier (decl->toPrettyChars (true));\n\t  IDENTIFIER_DSYMBOL (mangled_name) = decl;\n\t}\n\n      SET_DECL_ASSEMBLER_NAME (decl->csym, mangled_name);\n    }\n\n  DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (decl);\n  DECL_CONTEXT (decl->csym) = d_decl_context (decl);\n\n  if (TREE_CODE (decl->csym) == PARM_DECL)\n    {\n      /* Pass non-trivial structs by invisible reference.  */\n      if (TREE_ADDRESSABLE (TREE_TYPE (decl->csym)))\n\t{\n\t  tree argtype = build_reference_type (TREE_TYPE (decl->csym));\n\t  argtype = build_qualified_type (argtype, TYPE_QUAL_RESTRICT);\n\t  gcc_assert (!DECL_BY_REFERENCE (decl->csym));\n\t  TREE_TYPE (decl->csym) = argtype;\n\t  DECL_BY_REFERENCE (decl->csym) = 1;\n\t  TREE_ADDRESSABLE (decl->csym) = 0;\n\t  relayout_decl (decl->csym);\n\t  decl->storage_class |= STCref;\n\t}\n\n      DECL_ARG_TYPE (decl->csym) = TREE_TYPE (decl->csym);\n      gcc_assert (TREE_CODE (DECL_CONTEXT (decl->csym)) == FUNCTION_DECL);\n    }\n  else if (TREE_CODE (decl->csym) == CONST_DECL)\n    {\n      /* Manifest constants have no address in memory.  */\n      TREE_CONSTANT (decl->csym) = 1;\n      TREE_READONLY (decl->csym) = 1;\n    }\n  else if (TREE_CODE (decl->csym) == FUNCTION_DECL)\n    {\n      /* The real function type may differ from its declaration.  */\n      tree fntype = TREE_TYPE (decl->csym);\n      tree newfntype = NULL_TREE;\n\n      if (fd->isNested ())\n\t{\n\t  /* Add an extra argument for the frame/closure pointer, this is also\n\t     required to be compatible with D delegates.  */\n\t  newfntype = build_vthis_function (void_type_node, fntype);\n\t}\n      else if (fd->isThis ())\n\t{\n\t  /* Add an extra argument for the 'this' parameter.  The handle type is\n\t     used even if there is no debug info.  It is needed to make sure\n\t     virtual member functions are not called statically.  */\n\t  AggregateDeclaration *ad = fd->isMember2 ();\n\t  tree handle = build_ctype (ad->handleType ());\n\n\t  /* If handle is a pointer type, get record type.  */\n\t  if (!ad->isStructDeclaration ())\n\t    handle = TREE_TYPE (handle);\n\n\t  newfntype = build_vthis_function (handle, fntype);\n\n\t  /* Set the vindex on virtual functions.  */\n\t  if (fd->isVirtual () && fd->vtblIndex != -1)\n\t    {\n\t      DECL_VINDEX (decl->csym) = size_int (fd->vtblIndex);\n\t      DECL_VIRTUAL_P (decl->csym) = 1;\n\t    }\n\t}\n      else if (fd->isMain () || fd->isCMain ())\n\t{\n\t  /* The main function is named 'D main' to distinguish from C main.  */\n\t  if (fd->isMain ())\n\t    DECL_NAME (decl->csym) = get_identifier (fd->toPrettyChars (true));\n\n\t  /* 'void main' is implicitly converted to returning an int.  */\n\t  newfntype = build_function_type (d_int_type, TYPE_ARG_TYPES (fntype));\n\t}\n\n      if (newfntype != NULL_TREE)\n\t{\n\t  /* Copy the old attributes from the original type.  */\n\t  TYPE_ATTRIBUTES (newfntype) = TYPE_ATTRIBUTES (fntype);\n\t  TYPE_LANG_SPECIFIC (newfntype) = TYPE_LANG_SPECIFIC (fntype);\n\t  TREE_ADDRESSABLE (newfntype) = TREE_ADDRESSABLE (fntype);\n\t  TREE_TYPE (decl->csym) = newfntype;\n\t  d_keep (newfntype);\n\t}\n\n      /* Miscellaneous function flags.  */\n      if (fd->isMember2 () || fd->isFuncLiteralDeclaration ())\n\t{\n\t  /* See grokmethod in cp/decl.c.  Maybe we shouldn't be setting inline\n\t     flags without reason or proper handling.  */\n\t  DECL_DECLARED_INLINE_P (decl->csym) = 1;\n\t  DECL_NO_INLINE_WARNING_P (decl->csym) = 1;\n\t}\n\n      /* Function was declared 'naked'.  */\n      if (fd->naked)\n\t{\n\t  insert_decl_attribute (decl->csym, \"naked\");\n\t  DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl->csym) = 1;\n\t}\n\n      /* Vector array operations are always compiler generated.  */\n      if (fd->isArrayOp)\n\t{\n\t  TREE_PUBLIC (decl->csym) = 1;\n\t  DECL_ARTIFICIAL (decl->csym) = 1;\n\t  DECL_DECLARED_INLINE_P (decl->csym) = 1;\n\t  d_comdat_linkage (decl->csym);\n\t}\n\n      /* And so are ensure and require contracts.  */\n      if (fd->ident == Identifier::idPool (\"ensure\")\n\t  || fd->ident == Identifier::idPool (\"require\"))\n\t{\n\t  DECL_ARTIFICIAL (decl->csym) = 1;\n\t  TREE_PUBLIC (decl->csym) = 1;\n\t}\n\n      if (decl->storage_class & STCfinal)\n\tDECL_FINAL_P (decl->csym) = 1;\n\n      /* Check whether this function is expanded by the frontend.  */\n      DECL_INTRINSIC_CODE (decl->csym) = INTRINSIC_NONE;\n      maybe_set_intrinsic (fd);\n\n      /* For nested functions in particular, unnest fndecl in the cgraph, as\n\t all static chain passing is handled by the front-end.  Do this even\n\t if we are not emitting the body.  */\n      struct cgraph_node *node = cgraph_node::get_create (decl->csym);\n      if (node->origin)\n\tnode->unnest ();\n    }\n\n  /* Mark compiler generated temporaries as artificial.  */\n  if (decl->storage_class & STCtemp)\n    DECL_ARTIFICIAL (decl->csym) = 1;\n\n  /* Propagate shared on the decl.  */\n  if (TYPE_SHARED (TREE_TYPE (decl->csym)))\n    TREE_ADDRESSABLE (decl->csym) = 1;\n\n  /* Symbol was marked volatile.  */\n  if (decl->storage_class & STCvolatile)\n    TREE_THIS_VOLATILE (decl->csym) = 1;\n\n  /* Protection attributes are used by the debugger.  */\n  if (decl->protection.kind == Prot::private_)\n    TREE_PRIVATE (decl->csym) = 1;\n  else if (decl->protection.kind == Prot::protected_)\n    TREE_PROTECTED (decl->csym) = 1;\n\n  /* Likewise, so could the deprecated attribute.  */\n  if (decl->storage_class & STCdeprecated)\n    TREE_DEPRECATED (decl->csym) = 1;\n\n#if TARGET_DLLIMPORT_DECL_ATTRIBUTES\n  /* Have to test for import first.  */\n  if (decl->isImportedSymbol ())\n    {\n      insert_decl_attribute (decl->csym, \"dllimport\");\n      DECL_DLLIMPORT_P (decl->csym) = 1;\n    }\n  else if (decl->isExport ())\n    insert_decl_attribute (decl->csym, \"dllexport\");\n#endif\n\n  if (decl->isDataseg () || decl->isCodeseg () || decl->isThreadlocal ())\n    {\n      /* Set TREE_PUBLIC by default, but allow private template to override.  */\n      if (!fd || !fd->isNested ())\n\tTREE_PUBLIC (decl->csym) = 1;\n\n      TREE_STATIC (decl->csym) = 1;\n      /* The decl has not been defined -- yet.  */\n      DECL_EXTERNAL (decl->csym) = 1;\n\n      if (decl->isInstantiated ())\n\td_linkonce_linkage (decl->csym);\n    }\n\n  /* Symbol is going in thread local storage.  */\n  if (decl->isThreadlocal () && !DECL_ARTIFICIAL (decl->csym))\n    {\n      if (global.params.vtls)\n\tmessage (decl->loc, \"`%s` is thread local\", decl->toChars ());\n\n      set_decl_tls_model (decl->csym, decl_default_tls_model (decl->csym));\n    }\n\n  /* Apply any user attributes that may affect semantic meaning.  */\n  if (decl->userAttribDecl)\n    {\n      Expressions *attrs = decl->userAttribDecl->getAttributes ();\n      decl_attributes (&decl->csym, build_attributes (attrs), 0);\n    }\n  else if (DECL_ATTRIBUTES (decl->csym) != NULL)\n    decl_attributes (&decl->csym, DECL_ATTRIBUTES (decl->csym), 0);\n\n  /* %% Probably should be a little more intelligent about setting this.  */\n  TREE_USED (decl->csym) = 1;\n  d_keep (decl->csym);\n\n  return decl->csym;\n}\n\n/* Returns a declaration for a VAR_DECL.  Used to create compiler-generated\n   global variables.  */\n\ntree\ndeclare_extern_var (tree ident, tree type)\n{\n  /* If the VAR_DECL has already been declared, return it.  */\n  if (IDENTIFIER_DECL_TREE (ident))\n    return IDENTIFIER_DECL_TREE (ident);\n\n  tree name = IDENTIFIER_PRETTY_NAME (ident)\n    ? IDENTIFIER_PRETTY_NAME (ident) : ident;\n  tree decl = build_decl (input_location, VAR_DECL, name, type);\n\n  IDENTIFIER_DECL_TREE (ident) = decl;\n  d_keep (decl);\n\n  SET_DECL_ASSEMBLER_NAME (decl, ident);\n  DECL_ARTIFICIAL (decl) = 1;\n  TREE_STATIC (decl) = 1;\n  TREE_PUBLIC (decl) = 1;\n\n  /* The decl has not been defined -- yet.  */\n  DECL_EXTERNAL (decl) = 1;\n\n  return decl;\n}\n\n/* Add local variable VAR into the current function body.  */\n\nvoid\ndeclare_local_var (VarDeclaration *var)\n{\n  gcc_assert (!var->isDataseg () && !var->isMember ());\n  gcc_assert (current_function_decl != NULL_TREE);\n\n  FuncDeclaration *fd = cfun->language->function;\n  tree decl = get_symbol_decl (var);\n\n  gcc_assert (!TREE_STATIC (decl));\n  d_pushdecl (decl);\n  DECL_CONTEXT (decl) = current_function_decl;\n\n  /* Compiler generated symbols.  */\n  if (var == fd->vresult || var == fd->v_argptr)\n    DECL_ARTIFICIAL (decl) = 1;\n\n  if (DECL_LANG_FRAME_FIELD (decl))\n    {\n      /* Fixes debugging local variables.  */\n      SET_DECL_VALUE_EXPR (decl, get_decl_tree (var));\n      DECL_HAS_VALUE_EXPR_P (decl) = 1;\n    }\n}\n\n/* Return an unnamed local temporary of type TYPE.  */\n\ntree\nbuild_local_temp (tree type)\n{\n  tree decl = build_decl (input_location, VAR_DECL, NULL_TREE, type);\n\n  DECL_CONTEXT (decl) = current_function_decl;\n  DECL_ARTIFICIAL (decl) = 1;\n  DECL_IGNORED_P (decl) = 1;\n  d_pushdecl (decl);\n\n  return decl;\n}\n\n/* Return the correct decl to be used for DECL.  For VAR_DECLs, this could\n   instead be a FIELD_DECL from a closure, or a RESULT_DECL from a named return\n   value.  For PARM_DECLs, this could be a FIELD_DECL for a non-local `this'.\n   For all other kinds of decls, this just returns the result of\n   get_symbol_decl().  */\n\ntree\nget_decl_tree (Declaration *decl)\n{\n  tree t = get_symbol_decl (decl);\n  FuncDeclaration *fd = cfun ? cfun->language->function : NULL;\n  VarDeclaration *vd = decl->isVarDeclaration ();\n\n  /* If cfun is NULL, then this is a global static.  */\n  if (vd == NULL || fd == NULL)\n    return t;\n\n  /* Get the named return value.  */\n  if (DECL_LANG_NRVO (t))\n    return DECL_LANG_NRVO (t);\n\n  /* Get the closure holding the var decl.  */\n  if (DECL_LANG_FRAME_FIELD (t))\n    {\n      FuncDeclaration *parent = vd->toParent2 ()->isFuncDeclaration ();\n      tree frame_ref = get_framedecl (fd, parent);\n\n      return component_ref (build_deref (frame_ref),\n\t\t\t    DECL_LANG_FRAME_FIELD (t));\n    }\n\n  /* Get the non-local 'this' value by going through parent link\n     of nested classes, this routine pretty much undoes what\n     getRightThis in the frontend removes from codegen.  */\n  if (vd->parent != fd && vd->isThisDeclaration ())\n    {\n      /* Find the first parent that is a member function.  */\n      while (!fd->isMember2 ())\n\t{\n\t  gcc_assert (fd->vthis);\n\t  fd = fd->toParent2 ()->isFuncDeclaration ();\n\t  gcc_assert (fd != NULL);\n\t}\n\n      AggregateDeclaration *ad = fd->isThis ();\n      gcc_assert (ad != NULL);\n\n      t = get_decl_tree (fd->vthis);\n      Dsymbol *outer = fd;\n\n      while (outer != vd->parent)\n\t{\n\t  gcc_assert (ad != NULL);\n\t  outer = ad->toParent2 ();\n\n\t  /* Get the this->this parent link.  */\n\t  tree vfield = get_symbol_decl (ad->vthis);\n\t  t = component_ref (build_deref (t), vfield);\n\n\t  ad = outer->isAggregateDeclaration ();\n\t  if (ad != NULL)\n\t    continue;\n\n\t  fd = outer->isFuncDeclaration ();\n\t  while (fd != NULL)\n\t    {\n\t      /* If outer function creates a closure, then the 'this'\n\t\t value would be the closure pointer, and the real\n\t\t 'this' the first field of that closure.  */\n\t      tree ff = get_frameinfo (fd);\n\t      if (FRAMEINFO_CREATES_FRAME (ff))\n\t\t{\n\t\t  t = build_nop (build_pointer_type (FRAMEINFO_TYPE (ff)), t);\n\t\t  t = indirect_ref (build_ctype (fd->vthis->type), t);\n\t\t}\n\n\t      if (fd == vd->parent)\n\t\tbreak;\n\n\t      /* Continue looking for the right `this'.  */\n\t      outer = outer->toParent2 ();\n\t      fd = outer->isFuncDeclaration ();\n\t    }\n\n\t  ad = outer->isAggregateDeclaration ();\n\t}\n\n      return t;\n    }\n\n  /* Auto variable that the back end will handle for us.  */\n  return t;\n}\n\n/* Update the TLS model on variable DECL, typically after the linkage\n   has been modified.  */\n\nstatic void\nreset_decl_tls_model (tree decl)\n{\n  if (DECL_THREAD_LOCAL_P (decl))\n    set_decl_tls_model (decl, decl_default_tls_model (decl));\n}\n\n/* Finish up a variable declaration and compile it all the way to\n   the assembler language output.  */\n\nvoid\nd_finish_decl (tree decl)\n{\n  gcc_assert (!error_operand_p (decl));\n\n  /* We are sending this symbol to object file, can't be extern.  */\n  TREE_STATIC (decl) = 1;\n  DECL_EXTERNAL (decl) = 0;\n  reset_decl_tls_model (decl);\n  relayout_decl (decl);\n\n  if (flag_checking && DECL_INITIAL (decl))\n    {\n      /* Initializer must never be bigger than symbol size.  */\n      dinteger_t tsize = int_size_in_bytes (TREE_TYPE (decl));\n      dinteger_t dtsize = int_size_in_bytes (TREE_TYPE (DECL_INITIAL (decl)));\n\n      if (tsize < dtsize)\n\t{\n\t  tree name = DECL_ASSEMBLER_NAME (decl);\n\n\t  internal_error (\"Mismatch between declaration %qE size (%wd) and \"\n\t\t\t  \"its initializer size (%wd).\",\n\t\t\t  IDENTIFIER_PRETTY_NAME (name)\n\t\t\t  ? IDENTIFIER_PRETTY_NAME (name) : name,\n\t\t\t  tsize, dtsize);\n\t}\n    }\n\n  /* Without weak symbols, symbol should be put in .common, but that can't\n     be done if there is a nonzero initializer.  */\n  if (DECL_COMDAT (decl) && DECL_COMMON (decl)\n      && initializer_zerop (DECL_INITIAL (decl)))\n    DECL_INITIAL (decl) = error_mark_node;\n\n  /* Add this decl to the current binding level.  */\n  d_pushdecl (decl);\n\n  rest_of_decl_compilation (decl, 1, 0);\n}\n\n/* Thunk code is based on g++.  */\n\nstatic int thunk_labelno;\n\n/* Create a static alias to function.  */\n\nstatic tree\nmake_alias_for_thunk (tree function)\n{\n  tree alias;\n  char buf[256];\n\n  /* Thunks may reference extern functions which cannot be aliased.  */\n  if (DECL_EXTERNAL (function))\n    return function;\n\n  targetm.asm_out.generate_internal_label (buf, \"LTHUNK\", thunk_labelno);\n  thunk_labelno++;\n\n  alias = build_decl (DECL_SOURCE_LOCATION (function), FUNCTION_DECL,\n\t\t      get_identifier (buf), TREE_TYPE (function));\n  DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function);\n  lang_hooks.dup_lang_specific_decl (alias);\n  DECL_CONTEXT (alias) = NULL_TREE;\n  TREE_READONLY (alias) = TREE_READONLY (function);\n  TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (function);\n  TREE_PUBLIC (alias) = 0;\n\n  DECL_EXTERNAL (alias) = 0;\n  DECL_ARTIFICIAL (alias) = 1;\n\n  DECL_DECLARED_INLINE_P (alias) = 0;\n  DECL_INITIAL (alias) = error_mark_node;\n  DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (function));\n\n  TREE_ADDRESSABLE (alias) = 1;\n  TREE_USED (alias) = 1;\n  SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));\n\n  if (!flag_syntax_only)\n    {\n      cgraph_node *aliasn;\n      aliasn = cgraph_node::create_same_body_alias (alias, function);\n      gcc_assert (aliasn != NULL);\n    }\n  return alias;\n}\n\n/* Emit the definition of a D vtable thunk.  */\n\nstatic void\nfinish_thunk (tree thunk, tree function)\n{\n  /* Setup how D thunks are outputted.  */\n  int fixed_offset = -THUNK_LANG_OFFSET (thunk);\n  bool this_adjusting = true;\n  tree alias;\n\n  if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))\n    alias = make_alias_for_thunk (function);\n  else\n    alias = function;\n\n  TREE_ADDRESSABLE (function) = 1;\n  TREE_USED (function) = 1;\n\n  if (flag_syntax_only)\n    {\n      TREE_ASM_WRITTEN (thunk) = 1;\n      return;\n    }\n\n  if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function)\n      && targetm_common.have_named_sections)\n    {\n      tree fn = function;\n      symtab_node *symbol = symtab_node::get (function);\n\n      if (symbol != NULL && symbol->alias)\n\t{\n\t  if (symbol->analyzed)\n\t    fn = symtab_node::get (function)->ultimate_alias_target ()->decl;\n\t  else\n\t    fn = symtab_node::get (function)->alias_target;\n\t}\n      resolve_unique_section (fn, 0, flag_function_sections);\n\n      if (DECL_SECTION_NAME (fn) != NULL && DECL_ONE_ONLY (fn))\n\t{\n\t  resolve_unique_section (thunk, 0, flag_function_sections);\n\n\t  /* Output the thunk into the same section as function.  */\n\t  set_decl_section_name (thunk, DECL_SECTION_NAME (fn));\n\t  symtab_node::get (thunk)->implicit_section\n\t    = symtab_node::get (fn)->implicit_section;\n\t}\n    }\n\n  /* Set up cloned argument trees for the thunk.  */\n  tree t = NULL_TREE;\n  for (tree a = DECL_ARGUMENTS (function); a; a = DECL_CHAIN (a))\n    {\n      tree x = copy_node (a);\n      DECL_CHAIN (x) = t;\n      DECL_CONTEXT (x) = thunk;\n      SET_DECL_RTL (x, NULL);\n      DECL_HAS_VALUE_EXPR_P (x) = 0;\n      TREE_ADDRESSABLE (x) = 0;\n      t = x;\n    }\n  DECL_ARGUMENTS (thunk) = nreverse (t);\n  TREE_ASM_WRITTEN (thunk) = 1;\n\n  cgraph_node *funcn, *thunk_node;\n\n  funcn = cgraph_node::get_create (function);\n  gcc_assert (funcn);\n  thunk_node = funcn->create_thunk (thunk, thunk, this_adjusting,\n\t\t\t\t    fixed_offset, 0, 0, 0, alias);\n\n  if (DECL_ONE_ONLY (function))\n    thunk_node->add_to_same_comdat_group (funcn);\n\n  /* Target assemble_mi_thunk doesn't work across section boundaries\n     on many targets, instead force thunk to be expanded in gimple.  */\n  if (DECL_EXTERNAL (function))\n    {\n      /* cgraph::expand_thunk writes over current_function_decl, so if this\n\t could ever be in use by the codegen pass, we want to know about it.  */\n      gcc_assert (current_function_decl == NULL_TREE);\n\n      if (!stdarg_p (TREE_TYPE (thunk)))\n\t{\n\t  thunk_node->create_edge (funcn, NULL, thunk_node->count);\n\t  thunk_node->expand_thunk (false, true);\n\t}\n\n      /* Tell the back-end to not bother inlining the function, this is\n\t assumed not to work as it could be referencing symbols outside\n\t of the current compilation unit.  */\n      DECL_UNINLINABLE (function) = 1;\n    }\n}\n\n/* Return a thunk to DECL.  Thunks adjust the incoming `this' pointer by OFFSET.\n   Adjustor thunks are created and pointers to them stored in the method entries\n   in the vtable in order to set the this pointer to the start of the object\n   instance corresponding to the implementing method.  */\n\ntree\nmake_thunk (FuncDeclaration *decl, int offset)\n{\n  tree function = get_symbol_decl (decl);\n\n  if (!DECL_ARGUMENTS (function) || !DECL_RESULT (function))\n    {\n      /* Compile the function body before generating the thunk, this is done\n\t even if the decl is external to the current module.  */\n      if (decl->fbody)\n\tbuild_decl_tree (decl);\n      else\n\t{\n\t  /* Build parameters for functions that are not being compiled,\n\t     so that they can be correctly cloned in finish_thunk.  */\n\t  tree fntype = TREE_TYPE (function);\n\t  tree params = NULL_TREE;\n\n\t  for (tree t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))\n\t    {\n\t      if (t == void_list_node)\n\t\tbreak;\n\n\t      tree param = build_decl (DECL_SOURCE_LOCATION (function),\n\t\t\t\t       PARM_DECL, NULL_TREE, TREE_VALUE (t));\n\t      DECL_ARG_TYPE (param) = TREE_TYPE (param);\n\t      DECL_ARTIFICIAL (param) = 1;\n\t      DECL_IGNORED_P (param) = 1;\n\t      DECL_CONTEXT (param) = function;\n\t      params = chainon (params, param);\n\t    }\n\n\t  DECL_ARGUMENTS (function) = params;\n\n\t  /* Also build the result decl, which is needed when force creating\n\t     the thunk in gimple inside cgraph_node::expand_thunk.  */\n\t  tree resdecl = build_decl (DECL_SOURCE_LOCATION (function),\n\t\t\t\t     RESULT_DECL, NULL_TREE,\n\t\t\t\t     TREE_TYPE (fntype));\n\t  DECL_ARTIFICIAL (resdecl) = 1;\n\t  DECL_IGNORED_P (resdecl) = 1;\n\t  DECL_CONTEXT (resdecl) = function;\n\t  DECL_RESULT (function) = resdecl;\n\t}\n    }\n\n  /* Don't build the thunk if the compilation step failed.  */\n  if (global.errors)\n    return error_mark_node;\n\n  /* See if we already have the thunk in question.  */\n  for (tree t = DECL_LANG_THUNKS (function); t; t = DECL_CHAIN (t))\n    {\n      if (THUNK_LANG_OFFSET (t) == offset)\n\treturn t;\n    }\n\n  tree thunk = build_decl (DECL_SOURCE_LOCATION (function),\n\t\t\t   FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));\n  DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);\n  lang_hooks.dup_lang_specific_decl (thunk);\n  THUNK_LANG_OFFSET (thunk) = offset;\n\n  TREE_READONLY (thunk) = TREE_READONLY (function);\n  TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);\n  TREE_NOTHROW (thunk) = TREE_NOTHROW (function);\n\n  DECL_CONTEXT (thunk) = d_decl_context (decl);\n\n  /* Thunks inherit the public access of the function they are targetting.  */\n  TREE_PUBLIC (thunk) = TREE_PUBLIC (function);\n  DECL_EXTERNAL (thunk) = 0;\n\n  /* Thunks are always addressable.  */\n  TREE_ADDRESSABLE (thunk) = 1;\n  TREE_USED (thunk) = 1;\n  DECL_ARTIFICIAL (thunk) = 1;\n  DECL_DECLARED_INLINE_P (thunk) = 0;\n\n  DECL_VISIBILITY (thunk) = DECL_VISIBILITY (function);\n  DECL_COMDAT (thunk) = DECL_COMDAT (function);\n  DECL_WEAK (thunk) = DECL_WEAK (function);\n\n  tree target_name = DECL_ASSEMBLER_NAME (function);\n  unsigned identlen = IDENTIFIER_LENGTH (target_name) + 14;\n  const char *ident = XNEWVEC (const char, identlen);\n  snprintf (CONST_CAST (char *, ident), identlen,\n\t    \"_DT%u%s\", offset, IDENTIFIER_POINTER (target_name));\n\n  DECL_NAME (thunk) = get_identifier (ident);\n  SET_DECL_ASSEMBLER_NAME (thunk, DECL_NAME (thunk));\n\n  d_keep (thunk);\n\n  finish_thunk (thunk, function);\n\n  /* Add it to the list of thunks associated with the function.  */\n  DECL_LANG_THUNKS (thunk) = NULL_TREE;\n  DECL_CHAIN (thunk) = DECL_LANG_THUNKS (function);\n  DECL_LANG_THUNKS (function) = thunk;\n\n  return thunk;\n}\n\n/* Create the FUNCTION_DECL for a function definition.\n   This function creates a binding context for the function body\n   as well as setting up the FUNCTION_DECL in current_function_decl.\n   Returns the previous function context if it was already set.  */\n\ntree\nstart_function (FuncDeclaration *fd)\n{\n  tree fndecl = get_symbol_decl (fd);\n\n  /* Function has been defined, check now whether we intend to send it to\n     object file, or it really is extern.  Such as inlinable functions from\n     modules not in this compilation, or thunk aliases.  */\n  TemplateInstance *ti = fd->isInstantiated ();\n  if (ti && ti->needsCodegen ())\n    {\n      /* Warn about templates instantiated in this compilation.  */\n      if (ti == fd->parent)\n\t{\n\t  warning (OPT_Wtemplates, \"%s %qs instantiated\",\n\t\t   ti->kind (), ti->toPrettyChars (false));\n\t}\n\n      DECL_EXTERNAL (fndecl) = 0;\n    }\n  else\n    {\n      Module *md = fd->getModule ();\n      if (md && md->isRoot ())\n\tDECL_EXTERNAL (fndecl) = 0;\n    }\n\n  DECL_INITIAL (fndecl) = error_mark_node;\n\n  /* Add this decl to the current binding level.  */\n  d_pushdecl (fndecl);\n\n  /* Save the current function context.  */\n  tree old_context = current_function_decl;\n\n  if (old_context)\n    push_function_context ();\n\n  /* Let GCC know the current scope is this function.  */\n  current_function_decl = fndecl;\n\n  tree restype = TREE_TYPE (TREE_TYPE (fndecl));\n  tree resdecl = build_decl (make_location_t (fd->loc), RESULT_DECL,\n\t\t\t     NULL_TREE, restype);\n\n  DECL_RESULT (fndecl) = resdecl;\n  DECL_CONTEXT (resdecl) = fndecl;\n  DECL_ARTIFICIAL (resdecl) = 1;\n  DECL_IGNORED_P (resdecl) = 1;\n\n  /* Initialize the RTL code for the function.  */\n  allocate_struct_function (fndecl, false);\n\n  /* Store the end of the function.  */\n  if (fd->endloc.filename)\n    cfun->function_end_locus = make_location_t (fd->endloc);\n  else\n    cfun->function_end_locus = DECL_SOURCE_LOCATION (fndecl);\n\n  cfun->language = ggc_cleared_alloc<language_function> ();\n  cfun->language->function = fd;\n\n  /* Default chain value is 'null' unless parent found.  */\n  cfun->language->static_chain = null_pointer_node;\n\n  /* Find module for this function.  */\n  for (Dsymbol *p = fd->parent; p != NULL; p = p->parent)\n    {\n      cfun->language->module = p->isModule ();\n      if (cfun->language->module)\n\tbreak;\n    }\n  gcc_assert (cfun->language->module != NULL);\n\n  /* Begin the statement tree for this function.  */\n  push_stmt_list ();\n  push_binding_level (level_function);\n\n  return old_context;\n}\n\n/* Finish up a function declaration and compile that function all\n   the way to assembler language output.  The free the storage for\n   the function definition.  Restores the previous function context.  */\n\nvoid\nfinish_function (tree old_context)\n{\n  tree fndecl = current_function_decl;\n\n  /* Tie off the statement tree for this function.  */\n  tree block = pop_binding_level ();\n  tree body = pop_stmt_list ();\n  tree bind = build3 (BIND_EXPR, void_type_node,\n\t\t      BLOCK_VARS (block), body, block);\n\n  gcc_assert (vec_safe_is_empty (d_function_chain->stmt_list));\n\n  /* Back-end expects a statement list to come from somewhere, however\n     pop_stmt_list returns expressions when there is a single statement.\n     So here we create a statement list unconditionally.  */\n  if (TREE_CODE (body) != STATEMENT_LIST)\n    {\n      tree stmtlist = alloc_stmt_list ();\n      append_to_statement_list_force (body, &stmtlist);\n      BIND_EXPR_BODY (bind) = stmtlist;\n    }\n  else if (!STATEMENT_LIST_HEAD (body))\n    {\n      /* For empty functions add a void return.  */\n      append_to_statement_list_force (return_expr (NULL_TREE), &body);\n    }\n\n  DECL_SAVED_TREE (fndecl) = bind;\n\n  if (!errorcount && !global.errors)\n    {\n      /* Dump the D-specific tree IR.  */\n      dump_function (TDI_original, fndecl);\n\n      cgraph_node::finalize_function (fndecl, true);\n    }\n\n  /* We're leaving the context of this function, so free it.  */\n  ggc_free (cfun->language);\n  cfun->language = NULL;\n  set_cfun (NULL);\n\n  if (old_context)\n    pop_function_context ();\n\n  current_function_decl = old_context;\n}\n\n/* Mark DECL, which is a VAR_DECL or FUNCTION_DECL as a symbol that\n   must be emitted in this, output module.  */\n\nvoid\nmark_needed (tree decl)\n{\n  TREE_USED (decl) = 1;\n\n  if (TREE_CODE (decl) == FUNCTION_DECL)\n    {\n      struct cgraph_node *node = cgraph_node::get_create (decl);\n      node->forced_by_abi = true;\n    }\n  else if (VAR_P (decl))\n    {\n      struct varpool_node *node = varpool_node::get_create (decl);\n      node->forced_by_abi = true;\n    }\n}\n\n/* Get the offset to the BC's vtbl[] initializer from the start of CD.\n   Returns \"~0u\" if the base class is not found in any vtable interfaces.  */\n\nunsigned\nbase_vtable_offset (ClassDeclaration *cd, BaseClass *bc)\n{\n  unsigned csymoffset = Target::classinfosize;\n  unsigned interfacesize = int_size_in_bytes (vtbl_interface_type_node);\n  csymoffset += cd->vtblInterfaces->dim * interfacesize;\n\n  for (size_t i = 0; i < cd->vtblInterfaces->dim; i++)\n    {\n      BaseClass *b = (*cd->vtblInterfaces)[i];\n      if (b == bc)\n\treturn csymoffset;\n      csymoffset += b->sym->vtbl.dim * Target::ptrsize;\n    }\n\n  /* Check all overriding interface vtbl[]s.  */\n  for (ClassDeclaration *cd2 = cd->baseClass; cd2; cd2 = cd2->baseClass)\n    {\n      for (size_t k = 0; k < cd2->vtblInterfaces->dim; k++)\n\t{\n\t  BaseClass *bs = (*cd2->vtblInterfaces)[k];\n\t  if (bs->fillVtbl (cd, NULL, 0))\n\t    {\n\t      if (bc == bs)\n\t\treturn csymoffset;\n\t      csymoffset += bs->sym->vtbl.dim * Target::ptrsize;\n\t    }\n\t}\n    }\n\n  return ~0u;\n}\n\n/* Get the VAR_DECL of the vtable symbol for DECL.  If this does not yet exist,\n   create it.  The vtable is accessible via ClassInfo, but since it is needed\n   frequently (like for rtti comparisons), make it directly accessible.  */\n\ntree\nget_vtable_decl (ClassDeclaration *decl)\n{\n  if (decl->vtblsym && decl->vtblsym->csym)\n    return decl->vtblsym->csym;\n\n  tree ident = mangle_internal_decl (decl, \"__vtbl\", \"Z\");\n  /* Note: Using a static array type for the VAR_DECL, the DECL_INITIAL value\n     will have a different type.  However the back-end seems to accept this.  */\n  tree type = build_ctype (Type::tvoidptr->sarrayOf (decl->vtbl.dim));\n\n  Dsymbol *vtblsym = decl->vtblSymbol ();\n  vtblsym->csym = declare_extern_var (ident, type);\n  DECL_LANG_SPECIFIC (vtblsym->csym) = build_lang_decl (NULL);\n\n  /* Class is a reference, want the record type.  */\n  DECL_CONTEXT (vtblsym->csym) = TREE_TYPE (build_ctype (decl->type));\n  TREE_READONLY (vtblsym->csym) = 1;\n  DECL_VIRTUAL_P (vtblsym->csym) = 1;\n\n  SET_DECL_ALIGN (vtblsym->csym, TARGET_VTABLE_ENTRY_ALIGN);\n  DECL_USER_ALIGN (vtblsym->csym) = true;\n\n  return vtblsym->csym;\n}\n\n/* Helper function of build_class_instance.  Find the field inside aggregate\n   TYPE identified by IDENT at field OFFSET.  */\n\nstatic tree\nfind_aggregate_field (tree type, tree ident, tree offset)\n{\n  tree fields = TYPE_FIELDS (type);\n\n  for (tree field = fields; field != NULL_TREE; field = TREE_CHAIN (field))\n    {\n      if (DECL_NAME (field) == NULL_TREE\n\t  && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))\n\t  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))\n\t{\n\t  /* Search nesting anonymous structs and unions.  */\n\t  tree vfield = find_aggregate_field (TREE_TYPE (field),\n\t\t\t\t\t      ident, offset);\n\t  if (vfield != NULL_TREE)\n\t    return vfield;\n\t}\n      else if (DECL_NAME (field) == ident\n\t       && (offset == NULL_TREE\n\t\t   || DECL_FIELD_OFFSET (field) == offset))\n\t{\n\t  /* Found matching field at offset.  */\n\t  return field;\n\t}\n    }\n\n  return NULL_TREE;\n}\n\n/* Helper function of build_new_class_expr.  Return a constructor that matches\n   the layout of the class expression EXP.  */\n\nstatic tree\nbuild_class_instance (ClassReferenceExp *exp)\n{\n  ClassDeclaration *cd = exp->originalClass ();\n  tree type = TREE_TYPE (build_ctype (exp->value->stype));\n  vec<constructor_elt, va_gc> *ve = NULL;\n\n  /* The set base vtable field.  */\n  tree vptr = build_address (get_vtable_decl (cd));\n  CONSTRUCTOR_APPEND_ELT (ve, TYPE_FIELDS (type), vptr);\n\n  /* Go through the inheritance graph from top to bottom.  This will add all\n     values to the constructor out of order, however build_struct_literal\n     will re-order all values before returning the finished literal.  */\n  for (ClassDeclaration *bcd = cd; bcd != NULL; bcd = bcd->baseClass)\n    {\n      /* Anonymous vtable interface fields are laid out before the fields of\n\t each class.  The interface offset is used to determine where to put\n\t the classinfo offset reference.  */\n      for (size_t i = 0; i < bcd->vtblInterfaces->dim; i++)\n\t{\n\t  BaseClass *bc = (*bcd->vtblInterfaces)[i];\n\n\t  for (ClassDeclaration *cd2 = cd; 1; cd2 = cd2->baseClass)\n\t    {\n\t      gcc_assert (cd2 != NULL);\n\n\t      unsigned csymoffset = base_vtable_offset (cd2, bc);\n\t      /* If the base class vtable was found.  */\n\t      if (csymoffset != ~0u)\n\t\t{\n\t\t  tree csym = build_address (get_classinfo_decl (cd2));\n\t\t  csym = build_offset (csym, size_int (csymoffset));\n\n\t\t  tree field = find_aggregate_field (type, NULL_TREE,\n\t\t\t\t\t\t     size_int (bc->offset));\n\t\t  gcc_assert (field != NULL_TREE);\n\n\t\t  CONSTRUCTOR_APPEND_ELT (ve, field, csym);\n\t\t  break;\n\t\t}\n\t    }\n\t}\n\n      /* Generate initial values of all fields owned by current class.\n\t Use both the name and offset to find the right field.  */\n      for (size_t i = 0; i < bcd->fields.dim; i++)\n\t{\n\t  VarDeclaration *vfield = bcd->fields[i];\n\t  int index = exp->findFieldIndexByName (vfield);\n\t  gcc_assert (index != -1);\n\n\t  Expression *value = (*exp->value->elements)[index];\n\t  if (!value)\n\t    continue;\n\n\t  /* Use find_aggregate_field to get the overridden field decl,\n\t     instead of the field associated with the base class.  */\n\t  tree field = get_symbol_decl (bcd->fields[i]);\n\t  field = find_aggregate_field (type, DECL_NAME (field),\n\t\t\t\t\tDECL_FIELD_OFFSET (field));\n\t  gcc_assert (field != NULL_TREE);\n\n\t  CONSTRUCTOR_APPEND_ELT (ve, field, build_expr (value, true));\n\t}\n    }\n\n  return build_struct_literal (type, ve);\n}\n\n/* Get the VAR_DECL of a class instance representing EXPR as static data.\n   If this does not yet exist, create it.  This is used to support initializing\n   a static variable that is of a class type using values known during CTFE.\n   In user code, it is analogous to the following code snippet.\n\n    enum E = new C(1, 2, 3);\n\n   That we write the contents of `C(1, 2, 3)' to static data is only a compiler\n   implementation detail.  The initialization of these symbols could be done at\n   run-time using during as part of the module initialization or shared static\n   constructors phase of run-time start-up - whichever comes after `gc_init()'.\n   And infact that would be the better thing to do here eventually.  */\n\ntree\nbuild_new_class_expr (ClassReferenceExp *expr)\n{\n  if (expr->value->sym)\n    return expr->value->sym;\n\n  /* Build the reference symbol.  */\n  tree type = build_ctype (expr->value->stype);\n  expr->value->sym = build_artificial_decl (TREE_TYPE (type), NULL_TREE, \"C\");\n\n  DECL_INITIAL (expr->value->sym) = build_class_instance (expr);\n  d_pushdecl (expr->value->sym);\n  rest_of_decl_compilation (expr->value->sym, 1, 0);\n\n  return expr->value->sym;\n}\n\n/* Get the VAR_DECL of the static initializer symbol for the struct/class DECL.\n   If this does not yet exist, create it.  The static initializer data is\n   accessible via TypeInfo, and is also used in 'new class' and default\n   initializing struct literals.  */\n\ntree\naggregate_initializer_decl (AggregateDeclaration *decl)\n{\n  if (decl->sinit)\n    return decl->sinit;\n\n  /* Class is a reference, want the record type.  */\n  tree type = build_ctype (decl->type);\n  StructDeclaration *sd = decl->isStructDeclaration ();\n  if (!sd)\n    type = TREE_TYPE (type);\n\n  tree ident = mangle_internal_decl (decl, \"__init\", \"Z\");\n\n  decl->sinit = declare_extern_var (ident, type);\n  DECL_LANG_SPECIFIC (decl->sinit) = build_lang_decl (NULL);\n\n  DECL_CONTEXT (decl->sinit) = type;\n  TREE_READONLY (decl->sinit) = 1;\n\n  /* Honor struct alignment set by user.  */\n  if (sd && sd->alignment != STRUCTALIGN_DEFAULT)\n    {\n      SET_DECL_ALIGN (decl->sinit, sd->alignment * BITS_PER_UNIT);\n      DECL_USER_ALIGN (decl->sinit) = true;\n    }\n\n  return decl->sinit;\n}\n\n/* Generate the data for the static initializer.  */\n\ntree\nlayout_class_initializer (ClassDeclaration *cd)\n{\n  NewExp *ne = NewExp::create (cd->loc, NULL, NULL, cd->type, NULL);\n  ne->type = cd->type;\n\n  Expression *e = ne->ctfeInterpret ();\n  gcc_assert (e->op == TOKclassreference);\n\n  return build_class_instance ((ClassReferenceExp *) e);\n}\n\ntree\nlayout_struct_initializer (StructDeclaration *sd)\n{\n  StructLiteralExp *sle = StructLiteralExp::create (sd->loc, sd, NULL);\n\n  if (!sd->fill (sd->loc, sle->elements, true))\n    gcc_unreachable ();\n\n  sle->type = sd->type;\n  return build_expr (sle, true);\n}\n\n/* Get the VAR_DECL of the static initializer symbol for the enum DECL.\n   If this does not yet exist, create it.  The static initializer data is\n   accessible via TypeInfo_Enum, but the field member type is a byte[] that\n   requires a pointer to a symbol reference.  */\n\ntree\nenum_initializer_decl (EnumDeclaration *decl)\n{\n  if (decl->sinit)\n    return decl->sinit;\n\n  tree type = build_ctype (decl->type);\n\n  Identifier *ident_save = decl->ident;\n  if (!decl->ident)\n    decl->ident = Identifier::generateId (\"__enum\");\n  tree ident = mangle_internal_decl (decl, \"__init\", \"Z\");\n  decl->ident = ident_save;\n\n  decl->sinit = declare_extern_var (ident, type);\n  DECL_LANG_SPECIFIC (decl->sinit) = build_lang_decl (NULL);\n\n  DECL_CONTEXT (decl->sinit) = d_decl_context (decl);\n  TREE_READONLY (decl->sinit) = 1;\n\n  return decl->sinit;\n}\n\n/* Return an anonymous static variable of type TYPE, initialized with INIT,\n   and optionally prefixing the name with PREFIX.  */\n\ntree\nbuild_artificial_decl (tree type, tree init, const char *prefix)\n{\n  tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, type);\n  const char *name = prefix ? prefix : \"___s\";\n  char *label;\n\n  ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl));\n  SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label));\n  DECL_NAME (decl) = DECL_ASSEMBLER_NAME (decl);\n\n  TREE_PUBLIC (decl) = 0;\n  TREE_STATIC (decl) = 1;\n  TREE_USED (decl) = 1;\n  DECL_IGNORED_P (decl) = 1;\n  DECL_ARTIFICIAL (decl) = 1;\n\n  /* Perhaps at some point the initializer constant should be hashed\n     to remove duplicates.  */\n  DECL_INITIAL (decl) = init;\n\n  return decl;\n}\n\n/* Build TYPE_DECL for the declaration DSYM.  */\n\nvoid\nbuild_type_decl (tree type, Dsymbol *dsym)\n{\n  if (TYPE_STUB_DECL (type))\n    return;\n\n  gcc_assert (!POINTER_TYPE_P (type));\n\n  tree decl = build_decl (make_location_t (dsym->loc), TYPE_DECL,\n\t\t\t  get_identifier (dsym->ident->toChars ()), type);\n  SET_DECL_ASSEMBLER_NAME (decl, get_identifier (mangle_decl (dsym)));\n  TREE_PUBLIC (decl) = 1;\n  DECL_ARTIFICIAL (decl) = 1;\n  DECL_CONTEXT (decl) = d_decl_context (dsym);\n\n  TYPE_CONTEXT (type) = DECL_CONTEXT (decl);\n  TYPE_NAME (type) = decl;\n\n  /* Not sure if there is a need for separate TYPE_DECLs in\n     TYPE_NAME and TYPE_STUB_DECL.  */\n  if (TREE_CODE (type) == ENUMERAL_TYPE || RECORD_OR_UNION_TYPE_P (type))\n    TYPE_STUB_DECL (type) = decl;\n\n  rest_of_decl_compilation (decl, SCOPE_FILE_SCOPE_P (decl), 0);\n}\n\n/* Create a declaration for field NAME of a given TYPE, setting the flags\n   for whether the field is ARTIFICIAL and/or IGNORED.  */\n\ntree\ncreate_field_decl (tree type, const char *name, int artificial, int ignored)\n{\n  tree decl = build_decl (input_location, FIELD_DECL,\n\t\t\t  name ? get_identifier (name) : NULL_TREE, type);\n  DECL_ARTIFICIAL (decl) = artificial;\n  DECL_IGNORED_P (decl) = ignored;\n\n  return decl;\n}\n\n/* Return the COMDAT group into which DECL should be placed.  */\n\nstatic tree\nd_comdat_group (tree decl)\n{\n  /* If already part of a comdat group, use that.  */\n  if (DECL_COMDAT_GROUP (decl))\n    return DECL_COMDAT_GROUP (decl);\n\n  return DECL_ASSEMBLER_NAME (decl);\n}\n\n/* Set DECL up to have the closest approximation of \"initialized common\"\n   linkage available.  */\n\nvoid\nd_comdat_linkage (tree decl)\n{\n  if (flag_weak)\n    make_decl_one_only (decl, d_comdat_group (decl));\n  else if (TREE_CODE (decl) == FUNCTION_DECL\n\t   || (VAR_P (decl) && DECL_ARTIFICIAL (decl)))\n    /* We can just emit function and compiler-generated variables statically;\n       having multiple copies is (for the most part) only a waste of space.  */\n    TREE_PUBLIC (decl) = 0;\n  else if (DECL_INITIAL (decl) == NULL_TREE\n\t   || DECL_INITIAL (decl) == error_mark_node)\n    /* Fallback, cannot have multiple copies.  */\n    DECL_COMMON (decl) = 1;\n\n  if (TREE_PUBLIC (decl))\n    DECL_COMDAT (decl) = 1;\n}\n\n/* Set DECL up to have the closest approximation of \"linkonce\" linkage.  */\n\nvoid\nd_linkonce_linkage (tree decl)\n{\n  /* Weak definitions have to be public.  */\n  if (!TREE_PUBLIC (decl))\n    return;\n\n  /* Necessary to allow DECL_ONE_ONLY or DECL_WEAK functions to be inlined.  */\n  if (TREE_CODE (decl) == FUNCTION_DECL)\n    DECL_DECLARED_INLINE_P (decl) = 1;\n\n  /* No weak support, fallback to COMDAT linkage.  */\n  if (!flag_weak)\n   return d_comdat_linkage (decl);\n\n  make_decl_one_only (decl, d_comdat_group (decl));\n}\n"
  },
  {
    "path": "gcc/d/dmd/MERGE",
    "content": "76d619c28590c632d01e8b0840b358acdf141357\n\nThe first line of this file holds the git revision number of the last\nmerge done from the dlang/dmd repository.\n"
  },
  {
    "path": "gcc/d/dmd/access.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/access.d, _access.d)\n * Documentation:  https://dlang.org/phobos/dmd_access.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/access.d\n */\n\nmodule dmd.access;\n\nimport dmd.aggregate;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.mtype;\nimport dmd.tokens;\n\nprivate enum LOG = false;\n\n/****************************************\n * Return Prot access for Dsymbol smember in this declaration.\n */\nprivate Prot getAccess(AggregateDeclaration ad, Dsymbol smember)\n{\n    Prot access_ret = Prot(Prot.Kind.none);\n    static if (LOG)\n    {\n        printf(\"+AggregateDeclaration::getAccess(this = '%s', smember = '%s')\\n\", ad.toChars(), smember.toChars());\n    }\n    assert(ad.isStructDeclaration() || ad.isClassDeclaration());\n    if (smember.toParent() == ad)\n    {\n        access_ret = smember.prot();\n    }\n    else if (smember.isDeclaration().isStatic())\n    {\n        access_ret = smember.prot();\n    }\n    if (ClassDeclaration cd = ad.isClassDeclaration())\n    {\n        foreach (b; *cd.baseclasses)\n        {\n            Prot access = getAccess(b.sym, smember);\n            final switch (access.kind)\n            {\n            case Prot.Kind.none:\n            case Prot.Kind.undefined:\n                break;\n            case Prot.Kind.private_:\n                access_ret = Prot(Prot.Kind.none); // private members of base class not accessible\n                break;\n            case Prot.Kind.package_:\n            case Prot.Kind.protected_:\n            case Prot.Kind.public_:\n            case Prot.Kind.export_:\n                // If access is to be tightened\n                if (Prot.Kind.public_ < access.kind)\n                    access = Prot(Prot.Kind.public_);\n                // Pick path with loosest access\n                if (access_ret.isMoreRestrictiveThan(access))\n                    access_ret = access;\n                break;\n            }\n        }\n    }\n    static if (LOG)\n    {\n        printf(\"-AggregateDeclaration::getAccess(this = '%s', smember = '%s') = %d\\n\", ad.toChars(), smember.toChars(), access_ret);\n    }\n    return access_ret;\n}\n\n/********************************************************\n * Helper function for checkAccess()\n * Returns:\n *      false   is not accessible\n *      true    is accessible\n */\nprivate bool isAccessible(Dsymbol smember, Dsymbol sfunc, AggregateDeclaration dthis, AggregateDeclaration cdscope)\n{\n    assert(dthis);\n    version (none)\n    {\n        printf(\"isAccessible for %s.%s in function %s() in scope %s\\n\", dthis.toChars(), smember.toChars(), sfunc ? sfunc.toChars() : \"NULL\", cdscope ? cdscope.toChars() : \"NULL\");\n    }\n    if (hasPrivateAccess(dthis, sfunc) || isFriendOf(dthis, cdscope))\n    {\n        if (smember.toParent() == dthis)\n            return true;\n        if (ClassDeclaration cdthis = dthis.isClassDeclaration())\n        {\n            foreach (b; *cdthis.baseclasses)\n            {\n                const Prot access = getAccess(b.sym, smember);\n                if (access.kind >= Prot.Kind.protected_ || isAccessible(smember, sfunc, b.sym, cdscope))\n                {\n                    return true;\n                }\n            }\n        }\n    }\n    else\n    {\n        if (smember.toParent() != dthis)\n        {\n            if (ClassDeclaration cdthis = dthis.isClassDeclaration())\n            {\n                foreach (b; *cdthis.baseclasses)\n                    if (isAccessible(smember, sfunc, b.sym, cdscope))\n                        return true;\n            }\n        }\n    }\n    return false;\n}\n\n/*******************************\n * Do access check for member of this class, this class being the\n * type of the 'this' pointer used to access smember.\n * Returns true if the member is not accessible.\n */\nbool checkAccess(AggregateDeclaration ad, Loc loc, Scope* sc, Dsymbol smember)\n{\n    FuncDeclaration f = sc.func;\n    AggregateDeclaration cdscope = sc.getStructClassScope();\n    static if (LOG)\n    {\n        printf(\"AggregateDeclaration::checkAccess() for %s.%s in function %s() in scope %s\\n\", ad.toChars(), smember.toChars(), f ? f.toChars() : null, cdscope ? cdscope.toChars() : null);\n    }\n    Dsymbol smemberparent = smember.toParent();\n    if (!smemberparent || !smemberparent.isAggregateDeclaration())\n    {\n        static if (LOG)\n        {\n            printf(\"not an aggregate member\\n\");\n        }\n        return false; // then it is accessible\n    }\n    // BUG: should enable this check\n    //assert(smember.parent.isBaseOf(this, NULL));\n    bool result;\n    Prot access;\n    if (smemberparent == ad)\n    {\n        access = smember.prot();\n        result = access.kind >= Prot.Kind.public_ || hasPrivateAccess(ad, f) || isFriendOf(ad, cdscope) || (access.kind == Prot.Kind.package_ && hasPackageAccess(sc, smember)) || ad.getAccessModule() == sc._module;\n        static if (LOG)\n        {\n            printf(\"result1 = %d\\n\", result);\n        }\n    }\n    else if ((access = getAccess(ad, smember)).kind >= Prot.Kind.public_)\n    {\n        result = true;\n        static if (LOG)\n        {\n            printf(\"result2 = %d\\n\", result);\n        }\n    }\n    else if (access.kind == Prot.Kind.package_ && hasPackageAccess(sc, ad))\n    {\n        result = true;\n        static if (LOG)\n        {\n            printf(\"result3 = %d\\n\", result);\n        }\n    }\n    else\n    {\n        result = isAccessible(smember, f, ad, cdscope);\n        static if (LOG)\n        {\n            printf(\"result4 = %d\\n\", result);\n        }\n    }\n    if (!result && (!(sc.flags & SCOPE.onlysafeaccess) || sc.func.setUnsafe()))\n    {\n        ad.error(loc, \"member `%s` is not accessible%s\", smember.toChars(), (sc.flags & SCOPE.onlysafeaccess) ? \" from `@safe` code\".ptr : \"\".ptr);\n        //printf(\"smember = %s %s, prot = %d, semanticRun = %d\\n\",\n        //        smember.kind(), smember.toPrettyChars(), smember.prot(), smember.semanticRun);\n        return true;\n    }\n    return false;\n}\n\n/****************************************\n * Determine if this is the same or friend of cd.\n */\nprivate bool isFriendOf(AggregateDeclaration ad, AggregateDeclaration cd)\n{\n    static if (LOG)\n    {\n        printf(\"AggregateDeclaration::isFriendOf(this = '%s', cd = '%s')\\n\", ad.toChars(), cd ? cd.toChars() : \"null\");\n    }\n    if (ad == cd)\n        return true;\n    // Friends if both are in the same module\n    //if (toParent() == cd.toParent())\n    if (cd && ad.getAccessModule() == cd.getAccessModule())\n    {\n        static if (LOG)\n        {\n            printf(\"\\tin same module\\n\");\n        }\n        return true;\n    }\n    static if (LOG)\n    {\n        printf(\"\\tnot friend\\n\");\n    }\n    return false;\n}\n\n/****************************************\n * Determine if scope sc has package level access to s.\n */\nprivate bool hasPackageAccess(Scope* sc, Dsymbol s)\n{\n    return hasPackageAccess(sc._module, s);\n}\n\nprivate bool hasPackageAccess(Module mod, Dsymbol s)\n{\n    static if (LOG)\n    {\n        printf(\"hasPackageAccess(s = '%s', mod = '%s', s.protection.pkg = '%s')\\n\", s.toChars(), mod.toChars(), s.prot().pkg ? s.prot().pkg.toChars() : \"NULL\");\n    }\n    Package pkg = null;\n    if (s.prot().pkg)\n        pkg = s.prot().pkg;\n    else\n    {\n        // no explicit package for protection, inferring most qualified one\n        for (; s; s = s.parent)\n        {\n            if (Module m = s.isModule())\n            {\n                DsymbolTable dst = Package.resolve(m.md ? m.md.packages : null, null, null);\n                assert(dst);\n                Dsymbol s2 = dst.lookup(m.ident);\n                assert(s2);\n                Package p = s2.isPackage();\n                if (p && p.isPackageMod())\n                {\n                    pkg = p;\n                    break;\n                }\n            }\n            else if ((pkg = s.isPackage()) !is null)\n                break;\n        }\n    }\n    static if (LOG)\n    {\n        if (pkg)\n            printf(\"\\tsymbol access binds to package '%s'\\n\", pkg.toChars());\n    }\n    if (pkg)\n    {\n        if (pkg == mod.parent)\n        {\n            static if (LOG)\n            {\n                printf(\"\\tsc is in permitted package for s\\n\");\n            }\n            return true;\n        }\n        if (pkg.isPackageMod() == mod)\n        {\n            static if (LOG)\n            {\n                printf(\"\\ts is in same package.d module as sc\\n\");\n            }\n            return true;\n        }\n        Dsymbol ancestor = mod.parent;\n        for (; ancestor; ancestor = ancestor.parent)\n        {\n            if (ancestor == pkg)\n            {\n                static if (LOG)\n                {\n                    printf(\"\\tsc is in permitted ancestor package for s\\n\");\n                }\n                return true;\n            }\n        }\n    }\n    static if (LOG)\n    {\n        printf(\"\\tno package access\\n\");\n    }\n    return false;\n}\n\n/****************************************\n * Determine if scope sc has protected level access to cd.\n */\nprivate bool hasProtectedAccess(Scope *sc, Dsymbol s)\n{\n    if (auto cd = s.isClassMember()) // also includes interfaces\n    {\n        for (auto scx = sc; scx; scx = scx.enclosing)\n        {\n            if (!scx.scopesym)\n                continue;\n            auto cd2 = scx.scopesym.isClassDeclaration();\n            if (cd2 && cd.isBaseOf(cd2, null))\n                return true;\n        }\n    }\n    return sc._module == s.getAccessModule();\n}\n\n/**********************************\n * Determine if smember has access to private members of this declaration.\n */\nprivate bool hasPrivateAccess(AggregateDeclaration ad, Dsymbol smember)\n{\n    if (smember)\n    {\n        AggregateDeclaration cd = null;\n        Dsymbol smemberparent = smember.toParent();\n        if (smemberparent)\n            cd = smemberparent.isAggregateDeclaration();\n        static if (LOG)\n        {\n            printf(\"AggregateDeclaration::hasPrivateAccess(class %s, member %s)\\n\", ad.toChars(), smember.toChars());\n        }\n        if (ad == cd) // smember is a member of this class\n        {\n            static if (LOG)\n            {\n                printf(\"\\tyes 1\\n\");\n            }\n            return true; // so we get private access\n        }\n        // If both are members of the same module, grant access\n        while (1)\n        {\n            Dsymbol sp = smember.toParent();\n            if (sp.isFuncDeclaration() && smember.isFuncDeclaration())\n                smember = sp;\n            else\n                break;\n        }\n        if (!cd && ad.toParent() == smember.toParent())\n        {\n            static if (LOG)\n            {\n                printf(\"\\tyes 2\\n\");\n            }\n            return true;\n        }\n        if (!cd && ad.getAccessModule() == smember.getAccessModule())\n        {\n            static if (LOG)\n            {\n                printf(\"\\tyes 3\\n\");\n            }\n            return true;\n        }\n    }\n    static if (LOG)\n    {\n        printf(\"\\tno\\n\");\n    }\n    return false;\n}\n\n/****************************************\n * Check access to d for expression e.d\n * Returns true if the declaration is not accessible.\n */\nbool checkAccess(Loc loc, Scope* sc, Expression e, Declaration d)\n{\n    if (sc.flags & SCOPE.noaccesscheck)\n        return false;\n    static if (LOG)\n    {\n        if (e)\n        {\n            printf(\"checkAccess(%s . %s)\\n\", e.toChars(), d.toChars());\n            printf(\"\\te.type = %s\\n\", e.type.toChars());\n        }\n        else\n        {\n            printf(\"checkAccess(%s)\\n\", d.toPrettyChars());\n        }\n    }\n    if (d.isUnitTestDeclaration())\n    {\n        // Unittests are always accessible.\n        return false;\n    }\n    if (!e)\n    {\n        if (d.prot().kind == Prot.Kind.private_ && d.getAccessModule() != sc._module || d.prot().kind == Prot.Kind.package_ && !hasPackageAccess(sc, d))\n        {\n            error(loc, \"%s `%s` is not accessible from module `%s`\", d.kind(), d.toPrettyChars(), sc._module.toChars());\n            return true;\n        }\n    }\n    else if (e.type.ty == Tclass)\n    {\n        // Do access check\n        ClassDeclaration cd = (cast(TypeClass)e.type).sym;\n        if (e.op == TOK.super_)\n        {\n            if (ClassDeclaration cd2 = sc.func.toParent().isClassDeclaration())\n                cd = cd2;\n        }\n        return checkAccess(cd, loc, sc, d);\n    }\n    else if (e.type.ty == Tstruct)\n    {\n        // Do access check\n        StructDeclaration cd = (cast(TypeStruct)e.type).sym;\n        return checkAccess(cd, loc, sc, d);\n    }\n    return false;\n}\n\n/****************************************\n * Check access to package/module `p` from scope `sc`.\n *\n * Params:\n *   loc = source location for issued error message\n *   sc = scope from which to access to a fully qualified package name\n *   p = the package/module to check access for\n * Returns: true if the package is not accessible.\n *\n * Because a global symbol table tree is used for imported packages/modules,\n * access to them needs to be checked based on the imports in the scope chain\n * (see https://issues.dlang.org/show_bug.cgi?id=313).\n *\n */\nbool checkAccess(Loc loc, Scope* sc, Package p)\n{\n    if (sc._module == p)\n        return false;\n    for (; sc; sc = sc.enclosing)\n    {\n        if (sc.scopesym && sc.scopesym.isPackageAccessible(p, Prot(Prot.Kind.private_)))\n            return false;\n    }\n    auto name = p.toPrettyChars();\n    if (p.isPkgMod == PKG.module_ || p.isModule())\n        error(loc, \"%s `%s` is not accessible here, perhaps add `static import %s;`\", p.kind(), name, name);\n    else\n        error(loc, \"%s `%s` is not accessible here\", p.kind(), name);\n    return true;\n}\n\n/**\n * Check whether symbols `s` is visible in `mod`.\n *\n * Params:\n *  mod = lookup origin\n *  s = symbol to check for visibility\n * Returns: true if s is visible in mod\n */\nbool symbolIsVisible(Module mod, Dsymbol s)\n{\n    // should sort overloads by ascending protection instead of iterating here\n    s = mostVisibleOverload(s);\n    final switch (s.prot().kind)\n    {\n    case Prot.Kind.undefined: return true;\n    case Prot.Kind.none: return false; // no access\n    case Prot.Kind.private_: return s.getAccessModule() == mod;\n    case Prot.Kind.package_: return s.getAccessModule() == mod || hasPackageAccess(mod, s);\n    case Prot.Kind.protected_: return s.getAccessModule() == mod;\n    case Prot.Kind.public_, Prot.Kind.export_: return true;\n    }\n}\n\n/**\n * Same as above, but determines the lookup module from symbols `origin`.\n */\nbool symbolIsVisible(Dsymbol origin, Dsymbol s)\n{\n    return symbolIsVisible(origin.getAccessModule(), s);\n}\n\n/**\n * Same as above but also checks for protected symbols visible from scope `sc`.\n * Used for qualified name lookup.\n *\n * Params:\n *  sc = lookup scope\n *  s = symbol to check for visibility\n * Returns: true if s is visible by origin\n */\nbool symbolIsVisible(Scope *sc, Dsymbol s)\n{\n    s = mostVisibleOverload(s);\n    return checkSymbolAccess(sc, s);\n}\n\n/**\n * Check if a symbol is visible from a given scope without taking\n * into account the most visible overload.\n *\n * Params:\n *  sc = lookup scope\n *  s = symbol to check for visibility\n * Returns: true if s is visible by origin\n */\nbool checkSymbolAccess(Scope *sc, Dsymbol s)\n{\n    final switch (s.prot().kind)\n    {\n    case Prot.Kind.undefined: return true;\n    case Prot.Kind.none: return false; // no access\n    case Prot.Kind.private_: return sc._module == s.getAccessModule();\n    case Prot.Kind.package_: return sc._module == s.getAccessModule() || hasPackageAccess(sc._module, s);\n    case Prot.Kind.protected_: return hasProtectedAccess(sc, s);\n    case Prot.Kind.public_, Prot.Kind.export_: return true;\n    }\n}\n\n/**\n * Use the most visible overload to check visibility. Later perform an access\n * check on the resolved overload.  This function is similar to overloadApply,\n * but doesn't recurse nor resolve aliases because protection/visibility is an\n * attribute of the alias not the aliasee.\n */\npublic Dsymbol mostVisibleOverload(Dsymbol s, Module mod = null)\n{\n    if (!s.isOverloadable())\n        return s;\n\n    Dsymbol next, fstart = s, mostVisible = s;\n    for (; s; s = next)\n    {\n        // void func() {}\n        // private void func(int) {}\n        if (auto fd = s.isFuncDeclaration())\n            next = fd.overnext;\n        // template temp(T) {}\n        // private template temp(T:int) {}\n        else if (auto td = s.isTemplateDeclaration())\n            next = td.overnext;\n        // alias common = mod1.func1;\n        // alias common = mod2.func2;\n        else if (auto fa = s.isFuncAliasDeclaration())\n            next = fa.overnext;\n        // alias common = mod1.templ1;\n        // alias common = mod2.templ2;\n        else if (auto od = s.isOverDeclaration())\n            next = od.overnext;\n        // alias name = sym;\n        // private void name(int) {}\n        else if (auto ad = s.isAliasDeclaration())\n        {\n            assert(ad.isOverloadable || ad.type && ad.type.ty == Terror,\n                \"Non overloadable Aliasee in overload list\");\n            // Yet unresolved aliases store overloads in overnext.\n            if (ad.semanticRun < PASS.semanticdone)\n                next = ad.overnext;\n            else\n            {\n                /* This is a bit messy due to the complicated implementation of\n                 * alias.  Aliases aren't overloadable themselves, but if their\n                 * Aliasee is overloadable they can be converted to an overloadable\n                 * alias.\n                 *\n                 * This is done by replacing the Aliasee w/ FuncAliasDeclaration\n                 * (for functions) or OverDeclaration (for templates) which are\n                 * simply overloadable aliases w/ weird names.\n                 *\n                 * Usually aliases should not be resolved for visibility checking\n                 * b/c public aliases to private symbols are public. But for the\n                 * overloadable alias situation, the Alias (_ad_) has been moved\n                 * into it's own Aliasee, leaving a shell that we peel away here.\n                 */\n                auto aliasee = ad.toAlias();\n                if (aliasee.isFuncAliasDeclaration || aliasee.isOverDeclaration)\n                    next = aliasee;\n                else\n                {\n                    /* A simple alias can be at the end of a function or template overload chain.\n                     * It can't have further overloads b/c it would have been\n                     * converted to an overloadable alias.\n                     */\n                    assert(ad.overnext is null, \"Unresolved overload of alias\");\n                    break;\n                }\n            }\n            // handled by dmd.func.overloadApply for unknown reason\n            assert(next !is ad); // should not alias itself\n            assert(next !is fstart); // should not alias the overload list itself\n        }\n        else\n            break;\n\n        /**\n        * Return the \"effective\" protection attribute of a symbol when accessed in a module.\n        * The effective protection attribute is the same as the regular protection attribute,\n        * except package() is \"private\" if the module is outside the package;\n        * otherwise, \"public\".\n        */\n        static Prot protectionSeenFromModule(Dsymbol d, Module mod = null)\n        {\n            Prot prot = d.prot();\n            if (mod && prot.kind == Prot.Kind.package_)\n            {\n                return hasPackageAccess(mod, d) ? Prot(Prot.Kind.public_) : Prot(Prot.Kind.private_);\n            }\n            return prot;\n        }\n\n        if (next &&\n            protectionSeenFromModule(mostVisible, mod).isMoreRestrictiveThan(protectionSeenFromModule(next, mod)))\n            mostVisible = next;\n    }\n    return mostVisible;\n}\n"
  },
  {
    "path": "gcc/d/dmd/aggregate.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/aggregate.d, _aggregate.d)\n * Documentation:  https://dlang.org/phobos/dmd_aggregate.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/aggregate.d\n */\n\nmodule dmd.aggregate;\n\nimport core.stdc.stdio;\nimport core.checkedint;\n\nimport dmd.arraytypes;\nimport dmd.gluelayer;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.semantic2;\nimport dmd.semantic3;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.visitor;\n\nenum Sizeok : int\n{\n    none,           // size of aggregate is not yet able to compute\n    fwd,            // size of aggregate is ready to compute\n    done,           // size of aggregate is set correctly\n}\n\nenum Baseok : int\n{\n    none,             // base classes not computed yet\n    start,            // in process of resolving base classes\n    done,             // all base classes are resolved\n    semanticdone,     // all base classes semantic done\n}\n\n/**\n * The ClassKind enum is used in AggregateDeclaration AST nodes to\n * specify the linkage type of the struct/class/interface or if it\n * is an anonymous class. If the class is anonymous it is also\n * considered to be a D class.\n */\nenum ClassKind : int\n{\n    /// the aggregate is a d(efault) class\n    d,\n    /// the aggregate is a C++ struct/class/interface\n    cpp,\n    /// the aggregate is an Objective-C class/interface\n    objc,\n}\n\n/***********************************************************\n */\nextern (C++) abstract class AggregateDeclaration : ScopeDsymbol\n{\n    Type type;\n    StorageClass storage_class;\n    Prot protection;\n    uint structsize;        // size of struct\n    uint alignsize;         // size of struct for alignment purposes\n    VarDeclarations fields; // VarDeclaration fields\n    Sizeok sizeok;          // set when structsize contains valid data\n    Dsymbol deferred;       // any deferred semantic2() or semantic3() symbol\n    bool isdeprecated;      // true if deprecated\n\n    /// specifies whether this is a D, C++, Objective-C or anonymous struct/class/interface\n    ClassKind classKind;\n\n    /* !=null if is nested\n     * pointing to the dsymbol that directly enclosing it.\n     * 1. The function that enclosing it (nested struct and class)\n     * 2. The class that enclosing it (nested class only)\n     * 3. If enclosing aggregate is template, its enclosing dsymbol.\n     * See AggregateDeclaraton::makeNested for the details.\n     */\n    Dsymbol enclosing;\n\n    VarDeclaration vthis;   // 'this' parameter if this aggregate is nested\n\n    // Special member functions\n    FuncDeclarations invs;          // Array of invariants\n    FuncDeclaration inv;            // invariant\n    NewDeclaration aggNew;          // allocator\n    DeleteDeclaration aggDelete;    // deallocator\n\n    // CtorDeclaration or TemplateDeclaration\n    Dsymbol ctor;\n\n    // default constructor - should have no arguments, because\n    // it would be stored in TypeInfo_Class.defaultConstructor\n    CtorDeclaration defaultCtor;\n\n    Dsymbol aliasthis;      // forward unresolved lookups to aliasthis\n    bool noDefaultCtor;     // no default construction\n\n    DtorDeclarations dtors; // Array of destructors\n    DtorDeclaration dtor;   // aggregate destructor\n    DtorDeclaration primaryDtor; // non-deleting C++ destructor, same as dtor for D\n    DtorDeclaration tidtor; // aggregate destructor used in TypeInfo (must have extern(D) ABI)\n    FuncDeclaration fieldDtor;   // aggregate destructor for just the fields\n\n    Expression getRTInfo;   // pointer to GC info generated by object.RTInfo(this)\n\n    final extern (D) this(const ref Loc loc, Identifier id)\n    {\n        super(id);\n        this.loc = loc;\n        protection = Prot(Prot.Kind.public_);\n        sizeok = Sizeok.none; // size not determined yet\n    }\n\n    /***************************************\n     * Create a new scope from sc.\n     * semantic, semantic2 and semantic3 will use this for aggregate members.\n     */\n    Scope* newScope(Scope* sc)\n    {\n        auto sc2 = sc.push(this);\n        sc2.stc &= STC.safe | STC.trusted | STC.system;\n        sc2.parent = this;\n        if (isUnionDeclaration())\n            sc2.inunion = true;\n        sc2.protection = Prot(Prot.Kind.public_);\n        sc2.explicitProtection = 0;\n        sc2.aligndecl = null;\n        sc2.userAttribDecl = null;\n        return sc2;\n    }\n\n    override final void setScope(Scope* sc)\n    {\n        // Might need a scope to resolve forward references. The check for\n        // semanticRun prevents unnecessary setting of _scope during deferred\n        // setScope phases for aggregates which already finished semantic().\n        // See https://issues.dlang.org/show_bug.cgi?id=16607\n        if (semanticRun < PASS.semanticdone)\n            ScopeDsymbol.setScope(sc);\n    }\n\n    /***************************************\n     * Find all instance fields, then push them into `fields`.\n     *\n     * Runs semantic() for all instance field variables, but also\n     * the field types can remain yet not resolved forward references,\n     * except direct recursive definitions.\n     * After the process sizeok is set to Sizeok.fwd.\n     *\n     * Returns:\n     *      false if any errors occur.\n     */\n    final bool determineFields()\n    {\n        if (_scope)\n            dsymbolSemantic(this, null);\n        if (sizeok != Sizeok.none)\n            return true;\n\n        //printf(\"determineFields() %s, fields.dim = %d\\n\", toChars(), fields.dim);\n        // determineFields can be called recursively from one of the fields's v.semantic\n        fields.setDim(0);\n\n        extern (C++) static int func(Dsymbol s, void* param)\n        {\n            auto v = s.isVarDeclaration();\n            if (!v)\n                return 0;\n            if (v.storage_class & STC.manifest)\n                return 0;\n\n            auto ad = cast(AggregateDeclaration)param;\n\n            if (v.semanticRun < PASS.semanticdone)\n                v.dsymbolSemantic(null);\n            // Return in case a recursive determineFields triggered by v.semantic already finished\n            if (ad.sizeok != Sizeok.none)\n                return 1;\n\n            if (v.aliassym)\n                return 0;   // If this variable was really a tuple, skip it.\n\n            if (v.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.ctfe | STC.templateparameter))\n                return 0;\n            if (!v.isField() || v.semanticRun < PASS.semanticdone)\n                return 1;   // unresolvable forward reference\n\n            ad.fields.push(v);\n\n            if (v.storage_class & STC.ref_)\n                return 0;\n            auto tv = v.type.baseElemOf();\n            if (tv.ty != Tstruct)\n                return 0;\n            if (ad == (cast(TypeStruct)tv).sym)\n            {\n                const(char)* psz = (v.type.toBasetype().ty == Tsarray) ? \"static array of \" : \"\";\n                ad.error(\"cannot have field `%s` with %ssame struct type\", v.toChars(), psz);\n                ad.type = Type.terror;\n                ad.errors = true;\n                return 1;\n            }\n            return 0;\n        }\n\n        for (size_t i = 0; i < members.dim; i++)\n        {\n            auto s = (*members)[i];\n            if (s.apply(&func, cast(void*)this))\n            {\n                if (sizeok != Sizeok.none)\n                {\n                    // recursive determineFields already finished\n                    return true;\n                }\n                return false;\n            }\n        }\n\n        if (sizeok != Sizeok.done)\n            sizeok = Sizeok.fwd;\n\n        return true;\n    }\n\n    /***************************************\n     * Collect all instance fields, then determine instance size.\n     * Returns:\n     *      false if failed to determine the size.\n     */\n    final bool determineSize(Loc loc)\n    {\n        //printf(\"AggregateDeclaration::determineSize() %s, sizeok = %d\\n\", toChars(), sizeok);\n\n        // The previous instance size finalizing had:\n        if (type.ty == Terror)\n            return false;   // failed already\n        if (sizeok == Sizeok.done)\n            return true;    // succeeded\n\n        if (!members)\n        {\n            error(loc, \"unknown size\");\n            return false;\n        }\n\n        if (_scope)\n            dsymbolSemantic(this, null);\n\n        // Determine the instance size of base class first.\n        if (auto cd = isClassDeclaration())\n        {\n            cd = cd.baseClass;\n            if (cd && !cd.determineSize(loc))\n                goto Lfail;\n        }\n\n        // Determine instance fields when sizeok == Sizeok.none\n        if (!determineFields())\n            goto Lfail;\n        if (sizeok != Sizeok.done)\n            finalizeSize();\n\n        // this aggregate type has:\n        if (type.ty == Terror)\n            return false;   // marked as invalid during the finalizing.\n        if (sizeok == Sizeok.done)\n            return true;    // succeeded to calculate instance size.\n\n    Lfail:\n        // There's unresolvable forward reference.\n        if (type != Type.terror)\n            error(loc, \"no size because of forward reference\");\n        // Don't cache errors from speculative semantic, might be resolvable later.\n        // https://issues.dlang.org/show_bug.cgi?id=16574\n        if (!global.gag)\n        {\n            type = Type.terror;\n            errors = true;\n        }\n        return false;\n    }\n\n    abstract void finalizeSize();\n\n    override final d_uns64 size(const ref Loc loc)\n    {\n        //printf(\"+AggregateDeclaration::size() %s, scope = %p, sizeok = %d\\n\", toChars(), _scope, sizeok);\n        bool ok = determineSize(loc);\n        //printf(\"-AggregateDeclaration::size() %s, scope = %p, sizeok = %d\\n\", toChars(), _scope, sizeok);\n        return ok ? structsize : SIZE_INVALID;\n    }\n\n    /***************************************\n     * Calculate field[i].overlapped and overlapUnsafe, and check that all of explicit\n     * field initializers have unique memory space on instance.\n     * Returns:\n     *      true if any errors happen.\n     */\n    extern (D) final bool checkOverlappedFields()\n    {\n        //printf(\"AggregateDeclaration::checkOverlappedFields() %s\\n\", toChars());\n        assert(sizeok == Sizeok.done);\n        size_t nfields = fields.dim;\n        if (isNested())\n        {\n            auto cd = isClassDeclaration();\n            if (!cd || !cd.baseClass || !cd.baseClass.isNested())\n                nfields--;\n        }\n        bool errors = false;\n\n        // Fill in missing any elements with default initializers\n        foreach (i; 0 .. nfields)\n        {\n            auto vd = fields[i];\n            if (vd.errors)\n            {\n                errors = true;\n                continue;\n            }\n\n            auto vx = vd;\n            if (vd._init && vd._init.isVoidInitializer())\n                vx = null;\n\n            // Find overlapped fields with the hole [vd.offset .. vd.offset.size()].\n            foreach (j; 0 .. nfields)\n            {\n                if (i == j)\n                    continue;\n                auto v2 = fields[j];\n                if (v2.errors)\n                {\n                    errors = true;\n                    continue;\n                }\n                if (!vd.isOverlappedWith(v2))\n                    continue;\n\n                // vd and v2 are overlapping.\n                vd.overlapped = true;\n                v2.overlapped = true;\n\n                if (!MODimplicitConv(vd.type.mod, v2.type.mod))\n                    v2.overlapUnsafe = true;\n                if (!MODimplicitConv(v2.type.mod, vd.type.mod))\n                    vd.overlapUnsafe = true;\n\n                if (!vx)\n                    continue;\n                if (v2._init && v2._init.isVoidInitializer())\n                    continue;\n\n                if (vx._init && v2._init)\n                {\n                    .error(loc, \"overlapping default initialization for field `%s` and `%s`\", v2.toChars(), vd.toChars());\n                    errors = true;\n                }\n            }\n        }\n        return errors;\n    }\n\n    /***************************************\n     * Fill out remainder of elements[] with default initializers for fields[].\n     * Params:\n     *      loc         = location\n     *      elements    = explicit arguments which given to construct object.\n     *      ctorinit    = true if the elements will be used for default initialization.\n     * Returns:\n     *      false if any errors occur.\n     *      Otherwise, returns true and the missing arguments will be pushed in elements[].\n     */\n    final bool fill(Loc loc, Expressions* elements, bool ctorinit)\n    {\n        //printf(\"AggregateDeclaration::fill() %s\\n\", toChars());\n        assert(sizeok == Sizeok.done);\n        assert(elements);\n        size_t nfields = fields.dim - isNested();\n        bool errors = false;\n\n        size_t dim = elements.dim;\n        elements.setDim(nfields);\n        foreach (size_t i; dim .. nfields)\n            (*elements)[i] = null;\n\n        // Fill in missing any elements with default initializers\n        foreach (i; 0 .. nfields)\n        {\n            if ((*elements)[i])\n                continue;\n\n            auto vd = fields[i];\n            auto vx = vd;\n            if (vd._init && vd._init.isVoidInitializer())\n                vx = null;\n\n            // Find overlapped fields with the hole [vd.offset .. vd.offset.size()].\n            size_t fieldi = i;\n            foreach (j; 0 .. nfields)\n            {\n                if (i == j)\n                    continue;\n                auto v2 = fields[j];\n                if (!vd.isOverlappedWith(v2))\n                    continue;\n\n                if ((*elements)[j])\n                {\n                    vx = null;\n                    break;\n                }\n                if (v2._init && v2._init.isVoidInitializer())\n                    continue;\n\n                version (all)\n                {\n                    /* Prefer first found non-void-initialized field\n                     * union U { int a; int b = 2; }\n                     * U u;    // Error: overlapping initialization for field a and b\n                     */\n                    if (!vx)\n                    {\n                        vx = v2;\n                        fieldi = j;\n                    }\n                    else if (v2._init)\n                    {\n                        .error(loc, \"overlapping initialization for field `%s` and `%s`\", v2.toChars(), vd.toChars());\n                        errors = true;\n                    }\n                }\n                else\n                {\n                    // fixes https://issues.dlang.org/show_bug.cgi?id=1432 by enabling this path always\n\n                    /* Prefer explicitly initialized field\n                     * union U { int a; int b = 2; }\n                     * U u;    // OK (u.b == 2)\n                     */\n                    if (!vx || !vx._init && v2._init)\n                    {\n                        vx = v2;\n                        fieldi = j;\n                    }\n                    else if (vx != vd && !vx.isOverlappedWith(v2))\n                    {\n                        // Both vx and v2 fills vd, but vx and v2 does not overlap\n                    }\n                    else if (vx._init && v2._init)\n                    {\n                        .error(loc, \"overlapping default initialization for field `%s` and `%s`\",\n                            v2.toChars(), vd.toChars());\n                        errors = true;\n                    }\n                    else\n                        assert(vx._init || !vx._init && !v2._init);\n                }\n            }\n            if (vx)\n            {\n                Expression e;\n                if (vx.type.size() == 0)\n                {\n                    e = null;\n                }\n                else if (vx._init)\n                {\n                    assert(!vx._init.isVoidInitializer());\n                    if (vx.inuse)   // https://issues.dlang.org/show_bug.cgi?id=18057\n                    {\n                        vx.error(loc, \"recursive initialization of field\");\n                        errors = true;\n                    }\n                    else\n                        e = vx.getConstInitializer(false);\n                }\n                else\n                {\n                    if ((vx.storage_class & STC.nodefaultctor) && !ctorinit)\n                    {\n                        .error(loc, \"field `%s.%s` must be initialized because it has no default constructor\",\n                            type.toChars(), vx.toChars());\n                        errors = true;\n                    }\n                    /* https://issues.dlang.org/show_bug.cgi?id=12509\n                     * Get the element of static array type.\n                     */\n                    Type telem = vx.type;\n                    if (telem.ty == Tsarray)\n                    {\n                        /* We cannot use Type::baseElemOf() here.\n                         * If the bottom of the Tsarray is an enum type, baseElemOf()\n                         * will return the base of the enum, and its default initializer\n                         * would be different from the enum's.\n                         */\n                        while (telem.toBasetype().ty == Tsarray)\n                            telem = (cast(TypeSArray)telem.toBasetype()).next;\n                        if (telem.ty == Tvoid)\n                            telem = Type.tuns8.addMod(telem.mod);\n                    }\n                    if (telem.needsNested() && ctorinit)\n                        e = telem.defaultInit(loc);\n                    else\n                        e = telem.defaultInitLiteral(loc);\n                }\n                (*elements)[fieldi] = e;\n            }\n        }\n        foreach (e; *elements)\n        {\n            if (e && e.op == TOK.error)\n                return false;\n        }\n\n        return !errors;\n    }\n\n    /****************************\n     * Do byte or word alignment as necessary.\n     * Align sizes of 0, as we may not know array sizes yet.\n     * Params:\n     *   alignment = struct alignment that is in effect\n     *   size = alignment requirement of field\n     *   poffset = pointer to offset to be aligned\n     */\n    extern (D) static void alignmember(structalign_t alignment, uint size, uint* poffset) pure nothrow @safe\n    {\n        //printf(\"alignment = %d, size = %d, offset = %d\\n\",alignment,size,offset);\n        switch (alignment)\n        {\n        case cast(structalign_t)1:\n            // No alignment\n            break;\n\n        case cast(structalign_t)STRUCTALIGN_DEFAULT:\n            // Alignment in Target::fieldalignsize must match what the\n            // corresponding C compiler's default alignment behavior is.\n            assert(size > 0 && !(size & (size - 1)));\n            *poffset = (*poffset + size - 1) & ~(size - 1);\n            break;\n\n        default:\n            // Align on alignment boundary, which must be a positive power of 2\n            assert(alignment > 0 && !(alignment & (alignment - 1)));\n            *poffset = (*poffset + alignment - 1) & ~(alignment - 1);\n            break;\n        }\n    }\n\n    /****************************************\n     * Place a member (mem) into an aggregate (agg), which can be a struct, union or class\n     * Returns:\n     *      offset to place field at\n     *\n     * nextoffset:    next location in aggregate\n     * memsize:       size of member\n     * memalignsize:  natural alignment of member\n     * alignment:     alignment in effect for this member\n     * paggsize:      size of aggregate (updated)\n     * paggalignsize: alignment of aggregate (updated)\n     * isunion:       the aggregate is a union\n     */\n    extern (D) static uint placeField(uint* nextoffset, uint memsize, uint memalignsize,\n        structalign_t alignment, uint* paggsize, uint* paggalignsize, bool isunion)\n    {\n        uint ofs = *nextoffset;\n\n        const uint actualAlignment =\n            alignment == STRUCTALIGN_DEFAULT ? memalignsize : alignment;\n\n        // Ensure no overflow\n        bool overflow;\n        const sz = addu(memsize, actualAlignment, overflow);\n        const sum = addu(ofs, sz, overflow);\n        if (overflow) assert(0);\n\n        alignmember(alignment, memalignsize, &ofs);\n        uint memoffset = ofs;\n        ofs += memsize;\n        if (ofs > *paggsize)\n            *paggsize = ofs;\n        if (!isunion)\n            *nextoffset = ofs;\n\n        if (*paggalignsize < actualAlignment)\n            *paggalignsize = actualAlignment;\n\n        return memoffset;\n    }\n\n    override final Type getType()\n    {\n        return type;\n    }\n\n    // is aggregate deprecated?\n    override final bool isDeprecated()\n    {\n        return isdeprecated;\n    }\n\n    /****************************************\n     * Returns true if there's an extra member which is the 'this'\n     * pointer to the enclosing context (enclosing aggregate or function)\n     */\n    final bool isNested()\n    {\n        return enclosing !is null;\n    }\n\n    /* Append vthis field (this.tupleof[$-1]) to make this aggregate type nested.\n     */\n    final void makeNested()\n    {\n        if (enclosing) // if already nested\n            return;\n        if (sizeok == Sizeok.done)\n            return;\n        if (isUnionDeclaration() || isInterfaceDeclaration())\n            return;\n        if (storage_class & STC.static_)\n            return;\n\n        // If nested struct, add in hidden 'this' pointer to outer scope\n        auto s = toParent2();\n        if (!s)\n            return;\n        Type t = null;\n        if (auto fd = s.isFuncDeclaration())\n        {\n            enclosing = fd;\n\n            /* https://issues.dlang.org/show_bug.cgi?id=14422\n             * If a nested class parent is a function, its\n             * context pointer (== `outer`) should be void* always.\n             */\n            t = Type.tvoidptr;\n        }\n        else if (auto ad = s.isAggregateDeclaration())\n        {\n            if (isClassDeclaration() && ad.isClassDeclaration())\n            {\n                enclosing = ad;\n            }\n            else if (isStructDeclaration())\n            {\n                if (auto ti = ad.parent.isTemplateInstance())\n                {\n                    enclosing = ti.enclosing;\n                }\n            }\n            t = ad.handleType();\n        }\n        if (enclosing)\n        {\n            //printf(\"makeNested %s, enclosing = %s\\n\", toChars(), enclosing.toChars());\n            assert(t);\n            if (t.ty == Tstruct)\n                t = Type.tvoidptr; // t should not be a ref type\n\n            assert(!vthis);\n            vthis = new ThisDeclaration(loc, t);\n            //vthis.storage_class |= STC.ref_;\n\n            // Emulate vthis.addMember()\n            members.push(vthis);\n\n            // Emulate vthis.dsymbolSemantic()\n            vthis.storage_class |= STC.field;\n            vthis.parent = this;\n            vthis.protection = Prot(Prot.Kind.public_);\n            vthis.alignment = t.alignment();\n            vthis.semanticRun = PASS.semanticdone;\n\n            if (sizeok == Sizeok.fwd)\n                fields.push(vthis);\n        }\n    }\n\n    override final bool isExport() const\n    {\n        return protection.kind == Prot.Kind.export_;\n    }\n\n    /*******************************************\n     * Look for constructor declaration.\n     */\n    final Dsymbol searchCtor()\n    {\n        auto s = search(Loc.initial, Id.ctor);\n        if (s)\n        {\n            if (!(s.isCtorDeclaration() ||\n                  s.isTemplateDeclaration() ||\n                  s.isOverloadSet()))\n            {\n                s.error(\"is not a constructor; identifiers starting with `__` are reserved for the implementation\");\n                errors = true;\n                s = null;\n            }\n        }\n        if (s && s.toParent() != this)\n            s = null; // search() looks through ancestor classes\n        if (s)\n        {\n            // Finish all constructors semantics to determine this.noDefaultCtor.\n            struct SearchCtor\n            {\n                extern (C++) static int fp(Dsymbol s, void* ctxt)\n                {\n                    auto f = s.isCtorDeclaration();\n                    if (f && f.semanticRun == PASS.init)\n                        f.dsymbolSemantic(null);\n                    return 0;\n                }\n            }\n\n            for (size_t i = 0; i < members.dim; i++)\n            {\n                auto sm = (*members)[i];\n                sm.apply(&SearchCtor.fp, null);\n            }\n        }\n        return s;\n    }\n\n    override final Prot prot()\n    {\n        return protection;\n    }\n\n    // 'this' type\n    final Type handleType()\n    {\n        return type;\n    }\n\n    // Back end\n    Symbol* stag; // tag symbol for debug data\n    Symbol* sinit;\n\n    override final inout(AggregateDeclaration) isAggregateDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/aggregate.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/aggregate.h\n */\n\n#pragma once\n\n#include \"dsymbol.h\"\n#include \"objc.h\"\n\nclass Identifier;\nclass Type;\nclass TypeFunction;\nclass Expression;\nclass FuncDeclaration;\nclass CtorDeclaration;\nclass DtorDeclaration;\nclass NewDeclaration;\nclass DeleteDeclaration;\nclass InterfaceDeclaration;\nclass TypeInfoClassDeclaration;\nclass VarDeclaration;\n\nenum Sizeok\n{\n    SIZEOKnone,         // size of aggregate is not yet able to compute\n    SIZEOKfwd,          // size of aggregate is ready to compute\n    SIZEOKdone          // size of aggregate is set correctly\n};\n\nenum Baseok\n{\n    BASEOKnone,         // base classes not computed yet\n    BASEOKin,           // in process of resolving base classes\n    BASEOKdone,         // all base classes are resolved\n    BASEOKsemanticdone  // all base classes semantic done\n};\n\nenum StructPOD\n{\n    ISPODno,            // struct is not POD\n    ISPODyes,           // struct is POD\n    ISPODfwd            // POD not yet computed\n};\n\nenum Abstract\n{\n    ABSfwdref = 0,      // whether an abstract class is not yet computed\n    ABSyes,             // is abstract class\n    ABSno               // is not abstract class\n};\n\nFuncDeclaration *search_toString(StructDeclaration *sd);\n\nstruct ClassKind\n{\n    enum Type\n    {\n        /// the aggregate is a d(efault) struct/class/interface\n        d,\n        /// the aggregate is a C++ struct/class/interface\n        cpp,\n        /// the aggregate is an Objective-C class/interface\n        objc\n    };\n};\n\nclass AggregateDeclaration : public ScopeDsymbol\n{\npublic:\n    Type *type;\n    StorageClass storage_class;\n    Prot protection;\n    unsigned structsize;        // size of struct\n    unsigned alignsize;         // size of struct for alignment purposes\n    VarDeclarations fields;     // VarDeclaration fields\n    Sizeok sizeok;              // set when structsize contains valid data\n    Dsymbol *deferred;          // any deferred semantic2() or semantic3() symbol\n    bool isdeprecated;          // true if deprecated\n\n    ClassKind::Type classKind;  // specifies the linkage type\n\n    /* !=NULL if is nested\n     * pointing to the dsymbol that directly enclosing it.\n     * 1. The function that enclosing it (nested struct and class)\n     * 2. The class that enclosing it (nested class only)\n     * 3. If enclosing aggregate is template, its enclosing dsymbol.\n     * See AggregateDeclaraton::makeNested for the details.\n     */\n    Dsymbol *enclosing;\n    VarDeclaration *vthis;      // 'this' parameter if this aggregate is nested\n    // Special member functions\n    FuncDeclarations invs;              // Array of invariants\n    FuncDeclaration *inv;               // invariant\n    NewDeclaration *aggNew;             // allocator\n    DeleteDeclaration *aggDelete;       // deallocator\n\n    Dsymbol *ctor;                      // CtorDeclaration or TemplateDeclaration\n\n    // default constructor - should have no arguments, because\n    // it would be stored in TypeInfo_Class.defaultConstructor\n    CtorDeclaration *defaultCtor;\n\n    Dsymbol *aliasthis;         // forward unresolved lookups to aliasthis\n    bool noDefaultCtor;         // no default construction\n\n    DtorDeclarations dtors;     // Array of destructors\n    DtorDeclaration *dtor;      // aggregate destructor\n    DtorDeclaration *primaryDtor; // non-deleting C++ destructor, same as dtor for D\n    DtorDeclaration *tidtor;    // aggregate destructor used in TypeInfo (must have extern(D) ABI)\n    FuncDeclaration *fieldDtor;   // aggregate destructor for just the fields\n\n    Expression *getRTInfo;      // pointer to GC info generated by object.RTInfo(this)\n\n    virtual Scope *newScope(Scope *sc);\n    void setScope(Scope *sc);\n    bool determineFields();\n    bool determineSize(Loc loc);\n    virtual void finalizeSize() = 0;\n    d_uns64 size(const Loc &loc);\n    bool fill(Loc loc, Expressions *elements, bool ctorinit);\n    Type *getType();\n    bool isDeprecated();         // is aggregate deprecated?\n    bool isNested();\n    void makeNested();\n    bool isExport() const;\n    Dsymbol *searchCtor();\n\n    Prot prot();\n\n    // 'this' type\n    Type *handleType() { return type; }\n\n    // Back end\n    Symbol *stag;               // tag symbol for debug data\n    Symbol *sinit;\n\n    AggregateDeclaration *isAggregateDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nstruct StructFlags\n{\n    enum Type\n    {\n        none = 0x0,\n        hasPointers = 0x1  // NB: should use noPointers as in ClassFlags\n    };\n};\n\nclass StructDeclaration : public AggregateDeclaration\n{\npublic:\n    bool zeroInit;              // !=0 if initialize with 0 fill\n    bool hasIdentityAssign;     // true if has identity opAssign\n    bool hasIdentityEquals;     // true if has identity opEquals\n    bool hasNoFields;           // has no fields\n    FuncDeclarations postblits; // Array of postblit functions\n    FuncDeclaration *postblit;  // aggregate postblit\n\n    FuncDeclaration *xeq;       // TypeInfo_Struct.xopEquals\n    FuncDeclaration *xcmp;      // TypeInfo_Struct.xopCmp\n    FuncDeclaration *xhash;     // TypeInfo_Struct.xtoHash\n    static FuncDeclaration *xerreq;      // object.xopEquals\n    static FuncDeclaration *xerrcmp;     // object.xopCmp\n\n    structalign_t alignment;    // alignment applied outside of the struct\n    StructPOD ispod;            // if struct is POD\n\n    // For 64 bit Efl function call/return ABI\n    Type *arg1type;\n    Type *arg2type;\n\n    // Even if struct is defined as non-root symbol, some built-in operations\n    // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.\n    // For those, today TypeInfo_Struct is generated in COMDAT.\n    bool requestTypeInfo;\n\n    static StructDeclaration *create(Loc loc, Identifier *id, bool inObject);\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    void semanticTypeInfoMembers();\n    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);\n    const char *kind() const;\n    void finalizeSize();\n    bool fit(const Loc &loc, Scope *sc, Expressions *elements, Type *stype);\n    bool isPOD();\n\n    StructDeclaration *isStructDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass UnionDeclaration : public StructDeclaration\n{\npublic:\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    const char *kind() const;\n\n    UnionDeclaration *isUnionDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nstruct BaseClass\n{\n    Type *type;                         // (before semantic processing)\n\n    ClassDeclaration *sym;\n    unsigned offset;                    // 'this' pointer offset\n    // for interfaces: Array of FuncDeclaration's\n    // making up the vtbl[]\n    FuncDeclarations vtbl;\n\n    DArray<BaseClass> baseInterfaces;   // if BaseClass is an interface, these\n                                        // are a copy of the InterfaceDeclaration::interfaces\n\n    BaseClass();\n    BaseClass(Type *type);\n\n    bool fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance);\n    void copyBaseInterfaces(BaseClasses *);\n};\n\nstruct ClassFlags\n{\n    enum Type\n    {\n        none = 0x0,\n        isCOMclass = 0x1,\n        noPointers = 0x2,\n        hasOffTi = 0x4,\n        hasCtor = 0x8,\n        hasGetMembers = 0x10,\n        hasTypeInfo = 0x20,\n        isAbstract = 0x40,\n        isCPPclass = 0x80,\n        hasDtor = 0x100\n    };\n};\n\nclass ClassDeclaration : public AggregateDeclaration\n{\npublic:\n    static ClassDeclaration *object;\n    static ClassDeclaration *throwable;\n    static ClassDeclaration *exception;\n    static ClassDeclaration *errorException;\n    static ClassDeclaration *cpp_type_info_ptr;\n\n    ClassDeclaration *baseClass;        // NULL only if this is Object\n    FuncDeclaration *staticCtor;\n    FuncDeclaration *staticDtor;\n    Dsymbols vtbl;                      // Array of FuncDeclaration's making up the vtbl[]\n    Dsymbols vtblFinal;                 // More FuncDeclaration's that aren't in vtbl[]\n\n    BaseClasses *baseclasses;           // Array of BaseClass's; first is super,\n                                        // rest are Interface's\n\n    DArray<BaseClass*> interfaces;      // interfaces[interfaces_dim] for this class\n                                        // (does not include baseClass)\n\n    BaseClasses *vtblInterfaces;        // array of base interfaces that have\n                                        // their own vtbl[]\n\n    TypeInfoClassDeclaration *vclassinfo;       // the ClassInfo object for this ClassDeclaration\n    bool com;                           // true if this is a COM class (meaning it derives from IUnknown)\n    bool stack;                         // true if this is a scope class\n    int cppDtorVtblIndex;               // slot reserved for the virtual destructor [extern(C++)]\n    bool inuse;                         // to prevent recursive attempts\n    bool isActuallyAnonymous;           // true if this class has an identifier, but was originally declared anonymous\n                                        // used in support of https://issues.dlang.org/show_bug.cgi?id=17371\n\n    Abstract isabstract;                // 0: fwdref, 1: is abstract class, 2: not abstract\n    Baseok baseok;                      // set the progress of base classes resolving\n    ObjcClassDeclaration objc;          // Data for a class declaration that is needed for the Objective-C integration\n    Symbol *cpp_type_info_ptr_sym;      // cached instance of class Id.cpp_type_info_ptr\n\n    static ClassDeclaration *create(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject);\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Scope *newScope(Scope *sc);\n    bool isBaseOf2(ClassDeclaration *cd);\n\n    #define OFFSET_RUNTIME 0x76543210\n    #define OFFSET_FWDREF 0x76543211\n    virtual bool isBaseOf(ClassDeclaration *cd, int *poffset);\n    bool isAnonymous();\n\n    bool isBaseInfoComplete();\n    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);\n    ClassDeclaration *searchBase(Identifier *ident);\n    void finalizeSize();\n    bool isFuncHidden(FuncDeclaration *fd);\n    FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);\n    bool isCOMclass() const;\n    virtual bool isCOMinterface() const;\n    bool isCPPclass() const;\n    virtual bool isCPPinterface() const;\n    bool isAbstract();\n    virtual int vtblOffset() const;\n    const char *kind() const;\n\n    void addLocalClass(ClassDeclarations *);\n\n    // Back end\n    Dsymbol *vtblsym;\n    Dsymbol *vtblSymbol();\n\n    ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass InterfaceDeclaration : public ClassDeclaration\n{\npublic:\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Scope *newScope(Scope *sc);\n    bool isBaseOf(ClassDeclaration *cd, int *poffset);\n    bool isBaseOf(BaseClass *bc, int *poffset);\n    const char *kind() const;\n    int vtblOffset() const;\n    bool isCPPinterface() const;\n    bool isCOMinterface() const;\n\n    InterfaceDeclaration *isInterfaceDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n"
  },
  {
    "path": "gcc/d/dmd/aliasthis.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/aliasthis.d, _aliasthis.d)\n * Documentation:  https://dlang.org/phobos/dmd_aliasthis.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/aliasthis.d\n */\n\nmodule dmd.aliasthis;\n\nimport core.stdc.stdio;\nimport dmd.aggregate;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.globals;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.opover;\nimport dmd.tokens;\nimport dmd.visitor;\n\n/***********************************************************\n * alias ident this;\n */\nextern (C++) final class AliasThis : Dsymbol\n{\n    Identifier ident;\n\n    extern (D) this(const ref Loc loc, Identifier ident)\n    {\n        super(null);    // it's anonymous (no identifier)\n        this.loc = loc;\n        this.ident = ident;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new AliasThis(loc, ident);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"alias this\";\n    }\n\n    AliasThis isAliasThis()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\nExpression resolveAliasThis(Scope* sc, Expression e, bool gag = false)\n{\n    for (AggregateDeclaration ad = isAggregate(e.type); ad;)\n    {\n        if (ad.aliasthis)\n        {\n            uint olderrors = gag ? global.startGagging() : 0;\n            Loc loc = e.loc;\n            Type tthis = (e.op == TOK.type ? e.type : null);\n            e = new DotIdExp(loc, e, ad.aliasthis.ident);\n            e = e.expressionSemantic(sc);\n            if (tthis && ad.aliasthis.needThis())\n            {\n                if (e.op == TOK.variable)\n                {\n                    if (auto fd = (cast(VarExp)e).var.isFuncDeclaration())\n                    {\n                        // https://issues.dlang.org/show_bug.cgi?id=13009\n                        // Support better match for the overloaded alias this.\n                        bool hasOverloads;\n                        if (auto f = fd.overloadModMatch(loc, tthis, hasOverloads))\n                        {\n                            if (!hasOverloads)\n                                fd = f;     // use exact match\n                            e = new VarExp(loc, fd, hasOverloads);\n                            e.type = f.type;\n                            e = new CallExp(loc, e);\n                            goto L1;\n                        }\n                    }\n                }\n                /* non-@property function is not called inside typeof(),\n                 * so resolve it ahead.\n                 */\n                {\n                    int save = sc.intypeof;\n                    sc.intypeof = 1; // bypass \"need this\" error check\n                    e = resolveProperties(sc, e);\n                    sc.intypeof = save;\n                }\n            L1:\n                e = new TypeExp(loc, new TypeTypeof(loc, e));\n                e = e.expressionSemantic(sc);\n            }\n            e = resolveProperties(sc, e);\n            if (gag && global.endGagging(olderrors))\n                e = null;\n        }\n\n        import dmd.dclass : ClassDeclaration;\n        auto cd = ad.isClassDeclaration();\n        if ((!e || !ad.aliasthis) && cd && cd.baseClass && cd.baseClass != ClassDeclaration.object)\n        {\n            ad = cd.baseClass;\n            continue;\n        }\n        break;\n    }\n    return e;\n}\n"
  },
  {
    "path": "gcc/d/dmd/apply.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/apply.d, _apply.d)\n * Documentation:  https://dlang.org/phobos/dmd_apply.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/apply.d\n */\n\nmodule dmd.apply;\n\nimport dmd.arraytypes;\nimport dmd.dtemplate;\nimport dmd.expression;\nimport dmd.visitor;\n\n/**************************************\n * An Expression tree walker that will visit each Expression e in the tree,\n * in depth-first evaluation order, and call fp(e,param) on it.\n * fp() signals whether the walking continues with its return value:\n * Returns:\n *      0       continue\n *      1       done\n * It's a bit slower than using virtual functions, but more encapsulated and less brittle.\n * Creating an iterator for this would be much more complex.\n */\nprivate extern (C++) final class PostorderExpressionVisitor : StoppableVisitor\n{\n    alias visit = typeof(super).visit;\npublic:\n    StoppableVisitor v;\n\n    extern (D) this(StoppableVisitor v)\n    {\n        this.v = v;\n    }\n\n    bool doCond(Expression e)\n    {\n        if (!stop && e)\n            e.accept(this);\n        return stop;\n    }\n\n    bool doCond(Expressions* e)\n    {\n        if (!e)\n            return false;\n        for (size_t i = 0; i < e.dim && !stop; i++)\n            doCond((*e)[i]);\n        return stop;\n    }\n\n    bool applyTo(Expression e)\n    {\n        e.accept(v);\n        stop = v.stop;\n        return true;\n    }\n\n    override void visit(Expression e)\n    {\n        applyTo(e);\n    }\n\n    override void visit(NewExp e)\n    {\n        //printf(\"NewExp::apply(): %s\\n\", toChars());\n        doCond(e.thisexp) || doCond(e.newargs) || doCond(e.arguments) || applyTo(e);\n    }\n\n    override void visit(NewAnonClassExp e)\n    {\n        //printf(\"NewAnonClassExp::apply(): %s\\n\", toChars());\n        doCond(e.thisexp) || doCond(e.newargs) || doCond(e.arguments) || applyTo(e);\n    }\n\n    override void visit(TypeidExp e)\n    {\n        doCond(isExpression(e.obj)) || applyTo(e);\n    }\n\n    override void visit(UnaExp e)\n    {\n        doCond(e.e1) || applyTo(e);\n    }\n\n    override void visit(BinExp e)\n    {\n        doCond(e.e1) || doCond(e.e2) || applyTo(e);\n    }\n\n    override void visit(AssertExp e)\n    {\n        //printf(\"CallExp::apply(apply_fp_t fp, void *param): %s\\n\", toChars());\n        doCond(e.e1) || doCond(e.msg) || applyTo(e);\n    }\n\n    override void visit(CallExp e)\n    {\n        //printf(\"CallExp::apply(apply_fp_t fp, void *param): %s\\n\", toChars());\n        doCond(e.e1) || doCond(e.arguments) || applyTo(e);\n    }\n\n    override void visit(ArrayExp e)\n    {\n        //printf(\"ArrayExp::apply(apply_fp_t fp, void *param): %s\\n\", toChars());\n        doCond(e.e1) || doCond(e.arguments) || applyTo(e);\n    }\n\n    override void visit(SliceExp e)\n    {\n        doCond(e.e1) || doCond(e.lwr) || doCond(e.upr) || applyTo(e);\n    }\n\n    override void visit(ArrayLiteralExp e)\n    {\n        doCond(e.basis) || doCond(e.elements) || applyTo(e);\n    }\n\n    override void visit(AssocArrayLiteralExp e)\n    {\n        doCond(e.keys) || doCond(e.values) || applyTo(e);\n    }\n\n    override void visit(StructLiteralExp e)\n    {\n        if (e.stageflags & stageApply)\n            return;\n        int old = e.stageflags;\n        e.stageflags |= stageApply;\n        doCond(e.elements) || applyTo(e);\n        e.stageflags = old;\n    }\n\n    override void visit(TupleExp e)\n    {\n        doCond(e.e0) || doCond(e.exps) || applyTo(e);\n    }\n\n    override void visit(CondExp e)\n    {\n        doCond(e.econd) || doCond(e.e1) || doCond(e.e2) || applyTo(e);\n    }\n}\n\nbool walkPostorder(Expression e, StoppableVisitor v)\n{\n    scope PostorderExpressionVisitor pv = new PostorderExpressionVisitor(v);\n    e.accept(pv);\n    return v.stop;\n}\n"
  },
  {
    "path": "gcc/d/dmd/argtypes.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/argtypes.d, _argtypes.d)\n * Documentation:  https://dlang.org/phobos/dmd_argtypes.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/argtypes.d\n */\n\nmodule dmd.argtypes;\n\nimport core.stdc.stdio;\nimport core.checkedint;\n\nimport dmd.declaration;\nimport dmd.globals;\nimport dmd.mtype;\nimport dmd.visitor;\n\n/****************************************************\n * This breaks a type down into 'simpler' types that can be passed to a function\n * in registers, and returned in registers.\n * It's highly platform dependent.\n * Params:\n *      t = type to break down\n * Returns:\n *      tuple of types, each element can be passed in a register.\n *      A tuple of zero length means the type cannot be passed/returned in registers.\n *      null indicates a `void`.\n * References:\n *  For 64 bit code, follows Itanium C++ ABI 1.86 Chapter 3\n *  http://refspecs.linux-foundation.org/cxxabi-1.86.html#calls\n */\nTypeTuple toArgTypes(Type t)\n{\n    extern (C++) final class ToArgTypes : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        TypeTuple result;\n\n        /*****\n         * Pass type in memory (i.e. on the stack), a tuple of one type, or a tuple of 2 types\n         */\n        void memory()\n        {\n            //printf(\"\\ttoArgTypes() %s => [ ]\\n\", t.toChars());\n            result = new TypeTuple(); // pass on the stack\n        }\n\n        ///\n        void oneType(Type t)\n        {\n            result = new TypeTuple(t);\n        }\n\n        ///\n        void twoTypes(Type t1, Type t2)\n        {\n            result = new TypeTuple(t1, t2);\n        }\n\n\n        override void visit(Type)\n        {\n            // not valid for a parameter\n        }\n\n        override void visit(TypeError)\n        {\n            result = new TypeTuple(Type.terror);\n        }\n\n        override void visit(TypeBasic t)\n        {\n            Type t1 = null;\n            Type t2 = null;\n            switch (t.ty)\n            {\n            case Tvoid:\n                return;\n            case Tbool:\n            case Tint8:\n            case Tuns8:\n            case Tint16:\n            case Tuns16:\n            case Tint32:\n            case Tuns32:\n            case Tfloat32:\n            case Tint64:\n            case Tuns64:\n            case Tint128:\n            case Tuns128:\n            case Tfloat64:\n            case Tfloat80:\n                t1 = t;\n                break;\n            case Timaginary32:\n                t1 = Type.tfloat32;\n                break;\n            case Timaginary64:\n                t1 = Type.tfloat64;\n                break;\n            case Timaginary80:\n                t1 = Type.tfloat80;\n                break;\n            case Tcomplex32:\n                if (global.params.is64bit)\n                    t1 = Type.tfloat64;\n                else\n                {\n                    t1 = Type.tfloat64;\n                    t2 = Type.tfloat64;\n                }\n                break;\n            case Tcomplex64:\n                t1 = Type.tfloat64;\n                t2 = Type.tfloat64;\n                break;\n            case Tcomplex80:\n                t1 = Type.tfloat80;\n                t2 = Type.tfloat80;\n                break;\n            case Tchar:\n                t1 = Type.tuns8;\n                break;\n            case Twchar:\n                t1 = Type.tuns16;\n                break;\n            case Tdchar:\n                t1 = Type.tuns32;\n                break;\n            default:\n                assert(0);\n            }\n            if (t1)\n            {\n                if (t2)\n                    return twoTypes(t1, t2);\n                else\n                    return oneType(t1);\n            }\n            else\n                return memory();\n        }\n\n        override void visit(TypeVector t)\n        {\n            return oneType(t);\n        }\n\n        override void visit(TypeAArray)\n        {\n            return oneType(Type.tvoidptr);\n        }\n\n        override void visit(TypePointer)\n        {\n            return oneType(Type.tvoidptr);\n        }\n\n        /*************************************\n         * Convert a floating point type into the equivalent integral type.\n         */\n        static Type mergeFloatToInt(Type t)\n        {\n            switch (t.ty)\n            {\n            case Tfloat32:\n            case Timaginary32:\n                t = Type.tint32;\n                break;\n            case Tfloat64:\n            case Timaginary64:\n            case Tcomplex32:\n                t = Type.tint64;\n                break;\n            default:\n                debug\n                {\n                    printf(\"mergeFloatToInt() %s\\n\", t.toChars());\n                }\n                assert(0);\n            }\n            return t;\n        }\n\n        /*************************************\n         * This merges two types into an 8byte type.\n         * Params:\n         *      t1 = first type (can be null)\n         *      t2 = second type (can be null)\n         *      offset2 = offset of t2 from start of t1\n         * Returns:\n         *      type that encompasses both t1 and t2, null if cannot be done\n         */\n        static Type argtypemerge(Type t1, Type t2, uint offset2)\n        {\n            //printf(\"argtypemerge(%s, %s, %d)\\n\", t1 ? t1.toChars() : \"\", t2 ? t2.toChars() : \"\", offset2);\n            if (!t1)\n            {\n                assert(!t2 || offset2 == 0);\n                return t2;\n            }\n            if (!t2)\n                return t1;\n            const sz1 = t1.size(Loc.initial);\n            const sz2 = t2.size(Loc.initial);\n            assert(sz1 != SIZE_INVALID && sz2 != SIZE_INVALID);\n            if (t1.ty != t2.ty && (t1.ty == Tfloat80 || t2.ty == Tfloat80))\n                return null;\n            // [float,float] => [cfloat]\n            if (t1.ty == Tfloat32 && t2.ty == Tfloat32 && offset2 == 4)\n                return Type.tfloat64;\n            // Merging floating and non-floating types produces the non-floating type\n            if (t1.isfloating())\n            {\n                if (!t2.isfloating())\n                    t1 = mergeFloatToInt(t1);\n            }\n            else if (t2.isfloating())\n                t2 = mergeFloatToInt(t2);\n            Type t;\n            // Pick type with larger size\n            if (sz1 < sz2)\n                t = t2;\n            else\n                t = t1;\n            // If t2 does not lie within t1, need to increase the size of t to enclose both\n            bool overflow;\n            const offset3 = addu(offset2, sz2, overflow);\n            assert(!overflow);\n            if (offset2 && sz1 < offset3)\n            {\n                switch (offset3)\n                {\n                case 2:\n                    t = Type.tint16;\n                    break;\n                case 3:\n                case 4:\n                    t = Type.tint32;\n                    break;\n                default:\n                    t = Type.tint64;\n                    break;\n                }\n            }\n            return t;\n        }\n\n        override void visit(TypeDArray)\n        {\n            /* Should be done as if it were:\n             * struct S { size_t length; void* ptr; }\n             */\n            if (global.params.is64bit && !global.params.isLP64)\n            {\n                // For AMD64 ILP32 ABI, D arrays fit into a single integer register.\n                const offset = cast(uint)Type.tsize_t.size(Loc.initial);\n                Type t = argtypemerge(Type.tsize_t, Type.tvoidptr, offset);\n                if (t)\n                {\n                    return oneType(t);\n                }\n            }\n            return twoTypes(Type.tsize_t, Type.tvoidptr);\n        }\n\n        override void visit(TypeDelegate)\n        {\n            /* Should be done as if it were:\n             * struct S { void* funcptr; void* ptr; }\n             */\n            if (global.params.is64bit && !global.params.isLP64)\n            {\n                // For AMD64 ILP32 ABI, delegates fit into a single integer register.\n                const offset = cast(uint)Type.tsize_t.size(Loc.initial);\n                Type t = argtypemerge(Type.tvoidptr, Type.tvoidptr, offset);\n                if (t)\n                {\n                    return oneType(t);\n                }\n            }\n            return twoTypes(Type.tvoidptr, Type.tvoidptr);\n        }\n\n        override void visit(TypeSArray t)\n        {\n            const sz = t.size(Loc.initial);\n            if (sz > 16)\n                return memory();\n\n            const dim = t.dim.toInteger();\n            Type tn = t.next;\n            const tnsize = tn.size();\n            const tnalignsize = tn.alignsize();\n\n            /*****\n             * Get the nth element of this array.\n             * Params:\n             *   n = element number, from 0..dim\n             *   offset = set to offset of the element from the start of the array\n             *   alignsize = set to the aligned size of the element\n             * Returns:\n             *   type of the element\n             */\n            extern (D) Type getNthElement(size_t n, out uint offset, out uint alignsize)\n            {\n                offset = cast(uint)(n * tnsize);\n                alignsize = tnalignsize;\n                return tn;\n            }\n\n            aggregate(sz, cast(size_t)dim, &getNthElement);\n        }\n\n        override void visit(TypeStruct t)\n        {\n            //printf(\"TypeStruct.toArgTypes() %s\\n\", t.toChars());\n\n            if (!t.sym.isPOD())\n                return memory();\n\n            /*****\n             * Get the nth field of this struct.\n             * Params:\n             *   n = field number, from 0..nfields\n             *   offset = set to offset of the field from the start of the type\n             *   alignsize = set to the aligned size of the field\n             * Returns:\n             *   type of the field\n             */\n            extern (D) Type getNthField(size_t n, out uint offset, out uint alignsize)\n            {\n                auto field = t.sym.fields[n];\n                offset = field.offset;\n                alignsize = field.type.alignsize();\n                return field.type;\n            }\n\n            aggregate(t.size(Loc.initial), t.sym.fields.dim, &getNthField);\n        }\n\n        /*******************\n         * Handle aggregates (struct, union, and static array) and set `result`\n         * Params:\n         *      sz = total size of aggregate\n         *      nfields = number of fields in the aggregate (dimension for static arrays)\n         *      getFieldInfo = get information about the nth field in the aggregate\n         */\n        extern (D) void aggregate(d_uns64 sz, size_t nfields, Type delegate(size_t, out uint, out uint) getFieldInfo)\n        {\n            if (nfields == 0)\n                return memory();\n\n            if (global.params.is64bit)\n            {\n                if (sz == 0 || sz > 16)\n                    return memory();\n\n                Type t1 = null;\n                Type t2 = null;\n\n                foreach (n; 0 .. nfields)\n                {\n                    uint foffset;\n                    uint falignsize;\n                    Type ftype = getFieldInfo(n, foffset, falignsize);\n\n                    //printf(\"  [%u] ftype = %s\\n\", n, ftype.toChars());\n                    TypeTuple tup = toArgTypes(ftype);\n                    if (!tup)\n                        return memory();\n                    const dim = tup.arguments.dim;\n                    Type ft1 = null;\n                    Type ft2 = null;\n                    switch (dim)\n                    {\n                    case 2:\n                        ft1 = (*tup.arguments)[0].type;\n                        ft2 = (*tup.arguments)[1].type;\n                        break;\n                    case 1:\n                        if (foffset < 8)\n                            ft1 = (*tup.arguments)[0].type;\n                        else\n                            ft2 = (*tup.arguments)[0].type;\n                        break;\n                    default:\n                        return memory();\n                    }\n                    if (foffset & 7)\n                    {\n                        // Misaligned fields goto Lmemory\n                        if (foffset & (falignsize - 1))\n                            return memory();\n\n                        // Fields that overlap the 8byte boundary goto memory\n                        const fieldsz = ftype.size(Loc.initial);\n                        bool overflow;\n                        const nextOffset = addu(foffset, fieldsz, overflow);\n                        assert(!overflow);\n                        if (foffset < 8 && nextOffset > 8)\n                            return memory();\n                    }\n                    // First field in 8byte must be at start of 8byte\n                    assert(t1 || foffset == 0);\n                    //printf(\"ft1 = %s\\n\", ft1 ? ft1.toChars() : \"null\");\n                    //printf(\"ft2 = %s\\n\", ft2 ? ft2.toChars() : \"null\");\n                    if (ft1)\n                    {\n                        t1 = argtypemerge(t1, ft1, foffset);\n                        if (!t1)\n                            return memory();\n                    }\n                    if (ft2)\n                    {\n                        const off2 = ft1 ? 8 : foffset;\n                        if (!t2 && off2 != 8)\n                            return memory();\n                        assert(t2 || off2 == 8);\n                        t2 = argtypemerge(t2, ft2, off2 - 8);\n                        if (!t2)\n                            return memory();\n                    }\n                }\n                if (t2)\n                {\n                    if (t1.isfloating() && t2.isfloating())\n                    {\n                        if ((t1.ty == Tfloat32 || t1.ty == Tfloat64) && (t2.ty == Tfloat32 || t2.ty == Tfloat64))\n                        {\n                        }\n                        else\n                            return memory();\n                    }\n                    else if (t1.isfloating() || t2.isfloating())\n                        return memory();\n                    return twoTypes(t1, t2);\n                }\n\n                //printf(\"\\ttoArgTypes() %s => [%s,%s]\\n\", t.toChars(), t1 ? t1.toChars() : \"\", t2 ? t2.toChars() : \"\");\n                if (t1)\n                    return oneType(t1);\n                else\n                    return memory();\n            }\n            else\n            {\n                Type t1 = null;\n                switch (cast(uint)sz)\n                {\n                case 1:\n                    t1 = Type.tint8;\n                    break;\n                case 2:\n                    t1 = Type.tint16;\n                    break;\n                case 4:\n                    t1 = Type.tint32;\n                    break;\n                case 8:\n                    t1 = Type.tint64;\n                    break;\n                case 16:\n                    t1 = null; // could be a TypeVector\n                    break;\n                default:\n                    return memory();\n                }\n                if (global.params.isFreeBSD && nfields == 1 &&\n                    (sz == 4 || sz == 8))\n                {\n                    /* FreeBSD changed their 32 bit ABI at some point before 10.3 for the following:\n                     *  struct { float f;  } => arg1type is float\n                     *  struct { double d; } => arg1type is double\n                     * Cannot find any documentation on it.\n                     */\n\n                    uint foffset;\n                    uint falignsize;\n                    Type ftype = getFieldInfo(0, foffset, falignsize);\n                    TypeTuple tup = toArgTypes(ftype);\n                    if (tup && tup.arguments.dim == 1)\n                    {\n                        Type ft1 = (*tup.arguments)[0].type;\n                        if (ft1.ty == Tfloat32 || ft1.ty == Tfloat64)\n                            return oneType(ft1);\n                    }\n                }\n\n                if (t1)\n                    return oneType(t1);\n                else\n                    return memory();\n            }\n        }\n\n        override void visit(TypeEnum t)\n        {\n            t.toBasetype().accept(this);\n        }\n\n        override void visit(TypeClass)\n        {\n            result = new TypeTuple(Type.tvoidptr);\n        }\n    }\n\n    scope ToArgTypes v = new ToArgTypes();\n    t.accept(v);\n    return v.result;\n}\n"
  },
  {
    "path": "gcc/d/dmd/arrayop.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/arrayop.d, _arrayop.d)\n * Documentation:  https://dlang.org/phobos/dmd_arrayop.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/arrayop.d\n */\n\nmodule dmd.arrayop;\n\nimport core.stdc.stdio;\nimport dmd.arraytypes;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.root.outbuffer;\nimport dmd.statement;\nimport dmd.tokens;\nimport dmd.visitor;\n\n/**********************************************\n * Check that there are no uses of arrays without [].\n */\nbool isArrayOpValid(Expression e)\n{\n    if (e.op == TOK.slice)\n        return true;\n    if (e.op == TOK.arrayLiteral)\n    {\n        Type t = e.type.toBasetype();\n        while (t.ty == Tarray || t.ty == Tsarray)\n            t = t.nextOf().toBasetype();\n        return (t.ty != Tvoid);\n    }\n    Type tb = e.type.toBasetype();\n    if (tb.ty == Tarray || tb.ty == Tsarray)\n    {\n        if (isUnaArrayOp(e.op))\n        {\n            return isArrayOpValid((cast(UnaExp)e).e1);\n        }\n        if (isBinArrayOp(e.op) || isBinAssignArrayOp(e.op) || e.op == TOK.assign)\n        {\n            BinExp be = cast(BinExp)e;\n            return isArrayOpValid(be.e1) && isArrayOpValid(be.e2);\n        }\n        if (e.op == TOK.construct)\n        {\n            BinExp be = cast(BinExp)e;\n            return be.e1.op == TOK.slice && isArrayOpValid(be.e2);\n        }\n        // if (e.op == TOK.call)\n        // {\n        // TODO: Decide if [] is required after arrayop calls.\n        // }\n        return false;\n    }\n    return true;\n}\n\nbool isNonAssignmentArrayOp(Expression e)\n{\n    if (e.op == TOK.slice)\n        return isNonAssignmentArrayOp((cast(SliceExp)e).e1);\n\n    Type tb = e.type.toBasetype();\n    if (tb.ty == Tarray || tb.ty == Tsarray)\n    {\n        return (isUnaArrayOp(e.op) || isBinArrayOp(e.op));\n    }\n    return false;\n}\n\nbool checkNonAssignmentArrayOp(Expression e, bool suggestion = false)\n{\n    if (isNonAssignmentArrayOp(e))\n    {\n        const(char)* s = \"\";\n        if (suggestion)\n            s = \" (possible missing [])\";\n        e.error(\"array operation `%s` without destination memory not allowed%s\", e.toChars(), s);\n        return true;\n    }\n    return false;\n}\n\n/***********************************\n * Construct the array operation expression, call object._arrayOp!(tiargs)(args).\n * Encode operand types and operations into tiargs using reverse polish notation (RPN) to preserve precedence.\n * Unary operations are prefixed with \"u\" (e.g. \"u~\").\n * Pass operand values (slices or scalars) as args.\n *\n * Scalar expression sub-trees of `e` are evaluated before calling\n * into druntime to hoist them out of the loop. This is a valid\n * evaluation order as the actual array operations have no\n * side-effect.\n */\nExpression arrayOp(BinExp e, Scope* sc)\n{\n    //printf(\"BinExp.arrayOp() %s\\n\", toChars());\n    Type tb = e.type.toBasetype();\n    assert(tb.ty == Tarray || tb.ty == Tsarray);\n    Type tbn = tb.nextOf().toBasetype();\n    if (tbn.ty == Tvoid)\n    {\n        e.error(\"cannot perform array operations on `void[]` arrays\");\n        return new ErrorExp();\n    }\n    if (!isArrayOpValid(e))\n        return arrayOpInvalidError(e);\n\n    auto tiargs = new Objects();\n    auto args = new Expressions();\n    buildArrayOp(sc, e, tiargs, args);\n\n    import dmd.dtemplate : TemplateDeclaration;\n    __gshared TemplateDeclaration arrayOp;\n    if (arrayOp is null)\n    {\n        Expression id = new IdentifierExp(e.loc, Id.empty);\n        id = new DotIdExp(e.loc, id, Id.object);\n        id = new DotIdExp(e.loc, id, Identifier.idPool(\"_arrayOp\"));\n        id = id.expressionSemantic(sc);\n        if (id.op != TOK.template_)\n            ObjectNotFound(Identifier.idPool(\"_arrayOp\"));\n        arrayOp = (cast(TemplateExp)id).td;\n    }\n\n    auto fd = resolveFuncCall(e.loc, sc, arrayOp, tiargs, null, args);\n    if (!fd || fd.errors)\n        return new ErrorExp();\n    return new CallExp(e.loc, new VarExp(e.loc, fd, false), args).expressionSemantic(sc);\n}\n\n/// ditto\nExpression arrayOp(BinAssignExp e, Scope* sc)\n{\n    //printf(\"BinAssignExp.arrayOp() %s\\n\", toChars());\n\n    /* Check that the elements of e1 can be assigned to\n     */\n    Type tn = e.e1.type.toBasetype().nextOf();\n\n    if (tn && (!tn.isMutable() || !tn.isAssignable()))\n    {\n        e.error(\"slice `%s` is not mutable\", e.e1.toChars());\n        return new ErrorExp();\n    }\n    if (e.e1.op == TOK.arrayLiteral)\n    {\n        return e.e1.modifiableLvalue(sc, e.e1);\n    }\n\n    return arrayOp(cast(BinExp)e, sc);\n}\n\n/******************************************\n * Convert the expression tree e to template and function arguments,\n * using reverse polish notation (RPN) to encode order of operations.\n * Encode operations as string arguments, using a \"u\" prefix for unary operations.\n */\nprivate void buildArrayOp(Scope* sc, Expression e, Objects* tiargs, Expressions* args)\n{\n    extern (C++) final class BuildArrayOpVisitor : Visitor\n    {\n        alias visit = Visitor.visit;\n        Scope* sc;\n        Objects* tiargs;\n        Expressions* args;\n\n    public:\n        extern (D) this(Scope* sc, Objects* tiargs, Expressions* args)\n        {\n            this.sc = sc;\n            this.tiargs = tiargs;\n            this.args = args;\n        }\n\n        override void visit(Expression e)\n        {\n            tiargs.push(e.type);\n            args.push(e);\n        }\n\n        override void visit(SliceExp e)\n        {\n            visit(cast(Expression) e);\n        }\n\n        override void visit(CastExp e)\n        {\n            visit(cast(Expression) e);\n        }\n\n        override void visit(UnaExp e)\n        {\n            Type tb = e.type.toBasetype();\n            if (tb.ty != Tarray && tb.ty != Tsarray) // hoist scalar expressions\n            {\n                visit(cast(Expression) e);\n            }\n            else\n            {\n                // RPN, prefix unary ops with u\n                OutBuffer buf;\n                buf.writestring(\"u\");\n                buf.writestring(Token.toString(e.op));\n                e.e1.accept(this);\n                tiargs.push(new StringExp(Loc.initial, buf.extractString()).expressionSemantic(sc));\n            }\n        }\n\n        override void visit(BinExp e)\n        {\n            Type tb = e.type.toBasetype();\n            if (tb.ty != Tarray && tb.ty != Tsarray) // hoist scalar expressions\n            {\n                visit(cast(Expression) e);\n            }\n            else\n            {\n                // RPN\n                e.e1.accept(this);\n                e.e2.accept(this);\n                tiargs.push(new StringExp(Loc.initial, cast(char*) Token.toChars(e.op)).expressionSemantic(sc));\n            }\n        }\n    }\n\n    scope v = new BuildArrayOpVisitor(sc, tiargs, args);\n    e.accept(v);\n}\n\n/***********************************************\n * Test if expression is a unary array op.\n */\nbool isUnaArrayOp(TOK op)\n{\n    switch (op)\n    {\n    case TOK.negate:\n    case TOK.tilde:\n        return true;\n    default:\n        break;\n    }\n    return false;\n}\n\n/***********************************************\n * Test if expression is a binary array op.\n */\nbool isBinArrayOp(TOK op)\n{\n    switch (op)\n    {\n    case TOK.add:\n    case TOK.min:\n    case TOK.mul:\n    case TOK.div:\n    case TOK.mod:\n    case TOK.xor:\n    case TOK.and:\n    case TOK.or:\n    case TOK.pow:\n        return true;\n    default:\n        break;\n    }\n    return false;\n}\n\n/***********************************************\n * Test if expression is a binary assignment array op.\n */\nbool isBinAssignArrayOp(TOK op)\n{\n    switch (op)\n    {\n    case TOK.addAssign:\n    case TOK.minAssign:\n    case TOK.mulAssign:\n    case TOK.divAssign:\n    case TOK.modAssign:\n    case TOK.xorAssign:\n    case TOK.andAssign:\n    case TOK.orAssign:\n    case TOK.powAssign:\n        return true;\n    default:\n        break;\n    }\n    return false;\n}\n\n/***********************************************\n * Test if operand is a valid array op operand.\n */\nbool isArrayOpOperand(Expression e)\n{\n    //printf(\"Expression.isArrayOpOperand() %s\\n\", e.toChars());\n    if (e.op == TOK.slice)\n        return true;\n    if (e.op == TOK.arrayLiteral)\n    {\n        Type t = e.type.toBasetype();\n        while (t.ty == Tarray || t.ty == Tsarray)\n            t = t.nextOf().toBasetype();\n        return (t.ty != Tvoid);\n    }\n    Type tb = e.type.toBasetype();\n    if (tb.ty == Tarray)\n    {\n        return (isUnaArrayOp(e.op) ||\n                isBinArrayOp(e.op) ||\n                isBinAssignArrayOp(e.op) ||\n                e.op == TOK.assign);\n    }\n    return false;\n}\n\n\n/***************************************************\n * Print error message about invalid array operation.\n * Params:\n *      e = expression with the invalid array operation\n * Returns:\n *      instance of ErrorExp\n */\n\nErrorExp arrayOpInvalidError(Expression e)\n{\n    e.error(\"invalid array operation `%s` (possible missing [])\", e.toChars());\n    return new ErrorExp();\n}\n"
  },
  {
    "path": "gcc/d/dmd/arraytypes.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/arraytypes.d, _arraytypes.d)\n * Documentation:  https://dlang.org/phobos/dmd_arraytypes.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/arraytypes.d\n */\n\nmodule dmd.arraytypes;\n\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dmodule;\nimport dmd.dsymbol;\nimport dmd.dtemplate;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.mtype;\nimport dmd.root.array;\nimport dmd.root.rootobject;\nimport dmd.statement;\n\nalias Strings = Array!(const(char)*);\nalias Identifiers = Array!(Identifier);\nalias TemplateParameters = Array!(TemplateParameter);\nalias Expressions = Array!(Expression);\nalias Statements = Array!(Statement);\nalias BaseClasses = Array!(BaseClass*);\nalias ClassDeclarations = Array!(ClassDeclaration);\nalias Dsymbols = Array!(Dsymbol);\nalias Objects = Array!(RootObject);\nalias DtorDeclarations = Array!(DtorDeclaration);\nalias FuncDeclarations = Array!(FuncDeclaration);\nalias Parameters = Array!(Parameter);\nalias Initializers = Array!(Initializer);\nalias VarDeclarations = Array!(VarDeclaration);\nalias Types = Array!(Type);\nalias Catches = Array!(Catch);\nalias StaticDtorDeclarations = Array!(StaticDtorDeclaration);\nalias SharedStaticDtorDeclarations = Array!(SharedStaticDtorDeclaration);\nalias AliasDeclarations = Array!(AliasDeclaration);\nalias Modules = Array!(Module);\nalias CaseStatements = Array!(CaseStatement);\nalias ScopeStatements = Array!(ScopeStatement);\nalias GotoCaseStatements = Array!(GotoCaseStatement);\nalias ReturnStatements = Array!(ReturnStatement);\nalias GotoStatements = Array!(GotoStatement);\nalias TemplateInstances = Array!(TemplateInstance);\nalias Ensures = Array!(Ensure);\n"
  },
  {
    "path": "gcc/d/dmd/arraytypes.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 2006-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/arraytypes.h\n */\n\n#pragma once\n\n#include \"root/array.h\"\n\ntypedef Array<class TemplateParameter *> TemplateParameters;\n\ntypedef Array<class Expression *> Expressions;\n\ntypedef Array<class Statement *> Statements;\n\ntypedef Array<struct BaseClass *> BaseClasses;\n\ntypedef Array<class ClassDeclaration *> ClassDeclarations;\n\ntypedef Array<class Dsymbol *> Dsymbols;\n\ntypedef Array<class RootObject *> Objects;\n\ntypedef Array<class DtorDeclaration *> DtorDeclarations;\n\ntypedef Array<class FuncDeclaration *> FuncDeclarations;\n\ntypedef Array<class Parameter *> Parameters;\n\ntypedef Array<class Identifier *> Identifiers;\n\ntypedef Array<class Initializer *> Initializers;\n\ntypedef Array<class VarDeclaration *> VarDeclarations;\n\ntypedef Array<class Type *> Types;\ntypedef Array<class Catch *> Catches;\n\ntypedef Array<class StaticDtorDeclaration *> StaticDtorDeclarations;\n\ntypedef Array<class SharedStaticDtorDeclaration *> SharedStaticDtorDeclarations;\n\ntypedef Array<class AliasDeclaration *> AliasDeclarations;\n\ntypedef Array<class Module *> Modules;\n\ntypedef Array<struct File *> Files;\n\ntypedef Array<class CaseStatement *> CaseStatements;\n\ntypedef Array<class ScopeStatement *> ScopeStatements;\n\ntypedef Array<class GotoCaseStatement *> GotoCaseStatements;\n\ntypedef Array<class ReturnStatement *> ReturnStatements;\n\ntypedef Array<class GotoStatement *> GotoStatements;\n\ntypedef Array<class TemplateInstance *> TemplateInstances;\n\ntypedef Array<struct Ensure> Ensures;\n"
  },
  {
    "path": "gcc/d/dmd/astcodegen.d",
    "content": "module dmd.astcodegen;\n\n/**\n * Documentation:  https://dlang.org/phobos/dmd_astcodegen.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/astcodegen.d\n */\n\nstruct ASTCodegen\n{\n    public import dmd.aggregate;\n    public import dmd.aliasthis;\n    public import dmd.arraytypes;\n    public import dmd.attrib;\n    public import dmd.cond;\n    public import dmd.dclass;\n    public import dmd.declaration;\n    public import dmd.denum;\n    public import dmd.dimport;\n    public import dmd.dmodule;\n    public import dmd.dstruct;\n    public import dmd.dsymbol;\n    public import dmd.dtemplate;\n    public import dmd.dversion;\n    public import dmd.expression;\n    public import dmd.func;\n    public import dmd.hdrgen;\n    public import dmd.init;\n    public import dmd.initsem;\n    public import dmd.mtype;\n    public import dmd.nspace;\n    public import dmd.statement;\n    public import dmd.staticassert;\n    public import dmd.typesem;\n    public import dmd.ctfeexpr;\n\n\n    alias initializerToExpression   = dmd.initsem.initializerToExpression;\n    alias typeToExpression          = dmd.typesem.typeToExpression;\n    alias UserAttributeDeclaration  = dmd.attrib.UserAttributeDeclaration;\n    alias Ensure                    = dmd.func.Ensure; // workaround for bug in older DMD frontends\n\n    alias MODFlags                  = dmd.mtype.MODFlags;\n    alias Type                      = dmd.mtype.Type;\n    alias Parameter                 = dmd.mtype.Parameter;\n    alias Taarray                   = dmd.mtype.Taarray;\n    alias Tbool                     = dmd.mtype.Tbool;\n    alias Tchar                     = dmd.mtype.Tchar;\n    alias Tdchar                    = dmd.mtype.Tdchar;\n    alias Tdelegate                 = dmd.mtype.Tdelegate;\n    alias Tenum                     = dmd.mtype.Tenum;\n    alias Terror                    = dmd.mtype.Terror;\n    alias Tfloat32                  = dmd.mtype.Tfloat32;\n    alias Tfloat64                  = dmd.mtype.Tfloat64;\n    alias Tfloat80                  = dmd.mtype.Tfloat80;\n    alias Tfunction                 = dmd.mtype.Tfunction;\n    alias Tident                    = dmd.mtype.Tident;\n    alias Tint8                     = dmd.mtype.Tint8;\n    alias Tint16                    = dmd.mtype.Tint16;\n    alias Tint32                    = dmd.mtype.Tint32;\n    alias Tint64                    = dmd.mtype.Tint64;\n    alias Tsarray                   = dmd.mtype.Tsarray;\n    alias Tstruct                   = dmd.mtype.Tstruct;\n    alias Tuns8                     = dmd.mtype.Tuns8;\n    alias Tuns16                    = dmd.mtype.Tuns16;\n    alias Tuns32                    = dmd.mtype.Tuns32;\n    alias Tuns64                    = dmd.mtype.Tuns64;\n    alias Tvoid                     = dmd.mtype.Tvoid;\n    alias Twchar                    = dmd.mtype.Twchar;\n\n    alias STC                       = dmd.declaration.STC;\n    alias Dsymbol                   = dmd.dsymbol.Dsymbol;\n    alias Dsymbols                  = dmd.dsymbol.Dsymbols;\n    alias Prot                      = dmd.dsymbol.Prot;\n\n    alias stcToBuffer               = dmd.hdrgen.stcToBuffer;\n    alias linkageToChars            = dmd.hdrgen.linkageToChars;\n    alias protectionToChars         = dmd.hdrgen.protectionToChars;\n\n    alias isType                    = dmd.dtemplate.isType;\n    alias isExpression              = dmd.dtemplate.isExpression;\n    alias isTuple                   = dmd.dtemplate.isTuple;\n\n}\n"
  },
  {
    "path": "gcc/d/dmd/attrib.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/attrib.d, _attrib.d)\n * Documentation:  https://dlang.org/phobos/dmd_attrib.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/attrib.d\n */\n\nmodule dmd.attrib;\n\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.cond;\nimport dmd.declaration;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.root.outbuffer;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.visitor;\n\n/***********************************************************\n */\nextern (C++) abstract class AttribDeclaration : Dsymbol\n{\n    Dsymbols* decl;     // array of Dsymbol's\n\n    extern (D) this(Dsymbols* decl)\n    {\n        this.decl = decl;\n    }\n\n    Dsymbols* include(Scope* sc)\n    {\n        if (errors)\n            return null;\n\n        return decl;\n    }\n\n    override final int apply(Dsymbol_apply_ft_t fp, void* param)\n    {\n        Dsymbols* d = include(_scope);\n        if (d)\n        {\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                if (s)\n                {\n                    if (s.apply(fp, param))\n                        return 1;\n                }\n            }\n        }\n        return 0;\n    }\n\n    /****************************************\n     * Create a new scope if one or more given attributes\n     * are different from the sc's.\n     * If the returned scope != sc, the caller should pop\n     * the scope after it used.\n     */\n    extern (D) static Scope* createNewScope(Scope* sc, StorageClass stc, LINK linkage,\n        CPPMANGLE cppmangle, Prot protection, int explicitProtection,\n        AlignDeclaration aligndecl, PINLINE inlining)\n    {\n        Scope* sc2 = sc;\n        if (stc != sc.stc ||\n            linkage != sc.linkage ||\n            cppmangle != sc.cppmangle ||\n            !protection.isSubsetOf(sc.protection) ||\n            explicitProtection != sc.explicitProtection ||\n            aligndecl !is sc.aligndecl ||\n            inlining != sc.inlining)\n        {\n            // create new one for changes\n            sc2 = sc.copy();\n            sc2.stc = stc;\n            sc2.linkage = linkage;\n            sc2.cppmangle = cppmangle;\n            sc2.protection = protection;\n            sc2.explicitProtection = explicitProtection;\n            sc2.aligndecl = aligndecl;\n            sc2.inlining = inlining;\n        }\n        return sc2;\n    }\n\n    /****************************************\n     * A hook point to supply scope for members.\n     * addMember, setScope, importAll, semantic, semantic2 and semantic3 will use this.\n     */\n    Scope* newScope(Scope* sc)\n    {\n        return sc;\n    }\n\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        Dsymbols* d = include(sc);\n        if (d)\n        {\n            Scope* sc2 = newScope(sc);\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                //printf(\"\\taddMember %s to %s\\n\", s.toChars(), sds.toChars());\n                s.addMember(sc2, sds);\n            }\n            if (sc2 != sc)\n                sc2.pop();\n        }\n    }\n\n    override void setScope(Scope* sc)\n    {\n        Dsymbols* d = include(sc);\n        //printf(\"\\tAttribDeclaration::setScope '%s', d = %p\\n\",toChars(), d);\n        if (d)\n        {\n            Scope* sc2 = newScope(sc);\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                s.setScope(sc2);\n            }\n            if (sc2 != sc)\n                sc2.pop();\n        }\n    }\n\n    override void importAll(Scope* sc)\n    {\n        Dsymbols* d = include(sc);\n        //printf(\"\\tAttribDeclaration::importAll '%s', d = %p\\n\", toChars(), d);\n        if (d)\n        {\n            Scope* sc2 = newScope(sc);\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                s.importAll(sc2);\n            }\n            if (sc2 != sc)\n                sc2.pop();\n        }\n    }\n\n    override void addComment(const(char)* comment)\n    {\n        //printf(\"AttribDeclaration::addComment %s\\n\", comment);\n        if (comment)\n        {\n            Dsymbols* d = include(null);\n            if (d)\n            {\n                for (size_t i = 0; i < d.dim; i++)\n                {\n                    Dsymbol s = (*d)[i];\n                    //printf(\"AttribDeclaration::addComment %s\\n\", s.toChars());\n                    s.addComment(comment);\n                }\n            }\n        }\n    }\n\n    override const(char)* kind() const\n    {\n        return \"attribute\";\n    }\n\n    override bool oneMember(Dsymbol* ps, Identifier ident)\n    {\n        Dsymbols* d = include(null);\n        return Dsymbol.oneMembers(d, ps, ident);\n    }\n\n    override void setFieldOffset(AggregateDeclaration ad, uint* poffset, bool isunion)\n    {\n        Dsymbols* d = include(null);\n        if (d)\n        {\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                s.setFieldOffset(ad, poffset, isunion);\n            }\n        }\n    }\n\n    override final bool hasPointers()\n    {\n        Dsymbols* d = include(null);\n        if (d)\n        {\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                if (s.hasPointers())\n                    return true;\n            }\n        }\n        return false;\n    }\n\n    override final bool hasStaticCtorOrDtor()\n    {\n        Dsymbols* d = include(null);\n        if (d)\n        {\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                if (s.hasStaticCtorOrDtor())\n                    return true;\n            }\n        }\n        return false;\n    }\n\n    override final void checkCtorConstInit()\n    {\n        Dsymbols* d = include(null);\n        if (d)\n        {\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                s.checkCtorConstInit();\n            }\n        }\n    }\n\n    /****************************************\n     */\n    override final void addLocalClass(ClassDeclarations* aclasses)\n    {\n        Dsymbols* d = include(null);\n        if (d)\n        {\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                s.addLocalClass(aclasses);\n            }\n        }\n    }\n\n    override final inout(AttribDeclaration) isAttribDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class StorageClassDeclaration : AttribDeclaration\n{\n    StorageClass stc;\n\n    extern (D) this(StorageClass stc, Dsymbols* decl)\n    {\n        super(decl);\n        this.stc = stc;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new StorageClassDeclaration(stc, Dsymbol.arraySyntaxCopy(decl));\n    }\n\n    override Scope* newScope(Scope* sc)\n    {\n        StorageClass scstc = sc.stc;\n        /* These sets of storage classes are mutually exclusive,\n         * so choose the innermost or most recent one.\n         */\n        if (stc & (STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | STC.manifest))\n            scstc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | STC.manifest);\n        if (stc & (STC.auto_ | STC.scope_ | STC.static_ | STC.tls | STC.manifest | STC.gshared))\n            scstc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.tls | STC.manifest | STC.gshared);\n        if (stc & (STC.const_ | STC.immutable_ | STC.manifest))\n            scstc &= ~(STC.const_ | STC.immutable_ | STC.manifest);\n        if (stc & (STC.gshared | STC.shared_ | STC.tls))\n            scstc &= ~(STC.gshared | STC.shared_ | STC.tls);\n        if (stc & (STC.safe | STC.trusted | STC.system))\n            scstc &= ~(STC.safe | STC.trusted | STC.system);\n        scstc |= stc;\n        //printf(\"scstc = x%llx\\n\", scstc);\n        return createNewScope(sc, scstc, sc.linkage, sc.cppmangle,\n            sc.protection, sc.explicitProtection, sc.aligndecl, sc.inlining);\n    }\n\n    override final bool oneMember(Dsymbol* ps, Identifier ident)\n    {\n        bool t = Dsymbol.oneMembers(decl, ps, ident);\n        if (t && *ps)\n        {\n            /* This is to deal with the following case:\n             * struct Tick {\n             *   template to(T) { const T to() { ... } }\n             * }\n             * For eponymous function templates, the 'const' needs to get attached to 'to'\n             * before the semantic analysis of 'to', so that template overloading based on the\n             * 'this' pointer can be successful.\n             */\n            FuncDeclaration fd = (*ps).isFuncDeclaration();\n            if (fd)\n            {\n                /* Use storage_class2 instead of storage_class otherwise when we do .di generation\n                 * we'll wind up with 'const const' rather than 'const'.\n                 */\n                /* Don't think we need to worry about mutually exclusive storage classes here\n                 */\n                fd.storage_class2 |= stc;\n            }\n        }\n        return t;\n    }\n\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        Dsymbols* d = include(sc);\n        if (d)\n        {\n            Scope* sc2 = newScope(sc);\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                //printf(\"\\taddMember %s to %s\\n\", s.toChars(), sds.toChars());\n                // STC.local needs to be attached before the member is added to the scope (because it influences the parent symbol)\n                if (auto decl = s.isDeclaration())\n                {\n                    decl.storage_class |= stc & STC.local;\n                    if (auto sdecl = s.isStorageClassDeclaration()) // TODO: why is this not enough to deal with the nested case?\n                    {\n                        sdecl.stc |= stc & STC.local;\n                    }\n                }\n                s.addMember(sc2, sds);\n            }\n            if (sc2 != sc)\n                sc2.pop();\n        }\n\n    }\n\n    override inout(StorageClassDeclaration) isStorageClassDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DeprecatedDeclaration : StorageClassDeclaration\n{\n    Expression msg;\n    const(char)* msgstr;\n\n    extern (D) this(Expression msg, Dsymbols* decl)\n    {\n        super(STC.deprecated_, decl);\n        this.msg = msg;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new DeprecatedDeclaration(msg.syntaxCopy(), Dsymbol.arraySyntaxCopy(decl));\n    }\n\n    /**\n     * Provides a new scope with `STC.deprecated_` and `Scope.depdecl` set\n     *\n     * Calls `StorageClassDeclaration.newScope` (as it must be called or copied\n     * in any function overriding `newScope`), then set the `Scope`'s depdecl.\n     *\n     * Returns:\n     *   Always a new scope, to use for this `DeprecatedDeclaration`'s members.\n     */\n    override Scope* newScope(Scope* sc)\n    {\n        auto scx = super.newScope(sc);\n        // The enclosing scope is deprecated as well\n        if (scx == sc)\n            scx = sc.push();\n        scx.depdecl = this;\n        return scx;\n    }\n\n    override void setScope(Scope* sc)\n    {\n        //printf(\"DeprecatedDeclaration::setScope() %p\\n\", this);\n        if (decl)\n            Dsymbol.setScope(sc); // for forward reference\n        return AttribDeclaration.setScope(sc);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class LinkDeclaration : AttribDeclaration\n{\n    LINK linkage;\n\n    extern (D) this(LINK p, Dsymbols* decl)\n    {\n        super(decl);\n        //printf(\"LinkDeclaration(linkage = %d, decl = %p)\\n\", p, decl);\n        linkage = (p == LINK.system) ? Target.systemLinkage() : p;\n    }\n\n    static LinkDeclaration create(LINK p, Dsymbols* decl)\n    {\n        return new LinkDeclaration(p, decl);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new LinkDeclaration(linkage, Dsymbol.arraySyntaxCopy(decl));\n    }\n\n    override Scope* newScope(Scope* sc)\n    {\n        return createNewScope(sc, sc.stc, this.linkage, sc.cppmangle, sc.protection, sc.explicitProtection,\n            sc.aligndecl, sc.inlining);\n    }\n\n    override const(char)* toChars() const\n    {\n        return \"extern ()\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class CPPMangleDeclaration : AttribDeclaration\n{\n    CPPMANGLE cppmangle;\n\n    extern (D) this(CPPMANGLE p, Dsymbols* decl)\n    {\n        super(decl);\n        //printf(\"CPPMangleDeclaration(cppmangle = %d, decl = %p)\\n\", p, decl);\n        cppmangle = p;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new CPPMangleDeclaration(cppmangle, Dsymbol.arraySyntaxCopy(decl));\n    }\n\n    override Scope* newScope(Scope* sc)\n    {\n        return createNewScope(sc, sc.stc, LINK.cpp, cppmangle, sc.protection, sc.explicitProtection,\n            sc.aligndecl, sc.inlining);\n    }\n\n    override const(char)* toChars() const\n    {\n        return \"extern ()\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ProtDeclaration : AttribDeclaration\n{\n    Prot protection;\n    Identifiers* pkg_identifiers;\n\n    /**\n     * Params:\n     *  loc = source location of attribute token\n     *  p = protection attribute data\n     *  decl = declarations which are affected by this protection attribute\n     */\n    extern (D) this(const ref Loc loc, Prot p, Dsymbols* decl)\n    {\n        super(decl);\n        this.loc = loc;\n        this.protection = p;\n        //printf(\"decl = %p\\n\", decl);\n    }\n\n    /**\n     * Params:\n     *  loc = source location of attribute token\n     *  pkg_identifiers = list of identifiers for a qualified package name\n     *  decl = declarations which are affected by this protection attribute\n     */\n    extern (D) this(const ref Loc loc, Identifiers* pkg_identifiers, Dsymbols* decl)\n    {\n        super(decl);\n        this.loc = loc;\n        this.protection.kind = Prot.Kind.package_;\n        this.pkg_identifiers = pkg_identifiers;\n        if (pkg_identifiers !is null && pkg_identifiers.dim > 0)\n        {\n            Dsymbol tmp;\n            Package.resolve(pkg_identifiers, &tmp, null);\n            protection.pkg = tmp ? tmp.isPackage() : null;\n        }\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        if (protection.kind == Prot.Kind.package_)\n            return new ProtDeclaration(this.loc, pkg_identifiers, Dsymbol.arraySyntaxCopy(decl));\n        else\n            return new ProtDeclaration(this.loc, protection, Dsymbol.arraySyntaxCopy(decl));\n    }\n\n    override Scope* newScope(Scope* sc)\n    {\n        if (pkg_identifiers)\n            dsymbolSemantic(this, sc);\n        return createNewScope(sc, sc.stc, sc.linkage, sc.cppmangle, this.protection, 1, sc.aligndecl, sc.inlining);\n    }\n\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        if (pkg_identifiers)\n        {\n            Dsymbol tmp;\n            Package.resolve(pkg_identifiers, &tmp, null);\n            protection.pkg = tmp ? tmp.isPackage() : null;\n            pkg_identifiers = null;\n        }\n        if (protection.kind == Prot.Kind.package_ && protection.pkg && sc._module)\n        {\n            Module m = sc._module;\n            Package pkg = m.parent ? m.parent.isPackage() : null;\n            if (!pkg || !protection.pkg.isAncestorPackageOf(pkg))\n                error(\"does not bind to one of ancestor packages of module `%s`\", m.toPrettyChars(true));\n        }\n        return AttribDeclaration.addMember(sc, sds);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"protection attribute\";\n    }\n\n    override const(char)* toPrettyChars(bool)\n    {\n        assert(protection.kind > Prot.Kind.undefined);\n        OutBuffer buf;\n        protectionToBuffer(&buf, protection);\n        return buf.extractString();\n    }\n\n    override inout(ProtDeclaration) isProtDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class AlignDeclaration : AttribDeclaration\n{\n    Expression ealign;\n    enum structalign_t UNKNOWN = 0;\n    static assert(STRUCTALIGN_DEFAULT != UNKNOWN);\n    structalign_t salign = UNKNOWN;\n\n    extern (D) this(const ref Loc loc, Expression ealign, Dsymbols* decl)\n    {\n        super(decl);\n        this.loc = loc;\n        this.ealign = ealign;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new AlignDeclaration(loc,\n            ealign.syntaxCopy(), Dsymbol.arraySyntaxCopy(decl));\n    }\n\n    override Scope* newScope(Scope* sc)\n    {\n        return createNewScope(sc, sc.stc, sc.linkage, sc.cppmangle, sc.protection, sc.explicitProtection, this, sc.inlining);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class AnonDeclaration : AttribDeclaration\n{\n    bool isunion;\n    int sem;                // 1 if successful semantic()\n    uint anonoffset;        // offset of anonymous struct\n    uint anonstructsize;    // size of anonymous struct\n    uint anonalignsize;     // size of anonymous struct for alignment purposes\n\n    extern (D) this(const ref Loc loc, bool isunion, Dsymbols* decl)\n    {\n        super(decl);\n        this.loc = loc;\n        this.isunion = isunion;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new AnonDeclaration(loc, isunion, Dsymbol.arraySyntaxCopy(decl));\n    }\n\n    override void setScope(Scope* sc)\n    {\n        if (decl)\n            Dsymbol.setScope(sc);\n        return AttribDeclaration.setScope(sc);\n    }\n\n    override void setFieldOffset(AggregateDeclaration ad, uint* poffset, bool isunion)\n    {\n        //printf(\"\\tAnonDeclaration::setFieldOffset %s %p\\n\", isunion ? \"union\" : \"struct\", this);\n        if (decl)\n        {\n            /* This works by treating an AnonDeclaration as an aggregate 'member',\n             * so in order to place that member we need to compute the member's\n             * size and alignment.\n             */\n            size_t fieldstart = ad.fields.dim;\n\n            /* Hackishly hijack ad's structsize and alignsize fields\n             * for use in our fake anon aggregate member.\n             */\n            uint savestructsize = ad.structsize;\n            uint savealignsize = ad.alignsize;\n            ad.structsize = 0;\n            ad.alignsize = 0;\n\n            uint offset = 0;\n            for (size_t i = 0; i < decl.dim; i++)\n            {\n                Dsymbol s = (*decl)[i];\n                s.setFieldOffset(ad, &offset, this.isunion);\n                if (this.isunion)\n                    offset = 0;\n            }\n\n            /* https://issues.dlang.org/show_bug.cgi?id=13613\n             * If the fields in this.members had been already\n             * added in ad.fields, just update *poffset for the subsequent\n             * field offset calculation.\n             */\n            if (fieldstart == ad.fields.dim)\n            {\n                ad.structsize = savestructsize;\n                ad.alignsize = savealignsize;\n                *poffset = ad.structsize;\n                return;\n            }\n\n            anonstructsize = ad.structsize;\n            anonalignsize = ad.alignsize;\n            ad.structsize = savestructsize;\n            ad.alignsize = savealignsize;\n\n            // 0 sized structs are set to 1 byte\n            if (anonstructsize == 0)\n            {\n                anonstructsize = 1;\n                anonalignsize = 1;\n            }\n\n            assert(_scope);\n            auto alignment = _scope.alignment();\n\n            /* Given the anon 'member's size and alignment,\n             * go ahead and place it.\n             */\n            anonoffset = AggregateDeclaration.placeField(\n                poffset,\n                anonstructsize, anonalignsize, alignment,\n                &ad.structsize, &ad.alignsize,\n                isunion);\n\n            // Add to the anon fields the base offset of this anonymous aggregate\n            //printf(\"anon fields, anonoffset = %d\\n\", anonoffset);\n            for (size_t i = fieldstart; i < ad.fields.dim; i++)\n            {\n                VarDeclaration v = ad.fields[i];\n                //printf(\"\\t[%d] %s %d\\n\", i, v.toChars(), v.offset);\n                v.offset += anonoffset;\n            }\n        }\n    }\n\n    override const(char)* kind() const\n    {\n        return (isunion ? \"anonymous union\" : \"anonymous struct\");\n    }\n\n    override inout(AnonDeclaration) isAnonDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class PragmaDeclaration : AttribDeclaration\n{\n    Expressions* args;      // array of Expression's\n\n    extern (D) this(const ref Loc loc, Identifier ident, Expressions* args, Dsymbols* decl)\n    {\n        super(decl);\n        this.loc = loc;\n        this.ident = ident;\n        this.args = args;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        //printf(\"PragmaDeclaration::syntaxCopy(%s)\\n\", toChars());\n        assert(!s);\n        return new PragmaDeclaration(loc, ident, Expression.arraySyntaxCopy(args), Dsymbol.arraySyntaxCopy(decl));\n    }\n\n    override Scope* newScope(Scope* sc)\n    {\n        if (ident == Id.Pinline)\n        {\n            PINLINE inlining = PINLINE.default_;\n            if (!args || args.dim == 0)\n                inlining = PINLINE.default_;\n            else if (args.dim != 1)\n            {\n                error(\"one boolean expression expected for `pragma(inline)`, not %d\", args.dim);\n                args.setDim(1);\n                (*args)[0] = new ErrorExp();\n            }\n            else\n            {\n                Expression e = (*args)[0];\n                if (e.op != TOK.int64 || !e.type.equals(Type.tbool))\n                {\n                    if (e.op != TOK.error)\n                    {\n                        error(\"pragma(`inline`, `true` or `false`) expected, not `%s`\", e.toChars());\n                        (*args)[0] = new ErrorExp();\n                    }\n                }\n                else if (e.isBool(true))\n                    inlining = PINLINE.always;\n                else if (e.isBool(false))\n                    inlining = PINLINE.never;\n            }\n            return createNewScope(sc, sc.stc, sc.linkage, sc.cppmangle, sc.protection, sc.explicitProtection, sc.aligndecl, inlining);\n        }\n        return sc;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"pragma\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class ConditionalDeclaration : AttribDeclaration\n{\n    Condition condition;\n    Dsymbols* elsedecl;     // array of Dsymbol's for else block\n\n    extern (D) this(Condition condition, Dsymbols* decl, Dsymbols* elsedecl)\n    {\n        super(decl);\n        //printf(\"ConditionalDeclaration::ConditionalDeclaration()\\n\");\n        this.condition = condition;\n        this.elsedecl = elsedecl;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new ConditionalDeclaration(condition.syntaxCopy(), Dsymbol.arraySyntaxCopy(decl), Dsymbol.arraySyntaxCopy(elsedecl));\n    }\n\n    override final bool oneMember(Dsymbol* ps, Identifier ident)\n    {\n        //printf(\"ConditionalDeclaration::oneMember(), inc = %d\\n\", condition.inc);\n        if (condition.inc)\n        {\n            Dsymbols* d = condition.include(null) ? decl : elsedecl;\n            return Dsymbol.oneMembers(d, ps, ident);\n        }\n        else\n        {\n            bool res = (Dsymbol.oneMembers(decl, ps, ident) && *ps is null && Dsymbol.oneMembers(elsedecl, ps, ident) && *ps is null);\n            *ps = null;\n            return res;\n        }\n    }\n\n    // Decide if 'then' or 'else' code should be included\n    override Dsymbols* include(Scope* sc)\n    {\n        //printf(\"ConditionalDeclaration::include(sc = %p) scope = %p\\n\", sc, scope);\n\n        if (errors)\n            return null;\n\n        assert(condition);\n        return condition.include(_scope ? _scope : sc) ? decl : elsedecl;\n    }\n\n    override final void addComment(const(char)* comment)\n    {\n        /* Because addComment is called by the parser, if we called\n         * include() it would define a version before it was used.\n         * But it's no problem to drill down to both decl and elsedecl,\n         * so that's the workaround.\n         */\n        if (comment)\n        {\n            Dsymbols* d = decl;\n            for (int j = 0; j < 2; j++)\n            {\n                if (d)\n                {\n                    for (size_t i = 0; i < d.dim; i++)\n                    {\n                        Dsymbol s = (*d)[i];\n                        //printf(\"ConditionalDeclaration::addComment %s\\n\", s.toChars());\n                        s.addComment(comment);\n                    }\n                }\n                d = elsedecl;\n            }\n        }\n    }\n\n    override void setScope(Scope* sc)\n    {\n        Dsymbols* d = include(sc);\n        //printf(\"\\tConditionalDeclaration::setScope '%s', d = %p\\n\",toChars(), d);\n        if (d)\n        {\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                s.setScope(sc);\n            }\n        }\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class StaticIfDeclaration : ConditionalDeclaration\n{\n    ScopeDsymbol scopesym;\n    private bool addisdone = false; // true if members have been added to scope\n    private bool onStack = false;   // true if a call to `include` is currently active\n\n    extern (D) this(Condition condition, Dsymbols* decl, Dsymbols* elsedecl)\n    {\n        super(condition, decl, elsedecl);\n        //printf(\"StaticIfDeclaration::StaticIfDeclaration()\\n\");\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new StaticIfDeclaration(condition.syntaxCopy(), Dsymbol.arraySyntaxCopy(decl), Dsymbol.arraySyntaxCopy(elsedecl));\n    }\n\n    /****************************************\n     * Different from other AttribDeclaration subclasses, include() call requires\n     * the completion of addMember and setScope phases.\n     */\n    override Dsymbols* include(Scope* sc)\n    {\n        //printf(\"StaticIfDeclaration::include(sc = %p) scope = %p\\n\", sc, scope);\n\n        if (errors || onStack)\n            return null;\n        onStack = true;\n        scope(exit) onStack = false;\n\n        if (sc && condition.inc == 0)\n        {\n            assert(scopesym); // addMember is already done\n            assert(_scope); // setScope is already done\n            Dsymbols* d = ConditionalDeclaration.include(_scope);\n            if (d && !addisdone)\n            {\n                // Add members lazily.\n                for (size_t i = 0; i < d.dim; i++)\n                {\n                    Dsymbol s = (*d)[i];\n                    s.addMember(_scope, scopesym);\n                }\n                // Set the member scopes lazily.\n                for (size_t i = 0; i < d.dim; i++)\n                {\n                    Dsymbol s = (*d)[i];\n                    s.setScope(_scope);\n                }\n                addisdone = true;\n            }\n            return d;\n        }\n        else\n        {\n            return ConditionalDeclaration.include(sc);\n        }\n    }\n\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        //printf(\"StaticIfDeclaration::addMember() '%s'\\n\", toChars());\n        /* This is deferred until the condition evaluated later (by the include() call),\n         * so that expressions in the condition can refer to declarations\n         * in the same scope, such as:\n         *\n         * template Foo(int i)\n         * {\n         *     const int j = i + 1;\n         *     static if (j == 3)\n         *         const int k;\n         * }\n         */\n        this.scopesym = sds;\n    }\n\n    override void setScope(Scope* sc)\n    {\n        // do not evaluate condition before semantic pass\n        // But do set the scope, in case we need it for forward referencing\n        Dsymbol.setScope(sc);\n    }\n\n    override void importAll(Scope* sc)\n    {\n        // do not evaluate condition before semantic pass\n    }\n\n    override const(char)* kind() const\n    {\n        return \"static if\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Static foreach at declaration scope, like:\n *     static foreach (i; [0, 1, 2]){ }\n */\n\nextern (C++) final class StaticForeachDeclaration : AttribDeclaration\n{\n    StaticForeach sfe; /// contains `static foreach` expansion logic\n\n    ScopeDsymbol scopesym; /// cached enclosing scope (mimics `static if` declaration)\n\n    /++\n     `include` can be called multiple times, but a `static foreach`\n     should be expanded at most once.  Achieved by caching the result\n     of the first call.  We need both `cached` and `cache`, because\n     `null` is a valid value for `cache`.\n     +/\n    bool onStack = false;\n    bool cached = false;\n    Dsymbols* cache = null;\n\n    extern (D) this(StaticForeach sfe, Dsymbols* decl)\n    {\n        super(decl);\n        this.sfe = sfe;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new StaticForeachDeclaration(\n            sfe.syntaxCopy(),\n            Dsymbol.arraySyntaxCopy(decl));\n    }\n\n    override bool oneMember(Dsymbol* ps, Identifier ident)\n    {\n        // Required to support IFTI on a template that contains a\n        // `static foreach` declaration.  `super.oneMember` calls\n        // include with a `null` scope.  As `static foreach` requires\n        // the scope for expansion, `oneMember` can only return a\n        // precise result once `static foreach` has been expanded.\n        if (cached)\n        {\n            return super.oneMember(ps, ident);\n        }\n        *ps = null; // a `static foreach` declaration may in general expand to multiple symbols\n        return false;\n    }\n\n    override Dsymbols* include(Scope* sc)\n    {\n        if (errors || onStack)\n            return null;\n        if (cached)\n        {\n            assert(!onStack);\n            return cache;\n        }\n        onStack = true;\n        scope(exit) onStack = false;\n\n        if (_scope)\n        {\n            sfe.prepare(_scope); // lower static foreach aggregate\n        }\n        if (!sfe.ready())\n        {\n            return null; // TODO: ok?\n        }\n\n        // expand static foreach\n        import dmd.statementsem: makeTupleForeach;\n        Dsymbols* d = makeTupleForeach!(true,true)(_scope, sfe.aggrfe, decl, sfe.needExpansion);\n        if (d) // process generated declarations\n        {\n            // Add members lazily.\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                s.addMember(_scope, scopesym);\n            }\n            // Set the member scopes lazily.\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                s.setScope(_scope);\n            }\n        }\n        cached = true;\n        cache = d;\n        return d;\n    }\n\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        // used only for caching the enclosing symbol\n        this.scopesym = sds;\n    }\n\n    override void addComment(const(char)* comment)\n    {\n        // do nothing\n        // change this to give semantics to documentation comments on static foreach declarations\n    }\n\n    override void setScope(Scope* sc)\n    {\n        // do not evaluate condition before semantic pass\n        // But do set the scope, in case we need it for forward referencing\n        Dsymbol.setScope(sc);\n    }\n\n    override void importAll(Scope* sc)\n    {\n        // do not evaluate aggregate before semantic pass\n    }\n\n    override const(char)* kind() const\n    {\n        return \"static foreach\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Collection of declarations that stores foreach index variables in a\n * local symbol table.  Other symbols declared within are forwarded to\n * another scope, like:\n *\n *      static foreach (i; 0 .. 10) // loop variables for different indices do not conflict.\n *      { // this body is expanded into 10 ForwardingAttribDeclarations, where `i` has storage class STC.local\n *          mixin(\"enum x\" ~ to!string(i) ~ \" = i\"); // ok, can access current loop variable\n *      }\n *\n *      static foreach (i; 0.. 10)\n *      {\n *          pragma(msg, mixin(\"x\" ~ to!string(i))); // ok, all 10 symbols are visible as they were forwarded to the global scope\n *      }\n *\n *      static assert (!is(typeof(i))); // loop index variable is not visible outside of the static foreach loop\n *\n * A StaticForeachDeclaration generates one\n * ForwardingAttribDeclaration for each expansion of its body.  The\n * AST of the ForwardingAttribDeclaration contains both the `static\n * foreach` variables and the respective copy of the `static foreach`\n * body.  The functionality is achieved by using a\n * ForwardingScopeDsymbol as the parent symbol for the generated\n * declarations.\n */\n\nextern(C++) final class ForwardingAttribDeclaration: AttribDeclaration\n{\n    ForwardingScopeDsymbol sym = null;\n\n    this(Dsymbols* decl)\n    {\n        super(decl);\n        sym = new ForwardingScopeDsymbol(null);\n        sym.symtab = new DsymbolTable();\n    }\n\n    /**************************************\n     * Use the ForwardingScopeDsymbol as the parent symbol for members.\n     */\n    override Scope* newScope(Scope* sc)\n    {\n        return sc.push(sym);\n    }\n\n    /***************************************\n     * Lazily initializes the scope to forward to.\n     */\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        parent = sym.parent = sym.forward = sds;\n        return super.addMember(sc, sym);\n    }\n\n    override inout(ForwardingAttribDeclaration) isForwardingAttribDeclaration() inout\n    {\n        return this;\n    }\n}\n\n\n/***********************************************************\n * Mixin declarations, like:\n *      mixin(\"int x\");\n * https://dlang.org/spec/module.html#mixin-declaration\n */\nextern (C++) final class CompileDeclaration : AttribDeclaration\n{\n    Expressions* exps;\n    ScopeDsymbol scopesym;\n    bool compiled;\n\n    extern (D) this(const ref Loc loc, Expressions* exps)\n    {\n        super(null);\n        //printf(\"CompileDeclaration(loc = %d)\\n\", loc.linnum);\n        this.loc = loc;\n        this.exps = exps;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        //printf(\"CompileDeclaration::syntaxCopy('%s')\\n\", toChars());\n        return new CompileDeclaration(loc, Expression.arraySyntaxCopy(exps));\n    }\n\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        //printf(\"CompileDeclaration::addMember(sc = %p, sds = %p, memnum = %d)\\n\", sc, sds, memnum);\n        this.scopesym = sds;\n    }\n\n    override void setScope(Scope* sc)\n    {\n        Dsymbol.setScope(sc);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"mixin\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * User defined attributes look like:\n *      @foo(args, ...)\n *      @(args, ...)\n */\nextern (C++) final class UserAttributeDeclaration : AttribDeclaration\n{\n    Expressions* atts;\n\n    extern (D) this(Expressions* atts, Dsymbols* decl)\n    {\n        super(decl);\n        //printf(\"UserAttributeDeclaration()\\n\");\n        this.atts = atts;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        //printf(\"UserAttributeDeclaration::syntaxCopy('%s')\\n\", toChars());\n        assert(!s);\n        return new UserAttributeDeclaration(Expression.arraySyntaxCopy(this.atts), Dsymbol.arraySyntaxCopy(decl));\n    }\n\n    override Scope* newScope(Scope* sc)\n    {\n        Scope* sc2 = sc;\n        if (atts && atts.dim)\n        {\n            // create new one for changes\n            sc2 = sc.copy();\n            sc2.userAttribDecl = this;\n        }\n        return sc2;\n    }\n\n    override void setScope(Scope* sc)\n    {\n        //printf(\"UserAttributeDeclaration::setScope() %p\\n\", this);\n        if (decl)\n            Dsymbol.setScope(sc); // for forward reference of UDAs\n        return AttribDeclaration.setScope(sc);\n    }\n\n    extern (D) static Expressions* concat(Expressions* udas1, Expressions* udas2)\n    {\n        Expressions* udas;\n        if (!udas1 || udas1.dim == 0)\n            udas = udas2;\n        else if (!udas2 || udas2.dim == 0)\n            udas = udas1;\n        else\n        {\n            /* Create a new tuple that combines them\n             * (do not append to left operand, as this is a copy-on-write operation)\n             */\n            udas = new Expressions();\n            udas.push(new TupleExp(Loc.initial, udas1));\n            udas.push(new TupleExp(Loc.initial, udas2));\n        }\n        return udas;\n    }\n\n    Expressions* getAttributes()\n    {\n        if (auto sc = _scope)\n        {\n            _scope = null;\n            arrayExpressionSemantic(atts, sc);\n        }\n        auto exps = new Expressions();\n        if (userAttribDecl)\n            exps.push(new TupleExp(Loc.initial, userAttribDecl.getAttributes()));\n        if (atts && atts.dim)\n            exps.push(new TupleExp(Loc.initial, atts));\n        return exps;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"UserAttribute\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/attrib.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/attrib.h\n */\n\n#pragma once\n\n#include \"root/port.h\"\n#include \"dsymbol.h\"\n\nclass Expression;\nclass Condition;\nclass StaticForeach;\n\n/**************************************************************/\n\nclass AttribDeclaration : public Dsymbol\n{\npublic:\n    Dsymbols *decl;     // array of Dsymbol's\n\n    virtual Dsymbols *include(Scope *sc);\n    int apply(Dsymbol_apply_ft_t fp, void *param);\n    virtual Scope *newScope(Scope *sc);\n    void addMember(Scope *sc, ScopeDsymbol *sds);\n    void setScope(Scope *sc);\n    void importAll(Scope *sc);\n    void addComment(const utf8_t *comment);\n    const char *kind() const;\n    bool oneMember(Dsymbol **ps, Identifier *ident);\n    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);\n    bool hasPointers();\n    bool hasStaticCtorOrDtor();\n    void checkCtorConstInit();\n    void addLocalClass(ClassDeclarations *);\n    AttribDeclaration *isAttribDeclaration() { return this; }\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StorageClassDeclaration : public AttribDeclaration\n{\npublic:\n    StorageClass stc;\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Scope *newScope(Scope *sc);\n    bool oneMember(Dsymbol **ps, Identifier *ident);\n    void addMember(Scope *sc, ScopeDsymbol *sds);\n    StorageClassDeclaration *isStorageClassDeclaration() { return this; }\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DeprecatedDeclaration : public StorageClassDeclaration\n{\npublic:\n    Expression *msg;\n    const char *msgstr;\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Scope *newScope(Scope *sc);\n    void setScope(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass LinkDeclaration : public AttribDeclaration\n{\npublic:\n    LINK linkage;\n\n    static LinkDeclaration *create(LINK p, Dsymbols *decl);\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Scope *newScope(Scope *sc);\n    const char *toChars();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass CPPMangleDeclaration : public AttribDeclaration\n{\npublic:\n    CPPMANGLE cppmangle;\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Scope *newScope(Scope *sc);\n    const char *toChars();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ProtDeclaration : public AttribDeclaration\n{\npublic:\n    Prot protection;\n    Identifiers* pkg_identifiers;\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Scope *newScope(Scope *sc);\n    void addMember(Scope *sc, ScopeDsymbol *sds);\n    const char *kind() const;\n    const char *toPrettyChars(bool unused);\n    ProtDeclaration *isProtDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass AlignDeclaration : public AttribDeclaration\n{\npublic:\n    Expression *ealign;\n    structalign_t salign;\n\n    AlignDeclaration(const Loc &loc, Expression *ealign, Dsymbols *decl);\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Scope *newScope(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass AnonDeclaration : public AttribDeclaration\n{\npublic:\n    bool isunion;\n    int sem;                    // 1 if successful semantic()\n    unsigned anonoffset;        // offset of anonymous struct\n    unsigned anonstructsize;    // size of anonymous struct\n    unsigned anonalignsize;     // size of anonymous struct for alignment purposes\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    void setScope(Scope *sc);\n    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);\n    const char *kind() const;\n    AnonDeclaration *isAnonDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass PragmaDeclaration : public AttribDeclaration\n{\npublic:\n    Expressions *args;          // array of Expression's\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Scope *newScope(Scope *sc);\n    const char *kind() const;\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ConditionalDeclaration : public AttribDeclaration\n{\npublic:\n    Condition *condition;\n    Dsymbols *elsedecl; // array of Dsymbol's for else block\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    bool oneMember(Dsymbol **ps, Identifier *ident);\n    Dsymbols *include(Scope *sc);\n    void addComment(const utf8_t *comment);\n    void setScope(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StaticIfDeclaration : public ConditionalDeclaration\n{\npublic:\n    ScopeDsymbol *scopesym;\n    bool addisdone;\n    bool onStack;\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Dsymbols *include(Scope *sc);\n    void addMember(Scope *sc, ScopeDsymbol *sds);\n    void setScope(Scope *sc);\n    void importAll(Scope *sc);\n    const char *kind() const;\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StaticForeachDeclaration : public ConditionalDeclaration\n{\npublic:\n    StaticForeach *sfe;\n    ScopeDsymbol *scopesym;\n    bool cached;\n    Dsymbols *cache;\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    bool oneMember(Dsymbol **ps, Identifier *ident);\n    Dsymbols *include(Scope *sc);\n    void addMember(Scope *sc, ScopeDsymbol *sds);\n    void addComment(const utf8_t *comment);\n    void setScope(Scope *sc);\n    void importAll(Scope *sc);\n    const char *kind() const;\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ForwardingAttribDeclaration : AttribDeclaration\n{\npublic:\n    ForwardingScopeDsymbol *sym;\n\n    Scope *newScope(Scope *sc);\n    void addMember(Scope *sc, ScopeDsymbol *sds);\n    ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return this; }\n};\n\n// Mixin declarations\n\nclass CompileDeclaration : public AttribDeclaration\n{\npublic:\n    Expressions *exps;\n\n    ScopeDsymbol *scopesym;\n    bool compiled;\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    void addMember(Scope *sc, ScopeDsymbol *sds);\n    void setScope(Scope *sc);\n    const char *kind() const;\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/**\n * User defined attributes look like:\n *      @(args, ...)\n */\nclass UserAttributeDeclaration : public AttribDeclaration\n{\npublic:\n    Expressions *atts;\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Scope *newScope(Scope *sc);\n    void setScope(Scope *sc);\n    Expressions *getAttributes();\n    const char *kind() const;\n    void accept(Visitor *v) { v->visit(this); }\n};\n"
  },
  {
    "path": "gcc/d/dmd/blockexit.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/blockexit.d, _blockexit.d)\n * Documentation:  https://dlang.org/phobos/dmd_blockexit.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/blockexit.d\n */\n\nmodule dmd.blockexit;\n\nimport core.stdc.stdio;\n\nimport dmd.arraytypes;\nimport dmd.canthrow;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.statement;\nimport dmd.tokens;\nimport dmd.visitor;\n\n/**\n * BE stands for BlockExit.\n *\n * It indicates if a statement does transfer control to another block.\n * A block is a sequence of statements enclosed in { }\n */\nenum BE : int\n{\n    none      = 0,\n    fallthru  = 1,\n    throw_    = 2,\n    return_   = 4,\n    goto_     = 8,\n    halt      = 0x10,\n    break_    = 0x20,\n    continue_ = 0x40,\n    errthrow  = 0x80,\n    any       = (fallthru | throw_ | return_ | goto_ | halt),\n}\n\n\n/*********************************************\n * Determine mask of ways that a statement can exit.\n *\n * Only valid after semantic analysis.\n * Params:\n *   s = statement to check for block exit status\n *   func = function that statement s is in\n *   mustNotThrow = generate an error if it throws\n * Returns:\n *   BE.xxxx\n */\nint blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)\n{\n    extern (C++) final class BlockExit : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        FuncDeclaration func;\n        bool mustNotThrow;\n        int result;\n\n        extern (D) this(FuncDeclaration func, bool mustNotThrow)\n        {\n            this.func = func;\n            this.mustNotThrow = mustNotThrow;\n            result = BE.none;\n        }\n\n        override void visit(Statement s)\n        {\n            printf(\"Statement::blockExit(%p)\\n\", s);\n            printf(\"%s\\n\", s.toChars());\n            assert(0);\n        }\n\n        override void visit(ErrorStatement s)\n        {\n            result = BE.none;\n        }\n\n        override void visit(ExpStatement s)\n        {\n            result = BE.fallthru;\n            if (s.exp)\n            {\n                if (s.exp.op == TOK.halt)\n                {\n                    result = BE.halt;\n                    return;\n                }\n                if (s.exp.op == TOK.assert_)\n                {\n                    AssertExp a = cast(AssertExp)s.exp;\n                    if (a.e1.isBool(false)) // if it's an assert(0)\n                    {\n                        result = BE.halt;\n                        return;\n                    }\n                }\n                if (canThrow(s.exp, func, mustNotThrow))\n                    result |= BE.throw_;\n            }\n        }\n\n        override void visit(CompileStatement s)\n        {\n            assert(global.errors);\n            result = BE.fallthru;\n        }\n\n        override void visit(CompoundStatement cs)\n        {\n            //printf(\"CompoundStatement.blockExit(%p) %d result = x%X\\n\", cs, cs.statements.dim, result);\n            result = BE.fallthru;\n            Statement slast = null;\n            foreach (s; *cs.statements)\n            {\n                if (s)\n                {\n                    //printf(\"result = x%x\\n\", result);\n                    //printf(\"s: %s\\n\", s.toChars());\n                    if (result & BE.fallthru && slast)\n                    {\n                        slast = slast.last();\n                        if (slast && (slast.isCaseStatement() || slast.isDefaultStatement()) && (s.isCaseStatement() || s.isDefaultStatement()))\n                        {\n                            // Allow if last case/default was empty\n                            CaseStatement sc = slast.isCaseStatement();\n                            DefaultStatement sd = slast.isDefaultStatement();\n                            if (sc && (!sc.statement.hasCode() || sc.statement.isCaseStatement() || sc.statement.isErrorStatement()))\n                            {\n                            }\n                            else if (sd && (!sd.statement.hasCode() || sd.statement.isCaseStatement() || sd.statement.isErrorStatement()))\n                            {\n                            }\n                            else\n                            {\n                                const(char)* gototype = s.isCaseStatement() ? \"case\" : \"default\";\n                                s.deprecation(\"switch case fallthrough - use 'goto %s;' if intended\", gototype);\n                            }\n                        }\n                    }\n\n                    if (!(result & BE.fallthru) && !s.comeFrom())\n                    {\n                        if (blockExit(s, func, mustNotThrow) != BE.halt && s.hasCode())\n                            s.warning(\"statement is not reachable\");\n                    }\n                    else\n                    {\n                        result &= ~BE.fallthru;\n                        result |= blockExit(s, func, mustNotThrow);\n                    }\n                    slast = s;\n                }\n            }\n        }\n\n        override void visit(UnrolledLoopStatement uls)\n        {\n            result = BE.fallthru;\n            foreach (s; *uls.statements)\n            {\n                if (s)\n                {\n                    int r = blockExit(s, func, mustNotThrow);\n                    result |= r & ~(BE.break_ | BE.continue_ | BE.fallthru);\n                    if ((r & (BE.fallthru | BE.continue_ | BE.break_)) == 0)\n                        result &= ~BE.fallthru;\n                }\n            }\n        }\n\n        override void visit(ScopeStatement s)\n        {\n            //printf(\"ScopeStatement::blockExit(%p)\\n\", s.statement);\n            result = blockExit(s.statement, func, mustNotThrow);\n        }\n\n        override void visit(WhileStatement s)\n        {\n            assert(global.errors);\n            result = BE.fallthru;\n        }\n\n        override void visit(DoStatement s)\n        {\n            if (s._body)\n            {\n                result = blockExit(s._body, func, mustNotThrow);\n                if (result == BE.break_)\n                {\n                    result = BE.fallthru;\n                    return;\n                }\n                if (result & BE.continue_)\n                    result |= BE.fallthru;\n            }\n            else\n                result = BE.fallthru;\n            if (result & BE.fallthru)\n            {\n                if (canThrow(s.condition, func, mustNotThrow))\n                    result |= BE.throw_;\n                if (!(result & BE.break_) && s.condition.isBool(true))\n                    result &= ~BE.fallthru;\n            }\n            result &= ~(BE.break_ | BE.continue_);\n        }\n\n        override void visit(ForStatement s)\n        {\n            result = BE.fallthru;\n            if (s._init)\n            {\n                result = blockExit(s._init, func, mustNotThrow);\n                if (!(result & BE.fallthru))\n                    return;\n            }\n            if (s.condition)\n            {\n                if (canThrow(s.condition, func, mustNotThrow))\n                    result |= BE.throw_;\n                if (s.condition.isBool(true))\n                    result &= ~BE.fallthru;\n                else if (s.condition.isBool(false))\n                    return;\n            }\n            else\n                result &= ~BE.fallthru; // the body must do the exiting\n            if (s._body)\n            {\n                int r = blockExit(s._body, func, mustNotThrow);\n                if (r & (BE.break_ | BE.goto_))\n                    result |= BE.fallthru;\n                result |= r & ~(BE.fallthru | BE.break_ | BE.continue_);\n            }\n            if (s.increment && canThrow(s.increment, func, mustNotThrow))\n                result |= BE.throw_;\n        }\n\n        override void visit(ForeachStatement s)\n        {\n            result = BE.fallthru;\n            if (canThrow(s.aggr, func, mustNotThrow))\n                result |= BE.throw_;\n            if (s._body)\n                result |= blockExit(s._body, func, mustNotThrow) & ~(BE.break_ | BE.continue_);\n        }\n\n        override void visit(ForeachRangeStatement s)\n        {\n            assert(global.errors);\n            result = BE.fallthru;\n        }\n\n        override void visit(IfStatement s)\n        {\n            //printf(\"IfStatement::blockExit(%p)\\n\", s);\n            result = BE.none;\n            if (canThrow(s.condition, func, mustNotThrow))\n                result |= BE.throw_;\n            if (s.condition.isBool(true))\n            {\n                result |= blockExit(s.ifbody, func, mustNotThrow);\n            }\n            else if (s.condition.isBool(false))\n            {\n                result |= blockExit(s.elsebody, func, mustNotThrow);\n            }\n            else\n            {\n                result |= blockExit(s.ifbody, func, mustNotThrow);\n                result |= blockExit(s.elsebody, func, mustNotThrow);\n            }\n            //printf(\"IfStatement::blockExit(%p) = x%x\\n\", s, result);\n        }\n\n        override void visit(ConditionalStatement s)\n        {\n            result = blockExit(s.ifbody, func, mustNotThrow);\n            if (s.elsebody)\n                result |= blockExit(s.elsebody, func, mustNotThrow);\n        }\n\n        override void visit(PragmaStatement s)\n        {\n            result = BE.fallthru;\n        }\n\n        override void visit(StaticAssertStatement s)\n        {\n            result = BE.fallthru;\n        }\n\n        override void visit(SwitchStatement s)\n        {\n            result = BE.none;\n            if (canThrow(s.condition, func, mustNotThrow))\n                result |= BE.throw_;\n            if (s._body)\n            {\n                result |= blockExit(s._body, func, mustNotThrow);\n                if (result & BE.break_)\n                {\n                    result |= BE.fallthru;\n                    result &= ~BE.break_;\n                }\n            }\n            else\n                result |= BE.fallthru;\n        }\n\n        override void visit(CaseStatement s)\n        {\n            result = blockExit(s.statement, func, mustNotThrow);\n        }\n\n        override void visit(DefaultStatement s)\n        {\n            result = blockExit(s.statement, func, mustNotThrow);\n        }\n\n        override void visit(GotoDefaultStatement s)\n        {\n            result = BE.goto_;\n        }\n\n        override void visit(GotoCaseStatement s)\n        {\n            result = BE.goto_;\n        }\n\n        override void visit(SwitchErrorStatement s)\n        {\n            // Switch errors are non-recoverable\n            result = BE.halt;\n        }\n\n        override void visit(ReturnStatement s)\n        {\n            result = BE.return_;\n            if (s.exp && canThrow(s.exp, func, mustNotThrow))\n                result |= BE.throw_;\n        }\n\n        override void visit(BreakStatement s)\n        {\n            //printf(\"BreakStatement::blockExit(%p) = x%x\\n\", s, s.ident ? BE.goto_ : BE.break_);\n            result = s.ident ? BE.goto_ : BE.break_;\n        }\n\n        override void visit(ContinueStatement s)\n        {\n            result = s.ident ? BE.continue_ | BE.goto_ : BE.continue_;\n        }\n\n        override void visit(SynchronizedStatement s)\n        {\n            result = blockExit(s._body, func, mustNotThrow);\n        }\n\n        override void visit(WithStatement s)\n        {\n            result = BE.none;\n            if (canThrow(s.exp, func, mustNotThrow))\n                result = BE.throw_;\n            result |= blockExit(s._body, func, mustNotThrow);\n        }\n\n        override void visit(TryCatchStatement s)\n        {\n            assert(s._body);\n            result = blockExit(s._body, func, false);\n\n            int catchresult = 0;\n            foreach (c; *s.catches)\n            {\n                if (c.type == Type.terror)\n                    continue;\n\n                int cresult = blockExit(c.handler, func, mustNotThrow);\n\n                /* If we're catching Object, then there is no throwing\n                 */\n                Identifier id = c.type.toBasetype().isClassHandle().ident;\n                if (c.internalCatch && (cresult & BE.fallthru))\n                {\n                    // https://issues.dlang.org/show_bug.cgi?id=11542\n                    // leave blockExit flags of the body\n                    cresult &= ~BE.fallthru;\n                }\n                else if (id == Id.Object || id == Id.Throwable)\n                {\n                    result &= ~(BE.throw_ | BE.errthrow);\n                }\n                else if (id == Id.Exception)\n                {\n                    result &= ~BE.throw_;\n                }\n                catchresult |= cresult;\n            }\n            if (mustNotThrow && (result & BE.throw_))\n            {\n                // now explain why this is nothrow\n                blockExit(s._body, func, mustNotThrow);\n            }\n            result |= catchresult;\n        }\n\n        override void visit(TryFinallyStatement s)\n        {\n            result = BE.fallthru;\n            if (s._body)\n                result = blockExit(s._body, func, false);\n\n            // check finally body as well, it may throw (bug #4082)\n            int finalresult = BE.fallthru;\n            if (s.finalbody)\n                finalresult = blockExit(s.finalbody, func, false);\n\n            // If either body or finalbody halts\n            if (result == BE.halt)\n                finalresult = BE.none;\n            if (finalresult == BE.halt)\n                result = BE.none;\n\n            if (mustNotThrow)\n            {\n                // now explain why this is nothrow\n                if (s._body && (result & BE.throw_))\n                    blockExit(s._body, func, mustNotThrow);\n                if (s.finalbody && (finalresult & BE.throw_))\n                    blockExit(s.finalbody, func, mustNotThrow);\n            }\n\n            version (none)\n            {\n                // https://issues.dlang.org/show_bug.cgi?id=13201\n                // Mask to prevent spurious warnings for\n                // destructor call, exit of synchronized statement, etc.\n                if (result == BE.halt && finalresult != BE.halt && s.finalbody && s.finalbody.hasCode())\n                {\n                    s.finalbody.warning(\"statement is not reachable\");\n                }\n            }\n\n            if (!(finalresult & BE.fallthru))\n                result &= ~BE.fallthru;\n            result |= finalresult & ~BE.fallthru;\n        }\n\n        override void visit(OnScopeStatement s)\n        {\n            // At this point, this statement is just an empty placeholder\n            result = BE.fallthru;\n        }\n\n        override void visit(ThrowStatement s)\n        {\n            if (s.internalThrow)\n            {\n                // https://issues.dlang.org/show_bug.cgi?id=8675\n                // Allow throwing 'Throwable' object even if mustNotThrow.\n                result = BE.fallthru;\n                return;\n            }\n\n            Type t = s.exp.type.toBasetype();\n            ClassDeclaration cd = t.isClassHandle();\n            assert(cd);\n\n            if (cd == ClassDeclaration.errorException || ClassDeclaration.errorException.isBaseOf(cd, null))\n            {\n                result = BE.errthrow;\n                return;\n            }\n            if (mustNotThrow)\n                s.error(\"`%s` is thrown but not caught\", s.exp.type.toChars());\n\n            result = BE.throw_;\n        }\n\n        override void visit(GotoStatement s)\n        {\n            //printf(\"GotoStatement::blockExit(%p)\\n\", s);\n            result = BE.goto_;\n        }\n\n        override void visit(LabelStatement s)\n        {\n            //printf(\"LabelStatement::blockExit(%p)\\n\", s);\n            result = blockExit(s.statement, func, mustNotThrow);\n            if (s.breaks)\n                result |= BE.fallthru;\n        }\n\n        override void visit(CompoundAsmStatement s)\n        {\n            // Assume the worst\n            result = BE.fallthru | BE.return_ | BE.goto_ | BE.halt;\n            if (!(s.stc & STC.nothrow_))\n            {\n                if (mustNotThrow && !(s.stc & STC.nothrow_))\n                    s.deprecation(\"`asm` statement is assumed to throw - mark it with `nothrow` if it does not\");\n                else\n                    result |= BE.throw_;\n            }\n        }\n\n        override void visit(ImportStatement s)\n        {\n            result = BE.fallthru;\n        }\n    }\n\n    if (!s)\n        return BE.fallthru;\n    scope BlockExit be = new BlockExit(func, mustNotThrow);\n    s.accept(be);\n    return be.result;\n}\n\n"
  },
  {
    "path": "gcc/d/dmd/boostlicense.txt",
    "content": "Boost Software License - Version 1.0 - August 17th, 2003\n\nPermission is hereby granted, free of charge, to any person or organization\nobtaining a copy of the software and accompanying documentation covered by\nthis license (the \"Software\") to use, reproduce, display, distribute,\nexecute, and transmit the Software, and to prepare derivative works of the\nSoftware, and to permit third-parties to whom the Software is furnished to\ndo so, all subject to the following:\n\nThe copyright notices in the Software and this entire statement, including\nthe above license grant, this restriction and the following disclaimer,\nmust be included in all copies of the Software, in whole or in part, and\nall derivative works of the Software, unless such copies or derivative\nworks are solely in the form of machine-executable object code generated by\na source language processor.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "gcc/d/dmd/builtin.d",
    "content": "/* builtin.d -- Handlers for evaluating builtins during CTFE.\n * Copyright (C) 2018 Free Software Foundation, Inc.\n *\n * GCC is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3, or (at your option)\n * any later version.\n *\n * GCC is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with GCC; see the file COPYING3.  If not see\n * <http://www.gnu.org/licenses/>.\n */\n\nmodule dmd.builtin;\n\nimport core.stdc.math;\nimport core.stdc.string;\nimport dmd.arraytypes;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\n\n/**********************************\n * Determine if function is a builtin one that we can\n * evaluate at compile time.\n */\npublic extern (C++) BUILTIN isBuiltin(FuncDeclaration fd);\n\n/**************************************\n * Evaluate builtin function.\n * Return result; NULL if cannot evaluate it.\n */\npublic extern (C++) Expression eval_builtin(Loc loc, FuncDeclaration fd, Expressions* arguments);\n"
  },
  {
    "path": "gcc/d/dmd/canthrow.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/canthrow.d, _canthrow.d)\n * Documentation:  https://dlang.org/phobos/dmd_canthrow.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/canthrow.d\n */\n\nmodule dmd.canthrow;\n\nimport dmd.aggregate;\nimport dmd.apply;\nimport dmd.arraytypes;\nimport dmd.attrib;\nimport dmd.declaration;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dtemplate;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.init;\nimport dmd.mtype;\nimport dmd.root.rootobject;\nimport dmd.tokens;\nimport dmd.visitor;\n\n/********************************************\n * Returns true if the expression may throw exceptions.\n * If 'mustNotThrow' is true, generate an error if it throws\n */\nextern (C++) bool canThrow(Expression e, FuncDeclaration func, bool mustNotThrow)\n{\n    //printf(\"Expression::canThrow(%d) %s\\n\", mustNotThrow, toChars());\n    // stop walking if we determine this expression can throw\n    extern (C++) final class CanThrow : StoppableVisitor\n    {\n        alias visit = typeof(super).visit;\n        FuncDeclaration func;\n        bool mustNotThrow;\n\n    public:\n        extern (D) this(FuncDeclaration func, bool mustNotThrow)\n        {\n            this.func = func;\n            this.mustNotThrow = mustNotThrow;\n        }\n\n        override void visit(Expression)\n        {\n        }\n\n        override void visit(DeclarationExp de)\n        {\n            stop = Dsymbol_canThrow(de.declaration, func, mustNotThrow);\n        }\n\n        override void visit(CallExp ce)\n        {\n            if (global.errors && !ce.e1.type)\n                return; // error recovery\n            /* If calling a function or delegate that is typed as nothrow,\n             * then this expression cannot throw.\n             * Note that pure functions can throw.\n             */\n            Type t = ce.e1.type.toBasetype();\n            if (ce.f && ce.f == func)\n                return;\n            if (t.ty == Tfunction && (cast(TypeFunction)t).isnothrow)\n                return;\n            if (t.ty == Tdelegate && (cast(TypeFunction)(cast(TypeDelegate)t).next).isnothrow)\n                return;\n\n            if (mustNotThrow)\n            {\n                if (ce.f)\n                {\n                    ce.error(\"%s `%s` is not `nothrow`\",\n                        ce.f.kind(), ce.f.toPrettyChars());\n                }\n                else\n                {\n                    auto e1 = ce.e1;\n                    if (e1.op == TOK.star)   // print 'fp' if e1 is (*fp)\n                        e1 = (cast(PtrExp)e1).e1;\n                    ce.error(\"`%s` is not `nothrow`\", e1.toChars());\n                }\n            }\n            stop = true;\n        }\n\n        override void visit(NewExp ne)\n        {\n            if (ne.member)\n            {\n                if (ne.allocator)\n                {\n                    // https://issues.dlang.org/show_bug.cgi?id=14407\n                    Type t = ne.allocator.type.toBasetype();\n                    if (t.ty == Tfunction && !(cast(TypeFunction)t).isnothrow)\n                    {\n                        if (mustNotThrow)\n                        {\n                            ne.error(\"%s `%s` is not `nothrow`\",\n                                ne.allocator.kind(), ne.allocator.toPrettyChars());\n                        }\n                        stop = true;\n                    }\n                }\n                // See if constructor call can throw\n                Type t = ne.member.type.toBasetype();\n                if (t.ty == Tfunction && !(cast(TypeFunction)t).isnothrow)\n                {\n                    if (mustNotThrow)\n                    {\n                        ne.error(\"%s `%s` is not `nothrow`\",\n                            ne.member.kind(), ne.member.toPrettyChars());\n                    }\n                    stop = true;\n                }\n            }\n            // regard storage allocation failures as not recoverable\n        }\n\n        override void visit(DeleteExp de)\n        {\n            Type tb = de.e1.type.toBasetype();\n            AggregateDeclaration ad = null;\n            switch (tb.ty)\n            {\n            case Tclass:\n                ad = (cast(TypeClass)tb).sym;\n                break;\n\n            case Tpointer:\n                tb = (cast(TypePointer)tb).next.toBasetype();\n                if (tb.ty == Tstruct)\n                    ad = (cast(TypeStruct)tb).sym;\n                break;\n\n            case Tarray:\n                Type tv = tb.nextOf().baseElemOf();\n                if (tv.ty == Tstruct)\n                    ad = (cast(TypeStruct)tv).sym;\n                break;\n\n            default:\n                break;\n            }\n            if (!ad)\n                return;\n\n            if (ad.dtor)\n            {\n                Type t = ad.dtor.type.toBasetype();\n                if (t.ty == Tfunction && !(cast(TypeFunction)t).isnothrow)\n                {\n                    if (mustNotThrow)\n                    {\n                        de.error(\"%s `%s` is not `nothrow`\",\n                            ad.dtor.kind(), ad.dtor.toPrettyChars());\n                    }\n                    stop = true;\n                }\n            }\n            if (ad.aggDelete && tb.ty != Tarray)\n            {\n                Type t = ad.aggDelete.type;\n                if (t.ty == Tfunction && !(cast(TypeFunction)t).isnothrow)\n                {\n                    if (mustNotThrow)\n                    {\n                        de.error(\"%s `%s` is not `nothrow`\",\n                            ad.aggDelete.kind(), ad.aggDelete.toPrettyChars());\n                    }\n                    stop = true;\n                }\n            }\n        }\n\n        override void visit(AssignExp ae)\n        {\n            // blit-init cannot throw\n            if (ae.op == TOK.blit)\n                return;\n            /* Element-wise assignment could invoke postblits.\n             */\n            Type t;\n            if (ae.type.toBasetype().ty == Tsarray)\n            {\n                if (!ae.e2.isLvalue())\n                    return;\n                t = ae.type;\n            }\n            else if (ae.e1.op == TOK.slice)\n                t = (cast(SliceExp)ae.e1).e1.type;\n            else\n                return;\n            Type tv = t.baseElemOf();\n            if (tv.ty != Tstruct)\n                return;\n            StructDeclaration sd = (cast(TypeStruct)tv).sym;\n            if (!sd.postblit || sd.postblit.type.ty != Tfunction)\n                return;\n            if ((cast(TypeFunction)sd.postblit.type).isnothrow)\n            {\n            }\n            else\n            {\n                if (mustNotThrow)\n                {\n                    ae.error(\"%s `%s` is not `nothrow`\",\n                        sd.postblit.kind(), sd.postblit.toPrettyChars());\n                }\n                stop = true;\n            }\n        }\n\n        override void visit(NewAnonClassExp)\n        {\n            assert(0); // should have been lowered by semantic()\n        }\n    }\n\n    scope CanThrow ct = new CanThrow(func, mustNotThrow);\n    return walkPostorder(e, ct);\n}\n\n/**************************************\n * Does symbol, when initialized, throw?\n * Mirrors logic in Dsymbol_toElem().\n */\nprivate bool Dsymbol_canThrow(Dsymbol s, FuncDeclaration func, bool mustNotThrow)\n{\n    AttribDeclaration ad;\n    VarDeclaration vd;\n    TemplateMixin tm;\n    TupleDeclaration td;\n    //printf(\"Dsymbol_toElem() %s\\n\", s.toChars());\n    ad = s.isAttribDeclaration();\n    if (ad)\n    {\n        Dsymbols* decl = ad.include(null);\n        if (decl && decl.dim)\n        {\n            for (size_t i = 0; i < decl.dim; i++)\n            {\n                s = (*decl)[i];\n                if (Dsymbol_canThrow(s, func, mustNotThrow))\n                    return true;\n            }\n        }\n    }\n    else if ((vd = s.isVarDeclaration()) !is null)\n    {\n        s = s.toAlias();\n        if (s != vd)\n            return Dsymbol_canThrow(s, func, mustNotThrow);\n        if (vd.storage_class & STC.manifest)\n        {\n        }\n        else if (vd.isStatic() || vd.storage_class & (STC.extern_ | STC.tls | STC.gshared))\n        {\n        }\n        else\n        {\n            if (vd._init)\n            {\n                ExpInitializer ie = vd._init.isExpInitializer();\n                if (ie && canThrow(ie.exp, func, mustNotThrow))\n                    return true;\n            }\n            if (vd.needsScopeDtor())\n                return canThrow(vd.edtor, func, mustNotThrow);\n        }\n    }\n    else if ((tm = s.isTemplateMixin()) !is null)\n    {\n        //printf(\"%s\\n\", tm.toChars());\n        if (tm.members)\n        {\n            for (size_t i = 0; i < tm.members.dim; i++)\n            {\n                Dsymbol sm = (*tm.members)[i];\n                if (Dsymbol_canThrow(sm, func, mustNotThrow))\n                    return true;\n            }\n        }\n    }\n    else if ((td = s.isTupleDeclaration()) !is null)\n    {\n        for (size_t i = 0; i < td.objects.dim; i++)\n        {\n            RootObject o = (*td.objects)[i];\n            if (o.dyncast() == DYNCAST.expression)\n            {\n                Expression eo = cast(Expression)o;\n                if (eo.op == TOK.dSymbol)\n                {\n                    DsymbolExp se = cast(DsymbolExp)eo;\n                    if (Dsymbol_canThrow(se.s, func, mustNotThrow))\n                        return true;\n                }\n            }\n        }\n    }\n    return false;\n}\n"
  },
  {
    "path": "gcc/d/dmd/clone.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/clone.d, _clone.d)\n * Documentation:  https://dlang.org/phobos/dmd_clone.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/clone.d\n */\n\nmodule dmd.clone;\n\nimport core.stdc.stdio;\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.mtype;\nimport dmd.opover;\nimport dmd.semantic2;\nimport dmd.statement;\nimport dmd.target;\nimport dmd.typesem;\nimport dmd.tokens;\n\n/*******************************************\n * Merge function attributes pure, nothrow, @safe, @nogc, and @disable\n * from f into s1.\n * Params:\n *      s1 = storage class to merge into\n *      f = function\n * Returns:\n *      merged storage class\n */\nStorageClass mergeFuncAttrs(StorageClass s1, const FuncDeclaration f) pure\n{\n    if (!f)\n        return s1;\n    StorageClass s2 = (f.storage_class & STC.disable);\n\n    TypeFunction tf = cast(TypeFunction)f.type;\n    if (tf.trust == TRUST.safe)\n        s2 |= STC.safe;\n    else if (tf.trust == TRUST.system)\n        s2 |= STC.system;\n    else if (tf.trust == TRUST.trusted)\n        s2 |= STC.trusted;\n\n    if (tf.purity != PURE.impure)\n        s2 |= STC.pure_;\n    if (tf.isnothrow)\n        s2 |= STC.nothrow_;\n    if (tf.isnogc)\n        s2 |= STC.nogc;\n\n    const sa = s1 & s2;\n    const so = s1 | s2;\n\n    StorageClass stc = (sa & (STC.pure_ | STC.nothrow_ | STC.nogc)) | (so & STC.disable);\n\n    if (so & STC.system)\n        stc |= STC.system;\n    else if (sa & STC.trusted)\n        stc |= STC.trusted;\n    else if ((so & (STC.trusted | STC.safe)) == (STC.trusted | STC.safe))\n        stc |= STC.trusted;\n    else if (sa & STC.safe)\n        stc |= STC.safe;\n\n    return stc;\n}\n\n/*******************************************\n * Check given aggregate actually has an identity opAssign or not.\n * Params:\n *      ad = struct or class\n *      sc = current scope\n * Returns:\n *      if found, returns FuncDeclaration of opAssign, otherwise null\n */\nFuncDeclaration hasIdentityOpAssign(AggregateDeclaration ad, Scope* sc)\n{\n    Dsymbol assign = search_function(ad, Id.assign);\n    if (assign)\n    {\n        /* check identity opAssign exists\n         */\n        scope er = new NullExp(ad.loc, ad.type);    // dummy rvalue\n        scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue\n        el.type = ad.type;\n        Expressions a;\n        a.setDim(1);\n        const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it.\n        sc = sc.push();\n        sc.tinst = null;\n        sc.minst = null;\n\n        a[0] = er;\n        auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, &a, 1);\n        if (!f)\n        {\n            a[0] = el;\n            f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, &a, 1);\n        }\n\n        sc = sc.pop();\n        global.endGagging(errors);\n        if (f)\n        {\n            if (f.errors)\n                return null;\n            int varargs;\n            auto fparams = f.getParameters(&varargs);\n            if (fparams.dim >= 1)\n            {\n                auto fparam0 = Parameter.getNth(fparams, 0);\n                if (fparam0.type.toDsymbol(null) != ad)\n                    f = null;\n            }\n        }\n        // BUGS: This detection mechanism cannot find some opAssign-s like follows:\n        // struct S { void opAssign(ref immutable S) const; }\n        return f;\n    }\n    return null;\n}\n\n/*******************************************\n * We need an opAssign for the struct if\n * it has a destructor or a postblit.\n * We need to generate one if a user-specified one does not exist.\n */\nprivate bool needOpAssign(StructDeclaration sd)\n{\n    //printf(\"StructDeclaration::needOpAssign() %s\\n\", sd.toChars());\n\n    static bool isNeeded()\n    {\n        //printf(\"\\tneed\\n\");\n        return true;\n    }\n\n    if (sd.isUnionDeclaration())\n        return !isNeeded();\n\n    if (sd.hasIdentityAssign || // because has identity==elaborate opAssign\n        sd.dtor ||\n        sd.postblit)\n        return isNeeded();\n\n    /* If any of the fields need an opAssign, then we\n     * need it too.\n     */\n    foreach (v; sd.fields)\n    {\n        if (v.storage_class & STC.ref_)\n            continue;\n        if (v.overlapped)               // if field of a union\n            continue;                   // user must handle it themselves\n        Type tv = v.type.baseElemOf();\n        if (tv.ty == Tstruct)\n        {\n            TypeStruct ts = cast(TypeStruct)tv;\n            if (ts.sym.isUnionDeclaration())\n                continue;\n            if (needOpAssign(ts.sym))\n                return isNeeded();\n        }\n    }\n    return !isNeeded();\n}\n\n/******************************************\n * Build opAssign for a `struct`.\n *\n * The generated `opAssign` function has the following signature:\n *---\n *ref S opAssign(S s)    // S is the name of the `struct`\n *---\n *\n * The opAssign function will be built for a struct `S` if the\n * following constraints are met:\n *\n * 1. `S` does not have an identity `opAssign` defined.\n *\n * 2. `S` has at least one of the following members: a postblit (user-defined or\n * generated for fields that have a defined postblit), a destructor\n * (user-defined or generated for fields that have a defined destructor)\n * or at least one field that has a defined `opAssign`.\n *\n * 3. `S` does not have any non-mutable fields.\n *\n * If `S` has a disabled destructor or at least one field that has a disabled\n * `opAssign`, `S.opAssign` is going to be generated, but marked with `@disable`\n *\n * If `S` defines a destructor, the generated code for `opAssign` is:\n *\n *---\n *S __swap = void;\n *__swap = this;   // bit copy\n *this = s;        // bit copy\n *__swap.dtor();\n *---\n *\n * Otherwise, if `S` defines a postblit, the generated code for `opAssign` is:\n *\n *---\n *this = s;\n *---\n *\n * Note that the parameter to the generated `opAssign` is passed by value, which means\n * that the postblit is going to be called (if it is defined) in both  of the above\n * situations before entering the body of `opAssign`. The assignments in the above generated\n * function bodies are blit expressions, so they can be regarded as `memcpy`s\n * (`opAssign` is not called as this will result in an infinite recursion; the postblit\n * is not called because it has already been called when the parameter was passed by value).\n *\n * If `S` does not have a postblit or a destructor, but contains at least one field that defines\n * an `opAssign` function (which is not disabled), then the body will make member-wise\n * assignments:\n *\n *---\n *this.field1 = s.field1;\n *this.field2 = s.field2;\n *...;\n *---\n *\n * In this situation, the assignemnts are actual assign expressions (`opAssign` is used\n * if defined).\n *\n * References:\n *      https://dlang.org/spec/struct.html#assign-overload\n * Params:\n *      sd = struct to generate opAssign for\n *      sc = context\n * Returns:\n *      generated `opAssign` function\n */\nFuncDeclaration buildOpAssign(StructDeclaration sd, Scope* sc)\n{\n    if (FuncDeclaration f = hasIdentityOpAssign(sd, sc))\n    {\n        sd.hasIdentityAssign = true;\n        return f;\n    }\n    // Even if non-identity opAssign is defined, built-in identity opAssign\n    // will be defined.\n    if (!needOpAssign(sd))\n        return null;\n\n    //printf(\"StructDeclaration::buildOpAssign() %s\\n\", sd.toChars());\n    StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;\n    Loc declLoc = sd.loc;\n    Loc loc; // internal code should have no loc to prevent coverage\n\n    // One of our sub-field might have `@disable opAssign` so we need to\n    // check for it.\n    // In this event, it will be reflected by having `stc` (opAssign's\n    // storage class) include `STC.disabled`.\n    foreach (v; sd.fields)\n    {\n        if (v.storage_class & STC.ref_)\n            continue;\n        if (v.overlapped)\n            continue;\n        Type tv = v.type.baseElemOf();\n        if (tv.ty != Tstruct)\n            continue;\n        StructDeclaration sdv = (cast(TypeStruct)tv).sym;\n        stc = mergeFuncAttrs(stc, hasIdentityOpAssign(sdv, sc));\n    }\n\n    if (sd.dtor || sd.postblit)\n    {\n        // if the type is not assignable, we cannot generate opAssign\n        if (!sd.type.isAssignable()) // https://issues.dlang.org/show_bug.cgi?id=13044\n            return null;\n        stc = mergeFuncAttrs(stc, sd.dtor);\n        if (stc & STC.safe)\n            stc = (stc & ~STC.safe) | STC.trusted;\n    }\n\n    auto fparams = new Parameters();\n    fparams.push(new Parameter(STC.nodtor, sd.type, Id.p, null, null));\n    auto tf = new TypeFunction(fparams, sd.handleType(), 0, LINK.d, stc | STC.ref_);\n    auto fop = new FuncDeclaration(declLoc, Loc.initial, Id.assign, stc, tf);\n    fop.storage_class |= STC.inference;\n    fop.generated = true;\n    Expression e;\n    if (stc & STC.disable)\n    {\n        e = null;\n    }\n    /* Do swap this and rhs.\n     *    __swap = this; this = s; __swap.dtor();\n     */\n    else if (sd.dtor)\n    {\n        //printf(\"\\tswap copy\\n\");\n        TypeFunction tdtor = cast(TypeFunction)sd.dtor.type;\n        assert(tdtor.ty == Tfunction);\n\n        auto idswap = Identifier.generateId(\"__swap\");\n        auto swap = new VarDeclaration(loc, sd.type, idswap, new VoidInitializer(loc));\n        swap.storage_class |= STC.nodtor | STC.temp | STC.ctfe;\n        if (tdtor.isscope)\n            swap.storage_class |= STC.scope_;\n        auto e1 = new DeclarationExp(loc, swap);\n\n        auto e2 = new BlitExp(loc, new VarExp(loc, swap), new ThisExp(loc));\n        auto e3 = new BlitExp(loc, new ThisExp(loc), new IdentifierExp(loc, Id.p));\n\n        /* Instead of running the destructor on s, run it\n         * on swap. This avoids needing to copy swap back in to s.\n         */\n        auto e4 = new CallExp(loc, new DotVarExp(loc, new VarExp(loc, swap), sd.dtor, false));\n\n        e = Expression.combine(e1, e2, e3, e4);\n    }\n    /* postblit was called when the value was passed to opAssign, we just need to blit the result */\n    else if (sd.postblit)\n        e = new BlitExp(loc, new ThisExp(loc), new IdentifierExp(loc, Id.p));\n    else\n    {\n        /* Do memberwise copy.\n         *\n         * If sd is a nested struct, its vthis field assignment is:\n         * 1. If it's nested in a class, it's a rebind of class reference.\n         * 2. If it's nested in a function or struct, it's an update of void*.\n         * In both cases, it will change the parent context.\n         */\n        //printf(\"\\tmemberwise copy\\n\");\n        e = null;\n        foreach (v; sd.fields)\n        {\n            // this.v = s.v;\n            auto ec = new AssignExp(loc,\n                new DotVarExp(loc, new ThisExp(loc), v),\n                new DotVarExp(loc, new IdentifierExp(loc, Id.p), v));\n            e = Expression.combine(e, ec);\n        }\n    }\n    if (e)\n    {\n        Statement s1 = new ExpStatement(loc, e);\n        /* Add:\n         *   return this;\n         */\n        auto er = new ThisExp(loc);\n        Statement s2 = new ReturnStatement(loc, er);\n        fop.fbody = new CompoundStatement(loc, s1, s2);\n        tf.isreturn = true;\n    }\n    sd.members.push(fop);\n    fop.addMember(sc, sd);\n    sd.hasIdentityAssign = true; // temporary mark identity assignable\n    const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it.\n    Scope* sc2 = sc.push();\n    sc2.stc = 0;\n    sc2.linkage = LINK.d;\n    fop.dsymbolSemantic(sc2);\n    fop.semantic2(sc2);\n    // https://issues.dlang.org/show_bug.cgi?id=15044\n    //semantic3(fop, sc2); // isn't run here for lazy forward reference resolution.\n\n    sc2.pop();\n    if (global.endGagging(errors)) // if errors happened\n    {\n        // Disable generated opAssign, because some members forbid identity assignment.\n        fop.storage_class |= STC.disable;\n        fop.fbody = null; // remove fbody which contains the error\n    }\n\n    //printf(\"-StructDeclaration::buildOpAssign() %s, errors = %d\\n\", sd.toChars(), (fop.storage_class & STC.disable) != 0);\n    //printf(\"fop.type: %s\\n\", fop.type.toPrettyChars());\n    return fop;\n}\n\n/*******************************************\n * We need an opEquals for the struct if\n * any fields has an opEquals.\n * Generate one if a user-specified one does not exist.\n */\nbool needOpEquals(StructDeclaration sd)\n{\n    //printf(\"StructDeclaration::needOpEquals() %s\\n\", sd.toChars());\n    if (sd.isUnionDeclaration())\n        goto Ldontneed;\n    if (sd.hasIdentityEquals)\n        goto Lneed;\n    /* If any of the fields has an opEquals, then we\n     * need it too.\n     */\n    for (size_t i = 0; i < sd.fields.dim; i++)\n    {\n        VarDeclaration v = sd.fields[i];\n        if (v.storage_class & STC.ref_)\n            continue;\n        if (v.overlapped)\n            continue;\n        Type tv = v.type.toBasetype();\n        auto tvbase = tv.baseElemOf();\n        if (tvbase.ty == Tstruct)\n        {\n            TypeStruct ts = cast(TypeStruct)tvbase;\n            if (ts.sym.isUnionDeclaration())\n                continue;\n            if (needOpEquals(ts.sym))\n                goto Lneed;\n            if (ts.sym.aliasthis) // https://issues.dlang.org/show_bug.cgi?id=14806\n                goto Lneed;\n        }\n        if (tv.isfloating())\n        {\n            // This is necessray for:\n            //  1. comparison of +0.0 and -0.0 should be true.\n            //  2. comparison of NANs should be false always.\n            goto Lneed;\n        }\n        if (tv.ty == Tarray)\n            goto Lneed;\n        if (tv.ty == Taarray)\n            goto Lneed;\n        if (tv.ty == Tclass)\n            goto Lneed;\n    }\nLdontneed:\n    //printf(\"\\tdontneed\\n\");\n    return false;\nLneed:\n    //printf(\"\\tneed\\n\");\n    return true;\n}\n\n/*******************************************\n * Check given aggregate actually has an identity opEquals or not.\n */\nprivate FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc)\n{\n    Dsymbol eq = search_function(ad, Id.eq);\n    if (eq)\n    {\n        /* check identity opEquals exists\n         */\n        scope er = new NullExp(ad.loc, null); // dummy rvalue\n        scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue\n        Expressions a;\n        a.setDim(1);\n        foreach (i; 0 .. 5)\n        {\n            Type tthis = null; // dead-store to prevent spurious warning\n            final switch (i)\n            {\n                case 0:  tthis = ad.type;                 break;\n                case 1:  tthis = ad.type.constOf();       break;\n                case 2:  tthis = ad.type.immutableOf();   break;\n                case 3:  tthis = ad.type.sharedOf();      break;\n                case 4:  tthis = ad.type.sharedConstOf(); break;\n            }\n            FuncDeclaration f = null;\n            const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it.\n            sc = sc.push();\n            sc.tinst = null;\n            sc.minst = null;\n            foreach (j; 0 .. 2)\n            {\n                a[0] = (j == 0 ? er : el);\n                a[0].type = tthis;\n                f = resolveFuncCall(ad.loc, sc, eq, null, tthis, &a, 1);\n                if (f)\n                    break;\n            }\n            sc = sc.pop();\n            global.endGagging(errors);\n            if (f)\n            {\n                if (f.errors)\n                    return null;\n                return f;\n            }\n        }\n    }\n    return null;\n}\n\n/******************************************\n * Build opEquals for struct.\n *      const bool opEquals(const S s) { ... }\n *\n * By fixing https://issues.dlang.org/show_bug.cgi?id=3789\n * opEquals is changed to be never implicitly generated.\n * Now, struct objects comparison s1 == s2 is translated to:\n *      s1.tupleof == s2.tupleof\n * to calculate structural equality. See EqualExp.op_overload.\n */\nFuncDeclaration buildOpEquals(StructDeclaration sd, Scope* sc)\n{\n    if (hasIdentityOpEquals(sd, sc))\n    {\n        sd.hasIdentityEquals = true;\n    }\n    return null;\n}\n\n/******************************************\n * Build __xopEquals for TypeInfo_Struct\n *      static bool __xopEquals(ref const S p, ref const S q)\n *      {\n *          return p == q;\n *      }\n *\n * This is called by TypeInfo.equals(p1, p2). If the struct does not support\n * const objects comparison, it will throw \"not implemented\" Error in runtime.\n */\nFuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc)\n{\n    if (!needOpEquals(sd))\n        return null; // bitwise comparison would work\n\n    //printf(\"StructDeclaration::buildXopEquals() %s\\n\", sd.toChars());\n    if (Dsymbol eq = search_function(sd, Id.eq))\n    {\n        if (FuncDeclaration fd = eq.isFuncDeclaration())\n        {\n            TypeFunction tfeqptr;\n            {\n                Scope scx;\n                /* const bool opEquals(ref const S s);\n                 */\n                auto parameters = new Parameters();\n                parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, null, null, null));\n                tfeqptr = new TypeFunction(parameters, Type.tbool, 0, LINK.d);\n                tfeqptr.mod = MODFlags.const_;\n                tfeqptr = cast(TypeFunction)tfeqptr.typeSemantic(Loc.initial, &scx);\n            }\n            fd = fd.overloadExactMatch(tfeqptr);\n            if (fd)\n                return fd;\n        }\n    }\n    if (!sd.xerreq)\n    {\n        // object._xopEquals\n        Identifier id = Identifier.idPool(\"_xopEquals\");\n        Expression e = new IdentifierExp(sd.loc, Id.empty);\n        e = new DotIdExp(sd.loc, e, Id.object);\n        e = new DotIdExp(sd.loc, e, id);\n        e = e.expressionSemantic(sc);\n        Dsymbol s = getDsymbol(e);\n        assert(s);\n        sd.xerreq = s.isFuncDeclaration();\n    }\n    Loc declLoc; // loc is unnecessary so __xopEquals is never called directly\n    Loc loc; // loc is unnecessary so errors are gagged\n    auto parameters = new Parameters();\n    parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));\n    parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.q, null, null));\n    auto tf = new TypeFunction(parameters, Type.tbool, 0, LINK.d);\n    Identifier id = Id.xopEquals;\n    auto fop = new FuncDeclaration(declLoc, Loc.initial, id, STC.static_, tf);\n    fop.generated = true;\n    Expression e1 = new IdentifierExp(loc, Id.p);\n    Expression e2 = new IdentifierExp(loc, Id.q);\n    Expression e = new EqualExp(TOK.equal, loc, e1, e2);\n    fop.fbody = new ReturnStatement(loc, e);\n    uint errors = global.startGagging(); // Do not report errors\n    Scope* sc2 = sc.push();\n    sc2.stc = 0;\n    sc2.linkage = LINK.d;\n    fop.dsymbolSemantic(sc2);\n    fop.semantic2(sc2);\n    sc2.pop();\n    if (global.endGagging(errors)) // if errors happened\n        fop = sd.xerreq;\n    return fop;\n}\n\n/******************************************\n * Build __xopCmp for TypeInfo_Struct\n *      static bool __xopCmp(ref const S p, ref const S q)\n *      {\n *          return p.opCmp(q);\n *      }\n *\n * This is called by TypeInfo.compare(p1, p2). If the struct does not support\n * const objects comparison, it will throw \"not implemented\" Error in runtime.\n */\nFuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc)\n{\n    //printf(\"StructDeclaration::buildXopCmp() %s\\n\", toChars());\n    if (Dsymbol cmp = search_function(sd, Id.cmp))\n    {\n        if (FuncDeclaration fd = cmp.isFuncDeclaration())\n        {\n            TypeFunction tfcmpptr;\n            {\n                Scope scx;\n                /* const int opCmp(ref const S s);\n                 */\n                auto parameters = new Parameters();\n                parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, null, null, null));\n                tfcmpptr = new TypeFunction(parameters, Type.tint32, 0, LINK.d);\n                tfcmpptr.mod = MODFlags.const_;\n                tfcmpptr = cast(TypeFunction)tfcmpptr.typeSemantic(Loc.initial, &scx);\n            }\n            fd = fd.overloadExactMatch(tfcmpptr);\n            if (fd)\n                return fd;\n        }\n    }\n    else\n    {\n        version (none) // FIXME: doesn't work for recursive alias this\n        {\n            /* Check opCmp member exists.\n             * Consider 'alias this', but except opDispatch.\n             */\n            Expression e = new DsymbolExp(sd.loc, sd);\n            e = new DotIdExp(sd.loc, e, Id.cmp);\n            Scope* sc2 = sc.push();\n            e = e.trySemantic(sc2);\n            sc2.pop();\n            if (e)\n            {\n                Dsymbol s = null;\n                switch (e.op)\n                {\n                case TOK.overloadSet:\n                    s = (cast(OverExp)e).vars;\n                    break;\n                case TOK.scope_:\n                    s = (cast(ScopeExp)e).sds;\n                    break;\n                case TOK.variable:\n                    s = (cast(VarExp)e).var;\n                    break;\n                default:\n                    break;\n                }\n                if (!s || s.ident != Id.cmp)\n                    e = null; // there's no valid member 'opCmp'\n            }\n            if (!e)\n                return null; // bitwise comparison would work\n            /* Essentially, a struct which does not define opCmp is not comparable.\n             * At this time, typeid(S).compare might be correct that throwing \"not implement\" Error.\n             * But implementing it would break existing code, such as:\n             *\n             * struct S { int value; }  // no opCmp\n             * int[S] aa;   // Currently AA key uses bitwise comparison\n             *              // (It's default behavior of TypeInfo_Strust.compare).\n             *\n             * Not sure we should fix this inconsistency, so just keep current behavior.\n             */\n        }\n        else\n        {\n            return null;\n        }\n    }\n    if (!sd.xerrcmp)\n    {\n        // object._xopCmp\n        Identifier id = Identifier.idPool(\"_xopCmp\");\n        Expression e = new IdentifierExp(sd.loc, Id.empty);\n        e = new DotIdExp(sd.loc, e, Id.object);\n        e = new DotIdExp(sd.loc, e, id);\n        e = e.expressionSemantic(sc);\n        Dsymbol s = getDsymbol(e);\n        assert(s);\n        sd.xerrcmp = s.isFuncDeclaration();\n    }\n    Loc declLoc; // loc is unnecessary so __xopCmp is never called directly\n    Loc loc; // loc is unnecessary so errors are gagged\n    auto parameters = new Parameters();\n    parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));\n    parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.q, null, null));\n    auto tf = new TypeFunction(parameters, Type.tint32, 0, LINK.d);\n    Identifier id = Id.xopCmp;\n    auto fop = new FuncDeclaration(declLoc, Loc.initial, id, STC.static_, tf);\n    fop.generated = true;\n    Expression e1 = new IdentifierExp(loc, Id.p);\n    Expression e2 = new IdentifierExp(loc, Id.q);\n    version (IN_GCC)\n        Expression e = new CallExp(loc, new DotIdExp(loc, e1, Id.cmp), e2);\n    else\n        Expression e = new CallExp(loc, new DotIdExp(loc, e2, Id.cmp), e1);\n    fop.fbody = new ReturnStatement(loc, e);\n    uint errors = global.startGagging(); // Do not report errors\n    Scope* sc2 = sc.push();\n    sc2.stc = 0;\n    sc2.linkage = LINK.d;\n    fop.dsymbolSemantic(sc2);\n    fop.semantic2(sc2);\n    sc2.pop();\n    if (global.endGagging(errors)) // if errors happened\n        fop = sd.xerrcmp;\n    return fop;\n}\n\n/*******************************************\n * We need a toHash for the struct if\n * any fields has a toHash.\n * Generate one if a user-specified one does not exist.\n */\nprivate bool needToHash(StructDeclaration sd)\n{\n    //printf(\"StructDeclaration::needToHash() %s\\n\", sd.toChars());\n    if (sd.isUnionDeclaration())\n        goto Ldontneed;\n    if (sd.xhash)\n        goto Lneed;\n\n    /* If any of the fields has an opEquals, then we\n     * need it too.\n     */\n    for (size_t i = 0; i < sd.fields.dim; i++)\n    {\n        VarDeclaration v = sd.fields[i];\n        if (v.storage_class & STC.ref_)\n            continue;\n        if (v.overlapped)\n            continue;\n        Type tv = v.type.toBasetype();\n        auto tvbase = tv.baseElemOf();\n        if (tvbase.ty == Tstruct)\n        {\n            TypeStruct ts = cast(TypeStruct)tvbase;\n            if (ts.sym.isUnionDeclaration())\n                continue;\n            if (needToHash(ts.sym))\n                goto Lneed;\n            if (ts.sym.aliasthis) // https://issues.dlang.org/show_bug.cgi?id=14948\n                goto Lneed;\n        }\n        if (tv.isfloating())\n        {\n            /* This is necessary because comparison of +0.0 and -0.0 should be true,\n             * i.e. not a bit compare.\n             */\n            goto Lneed;\n        }\n        if (tv.ty == Tarray)\n            goto Lneed;\n        if (tv.ty == Taarray)\n            goto Lneed;\n        if (tv.ty == Tclass)\n            goto Lneed;\n    }\nLdontneed:\n    //printf(\"\\tdontneed\\n\");\n    return false;\nLneed:\n    //printf(\"\\tneed\\n\");\n    return true;\n}\n\n/******************************************\n * Build __xtoHash for non-bitwise hashing\n *      static hash_t xtoHash(ref const S p) nothrow @trusted;\n */\nFuncDeclaration buildXtoHash(StructDeclaration sd, Scope* sc)\n{\n    if (Dsymbol s = search_function(sd, Id.tohash))\n    {\n        __gshared TypeFunction tftohash;\n        if (!tftohash)\n        {\n            tftohash = new TypeFunction(null, Type.thash_t, 0, LINK.d);\n            tftohash.mod = MODFlags.const_;\n            tftohash = cast(TypeFunction)tftohash.merge();\n        }\n        if (FuncDeclaration fd = s.isFuncDeclaration())\n        {\n            fd = fd.overloadExactMatch(tftohash);\n            if (fd)\n                return fd;\n        }\n    }\n    if (!needToHash(sd))\n        return null;\n\n    //printf(\"StructDeclaration::buildXtoHash() %s\\n\", sd.toPrettyChars());\n    Loc declLoc; // loc is unnecessary so __xtoHash is never called directly\n    Loc loc; // internal code should have no loc to prevent coverage\n    auto parameters = new Parameters();\n    parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));\n    auto tf = new TypeFunction(parameters, Type.thash_t, 0, LINK.d, STC.nothrow_ | STC.trusted);\n    Identifier id = Id.xtoHash;\n    auto fop = new FuncDeclaration(declLoc, Loc.initial, id, STC.static_, tf);\n    fop.generated = true;\n\n    /* Do memberwise hashing.\n     *\n     * If sd is a nested struct, and if it's nested in a class, the calculated\n     * hash value will also contain the result of parent class's toHash().\n     */\n    const(char)* code =\n        \"size_t h = 0;\" ~\n        \"foreach (i, T; typeof(p.tupleof))\" ~\n        // workaround https://issues.dlang.org/show_bug.cgi?id=17968\n        \"    static if(is(T* : const(.object.Object)*)) \" ~\n        \"        h = h * 33 + typeid(const(.object.Object)).getHash(cast(const void*)&p.tupleof[i]);\" ~\n        \"    else \" ~\n        \"        h = h * 33 + typeid(T).getHash(cast(const void*)&p.tupleof[i]);\" ~\n        \"return h;\";\n    fop.fbody = new CompileStatement(loc, new StringExp(loc, cast(char*)code));\n    Scope* sc2 = sc.push();\n    sc2.stc = 0;\n    sc2.linkage = LINK.d;\n    fop.dsymbolSemantic(sc2);\n    fop.semantic2(sc2);\n    sc2.pop();\n\n    //printf(\"%s fop = %s %s\\n\", sd.toChars(), fop.toChars(), fop.type.toChars());\n    return fop;\n}\n\n/*****************************************\n * Create inclusive destructor for struct/class by aggregating\n * all the destructors in dtors[] with the destructors for\n * all the members.\n * Params:\n *      ad = struct or class to build destructor for\n *      sc = context\n * Returns:\n *      generated function, null if none needed\n * Note:\n * Close similarity with StructDeclaration::buildPostBlit(),\n * and the ordering changes (runs backward instead of forwards).\n */\nDtorDeclaration buildDtor(AggregateDeclaration ad, Scope* sc)\n{\n    //printf(\"AggregateDeclaration::buildDtor() %s\\n\", ad.toChars());\n    if (ad.isUnionDeclaration())\n        return null;                    // unions don't have destructors\n\n    StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;\n    Loc declLoc = ad.dtors.dim ? ad.dtors[0].loc : ad.loc;\n    Loc loc; // internal code should have no loc to prevent coverage\n\n    // if the dtor is an extern(C++) prototype, then we expect it performs a full-destruction; we don't need to build a full-dtor\n    const bool dtorIsCppPrototype = ad.dtors.dim == 1 && ad.dtors[0].linkage == LINK.cpp && !ad.dtors[0].fbody;\n    if (!dtorIsCppPrototype)\n    {\n        Expression e = null;\n        for (size_t i = 0; i < ad.fields.dim; i++)\n        {\n            auto v = ad.fields[i];\n            if (v.storage_class & STC.ref_)\n                continue;\n            if (v.overlapped)\n                continue;\n            auto tv = v.type.baseElemOf();\n            if (tv.ty != Tstruct)\n                continue;\n            auto sdv = (cast(TypeStruct)tv).sym;\n            if (!sdv.dtor)\n                continue;\n            sdv.dtor.functionSemantic();\n\n            stc = mergeFuncAttrs(stc, sdv.dtor);\n            if (stc & STC.disable)\n            {\n                e = null;\n                break;\n            }\n\n            Expression ex;\n            tv = v.type.toBasetype();\n            if (tv.ty == Tstruct)\n            {\n                // this.v.__xdtor()\n\n                ex = new ThisExp(loc);\n                ex = new DotVarExp(loc, ex, v);\n\n                // This is a hack so we can call destructors on const/immutable objects.\n                // Do it as a type 'paint'.\n                ex = new CastExp(loc, ex, v.type.mutableOf());\n                if (stc & STC.safe)\n                    stc = (stc & ~STC.safe) | STC.trusted;\n\n                ex = new DotVarExp(loc, ex, sdv.dtor, false);\n                ex = new CallExp(loc, ex);\n            }\n            else\n            {\n                // __ArrayDtor((cast(S*)this.v.ptr)[0 .. n])\n\n                const n = tv.numberOfElems(loc);\n                if (n == 0)\n                    continue;\n\n                ex = new ThisExp(loc);\n                ex = new DotVarExp(loc, ex, v);\n\n                // This is a hack so we can call destructors on const/immutable objects.\n                ex = new DotIdExp(loc, ex, Id.ptr);\n                ex = new CastExp(loc, ex, sdv.type.pointerTo());\n                if (stc & STC.safe)\n                    stc = (stc & ~STC.safe) | STC.trusted;\n\n                ex = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t),\n                                           new IntegerExp(loc, n, Type.tsize_t));\n                // Prevent redundant bounds check\n                (cast(SliceExp)ex).upperIsInBounds = true;\n                (cast(SliceExp)ex).lowerIsLessThanUpper = true;\n\n                ex = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayDtor), ex);\n            }\n            e = Expression.combine(ex, e); // combine in reverse order\n        }\n\n        /* extern(C++) destructors call into super to destruct the full hierarchy\n        */\n        ClassDeclaration cldec = ad.isClassDeclaration();\n        if (cldec && cldec.classKind == ClassKind.cpp && cldec.baseClass && cldec.baseClass.primaryDtor)\n        {\n            // WAIT BUT: do I need to run `cldec.baseClass.dtor` semantic? would it have been run before?\n            cldec.baseClass.dtor.functionSemantic();\n\n            stc = mergeFuncAttrs(stc, cldec.baseClass.primaryDtor);\n            if (!(stc & STC.disable))\n            {\n                // super.__xdtor()\n\n                Expression ex = new SuperExp(loc);\n\n                // This is a hack so we can call destructors on const/immutable objects.\n                // Do it as a type 'paint'.\n                ex = new CastExp(loc, ex, cldec.baseClass.type.mutableOf());\n                if (stc & STC.safe)\n                    stc = (stc & ~STC.safe) | STC.trusted;\n\n                ex = new DotVarExp(loc, ex, cldec.baseClass.primaryDtor, false);\n                ex = new CallExp(loc, ex);\n\n                e = Expression.combine(e, ex); // super dtor last\n            }\n        }\n\n        /* Build our own \"destructor\" which executes e\n         */\n        if (e || (stc & STC.disable))\n        {\n            //printf(\"Building __fieldDtor(), %s\\n\", e.toChars());\n            auto dd = new DtorDeclaration(declLoc, Loc.initial, stc, Id.__fieldDtor);\n            dd.generated = true;\n            dd.storage_class |= STC.inference;\n            dd.fbody = new ExpStatement(loc, e);\n            ad.dtors.shift(dd);\n            ad.members.push(dd);\n            dd.dsymbolSemantic(sc);\n            ad.fieldDtor = dd;\n        }\n    }\n\n    DtorDeclaration xdtor = null;\n    switch (ad.dtors.dim)\n    {\n    case 0:\n        break;\n\n    case 1:\n        xdtor = ad.dtors[0];\n        break;\n\n    default:\n        assert(!dtorIsCppPrototype);\n        Expression e = null;\n        e = null;\n        stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;\n        for (size_t i = 0; i < ad.dtors.dim; i++)\n        {\n            FuncDeclaration fd = ad.dtors[i];\n            stc = mergeFuncAttrs(stc, fd);\n            if (stc & STC.disable)\n            {\n                e = null;\n                break;\n            }\n            Expression ex = new ThisExp(loc);\n            ex = new DotVarExp(loc, ex, fd, false);\n            ex = new CallExp(loc, ex);\n            e = Expression.combine(ex, e);\n        }\n        auto dd = new DtorDeclaration(declLoc, Loc.initial, stc, Id.__aggrDtor);\n        dd.generated = true;\n        dd.storage_class |= STC.inference;\n        dd.fbody = new ExpStatement(loc, e);\n        ad.members.push(dd);\n        dd.dsymbolSemantic(sc);\n        xdtor = dd;\n        break;\n    }\n\n    ad.primaryDtor = xdtor;\n\n    if (xdtor && xdtor.linkage == LINK.cpp && !Target.twoDtorInVtable)\n        xdtor = buildWindowsCppDtor(ad, xdtor, sc);\n\n    // Add an __xdtor alias to make the inclusive dtor accessible\n    if (xdtor)\n    {\n        auto _alias = new AliasDeclaration(Loc.initial, Id.__xdtor, xdtor);\n        _alias.dsymbolSemantic(sc);\n        ad.members.push(_alias);\n        _alias.addMember(sc, ad); // add to symbol table\n    }\n\n    return xdtor;\n}\n\n/**\n * build a shim function around the compound dtor that accepts an argument\n *  that is used to implement the deleting C++ destructor\n *\n * Params:\n *  ad = the aggregate that contains the destructor to wrap\n *  dtor = the destructor to wrap\n *  sc = the scope in which to analyze the new function\n *\n * Returns:\n *  the shim destructor, semantically analyzed and added to the class as a member\n */\nprivate DtorDeclaration buildWindowsCppDtor(AggregateDeclaration ad, DtorDeclaration dtor, Scope* sc)\n{\n    auto cldec = ad.isClassDeclaration();\n    if (!cldec || cldec.cppDtorVtblIndex == -1) // scalar deleting dtor not built for non-virtual dtors\n        return dtor;\n\n    // generate deleting C++ destructor corresponding to:\n    // void* C::~C(int del)\n    // {\n    //   this->~C();\n    //   // TODO: if (del) delete (char*)this;\n    //   return (void*) this;\n    // }\n    Parameter delparam = new Parameter(STC.undefined_, Type.tuns32, Identifier.idPool(\"del\"), new IntegerExp(dtor.loc, 0, Type.tuns32), null);\n    Parameters* params = new Parameters;\n    params.push(delparam);\n    auto ftype = new TypeFunction(params, Type.tvoidptr, false, LINK.cpp, dtor.storage_class);\n    auto func = new DtorDeclaration(dtor.loc, dtor.loc, dtor.storage_class, Id.cppdtor);\n    func.type = ftype;\n    if (dtor.fbody)\n    {\n        const loc = dtor.loc;\n        auto stmts = new Statements;\n        auto call = new CallExp(loc, dtor, null);\n        call.directcall = true;\n        stmts.push(new ExpStatement(loc, call));\n        stmts.push(new ReturnStatement(loc, new CastExp(loc, new ThisExp(loc), Type.tvoidptr)));\n        func.fbody = new CompoundStatement(loc, stmts);\n        func.generated = true;\n    }\n\n    auto sc2 = sc.push();\n    sc2.stc &= ~STC.static_; // not a static destructor\n    sc2.linkage = LINK.cpp;\n\n    ad.members.push(func);\n    func.addMember(sc2, ad);\n    func.dsymbolSemantic(sc2);\n\n    sc2.pop();\n    return func;\n}\n\n/**\n * build a shim function around the compound dtor that translates\n *  a C++ destructor to a destructor with extern(D) calling convention\n *\n * Params:\n *  ad = the aggregate that contains the destructor to wrap\n *  sc = the scope in which to analyze the new function\n *\n * Returns:\n *  the shim destructor, semantically analyzed and added to the class as a member\n */\nDtorDeclaration buildExternDDtor(AggregateDeclaration ad, Scope* sc)\n{\n    auto dtor = ad.primaryDtor;\n    if (!dtor)\n        return null;\n\n    // ABI incompatible on all (?) x86 32-bit platforms\n    if (ad.classKind != ClassKind.cpp || global.params.is64bit)\n        return dtor;\n\n    // generate member function that adjusts calling convention\n    // (EAX used for 'this' instead of ECX on Windows/stack on others):\n    // extern(D) void __ticppdtor()\n    // {\n    //     Class.__dtor();\n    // }\n    auto ftype = new TypeFunction(null, Type.tvoid, false, LINK.d, dtor.storage_class);\n    auto func = new DtorDeclaration(dtor.loc, dtor.loc, dtor.storage_class, Id.ticppdtor);\n    func.type = ftype;\n\n    auto call = new CallExp(dtor.loc, dtor, null);\n    call.directcall = true;                   // non-virtual call Class.__dtor();\n    func.fbody = new ExpStatement(dtor.loc, call);\n    func.generated = true;\n    func.storage_class |= STC.inference;\n\n    auto sc2 = sc.push();\n    sc2.stc &= ~STC.static_; // not a static destructor\n    sc2.linkage = LINK.d;\n\n    ad.members.push(func);\n    func.addMember(sc2, ad);\n    func.dsymbolSemantic(sc2);\n    func.functionSemantic(); // to infer attributes\n\n    sc2.pop();\n    return func;\n}\n\n/******************************************\n * Create inclusive invariant for struct/class by aggregating\n * all the invariants in invs[].\n *      void __invariant() const [pure nothrow @trusted]\n *      {\n *          invs[0](), invs[1](), ...;\n *      }\n */\nFuncDeclaration buildInv(AggregateDeclaration ad, Scope* sc)\n{\n    switch (ad.invs.dim)\n    {\n    case 0:\n        return null;\n\n    case 1:\n        // Don't return invs[0] so it has uniquely generated name.\n        goto default;\n\n    default:\n        Expression e = null;\n        StorageClass stcx = 0;\n        StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;\n        foreach (i, inv; ad.invs)\n        {\n            stc = mergeFuncAttrs(stc, inv);\n            if (stc & STC.disable)\n            {\n                // What should do?\n            }\n            const stcy = (inv.storage_class & STC.synchronized_) |\n                         (inv.type.mod & MODFlags.shared_ ? STC.shared_ : 0);\n            if (i == 0)\n                stcx = stcy;\n            else if (stcx ^ stcy)\n            {\n                version (all)\n                {\n                    // currently rejects\n                    ad.error(inv.loc, \"mixing invariants with different `shared`/`synchronized` qualifiers is not supported\");\n                    e = null;\n                    break;\n                }\n            }\n            e = Expression.combine(e, new CallExp(Loc.initial, new VarExp(Loc.initial, inv, false)));\n        }\n        auto inv = new InvariantDeclaration(ad.loc, Loc.initial, stc | stcx,\n                Id.classInvariant, new ExpStatement(Loc.initial, e));\n        ad.members.push(inv);\n        inv.dsymbolSemantic(sc);\n        return inv;\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/compiler.d",
    "content": "/* compiler.d -- Compiler interface for the D front end.\n * Copyright (C) 2018 Free Software Foundation, Inc.\n *\n * GCC is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3, or (at your option)\n * any later version.\n *\n * GCC is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with GCC; see the file COPYING3.  If not see\n * <http://www.gnu.org/licenses/>.\n */\n\nmodule dmd.compiler;\n\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.expression;\nimport dmd.mtype;\n\n/**\n * A data structure that describes a back-end compiler and implements\n * compiler-specific actions.\n */\nstruct Compiler\n{\n    /**\n     * Generate C main() in response to seeing D main().\n     *\n     * This function will generate a module called `__entrypoint`,\n     * and set the globals `entrypoint` and `rootHasMain`.\n     *\n     * This used to be in druntime, but contained a reference to _Dmain\n     * which didn't work when druntime was made into a dll and was linked\n     * to a program, such as a C++ program, that didn't have a _Dmain.\n     *\n     * Params:\n     *   sc = Scope which triggered the generation of the C main,\n     *        used to get the module where the D main is.\n     */\n    extern (C++) static void genCmain(Scope* sc);\n\n    /******************************\n     * Encode the given expression, which is assumed to be an rvalue literal\n     * as another type for use in CTFE.\n     * This corresponds roughly to the idiom *(Type *)&e.\n     */\n    extern (C++) static Expression paintAsType(Expression e, Type type);\n\n    /******************************\n     * For the given module, perform any post parsing analysis.\n     * Certain compiler backends (ie: GDC) have special placeholder\n     * modules whose source are empty, but code gets injected\n     * immediately after loading.\n     */\n    extern (C++) static void loadModule(Module m);\n\n    /**\n     * A callback function that is called once an imported module is\n     * parsed. If the callback returns true, then it tells the\n     * frontend that the driver intends on compiling the import.\n     */\n    extern(C++) static bool onImport(Module m);\n}\n"
  },
  {
    "path": "gcc/d/dmd/compiler.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/compiler.h\n */\n\n#pragma once\n\n#include \"root/array.h\"\n\n// This file contains a data structure that describes a back-end compiler\n// and implements compiler-specific actions.\n\nclass Expression;\nclass Module;\nclass Type;\nstruct Scope;\n\n// DMD-generated module `__entrypoint` where the C main resides\nextern Module *entrypoint;\n// Module in which the D main is\nextern Module *rootHasMain;\n\nextern bool includeImports;\n// array of module patterns used to include/exclude imported modules\nextern Array<const char*> includeModulePatterns;\nextern Array<Module *> compiledImports;\n\nstruct Compiler\n{\n    // CTFE support for cross-compilation.\n    static Expression *paintAsType(Expression *, Type *);\n    // Backend\n    static void loadModule(Module *);\n    static void genCmain(Scope *);\n    static bool onImport(Module *);\n};\n"
  },
  {
    "path": "gcc/d/dmd/complex.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/complex.d, _complex.d)\n * Documentation:  https://dlang.org/phobos/dmd_complex.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/complex.d\n */\n\nmodule dmd.complex;\n\nimport dmd.root.ctfloat;\n\nstruct complex_t\n{\n    real_t re;\n    real_t im;\n\n    this() @disable;\n\n    this(real_t re)\n    {\n        this(re, CTFloat.zero);\n    }\n\n    this(real_t re, real_t im)\n    {\n        this.re = re;\n        this.im = im;\n    }\n\n    complex_t opAdd(complex_t y)\n    {\n        return complex_t(re + y.re, im + y.im);\n    }\n\n    complex_t opSub(complex_t y)\n    {\n        return complex_t(re - y.re, im - y.im);\n    }\n\n    complex_t opNeg()\n    {\n        return complex_t(-re, -im);\n    }\n\n    complex_t opMul(complex_t y)\n    {\n        return complex_t(re * y.re - im * y.im, im * y.re + re * y.im);\n    }\n\n    complex_t opMul_r(real_t x)\n    {\n        return complex_t(x) * this;\n    }\n\n    complex_t opMul(real_t y)\n    {\n        return this * complex_t(y);\n    }\n\n    complex_t opDiv(real_t y)\n    {\n        return this / complex_t(y);\n    }\n\n    complex_t opDiv(complex_t y)\n    {\n        if (CTFloat.fabs(y.re) < CTFloat.fabs(y.im))\n        {\n            const r = y.re / y.im;\n            const den = y.im + r * y.re;\n            return complex_t((re * r + im) / den, (im * r - re) / den);\n        }\n        else\n        {\n            const r = y.im / y.re;\n            const den = y.re + r * y.im;\n            return complex_t((re + r * im) / den, (im - r * re) / den);\n        }\n    }\n\n    bool opCast(T : bool)() const\n    {\n        return re || im;\n    }\n\n    int opEquals(complex_t y) const\n    {\n        return re == y.re && im == y.im;\n    }\n}\n\nextern (C++) real_t creall(complex_t x)\n{\n    return x.re;\n}\n\nextern (C++) real_t cimagl(complex_t x)\n{\n    return x.im;\n}\n"
  },
  {
    "path": "gcc/d/dmd/complex_t.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/complex_t.h\n */\n\n#pragma once\n\n#include \"root/ctfloat.h\"\n\n/* Roll our own complex type for compilers that don't support complex\n */\n\nstruct complex_t\n{\n    real_t re;\n    real_t im;\n\n    complex_t(real_t re) : re(re), im(CTFloat::zero) {}\n    complex_t(real_t re, real_t im) : re(re), im(im) {}\n\n    complex_t operator + (complex_t y) { return complex_t(re + y.re, im + y.im); }\n    complex_t operator - (complex_t y) { return complex_t(re - y.re, im - y.im); }\n    complex_t operator - () { return complex_t(-re, -im); }\n    complex_t operator * (complex_t y) { return complex_t(re * y.re - im * y.im, im * y.re + re * y.im); }\n\n    complex_t operator / (complex_t y)\n    {\n        if (CTFloat::fabs(y.re) < CTFloat::fabs(y.im))\n        {\n            real_t r = y.re / y.im;\n            real_t den = y.im + r * y.re;\n            return complex_t((re * r + im) / den,\n                             (im * r - re) / den);\n        }\n        else\n        {\n            real_t r = y.im / y.re;\n            real_t den = y.re + r * y.im;\n            return complex_t((re + r * im) / den,\n                             (im - r * re) / den);\n        }\n    }\n\n    operator bool () { return re || im; }\n\n    int operator == (complex_t y) { return re == y.re && im == y.im; }\n    int operator != (complex_t y) { return re != y.re || im != y.im; }\n\nprivate:\n    complex_t() : re(CTFloat::zero), im(CTFloat::zero) {}\n};\n\ninline complex_t operator * (real_t x, complex_t y) { return complex_t(x) * y; }\ninline complex_t operator * (complex_t x, real_t y) { return x * complex_t(y); }\ninline complex_t operator / (complex_t x, real_t y) { return x / complex_t(y); }\n\n\ninline real_t creall(complex_t x)\n{\n    return x.re;\n}\n\ninline real_t cimagl(complex_t x)\n{\n    return x.im;\n}\n"
  },
  {
    "path": "gcc/d/dmd/cond.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/cond.d, _cond.d)\n * Documentation:  https://dlang.org/phobos/dmd_cond.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/cond.d\n */\n\nmodule dmd.cond;\n\nimport core.stdc.string;\nimport dmd.arraytypes;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.globals;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.tokens;\nimport dmd.utils;\nimport dmd.visitor;\nimport dmd.id;\nimport dmd.statement;\nimport dmd.declaration;\nimport dmd.dstruct;\nimport dmd.func;\n\n/***********************************************************\n */\nextern (C++) abstract class Condition : RootObject\n{\n    Loc loc;\n    // 0: not computed yet\n    // 1: include\n    // 2: do not include\n    int inc;\n\n    override final DYNCAST dyncast() const\n    {\n        return DYNCAST.condition;\n    }\n\n    extern (D) this(const ref Loc loc)\n    {\n        this.loc = loc;\n    }\n\n    abstract Condition syntaxCopy();\n\n    abstract int include(Scope* sc);\n\n    DebugCondition isDebugCondition()\n    {\n        return null;\n    }\n\n    void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Implements common functionality for StaticForeachDeclaration and\n * StaticForeachStatement This performs the necessary lowerings before\n * dmd.statementsem.makeTupleForeach can be used to expand the\n * corresponding `static foreach` declaration or statement.\n */\n\nextern (C++) final class StaticForeach : RootObject\n{\n    extern(D) static immutable tupleFieldName = \"tuple\"; // used in lowering\n\n    Loc loc;\n\n    /***************\n     * Not `null` iff the `static foreach` is over an aggregate. In\n     * this case, it contains the corresponding ForeachStatement. For\n     * StaticForeachDeclaration, the body is `null`.\n    */\n    ForeachStatement aggrfe;\n    /***************\n     * Not `null` iff the `static foreach` is over a range. Exactly\n     * one of the `aggrefe` and `rangefe` fields is not null. See\n     * `aggrfe` field for more details.\n     */\n    ForeachRangeStatement rangefe;\n\n    /***************\n     * true if it is necessary to expand a tuple into multiple\n     * variables (see lowerNonArrayAggregate).\n     */\n    bool needExpansion = false;\n\n    extern (D) this(const ref Loc loc,ForeachStatement aggrfe,ForeachRangeStatement rangefe)\n    {\n        assert(!!aggrfe ^ !!rangefe);\n\n        this.loc = loc;\n        this.aggrfe = aggrfe;\n        this.rangefe = rangefe;\n    }\n\n    StaticForeach syntaxCopy()\n    {\n        return new StaticForeach(\n            loc,\n            aggrfe ? cast(ForeachStatement)aggrfe.syntaxCopy() : null,\n            rangefe ? cast(ForeachRangeStatement)rangefe.syntaxCopy() : null\n        );\n    }\n\n    /*****************************************\n     * Turn an aggregate which is an array into an expression tuple\n     * of its elements. I.e., lower\n     *     static foreach (x; [1, 2, 3, 4]) { ... }\n     * to\n     *     static foreach (x; AliasSeq!(1, 2, 3, 4)) { ... }\n     */\n    private extern(D) void lowerArrayAggregate(Scope* sc)\n    {\n        auto aggr = aggrfe.aggr;\n        Expression el = new ArrayLengthExp(aggr.loc, aggr);\n        sc = sc.startCTFE();\n        el = el.expressionSemantic(sc);\n        sc = sc.endCTFE();\n        el = el.optimize(WANTvalue);\n        el = el.ctfeInterpret();\n        if (el.op == TOK.int64)\n        {\n            dinteger_t length = el.toInteger();\n            auto es = new Expressions();\n            foreach (i; 0 .. length)\n            {\n                auto index = new IntegerExp(loc, i, Type.tsize_t);\n                auto value = new IndexExp(aggr.loc, aggr, index);\n                es.push(value);\n            }\n            aggrfe.aggr = new TupleExp(aggr.loc, es);\n            aggrfe.aggr = aggrfe.aggr.expressionSemantic(sc);\n            aggrfe.aggr = aggrfe.aggr.optimize(WANTvalue);\n        }\n        else\n        {\n            aggrfe.aggr = new ErrorExp();\n        }\n    }\n\n    /*****************************************\n     * Wrap a statement into a function literal and call it.\n     *\n     * Params:\n     *     loc = The source location.\n     *     s  = The statement.\n     * Returns:\n     *     AST of the expression `(){ s; }()` with location loc.\n     */\n    private extern(D) Expression wrapAndCall(const ref Loc loc, Statement s)\n    {\n        auto tf = new TypeFunction(new Parameters(), null, 0, LINK.default_, 0);\n        auto fd = new FuncLiteralDeclaration(loc, loc, tf, TOK.reserved, null);\n        fd.fbody = s;\n        auto fe = new FuncExp(loc, fd);\n        auto ce = new CallExp(loc, fe, new Expressions());\n        return ce;\n    }\n\n    /*****************************************\n     * Create a `foreach` statement from `aggrefe/rangefe` with given\n     * `foreach` variables and body `s`.\n     *\n     * Params:\n     *     loc = The source location.\n     *     parameters = The foreach variables.\n     *     s = The `foreach` body.\n     * Returns:\n     *     `foreach (parameters; aggregate) s;` or\n     *     `foreach (parameters; lower .. upper) s;`\n     *     Where aggregate/lower, upper are as for the current StaticForeach.\n     */\n    private extern(D) Statement createForeach(const ref Loc loc, Parameters* parameters, Statement s)\n    {\n        if (aggrfe)\n        {\n            return new ForeachStatement(loc, aggrfe.op, parameters, aggrfe.aggr.syntaxCopy(), s, loc);\n        }\n        else\n        {\n            assert(rangefe && parameters.dim == 1);\n            return new ForeachRangeStatement(loc, rangefe.op, (*parameters)[0], rangefe.lwr.syntaxCopy(), rangefe.upr.syntaxCopy(), s, loc);\n        }\n    }\n\n    /*****************************************\n     * For a `static foreach` with multiple loop variables, the\n     * aggregate is lowered to an array of tuples. As D does not have\n     * built-in tuples, we need a suitable tuple type. This generates\n     * a `struct` that serves as the tuple type. This type is only\n     * used during CTFE and hence its typeinfo will not go to the\n     * object file.\n     *\n     * Params:\n     *     loc = The source location.\n     *     e = The expressions we wish to store in the tuple.\n     *     sc  = The current scope.\n     * Returns:\n     *     A struct type of the form\n     *         struct Tuple\n     *         {\n     *             typeof(AliasSeq!(e)) tuple;\n     *         }\n     */\n\n    private extern(D) TypeStruct createTupleType(const ref Loc loc, Expressions* e, Scope* sc)\n    {   // TODO: move to druntime?\n        auto sid = Identifier.generateId(\"Tuple\");\n        auto sdecl = new StructDeclaration(loc, sid, false);\n        sdecl.storage_class |= STC.static_;\n        sdecl.members = new Dsymbols();\n        auto fid = Identifier.idPool(tupleFieldName.ptr, tupleFieldName.length);\n        auto ty = new TypeTypeof(loc, new TupleExp(loc, e));\n        sdecl.members.push(new VarDeclaration(loc, ty, fid, null, 0));\n        auto r = cast(TypeStruct)sdecl.type;\n        r.vtinfo = TypeInfoStructDeclaration.create(r); // prevent typeinfo from going to object file\n        return r;\n    }\n\n    /*****************************************\n     * Create the AST for an instantiation of a suitable tuple type.\n     *\n     * Params:\n     *     loc = The source location.\n     *     type = A Tuple type, created with createTupleType.\n     *     e = The expressions we wish to store in the tuple.\n     * Returns:\n     *     An AST for the expression `Tuple(e)`.\n     */\n\n    private extern(D) Expression createTuple(const ref Loc loc, TypeStruct type, Expressions* e)\n    {   // TODO: move to druntime?\n        return new CallExp(loc, new TypeExp(loc, type), e);\n    }\n\n\n    /*****************************************\n     * Lower any aggregate that is not an array to an array using a\n     * regular foreach loop within CTFE.  If there are multiple\n     * `static foreach` loop variables, an array of tuples is\n     * generated. In thise case, the field `needExpansion` is set to\n     * true to indicate that the static foreach loop expansion will\n     * need to expand the tuples into multiple variables.\n     *\n     * For example, `static foreach (x; range) { ... }` is lowered to:\n     *\n     *     static foreach (x; {\n     *         typeof({\n     *             foreach (x; range) return x;\n     *         }())[] __res;\n     *         foreach (x; range) __res ~= x;\n     *         return __res;\n     *     }()) { ... }\n     *\n     * Finally, call `lowerArrayAggregate` to turn the produced\n     * array into an expression tuple.\n     *\n     * Params:\n     *     sc = The current scope.\n     */\n\n    private void lowerNonArrayAggregate(Scope* sc)\n    {\n        auto nvars = aggrfe ? aggrfe.parameters.dim : 1;\n        auto aloc = aggrfe ? aggrfe.aggr.loc : rangefe.lwr.loc;\n        // We need three sets of foreach loop variables because the\n        // lowering contains three foreach loops.\n        Parameters*[3] pparams = [new Parameters(), new Parameters(), new Parameters()];\n        foreach (i; 0 .. nvars)\n        {\n            foreach (params; pparams)\n            {\n                auto p = aggrfe ? (*aggrfe.parameters)[i] : rangefe.prm;\n                params.push(new Parameter(p.storageClass, p.type, p.ident, null, null));\n            }\n        }\n        Expression[2] res;\n        TypeStruct tplty = null;\n        if (nvars == 1) // only one `static foreach` variable, generate identifiers.\n        {\n            foreach (i; 0 .. 2)\n            {\n                res[i] = new IdentifierExp(aloc, (*pparams[i])[0].ident);\n            }\n        }\n        else // multiple `static foreach` variables, generate tuples.\n        {\n            foreach (i; 0 .. 2)\n            {\n                auto e = new Expressions();\n                foreach (j; 0 .. pparams[0].dim)\n                {\n                    auto p = (*pparams[i])[j];\n                    e.push(new IdentifierExp(aloc, p.ident));\n                }\n                if (!tplty)\n                {\n                    tplty = createTupleType(aloc, e, sc);\n                }\n                res[i] = createTuple(aloc, tplty, e);\n            }\n            needExpansion = true; // need to expand the tuples later\n        }\n        // generate remaining code for the new aggregate which is an\n        // array (see documentation comment).\n        if (rangefe)\n        {\n            sc = sc.startCTFE();\n            rangefe.lwr = rangefe.lwr.expressionSemantic(sc);\n            rangefe.lwr = resolveProperties(sc, rangefe.lwr);\n            rangefe.upr = rangefe.upr.expressionSemantic(sc);\n            rangefe.upr = resolveProperties(sc, rangefe.upr);\n            sc = sc.endCTFE();\n            rangefe.lwr = rangefe.lwr.optimize(WANTvalue);\n            rangefe.lwr = rangefe.lwr.ctfeInterpret();\n            rangefe.upr = rangefe.upr.optimize(WANTvalue);\n            rangefe.upr = rangefe.upr.ctfeInterpret();\n        }\n        auto s1 = new Statements();\n        auto sfe = new Statements();\n        if (tplty) sfe.push(new ExpStatement(loc, tplty.sym));\n        sfe.push(new ReturnStatement(aloc, res[0]));\n        s1.push(createForeach(aloc, pparams[0], new CompoundStatement(aloc, sfe)));\n        s1.push(new ExpStatement(aloc, new AssertExp(aloc, new IntegerExp(aloc, 0, Type.tint32))));\n        auto ety = new TypeTypeof(aloc, wrapAndCall(aloc, new CompoundStatement(aloc, s1)));\n        auto aty = ety.arrayOf();\n        auto idres = Identifier.generateId(\"__res\");\n        auto vard = new VarDeclaration(aloc, aty, idres, null);\n        auto s2 = new Statements();\n        s2.push(new ExpStatement(aloc, vard));\n        auto catass = new CatAssignExp(aloc, new IdentifierExp(aloc, idres), res[1]);\n        s2.push(createForeach(aloc, pparams[1], new ExpStatement(aloc, catass)));\n        s2.push(new ReturnStatement(aloc, new IdentifierExp(aloc, idres)));\n        auto aggr = wrapAndCall(aloc, new CompoundStatement(aloc, s2));\n        sc = sc.startCTFE();\n        aggr = aggr.expressionSemantic(sc);\n        aggr = resolveProperties(sc, aggr);\n        sc = sc.endCTFE();\n        aggr = aggr.optimize(WANTvalue);\n        aggr = aggr.ctfeInterpret();\n\n        assert(!!aggrfe ^ !!rangefe);\n        aggrfe = new ForeachStatement(loc, TOK.foreach_, pparams[2], aggr,\n                                      aggrfe ? aggrfe._body : rangefe._body,\n                                      aggrfe ? aggrfe.endloc : rangefe.endloc);\n        rangefe = null;\n        lowerArrayAggregate(sc); // finally, turn generated array into expression tuple\n    }\n\n    /*****************************************\n     * Perform `static foreach` lowerings that are necessary in order\n     * to finally expand the `static foreach` using\n     * `dmd.statementsem.makeTupleForeach`.\n     */\n    extern(D) void prepare(Scope* sc)\n    {\n        assert(sc);\n\n        if (aggrfe)\n        {\n            sc = sc.startCTFE();\n            aggrfe.aggr = aggrfe.aggr.expressionSemantic(sc);\n            sc = sc.endCTFE();\n            aggrfe.aggr = aggrfe.aggr.optimize(WANTvalue);\n            auto tab = aggrfe.aggr.type.toBasetype();\n            if (tab.ty != Ttuple)\n            {\n                aggrfe.aggr = aggrfe.aggr.ctfeInterpret();\n            }\n        }\n\n        if (aggrfe && aggrfe.aggr.type.toBasetype().ty == Terror)\n        {\n            return;\n        }\n\n        if (!ready())\n        {\n            if (aggrfe && aggrfe.aggr.type.toBasetype().ty == Tarray)\n            {\n                lowerArrayAggregate(sc);\n            }\n            else\n            {\n                lowerNonArrayAggregate(sc);\n            }\n        }\n    }\n\n    /*****************************************\n     * Returns:\n     *     `true` iff ready to call `dmd.statementsem.makeTupleForeach`.\n     */\n    extern(D) bool ready()\n    {\n        return aggrfe && aggrfe.aggr && aggrfe.aggr.type && aggrfe.aggr.type.toBasetype().ty == Ttuple;\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class DVCondition : Condition\n{\n    uint level;\n    Identifier ident;\n    Module mod;\n\n    extern (D) this(Module mod, uint level, Identifier ident)\n    {\n        super(Loc.initial);\n        this.mod = mod;\n        this.level = level;\n        this.ident = ident;\n    }\n\n    override final Condition syntaxCopy()\n    {\n        return this; // don't need to copy\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DebugCondition : DVCondition\n{\n    /**\n     * Add an user-supplied identifier to the list of global debug identifiers\n     *\n     * Can be called from either the driver or a `debug = Ident;` statement.\n     * Unlike version identifier, there isn't any reserved debug identifier\n     * so no validation takes place.\n     *\n     * Params:\n     *   ident = identifier to add\n     */\n    deprecated(\"Kept for C++ compat - Use the string overload instead\")\n    static void addGlobalIdent(const(char)* ident)\n    {\n        addGlobalIdent(ident[0 .. ident.strlen]);\n    }\n\n    /// Ditto\n    extern(D) static void addGlobalIdent(string ident)\n    {\n        // Overload necessary for string literals\n        addGlobalIdent(cast(const(char)[])ident);\n    }\n\n\n    /// Ditto\n    extern(D) static void addGlobalIdent(const(char)[] ident)\n    {\n        if (!global.debugids)\n            global.debugids = new Identifiers();\n        global.debugids.push(Identifier.idPool(ident));\n    }\n\n\n    /**\n     * Instantiate a new `DebugCondition`\n     *\n     * Params:\n     *   mod = Module this node belongs to\n     *   level = Minimum global level this condition needs to pass.\n     *           Only used if `ident` is `null`.\n     *   ident = Identifier required for this condition to pass.\n     *           If `null`, this conditiion will use an integer level.\n     */\n    extern (D) this(Module mod, uint level, Identifier ident)\n    {\n        super(mod, level, ident);\n    }\n\n    override int include(Scope* sc)\n    {\n        //printf(\"DebugCondition::include() level = %d, debuglevel = %d\\n\", level, global.params.debuglevel);\n        if (inc == 0)\n        {\n            inc = 2;\n            bool definedInModule = false;\n            if (ident)\n            {\n                if (findCondition(mod.debugids, ident))\n                {\n                    inc = 1;\n                    definedInModule = true;\n                }\n                else if (findCondition(global.debugids, ident))\n                    inc = 1;\n                else\n                {\n                    if (!mod.debugidsNot)\n                        mod.debugidsNot = new Identifiers();\n                    mod.debugidsNot.push(ident);\n                }\n            }\n            else if (level <= global.params.debuglevel || level <= mod.debuglevel)\n                inc = 1;\n            if (!definedInModule)\n                printDepsConditional(sc, this, \"depsDebug \");\n        }\n        return (inc == 1);\n    }\n\n    override DebugCondition isDebugCondition()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    override const(char)* toChars()\n    {\n        return ident ? ident.toChars() : \"debug\".ptr;\n    }\n}\n\n/**\n * Node to represent a version condition\n *\n * A version condition is of the form:\n * ---\n * version (Identifier)\n * ---\n * In user code.\n * This class also provides means to add version identifier\n * to the list of global (cross module) identifiers.\n */\nextern (C++) final class VersionCondition : DVCondition\n{\n    /**\n     * Check if a given version identifier is reserved.\n     *\n     * Params:\n     *   ident = identifier being checked\n     *\n     * Returns:\n     *   `true` if it is reserved, `false` otherwise\n     */\n    extern(D) private static bool isReserved(const(char)[] ident)\n    {\n        // This list doesn't include \"D_*\" versions, see the last return\n        switch (ident)\n        {\n            case \"DigitalMars\":\n            case \"GNU\":\n            case \"LDC\":\n            case \"SDC\":\n            case \"Windows\":\n            case \"Win32\":\n            case \"Win64\":\n            case \"linux\":\n            case \"OSX\":\n            case \"iOS\":\n            case \"TVOS\":\n            case \"WatchOS\":\n            case \"FreeBSD\":\n            case \"OpenBSD\":\n            case \"NetBSD\":\n            case \"DragonFlyBSD\":\n            case \"BSD\":\n            case \"Solaris\":\n            case \"Posix\":\n            case \"AIX\":\n            case \"Haiku\":\n            case \"SkyOS\":\n            case \"SysV3\":\n            case \"SysV4\":\n            case \"Hurd\":\n            case \"Android\":\n            case \"Emscripten\":\n            case \"PlayStation\":\n            case \"PlayStation4\":\n            case \"Cygwin\":\n            case \"MinGW\":\n            case \"FreeStanding\":\n            case \"X86\":\n            case \"X86_64\":\n            case \"ARM\":\n            case \"ARM_Thumb\":\n            case \"ARM_SoftFloat\":\n            case \"ARM_SoftFP\":\n            case \"ARM_HardFloat\":\n            case \"AArch64\":\n            case \"AsmJS\":\n            case \"Epiphany\":\n            case \"PPC\":\n            case \"PPC_SoftFloat\":\n            case \"PPC_HardFloat\":\n            case \"PPC64\":\n            case \"IA64\":\n            case \"MIPS32\":\n            case \"MIPS64\":\n            case \"MIPS_O32\":\n            case \"MIPS_N32\":\n            case \"MIPS_O64\":\n            case \"MIPS_N64\":\n            case \"MIPS_EABI\":\n            case \"MIPS_SoftFloat\":\n            case \"MIPS_HardFloat\":\n            case \"MSP430\":\n            case \"NVPTX\":\n            case \"NVPTX64\":\n            case \"RISCV32\":\n            case \"RISCV64\":\n            case \"SPARC\":\n            case \"SPARC_V8Plus\":\n            case \"SPARC_SoftFloat\":\n            case \"SPARC_HardFloat\":\n            case \"SPARC64\":\n            case \"S390\":\n            case \"S390X\":\n            case \"SystemZ\":\n            case \"HPPA\":\n            case \"HPPA64\":\n            case \"SH\":\n            case \"WebAssembly\":\n            case \"Alpha\":\n            case \"Alpha_SoftFloat\":\n            case \"Alpha_HardFloat\":\n            case \"LittleEndian\":\n            case \"BigEndian\":\n            case \"ELFv1\":\n            case \"ELFv2\":\n            case \"CRuntime_Bionic\":\n            case \"CRuntime_DigitalMars\":\n            case \"CRuntime_Glibc\":\n            case \"CRuntime_Microsoft\":\n            case \"CRuntime_Musl\":\n            case \"CRuntime_UClibc\":\n            case \"CppRuntime_Clang\":\n            case \"CppRuntime_DigitalMars\":\n            case \"CppRuntime_Gcc\":\n            case \"CppRuntime_Microsoft\":\n            case \"CppRuntime_Sun\":\n            case \"unittest\":\n            case \"assert\":\n            case \"all\":\n            case \"none\":\n                return true;\n\n            default:\n                // Anything that starts with \"D_\" is reserved\n                return (ident.length >= 2 && ident[0 .. 2] == \"D_\");\n        }\n    }\n\n    /**\n     * Raises an error if a version identifier is reserved.\n     *\n     * Called when setting a version identifier, e.g. `-version=identifier`\n     * parameter to the compiler or `version = Foo` in user code.\n     *\n     * Params:\n     *   loc = Where the identifier is set\n     *   ident = identifier being checked (ident[$] must be '\\0')\n     */\n    extern(D) static void checkReserved(const ref Loc loc, const(char)[] ident)\n    {\n        if (isReserved(ident))\n            error(loc, \"version identifier `%s` is reserved and cannot be set\",\n                  ident.ptr);\n    }\n\n    /**\n     * Add an user-supplied global identifier to the list\n     *\n     * Only called from the driver for `-version=Ident` parameters.\n     * Will raise an error if the identifier is reserved.\n     *\n     * Params:\n     *   ident = identifier to add\n     */\n    deprecated(\"Kept for C++ compat - Use the string overload instead\")\n    static void addGlobalIdent(const(char)* ident)\n    {\n        addGlobalIdent(ident[0 .. ident.strlen]);\n    }\n\n    /// Ditto\n    extern(D) static void addGlobalIdent(string ident)\n    {\n        // Overload necessary for string literals\n        addGlobalIdent(cast(const(char)[])ident);\n    }\n\n\n    /// Ditto\n    extern(D) static void addGlobalIdent(const(char)[] ident)\n    {\n        checkReserved(Loc.initial, ident);\n        addPredefinedGlobalIdent(ident);\n    }\n\n    /**\n     * Add any global identifier to the list, without checking\n     * if it's predefined\n     *\n     * Only called from the driver after platform detection,\n     * and internally.\n     *\n     * Params:\n     *   ident = identifier to add (ident[$] must be '\\0')\n     */\n    deprecated(\"Kept for C++ compat - Use the string overload instead\")\n    static void addPredefinedGlobalIdent(const(char)* ident)\n    {\n        addPredefinedGlobalIdent(ident[0 .. ident.strlen]);\n    }\n\n    /// Ditto\n    extern(D) static void addPredefinedGlobalIdent(string ident)\n    {\n        // Forward: Overload necessary for string literal\n        addPredefinedGlobalIdent(cast(const(char)[])ident);\n    }\n\n\n    /// Ditto\n    extern(D) static void addPredefinedGlobalIdent(const(char)[] ident)\n    {\n        if (!global.versionids)\n            global.versionids = new Identifiers();\n        global.versionids.push(Identifier.idPool(ident));\n    }\n\n    /**\n     * Instantiate a new `VersionCondition`\n     *\n     * Params:\n     *   mod = Module this node belongs to\n     *   level = Minimum global level this condition needs to pass.\n     *           Only used if `ident` is `null`.\n     *   ident = Identifier required for this condition to pass.\n     *           If `null`, this conditiion will use an integer level.\n     */\n    extern (D) this(Module mod, uint level, Identifier ident)\n    {\n        super(mod, level, ident);\n    }\n\n    override int include(Scope* sc)\n    {\n        //printf(\"VersionCondition::include() level = %d, versionlevel = %d\\n\", level, global.params.versionlevel);\n        //if (ident) printf(\"\\tident = '%s'\\n\", ident.toChars());\n        if (inc == 0)\n        {\n            inc = 2;\n            bool definedInModule = false;\n            if (ident)\n            {\n                if (findCondition(mod.versionids, ident))\n                {\n                    inc = 1;\n                    definedInModule = true;\n                }\n                else if (findCondition(global.versionids, ident))\n                    inc = 1;\n                else\n                {\n                    if (!mod.versionidsNot)\n                        mod.versionidsNot = new Identifiers();\n                    mod.versionidsNot.push(ident);\n                }\n            }\n            else if (level <= global.params.versionlevel || level <= mod.versionlevel)\n                inc = 1;\n            if (!definedInModule &&\n                (!ident || (!isReserved(ident.toString()) && ident != Id._unittest && ident != Id._assert)))\n            {\n                printDepsConditional(sc, this, \"depsVersion \");\n            }\n        }\n        return (inc == 1);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    override const(char)* toChars()\n    {\n        return ident ? ident.toChars() : \"version\".ptr;\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class StaticIfCondition : Condition\n{\n    Expression exp;\n\n    extern (D) this(const ref Loc loc, Expression exp)\n    {\n        super(loc);\n        this.exp = exp;\n    }\n\n    override Condition syntaxCopy()\n    {\n        return new StaticIfCondition(loc, exp.syntaxCopy());\n    }\n\n    override int include(Scope* sc)\n    {\n        // printf(\"StaticIfCondition::include(sc = %p) this=%p inc = %d\\n\", sc, this, inc);\n\n        int errorReturn()\n        {\n            if (!global.gag)\n                inc = 2; // so we don't see the error message again\n            return 0;\n        }\n\n        if (inc == 0)\n        {\n            if (!sc)\n            {\n                error(loc, \"`static if` conditional cannot be at global scope\");\n                inc = 2;\n                return 0;\n            }\n\n            sc = sc.push(sc.scopesym);\n\n            import dmd.staticcond;\n            bool errors;\n            bool result = evalStaticCondition(sc, exp, exp, errors);\n            sc.pop();\n            // Prevent repeated condition evaluation.\n            // See: fail_compilation/fail7815.d\n            if (inc != 0)\n                return (inc == 1);\n            if (errors)\n                return errorReturn();\n            if (result)\n                inc = 1;\n            else\n                inc = 2;\n        }\n        return (inc == 1);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    override const(char)* toChars()\n    {\n        return exp ? exp.toChars() : \"static if\".ptr;\n    }\n}\n\n\n/****************************************\n * Find `ident` in an array of identifiers.\n * Params:\n *      ids = array of identifiers\n *      ident = identifier to search for\n * Returns:\n *      true if found\n */\nextern (C++) bool findCondition(Identifiers* ids, Identifier ident)\n{\n    if (ids)\n    {\n        foreach (id; *ids)\n        {\n            if (id == ident)\n                return true;\n        }\n    }\n    return false;\n}\n\n// Helper for printing dependency information\nprivate void printDepsConditional(Scope* sc, DVCondition condition, const(char)[] depType)\n{\n    if (!global.params.moduleDeps || global.params.moduleDepsFile)\n        return;\n    OutBuffer* ob = global.params.moduleDeps;\n    Module imod = sc ? sc.instantiatingModule() : condition.mod;\n    if (!imod)\n        return;\n    ob.writestring(depType);\n    ob.writestring(imod.toPrettyChars());\n    ob.writestring(\" (\");\n    escapePath(ob, imod.srcfile.toChars());\n    ob.writestring(\") : \");\n    if (condition.ident)\n        ob.writestring(condition.ident.toString());\n    else\n        ob.print(condition.level);\n    ob.writeByte('\\n');\n}\n"
  },
  {
    "path": "gcc/d/dmd/cond.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/cond.h\n */\n\n#pragma once\n\n#include \"globals.h\"\n#include \"visitor.h\"\n\nclass Expression;\nclass Identifier;\nclass Module;\nstruct Scope;\nclass DebugCondition;\nclass ForeachStatement;\nclass ForeachRangeStatement;\n\nint findCondition(Strings *ids, Identifier *ident);\n\nclass Condition\n{\npublic:\n    Loc loc;\n    // 0: not computed yet\n    // 1: include\n    // 2: do not include\n    int inc;\n\n    virtual Condition *syntaxCopy() = 0;\n    virtual int include(Scope *sc) = 0;\n    virtual DebugCondition *isDebugCondition() { return NULL; }\n    virtual void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StaticForeach\n{\npublic:\n    Loc loc;\n\n    ForeachStatement *aggrfe;\n    ForeachRangeStatement *rangefe;\n\n    bool needExpansion;\n\n    StaticForeach *syntaxCopy();\n};\n\nclass DVCondition : public Condition\n{\npublic:\n    unsigned level;\n    Identifier *ident;\n    Module *mod;\n\n    Condition *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DebugCondition : public DVCondition\n{\npublic:\n    static void addGlobalIdent(const char *ident);\n\n    int include(Scope *sc);\n    DebugCondition *isDebugCondition() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass VersionCondition : public DVCondition\n{\npublic:\n    static void addGlobalIdent(const char *ident);\n    static void addPredefinedGlobalIdent(const char *ident);\n\n    int include(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StaticIfCondition : public Condition\n{\npublic:\n    Expression *exp;\n    int nest;         // limit circular dependencies\n\n    Condition *syntaxCopy();\n    int include(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n"
  },
  {
    "path": "gcc/d/dmd/constfold.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/constfold.d, _constfold.d)\n * Documentation:  https://dlang.org/phobos/dmd_constfold.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/constfold.d\n */\n\nmodule dmd.constfold;\n\nimport core.stdc.string;\nimport core.stdc.stdio;\nimport dmd.arraytypes;\nimport dmd.complex;\nimport dmd.ctfeexpr;\nimport dmd.declaration;\nimport dmd.dstruct;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.globals;\nimport dmd.mtype;\nimport dmd.root.ctfloat;\nimport dmd.root.port;\nimport dmd.root.rmem;\nimport dmd.sideeffect;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.utf;\n\nprivate enum LOG = false;\n\nprivate Expression expType(Type type, Expression e)\n{\n    if (type != e.type)\n    {\n        e = e.copy();\n        e.type = type;\n    }\n    return e;\n}\n\n/************************************\n * Returns:\n *    true if e is a constant\n */\nint isConst(Expression e)\n{\n    //printf(\"Expression::isConst(): %s\\n\", e.toChars());\n    switch (e.op)\n    {\n    case TOK.int64:\n    case TOK.float64:\n    case TOK.complex80:\n        return 1;\n    case TOK.null_:\n        return 0;\n    case TOK.symbolOffset:\n        return 2;\n    default:\n        return 0;\n    }\n    assert(0);\n}\n\n/**********************************\n * Initialize a TOK.cantExpression Expression.\n * Params:\n *      ue = where to write it\n */\nvoid cantExp(out UnionExp ue)\n{\n    emplaceExp!(CTFEExp)(&ue, TOK.cantExpression);\n}\n\n/* =============================== constFold() ============================== */\n/* The constFold() functions were redundant with the optimize() ones,\n * and so have been folded in with them.\n */\n/* ========================================================================== */\nUnionExp Neg(Type type, Expression e1)\n{\n    UnionExp ue = void;\n    Loc loc = e1.loc;\n    if (e1.type.isreal())\n    {\n        emplaceExp!(RealExp)(&ue, loc, -e1.toReal(), type);\n    }\n    else if (e1.type.isimaginary())\n    {\n        emplaceExp!(RealExp)(&ue, loc, -e1.toImaginary(), type);\n    }\n    else if (e1.type.iscomplex())\n    {\n        emplaceExp!(ComplexExp)(&ue, loc, -e1.toComplex(), type);\n    }\n    else\n    {\n        emplaceExp!(IntegerExp)(&ue, loc, -e1.toInteger(), type);\n    }\n    return ue;\n}\n\nUnionExp Com(Type type, Expression e1)\n{\n    UnionExp ue = void;\n    Loc loc = e1.loc;\n    emplaceExp!(IntegerExp)(&ue, loc, ~e1.toInteger(), type);\n    return ue;\n}\n\nUnionExp Not(Type type, Expression e1)\n{\n    UnionExp ue = void;\n    Loc loc = e1.loc;\n    emplaceExp!(IntegerExp)(&ue, loc, e1.isBool(false) ? 1 : 0, type);\n    return ue;\n}\n\nprivate UnionExp Bool(Type type, Expression e1)\n{\n    UnionExp ue = void;\n    Loc loc = e1.loc;\n    emplaceExp!(IntegerExp)(&ue, loc, e1.isBool(true) ? 1 : 0, type);\n    return ue;\n}\n\nUnionExp Add(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    static if (LOG)\n    {\n        printf(\"Add(e1 = %s, e2 = %s)\\n\", e1.toChars(), e2.toChars());\n    }\n    if (type.isreal())\n    {\n        emplaceExp!(RealExp)(&ue, loc, e1.toReal() + e2.toReal(), type);\n    }\n    else if (type.isimaginary())\n    {\n        emplaceExp!(RealExp)(&ue, loc, e1.toImaginary() + e2.toImaginary(), type);\n    }\n    else if (type.iscomplex())\n    {\n        // This rigamarole is necessary so that -0.0 doesn't get\n        // converted to +0.0 by doing an extraneous add with +0.0\n        auto c1 = complex_t(CTFloat.zero);\n        real_t r1 = CTFloat.zero;\n        real_t i1 = CTFloat.zero;\n        auto c2 = complex_t(CTFloat.zero);\n        real_t r2 = CTFloat.zero;\n        real_t i2 = CTFloat.zero;\n        auto v = complex_t(CTFloat.zero);\n        int x;\n        if (e1.type.isreal())\n        {\n            r1 = e1.toReal();\n            x = 0;\n        }\n        else if (e1.type.isimaginary())\n        {\n            i1 = e1.toImaginary();\n            x = 3;\n        }\n        else\n        {\n            c1 = e1.toComplex();\n            x = 6;\n        }\n        if (e2.type.isreal())\n        {\n            r2 = e2.toReal();\n        }\n        else if (e2.type.isimaginary())\n        {\n            i2 = e2.toImaginary();\n            x += 1;\n        }\n        else\n        {\n            c2 = e2.toComplex();\n            x += 2;\n        }\n        switch (x)\n        {\n        case 0 + 0:\n            v = complex_t(r1 + r2);\n            break;\n        case 0 + 1:\n            v = complex_t(r1, i2);\n            break;\n        case 0 + 2:\n            v = complex_t(r1 + creall(c2), cimagl(c2));\n            break;\n        case 3 + 0:\n            v = complex_t(r2, i1);\n            break;\n        case 3 + 1:\n            v = complex_t(CTFloat.zero, i1 + i2);\n            break;\n        case 3 + 2:\n            v = complex_t(creall(c2), i1 + cimagl(c2));\n            break;\n        case 6 + 0:\n            v = complex_t(creall(c1) + r2, cimagl(c2));\n            break;\n        case 6 + 1:\n            v = complex_t(creall(c1), cimagl(c1) + i2);\n            break;\n        case 6 + 2:\n            v = c1 + c2;\n            break;\n        default:\n            assert(0);\n        }\n        emplaceExp!(ComplexExp)(&ue, loc, v, type);\n    }\n    else if (e1.op == TOK.symbolOffset)\n    {\n        SymOffExp soe = cast(SymOffExp)e1;\n        emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset + e2.toInteger());\n        ue.exp().type = type;\n    }\n    else if (e2.op == TOK.symbolOffset)\n    {\n        SymOffExp soe = cast(SymOffExp)e2;\n        emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset + e1.toInteger());\n        ue.exp().type = type;\n    }\n    else\n        emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() + e2.toInteger(), type);\n    return ue;\n}\n\nUnionExp Min(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    if (type.isreal())\n    {\n        emplaceExp!(RealExp)(&ue, loc, e1.toReal() - e2.toReal(), type);\n    }\n    else if (type.isimaginary())\n    {\n        emplaceExp!(RealExp)(&ue, loc, e1.toImaginary() - e2.toImaginary(), type);\n    }\n    else if (type.iscomplex())\n    {\n        // This rigamarole is necessary so that -0.0 doesn't get\n        // converted to +0.0 by doing an extraneous add with +0.0\n        auto c1 = complex_t(CTFloat.zero);\n        real_t r1 = CTFloat.zero;\n        real_t i1 = CTFloat.zero;\n        auto c2 = complex_t(CTFloat.zero);\n        real_t r2 = CTFloat.zero;\n        real_t i2 = CTFloat.zero;\n        auto v = complex_t(CTFloat.zero);\n        int x;\n        if (e1.type.isreal())\n        {\n            r1 = e1.toReal();\n            x = 0;\n        }\n        else if (e1.type.isimaginary())\n        {\n            i1 = e1.toImaginary();\n            x = 3;\n        }\n        else\n        {\n            c1 = e1.toComplex();\n            x = 6;\n        }\n        if (e2.type.isreal())\n        {\n            r2 = e2.toReal();\n        }\n        else if (e2.type.isimaginary())\n        {\n            i2 = e2.toImaginary();\n            x += 1;\n        }\n        else\n        {\n            c2 = e2.toComplex();\n            x += 2;\n        }\n        switch (x)\n        {\n        case 0 + 0:\n            v = complex_t(r1 - r2);\n            break;\n        case 0 + 1:\n            v = complex_t(r1, -i2);\n            break;\n        case 0 + 2:\n            v = complex_t(r1 - creall(c2), -cimagl(c2));\n            break;\n        case 3 + 0:\n            v = complex_t(-r2, i1);\n            break;\n        case 3 + 1:\n            v = complex_t(CTFloat.zero, i1 - i2);\n            break;\n        case 3 + 2:\n            v = complex_t(-creall(c2), i1 - cimagl(c2));\n            break;\n        case 6 + 0:\n            v = complex_t(creall(c1) - r2, cimagl(c1));\n            break;\n        case 6 + 1:\n            v = complex_t(creall(c1), cimagl(c1) - i2);\n            break;\n        case 6 + 2:\n            v = c1 - c2;\n            break;\n        default:\n            assert(0);\n        }\n        emplaceExp!(ComplexExp)(&ue, loc, v, type);\n    }\n    else if (e1.op == TOK.symbolOffset)\n    {\n        SymOffExp soe = cast(SymOffExp)e1;\n        emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset - e2.toInteger());\n        ue.exp().type = type;\n    }\n    else\n    {\n        emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() - e2.toInteger(), type);\n    }\n    return ue;\n}\n\nUnionExp Mul(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    if (type.isfloating())\n    {\n        auto c = complex_t(CTFloat.zero);\n        real_t r = CTFloat.zero;\n        if (e1.type.isreal())\n        {\n            r = e1.toReal();\n            c = e2.toComplex();\n            c = complex_t(r * creall(c), r * cimagl(c));\n        }\n        else if (e1.type.isimaginary())\n        {\n            r = e1.toImaginary();\n            c = e2.toComplex();\n            c = complex_t(-r * cimagl(c), r * creall(c));\n        }\n        else if (e2.type.isreal())\n        {\n            r = e2.toReal();\n            c = e1.toComplex();\n            c = complex_t(r * creall(c), r * cimagl(c));\n        }\n        else if (e2.type.isimaginary())\n        {\n            r = e2.toImaginary();\n            c = e1.toComplex();\n            c = complex_t(-r * cimagl(c), r * creall(c));\n        }\n        else\n            c = e1.toComplex() * e2.toComplex();\n        if (type.isreal())\n            emplaceExp!(RealExp)(&ue, loc, creall(c), type);\n        else if (type.isimaginary())\n            emplaceExp!(RealExp)(&ue, loc, cimagl(c), type);\n        else if (type.iscomplex())\n            emplaceExp!(ComplexExp)(&ue, loc, c, type);\n        else\n            assert(0);\n    }\n    else\n    {\n        emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() * e2.toInteger(), type);\n    }\n    return ue;\n}\n\nUnionExp Div(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    if (type.isfloating())\n    {\n        auto c = complex_t(CTFloat.zero);\n        if (e2.type.isreal())\n        {\n            if (e1.type.isreal())\n            {\n                emplaceExp!(RealExp)(&ue, loc, e1.toReal() / e2.toReal(), type);\n                return ue;\n            }\n            const r = e2.toReal();\n            c = e1.toComplex();\n            c = complex_t(creall(c) / r, cimagl(c) / r);\n        }\n        else if (e2.type.isimaginary())\n        {\n            const r = e2.toImaginary();\n            c = e1.toComplex();\n            c = complex_t(cimagl(c) / r, -creall(c) / r);\n        }\n        else\n        {\n            c = e1.toComplex() / e2.toComplex();\n        }\n\n        if (type.isreal())\n            emplaceExp!(RealExp)(&ue, loc, creall(c), type);\n        else if (type.isimaginary())\n            emplaceExp!(RealExp)(&ue, loc, cimagl(c), type);\n        else if (type.iscomplex())\n            emplaceExp!(ComplexExp)(&ue, loc, c, type);\n        else\n            assert(0);\n    }\n    else\n    {\n        sinteger_t n1;\n        sinteger_t n2;\n        sinteger_t n;\n        n1 = e1.toInteger();\n        n2 = e2.toInteger();\n        if (n2 == 0)\n        {\n            e2.error(\"divide by 0\");\n            emplaceExp!(ErrorExp)(&ue);\n            return ue;\n        }\n        if (n2 == -1 && !type.isunsigned())\n        {\n            // Check for int.min / -1\n            if (n1 == 0xFFFFFFFF80000000UL && type.toBasetype().ty != Tint64)\n            {\n                e2.error(\"integer overflow: `int.min / -1`\");\n                emplaceExp!(ErrorExp)(&ue);\n                return ue;\n            }\n            else if (n1 == 0x8000000000000000L) // long.min / -1\n            {\n                e2.error(\"integer overflow: `long.min / -1L`\");\n                emplaceExp!(ErrorExp)(&ue);\n                return ue;\n            }\n        }\n        if (e1.type.isunsigned() || e2.type.isunsigned())\n            n = (cast(dinteger_t)n1) / (cast(dinteger_t)n2);\n        else\n            n = n1 / n2;\n        emplaceExp!(IntegerExp)(&ue, loc, n, type);\n    }\n    return ue;\n}\n\nUnionExp Mod(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    if (type.isfloating())\n    {\n        auto c = complex_t(CTFloat.zero);\n        if (e2.type.isreal())\n        {\n            const r2 = e2.toReal();\n            c = complex_t(e1.toReal() % r2, e1.toImaginary() % r2);\n        }\n        else if (e2.type.isimaginary())\n        {\n            const i2 = e2.toImaginary();\n            c = complex_t(e1.toReal() % i2, e1.toImaginary() % i2);\n        }\n        else\n            assert(0);\n        if (type.isreal())\n            emplaceExp!(RealExp)(&ue, loc, creall(c), type);\n        else if (type.isimaginary())\n            emplaceExp!(RealExp)(&ue, loc, cimagl(c), type);\n        else if (type.iscomplex())\n            emplaceExp!(ComplexExp)(&ue, loc, c, type);\n        else\n            assert(0);\n    }\n    else\n    {\n        sinteger_t n1;\n        sinteger_t n2;\n        sinteger_t n;\n        n1 = e1.toInteger();\n        n2 = e2.toInteger();\n        if (n2 == 0)\n        {\n            e2.error(\"divide by 0\");\n            emplaceExp!(ErrorExp)(&ue);\n            return ue;\n        }\n        if (n2 == -1 && !type.isunsigned())\n        {\n            // Check for int.min % -1\n            if (n1 == 0xFFFFFFFF80000000UL && type.toBasetype().ty != Tint64)\n            {\n                e2.error(\"integer overflow: `int.min %% -1`\");\n                emplaceExp!(ErrorExp)(&ue);\n                return ue;\n            }\n            else if (n1 == 0x8000000000000000L) // long.min % -1\n            {\n                e2.error(\"integer overflow: `long.min %% -1L`\");\n                emplaceExp!(ErrorExp)(&ue);\n                return ue;\n            }\n        }\n        if (e1.type.isunsigned() || e2.type.isunsigned())\n            n = (cast(dinteger_t)n1) % (cast(dinteger_t)n2);\n        else\n            n = n1 % n2;\n        emplaceExp!(IntegerExp)(&ue, loc, n, type);\n    }\n    return ue;\n}\n\nUnionExp Pow(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    //printf(\"Pow()\\n\");\n    UnionExp ue;\n    // Handle integer power operations.\n    if (e2.type.isintegral())\n    {\n        dinteger_t n = e2.toInteger();\n        bool neg;\n        if (!e2.type.isunsigned() && cast(sinteger_t)n < 0)\n        {\n            if (e1.type.isintegral())\n            {\n                cantExp(ue);\n                return ue;\n            }\n            // Don't worry about overflow, from now on n is unsigned.\n            neg = true;\n            n = -n;\n        }\n        else\n            neg = false;\n        UnionExp ur, uv;\n        if (e1.type.iscomplex())\n        {\n            emplaceExp!(ComplexExp)(&ur, loc, e1.toComplex(), e1.type);\n            emplaceExp!(ComplexExp)(&uv, loc, complex_t(CTFloat.one), e1.type);\n        }\n        else if (e1.type.isfloating())\n        {\n            emplaceExp!(RealExp)(&ur, loc, e1.toReal(), e1.type);\n            emplaceExp!(RealExp)(&uv, loc, CTFloat.one, e1.type);\n        }\n        else\n        {\n            emplaceExp!(IntegerExp)(&ur, loc, e1.toInteger(), e1.type);\n            emplaceExp!(IntegerExp)(&uv, loc, 1, e1.type);\n        }\n        Expression r = ur.exp();\n        Expression v = uv.exp();\n        while (n != 0)\n        {\n            if (n & 1)\n            {\n                // v = v * r;\n                uv = Mul(loc, v.type, v, r);\n            }\n            n >>= 1;\n            // r = r * r\n            ur = Mul(loc, r.type, r, r);\n        }\n        if (neg)\n        {\n            // ue = 1.0 / v\n            UnionExp one;\n            emplaceExp!(RealExp)(&one, loc, CTFloat.one, v.type);\n            uv = Div(loc, v.type, one.exp(), v);\n        }\n        if (type.iscomplex())\n            emplaceExp!(ComplexExp)(&ue, loc, v.toComplex(), type);\n        else if (type.isintegral())\n            emplaceExp!(IntegerExp)(&ue, loc, v.toInteger(), type);\n        else\n            emplaceExp!(RealExp)(&ue, loc, v.toReal(), type);\n    }\n    else if (e2.type.isfloating())\n    {\n        // x ^^ y for x < 0 and y not an integer is not defined; so set result as NaN\n        if (e1.toReal() < CTFloat.zero)\n        {\n            emplaceExp!(RealExp)(&ue, loc, Target.RealProperties.nan, type);\n        }\n        else\n            cantExp(ue);\n    }\n    else\n        cantExp(ue);\n    return ue;\n}\n\nUnionExp Shl(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() << e2.toInteger(), type);\n    return ue;\n}\n\nUnionExp Shr(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    dinteger_t value = e1.toInteger();\n    dinteger_t dcount = e2.toInteger();\n    assert(dcount <= 0xFFFFFFFF);\n    uint count = cast(uint)dcount;\n    switch (e1.type.toBasetype().ty)\n    {\n    case Tint8:\n        value = cast(d_int8)value >> count;\n        break;\n    case Tuns8:\n    case Tchar:\n        value = cast(d_uns8)value >> count;\n        break;\n    case Tint16:\n        value = cast(d_int16)value >> count;\n        break;\n    case Tuns16:\n    case Twchar:\n        value = cast(d_uns16)value >> count;\n        break;\n    case Tint32:\n        value = cast(d_int32)value >> count;\n        break;\n    case Tuns32:\n    case Tdchar:\n        value = cast(d_uns32)value >> count;\n        break;\n    case Tint64:\n        value = cast(d_int64)value >> count;\n        break;\n    case Tuns64:\n        value = cast(d_uns64)value >> count;\n        break;\n    case Terror:\n        emplaceExp!(ErrorExp)(&ue);\n        return ue;\n    default:\n        assert(0);\n    }\n    emplaceExp!(IntegerExp)(&ue, loc, value, type);\n    return ue;\n}\n\nUnionExp Ushr(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    dinteger_t value = e1.toInteger();\n    dinteger_t dcount = e2.toInteger();\n    assert(dcount <= 0xFFFFFFFF);\n    uint count = cast(uint)dcount;\n    switch (e1.type.toBasetype().ty)\n    {\n    case Tint8:\n    case Tuns8:\n    case Tchar:\n        // Possible only with >>>=. >>> always gets promoted to int.\n        value = (value & 0xFF) >> count;\n        break;\n    case Tint16:\n    case Tuns16:\n    case Twchar:\n        // Possible only with >>>=. >>> always gets promoted to int.\n        value = (value & 0xFFFF) >> count;\n        break;\n    case Tint32:\n    case Tuns32:\n    case Tdchar:\n        value = (value & 0xFFFFFFFF) >> count;\n        break;\n    case Tint64:\n    case Tuns64:\n        value = cast(d_uns64)value >> count;\n        break;\n    case Terror:\n        emplaceExp!(ErrorExp)(&ue);\n        return ue;\n    default:\n        assert(0);\n    }\n    emplaceExp!(IntegerExp)(&ue, loc, value, type);\n    return ue;\n}\n\nUnionExp And(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() & e2.toInteger(), type);\n    return ue;\n}\n\nUnionExp Or(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() | e2.toInteger(), type);\n    return ue;\n}\n\nUnionExp Xor(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    //printf(\"Xor(linnum = %d, e1 = %s, e2 = %s)\\n\", loc.linnum, e1.toChars(), e2.toChars());\n    UnionExp ue = void;\n    emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() ^ e2.toInteger(), type);\n    return ue;\n}\n\n/* Also returns TOK.cantExpression if cannot be computed.\n */\nUnionExp Equal(TOK op, const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    int cmp = 0;\n    real_t r1 = CTFloat.zero;\n    real_t r2 = CTFloat.zero;\n    //printf(\"Equal(e1 = %s, e2 = %s)\\n\", e1.toChars(), e2.toChars());\n    assert(op == TOK.equal || op == TOK.notEqual);\n    if (e1.op == TOK.null_)\n    {\n        if (e2.op == TOK.null_)\n            cmp = 1;\n        else if (e2.op == TOK.string_)\n        {\n            StringExp es2 = cast(StringExp)e2;\n            cmp = (0 == es2.len);\n        }\n        else if (e2.op == TOK.arrayLiteral)\n        {\n            ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2;\n            cmp = !es2.elements || (0 == es2.elements.dim);\n        }\n        else\n        {\n            cantExp(ue);\n            return ue;\n        }\n    }\n    else if (e2.op == TOK.null_)\n    {\n        if (e1.op == TOK.string_)\n        {\n            StringExp es1 = cast(StringExp)e1;\n            cmp = (0 == es1.len);\n        }\n        else if (e1.op == TOK.arrayLiteral)\n        {\n            ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1;\n            cmp = !es1.elements || (0 == es1.elements.dim);\n        }\n        else\n        {\n            cantExp(ue);\n            return ue;\n        }\n    }\n    else if (e1.op == TOK.string_ && e2.op == TOK.string_)\n    {\n        StringExp es1 = cast(StringExp)e1;\n        StringExp es2 = cast(StringExp)e2;\n        if (es1.sz != es2.sz)\n        {\n            assert(global.errors);\n            cantExp(ue);\n            return ue;\n        }\n        if (es1.len == es2.len && memcmp(es1.string, es2.string, es1.sz * es1.len) == 0)\n            cmp = 1;\n        else\n            cmp = 0;\n    }\n    else if (e1.op == TOK.arrayLiteral && e2.op == TOK.arrayLiteral)\n    {\n        ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1;\n        ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2;\n        if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))\n            cmp = 1; // both arrays are empty\n        else if (!es1.elements || !es2.elements)\n            cmp = 0;\n        else if (es1.elements.dim != es2.elements.dim)\n            cmp = 0;\n        else\n        {\n            for (size_t i = 0; i < es1.elements.dim; i++)\n            {\n                auto ee1 = es1.getElement(i);\n                auto ee2 = es2.getElement(i);\n                ue = Equal(TOK.equal, loc, Type.tint32, ee1, ee2);\n                if (CTFEExp.isCantExp(ue.exp()))\n                    return ue;\n                cmp = cast(int)ue.exp().toInteger();\n                if (cmp == 0)\n                    break;\n            }\n        }\n    }\n    else if (e1.op == TOK.arrayLiteral && e2.op == TOK.string_)\n    {\n        // Swap operands and use common code\n        Expression etmp = e1;\n        e1 = e2;\n        e2 = etmp;\n        goto Lsa;\n    }\n    else if (e1.op == TOK.string_ && e2.op == TOK.arrayLiteral)\n    {\n    Lsa:\n        StringExp es1 = cast(StringExp)e1;\n        ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2;\n        size_t dim1 = es1.len;\n        size_t dim2 = es2.elements ? es2.elements.dim : 0;\n        if (dim1 != dim2)\n            cmp = 0;\n        else\n        {\n            cmp = 1; // if dim1 winds up being 0\n            for (size_t i = 0; i < dim1; i++)\n            {\n                uinteger_t c = es1.charAt(i);\n                auto ee2 = es2.getElement(i);\n                if (ee2.isConst() != 1)\n                {\n                    cantExp(ue);\n                    return ue;\n                }\n                cmp = (c == ee2.toInteger());\n                if (cmp == 0)\n                    break;\n            }\n        }\n    }\n    else if (e1.op == TOK.structLiteral && e2.op == TOK.structLiteral)\n    {\n        StructLiteralExp es1 = cast(StructLiteralExp)e1;\n        StructLiteralExp es2 = cast(StructLiteralExp)e2;\n        if (es1.sd != es2.sd)\n            cmp = 0;\n        else if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))\n            cmp = 1; // both arrays are empty\n        else if (!es1.elements || !es2.elements)\n            cmp = 0;\n        else if (es1.elements.dim != es2.elements.dim)\n            cmp = 0;\n        else\n        {\n            cmp = 1;\n            for (size_t i = 0; i < es1.elements.dim; i++)\n            {\n                Expression ee1 = (*es1.elements)[i];\n                Expression ee2 = (*es2.elements)[i];\n                if (ee1 == ee2)\n                    continue;\n                if (!ee1 || !ee2)\n                {\n                    cmp = 0;\n                    break;\n                }\n                ue = Equal(TOK.equal, loc, Type.tint32, ee1, ee2);\n                if (ue.exp().op == TOK.cantExpression)\n                    return ue;\n                cmp = cast(int)ue.exp().toInteger();\n                if (cmp == 0)\n                    break;\n            }\n        }\n    }\n    else if (e1.isConst() != 1 || e2.isConst() != 1)\n    {\n        cantExp(ue);\n        return ue;\n    }\n    else if (e1.type.isreal())\n    {\n        r1 = e1.toReal();\n        r2 = e2.toReal();\n        goto L1;\n    }\n    else if (e1.type.isimaginary())\n    {\n        r1 = e1.toImaginary();\n        r2 = e2.toImaginary();\n    L1:\n        if (CTFloat.isNaN(r1) || CTFloat.isNaN(r2)) // if unordered\n        {\n            cmp = 0;\n        }\n        else\n        {\n            cmp = (r1 == r2);\n        }\n    }\n    else if (e1.type.iscomplex())\n    {\n        cmp = e1.toComplex() == e2.toComplex();\n    }\n    else if (e1.type.isintegral() || e1.type.toBasetype().ty == Tpointer)\n    {\n        cmp = (e1.toInteger() == e2.toInteger());\n    }\n    else\n    {\n        cantExp(ue);\n        return ue;\n    }\n    if (op == TOK.notEqual)\n        cmp ^= 1;\n    emplaceExp!(IntegerExp)(&ue, loc, cmp, type);\n    return ue;\n}\n\nUnionExp Identity(TOK op, const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    int cmp;\n    if (e1.op == TOK.null_)\n    {\n        cmp = (e2.op == TOK.null_);\n    }\n    else if (e2.op == TOK.null_)\n    {\n        cmp = 0;\n    }\n    else if (e1.op == TOK.symbolOffset && e2.op == TOK.symbolOffset)\n    {\n        SymOffExp es1 = cast(SymOffExp)e1;\n        SymOffExp es2 = cast(SymOffExp)e2;\n        cmp = (es1.var == es2.var && es1.offset == es2.offset);\n    }\n    else\n    {\n        if (e1.type.isreal())\n        {\n            cmp = RealEquals(e1.toReal(), e2.toReal());\n        }\n        else if (e1.type.isimaginary())\n        {\n            cmp = RealEquals(e1.toImaginary(), e2.toImaginary());\n        }\n        else if (e1.type.iscomplex())\n        {\n            complex_t v1 = e1.toComplex();\n            complex_t v2 = e2.toComplex();\n            cmp = RealEquals(creall(v1), creall(v2)) && RealEquals(cimagl(v1), cimagl(v1));\n        }\n        else\n        {\n            ue = Equal((op == TOK.identity) ? TOK.equal : TOK.notEqual, loc, type, e1, e2);\n            return ue;\n        }\n    }\n    if (op == TOK.notIdentity)\n        cmp ^= 1;\n    emplaceExp!(IntegerExp)(&ue, loc, cmp, type);\n    return ue;\n}\n\nUnionExp Cmp(TOK op, const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    dinteger_t n;\n    real_t r1 = CTFloat.zero;\n    real_t r2 = CTFloat.zero;\n    //printf(\"Cmp(e1 = %s, e2 = %s)\\n\", e1.toChars(), e2.toChars());\n    if (e1.op == TOK.string_ && e2.op == TOK.string_)\n    {\n        StringExp es1 = cast(StringExp)e1;\n        StringExp es2 = cast(StringExp)e2;\n        size_t sz = es1.sz;\n        assert(sz == es2.sz);\n        size_t len = es1.len;\n        if (es2.len < len)\n            len = es2.len;\n        int rawCmp = memcmp(es1.string, es2.string, sz * len);\n        if (rawCmp == 0)\n            rawCmp = cast(int)(es1.len - es2.len);\n        n = specificCmp(op, rawCmp);\n    }\n    else if (e1.isConst() != 1 || e2.isConst() != 1)\n    {\n        cantExp(ue);\n        return ue;\n    }\n    else if (e1.type.isreal())\n    {\n        r1 = e1.toReal();\n        r2 = e2.toReal();\n        goto L1;\n    }\n    else if (e1.type.isimaginary())\n    {\n        r1 = e1.toImaginary();\n        r2 = e2.toImaginary();\n    L1:\n        n = realCmp(op, r1, r2);\n    }\n    else if (e1.type.iscomplex())\n    {\n        assert(0);\n    }\n    else\n    {\n        sinteger_t n1;\n        sinteger_t n2;\n        n1 = e1.toInteger();\n        n2 = e2.toInteger();\n        if (e1.type.isunsigned() || e2.type.isunsigned())\n            n = intUnsignedCmp(op, n1, n2);\n        else\n            n = intSignedCmp(op, n1, n2);\n    }\n    emplaceExp!(IntegerExp)(&ue, loc, n, type);\n    return ue;\n}\n\n/* Also returns TOK.cantExpression if cannot be computed.\n *  to: type to cast to\n *  type: type to paint the result\n */\nUnionExp Cast(const ref Loc loc, Type type, Type to, Expression e1)\n{\n    UnionExp ue = void;\n    Type tb = to.toBasetype();\n    Type typeb = type.toBasetype();\n    //printf(\"Cast(type = %s, to = %s, e1 = %s)\\n\", type.toChars(), to.toChars(), e1.toChars());\n    //printf(\"\\te1.type = %s\\n\", e1.type.toChars());\n    if (e1.type.equals(type) && type.equals(to))\n    {\n        emplaceExp!(UnionExp)(&ue, e1);\n        return ue;\n    }\n    if (e1.op == TOK.vector && (cast(TypeVector)e1.type).basetype.equals(type) && type.equals(to))\n    {\n        Expression ex = (cast(VectorExp)e1).e1;\n        emplaceExp!(UnionExp)(&ue, ex);\n        return ue;\n    }\n    if (e1.type.implicitConvTo(to) >= MATCH.constant || to.implicitConvTo(e1.type) >= MATCH.constant)\n    {\n        goto L1;\n    }\n    // Allow covariant converions of delegates\n    // (Perhaps implicit conversion from pure to impure should be a MATCH.constant,\n    // then we wouldn't need this extra check.)\n    if (e1.type.toBasetype().ty == Tdelegate && e1.type.implicitConvTo(to) == MATCH.convert)\n    {\n        goto L1;\n    }\n    /* Allow casting from one string type to another\n     */\n    if (e1.op == TOK.string_)\n    {\n        if (tb.ty == Tarray && typeb.ty == Tarray && tb.nextOf().size() == typeb.nextOf().size())\n        {\n            goto L1;\n        }\n    }\n    if (e1.op == TOK.arrayLiteral && typeb == tb)\n    {\n    L1:\n        Expression ex = expType(to, e1);\n        emplaceExp!(UnionExp)(&ue, ex);\n        return ue;\n    }\n    if (e1.isConst() != 1)\n    {\n        cantExp(ue);\n    }\n    else if (tb.ty == Tbool)\n    {\n        emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() != 0, type);\n    }\n    else if (type.isintegral())\n    {\n        if (e1.type.isfloating())\n        {\n            dinteger_t result;\n            real_t r = e1.toReal();\n            switch (typeb.ty)\n            {\n            case Tint8:\n                result = cast(d_int8)cast(sinteger_t)r;\n                break;\n            case Tchar:\n            case Tuns8:\n                result = cast(d_uns8)cast(dinteger_t)r;\n                break;\n            case Tint16:\n                result = cast(d_int16)cast(sinteger_t)r;\n                break;\n            case Twchar:\n            case Tuns16:\n                result = cast(d_uns16)cast(dinteger_t)r;\n                break;\n            case Tint32:\n                result = cast(d_int32)r;\n                break;\n            case Tdchar:\n            case Tuns32:\n                result = cast(d_uns32)r;\n                break;\n            case Tint64:\n                result = cast(d_int64)r;\n                break;\n            case Tuns64:\n                result = cast(d_uns64)r;\n                break;\n            default:\n                assert(0);\n            }\n            emplaceExp!(IntegerExp)(&ue, loc, result, type);\n        }\n        else if (type.isunsigned())\n            emplaceExp!(IntegerExp)(&ue, loc, e1.toUInteger(), type);\n        else\n            emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger(), type);\n    }\n    else if (tb.isreal())\n    {\n        real_t value = e1.toReal();\n        emplaceExp!(RealExp)(&ue, loc, value, type);\n    }\n    else if (tb.isimaginary())\n    {\n        real_t value = e1.toImaginary();\n        emplaceExp!(RealExp)(&ue, loc, value, type);\n    }\n    else if (tb.iscomplex())\n    {\n        complex_t value = e1.toComplex();\n        emplaceExp!(ComplexExp)(&ue, loc, value, type);\n    }\n    else if (tb.isscalar())\n    {\n        emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger(), type);\n    }\n    else if (tb.ty == Tvoid)\n    {\n        cantExp(ue);\n    }\n    else if (tb.ty == Tstruct && e1.op == TOK.int64)\n    {\n        // Struct = 0;\n        StructDeclaration sd = tb.toDsymbol(null).isStructDeclaration();\n        assert(sd);\n        auto elements = new Expressions();\n        for (size_t i = 0; i < sd.fields.dim; i++)\n        {\n            VarDeclaration v = sd.fields[i];\n            UnionExp zero;\n            emplaceExp!(IntegerExp)(&zero, 0);\n            ue = Cast(loc, v.type, v.type, zero.exp());\n            if (ue.exp().op == TOK.cantExpression)\n                return ue;\n            elements.push(ue.exp().copy());\n        }\n        emplaceExp!(StructLiteralExp)(&ue, loc, sd, elements);\n        ue.exp().type = type;\n    }\n    else\n    {\n        if (type != Type.terror)\n        {\n            // have to change to Internal Compiler Error\n            // all invalid casts should be handled already in Expression::castTo().\n            error(loc, \"cannot cast `%s` to `%s`\", e1.type.toChars(), type.toChars());\n        }\n        emplaceExp!(ErrorExp)(&ue);\n    }\n    return ue;\n}\n\nUnionExp ArrayLength(Type type, Expression e1)\n{\n    UnionExp ue = void;\n    Loc loc = e1.loc;\n    if (e1.op == TOK.string_)\n    {\n        StringExp es1 = cast(StringExp)e1;\n        emplaceExp!(IntegerExp)(&ue, loc, es1.len, type);\n    }\n    else if (e1.op == TOK.arrayLiteral)\n    {\n        ArrayLiteralExp ale = cast(ArrayLiteralExp)e1;\n        size_t dim = ale.elements ? ale.elements.dim : 0;\n        emplaceExp!(IntegerExp)(&ue, loc, dim, type);\n    }\n    else if (e1.op == TOK.assocArrayLiteral)\n    {\n        AssocArrayLiteralExp ale = cast(AssocArrayLiteralExp)e1;\n        size_t dim = ale.keys.dim;\n        emplaceExp!(IntegerExp)(&ue, loc, dim, type);\n    }\n    else if (e1.type.toBasetype().ty == Tsarray)\n    {\n        Expression e = (cast(TypeSArray)e1.type.toBasetype()).dim;\n        emplaceExp!(UnionExp)(&ue, e);\n    }\n    else\n        cantExp(ue);\n    return ue;\n}\n\n/* Also return TOK.cantExpression if this fails\n */\nUnionExp Index(Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    Loc loc = e1.loc;\n    //printf(\"Index(e1 = %s, e2 = %s)\\n\", e1.toChars(), e2.toChars());\n    assert(e1.type);\n    if (e1.op == TOK.string_ && e2.op == TOK.int64)\n    {\n        StringExp es1 = cast(StringExp)e1;\n        uinteger_t i = e2.toInteger();\n        if (i >= es1.len)\n        {\n            e1.error(\"string index %llu is out of bounds `[0 .. %llu]`\", i, cast(ulong)es1.len);\n            emplaceExp!(ErrorExp)(&ue);\n        }\n        else\n        {\n            emplaceExp!(IntegerExp)(&ue, loc, es1.charAt(i), type);\n        }\n    }\n    else if (e1.type.toBasetype().ty == Tsarray && e2.op == TOK.int64)\n    {\n        TypeSArray tsa = cast(TypeSArray)e1.type.toBasetype();\n        uinteger_t length = tsa.dim.toInteger();\n        uinteger_t i = e2.toInteger();\n        if (i >= length)\n        {\n            e1.error(\"array index %llu is out of bounds `%s[0 .. %llu]`\", i, e1.toChars(), length);\n            emplaceExp!(ErrorExp)(&ue);\n        }\n        else if (e1.op == TOK.arrayLiteral)\n        {\n            ArrayLiteralExp ale = cast(ArrayLiteralExp)e1;\n            auto e = ale.getElement(cast(size_t)i);\n            e.type = type;\n            e.loc = loc;\n            if (hasSideEffect(e))\n                cantExp(ue);\n            else\n                emplaceExp!(UnionExp)(&ue, e);\n        }\n        else\n            cantExp(ue);\n    }\n    else if (e1.type.toBasetype().ty == Tarray && e2.op == TOK.int64)\n    {\n        uinteger_t i = e2.toInteger();\n        if (e1.op == TOK.arrayLiteral)\n        {\n            ArrayLiteralExp ale = cast(ArrayLiteralExp)e1;\n            if (i >= ale.elements.dim)\n            {\n                e1.error(\"array index %llu is out of bounds `%s[0 .. %u]`\", i, e1.toChars(), ale.elements.dim);\n                emplaceExp!(ErrorExp)(&ue);\n            }\n            else\n            {\n                auto e = ale.getElement(cast(size_t)i);\n                e.type = type;\n                e.loc = loc;\n                if (hasSideEffect(e))\n                    cantExp(ue);\n                else\n                    emplaceExp!(UnionExp)(&ue, e);\n            }\n        }\n        else\n            cantExp(ue);\n    }\n    else if (e1.op == TOK.assocArrayLiteral)\n    {\n        AssocArrayLiteralExp ae = cast(AssocArrayLiteralExp)e1;\n        /* Search the keys backwards, in case there are duplicate keys\n         */\n        for (size_t i = ae.keys.dim; i;)\n        {\n            i--;\n            Expression ekey = (*ae.keys)[i];\n            ue = Equal(TOK.equal, loc, Type.tbool, ekey, e2);\n            if (CTFEExp.isCantExp(ue.exp()))\n                return ue;\n            if (ue.exp().isBool(true))\n            {\n                Expression e = (*ae.values)[i];\n                e.type = type;\n                e.loc = loc;\n                if (hasSideEffect(e))\n                    cantExp(ue);\n                else\n                    emplaceExp!(UnionExp)(&ue, e);\n                return ue;\n            }\n        }\n        cantExp(ue);\n    }\n    else\n        cantExp(ue);\n    return ue;\n}\n\n/* Also return TOK.cantExpression if this fails\n */\nUnionExp Slice(Type type, Expression e1, Expression lwr, Expression upr)\n{\n    UnionExp ue = void;\n    Loc loc = e1.loc;\n    static if (LOG)\n    {\n        printf(\"Slice()\\n\");\n        if (lwr)\n        {\n            printf(\"\\te1 = %s\\n\", e1.toChars());\n            printf(\"\\tlwr = %s\\n\", lwr.toChars());\n            printf(\"\\tupr = %s\\n\", upr.toChars());\n        }\n    }\n\n    static bool sliceBoundsCheck(uinteger_t lwr, uinteger_t upr, uinteger_t newlwr, uinteger_t newupr) pure\n    {\n        assert(lwr <= upr);\n        return !(newlwr <= newupr &&\n                 lwr <= newlwr &&\n                 newupr <= upr);\n    }\n\n    if (e1.op == TOK.string_ && lwr.op == TOK.int64 && upr.op == TOK.int64)\n    {\n        StringExp es1 = cast(StringExp)e1;\n        const uinteger_t ilwr = lwr.toInteger();\n        const uinteger_t iupr = upr.toInteger();\n        if (sliceBoundsCheck(0, es1.len, ilwr, iupr))\n            cantExp(ue);   // https://issues.dlang.org/show_bug.cgi?id=18115\n        else\n        {\n            const len = cast(size_t)(iupr - ilwr);\n            const sz = es1.sz;\n            void* s = mem.xmalloc(len * sz);\n            memcpy(s, es1.string + ilwr * sz, len * sz);\n            emplaceExp!(StringExp)(&ue, loc, s, len, es1.postfix);\n            StringExp es = cast(StringExp)ue.exp();\n            es.sz = sz;\n            es.committed = es1.committed;\n            es.type = type;\n        }\n    }\n    else if (e1.op == TOK.arrayLiteral && lwr.op == TOK.int64 && upr.op == TOK.int64 && !hasSideEffect(e1))\n    {\n        ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1;\n        const uinteger_t ilwr = lwr.toInteger();\n        const uinteger_t iupr = upr.toInteger();\n        if (sliceBoundsCheck(0, es1.elements.dim, ilwr, iupr))\n            cantExp(ue);\n        else\n        {\n            auto elements = new Expressions(cast(size_t)(iupr - ilwr));\n            memcpy(elements.tdata(), es1.elements.tdata() + ilwr, cast(size_t)(iupr - ilwr) * ((*es1.elements)[0]).sizeof);\n            emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, elements);\n        }\n    }\n    else\n        cantExp(ue);\n    return ue;\n}\n\n/* Set a slice of char/integer array literal 'existingAE' from a string 'newval'.\n * existingAE[firstIndex..firstIndex+newval.length] = newval.\n */\nvoid sliceAssignArrayLiteralFromString(ArrayLiteralExp existingAE, const StringExp newval, size_t firstIndex)\n{\n    const len = newval.len;\n    Type elemType = existingAE.type.nextOf();\n    foreach (j; 0 .. len)\n    {\n        const val = newval.getCodeUnit(j);\n        (*existingAE.elements)[j + firstIndex] = new IntegerExp(newval.loc, val, elemType);\n    }\n}\n\n/* Set a slice of string 'existingSE' from a char array literal 'newae'.\n *   existingSE[firstIndex..firstIndex+newae.length] = newae.\n */\nvoid sliceAssignStringFromArrayLiteral(StringExp existingSE, ArrayLiteralExp newae, size_t firstIndex)\n{\n    assert(existingSE.ownedByCtfe != OwnedBy.code);\n    foreach (j; 0 .. newae.elements.dim)\n    {\n        existingSE.setCodeUnit(firstIndex + j, cast(dchar)newae.getElement(j).toInteger());\n    }\n}\n\n/* Set a slice of string 'existingSE' from a string 'newstr'.\n *   existingSE[firstIndex..firstIndex+newstr.length] = newstr.\n */\nvoid sliceAssignStringFromString(StringExp existingSE, const StringExp newstr, size_t firstIndex)\n{\n    assert(existingSE.ownedByCtfe != OwnedBy.code);\n    size_t sz = existingSE.sz;\n    assert(sz == newstr.sz);\n    memcpy(existingSE.string + firstIndex * sz, newstr.string, sz * newstr.len);\n}\n\n/* Compare a string slice with another string slice.\n * Conceptually equivalent to memcmp( se1[lo1..lo1+len],  se2[lo2..lo2+len])\n */\nint sliceCmpStringWithString(const StringExp se1, const StringExp se2, size_t lo1, size_t lo2, size_t len)\n{\n    size_t sz = se1.sz;\n    assert(sz == se2.sz);\n    return memcmp(se1.string + sz * lo1, se2.string + sz * lo2, sz * len);\n}\n\n/* Compare a string slice with an array literal slice\n * Conceptually equivalent to memcmp( se1[lo1..lo1+len],  ae2[lo2..lo2+len])\n */\nint sliceCmpStringWithArray(const StringExp se1, ArrayLiteralExp ae2, size_t lo1, size_t lo2, size_t len)\n{\n    foreach (j; 0 .. len)\n    {\n        const val2 = cast(dchar)ae2.getElement(j + lo2).toInteger();\n        const val1 = se1.getCodeUnit(j + lo1);\n        const int c = val1 - val2;\n        if (c)\n            return c;\n    }\n    return 0;\n}\n\n/** Copy element `Expressions` in the parameters when they're `ArrayLiteralExp`s.\n * Params:\n *      e1  = If it's ArrayLiteralExp, its `elements` will be copied.\n *            Otherwise, `e1` itself will be pushed into the new `Expressions`.\n *      e2  = If it's not `null`, it will be pushed/appended to the new\n *            `Expressions` by the same way with `e1`.\n * Returns:\n *      Newly allocated `Expressions`. Note that it points to the original\n *      `Expression` values in e1 and e2.\n */\nprivate Expressions* copyElements(Expression e1, Expression e2 = null)\n{\n    auto elems = new Expressions();\n\n    void append(ArrayLiteralExp ale)\n    {\n        if (!ale.elements)\n            return;\n        auto d = elems.dim;\n        elems.append(ale.elements);\n        foreach (ref el; (*elems)[d .. elems.dim])\n        {\n            if (!el)\n                el = ale.basis;\n        }\n    }\n\n    if (e1.op == TOK.arrayLiteral)\n        append(cast(ArrayLiteralExp)e1);\n    else\n        elems.push(e1);\n\n    if (e2)\n    {\n        if (e2.op == TOK.arrayLiteral)\n            append(cast(ArrayLiteralExp)e2);\n        else\n            elems.push(e2);\n    }\n\n    return elems;\n}\n\n/* Also return TOK.cantExpression if this fails\n */\nUnionExp Cat(Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    Expression e = CTFEExp.cantexp;\n    Loc loc = e1.loc;\n    Type t;\n    Type t1 = e1.type.toBasetype();\n    Type t2 = e2.type.toBasetype();\n    //printf(\"Cat(e1 = %s, e2 = %s)\\n\", e1.toChars(), e2.toChars());\n    //printf(\"\\tt1 = %s, t2 = %s, type = %s\\n\", t1.toChars(), t2.toChars(), type.toChars());\n    if (e1.op == TOK.null_ && (e2.op == TOK.int64 || e2.op == TOK.structLiteral))\n    {\n        e = e2;\n        t = t1;\n        goto L2;\n    }\n    else if ((e1.op == TOK.int64 || e1.op == TOK.structLiteral) && e2.op == TOK.null_)\n    {\n        e = e1;\n        t = t2;\n    L2:\n        Type tn = e.type.toBasetype();\n        if (tn.ty == Tchar || tn.ty == Twchar || tn.ty == Tdchar)\n        {\n            // Create a StringExp\n            if (t.nextOf())\n                t = t.nextOf().toBasetype();\n            ubyte sz = cast(ubyte)t.size();\n            dinteger_t v = e.toInteger();\n            size_t len = (t.ty == tn.ty) ? 1 : utf_codeLength(sz, cast(dchar)v);\n            void* s = mem.xmalloc(len * sz);\n            if (t.ty == tn.ty)\n                Port.valcpy(s, v, sz);\n            else\n                utf_encode(sz, s, cast(dchar)v);\n            emplaceExp!(StringExp)(&ue, loc, s, len);\n            StringExp es = cast(StringExp)ue.exp();\n            es.type = type;\n            es.sz = sz;\n            es.committed = 1;\n        }\n        else\n        {\n            // Create an ArrayLiteralExp\n            auto elements = new Expressions();\n            elements.push(e);\n            emplaceExp!(ArrayLiteralExp)(&ue, e.loc, type, elements);\n        }\n        assert(ue.exp().type);\n        return ue;\n    }\n    else if (e1.op == TOK.null_ && e2.op == TOK.null_)\n    {\n        if (type == e1.type)\n        {\n            // Handle null ~= null\n            if (t1.ty == Tarray && t2 == t1.nextOf())\n            {\n                emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, e2);\n                assert(ue.exp().type);\n                return ue;\n            }\n            else\n            {\n                emplaceExp!(UnionExp)(&ue, e1);\n                assert(ue.exp().type);\n                return ue;\n            }\n        }\n        if (type == e2.type)\n        {\n            emplaceExp!(UnionExp)(&ue, e2);\n            assert(ue.exp().type);\n            return ue;\n        }\n        emplaceExp!(NullExp)(&ue, e1.loc, type);\n        assert(ue.exp().type);\n        return ue;\n    }\n    else if (e1.op == TOK.string_ && e2.op == TOK.string_)\n    {\n        // Concatenate the strings\n        StringExp es1 = cast(StringExp)e1;\n        StringExp es2 = cast(StringExp)e2;\n        size_t len = es1.len + es2.len;\n        ubyte sz = es1.sz;\n        if (sz != es2.sz)\n        {\n            /* Can happen with:\n             *   auto s = \"foo\"d ~ \"bar\"c;\n             */\n            assert(global.errors);\n            cantExp(ue);\n            assert(ue.exp().type);\n            return ue;\n        }\n        void* s = mem.xmalloc(len * sz);\n        memcpy(cast(char*)s, es1.string, es1.len * sz);\n        memcpy(cast(char*)s + es1.len * sz, es2.string, es2.len * sz);\n        emplaceExp!(StringExp)(&ue, loc, s, len);\n        StringExp es = cast(StringExp)ue.exp();\n        es.sz = sz;\n        es.committed = es1.committed | es2.committed;\n        es.type = type;\n        assert(ue.exp().type);\n        return ue;\n    }\n    else if (e2.op == TOK.string_ && e1.op == TOK.arrayLiteral && t1.nextOf().isintegral())\n    {\n        // [chars] ~ string --> [chars]\n        StringExp es = cast(StringExp)e2;\n        ArrayLiteralExp ea = cast(ArrayLiteralExp)e1;\n        size_t len = es.len + ea.elements.dim;\n        auto elems = new Expressions(len);\n        for (size_t i = 0; i < ea.elements.dim; ++i)\n        {\n            (*elems)[i] = ea.getElement(i);\n        }\n        emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, elems);\n        ArrayLiteralExp dest = cast(ArrayLiteralExp)ue.exp();\n        sliceAssignArrayLiteralFromString(dest, es, ea.elements.dim);\n        assert(ue.exp().type);\n        return ue;\n    }\n    else if (e1.op == TOK.string_ && e2.op == TOK.arrayLiteral && t2.nextOf().isintegral())\n    {\n        // string ~ [chars] --> [chars]\n        StringExp es = cast(StringExp)e1;\n        ArrayLiteralExp ea = cast(ArrayLiteralExp)e2;\n        size_t len = es.len + ea.elements.dim;\n        auto elems = new Expressions(len);\n        for (size_t i = 0; i < ea.elements.dim; ++i)\n        {\n            (*elems)[es.len + i] = ea.getElement(i);\n        }\n        emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, elems);\n        ArrayLiteralExp dest = cast(ArrayLiteralExp)ue.exp();\n        sliceAssignArrayLiteralFromString(dest, es, 0);\n        assert(ue.exp().type);\n        return ue;\n    }\n    else if (e1.op == TOK.string_ && e2.op == TOK.int64)\n    {\n        // string ~ char --> string\n        StringExp es1 = cast(StringExp)e1;\n        StringExp es;\n        ubyte sz = es1.sz;\n        dinteger_t v = e2.toInteger();\n        // Is it a concatenation of homogenous types?\n        // (char[] ~ char, wchar[]~wchar, or dchar[]~dchar)\n        bool homoConcat = (sz == t2.size());\n        size_t len = es1.len;\n        len += homoConcat ? 1 : utf_codeLength(sz, cast(dchar)v);\n        void* s = mem.xmalloc(len * sz);\n        memcpy(s, es1.string, es1.len * sz);\n        if (homoConcat)\n            Port.valcpy(cast(char*)s + (sz * es1.len), v, sz);\n        else\n            utf_encode(sz, cast(char*)s + (sz * es1.len), cast(dchar)v);\n        emplaceExp!(StringExp)(&ue, loc, s, len);\n        es = cast(StringExp)ue.exp();\n        es.sz = sz;\n        es.committed = es1.committed;\n        es.type = type;\n        assert(ue.exp().type);\n        return ue;\n    }\n    else if (e1.op == TOK.int64 && e2.op == TOK.string_)\n    {\n        // Concatenate the strings\n        StringExp es2 = cast(StringExp)e2;\n        size_t len = 1 + es2.len;\n        ubyte sz = es2.sz;\n        dinteger_t v = e1.toInteger();\n        void* s = mem.xmalloc(len * sz);\n        memcpy(cast(char*)s, &v, sz);\n        memcpy(cast(char*)s + sz, es2.string, es2.len * sz);\n        emplaceExp!(StringExp)(&ue, loc, s, len);\n        StringExp es = cast(StringExp)ue.exp();\n        es.sz = sz;\n        es.committed = es2.committed;\n        es.type = type;\n        assert(ue.exp().type);\n        return ue;\n    }\n    else if (e1.op == TOK.arrayLiteral && e2.op == TOK.arrayLiteral && t1.nextOf().equals(t2.nextOf()))\n    {\n        // Concatenate the arrays\n        auto elems = copyElements(e1, e2);\n\n        emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, cast(Type)null, elems);\n\n        e = ue.exp();\n        if (type.toBasetype().ty == Tsarray)\n        {\n            e.type = t1.nextOf().sarrayOf(elems.dim);\n        }\n        else\n            e.type = type;\n        assert(ue.exp().type);\n        return ue;\n    }\n    else if (e1.op == TOK.arrayLiteral && e2.op == TOK.null_ && t1.nextOf().equals(t2.nextOf()))\n    {\n        e = e1;\n        goto L3;\n    }\n    else if (e1.op == TOK.null_ && e2.op == TOK.arrayLiteral && t1.nextOf().equals(t2.nextOf()))\n    {\n        e = e2;\n    L3:\n        // Concatenate the array with null\n        auto elems = copyElements(e);\n\n        emplaceExp!(ArrayLiteralExp)(&ue, e.loc, cast(Type)null, elems);\n\n        e = ue.exp();\n        if (type.toBasetype().ty == Tsarray)\n        {\n            e.type = t1.nextOf().sarrayOf(elems.dim);\n        }\n        else\n            e.type = type;\n        assert(ue.exp().type);\n        return ue;\n    }\n    else if ((e1.op == TOK.arrayLiteral || e1.op == TOK.null_) && e1.type.toBasetype().nextOf() && e1.type.toBasetype().nextOf().equals(e2.type))\n    {\n        auto elems = (e1.op == TOK.arrayLiteral)\n                ? copyElements(e1) : new Expressions();\n        elems.push(e2);\n\n        emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, cast(Type)null, elems);\n\n        e = ue.exp();\n        if (type.toBasetype().ty == Tsarray)\n        {\n            e.type = e2.type.sarrayOf(elems.dim);\n        }\n        else\n            e.type = type;\n        assert(ue.exp().type);\n        return ue;\n    }\n    else if (e2.op == TOK.arrayLiteral && e2.type.toBasetype().nextOf().equals(e1.type))\n    {\n        auto elems = copyElements(e1, e2);\n\n        emplaceExp!(ArrayLiteralExp)(&ue, e2.loc, cast(Type)null, elems);\n\n        e = ue.exp();\n        if (type.toBasetype().ty == Tsarray)\n        {\n            e.type = e1.type.sarrayOf(elems.dim);\n        }\n        else\n            e.type = type;\n        assert(ue.exp().type);\n        return ue;\n    }\n    else if (e1.op == TOK.null_ && e2.op == TOK.string_)\n    {\n        t = e1.type;\n        e = e2;\n        goto L1;\n    }\n    else if (e1.op == TOK.string_ && e2.op == TOK.null_)\n    {\n        e = e1;\n        t = e2.type;\n    L1:\n        Type tb = t.toBasetype();\n        if (tb.ty == Tarray && tb.nextOf().equivalent(e.type))\n        {\n            auto expressions = new Expressions();\n            expressions.push(e);\n            emplaceExp!(ArrayLiteralExp)(&ue, loc, t, expressions);\n            e = ue.exp();\n        }\n        else\n        {\n            emplaceExp!(UnionExp)(&ue, e);\n            e = ue.exp();\n        }\n        if (!e.type.equals(type))\n        {\n            StringExp se = cast(StringExp)e.copy();\n            e = se.castTo(null, type);\n            emplaceExp!(UnionExp)(&ue, e);\n            e = ue.exp();\n        }\n    }\n    else\n        cantExp(ue);\n    assert(ue.exp().type);\n    return ue;\n}\n\nUnionExp Ptr(Type type, Expression e1)\n{\n    //printf(\"Ptr(e1 = %s)\\n\", e1.toChars());\n    UnionExp ue = void;\n    if (e1.op == TOK.add)\n    {\n        AddExp ae = cast(AddExp)e1;\n        if (ae.e1.op == TOK.address && ae.e2.op == TOK.int64)\n        {\n            AddrExp ade = cast(AddrExp)ae.e1;\n            if (ade.e1.op == TOK.structLiteral)\n            {\n                StructLiteralExp se = cast(StructLiteralExp)ade.e1;\n                uint offset = cast(uint)ae.e2.toInteger();\n                Expression e = se.getField(type, offset);\n                if (e)\n                {\n                    emplaceExp!(UnionExp)(&ue, e);\n                    return ue;\n                }\n            }\n        }\n    }\n    cantExp(ue);\n    return ue;\n}\n"
  },
  {
    "path": "gcc/d/dmd/cppmangle.d",
    "content": "/**\n * Compiler implementation of the $(LINK2 http://www.dlang.org, D programming language)\n *\n * Do mangling for C++ linkage.\n * This is the POSIX side of the implementation.\n * It exports two functions to C++, `toCppMangleItanium` and `cppTypeInfoMangleItanium`.\n *\n * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors: Walter Bright, http://www.digitalmars.com\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/cppmangle.d, _cppmangle.d)\n * Documentation:  https://dlang.org/phobos/dmd_cppmangle.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/cppmangle.d\n *\n * References:\n *  Follows Itanium C++ ABI 1.86 section 5.1\n *  http://refspecs.linux-foundation.org/cxxabi-1.86.html#mangling\n *  which is where the grammar comments come from.\n *\n * Bugs:\n *  https://issues.dlang.org/query.cgi\n *  enter `C++, mangling` as the keywords.\n */\n\nmodule dmd.cppmangle;\n\nimport core.stdc.string;\nimport core.stdc.stdio;\n\nimport dmd.arraytypes;\nimport dmd.declaration;\nimport dmd.dsymbol;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.nspace;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.visitor;\n\n\n// helper to check if an identifier is a C++ operator\nenum CppOperator { Cast, Assign, Eq, Index, Call, Unary, Binary, OpAssign, Unknown }\npackage CppOperator isCppOperator(Identifier id)\n{\n    __gshared const(Identifier)[] operators = null;\n    if (!operators)\n        operators = [Id._cast, Id.assign, Id.eq, Id.index, Id.call, Id.opUnary, Id.opBinary, Id.opOpAssign];\n    foreach (i, op; operators)\n    {\n        if (op == id)\n            return cast(CppOperator)i;\n    }\n    return CppOperator.Unknown;\n}\n\n///\nextern(C++) const(char)* toCppMangleItanium(Dsymbol s)\n{\n    //printf(\"toCppMangleItanium(%s)\\n\", s.toChars());\n    OutBuffer buf;\n    scope CppMangleVisitor v = new CppMangleVisitor(&buf, s.loc);\n    v.mangleOf(s);\n    return buf.extractString();\n}\n\n///\nextern(C++) const(char)* cppTypeInfoMangleItanium(Dsymbol s)\n{\n    //printf(\"cppTypeInfoMangle(%s)\\n\", s.toChars());\n    OutBuffer buf;\n    buf.writestring(\"_ZTI\");    // \"TI\" means typeinfo structure\n    scope CppMangleVisitor v = new CppMangleVisitor(&buf, s.loc);\n    v.cpp_mangle_name(s, false);\n    return buf.extractString();\n}\n\n/******************************\n * Determine if sym is the 'primary' destructor, that is,\n * the most-aggregate destructor (the one that is defined as __xdtor)\n * Params:\n *      sym = Dsymbol\n * Returns:\n *      true if sym is the primary destructor for an aggregate\n */\nbool isPrimaryDtor(const Dsymbol sym)\n{\n    const dtor = sym.isDtorDeclaration();\n    if (!dtor)\n        return false;\n    const ad = dtor.isMember();\n    assert(ad);\n    return dtor == ad.primaryDtor;\n}\n\n/// Context used when processing pre-semantic AST\nprivate struct Context\n{\n    /// Template instance of the function being mangled\n    TemplateInstance ti;\n    /// Function declaration we're mangling\n    FuncDeclaration fd;\n    /// Current type / expression being processed (semantically analyzed)\n    RootObject res;\n\n    @disable ref Context opAssign(ref Context other);\n    @disable ref Context opAssign(Context other);\n\n    /**\n     * Helper function to track `res`\n     *\n     * Params:\n     *   next = Value to set `this.res` to.\n     *          If `this.res` is `null`, the expression is not evalutated.\n     *          This allow this code to be used even when no context is needed.\n     *\n     * Returns:\n     *   The previous state of this `Context` object\n     */\n    private Context push(lazy RootObject next)\n    {\n        auto r = this.res;\n        if (r !is null)\n            this.res = next;\n        return Context(this.ti, this.fd, r);\n    }\n\n    /**\n     * Reset the context to a previous one, making any adjustment necessary\n     */\n    private void pop(ref Context prev)\n    {\n        this.res = prev.res;\n    }\n}\n\nprivate final class CppMangleVisitor : Visitor\n{\n    /// Context used when processing pre-semantic AST\n    private Context context;\n\n    Objects components;         // array of components available for substitution\n    OutBuffer* buf;             // append the mangling to buf[]\n    Loc loc;                    // location for use in error messages\n\n    /**\n     * Constructor\n     *\n     * Params:\n     *   buf = `OutBuffer` to write the mangling to\n     *   loc = `Loc` of the symbol being mangled\n     */\n    this(OutBuffer* buf, Loc loc)\n    {\n        this.buf = buf;\n        this.loc = loc;\n    }\n\n    /*****\n     * Entry point. Append mangling to buf[]\n     * Params:\n     *  s = symbol to mangle\n     */\n    void mangleOf(Dsymbol s)\n    {\n        if (VarDeclaration vd = s.isVarDeclaration())\n        {\n            mangle_variable(vd, false);\n        }\n        else if (FuncDeclaration fd = s.isFuncDeclaration())\n        {\n            mangle_function(fd);\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n\n    /**\n     * Mangle the return type of a function\n     *\n     * This is called on a templated function type.\n     * Context is set to the `FuncDeclaration`.\n     *\n     * Params:\n     *   preSemantic = the `FuncDeclaration`'s `originalType`\n     */\n    void mangleReturnType(TypeFunction preSemantic)\n    {\n        auto tf = cast(TypeFunction)this.context.res.asFuncDecl().type;\n        Type rt = preSemantic.nextOf();\n        if (tf.isref)\n            rt = rt.referenceTo();\n        auto prev = this.context.push(tf.nextOf());\n        scope (exit) this.context.pop(prev);\n        this.headOfType(rt);\n    }\n\n    /**\n     * Write a seq-id from an index number, excluding the terminating '_'\n     *\n     * Params:\n     *   idx = the index in a substitution list.\n     *         Note that index 0 has no value, and `S0_` would be the\n     *         substitution at index 1 in the list.\n     *\n     * See-Also:\n     *  https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.seq-id\n     */\n    private void writeSequenceFromIndex(size_t idx)\n    {\n        if (idx)\n        {\n            void write_seq_id(size_t i)\n            {\n                if (i >= 36)\n                {\n                    write_seq_id(i / 36);\n                    i %= 36;\n                }\n                i += (i < 10) ? '0' : 'A' - 10;\n                buf.writeByte(cast(char)i);\n            }\n\n            write_seq_id(idx - 1);\n        }\n    }\n\n    bool substitute(RootObject p)\n    {\n        //printf(\"substitute %s\\n\", p ? p.toChars() : null);\n        auto i = find(p);\n        if (i >= 0)\n        {\n            //printf(\"\\tmatch\\n\");\n            /* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...\n             */\n            buf.writeByte('S');\n            writeSequenceFromIndex(i);\n            buf.writeByte('_');\n            return true;\n        }\n        return false;\n    }\n\n    /******\n     * See if `p` exists in components[]\n     *\n     * Note that components can contain `null` entries,\n     * as the index used in mangling is based on the index in the array.\n     *\n     * If called with an object whose dynamic type is `Nspace`,\n     * calls the `find(Nspace)` overload.\n     *\n     * Returns:\n     *  index if found, -1 if not\n     */\n    int find(RootObject p)\n    {\n        //printf(\"find %p %d %s\\n\", p, p.dyncast(), p ? p.toChars() : null);\n        scope v = new ComponentVisitor(p);\n        foreach (i, component; components)\n        {\n            if (component)\n                component.visitObject(v);\n            if (v.result)\n                return cast(int)i;\n        }\n        return -1;\n    }\n\n    /*********************\n     * Append p to components[]\n     */\n    void append(RootObject p)\n    {\n        //printf(\"append %p %d %s\\n\", p, p.dyncast(), p ? p.toChars() : \"null\");\n        components.push(p);\n    }\n\n    /**\n     * Write an identifier preceded by its length\n     *\n     * Params:\n     *   ident = `Identifier` to write to `this.buf`\n     */\n    void writeIdentifier(const ref Identifier ident)\n    {\n        const name = ident.toString();\n        this.buf.print(name.length);\n        this.buf.writestring(name);\n    }\n\n    /************************\n     * Determine if symbol is indeed the global ::std namespace.\n     * Params:\n     *  s = symbol to check\n     * Returns:\n     *  true if it is ::std\n     */\n    static bool isStd(Dsymbol s)\n    {\n        return (s &&\n                s.ident == Id.std &&    // the right name\n                s.isNspace() &&         // g++ disallows global \"std\" for other than a namespace\n                !getQualifier(s));      // at global level\n    }\n\n    /******************************\n     * Write the mangled representation of a template argument.\n     * Params:\n     *  ti  = the template instance\n     *  arg = the template argument index\n     */\n    void template_arg(TemplateInstance ti, size_t arg)\n    {\n        TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration();\n        assert(td);\n        TemplateParameter tp = (*td.parameters)[arg];\n        RootObject o = (*ti.tiargs)[arg];\n\n        Objects* pctx;\n        auto prev = this.context.push({\n                TemplateInstance parentti;\n                if (this.context.res.dyncast() == DYNCAST.dsymbol)\n                    parentti = this.context.res.asFuncDecl().parent.isTemplateInstance();\n                else\n                    parentti = this.context.res.asType().toDsymbol(null).parent.isTemplateInstance();\n                return (*parentti.tiargs)[arg];\n            }());\n        scope (exit) this.context.pop(prev);\n\n        if (tp.isTemplateTypeParameter())\n        {\n            Type t = isType(o);\n            assert(t);\n            t.accept(this);\n        }\n        else if (TemplateValueParameter tv = tp.isTemplateValueParameter())\n        {\n            // <expr-primary> ::= L <type> <value number> E  # integer literal\n            if (tv.valType.isintegral())\n            {\n                Expression e = isExpression(o);\n                assert(e);\n                buf.writeByte('L');\n                tv.valType.accept(this);\n                auto val = e.toUInteger();\n                if (!tv.valType.isunsigned() && cast(sinteger_t)val < 0)\n                {\n                    val = -val;\n                    buf.writeByte('n');\n                }\n                buf.print(val);\n                buf.writeByte('E');\n            }\n            else\n            {\n                ti.error(\"Internal Compiler Error: C++ `%s` template value parameter is not supported\", tv.valType.toChars());\n                fatal();\n            }\n        }\n        else if (tp.isTemplateAliasParameter())\n        {\n            // Passing a function as alias parameter is the same as passing\n            // `&function`\n            Dsymbol d = isDsymbol(o);\n            Expression e = isExpression(o);\n            if (d && d.isFuncDeclaration())\n            {\n                // X .. E => template parameter is an expression\n                // 'ad'   => unary operator ('&')\n                // L .. E => is a <expr-primary>\n                buf.writestring(\"XadL\");\n                mangle_function(d.isFuncDeclaration());\n                buf.writestring(\"EE\");\n            }\n            else if (e && e.op == TOK.variable && (cast(VarExp)e).var.isVarDeclaration())\n            {\n                VarDeclaration vd = (cast(VarExp)e).var.isVarDeclaration();\n                buf.writeByte('L');\n                mangle_variable(vd, true);\n                buf.writeByte('E');\n            }\n            else if (d && d.isTemplateDeclaration() && d.isTemplateDeclaration().onemember)\n            {\n                if (!substitute(d))\n                {\n                    cpp_mangle_name(d, false);\n                }\n            }\n            else\n            {\n                ti.error(\"Internal Compiler Error: C++ `%s` template alias parameter is not supported\", o.toChars());\n                fatal();\n            }\n        }\n        else if (tp.isTemplateThisParameter())\n        {\n            ti.error(\"Internal Compiler Error: C++ `%s` template this parameter is not supported\", o.toChars());\n            fatal();\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n\n    /******************************\n     * Write the mangled representation of the template arguments.\n     * Params:\n     *  ti = the template instance\n     *  firstArg = index of the first template argument to mangle\n     *             (used for operator overloading)\n     * Returns:\n     *  true if any arguments were written\n     */\n    bool template_args(TemplateInstance ti, int firstArg = 0)\n    {\n        /* <template-args> ::= I <template-arg>+ E\n         */\n        if (!ti || ti.tiargs.dim <= firstArg)   // could happen if std::basic_string is not a template\n            return false;\n        buf.writeByte('I');\n        foreach (i; firstArg .. ti.tiargs.dim)\n        {\n            TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration();\n            assert(td);\n            TemplateParameter tp = (*td.parameters)[i];\n\n            /*\n             * <template-arg> ::= <type>               # type or template\n             *                ::= X <expression> E     # expression\n             *                ::= <expr-primary>       # simple expressions\n             *                ::= I <template-arg>* E  # argument pack\n             */\n            if (TemplateTupleParameter tt = tp.isTemplateTupleParameter())\n            {\n                buf.writeByte('I');     // argument pack\n\n                // mangle the rest of the arguments as types\n                foreach (j; i .. (*ti.tiargs).dim)\n                {\n                    Type t = isType((*ti.tiargs)[j]);\n                    assert(t);\n                    t.accept(this);\n                }\n\n                buf.writeByte('E');\n                break;\n            }\n\n            template_arg(ti, i);\n        }\n        buf.writeByte('E');\n        return true;\n    }\n\n\n    void source_name(Dsymbol s)\n    {\n        //printf(\"source_name(%s)\\n\", s.toChars());\n        if (TemplateInstance ti = s.isTemplateInstance())\n        {\n            if (!substitute(ti.tempdecl))\n            {\n                append(ti.tempdecl);\n                this.writeIdentifier(ti.tempdecl.toAlias().ident);\n            }\n            template_args(ti);\n        }\n        else\n            this.writeIdentifier(s.ident);\n    }\n\n    /********\n     * See if s is actually an instance of a template\n     * Params:\n     *  s = symbol\n     * Returns:\n     *  if s is instance of a template, return the instance, otherwise return s\n     */\n    Dsymbol getInstance(Dsymbol s)\n    {\n        Dsymbol p = s.toParent();\n        if (p)\n        {\n            if (TemplateInstance ti = p.isTemplateInstance())\n                return ti;\n        }\n        return s;\n    }\n\n    /********\n     * Get qualifier for `s`, meaning the symbol\n     * that s is in the symbol table of.\n     * The module does not count as a qualifier, because C++\n     * does not have modules.\n     * Params:\n     *  s = symbol that may have a qualifier\n     *      s is rewritten to be TemplateInstance if s is one\n     * Returns:\n     *  qualifier, null if none\n     */\n    static Dsymbol getQualifier(Dsymbol s)\n    {\n        Dsymbol p = s.toParent();\n        return (p && !p.isModule()) ? p : null;\n    }\n\n    // Detect type char\n    static bool isChar(RootObject o)\n    {\n        Type t = isType(o);\n        return (t && t.equals(Type.tchar));\n    }\n\n    // Detect type ::std::char_traits<char>\n    static bool isChar_traits_char(RootObject o)\n    {\n        return isIdent_char(Id.char_traits, o);\n    }\n\n    // Detect type ::std::allocator<char>\n    static bool isAllocator_char(RootObject o)\n    {\n        return isIdent_char(Id.allocator, o);\n    }\n\n    // Detect type ::std::ident<char>\n    static bool isIdent_char(Identifier ident, RootObject o)\n    {\n        Type t = isType(o);\n        if (!t || t.ty != Tstruct)\n            return false;\n        Dsymbol s = (cast(TypeStruct)t).toDsymbol(null);\n        if (s.ident != ident)\n            return false;\n        Dsymbol p = s.toParent();\n        if (!p)\n            return false;\n        TemplateInstance ti = p.isTemplateInstance();\n        if (!ti)\n            return false;\n        Dsymbol q = getQualifier(ti);\n        return isStd(q) && ti.tiargs.dim == 1 && isChar((*ti.tiargs)[0]);\n    }\n\n    /***\n     * Detect template args <char, ::std::char_traits<char>>\n     * and write st if found.\n     * Returns:\n     *  true if found\n     */\n    bool char_std_char_traits_char(TemplateInstance ti, string st)\n    {\n        if (ti.tiargs.dim == 2 &&\n            isChar((*ti.tiargs)[0]) &&\n            isChar_traits_char((*ti.tiargs)[1]))\n        {\n            buf.writestring(st.ptr);\n            return true;\n        }\n        return false;\n    }\n\n\n    void prefix_name(Dsymbol s)\n    {\n        //printf(\"prefix_name(%s)\\n\", s.toChars());\n        if (substitute(s))\n            return;\n\n        auto si = getInstance(s);\n        Dsymbol p = getQualifier(si);\n        if (p)\n        {\n            if (isStd(p))\n            {\n                bool needsTa;\n                auto ti = si.isTemplateInstance();\n                if (this.writeStdSubstitution(ti, needsTa))\n                {\n                    if (needsTa)\n                    {\n                        template_args(ti);\n                        append(ti);\n                    }\n                    return;\n                }\n                buf.writestring(\"St\");\n            }\n            else\n                prefix_name(p);\n        }\n        source_name(si);\n        if (!isStd(si))\n            /* Do this after the source_name() call to keep components[]\n             * in the right order.\n             * https://issues.dlang.org/show_bug.cgi?id=17947\n             */\n            append(si);\n    }\n\n    /**\n     * Write common substitution for standard types, such as std::allocator\n     *\n     * This function assumes that the symbol `ti` is in the namespace `std`.\n     *\n     * Params:\n     *   ti = Template instance to consider\n     *   needsTa = If this function returns `true`, this value indicates\n     *             if additional template argument mangling is needed\n     *\n     * Returns:\n     *   `true` if a special std symbol was found\n     */\n    bool writeStdSubstitution(TemplateInstance ti, out bool needsTa)\n    {\n        if (!ti)\n            return false;\n\n        if (ti.name == Id.allocator)\n        {\n            buf.writestring(\"Sa\");\n            needsTa = true;\n            return true;\n        }\n        if (ti.name == Id.basic_string)\n        {\n            // ::std::basic_string<char, ::std::char_traits<char>, ::std::allocator<char>>\n            if (ti.tiargs.dim == 3 &&\n                isChar((*ti.tiargs)[0]) &&\n                isChar_traits_char((*ti.tiargs)[1]) &&\n                isAllocator_char((*ti.tiargs)[2]))\n\n            {\n                buf.writestring(\"Ss\");\n                return true;\n            }\n            buf.writestring(\"Sb\");      // ::std::basic_string\n            needsTa = true;\n            return true;\n        }\n\n        // ::std::basic_istream<char, ::std::char_traits<char>>\n        if (ti.name == Id.basic_istream &&\n            char_std_char_traits_char(ti, \"Si\"))\n            return true;\n\n        // ::std::basic_ostream<char, ::std::char_traits<char>>\n        if (ti.name == Id.basic_ostream &&\n            char_std_char_traits_char(ti, \"So\"))\n            return true;\n\n        // ::std::basic_iostream<char, ::std::char_traits<char>>\n        if (ti.name == Id.basic_iostream &&\n            char_std_char_traits_char(ti, \"Sd\"))\n            return true;\n\n        return false;\n    }\n\n\n    void cpp_mangle_name(Dsymbol s, bool qualified)\n    {\n        //printf(\"cpp_mangle_name(%s, %d)\\n\", s.toChars(), qualified);\n        Dsymbol p = s.toParent();\n        Dsymbol se = s;\n        bool write_prefix = true;\n        if (p && p.isTemplateInstance())\n        {\n            se = p;\n            if (find(p.isTemplateInstance().tempdecl) >= 0)\n                write_prefix = false;\n            p = p.toParent();\n        }\n        if (p && !p.isModule())\n        {\n            /* The N..E is not required if:\n             * 1. the parent is 'std'\n             * 2. 'std' is the initial qualifier\n             * 3. there is no CV-qualifier or a ref-qualifier for a member function\n             * ABI 5.1.8\n             */\n            if (isStd(p) && !qualified)\n            {\n                TemplateInstance ti = se.isTemplateInstance();\n                if (s.ident == Id.allocator)\n                {\n                    buf.writestring(\"Sa\"); // \"Sa\" is short for ::std::allocator\n                    template_args(ti);\n                }\n                else if (s.ident == Id.basic_string)\n                {\n                    // ::std::basic_string<char, ::std::char_traits<char>, ::std::allocator<char>>\n                    if (ti.tiargs.dim == 3 &&\n                        isChar((*ti.tiargs)[0]) &&\n                        isChar_traits_char((*ti.tiargs)[1]) &&\n                        isAllocator_char((*ti.tiargs)[2]))\n\n                    {\n                        buf.writestring(\"Ss\");\n                        return;\n                    }\n                    buf.writestring(\"Sb\");      // ::std::basic_string\n                    template_args(ti);\n                }\n                else\n                {\n                    // ::std::basic_istream<char, ::std::char_traits<char>>\n                    if (s.ident == Id.basic_istream)\n                    {\n                        if (char_std_char_traits_char(ti, \"Si\"))\n                            return;\n                    }\n                    else if (s.ident == Id.basic_ostream)\n                    {\n                        if (char_std_char_traits_char(ti, \"So\"))\n                            return;\n                    }\n                    else if (s.ident == Id.basic_iostream)\n                    {\n                        if (char_std_char_traits_char(ti, \"Sd\"))\n                            return;\n                    }\n                    buf.writestring(\"St\");\n                    source_name(se);\n                }\n            }\n            else\n            {\n                buf.writeByte('N');\n                if (write_prefix)\n                {\n                    if (isStd(p))\n                        buf.writestring(\"St\");\n                    else\n                        prefix_name(p);\n                }\n                source_name(se);\n                buf.writeByte('E');\n            }\n        }\n        else\n            source_name(se);\n        append(s);\n    }\n\n    /**\n     * Write CV-qualifiers to the buffer\n     *\n     * CV-qualifiers are 'r': restrict (unused in D), 'V': volatile, 'K': const\n     *\n     * See_Also:\n     *   https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.CV-qualifiers\n     */\n    void CV_qualifiers(const Type t)\n    {\n        if (t.isConst())\n            buf.writeByte('K');\n    }\n\n    void mangle_variable(VarDeclaration d, bool is_temp_arg_ref)\n    {\n        // fake mangling for fields to fix https://issues.dlang.org/show_bug.cgi?id=16525\n        if (!(d.storage_class & (STC.extern_ | STC.field | STC.gshared)))\n        {\n            d.error(\"Internal Compiler Error: C++ static non-`__gshared` non-`extern` variables not supported\");\n            fatal();\n        }\n        Dsymbol p = d.toParent();\n        if (p && !p.isModule()) //for example: char Namespace1::beta[6] should be mangled as \"_ZN10Namespace14betaE\"\n        {\n            buf.writestring(\"_ZN\");\n            prefix_name(p);\n            source_name(d);\n            buf.writeByte('E');\n        }\n        else //char beta[6] should mangle as \"beta\"\n        {\n            if (!is_temp_arg_ref)\n            {\n                buf.writestring(d.ident.toChars());\n            }\n            else\n            {\n                buf.writestring(\"_Z\");\n                source_name(d);\n            }\n        }\n    }\n\n    void mangle_function(FuncDeclaration d)\n    {\n        //printf(\"mangle_function(%s)\\n\", d.toChars());\n        /*\n         * <mangled-name> ::= _Z <encoding>\n         * <encoding> ::= <function name> <bare-function-type>\n         *            ::= <data name>\n         *            ::= <special-name>\n         */\n        TypeFunction tf = cast(TypeFunction)d.type;\n        buf.writestring(\"_Z\");\n\n        if (TemplateDeclaration ftd = getFuncTemplateDecl(d))\n        {\n            /* It's an instance of a function template\n             */\n            TemplateInstance ti = d.parent.isTemplateInstance();\n            assert(ti);\n            this.mangleTemplatedFunction(d, tf, ftd, ti);\n        }\n        else\n        {\n            Dsymbol p = d.toParent();\n            if (p && !p.isModule() && tf.linkage == LINK.cpp)\n            {\n                this.mangleNestedFuncPrefix(tf, p);\n\n                if (d.isCtorDeclaration())\n                    buf.writestring(\"C1\");\n                else if (d.isPrimaryDtor())\n                    buf.writestring(\"D1\");\n                else if (d.ident && d.ident == Id.assign)\n                    buf.writestring(\"aS\");\n                else if (d.ident && d.ident == Id.eq)\n                    buf.writestring(\"eq\");\n                else if (d.ident && d.ident == Id.index)\n                    buf.writestring(\"ix\");\n                else if (d.ident && d.ident == Id.call)\n                    buf.writestring(\"cl\");\n                else\n                    source_name(d);\n                buf.writeByte('E');\n            }\n            else\n            {\n                source_name(d);\n            }\n            // Template args accept extern \"C\" symbols with special mangling\n            if (tf.linkage == LINK.cpp)\n                mangleFunctionParameters(tf.parameters, tf.varargs);\n        }\n    }\n\n    /**\n     * Mangles a function template to C++\n     *\n     * Params:\n     *   d = Function declaration\n     *   tf = Function type (casted d.type)\n     *   ftd = Template declaration (ti.templdecl)\n     *   ti = Template instance (d.parent)\n     */\n    void mangleTemplatedFunction(FuncDeclaration d, TypeFunction tf,\n                                 TemplateDeclaration ftd, TemplateInstance ti)\n    {\n        Dsymbol p = ti.toParent();\n        // Check if this function is *not* nested\n        if (!p || p.isModule() || tf.linkage != LINK.cpp)\n        {\n            this.context.ti = ti;\n            this.context.fd = d;\n            this.context.res = d;\n            TypeFunction preSemantic = cast(TypeFunction)d.originalType;\n            source_name(ti);\n            this.mangleReturnType(preSemantic);\n            this.mangleFunctionParameters(preSemantic.parameters, tf.varargs);\n            return;\n        }\n\n        // It's a nested function (e.g. a member of an aggregate)\n        this.mangleNestedFuncPrefix(tf, p);\n\n        if (d.isCtorDeclaration())\n        {\n            buf.writestring(\"C1\");\n        }\n        else if (d.isPrimaryDtor())\n        {\n            buf.writestring(\"D1\");\n        }\n        else\n        {\n            int firstTemplateArg = 0;\n            bool appendReturnType = true;\n            bool isConvertFunc = false;\n            string symName;\n\n            // test for special symbols\n            CppOperator whichOp = isCppOperator(ti.name);\n            final switch (whichOp)\n            {\n            case CppOperator.Unknown:\n                break;\n            case CppOperator.Cast:\n                symName = \"cv\";\n                firstTemplateArg = 1;\n                isConvertFunc = true;\n                appendReturnType = false;\n                break;\n            case CppOperator.Assign:\n                symName = \"aS\";\n                break;\n            case CppOperator.Eq:\n                symName = \"eq\";\n                break;\n            case CppOperator.Index:\n                symName = \"ix\";\n                break;\n            case CppOperator.Call:\n                symName = \"cl\";\n                break;\n            case CppOperator.Unary:\n            case CppOperator.Binary:\n            case CppOperator.OpAssign:\n                TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration();\n                assert(td);\n                assert(ti.tiargs.dim >= 1);\n                TemplateParameter tp = (*td.parameters)[0];\n                TemplateValueParameter tv = tp.isTemplateValueParameter();\n                if (!tv || !tv.valType.isString())\n                    break; // expecting a string argument to operators!\n                Expression exp = (*ti.tiargs)[0].isExpression();\n                StringExp str = exp.toStringExp();\n                switch (whichOp)\n                {\n                case CppOperator.Unary:\n                    switch (str.peekSlice())\n                    {\n                    case \"*\":   symName = \"de\"; goto continue_template;\n                    case \"++\":  symName = \"pp\"; goto continue_template;\n                    case \"--\":  symName = \"mm\"; goto continue_template;\n                    case \"-\":   symName = \"ng\"; goto continue_template;\n                    case \"+\":   symName = \"ps\"; goto continue_template;\n                    case \"~\":   symName = \"co\"; goto continue_template;\n                    default:    break;\n                    }\n                    break;\n                case CppOperator.Binary:\n                    switch (str.peekSlice())\n                    {\n                    case \">>\":  symName = \"rs\"; goto continue_template;\n                    case \"<<\":  symName = \"ls\"; goto continue_template;\n                    case \"*\":   symName = \"ml\"; goto continue_template;\n                    case \"-\":   symName = \"mi\"; goto continue_template;\n                    case \"+\":   symName = \"pl\"; goto continue_template;\n                    case \"&\":   symName = \"an\"; goto continue_template;\n                    case \"/\":   symName = \"dv\"; goto continue_template;\n                    case \"%\":   symName = \"rm\"; goto continue_template;\n                    case \"^\":   symName = \"eo\"; goto continue_template;\n                    case \"|\":   symName = \"or\"; goto continue_template;\n                    default:    break;\n                    }\n                    break;\n                case CppOperator.OpAssign:\n                    switch (str.peekSlice())\n                    {\n                    case \"*\":   symName = \"mL\"; goto continue_template;\n                    case \"+\":   symName = \"pL\"; goto continue_template;\n                    case \"-\":   symName = \"mI\"; goto continue_template;\n                    case \"/\":   symName = \"dV\"; goto continue_template;\n                    case \"%\":   symName = \"rM\"; goto continue_template;\n                    case \">>\":  symName = \"rS\"; goto continue_template;\n                    case \"<<\":  symName = \"lS\"; goto continue_template;\n                    case \"&\":   symName = \"aN\"; goto continue_template;\n                    case \"|\":   symName = \"oR\"; goto continue_template;\n                    case \"^\":   symName = \"eO\"; goto continue_template;\n                    default:    break;\n                    }\n                    break;\n                default:\n                    assert(0);\n                continue_template:\n                    firstTemplateArg = 1;\n                    break;\n                }\n                break;\n            }\n            if (symName.length == 0)\n                source_name(ti);\n            else\n            {\n                buf.writestring(symName);\n                if (isConvertFunc)\n                    template_arg(ti, 0);\n                appendReturnType = template_args(ti, firstTemplateArg) && appendReturnType;\n            }\n            buf.writeByte('E');\n            if (appendReturnType)\n                headOfType(tf.nextOf());  // mangle return type\n        }\n        mangleFunctionParameters(tf.parameters, tf.varargs);\n    }\n\n    /**\n     * Mangle the parameters of a function\n     *\n     * For templated functions, `context.res` is set to the `FuncDeclaration`\n     *\n     * Params:\n     *   parameters = Array of `Parameter` to mangle\n     *   varargs = if != 0, this function has varargs parameters\n     */\n    void mangleFunctionParameters(Parameters* parameters, int varargs)\n    {\n        int numparams = 0;\n\n        int paramsCppMangleDg(size_t n, Parameter fparam)\n        {\n            Type t = Target.cppParameterType(fparam);\n            if (t.ty == Tsarray)\n            {\n                // Static arrays in D are passed by value; no counterpart in C++\n                .error(loc, \"Internal Compiler Error: unable to pass static array `%s` to extern(C++) function, use pointer instead\",\n                    t.toChars());\n                fatal();\n            }\n            auto prev = this.context.push({\n                    auto tf = cast(TypeFunction)this.context.res.asFuncDecl().type;\n                    return (*tf.parameters)[n].type;\n                }());\n            scope (exit) this.context.pop(prev);\n            headOfType(t);\n            ++numparams;\n            return 0;\n        }\n\n        if (parameters)\n            Parameter._foreach(parameters, &paramsCppMangleDg);\n        if (varargs)\n            buf.writeByte('z');\n        else if (!numparams)\n            buf.writeByte('v'); // encode (void) parameters\n    }\n\n    /****** The rest is type mangling ************/\n\n    void error(Type t)\n    {\n        const(char)* p;\n        if (t.isImmutable())\n            p = \"`immutable` \";\n        else if (t.isShared())\n            p = \"`shared` \";\n        else\n            p = \"\";\n        .error(loc, \"Internal Compiler Error: %stype `%s` can not be mapped to C++\\n\", p, t.toChars());\n        fatal(); //Fatal, because this error should be handled in frontend\n    }\n\n    /****************************\n     * Mangle a type,\n     * treating it as a Head followed by a Tail.\n     * Params:\n     *  t = Head of a type\n     */\n    void headOfType(Type t)\n    {\n        if (t.ty == Tclass)\n        {\n            mangleTypeClass(cast(TypeClass)t, true);\n        }\n        else\n        {\n            // For value types, strip const/immutable/shared from the head of the type\n            auto prev = this.context.push(this.context.res.asType().mutableOf().unSharedOf());\n            scope (exit) this.context.pop(prev);\n            t.mutableOf().unSharedOf().accept(this);\n        }\n    }\n\n    /******\n     * Write out 1 or 2 character basic type mangling.\n     * Handle const and substitutions.\n     * Params:\n     *  t = type to mangle\n     *  p = if not 0, then character prefix\n     *  c = mangling character\n     */\n    void writeBasicType(Type t, char p, char c)\n    {\n        if (p || t.isConst())\n        {\n            if (substitute(t))\n                return;\n            else\n                append(t);\n        }\n        CV_qualifiers(t);\n        if (p)\n            buf.writeByte(p);\n        buf.writeByte(c);\n    }\n\n\n    /****************\n     * Write structs and enums.\n     * Params:\n     *  t = TypeStruct or TypeEnum\n     */\n    void doSymbol(Type t)\n    {\n        if (substitute(t))\n            return;\n        CV_qualifiers(t);\n\n        // Handle any target-specific struct types.\n        if (auto tm = Target.cppTypeMangle(t))\n        {\n            buf.writestring(tm);\n        }\n        else\n        {\n            Dsymbol s = t.toDsymbol(null);\n            Dsymbol p = s.toParent();\n            if (p && p.isTemplateInstance())\n            {\n                 /* https://issues.dlang.org/show_bug.cgi?id=17947\n                  * Substitute the template instance symbol, not the struct/enum symbol\n                  */\n                if (substitute(p))\n                    return;\n            }\n            if (!substitute(s))\n            {\n                cpp_mangle_name(s, false);\n            }\n        }\n        if (t.isConst())\n            append(t);\n    }\n\n\n\n    /************************\n     * Mangle a class type.\n     * If it's the head, treat the initial pointer as a value type.\n     * Params:\n     *  t = class type\n     *  head = true for head of a type\n     */\n    void mangleTypeClass(TypeClass t, bool head)\n    {\n        if (t.isImmutable() || t.isShared())\n            return error(t);\n\n        /* Mangle as a <pointer to><struct>\n         */\n        if (substitute(t))\n            return;\n        if (!head)\n            CV_qualifiers(t);\n        buf.writeByte('P');\n\n        CV_qualifiers(t);\n\n        {\n            Dsymbol s = t.toDsymbol(null);\n            Dsymbol p = s.toParent();\n            if (p && p.isTemplateInstance())\n            {\n                 /* https://issues.dlang.org/show_bug.cgi?id=17947\n                  * Substitute the template instance symbol, not the class symbol\n                  */\n                if (substitute(p))\n                    return;\n            }\n        }\n\n        if (!substitute(t.sym))\n        {\n            cpp_mangle_name(t.sym, false);\n        }\n        if (t.isConst())\n            append(null);  // C++ would have an extra type here\n        append(t);\n    }\n\n    /**\n     * Mangle the prefix of a nested (e.g. member) function\n     *\n     * Params:\n     *   tf = Type of the nested function\n     *   parent = Parent in which the function is nested\n     */\n    void mangleNestedFuncPrefix(TypeFunction tf, Dsymbol parent)\n    {\n        /* <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E\n         *               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E\n         */\n        buf.writeByte('N');\n        CV_qualifiers(tf);\n\n        /* <prefix> ::= <prefix> <unqualified-name>\n         *          ::= <template-prefix> <template-args>\n         *          ::= <template-param>\n         *          ::= # empty\n         *          ::= <substitution>\n         *          ::= <prefix> <data-member-prefix>\n         */\n        prefix_name(parent);\n    }\n\nextern(C++):\n\n    alias visit = Visitor.visit;\n\n    override void visit(TypeNull t)\n    {\n        if (t.isImmutable() || t.isShared())\n            return error(t);\n\n        writeBasicType(t, 'D', 'n');\n    }\n\n    override void visit(TypeBasic t)\n    {\n        if (t.isImmutable() || t.isShared())\n            return error(t);\n\n        /* <builtin-type>:\n         * v        void\n         * w        wchar_t\n         * b        bool\n         * c        char\n         * a        signed char\n         * h        unsigned char\n         * s        short\n         * t        unsigned short\n         * i        int\n         * j        unsigned int\n         * l        long\n         * m        unsigned long\n         * x        long long, __int64\n         * y        unsigned long long, __int64\n         * n        __int128\n         * o        unsigned __int128\n         * f        float\n         * d        double\n         * e        long double, __float80\n         * g        __float128\n         * z        ellipsis\n         * Dd       64 bit IEEE 754r decimal floating point\n         * De       128 bit IEEE 754r decimal floating point\n         * Df       32 bit IEEE 754r decimal floating point\n         * Dh       16 bit IEEE 754r half-precision floating point\n         * Di       char32_t\n         * Ds       char16_t\n         * u <source-name>  # vendor extended type\n         */\n        char c;\n        char p = 0;\n        switch (t.ty)\n        {\n            case Tvoid:                 c = 'v';        break;\n            case Tint8:                 c = 'a';        break;\n            case Tuns8:                 c = 'h';        break;\n            case Tint16:                c = 's';        break;\n            case Tuns16:                c = 't';        break;\n            case Tint32:                c = 'i';        break;\n            case Tuns32:                c = 'j';        break;\n            case Tfloat32:              c = 'f';        break;\n            case Tint64:\n                c = Target.c_longsize == 8 ? 'l' : 'x';\n                break;\n            case Tuns64:\n                c = Target.c_longsize == 8 ? 'm' : 'y';\n                break;\n            case Tint128:                c = 'n';       break;\n            case Tuns128:                c = 'o';       break;\n            case Tfloat64:               c = 'd';       break;\n            case Tfloat80:               c = 'e';       break;\n            case Tbool:                  c = 'b';       break;\n            case Tchar:                  c = 'c';       break;\n            case Twchar:                 c = 't';       break;  // unsigned short (perhaps use 'Ds' ?\n            case Tdchar:                 c = 'w';       break;  // wchar_t (UTF-32) (perhaps use 'Di' ?\n            case Timaginary32:  p = 'G'; c = 'f';       break;  // 'G' means imaginary\n            case Timaginary64:  p = 'G'; c = 'd';       break;\n            case Timaginary80:  p = 'G'; c = 'e';       break;\n            case Tcomplex32:    p = 'C'; c = 'f';       break;  // 'C' means complex\n            case Tcomplex64:    p = 'C'; c = 'd';       break;\n            case Tcomplex80:    p = 'C'; c = 'e';       break;\n\n            default:\n                // Handle any target-specific basic types.\n                if (auto tm = Target.cppTypeMangle(t))\n                {\n                    if (substitute(t))\n                        return;\n                    else\n                        append(t);\n                    CV_qualifiers(t);\n                    buf.writestring(tm);\n                    return;\n                }\n                return error(t);\n        }\n        writeBasicType(t, p, c);\n    }\n\n    override void visit(TypeVector t)\n    {\n        if (t.isImmutable() || t.isShared())\n            return error(t);\n\n        if (substitute(t))\n            return;\n        append(t);\n        CV_qualifiers(t);\n\n        // Handle any target-specific vector types.\n        if (auto tm = Target.cppTypeMangle(t))\n        {\n            buf.writestring(tm);\n        }\n        else\n        {\n            assert(t.basetype && t.basetype.ty == Tsarray);\n            assert((cast(TypeSArray)t.basetype).dim);\n            version (none)\n            {\n                buf.writestring(\"Dv\");\n                buf.print((cast(TypeSArray *)t.basetype).dim.toInteger()); // -- Gnu ABI v.4\n                buf.writeByte('_');\n            }\n            else\n                buf.writestring(\"U8__vector\"); //-- Gnu ABI v.3\n            t.basetype.nextOf().accept(this);\n        }\n    }\n\n    override void visit(TypeSArray t)\n    {\n        if (t.isImmutable() || t.isShared())\n            return error(t);\n\n        if (!substitute(t))\n            append(t);\n        CV_qualifiers(t);\n        buf.writeByte('A');\n        buf.print(t.dim ? t.dim.toInteger() : 0);\n        buf.writeByte('_');\n        t.next.accept(this);\n    }\n\n    override void visit(TypePointer t)\n    {\n        if (t.isImmutable() || t.isShared())\n            return error(t);\n\n        if (substitute(t))\n            return;\n        CV_qualifiers(t);\n        buf.writeByte('P');\n        auto prev = this.context.push(this.context.res.asType().nextOf());\n        scope (exit) this.context.pop(prev);\n        t.next.accept(this);\n        append(t);\n    }\n\n    override void visit(TypeReference t)\n    {\n        if (substitute(t))\n            return;\n        buf.writeByte('R');\n        auto prev = this.context.push(this.context.res.asType().nextOf());\n        scope (exit) this.context.pop(prev);\n        t.next.accept(this);\n        append(t);\n    }\n\n    override void visit(TypeFunction t)\n    {\n        /*\n         *  <function-type> ::= F [Y] <bare-function-type> E\n         *  <bare-function-type> ::= <signature type>+\n         *  # types are possible return type, then parameter types\n         */\n        /* ABI says:\n            \"The type of a non-static member function is considered to be different,\n            for the purposes of substitution, from the type of a namespace-scope or\n            static member function whose type appears similar. The types of two\n            non-static member functions are considered to be different, for the\n            purposes of substitution, if the functions are members of different\n            classes. In other words, for the purposes of substitution, the class of\n            which the function is a member is considered part of the type of\n            function.\"\n\n            BUG: Right now, types of functions are never merged, so our simplistic\n            component matcher always finds them to be different.\n            We should use Type.equals on these, and use different\n            TypeFunctions for non-static member functions, and non-static\n            member functions of different classes.\n         */\n        if (substitute(t))\n            return;\n        buf.writeByte('F');\n        if (t.linkage == LINK.c)\n            buf.writeByte('Y');\n        Type tn = t.next;\n        if (t.isref)\n            tn = tn.referenceTo();\n        tn.accept(this);\n        mangleFunctionParameters(t.parameters, t.varargs);\n        buf.writeByte('E');\n        append(t);\n    }\n\n    override void visit(TypeStruct t)\n    {\n        if (t.isImmutable() || t.isShared())\n            return error(t);\n\n        /* __c_long and __c_ulong get special mangling\n         */\n        const id = t.sym.ident;\n        //printf(\"struct id = '%s'\\n\", id.toChars());\n        if (id == Id.__c_long)\n            return writeBasicType(t, 0, 'l');\n        else if (id == Id.__c_ulong)\n            return writeBasicType(t, 0, 'm');\n\n        //printf(\"TypeStruct %s\\n\", t.toChars());\n        doSymbol(t);\n    }\n\n    override void visit(TypeEnum t)\n    {\n        if (t.isImmutable() || t.isShared())\n            return error(t);\n\n        /* __c_(u)long(long) get special mangling\n         */\n        const id = t.sym.ident;\n        //printf(\"enum id = '%s'\\n\", id.toChars());\n        if (id == Id.__c_long)\n            return writeBasicType(t, 0, 'l');\n        else if (id == Id.__c_ulong)\n            return writeBasicType(t, 0, 'm');\n        else if (id == Id.__c_longlong)\n            return writeBasicType(t, 0, 'x');\n        else if (id == Id.__c_ulonglong)\n            return writeBasicType(t, 0, 'y');\n\n        doSymbol(t);\n    }\n\n    override void visit(TypeClass t)\n    {\n        mangleTypeClass(t, false);\n    }\n\n    /**\n     * Performs template parameter substitution\n     *\n     * Mangling is performed on a copy of the post-parsing AST before\n     * any semantic pass is run.\n     * There is no easy way to link a type to the template parameters\n     * once semantic has run, because:\n     * - the `TemplateInstance` installs aliases in its scope to its params\n     * - `AliasDeclaration`s are resolved in many places\n     * - semantic passes are destructive, so the `TypeIdentifier` gets lost\n     *\n     * As a result, the best approach with the current architecture is to:\n     * - Run the visitor on the `originalType` of the function,\n     *   looking up any `TypeIdentifier` at the template scope when found.\n     * - Fallback to the post-semantic `TypeFunction` when the identifier is\n     *   not a template parameter.\n     */\n    override void visit(TypeIdentifier t)\n    {\n        auto decl = cast(TemplateDeclaration)this.context.ti.tempdecl;\n        assert(decl.parameters !is null);\n        // If not found, default to the post-semantic type\n        if (!this.writeTemplateSubstitution(t.ident, decl.parameters, this.context.res.isType()))\n            this.context.res.visitObject(this);\n    }\n\n    /// Ditto\n    override void visit(TypeInstance t)\n    {\n        assert(t.tempinst !is null);\n        t.tempinst.accept(this);\n    }\n\n    /// Ditto\n    override void visit(TemplateInstance t)\n    {\n        assert(t.name !is null);\n        assert(t.tiargs !is null);\n\n        if (this.substitute(t))\n            return;\n        auto topdecl = cast(TemplateDeclaration)this.context.ti.tempdecl;\n        // Template names are substituted, but args still need to be written\n        bool needclosing;\n        if (!this.writeTemplateSubstitution(t.name, topdecl.parameters, t.getType()))\n        {\n            needclosing = this.writeQualified(t);\n            this.append(t);\n        }\n        buf.writeByte('I');\n        // When visiting the arguments, the context will be set to the\n        // resolved type\n        auto analyzed_ti = this.context.res.asType().toDsymbol(null).isInstantiated();\n        auto prev = this.context;\n        scope (exit) this.context.pop(prev);\n        foreach (idx, RootObject o; *t.tiargs)\n        {\n            this.context.res = (*analyzed_ti.tiargs)[idx];\n            o.visitObject(this);\n        }\n        if (analyzed_ti.tiargs.dim > t.tiargs.dim)\n        {\n            // If the resolved AST has more args than the parse one,\n            // we have default arguments\n            auto oparams = (cast(TemplateDeclaration)analyzed_ti.tempdecl).origParameters;\n            foreach (idx, arg; (*oparams)[t.tiargs.dim .. $])\n            {\n                this.context.res = (*analyzed_ti.tiargs)[idx + t.tiargs.dim];\n\n                if (auto ttp = arg.isTemplateTypeParameter())\n                    ttp.defaultType.accept(this);\n                else if (auto tvp = arg.isTemplateValueParameter())\n                    tvp.defaultValue.accept(this);\n                else if (auto tvp = arg.isTemplateThisParameter())\n                    tvp.defaultType.accept(this);\n                else if (auto tvp = arg.isTemplateAliasParameter())\n                    tvp.defaultAlias.visitObject(this);\n                else\n                    assert(0, arg.toString());\n            }\n        }\n        buf.writeByte('E');\n        if (needclosing)\n            buf.writeByte('E');\n    }\n\n    /// Ditto\n    override void visit(IntegerExp t)\n    {\n        this.buf.writeByte('L');\n        t.type.accept(this);\n        this.buf.print(t.getInteger());\n        this.buf.writeByte('E');\n    }\n\n    override void visit(Nspace t)\n    {\n        if (auto p = getQualifier(t))\n            p.accept(this);\n\n        if (isStd(t))\n            buf.writestring(\"St\");\n        else\n        {\n            this.writeIdentifier(t.ident);\n            this.append(t);\n        }\n    }\n\n    override void visit(Type t)\n    {\n        error(t);\n    }\n\n    void visit(Tuple t)\n    {\n        assert(0);\n    }\n\n    /**\n     * Helper function to go through the `TemplateParameter`s and perform\n     * a substitution, if possible.\n     *\n     * Params:\n     *   ident = Identifier for which substitution is attempted\n     *           (e.g. `void func(T)(T param)` => `T` from `T param`)\n     *   params = `TemplateParameters` of the enclosing symbol\n     *           (in the previous example, `func`'s template parameters)\n     *   type = Resolved type of `T`, so that `void func(T)(const T)`\n     *          gets mangled correctly\n     *\n     * Returns:\n     *   `true` if something was written to the buffer\n     */\n    private bool writeTemplateSubstitution(const ref Identifier ident,\n        TemplateParameters* params, Type type)\n    {\n        foreach (idx, param; *params)\n        {\n            if (param.ident == ident)\n            {\n                if (type)\n                    CV_qualifiers(type);\n                if (this.substitute(param))\n                    return true;\n                this.append(param);\n\n                // expressions are mangled in <X..E>\n                if (param.isTemplateValueParameter())\n                    buf.writeByte('X');\n                buf.writeByte('T');\n                writeSequenceFromIndex(idx);\n                buf.writeByte('_');\n                if (param.isTemplateValueParameter())\n                    buf.writeByte('E');\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Given a template instance `t`, write its qualified name\n     * without the template parameter list\n     *\n     * Params:\n     *   t = Post-parsing `TemplateInstance` pointing to the symbol\n     *       to mangle (one level deep)\n     *\n     * Returns:\n     *   `true` if the name was qualified and requires an ending `E`\n     */\n    private bool writeQualified(TemplateInstance t)\n    {\n        auto type = isType(this.context.res);\n        if (!type)\n        {\n            this.writeIdentifier(t.name);\n            return false;\n        }\n        auto sym = type.toDsymbol(null);\n        if (!sym)\n        {\n            this.writeIdentifier(t.name);\n            return false;\n        }\n        // Get the template instance\n        sym = getQualifier(sym);\n        auto sym2 = getQualifier(sym);\n        if (sym2)\n        {\n            if (isStd(sym2))\n            {\n                bool unused;\n                assert(sym.isTemplateInstance());\n                if (this.writeStdSubstitution(sym.isTemplateInstance(), unused))\n                    return false;\n                // std names don't require `N..E`\n                buf.writestring(\"St\");\n                this.writeIdentifier(t.name);\n                return false;\n            }\n            buf.writestring(\"N\");\n            if (!this.substitute(sym2))\n                sym2.accept(this);\n        }\n        this.writeIdentifier(t.name);\n        return sym2 !is null;\n    }\n}\n\n/// Helper code to visit `RootObject`, as it doesn't define `accept`,\n/// only its direct subtypes do.\nprivate void visitObject(V : Visitor)(RootObject o, V this_)\n{\n    assert(o !is null);\n    if (Type ta = isType(o))\n        ta.accept(this_);\n    else if (Expression ea = isExpression(o))\n        ea.accept(this_);\n    else if (Dsymbol sa = isDsymbol(o))\n        sa.accept(this_);\n    else if (TemplateParameter t = isTemplateParameter(o))\n        t.accept(this_);\n    else if (Tuple t = isTuple(o))\n        // `Tuple` inherits `RootObject` and does not define accept\n        // For this reason, this uses static dispatch on the visitor\n        this_.visit(t);\n    else\n        assert(0, o.toString());\n}\n\n/// Helper function to safely get a type out of a `RootObject`\nprivate Type asType(RootObject o)\n{\n    Type ta = isType(o);\n    assert(ta !is null, o.toString());\n    return ta;\n}\n\n/// Helper function to safely get a `FuncDeclaration` out of a `RootObject`\nprivate FuncDeclaration asFuncDecl(RootObject o)\n{\n    Dsymbol d = isDsymbol(o);\n    assert(d !is null);\n    auto fd = d.isFuncDeclaration();\n    assert(fd !is null);\n    return fd;\n}\n\n/// Helper class to compare entries in components\nprivate extern(C++) final class ComponentVisitor : Visitor\n{\n    /// Only one of the following is not `null`, it's always\n    /// the most specialized type, set from the ctor\n    private Nspace namespace;\n\n    /// Ditto\n    private TypePointer tpointer;\n\n    /// Ditto\n    private TypeReference tref;\n\n    /// Ditto\n    private TypeIdentifier tident;\n\n    /// Least specialized type\n    private RootObject object;\n\n    /// Set to the result of the comparison\n    private bool result;\n\n    public this(RootObject base)\n    {\n        switch (base.dyncast())\n        {\n        case DYNCAST.dsymbol:\n            if (auto ns = (cast(Dsymbol)base).isNspace())\n                this.namespace = ns;\n            else\n                goto default;\n            break;\n\n        case DYNCAST.type:\n            auto t = cast(Type)base;\n            if (t.ty == Tpointer)\n                this.tpointer = cast(TypePointer)t;\n            else if (t.ty == Treference)\n                this.tref = cast(TypeReference)t;\n            else if (t.ty == Tident)\n                this.tident = cast(TypeIdentifier)t;\n            else\n                goto default;\n            break;\n\n        default:\n            this.object = base;\n        }\n    }\n\n    /// Introduce base class overloads\n    alias visit = Visitor.visit;\n\n    /// Least specialized overload of each direct child of `RootObject`\n    public override void visit(Dsymbol o)\n    {\n        this.result = this.object && this.object == o;\n    }\n\n    /// Ditto\n    public override void visit(Expression o)\n    {\n        this.result = this.object && this.object == o;\n    }\n\n    /// Ditto\n    public void visit(Tuple o)\n    {\n        this.result = this.object && this.object == o;\n    }\n\n    /// Ditto\n    public override void visit(Type o)\n    {\n        this.result = this.object && this.object == o;\n    }\n\n    /// Ditto\n    public override void visit(TemplateParameter o)\n    {\n        this.result = this.object && this.object == o;\n    }\n\n    /**\n     * This overload handles composed types including template parameters\n     *\n     * Components for substitutions include \"next\" type.\n     * For example, if `ref T` is present, `ref T` and `T` will be present\n     * in the substitution array.\n     * But since we don't have the final/merged type, we cannot rely on\n     * object comparison, and need to recurse instead.\n     */\n    public override void visit(TypeReference o)\n    {\n        if (!this.tref)\n            return;\n        if (this.tref == o)\n            this.result = true;\n        else\n        {\n            // It might be a reference to a template parameter that we already\n            // saw, so we need to recurse\n            scope v = new ComponentVisitor(this.tref.next);\n            o.next.visitObject(v);\n            this.result = v.result;\n        }\n    }\n\n    /// Ditto\n    public override void visit(TypePointer o)\n    {\n        if (!this.tpointer)\n            return;\n        if (this.tpointer == o)\n            this.result = true;\n        else\n        {\n            // It might be a pointer to a template parameter that we already\n            // saw, so we need to recurse\n            scope v = new ComponentVisitor(this.tpointer.next);\n            o.next.visitObject(v);\n            this.result = v.result;\n        }\n    }\n\n    /// Ditto\n    public override void visit(TypeIdentifier o)\n    {\n        /// Since we know they are at the same level, scope resolution will\n        /// give us the same symbol, thus we can just compare ident.\n        this.result = (this.tident && (this.tident.ident == o.ident));\n    }\n\n    /**\n     * Overload which accepts a Namespace\n     *\n     * It is very common for large C++ projects to have multiple files sharing\n     * the same `namespace`. If any D project adopts the same approach\n     * (e.g. separating data structures from functions), it will lead to two\n     * `Nspace` objects being instantiated, with different addresses.\n     * At the same time, we cannot compare just any Dsymbol via identifier,\n     * because it messes with templates.\n     *\n     * See_Also:\n     *  https://issues.dlang.org/show_bug.cgi?id=18922\n     *\n     * Params:\n     *   ns = C++ namespace to do substitution for\n     */\n    public override void visit(Nspace ns)\n    {\n        this.result = this.namespace && this.namespace.equals(ns);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/ctfe.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/ctfe.h\n */\n\n#pragma once\n\n#include \"tokens.h\"\n#include \"expression.h\"\n\n/**\n  A reference to a class, or an interface. We need this when we\n  point to a base class (we must record what the type is).\n */\nclass ClassReferenceExp : public Expression\n{\npublic:\n    StructLiteralExp *value;\n    ClassDeclaration *originalClass();\n\n    /// Return index of the field, or -1 if not found\n    /// Same as getFieldIndex, but checks for a direct match with the VarDeclaration\n    int findFieldIndexByName(VarDeclaration *v);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/**\n  An uninitialized value\n */\nclass VoidInitExp : public Expression\n{\npublic:\n    VarDeclaration *var;\n\n    const char *toChars();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/**\n  Fake class which holds the thrown exception.\n  Used for implementing exception handling.\n*/\nclass ThrownExceptionExp : public Expression\n{\npublic:\n    ClassReferenceExp *thrown; // the thing being tossed\n    const char *toChars();\n    /// Generate an error message when this exception is not caught\n    void generateUncaughtError();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/****************************************************************/\n\n// This type is only used by the interpreter.\n\nclass CTFEExp : public Expression\n{\npublic:\n    const char *toChars();\n};\n"
  },
  {
    "path": "gcc/d/dmd/ctfeexpr.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/ctfeexpr.d, _ctfeexpr.d)\n * Documentation:  https://dlang.org/phobos/dmd_ctfeexpr.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/ctfeexpr.d\n */\n\nmodule dmd.ctfeexpr;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.arraytypes;\nimport dmd.complex;\nimport dmd.constfold;\nimport dmd.compiler;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dinterpret;\nimport dmd.dstruct;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.mtype;\nimport dmd.root.ctfloat;\nimport dmd.root.port;\nimport dmd.root.rmem;\nimport dmd.tokens;\nimport dmd.visitor;\n\n/***********************************************************\n * Global status of the CTFE engine. Mostly used for performance diagnostics\n */\nstruct CtfeStatus\n{\n    __gshared int callDepth = 0;        // current number of recursive calls\n\n    // When printing a stack trace, suppress this number of calls\n    __gshared int stackTraceCallsToSuppress = 0;\n\n    __gshared int maxCallDepth = 0;     // highest number of recursive calls\n    __gshared int numArrayAllocs = 0;   // Number of allocated arrays\n    __gshared int numAssignments = 0;   // total number of assignments executed\n}\n\n/***********************************************************\n * A reference to a class, or an interface. We need this when we\n * point to a base class (we must record what the type is).\n */\nextern (C++) final class ClassReferenceExp : Expression\n{\n    StructLiteralExp value;\n\n    extern (D) this(const ref Loc loc, StructLiteralExp lit, Type type)\n    {\n        super(loc, TOK.classReference, __traits(classInstanceSize, ClassReferenceExp));\n        assert(lit && lit.sd && lit.sd.isClassDeclaration());\n        this.value = lit;\n        this.type = type;\n    }\n\n    ClassDeclaration originalClass()\n    {\n        return value.sd.isClassDeclaration();\n    }\n\n    // Return index of the field, or -1 if not found\n    private int getFieldIndex(Type fieldtype, uint fieldoffset)\n    {\n        ClassDeclaration cd = originalClass();\n        uint fieldsSoFar = 0;\n        for (size_t j = 0; j < value.elements.dim; j++)\n        {\n            while (j - fieldsSoFar >= cd.fields.dim)\n            {\n                fieldsSoFar += cd.fields.dim;\n                cd = cd.baseClass;\n            }\n            VarDeclaration v2 = cd.fields[j - fieldsSoFar];\n            if (fieldoffset == v2.offset && fieldtype.size() == v2.type.size())\n            {\n                return cast(int)(value.elements.dim - fieldsSoFar - cd.fields.dim + (j - fieldsSoFar));\n            }\n        }\n        return -1;\n    }\n\n    // Return index of the field, or -1 if not found\n    // Same as getFieldIndex, but checks for a direct match with the VarDeclaration\n    int findFieldIndexByName(VarDeclaration v)\n    {\n        ClassDeclaration cd = originalClass();\n        size_t fieldsSoFar = 0;\n        for (size_t j = 0; j < value.elements.dim; j++)\n        {\n            while (j - fieldsSoFar >= cd.fields.dim)\n            {\n                fieldsSoFar += cd.fields.dim;\n                cd = cd.baseClass;\n            }\n            VarDeclaration v2 = cd.fields[j - fieldsSoFar];\n            if (v == v2)\n            {\n                return cast(int)(value.elements.dim - fieldsSoFar - cd.fields.dim + (j - fieldsSoFar));\n            }\n        }\n        return -1;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/*************************\n * Same as getFieldIndex, but checks for a direct match with the VarDeclaration\n * Returns:\n *    index of the field, or -1 if not found\n */\nint findFieldIndexByName(const StructDeclaration sd, const VarDeclaration v) pure\n{\n    foreach (i, field; sd.fields)\n    {\n        if (field == v)\n            return cast(int)i;\n    }\n    return -1;\n}\n\n/***********************************************************\n * Fake class which holds the thrown exception.\n * Used for implementing exception handling.\n */\nextern (C++) final class ThrownExceptionExp : Expression\n{\n    ClassReferenceExp thrown;   // the thing being tossed\n\n    extern (D) this(const ref Loc loc, ClassReferenceExp victim)\n    {\n        super(loc, TOK.thrownException, __traits(classInstanceSize, ThrownExceptionExp));\n        this.thrown = victim;\n        this.type = victim.type;\n    }\n\n    override const(char)* toChars() const\n    {\n        return \"CTFE ThrownException\";\n    }\n\n    // Generate an error message when this exception is not caught\n    void generateUncaughtError()\n    {\n        UnionExp ue = void;\n        Expression e = resolveSlice((*thrown.value.elements)[0], &ue);\n        StringExp se = e.toStringExp();\n        thrown.error(\"uncaught CTFE exception `%s(%s)`\", thrown.type.toChars(), se ? se.toChars() : e.toChars());\n        /* Also give the line where the throw statement was. We won't have it\n         * in the case where the ThrowStatement is generated internally\n         * (eg, in ScopeStatement)\n         */\n        if (loc.isValid() && !loc.equals(thrown.loc))\n            .errorSupplemental(loc, \"thrown from here\");\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * This type is only used by the interpreter.\n */\nextern (C++) final class CTFEExp : Expression\n{\n    extern (D) this(TOK tok)\n    {\n        super(Loc.initial, tok, __traits(classInstanceSize, CTFEExp));\n        type = Type.tvoid;\n    }\n\n    override const(char)* toChars() const\n    {\n        switch (op)\n        {\n        case TOK.cantExpression:\n            return \"<cant>\";\n        case TOK.voidExpression:\n            return \"<void>\";\n        case TOK.showCtfeContext:\n            return \"<error>\";\n        case TOK.break_:\n            return \"<break>\";\n        case TOK.continue_:\n            return \"<continue>\";\n        case TOK.goto_:\n            return \"<goto>\";\n        default:\n            assert(0);\n        }\n    }\n\n    extern (D) __gshared CTFEExp cantexp;\n    extern (D) __gshared CTFEExp voidexp;\n    extern (D) __gshared CTFEExp breakexp;\n    extern (D) __gshared CTFEExp continueexp;\n    extern (D) __gshared CTFEExp gotoexp;\n    /* Used when additional information is needed regarding\n     * a ctfe error.\n     */\n    extern (D) __gshared CTFEExp showcontext;\n\n    extern (D) static bool isCantExp(const Expression e)\n    {\n        return e && e.op == TOK.cantExpression;\n    }\n\n    extern (D) static bool isGotoExp(const Expression e)\n    {\n        return e && e.op == TOK.goto_;\n    }\n}\n\n// True if 'e' is CTFEExp::cantexp, or an exception\nbool exceptionOrCantInterpret(const Expression e)\n{\n    return e && (e.op == TOK.cantExpression || e.op == TOK.thrownException || e.op == TOK.showCtfeContext);\n}\n\n/************** Aggregate literals (AA/string/array/struct) ******************/\n// Given expr, which evaluates to an array/AA/string literal,\n// return true if it needs to be copied\nbool needToCopyLiteral(const Expression expr)\n{\n    Expression e = cast()expr;\n    for (;;)\n    {\n        switch (e.op)\n        {\n        case TOK.arrayLiteral:\n            return (cast(ArrayLiteralExp)e).ownedByCtfe == OwnedBy.code;\n        case TOK.assocArrayLiteral:\n            return (cast(AssocArrayLiteralExp)e).ownedByCtfe == OwnedBy.code;\n        case TOK.structLiteral:\n            return (cast(StructLiteralExp)e).ownedByCtfe == OwnedBy.code;\n        case TOK.string_:\n        case TOK.this_:\n        case TOK.variable:\n            return false;\n        case TOK.assign:\n            return false;\n        case TOK.index:\n        case TOK.dotVariable:\n        case TOK.slice:\n        case TOK.cast_:\n            e = (cast(UnaExp)e).e1;\n            continue;\n        case TOK.concatenate:\n            return needToCopyLiteral((cast(BinExp)e).e1) || needToCopyLiteral((cast(BinExp)e).e2);\n        case TOK.concatenateAssign:\n        case TOK.concatenateElemAssign:\n        case TOK.concatenateDcharAssign:\n            e = (cast(BinExp)e).e2;\n            continue;\n        default:\n            return false;\n        }\n    }\n}\n\nprivate Expressions* copyLiteralArray(Expressions* oldelems, Expression basis = null)\n{\n    if (!oldelems)\n        return oldelems;\n    CtfeStatus.numArrayAllocs++;\n    auto newelems = new Expressions(oldelems.dim);\n    foreach (i, el; *oldelems)\n    {\n        (*newelems)[i] = copyLiteral(el ? el : basis).copy();\n    }\n    return newelems;\n}\n\n// Make a copy of the ArrayLiteral, AALiteral, String, or StructLiteral.\n// This value will be used for in-place modification.\nUnionExp copyLiteral(Expression e)\n{\n    UnionExp ue;\n    if (e.op == TOK.string_) // syntaxCopy doesn't make a copy for StringExp!\n    {\n        StringExp se = cast(StringExp)e;\n        char* s = cast(char*)mem.xcalloc(se.len + 1, se.sz);\n        memcpy(s, se.string, se.len * se.sz);\n        emplaceExp!(StringExp)(&ue, se.loc, s, se.len);\n        StringExp se2 = cast(StringExp)ue.exp();\n        se2.committed = se.committed;\n        se2.postfix = se.postfix;\n        se2.type = se.type;\n        se2.sz = se.sz;\n        se2.ownedByCtfe = OwnedBy.ctfe;\n        return ue;\n    }\n    if (e.op == TOK.arrayLiteral)\n    {\n        auto ale = cast(ArrayLiteralExp)e;\n        auto elements = copyLiteralArray(ale.elements, ale.basis);\n\n        emplaceExp!(ArrayLiteralExp)(&ue, e.loc, e.type, elements);\n\n        ArrayLiteralExp r = cast(ArrayLiteralExp)ue.exp();\n        r.ownedByCtfe = OwnedBy.ctfe;\n        return ue;\n    }\n    if (e.op == TOK.assocArrayLiteral)\n    {\n        AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)e;\n        emplaceExp!(AssocArrayLiteralExp)(&ue, e.loc, copyLiteralArray(aae.keys), copyLiteralArray(aae.values));\n        AssocArrayLiteralExp r = cast(AssocArrayLiteralExp)ue.exp();\n        r.type = e.type;\n        r.ownedByCtfe = OwnedBy.ctfe;\n        return ue;\n    }\n    if (e.op == TOK.structLiteral)\n    {\n        /* syntaxCopy doesn't work for struct literals, because of a nasty special\n         * case: block assignment is permitted inside struct literals, eg,\n         * an int[4] array can be initialized with a single int.\n         */\n        auto sle = cast(StructLiteralExp)e;\n        auto oldelems = sle.elements;\n        auto newelems = new Expressions(oldelems.dim);\n        foreach (i, ref el; *newelems)\n        {\n            // We need the struct definition to detect block assignment\n            auto v = sle.sd.fields[i];\n            auto m = (*oldelems)[i];\n\n            // If it is a void assignment, use the default initializer\n            if (!m)\n                m = voidInitLiteral(v.type, v).copy();\n\n            if (v.type.ty == Tarray || v.type.ty == Taarray)\n            {\n                // Don't have to copy array references\n            }\n            else\n            {\n                // Buzilla 15681: Copy the source element always.\n                m = copyLiteral(m).copy();\n\n                // Block assignment from inside struct literals\n                if (v.type.ty != m.type.ty && v.type.ty == Tsarray)\n                {\n                    auto tsa = cast(TypeSArray)v.type;\n                    auto len = cast(size_t)tsa.dim.toInteger();\n                    m = createBlockDuplicatedArrayLiteral(e.loc, v.type, m, len);\n                }\n            }\n            el = m;\n        }\n        emplaceExp!(StructLiteralExp)(&ue, e.loc, sle.sd, newelems, sle.stype);\n        auto r = cast(StructLiteralExp)ue.exp();\n        r.type = e.type;\n        r.ownedByCtfe = OwnedBy.ctfe;\n        r.origin = (cast(StructLiteralExp)e).origin;\n        return ue;\n    }\n    if (e.op == TOK.function_ || e.op == TOK.delegate_ || e.op == TOK.symbolOffset || e.op == TOK.null_ || e.op == TOK.variable || e.op == TOK.dotVariable || e.op == TOK.int64 || e.op == TOK.float64 || e.op == TOK.char_ || e.op == TOK.complex80 || e.op == TOK.void_ || e.op == TOK.vector || e.op == TOK.typeid_)\n    {\n        // Simple value types\n        // Keep e1 for DelegateExp and DotVarExp\n        emplaceExp!(UnionExp)(&ue, e);\n        Expression r = ue.exp();\n        r.type = e.type;\n        return ue;\n    }\n    if (e.op == TOK.slice)\n    {\n        SliceExp se = cast(SliceExp)e;\n        if (se.type.toBasetype().ty == Tsarray)\n        {\n            // same with resolveSlice()\n            if (se.e1.op == TOK.null_)\n            {\n                emplaceExp!(NullExp)(&ue, se.loc, se.type);\n                return ue;\n            }\n            ue = Slice(se.type, se.e1, se.lwr, se.upr);\n            assert(ue.exp().op == TOK.arrayLiteral);\n            ArrayLiteralExp r = cast(ArrayLiteralExp)ue.exp();\n            r.elements = copyLiteralArray(r.elements);\n            r.ownedByCtfe = OwnedBy.ctfe;\n            return ue;\n        }\n        else\n        {\n            // Array slices only do a shallow copy\n            emplaceExp!(SliceExp)(&ue, e.loc, se.e1, se.lwr, se.upr);\n            Expression r = ue.exp();\n            r.type = e.type;\n            return ue;\n        }\n    }\n    if (isPointer(e.type))\n    {\n        // For pointers, we only do a shallow copy.\n        if (e.op == TOK.address)\n            emplaceExp!(AddrExp)(&ue, e.loc, (cast(AddrExp)e).e1);\n        else if (e.op == TOK.index)\n            emplaceExp!(IndexExp)(&ue, e.loc, (cast(IndexExp)e).e1, (cast(IndexExp)e).e2);\n        else if (e.op == TOK.dotVariable)\n        {\n            emplaceExp!(DotVarExp)(&ue, e.loc, (cast(DotVarExp)e).e1, (cast(DotVarExp)e).var, (cast(DotVarExp)e).hasOverloads);\n        }\n        else\n            assert(0);\n\n        Expression r = ue.exp();\n        r.type = e.type;\n        return ue;\n    }\n    if (e.op == TOK.classReference)\n    {\n        emplaceExp!(ClassReferenceExp)(&ue, e.loc, (cast(ClassReferenceExp)e).value, e.type);\n        return ue;\n    }\n    if (e.op == TOK.error)\n    {\n        emplaceExp!(UnionExp)(&ue, e);\n        return ue;\n    }\n    e.error(\"CTFE internal error: literal `%s`\", e.toChars());\n    assert(0);\n}\n\n/* Deal with type painting.\n * Type painting is a major nuisance: we can't just set\n * e.type = type, because that would change the original literal.\n * But, we can't simply copy the literal either, because that would change\n * the values of any pointers.\n */\nExpression paintTypeOntoLiteral(Type type, Expression lit)\n{\n    if (lit.type.equals(type))\n        return lit;\n    return paintTypeOntoLiteralCopy(type, lit).copy();\n}\n\nprivate UnionExp paintTypeOntoLiteralCopy(Type type, Expression lit)\n{\n    UnionExp ue;\n    if (lit.type.equals(type))\n    {\n        emplaceExp!(UnionExp)(&ue, lit);\n        return ue;\n    }\n    // If it is a cast to inout, retain the original type of the referenced part.\n    if (type.hasWild() && type.hasPointers())\n    {\n        emplaceExp!(UnionExp)(&ue, lit);\n        ue.exp().type = type;\n        return ue;\n    }\n    if (lit.op == TOK.slice)\n    {\n        SliceExp se = cast(SliceExp)lit;\n        emplaceExp!(SliceExp)(&ue, lit.loc, se.e1, se.lwr, se.upr);\n    }\n    else if (lit.op == TOK.index)\n    {\n        IndexExp ie = cast(IndexExp)lit;\n        emplaceExp!(IndexExp)(&ue, lit.loc, ie.e1, ie.e2);\n    }\n    else if (lit.op == TOK.arrayLiteral)\n    {\n        emplaceExp!(SliceExp)(&ue, lit.loc, lit, new IntegerExp(Loc.initial, 0, Type.tsize_t), ArrayLength(Type.tsize_t, lit).copy());\n    }\n    else if (lit.op == TOK.string_)\n    {\n        // For strings, we need to introduce another level of indirection\n        emplaceExp!(SliceExp)(&ue, lit.loc, lit, new IntegerExp(Loc.initial, 0, Type.tsize_t), ArrayLength(Type.tsize_t, lit).copy());\n    }\n    else if (lit.op == TOK.assocArrayLiteral)\n    {\n        AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)lit;\n        // TODO: we should be creating a reference to this AAExp, not\n        // just a ref to the keys and values.\n        OwnedBy wasOwned = aae.ownedByCtfe;\n        emplaceExp!(AssocArrayLiteralExp)(&ue, lit.loc, aae.keys, aae.values);\n        aae = cast(AssocArrayLiteralExp)ue.exp();\n        aae.ownedByCtfe = wasOwned;\n    }\n    else\n    {\n        // Can't type paint from struct to struct*; this needs another\n        // level of indirection\n        if (lit.op == TOK.structLiteral && isPointer(type))\n            lit.error(\"CTFE internal error: painting `%s`\", type.toChars());\n        ue = copyLiteral(lit);\n    }\n    ue.exp().type = type;\n    return ue;\n}\n\n/*************************************\n * If e is a SliceExp, constant fold it.\n * Params:\n *      e = expression to resolve\n *      pue = if not null, store resulting expression here\n * Returns:\n *      resulting expression\n */\nExpression resolveSlice(Expression e, UnionExp* pue = null)\n{\n    if (e.op != TOK.slice)\n        return e;\n    SliceExp se = cast(SliceExp)e;\n    if (se.e1.op == TOK.null_)\n        return se.e1;\n    if (pue)\n    {\n        *pue = Slice(e.type, se.e1, se.lwr, se.upr);\n        return pue.exp();\n    }\n    else\n        return Slice(e.type, se.e1, se.lwr, se.upr).copy();\n}\n\n/* Determine the array length, without interpreting it.\n * e must be an array literal, or a slice\n * It's very wasteful to resolve the slice when we only\n * need the length.\n */\nuinteger_t resolveArrayLength(const Expression e)\n{\n    switch (e.op)\n    {\n        case TOK.vector:\n            return resolveArrayLength((cast(VectorExp)e).e1);\n\n        case TOK.null_:\n            return 0;\n\n        case TOK.slice:\n        {\n            const ilo = (cast(SliceExp)e).lwr.toInteger();\n            const iup = (cast(SliceExp)e).upr.toInteger();\n            return iup - ilo;\n        }\n\n        case TOK.string_:\n            return (cast(StringExp)e).len;\n\n        case TOK.arrayLiteral:\n        {\n            const ale = cast(ArrayLiteralExp)e;\n            return ale.elements ? ale.elements.dim : 0;\n        }\n\n        case TOK.assocArrayLiteral:\n        {\n            const ale = cast(AssocArrayLiteralExp)e;\n            return ale.keys.dim;\n        }\n\n        default:\n            assert(0);\n    }\n}\n\n/******************************\n * Helper for NewExp\n * Create an array literal consisting of 'elem' duplicated 'dim' times.\n * Params:\n *      loc = source location where the interpretation occurs\n *      type = target type of the result\n *      elem = the source of array element, it will be owned by the result\n *      dim = element number of the result\n * Returns:\n *      Constructed ArrayLiteralExp\n */\nArrayLiteralExp createBlockDuplicatedArrayLiteral(const ref Loc loc, Type type, Expression elem, size_t dim)\n{\n    if (type.ty == Tsarray && type.nextOf().ty == Tsarray && elem.type.ty != Tsarray)\n    {\n        // If it is a multidimensional array literal, do it recursively\n        auto tsa = cast(TypeSArray)type.nextOf();\n        const len = cast(size_t)tsa.dim.toInteger();\n        elem = createBlockDuplicatedArrayLiteral(loc, type.nextOf(), elem, len);\n    }\n\n    // Buzilla 15681\n    const tb = elem.type.toBasetype();\n    const mustCopy = tb.ty == Tstruct || tb.ty == Tsarray;\n\n    auto elements = new Expressions(dim);\n    foreach (i, ref el; *elements)\n    {\n        el = mustCopy && i ? copyLiteral(elem).copy() : elem;\n    }\n    auto ale = new ArrayLiteralExp(loc, type, elements);\n    ale.ownedByCtfe = OwnedBy.ctfe;\n    return ale;\n}\n\n/******************************\n * Helper for NewExp\n * Create a string literal consisting of 'value' duplicated 'dim' times.\n */\nStringExp createBlockDuplicatedStringLiteral(const ref Loc loc, Type type, dchar value, size_t dim, ubyte sz)\n{\n    auto s = cast(char*)mem.xcalloc(dim, sz);\n    foreach (elemi; 0 .. dim)\n    {\n        switch (sz)\n        {\n        case 1:\n            s[elemi] = cast(char)value;\n            break;\n        case 2:\n            (cast(wchar*)s)[elemi] = cast(wchar)value;\n            break;\n        case 4:\n            (cast(dchar*)s)[elemi] = value;\n            break;\n        default:\n            assert(0);\n        }\n    }\n    auto se = new StringExp(loc, s, dim);\n    se.type = type;\n    se.sz = sz;\n    se.committed = true;\n    se.ownedByCtfe = OwnedBy.ctfe;\n    return se;\n}\n\n// Return true if t is an AA\nbool isAssocArray(Type t)\n{\n    t = t.toBasetype();\n    if (t.ty == Taarray)\n        return true;\n    return false;\n}\n\n// Given a template AA type, extract the corresponding built-in AA type\nTypeAArray toBuiltinAAType(Type t)\n{\n    t = t.toBasetype();\n    if (t.ty == Taarray)\n        return cast(TypeAArray)t;\n    assert(0);\n}\n\n/************** TypeInfo operations ************************************/\n// Return true if type is TypeInfo_Class\nbool isTypeInfo_Class(const Type type)\n{\n    return type.ty == Tclass && (Type.dtypeinfo == (cast(TypeClass)type).sym || Type.dtypeinfo.isBaseOf((cast(TypeClass)type).sym, null));\n}\n\n/************** Pointer operations ************************************/\n// Return true if t is a pointer (not a function pointer)\nbool isPointer(Type t)\n{\n    Type tb = t.toBasetype();\n    return tb.ty == Tpointer && tb.nextOf().ty != Tfunction;\n}\n\n// For CTFE only. Returns true if 'e' is true or a non-null pointer.\nbool isTrueBool(Expression e)\n{\n    return e.isBool(true) || ((e.type.ty == Tpointer || e.type.ty == Tclass) && e.op != TOK.null_);\n}\n\n/* Is it safe to convert from srcPointee* to destPointee* ?\n * srcPointee is the genuine type (never void).\n * destPointee may be void.\n */\nbool isSafePointerCast(Type srcPointee, Type destPointee)\n{\n    // It's safe to cast S** to D** if it's OK to cast S* to D*\n    while (srcPointee.ty == Tpointer && destPointee.ty == Tpointer)\n    {\n        srcPointee = srcPointee.nextOf();\n        destPointee = destPointee.nextOf();\n    }\n    // It's OK if both are the same (modulo const)\n    if (srcPointee.constConv(destPointee))\n        return true;\n    // It's OK if function pointers differ only in safe/pure/nothrow\n    if (srcPointee.ty == Tfunction && destPointee.ty == Tfunction)\n        return srcPointee.covariant(destPointee) == 1;\n    // it's OK to cast to void*\n    if (destPointee.ty == Tvoid)\n        return true;\n    // It's OK to cast from V[K] to void*\n    if (srcPointee.ty == Taarray && destPointee == Type.tvoidptr)\n        return true;\n    // It's OK if they are the same size (static array of) integers, eg:\n    //     int*     --> uint*\n    //     int[5][] --> uint[5][]\n    if (srcPointee.ty == Tsarray && destPointee.ty == Tsarray)\n    {\n        if (srcPointee.size() != destPointee.size())\n            return false;\n        srcPointee = srcPointee.baseElemOf();\n        destPointee = destPointee.baseElemOf();\n    }\n    return srcPointee.isintegral() && destPointee.isintegral() && srcPointee.size() == destPointee.size();\n}\n\nExpression getAggregateFromPointer(Expression e, dinteger_t* ofs)\n{\n    *ofs = 0;\n    if (e.op == TOK.address)\n        e = (cast(AddrExp)e).e1;\n    if (e.op == TOK.symbolOffset)\n        *ofs = (cast(SymOffExp)e).offset;\n    if (e.op == TOK.dotVariable)\n    {\n        const ex = (cast(DotVarExp)e).e1;\n        const v = (cast(DotVarExp)e).var.isVarDeclaration();\n        assert(v);\n        StructLiteralExp se = (ex.op == TOK.classReference)\n            ? (cast(ClassReferenceExp)ex).value\n            : cast(StructLiteralExp)ex;\n\n        // We can't use getField, because it makes a copy\n        const i = (ex.op == TOK.classReference)\n            ? (cast(ClassReferenceExp)ex).getFieldIndex(e.type, v.offset)\n            : se.getFieldIndex(e.type, v.offset);\n        e = (*se.elements)[i];\n    }\n    if (e.op == TOK.index)\n    {\n        IndexExp ie = cast(IndexExp)e;\n        // Note that each AA element is part of its own memory block\n        if ((ie.e1.type.ty == Tarray || ie.e1.type.ty == Tsarray || ie.e1.op == TOK.string_ || ie.e1.op == TOK.arrayLiteral) && ie.e2.op == TOK.int64)\n        {\n            *ofs = ie.e2.toInteger();\n            return ie.e1;\n        }\n    }\n    if (e.op == TOK.slice && e.type.toBasetype().ty == Tsarray)\n    {\n        SliceExp se = cast(SliceExp)e;\n        if ((se.e1.type.ty == Tarray || se.e1.type.ty == Tsarray || se.e1.op == TOK.string_ || se.e1.op == TOK.arrayLiteral) && se.lwr.op == TOK.int64)\n        {\n            *ofs = se.lwr.toInteger();\n            return se.e1;\n        }\n    }\n    return e;\n}\n\n/** Return true if agg1 and agg2 are pointers to the same memory block\n */\nbool pointToSameMemoryBlock(Expression agg1, Expression agg2)\n{\n    if (agg1 == agg2)\n        return true;\n    // For integers cast to pointers, we regard them as non-comparable\n    // unless they are identical. (This may be overly strict).\n    if (agg1.op == TOK.int64 && agg2.op == TOK.int64 && agg1.toInteger() == agg2.toInteger())\n    {\n        return true;\n    }\n    // Note that type painting can occur with VarExp, so we\n    // must compare the variables being pointed to.\n    if (agg1.op == TOK.variable && agg2.op == TOK.variable && (cast(VarExp)agg1).var == (cast(VarExp)agg2).var)\n    {\n        return true;\n    }\n    if (agg1.op == TOK.symbolOffset && agg2.op == TOK.symbolOffset && (cast(SymOffExp)agg1).var == (cast(SymOffExp)agg2).var)\n    {\n        return true;\n    }\n    return false;\n}\n\n// return e1 - e2 as an integer, or error if not possible\nUnionExp pointerDifference(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    UnionExp ue = void;\n    dinteger_t ofs1, ofs2;\n    Expression agg1 = getAggregateFromPointer(e1, &ofs1);\n    Expression agg2 = getAggregateFromPointer(e2, &ofs2);\n    if (agg1 == agg2)\n    {\n        Type pointee = (cast(TypePointer)agg1.type).next;\n        const sz = pointee.size();\n        emplaceExp!(IntegerExp)(&ue, loc, (ofs1 - ofs2) * sz, type);\n    }\n    else if (agg1.op == TOK.string_ && agg2.op == TOK.string_ &&\n             (cast(StringExp)agg1).string == (cast(StringExp)agg2).string)\n    {\n        Type pointee = (cast(TypePointer)agg1.type).next;\n        const sz = pointee.size();\n        emplaceExp!(IntegerExp)(&ue, loc, (ofs1 - ofs2) * sz, type);\n    }\n    else if (agg1.op == TOK.symbolOffset && agg2.op == TOK.symbolOffset &&\n             (cast(SymOffExp)agg1).var == (cast(SymOffExp)agg2).var)\n    {\n        emplaceExp!(IntegerExp)(&ue, loc, ofs1 - ofs2, type);\n    }\n    else\n    {\n        error(loc, \"`%s - %s` cannot be interpreted at compile time: cannot subtract pointers to two different memory blocks\", e1.toChars(), e2.toChars());\n        emplaceExp!(CTFEExp)(&ue, TOK.cantExpression);\n    }\n    return ue;\n}\n\n// Return eptr op e2, where eptr is a pointer, e2 is an integer,\n// and op is TOK.add or TOK.min\nUnionExp pointerArithmetic(const ref Loc loc, TOK op, Type type, Expression eptr, Expression e2)\n{\n    UnionExp ue;\n    if (eptr.type.nextOf().ty == Tvoid)\n    {\n        error(loc, \"cannot perform arithmetic on `void*` pointers at compile time\");\n    Lcant:\n        emplaceExp!(CTFEExp)(&ue, TOK.cantExpression);\n        return ue;\n    }\n    if (eptr.op == TOK.address)\n        eptr = (cast(AddrExp)eptr).e1;\n    dinteger_t ofs1;\n    Expression agg1 = getAggregateFromPointer(eptr, &ofs1);\n    if (agg1.op == TOK.symbolOffset)\n    {\n        if ((cast(SymOffExp)agg1).var.type.ty != Tsarray)\n        {\n            error(loc, \"cannot perform pointer arithmetic on arrays of unknown length at compile time\");\n            goto Lcant;\n        }\n    }\n    else if (agg1.op != TOK.string_ && agg1.op != TOK.arrayLiteral)\n    {\n        error(loc, \"cannot perform pointer arithmetic on non-arrays at compile time\");\n        goto Lcant;\n    }\n    dinteger_t ofs2 = e2.toInteger();\n    Type pointee = (cast(TypeNext)agg1.type.toBasetype()).next;\n    dinteger_t sz = pointee.size();\n    sinteger_t indx;\n    dinteger_t len;\n    if (agg1.op == TOK.symbolOffset)\n    {\n        indx = ofs1 / sz;\n        len = (cast(TypeSArray)(cast(SymOffExp)agg1).var.type).dim.toInteger();\n    }\n    else\n    {\n        Expression dollar = ArrayLength(Type.tsize_t, agg1).copy();\n        assert(!CTFEExp.isCantExp(dollar));\n        indx = ofs1;\n        len = dollar.toInteger();\n    }\n    if (op == TOK.add || op == TOK.addAssign || op == TOK.plusPlus)\n        indx += ofs2 / sz;\n    else if (op == TOK.min || op == TOK.minAssign || op == TOK.minusMinus)\n        indx -= ofs2 / sz;\n    else\n    {\n        error(loc, \"CTFE internal error: bad pointer operation\");\n        goto Lcant;\n    }\n    if (indx < 0 || len < indx)\n    {\n        error(loc, \"cannot assign pointer to index %lld inside memory block `[0..%lld]`\", indx, len);\n        goto Lcant;\n    }\n    if (agg1.op == TOK.symbolOffset)\n    {\n        emplaceExp!(SymOffExp)(&ue, loc, (cast(SymOffExp)agg1).var, indx * sz);\n        SymOffExp se = cast(SymOffExp)ue.exp();\n        se.type = type;\n        return ue;\n    }\n    if (agg1.op != TOK.arrayLiteral && agg1.op != TOK.string_)\n    {\n        error(loc, \"CTFE internal error: pointer arithmetic `%s`\", agg1.toChars());\n        goto Lcant;\n    }\n    if (eptr.type.toBasetype().ty == Tsarray)\n    {\n        dinteger_t dim = (cast(TypeSArray)eptr.type.toBasetype()).dim.toInteger();\n        // Create a CTFE pointer &agg1[indx .. indx+dim]\n        auto se = new SliceExp(loc, agg1, new IntegerExp(loc, indx, Type.tsize_t), new IntegerExp(loc, indx + dim, Type.tsize_t));\n        se.type = type.toBasetype().nextOf();\n        emplaceExp!(AddrExp)(&ue, loc, se);\n        ue.exp().type = type;\n        return ue;\n    }\n    // Create a CTFE pointer &agg1[indx]\n    auto ofs = new IntegerExp(loc, indx, Type.tsize_t);\n    Expression ie = new IndexExp(loc, agg1, ofs);\n    ie.type = type.toBasetype().nextOf(); // https://issues.dlang.org/show_bug.cgi?id=13992\n    emplaceExp!(AddrExp)(&ue, loc, ie);\n    ue.exp().type = type;\n    return ue;\n}\n\n// Return 1 if true, 0 if false\n// -1 if comparison is illegal because they point to non-comparable memory blocks\nint comparePointers(TOK op, Expression agg1, dinteger_t ofs1, Expression agg2, dinteger_t ofs2)\n{\n    if (pointToSameMemoryBlock(agg1, agg2))\n    {\n        int n;\n        switch (op)\n        {\n        case TOK.lessThan:\n            n = (ofs1 < ofs2);\n            break;\n        case TOK.lessOrEqual:\n            n = (ofs1 <= ofs2);\n            break;\n        case TOK.greaterThan:\n            n = (ofs1 > ofs2);\n            break;\n        case TOK.greaterOrEqual:\n            n = (ofs1 >= ofs2);\n            break;\n        case TOK.identity:\n        case TOK.equal:\n            n = (ofs1 == ofs2);\n            break;\n        case TOK.notIdentity:\n        case TOK.notEqual:\n            n = (ofs1 != ofs2);\n            break;\n        default:\n            assert(0);\n        }\n        return n;\n    }\n    const null1 = (agg1.op == TOK.null_);\n    const null2 = (agg2.op == TOK.null_);\n    int cmp;\n    if (null1 || null2)\n    {\n        switch (op)\n        {\n        case TOK.lessThan:\n            cmp = null1 && !null2;\n            break;\n        case TOK.greaterThan:\n            cmp = !null1 && null2;\n            break;\n        case TOK.lessOrEqual:\n            cmp = null1;\n            break;\n        case TOK.greaterOrEqual:\n            cmp = null2;\n            break;\n        case TOK.identity:\n        case TOK.equal:\n        case TOK.notIdentity: // 'cmp' gets inverted below\n        case TOK.notEqual:\n            cmp = (null1 == null2);\n            break;\n        default:\n            assert(0);\n        }\n    }\n    else\n    {\n        switch (op)\n        {\n        case TOK.identity:\n        case TOK.equal:\n        case TOK.notIdentity: // 'cmp' gets inverted below\n        case TOK.notEqual:\n            cmp = 0;\n            break;\n        default:\n            return -1; // memory blocks are different\n        }\n    }\n    if (op == TOK.notIdentity || op == TOK.notEqual)\n        cmp ^= 1;\n    return cmp;\n}\n\n// True if conversion from type 'from' to 'to' involves a reinterpret_cast\n// floating point -> integer or integer -> floating point\nbool isFloatIntPaint(Type to, Type from)\n{\n    return from.size() == to.size() && (from.isintegral() && to.isfloating() || from.isfloating() && to.isintegral());\n}\n\n// Reinterpret float/int value 'fromVal' as a float/integer of type 'to'.\nExpression paintFloatInt(Expression fromVal, Type to)\n{\n    if (exceptionOrCantInterpret(fromVal))\n        return fromVal;\n    assert(to.size() == 4 || to.size() == 8);\n    return Compiler.paintAsType(fromVal, to);\n}\n\n/******** Constant folding, with support for CTFE ***************************/\n/// Return true if non-pointer expression e can be compared\n/// with >,is, ==, etc, using ctfeCmp, ctfeEqual, ctfeIdentity\nbool isCtfeComparable(Expression e)\n{\n    if (e.op == TOK.slice)\n        e = (cast(SliceExp)e).e1;\n    if (e.isConst() != 1)\n    {\n        if (e.op == TOK.null_ || e.op == TOK.string_ || e.op == TOK.function_ || e.op == TOK.delegate_ || e.op == TOK.arrayLiteral || e.op == TOK.structLiteral || e.op == TOK.assocArrayLiteral || e.op == TOK.classReference)\n        {\n            return true;\n        }\n        // https://issues.dlang.org/show_bug.cgi?id=14123\n        // TypeInfo object is comparable in CTFE\n        if (e.op == TOK.typeid_)\n            return true;\n        return false;\n    }\n    return true;\n}\n\n/// Map TOK comparison ops\nprivate bool numCmp(N)(TOK op, N n1, N n2)\n{\n    switch (op)\n    {\n    case TOK.lessThan:\n        return n1 < n2;\n    case TOK.lessOrEqual:\n        return n1 <= n2;\n    case TOK.greaterThan:\n        return n1 > n2;\n    case TOK.greaterOrEqual:\n        return n1 >= n2;\n\n    default:\n        assert(0);\n    }\n}\n\n/// Returns cmp OP 0; where OP is ==, !=, <, >=, etc. Result is 0 or 1\nint specificCmp(TOK op, int rawCmp)\n{\n    return numCmp!int(op, rawCmp, 0);\n}\n\n/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1\nint intUnsignedCmp(TOK op, dinteger_t n1, dinteger_t n2)\n{\n    return numCmp!dinteger_t(op, n1, n2);\n}\n\n/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1\nint intSignedCmp(TOK op, sinteger_t n1, sinteger_t n2)\n{\n    return numCmp!sinteger_t(op, n1, n2);\n}\n\n/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1\nint realCmp(TOK op, real_t r1, real_t r2)\n{\n    // Don't rely on compiler, handle NAN arguments separately\n    if (CTFloat.isNaN(r1) || CTFloat.isNaN(r2)) // if unordered\n    {\n        switch (op)\n        {\n        case TOK.lessThan:\n        case TOK.lessOrEqual:\n        case TOK.greaterThan:\n        case TOK.greaterOrEqual:\n            return 0;\n\n        default:\n            assert(0);\n        }\n    }\n    else\n    {\n        return numCmp!real_t(op, r1, r2);\n    }\n}\n\n/* Conceptually the same as memcmp(e1, e2).\n * e1 and e2 may be strings, arrayliterals, or slices.\n * For string types, return <0 if e1 < e2, 0 if e1==e2, >0 if e1 > e2.\n * For all other types, return 0 if e1 == e2, !=0 if e1 != e2.\n */\nprivate int ctfeCmpArrays(const ref Loc loc, Expression e1, Expression e2, uinteger_t len)\n{\n    // Resolve slices, if necessary\n    uinteger_t lo1 = 0;\n    uinteger_t lo2 = 0;\n    Expression x = e1;\n    if (x.op == TOK.slice)\n    {\n        lo1 = (cast(SliceExp)x).lwr.toInteger();\n        x = (cast(SliceExp)x).e1;\n    }\n    StringExp se1 = (x.op == TOK.string_) ? cast(StringExp)x : null;\n    ArrayLiteralExp ae1 = (x.op == TOK.arrayLiteral) ? cast(ArrayLiteralExp)x : null;\n    x = e2;\n    if (x.op == TOK.slice)\n    {\n        lo2 = (cast(SliceExp)x).lwr.toInteger();\n        x = (cast(SliceExp)x).e1;\n    }\n    StringExp se2 = (x.op == TOK.string_) ? cast(StringExp)x : null;\n    ArrayLiteralExp ae2 = (x.op == TOK.arrayLiteral) ? cast(ArrayLiteralExp)x : null;\n    // Now both must be either TOK.arrayLiteral or TOK.string_\n    if (se1 && se2)\n        return sliceCmpStringWithString(se1, se2, cast(size_t)lo1, cast(size_t)lo2, cast(size_t)len);\n    if (se1 && ae2)\n        return sliceCmpStringWithArray(se1, ae2, cast(size_t)lo1, cast(size_t)lo2, cast(size_t)len);\n    if (se2 && ae1)\n        return -sliceCmpStringWithArray(se2, ae1, cast(size_t)lo2, cast(size_t)lo1, cast(size_t)len);\n    assert(ae1 && ae2);\n    // Comparing two array literals. This case is potentially recursive.\n    // If they aren't strings, we just need an equality check rather than\n    // a full cmp.\n    const bool needCmp = ae1.type.nextOf().isintegral();\n    foreach (size_t i; 0 .. cast(size_t)len)\n    {\n        Expression ee1 = (*ae1.elements)[cast(size_t)(lo1 + i)];\n        Expression ee2 = (*ae2.elements)[cast(size_t)(lo2 + i)];\n        if (needCmp)\n        {\n            const sinteger_t c = ee1.toInteger() - ee2.toInteger();\n            if (c > 0)\n                return 1;\n            if (c < 0)\n                return -1;\n        }\n        else\n        {\n            if (ctfeRawCmp(loc, ee1, ee2))\n                return 1;\n        }\n    }\n    return 0;\n}\n\n/* Given a delegate expression e, return .funcptr.\n * If e is NullExp, return NULL.\n */\nprivate FuncDeclaration funcptrOf(Expression e)\n{\n    assert(e.type.ty == Tdelegate);\n    if (e.op == TOK.delegate_)\n        return (cast(DelegateExp)e).func;\n    if (e.op == TOK.function_)\n        return (cast(FuncExp)e).fd;\n    assert(e.op == TOK.null_);\n    return null;\n}\n\nprivate bool isArray(const Expression e)\n{\n    return e.op == TOK.arrayLiteral || e.op == TOK.string_ || e.op == TOK.slice || e.op == TOK.null_;\n}\n\n/* For strings, return <0 if e1 < e2, 0 if e1==e2, >0 if e1 > e2.\n * For all other types, return 0 if e1 == e2, !=0 if e1 != e2.\n */\nprivate int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2)\n{\n    if (e1.op == TOK.classReference || e2.op == TOK.classReference)\n    {\n        if (e1.op == TOK.classReference && e2.op == TOK.classReference && (cast(ClassReferenceExp)e1).value == (cast(ClassReferenceExp)e2).value)\n            return 0;\n        return 1;\n    }\n    if (e1.op == TOK.typeid_ && e2.op == TOK.typeid_)\n    {\n        // printf(\"e1: %s\\n\", e1.toChars());\n        // printf(\"e2: %s\\n\", e2.toChars());\n        Type t1 = isType((cast(TypeidExp)e1).obj);\n        Type t2 = isType((cast(TypeidExp)e2).obj);\n        assert(t1);\n        assert(t2);\n        return t1 != t2;\n    }\n    // null == null, regardless of type\n    if (e1.op == TOK.null_ && e2.op == TOK.null_)\n        return 0;\n    if (e1.type.ty == Tpointer && e2.type.ty == Tpointer)\n    {\n        // Can only be an equality test.\n        dinteger_t ofs1, ofs2;\n        Expression agg1 = getAggregateFromPointer(e1, &ofs1);\n        Expression agg2 = getAggregateFromPointer(e2, &ofs2);\n        if ((agg1 == agg2) || (agg1.op == TOK.variable && agg2.op == TOK.variable && (cast(VarExp)agg1).var == (cast(VarExp)agg2).var))\n        {\n            if (ofs1 == ofs2)\n                return 0;\n        }\n        return 1;\n    }\n    if (e1.type.ty == Tdelegate && e2.type.ty == Tdelegate)\n    {\n        // If .funcptr isn't the same, they are not equal\n        if (funcptrOf(e1) != funcptrOf(e2))\n            return 1;\n        // If both are delegate literals, assume they have the\n        // same closure pointer. TODO: We don't support closures yet!\n        if (e1.op == TOK.function_ && e2.op == TOK.function_)\n            return 0;\n        assert(e1.op == TOK.delegate_ && e2.op == TOK.delegate_);\n        // Same .funcptr. Do they have the same .ptr?\n        Expression ptr1 = (cast(DelegateExp)e1).e1;\n        Expression ptr2 = (cast(DelegateExp)e2).e1;\n        dinteger_t ofs1, ofs2;\n        Expression agg1 = getAggregateFromPointer(ptr1, &ofs1);\n        Expression agg2 = getAggregateFromPointer(ptr2, &ofs2);\n        // If they are TOK.variable, it means they are FuncDeclarations\n        if ((agg1 == agg2 && ofs1 == ofs2) || (agg1.op == TOK.variable && agg2.op == TOK.variable && (cast(VarExp)agg1).var == (cast(VarExp)agg2).var))\n        {\n            return 0;\n        }\n        return 1;\n    }\n    if (isArray(e1) && isArray(e2))\n    {\n        const uinteger_t len1 = resolveArrayLength(e1);\n        const uinteger_t len2 = resolveArrayLength(e2);\n        // workaround for dmc optimizer bug calculating wrong len for\n        // uinteger_t len = (len1 < len2 ? len1 : len2);\n        // if (len == 0) ...\n        if (len1 > 0 && len2 > 0)\n        {\n            const uinteger_t len = (len1 < len2 ? len1 : len2);\n            const int res = ctfeCmpArrays(loc, e1, e2, len);\n            if (res != 0)\n                return res;\n        }\n        return cast(int)(len1 - len2);\n    }\n    if (e1.type.isintegral())\n    {\n        return e1.toInteger() != e2.toInteger();\n    }\n    if (e1.type.isreal() || e1.type.isimaginary())\n    {\n        real_t r1 = e1.type.isreal() ? e1.toReal() : e1.toImaginary();\n        real_t r2 = e1.type.isreal() ? e2.toReal() : e2.toImaginary();\n        if (CTFloat.isNaN(r1) || CTFloat.isNaN(r2)) // if unordered\n        {\n            return 1;\n        }\n        else\n        {\n            return (r1 != r2);\n        }\n    }\n    else if (e1.type.iscomplex())\n    {\n        return e1.toComplex() != e2.toComplex();\n    }\n    if (e1.op == TOK.structLiteral && e2.op == TOK.structLiteral)\n    {\n        StructLiteralExp es1 = cast(StructLiteralExp)e1;\n        StructLiteralExp es2 = cast(StructLiteralExp)e2;\n        // For structs, we only need to return 0 or 1 (< and > aren't legal).\n        if (es1.sd != es2.sd)\n            return 1;\n        else if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))\n            return 0; // both arrays are empty\n        else if (!es1.elements || !es2.elements)\n            return 1;\n        else if (es1.elements.dim != es2.elements.dim)\n            return 1;\n        else\n        {\n            foreach (size_t i; 0 .. es1.elements.dim)\n            {\n                Expression ee1 = (*es1.elements)[i];\n                Expression ee2 = (*es2.elements)[i];\n                if (ee1 == ee2)\n                    continue;\n                if (!ee1 || !ee2)\n                    return 1;\n                const int cmp = ctfeRawCmp(loc, ee1, ee2);\n                if (cmp)\n                    return 1;\n            }\n            return 0; // All elements are equal\n        }\n    }\n    if (e1.op == TOK.assocArrayLiteral && e2.op == TOK.assocArrayLiteral)\n    {\n        AssocArrayLiteralExp es1 = cast(AssocArrayLiteralExp)e1;\n        AssocArrayLiteralExp es2 = cast(AssocArrayLiteralExp)e2;\n        size_t dim = es1.keys.dim;\n        if (es2.keys.dim != dim)\n            return 1;\n        bool* used = cast(bool*)mem.xmalloc(bool.sizeof * dim);\n        memset(used, 0, bool.sizeof * dim);\n        foreach (size_t i; 0 .. dim)\n        {\n            Expression k1 = (*es1.keys)[i];\n            Expression v1 = (*es1.values)[i];\n            Expression v2 = null;\n            foreach (size_t j; 0 .. dim)\n            {\n                if (used[j])\n                    continue;\n                Expression k2 = (*es2.keys)[j];\n                if (ctfeRawCmp(loc, k1, k2))\n                    continue;\n                used[j] = true;\n                v2 = (*es2.values)[j];\n                break;\n            }\n            if (!v2 || ctfeRawCmp(loc, v1, v2))\n            {\n                mem.xfree(used);\n                return 1;\n            }\n        }\n        mem.xfree(used);\n        return 0;\n    }\n    error(loc, \"CTFE internal error: bad compare of `%s` and `%s`\", e1.toChars(), e2.toChars());\n    assert(0);\n}\n\n/// Evaluate ==, !=.  Resolves slices before comparing. Returns 0 or 1\nint ctfeEqual(const ref Loc loc, TOK op, Expression e1, Expression e2)\n{\n    return !ctfeRawCmp(loc, e1, e2) ^ (op == TOK.notEqual);\n}\n\n/// Evaluate is, !is.  Resolves slices before comparing. Returns 0 or 1\nint ctfeIdentity(const ref Loc loc, TOK op, Expression e1, Expression e2)\n{\n    //printf(\"ctfeIdentity op = '%s', e1 = %s %s, e2 = %s %s\\n\", Token::toChars(op),\n    //    Token::toChars(e1.op), e1.toChars(), Token::toChars(e2.op), e1.toChars());\n    int cmp;\n    if (e1.op == TOK.null_)\n    {\n        cmp = (e2.op == TOK.null_);\n    }\n    else if (e2.op == TOK.null_)\n    {\n        cmp = 0;\n    }\n    else if (e1.op == TOK.symbolOffset && e2.op == TOK.symbolOffset)\n    {\n        SymOffExp es1 = cast(SymOffExp)e1;\n        SymOffExp es2 = cast(SymOffExp)e2;\n        cmp = (es1.var == es2.var && es1.offset == es2.offset);\n    }\n    else if (e1.type.isreal())\n        cmp = RealEquals(e1.toReal(), e2.toReal());\n    else if (e1.type.isimaginary())\n        cmp = RealEquals(e1.toImaginary(), e2.toImaginary());\n    else if (e1.type.iscomplex())\n    {\n        complex_t v1 = e1.toComplex();\n        complex_t v2 = e2.toComplex();\n        cmp = RealEquals(creall(v1), creall(v2)) && RealEquals(cimagl(v1), cimagl(v1));\n    }\n    else\n        cmp = !ctfeRawCmp(loc, e1, e2);\n    if (op == TOK.notIdentity || op == TOK.notEqual)\n        cmp ^= 1;\n    return cmp;\n}\n\n/// Evaluate >,<=, etc. Resolves slices before comparing. Returns 0 or 1\nint ctfeCmp(const ref Loc loc, TOK op, Expression e1, Expression e2)\n{\n    Type t1 = e1.type.toBasetype();\n    Type t2 = e2.type.toBasetype();\n\n    if (t1.isString() && t2.isString())\n        return specificCmp(op, ctfeRawCmp(loc, e1, e2));\n    else if (t1.isreal())\n        return realCmp(op, e1.toReal(), e2.toReal());\n    else if (t1.isimaginary())\n        return realCmp(op, e1.toImaginary(), e2.toImaginary());\n    else if (t1.isunsigned() || t2.isunsigned())\n        return intUnsignedCmp(op, e1.toInteger(), e2.toInteger());\n    else\n        return intSignedCmp(op, e1.toInteger(), e2.toInteger());\n}\n\nUnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2)\n{\n    Type t1 = e1.type.toBasetype();\n    Type t2 = e2.type.toBasetype();\n    UnionExp ue;\n    if (e2.op == TOK.string_ && e1.op == TOK.arrayLiteral && t1.nextOf().isintegral())\n    {\n        // [chars] ~ string => string (only valid for CTFE)\n        StringExp es1 = cast(StringExp)e2;\n        ArrayLiteralExp es2 = cast(ArrayLiteralExp)e1;\n        const len = es1.len + es2.elements.dim;\n        const sz = es1.sz;\n        void* s = mem.xmalloc((len + 1) * sz);\n        memcpy(cast(char*)s + sz * es2.elements.dim, es1.string, es1.len * sz);\n        foreach (size_t i; 0 .. es2.elements.dim)\n        {\n            Expression es2e = (*es2.elements)[i];\n            if (es2e.op != TOK.int64)\n            {\n                emplaceExp!(CTFEExp)(&ue, TOK.cantExpression);\n                return ue;\n            }\n            dinteger_t v = es2e.toInteger();\n            Port.valcpy(cast(char*)s + i * sz, v, sz);\n        }\n        // Add terminating 0\n        memset(cast(char*)s + len * sz, 0, sz);\n        emplaceExp!(StringExp)(&ue, loc, s, len);\n        StringExp es = cast(StringExp)ue.exp();\n        es.sz = sz;\n        es.committed = 0;\n        es.type = type;\n        return ue;\n    }\n    if (e1.op == TOK.string_ && e2.op == TOK.arrayLiteral && t2.nextOf().isintegral())\n    {\n        // string ~ [chars] => string (only valid for CTFE)\n        // Concatenate the strings\n        StringExp es1 = cast(StringExp)e1;\n        ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2;\n        const len = es1.len + es2.elements.dim;\n        const sz = es1.sz;\n        void* s = mem.xmalloc((len + 1) * sz);\n        memcpy(s, es1.string, es1.len * sz);\n        foreach (size_t i; 0 .. es2.elements.dim)\n        {\n            Expression es2e = (*es2.elements)[i];\n            if (es2e.op != TOK.int64)\n            {\n                emplaceExp!(CTFEExp)(&ue, TOK.cantExpression);\n                return ue;\n            }\n            const v = es2e.toInteger();\n            Port.valcpy(cast(char*)s + (es1.len + i) * sz, v, sz);\n        }\n        // Add terminating 0\n        memset(cast(char*)s + len * sz, 0, sz);\n        emplaceExp!(StringExp)(&ue, loc, s, len);\n        StringExp es = cast(StringExp)ue.exp();\n        es.sz = sz;\n        es.committed = 0; //es1.committed;\n        es.type = type;\n        return ue;\n    }\n    if (e1.op == TOK.arrayLiteral && e2.op == TOK.arrayLiteral && t1.nextOf().equals(t2.nextOf()))\n    {\n        //  [ e1 ] ~ [ e2 ] ---> [ e1, e2 ]\n        ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1;\n        ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2;\n        emplaceExp!(ArrayLiteralExp)(&ue, es1.loc, type, copyLiteralArray(es1.elements));\n        es1 = cast(ArrayLiteralExp)ue.exp();\n        es1.elements.insert(es1.elements.dim, copyLiteralArray(es2.elements));\n        return ue;\n    }\n    if (e1.op == TOK.arrayLiteral && e2.op == TOK.null_ && t1.nextOf().equals(t2.nextOf()))\n    {\n        //  [ e1 ] ~ null ----> [ e1 ].dup\n        ue = paintTypeOntoLiteralCopy(type, copyLiteral(e1).copy());\n        return ue;\n    }\n    if (e1.op == TOK.null_ && e2.op == TOK.arrayLiteral && t1.nextOf().equals(t2.nextOf()))\n    {\n        //  null ~ [ e2 ] ----> [ e2 ].dup\n        ue = paintTypeOntoLiteralCopy(type, copyLiteral(e2).copy());\n        return ue;\n    }\n    ue = Cat(type, e1, e2);\n    return ue;\n}\n\n/*  Given an AA literal 'ae', and a key 'e2':\n *  Return ae[e2] if present, or NULL if not found.\n */\nExpression findKeyInAA(const ref Loc loc, AssocArrayLiteralExp ae, Expression e2)\n{\n    /* Search the keys backwards, in case there are duplicate keys\n     */\n    for (size_t i = ae.keys.dim; i;)\n    {\n        --i;\n        Expression ekey = (*ae.keys)[i];\n        const int eq = ctfeEqual(loc, TOK.equal, ekey, e2);\n        if (eq)\n        {\n            return (*ae.values)[i];\n        }\n    }\n    return null;\n}\n\n/* Same as for constfold.Index, except that it only works for static arrays,\n * dynamic arrays, and strings. We know that e1 is an\n * interpreted CTFE expression, so it cannot have side-effects.\n */\nExpression ctfeIndex(const ref Loc loc, Type type, Expression e1, uinteger_t indx)\n{\n    //printf(\"ctfeIndex(e1 = %s)\\n\", e1.toChars());\n    assert(e1.type);\n    if (e1.op == TOK.string_)\n    {\n        StringExp es1 = cast(StringExp)e1;\n        if (indx >= es1.len)\n        {\n            error(loc, \"string index %llu is out of bounds `[0 .. %llu]`\", indx, cast(ulong)es1.len);\n            return CTFEExp.cantexp;\n        }\n        return new IntegerExp(loc, es1.charAt(indx), type);\n    }\n    assert(e1.op == TOK.arrayLiteral);\n    {\n        ArrayLiteralExp ale = cast(ArrayLiteralExp)e1;\n        if (indx >= ale.elements.dim)\n        {\n            error(loc, \"array index %llu is out of bounds `%s[0 .. %llu]`\", indx, e1.toChars(), cast(ulong)ale.elements.dim);\n            return CTFEExp.cantexp;\n        }\n        Expression e = (*ale.elements)[cast(size_t)indx];\n        return paintTypeOntoLiteral(type, e);\n    }\n}\n\nExpression ctfeCast(const ref Loc loc, Type type, Type to, Expression e)\n{\n    if (e.op == TOK.null_)\n        return paintTypeOntoLiteral(to, e);\n    if (e.op == TOK.classReference)\n    {\n        // Disallow reinterpreting class casts. Do this by ensuring that\n        // the original class can implicitly convert to the target class\n        ClassDeclaration originalClass = (cast(ClassReferenceExp)e).originalClass();\n        if (originalClass.type.implicitConvTo(to.mutableOf()))\n            return paintTypeOntoLiteral(to, e);\n        else\n            return new NullExp(loc, to);\n    }\n    // Allow TypeInfo type painting\n    if (isTypeInfo_Class(e.type) && e.type.implicitConvTo(to))\n        return paintTypeOntoLiteral(to, e);\n    // Allow casting away const for struct literals\n    if (e.op == TOK.structLiteral && e.type.toBasetype().castMod(0) == to.toBasetype().castMod(0))\n    {\n        return paintTypeOntoLiteral(to, e);\n    }\n    Expression r;\n    if (e.type.equals(type) && type.equals(to))\n    {\n        // necessary not to change e's address for pointer comparisons\n        r = e;\n    }\n    else if (to.toBasetype().ty == Tarray && type.toBasetype().ty == Tarray && to.toBasetype().nextOf().size() == type.toBasetype().nextOf().size())\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=12495\n        // Array reinterpret casts: eg. string to immutable(ubyte)[]\n        return paintTypeOntoLiteral(to, e);\n    }\n    else\n    {\n        r = Cast(loc, type, to, e).copy();\n    }\n    if (CTFEExp.isCantExp(r))\n        error(loc, \"cannot cast `%s` to `%s` at compile time\", e.toChars(), to.toChars());\n    if (e.op == TOK.arrayLiteral)\n        (cast(ArrayLiteralExp)e).ownedByCtfe = OwnedBy.ctfe;\n    if (e.op == TOK.string_)\n        (cast(StringExp)e).ownedByCtfe = OwnedBy.ctfe;\n    return r;\n}\n\n/******** Assignment helper functions ***************************/\n/* Set dest = src, where both dest and src are container value literals\n * (ie, struct literals, or static arrays (can be an array literal or a string))\n * Assignment is recursively in-place.\n * Purpose: any reference to a member of 'dest' will remain valid after the\n * assignment.\n */\nvoid assignInPlace(Expression dest, Expression src)\n{\n    assert(dest.op == TOK.structLiteral || dest.op == TOK.arrayLiteral || dest.op == TOK.string_);\n    Expressions* oldelems;\n    Expressions* newelems;\n    if (dest.op == TOK.structLiteral)\n    {\n        assert(dest.op == src.op);\n        oldelems = (cast(StructLiteralExp)dest).elements;\n        newelems = (cast(StructLiteralExp)src).elements;\n        if ((cast(StructLiteralExp)dest).sd.isNested() && oldelems.dim == newelems.dim - 1)\n            oldelems.push(null);\n    }\n    else if (dest.op == TOK.arrayLiteral && src.op == TOK.arrayLiteral)\n    {\n        oldelems = (cast(ArrayLiteralExp)dest).elements;\n        newelems = (cast(ArrayLiteralExp)src).elements;\n    }\n    else if (dest.op == TOK.string_ && src.op == TOK.string_)\n    {\n        sliceAssignStringFromString(cast(StringExp)dest, cast(StringExp)src, 0);\n        return;\n    }\n    else if (dest.op == TOK.arrayLiteral && src.op == TOK.string_)\n    {\n        sliceAssignArrayLiteralFromString(cast(ArrayLiteralExp)dest, cast(StringExp)src, 0);\n        return;\n    }\n    else if (src.op == TOK.arrayLiteral && dest.op == TOK.string_)\n    {\n        sliceAssignStringFromArrayLiteral(cast(StringExp)dest, cast(ArrayLiteralExp)src, 0);\n        return;\n    }\n    else\n        assert(0);\n    assert(oldelems.dim == newelems.dim);\n    foreach (size_t i; 0 .. oldelems.dim)\n    {\n        Expression e = (*newelems)[i];\n        Expression o = (*oldelems)[i];\n        if (e.op == TOK.structLiteral)\n        {\n            assert(o.op == e.op);\n            assignInPlace(o, e);\n        }\n        else if (e.type.ty == Tsarray && e.op != TOK.void_ && o.type.ty == Tsarray)\n        {\n            assignInPlace(o, e);\n        }\n        else\n        {\n            (*oldelems)[i] = (*newelems)[i];\n        }\n    }\n}\n\n// Given an AA literal aae,  set aae[index] = newval and return newval.\nExpression assignAssocArrayElement(const ref Loc loc, AssocArrayLiteralExp aae, Expression index, Expression newval)\n{\n    /* Create new associative array literal reflecting updated key/value\n     */\n    Expressions* keysx = aae.keys;\n    Expressions* valuesx = aae.values;\n    int updated = 0;\n    for (size_t j = valuesx.dim; j;)\n    {\n        j--;\n        Expression ekey = (*aae.keys)[j];\n        int eq = ctfeEqual(loc, TOK.equal, ekey, index);\n        if (eq)\n        {\n            (*valuesx)[j] = newval;\n            updated = 1;\n        }\n    }\n    if (!updated)\n    {\n        // Append index/newval to keysx[]/valuesx[]\n        valuesx.push(newval);\n        keysx.push(index);\n    }\n    return newval;\n}\n\n/// Given array literal oldval of type ArrayLiteralExp or StringExp, of length\n/// oldlen, change its length to newlen. If the newlen is longer than oldlen,\n/// all new elements will be set to the default initializer for the element type.\nUnionExp changeArrayLiteralLength(const ref Loc loc, TypeArray arrayType, Expression oldval, size_t oldlen, size_t newlen)\n{\n    UnionExp ue;\n    Type elemType = arrayType.next;\n    assert(elemType);\n    Expression defaultElem = elemType.defaultInitLiteral(loc);\n    auto elements = new Expressions(newlen);\n    // Resolve slices\n    size_t indxlo = 0;\n    if (oldval.op == TOK.slice)\n    {\n        indxlo = cast(size_t)(cast(SliceExp)oldval).lwr.toInteger();\n        oldval = (cast(SliceExp)oldval).e1;\n    }\n    size_t copylen = oldlen < newlen ? oldlen : newlen;\n    if (oldval.op == TOK.string_)\n    {\n        StringExp oldse = cast(StringExp)oldval;\n        void* s = mem.xcalloc(newlen + 1, oldse.sz);\n        memcpy(s, oldse.string, copylen * oldse.sz);\n        const defaultValue = cast(uint)defaultElem.toInteger();\n        foreach (size_t elemi; copylen .. newlen)\n        {\n            switch (oldse.sz)\n            {\n            case 1:\n                (cast(char*)s)[cast(size_t)(indxlo + elemi)] = cast(char)defaultValue;\n                break;\n            case 2:\n                (cast(wchar*)s)[cast(size_t)(indxlo + elemi)] = cast(wchar)defaultValue;\n                break;\n            case 4:\n                (cast(dchar*)s)[cast(size_t)(indxlo + elemi)] = cast(dchar)defaultValue;\n                break;\n            default:\n                assert(0);\n            }\n        }\n        emplaceExp!(StringExp)(&ue, loc, s, newlen);\n        StringExp se = cast(StringExp)ue.exp();\n        se.type = arrayType;\n        se.sz = oldse.sz;\n        se.committed = oldse.committed;\n        se.ownedByCtfe = OwnedBy.ctfe;\n    }\n    else\n    {\n        if (oldlen != 0)\n        {\n            assert(oldval.op == TOK.arrayLiteral);\n            ArrayLiteralExp ae = cast(ArrayLiteralExp)oldval;\n            foreach (size_t i; 0 .. copylen)\n                (*elements)[i] = (*ae.elements)[indxlo + i];\n        }\n        if (elemType.ty == Tstruct || elemType.ty == Tsarray)\n        {\n            /* If it is an aggregate literal representing a value type,\n             * we need to create a unique copy for each element\n             */\n            foreach (size_t i; copylen .. newlen)\n                (*elements)[i] = copyLiteral(defaultElem).copy();\n        }\n        else\n        {\n            foreach (size_t i; copylen .. newlen)\n                (*elements)[i] = defaultElem;\n        }\n        emplaceExp!(ArrayLiteralExp)(&ue, loc, arrayType, elements);\n        ArrayLiteralExp aae = cast(ArrayLiteralExp)ue.exp();\n        aae.ownedByCtfe = OwnedBy.ctfe;\n    }\n    return ue;\n}\n\n/*************************** CTFE Sanity Checks ***************************/\nbool isCtfeValueValid(Expression newval)\n{\n    Type tb = newval.type.toBasetype();\n    if (newval.op == TOK.int64 || newval.op == TOK.float64 || newval.op == TOK.char_ || newval.op == TOK.complex80)\n    {\n        return tb.isscalar();\n    }\n    if (newval.op == TOK.null_)\n    {\n        return tb.ty == Tnull || tb.ty == Tpointer || tb.ty == Tarray || tb.ty == Taarray || tb.ty == Tclass || tb.ty == Tdelegate;\n    }\n    if (newval.op == TOK.string_)\n        return true; // CTFE would directly use the StringExp in AST.\n    if (newval.op == TOK.arrayLiteral)\n        return true; //((ArrayLiteralExp *)newval)->ownedByCtfe;\n    if (newval.op == TOK.assocArrayLiteral)\n        return true; //((AssocArrayLiteralExp *)newval)->ownedByCtfe;\n    if (newval.op == TOK.structLiteral)\n        return true; //((StructLiteralExp *)newval)->ownedByCtfe;\n    if (newval.op == TOK.classReference)\n        return true;\n    if (newval.op == TOK.vector)\n        return true; // vector literal\n    if (newval.op == TOK.function_)\n        return true; // function literal or delegate literal\n    if (newval.op == TOK.delegate_)\n    {\n        // &struct.func or &clasinst.func\n        // &nestedfunc\n        Expression ethis = (cast(DelegateExp)newval).e1;\n        return (ethis.op == TOK.structLiteral || ethis.op == TOK.classReference || ethis.op == TOK.variable && (cast(VarExp)ethis).var == (cast(DelegateExp)newval).func);\n    }\n    if (newval.op == TOK.symbolOffset)\n    {\n        // function pointer, or pointer to static variable\n        Declaration d = (cast(SymOffExp)newval).var;\n        return d.isFuncDeclaration() || d.isDataseg();\n    }\n    if (newval.op == TOK.typeid_)\n    {\n        // always valid\n        return true;\n    }\n    if (newval.op == TOK.address)\n    {\n        // e1 should be a CTFE reference\n        Expression e1 = (cast(AddrExp)newval).e1;\n        return tb.ty == Tpointer && (e1.op == TOK.structLiteral && isCtfeValueValid(e1) || e1.op == TOK.variable || e1.op == TOK.dotVariable && isCtfeReferenceValid(e1) || e1.op == TOK.index && isCtfeReferenceValid(e1) || e1.op == TOK.slice && e1.type.toBasetype().ty == Tsarray);\n    }\n    if (newval.op == TOK.slice)\n    {\n        // e1 should be an array aggregate\n        const SliceExp se = cast(SliceExp)newval;\n        assert(se.lwr && se.lwr.op == TOK.int64);\n        assert(se.upr && se.upr.op == TOK.int64);\n        return (tb.ty == Tarray || tb.ty == Tsarray) && (se.e1.op == TOK.string_ || se.e1.op == TOK.arrayLiteral);\n    }\n    if (newval.op == TOK.void_)\n        return true; // uninitialized value\n    newval.error(\"CTFE internal error: illegal CTFE value `%s`\", newval.toChars());\n    return false;\n}\n\nbool isCtfeReferenceValid(Expression newval)\n{\n    if (newval.op == TOK.this_)\n        return true;\n    if (newval.op == TOK.variable)\n    {\n        const VarDeclaration v = (cast(VarExp)newval).var.isVarDeclaration();\n        assert(v);\n        // Must not be a reference to a reference\n        return true;\n    }\n    if (newval.op == TOK.index)\n    {\n        const Expression eagg = (cast(IndexExp)newval).e1;\n        return eagg.op == TOK.string_ || eagg.op == TOK.arrayLiteral || eagg.op == TOK.assocArrayLiteral;\n    }\n    if (newval.op == TOK.dotVariable)\n    {\n        Expression eagg = (cast(DotVarExp)newval).e1;\n        return (eagg.op == TOK.structLiteral || eagg.op == TOK.classReference) && isCtfeValueValid(eagg);\n    }\n    // Internally a ref variable may directly point a stack memory.\n    // e.g. ref int v = 1;\n    return isCtfeValueValid(newval);\n}\n\n// Used for debugging only\nvoid showCtfeExpr(Expression e, int level = 0)\n{\n    for (int i = level; i > 0; --i)\n        printf(\" \");\n    Expressions* elements = null;\n    // We need the struct definition to detect block assignment\n    StructDeclaration sd = null;\n    ClassDeclaration cd = null;\n    if (e.op == TOK.structLiteral)\n    {\n        elements = (cast(StructLiteralExp)e).elements;\n        sd = (cast(StructLiteralExp)e).sd;\n        printf(\"STRUCT type = %s %p:\\n\", e.type.toChars(), e);\n    }\n    else if (e.op == TOK.classReference)\n    {\n        elements = (cast(ClassReferenceExp)e).value.elements;\n        cd = (cast(ClassReferenceExp)e).originalClass();\n        printf(\"CLASS type = %s %p:\\n\", e.type.toChars(), (cast(ClassReferenceExp)e).value);\n    }\n    else if (e.op == TOK.arrayLiteral)\n    {\n        elements = (cast(ArrayLiteralExp)e).elements;\n        printf(\"ARRAY LITERAL type=%s %p:\\n\", e.type.toChars(), e);\n    }\n    else if (e.op == TOK.assocArrayLiteral)\n    {\n        printf(\"AA LITERAL type=%s %p:\\n\", e.type.toChars(), e);\n    }\n    else if (e.op == TOK.string_)\n    {\n        printf(\"STRING %s %p\\n\", e.toChars(), (cast(StringExp)e).string);\n    }\n    else if (e.op == TOK.slice)\n    {\n        printf(\"SLICE %p: %s\\n\", e, e.toChars());\n        showCtfeExpr((cast(SliceExp)e).e1, level + 1);\n    }\n    else if (e.op == TOK.variable)\n    {\n        printf(\"VAR %p %s\\n\", e, e.toChars());\n        VarDeclaration v = (cast(VarExp)e).var.isVarDeclaration();\n        if (v && getValue(v))\n            showCtfeExpr(getValue(v), level + 1);\n    }\n    else if (e.op == TOK.address)\n    {\n        // This is potentially recursive. We mustn't try to print the thing we're pointing to.\n        printf(\"POINTER %p to %p: %s\\n\", e, (cast(AddrExp)e).e1, e.toChars());\n    }\n    else\n        printf(\"VALUE %p: %s\\n\", e, e.toChars());\n    if (elements)\n    {\n        size_t fieldsSoFar = 0;\n        for (size_t i = 0; i < elements.dim; i++)\n        {\n            Expression z = null;\n            VarDeclaration v = null;\n            if (i > 15)\n            {\n                printf(\"...(total %d elements)\\n\", cast(int)elements.dim);\n                return;\n            }\n            if (sd)\n            {\n                v = sd.fields[i];\n                z = (*elements)[i];\n            }\n            else if (cd)\n            {\n                while (i - fieldsSoFar >= cd.fields.dim)\n                {\n                    fieldsSoFar += cd.fields.dim;\n                    cd = cd.baseClass;\n                    for (int j = level; j > 0; --j)\n                        printf(\" \");\n                    printf(\" BASE CLASS: %s\\n\", cd.toChars());\n                }\n                v = cd.fields[i - fieldsSoFar];\n                assert((elements.dim + i) >= (fieldsSoFar + cd.fields.dim));\n                size_t indx = (elements.dim - fieldsSoFar) - cd.fields.dim + i;\n                assert(indx < elements.dim);\n                z = (*elements)[indx];\n            }\n            if (!z)\n            {\n                for (int j = level; j > 0; --j)\n                    printf(\" \");\n                printf(\" void\\n\");\n                continue;\n            }\n            if (v)\n            {\n                // If it is a void assignment, use the default initializer\n                if ((v.type.ty != z.type.ty) && v.type.ty == Tsarray)\n                {\n                    for (int j = level; --j;)\n                        printf(\" \");\n                    printf(\" field: block initialized static array\\n\");\n                    continue;\n                }\n            }\n            showCtfeExpr(z, level + 1);\n        }\n    }\n}\n\n/*************************** Void initialization ***************************/\nUnionExp voidInitLiteral(Type t, VarDeclaration var)\n{\n    UnionExp ue;\n    if (t.ty == Tsarray)\n    {\n        TypeSArray tsa = cast(TypeSArray)t;\n        Expression elem = voidInitLiteral(tsa.next, var).copy();\n        // For aggregate value types (structs, static arrays) we must\n        // create an a separate copy for each element.\n        const mustCopy = (elem.op == TOK.arrayLiteral || elem.op == TOK.structLiteral);\n        const d = cast(size_t)tsa.dim.toInteger();\n        auto elements = new Expressions(d);\n        foreach (i; 0 .. d)\n        {\n            if (mustCopy && i > 0)\n                elem = copyLiteral(elem).copy();\n            (*elements)[i] = elem;\n        }\n        emplaceExp!(ArrayLiteralExp)(&ue, var.loc, tsa, elements);\n        ArrayLiteralExp ae = cast(ArrayLiteralExp)ue.exp();\n        ae.ownedByCtfe = OwnedBy.ctfe;\n    }\n    else if (t.ty == Tstruct)\n    {\n        TypeStruct ts = cast(TypeStruct)t;\n        auto exps = new Expressions(ts.sym.fields.dim);\n        foreach (size_t i;  0 .. ts.sym.fields.dim)\n        {\n            (*exps)[i] = voidInitLiteral(ts.sym.fields[i].type, ts.sym.fields[i]).copy();\n        }\n        emplaceExp!(StructLiteralExp)(&ue, var.loc, ts.sym, exps);\n        StructLiteralExp se = cast(StructLiteralExp)ue.exp();\n        se.type = ts;\n        se.ownedByCtfe = OwnedBy.ctfe;\n    }\n    else\n        emplaceExp!(VoidInitExp)(&ue, var);\n    return ue;\n}\n"
  },
  {
    "path": "gcc/d/dmd/ctorflow.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Manage flow analysis for constructors.\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/ctorflow.d, _ctorflow.d)\n * Documentation:  https://dlang.org/phobos/dmd_ctorflow.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/ctorflow.d\n */\n\nmodule dmd.ctorflow;\n\nimport core.stdc.stdio;\n\nimport dmd.root.rmem;\nimport dmd.globals : Loc;\n\nenum CSX : ushort\n{\n    none            = 0,\n    this_ctor       = 0x01,     /// called this()\n    super_ctor      = 0x02,     /// called super()\n    label           = 0x04,     /// seen a label\n    return_         = 0x08,     /// seen a return statement\n    any_ctor        = 0x10,     /// either this() or super() was called\n    halt            = 0x20,     /// assert(0)\n    deprecate_18719 = 0x40,    // issue deprecation for Issue 18719 - delete when deprecation period is over\n}\n\n/// Individual field in the Ctor with information about its callees and location.\nstruct FieldInit\n{\n    CSX csx; /// information about the field's callees\n    Loc loc; /// location of the field initialization\n}\n\n/***********\n * Primitive flow analysis for constructors\n */\nstruct CtorFlow\n{\n    CSX callSuper;      /// state of calling other constructors\n\n    FieldInit[] fieldinit;    /// state of field initializations\n\n    void allocFieldinit(size_t dim)\n    {\n        fieldinit = (cast(FieldInit*)mem.xcalloc(FieldInit.sizeof, dim))[0 .. dim];\n    }\n\n    void freeFieldinit()\n    {\n        if (fieldinit.ptr)\n            mem.xfree(fieldinit.ptr);\n\n        fieldinit = null;\n    }\n\n    /***********************\n     * Create a deep copy of `this`\n     * Returns:\n     *  a copy\n     */\n    CtorFlow clone()\n    {\n        return CtorFlow(callSuper, fieldinit.arraydup);\n    }\n\n    /**********************************\n     * Set CSX bits in flow analysis state\n     * Params:\n     *  csx = bits to set\n     */\n    void orCSX(CSX csx) nothrow pure\n    {\n        callSuper |= csx;\n        foreach (ref u; fieldinit)\n            u.csx |= csx;\n    }\n\n    /******************************\n     * OR CSX bits to `this`\n     * Params:\n     *  ctorflow = bits to OR in\n     */\n    void OR(const ref CtorFlow ctorflow) pure nothrow\n    {\n        callSuper |= ctorflow.callSuper;\n        if (fieldinit.length && ctorflow.fieldinit.length)\n        {\n            assert(fieldinit.length == ctorflow.fieldinit.length);\n            foreach (i, u; ctorflow.fieldinit)\n            {\n                auto fi = &fieldinit[i];\n                fi.csx |= u.csx;\n                if (fi.loc == Loc.init)\n                    fi.loc = u.loc;\n            }\n        }\n    }\n}\n\n\n/****************************************\n * Merge `b` flow analysis results into `a`.\n * Params:\n *      a = the path to merge `b` into\n *      b = the other path\n * Returns:\n *      false means one of the paths skips construction\n */\nbool mergeCallSuper(ref CSX a, const CSX b) pure nothrow\n{\n    // This does a primitive flow analysis to support the restrictions\n    // regarding when and how constructors can appear.\n    // It merges the results of two paths.\n    // The two paths are `a` and `b`; the result is merged into `a`.\n    if (b == a)\n        return true;\n\n    // Have ALL branches called a constructor?\n    const aAll = (a & (CSX.this_ctor | CSX.super_ctor)) != 0;\n    const bAll = (b & (CSX.this_ctor | CSX.super_ctor)) != 0;\n    // Have ANY branches called a constructor?\n    const aAny = (a & CSX.any_ctor) != 0;\n    const bAny = (b & CSX.any_ctor) != 0;\n    // Have any branches returned?\n    const aRet = (a & CSX.return_) != 0;\n    const bRet = (b & CSX.return_) != 0;\n    // Have any branches halted?\n    const aHalt = (a & CSX.halt) != 0;\n    const bHalt = (b & CSX.halt) != 0;\n    if (aHalt && bHalt)\n    {\n        a = CSX.halt;\n    }\n    else if ((!bHalt && bRet && !bAny && aAny) || (!aHalt && aRet && !aAny && bAny))\n    {\n        // If one has returned without a constructor call, there must not\n        // be ctor calls in the other.\n        return false;\n    }\n    else if (bHalt || bRet && bAll)\n    {\n        // If one branch has called a ctor and then exited, anything the\n        // other branch has done is OK (except returning without a\n        // ctor call, but we already checked that).\n        a |= b & (CSX.any_ctor | CSX.label);\n    }\n    else if (aHalt || aRet && aAll)\n    {\n        a = cast(CSX)(b | (a & (CSX.any_ctor | CSX.label)));\n    }\n    else if (aAll != bAll) // both branches must have called ctors, or both not\n        return false;\n    else\n    {\n        // If one returned without a ctor, remember that\n        if (bRet && !bAny)\n            a |= CSX.return_;\n        a |= b & (CSX.any_ctor | CSX.label);\n    }\n    return true;\n}\n\n\n/****************************************\n * Merge `b` flow analysis results into `a`.\n * Params:\n *      a = the path to merge `b` into\n *      b = the other path\n * Returns:\n *      false means either `a` or `b` skips initialization\n */\nbool mergeFieldInit(ref CSX a, const CSX b) pure nothrow\n{\n    if (b == a)\n        return true;\n\n    // Have any branches returned?\n    const aRet = (a & CSX.return_) != 0;\n    const bRet = (b & CSX.return_) != 0;\n    // Have any branches halted?\n    const aHalt = (a & CSX.halt) != 0;\n    const bHalt = (b & CSX.halt) != 0;\n\n    if (aHalt && bHalt)\n    {\n        a = CSX.halt;\n        return true;\n    }\n\n    bool ok;\n    if (!bHalt && bRet)\n    {\n        ok = (b & CSX.this_ctor);\n        a = a;\n    }\n    else if (!aHalt && aRet)\n    {\n        ok = (a & CSX.this_ctor);\n        a = b;\n    }\n    else if (bHalt)\n    {\n        ok = (a & CSX.this_ctor);\n        a = a;\n    }\n    else if (aHalt)\n    {\n        ok = (b & CSX.this_ctor);\n        a = b;\n    }\n    else\n    {\n        ok = !((a ^ b) & CSX.this_ctor);\n        a |= b;\n    }\n    return ok;\n}\n\n"
  },
  {
    "path": "gcc/d/dmd/dcast.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dcast.d, _dcast.d)\n * Documentation:  https://dlang.org/phobos/dmd_dcast.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dcast.d\n */\n\nmodule dmd.dcast;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arrayop;\nimport dmd.arraytypes;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.errors;\nimport dmd.escape;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.impcnvtab;\nimport dmd.id;\nimport dmd.init;\nimport dmd.intrange;\nimport dmd.mtype;\nimport dmd.opover;\nimport dmd.root.ctfloat;\nimport dmd.root.outbuffer;\nimport dmd.root.rmem;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.utf;\nimport dmd.visitor;\n\nenum LOG = false;\n\n/**************************************\n * Do an implicit cast.\n * Issue error if it can't be done.\n */\nExpression implicitCastTo(Expression e, Scope* sc, Type t)\n{\n    extern (C++) final class ImplicitCastTo : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        Type t;\n        Scope* sc;\n        Expression result;\n\n        extern (D) this(Scope* sc, Type t)\n        {\n            this.sc = sc;\n            this.t = t;\n        }\n\n        override void visit(Expression e)\n        {\n            //printf(\"Expression.implicitCastTo(%s of type %s) => %s\\n\", e.toChars(), e.type.toChars(), t.toChars());\n\n            MATCH match = e.implicitConvTo(t);\n            if (match)\n            {\n                if (match == MATCH.constant && (e.type.constConv(t) || !e.isLvalue() && e.type.equivalent(t)))\n                {\n                    /* Do not emit CastExp for const conversions and\n                     * unique conversions on rvalue.\n                     */\n                    result = e.copy();\n                    result.type = t;\n                    return;\n                }\n                result = e.castTo(sc, t);\n                return;\n            }\n\n            result = e.optimize(WANTvalue);\n            if (result != e)\n            {\n                result.accept(this);\n                return;\n            }\n\n            if (t.ty != Terror && e.type.ty != Terror)\n            {\n                if (!t.deco)\n                {\n                    e.error(\"forward reference to type `%s`\", t.toChars());\n                }\n                else\n                {\n                    //printf(\"type %p ty %d deco %p\\n\", type, type.ty, type.deco);\n                    //type = type.typeSemantic(loc, sc);\n                    //printf(\"type %s t %s\\n\", type.deco, t.deco);\n                    auto ts = toAutoQualChars(e.type, t);\n                    e.error(\"cannot implicitly convert expression `%s` of type `%s` to `%s`\",\n                        e.toChars(), ts[0], ts[1]);\n                }\n            }\n            result = new ErrorExp();\n        }\n\n        override void visit(StringExp e)\n        {\n            //printf(\"StringExp::implicitCastTo(%s of type %s) => %s\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            visit(cast(Expression)e);\n            if (result.op == TOK.string_)\n            {\n                // Retain polysemous nature if it started out that way\n                (cast(StringExp)result).committed = e.committed;\n            }\n        }\n\n        override void visit(ErrorExp e)\n        {\n            result = e;\n        }\n\n        override void visit(FuncExp e)\n        {\n            //printf(\"FuncExp::implicitCastTo type = %p %s, t = %s\\n\", e.type, e.type ? e.type.toChars() : NULL, t.toChars());\n            FuncExp fe;\n            if (e.matchType(t, sc, &fe) > MATCH.nomatch)\n            {\n                result = fe;\n                return;\n            }\n            visit(cast(Expression)e);\n        }\n\n        override void visit(ArrayLiteralExp e)\n        {\n            visit(cast(Expression)e);\n\n            Type tb = result.type.toBasetype();\n            if (tb.ty == Tarray && global.params.useTypeInfo && Type.dtypeinfo)\n                semanticTypeInfo(sc, (cast(TypeDArray)tb).next);\n        }\n\n        override void visit(SliceExp e)\n        {\n            visit(cast(Expression)e);\n            if (result.op != TOK.slice)\n                return;\n\n            e = cast(SliceExp)result;\n            if (e.e1.op == TOK.arrayLiteral)\n            {\n                ArrayLiteralExp ale = cast(ArrayLiteralExp)e.e1;\n                Type tb = t.toBasetype();\n                Type tx;\n                if (tb.ty == Tsarray)\n                    tx = tb.nextOf().sarrayOf(ale.elements ? ale.elements.dim : 0);\n                else\n                    tx = tb.nextOf().arrayOf();\n                e.e1 = ale.implicitCastTo(sc, tx);\n            }\n        }\n    }\n\n    scope ImplicitCastTo v = new ImplicitCastTo(sc, t);\n    e.accept(v);\n    return v.result;\n}\n\n/*******************************************\n * Return MATCH level of implicitly converting e to type t.\n * Don't do the actual cast; don't change e.\n */\nMATCH implicitConvTo(Expression e, Type t)\n{\n    extern (C++) final class ImplicitConvTo : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        Type t;\n        MATCH result;\n\n        extern (D) this(Type t)\n        {\n            this.t = t;\n            result = MATCH.nomatch;\n        }\n\n        override void visit(Expression e)\n        {\n            version (none)\n            {\n                printf(\"Expression::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            //static int nest; if (++nest == 10) assert(0);\n            if (t == Type.terror)\n                return;\n            if (!e.type)\n            {\n                e.error(\"`%s` is not an expression\", e.toChars());\n                e.type = Type.terror;\n            }\n\n            Expression ex = e.optimize(WANTvalue);\n            if (ex.type.equals(t))\n            {\n                result = MATCH.exact;\n                return;\n            }\n            if (ex != e)\n            {\n                //printf(\"\\toptimized to %s of type %s\\n\", e.toChars(), e.type.toChars());\n                result = ex.implicitConvTo(t);\n                return;\n            }\n\n            MATCH match = e.type.implicitConvTo(t);\n            if (match != MATCH.nomatch)\n            {\n                result = match;\n                return;\n            }\n\n            /* See if we can do integral narrowing conversions\n             */\n            if (e.type.isintegral() && t.isintegral() && e.type.isTypeBasic() && t.isTypeBasic())\n            {\n                IntRange src = getIntRange(e);\n                IntRange target = IntRange.fromType(t);\n                if (target.contains(src))\n                {\n                    result = MATCH.convert;\n                    return;\n                }\n            }\n        }\n\n        /******\n         * Given expression e of type t, see if we can implicitly convert e\n         * to type tprime, where tprime is type t with mod bits added.\n         * Returns:\n         *      match level\n         */\n        static MATCH implicitMod(Expression e, Type t, MOD mod)\n        {\n            Type tprime;\n            if (t.ty == Tpointer)\n                tprime = t.nextOf().castMod(mod).pointerTo();\n            else if (t.ty == Tarray)\n                tprime = t.nextOf().castMod(mod).arrayOf();\n            else if (t.ty == Tsarray)\n                tprime = t.nextOf().castMod(mod).sarrayOf(t.size() / t.nextOf().size());\n            else\n                tprime = t.castMod(mod);\n\n            return e.implicitConvTo(tprime);\n        }\n\n        static MATCH implicitConvToAddMin(BinExp e, Type t)\n        {\n            /* Is this (ptr +- offset)? If so, then ask ptr\n             * if the conversion can be done.\n             * This is to support doing things like implicitly converting a mutable unique\n             * pointer to an immutable pointer.\n             */\n\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            if (typeb.ty != Tpointer || tb.ty != Tpointer)\n                return MATCH.nomatch;\n\n            Type t1b = e.e1.type.toBasetype();\n            Type t2b = e.e2.type.toBasetype();\n            if (t1b.ty == Tpointer && t2b.isintegral() && t1b.equivalent(tb))\n            {\n                // ptr + offset\n                // ptr - offset\n                MATCH m = e.e1.implicitConvTo(t);\n                return (m > MATCH.constant) ? MATCH.constant : m;\n            }\n            if (t2b.ty == Tpointer && t1b.isintegral() && t2b.equivalent(tb))\n            {\n                // offset + ptr\n                MATCH m = e.e2.implicitConvTo(t);\n                return (m > MATCH.constant) ? MATCH.constant : m;\n            }\n\n            return MATCH.nomatch;\n        }\n\n        override void visit(AddExp e)\n        {\n            version (none)\n            {\n                printf(\"AddExp::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            visit(cast(Expression)e);\n            if (result == MATCH.nomatch)\n                result = implicitConvToAddMin(e, t);\n        }\n\n        override void visit(MinExp e)\n        {\n            version (none)\n            {\n                printf(\"MinExp::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            visit(cast(Expression)e);\n            if (result == MATCH.nomatch)\n                result = implicitConvToAddMin(e, t);\n        }\n\n        override void visit(IntegerExp e)\n        {\n            version (none)\n            {\n                printf(\"IntegerExp::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            MATCH m = e.type.implicitConvTo(t);\n            if (m >= MATCH.constant)\n            {\n                result = m;\n                return;\n            }\n\n            TY ty = e.type.toBasetype().ty;\n            TY toty = t.toBasetype().ty;\n            TY oldty = ty;\n\n            if (m == MATCH.nomatch && t.ty == Tenum)\n                return;\n\n            if (t.ty == Tvector)\n            {\n                TypeVector tv = cast(TypeVector)t;\n                TypeBasic tb = tv.elementType();\n                if (tb.ty == Tvoid)\n                    return;\n                toty = tb.ty;\n            }\n\n            switch (ty)\n            {\n            case Tbool:\n            case Tint8:\n            case Tchar:\n            case Tuns8:\n            case Tint16:\n            case Tuns16:\n            case Twchar:\n                ty = Tint32;\n                break;\n\n            case Tdchar:\n                ty = Tuns32;\n                break;\n\n            default:\n                break;\n            }\n\n            // Only allow conversion if no change in value\n            immutable dinteger_t value = e.toInteger();\n\n            bool isLosslesslyConvertibleToFP(T)()\n            {\n                if (e.type.isunsigned())\n                {\n                    const f = cast(T) value;\n                    return cast(dinteger_t) f == value;\n                }\n\n                const f = cast(T) cast(sinteger_t) value;\n                return cast(sinteger_t) f == cast(sinteger_t) value;\n            }\n\n            switch (toty)\n            {\n            case Tbool:\n                if ((value & 1) != value)\n                    return;\n                break;\n\n            case Tint8:\n                if (ty == Tuns64 && value & ~0x7FU)\n                    return;\n                else if (cast(byte)value != value)\n                    return;\n                break;\n\n            case Tchar:\n                if ((oldty == Twchar || oldty == Tdchar) && value > 0x7F)\n                    return;\n                goto case Tuns8;\n            case Tuns8:\n                //printf(\"value = %llu %llu\\n\", (dinteger_t)(unsigned char)value, value);\n                if (cast(ubyte)value != value)\n                    return;\n                break;\n\n            case Tint16:\n                if (ty == Tuns64 && value & ~0x7FFFU)\n                    return;\n                else if (cast(short)value != value)\n                    return;\n                break;\n\n            case Twchar:\n                if (oldty == Tdchar && value > 0xD7FF && value < 0xE000)\n                    return;\n                goto case Tuns16;\n            case Tuns16:\n                if (cast(ushort)value != value)\n                    return;\n                break;\n\n            case Tint32:\n                if (ty == Tuns32)\n                {\n                }\n                else if (ty == Tuns64 && value & ~0x7FFFFFFFU)\n                    return;\n                else if (cast(int)value != value)\n                    return;\n                break;\n\n            case Tuns32:\n                if (ty == Tint32)\n                {\n                }\n                else if (cast(uint)value != value)\n                    return;\n                break;\n\n            case Tdchar:\n                if (value > 0x10FFFFU)\n                    return;\n                break;\n\n            case Tfloat32:\n                if (!isLosslesslyConvertibleToFP!float)\n                    return;\n                break;\n\n            case Tfloat64:\n                if (!isLosslesslyConvertibleToFP!double)\n                    return;\n                break;\n\n            case Tfloat80:\n                if (!isLosslesslyConvertibleToFP!real_t)\n                    return;\n                break;\n\n            case Tpointer:\n                //printf(\"type = %s\\n\", type.toBasetype()->toChars());\n                //printf(\"t = %s\\n\", t.toBasetype()->toChars());\n                if (ty == Tpointer && e.type.toBasetype().nextOf().ty == t.toBasetype().nextOf().ty)\n                {\n                    /* Allow things like:\n                     *      const char* P = cast(char *)3;\n                     *      char* q = P;\n                     */\n                    break;\n                }\n                goto default;\n\n            default:\n                visit(cast(Expression)e);\n                return;\n            }\n\n            //printf(\"MATCH.convert\\n\");\n            result = MATCH.convert;\n        }\n\n        override void visit(ErrorExp e)\n        {\n            // no match\n        }\n\n        override void visit(NullExp e)\n        {\n            version (none)\n            {\n                printf(\"NullExp::implicitConvTo(this=%s, type=%s, t=%s, committed = %d)\\n\", e.toChars(), e.type.toChars(), t.toChars(), e.committed);\n            }\n            if (e.type.equals(t))\n            {\n                result = MATCH.exact;\n                return;\n            }\n\n            /* Allow implicit conversions from immutable to mutable|const,\n             * and mutable to immutable. It works because, after all, a null\n             * doesn't actually point to anything.\n             */\n            if (t.equivalent(e.type))\n            {\n                result = MATCH.constant;\n                return;\n            }\n\n            visit(cast(Expression)e);\n        }\n\n        override void visit(StructLiteralExp e)\n        {\n            version (none)\n            {\n                printf(\"StructLiteralExp::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            visit(cast(Expression)e);\n            if (result != MATCH.nomatch)\n                return;\n            if (e.type.ty == t.ty && e.type.ty == Tstruct && (cast(TypeStruct)e.type).sym == (cast(TypeStruct)t).sym)\n            {\n                result = MATCH.constant;\n                for (size_t i = 0; i < e.elements.dim; i++)\n                {\n                    Expression el = (*e.elements)[i];\n                    if (!el)\n                        continue;\n                    Type te = e.sd.fields[i].type.addMod(t.mod);\n                    MATCH m2 = el.implicitConvTo(te);\n                    //printf(\"\\t%s => %s, match = %d\\n\", el.toChars(), te.toChars(), m2);\n                    if (m2 < result)\n                        result = m2;\n                }\n            }\n        }\n\n        override void visit(StringExp e)\n        {\n            version (none)\n            {\n                printf(\"StringExp::implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\\n\", e.toChars(), e.committed, e.type.toChars(), t.toChars());\n            }\n            if (!e.committed && t.ty == Tpointer && t.nextOf().ty == Tvoid)\n                return;\n\n            if (e.type.ty == Tsarray || e.type.ty == Tarray || e.type.ty == Tpointer)\n            {\n                TY tyn = e.type.nextOf().ty;\n                if (tyn == Tchar || tyn == Twchar || tyn == Tdchar)\n                {\n                    switch (t.ty)\n                    {\n                    case Tsarray:\n                        if (e.type.ty == Tsarray)\n                        {\n                            TY tynto = t.nextOf().ty;\n                            if (tynto == tyn)\n                            {\n                                if ((cast(TypeSArray)e.type).dim.toInteger() == (cast(TypeSArray)t).dim.toInteger())\n                                {\n                                    result = MATCH.exact;\n                                }\n                                return;\n                            }\n                            if (tynto == Tchar || tynto == Twchar || tynto == Tdchar)\n                            {\n                                if (e.committed && tynto != tyn)\n                                    return;\n                                size_t fromlen = e.numberOfCodeUnits(tynto);\n                                size_t tolen = cast(size_t)(cast(TypeSArray)t).dim.toInteger();\n                                if (tolen < fromlen)\n                                    return;\n                                if (tolen != fromlen)\n                                {\n                                    // implicit length extending\n                                    result = MATCH.convert;\n                                    return;\n                                }\n                            }\n                            if (!e.committed && (tynto == Tchar || tynto == Twchar || tynto == Tdchar))\n                            {\n                                result = MATCH.exact;\n                                return;\n                            }\n                        }\n                        else if (e.type.ty == Tarray)\n                        {\n                            TY tynto = t.nextOf().ty;\n                            if (tynto == Tchar || tynto == Twchar || tynto == Tdchar)\n                            {\n                                if (e.committed && tynto != tyn)\n                                    return;\n                                size_t fromlen = e.numberOfCodeUnits(tynto);\n                                size_t tolen = cast(size_t)(cast(TypeSArray)t).dim.toInteger();\n                                if (tolen < fromlen)\n                                    return;\n                                if (tolen != fromlen)\n                                {\n                                    // implicit length extending\n                                    result = MATCH.convert;\n                                    return;\n                                }\n                            }\n                            if (tynto == tyn)\n                            {\n                                result = MATCH.exact;\n                                return;\n                            }\n                            if (!e.committed && (tynto == Tchar || tynto == Twchar || tynto == Tdchar))\n                            {\n                                result = MATCH.exact;\n                                return;\n                            }\n                        }\n                        goto case; /+ fall through +/\n                    case Tarray:\n                    case Tpointer:\n                        Type tn = t.nextOf();\n                        MATCH m = MATCH.exact;\n                        if (e.type.nextOf().mod != tn.mod)\n                        {\n                            // https://issues.dlang.org/show_bug.cgi?id=16183\n                            if (!tn.isConst() && !tn.isImmutable())\n                                return;\n                            m = MATCH.constant;\n                        }\n                        if (!e.committed)\n                        {\n                            switch (tn.ty)\n                            {\n                            case Tchar:\n                                if (e.postfix == 'w' || e.postfix == 'd')\n                                    m = MATCH.convert;\n                                result = m;\n                                return;\n                            case Twchar:\n                                if (e.postfix != 'w')\n                                    m = MATCH.convert;\n                                result = m;\n                                return;\n                            case Tdchar:\n                                if (e.postfix != 'd')\n                                    m = MATCH.convert;\n                                result = m;\n                                return;\n                            default:\n                                break;\n                            }\n                        }\n                        break;\n\n                    default:\n                        break;\n                    }\n                }\n            }\n\n            visit(cast(Expression)e);\n        }\n\n        override void visit(ArrayLiteralExp e)\n        {\n            version (none)\n            {\n                printf(\"ArrayLiteralExp::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            if ((tb.ty == Tarray || tb.ty == Tsarray) &&\n                (typeb.ty == Tarray || typeb.ty == Tsarray))\n            {\n                result = MATCH.exact;\n                Type typen = typeb.nextOf().toBasetype();\n\n                if (tb.ty == Tsarray)\n                {\n                    TypeSArray tsa = cast(TypeSArray)tb;\n                    if (e.elements.dim != tsa.dim.toInteger())\n                        result = MATCH.nomatch;\n                }\n\n                Type telement = tb.nextOf();\n                if (!e.elements.dim)\n                {\n                    if (typen.ty != Tvoid)\n                        result = typen.implicitConvTo(telement);\n                }\n                else\n                {\n                    if (e.basis)\n                    {\n                        MATCH m = e.basis.implicitConvTo(telement);\n                        if (m < result)\n                            result = m;\n                    }\n                    for (size_t i = 0; i < e.elements.dim; i++)\n                    {\n                        Expression el = (*e.elements)[i];\n                        if (result == MATCH.nomatch)\n                            break;\n                        if (!el)\n                            continue;\n                        MATCH m = el.implicitConvTo(telement);\n                        if (m < result)\n                            result = m; // remember worst match\n                    }\n                }\n\n                if (!result)\n                    result = e.type.implicitConvTo(t);\n\n                return;\n            }\n            else if (tb.ty == Tvector && (typeb.ty == Tarray || typeb.ty == Tsarray))\n            {\n                result = MATCH.exact;\n                // Convert array literal to vector type\n                TypeVector tv = cast(TypeVector)tb;\n                TypeSArray tbase = cast(TypeSArray)tv.basetype;\n                assert(tbase.ty == Tsarray);\n                const edim = e.elements.dim;\n                const tbasedim = tbase.dim.toInteger();\n                if (edim > tbasedim)\n                {\n                    result = MATCH.nomatch;\n                    return;\n                }\n\n                Type telement = tv.elementType();\n                if (edim < tbasedim)\n                {\n                    Expression el = typeb.nextOf.defaultInitLiteral(e.loc);\n                    MATCH m = el.implicitConvTo(telement);\n                    if (m < result)\n                        result = m; // remember worst match\n                }\n                foreach (i; 0 .. edim)\n                {\n                    Expression el = (*e.elements)[i];\n                    MATCH m = el.implicitConvTo(telement);\n                    if (m < result)\n                        result = m; // remember worst match\n                    if (result == MATCH.nomatch)\n                        break; // no need to check for worse\n                }\n                return;\n            }\n\n            visit(cast(Expression)e);\n        }\n\n        override void visit(AssocArrayLiteralExp e)\n        {\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            if (tb.ty == Taarray && typeb.ty == Taarray)\n            {\n                result = MATCH.exact;\n                for (size_t i = 0; i < e.keys.dim; i++)\n                {\n                    Expression el = (*e.keys)[i];\n                    MATCH m = el.implicitConvTo((cast(TypeAArray)tb).index);\n                    if (m < result)\n                        result = m; // remember worst match\n                    if (result == MATCH.nomatch)\n                        break; // no need to check for worse\n                    el = (*e.values)[i];\n                    m = el.implicitConvTo(tb.nextOf());\n                    if (m < result)\n                        result = m; // remember worst match\n                    if (result == MATCH.nomatch)\n                        break; // no need to check for worse\n                }\n                return;\n            }\n            else\n                visit(cast(Expression)e);\n        }\n\n        override void visit(CallExp e)\n        {\n            enum LOG = false;\n            static if (LOG)\n            {\n                printf(\"CallExp::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n\n            visit(cast(Expression)e);\n            if (result != MATCH.nomatch)\n                return;\n\n            /* Allow the result of strongly pure functions to\n             * convert to immutable\n             */\n            if (e.f && e.f.isReturnIsolated() &&\n                (!global.params.vsafe ||        // lots of legacy code breaks with the following purity check\n                 e.f.isPure() >= PURE.strong ||\n                 // Special case exemption for Object.dup() which we assume is implemented correctly\n                 e.f.ident == Id.dup &&\n                 e.f.toParent2() == ClassDeclaration.object.toParent())\n               )\n            {\n                result = e.type.immutableOf().implicitConvTo(t);\n                if (result > MATCH.constant) // Match level is MATCH.constant at best.\n                    result = MATCH.constant;\n                return;\n            }\n\n            /* Conversion is 'const' conversion if:\n             * 1. function is pure (weakly pure is ok)\n             * 2. implicit conversion only fails because of mod bits\n             * 3. each function parameter can be implicitly converted to the mod bits\n             */\n            Type tx = e.f ? e.f.type : e.e1.type;\n            tx = tx.toBasetype();\n            if (tx.ty != Tfunction)\n                return;\n            TypeFunction tf = cast(TypeFunction)tx;\n\n            if (tf.purity == PURE.impure)\n                return;\n            if (e.f && e.f.isNested())\n                return;\n\n            /* See if fail only because of mod bits.\n             *\n             * https://issues.dlang.org/show_bug.cgi?id=14155\n             * All pure functions can access global immutable data.\n             * So the returned pointer may refer an immutable global data,\n             * and then the returned pointer that points non-mutable object\n             * cannot be unique pointer.\n             *\n             * Example:\n             *  immutable g;\n             *  static this() { g = 1; }\n             *  const(int*) foo() pure { return &g; }\n             *  void test() {\n             *    immutable(int*) ip = foo(); // OK\n             *    int* mp = foo();            // should be disallowed\n             *  }\n             */\n            if (e.type.immutableOf().implicitConvTo(t) < MATCH.constant && e.type.addMod(MODFlags.shared_).implicitConvTo(t) < MATCH.constant && e.type.implicitConvTo(t.addMod(MODFlags.shared_)) < MATCH.constant)\n            {\n                return;\n            }\n            // Allow a conversion to immutable type, or\n            // conversions of mutable types between thread-local and shared.\n\n            /* Get mod bits of what we're converting to\n             */\n            Type tb = t.toBasetype();\n            MOD mod = tb.mod;\n            if (tf.isref)\n            {\n            }\n            else\n            {\n                Type ti = getIndirection(t);\n                if (ti)\n                    mod = ti.mod;\n            }\n            static if (LOG)\n            {\n                printf(\"mod = x%x\\n\", mod);\n            }\n            if (mod & MODFlags.wild)\n                return; // not sure what to do with this\n\n            /* Apply mod bits to each function parameter,\n             * and see if we can convert the function argument to the modded type\n             */\n\n            size_t nparams = Parameter.dim(tf.parameters);\n            size_t j = (tf.linkage == LINK.d && tf.varargs == 1); // if TypeInfoArray was prepended\n            if (e.e1.op == TOK.dotVariable)\n            {\n                /* Treat 'this' as just another function argument\n                 */\n                DotVarExp dve = cast(DotVarExp)e.e1;\n                Type targ = dve.e1.type;\n                if (targ.constConv(targ.castMod(mod)) == MATCH.nomatch)\n                    return;\n            }\n            for (size_t i = j; i < e.arguments.dim; ++i)\n            {\n                Expression earg = (*e.arguments)[i];\n                Type targ = earg.type.toBasetype();\n                static if (LOG)\n                {\n                    printf(\"[%d] earg: %s, targ: %s\\n\", cast(int)i, earg.toChars(), targ.toChars());\n                }\n                if (i - j < nparams)\n                {\n                    Parameter fparam = Parameter.getNth(tf.parameters, i - j);\n                    if (fparam.storageClass & STC.lazy_)\n                        return; // not sure what to do with this\n                    Type tparam = fparam.type;\n                    if (!tparam)\n                        continue;\n                    if (fparam.storageClass & (STC.out_ | STC.ref_))\n                    {\n                        if (targ.constConv(tparam.castMod(mod)) == MATCH.nomatch)\n                            return;\n                        continue;\n                    }\n                }\n                static if (LOG)\n                {\n                    printf(\"[%d] earg: %s, targm: %s\\n\", cast(int)i, earg.toChars(), targ.addMod(mod).toChars());\n                }\n                if (implicitMod(earg, targ, mod) == MATCH.nomatch)\n                    return;\n            }\n\n            /* Success\n             */\n            result = MATCH.constant;\n        }\n\n        override void visit(AddrExp e)\n        {\n            version (none)\n            {\n                printf(\"AddrExp::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            result = e.type.implicitConvTo(t);\n            //printf(\"\\tresult = %d\\n\", result);\n\n            if (result != MATCH.nomatch)\n                return;\n\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            // Look for pointers to functions where the functions are overloaded.\n            if (e.e1.op == TOK.overloadSet &&\n                (tb.ty == Tpointer || tb.ty == Tdelegate) && tb.nextOf().ty == Tfunction)\n            {\n                OverExp eo = cast(OverExp)e.e1;\n                FuncDeclaration f = null;\n                for (size_t i = 0; i < eo.vars.a.dim; i++)\n                {\n                    Dsymbol s = eo.vars.a[i];\n                    FuncDeclaration f2 = s.isFuncDeclaration();\n                    assert(f2);\n                    if (f2.overloadExactMatch(tb.nextOf()))\n                    {\n                        if (f)\n                        {\n                            /* Error if match in more than one overload set,\n                             * even if one is a 'better' match than the other.\n                             */\n                            ScopeDsymbol.multiplyDefined(e.loc, f, f2);\n                        }\n                        else\n                            f = f2;\n                        result = MATCH.exact;\n                    }\n                }\n            }\n\n            if (e.e1.op == TOK.variable &&\n                typeb.ty == Tpointer && typeb.nextOf().ty == Tfunction &&\n                tb.ty == Tpointer && tb.nextOf().ty == Tfunction)\n            {\n                /* I don't think this can ever happen -\n                 * it should have been\n                 * converted to a SymOffExp.\n                 */\n                assert(0);\n            }\n\n            //printf(\"\\tresult = %d\\n\", result);\n        }\n\n        override void visit(SymOffExp e)\n        {\n            version (none)\n            {\n                printf(\"SymOffExp::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            result = e.type.implicitConvTo(t);\n            //printf(\"\\tresult = %d\\n\", result);\n            if (result != MATCH.nomatch)\n                return;\n\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            // Look for pointers to functions where the functions are overloaded.\n            if (typeb.ty == Tpointer && typeb.nextOf().ty == Tfunction &&\n                (tb.ty == Tpointer || tb.ty == Tdelegate) && tb.nextOf().ty == Tfunction)\n            {\n                if (FuncDeclaration f = e.var.isFuncDeclaration())\n                {\n                    f = f.overloadExactMatch(tb.nextOf());\n                    if (f)\n                    {\n                        if ((tb.ty == Tdelegate && (f.needThis() || f.isNested())) ||\n                            (tb.ty == Tpointer && !(f.needThis() || f.isNested())))\n                        {\n                            result = MATCH.exact;\n                        }\n                    }\n                }\n            }\n            //printf(\"\\tresult = %d\\n\", result);\n        }\n\n        override void visit(DelegateExp e)\n        {\n            version (none)\n            {\n                printf(\"DelegateExp::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            result = e.type.implicitConvTo(t);\n            if (result != MATCH.nomatch)\n                return;\n\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            // Look for pointers to functions where the functions are overloaded.\n            if (typeb.ty == Tdelegate && tb.ty == Tdelegate)\n            {\n                if (e.func && e.func.overloadExactMatch(tb.nextOf()))\n                    result = MATCH.exact;\n            }\n        }\n\n        override void visit(FuncExp e)\n        {\n            //printf(\"FuncExp::implicitConvTo type = %p %s, t = %s\\n\", e.type, e.type ? e.type.toChars() : NULL, t.toChars());\n            MATCH m = e.matchType(t, null, null, 1);\n            if (m > MATCH.nomatch)\n            {\n                result = m;\n                return;\n            }\n            visit(cast(Expression)e);\n        }\n\n        override void visit(OrExp e)\n        {\n            visit(cast(Expression)e);\n            if (result != MATCH.nomatch)\n                return;\n\n            MATCH m1 = e.e1.implicitConvTo(t);\n            MATCH m2 = e.e2.implicitConvTo(t);\n\n            // Pick the worst match\n            result = (m1 < m2) ? m1 : m2;\n        }\n\n        override void visit(XorExp e)\n        {\n            visit(cast(Expression)e);\n            if (result != MATCH.nomatch)\n                return;\n\n            MATCH m1 = e.e1.implicitConvTo(t);\n            MATCH m2 = e.e2.implicitConvTo(t);\n\n            // Pick the worst match\n            result = (m1 < m2) ? m1 : m2;\n        }\n\n        override void visit(CondExp e)\n        {\n            MATCH m1 = e.e1.implicitConvTo(t);\n            MATCH m2 = e.e2.implicitConvTo(t);\n            //printf(\"CondExp: m1 %d m2 %d\\n\", m1, m2);\n\n            // Pick the worst match\n            result = (m1 < m2) ? m1 : m2;\n        }\n\n        override void visit(CommaExp e)\n        {\n            e.e2.accept(this);\n        }\n\n        override void visit(CastExp e)\n        {\n            version (none)\n            {\n                printf(\"CastExp::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            result = e.type.implicitConvTo(t);\n            if (result != MATCH.nomatch)\n                return;\n\n            if (t.isintegral() && e.e1.type.isintegral() && e.e1.implicitConvTo(t) != MATCH.nomatch)\n                result = MATCH.convert;\n            else\n                visit(cast(Expression)e);\n        }\n\n        override void visit(NewExp e)\n        {\n            version (none)\n            {\n                printf(\"NewExp::implicitConvTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            visit(cast(Expression)e);\n            if (result != MATCH.nomatch)\n                return;\n\n            /* Calling new() is like calling a pure function. We can implicitly convert the\n             * return from new() to t using the same algorithm as in CallExp, with the function\n             * 'arguments' being:\n             *    thisexp\n             *    newargs\n             *    arguments\n             *    .init\n             * 'member' and 'allocator' need to be pure.\n             */\n\n            /* See if fail only because of mod bits\n             */\n            if (e.type.immutableOf().implicitConvTo(t.immutableOf()) == MATCH.nomatch)\n                return;\n\n            /* Get mod bits of what we're converting to\n             */\n            Type tb = t.toBasetype();\n            MOD mod = tb.mod;\n            if (Type ti = getIndirection(t))\n                mod = ti.mod;\n            static if (LOG)\n            {\n                printf(\"mod = x%x\\n\", mod);\n            }\n            if (mod & MODFlags.wild)\n                return; // not sure what to do with this\n\n            /* Apply mod bits to each argument,\n             * and see if we can convert the argument to the modded type\n             */\n\n            if (e.thisexp)\n            {\n                /* Treat 'this' as just another function argument\n                 */\n                Type targ = e.thisexp.type;\n                if (targ.constConv(targ.castMod(mod)) == MATCH.nomatch)\n                    return;\n            }\n\n            /* Check call to 'allocator', then 'member'\n             */\n            FuncDeclaration fd = e.allocator;\n            for (int count = 0; count < 2; ++count, (fd = e.member))\n            {\n                if (!fd)\n                    continue;\n                if (fd.errors || fd.type.ty != Tfunction)\n                    return; // error\n                TypeFunction tf = cast(TypeFunction)fd.type;\n                if (tf.purity == PURE.impure)\n                    return; // impure\n\n                if (fd == e.member)\n                {\n                    if (e.type.immutableOf().implicitConvTo(t) < MATCH.constant && e.type.addMod(MODFlags.shared_).implicitConvTo(t) < MATCH.constant && e.type.implicitConvTo(t.addMod(MODFlags.shared_)) < MATCH.constant)\n                    {\n                        return;\n                    }\n                    // Allow a conversion to immutable type, or\n                    // conversions of mutable types between thread-local and shared.\n                }\n\n                Expressions* args = (fd == e.allocator) ? e.newargs : e.arguments;\n\n                size_t nparams = Parameter.dim(tf.parameters);\n                size_t j = (tf.linkage == LINK.d && tf.varargs == 1); // if TypeInfoArray was prepended\n                for (size_t i = j; i < e.arguments.dim; ++i)\n                {\n                    Expression earg = (*args)[i];\n                    Type targ = earg.type.toBasetype();\n                    static if (LOG)\n                    {\n                        printf(\"[%d] earg: %s, targ: %s\\n\", cast(int)i, earg.toChars(), targ.toChars());\n                    }\n                    if (i - j < nparams)\n                    {\n                        Parameter fparam = Parameter.getNth(tf.parameters, i - j);\n                        if (fparam.storageClass & STC.lazy_)\n                            return; // not sure what to do with this\n                        Type tparam = fparam.type;\n                        if (!tparam)\n                            continue;\n                        if (fparam.storageClass & (STC.out_ | STC.ref_))\n                        {\n                            if (targ.constConv(tparam.castMod(mod)) == MATCH.nomatch)\n                                return;\n                            continue;\n                        }\n                    }\n                    static if (LOG)\n                    {\n                        printf(\"[%d] earg: %s, targm: %s\\n\", cast(int)i, earg.toChars(), targ.addMod(mod).toChars());\n                    }\n                    if (implicitMod(earg, targ, mod) == MATCH.nomatch)\n                        return;\n                }\n            }\n\n            /* If no 'member', then construction is by simple assignment,\n             * and just straight check 'arguments'\n             */\n            if (!e.member && e.arguments)\n            {\n                for (size_t i = 0; i < e.arguments.dim; ++i)\n                {\n                    Expression earg = (*e.arguments)[i];\n                    if (!earg) // https://issues.dlang.org/show_bug.cgi?id=14853\n                               // if it's on overlapped field\n                        continue;\n                    Type targ = earg.type.toBasetype();\n                    static if (LOG)\n                    {\n                        printf(\"[%d] earg: %s, targ: %s\\n\", cast(int)i, earg.toChars(), targ.toChars());\n                        printf(\"[%d] earg: %s, targm: %s\\n\", cast(int)i, earg.toChars(), targ.addMod(mod).toChars());\n                    }\n                    if (implicitMod(earg, targ, mod) == MATCH.nomatch)\n                        return;\n                }\n            }\n\n            /* Consider the .init expression as an argument\n             */\n            Type ntb = e.newtype.toBasetype();\n            if (ntb.ty == Tarray)\n                ntb = ntb.nextOf().toBasetype();\n            if (ntb.ty == Tstruct)\n            {\n                // Don't allow nested structs - uplevel reference may not be convertible\n                StructDeclaration sd = (cast(TypeStruct)ntb).sym;\n                sd.size(e.loc); // resolve any forward references\n                if (sd.isNested())\n                    return;\n            }\n            if (ntb.isZeroInit(e.loc))\n            {\n                /* Zeros are implicitly convertible, except for special cases.\n                 */\n                if (ntb.ty == Tclass)\n                {\n                    /* With new() must look at the class instance initializer.\n                     */\n                    ClassDeclaration cd = (cast(TypeClass)ntb).sym;\n\n                    cd.size(e.loc); // resolve any forward references\n\n                    if (cd.isNested())\n                        return; // uplevel reference may not be convertible\n\n                    assert(!cd.isInterfaceDeclaration());\n\n                    struct ClassCheck\n                    {\n                        extern (C++) static bool convertible(Loc loc, ClassDeclaration cd, MOD mod)\n                        {\n                            for (size_t i = 0; i < cd.fields.dim; i++)\n                            {\n                                VarDeclaration v = cd.fields[i];\n                                Initializer _init = v._init;\n                                if (_init)\n                                {\n                                    if (_init.isVoidInitializer())\n                                    {\n                                    }\n                                    else if (ExpInitializer ei = _init.isExpInitializer())\n                                    {\n                                        Type tb = v.type.toBasetype();\n                                        if (implicitMod(ei.exp, tb, mod) == MATCH.nomatch)\n                                            return false;\n                                    }\n                                    else\n                                    {\n                                        /* Enhancement: handle StructInitializer and ArrayInitializer\n                                         */\n                                        return false;\n                                    }\n                                }\n                                else if (!v.type.isZeroInit(loc))\n                                    return false;\n                            }\n                            return cd.baseClass ? convertible(loc, cd.baseClass, mod) : true;\n                        }\n                    }\n\n                    if (!ClassCheck.convertible(e.loc, cd, mod))\n                        return;\n                }\n            }\n            else\n            {\n                Expression earg = e.newtype.defaultInitLiteral(e.loc);\n                Type targ = e.newtype.toBasetype();\n\n                if (implicitMod(earg, targ, mod) == MATCH.nomatch)\n                    return;\n            }\n\n            /* Success\n             */\n            result = MATCH.constant;\n        }\n\n        override void visit(SliceExp e)\n        {\n            //printf(\"SliceExp::implicitConvTo e = %s, type = %s\\n\", e.toChars(), e.type.toChars());\n            visit(cast(Expression)e);\n            if (result != MATCH.nomatch)\n                return;\n\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            if (tb.ty == Tsarray && typeb.ty == Tarray)\n            {\n                typeb = toStaticArrayType(e);\n                if (typeb)\n                    result = typeb.implicitConvTo(t);\n                return;\n            }\n\n            /* If the only reason it won't convert is because of the mod bits,\n             * then test for conversion by seeing if e1 can be converted with those\n             * same mod bits.\n             */\n            Type t1b = e.e1.type.toBasetype();\n            if (tb.ty == Tarray && typeb.equivalent(tb))\n            {\n                Type tbn = tb.nextOf();\n                Type tx = null;\n\n                /* If e.e1 is dynamic array or pointer, the uniqueness of e.e1\n                 * is equivalent with the uniqueness of the referred data. And in here\n                 * we can have arbitrary typed reference for that.\n                 */\n                if (t1b.ty == Tarray)\n                    tx = tbn.arrayOf();\n                if (t1b.ty == Tpointer)\n                    tx = tbn.pointerTo();\n\n                /* If e.e1 is static array, at least it should be an rvalue.\n                 * If not, e.e1 is a reference, and its uniqueness does not link\n                 * to the uniqueness of the referred data.\n                 */\n                if (t1b.ty == Tsarray && !e.e1.isLvalue())\n                    tx = tbn.sarrayOf(t1b.size() / tbn.size());\n\n                if (tx)\n                {\n                    result = e.e1.implicitConvTo(tx);\n                    if (result > MATCH.constant) // Match level is MATCH.constant at best.\n                        result = MATCH.constant;\n                }\n            }\n\n            // Enhancement 10724\n            if (tb.ty == Tpointer && e.e1.op == TOK.string_)\n                e.e1.accept(this);\n        }\n    }\n\n    scope ImplicitConvTo v = new ImplicitConvTo(t);\n    e.accept(v);\n    return v.result;\n}\n\nType toStaticArrayType(SliceExp e)\n{\n    if (e.lwr && e.upr)\n    {\n        // For the following code to work, e should be optimized beforehand.\n        // (eg. $ in lwr and upr should be already resolved, if possible)\n        Expression lwr = e.lwr.optimize(WANTvalue);\n        Expression upr = e.upr.optimize(WANTvalue);\n        if (lwr.isConst() && upr.isConst())\n        {\n            size_t len = cast(size_t)(upr.toUInteger() - lwr.toUInteger());\n            return e.type.toBasetype().nextOf().sarrayOf(len);\n        }\n    }\n    else\n    {\n        Type t1b = e.e1.type.toBasetype();\n        if (t1b.ty == Tsarray)\n            return t1b;\n    }\n    return null;\n}\n\n/**************************************\n * Do an explicit cast.\n * Assume that the 'this' expression does not have any indirections.\n */\nExpression castTo(Expression e, Scope* sc, Type t)\n{\n    extern (C++) final class CastTo : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        Type t;\n        Scope* sc;\n        Expression result;\n\n        extern (D) this(Scope* sc, Type t)\n        {\n            this.sc = sc;\n            this.t = t;\n        }\n\n        override void visit(Expression e)\n        {\n            //printf(\"Expression::castTo(this=%s, t=%s)\\n\", e.toChars(), t.toChars());\n            version (none)\n            {\n                printf(\"Expression::castTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            if (e.type.equals(t))\n            {\n                result = e;\n                return;\n            }\n            if (e.op == TOK.variable)\n            {\n                VarDeclaration v = (cast(VarExp)e).var.isVarDeclaration();\n                if (v && v.storage_class & STC.manifest)\n                {\n                    result = e.ctfeInterpret();\n                    /* https://issues.dlang.org/show_bug.cgi?id=18236\n                     *\n                     * The expression returned by ctfeInterpret points\n                     * to the line where the manifest constant was declared\n                     * so we need to update the location before trying to cast\n                     */\n                    result.loc = e.loc;\n                    result = result.castTo(sc, t);\n                    return;\n                }\n            }\n\n            Type tob = t.toBasetype();\n            Type t1b = e.type.toBasetype();\n            if (tob.equals(t1b))\n            {\n                result = e.copy(); // because of COW for assignment to e.type\n                result.type = t;\n                return;\n            }\n\n            /* Make semantic error against invalid cast between concrete types.\n             * Assume that 'e' is never be any placeholder expressions.\n             * The result of these checks should be consistent with CastExp::toElem().\n             */\n\n            // Fat Value types\n            const(bool) tob_isFV = (tob.ty == Tstruct || tob.ty == Tsarray || tob.ty == Tvector);\n            const(bool) t1b_isFV = (t1b.ty == Tstruct || t1b.ty == Tsarray || t1b.ty == Tvector);\n\n            // Fat Reference types\n            const(bool) tob_isFR = (tob.ty == Tarray || tob.ty == Tdelegate);\n            const(bool) t1b_isFR = (t1b.ty == Tarray || t1b.ty == Tdelegate);\n\n            // Reference types\n            const(bool) tob_isR = (tob_isFR || tob.ty == Tpointer || tob.ty == Taarray || tob.ty == Tclass);\n            const(bool) t1b_isR = (t1b_isFR || t1b.ty == Tpointer || t1b.ty == Taarray || t1b.ty == Tclass);\n\n            // Arithmetic types (== valueable basic types)\n            const(bool) tob_isA = ((tob.isintegral() || tob.isfloating()) && tob.ty != Tvector);\n            const(bool) t1b_isA = ((t1b.isintegral() || t1b.isfloating()) && t1b.ty != Tvector);\n\n            if (AggregateDeclaration t1ad = isAggregate(t1b))\n            {\n                AggregateDeclaration toad = isAggregate(tob);\n                if (t1ad != toad && t1ad.aliasthis)\n                {\n                    if (t1b.ty == Tclass && tob.ty == Tclass)\n                    {\n                        ClassDeclaration t1cd = t1b.isClassHandle();\n                        ClassDeclaration tocd = tob.isClassHandle();\n                        int offset;\n                        if (tocd.isBaseOf(t1cd, &offset))\n                            goto Lok;\n                    }\n\n                    /* Forward the cast to our alias this member, rewrite to:\n                     *   cast(to)e1.aliasthis\n                     */\n                    result = resolveAliasThis(sc, e);\n                    result = result.castTo(sc, t);\n                    return;\n                }\n            }\n            else if (tob.ty == Tvector && t1b.ty != Tvector)\n            {\n                //printf(\"test1 e = %s, e.type = %s, tob = %s\\n\", e.toChars(), e.type.toChars(), tob.toChars());\n                TypeVector tv = cast(TypeVector)tob;\n                result = new CastExp(e.loc, e, tv.elementType());\n                result = new VectorExp(e.loc, result, tob);\n                result = result.expressionSemantic(sc);\n                return;\n            }\n            else if (tob.ty != Tvector && t1b.ty == Tvector)\n            {\n                // T[n] <-- __vector(U[m])\n                if (tob.ty == Tsarray)\n                {\n                    if (t1b.size(e.loc) == tob.size(e.loc))\n                        goto Lok;\n                }\n                goto Lfail;\n            }\n            else if (t1b.implicitConvTo(tob) == MATCH.constant && t.equals(e.type.constOf()))\n            {\n                result = e.copy();\n                result.type = t;\n                return;\n            }\n\n            // arithmetic values vs. other arithmetic values\n            // arithmetic values vs. T*\n            if (tob_isA && (t1b_isA || t1b.ty == Tpointer) || t1b_isA && (tob_isA || tob.ty == Tpointer))\n            {\n                goto Lok;\n            }\n\n            // arithmetic values vs. references or fat values\n            if (tob_isA && (t1b_isR || t1b_isFV) || t1b_isA && (tob_isR || tob_isFV))\n            {\n                goto Lfail;\n            }\n\n            // Bugzlla 3133: A cast between fat values is possible only when the sizes match.\n            if (tob_isFV && t1b_isFV)\n            {\n                if (t1b.size(e.loc) == tob.size(e.loc))\n                    goto Lok;\n                auto ts = toAutoQualChars(e.type, t);\n                e.error(\"cannot cast expression `%s` of type `%s` to `%s` because of different sizes\",\n                    e.toChars(), ts[0], ts[1]);\n                result = new ErrorExp();\n                return;\n            }\n\n            // Fat values vs. null or references\n            if (tob_isFV && (t1b.ty == Tnull || t1b_isR) || t1b_isFV && (tob.ty == Tnull || tob_isR))\n            {\n                if (tob.ty == Tpointer && t1b.ty == Tsarray)\n                {\n                    // T[n] sa;\n                    // cast(U*)sa; // ==> cast(U*)sa.ptr;\n                    result = new AddrExp(e.loc, e, t);\n                    return;\n                }\n                if (tob.ty == Tarray && t1b.ty == Tsarray)\n                {\n                    // T[n] sa;\n                    // cast(U[])sa; // ==> cast(U[])sa[];\n                    d_uns64 fsize = t1b.nextOf().size();\n                    d_uns64 tsize = tob.nextOf().size();\n                    if (((cast(TypeSArray)t1b).dim.toInteger() * fsize) % tsize != 0)\n                    {\n                        // copied from sarray_toDarray() in e2ir.c\n                        e.error(\"cannot cast expression `%s` of type `%s` to `%s` since sizes don't line up\", e.toChars(), e.type.toChars(), t.toChars());\n                        result = new ErrorExp();\n                        return;\n                    }\n                    goto Lok;\n                }\n                goto Lfail;\n            }\n\n            /* For references, any reinterpret casts are allowed to same 'ty' type.\n             *      T* to U*\n             *      R1 function(P1) to R2 function(P2)\n             *      R1 delegate(P1) to R2 delegate(P2)\n             *      T[] to U[]\n             *      V1[K1] to V2[K2]\n             *      class/interface A to B  (will be a dynamic cast if possible)\n             */\n            if (tob.ty == t1b.ty && tob_isR && t1b_isR)\n                goto Lok;\n\n            // typeof(null) <-- non-null references or values\n            if (tob.ty == Tnull && t1b.ty != Tnull)\n                goto Lfail; // https://issues.dlang.org/show_bug.cgi?id=14629\n            // typeof(null) --> non-null references or arithmetic values\n            if (t1b.ty == Tnull && tob.ty != Tnull)\n                goto Lok;\n\n            // Check size mismatch of references.\n            // Tarray and Tdelegate are (void*).sizeof*2, but others have (void*).sizeof.\n            if (tob_isFR && t1b_isR || t1b_isFR && tob_isR)\n            {\n                if (tob.ty == Tpointer && t1b.ty == Tarray)\n                {\n                    // T[] da;\n                    // cast(U*)da; // ==> cast(U*)da.ptr;\n                    goto Lok;\n                }\n                if (tob.ty == Tpointer && t1b.ty == Tdelegate)\n                {\n                    // void delegate() dg;\n                    // cast(U*)dg; // ==> cast(U*)dg.ptr;\n                    // Note that it happens even when U is a Tfunction!\n                    e.deprecation(\"casting from %s to %s is deprecated\", e.type.toChars(), t.toChars());\n                    goto Lok;\n                }\n                goto Lfail;\n            }\n\n            if (t1b.ty == Tvoid && tob.ty != Tvoid)\n            {\n            Lfail:\n                e.error(\"cannot cast expression `%s` of type `%s` to `%s`\", e.toChars(), e.type.toChars(), t.toChars());\n                result = new ErrorExp();\n                return;\n            }\n\n        Lok:\n            result = new CastExp(e.loc, e, t);\n            result.type = t; // Don't call semantic()\n            //printf(\"Returning: %s\\n\", result.toChars());\n        }\n\n        override void visit(ErrorExp e)\n        {\n            result = e;\n        }\n\n        override void visit(RealExp e)\n        {\n            if (!e.type.equals(t))\n            {\n                if ((e.type.isreal() && t.isreal()) || (e.type.isimaginary() && t.isimaginary()))\n                {\n                    result = e.copy();\n                    result.type = t;\n                }\n                else\n                    visit(cast(Expression)e);\n                return;\n            }\n            result = e;\n        }\n\n        override void visit(ComplexExp e)\n        {\n            if (!e.type.equals(t))\n            {\n                if (e.type.iscomplex() && t.iscomplex())\n                {\n                    result = e.copy();\n                    result.type = t;\n                }\n                else\n                    visit(cast(Expression)e);\n                return;\n            }\n            result = e;\n        }\n\n        override void visit(NullExp e)\n        {\n            //printf(\"NullExp::castTo(t = %s) %s\\n\", t.toChars(), toChars());\n            visit(cast(Expression)e);\n            if (result.op == TOK.null_)\n            {\n                NullExp ex = cast(NullExp)result;\n                ex.committed = 1;\n                return;\n            }\n        }\n\n        override void visit(StructLiteralExp e)\n        {\n            visit(cast(Expression)e);\n            if (result.op == TOK.structLiteral)\n                (cast(StructLiteralExp)result).stype = t; // commit type\n        }\n\n        override void visit(StringExp e)\n        {\n            /* This follows copy-on-write; any changes to 'this'\n             * will result in a copy.\n             * The this.string member is considered immutable.\n             */\n            int copied = 0;\n\n            //printf(\"StringExp::castTo(t = %s), '%s' committed = %d\\n\", t.toChars(), e.toChars(), e.committed);\n\n            if (!e.committed && t.ty == Tpointer && t.nextOf().ty == Tvoid)\n            {\n                e.error(\"cannot convert string literal to `void*`\");\n                result = new ErrorExp();\n                return;\n            }\n\n            StringExp se = e;\n            if (!e.committed)\n            {\n                se = cast(StringExp)e.copy();\n                se.committed = 1;\n                copied = 1;\n            }\n\n            if (e.type.equals(t))\n            {\n                result = se;\n                return;\n            }\n\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            //printf(\"\\ttype = %s\\n\", e.type.toChars());\n            if (tb.ty == Tdelegate && typeb.ty != Tdelegate)\n            {\n                visit(cast(Expression)e);\n                return;\n            }\n\n            if (typeb.equals(tb))\n            {\n                if (!copied)\n                {\n                    se = cast(StringExp)e.copy();\n                    copied = 1;\n                }\n                se.type = t;\n                result = se;\n                return;\n            }\n\n            /* Handle reinterpret casts:\n             *  cast(wchar[3])\"abcd\"c --> [\\u6261, \\u6463, \\u0000]\n             *  cast(wchar[2])\"abcd\"c --> [\\u6261, \\u6463]\n             *  cast(wchar[1])\"abcd\"c --> [\\u6261]\n             */\n            if (e.committed && tb.ty == Tsarray && typeb.ty == Tarray)\n            {\n                se = cast(StringExp)e.copy();\n                d_uns64 szx = tb.nextOf().size();\n                assert(szx <= 255);\n                se.sz = cast(ubyte)szx;\n                se.len = cast(size_t)(cast(TypeSArray)tb).dim.toInteger();\n                se.committed = 1;\n                se.type = t;\n\n                /* Assure space for terminating 0\n                 */\n                if ((se.len + 1) * se.sz > (e.len + 1) * e.sz)\n                {\n                    void* s = mem.xmalloc((se.len + 1) * se.sz);\n                    memcpy(s, se.string, se.len * se.sz);\n                    memset(s + se.len * se.sz, 0, se.sz);\n                    se.string = cast(char*)s;\n                }\n                result = se;\n                return;\n            }\n\n            if (tb.ty != Tsarray && tb.ty != Tarray && tb.ty != Tpointer)\n            {\n                if (!copied)\n                {\n                    se = cast(StringExp)e.copy();\n                    copied = 1;\n                }\n                goto Lcast;\n            }\n            if (typeb.ty != Tsarray && typeb.ty != Tarray && typeb.ty != Tpointer)\n            {\n                if (!copied)\n                {\n                    se = cast(StringExp)e.copy();\n                    copied = 1;\n                }\n                goto Lcast;\n            }\n\n            if (typeb.nextOf().size() == tb.nextOf().size())\n            {\n                if (!copied)\n                {\n                    se = cast(StringExp)e.copy();\n                    copied = 1;\n                }\n                if (tb.ty == Tsarray)\n                    goto L2; // handle possible change in static array dimension\n                se.type = t;\n                result = se;\n                return;\n            }\n\n            if (e.committed)\n                goto Lcast;\n\n            auto X(T, U)(T tf, U tt)\n            {\n                return (cast(int)tf * 256 + cast(int)tt);\n            }\n\n            {\n                OutBuffer buffer;\n                size_t newlen = 0;\n                int tfty = typeb.nextOf().toBasetype().ty;\n                int ttty = tb.nextOf().toBasetype().ty;\n                switch (X(tfty, ttty))\n                {\n                case X(Tchar, Tchar):\n                case X(Twchar, Twchar):\n                case X(Tdchar, Tdchar):\n                    break;\n\n                case X(Tchar, Twchar):\n                    for (size_t u = 0; u < e.len;)\n                    {\n                        dchar c;\n                        const p = utf_decodeChar(se.string, e.len, u, c);\n                        if (p)\n                            e.error(\"%s\", p);\n                        else\n                            buffer.writeUTF16(c);\n                    }\n                    newlen = buffer.offset / 2;\n                    buffer.writeUTF16(0);\n                    goto L1;\n\n                case X(Tchar, Tdchar):\n                    for (size_t u = 0; u < e.len;)\n                    {\n                        dchar c;\n                        const p = utf_decodeChar(se.string, e.len, u, c);\n                        if (p)\n                            e.error(\"%s\", p);\n                        buffer.write4(c);\n                        newlen++;\n                    }\n                    buffer.write4(0);\n                    goto L1;\n\n                case X(Twchar, Tchar):\n                    for (size_t u = 0; u < e.len;)\n                    {\n                        dchar c;\n                        const p = utf_decodeWchar(se.wstring, e.len, u, c);\n                        if (p)\n                            e.error(\"%s\", p);\n                        else\n                            buffer.writeUTF8(c);\n                    }\n                    newlen = buffer.offset;\n                    buffer.writeUTF8(0);\n                    goto L1;\n\n                case X(Twchar, Tdchar):\n                    for (size_t u = 0; u < e.len;)\n                    {\n                        dchar c;\n                        const p = utf_decodeWchar(se.wstring, e.len, u, c);\n                        if (p)\n                            e.error(\"%s\", p);\n                        buffer.write4(c);\n                        newlen++;\n                    }\n                    buffer.write4(0);\n                    goto L1;\n\n                case X(Tdchar, Tchar):\n                    for (size_t u = 0; u < e.len; u++)\n                    {\n                        uint c = se.dstring[u];\n                        if (!utf_isValidDchar(c))\n                            e.error(\"invalid UCS-32 char \\\\U%08x\", c);\n                        else\n                            buffer.writeUTF8(c);\n                        newlen++;\n                    }\n                    newlen = buffer.offset;\n                    buffer.writeUTF8(0);\n                    goto L1;\n\n                case X(Tdchar, Twchar):\n                    for (size_t u = 0; u < e.len; u++)\n                    {\n                        uint c = se.dstring[u];\n                        if (!utf_isValidDchar(c))\n                            e.error(\"invalid UCS-32 char \\\\U%08x\", c);\n                        else\n                            buffer.writeUTF16(c);\n                        newlen++;\n                    }\n                    newlen = buffer.offset / 2;\n                    buffer.writeUTF16(0);\n                    goto L1;\n\n                L1:\n                    if (!copied)\n                    {\n                        se = cast(StringExp)e.copy();\n                        copied = 1;\n                    }\n                    se.string = buffer.extractData();\n                    se.len = newlen;\n\n                    {\n                        d_uns64 szx = tb.nextOf().size();\n                        assert(szx <= 255);\n                        se.sz = cast(ubyte)szx;\n                    }\n                    break;\n\n                default:\n                    assert(typeb.nextOf().size() != tb.nextOf().size());\n                    goto Lcast;\n                }\n            }\n        L2:\n            assert(copied);\n\n            // See if need to truncate or extend the literal\n            if (tb.ty == Tsarray)\n            {\n                size_t dim2 = cast(size_t)(cast(TypeSArray)tb).dim.toInteger();\n                //printf(\"dim from = %d, to = %d\\n\", (int)se.len, (int)dim2);\n\n                // Changing dimensions\n                if (dim2 != se.len)\n                {\n                    // Copy when changing the string literal\n                    size_t newsz = se.sz;\n                    size_t d = (dim2 < se.len) ? dim2 : se.len;\n                    void* s = mem.xmalloc((dim2 + 1) * newsz);\n                    memcpy(s, se.string, d * newsz);\n                    // Extend with 0, add terminating 0\n                    memset(s + d * newsz, 0, (dim2 + 1 - d) * newsz);\n                    se.string = cast(char*)s;\n                    se.len = dim2;\n                }\n            }\n            se.type = t;\n            result = se;\n            return;\n\n        Lcast:\n            result = new CastExp(e.loc, se, t);\n            result.type = t; // so semantic() won't be run on e\n        }\n\n        override void visit(AddrExp e)\n        {\n            version (none)\n            {\n                printf(\"AddrExp::castTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            result = e;\n\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            if (tb.equals(typeb))\n            {\n                result = e.copy();\n                result.type = t;\n                return;\n            }\n\n            // Look for pointers to functions where the functions are overloaded.\n            if (e.e1.op == TOK.overloadSet &&\n                (tb.ty == Tpointer || tb.ty == Tdelegate) && tb.nextOf().ty == Tfunction)\n            {\n                OverExp eo = cast(OverExp)e.e1;\n                FuncDeclaration f = null;\n                for (size_t i = 0; i < eo.vars.a.dim; i++)\n                {\n                    auto s = eo.vars.a[i];\n                    auto f2 = s.isFuncDeclaration();\n                    assert(f2);\n                    if (f2.overloadExactMatch(tb.nextOf()))\n                    {\n                        if (f)\n                        {\n                            /* Error if match in more than one overload set,\n                             * even if one is a 'better' match than the other.\n                             */\n                            ScopeDsymbol.multiplyDefined(e.loc, f, f2);\n                        }\n                        else\n                            f = f2;\n                    }\n                }\n                if (f)\n                {\n                    f.tookAddressOf++;\n                    auto se = new SymOffExp(e.loc, f, 0, false);\n                    se.expressionSemantic(sc);\n                    // Let SymOffExp::castTo() do the heavy lifting\n                    visit(se);\n                    return;\n                }\n            }\n\n            if (e.e1.op == TOK.variable &&\n                typeb.ty == Tpointer && typeb.nextOf().ty == Tfunction &&\n                tb.ty == Tpointer && tb.nextOf().ty == Tfunction)\n            {\n                auto ve = cast(VarExp)e.e1;\n                auto f = ve.var.isFuncDeclaration();\n                if (f)\n                {\n                    assert(f.isImportedSymbol());\n                    f = f.overloadExactMatch(tb.nextOf());\n                    if (f)\n                    {\n                        result = new VarExp(e.loc, f, false);\n                        result.type = f.type;\n                        result = new AddrExp(e.loc, result, t);\n                        return;\n                    }\n                }\n            }\n\n            if (auto f = isFuncAddress(e))\n            {\n                if (f.checkForwardRef(e.loc))\n                {\n                    result = new ErrorExp();\n                    return;\n                }\n            }\n\n            visit(cast(Expression)e);\n        }\n\n        override void visit(TupleExp e)\n        {\n            if (e.type.equals(t))\n            {\n                result = e;\n                return;\n            }\n\n            TupleExp te = cast(TupleExp)e.copy();\n            te.e0 = e.e0 ? e.e0.copy() : null;\n            te.exps = e.exps.copy();\n            for (size_t i = 0; i < te.exps.dim; i++)\n            {\n                Expression ex = (*te.exps)[i];\n                ex = ex.castTo(sc, t);\n                (*te.exps)[i] = ex;\n            }\n            result = te;\n\n            /* Questionable behavior: In here, result.type is not set to t.\n             * Therefoe:\n             *  TypeTuple!(int, int) values;\n             *  auto values2 = cast(long)values;\n             *  // typeof(values2) == TypeTuple!(int, int) !!\n             *\n             * Only when the casted tuple is immediately expanded, it would work.\n             *  auto arr = [cast(long)values];\n             *  // typeof(arr) == long[]\n             */\n        }\n\n        override void visit(ArrayLiteralExp e)\n        {\n            version (none)\n            {\n                printf(\"ArrayLiteralExp::castTo(this=%s, type=%s, => %s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n\n            ArrayLiteralExp ae = e;\n\n            Type tb = t.toBasetype();\n            if (tb.ty == Tarray && global.params.vsafe)\n            {\n                if (checkArrayLiteralEscape(sc, ae, false))\n                {\n                    result = new ErrorExp();\n                    return;\n                }\n            }\n\n            if (e.type == t)\n            {\n                result = e;\n                return;\n            }\n            Type typeb = e.type.toBasetype();\n\n            if ((tb.ty == Tarray || tb.ty == Tsarray) &&\n                (typeb.ty == Tarray || typeb.ty == Tsarray))\n            {\n                if (tb.nextOf().toBasetype().ty == Tvoid && typeb.nextOf().toBasetype().ty != Tvoid)\n                {\n                    // Don't do anything to cast non-void[] to void[]\n                }\n                else if (typeb.ty == Tsarray && typeb.nextOf().toBasetype().ty == Tvoid)\n                {\n                    // Don't do anything for casting void[n] to others\n                }\n                else\n                {\n                    if (tb.ty == Tsarray)\n                    {\n                        TypeSArray tsa = cast(TypeSArray)tb;\n                        if (e.elements.dim != tsa.dim.toInteger())\n                            goto L1;\n                    }\n\n                    ae = cast(ArrayLiteralExp)e.copy();\n                    if (e.basis)\n                        ae.basis = e.basis.castTo(sc, tb.nextOf());\n                    ae.elements = e.elements.copy();\n                    for (size_t i = 0; i < e.elements.dim; i++)\n                    {\n                        Expression ex = (*e.elements)[i];\n                        if (!ex)\n                            continue;\n                        ex = ex.castTo(sc, tb.nextOf());\n                        (*ae.elements)[i] = ex;\n                    }\n                    ae.type = t;\n                    result = ae;\n                    return;\n                }\n            }\n            else if (tb.ty == Tpointer && typeb.ty == Tsarray)\n            {\n                Type tp = typeb.nextOf().pointerTo();\n                if (!tp.equals(ae.type))\n                {\n                    ae = cast(ArrayLiteralExp)e.copy();\n                    ae.type = tp;\n                }\n            }\n            else if (tb.ty == Tvector && (typeb.ty == Tarray || typeb.ty == Tsarray))\n            {\n                // Convert array literal to vector type\n                TypeVector tv = cast(TypeVector)tb;\n                TypeSArray tbase = cast(TypeSArray)tv.basetype;\n                assert(tbase.ty == Tsarray);\n                const edim = e.elements.dim;\n                const tbasedim = tbase.dim.toInteger();\n                if (edim > tbasedim)\n                    goto L1;\n\n                ae = cast(ArrayLiteralExp)e.copy();\n                ae.type = tbase; // https://issues.dlang.org/show_bug.cgi?id=12642\n                ae.elements = e.elements.copy();\n                Type telement = tv.elementType();\n                foreach (i; 0 .. edim)\n                {\n                    Expression ex = (*e.elements)[i];\n                    ex = ex.castTo(sc, telement);\n                    (*ae.elements)[i] = ex;\n                }\n                // Fill in the rest with the default initializer\n                ae.elements.setDim(cast(size_t)tbasedim);\n                foreach (i; edim .. cast(size_t)tbasedim)\n                {\n                    Expression ex = typeb.nextOf.defaultInitLiteral(e.loc);\n                    ex = ex.castTo(sc, telement);\n                    (*ae.elements)[i] = ex;\n                }\n                Expression ev = new VectorExp(e.loc, ae, tb);\n                ev = ev.expressionSemantic(sc);\n                result = ev;\n                return;\n            }\n        L1:\n            visit(cast(Expression)ae);\n        }\n\n        override void visit(AssocArrayLiteralExp e)\n        {\n            //printf(\"AssocArrayLiteralExp::castTo(this=%s, type=%s, => %s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            if (e.type == t)\n            {\n                result = e;\n                return;\n            }\n\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            if (tb.ty == Taarray && typeb.ty == Taarray &&\n                tb.nextOf().toBasetype().ty != Tvoid)\n            {\n                AssocArrayLiteralExp ae = cast(AssocArrayLiteralExp)e.copy();\n                ae.keys = e.keys.copy();\n                ae.values = e.values.copy();\n                assert(e.keys.dim == e.values.dim);\n                for (size_t i = 0; i < e.keys.dim; i++)\n                {\n                    Expression ex = (*e.values)[i];\n                    ex = ex.castTo(sc, tb.nextOf());\n                    (*ae.values)[i] = ex;\n\n                    ex = (*e.keys)[i];\n                    ex = ex.castTo(sc, (cast(TypeAArray)tb).index);\n                    (*ae.keys)[i] = ex;\n                }\n                ae.type = t;\n                result = ae;\n                return;\n            }\n            visit(cast(Expression)e);\n        }\n\n        override void visit(SymOffExp e)\n        {\n            version (none)\n            {\n                printf(\"SymOffExp::castTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            if (e.type == t && !e.hasOverloads)\n            {\n                result = e;\n                return;\n            }\n\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            if (tb.equals(typeb))\n            {\n                result = e.copy();\n                result.type = t;\n                (cast(SymOffExp)result).hasOverloads = false;\n                return;\n            }\n\n            // Look for pointers to functions where the functions are overloaded.\n            if (e.hasOverloads &&\n                typeb.ty == Tpointer && typeb.nextOf().ty == Tfunction &&\n                (tb.ty == Tpointer || tb.ty == Tdelegate) && tb.nextOf().ty == Tfunction)\n            {\n                FuncDeclaration f = e.var.isFuncDeclaration();\n                f = f ? f.overloadExactMatch(tb.nextOf()) : null;\n                if (f)\n                {\n                    if (tb.ty == Tdelegate)\n                    {\n                        if (f.needThis() && hasThis(sc))\n                        {\n                            result = new DelegateExp(e.loc, new ThisExp(e.loc), f, false);\n                            result = result.expressionSemantic(sc);\n                        }\n                        else if (f.isNested())\n                        {\n                            result = new DelegateExp(e.loc, new IntegerExp(0), f, false);\n                            result = result.expressionSemantic(sc);\n                        }\n                        else if (f.needThis())\n                        {\n                            e.error(\"no `this` to create delegate for `%s`\", f.toChars());\n                            result = new ErrorExp();\n                            return;\n                        }\n                        else\n                        {\n                            e.error(\"cannot cast from function pointer to delegate\");\n                            result = new ErrorExp();\n                            return;\n                        }\n                    }\n                    else\n                    {\n                        result = new SymOffExp(e.loc, f, 0, false);\n                        result.type = t;\n                    }\n                    f.tookAddressOf++;\n                    return;\n                }\n            }\n\n            if (auto f = isFuncAddress(e))\n            {\n                if (f.checkForwardRef(e.loc))\n                {\n                    result = new ErrorExp();\n                    return;\n                }\n            }\n\n            visit(cast(Expression)e);\n        }\n\n        override void visit(DelegateExp e)\n        {\n            version (none)\n            {\n                printf(\"DelegateExp::castTo(this=%s, type=%s, t=%s)\\n\", e.toChars(), e.type.toChars(), t.toChars());\n            }\n            __gshared const(char)* msg = \"cannot form delegate due to covariant return type\";\n\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            if (tb.equals(typeb) && !e.hasOverloads)\n            {\n                int offset;\n                e.func.tookAddressOf++;\n                if (e.func.tintro && e.func.tintro.nextOf().isBaseOf(e.func.type.nextOf(), &offset) && offset)\n                    e.error(\"%s\", msg);\n                result = e.copy();\n                result.type = t;\n                return;\n            }\n\n            // Look for delegates to functions where the functions are overloaded.\n            if (typeb.ty == Tdelegate && tb.ty == Tdelegate)\n            {\n                if (e.func)\n                {\n                    auto f = e.func.overloadExactMatch(tb.nextOf());\n                    if (f)\n                    {\n                        int offset;\n                        if (f.tintro && f.tintro.nextOf().isBaseOf(f.type.nextOf(), &offset) && offset)\n                            e.error(\"%s\", msg);\n                        if (f != e.func)    // if address not already marked as taken\n                            f.tookAddressOf++;\n                        result = new DelegateExp(e.loc, e.e1, f, false);\n                        result.type = t;\n                        return;\n                    }\n                    if (e.func.tintro)\n                        e.error(\"%s\", msg);\n                }\n            }\n\n            if (auto f = isFuncAddress(e))\n            {\n                if (f.checkForwardRef(e.loc))\n                {\n                    result = new ErrorExp();\n                    return;\n                }\n            }\n\n            visit(cast(Expression)e);\n        }\n\n        override void visit(FuncExp e)\n        {\n            //printf(\"FuncExp::castTo type = %s, t = %s\\n\", e.type.toChars(), t.toChars());\n            FuncExp fe;\n            if (e.matchType(t, sc, &fe, 1) > MATCH.nomatch)\n            {\n                result = fe;\n                return;\n            }\n            visit(cast(Expression)e);\n        }\n\n        override void visit(CondExp e)\n        {\n            if (!e.type.equals(t))\n            {\n                result = new CondExp(e.loc, e.econd, e.e1.castTo(sc, t), e.e2.castTo(sc, t));\n                result.type = t;\n                return;\n            }\n            result = e;\n        }\n\n        override void visit(CommaExp e)\n        {\n            Expression e2c = e.e2.castTo(sc, t);\n\n            if (e2c != e.e2)\n            {\n                result = new CommaExp(e.loc, e.e1, e2c);\n                result.type = e2c.type;\n            }\n            else\n            {\n                result = e;\n                result.type = e.e2.type;\n            }\n        }\n\n        override void visit(SliceExp e)\n        {\n            //printf(\"SliceExp::castTo e = %s, type = %s, t = %s\\n\", e.toChars(), e.type.toChars(), t.toChars());\n\n            Type tb = t.toBasetype();\n            Type typeb = e.type.toBasetype();\n\n            if (e.type.equals(t) || typeb.ty != Tarray ||\n                (tb.ty != Tarray && tb.ty != Tsarray))\n            {\n                visit(cast(Expression)e);\n                return;\n            }\n\n            if (tb.ty == Tarray)\n            {\n                if (typeb.nextOf().equivalent(tb.nextOf()))\n                {\n                    // T[] to const(T)[]\n                    result = e.copy();\n                    result.type = t;\n                }\n                else\n                {\n                    visit(cast(Expression)e);\n                }\n                return;\n            }\n\n            // Handle the cast from Tarray to Tsarray with CT-known slicing\n\n            TypeSArray tsa = cast(TypeSArray)toStaticArrayType(e);\n            if (tsa && tsa.size(e.loc) == tb.size(e.loc))\n            {\n                /* Match if the sarray sizes are equal:\n                 *  T[a .. b] to const(T)[b-a]\n                 *  T[a .. b] to U[dim] if (T.sizeof*(b-a) == U.sizeof*dim)\n                 *\n                 * If a SliceExp has Tsarray, it will become lvalue.\n                 * That's handled in SliceExp::isLvalue and toLvalue\n                 */\n                result = e.copy();\n                result.type = t;\n                return;\n            }\n            if (tsa && tsa.dim.equals((cast(TypeSArray)tb).dim))\n            {\n                /* Match if the dimensions are equal\n                 * with the implicit conversion of e.e1:\n                 *  cast(float[2]) [2.0, 1.0, 0.0][0..2];\n                 */\n                Type t1b = e.e1.type.toBasetype();\n                if (t1b.ty == Tsarray)\n                    t1b = tb.nextOf().sarrayOf((cast(TypeSArray)t1b).dim.toInteger());\n                else if (t1b.ty == Tarray)\n                    t1b = tb.nextOf().arrayOf();\n                else if (t1b.ty == Tpointer)\n                    t1b = tb.nextOf().pointerTo();\n                else\n                    assert(0);\n                if (e.e1.implicitConvTo(t1b) > MATCH.nomatch)\n                {\n                    Expression e1x = e.e1.implicitCastTo(sc, t1b);\n                    assert(e1x.op != TOK.error);\n                    e = cast(SliceExp)e.copy();\n                    e.e1 = e1x;\n                    e.type = t;\n                    result = e;\n                    return;\n                }\n            }\n            auto ts = toAutoQualChars(tsa ? tsa : e.type, t);\n            e.error(\"cannot cast expression `%s` of type `%s` to `%s`\",\n                e.toChars(), ts[0], ts[1]);\n            result = new ErrorExp();\n        }\n    }\n\n    scope CastTo v = new CastTo(sc, t);\n    e.accept(v);\n    return v.result;\n}\n\n/****************************************\n * Set type inference target\n *      t       Target type\n *      flag    1: don't put an error when inference fails\n */\nExpression inferType(Expression e, Type t, int flag = 0)\n{\n    extern (C++) final class InferType : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        Type t;\n        int flag;\n        Expression result;\n\n        extern (D) this(Type t, int flag)\n        {\n            this.t = t;\n            this.flag = flag;\n        }\n\n        override void visit(Expression e)\n        {\n            result = e;\n        }\n\n        override void visit(ArrayLiteralExp ale)\n        {\n            Type tb = t.toBasetype();\n            if (tb.ty == Tarray || tb.ty == Tsarray)\n            {\n                Type tn = tb.nextOf();\n                if (ale.basis)\n                    ale.basis = inferType(ale.basis, tn, flag);\n                for (size_t i = 0; i < ale.elements.dim; i++)\n                {\n                    Expression e = (*ale.elements)[i];\n                    if (e)\n                    {\n                        e = inferType(e, tn, flag);\n                        (*ale.elements)[i] = e;\n                    }\n                }\n            }\n            result = ale;\n        }\n\n        override void visit(AssocArrayLiteralExp aale)\n        {\n            Type tb = t.toBasetype();\n            if (tb.ty == Taarray)\n            {\n                TypeAArray taa = cast(TypeAArray)tb;\n                Type ti = taa.index;\n                Type tv = taa.nextOf();\n                for (size_t i = 0; i < aale.keys.dim; i++)\n                {\n                    Expression e = (*aale.keys)[i];\n                    if (e)\n                    {\n                        e = inferType(e, ti, flag);\n                        (*aale.keys)[i] = e;\n                    }\n                }\n                for (size_t i = 0; i < aale.values.dim; i++)\n                {\n                    Expression e = (*aale.values)[i];\n                    if (e)\n                    {\n                        e = inferType(e, tv, flag);\n                        (*aale.values)[i] = e;\n                    }\n                }\n            }\n            result = aale;\n        }\n\n        override void visit(FuncExp fe)\n        {\n            //printf(\"FuncExp::inferType('%s'), to=%s\\n\", fe.type ? fe.type.toChars() : \"null\", t.toChars());\n            if (t.ty == Tdelegate || t.ty == Tpointer && t.nextOf().ty == Tfunction)\n            {\n                fe.fd.treq = t;\n            }\n            result = fe;\n        }\n\n        override void visit(CondExp ce)\n        {\n            Type tb = t.toBasetype();\n            ce.e1 = inferType(ce.e1, tb, flag);\n            ce.e2 = inferType(ce.e2, tb, flag);\n            result = ce;\n        }\n    }\n\n    if (!t)\n        return e;\n\n    scope InferType v = new InferType(t, flag);\n    e.accept(v);\n    return v.result;\n}\n\n/****************************************\n * Scale addition/subtraction to/from pointer.\n */\nExpression scaleFactor(BinExp be, Scope* sc)\n{\n    Type t1b = be.e1.type.toBasetype();\n    Type t2b = be.e2.type.toBasetype();\n    Expression eoff;\n\n    if (t1b.ty == Tpointer && t2b.isintegral())\n    {\n        // Need to adjust operator by the stride\n        // Replace (ptr + int) with (ptr + (int * stride))\n        Type t = Type.tptrdiff_t;\n\n        d_uns64 stride = t1b.nextOf().size(be.loc);\n        if (!t.equals(t2b))\n            be.e2 = be.e2.castTo(sc, t);\n        eoff = be.e2;\n        be.e2 = new MulExp(be.loc, be.e2, new IntegerExp(Loc.initial, stride, t));\n        be.e2.type = t;\n        be.type = be.e1.type;\n    }\n    else if (t2b.ty == Tpointer && t1b.isintegral())\n    {\n        // Need to adjust operator by the stride\n        // Replace (int + ptr) with (ptr + (int * stride))\n        Type t = Type.tptrdiff_t;\n        Expression e;\n\n        d_uns64 stride = t2b.nextOf().size(be.loc);\n        if (!t.equals(t1b))\n            e = be.e1.castTo(sc, t);\n        else\n            e = be.e1;\n        eoff = e;\n        e = new MulExp(be.loc, e, new IntegerExp(Loc.initial, stride, t));\n        e.type = t;\n        be.type = be.e2.type;\n        be.e1 = be.e2;\n        be.e2 = e;\n    }\n    else\n        assert(0);\n\n    if (sc.func && !sc.intypeof)\n    {\n        eoff = eoff.optimize(WANTvalue);\n        if (eoff.op == TOK.int64 && eoff.toInteger() == 0)\n        {\n        }\n        else if (sc.func.setUnsafe())\n        {\n            be.error(\"pointer arithmetic not allowed in @safe functions\");\n            return new ErrorExp();\n        }\n    }\n\n    return be;\n}\n\n/**************************************\n * Return true if e is an empty array literal with dimensionality\n * equal to or less than type of other array.\n * [], [[]], [[[]]], etc.\n * I.e., make sure that [1,2] is compatible with [],\n * [[1,2]] is compatible with [[]], etc.\n */\nprivate bool isVoidArrayLiteral(Expression e, Type other)\n{\n    while (e.op == TOK.arrayLiteral && e.type.ty == Tarray && ((cast(ArrayLiteralExp)e).elements.dim == 1))\n    {\n        auto ale = cast(ArrayLiteralExp)e;\n        e = ale.getElement(0);\n        if (other.ty == Tsarray || other.ty == Tarray)\n            other = other.nextOf();\n        else\n            return false;\n    }\n    if (other.ty != Tsarray && other.ty != Tarray)\n        return false;\n    Type t = e.type;\n    return (e.op == TOK.arrayLiteral && t.ty == Tarray && t.nextOf().ty == Tvoid && (cast(ArrayLiteralExp)e).elements.dim == 0);\n}\n\n/**************************************\n * Combine types.\n * Output:\n *      *pt     merged type, if *pt is not NULL\n *      *pe1    rewritten e1\n *      *pe2    rewritten e2\n * Returns:\n *      true    success\n *      false   failed\n */\nbool typeMerge(Scope* sc, TOK op, Type* pt, Expression* pe1, Expression* pe2)\n{\n    //printf(\"typeMerge() %s op %s\\n\", pe1.toChars(), pe2.toChars());\n\n    MATCH m;\n    Expression e1 = *pe1;\n    Expression e2 = *pe2;\n    Type t1b = e1.type.toBasetype();\n    Type t2b = e2.type.toBasetype();\n\n    if (op != TOK.question || t1b.ty != t2b.ty && (t1b.isTypeBasic() && t2b.isTypeBasic()))\n    {\n        e1 = integralPromotions(e1, sc);\n        e2 = integralPromotions(e2, sc);\n    }\n\n    Type t1 = e1.type;\n    Type t2 = e2.type;\n    assert(t1);\n    Type t = t1;\n\n    /* The start type of alias this type recursion.\n     * In following case, we should save A, and stop recursion\n     * if it appears again.\n     *      X -> Y -> [A] -> B -> A -> B -> ...\n     */\n    Type att1 = null;\n    Type att2 = null;\n\n    //if (t1) printf(\"\\tt1 = %s\\n\", t1.toChars());\n    //if (t2) printf(\"\\tt2 = %s\\n\", t2.toChars());\n    debug\n    {\n        if (!t2)\n            printf(\"\\te2 = '%s'\\n\", e2.toChars());\n    }\n    assert(t2);\n\n    if (t1.mod != t2.mod &&\n        t1.ty == Tenum && t2.ty == Tenum &&\n        (cast(TypeEnum)t1).sym == (cast(TypeEnum)t2).sym)\n    {\n        ubyte mod = MODmerge(t1.mod, t2.mod);\n        t1 = t1.castMod(mod);\n        t2 = t2.castMod(mod);\n    }\n\nLagain:\n    t1b = t1.toBasetype();\n    t2b = t2.toBasetype();\n\n    TY ty = cast(TY)impcnvResult[t1b.ty][t2b.ty];\n    if (ty != Terror)\n    {\n        TY ty1 = cast(TY)impcnvType1[t1b.ty][t2b.ty];\n        TY ty2 = cast(TY)impcnvType2[t1b.ty][t2b.ty];\n\n        if (t1b.ty == ty1) // if no promotions\n        {\n            if (t1.equals(t2))\n            {\n                t = t1;\n                goto Lret;\n            }\n\n            if (t1b.equals(t2b))\n            {\n                t = t1b;\n                goto Lret;\n            }\n        }\n\n        t = Type.basic[ty];\n\n        t1 = Type.basic[ty1];\n        t2 = Type.basic[ty2];\n        e1 = e1.castTo(sc, t1);\n        e2 = e2.castTo(sc, t2);\n        goto Lret;\n    }\n\n    t1 = t1b;\n    t2 = t2b;\n\n    if (t1.ty == Ttuple || t2.ty == Ttuple)\n        goto Lincompatible;\n\n    if (t1.equals(t2))\n    {\n        // merging can not result in new enum type\n        if (t.ty == Tenum)\n            t = t1b;\n    }\n    else if ((t1.ty == Tpointer && t2.ty == Tpointer) || (t1.ty == Tdelegate && t2.ty == Tdelegate))\n    {\n        // Bring pointers to compatible type\n        Type t1n = t1.nextOf();\n        Type t2n = t2.nextOf();\n\n        if (t1n.equals(t2n))\n        {\n        }\n        else if (t1n.ty == Tvoid) // pointers to void are always compatible\n            t = t2;\n        else if (t2n.ty == Tvoid)\n        {\n        }\n        else if (t1.implicitConvTo(t2))\n        {\n            goto Lt2;\n        }\n        else if (t2.implicitConvTo(t1))\n        {\n            goto Lt1;\n        }\n        else if (t1n.ty == Tfunction && t2n.ty == Tfunction)\n        {\n            TypeFunction tf1 = cast(TypeFunction)t1n;\n            TypeFunction tf2 = cast(TypeFunction)t2n;\n            tf1.purityLevel();\n            tf2.purityLevel();\n\n            TypeFunction d = cast(TypeFunction)tf1.syntaxCopy();\n\n            if (tf1.purity != tf2.purity)\n                d.purity = PURE.impure;\n            assert(d.purity != PURE.fwdref);\n\n            d.isnothrow = (tf1.isnothrow && tf2.isnothrow);\n            d.isnogc = (tf1.isnogc && tf2.isnogc);\n\n            if (tf1.trust == tf2.trust)\n                d.trust = tf1.trust;\n            else if (tf1.trust <= TRUST.system || tf2.trust <= TRUST.system)\n                d.trust = TRUST.system;\n            else\n                d.trust = TRUST.trusted;\n\n            Type tx = null;\n            if (t1.ty == Tdelegate)\n            {\n                tx = new TypeDelegate(d);\n            }\n            else\n                tx = d.pointerTo();\n\n            tx = tx.typeSemantic(e1.loc, sc);\n\n            if (t1.implicitConvTo(tx) && t2.implicitConvTo(tx))\n            {\n                t = tx;\n                e1 = e1.castTo(sc, t);\n                e2 = e2.castTo(sc, t);\n                goto Lret;\n            }\n            goto Lincompatible;\n        }\n        else if (t1n.mod != t2n.mod)\n        {\n            if (!t1n.isImmutable() && !t2n.isImmutable() && t1n.isShared() != t2n.isShared())\n                goto Lincompatible;\n            ubyte mod = MODmerge(t1n.mod, t2n.mod);\n            t1 = t1n.castMod(mod).pointerTo();\n            t2 = t2n.castMod(mod).pointerTo();\n            t = t1;\n            goto Lagain;\n        }\n        else if (t1n.ty == Tclass && t2n.ty == Tclass)\n        {\n            ClassDeclaration cd1 = t1n.isClassHandle();\n            ClassDeclaration cd2 = t2n.isClassHandle();\n            int offset;\n            if (cd1.isBaseOf(cd2, &offset))\n            {\n                if (offset)\n                    e2 = e2.castTo(sc, t);\n            }\n            else if (cd2.isBaseOf(cd1, &offset))\n            {\n                t = t2;\n                if (offset)\n                    e1 = e1.castTo(sc, t);\n            }\n            else\n                goto Lincompatible;\n        }\n        else\n        {\n            t1 = t1n.constOf().pointerTo();\n            t2 = t2n.constOf().pointerTo();\n            if (t1.implicitConvTo(t2))\n            {\n                goto Lt2;\n            }\n            else if (t2.implicitConvTo(t1))\n            {\n                goto Lt1;\n            }\n            goto Lincompatible;\n        }\n    }\n    else if ((t1.ty == Tsarray || t1.ty == Tarray) && (e2.op == TOK.null_ && t2.ty == Tpointer && t2.nextOf().ty == Tvoid || e2.op == TOK.arrayLiteral && t2.ty == Tsarray && t2.nextOf().ty == Tvoid && (cast(TypeSArray)t2).dim.toInteger() == 0 || isVoidArrayLiteral(e2, t1)))\n    {\n        /*  (T[n] op void*)   => T[]\n         *  (T[]  op void*)   => T[]\n         *  (T[n] op void[0]) => T[]\n         *  (T[]  op void[0]) => T[]\n         *  (T[n] op void[])  => T[]\n         *  (T[]  op void[])  => T[]\n         */\n        goto Lx1;\n    }\n    else if ((t2.ty == Tsarray || t2.ty == Tarray) && (e1.op == TOK.null_ && t1.ty == Tpointer && t1.nextOf().ty == Tvoid || e1.op == TOK.arrayLiteral && t1.ty == Tsarray && t1.nextOf().ty == Tvoid && (cast(TypeSArray)t1).dim.toInteger() == 0 || isVoidArrayLiteral(e1, t2)))\n    {\n        /*  (void*   op T[n]) => T[]\n         *  (void*   op T[])  => T[]\n         *  (void[0] op T[n]) => T[]\n         *  (void[0] op T[])  => T[]\n         *  (void[]  op T[n]) => T[]\n         *  (void[]  op T[])  => T[]\n         */\n        goto Lx2;\n    }\n    else if ((t1.ty == Tsarray || t1.ty == Tarray) && (m = t1.implicitConvTo(t2)) != MATCH.nomatch)\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=7285\n        // Tsarray op [x, y, ...] should to be Tsarray\n        // https://issues.dlang.org/show_bug.cgi?id=14737\n        // Tsarray ~ [x, y, ...] should to be Tarray\n        if (t1.ty == Tsarray && e2.op == TOK.arrayLiteral && op != TOK.concatenate)\n            goto Lt1;\n        if (m == MATCH.constant && (op == TOK.addAssign || op == TOK.minAssign || op == TOK.mulAssign || op == TOK.divAssign || op == TOK.modAssign || op == TOK.powAssign || op == TOK.andAssign || op == TOK.orAssign || op == TOK.xorAssign))\n        {\n            // Don't make the lvalue const\n            t = t2;\n            goto Lret;\n        }\n        goto Lt2;\n    }\n    else if ((t2.ty == Tsarray || t2.ty == Tarray) && t2.implicitConvTo(t1))\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=7285\n        // https://issues.dlang.org/show_bug.cgi?id=14737\n        if (t2.ty == Tsarray && e1.op == TOK.arrayLiteral && op != TOK.concatenate)\n            goto Lt2;\n        goto Lt1;\n    }\n    else if ((t1.ty == Tsarray || t1.ty == Tarray || t1.ty == Tpointer) && (t2.ty == Tsarray || t2.ty == Tarray || t2.ty == Tpointer) && t1.nextOf().mod != t2.nextOf().mod)\n    {\n        /* If one is mutable and the other invariant, then retry\n         * with both of them as const\n         */\n        Type t1n = t1.nextOf();\n        Type t2n = t2.nextOf();\n        ubyte mod;\n        if (e1.op == TOK.null_ && e2.op != TOK.null_)\n            mod = t2n.mod;\n        else if (e1.op != TOK.null_ && e2.op == TOK.null_)\n            mod = t1n.mod;\n        else if (!t1n.isImmutable() && !t2n.isImmutable() && t1n.isShared() != t2n.isShared())\n            goto Lincompatible;\n        else\n            mod = MODmerge(t1n.mod, t2n.mod);\n\n        if (t1.ty == Tpointer)\n            t1 = t1n.castMod(mod).pointerTo();\n        else\n            t1 = t1n.castMod(mod).arrayOf();\n\n        if (t2.ty == Tpointer)\n            t2 = t2n.castMod(mod).pointerTo();\n        else\n            t2 = t2n.castMod(mod).arrayOf();\n        t = t1;\n        goto Lagain;\n    }\n    else if (t1.ty == Tclass && t2.ty == Tclass)\n    {\n        if (t1.mod != t2.mod)\n        {\n            ubyte mod;\n            if (e1.op == TOK.null_ && e2.op != TOK.null_)\n                mod = t2.mod;\n            else if (e1.op != TOK.null_ && e2.op == TOK.null_)\n                mod = t1.mod;\n            else if (!t1.isImmutable() && !t2.isImmutable() && t1.isShared() != t2.isShared())\n                goto Lincompatible;\n            else\n                mod = MODmerge(t1.mod, t2.mod);\n            t1 = t1.castMod(mod);\n            t2 = t2.castMod(mod);\n            t = t1;\n            goto Lagain;\n        }\n        goto Lcc;\n    }\n    else if (t1.ty == Tclass || t2.ty == Tclass)\n    {\n    Lcc:\n        while (1)\n        {\n            MATCH i1 = e2.implicitConvTo(t1);\n            MATCH i2 = e1.implicitConvTo(t2);\n\n            if (i1 && i2)\n            {\n                // We have the case of class vs. void*, so pick class\n                if (t1.ty == Tpointer)\n                    i1 = MATCH.nomatch;\n                else if (t2.ty == Tpointer)\n                    i2 = MATCH.nomatch;\n            }\n\n            if (i2)\n            {\n                e2 = e2.castTo(sc, t2);\n                goto Lt2;\n            }\n            else if (i1)\n            {\n                e1 = e1.castTo(sc, t1);\n                goto Lt1;\n            }\n            else if (t1.ty == Tclass && t2.ty == Tclass)\n            {\n                TypeClass tc1 = cast(TypeClass)t1;\n                TypeClass tc2 = cast(TypeClass)t2;\n\n                /* Pick 'tightest' type\n                 */\n                ClassDeclaration cd1 = tc1.sym.baseClass;\n                ClassDeclaration cd2 = tc2.sym.baseClass;\n                if (cd1 && cd2)\n                {\n                    t1 = cd1.type.castMod(t1.mod);\n                    t2 = cd2.type.castMod(t2.mod);\n                }\n                else if (cd1)\n                    t1 = cd1.type;\n                else if (cd2)\n                    t2 = cd2.type;\n                else\n                    goto Lincompatible;\n            }\n            else if (t1.ty == Tstruct && (cast(TypeStruct)t1).sym.aliasthis)\n            {\n                if (att1 && e1.type == att1)\n                    goto Lincompatible;\n                if (!att1 && e1.type.checkAliasThisRec())\n                    att1 = e1.type;\n                //printf(\"att tmerge(c || c) e1 = %s\\n\", e1.type.toChars());\n                e1 = resolveAliasThis(sc, e1);\n                t1 = e1.type;\n                continue;\n            }\n            else if (t2.ty == Tstruct && (cast(TypeStruct)t2).sym.aliasthis)\n            {\n                if (att2 && e2.type == att2)\n                    goto Lincompatible;\n                if (!att2 && e2.type.checkAliasThisRec())\n                    att2 = e2.type;\n                //printf(\"att tmerge(c || c) e2 = %s\\n\", e2.type.toChars());\n                e2 = resolveAliasThis(sc, e2);\n                t2 = e2.type;\n                continue;\n            }\n            else\n                goto Lincompatible;\n        }\n    }\n    else if (t1.ty == Tstruct && t2.ty == Tstruct)\n    {\n        if (t1.mod != t2.mod)\n        {\n            if (!t1.isImmutable() && !t2.isImmutable() && t1.isShared() != t2.isShared())\n                goto Lincompatible;\n            ubyte mod = MODmerge(t1.mod, t2.mod);\n            t1 = t1.castMod(mod);\n            t2 = t2.castMod(mod);\n            t = t1;\n            goto Lagain;\n        }\n\n        TypeStruct ts1 = cast(TypeStruct)t1;\n        TypeStruct ts2 = cast(TypeStruct)t2;\n        if (ts1.sym != ts2.sym)\n        {\n            if (!ts1.sym.aliasthis && !ts2.sym.aliasthis)\n                goto Lincompatible;\n\n            MATCH i1 = MATCH.nomatch;\n            MATCH i2 = MATCH.nomatch;\n\n            Expression e1b = null;\n            Expression e2b = null;\n            if (ts2.sym.aliasthis)\n            {\n                if (att2 && e2.type == att2)\n                    goto Lincompatible;\n                if (!att2 && e2.type.checkAliasThisRec())\n                    att2 = e2.type;\n                //printf(\"att tmerge(s && s) e2 = %s\\n\", e2.type.toChars());\n                e2b = resolveAliasThis(sc, e2);\n                i1 = e2b.implicitConvTo(t1);\n            }\n            if (ts1.sym.aliasthis)\n            {\n                if (att1 && e1.type == att1)\n                    goto Lincompatible;\n                if (!att1 && e1.type.checkAliasThisRec())\n                    att1 = e1.type;\n                //printf(\"att tmerge(s && s) e1 = %s\\n\", e1.type.toChars());\n                e1b = resolveAliasThis(sc, e1);\n                i2 = e1b.implicitConvTo(t2);\n            }\n            if (i1 && i2)\n                goto Lincompatible;\n\n            if (i1)\n                goto Lt1;\n            else if (i2)\n                goto Lt2;\n\n            if (e1b)\n            {\n                e1 = e1b;\n                t1 = e1b.type.toBasetype();\n            }\n            if (e2b)\n            {\n                e2 = e2b;\n                t2 = e2b.type.toBasetype();\n            }\n            t = t1;\n            goto Lagain;\n        }\n    }\n    else if (t1.ty == Tstruct || t2.ty == Tstruct)\n    {\n        if (t1.ty == Tstruct && (cast(TypeStruct)t1).sym.aliasthis)\n        {\n            if (att1 && e1.type == att1)\n                goto Lincompatible;\n            if (!att1 && e1.type.checkAliasThisRec())\n                att1 = e1.type;\n            //printf(\"att tmerge(s || s) e1 = %s\\n\", e1.type.toChars());\n            e1 = resolveAliasThis(sc, e1);\n            t1 = e1.type;\n            t = t1;\n            goto Lagain;\n        }\n        if (t2.ty == Tstruct && (cast(TypeStruct)t2).sym.aliasthis)\n        {\n            if (att2 && e2.type == att2)\n                goto Lincompatible;\n            if (!att2 && e2.type.checkAliasThisRec())\n                att2 = e2.type;\n            //printf(\"att tmerge(s || s) e2 = %s\\n\", e2.type.toChars());\n            e2 = resolveAliasThis(sc, e2);\n            t2 = e2.type;\n            t = t2;\n            goto Lagain;\n        }\n        goto Lincompatible;\n    }\n    else if ((e1.op == TOK.string_ || e1.op == TOK.null_) && e1.implicitConvTo(t2))\n    {\n        goto Lt2;\n    }\n    else if ((e2.op == TOK.string_ || e2.op == TOK.null_) && e2.implicitConvTo(t1))\n    {\n        goto Lt1;\n    }\n    else if (t1.ty == Tsarray && t2.ty == Tsarray && e2.implicitConvTo(t1.nextOf().arrayOf()))\n    {\n    Lx1:\n        t = t1.nextOf().arrayOf(); // T[]\n        e1 = e1.castTo(sc, t);\n        e2 = e2.castTo(sc, t);\n    }\n    else if (t1.ty == Tsarray && t2.ty == Tsarray && e1.implicitConvTo(t2.nextOf().arrayOf()))\n    {\n    Lx2:\n        t = t2.nextOf().arrayOf();\n        e1 = e1.castTo(sc, t);\n        e2 = e2.castTo(sc, t);\n    }\n    else if (t1.ty == Tvector && t2.ty == Tvector)\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=13841\n        // all vector types should have no common types between\n        // different vectors, even though their sizes are same.\n        auto tv1 = cast(TypeVector)t1;\n        auto tv2 = cast(TypeVector)t2;\n        if (!tv1.basetype.equals(tv2.basetype))\n            goto Lincompatible;\n\n        goto LmodCompare;\n    }\n    else if (t1.ty == Tvector && t2.ty != Tvector && e2.implicitConvTo(t1))\n    {\n        e2 = e2.castTo(sc, t1);\n        t2 = t1;\n        t = t1;\n        goto Lagain;\n    }\n    else if (t2.ty == Tvector && t1.ty != Tvector && e1.implicitConvTo(t2))\n    {\n        e1 = e1.castTo(sc, t2);\n        t1 = t2;\n        t = t1;\n        goto Lagain;\n    }\n    else if (t1.isintegral() && t2.isintegral())\n    {\n        if (t1.ty != t2.ty)\n        {\n            if (t1.ty == Tvector || t2.ty == Tvector)\n                goto Lincompatible;\n            e1 = integralPromotions(e1, sc);\n            e2 = integralPromotions(e2, sc);\n            t1 = e1.type;\n            t2 = e2.type;\n            goto Lagain;\n        }\n        assert(t1.ty == t2.ty);\nLmodCompare:\n        if (!t1.isImmutable() && !t2.isImmutable() && t1.isShared() != t2.isShared())\n            goto Lincompatible;\n        ubyte mod = MODmerge(t1.mod, t2.mod);\n\n        t1 = t1.castMod(mod);\n        t2 = t2.castMod(mod);\n        t = t1;\n        e1 = e1.castTo(sc, t);\n        e2 = e2.castTo(sc, t);\n        goto Lagain;\n    }\n    else if (t1.ty == Tnull && t2.ty == Tnull)\n    {\n        ubyte mod = MODmerge(t1.mod, t2.mod);\n\n        t = t1.castMod(mod);\n        e1 = e1.castTo(sc, t);\n        e2 = e2.castTo(sc, t);\n        goto Lret;\n    }\n    else if (t2.ty == Tnull && (t1.ty == Tpointer || t1.ty == Taarray || t1.ty == Tarray))\n    {\n        goto Lt1;\n    }\n    else if (t1.ty == Tnull && (t2.ty == Tpointer || t2.ty == Taarray || t2.ty == Tarray))\n    {\n        goto Lt2;\n    }\n    else if (t1.ty == Tarray && isBinArrayOp(op) && isArrayOpOperand(e1))\n    {\n        if (e2.implicitConvTo(t1.nextOf()))\n        {\n            // T[] op T\n            // T[] op cast(T)U\n            e2 = e2.castTo(sc, t1.nextOf());\n            t = t1.nextOf().arrayOf();\n        }\n        else if (t1.nextOf().implicitConvTo(e2.type))\n        {\n            // (cast(T)U)[] op T    (https://issues.dlang.org/show_bug.cgi?id=12780)\n            // e1 is left as U[], it will be handled in arrayOp() later.\n            t = e2.type.arrayOf();\n        }\n        else if (t2.ty == Tarray && isArrayOpOperand(e2))\n        {\n            if (t1.nextOf().implicitConvTo(t2.nextOf()))\n            {\n                // (cast(T)U)[] op T[]  (https://issues.dlang.org/show_bug.cgi?id=12780)\n                // e1 is left as U[], it will be handled in arrayOp() later.\n                t = t2.nextOf().arrayOf();\n            }\n            else if (t2.nextOf().implicitConvTo(t1.nextOf()))\n            {\n                // T[] op (cast(T)U)[]  (https://issues.dlang.org/show_bug.cgi?id=12780)\n                // e2 is left as U[], it will be handled in arrayOp() later.\n                t = t1.nextOf().arrayOf();\n            }\n            else\n                goto Lincompatible;\n        }\n        else\n            goto Lincompatible;\n    }\n    else if (t2.ty == Tarray && isBinArrayOp(op) && isArrayOpOperand(e2))\n    {\n        if (e1.implicitConvTo(t2.nextOf()))\n        {\n            // T op T[]\n            // cast(T)U op T[]\n            e1 = e1.castTo(sc, t2.nextOf());\n            t = t2.nextOf().arrayOf();\n        }\n        else if (t2.nextOf().implicitConvTo(e1.type))\n        {\n            // T op (cast(T)U)[]    (https://issues.dlang.org/show_bug.cgi?id=12780)\n            // e2 is left as U[], it will be handled in arrayOp() later.\n            t = e1.type.arrayOf();\n        }\n        else\n            goto Lincompatible;\n\n        //printf(\"test %s\\n\", Token::toChars(op));\n        e1 = e1.optimize(WANTvalue);\n        if (isCommutative(op) && e1.isConst())\n        {\n            /* Swap operands to minimize number of functions generated\n             */\n            //printf(\"swap %s\\n\", Token::toChars(op));\n            Expression tmp = e1;\n            e1 = e2;\n            e2 = tmp;\n        }\n    }\n    else\n    {\n    Lincompatible:\n        return false;\n    }\nLret:\n    if (!*pt)\n        *pt = t;\n    *pe1 = e1;\n    *pe2 = e2;\n\n    version (none)\n    {\n        printf(\"-typeMerge() %s op %s\\n\", e1.toChars(), e2.toChars());\n        if (e1.type)\n            printf(\"\\tt1 = %s\\n\", e1.type.toChars());\n        if (e2.type)\n            printf(\"\\tt2 = %s\\n\", e2.type.toChars());\n        printf(\"\\ttype = %s\\n\", t.toChars());\n    }\n    return true;\n\nLt1:\n    e2 = e2.castTo(sc, t1);\n    t = t1;\n    goto Lret;\n\nLt2:\n    e1 = e1.castTo(sc, t2);\n    t = t2;\n    goto Lret;\n}\n\n/************************************\n * Bring leaves to common type.\n * Returns:\n *    null on success, ErrorExp if error occurs\n */\nExpression typeCombine(BinExp be, Scope* sc)\n{\n    Expression errorReturn()\n    {\n        Expression ex = be.incompatibleTypes();\n        if (ex.op == TOK.error)\n            return ex;\n        return new ErrorExp();\n    }\n\n    Type t1 = be.e1.type.toBasetype();\n    Type t2 = be.e2.type.toBasetype();\n\n    if (be.op == TOK.min || be.op == TOK.add)\n    {\n        // struct+struct, and class+class are errors\n        if (t1.ty == Tstruct && t2.ty == Tstruct)\n            return errorReturn();\n        else if (t1.ty == Tclass && t2.ty == Tclass)\n            return errorReturn();\n        else if (t1.ty == Taarray && t2.ty == Taarray)\n            return errorReturn();\n    }\n\n    if (!typeMerge(sc, be.op, &be.type, &be.e1, &be.e2))\n        return errorReturn();\n\n    // If the types have no value, return an error\n    if (be.e1.op == TOK.error)\n        return be.e1;\n    if (be.e2.op == TOK.error)\n        return be.e2;\n    return null;\n}\n\n/***********************************\n * Do integral promotions (convertchk).\n * Don't convert <array of> to <pointer to>\n */\nExpression integralPromotions(Expression e, Scope* sc)\n{\n    //printf(\"integralPromotions %s %s\\n\", e.toChars(), e.type.toChars());\n    switch (e.type.toBasetype().ty)\n    {\n    case Tvoid:\n        e.error(\"void has no value\");\n        return new ErrorExp();\n\n    case Tint8:\n    case Tuns8:\n    case Tint16:\n    case Tuns16:\n    case Tbool:\n    case Tchar:\n    case Twchar:\n        e = e.castTo(sc, Type.tint32);\n        break;\n\n    case Tdchar:\n        e = e.castTo(sc, Type.tuns32);\n        break;\n\n    default:\n        break;\n    }\n    return e;\n}\n\n/******************************************************\n * This provides a transition from the non-promoting behavior\n * of unary + - ~ to the C-like integral promotion behavior.\n * Params:\n *    sc = context\n *    ue = NegExp, UAddExp, or ComExp which is revised per rules\n * References:\n *      https://issues.dlang.org/show_bug.cgi?id=16997\n */\n\nvoid fix16997(Scope* sc, UnaExp ue)\n{\n    if (global.params.fix16997)\n        ue.e1 = integralPromotions(ue.e1, sc);          // desired C-like behavor\n    else\n    {\n        switch (ue.e1.type.toBasetype.ty)\n        {\n            case Tint8:\n            case Tuns8:\n            case Tint16:\n            case Tuns16:\n            //case Tbool:       // these operations aren't allowed on bool anyway\n            case Tchar:\n            case Twchar:\n            case Tdchar:\n                ue.deprecation(\"integral promotion not done for `%s`, use '-transition=intpromote' switch or `%scast(int)(%s)`\",\n                    ue.toChars(), Token.toChars(ue.op), ue.e1.toChars());\n                break;\n\n            default:\n                break;\n        }\n    }\n}\n\n/***********************************\n * See if both types are arrays that can be compared\n * for equality. Return true if so.\n * If they are arrays, but incompatible, issue error.\n * This is to enable comparing things like an immutable\n * array with a mutable one.\n */\nextern (C++) bool arrayTypeCompatible(Loc loc, Type t1, Type t2)\n{\n    t1 = t1.toBasetype().merge2();\n    t2 = t2.toBasetype().merge2();\n\n    if ((t1.ty == Tarray || t1.ty == Tsarray || t1.ty == Tpointer) && (t2.ty == Tarray || t2.ty == Tsarray || t2.ty == Tpointer))\n    {\n        if (t1.nextOf().implicitConvTo(t2.nextOf()) < MATCH.constant && t2.nextOf().implicitConvTo(t1.nextOf()) < MATCH.constant && (t1.nextOf().ty != Tvoid && t2.nextOf().ty != Tvoid))\n        {\n            error(loc, \"array equality comparison type mismatch, `%s` vs `%s`\", t1.toChars(), t2.toChars());\n        }\n        return true;\n    }\n    return false;\n}\n\n/***********************************\n * See if both types are arrays that can be compared\n * for equality without any casting. Return true if so.\n * This is to enable comparing things like an immutable\n * array with a mutable one.\n */\nextern (C++) bool arrayTypeCompatibleWithoutCasting(Type t1, Type t2)\n{\n    t1 = t1.toBasetype();\n    t2 = t2.toBasetype();\n\n    if ((t1.ty == Tarray || t1.ty == Tsarray || t1.ty == Tpointer) && t2.ty == t1.ty)\n    {\n        if (t1.nextOf().implicitConvTo(t2.nextOf()) >= MATCH.constant || t2.nextOf().implicitConvTo(t1.nextOf()) >= MATCH.constant)\n            return true;\n    }\n    return false;\n}\n\n/******************************************************************/\n/* Determine the integral ranges of an expression.\n * This is used to determine if implicit narrowing conversions will\n * be allowed.\n */\nIntRange getIntRange(Expression e)\n{\n    extern (C++) final class IntRangeVisitor : Visitor\n    {\n        alias visit = Visitor.visit;\n\n    public:\n        IntRange range;\n\n        override void visit(Expression e)\n        {\n            range = IntRange.fromType(e.type);\n        }\n\n        override void visit(IntegerExp e)\n        {\n            range = IntRange(SignExtendedNumber(e.getInteger()))._cast(e.type);\n        }\n\n        override void visit(CastExp e)\n        {\n            range = getIntRange(e.e1)._cast(e.type);\n        }\n\n        override void visit(AddExp e)\n        {\n            IntRange ir1 = getIntRange(e.e1);\n            IntRange ir2 = getIntRange(e.e2);\n            range = (ir1 + ir2)._cast(e.type);\n        }\n\n        override void visit(MinExp e)\n        {\n            IntRange ir1 = getIntRange(e.e1);\n            IntRange ir2 = getIntRange(e.e2);\n            range = (ir1 - ir2)._cast(e.type);\n        }\n\n        override void visit(DivExp e)\n        {\n            IntRange ir1 = getIntRange(e.e1);\n            IntRange ir2 = getIntRange(e.e2);\n\n            range = (ir1 / ir2)._cast(e.type);\n        }\n\n        override void visit(MulExp e)\n        {\n            IntRange ir1 = getIntRange(e.e1);\n            IntRange ir2 = getIntRange(e.e2);\n\n            range = (ir1 * ir2)._cast(e.type);\n        }\n\n        override void visit(ModExp e)\n        {\n            IntRange ir1 = getIntRange(e.e1);\n            IntRange ir2 = getIntRange(e.e2);\n\n            // Modding on 0 is invalid anyway.\n            if (!ir2.absNeg().imin.negative)\n            {\n                visit(cast(Expression)e);\n                return;\n            }\n            range = (ir1 % ir2)._cast(e.type);\n        }\n\n        override void visit(AndExp e)\n        {\n            IntRange result;\n            bool hasResult = false;\n            result.unionOrAssign(getIntRange(e.e1) & getIntRange(e.e2), hasResult);\n\n            assert(hasResult);\n            range = result._cast(e.type);\n        }\n\n        override void visit(OrExp e)\n        {\n            IntRange result;\n            bool hasResult = false;\n            result.unionOrAssign(getIntRange(e.e1) | getIntRange(e.e2), hasResult);\n\n            assert(hasResult);\n            range = result._cast(e.type);\n        }\n\n        override void visit(XorExp e)\n        {\n            IntRange result;\n            bool hasResult = false;\n            result.unionOrAssign(getIntRange(e.e1) ^ getIntRange(e.e2), hasResult);\n\n            assert(hasResult);\n            range = result._cast(e.type);\n        }\n\n        override void visit(ShlExp e)\n        {\n            IntRange ir1 = getIntRange(e.e1);\n            IntRange ir2 = getIntRange(e.e2);\n\n            range = (ir1 << ir2)._cast(e.type);\n        }\n\n        override void visit(ShrExp e)\n        {\n            IntRange ir1 = getIntRange(e.e1);\n            IntRange ir2 = getIntRange(e.e2);\n\n            range = (ir1 >> ir2)._cast(e.type);\n        }\n\n        override void visit(UshrExp e)\n        {\n            IntRange ir1 = getIntRange(e.e1).castUnsigned(e.e1.type);\n            IntRange ir2 = getIntRange(e.e2);\n\n            range = (ir1 >>> ir2)._cast(e.type);\n        }\n\n        override void visit(AssignExp e)\n        {\n            range = getIntRange(e.e2)._cast(e.type);\n        }\n\n        override void visit(CondExp e)\n        {\n            // No need to check e.econd; assume caller has called optimize()\n            IntRange ir1 = getIntRange(e.e1);\n            IntRange ir2 = getIntRange(e.e2);\n            range = ir1.unionWith(ir2)._cast(e.type);\n        }\n\n        override void visit(VarExp e)\n        {\n            Expression ie;\n            VarDeclaration vd = e.var.isVarDeclaration();\n            if (vd && vd.range)\n                range = vd.range._cast(e.type);\n            else if (vd && vd._init && !vd.type.isMutable() && (ie = vd.getConstInitializer()) !is null)\n                ie.accept(this);\n            else\n                visit(cast(Expression)e);\n        }\n\n        override void visit(CommaExp e)\n        {\n            e.e2.accept(this);\n        }\n\n        override void visit(ComExp e)\n        {\n            IntRange ir = getIntRange(e.e1);\n            range = IntRange(SignExtendedNumber(~ir.imax.value, !ir.imax.negative), SignExtendedNumber(~ir.imin.value, !ir.imin.negative))._cast(e.type);\n        }\n\n        override void visit(NegExp e)\n        {\n            IntRange ir = getIntRange(e.e1);\n            range = (-ir)._cast(e.type);\n        }\n    }\n\n    scope IntRangeVisitor v = new IntRangeVisitor();\n    e.accept(v);\n    return v.range;\n}\n"
  },
  {
    "path": "gcc/d/dmd/dclass.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dclass.d, _dclass.d)\n * Documentation:  https://dlang.org/phobos/dmd_dclass.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dclass.d\n */\n\nmodule dmd.dclass;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\n\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.gluelayer;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.objc;\nimport dmd.root.rmem;\nimport dmd.target;\nimport dmd.visitor;\n\nenum Abstract : int\n{\n    fwdref = 0,      // whether an abstract class is not yet computed\n    yes,             // is abstract class\n    no,              // is not abstract class\n}\n\n/***********************************************************\n */\nstruct BaseClass\n{\n    Type type;          // (before semantic processing)\n\n    ClassDeclaration sym;\n    uint offset;        // 'this' pointer offset\n\n    // for interfaces: Array of FuncDeclaration's making up the vtbl[]\n    FuncDeclarations vtbl;\n\n    // if BaseClass is an interface, these\n    // are a copy of the InterfaceDeclaration.interfaces\n    BaseClass[] baseInterfaces;\n\n    extern (D) this(Type type)\n    {\n        //printf(\"BaseClass(this = %p, '%s')\\n\", this, type.toChars());\n        this.type = type;\n    }\n\n    /****************************************\n     * Fill in vtbl[] for base class based on member functions of class cd.\n     * Input:\n     *      vtbl            if !=NULL, fill it in\n     *      newinstance     !=0 means all entries must be filled in by members\n     *                      of cd, not members of any base classes of cd.\n     * Returns:\n     *      true if any entries were filled in by members of cd (not exclusively\n     *      by base classes)\n     */\n    extern (C++) bool fillVtbl(ClassDeclaration cd, FuncDeclarations* vtbl, int newinstance)\n    {\n        bool result = false;\n\n        //printf(\"BaseClass.fillVtbl(this='%s', cd='%s')\\n\", sym.toChars(), cd.toChars());\n        if (vtbl)\n            vtbl.setDim(sym.vtbl.dim);\n\n        // first entry is ClassInfo reference\n        for (size_t j = sym.vtblOffset(); j < sym.vtbl.dim; j++)\n        {\n            FuncDeclaration ifd = sym.vtbl[j].isFuncDeclaration();\n            FuncDeclaration fd;\n            TypeFunction tf;\n\n            //printf(\"        vtbl[%d] is '%s'\\n\", j, ifd ? ifd.toChars() : \"null\");\n            assert(ifd);\n\n            // Find corresponding function in this class\n            tf = ifd.type.toTypeFunction();\n            fd = cd.findFunc(ifd.ident, tf);\n            if (fd && !fd.isAbstract())\n            {\n                //printf(\"            found\\n\");\n                // Check that calling conventions match\n                if (fd.linkage != ifd.linkage)\n                    fd.error(\"linkage doesn't match interface function\");\n\n                // Check that it is current\n                //printf(\"newinstance = %d fd.toParent() = %s ifd.toParent() = %s\\n\",\n                    //newinstance, fd.toParent().toChars(), ifd.toParent().toChars());\n                if (newinstance && fd.toParent() != cd && ifd.toParent() == sym)\n                    cd.error(\"interface function `%s` is not implemented\", ifd.toFullSignature());\n\n                if (fd.toParent() == cd)\n                    result = true;\n            }\n            else\n            {\n                //printf(\"            not found %p\\n\", fd);\n                // BUG: should mark this class as abstract?\n                if (!cd.isAbstract())\n                    cd.error(\"interface function `%s` is not implemented\", ifd.toFullSignature());\n\n                fd = null;\n            }\n            if (vtbl)\n                (*vtbl)[j] = fd;\n        }\n        return result;\n    }\n\n    extern (C++) void copyBaseInterfaces(BaseClasses* vtblInterfaces)\n    {\n        //printf(\"+copyBaseInterfaces(), %s\\n\", sym.toChars());\n        //    if (baseInterfaces.length)\n        //      return;\n        auto bc = cast(BaseClass*)mem.xcalloc(sym.interfaces.length, BaseClass.sizeof);\n        baseInterfaces = bc[0 .. sym.interfaces.length];\n        //printf(\"%s.copyBaseInterfaces()\\n\", sym.toChars());\n        for (size_t i = 0; i < baseInterfaces.length; i++)\n        {\n            BaseClass* b = &baseInterfaces[i];\n            BaseClass* b2 = sym.interfaces[i];\n\n            assert(b2.vtbl.dim == 0); // should not be filled yet\n            memcpy(b, b2, BaseClass.sizeof);\n\n            if (i) // single inheritance is i==0\n                vtblInterfaces.push(b); // only need for M.I.\n            b.copyBaseInterfaces(vtblInterfaces);\n        }\n        //printf(\"-copyBaseInterfaces\\n\");\n    }\n}\n\nenum ClassFlags : int\n{\n    none          = 0x0,\n    isCOMclass    = 0x1,\n    noPointers    = 0x2,\n    hasOffTi      = 0x4,\n    hasCtor       = 0x8,\n    hasGetMembers = 0x10,\n    hasTypeInfo   = 0x20,\n    isAbstract    = 0x40,\n    isCPPclass    = 0x80,\n    hasDtor       = 0x100,\n}\n\n/***********************************************************\n */\nextern (C++) class ClassDeclaration : AggregateDeclaration\n{\n    extern (C++) __gshared\n    {\n        // Names found by reading object.d in druntime\n        ClassDeclaration object;\n        ClassDeclaration throwable;\n        ClassDeclaration exception;\n        ClassDeclaration errorException;\n        ClassDeclaration cpp_type_info_ptr;   // Object.__cpp_type_info_ptr\n    }\n\n    ClassDeclaration baseClass; // NULL only if this is Object\n    FuncDeclaration staticCtor;\n    FuncDeclaration staticDtor;\n    Dsymbols vtbl;              // Array of FuncDeclaration's making up the vtbl[]\n    Dsymbols vtblFinal;         // More FuncDeclaration's that aren't in vtbl[]\n\n    // Array of BaseClass's; first is super, rest are Interface's\n    BaseClasses* baseclasses;\n\n    /* Slice of baseclasses[] that does not include baseClass\n     */\n    BaseClass*[] interfaces;\n\n    // array of base interfaces that have their own vtbl[]\n    BaseClasses* vtblInterfaces;\n\n    // the ClassInfo object for this ClassDeclaration\n    TypeInfoClassDeclaration vclassinfo;\n\n    // true if this is a COM class\n    bool com;\n\n    /// true if this is a scope class\n    bool stack;\n\n    /// if this is a C++ class, this is the slot reserved for the virtual destructor\n    int cppDtorVtblIndex = -1;\n\n    /// to prevent recursive attempts\n    private bool inuse;\n\n    /// true if this class has an identifier, but was originally declared anonymous\n    /// used in support of https://issues.dlang.org/show_bug.cgi?id=17371\n    private bool isActuallyAnonymous;\n\n    Abstract isabstract;\n\n    /// set the progress of base classes resolving\n    Baseok baseok;\n\n    /**\n     * Data for a class declaration that is needed for the Objective-C\n     * integration.\n     */\n    ObjcClassDeclaration objc;\n\n    Symbol* cpp_type_info_ptr_sym;      // cached instance of class Id.cpp_type_info_ptr\n\n    final extern (D) this(const ref Loc loc, Identifier id, BaseClasses* baseclasses, Dsymbols* members, bool inObject)\n    {\n        if (!id)\n        {\n            id = Identifier.generateId(\"__anonclass\");\n            isActuallyAnonymous = true;\n        }\n        assert(id);\n\n        super(loc, id);\n\n        __gshared const(char)* msg = \"only object.d can define this reserved class name\";\n\n        if (baseclasses)\n        {\n            // Actually, this is a transfer\n            this.baseclasses = baseclasses;\n        }\n        else\n            this.baseclasses = new BaseClasses();\n\n        this.members = members;\n\n        //printf(\"ClassDeclaration(%s), dim = %d\\n\", id.toChars(), this.baseclasses.dim);\n\n        // For forward references\n        type = new TypeClass(this);\n\n        if (id)\n        {\n            // Look for special class names\n            if (id == Id.__sizeof || id == Id.__xalignof || id == Id._mangleof)\n                error(\"illegal class name\");\n\n            // BUG: What if this is the wrong TypeInfo, i.e. it is nested?\n            if (id.toChars()[0] == 'T')\n            {\n                if (id == Id.TypeInfo)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.dtypeinfo = this;\n                }\n                if (id == Id.TypeInfo_Class)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfoclass = this;\n                }\n                if (id == Id.TypeInfo_Interface)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfointerface = this;\n                }\n                if (id == Id.TypeInfo_Struct)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfostruct = this;\n                }\n                if (id == Id.TypeInfo_Pointer)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfopointer = this;\n                }\n                if (id == Id.TypeInfo_Array)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfoarray = this;\n                }\n                if (id == Id.TypeInfo_StaticArray)\n                {\n                    //if (!inObject)\n                    //    Type.typeinfostaticarray.error(\"%s\", msg);\n                    Type.typeinfostaticarray = this;\n                }\n                if (id == Id.TypeInfo_AssociativeArray)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfoassociativearray = this;\n                }\n                if (id == Id.TypeInfo_Enum)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfoenum = this;\n                }\n                if (id == Id.TypeInfo_Function)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfofunction = this;\n                }\n                if (id == Id.TypeInfo_Delegate)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfodelegate = this;\n                }\n                if (id == Id.TypeInfo_Tuple)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfotypelist = this;\n                }\n                if (id == Id.TypeInfo_Const)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfoconst = this;\n                }\n                if (id == Id.TypeInfo_Invariant)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfoinvariant = this;\n                }\n                if (id == Id.TypeInfo_Shared)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfoshared = this;\n                }\n                if (id == Id.TypeInfo_Wild)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfowild = this;\n                }\n                if (id == Id.TypeInfo_Vector)\n                {\n                    if (!inObject)\n                        error(\"%s\", msg);\n                    Type.typeinfovector = this;\n                }\n            }\n\n            if (id == Id.Object)\n            {\n                if (!inObject)\n                    error(\"%s\", msg);\n                object = this;\n            }\n\n            if (id == Id.Throwable)\n            {\n                if (!inObject)\n                    error(\"%s\", msg);\n                throwable = this;\n            }\n            if (id == Id.Exception)\n            {\n                if (!inObject)\n                    error(\"%s\", msg);\n                exception = this;\n            }\n            if (id == Id.Error)\n            {\n                if (!inObject)\n                    error(\"%s\", msg);\n                errorException = this;\n            }\n            if (id == Id.cpp_type_info_ptr)\n            {\n                if (!inObject)\n                    error(\"%s\", msg);\n                cpp_type_info_ptr = this;\n            }\n        }\n        baseok = Baseok.none;\n    }\n\n    static ClassDeclaration create(Loc loc, Identifier id, BaseClasses* baseclasses, Dsymbols* members, bool inObject)\n    {\n        return new ClassDeclaration(loc, id, baseclasses, members, inObject);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        //printf(\"ClassDeclaration.syntaxCopy('%s')\\n\", toChars());\n        ClassDeclaration cd =\n            s ? cast(ClassDeclaration)s\n              : new ClassDeclaration(loc, ident, null, null, false);\n\n        cd.storage_class |= storage_class;\n\n        cd.baseclasses.setDim(this.baseclasses.dim);\n        for (size_t i = 0; i < cd.baseclasses.dim; i++)\n        {\n            BaseClass* b = (*this.baseclasses)[i];\n            auto b2 = new BaseClass(b.type.syntaxCopy());\n            (*cd.baseclasses)[i] = b2;\n        }\n\n        return ScopeDsymbol.syntaxCopy(cd);\n    }\n\n    override Scope* newScope(Scope* sc)\n    {\n        auto sc2 = super.newScope(sc);\n        if (isCOMclass())\n        {\n            /* This enables us to use COM objects under Linux and\n             * work with things like XPCOM\n             */\n            sc2.linkage = Target.systemLinkage();\n        }\n        return sc2;\n    }\n\n    /*********************************************\n     * Determine if 'this' is a base class of cd.\n     * This is used to detect circular inheritance only.\n     */\n    final bool isBaseOf2(ClassDeclaration cd)\n    {\n        if (!cd)\n            return false;\n        //printf(\"ClassDeclaration.isBaseOf2(this = '%s', cd = '%s')\\n\", toChars(), cd.toChars());\n        for (size_t i = 0; i < cd.baseclasses.dim; i++)\n        {\n            BaseClass* b = (*cd.baseclasses)[i];\n            if (b.sym == this || isBaseOf2(b.sym))\n                return true;\n        }\n        return false;\n    }\n\n    enum OFFSET_RUNTIME = 0x76543210;\n    enum OFFSET_FWDREF = 0x76543211;\n\n    /*******************************************\n     * Determine if 'this' is a base class of cd.\n     */\n    bool isBaseOf(ClassDeclaration cd, int* poffset)\n    {\n        //printf(\"ClassDeclaration.isBaseOf(this = '%s', cd = '%s')\\n\", toChars(), cd.toChars());\n        if (poffset)\n            *poffset = 0;\n        while (cd)\n        {\n            /* cd.baseClass might not be set if cd is forward referenced.\n             */\n            if (!cd.baseClass && cd.semanticRun < PASS.semanticdone && !cd.isInterfaceDeclaration())\n            {\n                cd.dsymbolSemantic(null);\n                if (!cd.baseClass && cd.semanticRun < PASS.semanticdone)\n                    cd.error(\"base class is forward referenced by `%s`\", toChars());\n            }\n\n            if (this == cd.baseClass)\n                return true;\n\n            cd = cd.baseClass;\n        }\n        return false;\n    }\n\n    /*********************************************\n     * Determine if 'this' has complete base class information.\n     * This is used to detect forward references in covariant overloads.\n     */\n    final bool isBaseInfoComplete() const\n    {\n        return baseok >= Baseok.done;\n    }\n\n    override final Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)\n    {\n        //printf(\"%s.ClassDeclaration.search('%s', flags=x%x)\\n\", toChars(), ident.toChars(), flags);\n        //if (_scope) printf(\"%s baseok = %d\\n\", toChars(), baseok);\n        if (_scope && baseok < Baseok.done)\n        {\n            if (!inuse)\n            {\n                // must semantic on base class/interfaces\n                inuse = true;\n                dsymbolSemantic(this, null);\n                inuse = false;\n            }\n        }\n\n        if (!members || !symtab) // opaque or addMember is not yet done\n        {\n            error(\"is forward referenced when looking for `%s`\", ident.toChars());\n            //*(char*)0=0;\n            return null;\n        }\n\n        auto s = ScopeDsymbol.search(loc, ident, flags);\n\n        // don't search imports of base classes\n        if (flags & SearchImportsOnly)\n            return s;\n\n        if (!s)\n        {\n            // Search bases classes in depth-first, left to right order\n            for (size_t i = 0; i < baseclasses.dim; i++)\n            {\n                BaseClass* b = (*baseclasses)[i];\n                if (b.sym)\n                {\n                    if (!b.sym.symtab)\n                        error(\"base `%s` is forward referenced\", b.sym.ident.toChars());\n                    else\n                    {\n                        import dmd.access : symbolIsVisible;\n\n                        s = b.sym.search(loc, ident, flags);\n                        if (!s)\n                            continue;\n                        else if (s == this) // happens if s is nested in this and derives from this\n                            s = null;\n                        else if (!(flags & IgnoreSymbolVisibility) && !(s.prot().kind == Prot.Kind.protected_) && !symbolIsVisible(this, s))\n                            s = null;\n                        else\n                            break;\n                    }\n                }\n            }\n        }\n        return s;\n    }\n\n    /************************************\n     * Search base classes in depth-first, left-to-right order for\n     * a class or interface named 'ident'.\n     * Stops at first found. Does not look for additional matches.\n     * Params:\n     *  ident = identifier to search for\n     * Returns:\n     *  ClassDeclaration if found, null if not\n     */\n    final ClassDeclaration searchBase(Identifier ident)\n    {\n        foreach (b; *baseclasses)\n        {\n            auto cdb = b.type.isClassHandle();\n            if (!cdb) // https://issues.dlang.org/show_bug.cgi?id=10616\n                return null;\n            if (cdb.ident.equals(ident))\n                return cdb;\n            auto result = cdb.searchBase(ident);\n            if (result)\n                return result;\n        }\n        return null;\n    }\n\n    final override void finalizeSize()\n    {\n        assert(sizeok != Sizeok.done);\n\n        // Set the offsets of the fields and determine the size of the class\n        if (baseClass)\n        {\n            assert(baseClass.sizeok == Sizeok.done);\n\n            alignsize = baseClass.alignsize;\n            structsize = baseClass.structsize;\n            if (classKind == ClassKind.cpp && global.params.isWindows)\n                structsize = (structsize + alignsize - 1) & ~(alignsize - 1);\n        }\n        else if (isInterfaceDeclaration())\n        {\n            if (interfaces.length == 0)\n            {\n                alignsize = Target.ptrsize;\n                structsize = Target.ptrsize;      // allow room for __vptr\n            }\n        }\n        else\n        {\n            alignsize = Target.ptrsize;\n            structsize = Target.ptrsize;      // allow room for __vptr\n            if (classKind != ClassKind.cpp)\n                structsize += Target.ptrsize; // allow room for __monitor\n        }\n\n        //printf(\"finalizeSize() %s, sizeok = %d\\n\", toChars(), sizeok);\n        size_t bi = 0;                  // index into vtblInterfaces[]\n\n        /****\n         * Runs through the inheritance graph to set the BaseClass.offset fields.\n         * Recursive in order to account for the size of the interface classes, if they are\n         * more than just interfaces.\n         * Params:\n         *      cd = interface to look at\n         *      baseOffset = offset of where cd will be placed\n         * Returns:\n         *      subset of instantiated size used by cd for interfaces\n         */\n        uint membersPlace(ClassDeclaration cd, uint baseOffset)\n        {\n            //printf(\"    membersPlace(%s, %d)\\n\", cd.toChars(), baseOffset);\n            uint offset = baseOffset;\n\n            foreach (BaseClass* b; cd.interfaces)\n            {\n                if (b.sym.sizeok != Sizeok.done)\n                    b.sym.finalizeSize();\n                assert(b.sym.sizeok == Sizeok.done);\n\n                if (!b.sym.alignsize)\n                    b.sym.alignsize = Target.ptrsize;\n                alignmember(b.sym.alignsize, b.sym.alignsize, &offset);\n                assert(bi < vtblInterfaces.dim);\n\n                BaseClass* bv = (*vtblInterfaces)[bi];\n                if (b.sym.interfaces.length == 0)\n                {\n                    //printf(\"\\tvtblInterfaces[%d] b=%p b.sym = %s, offset = %d\\n\", bi, bv, bv.sym.toChars(), offset);\n                    bv.offset = offset;\n                    ++bi;\n                    // All the base interfaces down the left side share the same offset\n                    for (BaseClass* b2 = bv; b2.baseInterfaces.length; )\n                    {\n                        b2 = &b2.baseInterfaces[0];\n                        b2.offset = offset;\n                        //printf(\"\\tvtblInterfaces[%d] b=%p   sym = %s, offset = %d\\n\", bi, b2, b2.sym.toChars(), b2.offset);\n                    }\n                }\n                membersPlace(b.sym, offset);\n                //printf(\" %s size = %d\\n\", b.sym.toChars(), b.sym.structsize);\n                offset += b.sym.structsize;\n                if (alignsize < b.sym.alignsize)\n                    alignsize = b.sym.alignsize;\n            }\n            return offset - baseOffset;\n        }\n\n        structsize += membersPlace(this, structsize);\n\n        if (isInterfaceDeclaration())\n        {\n            sizeok = Sizeok.done;\n            return;\n        }\n\n        // FIXME: Currently setFieldOffset functions need to increase fields\n        // to calculate each variable offsets. It can be improved later.\n        fields.setDim(0);\n\n        uint offset = structsize;\n        foreach (s; *members)\n        {\n            s.setFieldOffset(this, &offset, false);\n        }\n\n        sizeok = Sizeok.done;\n\n        // Calculate fields[i].overlapped\n        checkOverlappedFields();\n    }\n\n    override bool isAnonymous()\n    {\n        return isActuallyAnonymous;\n    }\n\n    final bool isFuncHidden(FuncDeclaration fd)\n    {\n        //printf(\"ClassDeclaration.isFuncHidden(class = %s, fd = %s)\\n\", toChars(), fd.toPrettyChars());\n        Dsymbol s = search(Loc.initial, fd.ident, IgnoreAmbiguous | IgnoreErrors);\n        if (!s)\n        {\n            //printf(\"not found\\n\");\n            /* Because, due to a hack, if there are multiple definitions\n             * of fd.ident, NULL is returned.\n             */\n            return false;\n        }\n        s = s.toAlias();\n        if (auto os = s.isOverloadSet())\n        {\n            foreach (sm; os.a)\n            {\n                auto fm = sm.isFuncDeclaration();\n                if (overloadApply(fm, s => fd == s.isFuncDeclaration()))\n                    return false;\n            }\n            return true;\n        }\n        else\n        {\n            auto f = s.isFuncDeclaration();\n            //printf(\"%s fdstart = %p\\n\", s.kind(), fdstart);\n            if (overloadApply(f, s => fd == s.isFuncDeclaration()))\n                return false;\n            return !fd.parent.isTemplateMixin();\n        }\n    }\n\n    /****************\n     * Find virtual function matching identifier and type.\n     * Used to build virtual function tables for interface implementations.\n     * Params:\n     *  ident = function's identifier\n     *  tf = function's type\n     * Returns:\n     *  function symbol if found, null if not\n     * Errors:\n     *  prints error message if more than one match\n     */\n    final FuncDeclaration findFunc(Identifier ident, TypeFunction tf)\n    {\n        //printf(\"ClassDeclaration.findFunc(%s, %s) %s\\n\", ident.toChars(), tf.toChars(), toChars());\n        FuncDeclaration fdmatch = null;\n        FuncDeclaration fdambig = null;\n\n        void searchVtbl(ref Dsymbols vtbl)\n        {\n            foreach (s; vtbl)\n            {\n                auto fd = s.isFuncDeclaration();\n                if (!fd)\n                    continue;\n\n                // the first entry might be a ClassInfo\n                //printf(\"\\t[%d] = %s\\n\", i, fd.toChars());\n                if (ident == fd.ident && fd.type.covariant(tf) == 1)\n                {\n                    //printf(\"fd.parent.isClassDeclaration() = %p\\n\", fd.parent.isClassDeclaration());\n                    if (!fdmatch)\n                        goto Lfd;\n                    if (fd == fdmatch)\n                        goto Lfdmatch;\n\n                    {\n                    // Function type matching: exact > covariant\n                    MATCH m1 = tf.equals(fd.type) ? MATCH.exact : MATCH.nomatch;\n                    MATCH m2 = tf.equals(fdmatch.type) ? MATCH.exact : MATCH.nomatch;\n                    if (m1 > m2)\n                        goto Lfd;\n                    else if (m1 < m2)\n                        goto Lfdmatch;\n                    }\n                    {\n                    MATCH m1 = (tf.mod == fd.type.mod) ? MATCH.exact : MATCH.nomatch;\n                    MATCH m2 = (tf.mod == fdmatch.type.mod) ? MATCH.exact : MATCH.nomatch;\n                    if (m1 > m2)\n                        goto Lfd;\n                    else if (m1 < m2)\n                        goto Lfdmatch;\n                    }\n                    {\n                    // The way of definition: non-mixin > mixin\n                    MATCH m1 = fd.parent.isClassDeclaration() ? MATCH.exact : MATCH.nomatch;\n                    MATCH m2 = fdmatch.parent.isClassDeclaration() ? MATCH.exact : MATCH.nomatch;\n                    if (m1 > m2)\n                        goto Lfd;\n                    else if (m1 < m2)\n                        goto Lfdmatch;\n                    }\n\n                    fdambig = fd;\n                    //printf(\"Lambig fdambig = %s %s [%s]\\n\", fdambig.toChars(), fdambig.type.toChars(), fdambig.loc.toChars());\n                    continue;\n\n                Lfd:\n                    fdmatch = fd;\n                    fdambig = null;\n                    //printf(\"Lfd fdmatch = %s %s [%s]\\n\", fdmatch.toChars(), fdmatch.type.toChars(), fdmatch.loc.toChars());\n                    continue;\n\n                Lfdmatch:\n                    continue;\n                }\n                //else printf(\"\\t\\t%d\\n\", fd.type.covariant(tf));\n            }\n        }\n\n        searchVtbl(vtbl);\n        for (auto cd = this; cd; cd = cd.baseClass)\n        {\n            searchVtbl(cd.vtblFinal);\n        }\n\n        if (fdambig)\n            error(\"ambiguous virtual function `%s`\", fdambig.toChars());\n\n        return fdmatch;\n    }\n\n    /****************************************\n     */\n    final bool isCOMclass() const\n    {\n        return com;\n    }\n\n    bool isCOMinterface() const\n    {\n        return false;\n    }\n\n    final bool isCPPclass() const\n    {\n        return classKind == ClassKind.cpp;\n    }\n\n    bool isCPPinterface() const\n    {\n        return false;\n    }\n\n    /****************************************\n     */\n    final bool isAbstract()\n    {\n        enum log = false;\n        if (isabstract != Abstract.fwdref)\n            return isabstract == Abstract.yes;\n\n        if (log) printf(\"isAbstract(%s)\\n\", toChars());\n\n        bool no()  { if (log) printf(\"no\\n\");  isabstract = Abstract.no;  return false; }\n        bool yes() { if (log) printf(\"yes\\n\"); isabstract = Abstract.yes; return true;  }\n\n        if (storage_class & STC.abstract_ || _scope && _scope.stc & STC.abstract_)\n            return yes();\n\n        if (errors)\n            return no();\n\n        /* https://issues.dlang.org/show_bug.cgi?id=11169\n         * Resolve forward references to all class member functions,\n         * and determine whether this class is abstract.\n         */\n        extern (C++) static int func(Dsymbol s, void* param)\n        {\n            auto fd = s.isFuncDeclaration();\n            if (!fd)\n                return 0;\n            if (fd.storage_class & STC.static_)\n                return 0;\n\n            if (fd.isAbstract())\n                return 1;\n            return 0;\n        }\n\n        for (size_t i = 0; i < members.dim; i++)\n        {\n            auto s = (*members)[i];\n            if (s.apply(&func, cast(void*)this))\n            {\n                return yes();\n            }\n        }\n\n        /* If the base class is not abstract, then this class cannot\n         * be abstract.\n         */\n        if (!isInterfaceDeclaration() && (!baseClass || !baseClass.isAbstract()))\n            return no();\n\n        /* If any abstract functions are inherited, but not overridden,\n         * then the class is abstract. Do this by checking the vtbl[].\n         * Need to do semantic() on class to fill the vtbl[].\n         */\n        this.dsymbolSemantic(null);\n\n        /* The next line should work, but does not because when ClassDeclaration.dsymbolSemantic()\n         * is called recursively it can set PASS.semanticdone without finishing it.\n         */\n        //if (semanticRun < PASS.semanticdone)\n        {\n            /* Could not complete semantic(). Try running semantic() on\n             * each of the virtual functions,\n             * which will fill in the vtbl[] overrides.\n             */\n            extern (C++) static int virtualSemantic(Dsymbol s, void* param)\n            {\n                auto fd = s.isFuncDeclaration();\n                if (fd && !(fd.storage_class & STC.static_) && !fd.isUnitTestDeclaration())\n                    fd.dsymbolSemantic(null);\n                return 0;\n            }\n\n            for (size_t i = 0; i < members.dim; i++)\n            {\n                auto s = (*members)[i];\n                s.apply(&virtualSemantic, cast(void*)this);\n            }\n        }\n\n        /* Finally, check the vtbl[]\n         */\n        foreach (i; 1 .. vtbl.dim)\n        {\n            auto fd = vtbl[i].isFuncDeclaration();\n            //if (fd) printf(\"\\tvtbl[%d] = [%s] %s\\n\", i, fd.loc.toChars(), fd.toPrettyChars());\n            if (!fd || fd.isAbstract())\n            {\n                return yes();\n            }\n        }\n\n        return no();\n    }\n\n    /****************************************\n     * Determine if slot 0 of the vtbl[] is reserved for something else.\n     * For class objects, yes, this is where the classinfo ptr goes.\n     * For COM interfaces, no.\n     * For non-COM interfaces, yes, this is where the Interface ptr goes.\n     * Returns:\n     *      0       vtbl[0] is first virtual function pointer\n     *      1       vtbl[0] is classinfo/interfaceinfo pointer\n     */\n    int vtblOffset() const\n    {\n        return classKind == ClassKind.cpp ? 0 : 1;\n    }\n\n    /****************************************\n     */\n    override const(char)* kind() const\n    {\n        return \"class\";\n    }\n\n    /****************************************\n     */\n    override final void addLocalClass(ClassDeclarations* aclasses)\n    {\n        aclasses.push(this);\n    }\n\n    // Back end\n    Dsymbol vtblsym;\n\n    final Dsymbol vtblSymbol()\n    {\n        if (!vtblsym)\n        {\n            auto vtype = Type.tvoidptr.immutableOf().sarrayOf(vtbl.dim);\n            auto var = new VarDeclaration(loc, vtype, Identifier.idPool(\"__vtbl\"), null, STC.immutable_ | STC.static_);\n            var.addMember(null, this);\n            var.isdataseg = 1;\n            var.linkage = LINK.d;\n            var.semanticRun = PASS.semanticdone; // no more semantic wanted\n            vtblsym = var;\n        }\n        return vtblsym;\n    }\n\n    override final inout(ClassDeclaration) isClassDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class InterfaceDeclaration : ClassDeclaration\n{\n    extern (D) this(const ref Loc loc, Identifier id, BaseClasses* baseclasses)\n    {\n        super(loc, id, baseclasses, null, false);\n        if (id == Id.IUnknown) // IUnknown is the root of all COM interfaces\n        {\n            com = true;\n            classKind = ClassKind.cpp; // IUnknown is also a C++ interface\n        }\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        InterfaceDeclaration id =\n            s ? cast(InterfaceDeclaration)s\n              : new InterfaceDeclaration(loc, ident, null);\n        return ClassDeclaration.syntaxCopy(id);\n    }\n\n\n    override Scope* newScope(Scope* sc)\n    {\n        auto sc2 = super.newScope(sc);\n        if (com)\n            sc2.linkage = LINK.windows;\n        else if (classKind == ClassKind.cpp)\n            sc2.linkage = LINK.cpp;\n        else if (classKind == ClassKind.objc)\n            sc2.linkage = LINK.objc;\n        return sc2;\n    }\n\n    /*******************************************\n     * Determine if 'this' is a base class of cd.\n     * (Actually, if it is an interface supported by cd)\n     * Output:\n     *      *poffset        offset to start of class\n     *                      OFFSET_RUNTIME  must determine offset at runtime\n     * Returns:\n     *      false   not a base\n     *      true    is a base\n     */\n    override bool isBaseOf(ClassDeclaration cd, int* poffset)\n    {\n        //printf(\"%s.InterfaceDeclaration.isBaseOf(cd = '%s')\\n\", toChars(), cd.toChars());\n        assert(!baseClass);\n        foreach (b; cd.interfaces)\n        {\n            //printf(\"\\tX base %s\\n\", b.sym.toChars());\n            if (this == b.sym)\n            {\n                //printf(\"\\tfound at offset %d\\n\", b.offset);\n                if (poffset)\n                {\n                    // don't return incorrect offsets\n                    // https://issues.dlang.org/show_bug.cgi?id=16980\n                    *poffset = cd.sizeok == Sizeok.done ? b.offset : OFFSET_FWDREF;\n                }\n                // printf(\"\\tfound at offset %d\\n\", b.offset);\n                return true;\n            }\n            if (isBaseOf(b, poffset))\n                return true;\n        }\n        if (cd.baseClass && isBaseOf(cd.baseClass, poffset))\n            return true;\n\n        if (poffset)\n            *poffset = 0;\n        return false;\n    }\n\n    bool isBaseOf(BaseClass* bc, int* poffset)\n    {\n        //printf(\"%s.InterfaceDeclaration.isBaseOf(bc = '%s')\\n\", toChars(), bc.sym.toChars());\n        for (size_t j = 0; j < bc.baseInterfaces.length; j++)\n        {\n            BaseClass* b = &bc.baseInterfaces[j];\n            //printf(\"\\tY base %s\\n\", b.sym.toChars());\n            if (this == b.sym)\n            {\n                //printf(\"\\tfound at offset %d\\n\", b.offset);\n                if (poffset)\n                {\n                    *poffset = b.offset;\n                }\n                return true;\n            }\n            if (isBaseOf(b, poffset))\n            {\n                return true;\n            }\n        }\n\n        if (poffset)\n            *poffset = 0;\n        return false;\n    }\n\n    /*******************************************\n     */\n    override const(char)* kind() const\n    {\n        return \"interface\";\n    }\n\n    /****************************************\n     * Determine if slot 0 of the vtbl[] is reserved for something else.\n     * For class objects, yes, this is where the ClassInfo ptr goes.\n     * For COM interfaces, no.\n     * For non-COM interfaces, yes, this is where the Interface ptr goes.\n     */\n    override int vtblOffset() const\n    {\n        if (isCOMinterface() || isCPPinterface())\n            return 0;\n        return 1;\n    }\n\n    override bool isCPPinterface() const\n    {\n        return classKind == ClassKind.cpp;\n    }\n\n    override bool isCOMinterface() const\n    {\n        return com;\n    }\n\n    override inout(InterfaceDeclaration) isInterfaceDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/ddoc/default_ddoc_theme.ddoc",
    "content": "LPAREN = (\nRPAREN = )\nBACKTICK = `\nDOLLAR = $\nLF =\n$(LF)\n\nESCAPES =\n  /</&lt;/\n  />/&gt;/\n  /&/&amp;/\n\nB = <b>$0</b>\nI = <i>$0</i>\nU = <u>$0</u>\nP = <p>$0</p>\nDL = <dl>$0</dl>\nDT = <dt>$0</dt>\nDD = <dd>$0</dd>\nTABLE = <table>$0</table>\nTR = <tr>$0</tr>\nTH = <th>$0</th>\nTD = <td>$0</td>\nOL = <ol>$0</ol>\nUL = <ul>$0</ul>\nLI = <li>$0</li>\nBIG = <span class=\"font_big\">$0</span>\nSMALL = <small>$0</small>\nBR = <br>\nLINK = <a href=\"$0\">$0</a>\nLINK2 = <a href=\"$1\">$+</a>\nDEPRECATED = $0\n\nRED = <span class=\"color_red\">$0</span>\nBLUE = <span class=\"color_blue\">$0</span>\nGREEN = <span class=\"color_green\">$0</span>\nYELLOW = <span class=\"color_yellow\">$0</span>\nBLACK = <span class=\"color_black\">$0</span>\nWHITE = <span class=\"color_white\">$0</span>\n\nD_CODE =\n<section class=\"code_listing\">\n  <div class=\"code_sample\">\n    <div class=\"dlang\">\n      <ol class=\"code_lines\">\n        <li><code class=\"code\">$0</code></li>\n      </ol>\n    </div>\n  </div>\n</section>\n\nD_INLINECODE = <code class=\"code\">$0</code>\nDDOC_BACKQUOTED = $(D_INLINECODE $0)\nD_COMMENT = <span class=\"comment\">$0</span>\nD_STRING = <span class=\"string_literal\">$0</span>\nD_KEYWORD = <span class=\"keyword\">$0</span>\nD_PSYMBOL = <span class=\"psymbol\">$0</span>\nD_PARAM = <span class=\"param\">$0</span>\n\nDDOC_BLANKLINE = <br><br>\nDDOC_COMMENT = <!-- $0 -->\n\nDDOC =\n<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"UTF-8\">\n    <title>$(TITLE)</title>\n    <style type=\"text/css\" media=\"screen\">\n      html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p,\n      blockquote, pre, a, abbr, address, cite, code, del, dfn, em, figure,\n      img, ins, kbd, q, s, samp, small, strong, sub, sup, var, b, u, i, dl,\n      dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption,\n      tbody, tfoot, thead, tr, th, td {\n        background: transparent none repeat scroll 0 0;\n        border: 0 none;\n        font-size: 100%;\n        margin: 0;\n        outline: 0 none;\n        padding: 0;\n        vertical-align: baseline;\n      }\n\n      .color_red { color: #dc322f; }\n      .color_blue { color: #268bd2; }\n      .color_green { color: #859901; }\n      .color_yellow { color: #b58901; }\n      .color_black { color: black; }\n      .color_white { color: white; }\n\n      .font_big {\n        font-size: 1.2em;\n      }\n\n      .ddoc_section_h {\n        font-weight: bold;\n        font-size: 13px;\n        line-height: 19.5px;\n        margin-top: 11px;\n        display: block;\n      }\n\n      body.dlang .dlang {\n        display: inline-block;\n      }\n\n      body.dlang .declaration .dlang {\n          display: block;\n      }\n\n      body.dlang .ddoc_header_anchor a.dlang {\n        display: block;\n        color: rgba(0, 136, 204, 1);\n        text-decoration: none;\n      }\n\n      body.dlang .ddoc_header_anchor .code {\n        color: rgba(0, 136, 204, 1);\n      }\n\n      #ddoc_main .module {\n          border-color: currentColor rgba(233, 233, 233, 1) rgba(233, 233, 233, 1);\n          border-style: none solid solid;\n          border-width: 0 1px 1px;\n          overflow-x: hidden;\n          padding: 15px;\n      }\n\n      #ddoc_main .section .section {\n        margin-top: 0;\n      }\n\n      #ddoc_main .ddoc_module_members_section {\n          padding: 1px 0 0;\n          transition: transform 0.3s ease 0s;\n      }\n\n      #ddoc_main .ddoc_member, #ddoc_main .ddoc_module_members section.intro {\n          background: #fff none repeat scroll 0 0;\n          list-style-type: none;\n          width: 100%;\n      }\n\n      #ddoc_main .ddoc_header_anchor {\n          font-size: 1.4em;\n          transition: transform 0.3s ease 0s;\n      }\n\n      #ddoc_main .ddoc_header_anchor > .code {\n          display: inline-block;\n\n      }\n\n      #ddoc_main .ddoc_decl {\n        background-color: transparent;\n        height: 100%;\n        left: 0;\n        top: 0;\n        padding: 0;\n        padding-left: 15px;\n      }\n\n      #ddoc_main .ddoc_decl .section, #ddoc_main .section.ddoc_sections {\n        background: white none repeat scroll 0 0;\n        margin: 0;\n        padding: 5px;\n        position: relative;\n        border-radius: 5px;\n      }\n\n      #ddoc_main .ddoc_decl .section h4, #ddoc_main .section.ddoc_sections h4 {\n        font-size: 13px;\n        line-height: 1.5;\n        margin-top: 21px;\n      }\n\n      #ddoc_main .section .declaration {\n          margin-top: 21px;\n      }\n\n      #ddoc_main .section .declaration .code {\n          color: rgba(0, 0, 0, 1);\n          margin-bottom: 15px;\n          padding-bottom: 6px;\n      }\n\n      #ddoc_main .declaration div .para {\n          margin-bottom: 0;\n      }\n\n      #ddoc_main .ddoc_params .graybox tr td:first-of-type {\n        padding: 7px;\n        text-align: right;\n        vertical-align: top;\n        word-break: normal;\n        white-space: nowrap;\n      }\n\n      #ddoc_main .ddoc_params .graybox {\n        border: 0 none;\n      }\n\n      #ddoc_main .ddoc_params .graybox td {\n        border-color: rgba(214, 214, 214, 1);\n      }\n\n      #ddoc_main .ddoc_params .graybox tr:first-child > td {\n        border-top: 0 none;\n      }\n\n      #ddoc_main .ddoc_params .graybox tr:last-child > td {\n        border-bottom: 0 none;\n      }\n\n      #ddoc_main .ddoc_params .graybox tr > td:first-child {\n        border-left: 0 none;\n      }\n\n      #ddoc_main .ddoc_params .graybox tr > td:last-child {\n        border-right: 0 none;\n        width: 100%;\n      }\n\n      #ddoc_main em.term, #ddoc_main em.term .code {\n        color: rgba(65, 65, 65, 1);\n        font-size: 12px;\n        font-style: italic;\n        line-height: 1.5;\n      }\n\n      #ddoc_main .see-also {\n        cursor: pointer;\n        font-family: Menlo,monospace;\n      }\n\n      #ddoc_main .ddoc_decl .section > div:last-of-type {\n        margin-bottom: 15px;\n      }\n\n      #ddoc_main .ddoc_member, #ddoc_main .ddoc_module_members {\n          transition: transform 0.3s ease 0s;\n      }\n\n      #ddoc_main .code_sample {\n        background: inherit;\n      }\n\n      #ddoc_main .declaration .code-line {\n          display: block;\n          font: 1em Menlo,monospace;\n      }\n\n      #ddoc_main a[name] {\n        margin: -112px 0 0;\n        padding-top: 112px;\n      }\n\n      #ddoc_main .ddoc_decl td {\n        max-width: inherit;\n      }\n\n      #ddoc_main .declaration a {\n        color: inherit;\n      }\n\n      #ddoc_main .declaration a:hover {\n          color: rgba(0, 136, 204, 1);\n          text-decoration: underline;\n      }\n\n      body.ddoc {\n        background-color: transparent;\n        color: rgba(0, 0, 0, 1);\n        font-family: Helvetica,Arial,sans-serif;\n        font-size: 62.5%;\n        margin: 0;\n        border: 0;\n        left: 0;\n        top: 0;\n        padding: 0;\n      }\n\n      .ddoc a[name] {\n        display: block;\n        height: 0;\n        margin: -85px 0 0;\n        padding-top: 85px;\n        width: 0;\n      }\n\n      .ddoc .module {\n          border-color: transparent;\n          background-color: rgba(255, 255, 255, 1);\n          border-color: currentColor rgba(233, 233, 233, 1) rgba(233, 233, 233, 1);\n          border-image: none;\n          border-style: none solid solid;\n          border-width: 0 1px 1px;\n          box-shadow: 0 0 1px rgba(0, 0, 0, 0.07);\n          display: block;\n          margin-left: 0;\n          min-height: calc(100% - 173px);\n          overflow: auto;\n          padding-bottom: 100px;\n      }\n\n      .ddoc .content_wrapper {\n          background-color: rgba(242, 242, 242, 1);\n          margin: 0 auto;\n          max-width: 980px;\n      }\n\n      .ddoc .section {\n        padding: 15px 25px 30px;\n      }\n\n      .ddoc .section .section {\n        margin: 30px 0 0;\n        padding: 0;\n      }\n\n      .ddoc .para {\n        color: rgba(65, 65, 65, 1);\n        font-size: 1.4em;\n        line-height: 145%;\n        margin-bottom: 15px;\n      }\n\n      .ddoc .ddoc_examples .para {\n        margin-bottom: 0;\n      }\n\n      .ddoc .module_name {\n          color: rgba(0, 0, 0, 1);\n          display: block;\n          font-family: Helvetica;\n          font-size: 2.8em;\n          font-weight: 100;\n          margin-bottom: 0;\n          padding: 15px 0;\n      }\n\n      .ddoc .module a {\n          color: rgba(0, 136, 204, 1);\n          text-decoration: none;\n      }\n\n      .ddoc .code {\n        color: rgba(128, 128, 128, 1);\n        font-family: Menlo,monospace;\n        font-size: 0.85em;\n        word-wrap: break-word;\n      }\n\n      .ddoc .code i {\n        font-style: normal;\n      }\n\n      .ddoc .code .code {\n        font-size: 1em;\n      }\n\n      .ddoc .code_sample {\n        background-clip: padding-box;\n        margin: 1px 0;\n        text-align: left;\n      }\n\n      .ddoc .code_sample {\n        display: block;\n        font-size: 1.4em;\n        margin-left: 21px;\n      }\n\n      .ddoc ol .code_sample {\n        font-size: 1em;\n      }\n\n      .ddoc .code_lines {\n        counter-reset: li;\n        line-height: 1.6em;\n        list-style: outside none none;\n        margin: 0;\n        padding: 0;\n      }\n\n      .ddoc .code_listing .code_sample div {\n        margin-left: 13px;\n        width: 93%;\n      }\n\n      .ddoc .code_listing .code_sample div .code_lines li {\n        list-style-type: none;\n        margin: 0;\n        padding-right: 10px;\n      }\n\n      .ddoc .code_sample div .code_lines li::before {\n        margin-left: -33px;\n        margin-right: 25px;\n      }\n\n      .ddoc .code_sample div .code_lines li:nth-child(n+10)::before {\n        margin-left: -39px;\n        margin-right: 25px;\n      }\n\n      .ddoc .code_sample div .code_lines li:nth-child(n+100)::before {\n        margin-left: -46px;\n        margin-right: 25px;\n      }\n\n      .ddoc .code_sample .code_lines .code {\n        color: #000;\n      }\n\n      .ddoc div.dlang {\n        margin: 10px 0 21px;\n        padding: 4px 0 2px 10px;\n      }\n\n      .ddoc div.dlang {\n          margin: 10px 0 21px;\n          padding: 4px 0 2px 10px;\n      }\n\n      .ddoc div.dlang {\n        border-left: 5px solid rgba(0, 155, 51, 0.2);\n      }\n\n      .ddoc .code_lines li::before {\n        color: rgba(128, 128, 128, 1);\n        content: counter(li, decimal);\n        counter-increment: li;\n        font-family: Menlo,monospace;\n        font-size: 0.9em;\n        margin-right: 16px;\n      }\n\n      .ddoc .code_lines li {\n        padding-left: 0;\n        white-space: pre-wrap;\n      }\n\n      .ddoc .code_lines li:only-of-type::before {\n        color: rgba(255, 255, 255, 1);\n        content: \" \";\n      }\n\n      .ddoc .code_lines li:only-of-type {\n        color: rgba(255, 255, 255, 1);\n        content: \" \";\n      }\n\n      .ddoc .code_lines li:nth-child(n+10) {\n        text-indent: -17px;\n      }\n\n      .ddoc .code_lines li:nth-child(n+10)::before {\n        margin-right: 12px;\n      }\n\n      .ddoc .graybox {\n        border: 1px solid rgba(233, 233, 233, 1);\n        border-collapse: collapse;\n        border-spacing: 0;\n        empty-cells: hide;\n        margin: 20px 0 36px;\n        text-align: left;\n      }\n\n      .ddoc .graybox p {\n        margin: 0;\n        min-width: 50px;\n      }\n\n      .ddoc td {\n        border: 1px solid rgba(233, 233, 233, 1);\n        margin: 0;\n        max-width: 260px;\n        padding: 5px 25px 5px 10px;\n        vertical-align: middle;\n      }\n\n      .punctuation {\n        color: rgba(0, 0, 0, 1);\n      }\n\n      .comment {\n        color: rgba(0, 131, 18, 1);\n      }\n\n      .operator {\n        color: #000;\n      }\n\n      .keyword {\n        color: rgba(170, 13, 145, 1);\n      }\n\n      .keyword_type {\n        color: rgba(170, 51, 145, 1);\n      }\n\n      .string_literal {\n        color: rgba(196, 26, 22, 1);\n      }\n\n      .ddoc_psuper_symbol {\n        color: rgba(92, 38, 153, 1);\n      }\n\n      .param {\n        color: rgba(0, 0, 0, 1);\n      }\n\n      .psymbol {\n        color: rgba(0, 0, 0, 1);\n      }\n\n      .ddoc_member_header .ddoc_header_anchor .code {\n        font-size: 1em;\n      }\n    </style>\n  </head>\n  <body id=\"ddoc_main\" class=\"ddoc dlang\">\n    <div class=\"content_wrapper\">\n      <article class=\"module\">\n        <h1 class=\"module_name\">$(TITLE)</h1>\n        <section id=\"module_content\">$(BODY)</section>\n      </article>\n    </div>\n  </body>\n</html>$(LF)\n\nDDOC_MODULE_MEMBERS = <section class=\"section ddoc_module_members_section\">\n  <div class=\"ddoc_module_members\">\n    $(DDOC_MEMBERS $0)\n  </div>\n</section>$(LF)\n\nDDOC_CLASS_MEMBERS = $(DDOC_MEMBERS $0)$(LF)\nDDOC_STRUCT_MEMBERS = $(DDOC_MEMBERS $0)$(LF)\nDDOC_ENUM_MEMBERS = $(DDOC_MEMBERS $0)$(LF)\nDDOC_TEMPLATE_MEMBERS = $(DDOC_MEMBERS $0)$(LF)\n\nDDOC_MEMBERS = <ul class=\"ddoc_members\">\n  $0\n</ul>\n\nDDOC_MEMBER = <li class=\"ddoc_member\">\n  $0\n</li>\n\nDDOC_MEMBER_HEADER = <div class=\"ddoc_member_header\">\n  $0\n</div>\n\nDDOC_HEADER_ANCHOR = <div class=\"ddoc_header_anchor\">\n  <a href=\"#$1\" id=\"$1\"><code class=\"code\">$2</code></a>\n</div>\n\nDDOC_DECL = <div class=\"ddoc_decl\">\n  <section class=\"section\">\n    <div class=\"declaration\">\n      <h4>Declaration</h4>\n      <div class=\"dlang\">\n        <p class=\"para\">\n          <code class=\"code\">\n            $0\n          </code>\n        </p>\n      </div>\n    </div>\n  </section>\n</div>\n\nDDOC_ANCHOR = <span class=\"ddoc_anchor\" id=\"$1\"></span>\n\nDDOC_DECL_DD = <div class=\"ddoc_decl\">\n  $0\n</div>\n\nDDOC_SECTIONS = <section class=\"section ddoc_sections\">\n  $0\n</section>$(LF)\n\nDDOC_SUMMARY = <div class=\"ddoc_summary\">\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_DESCRIPTION = <div class=\"ddoc_description\">\n  <h4>Discussion</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_EXAMPLES = <div class=\"ddoc_examples\">\n  <h4>Examples</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>\n\nDDOC_RETURNS = <div class=\"ddoc_returns\">\n  <h4>Return Value</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_PARAMS = <div class=\"ddoc_params\">\n  <h4>Parameters</h4>\n  <table cellspacing=\"0\" cellpadding=\"5\" border=\"0\" class=\"graybox\">\n    <tbody>\n      $0\n    </tbody>\n  </table>\n</div>$(LF)\n\nDDOC_PARAM_ROW = <tr class=\"ddoc_param_row\">\n  $0\n</tr>$(LF)\n\nDDOC_PARAM_ID = <td scope=\"ddoc_param_id\">\n  <code class=\"code\">\n    <em class=\"term\">$0</em>\n  </code>\n</td>$(LF)\n\nDDOC_PARAM_DESC = <td>\n  <div class=\"ddoc_param_desc\">\n    <p class=\"para\">\n      $0\n    </p>\n  </div>\n</td>\n\nDDOC_LICENSE = <div class=\"ddoc_license\">\n  <h4>License</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_AUTHORS = <div class=\"ddoc_authors\">\n  <h4>Authors</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_BUGS = <div class=\"ddoc_bugs\">\n  <h4>Bugs</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_COPYRIGHT = <div class=\"ddoc_copyright\">\n  <h4>Copyright</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_DATE = <div class=\"ddoc_date\">\n  <h4>Date</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_DEPRECATED = <div class=\"ddoc_deprecated\">\n  <h4>Deprecated</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_HISTORY = <div class=\"ddoc_history\">\n  <h4>History</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_SEE_ALSO = <div class=\"ddoc_see_also\">\n  <h4>See Also</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_STANDARDS = <div class=\"ddoc_standards\">\n  <h4>Standards</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>\n\nDDOC_THROWS = <div class=\"ddoc_throws\">\n  <h4>Throws</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>\n\nDDOC_VERSION = <div class=\"ddoc_version\">\n  <h4>Version</h4>\n  <p class=\"para\">\n    $0\n  </p>\n</div>\n\nDDOC_SECTION = <div class=\"ddoc_section\">\n  <p class=\"para\">\n    $0\n  </p>\n</div>$(LF)\n\nDDOC_SECTION_H = <span class=\"ddoc_section_h\">$0:</span>$(LF)\n\nDDOC_DITTO = <br>\n$0\n\nDDOC_PSYMBOL = <code class=\"code\">$0</code>\nDDOC_ENUM_BASETYPE = $0\nDDOC_PSUPER_SYMBOL = <span class=\"ddoc_psuper_symbol\">$0</span>\nDDOC_KEYWORD = <code class=\"code\">$0</code>\nDDOC_PARAM = <code class=\"code\">$0</code>\nDDOC_CONSTRAINT = $(DDOC_CONSTRAINT) if ($0)\nDDOC_OVERLOAD_SEPARATOR = $0\nDDOC_TEMPLATE_PARAM_LIST = $0\nDDOC_TEMPLATE_PARAM = $0\nDDOC_LINK_AUTODETECT = $(LINK $0)\nDDOC_AUTO_PSYMBOL = $(DDOC_PSYMBOL $0)\nDDOC_AUTO_KEYWORD = $(DDOC_KEYWORD $0)\nDDOC_AUTO_PARAM = $(DDOC_PARAM $0)\nDDOC_AUTO_PSYMBOL_SUPPRESS = $0\n"
  },
  {
    "path": "gcc/d/dmd/declaration.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/declaration.d, _declaration.d)\n * Documentation:  https://dlang.org/phobos/dmd_declaration.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/declaration.d\n */\n\nmodule dmd.declaration;\n\nimport core.stdc.stdio;\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.ctorflow;\nimport dmd.dclass;\nimport dmd.delegatize;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.initsem;\nimport dmd.intrange;\nimport dmd.mtype;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.visitor;\n\n/************************************\n * Check to see the aggregate type is nested and its context pointer is\n * accessible from the current scope.\n * Returns true if error occurs.\n */\nbool checkFrameAccess(Loc loc, Scope* sc, AggregateDeclaration ad, size_t iStart = 0)\n{\n    Dsymbol sparent = ad.toParent2();\n    Dsymbol s = sc.func;\n    if (ad.isNested() && s)\n    {\n        //printf(\"ad = %p %s [%s], parent:%p\\n\", ad, ad.toChars(), ad.loc.toChars(), ad.parent);\n        //printf(\"sparent = %p %s [%s], parent: %s\\n\", sparent, sparent.toChars(), sparent.loc.toChars(), sparent.parent,toChars());\n        if (!ensureStaticLinkTo(s, sparent))\n        {\n            error(loc, \"cannot access frame pointer of `%s`\", ad.toPrettyChars());\n            return true;\n        }\n    }\n\n    bool result = false;\n    for (size_t i = iStart; i < ad.fields.dim; i++)\n    {\n        VarDeclaration vd = ad.fields[i];\n        Type tb = vd.type.baseElemOf();\n        if (tb.ty == Tstruct)\n        {\n            result |= checkFrameAccess(loc, sc, (cast(TypeStruct)tb).sym);\n        }\n    }\n    return result;\n}\n\n/***********************************************\n * Mark variable v as modified if it is inside a constructor that var\n * is a field in.\n */\nbool modifyFieldVar(Loc loc, Scope* sc, VarDeclaration var, Expression e1)\n{\n    //printf(\"modifyFieldVar(var = %s)\\n\", var.toChars());\n    Dsymbol s = sc.func;\n    while (1)\n    {\n        FuncDeclaration fd = null;\n        if (s)\n            fd = s.isFuncDeclaration();\n        if (fd &&\n            ((fd.isCtorDeclaration() && var.isField()) ||\n             (fd.isStaticCtorDeclaration() && !var.isField())) &&\n            fd.toParent2() == var.toParent2() &&\n            (!e1 || e1.op == TOK.this_))\n        {\n            bool result = true;\n\n            var.ctorinit = true;\n            //printf(\"setting ctorinit\\n\");\n\n            if (var.isField() && sc.ctorflow.fieldinit.length && !sc.intypeof)\n            {\n                assert(e1);\n                auto mustInit = ((var.storage_class & STC.nodefaultctor) != 0 ||\n                                 var.type.needsNested());\n\n                const dim = sc.ctorflow.fieldinit.length;\n                auto ad = fd.isMember2();\n                assert(ad);\n                size_t i;\n                for (i = 0; i < dim; i++) // same as findFieldIndexByName in ctfeexp.c ?\n                {\n                    if (ad.fields[i] == var)\n                        break;\n                }\n                assert(i < dim);\n                auto fieldInit = &sc.ctorflow.fieldinit[i];\n                const fi = fieldInit.csx;\n\n                if (fi & CSX.this_ctor)\n                {\n                    if (var.type.isMutable() && e1.type.isMutable())\n                        result = false;\n                    else\n                    {\n                        const(char)* modStr = !var.type.isMutable() ? MODtoChars(var.type.mod) : MODtoChars(e1.type.mod);\n                        // Deprecated in 2018-04.\n                        // Change to error in 2019-04 by deleting the following\n                        // if-branch and the deprecate_18719 enum member in the\n                        // dmd.ctorflow.CSX enum.\n                        // @@@DEPRECATED_2019-01@@@.\n                        if (fi & CSX.deprecate_18719)\n                        {\n                            .deprecation(loc, \"%s field `%s` was initialized in a previous constructor call\", modStr, var.toChars());\n                        }\n                        else\n                        {\n                            .error(loc, \"%s field `%s` initialized multiple times\", modStr, var.toChars());\n                            .errorSupplemental(fieldInit.loc, \"Previous initialization is here.\");\n                        }\n                    }\n                }\n                else if (sc.inLoop || (fi & CSX.label))\n                {\n                    if (!mustInit && var.type.isMutable() && e1.type.isMutable())\n                        result = false;\n                    else\n                    {\n                        const(char)* modStr = !var.type.isMutable() ? MODtoChars(var.type.mod) : MODtoChars(e1.type.mod);\n                        .error(loc, \"%s field `%s` initialization is not allowed in loops or after labels\", modStr, var.toChars());\n                    }\n                }\n\n                fieldInit.csx |= CSX.this_ctor;\n                fieldInit.loc = e1.loc;\n                if (var.overlapped) // https://issues.dlang.org/show_bug.cgi?id=15258\n                {\n                    foreach (j, v; ad.fields)\n                    {\n                        if (v is var || !var.isOverlappedWith(v))\n                            continue;\n                        v.ctorinit = true;\n                        sc.ctorflow.fieldinit[j].csx = CSX.this_ctor;\n                    }\n                }\n            }\n            else if (fd != sc.func)\n            {\n                if (var.type.isMutable())\n                    result = false;\n                else if (sc.func.fes)\n                {\n                    const(char)* p = var.isField() ? \"field\" : var.kind();\n                    .error(loc, \"%s %s `%s` initialization is not allowed in foreach loop\",\n                        MODtoChars(var.type.mod), p, var.toChars());\n                }\n                else\n                {\n                    const(char)* p = var.isField() ? \"field\" : var.kind();\n                    .error(loc, \"%s %s `%s` initialization is not allowed in nested function `%s`\",\n                        MODtoChars(var.type.mod), p, var.toChars(), sc.func.toChars());\n                }\n            }\n            return result;\n        }\n        else\n        {\n            if (s)\n            {\n                s = s.toParent2();\n                continue;\n            }\n        }\n        break;\n    }\n    return false;\n}\n\n/******************************************\n */\nextern (C++) void ObjectNotFound(Identifier id)\n{\n    error(Loc.initial, \"`%s` not found. object.d may be incorrectly installed or corrupt.\", id.toChars());\n    fatal();\n}\n\nenum STC : long\n{\n    undefined_          = 0L,\n    static_             = (1L << 0),\n    extern_             = (1L << 1),\n    const_              = (1L << 2),\n    final_              = (1L << 3),\n    abstract_           = (1L << 4),\n    parameter           = (1L << 5),\n    field               = (1L << 6),\n    override_           = (1L << 7),\n    auto_               = (1L << 8),\n    synchronized_       = (1L << 9),\n    deprecated_         = (1L << 10),\n    in_                 = (1L << 11),   // in parameter\n    out_                = (1L << 12),   // out parameter\n    lazy_               = (1L << 13),   // lazy parameter\n    foreach_            = (1L << 14),   // variable for foreach loop\n                          //(1L << 15)\n    variadic            = (1L << 16),   // the 'variadic' parameter in: T foo(T a, U b, V variadic...)\n    ctorinit            = (1L << 17),   // can only be set inside constructor\n    templateparameter   = (1L << 18),   // template parameter\n    scope_              = (1L << 19),\n    immutable_          = (1L << 20),\n    ref_                = (1L << 21),\n    init                = (1L << 22),   // has explicit initializer\n    manifest            = (1L << 23),   // manifest constant\n    nodtor              = (1L << 24),   // don't run destructor\n    nothrow_            = (1L << 25),   // never throws exceptions\n    pure_               = (1L << 26),   // pure function\n    tls                 = (1L << 27),   // thread local\n    alias_              = (1L << 28),   // alias parameter\n    shared_             = (1L << 29),   // accessible from multiple threads\n    gshared             = (1L << 30),   // accessible from multiple threads, but not typed as \"shared\"\n    wild                = (1L << 31),   // for \"wild\" type constructor\n    property            = (1L << 32),\n    safe                = (1L << 33),\n    trusted             = (1L << 34),\n    system              = (1L << 35),\n    ctfe                = (1L << 36),   // can be used in CTFE, even if it is static\n    disable             = (1L << 37),   // for functions that are not callable\n    result              = (1L << 38),   // for result variables passed to out contracts\n    nodefaultctor       = (1L << 39),   // must be set inside constructor\n    temp                = (1L << 40),   // temporary variable\n    rvalue              = (1L << 41),   // force rvalue for variables\n    nogc                = (1L << 42),   // @nogc\n    volatile_           = (1L << 43),   // destined for volatile in the back end\n    return_             = (1L << 44),   // 'return ref' or 'return scope' for function parameters\n    autoref             = (1L << 45),   // Mark for the already deduced 'auto ref' parameter\n    inference           = (1L << 46),   // do attribute inference\n    exptemp             = (1L << 47),   // temporary variable that has lifetime restricted to an expression\n    maybescope          = (1L << 48),   // parameter might be 'scope'\n    scopeinferred       = (1L << 49),   // 'scope' has been inferred and should not be part of mangling\n    future              = (1L << 50),   // introducing new base class function\n    local               = (1L << 51),   // do not forward (see dmd.dsymbol.ForwardingScopeDsymbol).\n\n    TYPECTOR = (STC.const_ | STC.immutable_ | STC.shared_ | STC.wild),\n    FUNCATTR = (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.property | STC.safe | STC.trusted | STC.system),\n}\n\nenum STCStorageClass =\n    (STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | STC.const_ | STC.final_ | STC.abstract_ | STC.synchronized_ |\n     STC.deprecated_ | STC.future | STC.override_ | STC.lazy_ | STC.alias_ | STC.out_ | STC.in_ | STC.manifest |\n     STC.immutable_ | STC.shared_ | STC.wild | STC.nothrow_ | STC.nogc | STC.pure_ | STC.ref_ | STC.return_ | STC.tls | STC.gshared |\n     STC.property | STC.safe | STC.trusted | STC.system | STC.disable | STC.local);\n\nstruct Match\n{\n    int count;              // number of matches found\n    MATCH last;             // match level of lastf\n    FuncDeclaration lastf;  // last matching function we found\n    FuncDeclaration nextf;  // current matching function\n    FuncDeclaration anyf;   // pick a func, any func, to use for error recovery\n}\n\n/***********************************************************\n */\nextern (C++) abstract class Declaration : Dsymbol\n{\n    Type type;\n    Type originalType;  // before semantic analysis\n    StorageClass storage_class;\n    Prot protection;\n    LINK linkage;\n    int inuse;          // used to detect cycles\n\n    // overridden symbol with pragma(mangle, \"...\")\n    const(char)[] mangleOverride;\n\n    final extern (D) this(Identifier id)\n    {\n        super(id);\n        storage_class = STC.undefined_;\n        protection = Prot(Prot.Kind.undefined);\n        linkage = LINK.default_;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"declaration\";\n    }\n\n    override final d_uns64 size(const ref Loc loc)\n    {\n        assert(type);\n        return type.size();\n    }\n\n    /**\n     * Issue an error if an attempt to call a disabled method is made\n     *\n     * If the declaration is disabled but inside a disabled function,\n     * returns `true` but do not issue an error message.\n     *\n     * Params:\n     *   loc = Location information of the call\n     *   sc  = Scope in which the call occurs\n     *   isAliasedDeclaration = if `true` searches overload set\n     *\n     * Returns:\n     *   `true` if this `Declaration` is `@disable`d, `false` otherwise.\n     */\n    extern (D) final bool checkDisabled(Loc loc, Scope* sc, bool isAliasedDeclaration = false)\n    {\n        if (storage_class & STC.disable)\n        {\n            if (!(sc.func && sc.func.storage_class & STC.disable))\n            {\n                auto p = toParent();\n                if (p && isPostBlitDeclaration())\n                    p.error(loc, \"is not copyable because it is annotated with `@disable`\");\n                else\n                {\n                    // if the function is @disabled, maybe there\n                    // is an overload in the overload set that isn't\n                    if (isAliasedDeclaration)\n                    {\n                        FuncDeclaration fd = isFuncDeclaration();\n                        if (fd)\n                        {\n                            for (FuncDeclaration ovl = fd; ovl; ovl = cast(FuncDeclaration)ovl.overnext)\n                                if (!(ovl.storage_class & STC.disable))\n                                    return false;\n                        }\n                    }\n                    error(loc, \"cannot be used because it is annotated with `@disable`\");\n                }\n            }\n            return true;\n        }\n\n        return false;\n    }\n\n    /*************************************\n     * Check to see if declaration can be modified in this context (sc).\n     * Issue error if not.\n     */\n    extern (D) final int checkModify(Loc loc, Scope* sc, Expression e1, int flag)\n    {\n        VarDeclaration v = isVarDeclaration();\n        if (v && v.canassign)\n            return 2;\n\n        if (isParameter() || isResult())\n        {\n            for (Scope* scx = sc; scx; scx = scx.enclosing)\n            {\n                if (scx.func == parent && (scx.flags & SCOPE.contract))\n                {\n                    const(char)* s = isParameter() && parent.ident != Id.ensure ? \"parameter\" : \"result\";\n                    if (!flag)\n                        error(loc, \"cannot modify %s `%s` in contract\", s, toChars());\n                    return 2; // do not report type related errors\n                }\n            }\n        }\n\n        if (e1 && e1.op == TOK.this_ && isField())\n        {\n            VarDeclaration vthis = (cast(ThisExp)e1).var;\n            for (Scope* scx = sc; scx; scx = scx.enclosing)\n            {\n                if (scx.func == vthis.parent && (scx.flags & SCOPE.contract))\n                {\n                    if (!flag)\n                        error(loc, \"cannot modify parameter 'this' in contract\");\n                    return 2; // do not report type related errors\n                }\n            }\n        }\n\n        if (v && (isCtorinit() || isField()))\n        {\n            // It's only modifiable if inside the right constructor\n            if ((storage_class & (STC.foreach_ | STC.ref_)) == (STC.foreach_ | STC.ref_))\n                return 2;\n            return modifyFieldVar(loc, sc, v, e1) ? 2 : 1;\n        }\n        return 1;\n    }\n\n    override final Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)\n    {\n        Dsymbol s = Dsymbol.search(loc, ident, flags);\n        if (!s && type)\n        {\n            s = type.toDsymbol(_scope);\n            if (s)\n                s = s.search(loc, ident, flags);\n        }\n        return s;\n    }\n\n    final bool isStatic() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.static_) != 0;\n    }\n\n    bool isDelete()\n    {\n        return false;\n    }\n\n    bool isDataseg()\n    {\n        return false;\n    }\n\n    bool isThreadlocal()\n    {\n        return false;\n    }\n\n    bool isCodeseg() const pure nothrow @nogc @safe\n    {\n        return false;\n    }\n\n    final bool isCtorinit() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.ctorinit) != 0;\n    }\n\n    final bool isFinal() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.final_) != 0;\n    }\n\n    bool isAbstract()\n    {\n        return (storage_class & STC.abstract_) != 0;\n    }\n\n    final bool isConst() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.const_) != 0;\n    }\n\n    final bool isImmutable() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.immutable_) != 0;\n    }\n\n    final bool isWild() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.wild) != 0;\n    }\n\n    final bool isAuto() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.auto_) != 0;\n    }\n\n    final bool isScope() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.scope_) != 0;\n    }\n\n    final bool isSynchronized() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.synchronized_) != 0;\n    }\n\n    final bool isParameter() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.parameter) != 0;\n    }\n\n    override final bool isDeprecated() pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.deprecated_) != 0;\n    }\n\n    final bool isDisabled() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.disable) != 0;\n    }\n\n    final bool isOverride() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.override_) != 0;\n    }\n\n    final bool isResult() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.result) != 0;\n    }\n\n    final bool isField() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.field) != 0;\n    }\n\n    final bool isIn() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.in_) != 0;\n    }\n\n    final bool isOut() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.out_) != 0;\n    }\n\n    final bool isRef() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.ref_) != 0;\n    }\n\n    final bool isFuture() const pure nothrow @nogc @safe\n    {\n        return (storage_class & STC.future) != 0;\n    }\n\n    override final Prot prot() pure nothrow @nogc @safe\n    {\n        return protection;\n    }\n\n    override final inout(Declaration) isDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TupleDeclaration : Declaration\n{\n    Objects* objects;\n    bool isexp;             // true: expression tuple\n    TypeTuple tupletype;    // !=null if this is a type tuple\n\n    extern (D) this(const ref Loc loc, Identifier id, Objects* objects)\n    {\n        super(id);\n        this.loc = loc;\n        this.objects = objects;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(0);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"tuple\";\n    }\n\n    override Type getType()\n    {\n        /* If this tuple represents a type, return that type\n         */\n\n        //printf(\"TupleDeclaration::getType() %s\\n\", toChars());\n        if (isexp)\n            return null;\n        if (!tupletype)\n        {\n            /* It's only a type tuple if all the Object's are types\n             */\n            for (size_t i = 0; i < objects.dim; i++)\n            {\n                RootObject o = (*objects)[i];\n                if (o.dyncast() != DYNCAST.type)\n                {\n                    //printf(\"\\tnot[%d], %p, %d\\n\", i, o, o.dyncast());\n                    return null;\n                }\n            }\n\n            /* We know it's a type tuple, so build the TypeTuple\n             */\n            Types* types = cast(Types*)objects;\n            auto args = new Parameters(objects.dim);\n            OutBuffer buf;\n            int hasdeco = 1;\n            for (size_t i = 0; i < types.dim; i++)\n            {\n                Type t = (*types)[i];\n                //printf(\"type = %s\\n\", t.toChars());\n                version (none)\n                {\n                    buf.printf(\"_%s_%d\", ident.toChars(), i);\n                    const len = buf.offset;\n                    const name = cast(const(char)*)buf.extractData();\n                    auto id = Identifier.idPool(name, len);\n                    auto arg = new Parameter(STC.in_, t, id, null);\n                }\n                else\n                {\n                    auto arg = new Parameter(0, t, null, null, null);\n                }\n                (*args)[i] = arg;\n                if (!t.deco)\n                    hasdeco = 0;\n            }\n\n            tupletype = new TypeTuple(args);\n            if (hasdeco)\n                return tupletype.typeSemantic(Loc.initial, null);\n        }\n        return tupletype;\n    }\n\n    override Dsymbol toAlias2()\n    {\n        //printf(\"TupleDeclaration::toAlias2() '%s' objects = %s\\n\", toChars(), objects.toChars());\n        for (size_t i = 0; i < objects.dim; i++)\n        {\n            RootObject o = (*objects)[i];\n            if (Dsymbol s = isDsymbol(o))\n            {\n                s = s.toAlias2();\n                (*objects)[i] = s;\n            }\n        }\n        return this;\n    }\n\n    override bool needThis()\n    {\n        //printf(\"TupleDeclaration::needThis(%s)\\n\", toChars());\n        for (size_t i = 0; i < objects.dim; i++)\n        {\n            RootObject o = (*objects)[i];\n            if (o.dyncast() == DYNCAST.expression)\n            {\n                Expression e = cast(Expression)o;\n                if (e.op == TOK.dSymbol)\n                {\n                    DsymbolExp ve = cast(DsymbolExp)e;\n                    Declaration d = ve.s.isDeclaration();\n                    if (d && d.needThis())\n                    {\n                        return true;\n                    }\n                }\n            }\n        }\n        return false;\n    }\n\n    override inout(TupleDeclaration) isTupleDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class AliasDeclaration : Declaration\n{\n    Dsymbol aliassym;\n    Dsymbol overnext;   // next in overload list\n    Dsymbol _import;    // !=null if unresolved internal alias for selective import\n\n    extern (D) this(const ref Loc loc, Identifier id, Type type)\n    {\n        super(id);\n        //printf(\"AliasDeclaration(id = '%s', type = %p)\\n\", id.toChars(), type);\n        //printf(\"type = '%s'\\n\", type.toChars());\n        this.loc = loc;\n        this.type = type;\n        assert(type);\n    }\n\n    extern (D) this(const ref Loc loc, Identifier id, Dsymbol s)\n    {\n        super(id);\n        //printf(\"AliasDeclaration(id = '%s', s = %p)\\n\", id.toChars(), s);\n        assert(s != this);\n        this.loc = loc;\n        this.aliassym = s;\n        assert(s);\n    }\n\n    static AliasDeclaration create(Loc loc, Identifier id, Type type)\n    {\n        return new AliasDeclaration(loc, id, type);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        //printf(\"AliasDeclaration::syntaxCopy()\\n\");\n        assert(!s);\n        AliasDeclaration sa = type ? new AliasDeclaration(loc, ident, type.syntaxCopy()) : new AliasDeclaration(loc, ident, aliassym.syntaxCopy(null));\n        sa.storage_class = storage_class;\n        return sa;\n    }\n\n    override bool overloadInsert(Dsymbol s)\n    {\n        //printf(\"[%s] AliasDeclaration::overloadInsert('%s') s = %s %s @ [%s]\\n\",\n        //       loc.toChars(), toChars(), s.kind(), s.toChars(), s.loc.toChars());\n\n        /** Aliases aren't overloadable themselves, but if their Aliasee is\n         *  overloadable they are converted to an overloadable Alias (either\n         *  FuncAliasDeclaration or OverDeclaration).\n         *\n         *  This is done by moving the Aliasee into such an overloadable alias\n         *  which is then used to replace the existing Aliasee. The original\n         *  Alias (_this_) remains a useless shell.\n         *\n         *  This is a horrible mess. It was probably done to avoid replacing\n         *  existing AST nodes and references, but it needs a major\n         *  simplification b/c it's too complex to maintain.\n         *\n         *  A simpler approach might be to merge any colliding symbols into a\n         *  simple Overload class (an array) and then later have that resolve\n         *  all collisions.\n         */\n        if (semanticRun >= PASS.semanticdone)\n        {\n            /* Semantic analysis is already finished, and the aliased entity\n             * is not overloadable.\n             */\n            if (type)\n                return false;\n\n            /* When s is added in member scope by static if, mixin(\"code\") or others,\n             * aliassym is determined already. See the case in: test/compilable/test61.d\n             */\n            auto sa = aliassym.toAlias();\n            if (auto fd = sa.isFuncDeclaration())\n            {\n                auto fa = new FuncAliasDeclaration(ident, fd);\n                fa.protection = protection;\n                fa.parent = parent;\n                aliassym = fa;\n                return aliassym.overloadInsert(s);\n            }\n            if (auto td = sa.isTemplateDeclaration())\n            {\n                auto od = new OverDeclaration(ident, td);\n                od.protection = protection;\n                od.parent = parent;\n                aliassym = od;\n                return aliassym.overloadInsert(s);\n            }\n            if (auto od = sa.isOverDeclaration())\n            {\n                if (sa.ident != ident || sa.parent != parent)\n                {\n                    od = new OverDeclaration(ident, od);\n                    od.protection = protection;\n                    od.parent = parent;\n                    aliassym = od;\n                }\n                return od.overloadInsert(s);\n            }\n            if (auto os = sa.isOverloadSet())\n            {\n                if (sa.ident != ident || sa.parent != parent)\n                {\n                    os = new OverloadSet(ident, os);\n                    // TODO: protection is lost here b/c OverloadSets have no protection attribute\n                    // Might no be a practical issue, b/c the code below fails to resolve the overload anyhow.\n                    // ----\n                    // module os1;\n                    // import a, b;\n                    // private alias merged = foo; // private alias to overload set of a.foo and b.foo\n                    // ----\n                    // module os2;\n                    // import a, b;\n                    // public alias merged = bar; // public alias to overload set of a.bar and b.bar\n                    // ----\n                    // module bug;\n                    // import os1, os2;\n                    // void test() { merged(123); } // should only look at os2.merged\n                    //\n                    // os.protection = protection;\n                    os.parent = parent;\n                    aliassym = os;\n                }\n                os.push(s);\n                return true;\n            }\n            return false;\n        }\n\n        /* Don't know yet what the aliased symbol is, so assume it can\n         * be overloaded and check later for correctness.\n         */\n        if (overnext)\n            return overnext.overloadInsert(s);\n        if (s is this)\n            return true;\n        overnext = s;\n        return true;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"alias\";\n    }\n\n    override Type getType()\n    {\n        if (type)\n            return type;\n        return toAlias().getType();\n    }\n\n    override Dsymbol toAlias()\n    {\n        //printf(\"[%s] AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s', inuse = %d)\\n\",\n        //    loc.toChars(), toChars(), this, aliassym, aliassym ? aliassym.kind() : \"\", inuse);\n        assert(this != aliassym);\n        //static int count; if (++count == 10) *(char*)0=0;\n        if (inuse == 1 && type && _scope)\n        {\n            inuse = 2;\n            uint olderrors = global.errors;\n            Dsymbol s = type.toDsymbol(_scope);\n            //printf(\"[%s] type = %s, s = %p, this = %p\\n\", loc.toChars(), type.toChars(), s, this);\n            if (global.errors != olderrors)\n                goto Lerr;\n            if (s)\n            {\n                s = s.toAlias();\n                if (global.errors != olderrors)\n                    goto Lerr;\n                aliassym = s;\n                inuse = 0;\n            }\n            else\n            {\n                Type t = type.typeSemantic(loc, _scope);\n                if (t.ty == Terror)\n                    goto Lerr;\n                if (global.errors != olderrors)\n                    goto Lerr;\n                //printf(\"t = %s\\n\", t.toChars());\n                inuse = 0;\n            }\n        }\n        if (inuse)\n        {\n            error(\"recursive alias declaration\");\n\n        Lerr:\n            // Avoid breaking \"recursive alias\" state during errors gagged\n            if (global.gag)\n                return this;\n            aliassym = new AliasDeclaration(loc, ident, Type.terror);\n            type = Type.terror;\n            return aliassym;\n        }\n\n        if (semanticRun >= PASS.semanticdone)\n        {\n            // semantic is already done.\n\n            // Do not see aliassym !is null, because of lambda aliases.\n\n            // Do not see type.deco !is null, even so \"alias T = const int;` needs\n            // semantic analysis to take the storage class `const` as type qualifier.\n        }\n        else\n        {\n            if (_import && _import._scope)\n            {\n                /* If this is an internal alias for selective/renamed import,\n                 * load the module first.\n                 */\n                _import.dsymbolSemantic(null);\n            }\n            if (_scope)\n            {\n                aliasSemantic(this, _scope);\n            }\n        }\n\n        inuse = 1;\n        Dsymbol s = aliassym ? aliassym.toAlias() : this;\n        inuse = 0;\n        return s;\n    }\n\n    override Dsymbol toAlias2()\n    {\n        if (inuse)\n        {\n            error(\"recursive alias declaration\");\n            return this;\n        }\n        inuse = 1;\n        Dsymbol s = aliassym ? aliassym.toAlias2() : this;\n        inuse = 0;\n        return s;\n    }\n\n    override bool isOverloadable()\n    {\n        // assume overloadable until alias is resolved\n        return semanticRun < PASS.semanticdone ||\n            aliassym && aliassym.isOverloadable();\n    }\n\n    override inout(AliasDeclaration) isAliasDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class OverDeclaration : Declaration\n{\n    Dsymbol overnext;   // next in overload list\n    Dsymbol aliassym;\n    bool hasOverloads;\n\n    extern (D) this(Identifier ident, Dsymbol s, bool hasOverloads = true)\n    {\n        super(ident);\n        this.aliassym = s;\n        this.hasOverloads = hasOverloads;\n        if (hasOverloads)\n        {\n            if (OverDeclaration od = aliassym.isOverDeclaration())\n                this.hasOverloads = od.hasOverloads;\n        }\n        else\n        {\n            // for internal use\n            assert(!aliassym.isOverDeclaration());\n        }\n    }\n\n    override const(char)* kind() const\n    {\n        return \"overload alias\"; // todo\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n\n        Dsymbol s = isDsymbol(o);\n        if (!s)\n            return false;\n\n        OverDeclaration od1 = this;\n        if (OverDeclaration od2 = s.isOverDeclaration())\n        {\n            return od1.aliassym.equals(od2.aliassym) && od1.hasOverloads == od2.hasOverloads;\n        }\n        if (aliassym == s)\n        {\n            if (hasOverloads)\n                return true;\n            if (FuncDeclaration fd = s.isFuncDeclaration())\n            {\n                return fd.isUnique() !is null;\n            }\n            if (TemplateDeclaration td = s.isTemplateDeclaration())\n            {\n                return td.overnext is null;\n            }\n        }\n        return false;\n    }\n\n    override bool overloadInsert(Dsymbol s)\n    {\n        //printf(\"OverDeclaration::overloadInsert('%s') aliassym = %p, overnext = %p\\n\", s.toChars(), aliassym, overnext);\n        if (overnext)\n            return overnext.overloadInsert(s);\n        if (s == this)\n            return true;\n        overnext = s;\n        return true;\n    }\n\n    override bool isOverloadable()\n    {\n        return true;\n    }\n\n    Dsymbol isUnique()\n    {\n        if (!hasOverloads)\n        {\n            if (aliassym.isFuncDeclaration() ||\n                aliassym.isTemplateDeclaration())\n            {\n                return aliassym;\n            }\n        }\n\n        Dsymbol result = null;\n        overloadApply(aliassym, (Dsymbol s)\n        {\n            if (result)\n            {\n                result = null;\n                return 1; // ambiguous, done\n            }\n            else\n            {\n                result = s;\n                return 0;\n            }\n        });\n        return result;\n    }\n\n    override inout(OverDeclaration) isOverDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class VarDeclaration : Declaration\n{\n    Initializer _init;\n    uint offset;\n    uint sequenceNumber;            // order the variables are declared\n    __gshared uint nextSequenceNumber;   // the counter for sequenceNumber\n    FuncDeclarations nestedrefs;    // referenced by these lexically nested functions\n    structalign_t alignment;\n    bool isargptr;                  // if parameter that _argptr points to\n    bool ctorinit;                  // it has been initialized in a ctor\n    bool iscatchvar;                // this is the exception object variable in catch() clause\n\n    // Both these mean the var is not rebindable once assigned,\n    // and the destructor gets run when it goes out of scope\n    bool onstack;                   // it is a class that was allocated on the stack\n    bool mynew;                     // it is a class new'd with custom operator new\n\n    int canassign;                  // it can be assigned to\n    bool overlapped;                // if it is a field and has overlapping\n    bool overlapUnsafe;             // if it is an overlapping field and the overlaps are unsafe\n    bool doNotInferScope;           // do not infer 'scope' for this variable\n    ubyte isdataseg;                // private data for isDataseg 0 unset, 1 true, 2 false\n    Dsymbol aliassym;               // if redone as alias to another symbol\n    VarDeclaration lastVar;         // Linked list of variables for goto-skips-init detection\n    uint endlinnum;                 // line number of end of scope that this var lives in\n\n    // When interpreting, these point to the value (NULL if value not determinable)\n    // The index of this variable on the CTFE stack, -1 if not allocated\n    int ctfeAdrOnStack;\n\n    Expression edtor;               // if !=null, does the destruction of the variable\n    IntRange* range;                // if !=null, the variable is known to be within the range\n\n    VarDeclarations* maybes;        // STC.maybescope variables that are assigned to this STC.maybescope variable\n\n    final extern (D) this(const ref Loc loc, Type type, Identifier id, Initializer _init, StorageClass storage_class = STC.undefined_)\n    {\n        super(id);\n        //printf(\"VarDeclaration('%s')\\n\", id.toChars());\n        assert(id);\n        debug\n        {\n            if (!type && !_init)\n            {\n                //printf(\"VarDeclaration('%s')\\n\", id.toChars());\n                //*(char*)0=0;\n            }\n        }\n\n        assert(type || _init);\n        this.type = type;\n        this._init = _init;\n        this.loc = loc;\n        ctfeAdrOnStack = -1;\n        this.storage_class = storage_class;\n        sequenceNumber = ++nextSequenceNumber;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        //printf(\"VarDeclaration::syntaxCopy(%s)\\n\", toChars());\n        assert(!s);\n        auto v = new VarDeclaration(loc, type ? type.syntaxCopy() : null, ident, _init ? _init.syntaxCopy() : null, storage_class);\n        return v;\n    }\n\n    override final void setFieldOffset(AggregateDeclaration ad, uint* poffset, bool isunion)\n    {\n        //printf(\"VarDeclaration::setFieldOffset(ad = %s) %s\\n\", ad.toChars(), toChars());\n\n        if (aliassym)\n        {\n            // If this variable was really a tuple, set the offsets for the tuple fields\n            TupleDeclaration v2 = aliassym.isTupleDeclaration();\n            assert(v2);\n            for (size_t i = 0; i < v2.objects.dim; i++)\n            {\n                RootObject o = (*v2.objects)[i];\n                assert(o.dyncast() == DYNCAST.expression);\n                Expression e = cast(Expression)o;\n                assert(e.op == TOK.dSymbol);\n                DsymbolExp se = cast(DsymbolExp)e;\n                se.s.setFieldOffset(ad, poffset, isunion);\n            }\n            return;\n        }\n\n        if (!isField())\n            return;\n        assert(!(storage_class & (STC.static_ | STC.extern_ | STC.parameter | STC.tls)));\n\n        //printf(\"+VarDeclaration::setFieldOffset(ad = %s) %s\\n\", ad.toChars(), toChars());\n\n        /* Fields that are tuples appear both as part of TupleDeclarations and\n         * as members. That means ignore them if they are already a field.\n         */\n        if (offset)\n        {\n            // already a field\n            *poffset = ad.structsize; // https://issues.dlang.org/show_bug.cgi?id=13613\n            return;\n        }\n        for (size_t i = 0; i < ad.fields.dim; i++)\n        {\n            if (ad.fields[i] == this)\n            {\n                // already a field\n                *poffset = ad.structsize; // https://issues.dlang.org/show_bug.cgi?id=13613\n                return;\n            }\n        }\n\n        // Check for forward referenced types which will fail the size() call\n        Type t = type.toBasetype();\n        if (storage_class & STC.ref_)\n        {\n            // References are the size of a pointer\n            t = Type.tvoidptr;\n        }\n        Type tv = t.baseElemOf();\n        if (tv.ty == Tstruct)\n        {\n            auto ts = cast(TypeStruct)tv;\n            assert(ts.sym != ad);   // already checked in ad.determineFields()\n            if (!ts.sym.determineSize(loc))\n            {\n                type = Type.terror;\n                errors = true;\n                return;\n            }\n        }\n\n        // List in ad.fields. Even if the type is error, it's necessary to avoid\n        // pointless error diagnostic \"more initializers than fields\" on struct literal.\n        ad.fields.push(this);\n\n        if (t.ty == Terror)\n            return;\n\n        const sz = t.size(loc);\n        assert(sz != SIZE_INVALID && sz < uint.max);\n        uint memsize = cast(uint)sz;                // size of member\n        uint memalignsize = Target.fieldalign(t);   // size of member for alignment purposes\n        offset = AggregateDeclaration.placeField(\n            poffset,\n            memsize, memalignsize, alignment,\n            &ad.structsize, &ad.alignsize,\n            isunion);\n\n        //printf(\"\\t%s: memalignsize = %d\\n\", toChars(), memalignsize);\n        //printf(\" addField '%s' to '%s' at offset %d, size = %d\\n\", toChars(), ad.toChars(), offset, memsize);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"variable\";\n    }\n\n    override final inout(AggregateDeclaration) isThis() inout\n    {\n        if (!(storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.templateparameter | STC.tls | STC.gshared | STC.ctfe)))\n        {\n            /* The casting is necessary because `s = s.parent` is otherwise rejected\n             */\n            for (auto s = cast(Dsymbol)this; s; s = s.parent)\n            {\n                auto ad = (cast(inout)s).isMember();\n                if (ad)\n                    return ad;\n                if (!s.parent || !s.parent.isTemplateMixin())\n                    break;\n            }\n        }\n        return null;\n    }\n\n    override final bool needThis()\n    {\n        //printf(\"VarDeclaration::needThis(%s, x%x)\\n\", toChars(), storage_class);\n        return isField();\n    }\n\n    override final bool isExport() const\n    {\n        return protection.kind == Prot.Kind.export_;\n    }\n\n    override final bool isImportedSymbol() const\n    {\n        if (protection.kind == Prot.Kind.export_ && !_init && (storage_class & STC.static_ || parent.isModule()))\n            return true;\n        return false;\n    }\n\n    /*******************************\n     * Does symbol go into data segment?\n     * Includes extern variables.\n     */\n    override final bool isDataseg()\n    {\n        version (none)\n        {\n            printf(\"VarDeclaration::isDataseg(%p, '%s')\\n\", this, toChars());\n            printf(\"%llx, isModule: %p, isTemplateInstance: %p, isNspace: %p\\n\",\n                   storage_class & (STC.static_ | STC.const_), parent.isModule(), parent.isTemplateInstance(), parent.isNspace());\n            printf(\"parent = '%s'\\n\", parent.toChars());\n        }\n\n        if (isdataseg == 0) // the value is not cached\n        {\n            isdataseg = 2; // The Variables does not go into the datasegment\n\n            if (!canTakeAddressOf())\n            {\n                return false;\n            }\n\n            Dsymbol parent = toParent();\n            if (!parent && !(storage_class & STC.static_))\n            {\n                error(\"forward referenced\");\n                type = Type.terror;\n            }\n            else if (storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared) ||\n                parent.isModule() || parent.isTemplateInstance() || parent.isNspace())\n            {\n                isdataseg = 1; // It is in the DataSegment\n            }\n        }\n\n        return (isdataseg == 1);\n    }\n    /************************************\n     * Does symbol go into thread local storage?\n     */\n    override final bool isThreadlocal()\n    {\n        //printf(\"VarDeclaration::isThreadlocal(%p, '%s')\\n\", this, toChars());\n        /* Data defaults to being thread-local. It is not thread-local\n         * if it is immutable, const or shared.\n         */\n        bool i = isDataseg() && !(storage_class & (STC.immutable_ | STC.const_ | STC.shared_ | STC.gshared));\n        //printf(\"\\treturn %d\\n\", i);\n        return i;\n    }\n\n    /********************************************\n     * Can variable be read and written by CTFE?\n     */\n    final bool isCTFE()\n    {\n        return (storage_class & STC.ctfe) != 0; // || !isDataseg();\n    }\n\n    final bool isOverlappedWith(VarDeclaration v)\n    {\n        const vsz = v.type.size();\n        const tsz = type.size();\n        assert(vsz != SIZE_INVALID && tsz != SIZE_INVALID);\n        return    offset < v.offset + vsz &&\n                v.offset <   offset + tsz;\n    }\n\n    override final bool hasPointers()\n    {\n        //printf(\"VarDeclaration::hasPointers() %s, ty = %d\\n\", toChars(), type.ty);\n        return (!isDataseg() && type.hasPointers());\n    }\n\n    /*************************************\n     * Return true if we can take the address of this variable.\n     */\n    final bool canTakeAddressOf()\n    {\n        return !(storage_class & STC.manifest);\n    }\n\n    /******************************************\n     * Return true if variable needs to call the destructor.\n     */\n    final bool needsScopeDtor()\n    {\n        //printf(\"VarDeclaration::needsScopeDtor() %s\\n\", toChars());\n        return edtor && !(storage_class & STC.nodtor);\n    }\n\n    /******************************************\n     * If a variable has a scope destructor call, return call for it.\n     * Otherwise, return NULL.\n     */\n    final Expression callScopeDtor(Scope* sc)\n    {\n        //printf(\"VarDeclaration::callScopeDtor() %s\\n\", toChars());\n\n        // Destruction of STC.field's is handled by buildDtor()\n        if (storage_class & (STC.nodtor | STC.ref_ | STC.out_ | STC.field))\n        {\n            return null;\n        }\n\n        if (iscatchvar)\n            return null;    // destructor is built by `void semantic(Catch c, Scope* sc)`, not here\n\n        Expression e = null;\n        // Destructors for structs and arrays of structs\n        Type tv = type.baseElemOf();\n        if (tv.ty == Tstruct)\n        {\n            StructDeclaration sd = (cast(TypeStruct)tv).sym;\n            if (!sd.dtor || sd.errors)\n                return null;\n\n            const sz = type.size();\n            assert(sz != SIZE_INVALID);\n            if (!sz)\n                return null;\n\n            if (type.toBasetype().ty == Tstruct)\n            {\n                // v.__xdtor()\n                e = new VarExp(loc, this);\n\n                /* This is a hack so we can call destructors on const/immutable objects.\n                 * Need to add things like \"const ~this()\" and \"immutable ~this()\" to\n                 * fix properly.\n                 */\n                e.type = e.type.mutableOf();\n\n                // Enable calling destructors on shared objects.\n                // The destructor is always a single, non-overloaded function,\n                // and must serve both shared and non-shared objects.\n                e.type = e.type.unSharedOf;\n\n                e = new DotVarExp(loc, e, sd.dtor, false);\n                e = new CallExp(loc, e);\n            }\n            else\n            {\n                // __ArrayDtor(v[0 .. n])\n                e = new VarExp(loc, this);\n\n                const sdsz = sd.type.size();\n                assert(sdsz != SIZE_INVALID && sdsz != 0);\n                const n = sz / sdsz;\n                e = new SliceExp(loc, e, new IntegerExp(loc, 0, Type.tsize_t), new IntegerExp(loc, n, Type.tsize_t));\n\n                // Prevent redundant bounds check\n                (cast(SliceExp)e).upperIsInBounds = true;\n                (cast(SliceExp)e).lowerIsLessThanUpper = true;\n\n                // This is a hack so we can call destructors on const/immutable objects.\n                e.type = sd.type.arrayOf();\n\n                e = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayDtor), e);\n            }\n            return e;\n        }\n        // Destructors for classes\n        if (storage_class & (STC.auto_ | STC.scope_) && !(storage_class & STC.parameter))\n        {\n            for (ClassDeclaration cd = type.isClassHandle(); cd; cd = cd.baseClass)\n            {\n                /* We can do better if there's a way with onstack\n                 * classes to determine if there's no way the monitor\n                 * could be set.\n                 */\n                //if (cd.isInterfaceDeclaration())\n                //    error(\"interface `%s` cannot be scope\", cd.toChars());\n\n                // Destroying C++ scope classes crashes currently. Since C++ class dtors are not currently supported, simply do not run dtors for them.\n                // See https://issues.dlang.org/show_bug.cgi?id=13182\n                if (cd.classKind == ClassKind.cpp)\n                {\n                    break;\n                }\n                if (mynew || onstack) // if any destructors\n                {\n                    // delete this;\n                    Expression ec;\n                    ec = new VarExp(loc, this);\n                    e = new DeleteExp(loc, ec, true);\n                    e.type = Type.tvoid;\n                    break;\n                }\n            }\n        }\n        return e;\n    }\n\n    /*******************************************\n     * If variable has a constant expression initializer, get it.\n     * Otherwise, return null.\n     */\n    final Expression getConstInitializer(bool needFullType = true)\n    {\n        assert(type && _init);\n\n        // Ungag errors when not speculative\n        uint oldgag = global.gag;\n        if (global.gag)\n        {\n            Dsymbol sym = toParent().isAggregateDeclaration();\n            if (sym && !sym.isSpeculative())\n                global.gag = 0;\n        }\n\n        if (_scope)\n        {\n            inuse++;\n            _init = _init.initializerSemantic(_scope, type, INITinterpret);\n            _scope = null;\n            inuse--;\n        }\n\n        Expression e = _init.initializerToExpression(needFullType ? type : null);\n        global.gag = oldgag;\n        return e;\n    }\n\n    /*******************************************\n     * Helper function for the expansion of manifest constant.\n     */\n    final Expression expandInitializer(Loc loc)\n    {\n        assert((storage_class & STC.manifest) && _init);\n\n        auto e = getConstInitializer();\n        if (!e)\n        {\n            .error(loc, \"cannot make expression out of initializer for `%s`\", toChars());\n            return new ErrorExp();\n        }\n\n        e = e.copy();\n        e.loc = loc;    // for better error message\n        return e;\n    }\n\n    override final void checkCtorConstInit()\n    {\n        version (none)\n        {\n            /* doesn't work if more than one static ctor */\n            if (ctorinit == 0 && isCtorinit() && !isField())\n                error(\"missing initializer in static constructor for const variable\");\n        }\n    }\n\n    /************************************\n     * Check to see if this variable is actually in an enclosing function\n     * rather than the current one.\n     * Returns true if error occurs.\n     */\n    extern (D) final bool checkNestedReference(Scope* sc, Loc loc)\n    {\n        //printf(\"VarDeclaration::checkNestedReference() %s\\n\", toChars());\n        if (sc.intypeof == 1 || (sc.flags & SCOPE.ctfe))\n            return false;\n        if (!parent || parent == sc.parent)\n            return false;\n        if (isDataseg() || (storage_class & STC.manifest))\n            return false;\n\n        // The current function\n        FuncDeclaration fdthis = sc.parent.isFuncDeclaration();\n        if (!fdthis)\n            return false; // out of function scope\n\n        Dsymbol p = toParent2();\n\n        // Function literals from fdthis to p must be delegates\n        ensureStaticLinkTo(fdthis, p);\n\n        // The function that this variable is in\n        FuncDeclaration fdv = p.isFuncDeclaration();\n        if (!fdv || fdv == fdthis)\n            return false;\n\n        // Add fdthis to nestedrefs[] if not already there\n        for (size_t i = 0; 1; i++)\n        {\n            if (i == nestedrefs.dim)\n            {\n                nestedrefs.push(fdthis);\n                break;\n            }\n            if (nestedrefs[i] == fdthis)\n                break;\n        }\n\n        /* __require and __ensure will always get called directly,\n         * so they never make outer functions closure.\n         */\n        if (fdthis.ident == Id.require || fdthis.ident == Id.ensure)\n            return false;\n\n        //printf(\"\\tfdv = %s\\n\", fdv.toChars());\n        //printf(\"\\tfdthis = %s\\n\", fdthis.toChars());\n        if (loc.isValid())\n        {\n            int lv = fdthis.getLevel(loc, sc, fdv);\n            if (lv == -2) // error\n                return true;\n        }\n\n        // Add this to fdv.closureVars[] if not already there\n        if (!sc.intypeof && !(sc.flags & SCOPE.compile) &&\n            // https://issues.dlang.org/show_bug.cgi?id=17605\n            (fdv.flags & FUNCFLAG.compileTimeOnly || !(fdthis.flags & FUNCFLAG.compileTimeOnly))\n           )\n        {\n            for (size_t i = 0; 1; i++)\n            {\n                if (i == fdv.closureVars.dim)\n                {\n                    fdv.closureVars.push(this);\n                    break;\n                }\n                if (fdv.closureVars[i] == this)\n                    break;\n            }\n        }\n\n        //printf(\"fdthis is %s\\n\", fdthis.toChars());\n        //printf(\"var %s in function %s is nested ref\\n\", toChars(), fdv.toChars());\n        // __dollar creates problems because it isn't a real variable\n        // https://issues.dlang.org/show_bug.cgi?id=3326\n        if (ident == Id.dollar)\n        {\n            .error(loc, \"cannnot use `$` inside a function literal\");\n            return true;\n        }\n        if (ident == Id.withSym) // https://issues.dlang.org/show_bug.cgi?id=1759\n        {\n            ExpInitializer ez = _init.isExpInitializer();\n            assert(ez);\n            Expression e = ez.exp;\n            if (e.op == TOK.construct || e.op == TOK.blit)\n                e = (cast(AssignExp)e).e2;\n            return lambdaCheckForNestedRef(e, sc);\n        }\n\n        return false;\n    }\n\n    override final Dsymbol toAlias()\n    {\n        //printf(\"VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\\n\", toChars(), this, aliassym);\n        if ((!type || !type.deco) && _scope)\n            dsymbolSemantic(this, _scope);\n\n        assert(this != aliassym);\n        Dsymbol s = aliassym ? aliassym.toAlias() : this;\n        return s;\n    }\n\n    // Eliminate need for dynamic_cast\n    override final inout(VarDeclaration) isVarDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    /**********************************\n     * Determine if `this` has a lifetime that lasts past\n     * the destruction of `v`\n     * Params:\n     *  v = variable to test against\n     * Returns:\n     *  true if it does\n     */\n    final bool enclosesLifetimeOf(VarDeclaration v) const pure\n    {\n        return sequenceNumber < v.sequenceNumber;\n    }\n\n    /***************************************\n     * Add variable to maybes[].\n     * When a maybescope variable `v` is assigned to a maybescope variable `this`,\n     * we cannot determine if `this` is actually scope until the semantic\n     * analysis for the function is completed. Thus, we save the data\n     * until then.\n     * Params:\n     *  v = an STC.maybescope variable that was assigned to `this`\n     */\n    final void addMaybe(VarDeclaration v)\n    {\n        //printf(\"add %s to %s's list of dependencies\\n\", v.toChars(), toChars());\n        if (!maybes)\n            maybes = new VarDeclarations();\n        maybes.push(v);\n    }\n}\n\n/***********************************************************\n * This is a shell around a back end symbol\n */\nextern (C++) final class SymbolDeclaration : Declaration\n{\n    StructDeclaration dsym;\n\n    extern (D) this(const ref Loc loc, StructDeclaration dsym)\n    {\n        super(dsym.ident);\n        this.loc = loc;\n        this.dsym = dsym;\n        storage_class |= STC.const_;\n    }\n\n    // Eliminate need for dynamic_cast\n    override inout(SymbolDeclaration) isSymbolDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class TypeInfoDeclaration : VarDeclaration\n{\n    Type tinfo;\n\n    final extern (D) this(Type tinfo)\n    {\n        super(Loc.initial, Type.dtypeinfo.type, tinfo.getTypeInfoIdent(), null);\n        this.tinfo = tinfo;\n        storage_class = STC.static_ | STC.gshared;\n        protection = Prot(Prot.Kind.public_);\n        linkage = LINK.c;\n        alignment = Target.ptrsize;\n    }\n\n    static TypeInfoDeclaration create(Type tinfo)\n    {\n        return new TypeInfoDeclaration(tinfo);\n    }\n\n    override final Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(0); // should never be produced by syntax\n    }\n\n    override final const(char)* toChars()\n    {\n        //printf(\"TypeInfoDeclaration::toChars() tinfo = %s\\n\", tinfo.toChars());\n        OutBuffer buf;\n        buf.writestring(\"typeid(\");\n        buf.writestring(tinfo.toChars());\n        buf.writeByte(')');\n        return buf.extractString();\n    }\n\n    override final inout(TypeInfoDeclaration) isTypeInfoDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoStructDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfostruct)\n        {\n            ObjectNotFound(Id.TypeInfo_Struct);\n        }\n        type = Type.typeinfostruct.type;\n    }\n\n    static TypeInfoStructDeclaration create(Type tinfo)\n    {\n        return new TypeInfoStructDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoClassDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfoclass)\n        {\n            ObjectNotFound(Id.TypeInfo_Class);\n        }\n        type = Type.typeinfoclass.type;\n    }\n\n    static TypeInfoClassDeclaration create(Type tinfo)\n    {\n        return new TypeInfoClassDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoInterfaceDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfointerface)\n        {\n            ObjectNotFound(Id.TypeInfo_Interface);\n        }\n        type = Type.typeinfointerface.type;\n    }\n\n    static TypeInfoInterfaceDeclaration create(Type tinfo)\n    {\n        return new TypeInfoInterfaceDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoPointerDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfopointer)\n        {\n            ObjectNotFound(Id.TypeInfo_Pointer);\n        }\n        type = Type.typeinfopointer.type;\n    }\n\n    static TypeInfoPointerDeclaration create(Type tinfo)\n    {\n        return new TypeInfoPointerDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoArrayDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfoarray)\n        {\n            ObjectNotFound(Id.TypeInfo_Array);\n        }\n        type = Type.typeinfoarray.type;\n    }\n\n    static TypeInfoArrayDeclaration create(Type tinfo)\n    {\n        return new TypeInfoArrayDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoStaticArrayDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfostaticarray)\n        {\n            ObjectNotFound(Id.TypeInfo_StaticArray);\n        }\n        type = Type.typeinfostaticarray.type;\n    }\n\n    static TypeInfoStaticArrayDeclaration create(Type tinfo)\n    {\n        return new TypeInfoStaticArrayDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfoassociativearray)\n        {\n            ObjectNotFound(Id.TypeInfo_AssociativeArray);\n        }\n        type = Type.typeinfoassociativearray.type;\n    }\n\n    static TypeInfoAssociativeArrayDeclaration create(Type tinfo)\n    {\n        return new TypeInfoAssociativeArrayDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoEnumDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfoenum)\n        {\n            ObjectNotFound(Id.TypeInfo_Enum);\n        }\n        type = Type.typeinfoenum.type;\n    }\n\n    static TypeInfoEnumDeclaration create(Type tinfo)\n    {\n        return new TypeInfoEnumDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoFunctionDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfofunction)\n        {\n            ObjectNotFound(Id.TypeInfo_Function);\n        }\n        type = Type.typeinfofunction.type;\n    }\n\n    static TypeInfoFunctionDeclaration create(Type tinfo)\n    {\n        return new TypeInfoFunctionDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoDelegateDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfodelegate)\n        {\n            ObjectNotFound(Id.TypeInfo_Delegate);\n        }\n        type = Type.typeinfodelegate.type;\n    }\n\n    static TypeInfoDelegateDeclaration create(Type tinfo)\n    {\n        return new TypeInfoDelegateDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoTupleDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfotypelist)\n        {\n            ObjectNotFound(Id.TypeInfo_Tuple);\n        }\n        type = Type.typeinfotypelist.type;\n    }\n\n    static TypeInfoTupleDeclaration create(Type tinfo)\n    {\n        return new TypeInfoTupleDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoConstDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfoconst)\n        {\n            ObjectNotFound(Id.TypeInfo_Const);\n        }\n        type = Type.typeinfoconst.type;\n    }\n\n    static TypeInfoConstDeclaration create(Type tinfo)\n    {\n        return new TypeInfoConstDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoInvariantDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfoinvariant)\n        {\n            ObjectNotFound(Id.TypeInfo_Invariant);\n        }\n        type = Type.typeinfoinvariant.type;\n    }\n\n    static TypeInfoInvariantDeclaration create(Type tinfo)\n    {\n        return new TypeInfoInvariantDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoSharedDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfoshared)\n        {\n            ObjectNotFound(Id.TypeInfo_Shared);\n        }\n        type = Type.typeinfoshared.type;\n    }\n\n    static TypeInfoSharedDeclaration create(Type tinfo)\n    {\n        return new TypeInfoSharedDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoWildDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfowild)\n        {\n            ObjectNotFound(Id.TypeInfo_Wild);\n        }\n        type = Type.typeinfowild.type;\n    }\n\n    static TypeInfoWildDeclaration create(Type tinfo)\n    {\n        return new TypeInfoWildDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeInfoVectorDeclaration : TypeInfoDeclaration\n{\n    extern (D) this(Type tinfo)\n    {\n        super(tinfo);\n        if (!Type.typeinfovector)\n        {\n            ObjectNotFound(Id.TypeInfo_Vector);\n        }\n        type = Type.typeinfovector.type;\n    }\n\n    static TypeInfoVectorDeclaration create(Type tinfo)\n    {\n        return new TypeInfoVectorDeclaration(tinfo);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * For the \"this\" parameter to member functions\n */\nextern (C++) final class ThisDeclaration : VarDeclaration\n{\n    extern (D) this(const ref Loc loc, Type t)\n    {\n        super(loc, t, Id.This, null);\n        storage_class |= STC.nodtor;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(0); // should never be produced by syntax\n    }\n\n    override inout(ThisDeclaration) isThisDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/declaration.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/declaration.h\n */\n\n#pragma once\n\n#include \"dsymbol.h\"\n#include \"mtype.h\"\n#include \"tokens.h\"\n\nclass Expression;\nclass Statement;\nclass LabelDsymbol;\nclass Initializer;\nclass ForeachStatement;\nstruct Ensure\n{\n    Identifier *id;\n    Statement *ensure;\n};\nclass FuncDeclaration;\nclass StructDeclaration;\nstruct CompiledCtfeFunction;\nstruct ObjcSelector;\nstruct IntRange;\n\n#define STCundefined    0LL\n#define STCstatic       1LL\n#define STCextern       2LL\n#define STCconst        4LL\n#define STCfinal        8LL\n#define STCabstract     0x10LL\n#define STCparameter    0x20LL\n#define STCfield        0x40LL\n#define STCoverride     0x80LL\n#define STCauto         0x100LL\n#define STCsynchronized 0x200LL\n#define STCdeprecated   0x400LL\n#define STCin           0x800LL         // in parameter\n#define STCout          0x1000LL        // out parameter\n#define STClazy         0x2000LL        // lazy parameter\n#define STCforeach      0x4000LL        // variable for foreach loop\n#define STCvariadic     0x10000LL       // the 'variadic' parameter in: T foo(T a, U b, V variadic...)\n#define STCctorinit     0x20000LL       // can only be set inside constructor\n#define STCtemplateparameter  0x40000LL // template parameter\n#define STCscope        0x80000LL\n#define STCimmutable    0x100000LL\n#define STCref          0x200000LL\n#define STCinit         0x400000LL      // has explicit initializer\n#define STCmanifest     0x800000LL      // manifest constant\n#define STCnodtor       0x1000000LL     // don't run destructor\n#define STCnothrow      0x2000000LL     // never throws exceptions\n#define STCpure         0x4000000LL     // pure function\n#define STCtls          0x8000000LL     // thread local\n#define STCalias        0x10000000LL    // alias parameter\n#define STCshared       0x20000000LL    // accessible from multiple threads\n// accessible from multiple threads\n// but not typed as \"shared\"\n#define STCgshared      0x40000000LL\n#define STCwild         0x80000000LL    // for \"wild\" type constructor\n#define STC_TYPECTOR    (STCconst | STCimmutable | STCshared | STCwild)\n#define STC_FUNCATTR    (STCref | STCnothrow | STCnogc | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem)\n\n#define STCproperty      0x100000000LL\n#define STCsafe          0x200000000LL\n#define STCtrusted       0x400000000LL\n#define STCsystem        0x800000000LL\n#define STCctfe          0x1000000000LL  // can be used in CTFE, even if it is static\n#define STCdisable       0x2000000000LL  // for functions that are not callable\n#define STCresult        0x4000000000LL  // for result variables passed to out contracts\n#define STCnodefaultctor 0x8000000000LL  // must be set inside constructor\n#define STCtemp          0x10000000000LL // temporary variable\n#define STCrvalue        0x20000000000LL // force rvalue for variables\n#define STCnogc          0x40000000000LL // @nogc\n#define STCvolatile      0x80000000000LL // destined for volatile in the back end\n#define STCreturn        0x100000000000LL // 'return ref' or 'return scope' for function parameters\n#define STCautoref       0x200000000000LL // Mark for the already deduced 'auto ref' parameter\n#define STCinference     0x400000000000LL // do attribute inference\n#define STCexptemp       0x800000000000LL // temporary variable that has lifetime restricted to an expression\n#define STCmaybescope    0x1000000000000LL // parameter might be 'scope'\n#define STCscopeinferred 0x2000000000000LL // 'scope' has been inferred and should not be part of mangling\n#define STCfuture        0x4000000000000LL // introducing new base class function\n#define STClocal         0x8000000000000LL // do not forward (see dmd.dsymbol.ForwardingScopeDsymbol).\n\nvoid ObjectNotFound(Identifier *id);\n\n/**************************************************************/\n\nclass Declaration : public Dsymbol\n{\npublic:\n    Type *type;\n    Type *originalType;         // before semantic analysis\n    StorageClass storage_class;\n    Prot protection;\n    LINK linkage;\n    int inuse;                  // used to detect cycles\n    DArray<const char> mangleOverride;      // overridden symbol with pragma(mangle, \"...\")\n\n    const char *kind() const;\n    d_uns64 size(const Loc &loc);\n\n    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);\n\n    bool isStatic() const { return (storage_class & STCstatic) != 0; }\n    virtual bool isDelete();\n    virtual bool isDataseg();\n    virtual bool isThreadlocal();\n    virtual bool isCodeseg() const;\n    bool isCtorinit() const     { return (storage_class & STCctorinit) != 0; }\n    bool isFinal() const        { return (storage_class & STCfinal) != 0; }\n    virtual bool isAbstract()   { return (storage_class & STCabstract) != 0; }\n    bool isConst() const        { return (storage_class & STCconst) != 0; }\n    bool isImmutable() const    { return (storage_class & STCimmutable) != 0; }\n    bool isWild() const         { return (storage_class & STCwild) != 0; }\n    bool isAuto() const         { return (storage_class & STCauto) != 0; }\n    bool isScope() const        { return (storage_class & STCscope) != 0; }\n    bool isSynchronized() const { return (storage_class & STCsynchronized) != 0; }\n    bool isParameter() const    { return (storage_class & STCparameter) != 0; }\n    bool isDeprecated()         { return (storage_class & STCdeprecated) != 0; }\n    bool isOverride() const     { return (storage_class & STCoverride) != 0; }\n    bool isResult() const       { return (storage_class & STCresult) != 0; }\n    bool isField() const        { return (storage_class & STCfield) != 0; }\n\n    bool isIn()  const  { return (storage_class & STCin) != 0; }\n    bool isOut() const  { return (storage_class & STCout) != 0; }\n    bool isRef() const  { return (storage_class & STCref) != 0; }\n\n    bool isFuture() const { return (storage_class & STCfuture) != 0; }\n\n    Prot prot();\n\n    Declaration *isDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/**************************************************************/\n\nclass TupleDeclaration : public Declaration\n{\npublic:\n    Objects *objects;\n    bool isexp;                 // true: expression tuple\n\n    TypeTuple *tupletype;       // !=NULL if this is a type tuple\n\n    Dsymbol *syntaxCopy(Dsymbol *);\n    const char *kind() const;\n    Type *getType();\n    Dsymbol *toAlias2();\n    bool needThis();\n\n    TupleDeclaration *isTupleDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/**************************************************************/\n\nclass AliasDeclaration : public Declaration\n{\npublic:\n    Dsymbol *aliassym;\n    Dsymbol *overnext;          // next in overload list\n    Dsymbol *_import;           // !=NULL if unresolved internal alias for selective import\n\n    static AliasDeclaration *create(Loc loc, Identifier *id, Type *type);\n    Dsymbol *syntaxCopy(Dsymbol *);\n    bool overloadInsert(Dsymbol *s);\n    const char *kind() const;\n    Type *getType();\n    Dsymbol *toAlias();\n    Dsymbol *toAlias2();\n    bool isOverloadable();\n\n    AliasDeclaration *isAliasDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/**************************************************************/\n\nclass OverDeclaration : public Declaration\n{\npublic:\n    Dsymbol *overnext;          // next in overload list\n    Dsymbol *aliassym;\n    bool hasOverloads;\n\n    const char *kind() const;\n    bool equals(RootObject *o);\n    bool overloadInsert(Dsymbol *s);\n\n    Dsymbol *toAlias();\n    Dsymbol *isUnique();\n    bool isOverloadable();\n\n    OverDeclaration *isOverDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/**************************************************************/\n\nclass VarDeclaration : public Declaration\n{\npublic:\n    Initializer *_init;\n    unsigned offset;\n    unsigned sequenceNumber;     // order the variables are declared\n    FuncDeclarations nestedrefs; // referenced by these lexically nested functions\n    structalign_t alignment;\n    bool isargptr;              // if parameter that _argptr points to\n    bool ctorinit;              // it has been initialized in a ctor\n    bool iscatchvar;            // this is the exception object variable in catch() clause\n    bool onstack;               // it is a class that was allocated on the stack\n    bool mynew;                 // it is a class new'd with custom operator new\n    int canassign;              // it can be assigned to\n    bool overlapped;            // if it is a field and has overlapping\n    bool overlapUnsafe;         // if it is an overlapping field and the overlaps are unsafe\n    bool doNotInferScope;       // do not infer 'scope' for this variable\n    unsigned char isdataseg;    // private data for isDataseg\n    Dsymbol *aliassym;          // if redone as alias to another symbol\n    VarDeclaration *lastVar;    // Linked list of variables for goto-skips-init detection\n    unsigned endlinnum;         // line number of end of scope that this var lives in\n\n    // When interpreting, these point to the value (NULL if value not determinable)\n    // The index of this variable on the CTFE stack, -1 if not allocated\n    int ctfeAdrOnStack;\n    Expression *edtor;          // if !=NULL, does the destruction of the variable\n    IntRange *range;            // if !NULL, the variable is known to be within the range\n\n    VarDeclarations *maybes;    // STCmaybescope variables that are assigned to this STCmaybescope variable\n\n    Dsymbol *syntaxCopy(Dsymbol *);\n    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);\n    const char *kind() const;\n    AggregateDeclaration *isThis();\n    bool needThis();\n    bool isExport() const;\n    bool isImportedSymbol() const;\n    bool isDataseg();\n    bool isThreadlocal();\n    bool isCTFE();\n    bool isOverlappedWith(VarDeclaration *v);\n    bool hasPointers();\n    bool canTakeAddressOf();\n    bool needsScopeDtor();\n    bool enclosesLifetimeOf(VarDeclaration *v) const;\n    Expression *callScopeDtor(Scope *sc);\n    Expression *getConstInitializer(bool needFullType = true);\n    Expression *expandInitializer(Loc loc);\n    void checkCtorConstInit();\n    Dsymbol *toAlias();\n    // Eliminate need for dynamic_cast\n    VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/**************************************************************/\n\n// This is a shell around a back end symbol\n\nclass SymbolDeclaration : public Declaration\n{\npublic:\n    StructDeclaration *dsym;\n\n    // Eliminate need for dynamic_cast\n    SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoDeclaration : public VarDeclaration\n{\npublic:\n    Type *tinfo;\n\n    static TypeInfoDeclaration *create(Type *tinfo);\n    Dsymbol *syntaxCopy(Dsymbol *);\n    const char *toChars();\n\n    TypeInfoDeclaration *isTypeInfoDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoStructDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoStructDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoClassDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoClassDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoInterfaceDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoInterfaceDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoPointerDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoPointerDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoArrayDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoArrayDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoStaticArrayDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoEnumDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoEnumDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoFunctionDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoFunctionDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoDelegateDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoDelegateDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoTupleDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoTupleDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoConstDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoConstDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoInvariantDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoInvariantDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoSharedDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoSharedDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoWildDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoWildDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeInfoVectorDeclaration : public TypeInfoDeclaration\n{\npublic:\n    static TypeInfoVectorDeclaration *create(Type *tinfo);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/**************************************************************/\n\nclass ThisDeclaration : public VarDeclaration\n{\npublic:\n    Dsymbol *syntaxCopy(Dsymbol *);\n    ThisDeclaration *isThisDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nenum ILS\n{\n    ILSuninitialized,   // not computed yet\n    ILSno,              // cannot inline\n    ILSyes              // can inline\n};\n\n/**************************************************************/\n\nenum BUILTIN\n{\n    BUILTINunknown = -1,        // not known if this is a builtin\n    BUILTINno,                  // this is not a builtin\n    BUILTINyes                  // this is a builtin\n};\n\nExpression *eval_builtin(Loc loc, FuncDeclaration *fd, Expressions *arguments);\nBUILTIN isBuiltin(FuncDeclaration *fd);\n\ntypedef Expression *(*builtin_fp)(Loc loc, FuncDeclaration *fd, Expressions *arguments);\nvoid add_builtin(const char *mangle, builtin_fp fp);\nvoid builtin_init();\n\nclass FuncDeclaration : public Declaration\n{\npublic:\n    Types *fthrows;                     // Array of Type's of exceptions (not used)\n    Statements *frequires;              // in contracts\n    Ensures *fensures;                  // out contracts\n    Statement *frequire;                // lowered in contract\n    Statement *fensure;                 // lowered out contract\n    Statement *fbody;\n\n    FuncDeclarations foverrides;        // functions this function overrides\n    FuncDeclaration *fdrequire;         // function that does the in contract\n    FuncDeclaration *fdensure;          // function that does the out contract\n\n    const char *mangleString;           // mangled symbol created from mangleExact()\n\n    VarDeclaration *vresult;            // result variable for out contracts\n    LabelDsymbol *returnLabel;          // where the return goes\n\n    // used to prevent symbols in different\n    // scopes from having the same name\n    DsymbolTable *localsymtab;\n    VarDeclaration *vthis;              // 'this' parameter (member and nested)\n    VarDeclaration *v_arguments;        // '_arguments' parameter\n    ObjcSelector* selector;             // Objective-C method selector (member function only)\n    VarDeclaration *v_argptr;           // '_argptr' variable\n    VarDeclarations *parameters;        // Array of VarDeclaration's for parameters\n    DsymbolTable *labtab;               // statement label symbol table\n    Dsymbol *overnext;                  // next in overload list\n    FuncDeclaration *overnext0;         // next in overload list (only used during IFTI)\n    Loc endloc;                         // location of closing curly bracket\n    int vtblIndex;                      // for member functions, index into vtbl[]\n    bool naked;                         // true if naked\n    bool generated;                     // true if function was generated by the compiler rather than\n                                        // supplied by the user\n    ILS inlineStatusStmt;\n    ILS inlineStatusExp;\n    PINLINE inlining;\n\n    CompiledCtfeFunction *ctfeCode;     // Compiled code for interpreter\n    int inlineNest;                     // !=0 if nested inline\n    bool isArrayOp;                     // true if array operation\n    bool eh_none;                       /// true if no exception unwinding is needed\n\n    // true if errors in semantic3 this function's frame ptr\n    bool semantic3Errors;\n    ForeachStatement *fes;              // if foreach body, this is the foreach\n    BaseClass* interfaceVirtual;        // if virtual, but only appears in interface vtbl[]\n    bool introducing;                   // true if 'introducing' function\n    // if !=NULL, then this is the type\n    // of the 'introducing' function\n    // this one is overriding\n    Type *tintro;\n    bool inferRetType;                  // true if return type is to be inferred\n    StorageClass storage_class2;        // storage class for template onemember's\n\n    // Things that should really go into Scope\n\n    // 1 if there's a return exp; statement\n    // 2 if there's a throw statement\n    // 4 if there's an assert(0)\n    // 8 if there's inline asm\n    // 16 if there are multiple return statements\n    int hasReturnExp;\n\n    // Support for NRVO (named return value optimization)\n    bool nrvo_can;                      // true means we can do it\n    VarDeclaration *nrvo_var;           // variable to replace with shidden\n    Symbol *shidden;                    // hidden pointer passed to function\n\n    ReturnStatements *returns;\n\n    GotoStatements *gotos;              // Gotos with forward references\n\n    // set if this is a known, builtin function we can evaluate at compile time\n    BUILTIN builtin;\n\n    // set if someone took the address of this function\n    int tookAddressOf;\n    bool requiresClosure;               // this function needs a closure\n\n    // local variables in this function which are referenced by nested functions\n    VarDeclarations closureVars;\n    // Sibling nested functions which called this one\n    FuncDeclarations siblingCallers;\n\n    FuncDeclarations *inlinedNestedCallees;\n\n    unsigned flags;                     // FUNCFLAGxxxxx\n\n    static FuncDeclaration *create(const Loc &loc, const Loc &endloc, Identifier *id, StorageClass storage_class, Type *type);\n    Dsymbol *syntaxCopy(Dsymbol *);\n    bool functionSemantic();\n    bool functionSemantic3();\n    // called from semantic3\n    VarDeclaration *declareThis(Scope *sc, AggregateDeclaration *ad);\n    bool equals(RootObject *o);\n\n    int overrides(FuncDeclaration *fd);\n    int findVtblIndex(Dsymbols *vtbl, int dim, bool fix17349 = true);\n    BaseClass *overrideInterface();\n    bool overloadInsert(Dsymbol *s);\n    FuncDeclaration *overloadExactMatch(Type *t);\n    FuncDeclaration *overloadModMatch(const Loc &loc, Type *tthis, bool &hasOverloads);\n    TemplateDeclaration *findTemplateDeclRoot();\n    bool inUnittest();\n    MATCH leastAsSpecialized(FuncDeclaration *g);\n    LabelDsymbol *searchLabel(Identifier *ident);\n    int getLevel(const Loc &loc, Scope *sc, FuncDeclaration *fd); // lexical nesting level difference\n    const char *toPrettyChars(bool QualifyTypes = false);\n    const char *toFullSignature();  // for diagnostics, e.g. 'int foo(int x, int y) pure'\n    bool isMain() const;\n    bool isCMain() const;\n    bool isWinMain() const;\n    bool isDllMain() const;\n    bool isExport() const;\n    bool isImportedSymbol() const;\n    bool isCodeseg() const;\n    bool isOverloadable();\n    bool isAbstract();\n    PURE isPure();\n    PURE isPureBypassingInference();\n    bool setImpure();\n    bool isSafe();\n    bool isSafeBypassingInference();\n    bool isTrusted();\n    bool setUnsafe();\n\n    bool isNogc();\n    bool isNogcBypassingInference();\n    bool setGC();\n\n    void printGCUsage(const Loc &loc, const char *warn);\n    bool isolateReturn();\n    bool parametersIntersect(Type *t);\n    virtual bool isNested();\n    AggregateDeclaration *isThis();\n    bool needThis();\n    bool isVirtualMethod();\n    virtual bool isVirtual() const;\n    bool isFinalFunc() const;\n    virtual bool addPreInvariant();\n    virtual bool addPostInvariant();\n    const char *kind() const;\n    FuncDeclaration *isUnique();\n    bool needsClosure();\n    bool hasNestedFrameRefs();\n    void buildResultVar(Scope *sc, Type *tret);\n    Statement *mergeFrequire(Statement *);\n    Statement *mergeFensure(Statement *, Identifier *oid);\n    Parameters *getParameters(int *pvarargs);\n\n    static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0);\n    static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0);\n\n    FuncDeclaration *isFuncDeclaration() { return this; }\n\n    virtual FuncDeclaration *toAliasFunc() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass FuncAliasDeclaration : public FuncDeclaration\n{\npublic:\n    FuncDeclaration *funcalias;\n    bool hasOverloads;\n\n    FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }\n    const char *kind() const;\n\n    FuncDeclaration *toAliasFunc();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass FuncLiteralDeclaration : public FuncDeclaration\n{\npublic:\n    TOK tok;                       // TOKfunction or TOKdelegate\n    Type *treq;                         // target of return type inference\n\n    // backend\n    bool deferToObj;\n\n    Dsymbol *syntaxCopy(Dsymbol *);\n    bool isNested();\n    AggregateDeclaration *isThis();\n    bool isVirtual() const;\n    bool addPreInvariant();\n    bool addPostInvariant();\n\n    void modifyReturns(Scope *sc, Type *tret);\n\n    FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }\n    const char *kind() const;\n    const char *toPrettyChars(bool QualifyTypes = false);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass CtorDeclaration : public FuncDeclaration\n{\npublic:\n    Dsymbol *syntaxCopy(Dsymbol *);\n    const char *kind() const;\n    const char *toChars();\n    bool isVirtual() const;\n    bool addPreInvariant();\n    bool addPostInvariant();\n\n    CtorDeclaration *isCtorDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass PostBlitDeclaration : public FuncDeclaration\n{\npublic:\n    Dsymbol *syntaxCopy(Dsymbol *);\n    bool isVirtual() const;\n    bool addPreInvariant();\n    bool addPostInvariant();\n    bool overloadInsert(Dsymbol *s);\n\n    PostBlitDeclaration *isPostBlitDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DtorDeclaration : public FuncDeclaration\n{\npublic:\n    Dsymbol *syntaxCopy(Dsymbol *);\n    const char *kind() const;\n    const char *toChars();\n    bool isVirtual() const;\n    bool addPreInvariant();\n    bool addPostInvariant();\n    bool overloadInsert(Dsymbol *s);\n\n    DtorDeclaration *isDtorDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StaticCtorDeclaration : public FuncDeclaration\n{\npublic:\n    Dsymbol *syntaxCopy(Dsymbol *);\n    AggregateDeclaration *isThis();\n    bool isVirtual() const;\n    bool addPreInvariant();\n    bool addPostInvariant();\n    bool hasStaticCtorOrDtor();\n\n    StaticCtorDeclaration *isStaticCtorDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass SharedStaticCtorDeclaration : public StaticCtorDeclaration\n{\npublic:\n    Dsymbol *syntaxCopy(Dsymbol *);\n\n    SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StaticDtorDeclaration : public FuncDeclaration\n{\npublic:\n    VarDeclaration *vgate;      // 'gate' variable\n\n    Dsymbol *syntaxCopy(Dsymbol *);\n    AggregateDeclaration *isThis();\n    bool isVirtual() const;\n    bool hasStaticCtorOrDtor();\n    bool addPreInvariant();\n    bool addPostInvariant();\n\n    StaticDtorDeclaration *isStaticDtorDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass SharedStaticDtorDeclaration : public StaticDtorDeclaration\n{\npublic:\n    Dsymbol *syntaxCopy(Dsymbol *);\n\n    SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass InvariantDeclaration : public FuncDeclaration\n{\npublic:\n    Dsymbol *syntaxCopy(Dsymbol *);\n    bool isVirtual() const;\n    bool addPreInvariant();\n    bool addPostInvariant();\n\n    InvariantDeclaration *isInvariantDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass UnitTestDeclaration : public FuncDeclaration\n{\npublic:\n    char *codedoc; /** For documented unittest. */\n\n    // toObjFile() these nested functions after this one\n    FuncDeclarations deferredNested;\n\n    Dsymbol *syntaxCopy(Dsymbol *);\n    AggregateDeclaration *isThis();\n    bool isVirtual() const;\n    bool addPreInvariant();\n    bool addPostInvariant();\n\n    UnitTestDeclaration *isUnitTestDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass NewDeclaration : public FuncDeclaration\n{\npublic:\n    Parameters *parameters;\n    int varargs;\n\n    Dsymbol *syntaxCopy(Dsymbol *);\n    const char *kind() const;\n    bool isVirtual() const;\n    bool addPreInvariant();\n    bool addPostInvariant();\n\n    NewDeclaration *isNewDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n\nclass DeleteDeclaration : public FuncDeclaration\n{\npublic:\n    Parameters *parameters;\n\n    Dsymbol *syntaxCopy(Dsymbol *);\n    const char *kind() const;\n    bool isDelete();\n    bool isVirtual() const;\n    bool addPreInvariant();\n    bool addPostInvariant();\n\n    DeleteDeclaration *isDeleteDeclaration() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n"
  },
  {
    "path": "gcc/d/dmd/delegatize.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/delegatize.d, _delegatize.d)\n * Documentation:  https://dlang.org/phobos/dmd_delegatize.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/delegatize.d\n */\n\nmodule dmd.delegatize;\n\nimport core.stdc.stdio;\nimport dmd.apply;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.initsem;\nimport dmd.mtype;\nimport dmd.statement;\nimport dmd.tokens;\nimport dmd.visitor;\n\n\n/*********************************\n * Convert expression into a delegate.\n *\n * Used to convert the argument to a lazy parameter.\n *\n * Params:\n *  e = argument to convert to a delegate\n *  t = the type to be returned by the delegate\n *  sc = context\n * Returns:\n *  A delegate literal\n */\nextern (C++) Expression toDelegate(Expression e, Type t, Scope* sc)\n{\n    //printf(\"Expression::toDelegate(t = %s) %s\\n\", t.toChars(), e.toChars());\n    Loc loc = e.loc;\n    auto tf = new TypeFunction(null, t, 0, LINK.d);\n    if (t.hasWild())\n        tf.mod = MODFlags.wild;\n    auto fld = new FuncLiteralDeclaration(loc, loc, tf, TOK.delegate_, null);\n    lambdaSetParent(e, fld);\n\n    sc = sc.push();\n    sc.parent = fld; // set current function to be the delegate\n    bool r = lambdaCheckForNestedRef(e, sc);\n    sc = sc.pop();\n    if (r)\n        return new ErrorExp();\n\n    Statement s;\n    if (t.ty == Tvoid)\n        s = new ExpStatement(loc, e);\n    else\n        s = new ReturnStatement(loc, e);\n    fld.fbody = s;\n    e = new FuncExp(loc, fld);\n    e = e.expressionSemantic(sc);\n    return e;\n}\n\n/******************************************\n * Patch the parent of declarations to be the new function literal.\n *\n * Since the expression is going to be moved into a function literal,\n * the parent for declarations in the expression needs to be\n * reset to that function literal.\n * Params:\n *   e = expression to check\n *   fd = function literal symbol (the new parent)\n */\nprivate void lambdaSetParent(Expression e, FuncDeclaration fd)\n{\n    extern (C++) final class LambdaSetParent : StoppableVisitor\n    {\n        alias visit = typeof(super).visit;\n        FuncDeclaration fd;\n\n    public:\n        extern (D) this(FuncDeclaration fd)\n        {\n            this.fd = fd;\n        }\n\n        override void visit(Expression)\n        {\n        }\n\n        override void visit(DeclarationExp e)\n        {\n            e.declaration.parent = fd;\n        }\n\n        override void visit(IndexExp e)\n        {\n            if (e.lengthVar)\n            {\n                //printf(\"lengthVar\\n\");\n                e.lengthVar.parent = fd;\n            }\n        }\n\n        override void visit(SliceExp e)\n        {\n            if (e.lengthVar)\n            {\n                //printf(\"lengthVar\\n\");\n                e.lengthVar.parent = fd;\n            }\n        }\n    }\n\n    scope LambdaSetParent lsp = new LambdaSetParent(fd);\n    walkPostorder(e, lsp);\n}\n\n/*******************************************\n * Look for references to variables in a scope enclosing the new function literal.\n *\n * Essentially just calls `checkNestedReference() for each variable reference in `e`.\n * Params:\n *      sc = context\n *      e = expression to check\n * Returns:\n *      true if error occurs.\n */\nbool lambdaCheckForNestedRef(Expression e, Scope* sc)\n{\n    extern (C++) final class LambdaCheckForNestedRef : StoppableVisitor\n    {\n        alias visit = typeof(super).visit;\n    public:\n        Scope* sc;\n        bool result;\n\n        extern (D) this(Scope* sc)\n        {\n            this.sc = sc;\n        }\n\n        override void visit(Expression)\n        {\n        }\n\n        override void visit(SymOffExp e)\n        {\n            VarDeclaration v = e.var.isVarDeclaration();\n            if (v)\n                result = v.checkNestedReference(sc, Loc.initial);\n        }\n\n        override void visit(VarExp e)\n        {\n            VarDeclaration v = e.var.isVarDeclaration();\n            if (v)\n                result = v.checkNestedReference(sc, Loc.initial);\n        }\n\n        override void visit(ThisExp e)\n        {\n            if (e.var)\n                result = e.var.checkNestedReference(sc, Loc.initial);\n        }\n\n        override void visit(DeclarationExp e)\n        {\n            VarDeclaration v = e.declaration.isVarDeclaration();\n            if (v)\n            {\n                result = v.checkNestedReference(sc, Loc.initial);\n                if (result)\n                    return;\n                /* Some expressions cause the frontend to create a temporary.\n                 * For example, structs with cpctors replace the original\n                 * expression e with:\n                 *  __cpcttmp = __cpcttmp.cpctor(e);\n                 *\n                 * In this instance, we need to ensure that the original\n                 * expression e does not have any nested references by\n                 * checking the declaration initializer too.\n                 */\n                if (v._init && v._init.isExpInitializer())\n                {\n                    Expression ie = v._init.initializerToExpression();\n                    result = lambdaCheckForNestedRef(ie, sc);\n                }\n            }\n        }\n    }\n\n    scope LambdaCheckForNestedRef v = new LambdaCheckForNestedRef(sc);\n    walkPostorder(e, v);\n    return v.result;\n}\n\n/*****************************************\n * See if context `s` is nested within context `p`, meaning\n * it `p` is reachable at runtime by walking the static links.\n * If any of the intervening contexts are function literals,\n * make sure they are delegates.\n * Params:\n *      s = inner context\n *      p = outer context\n * Returns:\n *      true means it is accessible by walking the context pointers at runtime\n * References:\n *      for static links see https://en.wikipedia.org/wiki/Call_stack#Functions_of_the_call_stack\n */\nbool ensureStaticLinkTo(Dsymbol s, Dsymbol p)\n{\n    while (s)\n    {\n        if (s == p) // hit!\n            return true;\n\n        if (auto fd = s.isFuncDeclaration())\n        {\n            if (!fd.isThis() && !fd.isNested())\n                break;\n\n            // https://issues.dlang.org/show_bug.cgi?id=15332\n            // change to delegate if fd is actually nested.\n            if (auto fld = fd.isFuncLiteralDeclaration())\n                fld.tok = TOK.delegate_;\n        }\n        if (auto ad = s.isAggregateDeclaration())\n        {\n            if (ad.storage_class & STC.static_)\n                break;\n        }\n        s = s.toParent2();\n    }\n    return false;\n}\n"
  },
  {
    "path": "gcc/d/dmd/denum.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/denum.d, _denum.d)\n * Documentation:  https://dlang.org/phobos/dmd_denum.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/denum.d\n */\n\nmodule dmd.denum;\n\nimport core.stdc.stdio;\n\nimport dmd.attrib;\nimport dmd.gluelayer;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.mtype;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.visitor;\n\n/***********************************************************\n */\nextern (C++) final class EnumDeclaration : ScopeDsymbol\n{\n    /* The separate, and distinct, cases are:\n     *  1. enum { ... }\n     *  2. enum : memtype { ... }\n     *  3. enum id { ... }\n     *  4. enum id : memtype { ... }\n     *  5. enum id : memtype;\n     *  6. enum id;\n     */\n    Type type;              // the TypeEnum\n    Type memtype;           // type of the members\n    Prot protection;\n    Expression maxval;\n    Expression minval;\n    Expression defaultval;  // default initializer\n    bool isdeprecated;\n    bool added;\n    int inuse;\n\n    extern (D) this(const ref Loc loc, Identifier id, Type memtype)\n    {\n        super(id);\n        //printf(\"EnumDeclaration() %s\\n\", toChars());\n        this.loc = loc;\n        type = new TypeEnum(this);\n        this.memtype = memtype;\n        protection = Prot(Prot.Kind.undefined);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto ed = new EnumDeclaration(loc, ident, memtype ? memtype.syntaxCopy() : null);\n        return ScopeDsymbol.syntaxCopy(ed);\n    }\n\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        version (none)\n        {\n            printf(\"EnumDeclaration::addMember() %s\\n\", toChars());\n            for (size_t i = 0; i < members.dim; i++)\n            {\n                EnumMember em = (*members)[i].isEnumMember();\n                printf(\"    member %s\\n\", em.toChars());\n            }\n        }\n\n        /* Anonymous enum members get added to enclosing scope.\n         */\n        ScopeDsymbol scopesym = isAnonymous() ? sds : this;\n\n        if (!isAnonymous())\n        {\n            ScopeDsymbol.addMember(sc, sds);\n            if (!symtab)\n                symtab = new DsymbolTable();\n        }\n\n        if (members)\n        {\n            for (size_t i = 0; i < members.dim; i++)\n            {\n                EnumMember em = (*members)[i].isEnumMember();\n                em.ed = this;\n                //printf(\"add %s to scope %s\\n\", em.toChars(), scopesym.toChars());\n                em.addMember(sc, isAnonymous() ? scopesym : this);\n            }\n        }\n        added = true;\n    }\n\n    override void setScope(Scope* sc)\n    {\n        if (semanticRun > PASS.init)\n            return;\n        ScopeDsymbol.setScope(sc);\n    }\n\n    override bool oneMember(Dsymbol* ps, Identifier ident)\n    {\n        if (isAnonymous())\n            return Dsymbol.oneMembers(members, ps, ident);\n        return Dsymbol.oneMember(ps, ident);\n    }\n\n    override Type getType()\n    {\n        return type;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"enum\";\n    }\n\n    override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)\n    {\n        //printf(\"%s.EnumDeclaration::search('%s')\\n\", toChars(), ident.toChars());\n        if (_scope)\n        {\n            // Try one last time to resolve this enum\n            dsymbolSemantic(this, _scope);\n        }\n\n        if (!members || !symtab || _scope)\n        {\n            error(\"is forward referenced when looking for `%s`\", ident.toChars());\n            //*(char*)0=0;\n            return null;\n        }\n\n        Dsymbol s = ScopeDsymbol.search(loc, ident, flags);\n        return s;\n    }\n\n    // is Dsymbol deprecated?\n    override bool isDeprecated()\n    {\n        return isdeprecated;\n    }\n\n    override Prot prot()\n    {\n        return protection;\n    }\n\n    /******************************\n     * Get the value of the .max/.min property as an Expression.\n     * Lazily computes the value and caches it in maxval/minval.\n     * Reports any errors.\n     * Params:\n     *      loc = location to use for error messages\n     *      id = Id::max or Id::min\n     * Returns:\n     *      corresponding value of .max/.min\n     */\n    Expression getMaxMinValue(const ref Loc loc, Identifier id)\n    {\n        //printf(\"EnumDeclaration::getMaxValue()\\n\");\n        bool first = true;\n\n        Expression* pval = (id == Id.max) ? &maxval : &minval;\n\n        Expression errorReturn()\n        {\n            *pval = new ErrorExp();\n            return *pval;\n        }\n\n        if (inuse)\n        {\n            error(loc, \"recursive definition of `.%s` property\", id.toChars());\n            return errorReturn();\n        }\n        if (*pval)\n            goto Ldone;\n\n        if (_scope)\n            dsymbolSemantic(this, _scope);\n        if (errors)\n            return errorReturn();\n        if (semanticRun == PASS.init || !members)\n        {\n            if (isSpecial())\n            {\n                /* Allow these special enums to not need a member list\n                 */\n                return memtype.getProperty(loc, id, 0);\n            }\n\n            error(\"is forward referenced looking for `.%s`\", id.toChars());\n            return errorReturn();\n        }\n        if (!(memtype && memtype.isintegral()))\n        {\n            error(loc, \"has no `.%s` property because base type `%s` is not an integral type\", id.toChars(), memtype ? memtype.toChars() : \"\");\n            return errorReturn();\n        }\n\n        for (size_t i = 0; i < members.dim; i++)\n        {\n            EnumMember em = (*members)[i].isEnumMember();\n            if (!em)\n                continue;\n            if (em.errors)\n                return errorReturn();\n\n            Expression e = em.value;\n            if (first)\n            {\n                *pval = e;\n                first = false;\n            }\n            else\n            {\n                /* In order to work successfully with UDTs,\n                 * build expressions to do the comparisons,\n                 * and let the semantic analyzer and constant\n                 * folder give us the result.\n                 */\n\n                /* Compute:\n                 *   if (e > maxval)\n                 *      maxval = e;\n                 */\n                Expression ec = new CmpExp(id == Id.max ? TOK.greaterThan : TOK.lessThan, em.loc, e, *pval);\n                inuse++;\n                ec = ec.expressionSemantic(em._scope);\n                inuse--;\n                ec = ec.ctfeInterpret();\n                if (ec.toInteger())\n                    *pval = e;\n            }\n        }\n    Ldone:\n        Expression e = *pval;\n        if (e.op != TOK.error)\n        {\n            e = e.copy();\n            e.loc = loc;\n        }\n        return e;\n    }\n\n    /****************\n     * Determine if enum is a 'special' one.\n     * Returns:\n     *  true if special\n     */\n    bool isSpecial() const nothrow @nogc\n    {\n        return (ident == Id.__c_long ||\n                ident == Id.__c_ulong ||\n                ident == Id.__c_longlong ||\n                ident == Id.__c_ulonglong ||\n                ident == Id.__c_long_double) && memtype;\n    }\n\n    Expression getDefaultValue(const ref Loc loc)\n    {\n        //printf(\"EnumDeclaration::getDefaultValue() %p %s\\n\", this, toChars());\n        if (defaultval)\n            return defaultval;\n\n        if (_scope)\n            dsymbolSemantic(this, _scope);\n        if (errors)\n            goto Lerrors;\n        if (semanticRun == PASS.init || !members)\n        {\n            if (isSpecial())\n            {\n                /* Allow these special enums to not need a member list\n                 */\n                return memtype.defaultInit(loc);\n            }\n\n            error(loc, \"forward reference of `%s.init`\", toChars());\n            goto Lerrors;\n        }\n\n        foreach (const i; 0 .. members.dim)\n        {\n            EnumMember em = (*members)[i].isEnumMember();\n            if (em)\n            {\n                defaultval = em.value;\n                return defaultval;\n            }\n        }\n\n    Lerrors:\n        defaultval = new ErrorExp();\n        return defaultval;\n    }\n\n    Type getMemtype(const ref Loc loc)\n    {\n        if (_scope)\n        {\n            /* Enum is forward referenced. We don't need to resolve the whole thing,\n             * just the base type\n             */\n            if (memtype)\n            {\n                Loc locx = loc.isValid() ? loc : this.loc;\n                memtype = memtype.typeSemantic(locx, _scope);\n            }\n            else\n            {\n                if (!isAnonymous() && members)\n                    memtype = Type.tint32;\n            }\n        }\n        if (!memtype)\n        {\n            if (!isAnonymous() && members)\n                memtype = Type.tint32;\n            else\n            {\n                Loc locx = loc.isValid() ? loc : this.loc;\n                error(locx, \"is forward referenced looking for base type\");\n                return Type.terror;\n            }\n        }\n        return memtype;\n    }\n\n    override inout(EnumDeclaration) isEnumDeclaration() inout\n    {\n        return this;\n    }\n\n    Symbol* sinit;\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class EnumMember : VarDeclaration\n{\n    /* Can take the following forms:\n     *  1. id\n     *  2. id = value\n     *  3. type id = value\n     */\n    @property ref value() { return (cast(ExpInitializer)_init).exp; }\n\n    // A cast() is injected to 'value' after dsymbolSemantic(),\n    // but 'origValue' will preserve the original value,\n    // or previous value + 1 if none was specified.\n    Expression origValue;\n\n    Type origType;\n\n    EnumDeclaration ed;\n\n    extern (D) this(const ref Loc loc, Identifier id, Expression value, Type origType)\n    {\n        super(loc, null, id ? id : Id.empty, new ExpInitializer(loc, value));\n        this.origValue = value;\n        this.origType = origType;\n    }\n\n    extern(D) this(Loc loc, Identifier id, Expression value, Type memtype,\n        StorageClass stc, UserAttributeDeclaration uad, DeprecatedDeclaration dd)\n    {\n        this(loc, id, value, memtype);\n        storage_class = stc;\n        userAttribDecl = uad;\n        depdecl = dd;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new EnumMember(\n            loc, ident,\n            value ? value.syntaxCopy() : null,\n            origType ? origType.syntaxCopy() : null,\n            storage_class,\n            userAttribDecl ? cast(UserAttributeDeclaration)userAttribDecl.syntaxCopy(s) : null,\n            depdecl ? cast(DeprecatedDeclaration)depdecl.syntaxCopy(s) : null);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"enum member\";\n    }\n\n    Expression getVarExp(const ref Loc loc, Scope* sc)\n    {\n        dsymbolSemantic(this, sc);\n        if (errors)\n            return new ErrorExp();\n        checkDisabled(loc, sc);\n\n        if (depdecl && !depdecl._scope)\n            depdecl._scope = sc;\n        checkDeprecated(loc, sc);\n\n        if (errors)\n            return new ErrorExp();\n        Expression e = new VarExp(loc, this);\n        return e.expressionSemantic(sc);\n    }\n\n    override inout(EnumMember) isEnumMember() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/dimport.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dimport.d, _dimport.d)\n * Documentation:  https://dlang.org/phobos/dmd_dimport.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dimport.d\n */\n\nmodule dmd.dimport;\n\nimport dmd.arraytypes;\nimport dmd.declaration;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.globals;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.visitor;\n\n/***********************************************************\n */\nextern (C++) final class Import : Dsymbol\n{\n    /* static import aliasId = pkg1.pkg2.id : alias1 = name1, alias2 = name2;\n     */\n    Identifiers* packages;  // array of Identifier's representing packages\n    Identifier id;          // module Identifier\n    Identifier aliasId;\n    int isstatic;           // !=0 if static import\n    Prot protection;\n\n    // Pairs of alias=name to bind into current namespace\n    Identifiers names;\n    Identifiers aliases;\n\n    Module mod;\n    Package pkg;            // leftmost package/module\n\n    // corresponding AliasDeclarations for alias=name pairs\n    AliasDeclarations aliasdecls;\n\n    extern (D) this(const ref Loc loc, Identifiers* packages, Identifier id, Identifier aliasId, int isstatic)\n    {\n        super(null);\n        assert(id);\n        version (none)\n        {\n            printf(\"Import::Import(\");\n            if (packages && packages.dim)\n            {\n                for (size_t i = 0; i < packages.dim; i++)\n                {\n                    Identifier id = (*packages)[i];\n                    printf(\"%s.\", id.toChars());\n                }\n            }\n            printf(\"%s)\\n\", id.toChars());\n        }\n        this.loc = loc;\n        this.packages = packages;\n        this.id = id;\n        this.aliasId = aliasId;\n        this.isstatic = isstatic;\n        this.protection = Prot.Kind.private_; // default to private\n        // Set symbol name (bracketed)\n        if (aliasId)\n        {\n            // import [cstdio] = std.stdio;\n            this.ident = aliasId;\n        }\n        else if (packages && packages.dim)\n        {\n            // import [std].stdio;\n            this.ident = (*packages)[0];\n        }\n        else\n        {\n            // import [foo];\n            this.ident = id;\n        }\n    }\n\n    void addAlias(Identifier name, Identifier _alias)\n    {\n        if (isstatic)\n            error(\"cannot have an import bind list\");\n        if (!aliasId)\n            this.ident = null; // make it an anonymous import\n        names.push(name);\n        aliases.push(_alias);\n    }\n\n    override const(char)* kind() const\n    {\n        return isstatic ? \"static import\" : \"import\";\n    }\n\n    override Prot prot()\n    {\n        return protection;\n    }\n\n    // copy only syntax trees\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto si = new Import(loc, packages, id, aliasId, isstatic);\n        for (size_t i = 0; i < names.dim; i++)\n        {\n            si.addAlias(names[i], aliases[i]);\n        }\n        return si;\n    }\n\n    /*******************************\n     * Load this module.\n     * Returns:\n     *  true for errors, false for success\n     */\n    bool load(Scope* sc)\n    {\n        //printf(\"Import::load('%s') %p\\n\", toPrettyChars(), this);\n        // See if existing module\n        const errors = global.errors;\n        DsymbolTable dst = Package.resolve(packages, null, &pkg);\n        version (none)\n        {\n            if (pkg && pkg.isModule())\n            {\n                .error(loc, \"can only import from a module, not from a member of module `%s`. Did you mean `import %s : %s`?\", pkg.toChars(), pkg.toPrettyChars(), id.toChars());\n                mod = pkg.isModule(); // Error recovery - treat as import of that module\n                return true;\n            }\n        }\n        Dsymbol s = dst.lookup(id);\n        if (s)\n        {\n            if (s.isModule())\n                mod = cast(Module)s;\n            else\n            {\n                if (s.isAliasDeclaration())\n                {\n                    .error(loc, \"%s `%s` conflicts with `%s`\", s.kind(), s.toPrettyChars(), id.toChars());\n                }\n                else if (Package p = s.isPackage())\n                {\n                    if (p.isPkgMod == PKG.unknown)\n                    {\n                        mod = Module.load(loc, packages, id);\n                        if (!mod)\n                            p.isPkgMod = PKG.package_;\n                        else\n                        {\n                            // mod is a package.d, or a normal module which conflicts with the package name.\n                            assert(mod.isPackageFile == (p.isPkgMod == PKG.module_));\n                            if (mod.isPackageFile)\n                                mod.tag = p.tag; // reuse the same package tag\n                        }\n                    }\n                    else\n                    {\n                        mod = p.isPackageMod();\n                    }\n                    if (!mod)\n                    {\n                        .error(loc, \"can only import from a module, not from package `%s.%s`\", p.toPrettyChars(), id.toChars());\n                    }\n                }\n                else if (pkg)\n                {\n                    .error(loc, \"can only import from a module, not from package `%s.%s`\", pkg.toPrettyChars(), id.toChars());\n                }\n                else\n                {\n                    .error(loc, \"can only import from a module, not from package `%s`\", id.toChars());\n                }\n            }\n        }\n        if (!mod)\n        {\n            // Load module\n            mod = Module.load(loc, packages, id);\n            if (mod)\n            {\n                // id may be different from mod.ident, if so then insert alias\n                dst.insert(id, mod);\n            }\n        }\n        if (mod && !mod.importedFrom)\n            mod.importedFrom = sc ? sc._module.importedFrom : Module.rootModule;\n        if (!pkg)\n            pkg = mod;\n        //printf(\"-Import::load('%s'), pkg = %p\\n\", toChars(), pkg);\n        return global.errors != errors;\n    }\n\n    override void importAll(Scope* sc)\n    {\n        if (!mod)\n        {\n            load(sc);\n            if (mod) // if successfully loaded module\n            {\n                if (mod.md && mod.md.isdeprecated)\n                {\n                    Expression msg = mod.md.msg;\n                    if (StringExp se = msg ? msg.toStringExp() : null)\n                        mod.deprecation(loc, \"is deprecated - %s\", se.string);\n                    else\n                        mod.deprecation(loc, \"is deprecated\");\n                }\n                mod.importAll(null);\n                if (sc.explicitProtection)\n                    protection = sc.protection;\n                if (!isstatic && !aliasId && !names.dim)\n                {\n                    sc.scopesym.importScope(mod, protection);\n                }\n            }\n        }\n    }\n\n    override Dsymbol toAlias()\n    {\n        if (aliasId)\n            return mod;\n        return this;\n    }\n\n    /*****************************\n     * Add import to sd's symbol table.\n     */\n    override void addMember(Scope* sc, ScopeDsymbol sd)\n    {\n        //printf(\"Import.addMember(this=%s, sd=%s, sc=%p)\\n\", toChars(), sd.toChars(), sc);\n        if (names.dim == 0)\n            return Dsymbol.addMember(sc, sd);\n        if (aliasId)\n            Dsymbol.addMember(sc, sd);\n        /* Instead of adding the import to sd's symbol table,\n         * add each of the alias=name pairs\n         */\n        for (size_t i = 0; i < names.dim; i++)\n        {\n            Identifier name = names[i];\n            Identifier _alias = aliases[i];\n            if (!_alias)\n                _alias = name;\n            auto tname = new TypeIdentifier(loc, name);\n            auto ad = new AliasDeclaration(loc, _alias, tname);\n            ad._import = this;\n            ad.addMember(sc, sd);\n            aliasdecls.push(ad);\n        }\n    }\n\n    override void setScope(Scope* sc)\n    {\n        Dsymbol.setScope(sc);\n        if (aliasdecls.dim)\n        {\n            if (!mod)\n                importAll(sc);\n\n            sc = sc.push(mod);\n            sc.protection = protection;\n            foreach (ad; aliasdecls)\n                ad.setScope(sc);\n            sc = sc.pop();\n        }\n    }\n\n    override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)\n    {\n        //printf(\"%s.Import.search(ident = '%s', flags = x%x)\\n\", toChars(), ident.toChars(), flags);\n        if (!pkg)\n        {\n            load(null);\n            mod.importAll(null);\n            mod.dsymbolSemantic(null);\n        }\n        // Forward it to the package/module\n        return pkg.search(loc, ident, flags);\n    }\n\n    override bool overloadInsert(Dsymbol s)\n    {\n        /* Allow multiple imports with the same package base, but disallow\n         * alias collisions\n         * https://issues.dlang.org/show_bug.cgi?id=5412\n         */\n        assert(ident && ident == s.ident);\n        Import imp;\n        if (!aliasId && (imp = s.isImport()) !is null && !imp.aliasId)\n            return true;\n        else\n            return false;\n    }\n\n    override inout(Import) isImport() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/dinterpret.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dinterpret.d, _dinterpret.d)\n * Documentation:  https://dlang.org/phobos/dmd_dinterpret.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dinterpret.d\n */\n\nmodule dmd.dinterpret;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.apply;\nimport dmd.arraytypes;\nimport dmd.attrib;\nimport dmd.builtin;\nimport dmd.constfold;\nimport dmd.ctfeexpr;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.initsem;\nimport dmd.mtype;\nimport dmd.root.array;\nimport dmd.root.rootobject;\nimport dmd.statement;\nimport dmd.tokens;\nimport dmd.utf;\nimport dmd.visitor;\n\n/*************************************\n * Entry point for CTFE.\n * A compile-time result is required. Give an error if not possible.\n *\n * `e` must be semantically valid expression. In other words, it should not\n * contain any `ErrorExp`s in it. But, CTFE interpretation will cross over\n * functions and may invoke a function that contains `ErrorStatement` in its body.\n * If that, the \"CTFE failed because of previous errors\" error is raised.\n */\npublic Expression ctfeInterpret(Expression e)\n{\n    if (e.op == TOK.error)\n        return e;\n    assert(e.type); // https://issues.dlang.org/show_bug.cgi?id=14642\n    //assert(e.type.ty != Terror);    // FIXME\n    if (e.type.ty == Terror)\n        return new ErrorExp();\n\n    // This code is outside a function, but still needs to be compiled\n    // (there are compiler-generated temporary variables such as __dollar).\n    // However, this will only be run once and can then be discarded.\n    auto ctfeCodeGlobal = CompiledCtfeFunction(null);\n    ctfeCodeGlobal.callingloc = e.loc;\n    ctfeCodeGlobal.onExpression(e);\n\n    Expression result = interpret(e, null);\n\n    if (!CTFEExp.isCantExp(result))\n        result = scrubReturnValue(e.loc, result);\n    if (CTFEExp.isCantExp(result))\n        result = new ErrorExp();\n\n    return result;\n}\n\n/* Run CTFE on the expression, but allow the expression to be a TypeExp\n *  or a tuple containing a TypeExp. (This is required by pragma(msg)).\n */\npublic Expression ctfeInterpretForPragmaMsg(Expression e)\n{\n    if (e.op == TOK.error || e.op == TOK.type)\n        return e;\n\n    // It's also OK for it to be a function declaration (happens only with\n    // __traits(getOverloads))\n    if (e.op == TOK.variable && (cast(VarExp)e).var.isFuncDeclaration())\n    {\n        return e;\n    }\n\n    if (e.op != TOK.tuple)\n        return e.ctfeInterpret();\n\n    // Tuples need to be treated separately, since they are\n    // allowed to contain a TypeExp in this case.\n\n    TupleExp tup = cast(TupleExp)e;\n    Expressions* expsx = null;\n    for (size_t i = 0; i < tup.exps.dim; ++i)\n    {\n        Expression g = (*tup.exps)[i];\n        Expression h = g;\n        h = ctfeInterpretForPragmaMsg(g);\n        if (h != g)\n        {\n            if (!expsx)\n            {\n                expsx = new Expressions(tup.exps.dim);\n                for (size_t j = 0; j < tup.exps.dim; j++)\n                    (*expsx)[j] = (*tup.exps)[j];\n            }\n            (*expsx)[i] = h;\n        }\n    }\n    if (expsx)\n    {\n        auto te = new TupleExp(e.loc, expsx);\n        expandTuples(te.exps);\n        te.type = new TypeTuple(te.exps);\n        return te;\n    }\n    return e;\n}\n\npublic extern (C++) Expression getValue(VarDeclaration vd)\n{\n    return ctfeStack.getValue(vd);\n}\n\n\n// CTFE diagnostic information\npublic extern (C++) void printCtfePerformanceStats()\n{\n    debug (SHOWPERFORMANCE)\n    {\n        printf(\"        ---- CTFE Performance ----\\n\");\n        printf(\"max call depth = %d\\tmax stack = %d\\n\", CtfeStatus.maxCallDepth, ctfeStack.maxStackUsage());\n        printf(\"array allocs = %d\\tassignments = %d\\n\\n\", CtfeStatus.numArrayAllocs, CtfeStatus.numAssignments);\n    }\n}\n\n/*********\n * Typesafe PIMPL idiom so we can keep CompiledCtfeFunction private.\n */\nstruct CompiledCtfeFunctionPimpl\n{\n    private CompiledCtfeFunction* pimpl;\n    private alias pimpl this;\n}\n\n/* ================================================ Implementation ======================================= */\n\nprivate:\n\nenum CtfeGoal : int\n{\n    ctfeNeedRvalue,     // Must return an Rvalue (== CTFE value)\n    ctfeNeedLvalue,     // Must return an Lvalue (== CTFE reference)\n    ctfeNeedNothing,    // The return value is not required\n}\n\nalias ctfeNeedRvalue = CtfeGoal.ctfeNeedRvalue;\nalias ctfeNeedLvalue = CtfeGoal.ctfeNeedLvalue;\nalias ctfeNeedNothing = CtfeGoal.ctfeNeedNothing;\n\n//debug = LOG;\n//debug = LOGASSIGN;\n//debug = LOGCOMPILE;\n//debug = SHOWPERFORMANCE;\n\n// Maximum allowable recursive function calls in CTFE\nenum CTFE_RECURSION_LIMIT = 1000;\n\n/**\n The values of all CTFE variables\n */\nstruct CtfeStack\n{\nprivate:\n    /* The stack. Every declaration we encounter is pushed here,\n     * together with the VarDeclaration, and the previous\n     * stack address of that variable, so that we can restore it\n     * when we leave the stack frame.\n     * Note that when a function is forward referenced, the interpreter must\n     * run semantic3, and that may start CTFE again with a NULL istate. Thus\n     * the stack might not be empty when CTFE begins.\n     *\n     * Ctfe Stack addresses are just 0-based integers, but we save\n     * them as 'void *' because Array can only do pointers.\n     */\n    Expressions values;         // values on the stack\n    VarDeclarations vars;       // corresponding variables\n    Array!(void*) savedId;      // id of the previous state of that var\n\n    Array!(void*) frames;       // all previous frame pointers\n    Expressions savedThis;      // all previous values of localThis\n\n    /* Global constants get saved here after evaluation, so we never\n     * have to redo them. This saves a lot of time and memory.\n     */\n    Expressions globalValues;   // values of global constants\n\n    size_t framepointer;        // current frame pointer\n    size_t maxStackPointer;     // most stack we've ever used\n    Expression localThis;       // value of 'this', or NULL if none\n\npublic:\n    extern (C++) size_t stackPointer()\n    {\n        return values.dim;\n    }\n\n    // The current value of 'this', or NULL if none\n    extern (C++) Expression getThis()\n    {\n        return localThis;\n    }\n\n    // Largest number of stack positions we've used\n    extern (C++) size_t maxStackUsage()\n    {\n        return maxStackPointer;\n    }\n\n    // Start a new stack frame, using the provided 'this'.\n    extern (C++) void startFrame(Expression thisexp)\n    {\n        frames.push(cast(void*)cast(size_t)framepointer);\n        savedThis.push(localThis);\n        framepointer = stackPointer();\n        localThis = thisexp;\n    }\n\n    extern (C++) void endFrame()\n    {\n        size_t oldframe = cast(size_t)frames[frames.dim - 1];\n        localThis = savedThis[savedThis.dim - 1];\n        popAll(framepointer);\n        framepointer = oldframe;\n        frames.setDim(frames.dim - 1);\n        savedThis.setDim(savedThis.dim - 1);\n    }\n\n    extern (C++) bool isInCurrentFrame(VarDeclaration v)\n    {\n        if (v.isDataseg() && !v.isCTFE())\n            return false; // It's a global\n        return v.ctfeAdrOnStack >= framepointer;\n    }\n\n    extern (C++) Expression getValue(VarDeclaration v)\n    {\n        if ((v.isDataseg() || v.storage_class & STC.manifest) && !v.isCTFE())\n        {\n            assert(v.ctfeAdrOnStack >= 0 && v.ctfeAdrOnStack < globalValues.dim);\n            return globalValues[v.ctfeAdrOnStack];\n        }\n        assert(v.ctfeAdrOnStack >= 0 && v.ctfeAdrOnStack < stackPointer());\n        return values[v.ctfeAdrOnStack];\n    }\n\n    extern (C++) void setValue(VarDeclaration v, Expression e)\n    {\n        assert(!v.isDataseg() || v.isCTFE());\n        assert(v.ctfeAdrOnStack >= 0 && v.ctfeAdrOnStack < stackPointer());\n        values[v.ctfeAdrOnStack] = e;\n    }\n\n    extern (C++) void push(VarDeclaration v)\n    {\n        assert(!v.isDataseg() || v.isCTFE());\n        if (v.ctfeAdrOnStack != cast(size_t)-1 && v.ctfeAdrOnStack >= framepointer)\n        {\n            // Already exists in this frame, reuse it.\n            values[v.ctfeAdrOnStack] = null;\n            return;\n        }\n        savedId.push(cast(void*)cast(size_t)v.ctfeAdrOnStack);\n        v.ctfeAdrOnStack = cast(int)values.dim;\n        vars.push(v);\n        values.push(null);\n    }\n\n    extern (C++) void pop(VarDeclaration v)\n    {\n        assert(!v.isDataseg() || v.isCTFE());\n        assert(!(v.storage_class & (STC.ref_ | STC.out_)));\n        int oldid = v.ctfeAdrOnStack;\n        v.ctfeAdrOnStack = cast(int)cast(size_t)savedId[oldid];\n        if (v.ctfeAdrOnStack == values.dim - 1)\n        {\n            values.pop();\n            vars.pop();\n            savedId.pop();\n        }\n    }\n\n    extern (C++) void popAll(size_t stackpointer)\n    {\n        if (stackPointer() > maxStackPointer)\n            maxStackPointer = stackPointer();\n        assert(values.dim >= stackpointer);\n        for (size_t i = stackpointer; i < values.dim; ++i)\n        {\n            VarDeclaration v = vars[i];\n            v.ctfeAdrOnStack = cast(int)cast(size_t)savedId[i];\n        }\n        values.setDim(stackpointer);\n        vars.setDim(stackpointer);\n        savedId.setDim(stackpointer);\n    }\n\n    extern (C++) void saveGlobalConstant(VarDeclaration v, Expression e)\n    {\n        assert(v._init && (v.isConst() || v.isImmutable() || v.storage_class & STC.manifest) && !v.isCTFE());\n        v.ctfeAdrOnStack = cast(int)globalValues.dim;\n        globalValues.push(e);\n    }\n}\n\nprivate struct InterState\n{\n    InterState* caller;     // calling function's InterState\n    FuncDeclaration fd;     // function being interpreted\n    Statement start;        // if !=NULL, start execution at this statement\n\n    /* target of CTFEExp result; also\n     * target of labelled CTFEExp or\n     * CTFEExp. (null if no label).\n     */\n    Statement gotoTarget;\n}\n\nprivate __gshared CtfeStack ctfeStack;\n\n/***********************************************************\n * CTFE-object code for a single function\n *\n * Currently only counts the number of local variables in the function\n */\nstruct CompiledCtfeFunction\n{\n    FuncDeclaration func; // Function being compiled, NULL if global scope\n    int numVars; // Number of variables declared in this function\n    Loc callingloc;\n\n    extern (D) this(FuncDeclaration f)\n    {\n        func = f;\n    }\n\n    extern (C++) void onDeclaration(VarDeclaration v)\n    {\n        //printf(\"%s CTFE declare %s\\n\", v.loc.toChars(), v.toChars());\n        ++numVars;\n    }\n\n    extern (C++) void onExpression(Expression e)\n    {\n        extern (C++) final class VarWalker : StoppableVisitor\n        {\n            alias visit = typeof(super).visit;\n        public:\n            CompiledCtfeFunction* ccf;\n\n            extern (D) this(CompiledCtfeFunction* ccf)\n            {\n                this.ccf = ccf;\n            }\n\n            override void visit(Expression e)\n            {\n            }\n\n            override void visit(ErrorExp e)\n            {\n                // Currently there's a front-end bug: silent errors\n                // can occur inside delegate literals inside is(typeof()).\n                // Suppress the check in this case.\n                if (global.gag && ccf.func)\n                {\n                    stop = 1;\n                    return;\n                }\n                .error(e.loc, \"CTFE internal error: ErrorExp in `%s`\\n\", ccf.func ? ccf.func.loc.toChars() : ccf.callingloc.toChars());\n                assert(0);\n            }\n\n            override void visit(DeclarationExp e)\n            {\n                VarDeclaration v = e.declaration.isVarDeclaration();\n                if (!v)\n                    return;\n                TupleDeclaration td = v.toAlias().isTupleDeclaration();\n                if (td)\n                {\n                    if (!td.objects)\n                        return;\n                    for (size_t i = 0; i < td.objects.dim; ++i)\n                    {\n                        RootObject o = td.objects.tdata()[i];\n                        Expression ex = isExpression(o);\n                        DsymbolExp s = (ex && ex.op == TOK.dSymbol) ? cast(DsymbolExp)ex : null;\n                        assert(s);\n                        VarDeclaration v2 = s.s.isVarDeclaration();\n                        assert(v2);\n                        if (!v2.isDataseg() || v2.isCTFE())\n                            ccf.onDeclaration(v2);\n                    }\n                }\n                else if (!(v.isDataseg() || v.storage_class & STC.manifest) || v.isCTFE())\n                    ccf.onDeclaration(v);\n                Dsymbol s = v.toAlias();\n                if (s == v && !v.isStatic() && v._init)\n                {\n                    ExpInitializer ie = v._init.isExpInitializer();\n                    if (ie)\n                        ccf.onExpression(ie.exp);\n                }\n            }\n\n            override void visit(IndexExp e)\n            {\n                if (e.lengthVar)\n                    ccf.onDeclaration(e.lengthVar);\n            }\n\n            override void visit(SliceExp e)\n            {\n                if (e.lengthVar)\n                    ccf.onDeclaration(e.lengthVar);\n            }\n        }\n\n        scope VarWalker v = new VarWalker(&this);\n        walkPostorder(e, v);\n    }\n}\n\nprivate extern (C++) final class CtfeCompiler : SemanticTimeTransitiveVisitor\n{\n    alias visit = SemanticTimeTransitiveVisitor.visit;\npublic:\n    CompiledCtfeFunction* ccf;\n\n    extern (D) this(CompiledCtfeFunction* ccf)\n    {\n        this.ccf = ccf;\n    }\n\n    override void visit(Statement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s Statement::ctfeCompile %s\\n\", s.loc.toChars(), s.toChars());\n        }\n        assert(0);\n    }\n\n    override void visit(ExpStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s ExpStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        if (s.exp)\n            ccf.onExpression(s.exp);\n    }\n\n    override void visit(IfStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s IfStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        ccf.onExpression(s.condition);\n        if (s.ifbody)\n            ctfeCompile(s.ifbody);\n        if (s.elsebody)\n            ctfeCompile(s.elsebody);\n    }\n\n    override void visit(OnScopeStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s OnScopeStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        // rewritten to try/catch/finally\n        assert(0);\n    }\n\n    override void visit(DoStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s DoStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        ccf.onExpression(s.condition);\n        if (s._body)\n            ctfeCompile(s._body);\n    }\n\n    override void visit(WhileStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s WhileStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        // rewritten to ForStatement\n        assert(0);\n    }\n\n    override void visit(ForStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s ForStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        if (s._init)\n            ctfeCompile(s._init);\n        if (s.condition)\n            ccf.onExpression(s.condition);\n        if (s.increment)\n            ccf.onExpression(s.increment);\n        if (s._body)\n            ctfeCompile(s._body);\n    }\n\n    override void visit(ForeachStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s ForeachStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        // rewritten for ForStatement\n        assert(0);\n    }\n\n    override void visit(SwitchStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s SwitchStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        ccf.onExpression(s.condition);\n        // Note that the body contains the the Case and Default\n        // statements, so we only need to compile the expressions\n        for (size_t i = 0; i < s.cases.dim; i++)\n        {\n            ccf.onExpression((*s.cases)[i].exp);\n        }\n        if (s._body)\n            ctfeCompile(s._body);\n    }\n\n    override void visit(CaseStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s CaseStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        if (s.statement)\n            ctfeCompile(s.statement);\n    }\n\n    override void visit(GotoDefaultStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s GotoDefaultStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n    }\n\n    override void visit(GotoCaseStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s GotoCaseStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n    }\n\n    override void visit(SwitchErrorStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s SwitchErrorStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n    }\n\n    override void visit(ReturnStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s ReturnStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        if (s.exp)\n            ccf.onExpression(s.exp);\n    }\n\n    override void visit(BreakStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s BreakStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n    }\n\n    override void visit(ContinueStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s ContinueStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n    }\n\n    override void visit(WithStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s WithStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        // If it is with(Enum) {...}, just execute the body.\n        if (s.exp.op == TOK.scope_ || s.exp.op == TOK.type)\n        {\n        }\n        else\n        {\n            ccf.onDeclaration(s.wthis);\n            ccf.onExpression(s.exp);\n        }\n        if (s._body)\n            ctfeCompile(s._body);\n    }\n\n    override void visit(TryCatchStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s TryCatchStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        if (s._body)\n            ctfeCompile(s._body);\n        for (size_t i = 0; i < s.catches.dim; i++)\n        {\n            Catch ca = (*s.catches)[i];\n            if (ca.var)\n                ccf.onDeclaration(ca.var);\n            if (ca.handler)\n                ctfeCompile(ca.handler);\n        }\n    }\n\n    override void visit(ThrowStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s ThrowStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        ccf.onExpression(s.exp);\n    }\n\n    override void visit(GotoStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s GotoStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n    }\n\n    override void visit(ImportStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s ImportStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        // Contains no variables or executable code\n    }\n\n    override void visit(ForeachRangeStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s ForeachRangeStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        // rewritten for ForStatement\n        assert(0);\n    }\n\n    override void visit(AsmStatement s)\n    {\n        debug (LOGCOMPILE)\n        {\n            printf(\"%s AsmStatement::ctfeCompile\\n\", s.loc.toChars());\n        }\n        // we can't compile asm statements\n    }\n\n    void ctfeCompile(Statement s)\n    {\n        s.accept(this);\n    }\n}\n\n/*************************************\n * Compile this function for CTFE.\n * At present, this merely allocates variables.\n */\nprivate void ctfeCompile(FuncDeclaration fd)\n{\n    debug (LOGCOMPILE)\n    {\n        printf(\"\\n%s FuncDeclaration::ctfeCompile %s\\n\", fd.loc.toChars(), fd.toChars());\n    }\n    assert(!fd.ctfeCode);\n    assert(!fd.semantic3Errors);\n    assert(fd.semanticRun == PASS.semantic3done);\n\n    fd.ctfeCode = new CompiledCtfeFunction(fd);\n    if (fd.parameters)\n    {\n        Type tb = fd.type.toBasetype();\n        assert(tb.ty == Tfunction);\n        for (size_t i = 0; i < fd.parameters.dim; i++)\n        {\n            VarDeclaration v = (*fd.parameters)[i];\n            fd.ctfeCode.onDeclaration(v);\n        }\n    }\n    if (fd.vresult)\n        fd.ctfeCode.onDeclaration(fd.vresult);\n    scope CtfeCompiler v = new CtfeCompiler(fd.ctfeCode);\n    v.ctfeCompile(fd.fbody);\n}\n\n/*************************************\n * Attempt to interpret a function given the arguments.\n * Input:\n *      istate     state for calling function (NULL if none)\n *      arguments  function arguments\n *      thisarg    'this', if a needThis() function, NULL if not.\n *\n * Return result expression if successful, TOK.cantExpression if not,\n * or CTFEExp if function returned void.\n */\nprivate Expression interpretFunction(FuncDeclaration fd, InterState* istate, Expressions* arguments, Expression thisarg)\n{\n    debug (LOG)\n    {\n        printf(\"\\n********\\n%s FuncDeclaration::interpret(istate = %p) %s\\n\", fd.loc.toChars(), istate, fd.toChars());\n    }\n    if (fd.semanticRun == PASS.semantic3)\n    {\n        fd.error(\"circular dependency. Functions cannot be interpreted while being compiled\");\n        return CTFEExp.cantexp;\n    }\n    if (!fd.functionSemantic3())\n        return CTFEExp.cantexp;\n    if (fd.semanticRun < PASS.semantic3done)\n        return CTFEExp.cantexp;\n\n    // CTFE-compile the function\n    if (!fd.ctfeCode)\n        ctfeCompile(fd);\n\n    Type tb = fd.type.toBasetype();\n    assert(tb.ty == Tfunction);\n    TypeFunction tf = cast(TypeFunction)tb;\n    if (tf.varargs && arguments && ((fd.parameters && arguments.dim != fd.parameters.dim) || (!fd.parameters && arguments.dim)))\n    {\n        fd.error(\"C-style variadic functions are not yet implemented in CTFE\");\n        return CTFEExp.cantexp;\n    }\n\n    // Nested functions always inherit the 'this' pointer from the parent,\n    // except for delegates. (Note that the 'this' pointer may be null).\n    // Func literals report isNested() even if they are in global scope,\n    // so we need to check that the parent is a function.\n    if (fd.isNested() && fd.toParent2().isFuncDeclaration() && !thisarg && istate)\n        thisarg = ctfeStack.getThis();\n\n    if (fd.needThis() && !thisarg)\n    {\n        // error, no this. Prevent segfault.\n        // Here should be unreachable by the strict 'this' check in front-end.\n        fd.error(\"need `this` to access member `%s`\", fd.toChars());\n        return CTFEExp.cantexp;\n    }\n\n    // Place to hold all the arguments to the function while\n    // we are evaluating them.\n    size_t dim = arguments ? arguments.dim : 0;\n    assert((fd.parameters ? fd.parameters.dim : 0) == dim);\n\n    /* Evaluate all the arguments to the function,\n     * store the results in eargs[]\n     */\n    Expressions eargs = Expressions(dim);\n    for (size_t i = 0; i < dim; i++)\n    {\n        Expression earg = (*arguments)[i];\n        Parameter fparam = Parameter.getNth(tf.parameters, i);\n\n        if (fparam.storageClass & (STC.out_ | STC.ref_))\n        {\n            if (!istate && (fparam.storageClass & STC.out_))\n            {\n                // initializing an out parameter involves writing to it.\n                earg.error(\"global `%s` cannot be passed as an `out` parameter at compile time\", earg.toChars());\n                return CTFEExp.cantexp;\n            }\n            // Convert all reference arguments into lvalue references\n            earg = interpret(earg, istate, ctfeNeedLvalue);\n            if (CTFEExp.isCantExp(earg))\n                return earg;\n        }\n        else if (fparam.storageClass & STC.lazy_)\n        {\n        }\n        else\n        {\n            /* Value parameters\n             */\n            Type ta = fparam.type.toBasetype();\n            if (ta.ty == Tsarray && earg.op == TOK.address)\n            {\n                /* Static arrays are passed by a simple pointer.\n                 * Skip past this to get at the actual arg.\n                 */\n                earg = (cast(AddrExp)earg).e1;\n            }\n            earg = interpret(earg, istate);\n            if (CTFEExp.isCantExp(earg))\n                return earg;\n\n            /* Struct literals are passed by value, but we don't need to\n             * copy them if they are passed as const\n             */\n            if (earg.op == TOK.structLiteral && !(fparam.storageClass & (STC.const_ | STC.immutable_)))\n                earg = copyLiteral(earg).copy();\n        }\n        if (earg.op == TOK.thrownException)\n        {\n            if (istate)\n                return earg;\n            (cast(ThrownExceptionExp)earg).generateUncaughtError();\n            return CTFEExp.cantexp;\n        }\n        eargs[i] = earg;\n    }\n\n    // Now that we've evaluated all the arguments, we can start the frame\n    // (this is the moment when the 'call' actually takes place).\n    InterState istatex;\n    istatex.caller = istate;\n    istatex.fd = fd;\n    ctfeStack.startFrame(thisarg);\n    if (fd.vthis && thisarg)\n    {\n        ctfeStack.push(fd.vthis);\n        setValue(fd.vthis, thisarg);\n    }\n\n    for (size_t i = 0; i < dim; i++)\n    {\n        Expression earg = eargs[i];\n        Parameter fparam = Parameter.getNth(tf.parameters, i);\n        VarDeclaration v = (*fd.parameters)[i];\n        debug (LOG)\n        {\n            printf(\"arg[%d] = %s\\n\", i, earg.toChars());\n        }\n        ctfeStack.push(v);\n\n        if ((fparam.storageClass & (STC.out_ | STC.ref_)) && earg.op == TOK.variable && (cast(VarExp)earg).var.toParent2() == fd)\n        {\n            VarDeclaration vx = (cast(VarExp)earg).var.isVarDeclaration();\n            if (!vx)\n            {\n                fd.error(\"cannot interpret `%s` as a `ref` parameter\", earg.toChars());\n                return CTFEExp.cantexp;\n            }\n\n            /* vx is a variable that is declared in fd.\n             * It means that fd is recursively called. e.g.\n             *\n             *  void fd(int n, ref int v = dummy) {\n             *      int vx;\n             *      if (n == 1) fd(2, vx);\n             *  }\n             *  fd(1);\n             *\n             * The old value of vx on the stack in fd(1)\n             * should be saved at the start of fd(2, vx) call.\n             */\n            int oldadr = vx.ctfeAdrOnStack;\n\n            ctfeStack.push(vx);\n            assert(!hasValue(vx)); // vx is made uninitialized\n\n            // https://issues.dlang.org/show_bug.cgi?id=14299\n            // v.ctfeAdrOnStack should be saved already\n            // in the stack before the overwrite.\n            v.ctfeAdrOnStack = oldadr;\n            assert(hasValue(v)); // ref parameter v should refer existing value.\n        }\n        else\n        {\n            // Value parameters and non-trivial references\n            setValueWithoutChecking(v, earg);\n        }\n        debug (LOG)\n        {\n            printf(\"interpreted arg[%d] = %s\\n\", i, earg.toChars());\n            showCtfeExpr(earg);\n        }\n        debug (LOGASSIGN)\n        {\n            printf(\"interpreted arg[%d] = %s\\n\", i, earg.toChars());\n            showCtfeExpr(earg);\n        }\n    }\n\n    if (fd.vresult)\n        ctfeStack.push(fd.vresult);\n\n    // Enter the function\n    ++CtfeStatus.callDepth;\n    if (CtfeStatus.callDepth > CtfeStatus.maxCallDepth)\n        CtfeStatus.maxCallDepth = CtfeStatus.callDepth;\n\n    Expression e = null;\n    while (1)\n    {\n        if (CtfeStatus.callDepth > CTFE_RECURSION_LIMIT)\n        {\n            // This is a compiler error. It must not be suppressed.\n            global.gag = 0;\n            fd.error(\"CTFE recursion limit exceeded\");\n            e = CTFEExp.cantexp;\n            break;\n        }\n        e = interpret(fd.fbody, &istatex);\n        if (CTFEExp.isCantExp(e))\n        {\n            debug (LOG)\n            {\n                printf(\"function body failed to interpret\\n\");\n            }\n        }\n\n        if (istatex.start)\n        {\n            fd.error(\"CTFE internal error: failed to resume at statement `%s`\", istatex.start.toChars());\n            return CTFEExp.cantexp;\n        }\n\n        /* This is how we deal with a recursive statement AST\n         * that has arbitrary goto statements in it.\n         * Bubble up a 'result' which is the target of the goto\n         * statement, then go recursively down the AST looking\n         * for that statement, then execute starting there.\n         */\n        if (CTFEExp.isGotoExp(e))\n        {\n            istatex.start = istatex.gotoTarget; // set starting statement\n            istatex.gotoTarget = null;\n        }\n        else\n        {\n            assert(!e || (e.op != TOK.continue_ && e.op != TOK.break_));\n            break;\n        }\n    }\n    // If fell off the end of a void function, return void\n    if (!e && tf.next.ty == Tvoid)\n        e = CTFEExp.voidexp;\n    if (tf.isref && e.op == TOK.variable && (cast(VarExp)e).var == fd.vthis)\n        e = thisarg;\n    assert(e !is null);\n\n    // Leave the function\n    --CtfeStatus.callDepth;\n\n    ctfeStack.endFrame();\n\n    // If it generated an uncaught exception, report error.\n    if (!istate && e.op == TOK.thrownException)\n    {\n        (cast(ThrownExceptionExp)e).generateUncaughtError();\n        e = CTFEExp.cantexp;\n    }\n\n    return e;\n}\n\nprivate extern (C++) final class Interpreter : Visitor\n{\n    alias visit = Visitor.visit;\npublic:\n    InterState* istate;\n    CtfeGoal goal;\n    Expression result;\n    UnionExp* pue;              // storage for `result`\n\n    extern (D) this(UnionExp* pue, InterState* istate, CtfeGoal goal)\n    {\n        this.pue = pue;\n        this.istate = istate;\n        this.goal = goal;\n    }\n\n    // If e is TOK.throw_exception or TOK.cantExpression,\n    // set it to 'result' and returns true.\n    bool exceptionOrCant(Expression e)\n    {\n        if (exceptionOrCantInterpret(e))\n        {\n            // Make sure e is not pointing to a stack temporary\n            result = (e.op == TOK.cantExpression) ? CTFEExp.cantexp : e;\n            return true;\n        }\n        return false;\n    }\n\n    static Expressions* copyArrayOnWrite(Expressions* exps, Expressions* original)\n    {\n        if (exps is original)\n        {\n            if (!original)\n                exps = new Expressions();\n            else\n                exps = original.copy();\n            ++CtfeStatus.numArrayAllocs;\n        }\n        return exps;\n    }\n\n    /******************************** Statement ***************************/\n\n    override void visit(Statement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s Statement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start)\n        {\n            if (istate.start != s)\n                return;\n            istate.start = null;\n        }\n\n        s.error(\"statement `%s` cannot be interpreted at compile time\", s.toChars());\n        result = CTFEExp.cantexp;\n    }\n\n    override void visit(ExpStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s ExpStatement::interpret(%s)\\n\", s.loc.toChars(), s.exp ? s.exp.toChars() : \"\");\n        }\n        if (istate.start)\n        {\n            if (istate.start != s)\n                return;\n            istate.start = null;\n        }\n\n        Expression e = interpret(pue, s.exp, istate, ctfeNeedNothing);\n        if (exceptionOrCant(e))\n            return;\n    }\n\n    override void visit(CompoundStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s CompoundStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n\n        const dim = s.statements ? s.statements.dim : 0;\n        foreach (i; 0 .. dim)\n        {\n            Statement sx = (*s.statements)[i];\n            result = interpret(pue, sx, istate);\n            if (result)\n                break;\n        }\n        debug (LOG)\n        {\n            printf(\"%s -CompoundStatement::interpret() %p\\n\", s.loc.toChars(), result);\n        }\n    }\n\n    override void visit(UnrolledLoopStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s UnrolledLoopStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n\n        const dim = s.statements ? s.statements.dim : 0;\n        foreach (i; 0 .. dim)\n        {\n            Statement sx = (*s.statements)[i];\n            Expression e = interpret(pue, sx, istate);\n            if (!e) // succeeds to interpret, or goto target was not found\n                continue;\n            if (exceptionOrCant(e))\n                return;\n            if (e.op == TOK.break_)\n            {\n                if (istate.gotoTarget && istate.gotoTarget != s)\n                {\n                    result = e; // break at a higher level\n                    return;\n                }\n                istate.gotoTarget = null;\n                result = null;\n                return;\n            }\n            if (e.op == TOK.continue_)\n            {\n                if (istate.gotoTarget && istate.gotoTarget != s)\n                {\n                    result = e; // continue at a higher level\n                    return;\n                }\n                istate.gotoTarget = null;\n                continue;\n            }\n\n            // expression from return statement, or thrown exception\n            result = e;\n            break;\n        }\n    }\n\n    override void visit(IfStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s IfStatement::interpret(%s)\\n\", s.loc.toChars(), s.condition.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n        if (istate.start)\n        {\n            Expression e = null;\n            e = interpret(s.ifbody, istate);\n            if (!e && istate.start)\n                e = interpret(s.elsebody, istate);\n            result = e;\n            return;\n        }\n\n        UnionExp ue = void;\n        Expression e = interpret(&ue, s.condition, istate);\n        assert(e);\n        if (exceptionOrCant(e))\n            return;\n\n        if (isTrueBool(e))\n            result = interpret(pue, s.ifbody, istate);\n        else if (e.isBool(false))\n            result = interpret(pue, s.elsebody, istate);\n        else\n        {\n            // no error, or assert(0)?\n            result = CTFEExp.cantexp;\n        }\n    }\n\n    override void visit(ScopeStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s ScopeStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n\n        result = interpret(pue, s.statement, istate);\n    }\n\n    /**\n     Given an expression e which is about to be returned from the current\n     function, generate an error if it contains pointers to local variables.\n\n     Only checks expressions passed by value (pointers to local variables\n     may already be stored in members of classes, arrays, or AAs which\n     were passed as mutable function parameters).\n     Returns:\n        true if it is safe to return, false if an error was generated.\n     */\n    static bool stopPointersEscaping(const ref Loc loc, Expression e)\n    {\n        if (!e.type.hasPointers())\n            return true;\n        if (isPointer(e.type))\n        {\n            Expression x = e;\n            if (e.op == TOK.address)\n                x = (cast(AddrExp)e).e1;\n            VarDeclaration v;\n            while (x.op == TOK.variable && (v = (cast(VarExp)x).var.isVarDeclaration()) !is null)\n            {\n                if (v.storage_class & STC.ref_)\n                {\n                    x = getValue(v);\n                    if (e.op == TOK.address)\n                        (cast(AddrExp)e).e1 = x;\n                    continue;\n                }\n                if (ctfeStack.isInCurrentFrame(v))\n                {\n                    error(loc, \"returning a pointer to a local stack variable\");\n                    return false;\n                }\n                else\n                    break;\n            }\n            // TODO: If it is a TOK.dotVariable or TOK.index, we should check that it is not\n            // pointing to a local struct or static array.\n        }\n        if (e.op == TOK.structLiteral)\n        {\n            StructLiteralExp se = cast(StructLiteralExp)e;\n            return stopPointersEscapingFromArray(loc, se.elements);\n        }\n        if (e.op == TOK.arrayLiteral)\n        {\n            return stopPointersEscapingFromArray(loc, (cast(ArrayLiteralExp)e).elements);\n        }\n        if (e.op == TOK.assocArrayLiteral)\n        {\n            AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)e;\n            if (!stopPointersEscapingFromArray(loc, aae.keys))\n                return false;\n            return stopPointersEscapingFromArray(loc, aae.values);\n        }\n        return true;\n    }\n\n    // Check all members of an array for escaping local variables. Return false if error\n    static bool stopPointersEscapingFromArray(const ref Loc loc, Expressions* elems)\n    {\n        for (size_t i = 0; i < elems.dim; i++)\n        {\n            Expression m = (*elems)[i];\n            if (!m)\n                continue;\n            if (!stopPointersEscaping(loc, m))\n                return false;\n        }\n        return true;\n    }\n\n    override void visit(ReturnStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s ReturnStatement::interpret(%s)\\n\", s.loc.toChars(), s.exp ? s.exp.toChars() : \"\");\n        }\n        if (istate.start)\n        {\n            if (istate.start != s)\n                return;\n            istate.start = null;\n        }\n\n        if (!s.exp)\n        {\n            result = CTFEExp.voidexp;\n            return;\n        }\n\n        assert(istate && istate.fd && istate.fd.type && istate.fd.type.ty == Tfunction);\n        TypeFunction tf = cast(TypeFunction)istate.fd.type;\n\n        /* If the function returns a ref AND it's been called from an assignment,\n         * we need to return an lvalue. Otherwise, just do an (rvalue) interpret.\n         */\n        if (tf.isref)\n        {\n            result = interpret(pue, s.exp, istate, ctfeNeedLvalue);\n            return;\n        }\n        if (tf.next && tf.next.ty == Tdelegate && istate.fd.closureVars.dim > 0)\n        {\n            // To support this, we need to copy all the closure vars\n            // into the delegate literal.\n            s.error(\"closures are not yet supported in CTFE\");\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        // We need to treat pointers specially, because TOK.symbolOffset can be used to\n        // return a value OR a pointer\n        Expression e = interpret(pue, s.exp, istate);\n        if (exceptionOrCant(e))\n            return;\n\n        // Disallow returning pointers to stack-allocated variables (bug 7876)\n        if (!stopPointersEscaping(s.loc, e))\n        {\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        if (needToCopyLiteral(e))\n            e = copyLiteral(e).copy();\n        debug (LOGASSIGN)\n        {\n            printf(\"RETURN %s\\n\", s.loc.toChars());\n            showCtfeExpr(e);\n        }\n        result = e;\n    }\n\n    static Statement findGotoTarget(InterState* istate, Identifier ident)\n    {\n        Statement target = null;\n        if (ident)\n        {\n            LabelDsymbol label = istate.fd.searchLabel(ident);\n            assert(label && label.statement);\n            LabelStatement ls = label.statement;\n            target = ls.gotoTarget ? ls.gotoTarget : ls.statement;\n        }\n        return target;\n    }\n\n    override void visit(BreakStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s BreakStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start)\n        {\n            if (istate.start != s)\n                return;\n            istate.start = null;\n        }\n\n        istate.gotoTarget = findGotoTarget(istate, s.ident);\n        result = CTFEExp.breakexp;\n    }\n\n    override void visit(ContinueStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s ContinueStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start)\n        {\n            if (istate.start != s)\n                return;\n            istate.start = null;\n        }\n\n        istate.gotoTarget = findGotoTarget(istate, s.ident);\n        result = CTFEExp.continueexp;\n    }\n\n    override void visit(WhileStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"WhileStatement::interpret()\\n\");\n        }\n        assert(0); // rewritten to ForStatement\n    }\n\n    override void visit(DoStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s DoStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n\n        while (1)\n        {\n            Expression e = interpret(s._body, istate);\n            if (!e && istate.start) // goto target was not found\n                return;\n            assert(!istate.start);\n\n            if (exceptionOrCant(e))\n                return;\n            if (e && e.op == TOK.break_)\n            {\n                if (istate.gotoTarget && istate.gotoTarget != s)\n                {\n                    result = e; // break at a higher level\n                    return;\n                }\n                istate.gotoTarget = null;\n                break;\n            }\n            if (e && e.op == TOK.continue_)\n            {\n                if (istate.gotoTarget && istate.gotoTarget != s)\n                {\n                    result = e; // continue at a higher level\n                    return;\n                }\n                istate.gotoTarget = null;\n                e = null;\n            }\n            if (e)\n            {\n                result = e; // bubbled up from ReturnStatement\n                return;\n            }\n\n            UnionExp ue = void;\n            e = interpret(&ue, s.condition, istate);\n            if (exceptionOrCant(e))\n                return;\n            if (!e.isConst())\n            {\n                result = CTFEExp.cantexp;\n                return;\n            }\n            if (e.isBool(false))\n                break;\n            assert(isTrueBool(e));\n        }\n        assert(result is null);\n    }\n\n    override void visit(ForStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s ForStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n\n        UnionExp ueinit = void;\n        Expression ei = interpret(&ueinit, s._init, istate);\n        if (exceptionOrCant(ei))\n            return;\n        assert(!ei); // s.init never returns from function, or jumps out from it\n\n        while (1)\n        {\n            if (s.condition && !istate.start)\n            {\n                UnionExp ue = void;\n                Expression e = interpret(&ue, s.condition, istate);\n                if (exceptionOrCant(e))\n                    return;\n                if (e.isBool(false))\n                    break;\n                assert(isTrueBool(e));\n            }\n\n            Expression e = interpret(pue, s._body, istate);\n            if (!e && istate.start) // goto target was not found\n                return;\n            assert(!istate.start);\n\n            if (exceptionOrCant(e))\n                return;\n            if (e && e.op == TOK.break_)\n            {\n                if (istate.gotoTarget && istate.gotoTarget != s)\n                {\n                    result = e; // break at a higher level\n                    return;\n                }\n                istate.gotoTarget = null;\n                break;\n            }\n            if (e && e.op == TOK.continue_)\n            {\n                if (istate.gotoTarget && istate.gotoTarget != s)\n                {\n                    result = e; // continue at a higher level\n                    return;\n                }\n                istate.gotoTarget = null;\n                e = null;\n            }\n            if (e)\n            {\n                result = e; // bubbled up from ReturnStatement\n                return;\n            }\n\n            UnionExp uei = void;\n            e = interpret(&uei, s.increment, istate, ctfeNeedNothing);\n            if (exceptionOrCant(e))\n                return;\n        }\n        assert(result is null);\n    }\n\n    override void visit(ForeachStatement s)\n    {\n        assert(0); // rewritten to ForStatement\n    }\n\n    override void visit(ForeachRangeStatement s)\n    {\n        assert(0); // rewritten to ForStatement\n    }\n\n    override void visit(SwitchStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s SwitchStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n        if (istate.start)\n        {\n            Expression e = interpret(s._body, istate);\n            if (istate.start) // goto target was not found\n                return;\n            if (exceptionOrCant(e))\n                return;\n            if (e && e.op == TOK.break_)\n            {\n                if (istate.gotoTarget && istate.gotoTarget != s)\n                {\n                    result = e; // break at a higher level\n                    return;\n                }\n                istate.gotoTarget = null;\n                e = null;\n            }\n            result = e;\n            return;\n        }\n\n        UnionExp uecond = void;\n        Expression econdition = interpret(&uecond, s.condition, istate);\n        if (exceptionOrCant(econdition))\n            return;\n\n        Statement scase = null;\n        size_t dim = s.cases ? s.cases.dim : 0;\n        for (size_t i = 0; i < dim; i++)\n        {\n            CaseStatement cs = (*s.cases)[i];\n            UnionExp uecase = void;\n            Expression ecase = interpret(&uecase, cs.exp, istate);\n            if (exceptionOrCant(ecase))\n                return;\n            if (ctfeEqual(cs.exp.loc, TOK.equal, econdition, ecase))\n            {\n                scase = cs;\n                break;\n            }\n        }\n        if (!scase)\n        {\n            if (s.hasNoDefault)\n                s.error(\"no `default` or `case` for `%s` in `switch` statement\", econdition.toChars());\n            scase = s.sdefault;\n        }\n\n        assert(scase);\n\n        /* Jump to scase\n         */\n        istate.start = scase;\n        Expression e = interpret(pue, s._body, istate);\n        assert(!istate.start); // jump must not fail\n        if (e && e.op == TOK.break_)\n        {\n            if (istate.gotoTarget && istate.gotoTarget != s)\n            {\n                result = e; // break at a higher level\n                return;\n            }\n            istate.gotoTarget = null;\n            e = null;\n        }\n        result = e;\n    }\n\n    override void visit(CaseStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s CaseStatement::interpret(%s) this = %p\\n\", s.loc.toChars(), s.exp.toChars(), s);\n        }\n        if (istate.start == s)\n            istate.start = null;\n\n        result = interpret(pue, s.statement, istate);\n    }\n\n    override void visit(DefaultStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s DefaultStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n\n        result = interpret(pue, s.statement, istate);\n    }\n\n    override void visit(GotoStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s GotoStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start)\n        {\n            if (istate.start != s)\n                return;\n            istate.start = null;\n        }\n\n        assert(s.label && s.label.statement);\n        istate.gotoTarget = s.label.statement;\n        result = CTFEExp.gotoexp;\n    }\n\n    override void visit(GotoCaseStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s GotoCaseStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start)\n        {\n            if (istate.start != s)\n                return;\n            istate.start = null;\n        }\n\n        assert(s.cs);\n        istate.gotoTarget = s.cs;\n        result = CTFEExp.gotoexp;\n    }\n\n    override void visit(GotoDefaultStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s GotoDefaultStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start)\n        {\n            if (istate.start != s)\n                return;\n            istate.start = null;\n        }\n\n        assert(s.sw && s.sw.sdefault);\n        istate.gotoTarget = s.sw.sdefault;\n        result = CTFEExp.gotoexp;\n    }\n\n    override void visit(LabelStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s LabelStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n\n        result = interpret(pue, s.statement, istate);\n    }\n\n    override void visit(TryCatchStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s TryCatchStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n        if (istate.start)\n        {\n            Expression e = null;\n            e = interpret(pue, s._body, istate);\n            for (size_t i = 0; i < s.catches.dim; i++)\n            {\n                if (e || !istate.start) // goto target was found\n                    break;\n                Catch ca = (*s.catches)[i];\n                e = interpret(pue, ca.handler, istate);\n            }\n            result = e;\n            return;\n        }\n\n        Expression e = interpret(s._body, istate);\n\n        // An exception was thrown\n        if (e && e.op == TOK.thrownException)\n        {\n            ThrownExceptionExp ex = cast(ThrownExceptionExp)e;\n            Type extype = ex.thrown.originalClass().type;\n\n            // Search for an appropriate catch clause.\n            for (size_t i = 0; i < s.catches.dim; i++)\n            {\n                Catch ca = (*s.catches)[i];\n                Type catype = ca.type;\n                if (!catype.equals(extype) && !catype.isBaseOf(extype, null))\n                    continue;\n\n                // Execute the handler\n                if (ca.var)\n                {\n                    ctfeStack.push(ca.var);\n                    setValue(ca.var, ex.thrown);\n                }\n                e = interpret(ca.handler, istate);\n                if (CTFEExp.isGotoExp(e))\n                {\n                    /* This is an optimization that relies on the locality of the jump target.\n                     * If the label is in the same catch handler, the following scan\n                     * would find it quickly and can reduce jump cost.\n                     * Otherwise, the catch block may be unnnecessary scanned again\n                     * so it would make CTFE speed slower.\n                     */\n                    InterState istatex = *istate;\n                    istatex.start = istate.gotoTarget; // set starting statement\n                    istatex.gotoTarget = null;\n                    Expression eh = interpret(ca.handler, &istatex);\n                    if (!istatex.start)\n                    {\n                        istate.gotoTarget = null;\n                        e = eh;\n                    }\n                }\n                break;\n            }\n        }\n        result = e;\n    }\n\n    static bool isAnErrorException(ClassDeclaration cd)\n    {\n        return cd == ClassDeclaration.errorException || ClassDeclaration.errorException.isBaseOf(cd, null);\n    }\n\n    static ThrownExceptionExp chainExceptions(ThrownExceptionExp oldest, ThrownExceptionExp newest)\n    {\n        debug (LOG)\n        {\n            printf(\"Collided exceptions %s %s\\n\", oldest.thrown.toChars(), newest.thrown.toChars());\n        }\n        // Little sanity check to make sure it's really a Throwable\n        ClassReferenceExp boss = oldest.thrown;\n        const next = 4;                         // index of Throwable.next\n        assert((*boss.value.elements)[next].type.ty == Tclass); // Throwable.next\n        ClassReferenceExp collateral = newest.thrown;\n        if (isAnErrorException(collateral.originalClass()) && !isAnErrorException(boss.originalClass()))\n        {\n            /* Find the index of the Error.bypassException field\n             */\n            auto bypass = next + 1;\n            if ((*collateral.value.elements)[bypass].type.ty == Tuns32)\n                bypass += 1;  // skip over _refcount field\n            assert((*collateral.value.elements)[bypass].type.ty == Tclass);\n\n            // The new exception bypass the existing chain\n            (*collateral.value.elements)[bypass] = boss;\n            return newest;\n        }\n        while ((*boss.value.elements)[next].op == TOK.classReference)\n        {\n            boss = cast(ClassReferenceExp)(*boss.value.elements)[next];\n        }\n        (*boss.value.elements)[next] = collateral;\n        return oldest;\n    }\n\n    override void visit(TryFinallyStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s TryFinallyStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n        if (istate.start)\n        {\n            Expression e = null;\n            e = interpret(pue, s._body, istate);\n            // Jump into/out from finalbody is disabled in semantic analysis.\n            // and jump inside will be handled by the ScopeStatement == finalbody.\n            result = e;\n            return;\n        }\n\n        Expression ex = interpret(s._body, istate);\n        if (CTFEExp.isCantExp(ex))\n        {\n            result = ex;\n            return;\n        }\n        while (CTFEExp.isGotoExp(ex))\n        {\n            // If the goto target is within the body, we must not interpret the finally statement,\n            // because that will call destructors for objects within the scope, which we should not do.\n            InterState istatex = *istate;\n            istatex.start = istate.gotoTarget; // set starting statement\n            istatex.gotoTarget = null;\n            Expression bex = interpret(s._body, &istatex);\n            if (istatex.start)\n            {\n                // The goto target is outside the current scope.\n                break;\n            }\n            // The goto target was within the body.\n            if (CTFEExp.isCantExp(bex))\n            {\n                result = bex;\n                return;\n            }\n            *istate = istatex;\n            ex = bex;\n        }\n\n        Expression ey = interpret(s.finalbody, istate);\n        if (CTFEExp.isCantExp(ey))\n        {\n            result = ey;\n            return;\n        }\n        if (ey && ey.op == TOK.thrownException)\n        {\n            // Check for collided exceptions\n            if (ex && ex.op == TOK.thrownException)\n                ex = chainExceptions(cast(ThrownExceptionExp)ex, cast(ThrownExceptionExp)ey);\n            else\n                ex = ey;\n        }\n        result = ex;\n    }\n\n    override void visit(ThrowStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s ThrowStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start)\n        {\n            if (istate.start != s)\n                return;\n            istate.start = null;\n        }\n\n        Expression e = interpret(s.exp, istate);\n        if (exceptionOrCant(e))\n            return;\n\n        assert(e.op == TOK.classReference);\n        result = new ThrownExceptionExp(s.loc, cast(ClassReferenceExp)e);\n    }\n\n    override void visit(OnScopeStatement s)\n    {\n        assert(0);\n    }\n\n    override void visit(WithStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s WithStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start == s)\n            istate.start = null;\n        if (istate.start)\n        {\n            result = s._body ? interpret(s._body, istate) : null;\n            return;\n        }\n\n        // If it is with(Enum) {...}, just execute the body.\n        if (s.exp.op == TOK.scope_ || s.exp.op == TOK.type)\n        {\n            result = interpret(pue, s._body, istate);\n            return;\n        }\n\n        Expression e = interpret(s.exp, istate);\n        if (exceptionOrCant(e))\n            return;\n\n        if (s.wthis.type.ty == Tpointer && s.exp.type.ty != Tpointer)\n        {\n            e = new AddrExp(s.loc, e, s.wthis.type);\n        }\n        ctfeStack.push(s.wthis);\n        setValue(s.wthis, e);\n        e = interpret(s._body, istate);\n        if (CTFEExp.isGotoExp(e))\n        {\n            /* This is an optimization that relies on the locality of the jump target.\n             * If the label is in the same WithStatement, the following scan\n             * would find it quickly and can reduce jump cost.\n             * Otherwise, the statement body may be unnnecessary scanned again\n             * so it would make CTFE speed slower.\n             */\n            InterState istatex = *istate;\n            istatex.start = istate.gotoTarget; // set starting statement\n            istatex.gotoTarget = null;\n            Expression ex = interpret(s._body, &istatex);\n            if (!istatex.start)\n            {\n                istate.gotoTarget = null;\n                e = ex;\n            }\n        }\n        ctfeStack.pop(s.wthis);\n        result = e;\n    }\n\n    override void visit(AsmStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"%s AsmStatement::interpret()\\n\", s.loc.toChars());\n        }\n        if (istate.start)\n        {\n            if (istate.start != s)\n                return;\n            istate.start = null;\n        }\n        s.error(\"`asm` statements cannot be interpreted at compile time\");\n        result = CTFEExp.cantexp;\n    }\n\n    override void visit(ImportStatement s)\n    {\n        debug (LOG)\n        {\n            printf(\"ImportStatement::interpret()\\n\");\n        }\n        if (istate.start)\n        {\n            if (istate.start != s)\n                return;\n            istate.start = null;\n        }\n    }\n\n    /******************************** Expression ***************************/\n\n    override void visit(Expression e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s Expression::interpret() '%s' %s\\n\", e.loc.toChars(), Token.toChars(e.op), e.toChars());\n            printf(\"type = %s\\n\", e.type.toChars());\n            e.print();\n        }\n        e.error(\"cannot interpret `%s` at compile time\", e.toChars());\n        result = CTFEExp.cantexp;\n    }\n\n    override void visit(ThisExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s ThisExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        if (goal == ctfeNeedLvalue)\n        {\n            // We might end up here with istate being zero\n            // https://issues.dlang.org/show_bug.cgi?id=16382\n            if (istate && istate.fd.vthis)\n            {\n                result = new VarExp(e.loc, istate.fd.vthis);\n                result.type = e.type;\n            }\n            else\n                result = e;\n            return;\n        }\n\n        result = ctfeStack.getThis();\n        if (result)\n        {\n            assert(result.op == TOK.structLiteral || result.op == TOK.classReference);\n            return;\n        }\n        e.error(\"value of `this` is not known at compile time\");\n        result = CTFEExp.cantexp;\n    }\n\n    override void visit(NullExp e)\n    {\n        result = e;\n    }\n\n    override void visit(IntegerExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s IntegerExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        result = e;\n    }\n\n    override void visit(RealExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s RealExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        result = e;\n    }\n\n    override void visit(ComplexExp e)\n    {\n        result = e;\n    }\n\n    override void visit(StringExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s StringExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        /* Attempts to modify string literals are prevented\n         * in BinExp::interpretAssignCommon.\n         */\n        result = e;\n    }\n\n    override void visit(FuncExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s FuncExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        result = e;\n    }\n\n    override void visit(SymOffExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s SymOffExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        if (e.var.isFuncDeclaration() && e.offset == 0)\n        {\n            result = e;\n            return;\n        }\n        if (isTypeInfo_Class(e.type) && e.offset == 0)\n        {\n            result = e;\n            return;\n        }\n        if (e.type.ty != Tpointer)\n        {\n            // Probably impossible\n            e.error(\"cannot interpret `%s` at compile time\", e.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        Type pointee = (cast(TypePointer)e.type).next;\n        if (e.var.isThreadlocal())\n        {\n            e.error(\"cannot take address of thread-local variable %s at compile time\", e.var.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        // Check for taking an address of a shared variable.\n        // If the shared variable is an array, the offset might not be zero.\n        Type fromType = null;\n        if (e.var.type.ty == Tarray || e.var.type.ty == Tsarray)\n        {\n            fromType = (cast(TypeArray)e.var.type).next;\n        }\n        if (e.var.isDataseg() && ((e.offset == 0 && isSafePointerCast(e.var.type, pointee)) || (fromType && isSafePointerCast(fromType, pointee))))\n        {\n            result = e;\n            return;\n        }\n\n        Expression val = getVarExp(e.loc, istate, e.var, goal);\n        if (exceptionOrCant(val))\n            return;\n        if (val.type.ty == Tarray || val.type.ty == Tsarray)\n        {\n            // Check for unsupported type painting operations\n            Type elemtype = (cast(TypeArray)val.type).next;\n            d_uns64 elemsize = elemtype.size();\n\n            // It's OK to cast from fixed length to dynamic array, eg &int[3] to int[]*\n            if (val.type.ty == Tsarray && pointee.ty == Tarray && elemsize == pointee.nextOf().size())\n            {\n                emplaceExp!(AddrExp)(pue, e.loc, val, e.type);\n                result = pue.exp();\n                return;\n            }\n\n            // It's OK to cast from fixed length to fixed length array, eg &int[n] to int[d]*.\n            if (val.type.ty == Tsarray && pointee.ty == Tsarray && elemsize == pointee.nextOf().size())\n            {\n                size_t d = cast(size_t)(cast(TypeSArray)pointee).dim.toInteger();\n                Expression elwr = new IntegerExp(e.loc, e.offset / elemsize, Type.tsize_t);\n                Expression eupr = new IntegerExp(e.loc, e.offset / elemsize + d, Type.tsize_t);\n\n                // Create a CTFE pointer &val[ofs..ofs+d]\n                auto se = new SliceExp(e.loc, val, elwr, eupr);\n                se.type = pointee;\n                emplaceExp!(AddrExp)(pue, e.loc, se, e.type);\n                result = pue.exp();\n                return;\n            }\n\n            if (!isSafePointerCast(elemtype, pointee))\n            {\n                // It's also OK to cast from &string to string*.\n                if (e.offset == 0 && isSafePointerCast(e.var.type, pointee))\n                {\n                    // Create a CTFE pointer &var\n                    auto ve = new VarExp(e.loc, e.var);\n                    ve.type = elemtype;\n                    emplaceExp!(AddrExp)(pue, e.loc, ve, e.type);\n                    result = pue.exp();\n                    return;\n                }\n                e.error(\"reinterpreting cast from `%s` to `%s` is not supported in CTFE\", val.type.toChars(), e.type.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n\n            const dinteger_t sz = pointee.size();\n            dinteger_t indx = e.offset / sz;\n            assert(sz * indx == e.offset);\n            Expression aggregate = null;\n            if (val.op == TOK.arrayLiteral || val.op == TOK.string_)\n            {\n                aggregate = val;\n            }\n            else if (val.op == TOK.slice)\n            {\n                aggregate = (cast(SliceExp)val).e1;\n                UnionExp uelwr = void;\n                Expression lwr = interpret(&uelwr, (cast(SliceExp)val).lwr, istate);\n                indx += lwr.toInteger();\n            }\n            if (aggregate)\n            {\n                // Create a CTFE pointer &aggregate[ofs]\n                auto ofs = new IntegerExp(e.loc, indx, Type.tsize_t);\n                auto ei = new IndexExp(e.loc, aggregate, ofs);\n                ei.type = elemtype;\n                emplaceExp!(AddrExp)(pue, e.loc, ei, e.type);\n                result = pue.exp();\n                return;\n            }\n        }\n        else if (e.offset == 0 && isSafePointerCast(e.var.type, pointee))\n        {\n            // Create a CTFE pointer &var\n            auto ve = new VarExp(e.loc, e.var);\n            ve.type = e.var.type;\n            emplaceExp!(AddrExp)(pue, e.loc, ve, e.type);\n            result = pue.exp();\n            return;\n        }\n\n        e.error(\"cannot convert `&%s` to `%s` at compile time\", e.var.type.toChars(), e.type.toChars());\n        result = CTFEExp.cantexp;\n    }\n\n    override void visit(AddrExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s AddrExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        if (e.e1.op == TOK.variable)\n        {\n            Declaration decl = (cast(VarExp)e.e1).var;\n\n            // We cannot take the address of an imported symbol at compile time\n            if (decl.isImportedSymbol()) {\n                e.error(\"cannot take address of imported symbol `%s` at compile time\", decl.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n\n            if (decl.isDataseg()) {\n                // Normally this is already done by optimize()\n                // Do it here in case optimize(WANTvalue) wasn't run before CTFE\n                result = new SymOffExp(e.loc, (cast(VarExp)e.e1).var, 0);\n                result.type = e.type;\n                return;\n            }\n        }\n        auto er = interpret(e.e1, istate, ctfeNeedLvalue);\n        if (er.op == TOK.variable && (cast(VarExp)er).var == istate.fd.vthis)\n            er = interpret(er, istate);\n        if (exceptionOrCant(er))\n            return;\n\n        // Return a simplified address expression\n        emplaceExp!(AddrExp)(pue, e.loc, er, e.type);\n        result = pue.exp();\n    }\n\n    override void visit(DelegateExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s DelegateExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        // TODO: Really we should create a CTFE-only delegate expression\n        // of a pointer and a funcptr.\n\n        // If it is &nestedfunc, just return it\n        // TODO: We should save the context pointer\n        if (e.e1.op == TOK.variable && (cast(VarExp)e.e1).var == e.func)\n        {\n            result = e;\n            return;\n        }\n\n        auto er = interpret(e.e1, istate);\n        if (exceptionOrCant(er))\n            return;\n        if (er == e.e1)\n        {\n            // If it has already been CTFE'd, just return it\n            result = e;\n        }\n        else\n        {\n            emplaceExp!(DelegateExp)(pue, e.loc, er, e.func, false);\n            result = pue.exp();\n            result.type = e.type;\n        }\n    }\n\n    static Expression getVarExp(const ref Loc loc, InterState* istate, Declaration d, CtfeGoal goal)\n    {\n        Expression e = CTFEExp.cantexp;\n        if (VarDeclaration v = d.isVarDeclaration())\n        {\n            /* Magic variable __ctfe always returns true when interpreting\n             */\n            if (v.ident == Id.ctfe)\n                return new IntegerExp(loc, 1, Type.tbool);\n\n            if (!v.originalType && v.semanticRun < PASS.semanticdone) // semantic() not yet run\n            {\n                v.dsymbolSemantic(null);\n                if (v.type.ty == Terror)\n                    return CTFEExp.cantexp;\n            }\n\n            if ((v.isConst() || v.isImmutable() || v.storage_class & STC.manifest) && !hasValue(v) && v._init && !v.isCTFE())\n            {\n                if (v.inuse)\n                {\n                    error(loc, \"circular initialization of %s `%s`\", v.kind(), v.toPrettyChars());\n                    return CTFEExp.cantexp;\n                }\n                if (v._scope)\n                {\n                    v.inuse++;\n                    v._init = v._init.initializerSemantic(v._scope, v.type, INITinterpret); // might not be run on aggregate members\n                    v.inuse--;\n                }\n                e = v._init.initializerToExpression(v.type);\n                if (!e)\n                    return CTFEExp.cantexp;\n                assert(e.type);\n\n                if (e.op == TOK.construct || e.op == TOK.blit)\n                {\n                    AssignExp ae = cast(AssignExp)e;\n                    e = ae.e2;\n                }\n\n                if (e.op == TOK.error)\n                {\n                    // FIXME: Ultimately all errors should be detected in prior semantic analysis stage.\n                }\n                else if (v.isDataseg() || (v.storage_class & STC.manifest))\n                {\n                    /* https://issues.dlang.org/show_bug.cgi?id=14304\n                     * e is a value that is not yet owned by CTFE.\n                     * Mark as \"cached\", and use it directly during interpretation.\n                     */\n                    e = scrubCacheValue(v.loc, e);\n                    ctfeStack.saveGlobalConstant(v, e);\n                }\n                else\n                {\n                    v.inuse++;\n                    e = interpret(e, istate);\n                    v.inuse--;\n                    if (CTFEExp.isCantExp(e) && !global.gag && !CtfeStatus.stackTraceCallsToSuppress)\n                        errorSupplemental(loc, \"while evaluating %s.init\", v.toChars());\n                    if (exceptionOrCantInterpret(e))\n                        return e;\n                }\n            }\n            else if (v.isCTFE() && !hasValue(v))\n            {\n                if (v._init && v.type.size() != 0)\n                {\n                    if (v._init.isVoidInitializer())\n                    {\n                        // var should have been initialized when it was created\n                        error(loc, \"CTFE internal error: trying to access uninitialized var\");\n                        assert(0);\n                    }\n                    e = v._init.initializerToExpression();\n                }\n                else\n                    e = v.type.defaultInitLiteral(e.loc);\n\n                e = interpret(e, istate);\n            }\n            else if (!(v.isDataseg() || v.storage_class & STC.manifest) && !v.isCTFE() && !istate)\n            {\n                error(loc, \"variable `%s` cannot be read at compile time\", v.toChars());\n                return CTFEExp.cantexp;\n            }\n            else\n            {\n                e = hasValue(v) ? getValue(v) : null;\n                if (!e && !v.isCTFE() && v.isDataseg())\n                {\n                    error(loc, \"static variable `%s` cannot be read at compile time\", v.toChars());\n                    return CTFEExp.cantexp;\n                }\n                if (!e)\n                {\n                    assert(!(v._init && v._init.isVoidInitializer()));\n                    // CTFE initiated from inside a function\n                    error(loc, \"variable `%s` cannot be read at compile time\", v.toChars());\n                    return CTFEExp.cantexp;\n                }\n                if (e.op == TOK.void_)\n                {\n                    VoidInitExp ve = cast(VoidInitExp)e;\n                    error(loc, \"cannot read uninitialized variable `%s` in ctfe\", v.toPrettyChars());\n                    errorSupplemental(ve.var.loc, \"`%s` was uninitialized and used before set\", ve.var.toChars());\n                    return CTFEExp.cantexp;\n                }\n                if (goal != ctfeNeedLvalue && (v.isRef() || v.isOut()))\n                    e = interpret(e, istate, goal);\n            }\n            if (!e)\n                e = CTFEExp.cantexp;\n        }\n        else if (SymbolDeclaration s = d.isSymbolDeclaration())\n        {\n            // Struct static initializers, for example\n            e = s.dsym.type.defaultInitLiteral(loc);\n            if (e.op == TOK.error)\n                error(loc, \"CTFE failed because of previous errors in `%s.init`\", s.toChars());\n            e = e.expressionSemantic(null);\n            if (e.op == TOK.error)\n                e = CTFEExp.cantexp;\n            else // Convert NULL to CTFEExp\n                e = interpret(e, istate, goal);\n        }\n        else\n            error(loc, \"cannot interpret declaration `%s` at compile time\", d.toChars());\n        return e;\n    }\n\n    override void visit(VarExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s VarExp::interpret() `%s`, goal = %d\\n\", e.loc.toChars(), e.toChars(), goal);\n        }\n        if (e.var.isFuncDeclaration())\n        {\n            result = e;\n            return;\n        }\n\n        if (goal == ctfeNeedLvalue)\n        {\n            VarDeclaration v = e.var.isVarDeclaration();\n            if (v && !v.isDataseg() && !v.isCTFE() && !istate)\n            {\n                e.error(\"variable `%s` cannot be read at compile time\", v.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            if (v && !hasValue(v))\n            {\n                if (!v.isCTFE() && v.isDataseg())\n                    e.error(\"static variable `%s` cannot be read at compile time\", v.toChars());\n                else // CTFE initiated from inside a function\n                    e.error(\"variable `%s` cannot be read at compile time\", v.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            if (v && (v.storage_class & (STC.out_ | STC.ref_)) && hasValue(v))\n            {\n                // Strip off the nest of ref variables\n                Expression ev = getValue(v);\n                if (ev.op == TOK.variable || ev.op == TOK.index || ev.op == TOK.dotVariable)\n                {\n                    result = interpret(pue, ev, istate, goal);\n                    return;\n                }\n            }\n            result = e;\n            return;\n        }\n        result = getVarExp(e.loc, istate, e.var, goal);\n        if (exceptionOrCant(result))\n            return;\n        if ((e.var.storage_class & (STC.ref_ | STC.out_)) == 0 && e.type.baseElemOf().ty != Tstruct)\n        {\n            /* Ultimately, STC.ref_|STC.out_ check should be enough to see the\n             * necessity of type repainting. But currently front-end paints\n             * non-ref struct variables by the const type.\n             *\n             *  auto foo(ref const S cs);\n             *  S s;\n             *  foo(s); // VarExp('s') will have const(S)\n             */\n            // A VarExp may include an implicit cast. It must be done explicitly.\n            result = paintTypeOntoLiteral(e.type, result);\n        }\n    }\n\n    override void visit(DeclarationExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s DeclarationExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        Dsymbol s = e.declaration;\n        if (VarDeclaration v = s.isVarDeclaration())\n        {\n            if (TupleDeclaration td = v.toAlias().isTupleDeclaration())\n            {\n                result = null;\n\n                // Reserve stack space for all tuple members\n                if (!td.objects)\n                    return;\n                for (size_t i = 0; i < td.objects.dim; ++i)\n                {\n                    RootObject o = (*td.objects)[i];\n                    Expression ex = isExpression(o);\n                    DsymbolExp ds = (ex && ex.op == TOK.dSymbol) ? cast(DsymbolExp)ex : null;\n                    VarDeclaration v2 = ds ? ds.s.isVarDeclaration() : null;\n                    assert(v2);\n                    if (v2.isDataseg() && !v2.isCTFE())\n                        continue;\n\n                    ctfeStack.push(v2);\n                    if (v2._init)\n                    {\n                        Expression einit;\n                        if (ExpInitializer ie = v2._init.isExpInitializer())\n                        {\n                            einit = interpret(ie.exp, istate, goal);\n                            if (exceptionOrCant(einit))\n                                return;\n                        }\n                        else if (v2._init.isVoidInitializer())\n                        {\n                            einit = voidInitLiteral(v2.type, v2).copy();\n                        }\n                        else\n                        {\n                            e.error(\"declaration `%s` is not yet implemented in CTFE\", e.toChars());\n                            result = CTFEExp.cantexp;\n                            return;\n                        }\n                        setValue(v2, einit);\n                    }\n                }\n                return;\n            }\n            if (v.isStatic())\n            {\n                // Just ignore static variables which aren't read or written yet\n                result = null;\n                return;\n            }\n            if (!(v.isDataseg() || v.storage_class & STC.manifest) || v.isCTFE())\n                ctfeStack.push(v);\n            if (v._init)\n            {\n                if (ExpInitializer ie = v._init.isExpInitializer())\n                {\n                    result = interpret(ie.exp, istate, goal);\n                }\n                else if (v._init.isVoidInitializer())\n                {\n                    result = voidInitLiteral(v.type, v).copy();\n                    // There is no AssignExp for void initializers,\n                    // so set it here.\n                    setValue(v, result);\n                }\n                else\n                {\n                    e.error(\"declaration `%s` is not yet implemented in CTFE\", e.toChars());\n                    result = CTFEExp.cantexp;\n                }\n            }\n            else if (v.type.size() == 0)\n            {\n                // Zero-length arrays don't need an initializer\n                result = v.type.defaultInitLiteral(e.loc);\n            }\n            else\n            {\n                e.error(\"variable `%s` cannot be modified at compile time\", v.toChars());\n                result = CTFEExp.cantexp;\n            }\n            return;\n        }\n        if (s.isAttribDeclaration() || s.isTemplateMixin() || s.isTupleDeclaration())\n        {\n            // Check for static struct declarations, which aren't executable\n            AttribDeclaration ad = e.declaration.isAttribDeclaration();\n            if (ad && ad.decl && ad.decl.dim == 1)\n            {\n                Dsymbol sparent = (*ad.decl)[0];\n                if (sparent.isAggregateDeclaration() || sparent.isTemplateDeclaration() || sparent.isAliasDeclaration())\n                {\n                    result = null;\n                    return; // static (template) struct declaration. Nothing to do.\n                }\n            }\n\n            // These can be made to work, too lazy now\n            e.error(\"declaration `%s` is not yet implemented in CTFE\", e.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        // Others should not contain executable code, so are trivial to evaluate\n        result = null;\n        debug (LOG)\n        {\n            printf(\"-DeclarationExp::interpret(%s): %p\\n\", e.toChars(), result);\n        }\n    }\n\n    override void visit(TypeidExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s TypeidExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        if (Type t = isType(e.obj))\n        {\n            result = e;\n            return;\n        }\n        if (Expression ex = isExpression(e.obj))\n        {\n            result = interpret(ex, istate);\n            if (exceptionOrCant(ex))\n                return;\n\n            if (result.op == TOK.null_)\n            {\n                e.error(\"null pointer dereference evaluating typeid. `%s` is `null`\", ex.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            if (result.op != TOK.classReference)\n            {\n                e.error(\"CTFE internal error: determining classinfo\");\n                result = CTFEExp.cantexp;\n                return;\n            }\n\n            ClassDeclaration cd = (cast(ClassReferenceExp)result).originalClass();\n            assert(cd);\n\n            emplaceExp!(TypeidExp)(pue, e.loc, cd.type);\n            result = pue.exp();\n            result.type = e.type;\n            return;\n        }\n        visit(cast(Expression)e);\n    }\n\n    override void visit(TupleExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s TupleExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        if (exceptionOrCant(interpret(e.e0, istate, ctfeNeedNothing)))\n            return;\n\n        auto expsx = e.exps;\n        for (size_t i = 0; i < expsx.dim; i++)\n        {\n            Expression exp = (*expsx)[i];\n            Expression ex = interpret(exp, istate);\n            if (exceptionOrCant(ex))\n                return;\n\n            // A tuple of assignments can contain void (Bug 5676).\n            if (goal == ctfeNeedNothing)\n                continue;\n            if (ex.op == TOK.voidExpression)\n            {\n                e.error(\"CTFE internal error: void element `%s` in tuple\", exp.toChars());\n                assert(0);\n            }\n\n            /* If any changes, do Copy On Write\n             */\n            if (ex !is exp)\n            {\n                expsx = copyArrayOnWrite(expsx, e.exps);\n                (*expsx)[i] = ex;\n            }\n        }\n\n        if (expsx !is e.exps)\n        {\n            expandTuples(expsx);\n            emplaceExp!(TupleExp)(pue, e.loc, expsx);\n            result = pue.exp();\n            result.type = new TypeTuple(expsx);\n        }\n        else\n            result = e;\n    }\n\n    override void visit(ArrayLiteralExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s ArrayLiteralExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        if (e.ownedByCtfe >= OwnedBy.ctfe) // We've already interpreted all the elements\n        {\n            result = e;\n            return;\n        }\n\n        Type tn = e.type.toBasetype().nextOf().toBasetype();\n        bool wantCopy = (tn.ty == Tsarray || tn.ty == Tstruct);\n\n        auto basis = interpret(e.basis, istate);\n        if (exceptionOrCant(basis))\n            return;\n\n        auto expsx = e.elements;\n        size_t dim = expsx ? expsx.dim : 0;\n        for (size_t i = 0; i < dim; i++)\n        {\n            Expression exp = (*expsx)[i];\n            Expression ex;\n            if (!exp)\n            {\n                ex = copyLiteral(basis).copy();\n            }\n            else\n            {\n                // segfault bug 6250\n                assert(exp.op != TOK.index || (cast(IndexExp)exp).e1 != e);\n\n                ex = interpret(exp, istate);\n                if (exceptionOrCant(ex))\n                    return;\n\n                /* Each elements should have distinct CTFE memory.\n                 *  int[1] z = 7;\n                 *  int[1][] pieces = [z,z];    // here\n                 */\n                if (wantCopy)\n                    ex = copyLiteral(ex).copy();\n            }\n\n            /* If any changes, do Copy On Write\n             */\n            if (ex !is exp)\n            {\n                expsx = copyArrayOnWrite(expsx, e.elements);\n                (*expsx)[i] = ex;\n            }\n        }\n\n        if (expsx !is e.elements)\n        {\n            // todo: all tuple expansions should go in semantic phase.\n            expandTuples(expsx);\n            if (expsx.dim != dim)\n            {\n                e.error(\"CTFE internal error: invalid array literal\");\n                result = CTFEExp.cantexp;\n                return;\n            }\n            emplaceExp!(ArrayLiteralExp)(pue, e.loc, e.type, basis, expsx);\n            auto ale = cast(ArrayLiteralExp)pue.exp();\n            ale.ownedByCtfe = OwnedBy.ctfe;\n            result = ale;\n        }\n        else if ((cast(TypeNext)e.type).next.mod & (MODFlags.const_ | MODFlags.immutable_))\n        {\n            // If it's immutable, we don't need to dup it\n            result = e;\n        }\n        else\n            result = copyLiteral(e).copy();\n    }\n\n    override void visit(AssocArrayLiteralExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s AssocArrayLiteralExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        if (e.ownedByCtfe >= OwnedBy.ctfe) // We've already interpreted all the elements\n        {\n            result = e;\n            return;\n        }\n\n        auto keysx = e.keys;\n        auto valuesx = e.values;\n        for (size_t i = 0; i < keysx.dim; i++)\n        {\n            auto ekey = (*keysx)[i];\n            auto evalue = (*valuesx)[i];\n\n            auto ek = interpret(ekey, istate);\n            if (exceptionOrCant(ek))\n                return;\n            auto ev = interpret(evalue, istate);\n            if (exceptionOrCant(ev))\n                return;\n\n            /* If any changes, do Copy On Write\n             */\n            if (ek !is ekey ||\n                ev !is evalue)\n            {\n                keysx = copyArrayOnWrite(keysx, e.keys);\n                valuesx = copyArrayOnWrite(valuesx, e.values);\n                (*keysx)[i] = ek;\n                (*valuesx)[i] = ev;\n            }\n        }\n        if (keysx !is e.keys)\n            expandTuples(keysx);\n        if (valuesx !is e.values)\n            expandTuples(valuesx);\n        if (keysx.dim != valuesx.dim)\n        {\n            e.error(\"CTFE internal error: invalid AA\");\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        /* Remove duplicate keys\n         */\n        for (size_t i = 1; i < keysx.dim; i++)\n        {\n            auto ekey = (*keysx)[i - 1];\n            for (size_t j = i; j < keysx.dim; j++)\n            {\n                auto ekey2 = (*keysx)[j];\n                if (!ctfeEqual(e.loc, TOK.equal, ekey, ekey2))\n                    continue;\n\n                // Remove ekey\n                keysx = copyArrayOnWrite(keysx, e.keys);\n                valuesx = copyArrayOnWrite(valuesx, e.values);\n                keysx.remove(i - 1);\n                valuesx.remove(i - 1);\n\n                i -= 1; // redo the i'th iteration\n                break;\n            }\n        }\n\n        if (keysx !is e.keys ||\n            valuesx !is e.values)\n        {\n            assert(keysx !is e.keys &&\n                   valuesx !is e.values);\n            auto aae = new AssocArrayLiteralExp(e.loc, keysx, valuesx);\n            aae.type = e.type;\n            aae.ownedByCtfe = OwnedBy.ctfe;\n            result = aae;\n        }\n        else\n            result = copyLiteral(e).copy();\n    }\n\n    override void visit(StructLiteralExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s StructLiteralExp::interpret() %s ownedByCtfe = %d\\n\", e.loc.toChars(), e.toChars(), e.ownedByCtfe);\n        }\n        if (e.ownedByCtfe >= OwnedBy.ctfe)\n        {\n            result = e;\n            return;\n        }\n\n        size_t dim = e.elements ? e.elements.dim : 0;\n        auto expsx = e.elements;\n\n        if (dim != e.sd.fields.dim)\n        {\n            // guaranteed by AggregateDeclaration.fill and TypeStruct.defaultInitLiteral\n            assert(e.sd.isNested() && dim == e.sd.fields.dim - 1);\n\n            /* If a nested struct has no initialized hidden pointer,\n             * set it to null to match the runtime behaviour.\n             */\n            auto ne = new NullExp(e.loc);\n            ne.type = e.sd.vthis.type;\n\n            expsx = copyArrayOnWrite(expsx, e.elements);\n            expsx.push(ne);\n            ++dim;\n        }\n        assert(dim == e.sd.fields.dim);\n\n        foreach (i; 0 .. dim)\n        {\n            auto v = e.sd.fields[i];\n            Expression exp = (*expsx)[i];\n            Expression ex;\n            if (!exp)\n            {\n                ex = voidInitLiteral(v.type, v).copy();\n            }\n            else\n            {\n                ex = interpret(exp, istate);\n                if (exceptionOrCant(ex))\n                    return;\n                if ((v.type.ty != ex.type.ty) && v.type.ty == Tsarray)\n                {\n                    // Block assignment from inside struct literals\n                    auto tsa = cast(TypeSArray)v.type;\n                    auto len = cast(size_t)tsa.dim.toInteger();\n                    ex = createBlockDuplicatedArrayLiteral(ex.loc, v.type, ex, len);\n                }\n            }\n\n            /* If any changes, do Copy On Write\n             */\n            if (ex !is exp)\n            {\n                expsx = copyArrayOnWrite(expsx, e.elements);\n                (*expsx)[i] = ex;\n            }\n        }\n\n        if (expsx !is e.elements)\n        {\n            expandTuples(expsx);\n            if (expsx.dim != e.sd.fields.dim)\n            {\n                e.error(\"CTFE internal error: invalid struct literal\");\n                result = CTFEExp.cantexp;\n                return;\n            }\n            emplaceExp!(StructLiteralExp)(pue, e.loc, e.sd, expsx);\n            auto sle = cast(StructLiteralExp)pue.exp();\n            sle.type = e.type;\n            sle.ownedByCtfe = OwnedBy.ctfe;\n            sle.origin = e.origin;\n            result = sle;\n        }\n        else\n            result = copyLiteral(e).copy();\n    }\n\n    // Create an array literal of type 'newtype' with dimensions given by\n    // 'arguments'[argnum..$]\n    static Expression recursivelyCreateArrayLiteral(const ref Loc loc, Type newtype, InterState* istate, Expressions* arguments, int argnum)\n    {\n        Expression lenExpr = interpret((*arguments)[argnum], istate);\n        if (exceptionOrCantInterpret(lenExpr))\n            return lenExpr;\n        size_t len = cast(size_t)lenExpr.toInteger();\n        Type elemType = (cast(TypeArray)newtype).next;\n        if (elemType.ty == Tarray && argnum < arguments.dim - 1)\n        {\n            Expression elem = recursivelyCreateArrayLiteral(loc, elemType, istate, arguments, argnum + 1);\n            if (exceptionOrCantInterpret(elem))\n                return elem;\n\n            auto elements = new Expressions(len);\n            for (size_t i = 0; i < len; i++)\n                (*elements)[i] = copyLiteral(elem).copy();\n            auto ae = new ArrayLiteralExp(loc, newtype, elements);\n            ae.ownedByCtfe = OwnedBy.ctfe;\n            return ae;\n        }\n        assert(argnum == arguments.dim - 1);\n        if (elemType.ty == Tchar || elemType.ty == Twchar || elemType.ty == Tdchar)\n        {\n            const ch = cast(dchar)elemType.defaultInitLiteral(loc).toInteger();\n            const sz = cast(ubyte)elemType.size();\n            return createBlockDuplicatedStringLiteral(loc, newtype, ch, len, sz);\n        }\n        else\n        {\n            auto el = interpret(elemType.defaultInitLiteral(loc), istate);\n            return createBlockDuplicatedArrayLiteral(loc, newtype, el, len);\n        }\n    }\n\n    override void visit(NewExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s NewExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        if (e.allocator)\n        {\n            e.error(\"member allocators not supported by CTFE\");\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        result = interpret(e.argprefix, istate, ctfeNeedNothing);\n        if (exceptionOrCant(result))\n            return;\n\n        if (e.newtype.ty == Tarray && e.arguments)\n        {\n            result = recursivelyCreateArrayLiteral(e.loc, e.newtype, istate, e.arguments, 0);\n            return;\n        }\n        if (e.newtype.toBasetype().ty == Tstruct)\n        {\n            if (e.member)\n            {\n                Expression se = e.newtype.defaultInitLiteral(e.loc);\n                se = interpret(se, istate);\n                if (exceptionOrCant(se))\n                    return;\n                result = interpretFunction(e.member, istate, e.arguments, se);\n\n                // Repaint as same as CallExp::interpret() does.\n                result.loc = e.loc;\n            }\n            else\n            {\n                StructDeclaration sd = (cast(TypeStruct)e.newtype.toBasetype()).sym;\n                auto exps = new Expressions();\n                exps.reserve(sd.fields.dim);\n                if (e.arguments)\n                {\n                    exps.setDim(e.arguments.dim);\n                    for (size_t i = 0; i < exps.dim; i++)\n                    {\n                        Expression ex = (*e.arguments)[i];\n                        ex = interpret(ex, istate);\n                        if (exceptionOrCant(ex))\n                            return;\n                        (*exps)[i] = ex;\n                    }\n                }\n                sd.fill(e.loc, exps, false);\n\n                auto se = new StructLiteralExp(e.loc, sd, exps, e.newtype);\n                se.type = e.newtype;\n                se.ownedByCtfe = OwnedBy.ctfe;\n                result = interpret(se, istate);\n            }\n            if (exceptionOrCant(result))\n                return;\n            emplaceExp!(AddrExp)(pue, e.loc, result, e.type);\n            result = pue.exp();\n            return;\n        }\n        if (e.newtype.toBasetype().ty == Tclass)\n        {\n            ClassDeclaration cd = (cast(TypeClass)e.newtype.toBasetype()).sym;\n            size_t totalFieldCount = 0;\n            for (ClassDeclaration c = cd; c; c = c.baseClass)\n                totalFieldCount += c.fields.dim;\n            auto elems = new Expressions(totalFieldCount);\n            size_t fieldsSoFar = totalFieldCount;\n            for (ClassDeclaration c = cd; c; c = c.baseClass)\n            {\n                fieldsSoFar -= c.fields.dim;\n                for (size_t i = 0; i < c.fields.dim; i++)\n                {\n                    VarDeclaration v = c.fields[i];\n                    if (v.inuse)\n                    {\n                        e.error(\"circular reference to `%s`\", v.toPrettyChars());\n                        result = CTFEExp.cantexp;\n                        return;\n                    }\n                    Expression m;\n                    if (v._init)\n                    {\n                        if (v._init.isVoidInitializer())\n                            m = voidInitLiteral(v.type, v).copy();\n                        else\n                            m = v.getConstInitializer(true);\n                    }\n                    else\n                        m = v.type.defaultInitLiteral(e.loc);\n                    if (exceptionOrCant(m))\n                        return;\n                    (*elems)[fieldsSoFar + i] = copyLiteral(m).copy();\n                }\n            }\n            // Hack: we store a ClassDeclaration instead of a StructDeclaration.\n            // We probably won't get away with this.\n            auto se = new StructLiteralExp(e.loc, cast(StructDeclaration)cd, elems, e.newtype);\n            se.ownedByCtfe = OwnedBy.ctfe;\n            Expression eref = new ClassReferenceExp(e.loc, se, e.type);\n            if (e.member)\n            {\n                // Call constructor\n                if (!e.member.fbody)\n                {\n                    Expression ctorfail = evaluateIfBuiltin(istate, e.loc, e.member, e.arguments, eref);\n                    if (ctorfail)\n                    {\n                        if (exceptionOrCant(ctorfail))\n                            return;\n                        result = eref;\n                        return;\n                    }\n                    e.member.error(\"`%s` cannot be constructed at compile time, because the constructor has no available source code\", e.newtype.toChars());\n                    result = CTFEExp.cantexp;\n                    return;\n                }\n                Expression ctorfail = interpretFunction(e.member, istate, e.arguments, eref);\n                if (exceptionOrCant(ctorfail))\n                    return;\n\n                /* https://issues.dlang.org/show_bug.cgi?id=14465\n                 * Repaint the loc, because a super() call\n                 * in the constructor modifies the loc of ClassReferenceExp\n                 * in CallExp::interpret().\n                 */\n                eref.loc = e.loc;\n            }\n            result = eref;\n            return;\n        }\n        if (e.newtype.toBasetype().isscalar())\n        {\n            Expression newval;\n            if (e.arguments && e.arguments.dim)\n                newval = (*e.arguments)[0];\n            else\n                newval = e.newtype.defaultInitLiteral(e.loc);\n            newval = interpret(newval, istate);\n            if (exceptionOrCant(newval))\n                return;\n\n            // Create a CTFE pointer &[newval][0]\n            auto elements = new Expressions(1);\n            (*elements)[0] = newval;\n            auto ae = new ArrayLiteralExp(e.loc, e.newtype.arrayOf(), elements);\n            ae.ownedByCtfe = OwnedBy.ctfe;\n\n            auto ei = new IndexExp(e.loc, ae, new IntegerExp(Loc.initial, 0, Type.tsize_t));\n            ei.type = e.newtype;\n            emplaceExp!(AddrExp)(pue, e.loc, ei, e.type);\n            result = pue.exp();\n            return;\n        }\n        e.error(\"cannot interpret `%s` at compile time\", e.toChars());\n        result = CTFEExp.cantexp;\n    }\n\n    override void visit(UnaExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s UnaExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        UnionExp ue = void;\n        Expression e1 = interpret(&ue, e.e1, istate);\n        if (exceptionOrCant(e1))\n            return;\n        switch (e.op)\n        {\n        case TOK.negate:\n            *pue = Neg(e.type, e1);\n            break;\n\n        case TOK.tilde:\n            *pue = Com(e.type, e1);\n            break;\n\n        case TOK.not:\n            *pue = Not(e.type, e1);\n            break;\n\n        case TOK.vector:\n            result = e;\n            return; // do nothing\n\n        default:\n            assert(0);\n        }\n        result = (*pue).exp();\n    }\n\n    override void visit(DotTypeExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s DotTypeExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        UnionExp ue = void;\n        Expression e1 = interpret(&ue, e.e1, istate);\n        if (exceptionOrCant(e1))\n            return;\n        if (e1 == e.e1)\n            result = e; // optimize: reuse this CTFE reference\n        else\n        {\n            auto edt = cast(DotTypeExp)e.copy();\n            edt.e1 = (e1 == ue.exp()) ? e1.copy() : e1; // don't return pointer to ue\n            result = edt;\n        }\n    }\n\n    extern (D) private void interpretCommon(BinExp e, fp_t fp)\n    {\n        debug (LOG)\n        {\n            printf(\"%s BinExp::interpretCommon() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        if (e.e1.type.ty == Tpointer && e.e2.type.ty == Tpointer && e.op == TOK.min)\n        {\n            UnionExp ue1 = void;\n            Expression e1 = interpret(&ue1, e.e1, istate);\n            if (exceptionOrCant(e1))\n                return;\n            UnionExp ue2 = void;\n            Expression e2 = interpret(&ue2, e.e2, istate);\n            if (exceptionOrCant(e2))\n                return;\n            *pue = pointerDifference(e.loc, e.type, e1, e2);\n            result = (*pue).exp();\n            return;\n        }\n        if (e.e1.type.ty == Tpointer && e.e2.type.isintegral())\n        {\n            UnionExp ue1 = void;\n            Expression e1 = interpret(&ue1, e.e1, istate);\n            if (exceptionOrCant(e1))\n                return;\n            UnionExp ue2 = void;\n            Expression e2 = interpret(&ue2, e.e2, istate);\n            if (exceptionOrCant(e2))\n                return;\n            *pue = pointerArithmetic(e.loc, e.op, e.type, e1, e2);\n            result = (*pue).exp();\n            return;\n        }\n        if (e.e2.type.ty == Tpointer && e.e1.type.isintegral() && e.op == TOK.add)\n        {\n            UnionExp ue1 = void;\n            Expression e1 = interpret(&ue1, e.e1, istate);\n            if (exceptionOrCant(e1))\n                return;\n            UnionExp ue2 = void;\n            Expression e2 = interpret(&ue2, e.e2, istate);\n            if (exceptionOrCant(e2))\n                return;\n            *pue = pointerArithmetic(e.loc, e.op, e.type, e2, e1);\n            result = (*pue).exp();\n            return;\n        }\n        if (e.e1.type.ty == Tpointer || e.e2.type.ty == Tpointer)\n        {\n            e.error(\"pointer expression `%s` cannot be interpreted at compile time\", e.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        bool evalOperand(UnionExp* pue, Expression ex, out Expression er)\n        {\n            er = interpret(pue, ex, istate);\n            if (exceptionOrCant(er))\n                return false;\n            if (er.isConst() != 1)\n            {\n                if (er.op == TOK.arrayLiteral)\n                    // Until we get it to work, issue a reasonable error message\n                    e.error(\"cannot interpret array literal expression `%s` at compile time\", e.toChars());\n                else\n                    e.error(\"CTFE internal error: non-constant value `%s`\", ex.toChars());\n                result = CTFEExp.cantexp;\n                return false;\n            }\n            return true;\n        }\n\n        UnionExp ue1 = void;\n        Expression e1;\n        if (!evalOperand(&ue1, e.e1, e1))\n            return;\n\n        UnionExp ue2 = void;\n        Expression e2;\n        if (!evalOperand(&ue2, e.e2, e2))\n            return;\n\n        if (e.op == TOK.rightShift || e.op == TOK.leftShift || e.op == TOK.unsignedRightShift)\n        {\n            const sinteger_t i2 = e2.toInteger();\n            const d_uns64 sz = e1.type.size() * 8;\n            if (i2 < 0 || i2 >= sz)\n            {\n                e.error(\"shift by %lld is outside the range 0..%llu\", i2, cast(ulong)sz - 1);\n                result = CTFEExp.cantexp;\n                return;\n            }\n        }\n        *pue = (*fp)(e.loc, e.type, e1, e2);\n        result = (*pue).exp();\n        if (CTFEExp.isCantExp(result))\n            e.error(\"`%s` cannot be interpreted at compile time\", e.toChars());\n    }\n\n    extern (D) private void interpretCompareCommon(BinExp e, fp2_t fp)\n    {\n        debug (LOG)\n        {\n            printf(\"%s BinExp::interpretCompareCommon() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        UnionExp ue1 = void;\n        UnionExp ue2 = void;\n        if (e.e1.type.ty == Tpointer && e.e2.type.ty == Tpointer)\n        {\n            Expression e1 = interpret(&ue1, e.e1, istate);\n            if (exceptionOrCant(e1))\n                return;\n            Expression e2 = interpret(&ue2, e.e2, istate);\n            if (exceptionOrCant(e2))\n                return;\n            //printf(\"e1 = %s %s, e2 = %s %s\\n\", e1.type.toChars(), e1.toChars(), e2.type.toChars(), e2.toChars());\n            dinteger_t ofs1, ofs2;\n            Expression agg1 = getAggregateFromPointer(e1, &ofs1);\n            Expression agg2 = getAggregateFromPointer(e2, &ofs2);\n            //printf(\"agg1 = %p %s, agg2 = %p %s\\n\", agg1, agg1.toChars(), agg2, agg2.toChars());\n            const cmp = comparePointers(e.op, agg1, ofs1, agg2, ofs2);\n            if (cmp == -1)\n            {\n                char dir = (e.op == TOK.greaterThan || e.op == TOK.greaterOrEqual) ? '<' : '>';\n                e.error(\"the ordering of pointers to unrelated memory blocks is indeterminate in CTFE. To check if they point to the same memory block, use both `>` and `<` inside `&&` or `||`, eg `%s && %s %c= %s + 1`\", e.toChars(), e.e1.toChars(), dir, e.e2.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            emplaceExp!(IntegerExp)(pue, e.loc, cmp, e.type);\n            result = (*pue).exp();\n            return;\n        }\n        Expression e1 = interpret(&ue1, e.e1, istate);\n        if (exceptionOrCant(e1))\n            return;\n        if (!isCtfeComparable(e1))\n        {\n            e.error(\"cannot compare `%s` at compile time\", e1.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        Expression e2 = interpret(&ue2, e.e2, istate);\n        if (exceptionOrCant(e2))\n            return;\n        if (!isCtfeComparable(e2))\n        {\n            e.error(\"cannot compare `%s` at compile time\", e2.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        const cmp = (*fp)(e.loc, e.op, e1, e2);\n        emplaceExp!(IntegerExp)(pue, e.loc, cmp, e.type);\n        result = (*pue).exp();\n    }\n\n    override void visit(BinExp e)\n    {\n        switch (e.op)\n        {\n        case TOK.add:\n            interpretCommon(e, &Add);\n            return;\n\n        case TOK.min:\n            interpretCommon(e, &Min);\n            return;\n\n        case TOK.mul:\n            interpretCommon(e, &Mul);\n            return;\n\n        case TOK.div:\n            interpretCommon(e, &Div);\n            return;\n\n        case TOK.mod:\n            interpretCommon(e, &Mod);\n            return;\n\n        case TOK.leftShift:\n            interpretCommon(e, &Shl);\n            return;\n\n        case TOK.rightShift:\n            interpretCommon(e, &Shr);\n            return;\n\n        case TOK.unsignedRightShift:\n            interpretCommon(e, &Ushr);\n            return;\n\n        case TOK.and:\n            interpretCommon(e, &And);\n            return;\n\n        case TOK.or:\n            interpretCommon(e, &Or);\n            return;\n\n        case TOK.xor:\n            interpretCommon(e, &Xor);\n            return;\n\n        case TOK.pow:\n            interpretCommon(e, &Pow);\n            return;\n\n        case TOK.equal:\n        case TOK.notEqual:\n            interpretCompareCommon(e, &ctfeEqual);\n            return;\n\n        case TOK.identity:\n        case TOK.notIdentity:\n            interpretCompareCommon(e, &ctfeIdentity);\n            return;\n\n        case TOK.lessThan:\n        case TOK.lessOrEqual:\n        case TOK.greaterThan:\n        case TOK.greaterOrEqual:\n            interpretCompareCommon(e, &ctfeCmp);\n            return;\n\n        default:\n            printf(\"be = '%s' %s at [%s]\\n\", Token.toChars(e.op), e.toChars(), e.loc.toChars());\n            assert(0);\n        }\n    }\n\n    /* Helper functions for BinExp::interpretAssignCommon\n     */\n    // Returns the variable which is eventually modified, or NULL if an rvalue.\n    // thisval is the current value of 'this'.\n    static VarDeclaration findParentVar(Expression e)\n    {\n        for (;;)\n        {\n            if (e.op == TOK.variable)\n                break;\n            if (e.op == TOK.index)\n                e = (cast(IndexExp)e).e1;\n            else if (e.op == TOK.dotVariable)\n                e = (cast(DotVarExp)e).e1;\n            else if (e.op == TOK.dotTemplateInstance)\n                e = (cast(DotTemplateInstanceExp)e).e1;\n            else if (e.op == TOK.slice)\n                e = (cast(SliceExp)e).e1;\n            else\n                return null;\n        }\n        VarDeclaration v = (cast(VarExp)e).var.isVarDeclaration();\n        assert(v);\n        return v;\n    }\n\n    extern (D) private void interpretAssignCommon(BinExp e, fp_t fp, int post = 0)\n    {\n        debug (LOG)\n        {\n            printf(\"%s BinExp::interpretAssignCommon() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        result = CTFEExp.cantexp;\n\n        Expression e1 = e.e1;\n        if (!istate)\n        {\n            e.error(\"value of `%s` is not known at compile time\", e1.toChars());\n            return;\n        }\n\n        ++CtfeStatus.numAssignments;\n\n        /* Before we begin, we need to know if this is a reference assignment\n         * (dynamic array, AA, or class) or a value assignment.\n         * Determining this for slice assignments are tricky: we need to know\n         * if it is a block assignment (a[] = e) rather than a direct slice\n         * assignment (a[] = b[]). Note that initializers of multi-dimensional\n         * static arrays can have 2D block assignments (eg, int[7][7] x = 6;).\n         * So we need to recurse to determine if it is a block assignment.\n         */\n        bool isBlockAssignment = false;\n        if (e1.op == TOK.slice)\n        {\n            // a[] = e can have const e. So we compare the naked types.\n            Type tdst = e1.type.toBasetype();\n            Type tsrc = e.e2.type.toBasetype();\n            while (tdst.ty == Tsarray || tdst.ty == Tarray)\n            {\n                tdst = (cast(TypeArray)tdst).next.toBasetype();\n                if (tsrc.equivalent(tdst))\n                {\n                    isBlockAssignment = true;\n                    break;\n                }\n            }\n        }\n\n        // ---------------------------------------\n        //      Deal with reference assignment\n        // ---------------------------------------\n        // If it is a construction of a ref variable, it is a ref assignment\n        if ((e.op == TOK.construct || e.op == TOK.blit) &&\n            ((cast(AssignExp)e).memset & MemorySet.referenceInit))\n        {\n            assert(!fp);\n\n            Expression newval = interpret(e.e2, istate, ctfeNeedLvalue);\n            if (exceptionOrCant(newval))\n                return;\n\n            VarDeclaration v = (cast(VarExp)e1).var.isVarDeclaration();\n            setValue(v, newval);\n\n            // Get the value to return. Note that 'newval' is an Lvalue,\n            // so if we need an Rvalue, we have to interpret again.\n            if (goal == ctfeNeedRvalue)\n                result = interpret(newval, istate);\n            else\n                result = e1; // VarExp is a CTFE reference\n            return;\n        }\n\n        if (fp)\n        {\n            while (e1.op == TOK.cast_)\n            {\n                CastExp ce = cast(CastExp)e1;\n                e1 = ce.e1;\n            }\n        }\n\n        // ---------------------------------------\n        //      Interpret left hand side\n        // ---------------------------------------\n        AssocArrayLiteralExp existingAA = null;\n        Expression lastIndex = null;\n        Expression oldval = null;\n        if (e1.op == TOK.index && (cast(IndexExp)e1).e1.type.toBasetype().ty == Taarray)\n        {\n            // ---------------------------------------\n            //      Deal with AA index assignment\n            // ---------------------------------------\n            /* This needs special treatment if the AA doesn't exist yet.\n             * There are two special cases:\n             * (1) If the AA is itself an index of another AA, we may need to create\n             *     multiple nested AA literals before we can insert the new value.\n             * (2) If the ultimate AA is null, no insertion happens at all. Instead,\n             *     we create nested AA literals, and change it into a assignment.\n             */\n            IndexExp ie = cast(IndexExp)e1;\n            int depth = 0; // how many nested AA indices are there?\n            while (ie.e1.op == TOK.index && (cast(IndexExp)ie.e1).e1.type.toBasetype().ty == Taarray)\n            {\n                assert(ie.modifiable);\n                ie = cast(IndexExp)ie.e1;\n                ++depth;\n            }\n\n            // Get the AA value to be modified.\n            Expression aggregate = interpret(ie.e1, istate);\n            if (exceptionOrCant(aggregate))\n                return;\n            if (aggregate.op == TOK.assocArrayLiteral)\n            {\n                existingAA = cast(AssocArrayLiteralExp)aggregate;\n\n                // Normal case, ultimate parent AA already exists\n                // We need to walk from the deepest index up, checking that an AA literal\n                // already exists on each level.\n                lastIndex = interpret((cast(IndexExp)e1).e2, istate);\n                lastIndex = resolveSlice(lastIndex); // only happens with AA assignment\n                if (exceptionOrCant(lastIndex))\n                    return;\n\n                while (depth > 0)\n                {\n                    // Walk the syntax tree to find the indexExp at this depth\n                    IndexExp xe = cast(IndexExp)e1;\n                    for (int d = 0; d < depth; ++d)\n                        xe = cast(IndexExp)xe.e1;\n\n                    Expression ekey = interpret(xe.e2, istate);\n                    if (exceptionOrCant(ekey))\n                        return;\n                    UnionExp ekeyTmp = void;\n                    ekey = resolveSlice(ekey, &ekeyTmp); // only happens with AA assignment\n\n                    // Look up this index in it up in the existing AA, to get the next level of AA.\n                    AssocArrayLiteralExp newAA = cast(AssocArrayLiteralExp)findKeyInAA(e.loc, existingAA, ekey);\n                    if (exceptionOrCant(newAA))\n                        return;\n                    if (!newAA)\n                    {\n                        // Doesn't exist yet, create an empty AA...\n                        auto keysx = new Expressions();\n                        auto valuesx = new Expressions();\n                        newAA = new AssocArrayLiteralExp(e.loc, keysx, valuesx);\n                        newAA.type = xe.type;\n                        newAA.ownedByCtfe = OwnedBy.ctfe;\n                        //... and insert it into the existing AA.\n                        existingAA.keys.push(ekey);\n                        existingAA.values.push(newAA);\n                    }\n                    existingAA = newAA;\n                    --depth;\n                }\n\n                if (fp)\n                {\n                    oldval = findKeyInAA(e.loc, existingAA, lastIndex);\n                    if (!oldval)\n                        oldval = copyLiteral(e.e1.type.defaultInitLiteral(e.loc)).copy();\n                }\n            }\n            else\n            {\n                /* The AA is currently null. 'aggregate' is actually a reference to\n                 * whatever contains it. It could be anything: var, dotvarexp, ...\n                 * We rewrite the assignment from:\n                 *     aa[i][j] op= newval;\n                 * into:\n                 *     aa = [i:[j:T.init]];\n                 *     aa[j] op= newval;\n                 */\n                oldval = copyLiteral(e.e1.type.defaultInitLiteral(e.loc)).copy();\n\n                Expression newaae = oldval;\n                while (e1.op == TOK.index && (cast(IndexExp)e1).e1.type.toBasetype().ty == Taarray)\n                {\n                    Expression ekey = interpret((cast(IndexExp)e1).e2, istate);\n                    if (exceptionOrCant(ekey))\n                        return;\n                    ekey = resolveSlice(ekey); // only happens with AA assignment\n\n                    auto keysx = new Expressions();\n                    auto valuesx = new Expressions();\n                    keysx.push(ekey);\n                    valuesx.push(newaae);\n\n                    auto aae = new AssocArrayLiteralExp(e.loc, keysx, valuesx);\n                    aae.type = (cast(IndexExp)e1).e1.type;\n                    aae.ownedByCtfe = OwnedBy.ctfe;\n                    if (!existingAA)\n                    {\n                        existingAA = aae;\n                        lastIndex = ekey;\n                    }\n                    newaae = aae;\n                    e1 = (cast(IndexExp)e1).e1;\n                }\n\n                // We must set to aggregate with newaae\n                e1 = interpret(e1, istate, ctfeNeedLvalue);\n                if (exceptionOrCant(e1))\n                    return;\n                e1 = assignToLvalue(e, e1, newaae);\n                if (exceptionOrCant(e1))\n                    return;\n            }\n            assert(existingAA && lastIndex);\n            e1 = null; // stomp\n        }\n        else if (e1.op == TOK.arrayLength)\n        {\n            oldval = interpret(e1, istate);\n            if (exceptionOrCant(oldval))\n                return;\n        }\n        else if (e.op == TOK.construct || e.op == TOK.blit)\n        {\n            // Unless we have a simple var assignment, we're\n            // only modifying part of the variable. So we need to make sure\n            // that the parent variable exists.\n            VarDeclaration ultimateVar = findParentVar(e1);\n            if (e1.op == TOK.variable)\n            {\n                VarDeclaration v = (cast(VarExp)e1).var.isVarDeclaration();\n                assert(v);\n                if (v.storage_class & STC.out_)\n                    goto L1;\n            }\n            else if (ultimateVar && !getValue(ultimateVar))\n            {\n                Expression ex = interpret(ultimateVar.type.defaultInitLiteral(e.loc), istate);\n                if (exceptionOrCant(ex))\n                    return;\n                setValue(ultimateVar, ex);\n            }\n            else\n                goto L1;\n        }\n        else\n        {\n        L1:\n            e1 = interpret(e1, istate, ctfeNeedLvalue);\n            if (exceptionOrCant(e1))\n                return;\n\n            if (e1.op == TOK.index && (cast(IndexExp)e1).e1.type.toBasetype().ty == Taarray)\n            {\n                IndexExp ie = cast(IndexExp)e1;\n                assert(ie.e1.op == TOK.assocArrayLiteral);\n                existingAA = cast(AssocArrayLiteralExp)ie.e1;\n                lastIndex = ie.e2;\n            }\n        }\n\n        // ---------------------------------------\n        //      Interpret right hand side\n        // ---------------------------------------\n        Expression newval = interpret(e.e2, istate);\n        if (exceptionOrCant(newval))\n            return;\n        if (e.op == TOK.blit && newval.op == TOK.int64)\n        {\n            Type tbn = e.type.baseElemOf();\n            if (tbn.ty == Tstruct)\n            {\n                /* Look for special case of struct being initialized with 0.\n                 */\n                newval = e.type.defaultInitLiteral(e.loc);\n                if (newval.op == TOK.error)\n                {\n                    result = CTFEExp.cantexp;\n                    return;\n                }\n                newval = interpret(newval, istate); // copy and set ownedByCtfe flag\n                if (exceptionOrCant(newval))\n                    return;\n            }\n        }\n\n        // ----------------------------------------------------\n        //  Deal with read-modify-write assignments.\n        //  Set 'newval' to the final assignment value\n        //  Also determine the return value (except for slice\n        //  assignments, which are more complicated)\n        // ----------------------------------------------------\n        if (fp)\n        {\n            if (!oldval)\n            {\n                // Load the left hand side after interpreting the right hand side.\n                oldval = interpret(e1, istate);\n                if (exceptionOrCant(oldval))\n                    return;\n            }\n\n            if (e.e1.type.ty != Tpointer)\n            {\n                // ~= can create new values (see bug 6052)\n                if (e.op == TOK.concatenateAssign || e.op == TOK.concatenateElemAssign || e.op == TOK.concatenateDcharAssign)\n                {\n                    // We need to dup it and repaint the type. For a dynamic array\n                    // we can skip duplication, because it gets copied later anyway.\n                    if (newval.type.ty != Tarray)\n                    {\n                        newval = copyLiteral(newval).copy();\n                        newval.type = e.e2.type; // repaint type\n                    }\n                    else\n                    {\n                        newval = paintTypeOntoLiteral(e.e2.type, newval);\n                        newval = resolveSlice(newval);\n                    }\n                }\n                oldval = resolveSlice(oldval);\n\n                newval = (*fp)(e.loc, e.type, oldval, newval).copy();\n            }\n            else if (e.e2.type.isintegral() &&\n                     (e.op == TOK.addAssign ||\n                      e.op == TOK.minAssign ||\n                      e.op == TOK.plusPlus ||\n                      e.op == TOK.minusMinus))\n            {\n                newval = pointerArithmetic(e.loc, e.op, e.type, oldval, newval).copy();\n            }\n            else\n            {\n                e.error(\"pointer expression `%s` cannot be interpreted at compile time\", e.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            if (exceptionOrCant(newval))\n            {\n                if (CTFEExp.isCantExp(newval))\n                    e.error(\"cannot interpret `%s` at compile time\", e.toChars());\n                return;\n            }\n        }\n\n        if (existingAA)\n        {\n            if (existingAA.ownedByCtfe != OwnedBy.ctfe)\n            {\n                e.error(\"cannot modify read-only constant `%s`\", existingAA.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n\n            //printf(\"\\t+L%d existingAA = %s, lastIndex = %s, oldval = %s, newval = %s\\n\",\n            //    __LINE__, existingAA.toChars(), lastIndex.toChars(), oldval ? oldval.toChars() : NULL, newval.toChars());\n            assignAssocArrayElement(e.loc, existingAA, lastIndex, newval);\n\n            // Determine the return value\n            result = ctfeCast(e.loc, e.type, e.type, fp && post ? oldval : newval);\n            return;\n        }\n        if (e1.op == TOK.arrayLength)\n        {\n            /* Change the assignment from:\n             *  arr.length = n;\n             * into:\n             *  arr = new_length_array; (result is n)\n             */\n\n            // Determine the return value\n            result = ctfeCast(e.loc, e.type, e.type, fp && post ? oldval : newval);\n            if (exceptionOrCant(result))\n                return;\n\n            size_t oldlen = cast(size_t)oldval.toInteger();\n            size_t newlen = cast(size_t)newval.toInteger();\n            if (oldlen == newlen) // no change required -- we're done!\n                return;\n\n            // We have changed it into a reference assignment\n            // Note that returnValue is still the new length.\n            e1 = (cast(ArrayLengthExp)e1).e1;\n            Type t = e1.type.toBasetype();\n            if (t.ty != Tarray)\n            {\n                e.error(\"`%s` is not yet supported at compile time\", e.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            e1 = interpret(e1, istate, ctfeNeedLvalue);\n            if (exceptionOrCant(e1))\n                return;\n\n            if (oldlen != 0) // Get the old array literal.\n                oldval = interpret(e1, istate);\n            newval = changeArrayLiteralLength(e.loc, cast(TypeArray)t, oldval, oldlen, newlen).copy();\n\n            e1 = assignToLvalue(e, e1, newval);\n            if (exceptionOrCant(e1))\n                return;\n\n            return;\n        }\n\n        if (!isBlockAssignment)\n        {\n            newval = ctfeCast(e.loc, e.type, e.type, newval);\n            if (exceptionOrCant(newval))\n                return;\n\n            // Determine the return value\n            if (goal == ctfeNeedLvalue) // https://issues.dlang.org/show_bug.cgi?id=14371\n                result = e1;\n            else\n                result = ctfeCast(e.loc, e.type, e.type, fp && post ? oldval : newval);\n            if (exceptionOrCant(result))\n                return;\n        }\n        if (exceptionOrCant(newval))\n            return;\n\n        debug (LOGASSIGN)\n        {\n            printf(\"ASSIGN: %s=%s\\n\", e1.toChars(), newval.toChars());\n            showCtfeExpr(newval);\n        }\n\n        /* Block assignment or element-wise assignment.\n         */\n        if (e1.op == TOK.slice ||\n            e1.op == TOK.vector ||\n            e1.op == TOK.arrayLiteral ||\n            e1.op == TOK.string_ ||\n            e1.op == TOK.null_ && e1.type.toBasetype().ty == Tarray)\n        {\n            // Note that slice assignments don't support things like ++, so\n            // we don't need to remember 'returnValue'.\n            result = interpretAssignToSlice(e, e1, newval, isBlockAssignment);\n            if (exceptionOrCant(result))\n                return;\n            if (e.e1.op == TOK.slice)\n            {\n                Expression e1x = interpret((cast(SliceExp)e.e1).e1, istate, ctfeNeedLvalue);\n                if (e1x.op == TOK.dotVariable)\n                {\n                    auto dve = cast(DotVarExp)e1x;\n                    auto ex = dve.e1;\n                    auto sle = ex.op == TOK.structLiteral ? (cast(StructLiteralExp)ex)\n                             : ex.op == TOK.classReference ? (cast(ClassReferenceExp)ex).value\n                             : null;\n                    auto v = dve.var.isVarDeclaration();\n                    if (!sle || !v)\n                    {\n                        e.error(\"CTFE internal error: dotvar slice assignment\");\n                        result = CTFEExp.cantexp;\n                        return;\n                    }\n                    stompOverlappedFields(sle, v);\n                }\n            }\n            return;\n        }\n        assert(result);\n\n        /* Assignment to a CTFE reference.\n         */\n        if (Expression ex = assignToLvalue(e, e1, newval))\n            result = ex;\n\n        return;\n    }\n\n    /* Set all sibling fields which overlap with v to VoidExp.\n     */\n    private void stompOverlappedFields(StructLiteralExp sle, VarDeclaration v)\n    {\n        if (!v.overlapped)\n            return;\n        foreach (size_t i, v2; sle.sd.fields)\n        {\n            if (v is v2 || !v.isOverlappedWith(v2))\n                continue;\n            auto e = (*sle.elements)[i];\n            if (e.op != TOK.void_)\n                (*sle.elements)[i] = voidInitLiteral(e.type, v).copy();\n        }\n    }\n\n    private Expression assignToLvalue(BinExp e, Expression e1, Expression newval)\n    {\n        VarDeclaration vd = null;\n        Expression* payload = null; // dead-store to prevent spurious warning\n        Expression oldval;\n\n        if (e1.op == TOK.variable)\n        {\n            vd = (cast(VarExp)e1).var.isVarDeclaration();\n            oldval = getValue(vd);\n        }\n        else if (e1.op == TOK.dotVariable)\n        {\n            /* Assignment to member variable of the form:\n             *  e.v = newval\n             */\n            auto ex = (cast(DotVarExp)e1).e1;\n            auto sle = ex.op == TOK.structLiteral ? (cast(StructLiteralExp)ex)\n                     : ex.op == TOK.classReference ? (cast(ClassReferenceExp)ex).value\n                     : null;\n            auto v = (cast(DotVarExp)e1).var.isVarDeclaration();\n            if (!sle || !v)\n            {\n                e.error(\"CTFE internal error: dotvar assignment\");\n                return CTFEExp.cantexp;\n            }\n            if (sle.ownedByCtfe != OwnedBy.ctfe)\n            {\n                e.error(\"cannot modify read-only constant `%s`\", sle.toChars());\n                return CTFEExp.cantexp;\n            }\n\n            int fieldi = ex.op == TOK.structLiteral ? findFieldIndexByName(sle.sd, v)\n                       : (cast(ClassReferenceExp)ex).findFieldIndexByName(v);\n            if (fieldi == -1)\n            {\n                e.error(\"CTFE internal error: cannot find field `%s` in `%s`\", v.toChars(), ex.toChars());\n                return CTFEExp.cantexp;\n            }\n            assert(0 <= fieldi && fieldi < sle.elements.dim);\n\n            // If it's a union, set all other members of this union to void\n            stompOverlappedFields(sle, v);\n\n            payload = &(*sle.elements)[fieldi];\n            oldval = *payload;\n        }\n        else if (e1.op == TOK.index)\n        {\n            IndexExp ie = cast(IndexExp)e1;\n            assert(ie.e1.type.toBasetype().ty != Taarray);\n\n            Expression aggregate;\n            uinteger_t indexToModify;\n            if (!resolveIndexing(ie, istate, &aggregate, &indexToModify, true))\n            {\n                return CTFEExp.cantexp;\n            }\n            size_t index = cast(size_t)indexToModify;\n\n            if (aggregate.op == TOK.string_)\n            {\n                StringExp existingSE = cast(StringExp)aggregate;\n                if (existingSE.ownedByCtfe != OwnedBy.ctfe)\n                {\n                    e.error(\"cannot modify read-only string literal `%s`\", ie.e1.toChars());\n                    return CTFEExp.cantexp;\n                }\n                existingSE.setCodeUnit(index, cast(dchar)newval.toInteger());\n                return null;\n            }\n            if (aggregate.op != TOK.arrayLiteral)\n            {\n                e.error(\"index assignment `%s` is not yet supported in CTFE \", e.toChars());\n                return CTFEExp.cantexp;\n            }\n\n            ArrayLiteralExp existingAE = cast(ArrayLiteralExp)aggregate;\n            if (existingAE.ownedByCtfe != OwnedBy.ctfe)\n            {\n                e.error(\"cannot modify read-only constant `%s`\", existingAE.toChars());\n                return CTFEExp.cantexp;\n            }\n\n            payload = &(*existingAE.elements)[index];\n            oldval = *payload;\n        }\n        else\n        {\n            e.error(\"`%s` cannot be evaluated at compile time\", e.toChars());\n            return CTFEExp.cantexp;\n        }\n\n        Type t1b = e1.type.toBasetype();\n        bool wantCopy = t1b.baseElemOf().ty == Tstruct;\n\n        if (newval.op == TOK.structLiteral && oldval)\n        {\n            newval = copyLiteral(newval).copy();\n            assignInPlace(oldval, newval);\n        }\n        else if (wantCopy && e.op == TOK.assign)\n        {\n            // Currently postblit/destructor calls on static array are done\n            // in the druntime internal functions so they don't appear in AST.\n            // Therefore interpreter should handle them specially.\n\n            assert(oldval);\n            version (all) // todo: instead we can directly access to each elements of the slice\n            {\n                newval = resolveSlice(newval);\n                if (CTFEExp.isCantExp(newval))\n                {\n                    e.error(\"CTFE internal error: assignment `%s`\", e.toChars());\n                    return CTFEExp.cantexp;\n                }\n            }\n            assert(oldval.op == TOK.arrayLiteral);\n            assert(newval.op == TOK.arrayLiteral);\n\n            Expressions* oldelems = (cast(ArrayLiteralExp)oldval).elements;\n            Expressions* newelems = (cast(ArrayLiteralExp)newval).elements;\n            assert(oldelems.dim == newelems.dim);\n\n            Type elemtype = oldval.type.nextOf();\n            for (size_t i = 0; i < newelems.dim; i++)\n            {\n                Expression oldelem = (*oldelems)[i];\n                Expression newelem = paintTypeOntoLiteral(elemtype, (*newelems)[i]);\n                // https://issues.dlang.org/show_bug.cgi?id=9245\n                if (e.e2.isLvalue())\n                {\n                    if (Expression ex = evaluatePostblit(istate, newelem))\n                        return ex;\n                }\n                // https://issues.dlang.org/show_bug.cgi?id=13661\n                if (Expression ex = evaluateDtor(istate, oldelem))\n                    return ex;\n                (*oldelems)[i] = newelem;\n            }\n        }\n        else\n        {\n            // e1 has its own payload, so we have to create a new literal.\n            if (wantCopy)\n                newval = copyLiteral(newval).copy();\n\n            if (t1b.ty == Tsarray && e.op == TOK.construct && e.e2.isLvalue())\n            {\n                // https://issues.dlang.org/show_bug.cgi?id=9245\n                if (Expression ex = evaluatePostblit(istate, newval))\n                    return ex;\n            }\n\n            oldval = newval;\n        }\n\n        if (vd)\n            setValue(vd, oldval);\n        else\n            *payload = oldval;\n\n        // Blit assignment should return the newly created value.\n        if (e.op == TOK.blit)\n            return oldval;\n\n        return null;\n    }\n\n    /*************\n     * Deal with assignments of the form:\n     *  dest[] = newval\n     *  dest[low..upp] = newval\n     * where newval has already been interpreted\n     *\n     * This could be a slice assignment or a block assignment, and\n     * dest could be either an array literal, or a string.\n     *\n     * Returns TOK.cantExpression on failure. If there are no errors,\n     * it returns aggregate[low..upp], except that as an optimisation,\n     * if goal == ctfeNeedNothing, it will return NULL\n     */\n    private Expression interpretAssignToSlice(BinExp e, Expression e1, Expression newval, bool isBlockAssignment)\n    {\n        dinteger_t lowerbound;\n        dinteger_t upperbound;\n        dinteger_t firstIndex;\n\n        Expression aggregate;\n\n        if (e1.op == TOK.vector)\n            e1 = (cast(VectorExp)e1).e1;\n        if (e1.op == TOK.slice)\n        {\n            // ------------------------------\n            //   aggregate[] = newval\n            //   aggregate[low..upp] = newval\n            // ------------------------------\n            SliceExp se = cast(SliceExp)e1;\n            version (all) // should be move in interpretAssignCommon as the evaluation of e1\n            {\n                Expression oldval = interpret(se.e1, istate);\n\n                // Set the $ variable\n                uinteger_t dollar = resolveArrayLength(oldval);\n                if (se.lengthVar)\n                {\n                    Expression dollarExp = new IntegerExp(e1.loc, dollar, Type.tsize_t);\n                    ctfeStack.push(se.lengthVar);\n                    setValue(se.lengthVar, dollarExp);\n                }\n                Expression lwr = interpret(se.lwr, istate);\n                if (exceptionOrCantInterpret(lwr))\n                {\n                    if (se.lengthVar)\n                        ctfeStack.pop(se.lengthVar);\n                    return lwr;\n                }\n                Expression upr = interpret(se.upr, istate);\n                if (exceptionOrCantInterpret(upr))\n                {\n                    if (se.lengthVar)\n                        ctfeStack.pop(se.lengthVar);\n                    return upr;\n                }\n                if (se.lengthVar)\n                    ctfeStack.pop(se.lengthVar); // $ is defined only in [L..U]\n\n                const dim = dollar;\n                lowerbound = lwr ? lwr.toInteger() : 0;\n                upperbound = upr ? upr.toInteger() : dim;\n\n                if (lowerbound < 0 || dim < upperbound)\n                {\n                    e.error(\"array bounds `[0..%llu]` exceeded in slice `[%llu..%llu]`\",\n                        ulong(dim), ulong(lowerbound), ulong(upperbound));\n                    return CTFEExp.cantexp;\n                }\n            }\n            aggregate = oldval;\n            firstIndex = lowerbound;\n\n            if (aggregate.op == TOK.slice)\n            {\n                // Slice of a slice --> change the bounds\n                SliceExp oldse = cast(SliceExp)aggregate;\n                if (oldse.upr.toInteger() < upperbound + oldse.lwr.toInteger())\n                {\n                    e.error(\"slice `[%llu..%llu]` exceeds array bounds `[0..%llu]`\",\n                        ulong(lowerbound), ulong(upperbound), oldse.upr.toInteger() - oldse.lwr.toInteger());\n                    return CTFEExp.cantexp;\n                }\n                aggregate = oldse.e1;\n                firstIndex = lowerbound + oldse.lwr.toInteger();\n            }\n        }\n        else\n        {\n            if (e1.op == TOK.arrayLiteral)\n            {\n                lowerbound = 0;\n                upperbound = (cast(ArrayLiteralExp)e1).elements.dim;\n            }\n            else if (e1.op == TOK.string_)\n            {\n                lowerbound = 0;\n                upperbound = (cast(StringExp)e1).len;\n            }\n            else if (e1.op == TOK.null_)\n            {\n                lowerbound = 0;\n                upperbound = 0;\n            }\n            else\n                assert(0);\n\n            aggregate = e1;\n            firstIndex = lowerbound;\n        }\n        if (upperbound == lowerbound)\n            return newval;\n\n        // For slice assignment, we check that the lengths match.\n        if (!isBlockAssignment)\n        {\n            const srclen = resolveArrayLength(newval);\n            if (srclen != (upperbound - lowerbound))\n            {\n                e.error(\"array length mismatch assigning `[0..%llu]` to `[%llu..%llu]`\",\n                    ulong(srclen), ulong(lowerbound), ulong(upperbound));\n                return CTFEExp.cantexp;\n            }\n        }\n\n        if (aggregate.op == TOK.string_)\n        {\n            StringExp existingSE = cast(StringExp)aggregate;\n            if (existingSE.ownedByCtfe != OwnedBy.ctfe)\n            {\n                e.error(\"cannot modify read-only string literal `%s`\", existingSE.toChars());\n                return CTFEExp.cantexp;\n            }\n\n            if (newval.op == TOK.slice)\n            {\n                auto se = cast(SliceExp)newval;\n                auto aggr2 = se.e1;\n                const srclower = se.lwr.toInteger();\n                const srcupper = se.upr.toInteger();\n\n                if (aggregate == aggr2 &&\n                    lowerbound < srcupper && srclower < upperbound)\n                {\n                    e.error(\"overlapping slice assignment `[%llu..%llu] = [%llu..%llu]`\",\n                        ulong(lowerbound), ulong(upperbound), ulong(srclower), ulong(srcupper));\n                    return CTFEExp.cantexp;\n                }\n                version (all) // todo: instead we can directly access to each elements of the slice\n                {\n                    Expression orignewval = newval;\n                    newval = resolveSlice(newval);\n                    if (CTFEExp.isCantExp(newval))\n                    {\n                        e.error(\"CTFE internal error: slice `%s`\", orignewval.toChars());\n                        return CTFEExp.cantexp;\n                    }\n                }\n                assert(newval.op != TOK.slice);\n            }\n            if (newval.op == TOK.string_)\n            {\n                sliceAssignStringFromString(existingSE, cast(StringExp)newval, cast(size_t)firstIndex);\n                return newval;\n            }\n            if (newval.op == TOK.arrayLiteral)\n            {\n                /* Mixed slice: it was initialized as a string literal.\n                 * Now a slice of it is being set with an array literal.\n                 */\n                sliceAssignStringFromArrayLiteral(existingSE, cast(ArrayLiteralExp)newval, cast(size_t)firstIndex);\n                return newval;\n            }\n\n            // String literal block slice assign\n            const value = cast(dchar)newval.toInteger();\n            foreach (i; 0 .. upperbound - lowerbound)\n            {\n                existingSE.setCodeUnit(cast(size_t)(i + firstIndex), value);\n            }\n            if (goal == ctfeNeedNothing)\n                return null; // avoid creating an unused literal\n            auto retslice = new SliceExp(e.loc, existingSE, new IntegerExp(e.loc, firstIndex, Type.tsize_t), new IntegerExp(e.loc, firstIndex + upperbound - lowerbound, Type.tsize_t));\n            retslice.type = e.type;\n            return interpret(retslice, istate);\n        }\n        if (aggregate.op == TOK.arrayLiteral)\n        {\n            ArrayLiteralExp existingAE = cast(ArrayLiteralExp)aggregate;\n            if (existingAE.ownedByCtfe != OwnedBy.ctfe)\n            {\n                e.error(\"cannot modify read-only constant `%s`\", existingAE.toChars());\n                return CTFEExp.cantexp;\n            }\n\n            if (newval.op == TOK.slice && !isBlockAssignment)\n            {\n                auto se = cast(SliceExp)newval;\n                auto aggr2 = se.e1;\n                const srclower = se.lwr.toInteger();\n                const srcupper = se.upr.toInteger();\n                const wantCopy = (newval.type.toBasetype().nextOf().baseElemOf().ty == Tstruct);\n\n                //printf(\"oldval = %p %s[%d..%u]\\nnewval = %p %s[%llu..%llu] wantCopy = %d\\n\",\n                //    aggregate, aggregate.toChars(), lowerbound, upperbound,\n                //    aggr2, aggr2.toChars(), srclower, srcupper, wantCopy);\n                if (wantCopy)\n                {\n                    // Currently overlapping for struct array is allowed.\n                    // The order of elements processing depends on the overlapping.\n                    // https://issues.dlang.org/show_bug.cgi?id=14024\n                    assert(aggr2.op == TOK.arrayLiteral);\n                    Expressions* oldelems = existingAE.elements;\n                    Expressions* newelems = (cast(ArrayLiteralExp)aggr2).elements;\n\n                    Type elemtype = aggregate.type.nextOf();\n                    bool needsPostblit = e.e2.isLvalue();\n\n                    if (aggregate == aggr2 && srclower < lowerbound && lowerbound < srcupper)\n                    {\n                        // reverse order\n                        for (auto i = upperbound - lowerbound; 0 < i--;)\n                        {\n                            Expression oldelem = (*oldelems)[cast(size_t)(i + firstIndex)];\n                            Expression newelem = (*newelems)[cast(size_t)(i + srclower)];\n                            newelem = copyLiteral(newelem).copy();\n                            newelem.type = elemtype;\n                            if (needsPostblit)\n                            {\n                                if (Expression x = evaluatePostblit(istate, newelem))\n                                    return x;\n                            }\n                            if (Expression x = evaluateDtor(istate, oldelem))\n                                return x;\n                            (*oldelems)[cast(size_t)(lowerbound + i)] = newelem;\n                        }\n                    }\n                    else\n                    {\n                        // normal order\n                        for (auto i = 0; i < upperbound - lowerbound; i++)\n                        {\n                            Expression oldelem = (*oldelems)[cast(size_t)(i + firstIndex)];\n                            Expression newelem = (*newelems)[cast(size_t)(i + srclower)];\n                            newelem = copyLiteral(newelem).copy();\n                            newelem.type = elemtype;\n                            if (needsPostblit)\n                            {\n                                if (Expression x = evaluatePostblit(istate, newelem))\n                                    return x;\n                            }\n                            if (Expression x = evaluateDtor(istate, oldelem))\n                                return x;\n                            (*oldelems)[cast(size_t)(lowerbound + i)] = newelem;\n                        }\n                    }\n\n                    //assert(0);\n                    return newval; // oldval?\n                }\n                if (aggregate == aggr2 &&\n                    lowerbound < srcupper && srclower < upperbound)\n                {\n                    e.error(\"overlapping slice assignment `[%llu..%llu] = [%llu..%llu]`\",\n                        ulong(lowerbound), ulong(upperbound), ulong(srclower), ulong(srcupper));\n                    return CTFEExp.cantexp;\n                }\n                version (all) // todo: instead we can directly access to each elements of the slice\n                {\n                    Expression orignewval = newval;\n                    newval = resolveSlice(newval);\n                    if (CTFEExp.isCantExp(newval))\n                    {\n                        e.error(\"CTFE internal error: slice `%s`\", orignewval.toChars());\n                        return CTFEExp.cantexp;\n                    }\n                }\n                // no overlapping\n                //length?\n                assert(newval.op != TOK.slice);\n            }\n            if (newval.op == TOK.string_ && !isBlockAssignment)\n            {\n                /* Mixed slice: it was initialized as an array literal of chars/integers.\n                 * Now a slice of it is being set with a string.\n                 */\n                sliceAssignArrayLiteralFromString(existingAE, cast(StringExp)newval, cast(size_t)firstIndex);\n                return newval;\n            }\n            if (newval.op == TOK.arrayLiteral && !isBlockAssignment)\n            {\n                Expressions* oldelems = existingAE.elements;\n                Expressions* newelems = (cast(ArrayLiteralExp)newval).elements;\n                Type elemtype = existingAE.type.nextOf();\n                bool needsPostblit = e.op != TOK.blit && e.e2.isLvalue();\n                for (size_t j = 0; j < newelems.dim; j++)\n                {\n                    Expression newelem = (*newelems)[j];\n                    newelem = paintTypeOntoLiteral(elemtype, newelem);\n                    if (needsPostblit)\n                    {\n                        Expression x = evaluatePostblit(istate, newelem);\n                        if (exceptionOrCantInterpret(x))\n                            return x;\n                    }\n                    (*oldelems)[cast(size_t)(j + firstIndex)] = newelem;\n                }\n                return newval;\n            }\n\n            /* Block assignment, initialization of static arrays\n             *   x[] = newval\n             *  x may be a multidimensional static array. (Note that this\n             *  only happens with array literals, never with strings).\n             */\n            struct RecursiveBlock\n            {\n                InterState* istate;\n                Expression newval;\n                bool refCopy;\n                bool needsPostblit;\n                bool needsDtor;\n\n                extern (C++) Expression assignTo(ArrayLiteralExp ae)\n                {\n                    return assignTo(ae, 0, ae.elements.dim);\n                }\n\n                extern (C++) Expression assignTo(ArrayLiteralExp ae, size_t lwr, size_t upr)\n                {\n                    Expressions* w = ae.elements;\n                    assert(ae.type.ty == Tsarray || ae.type.ty == Tarray);\n                    bool directblk = (cast(TypeArray)ae.type).next.equivalent(newval.type);\n                    for (size_t k = lwr; k < upr; k++)\n                    {\n                        if (!directblk && (*w)[k].op == TOK.arrayLiteral)\n                        {\n                            // Multidimensional array block assign\n                            if (Expression ex = assignTo(cast(ArrayLiteralExp)(*w)[k]))\n                                return ex;\n                        }\n                        else if (refCopy)\n                        {\n                            (*w)[k] = newval;\n                        }\n                        else if (!needsPostblit && !needsDtor)\n                        {\n                            assignInPlace((*w)[k], newval);\n                        }\n                        else\n                        {\n                            Expression oldelem = (*w)[k];\n                            Expression tmpelem = needsDtor ? copyLiteral(oldelem).copy() : null;\n                            assignInPlace(oldelem, newval);\n                            if (needsPostblit)\n                            {\n                                if (Expression ex = evaluatePostblit(istate, oldelem))\n                                    return ex;\n                            }\n                            if (needsDtor)\n                            {\n                                // https://issues.dlang.org/show_bug.cgi?id=14860\n                                if (Expression ex = evaluateDtor(istate, tmpelem))\n                                    return ex;\n                            }\n                        }\n                    }\n                    return null;\n                }\n            }\n\n            Type tn = newval.type.toBasetype();\n            bool wantRef = (tn.ty == Tarray || isAssocArray(tn) || tn.ty == Tclass);\n            bool cow = newval.op != TOK.structLiteral && newval.op != TOK.arrayLiteral && newval.op != TOK.string_;\n            Type tb = tn.baseElemOf();\n            StructDeclaration sd = (tb.ty == Tstruct ? (cast(TypeStruct)tb).sym : null);\n\n            RecursiveBlock rb;\n            rb.istate = istate;\n            rb.newval = newval;\n            rb.refCopy = wantRef || cow;\n            rb.needsPostblit = sd && sd.postblit && e.op != TOK.blit && e.e2.isLvalue();\n            rb.needsDtor = sd && sd.dtor && e.op == TOK.assign;\n            if (Expression ex = rb.assignTo(existingAE, cast(size_t)lowerbound, cast(size_t)upperbound))\n                return ex;\n\n            if (goal == ctfeNeedNothing)\n                return null; // avoid creating an unused literal\n            auto retslice = new SliceExp(e.loc, existingAE, new IntegerExp(e.loc, firstIndex, Type.tsize_t), new IntegerExp(e.loc, firstIndex + upperbound - lowerbound, Type.tsize_t));\n            retslice.type = e.type;\n            return interpret(retslice, istate);\n        }\n\n        e.error(\"slice operation `%s = %s` cannot be evaluated at compile time\", e1.toChars(), newval.toChars());\n        return CTFEExp.cantexp;\n    }\n\n    override void visit(AssignExp e)\n    {\n        interpretAssignCommon(e, null);\n    }\n\n    override void visit(BinAssignExp e)\n    {\n        switch (e.op)\n        {\n        case TOK.addAssign:\n            interpretAssignCommon(e, &Add);\n            return;\n\n        case TOK.minAssign:\n            interpretAssignCommon(e, &Min);\n            return;\n\n        case TOK.concatenateAssign:\n        case TOK.concatenateElemAssign:\n        case TOK.concatenateDcharAssign:\n            interpretAssignCommon(e, &ctfeCat);\n            return;\n\n        case TOK.mulAssign:\n            interpretAssignCommon(e, &Mul);\n            return;\n\n        case TOK.divAssign:\n            interpretAssignCommon(e, &Div);\n            return;\n\n        case TOK.modAssign:\n            interpretAssignCommon(e, &Mod);\n            return;\n\n        case TOK.leftShiftAssign:\n            interpretAssignCommon(e, &Shl);\n            return;\n\n        case TOK.rightShiftAssign:\n            interpretAssignCommon(e, &Shr);\n            return;\n\n        case TOK.unsignedRightShiftAssign:\n            interpretAssignCommon(e, &Ushr);\n            return;\n\n        case TOK.andAssign:\n            interpretAssignCommon(e, &And);\n            return;\n\n        case TOK.orAssign:\n            interpretAssignCommon(e, &Or);\n            return;\n\n        case TOK.xorAssign:\n            interpretAssignCommon(e, &Xor);\n            return;\n\n        case TOK.powAssign:\n            interpretAssignCommon(e, &Pow);\n            return;\n\n        default:\n            assert(0);\n        }\n    }\n\n    override void visit(PostExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s PostExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        if (e.op == TOK.plusPlus)\n            interpretAssignCommon(e, &Add, 1);\n        else\n            interpretAssignCommon(e, &Min, 1);\n        debug (LOG)\n        {\n            if (CTFEExp.isCantExp(result))\n                printf(\"PostExp::interpret() CANT\\n\");\n        }\n    }\n\n    /* Return 1 if e is a p1 > p2 or p1 >= p2 pointer comparison;\n     *       -1 if e is a p1 < p2 or p1 <= p2 pointer comparison;\n     *        0 otherwise\n     */\n    static int isPointerCmpExp(Expression e, Expression* p1, Expression* p2)\n    {\n        int ret = 1;\n        while (e.op == TOK.not)\n        {\n            ret *= -1;\n            e = (cast(NotExp)e).e1;\n        }\n        switch (e.op)\n        {\n        case TOK.lessThan:\n        case TOK.lessOrEqual:\n            ret *= -1;\n            goto case; /+ fall through +/\n        case TOK.greaterThan:\n        case TOK.greaterOrEqual:\n            *p1 = (cast(BinExp)e).e1;\n            *p2 = (cast(BinExp)e).e2;\n            if (!(isPointer((*p1).type) && isPointer((*p2).type)))\n                ret = 0;\n            break;\n\n        default:\n            ret = 0;\n            break;\n        }\n        return ret;\n    }\n\n    /** Negate a relational operator, eg >= becomes <\n     */\n    static TOK reverseRelation(TOK op)\n    {\n        switch (op)\n        {\n        case TOK.greaterOrEqual:\n            return TOK.lessThan;\n\n        case TOK.greaterThan:\n            return TOK.lessOrEqual;\n\n        case TOK.lessOrEqual:\n            return TOK.greaterThan;\n\n        case TOK.lessThan:\n            return TOK.greaterOrEqual;\n\n        default:\n            assert(0);\n        }\n    }\n\n    /** If this is a four pointer relation, evaluate it, else return NULL.\n     *\n     *  This is an expression of the form (p1 > q1 && p2 < q2) or (p1 < q1 || p2 > q2)\n     *  where p1, p2 are expressions yielding pointers to memory block p,\n     *  and q1, q2 are expressions yielding pointers to memory block q.\n     *  This expression is valid even if p and q are independent memory\n     *  blocks and are therefore not normally comparable; the && form returns true\n     *  if [p1..p2] lies inside [q1..q2], and false otherwise; the || form returns\n     *  true if [p1..p2] lies outside [q1..q2], and false otherwise.\n     *\n     *  Within the expression, any ordering of p1, p2, q1, q2 is permissible;\n     *  the comparison operators can be any of >, <, <=, >=, provided that\n     *  both directions (p > q and p < q) are checked. Additionally the\n     *  relational sub-expressions can be negated, eg\n     *  (!(q1 < p1) && p2 <= q2) is valid.\n     */\n    private void interpretFourPointerRelation(BinExp e)\n    {\n        assert(e.op == TOK.andAnd || e.op == TOK.orOr);\n\n        /*  It can only be an isInside expression, if both e1 and e2 are\n         *  directional pointer comparisons.\n         *  Note that this check can be made statically; it does not depends on\n         *  any runtime values. This allows a JIT implementation to compile a\n         *  special AndAndPossiblyInside, keeping the normal AndAnd case efficient.\n         */\n\n        // Save the pointer expressions and the comparison directions,\n        // so we can use them later.\n        Expression p1 = null;\n        Expression p2 = null;\n        Expression p3 = null;\n        Expression p4 = null;\n        int dir1 = isPointerCmpExp(e.e1, &p1, &p2);\n        int dir2 = isPointerCmpExp(e.e2, &p3, &p4);\n        if (dir1 == 0 || dir2 == 0)\n        {\n            result = null;\n            return;\n        }\n\n        //printf(\"FourPointerRelation %s\\n\", toChars());\n\n        // Evaluate the first two pointers\n        p1 = interpret(p1, istate);\n        if (exceptionOrCant(p1))\n            return;\n        p2 = interpret(p2, istate);\n        if (exceptionOrCant(p2))\n            return;\n        dinteger_t ofs1, ofs2;\n        Expression agg1 = getAggregateFromPointer(p1, &ofs1);\n        Expression agg2 = getAggregateFromPointer(p2, &ofs2);\n\n        if (!pointToSameMemoryBlock(agg1, agg2) && agg1.op != TOK.null_ && agg2.op != TOK.null_)\n        {\n            // Here it is either CANT_INTERPRET,\n            // or an IsInside comparison returning false.\n            p3 = interpret(p3, istate);\n            if (CTFEExp.isCantExp(p3))\n                return;\n            // Note that it is NOT legal for it to throw an exception!\n            Expression except = null;\n            if (exceptionOrCantInterpret(p3))\n                except = p3;\n            else\n            {\n                p4 = interpret(p4, istate);\n                if (CTFEExp.isCantExp(p4))\n                {\n                    result = p4;\n                    return;\n                }\n                if (exceptionOrCantInterpret(p4))\n                    except = p4;\n            }\n            if (except)\n            {\n                e.error(\"comparison `%s` of pointers to unrelated memory blocks remains indeterminate at compile time because exception `%s` was thrown while evaluating `%s`\", e.e1.toChars(), except.toChars(), e.e2.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            dinteger_t ofs3, ofs4;\n            Expression agg3 = getAggregateFromPointer(p3, &ofs3);\n            Expression agg4 = getAggregateFromPointer(p4, &ofs4);\n            // The valid cases are:\n            // p1 > p2 && p3 > p4  (same direction, also for < && <)\n            // p1 > p2 && p3 < p4  (different direction, also < && >)\n            // Changing any > into >= doesn't affect the result\n            if ((dir1 == dir2 && pointToSameMemoryBlock(agg1, agg4) && pointToSameMemoryBlock(agg2, agg3)) || (dir1 != dir2 && pointToSameMemoryBlock(agg1, agg3) && pointToSameMemoryBlock(agg2, agg4)))\n            {\n                // it's a legal two-sided comparison\n                result = new IntegerExp(e.loc, (e.op == TOK.andAnd) ? 0 : 1, e.type);\n                return;\n            }\n            // It's an invalid four-pointer comparison. Either the second\n            // comparison is in the same direction as the first, or else\n            // more than two memory blocks are involved (either two independent\n            // invalid comparisons are present, or else agg3 == agg4).\n            e.error(\"comparison `%s` of pointers to unrelated memory blocks is indeterminate at compile time, even when combined with `%s`.\", e.e1.toChars(), e.e2.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        // The first pointer expression didn't need special treatment, so we\n        // we need to interpret the entire expression exactly as a normal && or ||.\n        // This is easy because we haven't evaluated e2 at all yet, and we already\n        // know it will return a bool.\n        // But we mustn't evaluate the pointer expressions in e1 again, in case\n        // they have side-effects.\n        bool nott = false;\n        Expression ex = e.e1;\n        while (ex.op == TOK.not)\n        {\n            nott = !nott;\n            ex = (cast(NotExp)ex).e1;\n        }\n        TOK cmpop = ex.op;\n        if (nott)\n            cmpop = reverseRelation(cmpop);\n        int cmp = comparePointers(cmpop, agg1, ofs1, agg2, ofs2);\n        // We already know this is a valid comparison.\n        assert(cmp >= 0);\n        if (e.op == TOK.andAnd && cmp == 1 || e.op == TOK.orOr && cmp == 0)\n        {\n            result = interpret(e.e2, istate);\n            return;\n        }\n        result = new IntegerExp(e.loc, (e.op == TOK.andAnd) ? 0 : 1, e.type);\n    }\n\n    override void visit(LogicalExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s LogicalExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        // Check for an insidePointer expression, evaluate it if so\n        interpretFourPointerRelation(e);\n        if (result)\n            return;\n\n        result = interpret(e.e1, istate);\n        if (exceptionOrCant(result))\n            return;\n\n        int res;\n        const andand = e.op == TOK.andAnd;\n        if (andand ? result.isBool(false) : isTrueBool(result))\n            res = !andand;\n        else if (andand ? isTrueBool(result) : result.isBool(false))\n        {\n            UnionExp ue2;\n            result = interpret(&ue2, e.e2, istate);\n            if (exceptionOrCant(result))\n                return;\n            if (result.op == TOK.voidExpression)\n            {\n                assert(e.type.ty == Tvoid);\n                result = null;\n                return;\n            }\n            if (result.isBool(false))\n                res = 0;\n            else if (isTrueBool(result))\n                res = 1;\n            else\n            {\n                result.error(\"`%s` does not evaluate to a `bool`\", result.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n        }\n        else\n        {\n            result.error(\"`%s` cannot be interpreted as a `bool`\", result.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        if (goal != ctfeNeedNothing)\n        {\n            emplaceExp!(IntegerExp)(pue, e.loc, res, e.type);\n            result = pue.exp();\n        }\n    }\n\n\n    // Print a stack trace, starting from callingExp which called fd.\n    // To shorten the stack trace, try to detect recursion.\n    private void showCtfeBackTrace(CallExp callingExp, FuncDeclaration fd)\n    {\n        if (CtfeStatus.stackTraceCallsToSuppress > 0)\n        {\n            --CtfeStatus.stackTraceCallsToSuppress;\n            return;\n        }\n        errorSupplemental(callingExp.loc, \"called from here: `%s`\", callingExp.toChars());\n        // Quit if it's not worth trying to compress the stack trace\n        if (CtfeStatus.callDepth < 6 || global.params.verbose)\n            return;\n        // Recursion happens if the current function already exists in the call stack.\n        int numToSuppress = 0;\n        int recurseCount = 0;\n        int depthSoFar = 0;\n        InterState* lastRecurse = istate;\n        for (InterState* cur = istate; cur; cur = cur.caller)\n        {\n            if (cur.fd == fd)\n            {\n                ++recurseCount;\n                numToSuppress = depthSoFar;\n                lastRecurse = cur;\n            }\n            ++depthSoFar;\n        }\n        // We need at least three calls to the same function, to make compression worthwhile\n        if (recurseCount < 2)\n            return;\n        // We found a useful recursion.  Print all the calls involved in the recursion\n        errorSupplemental(fd.loc, \"%d recursive calls to function `%s`\", recurseCount, fd.toChars());\n        for (InterState* cur = istate; cur.fd != fd; cur = cur.caller)\n        {\n            errorSupplemental(cur.fd.loc, \"recursively called from function `%s`\", cur.fd.toChars());\n        }\n        // We probably didn't enter the recursion in this function.\n        // Go deeper to find the real beginning.\n        InterState* cur = istate;\n        while (lastRecurse.caller && cur.fd == lastRecurse.caller.fd)\n        {\n            cur = cur.caller;\n            lastRecurse = lastRecurse.caller;\n            ++numToSuppress;\n        }\n        CtfeStatus.stackTraceCallsToSuppress = numToSuppress;\n    }\n\n    override void visit(CallExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s CallExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        Expression pthis = null;\n        FuncDeclaration fd = null;\n\n        Expression ecall = interpret(e.e1, istate);\n        if (exceptionOrCant(ecall))\n            return;\n\n        if (ecall.op == TOK.dotVariable)\n        {\n            DotVarExp dve = cast(DotVarExp)ecall;\n\n            // Calling a member function\n            pthis = dve.e1;\n            fd = dve.var.isFuncDeclaration();\n            assert(fd);\n\n            if (pthis.op == TOK.dotType)\n                pthis = (cast(DotTypeExp)dve.e1).e1;\n        }\n        else if (ecall.op == TOK.variable)\n        {\n            fd = (cast(VarExp)ecall).var.isFuncDeclaration();\n            assert(fd);\n\n            if (fd.ident == Id.__ArrayPostblit || fd.ident == Id.__ArrayDtor)\n            {\n                assert(e.arguments.dim == 1);\n                Expression ea = (*e.arguments)[0];\n                // printf(\"1 ea = %s %s\\n\", ea.type.toChars(), ea.toChars());\n                if (ea.op == TOK.slice)\n                    ea = (cast(SliceExp)ea).e1;\n                if (ea.op == TOK.cast_)\n                    ea = (cast(CastExp)ea).e1;\n\n                // printf(\"2 ea = %s, %s %s\\n\", ea.type.toChars(), Token.toChars(ea.op), ea.toChars());\n                if (ea.op == TOK.variable || ea.op == TOK.symbolOffset)\n                    result = getVarExp(e.loc, istate, (cast(SymbolExp)ea).var, ctfeNeedRvalue);\n                else if (ea.op == TOK.address)\n                    result = interpret((cast(AddrExp)ea).e1, istate);\n\n                // https://issues.dlang.org/show_bug.cgi?id=18871\n                // https://issues.dlang.org/show_bug.cgi?id=18819\n                else if (ea.op == TOK.arrayLiteral)\n                    result = interpret(cast(ArrayLiteralExp)ea, istate);\n\n                else\n                    assert(0);\n                if (CTFEExp.isCantExp(result))\n                    return;\n\n                if (fd.ident == Id.__ArrayPostblit)\n                    result = evaluatePostblit(istate, result);\n                else\n                    result = evaluateDtor(istate, result);\n                if (!result)\n                    result = CTFEExp.voidexp;\n                return;\n            }\n        }\n        else if (ecall.op == TOK.symbolOffset)\n        {\n            SymOffExp soe = cast(SymOffExp)ecall;\n            fd = soe.var.isFuncDeclaration();\n            assert(fd && soe.offset == 0);\n        }\n        else if (ecall.op == TOK.delegate_)\n        {\n            // Calling a delegate\n            fd = (cast(DelegateExp)ecall).func;\n            pthis = (cast(DelegateExp)ecall).e1;\n\n            // Special handling for: &nestedfunc --> DelegateExp(VarExp(nestedfunc), nestedfunc)\n            if (pthis.op == TOK.variable && (cast(VarExp)pthis).var == fd)\n                pthis = null; // context is not necessary for CTFE\n        }\n        else if (ecall.op == TOK.function_)\n        {\n            // Calling a delegate literal\n            fd = (cast(FuncExp)ecall).fd;\n        }\n        else\n        {\n            // delegate.funcptr()\n            // others\n            e.error(\"cannot call `%s` at compile time\", e.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        if (!fd)\n        {\n            e.error(\"CTFE internal error: cannot evaluate `%s` at compile time\", e.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        if (pthis)\n        {\n            // Member function call\n\n            // Currently this is satisfied because closure is not yet supported.\n            assert(!fd.isNested());\n\n            if (pthis.op == TOK.typeid_)\n            {\n                pthis.error(\"static variable `%s` cannot be read at compile time\", pthis.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            assert(pthis);\n\n            if (pthis.op == TOK.null_)\n            {\n                assert(pthis.type.toBasetype().ty == Tclass);\n                e.error(\"function call through null class reference `%s`\", pthis.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            assert(pthis.op == TOK.structLiteral || pthis.op == TOK.classReference);\n\n            if (fd.isVirtual() && !e.directcall)\n            {\n                // Make a virtual function call.\n                // Get the function from the vtable of the original class\n                assert(pthis.op == TOK.classReference);\n                ClassDeclaration cd = (cast(ClassReferenceExp)pthis).originalClass();\n\n                // We can't just use the vtable index to look it up, because\n                // vtables for interfaces don't get populated until the glue layer.\n                fd = cd.findFunc(fd.ident, cast(TypeFunction)fd.type);\n                assert(fd);\n            }\n        }\n\n        if (fd && fd.semanticRun >= PASS.semantic3done && fd.semantic3Errors)\n        {\n            e.error(\"CTFE failed because of previous errors in `%s`\", fd.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        // Check for built-in functions\n        result = evaluateIfBuiltin(istate, e.loc, fd, e.arguments, pthis);\n        if (result)\n            return;\n\n        if (!fd.fbody)\n        {\n            e.error(\"`%s` cannot be interpreted at compile time, because it has no available source code\", fd.toChars());\n            result = CTFEExp.showcontext;\n            return;\n        }\n\n        result = interpretFunction(fd, istate, e.arguments, pthis);\n        if (result.op == TOK.voidExpression)\n            return;\n        if (!exceptionOrCantInterpret(result))\n        {\n            if (goal != ctfeNeedLvalue) // Peel off CTFE reference if it's unnesessary\n                result = interpret(result, istate);\n        }\n        if (!exceptionOrCantInterpret(result))\n        {\n            result = paintTypeOntoLiteral(e.type, result);\n            result.loc = e.loc;\n        }\n        else if (CTFEExp.isCantExp(result) && !global.gag)\n            showCtfeBackTrace(e, fd); // Print a stack trace.\n    }\n\n    override void visit(CommaExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s CommaExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n\n        // If it creates a variable, and there's no context for\n        // the variable to be created in, we need to create one now.\n        InterState istateComma;\n        if (!istate && firstComma(e.e1).op == TOK.declaration)\n        {\n            ctfeStack.startFrame(null);\n            istate = &istateComma;\n        }\n\n        void endTempStackFrame()\n        {\n            // If we created a temporary stack frame, end it now.\n            if (istate == &istateComma)\n                ctfeStack.endFrame();\n        }\n\n        result = CTFEExp.cantexp;\n\n        // If the comma returns a temporary variable, it needs to be an lvalue\n        // (this is particularly important for struct constructors)\n        if (e.e1.op == TOK.declaration &&\n            e.e2.op == TOK.variable &&\n            (cast(DeclarationExp)e.e1).declaration == (cast(VarExp)e.e2).var &&\n            (cast(VarExp)e.e2).var.storage_class & STC.ctfe)\n        {\n            VarExp ve = cast(VarExp)e.e2;\n            VarDeclaration v = ve.var.isVarDeclaration();\n            ctfeStack.push(v);\n            if (!v._init && !getValue(v))\n            {\n                setValue(v, copyLiteral(v.type.defaultInitLiteral(e.loc)).copy());\n            }\n            if (!getValue(v))\n            {\n                Expression newval = v._init.initializerToExpression();\n                // Bug 4027. Copy constructors are a weird case where the\n                // initializer is a void function (the variable is modified\n                // through a reference parameter instead).\n                newval = interpret(newval, istate);\n                if (exceptionOrCant(newval))\n                    return endTempStackFrame();\n                if (newval.op != TOK.voidExpression)\n                {\n                    // v isn't necessarily null.\n                    setValueWithoutChecking(v, copyLiteral(newval).copy());\n                }\n            }\n        }\n        else\n        {\n            UnionExp ue = void;\n            auto e1 = interpret(&ue, e.e1, istate, ctfeNeedNothing);\n            if (exceptionOrCant(e1))\n                return endTempStackFrame();\n        }\n        result = interpret(pue, e.e2, istate, goal);\n        return endTempStackFrame();\n    }\n\n    override void visit(CondExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s CondExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        UnionExp uecond = void;\n        Expression econd;\n        econd = interpret(&uecond, e.econd, istate);\n        if (exceptionOrCant(econd))\n            return;\n\n        if (isPointer(e.econd.type))\n        {\n            if (econd.op != TOK.null_)\n            {\n                emplaceExp!(IntegerExp)(&uecond, e.loc, 1, Type.tbool);\n                econd = uecond.exp();\n            }\n        }\n\n        if (isTrueBool(econd))\n            result = interpret(pue, e.e1, istate, goal);\n        else if (econd.isBool(false))\n            result = interpret(pue, e.e2, istate, goal);\n        else\n        {\n            e.error(\"`%s` does not evaluate to boolean result at compile time\", e.econd.toChars());\n            result = CTFEExp.cantexp;\n        }\n    }\n\n    override void visit(ArrayLengthExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s ArrayLengthExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        UnionExp ue1;\n        Expression e1 = interpret(&ue1, e.e1, istate);\n        assert(e1);\n        if (exceptionOrCant(e1))\n            return;\n        if (e1.op != TOK.string_ && e1.op != TOK.arrayLiteral && e1.op != TOK.slice && e1.op != TOK.null_)\n        {\n            e.error(\"`%s` cannot be evaluated at compile time\", e.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        emplaceExp!(IntegerExp)(pue, e.loc, resolveArrayLength(e1), e.type);\n        result = pue.exp();\n    }\n\n    override void visit(DelegatePtrExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s DelegatePtrExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        Expression e1 = interpret(pue, e.e1, istate);\n        assert(e1);\n        if (exceptionOrCant(e1))\n            return;\n        e.error(\"`%s` cannot be evaluated at compile time\", e.toChars());\n        result = CTFEExp.cantexp;\n    }\n\n    override void visit(DelegateFuncptrExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s DelegateFuncptrExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        Expression e1 = interpret(pue, e.e1, istate);\n        assert(e1);\n        if (exceptionOrCant(e1))\n            return;\n        e.error(\"`%s` cannot be evaluated at compile time\", e.toChars());\n        result = CTFEExp.cantexp;\n    }\n\n    static bool resolveIndexing(IndexExp e, InterState* istate, Expression* pagg, uinteger_t* pidx, bool modify)\n    {\n        assert(e.e1.type.toBasetype().ty != Taarray);\n\n        if (e.e1.type.toBasetype().ty == Tpointer)\n        {\n            // Indexing a pointer. Note that there is no $ in this case.\n            Expression e1 = interpret(e.e1, istate);\n            if (exceptionOrCantInterpret(e1))\n                return false;\n\n            Expression e2 = interpret(e.e2, istate);\n            if (exceptionOrCantInterpret(e2))\n                return false;\n            sinteger_t indx = e2.toInteger();\n\n            dinteger_t ofs;\n            Expression agg = getAggregateFromPointer(e1, &ofs);\n\n            if (agg.op == TOK.null_)\n            {\n                e.error(\"cannot index through null pointer `%s`\", e.e1.toChars());\n                return false;\n            }\n            if (agg.op == TOK.int64)\n            {\n                e.error(\"cannot index through invalid pointer `%s` of value `%s`\", e.e1.toChars(), e1.toChars());\n                return false;\n            }\n            // Pointer to a non-array variable\n            if (agg.op == TOK.symbolOffset)\n            {\n                e.error(\"mutable variable `%s` cannot be %s at compile time, even through a pointer\", cast(char*)(modify ? \"modified\" : \"read\"), (cast(SymOffExp)agg).var.toChars());\n                return false;\n            }\n\n            if (agg.op == TOK.arrayLiteral || agg.op == TOK.string_)\n            {\n                dinteger_t len = resolveArrayLength(agg);\n                if (ofs + indx >= len)\n                {\n                    e.error(\"pointer index `[%lld]` exceeds allocated memory block `[0..%lld]`\", ofs + indx, len);\n                    return false;\n                }\n            }\n            else\n            {\n                if (ofs + indx != 0)\n                {\n                    e.error(\"pointer index `[%lld]` lies outside memory block `[0..1]`\", ofs + indx);\n                    return false;\n                }\n            }\n            *pagg = agg;\n            *pidx = ofs + indx;\n            return true;\n        }\n\n        Expression e1 = interpret(e.e1, istate);\n        if (exceptionOrCantInterpret(e1))\n            return false;\n        if (e1.op == TOK.null_)\n        {\n            e.error(\"cannot index null array `%s`\", e.e1.toChars());\n            return false;\n        }\n        if (e1.op == TOK.vector)\n            e1 = (cast(VectorExp)e1).e1;\n\n        // Set the $ variable, and find the array literal to modify\n        if (e1.op != TOK.arrayLiteral && e1.op != TOK.string_ && e1.op != TOK.slice)\n        {\n            e.error(\"cannot determine length of `%s` at compile time\", e.e1.toChars());\n            return false;\n        }\n\n        dinteger_t len = resolveArrayLength(e1);\n        if (e.lengthVar)\n        {\n            Expression dollarExp = new IntegerExp(e.loc, len, Type.tsize_t);\n            ctfeStack.push(e.lengthVar);\n            setValue(e.lengthVar, dollarExp);\n        }\n        Expression e2 = interpret(e.e2, istate);\n        if (e.lengthVar)\n            ctfeStack.pop(e.lengthVar); // $ is defined only inside []\n        if (exceptionOrCantInterpret(e2))\n            return false;\n        if (e2.op != TOK.int64)\n        {\n            e.error(\"CTFE internal error: non-integral index `[%s]`\", e.e2.toChars());\n            return false;\n        }\n\n        if (e1.op == TOK.slice)\n        {\n            // Simplify index of slice: agg[lwr..upr][indx] --> agg[indx']\n            uinteger_t index = e2.toInteger();\n            uinteger_t ilwr = (cast(SliceExp)e1).lwr.toInteger();\n            uinteger_t iupr = (cast(SliceExp)e1).upr.toInteger();\n\n            if (index > iupr - ilwr)\n            {\n                e.error(\"index %llu exceeds array length %llu\", index, iupr - ilwr);\n                return false;\n            }\n            *pagg = (cast(SliceExp)e1).e1;\n            *pidx = index + ilwr;\n        }\n        else\n        {\n            *pagg = e1;\n            *pidx = e2.toInteger();\n            if (len <= *pidx)\n            {\n                e.error(\"array index %lld is out of bounds `[0..%lld]`\", *pidx, len);\n                return false;\n            }\n        }\n        return true;\n    }\n\n    override void visit(IndexExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s IndexExp::interpret() %s, goal = %d\\n\", e.loc.toChars(), e.toChars(), goal);\n        }\n        if (e.e1.type.toBasetype().ty == Tpointer)\n        {\n            Expression agg;\n            uinteger_t indexToAccess;\n            if (!resolveIndexing(e, istate, &agg, &indexToAccess, false))\n            {\n                result = CTFEExp.cantexp;\n                return;\n            }\n            if (agg.op == TOK.arrayLiteral || agg.op == TOK.string_)\n            {\n                if (goal == ctfeNeedLvalue)\n                {\n                    // if we need a reference, IndexExp shouldn't be interpreting\n                    // the expression to a value, it should stay as a reference\n                    emplaceExp!(IndexExp)(pue, e.loc, agg, new IntegerExp(e.e2.loc, indexToAccess, e.e2.type));\n                    result = pue.exp();\n                    result.type = e.type;\n                    return;\n                }\n                result = ctfeIndex(e.loc, e.type, agg, indexToAccess);\n                return;\n            }\n            else\n            {\n                assert(indexToAccess == 0);\n                result = interpret(agg, istate, goal);\n                if (exceptionOrCant(result))\n                    return;\n                result = paintTypeOntoLiteral(e.type, result);\n                return;\n            }\n        }\n\n        if (e.e1.type.toBasetype().ty == Taarray)\n        {\n            Expression e1 = interpret(e.e1, istate);\n            if (exceptionOrCant(e1))\n                return;\n            if (e1.op == TOK.null_)\n            {\n                if (goal == ctfeNeedLvalue && e1.type.ty == Taarray && e.modifiable)\n                {\n                    assert(0); // does not reach here?\n                }\n                e.error(\"cannot index null array `%s`\", e.e1.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            Expression e2 = interpret(e.e2, istate);\n            if (exceptionOrCant(e2))\n                return;\n\n            if (goal == ctfeNeedLvalue)\n            {\n                // Pointer or reference of a scalar type\n                if (e1 == e.e1 && e2 == e.e2)\n                    result = e;\n                else\n                {\n                    emplaceExp!(IndexExp)(pue, e.loc, e1, e2);\n                    result = pue.exp();\n                    result.type = e.type;\n                }\n                return;\n            }\n\n            assert(e1.op == TOK.assocArrayLiteral);\n            UnionExp e2tmp = void;\n            e2 = resolveSlice(e2, &e2tmp);\n            result = findKeyInAA(e.loc, cast(AssocArrayLiteralExp)e1, e2);\n            if (!result)\n            {\n                e.error(\"key `%s` not found in associative array `%s`\", e2.toChars(), e.e1.toChars());\n                result = CTFEExp.cantexp;\n            }\n            return;\n        }\n\n        Expression agg;\n        uinteger_t indexToAccess;\n        if (!resolveIndexing(e, istate, &agg, &indexToAccess, false))\n        {\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        if (goal == ctfeNeedLvalue)\n        {\n            Expression e2 = new IntegerExp(e.e2.loc, indexToAccess, Type.tsize_t);\n            emplaceExp!(IndexExp)(pue, e.loc, agg, e2);\n            result = pue.exp();\n            result.type = e.type;\n            return;\n        }\n\n        result = ctfeIndex(e.loc, e.type, agg, indexToAccess);\n        if (exceptionOrCant(result))\n            return;\n        if (result.op == TOK.void_)\n        {\n            e.error(\"`%s` is used before initialized\", e.toChars());\n            errorSupplemental(result.loc, \"originally uninitialized here\");\n            result = CTFEExp.cantexp;\n            return;\n        }\n        result = paintTypeOntoLiteral(e.type, result);\n    }\n\n    override void visit(SliceExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s SliceExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        if (e.e1.type.toBasetype().ty == Tpointer)\n        {\n            // Slicing a pointer. Note that there is no $ in this case.\n            Expression e1 = interpret(e.e1, istate);\n            if (exceptionOrCant(e1))\n                return;\n            if (e1.op == TOK.int64)\n            {\n                e.error(\"cannot slice invalid pointer `%s` of value `%s`\", e.e1.toChars(), e1.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n\n            /* Evaluate lower and upper bounds of slice\n             */\n            Expression lwr = interpret(e.lwr, istate);\n            if (exceptionOrCant(lwr))\n                return;\n            Expression upr = interpret(e.upr, istate);\n            if (exceptionOrCant(upr))\n                return;\n            uinteger_t ilwr = lwr.toInteger();\n            uinteger_t iupr = upr.toInteger();\n\n            dinteger_t ofs;\n            Expression agg = getAggregateFromPointer(e1, &ofs);\n            ilwr += ofs;\n            iupr += ofs;\n            if (agg.op == TOK.null_)\n            {\n                if (iupr == ilwr)\n                {\n                    result = new NullExp(e.loc);\n                    result.type = e.type;\n                    return;\n                }\n                e.error(\"cannot slice null pointer `%s`\", e.e1.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            if (agg.op == TOK.symbolOffset)\n            {\n                e.error(\"slicing pointers to static variables is not supported in CTFE\");\n                result = CTFEExp.cantexp;\n                return;\n            }\n            if (agg.op != TOK.arrayLiteral && agg.op != TOK.string_)\n            {\n                e.error(\"pointer `%s` cannot be sliced at compile time (it does not point to an array)\", e.e1.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            assert(agg.op == TOK.arrayLiteral || agg.op == TOK.string_);\n            dinteger_t len = ArrayLength(Type.tsize_t, agg).exp().toInteger();\n            //Type *pointee = ((TypePointer *)agg.type)->next;\n            if (iupr > (len + 1) || iupr < ilwr)\n            {\n                e.error(\"pointer slice `[%lld..%lld]` exceeds allocated memory block `[0..%lld]`\", ilwr, iupr, len);\n                result = CTFEExp.cantexp;\n                return;\n            }\n            if (ofs != 0)\n            {\n                lwr = new IntegerExp(e.loc, ilwr, lwr.type);\n                upr = new IntegerExp(e.loc, iupr, upr.type);\n            }\n            emplaceExp!(SliceExp)(pue, e.loc, agg, lwr, upr);\n            result = pue.exp();\n            result.type = e.type;\n            return;\n        }\n\n        Expression e1 = interpret(e.e1, istate);\n        if (exceptionOrCant(e1))\n            return;\n\n        if (!e.lwr)\n        {\n            result = paintTypeOntoLiteral(e.type, e1);\n            return;\n        }\n\n        /* Set the $ variable\n         */\n        if (e1.op != TOK.arrayLiteral && e1.op != TOK.string_ && e1.op != TOK.null_ && e1.op != TOK.slice)\n        {\n            e.error(\"cannot determine length of `%s` at compile time\", e1.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        uinteger_t dollar = resolveArrayLength(e1);\n        if (e.lengthVar)\n        {\n            auto dollarExp = new IntegerExp(e.loc, dollar, Type.tsize_t);\n            ctfeStack.push(e.lengthVar);\n            setValue(e.lengthVar, dollarExp);\n        }\n\n        /* Evaluate lower and upper bounds of slice\n         */\n        Expression lwr = interpret(e.lwr, istate);\n        if (exceptionOrCant(lwr))\n        {\n            if (e.lengthVar)\n                ctfeStack.pop(e.lengthVar);\n            return;\n        }\n        Expression upr = interpret(e.upr, istate);\n        if (exceptionOrCant(upr))\n        {\n            if (e.lengthVar)\n                ctfeStack.pop(e.lengthVar);\n            return;\n        }\n        if (e.lengthVar)\n            ctfeStack.pop(e.lengthVar); // $ is defined only inside [L..U]\n\n        uinteger_t ilwr = lwr.toInteger();\n        uinteger_t iupr = upr.toInteger();\n        if (e1.op == TOK.null_)\n        {\n            if (ilwr == 0 && iupr == 0)\n            {\n                result = e1;\n                return;\n            }\n            e1.error(\"slice `[%llu..%llu]` is out of bounds\", ilwr, iupr);\n            result = CTFEExp.cantexp;\n            return;\n        }\n        if (e1.op == TOK.slice)\n        {\n            SliceExp se = cast(SliceExp)e1;\n            // Simplify slice of slice:\n            //  aggregate[lo1..up1][lwr..upr] ---> aggregate[lwr'..upr']\n            uinteger_t lo1 = se.lwr.toInteger();\n            uinteger_t up1 = se.upr.toInteger();\n            if (ilwr > iupr || iupr > up1 - lo1)\n            {\n                e.error(\"slice `[%llu..%llu]` exceeds array bounds `[%llu..%llu]`\", ilwr, iupr, lo1, up1);\n                result = CTFEExp.cantexp;\n                return;\n            }\n            ilwr += lo1;\n            iupr += lo1;\n            emplaceExp!(SliceExp)(pue, e.loc, se.e1, new IntegerExp(e.loc, ilwr, lwr.type), new IntegerExp(e.loc, iupr, upr.type));\n            result = pue.exp();\n            result.type = e.type;\n            return;\n        }\n        if (e1.op == TOK.arrayLiteral || e1.op == TOK.string_)\n        {\n            if (iupr < ilwr || dollar < iupr)\n            {\n                e.error(\"slice `[%lld..%lld]` exceeds array bounds `[0..%lld]`\", ilwr, iupr, dollar);\n                result = CTFEExp.cantexp;\n                return;\n            }\n        }\n        emplaceExp!(SliceExp)(pue, e.loc, e1, lwr, upr);\n        result = pue.exp();\n        result.type = e.type;\n    }\n\n    override void visit(InExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s InExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        Expression e1 = interpret(e.e1, istate);\n        if (exceptionOrCant(e1))\n            return;\n        Expression e2 = interpret(e.e2, istate);\n        if (exceptionOrCant(e2))\n            return;\n        if (e2.op == TOK.null_)\n        {\n            emplaceExp!(NullExp)(pue, e.loc, e.type);\n            result = pue.exp();\n            return;\n        }\n        if (e2.op != TOK.assocArrayLiteral)\n        {\n            e.error(\"`%s` cannot be interpreted at compile time\", e.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        e1 = resolveSlice(e1);\n        result = findKeyInAA(e.loc, cast(AssocArrayLiteralExp)e2, e1);\n        if (exceptionOrCant(result))\n            return;\n        if (!result)\n        {\n            emplaceExp!(NullExp)(pue, e.loc, e.type);\n            result = pue.exp();\n        }\n        else\n        {\n            // Create a CTFE pointer &aa[index]\n            result = new IndexExp(e.loc, e2, e1);\n            result.type = e.type.nextOf();\n            emplaceExp!(AddrExp)(pue, e.loc, result, e.type);\n            result = pue.exp();\n        }\n    }\n\n    override void visit(CatExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s CatExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        {\n        Expression e1 = interpret(e.e1, istate);\n        if (exceptionOrCant(e1))\n            return;\n        Expression e2 = interpret(e.e2, istate);\n        if (exceptionOrCant(e2))\n            return;\n\n        UnionExp e1tmp = void;\n        e1 = resolveSlice(e1, &e1tmp);\n        UnionExp e2tmp = void;\n        e2 = resolveSlice(e2, &e2tmp);\n        result = ctfeCat(e.loc, e.type, e1, e2).copy();\n        }\n        if (CTFEExp.isCantExp(result))\n        {\n            e.error(\"`%s` cannot be interpreted at compile time\", e.toChars());\n            return;\n        }\n        // We know we still own it, because we interpreted both e1 and e2\n        if (result.op == TOK.arrayLiteral)\n        {\n            ArrayLiteralExp ale = cast(ArrayLiteralExp)result;\n            ale.ownedByCtfe = OwnedBy.ctfe;\n\n            // https://issues.dlang.org/show_bug.cgi?id=14686\n            for (size_t i = 0; i < ale.elements.dim; i++)\n            {\n                Expression ex = evaluatePostblit(istate, (*ale.elements)[i]);\n                if (exceptionOrCant(ex))\n                    return;\n            }\n        }\n        if (result.op == TOK.string_)\n            (cast(StringExp)result).ownedByCtfe = OwnedBy.ctfe;\n    }\n\n    override void visit(DeleteExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s DeleteExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        result = interpret(e.e1, istate);\n        if (exceptionOrCant(result))\n            return;\n\n        if (result.op == TOK.null_)\n        {\n            result = CTFEExp.voidexp;\n            return;\n        }\n\n        auto tb = e.e1.type.toBasetype();\n        switch (tb.ty)\n        {\n        case Tclass:\n            if (result.op != TOK.classReference)\n            {\n                e.error(\"`delete` on invalid class reference `%s`\", result.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n\n            auto cre = cast(ClassReferenceExp)result;\n            auto cd = cre.originalClass();\n            if (cd.aggDelete)\n            {\n                e.error(\"member deallocators not supported by CTFE\");\n                result = CTFEExp.cantexp;\n                return;\n            }\n\n            if (cd.dtor)\n            {\n                result = interpretFunction(cd.dtor, istate, null, cre);\n                if (exceptionOrCant(result))\n                    return;\n            }\n            break;\n\n        case Tpointer:\n            tb = (cast(TypePointer)tb).next.toBasetype();\n            if (tb.ty == Tstruct)\n            {\n                if (result.op != TOK.address ||\n                    (cast(AddrExp)result).e1.op != TOK.structLiteral)\n                {\n                    e.error(\"`delete` on invalid struct pointer `%s`\", result.toChars());\n                    result = CTFEExp.cantexp;\n                    return;\n                }\n\n                auto sd = (cast(TypeStruct)tb).sym;\n                auto sle = cast(StructLiteralExp)(cast(AddrExp)result).e1;\n                if (sd.aggDelete)\n                {\n                    e.error(\"member deallocators not supported by CTFE\");\n                    result = CTFEExp.cantexp;\n                    return;\n                }\n\n                if (sd.dtor)\n                {\n                    result = interpretFunction(sd.dtor, istate, null, sle);\n                    if (exceptionOrCant(result))\n                        return;\n                }\n            }\n            break;\n\n        case Tarray:\n            auto tv = tb.nextOf().baseElemOf();\n            if (tv.ty == Tstruct)\n            {\n                if (result.op != TOK.arrayLiteral)\n                {\n                    e.error(\"`delete` on invalid struct array `%s`\", result.toChars());\n                    result = CTFEExp.cantexp;\n                    return;\n                }\n\n                auto sd = (cast(TypeStruct)tv).sym;\n                if (sd.aggDelete)\n                {\n                    e.error(\"member deallocators not supported by CTFE\");\n                    result = CTFEExp.cantexp;\n                    return;\n                }\n\n                if (sd.dtor)\n                {\n                    auto ale = cast(ArrayLiteralExp)result;\n                    foreach (el; *ale.elements)\n                    {\n                        result = interpretFunction(sd.dtor, istate, null, el);\n                        if (exceptionOrCant(result))\n                            return;\n                    }\n                }\n            }\n            break;\n\n        default:\n            assert(0);\n        }\n        result = CTFEExp.voidexp;\n    }\n\n    override void visit(CastExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s CastExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        Expression e1 = interpret(e.e1, istate, goal);\n        if (exceptionOrCant(e1))\n            return;\n        // If the expression has been cast to void, do nothing.\n        if (e.to.ty == Tvoid)\n        {\n            result = CTFEExp.voidexp;\n            return;\n        }\n        if (e.to.ty == Tpointer && e1.op != TOK.null_)\n        {\n            Type pointee = (cast(TypePointer)e.type).next;\n            // Implement special cases of normally-unsafe casts\n            if (e1.op == TOK.int64)\n            {\n                // Happens with Windows HANDLEs, for example.\n                result = paintTypeOntoLiteral(e.to, e1);\n                return;\n            }\n\n            bool castToSarrayPointer = false;\n            bool castBackFromVoid = false;\n            if (e1.type.ty == Tarray || e1.type.ty == Tsarray || e1.type.ty == Tpointer)\n            {\n                // Check for unsupported type painting operations\n                // For slices, we need the type being sliced,\n                // since it may have already been type painted\n                Type elemtype = e1.type.nextOf();\n                if (e1.op == TOK.slice)\n                    elemtype = (cast(SliceExp)e1).e1.type.nextOf();\n\n                // Allow casts from X* to void *, and X** to void** for any X.\n                // But don't allow cast from X* to void**.\n                // So, we strip all matching * from source and target to find X.\n                // Allow casts to X* from void* only if the 'void' was originally an X;\n                // we check this later on.\n                Type ultimatePointee = pointee;\n                Type ultimateSrc = elemtype;\n                while (ultimatePointee.ty == Tpointer && ultimateSrc.ty == Tpointer)\n                {\n                    ultimatePointee = ultimatePointee.nextOf();\n                    ultimateSrc = ultimateSrc.nextOf();\n                }\n                if (ultimatePointee.ty == Tsarray && ultimatePointee.nextOf().equivalent(ultimateSrc))\n                {\n                    castToSarrayPointer = true;\n                }\n                else if (ultimatePointee.ty != Tvoid && ultimateSrc.ty != Tvoid && !isSafePointerCast(elemtype, pointee))\n                {\n                    e.error(\"reinterpreting cast from `%s*` to `%s*` is not supported in CTFE\", elemtype.toChars(), pointee.toChars());\n                    result = CTFEExp.cantexp;\n                    return;\n                }\n                if (ultimateSrc.ty == Tvoid)\n                    castBackFromVoid = true;\n            }\n\n            if (e1.op == TOK.slice)\n            {\n                if ((cast(SliceExp)e1).e1.op == TOK.null_)\n                {\n                    result = paintTypeOntoLiteral(e.type, (cast(SliceExp)e1).e1);\n                    return;\n                }\n                // Create a CTFE pointer &aggregate[1..2]\n                auto ei = new IndexExp(e.loc, (cast(SliceExp)e1).e1, (cast(SliceExp)e1).lwr);\n                ei.type = e.type.nextOf();\n                emplaceExp!(AddrExp)(pue, e.loc, ei, e.type);\n                result = pue.exp();\n                return;\n            }\n            if (e1.op == TOK.arrayLiteral || e1.op == TOK.string_)\n            {\n                // Create a CTFE pointer &[1,2,3][0] or &\"abc\"[0]\n                auto ei = new IndexExp(e.loc, e1, new IntegerExp(e.loc, 0, Type.tsize_t));\n                ei.type = e.type.nextOf();\n                emplaceExp!(AddrExp)(pue, e.loc, ei, e.type);\n                result = pue.exp();\n                return;\n            }\n            if (e1.op == TOK.index && !(cast(IndexExp)e1).e1.type.equals(e1.type))\n            {\n                // type painting operation\n                IndexExp ie = cast(IndexExp)e1;\n                result = new IndexExp(e1.loc, ie.e1, ie.e2);\n                if (castBackFromVoid)\n                {\n                    // get the original type. For strings, it's just the type...\n                    Type origType = ie.e1.type.nextOf();\n                    // ..but for arrays of type void*, it's the type of the element\n                    if (ie.e1.op == TOK.arrayLiteral && ie.e2.op == TOK.int64)\n                    {\n                        ArrayLiteralExp ale = cast(ArrayLiteralExp)ie.e1;\n                        size_t indx = cast(size_t)ie.e2.toInteger();\n                        if (indx < ale.elements.dim)\n                        {\n                            if (Expression xx = (*ale.elements)[indx])\n                            {\n                                if (xx.op == TOK.index)\n                                    origType = (cast(IndexExp)xx).e1.type.nextOf();\n                                else if (xx.op == TOK.address)\n                                    origType = (cast(AddrExp)xx).e1.type;\n                                else if (xx.op == TOK.variable)\n                                    origType = (cast(VarExp)xx).var.type;\n                            }\n                        }\n                    }\n                    if (!isSafePointerCast(origType, pointee))\n                    {\n                        e.error(\"using `void*` to reinterpret cast from `%s*` to `%s*` is not supported in CTFE\", origType.toChars(), pointee.toChars());\n                        result = CTFEExp.cantexp;\n                        return;\n                    }\n                }\n                result.type = e.type;\n                return;\n            }\n            if (e1.op == TOK.address)\n            {\n                Type origType = (cast(AddrExp)e1).e1.type;\n                if (isSafePointerCast(origType, pointee))\n                {\n                    emplaceExp!(AddrExp)(pue, e.loc, (cast(AddrExp)e1).e1, e.type);\n                    result = pue.exp();\n                    return;\n                }\n                if (castToSarrayPointer && pointee.toBasetype().ty == Tsarray && (cast(AddrExp)e1).e1.op == TOK.index)\n                {\n                    // &val[idx]\n                    dinteger_t dim = (cast(TypeSArray)pointee.toBasetype()).dim.toInteger();\n                    IndexExp ie = cast(IndexExp)(cast(AddrExp)e1).e1;\n                    Expression lwr = ie.e2;\n                    Expression upr = new IntegerExp(ie.e2.loc, ie.e2.toInteger() + dim, Type.tsize_t);\n\n                    // Create a CTFE pointer &val[idx..idx+dim]\n                    auto er = new SliceExp(e.loc, ie.e1, lwr, upr);\n                    er.type = pointee;\n                    emplaceExp!(AddrExp)(pue, e.loc, er, e.type);\n                    result = pue.exp();\n                    return;\n                }\n            }\n            if (e1.op == TOK.variable || e1.op == TOK.symbolOffset)\n            {\n                // type painting operation\n                Type origType = (cast(SymbolExp)e1).var.type;\n                if (castBackFromVoid && !isSafePointerCast(origType, pointee))\n                {\n                    e.error(\"using `void*` to reinterpret cast from `%s*` to `%s*` is not supported in CTFE\", origType.toChars(), pointee.toChars());\n                    result = CTFEExp.cantexp;\n                    return;\n                }\n                if (e1.op == TOK.variable)\n                    emplaceExp!(VarExp)(pue, e.loc, (cast(VarExp)e1).var);\n                else\n                    emplaceExp!(SymOffExp)(pue, e.loc, (cast(SymOffExp)e1).var, (cast(SymOffExp)e1).offset);\n                result = pue.exp();\n                result.type = e.to;\n                return;\n            }\n\n            // Check if we have a null pointer (eg, inside a struct)\n            e1 = interpret(e1, istate);\n            if (e1.op != TOK.null_)\n            {\n                e.error(\"pointer cast from `%s` to `%s` is not supported at compile time\", e1.type.toChars(), e.to.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n        }\n        if (e.to.ty == Tsarray && e.e1.type.ty == Tvector)\n        {\n            // Special handling for: cast(float[4])__vector([w, x, y, z])\n            e1 = interpret(e.e1, istate);\n            if (exceptionOrCant(e1))\n                return;\n            assert(e1.op == TOK.vector);\n            e1 = (cast(VectorExp)e1).e1;\n        }\n        if (e.to.ty == Tarray && e1.op == TOK.slice)\n        {\n            // Note that the slice may be void[], so when checking for dangerous\n            // casts, we need to use the original type, which is se.e1.\n            SliceExp se = cast(SliceExp)e1;\n            if (!isSafePointerCast(se.e1.type.nextOf(), e.to.nextOf()))\n            {\n                e.error(\"array cast from `%s` to `%s` is not supported at compile time\", se.e1.type.toChars(), e.to.toChars());\n                result = CTFEExp.cantexp;\n                return;\n            }\n            emplaceExp!(SliceExp)(pue, e1.loc, se.e1, se.lwr, se.upr);\n            result = pue.exp();\n            result.type = e.to;\n            return;\n        }\n        // Disallow array type painting, except for conversions between built-in\n        // types of identical size.\n        if ((e.to.ty == Tsarray || e.to.ty == Tarray) && (e1.type.ty == Tsarray || e1.type.ty == Tarray) && !isSafePointerCast(e1.type.nextOf(), e.to.nextOf()))\n        {\n            e.error(\"array cast from `%s` to `%s` is not supported at compile time\", e1.type.toChars(), e.to.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        if (e.to.ty == Tsarray)\n            e1 = resolveSlice(e1);\n        if (e.to.toBasetype().ty == Tbool && e1.type.ty == Tpointer)\n        {\n            emplaceExp!(IntegerExp)(pue, e.loc, e1.op != TOK.null_, e.to);\n            result = pue.exp();\n            return;\n        }\n        result = ctfeCast(e.loc, e.type, e.to, e1);\n    }\n\n    override void visit(AssertExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s AssertExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        Expression e1 = interpret(pue, e.e1, istate);\n        if (exceptionOrCant(e1))\n            return;\n        if (isTrueBool(e1))\n        {\n        }\n        else if (e1.isBool(false))\n        {\n            if (e.msg)\n            {\n                UnionExp ue = void;\n                result = interpret(&ue, e.msg, istate);\n                if (exceptionOrCant(result))\n                    return;\n                e.error(\"`%s`\", result.toChars());\n            }\n            else\n                e.error(\"`%s` failed\", e.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        else\n        {\n            e.error(\"`%s` is not a compile time boolean expression\", e1.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        result = e1;\n        return;\n    }\n\n    override void visit(PtrExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s PtrExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        // Check for int<->float and long<->double casts.\n        if (e.e1.op == TOK.symbolOffset && (cast(SymOffExp)e.e1).offset == 0 && (cast(SymOffExp)e.e1).var.isVarDeclaration() && isFloatIntPaint(e.type, (cast(SymOffExp)e.e1).var.type))\n        {\n            // *(cast(int*)&v), where v is a float variable\n            result = paintFloatInt(getVarExp(e.loc, istate, (cast(SymOffExp)e.e1).var, ctfeNeedRvalue), e.type);\n            return;\n        }\n        if (e.e1.op == TOK.cast_ && (cast(CastExp)e.e1).e1.op == TOK.address)\n        {\n            // *(cast(int*)&x), where x is a float expression\n            Expression x = (cast(AddrExp)(cast(CastExp)e.e1).e1).e1;\n            if (isFloatIntPaint(e.type, x.type))\n            {\n                result = paintFloatInt(interpret(x, istate), e.type);\n                return;\n            }\n        }\n\n        // Constant fold *(&structliteral + offset)\n        if (e.e1.op == TOK.add)\n        {\n            AddExp ae = cast(AddExp)e.e1;\n            if (ae.e1.op == TOK.address && ae.e2.op == TOK.int64)\n            {\n                AddrExp ade = cast(AddrExp)ae.e1;\n                Expression ex = interpret(ade.e1, istate);\n                if (exceptionOrCant(ex))\n                    return;\n                if (ex.op == TOK.structLiteral)\n                {\n                    StructLiteralExp se = cast(StructLiteralExp)ex;\n                    dinteger_t offset = ae.e2.toInteger();\n                    result = se.getField(e.type, cast(uint)offset);\n                    if (result)\n                        return;\n                }\n            }\n        }\n\n        // It's possible we have an array bounds error. We need to make sure it\n        // errors with this line number, not the one where the pointer was set.\n        result = interpret(e.e1, istate);\n        if (exceptionOrCant(result))\n            return;\n\n        if (result.op == TOK.function_)\n            return;\n        if (result.op == TOK.symbolOffset)\n        {\n            SymOffExp soe = cast(SymOffExp)result;\n            if (soe.offset == 0 && soe.var.isFuncDeclaration())\n                return;\n            e.error(\"cannot dereference pointer to static variable `%s` at compile time\", soe.var.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        if (result.op != TOK.address)\n        {\n            if (result.op == TOK.null_)\n                e.error(\"dereference of null pointer `%s`\", e.e1.toChars());\n            else\n                e.error(\"dereference of invalid pointer `%s`\", result.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        // *(&x) ==> x\n        result = (cast(AddrExp)result).e1;\n\n        if (result.op == TOK.slice && e.type.toBasetype().ty == Tsarray)\n        {\n            /* aggr[lwr..upr]\n             * upr may exceed the upper boundary of aggr, but the check is deferred\n             * until those out-of-bounds elements will be touched.\n             */\n            return;\n        }\n        result = interpret(result, istate, goal);\n        if (exceptionOrCant(result))\n            return;\n\n        debug (LOG)\n        {\n            if (CTFEExp.isCantExp(result))\n                printf(\"PtrExp::interpret() %s = CTFEExp::cantexp\\n\", e.toChars());\n        }\n    }\n\n    override void visit(DotVarExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s DotVarExp::interpret() %s, goal = %d\\n\", e.loc.toChars(), e.toChars(), goal);\n        }\n        Expression ex = interpret(e.e1, istate);\n        if (exceptionOrCant(ex))\n            return;\n\n        if (FuncDeclaration f = e.var.isFuncDeclaration())\n        {\n            if (ex == e.e1)\n                result = e; // optimize: reuse this CTFE reference\n            else\n            {\n                emplaceExp!(DotVarExp)(pue, e.loc, ex, f, false);\n                result = pue.exp();\n                result.type = e.type;\n            }\n            return;\n        }\n\n        VarDeclaration v = e.var.isVarDeclaration();\n        if (!v)\n        {\n            e.error(\"CTFE internal error: `%s`\", e.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        if (ex.op == TOK.null_)\n        {\n            if (ex.type.toBasetype().ty == Tclass)\n                e.error(\"class `%s` is `null` and cannot be dereferenced\", e.e1.toChars());\n            else\n                e.error(\"CTFE internal error: null this `%s`\", e.e1.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        if (ex.op != TOK.structLiteral && ex.op != TOK.classReference)\n        {\n            e.error(\"`%s.%s` is not yet implemented at compile time\", e.e1.toChars(), e.var.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        StructLiteralExp se;\n        int i;\n\n        // We can't use getField, because it makes a copy\n        if (ex.op == TOK.classReference)\n        {\n            se = (cast(ClassReferenceExp)ex).value;\n            i = (cast(ClassReferenceExp)ex).findFieldIndexByName(v);\n        }\n        else\n        {\n            se = cast(StructLiteralExp)ex;\n            i = findFieldIndexByName(se.sd, v);\n        }\n        if (i == -1)\n        {\n            e.error(\"couldn't find field `%s` of type `%s` in `%s`\", v.toChars(), e.type.toChars(), se.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        if (goal == ctfeNeedLvalue)\n        {\n            Expression ev = (*se.elements)[i];\n            if (!ev || ev.op == TOK.void_)\n                (*se.elements)[i] = voidInitLiteral(e.type, v).copy();\n            // just return the (simplified) dotvar expression as a CTFE reference\n            if (e.e1 == ex)\n                result = e;\n            else\n            {\n                emplaceExp!(DotVarExp)(pue, e.loc, ex, v);\n                result = pue.exp();\n                result.type = e.type;\n            }\n            return;\n        }\n\n        result = (*se.elements)[i];\n        if (!result)\n        {\n            e.error(\"Internal Compiler Error: null field `%s`\", v.toChars());\n            result = CTFEExp.cantexp;\n            return;\n        }\n        if (result.op == TOK.void_)\n        {\n            VoidInitExp ve = cast(VoidInitExp)result;\n            const(char)* s = ve.var.toChars();\n            if (v.overlapped)\n            {\n                e.error(\"reinterpretation through overlapped field `%s` is not allowed in CTFE\", s);\n                result = CTFEExp.cantexp;\n                return;\n            }\n            e.error(\"cannot read uninitialized variable `%s` in CTFE\", s);\n            result = CTFEExp.cantexp;\n            return;\n        }\n\n        if (v.type.ty != result.type.ty && v.type.ty == Tsarray)\n        {\n            // Block assignment from inside struct literals\n            auto tsa = cast(TypeSArray)v.type;\n            auto len = cast(size_t)tsa.dim.toInteger();\n            result = createBlockDuplicatedArrayLiteral(ex.loc, v.type, ex, len);\n            (*se.elements)[i] = result;\n        }\n        debug (LOG)\n        {\n            if (CTFEExp.isCantExp(result))\n                printf(\"DotVarExp::interpret() %s = CTFEExp::cantexp\\n\", e.toChars());\n        }\n    }\n\n    override void visit(RemoveExp e)\n    {\n        debug (LOG)\n        {\n            printf(\"%s RemoveExp::interpret() %s\\n\", e.loc.toChars(), e.toChars());\n        }\n        Expression agg = interpret(e.e1, istate);\n        if (exceptionOrCant(agg))\n            return;\n        Expression index = interpret(e.e2, istate);\n        if (exceptionOrCant(index))\n            return;\n        if (agg.op == TOK.null_)\n        {\n            result = CTFEExp.voidexp;\n            return;\n        }\n\n        assert(agg.op == TOK.assocArrayLiteral);\n        AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)agg;\n        Expressions* keysx = aae.keys;\n        Expressions* valuesx = aae.values;\n        size_t removed = 0;\n        for (size_t j = 0; j < valuesx.dim; ++j)\n        {\n            Expression ekey = (*keysx)[j];\n            int eq = ctfeEqual(e.loc, TOK.equal, ekey, index);\n            if (eq)\n                ++removed;\n            else if (removed != 0)\n            {\n                (*keysx)[j - removed] = ekey;\n                (*valuesx)[j - removed] = (*valuesx)[j];\n            }\n        }\n        valuesx.dim = valuesx.dim - removed;\n        keysx.dim = keysx.dim - removed;\n        emplaceExp!(IntegerExp)(pue, e.loc, removed ? 1 : 0, Type.tbool);\n        result = pue.exp();\n    }\n\n    override void visit(ClassReferenceExp e)\n    {\n        //printf(\"ClassReferenceExp::interpret() %s\\n\", e.value.toChars());\n        result = e;\n    }\n\n    override void visit(VoidInitExp e)\n    {\n        e.error(\"CTFE internal error: trying to read uninitialized variable\");\n        assert(0);\n    }\n\n    override void visit(ThrownExceptionExp e)\n    {\n        assert(0); // This should never be interpreted\n    }\n}\n\n/********************************************\n * Interpret the expression.\n * Params:\n *    pue = non-null pointer to temporary storage that can be used to store the return value\n *    e = Expression to interpret\n *    istate = context\n *    goal = what the result will be used for\n * Returns:\n *    resulting expression\n */\n\nExpression interpret(UnionExp* pue, Expression e, InterState* istate, CtfeGoal goal = ctfeNeedRvalue)\n{\n    if (!e)\n        return null;\n    scope Interpreter v = new Interpreter(pue, istate, goal);\n    e.accept(v);\n    Expression ex = v.result;\n    assert(goal == ctfeNeedNothing || ex !is null);\n    return ex;\n}\n\n///\nExpression interpret(Expression e, InterState* istate, CtfeGoal goal = ctfeNeedRvalue)\n{\n    UnionExp ue = void;\n    auto result = interpret(&ue, e, istate, goal);\n    if (result == ue.exp())\n        result = ue.copy();\n    return result;\n}\n\n/***********************************\n * Interpret the statement.\n * Params:\n *    pue = non-null pointer to temporary storage that can be used to store the return value\n *    s = Statement to interpret\n *    istate = context\n * Returns:\n *      NULL    continue to next statement\n *      TOK.cantExpression      cannot interpret statement at compile time\n *      !NULL   expression from return statement, or thrown exception\n */\nExpression interpret(UnionExp* pue, Statement s, InterState* istate)\n{\n    if (!s)\n        return null;\n    scope Interpreter v = new Interpreter(pue, istate, ctfeNeedNothing);\n    s.accept(v);\n    return v.result;\n}\n\n///\nExpression interpret(Statement s, InterState* istate)\n{\n    UnionExp ue = void;\n    auto result = interpret(&ue, s, istate);\n    if (result == ue.exp())\n        result = ue.copy();\n    return result;\n}\n\n/* All results destined for use outside of CTFE need to have their CTFE-specific\n * features removed.\n * In particular, all slices must be resolved.\n */\nprivate Expression scrubReturnValue(const ref Loc loc, Expression e)\n{\n    if (e.op == TOK.classReference)\n    {\n        StructLiteralExp se = (cast(ClassReferenceExp)e).value;\n        se.ownedByCtfe = OwnedBy.code;\n        if (!(se.stageflags & stageScrub))\n        {\n            int old = se.stageflags;\n            se.stageflags |= stageScrub;\n            if (Expression ex = scrubArray(loc, se.elements, true))\n                return ex;\n            se.stageflags = old;\n        }\n    }\n    if (e.op == TOK.void_)\n    {\n        error(loc, \"uninitialized variable `%s` cannot be returned from CTFE\", (cast(VoidInitExp)e).var.toChars());\n        return new ErrorExp();\n    }\n    e = resolveSlice(e);\n    if (e.op == TOK.structLiteral)\n    {\n        StructLiteralExp se = cast(StructLiteralExp)e;\n        se.ownedByCtfe = OwnedBy.code;\n        if (!(se.stageflags & stageScrub))\n        {\n            int old = se.stageflags;\n            se.stageflags |= stageScrub;\n            if (Expression ex = scrubArray(loc, se.elements, true))\n                return ex;\n            se.stageflags = old;\n        }\n    }\n    if (e.op == TOK.string_)\n    {\n        (cast(StringExp)e).ownedByCtfe = OwnedBy.code;\n    }\n    if (e.op == TOK.arrayLiteral)\n    {\n        (cast(ArrayLiteralExp)e).ownedByCtfe = OwnedBy.code;\n        if (Expression ex = scrubArray(loc, (cast(ArrayLiteralExp)e).elements))\n            return ex;\n    }\n    if (e.op == TOK.assocArrayLiteral)\n    {\n        AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)e;\n        aae.ownedByCtfe = OwnedBy.code;\n        if (Expression ex = scrubArray(loc, aae.keys))\n            return ex;\n        if (Expression ex = scrubArray(loc, aae.values))\n            return ex;\n        aae.type = toBuiltinAAType(aae.type);\n    }\n    return e;\n}\n\n// Return true if every element is either void,\n// or is an array literal or struct literal of void elements.\nprivate bool isEntirelyVoid(Expressions* elems)\n{\n    for (size_t i = 0; i < elems.dim; i++)\n    {\n        Expression m = (*elems)[i];\n        // It can be NULL for performance reasons,\n        // see StructLiteralExp::interpret().\n        if (!m)\n            continue;\n\n        if (!(m.op == TOK.void_) && !(m.op == TOK.arrayLiteral && isEntirelyVoid((cast(ArrayLiteralExp)m).elements)) && !(m.op == TOK.structLiteral && isEntirelyVoid((cast(StructLiteralExp)m).elements)))\n        {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Scrub all members of an array. Return false if error\nprivate Expression scrubArray(const ref Loc loc, Expressions* elems, bool structlit = false)\n{\n    for (size_t i = 0; i < elems.dim; i++)\n    {\n        Expression m = (*elems)[i];\n        // It can be NULL for performance reasons,\n        // see StructLiteralExp::interpret().\n        if (!m)\n            continue;\n\n        // A struct .init may contain void members.\n        // Static array members are a weird special case (bug 10994).\n        if (structlit && ((m.op == TOK.void_) || (m.op == TOK.arrayLiteral && m.type.ty == Tsarray && isEntirelyVoid((cast(ArrayLiteralExp)m).elements)) || (m.op == TOK.structLiteral && isEntirelyVoid((cast(StructLiteralExp)m).elements))))\n        {\n            m = null;\n        }\n        else\n        {\n            m = scrubReturnValue(loc, m);\n            if (CTFEExp.isCantExp(m) || m.op == TOK.error)\n                return m;\n        }\n        (*elems)[i] = m;\n    }\n    return null;\n}\n\nprivate Expression scrubCacheValue(const ref Loc loc, Expression e)\n{\n    if (e.op == TOK.classReference)\n    {\n        StructLiteralExp sle = (cast(ClassReferenceExp)e).value;\n        sle.ownedByCtfe = OwnedBy.cache;\n        if (!(sle.stageflags & stageScrub))\n        {\n            int old = sle.stageflags;\n            sle.stageflags |= stageScrub;\n            if (Expression ex = scrubArrayCache(loc, sle.elements))\n                return ex;\n            sle.stageflags = old;\n        }\n    }\n    if (e.op == TOK.structLiteral)\n    {\n        StructLiteralExp sle = cast(StructLiteralExp)e;\n        sle.ownedByCtfe = OwnedBy.cache;\n        if (!(sle.stageflags & stageScrub))\n        {\n            int old = sle.stageflags;\n            sle.stageflags |= stageScrub;\n            if (Expression ex = scrubArrayCache(loc, sle.elements))\n                return ex;\n            sle.stageflags = old;\n        }\n    }\n    if (e.op == TOK.string_)\n    {\n        (cast(StringExp)e).ownedByCtfe = OwnedBy.cache;\n    }\n    if (e.op == TOK.arrayLiteral)\n    {\n        (cast(ArrayLiteralExp)e).ownedByCtfe = OwnedBy.cache;\n        if (Expression ex = scrubArrayCache(loc, (cast(ArrayLiteralExp)e).elements))\n            return ex;\n    }\n    if (e.op == TOK.assocArrayLiteral)\n    {\n        AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)e;\n        aae.ownedByCtfe = OwnedBy.cache;\n        if (Expression ex = scrubArrayCache(loc, aae.keys))\n            return ex;\n        if (Expression ex = scrubArrayCache(loc, aae.values))\n            return ex;\n    }\n    return e;\n}\n\nprivate Expression scrubArrayCache(const ref Loc loc, Expressions* elems)\n{\n    for (size_t i = 0; i < elems.dim; i++)\n    {\n        Expression m = (*elems)[i];\n        if (!m)\n            continue;\n        (*elems)[i] = scrubCacheValue(loc, m);\n    }\n    return null;\n}\n\n/******************************* Special Functions ***************************/\n\nprivate Expression interpret_length(InterState* istate, Expression earg)\n{\n    //printf(\"interpret_length()\\n\");\n    earg = interpret(earg, istate);\n    if (exceptionOrCantInterpret(earg))\n        return earg;\n    dinteger_t len = 0;\n    if (earg.op == TOK.assocArrayLiteral)\n        len = (cast(AssocArrayLiteralExp)earg).keys.dim;\n    else\n        assert(earg.op == TOK.null_);\n    Expression e = new IntegerExp(earg.loc, len, Type.tsize_t);\n    return e;\n}\n\nprivate Expression interpret_keys(InterState* istate, Expression earg, Type returnType)\n{\n    debug (LOG)\n    {\n        printf(\"interpret_keys()\\n\");\n    }\n    earg = interpret(earg, istate);\n    if (exceptionOrCantInterpret(earg))\n        return earg;\n    if (earg.op == TOK.null_)\n        return new NullExp(earg.loc, returnType);\n    if (earg.op != TOK.assocArrayLiteral && earg.type.toBasetype().ty != Taarray)\n        return null;\n    assert(earg.op == TOK.assocArrayLiteral);\n    AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg;\n    auto ae = new ArrayLiteralExp(aae.loc, returnType, aae.keys);\n    ae.ownedByCtfe = aae.ownedByCtfe;\n    return copyLiteral(ae).copy();\n}\n\nprivate Expression interpret_values(InterState* istate, Expression earg, Type returnType)\n{\n    debug (LOG)\n    {\n        printf(\"interpret_values()\\n\");\n    }\n    earg = interpret(earg, istate);\n    if (exceptionOrCantInterpret(earg))\n        return earg;\n    if (earg.op == TOK.null_)\n        return new NullExp(earg.loc, returnType);\n    if (earg.op != TOK.assocArrayLiteral && earg.type.toBasetype().ty != Taarray)\n        return null;\n    assert(earg.op == TOK.assocArrayLiteral);\n    AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg;\n    auto ae = new ArrayLiteralExp(aae.loc, returnType, aae.values);\n    ae.ownedByCtfe = aae.ownedByCtfe;\n    //printf(\"result is %s\\n\", e.toChars());\n    return copyLiteral(ae).copy();\n}\n\nprivate Expression interpret_dup(InterState* istate, Expression earg)\n{\n    debug (LOG)\n    {\n        printf(\"interpret_dup()\\n\");\n    }\n    earg = interpret(earg, istate);\n    if (exceptionOrCantInterpret(earg))\n        return earg;\n    if (earg.op == TOK.null_)\n        return new NullExp(earg.loc, earg.type);\n    if (earg.op != TOK.assocArrayLiteral && earg.type.toBasetype().ty != Taarray)\n        return null;\n    assert(earg.op == TOK.assocArrayLiteral);\n    AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)copyLiteral(earg).copy();\n    for (size_t i = 0; i < aae.keys.dim; i++)\n    {\n        if (Expression e = evaluatePostblit(istate, (*aae.keys)[i]))\n            return e;\n        if (Expression e = evaluatePostblit(istate, (*aae.values)[i]))\n            return e;\n    }\n    aae.type = earg.type.mutableOf(); // repaint type from const(int[int]) to const(int)[int]\n    //printf(\"result is %s\\n\", aae.toChars());\n    return aae;\n}\n\n// signature is int delegate(ref Value) OR int delegate(ref Key, ref Value)\nprivate Expression interpret_aaApply(InterState* istate, Expression aa, Expression deleg)\n{\n    aa = interpret(aa, istate);\n    if (exceptionOrCantInterpret(aa))\n        return aa;\n    if (aa.op != TOK.assocArrayLiteral)\n        return new IntegerExp(deleg.loc, 0, Type.tsize_t);\n\n    FuncDeclaration fd = null;\n    Expression pthis = null;\n    if (deleg.op == TOK.delegate_)\n    {\n        fd = (cast(DelegateExp)deleg).func;\n        pthis = (cast(DelegateExp)deleg).e1;\n    }\n    else if (deleg.op == TOK.function_)\n        fd = (cast(FuncExp)deleg).fd;\n\n    assert(fd && fd.fbody);\n    assert(fd.parameters);\n    size_t numParams = fd.parameters.dim;\n    assert(numParams == 1 || numParams == 2);\n\n    Parameter fparam = Parameter.getNth((cast(TypeFunction)fd.type).parameters, numParams - 1);\n    bool wantRefValue = 0 != (fparam.storageClass & (STC.out_ | STC.ref_));\n\n    Expressions args = Expressions(numParams);\n\n    AssocArrayLiteralExp ae = cast(AssocArrayLiteralExp)aa;\n    if (!ae.keys || ae.keys.dim == 0)\n        return new IntegerExp(deleg.loc, 0, Type.tsize_t);\n    Expression eresult;\n\n    for (size_t i = 0; i < ae.keys.dim; ++i)\n    {\n        Expression ekey = (*ae.keys)[i];\n        Expression evalue = (*ae.values)[i];\n        if (wantRefValue)\n        {\n            Type t = evalue.type;\n            evalue = new IndexExp(deleg.loc, ae, ekey);\n            evalue.type = t;\n        }\n        args[numParams - 1] = evalue;\n        if (numParams == 2)\n            args[0] = ekey;\n\n        eresult = interpretFunction(fd, istate, &args, pthis);\n        if (exceptionOrCantInterpret(eresult))\n            return eresult;\n\n        assert(eresult.op == TOK.int64);\n        if ((cast(IntegerExp)eresult).getInteger() != 0)\n            return eresult;\n    }\n    return eresult;\n}\n\n/* Decoding UTF strings for foreach loops. Duplicates the functionality of\n * the twelve _aApplyXXn functions in aApply.d in the runtime.\n */\nprivate Expression foreachApplyUtf(InterState* istate, Expression str, Expression deleg, bool rvs)\n{\n    debug (LOG)\n    {\n        printf(\"foreachApplyUtf(%s, %s)\\n\", str.toChars(), deleg.toChars());\n    }\n    FuncDeclaration fd = null;\n    Expression pthis = null;\n    if (deleg.op == TOK.delegate_)\n    {\n        fd = (cast(DelegateExp)deleg).func;\n        pthis = (cast(DelegateExp)deleg).e1;\n    }\n    else if (deleg.op == TOK.function_)\n        fd = (cast(FuncExp)deleg).fd;\n\n    assert(fd && fd.fbody);\n    assert(fd.parameters);\n    size_t numParams = fd.parameters.dim;\n    assert(numParams == 1 || numParams == 2);\n    Type charType = (*fd.parameters)[numParams - 1].type;\n    Type indexType = numParams == 2 ? (*fd.parameters)[0].type : Type.tsize_t;\n    size_t len = cast(size_t)resolveArrayLength(str);\n    if (len == 0)\n        return new IntegerExp(deleg.loc, 0, indexType);\n\n    str = resolveSlice(str);\n\n    StringExp se = null;\n    ArrayLiteralExp ale = null;\n    if (str.op == TOK.string_)\n        se = cast(StringExp)str;\n    else if (str.op == TOK.arrayLiteral)\n        ale = cast(ArrayLiteralExp)str;\n    else\n    {\n        str.error(\"CTFE internal error: cannot foreach `%s`\", str.toChars());\n        return CTFEExp.cantexp;\n    }\n    Expressions args = Expressions(numParams);\n\n    Expression eresult = null; // ded-store to prevent spurious warning\n\n    // Buffers for encoding; also used for decoding array literals\n    char[4] utf8buf;\n    wchar[2] utf16buf;\n\n    size_t start = rvs ? len : 0;\n    size_t end = rvs ? 0 : len;\n    for (size_t indx = start; indx != end;)\n    {\n        // Step 1: Decode the next dchar from the string.\n\n        const(char)* errmsg = null; // Used for reporting decoding errors\n        dchar rawvalue; // Holds the decoded dchar\n        size_t currentIndex = indx; // The index of the decoded character\n\n        if (ale)\n        {\n            // If it is an array literal, copy the code points into the buffer\n            size_t buflen = 1; // #code points in the buffer\n            size_t n = 1; // #code points in this char\n            size_t sz = cast(size_t)ale.type.nextOf().size();\n\n            switch (sz)\n            {\n            case 1:\n                if (rvs)\n                {\n                    // find the start of the string\n                    --indx;\n                    buflen = 1;\n                    while (indx > 0 && buflen < 4)\n                    {\n                        Expression r = (*ale.elements)[indx];\n                        assert(r.op == TOK.int64);\n                        char x = cast(char)(cast(IntegerExp)r).getInteger();\n                        if ((x & 0xC0) != 0x80)\n                            break;\n                        ++buflen;\n                    }\n                }\n                else\n                    buflen = (indx + 4 > len) ? len - indx : 4;\n                for (size_t i = 0; i < buflen; ++i)\n                {\n                    Expression r = (*ale.elements)[indx + i];\n                    assert(r.op == TOK.int64);\n                    utf8buf[i] = cast(char)(cast(IntegerExp)r).getInteger();\n                }\n                n = 0;\n                errmsg = utf_decodeChar(&utf8buf[0], buflen, n, rawvalue);\n                break;\n\n            case 2:\n                if (rvs)\n                {\n                    // find the start of the string\n                    --indx;\n                    buflen = 1;\n                    Expression r = (*ale.elements)[indx];\n                    assert(r.op == TOK.int64);\n                    ushort x = cast(ushort)(cast(IntegerExp)r).getInteger();\n                    if (indx > 0 && x >= 0xDC00 && x <= 0xDFFF)\n                    {\n                        --indx;\n                        ++buflen;\n                    }\n                }\n                else\n                    buflen = (indx + 2 > len) ? len - indx : 2;\n                for (size_t i = 0; i < buflen; ++i)\n                {\n                    Expression r = (*ale.elements)[indx + i];\n                    assert(r.op == TOK.int64);\n                    utf16buf[i] = cast(ushort)(cast(IntegerExp)r).getInteger();\n                }\n                n = 0;\n                errmsg = utf_decodeWchar(&utf16buf[0], buflen, n, rawvalue);\n                break;\n\n            case 4:\n                {\n                    if (rvs)\n                        --indx;\n                    Expression r = (*ale.elements)[indx];\n                    assert(r.op == TOK.int64);\n                    rawvalue = cast(dchar)(cast(IntegerExp)r).getInteger();\n                    n = 1;\n                }\n                break;\n\n            default:\n                assert(0);\n            }\n            if (!rvs)\n                indx += n;\n        }\n        else\n        {\n            // String literals\n            size_t saveindx; // used for reverse iteration\n\n            switch (se.sz)\n            {\n            case 1:\n                if (rvs)\n                {\n                    // find the start of the string\n                    --indx;\n                    while (indx > 0 && ((se.getCodeUnit(indx) & 0xC0) == 0x80))\n                        --indx;\n                    saveindx = indx;\n                }\n                errmsg = utf_decodeChar(se.string, se.len, indx, rawvalue);\n                if (rvs)\n                    indx = saveindx;\n                break;\n\n            case 2:\n                if (rvs)\n                {\n                    // find the start\n                    --indx;\n                    auto wc = se.getCodeUnit(indx);\n                    if (wc >= 0xDC00 && wc <= 0xDFFF)\n                        --indx;\n                    saveindx = indx;\n                }\n                errmsg = utf_decodeWchar(se.wstring, se.len, indx, rawvalue);\n                if (rvs)\n                    indx = saveindx;\n                break;\n\n            case 4:\n                if (rvs)\n                    --indx;\n                rawvalue = se.getCodeUnit(indx);\n                if (!rvs)\n                    ++indx;\n                break;\n\n            default:\n                assert(0);\n            }\n        }\n        if (errmsg)\n        {\n            deleg.error(\"`%s`\", errmsg);\n            return CTFEExp.cantexp;\n        }\n\n        // Step 2: encode the dchar in the target encoding\n\n        int charlen = 1; // How many codepoints are involved?\n        switch (charType.size())\n        {\n        case 1:\n            charlen = utf_codeLengthChar(rawvalue);\n            utf_encodeChar(&utf8buf[0], rawvalue);\n            break;\n        case 2:\n            charlen = utf_codeLengthWchar(rawvalue);\n            utf_encodeWchar(&utf16buf[0], rawvalue);\n            break;\n        case 4:\n            break;\n        default:\n            assert(0);\n        }\n        if (rvs)\n            currentIndex = indx;\n\n        // Step 3: call the delegate once for each code point\n\n        // The index only needs to be set once\n        if (numParams == 2)\n            args[0] = new IntegerExp(deleg.loc, currentIndex, indexType);\n\n        Expression val = null;\n\n        for (int k = 0; k < charlen; ++k)\n        {\n            dchar codepoint;\n            switch (charType.size())\n            {\n            case 1:\n                codepoint = utf8buf[k];\n                break;\n            case 2:\n                codepoint = utf16buf[k];\n                break;\n            case 4:\n                codepoint = rawvalue;\n                break;\n            default:\n                assert(0);\n            }\n            val = new IntegerExp(str.loc, codepoint, charType);\n\n            args[numParams - 1] = val;\n\n            eresult = interpretFunction(fd, istate, &args, pthis);\n            if (exceptionOrCantInterpret(eresult))\n                return eresult;\n            assert(eresult.op == TOK.int64);\n            if ((cast(IntegerExp)eresult).getInteger() != 0)\n                return eresult;\n        }\n    }\n    return eresult;\n}\n\n/* If this is a built-in function, return the interpreted result,\n * Otherwise, return NULL.\n */\nprivate Expression evaluateIfBuiltin(InterState* istate, const ref Loc loc, FuncDeclaration fd, Expressions* arguments, Expression pthis)\n{\n    Expression e = null;\n    size_t nargs = arguments ? arguments.dim : 0;\n    if (!pthis)\n    {\n        if (isBuiltin(fd) == BUILTIN.yes)\n        {\n            Expressions args = Expressions(nargs);\n            for (size_t i = 0; i < args.dim; i++)\n            {\n                Expression earg = (*arguments)[i];\n                earg = interpret(earg, istate);\n                if (exceptionOrCantInterpret(earg))\n                    return earg;\n                args[i] = earg;\n            }\n            e = eval_builtin(loc, fd, &args);\n            if (!e)\n            {\n                error(loc, \"cannot evaluate unimplemented builtin `%s` at compile time\", fd.toChars());\n                e = CTFEExp.cantexp;\n            }\n        }\n    }\n    if (!pthis)\n    {\n        Expression firstarg = nargs > 0 ? (*arguments)[0] : null;\n        if (firstarg && firstarg.type.toBasetype().ty == Taarray)\n        {\n            TypeAArray firstAAtype = cast(TypeAArray)firstarg.type;\n            const id = fd.ident.toChars();\n            if (nargs == 1 && fd.ident == Id.aaLen)\n                return interpret_length(istate, firstarg);\n            if (nargs == 3 && !strcmp(id, \"_aaApply\"))\n                return interpret_aaApply(istate, firstarg, arguments.data[2]);\n            if (nargs == 3 && !strcmp(id, \"_aaApply2\"))\n                return interpret_aaApply(istate, firstarg, arguments.data[2]);\n            if (nargs == 1 && !strcmp(id, \"keys\") && !strcmp(fd.toParent2().ident.toChars(), \"object\"))\n                return interpret_keys(istate, firstarg, firstAAtype.index.arrayOf());\n            if (nargs == 1 && !strcmp(id, \"values\") && !strcmp(fd.toParent2().ident.toChars(), \"object\"))\n                return interpret_values(istate, firstarg, firstAAtype.nextOf().arrayOf());\n            if (nargs == 1 && !strcmp(id, \"rehash\") && !strcmp(fd.toParent2().ident.toChars(), \"object\"))\n                return interpret(firstarg, istate);\n            if (nargs == 1 && !strcmp(id, \"dup\") && !strcmp(fd.toParent2().ident.toChars(), \"object\"))\n                return interpret_dup(istate, firstarg);\n        }\n    }\n    if (pthis && !fd.fbody && fd.isCtorDeclaration() && fd.parent && fd.parent.parent && fd.parent.parent.ident == Id.object)\n    {\n        if (pthis.op == TOK.classReference && fd.parent.ident == Id.Throwable)\n        {\n            // At present, the constructors just copy their arguments into the struct.\n            // But we might need some magic if stack tracing gets added to druntime.\n            StructLiteralExp se = (cast(ClassReferenceExp)pthis).value;\n            assert(arguments.dim <= se.elements.dim);\n            for (size_t i = 0; i < arguments.dim; ++i)\n            {\n                e = interpret((*arguments)[i], istate);\n                if (exceptionOrCantInterpret(e))\n                    return e;\n                (*se.elements)[i] = e;\n            }\n            return CTFEExp.voidexp;\n        }\n    }\n    if (nargs == 1 && !pthis && (fd.ident == Id.criticalenter || fd.ident == Id.criticalexit))\n    {\n        // Support synchronized{} as a no-op\n        return CTFEExp.voidexp;\n    }\n    if (!pthis)\n    {\n        const idlen = fd.ident.toString().length;\n        const id = fd.ident.toChars();\n        if (nargs == 2 && (idlen == 10 || idlen == 11) && !strncmp(id, \"_aApply\", 7))\n        {\n            // Functions from aApply.d and aApplyR.d in the runtime\n            bool rvs = (idlen == 11); // true if foreach_reverse\n            char c = id[idlen - 3]; // char width: 'c', 'w', or 'd'\n            char s = id[idlen - 2]; // string width: 'c', 'w', or 'd'\n            char n = id[idlen - 1]; // numParams: 1 or 2.\n            // There are 12 combinations\n            if ((n == '1' || n == '2') && (c == 'c' || c == 'w' || c == 'd') && (s == 'c' || s == 'w' || s == 'd') && c != s)\n            {\n                Expression str = (*arguments)[0];\n                str = interpret(str, istate);\n                if (exceptionOrCantInterpret(str))\n                    return str;\n                return foreachApplyUtf(istate, str, (*arguments)[1], rvs);\n            }\n        }\n    }\n    return e;\n}\n\nprivate Expression evaluatePostblit(InterState* istate, Expression e)\n{\n    Type tb = e.type.baseElemOf();\n    if (tb.ty != Tstruct)\n        return null;\n    StructDeclaration sd = (cast(TypeStruct)tb).sym;\n    if (!sd.postblit)\n        return null;\n\n    if (e.op == TOK.arrayLiteral)\n    {\n        ArrayLiteralExp ale = cast(ArrayLiteralExp)e;\n        for (size_t i = 0; i < ale.elements.dim; i++)\n        {\n            e = evaluatePostblit(istate, (*ale.elements)[i]);\n            if (e)\n                return e;\n        }\n        return null;\n    }\n    if (e.op == TOK.structLiteral)\n    {\n        // e.__postblit()\n        e = interpretFunction(sd.postblit, istate, null, e);\n        if (exceptionOrCantInterpret(e))\n            return e;\n        return null;\n    }\n    assert(0);\n}\n\nprivate Expression evaluateDtor(InterState* istate, Expression e)\n{\n    Type tb = e.type.baseElemOf();\n    if (tb.ty != Tstruct)\n        return null;\n    StructDeclaration sd = (cast(TypeStruct)tb).sym;\n    if (!sd.dtor)\n        return null;\n\n    if (e.op == TOK.arrayLiteral)\n    {\n        ArrayLiteralExp alex = cast(ArrayLiteralExp)e;\n        for (size_t i = alex.elements.dim; 0 < i--;)\n            e = evaluateDtor(istate, (*alex.elements)[i]);\n    }\n    else if (e.op == TOK.structLiteral)\n    {\n        // e.__dtor()\n        e = interpretFunction(sd.dtor, istate, null, e);\n    }\n    else\n        assert(0);\n    if (exceptionOrCantInterpret(e))\n        return e;\n    return null;\n}\n\n/*************************** CTFE Sanity Checks ***************************/\n/* Setter functions for CTFE variable values.\n * These functions exist to check for compiler CTFE bugs.\n */\nprivate bool hasValue(VarDeclaration vd)\n{\n    if (vd.ctfeAdrOnStack == cast(size_t)-1)\n        return false;\n    return null !is getValue(vd);\n}\n\n// Don't check for validity\nprivate void setValueWithoutChecking(VarDeclaration vd, Expression newval)\n{\n    ctfeStack.setValue(vd, newval);\n}\n\nprivate void setValue(VarDeclaration vd, Expression newval)\n{\n    version (none)\n    {\n        if (!((vd.storage_class & (STC.out_ | STC.ref_)) ? isCtfeReferenceValid(newval) : isCtfeValueValid(newval)))\n        {\n            printf(\"[%s] vd = %s %s, newval = %s\\n\", vd.loc.toChars(), vd.type.toChars(), vd.toChars(), newval.toChars());\n        }\n    }\n    assert((vd.storage_class & (STC.out_ | STC.ref_)) ? isCtfeReferenceValid(newval) : isCtfeValueValid(newval));\n    ctfeStack.setValue(vd, newval);\n}\n"
  },
  {
    "path": "gcc/d/dmd/dmacro.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dmacro.d, _dmacro.d)\n * Documentation:  https://dlang.org/phobos/dmd_dmacro.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dmacro.d\n */\n\nmodule dmd.dmacro;\n\nimport core.stdc.ctype;\nimport core.stdc.string;\nimport dmd.doc;\nimport dmd.errors;\nimport dmd.globals;\nimport dmd.root.outbuffer;\nimport dmd.root.rmem;\n\nstruct Macro\n{\nprivate:\n    Macro* next;            // next in list\n    const(char)[] name;     // macro name\n    const(char)[] text;     // macro replacement text\n    int inuse;              // macro is in use (don't expand)\n\n    this(const(char)[] name, const(char)[] text)\n    {\n        this.name = name;\n        this.text = text;\n    }\n\n    Macro* search(const(char)[] name)\n    {\n        Macro* table;\n        //printf(\"Macro::search(%.*s)\\n\", name.length, name.ptr);\n        for (table = &this; table; table = table.next)\n        {\n            if (table.name == name)\n            {\n                //printf(\"\\tfound %d\\n\", table.textlen);\n                break;\n            }\n        }\n        return table;\n    }\n\npublic:\n    static Macro* define(Macro** ptable, const(char)[] name, const(char)[] text)\n    {\n        //printf(\"Macro::define('%.*s' = '%.*s')\\n\", name.length, name.ptr, text.length, text.ptr);\n        Macro* table;\n        //assert(ptable);\n        for (table = *ptable; table; table = table.next)\n        {\n            if (table.name == name)\n            {\n                table.text = text;\n                return table;\n            }\n        }\n        table = new Macro(name, text);\n        table.next = *ptable;\n        *ptable = table;\n        return table;\n    }\n\n    /*****************************************************\n     * Expand macro in place in buf.\n     * Only look at the text in buf from start to end.\n     */\n    void expand(OutBuffer* buf, size_t start, size_t* pend, const(char)[] arg)\n    {\n        version (none)\n        {\n            printf(\"Macro::expand(buf[%d..%d], arg = '%.*s')\\n\", start, *pend, cast(int)arg.length, arg.ptr);\n            printf(\"Buf is: '%.*s'\\n\", *pend - start, buf.data + start);\n        }\n        // limit recursive expansion\n        __gshared int nest;\n        __gshared const(int) nestLimit = 1000;\n        if (nest > nestLimit)\n        {\n            error(Loc.initial, \"DDoc macro expansion limit exceeded; more than %d expansions.\", nestLimit);\n            return;\n        }\n        nest++;\n        size_t end = *pend;\n        assert(start <= end);\n        assert(end <= buf.offset);\n        /* First pass - replace $0\n         */\n        arg = memdup(arg);\n        for (size_t u = start; u + 1 < end;)\n        {\n            char* p = cast(char*)buf.data; // buf.data is not loop invariant\n            /* Look for $0, but not $$0, and replace it with arg.\n             */\n            if (p[u] == '$' && (isdigit(p[u + 1]) || p[u + 1] == '+'))\n            {\n                if (u > start && p[u - 1] == '$')\n                {\n                    // Don't expand $$0, but replace it with $0\n                    buf.remove(u - 1, 1);\n                    end--;\n                    u += 1; // now u is one past the closing '1'\n                    continue;\n                }\n                char c = p[u + 1];\n                int n = (c == '+') ? -1 : c - '0';\n                const(char)[] marg;\n                if (n == 0)\n                {\n                    marg = arg;\n                }\n                else\n                    extractArgN(arg, marg, n);\n                if (marg.length == 0)\n                {\n                    // Just remove macro invocation\n                    //printf(\"Replacing '$%c' with '%.*s'\\n\", p[u + 1], cast(int)marg.length, marg.ptr);\n                    buf.remove(u, 2);\n                    end -= 2;\n                }\n                else if (c == '+')\n                {\n                    // Replace '$+' with 'arg'\n                    //printf(\"Replacing '$%c' with '%.*s'\\n\", p[u + 1], cast(int)marg.length, marg.ptr);\n                    buf.remove(u, 2);\n                    buf.insert(u, marg);\n                    end += marg.length - 2;\n                    // Scan replaced text for further expansion\n                    size_t mend = u + marg.length;\n                    expand(buf, u, &mend, null);\n                    end += mend - (u + marg.length);\n                    u = mend;\n                }\n                else\n                {\n                    // Replace '$1' with '\\xFF{arg\\xFF}'\n                    //printf(\"Replacing '$%c' with '\\xFF{%.*s\\xFF}'\\n\", p[u + 1], cast(int)marg.length, marg.ptr);\n                    buf.data[u] = 0xFF;\n                    buf.data[u + 1] = '{';\n                    buf.insert(u + 2, marg);\n                    buf.insert(u + 2 + marg.length, \"\\xFF}\");\n                    end += -2 + 2 + marg.length + 2;\n                    // Scan replaced text for further expansion\n                    size_t mend = u + 2 + marg.length;\n                    expand(buf, u + 2, &mend, null);\n                    end += mend - (u + 2 + marg.length);\n                    u = mend;\n                }\n                //printf(\"u = %d, end = %d\\n\", u, end);\n                //printf(\"#%.*s#\\n\", end, &buf.data[0]);\n                continue;\n            }\n            u++;\n        }\n        /* Second pass - replace other macros\n         */\n        for (size_t u = start; u + 4 < end;)\n        {\n            char* p = cast(char*)buf.data; // buf.data is not loop invariant\n            /* A valid start of macro expansion is $(c, where c is\n             * an id start character, and not $$(c.\n             */\n            if (p[u] == '$' && p[u + 1] == '(' && isIdStart(p + u + 2))\n            {\n                //printf(\"\\tfound macro start '%c'\\n\", p[u + 2]);\n                char* name = p + u + 2;\n                size_t namelen = 0;\n                const(char)[] marg;\n                size_t v;\n                /* Scan forward to find end of macro name and\n                 * beginning of macro argument (marg).\n                 */\n                for (v = u + 2; v < end; v += utfStride(p + v))\n                {\n                    if (!isIdTail(p + v))\n                    {\n                        // We've gone past the end of the macro name.\n                        namelen = v - (u + 2);\n                        break;\n                    }\n                }\n                v += extractArgN(p[v .. end], marg, 0);\n                assert(v <= end);\n                if (v < end)\n                {\n                    // v is on the closing ')'\n                    if (u > start && p[u - 1] == '$')\n                    {\n                        // Don't expand $$(NAME), but replace it with $(NAME)\n                        buf.remove(u - 1, 1);\n                        end--;\n                        u = v; // now u is one past the closing ')'\n                        continue;\n                    }\n                    Macro* m = search(name[0 .. namelen]);\n                    if (!m)\n                    {\n                        immutable undef = \"DDOC_UNDEFINED_MACRO\";\n                        m = search(undef);\n                        if (m)\n                        {\n                            // Macro was not defined, so this is an expansion of\n                            //   DDOC_UNDEFINED_MACRO. Prepend macro name to args.\n                            // marg = name[ ] ~ \",\" ~ marg[ ];\n                            if (marg.length)\n                            {\n                                char* q = cast(char*)mem.xmalloc(namelen + 1 + marg.length);\n                                assert(q);\n                                memcpy(q, name, namelen);\n                                q[namelen] = ',';\n                                memcpy(q + namelen + 1, marg.ptr, marg.length);\n                                marg = q[0 .. marg.length + namelen + 1];\n                            }\n                            else\n                            {\n                                marg = name[0 .. namelen];\n                            }\n                        }\n                    }\n                    if (m)\n                    {\n                        if (m.inuse && marg.length == 0)\n                        {\n                            // Remove macro invocation\n                            buf.remove(u, v + 1 - u);\n                            end -= v + 1 - u;\n                        }\n                        else if (m.inuse && ((arg.length == marg.length && memcmp(arg.ptr, marg.ptr, arg.length) == 0) ||\n                                             (arg.length + 4 == marg.length && marg[0] == 0xFF && marg[1] == '{' && memcmp(arg.ptr, marg.ptr + 2, arg.length) == 0 && marg[marg.length - 2] == 0xFF && marg[marg.length - 1] == '}')))\n                        {\n                            /* Recursive expansion:\n                             *   marg is same as arg (with blue paint added)\n                             * Just leave in place.\n                             */\n                        }\n                        else\n                        {\n                            //printf(\"\\tmacro '%.*s'(%.*s) = '%.*s'\\n\", cast(int)m.namelen, m.name, cast(int)marg.length, marg.ptr, cast(int)m.textlen, m.text);\n                            marg = memdup(marg);\n                            // Insert replacement text\n                            buf.spread(v + 1, 2 + m.text.length + 2);\n                            buf.data[v + 1] = 0xFF;\n                            buf.data[v + 2] = '{';\n                            buf.data[v + 3 .. v + 3 + m.text.length] = cast(ubyte[])m.text[];\n                            buf.data[v + 3 + m.text.length] = 0xFF;\n                            buf.data[v + 3 + m.text.length + 1] = '}';\n                            end += 2 + m.text.length + 2;\n                            // Scan replaced text for further expansion\n                            m.inuse++;\n                            size_t mend = v + 1 + 2 + m.text.length + 2;\n                            expand(buf, v + 1, &mend, marg);\n                            end += mend - (v + 1 + 2 + m.text.length + 2);\n                            m.inuse--;\n                            buf.remove(u, v + 1 - u);\n                            end -= v + 1 - u;\n                            u += mend - (v + 1);\n                            mem.xfree(cast(char*)marg.ptr);\n                            //printf(\"u = %d, end = %d\\n\", u, end);\n                            //printf(\"#%.*s#\\n\", end - u, &buf.data[u]);\n                            continue;\n                        }\n                    }\n                    else\n                    {\n                        // Replace $(NAME) with nothing\n                        buf.remove(u, v + 1 - u);\n                        end -= (v + 1 - u);\n                        continue;\n                    }\n                }\n            }\n            u++;\n        }\n        mem.xfree(cast(char*)arg);\n        *pend = end;\n        nest--;\n    }\n}\n\n/************************\n * Make mutable copy of slice p.\n * Params:\n *      p = slice\n * Returns:\n *      copy allocated with mem.xmalloc()\n */\n\nprivate char[] memdup(const(char)[] p)\n{\n    size_t len = p.length;\n    return (cast(char*)memcpy(mem.xmalloc(len), p.ptr, len))[0 .. len];\n}\n\n/**********************************************************\n * Given buffer buf[], extract argument marg[].\n * Params:\n *      buf = source string\n *      marg = set to slice of buf[]\n *      n =     0:      get entire argument\n *              1..9:   get nth argument\n *              -1:     get 2nd through end\n */\nprivate size_t extractArgN(const(char)[] buf, out const(char)[] marg, int n)\n{\n    /* Scan forward for matching right parenthesis.\n     * Nest parentheses.\n     * Skip over \"...\" and '...' strings inside HTML tags.\n     * Skip over <!-- ... --> comments.\n     * Skip over previous macro insertions\n     * Set marg.\n     */\n    uint parens = 1;\n    ubyte instring = 0;\n    uint incomment = 0;\n    uint intag = 0;\n    uint inexp = 0;\n    uint argn = 0;\n    size_t v = 0;\n    const p = buf.ptr;\n    const end = buf.length;\nLargstart:\n    // Skip first space, if any, to find the start of the macro argument\n    if (n != 1 && v < end && isspace(p[v]))\n        v++;\n    size_t vstart = v;\n    for (; v < end; v++)\n    {\n        char c = p[v];\n        switch (c)\n        {\n        case ',':\n            if (!inexp && !instring && !incomment && parens == 1)\n            {\n                argn++;\n                if (argn == 1 && n == -1)\n                {\n                    v++;\n                    goto Largstart;\n                }\n                if (argn == n)\n                    break;\n                if (argn + 1 == n)\n                {\n                    v++;\n                    goto Largstart;\n                }\n            }\n            continue;\n        case '(':\n            if (!inexp && !instring && !incomment)\n                parens++;\n            continue;\n        case ')':\n            if (!inexp && !instring && !incomment && --parens == 0)\n            {\n                break;\n            }\n            continue;\n        case '\"':\n        case '\\'':\n            if (!inexp && !incomment && intag)\n            {\n                if (c == instring)\n                    instring = 0;\n                else if (!instring)\n                    instring = c;\n            }\n            continue;\n        case '<':\n            if (!inexp && !instring && !incomment)\n            {\n                if (v + 6 < end && p[v + 1] == '!' && p[v + 2] == '-' && p[v + 3] == '-')\n                {\n                    incomment = 1;\n                    v += 3;\n                }\n                else if (v + 2 < end && isalpha(p[v + 1]))\n                    intag = 1;\n            }\n            continue;\n        case '>':\n            if (!inexp)\n                intag = 0;\n            continue;\n        case '-':\n            if (!inexp && !instring && incomment && v + 2 < end && p[v + 1] == '-' && p[v + 2] == '>')\n            {\n                incomment = 0;\n                v += 2;\n            }\n            continue;\n        case 0xFF:\n            if (v + 1 < end)\n            {\n                if (p[v + 1] == '{')\n                    inexp++;\n                else if (p[v + 1] == '}')\n                    inexp--;\n            }\n            continue;\n        default:\n            continue;\n        }\n        break;\n    }\n    if (argn == 0 && n == -1)\n        marg = p[v .. v];\n    else\n        marg = p[vstart .. v];\n    //printf(\"extractArg%d('%.*s') = '%.*s'\\n\", n, cast(int)end, p, cast(int)marg.length, marg.ptr);\n    return v;\n}\n"
  },
  {
    "path": "gcc/d/dmd/dmangle.d",
    "content": "/**\n * Compiler implementation of the $(LINK2 http://www.dlang.org, D programming language)\n *\n * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors: Walter Bright, http://www.digitalmars.com\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dmangle.d, _dmangle.d)\n * Documentation:  https://dlang.org/phobos/dmd_dmangle.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dmangle.d\n * References:  https://dlang.org/blog/2017/12/20/ds-newfangled-name-mangling/\n */\n\nmodule dmd.dmangle;\n\nimport core.stdc.ctype;\nimport core.stdc.stdio;\nimport core.stdc.string;\n\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dmodule;\nimport dmd.dsymbol;\nimport dmd.dtemplate;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.root.ctfloat;\nimport dmd.root.outbuffer;\nimport dmd.root.aav;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.utf;\nimport dmd.visitor;\n\nprivate immutable char[TMAX] mangleChar =\n[\n    Tchar        : 'a',\n    Tbool        : 'b',\n    Tcomplex80   : 'c',\n    Tfloat64     : 'd',\n    Tfloat80     : 'e',\n    Tfloat32     : 'f',\n    Tint8        : 'g',\n    Tuns8        : 'h',\n    Tint32       : 'i',\n    Timaginary80 : 'j',\n    Tuns32       : 'k',\n    Tint64       : 'l',\n    Tuns64       : 'm',\n    Tnone        : 'n',\n    Tnull        : 'n', // yes, same as TypeNone\n    Timaginary32 : 'o',\n    Timaginary64 : 'p',\n    Tcomplex32   : 'q',\n    Tcomplex64   : 'r',\n    Tint16       : 's',\n    Tuns16       : 't',\n    Twchar       : 'u',\n    Tvoid        : 'v',\n    Tdchar       : 'w',\n    //              x   // const\n    //              y   // immutable\n    Tint128      : 'z', // zi\n    Tuns128      : 'z', // zk\n\n    Tarray       : 'A',\n    Ttuple       : 'B',\n    Tclass       : 'C',\n    Tdelegate    : 'D',\n    Tenum        : 'E',\n    Tfunction    : 'F', // D function\n    Tsarray      : 'G',\n    Taarray      : 'H',\n    Tident       : 'I',\n    //              J   // out\n    //              K   // ref\n    //              L   // lazy\n    //              M   // has this, or scope\n    //              N   // Nh:vector Ng:wild\n    //              O   // shared\n    Tpointer     : 'P',\n    //              Q   // Type/symbol/identifier backward reference\n    Treference   : 'R',\n    Tstruct      : 'S',\n    //              T   // Ttypedef\n    //              U   // C function\n    //              V   // Pascal function\n    //              W   // Windows function\n    //              X   // variadic T t...)\n    //              Y   // variadic T t,...)\n    //              Z   // not variadic, end of parameters\n\n    // '@' shouldn't appear anywhere in the deco'd names\n    Tinstance    : '@',\n    Terror       : '@',\n    Ttypeof      : '@',\n    Tslice       : '@',\n    Treturn      : '@',\n    Tvector      : '@',\n];\n\nunittest\n{\n    foreach (i, mangle; mangleChar)\n    {\n        if (mangle == char.init)\n        {\n            fprintf(stderr, \"ty = %u\\n\", cast(uint)i);\n            assert(0);\n        }\n    }\n}\n\n/***********************\n * Mangle basic type ty to buf.\n */\n\nprivate void tyToDecoBuffer(OutBuffer* buf, int ty)\n{\n    const c = mangleChar[ty];\n    buf.writeByte(c);\n    if (c == 'z')\n        buf.writeByte(ty == Tint128 ? 'i' : 'k');\n}\n\n/*********************************\n * Mangling for mod.\n */\nprivate void MODtoDecoBuffer(OutBuffer* buf, MOD mod)\n{\n    switch (mod)\n    {\n    case 0:\n        break;\n    case MODFlags.const_:\n        buf.writeByte('x');\n        break;\n    case MODFlags.immutable_:\n        buf.writeByte('y');\n        break;\n    case MODFlags.shared_:\n        buf.writeByte('O');\n        break;\n    case MODFlags.shared_ | MODFlags.const_:\n        buf.writestring(\"Ox\");\n        break;\n    case MODFlags.wild:\n        buf.writestring(\"Ng\");\n        break;\n    case MODFlags.wildconst:\n        buf.writestring(\"Ngx\");\n        break;\n    case MODFlags.shared_ | MODFlags.wild:\n        buf.writestring(\"ONg\");\n        break;\n    case MODFlags.shared_ | MODFlags.wildconst:\n        buf.writestring(\"ONgx\");\n        break;\n    default:\n        assert(0);\n    }\n}\n\nprivate extern (C++) final class Mangler : Visitor\n{\n    alias visit = Visitor.visit;\npublic:\n    static assert(Key.sizeof == size_t.sizeof);\n    AssocArray!(Type, size_t) types;\n    AssocArray!(Identifier, size_t) idents;\n    OutBuffer* buf;\n\n    extern (D) this(OutBuffer* buf)\n    {\n        this.buf = buf;\n    }\n\n    /**\n    * writes a back reference with the relative position encoded with base 26\n    *  using upper case letters for all digits but the last digit which uses\n    *  a lower case letter.\n    * The decoder has to look up the referenced position to determine\n    *  whether the back reference is an identifer (starts with a digit)\n    *  or a type (starts with a letter).\n    *\n    * Params:\n    *  pos           = relative position to encode\n    */\n    void writeBackRef(size_t pos)\n    {\n        buf.writeByte('Q');\n        enum base = 26;\n        size_t mul = 1;\n        while (pos >= mul * base)\n            mul *= base;\n        while (mul >= base)\n        {\n            auto dig = cast(ubyte)(pos / mul);\n            buf.writeByte('A' + dig);\n            pos -= dig * mul;\n            mul /= base;\n        }\n        buf.writeByte('a' + cast(ubyte)pos);\n    }\n\n    /**\n    * Back references a non-basic type\n    *\n    * The encoded mangling is\n    *       'Q' <relative position of first occurrence of type>\n    *\n    * Params:\n    *  t = the type to encode via back referencing\n    *\n    * Returns:\n    *  true if the type was found. A back reference has been encoded.\n    *  false if the type was not found. The current position is saved for later back references.\n    */\n    bool backrefType(Type t)\n    {\n        if (!t.isTypeBasic())\n        {\n            auto p = types.getLvalue(t);\n            if (*p)\n            {\n                writeBackRef(buf.offset - *p);\n                return true;\n            }\n            *p = buf.offset;\n        }\n        return false;\n    }\n\n    /**\n    * Back references a single identifier\n    *\n    * The encoded mangling is\n    *       'Q' <relative position of first occurrence of type>\n    *\n    * Params:\n    *  id = the identifier to encode via back referencing\n    *\n    * Returns:\n    *  true if the identifier was found. A back reference has been encoded.\n    *  false if the identifier was not found. The current position is saved for later back references.\n    */\n    bool backrefIdentifier(Identifier id)\n    {\n        auto p = idents.getLvalue(id);\n        if (*p)\n        {\n            writeBackRef(buf.offset - *p);\n            return true;\n        }\n        *p = buf.offset;\n        return false;\n    }\n\n    void mangleSymbol(Dsymbol s)\n    {\n        s.accept(this);\n    }\n\n    void mangleType(Type t)\n    {\n        if (!backrefType(t))\n            t.accept(this);\n    }\n\n    void mangleIdentifier(Identifier id, Dsymbol s)\n    {\n        if (!backrefIdentifier(id))\n            toBuffer(id.toString(), s);\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    /**************************************************\n     * Type mangling\n     */\n    void visitWithMask(Type t, ubyte modMask)\n    {\n        if (modMask != t.mod)\n        {\n            MODtoDecoBuffer(buf, t.mod);\n        }\n        mangleType(t);\n    }\n\n    override void visit(Type t)\n    {\n        tyToDecoBuffer(buf, t.ty);\n    }\n\n    override void visit(TypeNext t)\n    {\n        visit(cast(Type)t);\n        visitWithMask(t.next, t.mod);\n    }\n\n    override void visit(TypeVector t)\n    {\n        buf.writestring(\"Nh\");\n        visitWithMask(t.basetype, t.mod);\n    }\n\n    override void visit(TypeSArray t)\n    {\n        visit(cast(Type)t);\n        if (t.dim)\n            buf.print(t.dim.toInteger());\n        if (t.next)\n            visitWithMask(t.next, t.mod);\n    }\n\n    override void visit(TypeDArray t)\n    {\n        visit(cast(Type)t);\n        if (t.next)\n            visitWithMask(t.next, t.mod);\n    }\n\n    override void visit(TypeAArray t)\n    {\n        visit(cast(Type)t);\n        visitWithMask(t.index, 0);\n        visitWithMask(t.next, t.mod);\n    }\n\n    override void visit(TypeFunction t)\n    {\n        //printf(\"TypeFunction.toDecoBuffer() t = %p %s\\n\", t, t.toChars());\n        //static int nest; if (++nest == 50) *(char*)0=0;\n        mangleFuncType(t, t, t.mod, t.next);\n    }\n\n    void mangleFuncType(TypeFunction t, TypeFunction ta, ubyte modMask, Type tret)\n    {\n        //printf(\"mangleFuncType() %s\\n\", t.toChars());\n        if (t.inuse && tret)\n        {\n            // printf(\"TypeFunction.mangleFuncType() t = %s inuse\\n\", t.toChars());\n            t.inuse = 2; // flag error to caller\n            return;\n        }\n        t.inuse++;\n        if (modMask != t.mod)\n            MODtoDecoBuffer(buf, t.mod);\n\n        char mc;\n        final switch (t.linkage)\n        {\n        case LINK.default_:\n        case LINK.system:\n        case LINK.d:\n            mc = 'F';\n            break;\n        case LINK.c:\n            mc = 'U';\n            break;\n        case LINK.windows:\n            mc = 'W';\n            break;\n        case LINK.pascal:\n            mc = 'V';\n            break;\n        case LINK.cpp:\n            mc = 'R';\n            break;\n        case LINK.objc:\n            mc = 'Y';\n            break;\n        }\n        buf.writeByte(mc);\n\n        if (ta.purity)\n            buf.writestring(\"Na\");\n        if (ta.isnothrow)\n            buf.writestring(\"Nb\");\n        if (ta.isref)\n            buf.writestring(\"Nc\");\n        if (ta.isproperty)\n            buf.writestring(\"Nd\");\n        if (ta.isnogc)\n            buf.writestring(\"Ni\");\n\n        if (ta.isreturn)\n            buf.writestring(\"Nj\");\n        else if (ta.isscope && !ta.isscopeinferred)\n            buf.writestring(\"Nl\");\n\n        switch (ta.trust)\n        {\n            case TRUST.trusted:\n                buf.writestring(\"Ne\");\n                break;\n            case TRUST.safe:\n                buf.writestring(\"Nf\");\n                break;\n            default:\n                break;\n        }\n\n        // Write argument types\n        paramsToDecoBuffer(t.parameters);\n        //if (buf.data[buf.offset - 1] == '@') assert(0);\n        buf.writeByte('Z' - t.varargs); // mark end of arg list\n        if (tret !is null)\n            visitWithMask(tret, 0);\n        t.inuse--;\n    }\n\n    override void visit(TypeIdentifier t)\n    {\n        visit(cast(Type)t);\n        auto name = t.ident.toString();\n        buf.print(cast(int)name.length);\n        buf.writestring(name);\n    }\n\n    override void visit(TypeEnum t)\n    {\n        visit(cast(Type)t);\n        mangleSymbol(t.sym);\n    }\n\n    override void visit(TypeStruct t)\n    {\n        //printf(\"TypeStruct.toDecoBuffer('%s') = '%s'\\n\", t.toChars(), name);\n        visit(cast(Type)t);\n        mangleSymbol(t.sym);\n    }\n\n    override void visit(TypeClass t)\n    {\n        //printf(\"TypeClass.toDecoBuffer('%s' mod=%x) = '%s'\\n\", t.toChars(), mod, name);\n        visit(cast(Type)t);\n        mangleSymbol(t.sym);\n    }\n\n    override void visit(TypeTuple t)\n    {\n        //printf(\"TypeTuple.toDecoBuffer() t = %p, %s\\n\", t, t.toChars());\n        visit(cast(Type)t);\n        paramsToDecoBuffer(t.arguments);\n        buf.writeByte('Z');\n    }\n\n    override void visit(TypeNull t)\n    {\n        visit(cast(Type)t);\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    void mangleDecl(Declaration sthis)\n    {\n        mangleParent(sthis);\n        assert(sthis.ident);\n        mangleIdentifier(sthis.ident, sthis);\n        if (FuncDeclaration fd = sthis.isFuncDeclaration())\n        {\n            mangleFunc(fd, false);\n        }\n        else if (sthis.type)\n        {\n            visitWithMask(sthis.type, 0);\n        }\n        else\n            assert(0);\n    }\n\n    void mangleParent(Dsymbol s)\n    {\n        Dsymbol p;\n        if (TemplateInstance ti = s.isTemplateInstance())\n            p = ti.isTemplateMixin() ? ti.parent : ti.tempdecl.parent;\n        else\n            p = s.parent;\n        if (p)\n        {\n            mangleParent(p);\n            auto ti = p.isTemplateInstance();\n            if (ti && !ti.isTemplateMixin())\n            {\n                mangleTemplateInstance(ti);\n            }\n            else if (p.getIdent())\n            {\n                mangleIdentifier(p.ident, s);\n                if (FuncDeclaration f = p.isFuncDeclaration())\n                    mangleFunc(f, true);\n            }\n            else\n                buf.writeByte('0');\n        }\n    }\n\n    void mangleFunc(FuncDeclaration fd, bool inParent)\n    {\n        //printf(\"deco = '%s'\\n\", fd.type.deco ? fd.type.deco : \"null\");\n        //printf(\"fd.type = %s\\n\", fd.type.toChars());\n        if (fd.needThis() || fd.isNested())\n            buf.writeByte('M');\n\n        if (!fd.type || fd.type.ty == Terror)\n        {\n            // never should have gotten here, but could be the result of\n            // failed speculative compilation\n            buf.writestring(\"9__error__FZ\");\n\n            //printf(\"[%s] %s no type\\n\", fd.loc.toChars(), fd.toChars());\n            //assert(0); // don't mangle function until semantic3 done.\n        }\n        else if (inParent)\n        {\n            TypeFunction tf = cast(TypeFunction)fd.type;\n            TypeFunction tfo = cast(TypeFunction)fd.originalType;\n            mangleFuncType(tf, tfo, 0, null);\n        }\n        else\n        {\n            visitWithMask(fd.type, 0);\n        }\n    }\n\n    /************************************************************\n     * Write length prefixed string to buf.\n     */\n    extern (D) void toBuffer(const(char)[] id, Dsymbol s)\n    {\n        const len = id.length;\n        if (buf.offset + len >= 8 * 1024 * 1024) // 8 megs ought be enough for anyone\n            s.error(\"excessive length %llu for symbol, possible recursive expansion?\", cast(ulong)(buf.offset + len));\n        else\n        {\n            buf.print(len);\n            buf.writestring(id);\n        }\n    }\n\n    extern (D) static const(char)[] externallyMangledIdentifier(Declaration d)\n    {\n        if (!d.parent || d.parent.isModule() || d.linkage == LINK.cpp) // if at global scope\n        {\n            final switch (d.linkage)\n            {\n                case LINK.d:\n                    break;\n                case LINK.c:\n                case LINK.windows:\n                case LINK.pascal:\n                case LINK.objc:\n                    return d.ident.toString();\n                case LINK.cpp:\n                {\n                    const p = Target.toCppMangle(d);\n                    return p[0 .. strlen(p)];\n                }\n                case LINK.default_:\n                case LINK.system:\n                    d.error(\"forward declaration\");\n                    return d.ident.toString();\n            }\n        }\n        return null;\n    }\n\n    override void visit(Declaration d)\n    {\n        //printf(\"Declaration.mangle(this = %p, '%s', parent = '%s', linkage = %d)\\n\",\n        //        d, d.toChars(), d.parent ? d.parent.toChars() : \"null\", d.linkage);\n        if (const id = externallyMangledIdentifier(d))\n        {\n            buf.writestring(id);\n            return;\n        }\n        buf.writestring(\"_D\");\n        mangleDecl(d);\n        debug\n        {\n            const slice = buf.peekSlice();\n            assert(slice.length);\n            foreach (const char c; slice)\n            {\n                assert(c.isValidMangling, \"The mangled name '\" ~ slice ~ \"' \" ~\n                    \"contains an invalid character: \" ~ c);\n            }\n        }\n    }\n\n    /******************************************************************************\n     * Normally FuncDeclaration and FuncAliasDeclaration have overloads.\n     * If and only if there is no overloads, mangle() could return\n     * exact mangled name.\n     *\n     *      module test;\n     *      void foo(long) {}           // _D4test3fooFlZv\n     *      void foo(string) {}         // _D4test3fooFAyaZv\n     *\n     *      // from FuncDeclaration.mangle().\n     *      pragma(msg, foo.mangleof);  // prints unexact mangled name \"4test3foo\"\n     *                                  // by calling Dsymbol.mangle()\n     *\n     *      // from FuncAliasDeclaration.mangle()\n     *      pragma(msg, __traits(getOverloads, test, \"foo\")[0].mangleof);  // \"_D4test3fooFlZv\"\n     *      pragma(msg, __traits(getOverloads, test, \"foo\")[1].mangleof);  // \"_D4test3fooFAyaZv\"\n     *\n     * If a function has no overloads, .mangleof property still returns exact mangled name.\n     *\n     *      void bar() {}\n     *      pragma(msg, bar.mangleof);  // still prints \"_D4test3barFZv\"\n     *                                  // by calling FuncDeclaration.mangleExact().\n     */\n    override void visit(FuncDeclaration fd)\n    {\n        if (fd.isUnique())\n            mangleExact(fd);\n        else\n            visit(cast(Dsymbol)fd);\n    }\n\n    // ditto\n    override void visit(FuncAliasDeclaration fd)\n    {\n        FuncDeclaration f = fd.toAliasFunc();\n        FuncAliasDeclaration fa = f.isFuncAliasDeclaration();\n        if (!fd.hasOverloads && !fa)\n        {\n            mangleExact(f);\n            return;\n        }\n        if (fa)\n        {\n            mangleSymbol(fa);\n            return;\n        }\n        visit(cast(Dsymbol)fd);\n    }\n\n    override void visit(OverDeclaration od)\n    {\n        if (od.overnext)\n        {\n            visit(cast(Dsymbol)od);\n            return;\n        }\n        if (FuncDeclaration fd = od.aliassym.isFuncDeclaration())\n        {\n            if (!od.hasOverloads || fd.isUnique())\n            {\n                mangleExact(fd);\n                return;\n            }\n        }\n        if (TemplateDeclaration td = od.aliassym.isTemplateDeclaration())\n        {\n            if (!od.hasOverloads || td.overnext is null)\n            {\n                mangleSymbol(td);\n                return;\n            }\n        }\n        visit(cast(Dsymbol)od);\n    }\n\n    void mangleExact(FuncDeclaration fd)\n    {\n        assert(!fd.isFuncAliasDeclaration());\n        if (fd.mangleOverride)\n        {\n            buf.writestring(fd.mangleOverride);\n            return;\n        }\n        if (fd.isMain())\n        {\n            buf.writestring(\"_Dmain\");\n            return;\n        }\n        if (fd.isWinMain() || fd.isDllMain() || fd.ident == Id.tls_get_addr)\n        {\n            buf.writestring(fd.ident.toChars());\n            return;\n        }\n        visit(cast(Declaration)fd);\n    }\n\n    override void visit(VarDeclaration vd)\n    {\n        if (vd.mangleOverride)\n        {\n            buf.writestring(vd.mangleOverride);\n            return;\n        }\n        visit(cast(Declaration)vd);\n    }\n\n    override void visit(AggregateDeclaration ad)\n    {\n        ClassDeclaration cd = ad.isClassDeclaration();\n        Dsymbol parentsave = ad.parent;\n        if (cd)\n        {\n            /* These are reserved to the compiler, so keep simple\n             * names for them.\n             */\n            if (cd.ident == Id.Exception && cd.parent.ident == Id.object || cd.ident == Id.TypeInfo || cd.ident == Id.TypeInfo_Struct || cd.ident == Id.TypeInfo_Class || cd.ident == Id.TypeInfo_Tuple || cd == ClassDeclaration.object || cd == Type.typeinfoclass || cd == Module.moduleinfo || strncmp(cd.ident.toChars(), \"TypeInfo_\", 9) == 0)\n            {\n                // Don't mangle parent\n                ad.parent = null;\n            }\n        }\n        visit(cast(Dsymbol)ad);\n        ad.parent = parentsave;\n    }\n\n    override void visit(TemplateInstance ti)\n    {\n        version (none)\n        {\n            printf(\"TemplateInstance.mangle() %p %s\", ti, ti.toChars());\n            if (ti.parent)\n                printf(\"  parent = %s %s\", ti.parent.kind(), ti.parent.toChars());\n            printf(\"\\n\");\n        }\n        if (!ti.tempdecl)\n            ti.error(\"is not defined\");\n        else\n            mangleParent(ti);\n\n        if (ti.isTemplateMixin() && ti.ident)\n            mangleIdentifier(ti.ident, ti);\n        else\n            mangleTemplateInstance(ti);\n    }\n\n    void mangleTemplateInstance(TemplateInstance ti)\n    {\n        TemplateDeclaration tempdecl = ti.tempdecl.isTemplateDeclaration();\n        assert(tempdecl);\n\n        // Use \"__U\" for the symbols declared inside template constraint.\n        const char T = ti.members ? 'T' : 'U';\n        buf.printf(\"__%c\", T);\n        mangleIdentifier(tempdecl.ident, tempdecl);\n\n        auto args = ti.tiargs;\n        size_t nparams = tempdecl.parameters.dim - (tempdecl.isVariadic() ? 1 : 0);\n        for (size_t i = 0; i < args.dim; i++)\n        {\n            auto o = (*args)[i];\n            Type ta = isType(o);\n            Expression ea = isExpression(o);\n            Dsymbol sa = isDsymbol(o);\n            Tuple va = isTuple(o);\n            //printf(\"\\to [%d] %p ta %p ea %p sa %p va %p\\n\", i, o, ta, ea, sa, va);\n            if (i < nparams && (*tempdecl.parameters)[i].specialization())\n                buf.writeByte('H'); // https://issues.dlang.org/show_bug.cgi?id=6574\n            if (ta)\n            {\n                buf.writeByte('T');\n                visitWithMask(ta, 0);\n            }\n            else if (ea)\n            {\n                // Don't interpret it yet, it might actually be an alias template parameter.\n                // Only constfold manifest constants, not const/immutable lvalues, see https://issues.dlang.org/show_bug.cgi?id=17339.\n                enum keepLvalue = true;\n                ea = ea.optimize(WANTvalue, keepLvalue);\n                if (ea.op == TOK.variable)\n                {\n                    sa = (cast(VarExp)ea).var;\n                    ea = null;\n                    goto Lsa;\n                }\n                if (ea.op == TOK.this_)\n                {\n                    sa = (cast(ThisExp)ea).var;\n                    ea = null;\n                    goto Lsa;\n                }\n                if (ea.op == TOK.function_)\n                {\n                    if ((cast(FuncExp)ea).td)\n                        sa = (cast(FuncExp)ea).td;\n                    else\n                        sa = (cast(FuncExp)ea).fd;\n                    ea = null;\n                    goto Lsa;\n                }\n                buf.writeByte('V');\n                if (ea.op == TOK.tuple)\n                {\n                    ea.error(\"tuple is not a valid template value argument\");\n                    continue;\n                }\n                // Now that we know it is not an alias, we MUST obtain a value\n                uint olderr = global.errors;\n                ea = ea.ctfeInterpret();\n                if (ea.op == TOK.error || olderr != global.errors)\n                    continue;\n\n                /* Use type mangling that matches what it would be for a function parameter\n                */\n                visitWithMask(ea.type, 0);\n                ea.accept(this);\n            }\n            else if (sa)\n            {\n            Lsa:\n                sa = sa.toAlias();\n                if (Declaration d = sa.isDeclaration())\n                {\n                    if (auto fad = d.isFuncAliasDeclaration())\n                        d = fad.toAliasFunc();\n                    if (d.mangleOverride)\n                    {\n                        buf.writeByte('X');\n                        toBuffer(d.mangleOverride, d);\n                        continue;\n                    }\n                    if (const id = externallyMangledIdentifier(d))\n                    {\n                        buf.writeByte('X');\n                        toBuffer(id, d);\n                        continue;\n                    }\n                    if (!d.type || !d.type.deco)\n                    {\n                        ti.error(\"forward reference of %s `%s`\", d.kind(), d.toChars());\n                        continue;\n                    }\n                }\n                buf.writeByte('S');\n                mangleSymbol(sa);\n            }\n            else if (va)\n            {\n                assert(i + 1 == args.dim); // must be last one\n                args = &va.objects;\n                i = -cast(size_t)1;\n            }\n            else\n                assert(0);\n        }\n        buf.writeByte('Z');\n    }\n\n    override void visit(Dsymbol s)\n    {\n        version (none)\n        {\n            printf(\"Dsymbol.mangle() '%s'\", s.toChars());\n            if (s.parent)\n                printf(\"  parent = %s %s\", s.parent.kind(), s.parent.toChars());\n            printf(\"\\n\");\n        }\n        mangleParent(s);\n        if (s.ident)\n            mangleIdentifier(s.ident, s);\n        else\n            toBuffer(s.toString(), s);\n        //printf(\"Dsymbol.mangle() %s = %s\\n\", s.toChars(), id);\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    override void visit(Expression e)\n    {\n        e.error(\"expression `%s` is not a valid template value argument\", e.toChars());\n    }\n\n    override void visit(IntegerExp e)\n    {\n        const v = e.toInteger();\n        if (cast(sinteger_t)v < 0)\n        {\n            buf.writeByte('N');\n            buf.print(-v);\n        }\n        else\n        {\n            buf.writeByte('i');\n            buf.print(v);\n        }\n    }\n\n    override void visit(RealExp e)\n    {\n        buf.writeByte('e');\n        realToMangleBuffer(e.value);\n    }\n\n    void realToMangleBuffer(real_t value)\n    {\n        /* Rely on %A to get portable mangling.\n         * Must munge result to get only identifier characters.\n         *\n         * Possible values from %A  => mangled result\n         * NAN                      => NAN\n         * -INF                     => NINF\n         * INF                      => INF\n         * -0X1.1BC18BA997B95P+79   => N11BC18BA997B95P79\n         * 0X1.9P+2                 => 19P2\n         */\n        if (CTFloat.isNaN(value))\n            buf.writestring(\"NAN\"); // no -NAN bugs\n        else if (CTFloat.isInfinity(value))\n            buf.writestring(value < CTFloat.zero ? \"NINF\" : \"INF\");\n        else\n        {\n            enum BUFFER_LEN = 36;\n            char[BUFFER_LEN] buffer;\n            const n = CTFloat.sprint(buffer.ptr, 'A', value);\n            assert(n < BUFFER_LEN);\n            for (int i = 0; i < n; i++)\n            {\n                char c = buffer[i];\n                switch (c)\n                {\n                case '-':\n                    buf.writeByte('N');\n                    break;\n                case '+':\n                case 'X':\n                case '.':\n                    break;\n                case '0':\n                    if (i < 2)\n                        break; // skip leading 0X\n                    goto default;\n                default:\n                    buf.writeByte(c);\n                    break;\n                }\n            }\n        }\n    }\n\n    override void visit(ComplexExp e)\n    {\n        buf.writeByte('c');\n        realToMangleBuffer(e.toReal());\n        buf.writeByte('c'); // separate the two\n        realToMangleBuffer(e.toImaginary());\n    }\n\n    override void visit(NullExp e)\n    {\n        buf.writeByte('n');\n    }\n\n    override void visit(StringExp e)\n    {\n        char m;\n        OutBuffer tmp;\n        const(char)[] q;\n        /* Write string in UTF-8 format\n         */\n        switch (e.sz)\n        {\n        case 1:\n            m = 'a';\n            q = e.string[0 .. e.len];\n            break;\n        case 2:\n            m = 'w';\n            for (size_t u = 0; u < e.len;)\n            {\n                dchar c;\n                const p = utf_decodeWchar(e.wstring, e.len, u, c);\n                if (p)\n                    e.error(\"%s\", p);\n                else\n                    tmp.writeUTF8(c);\n            }\n            q = tmp.peekSlice();\n            break;\n        case 4:\n            m = 'd';\n            foreach (u; 0 .. e.len)\n            {\n                const c = (cast(uint*)e.string)[u];\n                if (!utf_isValidDchar(c))\n                    e.error(\"invalid UCS-32 char \\\\U%08x\", c);\n                else\n                    tmp.writeUTF8(c);\n            }\n            q = tmp.peekSlice();\n            break;\n        default:\n            assert(0);\n        }\n        buf.reserve(1 + 11 + 2 * q.length);\n        buf.writeByte(m);\n        buf.print(q.length);\n        buf.writeByte('_');    // nbytes <= 11\n        size_t qi = 0;\n        for (char* p = cast(char*)buf.data + buf.offset, pend = p + 2 * q.length; p < pend; p += 2, ++qi)\n        {\n            char hi = (q[qi] >> 4) & 0xF;\n            p[0] = cast(char)(hi < 10 ? hi + '0' : hi - 10 + 'a');\n            char lo = q[qi] & 0xF;\n            p[1] = cast(char)(lo < 10 ? lo + '0' : lo - 10 + 'a');\n        }\n        buf.offset += 2 * q.length;\n    }\n\n    override void visit(ArrayLiteralExp e)\n    {\n        const dim = e.elements ? e.elements.dim : 0;\n        buf.writeByte('A');\n        buf.print(dim);\n        foreach (i; 0 .. dim)\n        {\n            e.getElement(i).accept(this);\n        }\n    }\n\n    override void visit(AssocArrayLiteralExp e)\n    {\n        const dim = e.keys.dim;\n        buf.writeByte('A');\n        buf.print(dim);\n        foreach (i; 0 .. dim)\n        {\n            (*e.keys)[i].accept(this);\n            (*e.values)[i].accept(this);\n        }\n    }\n\n    override void visit(StructLiteralExp e)\n    {\n        const dim = e.elements ? e.elements.dim : 0;\n        buf.writeByte('S');\n        buf.print(dim);\n        foreach (i; 0 .. dim)\n        {\n            Expression ex = (*e.elements)[i];\n            if (ex)\n                ex.accept(this);\n            else\n                buf.writeByte('v'); // 'v' for void\n        }\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    void paramsToDecoBuffer(Parameters* parameters)\n    {\n        //printf(\"Parameter.paramsToDecoBuffer()\\n\");\n\n        int paramsToDecoBufferDg(size_t n, Parameter p)\n        {\n            p.accept(this);\n            return 0;\n        }\n\n        Parameter._foreach(parameters, &paramsToDecoBufferDg);\n    }\n\n    override void visit(Parameter p)\n    {\n        if (p.storageClass & STC.scope_ && !(p.storageClass & STC.scopeinferred))\n            buf.writeByte('M');\n        // 'return inout ref' is the same as 'inout ref'\n        if ((p.storageClass & (STC.return_ | STC.wild)) == STC.return_)\n            buf.writestring(\"Nk\");\n        switch (p.storageClass & (STC.in_ | STC.out_ | STC.ref_ | STC.lazy_))\n        {\n        case 0:\n        case STC.in_:\n            break;\n        case STC.out_:\n            buf.writeByte('J');\n            break;\n        case STC.ref_:\n            buf.writeByte('K');\n            break;\n        case STC.lazy_:\n            buf.writeByte('L');\n            break;\n        default:\n            debug\n            {\n                printf(\"storageClass = x%llx\\n\", p.storageClass & (STC.in_ | STC.out_ | STC.ref_ | STC.lazy_));\n            }\n            assert(0);\n        }\n        visitWithMask(p.type, 0);\n    }\n}\n\n/// Returns: `true` if the given character is a valid mangled character\npackage bool isValidMangling(dchar c) nothrow\n{\n    return\n        c >= 'A' && c <= 'Z' ||\n        c >= 'a' && c <= 'z' ||\n        c >= '0' && c <= '9' ||\n        c != 0 && strchr(\"$%().:?@[]_\", c);\n}\n\n// valid mangled characters\nunittest\n{\n    assert('a'.isValidMangling);\n    assert('B'.isValidMangling);\n    assert('2'.isValidMangling);\n    assert('@'.isValidMangling);\n    assert('_'.isValidMangling);\n}\n\n// invalid mangled characters\nunittest\n{\n    assert(!'-'.isValidMangling);\n    assert(!0.isValidMangling);\n    assert(!'/'.isValidMangling);\n    assert(!'\\\\'.isValidMangling);\n}\n\n/******************************************************************************\n * Returns exact mangled name of function.\n */\nextern (C++) const(char)* mangleExact(FuncDeclaration fd)\n{\n    if (!fd.mangleString)\n    {\n        OutBuffer buf;\n        scope Mangler v = new Mangler(&buf);\n        v.mangleExact(fd);\n        fd.mangleString = buf.extractString();\n    }\n    return fd.mangleString;\n}\n\nextern (C++) void mangleToBuffer(Type t, OutBuffer* buf)\n{\n    if (t.deco)\n        buf.writestring(t.deco);\n    else\n    {\n        scope Mangler v = new Mangler(buf);\n        v.visitWithMask(t, 0);\n    }\n}\n\nextern (C++) void mangleToBuffer(Expression e, OutBuffer* buf)\n{\n    scope Mangler v = new Mangler(buf);\n    e.accept(v);\n}\n\nextern (C++) void mangleToBuffer(Dsymbol s, OutBuffer* buf)\n{\n    scope Mangler v = new Mangler(buf);\n    s.accept(v);\n}\n\nextern (C++) void mangleToBuffer(TemplateInstance ti, OutBuffer* buf)\n{\n    scope Mangler v = new Mangler(buf);\n    v.mangleTemplateInstance(ti);\n}\n\n/******************************************************************************\n * Mangle function signatures ('this' qualifier, and parameter types)\n * to check conflicts in function overloads.\n * It's different from fd.type.deco. For example, fd.type.deco would be null\n * if fd is an auto function.\n *\n * Params:\n *    buf = `OutBuffer` to write the mangled function signature to\n*     fd  = `FuncDeclaration` to mangle\n */\nvoid mangleToFuncSignature(ref OutBuffer buf, FuncDeclaration fd)\n{\n    assert(fd.type.ty == Tfunction);\n    auto tf = cast(TypeFunction)fd.type;\n\n    scope Mangler v = new Mangler(&buf);\n\n    MODtoDecoBuffer(&buf, tf.mod);\n    v.paramsToDecoBuffer(tf.parameters);\n    buf.writeByte('Z' - tf.varargs);\n}\n"
  },
  {
    "path": "gcc/d/dmd/dmodule.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dmodule.d, _dmodule.d)\n * Documentation:  https://dlang.org/phobos/dmd_dmodule.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dmodule.d\n */\n\nmodule dmd.dmodule;\n\nimport core.stdc.stdio;\nimport core.stdc.stdlib;\nimport core.stdc.string;\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.astcodegen;\nimport dmd.compiler;\nimport dmd.gluelayer;\nimport dmd.dimport;\nimport dmd.dmacro;\nimport dmd.doc;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.parse;\nimport dmd.root.file;\nimport dmd.root.filename;\nimport dmd.root.outbuffer;\nimport dmd.root.port;\nimport dmd.semantic2;\nimport dmd.semantic3;\nimport dmd.utils;\nimport dmd.visitor;\n\nversion(Windows) {\n    extern (C) char* getcwd(char* buffer, size_t maxlen);\n} else {\n    import core.sys.posix.unistd : getcwd;\n}\n\n/* ===========================  ===================== */\n/********************************************\n * Look for the source file if it's different from filename.\n * Look for .di, .d, directory, and along global.path.\n * Does not open the file.\n * Input:\n *      filename        as supplied by the user\n *      global.path\n * Returns:\n *      NULL if it's not different from filename.\n */\nprivate const(char)[] lookForSourceFile(const(char)[] filename)\n{\n    /* Search along global.path for .di file, then .d file.\n     */\n    const sdi = FileName.forceExt(filename, global.hdr_ext.toDString());\n    if (FileName.exists(sdi) == 1)\n        return sdi;\n    const sd = FileName.forceExt(filename, global.mars_ext.toDString());\n    if (FileName.exists(sd) == 1)\n        return sd;\n    if (FileName.exists(filename) == 2)\n    {\n        /* The filename exists and it's a directory.\n         * Therefore, the result should be: filename/package.d\n         * iff filename/package.d is a file\n         */\n        const ni = FileName.combine(filename, \"package.di\");\n        if (FileName.exists(ni) == 1)\n            return ni;\n        FileName.free(ni.ptr);\n        const n = FileName.combine(filename, \"package.d\");\n        if (FileName.exists(n) == 1)\n            return n;\n        FileName.free(n.ptr);\n    }\n    if (FileName.absolute(filename))\n        return null;\n    if (!global.path)\n        return null;\n    for (size_t i = 0; i < global.path.dim; i++)\n    {\n        const p = (*global.path)[i].toDString();\n        const(char)[] n = FileName.combine(p, sdi);\n        if (FileName.exists(n) == 1) {\n            return n;\n        }\n        FileName.free(n.ptr);\n        n = FileName.combine(p, sd);\n        if (FileName.exists(n) == 1) {\n            return n;\n        }\n        FileName.free(n.ptr);\n        const b = FileName.removeExt(filename);\n        n = FileName.combine(p, b);\n        FileName.free(b.ptr);\n        if (FileName.exists(n) == 2)\n        {\n            const n2i = FileName.combine(n, \"package.di\");\n            if (FileName.exists(n2i) == 1)\n                return n2i;\n            FileName.free(n2i.ptr);\n            const n2 = FileName.combine(n, \"package.d\");\n            if (FileName.exists(n2) == 1) {\n                return n2;\n            }\n            FileName.free(n2.ptr);\n        }\n        FileName.free(n.ptr);\n    }\n    return null;\n}\n\n// function used to call semantic3 on a module's dependencies\nvoid semantic3OnDependencies(Module m)\n{\n    if (!m)\n        return;\n\n    if (m.semanticRun > PASS.semantic3)\n        return;\n\n    m.semantic3(null);\n\n    foreach (i; 1 .. m.aimports.dim)\n        semantic3OnDependencies(m.aimports[i]);\n}\n\nenum PKG : int\n{\n    unknown,     // not yet determined whether it's a package.d or not\n    module_,      // already determined that's an actual package.d\n    package_,     // already determined that's an actual package\n}\n\n/***********************************************************\n */\nextern (C++) class Package : ScopeDsymbol\n{\n    PKG isPkgMod;\n    uint tag;        // auto incremented tag, used to mask package tree in scopes\n    Module mod;     // !=null if isPkgMod == PKG.module_\n\n    final extern (D) this(Identifier ident)\n    {\n        super(ident);\n        this.isPkgMod = PKG.unknown;\n        __gshared uint packageTag;\n        this.tag = packageTag++;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"package\";\n    }\n\n    /****************************************************\n     * Input:\n     *      packages[]      the pkg1.pkg2 of pkg1.pkg2.mod\n     * Returns:\n     *      the symbol table that mod should be inserted into\n     * Output:\n     *      *pparent        the rightmost package, i.e. pkg2, or NULL if no packages\n     *      *ppkg           the leftmost package, i.e. pkg1, or NULL if no packages\n     */\n    extern (D) static DsymbolTable resolve(Identifiers* packages, Dsymbol* pparent, Package* ppkg)\n    {\n        DsymbolTable dst = Module.modules;\n        Dsymbol parent = null;\n        //printf(\"Package::resolve()\\n\");\n        if (ppkg)\n            *ppkg = null;\n        if (packages)\n        {\n            for (size_t i = 0; i < packages.dim; i++)\n            {\n                Identifier pid = (*packages)[i];\n                Package pkg;\n                Dsymbol p = dst.lookup(pid);\n                if (!p)\n                {\n                    pkg = new Package(pid);\n                    dst.insert(pkg);\n                    pkg.parent = parent;\n                    pkg.symtab = new DsymbolTable();\n                }\n                else\n                {\n                    pkg = p.isPackage();\n                    assert(pkg);\n                    // It might already be a module, not a package, but that needs\n                    // to be checked at a higher level, where a nice error message\n                    // can be generated.\n                    // dot net needs modules and packages with same name\n                    // But we still need a symbol table for it\n                    if (!pkg.symtab)\n                        pkg.symtab = new DsymbolTable();\n                }\n                parent = pkg;\n                dst = pkg.symtab;\n                if (ppkg && !*ppkg)\n                    *ppkg = pkg;\n                if (pkg.isModule())\n                {\n                    // Return the module so that a nice error message can be generated\n                    if (ppkg)\n                        *ppkg = cast(Package)p;\n                    break;\n                }\n            }\n        }\n        if (pparent)\n            *pparent = parent;\n        return dst;\n    }\n\n    override final inout(Package) isPackage() inout\n    {\n        return this;\n    }\n\n    /**\n     * Checks if pkg is a sub-package of this\n     *\n     * For example, if this qualifies to 'a1.a2' and pkg - to 'a1.a2.a3',\n     * this function returns 'true'. If it is other way around or qualified\n     * package paths conflict function returns 'false'.\n     *\n     * Params:\n     *  pkg = possible subpackage\n     *\n     * Returns:\n     *  see description\n     */\n    final bool isAncestorPackageOf(const Package pkg) const\n    {\n        if (this == pkg)\n            return true;\n        if (!pkg || !pkg.parent)\n            return false;\n        return isAncestorPackageOf(pkg.parent.isPackage());\n    }\n\n    override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)\n    {\n        //printf(\"%s Package.search('%s', flags = x%x)\\n\", toChars(), ident.toChars(), flags);\n        flags &= ~SearchLocalsOnly;  // searching an import is always transitive\n        if (!isModule() && mod)\n        {\n            // Prefer full package name.\n            Dsymbol s = symtab ? symtab.lookup(ident) : null;\n            if (s)\n                return s;\n            //printf(\"[%s] through pkdmod: %s\\n\", loc.toChars(), toChars());\n            return mod.search(loc, ident, flags);\n        }\n        return ScopeDsymbol.search(loc, ident, flags);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    final Module isPackageMod()\n    {\n        if (isPkgMod == PKG.module_)\n        {\n            return mod;\n        }\n        return null;\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class Module : Package\n{\n    extern (C++) __gshared Module rootModule;\n    extern (C++) __gshared DsymbolTable modules; // symbol table of all modules\n    extern (C++) __gshared Modules amodules;     // array of all modules\n    extern (C++) __gshared Dsymbols deferred;    // deferred Dsymbol's needing semantic() run on them\n    extern (C++) __gshared Dsymbols deferred2;   // deferred Dsymbol's needing semantic2() run on them\n    extern (C++) __gshared Dsymbols deferred3;   // deferred Dsymbol's needing semantic3() run on them\n    extern (C++) __gshared uint dprogress;       // progress resolving the deferred list\n\n    static void _init()\n    {\n        modules = new DsymbolTable();\n    }\n\n    extern (C++) __gshared AggregateDeclaration moduleinfo;\n\n    const(char)* arg;           // original argument name\n    ModuleDeclaration* md;      // if !=null, the contents of the ModuleDeclaration declaration\n    File* srcfile;              // input source file\n    File* objfile;              // output .obj file\n    File* hdrfile;              // 'header' file\n    File* docfile;              // output documentation file\n    uint errors;                // if any errors in file\n    uint numlines;              // number of lines in source file\n    int isDocFile;              // if it is a documentation input file, not D source\n    bool isPackageFile;         // if it is a package.d\n    Strings contentImportedFiles; // array of files whose content was imported\n    int needmoduleinfo;\n    int selfimports;            // 0: don't know, 1: does not, 2: does\n\n    /*************************************\n     * Return true if module imports itself.\n     */\n    bool selfImports()\n    {\n        //printf(\"Module::selfImports() %s\\n\", toChars());\n        if (selfimports == 0)\n        {\n            for (size_t i = 0; i < amodules.dim; i++)\n                amodules[i].insearch = 0;\n            selfimports = imports(this) + 1;\n            for (size_t i = 0; i < amodules.dim; i++)\n                amodules[i].insearch = 0;\n        }\n        return selfimports == 2;\n    }\n\n    int rootimports;            // 0: don't know, 1: does not, 2: does\n\n    /*************************************\n     * Return true if module imports root module.\n     */\n    bool rootImports()\n    {\n        //printf(\"Module::rootImports() %s\\n\", toChars());\n        if (rootimports == 0)\n        {\n            for (size_t i = 0; i < amodules.dim; i++)\n                amodules[i].insearch = 0;\n            rootimports = 1;\n            for (size_t i = 0; i < amodules.dim; ++i)\n            {\n                Module m = amodules[i];\n                if (m.isRoot() && imports(m))\n                {\n                    rootimports = 2;\n                    break;\n                }\n            }\n            for (size_t i = 0; i < amodules.dim; i++)\n                amodules[i].insearch = 0;\n        }\n        return rootimports == 2;\n    }\n\n    int insearch;\n    Identifier searchCacheIdent;\n    Dsymbol searchCacheSymbol;  // cached value of search\n    int searchCacheFlags;       // cached flags\n\n    /**\n     * A root module is one that will be compiled all the way to\n     * object code.  This field holds the root module that caused\n     * this module to be loaded.  If this module is a root module,\n     * then it will be set to `this`.  This is used to determine\n     * ownership of template instantiation.\n     */\n    Module importedFrom;\n\n    Dsymbols* decldefs;         // top level declarations for this Module\n\n    Modules aimports;           // all imported modules\n\n    uint debuglevel;            // debug level\n    Identifiers* debugids;      // debug identifiers\n    Identifiers* debugidsNot;   // forward referenced debug identifiers\n\n    uint versionlevel;          // version level\n    Identifiers* versionids;    // version identifiers\n    Identifiers* versionidsNot; // forward referenced version identifiers\n\n    Macro* macrotable;          // document comment macros\n    Escape* escapetable;        // document comment escapes\n\n    size_t nameoffset;          // offset of module name from start of ModuleInfo\n    size_t namelen;             // length of module name in characters\n\n    extern (D) this(const(char)* filename, Identifier ident, int doDocComment, int doHdrGen)\n    {\n        super(ident);\n        const(char)* srcfilename;\n        //printf(\"Module::Module(filename = '%s', ident = '%s')\\n\", filename, ident.toChars());\n        this.arg = filename;\n        srcfilename = FileName.defaultExt(filename, global.mars_ext);\n        if (global.run_noext && global.params.run && !FileName.ext(filename) && FileName.exists(srcfilename) == 0 && FileName.exists(filename) == 1)\n        {\n            FileName.free(srcfilename);\n            srcfilename = FileName.removeExt(filename); // just does a mem.strdup(filename)\n        }\n        else if (!FileName.equalsExt(srcfilename, global.mars_ext) && !FileName.equalsExt(srcfilename, global.hdr_ext) && !FileName.equalsExt(srcfilename, \"dd\"))\n        {\n            error(\"source file name '%s' must have .%s extension\", srcfilename, global.mars_ext);\n            fatal();\n        }\n        srcfile = new File(srcfilename);\n        objfile = setOutfile(global.params.objname, global.params.objdir, filename, global.obj_ext);\n        if (doDocComment)\n            setDocfile();\n        if (doHdrGen)\n            hdrfile = setOutfile(global.params.hdrname, global.params.hdrdir, arg, global.hdr_ext);\n        //objfile = new File(objfilename);\n    }\n\n    static Module create(const(char)* filename, Identifier ident, int doDocComment, int doHdrGen)\n    {\n        return new Module(filename, ident, doDocComment, doHdrGen);\n    }\n\n    static Module load(Loc loc, Identifiers* packages, Identifier ident)\n    {\n        //printf(\"Module::load(ident = '%s')\\n\", ident.toChars());\n        // Build module filename by turning:\n        //  foo.bar.baz\n        // into:\n        //  foo\\bar\\baz\n        const(char)[] filename = ident.toString();\n        if (packages && packages.dim)\n        {\n            OutBuffer buf;\n            OutBuffer dotmods;\n            auto ms = global.params.modFileAliasStrings;\n            const msdim = ms ? ms.dim : 0;\n\n            void checkModFileAlias(const(char)[] p)\n            {\n                /* Check and replace the contents of buf[] with\n                 * an alias string from global.params.modFileAliasStrings[]\n                 */\n                dotmods.writestring(p);\n            Lmain:\n                for (size_t j = msdim; j--;)\n                {\n                    const m = (*ms)[j];\n                    const q = strchr(m, '=');\n                    assert(q);\n                    if (dotmods.offset == q - m && memcmp(dotmods.peekString(), m, q - m) == 0)\n                    {\n                        buf.reset();\n                        auto qlen = strlen(q + 1);\n                        if (qlen && (q[qlen] == '/' || q[qlen] == '\\\\'))\n                            --qlen;             // remove trailing separator\n                        buf.writestring(q[1 .. qlen + 1]);\n                        break Lmain;            // last matching entry in ms[] wins\n                    }\n                }\n                dotmods.writeByte('.');\n            }\n\n            foreach (pid; *packages)\n            {\n                const p = pid.toString();\n                buf.writestring(p);\n                if (msdim)\n                    checkModFileAlias(p);\n                version (Windows)\n                {\n                    buf.writeByte('\\\\');\n                }\n                else\n                {\n                    buf.writeByte('/');\n                }\n            }\n            buf.writestring(filename);\n            if (msdim)\n                checkModFileAlias(filename);\n            buf.writeByte(0);\n            filename = buf.extractData().toDString();\n        }\n        auto m = new Module(filename.ptr, ident, 0, 0);\n        m.loc = loc;\n        /* Look for the source file\n         */\n        if (const result = lookForSourceFile(filename))\n            m.srcfile = new File(result);\n\n        if (!m.read(loc))\n            return null;\n        if (global.params.verbose)\n        {\n            OutBuffer buf;\n            if (packages)\n            {\n                foreach (pid; *packages)\n                {\n                    buf.writestring(pid.toString());\n                    buf.writeByte('.');\n                }\n            }\n            buf.printf(\"%s\\t(%s)\", ident.toChars(), m.srcfile.toChars());\n            message(\"import    %s\", buf.peekString());\n        }\n        m = m.parse();\n\n        // Call onImport here because if the module is going to be compiled then we\n        // need to determine it early because it affects semantic analysis. This is\n        // being done after parsing the module so the full module name can be taken\n        // from whatever was declared in the file.\n        if (!m.isRoot() && Compiler.onImport(m))\n        {\n            m.importedFrom = m;\n            assert(m.isRoot());\n        }\n\n        Compiler.loadModule(m);\n        return m;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"module\";\n    }\n\n    /*********************************************\n     * Combines things into output file name for .html and .di files.\n     * Input:\n     *      name    Command line name given for the file, NULL if none\n     *      dir     Command line directory given for the file, NULL if none\n     *      arg     Name of the source file\n     *      ext     File name extension to use if 'name' is NULL\n     *      global.params.preservePaths     get output path from arg\n     *      srcfile Input file - output file name must not match input file\n     */\n    File* setOutfile(const(char)* name, const(char)* dir, const(char)* arg, const(char)* ext)\n    {\n        return setOutfile(name.toDString(), dir.toDString(), arg.toDString(), ext.toDString());\n    }\n\n    /// Ditto\n    extern(D) File* setOutfile(const(char)[] name, const(char)[] dir, const(char)[] arg, const(char)[] ext)\n    {\n        const(char)[] docfilename;\n        if (name)\n        {\n            docfilename = name;\n        }\n        else\n        {\n            const(char)[] argdoc;\n            OutBuffer buf;\n            if (arg == \"__stdin.d\")\n            {\n                version (Posix)\n                    import core.sys.posix.unistd : getpid;\n                else version (Windows)\n                    import core.sys.windows.windows : getpid = GetCurrentProcessId;\n                buf.printf(\"__stdin_%d.d\", getpid());\n                arg = buf.peekSlice();\n            }\n            if (global.params.preservePaths)\n                argdoc = arg;\n            else\n                argdoc = FileName.name(arg);\n            // If argdoc doesn't have an absolute path, make it relative to dir\n            if (!FileName.absolute(argdoc))\n            {\n                //FileName::ensurePathExists(dir);\n                argdoc = FileName.combine(dir, argdoc);\n            }\n            docfilename = FileName.forceExt(argdoc, ext);\n        }\n        if (FileName.equals(docfilename, srcfile.name.toString()))\n        {\n            error(\"source file and output file have same name '%s'\", srcfile.name.toChars());\n            fatal();\n        }\n        return new File(docfilename);\n    }\n\n    void setDocfile()\n    {\n        docfile = setOutfile(global.params.docname, global.params.docdir, arg, global.doc_ext);\n    }\n\n    // read file, returns 'true' if succeed, 'false' otherwise.\n    bool read(Loc loc)\n    {\n        //printf(\"Module::read('%s') file '%s'\\n\", toChars(), srcfile.toChars());\n        if (!srcfile.read())\n            return true;\n\n        if (FileName.equals(srcfile.toString(), \"object.d\"))\n        {\n            .error(loc, \"cannot find source code for runtime library file 'object.d'\");\n            errorSupplemental(loc, \"dmd might not be correctly installed. Run 'dmd -man' for installation instructions.\");\n            const dmdConfFile = FileName.canonicalName(global.inifilename);\n            errorSupplemental(loc, \"config file: %s\", dmdConfFile ? dmdConfFile : \"not found\".ptr);\n        }\n        else\n        {\n            // if module is not named 'package' but we're trying to read 'package.d', we're looking for a package module\n            bool isPackageMod = (strcmp(toChars(), \"package\") != 0) && (strcmp(srcfile.name.name(), \"package.d\") == 0 || (strcmp(srcfile.name.name(), \"package.di\") == 0));\n            if (isPackageMod)\n                .error(loc, \"importing package '%s' requires a 'package.d' file which cannot be found in '%s'\", toChars(), srcfile.toChars());\n            else\n                error(loc, \"is in file '%s' which cannot be read\", srcfile.toChars());\n        }\n        if (!global.gag)\n        {\n            /* Print path\n             */\n            if (global.path)\n            {\n                foreach (i, p; *global.path)\n                    fprintf(stderr, \"import path[%llu] = %s\\n\", cast(ulong)i, p);\n            }\n            else\n                fprintf(stderr, \"Specify path to file '%s' with -I switch\\n\", srcfile.toChars());\n            fatal();\n        }\n        return false;\n    }\n\n    // syntactic parse\n    Module parse()\n    {\n        //printf(\"Module::parse(srcfile='%s') this=%p\\n\", srcfile.name.toChars(), this);\n        const(char)* srcname = srcfile.name.toChars();\n        //printf(\"Module::parse(srcname = '%s')\\n\", srcname);\n        isPackageFile = (strcmp(srcfile.name.name(), \"package.d\") == 0 ||\n                         strcmp(srcfile.name.name(), \"package.di\") == 0);\n        char* buf = cast(char*)srcfile.buffer;\n        size_t buflen = srcfile.len;\n        if (buflen >= 2)\n        {\n            /* Convert all non-UTF-8 formats to UTF-8.\n             * BOM : http://www.unicode.org/faq/utf_bom.html\n             * 00 00 FE FF  UTF-32BE, big-endian\n             * FF FE 00 00  UTF-32LE, little-endian\n             * FE FF        UTF-16BE, big-endian\n             * FF FE        UTF-16LE, little-endian\n             * EF BB BF     UTF-8\n             */\n            uint le;\n            uint bom = 1; // assume there's a BOM\n            if (buf[0] == 0xFF && buf[1] == 0xFE)\n            {\n                if (buflen >= 4 && buf[2] == 0 && buf[3] == 0)\n                {\n                    // UTF-32LE\n                    le = 1;\n                Lutf32:\n                    OutBuffer dbuf;\n                    uint* pu = cast(uint*)buf;\n                    uint* pumax = &pu[buflen / 4];\n                    if (buflen & 3)\n                    {\n                        error(\"odd length of UTF-32 char source %u\", buflen);\n                        fatal();\n                    }\n                    dbuf.reserve(buflen / 4);\n                    for (pu += bom; pu < pumax; pu++)\n                    {\n                        uint u;\n                        u = le ? Port.readlongLE(pu) : Port.readlongBE(pu);\n                        if (u & ~0x7F)\n                        {\n                            if (u > 0x10FFFF)\n                            {\n                                error(\"UTF-32 value %08x greater than 0x10FFFF\", u);\n                                fatal();\n                            }\n                            dbuf.writeUTF8(u);\n                        }\n                        else\n                            dbuf.writeByte(u);\n                    }\n                    dbuf.writeByte(0); // add 0 as sentinel for scanner\n                    buflen = dbuf.offset - 1; // don't include sentinel in count\n                    buf = dbuf.extractData();\n                }\n                else\n                {\n                    // UTF-16LE (X86)\n                    // Convert it to UTF-8\n                    le = 1;\n                Lutf16:\n                    OutBuffer dbuf;\n                    ushort* pu = cast(ushort*)buf;\n                    ushort* pumax = &pu[buflen / 2];\n                    if (buflen & 1)\n                    {\n                        error(\"odd length of UTF-16 char source %u\", buflen);\n                        fatal();\n                    }\n                    dbuf.reserve(buflen / 2);\n                    for (pu += bom; pu < pumax; pu++)\n                    {\n                        uint u;\n                        u = le ? Port.readwordLE(pu) : Port.readwordBE(pu);\n                        if (u & ~0x7F)\n                        {\n                            if (u >= 0xD800 && u <= 0xDBFF)\n                            {\n                                uint u2;\n                                if (++pu > pumax)\n                                {\n                                    error(\"surrogate UTF-16 high value %04x at end of file\", u);\n                                    fatal();\n                                }\n                                u2 = le ? Port.readwordLE(pu) : Port.readwordBE(pu);\n                                if (u2 < 0xDC00 || u2 > 0xDFFF)\n                                {\n                                    error(\"surrogate UTF-16 low value %04x out of range\", u2);\n                                    fatal();\n                                }\n                                u = (u - 0xD7C0) << 10;\n                                u |= (u2 - 0xDC00);\n                            }\n                            else if (u >= 0xDC00 && u <= 0xDFFF)\n                            {\n                                error(\"unpaired surrogate UTF-16 value %04x\", u);\n                                fatal();\n                            }\n                            else if (u == 0xFFFE || u == 0xFFFF)\n                            {\n                                error(\"illegal UTF-16 value %04x\", u);\n                                fatal();\n                            }\n                            dbuf.writeUTF8(u);\n                        }\n                        else\n                            dbuf.writeByte(u);\n                    }\n                    dbuf.writeByte(0); // add 0 as sentinel for scanner\n                    buflen = dbuf.offset - 1; // don't include sentinel in count\n                    buf = dbuf.extractData();\n                }\n            }\n            else if (buf[0] == 0xFE && buf[1] == 0xFF)\n            {\n                // UTF-16BE\n                le = 0;\n                goto Lutf16;\n            }\n            else if (buflen >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0xFE && buf[3] == 0xFF)\n            {\n                // UTF-32BE\n                le = 0;\n                goto Lutf32;\n            }\n            else if (buflen >= 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF)\n            {\n                // UTF-8\n                buf += 3;\n                buflen -= 3;\n            }\n            else\n            {\n                /* There is no BOM. Make use of Arcane Jill's insight that\n                 * the first char of D source must be ASCII to\n                 * figure out the encoding.\n                 */\n                bom = 0;\n                if (buflen >= 4)\n                {\n                    if (buf[1] == 0 && buf[2] == 0 && buf[3] == 0)\n                    {\n                        // UTF-32LE\n                        le = 1;\n                        goto Lutf32;\n                    }\n                    else if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0)\n                    {\n                        // UTF-32BE\n                        le = 0;\n                        goto Lutf32;\n                    }\n                }\n                if (buflen >= 2)\n                {\n                    if (buf[1] == 0)\n                    {\n                        // UTF-16LE\n                        le = 1;\n                        goto Lutf16;\n                    }\n                    else if (buf[0] == 0)\n                    {\n                        // UTF-16BE\n                        le = 0;\n                        goto Lutf16;\n                    }\n                }\n                // It's UTF-8\n                if (buf[0] >= 0x80)\n                {\n                    error(\"source file must start with BOM or ASCII character, not \\\\x%02X\", buf[0]);\n                    fatal();\n                }\n            }\n        }\n        /* If it starts with the string \"Ddoc\", then it's a documentation\n         * source file.\n         */\n        if (buflen >= 4 && memcmp(buf, cast(char*)\"Ddoc\", 4) == 0)\n        {\n            comment = buf + 4;\n            isDocFile = 1;\n            if (!docfile)\n                setDocfile();\n            return this;\n        }\n        /* If it has the extension \".dd\", it is also a documentation\n         * source file. Documentation source files may begin with \"Ddoc\"\n         * but do not have to if they have the .dd extension.\n         * https://issues.dlang.org/show_bug.cgi?id=15465\n         */\n        if (FileName.equalsExt(arg, \"dd\"))\n        {\n            comment = buf; // the optional Ddoc, if present, is handled above.\n            isDocFile = 1;\n            if (!docfile)\n                setDocfile();\n            return this;\n        }\n        {\n            scope p = new Parser!ASTCodegen(this, buf[0 .. buflen], docfile !is null);\n            p.nextToken();\n            members = p.parseModule();\n            md = p.md;\n            numlines = p.scanloc.linnum;\n            if (p.errors)\n                ++global.errors;\n        }\n        if (srcfile._ref == 0)\n            .free(srcfile.buffer);\n        srcfile.buffer = null;\n        srcfile.len = 0;\n        /* The symbol table into which the module is to be inserted.\n         */\n        DsymbolTable dst;\n        if (md)\n        {\n            /* A ModuleDeclaration, md, was provided.\n             * The ModuleDeclaration sets the packages this module appears in, and\n             * the name of this module.\n             */\n            this.ident = md.id;\n            Package ppack = null;\n            dst = Package.resolve(md.packages, &this.parent, &ppack);\n            assert(dst);\n            Module m = ppack ? ppack.isModule() : null;\n            if (m && (strcmp(m.srcfile.name.name(), \"package.d\") != 0 &&\n                      strcmp(m.srcfile.name.name(), \"package.di\") != 0))\n            {\n                .error(md.loc, \"package name '%s' conflicts with usage as a module name in file %s\", ppack.toPrettyChars(), m.srcfile.toChars());\n            }\n        }\n        else\n        {\n            /* The name of the module is set to the source file name.\n             * There are no packages.\n             */\n            dst = modules; // and so this module goes into global module symbol table\n            /* Check to see if module name is a valid identifier\n             */\n            if (!Identifier.isValidIdentifier(this.ident.toChars()))\n                error(\"has non-identifier characters in filename, use module declaration instead\");\n        }\n        // Insert module into the symbol table\n        Dsymbol s = this;\n        if (isPackageFile)\n        {\n            /* If the source tree is as follows:\n             *     pkg/\n             *     +- package.d\n             *     +- common.d\n             * the 'pkg' will be incorporated to the internal package tree in two ways:\n             *     import pkg;\n             * and:\n             *     import pkg.common;\n             *\n             * If both are used in one compilation, 'pkg' as a module (== pkg/package.d)\n             * and a package name 'pkg' will conflict each other.\n             *\n             * To avoid the conflict:\n             * 1. If preceding package name insertion had occurred by Package::resolve,\n             *    later package.d loading will change Package::isPkgMod to PKG.module_ and set Package::mod.\n             * 2. Otherwise, 'package.d' wrapped by 'Package' is inserted to the internal tree in here.\n             */\n            auto p = new Package(ident);\n            p.parent = this.parent;\n            p.isPkgMod = PKG.module_;\n            p.mod = this;\n            p.tag = this.tag; // reuse the same package tag\n            p.symtab = new DsymbolTable();\n            s = p;\n        }\n        if (!dst.insert(s))\n        {\n            /* It conflicts with a name that is already in the symbol table.\n             * Figure out what went wrong, and issue error message.\n             */\n            Dsymbol prev = dst.lookup(ident);\n            assert(prev);\n            if (Module mprev = prev.isModule())\n            {\n                if (!FileName.equals(srcname, mprev.srcfile.toChars()))\n                    error(loc, \"from file %s conflicts with another module %s from file %s\", srcname, mprev.toChars(), mprev.srcfile.toChars());\n                else if (isRoot() && mprev.isRoot())\n                    error(loc, \"from file %s is specified twice on the command line\", srcname);\n                else\n                    error(loc, \"from file %s must be imported with 'import %s;'\", srcname, toPrettyChars());\n                // https://issues.dlang.org/show_bug.cgi?id=14446\n                // Return previously parsed module to avoid AST duplication ICE.\n                return mprev;\n            }\n            else if (Package pkg = prev.isPackage())\n            {\n                if (pkg.isPkgMod == PKG.unknown && isPackageFile)\n                {\n                    /* If the previous inserted Package is not yet determined as package.d,\n                     * link it to the actual module.\n                     */\n                    pkg.isPkgMod = PKG.module_;\n                    pkg.mod = this;\n                    pkg.tag = this.tag; // reuse the same package tag\n                    amodules.push(this); // Add to global array of all modules\n                }\n                else\n                    error(md ? md.loc : loc, \"from file %s conflicts with package name %s\", srcname, pkg.toChars());\n            }\n            else\n                assert(global.errors);\n        }\n        else\n        {\n            // Add to global array of all modules\n            amodules.push(this);\n        }\n        return this;\n    }\n\n    override void importAll(Scope* prevsc)\n    {\n        //printf(\"+Module::importAll(this = %p, '%s'): parent = %p\\n\", this, toChars(), parent);\n        if (_scope)\n            return; // already done\n        if (isDocFile)\n        {\n            error(\"is a Ddoc file, cannot import it\");\n            return;\n        }\n        if (md && md.msg)\n        {\n            if (StringExp se = md.msg.toStringExp())\n                md.msg = se;\n            else\n                md.msg.error(\"string expected, not '%s'\", md.msg.toChars());\n        }\n        /* Note that modules get their own scope, from scratch.\n         * This is so regardless of where in the syntax a module\n         * gets imported, it is unaffected by context.\n         * Ignore prevsc.\n         */\n        Scope* sc = Scope.createGlobal(this); // create root scope\n        // Add import of \"object\", even for the \"object\" module.\n        // If it isn't there, some compiler rewrites, like\n        //    classinst == classinst -> .object.opEquals(classinst, classinst)\n        // would fail inside object.d.\n        if (members.dim == 0 || (*members)[0].ident != Id.object)\n        {\n            auto im = new Import(Loc.initial, null, Id.object, null, 0);\n            members.shift(im);\n        }\n        if (!symtab)\n        {\n            // Add all symbols into module's symbol table\n            symtab = new DsymbolTable();\n            for (size_t i = 0; i < members.dim; i++)\n            {\n                Dsymbol s = (*members)[i];\n                s.addMember(sc, sc.scopesym);\n            }\n        }\n        // anything else should be run after addMember, so version/debug symbols are defined\n        /* Set scope for the symbols so that if we forward reference\n         * a symbol, it can possibly be resolved on the spot.\n         * If this works out well, it can be extended to all modules\n         * before any semantic() on any of them.\n         */\n        setScope(sc); // remember module scope for semantic\n        for (size_t i = 0; i < members.dim; i++)\n        {\n            Dsymbol s = (*members)[i];\n            s.setScope(sc);\n        }\n        for (size_t i = 0; i < members.dim; i++)\n        {\n            Dsymbol s = (*members)[i];\n            s.importAll(sc);\n        }\n        sc = sc.pop();\n        sc.pop(); // 2 pops because Scope::createGlobal() created 2\n    }\n\n    /**********************************\n     * Determine if we need to generate an instance of ModuleInfo\n     * for this Module.\n     */\n    int needModuleInfo()\n    {\n        //printf(\"needModuleInfo() %s, %d, %d\\n\", toChars(), needmoduleinfo, global.params.cov);\n        return needmoduleinfo || global.params.cov;\n    }\n\n    override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)\n    {\n        /* Since modules can be circularly referenced,\n         * need to stop infinite recursive searches.\n         * This is done with the cache.\n         */\n        //printf(\"%s Module.search('%s', flags = x%x) insearch = %d\\n\", toChars(), ident.toChars(), flags, insearch);\n        if (insearch)\n            return null;\n\n        /* Qualified module searches always search their imports,\n         * even if SearchLocalsOnly\n         */\n        if (!(flags & SearchUnqualifiedModule))\n            flags &= ~(SearchUnqualifiedModule | SearchLocalsOnly);\n\n        if (searchCacheIdent == ident && searchCacheFlags == flags)\n        {\n            //printf(\"%s Module::search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\\n\",\n            //        toChars(), ident.toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol.toChars() : \"null\");\n            return searchCacheSymbol;\n        }\n\n        uint errors = global.errors;\n\n        insearch = 1;\n        Dsymbol s = ScopeDsymbol.search(loc, ident, flags);\n        insearch = 0;\n\n        if (errors == global.errors)\n        {\n            // https://issues.dlang.org/show_bug.cgi?id=10752\n            // Can cache the result only when it does not cause\n            // access error so the side-effect should be reproduced in later search.\n            searchCacheIdent = ident;\n            searchCacheSymbol = s;\n            searchCacheFlags = flags;\n        }\n        return s;\n    }\n\n    override bool isPackageAccessible(Package p, Prot protection, int flags = 0)\n    {\n        if (insearch) // don't follow import cycles\n            return false;\n        insearch = true;\n        scope (exit)\n            insearch = false;\n        if (flags & IgnorePrivateImports)\n            protection = Prot(Prot.Kind.public_); // only consider public imports\n        return super.isPackageAccessible(p, protection);\n    }\n\n    override Dsymbol symtabInsert(Dsymbol s)\n    {\n        searchCacheIdent = null; // symbol is inserted, so invalidate cache\n        return Package.symtabInsert(s);\n    }\n\n    void deleteObjFile()\n    {\n        if (global.params.obj)\n            objfile.remove();\n        if (docfile)\n            docfile.remove();\n    }\n\n    /*******************************************\n     * Can't run semantic on s now, try again later.\n     */\n    static void addDeferredSemantic(Dsymbol s)\n    {\n        //printf(\"Module::addDeferredSemantic('%s')\\n\", s.toChars());\n        deferred.push(s);\n    }\n\n    static void addDeferredSemantic2(Dsymbol s)\n    {\n        //printf(\"Module::addDeferredSemantic2('%s')\\n\", s.toChars());\n        deferred2.push(s);\n    }\n\n    static void addDeferredSemantic3(Dsymbol s)\n    {\n        //printf(\"Module::addDeferredSemantic3('%s')\\n\", s.toChars());\n        deferred3.push(s);\n    }\n\n    /******************************************\n     * Run semantic() on deferred symbols.\n     */\n    static void runDeferredSemantic()\n    {\n        if (dprogress == 0)\n            return;\n\n        __gshared int nested;\n        if (nested)\n            return;\n        //if (deferred.dim) printf(\"+Module::runDeferredSemantic(), len = %d\\n\", deferred.dim);\n        nested++;\n\n        size_t len;\n        do\n        {\n            dprogress = 0;\n            len = deferred.dim;\n            if (!len)\n                break;\n\n            Dsymbol* todo;\n            Dsymbol* todoalloc = null;\n            Dsymbol tmp;\n            if (len == 1)\n            {\n                todo = &tmp;\n            }\n            else\n            {\n                todo = cast(Dsymbol*)malloc(len * Dsymbol.sizeof);\n                assert(todo);\n                todoalloc = todo;\n            }\n            memcpy(todo, deferred.tdata(), len * Dsymbol.sizeof);\n            deferred.setDim(0);\n\n            for (size_t i = 0; i < len; i++)\n            {\n                Dsymbol s = todo[i];\n                s.dsymbolSemantic(null);\n                //printf(\"deferred: %s, parent = %s\\n\", s.toChars(), s.parent.toChars());\n            }\n            //printf(\"\\tdeferred.dim = %d, len = %d, dprogress = %d\\n\", deferred.dim, len, dprogress);\n            if (todoalloc)\n                free(todoalloc);\n        }\n        while (deferred.dim < len || dprogress); // while making progress\n        nested--;\n        //printf(\"-Module::runDeferredSemantic(), len = %d\\n\", deferred.dim);\n    }\n\n    static void runDeferredSemantic2()\n    {\n        Module.runDeferredSemantic();\n\n        Dsymbols* a = &Module.deferred2;\n        for (size_t i = 0; i < a.dim; i++)\n        {\n            Dsymbol s = (*a)[i];\n            //printf(\"[%d] %s semantic2a\\n\", i, s.toPrettyChars());\n            s.semantic2(null);\n\n            if (global.errors)\n                break;\n        }\n        a.setDim(0);\n    }\n\n    static void runDeferredSemantic3()\n    {\n        Module.runDeferredSemantic2();\n\n        Dsymbols* a = &Module.deferred3;\n        for (size_t i = 0; i < a.dim; i++)\n        {\n            Dsymbol s = (*a)[i];\n            //printf(\"[%d] %s semantic3a\\n\", i, s.toPrettyChars());\n            s.semantic3(null);\n\n            if (global.errors)\n                break;\n        }\n        a.setDim(0);\n    }\n\n    static void clearCache()\n    {\n        for (size_t i = 0; i < amodules.dim; i++)\n        {\n            Module m = amodules[i];\n            m.searchCacheIdent = null;\n        }\n    }\n\n    /************************************\n     * Recursively look at every module this module imports,\n     * return true if it imports m.\n     * Can be used to detect circular imports.\n     */\n    int imports(Module m)\n    {\n        //printf(\"%s Module::imports(%s)\\n\", toChars(), m.toChars());\n        version (none)\n        {\n            for (size_t i = 0; i < aimports.dim; i++)\n            {\n                Module mi = cast(Module)aimports.data[i];\n                printf(\"\\t[%d] %s\\n\", i, mi.toChars());\n            }\n        }\n        for (size_t i = 0; i < aimports.dim; i++)\n        {\n            Module mi = aimports[i];\n            if (mi == m)\n                return true;\n            if (!mi.insearch)\n            {\n                mi.insearch = 1;\n                int r = mi.imports(m);\n                if (r)\n                    return r;\n            }\n        }\n        return false;\n    }\n\n    bool isRoot()\n    {\n        return this.importedFrom == this;\n    }\n\n    // true if the module source file is directly\n    // listed in command line.\n    bool isCoreModule(Identifier ident)\n    {\n        return this.ident == ident && parent && parent.ident == Id.core && !parent.parent;\n    }\n\n    // Back end\n    int doppelganger; // sub-module\n    Symbol* cov; // private uint[] __coverage;\n    uint* covb; // bit array of valid code line numbers\n    Symbol* sictor; // module order independent constructor\n    Symbol* sctor; // module constructor\n    Symbol* sdtor; // module destructor\n    Symbol* ssharedctor; // module shared constructor\n    Symbol* sshareddtor; // module shared destructor\n    Symbol* stest; // module unit test\n    Symbol* sfilename; // symbol for filename\n\n    override inout(Module) isModule() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    /***********************************************\n     * Writes this module's fully-qualified name to buf\n     * Params:\n     *    buf = The buffer to write to\n     */\n    void fullyQualifiedName(ref OutBuffer buf)\n    {\n        buf.writestring(ident.toString());\n\n        for (auto package_ = parent; package_ !is null; package_ = package_.parent)\n        {\n            buf.prependstring(\".\");\n            buf.prependstring(package_.ident.toChars());\n        }\n    }\n}\n\n/***********************************************************\n */\nstruct ModuleDeclaration\n{\n    Loc loc;\n    Identifier id;\n    Identifiers* packages;  // array of Identifier's representing packages\n    bool isdeprecated;      // if it is a deprecated module\n    Expression msg;\n\n    extern (D) this(const ref Loc loc, Identifiers* packages, Identifier id, Expression msg, bool isdeprecated)\n    {\n        this.loc = loc;\n        this.packages = packages;\n        this.id = id;\n        this.msg = msg;\n        this.isdeprecated = isdeprecated;\n    }\n\n    extern (C++) const(char)* toChars() const\n    {\n        OutBuffer buf;\n        if (packages && packages.dim)\n        {\n            foreach (pid; *packages)\n            {\n                buf.writestring(pid.toString());\n                buf.writeByte('.');\n            }\n        }\n        buf.writestring(id.toString());\n        return buf.extractString();\n    }\n\n    /// Provide a human readable representation\n    extern (D) const(char)[] toString() const\n    {\n        return this.toChars().toDString;\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/doc.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/doc.d, _doc.d)\n * Documentation:  https://dlang.org/phobos/dmd_doc.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/doc.d\n */\n\nmodule dmd.doc;\n\nimport core.stdc.ctype;\nimport core.stdc.stdlib;\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport core.stdc.time;\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.attrib;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dmacro;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.lexer;\nimport dmd.mtype;\nimport dmd.root.array;\nimport dmd.root.file;\nimport dmd.root.filename;\nimport dmd.root.outbuffer;\nimport dmd.root.port;\nimport dmd.root.rmem;\nimport dmd.tokens;\nimport dmd.utf;\nimport dmd.utils;\nimport dmd.visitor;\n\nstruct Escape\n{\n    const(char)[][char.max] strings;\n\n    /***************************************\n     * Find character string to replace c with.\n     */\n    const(char)[] escapeChar(char c)\n    {\n        version (all)\n        {\n            //printf(\"escapeChar('%c') => %p, %p\\n\", c, strings, strings[c].ptr);\n            return strings[c];\n        }\n        else\n        {\n            const(char)[] s;\n            switch (c)\n            {\n            case '<':\n                s = \"&lt;\";\n                break;\n            case '>':\n                s = \"&gt;\";\n                break;\n            case '&':\n                s = \"&amp;\";\n                break;\n            default:\n                s = null;\n                break;\n            }\n            return s;\n        }\n    }\n}\n\n/***********************************************************\n */\nprivate class Section\n{\n    const(char)* name;\n    size_t namelen;\n    const(char)* _body;\n    size_t bodylen;\n    int nooutput;\n\n    void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)\n    {\n        assert(a.dim);\n        if (namelen)\n        {\n            static immutable table =\n            [\n                \"AUTHORS\",\n                \"BUGS\",\n                \"COPYRIGHT\",\n                \"DATE\",\n                \"DEPRECATED\",\n                \"EXAMPLES\",\n                \"HISTORY\",\n                \"LICENSE\",\n                \"RETURNS\",\n                \"SEE_ALSO\",\n                \"STANDARDS\",\n                \"THROWS\",\n                \"VERSION\",\n            ];\n            foreach (entry; table)\n            {\n                if (iequals(entry, name[0 .. namelen]))\n                {\n                    buf.printf(\"$(DDOC_%s \", entry.ptr);\n                    goto L1;\n                }\n            }\n            buf.writestring(\"$(DDOC_SECTION \");\n            // Replace _ characters with spaces\n            buf.writestring(\"$(DDOC_SECTION_H \");\n            size_t o = buf.offset;\n            for (size_t u = 0; u < namelen; u++)\n            {\n                char c = name[u];\n                buf.writeByte((c == '_') ? ' ' : c);\n            }\n            escapeStrayParenthesis(loc, buf, o);\n            buf.writestring(\")\");\n        }\n        else\n        {\n            buf.writestring(\"$(DDOC_DESCRIPTION \");\n        }\n    L1:\n        size_t o = buf.offset;\n        buf.write(_body, bodylen);\n        escapeStrayParenthesis(loc, buf, o);\n        highlightText(sc, a, buf, o);\n        buf.writestring(\")\");\n    }\n}\n\n/***********************************************************\n */\nprivate final class ParamSection : Section\n{\n    override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)\n    {\n        assert(a.dim);\n        Dsymbol s = (*a)[0]; // test\n        const(char)* p = _body;\n        size_t len = bodylen;\n        const(char)* pend = p + len;\n        const(char)* tempstart = null;\n        size_t templen = 0;\n        const(char)* namestart = null;\n        size_t namelen = 0; // !=0 if line continuation\n        const(char)* textstart = null;\n        size_t textlen = 0;\n        size_t paramcount = 0;\n        buf.writestring(\"$(DDOC_PARAMS \");\n        while (p < pend)\n        {\n            // Skip to start of macro\n            while (1)\n            {\n                switch (*p)\n                {\n                case ' ':\n                case '\\t':\n                    p++;\n                    continue;\n                case '\\n':\n                    p++;\n                    goto Lcont;\n                default:\n                    if (isIdStart(p) || isCVariadicArg(p[0 .. cast(size_t)(pend - p)]))\n                        break;\n                    if (namelen)\n                        goto Ltext;\n                    // continuation of prev macro\n                    goto Lskipline;\n                }\n                break;\n            }\n            tempstart = p;\n            while (isIdTail(p))\n                p += utfStride(p);\n            if (isCVariadicArg(p[0 .. cast(size_t)(pend - p)]))\n                p += 3;\n            templen = p - tempstart;\n            while (*p == ' ' || *p == '\\t')\n                p++;\n            if (*p != '=')\n            {\n                if (namelen)\n                    goto Ltext;\n                // continuation of prev macro\n                goto Lskipline;\n            }\n            p++;\n            if (namelen)\n            {\n                // Output existing param\n            L1:\n                //printf(\"param '%.*s' = '%.*s'\\n\", namelen, namestart, textlen, textstart);\n                ++paramcount;\n                HdrGenState hgs;\n                buf.writestring(\"$(DDOC_PARAM_ROW \");\n                {\n                    buf.writestring(\"$(DDOC_PARAM_ID \");\n                    {\n                        size_t o = buf.offset;\n                        Parameter fparam = isFunctionParameter(a, namestart, namelen);\n                        if (!fparam)\n                        {\n                            // Comments on a template might refer to function parameters within.\n                            // Search the parameters of nested eponymous functions (with the same name.)\n                            fparam = isEponymousFunctionParameter(a, namestart, namelen);\n                        }\n                        bool isCVariadic = isCVariadicParameter(a, namestart[0 .. namelen]);\n                        if (isCVariadic)\n                        {\n                            buf.writestring(\"...\");\n                        }\n                        else if (fparam && fparam.type && fparam.ident)\n                        {\n                            .toCBuffer(fparam.type, buf, fparam.ident, &hgs);\n                        }\n                        else\n                        {\n                            if (isTemplateParameter(a, namestart, namelen))\n                            {\n                                // 10236: Don't count template parameters for params check\n                                --paramcount;\n                            }\n                            else if (!fparam)\n                            {\n                                warning(s.loc, \"Ddoc: function declaration has no parameter '%.*s'\", namelen, namestart);\n                            }\n                            buf.write(namestart, namelen);\n                        }\n                        escapeStrayParenthesis(loc, buf, o);\n                        highlightCode(sc, a, buf, o);\n                    }\n                    buf.writestring(\")\");\n                    buf.writestring(\"$(DDOC_PARAM_DESC \");\n                    {\n                        size_t o = buf.offset;\n                        buf.write(textstart, textlen);\n                        escapeStrayParenthesis(loc, buf, o);\n                        highlightText(sc, a, buf, o);\n                    }\n                    buf.writestring(\")\");\n                }\n                buf.writestring(\")\");\n                namelen = 0;\n                if (p >= pend)\n                    break;\n            }\n            namestart = tempstart;\n            namelen = templen;\n            while (*p == ' ' || *p == '\\t')\n                p++;\n            textstart = p;\n        Ltext:\n            while (*p != '\\n')\n                p++;\n            textlen = p - textstart;\n            p++;\n        Lcont:\n            continue;\n        Lskipline:\n            // Ignore this line\n            while (*p++ != '\\n')\n            {\n            }\n        }\n        if (namelen)\n            goto L1;\n        // write out last one\n        buf.writestring(\")\");\n        TypeFunction tf = a.dim == 1 ? isTypeFunction(s) : null;\n        if (tf)\n        {\n            size_t pcount = (tf.parameters ? tf.parameters.dim : 0) + cast(int)(tf.varargs == 1);\n            if (pcount != paramcount)\n            {\n                warning(s.loc, \"Ddoc: parameter count mismatch\");\n            }\n        }\n    }\n}\n\n/***********************************************************\n */\nprivate final class MacroSection : Section\n{\n    override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)\n    {\n        //printf(\"MacroSection::write()\\n\");\n        DocComment.parseMacros(dc.pescapetable, dc.pmacrotable, _body, bodylen);\n    }\n}\n\nprivate alias Sections = Array!(Section);\n\n// Workaround for missing Parameter instance for variadic params. (it's unnecessary to instantiate one).\nprivate bool isCVariadicParameter(Dsymbols* a, const(char)[] p)\n{\n    foreach (member; *a)\n    {\n        TypeFunction tf = isTypeFunction(member);\n        if (tf && tf.varargs == 1 && p == \"...\")\n            return true;\n    }\n    return false;\n}\n\nprivate Dsymbol getEponymousMember(TemplateDeclaration td)\n{\n    if (!td.onemember)\n        return null;\n    if (AggregateDeclaration ad = td.onemember.isAggregateDeclaration())\n        return ad;\n    if (FuncDeclaration fd = td.onemember.isFuncDeclaration())\n        return fd;\n    if (auto em = td.onemember.isEnumMember())\n        return null;    // Keep backward compatibility. See compilable/ddoc9.d\n    if (VarDeclaration vd = td.onemember.isVarDeclaration())\n        return td.constraint ? null : vd;\n    return null;\n}\n\nprivate TemplateDeclaration getEponymousParent(Dsymbol s)\n{\n    if (!s.parent)\n        return null;\n    TemplateDeclaration td = s.parent.isTemplateDeclaration();\n    return (td && getEponymousMember(td)) ? td : null;\n}\n\nprivate immutable ddoc_default = import(\"default_ddoc_theme.ddoc\");\nprivate immutable ddoc_decl_s = \"$(DDOC_DECL \";\nprivate immutable ddoc_decl_e = \")\\n\";\nprivate immutable ddoc_decl_dd_s = \"$(DDOC_DECL_DD \";\nprivate immutable ddoc_decl_dd_e = \")\\n\";\n\n/****************************************************\n */\nextern(C++) void gendocfile(Module m)\n{\n    __gshared OutBuffer mbuf;\n    __gshared int mbuf_done;\n    OutBuffer buf;\n    //printf(\"Module::gendocfile()\\n\");\n    if (!mbuf_done) // if not already read the ddoc files\n    {\n        mbuf_done = 1;\n        // Use our internal default\n        mbuf.writestring(ddoc_default);\n        // Override with DDOCFILE specified in the sc.ini file\n        char* p = getenv(\"DDOCFILE\");\n        if (p)\n            global.params.ddocfiles.shift(p);\n        // Override with the ddoc macro files from the command line\n        for (size_t i = 0; i < global.params.ddocfiles.dim; i++)\n        {\n            auto file = File(global.params.ddocfiles[i].toDString());\n            readFile(m.loc, &file);\n            // BUG: convert file contents to UTF-8 before use\n            //printf(\"file: '%.*s'\\n\", file.len, file.buffer);\n            mbuf.write(file.buffer, file.len);\n        }\n    }\n    DocComment.parseMacros(&m.escapetable, &m.macrotable, mbuf.peekSlice().ptr, mbuf.peekSlice().length);\n    Scope* sc = Scope.createGlobal(m); // create root scope\n    DocComment* dc = DocComment.parse(m, m.comment);\n    dc.pmacrotable = &m.macrotable;\n    dc.pescapetable = &m.escapetable;\n    sc.lastdc = dc;\n    // Generate predefined macros\n    // Set the title to be the name of the module\n    {\n        const p = m.toPrettyChars().toDString;\n        Macro.define(&m.macrotable, \"TITLE\", p);\n    }\n    // Set time macros\n    {\n        time_t t;\n        time(&t);\n        char* p = ctime(&t);\n        p = mem.xstrdup(p);\n        Macro.define(&m.macrotable, \"DATETIME\", p[0 .. strlen(p)]);\n        Macro.define(&m.macrotable, \"YEAR\", p[20 .. 20 + 4]);\n    }\n    const srcfilename = m.srcfile.toString();\n    Macro.define(&m.macrotable, \"SRCFILENAME\", srcfilename);\n    const docfilename = m.docfile.toString();\n    Macro.define(&m.macrotable, \"DOCFILENAME\", docfilename);\n    if (dc.copyright)\n    {\n        dc.copyright.nooutput = 1;\n        Macro.define(&m.macrotable, \"COPYRIGHT\", dc.copyright._body[0 .. dc.copyright.bodylen]);\n    }\n    if (m.isDocFile)\n    {\n        Loc loc = m.md ? m.md.loc : m.loc;\n        size_t commentlen = strlen(cast(char*)m.comment);\n        Dsymbols a;\n        // https://issues.dlang.org/show_bug.cgi?id=9764\n        // Don't push m in a, to prevent emphasize ddoc file name.\n        if (dc.macros)\n        {\n            commentlen = dc.macros.name - m.comment;\n            dc.macros.write(loc, dc, sc, &a, &buf);\n        }\n        buf.write(m.comment, commentlen);\n        highlightText(sc, &a, &buf, 0);\n    }\n    else\n    {\n        Dsymbols a;\n        a.push(m);\n        dc.writeSections(sc, &a, &buf);\n        emitMemberComments(m, &buf, sc);\n    }\n    //printf(\"BODY= '%.*s'\\n\", buf.offset, buf.data);\n    Macro.define(&m.macrotable, \"BODY\", buf.peekSlice());\n    OutBuffer buf2;\n    buf2.writestring(\"$(DDOC)\");\n    size_t end = buf2.offset;\n    m.macrotable.expand(&buf2, 0, &end, null);\n    version (all)\n    {\n        /* Remove all the escape sequences from buf2,\n         * and make CR-LF the newline.\n         */\n        {\n            const slice = buf2.peekSlice();\n            buf.setsize(0);\n            buf.reserve(slice.length);\n            auto p = slice.ptr;\n            for (size_t j = 0; j < slice.length; j++)\n            {\n                char c = p[j];\n                if (c == 0xFF && j + 1 < slice.length)\n                {\n                    j++;\n                    continue;\n                }\n                if (c == '\\n')\n                    buf.writeByte('\\r');\n                else if (c == '\\r')\n                {\n                    buf.writestring(\"\\r\\n\");\n                    if (j + 1 < slice.length && p[j + 1] == '\\n')\n                    {\n                        j++;\n                    }\n                    continue;\n                }\n                buf.writeByte(c);\n            }\n        }\n        // Transfer image to file\n        assert(m.docfile);\n        m.docfile.setbuffer(cast(void*)buf.peekSlice().ptr, buf.peekSlice().length);\n        m.docfile._ref = 1;\n        ensurePathToNameExists(Loc.initial, m.docfile.toChars());\n        writeFile(m.loc, m.docfile);\n    }\n    else\n    {\n        /* Remove all the escape sequences from buf2\n         */\n        {\n            size_t i = 0;\n            char* p = buf2.data;\n            for (size_t j = 0; j < buf2.offset; j++)\n            {\n                if (p[j] == 0xFF && j + 1 < buf2.offset)\n                {\n                    j++;\n                    continue;\n                }\n                p[i] = p[j];\n                i++;\n            }\n            buf2.setsize(i);\n        }\n        // Transfer image to file\n        m.docfile.setbuffer(buf2.data, buf2.offset);\n        m.docfile._ref = 1;\n        ensurePathToNameExists(Loc.initial, m.docfile.toChars());\n        writeFile(m.loc, m.docfile);\n    }\n}\n\n/****************************************************\n * Having unmatched parentheses can hose the output of Ddoc,\n * as the macros depend on properly nested parentheses.\n * This function replaces all ( with $(LPAREN) and ) with $(RPAREN)\n * to preserve text literally. This also means macros in the\n * text won't be expanded.\n */\nvoid escapeDdocString(OutBuffer* buf, size_t start)\n{\n    for (size_t u = start; u < buf.offset; u++)\n    {\n        char c = buf.data[u];\n        switch (c)\n        {\n        case '$':\n            buf.remove(u, 1);\n            buf.insert(u, \"$(DOLLAR)\");\n            u += 8;\n            break;\n        case '(':\n            buf.remove(u, 1); //remove the (\n            buf.insert(u, \"$(LPAREN)\"); //insert this instead\n            u += 8; //skip over newly inserted macro\n            break;\n        case ')':\n            buf.remove(u, 1); //remove the )\n            buf.insert(u, \"$(RPAREN)\"); //insert this instead\n            u += 8; //skip over newly inserted macro\n            break;\n        default:\n            break;\n        }\n    }\n}\n\n/****************************************************\n * Having unmatched parentheses can hose the output of Ddoc,\n * as the macros depend on properly nested parentheses.\n *\n * Fix by replacing unmatched ( with $(LPAREN) and unmatched ) with $(RPAREN).\n */\nprivate void escapeStrayParenthesis(Loc loc, OutBuffer* buf, size_t start)\n{\n    uint par_open = 0;\n    char inCode = 0;\n    bool atLineStart = true;\n    for (size_t u = start; u < buf.offset; u++)\n    {\n        char c = buf.data[u];\n        switch (c)\n        {\n        case '(':\n            if (!inCode)\n                par_open++;\n            atLineStart = false;\n            break;\n        case ')':\n            if (!inCode)\n            {\n                if (par_open == 0)\n                {\n                    //stray ')'\n                    warning(loc, \"Ddoc: Stray ')'. This may cause incorrect Ddoc output. Use $(RPAREN) instead for unpaired right parentheses.\");\n                    buf.remove(u, 1); //remove the )\n                    buf.insert(u, \"$(RPAREN)\"); //insert this instead\n                    u += 8; //skip over newly inserted macro\n                }\n                else\n                    par_open--;\n            }\n            atLineStart = false;\n            break;\n        case '\\n':\n            atLineStart = true;\n            version (none)\n            {\n                // For this to work, loc must be set to the beginning of the passed\n                // text which is currently not possible\n                // (loc is set to the Loc of the Dsymbol)\n                loc.linnum++;\n            }\n            break;\n        case ' ':\n        case '\\r':\n        case '\\t':\n            break;\n        case '-':\n        case '`':\n            // Issue 15465: don't try to escape unbalanced parens inside code\n            // blocks.\n            int numdash = 1;\n            for (++u; u < buf.offset && buf.data[u] == '-'; ++u)\n                ++numdash;\n            --u;\n            if (c == '`' || (atLineStart && numdash >= 3))\n            {\n                if (inCode == c)\n                    inCode = 0;\n                else if (!inCode)\n                    inCode = c;\n            }\n            atLineStart = false;\n            break;\n        default:\n            atLineStart = false;\n            break;\n        }\n    }\n    if (par_open) // if any unmatched lparens\n    {\n        par_open = 0;\n        for (size_t u = buf.offset; u > start;)\n        {\n            u--;\n            char c = buf.data[u];\n            switch (c)\n            {\n            case ')':\n                par_open++;\n                break;\n            case '(':\n                if (par_open == 0)\n                {\n                    //stray '('\n                    warning(loc, \"Ddoc: Stray '('. This may cause incorrect Ddoc output. Use $(LPAREN) instead for unpaired left parentheses.\");\n                    buf.remove(u, 1); //remove the (\n                    buf.insert(u, \"$(LPAREN)\"); //insert this instead\n                }\n                else\n                    par_open--;\n                break;\n            default:\n                break;\n            }\n        }\n    }\n}\n\n// Basically, this is to skip over things like private{} blocks in a struct or\n// class definition that don't add any components to the qualified name.\nprivate Scope* skipNonQualScopes(Scope* sc)\n{\n    while (sc && !sc.scopesym)\n        sc = sc.enclosing;\n    return sc;\n}\n\nprivate bool emitAnchorName(OutBuffer* buf, Dsymbol s, Scope* sc, bool includeParent)\n{\n    if (!s || s.isPackage() || s.isModule())\n        return false;\n    // Add parent names first\n    bool dot = false;\n    auto eponymousParent = getEponymousParent(s);\n    if (includeParent && s.parent || eponymousParent)\n        dot = emitAnchorName(buf, s.parent, sc, includeParent);\n    else if (includeParent && sc)\n        dot = emitAnchorName(buf, sc.scopesym, skipNonQualScopes(sc.enclosing), includeParent);\n    // Eponymous template members can share the parent anchor name\n    if (eponymousParent)\n        return dot;\n    if (dot)\n        buf.writeByte('.');\n    // Use \"this\" not \"__ctor\"\n    TemplateDeclaration td;\n    if (s.isCtorDeclaration() || ((td = s.isTemplateDeclaration()) !is null && td.onemember && td.onemember.isCtorDeclaration()))\n    {\n        buf.writestring(\"this\");\n    }\n    else\n    {\n        /* We just want the identifier, not overloads like TemplateDeclaration::toChars.\n         * We don't want the template parameter list and constraints. */\n        buf.writestring(s.Dsymbol.toChars());\n    }\n    return true;\n}\n\nprivate void emitAnchor(OutBuffer* buf, Dsymbol s, Scope* sc, bool forHeader = false)\n{\n    Identifier ident;\n    {\n        OutBuffer anc;\n        emitAnchorName(&anc, s, skipNonQualScopes(sc), true);\n        ident = Identifier.idPool(anc.peekSlice());\n    }\n\n    auto pcount = cast(void*)ident in sc.anchorCounts;\n    typeof(*pcount) count;\n    if (!forHeader)\n    {\n        if (pcount)\n        {\n            // Existing anchor,\n            // don't write an anchor for matching consecutive ditto symbols\n            TemplateDeclaration td = getEponymousParent(s);\n            if (sc.prevAnchor == ident && sc.lastdc && (isDitto(s.comment) || (td && isDitto(td.comment))))\n                return;\n\n            count = ++*pcount;\n        }\n        else\n        {\n            sc.anchorCounts[cast(void*)ident] = 1;\n            count = 1;\n        }\n    }\n\n    // cache anchor name\n    sc.prevAnchor = ident;\n    auto macroName = forHeader ? \"DDOC_HEADER_ANCHOR\" : \"DDOC_ANCHOR\";\n    auto symbolName = ident.toString();\n    buf.printf(\"$(%.*s %.*s\", cast(int) macroName.length, macroName.ptr,\n        cast(int) symbolName.length, symbolName.ptr);\n    // only append count once there's a duplicate\n    if (count > 1)\n        buf.printf(\".%u\", count);\n\n    if (forHeader)\n    {\n        Identifier shortIdent;\n        {\n            OutBuffer anc;\n            emitAnchorName(&anc, s, skipNonQualScopes(sc), false);\n            shortIdent = Identifier.idPool(anc.peekSlice());\n        }\n\n        auto shortName = shortIdent.toString();\n        buf.printf(\", %.*s\", cast(int) shortName.length, shortName.ptr);\n    }\n\n    buf.writeByte(')');\n}\n\n/******************************* emitComment **********************************/\n\n/** Get leading indentation from 'src' which represents lines of code. */\nprivate size_t getCodeIndent(const(char)* src)\n{\n    while (src && (*src == '\\r' || *src == '\\n'))\n        ++src; // skip until we find the first non-empty line\n    size_t codeIndent = 0;\n    while (src && (*src == ' ' || *src == '\\t'))\n    {\n        codeIndent++;\n        src++;\n    }\n    return codeIndent;\n}\n\n/** Recursively expand template mixin member docs into the scope. */\nprivate void expandTemplateMixinComments(TemplateMixin tm, OutBuffer* buf, Scope* sc)\n{\n    if (!tm.semanticRun)\n        tm.dsymbolSemantic(sc);\n    TemplateDeclaration td = (tm && tm.tempdecl) ? tm.tempdecl.isTemplateDeclaration() : null;\n    if (td && td.members)\n    {\n        for (size_t i = 0; i < td.members.dim; i++)\n        {\n            Dsymbol sm = (*td.members)[i];\n            TemplateMixin tmc = sm.isTemplateMixin();\n            if (tmc && tmc.comment)\n                expandTemplateMixinComments(tmc, buf, sc);\n            else\n                emitComment(sm, buf, sc);\n        }\n    }\n}\n\nprivate void emitMemberComments(ScopeDsymbol sds, OutBuffer* buf, Scope* sc)\n{\n    if (!sds.members)\n        return;\n    //printf(\"ScopeDsymbol::emitMemberComments() %s\\n\", toChars());\n    const(char)[] m = \"$(DDOC_MEMBERS \";\n    if (sds.isTemplateDeclaration())\n        m = \"$(DDOC_TEMPLATE_MEMBERS \";\n    else if (sds.isClassDeclaration())\n        m = \"$(DDOC_CLASS_MEMBERS \";\n    else if (sds.isStructDeclaration())\n        m = \"$(DDOC_STRUCT_MEMBERS \";\n    else if (sds.isEnumDeclaration())\n        m = \"$(DDOC_ENUM_MEMBERS \";\n    else if (sds.isModule())\n        m = \"$(DDOC_MODULE_MEMBERS \";\n    size_t offset1 = buf.offset; // save starting offset\n    buf.writestring(m);\n    size_t offset2 = buf.offset; // to see if we write anything\n    sc = sc.push(sds);\n    for (size_t i = 0; i < sds.members.dim; i++)\n    {\n        Dsymbol s = (*sds.members)[i];\n        //printf(\"\\ts = '%s'\\n\", s.toChars());\n        // only expand if parent is a non-template (semantic won't work)\n        if (s.comment && s.isTemplateMixin() && s.parent && !s.parent.isTemplateDeclaration())\n            expandTemplateMixinComments(cast(TemplateMixin)s, buf, sc);\n        emitComment(s, buf, sc);\n    }\n    emitComment(null, buf, sc);\n    sc.pop();\n    if (buf.offset == offset2)\n    {\n        /* Didn't write out any members, so back out last write\n         */\n        buf.offset = offset1;\n    }\n    else\n        buf.writestring(\")\");\n}\n\nprivate void emitProtection(OutBuffer* buf, Prot prot)\n{\n    if (prot.kind != Prot.Kind.undefined && prot.kind != Prot.Kind.public_)\n    {\n        protectionToBuffer(buf, prot);\n        buf.writeByte(' ');\n    }\n}\n\nprivate void emitComment(Dsymbol s, OutBuffer* buf, Scope* sc)\n{\n    extern (C++) final class EmitComment : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        OutBuffer* buf;\n        Scope* sc;\n\n        extern (D) this(OutBuffer* buf, Scope* sc)\n        {\n            this.buf = buf;\n            this.sc = sc;\n        }\n\n        override void visit(Dsymbol)\n        {\n        }\n\n        override void visit(InvariantDeclaration)\n        {\n        }\n\n        override void visit(UnitTestDeclaration)\n        {\n        }\n\n        override void visit(PostBlitDeclaration)\n        {\n        }\n\n        override void visit(DtorDeclaration)\n        {\n        }\n\n        override void visit(StaticCtorDeclaration)\n        {\n        }\n\n        override void visit(StaticDtorDeclaration)\n        {\n        }\n\n        override void visit(TypeInfoDeclaration)\n        {\n        }\n\n        void emit(Scope* sc, Dsymbol s, const(char)* com)\n        {\n            if (s && sc.lastdc && isDitto(com))\n            {\n                sc.lastdc.a.push(s);\n                return;\n            }\n            // Put previous doc comment if exists\n            if (DocComment* dc = sc.lastdc)\n            {\n                assert(dc.a.dim > 0, \"Expects at least one declaration for a\" ~\n                    \"documentation comment\");\n\n                auto symbol = dc.a[0];\n\n                buf.writestring(\"$(DDOC_MEMBER\");\n                buf.writestring(\"$(DDOC_MEMBER_HEADER\");\n                emitAnchor(buf, symbol, sc, true);\n                buf.writeByte(')');\n\n                // Put the declaration signatures as the document 'title'\n                buf.writestring(ddoc_decl_s);\n                for (size_t i = 0; i < dc.a.dim; i++)\n                {\n                    Dsymbol sx = dc.a[i];\n                    // the added linebreaks in here make looking at multiple\n                    // signatures more appealing\n                    if (i == 0)\n                    {\n                        size_t o = buf.offset;\n                        toDocBuffer(sx, buf, sc);\n                        highlightCode(sc, sx, buf, o);\n                        buf.writestring(\"$(DDOC_OVERLOAD_SEPARATOR)\");\n                        continue;\n                    }\n                    buf.writestring(\"$(DDOC_DITTO \");\n                    {\n                        size_t o = buf.offset;\n                        toDocBuffer(sx, buf, sc);\n                        highlightCode(sc, sx, buf, o);\n                    }\n                    buf.writestring(\"$(DDOC_OVERLOAD_SEPARATOR)\");\n                    buf.writeByte(')');\n                }\n                buf.writestring(ddoc_decl_e);\n                // Put the ddoc comment as the document 'description'\n                buf.writestring(ddoc_decl_dd_s);\n                {\n                    dc.writeSections(sc, &dc.a, buf);\n                    if (ScopeDsymbol sds = dc.a[0].isScopeDsymbol())\n                        emitMemberComments(sds, buf, sc);\n                }\n                buf.writestring(ddoc_decl_dd_e);\n                buf.writeByte(')');\n                //printf(\"buf.2 = [[%.*s]]\\n\", buf.offset - o0, buf.data + o0);\n            }\n            if (s)\n            {\n                DocComment* dc = DocComment.parse(s, com);\n                dc.pmacrotable = &sc._module.macrotable;\n                sc.lastdc = dc;\n            }\n        }\n\n        override void visit(Declaration d)\n        {\n            //printf(\"Declaration::emitComment(%p '%s'), comment = '%s'\\n\", d, d.toChars(), d.comment);\n            //printf(\"type = %p\\n\", d.type);\n            const(char)* com = d.comment;\n            if (TemplateDeclaration td = getEponymousParent(d))\n            {\n                if (isDitto(td.comment))\n                    com = td.comment;\n                else\n                    com = Lexer.combineComments(td.comment, com, true);\n            }\n            else\n            {\n                if (!d.ident)\n                    return;\n                if (!d.type)\n                {\n                    if (!d.isCtorDeclaration() &&\n                        !d.isAliasDeclaration() &&\n                        !d.isVarDeclaration())\n                    {\n                        return;\n                    }\n                }\n                if (d.protection.kind == Prot.Kind.private_ || sc.protection.kind == Prot.Kind.private_)\n                    return;\n            }\n            if (!com)\n                return;\n            emit(sc, d, com);\n        }\n\n        override void visit(AggregateDeclaration ad)\n        {\n            //printf(\"AggregateDeclaration::emitComment() '%s'\\n\", ad.toChars());\n            const(char)* com = ad.comment;\n            if (TemplateDeclaration td = getEponymousParent(ad))\n            {\n                if (isDitto(td.comment))\n                    com = td.comment;\n                else\n                    com = Lexer.combineComments(td.comment, com, true);\n            }\n            else\n            {\n                if (ad.prot().kind == Prot.Kind.private_ || sc.protection.kind == Prot.Kind.private_)\n                    return;\n                if (!ad.comment)\n                    return;\n            }\n            if (!com)\n                return;\n            emit(sc, ad, com);\n        }\n\n        override void visit(TemplateDeclaration td)\n        {\n            //printf(\"TemplateDeclaration::emitComment() '%s', kind = %s\\n\", td.toChars(), td.kind());\n            if (td.prot().kind == Prot.Kind.private_ || sc.protection.kind == Prot.Kind.private_)\n                return;\n            if (!td.comment)\n                return;\n            if (Dsymbol ss = getEponymousMember(td))\n            {\n                ss.accept(this);\n                return;\n            }\n            emit(sc, td, td.comment);\n        }\n\n        override void visit(EnumDeclaration ed)\n        {\n            if (ed.prot().kind == Prot.Kind.private_ || sc.protection.kind == Prot.Kind.private_)\n                return;\n            if (ed.isAnonymous() && ed.members)\n            {\n                for (size_t i = 0; i < ed.members.dim; i++)\n                {\n                    Dsymbol s = (*ed.members)[i];\n                    emitComment(s, buf, sc);\n                }\n                return;\n            }\n            if (!ed.comment)\n                return;\n            if (ed.isAnonymous())\n                return;\n            emit(sc, ed, ed.comment);\n        }\n\n        override void visit(EnumMember em)\n        {\n            //printf(\"EnumMember::emitComment(%p '%s'), comment = '%s'\\n\", em, em.toChars(), em.comment);\n            if (em.prot().kind == Prot.Kind.private_ || sc.protection.kind == Prot.Kind.private_)\n                return;\n            if (!em.comment)\n                return;\n            emit(sc, em, em.comment);\n        }\n\n        override void visit(AttribDeclaration ad)\n        {\n            //printf(\"AttribDeclaration::emitComment(sc = %p)\\n\", sc);\n            /* A general problem with this,\n             * illustrated by https://issues.dlang.org/show_bug.cgi?id=2516\n             * is that attributes are not transmitted through to the underlying\n             * member declarations for template bodies, because semantic analysis\n             * is not done for template declaration bodies\n             * (only template instantiations).\n             * Hence, Ddoc omits attributes from template members.\n             */\n            Dsymbols* d = ad.include(null);\n            if (d)\n            {\n                for (size_t i = 0; i < d.dim; i++)\n                {\n                    Dsymbol s = (*d)[i];\n                    //printf(\"AttribDeclaration::emitComment %s\\n\", s.toChars());\n                    emitComment(s, buf, sc);\n                }\n            }\n        }\n\n        override void visit(ProtDeclaration pd)\n        {\n            if (pd.decl)\n            {\n                Scope* scx = sc;\n                sc = sc.copy();\n                sc.protection = pd.protection;\n                visit(cast(AttribDeclaration)pd);\n                scx.lastdc = sc.lastdc;\n                sc = sc.pop();\n            }\n        }\n\n        override void visit(ConditionalDeclaration cd)\n        {\n            //printf(\"ConditionalDeclaration::emitComment(sc = %p)\\n\", sc);\n            if (cd.condition.inc)\n            {\n                visit(cast(AttribDeclaration)cd);\n                return;\n            }\n            /* If generating doc comment, be careful because if we're inside\n             * a template, then include(null) will fail.\n             */\n            Dsymbols* d = cd.decl ? cd.decl : cd.elsedecl;\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                emitComment(s, buf, sc);\n            }\n        }\n    }\n\n    scope EmitComment v = new EmitComment(buf, sc);\n    if (!s)\n        v.emit(sc, null, null);\n    else\n        s.accept(v);\n}\n\nprivate void toDocBuffer(Dsymbol s, OutBuffer* buf, Scope* sc)\n{\n    extern (C++) final class ToDocBuffer : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        OutBuffer* buf;\n        Scope* sc;\n\n        extern (D) this(OutBuffer* buf, Scope* sc)\n        {\n            this.buf = buf;\n            this.sc = sc;\n        }\n\n        override void visit(Dsymbol s)\n        {\n            //printf(\"Dsymbol::toDocbuffer() %s\\n\", s.toChars());\n            HdrGenState hgs;\n            hgs.ddoc = true;\n            .toCBuffer(s, buf, &hgs);\n        }\n\n        void prefix(Dsymbol s)\n        {\n            if (s.isDeprecated())\n                buf.writestring(\"deprecated \");\n            if (Declaration d = s.isDeclaration())\n            {\n                emitProtection(buf, d.protection);\n                if (d.isStatic())\n                    buf.writestring(\"static \");\n                else if (d.isFinal())\n                    buf.writestring(\"final \");\n                else if (d.isAbstract())\n                    buf.writestring(\"abstract \");\n\n                if (d.isFuncDeclaration())      // functionToBufferFull handles this\n                    return;\n\n                if (d.isImmutable())\n                    buf.writestring(\"immutable \");\n                if (d.storage_class & STC.shared_)\n                    buf.writestring(\"shared \");\n                if (d.isWild())\n                    buf.writestring(\"inout \");\n                if (d.isConst())\n                    buf.writestring(\"const \");\n\n                if (d.isSynchronized())\n                    buf.writestring(\"synchronized \");\n\n                if (d.storage_class & STC.manifest)\n                    buf.writestring(\"enum \");\n\n                // Add \"auto\" for the untyped variable in template members\n                if (!d.type && d.isVarDeclaration() &&\n                    !d.isImmutable() && !(d.storage_class & STC.shared_) && !d.isWild() && !d.isConst() &&\n                    !d.isSynchronized())\n                {\n                    buf.writestring(\"auto \");\n                }\n            }\n        }\n\n        override void visit(Declaration d)\n        {\n            if (!d.ident)\n                return;\n            TemplateDeclaration td = getEponymousParent(d);\n            //printf(\"Declaration::toDocbuffer() %s, originalType = %s, td = %s\\n\", d.toChars(), d.originalType ? d.originalType.toChars() : \"--\", td ? td.toChars() : \"--\");\n            HdrGenState hgs;\n            hgs.ddoc = true;\n            if (d.isDeprecated())\n                buf.writestring(\"$(DEPRECATED \");\n            prefix(d);\n            if (d.type)\n            {\n                Type origType = d.originalType ? d.originalType : d.type;\n                if (origType.ty == Tfunction)\n                {\n                    functionToBufferFull(cast(TypeFunction)origType, buf, d.ident, &hgs, td);\n                }\n                else\n                    .toCBuffer(origType, buf, d.ident, &hgs);\n            }\n            else\n                buf.writestring(d.ident.toChars());\n            if (d.isVarDeclaration() && td)\n            {\n                buf.writeByte('(');\n                if (td.origParameters && td.origParameters.dim)\n                {\n                    for (size_t i = 0; i < td.origParameters.dim; i++)\n                    {\n                        if (i)\n                            buf.writestring(\", \");\n                        toCBuffer((*td.origParameters)[i], buf, &hgs);\n                    }\n                }\n                buf.writeByte(')');\n            }\n            // emit constraints if declaration is a templated declaration\n            if (td && td.constraint)\n            {\n                bool noFuncDecl = td.isFuncDeclaration() is null;\n                if (noFuncDecl)\n                {\n                    buf.writestring(\"$(DDOC_CONSTRAINT \");\n                }\n\n                .toCBuffer(td.constraint, buf, &hgs);\n\n                if (noFuncDecl)\n                {\n                    buf.writestring(\")\");\n                }\n            }\n            if (d.isDeprecated())\n                buf.writestring(\")\");\n            buf.writestring(\";\\n\");\n        }\n\n        override void visit(AliasDeclaration ad)\n        {\n            //printf(\"AliasDeclaration::toDocbuffer() %s\\n\", ad.toChars());\n            if (!ad.ident)\n                return;\n            if (ad.isDeprecated())\n                buf.writestring(\"deprecated \");\n            emitProtection(buf, ad.protection);\n            buf.printf(\"alias %s = \", ad.toChars());\n            if (Dsymbol s = ad.aliassym) // ident alias\n            {\n                prettyPrintDsymbol(s, ad.parent);\n            }\n            else if (Type type = ad.getType()) // type alias\n            {\n                if (type.ty == Tclass || type.ty == Tstruct || type.ty == Tenum)\n                {\n                    if (Dsymbol s = type.toDsymbol(null)) // elaborate type\n                        prettyPrintDsymbol(s, ad.parent);\n                    else\n                        buf.writestring(type.toChars());\n                }\n                else\n                {\n                    // simple type\n                    buf.writestring(type.toChars());\n                }\n            }\n            buf.writestring(\";\\n\");\n        }\n\n        void parentToBuffer(Dsymbol s)\n        {\n            if (s && !s.isPackage() && !s.isModule())\n            {\n                parentToBuffer(s.parent);\n                buf.writestring(s.toChars());\n                buf.writestring(\".\");\n            }\n        }\n\n        static bool inSameModule(Dsymbol s, Dsymbol p)\n        {\n            for (; s; s = s.parent)\n            {\n                if (s.isModule())\n                    break;\n            }\n            for (; p; p = p.parent)\n            {\n                if (p.isModule())\n                    break;\n            }\n            return s == p;\n        }\n\n        void prettyPrintDsymbol(Dsymbol s, Dsymbol parent)\n        {\n            if (s.parent && (s.parent == parent)) // in current scope -> naked name\n            {\n                buf.writestring(s.toChars());\n            }\n            else if (!inSameModule(s, parent)) // in another module -> full name\n            {\n                buf.writestring(s.toPrettyChars());\n            }\n            else // nested in a type in this module -> full name w/o module name\n            {\n                // if alias is nested in a user-type use module-scope lookup\n                if (!parent.isModule() && !parent.isPackage())\n                    buf.writestring(\".\");\n                parentToBuffer(s.parent);\n                buf.writestring(s.toChars());\n            }\n        }\n\n        override void visit(AggregateDeclaration ad)\n        {\n            if (!ad.ident)\n                return;\n            version (none)\n            {\n                emitProtection(buf, ad.protection);\n            }\n            buf.printf(\"%s %s\", ad.kind(), ad.toChars());\n            buf.writestring(\";\\n\");\n        }\n\n        override void visit(StructDeclaration sd)\n        {\n            //printf(\"StructDeclaration::toDocbuffer() %s\\n\", sd.toChars());\n            if (!sd.ident)\n                return;\n            version (none)\n            {\n                emitProtection(buf, sd.protection);\n            }\n            if (TemplateDeclaration td = getEponymousParent(sd))\n            {\n                toDocBuffer(td, buf, sc);\n            }\n            else\n            {\n                buf.printf(\"%s %s\", sd.kind(), sd.toChars());\n            }\n            buf.writestring(\";\\n\");\n        }\n\n        override void visit(ClassDeclaration cd)\n        {\n            //printf(\"ClassDeclaration::toDocbuffer() %s\\n\", cd.toChars());\n            if (!cd.ident)\n                return;\n            version (none)\n            {\n                emitProtection(buf, cd.protection);\n            }\n            if (TemplateDeclaration td = getEponymousParent(cd))\n            {\n                toDocBuffer(td, buf, sc);\n            }\n            else\n            {\n                if (!cd.isInterfaceDeclaration() && cd.isAbstract())\n                    buf.writestring(\"abstract \");\n                buf.printf(\"%s %s\", cd.kind(), cd.toChars());\n            }\n            int any = 0;\n            for (size_t i = 0; i < cd.baseclasses.dim; i++)\n            {\n                BaseClass* bc = (*cd.baseclasses)[i];\n                if (bc.sym && bc.sym.ident == Id.Object)\n                    continue;\n                if (any)\n                    buf.writestring(\", \");\n                else\n                {\n                    buf.writestring(\": \");\n                    any = 1;\n                }\n                emitProtection(buf, Prot(Prot.Kind.public_));\n                if (bc.sym)\n                {\n                    buf.printf(\"$(DDOC_PSUPER_SYMBOL %s)\", bc.sym.toPrettyChars());\n                }\n                else\n                {\n                    HdrGenState hgs;\n                    .toCBuffer(bc.type, buf, null, &hgs);\n                }\n            }\n            buf.writestring(\";\\n\");\n        }\n\n        override void visit(EnumDeclaration ed)\n        {\n            if (!ed.ident)\n                return;\n            buf.printf(\"%s %s\", ed.kind(), ed.toChars());\n            if (ed.memtype)\n            {\n                buf.writestring(\": $(DDOC_ENUM_BASETYPE \");\n                HdrGenState hgs;\n                .toCBuffer(ed.memtype, buf, null, &hgs);\n                buf.writestring(\")\");\n            }\n            buf.writestring(\";\\n\");\n        }\n\n        override void visit(EnumMember em)\n        {\n            if (!em.ident)\n                return;\n            buf.writestring(em.toChars());\n        }\n    }\n\n    scope ToDocBuffer v = new ToDocBuffer(buf, sc);\n    s.accept(v);\n}\n\n/***********************************************************\n */\nstruct DocComment\n{\n    Sections sections;      // Section*[]\n    Section summary;\n    Section copyright;\n    Section macros;\n    Macro** pmacrotable;\n    Escape** pescapetable;\n    Dsymbols a;\n\n    static DocComment* parse(Dsymbol s, const(char)* comment)\n    {\n        //printf(\"parse(%s): '%s'\\n\", s.toChars(), comment);\n        auto dc = new DocComment();\n        dc.a.push(s);\n        if (!comment)\n            return dc;\n        dc.parseSections(comment);\n        for (size_t i = 0; i < dc.sections.dim; i++)\n        {\n            Section sec = dc.sections[i];\n            if (iequals(\"copyright\", sec.name[0 .. sec.namelen]))\n            {\n                dc.copyright = sec;\n            }\n            if (iequals(\"macros\", sec.name[0 .. sec.namelen]))\n            {\n                dc.macros = sec;\n            }\n        }\n        return dc;\n    }\n\n    /************************************************\n     * Parse macros out of Macros: section.\n     * Macros are of the form:\n     *      name1 = value1\n     *\n     *      name2 = value2\n     */\n    static void parseMacros(Escape** pescapetable, Macro** pmacrotable, const(char)* m, size_t mlen)\n    {\n        const(char)* p = m;\n        size_t len = mlen;\n        const(char)* pend = p + len;\n        const(char)* tempstart = null;\n        size_t templen = 0;\n        const(char)* namestart = null;\n        size_t namelen = 0; // !=0 if line continuation\n        const(char)* textstart = null;\n        size_t textlen = 0;\n        while (p < pend)\n        {\n            // Skip to start of macro\n            while (1)\n            {\n                if (p >= pend)\n                    goto Ldone;\n                switch (*p)\n                {\n                case ' ':\n                case '\\t':\n                    p++;\n                    continue;\n                case '\\r':\n                case '\\n':\n                    p++;\n                    goto Lcont;\n                default:\n                    if (isIdStart(p))\n                        break;\n                    if (namelen)\n                        goto Ltext; // continuation of prev macro\n                    goto Lskipline;\n                }\n                break;\n            }\n            tempstart = p;\n            while (1)\n            {\n                if (p >= pend)\n                    goto Ldone;\n                if (!isIdTail(p))\n                    break;\n                p += utfStride(p);\n            }\n            templen = p - tempstart;\n            while (1)\n            {\n                if (p >= pend)\n                    goto Ldone;\n                if (!(*p == ' ' || *p == '\\t'))\n                    break;\n                p++;\n            }\n            if (*p != '=')\n            {\n                if (namelen)\n                    goto Ltext; // continuation of prev macro\n                goto Lskipline;\n            }\n            p++;\n            if (p >= pend)\n                goto Ldone;\n            if (namelen)\n            {\n                // Output existing macro\n            L1:\n                //printf(\"macro '%.*s' = '%.*s'\\n\", namelen, namestart, textlen, textstart);\n                if (iequals(\"ESCAPES\", namestart[0 .. namelen]))\n                    parseEscapes(pescapetable, textstart, textlen);\n                else\n                    Macro.define(pmacrotable, namestart[0 ..namelen], textstart[0 .. textlen]);\n                namelen = 0;\n                if (p >= pend)\n                    break;\n            }\n            namestart = tempstart;\n            namelen = templen;\n            while (p < pend && (*p == ' ' || *p == '\\t'))\n                p++;\n            textstart = p;\n        Ltext:\n            while (p < pend && *p != '\\r' && *p != '\\n')\n                p++;\n            textlen = p - textstart;\n            p++;\n            //printf(\"p = %p, pend = %p\\n\", p, pend);\n        Lcont:\n            continue;\n        Lskipline:\n            // Ignore this line\n            while (p < pend && *p != '\\r' && *p != '\\n')\n                p++;\n        }\n    Ldone:\n        if (namelen)\n            goto L1; // write out last one\n    }\n\n    /**************************************\n     * Parse escapes of the form:\n     *      /c/string/\n     * where c is a single character.\n     * Multiple escapes can be separated\n     * by whitespace and/or commas.\n     */\n    static void parseEscapes(Escape** pescapetable, const(char)* textstart, size_t textlen)\n    {\n        Escape* escapetable = *pescapetable;\n        if (!escapetable)\n        {\n            escapetable = new Escape();\n            memset(escapetable, 0, Escape.sizeof);\n            *pescapetable = escapetable;\n        }\n        //printf(\"parseEscapes('%.*s') pescapetable = %p\\n\", textlen, textstart, pescapetable);\n        const(char)* p = textstart;\n        const(char)* pend = p + textlen;\n        while (1)\n        {\n            while (1)\n            {\n                if (p + 4 >= pend)\n                    return;\n                if (!(*p == ' ' || *p == '\\t' || *p == '\\r' || *p == '\\n' || *p == ','))\n                    break;\n                p++;\n            }\n            if (p[0] != '/' || p[2] != '/')\n                return;\n            char c = p[1];\n            p += 3;\n            const(char)* start = p;\n            while (1)\n            {\n                if (p >= pend)\n                    return;\n                if (*p == '/')\n                    break;\n                p++;\n            }\n            size_t len = p - start;\n            char* s = cast(char*)memcpy(mem.xmalloc(len + 1), start, len);\n            s[len] = 0;\n            escapetable.strings[c] = s[0 .. len];\n            //printf(\"\\t%c = '%s'\\n\", c, s);\n            p++;\n        }\n    }\n\n    /*****************************************\n     * Parse next paragraph out of *pcomment.\n     * Update *pcomment to point past paragraph.\n     * Returns NULL if no more paragraphs.\n     * If paragraph ends in 'identifier:',\n     * then (*pcomment)[0 .. idlen] is the identifier.\n     */\n    void parseSections(const(char)* comment)\n    {\n        const(char)* p;\n        const(char)* pstart;\n        const(char)* pend;\n        const(char)* idstart = null; // dead-store to prevent spurious warning\n        size_t idlen;\n        const(char)* name = null;\n        size_t namelen = 0;\n        //printf(\"parseSections('%s')\\n\", comment);\n        p = comment;\n        while (*p)\n        {\n            const(char)* pstart0 = p;\n            p = skipwhitespace(p);\n            pstart = p;\n            pend = p;\n            /* Find end of section, which is ended by one of:\n             *      'identifier:' (but not inside a code section)\n             *      '\\0'\n             */\n            idlen = 0;\n            int inCode = 0;\n            while (1)\n            {\n                // Check for start/end of a code section\n                if (*p == '-')\n                {\n                    if (!inCode)\n                    {\n                        // restore leading indentation\n                        while (pstart0 < pstart && isIndentWS(pstart - 1))\n                            --pstart;\n                    }\n                    int numdash = 0;\n                    while (*p == '-')\n                    {\n                        ++numdash;\n                        p++;\n                    }\n                    // BUG: handle UTF PS and LS too\n                    if ((!*p || *p == '\\r' || *p == '\\n') && numdash >= 3)\n                        inCode ^= 1;\n                    pend = p;\n                }\n                if (!inCode && isIdStart(p))\n                {\n                    const(char)* q = p + utfStride(p);\n                    while (isIdTail(q))\n                        q += utfStride(q);\n\n                    // Detected tag ends it\n                    if (*q == ':' && isupper(*p)\n                            && (isspace(q[1]) || q[1] == 0))\n                    {\n                        idlen = q - p;\n                        idstart = p;\n                        for (pend = p; pend > pstart; pend--)\n                        {\n                            if (pend[-1] == '\\n')\n                                break;\n                        }\n                        p = q + 1;\n                        break;\n                    }\n                }\n                while (1)\n                {\n                    if (!*p)\n                        goto L1;\n                    if (*p == '\\n')\n                    {\n                        p++;\n                        if (*p == '\\n' && !summary && !namelen && !inCode)\n                        {\n                            pend = p;\n                            p++;\n                            goto L1;\n                        }\n                        break;\n                    }\n                    p++;\n                    pend = p;\n                }\n                p = skipwhitespace(p);\n            }\n        L1:\n            if (namelen || pstart < pend)\n            {\n                Section s;\n                if (iequals(\"Params\", name[0 .. namelen]))\n                    s = new ParamSection();\n                else if (iequals(\"Macros\", name[0 .. namelen]))\n                    s = new MacroSection();\n                else\n                    s = new Section();\n                s.name = name;\n                s.namelen = namelen;\n                s._body = pstart;\n                s.bodylen = pend - pstart;\n                s.nooutput = 0;\n                //printf(\"Section: '%.*s' = '%.*s'\\n\", s.namelen, s.name, s.bodylen, s.body);\n                sections.push(s);\n                if (!summary && !namelen)\n                    summary = s;\n            }\n            if (idlen)\n            {\n                name = idstart;\n                namelen = idlen;\n            }\n            else\n            {\n                name = null;\n                namelen = 0;\n                if (!*p)\n                    break;\n            }\n        }\n    }\n\n    void writeSections(Scope* sc, Dsymbols* a, OutBuffer* buf)\n    {\n        assert(a.dim);\n        //printf(\"DocComment::writeSections()\\n\");\n        Loc loc = (*a)[0].loc;\n        if (Module m = (*a)[0].isModule())\n        {\n            if (m.md)\n                loc = m.md.loc;\n        }\n        size_t offset1 = buf.offset;\n        buf.writestring(\"$(DDOC_SECTIONS \");\n        size_t offset2 = buf.offset;\n        for (size_t i = 0; i < sections.dim; i++)\n        {\n            Section sec = sections[i];\n            if (sec.nooutput)\n                continue;\n            //printf(\"Section: '%.*s' = '%.*s'\\n\", sec.namelen, sec.name, sec.bodylen, sec.body);\n            if (!sec.namelen && i == 0)\n            {\n                buf.writestring(\"$(DDOC_SUMMARY \");\n                size_t o = buf.offset;\n                buf.write(sec._body, sec.bodylen);\n                escapeStrayParenthesis(loc, buf, o);\n                highlightText(sc, a, buf, o);\n                buf.writestring(\")\");\n            }\n            else\n                sec.write(loc, &this, sc, a, buf);\n        }\n        for (size_t i = 0; i < a.dim; i++)\n        {\n            Dsymbol s = (*a)[i];\n            if (Dsymbol td = getEponymousParent(s))\n                s = td;\n            for (UnitTestDeclaration utd = s.ddocUnittest; utd; utd = utd.ddocUnittest)\n            {\n                if (utd.protection.kind == Prot.Kind.private_ || !utd.comment || !utd.fbody)\n                    continue;\n                // Strip whitespaces to avoid showing empty summary\n                const(char)* c = utd.comment;\n                while (*c == ' ' || *c == '\\t' || *c == '\\n' || *c == '\\r')\n                    ++c;\n                buf.writestring(\"$(DDOC_EXAMPLES \");\n                size_t o = buf.offset;\n                buf.writestring(cast(char*)c);\n                if (utd.codedoc)\n                {\n                    auto codedoc = utd.codedoc.stripLeadingNewlines;\n                    size_t n = getCodeIndent(codedoc);\n                    while (n--)\n                        buf.writeByte(' ');\n                    buf.writestring(\"----\\n\");\n                    buf.writestring(codedoc);\n                    buf.writestring(\"----\\n\");\n                    highlightText(sc, a, buf, o);\n                }\n                buf.writestring(\")\");\n            }\n        }\n        if (buf.offset == offset2)\n        {\n            /* Didn't write out any sections, so back out last write\n             */\n            buf.offset = offset1;\n            buf.writestring(\"\\n\");\n        }\n        else\n            buf.writestring(\")\");\n    }\n}\n\n/*****************************************\n * Return true if comment consists entirely of \"ditto\".\n */\nprivate bool isDitto(const(char)* comment)\n{\n    if (comment)\n    {\n        const(char)* p = skipwhitespace(comment);\n        if (Port.memicmp(p, \"ditto\", 5) == 0 && *skipwhitespace(p + 5) == 0)\n            return true;\n    }\n    return false;\n}\n\n/**********************************************\n * Skip white space.\n */\nprivate const(char)* skipwhitespace(const(char)* p)\n{\n    return skipwhitespace(p.toDString).ptr;\n}\n\n/// Ditto\nprivate const(char)[] skipwhitespace(const(char)[] p)\n{\n    foreach (idx, char c; p)\n    {\n        switch (c)\n        {\n        case ' ':\n        case '\\t':\n        case '\\n':\n            continue;\n        default:\n            return p[idx .. $];\n        }\n    }\n    return p[$ .. $];\n}\n\n/************************************************\n * Scan forward to one of:\n *      start of identifier\n *      beginning of next line\n *      end of buf\n */\nsize_t skiptoident(OutBuffer* buf, size_t i)\n{\n    const slice = buf.peekSlice();\n    while (i < slice.length)\n    {\n        dchar c;\n        size_t oi = i;\n        if (utf_decodeChar(slice.ptr, slice.length, i, c))\n        {\n            /* Ignore UTF errors, but still consume input\n             */\n            break;\n        }\n        if (c >= 0x80)\n        {\n            if (!isUniAlpha(c))\n                continue;\n        }\n        else if (!(isalpha(c) || c == '_' || c == '\\n'))\n            continue;\n        i = oi;\n        break;\n    }\n    return i;\n}\n\n/************************************************\n * Scan forward past end of identifier.\n */\nprivate size_t skippastident(OutBuffer* buf, size_t i)\n{\n    const slice = buf.peekSlice();\n    while (i < slice.length)\n    {\n        dchar c;\n        size_t oi = i;\n        if (utf_decodeChar(slice.ptr, slice.length, i, c))\n        {\n            /* Ignore UTF errors, but still consume input\n             */\n            break;\n        }\n        if (c >= 0x80)\n        {\n            if (isUniAlpha(c))\n                continue;\n        }\n        else if (isalnum(c) || c == '_')\n            continue;\n        i = oi;\n        break;\n    }\n    return i;\n}\n\n/************************************************\n * Scan forward past URL starting at i.\n * We don't want to highlight parts of a URL.\n * Returns:\n *      i if not a URL\n *      index just past it if it is a URL\n */\nprivate size_t skippastURL(OutBuffer* buf, size_t i)\n{\n    const slice = buf.peekSlice()[i .. $];\n    size_t j;\n    bool sawdot = false;\n    if (slice.length > 7 && Port.memicmp(slice.ptr, \"http://\", 7) == 0)\n    {\n        j = 7;\n    }\n    else if (slice.length > 8 && Port.memicmp(slice.ptr, \"https://\", 8) == 0)\n    {\n        j = 8;\n    }\n    else\n        goto Lno;\n    for (; j < slice.length; j++)\n    {\n        const c = slice[j];\n        if (isalnum(c))\n            continue;\n        if (c == '-' || c == '_' || c == '?' || c == '=' || c == '%' ||\n            c == '&' || c == '/' || c == '+' || c == '#' || c == '~')\n            continue;\n        if (c == '.')\n        {\n            sawdot = true;\n            continue;\n        }\n        break;\n    }\n    if (sawdot)\n        return i + j;\nLno:\n    return i;\n}\n\n/****************************************************\n */\nprivate bool isIdentifier(Dsymbols* a, const(char)* p, size_t len)\n{\n    foreach (member; *a)\n    {\n        if (p[0 .. len] == member.ident.toString())\n            return true;\n    }\n    return false;\n}\n\n/****************************************************\n */\nprivate bool isKeyword(const(char)* p, size_t len)\n{\n    immutable string[3] table = [\"true\", \"false\", \"null\"];\n    foreach (s; table)\n    {\n        if (p[0 .. len] == s)\n            return true;\n    }\n    return false;\n}\n\n/****************************************************\n */\nprivate TypeFunction isTypeFunction(Dsymbol s)\n{\n    FuncDeclaration f = s.isFuncDeclaration();\n    /* f.type may be NULL for template members.\n     */\n    if (f && f.type)\n    {\n        Type t = f.originalType ? f.originalType : f.type;\n        if (t.ty == Tfunction)\n            return cast(TypeFunction)t;\n    }\n    return null;\n}\n\n/****************************************************\n */\nprivate Parameter isFunctionParameter(Dsymbol s, const(char)* p, size_t len)\n{\n    TypeFunction tf = isTypeFunction(s);\n    if (tf && tf.parameters)\n    {\n        foreach (fparam; *tf.parameters)\n        {\n            if (fparam.ident && p[0 .. len] == fparam.ident.toString())\n            {\n                return fparam;\n            }\n        }\n    }\n    return null;\n}\n\n/****************************************************\n */\nprivate Parameter isFunctionParameter(Dsymbols* a, const(char)* p, size_t len)\n{\n    for (size_t i = 0; i < a.dim; i++)\n    {\n        Parameter fparam = isFunctionParameter((*a)[i], p, len);\n        if (fparam)\n        {\n            return fparam;\n        }\n    }\n    return null;\n}\n\n/****************************************************\n */\nprivate Parameter isEponymousFunctionParameter(Dsymbols *a, const(char) *p, size_t len)\n{\n    for (size_t i = 0; i < a.dim; i++)\n    {\n        TemplateDeclaration td = (*a)[i].isTemplateDeclaration();\n        if (td && td.onemember)\n        {\n            /* Case 1: we refer to a template declaration inside the template\n\n               /// ...ddoc...\n               template case1(T) {\n                 void case1(R)() {}\n               }\n             */\n            td = td.onemember.isTemplateDeclaration();\n        }\n        if (!td)\n        {\n            /* Case 2: we're an alias to a template declaration\n\n               /// ...ddoc...\n               alias case2 = case1!int;\n             */\n            AliasDeclaration ad = (*a)[i].isAliasDeclaration();\n            if (ad && ad.aliassym)\n            {\n                td = ad.aliassym.isTemplateDeclaration();\n            }\n        }\n        while (td)\n        {\n            Dsymbol sym = getEponymousMember(td);\n            if (sym)\n            {\n                Parameter fparam = isFunctionParameter(sym, p, len);\n                if (fparam)\n                {\n                    return fparam;\n                }\n            }\n            td = td.overnext;\n        }\n    }\n    return null;\n}\n\n/****************************************************\n */\nprivate TemplateParameter isTemplateParameter(Dsymbols* a, const(char)* p, size_t len)\n{\n    for (size_t i = 0; i < a.dim; i++)\n    {\n        TemplateDeclaration td = (*a)[i].isTemplateDeclaration();\n        // Check for the parent, if the current symbol is not a template declaration.\n        if (!td)\n            td = getEponymousParent((*a)[i]);\n        if (td && td.origParameters)\n        {\n            foreach (tp; *td.origParameters)\n            {\n                if (tp.ident && p[0 .. len] == tp.ident.toString())\n                {\n                    return tp;\n                }\n            }\n        }\n    }\n    return null;\n}\n\n/****************************************************\n * Return true if str is a reserved symbol name\n * that starts with a double underscore.\n */\nprivate bool isReservedName(const(char)[] str)\n{\n    immutable string[] table =\n    [\n        \"__ctor\",\n        \"__dtor\",\n        \"__postblit\",\n        \"__invariant\",\n        \"__unitTest\",\n        \"__require\",\n        \"__ensure\",\n        \"__dollar\",\n        \"__ctfe\",\n        \"__withSym\",\n        \"__result\",\n        \"__returnLabel\",\n        \"__vptr\",\n        \"__monitor\",\n        \"__gate\",\n        \"__xopEquals\",\n        \"__xopCmp\",\n        \"__LINE__\",\n        \"__FILE__\",\n        \"__MODULE__\",\n        \"__FUNCTION__\",\n        \"__PRETTY_FUNCTION__\",\n        \"__DATE__\",\n        \"__TIME__\",\n        \"__TIMESTAMP__\",\n        \"__VENDOR__\",\n        \"__VERSION__\",\n        \"__EOF__\",\n        \"__CXXLIB__\",\n        \"__LOCAL_SIZE\",\n        \"___tls_get_addr\",\n        \"__entrypoint\",\n    ];\n    foreach (s; table)\n    {\n        if (str == s)\n            return true;\n    }\n    return false;\n}\n\n/**************************************************\n * Highlight text section.\n */\nprivate void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t offset)\n{\n    Dsymbol s = a.dim ? (*a)[0] : null; // test\n    //printf(\"highlightText()\\n\");\n    int leadingBlank = 1;\n    int inCode = 0;\n    int inBacktick = 0;\n    //int inComment = 0;                  // in <!-- ... --> comment\n    int inMacro = 0;\n    size_t iCodeStart = 0; // start of code section\n    size_t codeIndent = 0;\n    size_t iLineStart = offset;\n    for (size_t i = offset; i < buf.offset; i++)\n    {\n        char c = buf.data[i];\n    Lcont:\n        switch (c)\n        {\n        case ' ':\n        case '\\t':\n            break;\n        case '\\n':\n            if (inBacktick)\n            {\n                // `inline code` is only valid if contained on a single line\n                // otherwise, the backticks should be output literally.\n                //\n                // This lets things like `output from the linker' display\n                // unmolested while keeping the feature consistent with GitHub.\n                inBacktick = false;\n                inCode = false; // the backtick also assumes we're in code\n                // Nothing else is necessary since the DDOC_BACKQUOTED macro is\n                // inserted lazily at the close quote, meaning the rest of the\n                // text is already OK.\n            }\n            if (!inCode && i == iLineStart && i + 1 < buf.offset) // if \"\\n\\n\"\n            {\n                i = buf.insert(i, \"$(DDOC_BLANKLINE)\");\n            }\n            leadingBlank = 1;\n            iLineStart = i + 1;\n            break;\n        case '<':\n            {\n                leadingBlank = 0;\n                if (inCode)\n                    break;\n                const slice = buf.peekSlice();\n                auto p = &slice[i];\n                const se = sc._module.escapetable.escapeChar('<');\n                if (se == \"&lt;\")\n                {\n                    // Generating HTML\n                    // Skip over comments\n                    if (p[1] == '!' && p[2] == '-' && p[3] == '-')\n                    {\n                        size_t j = i + 4;\n                        p += 4;\n                        while (1)\n                        {\n                            if (j == slice.length)\n                                goto L1;\n                            if (p[0] == '-' && p[1] == '-' && p[2] == '>')\n                            {\n                                i = j + 2; // place on closing '>'\n                                break;\n                            }\n                            j++;\n                            p++;\n                        }\n                        break;\n                    }\n                    // Skip over HTML tag\n                    if (isalpha(p[1]) || (p[1] == '/' && isalpha(p[2])))\n                    {\n                        size_t j = i + 2;\n                        p += 2;\n                        while (1)\n                        {\n                            if (j == slice.length)\n                                break;\n                            if (p[0] == '>')\n                            {\n                                i = j; // place on closing '>'\n                                break;\n                            }\n                            j++;\n                            p++;\n                        }\n                        break;\n                    }\n                }\n            L1:\n                // Replace '<' with '&lt;' character entity\n                if (se.length)\n                {\n                    buf.remove(i, 1);\n                    i = buf.insert(i, se);\n                    i--; // point to ';'\n                }\n                break;\n            }\n        case '>':\n            {\n                leadingBlank = 0;\n                if (inCode)\n                    break;\n                // Replace '>' with '&gt;' character entity\n                const se = sc._module.escapetable.escapeChar('>');\n                if (se.length)\n                {\n                    buf.remove(i, 1);\n                    i = buf.insert(i, se);\n                    i--; // point to ';'\n                }\n                break;\n            }\n        case '&':\n            {\n                leadingBlank = 0;\n                if (inCode)\n                    break;\n                char* p = cast(char*)&buf.data[i];\n                if (p[1] == '#' || isalpha(p[1]))\n                    break;\n                // already a character entity\n                // Replace '&' with '&amp;' character entity\n                const se = sc._module.escapetable.escapeChar('&');\n                if (se)\n                {\n                    buf.remove(i, 1);\n                    i = buf.insert(i, se);\n                    i--; // point to ';'\n                }\n                break;\n            }\n        case '`':\n            {\n                if (inBacktick)\n                {\n                    inBacktick = 0;\n                    inCode = 0;\n                    OutBuffer codebuf;\n                    codebuf.write(buf.peekSlice().ptr + iCodeStart + 1, i - (iCodeStart + 1));\n                    // escape the contents, but do not perform highlighting except for DDOC_PSYMBOL\n                    highlightCode(sc, a, &codebuf, 0);\n                    escapeStrayParenthesis(s ? s.loc : Loc.initial, &codebuf, 0);\n                    buf.remove(iCodeStart, i - iCodeStart + 1); // also trimming off the current `\n                    immutable pre = \"$(DDOC_BACKQUOTED \";\n                    i = buf.insert(iCodeStart, pre);\n                    i = buf.insert(i, codebuf.peekSlice());\n                    i = buf.insert(i, \")\");\n                    i--; // point to the ending ) so when the for loop does i++, it will see the next character\n                    break;\n                }\n                if (inCode)\n                    break;\n                inCode = 1;\n                inBacktick = 1;\n                codeIndent = 0; // inline code is not indented\n                // All we do here is set the code flags and record\n                // the location. The macro will be inserted lazily\n                // so we can easily cancel the inBacktick if we come\n                // across a newline character.\n                iCodeStart = i;\n                break;\n            }\n        case '-':\n            /* A line beginning with --- delimits a code section.\n             * inCode tells us if it is start or end of a code section.\n             */\n            if (leadingBlank)\n            {\n                size_t istart = i;\n                size_t eollen = 0;\n                leadingBlank = 0;\n                while (1)\n                {\n                    ++i;\n                    if (i >= buf.offset)\n                        break;\n                    c = buf.data[i];\n                    if (c == '\\n')\n                    {\n                        eollen = 1;\n                        break;\n                    }\n                    if (c == '\\r')\n                    {\n                        eollen = 1;\n                        if (i + 1 >= buf.offset)\n                            break;\n                        if (buf.data[i + 1] == '\\n')\n                        {\n                            eollen = 2;\n                            break;\n                        }\n                    }\n                    // BUG: handle UTF PS and LS too\n                    if (c != '-')\n                        goto Lcont;\n                }\n                if (i - istart < 3)\n                    goto Lcont;\n                // We have the start/end of a code section\n                // Remove the entire --- line, including blanks and \\n\n                buf.remove(iLineStart, i - iLineStart + eollen);\n                i = iLineStart;\n                if (inCode && (i <= iCodeStart))\n                {\n                    // Empty code section, just remove it completely.\n                    inCode = 0;\n                    break;\n                }\n                if (inCode)\n                {\n                    inCode = 0;\n                    // The code section is from iCodeStart to i\n                    OutBuffer codebuf;\n                    codebuf.write(buf.data + iCodeStart, i - iCodeStart);\n                    codebuf.writeByte(0);\n                    // Remove leading indentations from all lines\n                    bool lineStart = true;\n                    char* endp = cast(char*)codebuf.data + codebuf.offset;\n                    for (char* p = cast(char*)codebuf.data; p < endp;)\n                    {\n                        if (lineStart)\n                        {\n                            size_t j = codeIndent;\n                            char* q = p;\n                            while (j-- > 0 && q < endp && isIndentWS(q))\n                                ++q;\n                            codebuf.remove(p - cast(char*)codebuf.data, q - p);\n                            assert(cast(char*)codebuf.data <= p);\n                            assert(p < cast(char*)codebuf.data + codebuf.offset);\n                            lineStart = false;\n                            endp = cast(char*)codebuf.data + codebuf.offset; // update\n                            continue;\n                        }\n                        if (*p == '\\n')\n                            lineStart = true;\n                        ++p;\n                    }\n                    highlightCode2(sc, a, &codebuf, 0);\n                    escapeStrayParenthesis(s ? s.loc : Loc.initial, &codebuf, 0);\n                    buf.remove(iCodeStart, i - iCodeStart);\n                    i = buf.insert(iCodeStart, codebuf.peekSlice());\n                    i = buf.insert(i, \")\\n\");\n                    i -= 2; // in next loop, c should be '\\n'\n                }\n                else\n                {\n                    __gshared const(char)* d_code = \"$(D_CODE \";\n                    inCode = 1;\n                    codeIndent = istart - iLineStart; // save indent count\n                    i = buf.insert(i, d_code, strlen(d_code));\n                    iCodeStart = i;\n                    i--; // place i on >\n                    leadingBlank = true;\n                }\n            }\n            break;\n\n        case '$':\n        {\n            /* Look for the start of a macro, '$(Identifier'\n             */\n            leadingBlank = 0;\n            if (inCode || inBacktick)\n                break;\n            const slice = buf.peekSlice();\n            auto p = &slice[i];\n            if (p[1] == '(' && isIdStart(&p[2]))\n                ++inMacro;\n            break;\n        }\n\n        case ')':\n        {   /* End of macro\n             */\n            leadingBlank = 0;\n            if (inCode || inBacktick)\n                break;\n            if (inMacro)\n                --inMacro;\n            break;\n        }\n\n        default:\n            leadingBlank = 0;\n            if (sc._module.isDocFile || inCode)\n                break;\n            const start = cast(char*)buf.data + i;\n            if (isIdStart(start))\n            {\n                size_t j = skippastident(buf, i);\n                if (i < j)\n                {\n                    size_t k = skippastURL(buf, i);\n                    if (i < k)\n                    {\n                        /* The URL is buf[i..k]\n                         */\n                        if (inMacro)\n                            /* Leave alone if already in a macro\n                             */\n                            i = k - 1;\n                        else\n                        {\n                            /* Replace URL with '$(DDOC_LINK_AUTODETECT URL)'\n                             */\n                            i = buf.bracket(i, \"$(DDOC_LINK_AUTODETECT \", k, \")\") - 1;\n                        }\n                        break;\n                    }\n                }\n                else\n                    break;\n                size_t len = j - i;\n                // leading '_' means no highlight unless it's a reserved symbol name\n                if (c == '_' && (i == 0 || !isdigit(*(start - 1))) && (i == buf.offset - 1 || !isReservedName(start[0 .. len])))\n                {\n                    buf.remove(i, 1);\n                    i = buf.bracket(i, \"$(DDOC_AUTO_PSYMBOL_SUPPRESS \", j - 1, \")\") - 1;\n                    break;\n                }\n                if (isIdentifier(a, start, len))\n                {\n                    i = buf.bracket(i, \"$(DDOC_AUTO_PSYMBOL \", j, \")\") - 1;\n                    break;\n                }\n                if (isKeyword(start, len))\n                {\n                    i = buf.bracket(i, \"$(DDOC_AUTO_KEYWORD \", j, \")\") - 1;\n                    break;\n                }\n                if (isFunctionParameter(a, start, len))\n                {\n                    //printf(\"highlighting arg '%s', i = %d, j = %d\\n\", arg.ident.toChars(), i, j);\n                    i = buf.bracket(i, \"$(DDOC_AUTO_PARAM \", j, \")\") - 1;\n                    break;\n                }\n                i = j - 1;\n            }\n            break;\n        }\n    }\n    if (inCode)\n        error(s ? s.loc : Loc.initial, \"unmatched `---` in DDoc comment\");\n}\n\n/**************************************************\n * Highlight code for DDOC section.\n */\nprivate void highlightCode(Scope* sc, Dsymbol s, OutBuffer* buf, size_t offset)\n{\n    //printf(\"highlightCode(s = %s '%s')\\n\", s.kind(), s.toChars());\n    OutBuffer ancbuf;\n    emitAnchor(&ancbuf, s, sc);\n    buf.insert(offset, ancbuf.peekSlice());\n    offset += ancbuf.offset;\n    Dsymbols a;\n    a.push(s);\n    highlightCode(sc, &a, buf, offset);\n}\n\n/****************************************************\n */\nprivate void highlightCode(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t offset)\n{\n    //printf(\"highlightCode(a = '%s')\\n\", a.toChars());\n    bool resolvedTemplateParameters = false;\n\n    for (size_t i = offset; i < buf.offset; i++)\n    {\n        char c = buf.data[i];\n        const se = sc._module.escapetable.escapeChar(c);\n        if (se.length)\n        {\n            buf.remove(i, 1);\n            i = buf.insert(i, se);\n            i--; // point to ';'\n            continue;\n        }\n        char* start = cast(char*)buf.data + i;\n        if (isIdStart(start))\n        {\n            size_t j = skippastident(buf, i);\n            if (i < j)\n            {\n                size_t len = j - i;\n                if (isIdentifier(a, start, len))\n                {\n                    i = buf.bracket(i, \"$(DDOC_PSYMBOL \", j, \")\") - 1;\n                    continue;\n                }\n                if (isFunctionParameter(a, start, len))\n                {\n                    //printf(\"highlighting arg '%s', i = %d, j = %d\\n\", arg.ident.toChars(), i, j);\n                    i = buf.bracket(i, \"$(DDOC_PARAM \", j, \")\") - 1;\n                    continue;\n                }\n                i = j - 1;\n            }\n        }\n        else if (!resolvedTemplateParameters)\n        {\n            size_t previ = i;\n\n            // hunt for template declarations:\n            foreach (symi; 0 .. a.dim)\n            {\n                FuncDeclaration fd = (*a)[symi].isFuncDeclaration();\n\n                if (!fd || !fd.parent || !fd.parent.isTemplateDeclaration())\n                {\n                    continue;\n                }\n\n                TemplateDeclaration td = fd.parent.isTemplateDeclaration();\n\n                // build the template parameters\n                Array!(size_t) paramLens;\n                paramLens.reserve(td.parameters.dim);\n\n                OutBuffer parametersBuf;\n                HdrGenState hgs;\n\n                parametersBuf.writeByte('(');\n\n                foreach (parami; 0 .. td.parameters.dim)\n                {\n                    TemplateParameter tp = (*td.parameters)[parami];\n\n                    if (parami)\n                        parametersBuf.writestring(\", \");\n\n                    size_t lastOffset = parametersBuf.offset;\n\n                    .toCBuffer(tp, &parametersBuf, &hgs);\n\n                    paramLens[parami] = parametersBuf.offset - lastOffset;\n                }\n                parametersBuf.writeByte(')');\n\n                const templateParams = parametersBuf.peekSlice();\n\n                //printf(\"templateDecl: %s\\ntemplateParams: %s\\nstart: %s\\n\", td.toChars(), templateParams, start);\n                if (start[0 .. templateParams.length] == templateParams)\n                {\n                    immutable templateParamListMacro = \"$(DDOC_TEMPLATE_PARAM_LIST \";\n                    buf.bracket(i, templateParamListMacro.ptr, i + templateParams.length, \")\");\n\n                    // We have the parameter list. While we're here we might\n                    // as well wrap the parameters themselves as well\n\n                    // + 1 here to take into account the opening paren of the\n                    // template param list\n                    i += templateParamListMacro.length + 1;\n\n                    foreach (const len; paramLens)\n                    {\n                        i = buf.bracket(i, \"$(DDOC_TEMPLATE_PARAM \", i + len, \")\");\n                        // increment two here for space + comma\n                        i += 2;\n                    }\n\n                    resolvedTemplateParameters = true;\n                    // reset i to be positioned back before we found the template\n                    // param list this assures that anything within the template\n                    // param list that needs to be escaped or otherwise altered\n                    // has an opportunity for that to happen outside of this context\n                    i = previ;\n\n                    continue;\n                }\n            }\n        }\n    }\n}\n\n/****************************************\n */\nprivate void highlightCode3(Scope* sc, OutBuffer* buf, const(char)* p, const(char)* pend)\n{\n    for (; p < pend; p++)\n    {\n        const se = sc._module.escapetable.escapeChar(*p);\n        if (se.length)\n            buf.writestring(se);\n        else\n            buf.writeByte(*p);\n    }\n}\n\n/**************************************************\n * Highlight code for CODE section.\n */\nprivate void highlightCode2(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t offset)\n{\n    uint errorsave = global.errors;\n    scope Lexer lex = new Lexer(null, cast(char*)buf.data, 0, buf.offset - 1, 0, 1);\n    OutBuffer res;\n    const(char)* lastp = cast(char*)buf.data;\n    //printf(\"highlightCode2('%.*s')\\n\", buf.offset - 1, buf.data);\n    res.reserve(buf.offset);\n    while (1)\n    {\n        Token tok;\n        lex.scan(&tok);\n        highlightCode3(sc, &res, lastp, tok.ptr);\n        const(char)* highlight = null;\n        switch (tok.value)\n        {\n        case TOK.identifier:\n            {\n                if (!sc)\n                    break;\n                size_t len = lex.p - tok.ptr;\n                if (isIdentifier(a, tok.ptr, len))\n                {\n                    highlight = \"$(D_PSYMBOL \";\n                    break;\n                }\n                if (isFunctionParameter(a, tok.ptr, len))\n                {\n                    //printf(\"highlighting arg '%s', i = %d, j = %d\\n\", arg.ident.toChars(), i, j);\n                    highlight = \"$(D_PARAM \";\n                    break;\n                }\n                break;\n            }\n        case TOK.comment:\n            highlight = \"$(D_COMMENT \";\n            break;\n        case TOK.string_:\n            highlight = \"$(D_STRING \";\n            break;\n        default:\n            if (tok.isKeyword())\n                highlight = \"$(D_KEYWORD \";\n            break;\n        }\n        if (highlight)\n        {\n            res.writestring(highlight);\n            size_t o = res.offset;\n            highlightCode3(sc, &res, tok.ptr, lex.p);\n            if (tok.value == TOK.comment || tok.value == TOK.string_)\n                /* https://issues.dlang.org/show_bug.cgi?id=7656\n                 * https://issues.dlang.org/show_bug.cgi?id=7715\n                 * https://issues.dlang.org/show_bug.cgi?id=10519\n                 */\n                escapeDdocString(&res, o);\n            res.writeByte(')');\n        }\n        else\n            highlightCode3(sc, &res, tok.ptr, lex.p);\n        if (tok.value == TOK.endOfFile)\n            break;\n        lastp = lex.p;\n    }\n    buf.setsize(offset);\n    buf.write(&res);\n    global.errors = errorsave;\n}\n\n/****************************************\n * Determine if p points to the start of a \"...\" parameter identifier.\n */\nprivate bool isCVariadicArg(const(char)[] p)\n{\n    return p.length >= 3 && p[0 .. 3] == \"...\";\n}\n\n/****************************************\n * Determine if p points to the start of an identifier.\n */\nbool isIdStart(const(char)* p)\n{\n    dchar c = *p;\n    if (isalpha(c) || c == '_')\n        return true;\n    if (c >= 0x80)\n    {\n        size_t i = 0;\n        if (utf_decodeChar(p, 4, i, c))\n            return false; // ignore errors\n        if (isUniAlpha(c))\n            return true;\n    }\n    return false;\n}\n\n/****************************************\n * Determine if p points to the rest of an identifier.\n */\nbool isIdTail(const(char)* p)\n{\n    dchar c = *p;\n    if (isalnum(c) || c == '_')\n        return true;\n    if (c >= 0x80)\n    {\n        size_t i = 0;\n        if (utf_decodeChar(p, 4, i, c))\n            return false; // ignore errors\n        if (isUniAlpha(c))\n            return true;\n    }\n    return false;\n}\n\n/****************************************\n * Determine if p points to the indentation space.\n */\nprivate bool isIndentWS(const(char)* p)\n{\n    return (*p == ' ') || (*p == '\\t');\n}\n\n/*****************************************\n * Return number of bytes in UTF character.\n */\nint utfStride(const(char)* p)\n{\n    dchar c = *p;\n    if (c < 0x80)\n        return 1;\n    size_t i = 0;\n    utf_decodeChar(p, 4, i, c); // ignore errors, but still consume input\n    return cast(int)i;\n}\n\nprivate inout(char)* stripLeadingNewlines(inout(char)* s)\n{\n    while (s && *s == '\\n' || *s == '\\r')\n        s++;\n\n    return s;\n}\n"
  },
  {
    "path": "gcc/d/dmd/doc.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/doc.h\n */\n\n#pragma once\n\nclass Module;\n\nvoid gendocfile(Module *m);\n"
  },
  {
    "path": "gcc/d/dmd/dscope.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dscope.d, _dscope.d)\n * Documentation:  https://dlang.org/phobos/dmd_dscope.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dscope.d\n */\n\nmodule dmd.dscope;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.aggregate;\nimport dmd.attrib;\nimport dmd.ctorflow;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dmodule;\nimport dmd.doc;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.root.outbuffer;\nimport dmd.root.rmem;\nimport dmd.root.speller;\nimport dmd.statement;\nimport dmd.tokens;\n\n//version=LOGSEARCH;\n\n\n// Flags that would not be inherited beyond scope nesting\nenum SCOPE\n{\n    ctor          = 0x0001,   /// constructor type\n    noaccesscheck = 0x0002,   /// don't do access checks\n    condition     = 0x0004,   /// inside static if/assert condition\n    debug_        = 0x0008,   /// inside debug conditional\n    constraint    = 0x0010,   /// inside template constraint\n    invariant_    = 0x0020,   /// inside invariant code\n    require       = 0x0040,   /// inside in contract code\n    ensure        = 0x0060,   /// inside out contract code\n    contract      = 0x0060,   /// [mask] we're inside contract code\n    ctfe          = 0x0080,   /// inside a ctfe-only expression\n    compile       = 0x0100,   /// inside __traits(compile)\n    ignoresymbolvisibility    = 0x0200,   /// ignore symbol visibility\n                                          /// https://issues.dlang.org/show_bug.cgi?id=15907\n    onlysafeaccess = 0x0400,  /// unsafe access is not allowed for @safe code\n    free          = 0x8000,   /// is on free list\n\n    fullinst      = 0x10000,  /// fully instantiate templates\n}\n\n// Flags that are carried along with a scope push()\nenum SCOPEpush = SCOPE.contract | SCOPE.debug_ | SCOPE.ctfe | SCOPE.compile | SCOPE.constraint |\n                 SCOPE.noaccesscheck | SCOPE.onlysafeaccess | SCOPE.ignoresymbolvisibility;\n\nstruct Scope\n{\n    Scope* enclosing;               /// enclosing Scope\n\n    Module _module;                 /// Root module\n    ScopeDsymbol scopesym;          /// current symbol\n    FuncDeclaration func;           /// function we are in\n    Dsymbol parent;                 /// parent to use\n    LabelStatement slabel;          /// enclosing labelled statement\n    SwitchStatement sw;             /// enclosing switch statement\n    TryFinallyStatement tf;         /// enclosing try finally statement\n    OnScopeStatement os;            /// enclosing scope(xxx) statement\n    Statement sbreak;               /// enclosing statement that supports \"break\"\n    Statement scontinue;            /// enclosing statement that supports \"continue\"\n    ForeachStatement fes;           /// if nested function for ForeachStatement, this is it\n    Scope* callsc;                  /// used for __FUNCTION__, __PRETTY_FUNCTION__ and __MODULE__\n    bool inunion;                   /// true if processing members of a union\n    bool nofree;                    /// true if shouldn't free it\n    bool inLoop;                    /// true if inside a loop (where constructor calls aren't allowed)\n    int intypeof;                   /// in typeof(exp)\n    VarDeclaration lastVar;         /// Previous symbol used to prevent goto-skips-init\n\n    /* If  minst && !tinst, it's in definitely non-speculative scope (eg. module member scope).\n     * If !minst && !tinst, it's in definitely speculative scope (eg. template constraint).\n     * If  minst &&  tinst, it's in instantiated code scope without speculation.\n     * If !minst &&  tinst, it's in instantiated code scope with speculation.\n     */\n    Module minst;                   /// root module where the instantiated templates should belong to\n    TemplateInstance tinst;         /// enclosing template instance\n\n    CtorFlow ctorflow;              /// flow analysis for constructors\n\n    /// alignment for struct members\n    AlignDeclaration aligndecl;\n\n    /// linkage for external functions\n    LINK linkage = LINK.d;\n\n    /// mangle type\n    CPPMANGLE cppmangle = CPPMANGLE.def;\n\n    /// inlining strategy for functions\n    PINLINE inlining = PINLINE.default_;\n\n    /// protection for class members\n    Prot protection = Prot(Prot.Kind.public_);\n    int explicitProtection;         /// set if in an explicit protection attribute\n\n    StorageClass stc;               /// storage class\n\n    DeprecatedDeclaration depdecl;  /// customized deprecation message\n\n    uint flags;\n\n    // user defined attributes\n    UserAttributeDeclaration userAttribDecl;\n\n    DocComment* lastdc;        /// documentation comment for last symbol at this scope\n    uint[void*] anchorCounts;  /// lookup duplicate anchor name count\n    Identifier prevAnchor;     /// qualified symbol name of last doc anchor\n\n    extern (D) __gshared Scope* freelist;\n\n    extern (D) static Scope* alloc()\n    {\n        if (freelist)\n        {\n            Scope* s = freelist;\n            freelist = s.enclosing;\n            //printf(\"freelist %p\\n\", s);\n            assert(s.flags & SCOPE.free);\n            s.flags &= ~SCOPE.free;\n            return s;\n        }\n        return new Scope();\n    }\n\n    extern (D) static Scope* createGlobal(Module _module)\n    {\n        Scope* sc = Scope.alloc();\n        *sc = Scope.init;\n        sc._module = _module;\n        sc.minst = _module;\n        sc.scopesym = new ScopeDsymbol();\n        sc.scopesym.symtab = new DsymbolTable();\n        // Add top level package as member of this global scope\n        Dsymbol m = _module;\n        while (m.parent)\n            m = m.parent;\n        m.addMember(null, sc.scopesym);\n        m.parent = null; // got changed by addMember()\n        // Create the module scope underneath the global scope\n        sc = sc.push(_module);\n        sc.parent = _module;\n        return sc;\n    }\n\n    extern (C++) Scope* copy()\n    {\n        Scope* sc = Scope.alloc();\n        *sc = this;\n        /* https://issues.dlang.org/show_bug.cgi?id=11777\n         * The copied scope should not inherit fieldinit.\n         */\n        sc.ctorflow.fieldinit = null;\n        return sc;\n    }\n\n    extern (C++) Scope* push()\n    {\n        Scope* s = copy();\n        //printf(\"Scope::push(this = %p) new = %p\\n\", this, s);\n        assert(!(flags & SCOPE.free));\n        s.scopesym = null;\n        s.enclosing = &this;\n        debug\n        {\n            if (enclosing)\n                assert(!(enclosing.flags & SCOPE.free));\n            if (s == enclosing)\n            {\n                printf(\"this = %p, enclosing = %p, enclosing.enclosing = %p\\n\", s, &this, enclosing);\n            }\n            assert(s != enclosing);\n        }\n        s.slabel = null;\n        s.nofree = false;\n        s.ctorflow.fieldinit = ctorflow.fieldinit.arraydup;\n        s.flags = (flags & SCOPEpush);\n        s.lastdc = null;\n        assert(&this != s);\n        return s;\n    }\n\n    extern (C++) Scope* push(ScopeDsymbol ss)\n    {\n        //printf(\"Scope::push(%s)\\n\", ss.toChars());\n        Scope* s = push();\n        s.scopesym = ss;\n        return s;\n    }\n\n    extern (C++) Scope* pop()\n    {\n        //printf(\"Scope::pop() %p nofree = %d\\n\", this, nofree);\n        if (enclosing)\n            enclosing.ctorflow.OR(ctorflow);\n        ctorflow.freeFieldinit();\n\n        Scope* enc = enclosing;\n        if (!nofree)\n        {\n            enclosing = freelist;\n            freelist = &this;\n            flags |= SCOPE.free;\n        }\n        return enc;\n    }\n\n    /*************************\n     * Similar to pop(), but the results in `this` are not folded\n     * into `enclosing`.\n     */\n    extern (D) void detach()\n    {\n        ctorflow.freeFieldinit();\n        enclosing = null;\n        pop();\n    }\n\n    extern (C++) Scope* startCTFE()\n    {\n        Scope* sc = this.push();\n        sc.flags = this.flags | SCOPE.ctfe;\n        version (none)\n        {\n            /* TODO: Currently this is not possible, because we need to\n             * unspeculative some types and symbols if they are necessary for the\n             * final executable. Consider:\n             *\n             * struct S(T) {\n             *   string toString() const { return \"instantiated\"; }\n             * }\n             * enum x = S!int();\n             * void main() {\n             *   // To call x.toString in runtime, compiler should unspeculative S!int.\n             *   assert(x.toString() == \"instantiated\");\n             * }\n             */\n            // If a template is instantiated from CT evaluated expression,\n            // compiler can elide its code generation.\n            sc.tinst = null;\n            sc.minst = null;\n        }\n        return sc;\n    }\n\n    extern (C++) Scope* endCTFE()\n    {\n        assert(flags & SCOPE.ctfe);\n        return pop();\n    }\n\n\n    /*******************************\n     * Merge results of `ctorflow` into `this`.\n     * Params:\n     *   loc = for error messages\n     *   ctorflow = flow results to merge in\n     */\n    extern (D) void merge(const ref Loc loc, const ref CtorFlow ctorflow)\n    {\n        if (!mergeCallSuper(this.ctorflow.callSuper, ctorflow.callSuper))\n            error(loc, \"one path skips constructor\");\n\n        const fies = ctorflow.fieldinit;\n        if (this.ctorflow.fieldinit.length && fies.length)\n        {\n            FuncDeclaration f = func;\n            if (fes)\n                f = fes.func;\n            auto ad = f.isMember2();\n            assert(ad);\n            foreach (i, v; ad.fields)\n            {\n                bool mustInit = (v.storage_class & STC.nodefaultctor || v.type.needsNested());\n                auto fieldInit = &this.ctorflow.fieldinit[i];\n                const fiesCurrent = fies[i];\n                if (fieldInit.loc == Loc.init)\n                    fieldInit.loc = fiesCurrent.loc;\n                if (!mergeFieldInit(this.ctorflow.fieldinit[i].csx, fiesCurrent.csx) && mustInit)\n                {\n                    error(loc, \"one path skips field `%s`\", v.toChars());\n                }\n            }\n        }\n    }\n\n    extern (C++) Module instantiatingModule()\n    {\n        // TODO: in speculative context, returning 'module' is correct?\n        return minst ? minst : _module;\n    }\n\n    /************************************\n     * Perform unqualified name lookup by following the chain of scopes up\n     * until found.\n     *\n     * Params:\n     *  loc = location to use for error messages\n     *  ident = name to look up\n     *  pscopesym = if supplied and name is found, set to scope that ident was found in\n     *  flags = modify search based on flags\n     *\n     * Returns:\n     *  symbol if found, null if not\n     */\n    extern (C++) Dsymbol search(const ref Loc loc, Identifier ident, Dsymbol* pscopesym, int flags = IgnoreNone)\n    {\n        version (LOGSEARCH)\n        {\n            printf(\"Scope.search(%p, '%s' flags=x%x)\\n\", &this, ident.toChars(), flags);\n            // Print scope chain\n            for (Scope* sc = &this; sc; sc = sc.enclosing)\n            {\n                if (!sc.scopesym)\n                    continue;\n                printf(\"\\tscope %s\\n\", sc.scopesym.toChars());\n            }\n\n            static void printMsg(string txt, Dsymbol s)\n            {\n                printf(\"%.*s  %s.%s, kind = '%s'\\n\", cast(int)txt.length, txt.ptr,\n                    s.parent ? s.parent.toChars() : \"\", s.toChars(), s.kind());\n            }\n        }\n\n        // This function is called only for unqualified lookup\n        assert(!(flags & (SearchLocalsOnly | SearchImportsOnly)));\n\n        /* If ident is \"start at module scope\", only look at module scope\n         */\n        if (ident == Id.empty)\n        {\n            // Look for module scope\n            for (Scope* sc = &this; sc; sc = sc.enclosing)\n            {\n                assert(sc != sc.enclosing);\n                if (!sc.scopesym)\n                    continue;\n                if (Dsymbol s = sc.scopesym.isModule())\n                {\n                    //printMsg(\"\\tfound\", s);\n                    if (pscopesym)\n                        *pscopesym = sc.scopesym;\n                    return s;\n                }\n            }\n            return null;\n        }\n\n        Dsymbol searchScopes(int flags)\n        {\n            for (Scope* sc = &this; sc; sc = sc.enclosing)\n            {\n                assert(sc != sc.enclosing);\n                if (!sc.scopesym)\n                    continue;\n                //printf(\"\\tlooking in scopesym '%s', kind = '%s', flags = x%x\\n\", sc.scopesym.toChars(), sc.scopesym.kind(), flags);\n\n                if (sc.scopesym.isModule())\n                    flags |= SearchUnqualifiedModule;        // tell Module.search() that SearchLocalsOnly is to be obeyed\n\n                if (Dsymbol s = sc.scopesym.search(loc, ident, flags))\n                {\n                    if (!(flags & (SearchImportsOnly | IgnoreErrors)) &&\n                        ident == Id.length && sc.scopesym.isArrayScopeSymbol() &&\n                        sc.enclosing && sc.enclosing.search(loc, ident, null, flags))\n                    {\n                        warning(s.loc, \"array `length` hides other `length` name in outer scope\");\n                    }\n                    //printMsg(\"\\tfound local\", s);\n                    if (pscopesym)\n                        *pscopesym = sc.scopesym;\n                    return s;\n                }\n                // Stop when we hit a module, but keep going if that is not just under the global scope\n                if (sc.scopesym.isModule() && !(sc.enclosing && !sc.enclosing.enclosing))\n                    break;\n            }\n            return null;\n        }\n\n        if (this.flags & SCOPE.ignoresymbolvisibility)\n            flags |= IgnoreSymbolVisibility;\n\n        Dsymbol sold = void;\n        if (global.params.bug10378 || global.params.check10378)\n        {\n            sold = searchScopes(flags | IgnoreSymbolVisibility);\n            if (!global.params.check10378)\n                return sold;\n\n            if (ident == Id.dollar) // https://issues.dlang.org/show_bug.cgi?id=15825\n                return sold;\n\n            // Search both ways\n        }\n\n        // First look in local scopes\n        Dsymbol s = searchScopes(flags | SearchLocalsOnly);\n        version (LOGSEARCH) if (s) printMsg(\"-Scope.search() found local\", s);\n        if (!s)\n        {\n            // Second look in imported modules\n            s = searchScopes(flags | SearchImportsOnly);\n            version (LOGSEARCH) if (s) printMsg(\"-Scope.search() found import\", s);\n\n            /** Still find private symbols, so that symbols that weren't access\n             * checked by the compiler remain usable.  Once the deprecation is over,\n             * this should be moved to search_correct instead.\n             */\n            if (!s && !(flags & IgnoreSymbolVisibility))\n            {\n                s = searchScopes(flags | SearchLocalsOnly | IgnoreSymbolVisibility);\n                if (!s)\n                    s = searchScopes(flags | SearchImportsOnly | IgnoreSymbolVisibility);\n\n                if (s && !(flags & IgnoreErrors))\n                    .deprecation(loc, \"`%s` is not visible from module `%s`\", s.toPrettyChars(), _module.toChars());\n                version (LOGSEARCH) if (s) printMsg(\"-Scope.search() found imported private symbol\", s);\n            }\n        }\n        if (global.params.check10378)\n        {\n            alias snew = s;\n            if (sold !is snew)\n                deprecation10378(loc, sold, snew);\n            if (global.params.bug10378)\n                s = sold;\n        }\n        return s;\n    }\n\n    /* A helper function to show deprecation message for new name lookup rule.\n     */\n    extern (D) static void deprecation10378(Loc loc, Dsymbol sold, Dsymbol snew)\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=15857\n        //\n        // The overloadset found via the new lookup rules is either\n        // equal or a subset of the overloadset found via the old\n        // lookup rules, so it suffices to compare the dimension to\n        // check for equality.\n        OverloadSet osold, osnew;\n        if (sold && (osold = sold.isOverloadSet()) !is null &&\n            snew && (osnew = snew.isOverloadSet()) !is null &&\n            osold.a.dim == osnew.a.dim)\n            return;\n\n        OutBuffer buf;\n        buf.writestring(\"local import search method found \");\n        if (osold)\n            buf.printf(\"%s `%s` (%d overloads)\", sold.kind(), sold.toPrettyChars(), cast(int) osold.a.dim);\n        else if (sold)\n            buf.printf(\"%s `%s`\", sold.kind(), sold.toPrettyChars());\n        else\n            buf.writestring(\"nothing\");\n        buf.writestring(\" instead of \");\n        if (osnew)\n            buf.printf(\"%s `%s` (%d overloads)\", snew.kind(), snew.toPrettyChars(), cast(int) osnew.a.dim);\n        else if (snew)\n            buf.printf(\"%s `%s`\", snew.kind(), snew.toPrettyChars());\n        else\n            buf.writestring(\"nothing\");\n\n        deprecation(loc, buf.peekString());\n    }\n\n    extern (C++) Dsymbol search_correct(Identifier ident)\n    {\n        if (global.gag)\n            return null; // don't do it for speculative compiles; too time consuming\n\n        /************************************************\n         * Given the failed search attempt, try to find\n         * one with a close spelling.\n         */\n        extern (D) void* scope_search_fp(const(char)* seed, ref int cost)\n        {\n            //printf(\"scope_search_fp('%s')\\n\", seed);\n            /* If not in the lexer's string table, it certainly isn't in the symbol table.\n             * Doing this first is a lot faster.\n             */\n            size_t len = strlen(seed);\n            if (!len)\n                return null;\n            Identifier id = Identifier.lookup(seed, len);\n            if (!id)\n                return null;\n            Scope* sc = &this;\n            Module.clearCache();\n            Dsymbol scopesym = null;\n            Dsymbol s = sc.search(Loc.initial, id, &scopesym, IgnoreErrors);\n            if (s)\n            {\n                for (cost = 0; sc; sc = sc.enclosing, ++cost)\n                    if (sc.scopesym == scopesym)\n                        break;\n                if (scopesym != s.parent)\n                {\n                    ++cost; // got to the symbol through an import\n                    if (s.prot().kind == Prot.Kind.private_)\n                        return null;\n                }\n            }\n            return cast(void*)s;\n        }\n\n        return cast(Dsymbol)speller(ident.toChars(), &scope_search_fp, idchars);\n    }\n\n    /************************************\n     * Maybe `ident` was a C or C++ name. Check for that,\n     * and suggest the D equivalent.\n     * Params:\n     *  ident = unknown identifier\n     * Returns:\n     *  D identifier string if found, null if not\n     */\n    extern (D) static const(char)* search_correct_C(Identifier ident)\n    {\n        TOK tok;\n        if (ident == Id.NULL)\n            tok = TOK.null_;\n        else if (ident == Id.TRUE)\n            tok = TOK.true_;\n        else if (ident == Id.FALSE)\n            tok = TOK.false_;\n        else if (ident == Id.unsigned)\n            tok = TOK.uns32;\n        else if (ident == Id.wchar_t)\n            tok = global.params.isWindows ? TOK.wchar_ : TOK.dchar_;\n        else\n            return null;\n        return Token.toChars(tok);\n    }\n\n    extern (C++) Dsymbol insert(Dsymbol s)\n    {\n        if (VarDeclaration vd = s.isVarDeclaration())\n        {\n            if (lastVar)\n                vd.lastVar = lastVar;\n            lastVar = vd;\n        }\n        else if (WithScopeSymbol ss = s.isWithScopeSymbol())\n        {\n            if (VarDeclaration vd = ss.withstate.wthis)\n            {\n                if (lastVar)\n                    vd.lastVar = lastVar;\n                lastVar = vd;\n            }\n            return null;\n        }\n        for (Scope* sc = &this; sc; sc = sc.enclosing)\n        {\n            //printf(\"\\tsc = %p\\n\", sc);\n            if (sc.scopesym)\n            {\n                //printf(\"\\t\\tsc.scopesym = %p\\n\", sc.scopesym);\n                if (!sc.scopesym.symtab)\n                    sc.scopesym.symtab = new DsymbolTable();\n                return sc.scopesym.symtabInsert(s);\n            }\n        }\n        assert(0);\n    }\n\n    /********************************************\n     * Search enclosing scopes for ClassDeclaration.\n     */\n    extern (C++) ClassDeclaration getClassScope()\n    {\n        for (Scope* sc = &this; sc; sc = sc.enclosing)\n        {\n            if (!sc.scopesym)\n                continue;\n            ClassDeclaration cd = sc.scopesym.isClassDeclaration();\n            if (cd)\n                return cd;\n        }\n        return null;\n    }\n\n    /********************************************\n     * Search enclosing scopes for ClassDeclaration.\n     */\n    extern (C++) AggregateDeclaration getStructClassScope()\n    {\n        for (Scope* sc = &this; sc; sc = sc.enclosing)\n        {\n            if (!sc.scopesym)\n                continue;\n            AggregateDeclaration ad = sc.scopesym.isClassDeclaration();\n            if (ad)\n                return ad;\n            ad = sc.scopesym.isStructDeclaration();\n            if (ad)\n                return ad;\n        }\n        return null;\n    }\n\n    /*******************************************\n     * For TemplateDeclarations, we need to remember the Scope\n     * where it was declared. So mark the Scope as not\n     * to be free'd.\n     */\n    extern (C++) void setNoFree()\n    {\n        //int i = 0;\n        //printf(\"Scope::setNoFree(this = %p)\\n\", this);\n        for (Scope* sc = &this; sc; sc = sc.enclosing)\n        {\n            //printf(\"\\tsc = %p\\n\", sc);\n            sc.nofree = true;\n            assert(!(flags & SCOPE.free));\n            //assert(sc != sc.enclosing);\n            //assert(!sc.enclosing || sc != sc.enclosing.enclosing);\n            //if (++i == 10)\n            //    assert(0);\n        }\n    }\n\n    extern (D) this(ref Scope sc)\n    {\n        this._module = sc._module;\n        this.scopesym = sc.scopesym;\n        this.enclosing = sc.enclosing;\n        this.parent = sc.parent;\n        this.sw = sc.sw;\n        this.tf = sc.tf;\n        this.os = sc.os;\n        this.tinst = sc.tinst;\n        this.minst = sc.minst;\n        this.sbreak = sc.sbreak;\n        this.scontinue = sc.scontinue;\n        this.fes = sc.fes;\n        this.callsc = sc.callsc;\n        this.aligndecl = sc.aligndecl;\n        this.func = sc.func;\n        this.slabel = sc.slabel;\n        this.linkage = sc.linkage;\n        this.cppmangle = sc.cppmangle;\n        this.inlining = sc.inlining;\n        this.protection = sc.protection;\n        this.explicitProtection = sc.explicitProtection;\n        this.stc = sc.stc;\n        this.depdecl = sc.depdecl;\n        this.inunion = sc.inunion;\n        this.nofree = sc.nofree;\n        this.inLoop = sc.inLoop;\n        this.intypeof = sc.intypeof;\n        this.lastVar = sc.lastVar;\n        this.ctorflow = sc.ctorflow;\n        this.flags = sc.flags;\n        this.lastdc = sc.lastdc;\n        this.anchorCounts = sc.anchorCounts;\n        this.prevAnchor = sc.prevAnchor;\n        this.userAttribDecl = sc.userAttribDecl;\n    }\n\n    structalign_t alignment()\n    {\n        if (aligndecl)\n            return aligndecl.getAlignment(&this);\n        else\n            return STRUCTALIGN_DEFAULT;\n    }\n\n    /**********************************\n    * Checks whether the current scope (or any of its parents) is deprecated.\n    *\n    * Returns: `true` if this or any parent scope is deprecated, `false` otherwise`\n    */\n    extern(C++) bool isDeprecated()\n    {\n        for (Dsymbol sp = this.parent; sp; sp = sp.parent)\n        {\n            if (sp.isDeprecated())\n                return true;\n        }\n        for (Scope* sc2 = &this; sc2; sc2 = sc2.enclosing)\n        {\n            if (sc2.scopesym && sc2.scopesym.isDeprecated())\n                return true;\n\n            // If inside a StorageClassDeclaration that is deprecated\n            if (sc2.stc & STC.deprecated_)\n                return true;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/dstruct.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dstruct.d, _dstruct.d)\n * Documentation:  https://dlang.org/phobos/dmd_dstruct.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dstruct.d\n */\n\nmodule dmd.dstruct;\n\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.declaration;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.opover;\nimport dmd.semantic3;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.typinf;\nimport dmd.visitor;\n\n/***************************************\n * Search sd for a member function of the form:\n *   `extern (D) string toString();`\n * Params:\n *   sd = struct declaration to search\n * Returns:\n *   FuncDeclaration of `toString()` if found, `null` if not\n */\nextern (C++) FuncDeclaration search_toString(StructDeclaration sd)\n{\n    Dsymbol s = search_function(sd, Id.tostring);\n    FuncDeclaration fd = s ? s.isFuncDeclaration() : null;\n    if (fd)\n    {\n        __gshared TypeFunction tftostring;\n        if (!tftostring)\n        {\n            tftostring = new TypeFunction(null, Type.tstring, 0, LINK.d);\n            tftostring = tftostring.merge().toTypeFunction();\n        }\n        fd = fd.overloadExactMatch(tftostring);\n    }\n    return fd;\n}\n\n/***************************************\n * Request additional semantic analysis for TypeInfo generation.\n * Params:\n *      sc = context\n *      t = type that TypeInfo is being generated for\n */\nextern (C++) void semanticTypeInfo(Scope* sc, Type t)\n{\n    extern (C++) final class FullTypeInfoVisitor : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        Scope* sc;\n\n        override void visit(Type t)\n        {\n            Type tb = t.toBasetype();\n            if (tb != t)\n                tb.accept(this);\n        }\n\n        override void visit(TypeNext t)\n        {\n            if (t.next)\n                t.next.accept(this);\n        }\n\n        override void visit(TypeBasic t)\n        {\n        }\n\n        override void visit(TypeVector t)\n        {\n            t.basetype.accept(this);\n        }\n\n        override void visit(TypeAArray t)\n        {\n            t.index.accept(this);\n            visit(cast(TypeNext)t);\n        }\n\n        override void visit(TypeFunction t)\n        {\n            visit(cast(TypeNext)t);\n            // Currently TypeInfo_Function doesn't store parameter types.\n        }\n\n        override void visit(TypeStruct t)\n        {\n            //printf(\"semanticTypeInfo.visit(TypeStruct = %s)\\n\", t.toChars());\n            StructDeclaration sd = t.sym;\n\n            /* Step 1: create TypeInfoDeclaration\n             */\n            if (!sc) // inline may request TypeInfo.\n            {\n                Scope scx;\n                scx._module = sd.getModule();\n                getTypeInfoType(sd.loc, t, &scx);\n                sd.requestTypeInfo = true;\n            }\n            else if (!sc.minst)\n            {\n                // don't yet have to generate TypeInfo instance if\n                // the typeid(T) expression exists in speculative scope.\n            }\n            else\n            {\n                getTypeInfoType(sd.loc, t, sc);\n                sd.requestTypeInfo = true;\n\n                // https://issues.dlang.org/show_bug.cgi?id=15149\n                // if the typeid operand type comes from a\n                // result of auto function, it may be yet speculative.\n                unSpeculative(sc, sd);\n            }\n\n            /* Step 2: If the TypeInfo generation requires sd.semantic3, run it later.\n             * This should be done even if typeid(T) exists in speculative scope.\n             * Because it may appear later in non-speculative scope.\n             */\n            if (!sd.members)\n                return; // opaque struct\n            if (!sd.xeq && !sd.xcmp && !sd.postblit && !sd.dtor && !sd.xhash && !search_toString(sd))\n                return; // none of TypeInfo-specific members\n\n            // If the struct is in a non-root module, run semantic3 to get\n            // correct symbols for the member function.\n            if (sd.semanticRun >= PASS.semantic3)\n            {\n                // semantic3 is already done\n            }\n            else if (TemplateInstance ti = sd.isInstantiated())\n            {\n                if (ti.minst && !ti.minst.isRoot())\n                    Module.addDeferredSemantic3(sd);\n            }\n            else\n            {\n                if (sd.inNonRoot())\n                {\n                    //printf(\"deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\\n\", sd.toChars(), sd.inNonRoot());\n                    Module.addDeferredSemantic3(sd);\n                }\n            }\n        }\n\n        override void visit(TypeClass t)\n        {\n        }\n\n        override void visit(TypeTuple t)\n        {\n            if (t.arguments)\n            {\n                for (size_t i = 0; i < t.arguments.dim; i++)\n                {\n                    Type tprm = (*t.arguments)[i].type;\n                    if (tprm)\n                        tprm.accept(this);\n                }\n            }\n        }\n    }\n\n    if (sc)\n    {\n        if (!sc.func)\n            return;\n        if (sc.intypeof)\n            return;\n        if (sc.flags & (SCOPE.ctfe | SCOPE.compile))\n            return;\n    }\n\n    scope FullTypeInfoVisitor v = new FullTypeInfoVisitor();\n    v.sc = sc;\n    t.accept(v);\n}\n\nenum StructFlags : int\n{\n    none        = 0x0,\n    hasPointers = 0x1, // NB: should use noPointers as in ClassFlags\n}\n\nenum StructPOD : int\n{\n    no,    // struct is not POD\n    yes,   // struct is POD\n    fwd,   // POD not yet computed\n}\n\n/***********************************************************\n * All `struct` declarations are an instance of this.\n */\nextern (C++) class StructDeclaration : AggregateDeclaration\n{\n    bool zeroInit;              // !=0 if initialize with 0 fill\n    bool hasIdentityAssign;     // true if has identity opAssign\n    bool hasIdentityEquals;     // true if has identity opEquals\n    bool hasNoFields;           // has no fields\n    FuncDeclarations postblits; // Array of postblit functions\n    FuncDeclaration postblit;   // aggregate postblit\n\n    FuncDeclaration xeq;        // TypeInfo_Struct.xopEquals\n    FuncDeclaration xcmp;       // TypeInfo_Struct.xopCmp\n    FuncDeclaration xhash;      // TypeInfo_Struct.xtoHash\n    extern (C++) __gshared FuncDeclaration xerreq;   // object.xopEquals\n    extern (C++) __gshared FuncDeclaration xerrcmp;  // object.xopCmp\n\n    structalign_t alignment;    // alignment applied outside of the struct\n    StructPOD ispod;            // if struct is POD\n\n    // For 64 bit Efl function call/return ABI\n    Type arg1type;\n    Type arg2type;\n\n    // Even if struct is defined as non-root symbol, some built-in operations\n    // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.\n    // For those, today TypeInfo_Struct is generated in COMDAT.\n    bool requestTypeInfo;\n\n    extern (D) this(const ref Loc loc, Identifier id, bool inObject)\n    {\n        super(loc, id);\n        zeroInit = false; // assume false until we do semantic processing\n        ispod = StructPOD.fwd;\n        // For forward references\n        type = new TypeStruct(this);\n\n        if (inObject)\n        {\n            if (id == Id.ModuleInfo && !Module.moduleinfo)\n                Module.moduleinfo = this;\n        }\n    }\n\n    static StructDeclaration create(Loc loc, Identifier id, bool inObject)\n    {\n        return new StructDeclaration(loc, id, inObject);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        StructDeclaration sd =\n            s ? cast(StructDeclaration)s\n              : new StructDeclaration(loc, ident, false);\n        return ScopeDsymbol.syntaxCopy(sd);\n    }\n\n    final void semanticTypeInfoMembers()\n    {\n        if (xeq &&\n            xeq._scope &&\n            xeq.semanticRun < PASS.semantic3done)\n        {\n            uint errors = global.startGagging();\n            xeq.semantic3(xeq._scope);\n            if (global.endGagging(errors))\n                xeq = xerreq;\n        }\n\n        if (xcmp &&\n            xcmp._scope &&\n            xcmp.semanticRun < PASS.semantic3done)\n        {\n            uint errors = global.startGagging();\n            xcmp.semantic3(xcmp._scope);\n            if (global.endGagging(errors))\n                xcmp = xerrcmp;\n        }\n\n        FuncDeclaration ftostr = search_toString(this);\n        if (ftostr &&\n            ftostr._scope &&\n            ftostr.semanticRun < PASS.semantic3done)\n        {\n            ftostr.semantic3(ftostr._scope);\n        }\n\n        if (xhash &&\n            xhash._scope &&\n            xhash.semanticRun < PASS.semantic3done)\n        {\n            xhash.semantic3(xhash._scope);\n        }\n\n        if (postblit &&\n            postblit._scope &&\n            postblit.semanticRun < PASS.semantic3done)\n        {\n            postblit.semantic3(postblit._scope);\n        }\n\n        if (dtor &&\n            dtor._scope &&\n            dtor.semanticRun < PASS.semantic3done)\n        {\n            dtor.semantic3(dtor._scope);\n        }\n    }\n\n    override final Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)\n    {\n        //printf(\"%s.StructDeclaration::search('%s', flags = x%x)\\n\", toChars(), ident.toChars(), flags);\n        if (_scope && !symtab)\n            dsymbolSemantic(this, _scope);\n\n        if (!members || !symtab) // opaque or semantic() is not yet called\n        {\n            error(\"is forward referenced when looking for `%s`\", ident.toChars());\n            return null;\n        }\n\n        return ScopeDsymbol.search(loc, ident, flags);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"struct\";\n    }\n\n    override final void finalizeSize()\n    {\n        //printf(\"StructDeclaration::finalizeSize() %s, sizeok = %d\\n\", toChars(), sizeok);\n        assert(sizeok != Sizeok.done);\n\n        //printf(\"+StructDeclaration::finalizeSize() %s, fields.dim = %d, sizeok = %d\\n\", toChars(), fields.dim, sizeok);\n\n        fields.setDim(0);   // workaround\n\n        // Set the offsets of the fields and determine the size of the struct\n        uint offset = 0;\n        bool isunion = isUnionDeclaration() !is null;\n        for (size_t i = 0; i < members.dim; i++)\n        {\n            Dsymbol s = (*members)[i];\n            s.setFieldOffset(this, &offset, isunion);\n        }\n        if (type.ty == Terror)\n            return;\n\n        // 0 sized struct's are set to 1 byte\n        if (structsize == 0)\n        {\n            hasNoFields = true;\n            structsize = 1;\n            alignsize = 1;\n        }\n\n        // Round struct size up to next alignsize boundary.\n        // This will ensure that arrays of structs will get their internals\n        // aligned properly.\n        if (alignment == STRUCTALIGN_DEFAULT)\n            structsize = (structsize + alignsize - 1) & ~(alignsize - 1);\n        else\n            structsize = (structsize + alignment - 1) & ~(alignment - 1);\n\n        sizeok = Sizeok.done;\n\n        //printf(\"-StructDeclaration::finalizeSize() %s, fields.dim = %d, structsize = %d\\n\", toChars(), fields.dim, structsize);\n\n        if (errors)\n            return;\n\n        // Calculate fields[i].overlapped\n        if (checkOverlappedFields())\n        {\n            errors = true;\n            return;\n        }\n\n        // Determine if struct is all zeros or not\n        zeroInit = true;\n        foreach (vd; fields)\n        {\n            if (vd._init)\n            {\n                if (vd._init.isVoidInitializer())\n                    /* Treat as 0 for the purposes of putting the initializer\n                     * in the BSS segment, or doing a mass set to 0\n                     */\n                    continue;\n\n                // Zero size fields are zero initialized\n                if (vd.type.size(vd.loc) == 0)\n                    continue;\n\n                // Examine init to see if it is all 0s.\n                auto exp = vd.getConstInitializer();\n                if (!exp || !_isZeroInit(exp))\n                {\n                    zeroInit = false;\n                    break;\n                }\n            }\n            else if (!vd.type.isZeroInit(loc))\n            {\n                zeroInit = false;\n                break;\n            }\n        }\n\n        auto tt = Target.toArgTypes(type);\n        size_t dim = tt.arguments.dim;\n        if (dim >= 1)\n        {\n            assert(dim <= 2);\n            arg1type = (*tt.arguments)[0].type;\n            if (dim == 2)\n                arg2type = (*tt.arguments)[1].type;\n        }\n    }\n\n    /***************************************\n     * Fit elements[] to the corresponding types of the struct's fields.\n     *\n     * Params:\n     *      loc = location to use for error messages\n     *      sc = context\n     *      elements = explicit arguments used to construct object\n     *      stype = the constructed object type.\n     * Returns:\n     *      false if any errors occur,\n     *      otherwise true and elements[] are rewritten for the output.\n     */\n    final bool fit(const ref Loc loc, Scope* sc, Expressions* elements, Type stype)\n    {\n        if (!elements)\n            return true;\n\n        size_t nfields = fields.dim - isNested();\n        size_t offset = 0;\n        for (size_t i = 0; i < elements.dim; i++)\n        {\n            Expression e = (*elements)[i];\n            if (!e)\n                continue;\n\n            e = resolveProperties(sc, e);\n            if (i >= nfields)\n            {\n                if (i == fields.dim - 1 && isNested() && e.op == TOK.null_)\n                {\n                    // CTFE sometimes creates null as hidden pointer; we'll allow this.\n                    continue;\n                }\n                .error(loc, \"more initializers than fields (%d) of `%s`\", nfields, toChars());\n                return false;\n            }\n            VarDeclaration v = fields[i];\n            if (v.offset < offset)\n            {\n                .error(loc, \"overlapping initialization for `%s`\", v.toChars());\n                return false;\n            }\n            offset = cast(uint)(v.offset + v.type.size());\n\n            Type t = v.type;\n            if (stype)\n                t = t.addMod(stype.mod);\n            Type origType = t;\n            Type tb = t.toBasetype();\n\n            const hasPointers = tb.hasPointers();\n            if (hasPointers)\n            {\n                if ((stype.alignment() < Target.ptrsize ||\n                     (v.offset & (Target.ptrsize - 1))) &&\n                    (sc.func && sc.func.setUnsafe()))\n                {\n                    .error(loc, \"field `%s.%s` cannot assign to misaligned pointers in `@safe` code\",\n                        toChars(), v.toChars());\n                    return false;\n                }\n            }\n\n            /* Look for case of initializing a static array with a too-short\n             * string literal, such as:\n             *  char[5] foo = \"abc\";\n             * Allow this by doing an explicit cast, which will lengthen the string\n             * literal.\n             */\n            if (e.op == TOK.string_ && tb.ty == Tsarray)\n            {\n                StringExp se = cast(StringExp)e;\n                Type typeb = se.type.toBasetype();\n                TY tynto = tb.nextOf().ty;\n                if (!se.committed &&\n                    (typeb.ty == Tarray || typeb.ty == Tsarray) &&\n                    (tynto == Tchar || tynto == Twchar || tynto == Tdchar) &&\n                    se.numberOfCodeUnits(tynto) < (cast(TypeSArray)tb).dim.toInteger())\n                {\n                    e = se.castTo(sc, t);\n                    goto L1;\n                }\n            }\n\n            while (!e.implicitConvTo(t) && tb.ty == Tsarray)\n            {\n                /* Static array initialization, as in:\n                 *  T[3][5] = e;\n                 */\n                t = tb.nextOf();\n                tb = t.toBasetype();\n            }\n            if (!e.implicitConvTo(t))\n                t = origType; // restore type for better diagnostic\n\n            e = e.implicitCastTo(sc, t);\n        L1:\n            if (e.op == TOK.error)\n                return false;\n\n            (*elements)[i] = doCopyOrMove(sc, e);\n        }\n        return true;\n    }\n\n    /***************************************\n     * Determine if struct is POD (Plain Old Data).\n     *\n     * POD is defined as:\n     *      $(OL\n     *      $(LI not nested)\n     *      $(LI no postblits, destructors, or assignment operators)\n     *      $(LI no `ref` fields or fields that are themselves non-POD)\n     *      )\n     * The idea being these are compatible with C structs.\n     *\n     * Returns:\n     *     true if struct is POD\n     */\n    final bool isPOD()\n    {\n        // If we've already determined whether this struct is POD.\n        if (ispod != StructPOD.fwd)\n            return (ispod == StructPOD.yes);\n\n        ispod = StructPOD.yes;\n\n        if (enclosing || postblit || dtor)\n            ispod = StructPOD.no;\n\n        // Recursively check all fields are POD.\n        for (size_t i = 0; i < fields.dim; i++)\n        {\n            VarDeclaration v = fields[i];\n            if (v.storage_class & STC.ref_)\n            {\n                ispod = StructPOD.no;\n                break;\n            }\n\n            Type tv = v.type.baseElemOf();\n            if (tv.ty == Tstruct)\n            {\n                TypeStruct ts = cast(TypeStruct)tv;\n                StructDeclaration sd = ts.sym;\n                if (!sd.isPOD())\n                {\n                    ispod = StructPOD.no;\n                    break;\n                }\n            }\n        }\n\n        return (ispod == StructPOD.yes);\n    }\n\n    override final inout(StructDeclaration) isStructDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/**********************************\n * Determine if exp is all binary zeros.\n * Params:\n *      exp = expression to check\n * Returns:\n *      true if it's all binary 0\n */\nprivate bool _isZeroInit(Expression exp)\n{\n    switch (exp.op)\n    {\n        case TOK.int64:\n            return exp.toInteger() == 0;\n\n        case TOK.null_:\n        case TOK.false_:\n            return true;\n\n        case TOK.structLiteral:\n        {\n            auto sle = cast(StructLiteralExp) exp;\n            foreach (i; 0 .. sle.sd.fields.dim)\n            {\n                auto field = sle.sd.fields[i];\n                if (field.type.size(field.loc))\n                {\n                    auto e = (*sle.elements)[i];\n                    if (e ? !_isZeroInit(e)\n                          : !field.type.isZeroInit(field.loc))\n                        return false;\n                }\n            }\n            return true;\n        }\n\n        case TOK.arrayLiteral:\n        {\n            auto ale = cast(ArrayLiteralExp)exp;\n\n            const dim = ale.elements ? ale.elements.dim : 0;\n\n            if (ale.type.toBasetype().ty == Tarray) // if initializing a dynamic array\n                return dim == 0;\n\n            foreach (i; 0 .. dim)\n            {\n                if (!_isZeroInit(ale.getElement(i)))\n                    return false;\n            }\n\n            /* Note that true is returned for all T[0]\n             */\n            return true;\n        }\n\n        case TOK.string_:\n        {\n            StringExp se = cast(StringExp)exp;\n\n            if (se.type.toBasetype().ty == Tarray) // if initializing a dynamic array\n                return se.len == 0;\n\n            foreach (i; 0 .. se.len)\n            {\n                if (se.getCodeUnit(i))\n                    return false;\n            }\n            return true;\n        }\n\n        case TOK.vector:\n        {\n            auto ve = cast(VectorExp) exp;\n            return _isZeroInit(ve.e1);\n        }\n\n        case TOK.float64:\n        case TOK.complex80:\n        {\n            import dmd.root.ctfloat : CTFloat;\n            return (exp.toReal()      is CTFloat.zero) &&\n                   (exp.toImaginary() is CTFloat.zero);\n        }\n\n        default:\n            return false;\n    }\n}\n\n/***********************************************************\n * Unions are a variation on structs.\n */\nextern (C++) final class UnionDeclaration : StructDeclaration\n{\n    extern (D) this(const ref Loc loc, Identifier id)\n    {\n        super(loc, id, false);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto ud = new UnionDeclaration(loc, ident);\n        return StructDeclaration.syntaxCopy(ud);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"union\";\n    }\n\n    override inout(UnionDeclaration) isUnionDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/dsymbol.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dsymbol.d, _dsymbol.d)\n * Documentation:  https://dlang.org/phobos/dmd_dsymbol.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dsymbol.d\n */\n\nmodule dmd.dsymbol;\n\nimport core.stdc.stdarg;\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport core.stdc.stdlib;\n\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arraytypes;\nimport dmd.attrib;\nimport dmd.gluelayer;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dimport;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.lexer;\nimport dmd.mtype;\nimport dmd.nspace;\nimport dmd.opover;\nimport dmd.root.aav;\nimport dmd.root.rmem;\nimport dmd.root.rootobject;\nimport dmd.root.speller;\nimport dmd.statement;\nimport dmd.tokens;\nimport dmd.visitor;\n\nstruct Ungag\n{\n    uint oldgag;\n\n    extern (D) this(uint old)\n    {\n        this.oldgag = old;\n    }\n\n    extern (C++) ~this()\n    {\n        global.gag = oldgag;\n    }\n}\n\nstruct Prot\n{\n    ///\n    enum Kind : int\n    {\n        undefined,\n        none,           // no access\n        private_,\n        package_,\n        protected_,\n        public_,\n        export_,\n    }\n\n    Kind kind;\n    Package pkg;\n\n    extern (D) this(Prot.Kind kind)\n    {\n        this.kind = kind;\n    }\n\n    extern (C++):\n\n    /**\n     * Checks if `this` is superset of `other` restrictions.\n     * For example, \"protected\" is more restrictive than \"public\".\n     */\n    bool isMoreRestrictiveThan(const Prot other) const\n    {\n        return this.kind < other.kind;\n    }\n\n    /**\n     * Checks if `this` is absolutely identical protection attribute to `other`\n     */\n    bool opEquals(ref const Prot other) const\n    {\n        if (this.kind == other.kind)\n        {\n            if (this.kind == Prot.Kind.package_)\n                return this.pkg == other.pkg;\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * Checks if parent defines different access restrictions than this one.\n     *\n     * Params:\n     *  parent = protection attribute for scope that hosts this one\n     *\n     * Returns:\n     *  'true' if parent is already more restrictive than this one and thus\n     *  no differentiation is needed.\n     */\n    bool isSubsetOf(ref const Prot parent) const\n    {\n        if (this.kind != parent.kind)\n            return false;\n        if (this.kind == Prot.Kind.package_)\n        {\n            if (!this.pkg)\n                return true;\n            if (!parent.pkg)\n                return false;\n            if (parent.pkg.isAncestorPackageOf(this.pkg))\n                return true;\n        }\n        return true;\n    }\n}\n\nenum PASS : int\n{\n    init,           // initial state\n    semantic,       // semantic() started\n    semanticdone,   // semantic() done\n    semantic2,      // semantic2() started\n    semantic2done,  // semantic2() done\n    semantic3,      // semantic3() started\n    semantic3done,  // semantic3() done\n    inline,         // inline started\n    inlinedone,     // inline done\n    obj,            // toObjFile() run\n}\n\n// Search options\nenum : int\n{\n    IgnoreNone              = 0x00, // default\n    IgnorePrivateImports    = 0x01, // don't search private imports\n    IgnoreErrors            = 0x02, // don't give error messages\n    IgnoreAmbiguous         = 0x04, // return NULL if ambiguous\n    SearchLocalsOnly        = 0x08, // only look at locals (don't search imports)\n    SearchImportsOnly       = 0x10, // only look in imports\n    SearchUnqualifiedModule = 0x20, // the module scope search is unqualified,\n                                    // meaning don't search imports in that scope,\n                                    // because qualified module searches search\n                                    // their imports\n    IgnoreSymbolVisibility  = 0x80, // also find private and package protected symbols\n}\n\nextern (C++) alias Dsymbol_apply_ft_t = int function(Dsymbol, void*);\n\n/***********************************************************\n */\nextern (C++) class Dsymbol : RootObject\n{\n    Identifier ident;\n    Dsymbol parent;\n    Symbol* csym;           // symbol for code generator\n    Symbol* isym;           // import version of csym\n    const(char)* comment;   // documentation comment for this Dsymbol\n    Loc loc;                // where defined\n    Scope* _scope;          // !=null means context to use for semantic()\n    const(char)* prettystring;  // cached value of toPrettyChars()\n    bool errors;            // this symbol failed to pass semantic()\n    PASS semanticRun;\n\n    DeprecatedDeclaration depdecl;           // customized deprecation message\n    UserAttributeDeclaration userAttribDecl;    // user defined attributes\n\n    // !=null means there's a ddoc unittest associated with this symbol\n    // (only use this with ddoc)\n    UnitTestDeclaration ddocUnittest;\n\n    final extern (D) this()\n    {\n        //printf(\"Dsymbol::Dsymbol(%p)\\n\", this);\n        this.semanticRun = PASS.init;\n    }\n\n    final extern (D) this(Identifier ident)\n    {\n        //printf(\"Dsymbol::Dsymbol(%p, ident)\\n\", this);\n        this.ident = ident;\n        this.semanticRun = PASS.init;\n    }\n\n    static Dsymbol create(Identifier ident)\n    {\n        return new Dsymbol(ident);\n    }\n\n    override const(char)* toChars()\n    {\n        return ident ? ident.toChars() : \"__anonymous\";\n    }\n\n    // helper to print fully qualified (template) arguments\n    const(char)* toPrettyCharsHelper()\n    {\n        return toChars();\n    }\n\n    final ref const(Loc) getLoc()\n    {\n        if (!loc.isValid()) // avoid bug 5861.\n        {\n            auto m = getModule();\n            if (m && m.srcfile)\n                loc.filename = m.srcfile.toChars();\n        }\n        return loc;\n    }\n\n    final const(char)* locToChars()\n    {\n        return getLoc().toChars();\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n        if (o.dyncast() != DYNCAST.dsymbol)\n            return false;\n        Dsymbol s = cast(Dsymbol)o;\n        // Overload sets don't have an ident\n        if (s && ident && s.ident && ident.equals(s.ident))\n            return true;\n        return false;\n    }\n\n    bool isAnonymous()\n    {\n        return ident is null;\n    }\n\n    final void error(const ref Loc loc, const(char)* format, ...)\n    {\n        va_list ap;\n        va_start(ap, format);\n        const cstr = toPrettyChars();\n        const pretty = '`' ~ cstr[0 .. strlen(cstr)] ~ \"`\\0\";\n        .verror(loc, format, ap, kind(), pretty.ptr);\n        va_end(ap);\n    }\n\n    final void error(const(char)* format, ...)\n    {\n        va_list ap;\n        va_start(ap, format);\n        const cstr = toPrettyChars();\n        const pretty = '`' ~ cstr[0 .. strlen(cstr)] ~ \"`\\0\";\n        .verror(getLoc(), format, ap, kind(), pretty.ptr);\n        va_end(ap);\n    }\n\n    final void deprecation(const ref Loc loc, const(char)* format, ...)\n    {\n        va_list ap;\n        va_start(ap, format);\n        const cstr = toPrettyChars();\n        const pretty = '`' ~ cstr[0 .. strlen(cstr)] ~ \"`\\0\";\n        .vdeprecation(loc, format, ap, kind(), pretty.ptr);\n        va_end(ap);\n    }\n\n    final void deprecation(const(char)* format, ...)\n    {\n        va_list ap;\n        va_start(ap, format);\n        const cstr = toPrettyChars();\n        const pretty = '`' ~ cstr[0 .. strlen(cstr)] ~ \"`\\0\";\n        .vdeprecation(getLoc(), format, ap, kind(), pretty.ptr);\n        va_end(ap);\n    }\n\n    final bool checkDeprecated(const ref Loc loc, Scope* sc)\n    {\n        if (global.params.useDeprecated != Diagnostic.off && isDeprecated())\n        {\n            // Don't complain if we're inside a deprecated symbol's scope\n            if (sc.isDeprecated())\n                return false;\n\n            const(char)* message = null;\n            for (Dsymbol p = this; p; p = p.parent)\n            {\n                message = p.depdecl ? p.depdecl.getMessage() : null;\n                if (message)\n                    break;\n            }\n            if (message)\n                deprecation(loc, \"is deprecated - %s\", message);\n            else\n                deprecation(loc, \"is deprecated\");\n\n            return true;\n        }\n\n        return false;\n    }\n\n    /**********************************\n     * Determine which Module a Dsymbol is in.\n     */\n    final Module getModule()\n    {\n        //printf(\"Dsymbol::getModule()\\n\");\n        if (TemplateInstance ti = isInstantiated())\n            return ti.tempdecl.getModule();\n        Dsymbol s = this;\n        while (s)\n        {\n            //printf(\"\\ts = %s '%s'\\n\", s.kind(), s.toPrettyChars());\n            Module m = s.isModule();\n            if (m)\n                return m;\n            s = s.parent;\n        }\n        return null;\n    }\n\n    /**********************************\n     * Determine which Module a Dsymbol is in, as far as access rights go.\n     */\n    final Module getAccessModule()\n    {\n        //printf(\"Dsymbol::getAccessModule()\\n\");\n        if (TemplateInstance ti = isInstantiated())\n            return ti.tempdecl.getAccessModule();\n        Dsymbol s = this;\n        while (s)\n        {\n            //printf(\"\\ts = %s '%s'\\n\", s.kind(), s.toPrettyChars());\n            Module m = s.isModule();\n            if (m)\n                return m;\n            TemplateInstance ti = s.isTemplateInstance();\n            if (ti && ti.enclosing)\n            {\n                /* Because of local template instantiation, the parent isn't where the access\n                 * rights come from - it's the template declaration\n                 */\n                s = ti.tempdecl;\n            }\n            else\n                s = s.parent;\n        }\n        return null;\n    }\n\n    final inout(Dsymbol) pastMixin() inout\n    {\n        //printf(\"Dsymbol::pastMixin() %s\\n\", toChars());\n        if (!isTemplateMixin() && !isForwardingAttribDeclaration())\n            return this;\n        if (!parent)\n            return null;\n        return parent.pastMixin();\n    }\n\n    /**********************************\n     * `parent` field returns a lexically enclosing scope symbol this is a member of.\n     *\n     * `toParent()` returns a logically enclosing scope symbol this is a member of.\n     * It skips over TemplateMixin's.\n     *\n     * `toParent2()` returns an enclosing scope symbol this is living at runtime.\n     * It skips over both TemplateInstance's and TemplateMixin's.\n     * It's used when looking for the 'this' pointer of the enclosing function/class.\n     *\n     * Examples:\n     *  module mod;\n     *  template Foo(alias a) { mixin Bar!(); }\n     *  mixin template Bar() {\n     *    public {  // ProtDeclaration\n     *      void baz() { a = 2; }\n     *    }\n     *  }\n     *  void test() {\n     *    int v = 1;\n     *    alias foo = Foo!(v);\n     *    foo.baz();\n     *    assert(v == 2);\n     *  }\n     *\n     *  // s == FuncDeclaration('mod.test.Foo!().Bar!().baz()')\n     *  // s.parent == TemplateMixin('mod.test.Foo!().Bar!()')\n     *  // s.toParent() == TemplateInstance('mod.test.Foo!()')\n     *  // s.toParent2() == FuncDeclaration('mod.test')\n     */\n    final inout(Dsymbol) toParent() inout\n    {\n        return parent ? parent.pastMixin() : null;\n    }\n\n    /// ditto\n    final inout(Dsymbol) toParent2() inout\n    {\n        if (!parent || !parent.isTemplateInstance && !parent.isForwardingAttribDeclaration())\n            return parent;\n        return parent.toParent2;\n    }\n\n    final inout(TemplateInstance) isInstantiated() inout\n    {\n        if (!parent)\n            return null;\n        auto ti = parent.isTemplateInstance();\n        if (ti && !ti.isTemplateMixin())\n            return ti;\n        return parent.isInstantiated();\n    }\n\n    // Check if this function is a member of a template which has only been\n    // instantiated speculatively, eg from inside is(typeof()).\n    // Return the speculative template instance it is part of,\n    // or NULL if not speculative.\n    final inout(TemplateInstance) isSpeculative() inout\n    {\n        if (!parent)\n            return null;\n        auto ti = parent.isTemplateInstance();\n        if (ti && ti.gagged)\n            return ti;\n        if (!parent.toParent())\n            return null;\n        return parent.isSpeculative();\n    }\n\n    final Ungag ungagSpeculative() const\n    {\n        uint oldgag = global.gag;\n        if (global.gag && !isSpeculative() && !toParent2().isFuncDeclaration())\n            global.gag = 0;\n        return Ungag(oldgag);\n    }\n\n    // kludge for template.isSymbol()\n    override final DYNCAST dyncast() const\n    {\n        return DYNCAST.dsymbol;\n    }\n\n    /*************************************\n     * Do syntax copy of an array of Dsymbol's.\n     */\n    extern (D) static Dsymbols* arraySyntaxCopy(Dsymbols* a)\n    {\n        Dsymbols* b = null;\n        if (a)\n        {\n            b = a.copy();\n            for (size_t i = 0; i < b.dim; i++)\n            {\n                (*b)[i] = (*b)[i].syntaxCopy(null);\n            }\n        }\n        return b;\n    }\n\n    Identifier getIdent()\n    {\n        return ident;\n    }\n\n    const(char)* toPrettyChars(bool QualifyTypes = false)\n    {\n        if (prettystring && !QualifyTypes)\n            return prettystring;\n\n        //printf(\"Dsymbol::toPrettyChars() '%s'\\n\", toChars());\n        if (!parent)\n        {\n            auto s = toChars();\n            if (!QualifyTypes)\n                prettystring = s;\n            return s;\n        }\n\n        // Computer number of components\n        size_t complength = 0;\n        for (Dsymbol p = this; p; p = p.parent)\n            ++complength;\n\n        // Allocate temporary array comp[]\n        alias T = const(char)[];\n        auto compptr = cast(T*)malloc(complength * T.sizeof);\n        if (!compptr)\n            Mem.error();\n        auto comp = compptr[0 .. complength];\n\n        // Fill in comp[] and compute length of final result\n        size_t length = 0;\n        int i;\n        for (Dsymbol p = this; p; p = p.parent)\n        {\n            const s = QualifyTypes ? p.toPrettyCharsHelper() : p.toChars();\n            const len = strlen(s);\n            comp[i] = s[0 .. len];\n            ++i;\n            length += len + 1;\n        }\n\n        auto s = cast(char*)mem.xmalloc(length);\n        auto q = s + length - 1;\n        *q = 0;\n        foreach (j; 0 .. complength)\n        {\n            const t = comp[j].ptr;\n            const len = comp[j].length;\n            q -= len;\n            memcpy(q, t, len);\n            if (q == s)\n                break;\n            *--q = '.';\n        }\n        free(comp.ptr);\n        if (!QualifyTypes)\n            prettystring = s;\n        return s;\n    }\n\n    const(char)* kind() const pure nothrow @nogc @safe\n    {\n        return \"symbol\";\n    }\n\n    /*********************************\n     * If this symbol is really an alias for another,\n     * return that other.\n     * If needed, semantic() is invoked due to resolve forward reference.\n     */\n    Dsymbol toAlias()\n    {\n        return this;\n    }\n\n    /*********************************\n     * Resolve recursive tuple expansion in eponymous template.\n     */\n    Dsymbol toAlias2()\n    {\n        return toAlias();\n    }\n\n    /*********************************\n     * Iterate this dsymbol or members of this scoped dsymbol, then\n     * call `fp` with the found symbol and `param`.\n     * Params:\n     *  fp = function pointer to process the iterated symbol.\n     *       If it returns nonzero, the iteration will be aborted.\n     *  param = a parameter passed to fp.\n     * Returns:\n     *  nonzero if the iteration is aborted by the return value of fp,\n     *  or 0 if it's completed.\n     */\n    int apply(Dsymbol_apply_ft_t fp, void* param)\n    {\n        return (*fp)(this, param);\n    }\n\n    void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        //printf(\"Dsymbol::addMember('%s')\\n\", toChars());\n        //printf(\"Dsymbol::addMember(this = %p, '%s' scopesym = '%s')\\n\", this, toChars(), sds.toChars());\n        //printf(\"Dsymbol::addMember(this = %p, '%s' sds = %p, sds.symtab = %p)\\n\", this, toChars(), sds, sds.symtab);\n        parent = sds;\n        if (!isAnonymous()) // no name, so can't add it to symbol table\n        {\n            if (!sds.symtabInsert(this)) // if name is already defined\n            {\n                Dsymbol s2 = sds.symtabLookup(this,ident);\n                if (!s2.overloadInsert(this))\n                {\n                    sds.multiplyDefined(Loc.initial, this, s2);\n                    errors = true;\n                }\n            }\n            if (sds.isAggregateDeclaration() || sds.isEnumDeclaration())\n            {\n                if (ident == Id.__sizeof || ident == Id.__xalignof || ident == Id._mangleof)\n                {\n                    error(\"`.%s` property cannot be redefined\", ident.toChars());\n                    errors = true;\n                }\n            }\n        }\n    }\n\n    /*************************************\n     * Set scope for future semantic analysis so we can\n     * deal better with forward references.\n     */\n    void setScope(Scope* sc)\n    {\n        //printf(\"Dsymbol::setScope() %p %s, %p stc = %llx\\n\", this, toChars(), sc, sc.stc);\n        if (!sc.nofree)\n            sc.setNoFree(); // may need it even after semantic() finishes\n        _scope = sc;\n        if (sc.depdecl)\n            depdecl = sc.depdecl;\n        if (!userAttribDecl)\n            userAttribDecl = sc.userAttribDecl;\n    }\n\n    void importAll(Scope* sc)\n    {\n    }\n\n    /*********************************************\n     * Search for ident as member of s.\n     * Params:\n     *  loc = location to print for error messages\n     *  ident = identifier to search for\n     *  flags = IgnoreXXXX\n     * Returns:\n     *  null if not found\n     */\n    Dsymbol search(const ref Loc loc, Identifier ident, int flags = IgnoreNone)\n    {\n        //printf(\"Dsymbol::search(this=%p,%s, ident='%s')\\n\", this, toChars(), ident.toChars());\n        return null;\n    }\n\n    final Dsymbol search_correct(Identifier ident)\n    {\n        /***************************************************\n         * Search for symbol with correct spelling.\n         */\n        extern (D) void* symbol_search_fp(const(char)* seed, ref int cost)\n        {\n            /* If not in the lexer's string table, it certainly isn't in the symbol table.\n             * Doing this first is a lot faster.\n             */\n            size_t len = strlen(seed);\n            if (!len)\n                return null;\n            Identifier id = Identifier.lookup(seed, len);\n            if (!id)\n                return null;\n            cost = 0;\n            Dsymbol s = this;\n            Module.clearCache();\n            return cast(void*)s.search(Loc.initial, id, IgnoreErrors);\n        }\n\n        if (global.gag)\n            return null; // don't do it for speculative compiles; too time consuming\n        return cast(Dsymbol)speller(ident.toChars(), &symbol_search_fp, idchars);\n    }\n\n    /***************************************\n     * Search for identifier id as a member of `this`.\n     * `id` may be a template instance.\n     *\n     * Params:\n     *  loc = location to print the error messages\n     *  sc = the scope where the symbol is located\n     *  id = the id of the symbol\n     *  flags = the search flags which can be `SearchLocalsOnly` or `IgnorePrivateImports`\n     *\n     * Returns:\n     *      symbol found, NULL if not\n     */\n    final Dsymbol searchX(const ref Loc loc, Scope* sc, RootObject id, int flags)\n    {\n        //printf(\"Dsymbol::searchX(this=%p,%s, ident='%s')\\n\", this, toChars(), ident.toChars());\n        Dsymbol s = toAlias();\n        Dsymbol sm;\n        if (Declaration d = s.isDeclaration())\n        {\n            if (d.inuse)\n            {\n                .error(loc, \"circular reference to `%s`\", d.toPrettyChars());\n                return null;\n            }\n        }\n        switch (id.dyncast())\n        {\n        case DYNCAST.identifier:\n            sm = s.search(loc, cast(Identifier)id, flags);\n            break;\n        case DYNCAST.dsymbol:\n            {\n                // It's a template instance\n                //printf(\"\\ttemplate instance id\\n\");\n                Dsymbol st = cast(Dsymbol)id;\n                TemplateInstance ti = st.isTemplateInstance();\n                sm = s.search(loc, ti.name);\n                if (!sm)\n                {\n                    sm = s.search_correct(ti.name);\n                    if (sm)\n                        .error(loc, \"template identifier `%s` is not a member of %s `%s`, did you mean %s `%s`?\", ti.name.toChars(), s.kind(), s.toPrettyChars(), sm.kind(), sm.toChars());\n                    else\n                        .error(loc, \"template identifier `%s` is not a member of %s `%s`\", ti.name.toChars(), s.kind(), s.toPrettyChars());\n                    return null;\n                }\n                sm = sm.toAlias();\n                TemplateDeclaration td = sm.isTemplateDeclaration();\n                if (!td)\n                {\n                    .error(loc, \"`%s.%s` is not a template, it is a %s\", s.toPrettyChars(), ti.name.toChars(), sm.kind());\n                    return null;\n                }\n                ti.tempdecl = td;\n                if (!ti.semanticRun)\n                    ti.dsymbolSemantic(sc);\n                sm = ti.toAlias();\n                break;\n            }\n        case DYNCAST.type:\n        case DYNCAST.expression:\n        default:\n            assert(0);\n        }\n        return sm;\n    }\n\n    bool overloadInsert(Dsymbol s)\n    {\n        //printf(\"Dsymbol::overloadInsert('%s')\\n\", s.toChars());\n        return false;\n    }\n\n    /*********************************\n     * Returns:\n     *  SIZE_INVALID when the size cannot be determined\n     */\n    d_uns64 size(const ref Loc loc)\n    {\n        error(\"Dsymbol `%s` has no size\", toChars());\n        return SIZE_INVALID;\n    }\n\n    bool isforwardRef()\n    {\n        return false;\n    }\n\n    // is a 'this' required to access the member\n    inout(AggregateDeclaration) isThis() inout\n    {\n        return null;\n    }\n\n    // is Dsymbol exported?\n    bool isExport() const\n    {\n        return false;\n    }\n\n    // is Dsymbol imported?\n    bool isImportedSymbol() const\n    {\n        return false;\n    }\n\n    // is Dsymbol deprecated?\n    bool isDeprecated()\n    {\n        return false;\n    }\n\n    bool isOverloadable()\n    {\n        return false;\n    }\n\n    // is this a LabelDsymbol()?\n    LabelDsymbol isLabel()\n    {\n        return null;\n    }\n\n    /// Returns an AggregateDeclaration when toParent() is that.\n    final inout(AggregateDeclaration) isMember() inout\n    {\n        //printf(\"Dsymbol::isMember() %s\\n\", toChars());\n        auto p = toParent();\n        //printf(\"parent is %s %s\\n\", p.kind(), p.toChars());\n        return p ? p.isAggregateDeclaration() : null;\n    }\n\n    /// Returns an AggregateDeclaration when toParent2() is that.\n    final inout(AggregateDeclaration) isMember2() inout\n    {\n        //printf(\"Dsymbol::isMember2() '%s'\\n\", toChars());\n        auto p = toParent2();\n        //printf(\"parent is %s %s\\n\", p.kind(), p.toChars());\n        return p ? p.isAggregateDeclaration() : null;\n    }\n\n    // is this a member of a ClassDeclaration?\n    final ClassDeclaration isClassMember()\n    {\n        auto ad = isMember();\n        return ad ? ad.isClassDeclaration() : null;\n    }\n\n    // is this a type?\n    Type getType()\n    {\n        return null;\n    }\n\n    // need a 'this' pointer?\n    bool needThis()\n    {\n        return false;\n    }\n\n    /*************************************\n     */\n    Prot prot()\n    {\n        return Prot(Prot.Kind.public_);\n    }\n\n    /**************************************\n     * Copy the syntax.\n     * Used for template instantiations.\n     * If s is NULL, allocate the new object, otherwise fill it in.\n     */\n    Dsymbol syntaxCopy(Dsymbol s)\n    {\n        printf(\"%s %s\\n\", kind(), toChars());\n        assert(0);\n    }\n\n    /**************************************\n     * Determine if this symbol is only one.\n     * Returns:\n     *      false, *ps = NULL: There are 2 or more symbols\n     *      true,  *ps = NULL: There are zero symbols\n     *      true,  *ps = symbol: The one and only one symbol\n     */\n    bool oneMember(Dsymbol* ps, Identifier ident)\n    {\n        //printf(\"Dsymbol::oneMember()\\n\");\n        *ps = this;\n        return true;\n    }\n\n    /*****************************************\n     * Same as Dsymbol::oneMember(), but look at an array of Dsymbols.\n     */\n    extern (D) static bool oneMembers(Dsymbols* members, Dsymbol* ps, Identifier ident)\n    {\n        //printf(\"Dsymbol::oneMembers() %d\\n\", members ? members.dim : 0);\n        Dsymbol s = null;\n        if (members)\n        {\n            for (size_t i = 0; i < members.dim; i++)\n            {\n                Dsymbol sx = (*members)[i];\n                bool x = sx.oneMember(ps, ident);\n                //printf(\"\\t[%d] kind %s = %d, s = %p\\n\", i, sx.kind(), x, *ps);\n                if (!x)\n                {\n                    //printf(\"\\tfalse 1\\n\");\n                    assert(*ps is null);\n                    return false;\n                }\n                if (*ps)\n                {\n                    assert(ident);\n                    if (!(*ps).ident || !(*ps).ident.equals(ident))\n                        continue;\n                    if (!s)\n                        s = *ps;\n                    else if (s.isOverloadable() && (*ps).isOverloadable())\n                    {\n                        // keep head of overload set\n                        FuncDeclaration f1 = s.isFuncDeclaration();\n                        FuncDeclaration f2 = (*ps).isFuncDeclaration();\n                        if (f1 && f2)\n                        {\n                            assert(!f1.isFuncAliasDeclaration());\n                            assert(!f2.isFuncAliasDeclaration());\n                            for (; f1 != f2; f1 = f1.overnext0)\n                            {\n                                if (f1.overnext0 is null)\n                                {\n                                    f1.overnext0 = f2;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                    else // more than one symbol\n                    {\n                        *ps = null;\n                        //printf(\"\\tfalse 2\\n\");\n                        return false;\n                    }\n                }\n            }\n        }\n        *ps = s; // s is the one symbol, null if none\n        //printf(\"\\ttrue\\n\");\n        return true;\n    }\n\n    void setFieldOffset(AggregateDeclaration ad, uint* poffset, bool isunion)\n    {\n    }\n\n    /*****************************************\n     * Is Dsymbol a variable that contains pointers?\n     */\n    bool hasPointers()\n    {\n        //printf(\"Dsymbol::hasPointers() %s\\n\", toChars());\n        return false;\n    }\n\n    bool hasStaticCtorOrDtor()\n    {\n        //printf(\"Dsymbol::hasStaticCtorOrDtor() %s\\n\", toChars());\n        return false;\n    }\n\n    void addLocalClass(ClassDeclarations*)\n    {\n    }\n\n    void checkCtorConstInit()\n    {\n    }\n\n    /****************************************\n     * Add documentation comment to Dsymbol.\n     * Ignore NULL comments.\n     */\n    void addComment(const(char)* comment)\n    {\n        //if (comment)\n        //    printf(\"adding comment '%s' to symbol %p '%s'\\n\", comment, this, toChars());\n        if (!this.comment)\n            this.comment = comment;\n        else if (comment && strcmp(cast(char*)comment, cast(char*)this.comment) != 0)\n        {\n            // Concatenate the two\n            this.comment = Lexer.combineComments(this.comment, comment, true);\n        }\n    }\n\n    /****************************************\n     * Returns true if this symbol is defined in a non-root module without instantiation.\n     */\n    final bool inNonRoot()\n    {\n        Dsymbol s = parent;\n        for (; s; s = s.toParent())\n        {\n            if (auto ti = s.isTemplateInstance())\n            {\n                return false;\n            }\n            if (auto m = s.isModule())\n            {\n                if (!m.isRoot())\n                    return true;\n                break;\n            }\n        }\n        return false;\n    }\n\n    // Eliminate need for dynamic_cast\n    inout(Package) isPackage() inout\n    {\n        return null;\n    }\n\n    inout(Module) isModule() inout\n    {\n        return null;\n    }\n\n    inout(EnumMember) isEnumMember() inout\n    {\n        return null;\n    }\n\n    inout(TemplateDeclaration) isTemplateDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(TemplateInstance) isTemplateInstance() inout\n    {\n        return null;\n    }\n\n    inout(TemplateMixin) isTemplateMixin() inout\n    {\n        return null;\n    }\n\n    inout(ForwardingAttribDeclaration) isForwardingAttribDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(Nspace) isNspace() inout\n    {\n        return null;\n    }\n\n    inout(Declaration) isDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(StorageClassDeclaration) isStorageClassDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(ThisDeclaration) isThisDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(TypeInfoDeclaration) isTypeInfoDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(TupleDeclaration) isTupleDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(AliasDeclaration) isAliasDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(AggregateDeclaration) isAggregateDeclaration() inout pure nothrow @safe @nogc\n    {\n        return null;\n    }\n\n    inout(FuncDeclaration) isFuncDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(FuncAliasDeclaration) isFuncAliasDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(OverDeclaration) isOverDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(FuncLiteralDeclaration) isFuncLiteralDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(CtorDeclaration) isCtorDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(PostBlitDeclaration) isPostBlitDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(DtorDeclaration) isDtorDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(StaticCtorDeclaration) isStaticCtorDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(StaticDtorDeclaration) isStaticDtorDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(SharedStaticCtorDeclaration) isSharedStaticCtorDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(SharedStaticDtorDeclaration) isSharedStaticDtorDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(InvariantDeclaration) isInvariantDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(UnitTestDeclaration) isUnitTestDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(NewDeclaration) isNewDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(VarDeclaration) isVarDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(ClassDeclaration) isClassDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(StructDeclaration) isStructDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(UnionDeclaration) isUnionDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(InterfaceDeclaration) isInterfaceDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(ScopeDsymbol) isScopeDsymbol() inout\n    {\n        return null;\n    }\n\n    inout(ForwardingScopeDsymbol) isForwardingScopeDsymbol() inout\n    {\n        return null;\n    }\n\n    inout(WithScopeSymbol) isWithScopeSymbol() inout\n    {\n        return null;\n    }\n\n    inout(ArrayScopeSymbol) isArrayScopeSymbol() inout\n    {\n        return null;\n    }\n\n    inout(Import) isImport() inout\n    {\n        return null;\n    }\n\n    inout(EnumDeclaration) isEnumDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(DeleteDeclaration) isDeleteDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(SymbolDeclaration) isSymbolDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(AttribDeclaration) isAttribDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(AnonDeclaration) isAnonDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(ProtDeclaration) isProtDeclaration() inout\n    {\n        return null;\n    }\n\n    inout(OverloadSet) isOverloadSet() inout\n    {\n        return null;\n    }\n\n    /************\n     */\n    void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Dsymbol that generates a scope\n */\nextern (C++) class ScopeDsymbol : Dsymbol\n{\n    Dsymbols* members;          // all Dsymbol's in this scope\n    DsymbolTable symtab;        // members[] sorted into table\n    uint endlinnum;             // the linnumber of the statement after the scope (0 if unknown)\n\nprivate:\n    /// symbols whose members have been imported, i.e. imported modules and template mixins\n    Dsymbols* importedScopes;\n    Prot.Kind* prots;            // array of Prot.Kind, one for each import\n\n    import dmd.root.array : BitArray;\n    BitArray accessiblePackages, privateAccessiblePackages;// whitelists of accessible (imported) packages\n\npublic:\n    final extern (D) this()\n    {\n    }\n\n    final extern (D) this(Identifier id)\n    {\n        super(id);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        //printf(\"ScopeDsymbol::syntaxCopy('%s')\\n\", toChars());\n        ScopeDsymbol sds = s ? cast(ScopeDsymbol)s : new ScopeDsymbol(ident);\n        sds.members = arraySyntaxCopy(members);\n        sds.endlinnum = endlinnum;\n        return sds;\n    }\n\n    /*****************************************\n     * This function is #1 on the list of functions that eat cpu time.\n     * Be very, very careful about slowing it down.\n     */\n    override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)\n    {\n        //printf(\"%s.ScopeDsymbol::search(ident='%s', flags=x%x)\\n\", toChars(), ident.toChars(), flags);\n        //if (strcmp(ident.toChars(),\"c\") == 0) *(char*)0=0;\n\n        // Look in symbols declared in this module\n        if (symtab && !(flags & SearchImportsOnly))\n        {\n            //printf(\" look in locals\\n\");\n            auto s1 = symtab.lookup(ident);\n            if (s1)\n            {\n                //printf(\"\\tfound in locals = '%s.%s'\\n\",toChars(),s1.toChars());\n                return s1;\n            }\n        }\n        //printf(\" not found in locals\\n\");\n\n        // Look in imported scopes\n        if (importedScopes)\n        {\n            //printf(\" look in imports\\n\");\n            Dsymbol s = null;\n            OverloadSet a = null;\n            // Look in imported modules\n            for (size_t i = 0; i < importedScopes.dim; i++)\n            {\n                // If private import, don't search it\n                if ((flags & IgnorePrivateImports) && prots[i] == Prot.Kind.private_)\n                    continue;\n                int sflags = flags & (IgnoreErrors | IgnoreAmbiguous | IgnoreSymbolVisibility); // remember these in recursive searches\n                Dsymbol ss = (*importedScopes)[i];\n                //printf(\"\\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\\n\", ss.toChars(), prots[i], ss.isModule(), ss.isImport());\n\n                if (ss.isModule())\n                {\n                    if (flags & SearchLocalsOnly)\n                        continue;\n                }\n                else // mixin template\n                {\n                    if (flags & SearchImportsOnly)\n                        continue;\n                    // compatibility with -transition=import\n                    // https://issues.dlang.org/show_bug.cgi?id=15925\n                    // SearchLocalsOnly should always get set for new lookup rules\n                    sflags |= (flags & SearchLocalsOnly);\n                }\n\n                /* Don't find private members if ss is a module\n                 */\n                Dsymbol s2 = ss.search(loc, ident, sflags | (ss.isModule() ? IgnorePrivateImports : IgnoreNone));\n                import dmd.access : symbolIsVisible;\n                if (!s2 || !(flags & IgnoreSymbolVisibility) && !symbolIsVisible(this, s2))\n                    continue;\n                if (!s)\n                {\n                    s = s2;\n                    if (s && s.isOverloadSet())\n                        a = mergeOverloadSet(ident, a, s);\n                }\n                else if (s2 && s != s2)\n                {\n                    if (s.toAlias() == s2.toAlias() || s.getType() == s2.getType() && s.getType())\n                    {\n                        /* After following aliases, we found the same\n                         * symbol, so it's not an ambiguity.  But if one\n                         * alias is deprecated or less accessible, prefer\n                         * the other.\n                         */\n                        if (s.isDeprecated() || s.prot().isMoreRestrictiveThan(s2.prot()) && s2.prot().kind != Prot.Kind.none)\n                            s = s2;\n                    }\n                    else\n                    {\n                        /* Two imports of the same module should be regarded as\n                         * the same.\n                         */\n                        Import i1 = s.isImport();\n                        Import i2 = s2.isImport();\n                        if (!(i1 && i2 && (i1.mod == i2.mod || (!i1.parent.isImport() && !i2.parent.isImport() && i1.ident.equals(i2.ident)))))\n                        {\n                            /* https://issues.dlang.org/show_bug.cgi?id=8668\n                             * Public selective import adds AliasDeclaration in module.\n                             * To make an overload set, resolve aliases in here and\n                             * get actual overload roots which accessible via s and s2.\n                             */\n                            s = s.toAlias();\n                            s2 = s2.toAlias();\n                            /* If both s2 and s are overloadable (though we only\n                             * need to check s once)\n                             */\n\n                            if ((s2.isOverloadSet() || s2.isOverloadable()) && (a || s.isOverloadable()))\n                            {\n                                if (symbolIsVisible(this, s2))\n                                {\n                                    a = mergeOverloadSet(ident, a, s2);\n                                }\n                                if (!symbolIsVisible(this, s))\n                                    s = s2;\n                                continue;\n                            }\n                            if (flags & IgnoreAmbiguous) // if return NULL on ambiguity\n                                return null;\n                            if (!(flags & IgnoreErrors))\n                                ScopeDsymbol.multiplyDefined(loc, s, s2);\n                            break;\n                        }\n                    }\n                }\n            }\n            if (s)\n            {\n                /* Build special symbol if we had multiple finds\n                 */\n                if (a)\n                {\n                    if (!s.isOverloadSet())\n                        a = mergeOverloadSet(ident, a, s);\n                    s = a;\n                }\n                // TODO: remove once private symbol visibility has been deprecated\n                if (!(flags & IgnoreErrors) && s.prot().kind == Prot.Kind.private_ &&\n                    !s.isOverloadable() && !s.parent.isTemplateMixin() && !s.parent.isNspace())\n                {\n                    AliasDeclaration ad = void;\n                    // accessing private selective and renamed imports is\n                    // deprecated by restricting the symbol visibility\n                    if (s.isImport() || (ad = s.isAliasDeclaration()) !is null && ad._import !is null)\n                    {}\n                    else\n                        error(loc, \"%s `%s` is `private`\", s.kind(), s.toPrettyChars());\n                }\n                //printf(\"\\tfound in imports %s.%s\\n\", toChars(), s.toChars());\n                return s;\n            }\n            //printf(\" not found in imports\\n\");\n        }\n        return null;\n    }\n\n    final OverloadSet mergeOverloadSet(Identifier ident, OverloadSet os, Dsymbol s)\n    {\n        if (!os)\n        {\n            os = new OverloadSet(ident);\n            os.parent = this;\n        }\n        if (OverloadSet os2 = s.isOverloadSet())\n        {\n            // Merge the cross-module overload set 'os2' into 'os'\n            if (os.a.dim == 0)\n            {\n                os.a.setDim(os2.a.dim);\n                memcpy(os.a.tdata(), os2.a.tdata(), (os.a[0]).sizeof * os2.a.dim);\n            }\n            else\n            {\n                for (size_t i = 0; i < os2.a.dim; i++)\n                {\n                    os = mergeOverloadSet(ident, os, os2.a[i]);\n                }\n            }\n        }\n        else\n        {\n            assert(s.isOverloadable());\n            /* Don't add to os[] if s is alias of previous sym\n             */\n            for (size_t j = 0; j < os.a.dim; j++)\n            {\n                Dsymbol s2 = os.a[j];\n                if (s.toAlias() == s2.toAlias())\n                {\n                    if (s2.isDeprecated() || (s2.prot().isMoreRestrictiveThan(s.prot()) && s.prot().kind != Prot.Kind.none))\n                    {\n                        os.a[j] = s;\n                    }\n                    goto Lcontinue;\n                }\n            }\n            os.push(s);\n        Lcontinue:\n        }\n        return os;\n    }\n\n    void importScope(Dsymbol s, Prot protection)\n    {\n        //printf(\"%s.ScopeDsymbol::importScope(%s, %d)\\n\", toChars(), s.toChars(), protection);\n        // No circular or redundant import's\n        if (s != this)\n        {\n            if (!importedScopes)\n                importedScopes = new Dsymbols();\n            else\n            {\n                for (size_t i = 0; i < importedScopes.dim; i++)\n                {\n                    Dsymbol ss = (*importedScopes)[i];\n                    if (ss == s) // if already imported\n                    {\n                        if (protection.kind > prots[i])\n                            prots[i] = protection.kind; // upgrade access\n                        return;\n                    }\n                }\n            }\n            importedScopes.push(s);\n            prots = cast(Prot.Kind*)mem.xrealloc(prots, importedScopes.dim * (prots[0]).sizeof);\n            prots[importedScopes.dim - 1] = protection.kind;\n        }\n    }\n\n    final void addAccessiblePackage(Package p, Prot protection)\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=17991\n        // An import of truly empty file/package can happen\n        if (p is null)\n            return;\n        auto pary = protection.kind == Prot.Kind.private_ ? &privateAccessiblePackages : &accessiblePackages;\n        if (pary.length <= p.tag)\n            pary.length = p.tag + 1;\n        (*pary)[p.tag] = true;\n    }\n\n    bool isPackageAccessible(Package p, Prot protection, int flags = 0)\n    {\n        if (p.tag < accessiblePackages.length && accessiblePackages[p.tag] ||\n            protection.kind == Prot.Kind.private_ && p.tag < privateAccessiblePackages.length && privateAccessiblePackages[p.tag])\n            return true;\n        foreach (i, ss; importedScopes ? (*importedScopes)[] : null)\n        {\n            // only search visible scopes && imported modules should ignore private imports\n            if (protection.kind <= prots[i] &&\n                ss.isScopeDsymbol.isPackageAccessible(p, protection, IgnorePrivateImports))\n                return true;\n        }\n        return false;\n    }\n\n    override final bool isforwardRef()\n    {\n        return (members is null);\n    }\n\n    static void multiplyDefined(const ref Loc loc, Dsymbol s1, Dsymbol s2)\n    {\n        version (none)\n        {\n            printf(\"ScopeDsymbol::multiplyDefined()\\n\");\n            printf(\"s1 = %p, '%s' kind = '%s', parent = %s\\n\", s1, s1.toChars(), s1.kind(), s1.parent ? s1.parent.toChars() : \"\");\n            printf(\"s2 = %p, '%s' kind = '%s', parent = %s\\n\", s2, s2.toChars(), s2.kind(), s2.parent ? s2.parent.toChars() : \"\");\n        }\n        if (loc.isValid())\n        {\n            .error(loc, \"`%s` at %s conflicts with `%s` at %s\", s1.toPrettyChars(), s1.locToChars(), s2.toPrettyChars(), s2.locToChars());\n        }\n        else\n        {\n            s1.error(s1.loc, \"conflicts with %s `%s` at %s\", s2.kind(), s2.toPrettyChars(), s2.locToChars());\n        }\n    }\n\n    override const(char)* kind() const\n    {\n        return \"ScopeDsymbol\";\n    }\n\n    /*******************************************\n     * Look for member of the form:\n     *      const(MemberInfo)[] getMembers(string);\n     * Returns NULL if not found\n     */\n    final FuncDeclaration findGetMembers()\n    {\n        Dsymbol s = search_function(this, Id.getmembers);\n        FuncDeclaration fdx = s ? s.isFuncDeclaration() : null;\n        version (none)\n        {\n            // Finish\n            __gshared TypeFunction tfgetmembers;\n            if (!tfgetmembers)\n            {\n                Scope sc;\n                auto parameters = new Parameters();\n                Parameters* p = new Parameter(STC.in_, Type.tchar.constOf().arrayOf(), null, null);\n                parameters.push(p);\n                Type tret = null;\n                tfgetmembers = new TypeFunction(parameters, tret, 0, LINK.d);\n                tfgetmembers = cast(TypeFunction)tfgetmembers.dsymbolSemantic(Loc.initial, &sc);\n            }\n            if (fdx)\n                fdx = fdx.overloadExactMatch(tfgetmembers);\n        }\n        if (fdx && fdx.isVirtual())\n            fdx = null;\n        return fdx;\n    }\n\n    Dsymbol symtabInsert(Dsymbol s)\n    {\n        return symtab.insert(s);\n    }\n\n    /****************************************\n     * Look up identifier in symbol table.\n     */\n\n    Dsymbol symtabLookup(Dsymbol s, Identifier id)\n    {\n        return symtab.lookup(id);\n    }\n\n    /****************************************\n     * Return true if any of the members are static ctors or static dtors, or if\n     * any members have members that are.\n     */\n    override bool hasStaticCtorOrDtor()\n    {\n        if (members)\n        {\n            for (size_t i = 0; i < members.dim; i++)\n            {\n                Dsymbol member = (*members)[i];\n                if (member.hasStaticCtorOrDtor())\n                    return true;\n            }\n        }\n        return false;\n    }\n\n    extern (D) alias ForeachDg = int delegate(size_t idx, Dsymbol s);\n\n    /***************************************\n     * Expands attribute declarations in members in depth first\n     * order. Calls dg(size_t symidx, Dsymbol *sym) for each\n     * member.\n     * If dg returns !=0, stops and returns that value else returns 0.\n     * Use this function to avoid the O(N + N^2/2) complexity of\n     * calculating dim and calling N times getNth.\n     * Returns:\n     *  last value returned by dg()\n     */\n    extern (D) static int _foreach(Scope* sc, Dsymbols* members, scope ForeachDg dg, size_t* pn = null)\n    {\n        assert(dg);\n        if (!members)\n            return 0;\n        size_t n = pn ? *pn : 0; // take over index\n        int result = 0;\n        foreach (size_t i; 0 .. members.dim)\n        {\n            Dsymbol s = (*members)[i];\n            if (AttribDeclaration a = s.isAttribDeclaration())\n                result = _foreach(sc, a.include(sc), dg, &n);\n            else if (TemplateMixin tm = s.isTemplateMixin())\n                result = _foreach(sc, tm.members, dg, &n);\n            else if (s.isTemplateInstance())\n            {\n            }\n            else if (s.isUnitTestDeclaration())\n            {\n            }\n            else\n                result = dg(n++, s);\n            if (result)\n                break;\n        }\n        if (pn)\n            *pn = n; // update index\n        return result;\n    }\n\n    override final inout(ScopeDsymbol) isScopeDsymbol() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * With statement scope\n */\nextern (C++) final class WithScopeSymbol : ScopeDsymbol\n{\n    WithStatement withstate;\n\n    extern (D) this(WithStatement withstate)\n    {\n        this.withstate = withstate;\n    }\n\n    override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)\n    {\n        //printf(\"WithScopeSymbol.search(%s)\\n\", ident.toChars());\n        if (flags & SearchImportsOnly)\n            return null;\n        // Acts as proxy to the with class declaration\n        Dsymbol s = null;\n        Expression eold = null;\n        for (Expression e = withstate.exp; e != eold; e = resolveAliasThis(_scope, e))\n        {\n            if (e.op == TOK.scope_)\n            {\n                s = (cast(ScopeExp)e).sds;\n            }\n            else if (e.op == TOK.type)\n            {\n                s = e.type.toDsymbol(null);\n            }\n            else\n            {\n                Type t = e.type.toBasetype();\n                s = t.toDsymbol(null);\n            }\n            if (s)\n            {\n                s = s.search(loc, ident, flags);\n                if (s)\n                    return s;\n            }\n            eold = e;\n        }\n        return null;\n    }\n\n    override inout(WithScopeSymbol) isWithScopeSymbol() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Array Index/Slice scope\n */\nextern (C++) final class ArrayScopeSymbol : ScopeDsymbol\n{\n    Expression exp;         // IndexExp or SliceExp\n    TypeTuple type;         // for tuple[length]\n    TupleDeclaration td;    // for tuples of objects\n    Scope* sc;\n\n    extern (D) this(Scope* sc, Expression e)\n    {\n        assert(e.op == TOK.index || e.op == TOK.slice || e.op == TOK.array);\n        exp = e;\n        this.sc = sc;\n    }\n\n    extern (D) this(Scope* sc, TypeTuple t)\n    {\n        type = t;\n        this.sc = sc;\n    }\n\n    extern (D) this(Scope* sc, TupleDeclaration s)\n    {\n        td = s;\n        this.sc = sc;\n    }\n\n    override Dsymbol search(const ref Loc loc, Identifier ident, int flags = IgnoreNone)\n    {\n        //printf(\"ArrayScopeSymbol::search('%s', flags = %d)\\n\", ident.toChars(), flags);\n        if (ident == Id.dollar)\n        {\n            VarDeclaration* pvar;\n            Expression ce;\n        L1:\n            if (td)\n            {\n                /* $ gives the number of elements in the tuple\n                 */\n                auto v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null);\n                Expression e = new IntegerExp(Loc.initial, td.objects.dim, Type.tsize_t);\n                v._init = new ExpInitializer(Loc.initial, e);\n                v.storage_class |= STC.temp | STC.static_ | STC.const_;\n                v.dsymbolSemantic(sc);\n                return v;\n            }\n            if (type)\n            {\n                /* $ gives the number of type entries in the type tuple\n                 */\n                auto v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null);\n                Expression e = new IntegerExp(Loc.initial, type.arguments.dim, Type.tsize_t);\n                v._init = new ExpInitializer(Loc.initial, e);\n                v.storage_class |= STC.temp | STC.static_ | STC.const_;\n                v.dsymbolSemantic(sc);\n                return v;\n            }\n            if (exp.op == TOK.index)\n            {\n                /* array[index] where index is some function of $\n                 */\n                IndexExp ie = cast(IndexExp)exp;\n                pvar = &ie.lengthVar;\n                ce = ie.e1;\n            }\n            else if (exp.op == TOK.slice)\n            {\n                /* array[lwr .. upr] where lwr or upr is some function of $\n                 */\n                SliceExp se = cast(SliceExp)exp;\n                pvar = &se.lengthVar;\n                ce = se.e1;\n            }\n            else if (exp.op == TOK.array)\n            {\n                /* array[e0, e1, e2, e3] where e0, e1, e2 are some function of $\n                 * $ is a opDollar!(dim)() where dim is the dimension(0,1,2,...)\n                 */\n                ArrayExp ae = cast(ArrayExp)exp;\n                pvar = &ae.lengthVar;\n                ce = ae.e1;\n            }\n            else\n            {\n                /* Didn't find $, look in enclosing scope(s).\n                 */\n                return null;\n            }\n            while (ce.op == TOK.comma)\n                ce = (cast(CommaExp)ce).e2;\n            /* If we are indexing into an array that is really a type\n             * tuple, rewrite this as an index into a type tuple and\n             * try again.\n             */\n            if (ce.op == TOK.type)\n            {\n                Type t = (cast(TypeExp)ce).type;\n                if (t.ty == Ttuple)\n                {\n                    type = cast(TypeTuple)t;\n                    goto L1;\n                }\n            }\n            /* *pvar is lazily initialized, so if we refer to $\n             * multiple times, it gets set only once.\n             */\n            if (!*pvar) // if not already initialized\n            {\n                /* Create variable v and set it to the value of $\n                 */\n                VarDeclaration v;\n                Type t;\n                if (ce.op == TOK.tuple)\n                {\n                    /* It is for an expression tuple, so the\n                     * length will be a const.\n                     */\n                    Expression e = new IntegerExp(Loc.initial, (cast(TupleExp)ce).exps.dim, Type.tsize_t);\n                    v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, new ExpInitializer(Loc.initial, e));\n                    v.storage_class |= STC.temp | STC.static_ | STC.const_;\n                }\n                else if (ce.type && (t = ce.type.toBasetype()) !is null && (t.ty == Tstruct || t.ty == Tclass))\n                {\n                    // Look for opDollar\n                    assert(exp.op == TOK.array || exp.op == TOK.slice);\n                    AggregateDeclaration ad = isAggregate(t);\n                    assert(ad);\n                    Dsymbol s = ad.search(loc, Id.opDollar);\n                    if (!s) // no dollar exists -- search in higher scope\n                        return null;\n                    s = s.toAlias();\n                    Expression e = null;\n                    // Check for multi-dimensional opDollar(dim) template.\n                    if (TemplateDeclaration td = s.isTemplateDeclaration())\n                    {\n                        dinteger_t dim = 0;\n                        if (exp.op == TOK.array)\n                        {\n                            dim = (cast(ArrayExp)exp).currentDimension;\n                        }\n                        else if (exp.op == TOK.slice)\n                        {\n                            dim = 0; // slices are currently always one-dimensional\n                        }\n                        else\n                        {\n                            assert(0);\n                        }\n                        auto tiargs = new Objects();\n                        Expression edim = new IntegerExp(Loc.initial, dim, Type.tsize_t);\n                        edim = edim.expressionSemantic(sc);\n                        tiargs.push(edim);\n                        e = new DotTemplateInstanceExp(loc, ce, td.ident, tiargs);\n                    }\n                    else\n                    {\n                        /* opDollar exists, but it's not a template.\n                         * This is acceptable ONLY for single-dimension indexing.\n                         * Note that it's impossible to have both template & function opDollar,\n                         * because both take no arguments.\n                         */\n                        if (exp.op == TOK.array && (cast(ArrayExp)exp).arguments.dim != 1)\n                        {\n                            exp.error(\"`%s` only defines opDollar for one dimension\", ad.toChars());\n                            return null;\n                        }\n                        Declaration d = s.isDeclaration();\n                        assert(d);\n                        e = new DotVarExp(loc, ce, d);\n                    }\n                    e = e.expressionSemantic(sc);\n                    if (!e.type)\n                        exp.error(\"`%s` has no value\", e.toChars());\n                    t = e.type.toBasetype();\n                    if (t && t.ty == Tfunction)\n                        e = new CallExp(e.loc, e);\n                    v = new VarDeclaration(loc, null, Id.dollar, new ExpInitializer(Loc.initial, e));\n                    v.storage_class |= STC.temp | STC.ctfe | STC.rvalue;\n                }\n                else\n                {\n                    /* For arrays, $ will either be a compile-time constant\n                     * (in which case its value in set during constant-folding),\n                     * or a variable (in which case an expression is created in\n                     * toir.c).\n                     */\n                    auto e = new VoidInitializer(Loc.initial);\n                    e.type = Type.tsize_t;\n                    v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, e);\n                    v.storage_class |= STC.temp | STC.ctfe; // it's never a true static variable\n                }\n                *pvar = v;\n            }\n            (*pvar).dsymbolSemantic(sc);\n            return (*pvar);\n        }\n        return null;\n    }\n\n    override inout(ArrayScopeSymbol) isArrayScopeSymbol() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Overload Sets\n */\nextern (C++) final class OverloadSet : Dsymbol\n{\n    Dsymbols a;     // array of Dsymbols\n\n    extern (D) this(Identifier ident, OverloadSet os = null)\n    {\n        super(ident);\n        if (os)\n        {\n            for (size_t i = 0; i < os.a.dim; i++)\n                a.push(os.a[i]);\n        }\n    }\n\n    void push(Dsymbol s)\n    {\n        a.push(s);\n    }\n\n    override inout(OverloadSet) isOverloadSet() inout\n    {\n        return this;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"overloadset\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Forwarding ScopeDsymbol.  Used by ForwardingAttribDeclaration and\n * ForwardingScopeDeclaration to forward symbol insertions to another\n * scope.  See `dmd.attrib.ForwardingAttribDeclaration` for more\n * details.\n */\nextern (C++) final class ForwardingScopeDsymbol : ScopeDsymbol\n{\n    /*************************\n     * Symbol to forward insertions to.\n     * Can be `null` before being lazily initialized.\n     */\n    ScopeDsymbol forward;\n    extern (D) this(ScopeDsymbol forward)\n    {\n        super(null);\n        this.forward = forward;\n    }\n    override Dsymbol symtabInsert(Dsymbol s)\n    {\n        assert(forward);\n        if (auto d = s.isDeclaration())\n        {\n            if (d.storage_class & STC.local)\n            {\n                // Symbols with storage class STC.local are not\n                // forwarded, but stored in the local symbol\n                // table. (Those are the `static foreach` variables.)\n                if (!symtab)\n                {\n                    symtab = new DsymbolTable();\n                }\n                return super.symtabInsert(s); // insert locally\n            }\n        }\n        if (!forward.symtab)\n        {\n            forward.symtab = new DsymbolTable();\n        }\n        // Non-STC.local symbols are forwarded to `forward`.\n        return forward.symtabInsert(s);\n    }\n\n    /************************\n     * This override handles the following two cases:\n     *     static foreach (i, i; [0]) { ... }\n     * and\n     *     static foreach (i; [0]) { enum i = 2; }\n     */\n    override Dsymbol symtabLookup(Dsymbol s, Identifier id)\n    {\n        assert(forward);\n        // correctly diagnose clashing foreach loop variables.\n        if (auto d = s.isDeclaration())\n        {\n            if (d.storage_class & STC.local)\n            {\n                if (!symtab)\n                {\n                    symtab = new DsymbolTable();\n                }\n                return super.symtabLookup(s,id);\n            }\n        }\n        // Declarations within `static foreach` do not clash with\n        // `static foreach` loop variables.\n        if (!forward.symtab)\n        {\n            forward.symtab = new DsymbolTable();\n        }\n        return forward.symtabLookup(s,id);\n    }\n\n    override void importScope(Dsymbol s, Prot protection)\n    {\n        forward.importScope(s, protection);\n    }\n\n    override const(char)* kind()const{ return \"local scope\"; }\n\n    override inout(ForwardingScopeDsymbol) isForwardingScopeDsymbol() inout\n    {\n        return this;\n    }\n\n}\n\n\n/***********************************************************\n * Table of Dsymbol's\n */\nextern (C++) final class DsymbolTable : RootObject\n{\n    AssocArray!(Identifier, Dsymbol) tab;\n\n    // Look up Identifier. Return Dsymbol if found, NULL if not.\n    Dsymbol lookup(const Identifier ident)\n    {\n        //printf(\"DsymbolTable::lookup(%s)\\n\", ident.toChars());\n        return tab[ident];\n    }\n\n    // Insert Dsymbol in table. Return NULL if already there.\n    Dsymbol insert(Dsymbol s)\n    {\n        //printf(\"DsymbolTable::insert(this = %p, '%s')\\n\", this, s.ident.toChars());\n        const ident = s.ident;\n        Dsymbol* ps = tab.getLvalue(ident);\n        if (*ps)\n            return null; // already in table\n        *ps = s;\n        return s;\n    }\n\n    // Look for Dsymbol in table. If there, return it. If not, insert s and return that.\n    Dsymbol update(Dsymbol s)\n    {\n        const ident = s.ident;\n        Dsymbol* ps = tab.getLvalue(ident);\n        *ps = s;\n        return s;\n    }\n\n    // when ident and s are not the same\n    Dsymbol insert(const Identifier ident, Dsymbol s)\n    {\n        //printf(\"DsymbolTable::insert()\\n\");\n        Dsymbol* ps = tab.getLvalue(ident);\n        if (*ps)\n            return null; // already in table\n        *ps = s;\n        return s;\n    }\n\n    /*****\n     * Returns:\n     *  number of symbols in symbol table\n     */\n    uint len() const pure\n    {\n        return cast(uint)tab.length;\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/dsymbol.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/dsymbol.h\n */\n\n#pragma once\n\n#include \"root/port.h\"\n#include \"globals.h\"\n#include \"arraytypes.h\"\n#include \"visitor.h\"\n\nclass Identifier;\nstruct Scope;\nclass DsymbolTable;\nclass Declaration;\nclass ThisDeclaration;\nclass TypeInfoDeclaration;\nclass TupleDeclaration;\nclass AliasDeclaration;\nclass AggregateDeclaration;\nclass EnumDeclaration;\nclass ClassDeclaration;\nclass InterfaceDeclaration;\nclass StructDeclaration;\nclass UnionDeclaration;\nclass FuncDeclaration;\nclass FuncAliasDeclaration;\nclass OverDeclaration;\nclass FuncLiteralDeclaration;\nclass CtorDeclaration;\nclass PostBlitDeclaration;\nclass DtorDeclaration;\nclass StaticCtorDeclaration;\nclass StaticDtorDeclaration;\nclass SharedStaticCtorDeclaration;\nclass SharedStaticDtorDeclaration;\nclass InvariantDeclaration;\nclass UnitTestDeclaration;\nclass NewDeclaration;\nclass VarDeclaration;\nclass AttribDeclaration;\nclass ProtDeclaration;\nclass Package;\nclass Module;\nclass Import;\nclass Type;\nclass TypeTuple;\nclass WithStatement;\nclass LabelDsymbol;\nclass ScopeDsymbol;\nclass ForwardingScopeDsymbol;\nclass TemplateDeclaration;\nclass TemplateInstance;\nclass TemplateMixin;\nclass ForwardingAttribDeclaration;\nclass Nspace;\nclass EnumMember;\nclass WithScopeSymbol;\nclass ArrayScopeSymbol;\nclass SymbolDeclaration;\nclass Expression;\nclass DeleteDeclaration;\nclass OverloadSet;\nstruct AA;\n#ifdef IN_GCC\ntypedef union tree_node Symbol;\n#else\nstruct Symbol;\n#endif\n\nstruct Ungag\n{\n    unsigned oldgag;\n\n    Ungag(unsigned old) : oldgag(old) {}\n    ~Ungag() { global.gag = oldgag; }\n};\n\nvoid dsymbolSemantic(Dsymbol *dsym, Scope *sc);\nvoid semantic2(Dsymbol *dsym, Scope *sc);\nvoid semantic3(Dsymbol *dsym, Scope* sc);\n\nstruct Prot\n{\n    enum Kind\n    {\n        undefined,\n        none,           // no access\n        private_,\n        package_,\n        protected_,\n        public_,\n        export_\n    };\n    Kind kind;\n    Package *pkg;\n\n    bool isMoreRestrictiveThan(const Prot other) const;\n    bool isSubsetOf(const Prot& other) const;\n};\n\n/* State of symbol in winding its way through the passes of the compiler\n */\nenum PASS\n{\n    PASSinit,           // initial state\n    PASSsemantic,       // semantic() started\n    PASSsemanticdone,   // semantic() done\n    PASSsemantic2,      // semantic2() started\n    PASSsemantic2done,  // semantic2() done\n    PASSsemantic3,      // semantic3() started\n    PASSsemantic3done,  // semantic3() done\n    PASSinline,         // inline started\n    PASSinlinedone,     // inline done\n    PASSobj             // toObjFile() run\n};\n\n/* Flags for symbol search\n */\nenum\n{\n    IgnoreNone              = 0x00, // default\n    IgnorePrivateImports    = 0x01, // don't search private imports\n    IgnoreErrors            = 0x02, // don't give error messages\n    IgnoreAmbiguous         = 0x04, // return NULL if ambiguous\n    SearchLocalsOnly        = 0x08, // only look at locals (don't search imports)\n    SearchImportsOnly       = 0x10, // only look in imports\n    SearchUnqualifiedModule = 0x20, // the module scope search is unqualified,\n                                    // meaning don't search imports in that scope,\n                                    // because qualified module searches search\n                                    // their imports\n    IgnoreSymbolVisibility  = 0x80  // also find private and package protected symbols\n};\n\ntypedef int (*Dsymbol_apply_ft_t)(Dsymbol *, void *);\n\nclass Dsymbol : public RootObject\n{\npublic:\n    Identifier *ident;\n    Dsymbol *parent;\n    Symbol *csym;               // symbol for code generator\n    Symbol *isym;               // import version of csym\n    const utf8_t *comment;      // documentation comment for this Dsymbol\n    Loc loc;                    // where defined\n    Scope *_scope;               // !=NULL means context to use for semantic()\n    const utf8_t *prettystring;\n    bool errors;                // this symbol failed to pass semantic()\n    PASS semanticRun;\n    DeprecatedDeclaration *depdecl; // customized deprecation message\n    UserAttributeDeclaration *userAttribDecl;   // user defined attributes\n    UnitTestDeclaration *ddocUnittest; // !=NULL means there's a ddoc unittest associated with this symbol (only use this with ddoc)\n\n    static Dsymbol *create(Identifier *);\n    const char *toChars();\n    virtual const char *toPrettyCharsHelper(); // helper to print fully qualified (template) arguments\n    Loc& getLoc();\n    const char *locToChars();\n    bool equals(RootObject *o);\n    virtual bool isAnonymous();\n    void error(Loc loc, const char *format, ...);\n    void error(const char *format, ...);\n    void deprecation(const Loc &loc, const char *format, ...);\n    void deprecation(const char *format, ...);\n    bool checkDeprecated(const Loc &loc, Scope *sc);\n    Module *getModule();\n    Module *getAccessModule();\n    Dsymbol *pastMixin();\n    Dsymbol *toParent();\n    Dsymbol *toParent2();\n    TemplateInstance *isInstantiated();\n    TemplateInstance *isSpeculative();\n    Ungag ungagSpeculative();\n\n    // kludge for template.isSymbol()\n    int dyncast() const { return DYNCAST_DSYMBOL; }\n\n    virtual Identifier *getIdent();\n    virtual const char *toPrettyChars(bool QualifyTypes = false);\n    virtual const char *kind() const;\n    virtual Dsymbol *toAlias();                 // resolve real symbol\n    virtual Dsymbol *toAlias2();\n    virtual int apply(Dsymbol_apply_ft_t fp, void *param);\n    virtual void addMember(Scope *sc, ScopeDsymbol *sds);\n    virtual void setScope(Scope *sc);\n    virtual void importAll(Scope *sc);\n    virtual Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone);\n    Dsymbol *search_correct(Identifier *id);\n    Dsymbol *searchX(const Loc &loc, Scope *sc, RootObject *id);\n    virtual bool overloadInsert(Dsymbol *s);\n    virtual d_uns64 size(const Loc &loc);\n    virtual bool isforwardRef();\n    virtual AggregateDeclaration *isThis();     // is a 'this' required to access the member\n    virtual bool isExport() const;              // is Dsymbol exported?\n    virtual bool isImportedSymbol() const;      // is Dsymbol imported?\n    virtual bool isDeprecated();                // is Dsymbol deprecated?\n    virtual bool isOverloadable();\n    virtual LabelDsymbol *isLabel();            // is this a LabelDsymbol?\n    AggregateDeclaration *isMember();           // is this a member of an AggregateDeclaration?\n    AggregateDeclaration *isMember2();          // is this a member of an AggregateDeclaration?\n    ClassDeclaration *isClassMember();          // is this a member of a ClassDeclaration?\n    virtual Type *getType();                    // is this a type?\n    virtual bool needThis();                    // need a 'this' pointer?\n    virtual Prot prot();\n    virtual Dsymbol *syntaxCopy(Dsymbol *s);    // copy only syntax trees\n    virtual bool oneMember(Dsymbol **ps, Identifier *ident);\n    virtual void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);\n    virtual bool hasPointers();\n    virtual bool hasStaticCtorOrDtor();\n    virtual void addLocalClass(ClassDeclarations *) { }\n    virtual void checkCtorConstInit() { }\n\n    virtual void addComment(const utf8_t *comment);\n\n    bool inNonRoot();\n\n    // Eliminate need for dynamic_cast\n    virtual Package *isPackage() { return NULL; }\n    virtual Module *isModule() { return NULL; }\n    virtual EnumMember *isEnumMember() { return NULL; }\n    virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; }\n    virtual TemplateInstance *isTemplateInstance() { return NULL; }\n    virtual TemplateMixin *isTemplateMixin() { return NULL; }\n    virtual ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return NULL; }\n    virtual Nspace *isNspace() { return NULL; }\n    virtual Declaration *isDeclaration() { return NULL; }\n    virtual StorageClassDeclaration *isStorageClassDeclaration(){ return NULL; }\n    virtual ThisDeclaration *isThisDeclaration() { return NULL; }\n    virtual TypeInfoDeclaration *isTypeInfoDeclaration() { return NULL; }\n    virtual TupleDeclaration *isTupleDeclaration() { return NULL; }\n    virtual AliasDeclaration *isAliasDeclaration() { return NULL; }\n    virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; }\n    virtual FuncDeclaration *isFuncDeclaration() { return NULL; }\n    virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; }\n    virtual OverDeclaration *isOverDeclaration() { return NULL; }\n    virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; }\n    virtual CtorDeclaration *isCtorDeclaration() { return NULL; }\n    virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; }\n    virtual DtorDeclaration *isDtorDeclaration() { return NULL; }\n    virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; }\n    virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; }\n    virtual SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return NULL; }\n    virtual SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return NULL; }\n    virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; }\n    virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; }\n    virtual NewDeclaration *isNewDeclaration() { return NULL; }\n    virtual VarDeclaration *isVarDeclaration() { return NULL; }\n    virtual ClassDeclaration *isClassDeclaration() { return NULL; }\n    virtual StructDeclaration *isStructDeclaration() { return NULL; }\n    virtual UnionDeclaration *isUnionDeclaration() { return NULL; }\n    virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; }\n    virtual ScopeDsymbol *isScopeDsymbol() { return NULL; }\n    virtual ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return NULL; }\n    virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; }\n    virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; }\n    virtual Import *isImport() { return NULL; }\n    virtual EnumDeclaration *isEnumDeclaration() { return NULL; }\n    virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; }\n    virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; }\n    virtual AttribDeclaration *isAttribDeclaration() { return NULL; }\n    virtual AnonDeclaration *isAnonDeclaration() { return NULL; }\n    virtual ProtDeclaration *isProtDeclaration() { return NULL; }\n    virtual OverloadSet *isOverloadSet() { return NULL; }\n    virtual void accept(Visitor *v) { v->visit(this); }\n};\n\n// Dsymbol that generates a scope\n\nclass ScopeDsymbol : public Dsymbol\n{\npublic:\n    Dsymbols *members;          // all Dsymbol's in this scope\n    DsymbolTable *symtab;       // members[] sorted into table\n    unsigned endlinnum;         // the linnumber of the statement after the scope (0 if unknown)\n\nprivate:\n    Dsymbols *importedScopes;   // imported Dsymbol's\n    Prot::Kind *prots;            // array of PROTKIND, one for each import\n\n    BitArray accessiblePackages, privateAccessiblePackages;\n\npublic:\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);\n    OverloadSet *mergeOverloadSet(Identifier *ident, OverloadSet *os, Dsymbol *s);\n    virtual void importScope(Dsymbol *s, Prot protection);\n    void addAccessiblePackage(Package *p, Prot protection);\n    virtual bool isPackageAccessible(Package *p, Prot protection, int flags = 0);\n    bool isforwardRef();\n    static void multiplyDefined(const Loc &loc, Dsymbol *s1, Dsymbol *s2);\n    const char *kind() const;\n    FuncDeclaration *findGetMembers();\n    virtual Dsymbol *symtabInsert(Dsymbol *s);\n    virtual Dsymbol *symtabLookup(Dsymbol *s, Identifier *id);\n    bool hasStaticCtorOrDtor();\n\n    ScopeDsymbol *isScopeDsymbol() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// With statement scope\n\nclass WithScopeSymbol : public ScopeDsymbol\n{\npublic:\n    WithStatement *withstate;\n\n    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);\n\n    WithScopeSymbol *isWithScopeSymbol() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// Array Index/Slice scope\n\nclass ArrayScopeSymbol : public ScopeDsymbol\n{\npublic:\n    Expression *exp;    // IndexExp or SliceExp\n    TypeTuple *type;    // for tuple[length]\n    TupleDeclaration *td;       // for tuples of objects\n    Scope *sc;\n\n    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone);\n\n    ArrayScopeSymbol *isArrayScopeSymbol() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// Overload Sets\n\nclass OverloadSet : public Dsymbol\n{\npublic:\n    Dsymbols a;         // array of Dsymbols\n\n    void push(Dsymbol *s);\n    OverloadSet *isOverloadSet() { return this; }\n    const char *kind() const;\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// Forwarding ScopeDsymbol\n\nclass ForwardingScopeDsymbol : public ScopeDsymbol\n{\n    ScopeDsymbol *forward;\n\n    Dsymbol *symtabInsert(Dsymbol *s);\n    Dsymbol *symtabLookup(Dsymbol *s, Identifier *id);\n    void importScope(Dsymbol *s, Prot protection);\n    const char *kind() const;\n\n    ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return this; }\n};\n\n// Table of Dsymbol's\n\nclass DsymbolTable : public RootObject\n{\npublic:\n    AA *tab;\n\n    // Look up Identifier. Return Dsymbol if found, NULL if not.\n    Dsymbol *lookup(Identifier const * const ident);\n\n    // Insert Dsymbol in table. Return NULL if already there.\n    Dsymbol *insert(Dsymbol *s);\n\n    // Look for Dsymbol in table. If there, return it. If not, insert s and return that.\n    Dsymbol *update(Dsymbol *s);\n    Dsymbol *insert(Identifier const * const ident, Dsymbol *s);     // when ident and s are not the same\n};\n"
  },
  {
    "path": "gcc/d/dmd/dsymbolsem.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dsymbolsem.d, _dsymbolsem.d)\n * Documentation:  https://dlang.org/phobos/dmd_dsymbolsem.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dsymbolsem.d\n */\n\nmodule dmd.dsymbolsem;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\n\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arraytypes;\nimport dmd.astcodegen;\nimport dmd.attrib;\nimport dmd.blockexit;\nimport dmd.clone;\nimport dmd.compiler;\nimport dmd.dcast;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dimport;\nimport dmd.dinterpret;\nimport dmd.dmangle;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dtemplate;\nimport dmd.dversion;\nimport dmd.errors;\nimport dmd.escape;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.initsem;\nimport dmd.hdrgen;\nimport dmd.mtype;\nimport dmd.nogc;\nimport dmd.nspace;\nimport dmd.objc;\nimport dmd.opover;\nimport dmd.parse;\nimport dmd.root.filename;\nimport dmd.root.outbuffer;\nimport dmd.root.rmem;\nimport dmd.root.rootobject;\nimport dmd.semantic2;\nimport dmd.semantic3;\nimport dmd.sideeffect;\nimport dmd.statementsem;\nimport dmd.staticassert;\nimport dmd.tokens;\nimport dmd.utf;\nimport dmd.utils;\nimport dmd.statement;\nimport dmd.target;\nimport dmd.templateparamsem;\nimport dmd.typesem;\nimport dmd.visitor;\n\nenum LOG = false;\n\n/*****************************************\n * Create inclusive postblit for struct by aggregating\n * all the postblits in postblits[] with the postblits for\n * all the members.\n * Note the close similarity with AggregateDeclaration::buildDtor(),\n * and the ordering changes (runs forward instead of backwards).\n */\nprivate FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)\n{\n    //printf(\"StructDeclaration::buildPostBlit() %s\\n\", sd.toChars());\n    if (sd.isUnionDeclaration())\n        return null;\n\n    // by default, the storage class of the created postblit\n    StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;\n    Loc declLoc = sd.postblits.dim ? sd.postblits[0].loc : sd.loc;\n    Loc loc; // internal code should have no loc to prevent coverage\n\n    // if any of the postblits are disabled, then the generated postblit\n    // will be disabled\n    for (size_t i = 0; i < sd.postblits.dim; i++)\n    {\n        stc |= sd.postblits[i].storage_class & STC.disable;\n    }\n\n    VarDeclaration[] fieldsToDestroy;\n    auto postblitCalls = new Statements();\n    // iterate through all the struct fields that are not disabled\n    for (size_t i = 0; i < sd.fields.dim && !(stc & STC.disable); i++)\n    {\n        auto structField = sd.fields[i];\n        if (structField.storage_class & STC.ref_)\n            continue;\n        if (structField.overlapped)\n            continue;\n        // if it's a struct declaration or an array of structs\n        Type tv = structField.type.baseElemOf();\n        if (tv.ty != Tstruct)\n            continue;\n        auto sdv = (cast(TypeStruct)tv).sym;\n        // which has a postblit declaration\n        if (!sdv.postblit)\n            continue;\n        assert(!sdv.isUnionDeclaration());\n\n        // if this field's postblit is not `nothrow`, add a `scope(failure)`\n        // block to destroy any prior successfully postblitted fields should\n        // this field's postblit fail\n        if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow)\n        {\n             // create a list of destructors that need to be called\n            Expression[] dtorCalls;\n            foreach(sf; fieldsToDestroy)\n            {\n                Expression ex;\n                tv = sf.type.toBasetype();\n                if (tv.ty == Tstruct)\n                {\n                    // this.v.__xdtor()\n\n                    ex = new ThisExp(loc);\n                    ex = new DotVarExp(loc, ex, sf);\n\n                    // This is a hack so we can call destructors on const/immutable objects.\n                    ex = new AddrExp(loc, ex);\n                    ex = new CastExp(loc, ex, sf.type.mutableOf().pointerTo());\n                    ex = new PtrExp(loc, ex);\n                    if (stc & STC.safe)\n                        stc = (stc & ~STC.safe) | STC.trusted;\n\n                    auto sfv = (cast(TypeStruct)sf.type.baseElemOf()).sym;\n\n                    ex = new DotVarExp(loc, ex, sfv.dtor, false);\n                    ex = new CallExp(loc, ex);\n\n                    dtorCalls ~= ex;\n                }\n                else\n                {\n                    // _ArrayDtor((cast(S*)this.v.ptr)[0 .. n])\n\n                    uinteger_t length = 1;\n                    while (tv.ty == Tsarray)\n                    {\n                        length *= (cast(TypeSArray)tv).dim.toUInteger();\n                        tv = tv.nextOf().toBasetype();\n                    }\n                    //if (n == 0)\n                    //    continue;\n\n                    ex = new ThisExp(loc);\n                    ex = new DotVarExp(loc, ex, sf);\n\n                    // This is a hack so we can call destructors on const/immutable objects.\n                    ex = new DotIdExp(loc, ex, Id.ptr);\n                    ex = new CastExp(loc, ex, sdv.type.pointerTo());\n                    if (stc & STC.safe)\n                        stc = (stc & ~STC.safe) | STC.trusted;\n\n                    ex = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t),\n                                            new IntegerExp(loc, length, Type.tsize_t));\n                    // Prevent redundant bounds check\n                    (cast(SliceExp)ex).upperIsInBounds = true;\n                    (cast(SliceExp)ex).lowerIsLessThanUpper = true;\n\n                    ex = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayDtor), ex);\n\n                    dtorCalls ~= ex;\n                }\n            }\n            fieldsToDestroy = [];\n\n            // aggregate the destructor calls\n            auto dtors = new Statements();\n            foreach_reverse(dc; dtorCalls)\n            {\n                dtors.push(new ExpStatement(loc, dc));\n            }\n\n            // put destructor calls in a `scope(failure)` block\n            postblitCalls.push(new OnScopeStatement(loc, TOK.onScopeFailure, new CompoundStatement(loc, dtors)));\n        }\n\n        // perform semantic on the member postblit in order to\n        // be able to aggregate it later on with the rest of the\n        // postblits\n        sdv.postblit.functionSemantic();\n\n        stc = mergeFuncAttrs(stc, sdv.postblit);\n        stc = mergeFuncAttrs(stc, sdv.dtor);\n\n        // if any of the struct member fields has disabled\n        // its postblit, then `sd` is not copyable, so no\n        // postblit is generated\n        if (stc & STC.disable)\n        {\n            postblitCalls.setDim(0);\n            break;\n        }\n\n        Expression ex;\n        tv = structField.type.toBasetype();\n        if (tv.ty == Tstruct)\n        {\n            // this.v.__xpostblit()\n\n            ex = new ThisExp(loc);\n            ex = new DotVarExp(loc, ex, structField);\n\n            // This is a hack so we can call postblits on const/immutable objects.\n            ex = new AddrExp(loc, ex);\n            ex = new CastExp(loc, ex, structField.type.mutableOf().pointerTo());\n            ex = new PtrExp(loc, ex);\n            if (stc & STC.safe)\n                stc = (stc & ~STC.safe) | STC.trusted;\n\n            ex = new DotVarExp(loc, ex, sdv.postblit, false);\n            ex = new CallExp(loc, ex);\n        }\n        else\n        {\n            // _ArrayPostblit((cast(S*)this.v.ptr)[0 .. n])\n\n            uinteger_t length = 1;\n            while (tv.ty == Tsarray)\n            {\n                length *= (cast(TypeSArray)tv).dim.toUInteger();\n                tv = tv.nextOf().toBasetype();\n            }\n            if (length == 0)\n                continue;\n\n            ex = new ThisExp(loc);\n            ex = new DotVarExp(loc, ex, structField);\n\n            // This is a hack so we can call postblits on const/immutable objects.\n            ex = new DotIdExp(loc, ex, Id.ptr);\n            ex = new CastExp(loc, ex, sdv.type.pointerTo());\n            if (stc & STC.safe)\n                stc = (stc & ~STC.safe) | STC.trusted;\n\n            ex = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t),\n                                       new IntegerExp(loc, length, Type.tsize_t));\n            // Prevent redundant bounds check\n            (cast(SliceExp)ex).upperIsInBounds = true;\n            (cast(SliceExp)ex).lowerIsLessThanUpper = true;\n            ex = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayPostblit), ex);\n        }\n        postblitCalls.push(new ExpStatement(loc, ex)); // combine in forward order\n\n        /* https://issues.dlang.org/show_bug.cgi?id=10972\n         * When subsequent field postblit calls fail,\n         * this field should be destructed for Exception Safety.\n         */\n        if (sdv.dtor)\n        {\n            sdv.dtor.functionSemantic();\n\n            // keep a list of fields that need to be destroyed in case\n            // of a future postblit failure\n            fieldsToDestroy ~= structField;\n        }\n    }\n\n    void checkShared()\n    {\n        if (sd.type.isShared())\n            stc |= STC.shared_;\n    }\n\n    // Build our own \"postblit\" which executes a, but only if needed.\n    if (postblitCalls.dim || (stc & STC.disable))\n    {\n        //printf(\"Building __fieldPostBlit()\\n\");\n        checkShared();\n        auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__fieldPostblit);\n        dd.generated = true;\n        dd.storage_class |= STC.inference;\n        dd.fbody = (stc & STC.disable) ? null : new CompoundStatement(loc, postblitCalls);\n        sd.postblits.shift(dd);\n        sd.members.push(dd);\n        dd.dsymbolSemantic(sc);\n    }\n\n    // create __xpostblit, which is the generated postblit\n    FuncDeclaration xpostblit = null;\n    switch (sd.postblits.dim)\n    {\n    case 0:\n        break;\n\n    case 1:\n        xpostblit = sd.postblits[0];\n        break;\n\n    default:\n        Expression e = null;\n        stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;\n        for (size_t i = 0; i < sd.postblits.dim; i++)\n        {\n            auto fd = sd.postblits[i];\n            stc = mergeFuncAttrs(stc, fd);\n            if (stc & STC.disable)\n            {\n                e = null;\n                break;\n            }\n            Expression ex = new ThisExp(loc);\n            ex = new DotVarExp(loc, ex, fd, false);\n            ex = new CallExp(loc, ex);\n            e = Expression.combine(e, ex);\n        }\n\n        checkShared();\n        auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__aggrPostblit);\n        dd.generated = true;\n        dd.storage_class |= STC.inference;\n        dd.fbody = new ExpStatement(loc, e);\n        sd.members.push(dd);\n        dd.dsymbolSemantic(sc);\n        xpostblit = dd;\n        break;\n    }\n\n    // Add an __xpostblit alias to make the inclusive postblit accessible\n    if (xpostblit)\n    {\n        auto _alias = new AliasDeclaration(Loc.initial, Id.__xpostblit, xpostblit);\n        _alias.dsymbolSemantic(sc);\n        sd.members.push(_alias);\n        _alias.addMember(sc, sd); // add to symbol table\n    }\n    return xpostblit;\n}\n\nprivate uint setMangleOverride(Dsymbol s, const(char)[] sym)\n{\n    AttribDeclaration ad = s.isAttribDeclaration();\n    if (ad)\n    {\n        Dsymbols* decls = ad.include(null);\n        uint nestedCount = 0;\n        if (decls && decls.dim)\n            for (size_t i = 0; i < decls.dim; ++i)\n                nestedCount += setMangleOverride((*decls)[i], sym);\n        return nestedCount;\n    }\n    else if (s.isFuncDeclaration() || s.isVarDeclaration())\n    {\n        s.isDeclaration().mangleOverride = sym;\n        return 1;\n    }\n    else\n        return 0;\n}\n\n/*************************************\n * Does semantic analysis on the public face of declarations.\n */\nextern(C++) void dsymbolSemantic(Dsymbol dsym, Scope* sc)\n{\n    scope v = new DsymbolSemanticVisitor(sc);\n    dsym.accept(v);\n}\n\nstructalign_t getAlignment(AlignDeclaration ad, Scope* sc)\n{\n    if (ad.salign != ad.UNKNOWN)\n        return ad.salign;\n\n    if (!ad.ealign)\n        return ad.salign = STRUCTALIGN_DEFAULT;\n\n    sc = sc.startCTFE();\n    ad.ealign = ad.ealign.expressionSemantic(sc);\n    ad.ealign = resolveProperties(sc, ad.ealign);\n    sc = sc.endCTFE();\n    ad.ealign = ad.ealign.ctfeInterpret();\n\n    if (ad.ealign.op == TOK.error)\n        return ad.salign = STRUCTALIGN_DEFAULT;\n\n    Type tb = ad.ealign.type.toBasetype();\n    auto n = ad.ealign.toInteger();\n\n    if (n < 1 || n & (n - 1) || structalign_t.max < n || !tb.isintegral())\n    {\n        error(ad.loc, \"alignment must be an integer positive power of 2, not %s\", ad.ealign.toChars());\n        return ad.salign = STRUCTALIGN_DEFAULT;\n    }\n\n    return ad.salign = cast(structalign_t)n;\n}\n\nconst(char)* getMessage(DeprecatedDeclaration dd)\n{\n    if (auto sc = dd._scope)\n    {\n        dd._scope = null;\n\n        sc = sc.startCTFE();\n        dd.msg = dd.msg.expressionSemantic(sc);\n        dd.msg = resolveProperties(sc, dd.msg);\n        sc = sc.endCTFE();\n        dd.msg = dd.msg.ctfeInterpret();\n\n        if (auto se = dd.msg.toStringExp())\n            dd.msgstr = se.toStringz().ptr;\n        else\n            dd.msg.error(\"compile time constant expected, not `%s`\", dd.msg.toChars());\n    }\n    return dd.msgstr;\n}\n\n\n// Returns true if a contract can appear without a function body.\npackage bool allowsContractWithoutBody(FuncDeclaration funcdecl)\n{\n    assert(!funcdecl.fbody);\n\n    /* Contracts can only appear without a body when they are virtual\n     * interface functions or abstract.\n     */\n    Dsymbol parent = funcdecl.toParent();\n    InterfaceDeclaration id = parent.isInterfaceDeclaration();\n\n    if (!funcdecl.isAbstract() &&\n        (funcdecl.fensures || funcdecl.frequires) &&\n        !(id && funcdecl.isVirtual()))\n    {\n        auto cd = parent.isClassDeclaration();\n        if (!(cd && cd.isAbstract()))\n            return false;\n    }\n    return true;\n}\n\nprivate extern(C++) final class DsymbolSemanticVisitor : Visitor\n{\n    alias visit = Visitor.visit;\n\n    Scope* sc;\n    this(Scope* sc)\n    {\n        this.sc = sc;\n    }\n\n    override void visit(Dsymbol dsym)\n    {\n        dsym.error(\"%p has no semantic routine\", dsym);\n    }\n\n    override void visit(ScopeDsymbol) { }\n    override void visit(Declaration) { }\n\n    override void visit(AliasThis dsym)\n    {\n        if (dsym.semanticRun != PASS.init)\n            return;\n\n        if (dsym._scope)\n        {\n            sc = dsym._scope;\n            dsym._scope = null;\n        }\n\n        if (!sc)\n            return;\n\n        dsym.semanticRun = PASS.semantic;\n\n        Dsymbol p = sc.parent.pastMixin();\n        AggregateDeclaration ad = p.isAggregateDeclaration();\n        if (!ad)\n        {\n            error(dsym.loc, \"alias this can only be a member of aggregate, not %s `%s`\", p.kind(), p.toChars());\n            return;\n        }\n\n        assert(ad.members);\n        Dsymbol s = ad.search(dsym.loc, dsym.ident);\n        if (!s)\n        {\n            s = sc.search(dsym.loc, dsym.ident, null);\n            if (s)\n                error(dsym.loc, \"`%s` is not a member of `%s`\", s.toChars(), ad.toChars());\n            else\n                error(dsym.loc, \"undefined identifier `%s`\", dsym.ident.toChars());\n            return;\n        }\n        if (ad.aliasthis && s != ad.aliasthis)\n        {\n            error(dsym.loc, \"there can be only one alias this\");\n            return;\n        }\n\n        /* disable the alias this conversion so the implicit conversion check\n         * doesn't use it.\n         */\n        ad.aliasthis = null;\n\n        Dsymbol sx = s;\n        if (sx.isAliasDeclaration())\n            sx = sx.toAlias();\n        Declaration d = sx.isDeclaration();\n        if (d && !d.isTupleDeclaration())\n        {\n            /* https://issues.dlang.org/show_bug.cgi?id=18429\n             *\n             * If the identifier in the AliasThis declaration\n             * is defined later and is a voldemort type, we must\n             * perform semantic on the declaration to deduce the type.\n             */\n            if (!d.type)\n                d.dsymbolSemantic(sc);\n\n            Type t = d.type;\n            assert(t);\n            if (ad.type.implicitConvTo(t) > MATCH.nomatch)\n            {\n                error(dsym.loc, \"alias this is not reachable as `%s` already converts to `%s`\", ad.toChars(), t.toChars());\n            }\n        }\n\n        ad.aliasthis = s;\n        dsym.semanticRun = PASS.semanticdone;\n    }\n\n    override void visit(AliasDeclaration dsym)\n    {\n        if (dsym.semanticRun >= PASS.semanticdone)\n            return;\n        assert(dsym.semanticRun <= PASS.semantic);\n\n        dsym.storage_class |= sc.stc & STC.deprecated_;\n        dsym.protection = sc.protection;\n        dsym.userAttribDecl = sc.userAttribDecl;\n\n        if (!sc.func && dsym.inNonRoot())\n            return;\n\n        aliasSemantic(dsym, sc);\n    }\n\n    override void visit(VarDeclaration dsym)\n    {\n        version (none)\n        {\n            printf(\"VarDeclaration::semantic('%s', parent = '%s') sem = %d\\n\", toChars(), sc.parent ? sc.parent.toChars() : null, sem);\n            printf(\" type = %s\\n\", type ? type.toChars() : \"null\");\n            printf(\" stc = x%x\\n\", sc.stc);\n            printf(\" storage_class = x%llx\\n\", storage_class);\n            printf(\"linkage = %d\\n\", sc.linkage);\n            //if (strcmp(toChars(), \"mul\") == 0) assert(0);\n        }\n        //if (semanticRun > PASS.init)\n        //    return;\n        //semanticRun = PSSsemantic;\n\n        if (dsym.semanticRun >= PASS.semanticdone)\n            return;\n\n        Scope* scx = null;\n        if (dsym._scope)\n        {\n            sc = dsym._scope;\n            scx = sc;\n            dsym._scope = null;\n        }\n\n        if (!sc)\n            return;\n\n        dsym.semanticRun = PASS.semantic;\n\n        /* Pick up storage classes from context, but except synchronized,\n         * override, abstract, and final.\n         */\n        dsym.storage_class |= (sc.stc & ~(STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_));\n        if (dsym.storage_class & STC.extern_ && dsym._init)\n            dsym.error(\"extern symbols cannot have initializers\");\n\n        dsym.userAttribDecl = sc.userAttribDecl;\n\n        AggregateDeclaration ad = dsym.isThis();\n        if (ad)\n            dsym.storage_class |= ad.storage_class & STC.TYPECTOR;\n\n        /* If auto type inference, do the inference\n         */\n        int inferred = 0;\n        if (!dsym.type)\n        {\n            dsym.inuse++;\n\n            // Infering the type requires running semantic,\n            // so mark the scope as ctfe if required\n            bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0;\n            if (needctfe)\n                sc = sc.startCTFE();\n\n            //printf(\"inferring type for %s with init %s\\n\", toChars(), _init.toChars());\n            dsym._init = dsym._init.inferType(sc);\n            dsym.type = dsym._init.initializerToExpression().type;\n            if (needctfe)\n                sc = sc.endCTFE();\n\n            dsym.inuse--;\n            inferred = 1;\n\n            /* This is a kludge to support the existing syntax for RAII\n             * declarations.\n             */\n            dsym.storage_class &= ~STC.auto_;\n            dsym.originalType = dsym.type.syntaxCopy();\n        }\n        else\n        {\n            if (!dsym.originalType)\n                dsym.originalType = dsym.type.syntaxCopy();\n\n            /* Prefix function attributes of variable declaration can affect\n             * its type:\n             *      pure nothrow void function() fp;\n             *      static assert(is(typeof(fp) == void function() pure nothrow));\n             */\n            Scope* sc2 = sc.push();\n            sc2.stc |= (dsym.storage_class & STC.FUNCATTR);\n            dsym.inuse++;\n            dsym.type = dsym.type.typeSemantic(dsym.loc, sc2);\n            dsym.inuse--;\n            sc2.pop();\n        }\n        //printf(\" semantic type = %s\\n\", type ? type.toChars() : \"null\");\n        if (dsym.type.ty == Terror)\n            dsym.errors = true;\n\n        dsym.type.checkDeprecated(dsym.loc, sc);\n        dsym.linkage = sc.linkage;\n        dsym.parent = sc.parent;\n        //printf(\"this = %p, parent = %p, '%s'\\n\", this, parent, parent.toChars());\n        dsym.protection = sc.protection;\n\n        /* If scope's alignment is the default, use the type's alignment,\n         * otherwise the scope overrrides.\n         */\n        dsym.alignment = sc.alignment();\n        if (dsym.alignment == STRUCTALIGN_DEFAULT)\n            dsym.alignment = dsym.type.alignment(); // use type's alignment\n\n        //printf(\"sc.stc = %x\\n\", sc.stc);\n        //printf(\"storage_class = x%x\\n\", storage_class);\n\n        if (global.params.vcomplex)\n            dsym.type.checkComplexTransition(dsym.loc, sc);\n\n        // Calculate type size + safety checks\n        if (sc.func && !sc.intypeof)\n        {\n            if (dsym.storage_class & STC.gshared && !dsym.isMember())\n            {\n                if (sc.func.setUnsafe())\n                    dsym.error(\"__gshared not allowed in safe functions; use shared\");\n            }\n        }\n\n        Dsymbol parent = dsym.toParent();\n\n        Type tb = dsym.type.toBasetype();\n        Type tbn = tb.baseElemOf();\n        if (tb.ty == Tvoid && !(dsym.storage_class & STC.lazy_))\n        {\n            if (inferred)\n            {\n                dsym.error(\"type `%s` is inferred from initializer `%s`, and variables cannot be of type `void`\", dsym.type.toChars(), dsym._init.toChars());\n            }\n            else\n                dsym.error(\"variables cannot be of type `void`\");\n            dsym.type = Type.terror;\n            tb = dsym.type;\n        }\n        if (tb.ty == Tfunction)\n        {\n            dsym.error(\"cannot be declared to be a function\");\n            dsym.type = Type.terror;\n            tb = dsym.type;\n        }\n        if (tb.ty == Tstruct)\n        {\n            TypeStruct ts = cast(TypeStruct)tb;\n            if (!ts.sym.members)\n            {\n                dsym.error(\"no definition of struct `%s`\", ts.toChars());\n            }\n        }\n        if ((dsym.storage_class & STC.auto_) && !inferred)\n            dsym.error(\"storage class `auto` has no effect if type is not inferred, did you mean `scope`?\");\n\n        if (tb.ty == Ttuple)\n        {\n            /* Instead, declare variables for each of the tuple elements\n             * and add those.\n             */\n            TypeTuple tt = cast(TypeTuple)tb;\n            size_t nelems = Parameter.dim(tt.arguments);\n            Expression ie = (dsym._init && !dsym._init.isVoidInitializer()) ? dsym._init.initializerToExpression() : null;\n            if (ie)\n                ie = ie.expressionSemantic(sc);\n            if (nelems > 0 && ie)\n            {\n                auto iexps = new Expressions();\n                iexps.push(ie);\n                auto exps = new Expressions();\n                for (size_t pos = 0; pos < iexps.dim; pos++)\n                {\n                Lexpand1:\n                    Expression e = (*iexps)[pos];\n                    Parameter arg = Parameter.getNth(tt.arguments, pos);\n                    arg.type = arg.type.typeSemantic(dsym.loc, sc);\n                    //printf(\"[%d] iexps.dim = %d, \", pos, iexps.dim);\n                    //printf(\"e = (%s %s, %s), \", Token::tochars[e.op], e.toChars(), e.type.toChars());\n                    //printf(\"arg = (%s, %s)\\n\", arg.toChars(), arg.type.toChars());\n\n                    if (e != ie)\n                    {\n                        if (iexps.dim > nelems)\n                            goto Lnomatch;\n                        if (e.type.implicitConvTo(arg.type))\n                            continue;\n                    }\n\n                    if (e.op == TOK.tuple)\n                    {\n                        TupleExp te = cast(TupleExp)e;\n                        if (iexps.dim - 1 + te.exps.dim > nelems)\n                            goto Lnomatch;\n\n                        iexps.remove(pos);\n                        iexps.insert(pos, te.exps);\n                        (*iexps)[pos] = Expression.combine(te.e0, (*iexps)[pos]);\n                        goto Lexpand1;\n                    }\n                    else if (isAliasThisTuple(e))\n                    {\n                        auto v = copyToTemp(0, \"__tup\", e);\n                        v.dsymbolSemantic(sc);\n                        auto ve = new VarExp(dsym.loc, v);\n                        ve.type = e.type;\n\n                        exps.setDim(1);\n                        (*exps)[0] = ve;\n                        expandAliasThisTuples(exps, 0);\n\n                        for (size_t u = 0; u < exps.dim; u++)\n                        {\n                        Lexpand2:\n                            Expression ee = (*exps)[u];\n                            arg = Parameter.getNth(tt.arguments, pos + u);\n                            arg.type = arg.type.typeSemantic(dsym.loc, sc);\n                            //printf(\"[%d+%d] exps.dim = %d, \", pos, u, exps.dim);\n                            //printf(\"ee = (%s %s, %s), \", Token::tochars[ee.op], ee.toChars(), ee.type.toChars());\n                            //printf(\"arg = (%s, %s)\\n\", arg.toChars(), arg.type.toChars());\n\n                            size_t iexps_dim = iexps.dim - 1 + exps.dim;\n                            if (iexps_dim > nelems)\n                                goto Lnomatch;\n                            if (ee.type.implicitConvTo(arg.type))\n                                continue;\n\n                            if (expandAliasThisTuples(exps, u) != -1)\n                                goto Lexpand2;\n                        }\n\n                        if ((*exps)[0] != ve)\n                        {\n                            Expression e0 = (*exps)[0];\n                            (*exps)[0] = new CommaExp(dsym.loc, new DeclarationExp(dsym.loc, v), e0);\n                            (*exps)[0].type = e0.type;\n\n                            iexps.remove(pos);\n                            iexps.insert(pos, exps);\n                            goto Lexpand1;\n                        }\n                    }\n                }\n                if (iexps.dim < nelems)\n                    goto Lnomatch;\n\n                ie = new TupleExp(dsym._init.loc, iexps);\n            }\n        Lnomatch:\n\n            if (ie && ie.op == TOK.tuple)\n            {\n                TupleExp te = cast(TupleExp)ie;\n                size_t tedim = te.exps.dim;\n                if (tedim != nelems)\n                {\n                    error(dsym.loc, \"tuple of %d elements cannot be assigned to tuple of %d elements\", cast(int)tedim, cast(int)nelems);\n                    for (size_t u = tedim; u < nelems; u++) // fill dummy expression\n                        te.exps.push(new ErrorExp());\n                }\n            }\n\n            auto exps = new Objects(nelems);\n            for (size_t i = 0; i < nelems; i++)\n            {\n                Parameter arg = Parameter.getNth(tt.arguments, i);\n\n                OutBuffer buf;\n                buf.printf(\"__%s_field_%llu\", dsym.ident.toChars(), cast(ulong)i);\n                auto id = Identifier.idPool(buf.peekSlice());\n\n                Initializer ti;\n                if (ie)\n                {\n                    Expression einit = ie;\n                    if (ie.op == TOK.tuple)\n                    {\n                        TupleExp te = cast(TupleExp)ie;\n                        einit = (*te.exps)[i];\n                        if (i == 0)\n                            einit = Expression.combine(te.e0, einit);\n                    }\n                    ti = new ExpInitializer(einit.loc, einit);\n                }\n                else\n                    ti = dsym._init ? dsym._init.syntaxCopy() : null;\n\n                StorageClass storage_class = STC.temp | dsym.storage_class;\n                if (arg.storageClass & STC.parameter)\n                    storage_class |= arg.storageClass;\n                auto v = new VarDeclaration(dsym.loc, arg.type, id, ti, storage_class);\n                //printf(\"declaring field %s of type %s\\n\", v.toChars(), v.type.toChars());\n                v.dsymbolSemantic(sc);\n\n                if (sc.scopesym)\n                {\n                    //printf(\"adding %s to %s\\n\", v.toChars(), sc.scopesym.toChars());\n                    if (sc.scopesym.members)\n                        // Note this prevents using foreach() over members, because the limits can change\n                        sc.scopesym.members.push(v);\n                }\n\n                Expression e = new DsymbolExp(dsym.loc, v);\n                (*exps)[i] = e;\n            }\n            auto v2 = new TupleDeclaration(dsym.loc, dsym.ident, exps);\n            v2.parent = dsym.parent;\n            v2.isexp = true;\n            dsym.aliassym = v2;\n            dsym.semanticRun = PASS.semanticdone;\n            return;\n        }\n\n        /* Storage class can modify the type\n         */\n        dsym.type = dsym.type.addStorageClass(dsym.storage_class);\n\n        /* Adjust storage class to reflect type\n         */\n        if (dsym.type.isConst())\n        {\n            dsym.storage_class |= STC.const_;\n            if (dsym.type.isShared())\n                dsym.storage_class |= STC.shared_;\n        }\n        else if (dsym.type.isImmutable())\n            dsym.storage_class |= STC.immutable_;\n        else if (dsym.type.isShared())\n            dsym.storage_class |= STC.shared_;\n        else if (dsym.type.isWild())\n            dsym.storage_class |= STC.wild;\n\n        if (StorageClass stc = dsym.storage_class & (STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_))\n        {\n            if (stc == STC.final_)\n                dsym.error(\"cannot be `final`, perhaps you meant `const`?\");\n            else\n            {\n                OutBuffer buf;\n                stcToBuffer(&buf, stc);\n                dsym.error(\"cannot be `%s`\", buf.peekString());\n            }\n            dsym.storage_class &= ~stc; // strip off\n        }\n\n        if (dsym.storage_class & STC.scope_)\n        {\n            StorageClass stc = dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.tls | STC.gshared);\n            if (stc)\n            {\n                OutBuffer buf;\n                stcToBuffer(&buf, stc);\n                dsym.error(\"cannot be `scope` and `%s`\", buf.peekString());\n            }\n            else if (dsym.isMember())\n            {\n                dsym.error(\"field cannot be `scope`\");\n            }\n            else if (!dsym.type.hasPointers())\n            {\n                dsym.storage_class &= ~STC.scope_;     // silently ignore; may occur in generic code\n            }\n        }\n\n        if (dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.templateparameter | STC.tls | STC.gshared | STC.ctfe))\n        {\n        }\n        else\n        {\n            AggregateDeclaration aad = parent.isAggregateDeclaration();\n            if (aad)\n            {\n                if (global.params.vfield && dsym.storage_class & (STC.const_ | STC.immutable_) && dsym._init && !dsym._init.isVoidInitializer())\n                {\n                    const(char)* s = (dsym.storage_class & STC.immutable_) ? \"immutable\" : \"const\";\n                    message(dsym.loc, \"`%s.%s` is `%s` field\", ad.toPrettyChars(), dsym.toChars(), s);\n                }\n                dsym.storage_class |= STC.field;\n                if (tbn.ty == Tstruct && (cast(TypeStruct)tbn).sym.noDefaultCtor)\n                {\n                    if (!dsym.isThisDeclaration() && !dsym._init)\n                        aad.noDefaultCtor = true;\n                }\n            }\n\n            InterfaceDeclaration id = parent.isInterfaceDeclaration();\n            if (id)\n            {\n                dsym.error(\"field not allowed in interface\");\n            }\n            else if (aad && aad.sizeok == Sizeok.done)\n            {\n                dsym.error(\"cannot be further field because it will change the determined %s size\", aad.toChars());\n            }\n\n            /* Templates cannot add fields to aggregates\n             */\n            TemplateInstance ti = parent.isTemplateInstance();\n            if (ti)\n            {\n                // Take care of nested templates\n                while (1)\n                {\n                    TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();\n                    if (!ti2)\n                        break;\n                    ti = ti2;\n                }\n                // If it's a member template\n                AggregateDeclaration ad2 = ti.tempdecl.isMember();\n                if (ad2 && dsym.storage_class != STC.undefined_)\n                {\n                    dsym.error(\"cannot use template to add field to aggregate `%s`\", ad2.toChars());\n                }\n            }\n        }\n\n        if ((dsym.storage_class & (STC.ref_ | STC.parameter | STC.foreach_ | STC.temp | STC.result)) == STC.ref_ && dsym.ident != Id.This)\n        {\n            dsym.error(\"only parameters or `foreach` declarations can be `ref`\");\n        }\n\n        if (dsym.type.hasWild())\n        {\n            if (dsym.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.field) || dsym.isDataseg())\n            {\n                dsym.error(\"only parameters or stack based variables can be `inout`\");\n            }\n            FuncDeclaration func = sc.func;\n            if (func)\n            {\n                if (func.fes)\n                    func = func.fes.func;\n                bool isWild = false;\n                for (FuncDeclaration fd = func; fd; fd = fd.toParent2().isFuncDeclaration())\n                {\n                    if ((cast(TypeFunction)fd.type).iswild)\n                    {\n                        isWild = true;\n                        break;\n                    }\n                }\n                if (!isWild)\n                {\n                    dsym.error(\"`inout` variables can only be declared inside `inout` functions\");\n                }\n            }\n        }\n\n        if (!(dsym.storage_class & (STC.ctfe | STC.ref_ | STC.result)) && tbn.ty == Tstruct && (cast(TypeStruct)tbn).sym.noDefaultCtor)\n        {\n            if (!dsym._init)\n            {\n                if (dsym.isField())\n                {\n                    /* For fields, we'll check the constructor later to make sure it is initialized\n                     */\n                    dsym.storage_class |= STC.nodefaultctor;\n                }\n                else if (dsym.storage_class & STC.parameter)\n                {\n                }\n                else\n                    dsym.error(\"default construction is disabled for type `%s`\", dsym.type.toChars());\n            }\n        }\n\n        FuncDeclaration fd = parent.isFuncDeclaration();\n        if (dsym.type.isscope() && !(dsym.storage_class & STC.nodtor))\n        {\n            if (dsym.storage_class & (STC.field | STC.out_ | STC.ref_ | STC.static_ | STC.manifest | STC.tls | STC.gshared) || !fd)\n            {\n                dsym.error(\"globals, statics, fields, manifest constants, ref and out parameters cannot be `scope`\");\n            }\n            if (!(dsym.storage_class & STC.scope_))\n            {\n                if (!(dsym.storage_class & STC.parameter) && dsym.ident != Id.withSym)\n                    dsym.error(\"reference to `scope class` must be `scope`\");\n            }\n        }\n\n        // Calculate type size + safety checks\n        if (sc.func && !sc.intypeof)\n        {\n            if (dsym._init && dsym._init.isVoidInitializer() && dsym.type.hasPointers()) // get type size\n            {\n                if (sc.func.setUnsafe())\n                    dsym.error(\"`void` initializers for pointers not allowed in safe functions\");\n            }\n            else if (!dsym._init &&\n                     !(dsym.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.field | STC.parameter)) &&\n                     dsym.type.hasVoidInitPointers())\n            {\n                if (sc.func.setUnsafe())\n                    dsym.error(\"`void` initializers for pointers not allowed in safe functions\");\n            }\n        }\n\n        if ((!dsym._init || dsym._init.isVoidInitializer) && !fd)\n        {\n            // If not mutable, initializable by constructor only\n            dsym.storage_class |= STC.ctorinit;\n        }\n\n        if (dsym._init)\n            dsym.storage_class |= STC.init; // remember we had an explicit initializer\n        else if (dsym.storage_class & STC.manifest)\n            dsym.error(\"manifest constants must have initializers\");\n\n        bool isBlit = false;\n        d_uns64 sz;\n        if (!dsym._init &&\n            !(dsym.storage_class & (STC.static_ | STC.gshared | STC.extern_)) &&\n            fd &&\n            (!(dsym.storage_class & (STC.field | STC.in_ | STC.foreach_ | STC.parameter | STC.result)) ||\n             (dsym.storage_class & STC.out_)) &&\n            (sz = dsym.type.size()) != 0)\n        {\n            // Provide a default initializer\n\n            //printf(\"Providing default initializer for '%s'\\n\", toChars());\n            if (sz == SIZE_INVALID && dsym.type.ty != Terror)\n                dsym.error(\"size of type `%s` is invalid\", dsym.type.toChars());\n\n            Type tv = dsym.type;\n            while (tv.ty == Tsarray)    // Don't skip Tenum\n                tv = tv.nextOf();\n            if (tv.needsNested())\n            {\n                /* Nested struct requires valid enclosing frame pointer.\n                 * In StructLiteralExp::toElem(), it's calculated.\n                 */\n                assert(tbn.ty == Tstruct);\n                checkFrameAccess(dsym.loc, sc, (cast(TypeStruct)tbn).sym);\n\n                Expression e = tv.defaultInitLiteral(dsym.loc);\n                e = new BlitExp(dsym.loc, new VarExp(dsym.loc, dsym), e);\n                e = e.expressionSemantic(sc);\n                dsym._init = new ExpInitializer(dsym.loc, e);\n                goto Ldtor;\n            }\n            if (tv.ty == Tstruct && (cast(TypeStruct)tv).sym.zeroInit)\n            {\n                /* If a struct is all zeros, as a special case\n                 * set it's initializer to the integer 0.\n                 * In AssignExp::toElem(), we check for this and issue\n                 * a memset() to initialize the struct.\n                 * Must do same check in interpreter.\n                 */\n                Expression e = new IntegerExp(dsym.loc, 0, Type.tint32);\n                e = new BlitExp(dsym.loc, new VarExp(dsym.loc, dsym), e);\n                e.type = dsym.type;      // don't type check this, it would fail\n                dsym._init = new ExpInitializer(dsym.loc, e);\n                goto Ldtor;\n            }\n            if (dsym.type.baseElemOf().ty == Tvoid)\n            {\n                dsym.error(\"`%s` does not have a default initializer\", dsym.type.toChars());\n            }\n            else if (auto e = dsym.type.defaultInit(dsym.loc))\n            {\n                dsym._init = new ExpInitializer(dsym.loc, e);\n            }\n\n            // Default initializer is always a blit\n            isBlit = true;\n        }\n        if (dsym._init)\n        {\n            sc = sc.push();\n            sc.stc &= ~(STC.TYPECTOR | STC.pure_ | STC.nothrow_ | STC.nogc | STC.ref_ | STC.disable);\n\n            ExpInitializer ei = dsym._init.isExpInitializer();\n            if (ei) // https://issues.dlang.org/show_bug.cgi?id=13424\n                    // Preset the required type to fail in FuncLiteralDeclaration::semantic3\n                ei.exp = inferType(ei.exp, dsym.type);\n\n            // If inside function, there is no semantic3() call\n            if (sc.func || sc.intypeof == 1)\n            {\n                // If local variable, use AssignExp to handle all the various\n                // possibilities.\n                if (fd && !(dsym.storage_class & (STC.manifest | STC.static_ | STC.tls | STC.gshared | STC.extern_)) && !dsym._init.isVoidInitializer())\n                {\n                    //printf(\"fd = '%s', var = '%s'\\n\", fd.toChars(), toChars());\n                    if (!ei)\n                    {\n                        ArrayInitializer ai = dsym._init.isArrayInitializer();\n                        Expression e;\n                        if (ai && tb.ty == Taarray)\n                            e = ai.toAssocArrayLiteral();\n                        else\n                            e = dsym._init.initializerToExpression();\n                        if (!e)\n                        {\n                            // Run semantic, but don't need to interpret\n                            dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITnointerpret);\n                            e = dsym._init.initializerToExpression();\n                            if (!e)\n                            {\n                                dsym.error(\"is not a static and cannot have static initializer\");\n                                e = new ErrorExp();\n                            }\n                        }\n                        ei = new ExpInitializer(dsym._init.loc, e);\n                        dsym._init = ei;\n                    }\n\n                    Expression exp = ei.exp;\n                    Expression e1 = new VarExp(dsym.loc, dsym);\n                    if (isBlit)\n                        exp = new BlitExp(dsym.loc, e1, exp);\n                    else\n                        exp = new ConstructExp(dsym.loc, e1, exp);\n                    dsym.canassign++;\n                    exp = exp.expressionSemantic(sc);\n                    dsym.canassign--;\n                    exp = exp.optimize(WANTvalue);\n                    if (exp.op == TOK.error)\n                    {\n                        dsym._init = new ErrorInitializer();\n                        ei = null;\n                    }\n                    else\n                        ei.exp = exp;\n\n                    if (ei && dsym.isScope())\n                    {\n                        Expression ex = ei.exp;\n                        while (ex.op == TOK.comma)\n                            ex = (cast(CommaExp)ex).e2;\n                        if (ex.op == TOK.blit || ex.op == TOK.construct)\n                            ex = (cast(AssignExp)ex).e2;\n                        if (ex.op == TOK.new_)\n                        {\n                            // See if initializer is a NewExp that can be allocated on the stack\n                            NewExp ne = cast(NewExp)ex;\n                            if (dsym.type.toBasetype().ty == Tclass)\n                            {\n                                if (ne.newargs && ne.newargs.dim > 1)\n                                {\n                                    dsym.mynew = true;\n                                }\n                                else\n                                {\n                                    ne.onstack = 1;\n                                    dsym.onstack = true;\n                                }\n                            }\n                        }\n                        else if (ex.op == TOK.function_)\n                        {\n                            // or a delegate that doesn't escape a reference to the function\n                            FuncDeclaration f = (cast(FuncExp)ex).fd;\n                            f.tookAddressOf--;\n                        }\n                    }\n                }\n                else\n                {\n                    // https://issues.dlang.org/show_bug.cgi?id=14166\n                    // Don't run CTFE for the temporary variables inside typeof\n                    dsym._init = dsym._init.initializerSemantic(sc, dsym.type, sc.intypeof == 1 ? INITnointerpret : INITinterpret);\n                    const init_err = dsym._init.isExpInitializer();\n                    if (init_err && init_err.exp.op == TOK.showCtfeContext)\n                    {\n                         errorSupplemental(dsym.loc, \"compile time context created here\");\n                    }\n                }\n            }\n            else if (parent.isAggregateDeclaration())\n            {\n                dsym._scope = scx ? scx : sc.copy();\n                dsym._scope.setNoFree();\n            }\n            else if (dsym.storage_class & (STC.const_ | STC.immutable_ | STC.manifest) || dsym.type.isConst() || dsym.type.isImmutable())\n            {\n                /* Because we may need the results of a const declaration in a\n                 * subsequent type, such as an array dimension, before semantic2()\n                 * gets ordinarily run, try to run semantic2() now.\n                 * Ignore failure.\n                 */\n                if (!inferred)\n                {\n                    uint errors = global.errors;\n                    dsym.inuse++;\n                    if (ei)\n                    {\n                        Expression exp = ei.exp.syntaxCopy();\n\n                        bool needctfe = dsym.isDataseg() || (dsym.storage_class & STC.manifest);\n                        if (needctfe)\n                            sc = sc.startCTFE();\n                        exp = exp.expressionSemantic(sc);\n                        exp = resolveProperties(sc, exp);\n                        if (needctfe)\n                            sc = sc.endCTFE();\n\n                        Type tb2 = dsym.type.toBasetype();\n                        Type ti = exp.type.toBasetype();\n\n                        /* The problem is the following code:\n                         *  struct CopyTest {\n                         *     double x;\n                         *     this(double a) { x = a * 10.0;}\n                         *     this(this) { x += 2.0; }\n                         *  }\n                         *  const CopyTest z = CopyTest(5.3);  // ok\n                         *  const CopyTest w = z;              // not ok, postblit not run\n                         *  static assert(w.x == 55.0);\n                         * because the postblit doesn't get run on the initialization of w.\n                         */\n                        if (ti.ty == Tstruct)\n                        {\n                            StructDeclaration sd = (cast(TypeStruct)ti).sym;\n                            /* Look to see if initializer involves a copy constructor\n                             * (which implies a postblit)\n                             */\n                            // there is a copy constructor\n                            // and exp is the same struct\n                            if (sd.postblit && tb2.toDsymbol(null) == sd)\n                            {\n                                // The only allowable initializer is a (non-copy) constructor\n                                if (exp.isLvalue())\n                                    dsym.error(\"of type struct `%s` uses `this(this)`, which is not allowed in static initialization\", tb2.toChars());\n                            }\n                        }\n                        ei.exp = exp;\n                    }\n                    dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITinterpret);\n                    dsym.inuse--;\n                    if (global.errors > errors)\n                    {\n                        dsym._init = new ErrorInitializer();\n                        dsym.type = Type.terror;\n                    }\n                }\n                else\n                {\n                    dsym._scope = scx ? scx : sc.copy();\n                    dsym._scope.setNoFree();\n                }\n            }\n            sc = sc.pop();\n        }\n\n    Ldtor:\n        /* Build code to execute destruction, if necessary\n         */\n        dsym.edtor = dsym.callScopeDtor(sc);\n        if (dsym.edtor)\n        {\n            /* If dsym is a local variable, who's type is a struct with a scope destructor,\n             * then make dsym scope, too.\n             */\n            if (global.params.vsafe &&\n                !(dsym.storage_class & (STC.parameter | STC.temp | STC.field | STC.in_ | STC.foreach_ | STC.result | STC.manifest)) &&\n                !dsym.isDataseg() &&\n                !dsym.doNotInferScope &&\n                dsym.type.hasPointers())\n            {\n                auto tv = dsym.type.baseElemOf();\n                if (tv.ty == Tstruct &&\n                    (cast(TypeStruct)tv).sym.dtor.storage_class & STC.scope_)\n                {\n                    dsym.storage_class |= STC.scope_;\n                }\n            }\n\n            if (sc.func && dsym.storage_class & (STC.static_ | STC.gshared))\n                dsym.edtor = dsym.edtor.expressionSemantic(sc._module._scope);\n            else\n                dsym.edtor = dsym.edtor.expressionSemantic(sc);\n\n            version (none)\n            {\n                // currently disabled because of std.stdio.stdin, stdout and stderr\n                if (dsym.isDataseg() && !(dsym.storage_class & STC.extern_))\n                    dsym.error(\"static storage variables cannot have destructors\");\n            }\n        }\n\n        dsym.semanticRun = PASS.semanticdone;\n\n        if (dsym.type.toBasetype().ty == Terror)\n            dsym.errors = true;\n\n        if(sc.scopesym && !sc.scopesym.isAggregateDeclaration())\n        {\n            for (ScopeDsymbol sym = sc.scopesym; sym && dsym.endlinnum == 0;\n                 sym = sym.parent ? sym.parent.isScopeDsymbol() : null)\n                dsym.endlinnum = sym.endlinnum;\n        }\n    }\n\n    override void visit(TypeInfoDeclaration dsym)\n    {\n        assert(dsym.linkage == LINK.c);\n    }\n\n    override void visit(Import imp)\n    {\n        //printf(\"Import::semantic('%s') %s\\n\", toPrettyChars(), id.toChars());\n        if (imp.semanticRun > PASS.init)\n            return;\n\n        if (imp._scope)\n        {\n            sc = imp._scope;\n            imp._scope = null;\n        }\n        if (!sc)\n            return;\n\n        imp.semanticRun = PASS.semantic;\n\n        // Load if not already done so\n        bool loadErrored = false;\n        if (!imp.mod)\n        {\n            loadErrored = imp.load(sc);\n            if (imp.mod)\n                imp.mod.importAll(null);\n        }\n        if (imp.mod)\n        {\n            // Modules need a list of each imported module\n            //printf(\"%s imports %s\\n\", sc._module.toChars(), imp.mod.toChars());\n            sc._module.aimports.push(imp.mod);\n\n            if (sc.explicitProtection)\n                imp.protection = sc.protection;\n\n            if (!imp.aliasId && !imp.names.dim) // neither a selective nor a renamed import\n            {\n                ScopeDsymbol scopesym;\n                for (Scope* scd = sc; scd; scd = scd.enclosing)\n                {\n                    if (!scd.scopesym)\n                        continue;\n                    scopesym = scd.scopesym;\n                    break;\n                }\n\n                if (!imp.isstatic)\n                {\n                    scopesym.importScope(imp.mod, imp.protection);\n                }\n\n                // Mark the imported packages as accessible from the current\n                // scope. This access check is necessary when using FQN b/c\n                // we're using a single global package tree.\n                // https://issues.dlang.org/show_bug.cgi?id=313\n                if (imp.packages)\n                {\n                    // import a.b.c.d;\n                    auto p = imp.pkg; // a\n                    scopesym.addAccessiblePackage(p, imp.protection);\n                    foreach (id; (*imp.packages)[1 .. imp.packages.dim]) // [b, c]\n                    {\n                        p = cast(Package) p.symtab.lookup(id);\n                        scopesym.addAccessiblePackage(p, imp.protection);\n                    }\n                }\n                scopesym.addAccessiblePackage(imp.mod, imp.protection); // d\n            }\n\n            if (!loadErrored)\n            {\n                imp.mod.dsymbolSemantic(null);\n            }\n\n            if (imp.mod.needmoduleinfo)\n            {\n                //printf(\"module4 %s because of %s\\n\", sc.module.toChars(), mod.toChars());\n                sc._module.needmoduleinfo = 1;\n            }\n\n            sc = sc.push(imp.mod);\n            sc.protection = imp.protection;\n            for (size_t i = 0; i < imp.aliasdecls.dim; i++)\n            {\n                AliasDeclaration ad = imp.aliasdecls[i];\n                //printf(\"\\tImport %s alias %s = %s, scope = %p\\n\", toPrettyChars(), aliases[i].toChars(), names[i].toChars(), ad._scope);\n                Dsymbol sym = imp.mod.search(imp.loc, imp.names[i] /*, IgnorePrivateImports */);\n                if (sym)\n                {\n                    // Deprecated in 2018-01.\n                    // Change to error in 2019-01 by deleteting the following 5 lines and uncommenting\n                    // the IgnorePrivateImports parameter from above.\n                    // @@@DEPRECATED_2019-01@@@.\n                    Dsymbol s = imp.mod.search(imp.loc, imp.names[i], IgnorePrivateImports);\n                    if (!s)\n                        .deprecation(imp.loc,\n                            \"Symbol `%s` is not visible from module `%s` because it is privately imported in module `%s`\",\n                            sym.toPrettyChars, sc._module.toChars(), imp.mod.toChars());\n\n                    // Deprecated in 2018-01.\n                    // Change to error in 2019-01.\n                    // @@@DEPRECATED_2019-01@@@.\n                    import dmd.access : symbolIsVisible;\n                    if (!symbolIsVisible(sc, sym))\n                        imp.mod.deprecation(imp.loc, \"member `%s` is not visible from module `%s`\",\n                            imp.names[i].toChars(), sc._module.toChars());\n                    ad.dsymbolSemantic(sc);\n                    // If the import declaration is in non-root module,\n                    // analysis of the aliased symbol is deferred.\n                    // Therefore, don't see the ad.aliassym or ad.type here.\n                }\n                else\n                {\n                    Dsymbol s = imp.mod.search_correct(imp.names[i]);\n                    if (s)\n                        imp.mod.error(imp.loc, \"import `%s` not found, did you mean %s `%s`?\", imp.names[i].toChars(), s.kind(), s.toPrettyChars());\n                    else\n                        imp.mod.error(imp.loc, \"import `%s` not found\", imp.names[i].toChars());\n                    ad.type = Type.terror;\n                }\n            }\n            sc = sc.pop();\n        }\n\n        imp.semanticRun = PASS.semanticdone;\n\n        // object self-imports itself, so skip that\n        // https://issues.dlang.org/show_bug.cgi?id=7547\n        // don't list pseudo modules __entrypoint.d, __main.d\n        // https://issues.dlang.org/show_bug.cgi?id=11117\n        // https://issues.dlang.org/show_bug.cgi?id=11164\n        if (global.params.moduleDeps !is null && !(imp.id == Id.object && sc._module.ident == Id.object) &&\n            sc._module.ident != Id.entrypoint &&\n            strcmp(sc._module.ident.toChars(), \"__main\") != 0)\n        {\n            /* The grammar of the file is:\n             *      ImportDeclaration\n             *          ::= BasicImportDeclaration [ \" : \" ImportBindList ] [ \" -> \"\n             *      ModuleAliasIdentifier ] \"\\n\"\n             *\n             *      BasicImportDeclaration\n             *          ::= ModuleFullyQualifiedName \" (\" FilePath \") : \" Protection|\"string\"\n             *              \" [ \" static\" ] : \" ModuleFullyQualifiedName \" (\" FilePath \")\"\n             *\n             *      FilePath\n             *          - any string with '(', ')' and '\\' escaped with the '\\' character\n             */\n            OutBuffer* ob = global.params.moduleDeps;\n            Module imod = sc.instantiatingModule();\n            if (!global.params.moduleDepsFile)\n                ob.writestring(\"depsImport \");\n            ob.writestring(imod.toPrettyChars());\n            ob.writestring(\" (\");\n            escapePath(ob, imod.srcfile.toChars());\n            ob.writestring(\") : \");\n            // use protection instead of sc.protection because it couldn't be\n            // resolved yet, see the comment above\n            protectionToBuffer(ob, imp.protection);\n            ob.writeByte(' ');\n            if (imp.isstatic)\n            {\n                stcToBuffer(ob, STC.static_);\n                ob.writeByte(' ');\n            }\n            ob.writestring(\": \");\n            if (imp.packages)\n            {\n                for (size_t i = 0; i < imp.packages.dim; i++)\n                {\n                    Identifier pid = (*imp.packages)[i];\n                    ob.printf(\"%s.\", pid.toChars());\n                }\n            }\n            ob.writestring(imp.id.toChars());\n            ob.writestring(\" (\");\n            if (imp.mod)\n                escapePath(ob, imp.mod.srcfile.toChars());\n            else\n                ob.writestring(\"???\");\n            ob.writeByte(')');\n            foreach (i, name; imp.names)\n            {\n                if (i == 0)\n                    ob.writeByte(':');\n                else\n                    ob.writeByte(',');\n                Identifier _alias = imp.aliases[i];\n                if (!_alias)\n                {\n                    ob.printf(\"%s\", name.toChars());\n                    _alias = name;\n                }\n                else\n                    ob.printf(\"%s=%s\", _alias.toChars(), name.toChars());\n            }\n            if (imp.aliasId)\n                ob.printf(\" -> %s\", imp.aliasId.toChars());\n            ob.writenl();\n        }\n        //printf(\"-Import::semantic('%s'), pkg = %p\\n\", toChars(), pkg);\n    }\n\n    void attribSemantic(AttribDeclaration ad)\n    {\n        if (ad.semanticRun != PASS.init)\n            return;\n        ad.semanticRun = PASS.semantic;\n        Dsymbols* d = ad.include(sc);\n        //printf(\"\\tAttribDeclaration::semantic '%s', d = %p\\n\",toChars(), d);\n        if (d)\n        {\n            Scope* sc2 = ad.newScope(sc);\n            bool errors;\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                s.dsymbolSemantic(sc2);\n                errors |= s.errors;\n            }\n            ad.errors |= errors;\n            if (sc2 != sc)\n                sc2.pop();\n        }\n        ad.semanticRun = PASS.semanticdone;\n    }\n\n    override void visit(AttribDeclaration atd)\n    {\n        attribSemantic(atd);\n    }\n\n    override void visit(AnonDeclaration scd)\n    {\n        //printf(\"\\tAnonDeclaration::semantic %s %p\\n\", isunion ? \"union\" : \"struct\", this);\n        assert(sc.parent);\n        auto p = sc.parent.pastMixin();\n        auto ad = p.isAggregateDeclaration();\n        if (!ad)\n        {\n            error(scd.loc, \"%s can only be a part of an aggregate, not %s `%s`\", scd.kind(), p.kind(), p.toChars());\n            scd.errors = true;\n            return;\n        }\n\n        if (scd.decl)\n        {\n            sc = sc.push();\n            sc.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.tls | STC.gshared);\n            sc.inunion = scd.isunion;\n            sc.flags = 0;\n            for (size_t i = 0; i < scd.decl.dim; i++)\n            {\n                Dsymbol s = (*scd.decl)[i];\n                s.dsymbolSemantic(sc);\n            }\n            sc = sc.pop();\n        }\n    }\n\n    override void visit(PragmaDeclaration pd)\n    {\n        // Should be merged with PragmaStatement\n        //printf(\"\\tPragmaDeclaration::semantic '%s'\\n\", pd.toChars());\n        if (global.params.mscoff)\n        {\n            if (pd.ident == Id.linkerDirective)\n            {\n                if (!pd.args || pd.args.dim != 1)\n                    pd.error(\"one string argument expected for pragma(linkerDirective)\");\n                else\n                {\n                    auto se = semanticString(sc, (*pd.args)[0], \"linker directive\");\n                    if (!se)\n                        goto Lnodecl;\n                    (*pd.args)[0] = se;\n                    if (global.params.verbose)\n                        message(\"linkopt   %.*s\", cast(int)se.len, se.string);\n                }\n                goto Lnodecl;\n            }\n        }\n        if (pd.ident == Id.msg)\n        {\n            if (pd.args)\n            {\n                for (size_t i = 0; i < pd.args.dim; i++)\n                {\n                    Expression e = (*pd.args)[i];\n                    sc = sc.startCTFE();\n                    e = e.expressionSemantic(sc);\n                    e = resolveProperties(sc, e);\n                    sc = sc.endCTFE();\n                    // pragma(msg) is allowed to contain types as well as expressions\n                    if (e.type && e.type.ty == Tvoid)\n                    {\n                        error(pd.loc, \"Cannot pass argument `%s` to `pragma msg` because it is `void`\", e.toChars());\n                        return;\n                    }\n                    e = ctfeInterpretForPragmaMsg(e);\n                    if (e.op == TOK.error)\n                    {\n                        errorSupplemental(pd.loc, \"while evaluating `pragma(msg, %s)`\", (*pd.args)[i].toChars());\n                        return;\n                    }\n                    StringExp se = e.toStringExp();\n                    if (se)\n                    {\n                        se = se.toUTF8(sc);\n                        fprintf(stderr, \"%.*s\", cast(int)se.len, se.string);\n                    }\n                    else\n                        fprintf(stderr, \"%s\", e.toChars());\n                }\n                fprintf(stderr, \"\\n\");\n            }\n            goto Lnodecl;\n        }\n        else if (pd.ident == Id.lib)\n        {\n            if (!pd.args || pd.args.dim != 1)\n                pd.error(\"string expected for library name\");\n            else\n            {\n                auto se = semanticString(sc, (*pd.args)[0], \"library name\");\n                if (!se)\n                    goto Lnodecl;\n                (*pd.args)[0] = se;\n\n                auto name = cast(char*)mem.xmalloc(se.len + 1);\n                memcpy(name, se.string, se.len);\n                name[se.len] = 0;\n                if (global.params.verbose)\n                    message(\"library   %s\", name);\n                if (global.params.moduleDeps && !global.params.moduleDepsFile)\n                {\n                    OutBuffer* ob = global.params.moduleDeps;\n                    Module imod = sc.instantiatingModule();\n                    ob.writestring(\"depsLib \");\n                    ob.writestring(imod.toPrettyChars());\n                    ob.writestring(\" (\");\n                    escapePath(ob, imod.srcfile.toChars());\n                    ob.writestring(\") : \");\n                    ob.writestring(name);\n                    ob.writenl();\n                }\n                mem.xfree(name);\n            }\n            goto Lnodecl;\n        }\n        else if (pd.ident == Id.startaddress)\n        {\n            if (!pd.args || pd.args.dim != 1)\n                pd.error(\"function name expected for start address\");\n            else\n            {\n                /* https://issues.dlang.org/show_bug.cgi?id=11980\n                 * resolveProperties and ctfeInterpret call are not necessary.\n                 */\n                Expression e = (*pd.args)[0];\n                sc = sc.startCTFE();\n                e = e.expressionSemantic(sc);\n                sc = sc.endCTFE();\n                (*pd.args)[0] = e;\n                Dsymbol sa = getDsymbol(e);\n                if (!sa || !sa.isFuncDeclaration())\n                    pd.error(\"function name expected for start address, not `%s`\", e.toChars());\n            }\n            goto Lnodecl;\n        }\n        else if (pd.ident == Id.Pinline)\n        {\n            goto Ldecl;\n        }\n        else if (pd.ident == Id.mangle)\n        {\n            if (!pd.args)\n                pd.args = new Expressions();\n            if (pd.args.dim != 1)\n            {\n                pd.error(\"string expected for mangled name\");\n                pd.args.setDim(1);\n                (*pd.args)[0] = new ErrorExp(); // error recovery\n                goto Ldecl;\n            }\n\n            auto se = semanticString(sc, (*pd.args)[0], \"mangled name\");\n            if (!se)\n                goto Ldecl;\n            (*pd.args)[0] = se; // Will be used later\n\n            if (!se.len)\n            {\n                pd.error(\"zero-length string not allowed for mangled name\");\n                goto Ldecl;\n            }\n            if (se.sz != 1)\n            {\n                pd.error(\"mangled name characters can only be of type `char`\");\n                goto Ldecl;\n            }\n            version (all)\n            {\n                /* Note: D language specification should not have any assumption about backend\n                 * implementation. Ideally pragma(mangle) can accept a string of any content.\n                 *\n                 * Therefore, this validation is compiler implementation specific.\n                 */\n                for (size_t i = 0; i < se.len;)\n                {\n                    char* p = se.string;\n                    dchar c = p[i];\n                    if (c < 0x80)\n                    {\n                        if (c.isValidMangling)\n                        {\n                            ++i;\n                            continue;\n                        }\n                        else\n                        {\n                            pd.error(\"char 0x%02x not allowed in mangled name\", c);\n                            break;\n                        }\n                    }\n                    if (const msg = utf_decodeChar(se.string, se.len, i, c))\n                    {\n                        pd.error(\"%s\", msg);\n                        break;\n                    }\n                    if (!isUniAlpha(c))\n                    {\n                        pd.error(\"char `0x%04x` not allowed in mangled name\", c);\n                        break;\n                    }\n                }\n            }\n        }\n        else if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor)\n        {\n            if (pd.args && pd.args.dim != 0)\n                pd.error(\"takes no argument\");\n            goto Ldecl;\n        }\n        else if (global.params.ignoreUnsupportedPragmas)\n        {\n            if (global.params.verbose)\n            {\n                /* Print unrecognized pragmas\n                 */\n                OutBuffer buf;\n                buf.writestring(pd.ident.toChars());\n                if (pd.args)\n                {\n                    for (size_t i = 0; i < pd.args.dim; i++)\n                    {\n                        Expression e = (*pd.args)[i];\n                        sc = sc.startCTFE();\n                        e = e.expressionSemantic(sc);\n                        e = resolveProperties(sc, e);\n                        sc = sc.endCTFE();\n                        e = e.ctfeInterpret();\n                        if (i == 0)\n                            buf.writestring(\" (\");\n                        else\n                            buf.writeByte(',');\n                        buf.writestring(e.toChars());\n                    }\n                    if (pd.args.dim)\n                        buf.writeByte(')');\n                }\n                message(\"pragma    %s\", buf.peekString());\n            }\n            goto Lnodecl;\n        }\n        else\n            error(pd.loc, \"unrecognized `pragma(%s)`\", pd.ident.toChars());\n    Ldecl:\n        if (pd.decl)\n        {\n            Scope* sc2 = pd.newScope(sc);\n            for (size_t i = 0; i < pd.decl.dim; i++)\n            {\n                Dsymbol s = (*pd.decl)[i];\n                s.dsymbolSemantic(sc2);\n                if (pd.ident == Id.mangle)\n                {\n                    assert(pd.args && pd.args.dim == 1);\n                    if (auto se = (*pd.args)[0].toStringExp())\n                    {\n                        char* name = cast(char*)mem.xmalloc(se.len + 1);\n                        memcpy(name, se.string, se.len);\n                        name[se.len] = 0;\n                        uint cnt = setMangleOverride(s, name[0 .. se.len]);\n                        if (cnt > 1)\n                            pd.error(\"can only apply to a single declaration\");\n                    }\n                }\n            }\n            if (sc2 != sc)\n                sc2.pop();\n        }\n        return;\n    Lnodecl:\n        if (pd.decl)\n        {\n            pd.error(\"is missing a terminating `;`\");\n            goto Ldecl;\n            // do them anyway, to avoid segfaults.\n        }\n    }\n\n    override void visit(StaticIfDeclaration sid)\n    {\n        attribSemantic(sid);\n    }\n\n    override void visit(StaticForeachDeclaration sfd)\n    {\n        attribSemantic(sfd);\n    }\n\n    private Dsymbols* compileIt(CompileDeclaration cd)\n    {\n        //printf(\"CompileDeclaration::compileIt(loc = %d) %s\\n\", cd.loc.linnum, cd.exp.toChars());\n        OutBuffer buf;\n        if (cd.exps)\n        {\n            foreach (ex; *cd.exps)\n            {\n                sc = sc.startCTFE();\n                auto e = ex.expressionSemantic(sc);\n                e = resolveProperties(sc, e);\n                sc = sc.endCTFE();\n\n                // allowed to contain types as well as expressions\n                e = ctfeInterpretForPragmaMsg(e);\n                if (e.op == TOK.error)\n                {\n                    //errorSupplemental(exp.loc, \"while evaluating `mixin(%s)`\", ex.toChars());\n                    return null;\n                }\n                StringExp se = e.toStringExp();\n                if (se)\n                {\n                    se = se.toUTF8(sc);\n                    buf.printf(\"%.*s\", cast(int)se.len, se.string);\n                }\n                else\n                    buf.printf(\"%s\", e.toChars());\n            }\n        }\n\n        const errors = global.errors;\n        const len = buf.offset;\n        const str = buf.extractString()[0 .. len];\n        scope p = new Parser!ASTCodegen(cd.loc, sc._module, str, false);\n        p.nextToken();\n\n        auto d = p.parseDeclDefs(0);\n        if (p.errors)\n        {\n            assert(global.errors != errors);    // should have caught all these cases\n            return null;\n        }\n        if (p.token.value != TOK.endOfFile)\n        {\n            cd.error(\"incomplete mixin declaration `%s`\", str.ptr);\n            return null;\n        }\n        return d;\n    }\n\n    /***********************************************************\n     * https://dlang.org/spec/module.html#mixin-declaration\n     */\n    override void visit(CompileDeclaration cd)\n    {\n        //printf(\"CompileDeclaration::semantic()\\n\");\n        if (!cd.compiled)\n        {\n            cd.decl = compileIt(cd);\n            cd.AttribDeclaration.addMember(sc, cd.scopesym);\n            cd.compiled = true;\n\n            if (cd._scope && cd.decl)\n            {\n                for (size_t i = 0; i < cd.decl.dim; i++)\n                {\n                    Dsymbol s = (*cd.decl)[i];\n                    s.setScope(cd._scope);\n                }\n            }\n        }\n        attribSemantic(cd);\n    }\n\n    override void visit(UserAttributeDeclaration uad)\n    {\n        //printf(\"UserAttributeDeclaration::semantic() %p\\n\", this);\n        if (uad.decl && !uad._scope)\n            uad.Dsymbol.setScope(sc); // for function local symbols\n        return attribSemantic(uad);\n    }\n\n    override void visit(StaticAssert sa)\n    {\n        if (sa.semanticRun < PASS.semanticdone)\n            sa.semanticRun = PASS.semanticdone;\n    }\n\n    override void visit(DebugSymbol ds)\n    {\n        //printf(\"DebugSymbol::semantic() %s\\n\", toChars());\n        if (ds.semanticRun < PASS.semanticdone)\n            ds.semanticRun = PASS.semanticdone;\n    }\n\n    override void visit(VersionSymbol vs)\n    {\n        if (vs.semanticRun < PASS.semanticdone)\n            vs.semanticRun = PASS.semanticdone;\n    }\n\n    override void visit(Package pkg)\n    {\n        if (pkg.semanticRun < PASS.semanticdone)\n            pkg.semanticRun = PASS.semanticdone;\n    }\n\n    override void visit(Module m)\n    {\n        if (m.semanticRun != PASS.init)\n            return;\n        //printf(\"+Module::semantic(this = %p, '%s'): parent = %p\\n\", this, toChars(), parent);\n        m.semanticRun = PASS.semantic;\n        // Note that modules get their own scope, from scratch.\n        // This is so regardless of where in the syntax a module\n        // gets imported, it is unaffected by context.\n        Scope* sc = m._scope; // see if already got one from importAll()\n        if (!sc)\n        {\n            Scope.createGlobal(m); // create root scope\n        }\n        //printf(\"Module = %p, linkage = %d\\n\", sc.scopesym, sc.linkage);\n        // Pass 1 semantic routines: do public side of the definition\n        for (size_t i = 0; i < m.members.dim; i++)\n        {\n            Dsymbol s = (*m.members)[i];\n            //printf(\"\\tModule('%s'): '%s'.dsymbolSemantic()\\n\", toChars(), s.toChars());\n            s.dsymbolSemantic(sc);\n            m.runDeferredSemantic();\n        }\n        if (m.userAttribDecl)\n        {\n            m.userAttribDecl.dsymbolSemantic(sc);\n        }\n        if (!m._scope)\n        {\n            sc = sc.pop();\n            sc.pop(); // 2 pops because Scope::createGlobal() created 2\n        }\n        m.semanticRun = PASS.semanticdone;\n        //printf(\"-Module::semantic(this = %p, '%s'): parent = %p\\n\", this, toChars(), parent);\n    }\n\n    override void visit(EnumDeclaration ed)\n    {\n        //printf(\"EnumDeclaration::semantic(sd = %p, '%s') %s\\n\", sc.scopesym, sc.scopesym.toChars(), toChars());\n        //printf(\"EnumDeclaration::semantic() %p %s\\n\", this, toChars());\n        if (ed.semanticRun >= PASS.semanticdone)\n            return; // semantic() already completed\n        if (ed.semanticRun == PASS.semantic)\n        {\n            assert(ed.memtype);\n            error(ed.loc, \"circular reference to enum base type `%s`\", ed.memtype.toChars());\n            ed.errors = true;\n            ed.semanticRun = PASS.semanticdone;\n            return;\n        }\n        uint dprogress_save = Module.dprogress;\n\n        Scope* scx = null;\n        if (ed._scope)\n        {\n            sc = ed._scope;\n            scx = ed._scope; // save so we don't make redundant copies\n            ed._scope = null;\n        }\n\n        if (!sc)\n            return;\n\n        ed.parent = sc.parent;\n        ed.type = ed.type.typeSemantic(ed.loc, sc);\n\n        ed.protection = sc.protection;\n        if (sc.stc & STC.deprecated_)\n            ed.isdeprecated = true;\n        ed.userAttribDecl = sc.userAttribDecl;\n\n        ed.semanticRun = PASS.semantic;\n\n        if (!ed.members && !ed.memtype) // enum ident;\n        {\n            ed.semanticRun = PASS.semanticdone;\n            return;\n        }\n\n        if (!ed.symtab)\n            ed.symtab = new DsymbolTable();\n\n        /* The separate, and distinct, cases are:\n         *  1. enum { ... }\n         *  2. enum : memtype { ... }\n         *  3. enum ident { ... }\n         *  4. enum ident : memtype { ... }\n         *  5. enum ident : memtype;\n         *  6. enum ident;\n         */\n\n        if (ed.memtype)\n        {\n            ed.memtype = ed.memtype.typeSemantic(ed.loc, sc);\n\n            /* Check to see if memtype is forward referenced\n             */\n            if (ed.memtype.ty == Tenum)\n            {\n                EnumDeclaration sym = cast(EnumDeclaration)ed.memtype.toDsymbol(sc);\n                if (!sym.memtype || !sym.members || !sym.symtab || sym._scope)\n                {\n                    // memtype is forward referenced, so try again later\n                    ed._scope = scx ? scx : sc.copy();\n                    ed._scope.setNoFree();\n                    ed._scope._module.addDeferredSemantic(ed);\n                    Module.dprogress = dprogress_save;\n                    //printf(\"\\tdeferring %s\\n\", toChars());\n                    ed.semanticRun = PASS.init;\n                    return;\n                }\n            }\n            if (ed.memtype.ty == Tvoid)\n            {\n                ed.error(\"base type must not be `void`\");\n                ed.memtype = Type.terror;\n            }\n            if (ed.memtype.ty == Terror)\n            {\n                ed.errors = true;\n                if (ed.members)\n                {\n                    for (size_t i = 0; i < ed.members.dim; i++)\n                    {\n                        Dsymbol s = (*ed.members)[i];\n                        s.errors = true; // poison all the members\n                    }\n                }\n                ed.semanticRun = PASS.semanticdone;\n                return;\n            }\n        }\n\n        ed.semanticRun = PASS.semanticdone;\n\n        if (!ed.members) // enum ident : memtype;\n            return;\n\n        if (ed.members.dim == 0)\n        {\n            ed.error(\"enum `%s` must have at least one member\", ed.toChars());\n            ed.errors = true;\n            return;\n        }\n\n        Module.dprogress++;\n\n        Scope* sce;\n        if (ed.isAnonymous())\n            sce = sc;\n        else\n        {\n            sce = sc.push(ed);\n            sce.parent = ed;\n        }\n        sce = sce.startCTFE();\n        sce.setNoFree(); // needed for getMaxMinValue()\n\n        /* Each enum member gets the sce scope\n         */\n        for (size_t i = 0; i < ed.members.dim; i++)\n        {\n            EnumMember em = (*ed.members)[i].isEnumMember();\n            if (em)\n                em._scope = sce;\n        }\n\n        if (!ed.added)\n        {\n            /* addMember() is not called when the EnumDeclaration appears as a function statement,\n             * so we have to do what addMember() does and install the enum members in the right symbol\n             * table\n             */\n            ScopeDsymbol scopesym = null;\n            if (ed.isAnonymous())\n            {\n                /* Anonymous enum members get added to enclosing scope.\n                 */\n                for (Scope* sct = sce; 1; sct = sct.enclosing)\n                {\n                    assert(sct);\n                    if (sct.scopesym)\n                    {\n                        scopesym = sct.scopesym;\n                        if (!sct.scopesym.symtab)\n                            sct.scopesym.symtab = new DsymbolTable();\n                        break;\n                    }\n                }\n            }\n            else\n            {\n                // Otherwise enum members are in the EnumDeclaration's symbol table\n                scopesym = ed;\n            }\n\n            for (size_t i = 0; i < ed.members.dim; i++)\n            {\n                EnumMember em = (*ed.members)[i].isEnumMember();\n                if (em)\n                {\n                    em.ed = ed;\n                    em.addMember(sc, scopesym);\n                }\n            }\n        }\n\n        for (size_t i = 0; i < ed.members.dim; i++)\n        {\n            EnumMember em = (*ed.members)[i].isEnumMember();\n            if (em)\n                em.dsymbolSemantic(em._scope);\n        }\n        //printf(\"defaultval = %lld\\n\", defaultval);\n\n        //if (defaultval) printf(\"defaultval: %s %s\\n\", defaultval.toChars(), defaultval.type.toChars());\n        //printf(\"members = %s\\n\", members.toChars());\n    }\n\n    override void visit(EnumMember em)\n    {\n        //printf(\"EnumMember::semantic() %s\\n\", toChars());\n\n        void errorReturn()\n        {\n            em.errors = true;\n            em.semanticRun = PASS.semanticdone;\n        }\n\n        if (em.errors || em.semanticRun >= PASS.semanticdone)\n            return;\n        if (em.semanticRun == PASS.semantic)\n        {\n            em.error(\"circular reference to `enum` member\");\n            return errorReturn();\n        }\n        assert(em.ed);\n\n        em.ed.dsymbolSemantic(sc);\n        if (em.ed.errors)\n            return errorReturn();\n        if (em.errors || em.semanticRun >= PASS.semanticdone)\n            return;\n\n        if (em._scope)\n            sc = em._scope;\n        if (!sc)\n            return;\n\n        em.semanticRun = PASS.semantic;\n\n        em.protection = em.ed.isAnonymous() ? em.ed.protection : Prot(Prot.Kind.public_);\n        em.linkage = LINK.d;\n        em.storage_class |= STC.manifest;\n\n        // https://issues.dlang.org/show_bug.cgi?id=9701\n        if (em.ed.isAnonymous())\n        {\n            if (em.userAttribDecl)\n                em.userAttribDecl.userAttribDecl = em.ed.userAttribDecl;\n            else\n                em.userAttribDecl = em.ed.userAttribDecl;\n        }\n\n        // The first enum member is special\n        bool first = (em == (*em.ed.members)[0]);\n\n        if (em.origType)\n        {\n            em.origType = em.origType.typeSemantic(em.loc, sc);\n            em.type = em.origType;\n            assert(em.value); // \"type id;\" is not a valid enum member declaration\n        }\n\n        if (em.value)\n        {\n            Expression e = em.value;\n            assert(e.dyncast() == DYNCAST.expression);\n            e = e.expressionSemantic(sc);\n            e = resolveProperties(sc, e);\n            e = e.ctfeInterpret();\n            if (e.op == TOK.error)\n                return errorReturn();\n            if (first && !em.ed.memtype && !em.ed.isAnonymous())\n            {\n                em.ed.memtype = e.type;\n                if (em.ed.memtype.ty == Terror)\n                {\n                    em.ed.errors = true;\n                    return errorReturn();\n                }\n                if (em.ed.memtype.ty != Terror)\n                {\n                    /* https://issues.dlang.org/show_bug.cgi?id=11746\n                     * All of named enum members should have same type\n                     * with the first member. If the following members were referenced\n                     * during the first member semantic, their types should be unified.\n                     */\n                    for (size_t i = 0; i < em.ed.members.dim; i++)\n                    {\n                        EnumMember enm = (*em.ed.members)[i].isEnumMember();\n                        if (!enm || enm == em || enm.semanticRun < PASS.semanticdone || enm.origType)\n                            continue;\n\n                        //printf(\"[%d] em = %s, em.semanticRun = %d\\n\", i, toChars(), em.semanticRun);\n                        Expression ev = enm.value;\n                        ev = ev.implicitCastTo(sc, em.ed.memtype);\n                        ev = ev.ctfeInterpret();\n                        ev = ev.castTo(sc, em.ed.type);\n                        if (ev.op == TOK.error)\n                            em.ed.errors = true;\n                        enm.value = ev;\n                    }\n                    if (em.ed.errors)\n                    {\n                        em.ed.memtype = Type.terror;\n                        return errorReturn();\n                    }\n                }\n            }\n\n            if (em.ed.memtype && !em.origType)\n            {\n                e = e.implicitCastTo(sc, em.ed.memtype);\n                e = e.ctfeInterpret();\n\n                // save origValue for better json output\n                em.origValue = e;\n\n                if (!em.ed.isAnonymous())\n                {\n                    e = e.castTo(sc, em.ed.type.addMod(e.type.mod)); // https://issues.dlang.org/show_bug.cgi?id=12385\n                    e = e.ctfeInterpret();\n                }\n            }\n            else if (em.origType)\n            {\n                e = e.implicitCastTo(sc, em.origType);\n                e = e.ctfeInterpret();\n                assert(em.ed.isAnonymous());\n\n                // save origValue for better json output\n                em.origValue = e;\n            }\n            em.value = e;\n        }\n        else if (first)\n        {\n            Type t;\n            if (em.ed.memtype)\n                t = em.ed.memtype;\n            else\n            {\n                t = Type.tint32;\n                if (!em.ed.isAnonymous())\n                    em.ed.memtype = t;\n            }\n            Expression e = new IntegerExp(em.loc, 0, t);\n            e = e.ctfeInterpret();\n\n            // save origValue for better json output\n            em.origValue = e;\n\n            if (!em.ed.isAnonymous())\n            {\n                e = e.castTo(sc, em.ed.type);\n                e = e.ctfeInterpret();\n            }\n            em.value = e;\n        }\n        else\n        {\n            /* Find the previous enum member,\n             * and set this to be the previous value + 1\n             */\n            EnumMember emprev = null;\n            for (size_t i = 0; i < em.ed.members.dim; i++)\n            {\n                EnumMember enm = (*em.ed.members)[i].isEnumMember();\n                if (enm)\n                {\n                    if (enm == em)\n                        break;\n                    emprev = enm;\n                }\n            }\n            assert(emprev);\n            if (emprev.semanticRun < PASS.semanticdone) // if forward reference\n                emprev.dsymbolSemantic(emprev._scope); // resolve it\n            if (emprev.errors)\n                return errorReturn();\n\n            Expression eprev = emprev.value;\n            // .toHeadMutable() due to https://issues.dlang.org/show_bug.cgi?id=18645\n            Type tprev = eprev.type.toHeadMutable().equals(em.ed.type.toHeadMutable())\n                ? em.ed.memtype\n                : eprev.type;\n\n            Expression emax = tprev.getProperty(em.ed.loc, Id.max, 0);\n            emax = emax.expressionSemantic(sc);\n            emax = emax.ctfeInterpret();\n\n            // Set value to (eprev + 1).\n            // But first check that (eprev != emax)\n            assert(eprev);\n            Expression e = new EqualExp(TOK.equal, em.loc, eprev, emax);\n            e = e.expressionSemantic(sc);\n            e = e.ctfeInterpret();\n            if (e.toInteger())\n            {\n                em.error(\"initialization with `%s.%s+1` causes overflow for type `%s`\",\n                    emprev.ed.toChars(), emprev.toChars(), em.ed.memtype.toChars());\n                return errorReturn();\n            }\n\n            // Now set e to (eprev + 1)\n            e = new AddExp(em.loc, eprev, new IntegerExp(em.loc, 1, Type.tint32));\n            e = e.expressionSemantic(sc);\n            e = e.castTo(sc, eprev.type);\n            e = e.ctfeInterpret();\n\n            // save origValue (without cast) for better json output\n            if (e.op != TOK.error) // avoid duplicate diagnostics\n            {\n                assert(emprev.origValue);\n                em.origValue = new AddExp(em.loc, emprev.origValue, new IntegerExp(em.loc, 1, Type.tint32));\n                em.origValue = em.origValue.expressionSemantic(sc);\n                em.origValue = em.origValue.ctfeInterpret();\n            }\n\n            if (e.op == TOK.error)\n                return errorReturn();\n            if (e.type.isfloating())\n            {\n                // Check that e != eprev (not always true for floats)\n                Expression etest = new EqualExp(TOK.equal, em.loc, e, eprev);\n                etest = etest.expressionSemantic(sc);\n                etest = etest.ctfeInterpret();\n                if (etest.toInteger())\n                {\n                    em.error(\"has inexact value due to loss of precision\");\n                    return errorReturn();\n                }\n            }\n            em.value = e;\n        }\n        if (!em.origType)\n            em.type = em.value.type;\n\n        assert(em.origValue);\n        em.semanticRun = PASS.semanticdone;\n    }\n\n    override void visit(TemplateDeclaration tempdecl)\n    {\n        static if (LOG)\n        {\n            printf(\"TemplateDeclaration.dsymbolSemantic(this = %p, id = '%s')\\n\", this, tempdecl.ident.toChars());\n            printf(\"sc.stc = %llx\\n\", sc.stc);\n            printf(\"sc.module = %s\\n\", sc._module.toChars());\n        }\n        if (tempdecl.semanticRun != PASS.init)\n            return; // semantic() already run\n\n        if (tempdecl._scope)\n        {\n            sc = tempdecl._scope;\n            tempdecl._scope = null;\n        }\n        if (!sc)\n            return;\n\n        // Remember templates defined in module object that we need to know about\n        if (sc._module && sc._module.ident == Id.object)\n        {\n            if (tempdecl.ident == Id.RTInfo)\n                Type.rtinfo = tempdecl;\n        }\n\n        /* Remember Scope for later instantiations, but make\n         * a copy since attributes can change.\n         */\n        if (!tempdecl._scope)\n        {\n            tempdecl._scope = sc.copy();\n            tempdecl._scope.setNoFree();\n        }\n\n        tempdecl.semanticRun = PASS.semantic;\n\n        tempdecl.parent = sc.parent;\n        tempdecl.protection = sc.protection;\n        tempdecl.isstatic = tempdecl.toParent().isModule() || (tempdecl._scope.stc & STC.static_);\n\n        if (!tempdecl.isstatic)\n        {\n            if (auto ad = tempdecl.parent.pastMixin().isAggregateDeclaration())\n                ad.makeNested();\n        }\n\n        // Set up scope for parameters\n        auto paramsym = new ScopeDsymbol();\n        paramsym.parent = tempdecl.parent;\n        Scope* paramscope = sc.push(paramsym);\n        paramscope.stc = 0;\n\n        if (global.params.doDocComments)\n        {\n            tempdecl.origParameters = new TemplateParameters(tempdecl.parameters.dim);\n            for (size_t i = 0; i < tempdecl.parameters.dim; i++)\n            {\n                TemplateParameter tp = (*tempdecl.parameters)[i];\n                (*tempdecl.origParameters)[i] = tp.syntaxCopy();\n            }\n        }\n\n        for (size_t i = 0; i < tempdecl.parameters.dim; i++)\n        {\n            TemplateParameter tp = (*tempdecl.parameters)[i];\n            if (!tp.declareParameter(paramscope))\n            {\n                error(tp.loc, \"parameter `%s` multiply defined\", tp.ident.toChars());\n                tempdecl.errors = true;\n            }\n            if (!tp.tpsemantic(paramscope, tempdecl.parameters))\n            {\n                tempdecl.errors = true;\n            }\n            if (i + 1 != tempdecl.parameters.dim && tp.isTemplateTupleParameter())\n            {\n                tempdecl.error(\"template tuple parameter must be last one\");\n                tempdecl.errors = true;\n            }\n        }\n\n        /* Calculate TemplateParameter.dependent\n         */\n        TemplateParameters tparams = TemplateParameters(1);\n        for (size_t i = 0; i < tempdecl.parameters.dim; i++)\n        {\n            TemplateParameter tp = (*tempdecl.parameters)[i];\n            tparams[0] = tp;\n\n            for (size_t j = 0; j < tempdecl.parameters.dim; j++)\n            {\n                // Skip cases like: X(T : T)\n                if (i == j)\n                    continue;\n\n                if (TemplateTypeParameter ttp = (*tempdecl.parameters)[j].isTemplateTypeParameter())\n                {\n                    if (reliesOnTident(ttp.specType, &tparams))\n                        tp.dependent = true;\n                }\n                else if (TemplateAliasParameter tap = (*tempdecl.parameters)[j].isTemplateAliasParameter())\n                {\n                    if (reliesOnTident(tap.specType, &tparams) ||\n                        reliesOnTident(isType(tap.specAlias), &tparams))\n                    {\n                        tp.dependent = true;\n                    }\n                }\n            }\n        }\n\n        paramscope.pop();\n\n        // Compute again\n        tempdecl.onemember = null;\n        if (tempdecl.members)\n        {\n            Dsymbol s;\n            if (Dsymbol.oneMembers(tempdecl.members, &s, tempdecl.ident) && s)\n            {\n                tempdecl.onemember = s;\n                s.parent = tempdecl;\n            }\n        }\n\n        /* BUG: should check:\n         *  o no virtual functions or non-static data members of classes\n         */\n\n        tempdecl.semanticRun = PASS.semanticdone;\n    }\n\n    override void visit(TemplateInstance ti)\n    {\n        templateInstanceSemantic(ti, sc, null);\n    }\n\n    override void visit(TemplateMixin tm)\n    {\n        static if (LOG)\n        {\n            printf(\"+TemplateMixin.dsymbolSemantic('%s', this=%p)\\n\",tm.toChars(), tm);\n            fflush(stdout);\n        }\n        if (tm.semanticRun != PASS.init)\n        {\n            // When a class/struct contains mixin members, and is done over\n            // because of forward references, never reach here so semanticRun\n            // has been reset to PASS.init.\n            static if (LOG)\n            {\n                printf(\"\\tsemantic done\\n\");\n            }\n            return;\n        }\n        tm.semanticRun = PASS.semantic;\n        static if (LOG)\n        {\n            printf(\"\\tdo semantic\\n\");\n        }\n\n        Scope* scx = null;\n        if (tm._scope)\n        {\n            sc = tm._scope;\n            scx = tm._scope; // save so we don't make redundant copies\n            tm._scope = null;\n        }\n\n        /* Run semantic on each argument, place results in tiargs[],\n         * then find best match template with tiargs\n         */\n        if (!tm.findTempDecl(sc) || !tm.semanticTiargs(sc) || !tm.findBestMatch(sc, null))\n        {\n            if (tm.semanticRun == PASS.init) // forward reference had occurred\n            {\n                //printf(\"forward reference - deferring\\n\");\n                tm._scope = scx ? scx : sc.copy();\n                tm._scope.setNoFree();\n                tm._scope._module.addDeferredSemantic(tm);\n                return;\n            }\n\n            tm.inst = tm;\n            tm.errors = true;\n            return; // error recovery\n        }\n\n        auto tempdecl = tm.tempdecl.isTemplateDeclaration();\n        assert(tempdecl);\n\n        if (!tm.ident)\n        {\n            /* Assign scope local unique identifier, as same as lambdas.\n             */\n            const(char)* s = \"__mixin\";\n\n            if (FuncDeclaration func = sc.parent.isFuncDeclaration())\n            {\n                tm.symtab = func.localsymtab;\n                if (tm.symtab)\n                {\n                    // Inside template constraint, symtab is not set yet.\n                    goto L1;\n                }\n            }\n            else\n            {\n                tm.symtab = sc.parent.isScopeDsymbol().symtab;\n            L1:\n                assert(tm.symtab);\n                tm.ident = Identifier.generateId(s, tm.symtab.len + 1);\n                tm.symtab.insert(tm);\n            }\n        }\n\n        tm.inst = tm;\n        tm.parent = sc.parent;\n\n        /* Detect recursive mixin instantiations.\n         */\n        for (Dsymbol s = tm.parent; s; s = s.parent)\n        {\n            //printf(\"\\ts = '%s'\\n\", s.toChars());\n            TemplateMixin tmix = s.isTemplateMixin();\n            if (!tmix || tempdecl != tmix.tempdecl)\n                continue;\n\n            /* Different argument list lengths happen with variadic args\n             */\n            if (tm.tiargs.dim != tmix.tiargs.dim)\n                continue;\n\n            for (size_t i = 0; i < tm.tiargs.dim; i++)\n            {\n                RootObject o = (*tm.tiargs)[i];\n                Type ta = isType(o);\n                Expression ea = isExpression(o);\n                Dsymbol sa = isDsymbol(o);\n                RootObject tmo = (*tmix.tiargs)[i];\n                if (ta)\n                {\n                    Type tmta = isType(tmo);\n                    if (!tmta)\n                        goto Lcontinue;\n                    if (!ta.equals(tmta))\n                        goto Lcontinue;\n                }\n                else if (ea)\n                {\n                    Expression tme = isExpression(tmo);\n                    if (!tme || !ea.equals(tme))\n                        goto Lcontinue;\n                }\n                else if (sa)\n                {\n                    Dsymbol tmsa = isDsymbol(tmo);\n                    if (sa != tmsa)\n                        goto Lcontinue;\n                }\n                else\n                    assert(0);\n            }\n            tm.error(\"recursive mixin instantiation\");\n            return;\n\n        Lcontinue:\n            continue;\n        }\n\n        // Copy the syntax trees from the TemplateDeclaration\n        tm.members = Dsymbol.arraySyntaxCopy(tempdecl.members);\n        if (!tm.members)\n            return;\n\n        tm.symtab = new DsymbolTable();\n\n        for (Scope* sce = sc; 1; sce = sce.enclosing)\n        {\n            ScopeDsymbol sds = sce.scopesym;\n            if (sds)\n            {\n                sds.importScope(tm, Prot(Prot.Kind.public_));\n                break;\n            }\n        }\n\n        static if (LOG)\n        {\n            printf(\"\\tcreate scope for template parameters '%s'\\n\", tm.toChars());\n        }\n        Scope* scy = sc.push(tm);\n        scy.parent = tm;\n\n        tm.argsym = new ScopeDsymbol();\n        tm.argsym.parent = scy.parent;\n        Scope* argscope = scy.push(tm.argsym);\n\n        uint errorsave = global.errors;\n\n        // Declare each template parameter as an alias for the argument type\n        tm.declareParameters(argscope);\n\n        // Add members to enclosing scope, as well as this scope\n        for (size_t i = 0; i < tm.members.dim; i++)\n        {\n            Dsymbol s = (*tm.members)[i];\n            s.addMember(argscope, tm);\n            //printf(\"sc.parent = %p, sc.scopesym = %p\\n\", sc.parent, sc.scopesym);\n            //printf(\"s.parent = %s\\n\", s.parent.toChars());\n        }\n\n        // Do semantic() analysis on template instance members\n        static if (LOG)\n        {\n            printf(\"\\tdo semantic() on template instance members '%s'\\n\", tm.toChars());\n        }\n        Scope* sc2 = argscope.push(tm);\n        //size_t deferred_dim = Module.deferred.dim;\n\n        __gshared int nest;\n        //printf(\"%d\\n\", nest);\n        if (++nest > 500)\n        {\n            global.gag = 0; // ensure error message gets printed\n            tm.error(\"recursive expansion\");\n            fatal();\n        }\n\n        for (size_t i = 0; i < tm.members.dim; i++)\n        {\n            Dsymbol s = (*tm.members)[i];\n            s.setScope(sc2);\n        }\n\n        for (size_t i = 0; i < tm.members.dim; i++)\n        {\n            Dsymbol s = (*tm.members)[i];\n            s.importAll(sc2);\n        }\n\n        for (size_t i = 0; i < tm.members.dim; i++)\n        {\n            Dsymbol s = (*tm.members)[i];\n            s.dsymbolSemantic(sc2);\n        }\n\n        nest--;\n\n        /* In DeclDefs scope, TemplateMixin does not have to handle deferred symbols.\n         * Because the members would already call Module.addDeferredSemantic() for themselves.\n         * See Struct, Class, Interface, and EnumDeclaration.dsymbolSemantic().\n         */\n        //if (!sc.func && Module.deferred.dim > deferred_dim) {}\n\n        AggregateDeclaration ad = tm.toParent().isAggregateDeclaration();\n        if (sc.func && !ad)\n        {\n            tm.semantic2(sc2);\n            tm.semantic3(sc2);\n        }\n\n        // Give additional context info if error occurred during instantiation\n        if (global.errors != errorsave)\n        {\n            tm.error(\"error instantiating\");\n            tm.errors = true;\n        }\n\n        sc2.pop();\n        argscope.pop();\n        scy.pop();\n\n        static if (LOG)\n        {\n            printf(\"-TemplateMixin.dsymbolSemantic('%s', this=%p)\\n\", tm.toChars(), tm);\n        }\n    }\n\n    override void visit(Nspace ns)\n    {\n        if (ns.semanticRun != PASS.init)\n            return;\n        static if (LOG)\n        {\n            printf(\"+Nspace::semantic('%s')\\n\", ns.toChars());\n        }\n        if (ns._scope)\n        {\n            sc = ns._scope;\n            ns._scope = null;\n        }\n        if (!sc)\n            return;\n\n        ns.semanticRun = PASS.semantic;\n        ns.parent = sc.parent;\n        if (ns.members)\n        {\n            assert(sc);\n            sc = sc.push(ns);\n            sc.linkage = LINK.cpp; // note that namespaces imply C++ linkage\n            sc.parent = ns;\n            foreach (s; *ns.members)\n            {\n                s.importAll(sc);\n            }\n            foreach (s; *ns.members)\n            {\n                static if (LOG)\n                {\n                    printf(\"\\tmember '%s', kind = '%s'\\n\", s.toChars(), s.kind());\n                }\n                s.dsymbolSemantic(sc);\n            }\n            sc.pop();\n        }\n        ns.semanticRun = PASS.semanticdone;\n        static if (LOG)\n        {\n            printf(\"-Nspace::semantic('%s')\\n\", ns.toChars());\n        }\n    }\n\n    void funcDeclarationSemantic(FuncDeclaration funcdecl)\n    {\n        TypeFunction f;\n        AggregateDeclaration ad;\n        InterfaceDeclaration id;\n\n        version (none)\n        {\n            printf(\"FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\\n\", sc, funcdecl, funcdecl.toPrettyChars(), sc.linkage);\n            if (funcdecl.isFuncLiteralDeclaration())\n                printf(\"\\tFuncLiteralDeclaration()\\n\");\n            printf(\"sc.parent = %s, parent = %s\\n\", sc.parent.toChars(), funcdecl.parent ? funcdecl.parent.toChars() : \"\");\n            printf(\"type: %p, %s\\n\", funcdecl.type, funcdecl.type.toChars());\n        }\n\n        if (funcdecl.semanticRun != PASS.init && funcdecl.isFuncLiteralDeclaration())\n        {\n            /* Member functions that have return types that are\n             * forward references can have semantic() run more than\n             * once on them.\n             * See test\\interface2.d, test20\n             */\n            return;\n        }\n\n        if (funcdecl.semanticRun >= PASS.semanticdone)\n            return;\n        assert(funcdecl.semanticRun <= PASS.semantic);\n        funcdecl.semanticRun = PASS.semantic;\n\n        if (funcdecl._scope)\n        {\n            sc = funcdecl._scope;\n            funcdecl._scope = null;\n        }\n\n        if (!sc || funcdecl.errors)\n            return;\n\n        funcdecl.parent = sc.parent;\n        Dsymbol parent = funcdecl.toParent();\n\n        funcdecl.foverrides.setDim(0); // reset in case semantic() is being retried for this function\n\n        funcdecl.storage_class |= sc.stc & ~STC.ref_;\n        ad = funcdecl.isThis();\n        // Don't nest structs b/c of generated methods which should not access the outer scopes.\n        // https://issues.dlang.org/show_bug.cgi?id=16627\n        if (ad && !funcdecl.generated)\n        {\n            funcdecl.storage_class |= ad.storage_class & (STC.TYPECTOR | STC.synchronized_);\n            ad.makeNested();\n        }\n        if (sc.func)\n            funcdecl.storage_class |= sc.func.storage_class & STC.disable;\n        // Remove prefix storage classes silently.\n        if ((funcdecl.storage_class & STC.TYPECTOR) && !(ad || funcdecl.isNested()))\n            funcdecl.storage_class &= ~STC.TYPECTOR;\n\n        //printf(\"function storage_class = x%llx, sc.stc = x%llx, %x\\n\", storage_class, sc.stc, Declaration::isFinal());\n\n        if (sc.flags & SCOPE.compile)\n            funcdecl.flags |= FUNCFLAG.compileTimeOnly; // don't emit code for this function\n\n        FuncLiteralDeclaration fld = funcdecl.isFuncLiteralDeclaration();\n        if (fld && fld.treq)\n        {\n            Type treq = fld.treq;\n            assert(treq.nextOf().ty == Tfunction);\n            if (treq.ty == Tdelegate)\n                fld.tok = TOK.delegate_;\n            else if (treq.ty == Tpointer && treq.nextOf().ty == Tfunction)\n                fld.tok = TOK.function_;\n            else\n                assert(0);\n            funcdecl.linkage = treq.nextOf().toTypeFunction().linkage;\n        }\n        else\n            funcdecl.linkage = sc.linkage;\n        funcdecl.inlining = sc.inlining;\n        funcdecl.protection = sc.protection;\n        funcdecl.userAttribDecl = sc.userAttribDecl;\n\n        if (!funcdecl.originalType)\n            funcdecl.originalType = funcdecl.type.syntaxCopy();\n        if (funcdecl.type.ty != Tfunction)\n        {\n            if (funcdecl.type.ty != Terror)\n            {\n                funcdecl.error(\"`%s` must be a function instead of `%s`\", funcdecl.toChars(), funcdecl.type.toChars());\n                funcdecl.type = Type.terror;\n            }\n            funcdecl.errors = true;\n            return;\n        }\n        if (!funcdecl.type.deco)\n        {\n            sc = sc.push();\n            sc.stc |= funcdecl.storage_class & (STC.disable | STC.deprecated_); // forward to function type\n\n            TypeFunction tf = funcdecl.type.toTypeFunction();\n            if (sc.func)\n            {\n                /* If the nesting parent is pure without inference,\n                 * then this function defaults to pure too.\n                 *\n                 *  auto foo() pure {\n                 *    auto bar() {}     // become a weak purity function\n                 *    class C {         // nested class\n                 *      auto baz() {}   // become a weak purity function\n                 *    }\n                 *\n                 *    static auto boo() {}   // typed as impure\n                 *    // Even though, boo cannot call any impure functions.\n                 *    // See also Expression::checkPurity().\n                 *  }\n                 */\n                if (tf.purity == PURE.impure && (funcdecl.isNested() || funcdecl.isThis()))\n                {\n                    FuncDeclaration fd = null;\n                    for (Dsymbol p = funcdecl.toParent2(); p; p = p.toParent2())\n                    {\n                        if (AggregateDeclaration adx = p.isAggregateDeclaration())\n                        {\n                            if (adx.isNested())\n                                continue;\n                            break;\n                        }\n                        if ((fd = p.isFuncDeclaration()) !is null)\n                            break;\n                    }\n\n                    /* If the parent's purity is inferred, then this function's purity needs\n                     * to be inferred first.\n                     */\n                    if (fd && fd.isPureBypassingInference() >= PURE.weak && !funcdecl.isInstantiated())\n                    {\n                        tf.purity = PURE.fwdref; // default to pure\n                    }\n                }\n            }\n\n            if (tf.isref)\n                sc.stc |= STC.ref_;\n            if (tf.isscope)\n                sc.stc |= STC.scope_;\n            if (tf.isnothrow)\n                sc.stc |= STC.nothrow_;\n            if (tf.isnogc)\n                sc.stc |= STC.nogc;\n            if (tf.isproperty)\n                sc.stc |= STC.property;\n            if (tf.purity == PURE.fwdref)\n                sc.stc |= STC.pure_;\n            if (tf.trust != TRUST.default_)\n                sc.stc &= ~(STC.safe | STC.system | STC.trusted);\n            if (tf.trust == TRUST.safe)\n                sc.stc |= STC.safe;\n            if (tf.trust == TRUST.system)\n                sc.stc |= STC.system;\n            if (tf.trust == TRUST.trusted)\n                sc.stc |= STC.trusted;\n\n            if (funcdecl.isCtorDeclaration())\n            {\n                sc.flags |= SCOPE.ctor;\n                Type tret = ad.handleType();\n                assert(tret);\n                tret = tret.addStorageClass(funcdecl.storage_class | sc.stc);\n                tret = tret.addMod(funcdecl.type.mod);\n                tf.next = tret;\n                if (ad.isStructDeclaration())\n                    sc.stc |= STC.ref_;\n            }\n\n            // 'return' on a non-static class member function implies 'scope' as well\n            if (ad && ad.isClassDeclaration() && (tf.isreturn || sc.stc & STC.return_) && !(sc.stc & STC.static_))\n                sc.stc |= STC.scope_;\n\n            // If 'this' has no pointers, remove 'scope' as it has no meaning\n            if (sc.stc & STC.scope_ && ad && ad.isStructDeclaration() && !ad.type.hasPointers())\n            {\n                sc.stc &= ~STC.scope_;\n                tf.isscope = false;\n            }\n\n            sc.linkage = funcdecl.linkage;\n\n            if (!tf.isNaked() && !(funcdecl.isThis() || funcdecl.isNested()))\n            {\n                OutBuffer buf;\n                MODtoBuffer(&buf, tf.mod);\n                funcdecl.error(\"without `this` cannot be `%s`\", buf.peekString());\n                tf.mod = 0; // remove qualifiers\n            }\n\n            /* Apply const, immutable, wild and shared storage class\n             * to the function type. Do this before type semantic.\n             */\n            auto stc = funcdecl.storage_class;\n            if (funcdecl.type.isImmutable())\n                stc |= STC.immutable_;\n            if (funcdecl.type.isConst())\n                stc |= STC.const_;\n            if (funcdecl.type.isShared() || funcdecl.storage_class & STC.synchronized_)\n                stc |= STC.shared_;\n            if (funcdecl.type.isWild())\n                stc |= STC.wild;\n            funcdecl.type = funcdecl.type.addSTC(stc);\n\n            funcdecl.type = funcdecl.type.typeSemantic(funcdecl.loc, sc);\n            sc = sc.pop();\n        }\n        if (funcdecl.type.ty != Tfunction)\n        {\n            if (funcdecl.type.ty != Terror)\n            {\n                funcdecl.error(\"`%s` must be a function instead of `%s`\", funcdecl.toChars(), funcdecl.type.toChars());\n                funcdecl.type = Type.terror;\n            }\n            funcdecl.errors = true;\n            return;\n        }\n        else\n        {\n            // Merge back function attributes into 'originalType'.\n            // It's used for mangling, ddoc, and json output.\n            TypeFunction tfo = funcdecl.originalType.toTypeFunction();\n            TypeFunction tfx = funcdecl.type.toTypeFunction();\n            tfo.mod = tfx.mod;\n            tfo.isscope = tfx.isscope;\n            tfo.isscopeinferred = tfx.isscopeinferred;\n            tfo.isref = tfx.isref;\n            tfo.isnothrow = tfx.isnothrow;\n            tfo.isnogc = tfx.isnogc;\n            tfo.isproperty = tfx.isproperty;\n            tfo.purity = tfx.purity;\n            tfo.trust = tfx.trust;\n\n            funcdecl.storage_class &= ~(STC.TYPECTOR | STC.FUNCATTR);\n        }\n\n        f = cast(TypeFunction)funcdecl.type;\n\n        if ((funcdecl.storage_class & STC.auto_) && !f.isref && !funcdecl.inferRetType)\n            funcdecl.error(\"storage class `auto` has no effect if return type is not inferred\");\n\n        /* Functions can only be 'scope' if they have a 'this'\n         */\n        if (f.isscope && !funcdecl.isNested() && !ad)\n        {\n            funcdecl.error(\"functions cannot be `scope`\");\n        }\n\n        if (f.isreturn && !funcdecl.needThis() && !funcdecl.isNested())\n        {\n            /* Non-static nested functions have a hidden 'this' pointer to which\n             * the 'return' applies\n             */\n            funcdecl.error(\"`static` member has no `this` to which `return` can apply\");\n        }\n\n        if (funcdecl.isAbstract() && !funcdecl.isVirtual())\n        {\n            const(char)* sfunc;\n            if (funcdecl.isStatic())\n                sfunc = \"static\";\n            else if (funcdecl.protection.kind == Prot.Kind.private_ || funcdecl.protection.kind == Prot.Kind.package_)\n                sfunc = protectionToChars(funcdecl.protection.kind);\n            else\n                sfunc = \"final\";\n            funcdecl.error(\"`%s` functions cannot be `abstract`\", sfunc);\n        }\n\n        if (funcdecl.isOverride() && !funcdecl.isVirtual())\n        {\n            Prot.Kind kind = funcdecl.prot().kind;\n            if ((kind == Prot.Kind.private_ || kind == Prot.Kind.package_) && funcdecl.isMember())\n                funcdecl.error(\"`%s` method is not virtual and cannot override\", protectionToChars(kind));\n            else\n                funcdecl.error(\"cannot override a non-virtual function\");\n        }\n\n        if (funcdecl.isAbstract() && funcdecl.isFinalFunc())\n            funcdecl.error(\"cannot be both `final` and `abstract`\");\n        version (none)\n        {\n            if (funcdecl.isAbstract() && funcdecl.fbody)\n                funcdecl.error(\"`abstract` functions cannot have bodies\");\n        }\n\n        version (none)\n        {\n            if (funcdecl.isStaticConstructor() || funcdecl.isStaticDestructor())\n            {\n                if (!funcdecl.isStatic() || funcdecl.type.nextOf().ty != Tvoid)\n                    funcdecl.error(\"static constructors / destructors must be `static void`\");\n                if (f.arguments && f.arguments.dim)\n                    funcdecl.error(\"static constructors / destructors must have empty parameter list\");\n                // BUG: check for invalid storage classes\n            }\n        }\n\n        id = parent.isInterfaceDeclaration();\n        if (id)\n        {\n            funcdecl.storage_class |= STC.abstract_;\n            if (funcdecl.isCtorDeclaration() || funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration() || funcdecl.isNewDeclaration() || funcdecl.isDelete())\n                funcdecl.error(\"constructors, destructors, postblits, invariants, new and delete functions are not allowed in interface `%s`\", id.toChars());\n            if (funcdecl.fbody && funcdecl.isVirtual())\n                funcdecl.error(\"function body only allowed in `final` functions in interface `%s`\", id.toChars());\n        }\n        if (UnionDeclaration ud = parent.isUnionDeclaration())\n        {\n            if (funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration())\n                funcdecl.error(\"destructors, postblits and invariants are not allowed in union `%s`\", ud.toChars());\n        }\n\n        if (StructDeclaration sd = parent.isStructDeclaration())\n        {\n            if (funcdecl.isCtorDeclaration())\n            {\n                goto Ldone;\n            }\n        }\n\n        if (ClassDeclaration cd = parent.isClassDeclaration())\n        {\n            if (funcdecl.isCtorDeclaration())\n            {\n                goto Ldone;\n            }\n\n            if (funcdecl.storage_class & STC.abstract_)\n                cd.isabstract = Abstract.yes;\n\n            // if static function, do not put in vtbl[]\n            if (!funcdecl.isVirtual())\n            {\n                //printf(\"\\tnot virtual\\n\");\n                goto Ldone;\n            }\n            // Suppress further errors if the return type is an error\n            if (funcdecl.type.nextOf() == Type.terror)\n                goto Ldone;\n\n            bool may_override = false;\n            for (size_t i = 0; i < cd.baseclasses.dim; i++)\n            {\n                BaseClass* b = (*cd.baseclasses)[i];\n                ClassDeclaration cbd = b.type.toBasetype().isClassHandle();\n                if (!cbd)\n                    continue;\n                for (size_t j = 0; j < cbd.vtbl.dim; j++)\n                {\n                    FuncDeclaration f2 = cbd.vtbl[j].isFuncDeclaration();\n                    if (!f2 || f2.ident != funcdecl.ident)\n                        continue;\n                    if (cbd.parent && cbd.parent.isTemplateInstance())\n                    {\n                        if (!f2.functionSemantic())\n                            goto Ldone;\n                    }\n                    may_override = true;\n                }\n            }\n            if (may_override && funcdecl.type.nextOf() is null)\n            {\n                /* If same name function exists in base class but 'this' is auto return,\n                 * cannot find index of base class's vtbl[] to override.\n                 */\n                funcdecl.error(\"return type inference is not supported if may override base class function\");\n            }\n\n            /* Find index of existing function in base class's vtbl[] to override\n             * (the index will be the same as in cd's current vtbl[])\n             */\n            int vi = cd.baseClass ? funcdecl.findVtblIndex(&cd.baseClass.vtbl, cast(int)cd.baseClass.vtbl.dim) : -1;\n\n            bool doesoverride = false;\n            switch (vi)\n            {\n            case -1:\n            Lintro:\n                /* Didn't find one, so\n                 * This is an 'introducing' function which gets a new\n                 * slot in the vtbl[].\n                 */\n\n                // Verify this doesn't override previous final function\n                if (cd.baseClass)\n                {\n                    Dsymbol s = cd.baseClass.search(funcdecl.loc, funcdecl.ident);\n                    if (s)\n                    {\n                        FuncDeclaration f2 = s.isFuncDeclaration();\n                        if (f2)\n                        {\n                            f2 = f2.overloadExactMatch(funcdecl.type);\n                            if (f2 && f2.isFinalFunc() && f2.prot().kind != Prot.Kind.private_)\n                                funcdecl.error(\"cannot override `final` function `%s`\", f2.toPrettyChars());\n                        }\n                    }\n                }\n\n                /* These quirky conditions mimic what VC++ appears to do\n                 */\n                if (global.params.mscoff && cd.classKind == ClassKind.cpp &&\n                    cd.baseClass && cd.baseClass.vtbl.dim)\n                {\n                    /* if overriding an interface function, then this is not\n                     * introducing and don't put it in the class vtbl[]\n                     */\n                    funcdecl.interfaceVirtual = funcdecl.overrideInterface();\n                    if (funcdecl.interfaceVirtual)\n                    {\n                        //printf(\"\\tinterface function %s\\n\", toChars());\n                        cd.vtblFinal.push(funcdecl);\n                        goto Linterfaces;\n                    }\n                }\n\n                if (funcdecl.isFinalFunc())\n                {\n                    // Don't check here, as it may override an interface function\n                    //if (isOverride())\n                    //    error(\"is marked as override, but does not override any function\");\n                    cd.vtblFinal.push(funcdecl);\n                }\n                else\n                {\n                    //printf(\"\\tintroducing function %s\\n\", toChars());\n                    funcdecl.introducing = 1;\n                    if (cd.classKind == ClassKind.cpp && Target.reverseCppOverloads)\n                    {\n                        // with dmc, overloaded functions are grouped and in reverse order\n                        funcdecl.vtblIndex = cast(int)cd.vtbl.dim;\n                        for (size_t i = 0; i < cd.vtbl.dim; i++)\n                        {\n                            if (cd.vtbl[i].ident == funcdecl.ident && cd.vtbl[i].parent == parent)\n                            {\n                                funcdecl.vtblIndex = cast(int)i;\n                                break;\n                            }\n                        }\n                        // shift all existing functions back\n                        for (size_t i = cd.vtbl.dim; i > funcdecl.vtblIndex; i--)\n                        {\n                            FuncDeclaration fd = cd.vtbl[i - 1].isFuncDeclaration();\n                            assert(fd);\n                            fd.vtblIndex++;\n                        }\n                        cd.vtbl.insert(funcdecl.vtblIndex, funcdecl);\n                    }\n                    else\n                    {\n                        // Append to end of vtbl[]\n                        vi = cast(int)cd.vtbl.dim;\n                        cd.vtbl.push(funcdecl);\n                        funcdecl.vtblIndex = vi;\n                    }\n                }\n                break;\n\n            case -2:\n                // can't determine because of forward references\n                funcdecl.errors = true;\n                return;\n\n            default:\n                {\n                    FuncDeclaration fdv = cd.baseClass.vtbl[vi].isFuncDeclaration();\n                    FuncDeclaration fdc = cd.vtbl[vi].isFuncDeclaration();\n                    // This function is covariant with fdv\n\n                    if (fdc == funcdecl)\n                    {\n                        doesoverride = true;\n                        break;\n                    }\n\n                    if (fdc.toParent() == parent)\n                    {\n                        //printf(\"vi = %d,\\tthis = %p %s %s @ [%s]\\n\\tfdc  = %p %s %s @ [%s]\\n\\tfdv  = %p %s %s @ [%s]\\n\",\n                        //        vi, this, this.toChars(), this.type.toChars(), this.loc.toChars(),\n                        //            fdc,  fdc .toChars(), fdc .type.toChars(), fdc .loc.toChars(),\n                        //            fdv,  fdv .toChars(), fdv .type.toChars(), fdv .loc.toChars());\n\n                        // fdc overrides fdv exactly, then this introduces new function.\n                        if (fdc.type.mod == fdv.type.mod && funcdecl.type.mod != fdv.type.mod)\n                            goto Lintro;\n                    }\n\n                    if (fdv.isDeprecated)\n                        deprecation(funcdecl.loc, \"`%s` is overriding the deprecated method `%s`\",\n                                    funcdecl.toPrettyChars, fdv.toPrettyChars);\n\n                    // This function overrides fdv\n                    if (fdv.isFinalFunc())\n                        funcdecl.error(\"cannot override `final` function `%s`\", fdv.toPrettyChars());\n\n                    if (!funcdecl.isOverride())\n                    {\n                        if (fdv.isFuture())\n                        {\n                            deprecation(funcdecl.loc, \"`@__future` base class method `%s` is being overridden by `%s`; rename the latter\", fdv.toPrettyChars(), funcdecl.toPrettyChars());\n                            // Treat 'this' as an introducing function, giving it a separate hierarchy in the vtbl[]\n                            goto Lintro;\n                        }\n                        else\n                        {\n                            int vi2 = funcdecl.findVtblIndex(&cd.baseClass.vtbl, cast(int)cd.baseClass.vtbl.dim, false);\n                            if (vi2 < 0)\n                                // https://issues.dlang.org/show_bug.cgi?id=17349\n                                deprecation(funcdecl.loc, \"cannot implicitly override base class method `%s` with `%s`; add `override` attribute\", fdv.toPrettyChars(), funcdecl.toPrettyChars());\n                            else\n                                error(funcdecl.loc, \"cannot implicitly override base class method `%s` with `%s`; add `override` attribute\", fdv.toPrettyChars(), funcdecl.toPrettyChars());\n                        }\n                    }\n                    doesoverride = true;\n                    if (fdc.toParent() == parent)\n                    {\n                        // If both are mixins, or both are not, then error.\n                        // If either is not, the one that is not overrides the other.\n                        bool thismixin = funcdecl.parent.isClassDeclaration() !is null;\n                        bool fdcmixin = fdc.parent.isClassDeclaration() !is null;\n                        if (thismixin == fdcmixin)\n                        {\n                            funcdecl.error(\"multiple overrides of same function\");\n                        }\n                        else if (!thismixin) // fdc overrides fdv\n                        {\n                            // this doesn't override any function\n                            break;\n                        }\n                    }\n                    cd.vtbl[vi] = funcdecl;\n                    funcdecl.vtblIndex = vi;\n\n                    /* Remember which functions this overrides\n                     */\n                    funcdecl.foverrides.push(fdv);\n\n                    /* This works by whenever this function is called,\n                     * it actually returns tintro, which gets dynamically\n                     * cast to type. But we know that tintro is a base\n                     * of type, so we could optimize it by not doing a\n                     * dynamic cast, but just subtracting the isBaseOf()\n                     * offset if the value is != null.\n                     */\n\n                    if (fdv.tintro)\n                        funcdecl.tintro = fdv.tintro;\n                    else if (!funcdecl.type.equals(fdv.type))\n                    {\n                        /* Only need to have a tintro if the vptr\n                         * offsets differ\n                         */\n                        int offset;\n                        if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))\n                        {\n                            funcdecl.tintro = fdv.type;\n                        }\n                    }\n                    break;\n                }\n            }\n\n            /* Go through all the interface bases.\n             * If this function is covariant with any members of those interface\n             * functions, set the tintro.\n             */\n        Linterfaces:\n            foreach (b; cd.interfaces)\n            {\n                vi = funcdecl.findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.dim);\n                switch (vi)\n                {\n                case -1:\n                    break;\n\n                case -2:\n                    // can't determine because of forward references\n                    funcdecl.errors = true;\n                    return;\n\n                default:\n                    {\n                        auto fdv = cast(FuncDeclaration)b.sym.vtbl[vi];\n                        Type ti = null;\n\n                        /* Remember which functions this overrides\n                         */\n                        funcdecl.foverrides.push(fdv);\n\n                        /* Should we really require 'override' when implementing\n                         * an interface function?\n                         */\n                        //if (!isOverride())\n                        //    warning(loc, \"overrides base class function %s, but is not marked with 'override'\", fdv.toPrettyChars());\n\n                        if (fdv.tintro)\n                            ti = fdv.tintro;\n                        else if (!funcdecl.type.equals(fdv.type))\n                        {\n                            /* Only need to have a tintro if the vptr\n                             * offsets differ\n                             */\n                            int offset;\n                            if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))\n                            {\n                                ti = fdv.type;\n                            }\n                        }\n                        if (ti)\n                        {\n                            if (funcdecl.tintro)\n                            {\n                                if (!funcdecl.tintro.nextOf().equals(ti.nextOf()) && !funcdecl.tintro.nextOf().isBaseOf(ti.nextOf(), null) && !ti.nextOf().isBaseOf(funcdecl.tintro.nextOf(), null))\n                                {\n                                    funcdecl.error(\"incompatible covariant types `%s` and `%s`\", funcdecl.tintro.toChars(), ti.toChars());\n                                }\n                            }\n                            funcdecl.tintro = ti;\n                        }\n                        goto L2;\n                    }\n                }\n            }\n\n            if (!doesoverride && funcdecl.isOverride() && (funcdecl.type.nextOf() || !may_override))\n            {\n                BaseClass* bc = null;\n                Dsymbol s = null;\n                for (size_t i = 0; i < cd.baseclasses.dim; i++)\n                {\n                    bc = (*cd.baseclasses)[i];\n                    s = bc.sym.search_correct(funcdecl.ident);\n                    if (s)\n                        break;\n                }\n\n                if (s)\n                {\n                    HdrGenState hgs;\n                    OutBuffer buf;\n\n                    auto fd = s.isFuncDeclaration();\n                    functionToBufferFull(cast(TypeFunction)(funcdecl.type), &buf,\n                        new Identifier(funcdecl.toPrettyChars()), &hgs, null);\n                    const(char)* funcdeclToChars = buf.peekString();\n\n                    if (fd)\n                    {\n                        OutBuffer buf1;\n\n                        functionToBufferFull(cast(TypeFunction)(fd.type), &buf1,\n                            new Identifier(fd.toPrettyChars()), &hgs, null);\n\n                        error(funcdecl.loc, \"function `%s` does not override any function, did you mean to override `%s`?\",\n                            funcdeclToChars, buf1.peekString());\n                    }\n                    else\n                    {\n                        error(funcdecl.loc, \"function `%s` does not override any function, did you mean to override %s `%s`?\",\n                            funcdeclToChars, s.kind, s.toPrettyChars());\n                        errorSupplemental(funcdecl.loc, \"Functions are the only declarations that may be overriden\");\n                    }\n                }\n                else\n                    funcdecl.error(\"does not override any function\");\n            }\n\n        L2:\n            /* Go through all the interface bases.\n             * Disallow overriding any final functions in the interface(s).\n             */\n            foreach (b; cd.interfaces)\n            {\n                if (b.sym)\n                {\n                    Dsymbol s = search_function(b.sym, funcdecl.ident);\n                    if (s)\n                    {\n                        FuncDeclaration f2 = s.isFuncDeclaration();\n                        if (f2)\n                        {\n                            f2 = f2.overloadExactMatch(funcdecl.type);\n                            if (f2 && f2.isFinalFunc() && f2.prot().kind != Prot.Kind.private_)\n                                funcdecl.error(\"cannot override `final` function `%s.%s`\", b.sym.toChars(), f2.toPrettyChars());\n                        }\n                    }\n                }\n            }\n\n            if (funcdecl.isOverride)\n            {\n                if (funcdecl.storage_class & STC.disable)\n                    deprecation(funcdecl.loc,\n                                \"`%s` cannot be annotated with `@disable` because it is overriding a function in the base class\",\n                                funcdecl.toPrettyChars);\n                if (funcdecl.isDeprecated)\n                    deprecation(funcdecl.loc,\n                                \"`%s` cannot be marked as `deprecated` because it is overriding a function in the base class\",\n                                funcdecl.toPrettyChars);\n            }\n\n        }\n        else if (funcdecl.isOverride() && !parent.isTemplateInstance())\n            funcdecl.error(\"`override` only applies to class member functions\");\n\n        // Reflect this.type to f because it could be changed by findVtblIndex\n        f = funcdecl.type.toTypeFunction();\n\n    Ldone:\n        if (!funcdecl.fbody && !funcdecl.allowsContractWithoutBody())\n            funcdecl.error(\"`in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract\");\n\n        /* Do not allow template instances to add virtual functions\n         * to a class.\n         */\n        if (funcdecl.isVirtual())\n        {\n            TemplateInstance ti = parent.isTemplateInstance();\n            if (ti)\n            {\n                // Take care of nested templates\n                while (1)\n                {\n                    TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();\n                    if (!ti2)\n                        break;\n                    ti = ti2;\n                }\n\n                // If it's a member template\n                ClassDeclaration cd = ti.tempdecl.isClassMember();\n                if (cd)\n                {\n                    funcdecl.error(\"cannot use template to add virtual function to class `%s`\", cd.toChars());\n                }\n            }\n        }\n\n        if (funcdecl.isMain())\n            funcdecl.checkDmain();       // Check main() parameters and return type\n\n        /* Purity and safety can be inferred for some functions by examining\n         * the function body.\n         */\n        if (funcdecl.canInferAttributes(sc))\n            funcdecl.initInferAttributes();\n\n        Module.dprogress++;\n        funcdecl.semanticRun = PASS.semanticdone;\n\n        /* Save scope for possible later use (if we need the\n         * function internals)\n         */\n        funcdecl._scope = sc.copy();\n        funcdecl._scope.setNoFree();\n\n        __gshared bool printedMain = false; // semantic might run more than once\n        if (global.params.verbose && !printedMain)\n        {\n            const(char)* type = funcdecl.isMain() ? \"main\" : funcdecl.isWinMain() ? \"winmain\" : funcdecl.isDllMain() ? \"dllmain\" : cast(const(char)*)null;\n            Module mod = sc._module;\n\n            if (type && mod)\n            {\n                printedMain = true;\n                const(char)* name = FileName.searchPath(global.path, mod.srcfile.toChars(), true);\n                message(\"entry     %-10s\\t%s\", type, name);\n            }\n        }\n\n        if (funcdecl.fbody && funcdecl.isMain() && sc._module.isRoot())\n            Compiler.genCmain(sc);\n\n        assert(funcdecl.type.ty != Terror || funcdecl.errors);\n\n        // semantic for parameters' UDAs\n        foreach (i; 0 .. Parameter.dim(f.parameters))\n        {\n            Parameter param = Parameter.getNth(f.parameters, i);\n            if (param && param.userAttribDecl)\n                param.userAttribDecl.dsymbolSemantic(sc);\n        }\n    }\n\n     /// Do the semantic analysis on the external interface to the function.\n    override void visit(FuncDeclaration funcdecl)\n    {\n        funcDeclarationSemantic(funcdecl);\n    }\n\n    override void visit(CtorDeclaration ctd)\n    {\n        //printf(\"CtorDeclaration::semantic() %s\\n\", toChars());\n        if (ctd.semanticRun >= PASS.semanticdone)\n            return;\n        if (ctd._scope)\n        {\n            sc = ctd._scope;\n            ctd._scope = null;\n        }\n\n        ctd.parent = sc.parent;\n        Dsymbol p = ctd.toParent2();\n        AggregateDeclaration ad = p.isAggregateDeclaration();\n        if (!ad)\n        {\n            error(ctd.loc, \"constructor can only be a member of aggregate, not %s `%s`\", p.kind(), p.toChars());\n            ctd.type = Type.terror;\n            ctd.errors = true;\n            return;\n        }\n\n        sc = sc.push();\n\n        if (sc.stc & STC.static_)\n        {\n            // Deprecated in 2018-04.\n            // Change to error in 2019-04.\n            // @@@DEPRECATED_2019-04@@@.\n            if (sc.stc & STC.shared_)\n                deprecation(ctd.loc, \"`shared static` has no effect on a constructor inside a `shared static` block. Use `shared static this()`\");\n            else\n                deprecation(ctd.loc, \"`static` has no effect on a constructor inside a `static` block. Use `static this()`\");\n        }\n\n        sc.stc &= ~STC.static_; // not a static constructor\n        sc.flags |= SCOPE.ctor;\n\n        funcDeclarationSemantic(ctd);\n\n        sc.pop();\n\n        if (ctd.errors)\n            return;\n\n        TypeFunction tf = ctd.type.toTypeFunction();\n\n        /* See if it's the default constructor\n         * But, template constructor should not become a default constructor.\n         */\n        if (ad && (!ctd.parent.isTemplateInstance() || ctd.parent.isTemplateMixin()))\n        {\n            immutable dim = Parameter.dim(tf.parameters);\n\n            if (auto sd = ad.isStructDeclaration())\n            {\n                if (dim == 0 && tf.varargs == 0) // empty default ctor w/o any varargs\n                {\n                    if (ctd.fbody || !(ctd.storage_class & STC.disable))\n                    {\n                        ctd.error(\"default constructor for structs only allowed \" ~\n                            \"with `@disable`, no body, and no parameters\");\n                        ctd.storage_class |= STC.disable;\n                        ctd.fbody = null;\n                    }\n                    sd.noDefaultCtor = true;\n                }\n                else if (dim == 0 && tf.varargs) // allow varargs only ctor\n                {\n                }\n                else if (dim && Parameter.getNth(tf.parameters, 0).defaultArg)\n                {\n                    // if the first parameter has a default argument, then the rest does as well\n                    if (ctd.storage_class & STC.disable)\n                    {\n                        ctd.deprecation(\"is marked `@disable`, so it cannot have default \"~\n                                    \"arguments for all parameters.\");\n                        deprecationSupplemental(ctd.loc, \"Use `@disable this();` if you want to disable default initialization.\");\n                    }\n                    else\n                        ctd.deprecation(\"all parameters have default arguments, \"~\n                                    \"but structs cannot have default constructors.\");\n                }\n            }\n            else if (dim == 0 && tf.varargs == 0)\n            {\n                ad.defaultCtor = ctd;\n            }\n        }\n    }\n\n    override void visit(PostBlitDeclaration pbd)\n    {\n        //printf(\"PostBlitDeclaration::semantic() %s\\n\", toChars());\n        //printf(\"ident: %s, %s, %p, %p\\n\", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor);\n        //printf(\"stc = x%llx\\n\", sc.stc);\n        if (pbd.semanticRun >= PASS.semanticdone)\n            return;\n        if (pbd._scope)\n        {\n            sc = pbd._scope;\n            pbd._scope = null;\n        }\n\n        pbd.parent = sc.parent;\n        Dsymbol p = pbd.toParent2();\n        StructDeclaration ad = p.isStructDeclaration();\n        if (!ad)\n        {\n            error(pbd.loc, \"postblit can only be a member of struct, not %s `%s`\", p.kind(), p.toChars());\n            pbd.type = Type.terror;\n            pbd.errors = true;\n            return;\n        }\n        if (pbd.ident == Id.postblit && pbd.semanticRun < PASS.semantic)\n            ad.postblits.push(pbd);\n        if (!pbd.type)\n            pbd.type = new TypeFunction(null, Type.tvoid, false, LINK.d, pbd.storage_class);\n\n        sc = sc.push();\n        sc.stc &= ~STC.static_; // not static\n        sc.linkage = LINK.d;\n\n        funcDeclarationSemantic(pbd);\n\n        sc.pop();\n    }\n\n    override void visit(DtorDeclaration dd)\n    {\n        //printf(\"DtorDeclaration::semantic() %s\\n\", toChars());\n        //printf(\"ident: %s, %s, %p, %p\\n\", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor);\n        if (dd.semanticRun >= PASS.semanticdone)\n            return;\n        if (dd._scope)\n        {\n            sc = dd._scope;\n            dd._scope = null;\n        }\n\n        dd.parent = sc.parent;\n        Dsymbol p = dd.toParent2();\n        AggregateDeclaration ad = p.isAggregateDeclaration();\n        if (!ad)\n        {\n            error(dd.loc, \"destructor can only be a member of aggregate, not %s `%s`\", p.kind(), p.toChars());\n            dd.type = Type.terror;\n            dd.errors = true;\n            return;\n        }\n        if (dd.ident == Id.dtor && dd.semanticRun < PASS.semantic)\n            ad.dtors.push(dd);\n        if (!dd.type)\n        {\n            dd.type = new TypeFunction(null, Type.tvoid, false, LINK.d, dd.storage_class);\n            if (ad.classKind == ClassKind.cpp && dd.ident == Id.dtor)\n            {\n                if (auto cldec = ad.isClassDeclaration())\n                {\n                    assert (cldec.cppDtorVtblIndex == -1); // double-call check already by dd.type\n                    if (cldec.baseClass && cldec.baseClass.cppDtorVtblIndex != -1)\n                    {\n                        // override the base virtual\n                        cldec.cppDtorVtblIndex = cldec.baseClass.cppDtorVtblIndex;\n                    }\n                    else if (!dd.isFinal())\n                    {\n                        // reserve the dtor slot for the destructor (which we'll create later)\n                        cldec.cppDtorVtblIndex = cast(int)cldec.vtbl.dim;\n                        cldec.vtbl.push(dd);\n                        if (Target.twoDtorInVtable)\n                            cldec.vtbl.push(dd); // deleting destructor uses a second slot\n                    }\n                }\n            }\n        }\n\n        sc = sc.push();\n        sc.stc &= ~STC.static_; // not a static destructor\n        if (sc.linkage != LINK.cpp)\n            sc.linkage = LINK.d;\n\n        funcDeclarationSemantic(dd);\n\n        sc.pop();\n    }\n\n    override void visit(StaticCtorDeclaration scd)\n    {\n        //printf(\"StaticCtorDeclaration::semantic()\\n\");\n        if (scd.semanticRun >= PASS.semanticdone)\n            return;\n        if (scd._scope)\n        {\n            sc = scd._scope;\n            scd._scope = null;\n        }\n\n        scd.parent = sc.parent;\n        Dsymbol p = scd.parent.pastMixin();\n        if (!p.isScopeDsymbol())\n        {\n            const(char)* s = (scd.isSharedStaticCtorDeclaration() ? \"shared \" : \"\");\n            error(scd.loc, \"`%sstatic` constructor can only be member of module/aggregate/template, not %s `%s`\", s, p.kind(), p.toChars());\n            scd.type = Type.terror;\n            scd.errors = true;\n            return;\n        }\n        if (!scd.type)\n            scd.type = new TypeFunction(null, Type.tvoid, false, LINK.d, scd.storage_class);\n\n        /* If the static ctor appears within a template instantiation,\n         * it could get called multiple times by the module constructors\n         * for different modules. Thus, protect it with a gate.\n         */\n        if (scd.isInstantiated() && scd.semanticRun < PASS.semantic)\n        {\n            /* Add this prefix to the function:\n             *      static int gate;\n             *      if (++gate != 1) return;\n             * Note that this is not thread safe; should not have threads\n             * during static construction.\n             */\n            auto v = new VarDeclaration(Loc.initial, Type.tint32, Id.gate, null);\n            v.storage_class = STC.temp | (scd.isSharedStaticCtorDeclaration() ? STC.static_ : STC.tls);\n\n            auto sa = new Statements();\n            Statement s = new ExpStatement(Loc.initial, v);\n            sa.push(s);\n\n            Expression e = new IdentifierExp(Loc.initial, v.ident);\n            e = new AddAssignExp(Loc.initial, e, new IntegerExp(1));\n            e = new EqualExp(TOK.notEqual, Loc.initial, e, new IntegerExp(1));\n            s = new IfStatement(Loc.initial, null, e, new ReturnStatement(Loc.initial, null), null, Loc.initial);\n\n            sa.push(s);\n            if (scd.fbody)\n                sa.push(scd.fbody);\n\n            scd.fbody = new CompoundStatement(Loc.initial, sa);\n        }\n\n        funcDeclarationSemantic(scd);\n\n        // We're going to need ModuleInfo\n        Module m = scd.getModule();\n        if (!m)\n            m = sc._module;\n        if (m)\n        {\n            m.needmoduleinfo = 1;\n            //printf(\"module1 %s needs moduleinfo\\n\", m.toChars());\n        }\n    }\n\n    override void visit(StaticDtorDeclaration sdd)\n    {\n        if (sdd.semanticRun >= PASS.semanticdone)\n            return;\n        if (sdd._scope)\n        {\n            sc = sdd._scope;\n            sdd._scope = null;\n        }\n\n        sdd.parent = sc.parent;\n        Dsymbol p = sdd.parent.pastMixin();\n        if (!p.isScopeDsymbol())\n        {\n            const(char)* s = (sdd.isSharedStaticDtorDeclaration() ? \"shared \" : \"\");\n            error(sdd.loc, \"`%sstatic` destructor can only be member of module/aggregate/template, not %s `%s`\", s, p.kind(), p.toChars());\n            sdd.type = Type.terror;\n            sdd.errors = true;\n            return;\n        }\n        if (!sdd.type)\n            sdd.type = new TypeFunction(null, Type.tvoid, false, LINK.d, sdd.storage_class);\n\n        /* If the static ctor appears within a template instantiation,\n         * it could get called multiple times by the module constructors\n         * for different modules. Thus, protect it with a gate.\n         */\n        if (sdd.isInstantiated() && sdd.semanticRun < PASS.semantic)\n        {\n            /* Add this prefix to the function:\n             *      static int gate;\n             *      if (--gate != 0) return;\n             * Increment gate during constructor execution.\n             * Note that this is not thread safe; should not have threads\n             * during static destruction.\n             */\n            auto v = new VarDeclaration(Loc.initial, Type.tint32, Id.gate, null);\n            v.storage_class = STC.temp | (sdd.isSharedStaticDtorDeclaration() ? STC.static_ : STC.tls);\n\n            auto sa = new Statements();\n            Statement s = new ExpStatement(Loc.initial, v);\n            sa.push(s);\n\n            Expression e = new IdentifierExp(Loc.initial, v.ident);\n            e = new AddAssignExp(Loc.initial, e, new IntegerExp(-1));\n            e = new EqualExp(TOK.notEqual, Loc.initial, e, new IntegerExp(0));\n            s = new IfStatement(Loc.initial, null, e, new ReturnStatement(Loc.initial, null), null, Loc.initial);\n\n            sa.push(s);\n            if (sdd.fbody)\n                sa.push(sdd.fbody);\n\n            sdd.fbody = new CompoundStatement(Loc.initial, sa);\n\n            sdd.vgate = v;\n        }\n\n        funcDeclarationSemantic(sdd);\n\n        // We're going to need ModuleInfo\n        Module m = sdd.getModule();\n        if (!m)\n            m = sc._module;\n        if (m)\n        {\n            m.needmoduleinfo = 1;\n            //printf(\"module2 %s needs moduleinfo\\n\", m.toChars());\n        }\n    }\n\n    override void visit(InvariantDeclaration invd)\n    {\n        if (invd.semanticRun >= PASS.semanticdone)\n            return;\n        if (invd._scope)\n        {\n            sc = invd._scope;\n            invd._scope = null;\n        }\n\n        invd.parent = sc.parent;\n        Dsymbol p = invd.parent.pastMixin();\n        AggregateDeclaration ad = p.isAggregateDeclaration();\n        if (!ad)\n        {\n            error(invd.loc, \"`invariant` can only be a member of aggregate, not %s `%s`\", p.kind(), p.toChars());\n            invd.type = Type.terror;\n            invd.errors = true;\n            return;\n        }\n        if (invd.ident != Id.classInvariant &&\n             invd.semanticRun < PASS.semantic &&\n             !ad.isUnionDeclaration()           // users are on their own with union fields\n           )\n            ad.invs.push(invd);\n        if (!invd.type)\n            invd.type = new TypeFunction(null, Type.tvoid, false, LINK.d, invd.storage_class);\n\n        sc = sc.push();\n        sc.stc &= ~STC.static_; // not a static invariant\n        sc.stc |= STC.const_; // invariant() is always const\n        sc.flags = (sc.flags & ~SCOPE.contract) | SCOPE.invariant_;\n        sc.linkage = LINK.d;\n\n        funcDeclarationSemantic(invd);\n\n        sc.pop();\n    }\n\n    override void visit(UnitTestDeclaration utd)\n    {\n        if (utd.semanticRun >= PASS.semanticdone)\n            return;\n        if (utd._scope)\n        {\n            sc = utd._scope;\n            utd._scope = null;\n        }\n\n        utd.protection = sc.protection;\n\n        utd.parent = sc.parent;\n        Dsymbol p = utd.parent.pastMixin();\n        if (!p.isScopeDsymbol())\n        {\n            error(utd.loc, \"`unittest` can only be a member of module/aggregate/template, not %s `%s`\", p.kind(), p.toChars());\n            utd.type = Type.terror;\n            utd.errors = true;\n            return;\n        }\n\n        if (global.params.useUnitTests)\n        {\n            if (!utd.type)\n                utd.type = new TypeFunction(null, Type.tvoid, false, LINK.d, utd.storage_class);\n            Scope* sc2 = sc.push();\n            sc2.linkage = LINK.d;\n            funcDeclarationSemantic(utd);\n            sc2.pop();\n        }\n\n        version (none)\n        {\n            // We're going to need ModuleInfo even if the unit tests are not\n            // compiled in, because other modules may import this module and refer\n            // to this ModuleInfo.\n            // (This doesn't make sense to me?)\n            Module m = utd.getModule();\n            if (!m)\n                m = sc._module;\n            if (m)\n            {\n                //printf(\"module3 %s needs moduleinfo\\n\", m.toChars());\n                m.needmoduleinfo = 1;\n            }\n        }\n    }\n\n    override void visit(NewDeclaration nd)\n    {\n        //printf(\"NewDeclaration::semantic()\\n\");\n\n        // `@disable new();` should not be deprecated\n        if (!nd.isDisabled() && !nd.isDeprecated())\n        {\n            // @@@DEPRECATED_2.084@@@\n            // Should be changed to an error in 2.084\n            deprecation(nd.loc, \"class allocators have been deprecated, consider moving the allocation strategy outside of the class\");\n        }\n\n        if (nd.semanticRun >= PASS.semanticdone)\n            return;\n        if (nd._scope)\n        {\n            sc = nd._scope;\n            nd._scope = null;\n        }\n\n        nd.parent = sc.parent;\n        Dsymbol p = nd.parent.pastMixin();\n        if (!p.isAggregateDeclaration())\n        {\n            error(nd.loc, \"allocator can only be a member of aggregate, not %s `%s`\", p.kind(), p.toChars());\n            nd.type = Type.terror;\n            nd.errors = true;\n            return;\n        }\n        Type tret = Type.tvoid.pointerTo();\n        if (!nd.type)\n            nd.type = new TypeFunction(nd.parameters, tret, nd.varargs, LINK.d, nd.storage_class);\n\n        nd.type = nd.type.typeSemantic(nd.loc, sc);\n\n        // allow for `@disable new();` to force users of a type to use an external allocation strategy\n        if (!nd.isDisabled())\n        {\n            // Check that there is at least one argument of type size_t\n            TypeFunction tf = nd.type.toTypeFunction();\n            if (Parameter.dim(tf.parameters) < 1)\n            {\n                nd.error(\"at least one argument of type `size_t` expected\");\n            }\n            else\n            {\n                Parameter fparam = Parameter.getNth(tf.parameters, 0);\n                if (!fparam.type.equals(Type.tsize_t))\n                    nd.error(\"first argument must be type `size_t`, not `%s`\", fparam.type.toChars());\n            }\n        }\n\n        funcDeclarationSemantic(nd);\n    }\n\n    override void visit(DeleteDeclaration deld)\n    {\n        //printf(\"DeleteDeclaration::semantic()\\n\");\n\n        // @@@DEPRECATED_2.084@@@\n        // Should be changed to an error in 2.084\n        if (!deld.isDeprecated())\n            deprecation(deld.loc, \"class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\");\n\n        if (deld.semanticRun >= PASS.semanticdone)\n            return;\n        if (deld._scope)\n        {\n            sc = deld._scope;\n            deld._scope = null;\n        }\n\n        deld.parent = sc.parent;\n        Dsymbol p = deld.parent.pastMixin();\n        if (!p.isAggregateDeclaration())\n        {\n            error(deld.loc, \"deallocator can only be a member of aggregate, not %s `%s`\", p.kind(), p.toChars());\n            deld.type = Type.terror;\n            deld.errors = true;\n            return;\n        }\n        if (!deld.type)\n            deld.type = new TypeFunction(deld.parameters, Type.tvoid, 0, LINK.d, deld.storage_class);\n\n        deld.type = deld.type.typeSemantic(deld.loc, sc);\n\n        // Check that there is only one argument of type void*\n        TypeFunction tf = deld.type.toTypeFunction();\n        if (Parameter.dim(tf.parameters) != 1)\n        {\n            deld.error(\"one argument of type `void*` expected\");\n        }\n        else\n        {\n            Parameter fparam = Parameter.getNth(tf.parameters, 0);\n            if (!fparam.type.equals(Type.tvoid.pointerTo()))\n                deld.error(\"one argument of type `void*` expected, not `%s`\", fparam.type.toChars());\n        }\n\n        funcDeclarationSemantic(deld);\n    }\n\n    override void visit(StructDeclaration sd)\n    {\n        //printf(\"StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\\n\", sd, sd.toPrettyChars(), sd.sizeok);\n\n        //static int count; if (++count == 20) assert(0);\n\n        if (sd.semanticRun >= PASS.semanticdone)\n            return;\n        int errors = global.errors;\n\n        //printf(\"+StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\\n\", this, toPrettyChars(), sizeok);\n        Scope* scx = null;\n        if (sd._scope)\n        {\n            sc = sd._scope;\n            scx = sd._scope; // save so we don't make redundant copies\n            sd._scope = null;\n        }\n\n        if (!sd.parent)\n        {\n            assert(sc.parent && sc.func);\n            sd.parent = sc.parent;\n        }\n        assert(sd.parent && !sd.isAnonymous());\n\n        if (sd.errors)\n            sd.type = Type.terror;\n        if (sd.semanticRun == PASS.init)\n            sd.type = sd.type.addSTC(sc.stc | sd.storage_class);\n        sd.type = sd.type.typeSemantic(sd.loc, sc);\n        if (sd.type.ty == Tstruct && (cast(TypeStruct)sd.type).sym != sd)\n        {\n            auto ti = (cast(TypeStruct)sd.type).sym.isInstantiated();\n            if (ti && isError(ti))\n                (cast(TypeStruct)sd.type).sym = sd;\n        }\n\n        // Ungag errors when not speculative\n        Ungag ungag = sd.ungagSpeculative();\n\n        if (sd.semanticRun == PASS.init)\n        {\n            sd.protection = sc.protection;\n\n            sd.alignment = sc.alignment();\n\n            sd.storage_class |= sc.stc;\n            if (sd.storage_class & STC.deprecated_)\n                sd.isdeprecated = true;\n            if (sd.storage_class & STC.abstract_)\n                sd.error(\"structs, unions cannot be `abstract`\");\n\n            sd.userAttribDecl = sc.userAttribDecl;\n\n            if (sc.linkage == LINK.cpp)\n                sd.classKind = ClassKind.cpp;\n        }\n        else if (sd.symtab && !scx)\n            return;\n\n        sd.semanticRun = PASS.semantic;\n\n        if (!sd.members) // if opaque declaration\n        {\n            sd.semanticRun = PASS.semanticdone;\n            return;\n        }\n        if (!sd.symtab)\n        {\n            sd.symtab = new DsymbolTable();\n\n            for (size_t i = 0; i < sd.members.dim; i++)\n            {\n                auto s = (*sd.members)[i];\n                //printf(\"adding member '%s' to '%s'\\n\", s.toChars(), this.toChars());\n                s.addMember(sc, sd);\n            }\n        }\n\n        auto sc2 = sd.newScope(sc);\n\n        /* Set scope so if there are forward references, we still might be able to\n         * resolve individual members like enums.\n         */\n        for (size_t i = 0; i < sd.members.dim; i++)\n        {\n            auto s = (*sd.members)[i];\n            //printf(\"struct: setScope %s %s\\n\", s.kind(), s.toChars());\n            s.setScope(sc2);\n        }\n\n        for (size_t i = 0; i < sd.members.dim; i++)\n        {\n            auto s = (*sd.members)[i];\n            s.importAll(sc2);\n        }\n\n        for (size_t i = 0; i < sd.members.dim; i++)\n        {\n            auto s = (*sd.members)[i];\n            s.dsymbolSemantic(sc2);\n            sd.errors |= s.errors;\n        }\n        if (sd.errors)\n            sd.type = Type.terror;\n\n        if (!sd.determineFields())\n        {\n            if (sd.type.ty != Terror)\n            {\n                sd.error(sd.loc, \"circular or forward reference\");\n                sd.errors = true;\n                sd.type = Type.terror;\n            }\n\n            sc2.pop();\n            sd.semanticRun = PASS.semanticdone;\n            return;\n        }\n        /* Following special member functions creation needs semantic analysis\n         * completion of sub-structs in each field types. For example, buildDtor\n         * needs to check existence of elaborate dtor in type of each fields.\n         * See the case in compilable/test14838.d\n         */\n        foreach (v; sd.fields)\n        {\n            Type tb = v.type.baseElemOf();\n            if (tb.ty != Tstruct)\n                continue;\n            auto sdec = (cast(TypeStruct)tb).sym;\n            if (sdec.semanticRun >= PASS.semanticdone)\n                continue;\n\n            sc2.pop();\n\n            sd._scope = scx ? scx : sc.copy();\n            sd._scope.setNoFree();\n            sd._scope._module.addDeferredSemantic(sd);\n            //printf(\"\\tdeferring %s\\n\", toChars());\n            return;\n        }\n\n        /* Look for special member functions.\n         */\n        sd.aggNew = cast(NewDeclaration)sd.search(Loc.initial, Id.classNew);\n        sd.aggDelete = cast(DeleteDeclaration)sd.search(Loc.initial, Id.classDelete);\n\n        // Look for the constructor\n        sd.ctor = sd.searchCtor();\n\n        sd.dtor = buildDtor(sd, sc2);\n        sd.tidtor = buildExternDDtor(sd, sc2);\n        sd.postblit = buildPostBlit(sd, sc2);\n\n        buildOpAssign(sd, sc2);\n        buildOpEquals(sd, sc2);\n\n        if (global.params.useTypeInfo && Type.dtypeinfo)  // these functions are used for TypeInfo\n        {\n            sd.xeq = buildXopEquals(sd, sc2);\n            sd.xcmp = buildXopCmp(sd, sc2);\n            sd.xhash = buildXtoHash(sd, sc2);\n        }\n\n        sd.inv = buildInv(sd, sc2);\n\n        Module.dprogress++;\n        sd.semanticRun = PASS.semanticdone;\n        //printf(\"-StructDeclaration::semantic(this=%p, '%s')\\n\", sd, sd.toChars());\n\n        sc2.pop();\n\n        if (sd.ctor)\n        {\n            Dsymbol scall = sd.search(Loc.initial, Id.call);\n            if (scall)\n            {\n                uint xerrors = global.startGagging();\n                sc = sc.push();\n                sc.tinst = null;\n                sc.minst = null;\n                auto fcall = resolveFuncCall(sd.loc, sc, scall, null, null, null, 1);\n                sc = sc.pop();\n                global.endGagging(xerrors);\n\n                if (fcall && fcall.isStatic())\n                {\n                    sd.error(fcall.loc, \"`static opCall` is hidden by constructors and can never be called\");\n                    errorSupplemental(fcall.loc, \"Please use a factory method instead, or replace all constructors with `static opCall`.\");\n                }\n            }\n        }\n\n        if (sd.type.ty == Tstruct && (cast(TypeStruct)sd.type).sym != sd)\n        {\n            // https://issues.dlang.org/show_bug.cgi?id=19024\n            StructDeclaration sym = (cast(TypeStruct)sd.type).sym;\n            version (none)\n            {\n                printf(\"this = %p %s\\n\", sd, sd.toChars());\n                printf(\"type = %d sym = %p, %s\\n\", sd.type.ty, sym, sym.toPrettyChars());\n            }\n            sd.error(\"already exists at %s. Perhaps in another function with the same name?\", sym.loc.toChars());\n        }\n\n        if (global.errors != errors)\n        {\n            // The type is no good.\n            sd.type = Type.terror;\n            sd.errors = true;\n            if (sd.deferred)\n                sd.deferred.errors = true;\n        }\n\n        if (sd.deferred && !global.gag)\n        {\n            sd.deferred.semantic2(sc);\n            sd.deferred.semantic3(sc);\n        }\n    }\n\n    void interfaceSemantic(ClassDeclaration cd)\n    {\n        cd.vtblInterfaces = new BaseClasses();\n        cd.vtblInterfaces.reserve(cd.interfaces.length);\n        foreach (b; cd.interfaces)\n        {\n            cd.vtblInterfaces.push(b);\n            b.copyBaseInterfaces(cd.vtblInterfaces);\n        }\n    }\n\n    override void visit(ClassDeclaration cldec)\n    {\n        //printf(\"ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\\n\", toChars(), type, sizeok, this);\n        //printf(\"\\tparent = %p, '%s'\\n\", sc.parent, sc.parent ? sc.parent.toChars() : \"\");\n        //printf(\"sc.stc = %x\\n\", sc.stc);\n\n        //{ static int n;  if (++n == 20) *(char*)0=0; }\n\n        if (cldec.semanticRun >= PASS.semanticdone)\n            return;\n        int errors = global.errors;\n\n        //printf(\"+ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\\n\", toChars(), type, sizeok, this);\n\n        Scope* scx = null;\n        if (cldec._scope)\n        {\n            sc = cldec._scope;\n            scx = cldec._scope; // save so we don't make redundant copies\n            cldec._scope = null;\n        }\n\n        if (!cldec.parent)\n        {\n            assert(sc.parent);\n            cldec.parent = sc.parent;\n        }\n\n        if (cldec.errors)\n            cldec.type = Type.terror;\n        cldec.type = cldec.type.typeSemantic(cldec.loc, sc);\n        if (cldec.type.ty == Tclass && (cast(TypeClass)cldec.type).sym != cldec)\n        {\n            auto ti = (cast(TypeClass)cldec.type).sym.isInstantiated();\n            if (ti && isError(ti))\n                (cast(TypeClass)cldec.type).sym = cldec;\n        }\n\n        // Ungag errors when not speculative\n        Ungag ungag = cldec.ungagSpeculative();\n\n        if (cldec.semanticRun == PASS.init)\n        {\n            cldec.protection = sc.protection;\n\n            cldec.storage_class |= sc.stc;\n            if (cldec.storage_class & STC.deprecated_)\n                cldec.isdeprecated = true;\n            if (cldec.storage_class & STC.auto_)\n                cldec.error(\"storage class `auto` is invalid when declaring a class, did you mean to use `scope`?\");\n            if (cldec.storage_class & STC.scope_)\n                cldec.stack = true;\n            if (cldec.storage_class & STC.abstract_)\n                cldec.isabstract = Abstract.yes;\n\n            cldec.userAttribDecl = sc.userAttribDecl;\n\n            if (sc.linkage == LINK.cpp)\n                cldec.classKind = ClassKind.cpp;\n            if (sc.linkage == LINK.objc)\n                objc.setObjc(cldec);\n        }\n        else if (cldec.symtab && !scx)\n        {\n            cldec.semanticRun = PASS.semanticdone;\n            return;\n        }\n        cldec.semanticRun = PASS.semantic;\n\n        if (cldec.baseok < Baseok.done)\n        {\n            /* https://issues.dlang.org/show_bug.cgi?id=12078\n             * https://issues.dlang.org/show_bug.cgi?id=12143\n             * https://issues.dlang.org/show_bug.cgi?id=15733\n             * While resolving base classes and interfaces, a base may refer\n             * the member of this derived class. In that time, if all bases of\n             * this class can  be determined, we can go forward the semantc process\n             * beyond the Lancestorsdone. To do the recursive semantic analysis,\n             * temporarily set and unset `_scope` around exp().\n             */\n            T resolveBase(T)(lazy T exp)\n            {\n                if (!scx)\n                {\n                    scx = sc.copy();\n                    scx.setNoFree();\n                }\n                static if (!is(T == void))\n                {\n                    cldec._scope = scx;\n                    auto r = exp();\n                    cldec._scope = null;\n                    return r;\n                }\n                else\n                {\n                    cldec._scope = scx;\n                    exp();\n                    cldec._scope = null;\n                }\n            }\n\n            cldec.baseok = Baseok.start;\n\n            // Expand any tuples in baseclasses[]\n            for (size_t i = 0; i < cldec.baseclasses.dim;)\n            {\n                auto b = (*cldec.baseclasses)[i];\n                b.type = resolveBase(b.type.typeSemantic(cldec.loc, sc));\n\n                Type tb = b.type.toBasetype();\n                if (tb.ty == Ttuple)\n                {\n                    TypeTuple tup = cast(TypeTuple)tb;\n                    cldec.baseclasses.remove(i);\n                    size_t dim = Parameter.dim(tup.arguments);\n                    for (size_t j = 0; j < dim; j++)\n                    {\n                        Parameter arg = Parameter.getNth(tup.arguments, j);\n                        b = new BaseClass(arg.type);\n                        cldec.baseclasses.insert(i + j, b);\n                    }\n                }\n                else\n                    i++;\n            }\n\n            if (cldec.baseok >= Baseok.done)\n            {\n                //printf(\"%s already semantic analyzed, semanticRun = %d\\n\", toChars(), semanticRun);\n                if (cldec.semanticRun >= PASS.semanticdone)\n                    return;\n                goto Lancestorsdone;\n            }\n\n            // See if there's a base class as first in baseclasses[]\n            if (cldec.baseclasses.dim)\n            {\n                BaseClass* b = (*cldec.baseclasses)[0];\n                Type tb = b.type.toBasetype();\n                TypeClass tc = (tb.ty == Tclass) ? cast(TypeClass)tb : null;\n                if (!tc)\n                {\n                    if (b.type != Type.terror)\n                        cldec.error(\"base type must be `class` or `interface`, not `%s`\", b.type.toChars());\n                    cldec.baseclasses.remove(0);\n                    goto L7;\n                }\n                if (tc.sym.isDeprecated())\n                {\n                    if (!cldec.isDeprecated())\n                    {\n                        // Deriving from deprecated class makes this one deprecated too\n                        cldec.isdeprecated = true;\n                        tc.checkDeprecated(cldec.loc, sc);\n                    }\n                }\n                if (tc.sym.isInterfaceDeclaration())\n                    goto L7;\n\n                for (ClassDeclaration cdb = tc.sym; cdb; cdb = cdb.baseClass)\n                {\n                    if (cdb == cldec)\n                    {\n                        cldec.error(\"circular inheritance\");\n                        cldec.baseclasses.remove(0);\n                        goto L7;\n                    }\n                }\n\n                /* https://issues.dlang.org/show_bug.cgi?id=11034\n                 * Class inheritance hierarchy\n                 * and instance size of each classes are orthogonal information.\n                 * Therefore, even if tc.sym.sizeof == Sizeok.none,\n                 * we need to set baseClass field for class covariance check.\n                 */\n                cldec.baseClass = tc.sym;\n                b.sym = cldec.baseClass;\n\n                if (tc.sym.baseok < Baseok.done)\n                    resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference\n                if (tc.sym.baseok < Baseok.done)\n                {\n                    //printf(\"\\ttry later, forward reference of base class %s\\n\", tc.sym.toChars());\n                    if (tc.sym._scope)\n                        tc.sym._scope._module.addDeferredSemantic(tc.sym);\n                    cldec.baseok = Baseok.none;\n                }\n            L7:\n            }\n\n            // Treat the remaining entries in baseclasses as interfaces\n            // Check for errors, handle forward references\n            bool multiClassError = false;\n\n            for (size_t i = (cldec.baseClass ? 1 : 0); i < cldec.baseclasses.dim;)\n            {\n                BaseClass* b = (*cldec.baseclasses)[i];\n                Type tb = b.type.toBasetype();\n                TypeClass tc = (tb.ty == Tclass) ? cast(TypeClass)tb : null;\n                if (!tc || !tc.sym.isInterfaceDeclaration())\n                {\n                    // It's a class\n                    if (tc)\n                    {\n                        if (!multiClassError)\n                        {\n                            error(cldec.loc,\"`%s`: multiple class inheritance is not supported.\" ~\n                                  \" Use multiple interface inheritance and/or composition.\", cldec.toPrettyChars());\n                            multiClassError = true;\n                        }\n\n                        if (tc.sym.fields.dim)\n                            errorSupplemental(cldec.loc,\"`%s` has fields, consider making it a member of `%s`\",\n                                              b.type.toChars(), cldec.type.toChars());\n                        else\n                            errorSupplemental(cldec.loc,\"`%s` has no fields, consider making it an `interface`\",\n                                              b.type.toChars());\n                    }\n                    // It's something else: e.g. `int` in `class Foo : Bar, int { ... }`\n                    else if (b.type != Type.terror)\n                    {\n                        error(cldec.loc,\"`%s`: base type must be `interface`, not `%s`\",\n                              cldec.toPrettyChars(), b.type.toChars());\n                    }\n                    cldec.baseclasses.remove(i);\n                    continue;\n                }\n\n                // Check for duplicate interfaces\n                for (size_t j = (cldec.baseClass ? 1 : 0); j < i; j++)\n                {\n                    BaseClass* b2 = (*cldec.baseclasses)[j];\n                    if (b2.sym == tc.sym)\n                    {\n                        cldec.error(\"inherits from duplicate interface `%s`\", b2.sym.toChars());\n                        cldec.baseclasses.remove(i);\n                        continue;\n                    }\n                }\n                if (tc.sym.isDeprecated())\n                {\n                    if (!cldec.isDeprecated())\n                    {\n                        // Deriving from deprecated class makes this one deprecated too\n                        cldec.isdeprecated = true;\n                        tc.checkDeprecated(cldec.loc, sc);\n                    }\n                }\n\n                b.sym = tc.sym;\n\n                if (tc.sym.baseok < Baseok.done)\n                    resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference\n                if (tc.sym.baseok < Baseok.done)\n                {\n                    //printf(\"\\ttry later, forward reference of base %s\\n\", tc.sym.toChars());\n                    if (tc.sym._scope)\n                        tc.sym._scope._module.addDeferredSemantic(tc.sym);\n                    cldec.baseok = Baseok.none;\n                }\n                i++;\n            }\n            if (cldec.baseok == Baseok.none)\n            {\n                // Forward referencee of one or more bases, try again later\n                cldec._scope = scx ? scx : sc.copy();\n                cldec._scope.setNoFree();\n                cldec._scope._module.addDeferredSemantic(cldec);\n                //printf(\"\\tL%d semantic('%s') failed due to forward references\\n\", __LINE__, toChars());\n                return;\n            }\n            cldec.baseok = Baseok.done;\n\n            // If no base class, and this is not an Object, use Object as base class\n            if (!cldec.baseClass && cldec.ident != Id.Object && cldec.object && cldec.classKind == ClassKind.d)\n            {\n                void badObjectDotD()\n                {\n                    cldec.error(\"missing or corrupt object.d\");\n                    fatal();\n                }\n\n                if (!cldec.object || cldec.object.errors)\n                    badObjectDotD();\n\n                Type t = cldec.object.type;\n                t = t.typeSemantic(cldec.loc, sc).toBasetype();\n                if (t.ty == Terror)\n                    badObjectDotD();\n                assert(t.ty == Tclass);\n                TypeClass tc = cast(TypeClass)t;\n\n                auto b = new BaseClass(tc);\n                cldec.baseclasses.shift(b);\n\n                cldec.baseClass = tc.sym;\n                assert(!cldec.baseClass.isInterfaceDeclaration());\n                b.sym = cldec.baseClass;\n            }\n            if (cldec.baseClass)\n            {\n                if (cldec.baseClass.storage_class & STC.final_)\n                    cldec.error(\"cannot inherit from class `%s` because it is `final`\", cldec.baseClass.toChars());\n\n                // Inherit properties from base class\n                if (cldec.baseClass.isCOMclass())\n                    cldec.com = true;\n                if (cldec.baseClass.isCPPclass())\n                    cldec.classKind = ClassKind.cpp;\n                if (cldec.baseClass.stack)\n                    cldec.stack = true;\n                cldec.enclosing = cldec.baseClass.enclosing;\n                cldec.storage_class |= cldec.baseClass.storage_class & STC.TYPECTOR;\n            }\n\n            cldec.interfaces = cldec.baseclasses.tdata()[(cldec.baseClass ? 1 : 0) .. cldec.baseclasses.dim];\n            foreach (b; cldec.interfaces)\n            {\n                // If this is an interface, and it derives from a COM interface,\n                // then this is a COM interface too.\n                if (b.sym.isCOMinterface())\n                    cldec.com = true;\n                if (cldec.classKind == ClassKind.cpp && !b.sym.isCPPinterface())\n                {\n                    error(cldec.loc, \"C++ class `%s` cannot implement D interface `%s`\",\n                        cldec.toPrettyChars(), b.sym.toPrettyChars());\n                }\n            }\n            interfaceSemantic(cldec);\n        }\n    Lancestorsdone:\n        //printf(\"\\tClassDeclaration.dsymbolSemantic(%s) baseok = %d\\n\", toChars(), baseok);\n\n        if (!cldec.members) // if opaque declaration\n        {\n            cldec.semanticRun = PASS.semanticdone;\n            return;\n        }\n        if (!cldec.symtab)\n        {\n            cldec.symtab = new DsymbolTable();\n\n            /* https://issues.dlang.org/show_bug.cgi?id=12152\n             * The semantic analysis of base classes should be finished\n             * before the members semantic analysis of this class, in order to determine\n             * vtbl in this class. However if a base class refers the member of this class,\n             * it can be resolved as a normal forward reference.\n             * Call addMember() and setScope() to make this class members visible from the base classes.\n             */\n            for (size_t i = 0; i < cldec.members.dim; i++)\n            {\n                auto s = (*cldec.members)[i];\n                s.addMember(sc, cldec);\n            }\n\n            auto sc2 = cldec.newScope(sc);\n\n            /* Set scope so if there are forward references, we still might be able to\n             * resolve individual members like enums.\n             */\n            for (size_t i = 0; i < cldec.members.dim; i++)\n            {\n                auto s = (*cldec.members)[i];\n                //printf(\"[%d] setScope %s %s, sc2 = %p\\n\", i, s.kind(), s.toChars(), sc2);\n                s.setScope(sc2);\n            }\n\n            sc2.pop();\n        }\n\n        for (size_t i = 0; i < cldec.baseclasses.dim; i++)\n        {\n            BaseClass* b = (*cldec.baseclasses)[i];\n            Type tb = b.type.toBasetype();\n            assert(tb.ty == Tclass);\n            TypeClass tc = cast(TypeClass)tb;\n            if (tc.sym.semanticRun < PASS.semanticdone)\n            {\n                // Forward referencee of one or more bases, try again later\n                cldec._scope = scx ? scx : sc.copy();\n                cldec._scope.setNoFree();\n                if (tc.sym._scope)\n                    tc.sym._scope._module.addDeferredSemantic(tc.sym);\n                cldec._scope._module.addDeferredSemantic(cldec);\n                //printf(\"\\tL%d semantic('%s') failed due to forward references\\n\", __LINE__, toChars());\n                return;\n            }\n        }\n\n        if (cldec.baseok == Baseok.done)\n        {\n            cldec.baseok = Baseok.semanticdone;\n\n            // initialize vtbl\n            if (cldec.baseClass)\n            {\n                if (cldec.classKind == ClassKind.cpp && cldec.baseClass.vtbl.dim == 0)\n                {\n                    cldec.error(\"C++ base class `%s` needs at least one virtual function\", cldec.baseClass.toChars());\n                }\n\n                // Copy vtbl[] from base class\n                cldec.vtbl.setDim(cldec.baseClass.vtbl.dim);\n                memcpy(cldec.vtbl.tdata(), cldec.baseClass.vtbl.tdata(), (void*).sizeof * cldec.vtbl.dim);\n\n                cldec.vthis = cldec.baseClass.vthis;\n            }\n            else\n            {\n                // No base class, so this is the root of the class hierarchy\n                cldec.vtbl.setDim(0);\n                if (cldec.vtblOffset())\n                    cldec.vtbl.push(cldec); // leave room for classinfo as first member\n            }\n\n            /* If this is a nested class, add the hidden 'this'\n             * member which is a pointer to the enclosing scope.\n             */\n            if (cldec.vthis) // if inheriting from nested class\n            {\n                // Use the base class's 'this' member\n                if (cldec.storage_class & STC.static_)\n                    cldec.error(\"static class cannot inherit from nested class `%s`\", cldec.baseClass.toChars());\n                if (cldec.toParent2() != cldec.baseClass.toParent2() &&\n                    (!cldec.toParent2() ||\n                     !cldec.baseClass.toParent2().getType() ||\n                     !cldec.baseClass.toParent2().getType().isBaseOf(cldec.toParent2().getType(), null)))\n                {\n                    if (cldec.toParent2())\n                    {\n                        cldec.error(\"is nested within `%s`, but super class `%s` is nested within `%s`\",\n                            cldec.toParent2().toChars(),\n                            cldec.baseClass.toChars(),\n                            cldec.baseClass.toParent2().toChars());\n                    }\n                    else\n                    {\n                        cldec.error(\"is not nested, but super class `%s` is nested within `%s`\",\n                            cldec.baseClass.toChars(),\n                            cldec.baseClass.toParent2().toChars());\n                    }\n                    cldec.enclosing = null;\n                }\n            }\n            else\n                cldec.makeNested();\n        }\n\n        auto sc2 = cldec.newScope(sc);\n\n        for (size_t i = 0; i < cldec.members.dim; ++i)\n        {\n            auto s = (*cldec.members)[i];\n            s.importAll(sc2);\n        }\n\n        // Note that members.dim can grow due to tuple expansion during semantic()\n        for (size_t i = 0; i < cldec.members.dim; ++i)\n        {\n            auto s = (*cldec.members)[i];\n            s.dsymbolSemantic(sc2);\n        }\n\n        if (!cldec.determineFields())\n        {\n            assert(cldec.type == Type.terror);\n            sc2.pop();\n            return;\n        }\n        /* Following special member functions creation needs semantic analysis\n         * completion of sub-structs in each field types.\n         */\n        foreach (v; cldec.fields)\n        {\n            Type tb = v.type.baseElemOf();\n            if (tb.ty != Tstruct)\n                continue;\n            auto sd = (cast(TypeStruct)tb).sym;\n            if (sd.semanticRun >= PASS.semanticdone)\n                continue;\n\n            sc2.pop();\n\n            cldec._scope = scx ? scx : sc.copy();\n            cldec._scope.setNoFree();\n            cldec._scope._module.addDeferredSemantic(cldec);\n            //printf(\"\\tdeferring %s\\n\", toChars());\n            return;\n        }\n\n        /* Look for special member functions.\n         * They must be in this class, not in a base class.\n         */\n        // Can be in base class\n        cldec.aggNew = cast(NewDeclaration)cldec.search(Loc.initial, Id.classNew);\n        cldec.aggDelete = cast(DeleteDeclaration)cldec.search(Loc.initial, Id.classDelete);\n\n        // Look for the constructor\n        cldec.ctor = cldec.searchCtor();\n\n        if (!cldec.ctor && cldec.noDefaultCtor)\n        {\n            // A class object is always created by constructor, so this check is legitimate.\n            foreach (v; cldec.fields)\n            {\n                if (v.storage_class & STC.nodefaultctor)\n                    error(v.loc, \"field `%s` must be initialized in constructor\", v.toChars());\n            }\n        }\n\n        // If this class has no constructor, but base class has a default\n        // ctor, create a constructor:\n        //    this() { }\n        if (!cldec.ctor && cldec.baseClass && cldec.baseClass.ctor)\n        {\n            auto fd = resolveFuncCall(cldec.loc, sc2, cldec.baseClass.ctor, null, cldec.type, null, 1);\n            if (!fd) // try shared base ctor instead\n                fd = resolveFuncCall(cldec.loc, sc2, cldec.baseClass.ctor, null, cldec.type.sharedOf, null, 1);\n            if (fd && !fd.errors)\n            {\n                //printf(\"Creating default this(){} for class %s\\n\", toChars());\n                auto btf = fd.type.toTypeFunction();\n                auto tf = new TypeFunction(null, null, 0, LINK.d, fd.storage_class);\n                tf.mod       = btf.mod;\n                tf.purity    = btf.purity;\n                tf.isnothrow = btf.isnothrow;\n                tf.isnogc    = btf.isnogc;\n                tf.trust     = btf.trust;\n\n                auto ctor = new CtorDeclaration(cldec.loc, Loc.initial, 0, tf);\n                ctor.fbody = new CompoundStatement(Loc.initial, new Statements());\n\n                cldec.members.push(ctor);\n                ctor.addMember(sc, cldec);\n                ctor.dsymbolSemantic(sc2);\n\n                cldec.ctor = ctor;\n                cldec.defaultCtor = ctor;\n            }\n            else\n            {\n                cldec.error(\"cannot implicitly generate a default constructor when base class `%s` is missing a default constructor\",\n                    cldec.baseClass.toPrettyChars());\n            }\n        }\n\n        cldec.dtor = buildDtor(cldec, sc2);\n        cldec.tidtor = buildExternDDtor(cldec, sc2);\n\n        if (cldec.classKind == ClassKind.cpp && cldec.cppDtorVtblIndex != -1)\n        {\n            // now we've built the aggregate destructor, we'll make it virtual and assign it to the reserved vtable slot\n            cldec.dtor.vtblIndex = cldec.cppDtorVtblIndex;\n            cldec.vtbl[cldec.cppDtorVtblIndex] = cldec.dtor;\n\n            if (Target.twoDtorInVtable)\n            {\n                // TODO: create a C++ compatible deleting destructor (call out to `operator delete`)\n                //       for the moment, we'll call the non-deleting destructor and leak\n                cldec.vtbl[cldec.cppDtorVtblIndex + 1] = cldec.dtor;\n            }\n        }\n\n        if (auto f = hasIdentityOpAssign(cldec, sc2))\n        {\n            if (!(f.storage_class & STC.disable))\n                cldec.error(f.loc, \"identity assignment operator overload is illegal\");\n        }\n\n        cldec.inv = buildInv(cldec, sc2);\n\n        Module.dprogress++;\n        cldec.semanticRun = PASS.semanticdone;\n        //printf(\"-ClassDeclaration.dsymbolSemantic(%s), type = %p\\n\", toChars(), type);\n\n        sc2.pop();\n\n        /* isAbstract() is undecidable in some cases because of circular dependencies.\n         * Now that semantic is finished, get a definitive result, and error if it is not the same.\n         */\n        if (cldec.isabstract != Abstract.fwdref)    // if evaluated it before completion\n        {\n            const isabstractsave = cldec.isabstract;\n            cldec.isabstract = Abstract.fwdref;\n            cldec.isAbstract();               // recalculate\n            if (cldec.isabstract != isabstractsave)\n            {\n                cldec.error(\"cannot infer `abstract` attribute due to circular dependencies\");\n            }\n        }\n\n        if (cldec.type.ty == Tclass && (cast(TypeClass)cldec.type).sym != cldec)\n        {\n            // https://issues.dlang.org/show_bug.cgi?id=17492\n            ClassDeclaration cd = (cast(TypeClass)cldec.type).sym;\n            version (none)\n            {\n                printf(\"this = %p %s\\n\", cldec, cldec.toPrettyChars());\n                printf(\"type = %d sym = %p, %s\\n\", cldec.type.ty, cd, cd.toPrettyChars());\n            }\n            cldec.error(\"already exists at %s. Perhaps in another function with the same name?\", cd.loc.toChars());\n        }\n\n        if (global.errors != errors)\n        {\n            // The type is no good.\n            cldec.type = Type.terror;\n            cldec.errors = true;\n            if (cldec.deferred)\n                cldec.deferred.errors = true;\n        }\n\n        // Verify fields of a synchronized class are not public\n        if (cldec.storage_class & STC.synchronized_)\n        {\n            foreach (vd; cldec.fields)\n            {\n                if (!vd.isThisDeclaration() &&\n                    !vd.prot().isMoreRestrictiveThan(Prot(Prot.Kind.public_)))\n                {\n                    vd.error(\"Field members of a `synchronized` class cannot be `%s`\",\n                        protectionToChars(vd.prot().kind));\n                }\n            }\n        }\n\n        if (cldec.deferred && !global.gag)\n        {\n            cldec.deferred.semantic2(sc);\n            cldec.deferred.semantic3(sc);\n        }\n        //printf(\"-ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\\n\", toChars(), type, sizeok, this);\n    }\n\n    override void visit(InterfaceDeclaration idec)\n    {\n        //printf(\"InterfaceDeclaration.dsymbolSemantic(%s), type = %p\\n\", toChars(), type);\n        if (idec.semanticRun >= PASS.semanticdone)\n            return;\n        int errors = global.errors;\n\n        //printf(\"+InterfaceDeclaration.dsymbolSemantic(%s), type = %p\\n\", toChars(), type);\n\n        Scope* scx = null;\n        if (idec._scope)\n        {\n            sc = idec._scope;\n            scx = idec._scope; // save so we don't make redundant copies\n            idec._scope = null;\n        }\n\n        if (!idec.parent)\n        {\n            assert(sc.parent && sc.func);\n            idec.parent = sc.parent;\n        }\n        assert(idec.parent && !idec.isAnonymous());\n\n        if (idec.errors)\n            idec.type = Type.terror;\n        idec.type = idec.type.typeSemantic(idec.loc, sc);\n        if (idec.type.ty == Tclass && (cast(TypeClass)idec.type).sym != idec)\n        {\n            auto ti = (cast(TypeClass)idec.type).sym.isInstantiated();\n            if (ti && isError(ti))\n                (cast(TypeClass)idec.type).sym = idec;\n        }\n\n        // Ungag errors when not speculative\n        Ungag ungag = idec.ungagSpeculative();\n\n        if (idec.semanticRun == PASS.init)\n        {\n            idec.protection = sc.protection;\n\n            idec.storage_class |= sc.stc;\n            if (idec.storage_class & STC.deprecated_)\n                idec.isdeprecated = true;\n\n            idec.userAttribDecl = sc.userAttribDecl;\n        }\n        else if (idec.symtab)\n        {\n            if (idec.sizeok == Sizeok.done || !scx)\n            {\n                idec.semanticRun = PASS.semanticdone;\n                return;\n            }\n        }\n        idec.semanticRun = PASS.semantic;\n\n        if (idec.baseok < Baseok.done)\n        {\n            T resolveBase(T)(lazy T exp)\n            {\n                if (!scx)\n                {\n                    scx = sc.copy();\n                    scx.setNoFree();\n                }\n                static if (!is(T == void))\n                {\n                    idec._scope = scx;\n                    auto r = exp();\n                    idec._scope = null;\n                    return r;\n                }\n                else\n                {\n                    idec._scope = scx;\n                    exp();\n                    idec._scope = null;\n                }\n            }\n\n            idec.baseok = Baseok.start;\n\n            // Expand any tuples in baseclasses[]\n            for (size_t i = 0; i < idec.baseclasses.dim;)\n            {\n                auto b = (*idec.baseclasses)[i];\n                b.type = resolveBase(b.type.typeSemantic(idec.loc, sc));\n\n                Type tb = b.type.toBasetype();\n                if (tb.ty == Ttuple)\n                {\n                    TypeTuple tup = cast(TypeTuple)tb;\n                    idec.baseclasses.remove(i);\n                    size_t dim = Parameter.dim(tup.arguments);\n                    for (size_t j = 0; j < dim; j++)\n                    {\n                        Parameter arg = Parameter.getNth(tup.arguments, j);\n                        b = new BaseClass(arg.type);\n                        idec.baseclasses.insert(i + j, b);\n                    }\n                }\n                else\n                    i++;\n            }\n\n            if (idec.baseok >= Baseok.done)\n            {\n                //printf(\"%s already semantic analyzed, semanticRun = %d\\n\", toChars(), semanticRun);\n                if (idec.semanticRun >= PASS.semanticdone)\n                    return;\n                goto Lancestorsdone;\n            }\n\n            if (!idec.baseclasses.dim && sc.linkage == LINK.cpp)\n                idec.classKind = ClassKind.cpp;\n\n            if (sc.linkage == LINK.objc)\n                objc.setObjc(idec);\n\n            // Check for errors, handle forward references\n            for (size_t i = 0; i < idec.baseclasses.dim;)\n            {\n                BaseClass* b = (*idec.baseclasses)[i];\n                Type tb = b.type.toBasetype();\n                TypeClass tc = (tb.ty == Tclass) ? cast(TypeClass)tb : null;\n                if (!tc || !tc.sym.isInterfaceDeclaration())\n                {\n                    if (b.type != Type.terror)\n                        idec.error(\"base type must be `interface`, not `%s`\", b.type.toChars());\n                    idec.baseclasses.remove(i);\n                    continue;\n                }\n\n                // Check for duplicate interfaces\n                for (size_t j = 0; j < i; j++)\n                {\n                    BaseClass* b2 = (*idec.baseclasses)[j];\n                    if (b2.sym == tc.sym)\n                    {\n                        idec.error(\"inherits from duplicate interface `%s`\", b2.sym.toChars());\n                        idec.baseclasses.remove(i);\n                        continue;\n                    }\n                }\n                if (tc.sym == idec || idec.isBaseOf2(tc.sym))\n                {\n                    idec.error(\"circular inheritance of interface\");\n                    idec.baseclasses.remove(i);\n                    continue;\n                }\n                if (tc.sym.isDeprecated())\n                {\n                    if (!idec.isDeprecated())\n                    {\n                        // Deriving from deprecated class makes this one deprecated too\n                        idec.isdeprecated = true;\n                        tc.checkDeprecated(idec.loc, sc);\n                    }\n                }\n\n                b.sym = tc.sym;\n\n                if (tc.sym.baseok < Baseok.done)\n                    resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference\n                if (tc.sym.baseok < Baseok.done)\n                {\n                    //printf(\"\\ttry later, forward reference of base %s\\n\", tc.sym.toChars());\n                    if (tc.sym._scope)\n                        tc.sym._scope._module.addDeferredSemantic(tc.sym);\n                    idec.baseok = Baseok.none;\n                }\n                i++;\n            }\n            if (idec.baseok == Baseok.none)\n            {\n                // Forward referencee of one or more bases, try again later\n                idec._scope = scx ? scx : sc.copy();\n                idec._scope.setNoFree();\n                idec._scope._module.addDeferredSemantic(idec);\n                return;\n            }\n            idec.baseok = Baseok.done;\n\n            idec.interfaces = idec.baseclasses.tdata()[0 .. idec.baseclasses.dim];\n            foreach (b; idec.interfaces)\n            {\n                // If this is an interface, and it derives from a COM interface,\n                // then this is a COM interface too.\n                if (b.sym.isCOMinterface())\n                    idec.com = true;\n                if (b.sym.isCPPinterface())\n                    idec.classKind = ClassKind.cpp;\n            }\n\n            interfaceSemantic(idec);\n        }\n    Lancestorsdone:\n\n        if (!idec.members) // if opaque declaration\n        {\n            idec.semanticRun = PASS.semanticdone;\n            return;\n        }\n        if (!idec.symtab)\n            idec.symtab = new DsymbolTable();\n\n        for (size_t i = 0; i < idec.baseclasses.dim; i++)\n        {\n            BaseClass* b = (*idec.baseclasses)[i];\n            Type tb = b.type.toBasetype();\n            assert(tb.ty == Tclass);\n            TypeClass tc = cast(TypeClass)tb;\n            if (tc.sym.semanticRun < PASS.semanticdone)\n            {\n                // Forward referencee of one or more bases, try again later\n                idec._scope = scx ? scx : sc.copy();\n                idec._scope.setNoFree();\n                if (tc.sym._scope)\n                    tc.sym._scope._module.addDeferredSemantic(tc.sym);\n                idec._scope._module.addDeferredSemantic(idec);\n                return;\n            }\n        }\n\n        if (idec.baseok == Baseok.done)\n        {\n            idec.baseok = Baseok.semanticdone;\n            objc.setMetaclass(idec);\n\n            // initialize vtbl\n            if (idec.vtblOffset())\n                idec.vtbl.push(idec); // leave room at vtbl[0] for classinfo\n\n            // Cat together the vtbl[]'s from base interfaces\n            foreach (i, b; idec.interfaces)\n            {\n                // Skip if b has already appeared\n                for (size_t k = 0; k < i; k++)\n                {\n                    if (b == idec.interfaces[k])\n                        goto Lcontinue;\n                }\n\n                // Copy vtbl[] from base class\n                if (b.sym.vtblOffset())\n                {\n                    size_t d = b.sym.vtbl.dim;\n                    if (d > 1)\n                    {\n                        idec.vtbl.reserve(d - 1);\n                        for (size_t j = 1; j < d; j++)\n                            idec.vtbl.push(b.sym.vtbl[j]);\n                    }\n                }\n                else\n                {\n                    idec.vtbl.append(&b.sym.vtbl);\n                }\n\n            Lcontinue:\n            }\n        }\n\n        for (size_t i = 0; i < idec.members.dim; i++)\n        {\n            Dsymbol s = (*idec.members)[i];\n            s.addMember(sc, idec);\n        }\n\n        auto sc2 = idec.newScope(sc);\n\n        /* Set scope so if there are forward references, we still might be able to\n         * resolve individual members like enums.\n         */\n        for (size_t i = 0; i < idec.members.dim; i++)\n        {\n            Dsymbol s = (*idec.members)[i];\n            //printf(\"setScope %s %s\\n\", s.kind(), s.toChars());\n            s.setScope(sc2);\n        }\n\n        for (size_t i = 0; i < idec.members.dim; i++)\n        {\n            Dsymbol s = (*idec.members)[i];\n            s.importAll(sc2);\n        }\n\n        for (size_t i = 0; i < idec.members.dim; i++)\n        {\n            Dsymbol s = (*idec.members)[i];\n            s.dsymbolSemantic(sc2);\n        }\n\n        Module.dprogress++;\n        idec.semanticRun = PASS.semanticdone;\n        //printf(\"-InterfaceDeclaration.dsymbolSemantic(%s), type = %p\\n\", toChars(), type);\n\n        sc2.pop();\n\n        if (global.errors != errors)\n        {\n            // The type is no good.\n            idec.type = Type.terror;\n        }\n\n        version (none)\n        {\n            if (type.ty == Tclass && (cast(TypeClass)idec.type).sym != idec)\n            {\n                printf(\"this = %p %s\\n\", idec, idec.toChars());\n                printf(\"type = %d sym = %p\\n\", idec.type.ty, (cast(TypeClass)idec.type).sym);\n            }\n        }\n        assert(idec.type.ty != Tclass || (cast(TypeClass)idec.type).sym == idec);\n    }\n}\n\nvoid templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions* fargs)\n{\n    //printf(\"[%s] TemplateInstance.dsymbolSemantic('%s', this=%p, gag = %d, sc = %p)\\n\", tempinst.loc.toChars(), tempinst.toChars(), tempinst, global.gag, sc);\n    version (none)\n    {\n        for (Dsymbol s = tempinst; s; s = s.parent)\n        {\n            printf(\"\\t%s\\n\", s.toChars());\n        }\n        printf(\"Scope\\n\");\n        for (Scope* scx = sc; scx; scx = scx.enclosing)\n        {\n            printf(\"\\t%s parent %s\\n\", scx._module ? scx._module.toChars() : \"null\", scx.parent ? scx.parent.toChars() : \"null\");\n        }\n    }\n\n    static if (LOG)\n    {\n        printf(\"\\n+TemplateInstance.dsymbolSemantic('%s', this=%p)\\n\", tempinst.toChars(), tempinst);\n    }\n    if (tempinst.inst) // if semantic() was already run\n    {\n        static if (LOG)\n        {\n            printf(\"-TemplateInstance.dsymbolSemantic('%s', this=%p) already run\\n\", inst.toChars(), tempinst.inst);\n        }\n        return;\n    }\n    if (tempinst.semanticRun != PASS.init)\n    {\n        static if (LOG)\n        {\n            printf(\"Recursive template expansion\\n\");\n        }\n        auto ungag = Ungag(global.gag);\n        if (!tempinst.gagged)\n            global.gag = 0;\n        tempinst.error(tempinst.loc, \"recursive template expansion\");\n        if (tempinst.gagged)\n            tempinst.semanticRun = PASS.init;\n        else\n            tempinst.inst = tempinst;\n        tempinst.errors = true;\n        return;\n    }\n\n    // Get the enclosing template instance from the scope tinst\n    tempinst.tinst = sc.tinst;\n\n    // Get the instantiating module from the scope minst\n    tempinst.minst = sc.minst;\n    // https://issues.dlang.org/show_bug.cgi?id=10920\n    // If the enclosing function is non-root symbol,\n    // this instance should be speculative.\n    if (!tempinst.tinst && sc.func && sc.func.inNonRoot())\n    {\n        tempinst.minst = null;\n    }\n\n    tempinst.gagged = (global.gag > 0);\n\n    tempinst.semanticRun = PASS.semantic;\n\n    static if (LOG)\n    {\n        printf(\"\\tdo semantic\\n\");\n    }\n    /* Find template declaration first,\n     * then run semantic on each argument (place results in tiargs[]),\n     * last find most specialized template from overload list/set.\n     */\n    if (!tempinst.findTempDecl(sc, null) || !tempinst.semanticTiargs(sc) || !tempinst.findBestMatch(sc, fargs))\n    {\n    Lerror:\n        if (tempinst.gagged)\n        {\n            // https://issues.dlang.org/show_bug.cgi?id=13220\n            // Roll back status for later semantic re-running\n            tempinst.semanticRun = PASS.init;\n        }\n        else\n            tempinst.inst = tempinst;\n        tempinst.errors = true;\n        return;\n    }\n    TemplateDeclaration tempdecl = tempinst.tempdecl.isTemplateDeclaration();\n    assert(tempdecl);\n\n    // If tempdecl is a mixin, disallow it\n    if (tempdecl.ismixin)\n    {\n        tempinst.error(\"mixin templates are not regular templates\");\n        goto Lerror;\n    }\n\n    tempinst.hasNestedArgs(tempinst.tiargs, tempdecl.isstatic);\n    if (tempinst.errors)\n        goto Lerror;\n\n    /* See if there is an existing TemplateInstantiation that already\n     * implements the typeargs. If so, just refer to that one instead.\n     */\n    tempinst.inst = tempdecl.findExistingInstance(tempinst, fargs);\n    TemplateInstance errinst = null;\n    if (!tempinst.inst)\n    {\n        // So, we need to implement 'this' instance.\n    }\n    else if (tempinst.inst.gagged && !tempinst.gagged && tempinst.inst.errors)\n    {\n        // If the first instantiation had failed, re-run semantic,\n        // so that error messages are shown.\n        errinst = tempinst.inst;\n    }\n    else\n    {\n        // It's a match\n        tempinst.parent = tempinst.inst.parent;\n        tempinst.errors = tempinst.inst.errors;\n\n        // If both this and the previous instantiation were gagged,\n        // use the number of errors that happened last time.\n        global.errors += tempinst.errors;\n        global.gaggedErrors += tempinst.errors;\n\n        // If the first instantiation was gagged, but this is not:\n        if (tempinst.inst.gagged)\n        {\n            // It had succeeded, mark it is a non-gagged instantiation,\n            // and reuse it.\n            tempinst.inst.gagged = tempinst.gagged;\n        }\n\n        tempinst.tnext = tempinst.inst.tnext;\n        tempinst.inst.tnext = tempinst;\n\n        /* A module can have explicit template instance and its alias\n         * in module scope (e,g, `alias Base64 = Base64Impl!('+', '/');`).\n         * If the first instantiation 'inst' had happened in non-root module,\n         * compiler can assume that its instantiated code would be included\n         * in the separately compiled obj/lib file (e.g. phobos.lib).\n         *\n         * However, if 'this' second instantiation happened in root module,\n         * compiler might need to invoke its codegen\n         * (https://issues.dlang.org/show_bug.cgi?id=2500 & https://issues.dlang.org/show_bug.cgi?id=2644).\n         * But whole import graph is not determined until all semantic pass finished,\n         * so 'inst' should conservatively finish the semantic3 pass for the codegen.\n         */\n        if (tempinst.minst && tempinst.minst.isRoot() && !(tempinst.inst.minst && tempinst.inst.minst.isRoot()))\n        {\n            /* Swap the position of 'inst' and 'this' in the instantiation graph.\n             * Then, the primary instance `inst` will be changed to a root instance.\n             *\n             * Before:\n             *  non-root -> A!() -> B!()[inst] -> C!()\n             *                      |\n             *  root     -> D!() -> B!()[this]\n             *\n             * After:\n             *  non-root -> A!() -> B!()[this]\n             *                      |\n             *  root     -> D!() -> B!()[inst] -> C!()\n             */\n            Module mi = tempinst.minst;\n            TemplateInstance ti = tempinst.tinst;\n            tempinst.minst = tempinst.inst.minst;\n            tempinst.tinst = tempinst.inst.tinst;\n            tempinst.inst.minst = mi;\n            tempinst.inst.tinst = ti;\n\n            if (tempinst.minst) // if inst was not speculative\n            {\n                /* Add 'inst' once again to the root module members[], then the\n                 * instance members will get codegen chances.\n                 */\n                tempinst.inst.appendToModuleMember();\n            }\n        }\n        static if (LOG)\n        {\n            printf(\"\\tit's a match with instance %p, %d\\n\", tempinst.inst, tempinst.inst.semanticRun);\n        }\n        return;\n    }\n    static if (LOG)\n    {\n        printf(\"\\timplement template instance %s '%s'\\n\", tempdecl.parent.toChars(), tempinst.toChars());\n        printf(\"\\ttempdecl %s\\n\", tempdecl.toChars());\n    }\n    uint errorsave = global.errors;\n\n    tempinst.inst = tempinst;\n    tempinst.parent = tempinst.enclosing ? tempinst.enclosing : tempdecl.parent;\n    //printf(\"parent = '%s'\\n\", parent.kind());\n\n    TemplateInstance tempdecl_instance_idx = tempdecl.addInstance(tempinst);\n\n    //getIdent();\n\n    // Store the place we added it to in target_symbol_list(_idx) so we can\n    // remove it later if we encounter an error.\n    Dsymbols* target_symbol_list = tempinst.appendToModuleMember();\n    size_t target_symbol_list_idx = target_symbol_list ? target_symbol_list.dim - 1 : 0;\n\n    // Copy the syntax trees from the TemplateDeclaration\n    tempinst.members = Dsymbol.arraySyntaxCopy(tempdecl.members);\n\n    // resolve TemplateThisParameter\n    for (size_t i = 0; i < tempdecl.parameters.dim; i++)\n    {\n        if ((*tempdecl.parameters)[i].isTemplateThisParameter() is null)\n            continue;\n        Type t = isType((*tempinst.tiargs)[i]);\n        assert(t);\n        if (StorageClass stc = ModToStc(t.mod))\n        {\n            //printf(\"t = %s, stc = x%llx\\n\", t.toChars(), stc);\n            auto s = new Dsymbols();\n            s.push(new StorageClassDeclaration(stc, tempinst.members));\n            tempinst.members = s;\n        }\n        break;\n    }\n\n    // Create our own scope for the template parameters\n    Scope* _scope = tempdecl._scope;\n    if (tempdecl.semanticRun == PASS.init)\n    {\n        tempinst.error(\"template instantiation `%s` forward references template declaration `%s`\", tempinst.toChars(), tempdecl.toChars());\n        return;\n    }\n\n    static if (LOG)\n    {\n        printf(\"\\tcreate scope for template parameters '%s'\\n\", tempinst.toChars());\n    }\n    tempinst.argsym = new ScopeDsymbol();\n    tempinst.argsym.parent = _scope.parent;\n    _scope = _scope.push(tempinst.argsym);\n    _scope.tinst = tempinst;\n    _scope.minst = tempinst.minst;\n    //scope.stc = 0;\n\n    // Declare each template parameter as an alias for the argument type\n    Scope* paramscope = _scope.push();\n    paramscope.stc = 0;\n    paramscope.protection = Prot(Prot.Kind.public_); // https://issues.dlang.org/show_bug.cgi?id=14169\n                                              // template parameters should be public\n    tempinst.declareParameters(paramscope);\n    paramscope.pop();\n\n    // Add members of template instance to template instance symbol table\n    //parent = scope.scopesym;\n    tempinst.symtab = new DsymbolTable();\n    for (size_t i = 0; i < tempinst.members.dim; i++)\n    {\n        Dsymbol s = (*tempinst.members)[i];\n        static if (LOG)\n        {\n            printf(\"\\t[%d] adding member '%s' %p kind %s to '%s'\\n\", i, s.toChars(), s, s.kind(), tempinst.toChars());\n        }\n        s.addMember(_scope, tempinst);\n    }\n    static if (LOG)\n    {\n        printf(\"adding members done\\n\");\n    }\n\n    /* See if there is only one member of template instance, and that\n     * member has the same name as the template instance.\n     * If so, this template instance becomes an alias for that member.\n     */\n    //printf(\"members.dim = %d\\n\", members.dim);\n    if (tempinst.members.dim)\n    {\n        Dsymbol s;\n        if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)\n        {\n            //printf(\"tempdecl.ident = %s, s = '%s'\\n\", tempdecl.ident.toChars(), s.kind(), s.toPrettyChars());\n            //printf(\"setting aliasdecl\\n\");\n            tempinst.aliasdecl = s;\n        }\n    }\n\n    /* If function template declaration\n     */\n    if (fargs && tempinst.aliasdecl)\n    {\n        FuncDeclaration fd = tempinst.aliasdecl.isFuncDeclaration();\n        if (fd)\n        {\n            /* Transmit fargs to type so that TypeFunction.dsymbolSemantic() can\n             * resolve any \"auto ref\" storage classes.\n             */\n            TypeFunction tf = cast(TypeFunction)fd.type;\n            if (tf && tf.ty == Tfunction)\n                tf.fargs = fargs;\n        }\n    }\n\n    // Do semantic() analysis on template instance members\n    static if (LOG)\n    {\n        printf(\"\\tdo semantic() on template instance members '%s'\\n\", tempinst.toChars());\n    }\n    Scope* sc2;\n    sc2 = _scope.push(tempinst);\n    //printf(\"enclosing = %d, sc.parent = %s\\n\", tempinst.enclosing, sc.parent.toChars());\n    sc2.parent = tempinst;\n    sc2.tinst = tempinst;\n    sc2.minst = tempinst.minst;\n    tempinst.tryExpandMembers(sc2);\n\n    tempinst.semanticRun = PASS.semanticdone;\n\n    /* ConditionalDeclaration may introduce eponymous declaration,\n     * so we should find it once again after semantic.\n     */\n    if (tempinst.members.dim)\n    {\n        Dsymbol s;\n        if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)\n        {\n            if (!tempinst.aliasdecl || tempinst.aliasdecl != s)\n            {\n                //printf(\"tempdecl.ident = %s, s = '%s'\\n\", tempdecl.ident.toChars(), s.kind(), s.toPrettyChars());\n                //printf(\"setting aliasdecl 2\\n\");\n                tempinst.aliasdecl = s;\n            }\n        }\n    }\n\n    if (global.errors != errorsave)\n        goto Laftersemantic;\n\n    /* If any of the instantiation members didn't get semantic() run\n     * on them due to forward references, we cannot run semantic2()\n     * or semantic3() yet.\n     */\n    {\n        bool found_deferred_ad = false;\n        for (size_t i = 0; i < Module.deferred.dim; i++)\n        {\n            Dsymbol sd = Module.deferred[i];\n            AggregateDeclaration ad = sd.isAggregateDeclaration();\n            if (ad && ad.parent && ad.parent.isTemplateInstance())\n            {\n                //printf(\"deferred template aggregate: %s %s\\n\",\n                //        sd.parent.toChars(), sd.toChars());\n                found_deferred_ad = true;\n                if (ad.parent == tempinst)\n                {\n                    ad.deferred = tempinst;\n                    break;\n                }\n            }\n        }\n        if (found_deferred_ad || Module.deferred.dim)\n            goto Laftersemantic;\n    }\n\n    /* The problem is when to parse the initializer for a variable.\n     * Perhaps VarDeclaration.dsymbolSemantic() should do it like it does\n     * for initializers inside a function.\n     */\n    //if (sc.parent.isFuncDeclaration())\n    {\n        /* https://issues.dlang.org/show_bug.cgi?id=782\n         * this has problems if the classes this depends on\n         * are forward referenced. Find a way to defer semantic()\n         * on this template.\n         */\n        tempinst.semantic2(sc2);\n    }\n    if (global.errors != errorsave)\n        goto Laftersemantic;\n\n    if ((sc.func || (sc.flags & SCOPE.fullinst)) && !tempinst.tinst)\n    {\n        /* If a template is instantiated inside function, the whole instantiation\n         * should be done at that position. But, immediate running semantic3 of\n         * dependent templates may cause unresolved forward reference.\n         * https://issues.dlang.org/show_bug.cgi?id=9050\n         * To avoid the issue, don't run semantic3 until semantic and semantic2 done.\n         */\n        TemplateInstances deferred;\n        tempinst.deferred = &deferred;\n\n        //printf(\"Run semantic3 on %s\\n\", toChars());\n        tempinst.trySemantic3(sc2);\n\n        for (size_t i = 0; i < deferred.dim; i++)\n        {\n            //printf(\"+ run deferred semantic3 on %s\\n\", deferred[i].toChars());\n            deferred[i].semantic3(null);\n        }\n\n        tempinst.deferred = null;\n    }\n    else if (tempinst.tinst)\n    {\n        bool doSemantic3 = false;\n        FuncDeclaration fd;\n        if (tempinst.aliasdecl)\n            fd = tempinst.aliasdecl.toAlias2().isFuncDeclaration();\n\n        if (fd)\n        {\n            /* Template function instantiation should run semantic3 immediately\n             * for attribute inference.\n             */\n            scope fld = fd.isFuncLiteralDeclaration();\n            if (fld && fld.tok == TOK.reserved)\n                doSemantic3 = true;\n            else if (sc.func)\n                doSemantic3 = true;\n        }\n        else if (sc.func)\n        {\n            /* A lambda function in template arguments might capture the\n             * instantiated scope context. For the correct context inference,\n             * all instantiated functions should run the semantic3 immediately.\n             * See also compilable/test14973.d\n             */\n            foreach (oarg; tempinst.tdtypes)\n            {\n                auto s = getDsymbol(oarg);\n                if (!s)\n                    continue;\n\n                if (auto td = s.isTemplateDeclaration())\n                {\n                    if (!td.literal)\n                        continue;\n                    assert(td.members && td.members.dim == 1);\n                    s = (*td.members)[0];\n                }\n                if (auto fld = s.isFuncLiteralDeclaration())\n                {\n                    if (fld.tok == TOK.reserved)\n                    {\n                        doSemantic3 = true;\n                        break;\n                    }\n                }\n            }\n            //printf(\"[%s] %s doSemantic3 = %d\\n\", loc.toChars(), toChars(), doSemantic3);\n        }\n        if (doSemantic3)\n            tempinst.trySemantic3(sc2);\n\n        TemplateInstance ti = tempinst.tinst;\n        int nest = 0;\n        while (ti && !ti.deferred && ti.tinst)\n        {\n            ti = ti.tinst;\n            if (++nest > 500)\n            {\n                global.gag = 0; // ensure error message gets printed\n                tempinst.error(\"recursive expansion\");\n                fatal();\n            }\n        }\n        if (ti && ti.deferred)\n        {\n            //printf(\"deferred semantic3 of %p %s, ti = %s, ti.deferred = %p\\n\", this, toChars(), ti.toChars());\n            for (size_t i = 0;; i++)\n            {\n                if (i == ti.deferred.dim)\n                {\n                    ti.deferred.push(tempinst);\n                    break;\n                }\n                if ((*ti.deferred)[i] == tempinst)\n                    break;\n            }\n        }\n    }\n\n    if (tempinst.aliasdecl)\n    {\n        /* https://issues.dlang.org/show_bug.cgi?id=13816\n         * AliasDeclaration tries to resolve forward reference\n         * twice (See inuse check in AliasDeclaration.toAlias()). It's\n         * necessary to resolve mutual references of instantiated symbols, but\n         * it will left a true recursive alias in tuple declaration - an\n         * AliasDeclaration A refers TupleDeclaration B, and B contains A\n         * in its elements.  To correctly make it an error, we strictly need to\n         * resolve the alias of eponymous member.\n         */\n        tempinst.aliasdecl = tempinst.aliasdecl.toAlias2();\n    }\n\nLaftersemantic:\n    sc2.pop();\n    _scope.pop();\n\n    // Give additional context info if error occurred during instantiation\n    if (global.errors != errorsave)\n    {\n        if (!tempinst.errors)\n        {\n            if (!tempdecl.literal)\n                tempinst.error(tempinst.loc, \"error instantiating\");\n            if (tempinst.tinst)\n                tempinst.tinst.printInstantiationTrace();\n        }\n        tempinst.errors = true;\n        if (tempinst.gagged)\n        {\n            // Errors are gagged, so remove the template instance from the\n            // instance/symbol lists we added it to and reset our state to\n            // finish clean and so we can try to instantiate it again later\n            // (see https://issues.dlang.org/show_bug.cgi?id=4302 and https://issues.dlang.org/show_bug.cgi?id=6602).\n            tempdecl.removeInstance(tempdecl_instance_idx);\n            if (target_symbol_list)\n            {\n                // Because we added 'this' in the last position above, we\n                // should be able to remove it without messing other indices up.\n                assert((*target_symbol_list)[target_symbol_list_idx] == tempinst);\n                target_symbol_list.remove(target_symbol_list_idx);\n                tempinst.memberOf = null;                    // no longer a member\n            }\n            tempinst.semanticRun = PASS.init;\n            tempinst.inst = null;\n            tempinst.symtab = null;\n        }\n    }\n    else if (errinst)\n    {\n        /* https://issues.dlang.org/show_bug.cgi?id=14541\n         * If the previous gagged instance had failed by\n         * circular references, currrent \"error reproduction instantiation\"\n         * might succeed, because of the difference of instantiated context.\n         * On such case, the cached error instance needs to be overridden by the\n         * succeeded instance.\n         */\n        //printf(\"replaceInstance()\\n\");\n        assert(errinst.errors);\n        auto ti1 = TemplateInstanceBox(errinst);\n        tempdecl.instances.remove(ti1);\n\n        auto ti2 = TemplateInstanceBox(tempinst);\n        tempdecl.instances[ti2] = tempinst;\n    }\n\n    static if (LOG)\n    {\n        printf(\"-TemplateInstance.dsymbolSemantic('%s', this=%p)\\n\", toChars(), this);\n    }\n}\n\n// function used to perform semantic on AliasDeclaration\nvoid aliasSemantic(AliasDeclaration ds, Scope* sc)\n{\n    //printf(\"AliasDeclaration::semantic() %s\\n\", ds.toChars());\n    if (ds.aliassym)\n    {\n        auto fd = ds.aliassym.isFuncLiteralDeclaration();\n        auto td = ds.aliassym.isTemplateDeclaration();\n        if (fd || td && td.literal)\n        {\n            if (fd && fd.semanticRun >= PASS.semanticdone)\n                return;\n\n            Expression e = new FuncExp(ds.loc, ds.aliassym);\n            e = e.expressionSemantic(sc);\n            if (e.op == TOK.function_)\n            {\n                FuncExp fe = cast(FuncExp)e;\n                ds.aliassym = fe.td ? cast(Dsymbol)fe.td : fe.fd;\n            }\n            else\n            {\n                ds.aliassym = null;\n                ds.type = Type.terror;\n            }\n            return;\n        }\n\n        if (ds.aliassym.isTemplateInstance())\n            ds.aliassym.dsymbolSemantic(sc);\n        return;\n    }\n    ds.inuse = 1;\n\n    // Given:\n    //  alias foo.bar.abc def;\n    // it is not knowable from the syntax whether this is an alias\n    // for a type or an alias for a symbol. It is up to the semantic()\n    // pass to distinguish.\n    // If it is a type, then type is set and getType() will return that\n    // type. If it is a symbol, then aliassym is set and type is NULL -\n    // toAlias() will return aliasssym.\n\n    uint errors = global.errors;\n    Type oldtype = ds.type;\n\n    // Ungag errors when not instantiated DeclDefs scope alias\n    auto ungag = Ungag(global.gag);\n    //printf(\"%s parent = %s, gag = %d, instantiated = %d\\n\", toChars(), parent, global.gag, isInstantiated());\n    if (ds.parent && global.gag && !ds.isInstantiated() && !ds.toParent2().isFuncDeclaration())\n    {\n        //printf(\"%s type = %s\\n\", toPrettyChars(), type.toChars());\n        global.gag = 0;\n    }\n\n    // https://issues.dlang.org/show_bug.cgi?id=18480\n    // Detect `alias sym = sym;` to prevent creating loops in overload overnext lists.\n    // Selective imports are allowed to alias to the same name `import mod : sym=sym`.\n    if (ds.type.ty == Tident && !ds._import)\n    {\n        auto tident = cast(TypeIdentifier)ds.type;\n        if (tident.ident is ds.ident && !tident.idents.dim)\n        {\n            error(ds.loc, \"`alias %s = %s;` cannot alias itself, use a qualified name to create an overload set\",\n                ds.ident.toChars(), tident.ident.toChars());\n            ds.type = Type.terror;\n        }\n    }\n    /* This section is needed because Type.resolve() will:\n     *   const x = 3;\n     *   alias y = x;\n     * try to convert identifier x to 3.\n     */\n    auto s = ds.type.toDsymbol(sc);\n    if (errors != global.errors)\n    {\n        s = null;\n        ds.type = Type.terror;\n    }\n    if (s && s == ds)\n    {\n        ds.error(\"cannot resolve\");\n        s = null;\n        ds.type = Type.terror;\n    }\n    if (!s || !s.isEnumMember())\n    {\n        Type t;\n        Expression e;\n        Scope* sc2 = sc;\n        if (ds.storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.disable))\n        {\n            // For 'ref' to be attached to function types, and picked\n            // up by Type.resolve(), it has to go into sc.\n            sc2 = sc.push();\n            sc2.stc |= ds.storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.shared_ | STC.disable);\n        }\n        ds.type = ds.type.addSTC(ds.storage_class);\n        ds.type.resolve(ds.loc, sc2, &e, &t, &s);\n        if (sc2 != sc)\n            sc2.pop();\n\n        if (e)  // Try to convert Expression to Dsymbol\n        {\n            s = getDsymbol(e);\n            if (!s)\n            {\n                if (e.op != TOK.error)\n                    ds.error(\"cannot alias an expression `%s`\", e.toChars());\n                t = Type.terror;\n            }\n        }\n        ds.type = t;\n    }\n    if (s == ds)\n    {\n        assert(global.errors);\n        ds.type = Type.terror;\n        s = null;\n    }\n    if (!s) // it's a type alias\n    {\n        //printf(\"alias %s resolved to type %s\\n\", toChars(), type.toChars());\n        ds.type = ds.type.typeSemantic(ds.loc, sc);\n        ds.aliassym = null;\n    }\n    else    // it's a symbolic alias\n    {\n        //printf(\"alias %s resolved to %s %s\\n\", toChars(), s.kind(), s.toChars());\n        ds.type = null;\n        ds.aliassym = s;\n    }\n    if (global.gag && errors != global.errors)\n    {\n        ds.type = oldtype;\n        ds.aliassym = null;\n    }\n    ds.inuse = 0;\n    ds.semanticRun = PASS.semanticdone;\n\n    if (auto sx = ds.overnext)\n    {\n        ds.overnext = null;\n        if (!ds.overloadInsert(sx))\n            ScopeDsymbol.multiplyDefined(Loc.initial, sx, ds);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/dtemplate.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Template implementation.\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dtemplate.d, _dtemplate.d)\n * Documentation:  https://dlang.org/phobos/dmd_dtemplate.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dtemplate.d\n */\n\nmodule dmd.dtemplate;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arraytypes;\nimport dmd.dcast;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dmangle;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.impcnvtab;\nimport dmd.init;\nimport dmd.initsem;\nimport dmd.mtype;\nimport dmd.opover;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.semantic2;\nimport dmd.semantic3;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.visitor;\n\nimport dmd.templateparamsem;\n\n//debug = FindExistingInstance; // print debug stats of findExistingInstance\nprivate enum LOG = false;\n\nenum IDX_NOTFOUND = 0x12345678;\n\n/********************************************\n * These functions substitute for dynamic_cast. dynamic_cast does not work\n * on earlier versions of gcc.\n */\nextern (C++) inout(Expression) isExpression(inout RootObject o)\n{\n    //return dynamic_cast<Expression *>(o);\n    if (!o || o.dyncast() != DYNCAST.expression)\n        return null;\n    return cast(inout(Expression))o;\n}\n\nextern (C++) inout(Dsymbol) isDsymbol(inout RootObject o)\n{\n    //return dynamic_cast<Dsymbol *>(o);\n    if (!o || o.dyncast() != DYNCAST.dsymbol)\n        return null;\n    return cast(inout(Dsymbol))o;\n}\n\nextern (C++) inout(Type) isType(inout RootObject o)\n{\n    //return dynamic_cast<Type *>(o);\n    if (!o || o.dyncast() != DYNCAST.type)\n        return null;\n    return cast(inout(Type))o;\n}\n\nextern (C++) inout(Tuple) isTuple(inout RootObject o)\n{\n    //return dynamic_cast<Tuple *>(o);\n    if (!o || o.dyncast() != DYNCAST.tuple)\n        return null;\n    return cast(inout(Tuple))o;\n}\n\nextern (C++) inout(Parameter) isParameter(inout RootObject o)\n{\n    //return dynamic_cast<Parameter *>(o);\n    if (!o || o.dyncast() != DYNCAST.parameter)\n        return null;\n    return cast(inout(Parameter))o;\n}\n\nextern (C++) inout(TemplateParameter) isTemplateParameter(inout RootObject o)\n    {\n        if (!o || o.dyncast() != DYNCAST.templateparameter)\n            return null;\n        return cast(inout(TemplateParameter))o;\n    }\n\n/**************************************\n * Is this Object an error?\n */\nextern (C++) bool isError(const RootObject o)\n{\n    if (const t = isType(o))\n        return (t.ty == Terror);\n    if (const e = isExpression(o))\n        return (e.op == TOK.error || !e.type || e.type.ty == Terror);\n    if (const v = isTuple(o))\n        return arrayObjectIsError(&v.objects);\n    const s = isDsymbol(o);\n    assert(s);\n    if (s.errors)\n        return true;\n    return s.parent ? isError(s.parent) : false;\n}\n\n/**************************************\n * Are any of the Objects an error?\n */\nextern (C++) bool arrayObjectIsError(const Objects* args)\n{\n    foreach (const o; *args)\n    {\n        if (isError(o))\n            return true;\n    }\n    return false;\n}\n\n/***********************\n * Try to get arg as a type.\n */\nextern (C++) inout(Type) getType(inout RootObject o)\n{\n    inout t = isType(o);\n    if (!t)\n    {\n        if (inout e = isExpression(o))\n            return e.type;\n    }\n    return t;\n}\n\nextern (C++) Dsymbol getDsymbol(RootObject oarg)\n{\n    //printf(\"getDsymbol()\\n\");\n    //printf(\"e %p s %p t %p v %p\\n\", isExpression(oarg), isDsymbol(oarg), isType(oarg), isTuple(oarg));\n    Dsymbol sa;\n    if (Expression ea = isExpression(oarg))\n    {\n        // Try to convert Expression to symbol\n        if (ea.op == TOK.variable)\n            sa = (cast(VarExp)ea).var;\n        else if (ea.op == TOK.function_)\n        {\n            if ((cast(FuncExp)ea).td)\n                sa = (cast(FuncExp)ea).td;\n            else\n                sa = (cast(FuncExp)ea).fd;\n        }\n        else if (ea.op == TOK.template_)\n            sa = (cast(TemplateExp)ea).td;\n        else\n            sa = null;\n    }\n    else\n    {\n        // Try to convert Type to symbol\n        if (Type ta = isType(oarg))\n            sa = ta.toDsymbol(null);\n        else\n            sa = isDsymbol(oarg); // if already a symbol\n    }\n    return sa;\n}\n\nprivate Expression getValue(ref Dsymbol s)\n{\n    if (s)\n    {\n        if (VarDeclaration v = s.isVarDeclaration())\n        {\n            if (v.storage_class & STC.manifest)\n                return v.getConstInitializer();\n        }\n    }\n    return null;\n}\n\n/***********************\n * Try to get value from manifest constant\n */\nprivate Expression getValue(Expression e)\n{\n    if (e && e.op == TOK.variable)\n    {\n        VarDeclaration v = (cast(VarExp)e).var.isVarDeclaration();\n        if (v && v.storage_class & STC.manifest)\n        {\n            e = v.getConstInitializer();\n        }\n    }\n    return e;\n}\n\nprivate Expression getExpression(RootObject o)\n{\n    auto s = isDsymbol(o);\n    return s ? .getValue(s) : .getValue(isExpression(o));\n}\n\n/******************************\n * If o1 matches o2, return true.\n * Else, return false.\n */\nprivate bool match(RootObject o1, RootObject o2)\n{\n    enum log = false;\n\n    static if (log)\n    {\n        printf(\"match() o1 = %p %s (%d), o2 = %p %s (%d)\\n\",\n            o1, o1.toChars(), o1.dyncast(), o2, o2.toChars(), o2.dyncast());\n    }\n\n    /* A proper implementation of the various equals() overrides\n     * should make it possible to just do o1.equals(o2), but\n     * we'll do that another day.\n     */\n    /* Manifest constants should be compared by their values,\n     * at least in template arguments.\n     */\n\n    if (auto t1 = isType(o1))\n    {\n        auto t2 = isType(o2);\n        if (!t2)\n            goto Lnomatch;\n\n        static if (log)\n        {\n            printf(\"\\tt1 = %s\\n\", t1.toChars());\n            printf(\"\\tt2 = %s\\n\", t2.toChars());\n        }\n        if (!t1.equals(t2))\n            goto Lnomatch;\n\n        goto Lmatch;\n    }\n    if (auto e1 = getExpression(o1))\n    {\n        auto e2 = getExpression(o2);\n        if (!e2)\n            goto Lnomatch;\n\n        static if (log)\n        {\n            printf(\"\\te1 = %s '%s' %s\\n\", e1.type.toChars(), Token.toChars(e1.op), e1.toChars());\n            printf(\"\\te2 = %s '%s' %s\\n\", e2.type.toChars(), Token.toChars(e2.op), e2.toChars());\n        }\n\n        // two expressions can be equal although they do not have the same\n        // type; that happens when they have the same value. So check type\n        // as well as expression equality to ensure templates are properly\n        // matched.\n        if (!e1.type.equals(e2.type) || !e1.equals(e2))\n            goto Lnomatch;\n\n        goto Lmatch;\n    }\n    if (auto s1 = isDsymbol(o1))\n    {\n        auto s2 = isDsymbol(o2);\n        if (!s2)\n            goto Lnomatch;\n\n        static if (log)\n        {\n            printf(\"\\ts1 = %s \\n\", s1.kind(), s1.toChars());\n            printf(\"\\ts2 = %s \\n\", s2.kind(), s2.toChars());\n        }\n        if (!s1.equals(s2))\n            goto Lnomatch;\n        if (s1.parent != s2.parent && !s1.isFuncDeclaration() && !s2.isFuncDeclaration())\n            goto Lnomatch;\n\n        goto Lmatch;\n    }\n    if (auto u1 = isTuple(o1))\n    {\n        auto u2 = isTuple(o2);\n        if (!u2)\n            goto Lnomatch;\n\n        static if (log)\n        {\n            printf(\"\\tu1 = %s\\n\", u1.toChars());\n            printf(\"\\tu2 = %s\\n\", u2.toChars());\n        }\n        if (!arrayObjectMatch(&u1.objects, &u2.objects))\n            goto Lnomatch;\n\n        goto Lmatch;\n    }\nLmatch:\n    static if (log)\n        printf(\"\\t. match\\n\");\n    return true;\n\nLnomatch:\n    static if (log)\n        printf(\"\\t. nomatch\\n\");\n    return false;\n}\n\n/************************************\n * Match an array of them.\n */\nprivate bool arrayObjectMatch(Objects* oa1, Objects* oa2)\n{\n    if (oa1 == oa2)\n        return true;\n    if (oa1.dim != oa2.dim)\n        return false;\n    immutable oa1dim = oa1.dim;\n    auto oa1d = (*oa1).data;\n    auto oa2d = (*oa2).data;\n    foreach (j; 0 .. oa1dim)\n    {\n        RootObject o1 = oa1d[j];\n        RootObject o2 = oa2d[j];\n        if (!match(o1, o2))\n        {\n            return false;\n        }\n    }\n    return true;\n}\n\n/************************************\n * Return hash of Objects.\n */\nprivate hash_t arrayObjectHash(Objects* oa1)\n{\n    import dmd.root.hash : mixHash;\n\n    hash_t hash = 0;\n    foreach (o1; *oa1)\n    {\n        /* Must follow the logic of match()\n         */\n        if (auto t1 = isType(o1))\n            hash = mixHash(hash, cast(size_t)t1.deco);\n        else if (auto e1 = getExpression(o1))\n            hash = mixHash(hash, expressionHash(e1));\n        else if (auto s1 = isDsymbol(o1))\n        {\n            auto fa1 = s1.isFuncAliasDeclaration();\n            if (fa1)\n                s1 = fa1.toAliasFunc();\n            hash = mixHash(hash, mixHash(cast(size_t)cast(void*)s1.getIdent(), cast(size_t)cast(void*)s1.parent));\n        }\n        else if (auto u1 = isTuple(o1))\n            hash = mixHash(hash, arrayObjectHash(&u1.objects));\n    }\n    return hash;\n}\n\n\n/************************************\n * Computes hash of expression.\n * Handles all Expression classes and MUST match their equals method,\n * i.e. e1.equals(e2) implies expressionHash(e1) == expressionHash(e2).\n */\nprivate hash_t expressionHash(Expression e)\n{\n    import dmd.root.ctfloat : CTFloat;\n    import dmd.root.hash : calcHash, mixHash;\n\n    switch (e.op)\n    {\n    case TOK.int64:\n        return cast(size_t) (cast(IntegerExp)e).getInteger();\n\n    case TOK.float64:\n        return CTFloat.hash((cast(RealExp)e).value);\n\n    case TOK.complex80:\n        auto ce = cast(ComplexExp)e;\n        return mixHash(CTFloat.hash(ce.toReal), CTFloat.hash(ce.toImaginary));\n\n    case TOK.identifier:\n        return cast(size_t)cast(void*) (cast(IdentifierExp)e).ident;\n\n    case TOK.null_:\n        return cast(size_t)cast(void*) (cast(NullExp)e).type;\n\n    case TOK.string_:\n        auto se = cast(StringExp)e;\n        return calcHash(se.string, se.len * se.sz);\n\n    case TOK.tuple:\n    {\n        auto te = cast(TupleExp)e;\n        size_t hash = 0;\n        hash += te.e0 ? expressionHash(te.e0) : 0;\n        foreach (elem; *te.exps)\n            hash = mixHash(hash, expressionHash(elem));\n        return hash;\n    }\n\n    case TOK.arrayLiteral:\n    {\n        auto ae = cast(ArrayLiteralExp)e;\n        size_t hash;\n        foreach (i; 0 .. ae.elements.dim)\n            hash = mixHash(hash, expressionHash(ae.getElement(i)));\n        return hash;\n    }\n\n    case TOK.assocArrayLiteral:\n    {\n        auto ae = cast(AssocArrayLiteralExp)e;\n        size_t hash;\n        foreach (i; 0 .. ae.keys.dim)\n            // reduction needs associative op as keys are unsorted (use XOR)\n            hash ^= mixHash(expressionHash((*ae.keys)[i]), expressionHash((*ae.values)[i]));\n        return hash;\n    }\n\n    case TOK.structLiteral:\n    {\n        auto se = cast(StructLiteralExp)e;\n        size_t hash;\n        foreach (elem; *se.elements)\n            hash = mixHash(hash, elem ? expressionHash(elem) : 0);\n        return hash;\n    }\n\n    case TOK.variable:\n        return cast(size_t)cast(void*) (cast(VarExp)e).var;\n\n    case TOK.function_:\n        return cast(size_t)cast(void*) (cast(FuncExp)e).fd;\n\n    default:\n        // no custom equals for this expression\n        assert((&e.equals).funcptr is &RootObject.equals);\n        // equals based on identity\n        return cast(size_t)cast(void*) e;\n    }\n}\n\nRootObject objectSyntaxCopy(RootObject o)\n{\n    if (!o)\n        return null;\n    if (Type t = isType(o))\n        return t.syntaxCopy();\n    if (Expression e = isExpression(o))\n        return e.syntaxCopy();\n    return o;\n}\n\nextern (C++) final class Tuple : RootObject\n{\n    Objects objects;\n\n    extern (D) this() {}\n\n    /**\n    Params:\n        numObjects = The initial number of objects.\n    */\n    extern (D) this(size_t numObjects)\n    {\n        objects.setDim(numObjects);\n    }\n\n    // kludge for template.isType()\n    override DYNCAST dyncast() const\n    {\n        return DYNCAST.tuple;\n    }\n\n    override const(char)* toChars()\n    {\n        return objects.toChars();\n    }\n}\n\nstruct TemplatePrevious\n{\n    TemplatePrevious* prev;\n    Scope* sc;\n    Objects* dedargs;\n}\n\n/***********************************************************\n */\nextern (C++) final class TemplateDeclaration : ScopeDsymbol\n{\n    TemplateParameters* parameters;     // array of TemplateParameter's\n    TemplateParameters* origParameters; // originals for Ddoc\n\n    Expression constraint;\n\n    // Hash table to look up TemplateInstance's of this TemplateDeclaration\n    TemplateInstance[TemplateInstanceBox] instances;\n\n    TemplateDeclaration overnext;       // next overloaded TemplateDeclaration\n    TemplateDeclaration overroot;       // first in overnext list\n    FuncDeclaration funcroot;           // first function in unified overload list\n\n    Dsymbol onemember;      // if !=null then one member of this template\n\n    bool literal;           // this template declaration is a literal\n    bool ismixin;           // template declaration is only to be used as a mixin\n    bool isstatic;          // this is static template declaration\n    Prot protection;\n    int inuse;              /// for recursive expansion detection\n\n    // threaded list of previous instantiation attempts on stack\n    TemplatePrevious* previous;\n\n    extern (D) this(const ref Loc loc, Identifier id, TemplateParameters* parameters, Expression constraint, Dsymbols* decldefs, bool ismixin = false, bool literal = false)\n    {\n        super(id);\n        static if (LOG)\n        {\n            printf(\"TemplateDeclaration(this = %p, id = '%s')\\n\", this, id.toChars());\n        }\n        version (none)\n        {\n            if (parameters)\n                for (int i = 0; i < parameters.dim; i++)\n                {\n                    TemplateParameter tp = (*parameters)[i];\n                    //printf(\"\\tparameter[%d] = %p\\n\", i, tp);\n                    TemplateTypeParameter ttp = tp.isTemplateTypeParameter();\n                    if (ttp)\n                    {\n                        printf(\"\\tparameter[%d] = %s : %s\\n\", i, tp.ident.toChars(), ttp.specType ? ttp.specType.toChars() : \"\");\n                    }\n                }\n        }\n        this.loc = loc;\n        this.parameters = parameters;\n        this.origParameters = parameters;\n        this.constraint = constraint;\n        this.members = decldefs;\n        this.literal = literal;\n        this.ismixin = ismixin;\n        this.isstatic = true;\n        this.protection = Prot(Prot.Kind.undefined);\n\n        // Compute in advance for Ddoc's use\n        // https://issues.dlang.org/show_bug.cgi?id=11153: ident could be NULL if parsing fails.\n        if (members && ident)\n        {\n            Dsymbol s;\n            if (Dsymbol.oneMembers(members, &s, ident) && s)\n            {\n                onemember = s;\n                s.parent = this;\n            }\n        }\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol)\n    {\n        //printf(\"TemplateDeclaration.syntaxCopy()\\n\");\n        TemplateParameters* p = null;\n        if (parameters)\n        {\n            p = new TemplateParameters(parameters.dim);\n            for (size_t i = 0; i < p.dim; i++)\n                (*p)[i] = (*parameters)[i].syntaxCopy();\n        }\n        return new TemplateDeclaration(loc, ident, p, constraint ? constraint.syntaxCopy() : null, Dsymbol.arraySyntaxCopy(members), ismixin, literal);\n    }\n\n    /**********************************\n     * Overload existing TemplateDeclaration 'this' with the new one 's'.\n     * Return true if successful; i.e. no conflict.\n     */\n    override bool overloadInsert(Dsymbol s)\n    {\n        static if (LOG)\n        {\n            printf(\"TemplateDeclaration.overloadInsert('%s')\\n\", s.toChars());\n        }\n        FuncDeclaration fd = s.isFuncDeclaration();\n        if (fd)\n        {\n            if (funcroot)\n                return funcroot.overloadInsert(fd);\n            funcroot = fd;\n            return funcroot.overloadInsert(this);\n        }\n\n        TemplateDeclaration td = s.isTemplateDeclaration();\n        if (!td)\n            return false;\n\n        TemplateDeclaration pthis = this;\n        TemplateDeclaration* ptd;\n        for (ptd = &pthis; *ptd; ptd = &(*ptd).overnext)\n        {\n        }\n\n        td.overroot = this;\n        *ptd = td;\n        static if (LOG)\n        {\n            printf(\"\\ttrue: no conflict\\n\");\n        }\n        return true;\n    }\n\n    override bool hasStaticCtorOrDtor()\n    {\n        return false; // don't scan uninstantiated templates\n    }\n\n    override const(char)* kind() const\n    {\n        return (onemember && onemember.isAggregateDeclaration()) ? onemember.kind() : \"template\";\n    }\n\n    override const(char)* toChars()\n    {\n        if (literal)\n            return Dsymbol.toChars();\n\n        OutBuffer buf;\n        HdrGenState hgs;\n\n        buf.writestring(ident.toChars());\n        buf.writeByte('(');\n        for (size_t i = 0; i < parameters.dim; i++)\n        {\n            TemplateParameter tp = (*parameters)[i];\n            if (i)\n                buf.writestring(\", \");\n            .toCBuffer(tp, &buf, &hgs);\n        }\n        buf.writeByte(')');\n\n        if (onemember)\n        {\n            FuncDeclaration fd = onemember.isFuncDeclaration();\n            if (fd && fd.type)\n            {\n                TypeFunction tf = cast(TypeFunction)fd.type;\n                buf.writestring(parametersTypeToChars(tf.parameters, tf.varargs));\n            }\n        }\n\n        if (constraint)\n        {\n            buf.writestring(\" if (\");\n            .toCBuffer(constraint, &buf, &hgs);\n            buf.writeByte(')');\n        }\n        return buf.extractString();\n    }\n\n    override Prot prot()\n    {\n        return protection;\n    }\n\n    /****************************\n     * Check to see if constraint is satisfied.\n     */\n    extern (D) bool evaluateConstraint(TemplateInstance ti, Scope* sc, Scope* paramscope, Objects* dedargs, FuncDeclaration fd)\n    {\n        /* Detect recursive attempts to instantiate this template declaration,\n         * https://issues.dlang.org/show_bug.cgi?id=4072\n         *  void foo(T)(T x) if (is(typeof(foo(x)))) { }\n         *  static assert(!is(typeof(foo(7))));\n         * Recursive attempts are regarded as a constraint failure.\n         */\n        /* There's a chicken-and-egg problem here. We don't know yet if this template\n         * instantiation will be a local one (enclosing is set), and we won't know until\n         * after selecting the correct template. Thus, function we're nesting inside\n         * is not on the sc scope chain, and this can cause errors in FuncDeclaration.getLevel().\n         * Workaround the problem by setting a flag to relax the checking on frame errors.\n         */\n\n        for (TemplatePrevious* p = previous; p; p = p.prev)\n        {\n            if (arrayObjectMatch(p.dedargs, dedargs))\n            {\n                //printf(\"recursive, no match p.sc=%p %p %s\\n\", p.sc, this, this.toChars());\n                /* It must be a subscope of p.sc, other scope chains are not recursive\n                 * instantiations.\n                 */\n                for (Scope* scx = sc; scx; scx = scx.enclosing)\n                {\n                    if (scx == p.sc)\n                        return false;\n                }\n            }\n            /* BUG: should also check for ref param differences\n             */\n        }\n\n        TemplatePrevious pr;\n        pr.prev = previous;\n        pr.sc = paramscope;\n        pr.dedargs = dedargs;\n        previous = &pr; // add this to threaded list\n\n        Scope* scx = paramscope.push(ti);\n        scx.parent = ti;\n        scx.tinst = null;\n        scx.minst = null;\n\n        assert(!ti.symtab);\n        if (fd)\n        {\n            /* Declare all the function parameters as variables and add them to the scope\n             * Making parameters is similar to FuncDeclaration.semantic3\n             */\n            TypeFunction tf = cast(TypeFunction)fd.type;\n            assert(tf.ty == Tfunction);\n\n            scx.parent = fd;\n\n            Parameters* fparameters = tf.parameters;\n            int fvarargs = tf.varargs;\n            size_t nfparams = Parameter.dim(fparameters);\n            for (size_t i = 0; i < nfparams; i++)\n            {\n                Parameter fparam = Parameter.getNth(fparameters, i);\n                fparam.storageClass &= (STC.in_ | STC.out_ | STC.ref_ | STC.lazy_ | STC.final_ | STC.TYPECTOR | STC.nodtor);\n                fparam.storageClass |= STC.parameter;\n                if (fvarargs == 2 && i + 1 == nfparams)\n                {\n                    fparam.storageClass |= STC.variadic;\n                    /* Don't need to set STC.scope_ because this will only\n                     * be evaluated at compile time\n                     */\n                }\n            }\n            for (size_t i = 0; i < fparameters.dim; i++)\n            {\n                Parameter fparam = (*fparameters)[i];\n                if (!fparam.ident)\n                    continue;\n                // don't add it, if it has no name\n                auto v = new VarDeclaration(loc, fparam.type, fparam.ident, null);\n                v.storage_class = fparam.storageClass;\n                v.dsymbolSemantic(scx);\n                if (!ti.symtab)\n                    ti.symtab = new DsymbolTable();\n                if (!scx.insert(v))\n                    error(\"parameter `%s.%s` is already defined\", toChars(), v.toChars());\n                else\n                    v.parent = fd;\n            }\n            if (isstatic)\n                fd.storage_class |= STC.static_;\n            fd.vthis = fd.declareThis(scx, fd.isThis());\n        }\n\n        Expression e = constraint.syntaxCopy();\n\n        import dmd.staticcond;\n\n        assert(ti.inst is null);\n        ti.inst = ti; // temporary instantiation to enable genIdent()\n        scx.flags |= SCOPE.constraint;\n        bool errors;\n        bool result = evalStaticCondition(scx, constraint, e, errors);\n        ti.inst = null;\n        ti.symtab = null;\n        scx = scx.pop();\n        previous = pr.prev; // unlink from threaded list\n        if (errors)\n            return false;\n        return result;\n    }\n\n    /***************************************\n     * Given that ti is an instance of this TemplateDeclaration,\n     * deduce the types of the parameters to this, and store\n     * those deduced types in dedtypes[].\n     * Input:\n     *      flag    1: don't do semantic() because of dummy types\n     *              2: don't change types in matchArg()\n     * Output:\n     *      dedtypes        deduced arguments\n     * Return match level.\n     */\n    extern (D) MATCH matchWithInstance(Scope* sc, TemplateInstance ti, Objects* dedtypes, Expressions* fargs, int flag)\n    {\n        enum LOGM = 0;\n        static if (LOGM)\n        {\n            printf(\"\\n+TemplateDeclaration.matchWithInstance(this = %s, ti = %s, flag = %d)\\n\", toChars(), ti.toChars(), flag);\n        }\n        version (none)\n        {\n            printf(\"dedtypes.dim = %d, parameters.dim = %d\\n\", dedtypes.dim, parameters.dim);\n            if (ti.tiargs.dim)\n                printf(\"ti.tiargs.dim = %d, [0] = %p\\n\", ti.tiargs.dim, (*ti.tiargs)[0]);\n        }\n        MATCH m;\n        size_t dedtypes_dim = dedtypes.dim;\n\n        dedtypes.zero();\n\n        if (errors)\n            return MATCH.nomatch;\n\n        size_t parameters_dim = parameters.dim;\n        int variadic = isVariadic() !is null;\n\n        // If more arguments than parameters, no match\n        if (ti.tiargs.dim > parameters_dim && !variadic)\n        {\n            static if (LOGM)\n            {\n                printf(\" no match: more arguments than parameters\\n\");\n            }\n            return MATCH.nomatch;\n        }\n\n        assert(dedtypes_dim == parameters_dim);\n        assert(dedtypes_dim >= ti.tiargs.dim || variadic);\n\n        assert(_scope);\n\n        // Set up scope for template parameters\n        auto paramsym = new ScopeDsymbol();\n        paramsym.parent = _scope.parent;\n        Scope* paramscope = _scope.push(paramsym);\n        paramscope.tinst = ti;\n        paramscope.minst = sc.minst;\n        paramscope.callsc = sc;\n        paramscope.stc = 0;\n\n        // Attempt type deduction\n        m = MATCH.exact;\n        for (size_t i = 0; i < dedtypes_dim; i++)\n        {\n            MATCH m2;\n            TemplateParameter tp = (*parameters)[i];\n            Declaration sparam;\n\n            //printf(\"\\targument [%d]\\n\", i);\n            static if (LOGM)\n            {\n                //printf(\"\\targument [%d] is %s\\n\", i, oarg ? oarg.toChars() : \"null\");\n                TemplateTypeParameter ttp = tp.isTemplateTypeParameter();\n                if (ttp)\n                    printf(\"\\tparameter[%d] is %s : %s\\n\", i, tp.ident.toChars(), ttp.specType ? ttp.specType.toChars() : \"\");\n            }\n\n            inuse++;\n            m2 = tp.matchArg(ti.loc, paramscope, ti.tiargs, i, parameters, dedtypes, &sparam);\n            inuse--;\n            //printf(\"\\tm2 = %d\\n\", m2);\n            if (m2 == MATCH.nomatch)\n            {\n                version (none)\n                {\n                    printf(\"\\tmatchArg() for parameter %i failed\\n\", i);\n                }\n                goto Lnomatch;\n            }\n\n            if (m2 < m)\n                m = m2;\n\n            if (!flag)\n                sparam.dsymbolSemantic(paramscope);\n            if (!paramscope.insert(sparam)) // TODO: This check can make more early\n            {\n                // in TemplateDeclaration.semantic, and\n                // then we don't need to make sparam if flags == 0\n                goto Lnomatch;\n            }\n        }\n\n        if (!flag)\n        {\n            /* Any parameter left without a type gets the type of\n             * its corresponding arg\n             */\n            for (size_t i = 0; i < dedtypes_dim; i++)\n            {\n                if (!(*dedtypes)[i])\n                {\n                    assert(i < ti.tiargs.dim);\n                    (*dedtypes)[i] = cast(Type)(*ti.tiargs)[i];\n                }\n            }\n        }\n\n        if (m > MATCH.nomatch && constraint && !flag)\n        {\n            if (ti.hasNestedArgs(ti.tiargs, this.isstatic)) // TODO: should gag error\n                ti.parent = ti.enclosing;\n            else\n                ti.parent = this.parent;\n\n            // Similar to doHeaderInstantiation\n            FuncDeclaration fd = onemember ? onemember.isFuncDeclaration() : null;\n            if (fd)\n            {\n                assert(fd.type.ty == Tfunction);\n                TypeFunction tf = cast(TypeFunction)fd.type.syntaxCopy();\n\n                fd = new FuncDeclaration(fd.loc, fd.endloc, fd.ident, fd.storage_class, tf);\n                fd.parent = ti;\n                fd.inferRetType = true;\n\n                // Shouldn't run semantic on default arguments and return type.\n                for (size_t i = 0; i < tf.parameters.dim; i++)\n                    (*tf.parameters)[i].defaultArg = null;\n                tf.next = null;\n\n                // Resolve parameter types and 'auto ref's.\n                tf.fargs = fargs;\n                uint olderrors = global.startGagging();\n                fd.type = tf.typeSemantic(loc, paramscope);\n                if (global.endGagging(olderrors))\n                {\n                    assert(fd.type.ty != Tfunction);\n                    goto Lnomatch;\n                }\n                assert(fd.type.ty == Tfunction);\n                fd.originalType = fd.type; // for mangling\n            }\n\n            // TODO: dedtypes => ti.tiargs ?\n            if (!evaluateConstraint(ti, sc, paramscope, dedtypes, fd))\n                goto Lnomatch;\n        }\n\n        static if (LOGM)\n        {\n            // Print out the results\n            printf(\"--------------------------\\n\");\n            printf(\"template %s\\n\", toChars());\n            printf(\"instance %s\\n\", ti.toChars());\n            if (m > MATCH.nomatch)\n            {\n                for (size_t i = 0; i < dedtypes_dim; i++)\n                {\n                    TemplateParameter tp = (*parameters)[i];\n                    RootObject oarg;\n                    printf(\" [%d]\", i);\n                    if (i < ti.tiargs.dim)\n                        oarg = (*ti.tiargs)[i];\n                    else\n                        oarg = null;\n                    tp.print(oarg, (*dedtypes)[i]);\n                }\n            }\n            else\n                goto Lnomatch;\n        }\n        static if (LOGM)\n        {\n            printf(\" match = %d\\n\", m);\n        }\n        goto Lret;\n\n    Lnomatch:\n        static if (LOGM)\n        {\n            printf(\" no match\\n\");\n        }\n        m = MATCH.nomatch;\n\n    Lret:\n        paramscope.pop();\n        static if (LOGM)\n        {\n            printf(\"-TemplateDeclaration.matchWithInstance(this = %p, ti = %p) = %d\\n\", this, ti, m);\n        }\n        return m;\n    }\n\n    /********************************************\n     * Determine partial specialization order of 'this' vs td2.\n     * Returns:\n     *      match   this is at least as specialized as td2\n     *      0       td2 is more specialized than this\n     */\n    MATCH leastAsSpecialized(Scope* sc, TemplateDeclaration td2, Expressions* fargs)\n    {\n        enum LOG_LEASTAS = 0;\n        static if (LOG_LEASTAS)\n        {\n            printf(\"%s.leastAsSpecialized(%s)\\n\", toChars(), td2.toChars());\n        }\n\n        /* This works by taking the template parameters to this template\n         * declaration and feeding them to td2 as if it were a template\n         * instance.\n         * If it works, then this template is at least as specialized\n         * as td2.\n         */\n\n        // Set type arguments to dummy template instance to be types\n        // generated from the parameters to this template declaration\n        auto tiargs = new Objects();\n        tiargs.reserve(parameters.dim);\n        for (size_t i = 0; i < parameters.dim; i++)\n        {\n            TemplateParameter tp = (*parameters)[i];\n            if (tp.dependent)\n                break;\n            RootObject p = cast(RootObject)tp.dummyArg();\n            if (!p)\n                break;\n\n            tiargs.push(p);\n        }\n        scope TemplateInstance ti = new TemplateInstance(Loc.initial, ident, tiargs); // create dummy template instance\n\n        // Temporary Array to hold deduced types\n        Objects dedtypes = Objects(td2.parameters.dim);\n\n        // Attempt a type deduction\n        MATCH m = td2.matchWithInstance(sc, ti, &dedtypes, fargs, 1);\n        if (m > MATCH.nomatch)\n        {\n            /* A non-variadic template is more specialized than a\n             * variadic one.\n             */\n            TemplateTupleParameter tp = isVariadic();\n            if (tp && !tp.dependent && !td2.isVariadic())\n                goto L1;\n\n            static if (LOG_LEASTAS)\n            {\n                printf(\"  matches %d, so is least as specialized\\n\", m);\n            }\n            return m;\n        }\n    L1:\n        static if (LOG_LEASTAS)\n        {\n            printf(\"  doesn't match, so is not as specialized\\n\");\n        }\n        return MATCH.nomatch;\n    }\n\n    /*************************************************\n     * Match function arguments against a specific template function.\n     * Input:\n     *      ti\n     *      sc              instantiation scope\n     *      fd\n     *      tthis           'this' argument if !NULL\n     *      fargs           arguments to function\n     * Output:\n     *      fd              Partially instantiated function declaration\n     *      ti.tdtypes     Expression/Type deduced template arguments\n     * Returns:\n     *      match level\n     *          bit 0-3     Match template parameters by inferred template arguments\n     *          bit 4-7     Match template parameters by initial template arguments\n     */\n    extern (D) MATCH deduceFunctionTemplateMatch(TemplateInstance ti, Scope* sc, ref FuncDeclaration fd, Type tthis, Expressions* fargs)\n    {\n        size_t nfparams;\n        size_t nfargs;\n        size_t ntargs; // array size of tiargs\n        size_t fptupindex = IDX_NOTFOUND;\n        MATCH match = MATCH.exact;\n        MATCH matchTiargs = MATCH.exact;\n        Parameters* fparameters; // function parameter list\n        int fvarargs; // function varargs\n        uint wildmatch = 0;\n        size_t inferStart = 0;\n\n        Loc instLoc = ti.loc;\n        Objects* tiargs = ti.tiargs;\n        auto dedargs = new Objects();\n        Objects* dedtypes = &ti.tdtypes; // for T:T*, the dedargs is the T*, dedtypes is the T\n\n        version (none)\n        {\n            printf(\"\\nTemplateDeclaration.deduceFunctionTemplateMatch() %s\\n\", toChars());\n            for (size_t i = 0; i < (fargs ? fargs.dim : 0); i++)\n            {\n                Expression e = (*fargs)[i];\n                printf(\"\\tfarg[%d] is %s, type is %s\\n\", i, e.toChars(), e.type.toChars());\n            }\n            printf(\"fd = %s\\n\", fd.toChars());\n            printf(\"fd.type = %s\\n\", fd.type.toChars());\n            if (tthis)\n                printf(\"tthis = %s\\n\", tthis.toChars());\n        }\n\n        assert(_scope);\n\n        dedargs.setDim(parameters.dim);\n        dedargs.zero();\n\n        dedtypes.setDim(parameters.dim);\n        dedtypes.zero();\n\n        if (errors || fd.errors)\n            return MATCH.nomatch;\n\n        // Set up scope for parameters\n        auto paramsym = new ScopeDsymbol();\n        paramsym.parent = _scope.parent; // should use hasnestedArgs and enclosing?\n        Scope* paramscope = _scope.push(paramsym);\n        paramscope.tinst = ti;\n        paramscope.minst = sc.minst;\n        paramscope.callsc = sc;\n        paramscope.stc = 0;\n\n        TemplateTupleParameter tp = isVariadic();\n        Tuple declaredTuple = null;\n\n        version (none)\n        {\n            for (size_t i = 0; i < dedargs.dim; i++)\n            {\n                printf(\"\\tdedarg[%d] = \", i);\n                RootObject oarg = (*dedargs)[i];\n                if (oarg)\n                    printf(\"%s\", oarg.toChars());\n                printf(\"\\n\");\n            }\n        }\n\n        ntargs = 0;\n        if (tiargs)\n        {\n            // Set initial template arguments\n            ntargs = tiargs.dim;\n            size_t n = parameters.dim;\n            if (tp)\n                n--;\n            if (ntargs > n)\n            {\n                if (!tp)\n                    goto Lnomatch;\n\n                /* The extra initial template arguments\n                 * now form the tuple argument.\n                 */\n                auto t = new Tuple(ntargs - n);\n                assert(parameters.dim);\n                (*dedargs)[parameters.dim - 1] = t;\n\n                for (size_t i = 0; i < t.objects.dim; i++)\n                {\n                    t.objects[i] = (*tiargs)[n + i];\n                }\n                declareParameter(paramscope, tp, t);\n                declaredTuple = t;\n            }\n            else\n                n = ntargs;\n\n            memcpy(dedargs.tdata(), tiargs.tdata(), n * (*dedargs.tdata()).sizeof);\n\n            for (size_t i = 0; i < n; i++)\n            {\n                assert(i < parameters.dim);\n                Declaration sparam = null;\n                MATCH m = (*parameters)[i].matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, &sparam);\n                //printf(\"\\tdeduceType m = %d\\n\", m);\n                if (m <= MATCH.nomatch)\n                    goto Lnomatch;\n                if (m < matchTiargs)\n                    matchTiargs = m;\n\n                sparam.dsymbolSemantic(paramscope);\n                if (!paramscope.insert(sparam))\n                    goto Lnomatch;\n            }\n            if (n < parameters.dim && !declaredTuple)\n            {\n                inferStart = n;\n            }\n            else\n                inferStart = parameters.dim;\n            //printf(\"tiargs matchTiargs = %d\\n\", matchTiargs);\n        }\n        version (none)\n        {\n            for (size_t i = 0; i < dedargs.dim; i++)\n            {\n                printf(\"\\tdedarg[%d] = \", i);\n                RootObject oarg = (*dedargs)[i];\n                if (oarg)\n                    printf(\"%s\", oarg.toChars());\n                printf(\"\\n\");\n            }\n        }\n\n        fparameters = fd.getParameters(&fvarargs);\n        nfparams = Parameter.dim(fparameters); // number of function parameters\n        nfargs = fargs ? fargs.dim : 0; // number of function arguments\n\n        /* Check for match of function arguments with variadic template\n         * parameter, such as:\n         *\n         * void foo(T, A...)(T t, A a);\n         * void main() { foo(1,2,3); }\n         */\n        if (tp) // if variadic\n        {\n            // TemplateTupleParameter always makes most lesser matching.\n            matchTiargs = MATCH.convert;\n\n            if (nfparams == 0 && nfargs != 0) // if no function parameters\n            {\n                if (!declaredTuple)\n                {\n                    auto t = new Tuple();\n                    //printf(\"t = %p\\n\", t);\n                    (*dedargs)[parameters.dim - 1] = t;\n                    declareParameter(paramscope, tp, t);\n                    declaredTuple = t;\n                }\n            }\n            else\n            {\n                /* Figure out which of the function parameters matches\n                 * the tuple template parameter. Do this by matching\n                 * type identifiers.\n                 * Set the index of this function parameter to fptupindex.\n                 */\n                for (fptupindex = 0; fptupindex < nfparams; fptupindex++)\n                {\n                    Parameter fparam = (*fparameters)[fptupindex];\n                    if (fparam.type.ty != Tident)\n                        continue;\n                    TypeIdentifier tid = cast(TypeIdentifier)fparam.type;\n                    if (!tp.ident.equals(tid.ident) || tid.idents.dim)\n                        continue;\n\n                    if (fvarargs) // variadic function doesn't\n                        goto Lnomatch; // go with variadic template\n\n                    goto L1;\n                }\n                fptupindex = IDX_NOTFOUND;\n            L1:\n            }\n        }\n\n        if (toParent().isModule() || (_scope.stc & STC.static_))\n            tthis = null;\n        if (tthis)\n        {\n            bool hasttp = false;\n\n            // Match 'tthis' to any TemplateThisParameter's\n            for (size_t i = 0; i < parameters.dim; i++)\n            {\n                TemplateThisParameter ttp = (*parameters)[i].isTemplateThisParameter();\n                if (ttp)\n                {\n                    hasttp = true;\n\n                    Type t = new TypeIdentifier(Loc.initial, ttp.ident);\n                    MATCH m = deduceType(tthis, paramscope, t, parameters, dedtypes);\n                    if (m <= MATCH.nomatch)\n                        goto Lnomatch;\n                    if (m < match)\n                        match = m; // pick worst match\n                }\n            }\n\n            // Match attributes of tthis against attributes of fd\n            if (fd.type && !fd.isCtorDeclaration())\n            {\n                StorageClass stc = _scope.stc | fd.storage_class2;\n                // Propagate parent storage class, https://issues.dlang.org/show_bug.cgi?id=5504\n                Dsymbol p = parent;\n                while (p.isTemplateDeclaration() || p.isTemplateInstance())\n                    p = p.parent;\n                AggregateDeclaration ad = p.isAggregateDeclaration();\n                if (ad)\n                    stc |= ad.storage_class;\n\n                ubyte mod = fd.type.mod;\n                if (stc & STC.immutable_)\n                    mod = MODFlags.immutable_;\n                else\n                {\n                    if (stc & (STC.shared_ | STC.synchronized_))\n                        mod |= MODFlags.shared_;\n                    if (stc & STC.const_)\n                        mod |= MODFlags.const_;\n                    if (stc & STC.wild)\n                        mod |= MODFlags.wild;\n                }\n\n                ubyte thismod = tthis.mod;\n                if (hasttp)\n                    mod = MODmerge(thismod, mod);\n                MATCH m = MODmethodConv(thismod, mod);\n                if (m <= MATCH.nomatch)\n                    goto Lnomatch;\n                if (m < match)\n                    match = m;\n            }\n        }\n\n        // Loop through the function parameters\n        {\n            //printf(\"%s\\n\\tnfargs = %d, nfparams = %d, tuple_dim = %d\\n\", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple.objects.dim : 0);\n            //printf(\"\\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\\n\", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple.toChars() : NULL);\n            size_t argi = 0;\n            size_t nfargs2 = nfargs; // nfargs + supplied defaultArgs\n            for (size_t parami = 0; parami < nfparams; parami++)\n            {\n                Parameter fparam = Parameter.getNth(fparameters, parami);\n\n                // Apply function parameter storage classes to parameter types\n                Type prmtype = fparam.type.addStorageClass(fparam.storageClass);\n\n                Expression farg;\n\n                /* See function parameters which wound up\n                 * as part of a template tuple parameter.\n                 */\n                if (fptupindex != IDX_NOTFOUND && parami == fptupindex)\n                {\n                    assert(prmtype.ty == Tident);\n                    TypeIdentifier tid = cast(TypeIdentifier)prmtype;\n                    if (!declaredTuple)\n                    {\n                        /* The types of the function arguments\n                         * now form the tuple argument.\n                         */\n                        declaredTuple = new Tuple();\n                        (*dedargs)[parameters.dim - 1] = declaredTuple;\n\n                        /* Count function parameters with no defaults following a tuple parameter.\n                         * void foo(U, T...)(int y, T, U, double, int bar = 0) {}  // rem == 2 (U, double)\n                         */\n                        size_t rem = 0;\n                        for (size_t j = parami + 1; j < nfparams; j++)\n                        {\n                            Parameter p = Parameter.getNth(fparameters, j);\n                            if (p.defaultArg)\n                            {\n                               break;\n                            }\n                            if (!reliesOnTident(p.type, parameters, inferStart))\n                            {\n                                Type pt = p.type.syntaxCopy().typeSemantic(fd.loc, paramscope);\n                                rem += pt.ty == Ttuple ? (cast(TypeTuple)pt).arguments.dim : 1;\n                            }\n                            else\n                            {\n                                ++rem;\n                            }\n                        }\n\n                        if (nfargs2 - argi < rem)\n                            goto Lnomatch;\n                        declaredTuple.objects.setDim(nfargs2 - argi - rem);\n                        for (size_t i = 0; i < declaredTuple.objects.dim; i++)\n                        {\n                            farg = (*fargs)[argi + i];\n\n                            // Check invalid arguments to detect errors early.\n                            if (farg.op == TOK.error || farg.type.ty == Terror)\n                                goto Lnomatch;\n\n                            if (!(fparam.storageClass & STC.lazy_) && farg.type.ty == Tvoid)\n                                goto Lnomatch;\n\n                            Type tt;\n                            MATCH m;\n                            if (ubyte wm = deduceWildHelper(farg.type, &tt, tid))\n                            {\n                                wildmatch |= wm;\n                                m = MATCH.constant;\n                            }\n                            else\n                            {\n                                m = deduceTypeHelper(farg.type, &tt, tid);\n                            }\n                            if (m <= MATCH.nomatch)\n                                goto Lnomatch;\n                            if (m < match)\n                                match = m;\n\n                            /* Remove top const for dynamic array types and pointer types\n                             */\n                            if ((tt.ty == Tarray || tt.ty == Tpointer) && !tt.isMutable() && (!(fparam.storageClass & STC.ref_) || (fparam.storageClass & STC.auto_) && !farg.isLvalue()))\n                            {\n                                tt = tt.mutableOf();\n                            }\n                            declaredTuple.objects[i] = tt;\n                        }\n                        declareParameter(paramscope, tp, declaredTuple);\n                    }\n                    else\n                    {\n                        // https://issues.dlang.org/show_bug.cgi?id=6810\n                        // If declared tuple is not a type tuple,\n                        // it cannot be function parameter types.\n                        for (size_t i = 0; i < declaredTuple.objects.dim; i++)\n                        {\n                            if (!isType(declaredTuple.objects[i]))\n                                goto Lnomatch;\n                        }\n                    }\n                    assert(declaredTuple);\n                    argi += declaredTuple.objects.dim;\n                    continue;\n                }\n\n                // If parameter type doesn't depend on inferred template parameters,\n                // semantic it to get actual type.\n                if (!reliesOnTident(prmtype, parameters, inferStart))\n                {\n                    // should copy prmtype to avoid affecting semantic result\n                    prmtype = prmtype.syntaxCopy().typeSemantic(fd.loc, paramscope);\n\n                    if (prmtype.ty == Ttuple)\n                    {\n                        TypeTuple tt = cast(TypeTuple)prmtype;\n                        size_t tt_dim = tt.arguments.dim;\n                        for (size_t j = 0; j < tt_dim; j++, ++argi)\n                        {\n                            Parameter p = (*tt.arguments)[j];\n                            if (j == tt_dim - 1 && fvarargs == 2 && parami + 1 == nfparams && argi < nfargs)\n                            {\n                                prmtype = p.type;\n                                goto Lvarargs;\n                            }\n                            if (argi >= nfargs)\n                            {\n                                if (p.defaultArg)\n                                    continue;\n                                goto Lnomatch;\n                            }\n                            farg = (*fargs)[argi];\n                            if (!farg.implicitConvTo(p.type))\n                                goto Lnomatch;\n                        }\n                        continue;\n                    }\n                }\n\n                if (argi >= nfargs) // if not enough arguments\n                {\n                    if (!fparam.defaultArg)\n                        goto Lvarargs;\n\n                    /* https://issues.dlang.org/show_bug.cgi?id=2803\n                     * Before the starting of type deduction from the function\n                     * default arguments, set the already deduced parameters into paramscope.\n                     * It's necessary to avoid breaking existing acceptable code. Cases:\n                     *\n                     * 1. Already deduced template parameters can appear in fparam.defaultArg:\n                     *  auto foo(A, B)(A a, B b = A.stringof);\n                     *  foo(1);\n                     *  // at fparam == 'B b = A.string', A is equivalent with the deduced type 'int'\n                     *\n                     * 2. If prmtype depends on default-specified template parameter, the\n                     * default type should be preferred.\n                     *  auto foo(N = size_t, R)(R r, N start = 0)\n                     *  foo([1,2,3]);\n                     *  // at fparam `N start = 0`, N should be 'size_t' before\n                     *  // the deduction result from fparam.defaultArg.\n                     */\n                    if (argi == nfargs)\n                    {\n                        for (size_t i = 0; i < dedtypes.dim; i++)\n                        {\n                            Type at = isType((*dedtypes)[i]);\n                            if (at && at.ty == Tnone)\n                            {\n                                TypeDeduced xt = cast(TypeDeduced)at;\n                                (*dedtypes)[i] = xt.tded; // 'unbox'\n                            }\n                        }\n                        for (size_t i = ntargs; i < dedargs.dim; i++)\n                        {\n                            TemplateParameter tparam = (*parameters)[i];\n\n                            RootObject oarg = (*dedargs)[i];\n                            RootObject oded = (*dedtypes)[i];\n                            if (!oarg)\n                            {\n                                if (oded)\n                                {\n                                    if (tparam.specialization() || !tparam.isTemplateTypeParameter())\n                                    {\n                                        /* The specialization can work as long as afterwards\n                                         * the oded == oarg\n                                         */\n                                        (*dedargs)[i] = oded;\n                                        MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, null);\n                                        //printf(\"m2 = %d\\n\", m2);\n                                        if (m2 <= MATCH.nomatch)\n                                            goto Lnomatch;\n                                        if (m2 < matchTiargs)\n                                            matchTiargs = m2; // pick worst match\n                                        if (!(*dedtypes)[i].equals(oded))\n                                            error(\"specialization not allowed for deduced parameter `%s`\", tparam.ident.toChars());\n                                    }\n                                    else\n                                    {\n                                        if (MATCH.convert < matchTiargs)\n                                            matchTiargs = MATCH.convert;\n                                    }\n                                    (*dedargs)[i] = declareParameter(paramscope, tparam, oded);\n                                }\n                                else\n                                {\n                                    inuse++;\n                                    oded = tparam.defaultArg(instLoc, paramscope);\n                                    inuse--;\n                                    if (oded)\n                                        (*dedargs)[i] = declareParameter(paramscope, tparam, oded);\n                                }\n                            }\n                        }\n                    }\n                    nfargs2 = argi + 1;\n\n                    /* If prmtype does not depend on any template parameters:\n                     *\n                     *  auto foo(T)(T v, double x = 0);\n                     *  foo(\"str\");\n                     *  // at fparam == 'double x = 0'\n                     *\n                     * or, if all template parameters in the prmtype are already deduced:\n                     *\n                     *  auto foo(R)(R range, ElementType!R sum = 0);\n                     *  foo([1,2,3]);\n                     *  // at fparam == 'ElementType!R sum = 0'\n                     *\n                     * Deducing prmtype from fparam.defaultArg is not necessary.\n                     */\n                    if (prmtype.deco || prmtype.syntaxCopy().trySemantic(loc, paramscope))\n                    {\n                        ++argi;\n                        continue;\n                    }\n\n                    // Deduce prmtype from the defaultArg.\n                    farg = fparam.defaultArg.syntaxCopy();\n                    farg = farg.expressionSemantic(paramscope);\n                    farg = resolveProperties(paramscope, farg);\n                }\n                else\n                {\n                    farg = (*fargs)[argi];\n                }\n                {\n                    // Check invalid arguments to detect errors early.\n                    if (farg.op == TOK.error || farg.type.ty == Terror)\n                        goto Lnomatch;\n\n                    Type att = null;\n                Lretry:\n                    version (none)\n                    {\n                        printf(\"\\tfarg.type   = %s\\n\", farg.type.toChars());\n                        printf(\"\\tfparam.type = %s\\n\", prmtype.toChars());\n                    }\n                    Type argtype = farg.type;\n\n                    if (!(fparam.storageClass & STC.lazy_) && argtype.ty == Tvoid && farg.op != TOK.function_)\n                        goto Lnomatch;\n\n                    // https://issues.dlang.org/show_bug.cgi?id=12876\n                    // Optimize argument to allow CT-known length matching\n                    farg = farg.optimize(WANTvalue, (fparam.storageClass & (STC.ref_ | STC.out_)) != 0);\n                    //printf(\"farg = %s %s\\n\", farg.type.toChars(), farg.toChars());\n\n                    RootObject oarg = farg;\n                    if ((fparam.storageClass & STC.ref_) && (!(fparam.storageClass & STC.auto_) || farg.isLvalue()))\n                    {\n                        /* Allow expressions that have CT-known boundaries and type [] to match with [dim]\n                         */\n                        Type taai;\n                        if (argtype.ty == Tarray && (prmtype.ty == Tsarray || prmtype.ty == Taarray && (taai = (cast(TypeAArray)prmtype).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))\n                        {\n                            if (farg.op == TOK.string_)\n                            {\n                                StringExp se = cast(StringExp)farg;\n                                argtype = se.type.nextOf().sarrayOf(se.len);\n                            }\n                            else if (farg.op == TOK.arrayLiteral)\n                            {\n                                ArrayLiteralExp ae = cast(ArrayLiteralExp)farg;\n                                argtype = ae.type.nextOf().sarrayOf(ae.elements.dim);\n                            }\n                            else if (farg.op == TOK.slice)\n                            {\n                                SliceExp se = cast(SliceExp)farg;\n                                if (Type tsa = toStaticArrayType(se))\n                                    argtype = tsa;\n                            }\n                        }\n\n                        oarg = argtype;\n                    }\n                    else if ((fparam.storageClass & STC.out_) == 0 && (argtype.ty == Tarray || argtype.ty == Tpointer) && templateParameterLookup(prmtype, parameters) != IDX_NOTFOUND && (cast(TypeIdentifier)prmtype).idents.dim == 0)\n                    {\n                        /* The farg passing to the prmtype always make a copy. Therefore,\n                         * we can shrink the set of the deduced type arguments for prmtype\n                         * by adjusting top-qualifier of the argtype.\n                         *\n                         *  prmtype         argtype     ta\n                         *  T            <- const(E)[]  const(E)[]\n                         *  T            <- const(E[])  const(E)[]\n                         *  qualifier(T) <- const(E)[]  const(E[])\n                         *  qualifier(T) <- const(E[])  const(E[])\n                         */\n                        Type ta = argtype.castMod(prmtype.mod ? argtype.nextOf().mod : 0);\n                        if (ta != argtype)\n                        {\n                            Expression ea = farg.copy();\n                            ea.type = ta;\n                            oarg = ea;\n                        }\n                    }\n\n                    if (fvarargs == 2 && parami + 1 == nfparams && argi + 1 < nfargs)\n                        goto Lvarargs;\n\n                    uint wm = 0;\n                    MATCH m = deduceType(oarg, paramscope, prmtype, parameters, dedtypes, &wm, inferStart);\n                    //printf(\"\\tL%d deduceType m = %d, wm = x%x, wildmatch = x%x\\n\", __LINE__, m, wm, wildmatch);\n                    wildmatch |= wm;\n\n                    /* If no match, see if the argument can be matched by using\n                     * implicit conversions.\n                     */\n                    if (m == MATCH.nomatch && prmtype.deco)\n                        m = farg.implicitConvTo(prmtype);\n\n                    if (m == MATCH.nomatch)\n                    {\n                        AggregateDeclaration ad = isAggregate(farg.type);\n                        if (ad && ad.aliasthis && argtype != att)\n                        {\n                            if (!att && argtype.checkAliasThisRec())   // https://issues.dlang.org/show_bug.cgi?id=12537\n                                att = argtype;\n                            /* If a semantic error occurs while doing alias this,\n                             * eg purity(https://issues.dlang.org/show_bug.cgi?id=7295),\n                             * just regard it as not a match.\n                             */\n                            if (auto e = resolveAliasThis(sc, farg, true))\n                            {\n                                farg = e;\n                                goto Lretry;\n                            }\n                        }\n                    }\n\n                    if (m > MATCH.nomatch && (fparam.storageClass & (STC.ref_ | STC.auto_)) == STC.ref_)\n                    {\n                        if (!farg.isLvalue())\n                        {\n                            if ((farg.op == TOK.string_ || farg.op == TOK.slice) && (prmtype.ty == Tsarray || prmtype.ty == Taarray))\n                            {\n                                // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]\n                            }\n                            else\n                                goto Lnomatch;\n                        }\n                    }\n                    if (m > MATCH.nomatch && (fparam.storageClass & STC.out_))\n                    {\n                        if (!farg.isLvalue())\n                            goto Lnomatch;\n                        if (!farg.type.isMutable()) // https://issues.dlang.org/show_bug.cgi?id=11916\n                            goto Lnomatch;\n                    }\n                    if (m == MATCH.nomatch && (fparam.storageClass & STC.lazy_) && prmtype.ty == Tvoid && farg.type.ty != Tvoid)\n                        m = MATCH.convert;\n                    if (m != MATCH.nomatch)\n                    {\n                        if (m < match)\n                            match = m; // pick worst match\n                        argi++;\n                        continue;\n                    }\n                }\n\n            Lvarargs:\n                /* The following code for variadic arguments closely\n                 * matches TypeFunction.callMatch()\n                 */\n                if (!(fvarargs == 2 && parami + 1 == nfparams))\n                    goto Lnomatch;\n\n                /* Check for match with function parameter T...\n                 */\n                Type tb = prmtype.toBasetype();\n                switch (tb.ty)\n                {\n                    // 6764 fix - TypeAArray may be TypeSArray have not yet run semantic().\n                case Tsarray:\n                case Taarray:\n                    {\n                        // Perhaps we can do better with this, see TypeFunction.callMatch()\n                        if (tb.ty == Tsarray)\n                        {\n                            TypeSArray tsa = cast(TypeSArray)tb;\n                            dinteger_t sz = tsa.dim.toInteger();\n                            if (sz != nfargs - argi)\n                                goto Lnomatch;\n                        }\n                        else if (tb.ty == Taarray)\n                        {\n                            TypeAArray taa = cast(TypeAArray)tb;\n                            Expression dim = new IntegerExp(instLoc, nfargs - argi, Type.tsize_t);\n\n                            size_t i = templateParameterLookup(taa.index, parameters);\n                            if (i == IDX_NOTFOUND)\n                            {\n                                Expression e;\n                                Type t;\n                                Dsymbol s;\n                                Scope *sco;\n\n                                uint errors = global.startGagging();\n                                /* ref: https://issues.dlang.org/show_bug.cgi?id=11118\n                                 * The parameter isn't part of the template\n                                 * ones, let's try to find it in the\n                                 * instantiation scope 'sc' and the one\n                                 * belonging to the template itself. */\n                                sco = sc;\n                                taa.index.resolve(instLoc, sco, &e, &t, &s);\n                                if (!e)\n                                {\n                                    sco = paramscope;\n                                    taa.index.resolve(instLoc, sco, &e, &t, &s);\n                                }\n                                global.endGagging(errors);\n\n                                if (!e)\n                                {\n                                    goto Lnomatch;\n                                }\n\n                                e = e.ctfeInterpret();\n                                e = e.implicitCastTo(sco, Type.tsize_t);\n                                e = e.optimize(WANTvalue);\n                                if (!dim.equals(e))\n                                    goto Lnomatch;\n                            }\n                            else\n                            {\n                                // This code matches code in TypeInstance.deduceType()\n                                TemplateParameter tprm = (*parameters)[i];\n                                TemplateValueParameter tvp = tprm.isTemplateValueParameter();\n                                if (!tvp)\n                                    goto Lnomatch;\n                                Expression e = cast(Expression)(*dedtypes)[i];\n                                if (e)\n                                {\n                                    if (!dim.equals(e))\n                                        goto Lnomatch;\n                                }\n                                else\n                                {\n                                    Type vt = tvp.valType.typeSemantic(Loc.initial, sc);\n                                    MATCH m = dim.implicitConvTo(vt);\n                                    if (m <= MATCH.nomatch)\n                                        goto Lnomatch;\n                                    (*dedtypes)[i] = dim;\n                                }\n                            }\n                        }\n                        goto case Tarray;\n                    }\n                case Tarray:\n                    {\n                        TypeArray ta = cast(TypeArray)tb;\n                        Type tret = fparam.isLazyArray();\n                        for (; argi < nfargs; argi++)\n                        {\n                            Expression arg = (*fargs)[argi];\n                            assert(arg);\n\n                            MATCH m;\n                            /* If lazy array of delegates,\n                             * convert arg(s) to delegate(s)\n                             */\n                            if (tret)\n                            {\n                                if (ta.next.equals(arg.type))\n                                {\n                                    m = MATCH.exact;\n                                }\n                                else\n                                {\n                                    m = arg.implicitConvTo(tret);\n                                    if (m == MATCH.nomatch)\n                                    {\n                                        if (tret.toBasetype().ty == Tvoid)\n                                            m = MATCH.convert;\n                                    }\n                                }\n                            }\n                            else\n                            {\n                                uint wm = 0;\n                                m = deduceType(arg, paramscope, ta.next, parameters, dedtypes, &wm, inferStart);\n                                wildmatch |= wm;\n                            }\n                            if (m == MATCH.nomatch)\n                                goto Lnomatch;\n                            if (m < match)\n                                match = m;\n                        }\n                        goto Lmatch;\n                    }\n                case Tclass:\n                case Tident:\n                    goto Lmatch;\n\n                default:\n                    goto Lnomatch;\n                }\n                assert(0);\n            }\n            //printf(\". argi = %d, nfargs = %d, nfargs2 = %d\\n\", argi, nfargs, nfargs2);\n            if (argi != nfargs2 && !fvarargs)\n                goto Lnomatch;\n        }\n\n    Lmatch:\n        for (size_t i = 0; i < dedtypes.dim; i++)\n        {\n            Type at = isType((*dedtypes)[i]);\n            if (at)\n            {\n                if (at.ty == Tnone)\n                {\n                    TypeDeduced xt = cast(TypeDeduced)at;\n                    at = xt.tded; // 'unbox'\n                }\n                (*dedtypes)[i] = at.merge2();\n            }\n        }\n        for (size_t i = ntargs; i < dedargs.dim; i++)\n        {\n            TemplateParameter tparam = (*parameters)[i];\n            //printf(\"tparam[%d] = %s\\n\", i, tparam.ident.toChars());\n\n            /* For T:T*, the dedargs is the T*, dedtypes is the T\n             * But for function templates, we really need them to match\n             */\n            RootObject oarg = (*dedargs)[i];\n            RootObject oded = (*dedtypes)[i];\n            //printf(\"1dedargs[%d] = %p, dedtypes[%d] = %p\\n\", i, oarg, i, oded);\n            //if (oarg) printf(\"oarg: %s\\n\", oarg.toChars());\n            //if (oded) printf(\"oded: %s\\n\", oded.toChars());\n            if (!oarg)\n            {\n                if (oded)\n                {\n                    if (tparam.specialization() || !tparam.isTemplateTypeParameter())\n                    {\n                        /* The specialization can work as long as afterwards\n                         * the oded == oarg\n                         */\n                        (*dedargs)[i] = oded;\n                        MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, null);\n                        //printf(\"m2 = %d\\n\", m2);\n                        if (m2 <= MATCH.nomatch)\n                            goto Lnomatch;\n                        if (m2 < matchTiargs)\n                            matchTiargs = m2; // pick worst match\n                        if (!(*dedtypes)[i].equals(oded))\n                            error(\"specialization not allowed for deduced parameter `%s`\", tparam.ident.toChars());\n                    }\n                    else\n                    {\n                        // Discussion: https://issues.dlang.org/show_bug.cgi?id=16484\n                        if (MATCH.convert < matchTiargs)\n                            matchTiargs = MATCH.convert;\n                    }\n                }\n                else\n                {\n                    inuse++;\n                    oded = tparam.defaultArg(instLoc, paramscope);\n                    inuse--;\n                    if (!oded)\n                    {\n                        // if tuple parameter and\n                        // tuple parameter was not in function parameter list and\n                        // we're one or more arguments short (i.e. no tuple argument)\n                        if (tparam == tp &&\n                            fptupindex == IDX_NOTFOUND &&\n                            ntargs <= dedargs.dim - 1)\n                        {\n                            // make tuple argument an empty tuple\n                            oded = cast(RootObject)new Tuple();\n                        }\n                        else\n                            goto Lnomatch;\n                    }\n                    if (isError(oded))\n                        goto Lerror;\n                    ntargs++;\n\n                    /* At the template parameter T, the picked default template argument\n                     * X!int should be matched to T in order to deduce dependent\n                     * template parameter A.\n                     *  auto foo(T : X!A = X!int, A...)() { ... }\n                     *  foo();  // T <-- X!int, A <-- (int)\n                     */\n                    if (tparam.specialization())\n                    {\n                        (*dedargs)[i] = oded;\n                        MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, null);\n                        //printf(\"m2 = %d\\n\", m2);\n                        if (m2 <= MATCH.nomatch)\n                            goto Lnomatch;\n                        if (m2 < matchTiargs)\n                            matchTiargs = m2; // pick worst match\n                        if (!(*dedtypes)[i].equals(oded))\n                            error(\"specialization not allowed for deduced parameter `%s`\", tparam.ident.toChars());\n                    }\n                }\n                oded = declareParameter(paramscope, tparam, oded);\n                (*dedargs)[i] = oded;\n            }\n        }\n\n        /* https://issues.dlang.org/show_bug.cgi?id=7469\n         * As same as the code for 7469 in findBestMatch,\n         * expand a Tuple in dedargs to normalize template arguments.\n         */\n        if (auto d = dedargs.dim)\n        {\n            if (auto va = isTuple((*dedargs)[d - 1]))\n            {\n                dedargs.setDim(d - 1);\n                dedargs.insert(d - 1, &va.objects);\n            }\n        }\n        ti.tiargs = dedargs; // update to the normalized template arguments.\n\n        // Partially instantiate function for constraint and fd.leastAsSpecialized()\n        {\n            assert(paramsym);\n            Scope* sc2 = _scope;\n            sc2 = sc2.push(paramsym);\n            sc2 = sc2.push(ti);\n            sc2.parent = ti;\n            sc2.tinst = ti;\n            sc2.minst = sc.minst;\n\n            fd = doHeaderInstantiation(ti, sc2, fd, tthis, fargs);\n\n            sc2 = sc2.pop();\n            sc2 = sc2.pop();\n\n            if (!fd)\n                goto Lnomatch;\n        }\n\n        if (constraint)\n        {\n            if (!evaluateConstraint(ti, sc, paramscope, dedargs, fd))\n                goto Lnomatch;\n        }\n\n        version (none)\n        {\n            for (size_t i = 0; i < dedargs.dim; i++)\n            {\n                RootObject o = (*dedargs)[i];\n                printf(\"\\tdedargs[%d] = %d, %s\\n\", i, o.dyncast(), o.toChars());\n            }\n        }\n\n        paramscope.pop();\n        //printf(\"\\tmatch %d\\n\", match);\n        return cast(MATCH)(match | (matchTiargs << 4));\n\n    Lnomatch:\n        paramscope.pop();\n        //printf(\"\\tnomatch\\n\");\n        return MATCH.nomatch;\n\n    Lerror:\n        // todo: for the future improvement\n        paramscope.pop();\n        //printf(\"\\terror\\n\");\n        return MATCH.nomatch;\n    }\n\n    /**************************************************\n     * Declare template parameter tp with value o, and install it in the scope sc.\n     */\n    RootObject declareParameter(Scope* sc, TemplateParameter tp, RootObject o)\n    {\n        //printf(\"TemplateDeclaration.declareParameter('%s', o = %p)\\n\", tp.ident.toChars(), o);\n        Type ta = isType(o);\n        Expression ea = isExpression(o);\n        Dsymbol sa = isDsymbol(o);\n        Tuple va = isTuple(o);\n\n        Declaration d;\n        VarDeclaration v = null;\n\n        if (ea && ea.op == TOK.type)\n            ta = ea.type;\n        else if (ea && ea.op == TOK.scope_)\n            sa = (cast(ScopeExp)ea).sds;\n        else if (ea && (ea.op == TOK.this_ || ea.op == TOK.super_))\n            sa = (cast(ThisExp)ea).var;\n        else if (ea && ea.op == TOK.function_)\n        {\n            if ((cast(FuncExp)ea).td)\n                sa = (cast(FuncExp)ea).td;\n            else\n                sa = (cast(FuncExp)ea).fd;\n        }\n\n        if (ta)\n        {\n            //printf(\"type %s\\n\", ta.toChars());\n            d = new AliasDeclaration(Loc.initial, tp.ident, ta);\n        }\n        else if (sa)\n        {\n            //printf(\"Alias %s %s;\\n\", sa.ident.toChars(), tp.ident.toChars());\n            d = new AliasDeclaration(Loc.initial, tp.ident, sa);\n        }\n        else if (ea)\n        {\n            // tdtypes.data[i] always matches ea here\n            Initializer _init = new ExpInitializer(loc, ea);\n            TemplateValueParameter tvp = tp.isTemplateValueParameter();\n            Type t = tvp ? tvp.valType : null;\n            v = new VarDeclaration(loc, t, tp.ident, _init);\n            v.storage_class = STC.manifest | STC.templateparameter;\n            d = v;\n        }\n        else if (va)\n        {\n            //printf(\"\\ttuple\\n\");\n            d = new TupleDeclaration(loc, tp.ident, &va.objects);\n        }\n        else\n        {\n            assert(0);\n        }\n        d.storage_class |= STC.templateparameter;\n\n        if (ta)\n        {\n            Type t = ta;\n            // consistent with Type.checkDeprecated()\n            while (t.ty != Tenum)\n            {\n                if (!t.nextOf())\n                    break;\n                t = (cast(TypeNext)t).next;\n            }\n            if (Dsymbol s = t.toDsymbol(sc))\n            {\n                if (s.isDeprecated())\n                    d.storage_class |= STC.deprecated_;\n            }\n        }\n        else if (sa)\n        {\n            if (sa.isDeprecated())\n                d.storage_class |= STC.deprecated_;\n        }\n\n        if (!sc.insert(d))\n            error(\"declaration `%s` is already defined\", tp.ident.toChars());\n        d.dsymbolSemantic(sc);\n        /* So the caller's o gets updated with the result of semantic() being run on o\n         */\n        if (v)\n            o = v._init.initializerToExpression();\n        return o;\n    }\n\n    /*************************************************\n     * Limited function template instantiation for using fd.leastAsSpecialized()\n     */\n    extern (D) FuncDeclaration doHeaderInstantiation(TemplateInstance ti, Scope* sc2, FuncDeclaration fd, Type tthis, Expressions* fargs)\n    {\n        assert(fd);\n        version (none)\n        {\n            printf(\"doHeaderInstantiation this = %s\\n\", toChars());\n        }\n\n        // function body and contracts are not need\n        if (fd.isCtorDeclaration())\n            fd = new CtorDeclaration(fd.loc, fd.endloc, fd.storage_class, fd.type.syntaxCopy());\n        else\n            fd = new FuncDeclaration(fd.loc, fd.endloc, fd.ident, fd.storage_class, fd.type.syntaxCopy());\n        fd.parent = ti;\n\n        assert(fd.type.ty == Tfunction);\n        TypeFunction tf = cast(TypeFunction)fd.type;\n        tf.fargs = fargs;\n\n        if (tthis)\n        {\n            // Match 'tthis' to any TemplateThisParameter's\n            bool hasttp = false;\n            for (size_t i = 0; i < parameters.dim; i++)\n            {\n                TemplateParameter tp = (*parameters)[i];\n                TemplateThisParameter ttp = tp.isTemplateThisParameter();\n                if (ttp)\n                    hasttp = true;\n            }\n            if (hasttp)\n            {\n                tf = cast(TypeFunction)tf.addSTC(ModToStc(tthis.mod));\n                assert(!tf.deco);\n            }\n        }\n\n        Scope* scx = sc2.push();\n\n        // Shouldn't run semantic on default arguments and return type.\n        for (size_t i = 0; i < tf.parameters.dim; i++)\n            (*tf.parameters)[i].defaultArg = null;\n        if (fd.isCtorDeclaration())\n        {\n            // For constructors, emitting return type is necessary for\n            // isReturnIsolated() in functionResolve.\n            scx.flags |= SCOPE.ctor;\n\n            Dsymbol parent = toParent2();\n            Type tret;\n            AggregateDeclaration ad = parent.isAggregateDeclaration();\n            if (!ad || parent.isUnionDeclaration())\n            {\n                tret = Type.tvoid;\n            }\n            else\n            {\n                tret = ad.handleType();\n                assert(tret);\n                tret = tret.addStorageClass(fd.storage_class | scx.stc);\n                tret = tret.addMod(tf.mod);\n            }\n            tf.next = tret;\n            if (ad && ad.isStructDeclaration())\n                tf.isref = 1;\n            //printf(\"tf = %s\\n\", tf.toChars());\n        }\n        else\n            tf.next = null;\n        fd.type = tf;\n        fd.type = fd.type.addSTC(scx.stc);\n        fd.type = fd.type.typeSemantic(fd.loc, scx);\n        scx = scx.pop();\n\n        if (fd.type.ty != Tfunction)\n            return null;\n\n        fd.originalType = fd.type; // for mangling\n        //printf(\"\\t[%s] fd.type = %s, mod = %x, \", loc.toChars(), fd.type.toChars(), fd.type.mod);\n        //printf(\"fd.needThis() = %d\\n\", fd.needThis());\n\n        return fd;\n    }\n\n    debug (FindExistingInstance)\n    {\n        __gshared uint nFound, nNotFound, nAdded, nRemoved;\n\n        shared static ~this()\n        {\n            printf(\"debug (FindExistingInstance) nFound %u, nNotFound: %u, nAdded: %u, nRemoved: %u\\n\",\n                   nFound, nNotFound, nAdded, nRemoved);\n        }\n    }\n\n    /****************************************************\n     * Given a new instance tithis of this TemplateDeclaration,\n     * see if there already exists an instance.\n     * If so, return that existing instance.\n     */\n    extern (D) TemplateInstance findExistingInstance(TemplateInstance tithis, Expressions* fargs)\n    {\n        //printf(\"findExistingInstance(%p)\\n\", tithis);\n        tithis.fargs = fargs;\n        auto tibox = TemplateInstanceBox(tithis);\n        auto p = tibox in instances;\n        debug (FindExistingInstance) ++(p ? nFound : nNotFound);\n        //if (p) printf(\"\\tfound %p\\n\", *p); else printf(\"\\tnot found\\n\");\n        return p ? *p : null;\n    }\n\n    /********************************************\n     * Add instance ti to TemplateDeclaration's table of instances.\n     * Return a handle we can use to later remove it if it fails instantiation.\n     */\n    extern (D) TemplateInstance addInstance(TemplateInstance ti)\n    {\n        //printf(\"addInstance() %p %p\\n\", instances, ti);\n        auto tibox = TemplateInstanceBox(ti);\n        instances[tibox] = ti;\n        debug (FindExistingInstance) ++nAdded;\n        return ti;\n    }\n\n    /*******************************************\n     * Remove TemplateInstance from table of instances.\n     * Input:\n     *      handle returned by addInstance()\n     */\n    extern (D) void removeInstance(TemplateInstance ti)\n    {\n        //printf(\"removeInstance()\\n\");\n        auto tibox = TemplateInstanceBox(ti);\n        debug (FindExistingInstance) ++nRemoved;\n        instances.remove(tibox);\n    }\n\n    override inout(TemplateDeclaration) isTemplateDeclaration() inout\n    {\n        return this;\n    }\n\n    /**\n     * Check if the last template parameter is a tuple one,\n     * and returns it if so, else returns `null`.\n     *\n     * Returns:\n     *   The last template parameter if it's a `TemplateTupleParameter`\n     */\n    TemplateTupleParameter isVariadic()\n    {\n        size_t dim = parameters.dim;\n        if (dim == 0)\n            return null;\n        return (*parameters)[dim - 1].isTemplateTupleParameter();\n    }\n\n    /***********************************\n     * We can overload templates.\n     */\n    override bool isOverloadable()\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\nextern (C++) final class TypeDeduced : Type\n{\n    Type tded;\n    Expressions argexps; // corresponding expressions\n    Types tparams; // tparams[i].mod\n\n    extern (D) this(Type tt, Expression e, Type tparam)\n    {\n        super(Tnone);\n        tded = tt;\n        argexps.push(e);\n        tparams.push(tparam);\n    }\n\n    void update(Expression e, Type tparam)\n    {\n        argexps.push(e);\n        tparams.push(tparam);\n    }\n\n    void update(Type tt, Expression e, Type tparam)\n    {\n        tded = tt;\n        argexps.push(e);\n        tparams.push(tparam);\n    }\n\n    MATCH matchAll(Type tt)\n    {\n        MATCH match = MATCH.exact;\n        for (size_t j = 0; j < argexps.dim; j++)\n        {\n            Expression e = argexps[j];\n            assert(e);\n            if (e == emptyArrayElement)\n                continue;\n\n            Type t = tt.addMod(tparams[j].mod).substWildTo(MODFlags.const_);\n\n            MATCH m = e.implicitConvTo(t);\n            if (match > m)\n                match = m;\n            if (match <= MATCH.nomatch)\n                break;\n        }\n        return match;\n    }\n}\n\n\n/*************************************************\n * Given function arguments, figure out which template function\n * to expand, and return matching result.\n * Params:\n *      m           = matching result\n *      dstart      = the root of overloaded function templates\n *      loc         = instantiation location\n *      sc          = instantiation scope\n *      tiargs      = initial list of template arguments\n *      tthis       = if !NULL, the 'this' pointer argument\n *      fargs       = arguments to function\n *      pMessage    = address to store error message, or null\n */\nvoid functionResolve(Match* m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiargs,\n    Type tthis, Expressions* fargs, const(char)** pMessage = null)\n{\n    version (none)\n    {\n        printf(\"functionResolve() dstart = %s\\n\", dstart.toChars());\n        printf(\"    tiargs:\\n\");\n        if (tiargs)\n        {\n            for (size_t i = 0; i < tiargs.dim; i++)\n            {\n                RootObject arg = (*tiargs)[i];\n                printf(\"\\t%s\\n\", arg.toChars());\n            }\n        }\n        printf(\"    fargs:\\n\");\n        for (size_t i = 0; i < (fargs ? fargs.dim : 0); i++)\n        {\n            Expression arg = (*fargs)[i];\n            printf(\"\\t%s %s\\n\", arg.type.toChars(), arg.toChars());\n            //printf(\"\\tty = %d\\n\", arg.type.ty);\n        }\n        //printf(\"stc = %llx\\n\", dstart.scope.stc);\n        //printf(\"match:t/f = %d/%d\\n\", ta_last, m.last);\n    }\n\n    // results\n    int property = 0;   // 0: uninitialized\n                        // 1: seen @property\n                        // 2: not @property\n    size_t ov_index = 0;\n    TemplateDeclaration td_best;\n    TemplateInstance ti_best;\n    MATCH ta_last = m.last != MATCH.nomatch ? MATCH.exact : MATCH.nomatch;\n    Type tthis_best;\n\n    int applyFunction(FuncDeclaration fd)\n    {\n        // skip duplicates\n        if (fd == m.lastf)\n            return 0;\n        // explicitly specified tiargs never match to non template function\n        if (tiargs && tiargs.dim > 0)\n            return 0;\n\n        if (fd.semanticRun < PASS.semanticdone)\n        {\n            Ungag ungag = fd.ungagSpeculative();\n            fd.dsymbolSemantic(null);\n        }\n        if (fd.semanticRun == PASS.init)\n        {\n            .error(loc, \"forward reference to template `%s`\", fd.toChars());\n            return 1;\n        }\n        //printf(\"fd = %s %s, fargs = %s\\n\", fd.toChars(), fd.type.toChars(), fargs.toChars());\n        m.anyf = fd;\n        auto tf = cast(TypeFunction)fd.type;\n\n        int prop = tf.isproperty ? 1 : 2;\n        if (property == 0)\n            property = prop;\n        else if (property != prop)\n            error(fd.loc, \"cannot overload both property and non-property functions\");\n\n        /* For constructors, qualifier check will be opposite direction.\n         * Qualified constructor always makes qualified object, then will be checked\n         * that it is implicitly convertible to tthis.\n         */\n        Type tthis_fd = fd.needThis() ? tthis : null;\n        bool isCtorCall = tthis_fd && fd.isCtorDeclaration();\n        if (isCtorCall)\n        {\n            //printf(\"%s tf.mod = x%x tthis_fd.mod = x%x %d\\n\", tf.toChars(),\n            //        tf.mod, tthis_fd.mod, fd.isReturnIsolated());\n            if (MODimplicitConv(tf.mod, tthis_fd.mod) ||\n                tf.isWild() && tf.isShared() == tthis_fd.isShared() ||\n                fd.isReturnIsolated())\n            {\n                /* && tf.isShared() == tthis_fd.isShared()*/\n                // Uniquely constructed object can ignore shared qualifier.\n                // TODO: Is this appropriate?\n                tthis_fd = null;\n            }\n            else\n                return 0;   // MATCH.nomatch\n        }\n        /* Fix Issue 17970:\n           If a struct is declared as shared the dtor is automatically\n           considered to be shared, but when the struct is instantiated\n           the instance is no longer considered to be shared when the\n           function call matching is done. The fix makes it so that if a\n           struct declaration is shared, when the destructor is called,\n           the instantiated struct is also considered shared.\n        */\n        if (auto dt = fd.isDtorDeclaration())\n        {\n            auto dtmod = dt.type.toTypeFunction();\n            auto shared_dtor = dtmod.mod & MODFlags.shared_;\n            auto shared_this = tthis_fd !is null ?\n                tthis_fd.mod & MODFlags.shared_ : 0;\n            if (shared_dtor && !shared_this)\n                tthis_fd = dtmod;\n            else if (shared_this && !shared_dtor && tthis_fd !is null)\n                tf.mod = tthis_fd.mod;\n        }\n        MATCH mfa = tf.callMatch(tthis_fd, fargs, 0, pMessage);\n        //printf(\"test1: mfa = %d\\n\", mfa);\n        if (mfa > MATCH.nomatch)\n        {\n            if (mfa > m.last) goto LfIsBetter;\n            if (mfa < m.last) goto LlastIsBetter;\n\n            /* See if one of the matches overrides the other.\n             */\n            assert(m.lastf);\n            if (m.lastf.overrides(fd)) goto LlastIsBetter;\n            if (fd.overrides(m.lastf)) goto LfIsBetter;\n\n            /* Try to disambiguate using template-style partial ordering rules.\n             * In essence, if f() and g() are ambiguous, if f() can call g(),\n             * but g() cannot call f(), then pick f().\n             * This is because f() is \"more specialized.\"\n             */\n            {\n                MATCH c1 = fd.leastAsSpecialized(m.lastf);\n                MATCH c2 = m.lastf.leastAsSpecialized(fd);\n                //printf(\"c1 = %d, c2 = %d\\n\", c1, c2);\n                if (c1 > c2) goto LfIsBetter;\n                if (c1 < c2) goto LlastIsBetter;\n            }\n\n            /* The 'overrides' check above does covariant checking only\n             * for virtual member functions. It should do it for all functions,\n             * but in order to not risk breaking code we put it after\n             * the 'leastAsSpecialized' check.\n             * In the future try moving it before.\n             * I.e. a not-the-same-but-covariant match is preferred,\n             * as it is more restrictive.\n             */\n            if (!m.lastf.type.equals(fd.type))\n            {\n                //printf(\"cov: %d %d\\n\", m.lastf.type.covariant(fd.type), fd.type.covariant(m.lastf.type));\n                if (m.lastf.type.covariant(fd.type) == 1) goto LlastIsBetter;\n                if (fd.type.covariant(m.lastf.type) == 1) goto LfIsBetter;\n            }\n\n            /* If the two functions are the same function, like:\n             *    int foo(int);\n             *    int foo(int x) { ... }\n             * then pick the one with the body.\n             */\n            if (tf.equals(m.lastf.type) &&\n                fd.storage_class == m.lastf.storage_class &&\n                fd.parent == m.lastf.parent &&\n                fd.protection == m.lastf.protection &&\n                fd.linkage == m.lastf.linkage)\n            {\n                if (fd.fbody && !m.lastf.fbody) goto LfIsBetter;\n                if (!fd.fbody && m.lastf.fbody) goto LlastIsBetter;\n            }\n\n            // https://issues.dlang.org/show_bug.cgi?id=14450\n            // Prefer exact qualified constructor for the creating object type\n            if (isCtorCall && tf.mod != m.lastf.type.mod)\n            {\n                if (tthis.mod == tf.mod) goto LfIsBetter;\n                if (tthis.mod == m.lastf.type.mod) goto LlastIsBetter;\n            }\n\n            m.nextf = fd;\n            m.count++;\n            return 0;\n\n        LlastIsBetter:\n            return 0;\n\n        LfIsBetter:\n            td_best = null;\n            ti_best = null;\n            ta_last = MATCH.exact;\n            m.last = mfa;\n            m.lastf = fd;\n            tthis_best = tthis_fd;\n            ov_index = 0;\n            m.count = 1;\n            return 0;\n        }\n        return 0;\n    }\n\n    int applyTemplate(TemplateDeclaration td)\n    {\n        //printf(\"applyTemplate()\\n\");\n        if (td.inuse)\n        {\n            td.error(loc, \"recursive template expansion\");\n            return 1;\n        }\n        if (td == td_best)   // skip duplicates\n            return 0;\n\n        if (!sc)\n            sc = td._scope; // workaround for Type.aliasthisOf\n\n        if (td.semanticRun == PASS.init && td._scope)\n        {\n            // Try to fix forward reference. Ungag errors while doing so.\n            Ungag ungag = td.ungagSpeculative();\n            td.dsymbolSemantic(td._scope);\n        }\n        if (td.semanticRun == PASS.init)\n        {\n            .error(loc, \"forward reference to template `%s`\", td.toChars());\n        Lerror:\n            m.lastf = null;\n            m.count = 0;\n            m.last = MATCH.nomatch;\n            return 1;\n        }\n        //printf(\"td = %s\\n\", td.toChars());\n\n        auto f = td.onemember ? td.onemember.isFuncDeclaration() : null;\n        if (!f)\n        {\n            if (!tiargs)\n                tiargs = new Objects();\n            auto ti = new TemplateInstance(loc, td, tiargs);\n            Objects dedtypes = Objects(td.parameters.dim);\n            assert(td.semanticRun != PASS.init);\n            MATCH mta = td.matchWithInstance(sc, ti, &dedtypes, fargs, 0);\n            //printf(\"matchWithInstance = %d\\n\", mta);\n            if (mta <= MATCH.nomatch || mta < ta_last)   // no match or less match\n                return 0;\n\n            ti.templateInstanceSemantic(sc, fargs);\n            if (!ti.inst)               // if template failed to expand\n                return 0;\n\n            Dsymbol s = ti.inst.toAlias();\n            FuncDeclaration fd;\n            if (auto tdx = s.isTemplateDeclaration())\n            {\n                Objects dedtypesX;      // empty tiargs\n\n                // https://issues.dlang.org/show_bug.cgi?id=11553\n                // Check for recursive instantiation of tdx.\n                for (TemplatePrevious* p = tdx.previous; p; p = p.prev)\n                {\n                    if (arrayObjectMatch(p.dedargs, &dedtypesX))\n                    {\n                        //printf(\"recursive, no match p.sc=%p %p %s\\n\", p.sc, this, this.toChars());\n                        /* It must be a subscope of p.sc, other scope chains are not recursive\n                         * instantiations.\n                         */\n                        for (Scope* scx = sc; scx; scx = scx.enclosing)\n                        {\n                            if (scx == p.sc)\n                            {\n                                error(loc, \"recursive template expansion while looking for `%s.%s`\", ti.toChars(), tdx.toChars());\n                                goto Lerror;\n                            }\n                        }\n                    }\n                    /* BUG: should also check for ref param differences\n                     */\n                }\n\n                TemplatePrevious pr;\n                pr.prev = tdx.previous;\n                pr.sc = sc;\n                pr.dedargs = &dedtypesX;\n                tdx.previous = &pr;             // add this to threaded list\n\n                fd = resolveFuncCall(loc, sc, s, null, tthis, fargs, 1);\n\n                tdx.previous = pr.prev;         // unlink from threaded list\n            }\n            else if (s.isFuncDeclaration())\n            {\n                fd = resolveFuncCall(loc, sc, s, null, tthis, fargs, 1);\n            }\n            else\n                goto Lerror;\n\n            if (!fd)\n                return 0;\n\n            if (fd.type.ty != Tfunction)\n            {\n                m.lastf = fd;   // to propagate \"error match\"\n                m.count = 1;\n                m.last = MATCH.nomatch;\n                return 1;\n            }\n\n            Type tthis_fd = fd.needThis() && !fd.isCtorDeclaration() ? tthis : null;\n\n            auto tf = cast(TypeFunction)fd.type;\n            MATCH mfa = tf.callMatch(tthis_fd, fargs);\n            if (mfa < m.last)\n                return 0;\n\n            if (mta < ta_last) goto Ltd_best2;\n            if (mta > ta_last) goto Ltd2;\n\n            if (mfa < m.last) goto Ltd_best2;\n            if (mfa > m.last) goto Ltd2;\n\n        Lambig2:    // td_best and td are ambiguous\n            //printf(\"Lambig2\\n\");\n            m.nextf = fd;\n            m.count++;\n            return 0;\n\n        Ltd_best2:\n            return 0;\n\n        Ltd2:\n            // td is the new best match\n            assert(td._scope);\n            td_best = td;\n            ti_best = null;\n            property = 0;   // (backward compatibility)\n            ta_last = mta;\n            m.last = mfa;\n            m.lastf = fd;\n            tthis_best = tthis_fd;\n            ov_index = 0;\n            m.nextf = null;\n            m.count = 1;\n            return 0;\n        }\n\n        //printf(\"td = %s\\n\", td.toChars());\n        for (size_t ovi = 0; f; f = f.overnext0, ovi++)\n        {\n            if (f.type.ty != Tfunction || f.errors)\n                goto Lerror;\n\n            /* This is a 'dummy' instance to evaluate constraint properly.\n             */\n            auto ti = new TemplateInstance(loc, td, tiargs);\n            ti.parent = td.parent;  // Maybe calculating valid 'enclosing' is unnecessary.\n\n            auto fd = f;\n            int x = td.deduceFunctionTemplateMatch(ti, sc, fd, tthis, fargs);\n            MATCH mta = cast(MATCH)(x >> 4);\n            MATCH mfa = cast(MATCH)(x & 0xF);\n            //printf(\"match:t/f = %d/%d\\n\", mta, mfa);\n            if (!fd || mfa == MATCH.nomatch)\n                continue;\n\n            Type tthis_fd = fd.needThis() ? tthis : null;\n\n            bool isCtorCall = tthis_fd && fd.isCtorDeclaration();\n            if (isCtorCall)\n            {\n                // Constructor call requires additional check.\n\n                auto tf = cast(TypeFunction)fd.type;\n                assert(tf.next);\n                if (MODimplicitConv(tf.mod, tthis_fd.mod) ||\n                    tf.isWild() && tf.isShared() == tthis_fd.isShared() ||\n                    fd.isReturnIsolated())\n                {\n                    tthis_fd = null;\n                }\n                else\n                    continue;   // MATCH.nomatch\n            }\n\n            if (mta < ta_last) goto Ltd_best;\n            if (mta > ta_last) goto Ltd;\n\n            if (mfa < m.last) goto Ltd_best;\n            if (mfa > m.last) goto Ltd;\n\n            if (td_best)\n            {\n                // Disambiguate by picking the most specialized TemplateDeclaration\n                MATCH c1 = td.leastAsSpecialized(sc, td_best, fargs);\n                MATCH c2 = td_best.leastAsSpecialized(sc, td, fargs);\n                //printf(\"1: c1 = %d, c2 = %d\\n\", c1, c2);\n                if (c1 > c2) goto Ltd;\n                if (c1 < c2) goto Ltd_best;\n            }\n            assert(fd && m.lastf);\n            {\n                // Disambiguate by tf.callMatch\n                auto tf1 = cast(TypeFunction)fd.type;\n                assert(tf1.ty == Tfunction);\n                auto tf2 = cast(TypeFunction)m.lastf.type;\n                assert(tf2.ty == Tfunction);\n                MATCH c1 = tf1.callMatch(tthis_fd, fargs);\n                MATCH c2 = tf2.callMatch(tthis_best, fargs);\n                //printf(\"2: c1 = %d, c2 = %d\\n\", c1, c2);\n                if (c1 > c2) goto Ltd;\n                if (c1 < c2) goto Ltd_best;\n            }\n            {\n                // Disambiguate by picking the most specialized FunctionDeclaration\n                MATCH c1 = fd.leastAsSpecialized(m.lastf);\n                MATCH c2 = m.lastf.leastAsSpecialized(fd);\n                //printf(\"3: c1 = %d, c2 = %d\\n\", c1, c2);\n                if (c1 > c2) goto Ltd;\n                if (c1 < c2) goto Ltd_best;\n            }\n\n            // https://issues.dlang.org/show_bug.cgi?id=14450\n            // Prefer exact qualified constructor for the creating object type\n            if (isCtorCall && fd.type.mod != m.lastf.type.mod)\n            {\n                if (tthis.mod == fd.type.mod) goto Ltd;\n                if (tthis.mod == m.lastf.type.mod) goto Ltd_best;\n            }\n\n            m.nextf = fd;\n            m.count++;\n            continue;\n\n        Ltd_best:           // td_best is the best match so far\n            //printf(\"Ltd_best\\n\");\n            continue;\n\n        Ltd:                // td is the new best match\n            //printf(\"Ltd\\n\");\n            assert(td._scope);\n            td_best = td;\n            ti_best = ti;\n            property = 0;   // (backward compatibility)\n            ta_last = mta;\n            m.last = mfa;\n            m.lastf = fd;\n            tthis_best = tthis_fd;\n            ov_index = ovi;\n            m.nextf = null;\n            m.count = 1;\n            continue;\n        }\n        return 0;\n    }\n\n    auto td = dstart.isTemplateDeclaration();\n    if (td && td.funcroot)\n        dstart = td.funcroot;\n    overloadApply(dstart, (Dsymbol s)\n    {\n        if (s.errors)\n            return 0;\n        if (auto fd = s.isFuncDeclaration())\n            return applyFunction(fd);\n        if (auto td = s.isTemplateDeclaration())\n            return applyTemplate(td);\n        return 0;\n    }, sc);\n\n    //printf(\"td_best = %p, m.lastf = %p\\n\", td_best, m.lastf);\n    if (td_best && ti_best && m.count == 1)\n    {\n        // Matches to template function\n        assert(td_best.onemember && td_best.onemember.isFuncDeclaration());\n        /* The best match is td_best with arguments tdargs.\n         * Now instantiate the template.\n         */\n        assert(td_best._scope);\n        if (!sc)\n            sc = td_best._scope; // workaround for Type.aliasthisOf\n\n        auto ti = new TemplateInstance(loc, td_best, ti_best.tiargs);\n        ti.templateInstanceSemantic(sc, fargs);\n\n        m.lastf = ti.toAlias().isFuncDeclaration();\n        if (!m.lastf)\n            goto Lnomatch;\n        if (ti.errors)\n        {\n        Lerror:\n            m.count = 1;\n            assert(m.lastf);\n            m.last = MATCH.nomatch;\n            return;\n        }\n\n        // look forward instantiated overload function\n        // Dsymbol.oneMembers is alredy called in TemplateInstance.semantic.\n        // it has filled overnext0d\n        while (ov_index--)\n        {\n            m.lastf = m.lastf.overnext0;\n            assert(m.lastf);\n        }\n\n        tthis_best = m.lastf.needThis() && !m.lastf.isCtorDeclaration() ? tthis : null;\n\n        auto tf = cast(TypeFunction)m.lastf.type;\n        if (tf.ty == Terror)\n            goto Lerror;\n        assert(tf.ty == Tfunction);\n        if (!tf.callMatch(tthis_best, fargs))\n            goto Lnomatch;\n\n        /* As https://issues.dlang.org/show_bug.cgi?id=3682 shows,\n         * a template instance can be matched while instantiating\n         * that same template. Thus, the function type can be incomplete. Complete it.\n         *\n         * https://issues.dlang.org/show_bug.cgi?id=9208\n         * For auto function, completion should be deferred to the end of\n         * its semantic3. Should not complete it in here.\n         */\n        if (tf.next && !m.lastf.inferRetType)\n        {\n            m.lastf.type = tf.typeSemantic(loc, sc);\n        }\n    }\n    else if (m.lastf)\n    {\n        // Matches to non template function,\n        // or found matches were ambiguous.\n        assert(m.count >= 1);\n    }\n    else\n    {\n    Lnomatch:\n        m.count = 0;\n        m.lastf = null;\n        m.last = MATCH.nomatch;\n    }\n}\n\n/* ======================== Type ============================================ */\n\n/****\n * Given an identifier, figure out which TemplateParameter it is.\n * Return IDX_NOTFOUND if not found.\n */\nprivate size_t templateIdentifierLookup(Identifier id, TemplateParameters* parameters)\n{\n    for (size_t i = 0; i < parameters.dim; i++)\n    {\n        TemplateParameter tp = (*parameters)[i];\n        if (tp.ident.equals(id))\n            return i;\n    }\n    return IDX_NOTFOUND;\n}\n\nprivate size_t templateParameterLookup(Type tparam, TemplateParameters* parameters)\n{\n    if (tparam.ty == Tident)\n    {\n        TypeIdentifier tident = cast(TypeIdentifier)tparam;\n        //printf(\"\\ttident = '%s'\\n\", tident.toChars());\n        return templateIdentifierLookup(tident.ident, parameters);\n    }\n    return IDX_NOTFOUND;\n}\n\nprivate ubyte deduceWildHelper(Type t, Type* at, Type tparam)\n{\n    if ((tparam.mod & MODFlags.wild) == 0)\n        return 0;\n\n    *at = null;\n\n    auto X(T, U)(T U, U T)\n    {\n        return (U << 4) | T;\n    }\n\n    switch (X(tparam.mod, t.mod))\n    {\n    case X(MODFlags.wild, 0):\n    case X(MODFlags.wild, MODFlags.const_):\n    case X(MODFlags.wild, MODFlags.shared_):\n    case X(MODFlags.wild, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.wild, MODFlags.immutable_):\n    case X(MODFlags.wildconst, 0):\n    case X(MODFlags.wildconst, MODFlags.const_):\n    case X(MODFlags.wildconst, MODFlags.shared_):\n    case X(MODFlags.wildconst, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.wildconst, MODFlags.immutable_):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.shared_):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.immutable_):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.shared_):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.immutable_):\n        {\n            ubyte wm = (t.mod & ~MODFlags.shared_);\n            if (wm == 0)\n                wm = MODFlags.mutable;\n            ubyte m = (t.mod & (MODFlags.const_ | MODFlags.immutable_)) | (tparam.mod & t.mod & MODFlags.shared_);\n            *at = t.unqualify(m);\n            return wm;\n        }\n    case X(MODFlags.wild, MODFlags.wild):\n    case X(MODFlags.wild, MODFlags.wildconst):\n    case X(MODFlags.wild, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.wild, MODFlags.shared_ | MODFlags.wildconst):\n    case X(MODFlags.wildconst, MODFlags.wild):\n    case X(MODFlags.wildconst, MODFlags.wildconst):\n    case X(MODFlags.wildconst, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.wildconst, MODFlags.shared_ | MODFlags.wildconst):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.shared_ | MODFlags.wildconst):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.shared_ | MODFlags.wildconst):\n        {\n            *at = t.unqualify(tparam.mod & t.mod);\n            return MODFlags.wild;\n        }\n    default:\n        return 0;\n    }\n}\n\n/**\n * Returns the common type of the 2 types.\n */\nprivate Type rawTypeMerge(Type t1, Type t2)\n{\n    if (t1.equals(t2))\n        return t1;\n    if (t1.equivalent(t2))\n        return t1.castMod(MODmerge(t1.mod, t2.mod));\n\n    auto t1b = t1.toBasetype();\n    auto t2b = t2.toBasetype();\n    if (t1b.equals(t2b))\n        return t1b;\n    if (t1b.equivalent(t2b))\n        return t1b.castMod(MODmerge(t1b.mod, t2b.mod));\n\n    auto ty = cast(TY)impcnvResult[t1b.ty][t2b.ty];\n    if (ty != Terror)\n        return Type.basic[ty];\n\n    return null;\n}\n\nprivate MATCH deduceTypeHelper(Type t, Type* at, Type tparam)\n{\n    // 9*9 == 81 cases\n\n    auto X(T, U)(T U, U T)\n    {\n        return (U << 4) | T;\n    }\n\n    switch (X(tparam.mod, t.mod))\n    {\n    case X(0, 0):\n    case X(0, MODFlags.const_):\n    case X(0, MODFlags.wild):\n    case X(0, MODFlags.wildconst):\n    case X(0, MODFlags.shared_):\n    case X(0, MODFlags.shared_ | MODFlags.const_):\n    case X(0, MODFlags.shared_ | MODFlags.wild):\n    case X(0, MODFlags.shared_ | MODFlags.wildconst):\n    case X(0, MODFlags.immutable_):\n        // foo(U)                       T                       => T\n        // foo(U)                       const(T)                => const(T)\n        // foo(U)                       inout(T)                => inout(T)\n        // foo(U)                       inout(const(T))         => inout(const(T))\n        // foo(U)                       shared(T)               => shared(T)\n        // foo(U)                       shared(const(T))        => shared(const(T))\n        // foo(U)                       shared(inout(T))        => shared(inout(T))\n        // foo(U)                       shared(inout(const(T))) => shared(inout(const(T)))\n        // foo(U)                       immutable(T)            => immutable(T)\n        {\n            *at = t;\n            return MATCH.exact;\n        }\n    case X(MODFlags.const_, MODFlags.const_):\n    case X(MODFlags.wild, MODFlags.wild):\n    case X(MODFlags.wildconst, MODFlags.wildconst):\n    case X(MODFlags.shared_, MODFlags.shared_):\n    case X(MODFlags.shared_ | MODFlags.const_, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.shared_ | MODFlags.wildconst):\n    case X(MODFlags.immutable_, MODFlags.immutable_):\n        // foo(const(U))                const(T)                => T\n        // foo(inout(U))                inout(T)                => T\n        // foo(inout(const(U)))         inout(const(T))         => T\n        // foo(shared(U))               shared(T)               => T\n        // foo(shared(const(U)))        shared(const(T))        => T\n        // foo(shared(inout(U)))        shared(inout(T))        => T\n        // foo(shared(inout(const(U)))) shared(inout(const(T))) => T\n        // foo(immutable(U))            immutable(T)            => T\n        {\n            *at = t.mutableOf().unSharedOf();\n            return MATCH.exact;\n        }\n    case X(MODFlags.const_, 0):\n    case X(MODFlags.const_, MODFlags.wild):\n    case X(MODFlags.const_, MODFlags.wildconst):\n    case X(MODFlags.const_, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.const_, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.const_, MODFlags.shared_ | MODFlags.wildconst):\n    case X(MODFlags.const_, MODFlags.immutable_):\n    case X(MODFlags.wild, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.wildconst, MODFlags.shared_ | MODFlags.wildconst):\n    case X(MODFlags.shared_ | MODFlags.const_, MODFlags.immutable_):\n        // foo(const(U))                T                       => T\n        // foo(const(U))                inout(T)                => T\n        // foo(const(U))                inout(const(T))         => T\n        // foo(const(U))                shared(const(T))        => shared(T)\n        // foo(const(U))                shared(inout(T))        => shared(T)\n        // foo(const(U))                shared(inout(const(T))) => shared(T)\n        // foo(const(U))                immutable(T)            => T\n        // foo(inout(U))                shared(inout(T))        => shared(T)\n        // foo(inout(const(U)))         shared(inout(const(T))) => shared(T)\n        // foo(shared(const(U)))        immutable(T)            => T\n        {\n            *at = t.mutableOf();\n            return MATCH.constant;\n        }\n    case X(MODFlags.const_, MODFlags.shared_):\n        // foo(const(U))                shared(T)               => shared(T)\n        {\n            *at = t;\n            return MATCH.constant;\n        }\n    case X(MODFlags.shared_, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.shared_, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.shared_, MODFlags.shared_ | MODFlags.wildconst):\n    case X(MODFlags.shared_ | MODFlags.const_, MODFlags.shared_):\n        // foo(shared(U))               shared(const(T))        => const(T)\n        // foo(shared(U))               shared(inout(T))        => inout(T)\n        // foo(shared(U))               shared(inout(const(T))) => inout(const(T))\n        // foo(shared(const(U)))        shared(T)               => T\n        {\n            *at = t.unSharedOf();\n            return MATCH.constant;\n        }\n    case X(MODFlags.wildconst, MODFlags.immutable_):\n    case X(MODFlags.shared_ | MODFlags.const_, MODFlags.shared_ | MODFlags.wildconst):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.immutable_):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.shared_ | MODFlags.wild):\n        // foo(inout(const(U)))         immutable(T)            => T\n        // foo(shared(const(U)))        shared(inout(const(T))) => T\n        // foo(shared(inout(const(U)))) immutable(T)            => T\n        // foo(shared(inout(const(U)))) shared(inout(T))        => T\n        {\n            *at = t.unSharedOf().mutableOf();\n            return MATCH.constant;\n        }\n    case X(MODFlags.shared_ | MODFlags.const_, MODFlags.shared_ | MODFlags.wild):\n        // foo(shared(const(U)))        shared(inout(T))        => T\n        {\n            *at = t.unSharedOf().mutableOf();\n            return MATCH.constant;\n        }\n    case X(MODFlags.wild, 0):\n    case X(MODFlags.wild, MODFlags.const_):\n    case X(MODFlags.wild, MODFlags.wildconst):\n    case X(MODFlags.wild, MODFlags.immutable_):\n    case X(MODFlags.wild, MODFlags.shared_):\n    case X(MODFlags.wild, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.wild, MODFlags.shared_ | MODFlags.wildconst):\n    case X(MODFlags.wildconst, 0):\n    case X(MODFlags.wildconst, MODFlags.const_):\n    case X(MODFlags.wildconst, MODFlags.wild):\n    case X(MODFlags.wildconst, MODFlags.shared_):\n    case X(MODFlags.wildconst, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.wildconst, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.shared_, 0):\n    case X(MODFlags.shared_, MODFlags.const_):\n    case X(MODFlags.shared_, MODFlags.wild):\n    case X(MODFlags.shared_, MODFlags.wildconst):\n    case X(MODFlags.shared_, MODFlags.immutable_):\n    case X(MODFlags.shared_ | MODFlags.const_, 0):\n    case X(MODFlags.shared_ | MODFlags.const_, MODFlags.const_):\n    case X(MODFlags.shared_ | MODFlags.const_, MODFlags.wild):\n    case X(MODFlags.shared_ | MODFlags.const_, MODFlags.wildconst):\n    case X(MODFlags.shared_ | MODFlags.wild, 0):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.const_):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.wild):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.wildconst):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.immutable_):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.shared_):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.shared_ | MODFlags.wild, MODFlags.shared_ | MODFlags.wildconst):\n    case X(MODFlags.shared_ | MODFlags.wildconst, 0):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.const_):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.wild):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.wildconst):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.shared_):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.immutable_, 0):\n    case X(MODFlags.immutable_, MODFlags.const_):\n    case X(MODFlags.immutable_, MODFlags.wild):\n    case X(MODFlags.immutable_, MODFlags.wildconst):\n    case X(MODFlags.immutable_, MODFlags.shared_):\n    case X(MODFlags.immutable_, MODFlags.shared_ | MODFlags.const_):\n    case X(MODFlags.immutable_, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.immutable_, MODFlags.shared_ | MODFlags.wildconst):\n        // foo(inout(U))                T                       => nomatch\n        // foo(inout(U))                const(T)                => nomatch\n        // foo(inout(U))                inout(const(T))         => nomatch\n        // foo(inout(U))                immutable(T)            => nomatch\n        // foo(inout(U))                shared(T)               => nomatch\n        // foo(inout(U))                shared(const(T))        => nomatch\n        // foo(inout(U))                shared(inout(const(T))) => nomatch\n        // foo(inout(const(U)))         T                       => nomatch\n        // foo(inout(const(U)))         const(T)                => nomatch\n        // foo(inout(const(U)))         inout(T)                => nomatch\n        // foo(inout(const(U)))         shared(T)               => nomatch\n        // foo(inout(const(U)))         shared(const(T))        => nomatch\n        // foo(inout(const(U)))         shared(inout(T))        => nomatch\n        // foo(shared(U))               T                       => nomatch\n        // foo(shared(U))               const(T)                => nomatch\n        // foo(shared(U))               inout(T)                => nomatch\n        // foo(shared(U))               inout(const(T))         => nomatch\n        // foo(shared(U))               immutable(T)            => nomatch\n        // foo(shared(const(U)))        T                       => nomatch\n        // foo(shared(const(U)))        const(T)                => nomatch\n        // foo(shared(const(U)))        inout(T)                => nomatch\n        // foo(shared(const(U)))        inout(const(T))         => nomatch\n        // foo(shared(inout(U)))        T                       => nomatch\n        // foo(shared(inout(U)))        const(T)                => nomatch\n        // foo(shared(inout(U)))        inout(T)                => nomatch\n        // foo(shared(inout(U)))        inout(const(T))         => nomatch\n        // foo(shared(inout(U)))        immutable(T)            => nomatch\n        // foo(shared(inout(U)))        shared(T)               => nomatch\n        // foo(shared(inout(U)))        shared(const(T))        => nomatch\n        // foo(shared(inout(U)))        shared(inout(const(T))) => nomatch\n        // foo(shared(inout(const(U)))) T                       => nomatch\n        // foo(shared(inout(const(U)))) const(T)                => nomatch\n        // foo(shared(inout(const(U)))) inout(T)                => nomatch\n        // foo(shared(inout(const(U)))) inout(const(T))         => nomatch\n        // foo(shared(inout(const(U)))) shared(T)               => nomatch\n        // foo(shared(inout(const(U)))) shared(const(T))        => nomatch\n        // foo(immutable(U))            T                       => nomatch\n        // foo(immutable(U))            const(T)                => nomatch\n        // foo(immutable(U))            inout(T)                => nomatch\n        // foo(immutable(U))            inout(const(T))         => nomatch\n        // foo(immutable(U))            shared(T)               => nomatch\n        // foo(immutable(U))            shared(const(T))        => nomatch\n        // foo(immutable(U))            shared(inout(T))        => nomatch\n        // foo(immutable(U))            shared(inout(const(T))) => nomatch\n        return MATCH.nomatch;\n\n    default:\n        assert(0);\n    }\n}\n\n__gshared Expression emptyArrayElement = null;\n\n/* These form the heart of template argument deduction.\n * Given 'this' being the type argument to the template instance,\n * it is matched against the template declaration parameter specialization\n * 'tparam' to determine the type to be used for the parameter.\n * Example:\n *      template Foo(T:T*)      // template declaration\n *      Foo!(int*)              // template instantiation\n * Input:\n *      this = int*\n *      tparam = T*\n *      parameters = [ T:T* ]   // Array of TemplateParameter's\n * Output:\n *      dedtypes = [ int ]      // Array of Expression/Type's\n */\nMATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* parameters, Objects* dedtypes, uint* wm = null, size_t inferStart = 0)\n{\n    extern (C++) final class DeduceType : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        Scope* sc;\n        Type tparam;\n        TemplateParameters* parameters;\n        Objects* dedtypes;\n        uint* wm;\n        size_t inferStart;\n        MATCH result;\n\n        extern (D) this(Scope* sc, Type tparam, TemplateParameters* parameters, Objects* dedtypes, uint* wm, size_t inferStart)\n        {\n            this.sc = sc;\n            this.tparam = tparam;\n            this.parameters = parameters;\n            this.dedtypes = dedtypes;\n            this.wm = wm;\n            this.inferStart = inferStart;\n            result = MATCH.nomatch;\n        }\n\n        override void visit(Type t)\n        {\n            if (!tparam)\n                goto Lnomatch;\n\n            if (t == tparam)\n                goto Lexact;\n\n            if (tparam.ty == Tident)\n            {\n                // Determine which parameter tparam is\n                size_t i = templateParameterLookup(tparam, parameters);\n                if (i == IDX_NOTFOUND)\n                {\n                    if (!sc)\n                        goto Lnomatch;\n\n                    /* Need a loc to go with the semantic routine.\n                     */\n                    Loc loc;\n                    if (parameters.dim)\n                    {\n                        TemplateParameter tp = (*parameters)[0];\n                        loc = tp.loc;\n                    }\n\n                    /* BUG: what if tparam is a template instance, that\n                     * has as an argument another Tident?\n                     */\n                    tparam = tparam.typeSemantic(loc, sc);\n                    assert(tparam.ty != Tident);\n                    result = deduceType(t, sc, tparam, parameters, dedtypes, wm);\n                    return;\n                }\n\n                TemplateParameter tp = (*parameters)[i];\n\n                TypeIdentifier tident = cast(TypeIdentifier)tparam;\n                if (tident.idents.dim > 0)\n                {\n                    //printf(\"matching %s to %s\\n\", tparam.toChars(), t.toChars());\n                    Dsymbol s = t.toDsymbol(sc);\n                    for (size_t j = tident.idents.dim; j-- > 0;)\n                    {\n                        RootObject id = tident.idents[j];\n                        if (id.dyncast() == DYNCAST.identifier)\n                        {\n                            if (!s || !s.parent)\n                                goto Lnomatch;\n                            Dsymbol s2 = s.parent.search(Loc.initial, cast(Identifier)id);\n                            if (!s2)\n                                goto Lnomatch;\n                            s2 = s2.toAlias();\n                            //printf(\"[%d] s = %s %s, s2 = %s %s\\n\", j, s.kind(), s.toChars(), s2.kind(), s2.toChars());\n                            if (s != s2)\n                            {\n                                if (Type tx = s2.getType())\n                                {\n                                    if (s != tx.toDsymbol(sc))\n                                        goto Lnomatch;\n                                }\n                                else\n                                    goto Lnomatch;\n                            }\n                            s = s.parent;\n                        }\n                        else\n                            goto Lnomatch;\n                    }\n                    //printf(\"[e] s = %s\\n\", s?s.toChars():\"(null)\");\n                    if (tp.isTemplateTypeParameter())\n                    {\n                        Type tt = s.getType();\n                        if (!tt)\n                            goto Lnomatch;\n                        Type at = cast(Type)(*dedtypes)[i];\n                        if (at && at.ty == Tnone)\n                            at = (cast(TypeDeduced)at).tded;\n                        if (!at || tt.equals(at))\n                        {\n                            (*dedtypes)[i] = tt;\n                            goto Lexact;\n                        }\n                    }\n                    if (tp.isTemplateAliasParameter())\n                    {\n                        Dsymbol s2 = cast(Dsymbol)(*dedtypes)[i];\n                        if (!s2 || s == s2)\n                        {\n                            (*dedtypes)[i] = s;\n                            goto Lexact;\n                        }\n                    }\n                    goto Lnomatch;\n                }\n\n                // Found the corresponding parameter tp\n                if (!tp.isTemplateTypeParameter())\n                    goto Lnomatch;\n\n                Type at = cast(Type)(*dedtypes)[i];\n                Type tt;\n                if (ubyte wx = wm ? deduceWildHelper(t, &tt, tparam) : 0)\n                {\n                    // type vs (none)\n                    if (!at)\n                    {\n                        (*dedtypes)[i] = tt;\n                        *wm |= wx;\n                        result = MATCH.constant;\n                        return;\n                    }\n\n                    // type vs expressions\n                    if (at.ty == Tnone)\n                    {\n                        TypeDeduced xt = cast(TypeDeduced)at;\n                        result = xt.matchAll(tt);\n                        if (result > MATCH.nomatch)\n                        {\n                            (*dedtypes)[i] = tt;\n                            if (result > MATCH.constant)\n                                result = MATCH.constant; // limit level for inout matches\n                        }\n                        return;\n                    }\n\n                    // type vs type\n                    if (tt.equals(at))\n                    {\n                        (*dedtypes)[i] = tt; // Prefer current type match\n                        goto Lconst;\n                    }\n                    if (tt.implicitConvTo(at.constOf()))\n                    {\n                        (*dedtypes)[i] = at.constOf().mutableOf();\n                        *wm |= MODFlags.const_;\n                        goto Lconst;\n                    }\n                    if (at.implicitConvTo(tt.constOf()))\n                    {\n                        (*dedtypes)[i] = tt.constOf().mutableOf();\n                        *wm |= MODFlags.const_;\n                        goto Lconst;\n                    }\n                    goto Lnomatch;\n                }\n                else if (MATCH m = deduceTypeHelper(t, &tt, tparam))\n                {\n                    // type vs (none)\n                    if (!at)\n                    {\n                        (*dedtypes)[i] = tt;\n                        result = m;\n                        return;\n                    }\n\n                    // type vs expressions\n                    if (at.ty == Tnone)\n                    {\n                        TypeDeduced xt = cast(TypeDeduced)at;\n                        result = xt.matchAll(tt);\n                        if (result > MATCH.nomatch)\n                        {\n                            (*dedtypes)[i] = tt;\n                        }\n                        return;\n                    }\n\n                    // type vs type\n                    if (tt.equals(at))\n                    {\n                        goto Lexact;\n                    }\n                    if (tt.ty == Tclass && at.ty == Tclass)\n                    {\n                        result = tt.implicitConvTo(at);\n                        return;\n                    }\n                    if (tt.ty == Tsarray && at.ty == Tarray && tt.nextOf().implicitConvTo(at.nextOf()) >= MATCH.constant)\n                    {\n                        goto Lexact;\n                    }\n                }\n                goto Lnomatch;\n            }\n\n            if (tparam.ty == Ttypeof)\n            {\n                /* Need a loc to go with the semantic routine.\n                 */\n                Loc loc;\n                if (parameters.dim)\n                {\n                    TemplateParameter tp = (*parameters)[0];\n                    loc = tp.loc;\n                }\n\n                tparam = tparam.typeSemantic(loc, sc);\n            }\n            if (t.ty != tparam.ty)\n            {\n                if (Dsymbol sym = t.toDsymbol(sc))\n                {\n                    if (sym.isforwardRef() && !tparam.deco)\n                        goto Lnomatch;\n                }\n\n                MATCH m = t.implicitConvTo(tparam);\n                if (m == MATCH.nomatch)\n                {\n                    if (t.ty == Tclass)\n                    {\n                        TypeClass tc = cast(TypeClass)t;\n                        if (tc.sym.aliasthis && !(tc.att & AliasThisRec.tracingDT))\n                        {\n                            if (auto ato = t.aliasthisOf())\n                            {\n                                tc.att = cast(AliasThisRec)(tc.att | AliasThisRec.tracingDT);\n                                m = deduceType(ato, sc, tparam, parameters, dedtypes, wm);\n                                tc.att = cast(AliasThisRec)(tc.att & ~AliasThisRec.tracingDT);\n                            }\n                        }\n                    }\n                    else if (t.ty == Tstruct)\n                    {\n                        TypeStruct ts = cast(TypeStruct)t;\n                        if (ts.sym.aliasthis && !(ts.att & AliasThisRec.tracingDT))\n                        {\n                            if (auto ato = t.aliasthisOf())\n                            {\n                                ts.att = cast(AliasThisRec)(ts.att | AliasThisRec.tracingDT);\n                                m = deduceType(ato, sc, tparam, parameters, dedtypes, wm);\n                                ts.att = cast(AliasThisRec)(ts.att & ~AliasThisRec.tracingDT);\n                            }\n                        }\n                    }\n                }\n                result = m;\n                return;\n            }\n\n            if (t.nextOf())\n            {\n                if (tparam.deco && !tparam.hasWild())\n                {\n                    result = t.implicitConvTo(tparam);\n                    return;\n                }\n\n                Type tpn = tparam.nextOf();\n                if (wm && t.ty == Taarray && tparam.isWild())\n                {\n                    // https://issues.dlang.org/show_bug.cgi?id=12403\n                    // In IFTI, stop inout matching on transitive part of AA types.\n                    tpn = tpn.substWildTo(MODFlags.mutable);\n                }\n\n                result = deduceType(t.nextOf(), sc, tpn, parameters, dedtypes, wm);\n                return;\n            }\n\n        Lexact:\n            result = MATCH.exact;\n            return;\n\n        Lnomatch:\n            result = MATCH.nomatch;\n            return;\n\n        Lconst:\n            result = MATCH.constant;\n        }\n\n        override void visit(TypeVector t)\n        {\n            if (tparam.ty == Tvector)\n            {\n                TypeVector tp = cast(TypeVector)tparam;\n                result = deduceType(t.basetype, sc, tp.basetype, parameters, dedtypes, wm);\n                return;\n            }\n            visit(cast(Type)t);\n        }\n\n        override void visit(TypeDArray t)\n        {\n            visit(cast(Type)t);\n        }\n\n        override void visit(TypeSArray t)\n        {\n            // Extra check that array dimensions must match\n            if (tparam)\n            {\n                if (tparam.ty == Tarray)\n                {\n                    MATCH m = deduceType(t.next, sc, tparam.nextOf(), parameters, dedtypes, wm);\n                    result = (m >= MATCH.constant) ? MATCH.convert : MATCH.nomatch;\n                    return;\n                }\n\n                TemplateParameter tp = null;\n                Expression edim = null;\n                size_t i;\n                if (tparam.ty == Tsarray)\n                {\n                    TypeSArray tsa = cast(TypeSArray)tparam;\n                    if (tsa.dim.op == TOK.variable && (cast(VarExp)tsa.dim).var.storage_class & STC.templateparameter)\n                    {\n                        Identifier id = (cast(VarExp)tsa.dim).var.ident;\n                        i = templateIdentifierLookup(id, parameters);\n                        assert(i != IDX_NOTFOUND);\n                        tp = (*parameters)[i];\n                    }\n                    else\n                        edim = tsa.dim;\n                }\n                else if (tparam.ty == Taarray)\n                {\n                    TypeAArray taa = cast(TypeAArray)tparam;\n                    i = templateParameterLookup(taa.index, parameters);\n                    if (i != IDX_NOTFOUND)\n                        tp = (*parameters)[i];\n                    else\n                    {\n                        Expression e;\n                        Type tx;\n                        Dsymbol s;\n                        taa.index.resolve(Loc.initial, sc, &e, &tx, &s);\n                        edim = s ? getValue(s) : getValue(e);\n                    }\n                }\n                if (tp && tp.matchArg(sc, t.dim, i, parameters, dedtypes, null) || edim && edim.toInteger() == t.dim.toInteger())\n                {\n                    result = deduceType(t.next, sc, tparam.nextOf(), parameters, dedtypes, wm);\n                    return;\n                }\n            }\n            visit(cast(Type)t);\n        }\n\n        override void visit(TypeAArray t)\n        {\n            // Extra check that index type must match\n            if (tparam && tparam.ty == Taarray)\n            {\n                TypeAArray tp = cast(TypeAArray)tparam;\n                if (!deduceType(t.index, sc, tp.index, parameters, dedtypes))\n                {\n                    result = MATCH.nomatch;\n                    return;\n                }\n            }\n            visit(cast(Type)t);\n        }\n\n        override void visit(TypeFunction t)\n        {\n            // Extra check that function characteristics must match\n            if (tparam && tparam.ty == Tfunction)\n            {\n                TypeFunction tp = cast(TypeFunction)tparam;\n                if (t.varargs != tp.varargs || t.linkage != tp.linkage)\n                {\n                    result = MATCH.nomatch;\n                    return;\n                }\n\n                foreach (fparam; *tp.parameters)\n                {\n                    // https://issues.dlang.org/show_bug.cgi?id=2579\n                    // Apply function parameter storage classes to parameter types\n                    fparam.type = fparam.type.addStorageClass(fparam.storageClass);\n                    fparam.storageClass &= ~(STC.TYPECTOR | STC.in_);\n\n                    // https://issues.dlang.org/show_bug.cgi?id=15243\n                    // Resolve parameter type if it's not related with template parameters\n                    if (!reliesOnTident(fparam.type, parameters, inferStart))\n                    {\n                        auto tx = fparam.type.typeSemantic(Loc.initial, sc);\n                        if (tx.ty == Terror)\n                        {\n                            result = MATCH.nomatch;\n                            return;\n                        }\n                        fparam.type = tx;\n                    }\n                }\n\n                size_t nfargs = Parameter.dim(t.parameters);\n                size_t nfparams = Parameter.dim(tp.parameters);\n\n                /* See if tuple match\n                 */\n                if (nfparams > 0 && nfargs >= nfparams - 1)\n                {\n                    /* See if 'A' of the template parameter matches 'A'\n                     * of the type of the last function parameter.\n                     */\n                    Parameter fparam = Parameter.getNth(tp.parameters, nfparams - 1);\n                    assert(fparam);\n                    assert(fparam.type);\n                    if (fparam.type.ty != Tident)\n                        goto L1;\n                    TypeIdentifier tid = cast(TypeIdentifier)fparam.type;\n                    if (tid.idents.dim)\n                        goto L1;\n\n                    /* Look through parameters to find tuple matching tid.ident\n                     */\n                    size_t tupi = 0;\n                    for (; 1; tupi++)\n                    {\n                        if (tupi == parameters.dim)\n                            goto L1;\n                        TemplateParameter tx = (*parameters)[tupi];\n                        TemplateTupleParameter tup = tx.isTemplateTupleParameter();\n                        if (tup && tup.ident.equals(tid.ident))\n                            break;\n                    }\n\n                    /* The types of the function arguments [nfparams - 1 .. nfargs]\n                     * now form the tuple argument.\n                     */\n                    size_t tuple_dim = nfargs - (nfparams - 1);\n\n                    /* See if existing tuple, and whether it matches or not\n                     */\n                    RootObject o = (*dedtypes)[tupi];\n                    if (o)\n                    {\n                        // Existing deduced argument must be a tuple, and must match\n                        Tuple tup = isTuple(o);\n                        if (!tup || tup.objects.dim != tuple_dim)\n                        {\n                            result = MATCH.nomatch;\n                            return;\n                        }\n                        for (size_t i = 0; i < tuple_dim; i++)\n                        {\n                            Parameter arg = Parameter.getNth(t.parameters, nfparams - 1 + i);\n                            if (!arg.type.equals(tup.objects[i]))\n                            {\n                                result = MATCH.nomatch;\n                                return;\n                            }\n                        }\n                    }\n                    else\n                    {\n                        // Create new tuple\n                        auto tup = new Tuple(tuple_dim);\n                        for (size_t i = 0; i < tuple_dim; i++)\n                        {\n                            Parameter arg = Parameter.getNth(t.parameters, nfparams - 1 + i);\n                            tup.objects[i] = arg.type;\n                        }\n                        (*dedtypes)[tupi] = tup;\n                    }\n                    nfparams--; // don't consider the last parameter for type deduction\n                    goto L2;\n                }\n\n            L1:\n                if (nfargs != nfparams)\n                {\n                    result = MATCH.nomatch;\n                    return;\n                }\n            L2:\n                for (size_t i = 0; i < nfparams; i++)\n                {\n                    Parameter a = Parameter.getNth(t.parameters, i);\n                    Parameter ap = Parameter.getNth(tp.parameters, i);\n\n                    if (!a.isCovariant(t.isref, ap) ||\n                        !deduceType(a.type, sc, ap.type, parameters, dedtypes))\n                    {\n                        result = MATCH.nomatch;\n                        return;\n                    }\n                }\n            }\n            visit(cast(Type)t);\n        }\n\n        override void visit(TypeIdentifier t)\n        {\n            // Extra check\n            if (tparam && tparam.ty == Tident)\n            {\n                TypeIdentifier tp = cast(TypeIdentifier)tparam;\n                for (size_t i = 0; i < t.idents.dim; i++)\n                {\n                    RootObject id1 = t.idents[i];\n                    RootObject id2 = tp.idents[i];\n                    if (!id1.equals(id2))\n                    {\n                        result = MATCH.nomatch;\n                        return;\n                    }\n                }\n            }\n            visit(cast(Type)t);\n        }\n\n        override void visit(TypeInstance t)\n        {\n            // Extra check\n            if (tparam && tparam.ty == Tinstance && t.tempinst.tempdecl)\n            {\n                TemplateDeclaration tempdecl = t.tempinst.tempdecl.isTemplateDeclaration();\n                assert(tempdecl);\n\n                TypeInstance tp = cast(TypeInstance)tparam;\n\n                //printf(\"tempinst.tempdecl = %p\\n\", tempdecl);\n                //printf(\"tp.tempinst.tempdecl = %p\\n\", tp.tempinst.tempdecl);\n                if (!tp.tempinst.tempdecl)\n                {\n                    //printf(\"tp.tempinst.name = '%s'\\n\", tp.tempinst.name.toChars());\n\n                    /* Handle case of:\n                     *  template Foo(T : sa!(T), alias sa)\n                     */\n                    size_t i = templateIdentifierLookup(tp.tempinst.name, parameters);\n                    if (i == IDX_NOTFOUND)\n                    {\n                        /* Didn't find it as a parameter identifier. Try looking\n                         * it up and seeing if is an alias.\n                         * https://issues.dlang.org/show_bug.cgi?id=1454\n                         */\n                        auto tid = new TypeIdentifier(tp.loc, tp.tempinst.name);\n                        Type tx;\n                        Expression e;\n                        Dsymbol s;\n                        tid.resolve(tp.loc, sc, &e, &tx, &s);\n                        if (tx)\n                        {\n                            s = tx.toDsymbol(sc);\n                            if (TemplateInstance ti = s ? s.parent.isTemplateInstance() : null)\n                            {\n                                // https://issues.dlang.org/show_bug.cgi?id=14290\n                                // Try to match with ti.tempecl,\n                                // only when ti is an enclosing instance.\n                                Dsymbol p = sc.parent;\n                                while (p && p != ti)\n                                    p = p.parent;\n                                if (p)\n                                    s = ti.tempdecl;\n                            }\n                        }\n                        if (s)\n                        {\n                            s = s.toAlias();\n                            TemplateDeclaration td = s.isTemplateDeclaration();\n                            if (td)\n                            {\n                                if (td.overroot)\n                                    td = td.overroot;\n                                for (; td; td = td.overnext)\n                                {\n                                    if (td == tempdecl)\n                                        goto L2;\n                                }\n                            }\n                        }\n                        goto Lnomatch;\n                    }\n                    TemplateParameter tpx = (*parameters)[i];\n                    if (!tpx.matchArg(sc, tempdecl, i, parameters, dedtypes, null))\n                        goto Lnomatch;\n                }\n                else if (tempdecl != tp.tempinst.tempdecl)\n                    goto Lnomatch;\n\n            L2:\n                for (size_t i = 0; 1; i++)\n                {\n                    //printf(\"\\ttest: tempinst.tiargs[%d]\\n\", i);\n                    RootObject o1 = null;\n                    if (i < t.tempinst.tiargs.dim)\n                        o1 = (*t.tempinst.tiargs)[i];\n                    else if (i < t.tempinst.tdtypes.dim && i < tp.tempinst.tiargs.dim)\n                    {\n                        // Pick up default arg\n                        o1 = t.tempinst.tdtypes[i];\n                    }\n                    else if (i >= tp.tempinst.tiargs.dim)\n                        break;\n\n                    if (i >= tp.tempinst.tiargs.dim)\n                    {\n                        size_t dim = tempdecl.parameters.dim - (tempdecl.isVariadic() ? 1 : 0);\n                        while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg()))\n                        {\n                            i++;\n                        }\n                        if (i >= dim)\n                            break; // match if all remained parameters are dependent\n                        goto Lnomatch;\n                    }\n\n                    RootObject o2 = (*tp.tempinst.tiargs)[i];\n                    Type t2 = isType(o2);\n\n                    size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.dim - 1)\n                        ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;\n                    if (j != IDX_NOTFOUND && j == parameters.dim - 1 &&\n                        (*parameters)[j].isTemplateTupleParameter())\n                    {\n                        /* Given:\n                         *  struct A(B...) {}\n                         *  alias A!(int, float) X;\n                         *  static if (is(X Y == A!(Z), Z...)) {}\n                         * deduce that Z is a tuple(int, float)\n                         */\n\n                        /* Create tuple from remaining args\n                         */\n                        size_t vtdim = (tempdecl.isVariadic() ? t.tempinst.tiargs.dim : t.tempinst.tdtypes.dim) - i;\n                        auto vt = new Tuple(vtdim);\n                        for (size_t k = 0; k < vtdim; k++)\n                        {\n                            RootObject o;\n                            if (k < t.tempinst.tiargs.dim)\n                                o = (*t.tempinst.tiargs)[i + k];\n                            else // Pick up default arg\n                                o = t.tempinst.tdtypes[i + k];\n                            vt.objects[k] = o;\n                        }\n\n                        Tuple v = cast(Tuple)(*dedtypes)[j];\n                        if (v)\n                        {\n                            if (!match(v, vt))\n                                goto Lnomatch;\n                        }\n                        else\n                            (*dedtypes)[j] = vt;\n                        break;\n                    }\n                    else if (!o1)\n                        break;\n\n                    Type t1 = isType(o1);\n                    Dsymbol s1 = isDsymbol(o1);\n                    Dsymbol s2 = isDsymbol(o2);\n                    Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1));\n                    Expression e2 = isExpression(o2);\n                    version (none)\n                    {\n                        Tuple v1 = isTuple(o1);\n                        Tuple v2 = isTuple(o2);\n                        if (t1)\n                            printf(\"t1 = %s\\n\", t1.toChars());\n                        if (t2)\n                            printf(\"t2 = %s\\n\", t2.toChars());\n                        if (e1)\n                            printf(\"e1 = %s\\n\", e1.toChars());\n                        if (e2)\n                            printf(\"e2 = %s\\n\", e2.toChars());\n                        if (s1)\n                            printf(\"s1 = %s\\n\", s1.toChars());\n                        if (s2)\n                            printf(\"s2 = %s\\n\", s2.toChars());\n                        if (v1)\n                            printf(\"v1 = %s\\n\", v1.toChars());\n                        if (v2)\n                            printf(\"v2 = %s\\n\", v2.toChars());\n                    }\n\n                    if (t1 && t2)\n                    {\n                        if (!deduceType(t1, sc, t2, parameters, dedtypes))\n                            goto Lnomatch;\n                    }\n                    else if (e1 && e2)\n                    {\n                    Le:\n                        e1 = e1.ctfeInterpret();\n\n                        /* If it is one of the template parameters for this template,\n                         * we should not attempt to interpret it. It already has a value.\n                         */\n                        if (e2.op == TOK.variable && ((cast(VarExp)e2).var.storage_class & STC.templateparameter))\n                        {\n                            /*\n                             * (T:Number!(e2), int e2)\n                             */\n                            j = templateIdentifierLookup((cast(VarExp)e2).var.ident, parameters);\n                            if (j != IDX_NOTFOUND)\n                                goto L1;\n                            // The template parameter was not from this template\n                            // (it may be from a parent template, for example)\n                        }\n\n                        e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417\n                        e2 = e2.ctfeInterpret();\n\n                        //printf(\"e1 = %s, type = %s %d\\n\", e1.toChars(), e1.type.toChars(), e1.type.ty);\n                        //printf(\"e2 = %s, type = %s %d\\n\", e2.toChars(), e2.type.toChars(), e2.type.ty);\n                        if (!e1.equals(e2))\n                        {\n                            if (!e2.implicitConvTo(e1.type))\n                                goto Lnomatch;\n\n                            e2 = e2.implicitCastTo(sc, e1.type);\n                            e2 = e2.ctfeInterpret();\n                            if (!e1.equals(e2))\n                                goto Lnomatch;\n                        }\n                    }\n                    else if (e1 && t2 && t2.ty == Tident)\n                    {\n                        j = templateParameterLookup(t2, parameters);\n                    L1:\n                        if (j == IDX_NOTFOUND)\n                        {\n                            t2.resolve((cast(TypeIdentifier)t2).loc, sc, &e2, &t2, &s2);\n                            if (e2)\n                                goto Le;\n                            goto Lnomatch;\n                        }\n                        if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null))\n                            goto Lnomatch;\n                    }\n                    else if (s1 && s2)\n                    {\n                    Ls:\n                        if (!s1.equals(s2))\n                            goto Lnomatch;\n                    }\n                    else if (s1 && t2 && t2.ty == Tident)\n                    {\n                        j = templateParameterLookup(t2, parameters);\n                        if (j == IDX_NOTFOUND)\n                        {\n                            t2.resolve((cast(TypeIdentifier)t2).loc, sc, &e2, &t2, &s2);\n                            if (s2)\n                                goto Ls;\n                            goto Lnomatch;\n                        }\n                        if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null))\n                            goto Lnomatch;\n                    }\n                    else\n                        goto Lnomatch;\n                }\n            }\n            visit(cast(Type)t);\n            return;\n\n        Lnomatch:\n            //printf(\"no match\\n\");\n            result = MATCH.nomatch;\n        }\n\n        override void visit(TypeStruct t)\n        {\n            /* If this struct is a template struct, and we're matching\n             * it against a template instance, convert the struct type\n             * to a template instance, too, and try again.\n             */\n            TemplateInstance ti = t.sym.parent.isTemplateInstance();\n\n            if (tparam && tparam.ty == Tinstance)\n            {\n                if (ti && ti.toAlias() == t.sym)\n                {\n                    auto tx = new TypeInstance(Loc.initial, ti);\n                    result = deduceType(tx, sc, tparam, parameters, dedtypes, wm);\n                    return;\n                }\n\n                /* Match things like:\n                 *  S!(T).foo\n                 */\n                TypeInstance tpi = cast(TypeInstance)tparam;\n                if (tpi.idents.dim)\n                {\n                    RootObject id = tpi.idents[tpi.idents.dim - 1];\n                    if (id.dyncast() == DYNCAST.identifier && t.sym.ident.equals(cast(Identifier)id))\n                    {\n                        Type tparent = t.sym.parent.getType();\n                        if (tparent)\n                        {\n                            /* Slice off the .foo in S!(T).foo\n                             */\n                            tpi.idents.dim--;\n                            result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm);\n                            tpi.idents.dim++;\n                            return;\n                        }\n                    }\n                }\n            }\n\n            // Extra check\n            if (tparam && tparam.ty == Tstruct)\n            {\n                TypeStruct tp = cast(TypeStruct)tparam;\n\n                //printf(\"\\t%d\\n\", (MATCH) t.implicitConvTo(tp));\n                if (wm && t.deduceWild(tparam, false))\n                {\n                    result = MATCH.constant;\n                    return;\n                }\n                result = t.implicitConvTo(tp);\n                return;\n            }\n            visit(cast(Type)t);\n        }\n\n        override void visit(TypeEnum t)\n        {\n            // Extra check\n            if (tparam && tparam.ty == Tenum)\n            {\n                TypeEnum tp = cast(TypeEnum)tparam;\n                if (t.sym == tp.sym)\n                    visit(cast(Type)t);\n                else\n                    result = MATCH.nomatch;\n                return;\n            }\n            Type tb = t.toBasetype();\n            if (tb.ty == tparam.ty || tb.ty == Tsarray && tparam.ty == Taarray)\n            {\n                result = deduceType(tb, sc, tparam, parameters, dedtypes, wm);\n                return;\n            }\n            visit(cast(Type)t);\n        }\n\n        /* Helper for TypeClass.deduceType().\n         * Classes can match with implicit conversion to a base class or interface.\n         * This is complicated, because there may be more than one base class which\n         * matches. In such cases, one or more parameters remain ambiguous.\n         * For example,\n         *\n         *   interface I(X, Y) {}\n         *   class C : I(uint, double), I(char, double) {}\n         *   C x;\n         *   foo(T, U)( I!(T, U) x)\n         *\n         *   deduces that U is double, but T remains ambiguous (could be char or uint).\n         *\n         * Given a baseclass b, and initial deduced types 'dedtypes', this function\n         * tries to match tparam with b, and also tries all base interfaces of b.\n         * If a match occurs, numBaseClassMatches is incremented, and the new deduced\n         * types are ANDed with the current 'best' estimate for dedtypes.\n         */\n        static void deduceBaseClassParameters(ref BaseClass b, Scope* sc, Type tparam, TemplateParameters* parameters, Objects* dedtypes, Objects* best, ref int numBaseClassMatches)\n        {\n            TemplateInstance parti = b.sym ? b.sym.parent.isTemplateInstance() : null;\n            if (parti)\n            {\n                // Make a temporary copy of dedtypes so we don't destroy it\n                auto tmpdedtypes = new Objects(dedtypes.dim);\n                memcpy(tmpdedtypes.tdata(), dedtypes.tdata(), dedtypes.dim * (void*).sizeof);\n\n                auto t = new TypeInstance(Loc.initial, parti);\n                MATCH m = deduceType(t, sc, tparam, parameters, tmpdedtypes);\n                if (m > MATCH.nomatch)\n                {\n                    // If this is the first ever match, it becomes our best estimate\n                    if (numBaseClassMatches == 0)\n                        memcpy(best.tdata(), tmpdedtypes.tdata(), tmpdedtypes.dim * (void*).sizeof);\n                    else\n                        for (size_t k = 0; k < tmpdedtypes.dim; ++k)\n                        {\n                            // If we've found more than one possible type for a parameter,\n                            // mark it as unknown.\n                            if ((*tmpdedtypes)[k] != (*best)[k])\n                                (*best)[k] = (*dedtypes)[k];\n                        }\n                    ++numBaseClassMatches;\n                }\n            }\n\n            // Now recursively test the inherited interfaces\n            foreach (ref bi; b.baseInterfaces)\n            {\n                deduceBaseClassParameters(bi, sc, tparam, parameters, dedtypes, best, numBaseClassMatches);\n            }\n        }\n\n        override void visit(TypeClass t)\n        {\n            //printf(\"TypeClass.deduceType(this = %s)\\n\", t.toChars());\n\n            /* If this class is a template class, and we're matching\n             * it against a template instance, convert the class type\n             * to a template instance, too, and try again.\n             */\n            TemplateInstance ti = t.sym.parent.isTemplateInstance();\n\n            if (tparam && tparam.ty == Tinstance)\n            {\n                if (ti && ti.toAlias() == t.sym)\n                {\n                    auto tx = new TypeInstance(Loc.initial, ti);\n                    MATCH m = deduceType(tx, sc, tparam, parameters, dedtypes, wm);\n                    // Even if the match fails, there is still a chance it could match\n                    // a base class.\n                    if (m != MATCH.nomatch)\n                    {\n                        result = m;\n                        return;\n                    }\n                }\n\n                /* Match things like:\n                 *  S!(T).foo\n                 */\n                TypeInstance tpi = cast(TypeInstance)tparam;\n                if (tpi.idents.dim)\n                {\n                    RootObject id = tpi.idents[tpi.idents.dim - 1];\n                    if (id.dyncast() == DYNCAST.identifier && t.sym.ident.equals(cast(Identifier)id))\n                    {\n                        Type tparent = t.sym.parent.getType();\n                        if (tparent)\n                        {\n                            /* Slice off the .foo in S!(T).foo\n                             */\n                            tpi.idents.dim--;\n                            result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm);\n                            tpi.idents.dim++;\n                            return;\n                        }\n                    }\n                }\n\n                // If it matches exactly or via implicit conversion, we're done\n                visit(cast(Type)t);\n                if (result != MATCH.nomatch)\n                    return;\n\n                /* There is still a chance to match via implicit conversion to\n                 * a base class or interface. Because there could be more than one such\n                 * match, we need to check them all.\n                 */\n\n                int numBaseClassMatches = 0; // Have we found an interface match?\n\n                // Our best guess at dedtypes\n                auto best = new Objects(dedtypes.dim);\n\n                ClassDeclaration s = t.sym;\n                while (s && s.baseclasses.dim > 0)\n                {\n                    // Test the base class\n                    deduceBaseClassParameters(*(*s.baseclasses)[0], sc, tparam, parameters, dedtypes, best, numBaseClassMatches);\n\n                    // Test the interfaces inherited by the base class\n                    foreach (b; s.interfaces)\n                    {\n                        deduceBaseClassParameters(*b, sc, tparam, parameters, dedtypes, best, numBaseClassMatches);\n                    }\n                    s = (*s.baseclasses)[0].sym;\n                }\n\n                if (numBaseClassMatches == 0)\n                {\n                    result = MATCH.nomatch;\n                    return;\n                }\n\n                // If we got at least one match, copy the known types into dedtypes\n                memcpy(dedtypes.tdata(), best.tdata(), best.dim * (void*).sizeof);\n                result = MATCH.convert;\n                return;\n            }\n\n            // Extra check\n            if (tparam && tparam.ty == Tclass)\n            {\n                TypeClass tp = cast(TypeClass)tparam;\n\n                //printf(\"\\t%d\\n\", (MATCH) t.implicitConvTo(tp));\n                if (wm && t.deduceWild(tparam, false))\n                {\n                    result = MATCH.constant;\n                    return;\n                }\n                result = t.implicitConvTo(tp);\n                return;\n            }\n            visit(cast(Type)t);\n        }\n\n        override void visit(Expression e)\n        {\n            //printf(\"Expression.deduceType(e = %s)\\n\", e.toChars());\n            size_t i = templateParameterLookup(tparam, parameters);\n            if (i == IDX_NOTFOUND || (cast(TypeIdentifier)tparam).idents.dim > 0)\n            {\n                if (e == emptyArrayElement && tparam.ty == Tarray)\n                {\n                    Type tn = (cast(TypeNext)tparam).next;\n                    result = deduceType(emptyArrayElement, sc, tn, parameters, dedtypes, wm);\n                    return;\n                }\n                e.type.accept(this);\n                return;\n            }\n\n            TemplateTypeParameter tp = (*parameters)[i].isTemplateTypeParameter();\n            if (!tp)\n                return; // nomatch\n\n            if (e == emptyArrayElement)\n            {\n                if ((*dedtypes)[i])\n                {\n                    result = MATCH.exact;\n                    return;\n                }\n                if (tp.defaultType)\n                {\n                    tp.defaultType.accept(this);\n                    return;\n                }\n            }\n\n            /* Returns `true` if `t` is a reference type, or an array of reference types\n             */\n            bool isTopRef(Type t)\n            {\n                auto tb = t.baseElemOf();\n                return tb.ty == Tclass ||\n                       tb.ty == Taarray ||\n                       tb.ty == Tstruct && tb.hasPointers();\n            }\n\n            Type at = cast(Type)(*dedtypes)[i];\n            Type tt;\n            if (ubyte wx = deduceWildHelper(e.type, &tt, tparam))\n            {\n                *wm |= wx;\n                result = MATCH.constant;\n            }\n            else if (MATCH m = deduceTypeHelper(e.type, &tt, tparam))\n            {\n                result = m;\n            }\n            else if (!isTopRef(e.type))\n            {\n                /* https://issues.dlang.org/show_bug.cgi?id=15653\n                 * In IFTI, recognize top-qualifier conversions\n                 * through the value copy, e.g.\n                 *      int --> immutable(int)\n                 *      immutable(string[]) --> immutable(string)[]\n                 */\n                tt = e.type.mutableOf();\n                result = MATCH.convert;\n            }\n            else\n                return; // nomatch\n\n            // expression vs (none)\n            if (!at)\n            {\n                (*dedtypes)[i] = new TypeDeduced(tt, e, tparam);\n                return;\n            }\n\n            TypeDeduced xt = null;\n            if (at.ty == Tnone)\n            {\n                xt = cast(TypeDeduced)at;\n                at = xt.tded;\n            }\n\n            // From previous matched expressions to current deduced type\n            MATCH match1 = xt ? xt.matchAll(tt) : MATCH.nomatch;\n\n            // From current expressions to previous deduced type\n            Type pt = at.addMod(tparam.mod);\n            if (*wm)\n                pt = pt.substWildTo(*wm);\n            MATCH match2 = e.implicitConvTo(pt);\n\n            if (match1 > MATCH.nomatch && match2 > MATCH.nomatch)\n            {\n                if (at.implicitConvTo(tt) <= MATCH.nomatch)\n                    match1 = MATCH.nomatch; // Prefer at\n                else if (tt.implicitConvTo(at) <= MATCH.nomatch)\n                    match2 = MATCH.nomatch; // Prefer tt\n                else if (tt.isTypeBasic() && tt.ty == at.ty && tt.mod != at.mod)\n                {\n                    if (!tt.isMutable() && !at.isMutable())\n                        tt = tt.mutableOf().addMod(MODmerge(tt.mod, at.mod));\n                    else if (tt.isMutable())\n                    {\n                        if (at.mod == 0) // Prefer unshared\n                            match1 = MATCH.nomatch;\n                        else\n                            match2 = MATCH.nomatch;\n                    }\n                    else if (at.isMutable())\n                    {\n                        if (tt.mod == 0) // Prefer unshared\n                            match2 = MATCH.nomatch;\n                        else\n                            match1 = MATCH.nomatch;\n                    }\n                    //printf(\"tt = %s, at = %s\\n\", tt.toChars(), at.toChars());\n                }\n                else\n                {\n                    match1 = MATCH.nomatch;\n                    match2 = MATCH.nomatch;\n                }\n            }\n            if (match1 > MATCH.nomatch)\n            {\n                // Prefer current match: tt\n                if (xt)\n                    xt.update(tt, e, tparam);\n                else\n                    (*dedtypes)[i] = tt;\n                result = match1;\n                return;\n            }\n            if (match2 > MATCH.nomatch)\n            {\n                // Prefer previous match: (*dedtypes)[i]\n                if (xt)\n                    xt.update(e, tparam);\n                result = match2;\n                return;\n            }\n\n            /* Deduce common type\n             */\n            if (Type t = rawTypeMerge(at, tt))\n            {\n                if (xt)\n                    xt.update(t, e, tparam);\n                else\n                    (*dedtypes)[i] = t;\n\n                pt = tt.addMod(tparam.mod);\n                if (*wm)\n                    pt = pt.substWildTo(*wm);\n                result = e.implicitConvTo(pt);\n                return;\n            }\n\n            result = MATCH.nomatch;\n        }\n\n        MATCH deduceEmptyArrayElement()\n        {\n            if (!emptyArrayElement)\n            {\n                emptyArrayElement = new IdentifierExp(Loc.initial, Id.p); // dummy\n                emptyArrayElement.type = Type.tvoid;\n            }\n            assert(tparam.ty == Tarray);\n\n            Type tn = (cast(TypeNext)tparam).next;\n            return deduceType(emptyArrayElement, sc, tn, parameters, dedtypes, wm);\n        }\n\n        override void visit(NullExp e)\n        {\n            if (tparam.ty == Tarray && e.type.ty == Tnull)\n            {\n                // tparam:T[] <- e:null (void[])\n                result = deduceEmptyArrayElement();\n                return;\n            }\n            visit(cast(Expression)e);\n        }\n\n        override void visit(StringExp e)\n        {\n            Type taai;\n            if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))\n            {\n                // Consider compile-time known boundaries\n                e.type.nextOf().sarrayOf(e.len).accept(this);\n                return;\n            }\n            visit(cast(Expression)e);\n        }\n\n        override void visit(ArrayLiteralExp e)\n        {\n            if ((!e.elements || !e.elements.dim) && e.type.toBasetype().nextOf().ty == Tvoid && tparam.ty == Tarray)\n            {\n                // tparam:T[] <- e:[] (void[])\n                result = deduceEmptyArrayElement();\n                return;\n            }\n\n            if (tparam.ty == Tarray && e.elements && e.elements.dim)\n            {\n                Type tn = (cast(TypeDArray)tparam).next;\n                result = MATCH.exact;\n                if (e.basis)\n                {\n                    MATCH m = deduceType(e.basis, sc, tn, parameters, dedtypes, wm);\n                    if (m < result)\n                        result = m;\n                }\n                for (size_t i = 0; i < e.elements.dim; i++)\n                {\n                    if (result <= MATCH.nomatch)\n                        break;\n                    auto el = (*e.elements)[i];\n                    if (!el)\n                        continue;\n                    MATCH m = deduceType(el, sc, tn, parameters, dedtypes, wm);\n                    if (m < result)\n                        result = m;\n                }\n                return;\n            }\n\n            Type taai;\n            if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))\n            {\n                // Consider compile-time known boundaries\n                e.type.nextOf().sarrayOf(e.elements.dim).accept(this);\n                return;\n            }\n            visit(cast(Expression)e);\n        }\n\n        override void visit(AssocArrayLiteralExp e)\n        {\n            if (tparam.ty == Taarray && e.keys && e.keys.dim)\n            {\n                TypeAArray taa = cast(TypeAArray)tparam;\n                result = MATCH.exact;\n                for (size_t i = 0; i < e.keys.dim; i++)\n                {\n                    MATCH m1 = deduceType((*e.keys)[i], sc, taa.index, parameters, dedtypes, wm);\n                    if (m1 < result)\n                        result = m1;\n                    if (result <= MATCH.nomatch)\n                        break;\n                    MATCH m2 = deduceType((*e.values)[i], sc, taa.next, parameters, dedtypes, wm);\n                    if (m2 < result)\n                        result = m2;\n                    if (result <= MATCH.nomatch)\n                        break;\n                }\n                return;\n            }\n            visit(cast(Expression)e);\n        }\n\n        override void visit(FuncExp e)\n        {\n            //printf(\"e.type = %s, tparam = %s\\n\", e.type.toChars(), tparam.toChars());\n            if (e.td)\n            {\n                Type to = tparam;\n                if (!to.nextOf() || to.nextOf().ty != Tfunction)\n                    return;\n                TypeFunction tof = cast(TypeFunction)to.nextOf();\n\n                // Parameter types inference from 'tof'\n                assert(e.td._scope);\n                TypeFunction tf = cast(TypeFunction)e.fd.type;\n                //printf(\"\\ttof = %s\\n\", tof.toChars());\n                //printf(\"\\ttf  = %s\\n\", tf.toChars());\n                size_t dim = Parameter.dim(tf.parameters);\n\n                if (Parameter.dim(tof.parameters) != dim || tof.varargs != tf.varargs)\n                    return;\n\n                auto tiargs = new Objects();\n                tiargs.reserve(e.td.parameters.dim);\n\n                for (size_t i = 0; i < e.td.parameters.dim; i++)\n                {\n                    TemplateParameter tp = (*e.td.parameters)[i];\n                    size_t u = 0;\n                    for (; u < dim; u++)\n                    {\n                        Parameter p = Parameter.getNth(tf.parameters, u);\n                        if (p.type.ty == Tident && (cast(TypeIdentifier)p.type).ident == tp.ident)\n                        {\n                            break;\n                        }\n                    }\n                    assert(u < dim);\n                    Parameter pto = Parameter.getNth(tof.parameters, u);\n                    if (!pto)\n                        break;\n                    Type t = pto.type.syntaxCopy(); // https://issues.dlang.org/show_bug.cgi?id=11774\n                    if (reliesOnTident(t, parameters, inferStart))\n                        return;\n                    t = t.typeSemantic(e.loc, sc);\n                    if (t.ty == Terror)\n                        return;\n                    tiargs.push(t);\n                }\n\n                // Set target of return type inference\n                if (!tf.next && tof.next)\n                    e.fd.treq = tparam;\n\n                auto ti = new TemplateInstance(e.loc, e.td, tiargs);\n                Expression ex = (new ScopeExp(e.loc, ti)).expressionSemantic(e.td._scope);\n\n                // Reset inference target for the later re-semantic\n                e.fd.treq = null;\n\n                if (ex.op == TOK.error)\n                    return;\n                if (ex.op != TOK.function_)\n                    return;\n                visit(ex.type);\n                return;\n            }\n\n            Type t = e.type;\n\n            if (t.ty == Tdelegate && tparam.ty == Tpointer)\n                return;\n\n            // Allow conversion from implicit function pointer to delegate\n            if (e.tok == TOK.reserved && t.ty == Tpointer && tparam.ty == Tdelegate)\n            {\n                TypeFunction tf = cast(TypeFunction)t.nextOf();\n                t = (new TypeDelegate(tf)).merge();\n            }\n            //printf(\"tparam = %s <= e.type = %s, t = %s\\n\", tparam.toChars(), e.type.toChars(), t.toChars());\n            visit(t);\n        }\n\n        override void visit(SliceExp e)\n        {\n            Type taai;\n            if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))\n            {\n                // Consider compile-time known boundaries\n                if (Type tsa = toStaticArrayType(e))\n                {\n                    tsa.accept(this);\n                    return;\n                }\n            }\n            visit(cast(Expression)e);\n        }\n\n        override void visit(CommaExp e)\n        {\n            e.e2.accept(this);\n        }\n    }\n\n    scope DeduceType v = new DeduceType(sc, tparam, parameters, dedtypes, wm, inferStart);\n    if (Type t = isType(o))\n        t.accept(v);\n    else\n    {\n        assert(isExpression(o) && wm);\n        (cast(Expression)o).accept(v);\n    }\n    return v.result;\n}\n\n/***********************************************************\n * Check whether the type t representation relies on one or more the template parameters.\n * Params:\n *      t           = Tested type, if null, returns false.\n *      tparams     = Template parameters.\n *      iStart      = Start index of tparams to limit the tested parameters. If it's\n *                    nonzero, tparams[0..iStart] will be excluded from the test target.\n */\nbool reliesOnTident(Type t, TemplateParameters* tparams = null, size_t iStart = 0)\n{\n    extern (C++) final class ReliesOnTident : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        TemplateParameters* tparams;\n        size_t iStart;\n        bool result;\n\n        extern (D) this(TemplateParameters* tparams, size_t iStart)\n        {\n            this.tparams = tparams;\n            this.iStart = iStart;\n        }\n\n        override void visit(Type t)\n        {\n        }\n\n        override void visit(TypeNext t)\n        {\n            t.next.accept(this);\n        }\n\n        override void visit(TypeVector t)\n        {\n            t.basetype.accept(this);\n        }\n\n        override void visit(TypeAArray t)\n        {\n            visit(cast(TypeNext)t);\n            if (!result)\n                t.index.accept(this);\n        }\n\n        override void visit(TypeFunction t)\n        {\n            size_t dim = Parameter.dim(t.parameters);\n            for (size_t i = 0; i < dim; i++)\n            {\n                Parameter fparam = Parameter.getNth(t.parameters, i);\n                fparam.type.accept(this);\n                if (result)\n                    return;\n            }\n            if (t.next)\n                t.next.accept(this);\n        }\n\n        override void visit(TypeIdentifier t)\n        {\n            for (size_t i = iStart; i < tparams.dim; i++)\n            {\n                TemplateParameter tp = (*tparams)[i];\n                if (tp.ident.equals(t.ident))\n                {\n                    result = true;\n                    return;\n                }\n            }\n        }\n\n        override void visit(TypeInstance t)\n        {\n            for (size_t i = iStart; i < tparams.dim; i++)\n            {\n                TemplateParameter tp = (*tparams)[i];\n                if (t.tempinst.name == tp.ident)\n                {\n                    result = true;\n                    return;\n                }\n            }\n            if (!t.tempinst.tiargs)\n                return;\n            for (size_t i = 0; i < t.tempinst.tiargs.dim; i++)\n            {\n                Type ta = isType((*t.tempinst.tiargs)[i]);\n                if (ta)\n                {\n                    ta.accept(this);\n                    if (result)\n                        return;\n                }\n            }\n        }\n\n        override void visit(TypeTypeof t)\n        {\n            //printf(\"TypeTypeof.reliesOnTident('%s')\\n\", t.toChars());\n            t.exp.accept(this);\n        }\n\n        override void visit(TypeTuple t)\n        {\n            if (t.arguments)\n            {\n                for (size_t i = 0; i < t.arguments.dim; i++)\n                {\n                    Parameter arg = (*t.arguments)[i];\n                    arg.type.accept(this);\n                    if (result)\n                        return;\n                }\n            }\n        }\n\n        override void visit(Expression e)\n        {\n            //printf(\"Expression.reliesOnTident('%s')\\n\", e.toChars());\n        }\n\n        override void visit(IdentifierExp e)\n        {\n            //printf(\"IdentifierExp.reliesOnTident('%s')\\n\", e.toChars());\n            for (size_t i = iStart; i < tparams.dim; i++)\n            {\n                auto tp = (*tparams)[i];\n                if (e.ident == tp.ident)\n                {\n                    result = true;\n                    return;\n                }\n            }\n        }\n\n        override void visit(TupleExp e)\n        {\n            //printf(\"TupleExp.reliesOnTident('%s')\\n\", e.toChars());\n            if (e.exps)\n            {\n                foreach (ea; *e.exps)\n                {\n                    ea.accept(this);\n                    if (result)\n                        return;\n                }\n            }\n        }\n\n        override void visit(ArrayLiteralExp e)\n        {\n            //printf(\"ArrayLiteralExp.reliesOnTident('%s')\\n\", e.toChars());\n            if (e.elements)\n            {\n                foreach (el; *e.elements)\n                {\n                    el.accept(this);\n                    if (result)\n                        return;\n                }\n            }\n        }\n\n        override void visit(AssocArrayLiteralExp e)\n        {\n            //printf(\"AssocArrayLiteralExp.reliesOnTident('%s')\\n\", e.toChars());\n            foreach (ek; *e.keys)\n            {\n                ek.accept(this);\n                if (result)\n                    return;\n            }\n            foreach (ev; *e.values)\n            {\n                ev.accept(this);\n                if (result)\n                    return;\n            }\n        }\n\n        override void visit(StructLiteralExp e)\n        {\n            //printf(\"StructLiteralExp.reliesOnTident('%s')\\n\", e.toChars());\n            if (e.elements)\n            {\n                foreach (ea; *e.elements)\n                {\n                    ea.accept(this);\n                    if (result)\n                        return;\n                }\n            }\n        }\n\n        override void visit(TypeExp e)\n        {\n            //printf(\"TypeExp.reliesOnTident('%s')\\n\", e.toChars());\n            e.type.accept(this);\n        }\n\n        override void visit(NewExp e)\n        {\n            //printf(\"NewExp.reliesOnTident('%s')\\n\", e.toChars());\n            if (e.thisexp)\n                e.thisexp.accept(this);\n            if (!result && e.newargs)\n            {\n                foreach (ea; *e.newargs)\n                {\n                    ea.accept(this);\n                    if (result)\n                        return;\n                }\n            }\n            e.newtype.accept(this);\n            if (!result && e.arguments)\n            {\n                foreach (ea; *e.arguments)\n                {\n                    ea.accept(this);\n                    if (result)\n                        return;\n                }\n            }\n        }\n\n        override void visit(NewAnonClassExp e)\n        {\n            //printf(\"NewAnonClassExp.reliesOnTident('%s')\\n\", e.toChars());\n            result = true;\n        }\n\n        override void visit(FuncExp e)\n        {\n            //printf(\"FuncExp.reliesOnTident('%s')\\n\", e.toChars());\n            result = true;\n        }\n\n        override void visit(TypeidExp e)\n        {\n            //printf(\"TypeidExp.reliesOnTident('%s')\\n\", e.toChars());\n            if (auto ea = isExpression(e.obj))\n                ea.accept(this);\n            else if (auto ta = isType(e.obj))\n                ta.accept(this);\n        }\n\n        override void visit(TraitsExp e)\n        {\n            //printf(\"TraitsExp.reliesOnTident('%s')\\n\", e.toChars());\n            if (e.args)\n            {\n                foreach (oa; *e.args)\n                {\n                    if (auto ea = isExpression(oa))\n                        ea.accept(this);\n                    else if (auto ta = isType(oa))\n                        ta.accept(this);\n                    if (result)\n                        return;\n                }\n            }\n        }\n\n        override void visit(IsExp e)\n        {\n            //printf(\"IsExp.reliesOnTident('%s')\\n\", e.toChars());\n            e.targ.accept(this);\n        }\n\n        override void visit(UnaExp e)\n        {\n            //printf(\"UnaExp.reliesOnTident('%s')\\n\", e.toChars());\n            e.e1.accept(this);\n        }\n\n        override void visit(DotTemplateInstanceExp e)\n        {\n            //printf(\"DotTemplateInstanceExp.reliesOnTident('%s')\\n\", e.toChars());\n            visit(cast(UnaExp)e);\n            if (!result && e.ti.tiargs)\n            {\n                foreach (oa; *e.ti.tiargs)\n                {\n                    if (auto ea = isExpression(oa))\n                        ea.accept(this);\n                    else if (auto ta = isType(oa))\n                        ta.accept(this);\n                    if (result)\n                        return;\n                }\n            }\n        }\n\n        override void visit(CallExp e)\n        {\n            //printf(\"CallExp.reliesOnTident('%s')\\n\", e.toChars());\n            visit(cast(UnaExp)e);\n            if (!result && e.arguments)\n            {\n                foreach (ea; *e.arguments)\n                {\n                    ea.accept(this);\n                    if (result)\n                        return;\n                }\n            }\n        }\n\n        override void visit(CastExp e)\n        {\n            //printf(\"CallExp.reliesOnTident('%s')\\n\", e.toChars());\n            visit(cast(UnaExp)e);\n            // e.to can be null for cast() with no type\n            if (!result && e.to)\n                e.to.accept(this);\n        }\n\n        override void visit(SliceExp e)\n        {\n            //printf(\"SliceExp.reliesOnTident('%s')\\n\", e.toChars());\n            visit(cast(UnaExp)e);\n            if (!result && e.lwr)\n                e.lwr.accept(this);\n            if (!result && e.upr)\n                e.upr.accept(this);\n        }\n\n        override void visit(IntervalExp e)\n        {\n            //printf(\"IntervalExp.reliesOnTident('%s')\\n\", e.toChars());\n            e.lwr.accept(this);\n            if (!result)\n                e.upr.accept(this);\n        }\n\n        override void visit(ArrayExp e)\n        {\n            //printf(\"ArrayExp.reliesOnTident('%s')\\n\", e.toChars());\n            visit(cast(UnaExp)e);\n            if (!result && e.arguments)\n            {\n                foreach (ea; *e.arguments)\n                    ea.accept(this);\n            }\n        }\n\n        override void visit(BinExp e)\n        {\n            //printf(\"BinExp.reliesOnTident('%s')\\n\", e.toChars());\n            e.e1.accept(this);\n            if (!result)\n                e.e2.accept(this);\n        }\n\n        override void visit(CondExp e)\n        {\n            //printf(\"BinExp.reliesOnTident('%s')\\n\", e.toChars());\n            e.econd.accept(this);\n            if (!result)\n                visit(cast(BinExp)e);\n        }\n    }\n\n    if (!t)\n        return false;\n\n    assert(tparams);\n    scope ReliesOnTident v = new ReliesOnTident(tparams, iStart);\n    t.accept(v);\n    return v.result;\n}\n\n/***********************************************************\n */\nextern (C++) class TemplateParameter : RootObject\n{\n    Loc loc;\n    Identifier ident;\n\n    /* True if this is a part of precedent parameter specialization pattern.\n     *\n     *  template A(T : X!TL, alias X, TL...) {}\n     *  // X and TL are dependent template parameter\n     *\n     * A dependent template parameter should return MATCH.exact in matchArg()\n     * to respect the match level of the corresponding precedent parameter.\n     */\n    bool dependent;\n\n    /* ======================== TemplateParameter =============================== */\n    extern (D) this(const ref Loc loc, Identifier ident)\n    {\n        this.loc = loc;\n        this.ident = ident;\n    }\n\n    TemplateTypeParameter isTemplateTypeParameter()\n    {\n        return null;\n    }\n\n    TemplateValueParameter isTemplateValueParameter()\n    {\n        return null;\n    }\n\n    TemplateAliasParameter isTemplateAliasParameter()\n    {\n        return null;\n    }\n\n    TemplateThisParameter isTemplateThisParameter()\n    {\n        return null;\n    }\n\n    TemplateTupleParameter isTemplateTupleParameter()\n    {\n        return null;\n    }\n\n    abstract TemplateParameter syntaxCopy();\n\n    abstract bool declareParameter(Scope* sc);\n\n    abstract void print(RootObject oarg, RootObject oded);\n\n    abstract RootObject specialization();\n\n    abstract RootObject defaultArg(Loc instLoc, Scope* sc);\n\n    abstract bool hasDefaultArg();\n\n    override const(char)* toChars() { return this.ident.toChars(); }\n    override DYNCAST dyncast() const pure @nogc nothrow @safe\n    {\n        return DYNCAST.templateparameter;\n    }\n\n    /*******************************************\n     * Match to a particular TemplateParameter.\n     * Input:\n     *      instLoc         location that the template is instantiated.\n     *      tiargs[]        actual arguments to template instance\n     *      i               i'th argument\n     *      parameters[]    template parameters\n     *      dedtypes[]      deduced arguments to template instance\n     *      *psparam        set to symbol declared and initialized to dedtypes[i]\n     */\n    MATCH matchArg(Loc instLoc, Scope* sc, Objects* tiargs, size_t i, TemplateParameters* parameters, Objects* dedtypes, Declaration* psparam)\n    {\n        RootObject oarg;\n\n        if (i < tiargs.dim)\n            oarg = (*tiargs)[i];\n        else\n        {\n            // Get default argument instead\n            oarg = defaultArg(instLoc, sc);\n            if (!oarg)\n            {\n                assert(i < dedtypes.dim);\n                // It might have already been deduced\n                oarg = (*dedtypes)[i];\n                if (!oarg)\n                    goto Lnomatch;\n            }\n        }\n        return matchArg(sc, oarg, i, parameters, dedtypes, psparam);\n\n    Lnomatch:\n        if (psparam)\n            *psparam = null;\n        return MATCH.nomatch;\n    }\n\n    abstract MATCH matchArg(Scope* sc, RootObject oarg, size_t i, TemplateParameters* parameters, Objects* dedtypes, Declaration* psparam);\n\n    /* Create dummy argument based on parameter.\n     */\n    abstract void* dummyArg();\n\n    void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Syntax:\n *  ident : specType = defaultType\n */\nextern (C++) class TemplateTypeParameter : TemplateParameter\n{\n    Type specType;      // if !=null, this is the type specialization\n    Type defaultType;\n\n    extern (D) __gshared Type tdummy = null;\n\n    extern (D) this(const ref Loc loc, Identifier ident, Type specType, Type defaultType)\n    {\n        super(loc, ident);\n        this.ident = ident;\n        this.specType = specType;\n        this.defaultType = defaultType;\n    }\n\n    override final TemplateTypeParameter isTemplateTypeParameter()\n    {\n        return this;\n    }\n\n    override TemplateParameter syntaxCopy()\n    {\n        return new TemplateTypeParameter(loc, ident, specType ? specType.syntaxCopy() : null, defaultType ? defaultType.syntaxCopy() : null);\n    }\n\n    override final bool declareParameter(Scope* sc)\n    {\n        //printf(\"TemplateTypeParameter.declareParameter('%s')\\n\", ident.toChars());\n        auto ti = new TypeIdentifier(loc, ident);\n        Declaration ad = new AliasDeclaration(loc, ident, ti);\n        return sc.insert(ad) !is null;\n    }\n\n    override final void print(RootObject oarg, RootObject oded)\n    {\n        printf(\" %s\\n\", ident.toChars());\n\n        Type t = isType(oarg);\n        Type ta = isType(oded);\n        assert(ta);\n\n        if (specType)\n            printf(\"\\tSpecialization: %s\\n\", specType.toChars());\n        if (defaultType)\n            printf(\"\\tDefault:        %s\\n\", defaultType.toChars());\n        printf(\"\\tParameter:       %s\\n\", t ? t.toChars() : \"NULL\");\n        printf(\"\\tDeduced Type:   %s\\n\", ta.toChars());\n    }\n\n    override final RootObject specialization()\n    {\n        return specType;\n    }\n\n    override final RootObject defaultArg(Loc instLoc, Scope* sc)\n    {\n        Type t = defaultType;\n        if (t)\n        {\n            t = t.syntaxCopy();\n            t = t.typeSemantic(loc, sc); // use the parameter loc\n        }\n        return t;\n    }\n\n    override final bool hasDefaultArg()\n    {\n        return defaultType !is null;\n    }\n\n    override final MATCH matchArg(Scope* sc, RootObject oarg, size_t i, TemplateParameters* parameters, Objects* dedtypes, Declaration* psparam)\n    {\n        //printf(\"TemplateTypeParameter.matchArg('%s')\\n\", ident.toChars());\n        MATCH m = MATCH.exact;\n        Type ta = isType(oarg);\n        if (!ta)\n        {\n            //printf(\"%s %p %p %p\\n\", oarg.toChars(), isExpression(oarg), isDsymbol(oarg), isTuple(oarg));\n            goto Lnomatch;\n        }\n        //printf(\"ta is %s\\n\", ta.toChars());\n\n        if (specType)\n        {\n            if (!ta || ta == tdummy)\n                goto Lnomatch;\n\n            //printf(\"\\tcalling deduceType(): ta is %s, specType is %s\\n\", ta.toChars(), specType.toChars());\n            MATCH m2 = deduceType(ta, sc, specType, parameters, dedtypes);\n            if (m2 <= MATCH.nomatch)\n            {\n                //printf(\"\\tfailed deduceType\\n\");\n                goto Lnomatch;\n            }\n\n            if (m2 < m)\n                m = m2;\n            if ((*dedtypes)[i])\n            {\n                Type t = cast(Type)(*dedtypes)[i];\n\n                if (dependent && !t.equals(ta)) // https://issues.dlang.org/show_bug.cgi?id=14357\n                    goto Lnomatch;\n\n                /* This is a self-dependent parameter. For example:\n                 *  template X(T : T*) {}\n                 *  template X(T : S!T, alias S) {}\n                 */\n                //printf(\"t = %s ta = %s\\n\", t.toChars(), ta.toChars());\n                ta = t;\n            }\n        }\n        else\n        {\n            if ((*dedtypes)[i])\n            {\n                // Must match already deduced type\n                Type t = cast(Type)(*dedtypes)[i];\n\n                if (!t.equals(ta))\n                {\n                    //printf(\"t = %s ta = %s\\n\", t.toChars(), ta.toChars());\n                    goto Lnomatch;\n                }\n            }\n            else\n            {\n                // So that matches with specializations are better\n                m = MATCH.convert;\n            }\n        }\n        (*dedtypes)[i] = ta;\n\n        if (psparam)\n            *psparam = new AliasDeclaration(loc, ident, ta);\n        //printf(\"\\tm = %d\\n\", m);\n        return dependent ? MATCH.exact : m;\n\n    Lnomatch:\n        if (psparam)\n            *psparam = null;\n        //printf(\"\\tm = %d\\n\", MATCH.nomatch);\n        return MATCH.nomatch;\n    }\n\n    override final void* dummyArg()\n    {\n        Type t = specType;\n        if (!t)\n        {\n            // Use this for alias-parameter's too (?)\n            if (!tdummy)\n                tdummy = new TypeIdentifier(loc, ident);\n            t = tdummy;\n        }\n        return cast(void*)t;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Syntax:\n *  this ident : specType = defaultType\n */\nextern (C++) final class TemplateThisParameter : TemplateTypeParameter\n{\n    extern (D) this(const ref Loc loc, Identifier ident, Type specType, Type defaultType)\n    {\n        super(loc, ident, specType, defaultType);\n    }\n\n    override TemplateThisParameter isTemplateThisParameter()\n    {\n        return this;\n    }\n\n    override TemplateParameter syntaxCopy()\n    {\n        return new TemplateThisParameter(loc, ident, specType ? specType.syntaxCopy() : null, defaultType ? defaultType.syntaxCopy() : null);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Syntax:\n *  valType ident : specValue = defaultValue\n */\nextern (C++) final class TemplateValueParameter : TemplateParameter\n{\n    Type valType;\n    Expression specValue;\n    Expression defaultValue;\n\n    extern (D) __gshared Expression[void*] edummies;\n\n    extern (D) this(const ref Loc loc, Identifier ident, Type valType,\n        Expression specValue, Expression defaultValue)\n    {\n        super(loc, ident);\n        this.ident = ident;\n        this.valType = valType;\n        this.specValue = specValue;\n        this.defaultValue = defaultValue;\n    }\n\n    override TemplateValueParameter isTemplateValueParameter()\n    {\n        return this;\n    }\n\n    override TemplateParameter syntaxCopy()\n    {\n        return new TemplateValueParameter(loc, ident,\n            valType.syntaxCopy(),\n            specValue ? specValue.syntaxCopy() : null,\n            defaultValue ? defaultValue.syntaxCopy() : null);\n    }\n\n    override bool declareParameter(Scope* sc)\n    {\n        auto v = new VarDeclaration(loc, valType, ident, null);\n        v.storage_class = STC.templateparameter;\n        return sc.insert(v) !is null;\n    }\n\n    override void print(RootObject oarg, RootObject oded)\n    {\n        printf(\" %s\\n\", ident.toChars());\n        Expression ea = isExpression(oded);\n        if (specValue)\n            printf(\"\\tSpecialization: %s\\n\", specValue.toChars());\n        printf(\"\\tParameter Value: %s\\n\", ea ? ea.toChars() : \"NULL\");\n    }\n\n    override RootObject specialization()\n    {\n        return specValue;\n    }\n\n    override RootObject defaultArg(Loc instLoc, Scope* sc)\n    {\n        Expression e = defaultValue;\n        if (e)\n        {\n            e = e.syntaxCopy();\n            uint olderrs = global.errors;\n            if ((e = e.expressionSemantic(sc)) is null)\n                return null;\n            if ((e = resolveProperties(sc, e)) is null)\n                return null;\n            e = e.resolveLoc(instLoc, sc); // use the instantiated loc\n            e = e.optimize(WANTvalue);\n            if (global.errors != olderrs)\n                e = new ErrorExp();\n        }\n        return e;\n    }\n\n    override bool hasDefaultArg()\n    {\n        return defaultValue !is null;\n    }\n\n    override MATCH matchArg(Scope* sc, RootObject oarg,\n        size_t i, TemplateParameters* parameters, Objects* dedtypes,\n        Declaration* psparam)\n    {\n        //printf(\"TemplateValueParameter.matchArg('%s')\\n\", ident.toChars());\n\n        MATCH m = MATCH.exact;\n\n        Expression ei = isExpression(oarg);\n        Type vt;\n\n        if (!ei && oarg)\n        {\n            Dsymbol si = isDsymbol(oarg);\n            FuncDeclaration f = si ? si.isFuncDeclaration() : null;\n            if (!f || !f.fbody || f.needThis())\n                goto Lnomatch;\n\n            ei = new VarExp(loc, f);\n            ei = ei.expressionSemantic(sc);\n\n            /* If a function is really property-like, and then\n             * it's CTFEable, ei will be a literal expression.\n             */\n            uint olderrors = global.startGagging();\n            ei = resolveProperties(sc, ei);\n            ei = ei.ctfeInterpret();\n            if (global.endGagging(olderrors) || ei.op == TOK.error)\n                goto Lnomatch;\n\n            /* https://issues.dlang.org/show_bug.cgi?id=14520\n             * A property-like function can match to both\n             * TemplateAlias and ValueParameter. But for template overloads,\n             * it should always prefer alias parameter to be consistent\n             * template match result.\n             *\n             *   template X(alias f) { enum X = 1; }\n             *   template X(int val) { enum X = 2; }\n             *   int f1() { return 0; }  // CTFEable\n             *   int f2();               // body-less function is not CTFEable\n             *   enum x1 = X!f1;    // should be 1\n             *   enum x2 = X!f2;    // should be 1\n             *\n             * e.g. The x1 value must be same even if the f1 definition will be moved\n             *      into di while stripping body code.\n             */\n            m = MATCH.convert;\n        }\n\n        if (ei && ei.op == TOK.variable)\n        {\n            // Resolve const variables that we had skipped earlier\n            ei = ei.ctfeInterpret();\n        }\n\n        //printf(\"\\tvalType: %s, ty = %d\\n\", valType.toChars(), valType.ty);\n        vt = valType.typeSemantic(loc, sc);\n        //printf(\"ei: %s, ei.type: %s\\n\", ei.toChars(), ei.type.toChars());\n        //printf(\"vt = %s\\n\", vt.toChars());\n\n        if (ei.type)\n        {\n            MATCH m2 = ei.implicitConvTo(vt);\n            //printf(\"m: %d\\n\", m);\n            if (m2 < m)\n                m = m2;\n            if (m <= MATCH.nomatch)\n                goto Lnomatch;\n            ei = ei.implicitCastTo(sc, vt);\n            ei = ei.ctfeInterpret();\n        }\n\n        if (specValue)\n        {\n            if (ei is null || (cast(void*)ei.type in edummies && edummies[cast(void*)ei.type] == ei))\n                goto Lnomatch;\n\n            Expression e = specValue;\n\n            sc = sc.startCTFE();\n            e = e.expressionSemantic(sc);\n            e = resolveProperties(sc, e);\n            sc = sc.endCTFE();\n            e = e.implicitCastTo(sc, vt);\n            e = e.ctfeInterpret();\n\n            ei = ei.syntaxCopy();\n            sc = sc.startCTFE();\n            ei = ei.expressionSemantic(sc);\n            sc = sc.endCTFE();\n            ei = ei.implicitCastTo(sc, vt);\n            ei = ei.ctfeInterpret();\n            //printf(\"\\tei: %s, %s\\n\", ei.toChars(), ei.type.toChars());\n            //printf(\"\\te : %s, %s\\n\", e.toChars(), e.type.toChars());\n            if (!ei.equals(e))\n                goto Lnomatch;\n        }\n        else\n        {\n            if ((*dedtypes)[i])\n            {\n                // Must match already deduced value\n                Expression e = cast(Expression)(*dedtypes)[i];\n                if (!ei || !ei.equals(e))\n                    goto Lnomatch;\n            }\n        }\n        (*dedtypes)[i] = ei;\n\n        if (psparam)\n        {\n            Initializer _init = new ExpInitializer(loc, ei);\n            Declaration sparam = new VarDeclaration(loc, vt, ident, _init);\n            sparam.storage_class = STC.manifest;\n            *psparam = sparam;\n        }\n        return dependent ? MATCH.exact : m;\n\n    Lnomatch:\n        //printf(\"\\tno match\\n\");\n        if (psparam)\n            *psparam = null;\n        return MATCH.nomatch;\n    }\n\n    override void* dummyArg()\n    {\n        Expression e = specValue;\n        if (!e)\n        {\n            // Create a dummy value\n            auto pe = cast(void*)valType in edummies;\n            if (!pe)\n            {\n                e = valType.defaultInit(Loc.initial);\n                edummies[cast(void*)valType] = e;\n            }\n            else\n                e = *pe;\n        }\n        return cast(void*)e;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Syntax:\n *  specType ident : specAlias = defaultAlias\n */\nextern (C++) final class TemplateAliasParameter : TemplateParameter\n{\n    Type specType;\n    RootObject specAlias;\n    RootObject defaultAlias;\n\n    extern (D) __gshared Dsymbol sdummy = null;\n\n    extern (D) this(const ref Loc loc, Identifier ident, Type specType, RootObject specAlias, RootObject defaultAlias)\n    {\n        super(loc, ident);\n        this.ident = ident;\n        this.specType = specType;\n        this.specAlias = specAlias;\n        this.defaultAlias = defaultAlias;\n    }\n\n    override TemplateAliasParameter isTemplateAliasParameter()\n    {\n        return this;\n    }\n\n    override TemplateParameter syntaxCopy()\n    {\n        return new TemplateAliasParameter(loc, ident, specType ? specType.syntaxCopy() : null, objectSyntaxCopy(specAlias), objectSyntaxCopy(defaultAlias));\n    }\n\n    override bool declareParameter(Scope* sc)\n    {\n        auto ti = new TypeIdentifier(loc, ident);\n        Declaration ad = new AliasDeclaration(loc, ident, ti);\n        return sc.insert(ad) !is null;\n    }\n\n    override void print(RootObject oarg, RootObject oded)\n    {\n        printf(\" %s\\n\", ident.toChars());\n        Dsymbol sa = isDsymbol(oded);\n        assert(sa);\n        printf(\"\\tParameter alias: %s\\n\", sa.toChars());\n    }\n\n    override RootObject specialization()\n    {\n        return specAlias;\n    }\n\n    override RootObject defaultArg(Loc instLoc, Scope* sc)\n    {\n        RootObject da = defaultAlias;\n        Type ta = isType(defaultAlias);\n        if (ta)\n        {\n            if (ta.ty == Tinstance)\n            {\n                // If the default arg is a template, instantiate for each type\n                da = ta.syntaxCopy();\n            }\n        }\n\n        RootObject o = aliasParameterSemantic(loc, sc, da, null); // use the parameter loc\n        return o;\n    }\n\n    override bool hasDefaultArg()\n    {\n        return defaultAlias !is null;\n    }\n\n    override MATCH matchArg(Scope* sc, RootObject oarg, size_t i, TemplateParameters* parameters, Objects* dedtypes, Declaration* psparam)\n    {\n        //printf(\"TemplateAliasParameter.matchArg('%s')\\n\", ident.toChars());\n        MATCH m = MATCH.exact;\n        Type ta = isType(oarg);\n        RootObject sa = ta && !ta.deco ? null : getDsymbol(oarg);\n        Expression ea = isExpression(oarg);\n        if (ea && (ea.op == TOK.this_ || ea.op == TOK.super_))\n            sa = (cast(ThisExp)ea).var;\n        else if (ea && ea.op == TOK.scope_)\n            sa = (cast(ScopeExp)ea).sds;\n        if (sa)\n        {\n            if ((cast(Dsymbol)sa).isAggregateDeclaration())\n                m = MATCH.convert;\n\n            /* specType means the alias must be a declaration with a type\n             * that matches specType.\n             */\n            if (specType)\n            {\n                Declaration d = (cast(Dsymbol)sa).isDeclaration();\n                if (!d)\n                    goto Lnomatch;\n                if (!d.type.equals(specType))\n                    goto Lnomatch;\n            }\n        }\n        else\n        {\n            sa = oarg;\n            if (ea)\n            {\n                if (specType)\n                {\n                    if (!ea.type.equals(specType))\n                        goto Lnomatch;\n                }\n            }\n            else if (ta && ta.ty == Tinstance && !specAlias)\n            {\n                /* Specialized parameter should be preferred\n                 * match to the template type parameter.\n                 *  template X(alias a) {}                      // a == this\n                 *  template X(alias a : B!A, alias B, A...) {} // B!A => ta\n                 */\n            }\n            else if (sa && sa == TemplateTypeParameter.tdummy)\n            {\n                /* https://issues.dlang.org/show_bug.cgi?id=2025\n                 * Aggregate Types should preferentially\n                 * match to the template type parameter.\n                 *  template X(alias a) {}  // a == this\n                 *  template X(T) {}        // T => sa\n                 */\n            }\n            else\n                goto Lnomatch;\n        }\n\n        if (specAlias)\n        {\n            if (sa == sdummy)\n                goto Lnomatch;\n            Dsymbol sx = isDsymbol(sa);\n            if (sa != specAlias && sx)\n            {\n                Type talias = isType(specAlias);\n                if (!talias)\n                    goto Lnomatch;\n\n                TemplateInstance ti = sx.isTemplateInstance();\n                if (!ti && sx.parent)\n                {\n                    ti = sx.parent.isTemplateInstance();\n                    if (ti && ti.name != sx.ident)\n                        goto Lnomatch;\n                }\n                if (!ti)\n                    goto Lnomatch;\n\n                Type t = new TypeInstance(Loc.initial, ti);\n                MATCH m2 = deduceType(t, sc, talias, parameters, dedtypes);\n                if (m2 <= MATCH.nomatch)\n                    goto Lnomatch;\n            }\n        }\n        else if ((*dedtypes)[i])\n        {\n            // Must match already deduced symbol\n            RootObject si = (*dedtypes)[i];\n            if (!sa || si != sa)\n                goto Lnomatch;\n        }\n        (*dedtypes)[i] = sa;\n\n        if (psparam)\n        {\n            if (Dsymbol s = isDsymbol(sa))\n            {\n                *psparam = new AliasDeclaration(loc, ident, s);\n            }\n            else if (Type t = isType(sa))\n            {\n                *psparam = new AliasDeclaration(loc, ident, t);\n            }\n            else\n            {\n                assert(ea);\n\n                // Declare manifest constant\n                Initializer _init = new ExpInitializer(loc, ea);\n                auto v = new VarDeclaration(loc, null, ident, _init);\n                v.storage_class = STC.manifest;\n                v.dsymbolSemantic(sc);\n                *psparam = v;\n            }\n        }\n        return dependent ? MATCH.exact : m;\n\n    Lnomatch:\n        if (psparam)\n            *psparam = null;\n        //printf(\"\\tm = %d\\n\", MATCH.nomatch);\n        return MATCH.nomatch;\n    }\n\n    override void* dummyArg()\n    {\n        RootObject s = specAlias;\n        if (!s)\n        {\n            if (!sdummy)\n                sdummy = new Dsymbol();\n            s = sdummy;\n        }\n        return cast(void*)s;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Syntax:\n *  ident ...\n */\nextern (C++) final class TemplateTupleParameter : TemplateParameter\n{\n    extern (D) this(const ref Loc loc, Identifier ident)\n    {\n        super(loc, ident);\n        this.ident = ident;\n    }\n\n    override TemplateTupleParameter isTemplateTupleParameter()\n    {\n        return this;\n    }\n\n    override TemplateParameter syntaxCopy()\n    {\n        return new TemplateTupleParameter(loc, ident);\n    }\n\n    override bool declareParameter(Scope* sc)\n    {\n        auto ti = new TypeIdentifier(loc, ident);\n        Declaration ad = new AliasDeclaration(loc, ident, ti);\n        return sc.insert(ad) !is null;\n    }\n\n    override void print(RootObject oarg, RootObject oded)\n    {\n        printf(\" %s... [\", ident.toChars());\n        Tuple v = isTuple(oded);\n        assert(v);\n\n        //printf(\"|%d| \", v.objects.dim);\n        for (size_t i = 0; i < v.objects.dim; i++)\n        {\n            if (i)\n                printf(\", \");\n\n            RootObject o = v.objects[i];\n            Dsymbol sa = isDsymbol(o);\n            if (sa)\n                printf(\"alias: %s\", sa.toChars());\n            Type ta = isType(o);\n            if (ta)\n                printf(\"type: %s\", ta.toChars());\n            Expression ea = isExpression(o);\n            if (ea)\n                printf(\"exp: %s\", ea.toChars());\n\n            assert(!isTuple(o)); // no nested Tuple arguments\n        }\n        printf(\"]\\n\");\n    }\n\n    override RootObject specialization()\n    {\n        return null;\n    }\n\n    override RootObject defaultArg(Loc instLoc, Scope* sc)\n    {\n        return null;\n    }\n\n    override bool hasDefaultArg()\n    {\n        return false;\n    }\n\n    override MATCH matchArg(Loc instLoc, Scope* sc, Objects* tiargs, size_t i, TemplateParameters* parameters, Objects* dedtypes, Declaration* psparam)\n    {\n        /* The rest of the actual arguments (tiargs[]) form the match\n         * for the variadic parameter.\n         */\n        assert(i + 1 == dedtypes.dim); // must be the last one\n        Tuple ovar;\n\n        if (Tuple u = isTuple((*dedtypes)[i]))\n        {\n            // It has already been deduced\n            ovar = u;\n        }\n        else if (i + 1 == tiargs.dim && isTuple((*tiargs)[i]))\n            ovar = isTuple((*tiargs)[i]);\n        else\n        {\n            ovar = new Tuple();\n            //printf(\"ovar = %p\\n\", ovar);\n            if (i < tiargs.dim)\n            {\n                //printf(\"i = %d, tiargs.dim = %d\\n\", i, tiargs.dim);\n                ovar.objects.setDim(tiargs.dim - i);\n                for (size_t j = 0; j < ovar.objects.dim; j++)\n                    ovar.objects[j] = (*tiargs)[i + j];\n            }\n        }\n        return matchArg(sc, ovar, i, parameters, dedtypes, psparam);\n    }\n\n    override MATCH matchArg(Scope* sc, RootObject oarg, size_t i, TemplateParameters* parameters, Objects* dedtypes, Declaration* psparam)\n    {\n        //printf(\"TemplateTupleParameter.matchArg('%s')\\n\", ident.toChars());\n        Tuple ovar = isTuple(oarg);\n        if (!ovar)\n            return MATCH.nomatch;\n        if ((*dedtypes)[i])\n        {\n            Tuple tup = isTuple((*dedtypes)[i]);\n            if (!tup)\n                return MATCH.nomatch;\n            if (!match(tup, ovar))\n                return MATCH.nomatch;\n        }\n        (*dedtypes)[i] = ovar;\n\n        if (psparam)\n            *psparam = new TupleDeclaration(loc, ident, &ovar.objects);\n        return dependent ? MATCH.exact : MATCH.convert;\n    }\n\n    override void* dummyArg()\n    {\n        return null;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Given:\n *  foo!(args) =>\n *      name = foo\n *      tiargs = args\n */\nextern (C++) class TemplateInstance : ScopeDsymbol\n{\n    Identifier name;\n\n    // Array of Types/Expressions of template\n    // instance arguments [int*, char, 10*10]\n    Objects* tiargs;\n\n    // Array of Types/Expressions corresponding\n    // to TemplateDeclaration.parameters\n    // [int, char, 100]\n    Objects tdtypes;\n\n    Dsymbol tempdecl;           // referenced by foo.bar.abc\n    Dsymbol enclosing;          // if referencing local symbols, this is the context\n    Dsymbol aliasdecl;          // !=null if instance is an alias for its sole member\n    TemplateInstance inst;      // refer to existing instance\n    ScopeDsymbol argsym;        // argument symbol table\n    int inuse;                  // for recursive expansion detection\n    int nest;                   // for recursive pretty printing detection\n    bool semantictiargsdone;    // has semanticTiargs() been done?\n    bool havetempdecl;          // if used second constructor\n    bool gagged;                // if the instantiation is done with error gagging\n    hash_t hash;                // cached result of toHash()\n    Expressions* fargs;         // for function template, these are the function arguments\n\n    TemplateInstances* deferred;\n\n    Module memberOf;            // if !null, then this TemplateInstance appears in memberOf.members[]\n\n    // Used to determine the instance needs code generation.\n    // Note that these are inaccurate until semantic analysis phase completed.\n    TemplateInstance tinst;     // enclosing template instance\n    TemplateInstance tnext;     // non-first instantiated instances\n    Module minst;               // the top module that instantiated this instance\n\n    extern (D) this(const ref Loc loc, Identifier ident, Objects* tiargs)\n    {\n        super(null);\n        static if (LOG)\n        {\n            printf(\"TemplateInstance(this = %p, ident = '%s')\\n\", this, ident ? ident.toChars() : \"null\");\n        }\n        this.loc = loc;\n        this.name = ident;\n        this.tiargs = tiargs;\n    }\n\n    /*****************\n     * This constructor is only called when we figured out which function\n     * template to instantiate.\n     */\n    extern (D) this(const ref Loc loc, TemplateDeclaration td, Objects* tiargs)\n    {\n        super(null);\n        static if (LOG)\n        {\n            printf(\"TemplateInstance(this = %p, tempdecl = '%s')\\n\", this, td.toChars());\n        }\n        this.loc = loc;\n        this.name = td.ident;\n        this.tiargs = tiargs;\n        this.tempdecl = td;\n        this.semantictiargsdone = true;\n        this.havetempdecl = true;\n        assert(tempdecl._scope);\n    }\n\n    extern (D) static Objects* arraySyntaxCopy(Objects* objs)\n    {\n        Objects* a = null;\n        if (objs)\n        {\n            a = new Objects(objs.dim);\n            for (size_t i = 0; i < objs.dim; i++)\n                (*a)[i] = objectSyntaxCopy((*objs)[i]);\n        }\n        return a;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        TemplateInstance ti = s ? cast(TemplateInstance)s : new TemplateInstance(loc, name, null);\n        ti.tiargs = arraySyntaxCopy(tiargs);\n        TemplateDeclaration td;\n        if (inst && tempdecl && (td = tempdecl.isTemplateDeclaration()) !is null)\n            td.ScopeDsymbol.syntaxCopy(ti);\n        else\n            ScopeDsymbol.syntaxCopy(ti);\n        return ti;\n    }\n\n    // resolve real symbol\n    override final Dsymbol toAlias()\n    {\n        static if (LOG)\n        {\n            printf(\"TemplateInstance.toAlias()\\n\");\n        }\n        if (!inst)\n        {\n            // Maybe we can resolve it\n            if (_scope)\n            {\n                dsymbolSemantic(this, _scope);\n            }\n            if (!inst)\n            {\n                error(\"cannot resolve forward reference\");\n                errors = true;\n                return this;\n            }\n        }\n\n        if (inst != this)\n            return inst.toAlias();\n\n        if (aliasdecl)\n        {\n            return aliasdecl.toAlias();\n        }\n\n        return inst;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"template instance\";\n    }\n\n    override bool oneMember(Dsymbol* ps, Identifier ident)\n    {\n        *ps = null;\n        return true;\n    }\n\n    override const(char)* toChars()\n    {\n        OutBuffer buf;\n        toCBufferInstance(this, &buf);\n        return buf.extractString();\n    }\n\n    override final const(char)* toPrettyCharsHelper()\n    {\n        OutBuffer buf;\n        toCBufferInstance(this, &buf, true);\n        return buf.extractString();\n    }\n\n    /**************************************\n     * Given an error instantiating the TemplateInstance,\n     * give the nested TemplateInstance instantiations that got\n     * us here. Those are a list threaded into the nested scopes.\n     */\n    final void printInstantiationTrace()\n    {\n        if (global.gag)\n            return;\n\n        const(uint) max_shown = 6;\n        const(char)* format = \"instantiated from here: `%s`\";\n\n        // determine instantiation depth and number of recursive instantiations\n        int n_instantiations = 1;\n        int n_totalrecursions = 0;\n        for (TemplateInstance cur = this; cur; cur = cur.tinst)\n        {\n            ++n_instantiations;\n            // If two instantiations use the same declaration, they are recursive.\n            // (this works even if they are instantiated from different places in the\n            // same template).\n            // In principle, we could also check for multiple-template recursion, but it's\n            // probably not worthwhile.\n            if (cur.tinst && cur.tempdecl && cur.tinst.tempdecl && cur.tempdecl.loc.equals(cur.tinst.tempdecl.loc))\n                ++n_totalrecursions;\n        }\n\n        // show full trace only if it's short or verbose is on\n        if (n_instantiations <= max_shown || global.params.verbose)\n        {\n            for (TemplateInstance cur = this; cur; cur = cur.tinst)\n            {\n                cur.errors = true;\n                errorSupplemental(cur.loc, format, cur.toChars());\n            }\n        }\n        else if (n_instantiations - n_totalrecursions <= max_shown)\n        {\n            // By collapsing recursive instantiations into a single line,\n            // we can stay under the limit.\n            int recursionDepth = 0;\n            for (TemplateInstance cur = this; cur; cur = cur.tinst)\n            {\n                cur.errors = true;\n                if (cur.tinst && cur.tempdecl && cur.tinst.tempdecl && cur.tempdecl.loc.equals(cur.tinst.tempdecl.loc))\n                {\n                    ++recursionDepth;\n                }\n                else\n                {\n                    if (recursionDepth)\n                        errorSupplemental(cur.loc, \"%d recursive instantiations from here: `%s`\", recursionDepth + 2, cur.toChars());\n                    else\n                        errorSupplemental(cur.loc, format, cur.toChars());\n                    recursionDepth = 0;\n                }\n            }\n        }\n        else\n        {\n            // Even after collapsing the recursions, the depth is too deep.\n            // Just display the first few and last few instantiations.\n            uint i = 0;\n            for (TemplateInstance cur = this; cur; cur = cur.tinst)\n            {\n                cur.errors = true;\n\n                if (i == max_shown / 2)\n                    errorSupplemental(cur.loc, \"... (%d instantiations, -v to show) ...\", n_instantiations - max_shown);\n\n                if (i < max_shown / 2 || i >= n_instantiations - max_shown + max_shown / 2)\n                    errorSupplemental(cur.loc, format, cur.toChars());\n                ++i;\n            }\n        }\n    }\n\n    /*************************************\n     * Lazily generate identifier for template instance.\n     * This is because 75% of the ident's are never needed.\n     */\n    override final Identifier getIdent()\n    {\n        if (!ident && inst && !errors)\n            ident = genIdent(tiargs); // need an identifier for name mangling purposes.\n        return ident;\n    }\n\n    /*************************************\n     * Compare proposed template instantiation with existing template instantiation.\n     * Note that this is not commutative because of the auto ref check.\n     * Params:\n     *  o = existing template instantiation\n     * Returns:\n     *  0 for match, 1 for no match\n     */\n    override final int compare(RootObject o)\n    {\n        TemplateInstance ti = cast(TemplateInstance)o;\n\n        //printf(\"this = %p, ti = %p\\n\", this, ti);\n        assert(tdtypes.dim == ti.tdtypes.dim);\n\n        // Nesting must match\n        if (enclosing != ti.enclosing)\n        {\n            //printf(\"test2 enclosing %s ti.enclosing %s\\n\", enclosing ? enclosing.toChars() : \"\", ti.enclosing ? ti.enclosing.toChars() : \"\");\n            goto Lnotequals;\n        }\n        //printf(\"parent = %s, ti.parent = %s\\n\", parent.toPrettyChars(), ti.parent.toPrettyChars());\n\n        if (!arrayObjectMatch(&tdtypes, &ti.tdtypes))\n            goto Lnotequals;\n\n        /* Template functions may have different instantiations based on\n         * \"auto ref\" parameters.\n         */\n        if (auto fd = ti.toAlias().isFuncDeclaration())\n        {\n            if (!fd.errors)\n            {\n                auto fparameters = fd.getParameters(null);\n                size_t nfparams = Parameter.dim(fparameters);   // Num function parameters\n                for (size_t j = 0; j < nfparams; j++)\n                {\n                    Parameter fparam = Parameter.getNth(fparameters, j);\n                    if (fparam.storageClass & STC.autoref)       // if \"auto ref\"\n                    {\n                        if (!fargs)\n                            goto Lnotequals;\n                        if (fargs.dim <= j)\n                            break;\n                        Expression farg = (*fargs)[j];\n                        if (farg.isLvalue())\n                        {\n                            if (!(fparam.storageClass & STC.ref_))\n                                goto Lnotequals; // auto ref's don't match\n                        }\n                        else\n                        {\n                            if (fparam.storageClass & STC.ref_)\n                                goto Lnotequals; // auto ref's don't match\n                        }\n                    }\n                }\n            }\n        }\n        return 0;\n\n    Lnotequals:\n        return 1;\n    }\n\n    final hash_t toHash()\n    {\n        if (!hash)\n        {\n            hash = cast(size_t)cast(void*)enclosing;\n            hash += arrayObjectHash(&tdtypes);\n            hash += hash == 0;\n        }\n        return hash;\n    }\n\n    /***********************************************\n     * Returns true if this is not instantiated in non-root module, and\n     * is a part of non-speculative instantiatiation.\n     *\n     * Note: minst does not stabilize until semantic analysis is completed,\n     * so don't call this function during semantic analysis to return precise result.\n     */\n    final bool needsCodegen()\n    {\n        // Now -allInst is just for the backward compatibility.\n        if (global.params.allInst)\n        {\n            //printf(\"%s minst = %s, enclosing (%s).isNonRoot = %d\\n\",\n            //    toPrettyChars(), minst ? minst.toChars() : NULL,\n            //    enclosing ? enclosing.toPrettyChars() : NULL, enclosing && enclosing.inNonRoot());\n            if (enclosing)\n            {\n                /* https://issues.dlang.org/show_bug.cgi?id=14588\n                 * If the captured context is not a function\n                 * (e.g. class), the instance layout determination is guaranteed,\n                 * because the semantic/semantic2 pass will be executed\n                 * even for non-root instances.\n                 */\n                if (!enclosing.isFuncDeclaration())\n                    return true;\n\n                /* https://issues.dlang.org/show_bug.cgi?id=14834\n                 * If the captured context is a function,\n                 * this excessive instantiation may cause ODR violation, because\n                 * -allInst and others doesn't guarantee the semantic3 execution\n                 * for that function.\n                 *\n                 * If the enclosing is also an instantiated function,\n                 * we have to rely on the ancestor's needsCodegen() result.\n                 */\n                if (TemplateInstance ti = enclosing.isInstantiated())\n                    return ti.needsCodegen();\n\n                /* https://issues.dlang.org/show_bug.cgi?id=13415\n                 * If and only if the enclosing scope needs codegen,\n                 * this nested templates would also need code generation.\n                 */\n                return !enclosing.inNonRoot();\n            }\n            return true;\n        }\n\n        if (!minst)\n        {\n            // If this is a speculative instantiation,\n            // 1. do codegen if ancestors really needs codegen.\n            // 2. become non-speculative if siblings are not speculative\n\n            TemplateInstance tnext = this.tnext;\n            TemplateInstance tinst = this.tinst;\n            // At first, disconnect chain first to prevent infinite recursion.\n            this.tnext = null;\n            this.tinst = null;\n\n            // Determine necessity of tinst before tnext.\n            if (tinst && tinst.needsCodegen())\n            {\n                minst = tinst.minst; // cache result\n                assert(minst);\n                assert(minst.isRoot() || minst.rootImports());\n                return true;\n            }\n            if (tnext && (tnext.needsCodegen() || tnext.minst))\n            {\n                minst = tnext.minst; // cache result\n                assert(minst);\n                return minst.isRoot() || minst.rootImports();\n            }\n\n            // Elide codegen because this is really speculative.\n            return false;\n        }\n\n        /* Even when this is reached to the codegen pass,\n         * a non-root nested template should not generate code,\n         * due to avoid ODR violation.\n         */\n        if (enclosing && enclosing.inNonRoot())\n        {\n            if (tinst)\n            {\n                auto r = tinst.needsCodegen();\n                minst = tinst.minst; // cache result\n                return r;\n            }\n            if (tnext)\n            {\n                auto r = tnext.needsCodegen();\n                minst = tnext.minst; // cache result\n                return r;\n            }\n            return false;\n        }\n\n        /* The issue is that if the importee is compiled with a different -debug\n         * setting than the importer, the importer may believe it exists\n         * in the compiled importee when it does not, when the instantiation\n         * is behind a conditional debug declaration.\n         */\n        // workaround for https://issues.dlang.org/show_bug.cgi?id=11239\n        if (global.params.useUnitTests ||\n            global.params.debuglevel)\n        {\n            // Prefer instantiations from root modules, to maximize link-ability.\n            if (minst.isRoot())\n                return true;\n\n            TemplateInstance tnext = this.tnext;\n            TemplateInstance tinst = this.tinst;\n            this.tnext = null;\n            this.tinst = null;\n\n            if (tinst && tinst.needsCodegen())\n            {\n                minst = tinst.minst; // cache result\n                assert(minst);\n                assert(minst.isRoot() || minst.rootImports());\n                return true;\n            }\n            if (tnext && tnext.needsCodegen())\n            {\n                minst = tnext.minst; // cache result\n                assert(minst);\n                assert(minst.isRoot() || minst.rootImports());\n                return true;\n            }\n\n            // https://issues.dlang.org/show_bug.cgi?id=2500 case\n            if (minst.rootImports())\n                return true;\n\n            // Elide codegen because this is not included in root instances.\n            return false;\n        }\n        else\n        {\n            // Prefer instantiations from non-root module, to minimize object code size.\n\n            /* If a TemplateInstance is ever instantiated by non-root modules,\n             * we do not have to generate code for it,\n             * because it will be generated when the non-root module is compiled.\n             *\n             * But, if the non-root 'minst' imports any root modules, it might still need codegen.\n             *\n             * The problem is if A imports B, and B imports A, and both A\n             * and B instantiate the same template, does the compilation of A\n             * or the compilation of B do the actual instantiation?\n             *\n             * See https://issues.dlang.org/show_bug.cgi?id=2500.\n             */\n            if (!minst.isRoot() && !minst.rootImports())\n                return false;\n\n            TemplateInstance tnext = this.tnext;\n            this.tnext = null;\n\n            if (tnext && !tnext.needsCodegen() && tnext.minst)\n            {\n                minst = tnext.minst; // cache result\n                assert(!minst.isRoot());\n                return false;\n            }\n\n            // Do codegen because this is not included in non-root instances.\n            return true;\n        }\n    }\n\n    /**********************************************\n     * Find template declaration corresponding to template instance.\n     *\n     * Returns:\n     *      false if finding fails.\n     * Note:\n     *      This function is reentrant against error occurrence. If returns false,\n     *      any members of this object won't be modified, and repetition call will\n     *      reproduce same error.\n     */\n    extern (D) final bool findTempDecl(Scope* sc, WithScopeSymbol* pwithsym)\n    {\n        if (pwithsym)\n            *pwithsym = null;\n\n        if (havetempdecl)\n            return true;\n\n        //printf(\"TemplateInstance.findTempDecl() %s\\n\", toChars());\n        if (!tempdecl)\n        {\n            /* Given:\n             *    foo!( ... )\n             * figure out which TemplateDeclaration foo refers to.\n             */\n            Identifier id = name;\n            Dsymbol scopesym;\n            Dsymbol s = sc.search(loc, id, &scopesym);\n            if (!s)\n            {\n                s = sc.search_correct(id);\n                if (s)\n                    error(\"template `%s` is not defined, did you mean %s?\", id.toChars(), s.toChars());\n                else\n                    error(\"template `%s` is not defined\", id.toChars());\n                return false;\n            }\n            static if (LOG)\n            {\n                printf(\"It's an instance of '%s' kind '%s'\\n\", s.toChars(), s.kind());\n                if (s.parent)\n                    printf(\"s.parent = '%s'\\n\", s.parent.toChars());\n            }\n            if (pwithsym)\n                *pwithsym = scopesym.isWithScopeSymbol();\n\n            /* We might have found an alias within a template when\n             * we really want the template.\n             */\n            TemplateInstance ti;\n            if (s.parent && (ti = s.parent.isTemplateInstance()) !is null)\n            {\n                if (ti.tempdecl && ti.tempdecl.ident == id)\n                {\n                    /* This is so that one can refer to the enclosing\n                     * template, even if it has the same name as a member\n                     * of the template, if it has a !(arguments)\n                     */\n                    TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration();\n                    assert(td);\n                    if (td.overroot) // if not start of overloaded list of TemplateDeclaration's\n                        td = td.overroot; // then get the start\n                    s = td;\n                }\n            }\n\n            if (!updateTempDecl(sc, s))\n            {\n                return false;\n            }\n        }\n        assert(tempdecl);\n\n        // Look for forward references\n        auto tovers = tempdecl.isOverloadSet();\n        foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)\n        {\n            Dsymbol dstart = tovers ? tovers.a[oi] : tempdecl;\n            int r = overloadApply(dstart, (Dsymbol s)\n            {\n                auto td = s.isTemplateDeclaration();\n                if (!td)\n                    return 0;\n\n                if (td.semanticRun == PASS.init)\n                {\n                    if (td._scope)\n                    {\n                        // Try to fix forward reference. Ungag errors while doing so.\n                        Ungag ungag = td.ungagSpeculative();\n                        td.dsymbolSemantic(td._scope);\n                    }\n                    if (td.semanticRun == PASS.init)\n                    {\n                        error(\"`%s` forward references template declaration `%s`\",\n                            toChars(), td.toChars());\n                        return 1;\n                    }\n                }\n                return 0;\n            });\n            if (r)\n                return false;\n        }\n        return true;\n    }\n\n    /**********************************************\n     * Confirm s is a valid template, then store it.\n     * Input:\n     *      sc\n     *      s   candidate symbol of template. It may be:\n     *          TemplateDeclaration\n     *          FuncDeclaration with findTemplateDeclRoot() != NULL\n     *          OverloadSet which contains candidates\n     * Returns:\n     *      true if updating succeeds.\n     */\n    extern (D) final bool updateTempDecl(Scope* sc, Dsymbol s)\n    {\n        if (s)\n        {\n            Identifier id = name;\n            s = s.toAlias();\n\n            /* If an OverloadSet, look for a unique member that is a template declaration\n             */\n            OverloadSet os = s.isOverloadSet();\n            if (os)\n            {\n                s = null;\n                for (size_t i = 0; i < os.a.dim; i++)\n                {\n                    Dsymbol s2 = os.a[i];\n                    if (FuncDeclaration f = s2.isFuncDeclaration())\n                        s2 = f.findTemplateDeclRoot();\n                    else\n                        s2 = s2.isTemplateDeclaration();\n                    if (s2)\n                    {\n                        if (s)\n                        {\n                            tempdecl = os;\n                            return true;\n                        }\n                        s = s2;\n                    }\n                }\n                if (!s)\n                {\n                    error(\"template `%s` is not defined\", id.toChars());\n                    return false;\n                }\n            }\n\n            OverDeclaration od = s.isOverDeclaration();\n            if (od)\n            {\n                tempdecl = od; // TODO: more strict check\n                return true;\n            }\n\n            /* It should be a TemplateDeclaration, not some other symbol\n             */\n            if (FuncDeclaration f = s.isFuncDeclaration())\n                tempdecl = f.findTemplateDeclRoot();\n            else\n                tempdecl = s.isTemplateDeclaration();\n            if (!tempdecl)\n            {\n                if (!s.parent && global.errors)\n                    return false;\n                if (!s.parent && s.getType())\n                {\n                    Dsymbol s2 = s.getType().toDsymbol(sc);\n                    if (!s2)\n                    {\n                        .error(loc, \"`%s` is not a valid template instance, because `%s` is not a template declaration but a type (`%s == %s`)\", toChars(), id.toChars(), id.toChars(), s.getType.kind());\n                        return false;\n                    }\n                    s = s2;\n                }\n                debug\n                {\n                    //if (!s.parent) printf(\"s = %s %s\\n\", s.kind(), s.toChars());\n                }\n                //assert(s.parent);\n                TemplateInstance ti = s.parent ? s.parent.isTemplateInstance() : null;\n                if (ti && (ti.name == s.ident || ti.toAlias().ident == s.ident) && ti.tempdecl)\n                {\n                    /* This is so that one can refer to the enclosing\n                     * template, even if it has the same name as a member\n                     * of the template, if it has a !(arguments)\n                     */\n                    TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration();\n                    assert(td);\n                    if (td.overroot) // if not start of overloaded list of TemplateDeclaration's\n                        td = td.overroot; // then get the start\n                    tempdecl = td;\n                }\n                else\n                {\n                    error(\"`%s` is not a template declaration, it is a %s\", id.toChars(), s.kind());\n                    return false;\n                }\n            }\n        }\n        return (tempdecl !is null);\n    }\n\n    /**********************************\n     * Run semantic of tiargs as arguments of template.\n     * Input:\n     *      loc\n     *      sc\n     *      tiargs  array of template arguments\n     *      flags   1: replace const variables with their initializers\n     *              2: don't devolve Parameter to Type\n     * Returns:\n     *      false if one or more arguments have errors.\n     */\n    extern (D) static bool semanticTiargs(const ref Loc loc, Scope* sc, Objects* tiargs, int flags)\n    {\n        // Run semantic on each argument, place results in tiargs[]\n        //printf(\"+TemplateInstance.semanticTiargs()\\n\");\n        if (!tiargs)\n            return true;\n        bool err = false;\n        for (size_t j = 0; j < tiargs.dim; j++)\n        {\n            RootObject o = (*tiargs)[j];\n            Type ta = isType(o);\n            Expression ea = isExpression(o);\n            Dsymbol sa = isDsymbol(o);\n\n            //printf(\"1: (*tiargs)[%d] = %p, s=%p, v=%p, ea=%p, ta=%p\\n\", j, o, isDsymbol(o), isTuple(o), ea, ta);\n            if (ta)\n            {\n                //printf(\"type %s\\n\", ta.toChars());\n                // It might really be an Expression or an Alias\n                ta.resolve(loc, sc, &ea, &ta, &sa, (flags & 1) != 0);\n                if (ea)\n                    goto Lexpr;\n                if (sa)\n                    goto Ldsym;\n                if (ta is null)\n                {\n                    assert(global.errors);\n                    ta = Type.terror;\n                }\n\n            Ltype:\n                if (ta.ty == Ttuple)\n                {\n                    // Expand tuple\n                    TypeTuple tt = cast(TypeTuple)ta;\n                    size_t dim = tt.arguments.dim;\n                    tiargs.remove(j);\n                    if (dim)\n                    {\n                        tiargs.reserve(dim);\n                        for (size_t i = 0; i < dim; i++)\n                        {\n                            Parameter arg = (*tt.arguments)[i];\n                            if (flags & 2 && (arg.ident || arg.userAttribDecl))\n                                tiargs.insert(j + i, arg);\n                            else\n                                tiargs.insert(j + i, arg.type);\n                        }\n                    }\n                    j--;\n                    continue;\n                }\n                if (ta.ty == Terror)\n                {\n                    err = true;\n                    continue;\n                }\n                (*tiargs)[j] = ta.merge2();\n            }\n            else if (ea)\n            {\n            Lexpr:\n                //printf(\"+[%d] ea = %s %s\\n\", j, Token.toChars(ea.op), ea.toChars());\n                if (flags & 1) // only used by __traits\n                {\n                    ea = ea.expressionSemantic(sc);\n\n                    // must not interpret the args, excepting template parameters\n                    if (ea.op != TOK.variable || ((cast(VarExp)ea).var.storage_class & STC.templateparameter))\n                    {\n                        ea = ea.optimize(WANTvalue);\n                    }\n                }\n                else\n                {\n                    sc = sc.startCTFE();\n                    ea = ea.expressionSemantic(sc);\n                    sc = sc.endCTFE();\n\n                    if (ea.op == TOK.variable)\n                    {\n                        /* This test is to skip substituting a const var with\n                         * its initializer. The problem is the initializer won't\n                         * match with an 'alias' parameter. Instead, do the\n                         * const substitution in TemplateValueParameter.matchArg().\n                         */\n                    }\n                    else if (definitelyValueParameter(ea))\n                    {\n                        if (ea.checkValue()) // check void expression\n                            ea = new ErrorExp();\n                        uint olderrs = global.errors;\n                        ea = ea.ctfeInterpret();\n                        if (global.errors != olderrs)\n                            ea = new ErrorExp();\n                    }\n                }\n                //printf(\"-[%d] ea = %s %s\\n\", j, Token.toChars(ea.op), ea.toChars());\n                if (ea.op == TOK.tuple)\n                {\n                    // Expand tuple\n                    TupleExp te = cast(TupleExp)ea;\n                    size_t dim = te.exps.dim;\n                    tiargs.remove(j);\n                    if (dim)\n                    {\n                        tiargs.reserve(dim);\n                        for (size_t i = 0; i < dim; i++)\n                            tiargs.insert(j + i, (*te.exps)[i]);\n                    }\n                    j--;\n                    continue;\n                }\n                if (ea.op == TOK.error)\n                {\n                    err = true;\n                    continue;\n                }\n                (*tiargs)[j] = ea;\n\n                if (ea.op == TOK.type)\n                {\n                    ta = ea.type;\n                    goto Ltype;\n                }\n                if (ea.op == TOK.scope_)\n                {\n                    sa = (cast(ScopeExp)ea).sds;\n                    goto Ldsym;\n                }\n                if (ea.op == TOK.function_)\n                {\n                    FuncExp fe = cast(FuncExp)ea;\n                    /* A function literal, that is passed to template and\n                     * already semanticed as function pointer, never requires\n                     * outer frame. So convert it to global function is valid.\n                     */\n                    if (fe.fd.tok == TOK.reserved && fe.type.ty == Tpointer)\n                    {\n                        // change to non-nested\n                        fe.fd.tok = TOK.function_;\n                        fe.fd.vthis = null;\n                    }\n                    else if (fe.td)\n                    {\n                        /* If template argument is a template lambda,\n                         * get template declaration itself. */\n                        //sa = fe.td;\n                        //goto Ldsym;\n                    }\n                }\n                if (ea.op == TOK.dotVariable && !(flags & 1))\n                {\n                    // translate expression to dsymbol.\n                    sa = (cast(DotVarExp)ea).var;\n                    goto Ldsym;\n                }\n                if (ea.op == TOK.template_)\n                {\n                    sa = (cast(TemplateExp)ea).td;\n                    goto Ldsym;\n                }\n                if (ea.op == TOK.dotTemplateDeclaration && !(flags & 1))\n                {\n                    // translate expression to dsymbol.\n                    sa = (cast(DotTemplateExp)ea).td;\n                    goto Ldsym;\n                }\n            }\n            else if (sa)\n            {\n            Ldsym:\n                //printf(\"dsym %s %s\\n\", sa.kind(), sa.toChars());\n                if (sa.errors)\n                {\n                    err = true;\n                    continue;\n                }\n\n                TupleDeclaration d = sa.toAlias().isTupleDeclaration();\n                if (d)\n                {\n                    // Expand tuple\n                    tiargs.remove(j);\n                    tiargs.insert(j, d.objects);\n                    j--;\n                    continue;\n                }\n                if (FuncAliasDeclaration fa = sa.isFuncAliasDeclaration())\n                {\n                    FuncDeclaration f = fa.toAliasFunc();\n                    if (!fa.hasOverloads && f.isUnique())\n                    {\n                        // Strip FuncAlias only when the aliased function\n                        // does not have any overloads.\n                        sa = f;\n                    }\n                }\n                (*tiargs)[j] = sa;\n\n                TemplateDeclaration td = sa.isTemplateDeclaration();\n                if (td && td.semanticRun == PASS.init && td.literal)\n                {\n                    td.dsymbolSemantic(sc);\n                }\n                FuncDeclaration fd = sa.isFuncDeclaration();\n                if (fd)\n                    fd.functionSemantic();\n            }\n            else if (isParameter(o))\n            {\n            }\n            else\n            {\n                assert(0);\n            }\n            //printf(\"1: (*tiargs)[%d] = %p\\n\", j, (*tiargs)[j]);\n        }\n        version (none)\n        {\n            printf(\"-TemplateInstance.semanticTiargs()\\n\");\n            for (size_t j = 0; j < tiargs.dim; j++)\n            {\n                RootObject o = (*tiargs)[j];\n                Type ta = isType(o);\n                Expression ea = isExpression(o);\n                Dsymbol sa = isDsymbol(o);\n                Tuple va = isTuple(o);\n                printf(\"\\ttiargs[%d] = ta %p, ea %p, sa %p, va %p\\n\", j, ta, ea, sa, va);\n            }\n        }\n        return !err;\n    }\n\n    /**********************************\n     * Run semantic on the elements of tiargs.\n     * Input:\n     *      sc\n     * Returns:\n     *      false if one or more arguments have errors.\n     * Note:\n     *      This function is reentrant against error occurrence. If returns false,\n     *      all elements of tiargs won't be modified.\n     */\n    extern (D) final bool semanticTiargs(Scope* sc)\n    {\n        //printf(\"+TemplateInstance.semanticTiargs() %s\\n\", toChars());\n        if (semantictiargsdone)\n            return true;\n        if (semanticTiargs(loc, sc, tiargs, 0))\n        {\n            // cache the result iff semantic analysis succeeded entirely\n            semantictiargsdone = 1;\n            return true;\n        }\n        return false;\n    }\n\n    extern (D) final bool findBestMatch(Scope* sc, Expressions* fargs)\n    {\n        if (havetempdecl)\n        {\n            TemplateDeclaration tempdecl = this.tempdecl.isTemplateDeclaration();\n            assert(tempdecl);\n            assert(tempdecl._scope);\n            // Deduce tdtypes\n            tdtypes.setDim(tempdecl.parameters.dim);\n            if (!tempdecl.matchWithInstance(sc, this, &tdtypes, fargs, 2))\n            {\n                error(\"incompatible arguments for template instantiation\");\n                return false;\n            }\n            // TODO: Normalizing tiargs for https://issues.dlang.org/show_bug.cgi?id=7469 is necessary?\n            return true;\n        }\n\n        static if (LOG)\n        {\n            printf(\"TemplateInstance.findBestMatch()\\n\");\n        }\n\n        uint errs = global.errors;\n        TemplateDeclaration td_last = null;\n        Objects dedtypes;\n\n        /* Since there can be multiple TemplateDeclaration's with the same\n         * name, look for the best match.\n         */\n        auto tovers = tempdecl.isOverloadSet();\n        foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)\n        {\n            TemplateDeclaration td_best;\n            TemplateDeclaration td_ambig;\n            MATCH m_best = MATCH.nomatch;\n\n            Dsymbol dstart = tovers ? tovers.a[oi] : tempdecl;\n            overloadApply(dstart, (Dsymbol s)\n            {\n                auto td = s.isTemplateDeclaration();\n                if (!td)\n                    return 0;\n                if (td.inuse)\n                {\n                    td.error(loc, \"recursive template expansion\");\n                    return 1;\n                }\n                if (td == td_best)   // skip duplicates\n                    return 0;\n\n                //printf(\"td = %s\\n\", td.toPrettyChars());\n                // If more arguments than parameters,\n                // then this is no match.\n                if (td.parameters.dim < tiargs.dim)\n                {\n                    if (!td.isVariadic())\n                        return 0;\n                }\n\n                dedtypes.setDim(td.parameters.dim);\n                dedtypes.zero();\n                assert(td.semanticRun != PASS.init);\n\n                MATCH m = td.matchWithInstance(sc, this, &dedtypes, fargs, 0);\n                //printf(\"matchWithInstance = %d\\n\", m);\n                if (m <= MATCH.nomatch) // no match at all\n                    return 0;\n                if (m < m_best) goto Ltd_best;\n                if (m > m_best) goto Ltd;\n\n                // Disambiguate by picking the most specialized TemplateDeclaration\n                {\n                MATCH c1 = td.leastAsSpecialized(sc, td_best, fargs);\n                MATCH c2 = td_best.leastAsSpecialized(sc, td, fargs);\n                //printf(\"c1 = %d, c2 = %d\\n\", c1, c2);\n                if (c1 > c2) goto Ltd;\n                if (c1 < c2) goto Ltd_best;\n                }\n\n                td_ambig = td;\n                return 0;\n\n            Ltd_best:\n                // td_best is the best match so far\n                td_ambig = null;\n                return 0;\n\n            Ltd:\n                // td is the new best match\n                td_ambig = null;\n                td_best = td;\n                m_best = m;\n                tdtypes.setDim(dedtypes.dim);\n                memcpy(tdtypes.tdata(), dedtypes.tdata(), tdtypes.dim * (void*).sizeof);\n                return 0;\n            });\n\n            if (td_ambig)\n            {\n                .error(loc, \"%s `%s.%s` matches more than one template declaration:\\n%s:     `%s`\\nand\\n%s:     `%s`\",\n                    td_best.kind(), td_best.parent.toPrettyChars(), td_best.ident.toChars(),\n                    td_best.loc.toChars(), td_best.toChars(),\n                    td_ambig.loc.toChars(), td_ambig.toChars());\n                return false;\n            }\n            if (td_best)\n            {\n                if (!td_last)\n                    td_last = td_best;\n                else if (td_last != td_best)\n                {\n                    ScopeDsymbol.multiplyDefined(loc, td_last, td_best);\n                    return false;\n                }\n            }\n        }\n\n        if (td_last)\n        {\n            /* https://issues.dlang.org/show_bug.cgi?id=7469\n             * Normalize tiargs by using corresponding deduced\n             * template value parameters and tuples for the correct mangling.\n             *\n             * By doing this before hasNestedArgs, CTFEable local variable will be\n             * accepted as a value parameter. For example:\n             *\n             *  void foo() {\n             *    struct S(int n) {}   // non-global template\n             *    const int num = 1;   // CTFEable local variable\n             *    S!num s;             // S!1 is instantiated, not S!num\n             *  }\n             */\n            size_t dim = td_last.parameters.dim - (td_last.isVariadic() ? 1 : 0);\n            for (size_t i = 0; i < dim; i++)\n            {\n                if (tiargs.dim <= i)\n                    tiargs.push(tdtypes[i]);\n                assert(i < tiargs.dim);\n\n                auto tvp = (*td_last.parameters)[i].isTemplateValueParameter();\n                if (!tvp)\n                    continue;\n                assert(tdtypes[i]);\n                // tdtypes[i] is already normalized to the required type in matchArg\n\n                (*tiargs)[i] = tdtypes[i];\n            }\n            if (td_last.isVariadic() && tiargs.dim == dim && tdtypes[dim])\n            {\n                Tuple va = isTuple(tdtypes[dim]);\n                assert(va);\n                for (size_t i = 0; i < va.objects.dim; i++)\n                    tiargs.push(va.objects[i]);\n            }\n        }\n        else if (errors && inst)\n        {\n            // instantiation was failed with error reporting\n            assert(global.errors);\n            return false;\n        }\n        else\n        {\n            auto tdecl = tempdecl.isTemplateDeclaration();\n\n            if (errs != global.errors)\n                errorSupplemental(loc, \"while looking for match for `%s`\", toChars());\n            else if (tdecl && !tdecl.overnext)\n            {\n                // Only one template, so we can give better error message\n                error(\"does not match template declaration `%s`\", tdecl.toChars());\n            }\n            else\n                .error(loc, \"%s `%s.%s` does not match any template declaration\", tempdecl.kind(), tempdecl.parent.toPrettyChars(), tempdecl.ident.toChars());\n            return false;\n        }\n\n        /* The best match is td_last\n         */\n        tempdecl = td_last;\n\n        static if (LOG)\n        {\n            printf(\"\\tIt's a match with template declaration '%s'\\n\", tempdecl.toChars());\n        }\n        return (errs == global.errors);\n    }\n\n    /*****************************************************\n     * Determine if template instance is really a template function,\n     * and that template function needs to infer types from the function\n     * arguments.\n     *\n     * Like findBestMatch, iterate possible template candidates,\n     * but just looks only the necessity of type inference.\n     */\n    extern (D) final bool needsTypeInference(Scope* sc, int flag = 0)\n    {\n        //printf(\"TemplateInstance.needsTypeInference() %s\\n\", toChars());\n        if (semanticRun != PASS.init)\n            return false;\n\n        uint olderrs = global.errors;\n        Objects dedtypes;\n        size_t count = 0;\n\n        auto tovers = tempdecl.isOverloadSet();\n        foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)\n        {\n            Dsymbol dstart = tovers ? tovers.a[oi] : tempdecl;\n            int r = overloadApply(dstart, (Dsymbol s)\n            {\n                auto td = s.isTemplateDeclaration();\n                if (!td)\n                    return 0;\n                if (td.inuse)\n                {\n                    td.error(loc, \"recursive template expansion\");\n                    return 1;\n                }\n\n                /* If any of the overloaded template declarations need inference,\n                 * then return true\n                 */\n                if (!td.onemember)\n                    return 0;\n                if (auto td2 = td.onemember.isTemplateDeclaration())\n                {\n                    if (!td2.onemember || !td2.onemember.isFuncDeclaration())\n                        return 0;\n                    if (tiargs.dim >= td.parameters.dim - (td.isVariadic() ? 1 : 0))\n                        return 0;\n                    return 1;\n                }\n                auto fd = td.onemember.isFuncDeclaration();\n                if (!fd || fd.type.ty != Tfunction)\n                    return 0;\n\n                foreach (tp; *td.parameters)\n                {\n                    if (tp.isTemplateThisParameter())\n                        return 1;\n                }\n\n                /* Determine if the instance arguments, tiargs, are all that is necessary\n                 * to instantiate the template.\n                 */\n                //printf(\"tp = %p, td.parameters.dim = %d, tiargs.dim = %d\\n\", tp, td.parameters.dim, tiargs.dim);\n                auto tf = cast(TypeFunction)fd.type;\n                if (size_t dim = Parameter.dim(tf.parameters))\n                {\n                    auto tp = td.isVariadic();\n                    if (tp && td.parameters.dim > 1)\n                        return 1;\n\n                    if (!tp && tiargs.dim < td.parameters.dim)\n                    {\n                        // Can remain tiargs be filled by default arguments?\n                        foreach (size_t i; tiargs.dim .. td.parameters.dim)\n                        {\n                            if (!(*td.parameters)[i].hasDefaultArg())\n                                return 1;\n                        }\n                    }\n\n                    foreach (size_t i; 0 .. dim)\n                    {\n                        // 'auto ref' needs inference.\n                        if (Parameter.getNth(tf.parameters, i).storageClass & STC.auto_)\n                            return 1;\n                    }\n                }\n\n                if (!flag)\n                {\n                    /* Calculate the need for overload resolution.\n                     * When only one template can match with tiargs, inference is not necessary.\n                     */\n                    dedtypes.setDim(td.parameters.dim);\n                    dedtypes.zero();\n                    if (td.semanticRun == PASS.init)\n                    {\n                        if (td._scope)\n                        {\n                            // Try to fix forward reference. Ungag errors while doing so.\n                            Ungag ungag = td.ungagSpeculative();\n                            td.dsymbolSemantic(td._scope);\n                        }\n                        if (td.semanticRun == PASS.init)\n                        {\n                            error(\"`%s` forward references template declaration `%s`\", toChars(), td.toChars());\n                            return 1;\n                        }\n                    }\n                    MATCH m = td.matchWithInstance(sc, this, &dedtypes, null, 0);\n                    if (m <= MATCH.nomatch)\n                        return 0;\n                }\n\n                /* If there is more than one function template which matches, we may\n                 * need type inference (see https://issues.dlang.org/show_bug.cgi?id=4430)\n                 */\n                return ++count > 1 ? 1 : 0;\n            });\n            if (r)\n                return true;\n        }\n\n        if (olderrs != global.errors)\n        {\n            if (!global.gag)\n            {\n                errorSupplemental(loc, \"while looking for match for `%s`\", toChars());\n                semanticRun = PASS.semanticdone;\n                inst = this;\n            }\n            errors = true;\n        }\n        //printf(\"false\\n\");\n        return false;\n    }\n\n    /*****************************************\n     * Determines if a TemplateInstance will need a nested\n     * generation of the TemplateDeclaration.\n     * Sets enclosing property if so, and returns != 0;\n     */\n    extern (D) final bool hasNestedArgs(Objects* args, bool isstatic)\n    {\n        int nested = 0;\n        //printf(\"TemplateInstance.hasNestedArgs('%s')\\n\", tempdecl.ident.toChars());\n\n        version (none)\n        {\n            if (!enclosing)\n            {\n                if (TemplateInstance ti = tempdecl.isInstantiated())\n                    enclosing = ti.enclosing;\n            }\n        }\n\n        /* A nested instance happens when an argument references a local\n         * symbol that is on the stack.\n         */\n        for (size_t i = 0; i < args.dim; i++)\n        {\n            RootObject o = (*args)[i];\n            Expression ea = isExpression(o);\n            Dsymbol sa = isDsymbol(o);\n            Tuple va = isTuple(o);\n            if (ea)\n            {\n                if (ea.op == TOK.variable)\n                {\n                    sa = (cast(VarExp)ea).var;\n                    goto Lsa;\n                }\n                if (ea.op == TOK.this_)\n                {\n                    sa = (cast(ThisExp)ea).var;\n                    goto Lsa;\n                }\n                if (ea.op == TOK.function_)\n                {\n                    if ((cast(FuncExp)ea).td)\n                        sa = (cast(FuncExp)ea).td;\n                    else\n                        sa = (cast(FuncExp)ea).fd;\n                    goto Lsa;\n                }\n                // Emulate Expression.toMangleBuffer call that had exist in TemplateInstance.genIdent.\n                if (ea.op != TOK.int64 && ea.op != TOK.float64 && ea.op != TOK.complex80 && ea.op != TOK.null_ && ea.op != TOK.string_ && ea.op != TOK.arrayLiteral && ea.op != TOK.assocArrayLiteral && ea.op != TOK.structLiteral)\n                {\n                    ea.error(\"expression `%s` is not a valid template value argument\", ea.toChars());\n                    errors = true;\n                }\n            }\n            else if (sa)\n            {\n            Lsa:\n                sa = sa.toAlias();\n                TemplateDeclaration td = sa.isTemplateDeclaration();\n                if (td)\n                {\n                    TemplateInstance ti = sa.toParent().isTemplateInstance();\n                    if (ti && ti.enclosing)\n                        sa = ti;\n                }\n                TemplateInstance ti = sa.isTemplateInstance();\n                Declaration d = sa.isDeclaration();\n                if ((td && td.literal) || (ti && ti.enclosing) || (d && !d.isDataseg() && !(d.storage_class & STC.manifest) && (!d.isFuncDeclaration() || d.isFuncDeclaration().isNested()) && !isTemplateMixin()))\n                {\n                    // if module level template\n                    if (isstatic)\n                    {\n                        Dsymbol dparent = sa.toParent2();\n                        if (!dparent)\n                            goto L1;\n                        else if (!enclosing)\n                            enclosing = dparent;\n                        else if (enclosing != dparent)\n                        {\n                            /* Select the more deeply nested of the two.\n                             * Error if one is not nested inside the other.\n                             */\n                            for (Dsymbol p = enclosing; p; p = p.parent)\n                            {\n                                if (p == dparent)\n                                    goto L1; // enclosing is most nested\n                            }\n                            for (Dsymbol p = dparent; p; p = p.parent)\n                            {\n                                if (p == enclosing)\n                                {\n                                    enclosing = dparent;\n                                    goto L1; // dparent is most nested\n                                }\n                            }\n                            error(\"`%s` is nested in both `%s` and `%s`\", toChars(), enclosing.toChars(), dparent.toChars());\n                            errors = true;\n                        }\n                    L1:\n                        //printf(\"\\tnested inside %s\\n\", enclosing.toChars());\n                        nested |= 1;\n                    }\n                    else\n                    {\n                        error(\"cannot use local `%s` as parameter to non-global template `%s`\", sa.toChars(), tempdecl.toChars());\n                        errors = true;\n                    }\n                }\n            }\n            else if (va)\n            {\n                nested |= cast(int)hasNestedArgs(&va.objects, isstatic);\n            }\n        }\n        //printf(\"-TemplateInstance.hasNestedArgs('%s') = %d\\n\", tempdecl.ident.toChars(), nested);\n        return nested != 0;\n    }\n\n    /*****************************************\n     * Append 'this' to the specific module members[]\n     */\n    extern (D) final Dsymbols* appendToModuleMember()\n    {\n        Module mi = minst; // instantiated . inserted module\n\n        if (global.params.useUnitTests || global.params.debuglevel)\n        {\n            // Turn all non-root instances to speculative\n            if (mi && !mi.isRoot())\n                mi = null;\n        }\n\n        //printf(\"%s.appendToModuleMember() enclosing = %s mi = %s\\n\",\n        //    toPrettyChars(),\n        //    enclosing ? enclosing.toPrettyChars() : null,\n        //    mi ? mi.toPrettyChars() : null);\n        if (!mi || mi.isRoot())\n        {\n            /* If the instantiated module is speculative or root, insert to the\n             * member of a root module. Then:\n             *  - semantic3 pass will get called on the instance members.\n             *  - codegen pass will get a selection chance to do/skip it.\n             */\n            static Dsymbol getStrictEnclosing(TemplateInstance ti)\n            {\n                do\n                {\n                    if (ti.enclosing)\n                        return ti.enclosing;\n                    ti = ti.tempdecl.isInstantiated();\n                } while (ti);\n                return null;\n            }\n\n            Dsymbol enc = getStrictEnclosing(this);\n            // insert target is made stable by using the module\n            // where tempdecl is declared.\n            mi = (enc ? enc : tempdecl).getModule();\n            if (!mi.isRoot())\n                mi = mi.importedFrom;\n            assert(mi.isRoot());\n        }\n        else\n        {\n            /* If the instantiated module is non-root, insert to the member of the\n             * non-root module. Then:\n             *  - semantic3 pass won't be called on the instance.\n             *  - codegen pass won't reach to the instance.\n             */\n        }\n        //printf(\"\\t-. mi = %s\\n\", mi.toPrettyChars());\n\n        if (memberOf is mi)     // already a member\n        {\n            debug               // make sure it really is a member\n            {\n                auto a = mi.members;\n                for (size_t i = 0; 1; ++i)\n                {\n                    assert(i != a.dim);\n                    if (this == (*a)[i])\n                        break;\n                }\n            }\n            return null;\n        }\n\n        Dsymbols* a = mi.members;\n        a.push(this);\n        memberOf = mi;\n        if (mi.semanticRun >= PASS.semantic2done && mi.isRoot())\n            Module.addDeferredSemantic2(this);\n        if (mi.semanticRun >= PASS.semantic3done && mi.isRoot())\n            Module.addDeferredSemantic3(this);\n        return a;\n    }\n\n    /****************************************************\n     * Declare parameters of template instance, initialize them with the\n     * template instance arguments.\n     */\n    extern (D) final void declareParameters(Scope* sc)\n    {\n        TemplateDeclaration tempdecl = this.tempdecl.isTemplateDeclaration();\n        assert(tempdecl);\n\n        //printf(\"TemplateInstance.declareParameters()\\n\");\n        for (size_t i = 0; i < tdtypes.dim; i++)\n        {\n            TemplateParameter tp = (*tempdecl.parameters)[i];\n            //RootObject *o = (*tiargs)[i];\n            RootObject o = tdtypes[i]; // initializer for tp\n\n            //printf(\"\\ttdtypes[%d] = %p\\n\", i, o);\n            tempdecl.declareParameter(sc, tp, o);\n        }\n    }\n\n    /****************************************\n     * This instance needs an identifier for name mangling purposes.\n     * Create one by taking the template declaration name and adding\n     * the type signature for it.\n     */\n    extern (D) final Identifier genIdent(Objects* args)\n    {\n        //printf(\"TemplateInstance.genIdent('%s')\\n\", tempdecl.ident.toChars());\n        assert(args is tiargs);\n        OutBuffer buf;\n        mangleToBuffer(this, &buf);\n        //printf(\"\\tgenIdent = %s\\n\", buf.peekString());\n        return Identifier.idPool(buf.peekSlice());\n    }\n\n    extern (D) final void expandMembers(Scope* sc2)\n    {\n        for (size_t i = 0; i < members.dim; i++)\n        {\n            Dsymbol s = (*members)[i];\n            s.setScope(sc2);\n        }\n\n        for (size_t i = 0; i < members.dim; i++)\n        {\n            Dsymbol s = (*members)[i];\n            s.importAll(sc2);\n        }\n\n        for (size_t i = 0; i < members.dim; i++)\n        {\n            Dsymbol s = (*members)[i];\n            //printf(\"\\t[%d] semantic on '%s' %p kind %s in '%s'\\n\", i, s.toChars(), s, s.kind(), this.toChars());\n            //printf(\"test: enclosing = %d, sc2.parent = %s\\n\", enclosing, sc2.parent.toChars());\n            //if (enclosing)\n            //    s.parent = sc.parent;\n            //printf(\"test3: enclosing = %d, s.parent = %s\\n\", enclosing, s.parent.toChars());\n            s.dsymbolSemantic(sc2);\n            //printf(\"test4: enclosing = %d, s.parent = %s\\n\", enclosing, s.parent.toChars());\n            Module.runDeferredSemantic();\n        }\n    }\n\n    extern (D) final void tryExpandMembers(Scope* sc2)\n    {\n        __gshared int nest;\n        // extracted to a function to allow windows SEH to work without destructors in the same function\n        //printf(\"%d\\n\", nest);\n        if (++nest > 500)\n        {\n            global.gag = 0; // ensure error message gets printed\n            error(\"recursive expansion\");\n            fatal();\n        }\n\n        expandMembers(sc2);\n\n        nest--;\n    }\n\n    extern (D) final void trySemantic3(Scope* sc2)\n    {\n        // extracted to a function to allow windows SEH to work without destructors in the same function\n        __gshared int nest;\n        //printf(\"%d\\n\", nest);\n        if (++nest > 300)\n        {\n            global.gag = 0; // ensure error message gets printed\n            error(\"recursive expansion\");\n            fatal();\n        }\n\n        semantic3(this, sc2);\n\n        --nest;\n    }\n\n    override final inout(TemplateInstance) isTemplateInstance() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/**************************************\n * IsExpression can evaluate the specified type speculatively, and even if\n * it instantiates any symbols, they are normally unnecessary for the\n * final executable.\n * However, if those symbols leak to the actual code, compiler should remark\n * them as non-speculative to generate their code and link to the final executable.\n */\nvoid unSpeculative(Scope* sc, RootObject o)\n{\n    if (!o)\n        return;\n\n    if (Tuple tup = isTuple(o))\n    {\n        for (size_t i = 0; i < tup.objects.dim; i++)\n        {\n            unSpeculative(sc, tup.objects[i]);\n        }\n        return;\n    }\n\n    Dsymbol s = getDsymbol(o);\n    if (!s)\n        return;\n\n    if (Declaration d = s.isDeclaration())\n    {\n        if (VarDeclaration vd = d.isVarDeclaration())\n            o = vd.type;\n        else if (AliasDeclaration ad = d.isAliasDeclaration())\n        {\n            o = ad.getType();\n            if (!o)\n                o = ad.toAlias();\n        }\n        else\n            o = d.toAlias();\n\n        s = getDsymbol(o);\n        if (!s)\n            return;\n    }\n\n    if (TemplateInstance ti = s.isTemplateInstance())\n    {\n        // If the instance is already non-speculative,\n        // or it is leaked to the speculative scope.\n        if (ti.minst !is null || sc.minst is null)\n            return;\n\n        // Remark as non-speculative instance.\n        ti.minst = sc.minst;\n        if (!ti.tinst)\n            ti.tinst = sc.tinst;\n\n        unSpeculative(sc, ti.tempdecl);\n    }\n\n    if (TemplateInstance ti = s.isInstantiated())\n        unSpeculative(sc, ti);\n}\n\n/**********************************\n * Return true if e could be valid only as a template value parameter.\n * Return false if it might be an alias or tuple.\n * (Note that even in this case, it could still turn out to be a value).\n */\nbool definitelyValueParameter(Expression e)\n{\n    // None of these can be value parameters\n    if (e.op == TOK.tuple || e.op == TOK.scope_ ||\n        e.op == TOK.type || e.op == TOK.dotType ||\n        e.op == TOK.template_ || e.op == TOK.dotTemplateDeclaration ||\n        e.op == TOK.function_ || e.op == TOK.error ||\n        e.op == TOK.this_ || e.op == TOK.super_)\n        return false;\n\n    if (e.op != TOK.dotVariable)\n        return true;\n\n    /* Template instantiations involving a DotVar expression are difficult.\n     * In most cases, they should be treated as a value parameter, and interpreted.\n     * But they might also just be a fully qualified name, which should be treated\n     * as an alias.\n     */\n\n    // x.y.f cannot be a value\n    FuncDeclaration f = (cast(DotVarExp)e).var.isFuncDeclaration();\n    if (f)\n        return false;\n\n    while (e.op == TOK.dotVariable)\n    {\n        e = (cast(DotVarExp)e).e1;\n    }\n    // this.x.y and super.x.y couldn't possibly be valid values.\n    if (e.op == TOK.this_ || e.op == TOK.super_)\n        return false;\n\n    // e.type.x could be an alias\n    if (e.op == TOK.dotType)\n        return false;\n\n    // var.x.y is the only other possible form of alias\n    if (e.op != TOK.variable)\n        return true;\n\n    VarDeclaration v = (cast(VarExp)e).var.isVarDeclaration();\n    // func.x.y is not an alias\n    if (!v)\n        return true;\n\n    // https://issues.dlang.org/show_bug.cgi?id=16685\n    // var.x.y where var is a constant available at compile time\n    if (v.storage_class & STC.manifest)\n        return true;\n\n    // TODO: Should we force CTFE if it is a global constant?\n    return false;\n}\n\n/***********************************************************\n */\nextern (C++) final class TemplateMixin : TemplateInstance\n{\n    TypeQualified tqual;\n\n    extern (D) this(const ref Loc loc, Identifier ident, TypeQualified tqual, Objects* tiargs)\n    {\n        super(loc,\n              tqual.idents.dim ? cast(Identifier)tqual.idents[tqual.idents.dim - 1] : (cast(TypeIdentifier)tqual).ident,\n              tiargs ? tiargs : new Objects());\n        //printf(\"TemplateMixin(ident = '%s')\\n\", ident ? ident.toChars() : \"\");\n        this.ident = ident;\n        this.tqual = tqual;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        auto tm = new TemplateMixin(loc, ident, cast(TypeQualified)tqual.syntaxCopy(), tiargs);\n        return TemplateInstance.syntaxCopy(tm);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"mixin\";\n    }\n\n    override bool oneMember(Dsymbol* ps, Identifier ident)\n    {\n        return Dsymbol.oneMember(ps, ident);\n    }\n\n    override int apply(Dsymbol_apply_ft_t fp, void* param)\n    {\n        if (_scope) // if fwd reference\n            dsymbolSemantic(this, null); // try to resolve it\n        if (members)\n        {\n            for (size_t i = 0; i < members.dim; i++)\n            {\n                Dsymbol s = (*members)[i];\n                if (s)\n                {\n                    if (s.apply(fp, param))\n                        return 1;\n                }\n            }\n        }\n        return 0;\n    }\n\n    override bool hasPointers()\n    {\n        //printf(\"TemplateMixin.hasPointers() %s\\n\", toChars());\n        if (members)\n        {\n            for (size_t i = 0; i < members.dim; i++)\n            {\n                Dsymbol s = (*members)[i];\n                //printf(\" s = %s %s\\n\", s.kind(), s.toChars());\n                if (s.hasPointers())\n                {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    override void setFieldOffset(AggregateDeclaration ad, uint* poffset, bool isunion)\n    {\n        //printf(\"TemplateMixin.setFieldOffset() %s\\n\", toChars());\n        if (_scope) // if fwd reference\n            dsymbolSemantic(this, null); // try to resolve it\n        if (members)\n        {\n            for (size_t i = 0; i < members.dim; i++)\n            {\n                Dsymbol s = (*members)[i];\n                //printf(\"\\t%s\\n\", s.toChars());\n                s.setFieldOffset(ad, poffset, isunion);\n            }\n        }\n    }\n\n    override const(char)* toChars()\n    {\n        OutBuffer buf;\n        toCBufferInstance(this, &buf);\n        return buf.extractString();\n    }\n\n    extern (D) bool findTempDecl(Scope* sc)\n    {\n        // Follow qualifications to find the TemplateDeclaration\n        if (!tempdecl)\n        {\n            Expression e;\n            Type t;\n            Dsymbol s;\n            tqual.resolve(loc, sc, &e, &t, &s);\n            if (!s)\n            {\n                error(\"is not defined\");\n                return false;\n            }\n            s = s.toAlias();\n            tempdecl = s.isTemplateDeclaration();\n            OverloadSet os = s.isOverloadSet();\n\n            /* If an OverloadSet, look for a unique member that is a template declaration\n             */\n            if (os)\n            {\n                Dsymbol ds = null;\n                for (size_t i = 0; i < os.a.dim; i++)\n                {\n                    Dsymbol s2 = os.a[i].isTemplateDeclaration();\n                    if (s2)\n                    {\n                        if (ds)\n                        {\n                            tempdecl = os;\n                            break;\n                        }\n                        ds = s2;\n                    }\n                }\n            }\n            if (!tempdecl)\n            {\n                error(\"`%s` isn't a template\", s.toChars());\n                return false;\n            }\n        }\n        assert(tempdecl);\n\n        // Look for forward references\n        auto tovers = tempdecl.isOverloadSet();\n        foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)\n        {\n            Dsymbol dstart = tovers ? tovers.a[oi] : tempdecl;\n            int r = overloadApply(dstart, (Dsymbol s)\n            {\n                auto td = s.isTemplateDeclaration();\n                if (!td)\n                    return 0;\n\n                if (td.semanticRun == PASS.init)\n                {\n                    if (td._scope)\n                        td.dsymbolSemantic(td._scope);\n                    else\n                    {\n                        semanticRun = PASS.init;\n                        return 1;\n                    }\n                }\n                return 0;\n            });\n            if (r)\n                return false;\n        }\n        return true;\n    }\n\n    override inout(TemplateMixin) isTemplateMixin() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/************************************\n * This struct is needed for TemplateInstance to be the key in an associative array.\n * Fixing https://issues.dlang.org/show_bug.cgi?id=15812 and\n * https://issues.dlang.org/show_bug.cgi?id=15813 would make it unnecessary.\n */\nstruct TemplateInstanceBox\n{\n    TemplateInstance ti;\n\n    this(TemplateInstance ti)\n    {\n        this.ti = ti;\n        this.ti.toHash();\n        assert(this.ti.hash);\n    }\n\n    size_t toHash() const @trusted pure nothrow\n    {\n        assert(ti.hash);\n        return ti.hash;\n    }\n\n    bool opEquals(ref const TemplateInstanceBox s) @trusted const\n    {\n        bool res = void;\n        if (ti.inst && s.ti.inst)\n            /* This clause is only used when an instance with errors\n             * is replaced with a correct instance.\n             */\n            res = ti is s.ti;\n        else\n            /* Used when a proposed instance is used to see if there's\n             * an existing instance.\n             */\n            res = (cast()s.ti).compare(cast()ti) == 0;\n\n        debug (FindExistingInstance) ++(res ? nHits : nCollisions);\n        return res;\n    }\n\n    debug (FindExistingInstance)\n    {\n        __gshared uint nHits, nCollisions;\n\n        shared static ~this()\n        {\n            printf(\"debug (FindExistingInstance) TemplateInstanceBox.equals hits: %u collisions: %u\\n\",\n                   nHits, nCollisions);\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/dversion.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dversion.d, _dversion.d)\n * Documentation:  https://dlang.org/phobos/dmd_dversion.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dversion.d\n */\n\nmodule dmd.dversion;\n\nimport dmd.arraytypes;\nimport dmd.cond;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.globals;\nimport dmd.identifier;\nimport dmd.root.outbuffer;\nimport dmd.visitor;\n\n/***********************************************************\n * DebugSymbol's happen for statements like:\n *      debug = identifier;\n *      debug = integer;\n */\nextern (C++) final class DebugSymbol : Dsymbol\n{\n    uint level;\n\n    extern (D) this(const ref Loc loc, Identifier ident)\n    {\n        super(ident);\n        this.loc = loc;\n    }\n\n    extern (D) this(const ref Loc loc, uint level)\n    {\n        this.level = level;\n        this.loc = loc;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto ds = new DebugSymbol(loc, ident);\n        ds.level = level;\n        return ds;\n    }\n\n    override const(char)* toChars() const nothrow\n    {\n        if (ident)\n            return ident.toChars();\n        else\n        {\n            OutBuffer buf;\n            buf.print(level);\n            return buf.extractString();\n        }\n    }\n\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        //printf(\"DebugSymbol::addMember('%s') %s\\n\", sds.toChars(), toChars());\n        Module m = sds.isModule();\n        // Do not add the member to the symbol table,\n        // just make sure subsequent debug declarations work.\n        if (ident)\n        {\n            if (!m)\n            {\n                error(\"declaration must be at module level\");\n                errors = true;\n            }\n            else\n            {\n                if (findCondition(m.debugidsNot, ident))\n                {\n                    error(\"defined after use\");\n                    errors = true;\n                }\n                if (!m.debugids)\n                    m.debugids = new Identifiers();\n                m.debugids.push(ident);\n            }\n        }\n        else\n        {\n            if (!m)\n            {\n                error(\"level declaration must be at module level\");\n                errors = true;\n            }\n            else\n                m.debuglevel = level;\n        }\n    }\n\n    override const(char)* kind() const nothrow\n    {\n        return \"debug\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * VersionSymbol's happen for statements like:\n *      version = identifier;\n *      version = integer;\n */\nextern (C++) final class VersionSymbol : Dsymbol\n{\n    uint level;\n\n    extern (D) this(const ref Loc loc, Identifier ident)\n    {\n        super(ident);\n        this.loc = loc;\n    }\n\n    extern (D) this(const ref Loc loc, uint level)\n    {\n        this.level = level;\n        this.loc = loc;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto ds = ident ? new VersionSymbol(loc, ident)\n                        : new VersionSymbol(loc, level);\n        return ds;\n    }\n\n    override const(char)* toChars() nothrow\n    {\n        if (ident)\n            return ident.toChars();\n        else\n        {\n            OutBuffer buf;\n            buf.print(level);\n            return buf.extractString();\n        }\n    }\n\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        //printf(\"VersionSymbol::addMember('%s') %s\\n\", sds.toChars(), toChars());\n        Module m = sds.isModule();\n        // Do not add the member to the symbol table,\n        // just make sure subsequent debug declarations work.\n        if (ident)\n        {\n            VersionCondition.checkReserved(loc, ident.toString());\n            if (!m)\n            {\n                error(\"declaration must be at module level\");\n                errors = true;\n            }\n            else\n            {\n                if (findCondition(m.versionidsNot, ident))\n                {\n                    error(\"defined after use\");\n                    errors = true;\n                }\n                if (!m.versionids)\n                    m.versionids = new Identifiers();\n                m.versionids.push(ident);\n            }\n        }\n        else\n        {\n            if (!m)\n            {\n                error(\"level declaration must be at module level\");\n                errors = true;\n            }\n            else\n                m.versionlevel = level;\n        }\n    }\n\n    override const(char)* kind() const nothrow\n    {\n        return \"version\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/entity.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/entity.d, _entity.d)\n * Documentation:  https://dlang.org/phobos/dmd_entity.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/entity.d\n */\n\nmodule dmd.entity;\n\nimport core.stdc.ctype;\n\nprivate:\n\n/*********************************************\n * Convert from named entity to its encoding.\n * For reference:\n *      http://www.htmlhelp.com/reference/html40/entities/\n *      http://www.w3.org/2003/entities/2007/w3centities-f.ent\n */\nstruct NameId\n{\n    string name;\n    uint value;\n}\n\nimmutable NameId[] namesA =\n[\n    {\"Aacgr\",            0x00386},  // GREEK CAPITAL LETTER ALPHA WITH TONOS\n    {\"aacgr\",            0x003AC},  // GREEK SMALL LETTER ALPHA WITH TONOS\n    {\"Aacute\",           0x000C1},  // LATIN CAPITAL LETTER A WITH ACUTE\n    {\"aacute\",           0x000E1},  // LATIN SMALL LETTER A WITH ACUTE\n    {\"Abreve\",           0x00102},  // LATIN CAPITAL LETTER A WITH BREVE\n    {\"abreve\",           0x00103},  // LATIN SMALL LETTER A WITH BREVE\n    {\"ac\",               0x0223E},  // INVERTED LAZY S\n    {\"acd\",              0x0223F},  // SINE WAVE\n//  {\"acE\",              0x0223E;0x00333},  // INVERTED LAZY S with double underline\n    {\"Acirc\",            0x000C2},  // LATIN CAPITAL LETTER A WITH CIRCUMFLEX\n    {\"acirc\",            0x000E2},  // LATIN SMALL LETTER A WITH CIRCUMFLEX\n    {\"acute\",            0x000B4},  // ACUTE ACCENT\n    {\"Acy\",              0x00410},  // CYRILLIC CAPITAL LETTER A\n    {\"acy\",              0x00430},  // CYRILLIC SMALL LETTER A\n    {\"AElig\",            0x000C6},  // LATIN CAPITAL LETTER AE\n    {\"aelig\",            0x000E6},  // LATIN SMALL LETTER AE\n    {\"af\",               0x02061},  // FUNCTION APPLICATION\n    {\"Afr\",              0x1D504},  // MATHEMATICAL FRAKTUR CAPITAL A\n    {\"afr\",              0x1D51E},  // MATHEMATICAL FRAKTUR SMALL A\n    {\"Agr\",              0x00391},  // GREEK CAPITAL LETTER ALPHA\n    {\"agr\",              0x003B1},  // GREEK SMALL LETTER ALPHA\n    {\"Agrave\",           0x000C0},  // LATIN CAPITAL LETTER A WITH GRAVE\n    {\"agrave\",           0x000E0},  // LATIN SMALL LETTER A WITH GRAVE\n    {\"alefsym\",          0x02135},  // ALEF SYMBOL\n    {\"aleph\",            0x02135},  // ALEF SYMBOL\n    {\"Alpha\",            0x00391},  // GREEK CAPITAL LETTER ALPHA\n    {\"alpha\",            0x003B1},  // GREEK SMALL LETTER ALPHA\n    {\"Amacr\",            0x00100},  // LATIN CAPITAL LETTER A WITH MACRON\n    {\"amacr\",            0x00101},  // LATIN SMALL LETTER A WITH MACRON\n    {\"amalg\",            0x02A3F},  // AMALGAMATION OR COPRODUCT\n    {\"amp\",              0x00026},  // AMPERSAND\n    {\"AMP\",              0x00026},  // AMPERSAND\n    {\"and\",              0x02227},  // LOGICAL AND\n    {\"And\",              0x02A53},  // DOUBLE LOGICAL AND\n    {\"andand\",           0x02A55},  // TWO INTERSECTING LOGICAL AND\n    {\"andd\",             0x02A5C},  // LOGICAL AND WITH HORIZONTAL DASH\n    {\"andslope\",         0x02A58},  // SLOPING LARGE AND\n    {\"andv\",             0x02A5A},  // LOGICAL AND WITH MIDDLE STEM\n    {\"ang\",              0x02220},  // ANGLE\n    {\"ange\",             0x029A4},  // ANGLE WITH UNDERBAR\n    {\"angle\",            0x02220},  // ANGLE\n    {\"angmsd\",           0x02221},  // MEASURED ANGLE\n    {\"angmsdaa\",         0x029A8},  // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT\n    {\"angmsdab\",         0x029A9},  // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT\n    {\"angmsdac\",         0x029AA},  // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT\n    {\"angmsdad\",         0x029AB},  // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT\n    {\"angmsdae\",         0x029AC},  // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP\n    {\"angmsdaf\",         0x029AD},  // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP\n    {\"angmsdag\",         0x029AE},  // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN\n    {\"angmsdah\",         0x029AF},  // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN\n    {\"angrt\",            0x0221F},  // RIGHT ANGLE\n    {\"angrtvb\",          0x022BE},  // RIGHT ANGLE WITH ARC\n    {\"angrtvbd\",         0x0299D},  // MEASURED RIGHT ANGLE WITH DOT\n    {\"angsph\",           0x02222},  // SPHERICAL ANGLE\n    {\"angst\",            0x000C5},  // LATIN CAPITAL LETTER A WITH RING ABOVE\n    {\"angzarr\",          0x0237C},  // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW\n    {\"Aogon\",            0x00104},  // LATIN CAPITAL LETTER A WITH OGONEK\n    {\"aogon\",            0x00105},  // LATIN SMALL LETTER A WITH OGONEK\n    {\"Aopf\",             0x1D538},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL A\n    {\"aopf\",             0x1D552},  // MATHEMATICAL DOUBLE-STRUCK SMALL A\n    {\"ap\",               0x02248},  // ALMOST EQUAL TO\n    {\"apacir\",           0x02A6F},  // ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT\n    {\"ape\",              0x0224A},  // ALMOST EQUAL OR EQUAL TO\n    {\"apE\",              0x02A70},  // APPROXIMATELY EQUAL OR EQUAL TO\n    {\"apid\",             0x0224B},  // TRIPLE TILDE\n    {\"apos\",             0x00027},  // APOSTROPHE\n    {\"ApplyFunction\",    0x02061},  // FUNCTION APPLICATION\n    {\"approx\",           0x02248},  // ALMOST EQUAL TO\n    {\"approxeq\",         0x0224A},  // ALMOST EQUAL OR EQUAL TO\n    {\"Aring\",            0x000C5},  // LATIN CAPITAL LETTER A WITH RING ABOVE\n    {\"aring\",            0x000E5},  // LATIN SMALL LETTER A WITH RING ABOVE\n    {\"Ascr\",             0x1D49C},  // MATHEMATICAL SCRIPT CAPITAL A\n    {\"ascr\",             0x1D4B6},  // MATHEMATICAL SCRIPT SMALL A\n    {\"Assign\",           0x02254},  // COLON EQUALS\n    {\"ast\",              0x0002A},  // ASTERISK\n    {\"asymp\",            0x02248},  // ALMOST EQUAL TO\n    {\"asympeq\",          0x0224D},  // EQUIVALENT TO\n    {\"Atilde\",           0x000C3},  // LATIN CAPITAL LETTER A WITH TILDE\n    {\"atilde\",           0x000E3},  // LATIN SMALL LETTER A WITH TILDE\n    {\"Auml\",             0x000C4},  // LATIN CAPITAL LETTER A WITH DIAERESIS\n    {\"auml\",             0x000E4},  // LATIN SMALL LETTER A WITH DIAERESIS\n    {\"awconint\",         0x02233},  // ANTICLOCKWISE CONTOUR INTEGRAL\n    {\"awint\",            0x02A11},  // ANTICLOCKWISE INTEGRATION\n];\n\nimmutable NameId[] namesB =\n[\n    {\"backcong\",         0x0224C},  // ALL EQUAL TO\n    {\"backepsilon\",      0x003F6},  // GREEK REVERSED LUNATE EPSILON SYMBOL\n    {\"backprime\",        0x02035},  // REVERSED PRIME\n    {\"backsim\",          0x0223D},  // REVERSED TILDE\n    {\"backsimeq\",        0x022CD},  // REVERSED TILDE EQUALS\n    {\"Backslash\",        0x02216},  // SET MINUS\n//  \"b.alpha\",          0x1D6C2},  // MATHEMATICAL BOLD SMALL ALPHA\n    {\"Barv\",             0x02AE7},  // SHORT DOWN TACK WITH OVERBAR\n    {\"barvee\",           0x022BD},  // NOR\n    {\"barwed\",           0x02305},  // PROJECTIVE\n    {\"Barwed\",           0x02306},  // PERSPECTIVE\n    {\"barwedge\",         0x02305},  // PROJECTIVE\n//  \"b.beta\",           0x1D6C3},  // MATHEMATICAL BOLD SMALL BETA\n    {\"bbrk\",             0x023B5},  // BOTTOM SQUARE BRACKET\n    {\"bbrktbrk\",         0x023B6},  // BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET\n//  \"b.chi\",            0x1D6D8},  // MATHEMATICAL BOLD SMALL CHI\n    {\"bcong\",            0x0224C},  // ALL EQUAL TO\n    {\"Bcy\",              0x00411},  // CYRILLIC CAPITAL LETTER BE\n    {\"bcy\",              0x00431},  // CYRILLIC SMALL LETTER BE\n//  \"b.Delta\",          0x1D6AB},  // MATHEMATICAL BOLD CAPITAL DELTA\n//  \"b.delta\",          0x1D6C5},  // MATHEMATICAL BOLD SMALL DELTA\n    {\"bdquo\",            0x0201E},  // DOUBLE LOW-9 QUOTATION MARK\n    {\"becaus\",           0x02235},  // BECAUSE\n    {\"because\",          0x02235},  // BECAUSE\n    {\"Because\",          0x02235},  // BECAUSE\n    {\"bemptyv\",          0x029B0},  // REVERSED EMPTY SET\n    {\"bepsi\",            0x003F6},  // GREEK REVERSED LUNATE EPSILON SYMBOL\n//  \"b.epsi\",           0x1D6C6},  // MATHEMATICAL BOLD SMALL EPSILON\n//  \"b.epsiv\",          0x1D6DC},  // MATHEMATICAL BOLD EPSILON SYMBOL\n    {\"bernou\",           0x0212C},  // SCRIPT CAPITAL B\n    {\"Bernoullis\",       0x0212C},  // SCRIPT CAPITAL B\n    {\"Beta\",             0x00392},  // GREEK CAPITAL LETTER BETA\n    {\"beta\",             0x003B2},  // GREEK SMALL LETTER BETA\n//  \"b.eta\",            0x1D6C8},  // MATHEMATICAL BOLD SMALL ETA\n    {\"beth\",             0x02136},  // BET SYMBOL\n    {\"between\",          0x0226C},  // BETWEEN\n    {\"Bfr\",              0x1D505},  // MATHEMATICAL FRAKTUR CAPITAL B\n    {\"bfr\",              0x1D51F},  // MATHEMATICAL FRAKTUR SMALL B\n//  \"b.Gamma\",          0x1D6AA},  // MATHEMATICAL BOLD CAPITAL GAMMA\n//  \"b.gamma\",          0x1D6C4},  // MATHEMATICAL BOLD SMALL GAMMA\n//  \"b.Gammad\",         0x1D7CA},  // MATHEMATICAL BOLD CAPITAL DIGAMMA\n//  \"b.gammad\",         0x1D7CB},  // MATHEMATICAL BOLD SMALL DIGAMMA\n    {\"Bgr\",              0x00392},  // GREEK CAPITAL LETTER BETA\n    {\"bgr\",              0x003B2},  // GREEK SMALL LETTER BETA\n    {\"bigcap\",           0x022C2},  // N-ARY INTERSECTION\n    {\"bigcirc\",          0x025EF},  // LARGE CIRCLE\n    {\"bigcup\",           0x022C3},  // N-ARY UNION\n    {\"bigodot\",          0x02A00},  // N-ARY CIRCLED DOT OPERATOR\n    {\"bigoplus\",         0x02A01},  // N-ARY CIRCLED PLUS OPERATOR\n    {\"bigotimes\",        0x02A02},  // N-ARY CIRCLED TIMES OPERATOR\n    {\"bigsqcup\",         0x02A06},  // N-ARY SQUARE UNION OPERATOR\n    {\"bigstar\",          0x02605},  // BLACK STAR\n    {\"bigtriangledown\",  0x025BD},  // WHITE DOWN-POINTING TRIANGLE\n    {\"bigtriangleup\",    0x025B3},  // WHITE UP-POINTING TRIANGLE\n    {\"biguplus\",         0x02A04},  // N-ARY UNION OPERATOR WITH PLUS\n    {\"bigvee\",           0x022C1},  // N-ARY LOGICAL OR\n    {\"bigwedge\",         0x022C0},  // N-ARY LOGICAL AND\n//  \"b.iota\",           0x1D6CA},  // MATHEMATICAL BOLD SMALL IOTA\n//  \"b.kappa\",          0x1D6CB},  // MATHEMATICAL BOLD SMALL KAPPA\n//  \"b.kappav\",         0x1D6DE},  // MATHEMATICAL BOLD KAPPA SYMBOL\n    {\"bkarow\",           0x0290D},  // RIGHTWARDS DOUBLE DASH ARROW\n    {\"blacklozenge\",     0x029EB},  // BLACK LOZENGE\n    {\"blacksquare\",      0x025AA},  // BLACK SMALL SQUARE\n    {\"blacktriangle\",    0x025B4},  // BLACK UP-POINTING SMALL TRIANGLE\n    {\"blacktriangledown\", 0x025BE},  // BLACK DOWN-POINTING SMALL TRIANGLE\n    {\"blacktriangleleft\", 0x025C2},  // BLACK LEFT-POINTING SMALL TRIANGLE\n    {\"blacktriangleright\", 0x025B8},  // BLACK RIGHT-POINTING SMALL TRIANGLE\n//  \"b.Lambda\",         0x1D6B2},  // MATHEMATICAL BOLD CAPITAL LAMDA\n//  \"b.lambda\",         0x1D6CC},  // MATHEMATICAL BOLD SMALL LAMDA\n    {\"blank\",            0x02423},  // OPEN BOX\n    {\"blk12\",            0x02592},  // MEDIUM SHADE\n    {\"blk14\",            0x02591},  // LIGHT SHADE\n    {\"blk34\",            0x02593},  // DARK SHADE\n    {\"block\",            0x02588},  // FULL BLOCK\n//  \"b.mu\",             0x1D6CD},  // MATHEMATICAL BOLD SMALL MU\n//  \"bne\",              0x0003D;0x020E5},  // EQUALS SIGN with reverse slash\n//  \"bnequiv\",          0x02261;0x020E5},  // IDENTICAL TO with reverse slash\n    {\"bnot\",             0x02310},  // REVERSED NOT SIGN\n    {\"bNot\",             0x02AED},  // REVERSED DOUBLE STROKE NOT SIGN\n//  \"b.nu\",             0x1D6CE},  // MATHEMATICAL BOLD SMALL NU\n//  \"b.Omega\",          0x1D6C0},  // MATHEMATICAL BOLD CAPITAL OMEGA\n//  \"b.omega\",          0x1D6DA},  // MATHEMATICAL BOLD SMALL OMEGA\n    {\"Bopf\",             0x1D539},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL B\n    {\"bopf\",             0x1D553},  // MATHEMATICAL DOUBLE-STRUCK SMALL B\n    {\"bot\",              0x022A5},  // UP TACK\n    {\"bottom\",           0x022A5},  // UP TACK\n    {\"bowtie\",           0x022C8},  // BOWTIE\n    {\"boxbox\",           0x029C9},  // TWO JOINED SQUARES\n    {\"boxdl\",            0x02510},  // BOX DRAWINGS LIGHT DOWN AND LEFT\n    {\"boxdL\",            0x02555},  // BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE\n    {\"boxDl\",            0x02556},  // BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE\n    {\"boxDL\",            0x02557},  // BOX DRAWINGS DOUBLE DOWN AND LEFT\n    {\"boxdr\",            0x0250C},  // BOX DRAWINGS LIGHT DOWN AND RIGHT\n    {\"boxdR\",            0x02552},  // BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE\n    {\"boxDr\",            0x02553},  // BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE\n    {\"boxDR\",            0x02554},  // BOX DRAWINGS DOUBLE DOWN AND RIGHT\n    {\"boxh\",             0x02500},  // BOX DRAWINGS LIGHT HORIZONTAL\n    {\"boxH\",             0x02550},  // BOX DRAWINGS DOUBLE HORIZONTAL\n    {\"boxhd\",            0x0252C},  // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL\n    {\"boxHd\",            0x02564},  // BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE\n    {\"boxhD\",            0x02565},  // BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE\n    {\"boxHD\",            0x02566},  // BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL\n    {\"boxhu\",            0x02534},  // BOX DRAWINGS LIGHT UP AND HORIZONTAL\n    {\"boxHu\",            0x02567},  // BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE\n    {\"boxhU\",            0x02568},  // BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE\n    {\"boxHU\",            0x02569},  // BOX DRAWINGS DOUBLE UP AND HORIZONTAL\n    {\"boxminus\",         0x0229F},  // SQUARED MINUS\n    {\"boxplus\",          0x0229E},  // SQUARED PLUS\n    {\"boxtimes\",         0x022A0},  // SQUARED TIMES\n    {\"boxul\",            0x02518},  // BOX DRAWINGS LIGHT UP AND LEFT\n    {\"boxuL\",            0x0255B},  // BOX DRAWINGS UP SINGLE AND LEFT DOUBLE\n    {\"boxUl\",            0x0255C},  // BOX DRAWINGS UP DOUBLE AND LEFT SINGLE\n    {\"boxUL\",            0x0255D},  // BOX DRAWINGS DOUBLE UP AND LEFT\n    {\"boxur\",            0x02514},  // BOX DRAWINGS LIGHT UP AND RIGHT\n    {\"boxuR\",            0x02558},  // BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE\n    {\"boxUr\",            0x02559},  // BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE\n    {\"boxUR\",            0x0255A},  // BOX DRAWINGS DOUBLE UP AND RIGHT\n    {\"boxv\",             0x02502},  // BOX DRAWINGS LIGHT VERTICAL\n    {\"boxV\",             0x02551},  // BOX DRAWINGS DOUBLE VERTICAL\n    {\"boxvh\",            0x0253C},  // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL\n    {\"boxvH\",            0x0256A},  // BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE\n    {\"boxVh\",            0x0256B},  // BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE\n    {\"boxVH\",            0x0256C},  // BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL\n    {\"boxvl\",            0x02524},  // BOX DRAWINGS LIGHT VERTICAL AND LEFT\n    {\"boxvL\",            0x02561},  // BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE\n    {\"boxVl\",            0x02562},  // BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE\n    {\"boxVL\",            0x02563},  // BOX DRAWINGS DOUBLE VERTICAL AND LEFT\n    {\"boxvr\",            0x0251C},  // BOX DRAWINGS LIGHT VERTICAL AND RIGHT\n    {\"boxvR\",            0x0255E},  // BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE\n    {\"boxVr\",            0x0255F},  // BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE\n    {\"boxVR\",            0x02560},  // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT\n//  \"b.Phi\",            0x1D6BD},  // MATHEMATICAL BOLD CAPITAL PHI\n//  \"b.phi\",            0x1D6D7},  // MATHEMATICAL BOLD SMALL PHI\n//  \"b.phiv\",           0x1D6DF},  // MATHEMATICAL BOLD PHI SYMBOL\n//  \"b.Pi\",             0x1D6B7},  // MATHEMATICAL BOLD CAPITAL PI\n//  \"b.pi\",             0x1D6D1},  // MATHEMATICAL BOLD SMALL PI\n//  \"b.piv\",            0x1D6E1},  // MATHEMATICAL BOLD PI SYMBOL\n    {\"bprime\",           0x02035},  // REVERSED PRIME\n//  \"b.Psi\",            0x1D6BF},  // MATHEMATICAL BOLD CAPITAL PSI\n//  \"b.psi\",            0x1D6D9},  // MATHEMATICAL BOLD SMALL PSI\n    {\"breve\",            0x002D8},  // BREVE\n    {\"Breve\",            0x002D8},  // BREVE\n//  \"b.rho\",            0x1D6D2},  // MATHEMATICAL BOLD SMALL RHO\n//  \"b.rhov\",           0x1D6E0},  // MATHEMATICAL BOLD RHO SYMBOL\n    {\"brvbar\",           0x000A6},  // BROKEN BAR\n    {\"Bscr\",             0x0212C},  // SCRIPT CAPITAL B\n    {\"bscr\",             0x1D4B7},  // MATHEMATICAL SCRIPT SMALL B\n    {\"bsemi\",            0x0204F},  // REVERSED SEMICOLON\n//  \"b.Sigma\",          0x1D6BA},  // MATHEMATICAL BOLD CAPITAL SIGMA\n//  \"b.sigma\",          0x1D6D4},  // MATHEMATICAL BOLD SMALL SIGMA\n//  \"b.sigmav\",         0x1D6D3},  // MATHEMATICAL BOLD SMALL FINAL SIGMA\n    {\"bsim\",             0x0223D},  // REVERSED TILDE\n    {\"bsime\",            0x022CD},  // REVERSED TILDE EQUALS\n    {\"bsol\",             0x0005C},  // REVERSE SOLIDUS\n    {\"bsolb\",            0x029C5},  // SQUARED FALLING DIAGONAL SLASH\n    {\"bsolhsub\",         0x027C8},  // REVERSE SOLIDUS PRECEDING SUBSET\n//  \"b.tau\",            0x1D6D5},  // MATHEMATICAL BOLD SMALL TAU\n//  \"b.Theta\",          0x1D6AF},  // MATHEMATICAL BOLD CAPITAL THETA\n//  \"b.thetas\",         0x1D6C9},  // MATHEMATICAL BOLD SMALL THETA\n//  \"b.thetav\",         0x1D6DD},  // MATHEMATICAL BOLD THETA SYMBOL\n    {\"bull\",             0x02022},  // BULLET\n    {\"bullet\",           0x02022},  // BULLET\n    {\"bump\",             0x0224E},  // GEOMETRICALLY EQUIVALENT TO\n    {\"bumpe\",            0x0224F},  // DIFFERENCE BETWEEN\n    {\"bumpE\",            0x02AAE},  // EQUALS SIGN WITH BUMPY ABOVE\n    {\"Bumpeq\",           0x0224E},  // GEOMETRICALLY EQUIVALENT TO\n    {\"bumpeq\",           0x0224F},  // DIFFERENCE BETWEEN\n//  \"b.Upsi\",           0x1D6BC},  // MATHEMATICAL BOLD CAPITAL UPSILON\n//  \"b.upsi\",           0x1D6D6},  // MATHEMATICAL BOLD SMALL UPSILON\n//  \"b.Xi\",             0x1D6B5},  // MATHEMATICAL BOLD CAPITAL XI\n//  \"b.xi\",             0x1D6CF},  // MATHEMATICAL BOLD SMALL XI\n//  \"b.zeta\",           0x1D6C7},  // MATHEMATICAL BOLD SMALL ZETA\n];\n\nimmutable NameId[] namesC =\n[\n    {\"Cacute\",           0x00106},  // LATIN CAPITAL LETTER C WITH ACUTE\n    {\"cacute\",           0x00107},  // LATIN SMALL LETTER C WITH ACUTE\n    {\"cap\",              0x02229},  // INTERSECTION\n    {\"Cap\",              0x022D2},  // DOUBLE INTERSECTION\n    {\"capand\",           0x02A44},  // INTERSECTION WITH LOGICAL AND\n    {\"capbrcup\",         0x02A49},  // INTERSECTION ABOVE BAR ABOVE UNION\n    {\"capcap\",           0x02A4B},  // INTERSECTION BESIDE AND JOINED WITH INTERSECTION\n    {\"capcup\",           0x02A47},  // INTERSECTION ABOVE UNION\n    {\"capdot\",           0x02A40},  // INTERSECTION WITH DOT\n    {\"CapitalDifferentialD\", 0x02145},  // DOUBLE-STRUCK ITALIC CAPITAL D\n//  \"caps\",             0x02229;0x0FE00},  // INTERSECTION with serifs\n    {\"caret\",            0x02041},  // CARET INSERTION POINT\n    {\"caron\",            0x002C7},  // CARON\n    {\"Cayleys\",          0x0212D},  // BLACK-LETTER CAPITAL C\n    {\"ccaps\",            0x02A4D},  // CLOSED INTERSECTION WITH SERIFS\n    {\"Ccaron\",           0x0010C},  // LATIN CAPITAL LETTER C WITH CARON\n    {\"ccaron\",           0x0010D},  // LATIN SMALL LETTER C WITH CARON\n    {\"Ccedil\",           0x000C7},  // LATIN CAPITAL LETTER C WITH CEDILLA\n    {\"ccedil\",           0x000E7},  // LATIN SMALL LETTER C WITH CEDILLA\n    {\"Ccirc\",            0x00108},  // LATIN CAPITAL LETTER C WITH CIRCUMFLEX\n    {\"ccirc\",            0x00109},  // LATIN SMALL LETTER C WITH CIRCUMFLEX\n    {\"Cconint\",          0x02230},  // VOLUME INTEGRAL\n    {\"ccups\",            0x02A4C},  // CLOSED UNION WITH SERIFS\n    {\"ccupssm\",          0x02A50},  // CLOSED UNION WITH SERIFS AND SMASH PRODUCT\n    {\"Cdot\",             0x0010A},  // LATIN CAPITAL LETTER C WITH DOT ABOVE\n    {\"cdot\",             0x0010B},  // LATIN SMALL LETTER C WITH DOT ABOVE\n    {\"cedil\",            0x000B8},  // CEDILLA\n    {\"Cedilla\",          0x000B8},  // CEDILLA\n    {\"cemptyv\",          0x029B2},  // EMPTY SET WITH SMALL CIRCLE ABOVE\n    {\"cent\",             0x000A2},  // CENT SIGN\n    {\"centerdot\",        0x000B7},  // MIDDLE DOT\n    {\"CenterDot\",        0x000B7},  // MIDDLE DOT\n    {\"Cfr\",              0x0212D},  // BLACK-LETTER CAPITAL C\n    {\"cfr\",              0x1D520},  // MATHEMATICAL FRAKTUR SMALL C\n    {\"CHcy\",             0x00427},  // CYRILLIC CAPITAL LETTER CHE\n    {\"chcy\",             0x00447},  // CYRILLIC SMALL LETTER CHE\n    {\"check\",            0x02713},  // CHECK MARK\n    {\"checkmark\",        0x02713},  // CHECK MARK\n    {\"Chi\",              0x003A7},  // GREEK CAPITAL LETTER CHI\n    {\"chi\",              0x003C7},  // GREEK SMALL LETTER CHI\n    {\"cir\",              0x025CB},  // WHITE CIRCLE\n    {\"circ\",             0x002C6},  // MODIFIER LETTER CIRCUMFLEX ACCENT\n    {\"circeq\",           0x02257},  // RING EQUAL TO\n    {\"circlearrowleft\",  0x021BA},  // ANTICLOCKWISE OPEN CIRCLE ARROW\n    {\"circlearrowright\", 0x021BB},  // CLOCKWISE OPEN CIRCLE ARROW\n    {\"circledast\",       0x0229B},  // CIRCLED ASTERISK OPERATOR\n    {\"circledcirc\",      0x0229A},  // CIRCLED RING OPERATOR\n    {\"circleddash\",      0x0229D},  // CIRCLED DASH\n    {\"CircleDot\",        0x02299},  // CIRCLED DOT OPERATOR\n    {\"circledR\",         0x000AE},  // REGISTERED SIGN\n    {\"circledS\",         0x024C8},  // CIRCLED LATIN CAPITAL LETTER S\n    {\"CircleMinus\",      0x02296},  // CIRCLED MINUS\n    {\"CirclePlus\",       0x02295},  // CIRCLED PLUS\n    {\"CircleTimes\",      0x02297},  // CIRCLED TIMES\n    {\"cire\",             0x02257},  // RING EQUAL TO\n    {\"cirE\",             0x029C3},  // CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT\n    {\"cirfnint\",         0x02A10},  // CIRCULATION FUNCTION\n    {\"cirmid\",           0x02AEF},  // VERTICAL LINE WITH CIRCLE ABOVE\n    {\"cirscir\",          0x029C2},  // CIRCLE WITH SMALL CIRCLE TO THE RIGHT\n    {\"ClockwiseContourIntegral\", 0x02232},  // CLOCKWISE CONTOUR INTEGRAL\n    {\"CloseCurlyDoubleQuote\", 0x0201D},  // RIGHT DOUBLE QUOTATION MARK\n    {\"CloseCurlyQuote\",  0x02019},  // RIGHT SINGLE QUOTATION MARK\n    {\"clubs\",            0x02663},  // BLACK CLUB SUIT\n    {\"clubsuit\",         0x02663},  // BLACK CLUB SUIT\n    {\"colon\",            0x0003A},  // COLON\n    {\"Colon\",            0x02237},  // PROPORTION\n    {\"colone\",           0x02254},  // COLON EQUALS\n    {\"Colone\",           0x02A74},  // DOUBLE COLON EQUAL\n    {\"coloneq\",          0x02254},  // COLON EQUALS\n    {\"comma\",            0x0002C},  // COMMA\n    {\"commat\",           0x00040},  // COMMERCIAL AT\n    {\"comp\",             0x02201},  // COMPLEMENT\n    {\"compfn\",           0x02218},  // RING OPERATOR\n    {\"complement\",       0x02201},  // COMPLEMENT\n    {\"complexes\",        0x02102},  // DOUBLE-STRUCK CAPITAL C\n    {\"cong\",             0x02245},  // APPROXIMATELY EQUAL TO\n    {\"congdot\",          0x02A6D},  // CONGRUENT WITH DOT ABOVE\n    {\"Congruent\",        0x02261},  // IDENTICAL TO\n    {\"conint\",           0x0222E},  // CONTOUR INTEGRAL\n    {\"Conint\",           0x0222F},  // SURFACE INTEGRAL\n    {\"ContourIntegral\",  0x0222E},  // CONTOUR INTEGRAL\n    {\"Copf\",             0x02102},  // DOUBLE-STRUCK CAPITAL C\n    {\"copf\",             0x1D554},  // MATHEMATICAL DOUBLE-STRUCK SMALL C\n    {\"coprod\",           0x02210},  // N-ARY COPRODUCT\n    {\"Coproduct\",        0x02210},  // N-ARY COPRODUCT\n    {\"copy\",             0x000A9},  // COPYRIGHT SIGN\n    {\"COPY\",             0x000A9},  // COPYRIGHT SIGN\n    {\"copysr\",           0x02117},  // SOUND RECORDING COPYRIGHT\n    {\"CounterClockwiseContourIntegral\", 0x02233},  // ANTICLOCKWISE CONTOUR INTEGRAL\n    {\"crarr\",            0x021B5},  // DOWNWARDS ARROW WITH CORNER LEFTWARDS\n    {\"cross\",            0x02717},  // BALLOT X\n    {\"Cross\",            0x02A2F},  // VECTOR OR CROSS PRODUCT\n    {\"Cscr\",             0x1D49E},  // MATHEMATICAL SCRIPT CAPITAL C\n    {\"cscr\",             0x1D4B8},  // MATHEMATICAL SCRIPT SMALL C\n    {\"csub\",             0x02ACF},  // CLOSED SUBSET\n    {\"csube\",            0x02AD1},  // CLOSED SUBSET OR EQUAL TO\n    {\"csup\",             0x02AD0},  // CLOSED SUPERSET\n    {\"csupe\",            0x02AD2},  // CLOSED SUPERSET OR EQUAL TO\n    {\"ctdot\",            0x022EF},  // MIDLINE HORIZONTAL ELLIPSIS\n    {\"cudarrl\",          0x02938},  // RIGHT-SIDE ARC CLOCKWISE ARROW\n    {\"cudarrr\",          0x02935},  // ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS\n    {\"cuepr\",            0x022DE},  // EQUAL TO OR PRECEDES\n    {\"cuesc\",            0x022DF},  // EQUAL TO OR SUCCEEDS\n    {\"cularr\",           0x021B6},  // ANTICLOCKWISE TOP SEMICIRCLE ARROW\n    {\"cularrp\",          0x0293D},  // TOP ARC ANTICLOCKWISE ARROW WITH PLUS\n    {\"cup\",              0x0222A},  // UNION\n    {\"Cup\",              0x022D3},  // DOUBLE UNION\n    {\"cupbrcap\",         0x02A48},  // UNION ABOVE BAR ABOVE INTERSECTION\n    {\"CupCap\",           0x0224D},  // EQUIVALENT TO\n    {\"cupcap\",           0x02A46},  // UNION ABOVE INTERSECTION\n    {\"cupcup\",           0x02A4A},  // UNION BESIDE AND JOINED WITH UNION\n    {\"cupdot\",           0x0228D},  // MULTISET MULTIPLICATION\n    {\"cupor\",            0x02A45},  // UNION WITH LOGICAL OR\n//  \"cups\",             0x0222A;0x0FE00},  // UNION with serifs\n    {\"curarr\",           0x021B7},  // CLOCKWISE TOP SEMICIRCLE ARROW\n    {\"curarrm\",          0x0293C},  // TOP ARC CLOCKWISE ARROW WITH MINUS\n    {\"curlyeqprec\",      0x022DE},  // EQUAL TO OR PRECEDES\n    {\"curlyeqsucc\",      0x022DF},  // EQUAL TO OR SUCCEEDS\n    {\"curlyvee\",         0x022CE},  // CURLY LOGICAL OR\n    {\"curlywedge\",       0x022CF},  // CURLY LOGICAL AND\n    {\"curren\",           0x000A4},  // CURRENCY SIGN\n    {\"curvearrowleft\",   0x021B6},  // ANTICLOCKWISE TOP SEMICIRCLE ARROW\n    {\"curvearrowright\",  0x021B7},  // CLOCKWISE TOP SEMICIRCLE ARROW\n    {\"cuvee\",            0x022CE},  // CURLY LOGICAL OR\n    {\"cuwed\",            0x022CF},  // CURLY LOGICAL AND\n    {\"cwconint\",         0x02232},  // CLOCKWISE CONTOUR INTEGRAL\n    {\"cwint\",            0x02231},  // CLOCKWISE INTEGRAL\n    {\"cylcty\",           0x0232D},  // CYLINDRICITY\n];\n\nimmutable NameId[] namesD =\n[\n    {\"dagger\",           0x02020},  // DAGGER\n    {\"Dagger\",           0x02021},  // DOUBLE DAGGER\n    {\"daleth\",           0x02138},  // DALET SYMBOL\n    {\"darr\",             0x02193},  // DOWNWARDS ARROW\n    {\"Darr\",             0x021A1},  // DOWNWARDS TWO HEADED ARROW\n    {\"dArr\",             0x021D3},  // DOWNWARDS DOUBLE ARROW\n    {\"dash\",             0x02010},  // HYPHEN\n    {\"dashv\",            0x022A3},  // LEFT TACK\n    {\"Dashv\",            0x02AE4},  // VERTICAL BAR DOUBLE LEFT TURNSTILE\n    {\"dbkarow\",          0x0290F},  // RIGHTWARDS TRIPLE DASH ARROW\n    {\"dblac\",            0x002DD},  // DOUBLE ACUTE ACCENT\n    {\"Dcaron\",           0x0010E},  // LATIN CAPITAL LETTER D WITH CARON\n    {\"dcaron\",           0x0010F},  // LATIN SMALL LETTER D WITH CARON\n    {\"Dcy\",              0x00414},  // CYRILLIC CAPITAL LETTER DE\n    {\"dcy\",              0x00434},  // CYRILLIC SMALL LETTER DE\n    {\"DD\",               0x02145},  // DOUBLE-STRUCK ITALIC CAPITAL D\n    {\"dd\",               0x02146},  // DOUBLE-STRUCK ITALIC SMALL D\n    {\"ddagger\",          0x02021},  // DOUBLE DAGGER\n    {\"ddarr\",            0x021CA},  // DOWNWARDS PAIRED ARROWS\n    {\"DDotrahd\",         0x02911},  // RIGHTWARDS ARROW WITH DOTTED STEM\n    {\"ddotseq\",          0x02A77},  // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW\n    {\"deg\",              0x000B0},  // DEGREE SIGN\n    {\"Del\",              0x02207},  // NABLA\n    {\"Delta\",            0x00394},  // GREEK CAPITAL LETTER DELTA\n    {\"delta\",            0x003B4},  // GREEK SMALL LETTER DELTA\n    {\"demptyv\",          0x029B1},  // EMPTY SET WITH OVERBAR\n    {\"dfisht\",           0x0297F},  // DOWN FISH TAIL\n    {\"Dfr\",              0x1D507},  // MATHEMATICAL FRAKTUR CAPITAL D\n    {\"dfr\",              0x1D521},  // MATHEMATICAL FRAKTUR SMALL D\n    {\"Dgr\",              0x00394},  // GREEK CAPITAL LETTER DELTA\n    {\"dgr\",              0x003B4},  // GREEK SMALL LETTER DELTA\n    {\"dHar\",             0x02965},  // DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT\n    {\"dharl\",            0x021C3},  // DOWNWARDS HARPOON WITH BARB LEFTWARDS\n    {\"dharr\",            0x021C2},  // DOWNWARDS HARPOON WITH BARB RIGHTWARDS\n    {\"DiacriticalAcute\", 0x000B4},  // ACUTE ACCENT\n    {\"DiacriticalDot\",   0x002D9},  // DOT ABOVE\n    {\"DiacriticalDoubleAcute\", 0x002DD},  // DOUBLE ACUTE ACCENT\n    {\"DiacriticalGrave\", 0x00060},  // GRAVE ACCENT\n    {\"DiacriticalTilde\", 0x002DC},  // SMALL TILDE\n    {\"diam\",             0x022C4},  // DIAMOND OPERATOR\n    {\"diamond\",          0x022C4},  // DIAMOND OPERATOR\n    {\"Diamond\",          0x022C4},  // DIAMOND OPERATOR\n    {\"diamondsuit\",      0x02666},  // BLACK DIAMOND SUIT\n    {\"diams\",            0x02666},  // BLACK DIAMOND SUIT\n    {\"die\",              0x000A8},  // DIAERESIS\n    {\"DifferentialD\",    0x02146},  // DOUBLE-STRUCK ITALIC SMALL D\n    {\"digamma\",          0x003DD},  // GREEK SMALL LETTER DIGAMMA\n    {\"disin\",            0x022F2},  // ELEMENT OF WITH LONG HORIZONTAL STROKE\n    {\"div\",              0x000F7},  // DIVISION SIGN\n    {\"divide\",           0x000F7},  // DIVISION SIGN\n    {\"divideontimes\",    0x022C7},  // DIVISION TIMES\n    {\"divonx\",           0x022C7},  // DIVISION TIMES\n    {\"DJcy\",             0x00402},  // CYRILLIC CAPITAL LETTER DJE\n    {\"djcy\",             0x00452},  // CYRILLIC SMALL LETTER DJE\n    {\"dlcorn\",           0x0231E},  // BOTTOM LEFT CORNER\n    {\"dlcrop\",           0x0230D},  // BOTTOM LEFT CROP\n    {\"dollar\",           0x00024},  // DOLLAR SIGN\n    {\"Dopf\",             0x1D53B},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL D\n    {\"dopf\",             0x1D555},  // MATHEMATICAL DOUBLE-STRUCK SMALL D\n    {\"Dot\",              0x000A8},  // DIAERESIS\n    {\"dot\",              0x002D9},  // DOT ABOVE\n    {\"DotDot\",           0x020DC},  // COMBINING FOUR DOTS ABOVE\n    {\"doteq\",            0x02250},  // APPROACHES THE LIMIT\n    {\"doteqdot\",         0x02251},  // GEOMETRICALLY EQUAL TO\n    {\"DotEqual\",         0x02250},  // APPROACHES THE LIMIT\n    {\"dotminus\",         0x02238},  // DOT MINUS\n    {\"dotplus\",          0x02214},  // DOT PLUS\n    {\"dotsquare\",        0x022A1},  // SQUARED DOT OPERATOR\n    {\"doublebarwedge\",   0x02306},  // PERSPECTIVE\n    {\"DoubleContourIntegral\", 0x0222F},  // SURFACE INTEGRAL\n    {\"DoubleDot\",        0x000A8},  // DIAERESIS\n    {\"DoubleDownArrow\",  0x021D3},  // DOWNWARDS DOUBLE ARROW\n    {\"DoubleLeftArrow\",  0x021D0},  // LEFTWARDS DOUBLE ARROW\n    {\"DoubleLeftRightArrow\", 0x021D4},  // LEFT RIGHT DOUBLE ARROW\n    {\"DoubleLeftTee\",    0x02AE4},  // VERTICAL BAR DOUBLE LEFT TURNSTILE\n    {\"DoubleLongLeftArrow\", 0x027F8},  // LONG LEFTWARDS DOUBLE ARROW\n    {\"DoubleLongLeftRightArrow\", 0x027FA},  // LONG LEFT RIGHT DOUBLE ARROW\n    {\"DoubleLongRightArrow\", 0x027F9},  // LONG RIGHTWARDS DOUBLE ARROW\n    {\"DoubleRightArrow\", 0x021D2},  // RIGHTWARDS DOUBLE ARROW\n    {\"DoubleRightTee\",   0x022A8},  // TRUE\n    {\"DoubleUpArrow\",    0x021D1},  // UPWARDS DOUBLE ARROW\n    {\"DoubleUpDownArrow\", 0x021D5},  // UP DOWN DOUBLE ARROW\n    {\"DoubleVerticalBar\", 0x02225},  // PARALLEL TO\n    {\"downarrow\",        0x02193},  // DOWNWARDS ARROW\n    {\"DownArrow\",        0x02193},  // DOWNWARDS ARROW\n    {\"Downarrow\",        0x021D3},  // DOWNWARDS DOUBLE ARROW\n    {\"DownArrowBar\",     0x02913},  // DOWNWARDS ARROW TO BAR\n    {\"DownArrowUpArrow\", 0x021F5},  // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW\n    {\"DownBreve\",        0x00311},  // COMBINING INVERTED BREVE\n    {\"downdownarrows\",   0x021CA},  // DOWNWARDS PAIRED ARROWS\n    {\"downharpoonleft\",  0x021C3},  // DOWNWARDS HARPOON WITH BARB LEFTWARDS\n    {\"downharpoonright\", 0x021C2},  // DOWNWARDS HARPOON WITH BARB RIGHTWARDS\n    {\"DownLeftRightVector\", 0x02950},  // LEFT BARB DOWN RIGHT BARB DOWN HARPOON\n    {\"DownLeftTeeVector\", 0x0295E},  // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR\n    {\"DownLeftVector\",   0x021BD},  // LEFTWARDS HARPOON WITH BARB DOWNWARDS\n    {\"DownLeftVectorBar\", 0x02956},  // LEFTWARDS HARPOON WITH BARB DOWN TO BAR\n    {\"DownRightTeeVector\", 0x0295F},  // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR\n    {\"DownRightVector\",  0x021C1},  // RIGHTWARDS HARPOON WITH BARB DOWNWARDS\n    {\"DownRightVectorBar\", 0x02957},  // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR\n    {\"DownTee\",          0x022A4},  // DOWN TACK\n    {\"DownTeeArrow\",     0x021A7},  // DOWNWARDS ARROW FROM BAR\n    {\"drbkarow\",         0x02910},  // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW\n    {\"drcorn\",           0x0231F},  // BOTTOM RIGHT CORNER\n    {\"drcrop\",           0x0230C},  // BOTTOM RIGHT CROP\n    {\"Dscr\",             0x1D49F},  // MATHEMATICAL SCRIPT CAPITAL D\n    {\"dscr\",             0x1D4B9},  // MATHEMATICAL SCRIPT SMALL D\n    {\"DScy\",             0x00405},  // CYRILLIC CAPITAL LETTER DZE\n    {\"dscy\",             0x00455},  // CYRILLIC SMALL LETTER DZE\n    {\"dsol\",             0x029F6},  // SOLIDUS WITH OVERBAR\n    {\"Dstrok\",           0x00110},  // LATIN CAPITAL LETTER D WITH STROKE\n    {\"dstrok\",           0x00111},  // LATIN SMALL LETTER D WITH STROKE\n    {\"dtdot\",            0x022F1},  // DOWN RIGHT DIAGONAL ELLIPSIS\n    {\"dtri\",             0x025BF},  // WHITE DOWN-POINTING SMALL TRIANGLE\n    {\"dtrif\",            0x025BE},  // BLACK DOWN-POINTING SMALL TRIANGLE\n    {\"duarr\",            0x021F5},  // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW\n    {\"duhar\",            0x0296F},  // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT\n    {\"dwangle\",          0x029A6},  // OBLIQUE ANGLE OPENING UP\n    {\"DZcy\",             0x0040F},  // CYRILLIC CAPITAL LETTER DZHE\n    {\"dzcy\",             0x0045F},  // CYRILLIC SMALL LETTER DZHE\n    {\"dzigrarr\",         0x027FF},  // LONG RIGHTWARDS SQUIGGLE ARROW\n];\n\nimmutable NameId[] namesE =\n[\n    {\"Eacgr\",            0x00388},  // GREEK CAPITAL LETTER EPSILON WITH TONOS\n    {\"eacgr\",            0x003AD},  // GREEK SMALL LETTER EPSILON WITH TONOS\n    {\"Eacute\",           0x000C9},  // LATIN CAPITAL LETTER E WITH ACUTE\n    {\"eacute\",           0x000E9},  // LATIN SMALL LETTER E WITH ACUTE\n    {\"easter\",           0x02A6E},  // EQUALS WITH ASTERISK\n    {\"Ecaron\",           0x0011A},  // LATIN CAPITAL LETTER E WITH CARON\n    {\"ecaron\",           0x0011B},  // LATIN SMALL LETTER E WITH CARON\n    {\"ecir\",             0x02256},  // RING IN EQUAL TO\n    {\"Ecirc\",            0x000CA},  // LATIN CAPITAL LETTER E WITH CIRCUMFLEX\n    {\"ecirc\",            0x000EA},  // LATIN SMALL LETTER E WITH CIRCUMFLEX\n    {\"ecolon\",           0x02255},  // EQUALS COLON\n    {\"Ecy\",              0x0042D},  // CYRILLIC CAPITAL LETTER E\n    {\"ecy\",              0x0044D},  // CYRILLIC SMALL LETTER E\n    {\"eDDot\",            0x02A77},  // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW\n    {\"Edot\",             0x00116},  // LATIN CAPITAL LETTER E WITH DOT ABOVE\n    {\"edot\",             0x00117},  // LATIN SMALL LETTER E WITH DOT ABOVE\n    {\"eDot\",             0x02251},  // GEOMETRICALLY EQUAL TO\n    {\"ee\",               0x02147},  // DOUBLE-STRUCK ITALIC SMALL E\n    {\"EEacgr\",           0x00389},  // GREEK CAPITAL LETTER ETA WITH TONOS\n    {\"eeacgr\",           0x003AE},  // GREEK SMALL LETTER ETA WITH TONOS\n    {\"EEgr\",             0x00397},  // GREEK CAPITAL LETTER ETA\n    {\"eegr\",             0x003B7},  // GREEK SMALL LETTER ETA\n    {\"efDot\",            0x02252},  // APPROXIMATELY EQUAL TO OR THE IMAGE OF\n    {\"Efr\",              0x1D508},  // MATHEMATICAL FRAKTUR CAPITAL E\n    {\"efr\",              0x1D522},  // MATHEMATICAL FRAKTUR SMALL E\n    {\"eg\",               0x02A9A},  // DOUBLE-LINE EQUAL TO OR GREATER-THAN\n    {\"Egr\",              0x00395},  // GREEK CAPITAL LETTER EPSILON\n    {\"egr\",              0x003B5},  // GREEK SMALL LETTER EPSILON\n    {\"Egrave\",           0x000C8},  // LATIN CAPITAL LETTER E WITH GRAVE\n    {\"egrave\",           0x000E8},  // LATIN SMALL LETTER E WITH GRAVE\n    {\"egs\",              0x02A96},  // SLANTED EQUAL TO OR GREATER-THAN\n    {\"egsdot\",           0x02A98},  // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE\n    {\"el\",               0x02A99},  // DOUBLE-LINE EQUAL TO OR LESS-THAN\n    {\"Element\",          0x02208},  // ELEMENT OF\n    {\"elinters\",         0x023E7},  // ELECTRICAL INTERSECTION\n    {\"ell\",              0x02113},  // SCRIPT SMALL L\n    {\"els\",              0x02A95},  // SLANTED EQUAL TO OR LESS-THAN\n    {\"elsdot\",           0x02A97},  // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE\n    {\"Emacr\",            0x00112},  // LATIN CAPITAL LETTER E WITH MACRON\n    {\"emacr\",            0x00113},  // LATIN SMALL LETTER E WITH MACRON\n    {\"empty\",            0x02205},  // EMPTY SET\n    {\"emptyset\",         0x02205},  // EMPTY SET\n    {\"EmptySmallSquare\", 0x025FB},  // WHITE MEDIUM SQUARE\n    {\"emptyv\",           0x02205},  // EMPTY SET\n    {\"EmptyVerySmallSquare\", 0x025AB},  // WHITE SMALL SQUARE\n    {\"emsp\",             0x02003},  // EM SPACE\n    {\"emsp13\",           0x02004},  // THREE-PER-EM SPACE\n    {\"emsp14\",           0x02005},  // FOUR-PER-EM SPACE\n    {\"ENG\",              0x0014A},  // LATIN CAPITAL LETTER ENG\n    {\"eng\",              0x0014B},  // LATIN SMALL LETTER ENG\n    {\"ensp\",             0x02002},  // EN SPACE\n    {\"Eogon\",            0x00118},  // LATIN CAPITAL LETTER E WITH OGONEK\n    {\"eogon\",            0x00119},  // LATIN SMALL LETTER E WITH OGONEK\n    {\"Eopf\",             0x1D53C},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL E\n    {\"eopf\",             0x1D556},  // MATHEMATICAL DOUBLE-STRUCK SMALL E\n    {\"epar\",             0x022D5},  // EQUAL AND PARALLEL TO\n    {\"eparsl\",           0x029E3},  // EQUALS SIGN AND SLANTED PARALLEL\n    {\"eplus\",            0x02A71},  // EQUALS SIGN ABOVE PLUS SIGN\n    {\"epsi\",             0x003B5},  // GREEK SMALL LETTER EPSILON\n    {\"Epsilon\",          0x00395},  // GREEK CAPITAL LETTER EPSILON\n    {\"epsilon\",          0x003B5},  // GREEK SMALL LETTER EPSILON\n    {\"epsiv\",            0x003F5},  // GREEK LUNATE EPSILON SYMBOL\n    {\"eqcirc\",           0x02256},  // RING IN EQUAL TO\n    {\"eqcolon\",          0x02255},  // EQUALS COLON\n    {\"eqsim\",            0x02242},  // MINUS TILDE\n    {\"eqslantgtr\",       0x02A96},  // SLANTED EQUAL TO OR GREATER-THAN\n    {\"eqslantless\",      0x02A95},  // SLANTED EQUAL TO OR LESS-THAN\n    {\"Equal\",            0x02A75},  // TWO CONSECUTIVE EQUALS SIGNS\n    {\"equals\",           0x0003D},  // EQUALS SIGN\n    {\"EqualTilde\",       0x02242},  // MINUS TILDE\n    {\"equest\",           0x0225F},  // QUESTIONED EQUAL TO\n    {\"Equilibrium\",      0x021CC},  // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON\n    {\"equiv\",            0x02261},  // IDENTICAL TO\n    {\"equivDD\",          0x02A78},  // EQUIVALENT WITH FOUR DOTS ABOVE\n    {\"eqvparsl\",         0x029E5},  // IDENTICAL TO AND SLANTED PARALLEL\n    {\"erarr\",            0x02971},  // EQUALS SIGN ABOVE RIGHTWARDS ARROW\n    {\"erDot\",            0x02253},  // IMAGE OF OR APPROXIMATELY EQUAL TO\n    {\"escr\",             0x0212F},  // SCRIPT SMALL E\n    {\"Escr\",             0x02130},  // SCRIPT CAPITAL E\n    {\"esdot\",            0x02250},  // APPROACHES THE LIMIT\n    {\"esim\",             0x02242},  // MINUS TILDE\n    {\"Esim\",             0x02A73},  // EQUALS SIGN ABOVE TILDE OPERATOR\n    {\"Eta\",              0x00397},  // GREEK CAPITAL LETTER ETA\n    {\"eta\",              0x003B7},  // GREEK SMALL LETTER ETA\n    {\"ETH\",              0x000D0},  // LATIN CAPITAL LETTER ETH\n    {\"eth\",              0x000F0},  // LATIN SMALL LETTER ETH\n    {\"Euml\",             0x000CB},  // LATIN CAPITAL LETTER E WITH DIAERESIS\n    {\"euml\",             0x000EB},  // LATIN SMALL LETTER E WITH DIAERESIS\n    {\"euro\",             0x020AC},  // EURO SIGN\n    {\"excl\",             0x00021},  // EXCLAMATION MARK\n    {\"exist\",            0x02203},  // THERE EXISTS\n    {\"Exists\",           0x02203},  // THERE EXISTS\n    {\"expectation\",      0x02130},  // SCRIPT CAPITAL E\n    {\"exponentiale\",     0x02147},  // DOUBLE-STRUCK ITALIC SMALL E\n    {\"ExponentialE\",     0x02147},  // DOUBLE-STRUCK ITALIC SMALL E\n];\n\nimmutable NameId[] namesF =\n[\n    {\"fallingdotseq\",    0x02252},  // APPROXIMATELY EQUAL TO OR THE IMAGE OF\n    {\"Fcy\",              0x00424},  // CYRILLIC CAPITAL LETTER EF\n    {\"fcy\",              0x00444},  // CYRILLIC SMALL LETTER EF\n    {\"female\",           0x02640},  // FEMALE SIGN\n    {\"ffilig\",           0x0FB03},  // LATIN SMALL LIGATURE FFI\n    {\"fflig\",            0x0FB00},  // LATIN SMALL LIGATURE FF\n    {\"ffllig\",           0x0FB04},  // LATIN SMALL LIGATURE FFL\n    {\"Ffr\",              0x1D509},  // MATHEMATICAL FRAKTUR CAPITAL F\n    {\"ffr\",              0x1D523},  // MATHEMATICAL FRAKTUR SMALL F\n    {\"filig\",            0x0FB01},  // LATIN SMALL LIGATURE FI\n    {\"FilledSmallSquare\", 0x025FC},  // BLACK MEDIUM SQUARE\n    {\"FilledVerySmallSquare\", 0x025AA},  // BLACK SMALL SQUARE\n//  \"fjlig\",            0x00066;0x0006A},  // fj ligature\n    {\"flat\",             0x0266D},  // MUSIC FLAT SIGN\n    {\"fllig\",            0x0FB02},  // LATIN SMALL LIGATURE FL\n    {\"fltns\",            0x025B1},  // WHITE PARALLELOGRAM\n    {\"fnof\",             0x00192},  // LATIN SMALL LETTER F WITH HOOK\n    {\"Fopf\",             0x1D53D},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL F\n    {\"fopf\",             0x1D557},  // MATHEMATICAL DOUBLE-STRUCK SMALL F\n    {\"forall\",           0x02200},  // FOR ALL\n    {\"ForAll\",           0x02200},  // FOR ALL\n    {\"fork\",             0x022D4},  // PITCHFORK\n    {\"forkv\",            0x02AD9},  // ELEMENT OF OPENING DOWNWARDS\n    {\"Fouriertrf\",       0x02131},  // SCRIPT CAPITAL F\n    {\"fpartint\",         0x02A0D},  // FINITE PART INTEGRAL\n    {\"frac12\",           0x000BD},  // VULGAR FRACTION ONE HALF\n    {\"frac13\",           0x02153},  // VULGAR FRACTION ONE THIRD\n    {\"frac14\",           0x000BC},  // VULGAR FRACTION ONE QUARTER\n    {\"frac15\",           0x02155},  // VULGAR FRACTION ONE FIFTH\n    {\"frac16\",           0x02159},  // VULGAR FRACTION ONE SIXTH\n    {\"frac18\",           0x0215B},  // VULGAR FRACTION ONE EIGHTH\n    {\"frac23\",           0x02154},  // VULGAR FRACTION TWO THIRDS\n    {\"frac25\",           0x02156},  // VULGAR FRACTION TWO FIFTHS\n    {\"frac34\",           0x000BE},  // VULGAR FRACTION THREE QUARTERS\n    {\"frac35\",           0x02157},  // VULGAR FRACTION THREE FIFTHS\n    {\"frac38\",           0x0215C},  // VULGAR FRACTION THREE EIGHTHS\n    {\"frac45\",           0x02158},  // VULGAR FRACTION FOUR FIFTHS\n    {\"frac56\",           0x0215A},  // VULGAR FRACTION FIVE SIXTHS\n    {\"frac58\",           0x0215D},  // VULGAR FRACTION FIVE EIGHTHS\n    {\"frac78\",           0x0215E},  // VULGAR FRACTION SEVEN EIGHTHS\n    {\"frasl\",            0x02044},  // FRACTION SLASH\n    {\"frown\",            0x02322},  // FROWN\n    {\"Fscr\",             0x02131},  // SCRIPT CAPITAL F\n    {\"fscr\",             0x1D4BB},  // MATHEMATICAL SCRIPT SMALL F\n];\n\nimmutable NameId[] namesG =\n[\n    {\"gacute\",           0x001F5},  // LATIN SMALL LETTER G WITH ACUTE\n    {\"Gamma\",            0x00393},  // GREEK CAPITAL LETTER GAMMA\n    {\"gamma\",            0x003B3},  // GREEK SMALL LETTER GAMMA\n    {\"Gammad\",           0x003DC},  // GREEK LETTER DIGAMMA\n    {\"gammad\",           0x003DD},  // GREEK SMALL LETTER DIGAMMA\n    {\"gap\",              0x02A86},  // GREATER-THAN OR APPROXIMATE\n    {\"Gbreve\",           0x0011E},  // LATIN CAPITAL LETTER G WITH BREVE\n    {\"gbreve\",           0x0011F},  // LATIN SMALL LETTER G WITH BREVE\n    {\"Gcedil\",           0x00122},  // LATIN CAPITAL LETTER G WITH CEDILLA\n    {\"Gcirc\",            0x0011C},  // LATIN CAPITAL LETTER G WITH CIRCUMFLEX\n    {\"gcirc\",            0x0011D},  // LATIN SMALL LETTER G WITH CIRCUMFLEX\n    {\"Gcy\",              0x00413},  // CYRILLIC CAPITAL LETTER GHE\n    {\"gcy\",              0x00433},  // CYRILLIC SMALL LETTER GHE\n    {\"Gdot\",             0x00120},  // LATIN CAPITAL LETTER G WITH DOT ABOVE\n    {\"gdot\",             0x00121},  // LATIN SMALL LETTER G WITH DOT ABOVE\n    {\"ge\",               0x02265},  // GREATER-THAN OR EQUAL TO\n    {\"gE\",               0x02267},  // GREATER-THAN OVER EQUAL TO\n    {\"gel\",              0x022DB},  // GREATER-THAN EQUAL TO OR LESS-THAN\n    {\"gEl\",              0x02A8C},  // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN\n    {\"geq\",              0x02265},  // GREATER-THAN OR EQUAL TO\n    {\"geqq\",             0x02267},  // GREATER-THAN OVER EQUAL TO\n    {\"geqslant\",         0x02A7E},  // GREATER-THAN OR SLANTED EQUAL TO\n    {\"ges\",              0x02A7E},  // GREATER-THAN OR SLANTED EQUAL TO\n    {\"gescc\",            0x02AA9},  // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL\n    {\"gesdot\",           0x02A80},  // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE\n    {\"gesdoto\",          0x02A82},  // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE\n    {\"gesdotol\",         0x02A84},  // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT\n//  \"gesl\",             0x022DB;0x0FE00},  // GREATER-THAN slanted EQUAL TO OR LESS-THAN\n    {\"gesles\",           0x02A94},  // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL\n    {\"Gfr\",              0x1D50A},  // MATHEMATICAL FRAKTUR CAPITAL G\n    {\"gfr\",              0x1D524},  // MATHEMATICAL FRAKTUR SMALL G\n    {\"gg\",               0x0226B},  // MUCH GREATER-THAN\n    {\"Gg\",               0x022D9},  // VERY MUCH GREATER-THAN\n    {\"ggg\",              0x022D9},  // VERY MUCH GREATER-THAN\n    {\"Ggr\",              0x00393},  // GREEK CAPITAL LETTER GAMMA\n    {\"ggr\",              0x003B3},  // GREEK SMALL LETTER GAMMA\n    {\"gimel\",            0x02137},  // GIMEL SYMBOL\n    {\"GJcy\",             0x00403},  // CYRILLIC CAPITAL LETTER GJE\n    {\"gjcy\",             0x00453},  // CYRILLIC SMALL LETTER GJE\n    {\"gl\",               0x02277},  // GREATER-THAN OR LESS-THAN\n    {\"gla\",              0x02AA5},  // GREATER-THAN BESIDE LESS-THAN\n    {\"glE\",              0x02A92},  // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL\n    {\"glj\",              0x02AA4},  // GREATER-THAN OVERLAPPING LESS-THAN\n    {\"gnap\",             0x02A8A},  // GREATER-THAN AND NOT APPROXIMATE\n    {\"gnapprox\",         0x02A8A},  // GREATER-THAN AND NOT APPROXIMATE\n    {\"gnE\",              0x02269},  // GREATER-THAN BUT NOT EQUAL TO\n    {\"gne\",              0x02A88},  // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO\n    {\"gneq\",             0x02A88},  // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO\n    {\"gneqq\",            0x02269},  // GREATER-THAN BUT NOT EQUAL TO\n    {\"gnsim\",            0x022E7},  // GREATER-THAN BUT NOT EQUIVALENT TO\n    {\"Gopf\",             0x1D53E},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL G\n    {\"gopf\",             0x1D558},  // MATHEMATICAL DOUBLE-STRUCK SMALL G\n    {\"grave\",            0x00060},  // GRAVE ACCENT\n    {\"GreaterEqual\",     0x02265},  // GREATER-THAN OR EQUAL TO\n    {\"GreaterEqualLess\", 0x022DB},  // GREATER-THAN EQUAL TO OR LESS-THAN\n    {\"GreaterFullEqual\", 0x02267},  // GREATER-THAN OVER EQUAL TO\n    {\"GreaterGreater\",   0x02AA2},  // DOUBLE NESTED GREATER-THAN\n    {\"GreaterLess\",      0x02277},  // GREATER-THAN OR LESS-THAN\n    {\"GreaterSlantEqual\", 0x02A7E},  // GREATER-THAN OR SLANTED EQUAL TO\n    {\"GreaterTilde\",     0x02273},  // GREATER-THAN OR EQUIVALENT TO\n    {\"gscr\",             0x0210A},  // SCRIPT SMALL G\n    {\"Gscr\",             0x1D4A2},  // MATHEMATICAL SCRIPT CAPITAL G\n    {\"gsim\",             0x02273},  // GREATER-THAN OR EQUIVALENT TO\n    {\"gsime\",            0x02A8E},  // GREATER-THAN ABOVE SIMILAR OR EQUAL\n    {\"gsiml\",            0x02A90},  // GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN\n    {\"gt\",               0x0003E},  // GREATER-THAN SIGN\n    {\"GT\",               0x0003E},  // GREATER-THAN SIGN\n    {\"Gt\",               0x0226B},  // MUCH GREATER-THAN\n    {\"gtcc\",             0x02AA7},  // GREATER-THAN CLOSED BY CURVE\n    {\"gtcir\",            0x02A7A},  // GREATER-THAN WITH CIRCLE INSIDE\n    {\"gtdot\",            0x022D7},  // GREATER-THAN WITH DOT\n    {\"gtlPar\",           0x02995},  // DOUBLE LEFT ARC GREATER-THAN BRACKET\n    {\"gtquest\",          0x02A7C},  // GREATER-THAN WITH QUESTION MARK ABOVE\n    {\"gtrapprox\",        0x02A86},  // GREATER-THAN OR APPROXIMATE\n    {\"gtrarr\",           0x02978},  // GREATER-THAN ABOVE RIGHTWARDS ARROW\n    {\"gtrdot\",           0x022D7},  // GREATER-THAN WITH DOT\n    {\"gtreqless\",        0x022DB},  // GREATER-THAN EQUAL TO OR LESS-THAN\n    {\"gtreqqless\",       0x02A8C},  // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN\n    {\"gtrless\",          0x02277},  // GREATER-THAN OR LESS-THAN\n    {\"gtrsim\",           0x02273},  // GREATER-THAN OR EQUIVALENT TO\n//  \"gvertneqq\",        0x02269;0x0FE00},  // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke\n//  \"gvnE\",             0x02269;0x0FE00},  // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke\n];\n\nimmutable NameId[] namesH =\n[\n    {\"Hacek\",            0x002C7},  // CARON\n    {\"hairsp\",           0x0200A},  // HAIR SPACE\n    {\"half\",             0x000BD},  // VULGAR FRACTION ONE HALF\n    {\"hamilt\",           0x0210B},  // SCRIPT CAPITAL H\n    {\"HARDcy\",           0x0042A},  // CYRILLIC CAPITAL LETTER HARD SIGN\n    {\"hardcy\",           0x0044A},  // CYRILLIC SMALL LETTER HARD SIGN\n    {\"harr\",             0x02194},  // LEFT RIGHT ARROW\n    {\"hArr\",             0x021D4},  // LEFT RIGHT DOUBLE ARROW\n    {\"harrcir\",          0x02948},  // LEFT RIGHT ARROW THROUGH SMALL CIRCLE\n    {\"harrw\",            0x021AD},  // LEFT RIGHT WAVE ARROW\n    {\"Hat\",              0x0005E},  // CIRCUMFLEX ACCENT\n    {\"hbar\",             0x0210F},  // PLANCK CONSTANT OVER TWO PI\n    {\"Hcirc\",            0x00124},  // LATIN CAPITAL LETTER H WITH CIRCUMFLEX\n    {\"hcirc\",            0x00125},  // LATIN SMALL LETTER H WITH CIRCUMFLEX\n    {\"hearts\",           0x02665},  // BLACK HEART SUIT\n    {\"heartsuit\",        0x02665},  // BLACK HEART SUIT\n    {\"hellip\",           0x02026},  // HORIZONTAL ELLIPSIS\n    {\"hercon\",           0x022B9},  // HERMITIAN CONJUGATE MATRIX\n    {\"Hfr\",              0x0210C},  // BLACK-LETTER CAPITAL H\n    {\"hfr\",              0x1D525},  // MATHEMATICAL FRAKTUR SMALL H\n    {\"HilbertSpace\",     0x0210B},  // SCRIPT CAPITAL H\n    {\"hksearow\",         0x02925},  // SOUTH EAST ARROW WITH HOOK\n    {\"hkswarow\",         0x02926},  // SOUTH WEST ARROW WITH HOOK\n    {\"hoarr\",            0x021FF},  // LEFT RIGHT OPEN-HEADED ARROW\n    {\"homtht\",           0x0223B},  // HOMOTHETIC\n    {\"hookleftarrow\",    0x021A9},  // LEFTWARDS ARROW WITH HOOK\n    {\"hookrightarrow\",   0x021AA},  // RIGHTWARDS ARROW WITH HOOK\n    {\"Hopf\",             0x0210D},  // DOUBLE-STRUCK CAPITAL H\n    {\"hopf\",             0x1D559},  // MATHEMATICAL DOUBLE-STRUCK SMALL H\n    {\"horbar\",           0x02015},  // HORIZONTAL BAR\n    {\"HorizontalLine\",   0x02500},  // BOX DRAWINGS LIGHT HORIZONTAL\n    {\"Hscr\",             0x0210B},  // SCRIPT CAPITAL H\n    {\"hscr\",             0x1D4BD},  // MATHEMATICAL SCRIPT SMALL H\n    {\"hslash\",           0x0210F},  // PLANCK CONSTANT OVER TWO PI\n    {\"Hstrok\",           0x00126},  // LATIN CAPITAL LETTER H WITH STROKE\n    {\"hstrok\",           0x00127},  // LATIN SMALL LETTER H WITH STROKE\n    {\"HumpDownHump\",     0x0224E},  // GEOMETRICALLY EQUIVALENT TO\n    {\"HumpEqual\",        0x0224F},  // DIFFERENCE BETWEEN\n    {\"hybull\",           0x02043},  // HYPHEN BULLET\n    {\"hyphen\",           0x02010},  // HYPHEN\n];\n\nimmutable NameId[] namesI =\n[\n    {\"Iacgr\",            0x0038A},  // GREEK CAPITAL LETTER IOTA WITH TONOS\n    {\"iacgr\",            0x003AF},  // GREEK SMALL LETTER IOTA WITH TONOS\n    {\"Iacute\",           0x000CD},  // LATIN CAPITAL LETTER I WITH ACUTE\n    {\"iacute\",           0x000ED},  // LATIN SMALL LETTER I WITH ACUTE\n    {\"ic\",               0x02063},  // INVISIBLE SEPARATOR\n    {\"Icirc\",            0x000CE},  // LATIN CAPITAL LETTER I WITH CIRCUMFLEX\n    {\"icirc\",            0x000EE},  // LATIN SMALL LETTER I WITH CIRCUMFLEX\n    {\"Icy\",              0x00418},  // CYRILLIC CAPITAL LETTER I\n    {\"icy\",              0x00438},  // CYRILLIC SMALL LETTER I\n    {\"idiagr\",           0x00390},  // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS\n    {\"Idigr\",            0x003AA},  // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA\n    {\"idigr\",            0x003CA},  // GREEK SMALL LETTER IOTA WITH DIALYTIKA\n    {\"Idot\",             0x00130},  // LATIN CAPITAL LETTER I WITH DOT ABOVE\n    {\"IEcy\",             0x00415},  // CYRILLIC CAPITAL LETTER IE\n    {\"iecy\",             0x00435},  // CYRILLIC SMALL LETTER IE\n    {\"iexcl\",            0x000A1},  // INVERTED EXCLAMATION MARK\n    {\"iff\",              0x021D4},  // LEFT RIGHT DOUBLE ARROW\n    {\"Ifr\",              0x02111},  // BLACK-LETTER CAPITAL I\n    {\"ifr\",              0x1D526},  // MATHEMATICAL FRAKTUR SMALL I\n    {\"Igr\",              0x00399},  // GREEK CAPITAL LETTER IOTA\n    {\"igr\",              0x003B9},  // GREEK SMALL LETTER IOTA\n    {\"Igrave\",           0x000CC},  // LATIN CAPITAL LETTER I WITH GRAVE\n    {\"igrave\",           0x000EC},  // LATIN SMALL LETTER I WITH GRAVE\n    {\"ii\",               0x02148},  // DOUBLE-STRUCK ITALIC SMALL I\n    {\"iiiint\",           0x02A0C},  // QUADRUPLE INTEGRAL OPERATOR\n    {\"iiint\",            0x0222D},  // TRIPLE INTEGRAL\n    {\"iinfin\",           0x029DC},  // INCOMPLETE INFINITY\n    {\"iiota\",            0x02129},  // TURNED GREEK SMALL LETTER IOTA\n    {\"IJlig\",            0x00132},  // LATIN CAPITAL LIGATURE IJ\n    {\"ijlig\",            0x00133},  // LATIN SMALL LIGATURE IJ\n    {\"Im\",               0x02111},  // BLACK-LETTER CAPITAL I\n    {\"Imacr\",            0x0012A},  // LATIN CAPITAL LETTER I WITH MACRON\n    {\"imacr\",            0x0012B},  // LATIN SMALL LETTER I WITH MACRON\n    {\"image\",            0x02111},  // BLACK-LETTER CAPITAL I\n    {\"ImaginaryI\",       0x02148},  // DOUBLE-STRUCK ITALIC SMALL I\n    {\"imagline\",         0x02110},  // SCRIPT CAPITAL I\n    {\"imagpart\",         0x02111},  // BLACK-LETTER CAPITAL I\n    {\"imath\",            0x00131},  // LATIN SMALL LETTER DOTLESS I\n    {\"imof\",             0x022B7},  // IMAGE OF\n    {\"imped\",            0x001B5},  // LATIN CAPITAL LETTER Z WITH STROKE\n    {\"Implies\",          0x021D2},  // RIGHTWARDS DOUBLE ARROW\n    {\"in\",               0x02208},  // ELEMENT OF\n    {\"incare\",           0x02105},  // CARE OF\n    {\"infin\",            0x0221E},  // INFINITY\n    {\"infintie\",         0x029DD},  // TIE OVER INFINITY\n    {\"inodot\",           0x00131},  // LATIN SMALL LETTER DOTLESS I\n    {\"int\",              0x0222B},  // INTEGRAL\n    {\"Int\",              0x0222C},  // DOUBLE INTEGRAL\n    {\"intcal\",           0x022BA},  // INTERCALATE\n    {\"integers\",         0x02124},  // DOUBLE-STRUCK CAPITAL Z\n    {\"Integral\",         0x0222B},  // INTEGRAL\n    {\"intercal\",         0x022BA},  // INTERCALATE\n    {\"Intersection\",     0x022C2},  // N-ARY INTERSECTION\n    {\"intlarhk\",         0x02A17},  // INTEGRAL WITH LEFTWARDS ARROW WITH HOOK\n    {\"intprod\",          0x02A3C},  // INTERIOR PRODUCT\n    {\"InvisibleComma\",   0x02063},  // INVISIBLE SEPARATOR\n    {\"InvisibleTimes\",   0x02062},  // INVISIBLE TIMES\n    {\"IOcy\",             0x00401},  // CYRILLIC CAPITAL LETTER IO\n    {\"iocy\",             0x00451},  // CYRILLIC SMALL LETTER IO\n    {\"Iogon\",            0x0012E},  // LATIN CAPITAL LETTER I WITH OGONEK\n    {\"iogon\",            0x0012F},  // LATIN SMALL LETTER I WITH OGONEK\n    {\"Iopf\",             0x1D540},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL I\n    {\"iopf\",             0x1D55A},  // MATHEMATICAL DOUBLE-STRUCK SMALL I\n    {\"Iota\",             0x00399},  // GREEK CAPITAL LETTER IOTA\n    {\"iota\",             0x003B9},  // GREEK SMALL LETTER IOTA\n    {\"iprod\",            0x02A3C},  // INTERIOR PRODUCT\n    {\"iquest\",           0x000BF},  // INVERTED QUESTION MARK\n    {\"Iscr\",             0x02110},  // SCRIPT CAPITAL I\n    {\"iscr\",             0x1D4BE},  // MATHEMATICAL SCRIPT SMALL I\n    {\"isin\",             0x02208},  // ELEMENT OF\n    {\"isindot\",          0x022F5},  // ELEMENT OF WITH DOT ABOVE\n    {\"isinE\",            0x022F9},  // ELEMENT OF WITH TWO HORIZONTAL STROKES\n    {\"isins\",            0x022F4},  // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE\n    {\"isinsv\",           0x022F3},  // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE\n    {\"isinv\",            0x02208},  // ELEMENT OF\n    {\"it\",               0x02062},  // INVISIBLE TIMES\n    {\"Itilde\",           0x00128},  // LATIN CAPITAL LETTER I WITH TILDE\n    {\"itilde\",           0x00129},  // LATIN SMALL LETTER I WITH TILDE\n    {\"Iukcy\",            0x00406},  // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I\n    {\"iukcy\",            0x00456},  // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I\n    {\"Iuml\",             0x000CF},  // LATIN CAPITAL LETTER I WITH DIAERESIS\n    {\"iuml\",             0x000EF},  // LATIN SMALL LETTER I WITH DIAERESIS\n];\n\nimmutable NameId[] namesJ =\n[\n    {\"Jcirc\",            0x00134},  // LATIN CAPITAL LETTER J WITH CIRCUMFLEX\n    {\"jcirc\",            0x00135},  // LATIN SMALL LETTER J WITH CIRCUMFLEX\n    {\"Jcy\",              0x00419},  // CYRILLIC CAPITAL LETTER SHORT I\n    {\"jcy\",              0x00439},  // CYRILLIC SMALL LETTER SHORT I\n    {\"Jfr\",              0x1D50D},  // MATHEMATICAL FRAKTUR CAPITAL J\n    {\"jfr\",              0x1D527},  // MATHEMATICAL FRAKTUR SMALL J\n    {\"jmath\",            0x00237},  // LATIN SMALL LETTER DOTLESS J\n    {\"Jopf\",             0x1D541},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL J\n    {\"jopf\",             0x1D55B},  // MATHEMATICAL DOUBLE-STRUCK SMALL J\n    {\"Jscr\",             0x1D4A5},  // MATHEMATICAL SCRIPT CAPITAL J\n    {\"jscr\",             0x1D4BF},  // MATHEMATICAL SCRIPT SMALL J\n    {\"Jsercy\",           0x00408},  // CYRILLIC CAPITAL LETTER JE\n    {\"jsercy\",           0x00458},  // CYRILLIC SMALL LETTER JE\n    {\"Jukcy\",            0x00404},  // CYRILLIC CAPITAL LETTER UKRAINIAN IE\n    {\"jukcy\",            0x00454},  // CYRILLIC SMALL LETTER UKRAINIAN IE\n];\n\nimmutable NameId[] namesK =\n[\n    {\"Kappa\",            0x0039A},  // GREEK CAPITAL LETTER KAPPA\n    {\"kappa\",            0x003BA},  // GREEK SMALL LETTER KAPPA\n    {\"kappav\",           0x003F0},  // GREEK KAPPA SYMBOL\n    {\"Kcedil\",           0x00136},  // LATIN CAPITAL LETTER K WITH CEDILLA\n    {\"kcedil\",           0x00137},  // LATIN SMALL LETTER K WITH CEDILLA\n    {\"Kcy\",              0x0041A},  // CYRILLIC CAPITAL LETTER KA\n    {\"kcy\",              0x0043A},  // CYRILLIC SMALL LETTER KA\n    {\"Kfr\",              0x1D50E},  // MATHEMATICAL FRAKTUR CAPITAL K\n    {\"kfr\",              0x1D528},  // MATHEMATICAL FRAKTUR SMALL K\n    {\"Kgr\",              0x0039A},  // GREEK CAPITAL LETTER KAPPA\n    {\"kgr\",              0x003BA},  // GREEK SMALL LETTER KAPPA\n    {\"kgreen\",           0x00138},  // LATIN SMALL LETTER KRA\n    {\"KHcy\",             0x00425},  // CYRILLIC CAPITAL LETTER HA\n    {\"khcy\",             0x00445},  // CYRILLIC SMALL LETTER HA\n    {\"KHgr\",             0x003A7},  // GREEK CAPITAL LETTER CHI\n    {\"khgr\",             0x003C7},  // GREEK SMALL LETTER CHI\n    {\"KJcy\",             0x0040C},  // CYRILLIC CAPITAL LETTER KJE\n    {\"kjcy\",             0x0045C},  // CYRILLIC SMALL LETTER KJE\n    {\"Kopf\",             0x1D542},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL K\n    {\"kopf\",             0x1D55C},  // MATHEMATICAL DOUBLE-STRUCK SMALL K\n    {\"Kscr\",             0x1D4A6},  // MATHEMATICAL SCRIPT CAPITAL K\n    {\"kscr\",             0x1D4C0},  // MATHEMATICAL SCRIPT SMALL K\n];\n\nimmutable NameId[] namesL =\n[\n    {\"lAarr\",            0x021DA},  // LEFTWARDS TRIPLE ARROW\n    {\"Lacute\",           0x00139},  // LATIN CAPITAL LETTER L WITH ACUTE\n    {\"lacute\",           0x0013A},  // LATIN SMALL LETTER L WITH ACUTE\n    {\"laemptyv\",         0x029B4},  // EMPTY SET WITH LEFT ARROW ABOVE\n    {\"lagran\",           0x02112},  // SCRIPT CAPITAL L\n    {\"Lambda\",           0x0039B},  // GREEK CAPITAL LETTER LAMDA\n    {\"lambda\",           0x003BB},  // GREEK SMALL LETTER LAMDA\n    {\"lang\",             0x027E8},  // MATHEMATICAL LEFT ANGLE BRACKET\n    {\"Lang\",             0x027EA},  // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET\n    {\"langd\",            0x02991},  // LEFT ANGLE BRACKET WITH DOT\n    {\"langle\",           0x027E8},  // MATHEMATICAL LEFT ANGLE BRACKET\n    {\"lap\",              0x02A85},  // LESS-THAN OR APPROXIMATE\n    {\"Laplacetrf\",       0x02112},  // SCRIPT CAPITAL L\n    {\"laquo\",            0x000AB},  // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK\n    {\"larr\",             0x02190},  // LEFTWARDS ARROW\n    {\"Larr\",             0x0219E},  // LEFTWARDS TWO HEADED ARROW\n    {\"lArr\",             0x021D0},  // LEFTWARDS DOUBLE ARROW\n    {\"larrb\",            0x021E4},  // LEFTWARDS ARROW TO BAR\n    {\"larrbfs\",          0x0291F},  // LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND\n    {\"larrfs\",           0x0291D},  // LEFTWARDS ARROW TO BLACK DIAMOND\n    {\"larrhk\",           0x021A9},  // LEFTWARDS ARROW WITH HOOK\n    {\"larrlp\",           0x021AB},  // LEFTWARDS ARROW WITH LOOP\n    {\"larrpl\",           0x02939},  // LEFT-SIDE ARC ANTICLOCKWISE ARROW\n    {\"larrsim\",          0x02973},  // LEFTWARDS ARROW ABOVE TILDE OPERATOR\n    {\"larrtl\",           0x021A2},  // LEFTWARDS ARROW WITH TAIL\n    {\"lat\",              0x02AAB},  // LARGER THAN\n    {\"latail\",           0x02919},  // LEFTWARDS ARROW-TAIL\n    {\"lAtail\",           0x0291B},  // LEFTWARDS DOUBLE ARROW-TAIL\n    {\"late\",             0x02AAD},  // LARGER THAN OR EQUAL TO\n//  \"lates\",            0x02AAD;0x0FE00},  // LARGER THAN OR slanted EQUAL\n    {\"lbarr\",            0x0290C},  // LEFTWARDS DOUBLE DASH ARROW\n    {\"lBarr\",            0x0290E},  // LEFTWARDS TRIPLE DASH ARROW\n    {\"lbbrk\",            0x02772},  // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT\n    {\"lbrace\",           0x0007B},  // LEFT CURLY BRACKET\n    {\"lbrack\",           0x0005B},  // LEFT SQUARE BRACKET\n    {\"lbrke\",            0x0298B},  // LEFT SQUARE BRACKET WITH UNDERBAR\n    {\"lbrksld\",          0x0298F},  // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER\n    {\"lbrkslu\",          0x0298D},  // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER\n    {\"Lcaron\",           0x0013D},  // LATIN CAPITAL LETTER L WITH CARON\n    {\"lcaron\",           0x0013E},  // LATIN SMALL LETTER L WITH CARON\n    {\"Lcedil\",           0x0013B},  // LATIN CAPITAL LETTER L WITH CEDILLA\n    {\"lcedil\",           0x0013C},  // LATIN SMALL LETTER L WITH CEDILLA\n    {\"lceil\",            0x02308},  // LEFT CEILING\n    {\"lcub\",             0x0007B},  // LEFT CURLY BRACKET\n    {\"Lcy\",              0x0041B},  // CYRILLIC CAPITAL LETTER EL\n    {\"lcy\",              0x0043B},  // CYRILLIC SMALL LETTER EL\n    {\"ldca\",             0x02936},  // ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS\n    {\"ldquo\",            0x0201C},  // LEFT DOUBLE QUOTATION MARK\n    {\"ldquor\",           0x0201E},  // DOUBLE LOW-9 QUOTATION MARK\n    {\"ldrdhar\",          0x02967},  // LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN\n    {\"ldrushar\",         0x0294B},  // LEFT BARB DOWN RIGHT BARB UP HARPOON\n    {\"ldsh\",             0x021B2},  // DOWNWARDS ARROW WITH TIP LEFTWARDS\n    {\"le\",               0x02264},  // LESS-THAN OR EQUAL TO\n    {\"lE\",               0x02266},  // LESS-THAN OVER EQUAL TO\n    {\"LeftAngleBracket\", 0x027E8},  // MATHEMATICAL LEFT ANGLE BRACKET\n    {\"leftarrow\",        0x02190},  // LEFTWARDS ARROW\n    {\"LeftArrow\",        0x02190},  // LEFTWARDS ARROW\n    {\"Leftarrow\",        0x021D0},  // LEFTWARDS DOUBLE ARROW\n    {\"LeftArrowBar\",     0x021E4},  // LEFTWARDS ARROW TO BAR\n    {\"LeftArrowRightArrow\", 0x021C6},  // LEFTWARDS ARROW OVER RIGHTWARDS ARROW\n    {\"leftarrowtail\",    0x021A2},  // LEFTWARDS ARROW WITH TAIL\n    {\"LeftCeiling\",      0x02308},  // LEFT CEILING\n    {\"LeftDoubleBracket\", 0x027E6},  // MATHEMATICAL LEFT WHITE SQUARE BRACKET\n    {\"LeftDownTeeVector\", 0x02961},  // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR\n    {\"LeftDownVector\",   0x021C3},  // DOWNWARDS HARPOON WITH BARB LEFTWARDS\n    {\"LeftDownVectorBar\", 0x02959},  // DOWNWARDS HARPOON WITH BARB LEFT TO BAR\n    {\"LeftFloor\",        0x0230A},  // LEFT FLOOR\n    {\"leftharpoondown\",  0x021BD},  // LEFTWARDS HARPOON WITH BARB DOWNWARDS\n    {\"leftharpoonup\",    0x021BC},  // LEFTWARDS HARPOON WITH BARB UPWARDS\n    {\"leftleftarrows\",   0x021C7},  // LEFTWARDS PAIRED ARROWS\n    {\"leftrightarrow\",   0x02194},  // LEFT RIGHT ARROW\n    {\"LeftRightArrow\",   0x02194},  // LEFT RIGHT ARROW\n    {\"Leftrightarrow\",   0x021D4},  // LEFT RIGHT DOUBLE ARROW\n    {\"leftrightarrows\",  0x021C6},  // LEFTWARDS ARROW OVER RIGHTWARDS ARROW\n    {\"leftrightharpoons\", 0x021CB},  // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON\n    {\"leftrightsquigarrow\", 0x021AD},  // LEFT RIGHT WAVE ARROW\n    {\"LeftRightVector\",  0x0294E},  // LEFT BARB UP RIGHT BARB UP HARPOON\n    {\"LeftTee\",          0x022A3},  // LEFT TACK\n    {\"LeftTeeArrow\",     0x021A4},  // LEFTWARDS ARROW FROM BAR\n    {\"LeftTeeVector\",    0x0295A},  // LEFTWARDS HARPOON WITH BARB UP FROM BAR\n    {\"leftthreetimes\",   0x022CB},  // LEFT SEMIDIRECT PRODUCT\n    {\"LeftTriangle\",     0x022B2},  // NORMAL SUBGROUP OF\n    {\"LeftTriangleBar\",  0x029CF},  // LEFT TRIANGLE BESIDE VERTICAL BAR\n    {\"LeftTriangleEqual\", 0x022B4},  // NORMAL SUBGROUP OF OR EQUAL TO\n    {\"LeftUpDownVector\", 0x02951},  // UP BARB LEFT DOWN BARB LEFT HARPOON\n    {\"LeftUpTeeVector\",  0x02960},  // UPWARDS HARPOON WITH BARB LEFT FROM BAR\n    {\"LeftUpVector\",     0x021BF},  // UPWARDS HARPOON WITH BARB LEFTWARDS\n    {\"LeftUpVectorBar\",  0x02958},  // UPWARDS HARPOON WITH BARB LEFT TO BAR\n    {\"LeftVector\",       0x021BC},  // LEFTWARDS HARPOON WITH BARB UPWARDS\n    {\"LeftVectorBar\",    0x02952},  // LEFTWARDS HARPOON WITH BARB UP TO BAR\n    {\"leg\",              0x022DA},  // LESS-THAN EQUAL TO OR GREATER-THAN\n    {\"lEg\",              0x02A8B},  // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN\n    {\"leq\",              0x02264},  // LESS-THAN OR EQUAL TO\n    {\"leqq\",             0x02266},  // LESS-THAN OVER EQUAL TO\n    {\"leqslant\",         0x02A7D},  // LESS-THAN OR SLANTED EQUAL TO\n    {\"les\",              0x02A7D},  // LESS-THAN OR SLANTED EQUAL TO\n    {\"lescc\",            0x02AA8},  // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL\n    {\"lesdot\",           0x02A7F},  // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE\n    {\"lesdoto\",          0x02A81},  // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE\n    {\"lesdotor\",         0x02A83},  // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT\n//  \"lesg\",             0x022DA;0x0FE00},  // LESS-THAN slanted EQUAL TO OR GREATER-THAN\n    {\"lesges\",           0x02A93},  // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL\n    {\"lessapprox\",       0x02A85},  // LESS-THAN OR APPROXIMATE\n    {\"lessdot\",          0x022D6},  // LESS-THAN WITH DOT\n    {\"lesseqgtr\",        0x022DA},  // LESS-THAN EQUAL TO OR GREATER-THAN\n    {\"lesseqqgtr\",       0x02A8B},  // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN\n    {\"LessEqualGreater\", 0x022DA},  // LESS-THAN EQUAL TO OR GREATER-THAN\n    {\"LessFullEqual\",    0x02266},  // LESS-THAN OVER EQUAL TO\n    {\"LessGreater\",      0x02276},  // LESS-THAN OR GREATER-THAN\n    {\"lessgtr\",          0x02276},  // LESS-THAN OR GREATER-THAN\n    {\"LessLess\",         0x02AA1},  // DOUBLE NESTED LESS-THAN\n    {\"lesssim\",          0x02272},  // LESS-THAN OR EQUIVALENT TO\n    {\"LessSlantEqual\",   0x02A7D},  // LESS-THAN OR SLANTED EQUAL TO\n    {\"LessTilde\",        0x02272},  // LESS-THAN OR EQUIVALENT TO\n    {\"lfisht\",           0x0297C},  // LEFT FISH TAIL\n    {\"lfloor\",           0x0230A},  // LEFT FLOOR\n    {\"Lfr\",              0x1D50F},  // MATHEMATICAL FRAKTUR CAPITAL L\n    {\"lfr\",              0x1D529},  // MATHEMATICAL FRAKTUR SMALL L\n    {\"lg\",               0x02276},  // LESS-THAN OR GREATER-THAN\n    {\"lgE\",              0x02A91},  // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL\n    {\"Lgr\",              0x0039B},  // GREEK CAPITAL LETTER LAMDA\n    {\"lgr\",              0x003BB},  // GREEK SMALL LETTER LAMDA\n    {\"lHar\",             0x02962},  // LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN\n    {\"lhard\",            0x021BD},  // LEFTWARDS HARPOON WITH BARB DOWNWARDS\n    {\"lharu\",            0x021BC},  // LEFTWARDS HARPOON WITH BARB UPWARDS\n    {\"lharul\",           0x0296A},  // LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH\n    {\"lhblk\",            0x02584},  // LOWER HALF BLOCK\n    {\"LJcy\",             0x00409},  // CYRILLIC CAPITAL LETTER LJE\n    {\"ljcy\",             0x00459},  // CYRILLIC SMALL LETTER LJE\n    {\"ll\",               0x0226A},  // MUCH LESS-THAN\n    {\"Ll\",               0x022D8},  // VERY MUCH LESS-THAN\n    {\"llarr\",            0x021C7},  // LEFTWARDS PAIRED ARROWS\n    {\"llcorner\",         0x0231E},  // BOTTOM LEFT CORNER\n    {\"Lleftarrow\",       0x021DA},  // LEFTWARDS TRIPLE ARROW\n    {\"llhard\",           0x0296B},  // LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH\n    {\"lltri\",            0x025FA},  // LOWER LEFT TRIANGLE\n    {\"Lmidot\",           0x0013F},  // LATIN CAPITAL LETTER L WITH MIDDLE DOT\n    {\"lmidot\",           0x00140},  // LATIN SMALL LETTER L WITH MIDDLE DOT\n    {\"lmoust\",           0x023B0},  // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION\n    {\"lmoustache\",       0x023B0},  // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION\n    {\"lnap\",             0x02A89},  // LESS-THAN AND NOT APPROXIMATE\n    {\"lnapprox\",         0x02A89},  // LESS-THAN AND NOT APPROXIMATE\n    {\"lnE\",              0x02268},  // LESS-THAN BUT NOT EQUAL TO\n    {\"lne\",              0x02A87},  // LESS-THAN AND SINGLE-LINE NOT EQUAL TO\n    {\"lneq\",             0x02A87},  // LESS-THAN AND SINGLE-LINE NOT EQUAL TO\n    {\"lneqq\",            0x02268},  // LESS-THAN BUT NOT EQUAL TO\n    {\"lnsim\",            0x022E6},  // LESS-THAN BUT NOT EQUIVALENT TO\n    {\"loang\",            0x027EC},  // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET\n    {\"loarr\",            0x021FD},  // LEFTWARDS OPEN-HEADED ARROW\n    {\"lobrk\",            0x027E6},  // MATHEMATICAL LEFT WHITE SQUARE BRACKET\n    {\"longleftarrow\",    0x027F5},  // LONG LEFTWARDS ARROW\n    {\"LongLeftArrow\",    0x027F5},  // LONG LEFTWARDS ARROW\n    {\"Longleftarrow\",    0x027F8},  // LONG LEFTWARDS DOUBLE ARROW\n    {\"longleftrightarrow\", 0x027F7},  // LONG LEFT RIGHT ARROW\n    {\"LongLeftRightArrow\", 0x027F7},  // LONG LEFT RIGHT ARROW\n    {\"Longleftrightarrow\", 0x027FA},  // LONG LEFT RIGHT DOUBLE ARROW\n    {\"longmapsto\",       0x027FC},  // LONG RIGHTWARDS ARROW FROM BAR\n    {\"longrightarrow\",   0x027F6},  // LONG RIGHTWARDS ARROW\n    {\"LongRightArrow\",   0x027F6},  // LONG RIGHTWARDS ARROW\n    {\"Longrightarrow\",   0x027F9},  // LONG RIGHTWARDS DOUBLE ARROW\n    {\"looparrowleft\",    0x021AB},  // LEFTWARDS ARROW WITH LOOP\n    {\"looparrowright\",   0x021AC},  // RIGHTWARDS ARROW WITH LOOP\n    {\"lopar\",            0x02985},  // LEFT WHITE PARENTHESIS\n    {\"Lopf\",             0x1D543},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL L\n    {\"lopf\",             0x1D55D},  // MATHEMATICAL DOUBLE-STRUCK SMALL L\n    {\"loplus\",           0x02A2D},  // PLUS SIGN IN LEFT HALF CIRCLE\n    {\"lotimes\",          0x02A34},  // MULTIPLICATION SIGN IN LEFT HALF CIRCLE\n    {\"lowast\",           0x02217},  // ASTERISK OPERATOR\n    {\"lowbar\",           0x0005F},  // LOW LINE\n    {\"LowerLeftArrow\",   0x02199},  // SOUTH WEST ARROW\n    {\"LowerRightArrow\",  0x02198},  // SOUTH EAST ARROW\n    {\"loz\",              0x025CA},  // LOZENGE\n    {\"lozenge\",          0x025CA},  // LOZENGE\n    {\"lozf\",             0x029EB},  // BLACK LOZENGE\n    {\"lpar\",             0x00028},  // LEFT PARENTHESIS\n    {\"lparlt\",           0x02993},  // LEFT ARC LESS-THAN BRACKET\n    {\"lrarr\",            0x021C6},  // LEFTWARDS ARROW OVER RIGHTWARDS ARROW\n    {\"lrcorner\",         0x0231F},  // BOTTOM RIGHT CORNER\n    {\"lrhar\",            0x021CB},  // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON\n    {\"lrhard\",           0x0296D},  // RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH\n    {\"lrm\",              0x0200E},  // LEFT-TO-RIGHT MARK\n    {\"lrtri\",            0x022BF},  // RIGHT TRIANGLE\n    {\"lsaquo\",           0x02039},  // SINGLE LEFT-POINTING ANGLE QUOTATION MARK\n    {\"Lscr\",             0x02112},  // SCRIPT CAPITAL L\n    {\"lscr\",             0x1D4C1},  // MATHEMATICAL SCRIPT SMALL L\n    {\"lsh\",              0x021B0},  // UPWARDS ARROW WITH TIP LEFTWARDS\n    {\"Lsh\",              0x021B0},  // UPWARDS ARROW WITH TIP LEFTWARDS\n    {\"lsim\",             0x02272},  // LESS-THAN OR EQUIVALENT TO\n    {\"lsime\",            0x02A8D},  // LESS-THAN ABOVE SIMILAR OR EQUAL\n    {\"lsimg\",            0x02A8F},  // LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN\n    {\"lsqb\",             0x0005B},  // LEFT SQUARE BRACKET\n    {\"lsquo\",            0x02018},  // LEFT SINGLE QUOTATION MARK\n    {\"lsquor\",           0x0201A},  // SINGLE LOW-9 QUOTATION MARK\n    {\"Lstrok\",           0x00141},  // LATIN CAPITAL LETTER L WITH STROKE\n    {\"lstrok\",           0x00142},  // LATIN SMALL LETTER L WITH STROKE\n    {\"lt\",               0x0003C},  // LESS-THAN SIGN\n    {\"LT\",               0x0003C},  // LESS-THAN SIGN\n    {\"Lt\",               0x0226A},  // MUCH LESS-THAN\n    {\"ltcc\",             0x02AA6},  // LESS-THAN CLOSED BY CURVE\n    {\"ltcir\",            0x02A79},  // LESS-THAN WITH CIRCLE INSIDE\n    {\"ltdot\",            0x022D6},  // LESS-THAN WITH DOT\n    {\"lthree\",           0x022CB},  // LEFT SEMIDIRECT PRODUCT\n    {\"ltimes\",           0x022C9},  // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT\n    {\"ltlarr\",           0x02976},  // LESS-THAN ABOVE LEFTWARDS ARROW\n    {\"ltquest\",          0x02A7B},  // LESS-THAN WITH QUESTION MARK ABOVE\n    {\"ltri\",             0x025C3},  // WHITE LEFT-POINTING SMALL TRIANGLE\n    {\"ltrie\",            0x022B4},  // NORMAL SUBGROUP OF OR EQUAL TO\n    {\"ltrif\",            0x025C2},  // BLACK LEFT-POINTING SMALL TRIANGLE\n    {\"ltrPar\",           0x02996},  // DOUBLE RIGHT ARC LESS-THAN BRACKET\n    {\"lurdshar\",         0x0294A},  // LEFT BARB UP RIGHT BARB DOWN HARPOON\n    {\"luruhar\",          0x02966},  // LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP\n//  \"lvertneqq\",        0x02268;0x0FE00},  // LESS-THAN BUT NOT EQUAL TO - with vertical stroke\n//  \"lvnE\",             0x02268;0x0FE00},  // LESS-THAN BUT NOT EQUAL TO - with vertical stroke\n];\n\nimmutable NameId[] namesM =\n[\n    {\"macr\",             0x000AF},  // MACRON\n    {\"male\",             0x02642},  // MALE SIGN\n    {\"malt\",             0x02720},  // MALTESE CROSS\n    {\"maltese\",          0x02720},  // MALTESE CROSS\n    {\"map\",              0x021A6},  // RIGHTWARDS ARROW FROM BAR\n    {\"Map\",              0x02905},  // RIGHTWARDS TWO-HEADED ARROW FROM BAR\n    {\"mapsto\",           0x021A6},  // RIGHTWARDS ARROW FROM BAR\n    {\"mapstodown\",       0x021A7},  // DOWNWARDS ARROW FROM BAR\n    {\"mapstoleft\",       0x021A4},  // LEFTWARDS ARROW FROM BAR\n    {\"mapstoup\",         0x021A5},  // UPWARDS ARROW FROM BAR\n    {\"marker\",           0x025AE},  // BLACK VERTICAL RECTANGLE\n    {\"mcomma\",           0x02A29},  // MINUS SIGN WITH COMMA ABOVE\n    {\"Mcy\",              0x0041C},  // CYRILLIC CAPITAL LETTER EM\n    {\"mcy\",              0x0043C},  // CYRILLIC SMALL LETTER EM\n    {\"mdash\",            0x02014},  // EM DASH\n    {\"mDDot\",            0x0223A},  // GEOMETRIC PROPORTION\n    {\"measuredangle\",    0x02221},  // MEASURED ANGLE\n    {\"MediumSpace\",      0x0205F},  // MEDIUM MATHEMATICAL SPACE\n    {\"Mellintrf\",        0x02133},  // SCRIPT CAPITAL M\n    {\"Mfr\",              0x1D510},  // MATHEMATICAL FRAKTUR CAPITAL M\n    {\"mfr\",              0x1D52A},  // MATHEMATICAL FRAKTUR SMALL M\n    {\"Mgr\",              0x0039C},  // GREEK CAPITAL LETTER MU\n    {\"mgr\",              0x003BC},  // GREEK SMALL LETTER MU\n    {\"mho\",              0x02127},  // INVERTED OHM SIGN\n    {\"micro\",            0x000B5},  // MICRO SIGN\n    {\"mid\",              0x02223},  // DIVIDES\n    {\"midast\",           0x0002A},  // ASTERISK\n    {\"midcir\",           0x02AF0},  // VERTICAL LINE WITH CIRCLE BELOW\n    {\"middot\",           0x000B7},  // MIDDLE DOT\n    {\"minus\",            0x02212},  // MINUS SIGN\n    {\"minusb\",           0x0229F},  // SQUARED MINUS\n    {\"minusd\",           0x02238},  // DOT MINUS\n    {\"minusdu\",          0x02A2A},  // MINUS SIGN WITH DOT BELOW\n    {\"MinusPlus\",        0x02213},  // MINUS-OR-PLUS SIGN\n    {\"mlcp\",             0x02ADB},  // TRANSVERSAL INTERSECTION\n    {\"mldr\",             0x02026},  // HORIZONTAL ELLIPSIS\n    {\"mnplus\",           0x02213},  // MINUS-OR-PLUS SIGN\n    {\"models\",           0x022A7},  // MODELS\n    {\"Mopf\",             0x1D544},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL M\n    {\"mopf\",             0x1D55E},  // MATHEMATICAL DOUBLE-STRUCK SMALL M\n    {\"mp\",               0x02213},  // MINUS-OR-PLUS SIGN\n    {\"Mscr\",             0x02133},  // SCRIPT CAPITAL M\n    {\"mscr\",             0x1D4C2},  // MATHEMATICAL SCRIPT SMALL M\n    {\"mstpos\",           0x0223E},  // INVERTED LAZY S\n    {\"Mu\",               0x0039C},  // GREEK CAPITAL LETTER MU\n    {\"mu\",               0x003BC},  // GREEK SMALL LETTER MU\n    {\"multimap\",         0x022B8},  // MULTIMAP\n    {\"mumap\",            0x022B8},  // MULTIMAP\n];\n\nimmutable NameId[] namesN =\n[\n    {\"nabla\",            0x02207},  // NABLA\n    {\"Nacute\",           0x00143},  // LATIN CAPITAL LETTER N WITH ACUTE\n    {\"nacute\",           0x00144},  // LATIN SMALL LETTER N WITH ACUTE\n//  \"nang\",             0x02220;0x020D2},  // ANGLE with vertical line\n    {\"nap\",              0x02249},  // NOT ALMOST EQUAL TO\n//  \"napE\",             0x02A70;0x00338},  // APPROXIMATELY EQUAL OR EQUAL TO with slash\n//  \"napid\",            0x0224B;0x00338},  // TRIPLE TILDE with slash\n    {\"napos\",            0x00149},  // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE\n    {\"napprox\",          0x02249},  // NOT ALMOST EQUAL TO\n    {\"natur\",            0x0266E},  // MUSIC NATURAL SIGN\n    {\"natural\",          0x0266E},  // MUSIC NATURAL SIGN\n    {\"naturals\",         0x02115},  // DOUBLE-STRUCK CAPITAL N\n    {\"nbsp\",             0x000A0},  // NO-BREAK SPACE\n//  \"nbump\",            0x0224E;0x00338},  // GEOMETRICALLY EQUIVALENT TO with slash\n//  \"nbumpe\",           0x0224F;0x00338},  // DIFFERENCE BETWEEN with slash\n    {\"ncap\",             0x02A43},  // INTERSECTION WITH OVERBAR\n    {\"Ncaron\",           0x00147},  // LATIN CAPITAL LETTER N WITH CARON\n    {\"ncaron\",           0x00148},  // LATIN SMALL LETTER N WITH CARON\n    {\"Ncedil\",           0x00145},  // LATIN CAPITAL LETTER N WITH CEDILLA\n    {\"ncedil\",           0x00146},  // LATIN SMALL LETTER N WITH CEDILLA\n    {\"ncong\",            0x02247},  // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO\n//  \"ncongdot\",         0x02A6D;0x00338},  // CONGRUENT WITH DOT ABOVE with slash\n    {\"ncup\",             0x02A42},  // UNION WITH OVERBAR\n    {\"Ncy\",              0x0041D},  // CYRILLIC CAPITAL LETTER EN\n    {\"ncy\",              0x0043D},  // CYRILLIC SMALL LETTER EN\n    {\"ndash\",            0x02013},  // EN DASH\n    {\"ne\",               0x02260},  // NOT EQUAL TO\n    {\"nearhk\",           0x02924},  // NORTH EAST ARROW WITH HOOK\n    {\"nearr\",            0x02197},  // NORTH EAST ARROW\n    {\"neArr\",            0x021D7},  // NORTH EAST DOUBLE ARROW\n    {\"nearrow\",          0x02197},  // NORTH EAST ARROW\n//  \"nedot\",            0x02250;0x00338},  // APPROACHES THE LIMIT with slash\n    {\"NegativeMediumSpace\", 0x0200B},  // ZERO WIDTH SPACE\n    {\"NegativeThickSpace\", 0x0200B},  // ZERO WIDTH SPACE\n    {\"NegativeThinSpace\", 0x0200B},  // ZERO WIDTH SPACE\n    {\"NegativeVeryThinSpace\", 0x0200B},  // ZERO WIDTH SPACE\n    {\"nequiv\",           0x02262},  // NOT IDENTICAL TO\n    {\"nesear\",           0x02928},  // NORTH EAST ARROW AND SOUTH EAST ARROW\n//  \"nesim\",            0x02242;0x00338},  // MINUS TILDE with slash\n    {\"NestedGreaterGreater\", 0x0226B},  // MUCH GREATER-THAN\n    {\"NestedLessLess\",   0x0226A},  // MUCH LESS-THAN\n    {\"NewLine\",          0x0000A},  // LINE FEED (LF)\n    {\"nexist\",           0x02204},  // THERE DOES NOT EXIST\n    {\"nexists\",          0x02204},  // THERE DOES NOT EXIST\n    {\"Nfr\",              0x1D511},  // MATHEMATICAL FRAKTUR CAPITAL N\n    {\"nfr\",              0x1D52B},  // MATHEMATICAL FRAKTUR SMALL N\n//  \"ngE\",              0x02267;0x00338},  // GREATER-THAN OVER EQUAL TO with slash\n    {\"nge\",              0x02271},  // NEITHER GREATER-THAN NOR EQUAL TO\n    {\"ngeq\",             0x02271},  // NEITHER GREATER-THAN NOR EQUAL TO\n//  \"ngeqq\",            0x02267;0x00338},  // GREATER-THAN OVER EQUAL TO with slash\n//  \"ngeqslant\",        0x02A7E;0x00338},  // GREATER-THAN OR SLANTED EQUAL TO with slash\n//  \"nges\",             0x02A7E;0x00338},  // GREATER-THAN OR SLANTED EQUAL TO with slash\n//  \"nGg\",              0x022D9;0x00338},  // VERY MUCH GREATER-THAN with slash\n    {\"Ngr\",              0x0039D},  // GREEK CAPITAL LETTER NU\n    {\"ngr\",              0x003BD},  // GREEK SMALL LETTER NU\n    {\"ngsim\",            0x02275},  // NEITHER GREATER-THAN NOR EQUIVALENT TO\n//  \"nGt\",              0x0226B;0x020D2},  // MUCH GREATER THAN with vertical line\n    {\"ngt\",              0x0226F},  // NOT GREATER-THAN\n    {\"ngtr\",             0x0226F},  // NOT GREATER-THAN\n//  \"nGtv\",             0x0226B;0x00338},  // MUCH GREATER THAN with slash\n    {\"nharr\",            0x021AE},  // LEFT RIGHT ARROW WITH STROKE\n    {\"nhArr\",            0x021CE},  // LEFT RIGHT DOUBLE ARROW WITH STROKE\n    {\"nhpar\",            0x02AF2},  // PARALLEL WITH HORIZONTAL STROKE\n    {\"ni\",               0x0220B},  // CONTAINS AS MEMBER\n    {\"nis\",              0x022FC},  // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE\n    {\"nisd\",             0x022FA},  // CONTAINS WITH LONG HORIZONTAL STROKE\n    {\"niv\",              0x0220B},  // CONTAINS AS MEMBER\n    {\"NJcy\",             0x0040A},  // CYRILLIC CAPITAL LETTER NJE\n    {\"njcy\",             0x0045A},  // CYRILLIC SMALL LETTER NJE\n    {\"nlarr\",            0x0219A},  // LEFTWARDS ARROW WITH STROKE\n    {\"nlArr\",            0x021CD},  // LEFTWARDS DOUBLE ARROW WITH STROKE\n    {\"nldr\",             0x02025},  // TWO DOT LEADER\n//  \"nlE\",              0x02266;0x00338},  // LESS-THAN OVER EQUAL TO with slash\n    {\"nle\",              0x02270},  // NEITHER LESS-THAN NOR EQUAL TO\n    {\"nleftarrow\",       0x0219A},  // LEFTWARDS ARROW WITH STROKE\n    {\"nLeftarrow\",       0x021CD},  // LEFTWARDS DOUBLE ARROW WITH STROKE\n    {\"nleftrightarrow\",  0x021AE},  // LEFT RIGHT ARROW WITH STROKE\n    {\"nLeftrightarrow\",  0x021CE},  // LEFT RIGHT DOUBLE ARROW WITH STROKE\n    {\"nleq\",             0x02270},  // NEITHER LESS-THAN NOR EQUAL TO\n//  \"nleqq\",            0x02266;0x00338},  // LESS-THAN OVER EQUAL TO with slash\n//  \"nleqslant\",        0x02A7D;0x00338},  // LESS-THAN OR SLANTED EQUAL TO with slash\n//  \"nles\",             0x02A7D;0x00338},  // LESS-THAN OR SLANTED EQUAL TO with slash\n    {\"nless\",            0x0226E},  // NOT LESS-THAN\n//  \"nLl\",              0x022D8;0x00338},  // VERY MUCH LESS-THAN with slash\n    {\"nlsim\",            0x02274},  // NEITHER LESS-THAN NOR EQUIVALENT TO\n//  \"nLt\",              0x0226A;0x020D2},  // MUCH LESS THAN with vertical line\n    {\"nlt\",              0x0226E},  // NOT LESS-THAN\n    {\"nltri\",            0x022EA},  // NOT NORMAL SUBGROUP OF\n    {\"nltrie\",           0x022EC},  // NOT NORMAL SUBGROUP OF OR EQUAL TO\n//  \"nLtv\",             0x0226A;0x00338},  // MUCH LESS THAN with slash\n    {\"nmid\",             0x02224},  // DOES NOT DIVIDE\n    {\"NoBreak\",          0x02060},  // WORD JOINER\n    {\"NonBreakingSpace\", 0x000A0},  // NO-BREAK SPACE\n    {\"Nopf\",             0x02115},  // DOUBLE-STRUCK CAPITAL N\n    {\"nopf\",             0x1D55F},  // MATHEMATICAL DOUBLE-STRUCK SMALL N\n    {\"not\",              0x000AC},  // NOT SIGN\n    {\"Not\",              0x02AEC},  // DOUBLE STROKE NOT SIGN\n    {\"NotCongruent\",     0x02262},  // NOT IDENTICAL TO\n    {\"NotCupCap\",        0x0226D},  // NOT EQUIVALENT TO\n    {\"NotDoubleVerticalBar\", 0x02226},  // NOT PARALLEL TO\n    {\"NotElement\",       0x02209},  // NOT AN ELEMENT OF\n    {\"NotEqual\",         0x02260},  // NOT EQUAL TO\n//  \"NotEqualTilde\",    0x02242;0x00338},  // MINUS TILDE with slash\n    {\"NotExists\",        0x02204},  // THERE DOES NOT EXIST\n    {\"NotGreater\",       0x0226F},  // NOT GREATER-THAN\n    {\"NotGreaterEqual\",  0x02271},  // NEITHER GREATER-THAN NOR EQUAL TO\n//  \"NotGreaterFullEqual\", 0x02267;0x00338},  // GREATER-THAN OVER EQUAL TO with slash\n//  \"NotGreaterGreater\", 0x0226B;0x00338},  // MUCH GREATER THAN with slash\n    {\"NotGreaterLess\",   0x02279},  // NEITHER GREATER-THAN NOR LESS-THAN\n//  \"NotGreaterSlantEqual\", 0x02A7E;0x00338},  // GREATER-THAN OR SLANTED EQUAL TO with slash\n    {\"NotGreaterTilde\",  0x02275},  // NEITHER GREATER-THAN NOR EQUIVALENT TO\n//  \"NotHumpDownHump\",  0x0224E;0x00338},  // GEOMETRICALLY EQUIVALENT TO with slash\n//  \"NotHumpEqual\",     0x0224F;0x00338},  // DIFFERENCE BETWEEN with slash\n    {\"notin\",            0x02209},  // NOT AN ELEMENT OF\n//  \"notindot\",         0x022F5;0x00338},  // ELEMENT OF WITH DOT ABOVE with slash\n//  \"notinE\",           0x022F9;0x00338},  // ELEMENT OF WITH TWO HORIZONTAL STROKES with slash\n    {\"notinva\",          0x02209},  // NOT AN ELEMENT OF\n    {\"notinvb\",          0x022F7},  // SMALL ELEMENT OF WITH OVERBAR\n    {\"notinvc\",          0x022F6},  // ELEMENT OF WITH OVERBAR\n    {\"NotLeftTriangle\",  0x022EA},  // NOT NORMAL SUBGROUP OF\n//  \"NotLeftTriangleBar\", 0x029CF;0x00338},  // LEFT TRIANGLE BESIDE VERTICAL BAR with slash\n    {\"NotLeftTriangleEqual\", 0x022EC},  // NOT NORMAL SUBGROUP OF OR EQUAL TO\n    {\"NotLess\",          0x0226E},  // NOT LESS-THAN\n    {\"NotLessEqual\",     0x02270},  // NEITHER LESS-THAN NOR EQUAL TO\n    {\"NotLessGreater\",   0x02278},  // NEITHER LESS-THAN NOR GREATER-THAN\n//  \"NotLessLess\",      0x0226A;0x00338},  // MUCH LESS THAN with slash\n//  \"NotLessSlantEqual\", 0x02A7D;0x00338},  // LESS-THAN OR SLANTED EQUAL TO with slash\n    {\"NotLessTilde\",     0x02274},  // NEITHER LESS-THAN NOR EQUIVALENT TO\n//  \"NotNestedGreaterGreater\", 0x02AA2;0x00338},  // DOUBLE NESTED GREATER-THAN with slash\n//  \"NotNestedLessLess\", 0x02AA1;0x00338},  // DOUBLE NESTED LESS-THAN with slash\n    {\"notni\",            0x0220C},  // DOES NOT CONTAIN AS MEMBER\n    {\"notniva\",          0x0220C},  // DOES NOT CONTAIN AS MEMBER\n    {\"notnivb\",          0x022FE},  // SMALL CONTAINS WITH OVERBAR\n    {\"notnivc\",          0x022FD},  // CONTAINS WITH OVERBAR\n    {\"NotPrecedes\",      0x02280},  // DOES NOT PRECEDE\n//  \"NotPrecedesEqual\", 0x02AAF;0x00338},  // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash\n    {\"NotPrecedesSlantEqual\", 0x022E0},  // DOES NOT PRECEDE OR EQUAL\n    {\"NotReverseElement\", 0x0220C},  // DOES NOT CONTAIN AS MEMBER\n    {\"NotRightTriangle\", 0x022EB},  // DOES NOT CONTAIN AS NORMAL SUBGROUP\n//  \"NotRightTriangleBar\", 0x029D0;0x00338},  // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash\n    {\"NotRightTriangleEqual\", 0x022ED},  // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL\n//  \"NotSquareSubset\",  0x0228F;0x00338},  // SQUARE IMAGE OF with slash\n    {\"NotSquareSubsetEqual\", 0x022E2},  // NOT SQUARE IMAGE OF OR EQUAL TO\n//  \"NotSquareSuperset\", 0x02290;0x00338},  // SQUARE ORIGINAL OF with slash\n    {\"NotSquareSupersetEqual\", 0x022E3},  // NOT SQUARE ORIGINAL OF OR EQUAL TO\n//  \"NotSubset\",        0x02282;0x020D2},  // SUBSET OF with vertical line\n    {\"NotSubsetEqual\",   0x02288},  // NEITHER A SUBSET OF NOR EQUAL TO\n    {\"NotSucceeds\",      0x02281},  // DOES NOT SUCCEED\n//  \"NotSucceedsEqual\", 0x02AB0;0x00338},  // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash\n    {\"NotSucceedsSlantEqual\", 0x022E1},  // DOES NOT SUCCEED OR EQUAL\n//  \"NotSucceedsTilde\", 0x0227F;0x00338},  // SUCCEEDS OR EQUIVALENT TO with slash\n//  \"NotSuperset\",      0x02283;0x020D2},  // SUPERSET OF with vertical line\n    {\"NotSupersetEqual\", 0x02289},  // NEITHER A SUPERSET OF NOR EQUAL TO\n    {\"NotTilde\",         0x02241},  // NOT TILDE\n    {\"NotTildeEqual\",    0x02244},  // NOT ASYMPTOTICALLY EQUAL TO\n    {\"NotTildeFullEqual\", 0x02247},  // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO\n    {\"NotTildeTilde\",    0x02249},  // NOT ALMOST EQUAL TO\n    {\"NotVerticalBar\",   0x02224},  // DOES NOT DIVIDE\n    {\"npar\",             0x02226},  // NOT PARALLEL TO\n    {\"nparallel\",        0x02226},  // NOT PARALLEL TO\n//  \"nparsl\",           0x02AFD;0x020E5},  // DOUBLE SOLIDUS OPERATOR with reverse slash\n//  \"npart\",            0x02202;0x00338},  // PARTIAL DIFFERENTIAL with slash\n    {\"npolint\",          0x02A14},  // LINE INTEGRATION NOT INCLUDING THE POLE\n    {\"npr\",              0x02280},  // DOES NOT PRECEDE\n    {\"nprcue\",           0x022E0},  // DOES NOT PRECEDE OR EQUAL\n//  \"npre\",             0x02AAF;0x00338},  // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash\n    {\"nprec\",            0x02280},  // DOES NOT PRECEDE\n//  \"npreceq\",          0x02AAF;0x00338},  // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash\n    {\"nrarr\",            0x0219B},  // RIGHTWARDS ARROW WITH STROKE\n    {\"nrArr\",            0x021CF},  // RIGHTWARDS DOUBLE ARROW WITH STROKE\n//  \"nrarrc\",           0x02933;0x00338},  // WAVE ARROW POINTING DIRECTLY RIGHT with slash\n//  \"nrarrw\",           0x0219D;0x00338},  // RIGHTWARDS WAVE ARROW with slash\n    {\"nrightarrow\",      0x0219B},  // RIGHTWARDS ARROW WITH STROKE\n    {\"nRightarrow\",      0x021CF},  // RIGHTWARDS DOUBLE ARROW WITH STROKE\n    {\"nrtri\",            0x022EB},  // DOES NOT CONTAIN AS NORMAL SUBGROUP\n    {\"nrtrie\",           0x022ED},  // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL\n    {\"nsc\",              0x02281},  // DOES NOT SUCCEED\n    {\"nsccue\",           0x022E1},  // DOES NOT SUCCEED OR EQUAL\n//  \"nsce\",             0x02AB0;0x00338},  // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash\n    {\"Nscr\",             0x1D4A9},  // MATHEMATICAL SCRIPT CAPITAL N\n    {\"nscr\",             0x1D4C3},  // MATHEMATICAL SCRIPT SMALL N\n    {\"nshortmid\",        0x02224},  // DOES NOT DIVIDE\n    {\"nshortparallel\",   0x02226},  // NOT PARALLEL TO\n    {\"nsim\",             0x02241},  // NOT TILDE\n    {\"nsime\",            0x02244},  // NOT ASYMPTOTICALLY EQUAL TO\n    {\"nsimeq\",           0x02244},  // NOT ASYMPTOTICALLY EQUAL TO\n    {\"nsmid\",            0x02224},  // DOES NOT DIVIDE\n    {\"nspar\",            0x02226},  // NOT PARALLEL TO\n    {\"nsqsube\",          0x022E2},  // NOT SQUARE IMAGE OF OR EQUAL TO\n    {\"nsqsupe\",          0x022E3},  // NOT SQUARE ORIGINAL OF OR EQUAL TO\n    {\"nsub\",             0x02284},  // NOT A SUBSET OF\n    {\"nsube\",            0x02288},  // NEITHER A SUBSET OF NOR EQUAL TO\n//  \"nsubE\",            0x02AC5;0x00338},  // SUBSET OF ABOVE EQUALS SIGN with slash\n//  \"nsubset\",          0x02282;0x020D2},  // SUBSET OF with vertical line\n    {\"nsubseteq\",        0x02288},  // NEITHER A SUBSET OF NOR EQUAL TO\n//  \"nsubseteqq\",       0x02AC5;0x00338},  // SUBSET OF ABOVE EQUALS SIGN with slash\n    {\"nsucc\",            0x02281},  // DOES NOT SUCCEED\n//  \"nsucceq\",          0x02AB0;0x00338},  // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash\n    {\"nsup\",             0x02285},  // NOT A SUPERSET OF\n    {\"nsupe\",            0x02289},  // NEITHER A SUPERSET OF NOR EQUAL TO\n//  \"nsupE\",            0x02AC6;0x00338},  // SUPERSET OF ABOVE EQUALS SIGN with slash\n//  \"nsupset\",          0x02283;0x020D2},  // SUPERSET OF with vertical line\n    {\"nsupseteq\",        0x02289},  // NEITHER A SUPERSET OF NOR EQUAL TO\n//  \"nsupseteqq\",       0x02AC6;0x00338},  // SUPERSET OF ABOVE EQUALS SIGN with slash\n    {\"ntgl\",             0x02279},  // NEITHER GREATER-THAN NOR LESS-THAN\n    {\"Ntilde\",           0x000D1},  // LATIN CAPITAL LETTER N WITH TILDE\n    {\"ntilde\",           0x000F1},  // LATIN SMALL LETTER N WITH TILDE\n    {\"ntlg\",             0x02278},  // NEITHER LESS-THAN NOR GREATER-THAN\n    {\"ntriangleleft\",    0x022EA},  // NOT NORMAL SUBGROUP OF\n    {\"ntrianglelefteq\",  0x022EC},  // NOT NORMAL SUBGROUP OF OR EQUAL TO\n    {\"ntriangleright\",   0x022EB},  // DOES NOT CONTAIN AS NORMAL SUBGROUP\n    {\"ntrianglerighteq\", 0x022ED},  // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL\n    {\"Nu\",               0x0039D},  // GREEK CAPITAL LETTER NU\n    {\"nu\",               0x003BD},  // GREEK SMALL LETTER NU\n    {\"num\",              0x00023},  // NUMBER SIGN\n    {\"numero\",           0x02116},  // NUMERO SIGN\n    {\"numsp\",            0x02007},  // FIGURE SPACE\n//  \"nvap\",             0x0224D;0x020D2},  // EQUIVALENT TO with vertical line\n    {\"nvdash\",           0x022AC},  // DOES NOT PROVE\n    {\"nvDash\",           0x022AD},  // NOT TRUE\n    {\"nVdash\",           0x022AE},  // DOES NOT FORCE\n    {\"nVDash\",           0x022AF},  // NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE\n//  \"nvge\",             0x02265;0x020D2},  // GREATER-THAN OR EQUAL TO with vertical line\n//  \"nvgt\",             0x0003E;0x020D2},  // GREATER-THAN SIGN with vertical line\n    {\"nvHarr\",           0x02904},  // LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE\n    {\"nvinfin\",          0x029DE},  // INFINITY NEGATED WITH VERTICAL BAR\n    {\"nvlArr\",           0x02902},  // LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE\n//  \"nvle\",             0x02264;0x020D2},  // LESS-THAN OR EQUAL TO with vertical line\n//  \"nvlt\",             0x0003C;0x020D2},  // LESS-THAN SIGN with vertical line\n//  \"nvltrie\",          0x022B4;0x020D2},  // NORMAL SUBGROUP OF OR EQUAL TO with vertical line\n    {\"nvrArr\",           0x02903},  // RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE\n//  \"nvrtrie\",          0x022B5;0x020D2},  // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line\n//  \"nvsim\",            0x0223C;0x020D2},  // TILDE OPERATOR with vertical line\n    {\"nwarhk\",           0x02923},  // NORTH WEST ARROW WITH HOOK\n    {\"nwarr\",            0x02196},  // NORTH WEST ARROW\n    {\"nwArr\",            0x021D6},  // NORTH WEST DOUBLE ARROW\n    {\"nwarrow\",          0x02196},  // NORTH WEST ARROW\n    {\"nwnear\",           0x02927},  // NORTH WEST ARROW AND NORTH EAST ARROW\n];\n\nimmutable NameId[] namesO =\n[\n    {\"Oacgr\",            0x0038C},  // GREEK CAPITAL LETTER OMICRON WITH TONOS\n    {\"oacgr\",            0x003CC},  // GREEK SMALL LETTER OMICRON WITH TONOS\n    {\"Oacute\",           0x000D3},  // LATIN CAPITAL LETTER O WITH ACUTE\n    {\"oacute\",           0x000F3},  // LATIN SMALL LETTER O WITH ACUTE\n    {\"oast\",             0x0229B},  // CIRCLED ASTERISK OPERATOR\n    {\"ocir\",             0x0229A},  // CIRCLED RING OPERATOR\n    {\"Ocirc\",            0x000D4},  // LATIN CAPITAL LETTER O WITH CIRCUMFLEX\n    {\"ocirc\",            0x000F4},  // LATIN SMALL LETTER O WITH CIRCUMFLEX\n    {\"Ocy\",              0x0041E},  // CYRILLIC CAPITAL LETTER O\n    {\"ocy\",              0x0043E},  // CYRILLIC SMALL LETTER O\n    {\"odash\",            0x0229D},  // CIRCLED DASH\n    {\"Odblac\",           0x00150},  // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE\n    {\"odblac\",           0x00151},  // LATIN SMALL LETTER O WITH DOUBLE ACUTE\n    {\"odiv\",             0x02A38},  // CIRCLED DIVISION SIGN\n    {\"odot\",             0x02299},  // CIRCLED DOT OPERATOR\n    {\"odsold\",           0x029BC},  // CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN\n    {\"OElig\",            0x00152},  // LATIN CAPITAL LIGATURE OE\n    {\"oelig\",            0x00153},  // LATIN SMALL LIGATURE OE\n    {\"ofcir\",            0x029BF},  // CIRCLED BULLET\n    {\"Ofr\",              0x1D512},  // MATHEMATICAL FRAKTUR CAPITAL O\n    {\"ofr\",              0x1D52C},  // MATHEMATICAL FRAKTUR SMALL O\n    {\"ogon\",             0x002DB},  // OGONEK\n    {\"Ogr\",              0x0039F},  // GREEK CAPITAL LETTER OMICRON\n    {\"ogr\",              0x003BF},  // GREEK SMALL LETTER OMICRON\n    {\"Ograve\",           0x000D2},  // LATIN CAPITAL LETTER O WITH GRAVE\n    {\"ograve\",           0x000F2},  // LATIN SMALL LETTER O WITH GRAVE\n    {\"ogt\",              0x029C1},  // CIRCLED GREATER-THAN\n    {\"OHacgr\",           0x0038F},  // GREEK CAPITAL LETTER OMEGA WITH TONOS\n    {\"ohacgr\",           0x003CE},  // GREEK SMALL LETTER OMEGA WITH TONOS\n    {\"ohbar\",            0x029B5},  // CIRCLE WITH HORIZONTAL BAR\n    {\"OHgr\",             0x003A9},  // GREEK CAPITAL LETTER OMEGA\n    {\"ohgr\",             0x003C9},  // GREEK SMALL LETTER OMEGA\n    {\"ohm\",              0x003A9},  // GREEK CAPITAL LETTER OMEGA\n    {\"oint\",             0x0222E},  // CONTOUR INTEGRAL\n    {\"olarr\",            0x021BA},  // ANTICLOCKWISE OPEN CIRCLE ARROW\n    {\"olcir\",            0x029BE},  // CIRCLED WHITE BULLET\n    {\"olcross\",          0x029BB},  // CIRCLE WITH SUPERIMPOSED X\n    {\"oline\",            0x0203E},  // OVERLINE\n    {\"olt\",              0x029C0},  // CIRCLED LESS-THAN\n    {\"Omacr\",            0x0014C},  // LATIN CAPITAL LETTER O WITH MACRON\n    {\"omacr\",            0x0014D},  // LATIN SMALL LETTER O WITH MACRON\n    {\"Omega\",            0x003A9},  // GREEK CAPITAL LETTER OMEGA\n    {\"omega\",            0x003C9},  // GREEK SMALL LETTER OMEGA\n    {\"Omicron\",          0x0039F},  // GREEK CAPITAL LETTER OMICRON\n    {\"omicron\",          0x003BF},  // GREEK SMALL LETTER OMICRON\n    {\"omid\",             0x029B6},  // CIRCLED VERTICAL BAR\n    {\"ominus\",           0x02296},  // CIRCLED MINUS\n    {\"Oopf\",             0x1D546},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL O\n    {\"oopf\",             0x1D560},  // MATHEMATICAL DOUBLE-STRUCK SMALL O\n    {\"opar\",             0x029B7},  // CIRCLED PARALLEL\n    {\"OpenCurlyDoubleQuote\", 0x0201C},  // LEFT DOUBLE QUOTATION MARK\n    {\"OpenCurlyQuote\",   0x02018},  // LEFT SINGLE QUOTATION MARK\n    {\"operp\",            0x029B9},  // CIRCLED PERPENDICULAR\n    {\"oplus\",            0x02295},  // CIRCLED PLUS\n    {\"or\",               0x02228},  // LOGICAL OR\n    {\"Or\",               0x02A54},  // DOUBLE LOGICAL OR\n    {\"orarr\",            0x021BB},  // CLOCKWISE OPEN CIRCLE ARROW\n    {\"ord\",              0x02A5D},  // LOGICAL OR WITH HORIZONTAL DASH\n    {\"order\",            0x02134},  // SCRIPT SMALL O\n    {\"orderof\",          0x02134},  // SCRIPT SMALL O\n    {\"ordf\",             0x000AA},  // FEMININE ORDINAL INDICATOR\n    {\"ordm\",             0x000BA},  // MASCULINE ORDINAL INDICATOR\n    {\"origof\",           0x022B6},  // ORIGINAL OF\n    {\"oror\",             0x02A56},  // TWO INTERSECTING LOGICAL OR\n    {\"orslope\",          0x02A57},  // SLOPING LARGE OR\n    {\"orv\",              0x02A5B},  // LOGICAL OR WITH MIDDLE STEM\n    {\"oS\",               0x024C8},  // CIRCLED LATIN CAPITAL LETTER S\n    {\"oscr\",             0x02134},  // SCRIPT SMALL O\n    {\"Oscr\",             0x1D4AA},  // MATHEMATICAL SCRIPT CAPITAL O\n    {\"Oslash\",           0x000D8},  // LATIN CAPITAL LETTER O WITH STROKE\n    {\"oslash\",           0x000F8},  // LATIN SMALL LETTER O WITH STROKE\n    {\"osol\",             0x02298},  // CIRCLED DIVISION SLASH\n    {\"Otilde\",           0x000D5},  // LATIN CAPITAL LETTER O WITH TILDE\n    {\"otilde\",           0x000F5},  // LATIN SMALL LETTER O WITH TILDE\n    {\"otimes\",           0x02297},  // CIRCLED TIMES\n    {\"Otimes\",           0x02A37},  // MULTIPLICATION SIGN IN DOUBLE CIRCLE\n    {\"otimesas\",         0x02A36},  // CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT\n    {\"Ouml\",             0x000D6},  // LATIN CAPITAL LETTER O WITH DIAERESIS\n    {\"ouml\",             0x000F6},  // LATIN SMALL LETTER O WITH DIAERESIS\n    {\"ovbar\",            0x0233D},  // APL FUNCTIONAL SYMBOL CIRCLE STILE\n    {\"OverBar\",          0x0203E},  // OVERLINE\n    {\"OverBrace\",        0x023DE},  // TOP CURLY BRACKET\n    {\"OverBracket\",      0x023B4},  // TOP SQUARE BRACKET\n    {\"OverParenthesis\",  0x023DC},  // TOP PARENTHESIS\n];\n\nimmutable NameId[] namesP =\n[\n    {\"par\",              0x02225},  // PARALLEL TO\n    {\"para\",             0x000B6},  // PILCROW SIGN\n    {\"parallel\",         0x02225},  // PARALLEL TO\n    {\"parsim\",           0x02AF3},  // PARALLEL WITH TILDE OPERATOR\n    {\"parsl\",            0x02AFD},  // DOUBLE SOLIDUS OPERATOR\n    {\"part\",             0x02202},  // PARTIAL DIFFERENTIAL\n    {\"PartialD\",         0x02202},  // PARTIAL DIFFERENTIAL\n    {\"Pcy\",              0x0041F},  // CYRILLIC CAPITAL LETTER PE\n    {\"pcy\",              0x0043F},  // CYRILLIC SMALL LETTER PE\n    {\"percnt\",           0x00025},  // PERCENT SIGN\n    {\"period\",           0x0002E},  // FULL STOP\n    {\"permil\",           0x02030},  // PER MILLE SIGN\n    {\"perp\",             0x022A5},  // UP TACK\n    {\"pertenk\",          0x02031},  // PER TEN THOUSAND SIGN\n    {\"Pfr\",              0x1D513},  // MATHEMATICAL FRAKTUR CAPITAL P\n    {\"pfr\",              0x1D52D},  // MATHEMATICAL FRAKTUR SMALL P\n    {\"Pgr\",              0x003A0},  // GREEK CAPITAL LETTER PI\n    {\"pgr\",              0x003C0},  // GREEK SMALL LETTER PI\n    {\"PHgr\",             0x003A6},  // GREEK CAPITAL LETTER PHI\n    {\"phgr\",             0x003C6},  // GREEK SMALL LETTER PHI\n    {\"Phi\",              0x003A6},  // GREEK CAPITAL LETTER PHI\n    {\"phi\",              0x003C6},  // GREEK SMALL LETTER PHI\n    {\"phiv\",             0x003D5},  // GREEK PHI SYMBOL\n    {\"phmmat\",           0x02133},  // SCRIPT CAPITAL M\n    {\"phone\",            0x0260E},  // BLACK TELEPHONE\n    {\"Pi\",               0x003A0},  // GREEK CAPITAL LETTER PI\n    {\"pi\",               0x003C0},  // GREEK SMALL LETTER PI\n    {\"pitchfork\",        0x022D4},  // PITCHFORK\n    {\"piv\",              0x003D6},  // GREEK PI SYMBOL\n    {\"planck\",           0x0210F},  // PLANCK CONSTANT OVER TWO PI\n    {\"planckh\",          0x0210E},  // PLANCK CONSTANT\n    {\"plankv\",           0x0210F},  // PLANCK CONSTANT OVER TWO PI\n    {\"plus\",             0x0002B},  // PLUS SIGN\n    {\"plusacir\",         0x02A23},  // PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE\n    {\"plusb\",            0x0229E},  // SQUARED PLUS\n    {\"pluscir\",          0x02A22},  // PLUS SIGN WITH SMALL CIRCLE ABOVE\n    {\"plusdo\",           0x02214},  // DOT PLUS\n    {\"plusdu\",           0x02A25},  // PLUS SIGN WITH DOT BELOW\n    {\"pluse\",            0x02A72},  // PLUS SIGN ABOVE EQUALS SIGN\n    {\"PlusMinus\",        0x000B1},  // PLUS-MINUS SIGN\n    {\"plusmn\",           0x000B1},  // PLUS-MINUS SIGN\n    {\"plussim\",          0x02A26},  // PLUS SIGN WITH TILDE BELOW\n    {\"plustwo\",          0x02A27},  // PLUS SIGN WITH SUBSCRIPT TWO\n    {\"pm\",               0x000B1},  // PLUS-MINUS SIGN\n    {\"Poincareplane\",    0x0210C},  // BLACK-LETTER CAPITAL H\n    {\"pointint\",         0x02A15},  // INTEGRAL AROUND A POINT OPERATOR\n    {\"Popf\",             0x02119},  // DOUBLE-STRUCK CAPITAL P\n    {\"popf\",             0x1D561},  // MATHEMATICAL DOUBLE-STRUCK SMALL P\n    {\"pound\",            0x000A3},  // POUND SIGN\n    {\"pr\",               0x0227A},  // PRECEDES\n    {\"Pr\",               0x02ABB},  // DOUBLE PRECEDES\n    {\"prap\",             0x02AB7},  // PRECEDES ABOVE ALMOST EQUAL TO\n    {\"prcue\",            0x0227C},  // PRECEDES OR EQUAL TO\n    {\"pre\",              0x02AAF},  // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN\n    {\"prE\",              0x02AB3},  // PRECEDES ABOVE EQUALS SIGN\n    {\"prec\",             0x0227A},  // PRECEDES\n    {\"precapprox\",       0x02AB7},  // PRECEDES ABOVE ALMOST EQUAL TO\n    {\"preccurlyeq\",      0x0227C},  // PRECEDES OR EQUAL TO\n    {\"Precedes\",         0x0227A},  // PRECEDES\n    {\"PrecedesEqual\",    0x02AAF},  // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN\n    {\"PrecedesSlantEqual\", 0x0227C},  // PRECEDES OR EQUAL TO\n    {\"PrecedesTilde\",    0x0227E},  // PRECEDES OR EQUIVALENT TO\n    {\"preceq\",           0x02AAF},  // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN\n    {\"precnapprox\",      0x02AB9},  // PRECEDES ABOVE NOT ALMOST EQUAL TO\n    {\"precneqq\",         0x02AB5},  // PRECEDES ABOVE NOT EQUAL TO\n    {\"precnsim\",         0x022E8},  // PRECEDES BUT NOT EQUIVALENT TO\n    {\"precsim\",          0x0227E},  // PRECEDES OR EQUIVALENT TO\n    {\"prime\",            0x02032},  // PRIME\n    {\"Prime\",            0x02033},  // DOUBLE PRIME\n    {\"primes\",           0x02119},  // DOUBLE-STRUCK CAPITAL P\n    {\"prnap\",            0x02AB9},  // PRECEDES ABOVE NOT ALMOST EQUAL TO\n    {\"prnE\",             0x02AB5},  // PRECEDES ABOVE NOT EQUAL TO\n    {\"prnsim\",           0x022E8},  // PRECEDES BUT NOT EQUIVALENT TO\n    {\"prod\",             0x0220F},  // N-ARY PRODUCT\n    {\"Product\",          0x0220F},  // N-ARY PRODUCT\n    {\"profalar\",         0x0232E},  // ALL AROUND-PROFILE\n    {\"profline\",         0x02312},  // ARC\n    {\"profsurf\",         0x02313},  // SEGMENT\n    {\"prop\",             0x0221D},  // PROPORTIONAL TO\n    {\"Proportion\",       0x02237},  // PROPORTION\n    {\"Proportional\",     0x0221D},  // PROPORTIONAL TO\n    {\"propto\",           0x0221D},  // PROPORTIONAL TO\n    {\"prsim\",            0x0227E},  // PRECEDES OR EQUIVALENT TO\n    {\"prurel\",           0x022B0},  // PRECEDES UNDER RELATION\n    {\"Pscr\",             0x1D4AB},  // MATHEMATICAL SCRIPT CAPITAL P\n    {\"pscr\",             0x1D4C5},  // MATHEMATICAL SCRIPT SMALL P\n    {\"PSgr\",             0x003A8},  // GREEK CAPITAL LETTER PSI\n    {\"psgr\",             0x003C8},  // GREEK SMALL LETTER PSI\n    {\"Psi\",              0x003A8},  // GREEK CAPITAL LETTER PSI\n    {\"psi\",              0x003C8},  // GREEK SMALL LETTER PSI\n    {\"puncsp\",           0x02008},  // PUNCTUATION SPACE\n];\n\nimmutable NameId[] namesQ =\n[\n    {\"Qfr\",              0x1D514},  // MATHEMATICAL FRAKTUR CAPITAL Q\n    {\"qfr\",              0x1D52E},  // MATHEMATICAL FRAKTUR SMALL Q\n    {\"qint\",             0x02A0C},  // QUADRUPLE INTEGRAL OPERATOR\n    {\"Qopf\",             0x0211A},  // DOUBLE-STRUCK CAPITAL Q\n    {\"qopf\",             0x1D562},  // MATHEMATICAL DOUBLE-STRUCK SMALL Q\n    {\"qprime\",           0x02057},  // QUADRUPLE PRIME\n    {\"Qscr\",             0x1D4AC},  // MATHEMATICAL SCRIPT CAPITAL Q\n    {\"qscr\",             0x1D4C6},  // MATHEMATICAL SCRIPT SMALL Q\n    {\"quaternions\",      0x0210D},  // DOUBLE-STRUCK CAPITAL H\n    {\"quatint\",          0x02A16},  // QUATERNION INTEGRAL OPERATOR\n    {\"quest\",            0x0003F},  // QUESTION MARK\n    {\"questeq\",          0x0225F},  // QUESTIONED EQUAL TO\n    {\"quot\",             0x00022},  // QUOTATION MARK\n    {\"QUOT\",             0x00022},  // QUOTATION MARK\n];\n\nimmutable NameId[] namesR =\n[\n    {\"rAarr\",            0x021DB},  // RIGHTWARDS TRIPLE ARROW\n//  \"race\",             0x0223D;0x00331},  // REVERSED TILDE with underline\n    {\"Racute\",           0x00154},  // LATIN CAPITAL LETTER R WITH ACUTE\n    {\"racute\",           0x00155},  // LATIN SMALL LETTER R WITH ACUTE\n    {\"radic\",            0x0221A},  // SQUARE ROOT\n    {\"raemptyv\",         0x029B3},  // EMPTY SET WITH RIGHT ARROW ABOVE\n    {\"rang\",             0x027E9},  // MATHEMATICAL RIGHT ANGLE BRACKET\n    {\"Rang\",             0x027EB},  // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET\n    {\"rangd\",            0x02992},  // RIGHT ANGLE BRACKET WITH DOT\n    {\"range\",            0x029A5},  // REVERSED ANGLE WITH UNDERBAR\n    {\"rangle\",           0x027E9},  // MATHEMATICAL RIGHT ANGLE BRACKET\n    {\"raquo\",            0x000BB},  // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK\n    {\"rarr\",             0x02192},  // RIGHTWARDS ARROW\n    {\"Rarr\",             0x021A0},  // RIGHTWARDS TWO HEADED ARROW\n    {\"rArr\",             0x021D2},  // RIGHTWARDS DOUBLE ARROW\n    {\"rarrap\",           0x02975},  // RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO\n    {\"rarrb\",            0x021E5},  // RIGHTWARDS ARROW TO BAR\n    {\"rarrbfs\",          0x02920},  // RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND\n    {\"rarrc\",            0x02933},  // WAVE ARROW POINTING DIRECTLY RIGHT\n    {\"rarrfs\",           0x0291E},  // RIGHTWARDS ARROW TO BLACK DIAMOND\n    {\"rarrhk\",           0x021AA},  // RIGHTWARDS ARROW WITH HOOK\n    {\"rarrlp\",           0x021AC},  // RIGHTWARDS ARROW WITH LOOP\n    {\"rarrpl\",           0x02945},  // RIGHTWARDS ARROW WITH PLUS BELOW\n    {\"rarrsim\",          0x02974},  // RIGHTWARDS ARROW ABOVE TILDE OPERATOR\n    {\"rarrtl\",           0x021A3},  // RIGHTWARDS ARROW WITH TAIL\n    {\"Rarrtl\",           0x02916},  // RIGHTWARDS TWO-HEADED ARROW WITH TAIL\n    {\"rarrw\",            0x0219D},  // RIGHTWARDS WAVE ARROW\n    {\"ratail\",           0x0291A},  // RIGHTWARDS ARROW-TAIL\n    {\"rAtail\",           0x0291C},  // RIGHTWARDS DOUBLE ARROW-TAIL\n    {\"ratio\",            0x02236},  // RATIO\n    {\"rationals\",        0x0211A},  // DOUBLE-STRUCK CAPITAL Q\n    {\"rbarr\",            0x0290D},  // RIGHTWARDS DOUBLE DASH ARROW\n    {\"rBarr\",            0x0290F},  // RIGHTWARDS TRIPLE DASH ARROW\n    {\"RBarr\",            0x02910},  // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW\n    {\"rbbrk\",            0x02773},  // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT\n    {\"rbrace\",           0x0007D},  // RIGHT CURLY BRACKET\n    {\"rbrack\",           0x0005D},  // RIGHT SQUARE BRACKET\n    {\"rbrke\",            0x0298C},  // RIGHT SQUARE BRACKET WITH UNDERBAR\n    {\"rbrksld\",          0x0298E},  // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER\n    {\"rbrkslu\",          0x02990},  // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER\n    {\"Rcaron\",           0x00158},  // LATIN CAPITAL LETTER R WITH CARON\n    {\"rcaron\",           0x00159},  // LATIN SMALL LETTER R WITH CARON\n    {\"Rcedil\",           0x00156},  // LATIN CAPITAL LETTER R WITH CEDILLA\n    {\"rcedil\",           0x00157},  // LATIN SMALL LETTER R WITH CEDILLA\n    {\"rceil\",            0x02309},  // RIGHT CEILING\n    {\"rcub\",             0x0007D},  // RIGHT CURLY BRACKET\n    {\"Rcy\",              0x00420},  // CYRILLIC CAPITAL LETTER ER\n    {\"rcy\",              0x00440},  // CYRILLIC SMALL LETTER ER\n    {\"rdca\",             0x02937},  // ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS\n    {\"rdldhar\",          0x02969},  // RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN\n    {\"rdquo\",            0x0201D},  // RIGHT DOUBLE QUOTATION MARK\n    {\"rdquor\",           0x0201D},  // RIGHT DOUBLE QUOTATION MARK\n    {\"rdsh\",             0x021B3},  // DOWNWARDS ARROW WITH TIP RIGHTWARDS\n    {\"Re\",               0x0211C},  // BLACK-LETTER CAPITAL R\n    {\"real\",             0x0211C},  // BLACK-LETTER CAPITAL R\n    {\"realine\",          0x0211B},  // SCRIPT CAPITAL R\n    {\"realpart\",         0x0211C},  // BLACK-LETTER CAPITAL R\n    {\"reals\",            0x0211D},  // DOUBLE-STRUCK CAPITAL R\n    {\"rect\",             0x025AD},  // WHITE RECTANGLE\n    {\"reg\",              0x000AE},  // REGISTERED SIGN\n    {\"REG\",              0x000AE},  // REGISTERED SIGN\n    {\"ReverseElement\",   0x0220B},  // CONTAINS AS MEMBER\n    {\"ReverseEquilibrium\", 0x021CB},  // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON\n    {\"ReverseUpEquilibrium\", 0x0296F},  // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT\n    {\"rfisht\",           0x0297D},  // RIGHT FISH TAIL\n    {\"rfloor\",           0x0230B},  // RIGHT FLOOR\n    {\"Rfr\",              0x0211C},  // BLACK-LETTER CAPITAL R\n    {\"rfr\",              0x1D52F},  // MATHEMATICAL FRAKTUR SMALL R\n    {\"Rgr\",              0x003A1},  // GREEK CAPITAL LETTER RHO\n    {\"rgr\",              0x003C1},  // GREEK SMALL LETTER RHO\n    {\"rHar\",             0x02964},  // RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN\n    {\"rhard\",            0x021C1},  // RIGHTWARDS HARPOON WITH BARB DOWNWARDS\n    {\"rharu\",            0x021C0},  // RIGHTWARDS HARPOON WITH BARB UPWARDS\n    {\"rharul\",           0x0296C},  // RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH\n    {\"Rho\",              0x003A1},  // GREEK CAPITAL LETTER RHO\n    {\"rho\",              0x003C1},  // GREEK SMALL LETTER RHO\n    {\"rhov\",             0x003F1},  // GREEK RHO SYMBOL\n    {\"RightAngleBracket\", 0x027E9},  // MATHEMATICAL RIGHT ANGLE BRACKET\n    {\"rightarrow\",       0x02192},  // RIGHTWARDS ARROW\n    {\"RightArrow\",       0x02192},  // RIGHTWARDS ARROW\n    {\"Rightarrow\",       0x021D2},  // RIGHTWARDS DOUBLE ARROW\n    {\"RightArrowBar\",    0x021E5},  // RIGHTWARDS ARROW TO BAR\n    {\"RightArrowLeftArrow\", 0x021C4},  // RIGHTWARDS ARROW OVER LEFTWARDS ARROW\n    {\"rightarrowtail\",   0x021A3},  // RIGHTWARDS ARROW WITH TAIL\n    {\"RightCeiling\",     0x02309},  // RIGHT CEILING\n    {\"RightDoubleBracket\", 0x027E7},  // MATHEMATICAL RIGHT WHITE SQUARE BRACKET\n    {\"RightDownTeeVector\", 0x0295D},  // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR\n    {\"RightDownVector\",  0x021C2},  // DOWNWARDS HARPOON WITH BARB RIGHTWARDS\n    {\"RightDownVectorBar\", 0x02955},  // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR\n    {\"RightFloor\",       0x0230B},  // RIGHT FLOOR\n    {\"rightharpoondown\", 0x021C1},  // RIGHTWARDS HARPOON WITH BARB DOWNWARDS\n    {\"rightharpoonup\",   0x021C0},  // RIGHTWARDS HARPOON WITH BARB UPWARDS\n    {\"rightleftarrows\",  0x021C4},  // RIGHTWARDS ARROW OVER LEFTWARDS ARROW\n    {\"rightleftharpoons\", 0x021CC},  // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON\n    {\"rightrightarrows\", 0x021C9},  // RIGHTWARDS PAIRED ARROWS\n    {\"rightsquigarrow\",  0x0219D},  // RIGHTWARDS WAVE ARROW\n    {\"RightTee\",         0x022A2},  // RIGHT TACK\n    {\"RightTeeArrow\",    0x021A6},  // RIGHTWARDS ARROW FROM BAR\n    {\"RightTeeVector\",   0x0295B},  // RIGHTWARDS HARPOON WITH BARB UP FROM BAR\n    {\"rightthreetimes\",  0x022CC},  // RIGHT SEMIDIRECT PRODUCT\n    {\"RightTriangle\",    0x022B3},  // CONTAINS AS NORMAL SUBGROUP\n    {\"RightTriangleBar\", 0x029D0},  // VERTICAL BAR BESIDE RIGHT TRIANGLE\n    {\"RightTriangleEqual\", 0x022B5},  // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO\n    {\"RightUpDownVector\", 0x0294F},  // UP BARB RIGHT DOWN BARB RIGHT HARPOON\n    {\"RightUpTeeVector\", 0x0295C},  // UPWARDS HARPOON WITH BARB RIGHT FROM BAR\n    {\"RightUpVector\",    0x021BE},  // UPWARDS HARPOON WITH BARB RIGHTWARDS\n    {\"RightUpVectorBar\", 0x02954},  // UPWARDS HARPOON WITH BARB RIGHT TO BAR\n    {\"RightVector\",      0x021C0},  // RIGHTWARDS HARPOON WITH BARB UPWARDS\n    {\"RightVectorBar\",   0x02953},  // RIGHTWARDS HARPOON WITH BARB UP TO BAR\n    {\"ring\",             0x002DA},  // RING ABOVE\n    {\"risingdotseq\",     0x02253},  // IMAGE OF OR APPROXIMATELY EQUAL TO\n    {\"rlarr\",            0x021C4},  // RIGHTWARDS ARROW OVER LEFTWARDS ARROW\n    {\"rlhar\",            0x021CC},  // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON\n    {\"rlm\",              0x0200F},  // RIGHT-TO-LEFT MARK\n    {\"rmoust\",           0x023B1},  // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION\n    {\"rmoustache\",       0x023B1},  // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION\n    {\"rnmid\",            0x02AEE},  // DOES NOT DIVIDE WITH REVERSED NEGATION SLASH\n    {\"roang\",            0x027ED},  // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET\n    {\"roarr\",            0x021FE},  // RIGHTWARDS OPEN-HEADED ARROW\n    {\"robrk\",            0x027E7},  // MATHEMATICAL RIGHT WHITE SQUARE BRACKET\n    {\"ropar\",            0x02986},  // RIGHT WHITE PARENTHESIS\n    {\"Ropf\",             0x0211D},  // DOUBLE-STRUCK CAPITAL R\n    {\"ropf\",             0x1D563},  // MATHEMATICAL DOUBLE-STRUCK SMALL R\n    {\"roplus\",           0x02A2E},  // PLUS SIGN IN RIGHT HALF CIRCLE\n    {\"rotimes\",          0x02A35},  // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE\n    {\"RoundImplies\",     0x02970},  // RIGHT DOUBLE ARROW WITH ROUNDED HEAD\n    {\"rpar\",             0x00029},  // RIGHT PARENTHESIS\n    {\"rpargt\",           0x02994},  // RIGHT ARC GREATER-THAN BRACKET\n    {\"rppolint\",         0x02A12},  // LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE\n    {\"rrarr\",            0x021C9},  // RIGHTWARDS PAIRED ARROWS\n    {\"Rrightarrow\",      0x021DB},  // RIGHTWARDS TRIPLE ARROW\n    {\"rsaquo\",           0x0203A},  // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK\n    {\"Rscr\",             0x0211B},  // SCRIPT CAPITAL R\n    {\"rscr\",             0x1D4C7},  // MATHEMATICAL SCRIPT SMALL R\n    {\"rsh\",              0x021B1},  // UPWARDS ARROW WITH TIP RIGHTWARDS\n    {\"Rsh\",              0x021B1},  // UPWARDS ARROW WITH TIP RIGHTWARDS\n    {\"rsqb\",             0x0005D},  // RIGHT SQUARE BRACKET\n    {\"rsquo\",            0x02019},  // RIGHT SINGLE QUOTATION MARK\n    {\"rsquor\",           0x02019},  // RIGHT SINGLE QUOTATION MARK\n    {\"rthree\",           0x022CC},  // RIGHT SEMIDIRECT PRODUCT\n    {\"rtimes\",           0x022CA},  // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT\n    {\"rtri\",             0x025B9},  // WHITE RIGHT-POINTING SMALL TRIANGLE\n    {\"rtrie\",            0x022B5},  // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO\n    {\"rtrif\",            0x025B8},  // BLACK RIGHT-POINTING SMALL TRIANGLE\n    {\"rtriltri\",         0x029CE},  // RIGHT TRIANGLE ABOVE LEFT TRIANGLE\n    {\"RuleDelayed\",      0x029F4},  // RULE-DELAYED\n    {\"ruluhar\",          0x02968},  // RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP\n    {\"rx\",               0x0211E},  // PRESCRIPTION TAKE\n];\n\nimmutable NameId[] namesS =\n[\n    {\"Sacute\",           0x0015A},  // LATIN CAPITAL LETTER S WITH ACUTE\n    {\"sacute\",           0x0015B},  // LATIN SMALL LETTER S WITH ACUTE\n    {\"sbquo\",            0x0201A},  // SINGLE LOW-9 QUOTATION MARK\n    {\"sc\",               0x0227B},  // SUCCEEDS\n    {\"Sc\",               0x02ABC},  // DOUBLE SUCCEEDS\n    {\"scap\",             0x02AB8},  // SUCCEEDS ABOVE ALMOST EQUAL TO\n    {\"Scaron\",           0x00160},  // LATIN CAPITAL LETTER S WITH CARON\n    {\"scaron\",           0x00161},  // LATIN SMALL LETTER S WITH CARON\n    {\"sccue\",            0x0227D},  // SUCCEEDS OR EQUAL TO\n    {\"sce\",              0x02AB0},  // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN\n    {\"scE\",              0x02AB4},  // SUCCEEDS ABOVE EQUALS SIGN\n    {\"Scedil\",           0x0015E},  // LATIN CAPITAL LETTER S WITH CEDILLA\n    {\"scedil\",           0x0015F},  // LATIN SMALL LETTER S WITH CEDILLA\n    {\"Scirc\",            0x0015C},  // LATIN CAPITAL LETTER S WITH CIRCUMFLEX\n    {\"scirc\",            0x0015D},  // LATIN SMALL LETTER S WITH CIRCUMFLEX\n    {\"scnap\",            0x02ABA},  // SUCCEEDS ABOVE NOT ALMOST EQUAL TO\n    {\"scnE\",             0x02AB6},  // SUCCEEDS ABOVE NOT EQUAL TO\n    {\"scnsim\",           0x022E9},  // SUCCEEDS BUT NOT EQUIVALENT TO\n    {\"scpolint\",         0x02A13},  // LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE\n    {\"scsim\",            0x0227F},  // SUCCEEDS OR EQUIVALENT TO\n    {\"Scy\",              0x00421},  // CYRILLIC CAPITAL LETTER ES\n    {\"scy\",              0x00441},  // CYRILLIC SMALL LETTER ES\n    {\"sdot\",             0x022C5},  // DOT OPERATOR\n    {\"sdotb\",            0x022A1},  // SQUARED DOT OPERATOR\n    {\"sdote\",            0x02A66},  // EQUALS SIGN WITH DOT BELOW\n    {\"searhk\",           0x02925},  // SOUTH EAST ARROW WITH HOOK\n    {\"searr\",            0x02198},  // SOUTH EAST ARROW\n    {\"seArr\",            0x021D8},  // SOUTH EAST DOUBLE ARROW\n    {\"searrow\",          0x02198},  // SOUTH EAST ARROW\n    {\"sect\",             0x000A7},  // SECTION SIGN\n    {\"semi\",             0x0003B},  // SEMICOLON\n    {\"seswar\",           0x02929},  // SOUTH EAST ARROW AND SOUTH WEST ARROW\n    {\"setminus\",         0x02216},  // SET MINUS\n    {\"setmn\",            0x02216},  // SET MINUS\n    {\"sext\",             0x02736},  // SIX POINTED BLACK STAR\n    {\"sfgr\",             0x003C2},  // GREEK SMALL LETTER FINAL SIGMA\n    {\"Sfr\",              0x1D516},  // MATHEMATICAL FRAKTUR CAPITAL S\n    {\"sfr\",              0x1D530},  // MATHEMATICAL FRAKTUR SMALL S\n    {\"sfrown\",           0x02322},  // FROWN\n    {\"Sgr\",              0x003A3},  // GREEK CAPITAL LETTER SIGMA\n    {\"sgr\",              0x003C3},  // GREEK SMALL LETTER SIGMA\n    {\"sharp\",            0x0266F},  // MUSIC SHARP SIGN\n    {\"SHCHcy\",           0x00429},  // CYRILLIC CAPITAL LETTER SHCHA\n    {\"shchcy\",           0x00449},  // CYRILLIC SMALL LETTER SHCHA\n    {\"SHcy\",             0x00428},  // CYRILLIC CAPITAL LETTER SHA\n    {\"shcy\",             0x00448},  // CYRILLIC SMALL LETTER SHA\n    {\"ShortDownArrow\",   0x02193},  // DOWNWARDS ARROW\n    {\"ShortLeftArrow\",   0x02190},  // LEFTWARDS ARROW\n    {\"shortmid\",         0x02223},  // DIVIDES\n    {\"shortparallel\",    0x02225},  // PARALLEL TO\n    {\"ShortRightArrow\",  0x02192},  // RIGHTWARDS ARROW\n    {\"ShortUpArrow\",     0x02191},  // UPWARDS ARROW\n    {\"shy\",              0x000AD},  // SOFT HYPHEN\n    {\"Sigma\",            0x003A3},  // GREEK CAPITAL LETTER SIGMA\n    {\"sigma\",            0x003C3},  // GREEK SMALL LETTER SIGMA\n    {\"sigmaf\",           0x003C2},  // GREEK SMALL LETTER FINAL SIGMA\n    {\"sigmav\",           0x003C2},  // GREEK SMALL LETTER FINAL SIGMA\n    {\"sim\",              0x0223C},  // TILDE OPERATOR\n    {\"simdot\",           0x02A6A},  // TILDE OPERATOR WITH DOT ABOVE\n    {\"sime\",             0x02243},  // ASYMPTOTICALLY EQUAL TO\n    {\"simeq\",            0x02243},  // ASYMPTOTICALLY EQUAL TO\n    {\"simg\",             0x02A9E},  // SIMILAR OR GREATER-THAN\n    {\"simgE\",            0x02AA0},  // SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN\n    {\"siml\",             0x02A9D},  // SIMILAR OR LESS-THAN\n    {\"simlE\",            0x02A9F},  // SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN\n    {\"simne\",            0x02246},  // APPROXIMATELY BUT NOT ACTUALLY EQUAL TO\n    {\"simplus\",          0x02A24},  // PLUS SIGN WITH TILDE ABOVE\n    {\"simrarr\",          0x02972},  // TILDE OPERATOR ABOVE RIGHTWARDS ARROW\n    {\"slarr\",            0x02190},  // LEFTWARDS ARROW\n    {\"SmallCircle\",      0x02218},  // RING OPERATOR\n    {\"smallsetminus\",    0x02216},  // SET MINUS\n    {\"smashp\",           0x02A33},  // SMASH PRODUCT\n    {\"smeparsl\",         0x029E4},  // EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE\n    {\"smid\",             0x02223},  // DIVIDES\n    {\"smile\",            0x02323},  // SMILE\n    {\"smt\",              0x02AAA},  // SMALLER THAN\n    {\"smte\",             0x02AAC},  // SMALLER THAN OR EQUAL TO\n//  \"smtes\",            0x02AAC;0x0FE00},  // SMALLER THAN OR slanted EQUAL\n    {\"SOFTcy\",           0x0042C},  // CYRILLIC CAPITAL LETTER SOFT SIGN\n    {\"softcy\",           0x0044C},  // CYRILLIC SMALL LETTER SOFT SIGN\n    {\"sol\",              0x0002F},  // SOLIDUS\n    {\"solb\",             0x029C4},  // SQUARED RISING DIAGONAL SLASH\n    {\"solbar\",           0x0233F},  // APL FUNCTIONAL SYMBOL SLASH BAR\n    {\"Sopf\",             0x1D54A},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL S\n    {\"sopf\",             0x1D564},  // MATHEMATICAL DOUBLE-STRUCK SMALL S\n    {\"spades\",           0x02660},  // BLACK SPADE SUIT\n    {\"spadesuit\",        0x02660},  // BLACK SPADE SUIT\n    {\"spar\",             0x02225},  // PARALLEL TO\n    {\"sqcap\",            0x02293},  // SQUARE CAP\n//  \"sqcaps\",           0x02293;0x0FE00},  // SQUARE CAP with serifs\n    {\"sqcup\",            0x02294},  // SQUARE CUP\n//  \"sqcups\",           0x02294;0x0FE00},  // SQUARE CUP with serifs\n    {\"Sqrt\",             0x0221A},  // SQUARE ROOT\n    {\"sqsub\",            0x0228F},  // SQUARE IMAGE OF\n    {\"sqsube\",           0x02291},  // SQUARE IMAGE OF OR EQUAL TO\n    {\"sqsubset\",         0x0228F},  // SQUARE IMAGE OF\n    {\"sqsubseteq\",       0x02291},  // SQUARE IMAGE OF OR EQUAL TO\n    {\"sqsup\",            0x02290},  // SQUARE ORIGINAL OF\n    {\"sqsupe\",           0x02292},  // SQUARE ORIGINAL OF OR EQUAL TO\n    {\"sqsupset\",         0x02290},  // SQUARE ORIGINAL OF\n    {\"sqsupseteq\",       0x02292},  // SQUARE ORIGINAL OF OR EQUAL TO\n    {\"squ\",              0x025A1},  // WHITE SQUARE\n    {\"square\",           0x025A1},  // WHITE SQUARE\n    {\"Square\",           0x025A1},  // WHITE SQUARE\n    {\"SquareIntersection\", 0x02293},  // SQUARE CAP\n    {\"SquareSubset\",     0x0228F},  // SQUARE IMAGE OF\n    {\"SquareSubsetEqual\", 0x02291},  // SQUARE IMAGE OF OR EQUAL TO\n    {\"SquareSuperset\",   0x02290},  // SQUARE ORIGINAL OF\n    {\"SquareSupersetEqual\", 0x02292},  // SQUARE ORIGINAL OF OR EQUAL TO\n    {\"SquareUnion\",      0x02294},  // SQUARE CUP\n    {\"squarf\",           0x025AA},  // BLACK SMALL SQUARE\n    {\"squf\",             0x025AA},  // BLACK SMALL SQUARE\n    {\"srarr\",            0x02192},  // RIGHTWARDS ARROW\n    {\"Sscr\",             0x1D4AE},  // MATHEMATICAL SCRIPT CAPITAL S\n    {\"sscr\",             0x1D4C8},  // MATHEMATICAL SCRIPT SMALL S\n    {\"ssetmn\",           0x02216},  // SET MINUS\n    {\"ssmile\",           0x02323},  // SMILE\n    {\"sstarf\",           0x022C6},  // STAR OPERATOR\n    {\"Star\",             0x022C6},  // STAR OPERATOR\n    {\"star\",             0x02606},  // WHITE STAR\n    {\"starf\",            0x02605},  // BLACK STAR\n    {\"straightepsilon\",  0x003F5},  // GREEK LUNATE EPSILON SYMBOL\n    {\"straightphi\",      0x003D5},  // GREEK PHI SYMBOL\n    {\"strns\",            0x000AF},  // MACRON\n    {\"sub\",              0x02282},  // SUBSET OF\n    {\"Sub\",              0x022D0},  // DOUBLE SUBSET\n    {\"subdot\",           0x02ABD},  // SUBSET WITH DOT\n    {\"sube\",             0x02286},  // SUBSET OF OR EQUAL TO\n    {\"subE\",             0x02AC5},  // SUBSET OF ABOVE EQUALS SIGN\n    {\"subedot\",          0x02AC3},  // SUBSET OF OR EQUAL TO WITH DOT ABOVE\n    {\"submult\",          0x02AC1},  // SUBSET WITH MULTIPLICATION SIGN BELOW\n    {\"subne\",            0x0228A},  // SUBSET OF WITH NOT EQUAL TO\n    {\"subnE\",            0x02ACB},  // SUBSET OF ABOVE NOT EQUAL TO\n    {\"subplus\",          0x02ABF},  // SUBSET WITH PLUS SIGN BELOW\n    {\"subrarr\",          0x02979},  // SUBSET ABOVE RIGHTWARDS ARROW\n    {\"subset\",           0x02282},  // SUBSET OF\n    {\"Subset\",           0x022D0},  // DOUBLE SUBSET\n    {\"subseteq\",         0x02286},  // SUBSET OF OR EQUAL TO\n    {\"subseteqq\",        0x02AC5},  // SUBSET OF ABOVE EQUALS SIGN\n    {\"SubsetEqual\",      0x02286},  // SUBSET OF OR EQUAL TO\n    {\"subsetneq\",        0x0228A},  // SUBSET OF WITH NOT EQUAL TO\n    {\"subsetneqq\",       0x02ACB},  // SUBSET OF ABOVE NOT EQUAL TO\n    {\"subsim\",           0x02AC7},  // SUBSET OF ABOVE TILDE OPERATOR\n    {\"subsub\",           0x02AD5},  // SUBSET ABOVE SUBSET\n    {\"subsup\",           0x02AD3},  // SUBSET ABOVE SUPERSET\n    {\"succ\",             0x0227B},  // SUCCEEDS\n    {\"succapprox\",       0x02AB8},  // SUCCEEDS ABOVE ALMOST EQUAL TO\n    {\"succcurlyeq\",      0x0227D},  // SUCCEEDS OR EQUAL TO\n    {\"Succeeds\",         0x0227B},  // SUCCEEDS\n    {\"SucceedsEqual\",    0x02AB0},  // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN\n    {\"SucceedsSlantEqual\", 0x0227D},  // SUCCEEDS OR EQUAL TO\n    {\"SucceedsTilde\",    0x0227F},  // SUCCEEDS OR EQUIVALENT TO\n    {\"succeq\",           0x02AB0},  // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN\n    {\"succnapprox\",      0x02ABA},  // SUCCEEDS ABOVE NOT ALMOST EQUAL TO\n    {\"succneqq\",         0x02AB6},  // SUCCEEDS ABOVE NOT EQUAL TO\n    {\"succnsim\",         0x022E9},  // SUCCEEDS BUT NOT EQUIVALENT TO\n    {\"succsim\",          0x0227F},  // SUCCEEDS OR EQUIVALENT TO\n    {\"SuchThat\",         0x0220B},  // CONTAINS AS MEMBER\n    {\"sum\",              0x02211},  // N-ARY SUMMATION\n    {\"Sum\",              0x02211},  // N-ARY SUMMATION\n    {\"sung\",             0x0266A},  // EIGHTH NOTE\n    {\"sup\",              0x02283},  // SUPERSET OF\n    {\"Sup\",              0x022D1},  // DOUBLE SUPERSET\n    {\"sup1\",             0x000B9},  // SUPERSCRIPT ONE\n    {\"sup2\",             0x000B2},  // SUPERSCRIPT TWO\n    {\"sup3\",             0x000B3},  // SUPERSCRIPT THREE\n    {\"supdot\",           0x02ABE},  // SUPERSET WITH DOT\n    {\"supdsub\",          0x02AD8},  // SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET\n    {\"supe\",             0x02287},  // SUPERSET OF OR EQUAL TO\n    {\"supE\",             0x02AC6},  // SUPERSET OF ABOVE EQUALS SIGN\n    {\"supedot\",          0x02AC4},  // SUPERSET OF OR EQUAL TO WITH DOT ABOVE\n    {\"Superset\",         0x02283},  // SUPERSET OF\n    {\"SupersetEqual\",    0x02287},  // SUPERSET OF OR EQUAL TO\n    {\"suphsol\",          0x027C9},  // SUPERSET PRECEDING SOLIDUS\n    {\"suphsub\",          0x02AD7},  // SUPERSET BESIDE SUBSET\n    {\"suplarr\",          0x0297B},  // SUPERSET ABOVE LEFTWARDS ARROW\n    {\"supmult\",          0x02AC2},  // SUPERSET WITH MULTIPLICATION SIGN BELOW\n    {\"supne\",            0x0228B},  // SUPERSET OF WITH NOT EQUAL TO\n    {\"supnE\",            0x02ACC},  // SUPERSET OF ABOVE NOT EQUAL TO\n    {\"supplus\",          0x02AC0},  // SUPERSET WITH PLUS SIGN BELOW\n    {\"supset\",           0x02283},  // SUPERSET OF\n    {\"Supset\",           0x022D1},  // DOUBLE SUPERSET\n    {\"supseteq\",         0x02287},  // SUPERSET OF OR EQUAL TO\n    {\"supseteqq\",        0x02AC6},  // SUPERSET OF ABOVE EQUALS SIGN\n    {\"supsetneq\",        0x0228B},  // SUPERSET OF WITH NOT EQUAL TO\n    {\"supsetneqq\",       0x02ACC},  // SUPERSET OF ABOVE NOT EQUAL TO\n    {\"supsim\",           0x02AC8},  // SUPERSET OF ABOVE TILDE OPERATOR\n    {\"supsub\",           0x02AD4},  // SUPERSET ABOVE SUBSET\n    {\"supsup\",           0x02AD6},  // SUPERSET ABOVE SUPERSET\n    {\"swarhk\",           0x02926},  // SOUTH WEST ARROW WITH HOOK\n    {\"swarr\",            0x02199},  // SOUTH WEST ARROW\n    {\"swArr\",            0x021D9},  // SOUTH WEST DOUBLE ARROW\n    {\"swarrow\",          0x02199},  // SOUTH WEST ARROW\n    {\"swnwar\",           0x0292A},  // SOUTH WEST ARROW AND NORTH WEST ARROW\n    {\"szlig\",            0x000DF},  // LATIN SMALL LETTER SHARP S\n];\n\nimmutable NameId[] namesT =\n[\n    {\"Tab\",              0x00009},  // CHARACTER TABULATION\n    {\"target\",           0x02316},  // POSITION INDICATOR\n    {\"Tau\",              0x003A4},  // GREEK CAPITAL LETTER TAU\n    {\"tau\",              0x003C4},  // GREEK SMALL LETTER TAU\n    {\"tbrk\",             0x023B4},  // TOP SQUARE BRACKET\n    {\"Tcaron\",           0x00164},  // LATIN CAPITAL LETTER T WITH CARON\n    {\"tcaron\",           0x00165},  // LATIN SMALL LETTER T WITH CARON\n    {\"Tcedil\",           0x00162},  // LATIN CAPITAL LETTER T WITH CEDILLA\n    {\"tcedil\",           0x00163},  // LATIN SMALL LETTER T WITH CEDILLA\n    {\"Tcy\",              0x00422},  // CYRILLIC CAPITAL LETTER TE\n    {\"tcy\",              0x00442},  // CYRILLIC SMALL LETTER TE\n    {\"tdot\",             0x020DB},  // COMBINING THREE DOTS ABOVE\n    {\"telrec\",           0x02315},  // TELEPHONE RECORDER\n    {\"Tfr\",              0x1D517},  // MATHEMATICAL FRAKTUR CAPITAL T\n    {\"tfr\",              0x1D531},  // MATHEMATICAL FRAKTUR SMALL T\n    {\"Tgr\",              0x003A4},  // GREEK CAPITAL LETTER TAU\n    {\"tgr\",              0x003C4},  // GREEK SMALL LETTER TAU\n    {\"there4\",           0x02234},  // THEREFORE\n    {\"therefore\",        0x02234},  // THEREFORE\n    {\"Therefore\",        0x02234},  // THEREFORE\n    {\"Theta\",            0x00398},  // GREEK CAPITAL LETTER THETA\n    {\"theta\",            0x003B8},  // GREEK SMALL LETTER THETA\n    {\"thetasym\",         0x003D1},  // GREEK THETA SYMBOL\n    {\"thetav\",           0x003D1},  // GREEK THETA SYMBOL\n    {\"THgr\",             0x00398},  // GREEK CAPITAL LETTER THETA\n    {\"thgr\",             0x003B8},  // GREEK SMALL LETTER THETA\n    {\"thickapprox\",      0x02248},  // ALMOST EQUAL TO\n    {\"thicksim\",         0x0223C},  // TILDE OPERATOR\n//  \"ThickSpace\",       0x0205F;0x0200A},  // space of width 5/18 em\n    {\"thinsp\",           0x02009},  // THIN SPACE\n    {\"ThinSpace\",        0x02009},  // THIN SPACE\n    {\"thkap\",            0x02248},  // ALMOST EQUAL TO\n    {\"thksim\",           0x0223C},  // TILDE OPERATOR\n    {\"THORN\",            0x000DE},  // LATIN CAPITAL LETTER THORN\n    {\"thorn\",            0x000FE},  // LATIN SMALL LETTER THORN\n    {\"tilde\",            0x002DC},  // SMALL TILDE\n    {\"Tilde\",            0x0223C},  // TILDE OPERATOR\n    {\"TildeEqual\",       0x02243},  // ASYMPTOTICALLY EQUAL TO\n    {\"TildeFullEqual\",   0x02245},  // APPROXIMATELY EQUAL TO\n    {\"TildeTilde\",       0x02248},  // ALMOST EQUAL TO\n    {\"times\",            0x000D7},  // MULTIPLICATION SIGN\n    {\"timesb\",           0x022A0},  // SQUARED TIMES\n    {\"timesbar\",         0x02A31},  // MULTIPLICATION SIGN WITH UNDERBAR\n    {\"timesd\",           0x02A30},  // MULTIPLICATION SIGN WITH DOT ABOVE\n    {\"tint\",             0x0222D},  // TRIPLE INTEGRAL\n    {\"toea\",             0x02928},  // NORTH EAST ARROW AND SOUTH EAST ARROW\n    {\"top\",              0x022A4},  // DOWN TACK\n    {\"topbot\",           0x02336},  // APL FUNCTIONAL SYMBOL I-BEAM\n    {\"topcir\",           0x02AF1},  // DOWN TACK WITH CIRCLE BELOW\n    {\"Topf\",             0x1D54B},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL T\n    {\"topf\",             0x1D565},  // MATHEMATICAL DOUBLE-STRUCK SMALL T\n    {\"topfork\",          0x02ADA},  // PITCHFORK WITH TEE TOP\n    {\"tosa\",             0x02929},  // SOUTH EAST ARROW AND SOUTH WEST ARROW\n    {\"tprime\",           0x02034},  // TRIPLE PRIME\n    {\"trade\",            0x02122},  // TRADE MARK SIGN\n    {\"TRADE\",            0x02122},  // TRADE MARK SIGN\n    {\"triangle\",         0x025B5},  // WHITE UP-POINTING SMALL TRIANGLE\n    {\"triangledown\",     0x025BF},  // WHITE DOWN-POINTING SMALL TRIANGLE\n    {\"triangleleft\",     0x025C3},  // WHITE LEFT-POINTING SMALL TRIANGLE\n    {\"trianglelefteq\",   0x022B4},  // NORMAL SUBGROUP OF OR EQUAL TO\n    {\"triangleq\",        0x0225C},  // DELTA EQUAL TO\n    {\"triangleright\",    0x025B9},  // WHITE RIGHT-POINTING SMALL TRIANGLE\n    {\"trianglerighteq\",  0x022B5},  // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO\n    {\"tridot\",           0x025EC},  // WHITE UP-POINTING TRIANGLE WITH DOT\n    {\"trie\",             0x0225C},  // DELTA EQUAL TO\n    {\"triminus\",         0x02A3A},  // MINUS SIGN IN TRIANGLE\n    {\"TripleDot\",        0x020DB},  // COMBINING THREE DOTS ABOVE\n    {\"triplus\",          0x02A39},  // PLUS SIGN IN TRIANGLE\n    {\"trisb\",            0x029CD},  // TRIANGLE WITH SERIFS AT BOTTOM\n    {\"tritime\",          0x02A3B},  // MULTIPLICATION SIGN IN TRIANGLE\n    {\"trpezium\",         0x023E2},  // WHITE TRAPEZIUM\n    {\"Tscr\",             0x1D4AF},  // MATHEMATICAL SCRIPT CAPITAL T\n    {\"tscr\",             0x1D4C9},  // MATHEMATICAL SCRIPT SMALL T\n    {\"TScy\",             0x00426},  // CYRILLIC CAPITAL LETTER TSE\n    {\"tscy\",             0x00446},  // CYRILLIC SMALL LETTER TSE\n    {\"TSHcy\",            0x0040B},  // CYRILLIC CAPITAL LETTER TSHE\n    {\"tshcy\",            0x0045B},  // CYRILLIC SMALL LETTER TSHE\n    {\"Tstrok\",           0x00166},  // LATIN CAPITAL LETTER T WITH STROKE\n    {\"tstrok\",           0x00167},  // LATIN SMALL LETTER T WITH STROKE\n    {\"twixt\",            0x0226C},  // BETWEEN\n    {\"twoheadleftarrow\", 0x0219E},  // LEFTWARDS TWO HEADED ARROW\n    {\"twoheadrightarrow\", 0x021A0},  // RIGHTWARDS TWO HEADED ARROW\n];\n\nimmutable NameId[] namesU =\n[\n    {\"Uacgr\",            0x0038E},  // GREEK CAPITAL LETTER UPSILON WITH TONOS\n    {\"uacgr\",            0x003CD},  // GREEK SMALL LETTER UPSILON WITH TONOS\n    {\"Uacute\",           0x000DA},  // LATIN CAPITAL LETTER U WITH ACUTE\n    {\"uacute\",           0x000FA},  // LATIN SMALL LETTER U WITH ACUTE\n    {\"uarr\",             0x02191},  // UPWARDS ARROW\n    {\"Uarr\",             0x0219F},  // UPWARDS TWO HEADED ARROW\n    {\"uArr\",             0x021D1},  // UPWARDS DOUBLE ARROW\n    {\"Uarrocir\",         0x02949},  // UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE\n    {\"Ubrcy\",            0x0040E},  // CYRILLIC CAPITAL LETTER SHORT U\n    {\"ubrcy\",            0x0045E},  // CYRILLIC SMALL LETTER SHORT U\n    {\"Ubreve\",           0x0016C},  // LATIN CAPITAL LETTER U WITH BREVE\n    {\"ubreve\",           0x0016D},  // LATIN SMALL LETTER U WITH BREVE\n    {\"Ucirc\",            0x000DB},  // LATIN CAPITAL LETTER U WITH CIRCUMFLEX\n    {\"ucirc\",            0x000FB},  // LATIN SMALL LETTER U WITH CIRCUMFLEX\n    {\"Ucy\",              0x00423},  // CYRILLIC CAPITAL LETTER U\n    {\"ucy\",              0x00443},  // CYRILLIC SMALL LETTER U\n    {\"udarr\",            0x021C5},  // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW\n    {\"Udblac\",           0x00170},  // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE\n    {\"udblac\",           0x00171},  // LATIN SMALL LETTER U WITH DOUBLE ACUTE\n    {\"udhar\",            0x0296E},  // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT\n    {\"udiagr\",           0x003B0},  // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS\n    {\"Udigr\",            0x003AB},  // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA\n    {\"udigr\",            0x003CB},  // GREEK SMALL LETTER UPSILON WITH DIALYTIKA\n    {\"ufisht\",           0x0297E},  // UP FISH TAIL\n    {\"Ufr\",              0x1D518},  // MATHEMATICAL FRAKTUR CAPITAL U\n    {\"ufr\",              0x1D532},  // MATHEMATICAL FRAKTUR SMALL U\n    {\"Ugr\",              0x003A5},  // GREEK CAPITAL LETTER UPSILON\n    {\"ugr\",              0x003C5},  // GREEK SMALL LETTER UPSILON\n    {\"Ugrave\",           0x000D9},  // LATIN CAPITAL LETTER U WITH GRAVE\n    {\"ugrave\",           0x000F9},  // LATIN SMALL LETTER U WITH GRAVE\n    {\"uHar\",             0x02963},  // UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT\n    {\"uharl\",            0x021BF},  // UPWARDS HARPOON WITH BARB LEFTWARDS\n    {\"uharr\",            0x021BE},  // UPWARDS HARPOON WITH BARB RIGHTWARDS\n    {\"uhblk\",            0x02580},  // UPPER HALF BLOCK\n    {\"ulcorn\",           0x0231C},  // TOP LEFT CORNER\n    {\"ulcorner\",         0x0231C},  // TOP LEFT CORNER\n    {\"ulcrop\",           0x0230F},  // TOP LEFT CROP\n    {\"ultri\",            0x025F8},  // UPPER LEFT TRIANGLE\n    {\"Umacr\",            0x0016A},  // LATIN CAPITAL LETTER U WITH MACRON\n    {\"umacr\",            0x0016B},  // LATIN SMALL LETTER U WITH MACRON\n    {\"uml\",              0x000A8},  // DIAERESIS\n    {\"UnderBar\",         0x0005F},  // LOW LINE\n    {\"UnderBrace\",       0x023DF},  // BOTTOM CURLY BRACKET\n    {\"UnderBracket\",     0x023B5},  // BOTTOM SQUARE BRACKET\n    {\"UnderParenthesis\", 0x023DD},  // BOTTOM PARENTHESIS\n    {\"Union\",            0x022C3},  // N-ARY UNION\n    {\"UnionPlus\",        0x0228E},  // MULTISET UNION\n    {\"Uogon\",            0x00172},  // LATIN CAPITAL LETTER U WITH OGONEK\n    {\"uogon\",            0x00173},  // LATIN SMALL LETTER U WITH OGONEK\n    {\"Uopf\",             0x1D54C},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL U\n    {\"uopf\",             0x1D566},  // MATHEMATICAL DOUBLE-STRUCK SMALL U\n    {\"uparrow\",          0x02191},  // UPWARDS ARROW\n    {\"UpArrow\",          0x02191},  // UPWARDS ARROW\n    {\"Uparrow\",          0x021D1},  // UPWARDS DOUBLE ARROW\n    {\"UpArrowBar\",       0x02912},  // UPWARDS ARROW TO BAR\n    {\"UpArrowDownArrow\", 0x021C5},  // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW\n    {\"updownarrow\",      0x02195},  // UP DOWN ARROW\n    {\"UpDownArrow\",      0x02195},  // UP DOWN ARROW\n    {\"Updownarrow\",      0x021D5},  // UP DOWN DOUBLE ARROW\n    {\"UpEquilibrium\",    0x0296E},  // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT\n    {\"upharpoonleft\",    0x021BF},  // UPWARDS HARPOON WITH BARB LEFTWARDS\n    {\"upharpoonright\",   0x021BE},  // UPWARDS HARPOON WITH BARB RIGHTWARDS\n    {\"uplus\",            0x0228E},  // MULTISET UNION\n    {\"UpperLeftArrow\",   0x02196},  // NORTH WEST ARROW\n    {\"UpperRightArrow\",  0x02197},  // NORTH EAST ARROW\n    {\"upsi\",             0x003C5},  // GREEK SMALL LETTER UPSILON\n    {\"Upsi\",             0x003D2},  // GREEK UPSILON WITH HOOK SYMBOL\n    {\"upsih\",            0x003D2},  // GREEK UPSILON WITH HOOK SYMBOL\n    {\"Upsilon\",          0x003A5},  // GREEK CAPITAL LETTER UPSILON\n    {\"upsilon\",          0x003C5},  // GREEK SMALL LETTER UPSILON\n    {\"UpTee\",            0x022A5},  // UP TACK\n    {\"UpTeeArrow\",       0x021A5},  // UPWARDS ARROW FROM BAR\n    {\"upuparrows\",       0x021C8},  // UPWARDS PAIRED ARROWS\n    {\"urcorn\",           0x0231D},  // TOP RIGHT CORNER\n    {\"urcorner\",         0x0231D},  // TOP RIGHT CORNER\n    {\"urcrop\",           0x0230E},  // TOP RIGHT CROP\n    {\"Uring\",            0x0016E},  // LATIN CAPITAL LETTER U WITH RING ABOVE\n    {\"uring\",            0x0016F},  // LATIN SMALL LETTER U WITH RING ABOVE\n    {\"urtri\",            0x025F9},  // UPPER RIGHT TRIANGLE\n    {\"Uscr\",             0x1D4B0},  // MATHEMATICAL SCRIPT CAPITAL U\n    {\"uscr\",             0x1D4CA},  // MATHEMATICAL SCRIPT SMALL U\n    {\"utdot\",            0x022F0},  // UP RIGHT DIAGONAL ELLIPSIS\n    {\"Utilde\",           0x00168},  // LATIN CAPITAL LETTER U WITH TILDE\n    {\"utilde\",           0x00169},  // LATIN SMALL LETTER U WITH TILDE\n    {\"utri\",             0x025B5},  // WHITE UP-POINTING SMALL TRIANGLE\n    {\"utrif\",            0x025B4},  // BLACK UP-POINTING SMALL TRIANGLE\n    {\"uuarr\",            0x021C8},  // UPWARDS PAIRED ARROWS\n    {\"Uuml\",             0x000DC},  // LATIN CAPITAL LETTER U WITH DIAERESIS\n    {\"uuml\",             0x000FC},  // LATIN SMALL LETTER U WITH DIAERESIS\n    {\"uwangle\",          0x029A7},  // OBLIQUE ANGLE OPENING DOWN\n];\n\nimmutable NameId[] namesV =\n[\n    {\"vangrt\",           0x0299C},  // RIGHT ANGLE VARIANT WITH SQUARE\n    {\"varepsilon\",       0x003F5},  // GREEK LUNATE EPSILON SYMBOL\n    {\"varkappa\",         0x003F0},  // GREEK KAPPA SYMBOL\n    {\"varnothing\",       0x02205},  // EMPTY SET\n    {\"varphi\",           0x003D5},  // GREEK PHI SYMBOL\n    {\"varpi\",            0x003D6},  // GREEK PI SYMBOL\n    {\"varpropto\",        0x0221D},  // PROPORTIONAL TO\n    {\"varr\",             0x02195},  // UP DOWN ARROW\n    {\"vArr\",             0x021D5},  // UP DOWN DOUBLE ARROW\n    {\"varrho\",           0x003F1},  // GREEK RHO SYMBOL\n    {\"varsigma\",         0x003C2},  // GREEK SMALL LETTER FINAL SIGMA\n//  \"varsubsetneq\",     0x0228A;0x0FE00},  // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members\n//  \"varsubsetneqq\",    0x02ACB;0x0FE00},  // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members\n//  \"varsupsetneq\",     0x0228B;0x0FE00},  // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members\n//  \"varsupsetneqq\",    0x02ACC;0x0FE00},  // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members\n    {\"vartheta\",         0x003D1},  // GREEK THETA SYMBOL\n    {\"vartriangleleft\",  0x022B2},  // NORMAL SUBGROUP OF\n    {\"vartriangleright\", 0x022B3},  // CONTAINS AS NORMAL SUBGROUP\n    {\"vBar\",             0x02AE8},  // SHORT UP TACK WITH UNDERBAR\n    {\"Vbar\",             0x02AEB},  // DOUBLE UP TACK\n    {\"vBarv\",            0x02AE9},  // SHORT UP TACK ABOVE SHORT DOWN TACK\n    {\"Vcy\",              0x00412},  // CYRILLIC CAPITAL LETTER VE\n    {\"vcy\",              0x00432},  // CYRILLIC SMALL LETTER VE\n    {\"vdash\",            0x022A2},  // RIGHT TACK\n    {\"vDash\",            0x022A8},  // TRUE\n    {\"Vdash\",            0x022A9},  // FORCES\n    {\"VDash\",            0x022AB},  // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE\n    {\"Vdashl\",           0x02AE6},  // LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL\n    {\"vee\",              0x02228},  // LOGICAL OR\n    {\"Vee\",              0x022C1},  // N-ARY LOGICAL OR\n    {\"veebar\",           0x022BB},  // XOR\n    {\"veeeq\",            0x0225A},  // EQUIANGULAR TO\n    {\"vellip\",           0x022EE},  // VERTICAL ELLIPSIS\n    {\"verbar\",           0x0007C},  // VERTICAL LINE\n    {\"Verbar\",           0x02017},  // DOUBLE VERTICAL LINE\n    {\"vert\",             0x0007C},  // VERTICAL LINE\n    {\"Vert\",             0x02017},  // DOUBLE VERTICAL LINE\n    {\"VerticalBar\",      0x02223},  // DIVIDES\n    {\"VerticalLine\",     0x0007C},  // VERTICAL LINE\n    {\"VerticalSeparator\", 0x02758},  // LIGHT VERTICAL BAR\n    {\"VerticalTilde\",    0x02240},  // WREATH PRODUCT\n    {\"VeryThinSpace\",    0x0200A},  // HAIR SPACE\n    {\"Vfr\",              0x1D519},  // MATHEMATICAL FRAKTUR CAPITAL V\n    {\"vfr\",              0x1D533},  // MATHEMATICAL FRAKTUR SMALL V\n    {\"vltri\",            0x022B2},  // NORMAL SUBGROUP OF\n//  \"vnsub\",            0x02282;0x020D2},  // SUBSET OF with vertical line\n//  \"vnsup\",            0x02283;0x020D2},  // SUPERSET OF with vertical line\n    {\"Vopf\",             0x1D54D},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL V\n    {\"vopf\",             0x1D567},  // MATHEMATICAL DOUBLE-STRUCK SMALL V\n    {\"vprop\",            0x0221D},  // PROPORTIONAL TO\n    {\"vrtri\",            0x022B3},  // CONTAINS AS NORMAL SUBGROUP\n    {\"Vscr\",             0x1D4B1},  // MATHEMATICAL SCRIPT CAPITAL V\n    {\"vscr\",             0x1D4CB},  // MATHEMATICAL SCRIPT SMALL V\n//  \"vsubne\",           0x0228A;0x0FE00},  // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members\n//  \"vsubnE\",           0x02ACB;0x0FE00},  // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members\n//  \"vsupne\",           0x0228B;0x0FE00},  // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members\n//  \"vsupnE\",           0x02ACC;0x0FE00},  // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members\n    {\"Vvdash\",           0x022AA},  // TRIPLE VERTICAL BAR RIGHT TURNSTILE\n    {\"vzigzag\",          0x0299A},  // VERTICAL ZIGZAG LINE\n];\n\nimmutable NameId[] namesW =\n[\n    {\"Wcirc\",            0x00174},  // LATIN CAPITAL LETTER W WITH CIRCUMFLEX\n    {\"wcirc\",            0x00175},  // LATIN SMALL LETTER W WITH CIRCUMFLEX\n    {\"wedbar\",           0x02A5F},  // LOGICAL AND WITH UNDERBAR\n    {\"wedge\",            0x02227},  // LOGICAL AND\n    {\"Wedge\",            0x022C0},  // N-ARY LOGICAL AND\n    {\"wedgeq\",           0x02259},  // ESTIMATES\n    {\"weierp\",           0x02118},  // SCRIPT CAPITAL P\n    {\"Wfr\",              0x1D51A},  // MATHEMATICAL FRAKTUR CAPITAL W\n    {\"wfr\",              0x1D534},  // MATHEMATICAL FRAKTUR SMALL W\n    {\"Wopf\",             0x1D54E},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL W\n    {\"wopf\",             0x1D568},  // MATHEMATICAL DOUBLE-STRUCK SMALL W\n    {\"wp\",               0x02118},  // SCRIPT CAPITAL P\n    {\"wr\",               0x02240},  // WREATH PRODUCT\n    {\"wreath\",           0x02240},  // WREATH PRODUCT\n    {\"Wscr\",             0x1D4B2},  // MATHEMATICAL SCRIPT CAPITAL W\n    {\"wscr\",             0x1D4CC},  // MATHEMATICAL SCRIPT SMALL W\n];\n\nimmutable NameId[] namesX =\n[\n    {\"xcap\",             0x022C2},  // N-ARY INTERSECTION\n    {\"xcirc\",            0x025EF},  // LARGE CIRCLE\n    {\"xcup\",             0x022C3},  // N-ARY UNION\n    {\"xdtri\",            0x025BD},  // WHITE DOWN-POINTING TRIANGLE\n    {\"Xfr\",              0x1D51B},  // MATHEMATICAL FRAKTUR CAPITAL X\n    {\"xfr\",              0x1D535},  // MATHEMATICAL FRAKTUR SMALL X\n    {\"Xgr\",              0x0039E},  // GREEK CAPITAL LETTER XI\n    {\"xgr\",              0x003BE},  // GREEK SMALL LETTER XI\n    {\"xharr\",            0x027F7},  // LONG LEFT RIGHT ARROW\n    {\"xhArr\",            0x027FA},  // LONG LEFT RIGHT DOUBLE ARROW\n    {\"Xi\",               0x0039E},  // GREEK CAPITAL LETTER XI\n    {\"xi\",               0x003BE},  // GREEK SMALL LETTER XI\n    {\"xlarr\",            0x027F5},  // LONG LEFTWARDS ARROW\n    {\"xlArr\",            0x027F8},  // LONG LEFTWARDS DOUBLE ARROW\n    {\"xmap\",             0x027FC},  // LONG RIGHTWARDS ARROW FROM BAR\n    {\"xnis\",             0x022FB},  // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE\n    {\"xodot\",            0x02A00},  // N-ARY CIRCLED DOT OPERATOR\n    {\"Xopf\",             0x1D54F},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL X\n    {\"xopf\",             0x1D569},  // MATHEMATICAL DOUBLE-STRUCK SMALL X\n    {\"xoplus\",           0x02A01},  // N-ARY CIRCLED PLUS OPERATOR\n    {\"xotime\",           0x02A02},  // N-ARY CIRCLED TIMES OPERATOR\n    {\"xrarr\",            0x027F6},  // LONG RIGHTWARDS ARROW\n    {\"xrArr\",            0x027F9},  // LONG RIGHTWARDS DOUBLE ARROW\n    {\"Xscr\",             0x1D4B3},  // MATHEMATICAL SCRIPT CAPITAL X\n    {\"xscr\",             0x1D4CD},  // MATHEMATICAL SCRIPT SMALL X\n    {\"xsqcup\",           0x02A06},  // N-ARY SQUARE UNION OPERATOR\n    {\"xuplus\",           0x02A04},  // N-ARY UNION OPERATOR WITH PLUS\n    {\"xutri\",            0x025B3},  // WHITE UP-POINTING TRIANGLE\n    {\"xvee\",             0x022C1},  // N-ARY LOGICAL OR\n    {\"xwedge\",           0x022C0},  // N-ARY LOGICAL AND\n];\n\nimmutable NameId[] namesY =\n[\n    {\"Yacute\",           0x000DD},  // LATIN CAPITAL LETTER Y WITH ACUTE\n    {\"yacute\",           0x000FD},  // LATIN SMALL LETTER Y WITH ACUTE\n    {\"YAcy\",             0x0042F},  // CYRILLIC CAPITAL LETTER YA\n    {\"yacy\",             0x0044F},  // CYRILLIC SMALL LETTER YA\n    {\"Ycirc\",            0x00176},  // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX\n    {\"ycirc\",            0x00177},  // LATIN SMALL LETTER Y WITH CIRCUMFLEX\n    {\"Ycy\",              0x0042B},  // CYRILLIC CAPITAL LETTER YERU\n    {\"ycy\",              0x0044B},  // CYRILLIC SMALL LETTER YERU\n    {\"yen\",              0x000A5},  // YEN SIGN\n    {\"Yfr\",              0x1D51C},  // MATHEMATICAL FRAKTUR CAPITAL Y\n    {\"yfr\",              0x1D536},  // MATHEMATICAL FRAKTUR SMALL Y\n    {\"YIcy\",             0x00407},  // CYRILLIC CAPITAL LETTER YI\n    {\"yicy\",             0x00457},  // CYRILLIC SMALL LETTER YI\n    {\"Yopf\",             0x1D550},  // MATHEMATICAL DOUBLE-STRUCK CAPITAL Y\n    {\"yopf\",             0x1D56A},  // MATHEMATICAL DOUBLE-STRUCK SMALL Y\n    {\"Yscr\",             0x1D4B4},  // MATHEMATICAL SCRIPT CAPITAL Y\n    {\"yscr\",             0x1D4CE},  // MATHEMATICAL SCRIPT SMALL Y\n    {\"YUcy\",             0x0042E},  // CYRILLIC CAPITAL LETTER YU\n    {\"yucy\",             0x0044E},  // CYRILLIC SMALL LETTER YU\n    {\"yuml\",             0x000FF},  // LATIN SMALL LETTER Y WITH DIAERESIS\n    {\"Yuml\",             0x00178},  // LATIN CAPITAL LETTER Y WITH DIAERESIS\n];\n\nimmutable NameId[] namesZ =\n[\n    {\"Zacute\",           0x00179},  // LATIN CAPITAL LETTER Z WITH ACUTE\n    {\"zacute\",           0x0017A},  // LATIN SMALL LETTER Z WITH ACUTE\n    {\"Zcaron\",           0x0017D},  // LATIN CAPITAL LETTER Z WITH CARON\n    {\"zcaron\",           0x0017E},  // LATIN SMALL LETTER Z WITH CARON\n    {\"Zcy\",              0x00417},  // CYRILLIC CAPITAL LETTER ZE\n    {\"zcy\",              0x00437},  // CYRILLIC SMALL LETTER ZE\n    {\"Zdot\",             0x0017B},  // LATIN CAPITAL LETTER Z WITH DOT ABOVE\n    {\"zdot\",             0x0017C},  // LATIN SMALL LETTER Z WITH DOT ABOVE\n    {\"zeetrf\",           0x02128},  // BLACK-LETTER CAPITAL Z\n    {\"ZeroWidthSpace\",   0x0200B},  // ZERO WIDTH SPACE\n    {\"Zeta\",             0x00396},  // GREEK CAPITAL LETTER ZETA\n    {\"zeta\",             0x003B6},  // GREEK SMALL LETTER ZETA\n    {\"Zfr\",              0x02128},  // BLACK-LETTER CAPITAL Z\n    {\"zfr\",              0x1D537},  // MATHEMATICAL FRAKTUR SMALL Z\n    {\"Zgr\",              0x00396},  // GREEK CAPITAL LETTER ZETA\n    {\"zgr\",              0x003B6},  // GREEK SMALL LETTER ZETA\n    {\"ZHcy\",             0x00416},  // CYRILLIC CAPITAL LETTER ZHE\n    {\"zhcy\",             0x00436},  // CYRILLIC SMALL LETTER ZHE\n    {\"zigrarr\",          0x021DD},  // RIGHTWARDS SQUIGGLE ARROW\n    {\"Zopf\",             0x02124},  // DOUBLE-STRUCK CAPITAL Z\n    {\"zopf\",             0x1D56B},  // MATHEMATICAL DOUBLE-STRUCK SMALL Z\n    {\"Zscr\",             0x1D4B5},  // MATHEMATICAL SCRIPT CAPITAL Z\n    {\"zscr\",             0x1D4CF},  // MATHEMATICAL SCRIPT SMALL Z\n    {\"zwj\",              0x0200D},  // ZERO WIDTH JOINER\n    {\"zwnj\",             0x0200C},  // ZERO WIDTH NON-JOINER\n];\n\n// @todo@ order namesTable and names? by frequency\nimmutable NameId[][] namesTable =\n[\n    namesA, namesB, namesC, namesD, namesE, namesF, namesG, namesH, namesI,\n    namesJ, namesK, namesL, namesM, namesN, namesO, namesP, namesQ, namesR,\n    namesS, namesT, namesU, namesV, namesW, namesX, namesY, namesZ\n];\n\npublic int HtmlNamedEntity(const(char)* p, size_t length)\n{\n    int tableIndex = tolower(*p) - 'a';\n    if (tableIndex >= 0 && tableIndex < 26)\n    {\n        foreach (entity; namesTable[tableIndex])\n        {\n            if (entity.name == p[0 .. length])\n                return entity.value;\n        }\n    }\n    return -1;\n}\n"
  },
  {
    "path": "gcc/d/dmd/enum.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/enum.h\n */\n\n#pragma once\n\n#include \"dsymbol.h\"\n#include \"declaration.h\"\n\nclass Identifier;\nclass Type;\nclass Expression;\n\nclass EnumDeclaration : public ScopeDsymbol\n{\npublic:\n    /* The separate, and distinct, cases are:\n     *  1. enum { ... }\n     *  2. enum : memtype { ... }\n     *  3. enum id { ... }\n     *  4. enum id : memtype { ... }\n     *  5. enum id : memtype;\n     *  6. enum id;\n     */\n    Type *type;                 // the TypeEnum\n    Type *memtype;              // type of the members\n    Prot protection;\n\n    Expression *maxval;\n    Expression *minval;\n    Expression *defaultval;     // default initializer\n\n    bool isdeprecated;\n    bool added;\n    int inuse;\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    void addMember(Scope *sc, ScopeDsymbol *sds);\n    void setScope(Scope *sc);\n    bool oneMember(Dsymbol **ps, Identifier *ident);\n    Type *getType();\n    const char *kind() const;\n    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);\n    bool isDeprecated();                // is Dsymbol deprecated?\n    Prot prot();\n    Expression *getMaxMinValue(const Loc &loc, Identifier *id);\n    bool isSpecial() const;\n    Expression *getDefaultValue(const Loc &loc);\n    Type *getMemtype(const Loc &loc);\n\n    EnumDeclaration *isEnumDeclaration() { return this; }\n\n    Symbol *sinit;\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n\nclass EnumMember : public VarDeclaration\n{\npublic:\n    /* Can take the following forms:\n     *  1. id\n     *  2. id = value\n     *  3. type id = value\n     */\n    Expression *&value();\n\n    // A cast() is injected to 'value' after semantic(),\n    // but 'origValue' will preserve the original value,\n    // or previous value + 1 if none was specified.\n    Expression *origValue;\n    Type *origType;\n\n    EnumDeclaration *ed;\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    const char *kind() const;\n    Expression *getVarExp(const Loc &loc, Scope *sc);\n\n    EnumMember *isEnumMember() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n"
  },
  {
    "path": "gcc/d/dmd/errors.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/errors.d, _errors.d)\n * Documentation:  https://dlang.org/phobos/dmd_errors.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/errors.d\n */\n\nmodule dmd.errors;\n\nimport core.stdc.stdarg;\nimport dmd.globals;\n\n/**\n * Print an error message, increasing the global error count.\n * Params:\n *      loc    = location of error\n *      format = printf-style format specification\n *      ...    = printf-style variadic arguments\n */\nextern (C++) void error(const ref Loc loc, const(char)* format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    verror(loc, format, ap);\n    va_end(ap);\n}\n\n/**\n * Same as above, but allows Loc() literals to be passed.\n * Params:\n *      loc    = location of error\n *      format = printf-style format specification\n *      ...    = printf-style variadic arguments\n */\nextern (D) void error(Loc loc, const(char)* format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    verror(loc, format, ap);\n    va_end(ap);\n}\n\n/**\n * Same as above, but takes a filename and line information arguments as separate parameters.\n * Params:\n *      filename = source file of error\n *      linnum   = line in the source file\n *      charnum  = column number on the line\n *      format   = printf-style format specification\n *      ...      = printf-style variadic arguments\n */\nextern (C++) void error(const(char)* filename, uint linnum, uint charnum, const(char)* format, ...)\n{\n    const loc = Loc(filename, linnum, charnum);\n    va_list ap;\n    va_start(ap, format);\n    verror(loc, format, ap);\n    va_end(ap);\n}\n\n/**\n * Print additional details about an error message.\n * Doesn't increase the error count or print an additional error prefix.\n * Params:\n *      loc    = location of error\n *      format = printf-style format specification\n *      ...    = printf-style variadic arguments\n */\nextern (C++) void errorSupplemental(const ref Loc loc, const(char)* format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    verrorSupplemental(loc, format, ap);\n    va_end(ap);\n}\n\n/**\n * Print a warning message, increasing the global warning count.\n * Params:\n *      loc    = location of warning\n *      format = printf-style format specification\n *      ...    = printf-style variadic arguments\n */\nextern (C++) void warning(const ref Loc loc, const(char)* format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    vwarning(loc, format, ap);\n    va_end(ap);\n}\n\n/**\n * Print additional details about a warning message.\n * Doesn't increase the warning count or print an additional warning prefix.\n * Params:\n *      loc    = location of warning\n *      format = printf-style format specification\n *      ...    = printf-style variadic arguments\n */\nextern (C++) void warningSupplemental(const ref Loc loc, const(char)* format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    vwarningSupplemental(loc, format, ap);\n    va_end(ap);\n}\n\n/**\n * Print a deprecation message, may increase the global warning or error count\n * depending on whether deprecations are ignored.\n * Params:\n *      loc    = location of deprecation\n *      format = printf-style format specification\n *      ...    = printf-style variadic arguments\n */\nextern (C++) void deprecation(const ref Loc loc, const(char)* format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    vdeprecation(loc, format, ap);\n    va_end(ap);\n}\n\n/**\n * Print additional details about a deprecation message.\n * Doesn't increase the error count, or print an additional deprecation prefix.\n * Params:\n *      loc    = location of deprecation\n *      format = printf-style format specification\n *      ...    = printf-style variadic arguments\n */\nextern (C++) void deprecationSupplemental(const ref Loc loc, const(char)* format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    vdeprecationSupplemental(loc, format, ap);\n    va_end(ap);\n}\n\n/**\n * Print a verbose message.\n * Doesn't prefix or highlight messages.\n * Params:\n *      loc    = location of message\n *      format = printf-style format specification\n *      ...    = printf-style variadic arguments\n */\nextern (C++) void message(const ref Loc loc, const(char)* format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    vmessage(loc, format, ap);\n    va_end(ap);\n}\n\n/**\n * Same as above, but doesn't take a location argument.\n * Params:\n *      format = printf-style format specification\n *      ...    = printf-style variadic arguments\n */\nextern (C++) void message(const(char)* format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    vmessage(Loc.initial, format, ap);\n    va_end(ap);\n}\n\n/**\n * Same as $(D error), but takes a va_list parameter, and optionally additional message prefixes.\n * Params:\n *      loc    = location of error\n *      format = printf-style format specification\n *      ap     = printf-style variadic arguments\n *      p1     = additional message prefix\n *      p2     = additional message prefix\n *      header = title of error message\n */\nextern (C++) void verror(const ref Loc loc, const(char)* format, va_list ap, const(char)* p1 = null, const(char)* p2 = null, const(char)* header = \"Error: \");\n\n/**\n * Same as $(D errorSupplemental), but takes a va_list parameter.\n * Params:\n *      loc    = location of error\n *      format = printf-style format specification\n *      ap     = printf-style variadic arguments\n */\nextern (C++) void verrorSupplemental(const ref Loc loc, const(char)* format, va_list ap);\n\n/**\n * Same as $(D warning), but takes a va_list parameter.\n * Params:\n *      loc    = location of warning\n *      format = printf-style format specification\n *      ap     = printf-style variadic arguments\n */\nextern (C++) void vwarning(const ref Loc loc, const(char)* format, va_list ap);\n\n/**\n * Same as $(D warningSupplemental), but takes a va_list parameter.\n * Params:\n *      loc    = location of warning\n *      format = printf-style format specification\n *      ap     = printf-style variadic arguments\n */\nextern (C++) void vwarningSupplemental(const ref Loc loc, const(char)* format, va_list ap);\n\n/**\n * Same as $(D deprecation), but takes a va_list parameter, and optionally additional message prefixes.\n * Params:\n *      loc    = location of deprecation\n *      format = printf-style format specification\n *      ap     = printf-style variadic arguments\n *      p1     = additional message prefix\n *      p2     = additional message prefix\n */\nextern (C++) void vdeprecation(const ref Loc loc, const(char)* format, va_list ap, const(char)* p1 = null, const(char)* p2 = null);\n\n/**\n * Same as $(D message), but takes a va_list parameter.\n * Params:\n *      loc       = location of message\n *      format    = printf-style format specification\n *      ap        = printf-style variadic arguments\n */\nextern (C++) void vmessage(const ref Loc loc, const(char)* format, va_list ap);\n\n/**\n * Same as $(D deprecationSupplemental), but takes a va_list parameter.\n * Params:\n *      loc    = location of deprecation\n *      format = printf-style format specification\n *      ap     = printf-style variadic arguments\n */\nextern (C++) void vdeprecationSupplemental(const ref Loc loc, const(char)* format, va_list ap);\n\n/**\n * Call this after printing out fatal error messages to clean up and exit\n * the compiler.\n */\nextern (C++) void fatal();\n\n/**\n * Try to stop forgetting to remove the breakpoints from\n * release builds.\n */\nextern (C++) void halt();\n"
  },
  {
    "path": "gcc/d/dmd/errors.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/errors.h\n */\n\n#pragma once\n\n#include <stdarg.h>\n#include <stddef.h>\n\nstruct Loc;\n\nbool isConsoleColorSupported();\n\n#if defined(__GNUC__)\n#define D_ATTRIBUTE_FORMAT(m, n) __attribute__((format(printf, m, n))) __attribute__((nonnull (m)))\n#else\n#define D_ATTRIBUTE_FORMAT(m, n)\n#endif\n\n// Print a warning, deprecation, or error, accepts printf-like format specifiers.\nD_ATTRIBUTE_FORMAT(2, 3) void warning(const Loc& loc, const char *format, ...);\nD_ATTRIBUTE_FORMAT(2, 3) void warningSupplemental(const Loc& loc, const char *format, ...);\nD_ATTRIBUTE_FORMAT(2, 3) void deprecation(const Loc& loc, const char *format, ...);\nD_ATTRIBUTE_FORMAT(2, 3) void deprecationSupplemental(const Loc& loc, const char *format, ...);\nD_ATTRIBUTE_FORMAT(2, 3) void error(const Loc& loc, const char *format, ...);\nD_ATTRIBUTE_FORMAT(4, 5) void error(const char *filename, unsigned linnum, unsigned charnum, const char *format, ...);\nD_ATTRIBUTE_FORMAT(2, 3) void errorSupplemental(const Loc& loc, const char *format, ...);\nD_ATTRIBUTE_FORMAT(2, 0) void verror(const Loc& loc, const char *format, va_list ap, const char *p1 = NULL, const char *p2 = NULL, const char *header = \"Error: \");\nD_ATTRIBUTE_FORMAT(2, 0) void verrorSupplemental(const Loc& loc, const char *format, va_list ap);\nD_ATTRIBUTE_FORMAT(2, 0) void vwarning(const Loc& loc, const char *format, va_list);\nD_ATTRIBUTE_FORMAT(2, 0) void vwarningSupplemental(const Loc& loc, const char *format, va_list ap);\nD_ATTRIBUTE_FORMAT(2, 0) void vdeprecation(const Loc& loc, const char *format, va_list ap, const char *p1 = NULL, const char *p2 = NULL);\nD_ATTRIBUTE_FORMAT(2, 0) void vdeprecationSupplemental(const Loc& loc, const char *format, va_list ap);\nD_ATTRIBUTE_FORMAT(1, 2) void message(const char *format, ...);\nD_ATTRIBUTE_FORMAT(2, 3) void message(const Loc& loc, const char *format, ...);\nD_ATTRIBUTE_FORMAT(2, 0) void vmessage(const Loc& loc, const char *format, va_list);\n\n#if defined(__GNUC__) || defined(__clang__)\n#define D_ATTRIBUTE_NORETURN __attribute__((noreturn))\n#elif _MSC_VER\n#define D_ATTRIBUTE_NORETURN __declspec(noreturn)\n#else\n#define D_ATTRIBUTE_NORETURN\n#endif\n\n// Called after printing out fatal error messages.\nD_ATTRIBUTE_NORETURN void fatal();\nD_ATTRIBUTE_NORETURN void halt();\n"
  },
  {
    "path": "gcc/d/dmd/escape.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/escape.d, _escape.d)\n * Documentation:  https://dlang.org/phobos/dmd_escape.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/escape.d\n */\n\nmodule dmd.escape;\n\nimport core.stdc.stdio : printf;\n\nimport dmd.aggregate;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.mtype;\nimport dmd.root.rootobject;\nimport dmd.tokens;\nimport dmd.visitor;\nimport dmd.arraytypes;\n\n/******************************************\n * Array literal is going to be allocated on the GC heap.\n * Check its elements to see if any would escape by going on the heap.\n * Params:\n *      sc = used to determine current function and module\n *      ae = array literal expression\n *      gag = do not print error messages\n * Returns:\n *      true if any elements escaped\n */\nbool checkArrayLiteralEscape(Scope *sc, ArrayLiteralExp ae, bool gag)\n{\n    bool errors;\n    if (ae.basis)\n        errors = checkNewEscape(sc, ae.basis, gag);\n    foreach (ex; *ae.elements)\n    {\n        if (ex)\n            errors |= checkNewEscape(sc, ex, gag);\n    }\n    return errors;\n}\n\n/******************************************\n * Associative array literal is going to be allocated on the GC heap.\n * Check its elements to see if any would escape by going on the heap.\n * Params:\n *      sc = used to determine current function and module\n *      ae = associative array literal expression\n *      gag = do not print error messages\n * Returns:\n *      true if any elements escaped\n */\nbool checkAssocArrayLiteralEscape(Scope *sc, AssocArrayLiteralExp ae, bool gag)\n{\n    bool errors;\n    foreach (ex; *ae.keys)\n    {\n        if (ex)\n            errors |= checkNewEscape(sc, ex, gag);\n    }\n    foreach (ex; *ae.values)\n    {\n        if (ex)\n            errors |= checkNewEscape(sc, ex, gag);\n    }\n    return errors;\n}\n\n/****************************************\n * Function parameter par is being initialized to arg,\n * and par may escape.\n * Detect if scoped values can escape this way.\n * Print error messages when these are detected.\n * Params:\n *      sc = used to determine current function and module\n *      fdc = function being called, `null` if called indirectly\n *      par = identifier of function parameter\n *      arg = initializer for param\n *      gag = do not print error messages\n * Returns:\n *      true if pointers to the stack can escape via assignment\n */\nbool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier par, Expression arg, bool gag)\n{\n    enum log = false;\n    if (log) printf(\"checkParamArgumentEscape(arg: %s par: %s)\\n\", arg ? arg.toChars() : \"null\", par ? par.toChars() : \"null\");\n    //printf(\"type = %s, %d\\n\", arg.type.toChars(), arg.type.hasPointers());\n\n    if (!arg.type.hasPointers())\n        return false;\n\n    EscapeByResults er;\n\n    escapeByValue(arg, &er);\n\n    if (!er.byref.dim && !er.byvalue.dim && !er.byfunc.dim && !er.byexp.dim)\n        return false;\n\n    bool result = false;\n\n    /* 'v' is assigned unsafely to 'par'\n     */\n    void unsafeAssign(VarDeclaration v, const char* desc)\n    {\n        if (global.params.vsafe && sc.func.setUnsafe())\n        {\n            if (!gag)\n                error(arg.loc, \"%s `%s` assigned to non-scope parameter `%s` calling %s\",\n                    desc, v.toChars(),\n                    par ? par.toChars() : \"unnamed\",\n                    fdc ? fdc.toPrettyChars() : \"indirectly\");\n            result = true;\n        }\n    }\n\n    foreach (VarDeclaration v; er.byvalue)\n    {\n        if (log) printf(\"byvalue %s\\n\", v.toChars());\n        if (v.isDataseg())\n            continue;\n\n        Dsymbol p = v.toParent2();\n\n        notMaybeScope(v);\n\n        if (v.isScope())\n        {\n            unsafeAssign(v, \"scope variable\");\n        }\n        else if (v.storage_class & STC.variadic && p == sc.func)\n        {\n            Type tb = v.type.toBasetype();\n            if (tb.ty == Tarray || tb.ty == Tsarray)\n            {\n                unsafeAssign(v, \"variadic variable\");\n            }\n        }\n        else\n        {\n            /* v is not 'scope', and is assigned to a parameter that may escape.\n             * Therefore, v can never be 'scope'.\n             */\n            if (log) printf(\"no infer for %s in %s loc %s, fdc %s, %d\\n\",\n                v.toChars(), sc.func.ident.toChars(), sc.func.loc.toChars(), fdc.ident.toChars(),  __LINE__);\n            v.doNotInferScope = true;\n        }\n    }\n\n    foreach (VarDeclaration v; er.byref)\n    {\n        if (log) printf(\"byref %s\\n\", v.toChars());\n        if (v.isDataseg())\n            continue;\n\n        Dsymbol p = v.toParent2();\n\n        notMaybeScope(v);\n\n        if ((v.storage_class & (STC.ref_ | STC.out_)) == 0 && p == sc.func)\n        {\n            unsafeAssign(v, \"reference to local variable\");\n            continue;\n        }\n    }\n\n    foreach (FuncDeclaration fd; er.byfunc)\n    {\n        //printf(\"fd = %s, %d\\n\", fd.toChars(), fd.tookAddressOf);\n        VarDeclarations vars;\n        findAllOuterAccessedVariables(fd, &vars);\n\n        foreach (v; vars)\n        {\n            //printf(\"v = %s\\n\", v.toChars());\n            assert(!v.isDataseg());     // these are not put in the closureVars[]\n\n            Dsymbol p = v.toParent2();\n\n            notMaybeScope(v);\n\n            if ((v.storage_class & (STC.ref_ | STC.out_ | STC.scope_)) && p == sc.func)\n            {\n                unsafeAssign(v, \"reference to local\");\n                continue;\n            }\n        }\n    }\n\n    foreach (Expression ee; er.byexp)\n    {\n        if (sc.func.setUnsafe())\n        {\n            if (!gag)\n                error(ee.loc, \"reference to stack allocated value returned by `%s` assigned to non-scope parameter `%s`\",\n                    ee.toChars(),\n                    par ? par.toChars() : \"unnamed\");\n            result = true;\n        }\n    }\n\n    return result;\n}\n\n/****************************************\n * Given an AssignExp, determine if the lvalue will cause\n * the contents of the rvalue to escape.\n * Print error messages when these are detected.\n * Infer 'scope' for the lvalue where possible, in order\n * to eliminate the error.\n * Params:\n *      sc = used to determine current function and module\n *      e = AssignExp or CatAssignExp to check for any pointers to the stack\n *      gag = do not print error messages\n * Returns:\n *      true if pointers to the stack can escape via assignment\n */\nbool checkAssignEscape(Scope* sc, Expression e, bool gag)\n{\n    enum log = false;\n    if (log) printf(\"checkAssignEscape(e: %s)\\n\", e.toChars());\n    if (e.op != TOK.assign && e.op != TOK.blit && e.op != TOK.construct &&\n        e.op != TOK.concatenateAssign && e.op != TOK.concatenateElemAssign && e.op != TOK.concatenateDcharAssign)\n        return false;\n    auto ae = cast(BinExp)e;\n    Expression e1 = ae.e1;\n    Expression e2 = ae.e2;\n    //printf(\"type = %s, %d\\n\", e1.type.toChars(), e1.type.hasPointers());\n\n    if (!e1.type.hasPointers())\n        return false;\n\n    if (e1.op == TOK.slice)\n        return false;\n\n    EscapeByResults er;\n\n    escapeByValue(e2, &er);\n\n    if (!er.byref.dim && !er.byvalue.dim && !er.byfunc.dim && !er.byexp.dim)\n        return false;\n\n    VarDeclaration va = expToVariable(e1);\n\n    if (va && e.op == TOK.concatenateElemAssign)\n    {\n        /* https://issues.dlang.org/show_bug.cgi?id=17842\n         * Draw an equivalence between:\n         *   *q = p;\n         * and:\n         *   va ~= e;\n         * since we are not assigning to va, but are assigning indirectly through va.\n         */\n        va = null;\n    }\n\n    if (va && e1.op == TOK.dotVariable && va.type.toBasetype().ty == Tclass)\n    {\n        /* https://issues.dlang.org/show_bug.cgi?id=17949\n         * Draw an equivalence between:\n         *   *q = p;\n         * and:\n         *   va.field = e2;\n         * since we are not assigning to va, but are assigning indirectly through class reference va.\n         */\n        va = null;\n    }\n\n    if (log && va) printf(\"va: %s\\n\", va.toChars());\n\n    // Try to infer 'scope' for va if in a function not marked @system\n    bool inferScope = false;\n    if (va && sc.func && sc.func.type && sc.func.type.ty == Tfunction)\n        inferScope = (cast(TypeFunction)sc.func.type).trust != TRUST.system;\n    //printf(\"inferScope = %d, %d\\n\", inferScope, (va.storage_class & STCmaybescope) != 0);\n\n    // Determine if va is a parameter that is an indirect reference\n    const bool vaIsRef = va && va.storage_class & STC.parameter &&\n        (va.storage_class & (STC.ref_ | STC.out_) || va.type.toBasetype().ty == Tclass);\n\n    bool result = false;\n    foreach (VarDeclaration v; er.byvalue)\n    {\n        if (log) printf(\"byvalue: %s\\n\", v.toChars());\n        if (v.isDataseg())\n            continue;\n\n        if (v == va)\n            continue;\n\n        Dsymbol p = v.toParent2();\n\n        if (va && !vaIsRef && !va.isScope() && !v.isScope() &&\n            (va.storage_class & v.storage_class & (STC.maybescope | STC.variadic)) == STC.maybescope &&\n            p == sc.func)\n        {\n            /* Add v to va's list of dependencies\n             */\n            va.addMaybe(v);\n            continue;\n        }\n\n        if (!(va && va.isScope()) || vaIsRef)\n            notMaybeScope(v);\n\n        if (v.isScope())\n        {\n            if (va && va.isScope() && va.storage_class & STC.return_ && !(v.storage_class & STC.return_) &&\n                sc.func.setUnsafe())\n            {\n                if (!gag)\n                    error(ae.loc, \"scope variable `%s` assigned to return scope `%s`\", v.toChars(), va.toChars());\n                result = true;\n                continue;\n            }\n\n            // If va's lifetime encloses v's, then error\n            if (va &&\n                (va.enclosesLifetimeOf(v) && !(v.storage_class & (STC.parameter | STC.temp)) ||\n                 // va is class reference\n                 ae.e1.op == TOK.dotVariable && va.type.toBasetype().ty == Tclass && (va.enclosesLifetimeOf(v) || !va.isScope()) ||\n                 vaIsRef ||\n                 va.storage_class & (STC.ref_ | STC.out_) && !(v.storage_class & STC.temp)) &&\n                sc.func.setUnsafe())\n            {\n                if (!gag)\n                    error(ae.loc, \"scope variable `%s` assigned to `%s` with longer lifetime\", v.toChars(), va.toChars());\n                result = true;\n                continue;\n            }\n\n            if (va && !va.isDataseg() && !va.doNotInferScope)\n            {\n                if (!va.isScope() && inferScope)\n                {   //printf(\"inferring scope for %s\\n\", va.toChars());\n                    va.storage_class |= STC.scope_ | STC.scopeinferred;\n                    va.storage_class |= v.storage_class & STC.return_;\n                }\n                continue;\n            }\n            if (sc.func.setUnsafe())\n            {\n                if (!gag)\n                    error(ae.loc, \"scope variable `%s` assigned to non-scope `%s`\", v.toChars(), e1.toChars());\n                result = true;\n            }\n        }\n        else if (v.storage_class & STC.variadic && p == sc.func)\n        {\n            Type tb = v.type.toBasetype();\n            if (tb.ty == Tarray || tb.ty == Tsarray)\n            {\n                if (va && !va.isDataseg() && !va.doNotInferScope)\n                {\n                    if (!va.isScope() && inferScope)\n                    {   //printf(\"inferring scope for %s\\n\", va.toChars());\n                        va.storage_class |= STC.scope_ | STC.scopeinferred;\n                    }\n                    continue;\n                }\n                if (sc.func.setUnsafe())\n                {\n                    if (!gag)\n                        error(ae.loc, \"variadic variable `%s` assigned to non-scope `%s`\", v.toChars(), e1.toChars());\n                    result = true;\n                }\n            }\n        }\n        else\n        {\n            /* v is not 'scope', and we didn't check the scope of where we assigned it to.\n             * It may escape via that assignment, therefore, v can never be 'scope'.\n             */\n            //printf(\"no infer for %s in %s, %d\\n\", v.toChars(), sc.func.ident.toChars(), __LINE__);\n            v.doNotInferScope = true;\n        }\n    }\n\nByRef:\n    foreach (VarDeclaration v; er.byref)\n    {\n        if (log) printf(\"byref: %s\\n\", v.toChars());\n        if (v.isDataseg())\n            continue;\n\n        Dsymbol p = v.toParent2();\n\n        // If va's lifetime encloses v's, then error\n        if (va &&\n            (va.enclosesLifetimeOf(v) && !(v.storage_class & STC.parameter) ||\n             va.storage_class & STC.ref_ ||\n             va.isDataseg()) &&\n            sc.func.setUnsafe())\n        {\n            if (!gag)\n                error(ae.loc, \"address of variable `%s` assigned to `%s` with longer lifetime\", v.toChars(), va.toChars());\n            result = true;\n            continue;\n        }\n\n        if (va &&  v.storage_class & (STC.ref_ | STC.out_))\n        {\n            Dsymbol pva = va.toParent2();\n            for (Dsymbol pv = p; pv; )\n            {\n                pv = pv.toParent2();\n                if (pva == pv)  // if v is nested inside pva\n                {\n                    if (sc.func.setUnsafe())\n                    {\n                        if (!gag)\n                            error(ae.loc, \"reference `%s` assigned to `%s` with longer lifetime\", v.toChars(), va.toChars());\n                        result = true;\n                        continue ByRef;\n                    }\n                    break;\n                }\n            }\n        }\n\n        if (!(va && va.isScope()))\n            notMaybeScope(v);\n\n        if ((v.storage_class & (STC.ref_ | STC.out_)) == 0 && p == sc.func)\n        {\n            if (va && !va.isDataseg() && !va.doNotInferScope)\n            {\n                if (!va.isScope() && inferScope)\n                {   //printf(\"inferring scope for %s\\n\", va.toChars());\n                    va.storage_class |= STC.scope_ | STC.scopeinferred;\n                }\n                continue;\n            }\n            if (sc.func.setUnsafe())\n            {\n                if (!gag)\n                    error(ae.loc, \"reference to local variable `%s` assigned to non-scope `%s`\", v.toChars(), e1.toChars());\n                result = true;\n            }\n            continue;\n        }\n    }\n\n    foreach (FuncDeclaration fd; er.byfunc)\n    {\n        if (log) printf(\"byfunc: %s, %d\\n\", fd.toChars(), fd.tookAddressOf);\n        VarDeclarations vars;\n        findAllOuterAccessedVariables(fd, &vars);\n\n        /* https://issues.dlang.org/show_bug.cgi?id=16037\n         * If assigning the address of a delegate to a scope variable,\n         * then uncount that address of. This is so it won't cause a\n         * closure to be allocated.\n         */\n        if (va && va.isScope() && fd.tookAddressOf && global.params.vsafe)\n            --fd.tookAddressOf;\n\n        foreach (v; vars)\n        {\n            //printf(\"v = %s\\n\", v.toChars());\n            assert(!v.isDataseg());     // these are not put in the closureVars[]\n\n            Dsymbol p = v.toParent2();\n\n            if (!(va && va.isScope()))\n                notMaybeScope(v);\n\n            if ((v.storage_class & (STC.ref_ | STC.out_ | STC.scope_)) && p == sc.func)\n            {\n                if (va && !va.isDataseg() && !va.doNotInferScope)\n                {\n                    /* Don't infer STC.scope_ for va, because then a closure\n                     * won't be generated for sc.func.\n                     */\n                    //if (!va.isScope() && inferScope)\n                        //va.storage_class |= STC.scope_ | STC.scopeinferred;\n                    continue;\n                }\n                if (sc.func.setUnsafe())\n                {\n                    if (!gag)\n                        error(ae.loc, \"reference to local `%s` assigned to non-scope `%s` in @safe code\", v.toChars(), e1.toChars());\n                    result = true;\n                }\n                continue;\n            }\n        }\n    }\n\n    foreach (Expression ee; er.byexp)\n    {\n        if (log) printf(\"byexp: %s\\n\", ee.toChars());\n\n        /* Do not allow slicing of a static array returned by a function\n         */\n        if (va && ee.op == TOK.call && ee.type.toBasetype().ty == Tsarray && va.type.toBasetype().ty == Tarray &&\n            !(va.storage_class & STC.temp))\n        {\n            if (!gag)\n                deprecation(ee.loc, \"slice of static array temporary returned by `%s` assigned to longer lived variable `%s`\",\n                    ee.toChars(), va.toChars());\n            //result = true;\n            continue;\n        }\n\n        if (va && !va.isDataseg() && !va.doNotInferScope)\n        {\n            if (!va.isScope() && inferScope)\n            {   //printf(\"inferring scope for %s\\n\", va.toChars());\n                va.storage_class |= STC.scope_ | STC.scopeinferred;\n            }\n            continue;\n        }\n\n        if (sc.func.setUnsafe())\n        {\n            if (!gag)\n                error(ee.loc, \"reference to stack allocated value returned by `%s` assigned to non-scope `%s`\",\n                    ee.toChars(), e1.toChars());\n            result = true;\n        }\n    }\n\n    return result;\n}\n\n/************************************\n * Detect cases where pointers to the stack can 'escape' the\n * lifetime of the stack frame when throwing `e`.\n * Print error messages when these are detected.\n * Params:\n *      sc = used to determine current function and module\n *      e = expression to check for any pointers to the stack\n *      gag = do not print error messages\n * Returns:\n *      true if pointers to the stack can escape\n */\nbool checkThrowEscape(Scope* sc, Expression e, bool gag)\n{\n    //printf(\"[%s] checkThrowEscape, e = %s\\n\", e.loc.toChars(), e.toChars());\n    EscapeByResults er;\n\n    escapeByValue(e, &er);\n\n    if (!er.byref.dim && !er.byvalue.dim && !er.byexp.dim)\n        return false;\n\n    bool result = false;\n    foreach (VarDeclaration v; er.byvalue)\n    {\n        //printf(\"byvalue %s\\n\", v.toChars());\n        if (v.isDataseg())\n            continue;\n\n        if (v.isScope() && !v.iscatchvar)       // special case: allow catch var to be rethrown\n                                                // despite being `scope`\n        {\n            if (sc._module && sc._module.isRoot())\n            {\n                // Only look for errors if in module listed on command line\n                if (global.params.vsafe) // https://issues.dlang.org/show_bug.cgi?id=17029\n                {\n                    if (!gag)\n                        error(e.loc, \"scope variable `%s` may not be thrown\", v.toChars());\n                    result = true;\n                }\n                continue;\n            }\n        }\n        else\n        {\n            //printf(\"no infer for %s in %s, %d\\n\", v.toChars(), sc.func.ident.toChars(), __LINE__);\n            v.doNotInferScope = true;\n        }\n    }\n    return result;\n}\n\n/************************************\n * Detect cases where pointers to the stack can 'escape' the\n * lifetime of the stack frame by being placed into a GC allocated object.\n * Print error messages when these are detected.\n * Params:\n *      sc = used to determine current function and module\n *      e = expression to check for any pointers to the stack\n *      gag = do not print error messages\n * Returns:\n *      true if pointers to the stack can escape\n */\nbool checkNewEscape(Scope* sc, Expression e, bool gag)\n{\n    //printf(\"[%s] checkNewEscape, e = %s\\n\", e.loc.toChars(), e.toChars());\n    enum log = false;\n    if (log) printf(\"[%s] checkNewEscape, e: `%s`\\n\", e.loc.toChars(), e.toChars());\n    EscapeByResults er;\n\n    escapeByValue(e, &er);\n\n    if (!er.byref.dim && !er.byvalue.dim && !er.byexp.dim)\n        return false;\n\n    bool result = false;\n    foreach (VarDeclaration v; er.byvalue)\n    {\n        if (log) printf(\"byvalue `%s`\\n\", v.toChars());\n        if (v.isDataseg())\n            continue;\n\n        Dsymbol p = v.toParent2();\n\n        if (v.isScope())\n        {\n            if (sc._module && sc._module.isRoot() &&\n                /* This case comes up when the ReturnStatement of a __foreachbody is\n                 * checked for escapes by the caller of __foreachbody. Skip it.\n                 *\n                 * struct S { static int opApply(int delegate(S*) dg); }\n                 * S* foo() {\n                 *    foreach (S* s; S) // create __foreachbody for body of foreach\n                 *        return s;     // s is inferred as 'scope' but incorrectly tested in foo()\n                 *    return null; }\n                 */\n                !(p.parent == sc.func))\n            {\n                // Only look for errors if in module listed on command line\n                if (global.params.vsafe) // https://issues.dlang.org/show_bug.cgi?id=17029\n                {\n                    if (!gag)\n                        error(e.loc, \"scope variable `%s` may not be copied into allocated memory\", v.toChars());\n                    result = true;\n                }\n                continue;\n            }\n        }\n        else if (v.storage_class & STC.variadic && p == sc.func)\n        {\n            Type tb = v.type.toBasetype();\n            if (tb.ty == Tarray || tb.ty == Tsarray)\n            {\n                if (!gag)\n                    error(e.loc, \"copying `%s` into allocated memory escapes a reference to variadic parameter `%s`\", e.toChars(), v.toChars());\n                result = false;\n            }\n        }\n        else\n        {\n            //printf(\"no infer for %s in %s, %d\\n\", v.toChars(), sc.func.ident.toChars(), __LINE__);\n            v.doNotInferScope = true;\n        }\n    }\n\n    foreach (VarDeclaration v; er.byref)\n    {\n        if (log) printf(\"byref `%s`\\n\", v.toChars());\n\n        void escapingRef(VarDeclaration v)\n        {\n            if (!gag)\n            {\n                const(char)* kind = (v.storage_class & STC.parameter) ? \"parameter\" : \"local\";\n                error(e.loc, \"copying `%s` into allocated memory escapes a reference to %s variable `%s`\",\n                    e.toChars(), kind, v.toChars());\n            }\n            result = true;\n        }\n\n        if (v.isDataseg())\n            continue;\n\n        Dsymbol p = v.toParent2();\n\n        if ((v.storage_class & (STC.ref_ | STC.out_)) == 0)\n        {\n            if (p == sc.func)\n            {\n                escapingRef(v);\n                continue;\n            }\n        }\n\n        /* Check for returning a ref variable by 'ref', but should be 'return ref'\n         * Infer the addition of 'return', or set result to be the offending expression.\n         */\n        if (v.storage_class & (STC.ref_ | STC.out_))\n        {\n            if (global.params.useDIP25 &&\n                     sc._module && sc._module.isRoot())\n            {\n                // Only look for errors if in module listed on command line\n\n                if (p == sc.func)\n                {\n                    //printf(\"escaping reference to local ref variable %s\\n\", v.toChars());\n                    //printf(\"storage class = x%llx\\n\", v.storage_class);\n                    escapingRef(v);\n                    continue;\n                }\n                // Don't need to be concerned if v's parent does not return a ref\n                FuncDeclaration fd = p.isFuncDeclaration();\n                if (fd && fd.type && fd.type.ty == Tfunction)\n                {\n                    TypeFunction tf = cast(TypeFunction)fd.type;\n                    if (tf.isref)\n                    {\n                        if (!gag)\n                            error(e.loc, \"storing reference to outer local variable `%s` into allocated memory causes it to escape\",\n                                  v.toChars());\n                        result = true;\n                        continue;\n                    }\n                }\n\n            }\n        }\n    }\n\n    foreach (Expression ee; er.byexp)\n    {\n        if (log) printf(\"byexp %s\\n\", ee.toChars());\n        if (!gag)\n            error(ee.loc, \"storing reference to stack allocated value returned by `%s` into allocated memory causes it to escape\",\n                  ee.toChars());\n        result = true;\n    }\n\n    return result;\n}\n\n\n/************************************\n * Detect cases where pointers to the stack can 'escape' the\n * lifetime of the stack frame by returning 'e' by value.\n * Print error messages when these are detected.\n * Params:\n *      sc = used to determine current function and module\n *      e = expression to check for any pointers to the stack\n *      gag = do not print error messages\n * Returns:\n *      true if pointers to the stack can escape\n */\nbool checkReturnEscape(Scope* sc, Expression e, bool gag)\n{\n    //printf(\"[%s] checkReturnEscape, e = %s\\n\", e.loc.toChars(), e.toChars());\n    return checkReturnEscapeImpl(sc, e, false, gag);\n}\n\n/************************************\n * Detect cases where returning 'e' by ref can result in a reference to the stack\n * being returned.\n * Print error messages when these are detected.\n * Params:\n *      sc = used to determine current function and module\n *      e = expression to check\n *      gag = do not print error messages\n * Returns:\n *      true if references to the stack can escape\n */\nbool checkReturnEscapeRef(Scope* sc, Expression e, bool gag)\n{\n    version (none)\n    {\n        printf(\"[%s] checkReturnEscapeRef, e = %s\\n\", e.loc.toChars(), e.toChars());\n        printf(\"current function %s\\n\", sc.func.toChars());\n        printf(\"parent2 function %s\\n\", sc.func.toParent2().toChars());\n    }\n\n    return checkReturnEscapeImpl(sc, e, true, gag);\n}\n\n/***************************************\n * Implementation of checking for escapes in `return`.\n * Params:\n *      sc = used to determine current function and module\n *      e = expression to check\n *      gag = do not print error messages\n * Returns:\n *      true if references to the stack can escape\n */\nprivate bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)\n{\n    enum log = false;\n    if (log) printf(\"[%s] checkReturnEscapeImpl, refs: %d e: `%s`\\n\", e.loc.toChars(), refs, e.toChars());\n    EscapeByResults er;\n\n    if (refs)\n        escapeByRef(e, &er);\n    else\n        escapeByValue(e, &er);\n\n    if (!er.byref.dim && !er.byvalue.dim && !er.byexp.dim)\n        return false;\n\n    bool result = false;\n    foreach (VarDeclaration v; er.byvalue)\n    {\n        if (log) printf(\"byvalue `%s`\\n\", v.toChars());\n        if (v.isDataseg())\n            continue;\n\n        Dsymbol p = v.toParent2();\n\n        if ((v.isScope() || (v.storage_class & STC.maybescope)) &&\n            !(v.storage_class & STC.return_) &&\n            v.isParameter() &&\n            sc.func.flags & FUNCFLAG.returnInprocess &&\n            p == sc.func)\n        {\n            inferReturn(sc.func, v);        // infer addition of 'return'\n            continue;\n        }\n\n        if (v.isScope())\n        {\n            if (v.storage_class & STC.return_)\n                continue;\n\n            if (sc._module && sc._module.isRoot() &&\n                /* This case comes up when the ReturnStatement of a __foreachbody is\n                 * checked for escapes by the caller of __foreachbody. Skip it.\n                 *\n                 * struct S { static int opApply(int delegate(S*) dg); }\n                 * S* foo() {\n                 *    foreach (S* s; S) // create __foreachbody for body of foreach\n                 *        return s;     // s is inferred as 'scope' but incorrectly tested in foo()\n                 *    return null; }\n                 */\n                !(!refs && p.parent == sc.func))\n            {\n                // Only look for errors if in module listed on command line\n                if (global.params.vsafe) // https://issues.dlang.org/show_bug.cgi?id=17029\n                {\n                    if (!gag)\n                        error(e.loc, \"scope variable `%s` may not be returned\", v.toChars());\n                    result = true;\n                }\n                continue;\n            }\n        }\n        else if (v.storage_class & STC.variadic && p == sc.func)\n        {\n            Type tb = v.type.toBasetype();\n            if (tb.ty == Tarray || tb.ty == Tsarray)\n            {\n                if (!gag)\n                    error(e.loc, \"returning `%s` escapes a reference to variadic parameter `%s`\", e.toChars(), v.toChars());\n                result = false;\n            }\n        }\n        else\n        {\n            //printf(\"no infer for %s in %s, %d\\n\", v.toChars(), sc.func.ident.toChars(), __LINE__);\n            v.doNotInferScope = true;\n        }\n    }\n\n    foreach (VarDeclaration v; er.byref)\n    {\n        if (log) printf(\"byref `%s`\\n\", v.toChars());\n\n        void escapingRef(VarDeclaration v)\n        {\n            if (!gag)\n            {\n                const(char)* msg;\n                if (v.storage_class & STC.parameter)\n                    msg = \"returning `%s` escapes a reference to parameter `%s`, perhaps annotate with `return`\";\n                else\n                    msg = \"returning `%s` escapes a reference to local variable `%s`\";\n                error(e.loc, msg, e.toChars(), v.toChars());\n            }\n            result = true;\n        }\n\n        if (v.isDataseg())\n            continue;\n\n        Dsymbol p = v.toParent2();\n\n        if ((v.storage_class & (STC.ref_ | STC.out_)) == 0)\n        {\n            if (p == sc.func)\n            {\n                escapingRef(v);\n                continue;\n            }\n            FuncDeclaration fd = p.isFuncDeclaration();\n            if (fd && sc.func.flags & FUNCFLAG.returnInprocess)\n            {\n                /* Code like:\n                 *   int x;\n                 *   auto dg = () { return &x; }\n                 * Making it:\n                 *   auto dg = () return { return &x; }\n                 * Because dg.ptr points to x, this is returning dt.ptr+offset\n                 */\n                if (global.params.vsafe)\n                    sc.func.storage_class |= STC.return_;\n            }\n\n        }\n\n        /* Check for returning a ref variable by 'ref', but should be 'return ref'\n         * Infer the addition of 'return', or set result to be the offending expression.\n         */\n        if ( (v.storage_class & (STC.ref_ | STC.out_)) &&\n            !(v.storage_class & (STC.return_ | STC.foreach_)))\n        {\n            if (sc.func.flags & FUNCFLAG.returnInprocess && p == sc.func)\n            {\n                inferReturn(sc.func, v);        // infer addition of 'return'\n            }\n            else if (global.params.useDIP25 &&\n                     sc._module && sc._module.isRoot())\n            {\n                // Only look for errors if in module listed on command line\n\n                if (p == sc.func)\n                {\n                    //printf(\"escaping reference to local ref variable %s\\n\", v.toChars());\n                    //printf(\"storage class = x%llx\\n\", v.storage_class);\n                    escapingRef(v);\n                    continue;\n                }\n                // Don't need to be concerned if v's parent does not return a ref\n                FuncDeclaration fd = p.isFuncDeclaration();\n                if (fd && fd.type && fd.type.ty == Tfunction)\n                {\n                    TypeFunction tf = cast(TypeFunction)fd.type;\n                    if (tf.isref)\n                    {\n                        if (!gag)\n                            error(e.loc, \"escaping reference to outer local variable `%s`\", v.toChars());\n                        result = true;\n                        continue;\n                    }\n                }\n\n            }\n        }\n    }\n\n    foreach (Expression ee; er.byexp)\n    {\n        if (log) printf(\"byexp %s\\n\", ee.toChars());\n        if (!gag)\n            error(ee.loc, \"escaping reference to stack allocated value returned by `%s`\", ee.toChars());\n        result = true;\n    }\n\n    return result;\n}\n\n\n/*************************************\n * Variable v needs to have 'return' inferred for it.\n * Params:\n *      fd = function that v is a parameter to\n *      v = parameter that needs to be STC.return_\n */\n\nprivate void inferReturn(FuncDeclaration fd, VarDeclaration v)\n{\n    // v is a local in the current function\n\n    //printf(\"for function '%s' inferring 'return' for variable '%s'\\n\", fd.toChars(), v.toChars());\n    v.storage_class |= STC.return_;\n\n    TypeFunction tf = cast(TypeFunction)fd.type;\n    if (v == fd.vthis)\n    {\n        /* v is the 'this' reference, so mark the function\n         */\n        fd.storage_class |= STC.return_;\n        if (tf.ty == Tfunction)\n        {\n            //printf(\"'this' too %p %s\\n\", tf, sc.func.toChars());\n            tf.isreturn = true;\n        }\n    }\n    else\n    {\n        // Perform 'return' inference on parameter\n        if (tf.ty == Tfunction && tf.parameters)\n        {\n            const dim = Parameter.dim(tf.parameters);\n            foreach (const i; 0 .. dim)\n            {\n                Parameter p = Parameter.getNth(tf.parameters, i);\n                if (p.ident == v.ident)\n                {\n                    p.storageClass |= STC.return_;\n                    break;              // there can be only one\n                }\n            }\n        }\n    }\n}\n\n\n/****************************************\n * e is an expression to be returned by value, and that value contains pointers.\n * Walk e to determine which variables are possibly being\n * returned by value, such as:\n *      int* function(int* p) { return p; }\n * If e is a form of &p, determine which variables have content\n * which is being returned as ref, such as:\n *      int* function(int i) { return &i; }\n * Multiple variables can be inserted, because of expressions like this:\n *      int function(bool b, int i, int* p) { return b ? &i : p; }\n *\n * No side effects.\n *\n * Params:\n *      e = expression to be returned by value\n *      er = where to place collected data\n */\nprivate void escapeByValue(Expression e, EscapeByResults* er)\n{\n    //printf(\"[%s] escapeByValue, e: %s\\n\", e.loc.toChars(), e.toChars());\n    extern (C++) final class EscapeVisitor : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        EscapeByResults* er;\n\n        extern (D) this(EscapeByResults* er)\n        {\n            this.er = er;\n        }\n\n        override void visit(Expression e)\n        {\n        }\n\n        override void visit(AddrExp e)\n        {\n            /* Taking the address of struct literal is normally not\n             * allowed, but CTFE can generate one out of a new expression,\n             * but it'll be placed in static data so no need to check it.\n             */\n            if (e.e1.op != TOK.structLiteral)\n                escapeByRef(e.e1, er);\n        }\n\n        override void visit(SymOffExp e)\n        {\n            VarDeclaration v = e.var.isVarDeclaration();\n            if (v)\n                er.byref.push(v);\n        }\n\n        override void visit(VarExp e)\n        {\n            VarDeclaration v = e.var.isVarDeclaration();\n            if (v)\n                er.byvalue.push(v);\n        }\n\n        override void visit(ThisExp e)\n        {\n            if (e.var)\n                er.byvalue.push(e.var);\n        }\n\n        override void visit(DotVarExp e)\n        {\n            auto t = e.e1.type.toBasetype();\n            if (t.ty == Tstruct)\n                e.e1.accept(this);\n        }\n\n        override void visit(DelegateExp e)\n        {\n            Type t = e.e1.type.toBasetype();\n            if (t.ty == Tclass || t.ty == Tpointer)\n                escapeByValue(e.e1, er);\n            else\n                escapeByRef(e.e1, er);\n            er.byfunc.push(e.func);\n        }\n\n        override void visit(FuncExp e)\n        {\n            if (e.fd.tok == TOK.delegate_)\n                er.byfunc.push(e.fd);\n        }\n\n        override void visit(TupleExp e)\n        {\n            assert(0); // should have been lowered by now\n        }\n\n        override void visit(ArrayLiteralExp e)\n        {\n            Type tb = e.type.toBasetype();\n            if (tb.ty == Tsarray || tb.ty == Tarray)\n            {\n                if (e.basis)\n                    e.basis.accept(this);\n                foreach (el; *e.elements)\n                {\n                    if (el)\n                        el.accept(this);\n                }\n            }\n        }\n\n        override void visit(StructLiteralExp e)\n        {\n            if (e.elements)\n            {\n                foreach (ex; *e.elements)\n                {\n                    if (ex)\n                        ex.accept(this);\n                }\n            }\n        }\n\n        override void visit(NewExp e)\n        {\n            Type tb = e.newtype.toBasetype();\n            if (tb.ty == Tstruct && !e.member && e.arguments)\n            {\n                foreach (ex; *e.arguments)\n                {\n                    if (ex)\n                        ex.accept(this);\n                }\n            }\n        }\n\n        override void visit(CastExp e)\n        {\n            Type tb = e.type.toBasetype();\n            if (tb.ty == Tarray && e.e1.type.toBasetype().ty == Tsarray)\n            {\n                escapeByRef(e.e1, er);\n            }\n            else\n                e.e1.accept(this);\n        }\n\n        override void visit(SliceExp e)\n        {\n            if (e.e1.op == TOK.variable)\n            {\n                VarDeclaration v = (cast(VarExp)e.e1).var.isVarDeclaration();\n                Type tb = e.type.toBasetype();\n                if (v)\n                {\n                    if (tb.ty == Tsarray)\n                        return;\n                    if (v.storage_class & STC.variadic)\n                    {\n                        er.byvalue.push(v);\n                        return;\n                    }\n                }\n            }\n            Type t1b = e.e1.type.toBasetype();\n            if (t1b.ty == Tsarray)\n            {\n                Type tb = e.type.toBasetype();\n                if (tb.ty != Tsarray)\n                    escapeByRef(e.e1, er);\n            }\n            else\n                e.e1.accept(this);\n        }\n\n        override void visit(IndexExp e)\n        {\n            if (e.e1.type.toBasetype().ty == Tsarray)\n            {\n                e.e1.accept(this);\n            }\n        }\n\n        override void visit(BinExp e)\n        {\n            Type tb = e.type.toBasetype();\n            if (tb.ty == Tpointer)\n            {\n                e.e1.accept(this);\n                e.e2.accept(this);\n            }\n        }\n\n        override void visit(BinAssignExp e)\n        {\n            e.e1.accept(this);\n        }\n\n        override void visit(AssignExp e)\n        {\n            e.e1.accept(this);\n        }\n\n        override void visit(CommaExp e)\n        {\n            e.e2.accept(this);\n        }\n\n        override void visit(CondExp e)\n        {\n            e.e1.accept(this);\n            e.e2.accept(this);\n        }\n\n        override void visit(CallExp e)\n        {\n            //printf(\"CallExp(): %s\\n\", e.toChars());\n            /* Check each argument that is\n             * passed as 'return scope'.\n             */\n            Type t1 = e.e1.type.toBasetype();\n            TypeFunction tf;\n            TypeDelegate dg;\n            if (t1.ty == Tdelegate)\n            {\n                dg = cast(TypeDelegate)t1;\n                tf = cast(TypeFunction)(cast(TypeDelegate)t1).next;\n            }\n            else if (t1.ty == Tfunction)\n                tf = cast(TypeFunction)t1;\n            else\n                return;\n\n            if (e.arguments && e.arguments.dim)\n            {\n                /* j=1 if _arguments[] is first argument,\n                 * skip it because it is not passed by ref\n                 */\n                int j = (tf.linkage == LINK.d && tf.varargs == 1);\n                for (size_t i = j; i < e.arguments.dim; ++i)\n                {\n                    Expression arg = (*e.arguments)[i];\n                    size_t nparams = Parameter.dim(tf.parameters);\n                    if (i - j < nparams && i >= j)\n                    {\n                        Parameter p = Parameter.getNth(tf.parameters, i - j);\n                        const stc = tf.parameterStorageClass(null, p);\n                        if ((stc & (STC.scope_)) && (stc & STC.return_))\n                            arg.accept(this);\n                        else if ((stc & (STC.ref_)) && (stc & STC.return_))\n                            escapeByRef(arg, er);\n                    }\n                }\n            }\n            // If 'this' is returned, check it too\n            if (e.e1.op == TOK.dotVariable && t1.ty == Tfunction)\n            {\n                DotVarExp dve = cast(DotVarExp)e.e1;\n                FuncDeclaration fd = dve.var.isFuncDeclaration();\n                AggregateDeclaration ad;\n                if (global.params.vsafe && tf.isreturn && fd && (ad = fd.isThis()) !is null)\n                {\n                    if (ad.isClassDeclaration() || tf.isscope)       // this is 'return scope'\n                        dve.e1.accept(this);\n                    else if (ad.isStructDeclaration()) // this is 'return ref'\n                        escapeByRef(dve.e1, er);\n                }\n                else if (dve.var.storage_class & STC.return_ || tf.isreturn)\n                {\n                    if (dve.var.storage_class & STC.scope_)\n                        dve.e1.accept(this);\n                    else if (dve.var.storage_class & STC.ref_)\n                        escapeByRef(dve.e1, er);\n                }\n            }\n\n            /* If returning the result of a delegate call, the .ptr\n             * field of the delegate must be checked.\n             */\n            if (dg)\n            {\n                if (tf.isreturn)\n                    e.e1.accept(this);\n            }\n\n            /* If it's a nested function that is 'return scope'\n             */\n            if (e.e1.op == TOK.variable)\n            {\n                VarExp ve = cast(VarExp)e.e1;\n                FuncDeclaration fd = ve.var.isFuncDeclaration();\n                if (fd && fd.isNested())\n                {\n                    if (tf.isreturn && tf.isscope)\n                        er.byexp.push(e);\n                }\n            }\n        }\n    }\n\n    scope EscapeVisitor v = new EscapeVisitor(er);\n    e.accept(v);\n}\n\n\n/****************************************\n * e is an expression to be returned by 'ref'.\n * Walk e to determine which variables are possibly being\n * returned by ref, such as:\n *      ref int function(int i) { return i; }\n * If e is a form of *p, determine which variables have content\n * which is being returned as ref, such as:\n *      ref int function(int* p) { return *p; }\n * Multiple variables can be inserted, because of expressions like this:\n *      ref int function(bool b, int i, int* p) { return b ? i : *p; }\n *\n * No side effects.\n *\n * Params:\n *      e = expression to be returned by 'ref'\n *      er = where to place collected data\n */\nprivate void escapeByRef(Expression e, EscapeByResults* er)\n{\n    //printf(\"[%s] escapeByRef, e: %s\\n\", e.loc.toChars(), e.toChars());\n    extern (C++) final class EscapeRefVisitor : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        EscapeByResults* er;\n\n        extern (D) this(EscapeByResults* er)\n        {\n            this.er = er;\n        }\n\n        override void visit(Expression e)\n        {\n        }\n\n        override void visit(VarExp e)\n        {\n            auto v = e.var.isVarDeclaration();\n            if (v)\n            {\n                if (v.storage_class & STC.ref_ && v.storage_class & (STC.foreach_ | STC.temp) && v._init)\n                {\n                    /* If compiler generated ref temporary\n                     *   (ref v = ex; ex)\n                     * look at the initializer instead\n                     */\n                    if (ExpInitializer ez = v._init.isExpInitializer())\n                    {\n                        assert(ez.exp && ez.exp.op == TOK.construct);\n                        Expression ex = (cast(ConstructExp)ez.exp).e2;\n                        ex.accept(this);\n                    }\n                }\n                else\n                    er.byref.push(v);\n            }\n        }\n\n        override void visit(ThisExp e)\n        {\n            if (e.var)\n                er.byref.push(e.var);\n        }\n\n        override void visit(PtrExp e)\n        {\n            escapeByValue(e.e1, er);\n        }\n\n        override void visit(IndexExp e)\n        {\n            Type tb = e.e1.type.toBasetype();\n            if (e.e1.op == TOK.variable)\n            {\n                VarDeclaration v = (cast(VarExp)e.e1).var.isVarDeclaration();\n                if (tb.ty == Tarray || tb.ty == Tsarray)\n                {\n                    if (v && v.storage_class & STC.variadic)\n                    {\n                        er.byref.push(v);\n                        return;\n                    }\n                }\n            }\n            if (tb.ty == Tsarray)\n            {\n                e.e1.accept(this);\n            }\n            else if (tb.ty == Tarray)\n            {\n                escapeByValue(e.e1, er);\n            }\n        }\n\n        override void visit(StructLiteralExp e)\n        {\n            if (e.elements)\n            {\n                foreach (ex; *e.elements)\n                {\n                    if (ex)\n                        ex.accept(this);\n                }\n            }\n            er.byexp.push(e);\n        }\n\n        override void visit(DotVarExp e)\n        {\n            Type t1b = e.e1.type.toBasetype();\n            if (t1b.ty == Tclass)\n                escapeByValue(e.e1, er);\n            else\n                e.e1.accept(this);\n        }\n\n        override void visit(BinAssignExp e)\n        {\n            e.e1.accept(this);\n        }\n\n        override void visit(AssignExp e)\n        {\n            e.e1.accept(this);\n        }\n\n        override void visit(CommaExp e)\n        {\n            e.e2.accept(this);\n        }\n\n        override void visit(CondExp e)\n        {\n            e.e1.accept(this);\n            e.e2.accept(this);\n        }\n\n        override void visit(CallExp e)\n        {\n            /* If the function returns by ref, check each argument that is\n             * passed as 'return ref'.\n             */\n            Type t1 = e.e1.type.toBasetype();\n            TypeFunction tf;\n            if (t1.ty == Tdelegate)\n                tf = cast(TypeFunction)(cast(TypeDelegate)t1).next;\n            else if (t1.ty == Tfunction)\n                tf = cast(TypeFunction)t1;\n            else\n                return;\n            if (tf.isref)\n            {\n                if (e.arguments && e.arguments.dim)\n                {\n                    /* j=1 if _arguments[] is first argument,\n                     * skip it because it is not passed by ref\n                     */\n                    int j = (tf.linkage == LINK.d && tf.varargs == 1);\n                    for (size_t i = j; i < e.arguments.dim; ++i)\n                    {\n                        Expression arg = (*e.arguments)[i];\n                        size_t nparams = Parameter.dim(tf.parameters);\n                        if (i - j < nparams && i >= j)\n                        {\n                            Parameter p = Parameter.getNth(tf.parameters, i - j);\n                            const stc = tf.parameterStorageClass(null, p);\n                            if ((stc & (STC.out_ | STC.ref_)) && (stc & STC.return_))\n                                arg.accept(this);\n                            else if ((stc & STC.scope_) && (stc & STC.return_))\n                            {\n                                if (arg.op == TOK.delegate_)\n                                {\n                                    DelegateExp de = cast(DelegateExp)arg;\n                                    if (de.func.isNested())\n                                        er.byexp.push(de);\n                                }\n                                else\n                                    escapeByValue(arg, er);\n                            }\n                        }\n                    }\n                }\n                // If 'this' is returned by ref, check it too\n                if (e.e1.op == TOK.dotVariable && t1.ty == Tfunction)\n                {\n                    DotVarExp dve = cast(DotVarExp)e.e1;\n                    if (dve.var.storage_class & STC.return_ || tf.isreturn)\n                    {\n                        if (dve.var.storage_class & STC.scope_ || tf.isscope)\n                            escapeByValue(dve.e1, er);\n                        else if (dve.var.storage_class & STC.ref_ || tf.isref)\n                            dve.e1.accept(this);\n                    }\n                }\n                // If it's a delegate, check it too\n                if (e.e1.op == TOK.variable && t1.ty == Tdelegate)\n                {\n                    escapeByValue(e.e1, er);\n                }\n\n                /* If it's a nested function that is 'return ref'\n                 */\n                if (e.e1.op == TOK.variable)\n                {\n                    VarExp ve = cast(VarExp)e.e1;\n                    FuncDeclaration fd = ve.var.isFuncDeclaration();\n                    if (fd && fd.isNested())\n                    {\n                        if (tf.isreturn)\n                            er.byexp.push(e);\n                    }\n                }\n            }\n            else\n                er.byexp.push(e);\n        }\n    }\n\n    scope EscapeRefVisitor v = new EscapeRefVisitor(er);\n    e.accept(v);\n}\n\n\n/************************************\n * Aggregate the data collected by the escapeBy??() functions.\n */\nprivate struct EscapeByResults\n{\n    VarDeclarations byref;      // array into which variables being returned by ref are inserted\n    VarDeclarations byvalue;    // array into which variables with values containing pointers are inserted\n    FuncDeclarations byfunc;    // nested functions that are turned into delegates\n    Expressions byexp;          // array into which temporaries being returned by ref are inserted\n}\n\n/*************************\n * Find all variables accessed by this delegate that are\n * in functions enclosing it.\n * Params:\n *      fd = function\n *      vars = array to append found variables to\n */\nvoid findAllOuterAccessedVariables(FuncDeclaration fd, VarDeclarations* vars)\n{\n    //printf(\"findAllOuterAccessedVariables(fd: %s)\\n\", fd.toChars());\n    for (auto p = fd.parent; p; p = p.parent)\n    {\n        auto fdp = p.isFuncDeclaration();\n        if (fdp)\n        {\n            foreach (v; fdp.closureVars)\n            {\n                foreach (const fdv; v.nestedrefs)\n                {\n                    if (fdv == fd)\n                    {\n                        //printf(\"accessed: %s, type %s\\n\", v.toChars(), v.type.toChars());\n                        vars.push(v);\n                    }\n                }\n            }\n        }\n    }\n}\n\n/***********************************\n * Turn off STC.maybescope for variable `v`.\n * This exists in order to find where STC.maybescope is getting turned off.\n * Params:\n *      v = variable\n */\nversion (none)\n{\n    void notMaybeScope(string file = __FILE__, int line = __LINE__)(VarDeclaration v)\n    {\n        printf(\"%.*s(%d): notMaybeScope('%s')\\n\", cast(int)file.length, file.ptr, line, v.toChars());\n        v.storage_class &= ~STC.maybescope;\n    }\n}\nelse\n{\n    void notMaybeScope(VarDeclaration v)\n    {\n        v.storage_class &= ~STC.maybescope;\n    }\n}\n\n\n/**********************************************\n * Have some variables that are maybescopes that were\n * assigned values from other maybescope variables.\n * Now that semantic analysis of the function is\n * complete, we can finalize this by turning off\n * maybescope for array elements that cannot be scope.\n *\n *  `va`    `v`    =>  `va`   `v`\n *  maybe   maybe  =>  scope  scope\n *  scope   scope  =>  scope  scope\n *  scope   maybe  =>  scope  scope\n *  maybe   scope  =>  scope  scope\n *  -       -      =>  -      -\n *  -       maybe  =>  -      -\n *  -       scope  =>  error\n *  maybe   -      =>  scope  -\n *  scope   -      =>  scope  -\n * Params:\n *      array = array of variables that were assigned to from maybescope variables\n */\nvoid eliminateMaybeScopes(VarDeclaration[] array)\n{\n    enum log = false;\n    if (log) printf(\"eliminateMaybeScopes()\\n\");\n    bool changes;\n    do\n    {\n        changes = false;\n        foreach (va; array)\n        {\n            if (log) printf(\"  va = %s\\n\", va.toChars());\n            if (!(va.storage_class & (STC.maybescope | STC.scope_)))\n            {\n                if (va.maybes)\n                {\n                    foreach (v; *va.maybes)\n                    {\n                        if (log) printf(\"    v = %s\\n\", v.toChars());\n                        if (v.storage_class & STC.maybescope)\n                        {\n                            // v cannot be scope since it is assigned to a non-scope va\n                            notMaybeScope(v);\n                            changes = true;\n                        }\n                    }\n                }\n            }\n        }\n    } while (changes);\n}\n\n"
  },
  {
    "path": "gcc/d/dmd/expression.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/expression.d, _expression.d)\n * Documentation:  https://dlang.org/phobos/dmd_expression.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/expression.d\n */\n\nmodule dmd.expression;\n\nimport core.stdc.stdarg;\nimport core.stdc.stdio;\nimport core.stdc.string;\n\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.apply;\nimport dmd.arrayop;\nimport dmd.arraytypes;\nimport dmd.gluelayer;\nimport dmd.canthrow;\nimport dmd.complex;\nimport dmd.constfold;\nimport dmd.ctfeexpr;\nimport dmd.ctorflow;\nimport dmd.dcast;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.delegatize;\nimport dmd.dimport;\nimport dmd.dinterpret;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.escape;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.inline;\nimport dmd.mtype;\nimport dmd.nspace;\nimport dmd.objc;\nimport dmd.opover;\nimport dmd.optimize;\nimport dmd.root.ctfloat;\nimport dmd.root.filename;\nimport dmd.root.outbuffer;\nimport dmd.root.rmem;\nimport dmd.root.rootobject;\nimport dmd.safe;\nimport dmd.sideeffect;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.utf;\nimport dmd.visitor;\n\nenum LOGSEMANTIC = false;\nvoid emplaceExp(T : Expression, Args...)(void* p, Args args)\n{\n    scope tmp = new T(args);\n    memcpy(p, cast(void*)tmp, __traits(classInstanceSize, T));\n}\n\nvoid emplaceExp(T : UnionExp)(T* p, Expression e)\n{\n    memcpy(p, cast(void*)e, e.size);\n}\n\n\n/****************************************\n * Find the first non-comma expression.\n * Params:\n *      e = Expressions connected by commas\n * Returns:\n *      left-most non-comma expression\n */\ninout(Expression) firstComma(inout Expression e)\n{\n    Expression ex = cast()e;\n    while (ex.op == TOK.comma)\n        ex = (cast(CommaExp)ex).e1;\n    return cast(inout)ex;\n\n}\n\n/****************************************\n * Find the last non-comma expression.\n * Params:\n *      e = Expressions connected by commas\n * Returns:\n *      right-most non-comma expression\n */\n\ninout(Expression) lastComma(inout Expression e)\n{\n    Expression ex = cast()e;\n    while (ex.op == TOK.comma)\n        ex = (cast(CommaExp)ex).e2;\n    return cast(inout)ex;\n\n}\n\n/*****************************************\n * Determine if `this` is available by walking up the enclosing\n * scopes until a function is found.\n *\n * Params:\n *      sc = where to start looking for the enclosing function\n * Returns:\n *      Found function if it satisfies `isThis()`, otherwise `null`\n */\nFuncDeclaration hasThis(Scope* sc)\n{\n    //printf(\"hasThis()\\n\");\n    Dsymbol p = sc.parent;\n    while (p && p.isTemplateMixin())\n        p = p.parent;\n    FuncDeclaration fdthis = p ? p.isFuncDeclaration() : null;\n    //printf(\"fdthis = %p, '%s'\\n\", fdthis, fdthis ? fdthis.toChars() : \"\");\n\n    // Go upwards until we find the enclosing member function\n    FuncDeclaration fd = fdthis;\n    while (1)\n    {\n        if (!fd)\n        {\n            goto Lno;\n        }\n        if (!fd.isNested())\n            break;\n\n        Dsymbol parent = fd.parent;\n        while (1)\n        {\n            if (!parent)\n                goto Lno;\n            TemplateInstance ti = parent.isTemplateInstance();\n            if (ti)\n                parent = ti.parent;\n            else\n                break;\n        }\n        fd = parent.isFuncDeclaration();\n    }\n\n    if (!fd.isThis())\n    {\n        goto Lno;\n    }\n\n    assert(fd.vthis);\n    return fd;\n\nLno:\n    return null; // don't have 'this' available\n}\n\n/***********************************\n * Determine if a `this` is needed to access `d`.\n * Params:\n *      sc = context\n *      d = declaration to check\n * Returns:\n *      true means a `this` is needed\n */\nbool isNeedThisScope(Scope* sc, Declaration d)\n{\n    if (sc.intypeof == 1)\n        return false;\n\n    AggregateDeclaration ad = d.isThis();\n    if (!ad)\n        return false;\n    //printf(\"d = %s, ad = %s\\n\", d.toChars(), ad.toChars());\n\n    for (Dsymbol s = sc.parent; s; s = s.toParent2())\n    {\n        //printf(\"\\ts = %s %s, toParent2() = %p\\n\", s.kind(), s.toChars(), s.toParent2());\n        if (AggregateDeclaration ad2 = s.isAggregateDeclaration())\n        {\n            if (ad2 == ad)\n                return false;\n            else if (ad2.isNested())\n                continue;\n            else\n                return true;\n        }\n        if (FuncDeclaration f = s.isFuncDeclaration())\n        {\n            if (f.isMember2())\n                break;\n        }\n    }\n    return true;\n}\n\n/******************************\n * check e is exp.opDispatch!(tiargs) or not\n * It's used to switch to UFCS the semantic analysis path\n */\nbool isDotOpDispatch(Expression e)\n{\n    return e.op == TOK.dotTemplateInstance && (cast(DotTemplateInstanceExp)e).ti.name == Id.opDispatch;\n}\n\n/****************************************\n * Expand tuples.\n * Input:\n *      exps    aray of Expressions\n * Output:\n *      exps    rewritten in place\n */\nextern (C++) void expandTuples(Expressions* exps)\n{\n    //printf(\"expandTuples()\\n\");\n    if (exps)\n    {\n        for (size_t i = 0; i < exps.dim; i++)\n        {\n            Expression arg = (*exps)[i];\n            if (!arg)\n                continue;\n\n            // Look for tuple with 0 members\n            if (arg.op == TOK.type)\n            {\n                TypeExp e = cast(TypeExp)arg;\n                if (e.type.toBasetype().ty == Ttuple)\n                {\n                    TypeTuple tt = cast(TypeTuple)e.type.toBasetype();\n                    if (!tt.arguments || tt.arguments.dim == 0)\n                    {\n                        exps.remove(i);\n                        if (i == exps.dim)\n                            return;\n                        i--;\n                        continue;\n                    }\n                }\n            }\n\n            // Inline expand all the tuples\n            while (arg.op == TOK.tuple)\n            {\n                TupleExp te = cast(TupleExp)arg;\n                exps.remove(i); // remove arg\n                exps.insert(i, te.exps); // replace with tuple contents\n                if (i == exps.dim)\n                    return; // empty tuple, no more arguments\n                (*exps)[i] = Expression.combine(te.e0, (*exps)[i]);\n                arg = (*exps)[i];\n            }\n        }\n    }\n}\n\n/****************************************\n * Expand alias this tuples.\n */\nextern (C++) TupleDeclaration isAliasThisTuple(Expression e)\n{\n    if (!e.type)\n        return null;\n\n    Type t = e.type.toBasetype();\nLagain:\n    if (Dsymbol s = t.toDsymbol(null))\n    {\n        AggregateDeclaration ad = s.isAggregateDeclaration();\n        if (ad)\n        {\n            s = ad.aliasthis;\n            if (s && s.isVarDeclaration())\n            {\n                TupleDeclaration td = s.isVarDeclaration().toAlias().isTupleDeclaration();\n                if (td && td.isexp)\n                    return td;\n            }\n            if (Type att = t.aliasthisOf())\n            {\n                t = att;\n                goto Lagain;\n            }\n        }\n    }\n    return null;\n}\n\nextern (C++) int expandAliasThisTuples(Expressions* exps, size_t starti = 0)\n{\n    if (!exps || exps.dim == 0)\n        return -1;\n\n    for (size_t u = starti; u < exps.dim; u++)\n    {\n        Expression exp = (*exps)[u];\n        TupleDeclaration td = isAliasThisTuple(exp);\n        if (td)\n        {\n            exps.remove(u);\n            foreach (i, o; *td.objects)\n            {\n                Expression e = isExpression(o);\n                assert(e);\n                assert(e.op == TOK.dSymbol);\n                DsymbolExp se = cast(DsymbolExp)e;\n                Declaration d = se.s.isDeclaration();\n                assert(d);\n                e = new DotVarExp(exp.loc, exp, d);\n                assert(d.type);\n                e.type = d.type;\n                exps.insert(u + i, e);\n            }\n            version (none)\n            {\n                printf(\"expansion ->\\n\");\n                foreach (e; exps)\n                {\n                    printf(\"\\texps[%d] e = %s %s\\n\", i, Token.tochars[e.op], e.toChars());\n                }\n            }\n            return cast(int)u;\n        }\n    }\n    return -1;\n}\n\n/****************************************\n * If `s` is a function template, i.e. the only member of a template\n * and that member is a function, return that template.\n * Params:\n *      s = symbol that might be a function template\n * Returns:\n *      template for that function, otherwise null\n */\nextern (C++) TemplateDeclaration getFuncTemplateDecl(Dsymbol s)\n{\n    FuncDeclaration f = s.isFuncDeclaration();\n    if (f && f.parent)\n    {\n        TemplateInstance ti = f.parent.isTemplateInstance();\n        if (ti && !ti.isTemplateMixin() && ti.tempdecl && (cast(TemplateDeclaration)ti.tempdecl).onemember && ti.tempdecl.ident == f.ident)\n        {\n            return cast(TemplateDeclaration)ti.tempdecl;\n        }\n    }\n    return null;\n}\n\n/************************************************\n * If we want the value of this expression, but do not want to call\n * the destructor on it.\n */\nExpression valueNoDtor(Expression e)\n{\n    auto ex = lastComma(e);\n\n    if (ex.op == TOK.call)\n    {\n        /* The struct value returned from the function is transferred\n         * so do not call the destructor on it.\n         * Recognize:\n         *       ((S _ctmp = S.init), _ctmp).this(...)\n         * and make sure the destructor is not called on _ctmp\n         * BUG: if ex is a CommaExp, we should go down the right side.\n         */\n        CallExp ce = cast(CallExp)ex;\n        if (ce.e1.op == TOK.dotVariable)\n        {\n            DotVarExp dve = cast(DotVarExp)ce.e1;\n            if (dve.var.isCtorDeclaration())\n            {\n                // It's a constructor call\n                if (dve.e1.op == TOK.comma)\n                {\n                    CommaExp comma = cast(CommaExp)dve.e1;\n                    if (comma.e2.op == TOK.variable)\n                    {\n                        VarExp ve = cast(VarExp)comma.e2;\n                        VarDeclaration ctmp = ve.var.isVarDeclaration();\n                        if (ctmp)\n                        {\n                            ctmp.storage_class |= STC.nodtor;\n                            assert(!ce.isLvalue());\n                        }\n                    }\n                }\n            }\n        }\n    }\n    else if (ex.op == TOK.variable)\n    {\n        auto vtmp = (cast(VarExp)ex).var.isVarDeclaration();\n        if (vtmp && (vtmp.storage_class & STC.rvalue))\n        {\n            vtmp.storage_class |= STC.nodtor;\n        }\n    }\n    return e;\n}\n\n/*********************************************\n * If e is an instance of a struct, and that struct has a copy constructor,\n * rewrite e as:\n *    (tmp = e),tmp\n * Input:\n *      sc      just used to specify the scope of created temporary variable\n */\nprivate Expression callCpCtor(Scope* sc, Expression e)\n{\n    Type tv = e.type.baseElemOf();\n    if (tv.ty == Tstruct)\n    {\n        StructDeclaration sd = (cast(TypeStruct)tv).sym;\n        if (sd.postblit)\n        {\n            /* Create a variable tmp, and replace the argument e with:\n             *      (tmp = e),tmp\n             * and let AssignExp() handle the construction.\n             * This is not the most efficient, ideally tmp would be constructed\n             * directly onto the stack.\n             */\n            auto tmp = copyToTemp(STC.rvalue, \"__copytmp\", e);\n            tmp.storage_class |= STC.nodtor;\n            tmp.dsymbolSemantic(sc);\n            Expression de = new DeclarationExp(e.loc, tmp);\n            Expression ve = new VarExp(e.loc, tmp);\n            de.type = Type.tvoid;\n            ve.type = e.type;\n            e = Expression.combine(de, ve);\n        }\n    }\n    return e;\n}\n\n/************************************************\n * Handle the postblit call on lvalue, or the move of rvalue.\n */\nExpression doCopyOrMove(Scope *sc, Expression e)\n{\n    if (e.op == TOK.question)\n    {\n        auto ce = cast(CondExp)e;\n        ce.e1 = doCopyOrMove(sc, ce.e1);\n        ce.e2 = doCopyOrMove(sc, ce.e2);\n    }\n    else\n    {\n        e = e.isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e);\n    }\n    return e;\n}\n\n/****************************************************************/\n/* A type meant as a union of all the Expression types,\n * to serve essentially as a Variant that will sit on the stack\n * during CTFE to reduce memory consumption.\n */\nstruct UnionExp\n{\n    // yes, default constructor does nothing\n    extern (D) this(Expression e)\n    {\n        memcpy(&this, cast(void*)e, e.size);\n    }\n\n    /* Extract pointer to Expression\n     */\n    extern (C++) Expression exp()\n    {\n        return cast(Expression)&u;\n    }\n\n    /* Convert to an allocated Expression\n     */\n    extern (C++) Expression copy()\n    {\n        Expression e = exp();\n        //if (e.size > sizeof(u)) printf(\"%s\\n\", Token::toChars(e.op));\n        assert(e.size <= u.sizeof);\n        if (e.op == TOK.cantExpression)\n            return CTFEExp.cantexp;\n        if (e.op == TOK.voidExpression)\n            return CTFEExp.voidexp;\n        if (e.op == TOK.break_)\n            return CTFEExp.breakexp;\n        if (e.op == TOK.continue_)\n            return CTFEExp.continueexp;\n        if (e.op == TOK.goto_)\n            return CTFEExp.gotoexp;\n        return e.copy();\n    }\n\nprivate:\n    union __AnonStruct__u\n    {\n        char[__traits(classInstanceSize, Expression)] exp;\n        char[__traits(classInstanceSize, IntegerExp)] integerexp;\n        char[__traits(classInstanceSize, ErrorExp)] errorexp;\n        char[__traits(classInstanceSize, RealExp)] realexp;\n        char[__traits(classInstanceSize, ComplexExp)] complexexp;\n        char[__traits(classInstanceSize, SymOffExp)] symoffexp;\n        char[__traits(classInstanceSize, StringExp)] stringexp;\n        char[__traits(classInstanceSize, ArrayLiteralExp)] arrayliteralexp;\n        char[__traits(classInstanceSize, AssocArrayLiteralExp)] assocarrayliteralexp;\n        char[__traits(classInstanceSize, StructLiteralExp)] structliteralexp;\n        char[__traits(classInstanceSize, NullExp)] nullexp;\n        char[__traits(classInstanceSize, DotVarExp)] dotvarexp;\n        char[__traits(classInstanceSize, AddrExp)] addrexp;\n        char[__traits(classInstanceSize, IndexExp)] indexexp;\n        char[__traits(classInstanceSize, SliceExp)] sliceexp;\n        // Ensure that the union is suitably aligned.\n        real_t for_alignment_only;\n    }\n\n    __AnonStruct__u u;\n}\n\n/********************************\n * Test to see if two reals are the same.\n * Regard NaN's as equivalent.\n * Regard +0 and -0 as different.\n */\nint RealEquals(real_t x1, real_t x2)\n{\n    return (CTFloat.isNaN(x1) && CTFloat.isNaN(x2)) || CTFloat.isIdentical(x1, x2);\n}\n\n/************************ TypeDotIdExp ************************************/\n/* Things like:\n *      int.size\n *      foo.size\n *      (foo).size\n *      cast(foo).size\n */\nDotIdExp typeDotIdExp(const ref Loc loc, Type type, Identifier ident)\n{\n    return new DotIdExp(loc, new TypeExp(loc, type), ident);\n}\n\n/***************************************************\n * Given an Expression, find the variable it really is.\n *\n * For example, `a[index]` is really `a`, and `s.f` is really `s`.\n * Params:\n *      e = Expression to look at\n * Returns:\n *      variable if there is one, null if not\n */\nVarDeclaration expToVariable(Expression e)\n{\n    while (1)\n    {\n        switch (e.op)\n        {\n            case TOK.variable:\n                return (cast(VarExp)e).var.isVarDeclaration();\n\n            case TOK.dotVariable:\n                e = (cast(DotVarExp)e).e1;\n                continue;\n\n            case TOK.index:\n            {\n                IndexExp ei = cast(IndexExp)e;\n                e = ei.e1;\n                Type ti = e.type.toBasetype();\n                if (ti.ty == Tsarray)\n                    continue;\n                return null;\n            }\n\n            case TOK.slice:\n            {\n                SliceExp ei = cast(SliceExp)e;\n                e = ei.e1;\n                Type ti = e.type.toBasetype();\n                if (ti.ty == Tsarray)\n                    continue;\n                return null;\n            }\n\n            case TOK.this_:\n            case TOK.super_:\n                return (cast(ThisExp)e).var.isVarDeclaration();\n\n            default:\n                return null;\n        }\n    }\n}\n\nenum OwnedBy : int\n{\n    code,          // normal code expression in AST\n    ctfe,          // value expression for CTFE\n    cache,         // constant value cached for CTFE\n}\n\nenum WANTvalue  = 0;    // default\nenum WANTexpand = 1;    // expand const/immutable variables if possible\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#expression\n */\nextern (C++) abstract class Expression : RootObject\n{\n    Loc loc;        // file location\n    Type type;      // !=null means that semantic() has been run\n    TOK op;         // to minimize use of dynamic_cast\n    ubyte size;     // # of bytes in Expression so we can copy() it\n    ubyte parens;   // if this is a parenthesized expression\n\n    extern (D) this(const ref Loc loc, TOK op, int size)\n    {\n        //printf(\"Expression::Expression(op = %d) this = %p\\n\", op, this);\n        this.loc = loc;\n        this.op = op;\n        this.size = cast(ubyte)size;\n    }\n\n    static void _init()\n    {\n        CTFEExp.cantexp = new CTFEExp(TOK.cantExpression);\n        CTFEExp.voidexp = new CTFEExp(TOK.voidExpression);\n        CTFEExp.breakexp = new CTFEExp(TOK.break_);\n        CTFEExp.continueexp = new CTFEExp(TOK.continue_);\n        CTFEExp.gotoexp = new CTFEExp(TOK.goto_);\n        CTFEExp.showcontext = new CTFEExp(TOK.showCtfeContext);\n    }\n\n    /*********************************\n     * Does *not* do a deep copy.\n     */\n    final Expression copy()\n    {\n        Expression e;\n        if (!size)\n        {\n            debug\n            {\n                fprintf(stderr, \"No expression copy for: %s\\n\", toChars());\n                printf(\"op = %d\\n\", op);\n            }\n            assert(0);\n        }\n        e = cast(Expression)mem.xmalloc(size);\n        //printf(\"Expression::copy(op = %d) e = %p\\n\", op, e);\n        return cast(Expression)memcpy(cast(void*)e, cast(void*)this, size);\n    }\n\n    Expression syntaxCopy()\n    {\n        //printf(\"Expression::syntaxCopy()\\n\");\n        //print();\n        return copy();\n    }\n\n    // kludge for template.isExpression()\n    override final DYNCAST dyncast() const\n    {\n        return DYNCAST.expression;\n    }\n\n    override const(char)* toChars()\n    {\n        OutBuffer buf;\n        HdrGenState hgs;\n        toCBuffer(this, &buf, &hgs);\n        return buf.extractString();\n    }\n\n    final void error(const(char)* format, ...) const\n    {\n        if (type != Type.terror)\n        {\n            va_list ap;\n            va_start(ap, format);\n            .verror(loc, format, ap);\n            va_end(ap);\n        }\n    }\n\n    final void errorSupplemental(const(char)* format, ...)\n    {\n        if (type == Type.terror)\n            return;\n\n        va_list ap;\n        va_start(ap, format);\n        .verrorSupplemental(loc, format, ap);\n        va_end(ap);\n    }\n\n    final void warning(const(char)* format, ...) const\n    {\n        if (type != Type.terror)\n        {\n            va_list ap;\n            va_start(ap, format);\n            .vwarning(loc, format, ap);\n            va_end(ap);\n        }\n    }\n\n    final void deprecation(const(char)* format, ...) const\n    {\n        if (type != Type.terror)\n        {\n            va_list ap;\n            va_start(ap, format);\n            .vdeprecation(loc, format, ap);\n            va_end(ap);\n        }\n    }\n\n    /**********************************\n     * Combine e1 and e2 by CommaExp if both are not NULL.\n     */\n    extern (D) static Expression combine(Expression e1, Expression e2)\n    {\n        if (e1)\n        {\n            if (e2)\n            {\n                e1 = new CommaExp(e1.loc, e1, e2);\n                e1.type = e2.type;\n            }\n        }\n        else\n            e1 = e2;\n        return e1;\n    }\n\n    extern (D) static Expression combine(Expression e1, Expression e2, Expression e3)\n    {\n        return combine(combine(e1, e2), e3);\n    }\n\n    extern (D) static Expression combine(Expression e1, Expression e2, Expression e3, Expression e4)\n    {\n        return combine(combine(e1, e2), combine(e3, e4));\n    }\n\n    /**********************************\n     * If 'e' is a tree of commas, returns the rightmost expression\n     * by stripping off it from the tree. The remained part of the tree\n     * is returned via e0.\n     * Otherwise 'e' is directly returned and e0 is set to NULL.\n     */\n    extern (D) static Expression extractLast(Expression e, out Expression e0)\n    {\n        if (e.op != TOK.comma)\n        {\n            return e;\n        }\n\n        CommaExp ce = cast(CommaExp)e;\n        if (ce.e2.op != TOK.comma)\n        {\n            e0 = ce.e1;\n            return ce.e2;\n        }\n        else\n        {\n            e0 = e;\n\n            Expression* pce = &ce.e2;\n            while ((cast(CommaExp)(*pce)).e2.op == TOK.comma)\n            {\n                pce = &(cast(CommaExp)(*pce)).e2;\n            }\n            assert((*pce).op == TOK.comma);\n            ce = cast(CommaExp)(*pce);\n            *pce = ce.e1;\n\n            return ce.e2;\n        }\n    }\n\n    extern (D) static Expressions* arraySyntaxCopy(Expressions* exps)\n    {\n        Expressions* a = null;\n        if (exps)\n        {\n            a = new Expressions(exps.dim);\n            foreach (i, e; *exps)\n            {\n                (*a)[i] = e ? e.syntaxCopy() : null;\n            }\n        }\n        return a;\n    }\n\n    dinteger_t toInteger()\n    {\n        //printf(\"Expression %s\\n\", Token::toChars(op));\n        error(\"integer constant expression expected instead of `%s`\", toChars());\n        return 0;\n    }\n\n    uinteger_t toUInteger()\n    {\n        //printf(\"Expression %s\\n\", Token::toChars(op));\n        return cast(uinteger_t)toInteger();\n    }\n\n    real_t toReal()\n    {\n        error(\"floating point constant expression expected instead of `%s`\", toChars());\n        return CTFloat.zero;\n    }\n\n    real_t toImaginary()\n    {\n        error(\"floating point constant expression expected instead of `%s`\", toChars());\n        return CTFloat.zero;\n    }\n\n    complex_t toComplex()\n    {\n        error(\"floating point constant expression expected instead of `%s`\", toChars());\n        return complex_t(CTFloat.zero);\n    }\n\n    StringExp toStringExp()\n    {\n        return null;\n    }\n\n    /***************************************\n     * Return !=0 if expression is an lvalue.\n     */\n    bool isLvalue()\n    {\n        return false;\n    }\n\n    /*******************************\n     * Give error if we're not an lvalue.\n     * If we can, convert expression to be an lvalue.\n     */\n    Expression toLvalue(Scope* sc, Expression e)\n    {\n        if (!e)\n            e = this;\n        else if (!loc.isValid())\n            loc = e.loc;\n\n        if (e.op == TOK.type)\n            error(\"`%s` is a `%s` definition and cannot be modified\", e.type.toChars(), e.type.kind());\n        else\n            error(\"`%s` is not an lvalue and cannot be modified\", e.toChars());\n\n        return new ErrorExp();\n    }\n\n    Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        //printf(\"Expression::modifiableLvalue() %s, type = %s\\n\", toChars(), type.toChars());\n        // See if this expression is a modifiable lvalue (i.e. not const)\n        if (checkModifiable(sc) == 1)\n        {\n            assert(type);\n            if (!type.isMutable())\n            {\n                if (op == TOK.dotVariable)\n                {\n                    if (isNeedThisScope(sc, (cast(DotVarExp) this).var))\n                        for (Dsymbol s = sc.func; s; s = s.toParent2())\n                    {\n                        FuncDeclaration ff = s.isFuncDeclaration();\n                        if (!ff)\n                            break;\n                        if (!ff.type.isMutable)\n                        {\n                            error(\"cannot modify `%s` in `%s` function\", toChars(), MODtoChars(type.mod));\n                            return new ErrorExp();\n                        }\n                    }\n                }\n                error(\"cannot modify `%s` expression `%s`\", MODtoChars(type.mod), toChars());\n                return new ErrorExp();\n            }\n            else if (!type.isAssignable())\n            {\n                error(\"cannot modify struct instance `%s` of type `%s` because it contains `const` or `immutable` members\",\n                    toChars(), type.toChars());\n                return new ErrorExp();\n            }\n        }\n        return toLvalue(sc, e);\n    }\n\n    final Expression implicitCastTo(Scope* sc, Type t)\n    {\n        return .implicitCastTo(this, sc, t);\n    }\n\n    final MATCH implicitConvTo(Type t)\n    {\n        return .implicitConvTo(this, t);\n    }\n\n    final Expression castTo(Scope* sc, Type t)\n    {\n        return .castTo(this, sc, t);\n    }\n\n    /****************************************\n     * Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__, __FILE_FULL_PATH__ to loc.\n     */\n    Expression resolveLoc(const ref Loc loc, Scope* sc)\n    {\n        this.loc = loc;\n        return this;\n    }\n\n    /****************************************\n     * Check that the expression has a valid type.\n     * If not, generates an error \"... has no type\".\n     * Returns:\n     *      true if the expression is not valid.\n     * Note:\n     *      When this function returns true, `checkValue()` should also return true.\n     */\n    bool checkType()\n    {\n        return false;\n    }\n\n    /****************************************\n     * Check that the expression has a valid value.\n     * If not, generates an error \"... has no value\".\n     * Returns:\n     *      true if the expression is not valid or has void type.\n     */\n    bool checkValue()\n    {\n        if (type && type.toBasetype().ty == Tvoid)\n        {\n            error(\"expression `%s` is `void` and has no value\", toChars());\n            //print(); assert(0);\n            if (!global.gag)\n                type = Type.terror;\n            return true;\n        }\n        return false;\n    }\n\n    extern (D) final bool checkScalar()\n    {\n        if (op == TOK.error)\n            return true;\n        if (type.toBasetype().ty == Terror)\n            return true;\n        if (!type.isscalar())\n        {\n            error(\"`%s` is not a scalar, it is a `%s`\", toChars(), type.toChars());\n            return true;\n        }\n        return checkValue();\n    }\n\n    extern (D) final bool checkNoBool()\n    {\n        if (op == TOK.error)\n            return true;\n        if (type.toBasetype().ty == Terror)\n            return true;\n        if (type.toBasetype().ty == Tbool)\n        {\n            error(\"operation not allowed on `bool` `%s`\", toChars());\n            return true;\n        }\n        return false;\n    }\n\n    extern (D) final bool checkIntegral()\n    {\n        if (op == TOK.error)\n            return true;\n        if (type.toBasetype().ty == Terror)\n            return true;\n        if (!type.isintegral())\n        {\n            error(\"`%s` is not of integral type, it is a `%s`\", toChars(), type.toChars());\n            return true;\n        }\n        return checkValue();\n    }\n\n    extern (D) final bool checkArithmetic()\n    {\n        if (op == TOK.error)\n            return true;\n        if (type.toBasetype().ty == Terror)\n            return true;\n        if (!type.isintegral() && !type.isfloating())\n        {\n            error(\"`%s` is not of arithmetic type, it is a `%s`\", toChars(), type.toChars());\n            return true;\n        }\n        return checkValue();\n    }\n\n    final bool checkDeprecated(Scope* sc, Dsymbol s)\n    {\n        return s.checkDeprecated(loc, sc);\n    }\n\n    extern (D) final bool checkDisabled(Scope* sc, Dsymbol s)\n    {\n        if (auto d = s.isDeclaration())\n        {\n            return d.checkDisabled(loc, sc);\n        }\n\n        return false;\n    }\n\n    /*********************************************\n     * Calling function f.\n     * Check the purity, i.e. if we're in a pure function\n     * we can only call other pure functions.\n     * Returns true if error occurs.\n     */\n    extern (D) final bool checkPurity(Scope* sc, FuncDeclaration f)\n    {\n        if (!sc.func)\n            return false;\n        if (sc.func == f)\n            return false;\n        if (sc.intypeof == 1)\n            return false;\n        if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))\n            return false;\n\n        /* Given:\n         * void f() {\n         *   pure void g() {\n         *     /+pure+/ void h() {\n         *       /+pure+/ void i() { }\n         *     }\n         *   }\n         * }\n         * g() can call h() but not f()\n         * i() can call h() and g() but not f()\n         */\n\n        // Find the closest pure parent of the calling function\n        FuncDeclaration outerfunc = sc.func;\n        FuncDeclaration calledparent = f;\n\n        if (outerfunc.isInstantiated())\n        {\n            // The attributes of outerfunc should be inferred from the call of f.\n        }\n        else if (f.isInstantiated())\n        {\n            // The attributes of f are inferred from its body.\n        }\n        else if (f.isFuncLiteralDeclaration())\n        {\n            // The attributes of f are always inferred in its declared place.\n        }\n        else\n        {\n            /* Today, static local functions are impure by default, but they cannot\n             * violate purity of enclosing functions.\n             *\n             *  auto foo() pure {      // non instantiated function\n             *    static auto bar() {  // static, without pure attribute\n             *      impureFunc();      // impure call\n             *      // Although impureFunc is called inside bar, f(= impureFunc)\n             *      // is not callable inside pure outerfunc(= foo <- bar).\n             *    }\n             *\n             *    bar();\n             *    // Although bar is called inside foo, f(= bar) is callable\n             *    // bacause calledparent(= foo) is same with outerfunc(= foo).\n             *  }\n             */\n\n            while (outerfunc.toParent2() && outerfunc.isPureBypassingInference() == PURE.impure && outerfunc.toParent2().isFuncDeclaration())\n            {\n                outerfunc = outerfunc.toParent2().isFuncDeclaration();\n                if (outerfunc.type.ty == Terror)\n                    return true;\n            }\n            while (calledparent.toParent2() && calledparent.isPureBypassingInference() == PURE.impure && calledparent.toParent2().isFuncDeclaration())\n            {\n                calledparent = calledparent.toParent2().isFuncDeclaration();\n                if (calledparent.type.ty == Terror)\n                    return true;\n            }\n        }\n\n        // If the caller has a pure parent, then either the called func must be pure,\n        // OR, they must have the same pure parent.\n        if (!f.isPure() && calledparent != outerfunc)\n        {\n            FuncDeclaration ff = outerfunc;\n            if (sc.flags & SCOPE.compile ? ff.isPureBypassingInference() >= PURE.weak : ff.setImpure())\n            {\n                error(\"`pure` %s `%s` cannot call impure %s `%s`\",\n                    ff.kind(), ff.toPrettyChars(), f.kind(), f.toPrettyChars());\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /*******************************************\n     * Accessing variable v.\n     * Check for purity and safety violations.\n     * Returns true if error occurs.\n     */\n    extern (D) final bool checkPurity(Scope* sc, VarDeclaration v)\n    {\n        //printf(\"v = %s %s\\n\", v.type.toChars(), v.toChars());\n        /* Look for purity and safety violations when accessing variable v\n         * from current function.\n         */\n        if (!sc.func)\n            return false;\n        if (sc.intypeof == 1)\n            return false; // allow violations inside typeof(expression)\n        if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))\n            return false; // allow violations inside compile-time evaluated expressions and debug conditionals\n        if (v.ident == Id.ctfe)\n            return false; // magic variable never violates pure and safe\n        if (v.isImmutable())\n            return false; // always safe and pure to access immutables...\n        if (v.isConst() && !v.isRef() && (v.isDataseg() || v.isParameter()) && v.type.implicitConvTo(v.type.immutableOf()))\n            return false; // or const global/parameter values which have no mutable indirections\n        if (v.storage_class & STC.manifest)\n            return false; // ...or manifest constants\n\n        if (v.type.ty == Tstruct)\n        {\n            StructDeclaration sd = (cast(TypeStruct)v.type).sym;\n            if (sd.hasNoFields)\n                return false;\n        }\n\n        bool err = false;\n        if (v.isDataseg())\n        {\n            // https://issues.dlang.org/show_bug.cgi?id=7533\n            // Accessing implicit generated __gate is pure.\n            if (v.ident == Id.gate)\n                return false;\n\n            /* Accessing global mutable state.\n             * Therefore, this function and all its immediately enclosing\n             * functions must be pure.\n             */\n            /* Today, static local functions are impure by default, but they cannot\n             * violate purity of enclosing functions.\n             *\n             *  auto foo() pure {      // non instantiated function\n             *    static auto bar() {  // static, without pure attribute\n             *      globalData++;      // impure access\n             *      // Although globalData is accessed inside bar,\n             *      // it is not accessible inside pure foo.\n             *    }\n             *  }\n             */\n            for (Dsymbol s = sc.func; s; s = s.toParent2())\n            {\n                FuncDeclaration ff = s.isFuncDeclaration();\n                if (!ff)\n                    break;\n                if (sc.flags & SCOPE.compile ? ff.isPureBypassingInference() >= PURE.weak : ff.setImpure())\n                {\n                    error(\"`pure` %s `%s` cannot access mutable static data `%s`\",\n                        ff.kind(), ff.toPrettyChars(), v.toChars());\n                    err = true;\n                    break;\n                }\n\n                /* If the enclosing is an instantiated function or a lambda, its\n                 * attribute inference result is preferred.\n                 */\n                if (ff.isInstantiated())\n                    break;\n                if (ff.isFuncLiteralDeclaration())\n                    break;\n            }\n        }\n        else\n        {\n            /* Given:\n             * void f() {\n             *   int fx;\n             *   pure void g() {\n             *     int gx;\n             *     /+pure+/ void h() {\n             *       int hx;\n             *       /+pure+/ void i() { }\n             *     }\n             *   }\n             * }\n             * i() can modify hx and gx but not fx\n             */\n\n            Dsymbol vparent = v.toParent2();\n            for (Dsymbol s = sc.func; !err && s; s = s.toParent2())\n            {\n                if (s == vparent)\n                    break;\n\n                if (AggregateDeclaration ad = s.isAggregateDeclaration())\n                {\n                    if (ad.isNested())\n                        continue;\n                    break;\n                }\n                FuncDeclaration ff = s.isFuncDeclaration();\n                if (!ff)\n                    break;\n                if (ff.isNested() || ff.isThis())\n                {\n                    if (ff.type.isImmutable() ||\n                        ff.type.isShared() && !MODimplicitConv(ff.type.mod, v.type.mod))\n                    {\n                        OutBuffer ffbuf;\n                        OutBuffer vbuf;\n                        MODMatchToBuffer(&ffbuf, ff.type.mod, v.type.mod);\n                        MODMatchToBuffer(&vbuf, v.type.mod, ff.type.mod);\n                        error(\"%s%s `%s` cannot access %sdata `%s`\",\n                            ffbuf.peekString(), ff.kind(), ff.toPrettyChars(), vbuf.peekString(), v.toChars());\n                        err = true;\n                        break;\n                    }\n                    continue;\n                }\n                break;\n            }\n        }\n\n        /* Do not allow safe functions to access __gshared data\n         */\n        if (v.storage_class & STC.gshared)\n        {\n            if (sc.func.setUnsafe())\n            {\n                error(\"`@safe` %s `%s` cannot access `__gshared` data `%s`\",\n                    sc.func.kind(), sc.func.toChars(), v.toChars());\n                err = true;\n            }\n        }\n\n        return err;\n    }\n\n    /*********************************************\n     * Calling function f.\n     * Check the safety, i.e. if we're in a @safe function\n     * we can only call @safe or @trusted functions.\n     * Returns true if error occurs.\n     */\n    extern (D) final bool checkSafety(Scope* sc, FuncDeclaration f)\n    {\n        if (!sc.func)\n            return false;\n        if (sc.func == f)\n            return false;\n        if (sc.intypeof == 1)\n            return false;\n        if (sc.flags & SCOPE.ctfe)\n            return false;\n\n        if (!f.isSafe() && !f.isTrusted())\n        {\n            if (sc.flags & SCOPE.compile ? sc.func.isSafeBypassingInference() : sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n            {\n                if (!loc.isValid()) // e.g. implicitly generated dtor\n                    loc = sc.func.loc;\n\n                const prettyChars = f.toPrettyChars();\n                error(\"`@safe` %s `%s` cannot call `@system` %s `%s`\",\n                    sc.func.kind(), sc.func.toPrettyChars(), f.kind(),\n                    prettyChars);\n                .errorSupplemental(f.loc, \"`%s` is declared here\", prettyChars);\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /*********************************************\n     * Calling function f.\n     * Check the @nogc-ness, i.e. if we're in a @nogc function\n     * we can only call other @nogc functions.\n     * Returns true if error occurs.\n     */\n    extern (D) final bool checkNogc(Scope* sc, FuncDeclaration f)\n    {\n        if (!sc.func)\n            return false;\n        if (sc.func == f)\n            return false;\n        if (sc.intypeof == 1)\n            return false;\n        if (sc.flags & SCOPE.ctfe)\n            return false;\n\n        if (!f.isNogc())\n        {\n            if (sc.flags & SCOPE.compile ? sc.func.isNogcBypassingInference() : sc.func.setGC() && !(sc.flags & SCOPE.debug_))\n            {\n                if (loc.linnum == 0) // e.g. implicitly generated dtor\n                    loc = sc.func.loc;\n                error(\"`@nogc` %s `%s` cannot call non-@nogc %s `%s`\",\n                    sc.func.kind(), sc.func.toPrettyChars(), f.kind(), f.toPrettyChars());\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /********************************************\n     * Check that the postblit is callable if t is an array of structs.\n     * Returns true if error happens.\n     */\n    extern (D) final bool checkPostblit(Scope* sc, Type t)\n    {\n        t = t.baseElemOf();\n        if (t.ty == Tstruct)\n        {\n            // https://issues.dlang.org/show_bug.cgi?id=11395\n            // Require TypeInfo generation for array concatenation\n            semanticTypeInfo(sc, t);\n\n            StructDeclaration sd = (cast(TypeStruct)t).sym;\n            if (sd.postblit)\n            {\n                if (sd.postblit.checkDisabled(loc, sc))\n                    return true;\n\n                //checkDeprecated(sc, sd.postblit);        // necessary?\n                checkPurity(sc, sd.postblit);\n                checkSafety(sc, sd.postblit);\n                checkNogc(sc, sd.postblit);\n                //checkAccess(sd, loc, sc, sd.postblit);   // necessary?\n                return false;\n            }\n        }\n        return false;\n    }\n\n    extern (D) final bool checkRightThis(Scope* sc)\n    {\n        if (op == TOK.error)\n            return true;\n        if (op == TOK.variable && type.ty != Terror)\n        {\n            VarExp ve = cast(VarExp)this;\n            if (isNeedThisScope(sc, ve.var))\n            {\n                //printf(\"checkRightThis sc.intypeof = %d, ad = %p, func = %p, fdthis = %p\\n\",\n                //        sc.intypeof, sc.getStructClassScope(), func, fdthis);\n                error(\"need `this` for `%s` of type `%s`\", ve.var.toChars(), ve.var.type.toChars());\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /*******************************\n     * Check whether the expression allows RMW operations, error with rmw operator diagnostic if not.\n     * ex is the RHS expression, or NULL if ++/-- is used (for diagnostics)\n     * Returns true if error occurs.\n     */\n    extern (D) final bool checkReadModifyWrite(TOK rmwOp, Expression ex = null)\n    {\n        //printf(\"Expression::checkReadModifyWrite() %s %s\", toChars(), ex ? ex.toChars() : \"\");\n        if (!type || !type.isShared())\n            return false;\n\n        // atomicOp uses opAssign (+=/-=) rather than opOp (++/--) for the CT string literal.\n        switch (rmwOp)\n        {\n        case TOK.plusPlus:\n        case TOK.prePlusPlus:\n            rmwOp = TOK.addAssign;\n            break;\n        case TOK.minusMinus:\n        case TOK.preMinusMinus:\n            rmwOp = TOK.minAssign;\n            break;\n        default:\n            break;\n        }\n\n        error(\"read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\\\"%s\\\"(%s, %s)` instead.\", Token.toChars(rmwOp), toChars(), ex ? ex.toChars() : \"1\");\n\n         return true;\n    }\n\n    /***************************************\n     * Parameters:\n     *      sc:     scope\n     *      flag:   1: do not issue error message for invalid modification\n     * Returns:\n     *      0:      is not modifiable\n     *      1:      is modifiable in default == being related to type.isMutable()\n     *      2:      is modifiable, because this is a part of initializing.\n     */\n    int checkModifiable(Scope* sc, int flag = 0)\n    {\n        return type ? 1 : 0; // default modifiable\n    }\n\n    /*****************************\n     * If expression can be tested for true or false,\n     * returns the modified expression.\n     * Otherwise returns ErrorExp.\n     */\n    Expression toBoolean(Scope* sc)\n    {\n        // Default is 'yes' - do nothing\n        Expression e = this;\n        Type t = type;\n        Type tb = type.toBasetype();\n        Type att = null;\n    Lagain:\n        // Structs can be converted to bool using opCast(bool)()\n        if (tb.ty == Tstruct)\n        {\n            AggregateDeclaration ad = (cast(TypeStruct)tb).sym;\n            /* Don't really need to check for opCast first, but by doing so we\n             * get better error messages if it isn't there.\n             */\n            Dsymbol fd = search_function(ad, Id._cast);\n            if (fd)\n            {\n                e = new CastExp(loc, e, Type.tbool);\n                e = e.expressionSemantic(sc);\n                return e;\n            }\n\n            // Forward to aliasthis.\n            if (ad.aliasthis && tb != att)\n            {\n                if (!att && tb.checkAliasThisRec())\n                    att = tb;\n                e = resolveAliasThis(sc, e);\n                t = e.type;\n                tb = e.type.toBasetype();\n                goto Lagain;\n            }\n        }\n\n        if (!t.isBoolean())\n        {\n            if (tb != Type.terror)\n                error(\"expression `%s` of type `%s` does not have a boolean value\", toChars(), t.toChars());\n            return new ErrorExp();\n        }\n        return e;\n    }\n\n    /************************************************\n     * Destructors are attached to VarDeclarations.\n     * Hence, if expression returns a temp that needs a destructor,\n     * make sure and create a VarDeclaration for that temp.\n     */\n    Expression addDtorHook(Scope* sc)\n    {\n        return this;\n    }\n\n    /******************************\n     * Take address of expression.\n     */\n    final Expression addressOf()\n    {\n        //printf(\"Expression::addressOf()\\n\");\n        debug\n        {\n            assert(op == TOK.error || isLvalue());\n        }\n        Expression e = new AddrExp(loc, this);\n        e.type = type.pointerTo();\n        return e;\n    }\n\n    /******************************\n     * If this is a reference, dereference it.\n     */\n    final Expression deref()\n    {\n        //printf(\"Expression::deref()\\n\");\n        // type could be null if forward referencing an 'auto' variable\n        if (type && type.ty == Treference)\n        {\n            Expression e = new PtrExp(loc, this);\n            e.type = (cast(TypeReference)type).next;\n            return e;\n        }\n        return this;\n    }\n\n    final Expression optimize(int result, bool keepLvalue = false)\n    {\n        return Expression_optimize(this, result, keepLvalue);\n    }\n\n    // Entry point for CTFE.\n    // A compile-time result is required. Give an error if not possible\n    final Expression ctfeInterpret()\n    {\n        return .ctfeInterpret(this);\n    }\n\n    final int isConst()\n    {\n        return .isConst(this);\n    }\n\n    /********************************\n     * Does this expression statically evaluate to a boolean 'result' (true or false)?\n     */\n    bool isBool(bool result)\n    {\n        return false;\n    }\n\n    bool hasCode()\n    {\n        return true;\n    }\n\n    void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class IntegerExp : Expression\n{\n    private dinteger_t value;\n\n    extern (D) this(const ref Loc loc, dinteger_t value, Type type)\n    {\n        super(loc, TOK.int64, __traits(classInstanceSize, IntegerExp));\n        //printf(\"IntegerExp(value = %lld, type = '%s')\\n\", value, type ? type.toChars() : \"\");\n        assert(type);\n        if (!type.isscalar())\n        {\n            //printf(\"%s, loc = %d\\n\", toChars(), loc.linnum);\n            if (type.ty != Terror)\n                error(\"integral constant must be scalar type, not `%s`\", type.toChars());\n            type = Type.terror;\n        }\n        this.type = type;\n        this.value = normalize(type.toBasetype().ty, value);\n    }\n\n    extern (D) this(dinteger_t value)\n    {\n        super(Loc.initial, TOK.int64, __traits(classInstanceSize, IntegerExp));\n        this.type = Type.tint32;\n        this.value = cast(d_int32)value;\n    }\n\n    static IntegerExp create(Loc loc, dinteger_t value, Type type)\n    {\n        return new IntegerExp(loc, value, type);\n    }\n\n    static IntegerExp createi(Loc loc, int value, Type type)\n    {\n        return new IntegerExp(loc, value, type);\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n        if ((cast(Expression)o).op == TOK.int64)\n        {\n            IntegerExp ne = cast(IntegerExp)o;\n            if (type.toHeadMutable().equals(ne.type.toHeadMutable()) && value == ne.value)\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    override dinteger_t toInteger()\n    {\n        // normalize() is necessary until we fix all the paints of 'type'\n        return value = normalize(type.toBasetype().ty, value);\n    }\n\n    override real_t toReal()\n    {\n        // normalize() is necessary until we fix all the paints of 'type'\n        const ty = type.toBasetype().ty;\n        const val = normalize(ty, value);\n        value = val;\n        return (ty == Tuns64)\n            ? real_t(cast(d_uns64)val)\n            : real_t(cast(d_int64)val);\n    }\n\n    override real_t toImaginary()\n    {\n        return CTFloat.zero;\n    }\n\n    override complex_t toComplex()\n    {\n        return complex_t(toReal());\n    }\n\n    override bool isBool(bool result)\n    {\n        bool r = toInteger() != 0;\n        return result ? r : !r;\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        if (!e)\n            e = this;\n        else if (!loc.isValid())\n            loc = e.loc;\n        e.error(\"cannot modify constant `%s`\", e.toChars());\n        return new ErrorExp();\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    dinteger_t getInteger()\n    {\n        return value;\n    }\n\n    void setInteger(dinteger_t value)\n    {\n        this.value = normalize(type.toBasetype().ty, value);\n    }\n\n    static dinteger_t normalize(TY ty, dinteger_t value)\n    {\n        /* 'Normalize' the value of the integer to be in range of the type\n         */\n        dinteger_t result;\n        switch (ty)\n        {\n        case Tbool:\n            result = (value != 0);\n            break;\n\n        case Tint8:\n            result = cast(d_int8)value;\n            break;\n\n        case Tchar:\n        case Tuns8:\n            result = cast(d_uns8)value;\n            break;\n\n        case Tint16:\n            result = cast(d_int16)value;\n            break;\n\n        case Twchar:\n        case Tuns16:\n            result = cast(d_uns16)value;\n            break;\n\n        case Tint32:\n            result = cast(d_int32)value;\n            break;\n\n        case Tdchar:\n        case Tuns32:\n            result = cast(d_uns32)value;\n            break;\n\n        case Tint64:\n            result = cast(d_int64)value;\n            break;\n\n        case Tuns64:\n            result = cast(d_uns64)value;\n            break;\n\n        case Tpointer:\n            if (Target.ptrsize == 4)\n                result = cast(d_uns32)value;\n            else if (Target.ptrsize == 8)\n                result = cast(d_uns64)value;\n            else\n                assert(0);\n            break;\n\n        default:\n            break;\n        }\n        return result;\n    }\n}\n\n/***********************************************************\n * Use this expression for error recovery.\n * It should behave as a 'sink' to prevent further cascaded error messages.\n */\nextern (C++) final class ErrorExp : Expression\n{\n    extern (D) this()\n    {\n        super(Loc.initial, TOK.error, __traits(classInstanceSize, ErrorExp));\n        type = Type.terror;\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    extern (C++) __gshared ErrorExp errorexp; // handy shared value\n}\n\n\n/***********************************************************\n * An uninitialized value,\n * generated from void initializers.\n */\nextern (C++) final class VoidInitExp : Expression\n{\n    VarDeclaration var; /// the variable from where the void value came from, null if not known\n                        /// Useful for error messages\n\n    extern (D) this(VarDeclaration var)\n    {\n        super(var.loc, TOK.void_, __traits(classInstanceSize, VoidInitExp));\n        this.var = var;\n        this.type = var.type;\n    }\n\n    override const(char)* toChars() const\n    {\n        return \"void\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n\n/***********************************************************\n */\nextern (C++) final class RealExp : Expression\n{\n    real_t value;\n\n    extern (D) this(const ref Loc loc, real_t value, Type type)\n    {\n        super(loc, TOK.float64, __traits(classInstanceSize, RealExp));\n        //printf(\"RealExp::RealExp(%Lg)\\n\", value);\n        this.value = value;\n        this.type = type;\n    }\n\n    static RealExp create(Loc loc, real_t value, Type type)\n    {\n        return new RealExp(loc, value, type);\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n        if ((cast(Expression)o).op == TOK.float64)\n        {\n            RealExp ne = cast(RealExp)o;\n            if (type.toHeadMutable().equals(ne.type.toHeadMutable()) && RealEquals(value, ne.value))\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    override dinteger_t toInteger()\n    {\n        return cast(sinteger_t)toReal();\n    }\n\n    override uinteger_t toUInteger()\n    {\n        return cast(uinteger_t)toReal();\n    }\n\n    override real_t toReal()\n    {\n        return type.isreal() ? value : CTFloat.zero;\n    }\n\n    override real_t toImaginary()\n    {\n        return type.isreal() ? CTFloat.zero : value;\n    }\n\n    override complex_t toComplex()\n    {\n        return complex_t(toReal(), toImaginary());\n    }\n\n    override bool isBool(bool result)\n    {\n        return result ? cast(bool)value : !cast(bool)value;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ComplexExp : Expression\n{\n    complex_t value;\n\n    extern (D) this(const ref Loc loc, complex_t value, Type type)\n    {\n        super(loc, TOK.complex80, __traits(classInstanceSize, ComplexExp));\n        this.value = value;\n        this.type = type;\n        //printf(\"ComplexExp::ComplexExp(%s)\\n\", toChars());\n    }\n\n    static ComplexExp create(Loc loc, complex_t value, Type type)\n    {\n        return new ComplexExp(loc, value, type);\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n        if ((cast(Expression)o).op == TOK.complex80)\n        {\n            ComplexExp ne = cast(ComplexExp)o;\n            if (type.toHeadMutable().equals(ne.type.toHeadMutable()) && RealEquals(creall(value), creall(ne.value)) && RealEquals(cimagl(value), cimagl(ne.value)))\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    override dinteger_t toInteger()\n    {\n        return cast(sinteger_t)toReal();\n    }\n\n    override uinteger_t toUInteger()\n    {\n        return cast(uinteger_t)toReal();\n    }\n\n    override real_t toReal()\n    {\n        return creall(value);\n    }\n\n    override real_t toImaginary()\n    {\n        return cimagl(value);\n    }\n\n    override complex_t toComplex()\n    {\n        return value;\n    }\n\n    override bool isBool(bool result)\n    {\n        if (result)\n            return cast(bool)value;\n        else\n            return !value;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class IdentifierExp : Expression\n{\n    Identifier ident;\n\n    extern (D) this(const ref Loc loc, Identifier ident)\n    {\n        super(loc, TOK.identifier, __traits(classInstanceSize, IdentifierExp));\n        this.ident = ident;\n    }\n\n    static IdentifierExp create(Loc loc, Identifier ident)\n    {\n        return new IdentifierExp(loc, ident);\n    }\n\n    override final bool isLvalue()\n    {\n        return true;\n    }\n\n    override final Expression toLvalue(Scope* sc, Expression e)\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DollarExp : IdentifierExp\n{\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc, Id.dollar);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Won't be generated by parser.\n */\nextern (C++) final class DsymbolExp : Expression\n{\n    Dsymbol s;\n    bool hasOverloads;\n\n    extern (D) this(const ref Loc loc, Dsymbol s, bool hasOverloads = true)\n    {\n        super(loc, TOK.dSymbol, __traits(classInstanceSize, DsymbolExp));\n        this.s = s;\n        this.hasOverloads = hasOverloads;\n    }\n\n    override bool isLvalue()\n    {\n        return true;\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#this\n */\nextern (C++) class ThisExp : Expression\n{\n    VarDeclaration var;\n\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc, TOK.this_, __traits(classInstanceSize, ThisExp));\n        //printf(\"ThisExp::ThisExp() loc = %d\\n\", loc.linnum);\n    }\n\n    override final bool isBool(bool result)\n    {\n        return result ? true : false;\n    }\n\n    override final bool isLvalue()\n    {\n        // Class `this` should be an rvalue; struct `this` should be an lvalue.\n        return type.toBasetype().ty != Tclass;\n    }\n\n    override final Expression toLvalue(Scope* sc, Expression e)\n    {\n        if (type.toBasetype().ty == Tclass)\n        {\n            // Class `this` is an rvalue; struct `this` is an lvalue.\n            return Expression.toLvalue(sc, e);\n        }\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#super\n */\nextern (C++) final class SuperExp : ThisExp\n{\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc);\n        op = TOK.super_;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#null\n */\nextern (C++) final class NullExp : Expression\n{\n    ubyte committed;    // !=0 if type is committed\n\n    extern (D) this(const ref Loc loc, Type type = null)\n    {\n        super(loc, TOK.null_, __traits(classInstanceSize, NullExp));\n        this.type = type;\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (o && o.dyncast() == DYNCAST.expression)\n        {\n            Expression e = cast(Expression)o;\n            if (e.op == TOK.null_ && type.equals(e.type))\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    override bool isBool(bool result)\n    {\n        return result ? false : true;\n    }\n\n    override StringExp toStringExp()\n    {\n        if (implicitConvTo(Type.tstring))\n        {\n            auto se = new StringExp(loc, cast(char*)mem.xcalloc(1, 1), 0);\n            se.type = Type.tstring;\n            return se;\n        }\n        return null;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#string_literals\n */\nextern (C++) final class StringExp : Expression\n{\n    union\n    {\n        char* string;   // if sz == 1\n        wchar* wstring; // if sz == 2\n        dchar* dstring; // if sz == 4\n    }                   // (const if ownedByCtfe == OwnedBy.code)\n    size_t len;         // number of code units\n    ubyte sz = 1;       // 1: char, 2: wchar, 4: dchar\n    ubyte committed;    // !=0 if type is committed\n    char postfix = 0;   // 'c', 'w', 'd'\n    OwnedBy ownedByCtfe = OwnedBy.code;\n\n    extern (D) this(const ref Loc loc, char* string)\n    {\n        super(loc, TOK.string_, __traits(classInstanceSize, StringExp));\n        this.string = string;\n        this.len = strlen(string);\n        this.sz = 1;                    // work around LDC bug #1286\n    }\n\n    extern (D) this(const ref Loc loc, void* string, size_t len)\n    {\n        super(loc, TOK.string_, __traits(classInstanceSize, StringExp));\n        this.string = cast(char*)string;\n        this.len = len;\n        this.sz = 1;                    // work around LDC bug #1286\n    }\n\n    extern (D) this(const ref Loc loc, void* string, size_t len, char postfix)\n    {\n        super(loc, TOK.string_, __traits(classInstanceSize, StringExp));\n        this.string = cast(char*)string;\n        this.len = len;\n        this.postfix = postfix;\n        this.sz = 1;                    // work around LDC bug #1286\n    }\n\n    static StringExp create(Loc loc, char* s)\n    {\n        return new StringExp(loc, s);\n    }\n\n    static StringExp create(Loc loc, void* string, size_t len)\n    {\n        return new StringExp(loc, string, len);\n    }\n\n    override bool equals(RootObject o)\n    {\n        //printf(\"StringExp::equals('%s') %s\\n\", o.toChars(), toChars());\n        if (o && o.dyncast() == DYNCAST.expression)\n        {\n            Expression e = cast(Expression)o;\n            if (e.op == TOK.string_)\n            {\n                return compare(o) == 0;\n            }\n        }\n        return false;\n    }\n\n    /**********************************\n     * Return the number of code units the string would be if it were re-encoded\n     * as tynto.\n     * Params:\n     *      tynto = code unit type of the target encoding\n     * Returns:\n     *      number of code units\n     */\n    final size_t numberOfCodeUnits(int tynto = 0) const\n    {\n        int encSize;\n        switch (tynto)\n        {\n            case 0:      return len;\n            case Tchar:  encSize = 1; break;\n            case Twchar: encSize = 2; break;\n            case Tdchar: encSize = 4; break;\n            default:\n                assert(0);\n        }\n        if (sz == encSize)\n            return len;\n\n        size_t result = 0;\n        dchar c;\n\n        switch (sz)\n        {\n        case 1:\n            for (size_t u = 0; u < len;)\n            {\n                if (const p = utf_decodeChar(string, len, u, c))\n                {\n                    error(\"%s\", p);\n                    return 0;\n                }\n                result += utf_codeLength(encSize, c);\n            }\n            break;\n\n        case 2:\n            for (size_t u = 0; u < len;)\n            {\n                if (const p = utf_decodeWchar(wstring, len, u, c))\n                {\n                    error(\"%s\", p);\n                    return 0;\n                }\n                result += utf_codeLength(encSize, c);\n            }\n            break;\n\n        case 4:\n            foreach (u; 0 .. len)\n            {\n                result += utf_codeLength(encSize, dstring[u]);\n            }\n            break;\n\n        default:\n            assert(0);\n        }\n        return result;\n    }\n\n    /**********************************************\n     * Write the contents of the string to dest.\n     * Use numberOfCodeUnits() to determine size of result.\n     * Params:\n     *  dest = destination\n     *  tyto = encoding type of the result\n     *  zero = add terminating 0\n     */\n    void writeTo(void* dest, bool zero, int tyto = 0) const\n    {\n        int encSize;\n        switch (tyto)\n        {\n            case 0:      encSize = sz; break;\n            case Tchar:  encSize = 1; break;\n            case Twchar: encSize = 2; break;\n            case Tdchar: encSize = 4; break;\n            default:\n                assert(0);\n        }\n        if (sz == encSize)\n        {\n            memcpy(dest, string, len * sz);\n            if (zero)\n                memset(dest + len * sz, 0, sz);\n        }\n        else\n            assert(0);\n    }\n\n    /*********************************************\n     * Get the code unit at index i\n     * Params:\n     *  i = index\n     * Returns:\n     *  code unit at index i\n     */\n    final dchar getCodeUnit(size_t i) const pure\n    {\n        assert(i < len);\n        final switch (sz)\n        {\n        case 1:\n            return string[i];\n        case 2:\n            return wstring[i];\n        case 4:\n            return dstring[i];\n        }\n    }\n\n    /*********************************************\n     * Set the code unit at index i to c\n     * Params:\n     *  i = index\n     *  c = code unit to set it to\n     */\n    final void setCodeUnit(size_t i, dchar c)\n    {\n        assert(i < len);\n        final switch (sz)\n        {\n        case 1:\n            string[i] = cast(char)c;\n            break;\n        case 2:\n            wstring[i] = cast(wchar)c;\n            break;\n        case 4:\n            dstring[i] = c;\n            break;\n        }\n    }\n\n    /**************************************************\n     * If the string data is UTF-8 and can be accessed directly,\n     * return a pointer to it.\n     * Do not assume a terminating 0.\n     * Returns:\n     *  pointer to string data if possible, null if not\n     */\n    char* toPtr()\n    {\n        return (sz == 1) ? string : null;\n    }\n\n    override StringExp toStringExp()\n    {\n        return this;\n    }\n\n    /****************************************\n     * Convert string to char[].\n     */\n    StringExp toUTF8(Scope* sc)\n    {\n        if (sz != 1)\n        {\n            // Convert to UTF-8 string\n            committed = 0;\n            Expression e = castTo(sc, Type.tchar.arrayOf());\n            e = e.optimize(WANTvalue);\n            assert(e.op == TOK.string_);\n            StringExp se = cast(StringExp)e;\n            assert(se.sz == 1);\n            return se;\n        }\n        return this;\n    }\n\n    override int compare(RootObject obj)\n    {\n        //printf(\"StringExp::compare()\\n\");\n        // Used to sort case statement expressions so we can do an efficient lookup\n        StringExp se2 = cast(StringExp)obj;\n\n        // This is a kludge so isExpression() in template.c will return 5\n        // for StringExp's.\n        if (!se2)\n            return 5;\n\n        assert(se2.op == TOK.string_);\n\n        size_t len1 = len;\n        size_t len2 = se2.len;\n\n        //printf(\"sz = %d, len1 = %d, len2 = %d\\n\", sz, (int)len1, (int)len2);\n        if (len1 == len2)\n        {\n            switch (sz)\n            {\n            case 1:\n                return memcmp(string, se2.string, len1);\n\n            case 2:\n                {\n                    wchar* s1 = cast(wchar*)string;\n                    wchar* s2 = cast(wchar*)se2.string;\n                    foreach (u; 0 .. len)\n                    {\n                        if (s1[u] != s2[u])\n                            return s1[u] - s2[u];\n                    }\n                }\n                break;\n            case 4:\n                {\n                    dchar* s1 = cast(dchar*)string;\n                    dchar* s2 = cast(dchar*)se2.string;\n                    foreach (u; 0 .. len)\n                    {\n                        if (s1[u] != s2[u])\n                            return s1[u] - s2[u];\n                    }\n                }\n                break;\n            default:\n                assert(0);\n            }\n        }\n        return cast(int)(len1 - len2);\n    }\n\n    override bool isBool(bool result)\n    {\n        return result ? true : false;\n    }\n\n    override bool isLvalue()\n    {\n        /* string literal is rvalue in default, but\n         * conversion to reference of static array is only allowed.\n         */\n        return (type && type.toBasetype().ty == Tsarray);\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        //printf(\"StringExp::toLvalue(%s) type = %s\\n\", toChars(), type ? type.toChars() : NULL);\n        return (type && type.toBasetype().ty == Tsarray) ? this : Expression.toLvalue(sc, e);\n    }\n\n    override Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        error(\"cannot modify string literal `%s`\", toChars());\n        return new ErrorExp();\n    }\n\n    uint charAt(uinteger_t i) const\n    {\n        uint value;\n        switch (sz)\n        {\n        case 1:\n            value = (cast(char*)string)[cast(size_t)i];\n            break;\n\n        case 2:\n            value = (cast(ushort*)string)[cast(size_t)i];\n            break;\n\n        case 4:\n            value = (cast(uint*)string)[cast(size_t)i];\n            break;\n\n        default:\n            assert(0);\n        }\n        return value;\n    }\n\n    /********************************\n     * Convert string contents to a 0 terminated string,\n     * allocated by mem.xmalloc().\n     */\n    extern (D) final const(char)[] toStringz() const\n    {\n        auto nbytes = len * sz;\n        char* s = cast(char*)mem.xmalloc(nbytes + sz);\n        writeTo(s, true);\n        return s[0 .. nbytes];\n    }\n\n    extern (D) const(char)[] peekSlice() const\n    {\n        assert(sz == 1);\n        return this.string[0 .. len];\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TupleExp : Expression\n{\n    /* Tuple-field access may need to take out its side effect part.\n     * For example:\n     *      foo().tupleof\n     * is rewritten as:\n     *      (ref __tup = foo(); tuple(__tup.field0, __tup.field1, ...))\n     * The declaration of temporary variable __tup will be stored in TupleExp.e0.\n     */\n    Expression e0;\n\n    Expressions* exps;\n\n    extern (D) this(const ref Loc loc, Expression e0, Expressions* exps)\n    {\n        super(loc, TOK.tuple, __traits(classInstanceSize, TupleExp));\n        //printf(\"TupleExp(this = %p)\\n\", this);\n        this.e0 = e0;\n        this.exps = exps;\n    }\n\n    extern (D) this(const ref Loc loc, Expressions* exps)\n    {\n        super(loc, TOK.tuple, __traits(classInstanceSize, TupleExp));\n        //printf(\"TupleExp(this = %p)\\n\", this);\n        this.exps = exps;\n    }\n\n    extern (D) this(const ref Loc loc, TupleDeclaration tup)\n    {\n        super(loc, TOK.tuple, __traits(classInstanceSize, TupleExp));\n        this.exps = new Expressions();\n\n        this.exps.reserve(tup.objects.dim);\n        foreach (o; *tup.objects)\n        {\n            if (Dsymbol s = getDsymbol(o))\n            {\n                /* If tuple element represents a symbol, translate to DsymbolExp\n                 * to supply implicit 'this' if needed later.\n                 */\n                Expression e = new DsymbolExp(loc, s);\n                this.exps.push(e);\n            }\n            else if (o.dyncast() == DYNCAST.expression)\n            {\n                auto e = (cast(Expression)o).copy();\n                e.loc = loc;    // https://issues.dlang.org/show_bug.cgi?id=15669\n                this.exps.push(e);\n            }\n            else if (o.dyncast() == DYNCAST.type)\n            {\n                Type t = cast(Type)o;\n                Expression e = new TypeExp(loc, t);\n                this.exps.push(e);\n            }\n            else\n            {\n                error(\"`%s` is not an expression\", o.toChars());\n            }\n        }\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new TupleExp(loc, e0 ? e0.syntaxCopy() : null, arraySyntaxCopy(exps));\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n        if ((cast(Expression)o).op == TOK.tuple)\n        {\n            TupleExp te = cast(TupleExp)o;\n            if (exps.dim != te.exps.dim)\n                return false;\n            if (e0 && !e0.equals(te.e0) || !e0 && te.e0)\n                return false;\n            foreach (i, e1; *exps)\n            {\n                Expression e2 = (*te.exps)[i];\n                if (!e1.equals(e2))\n                    return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * [ e1, e2, e3, ... ]\n *\n * http://dlang.org/spec/expression.html#array_literals\n */\nextern (C++) final class ArrayLiteralExp : Expression\n{\n    /** If !is null, elements[] can be sparse and basis is used for the\n     * \"default\" element value. In other words, non-null elements[i] overrides\n     * this 'basis' value.\n     */\n    Expression basis;\n\n    Expressions* elements;\n    OwnedBy ownedByCtfe = OwnedBy.code;\n\n\n    extern (D) this(const ref Loc loc, Type type, Expressions* elements)\n    {\n        super(loc, TOK.arrayLiteral, __traits(classInstanceSize, ArrayLiteralExp));\n        this.type = type;\n        this.elements = elements;\n    }\n\n    extern (D) this(const ref Loc loc, Type type, Expression e)\n    {\n        super(loc, TOK.arrayLiteral, __traits(classInstanceSize, ArrayLiteralExp));\n        this.type = type;\n        elements = new Expressions();\n        elements.push(e);\n    }\n\n    extern (D) this(const ref Loc loc, Type type, Expression basis, Expressions* elements)\n    {\n        super(loc, TOK.arrayLiteral, __traits(classInstanceSize, ArrayLiteralExp));\n        this.type = type;\n        this.basis = basis;\n        this.elements = elements;\n    }\n\n    static ArrayLiteralExp create(Loc loc, Expressions* elements)\n    {\n        return new ArrayLiteralExp(loc, null, elements);\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new ArrayLiteralExp(loc,\n            null,\n            basis ? basis.syntaxCopy() : null,\n            arraySyntaxCopy(elements));\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n        if (o && o.dyncast() == DYNCAST.expression && (cast(Expression)o).op == TOK.arrayLiteral)\n        {\n            ArrayLiteralExp ae = cast(ArrayLiteralExp)o;\n            if (elements.dim != ae.elements.dim)\n                return false;\n            if (elements.dim == 0 && !type.equals(ae.type))\n            {\n                return false;\n            }\n            foreach (i, e1; *elements)\n            {\n                Expression e2 = (*ae.elements)[i];\n                if (!e1)\n                    e1 = basis;\n                if (!e2)\n                    e2 = ae.basis;\n                if (e1 != e2 && (!e1 || !e2 || !e1.equals(e2)))\n                    return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    Expression getElement(size_t i)\n    {\n        auto el = (*elements)[i];\n        if (!el)\n            el = basis;\n        return el;\n    }\n\n    override bool isBool(bool result)\n    {\n        size_t dim = elements ? elements.dim : 0;\n        return result ? (dim != 0) : (dim == 0);\n    }\n\n    override StringExp toStringExp()\n    {\n        TY telem = type.nextOf().toBasetype().ty;\n        if (telem == Tchar || telem == Twchar || telem == Tdchar || (telem == Tvoid && (!elements || elements.dim == 0)))\n        {\n            ubyte sz = 1;\n            if (telem == Twchar)\n                sz = 2;\n            else if (telem == Tdchar)\n                sz = 4;\n\n            OutBuffer buf;\n            if (elements)\n            {\n                foreach (i; 0 .. elements.dim)\n                {\n                    auto ch = getElement(i);\n                    if (ch.op != TOK.int64)\n                        return null;\n                    if (sz == 1)\n                        buf.writeByte(cast(uint)ch.toInteger());\n                    else if (sz == 2)\n                        buf.writeword(cast(uint)ch.toInteger());\n                    else\n                        buf.write4(cast(uint)ch.toInteger());\n                }\n            }\n            char prefix;\n            if (sz == 1)\n            {\n                prefix = 'c';\n                buf.writeByte(0);\n            }\n            else if (sz == 2)\n            {\n                prefix = 'w';\n                buf.writeword(0);\n            }\n            else\n            {\n                prefix = 'd';\n                buf.write4(0);\n            }\n\n            const(size_t) len = buf.offset / sz - 1;\n            auto se = new StringExp(loc, buf.extractData(), len, prefix);\n            se.sz = sz;\n            se.type = type;\n            return se;\n        }\n        return null;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * [ key0 : value0, key1 : value1, ... ]\n *\n * http://dlang.org/spec/expression.html#associative_array_literals\n */\nextern (C++) final class AssocArrayLiteralExp : Expression\n{\n    Expressions* keys;\n    Expressions* values;\n\n    OwnedBy ownedByCtfe = OwnedBy.code;\n\n    extern (D) this(const ref Loc loc, Expressions* keys, Expressions* values)\n    {\n        super(loc, TOK.assocArrayLiteral, __traits(classInstanceSize, AssocArrayLiteralExp));\n        assert(keys.dim == values.dim);\n        this.keys = keys;\n        this.values = values;\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n        if (o && o.dyncast() == DYNCAST.expression && (cast(Expression)o).op == TOK.assocArrayLiteral)\n        {\n            AssocArrayLiteralExp ae = cast(AssocArrayLiteralExp)o;\n            if (keys.dim != ae.keys.dim)\n                return false;\n            size_t count = 0;\n            foreach (i, key; *keys)\n            {\n                foreach (j, akey; *ae.keys)\n                {\n                    if (key.equals(akey))\n                    {\n                        if (!(*values)[i].equals((*ae.values)[j]))\n                            return false;\n                        ++count;\n                    }\n                }\n            }\n            return count == keys.dim;\n        }\n        return false;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new AssocArrayLiteralExp(loc, arraySyntaxCopy(keys), arraySyntaxCopy(values));\n    }\n\n    override bool isBool(bool result)\n    {\n        size_t dim = keys.dim;\n        return result ? (dim != 0) : (dim == 0);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\nenum stageScrub             = 0x1;  /// scrubReturnValue is running\nenum stageSearchPointers    = 0x2;  /// hasNonConstPointers is running\nenum stageOptimize          = 0x4;  /// optimize is running\nenum stageApply             = 0x8;  /// apply is running\nenum stageInlineScan        = 0x10; /// inlineScan is running\nenum stageToCBuffer         = 0x20; /// toCBuffer is running\n\n/***********************************************************\n * sd( e1, e2, e3, ... )\n */\nextern (C++) final class StructLiteralExp : Expression\n{\n    StructDeclaration sd;   /// which aggregate this is for\n    Expressions* elements;  /// parallels sd.fields[] with null entries for fields to skip\n    Type stype;             /// final type of result (can be different from sd's type)\n\n    bool useStaticInit;     /// if this is true, use the StructDeclaration's init symbol\n    Symbol* sym;            /// back end symbol to initialize with literal\n\n    OwnedBy ownedByCtfe = OwnedBy.code;\n\n    /** pointer to the origin instance of the expression.\n     * once a new expression is created, origin is set to 'this'.\n     * anytime when an expression copy is created, 'origin' pointer is set to\n     * 'origin' pointer value of the original expression.\n     */\n    StructLiteralExp origin;\n\n    /// those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.\n    StructLiteralExp inlinecopy;\n\n    /** anytime when recursive function is calling, 'stageflags' marks with bit flag of\n     * current stage and unmarks before return from this function.\n     * 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'\n     * (with infinite recursion) of this expression.\n     */\n    int stageflags;\n\n    extern (D) this(const ref Loc loc, StructDeclaration sd, Expressions* elements, Type stype = null)\n    {\n        super(loc, TOK.structLiteral, __traits(classInstanceSize, StructLiteralExp));\n        this.sd = sd;\n        if (!elements)\n            elements = new Expressions();\n        this.elements = elements;\n        this.stype = stype;\n        this.origin = this;\n        //printf(\"StructLiteralExp::StructLiteralExp(%s)\\n\", toChars());\n    }\n\n    static StructLiteralExp create(Loc loc, StructDeclaration sd, void* elements, Type stype = null)\n    {\n        return new StructLiteralExp(loc, sd, cast(Expressions*)elements, stype);\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n        if (o && o.dyncast() == DYNCAST.expression && (cast(Expression)o).op == TOK.structLiteral)\n        {\n            StructLiteralExp se = cast(StructLiteralExp)o;\n            if (!type.equals(se.type))\n                return false;\n            if (elements.dim != se.elements.dim)\n                return false;\n            foreach (i, e1; *elements)\n            {\n                Expression e2 = (*se.elements)[i];\n                if (e1 != e2 && (!e1 || !e2 || !e1.equals(e2)))\n                    return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    override Expression syntaxCopy()\n    {\n        auto exp = new StructLiteralExp(loc, sd, arraySyntaxCopy(elements), type ? type : stype);\n        exp.origin = this;\n        return exp;\n    }\n\n    /**************************************\n     * Gets expression at offset of type.\n     * Returns NULL if not found.\n     */\n    Expression getField(Type type, uint offset)\n    {\n        //printf(\"StructLiteralExp::getField(this = %s, type = %s, offset = %u)\\n\",\n        //  /*toChars()*/\"\", type.toChars(), offset);\n        Expression e = null;\n        int i = getFieldIndex(type, offset);\n\n        if (i != -1)\n        {\n            //printf(\"\\ti = %d\\n\", i);\n            if (i == sd.fields.dim - 1 && sd.isNested())\n                return null;\n\n            assert(i < elements.dim);\n            e = (*elements)[i];\n            if (e)\n            {\n                //printf(\"e = %s, e.type = %s\\n\", e.toChars(), e.type.toChars());\n\n                /* If type is a static array, and e is an initializer for that array,\n                 * then the field initializer should be an array literal of e.\n                 */\n                if (e.type.castMod(0) != type.castMod(0) && type.ty == Tsarray)\n                {\n                    TypeSArray tsa = cast(TypeSArray)type;\n                    size_t length = cast(size_t)tsa.dim.toInteger();\n                    auto z = new Expressions(length);\n                    foreach (ref q; *z)\n                        q = e.copy();\n                    e = new ArrayLiteralExp(loc, type, z);\n                }\n                else\n                {\n                    e = e.copy();\n                    e.type = type;\n                }\n                if (useStaticInit && e.op == TOK.structLiteral && e.type.needsNested())\n                {\n                    StructLiteralExp se = cast(StructLiteralExp)e;\n                    se.useStaticInit = true;\n                }\n            }\n        }\n        return e;\n    }\n\n    /************************************\n     * Get index of field.\n     * Returns -1 if not found.\n     */\n    int getFieldIndex(Type type, uint offset)\n    {\n        /* Find which field offset is by looking at the field offsets\n         */\n        if (elements.dim)\n        {\n            foreach (i, v; sd.fields)\n            {\n                if (offset == v.offset && type.size() == v.type.size())\n                {\n                    /* context field might not be filled. */\n                    if (i == sd.fields.dim - 1 && sd.isNested())\n                        return cast(int)i;\n                    Expression e = (*elements)[i];\n                    if (e)\n                    {\n                        return cast(int)i;\n                    }\n                    break;\n                }\n            }\n        }\n        return -1;\n    }\n\n    override Expression addDtorHook(Scope* sc)\n    {\n        /* If struct requires a destructor, rewrite as:\n         *    (S tmp = S()),tmp\n         * so that the destructor can be hung on tmp.\n         */\n        if (sd.dtor && sc.func)\n        {\n            /* Make an identifier for the temporary of the form:\n             *   __sl%s%d, where %s is the struct name\n             */\n            const(size_t) len = 10;\n            char[len + 1] buf;\n            buf[len] = 0;\n            strcpy(buf.ptr, \"__sl\");\n            strncat(buf.ptr, sd.ident.toChars(), len - 4 - 1);\n            assert(buf[len] == 0);\n\n            auto tmp = copyToTemp(0, buf.ptr, this);\n            Expression ae = new DeclarationExp(loc, tmp);\n            Expression e = new CommaExp(loc, ae, new VarExp(loc, tmp));\n            e = e.expressionSemantic(sc);\n            return e;\n        }\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Mainly just a placeholder\n */\nextern (C++) final class TypeExp : Expression\n{\n    extern (D) this(const ref Loc loc, Type type)\n    {\n        super(loc, TOK.type, __traits(classInstanceSize, TypeExp));\n        //printf(\"TypeExp::TypeExp(%s)\\n\", type.toChars());\n        this.type = type;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new TypeExp(loc, type.syntaxCopy());\n    }\n\n    override bool checkType()\n    {\n        error(\"type `%s` is not an expression\", toChars());\n        return true;\n    }\n\n    override bool checkValue()\n    {\n        error(\"type `%s` has no value\", toChars());\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Mainly just a placeholder of\n *  Package, Module, Nspace, and TemplateInstance (including TemplateMixin)\n *\n * A template instance that requires IFTI:\n *      foo!tiargs(fargs)       // foo!tiargs\n * is left until CallExp::semantic() or resolveProperties()\n */\nextern (C++) final class ScopeExp : Expression\n{\n    ScopeDsymbol sds;\n\n    extern (D) this(const ref Loc loc, ScopeDsymbol sds)\n    {\n        super(loc, TOK.scope_, __traits(classInstanceSize, ScopeExp));\n        //printf(\"ScopeExp::ScopeExp(sds = '%s')\\n\", sds.toChars());\n        //static int count; if (++count == 38) *(char*)0=0;\n        this.sds = sds;\n        assert(!sds.isTemplateDeclaration());   // instead, you should use TemplateExp\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new ScopeExp(loc, cast(ScopeDsymbol)sds.syntaxCopy(null));\n    }\n\n    override bool checkType()\n    {\n        if (sds.isPackage())\n        {\n            error(\"%s `%s` has no type\", sds.kind(), sds.toChars());\n            return true;\n        }\n        if (auto ti = sds.isTemplateInstance())\n        {\n            //assert(ti.needsTypeInference(sc));\n            if (ti.tempdecl &&\n                ti.semantictiargsdone &&\n                ti.semanticRun == PASS.init)\n            {\n                error(\"partial %s `%s` has no type\", sds.kind(), toChars());\n                return true;\n            }\n        }\n        return false;\n    }\n\n    override bool checkValue()\n    {\n        error(\"%s `%s` has no value\", sds.kind(), sds.toChars());\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Mainly just a placeholder\n */\nextern (C++) final class TemplateExp : Expression\n{\n    TemplateDeclaration td;\n    FuncDeclaration fd;\n\n    extern (D) this(const ref Loc loc, TemplateDeclaration td, FuncDeclaration fd = null)\n    {\n        super(loc, TOK.template_, __traits(classInstanceSize, TemplateExp));\n        //printf(\"TemplateExp(): %s\\n\", td.toChars());\n        this.td = td;\n        this.fd = fd;\n    }\n\n    override bool isLvalue()\n    {\n        return fd !is null;\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        if (!fd)\n            return Expression.toLvalue(sc, e);\n\n        assert(sc);\n        return resolve(loc, sc, fd, true);\n    }\n\n    override bool checkType()\n    {\n        error(\"%s `%s` has no type\", td.kind(), toChars());\n        return true;\n    }\n\n    override bool checkValue()\n    {\n        error(\"%s `%s` has no value\", td.kind(), toChars());\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * thisexp.new(newargs) newtype(arguments)\n */\nextern (C++) final class NewExp : Expression\n{\n    Expression thisexp;         // if !=null, 'this' for class being allocated\n    Expressions* newargs;       // Array of Expression's to call new operator\n    Type newtype;\n    Expressions* arguments;     // Array of Expression's\n\n    Expression argprefix;       // expression to be evaluated just before arguments[]\n    CtorDeclaration member;     // constructor function\n    NewDeclaration allocator;   // allocator function\n    bool onstack;               // allocate on stack\n    bool thrownew;              // this NewExp is the expression of a ThrowStatement\n\n    extern (D) this(const ref Loc loc, Expression thisexp, Expressions* newargs, Type newtype, Expressions* arguments)\n    {\n        super(loc, TOK.new_, __traits(classInstanceSize, NewExp));\n        this.thisexp = thisexp;\n        this.newargs = newargs;\n        this.newtype = newtype;\n        this.arguments = arguments;\n    }\n\n    static NewExp create(Loc loc, Expression thisexp, Expressions* newargs, Type newtype, Expressions* arguments)\n    {\n        return new NewExp(loc, thisexp, newargs, newtype, arguments);\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new NewExp(loc,\n            thisexp ? thisexp.syntaxCopy() : null,\n            arraySyntaxCopy(newargs),\n            newtype.syntaxCopy(),\n            arraySyntaxCopy(arguments));\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * thisexp.new(newargs) class baseclasses { } (arguments)\n */\nextern (C++) final class NewAnonClassExp : Expression\n{\n    Expression thisexp;     // if !=null, 'this' for class being allocated\n    Expressions* newargs;   // Array of Expression's to call new operator\n    ClassDeclaration cd;    // class being instantiated\n    Expressions* arguments; // Array of Expression's to call class constructor\n\n    extern (D) this(const ref Loc loc, Expression thisexp, Expressions* newargs, ClassDeclaration cd, Expressions* arguments)\n    {\n        super(loc, TOK.newAnonymousClass, __traits(classInstanceSize, NewAnonClassExp));\n        this.thisexp = thisexp;\n        this.newargs = newargs;\n        this.cd = cd;\n        this.arguments = arguments;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new NewAnonClassExp(loc, thisexp ? thisexp.syntaxCopy() : null, arraySyntaxCopy(newargs), cast(ClassDeclaration)cd.syntaxCopy(null), arraySyntaxCopy(arguments));\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class SymbolExp : Expression\n{\n    Declaration var;\n    bool hasOverloads;\n\n    extern (D) this(const ref Loc loc, TOK op, int size, Declaration var, bool hasOverloads)\n    {\n        super(loc, op, size);\n        assert(var);\n        this.var = var;\n        this.hasOverloads = hasOverloads;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Offset from symbol\n */\nextern (C++) final class SymOffExp : SymbolExp\n{\n    dinteger_t offset;\n\n    extern (D) this(const ref Loc loc, Declaration var, dinteger_t offset, bool hasOverloads = true)\n    {\n        if (auto v = var.isVarDeclaration())\n        {\n            // FIXME: This error report will never be handled anyone.\n            // It should be done before the SymOffExp construction.\n            if (v.needThis())\n                .error(loc, \"need `this` for address of `%s`\", v.toChars());\n            hasOverloads = false;\n        }\n        super(loc, TOK.symbolOffset, __traits(classInstanceSize, SymOffExp), var, hasOverloads);\n        this.offset = offset;\n    }\n\n    override bool isBool(bool result)\n    {\n        return result ? true : false;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Variable\n */\nextern (C++) final class VarExp : SymbolExp\n{\n    extern (D) this(const ref Loc loc, Declaration var, bool hasOverloads = true)\n    {\n        if (var.isVarDeclaration())\n            hasOverloads = false;\n\n        super(loc, TOK.variable, __traits(classInstanceSize, VarExp), var, hasOverloads);\n        //printf(\"VarExp(this = %p, '%s', loc = %s)\\n\", this, var.toChars(), loc.toChars());\n        //if (strcmp(var.ident.toChars(), \"func\") == 0) assert(0);\n        this.type = var.type;\n    }\n\n    static VarExp create(Loc loc, Declaration var, bool hasOverloads = true)\n    {\n        return new VarExp(loc, var, hasOverloads);\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n        if ((cast(Expression)o).op == TOK.variable)\n        {\n            VarExp ne = cast(VarExp)o;\n            if (type.toHeadMutable().equals(ne.type.toHeadMutable()) && var == ne.var)\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    override int checkModifiable(Scope* sc, int flag)\n    {\n        //printf(\"VarExp::checkModifiable %s\", toChars());\n        assert(type);\n        return var.checkModify(loc, sc, null, flag);\n    }\n\n    override bool isLvalue()\n    {\n        if (var.storage_class & (STC.lazy_ | STC.rvalue | STC.manifest))\n            return false;\n        return true;\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        if (var.storage_class & STC.manifest)\n        {\n            error(\"manifest constant `%s` cannot be modified\", var.toChars());\n            return new ErrorExp();\n        }\n        if (var.storage_class & STC.lazy_)\n        {\n            error(\"lazy variable `%s` cannot be modified\", var.toChars());\n            return new ErrorExp();\n        }\n        if (var.ident == Id.ctfe)\n        {\n            error(\"cannot modify compiler-generated variable `__ctfe`\");\n            return new ErrorExp();\n        }\n        if (var.ident == Id.dollar) // https://issues.dlang.org/show_bug.cgi?id=13574\n        {\n            error(\"cannot modify operator `$`\");\n            return new ErrorExp();\n        }\n        return this;\n    }\n\n    override Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        //printf(\"VarExp::modifiableLvalue('%s')\\n\", var.toChars());\n        if (var.storage_class & STC.manifest)\n        {\n            error(\"cannot modify manifest constant `%s`\", toChars());\n            return new ErrorExp();\n        }\n        // See if this expression is a modifiable lvalue (i.e. not const)\n        return Expression.modifiableLvalue(sc, e);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    override Expression syntaxCopy()\n    {\n        auto ret = super.syntaxCopy();\n        return ret;\n    }\n}\n\n/***********************************************************\n * Overload Set\n */\nextern (C++) final class OverExp : Expression\n{\n    OverloadSet vars;\n\n    extern (D) this(const ref Loc loc, OverloadSet s)\n    {\n        super(loc, TOK.overloadSet, __traits(classInstanceSize, OverExp));\n        //printf(\"OverExp(this = %p, '%s')\\n\", this, var.toChars());\n        vars = s;\n        type = Type.tvoid;\n    }\n\n    override bool isLvalue()\n    {\n        return true;\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Function/Delegate literal\n */\n\nextern (C++) final class FuncExp : Expression\n{\n    FuncLiteralDeclaration fd;\n    TemplateDeclaration td;\n    TOK tok;\n\n    extern (D) this(const ref Loc loc, Dsymbol s)\n    {\n        super(loc, TOK.function_, __traits(classInstanceSize, FuncExp));\n        this.td = s.isTemplateDeclaration();\n        this.fd = s.isFuncLiteralDeclaration();\n        if (td)\n        {\n            assert(td.literal);\n            assert(td.members && td.members.dim == 1);\n            fd = (*td.members)[0].isFuncLiteralDeclaration();\n        }\n        tok = fd.tok; // save original kind of function/delegate/(infer)\n        assert(fd.fbody);\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n        if (o.dyncast() != DYNCAST.expression)\n            return false;\n        if ((cast(Expression)o).op == TOK.function_)\n        {\n            FuncExp fe = cast(FuncExp)o;\n            return fd == fe.fd;\n        }\n        return false;\n    }\n\n    extern (D) void genIdent(Scope* sc)\n    {\n        if (fd.ident == Id.empty)\n        {\n            const(char)* s;\n            if (fd.fes)\n                s = \"__foreachbody\";\n            else if (fd.tok == TOK.reserved)\n                s = \"__lambda\";\n            else if (fd.tok == TOK.delegate_)\n                s = \"__dgliteral\";\n            else\n                s = \"__funcliteral\";\n\n            DsymbolTable symtab;\n            if (FuncDeclaration func = sc.parent.isFuncDeclaration())\n            {\n                if (func.localsymtab is null)\n                {\n                    // Inside template constraint, symtab is not set yet.\n                    // Initialize it lazily.\n                    func.localsymtab = new DsymbolTable();\n                }\n                symtab = func.localsymtab;\n            }\n            else\n            {\n                ScopeDsymbol sds = sc.parent.isScopeDsymbol();\n                if (!sds.symtab)\n                {\n                    // Inside template constraint, symtab may not be set yet.\n                    // Initialize it lazily.\n                    assert(sds.isTemplateInstance());\n                    sds.symtab = new DsymbolTable();\n                }\n                symtab = sds.symtab;\n            }\n            assert(symtab);\n            Identifier id = Identifier.generateId(s, symtab.len() + 1);\n            fd.ident = id;\n            if (td)\n                td.ident = id;\n            symtab.insert(td ? cast(Dsymbol)td : cast(Dsymbol)fd);\n        }\n    }\n\n    override Expression syntaxCopy()\n    {\n        if (td)\n            return new FuncExp(loc, td.syntaxCopy(null));\n        else if (fd.semanticRun == PASS.init)\n            return new FuncExp(loc, fd.syntaxCopy(null));\n        else // https://issues.dlang.org/show_bug.cgi?id=13481\n             // Prevent multiple semantic analysis of lambda body.\n            return new FuncExp(loc, fd);\n    }\n\n    extern (D) MATCH matchType(Type to, Scope* sc, FuncExp* presult, int flag = 0)\n    {\n        //printf(\"FuncExp::matchType('%s'), to=%s\\n\", type ? type.toChars() : \"null\", to.toChars());\n        if (presult)\n            *presult = null;\n\n        TypeFunction tof = null;\n        if (to.ty == Tdelegate)\n        {\n            if (tok == TOK.function_)\n            {\n                if (!flag)\n                    error(\"cannot match function literal to delegate type `%s`\", to.toChars());\n                return MATCH.nomatch;\n            }\n            tof = cast(TypeFunction)to.nextOf();\n        }\n        else if (to.ty == Tpointer && to.nextOf().ty == Tfunction)\n        {\n            if (tok == TOK.delegate_)\n            {\n                if (!flag)\n                    error(\"cannot match delegate literal to function pointer type `%s`\", to.toChars());\n                return MATCH.nomatch;\n            }\n            tof = cast(TypeFunction)to.nextOf();\n        }\n\n        if (td)\n        {\n            if (!tof)\n            {\n            L1:\n                if (!flag)\n                    error(\"cannot infer parameter types from `%s`\", to.toChars());\n                return MATCH.nomatch;\n            }\n\n            // Parameter types inference from 'tof'\n            assert(td._scope);\n            TypeFunction tf = cast(TypeFunction)fd.type;\n            //printf(\"\\ttof = %s\\n\", tof.toChars());\n            //printf(\"\\ttf  = %s\\n\", tf.toChars());\n            size_t dim = Parameter.dim(tf.parameters);\n\n            if (Parameter.dim(tof.parameters) != dim || tof.varargs != tf.varargs)\n                goto L1;\n\n            auto tiargs = new Objects();\n            tiargs.reserve(td.parameters.dim);\n\n            foreach (tp; *td.parameters)\n            {\n                size_t u = 0;\n                for (; u < dim; u++)\n                {\n                    Parameter p = Parameter.getNth(tf.parameters, u);\n                    if (p.type.ty == Tident && (cast(TypeIdentifier)p.type).ident == tp.ident)\n                    {\n                        break;\n                    }\n                }\n                assert(u < dim);\n                Parameter pto = Parameter.getNth(tof.parameters, u);\n                Type t = pto.type;\n                if (t.ty == Terror)\n                    goto L1;\n                tiargs.push(t);\n            }\n\n            // Set target of return type inference\n            if (!tf.next && tof.next)\n                fd.treq = to;\n\n            auto ti = new TemplateInstance(loc, td, tiargs);\n            Expression ex = (new ScopeExp(loc, ti)).expressionSemantic(td._scope);\n\n            // Reset inference target for the later re-semantic\n            fd.treq = null;\n\n            if (ex.op == TOK.error)\n                return MATCH.nomatch;\n            if (ex.op != TOK.function_)\n                goto L1;\n            return (cast(FuncExp)ex).matchType(to, sc, presult, flag);\n        }\n\n        if (!tof || !tof.next)\n            return MATCH.nomatch;\n\n        assert(type && type != Type.tvoid);\n        TypeFunction tfx = cast(TypeFunction)fd.type;\n        bool convertMatch = (type.ty != to.ty);\n\n        if (fd.inferRetType && tfx.next.implicitConvTo(tof.next) == MATCH.convert)\n        {\n            /* If return type is inferred and covariant return,\n             * tweak return statements to required return type.\n             *\n             * interface I {}\n             * class C : Object, I{}\n             *\n             * I delegate() dg = delegate() { return new class C(); }\n             */\n            convertMatch = true;\n\n            auto tfy = new TypeFunction(tfx.parameters, tof.next, tfx.varargs, tfx.linkage, STC.undefined_);\n            tfy.mod = tfx.mod;\n            tfy.isnothrow = tfx.isnothrow;\n            tfy.isnogc = tfx.isnogc;\n            tfy.purity = tfx.purity;\n            tfy.isproperty = tfx.isproperty;\n            tfy.isref = tfx.isref;\n            tfy.iswild = tfx.iswild;\n            tfy.deco = tfy.merge().deco;\n\n            tfx = tfy;\n        }\n        Type tx;\n        if (tok == TOK.delegate_ || tok == TOK.reserved && (type.ty == Tdelegate || type.ty == Tpointer && to.ty == Tdelegate))\n        {\n            // Allow conversion from implicit function pointer to delegate\n            tx = new TypeDelegate(tfx);\n            tx.deco = tx.merge().deco;\n        }\n        else\n        {\n            assert(tok == TOK.function_ || tok == TOK.reserved && type.ty == Tpointer);\n            tx = tfx.pointerTo();\n        }\n        //printf(\"\\ttx = %s, to = %s\\n\", tx.toChars(), to.toChars());\n\n        MATCH m = tx.implicitConvTo(to);\n        if (m > MATCH.nomatch)\n        {\n            // MATCH.exact:      exact type match\n            // MATCH.constant:      covairiant type match (eg. attributes difference)\n            // MATCH.convert:    context conversion\n            m = convertMatch ? MATCH.convert : tx.equals(to) ? MATCH.exact : MATCH.constant;\n\n            if (presult)\n            {\n                (*presult) = cast(FuncExp)copy();\n                (*presult).type = to;\n\n                // https://issues.dlang.org/show_bug.cgi?id=12508\n                // Tweak function body for covariant returns.\n                (*presult).fd.modifyReturns(sc, tof.next);\n            }\n        }\n        else if (!flag)\n        {\n            auto ts = toAutoQualChars(tx, to);\n            error(\"cannot implicitly convert expression `%s` of type `%s` to `%s`\",\n                toChars(), ts[0], ts[1]);\n        }\n        return m;\n    }\n\n    override const(char)* toChars()\n    {\n        return fd.toChars();\n    }\n\n    override bool checkType()\n    {\n        if (td)\n        {\n            error(\"template lambda has no type\");\n            return true;\n        }\n        return false;\n    }\n\n    override bool checkValue()\n    {\n        if (td)\n        {\n            error(\"template lambda has no value\");\n            return true;\n        }\n        return false;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Declaration of a symbol\n *\n * D grammar allows declarations only as statements. However in AST representation\n * it can be part of any expression. This is used, for example, during internal\n * syntax re-writes to inject hidden symbols.\n */\nextern (C++) final class DeclarationExp : Expression\n{\n    Dsymbol declaration;\n\n    extern (D) this(const ref Loc loc, Dsymbol declaration)\n    {\n        super(loc, TOK.declaration, __traits(classInstanceSize, DeclarationExp));\n        this.declaration = declaration;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new DeclarationExp(loc, declaration.syntaxCopy(null));\n    }\n\n    override bool hasCode()\n    {\n        if (auto vd = declaration.isVarDeclaration())\n        {\n            return !(vd.storage_class & (STC.manifest | STC.static_));\n        }\n        return false;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * typeid(int)\n */\nextern (C++) final class TypeidExp : Expression\n{\n    RootObject obj;\n\n    extern (D) this(const ref Loc loc, RootObject o)\n    {\n        super(loc, TOK.typeid_, __traits(classInstanceSize, TypeidExp));\n        this.obj = o;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new TypeidExp(loc, objectSyntaxCopy(obj));\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * __traits(identifier, args...)\n */\nextern (C++) final class TraitsExp : Expression\n{\n    Identifier ident;\n    Objects* args;\n\n    extern (D) this(const ref Loc loc, Identifier ident, Objects* args)\n    {\n        super(loc, TOK.traits, __traits(classInstanceSize, TraitsExp));\n        this.ident = ident;\n        this.args = args;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new TraitsExp(loc, ident, TemplateInstance.arraySyntaxCopy(args));\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class HaltExp : Expression\n{\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc, TOK.halt, __traits(classInstanceSize, HaltExp));\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * is(targ id tok tspec)\n * is(targ id == tok2)\n */\nextern (C++) final class IsExp : Expression\n{\n    Type targ;\n    Identifier id;      // can be null\n    TOK tok;            // ':' or '=='\n    Type tspec;         // can be null\n    TOK tok2;           // 'struct', 'union', etc.\n    TemplateParameters* parameters;\n\n    extern (D) this(const ref Loc loc, Type targ, Identifier id, TOK tok, Type tspec, TOK tok2, TemplateParameters* parameters)\n    {\n        super(loc, TOK.is_, __traits(classInstanceSize, IsExp));\n        this.targ = targ;\n        this.id = id;\n        this.tok = tok;\n        this.tspec = tspec;\n        this.tok2 = tok2;\n        this.parameters = parameters;\n    }\n\n    override Expression syntaxCopy()\n    {\n        // This section is identical to that in TemplateDeclaration::syntaxCopy()\n        TemplateParameters* p = null;\n        if (parameters)\n        {\n            p = new TemplateParameters(parameters.dim);\n            foreach (i, el; *parameters)\n                (*p)[i] = el.syntaxCopy();\n        }\n        return new IsExp(loc, targ.syntaxCopy(), id, tok, tspec ? tspec.syntaxCopy() : null, tok2, p);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) abstract class UnaExp : Expression\n{\n    Expression e1;\n    Type att1;      // Save alias this type to detect recursion\n\n    extern (D) this(const ref Loc loc, TOK op, int size, Expression e1)\n    {\n        super(loc, op, size);\n        this.e1 = e1;\n    }\n\n    override Expression syntaxCopy()\n    {\n        UnaExp e = cast(UnaExp)copy();\n        e.type = null;\n        e.e1 = e.e1.syntaxCopy();\n        return e;\n    }\n\n    /********************************\n     * The type for a unary expression is incompatible.\n     * Print error message.\n     * Returns:\n     *  ErrorExp\n     */\n    final Expression incompatibleTypes()\n    {\n        if (e1.type.toBasetype() == Type.terror)\n            return e1;\n\n        if (e1.op == TOK.type)\n        {\n            error(\"incompatible type for `%s(%s)`: cannot use `%s` with types\", Token.toChars(op), e1.toChars(), Token.toChars(op));\n        }\n        else\n        {\n            error(\"incompatible type for `%s(%s)`: `%s`\", Token.toChars(op), e1.toChars(), e1.type.toChars());\n        }\n        return new ErrorExp();\n    }\n\n    /*********************\n     * Mark the operand as will never be dereferenced,\n     * which is useful info for @safe checks.\n     * Do before semantic() on operands rewrites them.\n     */\n    final void setNoderefOperand()\n    {\n        if (e1.op == TOK.dotIdentifier)\n            (cast(DotIdExp)e1).noderef = true;\n\n    }\n\n    override final Expression resolveLoc(const ref Loc loc, Scope* sc)\n    {\n        e1 = e1.resolveLoc(loc, sc);\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\nalias fp_t = UnionExp function(const ref Loc loc, Type, Expression, Expression);\nalias fp2_t = int function(const ref Loc loc, TOK, Expression, Expression);\n\n/***********************************************************\n */\nextern (C++) abstract class BinExp : Expression\n{\n    Expression e1;\n    Expression e2;\n    Type att1;      // Save alias this type to detect recursion\n    Type att2;      // Save alias this type to detect recursion\n\n    extern (D) this(const ref Loc loc, TOK op, int size, Expression e1, Expression e2)\n    {\n        super(loc, op, size);\n        this.e1 = e1;\n        this.e2 = e2;\n    }\n\n    override Expression syntaxCopy()\n    {\n        BinExp e = cast(BinExp)copy();\n        e.type = null;\n        e.e1 = e.e1.syntaxCopy();\n        e.e2 = e.e2.syntaxCopy();\n        return e;\n    }\n\n    /********************************\n     * The types for a binary expression are incompatible.\n     * Print error message.\n     * Returns:\n     *  ErrorExp\n     */\n    final Expression incompatibleTypes()\n    {\n        if (e1.type.toBasetype() == Type.terror)\n            return e1;\n        if (e2.type.toBasetype() == Type.terror)\n            return e2;\n\n        // CondExp uses 'a ? b : c' but we're comparing 'b : c'\n        TOK thisOp = (op == TOK.question) ? TOK.colon : op;\n        if (e1.op == TOK.type || e2.op == TOK.type)\n        {\n            error(\"incompatible types for `(%s) %s (%s)`: cannot use `%s` with types\",\n                e1.toChars(), Token.toChars(thisOp), e2.toChars(), Token.toChars(op));\n        }\n        else if (e1.type.equals(e2.type))\n        {\n            error(\"incompatible types for `(%s) %s (%s)`: both operands are of type `%s`\",\n                e1.toChars(), Token.toChars(thisOp), e2.toChars(), e1.type.toChars());\n        }\n        else\n        {\n            auto ts = toAutoQualChars(e1.type, e2.type);\n            error(\"incompatible types for `(%s) %s (%s)`: `%s` and `%s`\",\n                e1.toChars(), Token.toChars(thisOp), e2.toChars(), ts[0], ts[1]);\n        }\n        return new ErrorExp();\n    }\n\n    extern (D) final Expression checkOpAssignTypes(Scope* sc)\n    {\n        // At that point t1 and t2 are the merged types. type is the original type of the lhs.\n        Type t1 = e1.type;\n        Type t2 = e2.type;\n\n        // T opAssign floating yields a floating. Prevent truncating conversions (float to int).\n        // See issue 3841.\n        // Should we also prevent double to float (type.isfloating() && type.size() < t2.size()) ?\n        if (op == TOK.addAssign || op == TOK.minAssign ||\n            op == TOK.mulAssign || op == TOK.divAssign || op == TOK.modAssign ||\n            op == TOK.powAssign)\n        {\n            if ((type.isintegral() && t2.isfloating()))\n            {\n                warning(\"`%s %s %s` is performing truncating conversion\", type.toChars(), Token.toChars(op), t2.toChars());\n            }\n        }\n\n        // generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary\n        if (op == TOK.mulAssign || op == TOK.divAssign || op == TOK.modAssign)\n        {\n            // Any multiplication by an imaginary or complex number yields a complex result.\n            // r *= c, i*=c, r*=i, i*=i are all forbidden operations.\n            const(char)* opstr = Token.toChars(op);\n            if (t1.isreal() && t2.iscomplex())\n            {\n                error(\"`%s %s %s` is undefined. Did you mean `%s %s %s.re`?\", t1.toChars(), opstr, t2.toChars(), t1.toChars(), opstr, t2.toChars());\n                return new ErrorExp();\n            }\n            else if (t1.isimaginary() && t2.iscomplex())\n            {\n                error(\"`%s %s %s` is undefined. Did you mean `%s %s %s.im`?\", t1.toChars(), opstr, t2.toChars(), t1.toChars(), opstr, t2.toChars());\n                return new ErrorExp();\n            }\n            else if ((t1.isreal() || t1.isimaginary()) && t2.isimaginary())\n            {\n                error(\"`%s %s %s` is an undefined operation\", t1.toChars(), opstr, t2.toChars());\n                return new ErrorExp();\n            }\n        }\n\n        // generate an error if this is a nonsensical += or -=, eg real += imaginary\n        if (op == TOK.addAssign || op == TOK.minAssign)\n        {\n            // Addition or subtraction of a real and an imaginary is a complex result.\n            // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations.\n            if ((t1.isreal() && (t2.isimaginary() || t2.iscomplex())) || (t1.isimaginary() && (t2.isreal() || t2.iscomplex())))\n            {\n                error(\"`%s %s %s` is undefined (result is complex)\", t1.toChars(), Token.toChars(op), t2.toChars());\n                return new ErrorExp();\n            }\n            if (type.isreal() || type.isimaginary())\n            {\n                assert(global.errors || t2.isfloating());\n                e2 = e2.castTo(sc, t1);\n            }\n        }\n        if (op == TOK.mulAssign)\n        {\n            if (t2.isfloating())\n            {\n                if (t1.isreal())\n                {\n                    if (t2.isimaginary() || t2.iscomplex())\n                    {\n                        e2 = e2.castTo(sc, t1);\n                    }\n                }\n                else if (t1.isimaginary())\n                {\n                    if (t2.isimaginary() || t2.iscomplex())\n                    {\n                        switch (t1.ty)\n                        {\n                        case Timaginary32:\n                            t2 = Type.tfloat32;\n                            break;\n\n                        case Timaginary64:\n                            t2 = Type.tfloat64;\n                            break;\n\n                        case Timaginary80:\n                            t2 = Type.tfloat80;\n                            break;\n\n                        default:\n                            assert(0);\n                        }\n                        e2 = e2.castTo(sc, t2);\n                    }\n                }\n            }\n        }\n        else if (op == TOK.divAssign)\n        {\n            if (t2.isimaginary())\n            {\n                if (t1.isreal())\n                {\n                    // x/iv = i(-x/v)\n                    // Therefore, the result is 0\n                    e2 = new CommaExp(loc, e2, new RealExp(loc, CTFloat.zero, t1));\n                    e2.type = t1;\n                    Expression e = new AssignExp(loc, e1, e2);\n                    e.type = t1;\n                    return e;\n                }\n                else if (t1.isimaginary())\n                {\n                    Type t3;\n                    switch (t1.ty)\n                    {\n                    case Timaginary32:\n                        t3 = Type.tfloat32;\n                        break;\n\n                    case Timaginary64:\n                        t3 = Type.tfloat64;\n                        break;\n\n                    case Timaginary80:\n                        t3 = Type.tfloat80;\n                        break;\n\n                    default:\n                        assert(0);\n                    }\n                    e2 = e2.castTo(sc, t3);\n                    Expression e = new AssignExp(loc, e1, e2);\n                    e.type = t1;\n                    return e;\n                }\n            }\n        }\n        else if (op == TOK.modAssign)\n        {\n            if (t2.iscomplex())\n            {\n                error(\"cannot perform modulo complex arithmetic\");\n                return new ErrorExp();\n            }\n        }\n        return this;\n    }\n\n    extern (D) final bool checkIntegralBin()\n    {\n        bool r1 = e1.checkIntegral();\n        bool r2 = e2.checkIntegral();\n        return (r1 || r2);\n    }\n\n    extern (D) final bool checkArithmeticBin()\n    {\n        bool r1 = e1.checkArithmetic();\n        bool r2 = e2.checkArithmetic();\n        return (r1 || r2);\n    }\n\n    /*********************\n     * Mark the operands as will never be dereferenced,\n     * which is useful info for @safe checks.\n     * Do before semantic() on operands rewrites them.\n     */\n    final void setNoderefOperands()\n    {\n        if (e1.op == TOK.dotIdentifier)\n            (cast(DotIdExp)e1).noderef = true;\n        if (e2.op == TOK.dotIdentifier)\n            (cast(DotIdExp)e2).noderef = true;\n\n    }\n\n    final Expression reorderSettingAAElem(Scope* sc)\n    {\n        BinExp be = this;\n\n        if (be.e1.op != TOK.index)\n            return be;\n        auto ie = cast(IndexExp)be.e1;\n        if (ie.e1.type.toBasetype().ty != Taarray)\n            return be;\n\n        /* Fix evaluation order of setting AA element\n         * https://issues.dlang.org/show_bug.cgi?id=3825\n         * Rewrite:\n         *     aa[k1][k2][k3] op= val;\n         * as:\n         *     auto ref __aatmp = aa;\n         *     auto ref __aakey3 = k1, __aakey2 = k2, __aakey1 = k3;\n         *     auto ref __aaval = val;\n         *     __aatmp[__aakey3][__aakey2][__aakey1] op= __aaval;  // assignment\n         */\n\n        Expression e0;\n        while (1)\n        {\n            Expression de;\n            ie.e2 = extractSideEffect(sc, \"__aakey\", de, ie.e2);\n            e0 = Expression.combine(de, e0);\n\n            Expression ie1 = ie.e1;\n            if (ie1.op != TOK.index ||\n                (cast(IndexExp)ie1).e1.type.toBasetype().ty != Taarray)\n            {\n                break;\n            }\n            ie = cast(IndexExp)ie1;\n        }\n        assert(ie.e1.type.toBasetype().ty == Taarray);\n\n        Expression de;\n        ie.e1 = extractSideEffect(sc, \"__aatmp\", de, ie.e1);\n        e0 = Expression.combine(de, e0);\n\n        be.e2 = extractSideEffect(sc, \"__aaval\", e0, be.e2, true);\n\n        //printf(\"-e0 = %s, be = %s\\n\", e0.toChars(), be.toChars());\n        return Expression.combine(e0, be);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class BinAssignExp : BinExp\n{\n    extern (D) this(const ref Loc loc, TOK op, int size, Expression e1, Expression e2)\n    {\n        super(loc, op, size, e1, e2);\n    }\n\n    override final bool isLvalue()\n    {\n        return true;\n    }\n\n    override final Expression toLvalue(Scope* sc, Expression ex)\n    {\n        // Lvalue-ness will be handled in glue layer.\n        return this;\n    }\n\n    override final Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        // should check e1.checkModifiable() ?\n        return toLvalue(sc, this);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * https://dlang.org/spec/expression.html#mixin_expressions\n */\nextern (C++) final class CompileExp : Expression\n{\n    Expressions* exps;\n\n    extern (D) this(const ref Loc loc, Expressions* exps)\n    {\n        super(loc, TOK.mixin_, __traits(classInstanceSize, CompileExp));\n        this.exps = exps;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new CompileExp(loc, arraySyntaxCopy(exps));\n    }\n\n    override bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n        if (o && o.dyncast() == DYNCAST.expression && (cast(Expression)o).op == TOK.mixin_)\n        {\n            CompileExp ce = cast(CompileExp)o;\n            if (exps.dim != ce.exps.dim)\n                return false;\n            foreach (i, e1; *exps)\n            {\n                Expression e2 = (*ce.exps)[i];\n                if (e1 != e2 && (!e1 || !e2 || !e1.equals(e2)))\n                    return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ImportExp : UnaExp\n{\n    extern (D) this(const ref Loc loc, Expression e)\n    {\n        super(loc, TOK.import_, __traits(classInstanceSize, ImportExp), e);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * https://dlang.org/spec/expression.html#assert_expressions\n */\nextern (C++) final class AssertExp : UnaExp\n{\n    Expression msg;\n\n    extern (D) this(const ref Loc loc, Expression e, Expression msg = null)\n    {\n        super(loc, TOK.assert_, __traits(classInstanceSize, AssertExp), e);\n        this.msg = msg;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new AssertExp(loc, e1.syntaxCopy(), msg ? msg.syntaxCopy() : null);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DotIdExp : UnaExp\n{\n    Identifier ident;\n    bool noderef;       // true if the result of the expression will never be dereferenced\n    bool wantsym;       // do not replace Symbol with its initializer during semantic()\n\n    extern (D) this(const ref Loc loc, Expression e, Identifier ident)\n    {\n        super(loc, TOK.dotIdentifier, __traits(classInstanceSize, DotIdExp), e);\n        this.ident = ident;\n    }\n\n    static DotIdExp create(Loc loc, Expression e, Identifier ident)\n    {\n        return new DotIdExp(loc, e, ident);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Mainly just a placeholder\n */\nextern (C++) final class DotTemplateExp : UnaExp\n{\n    TemplateDeclaration td;\n\n    extern (D) this(const ref Loc loc, Expression e, TemplateDeclaration td)\n    {\n        super(loc, TOK.dotTemplateDeclaration, __traits(classInstanceSize, DotTemplateExp), e);\n        this.td = td;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DotVarExp : UnaExp\n{\n    Declaration var;\n    bool hasOverloads;\n\n    extern (D) this(const ref Loc loc, Expression e, Declaration var, bool hasOverloads = true)\n    {\n        if (var.isVarDeclaration())\n            hasOverloads = false;\n\n        super(loc, TOK.dotVariable, __traits(classInstanceSize, DotVarExp), e);\n        //printf(\"DotVarExp()\\n\");\n        this.var = var;\n        this.hasOverloads = hasOverloads;\n    }\n\n    override int checkModifiable(Scope* sc, int flag)\n    {\n        //printf(\"DotVarExp::checkModifiable %s %s\\n\", toChars(), type.toChars());\n        if (checkUnsafeAccess(sc, this, false, !flag))\n            return 2;\n\n        if (e1.op == TOK.this_)\n            return var.checkModify(loc, sc, e1, flag);\n\n        /* https://issues.dlang.org/show_bug.cgi?id=12764\n         * If inside a constructor and an expression of type `this.field.var`\n         * is encountered, where `field` is a struct declaration with\n         * default construction disabled, we must make sure that\n         * assigning to `var` does not imply that `field` was initialized\n         */\n        if (sc.func)\n        {\n            auto ctd = sc.func.isCtorDeclaration();\n\n            // if inside a constructor scope and e1 of this DotVarExp\n            // is a DotVarExp, then check if e1.e1 is a `this` identifier\n            if (ctd && e1.op == TOK.dotVariable)\n            {\n                scope dve = cast(DotVarExp)e1;\n                if (dve.e1.op == TOK.this_)\n                {\n                    scope v = dve.var.isVarDeclaration();\n                    /* if v is a struct member field with no initializer, no default construction\n                     * and v wasn't intialized before\n                     */\n                    if (v && v.isField() && v.type.ty == Tstruct && !v._init && !v.ctorinit)\n                    {\n                        const sd = (cast(TypeStruct)v.type).sym;\n                        if (sd.noDefaultCtor)\n                        {\n                            /* checkModify will consider that this is an initialization\n                             * of v while it is actually an assignment of a field of v\n                             */\n                            scope modifyLevel = v.checkModify(loc, sc, dve.e1, flag);\n                            // reflect that assigning a field of v is not initialization of v\n                            v.ctorinit = false;\n                            if (modifyLevel == 2)\n                                return 1;\n                            return modifyLevel;\n                        }\n                    }\n                }\n            }\n        }\n\n        //printf(\"\\te1 = %s\\n\", e1.toChars());\n        return e1.checkModifiable(sc, flag);\n    }\n\n    override bool isLvalue()\n    {\n        return true;\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        //printf(\"DotVarExp::toLvalue(%s)\\n\", toChars());\n        if (e1.op == TOK.this_ && sc.ctorflow.fieldinit.length && !(sc.ctorflow.callSuper & CSX.any_ctor))\n        {\n            if (VarDeclaration vd = var.isVarDeclaration())\n            {\n                auto ad = vd.isMember2();\n                if (ad && ad.fields.dim == sc.ctorflow.fieldinit.length)\n                {\n                    foreach (i, f; ad.fields)\n                    {\n                        if (f == vd)\n                        {\n                            if (!(sc.ctorflow.fieldinit[i].csx & CSX.this_ctor))\n                            {\n                                /* If the address of vd is taken, assume it is thereby initialized\n                                 * https://issues.dlang.org/show_bug.cgi?id=15869\n                                 */\n                                modifyFieldVar(loc, sc, vd, e1);\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        return this;\n    }\n\n    override Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        version (none)\n        {\n            printf(\"DotVarExp::modifiableLvalue(%s)\\n\", toChars());\n            printf(\"e1.type = %s\\n\", e1.type.toChars());\n            printf(\"var.type = %s\\n\", var.type.toChars());\n        }\n\n        return Expression.modifiableLvalue(sc, e);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * foo.bar!(args)\n */\nextern (C++) final class DotTemplateInstanceExp : UnaExp\n{\n    TemplateInstance ti;\n\n    extern (D) this(const ref Loc loc, Expression e, Identifier name, Objects* tiargs)\n    {\n        super(loc, TOK.dotTemplateInstance, __traits(classInstanceSize, DotTemplateInstanceExp), e);\n        //printf(\"DotTemplateInstanceExp()\\n\");\n        this.ti = new TemplateInstance(loc, name, tiargs);\n    }\n\n    extern (D) this(const ref Loc loc, Expression e, TemplateInstance ti)\n    {\n        super(loc, TOK.dotTemplateInstance, __traits(classInstanceSize, DotTemplateInstanceExp), e);\n        this.ti = ti;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new DotTemplateInstanceExp(loc, e1.syntaxCopy(), ti.name, TemplateInstance.arraySyntaxCopy(ti.tiargs));\n    }\n\n    bool findTempDecl(Scope* sc)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"DotTemplateInstanceExp::findTempDecl('%s')\\n\", toChars());\n        }\n        if (ti.tempdecl)\n            return true;\n\n        Expression e = new DotIdExp(loc, e1, ti.name);\n        e = e.expressionSemantic(sc);\n        if (e.op == TOK.dot)\n            e = (cast(DotExp)e).e2;\n\n        Dsymbol s = null;\n        switch (e.op)\n        {\n        case TOK.overloadSet:\n            s = (cast(OverExp)e).vars;\n            break;\n\n        case TOK.dotTemplateDeclaration:\n            s = (cast(DotTemplateExp)e).td;\n            break;\n\n        case TOK.scope_:\n            s = (cast(ScopeExp)e).sds;\n            break;\n\n        case TOK.dotVariable:\n            s = (cast(DotVarExp)e).var;\n            break;\n\n        case TOK.variable:\n            s = (cast(VarExp)e).var;\n            break;\n\n        default:\n            return false;\n        }\n        return ti.updateTempDecl(sc, s);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DelegateExp : UnaExp\n{\n    FuncDeclaration func;\n    bool hasOverloads;\n\n    extern (D) this(const ref Loc loc, Expression e, FuncDeclaration f, bool hasOverloads = true)\n    {\n        super(loc, TOK.delegate_, __traits(classInstanceSize, DelegateExp), e);\n        this.func = f;\n        this.hasOverloads = hasOverloads;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DotTypeExp : UnaExp\n{\n    Dsymbol sym;        // symbol that represents a type\n\n    extern (D) this(const ref Loc loc, Expression e, Dsymbol s)\n    {\n        super(loc, TOK.dotType, __traits(classInstanceSize, DotTypeExp), e);\n        this.sym = s;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class CallExp : UnaExp\n{\n    Expressions* arguments; // function arguments\n    FuncDeclaration f;      // symbol to call\n    bool directcall;        // true if a virtual call is devirtualized\n\n    extern (D) this(const ref Loc loc, Expression e, Expressions* exps)\n    {\n        super(loc, TOK.call, __traits(classInstanceSize, CallExp), e);\n        this.arguments = exps;\n    }\n\n    extern (D) this(const ref Loc loc, Expression e)\n    {\n        super(loc, TOK.call, __traits(classInstanceSize, CallExp), e);\n    }\n\n    extern (D) this(const ref Loc loc, Expression e, Expression earg1)\n    {\n        super(loc, TOK.call, __traits(classInstanceSize, CallExp), e);\n        auto arguments = new Expressions();\n        if (earg1)\n        {\n            arguments.setDim(1);\n            (*arguments)[0] = earg1;\n        }\n        this.arguments = arguments;\n    }\n\n    extern (D) this(const ref Loc loc, Expression e, Expression earg1, Expression earg2)\n    {\n        super(loc, TOK.call, __traits(classInstanceSize, CallExp), e);\n        auto arguments = new Expressions(2);\n        (*arguments)[0] = earg1;\n        (*arguments)[1] = earg2;\n        this.arguments = arguments;\n    }\n\n    /***********************************************************\n    * Instatiates a new function call expression\n    * Params:\n    *       loc   = location\n    *       fd    = the declaration of the function to call\n    *       earg1 = the function argument\n    */\n    extern(D) this(const ref Loc loc, FuncDeclaration fd, Expression earg1)\n    {\n        this(loc, new VarExp(loc, fd, false), earg1);\n        this.f = fd;\n    }\n\n    static CallExp create(Loc loc, Expression e, Expressions* exps)\n    {\n        return new CallExp(loc, e, exps);\n    }\n\n    static CallExp create(Loc loc, Expression e)\n    {\n        return new CallExp(loc, e);\n    }\n\n    static CallExp create(Loc loc, Expression e, Expression earg1)\n    {\n        return new CallExp(loc, e, earg1);\n    }\n\n    /***********************************************************\n    * Creates a new function call expression\n    * Params:\n    *       loc   = location\n    *       fd    = the declaration of the function to call\n    *       earg1 = the function argument\n    */\n    static CallExp create(Loc loc, FuncDeclaration fd, Expression earg1)\n    {\n        return new CallExp(loc, fd, earg1);\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new CallExp(loc, e1.syntaxCopy(), arraySyntaxCopy(arguments));\n    }\n\n    override bool isLvalue()\n    {\n        Type tb = e1.type.toBasetype();\n        if (tb.ty == Tdelegate || tb.ty == Tpointer)\n            tb = tb.nextOf();\n        if (tb.ty == Tfunction && (cast(TypeFunction)tb).isref)\n        {\n            if (e1.op == TOK.dotVariable)\n                if ((cast(DotVarExp)e1).var.isCtorDeclaration())\n                    return false;\n            return true; // function returns a reference\n        }\n        return false;\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        if (isLvalue())\n            return this;\n        return Expression.toLvalue(sc, e);\n    }\n\n    override Expression addDtorHook(Scope* sc)\n    {\n        /* Only need to add dtor hook if it's a type that needs destruction.\n         * Use same logic as VarDeclaration::callScopeDtor()\n         */\n\n        if (e1.type && e1.type.ty == Tfunction)\n        {\n            TypeFunction tf = cast(TypeFunction)e1.type;\n            if (tf.isref)\n                return this;\n        }\n\n        Type tv = type.baseElemOf();\n        if (tv.ty == Tstruct)\n        {\n            TypeStruct ts = cast(TypeStruct)tv;\n            StructDeclaration sd = ts.sym;\n            if (sd.dtor)\n            {\n                /* Type needs destruction, so declare a tmp\n                 * which the back end will recognize and call dtor on\n                 */\n                auto tmp = copyToTemp(0, \"__tmpfordtor\", this);\n                auto de = new DeclarationExp(loc, tmp);\n                auto ve = new VarExp(loc, tmp);\n                Expression e = new CommaExp(loc, de, ve);\n                e = e.expressionSemantic(sc);\n                return e;\n            }\n        }\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\nFuncDeclaration isFuncAddress(Expression e, bool* hasOverloads = null)\n{\n    if (e.op == TOK.address)\n    {\n        auto ae1 = (cast(AddrExp)e).e1;\n        if (ae1.op == TOK.variable)\n        {\n            auto ve = cast(VarExp)ae1;\n            if (hasOverloads)\n                *hasOverloads = ve.hasOverloads;\n            return ve.var.isFuncDeclaration();\n        }\n        if (ae1.op == TOK.dotVariable)\n        {\n            auto dve = cast(DotVarExp)ae1;\n            if (hasOverloads)\n                *hasOverloads = dve.hasOverloads;\n            return dve.var.isFuncDeclaration();\n        }\n    }\n    else\n    {\n        if (e.op == TOK.symbolOffset)\n        {\n            auto soe = cast(SymOffExp)e;\n            if (hasOverloads)\n                *hasOverloads = soe.hasOverloads;\n            return soe.var.isFuncDeclaration();\n        }\n        if (e.op == TOK.delegate_)\n        {\n            auto dge = cast(DelegateExp)e;\n            if (hasOverloads)\n                *hasOverloads = dge.hasOverloads;\n            return dge.func.isFuncDeclaration();\n        }\n    }\n    return null;\n}\n\n/***********************************************************\n */\nextern (C++) final class AddrExp : UnaExp\n{\n    extern (D) this(const ref Loc loc, Expression e)\n    {\n        super(loc, TOK.address, __traits(classInstanceSize, AddrExp), e);\n    }\n\n    extern (D) this(const ref Loc loc, Expression e, Type t)\n    {\n        this(loc, e);\n        type = t;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class PtrExp : UnaExp\n{\n    extern (D) this(const ref Loc loc, Expression e)\n    {\n        super(loc, TOK.star, __traits(classInstanceSize, PtrExp), e);\n        //if (e.type)\n        //  type = ((TypePointer *)e.type).next;\n    }\n\n    extern (D) this(const ref Loc loc, Expression e, Type t)\n    {\n        super(loc, TOK.star, __traits(classInstanceSize, PtrExp), e);\n        type = t;\n    }\n\n    override int checkModifiable(Scope* sc, int flag)\n    {\n        if (e1.op == TOK.symbolOffset)\n        {\n            SymOffExp se = cast(SymOffExp)e1;\n            return se.var.checkModify(loc, sc, null, flag);\n        }\n        else if (e1.op == TOK.address)\n        {\n            AddrExp ae = cast(AddrExp)e1;\n            return ae.e1.checkModifiable(sc, flag);\n        }\n        return 1;\n    }\n\n    override bool isLvalue()\n    {\n        return true;\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        return this;\n    }\n\n    override Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        //printf(\"PtrExp::modifiableLvalue() %s, type %s\\n\", toChars(), type.toChars());\n        return Expression.modifiableLvalue(sc, e);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class NegExp : UnaExp\n{\n    extern (D) this(const ref Loc loc, Expression e)\n    {\n        super(loc, TOK.negate, __traits(classInstanceSize, NegExp), e);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class UAddExp : UnaExp\n{\n    extern (D) this(const ref Loc loc, Expression e)\n    {\n        super(loc, TOK.uadd, __traits(classInstanceSize, UAddExp), e);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ComExp : UnaExp\n{\n    extern (D) this(const ref Loc loc, Expression e)\n    {\n        super(loc, TOK.tilde, __traits(classInstanceSize, ComExp), e);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class NotExp : UnaExp\n{\n    extern (D) this(const ref Loc loc, Expression e)\n    {\n        super(loc, TOK.not, __traits(classInstanceSize, NotExp), e);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DeleteExp : UnaExp\n{\n    bool isRAII;        // true if called automatically as a result of scoped destruction\n\n    extern (D) this(const ref Loc loc, Expression e, bool isRAII)\n    {\n        super(loc, TOK.delete_, __traits(classInstanceSize, DeleteExp), e);\n        this.isRAII = isRAII;\n    }\n\n    override Expression toBoolean(Scope* sc)\n    {\n        error(\"`delete` does not give a boolean result\");\n        return new ErrorExp();\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Possible to cast to one type while painting to another type\n */\nextern (C++) final class CastExp : UnaExp\n{\n    Type to;                    // type to cast to\n    ubyte mod = cast(ubyte)~0;  // MODxxxxx\n\n    extern (D) this(const ref Loc loc, Expression e, Type t)\n    {\n        super(loc, TOK.cast_, __traits(classInstanceSize, CastExp), e);\n        this.to = t;\n    }\n\n    /* For cast(const) and cast(immutable)\n     */\n    extern (D) this(const ref Loc loc, Expression e, ubyte mod)\n    {\n        super(loc, TOK.cast_, __traits(classInstanceSize, CastExp), e);\n        this.mod = mod;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return to ? new CastExp(loc, e1.syntaxCopy(), to.syntaxCopy()) : new CastExp(loc, e1.syntaxCopy(), mod);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class VectorExp : UnaExp\n{\n    TypeVector to;      // the target vector type before semantic()\n    uint dim = ~0;      // number of elements in the vector\n\n    extern (D) this(const ref Loc loc, Expression e, Type t)\n    {\n        super(loc, TOK.vector, __traits(classInstanceSize, VectorExp), e);\n        assert(t.ty == Tvector);\n        to = cast(TypeVector)t;\n    }\n\n    static VectorExp create(Loc loc, Expression e, Type t)\n    {\n        return new VectorExp(loc, e, t);\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new VectorExp(loc, e1.syntaxCopy(), to.syntaxCopy());\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * e1 [lwr .. upr]\n *\n * http://dlang.org/spec/expression.html#slice_expressions\n */\nextern (C++) final class SliceExp : UnaExp\n{\n    Expression upr;             // null if implicit 0\n    Expression lwr;             // null if implicit [length - 1]\n\n    VarDeclaration lengthVar;\n    bool upperIsInBounds;       // true if upr <= e1.length\n    bool lowerIsLessThanUpper;  // true if lwr <= upr\n    bool arrayop;               // an array operation, rather than a slice\n\n    /************************************************************/\n    extern (D) this(const ref Loc loc, Expression e1, IntervalExp ie)\n    {\n        super(loc, TOK.slice, __traits(classInstanceSize, SliceExp), e1);\n        this.upr = ie ? ie.upr : null;\n        this.lwr = ie ? ie.lwr : null;\n    }\n\n    extern (D) this(const ref Loc loc, Expression e1, Expression lwr, Expression upr)\n    {\n        super(loc, TOK.slice, __traits(classInstanceSize, SliceExp), e1);\n        this.upr = upr;\n        this.lwr = lwr;\n    }\n\n    override Expression syntaxCopy()\n    {\n        auto se = new SliceExp(loc, e1.syntaxCopy(), lwr ? lwr.syntaxCopy() : null, upr ? upr.syntaxCopy() : null);\n        se.lengthVar = this.lengthVar; // bug7871\n        return se;\n    }\n\n    override int checkModifiable(Scope* sc, int flag)\n    {\n        //printf(\"SliceExp::checkModifiable %s\\n\", toChars());\n        if (e1.type.ty == Tsarray || (e1.op == TOK.index && e1.type.ty != Tarray) || e1.op == TOK.slice)\n        {\n            return e1.checkModifiable(sc, flag);\n        }\n        return 1;\n    }\n\n    override bool isLvalue()\n    {\n        /* slice expression is rvalue in default, but\n         * conversion to reference of static array is only allowed.\n         */\n        return (type && type.toBasetype().ty == Tsarray);\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        //printf(\"SliceExp::toLvalue(%s) type = %s\\n\", toChars(), type ? type.toChars() : NULL);\n        return (type && type.toBasetype().ty == Tsarray) ? this : Expression.toLvalue(sc, e);\n    }\n\n    override Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        error(\"slice expression `%s` is not a modifiable lvalue\", toChars());\n        return this;\n    }\n\n    override bool isBool(bool result)\n    {\n        return e1.isBool(result);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ArrayLengthExp : UnaExp\n{\n    extern (D) this(const ref Loc loc, Expression e1)\n    {\n        super(loc, TOK.arrayLength, __traits(classInstanceSize, ArrayLengthExp), e1);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * e1 [ a0, a1, a2, a3 ,... ]\n *\n * http://dlang.org/spec/expression.html#index_expressions\n */\nextern (C++) final class ArrayExp : UnaExp\n{\n    Expressions* arguments;     // Array of Expression's a0..an\n\n    size_t currentDimension;    // for opDollar\n    VarDeclaration lengthVar;\n\n    extern (D) this(const ref Loc loc, Expression e1, Expression index = null)\n    {\n        super(loc, TOK.array, __traits(classInstanceSize, ArrayExp), e1);\n        arguments = new Expressions();\n        if (index)\n            arguments.push(index);\n    }\n\n    extern (D) this(const ref Loc loc, Expression e1, Expressions* args)\n    {\n        super(loc, TOK.array, __traits(classInstanceSize, ArrayExp), e1);\n        arguments = args;\n    }\n\n    override Expression syntaxCopy()\n    {\n        auto ae = new ArrayExp(loc, e1.syntaxCopy(), arraySyntaxCopy(arguments));\n        ae.lengthVar = this.lengthVar; // bug7871\n        return ae;\n    }\n\n    override bool isLvalue()\n    {\n        if (type && type.toBasetype().ty == Tvoid)\n            return false;\n        return true;\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        if (type && type.toBasetype().ty == Tvoid)\n            error(\"`void`s have no value\");\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DotExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.dot, __traits(classInstanceSize, DotExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class CommaExp : BinExp\n{\n    /// This is needed because AssignExp rewrites CommaExp, hence it needs\n    /// to trigger the deprecation.\n    const bool isGenerated;\n\n    /// Temporary variable to enable / disable deprecation of comma expression\n    /// depending on the context.\n    /// Since most constructor calls are rewritting, the only place where\n    /// false will be passed will be from the parser.\n    bool allowCommaExp;\n\n\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2, bool generated = true)\n    {\n        super(loc, TOK.comma, __traits(classInstanceSize, CommaExp), e1, e2);\n        allowCommaExp = isGenerated = generated;\n    }\n\n    override int checkModifiable(Scope* sc, int flag)\n    {\n        return e2.checkModifiable(sc, flag);\n    }\n\n    override bool isLvalue()\n    {\n        return e2.isLvalue();\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        e2 = e2.toLvalue(sc, null);\n        return this;\n    }\n\n    override Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        e2 = e2.modifiableLvalue(sc, e);\n        return this;\n    }\n\n    override bool isBool(bool result)\n    {\n        return e2.isBool(result);\n    }\n\n    override Expression toBoolean(Scope* sc)\n    {\n        auto ex2 = e2.toBoolean(sc);\n        if (ex2.op == TOK.error)\n            return ex2;\n        e2 = ex2;\n        type = e2.type;\n        return this;\n    }\n\n    override Expression addDtorHook(Scope* sc)\n    {\n        e2 = e2.addDtorHook(sc);\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    /**\n     * If the argument is a CommaExp, set a flag to prevent deprecation messages\n     *\n     * It's impossible to know from CommaExp.semantic if the result will\n     * be used, hence when there is a result (type != void), a deprecation\n     * message is always emitted.\n     * However, some construct can produce a result but won't use it\n     * (ExpStatement and for loop increment).  Those should call this function\n     * to prevent unwanted deprecations to be emitted.\n     *\n     * Params:\n     *   exp = An expression that discards its result.\n     *         If the argument is null or not a CommaExp, nothing happens.\n     */\n    static void allow(Expression exp)\n    {\n        if (exp && exp.op == TOK.comma)\n            (cast(CommaExp)exp).allowCommaExp = true;\n    }\n}\n\n/***********************************************************\n * Mainly just a placeholder\n */\nextern (C++) final class IntervalExp : Expression\n{\n    Expression lwr;\n    Expression upr;\n\n    extern (D) this(const ref Loc loc, Expression lwr, Expression upr)\n    {\n        super(loc, TOK.interval, __traits(classInstanceSize, IntervalExp));\n        this.lwr = lwr;\n        this.upr = upr;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new IntervalExp(loc, lwr.syntaxCopy(), upr.syntaxCopy());\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\nextern (C++) final class DelegatePtrExp : UnaExp\n{\n    extern (D) this(const ref Loc loc, Expression e1)\n    {\n        super(loc, TOK.delegatePointer, __traits(classInstanceSize, DelegatePtrExp), e1);\n    }\n\n    override bool isLvalue()\n    {\n        return e1.isLvalue();\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        e1 = e1.toLvalue(sc, e);\n        return this;\n    }\n\n    override Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        if (sc.func.setUnsafe())\n        {\n            error(\"cannot modify delegate pointer in `@safe` code `%s`\", toChars());\n            return new ErrorExp();\n        }\n        return Expression.modifiableLvalue(sc, e);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DelegateFuncptrExp : UnaExp\n{\n    extern (D) this(const ref Loc loc, Expression e1)\n    {\n        super(loc, TOK.delegateFunctionPointer, __traits(classInstanceSize, DelegateFuncptrExp), e1);\n    }\n\n    override bool isLvalue()\n    {\n        return e1.isLvalue();\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        e1 = e1.toLvalue(sc, e);\n        return this;\n    }\n\n    override Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        if (sc.func.setUnsafe())\n        {\n            error(\"cannot modify delegate function pointer in `@safe` code `%s`\", toChars());\n            return new ErrorExp();\n        }\n        return Expression.modifiableLvalue(sc, e);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * e1 [ e2 ]\n */\nextern (C++) final class IndexExp : BinExp\n{\n    VarDeclaration lengthVar;\n    bool modifiable = false;    // assume it is an rvalue\n    bool indexIsInBounds;       // true if 0 <= e2 && e2 <= e1.length - 1\n\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.index, __traits(classInstanceSize, IndexExp), e1, e2);\n        //printf(\"IndexExp::IndexExp('%s')\\n\", toChars());\n    }\n\n    override Expression syntaxCopy()\n    {\n        auto ie = new IndexExp(loc, e1.syntaxCopy(), e2.syntaxCopy());\n        ie.lengthVar = this.lengthVar; // bug7871\n        return ie;\n    }\n\n    override int checkModifiable(Scope* sc, int flag)\n    {\n        if (e1.type.ty == Tsarray || e1.type.ty == Taarray || (e1.op == TOK.index && e1.type.ty != Tarray) || e1.op == TOK.slice)\n        {\n            return e1.checkModifiable(sc, flag);\n        }\n        return 1;\n    }\n\n    override bool isLvalue()\n    {\n        return true;\n    }\n\n    override Expression toLvalue(Scope* sc, Expression e)\n    {\n        return this;\n    }\n\n    override Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        //printf(\"IndexExp::modifiableLvalue(%s)\\n\", toChars());\n        Expression ex = markSettingAAElem();\n        if (ex.op == TOK.error)\n            return ex;\n\n        return Expression.modifiableLvalue(sc, e);\n    }\n\n    Expression markSettingAAElem()\n    {\n        if (e1.type.toBasetype().ty == Taarray)\n        {\n            Type t2b = e2.type.toBasetype();\n            if (t2b.ty == Tarray && t2b.nextOf().isMutable())\n            {\n                error(\"associative arrays can only be assigned values with immutable keys, not `%s`\", e2.type.toChars());\n                return new ErrorExp();\n            }\n            modifiable = true;\n\n            if (e1.op == TOK.index)\n            {\n                Expression ex = (cast(IndexExp)e1).markSettingAAElem();\n                if (ex.op == TOK.error)\n                    return ex;\n                assert(ex == e1);\n            }\n        }\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * For both i++ and i--\n */\nextern (C++) final class PostExp : BinExp\n{\n    extern (D) this(TOK op, const ref Loc loc, Expression e)\n    {\n        super(loc, op, __traits(classInstanceSize, PostExp), e, new IntegerExp(loc, 1, Type.tint32));\n        assert(op == TOK.minusMinus || op == TOK.plusPlus);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * For both ++i and --i\n */\nextern (C++) final class PreExp : UnaExp\n{\n    extern (D) this(TOK op, const ref Loc loc, Expression e)\n    {\n        super(loc, op, __traits(classInstanceSize, PreExp), e);\n        assert(op == TOK.preMinusMinus || op == TOK.prePlusPlus);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\nenum MemorySet\n{\n    blockAssign     = 1,    // setting the contents of an array\n    referenceInit   = 2,    // setting the reference of STC.ref_ variable\n}\n\n/***********************************************************\n */\nextern (C++) class AssignExp : BinExp\n{\n    int memset;         // combination of MemorySet flags\n\n    /************************************************************/\n    /* op can be TOK.assign, TOK.construct, or TOK.blit */\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.assign, __traits(classInstanceSize, AssignExp), e1, e2);\n    }\n\n    override final bool isLvalue()\n    {\n        // Array-op 'x[] = y[]' should make an rvalue.\n        // Setting array length 'x.length = v' should make an rvalue.\n        if (e1.op == TOK.slice || e1.op == TOK.arrayLength)\n        {\n            return false;\n        }\n        return true;\n    }\n\n    override final Expression toLvalue(Scope* sc, Expression ex)\n    {\n        if (e1.op == TOK.slice || e1.op == TOK.arrayLength)\n        {\n            return Expression.toLvalue(sc, ex);\n        }\n\n        /* In front-end level, AssignExp should make an lvalue of e1.\n         * Taking the address of e1 will be handled in low level layer,\n         * so this function does nothing.\n         */\n        return this;\n    }\n\n    override final Expression toBoolean(Scope* sc)\n    {\n        // Things like:\n        //  if (a = b) ...\n        // are usually mistakes.\n\n        error(\"assignment cannot be used as a condition, perhaps `==` was meant?\");\n        return new ErrorExp();\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ConstructExp : AssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, e1, e2);\n        op = TOK.construct;\n    }\n\n    // Internal use only. If `v` is a reference variable, the assinment\n    // will become a reference initialization automatically.\n    extern (D) this(const ref Loc loc, VarDeclaration v, Expression e2)\n    {\n        auto ve = new VarExp(loc, v);\n        assert(v.type && ve.type);\n\n        super(loc, ve, e2);\n        op = TOK.construct;\n\n        if (v.storage_class & (STC.ref_ | STC.out_))\n            memset |= MemorySet.referenceInit;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class BlitExp : AssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, e1, e2);\n        op = TOK.blit;\n    }\n\n    // Internal use only. If `v` is a reference variable, the assinment\n    // will become a reference rebinding automatically.\n    extern (D) this(const ref Loc loc, VarDeclaration v, Expression e2)\n    {\n        auto ve = new VarExp(loc, v);\n        assert(v.type && ve.type);\n\n        super(loc, ve, e2);\n        op = TOK.blit;\n\n        if (v.storage_class & (STC.ref_ | STC.out_))\n            memset |= MemorySet.referenceInit;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class AddAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.addAssign, __traits(classInstanceSize, AddAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class MinAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.minAssign, __traits(classInstanceSize, MinAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class MulAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.mulAssign, __traits(classInstanceSize, MulAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DivAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.divAssign, __traits(classInstanceSize, DivAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ModAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.modAssign, __traits(classInstanceSize, ModAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class AndAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.andAssign, __traits(classInstanceSize, AndAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class OrAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.orAssign, __traits(classInstanceSize, OrAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class XorAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.xorAssign, __traits(classInstanceSize, XorAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class PowAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.powAssign, __traits(classInstanceSize, PowAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ShlAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.leftShiftAssign, __traits(classInstanceSize, ShlAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ShrAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.rightShiftAssign, __traits(classInstanceSize, ShrAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class UshrAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.unsignedRightShiftAssign, __traits(classInstanceSize, UshrAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * The ~= operator. It can have one of the following operators:\n *\n * TOK.concatenateAssign      - appending T[] to T[]\n * TOK.concatenateElemAssign  - appending T to T[]\n * TOK.concatenateDcharAssign - appending dchar to T[]\n *\n * The parser initially sets it to TOK.concatenateAssign, and semantic() later decides which\n * of the three it will be set to.\n */\nextern (C++) final class CatAssignExp : BinAssignExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.concatenateAssign, __traits(classInstanceSize, CatAssignExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#add_expressions\n */\nextern (C++) final class AddExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.add, __traits(classInstanceSize, AddExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class MinExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.min, __traits(classInstanceSize, MinExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#cat_expressions\n */\nextern (C++) final class CatExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.concatenate, __traits(classInstanceSize, CatExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#mul_expressions\n */\nextern (C++) final class MulExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.mul, __traits(classInstanceSize, MulExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#mul_expressions\n */\nextern (C++) final class DivExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.div, __traits(classInstanceSize, DivExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#mul_expressions\n */\nextern (C++) final class ModExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.mod, __traits(classInstanceSize, ModExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#pow_expressions\n */\nextern (C++) final class PowExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.pow, __traits(classInstanceSize, PowExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ShlExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.leftShift, __traits(classInstanceSize, ShlExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ShrExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.rightShift, __traits(classInstanceSize, ShrExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class UshrExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.unsignedRightShift, __traits(classInstanceSize, UshrExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class AndExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.and, __traits(classInstanceSize, AndExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class OrExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.or, __traits(classInstanceSize, OrExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class XorExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.xor, __traits(classInstanceSize, XorExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * http://dlang.org/spec/expression.html#andand_expressions\n * http://dlang.org/spec/expression.html#oror_expressions\n */\nextern (C++) final class LogicalExp : BinExp\n{\n    extern (D) this(const ref Loc loc, TOK op, Expression e1, Expression e2)\n    {\n        super(loc, op, __traits(classInstanceSize, LogicalExp), e1, e2);\n        assert(op == TOK.andAnd || op == TOK.orOr);\n    }\n\n    override Expression toBoolean(Scope* sc)\n    {\n        auto ex2 = e2.toBoolean(sc);\n        if (ex2.op == TOK.error)\n            return ex2;\n        e2 = ex2;\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * `op` is one of:\n *      TOK.lessThan, TOK.lessOrEqual, TOK.greaterThan, TOK.greaterOrEqual\n *\n * http://dlang.org/spec/expression.html#relation_expressions\n */\nextern (C++) final class CmpExp : BinExp\n{\n    extern (D) this(TOK op, const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, op, __traits(classInstanceSize, CmpExp), e1, e2);\n        assert(op == TOK.lessThan || op == TOK.lessOrEqual || op == TOK.greaterThan || op == TOK.greaterOrEqual);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class InExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.in_, __traits(classInstanceSize, InExp), e1, e2);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * This deletes the key e1 from the associative array e2\n */\nextern (C++) final class RemoveExp : BinExp\n{\n    extern (D) this(const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, TOK.remove, __traits(classInstanceSize, RemoveExp), e1, e2);\n        type = Type.tbool;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * `==` and `!=`\n *\n * TOK.equal and TOK.notEqual\n *\n * http://dlang.org/spec/expression.html#equality_expressions\n */\nextern (C++) final class EqualExp : BinExp\n{\n    extern (D) this(TOK op, const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, op, __traits(classInstanceSize, EqualExp), e1, e2);\n        assert(op == TOK.equal || op == TOK.notEqual);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * `is` and `!is`\n *\n * TOK.identity and TOK.notIdentity\n *\n *  http://dlang.org/spec/expression.html#identity_expressions\n */\nextern (C++) final class IdentityExp : BinExp\n{\n    extern (D) this(TOK op, const ref Loc loc, Expression e1, Expression e2)\n    {\n        super(loc, op, __traits(classInstanceSize, IdentityExp), e1, e2);\n        assert(op == TOK.identity || op == TOK.notIdentity);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * `econd ? e1 : e2`\n *\n * http://dlang.org/spec/expression.html#conditional_expressions\n */\nextern (C++) final class CondExp : BinExp\n{\n    Expression econd;\n\n    extern (D) this(const ref Loc loc, Expression econd, Expression e1, Expression e2)\n    {\n        super(loc, TOK.question, __traits(classInstanceSize, CondExp), e1, e2);\n        this.econd = econd;\n    }\n\n    override Expression syntaxCopy()\n    {\n        return new CondExp(loc, econd.syntaxCopy(), e1.syntaxCopy(), e2.syntaxCopy());\n    }\n\n    override int checkModifiable(Scope* sc, int flag)\n    {\n        return e1.checkModifiable(sc, flag) && e2.checkModifiable(sc, flag);\n    }\n\n    override bool isLvalue()\n    {\n        return e1.isLvalue() && e2.isLvalue();\n    }\n\n    override Expression toLvalue(Scope* sc, Expression ex)\n    {\n        // convert (econd ? e1 : e2) to *(econd ? &e1 : &e2)\n        CondExp e = cast(CondExp)copy();\n        e.e1 = e1.toLvalue(sc, null).addressOf();\n        e.e2 = e2.toLvalue(sc, null).addressOf();\n        e.type = type.pointerTo();\n        return new PtrExp(loc, e, type);\n    }\n\n    override Expression modifiableLvalue(Scope* sc, Expression e)\n    {\n        //error(\"conditional expression %s is not a modifiable lvalue\", toChars());\n        e1 = e1.modifiableLvalue(sc, e1);\n        e2 = e2.modifiableLvalue(sc, e2);\n        return toLvalue(sc, this);\n    }\n\n    override Expression toBoolean(Scope* sc)\n    {\n        auto ex1 = e1.toBoolean(sc);\n        auto ex2 = e2.toBoolean(sc);\n        if (ex1.op == TOK.error)\n            return ex1;\n        if (ex2.op == TOK.error)\n            return ex2;\n        e1 = ex1;\n        e2 = ex2;\n        return this;\n    }\n\n    void hookDtors(Scope* sc)\n    {\n        extern (C++) final class DtorVisitor : StoppableVisitor\n        {\n            alias visit = typeof(super).visit;\n        public:\n            Scope* sc;\n            CondExp ce;\n            VarDeclaration vcond;\n            bool isThen;\n\n            extern (D) this(Scope* sc, CondExp ce)\n            {\n                this.sc = sc;\n                this.ce = ce;\n            }\n\n            override void visit(Expression e)\n            {\n                //printf(\"(e = %s)\\n\", e.toChars());\n            }\n\n            override void visit(DeclarationExp e)\n            {\n                auto v = e.declaration.isVarDeclaration();\n                if (v && !v.isDataseg())\n                {\n                    if (v._init)\n                    {\n                        if (auto ei = v._init.isExpInitializer())\n                            ei.exp.accept(this);\n                    }\n\n                    if (v.needsScopeDtor())\n                    {\n                        if (!vcond)\n                        {\n                            vcond = copyToTemp(STC.volatile_, \"__cond\", ce.econd);\n                            vcond.dsymbolSemantic(sc);\n\n                            Expression de = new DeclarationExp(ce.econd.loc, vcond);\n                            de = de.expressionSemantic(sc);\n\n                            Expression ve = new VarExp(ce.econd.loc, vcond);\n                            ce.econd = Expression.combine(de, ve);\n                        }\n\n                        //printf(\"\\t++v = %s, v.edtor = %s\\n\", v.toChars(), v.edtor.toChars());\n                        Expression ve = new VarExp(vcond.loc, vcond);\n                        if (isThen)\n                            v.edtor = new LogicalExp(v.edtor.loc, TOK.andAnd, ve, v.edtor);\n                        else\n                            v.edtor = new LogicalExp(v.edtor.loc, TOK.orOr, ve, v.edtor);\n                        v.edtor = v.edtor.expressionSemantic(sc);\n                        //printf(\"\\t--v = %s, v.edtor = %s\\n\", v.toChars(), v.edtor.toChars());\n                    }\n                }\n            }\n        }\n\n        scope DtorVisitor v = new DtorVisitor(sc, this);\n        //printf(\"+%s\\n\", toChars());\n        v.isThen = true;\n        walkPostorder(e1, v);\n        v.isThen = false;\n        walkPostorder(e2, v);\n        //printf(\"-%s\\n\", toChars());\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class DefaultInitExp : Expression\n{\n    TOK subop;      // which of the derived classes this is\n\n    extern (D) this(const ref Loc loc, TOK subop, int size)\n    {\n        super(loc, TOK.default_, size);\n        this.subop = subop;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class FileInitExp : DefaultInitExp\n{\n    extern (D) this(const ref Loc loc, TOK tok)\n    {\n        super(loc, tok, __traits(classInstanceSize, FileInitExp));\n    }\n\n    override Expression resolveLoc(const ref Loc loc, Scope* sc)\n    {\n        //printf(\"FileInitExp::resolve() %s\\n\", toChars());\n        const(char)* s;\n        if (subop == TOK.fileFullPath)\n            s = FileName.toAbsolute(loc.isValid() ? loc.filename : sc._module.srcfile.name.toChars());\n        else\n            s = loc.isValid() ? loc.filename : sc._module.ident.toChars();\n\n        Expression e = new StringExp(loc, cast(char*)s);\n        e = e.expressionSemantic(sc);\n        e = e.castTo(sc, type);\n        return e;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class LineInitExp : DefaultInitExp\n{\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc, TOK.line, __traits(classInstanceSize, LineInitExp));\n    }\n\n    override Expression resolveLoc(const ref Loc loc, Scope* sc)\n    {\n        Expression e = new IntegerExp(loc, loc.linnum, Type.tint32);\n        e = e.castTo(sc, type);\n        return e;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ModuleInitExp : DefaultInitExp\n{\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc, TOK.moduleString, __traits(classInstanceSize, ModuleInitExp));\n    }\n\n    override Expression resolveLoc(const ref Loc loc, Scope* sc)\n    {\n        const(char)* s;\n        if (sc.callsc)\n            s = sc.callsc._module.toPrettyChars();\n        else\n            s = sc._module.toPrettyChars();\n        Expression e = new StringExp(loc, cast(char*)s);\n        e = e.expressionSemantic(sc);\n        e = e.castTo(sc, type);\n        return e;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class FuncInitExp : DefaultInitExp\n{\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc, TOK.functionString, __traits(classInstanceSize, FuncInitExp));\n    }\n\n    override Expression resolveLoc(const ref Loc loc, Scope* sc)\n    {\n        const(char)* s;\n        if (sc.callsc && sc.callsc.func)\n            s = sc.callsc.func.Dsymbol.toPrettyChars();\n        else if (sc.func)\n            s = sc.func.Dsymbol.toPrettyChars();\n        else\n            s = \"\";\n        Expression e = new StringExp(loc, cast(char*)s);\n        e = e.expressionSemantic(sc);\n        e = e.castTo(sc, type);\n        return e;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class PrettyFuncInitExp : DefaultInitExp\n{\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc, TOK.prettyFunction, __traits(classInstanceSize, PrettyFuncInitExp));\n    }\n\n    override Expression resolveLoc(const ref Loc loc, Scope* sc)\n    {\n        FuncDeclaration fd;\n        if (sc.callsc && sc.callsc.func)\n            fd = sc.callsc.func;\n        else\n            fd = sc.func;\n\n        const(char)* s;\n        if (fd)\n        {\n            const(char)* funcStr = fd.Dsymbol.toPrettyChars();\n            OutBuffer buf;\n            functionToBufferWithIdent(cast(TypeFunction)fd.type, &buf, funcStr);\n            s = buf.extractString();\n        }\n        else\n        {\n            s = \"\";\n        }\n\n        Expression e = new StringExp(loc, cast(char*)s);\n        e = e.expressionSemantic(sc);\n        e = e.castTo(sc, type);\n        return e;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/**\n * Objective-C class reference expression.\n *\n * Used to get the metaclass of an Objective-C class, `NSObject.Class`.\n */\nextern (C++) final class ObjcClassReferenceExp : Expression\n{\n    ClassDeclaration classDeclaration;\n\n    extern (D) this(const ref Loc loc, ClassDeclaration classDeclaration)\n    {\n        super(loc, TOK.objcClassReference,\n            __traits(classInstanceSize, ObjcClassReferenceExp));\n        this.classDeclaration = classDeclaration;\n        type = objc.getRuntimeMetaclass(classDeclaration).getType();\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/expression.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/expression.h\n */\n\n#pragma once\n\n#include \"complex_t.h\"\n#include \"globals.h\"\n#include \"arraytypes.h\"\n#include \"visitor.h\"\n#include \"tokens.h\"\n\n#include \"root/rmem.h\"\n\nclass Type;\nclass TypeVector;\nstruct Scope;\nclass TupleDeclaration;\nclass VarDeclaration;\nclass FuncDeclaration;\nclass FuncLiteralDeclaration;\nclass CtorDeclaration;\nclass NewDeclaration;\nclass Dsymbol;\nclass ScopeDsymbol;\nclass Expression;\nclass Declaration;\nclass StructDeclaration;\nclass TemplateInstance;\nclass TemplateDeclaration;\nclass ClassDeclaration;\nclass OverloadSet;\nclass StringExp;\nstruct UnionExp;\n#ifdef IN_GCC\ntypedef union tree_node Symbol;\n#else\nstruct Symbol;          // back end symbol\n#endif\n\nvoid expandTuples(Expressions *exps);\nTupleDeclaration *isAliasThisTuple(Expression *e);\nint expandAliasThisTuples(Expressions *exps, size_t starti = 0);\nbool arrayExpressionSemantic(Expressions *exps, Scope *sc, bool preserveErrors = false);\nTemplateDeclaration *getFuncTemplateDecl(Dsymbol *s);\nbool isTrivialExp(Expression *e);\n\nExpression *toDelegate(Expression *e, Type* t, Scope *sc);\nbool hasSideEffect(Expression *e);\nbool canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow);\n\nenum OwnedBy\n{\n    OWNEDcode,      // normal code expression in AST\n    OWNEDctfe,      // value expression for CTFE\n    OWNEDcache      // constant value cached for CTFE\n};\n\nclass Expression : public RootObject\n{\npublic:\n    Loc loc;                    // file location\n    Type *type;                 // !=NULL means that semantic() has been run\n    TOK op;                     // to minimize use of dynamic_cast\n    unsigned char size;         // # of bytes in Expression so we can copy() it\n    unsigned char parens;       // if this is a parenthesized expression\n\n    static void _init();\n    Expression *copy();\n    virtual Expression *syntaxCopy();\n\n    // kludge for template.isExpression()\n    int dyncast() const { return DYNCAST_EXPRESSION; }\n\n    const char *toChars();\n    void error(const char *format, ...) const;\n    void warning(const char *format, ...) const;\n    void deprecation(const char *format, ...) const;\n\n    virtual dinteger_t toInteger();\n    virtual uinteger_t toUInteger();\n    virtual real_t toReal();\n    virtual real_t toImaginary();\n    virtual complex_t toComplex();\n    virtual StringExp *toStringExp();\n    virtual bool isLvalue();\n    virtual Expression *toLvalue(Scope *sc, Expression *e);\n    virtual Expression *modifiableLvalue(Scope *sc, Expression *e);\n    Expression *implicitCastTo(Scope *sc, Type *t);\n    MATCH implicitConvTo(Type *t);\n    Expression *castTo(Scope *sc, Type *t);\n    virtual Expression *resolveLoc(const Loc &loc, Scope *sc);\n    virtual bool checkType();\n    virtual bool checkValue();\n    bool checkDeprecated(Scope *sc, Dsymbol *s);\n    virtual int checkModifiable(Scope *sc, int flag = 0);\n    virtual Expression *toBoolean(Scope *sc);\n    virtual Expression *addDtorHook(Scope *sc);\n    Expression *addressOf();\n    Expression *deref();\n\n    Expression *optimize(int result, bool keepLvalue = false);\n\n    // Entry point for CTFE.\n    // A compile-time result is required. Give an error if not possible\n    Expression *ctfeInterpret();\n    int isConst();\n    virtual bool isBool(bool result);\n\n    virtual bool hasCode()\n    {\n        return true;\n    }\n\n    virtual void accept(Visitor *v) { v->visit(this); }\n};\n\nclass IntegerExp : public Expression\n{\npublic:\n    dinteger_t value;\n\n    static IntegerExp *create(Loc loc, dinteger_t value, Type *type);\n    static IntegerExp *createi(Loc loc, int value, Type *type);\n    bool equals(RootObject *o);\n    dinteger_t toInteger();\n    real_t toReal();\n    real_t toImaginary();\n    complex_t toComplex();\n    bool isBool(bool result);\n    Expression *toLvalue(Scope *sc, Expression *e);\n    void accept(Visitor *v) { v->visit(this); }\n    dinteger_t getInteger() { return value; }\n    void setInteger(dinteger_t value);\n    void normalize();\n};\n\nclass ErrorExp : public Expression\n{\npublic:\n    Expression *toLvalue(Scope *sc, Expression *e);\n    void accept(Visitor *v) { v->visit(this); }\n\n    static ErrorExp *errorexp; // handy shared value\n};\n\nclass RealExp : public Expression\n{\npublic:\n    real_t value;\n\n    static RealExp *create(Loc loc, real_t value, Type *type);\n    bool equals(RootObject *o);\n    dinteger_t toInteger();\n    uinteger_t toUInteger();\n    real_t toReal();\n    real_t toImaginary();\n    complex_t toComplex();\n    bool isBool(bool result);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ComplexExp : public Expression\n{\npublic:\n    complex_t value;\n\n    static ComplexExp *create(Loc loc, complex_t value, Type *type);\n    bool equals(RootObject *o);\n    dinteger_t toInteger();\n    uinteger_t toUInteger();\n    real_t toReal();\n    real_t toImaginary();\n    complex_t toComplex();\n    bool isBool(bool result);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass IdentifierExp : public Expression\n{\npublic:\n    Identifier *ident;\n\n    static IdentifierExp *create(Loc loc, Identifier *ident);\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DollarExp : public IdentifierExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DsymbolExp : public Expression\n{\npublic:\n    Dsymbol *s;\n    bool hasOverloads;\n\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ThisExp : public Expression\n{\npublic:\n    VarDeclaration *var;\n\n    bool isBool(bool result);\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass SuperExp : public ThisExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass NullExp : public Expression\n{\npublic:\n    unsigned char committed;    // !=0 if type is committed\n\n    bool equals(RootObject *o);\n    bool isBool(bool result);\n    StringExp *toStringExp();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StringExp : public Expression\n{\npublic:\n    void *string;       // char, wchar, or dchar data\n    size_t len;         // number of chars, wchars, or dchars\n    unsigned char sz;   // 1: char, 2: wchar, 4: dchar\n    unsigned char committed;    // !=0 if type is committed\n    utf8_t postfix;      // 'c', 'w', 'd'\n    OwnedBy ownedByCtfe;\n\n    static StringExp *create(Loc loc, char *s);\n    static StringExp *create(Loc loc, void *s, size_t len);\n    bool equals(RootObject *o);\n    StringExp *toStringExp();\n    StringExp *toUTF8(Scope *sc);\n    int compare(RootObject *obj);\n    bool isBool(bool result);\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    Expression *modifiableLvalue(Scope *sc, Expression *e);\n    unsigned charAt(uinteger_t i) const;\n    void accept(Visitor *v) { v->visit(this); }\n    size_t numberOfCodeUnits(int tynto = 0) const;\n    void writeTo(void* dest, bool zero, int tyto = 0) const;\n    char *toPtr();\n};\n\n// Tuple\n\nclass TupleExp : public Expression\n{\npublic:\n    Expression *e0;     // side-effect part\n    /* Tuple-field access may need to take out its side effect part.\n     * For example:\n     *      foo().tupleof\n     * is rewritten as:\n     *      (ref __tup = foo(); tuple(__tup.field0, __tup.field1, ...))\n     * The declaration of temporary variable __tup will be stored in TupleExp::e0.\n     */\n    Expressions *exps;\n\n    Expression *syntaxCopy();\n    bool equals(RootObject *o);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ArrayLiteralExp : public Expression\n{\npublic:\n    Expression *basis;\n    Expressions *elements;\n    OwnedBy ownedByCtfe;\n\n    static ArrayLiteralExp *create(Loc loc, Expressions *elements);\n    Expression *syntaxCopy();\n    bool equals(RootObject *o);\n    Expression *getElement(d_size_t i);\n    bool isBool(bool result);\n    StringExp *toStringExp();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass AssocArrayLiteralExp : public Expression\n{\npublic:\n    Expressions *keys;\n    Expressions *values;\n    OwnedBy ownedByCtfe;\n\n    bool equals(RootObject *o);\n    Expression *syntaxCopy();\n    bool isBool(bool result);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StructLiteralExp : public Expression\n{\npublic:\n    StructDeclaration *sd;      // which aggregate this is for\n    Expressions *elements;      // parallels sd->fields[] with NULL entries for fields to skip\n    Type *stype;                // final type of result (can be different from sd's type)\n\n    bool useStaticInit;         // if this is true, use the StructDeclaration's init symbol\n    Symbol *sym;                // back end symbol to initialize with literal\n\n    OwnedBy ownedByCtfe;\n\n    // pointer to the origin instance of the expression.\n    // once a new expression is created, origin is set to 'this'.\n    // anytime when an expression copy is created, 'origin' pointer is set to\n    // 'origin' pointer value of the original expression.\n    StructLiteralExp *origin;\n\n    // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.\n    StructLiteralExp *inlinecopy;\n\n    // anytime when recursive function is calling, 'stageflags' marks with bit flag of\n    // current stage and unmarks before return from this function.\n    // 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'\n    // (with infinite recursion) of this expression.\n    int stageflags;\n\n    static StructLiteralExp *create(Loc loc, StructDeclaration *sd, void *elements, Type *stype = NULL);\n    bool equals(RootObject *o);\n    Expression *syntaxCopy();\n    Expression *getField(Type *type, unsigned offset);\n    int getFieldIndex(Type *type, unsigned offset);\n    Expression *addDtorHook(Scope *sc);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeExp : public Expression\n{\npublic:\n    Expression *syntaxCopy();\n    bool checkType();\n    bool checkValue();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ScopeExp : public Expression\n{\npublic:\n    ScopeDsymbol *sds;\n\n    Expression *syntaxCopy();\n    bool checkType();\n    bool checkValue();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TemplateExp : public Expression\n{\npublic:\n    TemplateDeclaration *td;\n    FuncDeclaration *fd;\n\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    bool checkType();\n    bool checkValue();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass NewExp : public Expression\n{\npublic:\n    /* thisexp.new(newargs) newtype(arguments)\n     */\n    Expression *thisexp;        // if !NULL, 'this' for class being allocated\n    Expressions *newargs;       // Array of Expression's to call new operator\n    Type *newtype;\n    Expressions *arguments;     // Array of Expression's\n\n    Expression *argprefix;      // expression to be evaluated just before arguments[]\n\n    CtorDeclaration *member;    // constructor function\n    NewDeclaration *allocator;  // allocator function\n    bool onstack;               // allocate on stack\n    bool thrownew;              // this NewExp is the expression of a ThrowStatement\n\n    static NewExp *create(Loc loc, Expression *thisexp, Expressions *newargs, Type *newtype, Expressions *arguments);\n    Expression *syntaxCopy();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass NewAnonClassExp : public Expression\n{\npublic:\n    /* thisexp.new(newargs) class baseclasses { } (arguments)\n     */\n    Expression *thisexp;        // if !NULL, 'this' for class being allocated\n    Expressions *newargs;       // Array of Expression's to call new operator\n    ClassDeclaration *cd;       // class being instantiated\n    Expressions *arguments;     // Array of Expression's to call class constructor\n\n    Expression *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass SymbolExp : public Expression\n{\npublic:\n    Declaration *var;\n    bool hasOverloads;\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// Offset from symbol\n\nclass SymOffExp : public SymbolExp\n{\npublic:\n    dinteger_t offset;\n\n    bool isBool(bool result);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// Variable\n\nclass VarExp : public SymbolExp\n{\npublic:\n    static VarExp *create(Loc loc, Declaration *var, bool hasOverloads = true);\n    bool equals(RootObject *o);\n    int checkModifiable(Scope *sc, int flag);\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    Expression *modifiableLvalue(Scope *sc, Expression *e);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// Overload Set\n\nclass OverExp : public Expression\n{\npublic:\n    OverloadSet *vars;\n\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// Function/Delegate literal\n\nclass FuncExp : public Expression\n{\npublic:\n    FuncLiteralDeclaration *fd;\n    TemplateDeclaration *td;\n    TOK tok;\n\n    bool equals(RootObject *o);\n    Expression *syntaxCopy();\n    const char *toChars();\n    bool checkType();\n    bool checkValue();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// Declaration of a symbol\n\n// D grammar allows declarations only as statements. However in AST representation\n// it can be part of any expression. This is used, for example, during internal\n// syntax re-writes to inject hidden symbols.\nclass DeclarationExp : public Expression\n{\npublic:\n    Dsymbol *declaration;\n\n    Expression *syntaxCopy();\n\n    bool hasCode();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeidExp : public Expression\n{\npublic:\n    RootObject *obj;\n\n    Expression *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TraitsExp : public Expression\n{\npublic:\n    Identifier *ident;\n    Objects *args;\n\n    Expression *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass HaltExp : public Expression\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass IsExp : public Expression\n{\npublic:\n    /* is(targ id tok tspec)\n     * is(targ id == tok2)\n     */\n    Type *targ;\n    Identifier *id;     // can be NULL\n    TOK tok;       // ':' or '=='\n    Type *tspec;        // can be NULL\n    TOK tok2;      // 'struct', 'union', etc.\n    TemplateParameters *parameters;\n\n    Expression *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/****************************************************************/\n\nclass UnaExp : public Expression\n{\npublic:\n    Expression *e1;\n    Type *att1; // Save alias this type to detect recursion\n\n    Expression *syntaxCopy();\n    Expression *incompatibleTypes();\n    Expression *resolveLoc(const Loc &loc, Scope *sc);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass BinExp : public Expression\n{\npublic:\n    Expression *e1;\n    Expression *e2;\n\n    Type *att1; // Save alias this type to detect recursion\n    Type *att2; // Save alias this type to detect recursion\n\n    Expression *syntaxCopy();\n    Expression *incompatibleTypes();\n\n    Expression *reorderSettingAAElem(Scope *sc);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass BinAssignExp : public BinExp\n{\npublic:\n\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *ex);\n    Expression *modifiableLvalue(Scope *sc, Expression *e);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/****************************************************************/\n\nclass CompileExp : public UnaExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ImportExp : public UnaExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass AssertExp : public UnaExp\n{\npublic:\n    Expression *msg;\n\n    Expression *syntaxCopy();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DotIdExp : public UnaExp\n{\npublic:\n    Identifier *ident;\n    bool noderef;       // true if the result of the expression will never be dereferenced\n    bool wantsym;       // do not replace Symbol with its initializer during semantic()\n\n    static DotIdExp *create(Loc loc, Expression *e, Identifier *ident);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DotTemplateExp : public UnaExp\n{\npublic:\n    TemplateDeclaration *td;\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DotVarExp : public UnaExp\n{\npublic:\n    Declaration *var;\n    bool hasOverloads;\n\n    int checkModifiable(Scope *sc, int flag);\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    Expression *modifiableLvalue(Scope *sc, Expression *e);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DotTemplateInstanceExp : public UnaExp\n{\npublic:\n    TemplateInstance *ti;\n\n    Expression *syntaxCopy();\n    bool findTempDecl(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DelegateExp : public UnaExp\n{\npublic:\n    FuncDeclaration *func;\n    bool hasOverloads;\n\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DotTypeExp : public UnaExp\n{\npublic:\n    Dsymbol *sym;               // symbol that represents a type\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass CallExp : public UnaExp\n{\npublic:\n    Expressions *arguments;     // function arguments\n    FuncDeclaration *f;         // symbol to call\n    bool directcall;            // true if a virtual call is devirtualized\n\n    static CallExp *create(Loc loc, Expression *e, Expressions *exps);\n    static CallExp *create(Loc loc, Expression *e);\n    static CallExp *create(Loc loc, Expression *e, Expression *earg1);\n    static CallExp *create(Loc loc, FuncDeclaration *fd, Expression *earg1);\n\n    Expression *syntaxCopy();\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    Expression *addDtorHook(Scope *sc);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass AddrExp : public UnaExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass PtrExp : public UnaExp\n{\npublic:\n    int checkModifiable(Scope *sc, int flag);\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    Expression *modifiableLvalue(Scope *sc, Expression *e);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass NegExp : public UnaExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass UAddExp : public UnaExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ComExp : public UnaExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass NotExp : public UnaExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DeleteExp : public UnaExp\n{\npublic:\n    bool isRAII;\n    Expression *toBoolean(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass CastExp : public UnaExp\n{\npublic:\n    // Possible to cast to one type while painting to another type\n    Type *to;                   // type to cast to\n    unsigned char mod;          // MODxxxxx\n\n    Expression *syntaxCopy();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass VectorExp : public UnaExp\n{\npublic:\n    TypeVector *to;             // the target vector type before semantic()\n    unsigned dim;               // number of elements in the vector\n\n    static VectorExp *create(Loc loc, Expression *e, Type *t);\n    Expression *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass SliceExp : public UnaExp\n{\npublic:\n    Expression *upr;            // NULL if implicit 0\n    Expression *lwr;            // NULL if implicit [length - 1]\n    VarDeclaration *lengthVar;\n    bool upperIsInBounds;       // true if upr <= e1.length\n    bool lowerIsLessThanUpper;  // true if lwr <= upr\n    bool arrayop;               // an array operation, rather than a slice\n\n    Expression *syntaxCopy();\n    int checkModifiable(Scope *sc, int flag);\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    Expression *modifiableLvalue(Scope *sc, Expression *e);\n    bool isBool(bool result);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ArrayLengthExp : public UnaExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass IntervalExp : public Expression\n{\npublic:\n    Expression *lwr;\n    Expression *upr;\n\n    Expression *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DelegatePtrExp : public UnaExp\n{\npublic:\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    Expression *modifiableLvalue(Scope *sc, Expression *e);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DelegateFuncptrExp : public UnaExp\n{\npublic:\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    Expression *modifiableLvalue(Scope *sc, Expression *e);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// e1[a0,a1,a2,a3,...]\n\nclass ArrayExp : public UnaExp\n{\npublic:\n    Expressions *arguments;             // Array of Expression's\n    size_t currentDimension;            // for opDollar\n    VarDeclaration *lengthVar;\n\n    Expression *syntaxCopy();\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/****************************************************************/\n\nclass DotExp : public BinExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass CommaExp : public BinExp\n{\npublic:\n    bool isGenerated;\n    bool allowCommaExp;\n    int checkModifiable(Scope *sc, int flag);\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    Expression *modifiableLvalue(Scope *sc, Expression *e);\n    bool isBool(bool result);\n    Expression *toBoolean(Scope *sc);\n    Expression *addDtorHook(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass IndexExp : public BinExp\n{\npublic:\n    VarDeclaration *lengthVar;\n    bool modifiable;\n    bool indexIsInBounds;       // true if 0 <= e2 && e2 <= e1.length - 1\n\n    Expression *syntaxCopy();\n    int checkModifiable(Scope *sc, int flag);\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    Expression *modifiableLvalue(Scope *sc, Expression *e);\n\n    Expression *markSettingAAElem();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/* For both i++ and i--\n */\nclass PostExp : public BinExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/* For both ++i and --i\n */\nclass PreExp : public UnaExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nenum MemorySet\n{\n    blockAssign     = 1,    // setting the contents of an array\n    referenceInit   = 2     // setting the reference of STCref variable\n};\n\nclass AssignExp : public BinExp\n{\npublic:\n    int memset;         // combination of MemorySet flags\n\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *ex);\n    Expression *toBoolean(Scope *sc);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ConstructExp : public AssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass BlitExp : public AssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass AddAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass MinAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass MulAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DivAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ModAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass AndAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass OrAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass XorAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass PowAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ShlAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ShrAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass UshrAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass CatAssignExp : public BinAssignExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass AddExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass MinExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass CatExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass MulExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DivExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ModExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass PowExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ShlExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ShrExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass UshrExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass AndExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass OrExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass XorExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass LogicalExp : public BinExp\n{\npublic:\n    Expression *toBoolean(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass CmpExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass InExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass RemoveExp : public BinExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// == and !=\n\nclass EqualExp : public BinExp\n{\npublic:\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// is and !is\n\nclass IdentityExp : public BinExp\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/****************************************************************/\n\nclass CondExp : public BinExp\n{\npublic:\n    Expression *econd;\n\n    Expression *syntaxCopy();\n    int checkModifiable(Scope *sc, int flag);\n    bool isLvalue();\n    Expression *toLvalue(Scope *sc, Expression *e);\n    Expression *modifiableLvalue(Scope *sc, Expression *e);\n    Expression *toBoolean(Scope *sc);\n    void hookDtors(Scope *sc);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/****************************************************************/\n\nclass DefaultInitExp : public Expression\n{\npublic:\n    TOK subop;             // which of the derived classes this is\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass FileInitExp : public DefaultInitExp\n{\npublic:\n    Expression *resolveLoc(const Loc &loc, Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass LineInitExp : public DefaultInitExp\n{\npublic:\n    Expression *resolveLoc(const Loc &loc, Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ModuleInitExp : public DefaultInitExp\n{\npublic:\n    Expression *resolveLoc(const Loc &loc, Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass FuncInitExp : public DefaultInitExp\n{\npublic:\n    Expression *resolveLoc(const Loc &loc, Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass PrettyFuncInitExp : public DefaultInitExp\n{\npublic:\n    Expression *resolveLoc(const Loc &loc, Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/****************************************************************/\n\n/* A type meant as a union of all the Expression types,\n * to serve essentially as a Variant that will sit on the stack\n * during CTFE to reduce memory consumption.\n */\nstruct UnionExp\n{\n    UnionExp() { }  // yes, default constructor does nothing\n\n    UnionExp(Expression *e)\n    {\n        memcpy(this, (void *)e, e->size);\n    }\n\n    /* Extract pointer to Expression\n     */\n    Expression *exp() { return (Expression *)&u; }\n\n    /* Convert to an allocated Expression\n     */\n    Expression *copy();\n\nprivate:\n    union\n    {\n        char exp       [sizeof(Expression)];\n        char integerexp[sizeof(IntegerExp)];\n        char errorexp  [sizeof(ErrorExp)];\n        char realexp   [sizeof(RealExp)];\n        char complexexp[sizeof(ComplexExp)];\n        char symoffexp [sizeof(SymOffExp)];\n        char stringexp [sizeof(StringExp)];\n        char arrayliteralexp [sizeof(ArrayLiteralExp)];\n        char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)];\n        char structliteralexp [sizeof(StructLiteralExp)];\n        char nullexp   [sizeof(NullExp)];\n        char dotvarexp [sizeof(DotVarExp)];\n        char addrexp   [sizeof(AddrExp)];\n        char indexexp  [sizeof(IndexExp)];\n        char sliceexp  [sizeof(SliceExp)];\n\n        // Ensure that the union is suitably aligned.\n        real_t for_alignment_only;\n    } u;\n};\n\n/****************************************************************/\n\nclass ObjcClassReferenceExp : public Expression\n{\n    ClassDeclaration* classDeclaration;\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n"
  },
  {
    "path": "gcc/d/dmd/expressionsem.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/expressionsem.d, _expressionsem.d)\n * Documentation:  https://dlang.org/phobos/dmd_expressionsem.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/expressionsem.d\n */\n\nmodule dmd.expressionsem;\n\nimport core.stdc.stdio;\n\nimport dmd.access;\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arrayop;\nimport dmd.arraytypes;\nimport dmd.attrib;\nimport dmd.astcodegen;\nimport dmd.canthrow;\nimport dmd.ctorflow;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.declaration;\nimport dmd.dclass;\nimport dmd.dcast;\nimport dmd.delegatize;\nimport dmd.denum;\nimport dmd.dimport;\nimport dmd.dinterpret;\nimport dmd.dmangle;\nimport dmd.dmodule;\nimport dmd.dstruct;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.escape;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.imphint;\nimport dmd.inline;\nimport dmd.intrange;\nimport dmd.mtype;\nimport dmd.nspace;\nimport dmd.opover;\nimport dmd.optimize;\nimport dmd.parse;\nimport dmd.root.ctfloat;\nimport dmd.root.file;\nimport dmd.root.filename;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.semantic2;\nimport dmd.semantic3;\nimport dmd.sideeffect;\nimport dmd.safe;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.traits;\nimport dmd.typesem;\nimport dmd.typinf;\nimport dmd.utf;\nimport dmd.utils;\nimport dmd.visitor;\n\nenum LOGSEMANTIC = false;\n\n/***********************************************************\n * Resolve `exp` as a compile-time known string.\n * Params:\n *  sc  = scope\n *  exp = Expression which expected as a string\n *  s   = What the string is expected for, will be used in error diagnostic.\n * Returns:\n *  String literal, or `null` if error happens.\n */\nStringExp semanticString(Scope *sc, Expression exp, const char* s)\n{\n    sc = sc.startCTFE();\n    exp = exp.expressionSemantic(sc);\n    exp = resolveProperties(sc, exp);\n    sc = sc.endCTFE();\n\n    if (exp.op == TOK.error)\n        return null;\n\n    auto e = exp;\n    if (exp.type.isString())\n    {\n        e = e.ctfeInterpret();\n        if (e.op == TOK.error)\n            return null;\n    }\n\n    auto se = e.toStringExp();\n    if (!se)\n    {\n        exp.error(\"`string` expected for %s, not `(%s)` of type `%s`\",\n            s, exp.toChars(), exp.type.toChars());\n        return null;\n    }\n    return se;\n}\n\nprivate Expression extractOpDollarSideEffect(Scope* sc, UnaExp ue)\n{\n    Expression e0;\n    Expression e1 = Expression.extractLast(ue.e1, e0);\n    // https://issues.dlang.org/show_bug.cgi?id=12585\n    // Extract the side effect part if ue.e1 is comma.\n\n    if (!isTrivialExp(e1))\n    {\n        /* Even if opDollar is needed, 'e1' should be evaluate only once. So\n         * Rewrite:\n         *      e1.opIndex( ... use of $ ... )\n         *      e1.opSlice( ... use of $ ... )\n         * as:\n         *      (ref __dop = e1, __dop).opIndex( ... __dop.opDollar ...)\n         *      (ref __dop = e1, __dop).opSlice( ... __dop.opDollar ...)\n         */\n        e1 = extractSideEffect(sc, \"__dop\", e0, e1, false);\n        assert(e1.op == TOK.variable);\n        VarExp ve = cast(VarExp)e1;\n        ve.var.storage_class |= STC.exptemp;     // lifetime limited to expression\n    }\n    ue.e1 = e1;\n    return e0;\n}\n\n/**************************************\n * Runs semantic on ae.arguments. Declares temporary variables\n * if '$' was used.\n */\nExpression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)\n{\n    assert(!ae.lengthVar);\n    *pe0 = null;\n    AggregateDeclaration ad = isAggregate(ae.e1.type);\n    Dsymbol slice = search_function(ad, Id.slice);\n    //printf(\"slice = %s %s\\n\", slice.kind(), slice.toChars());\n    foreach (i, e; *ae.arguments)\n    {\n        if (i == 0)\n            *pe0 = extractOpDollarSideEffect(sc, ae);\n\n        if (e.op == TOK.interval && !(slice && slice.isTemplateDeclaration()))\n        {\n        Lfallback:\n            if (ae.arguments.dim == 1)\n                return null;\n            ae.error(\"multi-dimensional slicing requires template `opSlice`\");\n            return new ErrorExp();\n        }\n        //printf(\"[%d] e = %s\\n\", i, e.toChars());\n\n        // Create scope for '$' variable for this dimension\n        auto sym = new ArrayScopeSymbol(sc, ae);\n        sym.loc = ae.loc;\n        sym.parent = sc.scopesym;\n        sc = sc.push(sym);\n        ae.lengthVar = null; // Create it only if required\n        ae.currentDimension = i; // Dimension for $, if required\n\n        e = e.expressionSemantic(sc);\n        e = resolveProperties(sc, e);\n\n        if (ae.lengthVar && sc.func)\n        {\n            // If $ was used, declare it now\n            Expression de = new DeclarationExp(ae.loc, ae.lengthVar);\n            de = de.expressionSemantic(sc);\n            *pe0 = Expression.combine(*pe0, de);\n        }\n        sc = sc.pop();\n\n        if (e.op == TOK.interval)\n        {\n            IntervalExp ie = cast(IntervalExp)e;\n\n            auto tiargs = new Objects();\n            Expression edim = new IntegerExp(ae.loc, i, Type.tsize_t);\n            edim = edim.expressionSemantic(sc);\n            tiargs.push(edim);\n\n            auto fargs = new Expressions();\n            fargs.push(ie.lwr);\n            fargs.push(ie.upr);\n\n            uint xerrors = global.startGagging();\n            sc = sc.push();\n            FuncDeclaration fslice = resolveFuncCall(ae.loc, sc, slice, tiargs, ae.e1.type, fargs, 1);\n            sc = sc.pop();\n            global.endGagging(xerrors);\n            if (!fslice)\n                goto Lfallback;\n\n            e = new DotTemplateInstanceExp(ae.loc, ae.e1, slice.ident, tiargs);\n            e = new CallExp(ae.loc, e, fargs);\n            e = e.expressionSemantic(sc);\n        }\n\n        if (!e.type)\n        {\n            ae.error(\"`%s` has no value\", e.toChars());\n            e = new ErrorExp();\n        }\n        if (e.op == TOK.error)\n            return e;\n\n        (*ae.arguments)[i] = e;\n    }\n    return ae;\n}\n\n/**************************************\n * Runs semantic on se.lwr and se.upr. Declares a temporary variable\n * if '$' was used.\n */\nExpression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, Expression* pe0)\n{\n    //assert(!ae.lengthVar);\n    if (!ie)\n        return ae;\n\n    VarDeclaration lengthVar = ae.lengthVar;\n\n    // create scope for '$'\n    auto sym = new ArrayScopeSymbol(sc, ae);\n    sym.loc = ae.loc;\n    sym.parent = sc.scopesym;\n    sc = sc.push(sym);\n\n    foreach (i; 0 .. 2)\n    {\n        Expression e = i == 0 ? ie.lwr : ie.upr;\n        e = e.expressionSemantic(sc);\n        e = resolveProperties(sc, e);\n        if (!e.type)\n        {\n            ae.error(\"`%s` has no value\", e.toChars());\n            return new ErrorExp();\n        }\n        (i == 0 ? ie.lwr : ie.upr) = e;\n    }\n\n    if (lengthVar != ae.lengthVar && sc.func)\n    {\n        // If $ was used, declare it now\n        Expression de = new DeclarationExp(ae.loc, ae.lengthVar);\n        de = de.expressionSemantic(sc);\n        *pe0 = Expression.combine(*pe0, de);\n    }\n\n    sc = sc.pop();\n\n    return ae;\n}\n\n/******************************\n * Perform semantic() on an array of Expressions.\n */\nextern (C++) bool arrayExpressionSemantic(Expressions* exps, Scope* sc, bool preserveErrors = false)\n{\n    bool err = false;\n    if (exps)\n    {\n        foreach (ref e; *exps)\n        {\n            if (e)\n            {\n                auto e2 = e.expressionSemantic(sc);\n                if (e2.op == TOK.error)\n                    err = true;\n                if (preserveErrors || e2.op != TOK.error)\n                    e = e2;\n            }\n        }\n    }\n    return err;\n}\n\n/******************************\n * Check the tail CallExp is really property function call.\n * Bugs:\n * This doesn't appear to do anything.\n */\nprivate bool checkPropertyCall(Expression e)\n{\n    e = lastComma(e);\n\n    if (e.op == TOK.call)\n    {\n        CallExp ce = cast(CallExp)e;\n        TypeFunction tf;\n        if (ce.f)\n        {\n            tf = cast(TypeFunction)ce.f.type;\n            /* If a forward reference to ce.f, try to resolve it\n             */\n            if (!tf.deco && ce.f.semanticRun < PASS.semanticdone)\n            {\n                ce.f.dsymbolSemantic(null);\n                tf = cast(TypeFunction)ce.f.type;\n            }\n        }\n        else if (ce.e1.type.ty == Tfunction)\n            tf = cast(TypeFunction)ce.e1.type;\n        else if (ce.e1.type.ty == Tdelegate)\n            tf = cast(TypeFunction)ce.e1.type.nextOf();\n        else if (ce.e1.type.ty == Tpointer && ce.e1.type.nextOf().ty == Tfunction)\n            tf = cast(TypeFunction)ce.e1.type.nextOf();\n        else\n            assert(0);\n    }\n    return false;\n}\n\n/******************************\n * Find symbol in accordance with the UFCS name look up rule\n */\nprivate Expression searchUFCS(Scope* sc, UnaExp ue, Identifier ident)\n{\n    //printf(\"searchUFCS(ident = %s)\\n\", ident.toChars());\n    Loc loc = ue.loc;\n\n    // TODO: merge with Scope.search.searchScopes()\n    Dsymbol searchScopes(int flags)\n    {\n        Dsymbol s = null;\n        for (Scope* scx = sc; scx; scx = scx.enclosing)\n        {\n            if (!scx.scopesym)\n                continue;\n            if (scx.scopesym.isModule())\n                flags |= SearchUnqualifiedModule;    // tell Module.search() that SearchLocalsOnly is to be obeyed\n            s = scx.scopesym.search(loc, ident, flags);\n            if (s)\n            {\n                // overload set contains only module scope symbols.\n                if (s.isOverloadSet())\n                    break;\n                // selective/renamed imports also be picked up\n                if (AliasDeclaration ad = s.isAliasDeclaration())\n                {\n                    if (ad._import)\n                        break;\n                }\n                // See only module scope symbols for UFCS target.\n                Dsymbol p = s.toParent2();\n                if (p && p.isModule())\n                    break;\n            }\n            s = null;\n\n            // Stop when we hit a module, but keep going if that is not just under the global scope\n            if (scx.scopesym.isModule() && !(scx.enclosing && !scx.enclosing.enclosing))\n                break;\n        }\n        return s;\n    }\n\n    int flags = 0;\n    Dsymbol s;\n\n    if (sc.flags & SCOPE.ignoresymbolvisibility)\n        flags |= IgnoreSymbolVisibility;\n\n    Dsymbol sold = void;\n    if (global.params.bug10378 || global.params.check10378)\n    {\n        sold = searchScopes(flags | IgnoreSymbolVisibility);\n        if (!global.params.check10378)\n        {\n            s = sold;\n            goto Lsearchdone;\n        }\n    }\n\n    // First look in local scopes\n    s = searchScopes(flags | SearchLocalsOnly);\n    if (!s)\n    {\n        // Second look in imported modules\n        s = searchScopes(flags | SearchImportsOnly);\n\n        /** Still find private symbols, so that symbols that weren't access\n         * checked by the compiler remain usable.  Once the deprecation is over,\n         * this should be moved to search_correct instead.\n         */\n        if (!s && !(flags & IgnoreSymbolVisibility))\n        {\n            s = searchScopes(flags | SearchLocalsOnly | IgnoreSymbolVisibility);\n            if (!s)\n                s = searchScopes(flags | SearchImportsOnly | IgnoreSymbolVisibility);\n\n            if (s)\n                .deprecation(loc, \"`%s` is not visible from module `%s`\", s.toPrettyChars(), sc._module.toChars());\n        }\n    }\n    if (global.params.check10378)\n    {\n        alias snew = s;\n        if (sold !is snew)\n            Scope.deprecation10378(loc, sold, snew);\n        if (global.params.bug10378)\n            s = sold;\n    }\nLsearchdone:\n\n    if (!s)\n        return ue.e1.type.Type.getProperty(loc, ident, 0);\n\n    FuncDeclaration f = s.isFuncDeclaration();\n    if (f)\n    {\n        TemplateDeclaration td = getFuncTemplateDecl(f);\n        if (td)\n        {\n            if (td.overroot)\n                td = td.overroot;\n            s = td;\n        }\n    }\n\n    if (ue.op == TOK.dotTemplateInstance)\n    {\n        DotTemplateInstanceExp dti = cast(DotTemplateInstanceExp)ue;\n        auto ti = new TemplateInstance(loc, s.ident, dti.ti.tiargs);\n        if (!ti.updateTempDecl(sc, s))\n            return new ErrorExp();\n        return new ScopeExp(loc, ti);\n    }\n    else\n    {\n        //printf(\"-searchUFCS() %s\\n\", s.toChars());\n        return new DsymbolExp(loc, s);\n    }\n}\n\n/******************************\n * Pull out callable entity with UFCS.\n */\nprivate Expression resolveUFCS(Scope* sc, CallExp ce)\n{\n    Loc loc = ce.loc;\n    Expression eleft;\n    Expression e;\n\n    if (ce.e1.op == TOK.dotIdentifier)\n    {\n        DotIdExp die = cast(DotIdExp)ce.e1;\n        Identifier ident = die.ident;\n\n        Expression ex = die.semanticX(sc);\n        if (ex != die)\n        {\n            ce.e1 = ex;\n            return null;\n        }\n        eleft = die.e1;\n\n        Type t = eleft.type.toBasetype();\n        if (t.ty == Tarray || t.ty == Tsarray || t.ty == Tnull || (t.isTypeBasic() && t.ty != Tvoid))\n        {\n            /* Built-in types and arrays have no callable properties, so do shortcut.\n             * It is necessary in: e.init()\n             */\n        }\n        else if (t.ty == Taarray)\n        {\n            if (ident == Id.remove)\n            {\n                /* Transform:\n                 *  aa.remove(arg) into delete aa[arg]\n                 */\n                if (!ce.arguments || ce.arguments.dim != 1)\n                {\n                    ce.error(\"expected key as argument to `aa.remove()`\");\n                    return new ErrorExp();\n                }\n                if (!eleft.type.isMutable())\n                {\n                    ce.error(\"cannot remove key from `%s` associative array `%s`\", MODtoChars(t.mod), eleft.toChars());\n                    return new ErrorExp();\n                }\n                Expression key = (*ce.arguments)[0];\n                key = key.expressionSemantic(sc);\n                key = resolveProperties(sc, key);\n\n                TypeAArray taa = cast(TypeAArray)t;\n                key = key.implicitCastTo(sc, taa.index);\n\n                if (key.checkValue())\n                    return new ErrorExp();\n\n                semanticTypeInfo(sc, taa.index);\n\n                return new RemoveExp(loc, eleft, key);\n            }\n        }\n        else\n        {\n            // even opDispatch and ufcs must have valid arguments.\n            if (arrayExpressionSemantic(ce.arguments, sc))\n                return new ErrorExp();\n\n            if (Expression ey = die.semanticY(sc, 1))\n            {\n                if (ey.op == TOK.error)\n                    return ey;\n                ce.e1 = ey;\n                if (isDotOpDispatch(ey))\n                {\n                    uint errors = global.startGagging();\n                    e = ce.syntaxCopy().expressionSemantic(sc);\n                    if (!global.endGagging(errors))\n                        return e;\n                    /* fall down to UFCS */\n                }\n                else\n                    return null;\n            }\n        }\n        e = searchUFCS(sc, die, ident);\n    }\n    else if (ce.e1.op == TOK.dotTemplateInstance)\n    {\n        DotTemplateInstanceExp dti = cast(DotTemplateInstanceExp)ce.e1;\n        if (Expression ey = dti.semanticY(sc, 1))\n        {\n            ce.e1 = ey;\n            return null;\n        }\n        eleft = dti.e1;\n        e = searchUFCS(sc, dti, dti.ti.name);\n    }\n    else\n        return null;\n\n    // Rewrite\n    ce.e1 = e;\n    if (!ce.arguments)\n        ce.arguments = new Expressions();\n    ce.arguments.shift(eleft);\n\n    return null;\n}\n\n/******************************\n * Pull out property with UFCS.\n */\nprivate Expression resolveUFCSProperties(Scope* sc, Expression e1, Expression e2 = null)\n{\n    Loc loc = e1.loc;\n    Expression eleft;\n    Expression e;\n\n    if (e1.op == TOK.dotIdentifier)\n    {\n        DotIdExp die = cast(DotIdExp)e1;\n        eleft = die.e1;\n        e = searchUFCS(sc, die, die.ident);\n    }\n    else if (e1.op == TOK.dotTemplateInstance)\n    {\n        DotTemplateInstanceExp dti;\n        dti = cast(DotTemplateInstanceExp)e1;\n        eleft = dti.e1;\n        e = searchUFCS(sc, dti, dti.ti.name);\n    }\n    else\n        return null;\n\n    if (e is null)\n        return null;\n\n    // Rewrite\n    if (e2)\n    {\n        // run semantic without gagging\n        e2 = e2.expressionSemantic(sc);\n\n        /* f(e1) = e2\n         */\n        Expression ex = e.copy();\n        auto a1 = new Expressions(1);\n        (*a1)[0] = eleft;\n        ex = new CallExp(loc, ex, a1);\n        ex = ex.trySemantic(sc);\n\n        /* f(e1, e2)\n         */\n        auto a2 = new Expressions(2);\n        (*a2)[0] = eleft;\n        (*a2)[1] = e2;\n        e = new CallExp(loc, e, a2);\n        if (ex)\n        {\n            // if fallback setter exists, gag errors\n            e = e.trySemantic(sc);\n            if (!e)\n            {\n                checkPropertyCall(ex);\n                ex = new AssignExp(loc, ex, e2);\n                return ex.expressionSemantic(sc);\n            }\n        }\n        else\n        {\n            // strict setter prints errors if fails\n            e = e.expressionSemantic(sc);\n        }\n        checkPropertyCall(e);\n        return e;\n    }\n    else\n    {\n        /* f(e1)\n         */\n        auto arguments = new Expressions(1);\n        (*arguments)[0] = eleft;\n        e = new CallExp(loc, e, arguments);\n        e = e.expressionSemantic(sc);\n        checkPropertyCall(e);\n        return e.expressionSemantic(sc);\n    }\n}\n\n/******************************\n * If e1 is a property function (template), resolve it.\n */\nExpression resolvePropertiesOnly(Scope* sc, Expression e1)\n{\n    //printf(\"e1 = %s %s\\n\", Token::toChars(e1.op), e1.toChars());\n    OverloadSet os;\n    FuncDeclaration fd;\n    TemplateDeclaration td;\n\n    if (e1.op == TOK.dot)\n    {\n        DotExp de = cast(DotExp)e1;\n        if (de.e2.op == TOK.overloadSet)\n        {\n            os = (cast(OverExp)de.e2).vars;\n            goto Los;\n        }\n    }\n    else if (e1.op == TOK.overloadSet)\n    {\n        os = (cast(OverExp)e1).vars;\n    Los:\n        assert(os);\n        foreach (s; os.a)\n        {\n            fd = s.isFuncDeclaration();\n            td = s.isTemplateDeclaration();\n            if (fd)\n            {\n                if ((cast(TypeFunction)fd.type).isproperty)\n                    return resolveProperties(sc, e1);\n            }\n            else if (td && td.onemember && (fd = td.onemember.isFuncDeclaration()) !is null)\n            {\n                if ((cast(TypeFunction)fd.type).isproperty || (fd.storage_class2 & STC.property) || (td._scope.stc & STC.property))\n                {\n                    return resolveProperties(sc, e1);\n                }\n            }\n        }\n    }\n    else if (e1.op == TOK.dotTemplateInstance)\n    {\n        DotTemplateInstanceExp dti = cast(DotTemplateInstanceExp)e1;\n        if (dti.ti.tempdecl && (td = dti.ti.tempdecl.isTemplateDeclaration()) !is null)\n            goto Ltd;\n    }\n    else if (e1.op == TOK.dotTemplateDeclaration)\n    {\n        td = (cast(DotTemplateExp)e1).td;\n        goto Ltd;\n    }\n    else if (e1.op == TOK.scope_)\n    {\n        Dsymbol s = (cast(ScopeExp)e1).sds;\n        TemplateInstance ti = s.isTemplateInstance();\n        if (ti && !ti.semanticRun && ti.tempdecl)\n        {\n            if ((td = ti.tempdecl.isTemplateDeclaration()) !is null)\n                goto Ltd;\n        }\n    }\n    else if (e1.op == TOK.template_)\n    {\n        td = (cast(TemplateExp)e1).td;\n    Ltd:\n        assert(td);\n        if (td.onemember && (fd = td.onemember.isFuncDeclaration()) !is null)\n        {\n            if ((cast(TypeFunction)fd.type).isproperty || (fd.storage_class2 & STC.property) || (td._scope.stc & STC.property))\n            {\n                return resolveProperties(sc, e1);\n            }\n        }\n    }\n    else if (e1.op == TOK.dotVariable && e1.type.ty == Tfunction)\n    {\n        DotVarExp dve = cast(DotVarExp)e1;\n        fd = dve.var.isFuncDeclaration();\n        goto Lfd;\n    }\n    else if (e1.op == TOK.variable && e1.type && e1.type.ty == Tfunction && (sc.intypeof || !(cast(VarExp)e1).var.needThis()))\n    {\n        fd = (cast(VarExp)e1).var.isFuncDeclaration();\n    Lfd:\n        assert(fd);\n        if ((cast(TypeFunction)fd.type).isproperty)\n            return resolveProperties(sc, e1);\n    }\n    return e1;\n}\n\n/****************************************\n * Resolve a symbol `s` and wraps it in an expression object.\n *\n * Params:\n *      loc = location of use of `s`\n *      sc = context\n *      s = symbol to resolve\n *      hasOverloads = applies if `s` represents a function.\n *          true means it's overloaded and will be resolved later,\n *          false means it's the exact function symbol.\n * Returns:\n *      `s` turned into an expression, `ErrorExp` if an error occurred\n */\nExpression resolve(const ref Loc loc, Scope *sc, Dsymbol s, bool hasOverloads)\n{\n    static if (LOGSEMANTIC)\n    {\n        printf(\"DsymbolExp::resolve(%s %s)\\n\", s.kind(), s.toChars());\n    }\n\nLagain:\n    Expression e;\n\n    //printf(\"DsymbolExp:: %p '%s' is a symbol\\n\", this, toChars());\n    //printf(\"s = '%s', s.kind = '%s'\\n\", s.toChars(), s.kind());\n    Dsymbol olds = s;\n    Declaration d = s.isDeclaration();\n    if (d && (d.storage_class & STC.templateparameter))\n    {\n        s = s.toAlias();\n    }\n    else\n    {\n        if (!s.isFuncDeclaration()) // functions are checked after overloading\n        {\n            s.checkDeprecated(loc, sc);\n            if (d)\n                d.checkDisabled(loc, sc);\n        }\n\n        // https://issues.dlang.org/show_bug.cgi?id=12023\n        // if 's' is a tuple variable, the tuple is returned.\n        s = s.toAlias();\n\n        //printf(\"s = '%s', s.kind = '%s', s.needThis() = %p\\n\", s.toChars(), s.kind(), s.needThis());\n        if (s != olds && !s.isFuncDeclaration())\n        {\n            s.checkDeprecated(loc, sc);\n            if (d)\n                d.checkDisabled(loc, sc);\n        }\n    }\n\n    if (auto em = s.isEnumMember())\n    {\n        return em.getVarExp(loc, sc);\n    }\n    if (auto v = s.isVarDeclaration())\n    {\n        //printf(\"Identifier '%s' is a variable, type '%s'\\n\", s.toChars(), v.type.toChars());\n        if (!v.type ||                  // during variable type inference\n            !v.type.deco && v.inuse)    // during variable type semantic\n        {\n            if (v.inuse)    // variable type depends on the variable itself\n                error(loc, \"circular reference to %s `%s`\", v.kind(), v.toPrettyChars());\n            else            // variable type cannot be determined\n                error(loc, \"forward reference to %s `%s`\", v.kind(), v.toPrettyChars());\n            return new ErrorExp();\n        }\n        if (v.type.ty == Terror)\n            return new ErrorExp();\n\n        if ((v.storage_class & STC.manifest) && v._init)\n        {\n            if (v.inuse)\n            {\n                error(loc, \"circular initialization of %s `%s`\", v.kind(), v.toPrettyChars());\n                return new ErrorExp();\n            }\n            e = v.expandInitializer(loc);\n            v.inuse++;\n            e = e.expressionSemantic(sc);\n            v.inuse--;\n            return e;\n        }\n\n        // Change the ancestor lambdas to delegate before hasThis(sc) call.\n        if (v.checkNestedReference(sc, loc))\n            return new ErrorExp();\n\n        if (v.needThis() && hasThis(sc))\n            e = new DotVarExp(loc, new ThisExp(loc), v);\n        else\n            e = new VarExp(loc, v);\n        e = e.expressionSemantic(sc);\n        return e;\n    }\n    if (auto fld = s.isFuncLiteralDeclaration())\n    {\n        //printf(\"'%s' is a function literal\\n\", fld.toChars());\n        e = new FuncExp(loc, fld);\n        return e.expressionSemantic(sc);\n    }\n    if (auto f = s.isFuncDeclaration())\n    {\n        f = f.toAliasFunc();\n        if (!f.functionSemantic())\n            return new ErrorExp();\n\n        if (!hasOverloads && f.checkForwardRef(loc))\n            return new ErrorExp();\n\n        auto fd = s.isFuncDeclaration();\n        fd.type = f.type;\n        return new VarExp(loc, fd, hasOverloads);\n    }\n    if (OverDeclaration od = s.isOverDeclaration())\n    {\n        e = new VarExp(loc, od, true);\n        e.type = Type.tvoid;\n        return e;\n    }\n    if (OverloadSet o = s.isOverloadSet())\n    {\n        //printf(\"'%s' is an overload set\\n\", o.toChars());\n        return new OverExp(loc, o);\n    }\n\n    if (Import imp = s.isImport())\n    {\n        if (!imp.pkg)\n        {\n            .error(loc, \"forward reference of import `%s`\", imp.toChars());\n            return new ErrorExp();\n        }\n        auto ie = new ScopeExp(loc, imp.pkg);\n        return ie.expressionSemantic(sc);\n    }\n    if (Package pkg = s.isPackage())\n    {\n        auto ie = new ScopeExp(loc, pkg);\n        return ie.expressionSemantic(sc);\n    }\n    if (Module mod = s.isModule())\n    {\n        auto ie = new ScopeExp(loc, mod);\n        return ie.expressionSemantic(sc);\n    }\n    if (Nspace ns = s.isNspace())\n    {\n        auto ie = new ScopeExp(loc, ns);\n        return ie.expressionSemantic(sc);\n    }\n\n    if (Type t = s.getType())\n    {\n        return (new TypeExp(loc, t)).expressionSemantic(sc);\n    }\n\n    if (TupleDeclaration tup = s.isTupleDeclaration())\n    {\n        if (tup.needThis() && hasThis(sc))\n            e = new DotVarExp(loc, new ThisExp(loc), tup);\n        else\n            e = new TupleExp(loc, tup);\n        e = e.expressionSemantic(sc);\n        return e;\n    }\n\n    if (TemplateInstance ti = s.isTemplateInstance())\n    {\n        ti.dsymbolSemantic(sc);\n        if (!ti.inst || ti.errors)\n            return new ErrorExp();\n        s = ti.toAlias();\n        if (!s.isTemplateInstance())\n            goto Lagain;\n        e = new ScopeExp(loc, ti);\n        e = e.expressionSemantic(sc);\n        return e;\n    }\n    if (TemplateDeclaration td = s.isTemplateDeclaration())\n    {\n        Dsymbol p = td.toParent2();\n        FuncDeclaration fdthis = hasThis(sc);\n        AggregateDeclaration ad = p ? p.isAggregateDeclaration() : null;\n        if (fdthis && ad && isAggregate(fdthis.vthis.type) == ad && (td._scope.stc & STC.static_) == 0)\n        {\n            e = new DotTemplateExp(loc, new ThisExp(loc), td);\n        }\n        else\n            e = new TemplateExp(loc, td);\n        e = e.expressionSemantic(sc);\n        return e;\n    }\n\n    .error(loc, \"%s `%s` is not a variable\", s.kind(), s.toChars());\n    return new ErrorExp();\n}\n\n/*************************************************************\n * Given var, get the\n * right `this` pointer if var is in an outer class, but our\n * existing `this` pointer is in an inner class.\n * Params:\n *      loc = location to use for error messages\n *      sc = context\n *      ad = struct or class we need the correct `this` for\n *      e1 = existing `this`\n *      var = the specific member of ad we're accessing\n *      flag = if true, return `null` instead of throwing an error\n * Returns:\n *      Expression representing the `this` for the var\n */\nprivate Expression getRightThis(const ref Loc loc, Scope* sc, AggregateDeclaration ad, Expression e1, Declaration var, int flag = 0)\n{\n    //printf(\"\\ngetRightThis(e1 = %s, ad = %s, var = %s)\\n\", e1.toChars(), ad.toChars(), var.toChars());\nL1:\n    Type t = e1.type.toBasetype();\n    //printf(\"e1.type = %s, var.type = %s\\n\", e1.type.toChars(), var.type.toChars());\n\n    if (e1.op == TOK.objcClassReference)\n    {\n        // We already have an Objective-C class reference, just use that as 'this'.\n        return e1;\n    }\n    else if (ad && ad.isClassDeclaration && ad.isClassDeclaration.classKind == ClassKind.objc &&\n             var.isFuncDeclaration && var.isFuncDeclaration.isStatic &&\n             var.isFuncDeclaration.selector)\n    {\n        return new ObjcClassReferenceExp(e1.loc, cast(ClassDeclaration) ad);\n    }\n\n    /* If e1 is not the 'this' pointer for ad\n     */\n    if (ad &&\n        !(t.ty == Tpointer && t.nextOf().ty == Tstruct && (cast(TypeStruct)t.nextOf()).sym == ad) &&\n        !(t.ty == Tstruct && (cast(TypeStruct)t).sym == ad))\n    {\n        ClassDeclaration cd = ad.isClassDeclaration();\n        ClassDeclaration tcd = t.isClassHandle();\n\n        /* e1 is the right this if ad is a base class of e1\n         */\n        if (!cd || !tcd || !(tcd == cd || cd.isBaseOf(tcd, null)))\n        {\n            /* Only classes can be inner classes with an 'outer'\n             * member pointing to the enclosing class instance\n             */\n            if (tcd && tcd.isNested())\n            {\n                /* e1 is the 'this' pointer for an inner class: tcd.\n                 * Rewrite it as the 'this' pointer for the outer class.\n                 */\n                e1 = new DotVarExp(loc, e1, tcd.vthis);\n                e1.type = tcd.vthis.type;\n                e1.type = e1.type.addMod(t.mod);\n                // Do not call ensureStaticLinkTo()\n                //e1 = e1.semantic(sc);\n\n                // Skip up over nested functions, and get the enclosing\n                // class type.\n                int n = 0;\n                Dsymbol s;\n                for (s = tcd.toParent(); s && s.isFuncDeclaration(); s = s.toParent())\n                {\n                    FuncDeclaration f = s.isFuncDeclaration();\n                    if (f.vthis)\n                    {\n                        //printf(\"rewriting e1 to %s's this\\n\", f.toChars());\n                        n++;\n                        e1 = new VarExp(loc, f.vthis);\n                    }\n                    else\n                    {\n                        e1.error(\"need `this` of type `%s` to access member `%s` from static function `%s`\", ad.toChars(), var.toChars(), f.toChars());\n                        e1 = new ErrorExp();\n                        return e1;\n                    }\n                }\n                if (s && s.isClassDeclaration())\n                {\n                    e1.type = s.isClassDeclaration().type;\n                    e1.type = e1.type.addMod(t.mod);\n                    if (n > 1)\n                        e1 = e1.expressionSemantic(sc);\n                }\n                else\n                    e1 = e1.expressionSemantic(sc);\n                goto L1;\n            }\n\n            /* Can't find a path from e1 to ad\n             */\n            if (flag)\n                return null;\n            e1.error(\"`this` for `%s` needs to be type `%s` not type `%s`\", var.toChars(), ad.toChars(), t.toChars());\n            return new ErrorExp();\n        }\n    }\n    return e1;\n}\n\n/***************************************\n * Pull out any properties.\n */\nprivate Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = null)\n{\n    //printf(\"resolvePropertiesX, e1 = %s %s, e2 = %s\\n\", Token.toChars(e1.op), e1.toChars(), e2 ? e2.toChars() : null);\n    Loc loc = e1.loc;\n\n    OverloadSet os;\n    Dsymbol s;\n    Objects* tiargs;\n    Type tthis;\n    if (e1.op == TOK.dot)\n    {\n        DotExp de = cast(DotExp)e1;\n        if (de.e2.op == TOK.overloadSet)\n        {\n            tiargs = null;\n            tthis = de.e1.type;\n            os = (cast(OverExp)de.e2).vars;\n            goto Los;\n        }\n    }\n    else if (e1.op == TOK.overloadSet)\n    {\n        tiargs = null;\n        tthis = null;\n        os = (cast(OverExp)e1).vars;\n    Los:\n        assert(os);\n        FuncDeclaration fd = null;\n        if (e2)\n        {\n            e2 = e2.expressionSemantic(sc);\n            if (e2.op == TOK.error)\n                return new ErrorExp();\n            e2 = resolveProperties(sc, e2);\n\n            Expressions a;\n            a.push(e2);\n\n            for (size_t i = 0; i < os.a.dim; i++)\n            {\n                FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, &a, 1);\n                if (f)\n                {\n                    if (f.errors)\n                        return new ErrorExp();\n                    fd = f;\n                    assert(fd.type.ty == Tfunction);\n                }\n            }\n            if (fd)\n            {\n                Expression e = new CallExp(loc, e1, e2);\n                return e.expressionSemantic(sc);\n            }\n        }\n        {\n            for (size_t i = 0; i < os.a.dim; i++)\n            {\n                FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, null, 1);\n                if (f)\n                {\n                    if (f.errors)\n                        return new ErrorExp();\n                    fd = f;\n                    assert(fd.type.ty == Tfunction);\n                    TypeFunction tf = cast(TypeFunction)fd.type;\n                    if (!tf.isref && e2)\n                        goto Leproplvalue;\n                }\n            }\n            if (fd)\n            {\n                Expression e = new CallExp(loc, e1);\n                if (e2)\n                    e = new AssignExp(loc, e, e2);\n                return e.expressionSemantic(sc);\n            }\n        }\n        if (e2)\n            goto Leprop;\n    }\n    else if (e1.op == TOK.dotTemplateInstance)\n    {\n        DotTemplateInstanceExp dti = cast(DotTemplateInstanceExp)e1;\n        if (!dti.findTempDecl(sc))\n            goto Leprop;\n        if (!dti.ti.semanticTiargs(sc))\n            goto Leprop;\n        tiargs = dti.ti.tiargs;\n        tthis = dti.e1.type;\n        if ((os = dti.ti.tempdecl.isOverloadSet()) !is null)\n            goto Los;\n        if ((s = dti.ti.tempdecl) !is null)\n            goto Lfd;\n    }\n    else if (e1.op == TOK.dotTemplateDeclaration)\n    {\n        DotTemplateExp dte = cast(DotTemplateExp)e1;\n        s = dte.td;\n        tiargs = null;\n        tthis = dte.e1.type;\n        goto Lfd;\n    }\n    else if (e1.op == TOK.scope_)\n    {\n        s = (cast(ScopeExp)e1).sds;\n        TemplateInstance ti = s.isTemplateInstance();\n        if (ti && !ti.semanticRun && ti.tempdecl)\n        {\n            //assert(ti.needsTypeInference(sc));\n            if (!ti.semanticTiargs(sc))\n                goto Leprop;\n            tiargs = ti.tiargs;\n            tthis = null;\n            if ((os = ti.tempdecl.isOverloadSet()) !is null)\n                goto Los;\n            if ((s = ti.tempdecl) !is null)\n                goto Lfd;\n        }\n    }\n    else if (e1.op == TOK.template_)\n    {\n        s = (cast(TemplateExp)e1).td;\n        tiargs = null;\n        tthis = null;\n        goto Lfd;\n    }\n    else if (e1.op == TOK.dotVariable && e1.type && e1.type.toBasetype().ty == Tfunction)\n    {\n        DotVarExp dve = cast(DotVarExp)e1;\n        s = dve.var.isFuncDeclaration();\n        tiargs = null;\n        tthis = dve.e1.type;\n        goto Lfd;\n    }\n    else if (e1.op == TOK.variable && e1.type && e1.type.toBasetype().ty == Tfunction)\n    {\n        s = (cast(VarExp)e1).var.isFuncDeclaration();\n        tiargs = null;\n        tthis = null;\n    Lfd:\n        assert(s);\n        if (e2)\n        {\n            e2 = e2.expressionSemantic(sc);\n            if (e2.op == TOK.error)\n                return new ErrorExp();\n            e2 = resolveProperties(sc, e2);\n\n            Expressions a;\n            a.push(e2);\n\n            FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, &a, 1);\n            if (fd && fd.type)\n            {\n                if (fd.errors)\n                    return new ErrorExp();\n                assert(fd.type.ty == Tfunction);\n                Expression e = new CallExp(loc, e1, e2);\n                return e.expressionSemantic(sc);\n            }\n        }\n        {\n            FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, null, 1);\n            if (fd && fd.type)\n            {\n                if (fd.errors)\n                    return new ErrorExp();\n                assert(fd.type.ty == Tfunction);\n                TypeFunction tf = cast(TypeFunction)fd.type;\n                if (!e2 || tf.isref)\n                {\n                    Expression e = new CallExp(loc, e1);\n                    if (e2)\n                        e = new AssignExp(loc, e, e2);\n                    return e.expressionSemantic(sc);\n                }\n            }\n        }\n        if (FuncDeclaration fd = s.isFuncDeclaration())\n        {\n            // Keep better diagnostic message for invalid property usage of functions\n            assert(fd.type.ty == Tfunction);\n            Expression e = new CallExp(loc, e1, e2);\n            return e.expressionSemantic(sc);\n        }\n        if (e2)\n            goto Leprop;\n    }\n    if (e1.op == TOK.variable)\n    {\n        VarExp ve = cast(VarExp)e1;\n        VarDeclaration v = ve.var.isVarDeclaration();\n        if (v && ve.checkPurity(sc, v))\n            return new ErrorExp();\n    }\n    if (e2)\n        return null;\n\n    if (e1.type && e1.op != TOK.type) // function type is not a property\n    {\n        /* Look for e1 being a lazy parameter; rewrite as delegate call\n         */\n        if (e1.op == TOK.variable)\n        {\n            VarExp ve = cast(VarExp)e1;\n            if (ve.var.storage_class & STC.lazy_)\n            {\n                Expression e = new CallExp(loc, e1);\n                return e.expressionSemantic(sc);\n            }\n        }\n        else if (e1.op == TOK.dotVariable)\n        {\n            // Check for reading overlapped pointer field in @safe code.\n            if (checkUnsafeAccess(sc, e1, true, true))\n                return new ErrorExp();\n        }\n        else if (e1.op == TOK.dot)\n        {\n            e1.error(\"expression has no value\");\n            return new ErrorExp();\n        }\n        else if (e1.op == TOK.call)\n        {\n            CallExp ce = cast(CallExp)e1;\n            // Check for reading overlapped pointer field in @safe code.\n            if (checkUnsafeAccess(sc, ce.e1, true, true))\n                return new ErrorExp();\n        }\n    }\n\n    if (!e1.type)\n    {\n        error(loc, \"cannot resolve type for %s\", e1.toChars());\n        e1 = new ErrorExp();\n    }\n    return e1;\n\nLeprop:\n    error(loc, \"not a property %s\", e1.toChars());\n    return new ErrorExp();\n\nLeproplvalue:\n    error(loc, \"%s is not an lvalue\", e1.toChars());\n    return new ErrorExp();\n}\n\nextern (C++) Expression resolveProperties(Scope* sc, Expression e)\n{\n    //printf(\"resolveProperties(%s)\\n\", e.toChars());\n    e = resolvePropertiesX(sc, e);\n    if (e.checkRightThis(sc))\n        return new ErrorExp();\n    return e;\n}\n\n/****************************************\n * The common type is determined by applying ?: to each pair.\n * Output:\n *      exps[]  properties resolved, implicitly cast to common type, rewritten in place\n *      *pt     if pt is not NULL, set to the common type\n * Returns:\n *      true    a semantic error was detected\n */\nprivate bool arrayExpressionToCommonType(Scope* sc, Expressions* exps, Type* pt)\n{\n    /* Still have a problem with:\n     *  ubyte[][] = [ cast(ubyte[])\"hello\", [1]];\n     * which works if the array literal is initialized top down with the ubyte[][]\n     * type, but fails with this function doing bottom up typing.\n     */\n\n    //printf(\"arrayExpressionToCommonType()\\n\");\n    scope IntegerExp integerexp = new IntegerExp(0);\n    scope CondExp condexp = new CondExp(Loc.initial, integerexp, null, null);\n\n    Type t0 = null;\n    Expression e0 = null;\n    size_t j0 = ~0;\n\n    for (size_t i = 0; i < exps.dim; i++)\n    {\n        Expression e = (*exps)[i];\n        if (!e)\n            continue;\n\n        e = resolveProperties(sc, e);\n        if (!e.type)\n        {\n            e.error(\"`%s` has no value\", e.toChars());\n            t0 = Type.terror;\n            continue;\n        }\n        if (e.op == TOK.type)\n        {\n            e.checkValue(); // report an error \"type T has no value\"\n            t0 = Type.terror;\n            continue;\n        }\n        if (e.type.ty == Tvoid)\n        {\n            // void expressions do not concur to the determination of the common\n            // type.\n            continue;\n        }\n        if (checkNonAssignmentArrayOp(e))\n        {\n            t0 = Type.terror;\n            continue;\n        }\n\n        e = doCopyOrMove(sc, e);\n\n        if (t0 && !t0.equals(e.type))\n        {\n            /* This applies ?: to merge the types. It's backwards;\n             * ?: should call this function to merge types.\n             */\n            condexp.type = null;\n            condexp.e1 = e0;\n            condexp.e2 = e;\n            condexp.loc = e.loc;\n            Expression ex = condexp.expressionSemantic(sc);\n            if (ex.op == TOK.error)\n                e = ex;\n            else\n            {\n                (*exps)[j0] = condexp.e1;\n                e = condexp.e2;\n            }\n        }\n        j0 = i;\n        e0 = e;\n        t0 = e.type;\n        if (e.op != TOK.error)\n            (*exps)[i] = e;\n    }\n\n    if (!t0)\n        t0 = Type.tvoid; // [] is typed as void[]\n    else if (t0.ty != Terror)\n    {\n        for (size_t i = 0; i < exps.dim; i++)\n        {\n            Expression e = (*exps)[i];\n            if (!e)\n                continue;\n\n            e = e.implicitCastTo(sc, t0);\n            //assert(e.op != TOK.error);\n            if (e.op == TOK.error)\n            {\n                /* https://issues.dlang.org/show_bug.cgi?id=13024\n                 * a workaround for the bug in typeMerge -\n                 * it should paint e1 and e2 by deduced common type,\n                 * but doesn't in this particular case.\n                 */\n                t0 = Type.terror;\n                break;\n            }\n            (*exps)[i] = e;\n        }\n    }\n    if (pt)\n        *pt = t0;\n\n    return (t0 == Type.terror);\n}\n\nprivate Expression opAssignToOp(const ref Loc loc, TOK op, Expression e1, Expression e2)\n{\n    Expression e;\n    switch (op)\n    {\n    case TOK.addAssign:\n        e = new AddExp(loc, e1, e2);\n        break;\n\n    case TOK.minAssign:\n        e = new MinExp(loc, e1, e2);\n        break;\n\n    case TOK.mulAssign:\n        e = new MulExp(loc, e1, e2);\n        break;\n\n    case TOK.divAssign:\n        e = new DivExp(loc, e1, e2);\n        break;\n\n    case TOK.modAssign:\n        e = new ModExp(loc, e1, e2);\n        break;\n\n    case TOK.andAssign:\n        e = new AndExp(loc, e1, e2);\n        break;\n\n    case TOK.orAssign:\n        e = new OrExp(loc, e1, e2);\n        break;\n\n    case TOK.xorAssign:\n        e = new XorExp(loc, e1, e2);\n        break;\n\n    case TOK.leftShiftAssign:\n        e = new ShlExp(loc, e1, e2);\n        break;\n\n    case TOK.rightShiftAssign:\n        e = new ShrExp(loc, e1, e2);\n        break;\n\n    case TOK.unsignedRightShiftAssign:\n        e = new UshrExp(loc, e1, e2);\n        break;\n\n    default:\n        assert(0);\n    }\n    return e;\n}\n\n/*********************\n * Rewrite:\n *    array.length op= e2\n * as:\n *    array.length = array.length op e2\n * or:\n *    auto tmp = &array;\n *    (*tmp).length = (*tmp).length op e2\n */\nprivate Expression rewriteOpAssign(BinExp exp)\n{\n    Expression e;\n\n    assert(exp.e1.op == TOK.arrayLength);\n    ArrayLengthExp ale = cast(ArrayLengthExp)exp.e1;\n    if (ale.e1.op == TOK.variable)\n    {\n        e = opAssignToOp(exp.loc, exp.op, ale, exp.e2);\n        e = new AssignExp(exp.loc, ale.syntaxCopy(), e);\n    }\n    else\n    {\n        /*    auto tmp = &array;\n         *    (*tmp).length = (*tmp).length op e2\n         */\n        auto tmp = copyToTemp(0, \"__arraylength\", new AddrExp(ale.loc, ale.e1));\n\n        Expression e1 = new ArrayLengthExp(ale.loc, new PtrExp(ale.loc, new VarExp(ale.loc, tmp)));\n        Expression elvalue = e1.syntaxCopy();\n        e = opAssignToOp(exp.loc, exp.op, e1, exp.e2);\n        e = new AssignExp(exp.loc, elvalue, e);\n        e = new CommaExp(exp.loc, new DeclarationExp(ale.loc, tmp), e);\n    }\n    return e;\n}\n\n/****************************************\n * Preprocess arguments to function.\n * Output:\n *      exps[]  tuples expanded, properties resolved, rewritten in place\n * Returns:\n *      true    a semantic error occurred\n */\nprivate bool preFunctionParameters(Scope* sc, Expressions* exps)\n{\n    bool err = false;\n    if (exps)\n    {\n        expandTuples(exps);\n\n        for (size_t i = 0; i < exps.dim; i++)\n        {\n            Expression arg = (*exps)[i];\n            arg = resolveProperties(sc, arg);\n            if (arg.op == TOK.type)\n            {\n                arg.error(\"cannot pass type `%s` as a function argument\", arg.toChars());\n                arg = new ErrorExp();\n                err = true;\n            }\n            else if (checkNonAssignmentArrayOp(arg))\n            {\n                arg = new ErrorExp();\n                err = true;\n            }\n            (*exps)[i] = arg;\n        }\n    }\n    return err;\n}\n\n/********************************************\n * Issue an error if default construction is disabled for type t.\n * Default construction is required for arrays and 'out' parameters.\n * Returns:\n *      true    an error was issued\n */\nprivate bool checkDefCtor(Loc loc, Type t)\n{\n    t = t.baseElemOf();\n    if (t.ty == Tstruct)\n    {\n        StructDeclaration sd = (cast(TypeStruct)t).sym;\n        if (sd.noDefaultCtor)\n        {\n            sd.error(loc, \"default construction is disabled\");\n            return true;\n        }\n    }\n    return false;\n}\n\n/****************************************\n * Now that we know the exact type of the function we're calling,\n * the arguments[] need to be adjusted:\n *      1. implicitly convert argument to the corresponding parameter type\n *      2. add default arguments for any missing arguments\n *      3. do default promotions on arguments corresponding to ...\n *      4. add hidden _arguments[] argument\n *      5. call copy constructor for struct value arguments\n * Params:\n *      tf        = type of the function\n *      tthis     = type of `this` argument, `null` if no `this` argument\n *      arguments = array of actual arguments to function call\n *      fd        = the function being called, `null` if called indirectly\n *      prettype  = set to return type of function\n *      peprefix  = set to expression to execute before `arguments[]` are evaluated, `null` if none\n * Returns:\n *      true    errors happened\n */\nprivate bool functionParameters(const ref Loc loc, Scope* sc,\n    TypeFunction tf, Type tthis, Expressions* arguments, FuncDeclaration fd, Type* prettype, Expression* peprefix)\n{\n    //printf(\"functionParameters() %s\\n\", fd ? fd.toChars() : \"\");\n    assert(arguments);\n    assert(fd || tf.next);\n    size_t nargs = arguments ? arguments.dim : 0;\n    const size_t nparams = Parameter.dim(tf.parameters);\n    const olderrors = global.errors;\n    bool err = false;\n    *prettype = Type.terror;\n    Expression eprefix = null;\n    *peprefix = null;\n\n    if (nargs > nparams && tf.varargs == 0)\n    {\n        error(loc, \"expected %llu arguments, not %llu for non-variadic function type `%s`\", cast(ulong)nparams, cast(ulong)nargs, tf.toChars());\n        return true;\n    }\n\n    // If inferring return type, and semantic3() needs to be run if not already run\n    if (!tf.next && fd.inferRetType)\n    {\n        fd.functionSemantic();\n    }\n    else if (fd && fd.parent)\n    {\n        TemplateInstance ti = fd.parent.isTemplateInstance();\n        if (ti && ti.tempdecl)\n        {\n            fd.functionSemantic3();\n        }\n    }\n    const isCtorCall = fd && fd.needThis() && fd.isCtorDeclaration();\n\n    const size_t n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)\n\n    /* If the function return type has wildcards in it, we'll need to figure out the actual type\n     * based on the actual argument types.\n     * Start with the `this` argument, later on merge into wildmatch the mod bits of the rest\n     * of the arguments.\n     */\n    MOD wildmatch = (tthis && !isCtorCall) ? tthis.Type.deduceWild(tf, false) : 0;\n\n    bool done = false;\n    foreach (const i; 0 .. n)\n    {\n        Expression arg = (i < nargs) ? (*arguments)[i] : null;\n\n        if (i < nparams)\n        {\n            bool errorArgs()\n            {\n                error(loc, \"expected %llu function arguments, not %llu\", cast(ulong)nparams, cast(ulong)nargs);\n                return true;\n            }\n\n            Parameter p = Parameter.getNth(tf.parameters, i);\n\n            if (!arg)\n            {\n                if (!p.defaultArg)\n                {\n                    if (tf.varargs == 2 && i + 1 == nparams)\n                        goto L2;\n                    return errorArgs();\n                }\n                arg = p.defaultArg;\n                arg = inlineCopy(arg, sc);\n                // __FILE__, __LINE__, __MODULE__, __FUNCTION__, and __PRETTY_FUNCTION__\n                arg = arg.resolveLoc(loc, sc);\n                arguments.push(arg);\n                nargs++;\n            }\n            else\n            {\n                if (arg.op == TOK.default_)\n                {\n                    arg = arg.resolveLoc(loc, sc);\n                    (*arguments)[i] = arg;\n                }\n            }\n\n            if (tf.varargs == 2 && i + 1 == nparams) // https://dlang.org/spec/function.html#variadic\n            {\n                //printf(\"\\t\\tvarargs == 2, p.type = '%s'\\n\", p.type.toChars());\n                {\n                    MATCH m;\n                    if ((m = arg.implicitConvTo(p.type)) > MATCH.nomatch)\n                    {\n                        if (p.type.nextOf() && arg.implicitConvTo(p.type.nextOf()) >= m)\n                            goto L2;\n                        else if (nargs != nparams)\n                            return errorArgs();\n                        goto L1;\n                    }\n                }\n            L2:\n                Type tb = p.type.toBasetype();\n                switch (tb.ty)\n                {\n                case Tsarray:\n                case Tarray:\n                    {\n                        /* Create a static array variable v of type arg.type:\n                         *  T[dim] __arrayArg = [ arguments[i], ..., arguments[nargs-1] ];\n                         *\n                         * The array literal in the initializer of the hidden variable\n                         * is now optimized.\n                         * https://issues.dlang.org/show_bug.cgi?id=2356\n                         */\n                        Type tbn = (cast(TypeArray)tb).next;    // array element type\n                        Type tret = p.isLazyArray();\n\n                        auto elements = new Expressions(nargs - i);\n                        foreach (u; 0 .. elements.dim)\n                        {\n                            Expression a = (*arguments)[i + u];\n                            if (tret && a.implicitConvTo(tret))\n                            {\n                                // p is a lazy array of delegates, tret is return type of the delegates\n                                a = a.implicitCastTo(sc, tret)\n                                     .optimize(WANTvalue)\n                                     .toDelegate(tret, sc);\n                            }\n                            else\n                                a = a.implicitCastTo(sc, tbn);\n                            (*elements)[u] = a;\n                        }\n                        // https://issues.dlang.org/show_bug.cgi?id=14395\n                        // Convert to a static array literal, or its slice.\n                        arg = new ArrayLiteralExp(loc, tbn.sarrayOf(nargs - i), elements);\n                        if (tb.ty == Tarray)\n                        {\n                            arg = new SliceExp(loc, arg, null, null);\n                            arg.type = p.type;\n                        }\n                        break;\n                    }\n                case Tclass:\n                    {\n                        /* Set arg to be:\n                         *      new Tclass(arg0, arg1, ..., argn)\n                         */\n                        auto args = new Expressions(nargs - i);\n                        foreach (u; i .. nargs)\n                            (*args)[u - i] = (*arguments)[u];\n                        arg = new NewExp(loc, null, null, p.type, args);\n                        break;\n                    }\n                default:\n                    if (!arg)\n                    {\n                        error(loc, \"not enough arguments\");\n                        return true;\n                    }\n                    break;\n                }\n                arg = arg.expressionSemantic(sc);\n                //printf(\"\\targ = '%s'\\n\", arg.toChars());\n                arguments.setDim(i + 1);\n                (*arguments)[i] = arg;\n                nargs = i + 1;\n                done = true;\n            }\n\n        L1:\n            if (!(p.storageClass & STC.lazy_ && p.type.ty == Tvoid))\n            {\n                bool isRef = (p.storageClass & (STC.ref_ | STC.out_)) != 0;\n                if (ubyte wm = arg.type.deduceWild(p.type, isRef))\n                {\n                    wildmatch = wildmatch ? MODmerge(wildmatch, wm) : wm;\n                    //printf(\"[%d] p = %s, a = %s, wm = %d, wildmatch = %d\\n\", i, p.type.toChars(), arg.type.toChars(), wm, wildmatch);\n                }\n            }\n        }\n        if (done)\n            break;\n    }\n    if ((wildmatch == MODFlags.mutable || wildmatch == MODFlags.immutable_) &&\n        tf.next.hasWild() &&\n        (tf.isref || !tf.next.implicitConvTo(tf.next.immutableOf())))\n    {\n        bool errorInout(MOD wildmatch)\n        {\n            const(char)* s = wildmatch == MODFlags.mutable ? \"mutable\" : MODtoChars(wildmatch);\n            error(loc, \"modify `inout` to `%s` is not allowed inside `inout` function\", s);\n            return true;\n        }\n\n        if (fd)\n        {\n            /* If the called function may return the reference to\n             * outer inout data, it should be rejected.\n             *\n             * void foo(ref inout(int) x) {\n             *   ref inout(int) bar(inout(int)) { return x; }\n             *   struct S { ref inout(int) bar() inout { return x; } }\n             *   bar(int.init) = 1;  // bad!\n             *   S().bar() = 1;      // bad!\n             * }\n             */\n            Dsymbol s = null;\n            if (fd.isThis() || fd.isNested())\n                s = fd.toParent2();\n            for (; s; s = s.toParent2())\n            {\n                if (auto ad = s.isAggregateDeclaration())\n                {\n                    if (ad.isNested())\n                        continue;\n                    break;\n                }\n                if (auto ff = s.isFuncDeclaration())\n                {\n                    if ((cast(TypeFunction)ff.type).iswild)\n                        return errorInout(wildmatch);\n\n                    if (ff.isNested() || ff.isThis())\n                        continue;\n                }\n                break;\n            }\n        }\n        else if (tf.isWild())\n            return errorInout(wildmatch);\n    }\n\n    assert(nargs >= nparams);\n    foreach (const i, arg; (*arguments)[0 .. nargs])\n    {\n        assert(arg);\n        if (i < nparams)\n        {\n            Parameter p = Parameter.getNth(tf.parameters, i);\n            if (!(p.storageClass & STC.lazy_ && p.type.ty == Tvoid))\n            {\n                Type tprm = p.type.hasWild()\n                    ? p.type.substWildTo(wildmatch)\n                    : p.type;\n                if (!tprm.equals(arg.type))\n                {\n                    //printf(\"arg.type = %s, p.type = %s\\n\", arg.type.toChars(), p.type.toChars());\n                    arg = arg.implicitCastTo(sc, tprm);\n                    arg = arg.optimize(WANTvalue, (p.storageClass & (STC.ref_ | STC.out_)) != 0);\n                }\n            }\n            if (p.storageClass & STC.ref_)\n            {\n                arg = arg.toLvalue(sc, arg);\n\n                // Look for mutable misaligned pointer, etc., in @safe mode\n                err |= checkUnsafeAccess(sc, arg, false, true);\n            }\n            else if (p.storageClass & STC.out_)\n            {\n                Type t = arg.type;\n                if (!t.isMutable() || !t.isAssignable()) // check blit assignable\n                {\n                    arg.error(\"cannot modify struct `%s` with immutable members\", arg.toChars());\n                    err = true;\n                }\n                else\n                {\n                    // Look for misaligned pointer, etc., in @safe mode\n                    err |= checkUnsafeAccess(sc, arg, false, true);\n                    err |= checkDefCtor(arg.loc, t); // t must be default constructible\n                }\n                arg = arg.toLvalue(sc, arg);\n            }\n            else if (p.storageClass & STC.lazy_)\n            {\n                // Convert lazy argument to a delegate\n                auto t = (p.type.ty == Tvoid) ? p.type : arg.type;\n                arg = toDelegate(arg, t, sc);\n            }\n            //printf(\"arg: %s\\n\", arg.toChars());\n            //printf(\"type: %s\\n\", arg.type.toChars());\n            //printf(\"param: %s\\n\", p.toChars());\n\n            if (tf.parameterEscapes(tthis, p))\n            {\n                /* Argument value can escape from the called function.\n                 * Check arg to see if it matters.\n                 */\n                if (global.params.vsafe)\n                    err |= checkParamArgumentEscape(sc, fd, p.ident, arg, false);\n            }\n            else\n            {\n                /* Argument value cannot escape from the called function.\n                 */\n                Expression a = arg;\n                if (a.op == TOK.cast_)\n                    a = (cast(CastExp)a).e1;\n                if (a.op == TOK.function_)\n                {\n                    /* Function literals can only appear once, so if this\n                     * appearance was scoped, there cannot be any others.\n                     */\n                    FuncExp fe = cast(FuncExp)a;\n                    fe.fd.tookAddressOf = 0;\n                }\n                else if (a.op == TOK.delegate_)\n                {\n                    /* For passing a delegate to a scoped parameter,\n                     * this doesn't count as taking the address of it.\n                     * We only worry about 'escaping' references to the function.\n                     */\n                    DelegateExp de = cast(DelegateExp)a;\n                    if (de.e1.op == TOK.variable)\n                    {\n                        VarExp ve = cast(VarExp)de.e1;\n                        FuncDeclaration f = ve.var.isFuncDeclaration();\n                        if (f)\n                        {\n                            f.tookAddressOf--;\n                            //printf(\"--tookAddressOf = %d\\n\", f.tookAddressOf);\n                        }\n                    }\n                }\n            }\n            arg = arg.optimize(WANTvalue, (p.storageClass & (STC.ref_ | STC.out_)) != 0);\n        }\n        else\n        {\n            // These will be the trailing ... arguments\n            // If not D linkage, do promotions\n            if (tf.linkage != LINK.d)\n            {\n                // Promote bytes, words, etc., to ints\n                arg = integralPromotions(arg, sc);\n\n                // Promote floats to doubles\n                switch (arg.type.ty)\n                {\n                case Tfloat32:\n                    arg = arg.castTo(sc, Type.tfloat64);\n                    break;\n\n                case Timaginary32:\n                    arg = arg.castTo(sc, Type.timaginary64);\n                    break;\n\n                default:\n                    break;\n                }\n                if (tf.varargs == 1)\n                {\n                    const(char)* p = tf.linkage == LINK.c ? \"extern(C)\" : \"extern(C++)\";\n                    if (arg.type.ty == Tarray)\n                    {\n                        arg.error(\"cannot pass dynamic arrays to `%s` vararg functions\", p);\n                        err = true;\n                    }\n                    if (arg.type.ty == Tsarray)\n                    {\n                        arg.error(\"cannot pass static arrays to `%s` vararg functions\", p);\n                        err = true;\n                    }\n                }\n            }\n\n            // Do not allow types that need destructors\n            if (arg.type.needsDestruction())\n            {\n                arg.error(\"cannot pass types that need destruction as variadic arguments\");\n                err = true;\n            }\n\n            // Convert static arrays to dynamic arrays\n            // BUG: I don't think this is right for D2\n            Type tb = arg.type.toBasetype();\n            if (tb.ty == Tsarray)\n            {\n                TypeSArray ts = cast(TypeSArray)tb;\n                Type ta = ts.next.arrayOf();\n                if (ts.size(arg.loc) == 0)\n                    arg = new NullExp(arg.loc, ta);\n                else\n                    arg = arg.castTo(sc, ta);\n            }\n            if (tb.ty == Tstruct)\n            {\n                //arg = callCpCtor(sc, arg);\n            }\n            // Give error for overloaded function addresses\n            if (arg.op == TOK.symbolOffset)\n            {\n                SymOffExp se = cast(SymOffExp)arg;\n                if (se.hasOverloads && !se.var.isFuncDeclaration().isUnique())\n                {\n                    arg.error(\"function `%s` is overloaded\", arg.toChars());\n                    err = true;\n                }\n            }\n            if (arg.checkValue())\n                err = true;\n            arg = arg.optimize(WANTvalue);\n        }\n        (*arguments)[i] = arg;\n    }\n\n    /* Remaining problems:\n     * 1. order of evaluation - some function push L-to-R, others R-to-L. Until we resolve what array assignment does (which is\n     *    implemented by calling a function) we'll defer this for now.\n     * 2. value structs (or static arrays of them) that need to be copy constructed\n     * 3. value structs (or static arrays of them) that have destructors, and subsequent arguments that may throw before the\n     *    function gets called (functions normally destroy their parameters)\n     * 2 and 3 are handled by doing the argument construction in 'eprefix' so that if a later argument throws, they are cleaned\n     * up properly. Pushing arguments on the stack then cannot fail.\n     */\n    if (1)\n    {\n        /* TODO: tackle problem 1)\n         */\n        const bool leftToRight = true; // TODO: something like !fd.isArrayOp\n        if (!leftToRight)\n            assert(nargs == nparams); // no variadics for RTL order, as they would probably be evaluated LTR and so add complexity\n\n        const ptrdiff_t start = (leftToRight ? 0 : cast(ptrdiff_t)nargs - 1);\n        const ptrdiff_t end = (leftToRight ? cast(ptrdiff_t)nargs : -1);\n        const ptrdiff_t step = (leftToRight ? 1 : -1);\n\n        /* Compute indices of last throwing argument and first arg needing destruction.\n         * Used to not set up destructors unless an arg needs destruction on a throw\n         * in a later argument.\n         */\n        ptrdiff_t lastthrow = -1;\n        ptrdiff_t firstdtor = -1;\n        for (ptrdiff_t i = start; i != end; i += step)\n        {\n            Expression arg = (*arguments)[i];\n            if (canThrow(arg, sc.func, false))\n                lastthrow = i;\n            if (firstdtor == -1 && arg.type.needsDestruction())\n            {\n                Parameter p = (i >= nparams ? null : Parameter.getNth(tf.parameters, i));\n                if (!(p && (p.storageClass & (STC.lazy_ | STC.ref_ | STC.out_))))\n                    firstdtor = i;\n            }\n        }\n\n        /* Does problem 3) apply to this call?\n         */\n        const bool needsPrefix = (firstdtor >= 0 && lastthrow >= 0\n            && (lastthrow - firstdtor) * step > 0);\n\n        /* If so, initialize 'eprefix' by declaring the gate\n         */\n        VarDeclaration gate = null;\n        if (needsPrefix)\n        {\n            // eprefix => bool __gate [= false]\n            Identifier idtmp = Identifier.generateId(\"__gate\");\n            gate = new VarDeclaration(loc, Type.tbool, idtmp, null);\n            gate.storage_class |= STC.temp | STC.ctfe | STC.volatile_;\n            gate.dsymbolSemantic(sc);\n\n            auto ae = new DeclarationExp(loc, gate);\n            eprefix = ae.expressionSemantic(sc);\n        }\n\n        for (ptrdiff_t i = start; i != end; i += step)\n        {\n            Expression arg = (*arguments)[i];\n\n            Parameter parameter = (i >= nparams ? null : Parameter.getNth(tf.parameters, i));\n            const bool isRef = (parameter && (parameter.storageClass & (STC.ref_ | STC.out_)));\n            const bool isLazy = (parameter && (parameter.storageClass & STC.lazy_));\n\n            /* Skip lazy parameters\n             */\n            if (isLazy)\n                continue;\n\n            /* Do we have a gate? Then we have a prefix and we're not yet past the last throwing arg.\n             * Declare a temporary variable for this arg and append that declaration to 'eprefix',\n             * which will implicitly take care of potential problem 2) for this arg.\n             * 'eprefix' will therefore finally contain all args up to and including the last\n             * potentially throwing arg, excluding all lazy parameters.\n             */\n            if (gate)\n            {\n                const bool needsDtor = (!isRef && arg.type.needsDestruction() && i != lastthrow);\n\n                /* Declare temporary 'auto __pfx = arg' (needsDtor) or 'auto __pfy = arg' (!needsDtor)\n                 */\n                auto tmp = copyToTemp(0,\n                    needsDtor ? \"__pfx\" : \"__pfy\",\n                    !isRef ? arg : arg.addressOf());\n                tmp.dsymbolSemantic(sc);\n\n                /* Modify the destructor so it only runs if gate==false, i.e.,\n                 * only if there was a throw while constructing the args\n                 */\n                if (!needsDtor)\n                {\n                    if (tmp.edtor)\n                    {\n                        assert(i == lastthrow);\n                        tmp.edtor = null;\n                    }\n                }\n                else\n                {\n                    // edtor => (__gate || edtor)\n                    assert(tmp.edtor);\n                    Expression e = tmp.edtor;\n                    e = new LogicalExp(e.loc, TOK.orOr, new VarExp(e.loc, gate), e);\n                    tmp.edtor = e.expressionSemantic(sc);\n                    //printf(\"edtor: %s\\n\", tmp.edtor.toChars());\n                }\n\n                // eprefix => (eprefix, auto __pfx/y = arg)\n                auto ae = new DeclarationExp(loc, tmp);\n                eprefix = Expression.combine(eprefix, ae.expressionSemantic(sc));\n\n                // arg => __pfx/y\n                arg = new VarExp(loc, tmp);\n                arg = arg.expressionSemantic(sc);\n                if (isRef)\n                {\n                    arg = new PtrExp(loc, arg);\n                    arg = arg.expressionSemantic(sc);\n                }\n\n                /* Last throwing arg? Then finalize eprefix => (eprefix, gate = true),\n                 * i.e., disable the dtors right after constructing the last throwing arg.\n                 * From now on, the callee will take care of destructing the args because\n                 * the args are implicitly moved into function parameters.\n                 *\n                 * Set gate to null to let the next iterations know they don't need to\n                 * append to eprefix anymore.\n                 */\n                if (i == lastthrow)\n                {\n                    auto e = new AssignExp(gate.loc, new VarExp(gate.loc, gate), new IntegerExp(gate.loc, 1, Type.tbool));\n                    eprefix = Expression.combine(eprefix, e.expressionSemantic(sc));\n                    gate = null;\n                }\n            }\n            else\n            {\n                /* No gate, no prefix to append to.\n                 * Handle problem 2) by calling the copy constructor for value structs\n                 * (or static arrays of them) if appropriate.\n                 */\n                Type tv = arg.type.baseElemOf();\n                if (!isRef && tv.ty == Tstruct)\n                    arg = doCopyOrMove(sc, arg);\n            }\n\n            (*arguments)[i] = arg;\n        }\n    }\n    //if (eprefix) printf(\"eprefix: %s\\n\", eprefix.toChars());\n\n    // If D linkage and variadic, add _arguments[] as first argument\n    if (tf.linkage == LINK.d && tf.varargs == 1)\n    {\n        assert(arguments.dim >= nparams);\n\n        auto args = new Parameters(arguments.dim - nparams);\n        for (size_t i = 0; i < arguments.dim - nparams; i++)\n        {\n            auto arg = new Parameter(STC.in_, (*arguments)[nparams + i].type, null, null, null);\n            (*args)[i] = arg;\n        }\n        auto tup = new TypeTuple(args);\n        Expression e = (new TypeidExp(loc, tup)).expressionSemantic(sc);\n        arguments.insert(0, e);\n    }\n\n    Type tret = tf.next;\n    if (isCtorCall)\n    {\n        //printf(\"[%s] fd = %s %s, %d %d %d\\n\", loc.toChars(), fd.toChars(), fd.type.toChars(),\n        //    wildmatch, tf.isWild(), fd.isReturnIsolated());\n        if (!tthis)\n        {\n            assert(sc.intypeof || global.errors);\n            tthis = fd.isThis().type.addMod(fd.type.mod);\n        }\n        if (tf.isWild() && !fd.isReturnIsolated())\n        {\n            if (wildmatch)\n                tret = tret.substWildTo(wildmatch);\n            int offset;\n            if (!tret.implicitConvTo(tthis) && !(MODimplicitConv(tret.mod, tthis.mod) && tret.isBaseOf(tthis, &offset) && offset == 0))\n            {\n                const(char)* s1 = tret.isNaked() ? \" mutable\" : tret.modToChars();\n                const(char)* s2 = tthis.isNaked() ? \" mutable\" : tthis.modToChars();\n                .error(loc, \"`inout` constructor `%s` creates%s object, not%s\", fd.toPrettyChars(), s1, s2);\n                err = true;\n            }\n        }\n        tret = tthis;\n    }\n    else if (wildmatch && tret)\n    {\n        /* Adjust function return type based on wildmatch\n         */\n        //printf(\"wildmatch = x%x, tret = %s\\n\", wildmatch, tret.toChars());\n        tret = tret.substWildTo(wildmatch);\n    }\n    *prettype = tret;\n    *peprefix = eprefix;\n    return (err || olderrors != global.errors);\n}\n\nprivate Module loadStdMath()\n{\n    __gshared Import impStdMath = null;\n    if (!impStdMath)\n    {\n        auto a = new Identifiers();\n        a.push(Id.std);\n        auto s = new Import(Loc.initial, a, Id.math, null, false);\n        // Module.load will call fatal() if there's no std.math available.\n        // Gag the error here, pushing the error handling to the caller.\n        uint errors = global.startGagging();\n        s.load(null);\n        if (s.mod)\n        {\n            s.mod.importAll(null);\n            s.mod.dsymbolSemantic(null);\n        }\n        global.endGagging(errors);\n        impStdMath = s;\n    }\n    return impStdMath.mod;\n}\n\nprivate extern (C++) final class ExpressionSemanticVisitor : Visitor\n{\n    alias visit = Visitor.visit;\n\n    Scope* sc;\n    Expression result;\n\n    this(Scope* sc)\n    {\n        this.sc = sc;\n    }\n\n    private void setError()\n    {\n        result = new ErrorExp();\n    }\n\n    /**************************\n     * Semantically analyze Expression.\n     * Determine types, fold constants, etc.\n     */\n    override void visit(Expression e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"Expression::semantic() %s\\n\", e.toChars());\n        }\n        if (e.type)\n            e.type = e.type.typeSemantic(e.loc, sc);\n        else\n            e.type = Type.tvoid;\n        result = e;\n    }\n\n    override void visit(IntegerExp e)\n    {\n        assert(e.type);\n        if (e.type.ty == Terror)\n            return setError();\n\n        assert(e.type.deco);\n        e.setInteger(e.getInteger());\n        result = e;\n    }\n\n    override void visit(RealExp e)\n    {\n        if (!e.type)\n            e.type = Type.tfloat64;\n        else\n            e.type = e.type.typeSemantic(e.loc, sc);\n        result = e;\n    }\n\n    override void visit(ComplexExp e)\n    {\n        if (!e.type)\n            e.type = Type.tcomplex80;\n        else\n            e.type = e.type.typeSemantic(e.loc, sc);\n        result = e;\n    }\n\n    override void visit(IdentifierExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"IdentifierExp::semantic('%s')\\n\", exp.ident.toChars());\n        }\n        if (exp.type) // This is used as the dummy expression\n        {\n            result = exp;\n            return;\n        }\n\n        Dsymbol scopesym;\n        Dsymbol s = sc.search(exp.loc, exp.ident, &scopesym);\n        if (s)\n        {\n            if (s.errors)\n                return setError();\n\n            Expression e;\n\n            /* See if the symbol was a member of an enclosing 'with'\n             */\n            WithScopeSymbol withsym = scopesym.isWithScopeSymbol();\n            if (withsym && withsym.withstate.wthis)\n            {\n                /* Disallow shadowing\n                 */\n                // First find the scope of the with\n                Scope* scwith = sc;\n                while (scwith.scopesym != scopesym)\n                {\n                    scwith = scwith.enclosing;\n                    assert(scwith);\n                }\n                // Look at enclosing scopes for symbols with the same name,\n                // in the same function\n                for (Scope* scx = scwith; scx && scx.func == scwith.func; scx = scx.enclosing)\n                {\n                    Dsymbol s2;\n                    if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s != s2)\n                    {\n                        exp.error(\"with symbol `%s` is shadowing local symbol `%s`\", s.toPrettyChars(), s2.toPrettyChars());\n                        return setError();\n                    }\n                }\n                s = s.toAlias();\n\n                // Same as wthis.ident\n                //  TODO: DotIdExp.semantic will find 'ident' from 'wthis' again.\n                //  The redudancy should be removed.\n                e = new VarExp(exp.loc, withsym.withstate.wthis);\n                e = new DotIdExp(exp.loc, e, exp.ident);\n                e = e.expressionSemantic(sc);\n            }\n            else\n            {\n                if (withsym)\n                {\n                    Declaration d = s.isDeclaration();\n                    if (d)\n                        checkAccess(exp.loc, sc, null, d);\n                }\n\n                /* If f is really a function template,\n                 * then replace f with the function template declaration.\n                 */\n                FuncDeclaration f = s.isFuncDeclaration();\n                if (f)\n                {\n                    TemplateDeclaration td = getFuncTemplateDecl(f);\n                    if (td)\n                    {\n                        if (td.overroot) // if not start of overloaded list of TemplateDeclaration's\n                            td = td.overroot; // then get the start\n                        e = new TemplateExp(exp.loc, td, f);\n                        e = e.expressionSemantic(sc);\n                        result = e;\n                        return;\n                    }\n                }\n                // Haven't done overload resolution yet, so pass 1\n                e = resolve(exp.loc, sc, s, true);\n            }\n            result = e;\n            return;\n        }\n\n        if (hasThis(sc))\n        {\n            for (AggregateDeclaration ad = sc.getStructClassScope(); ad;)\n            {\n                if (ad.aliasthis)\n                {\n                    Expression e;\n                    e = new ThisExp(exp.loc);\n                    e = new DotIdExp(exp.loc, e, ad.aliasthis.ident);\n                    e = new DotIdExp(exp.loc, e, exp.ident);\n                    e = e.trySemantic(sc);\n                    if (e)\n                    {\n                        result = e;\n                        return;\n                    }\n                }\n\n                auto cd = ad.isClassDeclaration();\n                if (cd && cd.baseClass && cd.baseClass != ClassDeclaration.object)\n                {\n                    ad = cd.baseClass;\n                    continue;\n                }\n                break;\n            }\n        }\n\n        if (exp.ident == Id.ctfe)\n        {\n            if (sc.flags & SCOPE.ctfe)\n            {\n                exp.error(\"variable `__ctfe` cannot be read at compile time\");\n                return setError();\n            }\n\n            // Create the magic __ctfe bool variable\n            auto vd = new VarDeclaration(exp.loc, Type.tbool, Id.ctfe, null);\n            vd.storage_class |= STC.temp;\n            vd.semanticRun = PASS.semanticdone;\n            Expression e = new VarExp(exp.loc, vd);\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n\n        // If we've reached this point and are inside a with() scope then we may\n        // try one last attempt by checking whether the 'wthis' object supports\n        // dynamic dispatching via opDispatch.\n        // This is done by rewriting this expression as wthis.ident.\n        // The innermost with() scope of the hierarchy to satisfy the condition\n        // above wins.\n        // https://issues.dlang.org/show_bug.cgi?id=6400\n        for (Scope* sc2 = sc; sc2; sc2 = sc2.enclosing)\n        {\n            if (!sc2.scopesym)\n                continue;\n\n            if (auto ss = sc2.scopesym.isWithScopeSymbol())\n            {\n                if (ss.withstate.wthis)\n                {\n                    Expression e;\n                    e = new VarExp(exp.loc, ss.withstate.wthis);\n                    e = new DotIdExp(exp.loc, e, exp.ident);\n                    e = e.trySemantic(sc);\n                    if (e)\n                    {\n                        result = e;\n                        return;\n                    }\n                }\n            }\n        }\n\n        /* Look for what user might have meant\n         */\n        if (const n = importHint(exp.ident.toString()))\n            exp.error(\"`%s` is not defined, perhaps `import %.*s;` is needed?\", exp.ident.toChars(), cast(int)n.length, n.ptr);\n        else if (auto s2 = sc.search_correct(exp.ident))\n            exp.error(\"undefined identifier `%s`, did you mean %s `%s`?\", exp.ident.toChars(), s2.kind(), s2.toChars());\n        else if (const p = Scope.search_correct_C(exp.ident))\n            exp.error(\"undefined identifier `%s`, did you mean `%s`?\", exp.ident.toChars(), p);\n        else\n            exp.error(\"undefined identifier `%s`\", exp.ident.toChars());\n\n        result = new ErrorExp();\n    }\n\n    override void visit(DsymbolExp e)\n    {\n        result = resolve(e.loc, sc, e.s, e.hasOverloads);\n    }\n\n    override void visit(ThisExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"ThisExp::semantic()\\n\");\n        }\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n\n        FuncDeclaration fd = hasThis(sc); // fd is the uplevel function with the 'this' variable\n\n        /* Special case for typeof(this) and typeof(super) since both\n         * should work even if they are not inside a non-static member function\n         */\n        if (!fd && sc.intypeof == 1)\n        {\n            // Find enclosing struct or class\n            for (Dsymbol s = sc.getStructClassScope(); 1; s = s.parent)\n            {\n                if (!s)\n                {\n                    e.error(\"`%s` is not in a class or struct scope\", e.toChars());\n                    goto Lerr;\n                }\n                ClassDeclaration cd = s.isClassDeclaration();\n                if (cd)\n                {\n                    e.type = cd.type;\n                    result = e;\n                    return;\n                }\n                StructDeclaration sd = s.isStructDeclaration();\n                if (sd)\n                {\n                    e.type = sd.type;\n                    result = e;\n                    return;\n                }\n            }\n        }\n        if (!fd)\n            goto Lerr;\n\n        assert(fd.vthis);\n        e.var = fd.vthis;\n        assert(e.var.parent);\n        e.type = e.var.type;\n\n        if (e.var.checkNestedReference(sc, e.loc))\n            return setError();\n\n        result = e;\n        return;\n\n    Lerr:\n        e.error(\"`this` is only defined in non-static member functions, not `%s`\", sc.parent.toChars());\n        result = new ErrorExp();\n    }\n\n    override void visit(SuperExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"SuperExp::semantic('%s')\\n\", e.toChars());\n        }\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n\n        FuncDeclaration fd = hasThis(sc);\n        ClassDeclaration cd;\n        Dsymbol s;\n\n        /* Special case for typeof(this) and typeof(super) since both\n         * should work even if they are not inside a non-static member function\n         */\n        if (!fd && sc.intypeof == 1)\n        {\n            // Find enclosing class\n            for (s = sc.getStructClassScope(); 1; s = s.parent)\n            {\n                if (!s)\n                {\n                    e.error(\"`%s` is not in a class scope\", e.toChars());\n                    goto Lerr;\n                }\n                cd = s.isClassDeclaration();\n                if (cd)\n                {\n                    cd = cd.baseClass;\n                    if (!cd)\n                    {\n                        e.error(\"class `%s` has no `super`\", s.toChars());\n                        goto Lerr;\n                    }\n                    e.type = cd.type;\n                    result = e;\n                    return;\n                }\n            }\n        }\n        if (!fd)\n            goto Lerr;\n\n        e.var = fd.vthis;\n        assert(e.var && e.var.parent);\n\n        s = fd.toParent();\n        while (s && s.isTemplateInstance())\n            s = s.toParent();\n        if (s.isTemplateDeclaration()) // allow inside template constraint\n            s = s.toParent();\n        assert(s);\n        cd = s.isClassDeclaration();\n        //printf(\"parent is %s %s\\n\", fd.toParent().kind(), fd.toParent().toChars());\n        if (!cd)\n            goto Lerr;\n        if (!cd.baseClass)\n        {\n            e.error(\"no base class for `%s`\", cd.toChars());\n            e.type = e.var.type;\n        }\n        else\n        {\n            e.type = cd.baseClass.type;\n            e.type = e.type.castMod(e.var.type.mod);\n        }\n\n        if (e.var.checkNestedReference(sc, e.loc))\n            return setError();\n\n        result = e;\n        return;\n\n    Lerr:\n        e.error(\"`super` is only allowed in non-static class member functions\");\n        result = new ErrorExp();\n    }\n\n    override void visit(NullExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"NullExp::semantic('%s')\\n\", e.toChars());\n        }\n        // NULL is the same as (void *)0\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n        e.type = Type.tnull;\n        result = e;\n    }\n\n    override void visit(StringExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"StringExp::semantic() %s\\n\", e.toChars());\n        }\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n\n        OutBuffer buffer;\n        size_t newlen = 0;\n        const(char)* p;\n        size_t u;\n        dchar c;\n\n        switch (e.postfix)\n        {\n        case 'd':\n            for (u = 0; u < e.len;)\n            {\n                p = utf_decodeChar(e.string, e.len, u, c);\n                if (p)\n                {\n                    e.error(\"%s\", p);\n                    return setError();\n                }\n                else\n                {\n                    buffer.write4(c);\n                    newlen++;\n                }\n            }\n            buffer.write4(0);\n            e.dstring = cast(dchar*)buffer.extractData();\n            e.len = newlen;\n            e.sz = 4;\n            e.type = new TypeDArray(Type.tdchar.immutableOf());\n            e.committed = 1;\n            break;\n\n        case 'w':\n            for (u = 0; u < e.len;)\n            {\n                p = utf_decodeChar(e.string, e.len, u, c);\n                if (p)\n                {\n                    e.error(\"%s\", p);\n                    return setError();\n                }\n                else\n                {\n                    buffer.writeUTF16(c);\n                    newlen++;\n                    if (c >= 0x10000)\n                        newlen++;\n                }\n            }\n            buffer.writeUTF16(0);\n            e.wstring = cast(wchar*)buffer.extractData();\n            e.len = newlen;\n            e.sz = 2;\n            e.type = new TypeDArray(Type.twchar.immutableOf());\n            e.committed = 1;\n            break;\n\n        case 'c':\n            e.committed = 1;\n            goto default;\n\n        default:\n            e.type = new TypeDArray(Type.tchar.immutableOf());\n            break;\n        }\n        e.type = e.type.typeSemantic(e.loc, sc);\n        //type = type.immutableOf();\n        //printf(\"type = %s\\n\", type.toChars());\n\n        result = e;\n    }\n\n    override void visit(TupleExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"+TupleExp::semantic(%s)\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (exp.e0)\n            exp.e0 = exp.e0.expressionSemantic(sc);\n\n        // Run semantic() on each argument\n        bool err = false;\n        for (size_t i = 0; i < exp.exps.dim; i++)\n        {\n            Expression e = (*exp.exps)[i];\n            e = e.expressionSemantic(sc);\n            if (!e.type)\n            {\n                exp.error(\"`%s` has no value\", e.toChars());\n                err = true;\n            }\n            else if (e.op == TOK.error)\n                err = true;\n            else\n                (*exp.exps)[i] = e;\n        }\n        if (err)\n            return setError();\n\n        expandTuples(exp.exps);\n\n        exp.type = new TypeTuple(exp.exps);\n        exp.type = exp.type.typeSemantic(exp.loc, sc);\n        //printf(\"-TupleExp::semantic(%s)\\n\", toChars());\n        result = exp;\n    }\n\n    override void visit(ArrayLiteralExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"ArrayLiteralExp::semantic('%s')\\n\", e.toChars());\n        }\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n\n        /* Perhaps an empty array literal [ ] should be rewritten as null?\n         */\n\n        if (e.basis)\n            e.basis = e.basis.expressionSemantic(sc);\n        if (arrayExpressionSemantic(e.elements, sc) || (e.basis && e.basis.op == TOK.error))\n            return setError();\n\n        expandTuples(e.elements);\n\n        Type t0;\n        if (e.basis)\n            e.elements.push(e.basis);\n        bool err = arrayExpressionToCommonType(sc, e.elements, &t0);\n        if (e.basis)\n            e.basis = e.elements.pop();\n        if (err)\n            return setError();\n\n        e.type = t0.arrayOf();\n        e.type = e.type.typeSemantic(e.loc, sc);\n\n        /* Disallow array literals of type void being used.\n         */\n        if (e.elements.dim > 0 && t0.ty == Tvoid)\n        {\n            e.error(\"`%s` of type `%s` has no value\", e.toChars(), e.type.toChars());\n            return setError();\n        }\n\n        if (global.params.useTypeInfo && Type.dtypeinfo)\n            semanticTypeInfo(sc, e.type);\n\n        result = e;\n    }\n\n    override void visit(AssocArrayLiteralExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"AssocArrayLiteralExp::semantic('%s')\\n\", e.toChars());\n        }\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n\n        // Run semantic() on each element\n        bool err_keys = arrayExpressionSemantic(e.keys, sc);\n        bool err_vals = arrayExpressionSemantic(e.values, sc);\n        if (err_keys || err_vals)\n            return setError();\n\n        expandTuples(e.keys);\n        expandTuples(e.values);\n        if (e.keys.dim != e.values.dim)\n        {\n            e.error(\"number of keys is %u, must match number of values %u\", e.keys.dim, e.values.dim);\n            return setError();\n        }\n\n        Type tkey = null;\n        Type tvalue = null;\n        err_keys = arrayExpressionToCommonType(sc, e.keys, &tkey);\n        err_vals = arrayExpressionToCommonType(sc, e.values, &tvalue);\n        if (err_keys || err_vals)\n            return setError();\n\n        if (tkey == Type.terror || tvalue == Type.terror)\n            return setError();\n\n        e.type = new TypeAArray(tvalue, tkey);\n        e.type = e.type.typeSemantic(e.loc, sc);\n\n        semanticTypeInfo(sc, e.type);\n\n        if (global.params.vsafe)\n        {\n            if (checkAssocArrayLiteralEscape(sc, e, false))\n                return setError();\n        }\n\n        result = e;\n    }\n\n    override void visit(StructLiteralExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"StructLiteralExp::semantic('%s')\\n\", e.toChars());\n        }\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n\n        e.sd.size(e.loc);\n        if (e.sd.sizeok != Sizeok.done)\n            return setError();\n\n        // run semantic() on each element\n        if (arrayExpressionSemantic(e.elements, sc))\n            return setError();\n\n        expandTuples(e.elements);\n\n        /* Fit elements[] to the corresponding type of field[].\n         */\n        if (!e.sd.fit(e.loc, sc, e.elements, e.stype))\n            return setError();\n\n        /* Fill out remainder of elements[] with default initializers for fields[]\n         */\n        if (!e.sd.fill(e.loc, e.elements, false))\n        {\n            /* An error in the initializer needs to be recorded as an error\n             * in the enclosing function or template, since the initializer\n             * will be part of the stuct declaration.\n             */\n            global.increaseErrorCount();\n            return setError();\n        }\n\n        if (checkFrameAccess(e.loc, sc, e.sd, e.elements.dim))\n            return setError();\n\n        e.type = e.stype ? e.stype : e.sd.type;\n        result = e;\n    }\n\n    override void visit(TypeExp exp)\n    {\n        if (exp.type.ty == Terror)\n            return setError();\n\n        //printf(\"TypeExp::semantic(%s)\\n\", type.toChars());\n        Expression e;\n        Type t;\n        Dsymbol s;\n\n        dmd.typesem.resolve(exp.type, exp.loc, sc, &e, &t, &s, true);\n        if (e)\n        {\n            //printf(\"e = %s %s\\n\", Token::toChars(e.op), e.toChars());\n            e = e.expressionSemantic(sc);\n        }\n        else if (t)\n        {\n            //printf(\"t = %d %s\\n\", t.ty, t.toChars());\n            exp.type = t.typeSemantic(exp.loc, sc);\n            e = exp;\n        }\n        else if (s)\n        {\n            //printf(\"s = %s %s\\n\", s.kind(), s.toChars());\n            e = resolve(exp.loc, sc, s, true);\n        }\n        else\n            assert(0);\n\n        if (global.params.vcomplex)\n            exp.type.checkComplexTransition(exp.loc, sc);\n\n        result = e;\n    }\n\n    override void visit(ScopeExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"+ScopeExp::semantic(%p '%s')\\n\", exp, exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        ScopeDsymbol sds2 = exp.sds;\n        TemplateInstance ti = sds2.isTemplateInstance();\n        while (ti)\n        {\n            WithScopeSymbol withsym;\n            if (!ti.findTempDecl(sc, &withsym) || !ti.semanticTiargs(sc))\n                return setError();\n            if (withsym && withsym.withstate.wthis)\n            {\n                Expression e = new VarExp(exp.loc, withsym.withstate.wthis);\n                e = new DotTemplateInstanceExp(exp.loc, e, ti);\n                result = e.expressionSemantic(sc);\n                return;\n            }\n            if (ti.needsTypeInference(sc))\n            {\n                if (TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration())\n                {\n                    Dsymbol p = td.toParent2();\n                    FuncDeclaration fdthis = hasThis(sc);\n                    AggregateDeclaration ad = p ? p.isAggregateDeclaration() : null;\n                    if (fdthis && ad && isAggregate(fdthis.vthis.type) == ad && (td._scope.stc & STC.static_) == 0)\n                    {\n                        Expression e = new DotTemplateInstanceExp(exp.loc, new ThisExp(exp.loc), ti.name, ti.tiargs);\n                        result = e.expressionSemantic(sc);\n                        return;\n                    }\n                }\n                else if (OverloadSet os = ti.tempdecl.isOverloadSet())\n                {\n                    FuncDeclaration fdthis = hasThis(sc);\n                    AggregateDeclaration ad = os.parent.isAggregateDeclaration();\n                    if (fdthis && ad && isAggregate(fdthis.vthis.type) == ad)\n                    {\n                        Expression e = new DotTemplateInstanceExp(exp.loc, new ThisExp(exp.loc), ti.name, ti.tiargs);\n                        result = e.expressionSemantic(sc);\n                        return;\n                    }\n                }\n                // ti is an instance which requires IFTI.\n                exp.sds = ti;\n                exp.type = Type.tvoid;\n                result = exp;\n                return;\n            }\n            ti.dsymbolSemantic(sc);\n            if (!ti.inst || ti.errors)\n                return setError();\n\n            Dsymbol s = ti.toAlias();\n            if (s == ti)\n            {\n                exp.sds = ti;\n                exp.type = Type.tvoid;\n                result = exp;\n                return;\n            }\n            sds2 = s.isScopeDsymbol();\n            if (sds2)\n            {\n                ti = sds2.isTemplateInstance();\n                //printf(\"+ sds2 = %s, '%s'\\n\", sds2.kind(), sds2.toChars());\n                continue;\n            }\n\n            if (auto v = s.isVarDeclaration())\n            {\n                if (!v.type)\n                {\n                    exp.error(\"forward reference of %s `%s`\", v.kind(), v.toChars());\n                    return setError();\n                }\n                if ((v.storage_class & STC.manifest) && v._init)\n                {\n                    /* When an instance that will be converted to a constant exists,\n                     * the instance representation \"foo!tiargs\" is treated like a\n                     * variable name, and its recursive appearance check (note that\n                     * it's equivalent with a recursive instantiation of foo) is done\n                     * separately from the circular initialization check for the\n                     * eponymous enum variable declaration.\n                     *\n                     *  template foo(T) {\n                     *    enum bool foo = foo;    // recursive definition check (v.inuse)\n                     *  }\n                     *  template bar(T) {\n                     *    enum bool bar = bar!T;  // recursive instantiation check (ti.inuse)\n                     *  }\n                     */\n                    if (ti.inuse)\n                    {\n                        exp.error(\"recursive expansion of %s `%s`\", ti.kind(), ti.toPrettyChars());\n                        return setError();\n                    }\n                    auto e = v.expandInitializer(exp.loc);\n                    ti.inuse++;\n                    e = e.expressionSemantic(sc);\n                    ti.inuse--;\n                    result = e;\n                    return;\n                }\n            }\n\n            //printf(\"s = %s, '%s'\\n\", s.kind(), s.toChars());\n            auto e = resolve(exp.loc, sc, s, true);\n            //printf(\"-1ScopeExp::semantic()\\n\");\n            result = e;\n            return;\n        }\n\n        //printf(\"sds2 = %s, '%s'\\n\", sds2.kind(), sds2.toChars());\n        //printf(\"\\tparent = '%s'\\n\", sds2.parent.toChars());\n        sds2.dsymbolSemantic(sc);\n\n        // (Aggregate|Enum)Declaration\n        if (auto t = sds2.getType())\n        {\n            result = (new TypeExp(exp.loc, t)).expressionSemantic(sc);\n            return;\n        }\n\n        if (auto td = sds2.isTemplateDeclaration())\n        {\n            result = (new TemplateExp(exp.loc, td)).expressionSemantic(sc);\n            return;\n        }\n\n        exp.sds = sds2;\n        exp.type = Type.tvoid;\n        //printf(\"-2ScopeExp::semantic() %s\\n\", toChars());\n        result = exp;\n    }\n\n    override void visit(NewExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"NewExp::semantic() %s\\n\", exp.toChars());\n            if (exp.thisexp)\n                printf(\"\\tthisexp = %s\\n\", exp.thisexp.toChars());\n            printf(\"\\tnewtype: %s\\n\", exp.newtype.toChars());\n        }\n        if (exp.type) // if semantic() already run\n        {\n            result = exp;\n            return;\n        }\n\n        // https://issues.dlang.org/show_bug.cgi?id=11581\n        // With the syntax `new T[edim]` or `thisexp.new T[edim]`,\n        // T should be analyzed first and edim should go into arguments iff it's\n        // not a tuple.\n        Expression edim = null;\n        if (!exp.arguments && exp.newtype.ty == Tsarray)\n        {\n            edim = (cast(TypeSArray)exp.newtype).dim;\n            exp.newtype = (cast(TypeNext)exp.newtype).next;\n        }\n\n        ClassDeclaration cdthis = null;\n        if (exp.thisexp)\n        {\n            exp.thisexp = exp.thisexp.expressionSemantic(sc);\n            if (exp.thisexp.op == TOK.error)\n                return setError();\n\n            cdthis = exp.thisexp.type.isClassHandle();\n            if (!cdthis)\n            {\n                exp.error(\"`this` for nested class must be a class type, not `%s`\", exp.thisexp.type.toChars());\n                return setError();\n            }\n\n            sc = sc.push(cdthis);\n            exp.type = exp.newtype.typeSemantic(exp.loc, sc);\n            sc = sc.pop();\n        }\n        else\n        {\n            exp.type = exp.newtype.typeSemantic(exp.loc, sc);\n        }\n        if (exp.type.ty == Terror)\n            return setError();\n\n        if (edim)\n        {\n            if (exp.type.toBasetype().ty == Ttuple)\n            {\n                // --> new T[edim]\n                exp.type = new TypeSArray(exp.type, edim);\n                exp.type = exp.type.typeSemantic(exp.loc, sc);\n                if (exp.type.ty == Terror)\n                    return setError();\n            }\n            else\n            {\n                // --> new T[](edim)\n                exp.arguments = new Expressions();\n                exp.arguments.push(edim);\n                exp.type = exp.type.arrayOf();\n            }\n        }\n\n        exp.newtype = exp.type; // in case type gets cast to something else\n        Type tb = exp.type.toBasetype();\n        //printf(\"tb: %s, deco = %s\\n\", tb.toChars(), tb.deco);\n\n        if (arrayExpressionSemantic(exp.newargs, sc) ||\n            preFunctionParameters(sc, exp.newargs))\n        {\n            return setError();\n        }\n        if (arrayExpressionSemantic(exp.arguments, sc) ||\n            preFunctionParameters(sc, exp.arguments))\n        {\n            return setError();\n        }\n\n        if (exp.thisexp && tb.ty != Tclass)\n        {\n            exp.error(\"`.new` is only for allocating nested classes, not `%s`\", tb.toChars());\n            return setError();\n        }\n\n        size_t nargs = exp.arguments ? exp.arguments.dim : 0;\n        Expression newprefix = null;\n\n        if (tb.ty == Tclass)\n        {\n            auto cd = (cast(TypeClass)tb).sym;\n            cd.size(exp.loc);\n            if (cd.sizeok != Sizeok.done)\n                return setError();\n            if (!cd.ctor)\n                cd.ctor = cd.searchCtor();\n            if (cd.noDefaultCtor && !nargs && !cd.defaultCtor)\n            {\n                exp.error(\"default construction is disabled for type `%s`\", cd.type.toChars());\n                return setError();\n            }\n\n            if (cd.isInterfaceDeclaration())\n            {\n                exp.error(\"cannot create instance of interface `%s`\", cd.toChars());\n                return setError();\n            }\n\n            if (cd.isAbstract())\n            {\n                exp.error(\"cannot create instance of abstract class `%s`\", cd.toChars());\n                for (size_t i = 0; i < cd.vtbl.dim; i++)\n                {\n                    FuncDeclaration fd = cd.vtbl[i].isFuncDeclaration();\n                    if (fd && fd.isAbstract())\n                    {\n                        errorSupplemental(exp.loc, \"function `%s` is not implemented\",\n                            fd.toFullSignature());\n                    }\n                }\n                return setError();\n            }\n            // checkDeprecated() is already done in newtype.typeSemantic().\n\n            if (cd.isNested())\n            {\n                /* We need a 'this' pointer for the nested class.\n                 * Ensure we have the right one.\n                 */\n                Dsymbol s = cd.toParent2();\n\n                //printf(\"cd isNested, parent = %s '%s'\\n\", s.kind(), s.toPrettyChars());\n                if (auto cdn = s.isClassDeclaration())\n                {\n                    if (!cdthis)\n                    {\n                        // Supply an implicit 'this' and try again\n                        exp.thisexp = new ThisExp(exp.loc);\n                        for (Dsymbol sp = sc.parent; 1; sp = sp.parent)\n                        {\n                            if (!sp)\n                            {\n                                exp.error(\"outer class `%s` `this` needed to `new` nested class `%s`\",\n                                    cdn.toChars(), cd.toChars());\n                                return setError();\n                            }\n                            ClassDeclaration cdp = sp.isClassDeclaration();\n                            if (!cdp)\n                                continue;\n                            if (cdp == cdn || cdn.isBaseOf(cdp, null))\n                                break;\n                            // Add a '.outer' and try again\n                            exp.thisexp = new DotIdExp(exp.loc, exp.thisexp, Id.outer);\n                        }\n\n                        exp.thisexp = exp.thisexp.expressionSemantic(sc);\n                        if (exp.thisexp.op == TOK.error)\n                            return setError();\n                        cdthis = exp.thisexp.type.isClassHandle();\n                    }\n                    if (cdthis != cdn && !cdn.isBaseOf(cdthis, null))\n                    {\n                        //printf(\"cdthis = %s\\n\", cdthis.toChars());\n                        exp.error(\"`this` for nested class must be of type `%s`, not `%s`\",\n                            cdn.toChars(), exp.thisexp.type.toChars());\n                        return setError();\n                    }\n                    if (!MODimplicitConv(exp.thisexp.type.mod, exp.newtype.mod))\n                    {\n                        exp.error(\"nested type `%s` should have the same or weaker constancy as enclosing type `%s`\",\n                            exp.newtype.toChars(), exp.thisexp.type.toChars());\n                        return setError();\n                    }\n                }\n                else if (exp.thisexp)\n                {\n                    exp.error(\"`.new` is only for allocating nested classes\");\n                    return setError();\n                }\n                else if (auto fdn = s.isFuncDeclaration())\n                {\n                    // make sure the parent context fdn of cd is reachable from sc\n                    if (!ensureStaticLinkTo(sc.parent, fdn))\n                    {\n                        exp.error(\"outer function context of `%s` is needed to `new` nested class `%s`\",\n                            fdn.toPrettyChars(), cd.toPrettyChars());\n                        return setError();\n                    }\n                }\n                else\n                    assert(0);\n            }\n            else if (exp.thisexp)\n            {\n                exp.error(\"`.new` is only for allocating nested classes\");\n                return setError();\n            }\n\n            if (cd.aggNew)\n            {\n                // Prepend the size argument to newargs[]\n                Expression e = new IntegerExp(exp.loc, cd.size(exp.loc), Type.tsize_t);\n                if (!exp.newargs)\n                    exp.newargs = new Expressions();\n                exp.newargs.shift(e);\n\n                FuncDeclaration f = resolveFuncCall(exp.loc, sc, cd.aggNew, null, tb, exp.newargs);\n                if (!f || f.errors)\n                    return setError();\n\n                checkFunctionAttributes(exp, sc, f);\n                checkAccess(cd, exp.loc, sc, f);\n\n                TypeFunction tf = cast(TypeFunction)f.type;\n                Type rettype;\n                if (functionParameters(exp.loc, sc, tf, null, exp.newargs, f, &rettype, &newprefix))\n                    return setError();\n\n                exp.allocator = f.isNewDeclaration();\n                assert(exp.allocator);\n            }\n            else\n            {\n                if (exp.newargs && exp.newargs.dim)\n                {\n                    exp.error(\"no allocator for `%s`\", cd.toChars());\n                    return setError();\n                }\n            }\n\n            if (cd.ctor)\n            {\n                FuncDeclaration f = resolveFuncCall(exp.loc, sc, cd.ctor, null, tb, exp.arguments, 0);\n                if (!f || f.errors)\n                    return setError();\n\n                checkFunctionAttributes(exp, sc, f);\n                checkAccess(cd, exp.loc, sc, f);\n\n                TypeFunction tf = cast(TypeFunction)f.type;\n                if (!exp.arguments)\n                    exp.arguments = new Expressions();\n                if (functionParameters(exp.loc, sc, tf, exp.type, exp.arguments, f, &exp.type, &exp.argprefix))\n                    return setError();\n\n                exp.member = f.isCtorDeclaration();\n                assert(exp.member);\n            }\n            else\n            {\n                if (nargs)\n                {\n                    exp.error(\"no constructor for `%s`\", cd.toChars());\n                    return setError();\n                }\n            }\n        }\n        else if (tb.ty == Tstruct)\n        {\n            auto sd = (cast(TypeStruct)tb).sym;\n            sd.size(exp.loc);\n            if (sd.sizeok != Sizeok.done)\n                return setError();\n            if (!sd.ctor)\n                sd.ctor = sd.searchCtor();\n            if (sd.noDefaultCtor && !nargs)\n            {\n                exp.error(\"default construction is disabled for type `%s`\", sd.type.toChars());\n                return setError();\n            }\n            // checkDeprecated() is already done in newtype.typeSemantic().\n\n            if (sd.aggNew)\n            {\n                // Prepend the uint size argument to newargs[]\n                Expression e = new IntegerExp(exp.loc, sd.size(exp.loc), Type.tsize_t);\n                if (!exp.newargs)\n                    exp.newargs = new Expressions();\n                exp.newargs.shift(e);\n\n                FuncDeclaration f = resolveFuncCall(exp.loc, sc, sd.aggNew, null, tb, exp.newargs);\n                if (!f || f.errors)\n                    return setError();\n\n                checkFunctionAttributes(exp, sc, f);\n                checkAccess(sd, exp.loc, sc, f);\n\n                TypeFunction tf = cast(TypeFunction)f.type;\n                Type rettype;\n                if (functionParameters(exp.loc, sc, tf, null, exp.newargs, f, &rettype, &newprefix))\n                    return setError();\n\n                exp.allocator = f.isNewDeclaration();\n                assert(exp.allocator);\n            }\n            else\n            {\n                if (exp.newargs && exp.newargs.dim)\n                {\n                    exp.error(\"no allocator for `%s`\", sd.toChars());\n                    return setError();\n                }\n            }\n\n            if (sd.ctor && nargs)\n            {\n                FuncDeclaration f = resolveFuncCall(exp.loc, sc, sd.ctor, null, tb, exp.arguments, 0);\n                if (!f || f.errors)\n                    return setError();\n\n                checkFunctionAttributes(exp, sc, f);\n                checkAccess(sd, exp.loc, sc, f);\n\n                TypeFunction tf = cast(TypeFunction)f.type;\n                if (!exp.arguments)\n                    exp.arguments = new Expressions();\n                if (functionParameters(exp.loc, sc, tf, exp.type, exp.arguments, f, &exp.type, &exp.argprefix))\n                    return setError();\n\n                exp.member = f.isCtorDeclaration();\n                assert(exp.member);\n\n                if (checkFrameAccess(exp.loc, sc, sd, sd.fields.dim))\n                    return setError();\n            }\n            else\n            {\n                if (!exp.arguments)\n                    exp.arguments = new Expressions();\n\n                if (!sd.fit(exp.loc, sc, exp.arguments, tb))\n                    return setError();\n\n                if (!sd.fill(exp.loc, exp.arguments, false))\n                    return setError();\n\n                if (checkFrameAccess(exp.loc, sc, sd, exp.arguments ? exp.arguments.dim : 0))\n                    return setError();\n\n                /* Since a `new` allocation may escape, check each of the arguments for escaping\n                 */\n                if (global.params.vsafe)\n                {\n                    foreach (arg; *exp.arguments)\n                    {\n                        if (arg && checkNewEscape(sc, arg, false))\n                            return setError();\n                    }\n                }\n            }\n\n            exp.type = exp.type.pointerTo();\n        }\n        else if (tb.ty == Tarray && nargs)\n        {\n            Type tn = tb.nextOf().baseElemOf();\n            Dsymbol s = tn.toDsymbol(sc);\n            AggregateDeclaration ad = s ? s.isAggregateDeclaration() : null;\n            if (ad && ad.noDefaultCtor)\n            {\n                exp.error(\"default construction is disabled for type `%s`\", tb.nextOf().toChars());\n                return setError();\n            }\n            for (size_t i = 0; i < nargs; i++)\n            {\n                if (tb.ty != Tarray)\n                {\n                    exp.error(\"too many arguments for array\");\n                    return setError();\n                }\n\n                Expression arg = (*exp.arguments)[i];\n                arg = resolveProperties(sc, arg);\n                arg = arg.implicitCastTo(sc, Type.tsize_t);\n                arg = arg.optimize(WANTvalue);\n                if (arg.op == TOK.int64 && cast(sinteger_t)arg.toInteger() < 0)\n                {\n                    exp.error(\"negative array index `%s`\", arg.toChars());\n                    return setError();\n                }\n                (*exp.arguments)[i] = arg;\n                tb = (cast(TypeDArray)tb).next.toBasetype();\n            }\n        }\n        else if (tb.isscalar())\n        {\n            if (!nargs)\n            {\n            }\n            else if (nargs == 1)\n            {\n                Expression e = (*exp.arguments)[0];\n                e = e.implicitCastTo(sc, tb);\n                (*exp.arguments)[0] = e;\n            }\n            else\n            {\n                exp.error(\"more than one argument for construction of `%s`\", exp.type.toChars());\n                return setError();\n            }\n\n            exp.type = exp.type.pointerTo();\n        }\n        else\n        {\n            exp.error(\"new can only create structs, dynamic arrays or class objects, not `%s`'s\", exp.type.toChars());\n            return setError();\n        }\n\n        //printf(\"NewExp: '%s'\\n\", toChars());\n        //printf(\"NewExp:type '%s'\\n\", type.toChars());\n        semanticTypeInfo(sc, exp.type);\n\n        if (newprefix)\n        {\n            result = Expression.combine(newprefix, exp);\n            return;\n        }\n        result = exp;\n    }\n\n    override void visit(NewAnonClassExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"NewAnonClassExp::semantic() %s\\n\", e.toChars());\n            //printf(\"thisexp = %p\\n\", thisexp);\n            //printf(\"type: %s\\n\", type.toChars());\n        }\n\n        Expression d = new DeclarationExp(e.loc, e.cd);\n        sc = sc.push(); // just create new scope\n        sc.flags &= ~SCOPE.ctfe; // temporary stop CTFE\n        d = d.expressionSemantic(sc);\n        sc = sc.pop();\n\n        if (!e.cd.errors && sc.intypeof && !sc.parent.inNonRoot())\n        {\n            ScopeDsymbol sds = sc.tinst ? cast(ScopeDsymbol)sc.tinst : sc._module;\n            sds.members.push(e.cd);\n        }\n\n        Expression n = new NewExp(e.loc, e.thisexp, e.newargs, e.cd.type, e.arguments);\n\n        Expression c = new CommaExp(e.loc, d, n);\n        result = c.expressionSemantic(sc);\n    }\n\n    override void visit(SymOffExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"SymOffExp::semantic('%s')\\n\", e.toChars());\n        }\n        //var.dsymbolSemantic(sc);\n        if (!e.type)\n            e.type = e.var.type.pointerTo();\n\n        if (auto v = e.var.isVarDeclaration())\n        {\n            if (v.checkNestedReference(sc, e.loc))\n                return setError();\n        }\n        else if (auto f = e.var.isFuncDeclaration())\n        {\n            if (f.checkNestedReference(sc, e.loc))\n                return setError();\n        }\n\n        result = e;\n    }\n\n    override void visit(VarExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"VarExp::semantic(%s)\\n\", e.toChars());\n        }\n        if (auto fd = e.var.isFuncDeclaration())\n        {\n            //printf(\"L%d fd = %s\\n\", __LINE__, f.toChars());\n            if (!fd.functionSemantic())\n                return setError();\n        }\n\n        if (!e.type)\n            e.type = e.var.type;\n        if (e.type && !e.type.deco)\n            e.type = e.type.typeSemantic(e.loc, sc);\n\n        /* Fix for 1161 doesn't work because it causes protection\n         * problems when instantiating imported templates passing private\n         * variables as alias template parameters.\n         */\n        //checkAccess(loc, sc, NULL, var);\n\n        if (auto vd = e.var.isVarDeclaration())\n        {\n            if (vd.checkNestedReference(sc, e.loc))\n                return setError();\n\n            // https://issues.dlang.org/show_bug.cgi?id=12025\n            // If the variable is not actually used in runtime code,\n            // the purity violation error is redundant.\n            //checkPurity(sc, vd);\n        }\n        else if (auto fd = e.var.isFuncDeclaration())\n        {\n            // TODO: If fd isn't yet resolved its overload, the checkNestedReference\n            // call would cause incorrect validation.\n            // Maybe here should be moved in CallExp, or AddrExp for functions.\n            if (fd.checkNestedReference(sc, e.loc))\n                return setError();\n        }\n        else if (auto od = e.var.isOverDeclaration())\n        {\n            e.type = Type.tvoid; // ambiguous type?\n        }\n\n        result = e;\n    }\n\n    override void visit(FuncExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"FuncExp::semantic(%s)\\n\", exp.toChars());\n            if (exp.fd.treq)\n                printf(\"  treq = %s\\n\", exp.fd.treq.toChars());\n        }\n\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        Expression e = exp;\n        uint olderrors;\n\n        sc = sc.push(); // just create new scope\n        sc.flags &= ~SCOPE.ctfe; // temporary stop CTFE\n        sc.protection = Prot(Prot.Kind.public_); // https://issues.dlang.org/show_bug.cgi?id=12506\n\n        /* fd.treq might be incomplete type,\n            * so should not semantic it.\n            * void foo(T)(T delegate(int) dg){}\n            * foo(a=>a); // in IFTI, treq == T delegate(int)\n            */\n        //if (fd.treq)\n        //    fd.treq = fd.treq.dsymbolSemantic(loc, sc);\n\n        exp.genIdent(sc);\n\n        // Set target of return type inference\n        if (exp.fd.treq && !exp.fd.type.nextOf())\n        {\n            TypeFunction tfv = null;\n            if (exp.fd.treq.ty == Tdelegate || (exp.fd.treq.ty == Tpointer && exp.fd.treq.nextOf().ty == Tfunction))\n                tfv = cast(TypeFunction)exp.fd.treq.nextOf();\n            if (tfv)\n            {\n                TypeFunction tfl = cast(TypeFunction)exp.fd.type;\n                tfl.next = tfv.nextOf();\n            }\n        }\n\n        //printf(\"td = %p, treq = %p\\n\", td, fd.treq);\n        if (exp.td)\n        {\n            assert(exp.td.parameters && exp.td.parameters.dim);\n            exp.td.dsymbolSemantic(sc);\n            exp.type = Type.tvoid; // temporary type\n\n            if (exp.fd.treq) // defer type determination\n            {\n                FuncExp fe;\n                if (exp.matchType(exp.fd.treq, sc, &fe) > MATCH.nomatch)\n                    e = fe;\n                else\n                    e = new ErrorExp();\n            }\n            goto Ldone;\n        }\n\n        olderrors = global.errors;\n        exp.fd.dsymbolSemantic(sc);\n        if (olderrors == global.errors)\n        {\n            exp.fd.semantic2(sc);\n            if (olderrors == global.errors)\n                exp.fd.semantic3(sc);\n        }\n        if (olderrors != global.errors)\n        {\n            if (exp.fd.type && exp.fd.type.ty == Tfunction && !exp.fd.type.nextOf())\n                (cast(TypeFunction)exp.fd.type).next = Type.terror;\n            e = new ErrorExp();\n            goto Ldone;\n        }\n\n        // Type is a \"delegate to\" or \"pointer to\" the function literal\n        if ((exp.fd.isNested() && exp.fd.tok == TOK.delegate_) || (exp.tok == TOK.reserved && exp.fd.treq && exp.fd.treq.ty == Tdelegate))\n        {\n            exp.type = new TypeDelegate(exp.fd.type);\n            exp.type = exp.type.typeSemantic(exp.loc, sc);\n\n            exp.fd.tok = TOK.delegate_;\n        }\n        else\n        {\n            exp.type = new TypePointer(exp.fd.type);\n            exp.type = exp.type.typeSemantic(exp.loc, sc);\n            //type = fd.type.pointerTo();\n\n            /* A lambda expression deduced to function pointer might become\n                * to a delegate literal implicitly.\n                *\n                *   auto foo(void function() fp) { return 1; }\n                *   assert(foo({}) == 1);\n                *\n                * So, should keep fd.tok == TOKreserve if fd.treq == NULL.\n                */\n            if (exp.fd.treq && exp.fd.treq.ty == Tpointer)\n            {\n                // change to non-nested\n                exp.fd.tok = TOK.function_;\n                exp.fd.vthis = null;\n            }\n        }\n        exp.fd.tookAddressOf++;\n\n    Ldone:\n        sc = sc.pop();\n        result = e;\n    }\n\n    // used from CallExp::semantic()\n    Expression callExpSemantic(FuncExp exp, Scope* sc, Expressions* arguments)\n    {\n        if ((!exp.type || exp.type == Type.tvoid) && exp.td && arguments && arguments.dim)\n        {\n            for (size_t k = 0; k < arguments.dim; k++)\n            {\n                Expression checkarg = (*arguments)[k];\n                if (checkarg.op == TOK.error)\n                    return checkarg;\n            }\n\n            exp.genIdent(sc);\n\n            assert(exp.td.parameters && exp.td.parameters.dim);\n            exp.td.dsymbolSemantic(sc);\n\n            TypeFunction tfl = cast(TypeFunction)exp.fd.type;\n            size_t dim = Parameter.dim(tfl.parameters);\n            if (arguments.dim < dim)\n            {\n                // Default arguments are always typed, so they don't need inference.\n                Parameter p = Parameter.getNth(tfl.parameters, arguments.dim);\n                if (p.defaultArg)\n                    dim = arguments.dim;\n            }\n\n            if ((!tfl.varargs && arguments.dim == dim) || (tfl.varargs && arguments.dim >= dim))\n            {\n                auto tiargs = new Objects();\n                tiargs.reserve(exp.td.parameters.dim);\n\n                for (size_t i = 0; i < exp.td.parameters.dim; i++)\n                {\n                    TemplateParameter tp = (*exp.td.parameters)[i];\n                    for (size_t u = 0; u < dim; u++)\n                    {\n                        Parameter p = Parameter.getNth(tfl.parameters, u);\n                        if (p.type.ty == Tident && (cast(TypeIdentifier)p.type).ident == tp.ident)\n                        {\n                            Expression e = (*arguments)[u];\n                            tiargs.push(e.type);\n                            u = dim; // break inner loop\n                        }\n                    }\n                }\n\n                auto ti = new TemplateInstance(exp.loc, exp.td, tiargs);\n                return (new ScopeExp(exp.loc, ti)).expressionSemantic(sc);\n            }\n            exp.error(\"cannot infer function literal type\");\n            return new ErrorExp();\n        }\n        return exp.expressionSemantic(sc);\n    }\n\n    override void visit(CallExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"CallExp::semantic() %s\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return; // semantic() already run\n        }\n\n        Type t1;\n        Objects* tiargs = null; // initial list of template arguments\n        Expression ethis = null;\n        Type tthis = null;\n        Expression e1org = exp.e1;\n\n        if (exp.e1.op == TOK.comma)\n        {\n            /* Rewrite (a,b)(args) as (a,(b(args)))\n             */\n            auto ce = cast(CommaExp)exp.e1;\n            exp.e1 = ce.e2;\n            ce.e2 = exp;\n            result = ce.expressionSemantic(sc);\n            return;\n        }\n        if (exp.e1.op == TOK.delegate_)\n        {\n            DelegateExp de = cast(DelegateExp)exp.e1;\n            exp.e1 = new DotVarExp(de.loc, de.e1, de.func, de.hasOverloads);\n            visit(exp);\n            return;\n        }\n        if (exp.e1.op == TOK.function_)\n        {\n            if (arrayExpressionSemantic(exp.arguments, sc) || preFunctionParameters(sc, exp.arguments))\n                return setError();\n\n            // Run e1 semantic even if arguments have any errors\n            FuncExp fe = cast(FuncExp)exp.e1;\n            exp.e1 = callExpSemantic(fe, sc, exp.arguments);\n            if (exp.e1.op == TOK.error)\n            {\n                result = exp.e1;\n                return;\n            }\n        }\n\n        if (Expression ex = resolveUFCS(sc, exp))\n        {\n            result = ex;\n            return;\n        }\n\n        /* This recognizes:\n         *  foo!(tiargs)(funcargs)\n         */\n        if (exp.e1.op == TOK.scope_)\n        {\n            ScopeExp se = cast(ScopeExp)exp.e1;\n            TemplateInstance ti = se.sds.isTemplateInstance();\n            if (ti)\n            {\n                /* Attempt to instantiate ti. If that works, go with it.\n                 * If not, go with partial explicit specialization.\n                 */\n                WithScopeSymbol withsym;\n                if (!ti.findTempDecl(sc, &withsym) || !ti.semanticTiargs(sc))\n                    return setError();\n                if (withsym && withsym.withstate.wthis)\n                {\n                    exp.e1 = new VarExp(exp.e1.loc, withsym.withstate.wthis);\n                    exp.e1 = new DotTemplateInstanceExp(exp.e1.loc, exp.e1, ti);\n                    goto Ldotti;\n                }\n                if (ti.needsTypeInference(sc, 1))\n                {\n                    /* Go with partial explicit specialization\n                     */\n                    tiargs = ti.tiargs;\n                    assert(ti.tempdecl);\n                    if (TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration())\n                        exp.e1 = new TemplateExp(exp.loc, td);\n                    else if (OverDeclaration od = ti.tempdecl.isOverDeclaration())\n                        exp.e1 = new VarExp(exp.loc, od);\n                    else\n                        exp.e1 = new OverExp(exp.loc, ti.tempdecl.isOverloadSet());\n                }\n                else\n                {\n                    Expression e1x = exp.e1.expressionSemantic(sc);\n                    if (e1x.op == TOK.error)\n                    {\n                        result = e1x;\n                        return;\n                    }\n                    exp.e1 = e1x;\n                }\n            }\n        }\n\n        /* This recognizes:\n         *  expr.foo!(tiargs)(funcargs)\n         */\n    Ldotti:\n        if (exp.e1.op == TOK.dotTemplateInstance && !exp.e1.type)\n        {\n            DotTemplateInstanceExp se = cast(DotTemplateInstanceExp)exp.e1;\n            TemplateInstance ti = se.ti;\n            {\n                /* Attempt to instantiate ti. If that works, go with it.\n                 * If not, go with partial explicit specialization.\n                 */\n                if (!se.findTempDecl(sc) || !ti.semanticTiargs(sc))\n                    return setError();\n                if (ti.needsTypeInference(sc, 1))\n                {\n                    /* Go with partial explicit specialization\n                     */\n                    tiargs = ti.tiargs;\n                    assert(ti.tempdecl);\n                    if (TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration())\n                        exp.e1 = new DotTemplateExp(exp.loc, se.e1, td);\n                    else if (OverDeclaration od = ti.tempdecl.isOverDeclaration())\n                    {\n                        exp.e1 = new DotVarExp(exp.loc, se.e1, od, true);\n                    }\n                    else\n                        exp.e1 = new DotExp(exp.loc, se.e1, new OverExp(exp.loc, ti.tempdecl.isOverloadSet()));\n                }\n                else\n                {\n                    Expression e1x = exp.e1.expressionSemantic(sc);\n                    if (e1x.op == TOK.error)\n                    {\n                        result = e1x;\n                        return;\n                    }\n                    exp.e1 = e1x;\n                }\n            }\n        }\n\n    Lagain:\n        //printf(\"Lagain: %s\\n\", toChars());\n        exp.f = null;\n        if (exp.e1.op == TOK.this_ || exp.e1.op == TOK.super_)\n        {\n            // semantic() run later for these\n        }\n        else\n        {\n            if (exp.e1.op == TOK.dotIdentifier)\n            {\n                DotIdExp die = cast(DotIdExp)exp.e1;\n                exp.e1 = die.expressionSemantic(sc);\n                /* Look for e1 having been rewritten to expr.opDispatch!(string)\n                 * We handle such earlier, so go back.\n                 * Note that in the rewrite, we carefully did not run semantic() on e1\n                 */\n                if (exp.e1.op == TOK.dotTemplateInstance && !exp.e1.type)\n                {\n                    goto Ldotti;\n                }\n            }\n            else\n            {\n                __gshared int nest;\n                if (++nest > 500)\n                {\n                    exp.error(\"recursive evaluation of `%s`\", exp.toChars());\n                    --nest;\n                    return setError();\n                }\n                Expression ex = unaSemantic(exp, sc);\n                --nest;\n                if (ex)\n                {\n                    result = ex;\n                    return;\n                }\n            }\n\n            /* Look for e1 being a lazy parameter\n             */\n            if (exp.e1.op == TOK.variable)\n            {\n                VarExp ve = cast(VarExp)exp.e1;\n                if (ve.var.storage_class & STC.lazy_)\n                {\n                    // lazy parameters can be called without violating purity and safety\n                    Type tw = ve.var.type;\n                    Type tc = ve.var.type.substWildTo(MODFlags.const_);\n                    auto tf = new TypeFunction(null, tc, 0, LINK.d, STC.safe | STC.pure_);\n                    (tf = cast(TypeFunction)tf.typeSemantic(exp.loc, sc)).next = tw; // hack for bug7757\n                    auto t = new TypeDelegate(tf);\n                    ve.type = t.typeSemantic(exp.loc, sc);\n                }\n                VarDeclaration v = ve.var.isVarDeclaration();\n                if (v && ve.checkPurity(sc, v))\n                    return setError();\n            }\n\n            if (exp.e1.op == TOK.symbolOffset && (cast(SymOffExp)exp.e1).hasOverloads)\n            {\n                SymOffExp se = cast(SymOffExp)exp.e1;\n                exp.e1 = new VarExp(se.loc, se.var, true);\n                exp.e1 = exp.e1.expressionSemantic(sc);\n            }\n            else if (exp.e1.op == TOK.dot)\n            {\n                DotExp de = cast(DotExp)exp.e1;\n\n                if (de.e2.op == TOK.overloadSet)\n                {\n                    ethis = de.e1;\n                    tthis = de.e1.type;\n                    exp.e1 = de.e2;\n                }\n            }\n            else if (exp.e1.op == TOK.star && exp.e1.type.ty == Tfunction)\n            {\n                // Rewrite (*fp)(arguments) to fp(arguments)\n                exp.e1 = (cast(PtrExp)exp.e1).e1;\n            }\n        }\n\n        t1 = exp.e1.type ? exp.e1.type.toBasetype() : null;\n\n        if (exp.e1.op == TOK.error)\n        {\n            result = exp.e1;\n            return;\n        }\n        if (arrayExpressionSemantic(exp.arguments, sc) || preFunctionParameters(sc, exp.arguments))\n            return setError();\n\n        // Check for call operator overload\n        if (t1)\n        {\n            if (t1.ty == Tstruct)\n            {\n                auto sd = (cast(TypeStruct)t1).sym;\n                sd.size(exp.loc); // Resolve forward references to construct object\n                if (sd.sizeok != Sizeok.done)\n                    return setError();\n                if (!sd.ctor)\n                    sd.ctor = sd.searchCtor();\n\n                // First look for constructor\n                if (exp.e1.op == TOK.type && sd.ctor)\n                {\n                    if (!sd.noDefaultCtor && !(exp.arguments && exp.arguments.dim))\n                        goto Lx;\n\n                    auto sle = new StructLiteralExp(exp.loc, sd, null, exp.e1.type);\n                    if (!sd.fill(exp.loc, sle.elements, true))\n                        return setError();\n                    if (checkFrameAccess(exp.loc, sc, sd, sle.elements.dim))\n                        return setError();\n\n                    // https://issues.dlang.org/show_bug.cgi?id=14556\n                    // Set concrete type to avoid further redundant semantic().\n                    sle.type = exp.e1.type;\n\n                    /* Constructor takes a mutable object, so don't use\n                     * the immutable initializer symbol.\n                     */\n                    sle.useStaticInit = false;\n\n                    Expression e = sle;\n                    if (auto cf = sd.ctor.isCtorDeclaration())\n                    {\n                        e = new DotVarExp(exp.loc, e, cf, true);\n                    }\n                    else if (auto td = sd.ctor.isTemplateDeclaration())\n                    {\n                        e = new DotTemplateExp(exp.loc, e, td);\n                    }\n                    else if (auto os = sd.ctor.isOverloadSet())\n                    {\n                        e = new DotExp(exp.loc, e, new OverExp(exp.loc, os));\n                    }\n                    else\n                        assert(0);\n                    e = new CallExp(exp.loc, e, exp.arguments);\n                    e = e.expressionSemantic(sc);\n                    result = e;\n                    return;\n                }\n                // No constructor, look for overload of opCall\n                if (search_function(sd, Id.call))\n                    goto L1;\n                // overload of opCall, therefore it's a call\n                if (exp.e1.op != TOK.type)\n                {\n                    if (sd.aliasthis && exp.e1.type != exp.att1)\n                    {\n                        if (!exp.att1 && exp.e1.type.checkAliasThisRec())\n                            exp.att1 = exp.e1.type;\n                        exp.e1 = resolveAliasThis(sc, exp.e1);\n                        goto Lagain;\n                    }\n                    exp.error(\"%s `%s` does not overload ()\", sd.kind(), sd.toChars());\n                    return setError();\n                }\n\n                /* It's a struct literal\n                 */\n            Lx:\n                Expression e = new StructLiteralExp(exp.loc, sd, exp.arguments, exp.e1.type);\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n            else if (t1.ty == Tclass)\n            {\n            L1:\n                // Rewrite as e1.call(arguments)\n                Expression e = new DotIdExp(exp.loc, exp.e1, Id.call);\n                e = new CallExp(exp.loc, e, exp.arguments);\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n            else if (exp.e1.op == TOK.type && t1.isscalar())\n            {\n                Expression e;\n\n                // Make sure to use the the enum type itself rather than its\n                // base type\n                // https://issues.dlang.org/show_bug.cgi?id=16346\n                if (exp.e1.type.ty == Tenum)\n                {\n                    t1 = exp.e1.type;\n                }\n\n                if (!exp.arguments || exp.arguments.dim == 0)\n                {\n                    e = t1.defaultInitLiteral(exp.loc);\n                }\n                else if (exp.arguments.dim == 1)\n                {\n                    e = (*exp.arguments)[0];\n                    e = e.implicitCastTo(sc, t1);\n                    e = new CastExp(exp.loc, e, t1);\n                }\n                else\n                {\n                    exp.error(\"more than one argument for construction of `%s`\", t1.toChars());\n                    return setError();\n                }\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n        }\n\n        static FuncDeclaration resolveOverloadSet(Loc loc, Scope* sc,\n            OverloadSet os, Objects* tiargs, Type tthis, Expressions* arguments)\n        {\n            FuncDeclaration f = null;\n            foreach (s; os.a)\n            {\n                if (tiargs && s.isFuncDeclaration())\n                    continue;\n                if (auto f2 = resolveFuncCall(loc, sc, s, tiargs, tthis, arguments, 1))\n                {\n                    if (f2.errors)\n                        return null;\n                    if (f)\n                    {\n                        /* Error if match in more than one overload set,\n                         * even if one is a 'better' match than the other.\n                         */\n                        ScopeDsymbol.multiplyDefined(loc, f, f2);\n                    }\n                    else\n                        f = f2;\n                }\n            }\n            if (!f)\n                .error(loc, \"no overload matches for `%s`\", os.toChars());\n            else if (f.errors)\n                f = null;\n            return f;\n        }\n\n        bool isSuper = false;\n        if (exp.e1.op == TOK.dotVariable && t1.ty == Tfunction || exp.e1.op == TOK.dotTemplateDeclaration)\n        {\n            UnaExp ue = cast(UnaExp)exp.e1;\n\n            Expression ue1 = ue.e1;\n            Expression ue1old = ue1; // need for 'right this' check\n            VarDeclaration v;\n            if (ue1.op == TOK.variable && (v = (cast(VarExp)ue1).var.isVarDeclaration()) !is null && v.needThis())\n            {\n                ue.e1 = new TypeExp(ue1.loc, ue1.type);\n                ue1 = null;\n            }\n\n            DotVarExp dve;\n            DotTemplateExp dte;\n            Dsymbol s;\n            if (exp.e1.op == TOK.dotVariable)\n            {\n                dve = cast(DotVarExp)exp.e1;\n                dte = null;\n                s = dve.var;\n                tiargs = null;\n            }\n            else\n            {\n                dve = null;\n                dte = cast(DotTemplateExp)exp.e1;\n                s = dte.td;\n            }\n\n            // Do overload resolution\n            exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, ue1 ? ue1.type : null, exp.arguments);\n            if (!exp.f || exp.f.errors || exp.f.type.ty == Terror)\n                return setError();\n\n            if (exp.f.interfaceVirtual)\n            {\n                /* Cast 'this' to the type of the interface, and replace f with the interface's equivalent\n                 */\n                auto b = exp.f.interfaceVirtual;\n                auto ad2 = b.sym;\n                ue.e1 = ue.e1.castTo(sc, ad2.type.addMod(ue.e1.type.mod));\n                ue.e1 = ue.e1.expressionSemantic(sc);\n                ue1 = ue.e1;\n                auto vi = exp.f.findVtblIndex(&ad2.vtbl, cast(int)ad2.vtbl.dim);\n                assert(vi >= 0);\n                exp.f = ad2.vtbl[vi].isFuncDeclaration();\n                assert(exp.f);\n            }\n            if (exp.f.needThis())\n            {\n                AggregateDeclaration ad = exp.f.toParent2().isAggregateDeclaration();\n                ue.e1 = getRightThis(exp.loc, sc, ad, ue.e1, exp.f);\n                if (ue.e1.op == TOK.error)\n                {\n                    result = ue.e1;\n                    return;\n                }\n                ethis = ue.e1;\n                tthis = ue.e1.type;\n                if (!(exp.f.type.ty == Tfunction && (cast(TypeFunction)exp.f.type).isscope))\n                {\n                    if (global.params.vsafe && checkParamArgumentEscape(sc, exp.f, Id.This, ethis, false))\n                        return setError();\n                }\n            }\n\n            /* Cannot call public functions from inside invariant\n             * (because then the invariant would have infinite recursion)\n             */\n            if (sc.func && sc.func.isInvariantDeclaration() && ue.e1.op == TOK.this_ && exp.f.addPostInvariant())\n            {\n                exp.error(\"cannot call `public`/`export` function `%s` from invariant\", exp.f.toChars());\n                return setError();\n            }\n\n            checkFunctionAttributes(exp, sc, exp.f);\n            checkAccess(exp.loc, sc, ue.e1, exp.f);\n            if (!exp.f.needThis())\n            {\n                exp.e1 = Expression.combine(ue.e1, new VarExp(exp.loc, exp.f, false));\n            }\n            else\n            {\n                if (ue1old.checkRightThis(sc))\n                    return setError();\n                if (exp.e1.op == TOK.dotVariable)\n                {\n                    dve.var = exp.f;\n                    exp.e1.type = exp.f.type;\n                }\n                else\n                {\n                    exp.e1 = new DotVarExp(exp.loc, dte.e1, exp.f, false);\n                    exp.e1 = exp.e1.expressionSemantic(sc);\n                    if (exp.e1.op == TOK.error)\n                        return setError();\n                    ue = cast(UnaExp)exp.e1;\n                }\n                version (none)\n                {\n                    printf(\"ue.e1 = %s\\n\", ue.e1.toChars());\n                    printf(\"f = %s\\n\", exp.f.toChars());\n                    printf(\"t = %s\\n\", t.toChars());\n                    printf(\"e1 = %s\\n\", exp.e1.toChars());\n                    printf(\"e1.type = %s\\n\", exp.e1.type.toChars());\n                }\n\n                // See if we need to adjust the 'this' pointer\n                AggregateDeclaration ad = exp.f.isThis();\n                ClassDeclaration cd = ue.e1.type.isClassHandle();\n                if (ad && cd && ad.isClassDeclaration())\n                {\n                    if (ue.e1.op == TOK.dotType)\n                    {\n                        ue.e1 = (cast(DotTypeExp)ue.e1).e1;\n                        exp.directcall = true;\n                    }\n                    else if (ue.e1.op == TOK.super_)\n                        exp.directcall = true;\n                    else if ((cd.storage_class & STC.final_) != 0) // https://issues.dlang.org/show_bug.cgi?id=14211\n                        exp.directcall = true;\n\n                    if (ad != cd)\n                    {\n                        ue.e1 = ue.e1.castTo(sc, ad.type.addMod(ue.e1.type.mod));\n                        ue.e1 = ue.e1.expressionSemantic(sc);\n                    }\n                }\n            }\n            // If we've got a pointer to a function then deference it\n            // https://issues.dlang.org/show_bug.cgi?id=16483\n            if (exp.e1.type.ty == Tpointer && exp.e1.type.nextOf().ty == Tfunction)\n            {\n                Expression e = new PtrExp(exp.loc, exp.e1);\n                e.type = exp.e1.type.nextOf();\n                exp.e1 = e;\n            }\n            t1 = exp.e1.type;\n        }\n        else if (exp.e1.op == TOK.super_ || exp.e1.op == TOK.this_)\n        {\n            auto ad = sc.func ? sc.func.isThis() : null;\n            auto cd = ad ? ad.isClassDeclaration() : null;\n\n            isSuper = exp.e1.op == TOK.super_;\n            if (isSuper)\n            {\n                // Base class constructor call\n                if (!cd || !cd.baseClass || !sc.func.isCtorDeclaration())\n                {\n                    exp.error(\"super class constructor call must be in a constructor\");\n                    return setError();\n                }\n                if (!cd.baseClass.ctor)\n                {\n                    exp.error(\"no super class constructor for `%s`\", cd.baseClass.toChars());\n                    return setError();\n                }\n            }\n            else\n            {\n                // `this` call expression must be inside a\n                // constructor\n                if (!ad || !sc.func.isCtorDeclaration())\n                {\n                    exp.error(\"constructor call must be in a constructor\");\n                    return setError();\n                }\n\n                // https://issues.dlang.org/show_bug.cgi?id=18719\n                // If `exp` is a call expression to another constructor\n                // then it means that all struct/class fields will be\n                // initialized after this call.\n                foreach (ref field; sc.ctorflow.fieldinit)\n                {\n                    field.csx |= CSX.this_ctor | CSX.deprecate_18719;\n                }\n            }\n\n            if (!sc.intypeof && !(sc.ctorflow.callSuper & CSX.halt))\n            {\n                if (sc.inLoop || sc.ctorflow.callSuper & CSX.label)\n                    exp.error(\"constructor calls not allowed in loops or after labels\");\n                if (sc.ctorflow.callSuper & (CSX.super_ctor | CSX.this_ctor))\n                    exp.error(\"multiple constructor calls\");\n                if ((sc.ctorflow.callSuper & CSX.return_) && !(sc.ctorflow.callSuper & CSX.any_ctor))\n                    exp.error(\"an earlier `return` statement skips constructor\");\n                sc.ctorflow.callSuper |= CSX.any_ctor | (isSuper ? CSX.super_ctor : CSX.this_ctor);\n            }\n\n            tthis = ad.type.addMod(sc.func.type.mod);\n            auto ctor = isSuper ? cd.baseClass.ctor : ad.ctor;\n            if (auto os = ctor.isOverloadSet())\n                exp.f = resolveOverloadSet(exp.loc, sc, os, null, tthis, exp.arguments);\n            else\n                exp.f = resolveFuncCall(exp.loc, sc, ctor, null, tthis, exp.arguments, 0);\n\n            if (!exp.f || exp.f.errors)\n                return setError();\n\n            checkFunctionAttributes(exp, sc, exp.f);\n            checkAccess(exp.loc, sc, null, exp.f);\n\n            exp.e1 = new DotVarExp(exp.e1.loc, exp.e1, exp.f, false);\n            exp.e1 = exp.e1.expressionSemantic(sc);\n            t1 = exp.e1.type;\n\n            // BUG: this should really be done by checking the static\n            // call graph\n            if (exp.f == sc.func)\n            {\n                exp.error(\"cyclic constructor call\");\n                return setError();\n            }\n        }\n        else if (exp.e1.op == TOK.overloadSet)\n        {\n            auto os = (cast(OverExp)exp.e1).vars;\n            exp.f = resolveOverloadSet(exp.loc, sc, os, tiargs, tthis, exp.arguments);\n            if (!exp.f)\n                return setError();\n            if (ethis)\n                exp.e1 = new DotVarExp(exp.loc, ethis, exp.f, false);\n            else\n                exp.e1 = new VarExp(exp.loc, exp.f, false);\n            goto Lagain;\n        }\n        else if (!t1)\n        {\n            exp.error(\"function expected before `()`, not `%s`\", exp.e1.toChars());\n            return setError();\n        }\n        else if (t1.ty == Terror)\n        {\n            return setError();\n        }\n        else if (t1.ty != Tfunction)\n        {\n            TypeFunction tf;\n            const(char)* p;\n            Dsymbol s;\n            exp.f = null;\n            if (exp.e1.op == TOK.function_)\n            {\n                // function literal that direct called is always inferred.\n                assert((cast(FuncExp)exp.e1).fd);\n                exp.f = (cast(FuncExp)exp.e1).fd;\n                tf = cast(TypeFunction)exp.f.type;\n                p = \"function literal\";\n            }\n            else if (t1.ty == Tdelegate)\n            {\n                TypeDelegate td = cast(TypeDelegate)t1;\n                assert(td.next.ty == Tfunction);\n                tf = cast(TypeFunction)td.next;\n                p = \"delegate\";\n            }\n            else if (t1.ty == Tpointer && (cast(TypePointer)t1).next.ty == Tfunction)\n            {\n                tf = cast(TypeFunction)(cast(TypePointer)t1).next;\n                p = \"function pointer\";\n            }\n            else if (exp.e1.op == TOK.dotVariable && (cast(DotVarExp)exp.e1).var.isOverDeclaration())\n            {\n                DotVarExp dve = cast(DotVarExp)exp.e1;\n                exp.f = resolveFuncCall(exp.loc, sc, dve.var, tiargs, dve.e1.type, exp.arguments, 2);\n                if (!exp.f)\n                    return setError();\n                if (exp.f.needThis())\n                {\n                    dve.var = exp.f;\n                    dve.type = exp.f.type;\n                    dve.hasOverloads = false;\n                    goto Lagain;\n                }\n                exp.e1 = new VarExp(dve.loc, exp.f, false);\n                Expression e = new CommaExp(exp.loc, dve.e1, exp);\n                result = e.expressionSemantic(sc);\n                return;\n            }\n            else if (exp.e1.op == TOK.variable && (cast(VarExp)exp.e1).var.isOverDeclaration())\n            {\n                s = (cast(VarExp)exp.e1).var;\n                goto L2;\n            }\n            else if (exp.e1.op == TOK.template_)\n            {\n                s = (cast(TemplateExp)exp.e1).td;\n            L2:\n                exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.arguments);\n                if (!exp.f || exp.f.errors)\n                    return setError();\n                if (exp.f.needThis())\n                {\n                    if (hasThis(sc))\n                    {\n                        // Supply an implicit 'this', as in\n                        //    this.ident\n                        exp.e1 = new DotVarExp(exp.loc, (new ThisExp(exp.loc)).expressionSemantic(sc), exp.f, false);\n                        goto Lagain;\n                    }\n                    else if (isNeedThisScope(sc, exp.f))\n                    {\n                        exp.error(\"need `this` for `%s` of type `%s`\", exp.f.toChars(), exp.f.type.toChars());\n                        return setError();\n                    }\n                }\n                exp.e1 = new VarExp(exp.e1.loc, exp.f, false);\n                goto Lagain;\n            }\n            else\n            {\n                exp.error(\"function expected before `()`, not `%s` of type `%s`\", exp.e1.toChars(), exp.e1.type.toChars());\n                return setError();\n            }\n\n            const(char)* failMessage;\n            if (!tf.callMatch(null, exp.arguments, 0, &failMessage))\n            {\n                OutBuffer buf;\n                buf.writeByte('(');\n                argExpTypesToCBuffer(&buf, exp.arguments);\n                buf.writeByte(')');\n                if (tthis)\n                    tthis.modToBuffer(&buf);\n\n                //printf(\"tf = %s, args = %s\\n\", tf.deco, (*arguments)[0].type.deco);\n                .error(exp.loc, \"%s `%s%s` is not callable using argument types `%s`\",\n                    p, exp.e1.toChars(), parametersTypeToChars(tf.parameters, tf.varargs), buf.peekString());\n                if (failMessage)\n                    errorSupplemental(exp.loc, failMessage);\n                return setError();\n            }\n            // Purity and safety check should run after testing arguments matching\n            if (exp.f)\n            {\n                exp.checkPurity(sc, exp.f);\n                exp.checkSafety(sc, exp.f);\n                exp.checkNogc(sc, exp.f);\n                if (exp.f.checkNestedReference(sc, exp.loc))\n                    return setError();\n            }\n            else if (sc.func && sc.intypeof != 1 && !(sc.flags & SCOPE.ctfe))\n            {\n                bool err = false;\n                if (!tf.purity && !(sc.flags & SCOPE.debug_) && sc.func.setImpure())\n                {\n                    exp.error(\"`pure` %s `%s` cannot call impure %s `%s`\",\n                        sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());\n                    err = true;\n                }\n                if (!tf.isnogc && sc.func.setGC() && !(sc.flags & SCOPE.debug_) )\n                {\n                    exp.error(\"`@nogc` %s `%s` cannot call non-@nogc %s `%s`\",\n                        sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());\n                    err = true;\n                }\n                if (tf.trust <= TRUST.system && sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n                {\n                    exp.error(\"`@safe` %s `%s` cannot call `@system` %s `%s`\",\n                        sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());\n                    err = true;\n                }\n                if (err)\n                    return setError();\n            }\n\n            if (t1.ty == Tpointer)\n            {\n                Expression e = new PtrExp(exp.loc, exp.e1);\n                e.type = tf;\n                exp.e1 = e;\n            }\n            t1 = tf;\n        }\n        else if (exp.e1.op == TOK.variable)\n        {\n            // Do overload resolution\n            VarExp ve = cast(VarExp)exp.e1;\n\n            exp.f = ve.var.isFuncDeclaration();\n            assert(exp.f);\n            tiargs = null;\n\n            if (exp.f.overnext)\n                exp.f = resolveFuncCall(exp.loc, sc, exp.f, tiargs, null, exp.arguments, 2);\n            else\n            {\n                exp.f = exp.f.toAliasFunc();\n                TypeFunction tf = cast(TypeFunction)exp.f.type;\n                const(char)* failMessage;\n                if (!tf.callMatch(null, exp.arguments, 0, &failMessage))\n                {\n                    OutBuffer buf;\n                    buf.writeByte('(');\n                    argExpTypesToCBuffer(&buf, exp.arguments);\n                    buf.writeByte(')');\n\n                    //printf(\"tf = %s, args = %s\\n\", tf.deco, (*arguments)[0].type.deco);\n                    .error(exp.loc, \"%s `%s%s` is not callable using argument types `%s`\",\n                        exp.f.kind(), exp.f.toPrettyChars(), parametersTypeToChars(tf.parameters, tf.varargs), buf.peekString());\n                    if (failMessage)\n                        errorSupplemental(exp.loc, failMessage);\n                    exp.f = null;\n                }\n            }\n            if (!exp.f || exp.f.errors)\n                return setError();\n\n            if (exp.f.needThis())\n            {\n                // Change the ancestor lambdas to delegate before hasThis(sc) call.\n                if (exp.f.checkNestedReference(sc, exp.loc))\n                    return setError();\n\n                if (hasThis(sc))\n                {\n                    // Supply an implicit 'this', as in\n                    //    this.ident\n                    exp.e1 = new DotVarExp(exp.loc, (new ThisExp(exp.loc)).expressionSemantic(sc), ve.var);\n                    // Note: we cannot use f directly, because further overload resolution\n                    // through the supplied 'this' may cause different result.\n                    goto Lagain;\n                }\n                else if (isNeedThisScope(sc, exp.f))\n                {\n                    exp.error(\"need `this` for `%s` of type `%s`\", exp.f.toChars(), exp.f.type.toChars());\n                    return setError();\n                }\n            }\n\n            checkFunctionAttributes(exp, sc, exp.f);\n            checkAccess(exp.loc, sc, null, exp.f);\n            if (exp.f.checkNestedReference(sc, exp.loc))\n                return setError();\n\n            ethis = null;\n            tthis = null;\n\n            if (ve.hasOverloads)\n            {\n                exp.e1 = new VarExp(ve.loc, exp.f, false);\n                exp.e1.type = exp.f.type;\n            }\n            t1 = exp.f.type;\n        }\n        assert(t1.ty == Tfunction);\n\n        Expression argprefix;\n        if (!exp.arguments)\n            exp.arguments = new Expressions();\n        if (functionParameters(exp.loc, sc, cast(TypeFunction)t1, tthis, exp.arguments, exp.f, &exp.type, &argprefix))\n            return setError();\n\n        if (!exp.type)\n        {\n            exp.e1 = e1org; // https://issues.dlang.org/show_bug.cgi?id=10922\n                        // avoid recursive expression printing\n            exp.error(\"forward reference to inferred return type of function call `%s`\", exp.toChars());\n            return setError();\n        }\n\n        if (exp.f && exp.f.tintro)\n        {\n            Type t = exp.type;\n            int offset = 0;\n            TypeFunction tf = cast(TypeFunction)exp.f.tintro;\n            if (tf.next.isBaseOf(t, &offset) && offset)\n            {\n                exp.type = tf.next;\n                result = Expression.combine(argprefix, exp.castTo(sc, t));\n                return;\n            }\n        }\n\n        // Handle the case of a direct lambda call\n        if (exp.f && exp.f.isFuncLiteralDeclaration() && sc.func && !sc.intypeof)\n        {\n            exp.f.tookAddressOf = 0;\n        }\n\n        result = Expression.combine(argprefix, exp);\n\n        if (isSuper)\n        {\n            auto ad = sc.func ? sc.func.isThis() : null;\n            auto cd = ad ? ad.isClassDeclaration() : null;\n            if (cd && cd.classKind == ClassKind.cpp && exp.f && !exp.f.fbody)\n            {\n                // if super is defined in C++, it sets the vtable pointer to the base class\n                // so we have to restore it, but still return 'this' from super() call:\n                // (auto __vptrTmp = this.__vptr, auto __superTmp = super()), (this.__vptr = __vptrTmp, __superTmp)\n                Loc loc = exp.loc;\n\n                auto vptr = new DotIdExp(loc, new ThisExp(loc), Id.__vptr);\n                auto vptrTmpDecl = copyToTemp(0, \"__vptrTmp\", vptr);\n                auto declareVptrTmp = new DeclarationExp(loc, vptrTmpDecl);\n\n                auto superTmpDecl = copyToTemp(0, \"__superTmp\", result);\n                auto declareSuperTmp = new DeclarationExp(loc, superTmpDecl);\n\n                auto declareTmps = new CommaExp(loc, declareVptrTmp, declareSuperTmp);\n\n                auto restoreVptr = new AssignExp(loc, vptr.syntaxCopy(), new VarExp(loc, vptrTmpDecl));\n\n                Expression e = new CommaExp(loc, declareTmps, new CommaExp(loc, restoreVptr, new VarExp(loc, superTmpDecl)));\n                result = e.expressionSemantic(sc);\n            }\n        }\n    }\n\n    override void visit(DeclarationExp e)\n    {\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n        static if (LOGSEMANTIC)\n        {\n            printf(\"DeclarationExp::semantic() %s\\n\", e.toChars());\n        }\n\n        uint olderrors = global.errors;\n\n        /* This is here to support extern(linkage) declaration,\n         * where the extern(linkage) winds up being an AttribDeclaration\n         * wrapper.\n         */\n        Dsymbol s = e.declaration;\n\n        while (1)\n        {\n            AttribDeclaration ad = s.isAttribDeclaration();\n            if (ad)\n            {\n                if (ad.decl && ad.decl.dim == 1)\n                {\n                    s = (*ad.decl)[0];\n                    continue;\n                }\n            }\n            break;\n        }\n\n        VarDeclaration v = s.isVarDeclaration();\n        if (v)\n        {\n            // Do semantic() on initializer first, so:\n            //      int a = a;\n            // will be illegal.\n            e.declaration.dsymbolSemantic(sc);\n            s.parent = sc.parent;\n        }\n\n        //printf(\"inserting '%s' %p into sc = %p\\n\", s.toChars(), s, sc);\n        // Insert into both local scope and function scope.\n        // Must be unique in both.\n        if (s.ident)\n        {\n            if (!sc.insert(s))\n            {\n                e.error(\"declaration `%s` is already defined\", s.toPrettyChars());\n                return setError();\n            }\n            else if (sc.func)\n            {\n                // https://issues.dlang.org/show_bug.cgi?id=11720\n                // include Dataseg variables\n                if ((s.isFuncDeclaration() ||\n                     s.isAggregateDeclaration() ||\n                     s.isEnumDeclaration() ||\n                     v && v.isDataseg()) && !sc.func.localsymtab.insert(s))\n                {\n                    // https://issues.dlang.org/show_bug.cgi?id=18266\n                    // set parent so that type semantic does not assert\n                    s.parent = sc.parent;\n                    Dsymbol originalSymbol = sc.func.localsymtab.lookup(s.ident);\n                    assert(originalSymbol);\n                    e.error(\"declaration `%s` is already defined in another scope in `%s` at line `%d`\", s.toPrettyChars(), sc.func.toChars(), originalSymbol.loc.linnum);\n                    return setError();\n                }\n                else\n                {\n                    // Disallow shadowing\n                    for (Scope* scx = sc.enclosing; scx && scx.func == sc.func; scx = scx.enclosing)\n                    {\n                        Dsymbol s2;\n                        if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s != s2)\n                        {\n                            // allow STC.local symbols to be shadowed\n                            // TODO: not really an optimal design\n                            auto decl = s2.isDeclaration();\n                            if (!decl || !(decl.storage_class & STC.local))\n                            {\n                                e.error(\"%s `%s` is shadowing %s `%s`\", s.kind(), s.ident.toChars(), s2.kind(), s2.toPrettyChars());\n                                return setError();\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        if (!s.isVarDeclaration())\n        {\n            Scope* sc2 = sc;\n            if (sc2.stc & (STC.pure_ | STC.nothrow_ | STC.nogc))\n                sc2 = sc.push();\n            sc2.stc &= ~(STC.pure_ | STC.nothrow_ | STC.nogc);\n            e.declaration.dsymbolSemantic(sc2);\n            if (sc2 != sc)\n                sc2.pop();\n            s.parent = sc.parent;\n        }\n        if (global.errors == olderrors)\n        {\n            e.declaration.semantic2(sc);\n            if (global.errors == olderrors)\n            {\n                e.declaration.semantic3(sc);\n            }\n        }\n        // todo: error in declaration should be propagated.\n\n        e.type = Type.tvoid;\n        result = e;\n    }\n\n    override void visit(TypeidExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"TypeidExp::semantic() %s\\n\", exp.toChars());\n        }\n        Type ta = isType(exp.obj);\n        Expression ea = isExpression(exp.obj);\n        Dsymbol sa = isDsymbol(exp.obj);\n        //printf(\"ta %p ea %p sa %p\\n\", ta, ea, sa);\n\n        if (ta)\n        {\n            dmd.typesem.resolve(ta, exp.loc, sc, &ea, &ta, &sa, true);\n        }\n\n        if (ea)\n        {\n            if (auto sym = getDsymbol(ea))\n                ea = resolve(exp.loc, sc, sym, false);\n            else\n                ea = ea.expressionSemantic(sc);\n            ea = resolveProperties(sc, ea);\n            ta = ea.type;\n            if (ea.op == TOK.type)\n                ea = null;\n        }\n\n        if (!ta)\n        {\n            //printf(\"ta %p ea %p sa %p\\n\", ta, ea, sa);\n            exp.error(\"no type for `typeid(%s)`\", ea ? ea.toChars() : (sa ? sa.toChars() : \"\"));\n            return setError();\n        }\n\n        if (global.params.vcomplex)\n            ta.checkComplexTransition(exp.loc, sc);\n\n        Expression e;\n        auto tb = ta.toBasetype();\n        if (ea && tb.ty == Tclass)\n        {\n            if (tb.toDsymbol(sc).isClassDeclaration().classKind == ClassKind.cpp)\n            {\n                error(exp.loc, \"Runtime type information is not supported for `extern(C++)` classes\");\n                e = new ErrorExp();\n            }\n            else\n            {\n                /* Get the dynamic type, which is .classinfo\n                */\n                ea = ea.expressionSemantic(sc);\n                e = new TypeidExp(ea.loc, ea);\n                e.type = Type.typeinfoclass.type;\n            }\n        }\n        else if (ta.ty == Terror)\n        {\n            e = new ErrorExp();\n        }\n        else\n        {\n            // Handle this in the glue layer\n            e = new TypeidExp(exp.loc, ta);\n            e.type = getTypeInfoType(exp.loc, ta, sc);\n\n            semanticTypeInfo(sc, ta);\n\n            if (ea)\n            {\n                e = new CommaExp(exp.loc, ea, e); // execute ea\n                e = e.expressionSemantic(sc);\n            }\n        }\n        result = e;\n    }\n\n    override void visit(TraitsExp e)\n    {\n        result = semanticTraits(e, sc);\n    }\n\n    override void visit(HaltExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"HaltExp::semantic()\\n\");\n        }\n        e.type = Type.tvoid;\n        result = e;\n    }\n\n    override void visit(IsExp e)\n    {\n        /* is(targ id tok tspec)\n         * is(targ id :  tok2)\n         * is(targ id == tok2)\n         */\n\n        //printf(\"IsExp::semantic(%s)\\n\", toChars());\n        if (e.id && !(sc.flags & SCOPE.condition))\n        {\n            e.error(\"can only declare type aliases within `static if` conditionals or `static assert`s\");\n            return setError();\n        }\n\n        Type tded = null;\n        Scope* sc2 = sc.copy(); // keep sc.flags\n        sc2.tinst = null;\n        sc2.minst = null;\n        sc2.flags |= SCOPE.fullinst;\n        Type t = e.targ.trySemantic(e.loc, sc2);\n        sc2.pop();\n        if (!t)\n            goto Lno;\n        // errors, so condition is false\n        e.targ = t;\n        if (e.tok2 != TOK.reserved)\n        {\n            switch (e.tok2)\n            {\n            case TOK.struct_:\n                if (e.targ.ty != Tstruct)\n                    goto Lno;\n                if ((cast(TypeStruct)e.targ).sym.isUnionDeclaration())\n                    goto Lno;\n                tded = e.targ;\n                break;\n\n            case TOK.union_:\n                if (e.targ.ty != Tstruct)\n                    goto Lno;\n                if (!(cast(TypeStruct)e.targ).sym.isUnionDeclaration())\n                    goto Lno;\n                tded = e.targ;\n                break;\n\n            case TOK.class_:\n                if (e.targ.ty != Tclass)\n                    goto Lno;\n                if ((cast(TypeClass)e.targ).sym.isInterfaceDeclaration())\n                    goto Lno;\n                tded = e.targ;\n                break;\n\n            case TOK.interface_:\n                if (e.targ.ty != Tclass)\n                    goto Lno;\n                if (!(cast(TypeClass)e.targ).sym.isInterfaceDeclaration())\n                    goto Lno;\n                tded = e.targ;\n                break;\n\n            case TOK.const_:\n                if (!e.targ.isConst())\n                    goto Lno;\n                tded = e.targ;\n                break;\n\n            case TOK.immutable_:\n                if (!e.targ.isImmutable())\n                    goto Lno;\n                tded = e.targ;\n                break;\n\n            case TOK.shared_:\n                if (!e.targ.isShared())\n                    goto Lno;\n                tded = e.targ;\n                break;\n\n            case TOK.inout_:\n                if (!e.targ.isWild())\n                    goto Lno;\n                tded = e.targ;\n                break;\n\n            case TOK.super_:\n                // If class or interface, get the base class and interfaces\n                if (e.targ.ty != Tclass)\n                    goto Lno;\n                else\n                {\n                    ClassDeclaration cd = (cast(TypeClass)e.targ).sym;\n                    auto args = new Parameters();\n                    args.reserve(cd.baseclasses.dim);\n                    if (cd.semanticRun < PASS.semanticdone)\n                        cd.dsymbolSemantic(null);\n                    for (size_t i = 0; i < cd.baseclasses.dim; i++)\n                    {\n                        BaseClass* b = (*cd.baseclasses)[i];\n                        args.push(new Parameter(STC.in_, b.type, null, null, null));\n                    }\n                    tded = new TypeTuple(args);\n                }\n                break;\n\n            case TOK.enum_:\n                if (e.targ.ty != Tenum)\n                    goto Lno;\n                if (e.id)\n                    tded = (cast(TypeEnum)e.targ).sym.getMemtype(e.loc);\n                else\n                    tded = e.targ;\n\n                if (tded.ty == Terror)\n                    return setError();\n                break;\n\n            case TOK.delegate_:\n                if (e.targ.ty != Tdelegate)\n                    goto Lno;\n                tded = (cast(TypeDelegate)e.targ).next; // the underlying function type\n                break;\n\n            case TOK.function_:\n            case TOK.parameters:\n                {\n                    if (e.targ.ty != Tfunction)\n                        goto Lno;\n                    tded = e.targ;\n\n                    /* Generate tuple from function parameter types.\n                     */\n                    assert(tded.ty == Tfunction);\n                    Parameters* params = (cast(TypeFunction)tded).parameters;\n                    size_t dim = Parameter.dim(params);\n                    auto args = new Parameters();\n                    args.reserve(dim);\n                    for (size_t i = 0; i < dim; i++)\n                    {\n                        Parameter arg = Parameter.getNth(params, i);\n                        assert(arg && arg.type);\n                        /* If one of the default arguments was an error,\n                           don't return an invalid tuple\n                         */\n                        if (e.tok2 == TOK.parameters && arg.defaultArg && arg.defaultArg.op == TOK.error)\n                            return setError();\n                        args.push(new Parameter(arg.storageClass, arg.type, (e.tok2 == TOK.parameters) ? arg.ident : null, (e.tok2 == TOK.parameters) ? arg.defaultArg : null, arg.userAttribDecl));\n                    }\n                    tded = new TypeTuple(args);\n                    break;\n                }\n            case TOK.return_:\n                /* Get the 'return type' for the function,\n                 * delegate, or pointer to function.\n                 */\n                if (e.targ.ty == Tfunction)\n                    tded = (cast(TypeFunction)e.targ).next;\n                else if (e.targ.ty == Tdelegate)\n                {\n                    tded = (cast(TypeDelegate)e.targ).next;\n                    tded = (cast(TypeFunction)tded).next;\n                }\n                else if (e.targ.ty == Tpointer && (cast(TypePointer)e.targ).next.ty == Tfunction)\n                {\n                    tded = (cast(TypePointer)e.targ).next;\n                    tded = (cast(TypeFunction)tded).next;\n                }\n                else\n                    goto Lno;\n                break;\n\n            case TOK.argumentTypes:\n                /* Generate a type tuple of the equivalent types used to determine if a\n                 * function argument of this type can be passed in registers.\n                 * The results of this are highly platform dependent, and intended\n                 * primarly for use in implementing va_arg().\n                 */\n                tded = Target.toArgTypes(e.targ);\n                if (!tded)\n                    goto Lno;\n                // not valid for a parameter\n                break;\n\n            case TOK.vector:\n                if (e.targ.ty != Tvector)\n                    goto Lno;\n                tded = (cast(TypeVector)e.targ).basetype;\n                break;\n\n            default:\n                assert(0);\n            }\n\n            // https://issues.dlang.org/show_bug.cgi?id=18753\n            if (tded)\n                goto Lyes;\n            goto Lno;\n        }\n        else if (e.tspec && !e.id && !(e.parameters && e.parameters.dim))\n        {\n            /* Evaluate to true if targ matches tspec\n             * is(targ == tspec)\n             * is(targ : tspec)\n             */\n            e.tspec = e.tspec.typeSemantic(e.loc, sc);\n            //printf(\"targ  = %s, %s\\n\", targ.toChars(), targ.deco);\n            //printf(\"tspec = %s, %s\\n\", tspec.toChars(), tspec.deco);\n\n            if (e.tok == TOK.colon)\n            {\n                if (e.targ.implicitConvTo(e.tspec))\n                    goto Lyes;\n                else\n                    goto Lno;\n            }\n            else /* == */\n            {\n                if (e.targ.equals(e.tspec))\n                    goto Lyes;\n                else\n                    goto Lno;\n            }\n        }\n        else if (e.tspec)\n        {\n            /* Evaluate to true if targ matches tspec.\n             * If true, declare id as an alias for the specialized type.\n             * is(targ == tspec, tpl)\n             * is(targ : tspec, tpl)\n             * is(targ id == tspec)\n             * is(targ id : tspec)\n             * is(targ id == tspec, tpl)\n             * is(targ id : tspec, tpl)\n             */\n            Identifier tid = e.id ? e.id : Identifier.generateId(\"__isexp_id\");\n            e.parameters.insert(0, new TemplateTypeParameter(e.loc, tid, null, null));\n\n            Objects dedtypes = Objects(e.parameters.dim);\n            dedtypes.zero();\n\n            MATCH m = deduceType(e.targ, sc, e.tspec, e.parameters, &dedtypes);\n            //printf(\"targ: %s\\n\", targ.toChars());\n            //printf(\"tspec: %s\\n\", tspec.toChars());\n            if (m <= MATCH.nomatch || (m != MATCH.exact && e.tok == TOK.equal))\n            {\n                goto Lno;\n            }\n            else\n            {\n                tded = cast(Type)dedtypes[0];\n                if (!tded)\n                    tded = e.targ;\n                Objects tiargs = Objects(1);\n                tiargs[0] = e.targ;\n\n                /* Declare trailing parameters\n                 */\n                for (size_t i = 1; i < e.parameters.dim; i++)\n                {\n                    TemplateParameter tp = (*e.parameters)[i];\n                    Declaration s = null;\n\n                    m = tp.matchArg(e.loc, sc, &tiargs, i, e.parameters, &dedtypes, &s);\n                    if (m <= MATCH.nomatch)\n                        goto Lno;\n                    s.dsymbolSemantic(sc);\n                    if (!sc.insert(s))\n                        e.error(\"declaration `%s` is already defined\", s.toChars());\n\n                    unSpeculative(sc, s);\n                }\n                goto Lyes;\n            }\n        }\n        else if (e.id)\n        {\n            /* Declare id as an alias for type targ. Evaluate to true\n             * is(targ id)\n             */\n            tded = e.targ;\n            goto Lyes;\n        }\n\n    Lyes:\n        if (e.id)\n        {\n            Dsymbol s;\n            Tuple tup = isTuple(tded);\n            if (tup)\n                s = new TupleDeclaration(e.loc, e.id, &tup.objects);\n            else\n                s = new AliasDeclaration(e.loc, e.id, tded);\n            s.dsymbolSemantic(sc);\n\n            /* The reason for the !tup is unclear. It fails Phobos unittests if it is not there.\n             * More investigation is needed.\n             */\n            if (!tup && !sc.insert(s))\n                e.error(\"declaration `%s` is already defined\", s.toChars());\n\n            unSpeculative(sc, s);\n        }\n        //printf(\"Lyes\\n\");\n        result = new IntegerExp(e.loc, 1, Type.tbool);\n        return;\n\n    Lno:\n        //printf(\"Lno\\n\");\n        result = new IntegerExp(e.loc, 0, Type.tbool);\n    }\n\n    override void visit(BinAssignExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (exp.e1.op == TOK.arrayLength)\n        {\n            // arr.length op= e2;\n            e = rewriteOpAssign(exp);\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n        if (exp.e1.op == TOK.slice || exp.e1.type.ty == Tarray || exp.e1.type.ty == Tsarray)\n        {\n            if (checkNonAssignmentArrayOp(exp.e1))\n                return setError();\n\n            if (exp.e1.op == TOK.slice)\n                (cast(SliceExp)exp.e1).arrayop = true;\n\n            // T[] op= ...\n            if (exp.e2.implicitConvTo(exp.e1.type.nextOf()))\n            {\n                // T[] op= T\n                exp.e2 = exp.e2.castTo(sc, exp.e1.type.nextOf());\n            }\n            else if (Expression ex = typeCombine(exp, sc))\n            {\n                result = ex;\n                return;\n            }\n            exp.type = exp.e1.type;\n            result = arrayOp(exp, sc);\n            return;\n        }\n\n        exp.e1 = exp.e1.expressionSemantic(sc);\n        exp.e1 = exp.e1.optimize(WANTvalue);\n        exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);\n        exp.type = exp.e1.type;\n\n        if (auto ad = isAggregate(exp.e1.type))\n        {\n            if (const s = search_function(ad, Id.opOpAssign))\n            {\n                error(exp.loc, \"none of the `opOpAssign` overloads of `%s` are callable for `%s` of type `%s`\", ad.toChars(), exp.e1.toChars(), exp.e1.type.toChars());\n                return setError();\n            }\n        }\n        if (exp.e1.checkScalar() || exp.e1.checkReadModifyWrite(exp.op, exp.e2))\n            return setError();\n\n        int arith = (exp.op == TOK.addAssign || exp.op == TOK.minAssign || exp.op == TOK.mulAssign || exp.op == TOK.divAssign || exp.op == TOK.modAssign || exp.op == TOK.powAssign);\n        int bitwise = (exp.op == TOK.andAssign || exp.op == TOK.orAssign || exp.op == TOK.xorAssign);\n        int shift = (exp.op == TOK.leftShiftAssign || exp.op == TOK.rightShiftAssign || exp.op == TOK.unsignedRightShiftAssign);\n\n        if (bitwise && exp.type.toBasetype().ty == Tbool)\n            exp.e2 = exp.e2.implicitCastTo(sc, exp.type);\n        else if (exp.checkNoBool())\n            return setError();\n\n        if ((exp.op == TOK.addAssign || exp.op == TOK.minAssign) && exp.e1.type.toBasetype().ty == Tpointer && exp.e2.type.toBasetype().isintegral())\n        {\n            result = scaleFactor(exp, sc);\n            return;\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        if (arith && exp.checkArithmeticBin())\n            return setError();\n        if ((bitwise || shift) && exp.checkIntegralBin())\n            return setError();\n\n        if (shift)\n        {\n            if (exp.e2.type.toBasetype().ty != Tvector)\n                exp.e2 = exp.e2.castTo(sc, Type.tshiftcnt);\n        }\n\n        if (!Target.isVectorOpSupported(exp.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n\n        if (exp.e1.op == TOK.error || exp.e2.op == TOK.error)\n            return setError();\n\n        e = exp.checkOpAssignTypes(sc);\n        if (e.op == TOK.error)\n        {\n            result = e;\n            return;\n        }\n\n        assert(e.op == TOK.assign || e == exp);\n        result = (cast(BinExp)e).reorderSettingAAElem(sc);\n    }\n\n    private Expression compileIt(CompileExp exp)\n    {\n        OutBuffer buf;\n        if (exp.exps)\n        {\n            foreach (ex; *exp.exps)\n            {\n                sc = sc.startCTFE();\n                auto e = ex.expressionSemantic(sc);\n                e = resolveProperties(sc, e);\n                sc = sc.endCTFE();\n\n                // allowed to contain types as well as expressions\n                e = ctfeInterpretForPragmaMsg(e);\n                if (e.op == TOK.error)\n                {\n                    //errorSupplemental(exp.loc, \"while evaluating `mixin(%s)`\", ex.toChars());\n                    return null;\n                }\n                StringExp se = e.toStringExp();\n                if (se)\n                {\n                    se = se.toUTF8(sc);\n                    buf.printf(\"%.*s\", cast(int)se.len, se.string);\n                }\n                else\n                    buf.printf(\"%s\", e.toChars());\n            }\n        }\n\n        uint errors = global.errors;\n        const len = buf.offset;\n        const str = buf.extractString()[0 .. len];\n        scope p = new Parser!ASTCodegen(exp.loc, sc._module, str, false);\n        p.nextToken();\n        //printf(\"p.loc.linnum = %d\\n\", p.loc.linnum);\n\n        Expression e = p.parseExpression();\n        if (p.errors)\n        {\n            assert(global.errors != errors); // should have caught all these cases\n            return null;\n        }\n        if (p.token.value != TOK.endOfFile)\n        {\n            exp.error(\"incomplete mixin expression `%s`\", str.ptr);\n            return null;\n        }\n        return e;\n    }\n\n    override void visit(CompileExp exp)\n    {\n        /* https://dlang.org/spec/expression.html#mixin_expressions\n         */\n\n        static if (LOGSEMANTIC)\n        {\n            printf(\"CompileExp::semantic('%s')\\n\", exp.toChars());\n        }\n\n        auto e = compileIt(exp);\n        if (!e)\n            return setError();\n        result = e.expressionSemantic(sc);\n    }\n\n    override void visit(ImportExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"ImportExp::semantic('%s')\\n\", e.toChars());\n        }\n\n        auto se = semanticString(sc, e.e1, \"file name argument\");\n        if (!se)\n            return setError();\n        se = se.toUTF8(sc);\n\n        auto namez = se.toStringz().ptr;\n        if (!global.params.fileImppath)\n        {\n            e.error(\"need `-J` switch to import text file `%s`\", namez);\n            return setError();\n        }\n\n        /* Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory\n         * ('Path Traversal') attacks.\n         * http://cwe.mitre.org/data/definitions/22.html\n         */\n\n        auto name = FileName.safeSearchPath(global.filePath, namez);\n        if (!name)\n        {\n            e.error(\"file `%s` cannot be found or not in a path specified with `-J`\", se.toChars());\n            return setError();\n        }\n\n        sc._module.contentImportedFiles.push(name);\n        if (global.params.verbose)\n            message(\"file      %.*s\\t(%s)\", cast(int)se.len, se.string, name);\n        if (global.params.moduleDeps !is null)\n        {\n            OutBuffer* ob = global.params.moduleDeps;\n            Module imod = sc.instantiatingModule();\n\n            if (!global.params.moduleDepsFile)\n                ob.writestring(\"depsFile \");\n            ob.writestring(imod.toPrettyChars());\n            ob.writestring(\" (\");\n            escapePath(ob, imod.srcfile.toChars());\n            ob.writestring(\") : \");\n            if (global.params.moduleDepsFile)\n                ob.writestring(\"string : \");\n            ob.write(se.string, se.len);\n            ob.writestring(\" (\");\n            escapePath(ob, name);\n            ob.writestring(\")\");\n            ob.writenl();\n        }\n\n        {\n            auto f = File(name);\n            if (f.read())\n            {\n                e.error(\"cannot read file `%s`\", f.toChars());\n                return setError();\n            }\n            else\n            {\n                f._ref = 1;\n                se = new StringExp(e.loc, f.buffer, f.len);\n            }\n        }\n        result = se.expressionSemantic(sc);\n    }\n\n    override void visit(AssertExp exp)\n    {\n        // https://dlang.org/spec/expression.html#assert_expressions\n        static if (LOGSEMANTIC)\n        {\n            printf(\"AssertExp::semantic('%s')\\n\", exp.toChars());\n        }\n\n        if (Expression ex = unaSemantic(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        exp.e1 = resolveProperties(sc, exp.e1);\n        // BUG: see if we can do compile time elimination of the Assert\n        exp.e1 = exp.e1.optimize(WANTvalue);\n        exp.e1 = exp.e1.toBoolean(sc);\n\n        if (exp.msg)\n        {\n            exp.msg = exp.msg.expressionSemantic(sc);\n            exp.msg = resolveProperties(sc, exp.msg);\n            exp.msg = exp.msg.implicitCastTo(sc, Type.tchar.constOf().arrayOf());\n            exp.msg = exp.msg.optimize(WANTvalue);\n        }\n\n        if (exp.e1.op == TOK.error)\n        {\n            result = exp.e1;\n            return;\n        }\n        if (exp.msg && exp.msg.op == TOK.error)\n        {\n            result = exp.msg;\n            return;\n        }\n\n        auto f1 = checkNonAssignmentArrayOp(exp.e1);\n        auto f2 = exp.msg && checkNonAssignmentArrayOp(exp.msg);\n        if (f1 || f2)\n            return setError();\n\n        if (exp.e1.isBool(false))\n        {\n            /* This is an `assert(0)` which means halt program execution\n             */\n            FuncDeclaration fd = sc.parent.isFuncDeclaration();\n            if (fd)\n                fd.hasReturnExp |= 4;\n            sc.ctorflow.orCSX(CSX.halt);\n\n            if (global.params.useAssert == CHECKENABLE.off)\n            {\n                Expression e = new HaltExp(exp.loc);\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n        }\n        exp.type = Type.tvoid;\n        result = exp;\n    }\n\n    override void visit(DotIdExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"DotIdExp::semantic(this = %p, '%s')\\n\", exp, exp.toChars());\n            //printf(\"e1.op = %d, '%s'\\n\", e1.op, Token::toChars(e1.op));\n        }\n        Expression e = exp.semanticY(sc, 1);\n        if (e && isDotOpDispatch(e))\n        {\n            uint errors = global.startGagging();\n            e = resolvePropertiesX(sc, e);\n            if (global.endGagging(errors))\n                e = null; /* fall down to UFCS */\n            else\n            {\n                result = e;\n                return;\n            }\n        }\n        if (!e) // if failed to find the property\n        {\n            /* If ident is not a valid property, rewrite:\n             *   e1.ident\n             * as:\n             *   .ident(e1)\n             */\n            e = resolveUFCSProperties(sc, exp);\n        }\n        result = e;\n    }\n\n    override void visit(DotTemplateExp e)\n    {\n        if (Expression ex = unaSemantic(e, sc))\n        {\n            result = ex;\n            return;\n        }\n        result = e;\n    }\n\n    override void visit(DotVarExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"DotVarExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        exp.var = exp.var.toAlias().isDeclaration();\n\n        exp.e1 = exp.e1.expressionSemantic(sc);\n\n        if (auto tup = exp.var.isTupleDeclaration())\n        {\n            /* Replace:\n             *  e1.tuple(a, b, c)\n             * with:\n             *  tuple(e1.a, e1.b, e1.c)\n             */\n            Expression e0;\n            Expression ev = sc.func ? extractSideEffect(sc, \"__tup\", e0, exp.e1) : exp.e1;\n\n            auto exps = new Expressions();\n            exps.reserve(tup.objects.dim);\n            for (size_t i = 0; i < tup.objects.dim; i++)\n            {\n                RootObject o = (*tup.objects)[i];\n                Expression e;\n                if (o.dyncast() == DYNCAST.expression)\n                {\n                    e = cast(Expression)o;\n                    if (e.op == TOK.dSymbol)\n                    {\n                        Dsymbol s = (cast(DsymbolExp)e).s;\n                        e = new DotVarExp(exp.loc, ev, s.isDeclaration());\n                    }\n                }\n                else if (o.dyncast() == DYNCAST.dsymbol)\n                {\n                    e = new DsymbolExp(exp.loc, cast(Dsymbol)o);\n                }\n                else if (o.dyncast() == DYNCAST.type)\n                {\n                    e = new TypeExp(exp.loc, cast(Type)o);\n                }\n                else\n                {\n                    exp.error(\"`%s` is not an expression\", o.toChars());\n                    return setError();\n                }\n                exps.push(e);\n            }\n\n            Expression e = new TupleExp(exp.loc, e0, exps);\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n\n        exp.e1 = exp.e1.addDtorHook(sc);\n\n        Type t1 = exp.e1.type;\n\n        if (FuncDeclaration fd = exp.var.isFuncDeclaration())\n        {\n            // for functions, do checks after overload resolution\n            if (!fd.functionSemantic())\n                return setError();\n\n            /* https://issues.dlang.org/show_bug.cgi?id=13843\n             * If fd obviously has no overloads, we should\n             * normalize AST, and it will give a chance to wrap fd with FuncExp.\n             */\n            if (fd.isNested() || fd.isFuncLiteralDeclaration())\n            {\n                // (e1, fd)\n                auto e = resolve(exp.loc, sc, fd, false);\n                result = Expression.combine(exp.e1, e);\n                return;\n            }\n\n            exp.type = fd.type;\n            assert(exp.type);\n        }\n        else if (OverDeclaration od = exp.var.isOverDeclaration())\n        {\n            exp.type = Type.tvoid; // ambiguous type?\n        }\n        else\n        {\n            exp.type = exp.var.type;\n            if (!exp.type && global.errors) // var is goofed up, just return error.\n                return setError();\n            assert(exp.type);\n\n            if (t1.ty == Tpointer)\n                t1 = t1.nextOf();\n\n            exp.type = exp.type.addMod(t1.mod);\n\n            Dsymbol vparent = exp.var.toParent();\n            AggregateDeclaration ad = vparent ? vparent.isAggregateDeclaration() : null;\n            if (Expression e1x = getRightThis(exp.loc, sc, ad, exp.e1, exp.var, 1))\n                exp.e1 = e1x;\n            else\n            {\n                /* Later checkRightThis will report correct error for invalid field variable access.\n                 */\n                Expression e = new VarExp(exp.loc, exp.var);\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n            checkAccess(exp.loc, sc, exp.e1, exp.var);\n\n            VarDeclaration v = exp.var.isVarDeclaration();\n            if (v && (v.isDataseg() || (v.storage_class & STC.manifest)))\n            {\n                Expression e = expandVar(WANTvalue, v);\n                if (e)\n                {\n                    result = e;\n                    return;\n                }\n            }\n\n            if (v && v.isDataseg()) // fix https://issues.dlang.org/show_bug.cgi?id=8238\n            {\n                // (e1, v)\n                checkAccess(exp.loc, sc, exp.e1, v);\n                Expression e = new VarExp(exp.loc, v);\n                e = new CommaExp(exp.loc, exp.e1, e);\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n        }\n        //printf(\"-DotVarExp::semantic('%s')\\n\", toChars());\n        result = exp;\n    }\n\n    override void visit(DotTemplateInstanceExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"DotTemplateInstanceExp::semantic('%s')\\n\", exp.toChars());\n        }\n        // Indicate we need to resolve by UFCS.\n        Expression e = exp.semanticY(sc, 1);\n        if (!e)\n            e = resolveUFCSProperties(sc, exp);\n        result = e;\n    }\n\n    override void visit(DelegateExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"DelegateExp::semantic('%s')\\n\", e.toChars());\n        }\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n\n        e.e1 = e.e1.expressionSemantic(sc);\n\n        e.type = new TypeDelegate(e.func.type);\n        e.type = e.type.typeSemantic(e.loc, sc);\n\n        FuncDeclaration f = e.func.toAliasFunc();\n        AggregateDeclaration ad = f.toParent().isAggregateDeclaration();\n        if (f.needThis())\n            e.e1 = getRightThis(e.loc, sc, ad, e.e1, f);\n\n        /* A delegate takes the address of e.e1 in order to set the .ptr field\n         * https://issues.dlang.org/show_bug.cgi?id=18575\n         */\n        if (global.params.vsafe && e.e1.type.toBasetype().ty == Tstruct)\n        {\n            if (auto v = expToVariable(e.e1))\n            {\n                if (!checkAddressVar(sc, e, v))\n                    return setError();\n            }\n        }\n\n        if (f.type.ty == Tfunction)\n        {\n            TypeFunction tf = cast(TypeFunction)f.type;\n            if (!MODmethodConv(e.e1.type.mod, f.type.mod))\n            {\n                OutBuffer thisBuf, funcBuf;\n                MODMatchToBuffer(&thisBuf, e.e1.type.mod, tf.mod);\n                MODMatchToBuffer(&funcBuf, tf.mod, e.e1.type.mod);\n                e.error(\"%smethod `%s` is not callable using a %s`%s`\",\n                    funcBuf.peekString(), f.toPrettyChars(), thisBuf.peekString(), e.e1.toChars());\n                return setError();\n            }\n        }\n        if (ad && ad.isClassDeclaration() && ad.type != e.e1.type)\n        {\n            // A downcast is required for interfaces\n            // https://issues.dlang.org/show_bug.cgi?id=3706\n            e.e1 = new CastExp(e.loc, e.e1, ad.type);\n            e.e1 = e.e1.expressionSemantic(sc);\n        }\n        result = e;\n    }\n\n    override void visit(DotTypeExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"DotTypeExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (auto e = unaSemantic(exp, sc))\n        {\n            result = e;\n            return;\n        }\n\n        exp.type = exp.sym.getType().addMod(exp.e1.type.mod);\n        result = exp;\n    }\n\n    override void visit(AddrExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"AddrExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = unaSemantic(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        int wasCond = exp.e1.op == TOK.question;\n\n        if (exp.e1.op == TOK.dotTemplateInstance)\n        {\n            DotTemplateInstanceExp dti = cast(DotTemplateInstanceExp)exp.e1;\n            TemplateInstance ti = dti.ti;\n            {\n                //assert(ti.needsTypeInference(sc));\n                ti.dsymbolSemantic(sc);\n                if (!ti.inst || ti.errors) // if template failed to expand\n                    return setError();\n\n                Dsymbol s = ti.toAlias();\n                FuncDeclaration f = s.isFuncDeclaration();\n                if (f)\n                {\n                    exp.e1 = new DotVarExp(exp.e1.loc, dti.e1, f);\n                    exp.e1 = exp.e1.expressionSemantic(sc);\n                }\n            }\n        }\n        else if (exp.e1.op == TOK.scope_)\n        {\n            TemplateInstance ti = (cast(ScopeExp)exp.e1).sds.isTemplateInstance();\n            if (ti)\n            {\n                //assert(ti.needsTypeInference(sc));\n                ti.dsymbolSemantic(sc);\n                if (!ti.inst || ti.errors) // if template failed to expand\n                    return setError();\n\n                Dsymbol s = ti.toAlias();\n                FuncDeclaration f = s.isFuncDeclaration();\n                if (f)\n                {\n                    exp.e1 = new VarExp(exp.e1.loc, f);\n                    exp.e1 = exp.e1.expressionSemantic(sc);\n                }\n            }\n        }\n        exp.e1 = exp.e1.toLvalue(sc, null);\n        if (exp.e1.op == TOK.error)\n        {\n            result = exp.e1;\n            return;\n        }\n        if (checkNonAssignmentArrayOp(exp.e1))\n            return setError();\n\n        if (!exp.e1.type)\n        {\n            exp.error(\"cannot take address of `%s`\", exp.e1.toChars());\n            return setError();\n        }\n\n        bool hasOverloads;\n        if (auto f = isFuncAddress(exp, &hasOverloads))\n        {\n            if (!hasOverloads && f.checkForwardRef(exp.loc))\n                return setError();\n        }\n        else if (!exp.e1.type.deco)\n        {\n            if (exp.e1.op == TOK.variable)\n            {\n                VarExp ve = cast(VarExp)exp.e1;\n                Declaration d = ve.var;\n                exp.error(\"forward reference to %s `%s`\", d.kind(), d.toChars());\n            }\n            else\n                exp.error(\"forward reference to `%s`\", exp.e1.toChars());\n            return setError();\n        }\n\n        exp.type = exp.e1.type.pointerTo();\n\n        // See if this should really be a delegate\n        if (exp.e1.op == TOK.dotVariable)\n        {\n            DotVarExp dve = cast(DotVarExp)exp.e1;\n            FuncDeclaration f = dve.var.isFuncDeclaration();\n            if (f)\n            {\n                f = f.toAliasFunc(); // FIXME, should see overloads\n                                     // https://issues.dlang.org/show_bug.cgi?id=1983\n                if (!dve.hasOverloads)\n                    f.tookAddressOf++;\n\n                Expression e;\n                if (f.needThis())\n                    e = new DelegateExp(exp.loc, dve.e1, f, dve.hasOverloads);\n                else // It is a function pointer. Convert &v.f() --> (v, &V.f())\n                    e = new CommaExp(exp.loc, dve.e1, new AddrExp(exp.loc, new VarExp(exp.loc, f, dve.hasOverloads)));\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n\n            // Look for misaligned pointer in @safe mode\n            if (checkUnsafeAccess(sc, dve, !exp.type.isMutable(), true))\n                return setError();\n\n            if (global.params.vsafe)\n            {\n                if (VarDeclaration v = expToVariable(dve.e1))\n                {\n                    if (!checkAddressVar(sc, exp, v))\n                        return setError();\n                }\n            }\n        }\n        else if (exp.e1.op == TOK.variable)\n        {\n            VarExp ve = cast(VarExp)exp.e1;\n            VarDeclaration v = ve.var.isVarDeclaration();\n            if (v)\n            {\n                if (!checkAddressVar(sc, exp, v))\n                    return setError();\n\n                ve.checkPurity(sc, v);\n            }\n            FuncDeclaration f = ve.var.isFuncDeclaration();\n            if (f)\n            {\n                /* Because nested functions cannot be overloaded,\n                 * mark here that we took its address because castTo()\n                 * may not be called with an exact match.\n                 */\n                if (!ve.hasOverloads || f.isNested())\n                    f.tookAddressOf++;\n                if (f.isNested())\n                {\n                    if (f.isFuncLiteralDeclaration())\n                    {\n                        if (!f.FuncDeclaration.isNested())\n                        {\n                            /* Supply a 'null' for a this pointer if no this is available\n                             */\n                            Expression e = new DelegateExp(exp.loc, new NullExp(exp.loc, Type.tnull), f, ve.hasOverloads);\n                            e = e.expressionSemantic(sc);\n                            result = e;\n                            return;\n                        }\n                    }\n                    Expression e = new DelegateExp(exp.loc, exp.e1, f, ve.hasOverloads);\n                    e = e.expressionSemantic(sc);\n                    result = e;\n                    return;\n                }\n                if (f.needThis())\n                {\n                    if (hasThis(sc))\n                    {\n                        /* Should probably supply 'this' after overload resolution,\n                         * not before.\n                         */\n                        Expression ethis = new ThisExp(exp.loc);\n                        Expression e = new DelegateExp(exp.loc, ethis, f, ve.hasOverloads);\n                        e = e.expressionSemantic(sc);\n                        result = e;\n                        return;\n                    }\n                    if (sc.func && !sc.intypeof)\n                    {\n                        if (sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n                        {\n                            exp.error(\"`this` reference necessary to take address of member `%s` in `@safe` function `%s`\", f.toChars(), sc.func.toChars());\n                        }\n                    }\n                }\n            }\n        }\n        else if ((exp.e1.op == TOK.this_ || exp.e1.op == TOK.super_) && global.params.vsafe)\n        {\n            if (VarDeclaration v = expToVariable(exp.e1))\n            {\n                if (!checkAddressVar(sc, exp, v))\n                    return setError();\n            }\n        }\n        else if (exp.e1.op == TOK.call)\n        {\n            CallExp ce = cast(CallExp)exp.e1;\n            if (ce.e1.type.ty == Tfunction)\n            {\n                TypeFunction tf = cast(TypeFunction)ce.e1.type;\n                if (tf.isref && sc.func && !sc.intypeof && sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n                {\n                    exp.error(\"cannot take address of `ref return` of `%s()` in `@safe` function `%s`\",\n                        ce.e1.toChars(), sc.func.toChars());\n                }\n            }\n        }\n        else if (exp.e1.op == TOK.index)\n        {\n            /* For:\n             *   int[3] a;\n             *   &a[i]\n             * check 'a' the same as for a regular variable\n             */\n            if (VarDeclaration v = expToVariable(exp.e1))\n            {\n                if (global.params.vsafe && !checkAddressVar(sc, exp, v))\n                    return setError();\n\n                exp.e1.checkPurity(sc, v);\n            }\n        }\n        else if (wasCond)\n        {\n            /* a ? b : c was transformed to *(a ? &b : &c), but we still\n             * need to do safety checks\n             */\n            assert(exp.e1.op == TOK.star);\n            PtrExp pe = cast(PtrExp)exp.e1;\n            assert(pe.e1.op == TOK.question);\n            CondExp ce = cast(CondExp)pe.e1;\n            assert(ce.e1.op == TOK.address);\n            assert(ce.e2.op == TOK.address);\n\n            // Re-run semantic on the address expressions only\n            ce.e1.type = null;\n            ce.e1 = ce.e1.expressionSemantic(sc);\n            ce.e2.type = null;\n            ce.e2 = ce.e2.expressionSemantic(sc);\n        }\n        result = exp.optimize(WANTvalue);\n    }\n\n    override void visit(PtrExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"PtrExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        Type tb = exp.e1.type.toBasetype();\n        switch (tb.ty)\n        {\n        case Tpointer:\n            exp.type = (cast(TypePointer)tb).next;\n            break;\n\n        case Tsarray:\n        case Tarray:\n            if (isNonAssignmentArrayOp(exp.e1))\n                goto default;\n            exp.error(\"using `*` on an array is no longer supported; use `*(%s).ptr` instead\", exp.e1.toChars());\n            exp.type = (cast(TypeArray)tb).next;\n            exp.e1 = exp.e1.castTo(sc, exp.type.pointerTo());\n            break;\n\n        case Terror:\n            return setError();\n\n        default:\n            exp.error(\"can only `*` a pointer, not a `%s`\", exp.e1.type.toChars());\n            goto case Terror;\n        }\n\n        if (exp.checkValue())\n            return setError();\n\n        result = exp;\n    }\n\n    override void visit(NegExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"NegExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        fix16997(sc, exp);\n        exp.type = exp.e1.type;\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tarray || tb.ty == Tsarray)\n        {\n            if (!isArrayOpValid(exp.e1))\n            {\n                result = arrayOpInvalidError(exp);\n                return;\n            }\n            result = exp;\n            return;\n        }\n        if (!Target.isVectorOpSupported(tb, exp.op))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        if (exp.e1.checkNoBool())\n            return setError();\n        if (exp.e1.checkArithmetic())\n            return setError();\n\n        result = exp;\n    }\n\n    override void visit(UAddExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"UAddExp::semantic('%s')\\n\", exp.toChars());\n        }\n        assert(!exp.type);\n\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        fix16997(sc, exp);\n        if (!Target.isVectorOpSupported(exp.e1.type.toBasetype(), exp.op))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        if (exp.e1.checkNoBool())\n            return setError();\n        if (exp.e1.checkArithmetic())\n            return setError();\n\n        result = exp.e1;\n    }\n\n    override void visit(ComExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        fix16997(sc, exp);\n        exp.type = exp.e1.type;\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tarray || tb.ty == Tsarray)\n        {\n            if (!isArrayOpValid(exp.e1))\n            {\n                result = arrayOpInvalidError(exp);\n                return;\n            }\n            result = exp;\n            return;\n        }\n        if (!Target.isVectorOpSupported(tb, exp.op))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        if (exp.e1.checkNoBool())\n            return setError();\n        if (exp.e1.checkIntegral())\n            return setError();\n\n        result = exp;\n    }\n\n    override void visit(NotExp e)\n    {\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n\n        e.setNoderefOperand();\n\n        // Note there is no operator overload\n        if (Expression ex = unaSemantic(e, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684\n        if (e.e1.op == TOK.type)\n            e.e1 = resolveAliasThis(sc, e.e1);\n\n        e.e1 = resolveProperties(sc, e.e1);\n        e.e1 = e.e1.toBoolean(sc);\n        if (e.e1.type == Type.terror)\n        {\n            result = e.e1;\n            return;\n        }\n\n        if (!Target.isVectorOpSupported(e.e1.type.toBasetype(), e.op))\n        {\n            result = e.incompatibleTypes();\n        }\n        // https://issues.dlang.org/show_bug.cgi?id=13910\n        // Today NotExp can take an array as its operand.\n        if (checkNonAssignmentArrayOp(e.e1))\n            return setError();\n\n        e.type = Type.tbool;\n        result = e;\n    }\n\n    override void visit(DeleteExp exp)\n    {\n        if (!sc.isDeprecated)\n        {\n            // @@@DEPRECATED_2019-02@@@\n            // 1. Deprecation for 1 year\n            // 2. Error for 1 year\n            // 3. Removal of keyword, \"delete\" can be used for other identities\n            if (!exp.isRAII)\n                deprecation(exp.loc, \"The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\");\n        }\n\n        if (Expression ex = unaSemantic(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        exp.e1 = resolveProperties(sc, exp.e1);\n        exp.e1 = exp.e1.modifiableLvalue(sc, null);\n        if (exp.e1.op == TOK.error)\n        {\n            result = exp.e1;\n            return;\n        }\n        exp.type = Type.tvoid;\n\n        AggregateDeclaration ad = null;\n        Type tb = exp.e1.type.toBasetype();\n        switch (tb.ty)\n        {\n        case Tclass:\n            {\n                auto cd = (cast(TypeClass)tb).sym;\n                if (cd.isCOMinterface())\n                {\n                    /* Because COM classes are deleted by IUnknown.Release()\n                     */\n                    exp.error(\"cannot `delete` instance of COM interface `%s`\", cd.toChars());\n                    return setError();\n                }\n                ad = cd;\n                break;\n            }\n        case Tpointer:\n            tb = (cast(TypePointer)tb).next.toBasetype();\n            if (tb.ty == Tstruct)\n            {\n                ad = (cast(TypeStruct)tb).sym;\n                auto f = ad.aggDelete;\n                auto fd = ad.dtor;\n                if (!f)\n                {\n                    semanticTypeInfo(sc, tb);\n                    break;\n                }\n\n                /* Construct:\n                 *      ea = copy e1 to a tmp to do side effects only once\n                 *      eb = call destructor\n                 *      ec = call deallocator\n                 */\n                Expression ea = null;\n                Expression eb = null;\n                Expression ec = null;\n                VarDeclaration v = null;\n                if (fd && f)\n                {\n                    v = copyToTemp(0, \"__tmpea\", exp.e1);\n                    v.dsymbolSemantic(sc);\n                    ea = new DeclarationExp(exp.loc, v);\n                    ea.type = v.type;\n                }\n                if (fd)\n                {\n                    Expression e = ea ? new VarExp(exp.loc, v) : exp.e1;\n                    e = new DotVarExp(Loc.initial, e, fd, false);\n                    eb = new CallExp(exp.loc, e);\n                    eb = eb.expressionSemantic(sc);\n                }\n                if (f)\n                {\n                    Type tpv = Type.tvoid.pointerTo();\n                    Expression e = ea ? new VarExp(exp.loc, v) : exp.e1.castTo(sc, tpv);\n                    e = new CallExp(exp.loc, new VarExp(exp.loc, f, false), e);\n                    ec = e.expressionSemantic(sc);\n                }\n                ea = Expression.combine(ea, eb, ec);\n                assert(ea);\n                result = ea;\n                return;\n            }\n            break;\n\n        case Tarray:\n            {\n                Type tv = tb.nextOf().baseElemOf();\n                if (tv.ty == Tstruct)\n                {\n                    ad = (cast(TypeStruct)tv).sym;\n                    if (ad.dtor)\n                        semanticTypeInfo(sc, ad.type);\n                }\n                break;\n            }\n        default:\n            exp.error(\"cannot delete type `%s`\", exp.e1.type.toChars());\n            return setError();\n        }\n\n        bool err = false;\n        if (ad)\n        {\n            if (ad.dtor)\n            {\n                err |= exp.checkPurity(sc, ad.dtor);\n                err |= exp.checkSafety(sc, ad.dtor);\n                err |= exp.checkNogc(sc, ad.dtor);\n            }\n            if (ad.aggDelete && tb.ty != Tarray)\n            {\n                err |= exp.checkPurity(sc, ad.aggDelete);\n                err |= exp.checkSafety(sc, ad.aggDelete);\n                err |= exp.checkNogc(sc, ad.aggDelete);\n            }\n            if (err)\n                return setError();\n        }\n\n        if (!sc.intypeof && sc.func &&\n            !exp.isRAII &&\n            sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n        {\n            exp.error(\"`%s` is not `@safe` but is used in `@safe` function `%s`\", exp.toChars(), sc.func.toChars());\n            err = true;\n        }\n        if (err)\n            return setError();\n\n        result = exp;\n    }\n\n    override void visit(CastExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"CastExp::semantic('%s')\\n\", exp.toChars());\n        }\n        //static int x; assert(++x < 10);\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (exp.to)\n        {\n            exp.to = exp.to.typeSemantic(exp.loc, sc);\n            if (exp.to == Type.terror)\n                return setError();\n\n            if (!exp.to.hasPointers())\n                exp.setNoderefOperand();\n\n            // When e1 is a template lambda, this cast may instantiate it with\n            // the type 'to'.\n            exp.e1 = inferType(exp.e1, exp.to);\n        }\n\n        if (auto e = unaSemantic(exp, sc))\n        {\n            result = e;\n            return;\n        }\n        auto e1x = resolveProperties(sc, exp.e1);\n        if (e1x.op == TOK.error)\n        {\n            result = e1x;\n            return;\n        }\n        if (e1x.checkType())\n            return setError();\n        exp.e1 = e1x;\n\n        if (!exp.e1.type)\n        {\n            exp.error(\"cannot cast `%s`\", exp.e1.toChars());\n            return setError();\n        }\n\n        if (!exp.to) // Handle cast(const) and cast(immutable), etc.\n        {\n            exp.to = exp.e1.type.castMod(exp.mod);\n            exp.to = exp.to.typeSemantic(exp.loc, sc);\n            if (exp.to == Type.terror)\n                return setError();\n        }\n\n        if (exp.to.ty == Ttuple)\n        {\n            exp.error(\"cannot cast `%s` to tuple type `%s`\", exp.e1.toChars(), exp.to.toChars());\n            return setError();\n        }\n\n        // cast(void) is used to mark e1 as unused, so it is safe\n        if (exp.to.ty == Tvoid)\n        {\n            exp.type = exp.to;\n            result = exp;\n            return;\n        }\n\n        if (!exp.to.equals(exp.e1.type) && exp.mod == cast(ubyte)~0)\n        {\n            if (Expression e = exp.op_overload(sc))\n            {\n                result = e.implicitCastTo(sc, exp.to);\n                return;\n            }\n        }\n\n        Type t1b = exp.e1.type.toBasetype();\n        Type tob = exp.to.toBasetype();\n\n        if (tob.ty == Tstruct && !tob.equals(t1b))\n        {\n            /* Look to replace:\n             *  cast(S)t\n             * with:\n             *  S(t)\n             */\n\n            // Rewrite as to.call(e1)\n            Expression e = new TypeExp(exp.loc, exp.to);\n            e = new CallExp(exp.loc, e, exp.e1);\n            e = e.trySemantic(sc);\n            if (e)\n            {\n                result = e;\n                return;\n            }\n        }\n\n        if (!t1b.equals(tob) && (t1b.ty == Tarray || t1b.ty == Tsarray))\n        {\n            if (checkNonAssignmentArrayOp(exp.e1))\n                return setError();\n        }\n\n        // Look for casting to a vector type\n        if (tob.ty == Tvector && t1b.ty != Tvector)\n        {\n            result = new VectorExp(exp.loc, exp.e1, exp.to);\n            return;\n        }\n\n        Expression ex = exp.e1.castTo(sc, exp.to);\n        if (ex.op == TOK.error)\n        {\n            result = ex;\n            return;\n        }\n\n        // Check for unsafe casts\n        if (sc.func && !sc.intypeof &&\n            !isSafeCast(ex, t1b, tob) &&\n            sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n        {\n            exp.error(\"cast from `%s` to `%s` not allowed in safe code\", exp.e1.type.toChars(), exp.to.toChars());\n            return setError();\n        }\n\n        result = ex;\n    }\n\n    override void visit(VectorExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"VectorExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        exp.e1 = exp.e1.expressionSemantic(sc);\n        exp.type = exp.to.typeSemantic(exp.loc, sc);\n        if (exp.e1.op == TOK.error || exp.type.ty == Terror)\n        {\n            result = exp.e1;\n            return;\n        }\n\n        Type tb = exp.type.toBasetype();\n        assert(tb.ty == Tvector);\n        TypeVector tv = cast(TypeVector)tb;\n        Type te = tv.elementType();\n        exp.dim = cast(int)(tv.size(exp.loc) / te.size(exp.loc));\n\n        bool checkElem(Expression elem)\n        {\n            if (elem.isConst() == 1)\n                return false;\n\n             exp.error(\"constant expression expected, not `%s`\", elem.toChars());\n             return true;\n        }\n\n        exp.e1 = exp.e1.optimize(WANTvalue);\n        bool res;\n        if (exp.e1.op == TOK.arrayLiteral)\n        {\n            foreach (i; 0 .. exp.dim)\n            {\n                // Do not stop on first error - check all AST nodes even if error found\n                res |= checkElem((cast(ArrayLiteralExp)exp.e1).getElement(i));\n            }\n        }\n        else if (exp.e1.type.ty == Tvoid)\n            checkElem(exp.e1);\n\n        result = res ? new ErrorExp() : exp;\n    }\n\n    override void visit(SliceExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"SliceExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        // operator overloading should be handled in ArrayExp already.\n        if (Expression ex = unaSemantic(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        exp.e1 = resolveProperties(sc, exp.e1);\n        if (exp.e1.op == TOK.type && exp.e1.type.ty != Ttuple)\n        {\n            if (exp.lwr || exp.upr)\n            {\n                exp.error(\"cannot slice type `%s`\", exp.e1.toChars());\n                return setError();\n            }\n            Expression e = new TypeExp(exp.loc, exp.e1.type.arrayOf());\n            result = e.expressionSemantic(sc);\n            return;\n        }\n        if (!exp.lwr && !exp.upr)\n        {\n            if (exp.e1.op == TOK.arrayLiteral)\n            {\n                // Convert [a,b,c][] to [a,b,c]\n                Type t1b = exp.e1.type.toBasetype();\n                Expression e = exp.e1;\n                if (t1b.ty == Tsarray)\n                {\n                    e = e.copy();\n                    e.type = t1b.nextOf().arrayOf();\n                }\n                result = e;\n                return;\n            }\n            if (exp.e1.op == TOK.slice)\n            {\n                // Convert e[][] to e[]\n                SliceExp se = cast(SliceExp)exp.e1;\n                if (!se.lwr && !se.upr)\n                {\n                    result = se;\n                    return;\n                }\n            }\n            if (isArrayOpOperand(exp.e1))\n            {\n                // Convert (a[]+b[])[] to a[]+b[]\n                result = exp.e1;\n                return;\n            }\n        }\n        if (exp.e1.op == TOK.error)\n        {\n            result = exp.e1;\n            return;\n        }\n        if (exp.e1.type.ty == Terror)\n            return setError();\n\n        Type t1b = exp.e1.type.toBasetype();\n        if (t1b.ty == Tpointer)\n        {\n            if ((cast(TypePointer)t1b).next.ty == Tfunction)\n            {\n                exp.error(\"cannot slice function pointer `%s`\", exp.e1.toChars());\n                return setError();\n            }\n            if (!exp.lwr || !exp.upr)\n            {\n                exp.error(\"need upper and lower bound to slice pointer\");\n                return setError();\n            }\n            if (sc.func && !sc.intypeof && sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n            {\n                exp.error(\"pointer slicing not allowed in safe functions\");\n                return setError();\n            }\n        }\n        else if (t1b.ty == Tarray)\n        {\n        }\n        else if (t1b.ty == Tsarray)\n        {\n            if (!exp.arrayop && global.params.vsafe)\n            {\n                /* Slicing a static array is like taking the address of it.\n                 * Perform checks as if e[] was &e\n                 */\n                if (VarDeclaration v = expToVariable(exp.e1))\n                {\n                    if (exp.e1.op == TOK.dotVariable)\n                    {\n                        DotVarExp dve = cast(DotVarExp)exp.e1;\n                        if ((dve.e1.op == TOK.this_ || dve.e1.op == TOK.super_) &&\n                            !(v.storage_class & STC.ref_))\n                        {\n                            // because it's a class\n                            v = null;\n                        }\n                    }\n\n                    if (v && !checkAddressVar(sc, exp, v))\n                        return setError();\n                }\n            }\n        }\n        else if (t1b.ty == Ttuple)\n        {\n            if (!exp.lwr && !exp.upr)\n            {\n                result = exp.e1;\n                return;\n            }\n            if (!exp.lwr || !exp.upr)\n            {\n                exp.error(\"need upper and lower bound to slice tuple\");\n                return setError();\n            }\n        }\n        else if (t1b.ty == Tvector)\n        {\n            // Convert e1 to corresponding static array\n            TypeVector tv1 = cast(TypeVector)t1b;\n            t1b = tv1.basetype;\n            t1b = t1b.castMod(tv1.mod);\n            exp.e1.type = t1b;\n        }\n        else\n        {\n            exp.error(\"`%s` cannot be sliced with `[]`\", t1b.ty == Tvoid ? exp.e1.toChars() : t1b.toChars());\n            return setError();\n        }\n\n        /* Run semantic on lwr and upr.\n         */\n        Scope* scx = sc;\n        if (t1b.ty == Tsarray || t1b.ty == Tarray || t1b.ty == Ttuple)\n        {\n            // Create scope for 'length' variable\n            ScopeDsymbol sym = new ArrayScopeSymbol(sc, exp);\n            sym.loc = exp.loc;\n            sym.parent = sc.scopesym;\n            sc = sc.push(sym);\n        }\n        if (exp.lwr)\n        {\n            if (t1b.ty == Ttuple)\n                sc = sc.startCTFE();\n            exp.lwr = exp.lwr.expressionSemantic(sc);\n            exp.lwr = resolveProperties(sc, exp.lwr);\n            if (t1b.ty == Ttuple)\n                sc = sc.endCTFE();\n            exp.lwr = exp.lwr.implicitCastTo(sc, Type.tsize_t);\n        }\n        if (exp.upr)\n        {\n            if (t1b.ty == Ttuple)\n                sc = sc.startCTFE();\n            exp.upr = exp.upr.expressionSemantic(sc);\n            exp.upr = resolveProperties(sc, exp.upr);\n            if (t1b.ty == Ttuple)\n                sc = sc.endCTFE();\n            exp.upr = exp.upr.implicitCastTo(sc, Type.tsize_t);\n        }\n        if (sc != scx)\n            sc = sc.pop();\n        if (exp.lwr && exp.lwr.type == Type.terror || exp.upr && exp.upr.type == Type.terror)\n            return setError();\n\n        if (t1b.ty == Ttuple)\n        {\n            exp.lwr = exp.lwr.ctfeInterpret();\n            exp.upr = exp.upr.ctfeInterpret();\n            uinteger_t i1 = exp.lwr.toUInteger();\n            uinteger_t i2 = exp.upr.toUInteger();\n\n            TupleExp te;\n            TypeTuple tup;\n            size_t length;\n            if (exp.e1.op == TOK.tuple) // slicing an expression tuple\n            {\n                te = cast(TupleExp)exp.e1;\n                tup = null;\n                length = te.exps.dim;\n            }\n            else if (exp.e1.op == TOK.type) // slicing a type tuple\n            {\n                te = null;\n                tup = cast(TypeTuple)t1b;\n                length = Parameter.dim(tup.arguments);\n            }\n            else\n                assert(0);\n\n            if (i2 < i1 || length < i2)\n            {\n                exp.error(\"string slice `[%llu .. %llu]` is out of bounds\", i1, i2);\n                return setError();\n            }\n\n            size_t j1 = cast(size_t)i1;\n            size_t j2 = cast(size_t)i2;\n            Expression e;\n            if (exp.e1.op == TOK.tuple)\n            {\n                auto exps = new Expressions(j2 - j1);\n                for (size_t i = 0; i < j2 - j1; i++)\n                {\n                    (*exps)[i] = (*te.exps)[j1 + i];\n                }\n                e = new TupleExp(exp.loc, te.e0, exps);\n            }\n            else\n            {\n                auto args = new Parameters();\n                args.reserve(j2 - j1);\n                for (size_t i = j1; i < j2; i++)\n                {\n                    Parameter arg = Parameter.getNth(tup.arguments, i);\n                    args.push(arg);\n                }\n                e = new TypeExp(exp.e1.loc, new TypeTuple(args));\n            }\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n\n        exp.type = t1b.nextOf().arrayOf();\n        // Allow typedef[] -> typedef[]\n        if (exp.type.equals(t1b))\n            exp.type = exp.e1.type;\n\n        // We might know $ now\n        setLengthVarIfKnown(exp.lengthVar, t1b);\n\n        if (exp.lwr && exp.upr)\n        {\n            exp.lwr = exp.lwr.optimize(WANTvalue);\n            exp.upr = exp.upr.optimize(WANTvalue);\n\n            IntRange lwrRange = getIntRange(exp.lwr);\n            IntRange uprRange = getIntRange(exp.upr);\n\n            if (t1b.ty == Tsarray || t1b.ty == Tarray)\n            {\n                Expression el = new ArrayLengthExp(exp.loc, exp.e1);\n                el = el.expressionSemantic(sc);\n                el = el.optimize(WANTvalue);\n                if (el.op == TOK.int64)\n                {\n                    // Array length is known at compile-time. Upper is in bounds if it fits length.\n                    dinteger_t length = el.toInteger();\n                    auto bounds = IntRange(SignExtendedNumber(0), SignExtendedNumber(length));\n                    exp.upperIsInBounds = bounds.contains(uprRange);\n                }\n                else if (exp.upr.op == TOK.int64 && exp.upr.toInteger() == 0)\n                {\n                    // Upper slice expression is '0'. Value is always in bounds.\n                    exp.upperIsInBounds = true;\n                }\n                else if (exp.upr.op == TOK.variable && (cast(VarExp)exp.upr).var.ident == Id.dollar)\n                {\n                    // Upper slice expression is '$'. Value is always in bounds.\n                    exp.upperIsInBounds = true;\n                }\n            }\n            else if (t1b.ty == Tpointer)\n            {\n                exp.upperIsInBounds = true;\n            }\n            else\n                assert(0);\n\n            exp.lowerIsLessThanUpper = (lwrRange.imax <= uprRange.imin);\n\n            //printf(\"upperIsInBounds = %d lowerIsLessThanUpper = %d\\n\", exp.upperIsInBounds, exp.lowerIsLessThanUpper);\n        }\n\n        result = exp;\n    }\n\n    override void visit(ArrayLengthExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"ArrayLengthExp::semantic('%s')\\n\", e.toChars());\n        }\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n\n        if (Expression ex = unaSemantic(e, sc))\n        {\n            result = ex;\n            return;\n        }\n        e.e1 = resolveProperties(sc, e.e1);\n\n        e.type = Type.tsize_t;\n        result = e;\n    }\n\n    override void visit(ArrayExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"ArrayExp::semantic('%s')\\n\", exp.toChars());\n        }\n        assert(!exp.type);\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (isAggregate(exp.e1.type))\n            exp.error(\"no `[]` operator overload for type `%s`\", exp.e1.type.toChars());\n        else\n            exp.error(\"only one index allowed to index `%s`\", exp.e1.type.toChars());\n        result = new ErrorExp();\n    }\n\n    override void visit(DotExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"DotExp::semantic('%s')\\n\", exp.toChars());\n            if (exp.type)\n                printf(\"\\ttype = %s\\n\", exp.type.toChars());\n        }\n        exp.e1 = exp.e1.expressionSemantic(sc);\n        exp.e2 = exp.e2.expressionSemantic(sc);\n\n        if (exp.e1.op == TOK.type)\n        {\n            result = exp.e2;\n            return;\n        }\n        if (exp.e2.op == TOK.type)\n        {\n            result = exp.e2;\n            return;\n        }\n        if (exp.e2.op == TOK.template_)\n        {\n            auto td = (cast(TemplateExp)exp.e2).td;\n            Expression e = new DotTemplateExp(exp.loc, exp.e1, td);\n            result = e.expressionSemantic(sc);\n            return;\n        }\n        if (!exp.type)\n            exp.type = exp.e2.type;\n        result = exp;\n    }\n\n    override void visit(CommaExp e)\n    {\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n\n        // Allow `((a,b),(x,y))`\n        if (e.allowCommaExp)\n        {\n            CommaExp.allow(e.e1);\n            CommaExp.allow(e.e2);\n        }\n\n        if (Expression ex = binSemanticProp(e, sc))\n        {\n            result = ex;\n            return;\n        }\n        e.e1 = e.e1.addDtorHook(sc);\n\n        if (checkNonAssignmentArrayOp(e.e1))\n            return setError();\n\n        e.type = e.e2.type;\n        if (e.type !is Type.tvoid && !e.allowCommaExp && !e.isGenerated)\n            e.error(\"Using the result of a comma expression is not allowed\");\n        result = e;\n    }\n\n    override void visit(IntervalExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"IntervalExp::semantic('%s')\\n\", e.toChars());\n        }\n        if (e.type)\n        {\n            result = e;\n            return;\n        }\n\n        Expression le = e.lwr;\n        le = le.expressionSemantic(sc);\n        le = resolveProperties(sc, le);\n\n        Expression ue = e.upr;\n        ue = ue.expressionSemantic(sc);\n        ue = resolveProperties(sc, ue);\n\n        if (le.op == TOK.error)\n        {\n            result = le;\n            return;\n        }\n        if (ue.op == TOK.error)\n        {\n            result = ue;\n            return;\n        }\n\n        e.lwr = le;\n        e.upr = ue;\n\n        e.type = Type.tvoid;\n        result = e;\n    }\n\n    override void visit(DelegatePtrExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"DelegatePtrExp::semantic('%s')\\n\", e.toChars());\n        }\n        if (!e.type)\n        {\n            unaSemantic(e, sc);\n            e.e1 = resolveProperties(sc, e.e1);\n\n            if (e.e1.op == TOK.error)\n            {\n                result = e.e1;\n                return;\n            }\n            e.type = Type.tvoidptr;\n        }\n        result = e;\n    }\n\n    override void visit(DelegateFuncptrExp e)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"DelegateFuncptrExp::semantic('%s')\\n\", e.toChars());\n        }\n        if (!e.type)\n        {\n            unaSemantic(e, sc);\n            e.e1 = resolveProperties(sc, e.e1);\n            if (e.e1.op == TOK.error)\n            {\n                result = e.e1;\n                return;\n            }\n            e.type = e.e1.type.nextOf().pointerTo();\n        }\n        result = e;\n    }\n\n    override void visit(IndexExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"IndexExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        // operator overloading should be handled in ArrayExp already.\n        if (!exp.e1.type)\n            exp.e1 = exp.e1.expressionSemantic(sc);\n        assert(exp.e1.type); // semantic() should already be run on it\n        if (exp.e1.op == TOK.type && exp.e1.type.ty != Ttuple)\n        {\n            exp.e2 = exp.e2.expressionSemantic(sc);\n            exp.e2 = resolveProperties(sc, exp.e2);\n            Type nt;\n            if (exp.e2.op == TOK.type)\n                nt = new TypeAArray(exp.e1.type, exp.e2.type);\n            else\n                nt = new TypeSArray(exp.e1.type, exp.e2);\n            Expression e = new TypeExp(exp.loc, nt);\n            result = e.expressionSemantic(sc);\n            return;\n        }\n        if (exp.e1.op == TOK.error)\n        {\n            result = exp.e1;\n            return;\n        }\n        if (exp.e1.type.ty == Terror)\n            return setError();\n\n        // Note that unlike C we do not implement the int[ptr]\n\n        Type t1b = exp.e1.type.toBasetype();\n\n        if (t1b.ty == Tvector)\n        {\n            // Convert e1 to corresponding static array\n            TypeVector tv1 = cast(TypeVector)t1b;\n            t1b = tv1.basetype;\n            t1b = t1b.castMod(tv1.mod);\n            exp.e1.type = t1b;\n        }\n\n        /* Run semantic on e2\n         */\n        Scope* scx = sc;\n        if (t1b.ty == Tsarray || t1b.ty == Tarray || t1b.ty == Ttuple)\n        {\n            // Create scope for 'length' variable\n            ScopeDsymbol sym = new ArrayScopeSymbol(sc, exp);\n            sym.loc = exp.loc;\n            sym.parent = sc.scopesym;\n            sc = sc.push(sym);\n        }\n        if (t1b.ty == Ttuple)\n            sc = sc.startCTFE();\n        exp.e2 = exp.e2.expressionSemantic(sc);\n        exp.e2 = resolveProperties(sc, exp.e2);\n        if (t1b.ty == Ttuple)\n            sc = sc.endCTFE();\n        if (exp.e2.op == TOK.tuple)\n        {\n            TupleExp te = cast(TupleExp)exp.e2;\n            if (te.exps && te.exps.dim == 1)\n                exp.e2 = Expression.combine(te.e0, (*te.exps)[0]); // bug 4444 fix\n        }\n        if (sc != scx)\n            sc = sc.pop();\n        if (exp.e2.type == Type.terror)\n            return setError();\n\n        if (checkNonAssignmentArrayOp(exp.e1))\n            return setError();\n\n        switch (t1b.ty)\n        {\n        case Tpointer:\n            if ((cast(TypePointer)t1b).next.ty == Tfunction)\n            {\n                exp.error(\"cannot index function pointer `%s`\", exp.e1.toChars());\n                return setError();\n            }\n            exp.e2 = exp.e2.implicitCastTo(sc, Type.tsize_t);\n            if (exp.e2.type == Type.terror)\n                return setError();\n            exp.e2 = exp.e2.optimize(WANTvalue);\n            if (exp.e2.op == TOK.int64 && exp.e2.toInteger() == 0)\n            {\n            }\n            else if (sc.func && sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n            {\n                exp.error(\"safe function `%s` cannot index pointer `%s`\", sc.func.toPrettyChars(), exp.e1.toChars());\n                return setError();\n            }\n            exp.type = (cast(TypeNext)t1b).next;\n            break;\n\n        case Tarray:\n            exp.e2 = exp.e2.implicitCastTo(sc, Type.tsize_t);\n            if (exp.e2.type == Type.terror)\n                return setError();\n            exp.type = (cast(TypeNext)t1b).next;\n            break;\n\n        case Tsarray:\n            {\n                exp.e2 = exp.e2.implicitCastTo(sc, Type.tsize_t);\n                if (exp.e2.type == Type.terror)\n                    return setError();\n                exp.type = t1b.nextOf();\n                break;\n            }\n        case Taarray:\n            {\n                TypeAArray taa = cast(TypeAArray)t1b;\n                /* We can skip the implicit conversion if they differ only by\n                 * constness\n                 * https://issues.dlang.org/show_bug.cgi?id=2684\n                 * see also bug https://issues.dlang.org/show_bug.cgi?id=2954 b\n                 */\n                if (!arrayTypeCompatibleWithoutCasting(exp.e2.type, taa.index))\n                {\n                    exp.e2 = exp.e2.implicitCastTo(sc, taa.index); // type checking\n                    if (exp.e2.type == Type.terror)\n                        return setError();\n                }\n\n                semanticTypeInfo(sc, taa);\n\n                exp.type = taa.next;\n                break;\n            }\n        case Ttuple:\n            {\n                exp.e2 = exp.e2.implicitCastTo(sc, Type.tsize_t);\n                if (exp.e2.type == Type.terror)\n                    return setError();\n\n                exp.e2 = exp.e2.ctfeInterpret();\n                uinteger_t index = exp.e2.toUInteger();\n\n                TupleExp te;\n                TypeTuple tup;\n                size_t length;\n                if (exp.e1.op == TOK.tuple)\n                {\n                    te = cast(TupleExp)exp.e1;\n                    tup = null;\n                    length = te.exps.dim;\n                }\n                else if (exp.e1.op == TOK.type)\n                {\n                    te = null;\n                    tup = cast(TypeTuple)t1b;\n                    length = Parameter.dim(tup.arguments);\n                }\n                else\n                    assert(0);\n\n                if (length <= index)\n                {\n                    exp.error(\"array index `[%llu]` is outside array bounds `[0 .. %llu]`\", index, cast(ulong)length);\n                    return setError();\n                }\n                Expression e;\n                if (exp.e1.op == TOK.tuple)\n                {\n                    e = (*te.exps)[cast(size_t)index];\n                    e = Expression.combine(te.e0, e);\n                }\n                else\n                    e = new TypeExp(exp.e1.loc, Parameter.getNth(tup.arguments, cast(size_t)index).type);\n                result = e;\n                return;\n            }\n        default:\n            exp.error(\"`%s` must be an array or pointer type, not `%s`\", exp.e1.toChars(), exp.e1.type.toChars());\n            return setError();\n        }\n\n        // We might know $ now\n        setLengthVarIfKnown(exp.lengthVar, t1b);\n\n        if (t1b.ty == Tsarray || t1b.ty == Tarray)\n        {\n            Expression el = new ArrayLengthExp(exp.loc, exp.e1);\n            el = el.expressionSemantic(sc);\n            el = el.optimize(WANTvalue);\n            if (el.op == TOK.int64)\n            {\n                exp.e2 = exp.e2.optimize(WANTvalue);\n                dinteger_t length = el.toInteger();\n                if (length)\n                {\n                    auto bounds = IntRange(SignExtendedNumber(0), SignExtendedNumber(length - 1));\n                    exp.indexIsInBounds = bounds.contains(getIntRange(exp.e2));\n                }\n            }\n        }\n\n        result = exp;\n    }\n\n    override void visit(PostExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"PostExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemantic(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e1x = resolveProperties(sc, exp.e1);\n        if (e1x.op == TOK.error)\n        {\n            result = e1x;\n            return;\n        }\n        exp.e1 = e1x;\n\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (exp.e1.checkReadModifyWrite(exp.op))\n            return setError();\n\n        if (exp.e1.op == TOK.slice)\n        {\n            const(char)* s = exp.op == TOK.plusPlus ? \"increment\" : \"decrement\";\n            exp.error(\"cannot post-%s array slice `%s`, use pre-%s instead\", s, exp.e1.toChars(), s);\n            return setError();\n        }\n\n        exp.e1 = exp.e1.optimize(WANTvalue);\n\n        Type t1 = exp.e1.type.toBasetype();\n        if (t1.ty == Tclass || t1.ty == Tstruct || exp.e1.op == TOK.arrayLength)\n        {\n            /* Check for operator overloading,\n             * but rewrite in terms of ++e instead of e++\n             */\n\n            /* If e1 is not trivial, take a reference to it\n             */\n            Expression de = null;\n            if (exp.e1.op != TOK.variable && exp.e1.op != TOK.arrayLength)\n            {\n                // ref v = e1;\n                auto v = copyToTemp(STC.ref_, \"__postref\", exp.e1);\n                de = new DeclarationExp(exp.loc, v);\n                exp.e1 = new VarExp(exp.e1.loc, v);\n            }\n\n            /* Rewrite as:\n             * auto tmp = e1; ++e1; tmp\n             */\n            auto tmp = copyToTemp(0, \"__pitmp\", exp.e1);\n            Expression ea = new DeclarationExp(exp.loc, tmp);\n\n            Expression eb = exp.e1.syntaxCopy();\n            eb = new PreExp(exp.op == TOK.plusPlus ? TOK.prePlusPlus : TOK.preMinusMinus, exp.loc, eb);\n\n            Expression ec = new VarExp(exp.loc, tmp);\n\n            // Combine de,ea,eb,ec\n            if (de)\n                ea = new CommaExp(exp.loc, de, ea);\n            e = new CommaExp(exp.loc, ea, eb);\n            e = new CommaExp(exp.loc, e, ec);\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n\n        exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);\n\n        e = exp;\n        if (exp.e1.checkScalar())\n            return setError();\n        if (exp.e1.checkNoBool())\n            return setError();\n\n        if (exp.e1.type.ty == Tpointer)\n            e = scaleFactor(exp, sc);\n        else\n            exp.e2 = exp.e2.castTo(sc, exp.e1.type);\n        e.type = exp.e1.type;\n        result = e;\n    }\n\n    override void visit(PreExp exp)\n    {\n        Expression e = exp.op_overload(sc);\n        // printf(\"PreExp::semantic('%s')\\n\", toChars());\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        // Rewrite as e1+=1 or e1-=1\n        if (exp.op == TOK.prePlusPlus)\n            e = new AddAssignExp(exp.loc, exp.e1, new IntegerExp(exp.loc, 1, Type.tint32));\n        else\n            e = new MinAssignExp(exp.loc, exp.e1, new IntegerExp(exp.loc, 1, Type.tint32));\n        result = e.expressionSemantic(sc);\n    }\n\n    /*\n     * Get the expression initializer for a specific struct\n     *\n     * Params:\n     *  sd = the struct for which the expression initializer is needed\n     *  loc = the location of the initializer\n     *  sc = the scope where the expression is located\n     *  t = the type of the expression\n     *\n     * Returns:\n     *  The expression initializer or error expression if any errors occured\n     */\n    private Expression getInitExp(StructDeclaration sd, Loc loc, Scope* sc, Type t)\n    {\n        if (sd.zeroInit && !sd.isNested())\n        {\n            // https://issues.dlang.org/show_bug.cgi?id=14606\n            // Always use BlitExp for the special expression: (struct = 0)\n            return new IntegerExp(loc, 0, Type.tint32);\n        }\n\n        if (sd.isNested())\n        {\n            auto sle = new StructLiteralExp(loc, sd, null, t);\n            if (!sd.fill(loc, sle.elements, true))\n                return new ErrorExp();\n            if (checkFrameAccess(loc, sc, sd, sle.elements.dim))\n                return new ErrorExp();\n\n            sle.type = t;\n            return sle;\n        }\n\n        return t.defaultInit(loc);\n    }\n\n    override void visit(AssignExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"AssignExp::semantic('%s')\\n\", exp.toChars());\n        }\n        //printf(\"exp.e1.op = %d, '%s'\\n\", exp.e1.op, Token.toChars(exp.e1.op));\n        //printf(\"exp.e2.op = %d, '%s'\\n\", exp.e2.op, Token.toChars(exp.e2.op));\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        Expression e1old = exp.e1;\n\n        if (exp.e2.op == TOK.comma)\n        {\n            /* Rewrite to get rid of the comma from rvalue\n             */\n            if (!(cast(CommaExp)exp.e2).isGenerated)\n                exp.error(\"Using the result of a comma expression is not allowed\");\n            Expression e0;\n            exp.e2 = Expression.extractLast(exp.e2, e0);\n            Expression e = Expression.combine(e0, exp);\n            result = e.expressionSemantic(sc);\n            return;\n        }\n\n        /* Look for operator overloading of a[arguments] = e2.\n         * Do it before e1.expressionSemantic() otherwise the ArrayExp will have been\n         * converted to unary operator overloading already.\n         */\n        if (exp.e1.op == TOK.array)\n        {\n            Expression res;\n\n            ArrayExp ae = cast(ArrayExp)exp.e1;\n            ae.e1 = ae.e1.expressionSemantic(sc);\n            ae.e1 = resolveProperties(sc, ae.e1);\n            Expression ae1old = ae.e1;\n\n            const(bool) maybeSlice =\n                (ae.arguments.dim == 0 ||\n                 ae.arguments.dim == 1 && (*ae.arguments)[0].op == TOK.interval);\n\n            IntervalExp ie = null;\n            if (maybeSlice && ae.arguments.dim)\n            {\n                assert((*ae.arguments)[0].op == TOK.interval);\n                ie = cast(IntervalExp)(*ae.arguments)[0];\n            }\n            while (true)\n            {\n                if (ae.e1.op == TOK.error)\n                {\n                    result = ae.e1;\n                    return;\n                }\n                Expression e0 = null;\n                Expression ae1save = ae.e1;\n                ae.lengthVar = null;\n\n                Type t1b = ae.e1.type.toBasetype();\n                AggregateDeclaration ad = isAggregate(t1b);\n                if (!ad)\n                    break;\n                if (search_function(ad, Id.indexass))\n                {\n                    // Deal with $\n                    res = resolveOpDollar(sc, ae, &e0);\n                    if (!res) // a[i..j] = e2 might be: a.opSliceAssign(e2, i, j)\n                        goto Lfallback;\n                    if (res.op == TOK.error)\n                    {\n                        result = res;\n                        return;\n                    }\n\n                    res = exp.e2.expressionSemantic(sc);\n                    if (res.op == TOK.error)\n                    {\n                        result = res;\n                        return;\n                    }\n                    exp.e2 = res;\n\n                    /* Rewrite (a[arguments] = e2) as:\n                     *      a.opIndexAssign(e2, arguments)\n                     */\n                    Expressions* a = ae.arguments.copy();\n                    a.insert(0, exp.e2);\n                    res = new DotIdExp(exp.loc, ae.e1, Id.indexass);\n                    res = new CallExp(exp.loc, res, a);\n                    if (maybeSlice) // a[] = e2 might be: a.opSliceAssign(e2)\n                        res = res.trySemantic(sc);\n                    else\n                        res = res.expressionSemantic(sc);\n                    if (res)\n                    {\n                        res = Expression.combine(e0, res);\n                        result = res;\n                        return;\n                    }\n                }\n\n            Lfallback:\n                if (maybeSlice && search_function(ad, Id.sliceass))\n                {\n                    // Deal with $\n                    res = resolveOpDollar(sc, ae, ie, &e0);\n                    if (res.op == TOK.error)\n                    {\n                        result = res;\n                        return;\n                    }\n\n                    res = exp.e2.expressionSemantic(sc);\n                    if (res.op == TOK.error)\n                    {\n                        result = res;\n                        return;\n                    }\n                    exp.e2 = res;\n\n                    /* Rewrite (a[i..j] = e2) as:\n                     *      a.opSliceAssign(e2, i, j)\n                     */\n                    auto a = new Expressions();\n                    a.push(exp.e2);\n                    if (ie)\n                    {\n                        a.push(ie.lwr);\n                        a.push(ie.upr);\n                    }\n                    res = new DotIdExp(exp.loc, ae.e1, Id.sliceass);\n                    res = new CallExp(exp.loc, res, a);\n                    res = res.expressionSemantic(sc);\n                    res = Expression.combine(e0, res);\n                    result = res;\n                    return;\n                }\n\n                // No operator overloading member function found yet, but\n                // there might be an alias this to try.\n                if (ad.aliasthis && t1b != ae.att1)\n                {\n                    if (!ae.att1 && t1b.checkAliasThisRec())\n                        ae.att1 = t1b;\n\n                    /* Rewrite (a[arguments] op e2) as:\n                     *      a.aliasthis[arguments] op e2\n                     */\n                    ae.e1 = resolveAliasThis(sc, ae1save, true);\n                    if (ae.e1)\n                        continue;\n                }\n                break;\n            }\n            ae.e1 = ae1old; // recovery\n            ae.lengthVar = null;\n        }\n\n        /* Run this.e1 semantic.\n         */\n        {\n            Expression e1x = exp.e1;\n\n            /* With UFCS, e.f = value\n             * Could mean:\n             *      .f(e, value)\n             * or:\n             *      .f(e) = value\n             */\n            if (e1x.op == TOK.dotTemplateInstance)\n            {\n                DotTemplateInstanceExp dti = cast(DotTemplateInstanceExp)e1x;\n                Expression e = dti.semanticY(sc, 1);\n                if (!e)\n                {\n                    result = resolveUFCSProperties(sc, e1x, exp.e2);\n                    return;\n                }\n                e1x = e;\n            }\n            else if (e1x.op == TOK.dotIdentifier)\n            {\n                DotIdExp die = cast(DotIdExp)e1x;\n                Expression e = die.semanticY(sc, 1);\n                if (e && isDotOpDispatch(e))\n                {\n                    uint errors = global.startGagging();\n                    e = resolvePropertiesX(sc, e, exp.e2);\n                    if (global.endGagging(errors))\n                        e = null; /* fall down to UFCS */\n                    else\n                    {\n                        result = e;\n                        return;\n                    }\n                }\n                if (!e)\n                {\n                    result = resolveUFCSProperties(sc, e1x, exp.e2);\n                    return;\n                }\n                e1x = e;\n            }\n            else\n            {\n                if (e1x.op == TOK.slice)\n                    (cast(SliceExp)e1x).arrayop = true;\n\n                e1x = e1x.expressionSemantic(sc);\n            }\n\n            /* We have f = value.\n             * Could mean:\n             *      f(value)\n             * or:\n             *      f() = value\n             */\n            if (Expression e = resolvePropertiesX(sc, e1x, exp.e2))\n            {\n                result = e;\n                return;\n            }\n            if (e1x.checkRightThis(sc))\n                return setError();\n            exp.e1 = e1x;\n            assert(exp.e1.type);\n        }\n        Type t1 = exp.e1.type.toBasetype();\n\n        /* Run this.e2 semantic.\n         * Different from other binary expressions, the analysis of e2\n         * depends on the result of e1 in assignments.\n         */\n        {\n            Expression e2x = inferType(exp.e2, t1.baseElemOf());\n            e2x = e2x.expressionSemantic(sc);\n            e2x = resolveProperties(sc, e2x);\n            if (e2x.op == TOK.type)\n                e2x = resolveAliasThis(sc, e2x); //https://issues.dlang.org/show_bug.cgi?id=17684\n            if (e2x.op == TOK.error)\n            {\n                result = e2x;\n                return;\n            }\n            if (e2x.checkValue())\n                return setError();\n            exp.e2 = e2x;\n        }\n\n        /* Rewrite tuple assignment as a tuple of assignments.\n         */\n        {\n            Expression e2x = exp.e2;\n\n        Ltupleassign:\n            if (exp.e1.op == TOK.tuple && e2x.op == TOK.tuple)\n            {\n                TupleExp tup1 = cast(TupleExp)exp.e1;\n                TupleExp tup2 = cast(TupleExp)e2x;\n                size_t dim = tup1.exps.dim;\n                Expression e = null;\n                if (dim != tup2.exps.dim)\n                {\n                    exp.error(\"mismatched tuple lengths, %d and %d\", cast(int)dim, cast(int)tup2.exps.dim);\n                    return setError();\n                }\n                if (dim == 0)\n                {\n                    e = new IntegerExp(exp.loc, 0, Type.tint32);\n                    e = new CastExp(exp.loc, e, Type.tvoid); // avoid \"has no effect\" error\n                    e = Expression.combine(tup1.e0, tup2.e0, e);\n                }\n                else\n                {\n                    auto exps = new Expressions(dim);\n                    for (size_t i = 0; i < dim; i++)\n                    {\n                        Expression ex1 = (*tup1.exps)[i];\n                        Expression ex2 = (*tup2.exps)[i];\n                        (*exps)[i] = new AssignExp(exp.loc, ex1, ex2);\n                    }\n                    e = new TupleExp(exp.loc, Expression.combine(tup1.e0, tup2.e0), exps);\n                }\n                result = e.expressionSemantic(sc);\n                return;\n            }\n\n            /* Look for form: e1 = e2.aliasthis.\n             */\n            if (exp.e1.op == TOK.tuple)\n            {\n                TupleDeclaration td = isAliasThisTuple(e2x);\n                if (!td)\n                    goto Lnomatch;\n\n                assert(exp.e1.type.ty == Ttuple);\n                TypeTuple tt = cast(TypeTuple)exp.e1.type;\n\n                Expression e0;\n                Expression ev = extractSideEffect(sc, \"__tup\", e0, e2x);\n\n                auto iexps = new Expressions();\n                iexps.push(ev);\n                for (size_t u = 0; u < iexps.dim; u++)\n                {\n                Lexpand:\n                    Expression e = (*iexps)[u];\n\n                    Parameter arg = Parameter.getNth(tt.arguments, u);\n                    //printf(\"[%d] iexps.dim = %d, \", u, iexps.dim);\n                    //printf(\"e = (%s %s, %s), \", Token::tochars[e.op], e.toChars(), e.type.toChars());\n                    //printf(\"arg = (%s, %s)\\n\", arg.toChars(), arg.type.toChars());\n\n                    if (!arg || !e.type.implicitConvTo(arg.type))\n                    {\n                        // expand initializer to tuple\n                        if (expandAliasThisTuples(iexps, u) != -1)\n                        {\n                            if (iexps.dim <= u)\n                                break;\n                            goto Lexpand;\n                        }\n                        goto Lnomatch;\n                    }\n                }\n                e2x = new TupleExp(e2x.loc, e0, iexps);\n                e2x = e2x.expressionSemantic(sc);\n                if (e2x.op == TOK.error)\n                {\n                    result = e2x;\n                    return;\n                }\n                // Do not need to overwrite this.e2\n                goto Ltupleassign;\n            }\n        Lnomatch:\n        }\n\n        /* Inside constructor, if this is the first assignment of object field,\n         * rewrite this to initializing the field.\n         */\n        if (exp.op == TOK.assign && exp.e1.checkModifiable(sc) == 2)\n        {\n            //printf(\"[%s] change to init - %s\\n\", exp.loc.toChars(), exp.toChars());\n            exp.op = TOK.construct;\n\n            // https://issues.dlang.org/show_bug.cgi?id=13515\n            // set Index::modifiable flag for complex AA element initialization\n            if (exp.e1.op == TOK.index)\n            {\n                Expression e1x = (cast(IndexExp)exp.e1).markSettingAAElem();\n                if (e1x.op == TOK.error)\n                {\n                    result = e1x;\n                    return;\n                }\n            }\n        }\n        else if (exp.op == TOK.construct && exp.e1.op == TOK.variable &&\n                 (cast(VarExp)exp.e1).var.storage_class & (STC.out_ | STC.ref_))\n        {\n            exp.memset |= MemorySet.referenceInit;\n        }\n\n        /* If it is an assignment from a 'foreign' type,\n         * check for operator overloading.\n         */\n        if (exp.memset & MemorySet.referenceInit)\n        {\n            // If this is an initialization of a reference,\n            // do nothing\n        }\n        else if (t1.ty == Tstruct)\n        {\n            auto e1x = exp.e1;\n            auto e2x = exp.e2;\n            auto sd = (cast(TypeStruct)t1).sym;\n\n            if (exp.op == TOK.construct)\n            {\n                Type t2 = e2x.type.toBasetype();\n                if (t2.ty == Tstruct && sd == (cast(TypeStruct)t2).sym)\n                {\n                    sd.size(exp.loc);\n                    if (sd.sizeok != Sizeok.done)\n                        return setError();\n                    if (!sd.ctor)\n                        sd.ctor = sd.searchCtor();\n\n                    // https://issues.dlang.org/show_bug.cgi?id=15661\n                    // Look for the form from last of comma chain.\n                    auto e2y = lastComma(e2x);\n\n                    CallExp ce = (e2y.op == TOK.call) ? cast(CallExp)e2y : null;\n                    DotVarExp dve = (ce && ce.e1.op == TOK.dotVariable)\n                        ? cast(DotVarExp)ce.e1 : null;\n                    if (sd.ctor && ce && dve && dve.var.isCtorDeclaration() &&\n                        e2y.type.implicitConvTo(t1))\n                    {\n                        /* Look for form of constructor call which is:\n                         *    __ctmp.ctor(arguments...)\n                         */\n\n                        /* Before calling the constructor, initialize\n                         * variable with a bit copy of the default\n                         * initializer\n                         */\n                        Expression einit = getInitExp(sd, exp.loc, sc, t1);\n                        if (einit.op == TOK.error)\n                        {\n                            result = einit;\n                            return;\n                        }\n\n                        auto ae = new BlitExp(exp.loc, exp.e1, einit);\n                        ae.type = e1x.type;\n\n                        /* Replace __ctmp being constructed with e1.\n                         * We need to copy constructor call expression,\n                         * because it may be used in other place.\n                         */\n                        auto dvx = cast(DotVarExp)dve.copy();\n                        dvx.e1 = e1x;\n                        auto cx = cast(CallExp)ce.copy();\n                        cx.e1 = dvx;\n\n                        Expression e0;\n                        Expression.extractLast(e2x, e0);\n\n                        auto e = Expression.combine(e0, ae, cx);\n                        e = e.expressionSemantic(sc);\n                        result = e;\n                        return;\n                    }\n                    if (sd.postblit)\n                    {\n                        /* We have a copy constructor for this\n                         */\n                        if (e2x.op == TOK.question)\n                        {\n                            /* Rewrite as:\n                             *  a ? e1 = b : e1 = c;\n                             */\n                            CondExp econd = cast(CondExp)e2x;\n                            Expression ea1 = new ConstructExp(econd.e1.loc, e1x, econd.e1);\n                            Expression ea2 = new ConstructExp(econd.e1.loc, e1x, econd.e2);\n                            Expression e = new CondExp(exp.loc, econd.econd, ea1, ea2);\n                            result = e.expressionSemantic(sc);\n                            return;\n                        }\n\n                        if (e2x.isLvalue())\n                        {\n                            if (!e2x.type.implicitConvTo(e1x.type))\n                            {\n                                exp.error(\"conversion error from `%s` to `%s`\",\n                                    e2x.type.toChars(), e1x.type.toChars());\n                                return setError();\n                            }\n\n                            /* Rewrite as:\n                             *  (e1 = e2).postblit();\n                             *\n                             * Blit assignment e1 = e2 returns a reference to the original e1,\n                             * then call the postblit on it.\n                             */\n                            Expression e = e1x.copy();\n                            e.type = e.type.mutableOf();\n                            if (e.type.isShared && !sd.type.isShared)\n                                e.type = e.type.unSharedOf();\n                            e = new BlitExp(exp.loc, e, e2x);\n                            e = new DotVarExp(exp.loc, e, sd.postblit, false);\n                            e = new CallExp(exp.loc, e);\n                            result = e.expressionSemantic(sc);\n                            return;\n                        }\n                        else\n                        {\n                            /* The struct value returned from the function is transferred\n                             * so should not call the destructor on it.\n                             */\n                            e2x = valueNoDtor(e2x);\n                        }\n                    }\n\n                    // https://issues.dlang.org/show_bug.cgi?id=19251\n                    // if e2 cannot be converted to e1.type, maybe there is an alias this\n                    if (!e2x.implicitConvTo(t1))\n                    {\n                        AggregateDeclaration ad2 = isAggregate(e2x.type);\n                        if (ad2 && ad2.aliasthis && !(exp.att2 && e2x.type == exp.att2))\n                        {\n                            if (!exp.att2 && exp.e2.type.checkAliasThisRec())\n                            exp.att2 = exp.e2.type;\n                            /* Rewrite (e1 op e2) as:\n                             *      (e1 op e2.aliasthis)\n                             */\n                            exp.e2 = new DotIdExp(exp.e2.loc, exp.e2, ad2.aliasthis.ident);\n                            result = exp.expressionSemantic(sc);\n                            return;\n                        }\n                    }\n                }\n                else if (!e2x.implicitConvTo(t1))\n                {\n                    sd.size(exp.loc);\n                    if (sd.sizeok != Sizeok.done)\n                        return setError();\n                    if (!sd.ctor)\n                        sd.ctor = sd.searchCtor();\n\n                    if (sd.ctor)\n                    {\n                        /* Look for implicit constructor call\n                         * Rewrite as:\n                         *  e1 = init, e1.ctor(e2)\n                         */\n\n                        /* Fix Issue 5153 : https://issues.dlang.org/show_bug.cgi?id=5153\n                         * Using `new` to initialize a struct object is a common mistake, but\n                         * the error message from the compiler is not very helpful in that\n                         * case. If exp.e2 is a NewExp and the type of new is the same as\n                         * the type as exp.e1 (struct in this case), then we know for sure\n                         * that the user wants to instantiate a struct. This is done to avoid\n                         * issuing an error when the user actually wants to call a constructor\n                         * which receives a class object.\n                         *\n                         * Foo f = new Foo2(0); is a valid expression if Foo has a constructor\n                         * which receives an instance of a Foo2 class\n                         */\n                        if (exp.e2.op == TOK.new_)\n                        {\n                            auto newExp = cast(NewExp)(exp.e2);\n                            if (newExp.newtype && newExp.newtype == t1)\n                            {\n                                error(exp.loc, \"cannot implicitly convert expression `%s` of type `%s` to `%s`\",\n                                      newExp.toChars(), newExp.type.toChars(), t1.toChars());\n                                errorSupplemental(exp.loc, \"Perhaps remove the `new` keyword?\");\n                                return setError();\n                            }\n                        }\n\n                        Expression einit = new BlitExp(exp.loc, e1x, getInitExp(sd, exp.loc, sc, t1));\n                        einit.type = e1x.type;\n\n                        Expression e;\n                        e = new DotIdExp(exp.loc, e1x, Id.ctor);\n                        e = new CallExp(exp.loc, e, e2x);\n                        e = new CommaExp(exp.loc, einit, e);\n                        e = e.expressionSemantic(sc);\n                        result = e;\n                        return;\n                    }\n                    if (search_function(sd, Id.call))\n                    {\n                        /* Look for static opCall\n                         * https://issues.dlang.org/show_bug.cgi?id=2702\n                         * Rewrite as:\n                         *  e1 = typeof(e1).opCall(arguments)\n                         */\n                        e2x = typeDotIdExp(e2x.loc, e1x.type, Id.call);\n                        e2x = new CallExp(exp.loc, e2x, exp.e2);\n\n                        e2x = e2x.expressionSemantic(sc);\n                        e2x = resolveProperties(sc, e2x);\n                        if (e2x.op == TOK.error)\n                        {\n                            result = e2x;\n                            return;\n                        }\n                        if (e2x.checkValue())\n                            return setError();\n                    }\n                }\n                else // https://issues.dlang.org/show_bug.cgi?id=11355\n                {\n                    AggregateDeclaration ad2 = isAggregate(e2x.type);\n                    if (ad2 && ad2.aliasthis && !(exp.att2 && e2x.type == exp.att2))\n                    {\n                        if (!exp.att2 && exp.e2.type.checkAliasThisRec())\n                            exp.att2 = exp.e2.type;\n                        /* Rewrite (e1 op e2) as:\n                         *      (e1 op e2.aliasthis)\n                         */\n                        exp.e2 = new DotIdExp(exp.e2.loc, exp.e2, ad2.aliasthis.ident);\n                        result = exp.expressionSemantic(sc);\n                        return;\n                    }\n                }\n            }\n            else if (exp.op == TOK.assign)\n            {\n                if (e1x.op == TOK.index && (cast(IndexExp)e1x).e1.type.toBasetype().ty == Taarray)\n                {\n                    /*\n                     * Rewrite:\n                     *      aa[key] = e2;\n                     * as:\n                     *      ref __aatmp = aa;\n                     *      ref __aakey = key;\n                     *      ref __aaval = e2;\n                     *      (__aakey in __aatmp\n                     *          ? __aatmp[__aakey].opAssign(__aaval)\n                     *          : ConstructExp(__aatmp[__aakey], __aaval));\n                     */\n                    IndexExp ie = cast(IndexExp)e1x;\n                    Type t2 = e2x.type.toBasetype();\n\n                    Expression e0 = null;\n                    Expression ea = extractSideEffect(sc, \"__aatmp\", e0, ie.e1);\n                    Expression ek = extractSideEffect(sc, \"__aakey\", e0, ie.e2);\n                    Expression ev = extractSideEffect(sc, \"__aaval\", e0, e2x);\n\n                    AssignExp ae = cast(AssignExp)exp.copy();\n                    ae.e1 = new IndexExp(exp.loc, ea, ek);\n                    ae.e1 = ae.e1.expressionSemantic(sc);\n                    ae.e1 = ae.e1.optimize(WANTvalue);\n                    ae.e2 = ev;\n                    Expression e = ae.op_overload(sc);\n                    if (e)\n                    {\n                        Expression ey = null;\n                        if (t2.ty == Tstruct && sd == t2.toDsymbol(sc))\n                        {\n                            ey = ev;\n                        }\n                        else if (!ev.implicitConvTo(ie.type) && sd.ctor)\n                        {\n                            // Look for implicit constructor call\n                            // Rewrite as S().ctor(e2)\n                            ey = new StructLiteralExp(exp.loc, sd, null);\n                            ey = new DotIdExp(exp.loc, ey, Id.ctor);\n                            ey = new CallExp(exp.loc, ey, ev);\n                            ey = ey.trySemantic(sc);\n                        }\n                        if (ey)\n                        {\n                            Expression ex;\n                            ex = new IndexExp(exp.loc, ea, ek);\n                            ex = ex.expressionSemantic(sc);\n                            ex = ex.optimize(WANTvalue);\n                            ex = ex.modifiableLvalue(sc, ex); // allocate new slot\n\n                            ey = new ConstructExp(exp.loc, ex, ey);\n                            ey = ey.expressionSemantic(sc);\n                            if (ey.op == TOK.error)\n                            {\n                                result = ey;\n                                return;\n                            }\n                            ex = e;\n\n                            // https://issues.dlang.org/show_bug.cgi?id=14144\n                            // The whole expression should have the common type\n                            // of opAssign() return and assigned AA entry.\n                            // Even if there's no common type, expression should be typed as void.\n                            Type t = null;\n                            if (!typeMerge(sc, TOK.question, &t, &ex, &ey))\n                            {\n                                ex = new CastExp(ex.loc, ex, Type.tvoid);\n                                ey = new CastExp(ey.loc, ey, Type.tvoid);\n                            }\n                            e = new CondExp(exp.loc, new InExp(exp.loc, ek, ea), ex, ey);\n                        }\n                        e = Expression.combine(e0, e);\n                        e = e.expressionSemantic(sc);\n                        result = e;\n                        return;\n                    }\n                }\n                else\n                {\n                    Expression e = exp.op_overload(sc);\n                    if (e)\n                    {\n                        result = e;\n                        return;\n                    }\n                }\n            }\n            else\n                assert(exp.op == TOK.blit);\n\n            exp.e1 = e1x;\n            exp.e2 = e2x;\n        }\n        else if (t1.ty == Tclass)\n        {\n            // Disallow assignment operator overloads for same type\n            if (exp.op == TOK.assign && !exp.e2.implicitConvTo(exp.e1.type))\n            {\n                Expression e = exp.op_overload(sc);\n                if (e)\n                {\n                    result = e;\n                    return;\n                }\n            }\n        }\n        else if (t1.ty == Tsarray)\n        {\n            // SliceExp cannot have static array type without context inference.\n            assert(exp.e1.op != TOK.slice);\n            Expression e1x = exp.e1;\n            Expression e2x = exp.e2;\n\n            if (e2x.implicitConvTo(e1x.type))\n            {\n                if (exp.op != TOK.blit && (e2x.op == TOK.slice && (cast(UnaExp)e2x).e1.isLvalue() || e2x.op == TOK.cast_ && (cast(UnaExp)e2x).e1.isLvalue() || e2x.op != TOK.slice && e2x.isLvalue()))\n                {\n                    if (e1x.checkPostblit(sc, t1))\n                        return setError();\n                }\n\n                // e2 matches to t1 because of the implicit length match, so\n                if (isUnaArrayOp(e2x.op) || isBinArrayOp(e2x.op))\n                {\n                    // convert e1 to e1[]\n                    // e.g. e1[] = a[] + b[];\n                    auto sle = new SliceExp(e1x.loc, e1x, null, null);\n                    sle.arrayop = true;\n                    e1x = sle.expressionSemantic(sc);\n                }\n                else\n                {\n                    // convert e2 to t1 later\n                    // e.g. e1 = [1, 2, 3];\n                }\n            }\n            else\n            {\n                if (e2x.implicitConvTo(t1.nextOf().arrayOf()) > MATCH.nomatch)\n                {\n                    uinteger_t dim1 = (cast(TypeSArray)t1).dim.toInteger();\n                    uinteger_t dim2 = dim1;\n                    if (e2x.op == TOK.arrayLiteral)\n                    {\n                        ArrayLiteralExp ale = cast(ArrayLiteralExp)e2x;\n                        dim2 = ale.elements ? ale.elements.dim : 0;\n                    }\n                    else if (e2x.op == TOK.slice)\n                    {\n                        Type tx = toStaticArrayType(cast(SliceExp)e2x);\n                        if (tx)\n                            dim2 = (cast(TypeSArray)tx).dim.toInteger();\n                    }\n                    if (dim1 != dim2)\n                    {\n                        exp.error(\"mismatched array lengths, %d and %d\", cast(int)dim1, cast(int)dim2);\n                        return setError();\n                    }\n                }\n\n                // May be block or element-wise assignment, so\n                // convert e1 to e1[]\n                if (exp.op != TOK.assign)\n                {\n                    // If multidimensional static array, treat as one large array\n                    const dim = t1.numberOfElems(exp.loc);\n                    e1x.type = t1.baseElemOf().sarrayOf(dim);\n                }\n                auto sle = new SliceExp(e1x.loc, e1x, null, null);\n                sle.arrayop = true;\n                e1x = sle.expressionSemantic(sc);\n            }\n            if (e1x.op == TOK.error)\n            {\n                result = e1x;\n                return;\n            }\n            if (e2x.op == TOK.error)\n            {\n                result = e2x;\n                return;\n            }\n\n            exp.e1 = e1x;\n            exp.e2 = e2x;\n            t1 = e1x.type.toBasetype();\n        }\n        /* Check the mutability of e1.\n         */\n        if (exp.e1.op == TOK.arrayLength)\n        {\n            // e1 is not an lvalue, but we let code generator handle it\n            ArrayLengthExp ale = cast(ArrayLengthExp)exp.e1;\n\n            Expression ale1x = ale.e1;\n            ale1x = ale1x.modifiableLvalue(sc, exp.e1);\n            if (ale1x.op == TOK.error)\n            {\n                result = ale1x;\n                return;\n            }\n            ale.e1 = ale1x;\n\n            Type tn = ale.e1.type.toBasetype().nextOf();\n            checkDefCtor(ale.loc, tn);\n            semanticTypeInfo(sc, tn);\n        }\n        else if (exp.e1.op == TOK.slice)\n        {\n            Type tn = exp.e1.type.nextOf();\n            if (exp.op == TOK.assign && !tn.isMutable())\n            {\n                exp.error(\"slice `%s` is not mutable\", exp.e1.toChars());\n                return setError();\n            }\n\n            if (exp.op == TOK.assign && !tn.baseElemOf().isAssignable())\n            {\n                exp.error(\"slice `%s` is not mutable, struct `%s` has immutable members\",\n                    exp.e1.toChars(), tn.baseElemOf().toChars());\n                result = new ErrorExp();\n                return;\n            }\n\n            // For conditional operator, both branches need conversion.\n            SliceExp se = cast(SliceExp)exp.e1;\n            while (se.e1.op == TOK.slice)\n                se = cast(SliceExp)se.e1;\n            if (se.e1.op == TOK.question && se.e1.type.toBasetype().ty == Tsarray)\n            {\n                se.e1 = se.e1.modifiableLvalue(sc, exp.e1);\n                if (se.e1.op == TOK.error)\n                {\n                    result = se.e1;\n                    return;\n                }\n            }\n        }\n        else\n        {\n            if (t1.ty == Tsarray && exp.op == TOK.assign)\n            {\n                Type tn = exp.e1.type.nextOf();\n                if (tn && !tn.baseElemOf().isAssignable())\n                {\n                    exp.error(\"array `%s` is not mutable, struct `%s` has immutable members\",\n                        exp.e1.toChars(), tn.baseElemOf().toChars());\n                    result = new ErrorExp();\n                    return;\n                }\n            }\n\n            Expression e1x = exp.e1;\n\n            // Try to do a decent error message with the expression\n            // before it got constant folded\n\n            if (e1x.op != TOK.variable)\n                e1x = e1x.optimize(WANTvalue);\n\n            if (exp.op == TOK.assign)\n                e1x = e1x.modifiableLvalue(sc, e1old);\n\n            if (e1x.op == TOK.error)\n            {\n                result = e1x;\n                return;\n            }\n            exp.e1 = e1x;\n        }\n\n        /* Tweak e2 based on the type of e1.\n         */\n        Expression e2x = exp.e2;\n        Type t2 = e2x.type.toBasetype();\n\n        // If it is a array, get the element type. Note that it may be\n        // multi-dimensional.\n        Type telem = t1;\n        while (telem.ty == Tarray)\n            telem = telem.nextOf();\n\n        if (exp.e1.op == TOK.slice && t1.nextOf() &&\n            (telem.ty != Tvoid || e2x.op == TOK.null_) &&\n            e2x.implicitConvTo(t1.nextOf()))\n        {\n            // Check for block assignment. If it is of type void[], void[][], etc,\n            // '= null' is the only allowable block assignment (Bug 7493)\n            exp.memset |= MemorySet.blockAssign;    // make it easy for back end to tell what this is\n            e2x = e2x.implicitCastTo(sc, t1.nextOf());\n            if (exp.op != TOK.blit && e2x.isLvalue() && exp.e1.checkPostblit(sc, t1.nextOf()))\n                return setError();\n        }\n        else if (exp.e1.op == TOK.slice &&\n                 (t2.ty == Tarray || t2.ty == Tsarray) &&\n                 t2.nextOf().implicitConvTo(t1.nextOf()))\n        {\n            // Check element-wise assignment.\n\n            /* If assigned elements number is known at compile time,\n             * check the mismatch.\n             */\n            SliceExp se1 = cast(SliceExp)exp.e1;\n            TypeSArray tsa1 = cast(TypeSArray)toStaticArrayType(se1);\n            TypeSArray tsa2 = null;\n            if (e2x.op == TOK.arrayLiteral)\n                tsa2 = cast(TypeSArray)t2.nextOf().sarrayOf((cast(ArrayLiteralExp)e2x).elements.dim);\n            else if (e2x.op == TOK.slice)\n                tsa2 = cast(TypeSArray)toStaticArrayType(cast(SliceExp)e2x);\n            else if (t2.ty == Tsarray)\n                tsa2 = cast(TypeSArray)t2;\n            if (tsa1 && tsa2)\n            {\n                uinteger_t dim1 = tsa1.dim.toInteger();\n                uinteger_t dim2 = tsa2.dim.toInteger();\n                if (dim1 != dim2)\n                {\n                    exp.error(\"mismatched array lengths, %d and %d\", cast(int)dim1, cast(int)dim2);\n                    return setError();\n                }\n            }\n\n            if (exp.op != TOK.blit &&\n                (e2x.op == TOK.slice && (cast(UnaExp)e2x).e1.isLvalue() ||\n                 e2x.op == TOK.cast_ && (cast(UnaExp)e2x).e1.isLvalue() ||\n                 e2x.op != TOK.slice && e2x.isLvalue()))\n            {\n                if (exp.e1.checkPostblit(sc, t1.nextOf()))\n                    return setError();\n            }\n\n            if (0 && global.params.warnings != Diagnostic.off && !global.gag && exp.op == TOK.assign &&\n                e2x.op != TOK.slice && e2x.op != TOK.assign &&\n                e2x.op != TOK.arrayLiteral && e2x.op != TOK.string_ &&\n                !(e2x.op == TOK.add || e2x.op == TOK.min ||\n                  e2x.op == TOK.mul || e2x.op == TOK.div ||\n                  e2x.op == TOK.mod || e2x.op == TOK.xor ||\n                  e2x.op == TOK.and || e2x.op == TOK.or ||\n                  e2x.op == TOK.pow ||\n                  e2x.op == TOK.tilde || e2x.op == TOK.negate))\n            {\n                const(char)* e1str = exp.e1.toChars();\n                const(char)* e2str = e2x.toChars();\n                exp.warning(\"explicit element-wise assignment `%s = (%s)[]` is better than `%s = %s`\", e1str, e2str, e1str, e2str);\n            }\n\n            Type t2n = t2.nextOf();\n            Type t1n = t1.nextOf();\n            int offset;\n            if (t2n.equivalent(t1n) ||\n                t1n.isBaseOf(t2n, &offset) && offset == 0)\n            {\n                /* Allow copy of distinct qualifier elements.\n                 * eg.\n                 *  char[] dst;  const(char)[] src;\n                 *  dst[] = src;\n                 *\n                 *  class C {}   class D : C {}\n                 *  C[2] ca;  D[] da;\n                 *  ca[] = da;\n                 */\n                if (isArrayOpValid(e2x))\n                {\n                    // Don't add CastExp to keep AST for array operations\n                    e2x = e2x.copy();\n                    e2x.type = exp.e1.type.constOf();\n                }\n                else\n                    e2x = e2x.castTo(sc, exp.e1.type.constOf());\n            }\n            else\n            {\n                /* https://issues.dlang.org/show_bug.cgi?id=15778\n                 * A string literal has an array type of immutable\n                 * elements by default, and normally it cannot be convertible to\n                 * array type of mutable elements. But for element-wise assignment,\n                 * elements need to be const at best. So we should give a chance\n                 * to change code unit size for polysemous string literal.\n                 */\n                if (e2x.op == TOK.string_)\n                    e2x = e2x.implicitCastTo(sc, exp.e1.type.constOf());\n                else\n                    e2x = e2x.implicitCastTo(sc, exp.e1.type);\n            }\n            if (t1n.toBasetype.ty == Tvoid && t2n.toBasetype.ty == Tvoid)\n            {\n                if (!sc.intypeof && sc.func && sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n                {\n                    exp.error(\"cannot copy `void[]` to `void[]` in `@safe` code\");\n                    return setError();\n                }\n            }\n        }\n        else\n        {\n            if (0 && global.params.warnings != Diagnostic.off && !global.gag && exp.op == TOK.assign &&\n                t1.ty == Tarray && t2.ty == Tsarray &&\n                e2x.op != TOK.slice &&\n                t2.implicitConvTo(t1))\n            {\n                // Disallow ar[] = sa (Converted to ar[] = sa[])\n                // Disallow da   = sa (Converted to da   = sa[])\n                const(char)* e1str = exp.e1.toChars();\n                const(char)* e2str = e2x.toChars();\n                const(char)* atypestr = exp.e1.op == TOK.slice ? \"element-wise\" : \"slice\";\n                exp.warning(\"explicit %s assignment `%s = (%s)[]` is better than `%s = %s`\", atypestr, e1str, e2str, e1str, e2str);\n            }\n            if (exp.op == TOK.blit)\n                e2x = e2x.castTo(sc, exp.e1.type);\n            else\n            {\n                e2x = e2x.implicitCastTo(sc, exp.e1.type);\n\n                // Fix Issue 13435: https://issues.dlang.org/show_bug.cgi?id=13435\n\n                // If the implicit cast has failed and the assign expression is\n                // the initialization of a struct member field\n                if (e2x.op == TOK.error && exp.op == TOK.construct && t1.ty == Tstruct)\n                {\n                    scope sd = (cast(TypeStruct)t1).sym;\n                    Dsymbol opAssign = search_function(sd, Id.assign);\n\n                    // and the struct defines an opAssign\n                    if (opAssign)\n                    {\n                        // offer more information about the cause of the problem\n                        errorSupplemental(exp.loc,\n                                          \"`%s` is the first assignment of `%s` therefore it represents its initialization\",\n                                          exp.toChars(), exp.e1.toChars());\n                        errorSupplemental(exp.loc,\n                                          \"`opAssign` methods are not used for initialization, but for subsequent assignments\");\n                    }\n                }\n            }\n        }\n        if (e2x.op == TOK.error)\n        {\n            result = e2x;\n            return;\n        }\n        exp.e2 = e2x;\n        t2 = exp.e2.type.toBasetype();\n\n        /* Look for array operations\n         */\n        if ((t2.ty == Tarray || t2.ty == Tsarray) && isArrayOpValid(exp.e2))\n        {\n            // Look for valid array operations\n            if (!(exp.memset & MemorySet.blockAssign) &&\n                exp.e1.op == TOK.slice &&\n                (isUnaArrayOp(exp.e2.op) || isBinArrayOp(exp.e2.op)))\n            {\n                exp.type = exp.e1.type;\n                if (exp.op == TOK.construct) // https://issues.dlang.org/show_bug.cgi?id=10282\n                                        // tweak mutability of e1 element\n                    exp.e1.type = exp.e1.type.nextOf().mutableOf().arrayOf();\n                result = arrayOp(exp, sc);\n                return;\n            }\n\n            // Drop invalid array operations in e2\n            //  d = a[] + b[], d = (a[] + b[])[0..2], etc\n            if (checkNonAssignmentArrayOp(exp.e2, !(exp.memset & MemorySet.blockAssign) && exp.op == TOK.assign))\n                return setError();\n\n            // Remains valid array assignments\n            //  d = d[], d = [1,2,3], etc\n        }\n\n        /* Don't allow assignment to classes that were allocated on the stack with:\n         *      scope Class c = new Class();\n         */\n        if (exp.e1.op == TOK.variable && exp.op == TOK.assign)\n        {\n            VarExp ve = cast(VarExp)exp.e1;\n            VarDeclaration vd = ve.var.isVarDeclaration();\n            if (vd && (vd.onstack || vd.mynew))\n            {\n                assert(t1.ty == Tclass);\n                exp.error(\"cannot rebind scope variables\");\n            }\n        }\n\n        if (exp.e1.op == TOK.variable && (cast(VarExp)exp.e1).var.ident == Id.ctfe)\n        {\n            exp.error(\"cannot modify compiler-generated variable `__ctfe`\");\n        }\n\n        exp.type = exp.e1.type;\n        assert(exp.type);\n        auto res = exp.op == TOK.assign ? exp.reorderSettingAAElem(sc) : exp;\n        checkAssignEscape(sc, res, false);\n        result = res;\n    }\n\n    override void visit(PowAssignExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (exp.e1.checkReadModifyWrite(exp.op, exp.e2))\n            return setError();\n\n        assert(exp.e1.type && exp.e2.type);\n        if (exp.e1.op == TOK.slice || exp.e1.type.ty == Tarray || exp.e1.type.ty == Tsarray)\n        {\n            if (checkNonAssignmentArrayOp(exp.e1))\n                return setError();\n\n            // T[] ^^= ...\n            if (exp.e2.implicitConvTo(exp.e1.type.nextOf()))\n            {\n                // T[] ^^= T\n                exp.e2 = exp.e2.castTo(sc, exp.e1.type.nextOf());\n            }\n            else if (Expression ex = typeCombine(exp, sc))\n            {\n                result = ex;\n                return;\n            }\n\n            // Check element types are arithmetic\n            Type tb1 = exp.e1.type.nextOf().toBasetype();\n            Type tb2 = exp.e2.type.toBasetype();\n            if (tb2.ty == Tarray || tb2.ty == Tsarray)\n                tb2 = tb2.nextOf().toBasetype();\n            if ((tb1.isintegral() || tb1.isfloating()) && (tb2.isintegral() || tb2.isfloating()))\n            {\n                exp.type = exp.e1.type;\n                result = arrayOp(exp, sc);\n                return;\n            }\n        }\n        else\n        {\n            exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);\n        }\n\n        if ((exp.e1.type.isintegral() || exp.e1.type.isfloating()) && (exp.e2.type.isintegral() || exp.e2.type.isfloating()))\n        {\n            Expression e0 = null;\n            e = exp.reorderSettingAAElem(sc);\n            e = Expression.extractLast(e, e0);\n            assert(e == exp);\n\n            if (exp.e1.op == TOK.variable)\n            {\n                // Rewrite: e1 = e1 ^^ e2\n                e = new PowExp(exp.loc, exp.e1.syntaxCopy(), exp.e2);\n                e = new AssignExp(exp.loc, exp.e1, e);\n            }\n            else\n            {\n                // Rewrite: ref tmp = e1; tmp = tmp ^^ e2\n                auto v = copyToTemp(STC.ref_, \"__powtmp\", exp.e1);\n                auto de = new DeclarationExp(exp.e1.loc, v);\n                auto ve = new VarExp(exp.e1.loc, v);\n                e = new PowExp(exp.loc, ve, exp.e2);\n                e = new AssignExp(exp.loc, new VarExp(exp.e1.loc, v), e);\n                e = new CommaExp(exp.loc, de, e);\n            }\n            e = Expression.combine(e0, e);\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n        result = exp.incompatibleTypes();\n    }\n\n    override void visit(CatAssignExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        //printf(\"CatAssignExp::semantic() %s\\n\", exp.toChars());\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (exp.e1.op == TOK.slice)\n        {\n            SliceExp se = cast(SliceExp)exp.e1;\n            if (se.e1.type.toBasetype().ty == Tsarray)\n            {\n                exp.error(\"cannot append to static array `%s`\", se.e1.type.toChars());\n                return setError();\n            }\n        }\n\n        exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);\n        if (exp.e1.op == TOK.error)\n        {\n            result = exp.e1;\n            return;\n        }\n        if (exp.e2.op == TOK.error)\n        {\n            result = exp.e2;\n            return;\n        }\n\n        if (checkNonAssignmentArrayOp(exp.e2))\n            return setError();\n\n        Type tb1 = exp.e1.type.toBasetype();\n        Type tb1next = tb1.nextOf();\n        Type tb2 = exp.e2.type.toBasetype();\n\n        /* Possibilities:\n         * TOK.concatenateAssign: appending T[] to T[]\n         * TOK.concatenateElemAssign: appending T to T[]\n         * TOK.concatenateDcharAssign: appending dchar to T[]\n         */\n        if ((tb1.ty == Tarray) &&\n            (tb2.ty == Tarray || tb2.ty == Tsarray) &&\n            (exp.e2.implicitConvTo(exp.e1.type) ||\n             (tb2.nextOf().implicitConvTo(tb1next) &&\n              (tb2.nextOf().size(Loc.initial) == tb1next.size(Loc.initial)))))\n        {\n            // TOK.concatenateAssign\n            assert(exp.op == TOK.concatenateAssign);\n            if (exp.e1.checkPostblit(sc, tb1next))\n                return setError();\n\n            exp.e2 = exp.e2.castTo(sc, exp.e1.type);\n        }\n        else if ((tb1.ty == Tarray) && exp.e2.implicitConvTo(tb1next))\n        {\n            // Append element\n            if (exp.e2.checkPostblit(sc, tb2))\n                return setError();\n\n            if (checkNewEscape(sc, exp.e2, false))\n                return setError();\n\n            exp.op = TOK.concatenateElemAssign;\n            exp.e2 = exp.e2.castTo(sc, tb1next);\n            exp.e2 = doCopyOrMove(sc, exp.e2);\n        }\n        else if (tb1.ty == Tarray &&\n                 (tb1next.ty == Tchar || tb1next.ty == Twchar) &&\n                 exp.e2.type.ty != tb1next.ty &&\n                 exp.e2.implicitConvTo(Type.tdchar))\n        {\n            // Append dchar to char[] or wchar[]\n            exp.op = TOK.concatenateDcharAssign;\n            exp.e2 = exp.e2.castTo(sc, Type.tdchar);\n\n            /* Do not allow appending wchar to char[] because if wchar happens\n             * to be a surrogate pair, nothing good can result.\n             */\n        }\n        else\n        {\n            exp.error(\"cannot append type `%s` to type `%s`\", tb2.toChars(), tb1.toChars());\n            return setError();\n        }\n        if (exp.e2.checkValue())\n            return setError();\n\n        exp.type = exp.e1.type;\n        auto res = exp.reorderSettingAAElem(sc);\n        if ((exp.op == TOK.concatenateElemAssign || exp.op == TOK.concatenateDcharAssign) && global.params.vsafe)\n            checkAssignEscape(sc, res, false);\n        result = res;\n    }\n\n    override void visit(AddExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"AddExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        Type tb1 = exp.e1.type.toBasetype();\n        Type tb2 = exp.e2.type.toBasetype();\n\n        bool err = false;\n        if (tb1.ty == Tdelegate || tb1.ty == Tpointer && tb1.nextOf().ty == Tfunction)\n        {\n            err |= exp.e1.checkArithmetic();\n        }\n        if (tb2.ty == Tdelegate || tb2.ty == Tpointer && tb2.nextOf().ty == Tfunction)\n        {\n            err |= exp.e2.checkArithmetic();\n        }\n        if (err)\n            return setError();\n\n        if (tb1.ty == Tpointer && exp.e2.type.isintegral() || tb2.ty == Tpointer && exp.e1.type.isintegral())\n        {\n            result = scaleFactor(exp, sc);\n            return;\n        }\n\n        if (tb1.ty == Tpointer && tb2.ty == Tpointer)\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tarray || tb.ty == Tsarray)\n        {\n            if (!isArrayOpValid(exp))\n            {\n                result = arrayOpInvalidError(exp);\n                return;\n            }\n            result = exp;\n            return;\n        }\n\n        tb1 = exp.e1.type.toBasetype();\n        if (!Target.isVectorOpSupported(tb1, exp.op, tb2))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        if ((tb1.isreal() && exp.e2.type.isimaginary()) || (tb1.isimaginary() && exp.e2.type.isreal()))\n        {\n            switch (exp.type.toBasetype().ty)\n            {\n            case Tfloat32:\n            case Timaginary32:\n                exp.type = Type.tcomplex32;\n                break;\n\n            case Tfloat64:\n            case Timaginary64:\n                exp.type = Type.tcomplex64;\n                break;\n\n            case Tfloat80:\n            case Timaginary80:\n                exp.type = Type.tcomplex80;\n                break;\n\n            default:\n                assert(0);\n            }\n        }\n        result = exp;\n    }\n\n    override void visit(MinExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"MinExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        Type t1 = exp.e1.type.toBasetype();\n        Type t2 = exp.e2.type.toBasetype();\n\n        bool err = false;\n        if (t1.ty == Tdelegate || t1.ty == Tpointer && t1.nextOf().ty == Tfunction)\n        {\n            err |= exp.e1.checkArithmetic();\n        }\n        if (t2.ty == Tdelegate || t2.ty == Tpointer && t2.nextOf().ty == Tfunction)\n        {\n            err |= exp.e2.checkArithmetic();\n        }\n        if (err)\n            return setError();\n\n        if (t1.ty == Tpointer)\n        {\n            if (t2.ty == Tpointer)\n            {\n                // https://dlang.org/spec/expression.html#add_expressions\n                // \"If both operands are pointers, and the operator is -, the pointers are\n                // subtracted and the result is divided by the size of the type pointed to\n                // by the operands. It is an error if the pointers point to different types.\"\n                Type p1 = t1.nextOf();\n                Type p2 = t2.nextOf();\n\n                if (!p1.equivalent(p2))\n                {\n                    // Deprecation to remain for at least a year, after which this should be\n                    // changed to an error\n                    // See https://github.com/dlang/dmd/pull/7332\n                    deprecation(exp.loc,\n                        \"cannot subtract pointers to different types: `%s` and `%s`.\",\n                        t1.toChars(), t2.toChars());\n                }\n\n                // Need to divide the result by the stride\n                // Replace (ptr - ptr) with (ptr - ptr) / stride\n                d_int64 stride;\n\n                // make sure pointer types are compatible\n                if (Expression ex = typeCombine(exp, sc))\n                {\n                    result = ex;\n                    return;\n                }\n\n                exp.type = Type.tptrdiff_t;\n                stride = t2.nextOf().size();\n                if (stride == 0)\n                {\n                    e = new IntegerExp(exp.loc, 0, Type.tptrdiff_t);\n                }\n                else\n                {\n                    e = new DivExp(exp.loc, exp, new IntegerExp(Loc.initial, stride, Type.tptrdiff_t));\n                    e.type = Type.tptrdiff_t;\n                }\n            }\n            else if (t2.isintegral())\n                e = scaleFactor(exp, sc);\n            else\n            {\n                exp.error(\"can't subtract `%s` from pointer\", t2.toChars());\n                e = new ErrorExp();\n            }\n            result = e;\n            return;\n        }\n        if (t2.ty == Tpointer)\n        {\n            exp.type = exp.e2.type;\n            exp.error(\"can't subtract pointer from `%s`\", exp.e1.type.toChars());\n            return setError();\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tarray || tb.ty == Tsarray)\n        {\n            if (!isArrayOpValid(exp))\n            {\n                result = arrayOpInvalidError(exp);\n                return;\n            }\n            result = exp;\n            return;\n        }\n\n        t1 = exp.e1.type.toBasetype();\n        t2 = exp.e2.type.toBasetype();\n        if (!Target.isVectorOpSupported(t1, exp.op, t2))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        if ((t1.isreal() && t2.isimaginary()) || (t1.isimaginary() && t2.isreal()))\n        {\n            switch (exp.type.ty)\n            {\n            case Tfloat32:\n            case Timaginary32:\n                exp.type = Type.tcomplex32;\n                break;\n\n            case Tfloat64:\n            case Timaginary64:\n                exp.type = Type.tcomplex64;\n                break;\n\n            case Tfloat80:\n            case Timaginary80:\n                exp.type = Type.tcomplex80;\n                break;\n\n            default:\n                assert(0);\n            }\n        }\n        result = exp;\n        return;\n    }\n\n    override void visit(CatExp exp)\n    {\n        // https://dlang.org/spec/expression.html#cat_expressions\n        //printf(\"CatExp.semantic() %s\\n\", toChars());\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        Type tb1 = exp.e1.type.toBasetype();\n        Type tb2 = exp.e2.type.toBasetype();\n\n        auto f1 = checkNonAssignmentArrayOp(exp.e1);\n        auto f2 = checkNonAssignmentArrayOp(exp.e2);\n        if (f1 || f2)\n            return setError();\n\n        /* BUG: Should handle things like:\n         *      char c;\n         *      c ~ ' '\n         *      ' ' ~ c;\n         */\n\n        Type tb1next = tb1.nextOf();\n        Type tb2next = tb2.nextOf();\n\n        // Check for: array ~ array\n        if (tb1next && tb2next && (tb1next.implicitConvTo(tb2next) >= MATCH.constant || tb2next.implicitConvTo(tb1next) >= MATCH.constant || exp.e1.op == TOK.arrayLiteral && exp.e1.implicitConvTo(tb2) || exp.e2.op == TOK.arrayLiteral && exp.e2.implicitConvTo(tb1)))\n        {\n            /* https://issues.dlang.org/show_bug.cgi?id=9248\n             * Here to avoid the case of:\n             *    void*[] a = [cast(void*)1];\n             *    void*[] b = [cast(void*)2];\n             *    a ~ b;\n             * becoming:\n             *    a ~ [cast(void*)b];\n             */\n\n            /* https://issues.dlang.org/show_bug.cgi?id=14682\n             * Also to avoid the case of:\n             *    int[][] a;\n             *    a ~ [];\n             * becoming:\n             *    a ~ cast(int[])[];\n             */\n            goto Lpeer;\n        }\n\n        // Check for: array ~ element\n        if ((tb1.ty == Tsarray || tb1.ty == Tarray) && tb2.ty != Tvoid)\n        {\n            if (exp.e1.op == TOK.arrayLiteral)\n            {\n                exp.e2 = doCopyOrMove(sc, exp.e2);\n                // https://issues.dlang.org/show_bug.cgi?id=14686\n                // Postblit call appears in AST, and this is\n                // finally translated  to an ArrayLiteralExp in below optimize().\n            }\n            else if (exp.e1.op == TOK.string_)\n            {\n                // No postblit call exists on character (integer) value.\n            }\n            else\n            {\n                if (exp.e2.checkPostblit(sc, tb2))\n                    return setError();\n                // Postblit call will be done in runtime helper function\n            }\n\n            if (exp.e1.op == TOK.arrayLiteral && exp.e1.implicitConvTo(tb2.arrayOf()))\n            {\n                exp.e1 = exp.e1.implicitCastTo(sc, tb2.arrayOf());\n                exp.type = tb2.arrayOf();\n                goto L2elem;\n            }\n            if (exp.e2.implicitConvTo(tb1next) >= MATCH.convert)\n            {\n                exp.e2 = exp.e2.implicitCastTo(sc, tb1next);\n                exp.type = tb1next.arrayOf();\n            L2elem:\n                if (tb2.ty == Tarray || tb2.ty == Tsarray)\n                {\n                    // Make e2 into [e2]\n                    exp.e2 = new ArrayLiteralExp(exp.e2.loc, exp.type, exp.e2);\n                }\n                else if (checkNewEscape(sc, exp.e2, false))\n                    return setError();\n                result = exp.optimize(WANTvalue);\n                return;\n            }\n        }\n        // Check for: element ~ array\n        if ((tb2.ty == Tsarray || tb2.ty == Tarray) && tb1.ty != Tvoid)\n        {\n            if (exp.e2.op == TOK.arrayLiteral)\n            {\n                exp.e1 = doCopyOrMove(sc, exp.e1);\n            }\n            else if (exp.e2.op == TOK.string_)\n            {\n            }\n            else\n            {\n                if (exp.e1.checkPostblit(sc, tb1))\n                    return setError();\n            }\n\n            if (exp.e2.op == TOK.arrayLiteral && exp.e2.implicitConvTo(tb1.arrayOf()))\n            {\n                exp.e2 = exp.e2.implicitCastTo(sc, tb1.arrayOf());\n                exp.type = tb1.arrayOf();\n                goto L1elem;\n            }\n            if (exp.e1.implicitConvTo(tb2next) >= MATCH.convert)\n            {\n                exp.e1 = exp.e1.implicitCastTo(sc, tb2next);\n                exp.type = tb2next.arrayOf();\n            L1elem:\n                if (tb1.ty == Tarray || tb1.ty == Tsarray)\n                {\n                    // Make e1 into [e1]\n                    exp.e1 = new ArrayLiteralExp(exp.e1.loc, exp.type, exp.e1);\n                }\n                else if (checkNewEscape(sc, exp.e1, false))\n                    return setError();\n                result = exp.optimize(WANTvalue);\n                return;\n            }\n        }\n\n    Lpeer:\n        if ((tb1.ty == Tsarray || tb1.ty == Tarray) && (tb2.ty == Tsarray || tb2.ty == Tarray) && (tb1next.mod || tb2next.mod) && (tb1next.mod != tb2next.mod))\n        {\n            Type t1 = tb1next.mutableOf().constOf().arrayOf();\n            Type t2 = tb2next.mutableOf().constOf().arrayOf();\n            if (exp.e1.op == TOK.string_ && !(cast(StringExp)exp.e1).committed)\n                exp.e1.type = t1;\n            else\n                exp.e1 = exp.e1.castTo(sc, t1);\n            if (exp.e2.op == TOK.string_ && !(cast(StringExp)exp.e2).committed)\n                exp.e2.type = t2;\n            else\n                exp.e2 = exp.e2.castTo(sc, t2);\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        exp.type = exp.type.toHeadMutable();\n\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tsarray)\n            exp.type = tb.nextOf().arrayOf();\n        if (exp.type.ty == Tarray && tb1next && tb2next && tb1next.mod != tb2next.mod)\n        {\n            exp.type = exp.type.nextOf().toHeadMutable().arrayOf();\n        }\n        if (Type tbn = tb.nextOf())\n        {\n            if (exp.checkPostblit(sc, tbn))\n                return setError();\n        }\n        Type t1 = exp.e1.type.toBasetype();\n        Type t2 = exp.e2.type.toBasetype();\n        if ((t1.ty == Tarray || t1.ty == Tsarray) &&\n            (t2.ty == Tarray || t2.ty == Tsarray))\n        {\n            // Normalize to ArrayLiteralExp or StringExp as far as possible\n            e = exp.optimize(WANTvalue);\n        }\n        else\n        {\n            //printf(\"(%s) ~ (%s)\\n\", e1.toChars(), e2.toChars());\n            result = exp.incompatibleTypes();\n            return;\n        }\n\n        result = e;\n    }\n\n    override void visit(MulExp exp)\n    {\n        version (none)\n        {\n            printf(\"MulExp::semantic() %s\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tarray || tb.ty == Tsarray)\n        {\n            if (!isArrayOpValid(exp))\n            {\n                result = arrayOpInvalidError(exp);\n                return;\n            }\n            result = exp;\n            return;\n        }\n\n        if (exp.checkArithmeticBin())\n            return setError();\n\n        if (exp.type.isfloating())\n        {\n            Type t1 = exp.e1.type;\n            Type t2 = exp.e2.type;\n\n            if (t1.isreal())\n            {\n                exp.type = t2;\n            }\n            else if (t2.isreal())\n            {\n                exp.type = t1;\n            }\n            else if (t1.isimaginary())\n            {\n                if (t2.isimaginary())\n                {\n                    switch (t1.toBasetype().ty)\n                    {\n                    case Timaginary32:\n                        exp.type = Type.tfloat32;\n                        break;\n\n                    case Timaginary64:\n                        exp.type = Type.tfloat64;\n                        break;\n\n                    case Timaginary80:\n                        exp.type = Type.tfloat80;\n                        break;\n\n                    default:\n                        assert(0);\n                    }\n\n                    // iy * iv = -yv\n                    exp.e1.type = exp.type;\n                    exp.e2.type = exp.type;\n                    e = new NegExp(exp.loc, exp);\n                    e = e.expressionSemantic(sc);\n                    result = e;\n                    return;\n                }\n                else\n                    exp.type = t2; // t2 is complex\n            }\n            else if (t2.isimaginary())\n            {\n                exp.type = t1; // t1 is complex\n            }\n        }\n        else if (!Target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        result = exp;\n    }\n\n    override void visit(DivExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tarray || tb.ty == Tsarray)\n        {\n            if (!isArrayOpValid(exp))\n            {\n                result = arrayOpInvalidError(exp);\n                return;\n            }\n            result = exp;\n            return;\n        }\n\n        if (exp.checkArithmeticBin())\n            return setError();\n\n        if (exp.type.isfloating())\n        {\n            Type t1 = exp.e1.type;\n            Type t2 = exp.e2.type;\n\n            if (t1.isreal())\n            {\n                exp.type = t2;\n                if (t2.isimaginary())\n                {\n                    // x/iv = i(-x/v)\n                    exp.e2.type = t1;\n                    e = new NegExp(exp.loc, exp);\n                    e = e.expressionSemantic(sc);\n                    result = e;\n                    return;\n                }\n            }\n            else if (t2.isreal())\n            {\n                exp.type = t1;\n            }\n            else if (t1.isimaginary())\n            {\n                if (t2.isimaginary())\n                {\n                    switch (t1.toBasetype().ty)\n                    {\n                    case Timaginary32:\n                        exp.type = Type.tfloat32;\n                        break;\n\n                    case Timaginary64:\n                        exp.type = Type.tfloat64;\n                        break;\n\n                    case Timaginary80:\n                        exp.type = Type.tfloat80;\n                        break;\n\n                    default:\n                        assert(0);\n                    }\n                }\n                else\n                    exp.type = t2; // t2 is complex\n            }\n            else if (t2.isimaginary())\n            {\n                exp.type = t1; // t1 is complex\n            }\n        }\n        else if (!Target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        result = exp;\n    }\n\n    override void visit(ModExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tarray || tb.ty == Tsarray)\n        {\n            if (!isArrayOpValid(exp))\n            {\n                result = arrayOpInvalidError(exp);\n                return;\n            }\n            result = exp;\n            return;\n        }\n        if (!Target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n\n        if (exp.checkArithmeticBin())\n            return setError();\n\n        if (exp.type.isfloating())\n        {\n            exp.type = exp.e1.type;\n            if (exp.e2.type.iscomplex())\n            {\n                exp.error(\"cannot perform modulo complex arithmetic\");\n                return setError();\n            }\n        }\n        result = exp;\n    }\n\n    override void visit(PowExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        //printf(\"PowExp::semantic() %s\\n\", toChars());\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tarray || tb.ty == Tsarray)\n        {\n            if (!isArrayOpValid(exp))\n            {\n                result = arrayOpInvalidError(exp);\n                return;\n            }\n            result = exp;\n            return;\n        }\n\n        if (exp.checkArithmeticBin())\n            return setError();\n\n        if (!Target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n\n        // For built-in numeric types, there are several cases.\n        // TODO: backend support, especially for  e1 ^^ 2.\n\n        // First, attempt to fold the expression.\n        e = exp.optimize(WANTvalue);\n        if (e.op != TOK.pow)\n        {\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n\n        // Determine if we're raising to an integer power.\n        sinteger_t intpow = 0;\n        if (exp.e2.op == TOK.int64 && (cast(sinteger_t)exp.e2.toInteger() == 2 || cast(sinteger_t)exp.e2.toInteger() == 3))\n            intpow = exp.e2.toInteger();\n        else if (exp.e2.op == TOK.float64 && (exp.e2.toReal() == real_t(cast(sinteger_t)exp.e2.toReal())))\n            intpow = cast(sinteger_t)exp.e2.toReal();\n\n        // Deal with x^^2, x^^3 immediately, since they are of practical importance.\n        if (intpow == 2 || intpow == 3)\n        {\n            // Replace x^^2 with (tmp = x, tmp*tmp)\n            // Replace x^^3 with (tmp = x, tmp*tmp*tmp)\n            auto tmp = copyToTemp(0, \"__powtmp\", exp.e1);\n            Expression de = new DeclarationExp(exp.loc, tmp);\n            Expression ve = new VarExp(exp.loc, tmp);\n\n            /* Note that we're reusing ve. This should be ok.\n             */\n            Expression me = new MulExp(exp.loc, ve, ve);\n            if (intpow == 3)\n                me = new MulExp(exp.loc, me, ve);\n            e = new CommaExp(exp.loc, de, me);\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n\n        Module mmath = loadStdMath();\n        if (!mmath)\n        {\n            e.error(\"`%s` requires `std.math` for `^^` operators\", e.toChars());\n            return setError();\n        }\n        e = new ScopeExp(exp.loc, mmath);\n\n        if (exp.e2.op == TOK.float64 && exp.e2.toReal() == CTFloat.half)\n        {\n            // Replace e1 ^^ 0.5 with .std.math.sqrt(x)\n            e = new CallExp(exp.loc, new DotIdExp(exp.loc, e, Id._sqrt), exp.e1);\n        }\n        else\n        {\n            // Replace e1 ^^ e2 with .std.math.pow(e1, e2)\n            e = new CallExp(exp.loc, new DotIdExp(exp.loc, e, Id._pow), exp.e1, exp.e2);\n        }\n        e = e.expressionSemantic(sc);\n        result = e;\n        return;\n    }\n\n    override void visit(ShlExp exp)\n    {\n        //printf(\"ShlExp::semantic(), type = %p\\n\", type);\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (exp.checkIntegralBin())\n            return setError();\n\n        if (!Target.isVectorOpSupported(exp.e1.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        exp.e1 = integralPromotions(exp.e1, sc);\n        if (exp.e2.type.toBasetype().ty != Tvector)\n            exp.e2 = exp.e2.castTo(sc, Type.tshiftcnt);\n\n        exp.type = exp.e1.type;\n        result = exp;\n    }\n\n    override void visit(ShrExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (exp.checkIntegralBin())\n            return setError();\n\n        if (!Target.isVectorOpSupported(exp.e1.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        exp.e1 = integralPromotions(exp.e1, sc);\n        if (exp.e2.type.toBasetype().ty != Tvector)\n            exp.e2 = exp.e2.castTo(sc, Type.tshiftcnt);\n\n        exp.type = exp.e1.type;\n        result = exp;\n    }\n\n    override void visit(UshrExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (exp.checkIntegralBin())\n            return setError();\n\n        if (!Target.isVectorOpSupported(exp.e1.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        exp.e1 = integralPromotions(exp.e1, sc);\n        if (exp.e2.type.toBasetype().ty != Tvector)\n            exp.e2 = exp.e2.castTo(sc, Type.tshiftcnt);\n\n        exp.type = exp.e1.type;\n        result = exp;\n    }\n\n    override void visit(AndExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (exp.e1.type.toBasetype().ty == Tbool && exp.e2.type.toBasetype().ty == Tbool)\n        {\n            exp.type = exp.e1.type;\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tarray || tb.ty == Tsarray)\n        {\n            if (!isArrayOpValid(exp))\n            {\n                result = arrayOpInvalidError(exp);\n                return;\n            }\n            result = exp;\n            return;\n        }\n        if (!Target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        if (exp.checkIntegralBin())\n            return setError();\n\n        result = exp;\n    }\n\n    override void visit(OrExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (exp.e1.type.toBasetype().ty == Tbool && exp.e2.type.toBasetype().ty == Tbool)\n        {\n            exp.type = exp.e1.type;\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tarray || tb.ty == Tsarray)\n        {\n            if (!isArrayOpValid(exp))\n            {\n                result = arrayOpInvalidError(exp);\n                return;\n            }\n            result = exp;\n            return;\n        }\n        if (!Target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        if (exp.checkIntegralBin())\n            return setError();\n\n        result = exp;\n    }\n\n    override void visit(XorExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        if (exp.e1.type.toBasetype().ty == Tbool && exp.e2.type.toBasetype().ty == Tbool)\n        {\n            exp.type = exp.e1.type;\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        Type tb = exp.type.toBasetype();\n        if (tb.ty == Tarray || tb.ty == Tsarray)\n        {\n            if (!isArrayOpValid(exp))\n            {\n                result = arrayOpInvalidError(exp);\n                return;\n            }\n            result = exp;\n            return;\n        }\n        if (!Target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        if (exp.checkIntegralBin())\n            return setError();\n\n        result = exp;\n    }\n\n    override void visit(LogicalExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        exp.setNoderefOperands();\n\n        Expression e1x = exp.e1.expressionSemantic(sc);\n\n        // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684\n        if (e1x.op == TOK.type)\n            e1x = resolveAliasThis(sc, e1x);\n\n        e1x = resolveProperties(sc, e1x);\n        e1x = e1x.toBoolean(sc);\n\n        if (sc.flags & SCOPE.condition)\n        {\n            /* If in static if, don't evaluate e2 if we don't have to.\n             */\n            e1x = e1x.optimize(WANTvalue);\n            if (e1x.isBool(exp.op == TOK.orOr))\n            {\n                result = new IntegerExp(exp.loc, exp.op == TOK.orOr, Type.tbool);\n                return;\n            }\n        }\n\n        CtorFlow ctorflow = sc.ctorflow.clone();\n        Expression e2x = exp.e2.expressionSemantic(sc);\n        sc.merge(exp.loc, ctorflow);\n        ctorflow.freeFieldinit();\n\n        // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684\n        if (e2x.op == TOK.type)\n            e2x = resolveAliasThis(sc, e2x);\n\n        e2x = resolveProperties(sc, e2x);\n\n        auto f1 = checkNonAssignmentArrayOp(e1x);\n        auto f2 = checkNonAssignmentArrayOp(e2x);\n        if (f1 || f2)\n            return setError();\n\n        // Unless the right operand is 'void', the expression is converted to 'bool'.\n        if (e2x.type.ty != Tvoid)\n            e2x = e2x.toBoolean(sc);\n\n        if (e2x.op == TOK.type || e2x.op == TOK.scope_)\n        {\n            exp.error(\"`%s` is not an expression\", exp.e2.toChars());\n            return setError();\n        }\n        if (e1x.op == TOK.error)\n        {\n            result = e1x;\n            return;\n        }\n        if (e2x.op == TOK.error)\n        {\n            result = e2x;\n            return;\n        }\n\n        // The result type is 'bool', unless the right operand has type 'void'.\n        if (e2x.type.ty == Tvoid)\n            exp.type = Type.tvoid;\n        else\n            exp.type = Type.tbool;\n\n        exp.e1 = e1x;\n        exp.e2 = e2x;\n        result = exp;\n    }\n\n\n    override void visit(CmpExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"CmpExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        exp.setNoderefOperands();\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Type t1 = exp.e1.type.toBasetype();\n        Type t2 = exp.e2.type.toBasetype();\n        if (t1.ty == Tclass && exp.e2.op == TOK.null_ || t2.ty == Tclass && exp.e1.op == TOK.null_)\n        {\n            exp.error(\"do not use `null` when comparing class types\");\n            return setError();\n        }\n\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            if (!e.type.isscalar() && e.type.equals(exp.e1.type))\n            {\n                exp.error(\"recursive `opCmp` expansion\");\n                return setError();\n            }\n            if (e.op == TOK.call)\n            {\n                e = new CmpExp(exp.op, exp.loc, e, new IntegerExp(exp.loc, 0, Type.tint32));\n                e = e.expressionSemantic(sc);\n            }\n            result = e;\n            return;\n        }\n\n        if (Expression ex = typeCombine(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n\n        auto f1 = checkNonAssignmentArrayOp(exp.e1);\n        auto f2 = checkNonAssignmentArrayOp(exp.e2);\n        if (f1 || f2)\n            return setError();\n\n        exp.type = Type.tbool;\n\n        // Special handling for array comparisons\n        Expression arrayLowering = null;\n        t1 = exp.e1.type.toBasetype();\n        t2 = exp.e2.type.toBasetype();\n        if ((t1.ty == Tarray || t1.ty == Tsarray || t1.ty == Tpointer) && (t2.ty == Tarray || t2.ty == Tsarray || t2.ty == Tpointer))\n        {\n            Type t1next = t1.nextOf();\n            Type t2next = t2.nextOf();\n            if (t1next.implicitConvTo(t2next) < MATCH.constant && t2next.implicitConvTo(t1next) < MATCH.constant && (t1next.ty != Tvoid && t2next.ty != Tvoid))\n            {\n                exp.error(\"array comparison type mismatch, `%s` vs `%s`\", t1next.toChars(), t2next.toChars());\n                return setError();\n            }\n            if ((t1.ty == Tarray || t1.ty == Tsarray) && (t2.ty == Tarray || t2.ty == Tsarray))\n            {\n                // Lower to object.__cmp(e1, e2)\n                Expression al = new IdentifierExp(exp.loc, Id.empty);\n                al = new DotIdExp(exp.loc, al, Id.object);\n                al = new DotIdExp(exp.loc, al, Id.__cmp);\n                al = al.expressionSemantic(sc);\n\n                auto arguments = new Expressions();\n                arguments.push(exp.e1);\n                arguments.push(exp.e2);\n\n                al = new CallExp(exp.loc, al, arguments);\n                al = new CmpExp(exp.op, exp.loc, al, new IntegerExp(0));\n\n                arrayLowering = al;\n            }\n        }\n        else if (t1.ty == Tstruct || t2.ty == Tstruct || (t1.ty == Tclass && t2.ty == Tclass))\n        {\n            if (t2.ty == Tstruct)\n                exp.error(\"need member function `opCmp()` for %s `%s` to compare\", t2.toDsymbol(sc).kind(), t2.toChars());\n            else\n                exp.error(\"need member function `opCmp()` for %s `%s` to compare\", t1.toDsymbol(sc).kind(), t1.toChars());\n            return setError();\n        }\n        else if (t1.iscomplex() || t2.iscomplex())\n        {\n            exp.error(\"compare not defined for complex operands\");\n            return setError();\n        }\n        else if (t1.ty == Taarray || t2.ty == Taarray)\n        {\n            exp.error(\"`%s` is not defined for associative arrays\", Token.toChars(exp.op));\n            return setError();\n        }\n        else if (!Target.isVectorOpSupported(t1, exp.op, t2))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n        else\n        {\n            bool r1 = exp.e1.checkValue();\n            bool r2 = exp.e2.checkValue();\n            if (r1 || r2)\n                return setError();\n        }\n\n        //printf(\"CmpExp: %s, type = %s\\n\", e.toChars(), e.type.toChars());\n        if (arrayLowering)\n        {\n            arrayLowering = arrayLowering.expressionSemantic(sc);\n            result = arrayLowering;\n            return;\n        }\n        result = exp;\n        return;\n    }\n\n    override void visit(InExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (Expression ex = binSemanticProp(exp, sc))\n        {\n            result = ex;\n            return;\n        }\n        Expression e = exp.op_overload(sc);\n        if (e)\n        {\n            result = e;\n            return;\n        }\n\n        Type t2b = exp.e2.type.toBasetype();\n        switch (t2b.ty)\n        {\n        case Taarray:\n            {\n                TypeAArray ta = cast(TypeAArray)t2b;\n\n                // Special handling for array keys\n                if (!arrayTypeCompatibleWithoutCasting(exp.e1.type, ta.index))\n                {\n                    // Convert key to type of key\n                    exp.e1 = exp.e1.implicitCastTo(sc, ta.index);\n                }\n\n                semanticTypeInfo(sc, ta.index);\n\n                // Return type is pointer to value\n                exp.type = ta.nextOf().pointerTo();\n                break;\n            }\n\n        case Terror:\n            return setError();\n\n        default:\n            result = exp.incompatibleTypes();\n            return;\n        }\n        result = exp;\n    }\n\n    override void visit(RemoveExp e)\n    {\n        if (Expression ex = binSemantic(e, sc))\n        {\n            result = ex;\n            return;\n        }\n        result = e;\n    }\n\n    override void visit(EqualExp exp)\n    {\n        //printf(\"EqualExp::semantic('%s')\\n\", exp.toChars());\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        exp.setNoderefOperands();\n\n        if (auto e = binSemanticProp(exp, sc))\n        {\n            result = e;\n            return;\n        }\n        if (exp.e1.op == TOK.type || exp.e2.op == TOK.type)\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n\n        {\n            auto t1 = exp.e1.type;\n            auto t2 = exp.e2.type;\n            if (t1.ty == Tenum && t2.ty == Tenum && !t1.equivalent(t2))\n                exp.error(\"Comparison between different enumeration types `%s` and `%s`; If this behavior is intended consider using `std.conv.asOriginalType`\",\n                    t1.toChars(), t2.toChars());\n        }\n\n        /* Before checking for operator overloading, check to see if we're\n         * comparing the addresses of two statics. If so, we can just see\n         * if they are the same symbol.\n         */\n        if (exp.e1.op == TOK.address && exp.e2.op == TOK.address)\n        {\n            AddrExp ae1 = cast(AddrExp)exp.e1;\n            AddrExp ae2 = cast(AddrExp)exp.e2;\n            if (ae1.e1.op == TOK.variable && ae2.e1.op == TOK.variable)\n            {\n                VarExp ve1 = cast(VarExp)ae1.e1;\n                VarExp ve2 = cast(VarExp)ae2.e1;\n                if (ve1.var == ve2.var)\n                {\n                    // They are the same, result is 'true' for ==, 'false' for !=\n                    result = new IntegerExp(exp.loc, (exp.op == TOK.equal), Type.tbool);\n                    return;\n                }\n            }\n        }\n\n        Type t1 = exp.e1.type.toBasetype();\n        Type t2 = exp.e2.type.toBasetype();\n\n        bool needsDirectEq(Type t1, Type t2)\n        {\n            Type t1n = t1.nextOf().toBasetype();\n            Type t2n = t2.nextOf().toBasetype();\n            if (((t1n.ty == Tchar || t1n.ty == Twchar || t1n.ty == Tdchar) &&\n                 (t2n.ty == Tchar || t2n.ty == Twchar || t2n.ty == Tdchar)) ||\n                (t1n.ty == Tvoid || t2n.ty == Tvoid))\n            {\n                return false;\n            }\n            if (t1n.constOf() != t2n.constOf())\n                return true;\n\n            Type t = t1n;\n            while (t.toBasetype().nextOf())\n                t = t.nextOf().toBasetype();\n            if (t.ty != Tstruct)\n                return false;\n\n            if (global.params.useTypeInfo && Type.dtypeinfo)\n                semanticTypeInfo(sc, t);\n\n            return (cast(TypeStruct)t).sym.hasIdentityEquals;\n        }\n\n        if (auto e = exp.op_overload(sc))\n        {\n            result = e;\n            return;\n        }\n\n\n        if (!(t1.ty == Tarray && t2.ty == Tarray && needsDirectEq(t1, t2)))\n        {\n            if (auto e = typeCombine(exp, sc))\n            {\n                result = e;\n                return;\n            }\n        }\n\n        auto f1 = checkNonAssignmentArrayOp(exp.e1);\n        auto f2 = checkNonAssignmentArrayOp(exp.e2);\n        if (f1 || f2)\n            return setError();\n\n        exp.type = Type.tbool;\n\n        // Special handling for array comparisons\n        if (!(t1.ty == Tarray && t2.ty == Tarray && needsDirectEq(t1, t2)))\n        {\n            if (!arrayTypeCompatible(exp.loc, exp.e1.type, exp.e2.type))\n            {\n                if (exp.e1.type != exp.e2.type && exp.e1.type.isfloating() && exp.e2.type.isfloating())\n                {\n                    // Cast both to complex\n                    exp.e1 = exp.e1.castTo(sc, Type.tcomplex80);\n                    exp.e2 = exp.e2.castTo(sc, Type.tcomplex80);\n                }\n            }\n        }\n\n        if (t1.ty == Tarray && t2.ty == Tarray)\n        {\n            //printf(\"Lowering to __equals %s %s\\n\", e1.toChars(), e2.toChars());\n\n            // For e1 and e2 of struct type, lowers e1 == e2 to object.__equals(e1, e2)\n            // and e1 != e2 to !(object.__equals(e1, e2)).\n\n            Expression __equals = new IdentifierExp(exp.loc, Id.empty);\n            Identifier id = Identifier.idPool(\"__equals\");\n            __equals = new DotIdExp(exp.loc, __equals, Id.object);\n            __equals = new DotIdExp(exp.loc, __equals, id);\n\n            auto arguments = new Expressions();\n            arguments.push(exp.e1);\n            arguments.push(exp.e2);\n\n            __equals = new CallExp(exp.loc, __equals, arguments);\n            if (exp.op == TOK.notEqual)\n            {\n                __equals = new NotExp(exp.loc, __equals);\n            }\n            __equals = __equals.expressionSemantic(sc);\n\n            result = __equals;\n            return;\n        }\n\n        if (exp.e1.type.toBasetype().ty == Taarray)\n            semanticTypeInfo(sc, exp.e1.type.toBasetype());\n\n\n        if (!Target.isVectorOpSupported(t1, exp.op, t2))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n\n        result = exp;\n    }\n\n    override void visit(IdentityExp exp)\n    {\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        exp.setNoderefOperands();\n\n        if (auto e = binSemanticProp(exp, sc))\n        {\n            result = e;\n            return;\n        }\n\n        if (auto e = typeCombine(exp, sc))\n        {\n            result = e;\n            return;\n        }\n\n        auto f1 = checkNonAssignmentArrayOp(exp.e1);\n        auto f2 = checkNonAssignmentArrayOp(exp.e2);\n        if (f1 || f2)\n            return setError();\n\n        exp.type = Type.tbool;\n\n        if (exp.e1.type != exp.e2.type && exp.e1.type.isfloating() && exp.e2.type.isfloating())\n        {\n            // Cast both to complex\n            exp.e1 = exp.e1.castTo(sc, Type.tcomplex80);\n            exp.e2 = exp.e2.castTo(sc, Type.tcomplex80);\n        }\n\n        auto tb1 = exp.e1.type.toBasetype();\n        auto tb2 = exp.e2.type.toBasetype();\n        if (!Target.isVectorOpSupported(tb1, exp.op, tb2))\n        {\n            result = exp.incompatibleTypes();\n            return;\n        }\n\n        if (exp.e1.op == TOK.call)\n            exp.e1 = (cast(CallExp)exp.e1).addDtorHook(sc);\n        if (exp.e2.op == TOK.call)\n            exp.e2 = (cast(CallExp)exp.e2).addDtorHook(sc);\n\n        if (exp.e1.type.toBasetype().ty == Tsarray ||\n            exp.e2.type.toBasetype().ty == Tsarray)\n            exp.deprecation(\"identity comparison of static arrays \"\n                ~ \"implicitly coerces them to slices, \"\n                ~ \"which are compared by reference\");\n\n        result = exp;\n    }\n\n    override void visit(CondExp exp)\n    {\n        static if (LOGSEMANTIC)\n        {\n            printf(\"CondExp::semantic('%s')\\n\", exp.toChars());\n        }\n        if (exp.type)\n        {\n            result = exp;\n            return;\n        }\n\n        if (exp.econd.op == TOK.dotIdentifier)\n            (cast(DotIdExp)exp.econd).noderef = true;\n\n        Expression ec = exp.econd.expressionSemantic(sc);\n        ec = resolveProperties(sc, ec);\n        ec = ec.toBoolean(sc);\n\n        CtorFlow ctorflow_root = sc.ctorflow.clone();\n        Expression e1x = exp.e1.expressionSemantic(sc);\n        e1x = resolveProperties(sc, e1x);\n\n        CtorFlow ctorflow1 = sc.ctorflow;\n        sc.ctorflow = ctorflow_root;\n        Expression e2x = exp.e2.expressionSemantic(sc);\n        e2x = resolveProperties(sc, e2x);\n\n        sc.merge(exp.loc, ctorflow1);\n        ctorflow1.freeFieldinit();\n\n        if (ec.op == TOK.error)\n        {\n            result = ec;\n            return;\n        }\n        if (ec.type == Type.terror)\n            return setError();\n        exp.econd = ec;\n\n        if (e1x.op == TOK.error)\n        {\n            result = e1x;\n            return;\n        }\n        if (e1x.type == Type.terror)\n            return setError();\n        exp.e1 = e1x;\n\n        if (e2x.op == TOK.error)\n        {\n            result = e2x;\n            return;\n        }\n        if (e2x.type == Type.terror)\n            return setError();\n        exp.e2 = e2x;\n\n        auto f0 = checkNonAssignmentArrayOp(exp.econd);\n        auto f1 = checkNonAssignmentArrayOp(exp.e1);\n        auto f2 = checkNonAssignmentArrayOp(exp.e2);\n        if (f0 || f1 || f2)\n            return setError();\n\n        Type t1 = exp.e1.type;\n        Type t2 = exp.e2.type;\n        // If either operand is void the result is void, we have to cast both\n        // the expression to void so that we explicitly discard the expression\n        // value if any\n        // https://issues.dlang.org/show_bug.cgi?id=16598\n        if (t1.ty == Tvoid || t2.ty == Tvoid)\n        {\n            exp.type = Type.tvoid;\n            exp.e1 = exp.e1.castTo(sc, exp.type);\n            exp.e2 = exp.e2.castTo(sc, exp.type);\n        }\n        else if (t1 == t2)\n            exp.type = t1;\n        else\n        {\n            if (Expression ex = typeCombine(exp, sc))\n            {\n                result = ex;\n                return;\n            }\n\n            switch (exp.e1.type.toBasetype().ty)\n            {\n            case Tcomplex32:\n            case Tcomplex64:\n            case Tcomplex80:\n                exp.e2 = exp.e2.castTo(sc, exp.e1.type);\n                break;\n            default:\n                break;\n            }\n            switch (exp.e2.type.toBasetype().ty)\n            {\n            case Tcomplex32:\n            case Tcomplex64:\n            case Tcomplex80:\n                exp.e1 = exp.e1.castTo(sc, exp.e2.type);\n                break;\n            default:\n                break;\n            }\n            if (exp.type.toBasetype().ty == Tarray)\n            {\n                exp.e1 = exp.e1.castTo(sc, exp.type);\n                exp.e2 = exp.e2.castTo(sc, exp.type);\n            }\n        }\n        exp.type = exp.type.merge2();\n        version (none)\n        {\n            printf(\"res: %s\\n\", exp.type.toChars());\n            printf(\"e1 : %s\\n\", exp.e1.type.toChars());\n            printf(\"e2 : %s\\n\", exp.e2.type.toChars());\n        }\n\n        /* https://issues.dlang.org/show_bug.cgi?id=14696\n         * If either e1 or e2 contain temporaries which need dtor,\n         * make them conditional.\n         * Rewrite:\n         *      cond ? (__tmp1 = ..., __tmp1) : (__tmp2 = ..., __tmp2)\n         * to:\n         *      (auto __cond = cond) ? (... __tmp1) : (... __tmp2)\n         * and replace edtors of __tmp1 and __tmp2 with:\n         *      __tmp1.edtor --> __cond && __tmp1.dtor()\n         *      __tmp2.edtor --> __cond || __tmp2.dtor()\n         */\n        exp.hookDtors(sc);\n\n        result = exp;\n    }\n\n    override void visit(FileInitExp e)\n    {\n        //printf(\"FileInitExp::semantic()\\n\");\n        e.type = Type.tstring;\n        result = e;\n    }\n\n    override void visit(LineInitExp e)\n    {\n        e.type = Type.tint32;\n        result = e;\n    }\n\n    override void visit(ModuleInitExp e)\n    {\n        //printf(\"ModuleInitExp::semantic()\\n\");\n        e.type = Type.tstring;\n        result = e;\n    }\n\n    override void visit(FuncInitExp e)\n    {\n        //printf(\"FuncInitExp::semantic()\\n\");\n        e.type = Type.tstring;\n        if (sc.func)\n        {\n            result = e.resolveLoc(Loc.initial, sc);\n            return;\n        }\n        result = e;\n    }\n\n    override void visit(PrettyFuncInitExp e)\n    {\n        //printf(\"PrettyFuncInitExp::semantic()\\n\");\n        e.type = Type.tstring;\n        if (sc.func)\n        {\n            result = e.resolveLoc(Loc.initial, sc);\n            return;\n        }\n\n        result = e;\n    }\n}\n\n/**********************************\n * Try to run semantic routines.\n * If they fail, return NULL.\n */\nExpression trySemantic(Expression exp, Scope* sc)\n{\n    //printf(\"+trySemantic(%s)\\n\", exp.toChars());\n    uint errors = global.startGagging();\n    Expression e = expressionSemantic(exp, sc);\n    if (global.endGagging(errors))\n    {\n        e = null;\n    }\n    //printf(\"-trySemantic(%s)\\n\", exp.toChars());\n    return e;\n}\n\n/**************************\n * Helper function for easy error propagation.\n * If error occurs, returns ErrorExp. Otherwise returns NULL.\n */\nExpression unaSemantic(UnaExp e, Scope* sc)\n{\n    static if (LOGSEMANTIC)\n    {\n        printf(\"UnaExp::semantic('%s')\\n\", e.toChars());\n    }\n    Expression e1x = e.e1.expressionSemantic(sc);\n    if (e1x.op == TOK.error)\n        return e1x;\n    e.e1 = e1x;\n    return null;\n}\n\n/**************************\n * Helper function for easy error propagation.\n * If error occurs, returns ErrorExp. Otherwise returns NULL.\n */\nExpression binSemantic(BinExp e, Scope* sc)\n{\n    static if (LOGSEMANTIC)\n    {\n        printf(\"BinExp::semantic('%s')\\n\", e.toChars());\n    }\n    Expression e1x = e.e1.expressionSemantic(sc);\n    Expression e2x = e.e2.expressionSemantic(sc);\n\n    // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684\n    if (e1x.op == TOK.type)\n        e1x = resolveAliasThis(sc, e1x);\n    if (e2x.op == TOK.type)\n        e2x = resolveAliasThis(sc, e2x);\n\n    if (e1x.op == TOK.error)\n        return e1x;\n    if (e2x.op == TOK.error)\n        return e2x;\n    e.e1 = e1x;\n    e.e2 = e2x;\n    return null;\n}\n\nExpression binSemanticProp(BinExp e, Scope* sc)\n{\n    if (Expression ex = binSemantic(e, sc))\n        return ex;\n    Expression e1x = resolveProperties(sc, e.e1);\n    Expression e2x = resolveProperties(sc, e.e2);\n    if (e1x.op == TOK.error)\n        return e1x;\n    if (e2x.op == TOK.error)\n        return e2x;\n    e.e1 = e1x;\n    e.e2 = e2x;\n    return null;\n}\n\n// entrypoint for semantic ExpressionSemanticVisitor\nextern (C++) Expression expressionSemantic(Expression e, Scope* sc)\n{\n    scope v = new ExpressionSemanticVisitor(sc);\n    e.accept(v);\n    return v.result;\n}\n\nExpression semanticX(DotIdExp exp, Scope* sc)\n{\n    //printf(\"DotIdExp::semanticX(this = %p, '%s')\\n\", this, toChars());\n    if (Expression ex = unaSemantic(exp, sc))\n        return ex;\n\n    if (exp.ident == Id._mangleof)\n    {\n        // symbol.mangleof\n        Dsymbol ds;\n        switch (exp.e1.op)\n        {\n        case TOK.scope_:\n            ds = (cast(ScopeExp)exp.e1).sds;\n            goto L1;\n        case TOK.variable:\n            ds = (cast(VarExp)exp.e1).var;\n            goto L1;\n        case TOK.dotVariable:\n            ds = (cast(DotVarExp)exp.e1).var;\n            goto L1;\n        case TOK.overloadSet:\n            ds = (cast(OverExp)exp.e1).vars;\n            goto L1;\n        case TOK.template_:\n            {\n                TemplateExp te = cast(TemplateExp)exp.e1;\n                ds = te.fd ? cast(Dsymbol)te.fd : te.td;\n            }\n        L1:\n            {\n                assert(ds);\n                if (auto f = ds.isFuncDeclaration())\n                {\n                    if (f.checkForwardRef(exp.loc))\n                    {\n                        return new ErrorExp();\n                    }\n                }\n                OutBuffer buf;\n                mangleToBuffer(ds, &buf);\n                const s = buf.peekSlice();\n                Expression e = new StringExp(exp.loc, buf.extractString(), s.length);\n                e = e.expressionSemantic(sc);\n                return e;\n            }\n        default:\n            break;\n        }\n    }\n\n    if (exp.e1.op == TOK.variable && exp.e1.type.toBasetype().ty == Tsarray && exp.ident == Id.length)\n    {\n        // bypass checkPurity\n        return exp.e1.type.dotExp(sc, exp.e1, exp.ident, exp.noderef ? DotExpFlag.noDeref : 0);\n    }\n\n    if (exp.e1.op == TOK.dot)\n    {\n    }\n    else\n    {\n        exp.e1 = resolvePropertiesX(sc, exp.e1);\n    }\n    if (exp.e1.op == TOK.tuple && exp.ident == Id.offsetof)\n    {\n        /* 'distribute' the .offsetof to each of the tuple elements.\n         */\n        TupleExp te = cast(TupleExp)exp.e1;\n        auto exps = new Expressions(te.exps.dim);\n        for (size_t i = 0; i < exps.dim; i++)\n        {\n            Expression e = (*te.exps)[i];\n            e = e.expressionSemantic(sc);\n            e = new DotIdExp(e.loc, e, Id.offsetof);\n            (*exps)[i] = e;\n        }\n        // Don't evaluate te.e0 in runtime\n        Expression e = new TupleExp(exp.loc, null, exps);\n        e = e.expressionSemantic(sc);\n        return e;\n    }\n    if (exp.e1.op == TOK.tuple && exp.ident == Id.length)\n    {\n        TupleExp te = cast(TupleExp)exp.e1;\n        // Don't evaluate te.e0 in runtime\n        Expression e = new IntegerExp(exp.loc, te.exps.dim, Type.tsize_t);\n        return e;\n    }\n\n    // https://issues.dlang.org/show_bug.cgi?id=14416\n    // Template has no built-in properties except for 'stringof'.\n    if ((exp.e1.op == TOK.dotTemplateDeclaration || exp.e1.op == TOK.template_) && exp.ident != Id.stringof)\n    {\n        exp.error(\"template `%s` does not have property `%s`\", exp.e1.toChars(), exp.ident.toChars());\n        return new ErrorExp();\n    }\n    if (!exp.e1.type)\n    {\n        exp.error(\"expression `%s` does not have property `%s`\", exp.e1.toChars(), exp.ident.toChars());\n        return new ErrorExp();\n    }\n\n    return exp;\n}\n\n// Resolve e1.ident without seeing UFCS.\n// If flag == 1, stop \"not a property\" error and return NULL.\nExpression semanticY(DotIdExp exp, Scope* sc, int flag)\n{\n    //printf(\"DotIdExp::semanticY(this = %p, '%s')\\n\", exp, exp.toChars());\n\n    //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; }\n\n    /* Special case: rewrite this.id and super.id\n     * to be classtype.id and baseclasstype.id\n     * if we have no this pointer.\n     */\n    if ((exp.e1.op == TOK.this_ || exp.e1.op == TOK.super_) && !hasThis(sc))\n    {\n        if (AggregateDeclaration ad = sc.getStructClassScope())\n        {\n            if (exp.e1.op == TOK.this_)\n            {\n                exp.e1 = new TypeExp(exp.e1.loc, ad.type);\n            }\n            else\n            {\n                ClassDeclaration cd = ad.isClassDeclaration();\n                if (cd && cd.baseClass)\n                    exp.e1 = new TypeExp(exp.e1.loc, cd.baseClass.type);\n            }\n        }\n    }\n\n    Expression e = semanticX(exp, sc);\n    if (e != exp)\n        return e;\n\n    Expression eleft;\n    Expression eright;\n    if (exp.e1.op == TOK.dot)\n    {\n        DotExp de = cast(DotExp)exp.e1;\n        eleft = de.e1;\n        eright = de.e2;\n    }\n    else\n    {\n        eleft = null;\n        eright = exp.e1;\n    }\n\n    Type t1b = exp.e1.type.toBasetype();\n\n    if (eright.op == TOK.scope_) // also used for template alias's\n    {\n        ScopeExp ie = cast(ScopeExp)eright;\n\n        int flags = SearchLocalsOnly;\n        /* Disable access to another module's private imports.\n         * The check for 'is sds our current module' is because\n         * the current module should have access to its own imports.\n         */\n        if (ie.sds.isModule() && ie.sds != sc._module)\n            flags |= IgnorePrivateImports;\n        if (sc.flags & SCOPE.ignoresymbolvisibility)\n            flags |= IgnoreSymbolVisibility;\n        Dsymbol s = ie.sds.search(exp.loc, exp.ident, flags);\n        /* Check for visibility before resolving aliases because public\n         * aliases to private symbols are public.\n         */\n        if (s && !(sc.flags & SCOPE.ignoresymbolvisibility) && !symbolIsVisible(sc._module, s))\n        {\n            if (s.isDeclaration())\n                error(exp.loc, \"`%s` is not visible from module `%s`\", s.toPrettyChars(), sc._module.toChars());\n            else\n                deprecation(exp.loc, \"`%s` is not visible from module `%s`\", s.toPrettyChars(), sc._module.toChars());\n            // s = null;\n        }\n        if (s)\n        {\n            if (auto p = s.isPackage())\n                checkAccess(exp.loc, sc, p);\n\n            // if 's' is a tuple variable, the tuple is returned.\n            s = s.toAlias();\n\n            exp.checkDeprecated(sc, s);\n            exp.checkDisabled(sc, s);\n\n            EnumMember em = s.isEnumMember();\n            if (em)\n            {\n                return em.getVarExp(exp.loc, sc);\n            }\n            VarDeclaration v = s.isVarDeclaration();\n            if (v)\n            {\n                //printf(\"DotIdExp:: Identifier '%s' is a variable, type '%s'\\n\", toChars(), v.type.toChars());\n                if (!v.type ||\n                    !v.type.deco && v.inuse)\n                {\n                    if (v.inuse)\n                        exp.error(\"circular reference to %s `%s`\", v.kind(), v.toPrettyChars());\n                    else\n                        exp.error(\"forward reference to %s `%s`\", v.kind(), v.toPrettyChars());\n                    return new ErrorExp();\n                }\n                if (v.type.ty == Terror)\n                    return new ErrorExp();\n\n                if ((v.storage_class & STC.manifest) && v._init && !exp.wantsym)\n                {\n                    /* Normally, the replacement of a symbol with its initializer is supposed to be in semantic2().\n                     * Introduced by https://github.com/dlang/dmd/pull/5588 which should probably\n                     * be reverted. `wantsym` is the hack to work around the problem.\n                     */\n                    if (v.inuse)\n                    {\n                        error(exp.loc, \"circular initialization of %s `%s`\", v.kind(), v.toPrettyChars());\n                        return new ErrorExp();\n                    }\n                    e = v.expandInitializer(exp.loc);\n                    v.inuse++;\n                    e = e.expressionSemantic(sc);\n                    v.inuse--;\n                    return e;\n                }\n\n                if (v.needThis())\n                {\n                    if (!eleft)\n                        eleft = new ThisExp(exp.loc);\n                    e = new DotVarExp(exp.loc, eleft, v);\n                    e = e.expressionSemantic(sc);\n                }\n                else\n                {\n                    e = new VarExp(exp.loc, v);\n                    if (eleft)\n                    {\n                        e = new CommaExp(exp.loc, eleft, e);\n                        e.type = v.type;\n                    }\n                }\n                e = e.deref();\n                return e.expressionSemantic(sc);\n            }\n\n            FuncDeclaration f = s.isFuncDeclaration();\n            if (f)\n            {\n                //printf(\"it's a function\\n\");\n                if (!f.functionSemantic())\n                    return new ErrorExp();\n                if (f.needThis())\n                {\n                    if (!eleft)\n                        eleft = new ThisExp(exp.loc);\n                    e = new DotVarExp(exp.loc, eleft, f, true);\n                    e = e.expressionSemantic(sc);\n                }\n                else\n                {\n                    e = new VarExp(exp.loc, f, true);\n                    if (eleft)\n                    {\n                        e = new CommaExp(exp.loc, eleft, e);\n                        e.type = f.type;\n                    }\n                }\n                return e;\n            }\n            if (auto td = s.isTemplateDeclaration())\n            {\n                if (eleft)\n                    e = new DotTemplateExp(exp.loc, eleft, td);\n                else\n                    e = new TemplateExp(exp.loc, td);\n                e = e.expressionSemantic(sc);\n                return e;\n            }\n            if (OverDeclaration od = s.isOverDeclaration())\n            {\n                e = new VarExp(exp.loc, od, true);\n                if (eleft)\n                {\n                    e = new CommaExp(exp.loc, eleft, e);\n                    e.type = Type.tvoid; // ambiguous type?\n                }\n                return e;\n            }\n            OverloadSet o = s.isOverloadSet();\n            if (o)\n            {\n                //printf(\"'%s' is an overload set\\n\", o.toChars());\n                return new OverExp(exp.loc, o);\n            }\n\n            if (auto t = s.getType())\n            {\n                return (new TypeExp(exp.loc, t)).expressionSemantic(sc);\n            }\n\n            TupleDeclaration tup = s.isTupleDeclaration();\n            if (tup)\n            {\n                if (eleft)\n                {\n                    e = new DotVarExp(exp.loc, eleft, tup);\n                    e = e.expressionSemantic(sc);\n                    return e;\n                }\n                e = new TupleExp(exp.loc, tup);\n                e = e.expressionSemantic(sc);\n                return e;\n            }\n\n            ScopeDsymbol sds = s.isScopeDsymbol();\n            if (sds)\n            {\n                //printf(\"it's a ScopeDsymbol %s\\n\", ident.toChars());\n                e = new ScopeExp(exp.loc, sds);\n                e = e.expressionSemantic(sc);\n                if (eleft)\n                    e = new DotExp(exp.loc, eleft, e);\n                return e;\n            }\n\n            Import imp = s.isImport();\n            if (imp)\n            {\n                ie = new ScopeExp(exp.loc, imp.pkg);\n                return ie.expressionSemantic(sc);\n            }\n            // BUG: handle other cases like in IdentifierExp::semantic()\n            debug\n            {\n                printf(\"s = '%s', kind = '%s'\\n\", s.toChars(), s.kind());\n            }\n            assert(0);\n        }\n        else if (exp.ident == Id.stringof)\n        {\n            const p = ie.toString();\n            e = new StringExp(exp.loc, cast(char*)p.ptr, p.length);\n            e = e.expressionSemantic(sc);\n            return e;\n        }\n        if (ie.sds.isPackage() || ie.sds.isImport() || ie.sds.isModule())\n        {\n            flag = 0;\n        }\n        if (flag)\n            return null;\n        s = ie.sds.search_correct(exp.ident);\n        if (s)\n            exp.error(\"undefined identifier `%s` in %s `%s`, did you mean %s `%s`?\", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars(), s.kind(), s.toChars());\n        else\n            exp.error(\"undefined identifier `%s` in %s `%s`\", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars());\n        return new ErrorExp();\n    }\n    else if (t1b.ty == Tpointer && exp.e1.type.ty != Tenum && exp.ident != Id._init && exp.ident != Id.__sizeof && exp.ident != Id.__xalignof && exp.ident != Id.offsetof && exp.ident != Id._mangleof && exp.ident != Id.stringof)\n    {\n        Type t1bn = t1b.nextOf();\n        if (flag)\n        {\n            AggregateDeclaration ad = isAggregate(t1bn);\n            if (ad && !ad.members) // https://issues.dlang.org/show_bug.cgi?id=11312\n                return null;\n        }\n\n        /* Rewrite:\n         *   p.ident\n         * as:\n         *   (*p).ident\n         */\n        if (flag && t1bn.ty == Tvoid)\n            return null;\n        e = new PtrExp(exp.loc, exp.e1);\n        e = e.expressionSemantic(sc);\n        return e.type.dotExp(sc, e, exp.ident, flag | (exp.noderef ? DotExpFlag.noDeref : 0));\n    }\n    else\n    {\n        if (exp.e1.op == TOK.type || exp.e1.op == TOK.template_)\n            flag = 0;\n        e = exp.e1.type.dotExp(sc, exp.e1, exp.ident, flag | (exp.noderef ? DotExpFlag.noDeref : 0));\n        if (e)\n            e = e.expressionSemantic(sc);\n        return e;\n    }\n}\n\n// Resolve e1.ident!tiargs without seeing UFCS.\n// If flag == 1, stop \"not a property\" error and return NULL.\nExpression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag)\n{\n    static if (LOGSEMANTIC)\n    {\n        printf(\"DotTemplateInstanceExpY::semantic('%s')\\n\", exp.toChars());\n    }\n\n    static Expression errorExp()\n    {\n        return new ErrorExp();\n    }\n\n    auto die = new DotIdExp(exp.loc, exp.e1, exp.ti.name);\n\n    Expression e = die.semanticX(sc);\n    if (e == die)\n    {\n        exp.e1 = die.e1; // take back\n        Type t1b = exp.e1.type.toBasetype();\n        if (t1b.ty == Tarray || t1b.ty == Tsarray || t1b.ty == Taarray || t1b.ty == Tnull || (t1b.isTypeBasic() && t1b.ty != Tvoid))\n        {\n            /* No built-in type has templatized properties, so do shortcut.\n             * It is necessary in: 1024.max!\"a < b\"\n             */\n            if (flag)\n                return null;\n        }\n        e = die.semanticY(sc, flag);\n        if (flag)\n        {\n            if (!e ||\n                isDotOpDispatch(e))\n            {\n                /* opDispatch!tiargs would be a function template that needs IFTI,\n                 * so it's not a template\n                 */\n                return null;\n            }\n        }\n    }\n    assert(e);\n\n    if (e.op == TOK.error)\n        return e;\n    if (e.op == TOK.dotVariable)\n    {\n        DotVarExp dve = cast(DotVarExp)e;\n        if (FuncDeclaration fd = dve.var.isFuncDeclaration())\n        {\n            if (TemplateDeclaration td = fd.findTemplateDeclRoot())\n            {\n                e = new DotTemplateExp(dve.loc, dve.e1, td);\n                e = e.expressionSemantic(sc);\n            }\n        }\n        else if (OverDeclaration od = dve.var.isOverDeclaration())\n        {\n            exp.e1 = dve.e1; // pull semantic() result\n\n            if (!exp.findTempDecl(sc))\n                goto Lerr;\n            if (exp.ti.needsTypeInference(sc))\n                return exp;\n            exp.ti.dsymbolSemantic(sc);\n            if (!exp.ti.inst || exp.ti.errors) // if template failed to expand\n                return errorExp();\n\n            if (Declaration v = exp.ti.toAlias().isDeclaration())\n            {\n                if (v.type && !v.type.deco)\n                    v.type = v.type.typeSemantic(v.loc, sc);\n                return new DotVarExp(exp.loc, exp.e1, v)\n                       .expressionSemantic(sc);\n            }\n            return new DotExp(exp.loc, exp.e1, new ScopeExp(exp.loc, exp.ti))\n                   .expressionSemantic(sc);\n        }\n    }\n    else if (e.op == TOK.variable)\n    {\n        VarExp ve = cast(VarExp)e;\n        if (FuncDeclaration fd = ve.var.isFuncDeclaration())\n        {\n            if (TemplateDeclaration td = fd.findTemplateDeclRoot())\n            {\n                e = new TemplateExp(ve.loc, td)\n                    .expressionSemantic(sc);\n            }\n        }\n        else if (OverDeclaration od = ve.var.isOverDeclaration())\n        {\n            exp.ti.tempdecl = od;\n            return new ScopeExp(exp.loc, exp.ti)\n                   .expressionSemantic(sc);\n        }\n    }\n\n    if (e.op == TOK.dotTemplateDeclaration)\n    {\n        DotTemplateExp dte = cast(DotTemplateExp)e;\n        exp.e1 = dte.e1; // pull semantic() result\n\n        exp.ti.tempdecl = dte.td;\n        if (!exp.ti.semanticTiargs(sc))\n            return errorExp();\n        if (exp.ti.needsTypeInference(sc))\n            return exp;\n        exp.ti.dsymbolSemantic(sc);\n        if (!exp.ti.inst || exp.ti.errors) // if template failed to expand\n            return errorExp();\n\n        if (Declaration v = exp.ti.toAlias().isDeclaration())\n        {\n            if (v.isFuncDeclaration() || v.isVarDeclaration())\n            {\n                return new DotVarExp(exp.loc, exp.e1, v)\n                       .expressionSemantic(sc);\n            }\n        }\n        return new DotExp(exp.loc, exp.e1, new ScopeExp(exp.loc, exp.ti))\n               .expressionSemantic(sc);\n    }\n    else if (e.op == TOK.template_)\n    {\n        exp.ti.tempdecl = (cast(TemplateExp)e).td;\n        return new ScopeExp(exp.loc, exp.ti)\n               .expressionSemantic(sc);\n    }\n    else if (e.op == TOK.dot)\n    {\n        DotExp de = cast(DotExp)e;\n\n        if (de.e2.op == TOK.overloadSet)\n        {\n            if (!exp.findTempDecl(sc) || !exp.ti.semanticTiargs(sc))\n            {\n                return errorExp();\n            }\n            if (exp.ti.needsTypeInference(sc))\n                return exp;\n            exp.ti.dsymbolSemantic(sc);\n            if (!exp.ti.inst || exp.ti.errors) // if template failed to expand\n                return errorExp();\n\n            if (Declaration v = exp.ti.toAlias().isDeclaration())\n            {\n                if (v.type && !v.type.deco)\n                    v.type = v.type.typeSemantic(v.loc, sc);\n                return new DotVarExp(exp.loc, exp.e1, v)\n                       .expressionSemantic(sc);\n            }\n            return new DotExp(exp.loc, exp.e1, new ScopeExp(exp.loc, exp.ti))\n                   .expressionSemantic(sc);\n        }\n    }\n    else if (e.op == TOK.overloadSet)\n    {\n        OverExp oe = cast(OverExp)e;\n        exp.ti.tempdecl = oe.vars;\n        return new ScopeExp(exp.loc, exp.ti)\n               .expressionSemantic(sc);\n    }\n\nLerr:\n    exp.error(\"`%s` isn't a template\", e.toChars());\n    return errorExp();\n}\n\n\n/****************************************************\n * Determine if `exp`, which takes the address of `v`, can do so safely.\n * Params:\n *      sc = context\n *      exp = expression that takes the address of `v`\n *      v = the variable getting its address taken\n * Returns:\n *      `true` if ok, `false` for error\n */\nprivate bool checkAddressVar(Scope* sc, UnaExp exp, VarDeclaration v)\n{\n    //printf(\"checkAddressVar(exp: %s, v: %s)\\n\", exp.toChars(), v.toChars());\n    if (v)\n    {\n        if (!v.canTakeAddressOf())\n        {\n            exp.error(\"cannot take address of `%s`\", exp.e1.toChars());\n            return false;\n        }\n        if (sc.func && !sc.intypeof && !v.isDataseg())\n        {\n            const(char)* p = v.isParameter() ? \"parameter\" : \"local\";\n            if (global.params.vsafe)\n            {\n                // Taking the address of v means it cannot be set to 'scope' later\n                v.storage_class &= ~STC.maybescope;\n                v.doNotInferScope = true;\n                if (v.storage_class & STC.scope_ && sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n                {\n                    exp.error(\"cannot take address of `scope` %s `%s` in `@safe` function `%s`\", p, v.toChars(), sc.func.toChars());\n                    return false;\n                }\n            }\n            else if (sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n            {\n                exp.error(\"cannot take address of %s `%s` in `@safe` function `%s`\", p, v.toChars(), sc.func.toChars());\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\n/*******************************\n * Checks the attributes of a function.\n * Purity (`pure`), safety (`@safe`), no GC allocations(`@nogc`)\n * and usage of `deprecated` and `@disabled`-ed symbols are checked.\n *\n * Params:\n *  exp = expression to check attributes for\n *  sc  = scope of the function\n *  f   = function to be checked\n * Returns: `true` if error occur.\n */\nprivate bool checkFunctionAttributes(Expression exp, Scope* sc, FuncDeclaration f)\n{\n    with(exp)\n    {\n        bool error = checkDisabled(sc, f);\n        error |= checkDeprecated(sc, f);\n        error |= checkPurity(sc, f);\n        error |= checkSafety(sc, f);\n        error |= checkNogc(sc, f);\n        return error;\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/func.d",
    "content": "/***\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/func.d, _func.d)\n * Documentation:  https://dlang.org/phobos/dmd_func.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/func.d\n */\n\nmodule dmd.func;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.blockexit;\nimport dmd.gluelayer;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.delegatize;\nimport dmd.dinterpret;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.escape;\nimport dmd.expression;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.mtype;\nimport dmd.objc;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.semantic2;\nimport dmd.semantic3;\nimport dmd.statement_rewrite_walker;\nimport dmd.statement;\nimport dmd.statementsem;\nimport dmd.tokens;\nimport dmd.visitor;\n\n/// Inline Status\nenum ILS : int\n{\n    uninitialized,       /// not computed yet\n    no,                  /// cannot inline\n    yes,                 /// can inline\n}\n\nenum BUILTIN : int\n{\n    unknown = -1,    /// not known if this is a builtin\n    no,              /// this is not a builtin\n    yes,             /// this is a builtin\n}\n\n\n/* Tweak all return statements and dtor call for nrvo_var, for correct NRVO.\n */\nextern (C++) final class NrvoWalker : StatementRewriteWalker\n{\n    alias visit = typeof(super).visit;\npublic:\n    FuncDeclaration fd;\n    Scope* sc;\n\n    override void visit(ReturnStatement s)\n    {\n        // See if all returns are instead to be replaced with a goto returnLabel;\n        if (fd.returnLabel)\n        {\n            /* Rewrite:\n             *  return exp;\n             * as:\n             *  vresult = exp; goto Lresult;\n             */\n            auto gs = new GotoStatement(s.loc, Id.returnLabel);\n            gs.label = fd.returnLabel;\n\n            Statement s1 = gs;\n            if (s.exp)\n                s1 = new CompoundStatement(s.loc, new ExpStatement(s.loc, s.exp), gs);\n\n            replaceCurrent(s1);\n        }\n    }\n\n    override void visit(TryFinallyStatement s)\n    {\n        DtorExpStatement des;\n        if (fd.nrvo_can && s.finalbody && (des = s.finalbody.isDtorExpStatement()) !is null &&\n            fd.nrvo_var == des.var)\n        {\n            if (!(global.params.useExceptions && ClassDeclaration.throwable))\n            {\n                /* Don't need to call destructor at all, since it is nrvo\n                 */\n                replaceCurrent(s._body);\n                s._body.accept(this);\n                return;\n            }\n\n            /* Normally local variable dtors are called regardless exceptions.\n             * But for nrvo_var, its dtor should be called only when exception is thrown.\n             *\n             * Rewrite:\n             *      try { s.body; } finally { nrvo_var.edtor; }\n             *      // equivalent with:\n             *      //    s.body; scope(exit) nrvo_var.edtor;\n             * as:\n             *      try { s.body; } catch(Throwable __o) { nrvo_var.edtor; throw __o; }\n             *      // equivalent with:\n             *      //    s.body; scope(failure) nrvo_var.edtor;\n             */\n            Statement sexception = new DtorExpStatement(Loc.initial, fd.nrvo_var.edtor, fd.nrvo_var);\n            Identifier id = Identifier.generateId(\"__o\");\n\n            Statement handler = new PeelStatement(sexception);\n            if (sexception.blockExit(fd, false) & BE.fallthru)\n            {\n                auto ts = new ThrowStatement(Loc.initial, new IdentifierExp(Loc.initial, id));\n                ts.internalThrow = true;\n                handler = new CompoundStatement(Loc.initial, handler, ts);\n            }\n\n            auto catches = new Catches();\n            auto ctch = new Catch(Loc.initial, getThrowable(), id, handler);\n            ctch.internalCatch = true;\n            ctch.catchSemantic(sc); // Run semantic to resolve identifier '__o'\n            catches.push(ctch);\n\n            Statement s2 = new TryCatchStatement(Loc.initial, s._body, catches);\n            fd.eh_none = false;\n            replaceCurrent(s2);\n            s2.accept(this);\n        }\n        else\n            StatementRewriteWalker.visit(s);\n    }\n}\n\nenum FUNCFLAG : uint\n{\n    purityInprocess  = 1,      /// working on determining purity\n    safetyInprocess  = 2,      /// working on determining safety\n    nothrowInprocess = 4,      /// working on determining nothrow\n    nogcInprocess    = 8,      /// working on determining @nogc\n    returnInprocess  = 0x10,   /// working on inferring 'return' for parameters\n    inlineScanned    = 0x20,   /// function has been scanned for inline possibilities\n    inferScope       = 0x40,   /// infer 'scope' for parameters\n    hasCatches       = 0x80,   /// function has try-catch statements\n    compileTimeOnly  = 0x100,  /// is a compile time only function; no code will be generated for it\n}\n\n/***********************************************************\n * Tuple of result identifier (possibly null) and statement.\n * This is used to store out contracts: out(id){ ensure }\n */\nextern (C++) struct Ensure\n{\n    Identifier id;\n    Statement ensure;\n\n    Ensure syntaxCopy()\n    {\n        return Ensure(id, ensure.syntaxCopy());\n    }\n\n    /*****************************************\n     * Do syntax copy of an array of Ensure's.\n     */\n    static Ensures* arraySyntaxCopy(Ensures* a)\n    {\n        Ensures* b = null;\n        if (a)\n        {\n            b = a.copy();\n            foreach (i, e; *a)\n            {\n                (*b)[i] = e.syntaxCopy();\n            }\n        }\n        return b;\n    }\n\n}\n\n/***********************************************************\n */\nextern (C++) class FuncDeclaration : Declaration\n{\n    Types* fthrows;                     /// Array of Type's of exceptions (not used)\n    Statements* frequires;              /// in contracts\n    Ensures* fensures;                  /// out contracts\n    Statement frequire;                 /// lowered in contract\n    Statement fensure;                  /// lowered out contract\n    Statement fbody;                    /// function body\n\n    FuncDeclarations foverrides;        /// functions this function overrides\n    FuncDeclaration fdrequire;          /// function that does the in contract\n    FuncDeclaration fdensure;           /// function that does the out contract\n\n    const(char)* mangleString;          /// mangled symbol created from mangleExact()\n\n    VarDeclaration vresult;             /// result variable for out contracts\n    LabelDsymbol returnLabel;           /// where the return goes\n\n    // used to prevent symbols in different\n    // scopes from having the same name\n    DsymbolTable localsymtab;\n    VarDeclaration vthis;               /// 'this' parameter (member and nested)\n    VarDeclaration v_arguments;         /// '_arguments' parameter\n    ObjcSelector* selector;             /// Objective-C method selector (member function only)\n\n    VarDeclaration v_argptr;            /// '_argptr' variable\n    VarDeclarations* parameters;        /// Array of VarDeclaration's for parameters\n    DsymbolTable labtab;                /// statement label symbol table\n    Dsymbol overnext;                   /// next in overload list\n    FuncDeclaration overnext0;          /// next in overload list (only used during IFTI)\n    Loc endloc;                         /// location of closing curly bracket\n    int vtblIndex = -1;                 /// for member functions, index into vtbl[]\n    bool naked;                         /// true if naked\n    bool generated;                     /// true if function was generated by the compiler rather than\n                                        /// supplied by the user\n    ILS inlineStatusStmt = ILS.uninitialized;\n    ILS inlineStatusExp = ILS.uninitialized;\n    PINLINE inlining = PINLINE.default_;\n\n    CompiledCtfeFunctionPimpl ctfeCode; /// Local data (i.e. CompileCtfeFunction*) for module dinterpret\n    int inlineNest;                     /// !=0 if nested inline\n    bool isArrayOp;                     /// true if array operation\n    bool eh_none;                       /// true if no exception unwinding is needed\n\n    bool semantic3Errors;               /// true if errors in semantic3 this function's frame ptr\n    ForeachStatement fes;               /// if foreach body, this is the foreach\n    BaseClass* interfaceVirtual;        /// if virtual, but only appears in base interface vtbl[]\n    bool introducing;                   /// true if 'introducing' function\n    /** if !=NULL, then this is the type\n    of the 'introducing' function\n    this one is overriding\n    */\n    Type tintro;\n\n    bool inferRetType;                  /// true if return type is to be inferred\n    StorageClass storage_class2;        /// storage class for template onemember's\n\n    // Things that should really go into Scope\n\n    /// 1 if there's a return exp; statement\n    /// 2 if there's a throw statement\n    /// 4 if there's an assert(0)\n    /// 8 if there's inline asm\n    /// 16 if there are multiple return statements\n    int hasReturnExp;\n\n    // Support for NRVO (named return value optimization)\n    bool nrvo_can = true;               /// true means we can do NRVO\n    VarDeclaration nrvo_var;            /// variable to replace with shidden\n    Symbol* shidden;                    /// hidden pointer passed to function\n\n    ReturnStatements* returns;\n\n    GotoStatements* gotos;              /// Gotos with forward references\n\n    /// set if this is a known, builtin function we can evaluate at compile time\n    BUILTIN builtin = BUILTIN.unknown;\n\n    /// set if someone took the address of this function\n    int tookAddressOf;\n\n    bool requiresClosure;               // this function needs a closure\n\n    /// local variables in this function which are referenced by nested functions\n    VarDeclarations closureVars;\n    /// Sibling nested functions which called this one\n    FuncDeclarations siblingCallers;\n\n    FuncDeclarations *inlinedNestedCallees;\n\n    uint flags;                        /// FUNCFLAG.xxxxx\n\n    extern (D) this(const ref Loc loc, const ref Loc endloc, Identifier id, StorageClass storage_class, Type type)\n    {\n        super(id);\n        //printf(\"FuncDeclaration(id = '%s', type = %p)\\n\", id.toChars(), type);\n        //printf(\"storage_class = x%x\\n\", storage_class);\n        this.storage_class = storage_class;\n        this.type = type;\n        if (type)\n        {\n            // Normalize storage_class, because function-type related attributes\n            // are already set in the 'type' in parsing phase.\n            this.storage_class &= ~(STC.TYPECTOR | STC.FUNCATTR);\n        }\n        this.loc = loc;\n        this.endloc = endloc;\n        /* The type given for \"infer the return type\" is a TypeFunction with\n         * NULL for the return type.\n         */\n        inferRetType = (type && type.nextOf() is null);\n    }\n\n    static FuncDeclaration create(const ref Loc loc, const ref Loc endloc, Identifier id, StorageClass storage_class, Type type)\n    {\n        return new FuncDeclaration(loc, endloc, id, storage_class, type);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        //printf(\"FuncDeclaration::syntaxCopy('%s')\\n\", toChars());\n        FuncDeclaration f = s ? cast(FuncDeclaration)s : new FuncDeclaration(loc, endloc, ident, storage_class, type.syntaxCopy());\n        f.frequires = frequires ? Statement.arraySyntaxCopy(frequires) : null;\n        f.fensures = fensures ? Ensure.arraySyntaxCopy(fensures) : null;\n        f.fbody = fbody ? fbody.syntaxCopy() : null;\n        assert(!fthrows); // deprecated\n        return f;\n    }\n\n    /****************************************************\n     * Resolve forward reference of function signature -\n     * parameter types, return type, and attributes.\n     * Returns false if any errors exist in the signature.\n     */\n    final bool functionSemantic()\n    {\n        if (!_scope)\n            return !errors;\n\n        if (!originalType) // semantic not yet run\n        {\n            TemplateInstance spec = isSpeculative();\n            uint olderrs = global.errors;\n            uint oldgag = global.gag;\n            if (global.gag && !spec)\n                global.gag = 0;\n            dsymbolSemantic(this, _scope);\n            global.gag = oldgag;\n            if (spec && global.errors != olderrs)\n                spec.errors = (global.errors - olderrs != 0);\n            if (olderrs != global.errors) // if errors compiling this function\n                return false;\n        }\n\n        // if inferring return type, sematic3 needs to be run\n        // - When the function body contains any errors, we cannot assume\n        //   the inferred return type is valid.\n        //   So, the body errors should become the function signature error.\n        if (inferRetType && type && !type.nextOf())\n            return functionSemantic3();\n\n        TemplateInstance ti;\n        if (isInstantiated() && !isVirtualMethod() &&\n            ((ti = parent.isTemplateInstance()) is null || ti.isTemplateMixin() || ti.tempdecl.ident == ident))\n        {\n            AggregateDeclaration ad = isMember2();\n            if (ad && ad.sizeok != Sizeok.done)\n            {\n                /* Currently dmd cannot resolve forward references per methods,\n                 * then setting SIZOKfwd is too conservative and would break existing code.\n                 * So, just stop method attributes inference until ad.dsymbolSemantic() done.\n                 */\n                //ad.sizeok = Sizeok.fwd;\n            }\n            else\n                return functionSemantic3() || !errors;\n        }\n\n        if (storage_class & STC.inference)\n            return functionSemantic3() || !errors;\n\n        return !errors;\n    }\n\n    /****************************************************\n     * Resolve forward reference of function body.\n     * Returns false if any errors exist in the body.\n     */\n    final bool functionSemantic3()\n    {\n        if (semanticRun < PASS.semantic3 && _scope)\n        {\n            /* Forward reference - we need to run semantic3 on this function.\n             * If errors are gagged, and it's not part of a template instance,\n             * we need to temporarily ungag errors.\n             */\n            TemplateInstance spec = isSpeculative();\n            uint olderrs = global.errors;\n            uint oldgag = global.gag;\n            if (global.gag && !spec)\n                global.gag = 0;\n            semantic3(this, _scope);\n            global.gag = oldgag;\n\n            // If it is a speculatively-instantiated template, and errors occur,\n            // we need to mark the template as having errors.\n            if (spec && global.errors != olderrs)\n                spec.errors = (global.errors - olderrs != 0);\n            if (olderrs != global.errors) // if errors compiling this function\n                return false;\n        }\n\n        return !errors && !semantic3Errors;\n    }\n\n    /****************************************************\n     * Check that this function type is properly resolved.\n     * If not, report \"forward reference error\" and return true.\n     */\n    extern (D) final bool checkForwardRef(const ref Loc loc)\n    {\n        if (!functionSemantic())\n            return true;\n\n        /* No deco means the functionSemantic() call could not resolve\n         * forward referenes in the type of this function.\n         */\n        if (!type.deco)\n        {\n            bool inSemantic3 = (inferRetType && semanticRun >= PASS.semantic3);\n            .error(loc, \"forward reference to %s`%s`\",\n                (inSemantic3 ? \"inferred return type of function \" : \"\").ptr,\n                toChars());\n            return true;\n        }\n        return false;\n    }\n\n    // called from semantic3\n    final VarDeclaration declareThis(Scope* sc, AggregateDeclaration ad)\n    {\n        if (ad)\n        {\n            //printf(\"declareThis() %s\\n\", toChars());\n            Type thandle = ad.handleType();\n            assert(thandle);\n            thandle = thandle.addMod(type.mod);\n            thandle = thandle.addStorageClass(storage_class);\n            VarDeclaration v = new ThisDeclaration(loc, thandle);\n            v.storage_class |= STC.parameter;\n            if (thandle.ty == Tstruct)\n            {\n                v.storage_class |= STC.ref_;\n                // if member function is marked 'inout', then 'this' is 'return ref'\n                if (type.ty == Tfunction && (cast(TypeFunction)type).iswild & 2)\n                    v.storage_class |= STC.return_;\n            }\n            if (type.ty == Tfunction)\n            {\n                TypeFunction tf = cast(TypeFunction)type;\n                if (tf.isreturn)\n                    v.storage_class |= STC.return_;\n                if (tf.isscope)\n                    v.storage_class |= STC.scope_;\n            }\n            if (flags & FUNCFLAG.inferScope && !(v.storage_class & STC.scope_))\n                v.storage_class |= STC.maybescope;\n\n            v.dsymbolSemantic(sc);\n            if (!sc.insert(v))\n                assert(0);\n            v.parent = this;\n            return v;\n        }\n        if (isNested())\n        {\n            /* The 'this' for a nested function is the link to the\n             * enclosing function's stack frame.\n             * Note that nested functions and member functions are disjoint.\n             */\n            VarDeclaration v = new ThisDeclaration(loc, Type.tvoid.pointerTo());\n            v.storage_class |= STC.parameter;\n            if (type.ty == Tfunction)\n            {\n                TypeFunction tf = cast(TypeFunction)type;\n                if (tf.isreturn)\n                    v.storage_class |= STC.return_;\n                if (tf.isscope)\n                    v.storage_class |= STC.scope_;\n            }\n            if (flags & FUNCFLAG.inferScope && !(v.storage_class & STC.scope_))\n                v.storage_class |= STC.maybescope;\n\n            v.dsymbolSemantic(sc);\n            if (!sc.insert(v))\n                assert(0);\n            v.parent = this;\n            return v;\n        }\n        return null;\n    }\n\n    override final bool equals(RootObject o)\n    {\n        if (this == o)\n            return true;\n\n        Dsymbol s = isDsymbol(o);\n        if (s)\n        {\n            alias fd1 = this;\n            auto  fd2 = s.isFuncDeclaration();\n            if (!fd2)\n                return false;\n\n            auto fa1 = fd1.isFuncAliasDeclaration();\n            auto fa2 = fd2.isFuncAliasDeclaration();\n            if (fa1 && fa2)\n            {\n                return fa1.toAliasFunc().equals(fa2.toAliasFunc()) && fa1.hasOverloads == fa2.hasOverloads;\n            }\n\n            if (fa1 && (fd1 = fa1.toAliasFunc()).isUnique() && !fa1.hasOverloads)\n                fa1 = null;\n            if (fa2 && (fd2 = fa2.toAliasFunc()).isUnique() && !fa2.hasOverloads)\n                fa2 = null;\n            if ((fa1 !is null) != (fa2 !is null))\n                return false;\n\n            return fd1.toParent().equals(fd2.toParent()) && fd1.ident.equals(fd2.ident) && fd1.type.equals(fd2.type);\n        }\n        return false;\n    }\n\n    /****************************************************\n     * Determine if 'this' overrides fd.\n     * Return !=0 if it does.\n     */\n    final int overrides(FuncDeclaration fd)\n    {\n        int result = 0;\n        if (fd.ident == ident)\n        {\n            int cov = type.covariant(fd.type);\n            if (cov)\n            {\n                ClassDeclaration cd1 = toParent().isClassDeclaration();\n                ClassDeclaration cd2 = fd.toParent().isClassDeclaration();\n                if (cd1 && cd2 && cd2.isBaseOf(cd1, null))\n                    result = 1;\n            }\n        }\n        return result;\n    }\n\n    /*************************************************\n     * Find index of function in vtbl[0..dim] that\n     * this function overrides.\n     * Prefer an exact match to a covariant one.\n     * Params:\n     *      vtbl     = vtable to use\n     *      dim      = maximal vtable dimension\n     *      fix17349 = enable fix https://issues.dlang.org/show_bug.cgi?id=17349\n     * Returns:\n     *      -1      didn't find one\n     *      -2      can't determine because of forward references\n     */\n    final int findVtblIndex(Dsymbols* vtbl, int dim, bool fix17349 = true)\n    {\n        //printf(\"findVtblIndex() %s\\n\", toChars());\n        FuncDeclaration mismatch = null;\n        StorageClass mismatchstc = 0;\n        int mismatchvi = -1;\n        int exactvi = -1;\n        int bestvi = -1;\n        for (int vi = 0; vi < dim; vi++)\n        {\n            FuncDeclaration fdv = (*vtbl)[vi].isFuncDeclaration();\n            if (fdv && fdv.ident == ident)\n            {\n                if (type.equals(fdv.type)) // if exact match\n                {\n                    if (fdv.parent.isClassDeclaration())\n                    {\n                        if (fdv.isFuture())\n                        {\n                            bestvi = vi;\n                            continue;           // keep looking\n                        }\n                        return vi; // no need to look further\n                    }\n\n                    if (exactvi >= 0)\n                    {\n                        error(\"cannot determine overridden function\");\n                        return exactvi;\n                    }\n                    exactvi = vi;\n                    bestvi = vi;\n                    continue;\n                }\n\n                StorageClass stc = 0;\n                int cov = type.covariant(fdv.type, &stc, fix17349);\n                //printf(\"\\tbaseclass cov = %d\\n\", cov);\n                switch (cov)\n                {\n                case 0:\n                    // types are distinct\n                    break;\n\n                case 1:\n                    bestvi = vi; // covariant, but not identical\n                    break;\n                    // keep looking for an exact match\n\n                case 2:\n                    mismatchvi = vi;\n                    mismatchstc = stc;\n                    mismatch = fdv; // overrides, but is not covariant\n                    break;\n                    // keep looking for an exact match\n\n                case 3:\n                    return -2; // forward references\n\n                default:\n                    assert(0);\n                }\n            }\n        }\n        if (bestvi == -1 && mismatch)\n        {\n            //type.print();\n            //mismatch.type.print();\n            //printf(\"%s %s\\n\", type.deco, mismatch.type.deco);\n            //printf(\"stc = %llx\\n\", mismatchstc);\n            if (mismatchstc)\n            {\n                // Fix it by modifying the type to add the storage classes\n                type = type.addStorageClass(mismatchstc);\n                bestvi = mismatchvi;\n            }\n        }\n        return bestvi;\n    }\n\n    /*********************************\n     * If function a function in a base class,\n     * return that base class.\n     * Returns:\n     *  base class if overriding, null if not\n     */\n    final BaseClass* overrideInterface()\n    {\n        if (ClassDeclaration cd = toParent2().isClassDeclaration())\n        {\n            foreach (b; cd.interfaces)\n            {\n                auto v = findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.dim);\n                if (v >= 0)\n                    return b;\n            }\n        }\n        return null;\n    }\n\n    /****************************************************\n     * Overload this FuncDeclaration with the new one f.\n     * Return true if successful; i.e. no conflict.\n     */\n    override bool overloadInsert(Dsymbol s)\n    {\n        //printf(\"FuncDeclaration::overloadInsert(s = %s) this = %s\\n\", s.toChars(), toChars());\n        assert(s != this);\n        AliasDeclaration ad = s.isAliasDeclaration();\n        if (ad)\n        {\n            if (overnext)\n                return overnext.overloadInsert(ad);\n            if (!ad.aliassym && ad.type.ty != Tident && ad.type.ty != Tinstance && ad.type.ty != Ttypeof)\n            {\n                //printf(\"\\tad = '%s'\\n\", ad.type.toChars());\n                return false;\n            }\n            overnext = ad;\n            //printf(\"\\ttrue: no conflict\\n\");\n            return true;\n        }\n        TemplateDeclaration td = s.isTemplateDeclaration();\n        if (td)\n        {\n            if (!td.funcroot)\n                td.funcroot = this;\n            if (overnext)\n                return overnext.overloadInsert(td);\n            overnext = td;\n            return true;\n        }\n        FuncDeclaration fd = s.isFuncDeclaration();\n        if (!fd)\n            return false;\n\n        version (none)\n        {\n            /* Disable this check because:\n             *  const void foo();\n             * semantic() isn't run yet on foo(), so the const hasn't been\n             * applied yet.\n             */\n            if (type)\n            {\n                printf(\"type = %s\\n\", type.toChars());\n                printf(\"fd.type = %s\\n\", fd.type.toChars());\n            }\n            // fd.type can be NULL for overloaded constructors\n            if (type && fd.type && fd.type.covariant(type) && fd.type.mod == type.mod && !isFuncAliasDeclaration())\n            {\n                //printf(\"\\tfalse: conflict %s\\n\", kind());\n                return false;\n            }\n        }\n\n        if (overnext)\n        {\n            td = overnext.isTemplateDeclaration();\n            if (td)\n                fd.overloadInsert(td);\n            else\n                return overnext.overloadInsert(fd);\n        }\n        overnext = fd;\n        //printf(\"\\ttrue: no conflict\\n\");\n        return true;\n    }\n\n    /********************************************\n     * Find function in overload list that exactly matches t.\n     */\n    final FuncDeclaration overloadExactMatch(Type t)\n    {\n        FuncDeclaration fd;\n        overloadApply(this, (Dsymbol s)\n        {\n            auto f = s.isFuncDeclaration();\n            if (!f)\n                return 0;\n            if (t.equals(f.type))\n            {\n                fd = f;\n                return 1;\n            }\n\n            /* Allow covariant matches, as long as the return type\n             * is just a const conversion.\n             * This allows things like pure functions to match with an impure function type.\n             */\n            if (t.ty == Tfunction)\n            {\n                auto tf = cast(TypeFunction)f.type;\n                if (tf.covariant(t) == 1 &&\n                    tf.nextOf().implicitConvTo(t.nextOf()) >= MATCH.constant)\n                {\n                    fd = f;\n                    return 1;\n                }\n            }\n            return 0;\n        });\n        return fd;\n    }\n\n    /********************************************\n     * Find function in overload list that matches to the 'this' modifier.\n     * There's four result types.\n     *\n     * 1. If the 'tthis' matches only one candidate, it's an \"exact match\".\n     *    Returns the function and 'hasOverloads' is set to false.\n     *      eg. If 'tthis\" is mutable and there's only one mutable method.\n     * 2. If there's two or more match candidates, but a candidate function will be\n     *    a \"better match\".\n     *    Returns the better match function but 'hasOverloads' is set to true.\n     *      eg. If 'tthis' is mutable, and there's both mutable and const methods,\n     *          the mutable method will be a better match.\n     * 3. If there's two or more match candidates, but there's no better match,\n     *    Returns null and 'hasOverloads' is set to true to represent \"ambiguous match\".\n     *      eg. If 'tthis' is mutable, and there's two or more mutable methods.\n     * 4. If there's no candidates, it's \"no match\" and returns null with error report.\n     *      e.g. If 'tthis' is const but there's no const methods.\n     */\n    final FuncDeclaration overloadModMatch(const ref Loc loc, Type tthis, ref bool hasOverloads)\n    {\n        //printf(\"FuncDeclaration::overloadModMatch('%s')\\n\", toChars());\n        Match m;\n        m.last = MATCH.nomatch;\n        overloadApply(this, (Dsymbol s)\n        {\n            auto f = s.isFuncDeclaration();\n            if (!f || f == m.lastf) // skip duplicates\n                return 0;\n            m.anyf = f;\n\n            auto tf = f.type.toTypeFunction();\n            //printf(\"tf = %s\\n\", tf.toChars());\n\n            MATCH match;\n            if (tthis) // non-static functions are preferred than static ones\n            {\n                if (f.needThis())\n                    match = f.isCtorDeclaration() ? MATCH.exact : MODmethodConv(tthis.mod, tf.mod);\n                else\n                    match = MATCH.constant; // keep static function in overload candidates\n            }\n            else // static functions are preferred than non-static ones\n            {\n                if (f.needThis())\n                    match = MATCH.convert;\n                else\n                    match = MATCH.exact;\n            }\n            if (match == MATCH.nomatch)\n                return 0;\n\n            if (match > m.last) goto LcurrIsBetter;\n            if (match < m.last) goto LlastIsBetter;\n\n            // See if one of the matches overrides the other.\n            if (m.lastf.overrides(f)) goto LlastIsBetter;\n            if (f.overrides(m.lastf)) goto LcurrIsBetter;\n\n        Lambiguous:\n            //printf(\"\\tambiguous\\n\");\n            m.nextf = f;\n            m.count++;\n            return 0;\n\n        LlastIsBetter:\n            //printf(\"\\tlastbetter\\n\");\n            m.count++; // count up\n            return 0;\n\n        LcurrIsBetter:\n            //printf(\"\\tisbetter\\n\");\n            if (m.last <= MATCH.convert)\n            {\n                // clear last secondary matching\n                m.nextf = null;\n                m.count = 0;\n            }\n            m.last = match;\n            m.lastf = f;\n            m.count++; // count up\n            return 0;\n        });\n\n        if (m.count == 1)       // exact match\n        {\n            hasOverloads = false;\n        }\n        else if (m.count > 1)   // better or ambiguous match\n        {\n            hasOverloads = true;\n        }\n        else                    // no match\n        {\n            hasOverloads = true;\n            auto tf = this.type.toTypeFunction();\n            assert(tthis);\n            assert(!MODimplicitConv(tthis.mod, tf.mod)); // modifier mismatch\n            {\n                OutBuffer thisBuf, funcBuf;\n                MODMatchToBuffer(&thisBuf, tthis.mod, tf.mod);\n                MODMatchToBuffer(&funcBuf, tf.mod, tthis.mod);\n                .error(loc, \"%smethod %s is not callable using a %sobject\",\n                    funcBuf.peekString(), this.toPrettyChars(), thisBuf.peekString());\n            }\n        }\n        return m.lastf;\n    }\n\n    /********************************************\n     * find function template root in overload list\n     */\n    final TemplateDeclaration findTemplateDeclRoot()\n    {\n        FuncDeclaration f = this;\n        while (f && f.overnext)\n        {\n            //printf(\"f.overnext = %p %s\\n\", f.overnext, f.overnext.toChars());\n            TemplateDeclaration td = f.overnext.isTemplateDeclaration();\n            if (td)\n                return td;\n            f = f.overnext.isFuncDeclaration();\n        }\n        return null;\n    }\n\n    /********************************************\n     * Returns true if function was declared\n     * directly or indirectly in a unittest block\n     */\n    final bool inUnittest()\n    {\n        Dsymbol f = this;\n        do\n        {\n            if (f.isUnitTestDeclaration())\n                return true;\n            f = f.toParent();\n        }\n        while (f);\n        return false;\n    }\n\n    /*************************************\n     * Determine partial specialization order of 'this' vs g.\n     * This is very similar to TemplateDeclaration::leastAsSpecialized().\n     * Returns:\n     *      match   'this' is at least as specialized as g\n     *      0       g is more specialized than 'this'\n     */\n    final MATCH leastAsSpecialized(FuncDeclaration g)\n    {\n        enum LOG_LEASTAS = 0;\n        static if (LOG_LEASTAS)\n        {\n            printf(\"%s.leastAsSpecialized(%s)\\n\", toChars(), g.toChars());\n            printf(\"%s, %s\\n\", type.toChars(), g.type.toChars());\n        }\n\n        /* This works by calling g() with f()'s parameters, and\n         * if that is possible, then f() is at least as specialized\n         * as g() is.\n         */\n\n        TypeFunction tf = type.toTypeFunction();\n        TypeFunction tg = g.type.toTypeFunction();\n        size_t nfparams = Parameter.dim(tf.parameters);\n\n        /* If both functions have a 'this' pointer, and the mods are not\n         * the same and g's is not const, then this is less specialized.\n         */\n        if (needThis() && g.needThis() && tf.mod != tg.mod)\n        {\n            if (isCtorDeclaration())\n            {\n                if (!MODimplicitConv(tg.mod, tf.mod))\n                    return MATCH.nomatch;\n            }\n            else\n            {\n                if (!MODimplicitConv(tf.mod, tg.mod))\n                    return MATCH.nomatch;\n            }\n        }\n\n        /* Create a dummy array of arguments out of the parameters to f()\n         */\n        Expressions args = Expressions(nfparams);\n        for (size_t u = 0; u < nfparams; u++)\n        {\n            Parameter p = Parameter.getNth(tf.parameters, u);\n            Expression e;\n            if (p.storageClass & (STC.ref_ | STC.out_))\n            {\n                e = new IdentifierExp(Loc.initial, p.ident);\n                e.type = p.type;\n            }\n            else\n                e = p.type.defaultInitLiteral(Loc.initial);\n            args[u] = e;\n        }\n\n        MATCH m = tg.callMatch(null, &args, 1);\n        if (m > MATCH.nomatch)\n        {\n            /* A variadic parameter list is less specialized than a\n             * non-variadic one.\n             */\n            if (tf.varargs && !tg.varargs)\n                goto L1; // less specialized\n\n            static if (LOG_LEASTAS)\n            {\n                printf(\"  matches %d, so is least as specialized\\n\", m);\n            }\n            return m;\n        }\n    L1:\n        static if (LOG_LEASTAS)\n        {\n            printf(\"  doesn't match, so is not as specialized\\n\");\n        }\n        return MATCH.nomatch;\n    }\n\n    /********************************\n     * Labels are in a separate scope, one per function.\n     */\n    final LabelDsymbol searchLabel(Identifier ident)\n    {\n        Dsymbol s;\n        if (!labtab)\n            labtab = new DsymbolTable(); // guess we need one\n\n        s = labtab.lookup(ident);\n        if (!s)\n        {\n            s = new LabelDsymbol(ident);\n            labtab.insert(s);\n        }\n        return cast(LabelDsymbol)s;\n    }\n\n    /*****************************************\n     * Determine lexical level difference from 'this' to nested function 'fd'.\n     * Error if this cannot call fd.\n     * Returns:\n     *      0       same level\n     *      >0      decrease nesting by number\n     *      -1      increase nesting by 1 (fd is nested within 'this')\n     *      -2      error\n     */\n    final int getLevel(const ref Loc loc, Scope* sc, FuncDeclaration fd)\n    {\n        int level;\n        Dsymbol s;\n        Dsymbol fdparent;\n\n        //printf(\"FuncDeclaration::getLevel(fd = '%s')\\n\", fd.toChars());\n        fdparent = fd.toParent2();\n        if (fdparent == this)\n            return -1;\n        s = this;\n        level = 0;\n        while (fd != s && fdparent != s.toParent2())\n        {\n            //printf(\"\\ts = %s, '%s'\\n\", s.kind(), s.toChars());\n            FuncDeclaration thisfd = s.isFuncDeclaration();\n            if (thisfd)\n            {\n                if (!thisfd.isNested() && !thisfd.vthis && !sc.intypeof)\n                    goto Lerr;\n            }\n            else\n            {\n                AggregateDeclaration thiscd = s.isAggregateDeclaration();\n                if (thiscd)\n                {\n                    /* AggregateDeclaration::isNested returns true only when\n                     * it has a hidden pointer.\n                     * But, calling the function belongs unrelated lexical scope\n                     * is still allowed inside typeof.\n                     *\n                     * struct Map(alias fun) {\n                     *   typeof({ return fun(); }) RetType;\n                     *   // No member function makes Map struct 'not nested'.\n                     * }\n                     */\n                    if (!thiscd.isNested() && !sc.intypeof)\n                        goto Lerr;\n                }\n                else\n                    goto Lerr;\n            }\n\n            s = s.toParent2();\n            assert(s);\n            level++;\n        }\n        return level;\n\n    Lerr:\n        // Don't give error if in template constraint\n        if (!(sc.flags & SCOPE.constraint))\n        {\n            const(char)* xstatic = isStatic() ? \"static \" : \"\";\n            // better diagnostics for static functions\n            .error(loc, \"%s%s %s cannot access frame of function %s\", xstatic, kind(), toPrettyChars(), fd.toPrettyChars());\n            return -2;\n        }\n        return 1;\n    }\n\n    override const(char)* toPrettyChars(bool QualifyTypes = false)\n    {\n        if (isMain())\n            return \"D main\";\n        else\n            return Dsymbol.toPrettyChars(QualifyTypes);\n    }\n\n    /** for diagnostics, e.g. 'int foo(int x, int y) pure' */\n    final const(char)* toFullSignature()\n    {\n        OutBuffer buf;\n        functionToBufferWithIdent(type.toTypeFunction(), &buf, toChars());\n        return buf.extractString();\n    }\n\n    final bool isMain() const\n    {\n        return ident == Id.main && linkage != LINK.c && !isMember() && !isNested();\n    }\n\n    final bool isCMain() const\n    {\n        return ident == Id.main && linkage == LINK.c && !isMember() && !isNested();\n    }\n\n    final bool isWinMain() const\n    {\n        //printf(\"FuncDeclaration::isWinMain() %s\\n\", toChars());\n        version (none)\n        {\n            bool x = ident == Id.WinMain && linkage != LINK.c && !isMember();\n            printf(\"%s\\n\", x ? \"yes\" : \"no\");\n            return x;\n        }\n        else\n        {\n            return ident == Id.WinMain && linkage != LINK.c && !isMember();\n        }\n    }\n\n    final bool isDllMain() const\n    {\n        return ident == Id.DllMain && linkage != LINK.c && !isMember();\n    }\n\n    final bool isRtInit() const\n    {\n        return ident == Id.rt_init && linkage == LINK.c && !isMember() && !isNested();\n    }\n\n    override final bool isExport() const\n    {\n        return protection.kind == Prot.Kind.export_;\n    }\n\n    override final bool isImportedSymbol() const\n    {\n        //printf(\"isImportedSymbol()\\n\");\n        //printf(\"protection = %d\\n\", protection);\n        return (protection.kind == Prot.Kind.export_) && !fbody;\n    }\n\n    override final bool isCodeseg() const pure nothrow @nogc @safe\n    {\n        return true; // functions are always in the code segment\n    }\n\n    override final bool isOverloadable()\n    {\n        return true; // functions can be overloaded\n    }\n\n    /***********************************\n     * Override so it can work even if semantic() hasn't yet\n     * been run.\n     */\n    override final bool isAbstract()\n    {\n        if (storage_class & STC.abstract_)\n            return true;\n        if (semanticRun >= PASS.semanticdone)\n            return false;\n\n        if (_scope)\n        {\n           if (_scope.stc & STC.abstract_)\n                return true;\n           parent = _scope.parent;\n           Dsymbol parent = toParent();\n           if (parent.isInterfaceDeclaration())\n                return true;\n        }\n        return false;\n    }\n\n    /**********************************\n     * Decide if attributes for this function can be inferred from examining\n     * the function body.\n     * Returns:\n     *  true if can\n     */\n    final bool canInferAttributes(Scope* sc)\n    {\n        if (!fbody)\n            return false;\n\n        if (isVirtualMethod())\n            return false;               // since they may be overridden\n\n        if (sc.func &&\n            /********** this is for backwards compatibility for the moment ********/\n            (!isMember() || sc.func.isSafeBypassingInference() && !isInstantiated()))\n            return true;\n\n        if (isFuncLiteralDeclaration() ||               // externs are not possible with literals\n            (storage_class & STC.inference) ||           // do attribute inference\n            (inferRetType && !isCtorDeclaration()))\n            return true;\n\n        if (isInstantiated())\n        {\n            auto ti = parent.isTemplateInstance();\n            if (ti is null || ti.isTemplateMixin() || ti.tempdecl.ident == ident)\n                return true;\n        }\n\n        return false;\n    }\n\n    /*****************************************\n     * Initialize for inferring the attributes of this function.\n     */\n    final void initInferAttributes()\n    {\n        //printf(\"initInferAttributes() for %s (%s)\\n\", toPrettyChars(), ident.toChars());\n        TypeFunction tf = type.toTypeFunction();\n        if (tf.purity == PURE.impure) // purity not specified\n            flags |= FUNCFLAG.purityInprocess;\n\n        if (tf.trust == TRUST.default_)\n            flags |= FUNCFLAG.safetyInprocess;\n\n        if (!tf.isnothrow)\n            flags |= FUNCFLAG.nothrowInprocess;\n\n        if (!tf.isnogc)\n            flags |= FUNCFLAG.nogcInprocess;\n\n        if (!isVirtual() || introducing)\n            flags |= FUNCFLAG.returnInprocess;\n\n        // Initialize for inferring STC.scope_\n        if (global.params.vsafe)\n            flags |= FUNCFLAG.inferScope;\n    }\n\n    final PURE isPure()\n    {\n        //printf(\"FuncDeclaration::isPure() '%s'\\n\", toChars());\n        TypeFunction tf = type.toTypeFunction();\n        if (flags & FUNCFLAG.purityInprocess)\n            setImpure();\n        if (tf.purity == PURE.fwdref)\n            tf.purityLevel();\n        PURE purity = tf.purity;\n        if (purity > PURE.weak && isNested())\n            purity = PURE.weak;\n        if (purity > PURE.weak && needThis())\n        {\n            // The attribute of the 'this' reference affects purity strength\n            if (type.mod & MODFlags.immutable_)\n            {\n            }\n            else if (type.mod & (MODFlags.const_ | MODFlags.wild) && purity >= PURE.const_)\n                purity = PURE.const_;\n            else\n                purity = PURE.weak;\n        }\n        tf.purity = purity;\n        // ^ This rely on the current situation that every FuncDeclaration has a\n        //   unique TypeFunction.\n        return purity;\n    }\n\n    final PURE isPureBypassingInference()\n    {\n        if (flags & FUNCFLAG.purityInprocess)\n            return PURE.fwdref;\n        else\n            return isPure();\n    }\n\n    /**************************************\n     * The function is doing something impure,\n     * so mark it as impure.\n     * If there's a purity error, return true.\n     */\n    final bool setImpure()\n    {\n        if (flags & FUNCFLAG.purityInprocess)\n        {\n            flags &= ~FUNCFLAG.purityInprocess;\n            if (fes)\n                fes.func.setImpure();\n        }\n        else if (isPure())\n            return true;\n        return false;\n    }\n\n    final bool isSafe()\n    {\n        if (flags & FUNCFLAG.safetyInprocess)\n            setUnsafe();\n        return type.toTypeFunction().trust == TRUST.safe;\n    }\n\n    final bool isSafeBypassingInference()\n    {\n        return !(flags & FUNCFLAG.safetyInprocess) && isSafe();\n    }\n\n    final bool isTrusted()\n    {\n        if (flags & FUNCFLAG.safetyInprocess)\n            setUnsafe();\n        return type.toTypeFunction().trust == TRUST.trusted;\n    }\n\n    /**************************************\n     * The function is doing something unsave,\n     * so mark it as unsafe.\n     * If there's a safe error, return true.\n     */\n    final bool setUnsafe()\n    {\n        if (flags & FUNCFLAG.safetyInprocess)\n        {\n            flags &= ~FUNCFLAG.safetyInprocess;\n            type.toTypeFunction().trust = TRUST.system;\n            if (fes)\n                fes.func.setUnsafe();\n        }\n        else if (isSafe())\n            return true;\n        return false;\n    }\n\n    final bool isNogc()\n    {\n        //printf(\"isNogc() %s, inprocess: %d\\n\", toChars(), !!(flags & FUNCFLAG.nogcInprocess));\n        if (flags & FUNCFLAG.nogcInprocess)\n            setGC();\n        return type.toTypeFunction().isnogc;\n    }\n\n    final bool isNogcBypassingInference()\n    {\n        return !(flags & FUNCFLAG.nogcInprocess) && isNogc();\n    }\n\n    /**************************************\n     * The function is doing something that may allocate with the GC,\n     * so mark it as not nogc (not no-how).\n     * Returns:\n     *      true if function is marked as @nogc, meaning a user error occurred\n     */\n    final bool setGC()\n    {\n        //printf(\"setGC() %s\\n\", toChars());\n        if (flags & FUNCFLAG.nogcInprocess && semanticRun < PASS.semantic3 && _scope)\n        {\n            this.semantic2(_scope);\n            this.semantic3(_scope);\n        }\n\n        if (flags & FUNCFLAG.nogcInprocess)\n        {\n            flags &= ~FUNCFLAG.nogcInprocess;\n            type.toTypeFunction().isnogc = false;\n            if (fes)\n                fes.func.setGC();\n        }\n        else if (isNogc())\n            return true;\n        return false;\n    }\n\n    final void printGCUsage(const ref Loc loc, const(char)* warn)\n    {\n        if (!global.params.vgc)\n            return;\n\n        Module m = getModule();\n        if (m && m.isRoot() && !inUnittest())\n        {\n            message(loc, \"vgc: %s\", warn);\n        }\n    }\n\n    /********************************************\n     * See if pointers from function parameters, mutable globals, or uplevel functions\n     * could leak into return value.\n     * Returns:\n     *   true if the function return value is isolated from\n     *   any inputs to the function\n     */\n    final bool isReturnIsolated()\n    {\n        TypeFunction tf = type.toTypeFunction();\n        assert(tf.next);\n\n        Type treti = tf.next;\n        if (tf.isref)\n            return isTypeIsolatedIndirect(treti);              // check influence from parameters\n\n        return isTypeIsolated(treti);\n    }\n\n    /********************\n     * See if pointers from function parameters, mutable globals, or uplevel functions\n     * could leak into type `t`.\n     * Params:\n     *   t = type to check if it is isolated\n     * Returns:\n     *   true if `t` is isolated from\n     *   any inputs to the function\n     */\n    final bool isTypeIsolated(Type t)\n    {\n        //printf(\"isTypeIsolated(t: %s)\\n\", t.toChars());\n\n        t = t.baseElemOf();\n        switch (t.ty)\n        {\n            case Tarray:\n            case Tpointer:\n                return isTypeIsolatedIndirect(t.nextOf()); // go down one level\n\n            case Taarray:\n            case Tclass:\n                return isTypeIsolatedIndirect(t);\n\n            case Tstruct:\n                /* Drill down and check the struct's fields\n                 */\n                auto sym = t.toDsymbol(null).isStructDeclaration();\n                foreach (v; sym.fields)\n                {\n                    Type tmi = v.type.addMod(t.mod);\n                    //printf(\"\\tt = %s, tmi = %s\\n\", t.toChars(), tmi.toChars());\n                    if (!isTypeIsolated(tmi))\n                        return false;\n                }\n                return true;\n\n            default:\n                return true;\n        }\n    }\n\n    /********************************************\n     * Params:\n     *    t = type of object to test one level of indirection down\n     * Returns:\n     *    true if an object typed `t` has no indirections\n     *    which could have come from the function's parameters, mutable\n     *    globals, or uplevel functions.\n     */\n    private bool isTypeIsolatedIndirect(Type t)\n    {\n        //printf(\"isTypeIsolatedIndirect(t: %s)\\n\", t.toChars());\n        assert(t);\n\n        /* Since `t` is one level down from an indirection, it could pick\n         * up a reference to a mutable global or an outer function, so\n         * return false.\n         */\n        if (!isPureBypassingInference() || isNested())\n            return false;\n\n        TypeFunction tf = type.toTypeFunction();\n\n        //printf(\"isTypeIsolatedIndirect(%s) t = %s\\n\", tf.toChars(), t.toChars());\n\n        size_t dim = Parameter.dim(tf.parameters);\n        for (size_t i = 0; i < dim; i++)\n        {\n            Parameter fparam = Parameter.getNth(tf.parameters, i);\n            Type tp = fparam.type;\n            if (!tp)\n                continue;\n\n            if (fparam.storageClass & (STC.lazy_ | STC.out_ | STC.ref_))\n            {\n                if (!traverseIndirections(tp, t))\n                    return false;\n                continue;\n            }\n\n            /* Goes down one level of indirection, then calls traverseIndirection() on\n             * the result.\n             * Returns:\n             *  true if t is isolated from tp\n             */\n            static bool traverse(Type tp, Type t)\n            {\n                tp = tp.baseElemOf();\n                switch (tp.ty)\n                {\n                    case Tarray:\n                    case Tpointer:\n                        return traverseIndirections(tp.nextOf(), t);\n\n                    case Taarray:\n                    case Tclass:\n                        return traverseIndirections(tp, t);\n\n                    case Tstruct:\n                        /* Drill down and check the struct's fields\n                         */\n                        auto sym = tp.toDsymbol(null).isStructDeclaration();\n                        foreach (v; sym.fields)\n                        {\n                            Type tprmi = v.type.addMod(tp.mod);\n                            //printf(\"\\ttp = %s, tprmi = %s\\n\", tp.toChars(), tprmi.toChars());\n                            if (!traverse(tprmi, t))\n                                return false;\n                        }\n                        return true;\n\n                    default:\n                        return true;\n                }\n            }\n\n            if (!traverse(tp, t))\n                return false;\n        }\n        // The 'this' reference is a parameter, too\n        if (AggregateDeclaration ad = isCtorDeclaration() ? null : isThis())\n        {\n            Type tthis = ad.getType().addMod(tf.mod);\n            //printf(\"\\ttthis = %s\\n\", tthis.toChars());\n            if (!traverseIndirections(tthis, t))\n                return false;\n        }\n\n        return true;\n    }\n\n    /****************************************\n     * Determine if function needs a static frame pointer.\n     * Returns:\n     *  `true` if function is really nested within other function.\n     * Contracts:\n     *  If isNested() returns true, isThis() should return false.\n     */\n    bool isNested() const\n    {\n        auto f = toAliasFunc();\n        //printf(\"\\ttoParent2() = '%s'\\n\", f.toParent2().toChars());\n        return ((f.storage_class & STC.static_) == 0) &&\n                (f.linkage == LINK.d) &&\n                (f.toParent2().isFuncDeclaration() !is null);\n    }\n\n    /****************************************\n     * Determine if function is a non-static member function\n     * that has an implicit 'this' expression.\n     * Returns:\n     *  The aggregate it is a member of, or null.\n     * Contracts:\n     *  If isThis() returns true, isNested() should return false.\n     */\n    override inout(AggregateDeclaration) isThis() inout\n    {\n        //printf(\"+FuncDeclaration::isThis() '%s'\\n\", toChars());\n        auto ad = (storage_class & STC.static_) ? objc.isThis(this) : isMember2();\n        //printf(\"-FuncDeclaration::isThis() %p\\n\", ad);\n        return ad;\n    }\n\n    override final bool needThis()\n    {\n        //printf(\"FuncDeclaration::needThis() '%s'\\n\", toChars());\n        return toAliasFunc().isThis() !is null;\n    }\n\n    // Determine if a function is pedantically virtual\n    final bool isVirtualMethod()\n    {\n        if (toAliasFunc() != this)\n            return toAliasFunc().isVirtualMethod();\n\n        //printf(\"FuncDeclaration::isVirtualMethod() %s\\n\", toChars());\n        if (!isVirtual())\n            return false;\n        // If it's a final method, and does not override anything, then it is not virtual\n        if (isFinalFunc() && foverrides.dim == 0)\n        {\n            return false;\n        }\n        return true;\n    }\n\n    // Determine if function goes into virtual function pointer table\n    bool isVirtual() const\n    {\n        if (toAliasFunc() != this)\n            return toAliasFunc().isVirtual();\n\n        auto p = toParent();\n        version (none)\n        {\n            printf(\"FuncDeclaration::isVirtual(%s)\\n\", toChars());\n            printf(\"isMember:%p isStatic:%d private:%d ctor:%d !Dlinkage:%d\\n\", isMember(), isStatic(), protection == Prot.Kind.private_, isCtorDeclaration(), linkage != LINK.d);\n            printf(\"result is %d\\n\", isMember() && !(isStatic() || protection == Prot.Kind.private_ || protection == Prot.Kind.package_) && p.isClassDeclaration() && !(p.isInterfaceDeclaration() && isFinalFunc()));\n        }\n        return isMember() && !(isStatic() || protection.kind == Prot.Kind.private_ || protection.kind == Prot.Kind.package_) && p.isClassDeclaration() && !(p.isInterfaceDeclaration() && isFinalFunc());\n    }\n\n    final bool isFinalFunc() const\n    {\n        if (toAliasFunc() != this)\n            return toAliasFunc().isFinalFunc();\n\n        version (none)\n        {{\n            auto cd = toParent().isClassDeclaration();\n            printf(\"FuncDeclaration::isFinalFunc(%s), %x\\n\", toChars(), Declaration.isFinal());\n            printf(\"%p %d %d %d\\n\", isMember(), isStatic(), Declaration.isFinal(), ((cd = toParent().isClassDeclaration()) !is null && cd.storage_class & STC.final_));\n            printf(\"result is %d\\n\", isMember() && (Declaration.isFinal() || (cd !is null && cd.storage_class & STC.final_)));\n            if (cd)\n                printf(\"\\tmember of %s\\n\", cd.toChars());\n        }}\n        if (!isMember())\n            return false;\n        if (Declaration.isFinal())\n            return true;\n        auto cd = toParent().isClassDeclaration();\n        return (cd !is null) && (cd.storage_class & STC.final_);\n    }\n\n    bool addPreInvariant()\n    {\n        auto ad = isThis();\n        ClassDeclaration cd = ad ? ad.isClassDeclaration() : null;\n        return (ad && !(cd && cd.isCPPclass()) && global.params.useInvariants && (protection.kind == Prot.Kind.protected_ || protection.kind == Prot.Kind.public_ || protection.kind == Prot.Kind.export_) && !naked);\n    }\n\n    bool addPostInvariant()\n    {\n        auto ad = isThis();\n        ClassDeclaration cd = ad ? ad.isClassDeclaration() : null;\n        return (ad && !(cd && cd.isCPPclass()) && ad.inv && global.params.useInvariants && (protection.kind == Prot.Kind.protected_ || protection.kind == Prot.Kind.public_ || protection.kind == Prot.Kind.export_) && !naked);\n    }\n\n    override const(char)* kind() const\n    {\n        return generated ? \"generated function\" : \"function\";\n    }\n\n    /********************************************\n     * If there are no overloads of function f, return that function,\n     * otherwise return NULL.\n     */\n    final FuncDeclaration isUnique()\n    {\n        FuncDeclaration result = null;\n        overloadApply(this, (Dsymbol s)\n        {\n            auto f = s.isFuncDeclaration();\n            if (!f)\n                return 0;\n            if (result)\n            {\n                result = null;\n                return 1; // ambiguous, done\n            }\n            else\n            {\n                result = f;\n                return 0;\n            }\n        });\n        return result;\n    }\n\n    /*********************************************\n     * In the current function, we are calling 'this' function.\n     * 1. Check to see if the current function can call 'this' function, issue error if not.\n     * 2. If the current function is not the parent of 'this' function, then add\n     *    the current function to the list of siblings of 'this' function.\n     * 3. If the current function is a literal, and it's accessing an uplevel scope,\n     *    then mark it as a delegate.\n     * Returns true if error occurs.\n     */\n    extern (D) final bool checkNestedReference(Scope* sc, const ref Loc loc)\n    {\n        //printf(\"FuncDeclaration::checkNestedReference() %s\\n\", toPrettyChars());\n\n        if (auto fld = this.isFuncLiteralDeclaration())\n        {\n            if (fld.tok == TOK.reserved)\n            {\n                fld.tok = TOK.function_;\n                fld.vthis = null;\n            }\n        }\n\n        if (!parent || parent == sc.parent)\n            return false;\n        if (ident == Id.require || ident == Id.ensure)\n            return false;\n        if (!isThis() && !isNested())\n            return false;\n\n        // The current function\n        FuncDeclaration fdthis = sc.parent.isFuncDeclaration();\n        if (!fdthis)\n            return false; // out of function scope\n\n        Dsymbol p = toParent2();\n\n        // Function literals from fdthis to p must be delegates\n        ensureStaticLinkTo(fdthis, p);\n\n        if (isNested())\n        {\n            // The function that this function is in\n            FuncDeclaration fdv = p.isFuncDeclaration();\n            if (!fdv)\n                return false;\n            if (fdv == fdthis)\n                return false;\n\n            //printf(\"this = %s in [%s]\\n\", this.toChars(), this.loc.toChars());\n            //printf(\"fdv  = %s in [%s]\\n\", fdv .toChars(), fdv .loc.toChars());\n            //printf(\"fdthis = %s in [%s]\\n\", fdthis.toChars(), fdthis.loc.toChars());\n\n            // Add this function to the list of those which called us\n            if (fdthis != this)\n            {\n                bool found = false;\n                for (size_t i = 0; i < siblingCallers.dim; ++i)\n                {\n                    if (siblingCallers[i] == fdthis)\n                        found = true;\n                }\n                if (!found)\n                {\n                    //printf(\"\\tadding sibling %s\\n\", fdthis.toPrettyChars());\n                    if (!sc.intypeof && !(sc.flags & SCOPE.compile))\n                        siblingCallers.push(fdthis);\n                }\n            }\n\n            int lv = fdthis.getLevel(loc, sc, fdv);\n            if (lv == -2)\n                return true; // error\n            if (lv == -1)\n                return false; // downlevel call\n            if (lv == 0)\n                return false; // same level call\n\n            // Uplevel call\n        }\n        return false;\n    }\n\n    /*******************************\n     * Look at all the variables in this function that are referenced\n     * by nested functions, and determine if a closure needs to be\n     * created for them.\n     */\n    final bool needsClosure()\n    {\n        /* Need a closure for all the closureVars[] if any of the\n         * closureVars[] are accessed by a\n         * function that escapes the scope of this function.\n         * We take the conservative approach and decide that a function needs\n         * a closure if it:\n         * 1) is a virtual function\n         * 2) has its address taken\n         * 3) has a parent that escapes\n         * 4) calls another nested function that needs a closure\n         *\n         * Note that since a non-virtual function can be called by\n         * a virtual one, if that non-virtual function accesses a closure\n         * var, the closure still has to be taken. Hence, we check for isThis()\n         * instead of isVirtual(). (thanks to David Friedman)\n         *\n         * When the function returns a local struct or class, `requiresClosure`\n         * is already set to `true` upon entering this function when the\n         * struct/class refers to a local variable and a closure is needed.\n         */\n\n        //printf(\"FuncDeclaration::needsClosure() %s\\n\", toChars());\n\n        if (requiresClosure)\n            goto Lyes;\n\n        for (size_t i = 0; i < closureVars.dim; i++)\n        {\n            VarDeclaration v = closureVars[i];\n            //printf(\"\\tv = %s\\n\", v.toChars());\n\n            for (size_t j = 0; j < v.nestedrefs.dim; j++)\n            {\n                FuncDeclaration f = v.nestedrefs[j];\n                assert(f != this);\n\n                //printf(\"\\t\\tf = %p, %s, isVirtual=%d, isThis=%p, tookAddressOf=%d\\n\", f, f.toChars(), f.isVirtual(), f.isThis(), f.tookAddressOf);\n\n                /* Look to see if f escapes. We consider all parents of f within\n                 * this, and also all siblings which call f; if any of them escape,\n                 * so does f.\n                 * Mark all affected functions as requiring closures.\n                 */\n                for (Dsymbol s = f; s && s != this; s = s.parent)\n                {\n                    FuncDeclaration fx = s.isFuncDeclaration();\n                    if (!fx)\n                        continue;\n                    if (fx.isThis() || fx.tookAddressOf)\n                    {\n                        //printf(\"\\t\\tfx = %s, isVirtual=%d, isThis=%p, tookAddressOf=%d\\n\", fx.toChars(), fx.isVirtual(), fx.isThis(), fx.tookAddressOf);\n\n                        /* Mark as needing closure any functions between this and f\n                         */\n                        markAsNeedingClosure((fx == f) ? fx.parent : fx, this);\n\n                        requiresClosure = true;\n                    }\n\n                    /* We also need to check if any sibling functions that\n                     * called us, have escaped. This is recursive: we need\n                     * to check the callers of our siblings.\n                     */\n                    if (checkEscapingSiblings(fx, this))\n                        requiresClosure = true;\n\n                    /* https://issues.dlang.org/show_bug.cgi?id=12406\n                     * Iterate all closureVars to mark all descendant\n                     * nested functions that access to the closing context of this function.\n                     */\n                }\n            }\n        }\n        if (requiresClosure)\n            goto Lyes;\n\n        return false;\n\n    Lyes:\n        //printf(\"\\tneeds closure\\n\");\n        return true;\n    }\n\n    /***********************************************\n     * Check that the function contains any closure.\n     * If it's @nogc, report suitable errors.\n     * This is mostly consistent with FuncDeclaration::needsClosure().\n     *\n     * Returns:\n     *      true if any errors occur.\n     */\n    extern (D) final bool checkClosure()\n    {\n        if (!needsClosure())\n            return false;\n\n        if (setGC())\n        {\n            error(\"is `@nogc` yet allocates closures with the GC\");\n            if (global.gag)     // need not report supplemental errors\n                return true;\n        }\n        else\n        {\n            printGCUsage(loc, \"using closure causes GC allocation\");\n            return false;\n        }\n\n        FuncDeclarations a;\n        foreach (v; closureVars)\n        {\n            foreach (f; v.nestedrefs)\n            {\n                assert(f !is this);\n\n            LcheckAncestorsOfANestedRef:\n                for (Dsymbol s = f; s && s !is this; s = s.parent)\n                {\n                    auto fx = s.isFuncDeclaration();\n                    if (!fx)\n                        continue;\n                    if (fx.isThis() ||\n                        fx.tookAddressOf ||\n                        checkEscapingSiblings(fx, this))\n                    {\n                        foreach (f2; a)\n                        {\n                            if (f2 == f)\n                                break LcheckAncestorsOfANestedRef;\n                        }\n                        a.push(f);\n                        .errorSupplemental(f.loc, \"%s closes over variable %s at %s\",\n                            f.toPrettyChars(), v.toChars(), v.loc.toChars());\n                        break LcheckAncestorsOfANestedRef;\n                    }\n                }\n            }\n        }\n\n        return true;\n    }\n\n    /***********************************************\n     * Determine if function's variables are referenced by a function\n     * nested within it.\n     */\n    final bool hasNestedFrameRefs()\n    {\n        if (closureVars.dim)\n            return true;\n\n        /* If a virtual function has contracts, assume its variables are referenced\n         * by those contracts, even if they aren't. Because they might be referenced\n         * by the overridden or overriding function's contracts.\n         * This can happen because frequire and fensure are implemented as nested functions,\n         * and they can be called directly by an overriding function and the overriding function's\n         * context had better match, or\n         * https://issues.dlang.org/show_bug.cgi?id=7335 will bite.\n         */\n        if (fdrequire || fdensure)\n            return true;\n\n        if (foverrides.dim && isVirtualMethod())\n        {\n            for (size_t i = 0; i < foverrides.dim; i++)\n            {\n                FuncDeclaration fdv = foverrides[i];\n                if (fdv.hasNestedFrameRefs())\n                    return true;\n            }\n        }\n        return false;\n    }\n\n    /****************************************************\n     * Check whether result variable can be built.\n     * Returns:\n     *     `true` if the function has a return type that\n     *     is different from `void`.\n     */\n    extern (D) private bool canBuildResultVar()\n    {\n        auto f = cast(TypeFunction)type;\n        return f && f.nextOf() && f.nextOf().toBasetype().ty != Tvoid;\n    }\n\n    /****************************************************\n     * Declare result variable lazily.\n     */\n    final void buildResultVar(Scope* sc, Type tret)\n    {\n        if (!vresult)\n        {\n            Loc loc = fensure ? fensure.loc : this.loc;\n\n            /* If inferRetType is true, tret may not be a correct return type yet.\n             * So, in here it may be a temporary type for vresult, and after\n             * fbody.dsymbolSemantic() running, vresult.type might be modified.\n             */\n            vresult = new VarDeclaration(loc, tret, Id.result, null);\n            vresult.storage_class |= STC.nodtor | STC.temp;\n            if (!isVirtual())\n                vresult.storage_class |= STC.const_;\n            vresult.storage_class |= STC.result;\n\n            // set before the semantic() for checkNestedReference()\n            vresult.parent = this;\n        }\n\n        if (sc && vresult.semanticRun == PASS.init)\n        {\n            TypeFunction tf = type.toTypeFunction();\n            if (tf.isref)\n                vresult.storage_class |= STC.ref_;\n            vresult.type = tret;\n\n            vresult.dsymbolSemantic(sc);\n\n            if (!sc.insert(vresult))\n                error(\"out result %s is already defined\", vresult.toChars());\n            assert(vresult.parent == this);\n        }\n    }\n\n    /****************************************************\n     * Merge into this function the 'in' contracts of all it overrides.\n     * 'in's are OR'd together, i.e. only one of them needs to pass.\n     */\n    final Statement mergeFrequire(Statement sf)\n    {\n        /* If a base function and its override both have an IN contract, then\n         * only one of them needs to succeed. This is done by generating:\n         *\n         * void derived.in() {\n         *  try {\n         *    base.in();\n         *  }\n         *  catch () {\n         *    ... body of derived.in() ...\n         *  }\n         * }\n         *\n         * So if base.in() doesn't throw, derived.in() need not be executed, and the contract is valid.\n         * If base.in() throws, then derived.in()'s body is executed.\n         */\n\n        /* Implementing this is done by having the overriding function call\n         * nested functions (the fdrequire functions) nested inside the overridden\n         * function. This requires that the stack layout of the calling function's\n         * parameters and 'this' pointer be in the same place (as the nested\n         * function refers to them).\n         * This is easy for the parameters, as they are all on the stack in the same\n         * place by definition, since it's an overriding function. The problem is\n         * getting the 'this' pointer in the same place, since it is a local variable.\n         * We did some hacks in the code generator to make this happen:\n         *  1. always generate exception handler frame, or at least leave space for it\n         *     in the frame (Windows 32 SEH only)\n         *  2. always generate an EBP style frame\n         *  3. since 'this' is passed in a register that is subsequently copied into\n         *     a stack local, allocate that local immediately following the exception\n         *     handler block, so it is always at the same offset from EBP.\n         */\n        foreach (fdv; foverrides)\n        {\n            /* The semantic pass on the contracts of the overridden functions must\n             * be completed before code generation occurs.\n             * https://issues.dlang.org/show_bug.cgi?id=3602\n             */\n            if (fdv.frequires && fdv.semanticRun != PASS.semantic3done)\n            {\n                assert(fdv._scope);\n                Scope* sc = fdv._scope.push();\n                sc.stc &= ~STC.override_;\n                fdv.semantic3(sc);\n                sc.pop();\n            }\n\n            sf = fdv.mergeFrequire(sf);\n            if (sf && fdv.fdrequire)\n            {\n                //printf(\"fdv.frequire: %s\\n\", fdv.frequire.toChars());\n                /* Make the call:\n                 *   try { __require(); }\n                 *   catch (Throwable) { frequire; }\n                 */\n                Expression eresult = null;\n                Expression e = new CallExp(loc, new VarExp(loc, fdv.fdrequire, false), eresult);\n                Statement s2 = new ExpStatement(loc, e);\n\n                auto c = new Catch(loc, getThrowable(), null, sf);\n                c.internalCatch = true;\n                auto catches = new Catches();\n                catches.push(c);\n                sf = new TryCatchStatement(loc, s2, catches);\n            }\n            else\n                return null;\n        }\n        return sf;\n    }\n\n    /****************************************************\n     * Determine whether an 'out' contract is declared inside\n     * the given function or any of its overrides.\n     * Params:\n     *      fd = the function to search\n     * Returns:\n     *      true    found an 'out' contract\n     */\n    static bool needsFensure(FuncDeclaration fd)\n    {\n        if (fd.fensures)\n            return true;\n\n        foreach (fdv; fd.foverrides)\n        {\n            if (needsFensure(fdv))\n                return true;\n        }\n        return false;\n    }\n\n    /****************************************************\n     * Rewrite contracts as statements.\n     */\n    final void buildEnsureRequire()\n    {\n\n        if (frequires)\n        {\n            /*   in { statements1... }\n             *   in { statements2... }\n             *   ...\n             * becomes:\n             *   in { { statements1... } { statements2... } ... }\n             */\n            assert(frequires.dim);\n            auto loc = (*frequires)[0].loc;\n            auto s = new Statements;\n            foreach (r; *frequires)\n            {\n                s.push(new ScopeStatement(r.loc, r, r.loc));\n            }\n            frequire = new CompoundStatement(loc, s);\n        }\n\n        if (fensures)\n        {\n            /*   out(id1) { statements1... }\n             *   out(id2) { statements2... }\n             *   ...\n             * becomes:\n             *   out(__result) { { ref id1 = __result; { statements1... } }\n             *                   { ref id2 = __result; { statements2... } } ... }\n             */\n            assert(fensures.dim);\n            auto loc = (*fensures)[0].ensure.loc;\n            auto s = new Statements;\n            foreach (r; *fensures)\n            {\n                if (r.id && canBuildResultVar())\n                {\n                    auto rloc = r.ensure.loc;\n                    auto resultId = new IdentifierExp(rloc, Id.result);\n                    auto init = new ExpInitializer(rloc, resultId);\n                    auto stc = STC.ref_ | STC.temp | STC.result;\n                    auto decl = new VarDeclaration(rloc, null, r.id, init, stc);\n                    auto sdecl = new ExpStatement(rloc, decl);\n                    s.push(new ScopeStatement(rloc, new CompoundStatement(rloc, sdecl, r.ensure), rloc));\n                }\n                else\n                {\n                    s.push(r.ensure);\n                }\n            }\n            fensure = new CompoundStatement(loc, s);\n        }\n\n        if (!isVirtual())\n            return;\n\n        /* Rewrite contracts as nested functions, then call them. Doing it as nested\n         * functions means that overriding functions can call them.\n         */\n        TypeFunction f = cast(TypeFunction) type;\n\n        if (frequire)\n        {\n            /*   in { ... }\n             * becomes:\n             *   void __require() { ... }\n             *   __require();\n             */\n            Loc loc = frequire.loc;\n            auto tf = new TypeFunction(null, Type.tvoid, 0, LINK.d);\n            tf.isnothrow = f.isnothrow;\n            tf.isnogc = f.isnogc;\n            tf.purity = f.purity;\n            tf.trust = f.trust;\n            auto fd = new FuncDeclaration(loc, loc, Id.require, STC.undefined_, tf);\n            fd.fbody = frequire;\n            Statement s1 = new ExpStatement(loc, fd);\n            Expression e = new CallExp(loc, new VarExp(loc, fd, false), cast(Expressions*)null);\n            Statement s2 = new ExpStatement(loc, e);\n            frequire = new CompoundStatement(loc, s1, s2);\n            fdrequire = fd;\n        }\n\n        if (fensure)\n        {\n            /*   out (result) { ... }\n             * becomes:\n             *   void __ensure(ref tret result) { ... }\n             *   __ensure(result);\n             */\n            Loc loc = fensure.loc;\n            auto fparams = new Parameters();\n            Parameter p = null;\n            if (canBuildResultVar())\n            {\n                p = new Parameter(STC.ref_ | STC.const_, f.nextOf(), Id.result, null, null);\n                fparams.push(p);\n            }\n            auto tf = new TypeFunction(fparams, Type.tvoid, 0, LINK.d);\n            tf.isnothrow = f.isnothrow;\n            tf.isnogc = f.isnogc;\n            tf.purity = f.purity;\n            tf.trust = f.trust;\n            auto fd = new FuncDeclaration(loc, loc, Id.ensure, STC.undefined_, tf);\n            fd.fbody = fensure;\n            Statement s1 = new ExpStatement(loc, fd);\n            Expression eresult = null;\n            if (canBuildResultVar())\n                eresult = new IdentifierExp(loc, Id.result);\n            Expression e = new CallExp(loc, new VarExp(loc, fd, false), eresult);\n            Statement s2 = new ExpStatement(loc, e);\n            fensure = new CompoundStatement(loc, s1, s2);\n            fdensure = fd;\n        }\n    }\n\n    /****************************************************\n     * Merge into this function the 'out' contracts of all it overrides.\n     * 'out's are AND'd together, i.e. all of them need to pass.\n     */\n    final Statement mergeFensure(Statement sf, Identifier oid)\n    {\n        /* Same comments as for mergeFrequire(), except that we take care\n         * of generating a consistent reference to the 'result' local by\n         * explicitly passing 'result' to the nested function as a reference\n         * argument.\n         * This won't work for the 'this' parameter as it would require changing\n         * the semantic code for the nested function so that it looks on the parameter\n         * list for the 'this' pointer, something that would need an unknown amount\n         * of tweaking of various parts of the compiler that I'd rather leave alone.\n         */\n        foreach (fdv; foverrides)\n        {\n            /* The semantic pass on the contracts of the overridden functions must\n             * be completed before code generation occurs.\n             * https://issues.dlang.org/show_bug.cgi?id=3602 and\n             * https://issues.dlang.org/show_bug.cgi?id=5230\n             */\n            if (needsFensure(fdv) && fdv.semanticRun != PASS.semantic3done)\n            {\n                assert(fdv._scope);\n                Scope* sc = fdv._scope.push();\n                sc.stc &= ~STC.override_;\n                fdv.semantic3(sc);\n                sc.pop();\n            }\n\n            sf = fdv.mergeFensure(sf, oid);\n            if (fdv.fdensure)\n            {\n                //printf(\"fdv.fensure: %s\\n\", fdv.fensure.toChars());\n                // Make the call: __ensure(result)\n                Expression eresult = null;\n                if (canBuildResultVar())\n                {\n                    eresult = new IdentifierExp(loc, oid);\n\n                    Type t1 = fdv.type.nextOf().toBasetype();\n                    Type t2 = this.type.nextOf().toBasetype();\n                    if (t1.isBaseOf(t2, null))\n                    {\n                        /* Making temporary reference variable is necessary\n                         * in covariant return.\n                         * https://issues.dlang.org/show_bug.cgi?id=5204\n                         * https://issues.dlang.org/show_bug.cgi?id=10479\n                         */\n                        auto ei = new ExpInitializer(Loc.initial, eresult);\n                        auto v = new VarDeclaration(Loc.initial, t1, Identifier.generateId(\"__covres\"), ei);\n                        v.storage_class |= STC.temp;\n                        auto de = new DeclarationExp(Loc.initial, v);\n                        auto ve = new VarExp(Loc.initial, v);\n                        eresult = new CommaExp(Loc.initial, de, ve);\n                    }\n                }\n                Expression e = new CallExp(loc, new VarExp(loc, fdv.fdensure, false), eresult);\n                Statement s2 = new ExpStatement(loc, e);\n\n                if (sf)\n                {\n                    sf = new CompoundStatement(sf.loc, s2, sf);\n                }\n                else\n                    sf = s2;\n            }\n        }\n        return sf;\n    }\n\n    /*********************************************\n     * Return the function's parameter list, and whether\n     * it is variadic or not.\n     */\n    final Parameters* getParameters(int* pvarargs)\n    {\n        Parameters* fparameters = null;\n        int fvarargs = 0;\n\n        if (type)\n        {\n            TypeFunction fdtype = type.toTypeFunction();\n            fparameters = fdtype.parameters;\n            fvarargs = fdtype.varargs;\n        }\n        if (pvarargs)\n            *pvarargs = fvarargs;\n\n        return fparameters;\n    }\n\n    /**********************************\n     * Generate a FuncDeclaration for a runtime library function.\n     */\n    static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, const(char)* name, StorageClass stc = 0)\n    {\n        return genCfunc(fparams, treturn, Identifier.idPool(name, cast(uint)strlen(name)), stc);\n    }\n\n    static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, Identifier id, StorageClass stc = 0)\n    {\n        FuncDeclaration fd;\n        TypeFunction tf;\n        Dsymbol s;\n        __gshared DsymbolTable st = null;\n\n        //printf(\"genCfunc(name = '%s')\\n\", id.toChars());\n        //printf(\"treturn\\n\\t\"); treturn.print();\n\n        // See if already in table\n        if (!st)\n            st = new DsymbolTable();\n        s = st.lookup(id);\n        if (s)\n        {\n            fd = s.isFuncDeclaration();\n            assert(fd);\n            assert(fd.type.nextOf().equals(treturn));\n        }\n        else\n        {\n            tf = new TypeFunction(fparams, treturn, 0, LINK.c, stc);\n            fd = new FuncDeclaration(Loc.initial, Loc.initial, id, STC.static_, tf);\n            fd.protection = Prot(Prot.Kind.public_);\n            fd.linkage = LINK.c;\n\n            st.insert(fd);\n        }\n        return fd;\n    }\n\n    /******************\n     * Check parameters and return type of D main() function.\n     * Issue error messages.\n     */\n    extern (D) final void checkDmain()\n    {\n        TypeFunction tf = type.toTypeFunction();\n        const nparams = Parameter.dim(tf.parameters);\n        bool argerr;\n        if (nparams == 1)\n        {\n            auto fparam0 = Parameter.getNth(tf.parameters, 0);\n            auto t = fparam0.type.toBasetype();\n            if (t.ty != Tarray ||\n                t.nextOf().ty != Tarray ||\n                t.nextOf().nextOf().ty != Tchar ||\n                fparam0.storageClass & (STC.out_ | STC.ref_ | STC.lazy_))\n            {\n                argerr = true;\n            }\n        }\n\n        if (!tf.nextOf())\n            error(\"must return `int` or `void`\");\n        else if (tf.nextOf().ty != Tint32 && tf.nextOf().ty != Tvoid)\n            error(\"must return `int` or `void`, not `%s`\", tf.nextOf().toChars());\n        else if (tf.varargs || nparams >= 2 || argerr)\n            error(\"parameters must be `main()` or `main(string[] args)`\");\n    }\n\n    override final inout(FuncDeclaration) isFuncDeclaration() inout\n    {\n        return this;\n    }\n\n    inout(FuncDeclaration) toAliasFunc() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/********************************************************\n * Generate Expression to call the invariant.\n * Input:\n *      ad      aggregate with the invariant\n *      vthis   variable with 'this'\n * Returns:\n *      void expression that calls the invariant\n */\nExpression addInvariant(const ref Loc loc, Scope* sc, AggregateDeclaration ad, VarDeclaration vthis)\n{\n    Expression e = null;\n    // Call invariant directly only if it exists\n    FuncDeclaration inv = ad.inv;\n    ClassDeclaration cd = ad.isClassDeclaration();\n\n    while (!inv && cd)\n    {\n        cd = cd.baseClass;\n        if (!cd)\n            break;\n        inv = cd.inv;\n    }\n    if (inv)\n    {\n        version (all)\n        {\n            // Workaround for https://issues.dlang.org/show_bug.cgi?id=13394\n            // For the correct mangling,\n            // run attribute inference on inv if needed.\n            inv.functionSemantic();\n        }\n\n        //e = new DsymbolExp(Loc.initial, inv);\n        //e = new CallExp(Loc.initial, e);\n        //e = e.semantic(sc2);\n\n        /* https://issues.dlang.org/show_bug.cgi?id=13113\n         * Currently virtual invariant calls completely\n         * bypass attribute enforcement.\n         * Change the behavior of pre-invariant call by following it.\n         */\n        e = new ThisExp(Loc.initial);\n        e.type = vthis.type;\n        e = new DotVarExp(Loc.initial, e, inv, false);\n        e.type = inv.type;\n        e = new CallExp(Loc.initial, e);\n        e.type = Type.tvoid;\n    }\n    return e;\n}\n\n/***************************************************\n * Visit each overloaded function/template in turn, and call dg(s) on it.\n * Exit when no more, or dg(s) returns nonzero.\n *\n * Params:\n *  fstart = symbol to start from\n *  dg = the delegate to be called on the overload\n *  sc = the initial scope from the calling context\n *\n * Returns:\n *      ==0     continue\n *      !=0     done\n */\nextern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc = null)\n{\n    Dsymbol next;\n    for (Dsymbol d = fstart; d; d = next)\n    {\n        import dmd.access : checkSymbolAccess;\n        if (auto od = d.isOverDeclaration())\n        {\n            if (od.hasOverloads)\n            {\n                /* The scope is needed here to check whether a function in\n                   an overload set was added by means of a private alias (or a\n                   selective import). If the scope where the alias is created\n                   is imported somewhere, the overload set is visible, but the private\n                   alias is not.\n                 */\n                if (sc)\n                {\n                    if (checkSymbolAccess(sc, od))\n                    {\n                        if (int r = overloadApply(od.aliassym, dg, sc))\n                            return r;\n                    }\n                }\n                else if (int r = overloadApply(od.aliassym, dg, sc))\n                    return r;\n            }\n            else\n            {\n                if (int r = dg(od.aliassym))\n                    return r;\n            }\n            next = od.overnext;\n        }\n        else if (auto fa = d.isFuncAliasDeclaration())\n        {\n            if (fa.hasOverloads)\n            {\n                if (int r = overloadApply(fa.funcalias, dg, sc))\n                    return r;\n            }\n            else if (auto fd = fa.toAliasFunc())\n            {\n                if (int r = dg(fd))\n                    return r;\n            }\n            else\n            {\n                d.error(\"is aliased to a function\");\n                break;\n            }\n            next = fa.overnext;\n        }\n        else if (auto ad = d.isAliasDeclaration())\n        {\n            if (sc)\n            {\n                if (checkSymbolAccess(sc, ad))\n                    next = ad.toAlias();\n            }\n            else\n               next = ad.toAlias();\n            if (next == ad)\n                break;\n            if (next == fstart)\n                break;\n        }\n        else if (auto td = d.isTemplateDeclaration())\n        {\n            if (int r = dg(td))\n                return r;\n            next = td.overnext;\n        }\n        else if (auto fd = d.isFuncDeclaration())\n        {\n            if (int r = dg(fd))\n                return r;\n            next = fd.overnext;\n        }\n        else\n        {\n            d.error(\"is aliased to a function\");\n            break;\n            // BUG: should print error message?\n        }\n    }\n    return 0;\n}\n\n/**\nChecks for mismatching modifiers between `lhsMod` and `rhsMod` and prints the\nmismatching modifiers to `buf`.\n\nThe modifiers of the `lhsMod` mismatching the ones with the `rhsMod` are printed, i.e.\nlhs(shared) vs. rhs() prints \"`shared`\", wheras lhs() vs rhs(shared) prints \"non-shared\".\n\nParams:\n    buf = output buffer to write to\n    lhsMod = modifier on the left-hand side\n    lhsMod = modifier on the right-hand side\n\nReturns:\n\nA tuple with `isMutable` and `isNotShared` set\nif the `lhsMod` is missing those modifiers (compared to rhs).\n*/\nauto MODMatchToBuffer(OutBuffer* buf, ubyte lhsMod, ubyte rhsMod)\n{\n    static struct Mismatches\n    {\n        bool isNotShared;\n        bool isMutable;\n    }\n\n    Mismatches mismatches;\n\n    bool bothMutable = ((lhsMod & rhsMod) == 0);\n    bool sharedMismatch = ((lhsMod ^ rhsMod) & MODFlags.shared_) != 0;\n    bool sharedMismatchOnly = ((lhsMod ^ rhsMod) == MODFlags.shared_);\n\n    if (lhsMod & MODFlags.shared_)\n        buf.writestring(\"`shared` \");\n    else if (sharedMismatch && !(lhsMod & MODFlags.immutable_))\n    {\n        buf.writestring(\"non-shared \");\n        mismatches.isNotShared = true;\n    }\n\n    if (bothMutable && sharedMismatchOnly)\n    {\n    }\n    else if (lhsMod & MODFlags.immutable_)\n        buf.writestring(\"`immutable` \");\n    else if (lhsMod & MODFlags.const_)\n        buf.writestring(\"`const` \");\n    else if (lhsMod & MODFlags.wild)\n        buf.writestring(\"`inout` \");\n    else\n    {\n        buf.writestring(\"mutable \");\n        mismatches.isMutable = true;\n    }\n\n    return mismatches;\n}\n\n///\nunittest\n{\n    OutBuffer buf;\n    auto mismatches = MODMatchToBuffer(&buf, MODFlags.shared_, 0);\n    assert(buf.peekSlice == \"`shared` \");\n    assert(!mismatches.isNotShared);\n\n    buf.reset;\n    mismatches = MODMatchToBuffer(&buf, 0, MODFlags.shared_);\n    assert(buf.peekSlice == \"non-shared \");\n    assert(mismatches.isNotShared);\n\n    buf.reset;\n    mismatches = MODMatchToBuffer(&buf, MODFlags.const_, 0);\n    assert(buf.peekSlice == \"`const` \");\n    assert(!mismatches.isMutable);\n\n    buf.reset;\n    mismatches = MODMatchToBuffer(&buf, 0, MODFlags.const_);\n    assert(buf.peekSlice == \"mutable \");\n    assert(mismatches.isMutable);\n}\n\nprivate const(char)* prependSpace(const(char)* str)\n{\n    if (!str || !*str) return \"\";\n\n    return (\" \" ~ str[0 .. strlen(str)] ~ \"\\0\").ptr;\n}\n\n/*******************************************\n * Given a symbol that could be either a FuncDeclaration or\n * a function template, resolve it to a function symbol.\n * Params:\n *      loc =           instantiation location\n *      sc =            instantiation scope\n *      s =             instantiation symbol\n *      tiargs =        initial list of template arguments\n *      tthis =         if !NULL, the `this` argument type\n *      fargs =         arguments to function\n *      flags =         1: do not issue error message on no match, just return NULL\n *                      2: overloadResolve only\n * Returns:\n *      if match is found, then function symbol, else null\n */\nFuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,\n    Objects* tiargs, Type tthis, Expressions* fargs, int flags = 0)\n{\n    if (!s)\n        return null; // no match\n\n    version (none)\n    {\n        printf(\"resolveFuncCall('%s')\\n\", s.toChars());\n        if (tthis)\n            printf(\"\\tthis: %s\\n\", tthis.toChars());\n        if (fargs)\n        {\n            for (size_t i = 0; i < fargs.dim; i++)\n            {\n                Expression arg = (*fargs)[i];\n                assert(arg.type);\n                printf(\"\\t%s: \", arg.toChars());\n                arg.type.print();\n            }\n        }\n    }\n\n    if (tiargs && arrayObjectIsError(tiargs) ||\n        fargs && arrayObjectIsError(cast(Objects*)fargs))\n    {\n        return null;\n    }\n\n    Match m;\n    m.last = MATCH.nomatch;\n    functionResolve(&m, s, loc, sc, tiargs, tthis, fargs, null);\n    auto orig_s = s;\n\n    if (m.last > MATCH.nomatch && m.lastf)\n    {\n        if (m.count == 1) // exactly one match\n        {\n            if (!(flags & 1))\n                m.lastf.functionSemantic();\n            return m.lastf;\n        }\n        if ((flags & 2) && !tthis && m.lastf.needThis())\n        {\n            return m.lastf;\n        }\n    }\n\n    /* Failed to find a best match.\n     * Do nothing or print error.\n     */\n    if (m.last <= MATCH.nomatch)\n    {\n        // error was caused on matched function\n        if (m.count == 1)\n            return m.lastf;\n\n        // if do not print error messages\n        if (flags & 1)\n            return null; // no match\n    }\n\n    auto fd = s.isFuncDeclaration();\n    auto od = s.isOverDeclaration();\n    auto td = s.isTemplateDeclaration();\n    if (td && td.funcroot)\n        s = fd = td.funcroot;\n\n    OutBuffer tiargsBuf;\n    arrayObjectsToBuffer(&tiargsBuf, tiargs);\n\n    OutBuffer fargsBuf;\n    fargsBuf.writeByte('(');\n    argExpTypesToCBuffer(&fargsBuf, fargs);\n    fargsBuf.writeByte(')');\n    if (tthis)\n        tthis.modToBuffer(&fargsBuf);\n\n    // max num of overloads to print (-v overrides this).\n    enum int numOverloadsDisplay = 5;\n\n    if (!m.lastf && !(flags & 1)) // no match\n    {\n        if (td && !fd) // all of overloads are templates\n        {\n            .error(loc, \"%s `%s.%s` cannot deduce function from argument types `!(%s)%s`, candidates are:\",\n                td.kind(), td.parent.toPrettyChars(), td.ident.toChars(),\n                tiargsBuf.peekString(), fargsBuf.peekString());\n\n            printCandidates(loc, td);\n        }\n        else if (od)\n        {\n            .error(loc, \"none of the overloads of `%s` are callable using argument types `!(%s)%s`\",\n                od.ident.toChars(), tiargsBuf.peekString(), fargsBuf.peekString());\n        }\n        else\n        {\n            assert(fd);\n\n            if (fd.checkDisabled(loc, sc))\n                return null;\n\n            bool hasOverloads = fd.overnext !is null;\n            auto tf = fd.type.toTypeFunction();\n            if (tthis && !MODimplicitConv(tthis.mod, tf.mod)) // modifier mismatch\n            {\n                OutBuffer thisBuf, funcBuf;\n                MODMatchToBuffer(&thisBuf, tthis.mod, tf.mod);\n                auto mismatches = MODMatchToBuffer(&funcBuf, tf.mod, tthis.mod);\n                if (hasOverloads)\n                {\n                    .error(loc, \"none of the overloads of `%s` are callable using a %sobject, candidates are:\",\n                        fd.ident.toChars(), thisBuf.peekString());\n                }\n                else\n                {\n                    auto fullFdPretty = fd.toPrettyChars();\n                    .error(loc, \"%smethod `%s` is not callable using a %sobject\",\n                        funcBuf.peekString(), fullFdPretty,\n                        thisBuf.peekString());\n\n                    if (mismatches.isNotShared)\n                        .errorSupplemental(loc, \"Consider adding `shared` to %s\", fullFdPretty);\n                    else if (mismatches.isMutable)\n                        .errorSupplemental(loc, \"Consider adding `const` or `inout` to %s\", fullFdPretty);\n                }\n            }\n            else\n            {\n                //printf(\"tf = %s, args = %s\\n\", tf.deco, (*fargs)[0].type.deco);\n                if (hasOverloads)\n                {\n                    .error(loc, \"none of the overloads of `%s` are callable using argument types `%s`, candidates are:\",\n                        fd.toChars(), fargsBuf.peekString());\n                }\n                else\n                {\n                    .error(loc, \"%s `%s%s%s` is not callable using argument types `%s`\",\n                        fd.kind(), fd.toPrettyChars(), parametersTypeToChars(tf.parameters, tf.varargs),\n                        tf.modToChars(), fargsBuf.peekString());\n                    // re-resolve to check for supplemental message\n                    const(char)* failMessage;\n                    functionResolve(&m, orig_s, loc, sc, tiargs, tthis, fargs, &failMessage);\n                    if (failMessage)\n                        errorSupplemental(loc, failMessage);\n                }\n            }\n\n            if (hasOverloads)\n                printCandidates(loc, fd);\n        }\n    }\n    else if (m.nextf)\n    {\n        TypeFunction tf1 = m.lastf.type.toTypeFunction();\n        TypeFunction tf2 = m.nextf.type.toTypeFunction();\n        const(char)* lastprms = parametersTypeToChars(tf1.parameters, tf1.varargs);\n        const(char)* nextprms = parametersTypeToChars(tf2.parameters, tf2.varargs);\n\n        const(char)* mod1 = prependSpace(MODtoChars(tf1.mod));\n        const(char)* mod2 = prependSpace(MODtoChars(tf2.mod));\n\n        .error(loc, \"`%s.%s` called with argument types `%s` matches both:\\n%s:     `%s%s%s`\\nand:\\n%s:     `%s%s%s`\",\n            s.parent.toPrettyChars(), s.ident.toChars(),\n            fargsBuf.peekString(),\n            m.lastf.loc.toChars(), m.lastf.toPrettyChars(), lastprms, mod1,\n            m.nextf.loc.toChars(), m.nextf.toPrettyChars(), nextprms, mod2);\n    }\n    return null;\n}\n\n/*******************************************\n * Prints template and function overload candidates as supplemental errors.\n * Params:\n *      loc =           instantiation location\n *      declaration =   the declaration to print overload candidates for\n */\nprivate void printCandidates(Decl)(const ref Loc loc, Decl declaration)\nif (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration))\n{\n    // max num of overloads to print (-v overrides this).\n    int numToDisplay = 5;\n\n    overloadApply(declaration, (Dsymbol s)\n    {\n        Dsymbol nextOverload;\n\n        if (auto fd = s.isFuncDeclaration())\n        {\n            if (fd.errors || fd.type.ty == Terror)\n                return 0;\n\n            auto tf = cast(TypeFunction) fd.type;\n            .errorSupplemental(fd.loc, \"`%s%s`\", fd.toPrettyChars(),\n                parametersTypeToChars(tf.parameters, tf.varargs));\n            nextOverload = fd.overnext;\n        }\n        else if (auto td = s.isTemplateDeclaration())\n        {\n            .errorSupplemental(td.loc, \"`%s`\", td.toPrettyChars());\n            nextOverload = td.overnext;\n        }\n\n        if (global.params.verbose || --numToDisplay != 0)\n            return 0;\n\n        // Too many overloads to sensibly display.\n        // Just show count of remaining overloads.\n        int num = 0;\n        overloadApply(nextOverload, (s) { ++num; return 0; });\n\n        if (num > 0)\n            .errorSupplemental(loc, \"... (%d more, -v to show) ...\", num);\n        return 1;   // stop iterating\n    });\n}\n\n/**************************************\n * Returns an indirect type one step from t.\n */\nType getIndirection(Type t)\n{\n    t = t.baseElemOf();\n    if (t.ty == Tarray || t.ty == Tpointer)\n        return t.nextOf().toBasetype();\n    if (t.ty == Taarray || t.ty == Tclass)\n        return t;\n    if (t.ty == Tstruct)\n        return t.hasPointers() ? t : null; // TODO\n\n    // should consider TypeDelegate?\n    return null;\n}\n\n/**************************************\n * Performs type-based alias analysis between a newly created value and a pre-\n * existing memory reference:\n *\n * Assuming that a reference A to a value of type `ta` was available to the code\n * that created a reference B to a value of type `tb`, it returns whether B\n * might alias memory reachable from A based on the types involved (either\n * directly or via any number of indirections in either A or B).\n *\n * This relation is not symmetric in the two arguments. For example, a\n * a `const(int)` reference can point to a pre-existing `int`, but not the other\n * way round.\n *\n * Examples:\n *\n *      ta,           tb,               result\n *      `const(int)`, `int`,            `false`\n *      `int`,        `const(int)`,     `true`\n *      `int`,        `immutable(int)`, `false`\n *      const(immutable(int)*), immutable(int)*, false   // BUG: returns true\n *\n * Params:\n *      ta = value type being referred to\n *      tb = referred to value type that could be constructed from ta\n *\n * Returns:\n *      true if reference to `tb` is isolated from reference to `ta`\n */\nprivate bool traverseIndirections(Type ta, Type tb)\n{\n    //printf(\"traverseIndirections(%s, %s)\\n\", ta.toChars(), tb.toChars());\n\n    /* Threaded list of aggregate types already examined,\n     * used to break cycles.\n     * Cycles in type graphs can only occur with aggregates.\n     */\n    static struct Ctxt\n    {\n        Ctxt* prev;\n        Type type;      // an aggregate type\n    }\n\n    static bool traverse(Type ta, Type tb, Ctxt* ctxt, bool reversePass)\n    {\n        //printf(\"traverse(%s, %s)\\n\", ta.toChars(), tb.toChars());\n        ta = ta.baseElemOf();\n        tb = tb.baseElemOf();\n\n        // First, check if the pointed-to types are convertible to each other such\n        // that they might alias directly.\n        static bool mayAliasDirect(Type source, Type target)\n        {\n            return\n                // if source is the same as target or can be const-converted to target\n                source.constConv(target) != MATCH.nomatch ||\n                // if target is void and source can be const-converted to target\n                (target.ty == Tvoid && MODimplicitConv(source.mod, target.mod));\n        }\n\n        if (mayAliasDirect(reversePass ? tb : ta, reversePass ? ta : tb))\n        {\n            //printf(\" true  mayalias %s %s %d\\n\", ta.toChars(), tb.toChars(), reversePass);\n            return false;\n        }\n        if (ta.nextOf() && ta.nextOf() == tb.nextOf())\n        {\n             //printf(\" next==next %s %s %d\\n\", ta.toChars(), tb.toChars(), reversePass);\n             return true;\n        }\n\n        if (tb.ty == Tclass || tb.ty == Tstruct)\n        {\n            for (Ctxt* c = ctxt; c; c = c.prev)\n                if (tb == c.type)\n                    return true;\n            Ctxt c;\n            c.prev = ctxt;\n            c.type = tb;\n\n            /* Traverse the type of each field of the aggregate\n             */\n            AggregateDeclaration sym = tb.toDsymbol(null).isAggregateDeclaration();\n            foreach (v; sym.fields)\n            {\n                Type tprmi = v.type.addMod(tb.mod);\n                //printf(\"\\ttb = %s, tprmi = %s\\n\", tb.toChars(), tprmi.toChars());\n                if (!traverse(ta, tprmi, &c, reversePass))\n                    return false;\n            }\n        }\n        else if (tb.ty == Tarray || tb.ty == Taarray || tb.ty == Tpointer)\n        {\n            Type tind = tb.nextOf();\n            if (!traverse(ta, tind, ctxt, reversePass))\n                return false;\n        }\n        else if (tb.hasPointers())\n        {\n            // BUG: consider the context pointer of delegate types\n            return false;\n        }\n\n        // Still no match, so try breaking up ta if we have not done so yet.\n        if (!reversePass)\n            return traverse(tb, ta, ctxt, true);\n\n        return true;\n    }\n\n    // To handle arbitrary levels of indirections in both parameters, we\n    // recursively descend into aggregate members/levels of indirection in both\n    // `ta` and `tb` while avoiding cycles. Start with the original types.\n    const result = traverse(ta, tb, null, false);\n    //printf(\"  returns %d\\n\", result);\n    return result;\n}\n\n/* For all functions between outerFunc and f, mark them as needing\n * a closure.\n */\nprivate void markAsNeedingClosure(Dsymbol f, FuncDeclaration outerFunc)\n{\n    for (Dsymbol sx = f; sx && sx != outerFunc; sx = sx.parent)\n    {\n        FuncDeclaration fy = sx.isFuncDeclaration();\n        if (fy && fy.closureVars.dim)\n        {\n            /* fy needs a closure if it has closureVars[],\n             * because the frame pointer in the closure will be accessed.\n             */\n            fy.requiresClosure = true;\n        }\n    }\n}\n\n/********\n * Given a nested function f inside a function outerFunc, check\n * if any sibling callers of f have escaped. If so, mark\n * all the enclosing functions as needing closures.\n * This is recursive: we need to check the callers of our siblings.\n * Note that nested functions can only call lexically earlier nested\n * functions, so loops are impossible.\n * Params:\n *      f = inner function (nested within outerFunc)\n *      outerFunc = outer function\n *      p = for internal recursion use\n * Returns:\n *      true if any closures were needed\n */\nprivate bool checkEscapingSiblings(FuncDeclaration f, FuncDeclaration outerFunc, void* p = null)\n{\n    static struct PrevSibling\n    {\n        PrevSibling* p;\n        FuncDeclaration f;\n    }\n\n    PrevSibling ps;\n    ps.p = cast(PrevSibling*)p;\n    ps.f = f;\n\n    //printf(\"checkEscapingSiblings(f = %s, outerfunc = %s)\\n\", f.toChars(), outerFunc.toChars());\n    bool bAnyClosures = false;\n    for (size_t i = 0; i < f.siblingCallers.dim; ++i)\n    {\n        FuncDeclaration g = f.siblingCallers[i];\n        if (g.isThis() || g.tookAddressOf)\n        {\n            markAsNeedingClosure(g, outerFunc);\n            bAnyClosures = true;\n        }\n\n        PrevSibling* prev = cast(PrevSibling*)p;\n        while (1)\n        {\n            if (!prev)\n            {\n                bAnyClosures |= checkEscapingSiblings(g, outerFunc, &ps);\n                break;\n            }\n            if (prev.f == g)\n                break;\n            prev = prev.p;\n        }\n    }\n    //printf(\"\\t%d\\n\", bAnyClosures);\n    return bAnyClosures;\n}\n\n/***********************************************************\n * Used as a way to import a set of functions from another scope into this one.\n */\nextern (C++) final class FuncAliasDeclaration : FuncDeclaration\n{\n    FuncDeclaration funcalias;\n    bool hasOverloads;\n\n    extern (D) this(Identifier ident, FuncDeclaration funcalias, bool hasOverloads = true)\n    {\n        super(funcalias.loc, funcalias.endloc, ident, funcalias.storage_class, funcalias.type);\n        assert(funcalias != this);\n        this.funcalias = funcalias;\n\n        this.hasOverloads = hasOverloads;\n        if (hasOverloads)\n        {\n            if (FuncAliasDeclaration fad = funcalias.isFuncAliasDeclaration())\n                this.hasOverloads = fad.hasOverloads;\n        }\n        else\n        {\n            // for internal use\n            assert(!funcalias.isFuncAliasDeclaration());\n            this.hasOverloads = false;\n        }\n        userAttribDecl = funcalias.userAttribDecl;\n    }\n\n    override inout(FuncAliasDeclaration) isFuncAliasDeclaration() inout\n    {\n        return this;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"function alias\";\n    }\n\n    override inout(FuncDeclaration) toAliasFunc() inout\n    {\n        return funcalias.toAliasFunc();\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class FuncLiteralDeclaration : FuncDeclaration\n{\n    TOK tok;        // TOK.function_ or TOK.delegate_\n    Type treq;      // target of return type inference\n\n    // backend\n    bool deferToObj;\n\n    extern (D) this(const ref Loc loc, const ref Loc endloc, Type type, TOK tok, ForeachStatement fes, Identifier id = null)\n    {\n        super(loc, endloc, null, STC.undefined_, type);\n        this.ident = id ? id : Id.empty;\n        this.tok = tok;\n        this.fes = fes;\n        //printf(\"FuncLiteralDeclaration() id = '%s', type = '%s'\\n\", this.ident.toChars(), type.toChars());\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        //printf(\"FuncLiteralDeclaration::syntaxCopy('%s')\\n\", toChars());\n        assert(!s);\n        auto f = new FuncLiteralDeclaration(loc, endloc, type.syntaxCopy(), tok, fes, ident);\n        f.treq = treq; // don't need to copy\n        return FuncDeclaration.syntaxCopy(f);\n    }\n\n    override bool isNested() const\n    {\n        //printf(\"FuncLiteralDeclaration::isNested() '%s'\\n\", toChars());\n        return (tok != TOK.function_) && !isThis();\n    }\n\n    override inout(AggregateDeclaration) isThis() inout\n    {\n        return tok == TOK.delegate_ ? super.isThis() : null;\n    }\n\n    override bool isVirtual() const\n    {\n        return false;\n    }\n\n    override bool addPreInvariant()\n    {\n        return false;\n    }\n\n    override bool addPostInvariant()\n    {\n        return false;\n    }\n\n    /*******************************\n     * Modify all expression type of return statements to tret.\n     *\n     * On function literals, return type may be modified based on the context type\n     * after its semantic3 is done, in FuncExp::implicitCastTo.\n     *\n     *  A function() dg = (){ return new B(); } // OK if is(B : A) == true\n     *\n     * If B to A conversion is convariant that requires offseet adjusting,\n     * all return statements should be adjusted to return expressions typed A.\n     */\n    void modifyReturns(Scope* sc, Type tret)\n    {\n        import dmd.statement_rewrite_walker;\n\n        extern (C++) final class RetWalker : StatementRewriteWalker\n        {\n            alias visit = typeof(super).visit;\n        public:\n            Scope* sc;\n            Type tret;\n            FuncLiteralDeclaration fld;\n\n            override void visit(ReturnStatement s)\n            {\n                Expression exp = s.exp;\n                if (exp && !exp.type.equals(tret))\n                {\n                    s.exp = exp.castTo(sc, tret);\n                }\n            }\n        }\n\n        if (semanticRun < PASS.semantic3done)\n            return;\n\n        if (fes)\n            return;\n\n        scope RetWalker w = new RetWalker();\n        w.sc = sc;\n        w.tret = tret;\n        w.fld = this;\n        fbody.accept(w);\n\n        // Also update the inferred function type to match the new return type.\n        // This is required so the code generator does not try to cast the\n        // modified returns back to the original type.\n        if (inferRetType && type.nextOf() != tret)\n            type.toTypeFunction().next = tret;\n    }\n\n    override inout(FuncLiteralDeclaration) isFuncLiteralDeclaration() inout\n    {\n        return this;\n    }\n\n    override const(char)* kind() const\n    {\n        // GCC requires the (char*) casts\n        return (tok != TOK.function_) ? \"delegate\" : \"function\";\n    }\n\n    override const(char)* toPrettyChars(bool QualifyTypes = false)\n    {\n        if (parent)\n        {\n            TemplateInstance ti = parent.isTemplateInstance();\n            if (ti)\n                return ti.tempdecl.toPrettyChars(QualifyTypes);\n        }\n        return Dsymbol.toPrettyChars(QualifyTypes);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class CtorDeclaration : FuncDeclaration\n{\n    extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Type type)\n    {\n        super(loc, endloc, Id.ctor, stc, type);\n        //printf(\"CtorDeclaration(loc = %s) %s\\n\", loc.toChars(), toChars());\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto f = new CtorDeclaration(loc, endloc, storage_class, type.syntaxCopy());\n        return FuncDeclaration.syntaxCopy(f);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"constructor\";\n    }\n\n    override const(char)* toChars() const\n    {\n        return \"this\";\n    }\n\n    override bool isVirtual() const\n    {\n        return false;\n    }\n\n    override bool addPreInvariant()\n    {\n        return false;\n    }\n\n    override bool addPostInvariant()\n    {\n        return (isThis() && vthis && global.params.useInvariants);\n    }\n\n    override inout(CtorDeclaration) isCtorDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class PostBlitDeclaration : FuncDeclaration\n{\n    extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Identifier id)\n    {\n        super(loc, endloc, id, stc, null);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto dd = new PostBlitDeclaration(loc, endloc, storage_class, ident);\n        return FuncDeclaration.syntaxCopy(dd);\n    }\n\n    override bool isVirtual() const\n    {\n        return false;\n    }\n\n    override bool addPreInvariant()\n    {\n        return false;\n    }\n\n    override bool addPostInvariant()\n    {\n        return (isThis() && vthis && global.params.useInvariants);\n    }\n\n    override bool overloadInsert(Dsymbol s)\n    {\n        return false; // cannot overload postblits\n    }\n\n    override inout(PostBlitDeclaration) isPostBlitDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DtorDeclaration : FuncDeclaration\n{\n    extern (D) this(const ref Loc loc, const ref Loc endloc)\n    {\n        super(loc, endloc, Id.dtor, STC.undefined_, null);\n    }\n\n    extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Identifier id)\n    {\n        super(loc, endloc, id, stc, null);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto dd = new DtorDeclaration(loc, endloc, storage_class, ident);\n        return FuncDeclaration.syntaxCopy(dd);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"destructor\";\n    }\n\n    override const(char)* toChars() const\n    {\n        return \"~this\";\n    }\n\n    override bool isVirtual() const\n    {\n        // D dtor's don't get put into the vtbl[]\n        // this is a hack so that extern(C++) destructors report as virtual, which are manually added to the vtable\n        return vtblIndex != -1;\n    }\n\n    override bool addPreInvariant()\n    {\n        return (isThis() && vthis && global.params.useInvariants);\n    }\n\n    override bool addPostInvariant()\n    {\n        return false;\n    }\n\n    override bool overloadInsert(Dsymbol s)\n    {\n        return false; // cannot overload destructors\n    }\n\n    override inout(DtorDeclaration) isDtorDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class StaticCtorDeclaration : FuncDeclaration\n{\n    extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc)\n    {\n        super(loc, endloc, Identifier.generateIdWithLoc(\"_staticCtor\", loc), STC.static_ | stc, null);\n    }\n\n    extern (D) this(const ref Loc loc, const ref Loc endloc, string name, StorageClass stc)\n    {\n        super(loc, endloc, Identifier.generateIdWithLoc(name, loc), STC.static_ | stc, null);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto scd = new StaticCtorDeclaration(loc, endloc, storage_class);\n        return FuncDeclaration.syntaxCopy(scd);\n    }\n\n    override final inout(AggregateDeclaration) isThis() inout\n    {\n        return null;\n    }\n\n    override final bool isVirtual() const\n    {\n        return false;\n    }\n\n    override final bool addPreInvariant()\n    {\n        return false;\n    }\n\n    override final bool addPostInvariant()\n    {\n        return false;\n    }\n\n    override final bool hasStaticCtorOrDtor()\n    {\n        return true;\n    }\n\n    override final inout(StaticCtorDeclaration) isStaticCtorDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class SharedStaticCtorDeclaration : StaticCtorDeclaration\n{\n    extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc)\n    {\n        super(loc, endloc, \"_sharedStaticCtor\", stc);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto scd = new SharedStaticCtorDeclaration(loc, endloc, storage_class);\n        return FuncDeclaration.syntaxCopy(scd);\n    }\n\n    override inout(SharedStaticCtorDeclaration) isSharedStaticCtorDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class StaticDtorDeclaration : FuncDeclaration\n{\n    VarDeclaration vgate; // 'gate' variable\n\n    extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc)\n    {\n        super(loc, endloc, Identifier.generateIdWithLoc(\"_staticDtor\", loc), STC.static_ | stc, null);\n    }\n\n    extern (D) this(const ref Loc loc, const ref Loc endloc, string name, StorageClass stc)\n    {\n        super(loc, endloc, Identifier.generateIdWithLoc(name, loc), STC.static_ | stc, null);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto sdd = new StaticDtorDeclaration(loc, endloc, storage_class);\n        return FuncDeclaration.syntaxCopy(sdd);\n    }\n\n    override final inout(AggregateDeclaration) isThis() inout\n    {\n        return null;\n    }\n\n    override final bool isVirtual() const\n    {\n        return false;\n    }\n\n    override final bool hasStaticCtorOrDtor()\n    {\n        return true;\n    }\n\n    override final bool addPreInvariant()\n    {\n        return false;\n    }\n\n    override final bool addPostInvariant()\n    {\n        return false;\n    }\n\n    override final inout(StaticDtorDeclaration) isStaticDtorDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class SharedStaticDtorDeclaration : StaticDtorDeclaration\n{\n    extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc)\n    {\n        super(loc, endloc, \"_sharedStaticDtor\", stc);\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto sdd = new SharedStaticDtorDeclaration(loc, endloc, storage_class);\n        return FuncDeclaration.syntaxCopy(sdd);\n    }\n\n    override inout(SharedStaticDtorDeclaration) isSharedStaticDtorDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class InvariantDeclaration : FuncDeclaration\n{\n    extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Identifier id, Statement fbody)\n    {\n        super(loc, endloc, id ? id : Identifier.generateId(\"__invariant\"), stc, null);\n        this.fbody = fbody;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto id = new InvariantDeclaration(loc, endloc, storage_class, null, null);\n        return FuncDeclaration.syntaxCopy(id);\n    }\n\n    override bool isVirtual() const\n    {\n        return false;\n    }\n\n    override bool addPreInvariant()\n    {\n        return false;\n    }\n\n    override bool addPostInvariant()\n    {\n        return false;\n    }\n\n    override inout(InvariantDeclaration) isInvariantDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n\n/***********************************************************\n */\nextern (C++) final class UnitTestDeclaration : FuncDeclaration\n{\n    char* codedoc;      // for documented unittest\n\n    // toObjFile() these nested functions after this one\n    FuncDeclarations deferredNested;\n\n    extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, char* codedoc)\n    {\n        super(loc, endloc, Identifier.generateIdWithLoc(\"__unittest\", loc), stc, null);\n        this.codedoc = codedoc;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto utd = new UnitTestDeclaration(loc, endloc, storage_class, codedoc);\n        return FuncDeclaration.syntaxCopy(utd);\n    }\n\n    override inout(AggregateDeclaration) isThis() inout\n    {\n        return null;\n    }\n\n    override bool isVirtual() const\n    {\n        return false;\n    }\n\n    override bool addPreInvariant()\n    {\n        return false;\n    }\n\n    override bool addPostInvariant()\n    {\n        return false;\n    }\n\n    override inout(UnitTestDeclaration) isUnitTestDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class NewDeclaration : FuncDeclaration\n{\n    Parameters* parameters;\n    int varargs;\n\n    extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Parameters* fparams, int varargs)\n    {\n        super(loc, endloc, Id.classNew, STC.static_ | stc, null);\n        this.parameters = fparams;\n        this.varargs = varargs;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto f = new NewDeclaration(loc, endloc, storage_class, Parameter.arraySyntaxCopy(parameters), varargs);\n        return FuncDeclaration.syntaxCopy(f);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"allocator\";\n    }\n\n    override bool isVirtual() const\n    {\n        return false;\n    }\n\n    override bool addPreInvariant()\n    {\n        return false;\n    }\n\n    override bool addPostInvariant()\n    {\n        return false;\n    }\n\n    override inout(NewDeclaration) isNewDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DeleteDeclaration : FuncDeclaration\n{\n    Parameters* parameters;\n\n    extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Parameters* fparams)\n    {\n        super(loc, endloc, Id.classDelete, STC.static_ | stc, null);\n        this.parameters = fparams;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        auto f = new DeleteDeclaration(loc, endloc, storage_class, Parameter.arraySyntaxCopy(parameters));\n        return FuncDeclaration.syntaxCopy(f);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"deallocator\";\n    }\n\n    override bool isDelete()\n    {\n        return true;\n    }\n\n    override bool isVirtual() const\n    {\n        return false;\n    }\n\n    override bool addPreInvariant()\n    {\n        return false;\n    }\n\n    override bool addPostInvariant()\n    {\n        return false;\n    }\n\n    override inout(DeleteDeclaration) isDeleteDeclaration() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n"
  },
  {
    "path": "gcc/d/dmd/globals.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/globals.d, _globals.d)\n * Documentation:  https://dlang.org/phobos/dmd_globals.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/globals.d\n */\n\nmodule dmd.globals;\n\nimport core.stdc.stdint;\nimport dmd.root.array;\nimport dmd.root.filename;\nimport dmd.root.outbuffer;\nimport dmd.identifier;\n\ntemplate xversion(string s)\n{\n    enum xversion = mixin(`{ version (` ~ s ~ `) return true; else return false; }`)();\n}\n\nenum TARGET : bool\n{\n    Linux        = xversion!`linux`,\n    OSX          = xversion!`OSX`,\n    FreeBSD      = xversion!`FreeBSD`,\n    OpenBSD      = xversion!`OpenBSD`,\n    Solaris      = xversion!`Solaris`,\n    Windows      = xversion!`Windows`,\n    DragonFlyBSD = xversion!`DragonFlyBSD`,\n}\n\nenum Diagnostic : ubyte\n{\n    error,        // generate an error\n    inform,       // generate a warning\n    off,          // disable diagnostic\n}\n\nenum CHECKENABLE : ubyte\n{\n    _default,     // initial value\n    off,          // never do checking\n    on,           // always do checking\n    safeonly,     // do checking only in @safe functions\n}\n\nenum CHECKACTION : ubyte\n{\n    D,            // call D assert on failure\n    C,            // call C assert on failure\n    halt,         // cause program halt on failure\n}\n\nenum CPU\n{\n    x87,\n    mmx,\n    sse,\n    sse2,\n    sse3,\n    ssse3,\n    sse4_1,\n    sse4_2,\n    avx,                // AVX1 instruction set\n    avx2,               // AVX2 instruction set\n    avx512,             // AVX-512 instruction set\n\n    // Special values that don't survive past the command line processing\n    baseline,           // (default) the minimum capability CPU\n    native              // the machine the compiler is being run on\n}\n\n/**\nEach flag represents a field that can be included in the JSON output.\n\nNOTE: set type to uint so its size matches C++ unsigned type\n*/\nenum JsonFieldFlags : uint\n{\n    none         = 0,\n    compilerInfo = (1 << 0),\n    buildInfo    = (1 << 1),\n    modules      = (1 << 2),\n    semantics    = (1 << 3),\n}\n\n// Put command line switches in here\nstruct Param\n{\n    bool obj = true;        // write object file\n    bool link = true;       // perform link\n    bool dll;               // generate shared dynamic library\n    bool lib;               // write library file instead of object file(s)\n    bool multiobj;          // break one object file into multiple ones\n    bool oneobj;            // write one object file instead of multiple ones\n    bool trace;             // insert profiling hooks\n    bool tracegc;           // instrument calls to 'new'\n    bool verbose;           // verbose compile\n    bool vcg_ast;           // write-out codegen-ast\n    bool showColumns;       // print character (column) numbers in diagnostics\n    bool vtls;              // identify thread local variables\n    bool vgc;               // identify gc usage\n    bool vfield;            // identify non-mutable field variables\n    bool vcomplex;          // identify complex/imaginary type usage\n    ubyte symdebug;         // insert debug symbolic information\n    bool symdebugref;       // insert debug information for all referenced types, too\n    bool alwaysframe;       // always emit standard stack frame\n    bool optimize;          // run optimizer\n    bool map;               // generate linker .map file\n    bool is64bit = (size_t.sizeof == 8);  // generate 64 bit code; true by default for 64 bit dmd\n    bool isLP64;            // generate code for LP64\n    bool isLinux;           // generate code for linux\n    bool isOSX;             // generate code for Mac OSX\n    bool isWindows;         // generate code for Windows\n    bool isFreeBSD;         // generate code for FreeBSD\n    bool isOpenBSD;         // generate code for OpenBSD\n    bool isDragonFlyBSD;    // generate code for DragonFlyBSD\n    bool isSolaris;         // generate code for Solaris\n    bool hasObjectiveC;     // target supports Objective-C\n    bool mscoff = false;    // for Win32: write MsCoff object files instead of OMF\n    Diagnostic useDeprecated = Diagnostic.inform;  // how use of deprecated features are handled\n    bool useInvariants = true;  // generate class invariant checks\n    bool useIn = true;          // generate precondition checks\n    bool useOut = true;         // generate postcondition checks\n    bool stackstomp;            // add stack stomping code\n    bool useUnitTests;          // generate unittest code\n    bool useInline = false;     // inline expand functions\n    bool useDIP25;          // implement http://wiki.dlang.org/DIP25\n    bool release;           // build release version\n    bool preservePaths;     // true means don't strip path from source file\n    Diagnostic warnings = Diagnostic.off;  // how compiler warnings are handled\n    bool pic;               // generate position-independent-code for shared libs\n    bool color = true;      // use ANSI colors in console output\n    bool cov;               // generate code coverage data\n    ubyte covPercent;       // 0..100 code coverage percentage required\n    bool nofloat;           // code should not pull in floating point support\n    bool ignoreUnsupportedPragmas;  // rather than error on them\n    bool useModuleInfo = true;   // generate runtime module information\n    bool useTypeInfo = true;     // generate runtime type information\n    bool useExceptions = true;   // support exception handling\n    bool betterC;           // be a \"better C\" compiler; no dependency on D runtime\n    bool addMain;           // add a default main() function\n    bool allInst;           // generate code for all template instantiations\n    bool check10378;        // check for issues transitioning to 10738\n    bool bug10378;          // use pre- https://issues.dlang.org/show_bug.cgi?id=10378 search strategy\n    bool fix16997;          // fix integral promotions for unary + - ~ operators\n                            // https://issues.dlang.org/show_bug.cgi?id=16997\n    bool vsafe;             // use enhanced @safe checking\n    bool ehnogc;            // use @nogc exception handling\n    bool dtorFields;        // destruct fields of partially constructed objects\n                            // https://issues.dlang.org/show_bug.cgi?id=14246\n    /** The --transition=safe switch should only be used to show code with\n     * silent semantics changes related to @safe improvements.  It should not be\n     * used to hide a feature that will have to go through deprecate-then-error\n     * before becoming default.\n     */\n\n    bool showGaggedErrors;  // print gagged errors anyway\n    bool manual;            // open browser on compiler manual\n    bool usage;             // print usage and exit\n    bool mcpuUsage;         // print help on -mcpu switch\n    bool transitionUsage;   // print help on -transition switch\n    bool logo;              // print compiler logo\n\n    CPU cpu = CPU.baseline; // CPU instruction set to target\n\n    CHECKENABLE useArrayBounds = CHECKENABLE._default;  // when to generate code for array bounds checks\n    CHECKENABLE useAssert      = CHECKENABLE._default;  // when to generate code for assert()'s\n    CHECKENABLE useSwitchError = CHECKENABLE._default;  // check for switches without a default\n    CHECKACTION checkAction;       // action to take when bounds, asserts or switch defaults are violated\n\n    uint errorLimit = 20;\n\n    const(char)[] argv0;                // program name\n    Array!(const(char)*)* modFileAliasStrings; // array of char*'s of -I module filename alias strings\n    Array!(const(char)*)* imppath;      // array of char*'s of where to look for import modules\n    Array!(const(char)*)* fileImppath;  // array of char*'s of where to look for file import modules\n    const(char)* objdir;                // .obj/.lib file output directory\n    const(char)* objname;               // .obj file output name\n    const(char)* libname;               // .lib file output name\n\n    bool doDocComments;                 // process embedded documentation comments\n    const(char)* docdir;                // write documentation file to docdir directory\n    const(char)* docname;               // write documentation file to docname\n    Array!(const(char)*) ddocfiles;     // macro include files for Ddoc\n\n    bool doHdrGeneration;               // process embedded documentation comments\n    const(char)* hdrdir;                // write 'header' file to docdir directory\n    const(char)* hdrname;               // write 'header' file to docname\n    bool hdrStripPlainFunctions = true; // strip the bodies of plain (non-template) functions\n\n    bool doJsonGeneration;              // write JSON file\n    const(char)* jsonfilename;          // write JSON file to jsonfilename\n    JsonFieldFlags jsonFieldFlags;      // JSON field flags to include\n\n    uint debuglevel;                    // debug level\n    Array!(const(char)*)* debugids;     // debug identifiers\n\n    uint versionlevel;                  // version level\n    Array!(const(char)*)* versionids;   // version identifiers\n\n    const(char)* defaultlibname;        // default library for non-debug builds\n    const(char)* debuglibname;          // default library for debug builds\n    const(char)* mscrtlib;              // MS C runtime library\n\n    const(char)* moduleDepsFile;        // filename for deps output\n    OutBuffer* moduleDeps;              // contents to be written to deps file\n\n    // Hidden debug switches\n    bool debugb;\n    bool debugc;\n    bool debugf;\n    bool debugr;\n    bool debugx;\n    bool debugy;\n\n    bool run; // run resulting executable\n    Strings runargs; // arguments for executable\n\n    // Linker stuff\n    Array!(const(char)*) objfiles;\n    Array!(const(char)*) linkswitches;\n    Array!(const(char)*) libfiles;\n    Array!(const(char)*) dllfiles;\n    const(char)* deffile;\n    const(char)* resfile;\n    const(char)* exefile;\n    const(char)* mapfile;\n}\n\nalias structalign_t = uint;\n\n// magic value means \"match whatever the underlying C compiler does\"\n// other values are all powers of 2\nenum STRUCTALIGN_DEFAULT = (cast(structalign_t)~0);\n\nstruct Global\n{\n    const(char)* inifilename;\n    const(char)* mars_ext = \"d\";\n    const(char)* obj_ext;\n    const(char)* lib_ext;\n    const(char)* dll_ext;\n    const(char)* doc_ext = \"html\";      // for Ddoc generated files\n    const(char)* ddoc_ext = \"ddoc\";     // for Ddoc macro include files\n    const(char)* hdr_ext = \"di\";        // for D 'header' import files\n    const(char)* json_ext = \"json\";     // for JSON files\n    const(char)* map_ext = \"map\";       // for .map files\n    bool run_noext;                     // allow -run sources without extensions.\n\n    const(char)* copyright = \"Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\";\n    const(char)* written = \"written by Walter Bright\";\n    const(char)* main_d = \"__main.d\";   // dummy filename for dummy main()\n    Array!(const(char)*)* path;         // Array of char*'s which form the import lookup path\n    Array!(const(char)*)* filePath;     // Array of char*'s which form the file import lookup path\n\n    const(char)* _version;\n    const(char)* vendor;    // Compiler backend name\n\n    Param params;\n    uint errors;            // number of errors reported so far\n    uint warnings;          // number of warnings reported so far\n    uint gag;               // !=0 means gag reporting of errors & warnings\n    uint gaggedErrors;      // number of errors reported while gagged\n    uint gaggedWarnings;    // number of warnings reported while gagged\n\n    void* console;         // opaque pointer to console for controlling text attributes\n\n    Array!Identifier* versionids;    // command line versions and predefined versions\n    Array!Identifier* debugids;      // command line debug versions and predefined versions\n\n    /* Start gagging. Return the current number of gagged errors\n     */\n    extern (C++) uint startGagging()\n    {\n        ++gag;\n        gaggedWarnings = 0;\n        return gaggedErrors;\n    }\n\n    /* End gagging, restoring the old gagged state.\n     * Return true if errors occurred while gagged.\n     */\n    extern (C++) bool endGagging(uint oldGagged)\n    {\n        bool anyErrs = (gaggedErrors != oldGagged);\n        --gag;\n        // Restore the original state of gagged errors; set total errors\n        // to be original errors + new ungagged errors.\n        errors -= (gaggedErrors - oldGagged);\n        gaggedErrors = oldGagged;\n        return anyErrs;\n    }\n\n    /*  Increment the error count to record that an error\n     *  has occurred in the current context. An error message\n     *  may or may not have been printed.\n     */\n    extern (C++) void increaseErrorCount()\n    {\n        if (gag)\n            ++gaggedErrors;\n        ++errors;\n    }\n\n    extern (C++) void _init();\n\n    /**\n    Returns: the version as the number that would be returned for __VERSION__\n    */\n    extern(C++) uint versionNumber()\n    {\n        import core.stdc.ctype;\n        __gshared uint cached = 0;\n        if (cached == 0)\n        {\n            //\n            // parse _version\n            //\n            uint major = 0;\n            uint minor = 0;\n            bool point = false;\n            for (const(char)* p = _version + 1;; p++)\n            {\n                const c = *p;\n                if (isdigit(cast(char)c))\n                {\n                    minor = minor * 10 + c - '0';\n                }\n                else if (c == '.')\n                {\n                    if (point)\n                        break; // ignore everything after second '.'\n                    point = true;\n                    major = minor;\n                    minor = 0;\n                }\n                else\n                    break;\n            }\n            cached = major * 1000 + minor;\n        }\n        return cached;\n    }\n}\n\n// Because int64_t and friends may be any integral type of the\n// correct size, we have to explicitly ask for the correct\n// integer type to get the correct mangling with dmd\n\n// Be careful not to care about sign when using dinteger_t\n// use this instead of integer_t to\n// avoid conflicts with system #include's\nalias dinteger_t = ulong;\n// Signed and unsigned variants\nalias sinteger_t = long;\nalias uinteger_t = ulong;\n\nalias d_int8 = int8_t;\nalias d_uns8 = uint8_t;\nalias d_int16 = int16_t;\nalias d_uns16 = uint16_t;\nalias d_int32 = int32_t;\nalias d_uns32 = uint32_t;\nalias d_int64 = int64_t;\nalias d_uns64 = uint64_t;\n\n// file location\nstruct Loc\n{\n    const(char)* filename; // either absolute or relative to cwd\n    uint linnum;\n    uint charnum;\n\n    static immutable Loc initial;       /// use for default initialization of const ref Loc's\n\nnothrow:\n    extern (D) this(const(char)* filename, uint linnum, uint charnum) pure\n    {\n        this.linnum = linnum;\n        this.charnum = charnum;\n        this.filename = filename;\n    }\n\n    extern (C++) const(char)* toChars() const;\n\n    extern (C++) bool equals(ref const(Loc) loc) const\n    {\n        return (!global.params.showColumns || charnum == loc.charnum) &&\n               linnum == loc.linnum &&\n               FileName.equals(filename, loc.filename);\n    }\n\n    /******************\n     * Returns:\n     *   true if Loc has been set to other than the default initialization\n     */\n    bool isValid() const pure\n    {\n        return filename !is null;\n    }\n}\n\nenum LINK : int\n{\n    default_,\n    d,\n    c,\n    cpp,\n    windows,\n    pascal,\n    objc,\n    system,\n}\n\nenum CPPMANGLE : int\n{\n    def,\n    asStruct,\n    asClass,\n}\n\nenum MATCH : int\n{\n    nomatch,   // no match\n    convert,   // match with conversions\n    constant,  // match with conversion to const\n    exact,     // exact match\n}\n\nenum PINLINE : int\n{\n    default_,     // as specified on the command line\n    never,   // never inline\n    always,  // always inline\n}\n\nalias StorageClass = uinteger_t;\n\nextern (C++) __gshared Global global;\n"
  },
  {
    "path": "gcc/d/dmd/globals.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/globals.h\n */\n\n#pragma once\n\n#include \"root/dcompat.h\"\n#include \"root/ctfloat.h\"\n#include \"root/outbuffer.h\"\n#include \"root/filename.h\"\n#include \"compiler.h\"\n\n// Can't include arraytypes.h here, need to declare these directly.\ntemplate <typename TYPE> struct Array;\n\ntypedef unsigned char Diagnostic;\nenum\n{\n    DIAGNOSTICerror,  // generate an error\n    DIAGNOSTICinform, // generate a warning\n    DIAGNOSTICoff     // disable diagnostic\n};\n\n// The state of array bounds checking\ntypedef unsigned char CHECKENABLE;\nenum\n{\n    CHECKENABLEdefault, // initial value\n    CHECKENABLEoff,     // never do bounds checking\n    CHECKENABLEon,      // always do bounds checking\n    CHECKENABLEsafeonly // do bounds checking only in @safe functions\n};\n\ntypedef unsigned char CHECKACTION;\nenum\n{\n    CHECKACTION_D,        // call D assert on failure\n    CHECKACTION_C,        // call C assert on failure\n    CHECKACTION_halt      // cause program halt on failure\n};\n\nenum CPU\n{\n    x87,\n    mmx,\n    sse,\n    sse2,\n    sse3,\n    ssse3,\n    sse4_1,\n    sse4_2,\n    avx,                // AVX1 instruction set\n    avx2,               // AVX2 instruction set\n    avx512,             // AVX-512 instruction set\n\n    // Special values that don't survive past the command line processing\n    baseline,           // (default) the minimum capability CPU\n    native              // the machine the compiler is being run on\n};\n\n// Put command line switches in here\nstruct Param\n{\n    bool obj;           // write object file\n    bool link;          // perform link\n    bool dll;           // generate shared dynamic library\n    bool lib;           // write library file instead of object file(s)\n    bool multiobj;      // break one object file into multiple ones\n    bool oneobj;        // write one object file instead of multiple ones\n    bool trace;         // insert profiling hooks\n    bool tracegc;       // instrument calls to 'new'\n    bool verbose;       // verbose compile\n    bool vcg_ast;       // write-out codegen-ast\n    bool showColumns;   // print character (column) numbers in diagnostics\n    bool vtls;          // identify thread local variables\n    bool vgc;           // identify gc usage\n    bool vfield;        // identify non-mutable field variables\n    bool vcomplex;      // identify complex/imaginary type usage\n    char symdebug;      // insert debug symbolic information\n    bool symdebugref;   // insert debug information for all referenced types, too\n    bool alwaysframe;   // always emit standard stack frame\n    bool optimize;      // run optimizer\n    bool map;           // generate linker .map file\n    bool is64bit;       // generate 64 bit code\n    bool isLP64;        // generate code for LP64\n    bool isLinux;       // generate code for linux\n    bool isOSX;         // generate code for Mac OSX\n    bool isWindows;     // generate code for Windows\n    bool isFreeBSD;     // generate code for FreeBSD\n    bool isOpenBSD;     // generate code for OpenBSD\n    bool isDragonFlyBSD;// generate code for DragonFlyBSD\n    bool isSolaris;     // generate code for Solaris\n    bool hasObjectiveC; // target supports Objective-C\n    bool mscoff;        // for Win32: write COFF object files instead of OMF\n    Diagnostic useDeprecated;\n    bool useInvariants; // generate class invariant checks\n    bool useIn;         // generate precondition checks\n    bool useOut;        // generate postcondition checks\n    bool stackstomp;    // add stack stomping code\n    bool useUnitTests;  // generate unittest code\n    bool useInline;     // inline expand functions\n    bool useDIP25;      // implement http://wiki.dlang.org/DIP25\n    bool release;       // build release version\n    bool preservePaths; // true means don't strip path from source file\n    Diagnostic warnings;\n    bool pic;           // generate position-independent-code for shared libs\n    bool color;         // use ANSI colors in console output\n    bool cov;           // generate code coverage data\n    unsigned char covPercent;   // 0..100 code coverage percentage required\n    bool nofloat;       // code should not pull in floating point support\n    bool ignoreUnsupportedPragmas;      // rather than error on them\n    bool useModuleInfo; // generate runtime module information\n    bool useTypeInfo;   // generate runtime type information\n    bool useExceptions; // support exception handling\n    bool betterC;       // be a \"better C\" compiler; no dependency on D runtime\n    bool addMain;       // add a default main() function\n    bool allInst;       // generate code for all template instantiations\n    bool check10378;    // check for issues transitioning to 10738\n    bool bug10378;      // use pre-bugzilla 10378 search strategy\n    bool fix16997;      // fix integral promotions for unary + - ~ operators\n                        // https://issues.dlang.org/show_bug.cgi?id=16997\n    bool vsafe;         // use enhanced @safe checking\n    bool ehnogc;        // use @nogc exception handling\n    bool dtorFields;        // destruct fields of partially constructed objects\n                            // https://issues.dlang.org/show_bug.cgi?id=14246\n    bool showGaggedErrors;  // print gagged errors anyway\n    bool manual;            // open browser on compiler manual\n    bool usage;             // print usage and exit\n    bool mcpuUsage;         // print help on -mcpu switch\n    bool transitionUsage;   // print help on -transition switch\n    bool logo;              // print logo;\n\n    CPU cpu;                // CPU instruction set to target\n\n    CHECKENABLE useArrayBounds;    // when to generate code for array bounds checks\n    CHECKENABLE useAssert;         // when to generate code for assert()'s\n    CHECKENABLE useSwitchError;    // check for switches without a default\n    CHECKACTION checkAction;       // action to take when bounds, asserts or switch defaults are violated\n\n    unsigned errorLimit;\n\n    DArray<const char>  argv0;    // program name\n    Array<const char *> *modFileAliasStrings; // array of char*'s of -I module filename alias strings\n    Array<const char *> *imppath;     // array of char*'s of where to look for import modules\n    Array<const char *> *fileImppath; // array of char*'s of where to look for file import modules\n    const char *objdir;   // .obj/.lib file output directory\n    const char *objname;  // .obj file output name\n    const char *libname;  // .lib file output name\n\n    bool doDocComments;  // process embedded documentation comments\n    const char *docdir;  // write documentation file to docdir directory\n    const char *docname; // write documentation file to docname\n    Array<const char *> ddocfiles;  // macro include files for Ddoc\n\n    bool doHdrGeneration;  // process embedded documentation comments\n    const char *hdrdir;    // write 'header' file to docdir directory\n    const char *hdrname;   // write 'header' file to docname\n    bool hdrStripPlainFunctions; // strip the bodies of plain (non-template) functions\n\n    bool doJsonGeneration;    // write JSON file\n    const char *jsonfilename; // write JSON file to jsonfilename\n    unsigned jsonFieldFlags;  // JSON field flags to include\n\n    unsigned debuglevel;   // debug level\n    Array<const char *> *debugids;     // debug identifiers\n\n    unsigned versionlevel; // version level\n    Array<const char *> *versionids;   // version identifiers\n\n    const char *defaultlibname; // default library for non-debug builds\n    const char *debuglibname;   // default library for debug builds\n    const char *mscrtlib;       // MS C runtime library\n\n    const char *moduleDepsFile; // filename for deps output\n    OutBuffer *moduleDeps;      // contents to be written to deps file\n\n    // Hidden debug switches\n    bool debugb;\n    bool debugc;\n    bool debugf;\n    bool debugr;\n    bool debugx;\n    bool debugy;\n\n    bool run;           // run resulting executable\n    Strings runargs;    // arguments for executable\n\n    // Linker stuff\n    Array<const char *> objfiles;\n    Array<const char *> linkswitches;\n    Array<const char *> libfiles;\n    Array<const char *> dllfiles;\n    const char *deffile;\n    const char *resfile;\n    const char *exefile;\n    const char *mapfile;\n};\n\ntypedef unsigned structalign_t;\n// magic value means \"match whatever the underlying C compiler does\"\n// other values are all powers of 2\n#define STRUCTALIGN_DEFAULT ((structalign_t) ~0)\n\nstruct Global\n{\n    const char *inifilename;\n    const char *mars_ext;\n    const char *obj_ext;\n    const char *lib_ext;\n    const char *dll_ext;\n    const char *doc_ext;        // for Ddoc generated files\n    const char *ddoc_ext;       // for Ddoc macro include files\n    const char *hdr_ext;        // for D 'header' import files\n    const char *json_ext;       // for JSON files\n    const char *map_ext;        // for .map files\n    bool run_noext;             // allow -run sources without extensions.\n\n    const char *copyright;\n    const char *written;\n    const char *main_d;         // dummy filename for dummy main()\n    Array<const char *> *path;        // Array of char*'s which form the import lookup path\n    Array<const char *> *filePath;    // Array of char*'s which form the file import lookup path\n\n    const char *version;     // Compiler version string\n    const char *vendor;      // Compiler backend name\n\n    Param params;\n    unsigned errors;         // number of errors reported so far\n    unsigned warnings;       // number of warnings reported so far\n    unsigned gag;            // !=0 means gag reporting of errors & warnings\n    unsigned gaggedErrors;   // number of errors reported while gagged\n    unsigned gaggedWarnings; // number of warnings reported while gagged\n\n    void* console;         // opaque pointer to console for controlling text attributes\n\n    Array<class Identifier*>* versionids; // command line versions and predefined versions\n    Array<class Identifier*>* debugids;   // command line debug versions and predefined versions\n\n    /* Start gagging. Return the current number of gagged errors\n     */\n    unsigned startGagging();\n\n    /* End gagging, restoring the old gagged state.\n     * Return true if errors occurred while gagged.\n     */\n    bool endGagging(unsigned oldGagged);\n\n    /*  Increment the error count to record that an error\n     *  has occurred in the current context. An error message\n     *  may or may not have been printed.\n     */\n    void increaseErrorCount();\n\n    void _init();\n\n    /**\n    Returns: the version as the number that would be returned for __VERSION__\n    */\n    unsigned versionNumber();\n};\n\nextern Global global;\n\n// Because int64_t and friends may be any integral type of the\n// correct size, we have to explicitly ask for the correct\n// integer type to get the correct mangling with dmd\n#if __LP64__\n// Be careful not to care about sign when using dinteger_t\n// use this instead of integer_t to\n// avoid conflicts with system #include's\ntypedef unsigned long dinteger_t;\n// Signed and unsigned variants\ntypedef long sinteger_t;\ntypedef unsigned long uinteger_t;\n#else\ntypedef unsigned long long dinteger_t;\ntypedef long long sinteger_t;\ntypedef unsigned long long uinteger_t;\n#endif\n\ntypedef int8_t                  d_int8;\ntypedef uint8_t                 d_uns8;\ntypedef int16_t                 d_int16;\ntypedef uint16_t                d_uns16;\ntypedef int32_t                 d_int32;\ntypedef uint32_t                d_uns32;\ntypedef int64_t                 d_int64;\ntypedef uint64_t                d_uns64;\n\n// file location\nstruct Loc\n{\n    const char *filename; // either absolute or relative to cwd\n    unsigned linnum;\n    unsigned charnum;\n\n    Loc()\n    {\n        linnum = 0;\n        charnum = 0;\n        filename = NULL;\n    }\n\n    Loc(const char *filename, unsigned linnum, unsigned charnum);\n\n    const char *toChars() const;\n    bool equals(const Loc& loc) const;\n};\n\nenum LINK\n{\n    LINKdefault,\n    LINKd,\n    LINKc,\n    LINKcpp,\n    LINKwindows,\n    LINKpascal,\n    LINKobjc,\n    LINKsystem\n};\n\nenum CPPMANGLE\n{\n    CPPMANGLEdefault,\n    CPPMANGLEstruct,\n    CPPMANGLEclass\n};\n\nenum MATCH\n{\n    MATCHnomatch,       // no match\n    MATCHconvert,       // match with conversions\n    MATCHconst,         // match with conversion to const\n    MATCHexact          // exact match\n};\n\nenum PINLINE\n{\n    PINLINEdefault,      // as specified on the command line\n    PINLINEnever,        // never inline\n    PINLINEalways        // always inline\n};\n\ntypedef uinteger_t StorageClass;\n"
  },
  {
    "path": "gcc/d/dmd/gluelayer.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/gluelayer.d, _gluelayer.d)\n * Documentation:  https://dlang.org/phobos/dmd_gluelayer.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/gluelayer.d\n */\n\nmodule dmd.gluelayer;\n\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.mtype;\nimport dmd.statement;\nimport dmd.root.file;\n\nversion (NoBackend)\n{\n    import dmd.lib : Library;\n\n    struct Symbol;\n    struct code;\n    struct block;\n    struct Blockx;\n    struct elem;\n    struct TYPE;\n    alias type = TYPE;\n\n    extern (C++)\n    {\n        // glue\n        void obj_write_deferred(Library library)        {}\n        void obj_start(const(char)* srcfile)            {}\n        void obj_end(Library library, File* objfile)    {}\n        void genObjFile(Module m, bool multiobj)        {}\n\n        // msc\n        void backend_init() {}\n        void backend_term() {}\n\n        // iasm\n        Statement asmSemantic(AsmStatement s, Scope* sc) { assert(0); }\n\n        // toir\n        void toObjFile(Dsymbol ds, bool multiobj)   {}\n\n        extern(C++) abstract class ObjcGlue\n        {\n            static void initialize() {}\n        }\n    }\n}\nelse version (MARS)\n{\n    import dmd.lib : Library;\n\n    public import dmd.backend.cc : block, Blockx, Symbol;\n    public import dmd.backend.type : type;\n    public import dmd.backend.el : elem;\n    public import dmd.backend.code_x86 : code;\n\n    extern (C++)\n    {\n        void obj_write_deferred(Library library);\n        void obj_start(const(char)* srcfile);\n        void obj_end(Library library, File* objfile);\n        void genObjFile(Module m, bool multiobj);\n\n        void backend_init();\n        void backend_term();\n\n        Statement asmSemantic(AsmStatement s, Scope* sc);\n\n        void toObjFile(Dsymbol ds, bool multiobj);\n\n        extern(C++) abstract class ObjcGlue\n        {\n            static void initialize();\n        }\n    }\n}\nelse version (IN_GCC)\n{\n    union tree_node;\n\n    alias Symbol = tree_node;\n    alias code = tree_node;\n    alias type = tree_node;\n\n    extern (C++)\n    {\n        Statement asmSemantic(AsmStatement s, Scope* sc);\n    }\n\n    // stubs\n    extern(C++) abstract class ObjcGlue\n    {\n        static void initialize() {}\n    }\n}\nelse\n    static assert(false, \"Unsupported compiler backend\");\n"
  },
  {
    "path": "gcc/d/dmd/hdrgen.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/hdrgen.d, _hdrgen.d)\n * Documentation:  https://dlang.org/phobos/dmd_hdrgen.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/hdrgen.d\n */\n\nmodule dmd.hdrgen;\n\nimport core.stdc.ctype;\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arraytypes;\nimport dmd.attrib;\nimport dmd.complex;\nimport dmd.cond;\nimport dmd.ctfeexpr;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dimport;\nimport dmd.dmodule;\nimport dmd.doc;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dtemplate;\nimport dmd.dversion;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.mtype;\nimport dmd.nspace;\nimport dmd.parse;\nimport dmd.root.ctfloat;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.statement;\nimport dmd.staticassert;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.utils;\nimport dmd.visitor;\n\nstruct HdrGenState\n{\n    bool hdrgen;        /// true if generating header file\n    bool ddoc;          /// true if generating Ddoc file\n    bool fullDump;      /// true if generating a full AST dump file\n\n    bool fullQual;      /// fully qualify types when printing\n    int tpltMember;\n    int autoMember;\n    int forStmtInit;\n}\n\nenum TEST_EMIT_ALL = 0;\n\nextern (C++) void genhdrfile(Module m)\n{\n    OutBuffer buf;\n    buf.doindent = 1;\n    buf.printf(\"// D import file generated from '%s'\", m.srcfile.toChars());\n    buf.writenl();\n    HdrGenState hgs;\n    hgs.hdrgen = true;\n    toCBuffer(m, &buf, &hgs);\n    // Transfer image to file\n    m.hdrfile.setbuffer(buf.data, buf.offset);\n    buf.extractData();\n    ensurePathToNameExists(Loc.initial, m.hdrfile.toChars());\n    writeFile(m.loc, m.hdrfile);\n}\n\n/**\n * Dumps the full contents of module `m` to `buf`.\n * Params:\n *   buf = buffer to write to.\n *   m = module to visit all members of.\n */\nextern (C++) void moduleToBuffer(OutBuffer* buf, Module m)\n{\n    HdrGenState hgs;\n    hgs.fullDump = true;\n    toCBuffer(m, buf, &hgs);\n}\n\nextern (C++) final class PrettyPrintVisitor : Visitor\n{\n    alias visit = Visitor.visit;\npublic:\n    OutBuffer* buf;\n    HdrGenState* hgs;\n    bool declstring; // set while declaring alias for string,wstring or dstring\n    EnumDeclaration inEnumDecl;\n\n    extern (D) this(OutBuffer* buf, HdrGenState* hgs)\n    {\n        this.buf = buf;\n        this.hgs = hgs;\n    }\n\n    override void visit(Statement s)\n    {\n        buf.writestring(\"Statement::toCBuffer()\");\n        buf.writenl();\n        assert(0);\n    }\n\n    override void visit(ErrorStatement s)\n    {\n        buf.writestring(\"__error__\");\n        buf.writenl();\n    }\n\n    override void visit(ExpStatement s)\n    {\n        if (s.exp && s.exp.op == TOK.declaration)\n        {\n            // bypass visit(DeclarationExp)\n            (cast(DeclarationExp)s.exp).declaration.accept(this);\n            return;\n        }\n        if (s.exp)\n            s.exp.accept(this);\n        buf.writeByte(';');\n        if (!hgs.forStmtInit)\n            buf.writenl();\n    }\n\n    override void visit(CompileStatement s)\n    {\n        buf.writestring(\"mixin(\");\n        argsToBuffer(s.exps, null);\n        buf.writestring(\");\");\n        if (!hgs.forStmtInit)\n            buf.writenl();\n    }\n\n    override void visit(CompoundStatement s)\n    {\n        foreach (sx; *s.statements)\n        {\n            if (sx)\n                sx.accept(this);\n        }\n    }\n\n    override void visit(CompoundDeclarationStatement s)\n    {\n        bool anywritten = false;\n        foreach (sx; *s.statements)\n        {\n            auto ds = sx ? sx.isExpStatement() : null;\n            if (ds && ds.exp.op == TOK.declaration)\n            {\n                auto d = (cast(DeclarationExp)ds.exp).declaration;\n                assert(d.isDeclaration());\n                if (auto v = d.isVarDeclaration())\n                    visitVarDecl(v, anywritten);\n                else\n                    d.accept(this);\n                anywritten = true;\n            }\n        }\n        buf.writeByte(';');\n        if (!hgs.forStmtInit)\n            buf.writenl();\n    }\n\n    override void visit(UnrolledLoopStatement s)\n    {\n        buf.writestring(\"/*unrolled*/ {\");\n        buf.writenl();\n        buf.level++;\n        foreach (sx; *s.statements)\n        {\n            if (sx)\n                sx.accept(this);\n        }\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n    }\n\n    override void visit(ScopeStatement s)\n    {\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n        if (s.statement)\n            s.statement.accept(this);\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n    }\n\n    override void visit(WhileStatement s)\n    {\n        buf.writestring(\"while (\");\n        s.condition.accept(this);\n        buf.writeByte(')');\n        buf.writenl();\n        if (s._body)\n            s._body.accept(this);\n    }\n\n    override void visit(DoStatement s)\n    {\n        buf.writestring(\"do\");\n        buf.writenl();\n        if (s._body)\n            s._body.accept(this);\n        buf.writestring(\"while (\");\n        s.condition.accept(this);\n        buf.writestring(\");\");\n        buf.writenl();\n    }\n\n    override void visit(ForStatement s)\n    {\n        buf.writestring(\"for (\");\n        if (s._init)\n        {\n            hgs.forStmtInit++;\n            s._init.accept(this);\n            hgs.forStmtInit--;\n        }\n        else\n            buf.writeByte(';');\n        if (s.condition)\n        {\n            buf.writeByte(' ');\n            s.condition.accept(this);\n        }\n        buf.writeByte(';');\n        if (s.increment)\n        {\n            buf.writeByte(' ');\n            s.increment.accept(this);\n        }\n        buf.writeByte(')');\n        buf.writenl();\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n        if (s._body)\n            s._body.accept(this);\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n    }\n\n    private void visitWithoutBody(ForeachStatement s)\n    {\n        buf.writestring(Token.toString(s.op));\n        buf.writestring(\" (\");\n        foreach (i, p; *s.parameters)\n        {\n            if (i)\n                buf.writestring(\", \");\n            if (stcToBuffer(buf, p.storageClass))\n                buf.writeByte(' ');\n            if (p.type)\n                typeToBuffer(p.type, p.ident);\n            else\n                buf.writestring(p.ident.toString());\n        }\n        buf.writestring(\"; \");\n        s.aggr.accept(this);\n        buf.writeByte(')');\n        buf.writenl();\n    }\n\n    override void visit(ForeachStatement s)\n    {\n        visitWithoutBody(s);\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n        if (s._body)\n            s._body.accept(this);\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n    }\n\n    private void visitWithoutBody(ForeachRangeStatement s)\n    {\n        buf.writestring(Token.toString(s.op));\n        buf.writestring(\" (\");\n        if (s.prm.type)\n            typeToBuffer(s.prm.type, s.prm.ident);\n        else\n            buf.writestring(s.prm.ident.toString());\n        buf.writestring(\"; \");\n        s.lwr.accept(this);\n        buf.writestring(\" .. \");\n        s.upr.accept(this);\n        buf.writeByte(')');\n        buf.writenl();\n        buf.writeByte('{');\n        buf.writenl();\n    }\n\n    override void visit(ForeachRangeStatement s)\n    {\n        visitWithoutBody(s);\n        buf.level++;\n        if (s._body)\n            s._body.accept(this);\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n    }\n\n    override void visit(StaticForeachStatement s)\n    {\n        buf.writestring(\"static \");\n        if (s.sfe.aggrfe)\n        {\n            visit(s.sfe.aggrfe);\n        }\n        else\n        {\n            assert(s.sfe.rangefe);\n            visit(s.sfe.rangefe);\n        }\n    }\n\n    override void visit(IfStatement s)\n    {\n        buf.writestring(\"if (\");\n        if (Parameter p = s.prm)\n        {\n            StorageClass stc = p.storageClass;\n            if (!p.type && !stc)\n                stc = STC.auto_;\n            if (stcToBuffer(buf, stc))\n                buf.writeByte(' ');\n            if (p.type)\n                typeToBuffer(p.type, p.ident);\n            else\n                buf.writestring(p.ident.toString());\n            buf.writestring(\" = \");\n        }\n        s.condition.accept(this);\n        buf.writeByte(')');\n        buf.writenl();\n        if (s.ifbody.isScopeStatement())\n        {\n            s.ifbody.accept(this);\n        }\n        else\n        {\n            buf.level++;\n            s.ifbody.accept(this);\n            buf.level--;\n        }\n        if (s.elsebody)\n        {\n            buf.writestring(\"else\");\n            if (!s.elsebody.isIfStatement())\n            {\n                buf.writenl();\n            }\n            else\n            {\n                buf.writeByte(' ');\n            }\n            if (s.elsebody.isScopeStatement() || s.elsebody.isIfStatement())\n            {\n                s.elsebody.accept(this);\n            }\n            else\n            {\n                buf.level++;\n                s.elsebody.accept(this);\n                buf.level--;\n            }\n        }\n    }\n\n    override void visit(ConditionalStatement s)\n    {\n        s.condition.accept(this);\n        buf.writenl();\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n        if (s.ifbody)\n            s.ifbody.accept(this);\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n        if (s.elsebody)\n        {\n            buf.writestring(\"else\");\n            buf.writenl();\n            buf.writeByte('{');\n            buf.level++;\n            buf.writenl();\n            s.elsebody.accept(this);\n            buf.level--;\n            buf.writeByte('}');\n        }\n        buf.writenl();\n    }\n\n    override void visit(PragmaStatement s)\n    {\n        buf.writestring(\"pragma (\");\n        buf.writestring(s.ident.toString());\n        if (s.args && s.args.dim)\n        {\n            buf.writestring(\", \");\n            argsToBuffer(s.args);\n        }\n        buf.writeByte(')');\n        if (s._body)\n        {\n            buf.writenl();\n            buf.writeByte('{');\n            buf.writenl();\n            buf.level++;\n            s._body.accept(this);\n            buf.level--;\n            buf.writeByte('}');\n            buf.writenl();\n        }\n        else\n        {\n            buf.writeByte(';');\n            buf.writenl();\n        }\n    }\n\n    override void visit(StaticAssertStatement s)\n    {\n        s.sa.accept(this);\n    }\n\n    override void visit(SwitchStatement s)\n    {\n        buf.writestring(s.isFinal ? \"final switch (\" : \"switch (\");\n        s.condition.accept(this);\n        buf.writeByte(')');\n        buf.writenl();\n        if (s._body)\n        {\n            if (!s._body.isScopeStatement())\n            {\n                buf.writeByte('{');\n                buf.writenl();\n                buf.level++;\n                s._body.accept(this);\n                buf.level--;\n                buf.writeByte('}');\n                buf.writenl();\n            }\n            else\n            {\n                s._body.accept(this);\n            }\n        }\n    }\n\n    override void visit(CaseStatement s)\n    {\n        buf.writestring(\"case \");\n        s.exp.accept(this);\n        buf.writeByte(':');\n        buf.writenl();\n        s.statement.accept(this);\n    }\n\n    override void visit(CaseRangeStatement s)\n    {\n        buf.writestring(\"case \");\n        s.first.accept(this);\n        buf.writestring(\": .. case \");\n        s.last.accept(this);\n        buf.writeByte(':');\n        buf.writenl();\n        s.statement.accept(this);\n    }\n\n    override void visit(DefaultStatement s)\n    {\n        buf.writestring(\"default:\");\n        buf.writenl();\n        s.statement.accept(this);\n    }\n\n    override void visit(GotoDefaultStatement s)\n    {\n        buf.writestring(\"goto default;\");\n        buf.writenl();\n    }\n\n    override void visit(GotoCaseStatement s)\n    {\n        buf.writestring(\"goto case\");\n        if (s.exp)\n        {\n            buf.writeByte(' ');\n            s.exp.accept(this);\n        }\n        buf.writeByte(';');\n        buf.writenl();\n    }\n\n    override void visit(SwitchErrorStatement s)\n    {\n        buf.writestring(\"SwitchErrorStatement::toCBuffer()\");\n        buf.writenl();\n    }\n\n    override void visit(ReturnStatement s)\n    {\n        buf.writestring(\"return \");\n        if (s.exp)\n            s.exp.accept(this);\n        buf.writeByte(';');\n        buf.writenl();\n    }\n\n    override void visit(BreakStatement s)\n    {\n        buf.writestring(\"break\");\n        if (s.ident)\n        {\n            buf.writeByte(' ');\n            buf.writestring(s.ident.toString());\n        }\n        buf.writeByte(';');\n        buf.writenl();\n    }\n\n    override void visit(ContinueStatement s)\n    {\n        buf.writestring(\"continue\");\n        if (s.ident)\n        {\n            buf.writeByte(' ');\n            buf.writestring(s.ident.toString());\n        }\n        buf.writeByte(';');\n        buf.writenl();\n    }\n\n    override void visit(SynchronizedStatement s)\n    {\n        buf.writestring(\"synchronized\");\n        if (s.exp)\n        {\n            buf.writeByte('(');\n            s.exp.accept(this);\n            buf.writeByte(')');\n        }\n        if (s._body)\n        {\n            buf.writeByte(' ');\n            s._body.accept(this);\n        }\n    }\n\n    override void visit(WithStatement s)\n    {\n        buf.writestring(\"with (\");\n        s.exp.accept(this);\n        buf.writestring(\")\");\n        buf.writenl();\n        if (s._body)\n            s._body.accept(this);\n    }\n\n    override void visit(TryCatchStatement s)\n    {\n        buf.writestring(\"try\");\n        buf.writenl();\n        if (s._body)\n        {\n            if (s._body.isScopeStatement())\n            {\n                s._body.accept(this);\n            }\n            else\n            {\n                buf.level++;\n                s._body.accept(this);\n                buf.level--;\n            }\n        }\n        foreach (c; *s.catches)\n        {\n            visit(c);\n        }\n    }\n\n    override void visit(TryFinallyStatement s)\n    {\n        buf.writestring(\"try\");\n        buf.writenl();\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n        s._body.accept(this);\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n        buf.writestring(\"finally\");\n        buf.writenl();\n        if (s.finalbody.isScopeStatement())\n        {\n            s.finalbody.accept(this);\n        }\n        else\n        {\n            buf.level++;\n            s.finalbody.accept(this);\n            buf.level--;\n        }\n    }\n\n    override void visit(OnScopeStatement s)\n    {\n        buf.writestring(Token.toString(s.tok));\n        buf.writeByte(' ');\n        s.statement.accept(this);\n    }\n\n    override void visit(ThrowStatement s)\n    {\n        buf.writestring(\"throw \");\n        s.exp.accept(this);\n        buf.writeByte(';');\n        buf.writenl();\n    }\n\n    override void visit(DebugStatement s)\n    {\n        if (s.statement)\n        {\n            s.statement.accept(this);\n        }\n    }\n\n    override void visit(GotoStatement s)\n    {\n        buf.writestring(\"goto \");\n        buf.writestring(s.ident.toString());\n        buf.writeByte(';');\n        buf.writenl();\n    }\n\n    override void visit(LabelStatement s)\n    {\n        buf.writestring(s.ident.toString());\n        buf.writeByte(':');\n        buf.writenl();\n        if (s.statement)\n            s.statement.accept(this);\n    }\n\n    override void visit(AsmStatement s)\n    {\n        buf.writestring(\"asm { \");\n        Token* t = s.tokens;\n        buf.level++;\n        while (t)\n        {\n            buf.writestring(t.toChars());\n            if (t.next &&\n                t.value != TOK.min      &&\n                t.value != TOK.comma    && t.next.value != TOK.comma    &&\n                t.value != TOK.leftBracket && t.next.value != TOK.leftBracket &&\n                                          t.next.value != TOK.rightBracket &&\n                t.value != TOK.leftParentheses   && t.next.value != TOK.leftParentheses   &&\n                                          t.next.value != TOK.rightParentheses   &&\n                t.value != TOK.dot      && t.next.value != TOK.dot)\n            {\n                buf.writeByte(' ');\n            }\n            t = t.next;\n        }\n        buf.level--;\n        buf.writestring(\"; }\");\n        buf.writenl();\n    }\n\n    override void visit(ImportStatement s)\n    {\n        foreach (imp; *s.imports)\n        {\n            imp.accept(this);\n        }\n    }\n\n    void visit(Catch c)\n    {\n        buf.writestring(\"catch\");\n        if (c.type)\n        {\n            buf.writeByte('(');\n            typeToBuffer(c.type, c.ident);\n            buf.writeByte(')');\n        }\n        buf.writenl();\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n        if (c.handler)\n            c.handler.accept(this);\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    /**************************************************\n     * An entry point to pretty-print type.\n     */\n    void typeToBuffer(Type t, Identifier ident)\n    {\n        if (t.ty == Tfunction)\n        {\n            visitFuncIdentWithPrefix(cast(TypeFunction)t, ident, null);\n            return;\n        }\n        visitWithMask(t, 0);\n        if (ident)\n        {\n            buf.writeByte(' ');\n            buf.writestring(ident.toString());\n        }\n    }\n\n    void visitWithMask(Type t, ubyte modMask)\n    {\n        // Tuples and functions don't use the type constructor syntax\n        if (modMask == t.mod || t.ty == Tfunction || t.ty == Ttuple)\n        {\n            t.accept(this);\n        }\n        else\n        {\n            ubyte m = t.mod & ~(t.mod & modMask);\n            if (m & MODFlags.shared_)\n            {\n                MODtoBuffer(buf, MODFlags.shared_);\n                buf.writeByte('(');\n            }\n            if (m & MODFlags.wild)\n            {\n                MODtoBuffer(buf, MODFlags.wild);\n                buf.writeByte('(');\n            }\n            if (m & (MODFlags.const_ | MODFlags.immutable_))\n            {\n                MODtoBuffer(buf, m & (MODFlags.const_ | MODFlags.immutable_));\n                buf.writeByte('(');\n            }\n            t.accept(this);\n            if (m & (MODFlags.const_ | MODFlags.immutable_))\n                buf.writeByte(')');\n            if (m & MODFlags.wild)\n                buf.writeByte(')');\n            if (m & MODFlags.shared_)\n                buf.writeByte(')');\n        }\n    }\n\n    override void visit(Type t)\n    {\n        printf(\"t = %p, ty = %d\\n\", t, t.ty);\n        assert(0);\n    }\n\n    override void visit(TypeError t)\n    {\n        buf.writestring(\"_error_\");\n    }\n\n    override void visit(TypeBasic t)\n    {\n        //printf(\"TypeBasic::toCBuffer2(t.mod = %d)\\n\", t.mod);\n        buf.writestring(t.dstring);\n    }\n\n    override void visit(TypeVector t)\n    {\n        //printf(\"TypeVector::toCBuffer2(t.mod = %d)\\n\", t.mod);\n        buf.writestring(\"__vector(\");\n        visitWithMask(t.basetype, t.mod);\n        buf.writestring(\")\");\n    }\n\n    override void visit(TypeSArray t)\n    {\n        visitWithMask(t.next, t.mod);\n        buf.writeByte('[');\n        sizeToBuffer(t.dim);\n        buf.writeByte(']');\n    }\n\n    override void visit(TypeDArray t)\n    {\n        Type ut = t.castMod(0);\n        if (declstring)\n            goto L1;\n        if (ut.equals(Type.tstring))\n            buf.writestring(\"string\");\n        else if (ut.equals(Type.twstring))\n            buf.writestring(\"wstring\");\n        else if (ut.equals(Type.tdstring))\n            buf.writestring(\"dstring\");\n        else\n        {\n        L1:\n            visitWithMask(t.next, t.mod);\n            buf.writestring(\"[]\");\n        }\n    }\n\n    override void visit(TypeAArray t)\n    {\n        visitWithMask(t.next, t.mod);\n        buf.writeByte('[');\n        visitWithMask(t.index, 0);\n        buf.writeByte(']');\n    }\n\n    override void visit(TypePointer t)\n    {\n        //printf(\"TypePointer::toCBuffer2() next = %d\\n\", t.next.ty);\n        if (t.next.ty == Tfunction)\n            visitFuncIdentWithPostfix(cast(TypeFunction)t.next, \"function\");\n        else\n        {\n            visitWithMask(t.next, t.mod);\n            buf.writeByte('*');\n        }\n    }\n\n    override void visit(TypeReference t)\n    {\n        visitWithMask(t.next, t.mod);\n        buf.writeByte('&');\n    }\n\n    override void visit(TypeFunction t)\n    {\n        //printf(\"TypeFunction::toCBuffer2() t = %p, ref = %d\\n\", t, t.isref);\n        visitFuncIdentWithPostfix(t, null);\n    }\n\n    // callback for TypeFunction::attributesApply\n    struct PrePostAppendStrings\n    {\n        OutBuffer* buf;\n        bool isPostfixStyle;\n        bool isCtor;\n\n        extern (D) static int fp(void* param, string str)\n        {\n            PrePostAppendStrings* p = cast(PrePostAppendStrings*)param;\n            // don't write 'ref' for ctors\n            if (p.isCtor && str == \"ref\")\n                return 0;\n            if (p.isPostfixStyle)\n                p.buf.writeByte(' ');\n            p.buf.writestring(str);\n            if (!p.isPostfixStyle)\n                p.buf.writeByte(' ');\n            return 0;\n        }\n    }\n\n    void visitFuncIdentWithPostfix(TypeFunction t, const(char)* ident)\n    {\n        if (t.inuse)\n        {\n            t.inuse = 2; // flag error to caller\n            return;\n        }\n        t.inuse++;\n        PrePostAppendStrings pas;\n        pas.buf = buf;\n        pas.isCtor = false;\n        pas.isPostfixStyle = true;\n        if (t.linkage > LINK.d && hgs.ddoc != 1 && !hgs.hdrgen)\n        {\n            linkageToBuffer(buf, t.linkage);\n            buf.writeByte(' ');\n        }\n        if (t.next)\n        {\n            typeToBuffer(t.next, null);\n            if (ident)\n                buf.writeByte(' ');\n        }\n        else if (hgs.ddoc)\n            buf.writestring(\"auto \");\n        if (ident)\n            buf.writestring(ident);\n        parametersToBuffer(t.parameters, t.varargs);\n        /* Use postfix style for attributes\n         */\n        if (t.mod)\n        {\n            buf.writeByte(' ');\n            MODtoBuffer(buf, t.mod);\n        }\n        t.attributesApply(&pas, &PrePostAppendStrings.fp);\n        t.inuse--;\n    }\n\n    void visitFuncIdentWithPrefix(TypeFunction t, Identifier ident, TemplateDeclaration td)\n    {\n        if (t.inuse)\n        {\n            t.inuse = 2; // flag error to caller\n            return;\n        }\n        t.inuse++;\n        PrePostAppendStrings pas;\n        extern (D) static int ignoreReturn(void* param, string name)\n        {\n            if (name != \"return\")\n                PrePostAppendStrings.fp(param, name);\n            return 0;\n        }\n        pas.buf = buf;\n        pas.isCtor = (ident == Id.ctor);\n        pas.isPostfixStyle = false;\n        /* Use 'storage class' (prefix) style for attributes\n         */\n        if (t.mod)\n        {\n            MODtoBuffer(buf, t.mod);\n            buf.writeByte(' ');\n        }\n        t.attributesApply(&pas, &ignoreReturn);\n        if (t.linkage > LINK.d && hgs.ddoc != 1 && !hgs.hdrgen)\n        {\n            linkageToBuffer(buf, t.linkage);\n            buf.writeByte(' ');\n        }\n        if (ident && ident.toHChars2() != ident.toChars())\n        {\n            // Don't print return type for ctor, dtor, unittest, etc\n        }\n        else if (t.next)\n        {\n            typeToBuffer(t.next, null);\n            if (ident)\n                buf.writeByte(' ');\n        }\n        else if (hgs.ddoc)\n            buf.writestring(\"auto \");\n        if (ident)\n            buf.writestring(ident.toHChars2());\n        if (td)\n        {\n            buf.writeByte('(');\n            foreach (i, p; *td.origParameters)\n            {\n                if (i)\n                    buf.writestring(\", \");\n                p.accept(this);\n            }\n            buf.writeByte(')');\n        }\n        parametersToBuffer(t.parameters, t.varargs);\n        if (t.isreturn)\n        {\n            PrePostAppendStrings.fp(&pas, \" return\");\n            pas.buf.offset -= 1; // remove final whitespace\n        }\n        t.inuse--;\n    }\n\n    override void visit(TypeDelegate t)\n    {\n        visitFuncIdentWithPostfix(cast(TypeFunction)t.next, \"delegate\");\n    }\n\n    void visitTypeQualifiedHelper(TypeQualified t)\n    {\n        foreach (id; t.idents)\n        {\n            if (id.dyncast() == DYNCAST.dsymbol)\n            {\n                buf.writeByte('.');\n                TemplateInstance ti = cast(TemplateInstance)id;\n                ti.accept(this);\n            }\n            else if (id.dyncast() == DYNCAST.expression)\n            {\n                buf.writeByte('[');\n                (cast(Expression)id).accept(this);\n                buf.writeByte(']');\n            }\n            else if (id.dyncast() == DYNCAST.type)\n            {\n                buf.writeByte('[');\n                (cast(Type)id).accept(this);\n                buf.writeByte(']');\n            }\n            else\n            {\n                buf.writeByte('.');\n                buf.writestring(id.toChars());\n            }\n        }\n    }\n\n    override void visit(TypeIdentifier t)\n    {\n        buf.writestring(t.ident.toString());\n        visitTypeQualifiedHelper(t);\n    }\n\n    override void visit(TypeInstance t)\n    {\n        t.tempinst.accept(this);\n        visitTypeQualifiedHelper(t);\n    }\n\n    override void visit(TypeTypeof t)\n    {\n        buf.writestring(\"typeof(\");\n        t.exp.accept(this);\n        buf.writeByte(')');\n        visitTypeQualifiedHelper(t);\n    }\n\n    override void visit(TypeReturn t)\n    {\n        buf.writestring(\"typeof(return)\");\n        visitTypeQualifiedHelper(t);\n    }\n\n    override void visit(TypeEnum t)\n    {\n        buf.writestring(hgs.fullQual ? t.sym.toPrettyChars() : t.sym.toChars());\n    }\n\n    override void visit(TypeStruct t)\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=13776\n        // Don't use ti.toAlias() to avoid forward reference error\n        // while printing messages.\n        TemplateInstance ti = t.sym.parent ? t.sym.parent.isTemplateInstance() : null;\n        if (ti && ti.aliasdecl == t.sym)\n            buf.writestring(hgs.fullQual ? ti.toPrettyChars() : ti.toChars());\n        else\n            buf.writestring(hgs.fullQual ? t.sym.toPrettyChars() : t.sym.toChars());\n    }\n\n    override void visit(TypeClass t)\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=13776\n        // Don't use ti.toAlias() to avoid forward reference error\n        // while printing messages.\n        TemplateInstance ti = t.sym.parent.isTemplateInstance();\n        if (ti && ti.aliasdecl == t.sym)\n            buf.writestring(hgs.fullQual ? ti.toPrettyChars() : ti.toChars());\n        else\n            buf.writestring(hgs.fullQual ? t.sym.toPrettyChars() : t.sym.toChars());\n    }\n\n    override void visit(TypeTuple t)\n    {\n        parametersToBuffer(t.arguments, 0);\n    }\n\n    override void visit(TypeSlice t)\n    {\n        visitWithMask(t.next, t.mod);\n        buf.writeByte('[');\n        sizeToBuffer(t.lwr);\n        buf.writestring(\" .. \");\n        sizeToBuffer(t.upr);\n        buf.writeByte(']');\n    }\n\n    override void visit(TypeNull t)\n    {\n        buf.writestring(\"typeof(null)\");\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    override void visit(Dsymbol s)\n    {\n        buf.writestring(s.toChars());\n    }\n\n    override void visit(StaticAssert s)\n    {\n        buf.writestring(s.kind());\n        buf.writeByte('(');\n        s.exp.accept(this);\n        if (s.msg)\n        {\n            buf.writestring(\", \");\n            s.msg.accept(this);\n        }\n        buf.writestring(\");\");\n        buf.writenl();\n    }\n\n    override void visit(DebugSymbol s)\n    {\n        buf.writestring(\"debug = \");\n        if (s.ident)\n            buf.writestring(s.ident.toString());\n        else\n            buf.print(s.level);\n        buf.writeByte(';');\n        buf.writenl();\n    }\n\n    override void visit(VersionSymbol s)\n    {\n        buf.writestring(\"version = \");\n        if (s.ident)\n            buf.writestring(s.ident.toString());\n        else\n            buf.print(s.level);\n        buf.writeByte(';');\n        buf.writenl();\n    }\n\n    override void visit(EnumMember em)\n    {\n        if (em.type)\n            typeToBuffer(em.type, em.ident);\n        else\n            buf.writestring(em.ident.toString());\n        if (em.value)\n        {\n            buf.writestring(\" = \");\n            em.value.accept(this);\n        }\n    }\n\n    override void visit(Import imp)\n    {\n        if (hgs.hdrgen && imp.id == Id.object)\n            return; // object is imported by default\n        if (imp.isstatic)\n            buf.writestring(\"static \");\n        buf.writestring(\"import \");\n        if (imp.aliasId)\n        {\n            buf.printf(\"%s = \", imp.aliasId.toChars());\n        }\n        if (imp.packages && imp.packages.dim)\n        {\n            foreach (const pid; *imp.packages)\n            {\n                buf.printf(\"%s.\", pid.toChars());\n            }\n        }\n        buf.writestring(imp.id.toChars());\n        if (imp.names.dim)\n        {\n            buf.writestring(\" : \");\n            foreach (const i, const name; imp.names)\n            {\n                if (i)\n                    buf.writestring(\", \");\n                const _alias = imp.aliases[i];\n                if (_alias)\n                    buf.printf(\"%s = %s\", _alias.toChars(), name.toChars());\n                else\n                    buf.writestring(name.toChars());\n            }\n        }\n        buf.writeByte(';');\n        buf.writenl();\n    }\n\n    override void visit(AliasThis d)\n    {\n        buf.writestring(\"alias \");\n        buf.writestring(d.ident.toString());\n        buf.writestring(\" this;\\n\");\n    }\n\n    override void visit(AttribDeclaration d)\n    {\n        if (!d.decl)\n        {\n            buf.writeByte(';');\n            buf.writenl();\n            return;\n        }\n        if (d.decl.dim == 0)\n            buf.writestring(\"{}\");\n        else if (hgs.hdrgen && d.decl.dim == 1 && (*d.decl)[0].isUnitTestDeclaration())\n        {\n            // hack for bugzilla 8081\n            buf.writestring(\"{}\");\n        }\n        else if (d.decl.dim == 1)\n        {\n            (*d.decl)[0].accept(this);\n            return;\n        }\n        else\n        {\n            buf.writenl();\n            buf.writeByte('{');\n            buf.writenl();\n            buf.level++;\n            foreach (de; *d.decl)\n                de.accept(this);\n            buf.level--;\n            buf.writeByte('}');\n        }\n        buf.writenl();\n    }\n\n    override void visit(StorageClassDeclaration d)\n    {\n        if (stcToBuffer(buf, d.stc))\n            buf.writeByte(' ');\n        visit(cast(AttribDeclaration)d);\n    }\n\n    override void visit(DeprecatedDeclaration d)\n    {\n        buf.writestring(\"deprecated(\");\n        d.msg.accept(this);\n        buf.writestring(\") \");\n        visit(cast(AttribDeclaration)d);\n    }\n\n    override void visit(LinkDeclaration d)\n    {\n        const(char)* p;\n        final switch (d.linkage)\n        {\n        case LINK.d:\n            p = \"D\";\n            break;\n        case LINK.c:\n            p = \"C\";\n            break;\n        case LINK.cpp:\n            p = \"C++\";\n            break;\n        case LINK.windows:\n            p = \"Windows\";\n            break;\n        case LINK.pascal:\n            p = \"Pascal\";\n            break;\n        case LINK.objc:\n            p = \"Objective-C\";\n            break;\n        case LINK.default_:\n        case LINK.system:\n            assert(0);\n        }\n        buf.writestring(\"extern (\");\n        buf.writestring(p);\n        buf.writestring(\") \");\n        visit(cast(AttribDeclaration)d);\n    }\n\n    override void visit(CPPMangleDeclaration d)\n    {\n        const(char)* p;\n        final switch (d.cppmangle)\n        {\n        case CPPMANGLE.asClass:\n            p = \"class\";\n            break;\n        case CPPMANGLE.asStruct:\n            p = \"struct\";\n            break;\n        case CPPMANGLE.def:\n            break;\n        }\n        buf.writestring(\"extern (C++, \");\n        buf.writestring(p);\n        buf.writestring(\") \");\n        visit(cast(AttribDeclaration)d);\n    }\n\n    override void visit(ProtDeclaration d)\n    {\n        protectionToBuffer(buf, d.protection);\n        buf.writeByte(' ');\n        AttribDeclaration ad = cast(AttribDeclaration)d;\n        if (ad.decl.dim == 1 && (*ad.decl)[0].isProtDeclaration)\n            visit(cast(AttribDeclaration)(*ad.decl)[0]);\n        else\n            visit(cast(AttribDeclaration)d);\n    }\n\n    override void visit(AlignDeclaration d)\n    {\n        if (!d.ealign)\n            buf.writestring(\"align \");\n        else\n            buf.printf(\"align (%s) \", d.ealign.toChars());\n        visit(cast(AttribDeclaration)d);\n    }\n\n    override void visit(AnonDeclaration d)\n    {\n        buf.writestring(d.isunion ? \"union\" : \"struct\");\n        buf.writenl();\n        buf.writestring(\"{\");\n        buf.writenl();\n        buf.level++;\n        if (d.decl)\n        {\n            foreach (de; *d.decl)\n                de.accept(this);\n        }\n        buf.level--;\n        buf.writestring(\"}\");\n        buf.writenl();\n    }\n\n    override void visit(PragmaDeclaration d)\n    {\n        buf.writestring(\"pragma (\");\n        buf.writestring(d.ident.toString());\n        if (d.args && d.args.dim)\n        {\n            buf.writestring(\", \");\n            argsToBuffer(d.args);\n        }\n        buf.writeByte(')');\n        visit(cast(AttribDeclaration)d);\n    }\n\n    override void visit(ConditionalDeclaration d)\n    {\n        d.condition.accept(this);\n        if (d.decl || d.elsedecl)\n        {\n            buf.writenl();\n            buf.writeByte('{');\n            buf.writenl();\n            buf.level++;\n            if (d.decl)\n            {\n                foreach (de; *d.decl)\n                    de.accept(this);\n            }\n            buf.level--;\n            buf.writeByte('}');\n            if (d.elsedecl)\n            {\n                buf.writenl();\n                buf.writestring(\"else\");\n                buf.writenl();\n                buf.writeByte('{');\n                buf.writenl();\n                buf.level++;\n                foreach (de; *d.elsedecl)\n                    de.accept(this);\n                buf.level--;\n                buf.writeByte('}');\n            }\n        }\n        else\n            buf.writeByte(':');\n        buf.writenl();\n    }\n\n    override void visit(StaticForeachDeclaration s)\n    {\n        buf.writestring(\"static \");\n        if (s.sfe.aggrfe)\n        {\n            visitWithoutBody(s.sfe.aggrfe);\n        }\n        else\n        {\n            assert(s.sfe.rangefe);\n            visitWithoutBody(s.sfe.rangefe);\n        }\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n        visit(cast(AttribDeclaration)s);\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n\n    }\n\n    override void visit(CompileDeclaration d)\n    {\n        buf.writestring(\"mixin(\");\n        argsToBuffer(d.exps, null);\n        buf.writestring(\");\");\n        buf.writenl();\n    }\n\n    override void visit(UserAttributeDeclaration d)\n    {\n        buf.writestring(\"@(\");\n        argsToBuffer(d.atts);\n        buf.writeByte(')');\n        visit(cast(AttribDeclaration)d);\n    }\n\n    override void visit(TemplateDeclaration d)\n    {\n        version (none)\n        {\n            // Should handle template functions for doc generation\n            if (onemember && onemember.isFuncDeclaration())\n                buf.writestring(\"foo \");\n        }\n        if ((hgs.hdrgen || hgs.fullDump) && visitEponymousMember(d))\n            return;\n        if (hgs.ddoc)\n            buf.writestring(d.kind());\n        else\n            buf.writestring(\"template\");\n        buf.writeByte(' ');\n        buf.writestring(d.ident.toString());\n        buf.writeByte('(');\n        visitTemplateParameters(hgs.ddoc ? d.origParameters : d.parameters);\n        buf.writeByte(')');\n        visitTemplateConstraint(d.constraint);\n        if (hgs.hdrgen || hgs.fullDump)\n        {\n            hgs.tpltMember++;\n            buf.writenl();\n            buf.writeByte('{');\n            buf.writenl();\n            buf.level++;\n            foreach (s; *d.members)\n                s.accept(this);\n            buf.level--;\n            buf.writeByte('}');\n            buf.writenl();\n            hgs.tpltMember--;\n        }\n    }\n\n    bool visitEponymousMember(TemplateDeclaration d)\n    {\n        if (!d.members || d.members.dim != 1)\n            return false;\n        Dsymbol onemember = (*d.members)[0];\n        if (onemember.ident != d.ident)\n            return false;\n        if (FuncDeclaration fd = onemember.isFuncDeclaration())\n        {\n            assert(fd.type);\n            if (stcToBuffer(buf, fd.storage_class))\n                buf.writeByte(' ');\n            functionToBufferFull(cast(TypeFunction)fd.type, buf, d.ident, hgs, d);\n            visitTemplateConstraint(d.constraint);\n            hgs.tpltMember++;\n            bodyToBuffer(fd);\n            hgs.tpltMember--;\n            return true;\n        }\n        if (AggregateDeclaration ad = onemember.isAggregateDeclaration())\n        {\n            buf.writestring(ad.kind());\n            buf.writeByte(' ');\n            buf.writestring(ad.ident.toString());\n            buf.writeByte('(');\n            visitTemplateParameters(hgs.ddoc ? d.origParameters : d.parameters);\n            buf.writeByte(')');\n            visitTemplateConstraint(d.constraint);\n            visitBaseClasses(ad.isClassDeclaration());\n            hgs.tpltMember++;\n            if (ad.members)\n            {\n                buf.writenl();\n                buf.writeByte('{');\n                buf.writenl();\n                buf.level++;\n                foreach (s; *ad.members)\n                    s.accept(this);\n                buf.level--;\n                buf.writeByte('}');\n            }\n            else\n                buf.writeByte(';');\n            buf.writenl();\n            hgs.tpltMember--;\n            return true;\n        }\n        if (VarDeclaration vd = onemember.isVarDeclaration())\n        {\n            if (d.constraint)\n                return false;\n            if (stcToBuffer(buf, vd.storage_class))\n                buf.writeByte(' ');\n            if (vd.type)\n                typeToBuffer(vd.type, vd.ident);\n            else\n                buf.writestring(vd.ident.toString());\n            buf.writeByte('(');\n            visitTemplateParameters(hgs.ddoc ? d.origParameters : d.parameters);\n            buf.writeByte(')');\n            if (vd._init)\n            {\n                buf.writestring(\" = \");\n                ExpInitializer ie = vd._init.isExpInitializer();\n                if (ie && (ie.exp.op == TOK.construct || ie.exp.op == TOK.blit))\n                    (cast(AssignExp)ie.exp).e2.accept(this);\n                else\n                    vd._init.accept(this);\n            }\n            buf.writeByte(';');\n            buf.writenl();\n            return true;\n        }\n        return false;\n    }\n\n    void visitTemplateParameters(TemplateParameters* parameters)\n    {\n        if (!parameters || !parameters.dim)\n            return;\n        foreach (i, p; *parameters)\n        {\n            if (i)\n                buf.writestring(\", \");\n            p.accept(this);\n        }\n    }\n\n    void visitTemplateConstraint(Expression constraint)\n    {\n        if (!constraint)\n            return;\n        buf.writestring(\" if (\");\n        constraint.accept(this);\n        buf.writeByte(')');\n    }\n\n    override void visit(TemplateInstance ti)\n    {\n        buf.writestring(ti.name.toChars());\n        tiargsToBuffer(ti);\n\n        if (hgs.fullDump)\n        {\n            buf.writenl();\n            dumpTemplateInstance(ti);\n        }\n    }\n\n    override void visit(TemplateMixin tm)\n    {\n        buf.writestring(\"mixin \");\n        typeToBuffer(tm.tqual, null);\n        tiargsToBuffer(tm);\n        if (tm.ident && memcmp(tm.ident.toChars(), cast(const(char)*)\"__mixin\", 7) != 0)\n        {\n            buf.writeByte(' ');\n            buf.writestring(tm.ident.toString());\n        }\n        buf.writeByte(';');\n        buf.writenl();\n        if (hgs.fullDump)\n            dumpTemplateInstance(tm);\n    }\n\n    void dumpTemplateInstance(TemplateInstance ti)\n    {\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n\n        if (ti.aliasdecl)\n        {\n            ti.aliasdecl.accept(this);\n            buf.writenl();\n        }\n        else if (ti.members)\n        {\n            foreach(m;*ti.members)\n                m.accept(this);\n        }\n\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n\n    }\n\n    void tiargsToBuffer(TemplateInstance ti)\n    {\n        buf.writeByte('!');\n        if (ti.nest)\n        {\n            buf.writestring(\"(...)\");\n            return;\n        }\n        if (!ti.tiargs)\n        {\n            buf.writestring(\"()\");\n            return;\n        }\n        if (ti.tiargs.dim == 1)\n        {\n            RootObject oarg = (*ti.tiargs)[0];\n            if (Type t = isType(oarg))\n            {\n                if (t.equals(Type.tstring) || t.equals(Type.twstring) || t.equals(Type.tdstring) || t.mod == 0 && (t.isTypeBasic() || t.ty == Tident && (cast(TypeIdentifier)t).idents.dim == 0))\n                {\n                    buf.writestring(t.toChars());\n                    return;\n                }\n            }\n            else if (Expression e = isExpression(oarg))\n            {\n                if (e.op == TOK.int64 || e.op == TOK.float64 || e.op == TOK.null_ || e.op == TOK.string_ || e.op == TOK.this_)\n                {\n                    buf.writestring(e.toChars());\n                    return;\n                }\n            }\n        }\n        buf.writeByte('(');\n        ti.nest++;\n        foreach (i, arg; *ti.tiargs)\n        {\n            if (i)\n                buf.writestring(\", \");\n            objectToBuffer(arg);\n        }\n        ti.nest--;\n        buf.writeByte(')');\n    }\n\n    /****************************************\n     * This makes a 'pretty' version of the template arguments.\n     * It's analogous to genIdent() which makes a mangled version.\n     */\n    void objectToBuffer(RootObject oarg)\n    {\n        //printf(\"objectToBuffer()\\n\");\n        /* The logic of this should match what genIdent() does. The _dynamic_cast()\n         * function relies on all the pretty strings to be unique for different classes\n         * See https://issues.dlang.org/show_bug.cgi?id=7375\n         * Perhaps it would be better to demangle what genIdent() does.\n         */\n        if (auto t = isType(oarg))\n        {\n            //printf(\"\\tt: %s ty = %d\\n\", t.toChars(), t.ty);\n            typeToBuffer(t, null);\n        }\n        else if (auto e = isExpression(oarg))\n        {\n            if (e.op == TOK.variable)\n                e = e.optimize(WANTvalue); // added to fix https://issues.dlang.org/show_bug.cgi?id=7375\n            e.accept(this);\n        }\n        else if (Dsymbol s = isDsymbol(oarg))\n        {\n            const p = s.ident ? s.ident.toChars() : s.toChars();\n            buf.writestring(p);\n        }\n        else if (auto v = isTuple(oarg))\n        {\n            auto args = &v.objects;\n            foreach (i, arg; *args)\n            {\n                if (i)\n                    buf.writestring(\", \");\n                objectToBuffer(arg);\n            }\n        }\n        else if (!oarg)\n        {\n            buf.writestring(\"NULL\");\n        }\n        else\n        {\n            debug\n            {\n                printf(\"bad Object = %p\\n\", oarg);\n            }\n            assert(0);\n        }\n    }\n\n    override void visit(EnumDeclaration d)\n    {\n        auto oldInEnumDecl = inEnumDecl;\n        scope(exit) inEnumDecl = oldInEnumDecl;\n        inEnumDecl = d;\n        buf.writestring(\"enum \");\n        if (d.ident)\n        {\n            buf.writestring(d.ident.toString());\n            buf.writeByte(' ');\n        }\n        if (d.memtype)\n        {\n            buf.writestring(\": \");\n            typeToBuffer(d.memtype, null);\n        }\n        if (!d.members)\n        {\n            buf.writeByte(';');\n            buf.writenl();\n            return;\n        }\n        buf.writenl();\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n        foreach (em; *d.members)\n        {\n            if (!em)\n                continue;\n            em.accept(this);\n            buf.writeByte(',');\n            buf.writenl();\n        }\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n    }\n\n    override void visit(Nspace d)\n    {\n        buf.writestring(\"extern (C++, \");\n        buf.writestring(d.ident.toString());\n        buf.writeByte(')');\n        buf.writenl();\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n        foreach (s; *d.members)\n            s.accept(this);\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n    }\n\n    override void visit(StructDeclaration d)\n    {\n        buf.writestring(d.kind());\n        buf.writeByte(' ');\n        if (!d.isAnonymous())\n            buf.writestring(d.toChars());\n        if (!d.members)\n        {\n            buf.writeByte(';');\n            buf.writenl();\n            return;\n        }\n        buf.writenl();\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n        foreach (s; *d.members)\n            s.accept(this);\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n    }\n\n    override void visit(ClassDeclaration d)\n    {\n        if (!d.isAnonymous())\n        {\n            buf.writestring(d.kind());\n            buf.writeByte(' ');\n            buf.writestring(d.ident.toString());\n        }\n        visitBaseClasses(d);\n        if (d.members)\n        {\n            buf.writenl();\n            buf.writeByte('{');\n            buf.writenl();\n            buf.level++;\n            foreach (s; *d.members)\n                s.accept(this);\n            buf.level--;\n            buf.writeByte('}');\n        }\n        else\n            buf.writeByte(';');\n        buf.writenl();\n    }\n\n    void visitBaseClasses(ClassDeclaration d)\n    {\n        if (!d || !d.baseclasses.dim)\n            return;\n        if (!d.isAnonymous())\n            buf.writestring(\" : \");\n        foreach (i, b; *d.baseclasses)\n        {\n            if (i)\n                buf.writestring(\", \");\n            typeToBuffer(b.type, null);\n        }\n    }\n\n    override void visit(AliasDeclaration d)\n    {\n        if (d.storage_class & STC.local)\n            return;\n        buf.writestring(\"alias \");\n        if (d.aliassym)\n        {\n            buf.writestring(d.ident.toString());\n            buf.writestring(\" = \");\n            if (stcToBuffer(buf, d.storage_class))\n                buf.writeByte(' ');\n            d.aliassym.accept(this);\n        }\n        else if (d.type.ty == Tfunction)\n        {\n            if (stcToBuffer(buf, d.storage_class))\n                buf.writeByte(' ');\n            typeToBuffer(d.type, d.ident);\n        }\n        else\n        {\n            declstring = (d.ident == Id.string || d.ident == Id.wstring || d.ident == Id.dstring);\n            buf.writestring(d.ident.toString());\n            buf.writestring(\" = \");\n            if (stcToBuffer(buf, d.storage_class))\n                buf.writeByte(' ');\n            typeToBuffer(d.type, null);\n            declstring = false;\n        }\n        buf.writeByte(';');\n        buf.writenl();\n    }\n\n    override void visit(VarDeclaration d)\n    {\n        if (d.storage_class & STC.local)\n            return;\n        visitVarDecl(d, false);\n        buf.writeByte(';');\n        buf.writenl();\n    }\n\n    void visitVarDecl(VarDeclaration v, bool anywritten)\n    {\n        if (anywritten)\n        {\n            buf.writestring(\", \");\n            buf.writestring(v.ident.toString());\n        }\n        else\n        {\n            if (stcToBuffer(buf, v.storage_class))\n                buf.writeByte(' ');\n            if (v.type)\n                typeToBuffer(v.type, v.ident);\n            else\n                buf.writestring(v.ident.toString());\n        }\n        if (v._init)\n        {\n            buf.writestring(\" = \");\n            auto ie = v._init.isExpInitializer();\n            if (ie && (ie.exp.op == TOK.construct || ie.exp.op == TOK.blit))\n                (cast(AssignExp)ie.exp).e2.accept(this);\n            else\n                v._init.accept(this);\n        }\n    }\n\n    override void visit(FuncDeclaration f)\n    {\n        //printf(\"FuncDeclaration::toCBuffer() '%s'\\n\", f.toChars());\n        if (stcToBuffer(buf, f.storage_class))\n            buf.writeByte(' ');\n        auto tf = cast(TypeFunction)f.type;\n        typeToBuffer(tf, f.ident);\n\n        if (hgs.hdrgen)\n        {\n            // if the return type is missing (e.g. ref functions or auto)\n            if (!tf.next || f.storage_class & STC.auto_)\n            {\n                hgs.autoMember++;\n                bodyToBuffer(f);\n                hgs.autoMember--;\n            }\n            else if (hgs.tpltMember == 0 && global.params.hdrStripPlainFunctions)\n            {\n                buf.writeByte(';');\n                buf.writenl();\n            }\n            else\n                bodyToBuffer(f);\n        }\n        else\n            bodyToBuffer(f);\n    }\n\n    void bodyToBuffer(FuncDeclaration f)\n    {\n        if (!f.fbody || (hgs.hdrgen && global.params.hdrStripPlainFunctions && !hgs.autoMember && !hgs.tpltMember))\n        {\n            buf.writeByte(';');\n            buf.writenl();\n            return;\n        }\n        int savetlpt = hgs.tpltMember;\n        int saveauto = hgs.autoMember;\n        hgs.tpltMember = 0;\n        hgs.autoMember = 0;\n        buf.writenl();\n        bool requireDo = false;\n        // in{}\n        if (f.frequires)\n        {\n            foreach (frequire; *f.frequires)\n            {\n                buf.writestring(\"in\");\n                if (auto es = frequire.isExpStatement())\n                {\n                    assert(es.exp && es.exp.op == TOK.assert_);\n                    buf.writestring(\" (\");\n                    (cast(AssertExp)es.exp).e1.accept(this);\n                    buf.writeByte(')');\n                    buf.writenl();\n                    requireDo = false;\n                }\n                else\n                {\n                    buf.writenl();\n                    frequire.accept(this);\n                    requireDo = true;\n                }\n            }\n        }\n        // out{}\n        if (f.fensures)\n        {\n            foreach (fensure; *f.fensures)\n            {\n                buf.writestring(\"out\");\n                if (auto es = fensure.ensure.isExpStatement())\n                {\n                    assert(es.exp && es.exp.op == TOK.assert_);\n                    buf.writestring(\" (\");\n                    if (fensure.id)\n                    {\n                        buf.writestring(fensure.id.toChars());\n                    }\n                    buf.writestring(\"; \");\n                    (cast(AssertExp)es.exp).e1.accept(this);\n                    buf.writeByte(')');\n                    buf.writenl();\n                    requireDo = false;\n                }\n                else\n                {\n                    if (fensure.id)\n                    {\n                        buf.writeByte('(');\n                        buf.writestring(fensure.id.toChars());\n                        buf.writeByte(')');\n                    }\n                    buf.writenl();\n                    fensure.ensure.accept(this);\n                    requireDo = true;\n                }\n            }\n        }\n        if (requireDo)\n        {\n            buf.writestring(\"do\");\n            buf.writenl();\n        }\n        buf.writeByte('{');\n        buf.writenl();\n        buf.level++;\n        f.fbody.accept(this);\n        buf.level--;\n        buf.writeByte('}');\n        buf.writenl();\n        hgs.tpltMember = savetlpt;\n        hgs.autoMember = saveauto;\n    }\n\n    override void visit(FuncLiteralDeclaration f)\n    {\n        if (f.type.ty == Terror)\n        {\n            buf.writestring(\"__error\");\n            return;\n        }\n        if (f.tok != TOK.reserved)\n        {\n            buf.writestring(f.kind());\n            buf.writeByte(' ');\n        }\n        TypeFunction tf = cast(TypeFunction)f.type;\n        // Don't print tf.mod, tf.trust, and tf.linkage\n        if (!f.inferRetType && tf.next)\n            typeToBuffer(tf.next, null);\n        parametersToBuffer(tf.parameters, tf.varargs);\n        CompoundStatement cs = f.fbody.isCompoundStatement();\n        Statement s1;\n        if (f.semanticRun >= PASS.semantic3done && cs)\n        {\n            s1 = (*cs.statements)[cs.statements.dim - 1];\n        }\n        else\n            s1 = !cs ? f.fbody : null;\n        ReturnStatement rs = s1 ? s1.isReturnStatement() : null;\n        if (rs && rs.exp)\n        {\n            buf.writestring(\" => \");\n            rs.exp.accept(this);\n        }\n        else\n        {\n            hgs.tpltMember++;\n            bodyToBuffer(f);\n            hgs.tpltMember--;\n        }\n    }\n\n    override void visit(PostBlitDeclaration d)\n    {\n        if (stcToBuffer(buf, d.storage_class))\n            buf.writeByte(' ');\n        buf.writestring(\"this(this)\");\n        bodyToBuffer(d);\n    }\n\n    override void visit(DtorDeclaration d)\n    {\n        if (d.storage_class & STC.trusted)\n            buf.writestring(\"@trusted \");\n        if (d.storage_class & STC.safe)\n            buf.writestring(\"@safe \");\n        if (d.storage_class & STC.nogc)\n            buf.writestring(\"@nogc \");\n        if (d.storage_class & STC.disable)\n            buf.writestring(\"@disable \");\n\n        buf.writestring(\"~this()\");\n        bodyToBuffer(d);\n    }\n\n    override void visit(StaticCtorDeclaration d)\n    {\n        if (stcToBuffer(buf, d.storage_class & ~STC.static_))\n            buf.writeByte(' ');\n        if (d.isSharedStaticCtorDeclaration())\n            buf.writestring(\"shared \");\n        buf.writestring(\"static this()\");\n        if (hgs.hdrgen && !hgs.tpltMember)\n        {\n            buf.writeByte(';');\n            buf.writenl();\n        }\n        else\n            bodyToBuffer(d);\n    }\n\n    override void visit(StaticDtorDeclaration d)\n    {\n        if (stcToBuffer(buf, d.storage_class & ~STC.static_))\n            buf.writeByte(' ');\n        if (d.isSharedStaticDtorDeclaration())\n            buf.writestring(\"shared \");\n        buf.writestring(\"static ~this()\");\n        if (hgs.hdrgen && !hgs.tpltMember)\n        {\n            buf.writeByte(';');\n            buf.writenl();\n        }\n        else\n            bodyToBuffer(d);\n    }\n\n    override void visit(InvariantDeclaration d)\n    {\n        if (hgs.hdrgen)\n            return;\n        if (stcToBuffer(buf, d.storage_class))\n            buf.writeByte(' ');\n        buf.writestring(\"invariant\");\n        if(auto es = d.fbody.isExpStatement())\n        {\n            assert(es.exp && es.exp.op == TOK.assert_);\n            buf.writestring(\" (\");\n            (cast(AssertExp)es.exp).e1.accept(this);\n            buf.writestring(\");\");\n            buf.writenl();\n        }\n        else\n        {\n            bodyToBuffer(d);\n        }\n    }\n\n    override void visit(UnitTestDeclaration d)\n    {\n        if (hgs.hdrgen)\n            return;\n        if (stcToBuffer(buf, d.storage_class))\n            buf.writeByte(' ');\n        buf.writestring(\"unittest\");\n        bodyToBuffer(d);\n    }\n\n    override void visit(NewDeclaration d)\n    {\n        if (stcToBuffer(buf, d.storage_class & ~STC.static_))\n            buf.writeByte(' ');\n        buf.writestring(\"new\");\n        parametersToBuffer(d.parameters, d.varargs);\n        bodyToBuffer(d);\n    }\n\n    override void visit(DeleteDeclaration d)\n    {\n        if (stcToBuffer(buf, d.storage_class & ~STC.static_))\n            buf.writeByte(' ');\n        buf.writestring(\"delete\");\n        parametersToBuffer(d.parameters, 0);\n        bodyToBuffer(d);\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    override void visit(ErrorInitializer iz)\n    {\n        buf.writestring(\"__error__\");\n    }\n\n    override void visit(VoidInitializer iz)\n    {\n        buf.writestring(\"void\");\n    }\n\n    override void visit(StructInitializer si)\n    {\n        //printf(\"StructInitializer::toCBuffer()\\n\");\n        buf.writeByte('{');\n        foreach (i, const id; si.field)\n        {\n            if (i)\n                buf.writestring(\", \");\n            if (id)\n            {\n                buf.writestring(id.toChars());\n                buf.writeByte(':');\n            }\n            if (auto iz = si.value[i])\n                iz.accept(this);\n        }\n        buf.writeByte('}');\n    }\n\n    override void visit(ArrayInitializer ai)\n    {\n        buf.writeByte('[');\n        foreach (i, ex; ai.index)\n        {\n            if (i)\n                buf.writestring(\", \");\n            if (ex)\n            {\n                ex.accept(this);\n                buf.writeByte(':');\n            }\n            if (auto iz = ai.value[i])\n                iz.accept(this);\n        }\n        buf.writeByte(']');\n    }\n\n    override void visit(ExpInitializer ei)\n    {\n        ei.exp.accept(this);\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    /**************************************************\n     * Write out argument list to buf.\n     */\n    void argsToBuffer(Expressions* expressions, Expression basis = null)\n    {\n        if (!expressions || !expressions.dim)\n            return;\n        version (all)\n        {\n            foreach (i, el; *expressions)\n            {\n                if (i)\n                    buf.writestring(\", \");\n                if (!el)\n                    el = basis;\n                if (el)\n                    expToBuffer(el, PREC.assign);\n            }\n        }\n        else\n        {\n            // Sparse style formatting, for debug use only\n            //      [0..dim: basis, 1: e1, 5: e5]\n            if (basis)\n            {\n                buf.writestring(\"0..\");\n                buf.print(expressions.dim);\n                buf.writestring(\": \");\n                expToBuffer(basis, PREC.assign);\n            }\n            foreach (i, el; *expressions)\n            {\n                if (el)\n                {\n                    if (basis)\n                    {\n                        buf.writestring(\", \");\n                        buf.print(i);\n                        buf.writestring(\": \");\n                    }\n                    else if (i)\n                        buf.writestring(\", \");\n                    expToBuffer(el, PREC.assign);\n                }\n            }\n        }\n    }\n\n    void sizeToBuffer(Expression e)\n    {\n        if (e.type == Type.tsize_t)\n        {\n            Expression ex = (e.op == TOK.cast_ ? (cast(CastExp)e).e1 : e);\n            ex = ex.optimize(WANTvalue);\n            dinteger_t uval = ex.op == TOK.int64 ? ex.toInteger() : cast(dinteger_t)-1;\n            if (cast(sinteger_t)uval >= 0)\n            {\n                dinteger_t sizemax;\n                if (Target.ptrsize == 4)\n                    sizemax = 0xFFFFFFFFU;\n                else if (Target.ptrsize == 8)\n                    sizemax = 0xFFFFFFFFFFFFFFFFUL;\n                else\n                    assert(0);\n                if (uval <= sizemax && uval <= 0x7FFFFFFFFFFFFFFFUL)\n                {\n                    buf.print(uval);\n                    return;\n                }\n            }\n        }\n        expToBuffer(e, PREC.assign);\n    }\n\n    /**************************************************\n     * Write expression out to buf, but wrap it\n     * in ( ) if its precedence is less than pr.\n     */\n    void expToBuffer(Expression e, PREC pr)\n    {\n        debug\n        {\n            if (precedence[e.op] == PREC.zero)\n                printf(\"precedence not defined for token '%s'\\n\", Token.toChars(e.op));\n        }\n        assert(precedence[e.op] != PREC.zero);\n        assert(pr != PREC.zero);\n        /* Despite precedence, we don't allow a<b<c expressions.\n         * They must be parenthesized.\n         */\n        if (precedence[e.op] < pr || (pr == PREC.rel && precedence[e.op] == pr)\n            || (pr >= PREC.or && pr <= PREC.and && precedence[e.op] == PREC.rel))\n        {\n            buf.writeByte('(');\n            e.accept(this);\n            buf.writeByte(')');\n        }\n        else\n            e.accept(this);\n    }\n\n    override void visit(Expression e)\n    {\n        buf.writestring(Token.toString(e.op));\n    }\n\n    override void visit(IntegerExp e)\n    {\n        dinteger_t v = e.toInteger();\n        if (e.type)\n        {\n            Type t = e.type;\n        L1:\n            switch (t.ty)\n            {\n            case Tenum:\n                {\n                    TypeEnum te = cast(TypeEnum)t;\n                    if (hgs.fullDump)\n                    {\n                        auto sym = te.sym;\n                        if (inEnumDecl != sym)  foreach(i;0 .. sym.members.dim)\n                        {\n                            EnumMember em = cast(EnumMember) (*sym.members)[i];\n                            if (em.value.toInteger == v)\n                            {\n                                buf.printf(\"%s.%s\", sym.toChars(), em.ident.toChars());\n                                return ;\n                            }\n                        }\n                        //assert(0, \"We could not find the EmumMember\");// for some reason it won't append char* ~ e.toChars() ~ \" in \" ~ sym.toChars() );\n                    }\n\n                    buf.printf(\"cast(%s)\", te.sym.toChars());\n                    t = te.sym.memtype;\n                    goto L1;\n                }\n            case Twchar:\n                // BUG: need to cast(wchar)\n            case Tdchar:\n                // BUG: need to cast(dchar)\n                if (cast(uinteger_t)v > 0xFF)\n                {\n                    buf.printf(\"'\\\\U%08x'\", v);\n                    break;\n                }\n                goto case;\n            case Tchar:\n                {\n                    size_t o = buf.offset;\n                    if (v == '\\'')\n                        buf.writestring(\"'\\\\''\");\n                    else if (isprint(cast(int)v) && v != '\\\\')\n                        buf.printf(\"'%c'\", cast(int)v);\n                    else\n                        buf.printf(\"'\\\\x%02x'\", cast(int)v);\n                    if (hgs.ddoc)\n                        escapeDdocString(buf, o);\n                    break;\n                }\n            case Tint8:\n                buf.writestring(\"cast(byte)\");\n                goto L2;\n            case Tint16:\n                buf.writestring(\"cast(short)\");\n                goto L2;\n            case Tint32:\n            L2:\n                buf.printf(\"%d\", cast(int)v);\n                break;\n            case Tuns8:\n                buf.writestring(\"cast(ubyte)\");\n                goto L3;\n            case Tuns16:\n                buf.writestring(\"cast(ushort)\");\n                goto L3;\n            case Tuns32:\n            L3:\n                buf.printf(\"%uu\", cast(uint)v);\n                break;\n            case Tint64:\n                buf.printf(\"%lldL\", v);\n                break;\n            case Tuns64:\n            L4:\n                buf.printf(\"%lluLU\", v);\n                break;\n            case Tbool:\n                buf.writestring(v ? \"true\" : \"false\");\n                break;\n            case Tpointer:\n                buf.writestring(\"cast(\");\n                buf.writestring(t.toChars());\n                buf.writeByte(')');\n                if (Target.ptrsize == 4)\n                    goto L3;\n                else if (Target.ptrsize == 8)\n                    goto L4;\n                else\n                    assert(0);\n            default:\n                /* This can happen if errors, such as\n                 * the type is painted on like in fromConstInitializer().\n                 */\n                if (!global.errors)\n                {\n                    assert(0);\n                }\n                break;\n            }\n        }\n        else if (v & 0x8000000000000000L)\n            buf.printf(\"0x%llx\", v);\n        else\n            buf.print(v);\n    }\n\n    override void visit(ErrorExp e)\n    {\n        buf.writestring(\"__error\");\n    }\n\n    override void visit(VoidInitExp e)\n    {\n        buf.writestring(\"__void\");\n    }\n\n    void floatToBuffer(Type type, real_t value)\n    {\n        /** sizeof(value)*3 is because each byte of mantissa is max\n         of 256 (3 characters). The string will be \"-M.MMMMe-4932\".\n         (ie, 8 chars more than mantissa). Plus one for trailing \\0.\n         Plus one for rounding. */\n        const(size_t) BUFFER_LEN = value.sizeof * 3 + 8 + 1 + 1;\n        char[BUFFER_LEN] buffer;\n        CTFloat.sprint(buffer.ptr, 'g', value);\n        assert(strlen(buffer.ptr) < BUFFER_LEN);\n        if (hgs.hdrgen)\n        {\n            real_t r = CTFloat.parse(buffer.ptr);\n            if (r != value) // if exact duplication\n                CTFloat.sprint(buffer.ptr, 'a', value);\n        }\n        buf.writestring(buffer.ptr);\n        if (type)\n        {\n            Type t = type.toBasetype();\n            switch (t.ty)\n            {\n            case Tfloat32:\n            case Timaginary32:\n            case Tcomplex32:\n                buf.writeByte('F');\n                break;\n            case Tfloat80:\n            case Timaginary80:\n            case Tcomplex80:\n                buf.writeByte('L');\n                break;\n            default:\n                break;\n            }\n            if (t.isimaginary())\n                buf.writeByte('i');\n        }\n    }\n\n    override void visit(RealExp e)\n    {\n        floatToBuffer(e.type, e.value);\n    }\n\n    override void visit(ComplexExp e)\n    {\n        /* Print as:\n         *  (re+imi)\n         */\n        buf.writeByte('(');\n        floatToBuffer(e.type, creall(e.value));\n        buf.writeByte('+');\n        floatToBuffer(e.type, cimagl(e.value));\n        buf.writestring(\"i)\");\n    }\n\n    override void visit(IdentifierExp e)\n    {\n        if (hgs.hdrgen || hgs.ddoc)\n            buf.writestring(e.ident.toHChars2());\n        else\n            buf.writestring(e.ident.toString());\n    }\n\n    override void visit(DsymbolExp e)\n    {\n        buf.writestring(e.s.toChars());\n    }\n\n    override void visit(ThisExp e)\n    {\n        buf.writestring(\"this\");\n    }\n\n    override void visit(SuperExp e)\n    {\n        buf.writestring(\"super\");\n    }\n\n    override void visit(NullExp e)\n    {\n        buf.writestring(\"null\");\n    }\n\n    override void visit(StringExp e)\n    {\n        buf.writeByte('\"');\n        size_t o = buf.offset;\n        for (size_t i = 0; i < e.len; i++)\n        {\n            uint c = e.charAt(i);\n            switch (c)\n            {\n            case '\"':\n            case '\\\\':\n                buf.writeByte('\\\\');\n                goto default;\n            default:\n                if (c <= 0xFF)\n                {\n                    if (c <= 0x7F && isprint(c))\n                        buf.writeByte(c);\n                    else\n                        buf.printf(\"\\\\x%02x\", c);\n                }\n                else if (c <= 0xFFFF)\n                    buf.printf(\"\\\\x%02x\\\\x%02x\", c & 0xFF, c >> 8);\n                else\n                    buf.printf(\"\\\\x%02x\\\\x%02x\\\\x%02x\\\\x%02x\", c & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF, c >> 24);\n                break;\n            }\n        }\n        if (hgs.ddoc)\n            escapeDdocString(buf, o);\n        buf.writeByte('\"');\n        if (e.postfix)\n            buf.writeByte(e.postfix);\n    }\n\n    override void visit(ArrayLiteralExp e)\n    {\n        buf.writeByte('[');\n        argsToBuffer(e.elements, e.basis);\n        buf.writeByte(']');\n    }\n\n    override void visit(AssocArrayLiteralExp e)\n    {\n        buf.writeByte('[');\n        foreach (i, key; *e.keys)\n        {\n            if (i)\n                buf.writestring(\", \");\n            expToBuffer(key, PREC.assign);\n            buf.writeByte(':');\n            auto value = (*e.values)[i];\n            expToBuffer(value, PREC.assign);\n        }\n        buf.writeByte(']');\n    }\n\n    override void visit(StructLiteralExp e)\n    {\n        buf.writestring(e.sd.toChars());\n        buf.writeByte('(');\n        // CTFE can generate struct literals that contain an AddrExp pointing\n        // to themselves, need to avoid infinite recursion:\n        // struct S { this(int){ this.s = &this; } S* s; }\n        // const foo = new S(0);\n        if (e.stageflags & stageToCBuffer)\n            buf.writestring(\"<recursion>\");\n        else\n        {\n            int old = e.stageflags;\n            e.stageflags |= stageToCBuffer;\n            argsToBuffer(e.elements);\n            e.stageflags = old;\n        }\n        buf.writeByte(')');\n    }\n\n    override void visit(TypeExp e)\n    {\n        typeToBuffer(e.type, null);\n    }\n\n    override void visit(ScopeExp e)\n    {\n        if (e.sds.isTemplateInstance())\n        {\n            e.sds.accept(this);\n        }\n        else if (hgs !is null && hgs.ddoc)\n        {\n            // fixes bug 6491\n            Module m = e.sds.isModule();\n            if (m)\n                buf.writestring(m.md.toChars());\n            else\n                buf.writestring(e.sds.toChars());\n        }\n        else\n        {\n            buf.writestring(e.sds.kind());\n            buf.writeByte(' ');\n            buf.writestring(e.sds.toChars());\n        }\n    }\n\n    override void visit(TemplateExp e)\n    {\n        buf.writestring(e.td.toChars());\n    }\n\n    override void visit(NewExp e)\n    {\n        if (e.thisexp)\n        {\n            expToBuffer(e.thisexp, PREC.primary);\n            buf.writeByte('.');\n        }\n        buf.writestring(\"new \");\n        if (e.newargs && e.newargs.dim)\n        {\n            buf.writeByte('(');\n            argsToBuffer(e.newargs);\n            buf.writeByte(')');\n        }\n        typeToBuffer(e.newtype, null);\n        if (e.arguments && e.arguments.dim)\n        {\n            buf.writeByte('(');\n            argsToBuffer(e.arguments);\n            buf.writeByte(')');\n        }\n    }\n\n    override void visit(NewAnonClassExp e)\n    {\n        if (e.thisexp)\n        {\n            expToBuffer(e.thisexp, PREC.primary);\n            buf.writeByte('.');\n        }\n        buf.writestring(\"new\");\n        if (e.newargs && e.newargs.dim)\n        {\n            buf.writeByte('(');\n            argsToBuffer(e.newargs);\n            buf.writeByte(')');\n        }\n        buf.writestring(\" class \");\n        if (e.arguments && e.arguments.dim)\n        {\n            buf.writeByte('(');\n            argsToBuffer(e.arguments);\n            buf.writeByte(')');\n        }\n        if (e.cd)\n            e.cd.accept(this);\n    }\n\n    override void visit(SymOffExp e)\n    {\n        if (e.offset)\n            buf.printf(\"(& %s+%u)\", e.var.toChars(), e.offset);\n        else if (e.var.isTypeInfoDeclaration())\n            buf.writestring(e.var.toChars());\n        else\n            buf.printf(\"& %s\", e.var.toChars());\n    }\n\n    override void visit(VarExp e)\n    {\n        buf.writestring(e.var.toChars());\n    }\n\n    override void visit(OverExp e)\n    {\n        buf.writestring(e.vars.ident.toString());\n    }\n\n    override void visit(TupleExp e)\n    {\n        if (e.e0)\n        {\n            buf.writeByte('(');\n            e.e0.accept(this);\n            buf.writestring(\", tuple(\");\n            argsToBuffer(e.exps);\n            buf.writestring(\"))\");\n        }\n        else\n        {\n            buf.writestring(\"tuple(\");\n            argsToBuffer(e.exps);\n            buf.writeByte(')');\n        }\n    }\n\n    override void visit(FuncExp e)\n    {\n        e.fd.accept(this);\n        //buf.writestring(e.fd.toChars());\n    }\n\n    override void visit(DeclarationExp e)\n    {\n        /* Normal dmd execution won't reach here - regular variable declarations\n         * are handled in visit(ExpStatement), so here would be used only when\n         * we'll directly call Expression.toChars() for debugging.\n         */\n        if (auto v = e.declaration.isVarDeclaration())\n        {\n            // For debugging use:\n            // - Avoid printing newline.\n            // - Intentionally use the format (Type var;)\n            //   which isn't correct as regular D code.\n            buf.writeByte('(');\n            visitVarDecl(v, false);\n            buf.writeByte(';');\n            buf.writeByte(')');\n        }\n        else\n            e.declaration.accept(this);\n    }\n\n    override void visit(TypeidExp e)\n    {\n        buf.writestring(\"typeid(\");\n        objectToBuffer(e.obj);\n        buf.writeByte(')');\n    }\n\n    override void visit(TraitsExp e)\n    {\n        buf.writestring(\"__traits(\");\n        buf.writestring(e.ident.toString());\n        if (e.args)\n        {\n            foreach (arg; *e.args)\n            {\n                buf.writestring(\", \");\n                objectToBuffer(arg);\n            }\n        }\n        buf.writeByte(')');\n    }\n\n    override void visit(HaltExp e)\n    {\n        buf.writestring(\"halt\");\n    }\n\n    override void visit(IsExp e)\n    {\n        buf.writestring(\"is(\");\n        typeToBuffer(e.targ, e.id);\n        if (e.tok2 != TOK.reserved)\n        {\n            buf.printf(\" %s %s\", Token.toChars(e.tok), Token.toChars(e.tok2));\n        }\n        else if (e.tspec)\n        {\n            if (e.tok == TOK.colon)\n                buf.writestring(\" : \");\n            else\n                buf.writestring(\" == \");\n            typeToBuffer(e.tspec, null);\n        }\n        if (e.parameters && e.parameters.dim)\n        {\n            buf.writestring(\", \");\n            visitTemplateParameters(e.parameters);\n        }\n        buf.writeByte(')');\n    }\n\n    override void visit(UnaExp e)\n    {\n        buf.writestring(Token.toString(e.op));\n        expToBuffer(e.e1, precedence[e.op]);\n    }\n\n    override void visit(BinExp e)\n    {\n        expToBuffer(e.e1, precedence[e.op]);\n        buf.writeByte(' ');\n        buf.writestring(Token.toString(e.op));\n        buf.writeByte(' ');\n        expToBuffer(e.e2, cast(PREC)(precedence[e.op] + 1));\n    }\n\n    override void visit(CompileExp e)\n    {\n        buf.writestring(\"mixin(\");\n        argsToBuffer(e.exps, null);\n        buf.writeByte(')');\n    }\n\n    override void visit(ImportExp e)\n    {\n        buf.writestring(\"import(\");\n        expToBuffer(e.e1, PREC.assign);\n        buf.writeByte(')');\n    }\n\n    override void visit(AssertExp e)\n    {\n        buf.writestring(\"assert(\");\n        expToBuffer(e.e1, PREC.assign);\n        if (e.msg)\n        {\n            buf.writestring(\", \");\n            expToBuffer(e.msg, PREC.assign);\n        }\n        buf.writeByte(')');\n    }\n\n    override void visit(DotIdExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writeByte('.');\n        buf.writestring(e.ident.toString());\n    }\n\n    override void visit(DotTemplateExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writeByte('.');\n        buf.writestring(e.td.toChars());\n    }\n\n    override void visit(DotVarExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writeByte('.');\n        buf.writestring(e.var.toChars());\n    }\n\n    override void visit(DotTemplateInstanceExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writeByte('.');\n        e.ti.accept(this);\n    }\n\n    override void visit(DelegateExp e)\n    {\n        buf.writeByte('&');\n        if (!e.func.isNested())\n        {\n            expToBuffer(e.e1, PREC.primary);\n            buf.writeByte('.');\n        }\n        buf.writestring(e.func.toChars());\n    }\n\n    override void visit(DotTypeExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writeByte('.');\n        buf.writestring(e.sym.toChars());\n    }\n\n    override void visit(CallExp e)\n    {\n        if (e.e1.op == TOK.type)\n        {\n            /* Avoid parens around type to prevent forbidden cast syntax:\n             *   (sometype)(arg1)\n             * This is ok since types in constructor calls\n             * can never depend on parens anyway\n             */\n            e.e1.accept(this);\n        }\n        else\n            expToBuffer(e.e1, precedence[e.op]);\n        buf.writeByte('(');\n        argsToBuffer(e.arguments);\n        buf.writeByte(')');\n    }\n\n    override void visit(PtrExp e)\n    {\n        buf.writeByte('*');\n        expToBuffer(e.e1, precedence[e.op]);\n    }\n\n    override void visit(DeleteExp e)\n    {\n        buf.writestring(\"delete \");\n        expToBuffer(e.e1, precedence[e.op]);\n    }\n\n    override void visit(CastExp e)\n    {\n        buf.writestring(\"cast(\");\n        if (e.to)\n            typeToBuffer(e.to, null);\n        else\n        {\n            MODtoBuffer(buf, e.mod);\n        }\n        buf.writeByte(')');\n        expToBuffer(e.e1, precedence[e.op]);\n    }\n\n    override void visit(VectorExp e)\n    {\n        buf.writestring(\"cast(\");\n        typeToBuffer(e.to, null);\n        buf.writeByte(')');\n        expToBuffer(e.e1, precedence[e.op]);\n    }\n\n    override void visit(SliceExp e)\n    {\n        expToBuffer(e.e1, precedence[e.op]);\n        buf.writeByte('[');\n        if (e.upr || e.lwr)\n        {\n            if (e.lwr)\n                sizeToBuffer(e.lwr);\n            else\n                buf.writeByte('0');\n            buf.writestring(\"..\");\n            if (e.upr)\n                sizeToBuffer(e.upr);\n            else\n                buf.writeByte('$');\n        }\n        buf.writeByte(']');\n    }\n\n    override void visit(ArrayLengthExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writestring(\".length\");\n    }\n\n    override void visit(IntervalExp e)\n    {\n        expToBuffer(e.lwr, PREC.assign);\n        buf.writestring(\"..\");\n        expToBuffer(e.upr, PREC.assign);\n    }\n\n    override void visit(DelegatePtrExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writestring(\".ptr\");\n    }\n\n    override void visit(DelegateFuncptrExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writestring(\".funcptr\");\n    }\n\n    override void visit(ArrayExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writeByte('[');\n        argsToBuffer(e.arguments);\n        buf.writeByte(']');\n    }\n\n    override void visit(DotExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writeByte('.');\n        expToBuffer(e.e2, PREC.primary);\n    }\n\n    override void visit(IndexExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writeByte('[');\n        sizeToBuffer(e.e2);\n        buf.writeByte(']');\n    }\n\n    override void visit(PostExp e)\n    {\n        expToBuffer(e.e1, precedence[e.op]);\n        buf.writestring(Token.toString(e.op));\n    }\n\n    override void visit(PreExp e)\n    {\n        buf.writestring(Token.toString(e.op));\n        expToBuffer(e.e1, precedence[e.op]);\n    }\n\n    override void visit(RemoveExp e)\n    {\n        expToBuffer(e.e1, PREC.primary);\n        buf.writestring(\".remove(\");\n        expToBuffer(e.e2, PREC.assign);\n        buf.writeByte(')');\n    }\n\n    override void visit(CondExp e)\n    {\n        expToBuffer(e.econd, PREC.oror);\n        buf.writestring(\" ? \");\n        expToBuffer(e.e1, PREC.expr);\n        buf.writestring(\" : \");\n        expToBuffer(e.e2, PREC.cond);\n    }\n\n    override void visit(DefaultInitExp e)\n    {\n        buf.writestring(Token.toString(e.subop));\n    }\n\n    override void visit(ClassReferenceExp e)\n    {\n        buf.writestring(e.value.toChars());\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    override void visit(TemplateTypeParameter tp)\n    {\n        buf.writestring(tp.ident.toString());\n        if (tp.specType)\n        {\n            buf.writestring(\" : \");\n            typeToBuffer(tp.specType, null);\n        }\n        if (tp.defaultType)\n        {\n            buf.writestring(\" = \");\n            typeToBuffer(tp.defaultType, null);\n        }\n    }\n\n    override void visit(TemplateThisParameter tp)\n    {\n        buf.writestring(\"this \");\n        visit(cast(TemplateTypeParameter)tp);\n    }\n\n    override void visit(TemplateAliasParameter tp)\n    {\n        buf.writestring(\"alias \");\n        if (tp.specType)\n            typeToBuffer(tp.specType, tp.ident);\n        else\n            buf.writestring(tp.ident.toString());\n        if (tp.specAlias)\n        {\n            buf.writestring(\" : \");\n            objectToBuffer(tp.specAlias);\n        }\n        if (tp.defaultAlias)\n        {\n            buf.writestring(\" = \");\n            objectToBuffer(tp.defaultAlias);\n        }\n    }\n\n    override void visit(TemplateValueParameter tp)\n    {\n        typeToBuffer(tp.valType, tp.ident);\n        if (tp.specValue)\n        {\n            buf.writestring(\" : \");\n            tp.specValue.accept(this);\n        }\n        if (tp.defaultValue)\n        {\n            buf.writestring(\" = \");\n            tp.defaultValue.accept(this);\n        }\n    }\n\n    override void visit(TemplateTupleParameter tp)\n    {\n        buf.writestring(tp.ident.toString());\n        buf.writestring(\"...\");\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    override void visit(DebugCondition c)\n    {\n        buf.writestring(\"debug (\");\n        if (c.ident)\n            buf.writestring(c.ident.toString());\n        else\n            buf.print(c.level);\n        buf.writeByte(')');\n    }\n\n    override void visit(VersionCondition c)\n    {\n        buf.writestring(\"version (\");\n        if (c.ident)\n            buf.writestring(c.ident.toString());\n        else\n            buf.print(c.level);\n        buf.writeByte(')');\n    }\n\n    override void visit(StaticIfCondition c)\n    {\n        buf.writestring(\"static if (\");\n        c.exp.accept(this);\n        buf.writeByte(')');\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    override void visit(Parameter p)\n    {\n        if (p.userAttribDecl)\n        {\n            buf.writestring(\"@\");\n            scope(exit) buf.writestring(\" \");\n\n            bool isAnonymous = p.userAttribDecl.atts.dim > 0 && (*p.userAttribDecl.atts)[0].op != TOK.call;\n            if (isAnonymous)\n                buf.writestring(\"(\");\n            argsToBuffer(p.userAttribDecl.atts);\n            if (isAnonymous)\n                buf.writestring(\")\");\n        }\n        if (p.storageClass & STC.auto_)\n            buf.writestring(\"auto \");\n        if (p.storageClass & STC.return_)\n            buf.writestring(\"return \");\n        if (p.storageClass & STC.out_)\n            buf.writestring(\"out \");\n        else if (p.storageClass & STC.ref_)\n            buf.writestring(\"ref \");\n        else if (p.storageClass & STC.in_)\n            buf.writestring(\"in \");\n        else if (p.storageClass & STC.lazy_)\n            buf.writestring(\"lazy \");\n        else if (p.storageClass & STC.alias_)\n            buf.writestring(\"alias \");\n        StorageClass stc = p.storageClass;\n        if (p.type && p.type.mod & MODFlags.shared_)\n            stc &= ~STC.shared_;\n        if (stcToBuffer(buf, stc & (STC.const_ | STC.immutable_ | STC.wild | STC.shared_ | STC.scope_ | STC.scopeinferred)))\n            buf.writeByte(' ');\n        if (p.storageClass & STC.alias_)\n        {\n            if (p.ident)\n                buf.writestring(p.ident.toString());\n        }\n        else if (p.type.ty == Tident &&\n                 (cast(TypeIdentifier)p.type).ident.toString().length > 3 &&\n                 strncmp((cast(TypeIdentifier)p.type).ident.toChars(), \"__T\", 3) == 0)\n        {\n            // print parameter name, instead of undetermined type parameter\n            buf.writestring(p.ident.toString());\n        }\n        else\n            typeToBuffer(p.type, p.ident);\n        if (p.defaultArg)\n        {\n            buf.writestring(\" = \");\n            p.defaultArg.accept(this);\n        }\n    }\n\n    void parametersToBuffer(Parameters* parameters, int varargs)\n    {\n        buf.writeByte('(');\n        if (parameters)\n        {\n            size_t dim = Parameter.dim(parameters);\n            foreach (i; 0 .. dim)\n            {\n                if (i)\n                    buf.writestring(\", \");\n                Parameter fparam = Parameter.getNth(parameters, i);\n                fparam.accept(this);\n            }\n            if (varargs)\n            {\n                if (parameters.dim && varargs == 1)\n                    buf.writestring(\", \");\n                buf.writestring(\"...\");\n            }\n        }\n        buf.writeByte(')');\n    }\n\n    override void visit(Module m)\n    {\n        if (m.md)\n        {\n            if (m.userAttribDecl)\n            {\n                buf.writestring(\"@(\");\n                argsToBuffer(m.userAttribDecl.atts);\n                buf.writeByte(')');\n                buf.writenl();\n            }\n            if (m.md.isdeprecated)\n            {\n                if (m.md.msg)\n                {\n                    buf.writestring(\"deprecated(\");\n                    m.md.msg.accept(this);\n                    buf.writestring(\") \");\n                }\n                else\n                    buf.writestring(\"deprecated \");\n            }\n            buf.writestring(\"module \");\n            buf.writestring(m.md.toChars());\n            buf.writeByte(';');\n            buf.writenl();\n        }\n        foreach (s; *m.members)\n        {\n            s.accept(this);\n        }\n    }\n}\n\nvoid toCBuffer(Statement s, OutBuffer* buf, HdrGenState* hgs)\n{\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(buf, hgs);\n    s.accept(v);\n}\n\nvoid toCBuffer(Type t, OutBuffer* buf, Identifier ident, HdrGenState* hgs)\n{\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(buf, hgs);\n    v.typeToBuffer(t, ident);\n}\n\nvoid toCBuffer(Dsymbol s, OutBuffer* buf, HdrGenState* hgs)\n{\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(buf, hgs);\n    s.accept(v);\n}\n\n// used from TemplateInstance::toChars() and TemplateMixin::toChars()\nvoid toCBufferInstance(TemplateInstance ti, OutBuffer* buf, bool qualifyTypes = false)\n{\n    HdrGenState hgs;\n    hgs.fullQual = qualifyTypes;\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(buf, &hgs);\n    v.visit(ti);\n}\n\nvoid toCBuffer(Initializer iz, OutBuffer* buf, HdrGenState* hgs)\n{\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(buf, hgs);\n    iz.accept(v);\n}\n\nbool stcToBuffer(OutBuffer* buf, StorageClass stc)\n{\n    bool result = false;\n    if ((stc & (STC.return_ | STC.scope_)) == (STC.return_ | STC.scope_))\n        stc &= ~STC.scope_;\n    if (stc & STC.scopeinferred)\n        stc &= ~(STC.scope_ | STC.scopeinferred);\n    while (stc)\n    {\n        const(char)* p = stcToChars(stc);\n        if (!p) // there's no visible storage classes\n            break;\n        if (!result)\n            result = true;\n        else\n            buf.writeByte(' ');\n        buf.writestring(p);\n    }\n    return result;\n}\n\n/*************************************************\n * Pick off one of the storage classes from stc,\n * and return a pointer to a string representation of it.\n * stc is reduced by the one picked.\n */\nextern (C++) const(char)* stcToChars(ref StorageClass stc)\n{\n    struct SCstring\n    {\n        StorageClass stc;\n        TOK tok;\n        const(char)* id;\n    }\n\n    __gshared SCstring* table =\n    [\n        SCstring(STC.auto_, TOK.auto_),\n        SCstring(STC.scope_, TOK.scope_),\n        SCstring(STC.static_, TOK.static_),\n        SCstring(STC.extern_, TOK.extern_),\n        SCstring(STC.const_, TOK.const_),\n        SCstring(STC.final_, TOK.final_),\n        SCstring(STC.abstract_, TOK.abstract_),\n        SCstring(STC.synchronized_, TOK.synchronized_),\n        SCstring(STC.deprecated_, TOK.deprecated_),\n        SCstring(STC.override_, TOK.override_),\n        SCstring(STC.lazy_, TOK.lazy_),\n        SCstring(STC.alias_, TOK.alias_),\n        SCstring(STC.out_, TOK.out_),\n        SCstring(STC.in_, TOK.in_),\n        SCstring(STC.manifest, TOK.enum_),\n        SCstring(STC.immutable_, TOK.immutable_),\n        SCstring(STC.shared_, TOK.shared_),\n        SCstring(STC.nothrow_, TOK.nothrow_),\n        SCstring(STC.wild, TOK.inout_),\n        SCstring(STC.pure_, TOK.pure_),\n        SCstring(STC.ref_, TOK.ref_),\n        SCstring(STC.return_, TOK.return_),\n        SCstring(STC.tls),\n        SCstring(STC.gshared, TOK.gshared),\n        SCstring(STC.nogc, TOK.at, \"@nogc\"),\n        SCstring(STC.property, TOK.at, \"@property\"),\n        SCstring(STC.safe, TOK.at, \"@safe\"),\n        SCstring(STC.trusted, TOK.at, \"@trusted\"),\n        SCstring(STC.system, TOK.at, \"@system\"),\n        SCstring(STC.disable, TOK.at, \"@disable\"),\n        SCstring(STC.future, TOK.at, \"@__future\"),\n        SCstring(STC.local, TOK.at, \"__local\"),\n        SCstring(0, TOK.reserved)\n    ];\n    for (int i = 0; table[i].stc; i++)\n    {\n        StorageClass tbl = table[i].stc;\n        assert(tbl & STCStorageClass);\n        if (stc & tbl)\n        {\n            stc &= ~tbl;\n            if (tbl == STC.tls) // TOKtls was removed\n                return \"__thread\";\n            TOK tok = table[i].tok;\n            if (tok == TOK.at)\n                return table[i].id;\n            else\n                return Token.toChars(tok);\n        }\n    }\n    //printf(\"stc = %llx\\n\", stc);\n    return null;\n}\n\n\n/**\n * Returns:\n *   a human readable representation of `stc`\n */\nextern (D) const(char)[] stcToString(ref StorageClass stc)\n{\n    return stcToChars(stc).toDString;\n}\n\nextern (C++) void trustToBuffer(OutBuffer* buf, TRUST trust)\n{\n    const(char)* p = trustToChars(trust);\n    if (p)\n        buf.writestring(p);\n}\n\n/**\n * Returns:\n *   a human readable representation of `trust`,\n *   which is the token `trust` corresponds to\n */\nextern (C++) const(char)* trustToChars(TRUST trust)\n{\n    /// Works because we return a literal\n    return trustToString(trust).ptr;\n}\n\n/// Ditto\nextern (D) string trustToString(TRUST trust)\n{\n    final switch (trust)\n    {\n    case TRUST.default_:\n        return null;\n    case TRUST.system:\n        return \"@system\";\n    case TRUST.trusted:\n        return \"@trusted\";\n    case TRUST.safe:\n        return \"@safe\";\n    }\n}\n\nprivate void linkageToBuffer(OutBuffer* buf, LINK linkage)\n{\n    const(char)* p = linkageToChars(linkage);\n    if (p)\n    {\n        buf.writestring(\"extern (\");\n        buf.writestring(p);\n        buf.writeByte(')');\n    }\n}\n\nextern (C++) const(char)* linkageToChars(LINK linkage)\n{\n    final switch (linkage)\n    {\n    case LINK.default_:\n        return null;\n    case LINK.d:\n        return \"D\";\n    case LINK.c:\n        return \"C\";\n    case LINK.cpp:\n        return \"C++\";\n    case LINK.windows:\n        return \"Windows\";\n    case LINK.pascal:\n        return \"Pascal\";\n    case LINK.objc:\n        return \"Objective-C\";\n    case LINK.system:\n        return \"System\";\n    }\n}\n\nextern (C++) void protectionToBuffer(OutBuffer* buf, Prot prot)\n{\n    const(char)* p = protectionToChars(prot.kind);\n    if (p)\n        buf.writestring(p);\n    if (prot.kind == Prot.Kind.package_ && prot.pkg)\n    {\n        buf.writeByte('(');\n        buf.writestring(prot.pkg.toPrettyChars(true));\n        buf.writeByte(')');\n    }\n}\n\n/**\n * Returns:\n *   a human readable representation of `kind`\n */\nextern (C++) const(char)* protectionToChars(Prot.Kind kind)\n{\n    // Null terminated because we return a literal\n    return protectionToString(kind).ptr;\n}\n\n/// Ditto\nextern (D) string protectionToString(Prot.Kind kind)\n{\n    final switch (kind)\n    {\n    case Prot.Kind.undefined:\n        return null;\n    case Prot.Kind.none:\n        return \"none\";\n    case Prot.Kind.private_:\n        return \"private\";\n    case Prot.Kind.package_:\n        return \"package\";\n    case Prot.Kind.protected_:\n        return \"protected\";\n    case Prot.Kind.public_:\n        return \"public\";\n    case Prot.Kind.export_:\n        return \"export\";\n    }\n}\n\n// Print the full function signature with correct ident, attributes and template args\nvoid functionToBufferFull(TypeFunction tf, OutBuffer* buf, Identifier ident, HdrGenState* hgs, TemplateDeclaration td)\n{\n    //printf(\"TypeFunction::toCBuffer() this = %p\\n\", this);\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(buf, hgs);\n    v.visitFuncIdentWithPrefix(tf, ident, td);\n}\n\n// ident is inserted before the argument list and will be \"function\" or \"delegate\" for a type\nvoid functionToBufferWithIdent(TypeFunction tf, OutBuffer* buf, const(char)* ident)\n{\n    HdrGenState hgs;\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(buf, &hgs);\n    v.visitFuncIdentWithPostfix(tf, ident);\n}\n\nvoid toCBuffer(Expression e, OutBuffer* buf, HdrGenState* hgs)\n{\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(buf, hgs);\n    e.accept(v);\n}\n\n/**************************************************\n * Write out argument types to buf.\n */\nvoid argExpTypesToCBuffer(OutBuffer* buf, Expressions* arguments)\n{\n    if (!arguments || !arguments.dim)\n        return;\n    HdrGenState hgs;\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(buf, &hgs);\n    foreach (i, arg; *arguments)\n    {\n        if (i)\n            buf.writestring(\", \");\n        v.typeToBuffer(arg.type, null);\n    }\n}\n\nvoid toCBuffer(TemplateParameter tp, OutBuffer* buf, HdrGenState* hgs)\n{\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(buf, hgs);\n    tp.accept(v);\n}\n\nvoid arrayObjectsToBuffer(OutBuffer* buf, Objects* objects)\n{\n    if (!objects || !objects.dim)\n        return;\n    HdrGenState hgs;\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(buf, &hgs);\n    foreach (i, o; *objects)\n    {\n        if (i)\n            buf.writestring(\", \");\n        v.objectToBuffer(o);\n    }\n}\n\n/*************************************************************\n * Pretty print function parameters.\n * Params:\n *  parameters = parameters to print, such as TypeFunction.parameters.\n *  varargs = kind of varargs, see TypeFunction.varargs.\n * Returns: Null-terminated string representing parameters.\n */\nextern (C++) const(char)* parametersTypeToChars(Parameters* parameters, int varargs)\n{\n    OutBuffer buf;\n    HdrGenState hgs;\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(&buf, &hgs);\n    v.parametersToBuffer(parameters, varargs);\n    return buf.extractString();\n}\n\n/*************************************************************\n * Pretty print function parameter.\n * Params:\n *  parameter = parameter to print.\n *  tf = TypeFunction which holds parameter.\n *  fullQual = whether to fully qualify types.\n * Returns: Null-terminated string representing parameters.\n */\nconst(char)* parameterToChars(Parameter parameter, TypeFunction tf, bool fullQual)\n{\n    OutBuffer buf;\n    HdrGenState hgs;\n    hgs.fullQual = fullQual;\n    scope PrettyPrintVisitor v = new PrettyPrintVisitor(&buf, &hgs);\n\n    parameter.accept(v);\n    if (tf.varargs == 2 && parameter == Parameter.getNth(tf.parameters, tf.parameters.dim - 1))\n    {\n        buf.writestring(\"...\");\n    }\n    return buf.extractString();\n}\n"
  },
  {
    "path": "gcc/d/dmd/hdrgen.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Dave Fladebo\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/hdrgen.h\n */\n\n#pragma once\n\n#include \"globals.h\"\n#include \"dsymbol.h\"\n#include \"mtype.h\"\n\nclass Module;\n\nvoid genhdrfile(Module *m);\nvoid moduleToBuffer(OutBuffer *buf, Module *m);\n\nconst char *parametersTypeToChars(Parameters *parameters, int varargs);\nconst char *stcToChars(StorageClass& stc);\nvoid trustToBuffer(OutBuffer *buf, TRUST trust);\nconst char *trustToChars(TRUST trust);\nconst char *linkageToChars(LINK linkage);\nvoid protectionToBuffer(OutBuffer *buf, Prot prot);\nconst char *protectionToChars(Prot::Kind kind);\n"
  },
  {
    "path": "gcc/d/dmd/iasm.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n *              Copyright (C) 2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/iasm.d, _iasm.d)\n * Documentation:  https://dlang.org/phobos/dmd_iasm.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/iasm.d\n */\n\n/* Inline assembler for the D programming language compiler\n */\n\nmodule dmd.iasm;\n\nimport dmd.dscope;\nimport dmd.func;\nimport dmd.statement;\n\nversion (MARS)\n{\n    import dmd.iasmdmd;\n}\nelse version (IN_GCC)\n{\n    import dmd.iasmgcc;\n}\n\n/************************ AsmStatement ***************************************/\n\nextern(C++) Statement asmSemantic(AsmStatement s, Scope *sc)\n{\n    //printf(\"AsmStatement.semantic()\\n\");\n\n    FuncDeclaration fd = sc.parent.isFuncDeclaration();\n    assert(fd);\n\n    if (!s.tokens)\n        return null;\n\n    // Assume assembler code takes care of setting the return value\n    sc.func.hasReturnExp |= 8;\n\n    version (MARS)\n    {\n        auto ias = new InlineAsmStatement(s.loc, s.tokens);\n        return inlineAsmSemantic(ias, sc);\n    }\n    else version (IN_GCC)\n    {\n        auto eas = new GccAsmStatement(s.loc, s.tokens);\n        return gccAsmSemantic(eas, sc);\n    }\n    else\n    {\n        s.error(\"D inline assembler statements are not supported\");\n        return new ErrorStatement();\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/iasmgcc.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n *              Copyright (C) 2018 by The D Language Foundation, All Rights Reserved\n * Authors:     Iain Buclaw\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/iasmgcc.d, _iasmgcc.d)\n * Documentation:  https://dlang.org/phobos/dmd_iasmgcc.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/iasmgcc.d\n */\n\n/* Inline assembler for the GCC D compiler.\n */\n\nmodule dmd.iasmgcc;\n\nimport core.stdc.string;\n\nimport dmd.arraytypes;\nimport dmd.astcodegen;\nimport dmd.dscope;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.identifier;\nimport dmd.globals;\nimport dmd.parse;\nimport dmd.tokens;\nimport dmd.statement;\nimport dmd.statementsem;\n\nprivate:\n\n/***********************************\n * Parse list of extended asm input or output operands.\n * Grammar:\n *      | Operands:\n *      |     SymbolicName(opt) StringLiteral AssignExpression\n *      |     SymbolicName(opt) StringLiteral AssignExpression , Operands\n *      |\n *      | SymbolicName:\n *      |     [ Identifier ]\n * Params:\n *      p = parser state\n *      s = asm statement to parse\n * Returns:\n *      number of operands added to the gcc asm statement\n */\nint parseExtAsmOperands(Parser)(Parser p, GccAsmStatement s)\n{\n    int numargs = 0;\n\n    while (1)\n    {\n        Expression arg;\n        Identifier name;\n        Expression constraint;\n\n        switch (p.token.value)\n        {\n            case TOK.semicolon:\n            case TOK.colon:\n            case TOK.endOfFile:\n                return numargs;\n\n            case TOK.leftBracket:\n                if (p.peekNext() == TOK.identifier)\n                {\n                    p.nextToken();\n                    name = p.token.ident;\n                    p.nextToken();\n                }\n                else\n                {\n                    p.error(s.loc, \"expected identifier after `[`\");\n                    goto Lerror;\n                }\n                p.check(TOK.rightBracket);\n                goto case;\n\n            case TOK.string_:\n                constraint = p.parsePrimaryExp();\n                arg = p.parseAssignExp();\n\n                if (!s.args)\n                {\n                    s.names = new Identifiers();\n                    s.constraints = new Expressions();\n                    s.args = new Expressions();\n                }\n                s.names.push(name);\n                s.args.push(arg);\n                s.constraints.push(constraint);\n                numargs++;\n\n                if (p.token.value == TOK.comma)\n                    p.nextToken();\n                break;\n\n            default:\n                p.error(\"expected constant string constraint for operand, not `%s`\",\n                        p.token.toChars());\n                goto Lerror;\n        }\n    }\nLerror:\n    while (p.token.value != TOK.rightCurly &&\n           p.token.value != TOK.semicolon &&\n           p.token.value != TOK.endOfFile)\n        p.nextToken();\n\n    return numargs;\n}\n\n/***********************************\n * Parse list of extended asm clobbers.\n * Grammar:\n *      | Clobbers:\n *      |     StringLiteral\n *      |     StringLiteral , Clobbers\n * Params:\n *      p = parser state\n * Returns:\n *      array of parsed clobber expressions\n */\nExpressions *parseExtAsmClobbers(Parser)(Parser p)\n{\n    Expressions *clobbers;\n\n    while (1)\n    {\n        Expression clobber;\n\n        switch (p.token.value)\n        {\n            case TOK.semicolon:\n            case TOK.colon:\n            case TOK.endOfFile:\n                return clobbers;\n\n            case TOK.string_:\n                clobber = p.parsePrimaryExp();\n                if (!clobbers)\n                    clobbers = new Expressions();\n                clobbers.push(clobber);\n\n                if (p.token.value == TOK.comma)\n                    p.nextToken();\n                break;\n\n            default:\n                p.error(\"expected constant string constraint for clobber name, not `%s`\",\n                        p.token.toChars());\n                goto Lerror;\n        }\n    }\nLerror:\n    while (p.token.value != TOK.rightCurly &&\n           p.token.value != TOK.semicolon &&\n           p.token.value != TOK.endOfFile)\n        p.nextToken();\n\n    return clobbers;\n}\n\n/***********************************\n * Parse list of extended asm goto labels.\n * Grammar:\n *      | GotoLabels:\n *      |     Identifier\n *      |     Identifier , GotoLabels\n * Params:\n *      p = parser state\n * Returns:\n *      array of parsed goto labels\n */\nIdentifiers *parseExtAsmGotoLabels(Parser)(Parser p)\n{\n    Identifiers *labels;\n\n    while (1)\n    {\n        switch (p.token.value)\n        {\n            case TOK.semicolon:\n            case TOK.endOfFile:\n                return labels;\n\n            case TOK.identifier:\n                if (!labels)\n                    labels = new Identifiers();\n                labels.push(p.token.ident);\n\n                if (p.nextToken() == TOK.comma)\n                    p.nextToken();\n                break;\n\n            default:\n                p.error(\"expected identifier for goto label name, not `%s`\",\n                        p.token.toChars());\n                goto Lerror;\n        }\n    }\nLerror:\n    while (p.token.value != TOK.rightCurly &&\n           p.token.value != TOK.semicolon &&\n           p.token.value != TOK.endOfFile)\n        p.nextToken();\n\n    return labels;\n}\n\n/***********************************\n * Parse a gcc asm statement.\n * There are three forms of inline asm statements, basic, extended, and goto.\n * Grammar:\n *      | AsmInstruction:\n *      |     BasicAsmInstruction\n *      |     ExtAsmInstruction\n *      |     GotoAsmInstruction\n *      |\n *      | BasicAsmInstruction:\n *      |     Expression\n *      |\n *      | ExtAsmInstruction:\n *      |     Expression : Operands(opt) : Operands(opt) : Clobbers(opt)\n *      |\n *      | GotoAsmInstruction:\n *      |     Expression : : Operands(opt) : Clobbers(opt) : GotoLabels(opt)\n * Params:\n *      p = parser state\n *      s = asm statement to parse\n * Returns:\n *      the parsed gcc asm statement\n */\nGccAsmStatement parseGccAsm(Parser)(Parser p, GccAsmStatement s)\n{\n    s.insn = p.parseExpression();\n    if (p.token.value == TOK.semicolon)\n        goto Ldone;\n\n    // No semicolon followed after instruction template, treat as extended asm.\n    foreach (section; 0 .. 4)\n    {\n        p.check(TOK.colon);\n\n        final switch (section)\n        {\n            case 0:\n                s.outputargs = p.parseExtAsmOperands(s);\n                break;\n\n            case 1:\n                p.parseExtAsmOperands(s);\n                break;\n\n            case 2:\n                s.clobbers = p.parseExtAsmClobbers();\n                break;\n\n            case 3:\n                s.labels = p.parseExtAsmGotoLabels();\n                break;\n        }\n\n        if (p.token.value == TOK.semicolon)\n            goto Ldone;\n    }\nLdone:\n    p.check(TOK.semicolon);\n\n    return s;\n}\n\n/***********************************\n * Parse and run semantic analysis on a GccAsmStatement.\n * Params:\n *      s  = gcc asm statement being parsed\n *      sc = the scope where the asm statement is located\n * Returns:\n *      the completed gcc asm statement, or null if errors occurred\n */\npublic Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)\n{\n    //printf(\"GccAsmStatement.semantic()\\n\");\n    scope p = new Parser!ASTCodegen(sc._module, \";\", false);\n\n    // Make a safe copy of the token list before parsing.\n    Token *toklist = null;\n    Token **ptoklist = &toklist;\n\n    for (Token *token = s.tokens; token; token = token.next)\n    {\n        *ptoklist = Token.alloc();\n        memcpy(*ptoklist, token, Token.sizeof);\n        ptoklist = &(*ptoklist).next;\n        *ptoklist = null;\n    }\n    p.token = *toklist;\n\n    // Parse the gcc asm statement.\n    s = p.parseGccAsm(s);\n    if (p.errors)\n        return null;\n    s.stc = sc.stc;\n\n    // Fold the instruction template string.\n    s.insn = semanticString(sc, s.insn, \"asm instruction template\");\n\n    if (s.labels && s.outputargs)\n        s.error(\"extended asm statements with labels cannot have output constraints\");\n\n    // Analyse all input and output operands.\n    if (s.args)\n    {\n        foreach (i; 0 .. s.args.dim)\n        {\n            Expression e = (*s.args)[i];\n            e = e.expressionSemantic(sc);\n            // Check argument is a valid lvalue/rvalue.\n            if (i < s.outputargs)\n                e = e.modifiableLvalue(sc, null);\n            else if (e.checkValue())\n                e = new ErrorExp();\n            (*s.args)[i] = e;\n\n            e = (*s.constraints)[i];\n            e = e.expressionSemantic(sc);\n            assert(e.op == TOK.string_ && (cast(StringExp) e).sz == 1);\n            (*s.constraints)[i] = e;\n        }\n    }\n\n    // Analyse all clobbers.\n    if (s.clobbers)\n    {\n        foreach (i; 0 .. s.clobbers.dim)\n        {\n            Expression e = (*s.clobbers)[i];\n            e = e.expressionSemantic(sc);\n            assert(e.op == TOK.string_ && (cast(StringExp) e).sz == 1);\n            (*s.clobbers)[i] = e;\n        }\n    }\n\n    // Analyse all goto labels.\n    if (s.labels)\n    {\n        foreach (i; 0 .. s.labels.dim)\n        {\n            Identifier ident = (*s.labels)[i];\n            GotoStatement gs = new GotoStatement(s.loc, ident);\n            if (!s.gotos)\n                s.gotos = new GotoStatements();\n            s.gotos.push(gs);\n            gs.statementSemantic(sc);\n        }\n    }\n\n    return s;\n}\n\nunittest\n{\n    uint errors = global.startGagging();\n\n    // Immitates asmSemantic if version = IN_GCC.\n    static int semanticAsm(Token* tokens)\n    {\n        scope gas = new GccAsmStatement(Loc.initial, tokens);\n        scope p = new Parser!ASTCodegen(null, \";\", false);\n        p.token = *tokens;\n        p.parseGccAsm(gas);\n        return p.errors;\n    }\n\n    // Immitates parseStatement for asm statements.\n    static void parseAsm(string input, bool expectError)\n    {\n        // Generate tokens from input test.\n        scope p = new Parser!ASTCodegen(null, input, false);\n        p.nextToken();\n\n        Token* toklist = null;\n        Token** ptoklist = &toklist;\n        p.check(TOK.asm_);\n        p.check(TOK.leftCurly);\n        while (1)\n        {\n            if (p.token.value == TOK.rightCurly || p.token.value == TOK.endOfFile)\n                break;\n            *ptoklist = Token.alloc();\n            memcpy(*ptoklist, &p.token, Token.sizeof);\n            ptoklist = &(*ptoklist).next;\n            *ptoklist = null;\n            p.nextToken();\n        }\n        p.check(TOK.rightCurly);\n\n        auto res = semanticAsm(toklist);\n        assert(res == 0 || expectError);\n    }\n\n    /// Assembly Tests, all should pass.\n    /// Note: Frontend is not initialized, use only strings and identifiers.\n    immutable string[] passAsmTests = [\n        // Basic asm statement\n        q{ asm { \"nop\";\n        } },\n\n        // Extended asm statement\n        q{ asm { \"cpuid\"\n               : \"=a\" (a), \"=b\" (b), \"=c\" (c), \"=d\" (d)\n               : \"a\" input;\n        } },\n\n        // Assembly with symbolic names\n        q{ asm { \"bts %[base], %[offset]\"\n               : [base] \"+rm\" *ptr,\n               : [offset] \"Ir\" bitnum;\n        } },\n\n        // Assembly with clobbers\n        q{ asm { \"cpuid\"\n               : \"=a\" a\n               : \"a\" input\n               : \"ebx\", \"ecx\", \"edx\";\n        } },\n\n        // Goto asm statement\n        q{ asm { \"jmp %l0\"\n               :\n               :\n               :\n               : Ljmplabel;\n        } },\n\n        // Any CTFE-able string allowed as instruction template.\n        q{ asm { generateAsm();\n        } },\n\n        // Likewise mixins, permissible so long as the result is a string.\n        q{ asm { mixin(`\"repne\"`, `~ \"scasb\"`);\n        } },\n    ];\n\n    foreach (test; passAsmTests)\n        parseAsm(test, false);\n\n    global.endGagging(errors);\n}\n"
  },
  {
    "path": "gcc/d/dmd/id.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * This module contains the `Id` struct with a list of predefined symbols the\n * compiler knows about.\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/id.d, _id.d)\n * Documentation:  https://dlang.org/phobos/dmd_id.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/id.d\n */\n\nmodule dmd.id;\n\nimport dmd.identifier;\nimport dmd.tokens;\n\n/**\n * Represents a list of predefined symbols the compiler knows about.\n *\n * All static fields in this struct represents a specific predefined symbol.\n */\nstruct Id\n{\n    static __gshared:\n\n    mixin(msgtable.generate(&identifier));\n\n    /**\n     * Populates the identifier pool with all predefined symbols.\n     *\n     * An identifier that corresponds to each static field in this struct will\n     * be placed in the identifier pool.\n     */\n    extern(C++) void initialize()\n    {\n        mixin(msgtable.generate(&initializer));\n    }\n}\n\nprivate:\n\n\n/**\n * Each element in this array will generate one static field in the `Id` struct\n * and a call to `Identifier.idPool` to populate the identifier pool in the\n * `Id.initialize` method.\n */\nimmutable Msgtable[] msgtable =\n[\n    { \"IUnknown\" },\n    { \"Object\" },\n    { \"object\" },\n    { \"string\" },\n    { \"wstring\" },\n    { \"dstring\" },\n    { \"max\" },\n    { \"min\" },\n    { \"This\", \"this\" },\n    { \"_super\", \"super\" },\n    { \"ctor\", \"__ctor\" },\n    { \"dtor\", \"__dtor\" },\n    { \"__xdtor\", \"__xdtor\" },\n    { \"__fieldDtor\", \"__fieldDtor\" },\n    { \"__aggrDtor\", \"__aggrDtor\" },\n    { \"cppdtor\", \"__cppdtor\" },\n    { \"ticppdtor\", \"__ticppdtor\" },\n    { \"postblit\", \"__postblit\" },\n    { \"__xpostblit\", \"__xpostblit\" },\n    { \"__fieldPostblit\", \"__fieldPostblit\" },\n    { \"__aggrPostblit\", \"__aggrPostblit\" },\n    { \"classInvariant\", \"__invariant\" },\n    { \"unitTest\", \"__unitTest\" },\n    { \"require\", \"__require\" },\n    { \"ensure\", \"__ensure\" },\n    { \"_init\", \"init\" },\n    { \"__sizeof\", \"sizeof\" },\n    { \"__xalignof\", \"alignof\" },\n    { \"_mangleof\", \"mangleof\" },\n    { \"stringof\" },\n    { \"_tupleof\", \"tupleof\" },\n    { \"length\" },\n    { \"remove\" },\n    { \"ptr\" },\n    { \"array\" },\n    { \"funcptr\" },\n    { \"dollar\", \"__dollar\" },\n    { \"ctfe\", \"__ctfe\" },\n    { \"offset\" },\n    { \"offsetof\" },\n    { \"ModuleInfo\" },\n    { \"ClassInfo\" },\n    { \"classinfo\" },\n    { \"typeinfo\" },\n    { \"outer\" },\n    { \"Exception\" },\n    { \"RTInfo\" },\n    { \"Throwable\" },\n    { \"Error\" },\n    { \"withSym\", \"__withSym\" },\n    { \"result\", \"__result\" },\n    { \"returnLabel\", \"__returnLabel\" },\n    { \"line\" },\n    { \"empty\", \"\" },\n    { \"p\" },\n    { \"q\" },\n    { \"__vptr\" },\n    { \"__monitor\" },\n    { \"gate\", \"__gate\" },\n    { \"__c_long\" },\n    { \"__c_ulong\" },\n    { \"__c_longlong\" },\n    { \"__c_ulonglong\" },\n    { \"__c_long_double\" },\n    { \"cpp_type_info_ptr\", \"__cpp_type_info_ptr\" },\n    { \"_assert\", \"assert\" },\n    { \"_unittest\", \"unittest\" },\n    { \"_body\", \"body\" },\n\n    { \"TypeInfo\" },\n    { \"TypeInfo_Class\" },\n    { \"TypeInfo_Interface\" },\n    { \"TypeInfo_Struct\" },\n    { \"TypeInfo_Enum\" },\n    { \"TypeInfo_Pointer\" },\n    { \"TypeInfo_Vector\" },\n    { \"TypeInfo_Array\" },\n    { \"TypeInfo_StaticArray\" },\n    { \"TypeInfo_AssociativeArray\" },\n    { \"TypeInfo_Function\" },\n    { \"TypeInfo_Delegate\" },\n    { \"TypeInfo_Tuple\" },\n    { \"TypeInfo_Const\" },\n    { \"TypeInfo_Invariant\" },\n    { \"TypeInfo_Shared\" },\n    { \"TypeInfo_Wild\", \"TypeInfo_Inout\" },\n    { \"elements\" },\n    { \"_arguments_typeinfo\" },\n    { \"_arguments\" },\n    { \"_argptr\" },\n    { \"destroy\" },\n    { \"xopEquals\", \"__xopEquals\" },\n    { \"xopCmp\", \"__xopCmp\" },\n    { \"xtoHash\", \"__xtoHash\" },\n\n    { \"Class\" },\n\n    { \"LINE\", \"__LINE__\" },\n    { \"FILE\", \"__FILE__\" },\n    { \"MODULE\", \"__MODULE__\" },\n    { \"FUNCTION\", \"__FUNCTION__\" },\n    { \"PRETTY_FUNCTION\", \"__PRETTY_FUNCTION__\" },\n    { \"DATE\", \"__DATE__\" },\n    { \"TIME\", \"__TIME__\" },\n    { \"TIMESTAMP\", \"__TIMESTAMP__\" },\n    { \"VENDOR\", \"__VENDOR__\" },\n    { \"VERSIONX\", \"__VERSION__\" },\n    { \"EOFX\", \"__EOF__\" },\n\n    { \"nan\" },\n    { \"infinity\" },\n    { \"dig\" },\n    { \"epsilon\" },\n    { \"mant_dig\" },\n    { \"max_10_exp\" },\n    { \"max_exp\" },\n    { \"min_10_exp\" },\n    { \"min_exp\" },\n    { \"min_normal\" },\n    { \"re\" },\n    { \"im\" },\n\n    { \"C\" },\n    { \"D\" },\n    { \"Windows\" },\n    { \"Pascal\" },\n    { \"System\" },\n    { \"Objective\" },\n\n    { \"exit\" },\n    { \"success\" },\n    { \"failure\" },\n\n    { \"keys\" },\n    { \"values\" },\n    { \"rehash\" },\n\n    { \"future\", \"__future\" },\n    { \"property\" },\n    { \"nogc\" },\n    { \"safe\" },\n    { \"trusted\" },\n    { \"system\" },\n    { \"disable\" },\n\n    // For inline assembler\n    { \"___out\", \"out\" },\n    { \"___in\", \"in\" },\n    { \"__int\", \"int\" },\n    { \"_dollar\", \"$\" },\n    { \"__LOCAL_SIZE\" },\n\n    // For operator overloads\n    { \"uadd\",    \"opPos\" },\n    { \"neg\",     \"opNeg\" },\n    { \"com\",     \"opCom\" },\n    { \"add\",     \"opAdd\" },\n    { \"add_r\",   \"opAdd_r\" },\n    { \"sub\",     \"opSub\" },\n    { \"sub_r\",   \"opSub_r\" },\n    { \"mul\",     \"opMul\" },\n    { \"mul_r\",   \"opMul_r\" },\n    { \"div\",     \"opDiv\" },\n    { \"div_r\",   \"opDiv_r\" },\n    { \"mod\",     \"opMod\" },\n    { \"mod_r\",   \"opMod_r\" },\n    { \"eq\",      \"opEquals\" },\n    { \"cmp\",     \"opCmp\" },\n    { \"iand\",    \"opAnd\" },\n    { \"iand_r\",  \"opAnd_r\" },\n    { \"ior\",     \"opOr\" },\n    { \"ior_r\",   \"opOr_r\" },\n    { \"ixor\",    \"opXor\" },\n    { \"ixor_r\",  \"opXor_r\" },\n    { \"shl\",     \"opShl\" },\n    { \"shl_r\",   \"opShl_r\" },\n    { \"shr\",     \"opShr\" },\n    { \"shr_r\",   \"opShr_r\" },\n    { \"ushr\",    \"opUShr\" },\n    { \"ushr_r\",  \"opUShr_r\" },\n    { \"cat\",     \"opCat\" },\n    { \"cat_r\",   \"opCat_r\" },\n    { \"assign\",  \"opAssign\" },\n    { \"addass\",  \"opAddAssign\" },\n    { \"subass\",  \"opSubAssign\" },\n    { \"mulass\",  \"opMulAssign\" },\n    { \"divass\",  \"opDivAssign\" },\n    { \"modass\",  \"opModAssign\" },\n    { \"andass\",  \"opAndAssign\" },\n    { \"orass\",   \"opOrAssign\" },\n    { \"xorass\",  \"opXorAssign\" },\n    { \"shlass\",  \"opShlAssign\" },\n    { \"shrass\",  \"opShrAssign\" },\n    { \"ushrass\", \"opUShrAssign\" },\n    { \"catass\",  \"opCatAssign\" },\n    { \"postinc\", \"opPostInc\" },\n    { \"postdec\", \"opPostDec\" },\n    { \"index\",   \"opIndex\" },\n    { \"indexass\", \"opIndexAssign\" },\n    { \"slice\",   \"opSlice\" },\n    { \"sliceass\", \"opSliceAssign\" },\n    { \"call\",    \"opCall\" },\n    { \"_cast\",    \"opCast\" },\n    { \"opIn\" },\n    { \"opIn_r\" },\n    { \"opStar\" },\n    { \"opDot\" },\n    { \"opDispatch\" },\n    { \"opDollar\" },\n    { \"opUnary\" },\n    { \"opIndexUnary\" },\n    { \"opSliceUnary\" },\n    { \"opBinary\" },\n    { \"opBinaryRight\" },\n    { \"opOpAssign\" },\n    { \"opIndexOpAssign\" },\n    { \"opSliceOpAssign\" },\n    { \"pow\", \"opPow\" },\n    { \"pow_r\", \"opPow_r\" },\n    { \"powass\", \"opPowAssign\" },\n\n    { \"classNew\", \"new\" },\n    { \"classDelete\", \"delete\" },\n\n    // For foreach\n    { \"apply\", \"opApply\" },\n    { \"applyReverse\", \"opApplyReverse\" },\n\n    // Ranges\n    { \"Fempty\", \"empty\" },\n    { \"Ffront\", \"front\" },\n    { \"Fback\", \"back\" },\n    { \"FpopFront\", \"popFront\" },\n    { \"FpopBack\", \"popBack\" },\n\n    // For internal functions\n    { \"aaLen\", \"_aaLen\" },\n    { \"aaKeys\", \"_aaKeys\" },\n    { \"aaValues\", \"_aaValues\" },\n    { \"aaRehash\", \"_aaRehash\" },\n    { \"monitorenter\", \"_d_monitorenter\" },\n    { \"monitorexit\", \"_d_monitorexit\" },\n    { \"criticalenter\", \"_d_criticalenter\" },\n    { \"criticalexit\", \"_d_criticalexit\" },\n    { \"__ArrayEq\" },\n    { \"__ArrayPostblit\" },\n    { \"__ArrayDtor\" },\n    { \"_d_delThrowable\" },\n    { \"dup\" },\n\n    // For pragma's\n    { \"Pinline\", \"inline\" },\n    { \"lib\" },\n    { \"linkerDirective\" },\n    { \"mangle\" },\n    { \"msg\" },\n    { \"startaddress\" },\n    { \"crt_constructor\" },\n    { \"crt_destructor\" },\n\n    // For special functions\n    { \"tohash\", \"toHash\" },\n    { \"tostring\", \"toString\" },\n    { \"getmembers\", \"getMembers\" },\n\n    // Special functions\n    { \"__alloca\", \"alloca\" },\n    { \"main\" },\n    { \"WinMain\" },\n    { \"DllMain\" },\n    { \"tls_get_addr\", \"___tls_get_addr\" },\n    { \"entrypoint\", \"__entrypoint\" },\n    { \"rt_init\" },\n    { \"__cmp\" },\n    { \"__equals\"},\n    { \"__switch\"},\n    { \"__switch_error\"},\n\n    // varargs implementation\n    { \"va_start\" },\n\n    // Builtin functions\n    { \"std\" },\n    { \"core\" },\n    { \"etc\" },\n    { \"attribute\" },\n    { \"math\" },\n    { \"sin\" },\n    { \"cos\" },\n    { \"tan\" },\n    { \"_sqrt\", \"sqrt\" },\n    { \"_pow\", \"pow\" },\n    { \"atan2\" },\n    { \"rndtol\" },\n    { \"expm1\" },\n    { \"exp2\" },\n    { \"yl2x\" },\n    { \"yl2xp1\" },\n    { \"fabs\" },\n    { \"bitop\" },\n    { \"bsf\" },\n    { \"bsr\" },\n    { \"bswap\" },\n\n    // Traits\n    { \"isAbstractClass\" },\n    { \"isArithmetic\" },\n    { \"isAssociativeArray\" },\n    { \"isFinalClass\" },\n    { \"isTemplate\" },\n    { \"isPOD\" },\n    { \"isDeprecated\" },\n    { \"isDisabled\" },\n    { \"isFuture\" },\n    { \"isNested\" },\n    { \"isFloating\" },\n    { \"isIntegral\" },\n    { \"isScalar\" },\n    { \"isStaticArray\" },\n    { \"isUnsigned\" },\n    { \"isVirtualFunction\" },\n    { \"isVirtualMethod\" },\n    { \"isAbstractFunction\" },\n    { \"isFinalFunction\" },\n    { \"isOverrideFunction\" },\n    { \"isStaticFunction\" },\n    { \"isRef\" },\n    { \"isOut\" },\n    { \"isLazy\" },\n    { \"hasMember\" },\n    { \"identifier\" },\n    { \"getProtection\" },\n    { \"parent\" },\n    { \"getMember\" },\n    { \"getOverloads\" },\n    { \"getVirtualFunctions\" },\n    { \"getVirtualMethods\" },\n    { \"classInstanceSize\" },\n    { \"allMembers\" },\n    { \"derivedMembers\" },\n    { \"isSame\" },\n    { \"compiles\" },\n    { \"parameters\" },\n    { \"getAliasThis\" },\n    { \"getAttributes\" },\n    { \"getFunctionAttributes\" },\n    { \"getFunctionVariadicStyle\" },\n    { \"getParameterStorageClasses\" },\n    { \"getLinkage\" },\n    { \"getUnitTests\" },\n    { \"getVirtualIndex\" },\n    { \"getPointerBitmap\" },\n    { \"isReturnOnStack\" },\n    { \"isZeroInit\" },\n    { \"getTargetInfo\" },\n\n    // For C++ mangling\n    { \"allocator\" },\n    { \"basic_string\" },\n    { \"basic_istream\" },\n    { \"basic_ostream\" },\n    { \"basic_iostream\" },\n    { \"char_traits\" },\n\n    // Compiler recognized UDA's\n    { \"udaSelector\", \"selector\" },\n\n    // C names, for undefined identifier error messages\n    { \"NULL\" },\n    { \"TRUE\" },\n    { \"FALSE\" },\n    { \"unsigned\" },\n    { \"wchar_t\" },\n];\n\n\n/*\n * Tuple of DMD source code identifier and symbol in the D executable.\n *\n * The first element of the tuple is the identifier to use in the DMD source\n * code and the second element, if present, is the name to use in the D\n * executable. If second element, `name`, is not present the identifier,\n * `ident`, will be used instead\n */\nstruct Msgtable\n{\n    // The identifier to use in the DMD source.\n    string ident;\n\n    // The name to use in the D executable\n    private string name_;\n\n    /*\n     * Returns: the name to use in the D executable, `name_` if non-empty,\n     *  otherwise `ident`\n     */\n    string name()\n    {\n        return name_ ? name_ : ident;\n    }\n}\n\n/*\n * Iterates the given Msgtable array, passes each element to the given lambda\n * and accumulates a string from each return value of calling the lambda.\n * Appends a newline character after each call to the lambda.\n */\nstring generate(immutable(Msgtable)[] msgtable, string function(Msgtable) dg)\n{\n    string code;\n\n    foreach (i, m ; msgtable)\n    {\n        if (i != 0)\n            code ~= '\\n';\n\n        code ~= dg(m);\n    }\n\n    return code;\n}\n\n// Used to generate the code for each identifier.\nstring identifier(Msgtable m)\n{\n    return \"Identifier \" ~ m.ident ~ \";\";\n}\n\n// Used to generate the code for each initializer.\nstring initializer(Msgtable m)\n{\n    return m.ident ~ ` = Identifier.idPool(\"` ~ m.name ~ `\");`;\n}\n"
  },
  {
    "path": "gcc/d/dmd/id.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 2017-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/id.h\n */\n\n#pragma once\n\nstruct Id\n{\n    static void initialize();\n};\n"
  },
  {
    "path": "gcc/d/dmd/identifier.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/identifier.d, _identifier.d)\n * Documentation:  https://dlang.org/phobos/dmd_identifier.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/identifier.d\n */\n\nmodule dmd.identifier;\n\nimport core.stdc.ctype;\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.root.stringtable;\nimport dmd.tokens;\nimport dmd.utf;\nimport dmd.utils;\n\n\n/***********************************************************\n */\nextern (C++) final class Identifier : RootObject\n{\nprivate:\n    const int value;\n    const char[] name;\n\npublic:\n    /**\n       Construct an identifier from a D slice\n\n       Note: Since `name` needs to be `\\0` terminated for `toChars`,\n       no slice overload is provided yet.\n\n       Params:\n         name = the identifier name\n                There must be `'\\0'` at `name[length]`.\n         length = the length of `name`, excluding the terminating `'\\0'`\n         value = Identifier value (e.g. `Id.unitTest`) or `TOK.identifier`\n     */\n    extern (D) this(const(char)* name, size_t length, int value) nothrow\n    {\n        //printf(\"Identifier('%s', %d)\\n\", name, value);\n        this.name = name[0 .. length];\n        this.value = value;\n    }\n\n    extern (D) this(const(char)* name) nothrow\n    {\n        //printf(\"Identifier('%s', %d)\\n\", name, value);\n        this(name, strlen(name), TOK.identifier);\n    }\n\n    static Identifier create(const(char)* name) nothrow\n    {\n        return new Identifier(name);\n    }\n\n    override bool equals(RootObject o) const\n    {\n        return this == o || name == o.toString();\n    }\n\n    override int compare(RootObject o) const\n    {\n        return strncmp(name.ptr, o.toChars(), name.length + 1);\n    }\n\nnothrow:\n    override const(char)* toChars() const pure\n    {\n        return name.ptr;\n    }\n\n    extern (D) override const(char)[] toString() const pure\n    {\n        return name;\n    }\n\n    int getValue() const pure\n    {\n        return value;\n    }\n\n    const(char)* toHChars2() const\n    {\n        const(char)* p = null;\n        if (this == Id.ctor)\n            p = \"this\";\n        else if (this == Id.dtor)\n            p = \"~this\";\n        else if (this == Id.unitTest)\n            p = \"unittest\";\n        else if (this == Id.dollar)\n            p = \"$\";\n        else if (this == Id.withSym)\n            p = \"with\";\n        else if (this == Id.result)\n            p = \"result\";\n        else if (this == Id.returnLabel)\n            p = \"return\";\n        else\n        {\n            p = toChars();\n            if (*p == '_')\n            {\n                if (strncmp(p, \"_staticCtor\", 11) == 0)\n                    p = \"static this\";\n                else if (strncmp(p, \"_staticDtor\", 11) == 0)\n                    p = \"static ~this\";\n                else if (strncmp(p, \"__invariant\", 11) == 0)\n                    p = \"invariant\";\n            }\n        }\n        return p;\n    }\n\n    override DYNCAST dyncast() const\n    {\n        return DYNCAST.identifier;\n    }\n\n    private extern (D) __gshared StringTable stringtable;\n\n    /**\n       A secondary string table is used to guarantee that we generate unique\n       identifiers per module. See generateIdWithLoc and issues\n       https://issues.dlang.org/show_bug.cgi?id=16995\n       https://issues.dlang.org/show_bug.cgi?id=18097\n       https://issues.dlang.org/show_bug.cgi?id=18111\n       https://issues.dlang.org/show_bug.cgi?id=18880\n       https://issues.dlang.org/show_bug.cgi?id=18868\n       https://issues.dlang.org/show_bug.cgi?id=19058.\n     */\n    private extern (D) __gshared StringTable fullPathStringTable;\n\n    static Identifier generateId(const(char)* prefix)\n    {\n        __gshared size_t i;\n        return generateId(prefix, ++i);\n    }\n\n    static Identifier generateId(const(char)* prefix, size_t i)\n    {\n        OutBuffer buf;\n        buf.writestring(prefix);\n        buf.print(i);\n        return idPool(buf.peekSlice());\n    }\n\n    /***************************************\n     * Generate deterministic named identifier based on a source location,\n     * such that the name is consistent across multiple compilations.\n     * A new unique name is generated. If the prefix+location is already in\n     * the stringtable, an extra suffix is added (starting the count at \"_1\").\n     *\n     * Params:\n     *      prefix      = first part of the identifier name.\n     *      loc         = source location to use in the identifier name.\n     * Returns:\n     *      Identifier (inside Identifier.idPool) with deterministic name based\n     *      on the source location.\n     */\n    extern (D) static Identifier generateIdWithLoc(string prefix, const ref Loc loc)\n    {\n        import dmd.root.filename: absPathThen;\n\n        // see below for why we use absPathThen\n        return loc.filename.toDString().absPathThen!((absPath)\n        {\n            // this block generates the \"regular\" identifier, i.e. if there are no collisions\n            OutBuffer idBuf;\n            idBuf.writestring(prefix);\n            idBuf.writestring(\"_L\");\n            idBuf.print(loc.linnum);\n            idBuf.writestring(\"_C\");\n            idBuf.print(loc.charnum);\n\n            // This block generates an identifier that is prefixed by the absolute path of the file\n            // being compiled. The reason this is necessary is that we want unique identifiers per\n            // module, but the identifiers are generated before the module information is available.\n            // To guarantee that each generated identifier is unique without modules, we make them\n            // unique to each absolute file path. This also makes it consistent even if the files\n            // are compiled separately. See issues:\n            // https://issues.dlang.org/show_bug.cgi?id=16995\n            // https://issues.dlang.org/show_bug.cgi?id=18097\n            // https://issues.dlang.org/show_bug.cgi?id=18111\n            // https://issues.dlang.org/show_bug.cgi?id=18880\n            // https://issues.dlang.org/show_bug.cgi?id=18868\n            // https://issues.dlang.org/show_bug.cgi?id=19058.\n            OutBuffer fullPathIdBuf;\n\n            if (absPath)\n            {\n                // replace characters that demangle can't handle\n                foreach (ref c; absPath)\n                {\n                    // see dmd.dmangle.isValidMangling\n                    // Unfortunately importing it leads to either build failures or cyclic dependencies\n                    // between modules.\n                    if (c == '/' || c == '\\\\' || c == '.' || c == '?' || c == ':')\n                        c = '_';\n                }\n\n                fullPathIdBuf.writestring(absPath);\n                fullPathIdBuf.writestring(\"_\");\n            }\n\n            fullPathIdBuf.writestring(idBuf.peekSlice());\n            const fullPathIdLength = fullPathIdBuf.peekSlice().length;\n            uint counter = 1;\n\n            // loop until we can't find the absolute path ~ identifier, adding a counter suffix each time\n            while (fullPathStringTable.lookup(fullPathIdBuf.peekSlice()) !is null)\n            {\n                // Strip the counter suffix if any\n                fullPathIdBuf.setsize(fullPathIdLength);\n                // Add new counter suffix\n                fullPathIdBuf.writestring(\"_\");\n                fullPathIdBuf.print(counter++);\n            }\n\n            // `idStartIndex` is the start of the \"true\" identifier. We don't actually use the absolute\n            // file path in the generated identifier since the module system makes sure that the fully\n            // qualified name is unique.\n            const idStartIndex = fullPathIdLength - idBuf.peekSlice().length;\n\n            // Remember the full path identifier to avoid possible future collisions\n            fullPathStringTable.insert(fullPathIdBuf.peekSlice(),\n                                       null);\n\n            return idPool(fullPathIdBuf.peekSlice()[idStartIndex .. $]);\n        });\n    }\n\n    /********************************************\n     * Create an identifier in the string table.\n     */\n    extern (D) static Identifier idPool(const(char)[] s)\n    {\n        return idPool(s.ptr, cast(uint)s.length);\n    }\n\n    static Identifier idPool(const(char)* s, uint len)\n    {\n        StringValue* sv = stringtable.update(s, len);\n        Identifier id = cast(Identifier)sv.ptrvalue;\n        if (!id)\n        {\n            id = new Identifier(sv.toDchars(), len, TOK.identifier);\n            sv.ptrvalue = cast(char*)id;\n        }\n        return id;\n    }\n\n    extern (D) static Identifier idPool(const(char)* s, size_t len, int value)\n    {\n        auto sv = stringtable.insert(s, len, null);\n        assert(sv);\n        auto id = new Identifier(sv.toDchars(), len, value);\n        sv.ptrvalue = cast(char*)id;\n        return id;\n    }\n\n    /**********************************\n     * Determine if string is a valid Identifier.\n     * Returns:\n     *      0       invalid\n     */\n    static bool isValidIdentifier(const(char)* p)\n    {\n        if (!p || !*p)\n            return false;\n        return isValidIdentifier(p.toDString);\n    }\n\n    /**********************************\n     * ditto\n     */\n    extern (D) static bool isValidIdentifier(const(char)[] str)\n    {\n        const(char)* p = str.ptr;\n        size_t len = str.length;\n        size_t idx = 0;\n        if (!p || len == 0)\n            goto Linvalid;\n        if (*p >= '0' && *p <= '9') // beware of isdigit() on signed chars\n            goto Linvalid;\n        while (idx < len)\n        {\n            dchar dc;\n            const q = utf_decodeChar(p, len, idx, dc);\n            if (q)\n                goto Linvalid;\n            if (!((dc >= 0x80 && isUniAlpha(dc)) || isalnum(dc) || dc == '_'))\n                goto Linvalid;\n        }\n        return true;\n    Linvalid:\n        return false;\n    }\n\n    extern (D) static Identifier lookup(const(char)* s, size_t len)\n    {\n        auto sv = stringtable.lookup(s, len);\n        if (!sv)\n            return null;\n        return cast(Identifier)sv.ptrvalue;\n    }\n\n    extern (D) static void initTable()\n    {\n        enum size = 28_000;\n        stringtable._init(size);\n        fullPathStringTable._init(size);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/identifier.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/identifier.h\n */\n\n#pragma once\n\n#include \"root/dcompat.h\"\n#include \"root/root.h\"\n\nclass Identifier : public RootObject\n{\nprivate:\n    int value;\n    DArray<const char> string;\n\npublic:\n    static Identifier* create(const char *string);\n    bool equals(RootObject *o);\n    int compare(RootObject *o);\n    const char *toChars();\n    int getValue() const;\n    const char *toHChars2();\n    int dyncast() const;\n\n    static Identifier *generateId(const char *prefix);\n    static Identifier *generateId(const char *prefix, size_t i);\n    static Identifier *idPool(const char *s, unsigned len);\n\n    static inline Identifier *idPool(const char *s)\n    {\n        return idPool(s, strlen(s));\n    }\n\n    static bool isValidIdentifier(const char *p);\n};\n"
  },
  {
    "path": "gcc/d/dmd/impcnvtab.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/impcnvtab.d, _impcnvtab.d)\n * Documentation:  https://dlang.org/phobos/dmd_impcnvtab.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/impcnvtab.d\n */\n\nmodule dmd.impcnvtab;\n\nimport dmd.mtype;\n\nimmutable ENUMTY[TMAX][TMAX] impcnvResult = impCnvTab.impcnvResultTab;\nimmutable ENUMTY[TMAX][TMAX] impcnvType1 = impCnvTab.impcnvType1Tab;\nimmutable ENUMTY[TMAX][TMAX] impcnvType2 = impCnvTab.impcnvType2Tab;\n\nprivate:\n\nstruct ImpCnvTab\n{\n    ENUMTY[TMAX][TMAX] impcnvResultTab;\n    ENUMTY[TMAX][TMAX] impcnvType1Tab;\n    ENUMTY[TMAX][TMAX] impcnvType2Tab;\n}\n\nenum ImpCnvTab impCnvTab = generateImpCnvTab();\n\nImpCnvTab generateImpCnvTab()\n{\n    ImpCnvTab impCnvTab;\n\n    // Set conversion tables\n    foreach (i; 0 .. cast(size_t)TMAX)\n    {\n        foreach (j; 0 .. cast(size_t)TMAX)\n        {\n            impCnvTab.impcnvResultTab[i][j] = Terror;\n            impCnvTab.impcnvType1Tab[i][j] = Terror;\n            impCnvTab.impcnvType2Tab[i][j] = Terror;\n        }\n    }\n\n    void X(ENUMTY t1, ENUMTY t2, ENUMTY nt1, ENUMTY nt2, ENUMTY rt)\n    {\n        impCnvTab.impcnvResultTab[t1][t2] = rt;\n        impCnvTab.impcnvType1Tab[t1][t2] = nt1;\n        impCnvTab.impcnvType2Tab[t1][t2] = nt2;\n    }\n\n    /* ======================= */\n\n    X(Tbool,Tbool,   Tbool,Tbool,    Tbool);\n    X(Tbool,Tint8,   Tint32,Tint32,  Tint32);\n    X(Tbool,Tuns8,   Tint32,Tint32,  Tint32);\n    X(Tbool,Tint16,  Tint32,Tint32,  Tint32);\n    X(Tbool,Tuns16,  Tint32,Tint32,  Tint32);\n    X(Tbool,Tint32,  Tint32,Tint32,  Tint32);\n    X(Tbool,Tuns32,  Tuns32,Tuns32,  Tuns32);\n    X(Tbool,Tint64,  Tint64,Tint64,  Tint64);\n    X(Tbool,Tuns64,  Tuns64,Tuns64,  Tuns64);\n    X(Tbool,Tint128, Tint128,Tint128, Tint128);\n    X(Tbool,Tuns128, Tuns128,Tuns128, Tuns128);\n\n    X(Tbool,Tfloat32,     Tfloat32,Tfloat32,     Tfloat32);\n    X(Tbool,Tfloat64,     Tfloat64,Tfloat64,     Tfloat64);\n    X(Tbool,Tfloat80,     Tfloat80,Tfloat80,     Tfloat80);\n    X(Tbool,Timaginary32, Tfloat32,Timaginary32, Tfloat32);\n    X(Tbool,Timaginary64, Tfloat64,Timaginary64, Tfloat64);\n    X(Tbool,Timaginary80, Tfloat80,Timaginary80, Tfloat80);\n    X(Tbool,Tcomplex32,   Tfloat32,Tcomplex32,   Tcomplex32);\n    X(Tbool,Tcomplex64,   Tfloat64,Tcomplex64,   Tcomplex64);\n    X(Tbool,Tcomplex80,   Tfloat80,Tcomplex80,   Tcomplex80);\n\n    /* ======================= */\n\n    X(Tint8,Tint8,   Tint32,Tint32,  Tint32);\n    X(Tint8,Tuns8,   Tint32,Tint32,  Tint32);\n    X(Tint8,Tint16,  Tint32,Tint32,  Tint32);\n    X(Tint8,Tuns16,  Tint32,Tint32,  Tint32);\n    X(Tint8,Tint32,  Tint32,Tint32,  Tint32);\n    X(Tint8,Tuns32,  Tuns32,Tuns32,  Tuns32);\n    X(Tint8,Tint64,  Tint64,Tint64,  Tint64);\n    X(Tint8,Tuns64,  Tuns64,Tuns64,  Tuns64);\n    X(Tint8,Tint128, Tint128,Tint128, Tint128);\n    X(Tint8,Tuns128, Tuns128,Tuns128, Tuns128);\n\n    X(Tint8,Tfloat32,     Tfloat32,Tfloat32,     Tfloat32);\n    X(Tint8,Tfloat64,     Tfloat64,Tfloat64,     Tfloat64);\n    X(Tint8,Tfloat80,     Tfloat80,Tfloat80,     Tfloat80);\n    X(Tint8,Timaginary32, Tfloat32,Timaginary32, Tfloat32);\n    X(Tint8,Timaginary64, Tfloat64,Timaginary64, Tfloat64);\n    X(Tint8,Timaginary80, Tfloat80,Timaginary80, Tfloat80);\n    X(Tint8,Tcomplex32,   Tfloat32,Tcomplex32,   Tcomplex32);\n    X(Tint8,Tcomplex64,   Tfloat64,Tcomplex64,   Tcomplex64);\n    X(Tint8,Tcomplex80,   Tfloat80,Tcomplex80,   Tcomplex80);\n\n    /* ======================= */\n\n    X(Tuns8,Tuns8,   Tint32,Tint32,  Tint32);\n    X(Tuns8,Tint16,  Tint32,Tint32,  Tint32);\n    X(Tuns8,Tuns16,  Tint32,Tint32,  Tint32);\n    X(Tuns8,Tint32,  Tint32,Tint32,  Tint32);\n    X(Tuns8,Tuns32,  Tuns32,Tuns32,  Tuns32);\n    X(Tuns8,Tint64,  Tint64,Tint64,  Tint64);\n    X(Tuns8,Tuns64,  Tuns64,Tuns64,  Tuns64);\n    X(Tuns8,Tint128,  Tint128,Tint128,  Tint128);\n    X(Tuns8,Tuns128,  Tuns128,Tuns128,  Tuns128);\n\n    X(Tuns8,Tfloat32,     Tfloat32,Tfloat32,     Tfloat32);\n    X(Tuns8,Tfloat64,     Tfloat64,Tfloat64,     Tfloat64);\n    X(Tuns8,Tfloat80,     Tfloat80,Tfloat80,     Tfloat80);\n    X(Tuns8,Timaginary32, Tfloat32,Timaginary32, Tfloat32);\n    X(Tuns8,Timaginary64, Tfloat64,Timaginary64, Tfloat64);\n    X(Tuns8,Timaginary80, Tfloat80,Timaginary80, Tfloat80);\n    X(Tuns8,Tcomplex32,   Tfloat32,Tcomplex32,   Tcomplex32);\n    X(Tuns8,Tcomplex64,   Tfloat64,Tcomplex64,   Tcomplex64);\n    X(Tuns8,Tcomplex80,   Tfloat80,Tcomplex80,   Tcomplex80);\n\n    /* ======================= */\n\n    X(Tint16,Tint16,  Tint32,Tint32,  Tint32);\n    X(Tint16,Tuns16,  Tint32,Tint32,  Tint32);\n    X(Tint16,Tint32,  Tint32,Tint32,  Tint32);\n    X(Tint16,Tuns32,  Tuns32,Tuns32,  Tuns32);\n    X(Tint16,Tint64,  Tint64,Tint64,  Tint64);\n    X(Tint16,Tuns64,  Tuns64,Tuns64,  Tuns64);\n    X(Tint16,Tint128,  Tint128,Tint128,  Tint128);\n    X(Tint16,Tuns128,  Tuns128,Tuns128,  Tuns128);\n\n    X(Tint16,Tfloat32,     Tfloat32,Tfloat32,     Tfloat32);\n    X(Tint16,Tfloat64,     Tfloat64,Tfloat64,     Tfloat64);\n    X(Tint16,Tfloat80,     Tfloat80,Tfloat80,     Tfloat80);\n    X(Tint16,Timaginary32, Tfloat32,Timaginary32, Tfloat32);\n    X(Tint16,Timaginary64, Tfloat64,Timaginary64, Tfloat64);\n    X(Tint16,Timaginary80, Tfloat80,Timaginary80, Tfloat80);\n    X(Tint16,Tcomplex32,   Tfloat32,Tcomplex32,   Tcomplex32);\n    X(Tint16,Tcomplex64,   Tfloat64,Tcomplex64,   Tcomplex64);\n    X(Tint16,Tcomplex80,   Tfloat80,Tcomplex80,   Tcomplex80);\n\n    /* ======================= */\n\n    X(Tuns16,Tuns16,  Tint32,Tint32,  Tint32);\n    X(Tuns16,Tint32,  Tint32,Tint32,  Tint32);\n    X(Tuns16,Tuns32,  Tuns32,Tuns32,  Tuns32);\n    X(Tuns16,Tint64,  Tint64,Tint64,  Tint64);\n    X(Tuns16,Tuns64,  Tuns64,Tuns64,  Tuns64);\n    X(Tuns16,Tint128, Tint128,Tint128,  Tint128);\n    X(Tuns16,Tuns128, Tuns128,Tuns128,  Tuns128);\n\n    X(Tuns16,Tfloat32,     Tfloat32,Tfloat32,     Tfloat32);\n    X(Tuns16,Tfloat64,     Tfloat64,Tfloat64,     Tfloat64);\n    X(Tuns16,Tfloat80,     Tfloat80,Tfloat80,     Tfloat80);\n    X(Tuns16,Timaginary32, Tfloat32,Timaginary32, Tfloat32);\n    X(Tuns16,Timaginary64, Tfloat64,Timaginary64, Tfloat64);\n    X(Tuns16,Timaginary80, Tfloat80,Timaginary80, Tfloat80);\n    X(Tuns16,Tcomplex32,   Tfloat32,Tcomplex32,   Tcomplex32);\n    X(Tuns16,Tcomplex64,   Tfloat64,Tcomplex64,   Tcomplex64);\n    X(Tuns16,Tcomplex80,   Tfloat80,Tcomplex80,   Tcomplex80);\n\n    /* ======================= */\n\n    X(Tint32,Tint32,  Tint32,Tint32,  Tint32);\n    X(Tint32,Tuns32,  Tuns32,Tuns32,  Tuns32);\n    X(Tint32,Tint64,  Tint64,Tint64,  Tint64);\n    X(Tint32,Tuns64,  Tuns64,Tuns64,  Tuns64);\n    X(Tint32,Tint128, Tint128,Tint128,  Tint128);\n    X(Tint32,Tuns128, Tuns128,Tuns128,  Tuns128);\n\n    X(Tint32,Tfloat32,     Tfloat32,Tfloat32,     Tfloat32);\n    X(Tint32,Tfloat64,     Tfloat64,Tfloat64,     Tfloat64);\n    X(Tint32,Tfloat80,     Tfloat80,Tfloat80,     Tfloat80);\n    X(Tint32,Timaginary32, Tfloat32,Timaginary32, Tfloat32);\n    X(Tint32,Timaginary64, Tfloat64,Timaginary64, Tfloat64);\n    X(Tint32,Timaginary80, Tfloat80,Timaginary80, Tfloat80);\n    X(Tint32,Tcomplex32,   Tfloat32,Tcomplex32,   Tcomplex32);\n    X(Tint32,Tcomplex64,   Tfloat64,Tcomplex64,   Tcomplex64);\n    X(Tint32,Tcomplex80,   Tfloat80,Tcomplex80,   Tcomplex80);\n\n    /* ======================= */\n\n    X(Tuns32,Tuns32,  Tuns32,Tuns32,  Tuns32);\n    X(Tuns32,Tint64,  Tint64,Tint64,  Tint64);\n    X(Tuns32,Tuns64,  Tuns64,Tuns64,  Tuns64);\n    X(Tuns32,Tint128,  Tint128,Tint128,  Tint128);\n    X(Tuns32,Tuns128,  Tuns128,Tuns128,  Tuns128);\n\n    X(Tuns32,Tfloat32,     Tfloat32,Tfloat32,     Tfloat32);\n    X(Tuns32,Tfloat64,     Tfloat64,Tfloat64,     Tfloat64);\n    X(Tuns32,Tfloat80,     Tfloat80,Tfloat80,     Tfloat80);\n    X(Tuns32,Timaginary32, Tfloat32,Timaginary32, Tfloat32);\n    X(Tuns32,Timaginary64, Tfloat64,Timaginary64, Tfloat64);\n    X(Tuns32,Timaginary80, Tfloat80,Timaginary80, Tfloat80);\n    X(Tuns32,Tcomplex32,   Tfloat32,Tcomplex32,   Tcomplex32);\n    X(Tuns32,Tcomplex64,   Tfloat64,Tcomplex64,   Tcomplex64);\n    X(Tuns32,Tcomplex80,   Tfloat80,Tcomplex80,   Tcomplex80);\n\n    /* ======================= */\n\n    X(Tint64,Tint64,  Tint64,Tint64,  Tint64);\n    X(Tint64,Tuns64,  Tuns64,Tuns64,  Tuns64);\n    X(Tint64,Tint128,  Tint128,Tint128,  Tint128);\n    X(Tint64,Tuns128,  Tuns128,Tuns128,  Tuns128);\n\n    X(Tint64,Tfloat32,     Tfloat32,Tfloat32,     Tfloat32);\n    X(Tint64,Tfloat64,     Tfloat64,Tfloat64,     Tfloat64);\n    X(Tint64,Tfloat80,     Tfloat80,Tfloat80,     Tfloat80);\n    X(Tint64,Timaginary32, Tfloat32,Timaginary32, Tfloat32);\n    X(Tint64,Timaginary64, Tfloat64,Timaginary64, Tfloat64);\n    X(Tint64,Timaginary80, Tfloat80,Timaginary80, Tfloat80);\n    X(Tint64,Tcomplex32,   Tfloat32,Tcomplex32,   Tcomplex32);\n    X(Tint64,Tcomplex64,   Tfloat64,Tcomplex64,   Tcomplex64);\n    X(Tint64,Tcomplex80,   Tfloat80,Tcomplex80,   Tcomplex80);\n\n    /* ======================= */\n\n    X(Tuns64,Tuns64,  Tuns64,Tuns64,  Tuns64);\n    X(Tuns64,Tint128,  Tint128,Tint128,  Tint128);\n    X(Tuns64,Tuns128,  Tuns128,Tuns128,  Tuns128);\n\n    X(Tuns64,Tfloat32,     Tfloat32,Tfloat32,     Tfloat32);\n    X(Tuns64,Tfloat64,     Tfloat64,Tfloat64,     Tfloat64);\n    X(Tuns64,Tfloat80,     Tfloat80,Tfloat80,     Tfloat80);\n    X(Tuns64,Timaginary32, Tfloat32,Timaginary32, Tfloat32);\n    X(Tuns64,Timaginary64, Tfloat64,Timaginary64, Tfloat64);\n    X(Tuns64,Timaginary80, Tfloat80,Timaginary80, Tfloat80);\n    X(Tuns64,Tcomplex32,   Tfloat32,Tcomplex32,   Tcomplex32);\n    X(Tuns64,Tcomplex64,   Tfloat64,Tcomplex64,   Tcomplex64);\n    X(Tuns64,Tcomplex80,   Tfloat80,Tcomplex80,   Tcomplex80);\n\n    /* ======================= */\n\n    X(Tint128,Tint128,  Tint128,Tint128,  Tint128);\n    X(Tint128,Tuns128,  Tuns128,Tuns128,  Tuns128);\n\n    X(Tint128,Tfloat32,     Tfloat32,Tfloat32,     Tfloat32);\n    X(Tint128,Tfloat64,     Tfloat64,Tfloat64,     Tfloat64);\n    X(Tint128,Tfloat80,     Tfloat80,Tfloat80,     Tfloat80);\n    X(Tint128,Timaginary32, Tfloat32,Timaginary32, Tfloat32);\n    X(Tint128,Timaginary64, Tfloat64,Timaginary64, Tfloat64);\n    X(Tint128,Timaginary80, Tfloat80,Timaginary80, Tfloat80);\n    X(Tint128,Tcomplex32,   Tfloat32,Tcomplex32,   Tcomplex32);\n    X(Tint128,Tcomplex64,   Tfloat64,Tcomplex64,   Tcomplex64);\n    X(Tint128,Tcomplex80,   Tfloat80,Tcomplex80,   Tcomplex80);\n\n    /* ======================= */\n\n    X(Tuns128,Tuns128,  Tuns128,Tuns128,  Tuns128);\n\n    X(Tuns128,Tfloat32,     Tfloat32,Tfloat32,     Tfloat32);\n    X(Tuns128,Tfloat64,     Tfloat64,Tfloat64,     Tfloat64);\n    X(Tuns128,Tfloat80,     Tfloat80,Tfloat80,     Tfloat80);\n    X(Tuns128,Timaginary32, Tfloat32,Timaginary32, Tfloat32);\n    X(Tuns128,Timaginary64, Tfloat64,Timaginary64, Tfloat64);\n    X(Tuns128,Timaginary80, Tfloat80,Timaginary80, Tfloat80);\n    X(Tuns128,Tcomplex32,   Tfloat32,Tcomplex32,   Tcomplex32);\n    X(Tuns128,Tcomplex64,   Tfloat64,Tcomplex64,   Tcomplex64);\n    X(Tuns128,Tcomplex80,   Tfloat80,Tcomplex80,   Tcomplex80);\n\n    /* ======================= */\n\n    X(Tfloat32,Tfloat32,  Tfloat32,Tfloat32, Tfloat32);\n    X(Tfloat32,Tfloat64,  Tfloat64,Tfloat64, Tfloat64);\n    X(Tfloat32,Tfloat80,  Tfloat80,Tfloat80, Tfloat80);\n\n    X(Tfloat32,Timaginary32,  Tfloat32,Timaginary32, Tfloat32);\n    X(Tfloat32,Timaginary64,  Tfloat64,Timaginary64, Tfloat64);\n    X(Tfloat32,Timaginary80,  Tfloat80,Timaginary80, Tfloat80);\n\n    X(Tfloat32,Tcomplex32,  Tfloat32,Tcomplex32, Tcomplex32);\n    X(Tfloat32,Tcomplex64,  Tfloat64,Tcomplex64, Tcomplex64);\n    X(Tfloat32,Tcomplex80,  Tfloat80,Tcomplex80, Tcomplex80);\n\n    /* ======================= */\n\n    X(Tfloat64,Tfloat64,  Tfloat64,Tfloat64, Tfloat64);\n    X(Tfloat64,Tfloat80,  Tfloat80,Tfloat80, Tfloat80);\n\n    X(Tfloat64,Timaginary32,  Tfloat64,Timaginary64, Tfloat64);\n    X(Tfloat64,Timaginary64,  Tfloat64,Timaginary64, Tfloat64);\n    X(Tfloat64,Timaginary80,  Tfloat80,Timaginary80, Tfloat80);\n\n    X(Tfloat64,Tcomplex32,  Tfloat64,Tcomplex64, Tcomplex64);\n    X(Tfloat64,Tcomplex64,  Tfloat64,Tcomplex64, Tcomplex64);\n    X(Tfloat64,Tcomplex80,  Tfloat80,Tcomplex80, Tcomplex80);\n\n    /* ======================= */\n\n    X(Tfloat80,Tfloat80,  Tfloat80,Tfloat80, Tfloat80);\n\n    X(Tfloat80,Timaginary32,  Tfloat80,Timaginary80, Tfloat80);\n    X(Tfloat80,Timaginary64,  Tfloat80,Timaginary80, Tfloat80);\n    X(Tfloat80,Timaginary80,  Tfloat80,Timaginary80, Tfloat80);\n\n    X(Tfloat80,Tcomplex32,  Tfloat80,Tcomplex80, Tcomplex80);\n    X(Tfloat80,Tcomplex64,  Tfloat80,Tcomplex80, Tcomplex80);\n    X(Tfloat80,Tcomplex80,  Tfloat80,Tcomplex80, Tcomplex80);\n\n    /* ======================= */\n\n    X(Timaginary32,Timaginary32,  Timaginary32,Timaginary32, Timaginary32);\n    X(Timaginary32,Timaginary64,  Timaginary64,Timaginary64, Timaginary64);\n    X(Timaginary32,Timaginary80,  Timaginary80,Timaginary80, Timaginary80);\n\n    X(Timaginary32,Tcomplex32,  Timaginary32,Tcomplex32, Tcomplex32);\n    X(Timaginary32,Tcomplex64,  Timaginary64,Tcomplex64, Tcomplex64);\n    X(Timaginary32,Tcomplex80,  Timaginary80,Tcomplex80, Tcomplex80);\n\n    /* ======================= */\n\n    X(Timaginary64,Timaginary64,  Timaginary64,Timaginary64, Timaginary64);\n    X(Timaginary64,Timaginary80,  Timaginary80,Timaginary80, Timaginary80);\n\n    X(Timaginary64,Tcomplex32,  Timaginary64,Tcomplex64, Tcomplex64);\n    X(Timaginary64,Tcomplex64,  Timaginary64,Tcomplex64, Tcomplex64);\n    X(Timaginary64,Tcomplex80,  Timaginary80,Tcomplex80, Tcomplex80);\n\n    /* ======================= */\n\n    X(Timaginary80,Timaginary80,  Timaginary80,Timaginary80, Timaginary80);\n\n    X(Timaginary80,Tcomplex32,  Timaginary80,Tcomplex80, Tcomplex80);\n    X(Timaginary80,Tcomplex64,  Timaginary80,Tcomplex80, Tcomplex80);\n    X(Timaginary80,Tcomplex80,  Timaginary80,Tcomplex80, Tcomplex80);\n\n    /* ======================= */\n\n    X(Tcomplex32,Tcomplex32,  Tcomplex32,Tcomplex32, Tcomplex32);\n    X(Tcomplex32,Tcomplex64,  Tcomplex64,Tcomplex64, Tcomplex64);\n    X(Tcomplex32,Tcomplex80,  Tcomplex80,Tcomplex80, Tcomplex80);\n\n    /* ======================= */\n\n    X(Tcomplex64,Tcomplex64,  Tcomplex64,Tcomplex64, Tcomplex64);\n    X(Tcomplex64,Tcomplex80,  Tcomplex80,Tcomplex80, Tcomplex80);\n\n    /* ======================= */\n\n    X(Tcomplex80,Tcomplex80,  Tcomplex80,Tcomplex80, Tcomplex80);\n\n    foreach (i; 0 .. cast(size_t)TMAX)\n    {\n        foreach (j; 0 .. cast(size_t)TMAX)\n        {\n            if (impCnvTab.impcnvResultTab[i][j] == Terror)\n            {\n                impCnvTab.impcnvResultTab[i][j] = impCnvTab.impcnvResultTab[j][i];\n                impCnvTab.impcnvType1Tab[i][j] = impCnvTab.impcnvType2Tab[j][i];\n                impCnvTab.impcnvType2Tab[i][j] = impCnvTab.impcnvType1Tab[j][i];\n            }\n        }\n    }\n\n    return impCnvTab;\n}\n"
  },
  {
    "path": "gcc/d/dmd/imphint.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/imphint.d, _imphint.d)\n * Documentation:  https://dlang.org/phobos/dmd_imphint.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/imphint.d\n */\n\nmodule dmd.imphint;\n\nimport dmd.utils;\n\n/******************************************\n * Looks for undefined identifier s to see\n * if it might be undefined because an import\n * was not specified.\n * Not meant to be a comprehensive list of names in each module,\n * just the most common ones.\n */\nconst(char)[] importHint(const(char)[] s)\n{\n    if (auto entry = s in hints)\n        return *entry;\n    return null;\n}\n\nprivate immutable string[string] hints;\n\nshared static this()\n{\n    // in alphabetic order\n    hints = [\n        \"calloc\": \"core.stdc.stdlib\",\n        \"cos\": \"std.math\",\n        \"fabs\": \"std.math\",\n        \"free\": \"core.stdc.stdlib\",\n        \"malloc\": \"core.stdc.stdlib\",\n        \"printf\": \"core.stdc.stdio\",\n        \"realloc\": \"core.stdc.stdlib\",\n        \"sin\": \"std.math\",\n        \"sqrt\": \"std.math\",\n        \"writefln\": \"std.stdio\",\n        \"writeln\": \"std.stdio\",\n        \"__va_argsave_t\": \"core.vararg\",\n    ];\n}\n\nunittest\n{\n    assert(importHint(\"printf\") !is null);\n    assert(importHint(\"fabs\") !is null);\n    assert(importHint(\"xxxxx\") is null);\n}\n"
  },
  {
    "path": "gcc/d/dmd/import.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/import.h\n */\n\n#pragma once\n\n#include \"dsymbol.h\"\n\nclass Identifier;\nstruct Scope;\nclass Module;\nclass Package;\n\nclass Import : public Dsymbol\n{\npublic:\n    /* static import aliasId = pkg1.pkg2.id : alias1 = name1, alias2 = name2;\n     */\n\n    Identifiers *packages;      // array of Identifier's representing packages\n    Identifier *id;             // module Identifier\n    Identifier *aliasId;\n    int isstatic;               // !=0 if static import\n    Prot protection;\n\n    // Pairs of alias=name to bind into current namespace\n    Identifiers names;\n    Identifiers aliases;\n\n    Module *mod;\n    Package *pkg;               // leftmost package/module\n\n    AliasDeclarations aliasdecls; // corresponding AliasDeclarations for alias=name pairs\n\n    void addAlias(Identifier *name, Identifier *alias);\n    const char *kind() const;\n    Prot prot();\n    Dsymbol *syntaxCopy(Dsymbol *s);    // copy only syntax trees\n    void load(Scope *sc);\n    void importAll(Scope *sc);\n    Dsymbol *toAlias();\n    void addMember(Scope *sc, ScopeDsymbol *sds);\n    void setScope(Scope* sc);\n    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);\n    bool overloadInsert(Dsymbol *s);\n\n    Import *isImport() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n"
  },
  {
    "path": "gcc/d/dmd/init.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/init.d, _init.d)\n * Documentation:  https://dlang.org/phobos/dmd_init.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/init.d\n */\n\nmodule dmd.init;\n\nimport core.stdc.stdio;\nimport core.checkedint;\n\nimport dmd.arraytypes;\nimport dmd.dsymbol;\nimport dmd.expression;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.tokens;\nimport dmd.visitor;\n\nenum NeedInterpret : int\n{\n    INITnointerpret,\n    INITinterpret,\n}\n\nalias INITnointerpret = NeedInterpret.INITnointerpret;\nalias INITinterpret = NeedInterpret.INITinterpret;\n\n/*************\n * Discriminant for which kind of initializer\n */\nenum InitKind : ubyte\n{\n    void_,\n    error,\n    struct_,\n    array,\n    exp,\n}\n\n/***********************************************************\n */\nextern (C++) class Initializer : RootObject\n{\n    Loc loc;\n    InitKind kind;\n\n\n    extern (D) this(const ref Loc loc, InitKind kind)\n    {\n        this.loc = loc;\n        this.kind = kind;\n    }\n\n    override final const(char)* toChars()\n    {\n        OutBuffer buf;\n        HdrGenState hgs;\n        .toCBuffer(this, &buf, &hgs);\n        return buf.extractString();\n    }\n\n    final inout(ErrorInitializer) isErrorInitializer() inout pure\n    {\n        // Use void* cast to skip dynamic casting call\n        return kind == InitKind.error ? cast(inout ErrorInitializer)cast(void*)this : null;\n    }\n\n    final inout(VoidInitializer) isVoidInitializer() inout pure\n    {\n        return kind == InitKind.void_ ? cast(inout VoidInitializer)cast(void*)this : null;\n    }\n\n    final inout(StructInitializer) isStructInitializer() inout pure\n    {\n        return kind == InitKind.struct_ ? cast(inout StructInitializer)cast(void*)this : null;\n    }\n\n    final inout(ArrayInitializer) isArrayInitializer() inout pure\n    {\n        return kind == InitKind.array ? cast(inout ArrayInitializer)cast(void*)this : null;\n    }\n\n    final inout(ExpInitializer) isExpInitializer() inout pure\n    {\n        return kind == InitKind.exp ? cast(inout ExpInitializer)cast(void*)this : null;\n    }\n\n    void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class VoidInitializer : Initializer\n{\n    Type type;      // type that this will initialize to\n\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc, InitKind.void_);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ErrorInitializer : Initializer\n{\n    extern (D) this()\n    {\n        super(Loc.initial, InitKind.error);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class StructInitializer : Initializer\n{\n    Identifiers field;      // of Identifier *'s\n    Initializers value;     // parallel array of Initializer *'s\n\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc, InitKind.struct_);\n    }\n\n    void addInit(Identifier field, Initializer value)\n    {\n        //printf(\"StructInitializer::addInit(field = %p, value = %p)\\n\", field, value);\n        this.field.push(field);\n        this.value.push(value);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ArrayInitializer : Initializer\n{\n    Expressions index;      // indices\n    Initializers value;     // of Initializer *'s\n    uint dim;               // length of array being initialized\n    Type type;              // type that array will be used to initialize\n    bool sem;               // true if semantic() is run\n\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc, InitKind.array);\n    }\n\n    void addInit(Expression index, Initializer value)\n    {\n        this.index.push(index);\n        this.value.push(value);\n        dim = 0;\n        type = null;\n    }\n\n    bool isAssociativeArray()\n    {\n        for (size_t i = 0; i < value.dim; i++)\n        {\n            if (index[i])\n                return true;\n        }\n        return false;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ExpInitializer : Initializer\n{\n    bool expandTuples;\n    Expression exp;\n\n    extern (D) this(const ref Loc loc, Expression exp)\n    {\n        super(loc, InitKind.exp);\n        this.exp = exp;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\nversion (all)\n{\n    extern (C++) bool hasNonConstPointers(Expression e)\n    {\n        static bool checkArray(Expressions* elems)\n        {\n            foreach (e; *elems)\n            {\n                if (e && hasNonConstPointers(e))\n                    return true;\n            }\n            return false;\n        }\n\n        if (e.type.ty == Terror)\n            return false;\n        if (e.op == TOK.null_)\n            return false;\n        if (e.op == TOK.structLiteral)\n        {\n            StructLiteralExp se = cast(StructLiteralExp)e;\n            return checkArray(se.elements);\n        }\n        if (e.op == TOK.arrayLiteral)\n        {\n            if (!e.type.nextOf().hasPointers())\n                return false;\n            ArrayLiteralExp ae = cast(ArrayLiteralExp)e;\n            return checkArray(ae.elements);\n        }\n        if (e.op == TOK.assocArrayLiteral)\n        {\n            AssocArrayLiteralExp ae = cast(AssocArrayLiteralExp)e;\n            if (ae.type.nextOf().hasPointers() && checkArray(ae.values))\n                return true;\n            if ((cast(TypeAArray)ae.type).index.hasPointers())\n                return checkArray(ae.keys);\n            return false;\n        }\n        if (e.op == TOK.address)\n        {\n            AddrExp ae = cast(AddrExp)e;\n            if (ae.e1.op == TOK.structLiteral)\n            {\n                StructLiteralExp se = cast(StructLiteralExp)ae.e1;\n                if (!(se.stageflags & stageSearchPointers))\n                {\n                    int old = se.stageflags;\n                    se.stageflags |= stageSearchPointers;\n                    bool ret = checkArray(se.elements);\n                    se.stageflags = old;\n                    return ret;\n                }\n                else\n                {\n                    return false;\n                }\n            }\n            return true;\n        }\n        if (e.type.ty == Tpointer && e.type.nextOf().ty != Tfunction)\n        {\n            if (e.op == TOK.symbolOffset) // address of a global is OK\n                return false;\n            if (e.op == TOK.int64) // cast(void *)int is OK\n                return false;\n            if (e.op == TOK.string_) // \"abc\".ptr is OK\n                return false;\n            return true;\n        }\n        return false;\n    }\n}\n\n\n/****************************************\n * Copy the AST for Initializer.\n * Params:\n *      inx = Initializer AST to copy\n * Returns:\n *      the copy\n */\nInitializer syntaxCopy(Initializer inx)\n{\n    static Initializer copyStruct(StructInitializer vi)\n    {\n        auto si = new StructInitializer(vi.loc);\n        assert(vi.field.dim == vi.value.dim);\n        si.field.setDim(vi.field.dim);\n        si.value.setDim(vi.value.dim);\n        foreach (const i; 0 .. vi.field.dim)\n        {\n            si.field[i] = vi.field[i];\n            si.value[i] = vi.value[i].syntaxCopy();\n        }\n        return si;\n    }\n\n    static Initializer copyArray(ArrayInitializer vi)\n    {\n        auto ai = new ArrayInitializer(vi.loc);\n        assert(vi.index.dim == vi.value.dim);\n        ai.index.setDim(vi.index.dim);\n        ai.value.setDim(vi.value.dim);\n        foreach (const i; 0 .. vi.value.dim)\n        {\n            ai.index[i] = vi.index[i] ? vi.index[i].syntaxCopy() : null;\n            ai.value[i] = vi.value[i].syntaxCopy();\n        }\n        return ai;\n    }\n\n    final switch (inx.kind)\n    {\n        case InitKind.void_:   return new VoidInitializer(inx.loc);\n        case InitKind.error:   return inx;\n        case InitKind.struct_: return copyStruct(cast(StructInitializer)inx);\n        case InitKind.array:   return copyArray(cast(ArrayInitializer)inx);\n        case InitKind.exp:     return new ExpInitializer(inx.loc, (cast(ExpInitializer)inx).exp.syntaxCopy());\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/init.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/init.h\n */\n\n#pragma once\n\n#include \"globals.h\"\n#include \"arraytypes.h\"\n#include \"visitor.h\"\n\nclass Identifier;\nclass Expression;\nclass Type;\nclass ErrorInitializer;\nclass VoidInitializer;\nclass StructInitializer;\nclass ArrayInitializer;\nclass ExpInitializer;\n\nenum NeedInterpret { INITnointerpret, INITinterpret };\n\nclass Initializer : public RootObject\n{\npublic:\n    Loc loc;\n    unsigned char kind;\n\n    const char *toChars();\n\n    ErrorInitializer   *isErrorInitializer();\n    VoidInitializer    *isVoidInitializer();\n    StructInitializer  *isStructInitializer();\n    ArrayInitializer   *isArrayInitializer();\n    ExpInitializer     *isExpInitializer();\n\n    virtual void accept(Visitor *v) { v->visit(this); }\n};\n\nclass VoidInitializer : public Initializer\n{\npublic:\n    Type *type;         // type that this will initialize to\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ErrorInitializer : public Initializer\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StructInitializer : public Initializer\n{\npublic:\n    Identifiers field;  // of Identifier *'s\n    Initializers value; // parallel array of Initializer *'s\n\n    void addInit(Identifier *field, Initializer *value);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ArrayInitializer : public Initializer\n{\npublic:\n    Expressions index;  // indices\n    Initializers value; // of Initializer *'s\n    unsigned dim;       // length of array being initialized\n    Type *type;         // type that array will be used to initialize\n    bool sem;           // true if semantic() is run\n\n    void addInit(Expression *index, Initializer *value);\n    bool isAssociativeArray();\n    Expression *toAssocArrayLiteral();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ExpInitializer : public Initializer\n{\npublic:\n    bool expandTuples;\n    Expression *exp;\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nExpression *initializerToExpression(Initializer *init, Type *t = NULL);\n\nInitializer *syntaxCopy(Initializer *inx);\n\n"
  },
  {
    "path": "gcc/d/dmd/initsem.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/initsem.d, _initsem.d)\n * Documentation:  https://dlang.org/phobos/dmd_initsem.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/initsem.d\n */\n\nmodule dmd.initsem;\n\nimport core.stdc.stdio;\nimport core.checkedint;\n\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arraytypes;\nimport dmd.dcast;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.mtype;\nimport dmd.statement;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.typesem;\n\n/********************************\n * If possible, convert array initializer to associative array initializer.\n *\n *  Params:\n *     ai = array initializer to be converted\n *\n *  Returns:\n *     The converted associative array initializer or ErrorExp if `ai`\n *     is not an associative array initializer.\n */\nExpression toAssocArrayLiteral(ArrayInitializer ai)\n{\n    Expression e;\n    //printf(\"ArrayInitializer::toAssocArrayInitializer()\\n\");\n    //static int i; if (++i == 2) assert(0);\n    const dim = ai.value.dim;\n    auto keys = new Expressions(dim);\n    auto values = new Expressions(dim);\n    for (size_t i = 0; i < dim; i++)\n    {\n        e = ai.index[i];\n        if (!e)\n            goto Lno;\n        (*keys)[i] = e;\n        Initializer iz = ai.value[i];\n        if (!iz)\n            goto Lno;\n        e = iz.initializerToExpression();\n        if (!e)\n            goto Lno;\n        (*values)[i] = e;\n    }\n    e = new AssocArrayLiteralExp(ai.loc, keys, values);\n    return e;\nLno:\n    error(ai.loc, \"not an associative array initializer\");\n    return new ErrorExp();\n}\n\n/******************************************\n * Perform semantic analysis on init.\n * Params:\n *      init = Initializer AST node\n *      sc = context\n *      t = type that the initializer needs to become\n *      needInterpret = if CTFE needs to be run on this,\n *                      such as if it is the initializer for a const declaration\n * Returns:\n *      `Initializer` with completed semantic analysis, `ErrorInitializer` if errors\n *      were encountered\n */\nextern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, Type t, NeedInterpret needInterpret)\n{\n    Initializer visitVoid(VoidInitializer i)\n    {\n        i.type = t;\n        return i;\n    }\n\n    Initializer visitError(ErrorInitializer i)\n    {\n        return i;\n    }\n\n    Initializer visitStruct(StructInitializer i)\n    {\n        //printf(\"StructInitializer::semantic(t = %s) %s\\n\", t.toChars(), toChars());\n        t = t.toBasetype();\n        if (t.ty == Tsarray && t.nextOf().toBasetype().ty == Tstruct)\n            t = t.nextOf().toBasetype();\n        if (t.ty == Tstruct)\n        {\n            StructDeclaration sd = (cast(TypeStruct)t).sym;\n            if (sd.ctor)\n            {\n                error(i.loc, \"%s `%s` has constructors, cannot use `{ initializers }`, use `%s( initializers )` instead\", sd.kind(), sd.toChars(), sd.toChars());\n                return new ErrorInitializer();\n            }\n            sd.size(i.loc);\n            if (sd.sizeok != Sizeok.done)\n            {\n                return new ErrorInitializer();\n            }\n            size_t nfields = sd.fields.dim - sd.isNested();\n            //expandTuples for non-identity arguments?\n            auto elements = new Expressions(nfields);\n            for (size_t j = 0; j < elements.dim; j++)\n                (*elements)[j] = null;\n            // Run semantic for explicitly given initializers\n            // TODO: this part is slightly different from StructLiteralExp::semantic.\n            bool errors = false;\n            for (size_t fieldi = 0, j = 0; j < i.field.dim; j++)\n            {\n                if (Identifier id = i.field[j])\n                {\n                    Dsymbol s = sd.search(i.loc, id);\n                    if (!s)\n                    {\n                        s = sd.search_correct(id);\n                        Loc initLoc = i.value[j].loc;\n                        if (s)\n                            error(initLoc, \"`%s` is not a member of `%s`, did you mean %s `%s`?\", id.toChars(), sd.toChars(), s.kind(), s.toChars());\n                        else\n                            error(initLoc, \"`%s` is not a member of `%s`\", id.toChars(), sd.toChars());\n                        return new ErrorInitializer();\n                    }\n                    s = s.toAlias();\n                    // Find out which field index it is\n                    for (fieldi = 0; 1; fieldi++)\n                    {\n                        if (fieldi >= nfields)\n                        {\n                            error(i.loc, \"`%s.%s` is not a per-instance initializable field\", sd.toChars(), s.toChars());\n                            return new ErrorInitializer();\n                        }\n                        if (s == sd.fields[fieldi])\n                            break;\n                    }\n                }\n                else if (fieldi >= nfields)\n                {\n                    error(i.loc, \"too many initializers for `%s`\", sd.toChars());\n                    return new ErrorInitializer();\n                }\n                VarDeclaration vd = sd.fields[fieldi];\n                if ((*elements)[fieldi])\n                {\n                    error(i.loc, \"duplicate initializer for field `%s`\", vd.toChars());\n                    errors = true;\n                    continue;\n                }\n                if (vd.type.hasPointers)\n                {\n                    if ((t.alignment() < Target.ptrsize ||\n                         (vd.offset & (Target.ptrsize - 1))) &&\n                        sc.func && sc.func.setUnsafe())\n                    {\n                        error(i.loc, \"field `%s.%s` cannot assign to misaligned pointers in `@safe` code\",\n                            sd.toChars(), vd.toChars());\n                        errors = true;\n                    }\n                }\n                for (size_t k = 0; k < nfields; k++)\n                {\n                    VarDeclaration v2 = sd.fields[k];\n                    if (vd.isOverlappedWith(v2) && (*elements)[k])\n                    {\n                        error(i.loc, \"overlapping initialization for field `%s` and `%s`\", v2.toChars(), vd.toChars());\n                        errors = true;\n                        continue;\n                    }\n                }\n                assert(sc);\n                Initializer iz = i.value[j];\n                iz = iz.initializerSemantic(sc, vd.type.addMod(t.mod), needInterpret);\n                Expression ex = iz.initializerToExpression();\n                if (ex.op == TOK.error)\n                {\n                    errors = true;\n                    continue;\n                }\n                i.value[j] = iz;\n                (*elements)[fieldi] = doCopyOrMove(sc, ex);\n                ++fieldi;\n            }\n            if (errors)\n            {\n                return new ErrorInitializer();\n            }\n            auto sle = new StructLiteralExp(i.loc, sd, elements, t);\n            if (!sd.fill(i.loc, elements, false))\n            {\n                return new ErrorInitializer();\n            }\n            sle.type = t;\n            auto ie = new ExpInitializer(i.loc, sle);\n            return ie.initializerSemantic(sc, t, needInterpret);\n        }\n        else if ((t.ty == Tdelegate || t.ty == Tpointer && t.nextOf().ty == Tfunction) && i.value.dim == 0)\n        {\n            TOK tok = (t.ty == Tdelegate) ? TOK.delegate_ : TOK.function_;\n            /* Rewrite as empty delegate literal { }\n             */\n            auto parameters = new Parameters();\n            Type tf = new TypeFunction(parameters, null, 0, LINK.d);\n            auto fd = new FuncLiteralDeclaration(i.loc, Loc.initial, tf, tok, null);\n            fd.fbody = new CompoundStatement(i.loc, new Statements());\n            fd.endloc = i.loc;\n            Expression e = new FuncExp(i.loc, fd);\n            auto ie = new ExpInitializer(i.loc, e);\n            return ie.initializerSemantic(sc, t, needInterpret);\n        }\n        error(i.loc, \"a struct is not a valid initializer for a `%s`\", t.toChars());\n        return new ErrorInitializer();\n    }\n\n    Initializer visitArray(ArrayInitializer i)\n    {\n        uint length;\n        const(uint) amax = 0x80000000;\n        bool errors = false;\n        //printf(\"ArrayInitializer::semantic(%s)\\n\", t.toChars());\n        if (i.sem) // if semantic() already run\n        {\n            return i;\n        }\n        i.sem = true;\n        t = t.toBasetype();\n        switch (t.ty)\n        {\n        case Tsarray:\n        case Tarray:\n            break;\n        case Tvector:\n            t = (cast(TypeVector)t).basetype;\n            break;\n        case Taarray:\n        case Tstruct: // consider implicit constructor call\n            {\n                Expression e;\n                // note: MyStruct foo = [1:2, 3:4] is correct code if MyStruct has a this(int[int])\n                if (t.ty == Taarray || i.isAssociativeArray())\n                    e = i.toAssocArrayLiteral();\n                else\n                    e = i.initializerToExpression();\n                // Bugzilla 13987\n                if (!e)\n                {\n                    error(i.loc, \"cannot use array to initialize `%s`\", t.toChars());\n                    goto Lerr;\n                }\n                auto ei = new ExpInitializer(e.loc, e);\n                return ei.initializerSemantic(sc, t, needInterpret);\n            }\n        case Tpointer:\n            if (t.nextOf().ty != Tfunction)\n                break;\n            goto default;\n        default:\n            error(i.loc, \"cannot use array to initialize `%s`\", t.toChars());\n            goto Lerr;\n        }\n        i.type = t;\n        length = 0;\n        for (size_t j = 0; j < i.index.dim; j++)\n        {\n            Expression idx = i.index[j];\n            if (idx)\n            {\n                sc = sc.startCTFE();\n                idx = idx.expressionSemantic(sc);\n                sc = sc.endCTFE();\n                idx = idx.ctfeInterpret();\n                i.index[j] = idx;\n                const uinteger_t idxvalue = idx.toInteger();\n                if (idxvalue >= amax)\n                {\n                    error(i.loc, \"array index %llu overflow\", ulong(idxvalue));\n                    errors = true;\n                }\n                length = cast(uint)idxvalue;\n                if (idx.op == TOK.error)\n                    errors = true;\n            }\n            Initializer val = i.value[j];\n            ExpInitializer ei = val.isExpInitializer();\n            if (ei && !idx)\n                ei.expandTuples = true;\n            val = val.initializerSemantic(sc, t.nextOf(), needInterpret);\n            if (val.isErrorInitializer())\n                errors = true;\n            ei = val.isExpInitializer();\n            // found a tuple, expand it\n            if (ei && ei.exp.op == TOK.tuple)\n            {\n                TupleExp te = cast(TupleExp)ei.exp;\n                i.index.remove(j);\n                i.value.remove(j);\n                for (size_t k = 0; k < te.exps.dim; ++k)\n                {\n                    Expression e = (*te.exps)[k];\n                    i.index.insert(j + k, cast(Expression)null);\n                    i.value.insert(j + k, new ExpInitializer(e.loc, e));\n                }\n                j--;\n                continue;\n            }\n            else\n            {\n                i.value[j] = val;\n            }\n            length++;\n            if (length == 0)\n            {\n                error(i.loc, \"array dimension overflow\");\n                goto Lerr;\n            }\n            if (length > i.dim)\n                i.dim = length;\n        }\n        if (t.ty == Tsarray)\n        {\n            uinteger_t edim = (cast(TypeSArray)t).dim.toInteger();\n            if (i.dim > edim)\n            {\n                error(i.loc, \"array initializer has %u elements, but array length is %llu\", i.dim, edim);\n                goto Lerr;\n            }\n        }\n        if (errors)\n            goto Lerr;\n        {\n            const sz = t.nextOf().size();\n            bool overflow;\n            const max = mulu(i.dim, sz, overflow);\n            if (overflow || max >= amax)\n            {\n                error(i.loc, \"array dimension %llu exceeds max of %llu\", ulong(i.dim), ulong(amax / sz));\n                goto Lerr;\n            }\n            return i;\n        }\n    Lerr:\n        return new ErrorInitializer();\n    }\n\n    Initializer visitExp(ExpInitializer i)\n    {\n        //printf(\"ExpInitializer::semantic(%s), type = %s\\n\", i.exp.toChars(), t.toChars());\n        if (needInterpret)\n            sc = sc.startCTFE();\n        i.exp = i.exp.expressionSemantic(sc);\n        i.exp = resolveProperties(sc, i.exp);\n        if (needInterpret)\n            sc = sc.endCTFE();\n        if (i.exp.op == TOK.error)\n        {\n            return new ErrorInitializer();\n        }\n        uint olderrors = global.errors;\n        if (needInterpret)\n        {\n            // If the result will be implicitly cast, move the cast into CTFE\n            // to avoid premature truncation of polysemous types.\n            // eg real [] x = [1.1, 2.2]; should use real precision.\n            if (i.exp.implicitConvTo(t))\n            {\n                i.exp = i.exp.implicitCastTo(sc, t);\n            }\n            if (!global.gag && olderrors != global.errors)\n            {\n                return i;\n            }\n            i.exp = i.exp.ctfeInterpret();\n        }\n        else\n        {\n            i.exp = i.exp.optimize(WANTvalue);\n        }\n        if (!global.gag && olderrors != global.errors)\n        {\n            return i; // Failed, suppress duplicate error messages\n        }\n        if (i.exp.type.ty == Ttuple && (cast(TypeTuple)i.exp.type).arguments.dim == 0)\n        {\n            Type et = i.exp.type;\n            i.exp = new TupleExp(i.exp.loc, new Expressions());\n            i.exp.type = et;\n        }\n        if (i.exp.op == TOK.type)\n        {\n            i.exp.error(\"initializer must be an expression, not `%s`\", i.exp.toChars());\n            return new ErrorInitializer();\n        }\n        // Make sure all pointers are constants\n        if (needInterpret && hasNonConstPointers(i.exp))\n        {\n            i.exp.error(\"cannot use non-constant CTFE pointer in an initializer `%s`\", i.exp.toChars());\n            return new ErrorInitializer();\n        }\n        Type tb = t.toBasetype();\n        Type ti = i.exp.type.toBasetype();\n        if (i.exp.op == TOK.tuple && i.expandTuples && !i.exp.implicitConvTo(t))\n        {\n            return new ExpInitializer(i.loc, i.exp);\n        }\n        /* Look for case of initializing a static array with a too-short\n         * string literal, such as:\n         *  char[5] foo = \"abc\";\n         * Allow this by doing an explicit cast, which will lengthen the string\n         * literal.\n         */\n        if (i.exp.op == TOK.string_ && tb.ty == Tsarray)\n        {\n            StringExp se = cast(StringExp)i.exp;\n            Type typeb = se.type.toBasetype();\n            TY tynto = tb.nextOf().ty;\n            if (!se.committed &&\n                (typeb.ty == Tarray || typeb.ty == Tsarray) &&\n                (tynto == Tchar || tynto == Twchar || tynto == Tdchar) &&\n                se.numberOfCodeUnits(tynto) < (cast(TypeSArray)tb).dim.toInteger())\n            {\n                i.exp = se.castTo(sc, t);\n                goto L1;\n            }\n        }\n        // Look for implicit constructor call\n        if (tb.ty == Tstruct && !(ti.ty == Tstruct && tb.toDsymbol(sc) == ti.toDsymbol(sc)) && !i.exp.implicitConvTo(t))\n        {\n            StructDeclaration sd = (cast(TypeStruct)tb).sym;\n            if (sd.ctor)\n            {\n                // Rewrite as S().ctor(exp)\n                Expression e;\n                e = new StructLiteralExp(i.loc, sd, null);\n                e = new DotIdExp(i.loc, e, Id.ctor);\n                e = new CallExp(i.loc, e, i.exp);\n                e = e.expressionSemantic(sc);\n                if (needInterpret)\n                    i.exp = e.ctfeInterpret();\n                else\n                    i.exp = e.optimize(WANTvalue);\n            }\n        }\n        // Look for the case of statically initializing an array\n        // with a single member.\n        if (tb.ty == Tsarray && !tb.nextOf().equals(ti.toBasetype().nextOf()) && i.exp.implicitConvTo(tb.nextOf()))\n        {\n            /* If the variable is not actually used in compile time, array creation is\n             * redundant. So delay it until invocation of toExpression() or toDt().\n             */\n            t = tb.nextOf();\n        }\n        if (i.exp.implicitConvTo(t))\n        {\n            i.exp = i.exp.implicitCastTo(sc, t);\n        }\n        else\n        {\n            // Look for mismatch of compile-time known length to emit\n            // better diagnostic message, as same as AssignExp::semantic.\n            if (tb.ty == Tsarray && i.exp.implicitConvTo(tb.nextOf().arrayOf()) > MATCH.nomatch)\n            {\n                uinteger_t dim1 = (cast(TypeSArray)tb).dim.toInteger();\n                uinteger_t dim2 = dim1;\n                if (i.exp.op == TOK.arrayLiteral)\n                {\n                    ArrayLiteralExp ale = cast(ArrayLiteralExp)i.exp;\n                    dim2 = ale.elements ? ale.elements.dim : 0;\n                }\n                else if (i.exp.op == TOK.slice)\n                {\n                    Type tx = toStaticArrayType(cast(SliceExp)i.exp);\n                    if (tx)\n                        dim2 = (cast(TypeSArray)tx).dim.toInteger();\n                }\n                if (dim1 != dim2)\n                {\n                    i.exp.error(\"mismatched array lengths, %d and %d\", cast(int)dim1, cast(int)dim2);\n                    i.exp = new ErrorExp();\n                }\n            }\n            i.exp = i.exp.implicitCastTo(sc, t);\n        }\n    L1:\n        if (i.exp.op == TOK.error)\n        {\n            return i;\n        }\n        if (needInterpret)\n            i.exp = i.exp.ctfeInterpret();\n        else\n            i.exp = i.exp.optimize(WANTvalue);\n        //printf(\"-ExpInitializer::semantic(): \"); i.exp.print();\n        return i;\n    }\n\n    final switch (init.kind)\n    {\n        case InitKind.void_:   return visitVoid  (cast(  VoidInitializer)init);\n        case InitKind.error:   return visitError (cast( ErrorInitializer)init);\n        case InitKind.struct_: return visitStruct(cast(StructInitializer)init);\n        case InitKind.array:   return visitArray (cast( ArrayInitializer)init);\n        case InitKind.exp:     return visitExp   (cast(   ExpInitializer)init);\n    }\n}\n\n/***********************\n * Translate init to an `Expression` in order to infer the type.\n * Params:\n *      init = `Initializer` AST node\n *      sc = context\n * Returns:\n *      an equivalent `ExpInitializer` if successful, or `ErrorInitializer` if it cannot be translated\n */\nInitializer inferType(Initializer init, Scope* sc)\n{\n    Initializer visitVoid(VoidInitializer i)\n    {\n        error(i.loc, \"cannot infer type from void initializer\");\n        return new ErrorInitializer();\n    }\n\n    Initializer visitError(ErrorInitializer i)\n    {\n        return i;\n    }\n\n    Initializer visitStruct(StructInitializer i)\n    {\n        error(i.loc, \"cannot infer type from struct initializer\");\n        return new ErrorInitializer();\n    }\n\n    Initializer visitArray(ArrayInitializer init)\n    {\n        //printf(\"ArrayInitializer::inferType() %s\\n\", toChars());\n        Expressions* keys = null;\n        Expressions* values;\n        if (init.isAssociativeArray())\n        {\n            keys = new Expressions(init.value.dim);\n            values = new Expressions(init.value.dim);\n            for (size_t i = 0; i < init.value.dim; i++)\n            {\n                Expression e = init.index[i];\n                if (!e)\n                    goto Lno;\n                (*keys)[i] = e;\n                Initializer iz = init.value[i];\n                if (!iz)\n                    goto Lno;\n                iz = iz.inferType(sc);\n                if (iz.isErrorInitializer())\n                {\n                    return iz;\n                }\n                assert(iz.isExpInitializer());\n                (*values)[i] = (cast(ExpInitializer)iz).exp;\n                assert((*values)[i].op != TOK.error);\n            }\n            Expression e = new AssocArrayLiteralExp(init.loc, keys, values);\n            auto ei = new ExpInitializer(init.loc, e);\n            return ei.inferType(sc);\n        }\n        else\n        {\n            auto elements = new Expressions(init.value.dim);\n            elements.zero();\n            for (size_t i = 0; i < init.value.dim; i++)\n            {\n                assert(!init.index[i]); // already asserted by isAssociativeArray()\n                Initializer iz = init.value[i];\n                if (!iz)\n                    goto Lno;\n                iz = iz.inferType(sc);\n                if (iz.isErrorInitializer())\n                {\n                    return iz;\n                }\n                assert(iz.isExpInitializer());\n                (*elements)[i] = (cast(ExpInitializer)iz).exp;\n                assert((*elements)[i].op != TOK.error);\n            }\n            Expression e = new ArrayLiteralExp(init.loc, null, elements);\n            auto ei = new ExpInitializer(init.loc, e);\n            return ei.inferType(sc);\n        }\n    Lno:\n        if (keys)\n        {\n            error(init.loc, \"not an associative array initializer\");\n        }\n        else\n        {\n            error(init.loc, \"cannot infer type from array initializer\");\n        }\n        return new ErrorInitializer();\n    }\n\n    Initializer visitExp(ExpInitializer init)\n    {\n        //printf(\"ExpInitializer::inferType() %s\\n\", toChars());\n        init.exp = init.exp.expressionSemantic(sc);\n\n        // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684\n        if (init.exp.op == TOK.type)\n            init.exp = resolveAliasThis(sc, init.exp);\n\n        init.exp = resolveProperties(sc, init.exp);\n        if (init.exp.op == TOK.scope_)\n        {\n            ScopeExp se = cast(ScopeExp)init.exp;\n            TemplateInstance ti = se.sds.isTemplateInstance();\n            if (ti && ti.semanticRun == PASS.semantic && !ti.aliasdecl)\n                se.error(\"cannot infer type from %s `%s`, possible circular dependency\", se.sds.kind(), se.toChars());\n            else\n                se.error(\"cannot infer type from %s `%s`\", se.sds.kind(), se.toChars());\n            return new ErrorInitializer();\n        }\n\n        // Give error for overloaded function addresses\n        bool hasOverloads;\n        if (auto f = isFuncAddress(init.exp, &hasOverloads))\n        {\n            if (f.checkForwardRef(init.loc))\n            {\n                return new ErrorInitializer();\n            }\n            if (hasOverloads && !f.isUnique())\n            {\n                init.exp.error(\"cannot infer type from overloaded function symbol `%s`\", init.exp.toChars());\n                return new ErrorInitializer();\n            }\n        }\n        if (init.exp.op == TOK.address)\n        {\n            AddrExp ae = cast(AddrExp)init.exp;\n            if (ae.e1.op == TOK.overloadSet)\n            {\n                init.exp.error(\"cannot infer type from overloaded function symbol `%s`\", init.exp.toChars());\n                return new ErrorInitializer();\n            }\n        }\n        if (init.exp.op == TOK.error)\n        {\n            return new ErrorInitializer();\n        }\n        if (!init.exp.type)\n        {\n            return new ErrorInitializer();\n        }\n        return init;\n    }\n\n    final switch (init.kind)\n    {\n        case InitKind.void_:   return visitVoid  (cast(  VoidInitializer)init);\n        case InitKind.error:   return visitError (cast( ErrorInitializer)init);\n        case InitKind.struct_: return visitStruct(cast(StructInitializer)init);\n        case InitKind.array:   return visitArray (cast( ArrayInitializer)init);\n        case InitKind.exp:     return visitExp   (cast(   ExpInitializer)init);\n    }\n}\n\n/***********************\n * Translate init to an `Expression`.\n * Params:\n *      init = `Initializer` AST node\n *      itype = if not `null`, type to coerce expression to\n * Returns:\n *      `Expression` created, `null` if cannot, `ErrorExp` for other errors\n */\nextern (C++) Expression initializerToExpression(Initializer init, Type itype = null)\n{\n    Expression visitVoid(VoidInitializer)\n    {\n        return null;\n    }\n\n    Expression visitError(ErrorInitializer)\n    {\n        return new ErrorExp();\n    }\n\n    /***************************************\n     * This works by transforming a struct initializer into\n     * a struct literal. In the future, the two should be the\n     * same thing.\n     */\n    Expression visitStruct(StructInitializer)\n    {\n        // cannot convert to an expression without target 'ad'\n        return null;\n    }\n\n    /********************************\n     * If possible, convert array initializer to array literal.\n     * Otherwise return NULL.\n     */\n    Expression visitArray(ArrayInitializer init)\n    {\n        //printf(\"ArrayInitializer::toExpression(), dim = %d\\n\", dim);\n        //static int i; if (++i == 2) assert(0);\n        Expressions* elements;\n        uint edim;\n        const(uint) amax = 0x80000000;\n        Type t = null;\n        if (init.type)\n        {\n            if (init.type == Type.terror)\n            {\n                return new ErrorExp();\n            }\n            t = init.type.toBasetype();\n            switch (t.ty)\n            {\n            case Tvector:\n                t = (cast(TypeVector)t).basetype;\n                goto case Tsarray;\n\n            case Tsarray:\n                uinteger_t adim = (cast(TypeSArray)t).dim.toInteger();\n                if (adim >= amax)\n                    goto Lno;\n                edim = cast(uint)adim;\n                break;\n\n            case Tpointer:\n            case Tarray:\n                edim = init.dim;\n                break;\n\n            default:\n                assert(0);\n            }\n        }\n        else\n        {\n            edim = cast(uint)init.value.dim;\n            for (size_t i = 0, j = 0; i < init.value.dim; i++, j++)\n            {\n                if (init.index[i])\n                {\n                    if (init.index[i].op == TOK.int64)\n                    {\n                        const uinteger_t idxval = init.index[i].toInteger();\n                        if (idxval >= amax)\n                            goto Lno;\n                        j = cast(size_t)idxval;\n                    }\n                    else\n                        goto Lno;\n                }\n                if (j >= edim)\n                    edim = cast(uint)(j + 1);\n            }\n        }\n        elements = new Expressions(edim);\n        elements.zero();\n        for (size_t i = 0, j = 0; i < init.value.dim; i++, j++)\n        {\n            if (init.index[i])\n                j = cast(size_t)init.index[i].toInteger();\n            assert(j < edim);\n            Initializer iz = init.value[i];\n            if (!iz)\n                goto Lno;\n            Expression ex = iz.initializerToExpression();\n            if (!ex)\n            {\n                goto Lno;\n            }\n            (*elements)[j] = ex;\n        }\n        {\n            /* Fill in any missing elements with the default initializer\n             */\n            Expression _init = null;\n            for (size_t i = 0; i < edim; i++)\n            {\n                if (!(*elements)[i])\n                {\n                    if (!init.type)\n                        goto Lno;\n                    if (!_init)\n                        _init = (cast(TypeNext)t).next.defaultInit(Loc.initial);\n                    (*elements)[i] = _init;\n                }\n            }\n\n            /* Expand any static array initializers that are a single expression\n             * into an array of them\n             */\n            if (t)\n            {\n                Type tn = t.nextOf().toBasetype();\n                if (tn.ty == Tsarray)\n                {\n                    const dim = cast(size_t)(cast(TypeSArray)tn).dim.toInteger();\n                    Type te = tn.nextOf().toBasetype();\n                    foreach (ref e; *elements)\n                    {\n                        if (te.equals(e.type))\n                        {\n                            auto elements2 = new Expressions(dim);\n                            foreach (ref e2; *elements2)\n                                e2 = e;\n                            e = new ArrayLiteralExp(e.loc, tn, elements2);\n                        }\n                    }\n                }\n            }\n\n            /* If any elements are errors, then the whole thing is an error\n             */\n            for (size_t i = 0; i < edim; i++)\n            {\n                Expression e = (*elements)[i];\n                if (e.op == TOK.error)\n                {\n                    return e;\n                }\n            }\n\n            Expression e = new ArrayLiteralExp(init.loc, init.type, elements);\n            return e;\n        }\n    Lno:\n        return null;\n    }\n\n    Expression visitExp(ExpInitializer i)\n    {\n        if (itype)\n        {\n            //printf(\"ExpInitializer::toExpression(t = %s) exp = %s\\n\", itype.toChars(), i.exp.toChars());\n            Type tb = itype.toBasetype();\n            Expression e = (i.exp.op == TOK.construct || i.exp.op == TOK.blit) ? (cast(AssignExp)i.exp).e2 : i.exp;\n            if (tb.ty == Tsarray && e.implicitConvTo(tb.nextOf()))\n            {\n                TypeSArray tsa = cast(TypeSArray)tb;\n                size_t d = cast(size_t)tsa.dim.toInteger();\n                auto elements = new Expressions(d);\n                for (size_t j = 0; j < d; j++)\n                    (*elements)[j] = e;\n                auto ae = new ArrayLiteralExp(e.loc, itype, elements);\n                return ae;\n            }\n        }\n        return i.exp;\n    }\n\n\n    final switch (init.kind)\n    {\n        case InitKind.void_:   return visitVoid  (cast(  VoidInitializer)init);\n        case InitKind.error:   return visitError (cast( ErrorInitializer)init);\n        case InitKind.struct_: return visitStruct(cast(StructInitializer)init);\n        case InitKind.array:   return visitArray (cast( ArrayInitializer)init);\n        case InitKind.exp:     return visitExp   (cast(   ExpInitializer)init);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/inline.d",
    "content": "/* inline.d -- Inline interface for the D front end.\n * Copyright (C) 2018 Free Software Foundation, Inc.\n *\n * GCC is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3, or (at your option)\n * any later version.\n *\n * GCC is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with GCC; see the file COPYING3.  If not see\n * <http://www.gnu.org/licenses/>.\n */\n\nmodule dmd.inline;\n\nimport dmd.dscope;\nimport dmd.expression;\n\n/***********************************************************\n * Perform the \"inline copying\" of a default argument for a function parameter.\n */\n\npublic Expression inlineCopy(Expression e, Scope* sc)\n{\n    return e.copy();\n}\n"
  },
  {
    "path": "gcc/d/dmd/intrange.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/intrange.d, _intrange.d)\n * Documentation:  https://dlang.org/phobos/dmd_intrange.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/intrange.d\n */\n\nmodule dmd.intrange;\n\nimport core.stdc.stdio;\n\nimport dmd.mtype;\nimport dmd.expression;\nimport dmd.globals;\n\nprivate uinteger_t copySign(uinteger_t x, bool sign)\n{\n    // return sign ? -x : x;\n    return (x - cast(uinteger_t)sign) ^ -cast(uinteger_t)sign;\n}\n\nstruct SignExtendedNumber\n{\n    uinteger_t value;\n    bool negative;\n\n    static SignExtendedNumber fromInteger(uinteger_t value_)\n    {\n        return SignExtendedNumber(value_, value_ >> 63);\n    }\n\n    static SignExtendedNumber extreme(bool minimum)\n    {\n        return SignExtendedNumber(minimum - 1, minimum);\n    }\n\n    static SignExtendedNumber max()\n    {\n        return SignExtendedNumber(ulong.max, false);\n    }\n\n    static SignExtendedNumber min()\n    {\n        return SignExtendedNumber(0, true);\n    }\n\n    bool isMinimum() const\n    {\n        return negative && value == 0;\n    }\n\n    bool opEquals(const ref SignExtendedNumber a) const\n    {\n        return value == a.value && negative == a.negative;\n    }\n\n    int opCmp(const ref SignExtendedNumber a) const\n    {\n        if (negative != a.negative)\n        {\n            if (negative)\n                return -1;\n            else\n                return 1;\n        }\n        if (value < a.value)\n            return -1;\n        else if (value > a.value)\n            return 1;\n        else\n            return 0;\n    }\n\n    SignExtendedNumber opUnary(string op : \"++\")()\n    {\n        if (value != ulong.max)\n            ++value;\n        else if (negative)\n        {\n            value = 0;\n            negative = false;\n        }\n        return this;\n    }\n\n    SignExtendedNumber opUnary(string op : \"~\")() const\n    {\n        if (~value == 0)\n            return SignExtendedNumber(~value);\n        else\n            return SignExtendedNumber(~value, !negative);\n    }\n\n    SignExtendedNumber opUnary(string op : \"-\")() const\n    {\n        if (value == 0)\n            return SignExtendedNumber(-cast(ulong)negative);\n        else\n            return SignExtendedNumber(-value, !negative);\n    }\n\n    SignExtendedNumber opBinary(string op : \"&\")(SignExtendedNumber rhs) const\n    {\n        return SignExtendedNumber(value & rhs.value);\n    }\n\n    SignExtendedNumber opBinary(string op : \"|\")(SignExtendedNumber rhs)\n    {\n        return SignExtendedNumber(value | rhs.value);\n    }\n\n    SignExtendedNumber opBinary(string op : \"^\")(SignExtendedNumber rhs)\n    {\n        return SignExtendedNumber(value ^ rhs.value);\n    }\n\n    SignExtendedNumber opBinary(string op : \"+\")(SignExtendedNumber rhs)\n    {\n        uinteger_t sum = value + rhs.value;\n        bool carry = sum < value && sum < rhs.value;\n        if (negative != rhs.negative)\n            return SignExtendedNumber(sum, !carry);\n        else if (negative)\n            return SignExtendedNumber(carry ? sum : 0, true);\n        else\n            return SignExtendedNumber(carry ? ulong.max : sum, false);\n    }\n\n\n    SignExtendedNumber opBinary(string op : \"-\")(SignExtendedNumber rhs)\n    {\n        if (rhs.isMinimum())\n            return negative ? SignExtendedNumber(value, false) : max();\n        else\n            return this + (-rhs);\n    }\n\n    SignExtendedNumber opBinary(string op : \"*\")(SignExtendedNumber rhs)\n    {\n        // perform *saturated* multiplication, otherwise we may get bogus ranges\n        //  like 0x10 * 0x10 == 0x100 == 0.\n\n        /* Special handling for zeros:\n            INT65_MIN * 0 = 0\n            INT65_MIN * + = INT65_MIN\n            INT65_MIN * - = INT65_MAX\n            0 * anything = 0\n        */\n        if (value == 0)\n        {\n            if (!negative)\n                return this;\n            else if (rhs.negative)\n                return max();\n            else\n                return rhs.value == 0 ? rhs : this;\n        }\n        else if (rhs.value == 0)\n            return rhs * this; // don't duplicate the symmetric case.\n\n        SignExtendedNumber rv;\n        // these are != 0 now surely.\n        uinteger_t tAbs = copySign(value, negative);\n        uinteger_t aAbs = copySign(rhs.value, rhs.negative);\n        rv.negative = negative != rhs.negative;\n        if (ulong.max / tAbs < aAbs)\n            rv.value = rv.negative - 1;\n        else\n            rv.value = copySign(tAbs * aAbs, rv.negative);\n        return rv;\n    }\n\n    SignExtendedNumber opBinary(string op : \"/\")(SignExtendedNumber rhs)\n    {\n        /* special handling for zeros:\n            INT65_MIN / INT65_MIN = 1\n            anything / INT65_MIN = 0\n            + / 0 = INT65_MAX  (eh?)\n            - / 0 = INT65_MIN  (eh?)\n        */\n        if (rhs.value == 0)\n        {\n            if (rhs.negative)\n                return SignExtendedNumber(value == 0 && negative);\n            else\n                return extreme(negative);\n        }\n\n        uinteger_t aAbs = copySign(rhs.value, rhs.negative);\n        uinteger_t rvVal;\n\n        if (!isMinimum())\n            rvVal = copySign(value, negative) / aAbs;\n        // Special handling for INT65_MIN\n        //  if the denominator is not a power of 2, it is same as ulong.max / x.\n        else if (aAbs & (aAbs - 1))\n            rvVal = ulong.max / aAbs;\n        // otherwise, it's the same as reversing the bits of x.\n        else\n        {\n            if (aAbs == 1)\n                return extreme(!rhs.negative);\n            rvVal = 1UL << 63;\n            aAbs >>= 1;\n            if (aAbs & 0xAAAAAAAAAAAAAAAAUL) rvVal >>= 1;\n            if (aAbs & 0xCCCCCCCCCCCCCCCCUL) rvVal >>= 2;\n            if (aAbs & 0xF0F0F0F0F0F0F0F0UL) rvVal >>= 4;\n            if (aAbs & 0xFF00FF00FF00FF00UL) rvVal >>= 8;\n            if (aAbs & 0xFFFF0000FFFF0000UL) rvVal >>= 16;\n            if (aAbs & 0xFFFFFFFF00000000UL) rvVal >>= 32;\n        }\n        bool rvNeg = negative != rhs.negative;\n        rvVal = copySign(rvVal, rvNeg);\n\n        return SignExtendedNumber(rvVal, rvVal != 0 && rvNeg);\n    }\n\n    SignExtendedNumber opBinary(string op : \"%\")(SignExtendedNumber rhs)\n    {\n        if (rhs.value == 0)\n            return !rhs.negative ? rhs : isMinimum() ? SignExtendedNumber(0) : this;\n\n        uinteger_t aAbs = copySign(rhs.value, rhs.negative);\n        uinteger_t rvVal;\n\n        // a % b == sgn(a) * abs(a) % abs(b).\n        if (!isMinimum())\n            rvVal = copySign(value, negative) % aAbs;\n        // Special handling for INT65_MIN\n        //  if the denominator is not a power of 2, it is same as ulong.max % x + 1.\n        else if (aAbs & (aAbs - 1))\n            rvVal = ulong.max % aAbs + 1;\n        //  otherwise, the modulus is trivially zero.\n        else\n            rvVal = 0;\n\n        rvVal = copySign(rvVal, negative);\n        return SignExtendedNumber(rvVal, rvVal != 0 && negative);\n    }\n\n    SignExtendedNumber opBinary(string op : \"<<\")(SignExtendedNumber rhs)\n    {\n        // assume left-shift the shift-amount is always unsigned. Thus negative\n        //  shifts will give huge result.\n        if (value == 0)\n            return this;\n        else if (rhs.negative)\n            return extreme(negative);\n\n        uinteger_t v = copySign(value, negative);\n\n        // compute base-2 log of 'v' to determine the maximum allowed bits to shift.\n        // Ref: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog\n\n        // Why is this a size_t? Looks like a bug.\n        size_t r, s;\n\n        r = (v > 0xFFFFFFFFUL) << 5; v >>= r;\n        s = (v > 0xFFFFUL    ) << 4; v >>= s; r |= s;\n        s = (v > 0xFFUL      ) << 3; v >>= s; r |= s;\n        s = (v > 0xFUL       ) << 2; v >>= s; r |= s;\n        s = (v > 0x3UL       ) << 1; v >>= s; r |= s;\n                                               r |= (v >> 1);\n\n        uinteger_t allowableShift = 63 - r;\n        if (rhs.value > allowableShift)\n            return extreme(negative);\n        else\n            return SignExtendedNumber(value << rhs.value, negative);\n    }\n\n    SignExtendedNumber opBinary(string op : \">>\")(SignExtendedNumber rhs)\n    {\n        if (rhs.negative || rhs.value > 64)\n            return negative ? SignExtendedNumber(-1, true) : SignExtendedNumber(0);\n        else if (isMinimum())\n            return rhs.value == 0 ? this : SignExtendedNumber(-1UL << (64 - rhs.value), true);\n\n        uinteger_t x = value ^ -cast(int)negative;\n        x >>= rhs.value;\n        return SignExtendedNumber(x ^ -cast(int)negative, negative);\n    }\n\n    SignExtendedNumber opBinary(string op : \"^^\")(SignExtendedNumber rhs)\n    {\n        // Not yet implemented\n        assert(0);\n    }\n}\n\nstruct IntRange\n{\n    SignExtendedNumber imin, imax;\n\n    this(IntRange another)\n    {\n        imin = another.imin;\n        imax = another.imax;\n    }\n\n    this(SignExtendedNumber a)\n    {\n        imin = a;\n        imax = a;\n    }\n\n    this(SignExtendedNumber lower, SignExtendedNumber upper)\n    {\n        imin = lower;\n        imax = upper;\n    }\n\n    static IntRange fromType(Type type)\n    {\n        return fromType(type, type.isunsigned());\n    }\n\n    static IntRange fromType(Type type, bool isUnsigned)\n    {\n        if (!type.isintegral())\n            return widest();\n\n        uinteger_t mask = type.sizemask();\n        auto lower = SignExtendedNumber(0);\n        auto upper = SignExtendedNumber(mask);\n        if (type.toBasetype().ty == Tdchar)\n            upper.value = 0x10FFFFUL;\n        else if (!isUnsigned)\n        {\n            lower.value = ~(mask >> 1);\n            lower.negative = true;\n            upper.value = (mask >> 1);\n        }\n        return IntRange(lower, upper);\n    }\n\n    static IntRange fromNumbers2(SignExtendedNumber* numbers)\n    {\n        if (numbers[0] < numbers[1])\n            return IntRange(numbers[0], numbers[1]);\n        else\n            return IntRange(numbers[1], numbers[0]);\n    }\n\n    static IntRange fromNumbers4(SignExtendedNumber* numbers)\n    {\n        IntRange ab = fromNumbers2(numbers);\n        IntRange cd = fromNumbers2(numbers + 2);\n        if (cd.imin < ab.imin)\n            ab.imin = cd.imin;\n        if (cd.imax > ab.imax)\n            ab.imax = cd.imax;\n        return ab;\n    }\n\n    static IntRange widest()\n    {\n        return IntRange(SignExtendedNumber.min(), SignExtendedNumber.max());\n    }\n\n    IntRange castSigned(uinteger_t mask)\n    {\n        // .... 0x1e7f ] [0x1e80 .. 0x1f7f] [0x1f80 .. 0x7f] [0x80 .. 0x17f] [0x180 ....\n        //\n        // regular signed type. We use a technique similar to the unsigned version,\n        //  but the chunk has to be offset by 1/2 of the range.\n        uinteger_t halfChunkMask = mask >> 1;\n        uinteger_t minHalfChunk = imin.value & ~halfChunkMask;\n        uinteger_t maxHalfChunk = imax.value & ~halfChunkMask;\n        int minHalfChunkNegativity = imin.negative; // 1 = neg, 0 = nonneg, -1 = chunk containing ::max\n        int maxHalfChunkNegativity = imax.negative;\n        if (minHalfChunk & mask)\n        {\n            minHalfChunk += halfChunkMask + 1;\n            if (minHalfChunk == 0)\n                --minHalfChunkNegativity;\n        }\n        if (maxHalfChunk & mask)\n        {\n            maxHalfChunk += halfChunkMask + 1;\n            if (maxHalfChunk == 0)\n                --maxHalfChunkNegativity;\n        }\n        if (minHalfChunk == maxHalfChunk && minHalfChunkNegativity == maxHalfChunkNegativity)\n        {\n            imin.value &= mask;\n            imax.value &= mask;\n            // sign extend if necessary.\n            imin.negative = (imin.value & ~halfChunkMask) != 0;\n            imax.negative = (imax.value & ~halfChunkMask) != 0;\n            halfChunkMask += 1;\n            imin.value = (imin.value ^ halfChunkMask) - halfChunkMask;\n            imax.value = (imax.value ^ halfChunkMask) - halfChunkMask;\n        }\n        else\n        {\n            imin = SignExtendedNumber(~halfChunkMask, true);\n            imax = SignExtendedNumber(halfChunkMask, false);\n        }\n        return this;\n    }\n\n    IntRange castUnsigned(uinteger_t mask)\n    {\n        // .... 0x1eff ] [0x1f00 .. 0x1fff] [0 .. 0xff] [0x100 .. 0x1ff] [0x200 ....\n        //\n        // regular unsigned type. We just need to see if ir steps across the\n        //  boundary of validRange. If yes, ir will represent the whole validRange,\n        //  otherwise, we just take the modulus.\n        // e.g. [0x105, 0x107] & 0xff == [5, 7]\n        //      [0x105, 0x207] & 0xff == [0, 0xff]\n        uinteger_t minChunk = imin.value & ~mask;\n        uinteger_t maxChunk = imax.value & ~mask;\n        if (minChunk == maxChunk && imin.negative == imax.negative)\n        {\n            imin.value &= mask;\n            imax.value &= mask;\n        }\n        else\n        {\n            imin.value = 0;\n            imax.value = mask;\n        }\n        imin.negative = imax.negative = false;\n        return this;\n    }\n\n    IntRange castDchar()\n    {\n        // special case for dchar. Casting to dchar means \"I'll ignore all\n        //  invalid characters.\"\n        castUnsigned(0xFFFFFFFFUL);\n        if (imin.value > 0x10FFFFUL) // ??\n            imin.value = 0x10FFFFUL; // ??\n        if (imax.value > 0x10FFFFUL)\n            imax.value = 0x10FFFFUL;\n        return this;\n    }\n\n    IntRange _cast(Type type)\n    {\n        if (!type.isintegral())\n            return this;\n        else if (!type.isunsigned())\n            return castSigned(type.sizemask());\n        else if (type.toBasetype().ty == Tdchar)\n            return castDchar();\n        else\n            return castUnsigned(type.sizemask());\n    }\n\n    IntRange castUnsigned(Type type)\n    {\n        if (!type.isintegral())\n            return castUnsigned(ulong.max);\n        else if (type.toBasetype().ty == Tdchar)\n            return castDchar();\n        else\n            return castUnsigned(type.sizemask());\n    }\n\n    bool contains(IntRange a)\n    {\n        return imin <= a.imin && imax >= a.imax;\n    }\n\n    bool containsZero() const\n    {\n        return (imin.negative && !imax.negative)\n            || (!imin.negative && imin.value == 0);\n    }\n\n    IntRange absNeg() const\n    {\n        if (imax.negative)\n            return this;\n        else if (!imin.negative)\n            return IntRange(-imax, -imin);\n        else\n        {\n            SignExtendedNumber imaxAbsNeg = -imax;\n            return IntRange(imaxAbsNeg < imin ? imaxAbsNeg : imin,\n                            SignExtendedNumber(0));\n        }\n    }\n\n    IntRange unionWith(const ref IntRange other) const\n    {\n        return IntRange(imin < other.imin ? imin : other.imin,\n                        imax > other.imax ? imax : other.imax);\n    }\n\n    void unionOrAssign(IntRange other, ref bool union_)\n    {\n        if (!union_ || imin > other.imin)\n            imin = other.imin;\n        if (!union_ || imax < other.imax)\n            imax = other.imax;\n        union_ = true;\n    }\n\n    ref const(IntRange) dump(const(char)* funcName, Expression e) const\n    {\n        printf(\"[(%c)%#018llx, (%c)%#018llx] @ %s ::: %s\\n\",\n               imin.negative?'-':'+', cast(ulong)imin.value,\n               imax.negative?'-':'+', cast(ulong)imax.value,\n               funcName, e.toChars());\n        return this;\n    }\n\n    void splitBySign(ref IntRange negRange, ref bool hasNegRange, ref IntRange nonNegRange, ref bool hasNonNegRange) const\n    {\n        hasNegRange = imin.negative;\n        if (hasNegRange)\n        {\n            negRange.imin = imin;\n            negRange.imax = imax.negative ? imax : SignExtendedNumber(-1, true);\n        }\n        hasNonNegRange = !imax.negative;\n        if (hasNonNegRange)\n        {\n            nonNegRange.imin = imin.negative ? SignExtendedNumber(0) : imin;\n            nonNegRange.imax = imax;\n        }\n    }\n\n    IntRange opUnary(string op:\"~\")() const\n    {\n        return IntRange(~imax, ~imin);\n    }\n\n    IntRange opUnary(string op : \"-\")()\n    {\n        return IntRange(-imax, -imin);\n    }\n\n    // Credits to Timon Gehr for the algorithms for &, |\n    // https://github.com/tgehr/d-compiler/blob/master/vrange.d\n    IntRange opBinary(string op : \"&\")(IntRange rhs) const\n    {\n        // unsigned or identical sign bits\n        if ((imin.negative ^ imax.negative) != 1 && (rhs.imin.negative ^ rhs.imax.negative) != 1)\n        {\n            return IntRange(minAnd(this, rhs), maxAnd(this, rhs));\n        }\n\n        IntRange l = IntRange(this);\n        IntRange r = IntRange(rhs);\n\n        // both intervals span [-1,0]\n        if ((imin.negative ^ imax.negative) == 1 && (rhs.imin.negative ^ rhs.imax.negative) == 1)\n        {\n            // cannot be larger than either l.max or r.max, set the other one to -1\n            SignExtendedNumber max = l.imax.value > r.imax.value ? l.imax : r.imax;\n\n            // only negative numbers for minimum\n            l.imax.value = -1;\n            l.imax.negative = true;\n            r.imax.value = -1;\n            r.imax.negative = true;\n\n            return IntRange(minAnd(l, r), max);\n        }\n        else\n        {\n            // only one interval spans [-1,0]\n            if ((l.imin.negative ^ l.imax.negative) == 1)\n            {\n                swap(l, r); // r spans [-1,0]\n            }\n\n            auto minAndNeg = minAnd(l, IntRange(r.imin, SignExtendedNumber(-1)));\n            auto minAndPos = minAnd(l, IntRange(SignExtendedNumber(0), r.imax));\n            auto maxAndNeg = maxAnd(l, IntRange(r.imin, SignExtendedNumber(-1)));\n            auto maxAndPos = maxAnd(l, IntRange(SignExtendedNumber(0), r.imax));\n\n            auto min = minAndNeg < minAndPos ? minAndNeg : minAndPos;\n            auto max = maxAndNeg > maxAndNeg ? maxAndNeg : maxAndPos;\n\n            auto range = IntRange(min, max);\n            return range;\n        }\n    }\n\n    // Credits to Timon Gehr for the algorithms for &, |\n    // https://github.com/tgehr/d-compiler/blob/master/vrange.d\n    IntRange opBinary(string op : \"|\")(IntRange rhs) const\n    {\n        // unsigned or identical sign bits:\n        if ((imin.negative ^ imax.negative) == 0 && (rhs.imin.negative ^ rhs.imax.negative) == 0)\n        {\n            return IntRange(minOr(this, rhs), maxOr(this, rhs));\n        }\n\n        IntRange l = IntRange(this);\n        IntRange r = IntRange(rhs);\n\n        // both intervals span [-1,0]\n        if ((imin.negative ^ imax.negative) == 1 && (rhs.imin.negative ^ rhs.imax.negative) == 1)\n        {\n            // cannot be smaller than either l.min or r.min, set the other one to 0\n            SignExtendedNumber min = l.imin.value < r.imin.value ? l.imin : r.imin;\n\n            // only negative numbers for minimum\n            l.imin.value = 0;\n            l.imin.negative = false;\n            r.imin.value = 0;\n            r.imin.negative = false;\n\n            return IntRange(min, maxOr(l, r));\n        }\n        else\n        {\n            // only one interval spans [-1,0]\n            if ((imin.negative ^ imax.negative) == 1)\n            {\n                swap(l, r); // r spans [-1,0]\n            }\n\n            auto minOrNeg = minOr(l, IntRange(r.imin, SignExtendedNumber(-1)));\n            auto minOrPos = minOr(l, IntRange(SignExtendedNumber(0), r.imax));\n            auto maxOrNeg = maxOr(l, IntRange(r.imin, SignExtendedNumber(-1)));\n            auto maxOrPos = maxOr(l, IntRange(SignExtendedNumber(0), r.imax));\n\n            auto min = minOrNeg.value < minOrPos.value ? minOrNeg : minOrPos;\n            auto max = maxOrNeg.value > maxOrNeg.value ? maxOrNeg : maxOrPos;\n\n            auto range = IntRange(min, max);\n            return range;\n        }\n    }\n\n    IntRange opBinary(string op : \"^\")(IntRange rhs) const\n    {\n        return this & ~rhs | ~this & rhs;\n    }\n\n    IntRange opBinary(string op : \"+\")(IntRange rhs)\n    {\n        return IntRange(imin + rhs.imin, imax + rhs.imax);\n    }\n\n    IntRange opBinary(string op : \"-\")(IntRange rhs)\n    {\n        return IntRange(imin - rhs.imax, imax - rhs.imin);\n    }\n\n    IntRange opBinary(string op : \"*\")(IntRange rhs)\n    {\n        // [a,b] * [c,d] = [min (ac, ad, bc, bd), max (ac, ad, bc, bd)]\n        SignExtendedNumber[4] bdy;\n        bdy[0] = imin * rhs.imin;\n        bdy[1] = imin * rhs.imax;\n        bdy[2] = imax * rhs.imin;\n        bdy[3] = imax * rhs.imax;\n        return IntRange.fromNumbers4(bdy.ptr);\n    }\n\n    IntRange opBinary(string op : \"/\")(IntRange rhs)\n    {\n        // Handle divide by 0\n        if (rhs.imax.value == 0 && rhs.imin.value == 0)\n            return widest();\n\n        // Don't treat the whole range as divide by 0 if only one end of a range is 0.\n        // Issue 15289\n        if (rhs.imax.value == 0)\n        {\n            rhs.imax.value--;\n        }\n        else if(rhs.imin.value == 0)\n        {\n            rhs.imin.value++;\n        }\n\n        if (!imin.negative && !imax.negative && !rhs.imin.negative && !rhs.imax.negative)\n        {\n            return IntRange(imin / rhs.imax, imax / rhs.imin);\n        }\n        else\n        {\n            // [a,b] / [c,d] = [min (a/c, a/d, b/c, b/d), max (a/c, a/d, b/c, b/d)]\n            SignExtendedNumber[4] bdy;\n            bdy[0] = imin / rhs.imin;\n            bdy[1] = imin / rhs.imax;\n            bdy[2] = imax / rhs.imin;\n            bdy[3] = imax / rhs.imax;\n\n            return IntRange.fromNumbers4(bdy.ptr);\n        }\n    }\n\n    IntRange opBinary(string op : \"%\")(IntRange rhs)\n    {\n        IntRange irNum = this;\n        IntRange irDen = rhs.absNeg();\n\n        /*\n         due to the rules of D (C)'s % operator, we need to consider the cases\n         separately in different range of signs.\n\n             case 1. [500, 1700] % [7, 23] (numerator is always positive)\n                 = [0, 22]\n             case 2. [-500, 1700] % [7, 23] (numerator can be negative)\n                 = [-22, 22]\n             case 3. [-1700, -500] % [7, 23] (numerator is always negative)\n                 = [-22, 0]\n\n         the number 22 is the maximum absolute value in the denomator's range. We\n         don't care about divide by zero.\n         */\n\n        irDen.imin = irDen.imin + SignExtendedNumber(1);\n        irDen.imax = -irDen.imin;\n\n        if (!irNum.imin.negative)\n        {\n            irNum.imin.value = 0;\n        }\n        else if (irNum.imin < irDen.imin)\n        {\n            irNum.imin = irDen.imin;\n        }\n\n        if (irNum.imax.negative)\n        {\n            irNum.imax.negative = false;\n            irNum.imax.value = 0;\n        }\n        else if (irNum.imax > irDen.imax)\n        {\n            irNum.imax = irDen.imax;\n        }\n\n        return irNum;\n    }\n\n    IntRange opBinary(string op : \"<<\")(IntRange rhs)\n    {\n        if (rhs.imin.negative)\n        {\n            rhs = IntRange(SignExtendedNumber(0), SignExtendedNumber(64));\n        }\n\n        SignExtendedNumber lower = imin << (imin.negative ? rhs.imax : rhs.imin);\n        SignExtendedNumber upper = imax << (imax.negative ? rhs.imin : rhs.imax);\n\n        return IntRange(lower, upper);\n    }\n\n    IntRange opBinary(string op : \">>\")(IntRange rhs)\n    {\n        if (rhs.imin.negative)\n        {\n            rhs = IntRange(SignExtendedNumber(0), SignExtendedNumber(64));\n        }\n\n        SignExtendedNumber lower = imin >> (imin.negative ? rhs.imin : rhs.imax);\n        SignExtendedNumber upper = imax >> (imax.negative ? rhs.imax : rhs.imin);\n\n        return IntRange(lower, upper);\n    }\n\n    IntRange opBinary(string op : \">>>\")(IntRange rhs)\n    {\n        if (rhs.imin.negative)\n        {\n            rhs = IntRange(SignExtendedNumber(0), SignExtendedNumber(64));\n        }\n\n        return IntRange(imin >> rhs.imax, imax >> rhs.imin);\n    }\n\n    IntRange opBinary(string op : \"^^\")(IntRange rhs)\n    {\n        // Not yet implemented\n        assert(0);\n    }\n\nprivate:\n    // Credits to Timon Gehr maxOr, minOr, maxAnd, minAnd\n    // https://github.com/tgehr/d-compiler/blob/master/vrange.d\n    static SignExtendedNumber maxOr(const IntRange lhs, const IntRange rhs)\n    {\n        uinteger_t x = 0;\n        auto sign = false;\n        auto xor = lhs.imax.value ^ rhs.imax.value;\n        auto and = lhs.imax.value & rhs.imax.value;\n        auto lhsc = IntRange(lhs);\n        auto rhsc = IntRange(rhs);\n\n        // Sign bit not part of the .value so we need an extra iteration\n        if (lhsc.imax.negative ^ rhsc.imax.negative)\n        {\n            sign = true;\n            if (lhsc.imax.negative)\n            {\n                if (!lhsc.imin.negative)\n                {\n                    lhsc.imin.value = 0;\n                }\n                if (!rhsc.imin.negative)\n                {\n                    rhsc.imin.value = 0;\n                }\n            }\n        }\n        else if (lhsc.imin.negative & rhsc.imin.negative)\n        {\n            sign = true;\n        }\n        else if (lhsc.imax.negative & rhsc.imax.negative)\n        {\n            return SignExtendedNumber(-1, false);\n        }\n\n        for (uinteger_t d = 1LU << (8 * uinteger_t.sizeof - 1); d; d >>= 1)\n        {\n            if (xor & d)\n            {\n                x |= d;\n                if (lhsc.imax.value & d)\n                {\n                    if (~lhsc.imin.value & d)\n                    {\n                        lhsc.imin.value = 0;\n                    }\n                }\n                else\n                {\n                    if (~rhsc.imin.value & d)\n                    {\n                        rhsc.imin.value = 0;\n                    }\n                }\n            }\n            else if (lhsc.imin.value & rhsc.imin.value & d)\n            {\n                x |= d;\n            }\n            else if (and & d)\n            {\n                x |= (d << 1) - 1;\n                break;\n            }\n        }\n\n        auto range = SignExtendedNumber(x, sign);\n        return range;\n    }\n\n    // Credits to Timon Gehr maxOr, minOr, maxAnd, minAnd\n    // https://github.com/tgehr/d-compiler/blob/master/vrange.d\n    static SignExtendedNumber minOr(const IntRange lhs, const IntRange rhs)\n    {\n        return ~maxAnd(~lhs, ~rhs);\n    }\n\n    // Credits to Timon Gehr maxOr, minOr, maxAnd, minAnd\n    // https://github.com/tgehr/d-compiler/blob/master/vrange.d\n    static SignExtendedNumber maxAnd(const IntRange lhs, const IntRange rhs)\n    {\n        uinteger_t x = 0;\n        bool sign = false;\n        auto lhsc = IntRange(lhs);\n        auto rhsc = IntRange(rhs);\n\n        if (lhsc.imax.negative & rhsc.imax.negative)\n        {\n            sign = true;\n        }\n\n        for (uinteger_t d = 1LU << (8 * uinteger_t.sizeof - 1); d; d >>= 1)\n        {\n            if (lhsc.imax.value & rhsc.imax.value & d)\n            {\n                x |= d;\n                if (~lhsc.imin.value & d)\n                {\n                    lhsc.imin.value = 0;\n                }\n                if (~rhsc.imin.value & d)\n                {\n                    rhsc.imin.value = 0;\n                }\n            }\n            else if (~lhsc.imin.value & d && lhsc.imax.value & d)\n            {\n                lhsc.imax.value |= d - 1;\n            }\n            else if (~rhsc.imin.value & d && rhsc.imax.value & d)\n            {\n                rhsc.imax.value |= d - 1;\n            }\n        }\n\n        auto range = SignExtendedNumber(x, sign);\n        return range;\n    }\n\n    // Credits to Timon Gehr maxOr, minOr, maxAnd, minAnd\n    // https://github.com/tgehr/d-compiler/blob/master/vrange.d\n    static SignExtendedNumber minAnd(const IntRange lhs, const IntRange rhs)\n    {\n        return ~maxOr(~lhs, ~rhs);\n    }\n\n    static swap(ref IntRange a, ref IntRange b)\n    {\n        auto aux = a;\n        a = b;\n        b = aux;\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/json.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/json.d, _json.d)\n * Documentation:  https://dlang.org/phobos/dmd_json.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/json.d\n */\n\nmodule dmd.json;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.attrib;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dimport;\nimport dmd.dmodule;\nimport dmd.dsymbol;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.utils;\nimport dmd.visitor;\n\nversion(Windows) {\n    extern (C) char* getcwd(char* buffer, size_t maxlen);\n} else {\n    import core.sys.posix.unistd : getcwd;\n}\n\nprivate extern (C++) final class ToJsonVisitor : Visitor\n{\n    alias visit = Visitor.visit;\npublic:\n    OutBuffer* buf;\n    int indentLevel;\n    const(char)[] filename;\n\n    extern (D) this(OutBuffer* buf)\n    {\n        this.buf = buf;\n    }\n\n\n    void indent()\n    {\n        if (buf.offset >= 1 && buf.data[buf.offset - 1] == '\\n')\n            for (int i = 0; i < indentLevel; i++)\n                buf.writeByte(' ');\n    }\n\n    void removeComma()\n    {\n        if (buf.offset >= 2 && buf.data[buf.offset - 2] == ',' && (buf.data[buf.offset - 1] == '\\n' || buf.data[buf.offset - 1] == ' '))\n            buf.offset -= 2;\n    }\n\n    void comma()\n    {\n        if (indentLevel > 0)\n            buf.writestring(\",\\n\");\n    }\n\n    void stringStart()\n    {\n        buf.writeByte('\\\"');\n    }\n\n    void stringEnd()\n    {\n        buf.writeByte('\\\"');\n    }\n\n    extern(D) void stringPart(const(char)[] s)\n    {\n        foreach (char c; s)\n        {\n            switch (c)\n            {\n            case '\\n':\n                buf.writestring(\"\\\\n\");\n                break;\n            case '\\r':\n                buf.writestring(\"\\\\r\");\n                break;\n            case '\\t':\n                buf.writestring(\"\\\\t\");\n                break;\n            case '\\\"':\n                buf.writestring(\"\\\\\\\"\");\n                break;\n            case '\\\\':\n                buf.writestring(\"\\\\\\\\\");\n                break;\n            case '\\b':\n                buf.writestring(\"\\\\b\");\n                break;\n            case '\\f':\n                buf.writestring(\"\\\\f\");\n                break;\n            default:\n                if (c < 0x20)\n                    buf.printf(\"\\\\u%04x\", c);\n                else\n                {\n                    // Note that UTF-8 chars pass through here just fine\n                    buf.writeByte(c);\n                }\n                break;\n            }\n        }\n    }\n\n    // Json value functions\n    /*********************************\n     * Encode string into buf, and wrap it in double quotes.\n     */\n    extern(D) void value(const(char)[] s)\n    {\n        stringStart();\n        stringPart(s);\n        stringEnd();\n    }\n\n    void value(int value)\n    {\n        if (value < 0)\n        {\n            buf.writeByte('-');\n            value = -value;\n        }\n        buf.print(value);\n    }\n\n    void valueBool(bool value)\n    {\n        buf.writestring(value ? \"true\" : \"false\");\n    }\n\n    /*********************************\n     * Item is an intented value and a comma, for use in arrays\n     */\n    extern(D) void item(const(char)[] s)\n    {\n        indent();\n        value(s);\n        comma();\n    }\n\n    void item(int i)\n    {\n        indent();\n        value(i);\n        comma();\n    }\n\n    void itemBool(const bool b)\n    {\n        indent();\n        valueBool(b);\n        comma();\n    }\n\n    // Json array functions\n    void arrayStart()\n    {\n        indent();\n        buf.writestring(\"[\\n\");\n        indentLevel++;\n    }\n\n    void arrayEnd()\n    {\n        indentLevel--;\n        removeComma();\n        if (buf.offset >= 2 && buf.data[buf.offset - 2] == '[' && buf.data[buf.offset - 1] == '\\n')\n            buf.offset -= 1;\n        else if (!(buf.offset >= 1 && buf.data[buf.offset - 1] == '['))\n        {\n            buf.writestring(\"\\n\");\n            indent();\n        }\n        buf.writestring(\"]\");\n        comma();\n    }\n\n    // Json object functions\n    void objectStart()\n    {\n        indent();\n        buf.writestring(\"{\\n\");\n        indentLevel++;\n    }\n\n    void objectEnd()\n    {\n        indentLevel--;\n        removeComma();\n        if (buf.offset >= 2 && buf.data[buf.offset - 2] == '{' && buf.data[buf.offset - 1] == '\\n')\n            buf.offset -= 1;\n        else\n        {\n            buf.writestring(\"\\n\");\n            indent();\n        }\n        buf.writestring(\"}\");\n        comma();\n    }\n\n    // Json object property functions\n    extern(D) void propertyStart(const(char)[] name)\n    {\n        indent();\n        value(name);\n        buf.writestring(\" : \");\n    }\n\n    /**\n    Write the given string object property only if `s` is not null.\n\n    Params:\n     name = the name of the object property\n     s = the string value of the object property\n    */\n    extern(D) void property(const(char)[] name, const(char)[] s)\n    {\n        if (s is null)\n            return;\n        propertyStart(name);\n        value(s);\n        comma();\n    }\n\n    /**\n    Write the given string object property.\n\n    Params:\n     name = the name of the object property\n     s = the string value of the object property\n    */\n    extern(D) void requiredProperty(const(char)[] name, const(char)[] s)\n    {\n        propertyStart(name);\n        if (s is null)\n            buf.writestring(\"null\");\n        else\n            value(s);\n        comma();\n    }\n\n    extern(D) void property(const(char)[] name, int i)\n    {\n        propertyStart(name);\n        value(i);\n        comma();\n    }\n\n    extern(D) void propertyBool(const(char)[] name, const bool b)\n    {\n        propertyStart(name);\n        valueBool(b);\n        comma();\n    }\n\n    extern(D) void property(const(char)[] name, TRUST trust)\n    {\n        final switch (trust)\n        {\n        case TRUST.default_:\n            // Should not be printed\n            //property(name, \"default\");\n            break;\n        case TRUST.system:\n            property(name, \"system\");\n            break;\n        case TRUST.trusted:\n            property(name, \"trusted\");\n            break;\n        case TRUST.safe:\n            property(name, \"safe\");\n            break;\n        }\n    }\n\n    extern(D) void property(const(char)[] name, PURE purity)\n    {\n        final switch (purity)\n        {\n        case PURE.impure:\n            // Should not be printed\n            //property(name, \"impure\");\n            break;\n        case PURE.weak:\n            property(name, \"weak\");\n            break;\n        case PURE.const_:\n            property(name, \"const\");\n            break;\n        case PURE.strong:\n            property(name, \"strong\");\n            break;\n        case PURE.fwdref:\n            property(name, \"fwdref\");\n            break;\n        }\n    }\n\n    extern(D) void property(const(char)[] name, const LINK linkage)\n    {\n        final switch (linkage)\n        {\n        case LINK.default_:\n            // Should not be printed\n            //property(name, \"default\");\n            break;\n        case LINK.d:\n            // Should not be printed\n            //property(name, \"d\");\n            break;\n        case LINK.system:\n            // Should not be printed\n            //property(name, \"system\");\n            break;\n        case LINK.c:\n            property(name, \"c\");\n            break;\n        case LINK.cpp:\n            property(name, \"cpp\");\n            break;\n        case LINK.windows:\n            property(name, \"windows\");\n            break;\n        case LINK.pascal:\n            property(name, \"pascal\");\n            break;\n        case LINK.objc:\n            property(name, \"objc\");\n            break;\n        }\n    }\n\n    extern(D) void propertyStorageClass(const(char)[] name, StorageClass stc)\n    {\n        stc &= STCStorageClass;\n        if (stc)\n        {\n            propertyStart(name);\n            arrayStart();\n            while (stc)\n            {\n                auto p = stcToString(stc);\n                assert(p.length);\n                item(p);\n            }\n            arrayEnd();\n        }\n    }\n\n    extern(D) void property(const(char)[] linename, const(char)[] charname, Loc* loc)\n    {\n        if (loc)\n        {\n            if (auto filename = loc.filename.toDString)\n            {\n                if (filename != this.filename)\n                {\n                    this.filename = filename;\n                    property(\"file\", filename);\n                }\n            }\n            if (loc.linnum)\n            {\n                property(linename, loc.linnum);\n                if (loc.charnum)\n                    property(charname, loc.charnum);\n            }\n        }\n    }\n\n    extern(D) void property(const(char)[] name, Type type)\n    {\n        if (type)\n        {\n            property(name, type.toString());\n        }\n    }\n\n    extern(D) void property(const(char)[] name, const(char)[] deconame, Type type)\n    {\n        if (type)\n        {\n            if (type.deco)\n                property(deconame, type.deco.toDString);\n            else\n                property(name, type.toString());\n        }\n    }\n\n    extern(D) void property(const(char)[] name, Parameters* parameters)\n    {\n        if (parameters is null || parameters.dim == 0)\n            return;\n        propertyStart(name);\n        arrayStart();\n        if (parameters)\n        {\n            for (size_t i = 0; i < parameters.dim; i++)\n            {\n                Parameter p = (*parameters)[i];\n                objectStart();\n                if (p.ident)\n                    property(\"name\", p.ident.toString());\n                property(\"type\", \"deco\", p.type);\n                propertyStorageClass(\"storageClass\", p.storageClass);\n                if (p.defaultArg)\n                    property(\"default\", p.defaultArg.toString());\n                objectEnd();\n            }\n        }\n        arrayEnd();\n    }\n\n    /* ========================================================================== */\n    void jsonProperties(Dsymbol s)\n    {\n        if (s.isModule())\n            return;\n        if (!s.isTemplateDeclaration()) // TemplateDeclaration::kind() acts weird sometimes\n        {\n            property(\"name\", s.toString());\n            property(\"kind\", s.kind.toDString);\n        }\n        if (s.prot().kind != Prot.Kind.public_) // TODO: How about package(names)?\n            property(\"protection\", protectionToString(s.prot().kind));\n        if (EnumMember em = s.isEnumMember())\n        {\n            if (em.origValue)\n                property(\"value\", em.origValue.toString());\n        }\n        property(\"comment\", s.comment.toDString);\n        property(\"line\", \"char\", &s.loc);\n    }\n\n    void jsonProperties(Declaration d)\n    {\n        if (d.storage_class & STC.local)\n            return;\n        jsonProperties(cast(Dsymbol)d);\n        propertyStorageClass(\"storageClass\", d.storage_class);\n        property(\"linkage\", d.linkage);\n        property(\"type\", \"deco\", d.type);\n        // Emit originalType if it differs from type\n        if (d.type != d.originalType && d.originalType)\n        {\n            auto ostr = d.originalType.toString();\n            if (d.type)\n            {\n                auto tstr = d.type.toString();\n                if (ostr != tstr)\n                {\n                    //printf(\"tstr = %s, ostr = %s\\n\", tstr, ostr);\n                    property(\"originalType\", ostr);\n                }\n            }\n            else\n                property(\"originalType\", ostr);\n        }\n    }\n\n    void jsonProperties(TemplateDeclaration td)\n    {\n        jsonProperties(cast(Dsymbol)td);\n        if (td.onemember && td.onemember.isCtorDeclaration())\n            property(\"name\", \"this\"); // __ctor -> this\n        else\n            property(\"name\", td.ident.toString()); // Foo(T) -> Foo\n    }\n\n    /* ========================================================================== */\n    override void visit(Dsymbol s)\n    {\n    }\n\n    override void visit(Module s)\n    {\n        objectStart();\n        if (s.md)\n            property(\"name\", s.md.toString());\n        property(\"kind\", s.kind.toDString);\n        filename = s.srcfile.toString();\n        property(\"file\", filename);\n        property(\"comment\", s.comment.toDString);\n        propertyStart(\"members\");\n        arrayStart();\n        for (size_t i = 0; i < s.members.dim; i++)\n        {\n            (*s.members)[i].accept(this);\n        }\n        arrayEnd();\n        objectEnd();\n    }\n\n    override void visit(Import s)\n    {\n        if (s.id == Id.object)\n            return;\n        objectStart();\n        propertyStart(\"name\");\n        stringStart();\n        if (s.packages && s.packages.dim)\n        {\n            for (size_t i = 0; i < s.packages.dim; i++)\n            {\n                Identifier pid = (*s.packages)[i];\n                stringPart(pid.toString());\n                buf.writeByte('.');\n            }\n        }\n        stringPart(s.id.toString());\n        stringEnd();\n        comma();\n        property(\"kind\", s.kind.toDString);\n        property(\"comment\", s.comment.toDString);\n        property(\"line\", \"char\", &s.loc);\n        if (s.prot().kind != Prot.Kind.public_)\n            property(\"protection\", protectionToString(s.prot().kind));\n        if (s.aliasId)\n            property(\"alias\", s.aliasId.toString());\n        bool hasRenamed = false;\n        bool hasSelective = false;\n        for (size_t i = 0; i < s.aliases.dim; i++)\n        {\n            // avoid empty \"renamed\" and \"selective\" sections\n            if (hasRenamed && hasSelective)\n                break;\n            else if (s.aliases[i])\n                hasRenamed = true;\n            else\n                hasSelective = true;\n        }\n        if (hasRenamed)\n        {\n            // import foo : alias1 = target1;\n            propertyStart(\"renamed\");\n            objectStart();\n            for (size_t i = 0; i < s.aliases.dim; i++)\n            {\n                Identifier name = s.names[i];\n                Identifier _alias = s.aliases[i];\n                if (_alias)\n                    property(_alias.toString(), name.toString());\n            }\n            objectEnd();\n        }\n        if (hasSelective)\n        {\n            // import foo : target1;\n            propertyStart(\"selective\");\n            arrayStart();\n            foreach (i, name; s.names)\n            {\n                if (!s.aliases[i])\n                    item(name.toString());\n            }\n            arrayEnd();\n        }\n        objectEnd();\n    }\n\n    override void visit(AttribDeclaration d)\n    {\n        Dsymbols* ds = d.include(null);\n        if (ds)\n        {\n            for (size_t i = 0; i < ds.dim; i++)\n            {\n                Dsymbol s = (*ds)[i];\n                s.accept(this);\n            }\n        }\n    }\n\n    override void visit(ConditionalDeclaration d)\n    {\n        if (d.condition.inc)\n        {\n            visit(cast(AttribDeclaration)d);\n        }\n        Dsymbols* ds = d.decl ? d.decl : d.elsedecl;\n        for (size_t i = 0; i < ds.dim; i++)\n        {\n            Dsymbol s = (*ds)[i];\n            s.accept(this);\n        }\n    }\n\n    override void visit(TypeInfoDeclaration d)\n    {\n    }\n\n    override void visit(PostBlitDeclaration d)\n    {\n    }\n\n    override void visit(Declaration d)\n    {\n        objectStart();\n        //property(\"unknown\", \"declaration\");\n        jsonProperties(d);\n        objectEnd();\n    }\n\n    override void visit(AggregateDeclaration d)\n    {\n        objectStart();\n        jsonProperties(d);\n        ClassDeclaration cd = d.isClassDeclaration();\n        if (cd)\n        {\n            if (cd.baseClass && cd.baseClass.ident != Id.Object)\n            {\n                property(\"base\", cd.baseClass.toPrettyChars(true).toDString);\n            }\n            if (cd.interfaces.length)\n            {\n                propertyStart(\"interfaces\");\n                arrayStart();\n                foreach (b; cd.interfaces)\n                {\n                    item(b.sym.toPrettyChars(true).toDString);\n                }\n                arrayEnd();\n            }\n        }\n        if (d.members)\n        {\n            propertyStart(\"members\");\n            arrayStart();\n            for (size_t i = 0; i < d.members.dim; i++)\n            {\n                Dsymbol s = (*d.members)[i];\n                s.accept(this);\n            }\n            arrayEnd();\n        }\n        objectEnd();\n    }\n\n    override void visit(FuncDeclaration d)\n    {\n        objectStart();\n        jsonProperties(d);\n        TypeFunction tf = cast(TypeFunction)d.type;\n        if (tf && tf.ty == Tfunction)\n            property(\"parameters\", tf.parameters);\n        property(\"endline\", \"endchar\", &d.endloc);\n        if (d.foverrides.dim)\n        {\n            propertyStart(\"overrides\");\n            arrayStart();\n            for (size_t i = 0; i < d.foverrides.dim; i++)\n            {\n                FuncDeclaration fd = d.foverrides[i];\n                item(fd.toPrettyChars().toDString);\n            }\n            arrayEnd();\n        }\n        if (d.fdrequire)\n        {\n            propertyStart(\"in\");\n            d.fdrequire.accept(this);\n        }\n        if (d.fdensure)\n        {\n            propertyStart(\"out\");\n            d.fdensure.accept(this);\n        }\n        objectEnd();\n    }\n\n    override void visit(TemplateDeclaration d)\n    {\n        objectStart();\n        // TemplateDeclaration::kind returns the kind of its Aggregate onemember, if it is one\n        property(\"kind\", \"template\");\n        jsonProperties(d);\n        propertyStart(\"parameters\");\n        arrayStart();\n        for (size_t i = 0; i < d.parameters.dim; i++)\n        {\n            TemplateParameter s = (*d.parameters)[i];\n            objectStart();\n            property(\"name\", s.ident.toString());\n            TemplateTypeParameter type = s.isTemplateTypeParameter();\n            if (type)\n            {\n                if (s.isTemplateThisParameter())\n                    property(\"kind\", \"this\");\n                else\n                    property(\"kind\", \"type\");\n                property(\"type\", \"deco\", type.specType);\n                property(\"default\", \"defaultDeco\", type.defaultType);\n            }\n            TemplateValueParameter value = s.isTemplateValueParameter();\n            if (value)\n            {\n                property(\"kind\", \"value\");\n                property(\"type\", \"deco\", value.valType);\n                if (value.specValue)\n                    property(\"specValue\", value.specValue.toString());\n                if (value.defaultValue)\n                    property(\"defaultValue\", value.defaultValue.toString());\n            }\n            TemplateAliasParameter _alias = s.isTemplateAliasParameter();\n            if (_alias)\n            {\n                property(\"kind\", \"alias\");\n                property(\"type\", \"deco\", _alias.specType);\n                if (_alias.specAlias)\n                    property(\"specAlias\", _alias.specAlias.toString());\n                if (_alias.defaultAlias)\n                    property(\"defaultAlias\", _alias.defaultAlias.toString());\n            }\n            TemplateTupleParameter tuple = s.isTemplateTupleParameter();\n            if (tuple)\n            {\n                property(\"kind\", \"tuple\");\n            }\n            objectEnd();\n        }\n        arrayEnd();\n        Expression expression = d.constraint;\n        if (expression)\n        {\n            property(\"constraint\", expression.toString());\n        }\n        propertyStart(\"members\");\n        arrayStart();\n        for (size_t i = 0; i < d.members.dim; i++)\n        {\n            Dsymbol s = (*d.members)[i];\n            s.accept(this);\n        }\n        arrayEnd();\n        objectEnd();\n    }\n\n    override void visit(EnumDeclaration d)\n    {\n        if (d.isAnonymous())\n        {\n            if (d.members)\n            {\n                for (size_t i = 0; i < d.members.dim; i++)\n                {\n                    Dsymbol s = (*d.members)[i];\n                    s.accept(this);\n                }\n            }\n            return;\n        }\n        objectStart();\n        jsonProperties(d);\n        property(\"base\", \"baseDeco\", d.memtype);\n        if (d.members)\n        {\n            propertyStart(\"members\");\n            arrayStart();\n            for (size_t i = 0; i < d.members.dim; i++)\n            {\n                Dsymbol s = (*d.members)[i];\n                s.accept(this);\n            }\n            arrayEnd();\n        }\n        objectEnd();\n    }\n\n    override void visit(EnumMember s)\n    {\n        objectStart();\n        jsonProperties(cast(Dsymbol)s);\n        property(\"type\", \"deco\", s.origType);\n        objectEnd();\n    }\n\n    override void visit(VarDeclaration d)\n    {\n        if (d.storage_class & STC.local)\n            return;\n        objectStart();\n        jsonProperties(d);\n        if (d._init)\n            property(\"init\", d._init.toString());\n        if (d.isField())\n            property(\"offset\", d.offset);\n        if (d.alignment && d.alignment != STRUCTALIGN_DEFAULT)\n            property(\"align\", d.alignment);\n        objectEnd();\n    }\n\n    override void visit(TemplateMixin d)\n    {\n        objectStart();\n        jsonProperties(d);\n        objectEnd();\n    }\n\n    /**\n    Generate an array of module objects that represent the syntax of each\n    \"root module\".\n\n    Params:\n     modules = array of the \"root modules\"\n    */\n    private void generateModules(Modules* modules)\n    {\n        arrayStart();\n        if (modules)\n        {\n            foreach (m; *modules)\n            {\n                if (global.params.verbose)\n                    message(\"json gen %s\", m.toChars());\n                m.accept(this);\n            }\n        }\n        arrayEnd();\n    }\n\n    /**\n    Generate the \"compilerInfo\" object which contains information about the compiler\n    such as the filename, version, supported features, etc.\n    */\n    private void generateCompilerInfo()\n    {\n        objectStart();\n        requiredProperty(\"vendor\", global.vendor.toDString);\n        requiredProperty(\"version\", global._version.toDString);\n        property(\"__VERSION__\", global.versionNumber());\n        requiredProperty(\"interface\", determineCompilerInterface());\n        property(\"size_t\", size_t.sizeof);\n        propertyStart(\"platforms\");\n        arrayStart();\n        if (global.params.isWindows)\n        {\n            item(\"windows\");\n        }\n        else\n        {\n            item(\"posix\");\n            if (global.params.isLinux)\n                item(\"linux\");\n            else if (global.params.isOSX)\n                item(\"osx\");\n            else if (global.params.isFreeBSD)\n            {\n                item(\"freebsd\");\n                item(\"bsd\");\n            }\n            else if (global.params.isOpenBSD)\n            {\n                item(\"openbsd\");\n                item(\"bsd\");\n            }\n            else if (global.params.isSolaris)\n            {\n                item(\"solaris\");\n                item(\"bsd\");\n            }\n        }\n        arrayEnd();\n\n        propertyStart(\"architectures\");\n        arrayStart();\n        if (global.params.is64bit)\n            item(\"x86_64\");\n        else\n            version(X86) item(\"x86\");\n        arrayEnd();\n\n        propertyStart(\"predefinedVersions\");\n        arrayStart();\n        if (global.versionids)\n        {\n            foreach (const versionid; *global.versionids)\n            {\n                item(versionid.toString());\n            }\n        }\n        arrayEnd();\n\n        propertyStart(\"supportedFeatures\");\n        {\n            objectStart();\n            scope(exit) objectEnd();\n            propertyBool(\"includeImports\", true);\n        }\n        objectEnd();\n    }\n\n    /**\n    Generate the \"buildInfo\" object which contains information specific to the\n    current build such as CWD, importPaths, configFile, etc.\n    */\n    private void generateBuildInfo()\n    {\n        objectStart();\n        requiredProperty(\"cwd\", getcwd(null, 0).toDString);\n        requiredProperty(\"argv0\", global.params.argv0);\n        requiredProperty(\"config\", global.inifilename.toDString);\n        requiredProperty(\"libName\", global.params.libname.toDString);\n\n        propertyStart(\"importPaths\");\n        arrayStart();\n        if (global.params.imppath)\n        {\n            foreach (importPath; *global.params.imppath)\n            {\n                item(importPath.toDString);\n            }\n        }\n        arrayEnd();\n\n        propertyStart(\"objectFiles\");\n        arrayStart();\n        foreach (objfile; global.params.objfiles)\n        {\n            item(objfile.toDString);\n        }\n        arrayEnd();\n\n        propertyStart(\"libraryFiles\");\n        arrayStart();\n        foreach (lib; global.params.libfiles)\n        {\n            item(lib.toDString);\n        }\n        arrayEnd();\n\n        propertyStart(\"ddocFiles\");\n        arrayStart();\n        foreach (ddocFile; global.params.ddocfiles)\n        {\n            item(ddocFile.toDString);\n        }\n        arrayEnd();\n\n        requiredProperty(\"mapFile\", global.params.mapfile.toDString);\n        requiredProperty(\"resourceFile\", global.params.resfile.toDString);\n        requiredProperty(\"defFile\", global.params.deffile.toDString);\n\n        objectEnd();\n    }\n\n    /**\n    Generate the \"semantics\" object which contains a 'modules' field representing\n    semantic information about all the modules used in the compilation such as\n    module name, isRoot, contentImportedFiles, etc.\n    */\n    private void generateSemantics()\n    {\n        objectStart();\n        propertyStart(\"modules\");\n        arrayStart();\n        foreach (m; Module.amodules)\n        {\n            objectStart();\n            requiredProperty(\"name\", m.md ? m.md.toString() : null);\n            requiredProperty(\"file\", m.srcfile.toString());\n            propertyBool(\"isRoot\", m.isRoot());\n            if(m.contentImportedFiles.dim > 0)\n            {\n                propertyStart(\"contentImports\");\n                arrayStart();\n                foreach (file; m.contentImportedFiles)\n                {\n                    item(file.toDString);\n                }\n                arrayEnd();\n            }\n            objectEnd();\n        }\n        arrayEnd();\n        objectEnd();\n    }\n}\n\nextern (C++) void json_generate(OutBuffer* buf, Modules* modules)\n{\n    scope ToJsonVisitor json = new ToJsonVisitor(buf);\n    // write trailing newline\n    scope(exit) buf.writeByte('\\n');\n\n    if (global.params.jsonFieldFlags == 0)\n    {\n        // Generate the original format, which is just an array\n        // of modules representing their syntax.\n        json.generateModules(modules);\n        json.removeComma();\n    }\n    else\n    {\n        // Generate the new format which is an object where each\n        // output option is its own field.\n\n        json.objectStart();\n        if (global.params.jsonFieldFlags & JsonFieldFlags.compilerInfo)\n        {\n            json.propertyStart(\"compilerInfo\");\n            json.generateCompilerInfo();\n        }\n        if (global.params.jsonFieldFlags & JsonFieldFlags.buildInfo)\n        {\n            json.propertyStart(\"buildInfo\");\n            json.generateBuildInfo();\n        }\n        if (global.params.jsonFieldFlags & JsonFieldFlags.modules)\n        {\n            json.propertyStart(\"modules\");\n            json.generateModules(modules);\n        }\n        if (global.params.jsonFieldFlags & JsonFieldFlags.semantics)\n        {\n            json.propertyStart(\"semantics\");\n            json.generateSemantics();\n        }\n        json.objectEnd();\n    }\n}\n\n/**\nA string listing the name of each JSON field. Useful for errors messages.\n*/\nenum jsonFieldNames = () {\n    string s;\n    string prefix = \"\";\n    foreach (idx, enumName; __traits(allMembers, JsonFieldFlags))\n    {\n        static if (idx > 0)\n        {\n            s ~= prefix ~ \"`\" ~ enumName ~ \"`\";\n            prefix = \", \";\n        }\n    }\n    return s;\n}();\n\n/**\nParse the given `fieldName` and return its corresponding JsonFieldFlags value.\n\nParams:\n fieldName = the field name to parse\n\nReturns: JsonFieldFlags.none on error, otherwise the JsonFieldFlags value\n         corresponding to the given fieldName.\n*/\nJsonFieldFlags tryParseJsonField(const(char)* fieldName)\n{\n    auto fieldNameString = fieldName[0 .. strlen(fieldName)];\n    foreach (idx, enumName; __traits(allMembers, JsonFieldFlags))\n    {\n        static if (idx > 0)\n        {\n            if (fieldNameString == enumName)\n                return __traits(getMember, JsonFieldFlags, enumName);\n        }\n    }\n    return JsonFieldFlags.none;\n}\n\n/**\nDetermines and returns the compiler interface which is one of `dmd`, `ldc`,\n`gdc` or `sdc`. Returns `null` if no interface can be determined.\n*/\nprivate extern(D) string determineCompilerInterface()\n{\n    if (!strcmp(global.vendor, \"Digital Mars D\"))\n        return \"dmd\";\n    if (!strcmp(global.vendor, \"LDC\"))\n        return \"ldc\";\n    if (!strcmp(global.vendor, \"GNU\"))\n        return \"gdc\";\n    if (!strcmp(global.vendor, \"SDC\"))\n        return \"sdc\";\n    return null;\n}\n"
  },
  {
    "path": "gcc/d/dmd/json.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/json.h\n */\n\n#pragma once\n\n#include \"arraytypes.h\"\n\nstruct OutBuffer;\n\nvoid json_generate(OutBuffer *, Modules *);\n"
  },
  {
    "path": "gcc/d/dmd/lambdacomp.d",
    "content": "/***\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * This modules implements the serialization of a lambda function. The serialization\n * is computed by visiting the abstract syntax subtree of the given lambda function.\n * The serialization is a string which contains the type of the parameters and the\n * string represantation of the lambda expression.\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/lamdbacomp.d, _lambdacomp.d)\n * Documentation:  https://dlang.org/phobos/dmd_lambdacomp.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/lambdacomp.d\n */\n\nmodule dmd.lambdacomp;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\n\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dsymbol;\nimport dmd.dtemplate;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.dmangle;\nimport dmd.mtype;\nimport dmd.root.outbuffer;\nimport dmd.root.stringtable;\nimport dmd.dscope;\nimport dmd.statement;\nimport dmd.tokens;\nimport dmd.visitor;\n\nenum LOG = false;\n\n/**\n * The type of the visited expression.\n */\nprivate enum ExpType\n{\n    None,\n    EnumDecl,\n    Arg\n}\n\n/**\n * Compares 2 lambda functions described by their serialization.\n *\n * Params:\n *  l1 = first lambda to be compared\n *  l2 = second lambda to be compared\n *  sc = the scope where the lambdas are compared\n *\n * Returns:\n *  `true` if the 2 lambda functions are equal, `false` otherwise\n */\nbool isSameFuncLiteral(FuncLiteralDeclaration l1, FuncLiteralDeclaration l2, Scope* sc)\n{\n    if (auto ser1 = getSerialization(l1, sc))\n    {\n        //printf(\"l1 serialization: %s\\n\", &ser1[0]);\n        if (auto ser2 = getSerialization(l2, sc))\n        {\n            //printf(\"l2 serialization: %s\\n\", &ser2[0]);\n            if (ser1 == ser2)\n                return true;\n        }\n    }\n    return false;\n}\n\n/**\n * Computes the string representation of a\n * lambda function described by the subtree starting from a\n * $(REF dmd, func, FuncLiteralDeclaration).\n *\n * Limitations: only IntegerExps, Enums and function\n * arguments are supported in the lambda function body. The\n * arguments may be of any type (basic types, user defined types),\n * except template instantiations. If a function call, a local\n * variable or a template instance is encountered, the\n * serialization is dropped and the function is considered\n * uncomparable.\n *\n * Params:\n *  fld = the starting AST node for the lambda function\n *  sc = the scope in which the lambda function is located\n *\n * Returns:\n *  The serielization of `fld`.\n */\nprivate string getSerialization(FuncLiteralDeclaration fld, Scope* sc)\n{\n    scope serVisitor = new SerializeVisitor(sc);\n    fld.accept(serVisitor);\n    const len = serVisitor.buf.offset;\n    if (len == 0)\n        return null;\n\n    return cast(string)serVisitor.buf.extractString()[0 .. len];\n}\n\nprivate extern (C++) class SerializeVisitor : SemanticTimeTransitiveVisitor\n{\nprivate:\n    StringTable arg_hash;\n    Scope* sc;\n    ExpType et;\n    Dsymbol d;\n\npublic:\n    OutBuffer buf;\n    alias visit = SemanticTimeTransitiveVisitor.visit;\n\n    this(Scope* sc)\n    {\n        this.sc = sc;\n    }\n\n    /**\n     * Entrypoint of the SerializeVisitor.\n     *\n     * Params:\n     *     fld = the lambda function for which the serialization is computed\n     */\n    override void visit(FuncLiteralDeclaration fld)\n    {\n        assert(fld.type.ty != Terror);\n        static if (LOG)\n            printf(\"FuncLiteralDeclaration: %s\\n\", fld.toChars());\n\n        TypeFunction tf = cast(TypeFunction)fld.type;\n        uint dim = cast(uint)Parameter.dim(tf.parameters);\n        // Start the serialization by printing the number of\n        // arguments the lambda has.\n        buf.printf(\"%d:\", dim);\n\n        arg_hash._init(dim + 1);\n        // For each argument\n        foreach (i; 0 .. dim)\n        {\n            auto fparam = Parameter.getNth(tf.parameters, i);\n            if (fparam.ident !is null)\n            {\n                // the variable name is introduced into a hashtable\n                // where the key is the user defined name and the\n                // value is the cannonically name (arg0, arg1 ...)\n                auto key = fparam.ident.toString();\n                OutBuffer value;\n                value.writestring(\"arg\");\n                value.print(i);\n                arg_hash.insert(&key[0], key.length, value.extractString);\n                // and the type of the variable is serialized.\n                fparam.accept(this);\n            }\n        }\n\n        // Now the function body can be serialized.\n        ReturnStatement rs = fld.fbody.isReturnStatement();\n        if (rs && rs.exp)\n        {\n            rs.exp.accept(this);\n        }\n        else\n        {\n            buf.offset = 0;\n        }\n    }\n\n    override void visit(DotIdExp exp)\n    {\n        static if (LOG)\n            printf(\"DotIdExp: %s\\n\", exp.toChars());\n        if (buf.offset == 0)\n            return;\n\n        // First we need to see what kind of expression e1 is.\n        // It might an enum member (enum.value)  or the field of\n        // an argument (argX.value) if the argument is an aggregate\n        // type. This is reported through the et variable.\n        exp.e1.accept(this);\n        if (buf.offset == 0)\n            return;\n\n        if (et == ExpType.EnumDecl)\n        {\n            Dsymbol s = d.search(exp.loc, exp.ident);\n            if (s)\n            {\n                if (auto em = s.isEnumMember())\n                {\n                    em.value.accept(this);\n                }\n                et = ExpType.None;\n                d = null;\n            }\n        }\n\n        else if (et == ExpType.Arg)\n        {\n            buf.setsize(buf.offset -1);\n            buf.writeByte('.');\n            buf.writestring(exp.ident.toString());\n            buf.writeByte('_');\n        }\n    }\n\n    bool checkArgument(const(char)* id)\n    {\n        // The identifier may be an argument\n        auto stringtable_value = arg_hash.lookup(id, strlen(id));\n        if (stringtable_value)\n        {\n            // In which case we need to update the serialization accordingly\n            const(char)* gen_id = cast(const(char)*)stringtable_value.ptrvalue;\n            buf.writestring(gen_id);\n            buf.writeByte('_');\n            et = ExpType.Arg;\n            return true;\n        }\n        return false;\n    }\n\n    override void visit(IdentifierExp exp)\n    {\n        static if (LOG)\n            printf(\"IdentifierExp: %s\\n\", exp.toChars());\n\n        if (buf.offset == 0)\n            return;\n\n        auto id = exp.ident.toChars();\n\n        // If it's not an argument\n        if (!checkArgument(id))\n        {\n            // we must check what the identifier expression is.\n            Dsymbol scopesym;\n            Dsymbol s = sc.search(exp.loc, exp.ident, &scopesym);\n            if (s)\n            {\n                auto v = s.isVarDeclaration();\n                // If it's a VarDeclaration, it must be a manifest constant\n                if (v && (v.storage_class & STC.manifest))\n                {\n                    v.getConstInitializer.accept(this);\n                }\n                else if (auto em = s.isEnumDeclaration())\n                {\n                    d = em;\n                    et = ExpType.EnumDecl;\n                }\n                else if (auto fd = s.isFuncDeclaration())\n                {\n                    writeMangledName(fd);\n                }\n                // For anything else, the function is deemed uncomparable\n                else\n                {\n                    buf.reset();\n                }\n            }\n        }\n    }\n\n    override void visit(DotVarExp exp)\n    {\n        static if (LOG)\n            printf(\"DotVarExp: %s, var: %s, e1: %s\\n\", exp.toChars(),\n                    exp.var.toChars(), exp.e1.toChars());\n\n        exp.e1.accept(this);\n        if (buf.offset == 0)\n            return;\n\n        buf.setsize(buf.offset -1);\n        buf.writeByte('.');\n        buf.writestring(exp.var.toChars());\n        buf.writeByte('_');\n    }\n\n    override void visit(VarExp exp)\n    {\n        static if (LOG)\n            printf(\"VarExp: %s, var: %s\\n\", exp.toChars(), exp.var.toChars());\n\n        if (buf.offset == 0)\n            return;\n\n        auto id = exp.var.ident.toChars();\n        if (!checkArgument(id))\n        {\n            buf.offset = 0;\n        }\n    }\n\n    // serialize function calls\n    override void visit(CallExp exp)\n    {\n        static if (LOG)\n            printf(\"CallExp: %s\\n\", exp.toChars());\n\n        if (buf.offset == 0)\n            return;\n\n        if (!exp.f)\n        {\n            exp.e1.accept(this);\n        }\n        else\n        {\n            writeMangledName(exp.f);\n        }\n\n        buf.writeByte('(');\n        foreach (arg; *(exp.arguments))\n        {\n            arg.accept(this);\n        }\n        buf.writeByte(')');\n    }\n\n    override void visit(UnaExp exp)\n    {\n        if (buf.offset == 0)\n            return;\n\n        buf.writeByte('(');\n        buf.writestring(Token.toString(exp.op));\n        exp.e1.accept(this);\n        if (buf.offset != 0)\n            buf.writestring(\")_\");\n    }\n\n    override void visit(IntegerExp exp)\n    {\n        if (buf.offset == 0)\n            return;\n\n        buf.print(exp.toInteger());\n        buf.writeByte('_');\n    }\n\n    override void visit(RealExp exp)\n    {\n        if (buf.offset == 0)\n            return;\n\n        buf.writestring(exp.toChars());\n        buf.writeByte('_');\n    }\n\n    override void visit(BinExp exp)\n    {\n        static if (LOG)\n            printf(\"BinExp: %s\\n\", exp.toChars());\n\n        if (buf.offset == 0)\n            return;\n\n        buf.writeByte('(');\n        buf.writestring(Token.toChars(exp.op));\n\n        exp.e1.accept(this);\n        if (buf.offset == 0)\n            return;\n\n        exp.e2.accept(this);\n        if (buf.offset == 0)\n            return;\n\n        buf.writeByte(')');\n    }\n\n    override void visit(TypeBasic t)\n    {\n        buf.writestring(t.dstring);\n        buf.writeByte('_');\n    }\n\n    void writeMangledName(Dsymbol s)\n    {\n        if (s)\n        {\n            OutBuffer mangledName;\n            mangleToBuffer(s, &mangledName);\n            buf.writestring(mangledName.peekSlice);\n            buf.writeByte('_');\n        }\n        else\n            buf.reset();\n    }\n\n    private bool checkTemplateInstance(T)(T t)\n        if (is(T == TypeStruct) || is(T == TypeClass))\n    {\n        if (t.sym.parent && t.sym.parent.isTemplateInstance())\n        {\n            buf.reset();\n            return true;\n        }\n        return false;\n    }\n\n    override void visit(TypeStruct t)\n    {\n        static if (LOG)\n            printf(\"TypeStruct: %s\\n\", t.toChars);\n\n        if (!checkTemplateInstance!TypeStruct(t))\n            writeMangledName(t.sym);\n    }\n\n    override void visit(TypeClass t)\n    {\n        static if (LOG)\n            printf(\"TypeClass: %s\\n\", t.toChars());\n\n        if (!checkTemplateInstance!TypeClass(t))\n            writeMangledName(t.sym);\n    }\n\n    override void visit(Parameter p)\n    {\n        if (p.type.ty == Tident\n            && (cast(TypeIdentifier)p.type).ident.toString().length > 3\n            && strncmp((cast(TypeIdentifier)p.type).ident.toChars(), \"__T\", 3) == 0)\n        {\n            buf.writestring(\"none_\");\n        }\n        else\n            visitType(p.type);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/lexer.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/lexer.d, _lexer.d)\n * Documentation:  https://dlang.org/phobos/dmd_lexer.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/lexer.d\n */\n\nmodule dmd.lexer;\n\nimport core.stdc.ctype;\nimport core.stdc.errno;\nimport core.stdc.stdarg;\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport core.stdc.time;\n\nimport dmd.entity;\nimport dmd.errors;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.root.ctfloat;\nimport dmd.root.outbuffer;\nimport dmd.root.port;\nimport dmd.root.rmem;\nimport dmd.tokens;\nimport dmd.utf;\n\nenum LS = 0x2028;       // UTF line separator\nenum PS = 0x2029;       // UTF paragraph separator\n\n/********************************************\n * Do our own char maps\n */\nstatic immutable cmtable = () {\n    ubyte[256] table;\n    foreach (const c; 0 .. table.length)\n    {\n        if ('0' <= c && c <= '7')\n            table[c] |= CMoctal;\n        if (c_isxdigit(c))\n            table[c] |= CMhex;\n        if (c_isalnum(c) || c == '_')\n            table[c] |= CMidchar;\n\n        switch (c)\n        {\n            case 'x': case 'X':\n            case 'b': case 'B':\n                table[c] |= CMzerosecond;\n                break;\n\n            case '0': .. case '9':\n            case 'e': case 'E':\n            case 'f': case 'F':\n            case 'l': case 'L':\n            case 'p': case 'P':\n            case 'u': case 'U':\n            case 'i':\n            case '.':\n            case '_':\n                table[c] |= CMzerosecond | CMdigitsecond;\n                break;\n\n            default:\n                break;\n        }\n\n        switch (c)\n        {\n            case '\\\\':\n            case '\\n':\n            case '\\r':\n            case 0:\n            case 0x1A:\n            case '\\'':\n                break;\n            default:\n                if (!(c & 0x80))\n                    table[c] |= CMsinglechar;\n                break;\n        }\n    }\n    return table;\n}();\n\nenum CMoctal  = 0x1;\nenum CMhex    = 0x2;\nenum CMidchar = 0x4;\nenum CMzerosecond = 0x8;\nenum CMdigitsecond = 0x10;\nenum CMsinglechar = 0x20;\n\nbool isoctal(const char c)\n{\n    return (cmtable[c] & CMoctal) != 0;\n}\n\nbool ishex(const char c)\n{\n    return (cmtable[c] & CMhex) != 0;\n}\n\nbool isidchar(const char c)\n{\n    return (cmtable[c] & CMidchar) != 0;\n}\n\nbool isZeroSecond(const char c)\n{\n    return (cmtable[c] & CMzerosecond) != 0;\n}\n\nbool isDigitSecond(const char c)\n{\n    return (cmtable[c] & CMdigitsecond) != 0;\n}\n\nbool issinglechar(const char c)\n{\n    return (cmtable[c] & CMsinglechar) != 0;\n}\n\nprivate bool c_isxdigit(const int c)\n{\n    return (( c >= '0' && c <= '9') ||\n            ( c >= 'a' && c <= 'f') ||\n            ( c >= 'A' && c <= 'F'));\n}\n\nprivate bool c_isalnum(const int c)\n{\n    return (( c >= '0' && c <= '9') ||\n            ( c >= 'a' && c <= 'z') ||\n            ( c >= 'A' && c <= 'Z'));\n}\n\nunittest\n{\n    //printf(\"lexer.unittest\\n\");\n    /* Not much here, just trying things out.\n     */\n    string text = \"int\"; // We rely on the implicit null-terminator\n    scope Lexer lex1 = new Lexer(null, text.ptr, 0, text.length, 0, 0);\n    TOK tok;\n    tok = lex1.nextToken();\n    //printf(\"tok == %s, %d, %d\\n\", Token::toChars(tok), tok, TOK.int32);\n    assert(tok == TOK.int32);\n    tok = lex1.nextToken();\n    assert(tok == TOK.endOfFile);\n    tok = lex1.nextToken();\n    assert(tok == TOK.endOfFile);\n    tok = lex1.nextToken();\n    assert(tok == TOK.endOfFile);\n}\n\nunittest\n{\n    // We don't want to see Lexer error output during these tests.\n    uint errors = global.startGagging();\n    scope(exit) global.endGagging(errors);\n\n    // Test malformed input: even malformed input should end in a TOK.endOfFile.\n    static immutable char[][] testcases =\n    [   // Testcase must end with 0 or 0x1A.\n        [0], // not malformed, but pathological\n        ['\\'', 0],\n        ['\\'', 0x1A],\n        ['{', '{', 'q', '{', 0],\n        [0xFF, 0],\n        [0xFF, 0x80, 0],\n        [0xFF, 0xFF, 0],\n        [0xFF, 0xFF, 0],\n        ['x', '\"', 0x1A],\n    ];\n\n    foreach (testcase; testcases)\n    {\n        scope Lexer lex2 = new Lexer(null, testcase.ptr, 0, testcase.length-1, 0, 0);\n        TOK tok = lex2.nextToken();\n        size_t iterations = 1;\n        while ((tok != TOK.endOfFile) && (iterations++ < testcase.length))\n        {\n            tok = lex2.nextToken();\n        }\n        assert(tok == TOK.endOfFile);\n        tok = lex2.nextToken();\n        assert(tok == TOK.endOfFile);\n    }\n}\n\n/**\nHandles error messages\n*/\nclass ErrorHandler\n{\n    /**\n    Report an error message.\n    Params:\n        format = format string for error\n        ... = format string arguments\n    */\n    abstract void error(const(char)* format, ...);\n\n    /**\n    Report an error message.\n    Params:\n        loc = Location of error\n        format = format string for error\n        ... = format string arguments\n    */\n    abstract void error(Loc loc, const(char)* format, ...);\n}\n\n/***********************************************************\n */\nclass Lexer : ErrorHandler\n{\n    __gshared OutBuffer stringbuffer;\n\n    Loc scanloc;            // for error messages\n    Loc prevloc;            // location of token before current\n\n    const(char)* base;      // pointer to start of buffer\n    const(char)* end;       // pointer to last element of buffer\n    const(char)* p;         // current character\n    const(char)* line;      // start of current line\n    Token token;\n    bool doDocComment;      // collect doc comment information\n    bool anyToken;          // seen at least one token\n    bool commentToken;      // comments are TOK.comment's\n    int lastDocLine;        // last line of previous doc comment\n    bool errors;            // errors occurred during lexing or parsing\n\n    /*********************\n     * Creates a Lexer for the source code base[begoffset..endoffset+1].\n     * The last character, base[endoffset], must be null (0) or EOF (0x1A).\n     *\n     * Params:\n     *  filename = used for error messages\n     *  base = source code, must be terminated by a null (0) or EOF (0x1A) character\n     *  begoffset = starting offset into base[]\n     *  endoffset = the last offset to read into base[]\n     *  doDocComment = handle documentation comments\n     *  commentToken = comments become TOK.comment's\n     */\n    this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset, bool doDocComment, bool commentToken)\n    {\n        scanloc = Loc(filename, 1, 1);\n        //printf(\"Lexer::Lexer(%p,%d)\\n\",base,length);\n        //printf(\"lexer.filename = %s\\n\", filename);\n        token = Token.init;\n        this.base = base;\n        this.end = base + endoffset;\n        p = base + begoffset;\n        line = p;\n        this.doDocComment = doDocComment;\n        this.commentToken = commentToken;\n        this.lastDocLine = 0;\n        //initKeywords();\n        /* If first line starts with '#!', ignore the line\n         */\n        if (p && p[0] == '#' && p[1] == '!')\n        {\n            p += 2;\n            while (1)\n            {\n                char c = *p++;\n                switch (c)\n                {\n                case 0:\n                case 0x1A:\n                    p--;\n                    goto case;\n                case '\\n':\n                    break;\n                default:\n                    continue;\n                }\n                break;\n            }\n            endOfLine();\n        }\n    }\n\n    final TOK nextToken()\n    {\n        prevloc = token.loc;\n        if (token.next)\n        {\n            Token* t = token.next;\n            memcpy(&token, t, Token.sizeof);\n            t.free();\n        }\n        else\n        {\n            scan(&token);\n        }\n        //printf(token.toChars());\n        return token.value;\n    }\n\n    /***********************\n     * Look ahead at next token's value.\n     */\n    final TOK peekNext()\n    {\n        return peek(&token).value;\n    }\n\n    /***********************\n     * Look 2 tokens ahead at value.\n     */\n    final TOK peekNext2()\n    {\n        Token* t = peek(&token);\n        return peek(t).value;\n    }\n\n    /****************************\n     * Turn next token in buffer into a token.\n     */\n    final void scan(Token* t)\n    {\n        const lastLine = scanloc.linnum;\n        Loc startLoc;\n        t.blockComment = null;\n        t.lineComment = null;\n\n        while (1)\n        {\n            t.ptr = p;\n            //printf(\"p = %p, *p = '%c'\\n\",p,*p);\n            t.loc = loc();\n            switch (*p)\n            {\n            case 0:\n            case 0x1A:\n                t.value = TOK.endOfFile; // end of file\n                // Intentionally not advancing `p`, such that subsequent calls keep returning TOK.endOfFile.\n                return;\n            case ' ':\n            case '\\t':\n            case '\\v':\n            case '\\f':\n                p++;\n                continue; // skip white space\n            case '\\r':\n                p++;\n                if (*p != '\\n') // if CR stands by itself\n                    endOfLine();\n                continue; // skip white space\n            case '\\n':\n                p++;\n                endOfLine();\n                continue; // skip white space\n            case '0':\n                if (!isZeroSecond(p[1]))        // if numeric literal does not continue\n                {\n                    ++p;\n                    t.unsvalue = 0;\n                    t.value = TOK.int32Literal;\n                    return;\n                }\n                goto Lnumber;\n\n            case '1': .. case '9':\n                if (!isDigitSecond(p[1]))       // if numeric literal does not continue\n                {\n                    t.unsvalue = *p - '0';\n                    ++p;\n                    t.value = TOK.int32Literal;\n                    return;\n                }\n            Lnumber:\n                t.value = number(t);\n                return;\n\n            case '\\'':\n                if (issinglechar(p[1]) && p[2] == '\\'')\n                {\n                    t.unsvalue = p[1];        // simple one character literal\n                    t.value = TOK.charLiteral;\n                    p += 3;\n                }\n                else\n                    t.value = charConstant(t);\n                return;\n            case 'r':\n                if (p[1] != '\"')\n                    goto case_ident;\n                p++;\n                goto case '`';\n            case '`':\n                wysiwygStringConstant(t);\n                return;\n            case 'x':\n                if (p[1] != '\"')\n                    goto case_ident;\n                p++;\n                t.value = hexStringConstant(t);\n                deprecation(\"Built-in hex string literals are deprecated, use `std.conv.hexString` instead.\");\n                return;\n            case 'q':\n                if (p[1] == '\"')\n                {\n                    p++;\n                    delimitedStringConstant(t);\n                    return;\n                }\n                else if (p[1] == '{')\n                {\n                    p++;\n                    tokenStringConstant(t);\n                    return;\n                }\n                else\n                    goto case_ident;\n            case '\"':\n                escapeStringConstant(t);\n                return;\n            case 'a':\n            case 'b':\n            case 'c':\n            case 'd':\n            case 'e':\n            case 'f':\n            case 'g':\n            case 'h':\n            case 'i':\n            case 'j':\n            case 'k':\n            case 'l':\n            case 'm':\n            case 'n':\n            case 'o':\n            case 'p':\n                /*case 'q': case 'r':*/\n            case 's':\n            case 't':\n            case 'u':\n            case 'v':\n            case 'w':\n                /*case 'x':*/\n            case 'y':\n            case 'z':\n            case 'A':\n            case 'B':\n            case 'C':\n            case 'D':\n            case 'E':\n            case 'F':\n            case 'G':\n            case 'H':\n            case 'I':\n            case 'J':\n            case 'K':\n            case 'L':\n            case 'M':\n            case 'N':\n            case 'O':\n            case 'P':\n            case 'Q':\n            case 'R':\n            case 'S':\n            case 'T':\n            case 'U':\n            case 'V':\n            case 'W':\n            case 'X':\n            case 'Y':\n            case 'Z':\n            case '_':\n            case_ident:\n                {\n                    while (1)\n                    {\n                        const c = *++p;\n                        if (isidchar(c))\n                            continue;\n                        else if (c & 0x80)\n                        {\n                            const s = p;\n                            const u = decodeUTF();\n                            if (isUniAlpha(u))\n                                continue;\n                            error(\"char 0x%04x not allowed in identifier\", u);\n                            p = s;\n                        }\n                        break;\n                    }\n                    Identifier id = Identifier.idPool(cast(char*)t.ptr, cast(uint)(p - t.ptr));\n                    t.ident = id;\n                    t.value = cast(TOK)id.getValue();\n                    anyToken = 1;\n                    if (*t.ptr == '_') // if special identifier token\n                    {\n                        __gshared bool initdone = false;\n                        __gshared char[11 + 1] date;\n                        __gshared char[8 + 1] time;\n                        __gshared char[24 + 1] timestamp;\n                        if (!initdone) // lazy evaluation\n                        {\n                            initdone = true;\n                            time_t ct;\n                            .time(&ct);\n                            const p = ctime(&ct);\n                            assert(p);\n                            sprintf(&date[0], \"%.6s %.4s\", p + 4, p + 20);\n                            sprintf(&time[0], \"%.8s\", p + 11);\n                            sprintf(&timestamp[0], \"%.24s\", p);\n                        }\n                        if (id == Id.DATE)\n                        {\n                            t.ustring = date.ptr;\n                            goto Lstr;\n                        }\n                        else if (id == Id.TIME)\n                        {\n                            t.ustring = time.ptr;\n                            goto Lstr;\n                        }\n                        else if (id == Id.VENDOR)\n                        {\n                            t.ustring = global.vendor;\n                            goto Lstr;\n                        }\n                        else if (id == Id.TIMESTAMP)\n                        {\n                            t.ustring = timestamp.ptr;\n                        Lstr:\n                            t.value = TOK.string_;\n                            t.postfix = 0;\n                            t.len = cast(uint)strlen(t.ustring);\n                        }\n                        else if (id == Id.VERSIONX)\n                        {\n                            t.value = TOK.int64Literal;\n                            t.unsvalue = global.versionNumber();\n                        }\n                        else if (id == Id.EOFX)\n                        {\n                            t.value = TOK.endOfFile;\n                            // Advance scanner to end of file\n                            while (!(*p == 0 || *p == 0x1A))\n                                p++;\n                        }\n                    }\n                    //printf(\"t.value = %d\\n\",t.value);\n                    return;\n                }\n            case '/':\n                p++;\n                switch (*p)\n                {\n                case '=':\n                    p++;\n                    t.value = TOK.divAssign;\n                    return;\n                case '*':\n                    p++;\n                    startLoc = loc();\n                    while (1)\n                    {\n                        while (1)\n                        {\n                            const c = *p;\n                            switch (c)\n                            {\n                            case '/':\n                                break;\n                            case '\\n':\n                                endOfLine();\n                                p++;\n                                continue;\n                            case '\\r':\n                                p++;\n                                if (*p != '\\n')\n                                    endOfLine();\n                                continue;\n                            case 0:\n                            case 0x1A:\n                                error(\"unterminated /* */ comment\");\n                                p = end;\n                                t.loc = loc();\n                                t.value = TOK.endOfFile;\n                                return;\n                            default:\n                                if (c & 0x80)\n                                {\n                                    const u = decodeUTF();\n                                    if (u == PS || u == LS)\n                                        endOfLine();\n                                }\n                                p++;\n                                continue;\n                            }\n                            break;\n                        }\n                        p++;\n                        if (p[-2] == '*' && p - 3 != t.ptr)\n                            break;\n                    }\n                    if (commentToken)\n                    {\n                        t.loc = startLoc;\n                        t.value = TOK.comment;\n                        return;\n                    }\n                    else if (doDocComment && t.ptr[2] == '*' && p - 4 != t.ptr)\n                    {\n                        // if /** but not /**/\n                        getDocComment(t, lastLine == startLoc.linnum, startLoc.linnum - lastDocLine > 1);\n                        lastDocLine = scanloc.linnum;\n                    }\n                    continue;\n                case '/': // do // style comments\n                    startLoc = loc();\n                    while (1)\n                    {\n                        const c = *++p;\n                        switch (c)\n                        {\n                        case '\\n':\n                            break;\n                        case '\\r':\n                            if (p[1] == '\\n')\n                                p++;\n                            break;\n                        case 0:\n                        case 0x1A:\n                            if (commentToken)\n                            {\n                                p = end;\n                                t.loc = startLoc;\n                                t.value = TOK.comment;\n                                return;\n                            }\n                            if (doDocComment && t.ptr[2] == '/')\n                            {\n                                getDocComment(t, lastLine == startLoc.linnum, startLoc.linnum - lastDocLine > 1);\n                                lastDocLine = scanloc.linnum;\n                            }\n                            p = end;\n                            t.loc = loc();\n                            t.value = TOK.endOfFile;\n                            return;\n                        default:\n                            if (c & 0x80)\n                            {\n                                const u = decodeUTF();\n                                if (u == PS || u == LS)\n                                    break;\n                            }\n                            continue;\n                        }\n                        break;\n                    }\n                    if (commentToken)\n                    {\n                        p++;\n                        endOfLine();\n                        t.loc = startLoc;\n                        t.value = TOK.comment;\n                        return;\n                    }\n                    if (doDocComment && t.ptr[2] == '/')\n                    {\n                        getDocComment(t, lastLine == startLoc.linnum, startLoc.linnum - lastDocLine > 1);\n                        lastDocLine = scanloc.linnum;\n                    }\n                    p++;\n                    endOfLine();\n                    continue;\n                case '+':\n                    {\n                        int nest;\n                        startLoc = loc();\n                        p++;\n                        nest = 1;\n                        while (1)\n                        {\n                            char c = *p;\n                            switch (c)\n                            {\n                            case '/':\n                                p++;\n                                if (*p == '+')\n                                {\n                                    p++;\n                                    nest++;\n                                }\n                                continue;\n                            case '+':\n                                p++;\n                                if (*p == '/')\n                                {\n                                    p++;\n                                    if (--nest == 0)\n                                        break;\n                                }\n                                continue;\n                            case '\\r':\n                                p++;\n                                if (*p != '\\n')\n                                    endOfLine();\n                                continue;\n                            case '\\n':\n                                endOfLine();\n                                p++;\n                                continue;\n                            case 0:\n                            case 0x1A:\n                                error(\"unterminated /+ +/ comment\");\n                                p = end;\n                                t.loc = loc();\n                                t.value = TOK.endOfFile;\n                                return;\n                            default:\n                                if (c & 0x80)\n                                {\n                                    uint u = decodeUTF();\n                                    if (u == PS || u == LS)\n                                        endOfLine();\n                                }\n                                p++;\n                                continue;\n                            }\n                            break;\n                        }\n                        if (commentToken)\n                        {\n                            t.loc = startLoc;\n                            t.value = TOK.comment;\n                            return;\n                        }\n                        if (doDocComment && t.ptr[2] == '+' && p - 4 != t.ptr)\n                        {\n                            // if /++ but not /++/\n                            getDocComment(t, lastLine == startLoc.linnum, startLoc.linnum - lastDocLine > 1);\n                            lastDocLine = scanloc.linnum;\n                        }\n                        continue;\n                    }\n                default:\n                    break;\n                }\n                t.value = TOK.div;\n                return;\n            case '.':\n                p++;\n                if (isdigit(*p))\n                {\n                    /* Note that we don't allow ._1 and ._ as being\n                     * valid floating point numbers.\n                     */\n                    p--;\n                    t.value = inreal(t);\n                }\n                else if (p[0] == '.')\n                {\n                    if (p[1] == '.')\n                    {\n                        p += 2;\n                        t.value = TOK.dotDotDot;\n                    }\n                    else\n                    {\n                        p++;\n                        t.value = TOK.slice;\n                    }\n                }\n                else\n                    t.value = TOK.dot;\n                return;\n            case '&':\n                p++;\n                if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.andAssign;\n                }\n                else if (*p == '&')\n                {\n                    p++;\n                    t.value = TOK.andAnd;\n                }\n                else\n                    t.value = TOK.and;\n                return;\n            case '|':\n                p++;\n                if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.orAssign;\n                }\n                else if (*p == '|')\n                {\n                    p++;\n                    t.value = TOK.orOr;\n                }\n                else\n                    t.value = TOK.or;\n                return;\n            case '-':\n                p++;\n                if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.minAssign;\n                }\n                else if (*p == '-')\n                {\n                    p++;\n                    t.value = TOK.minusMinus;\n                }\n                else\n                    t.value = TOK.min;\n                return;\n            case '+':\n                p++;\n                if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.addAssign;\n                }\n                else if (*p == '+')\n                {\n                    p++;\n                    t.value = TOK.plusPlus;\n                }\n                else\n                    t.value = TOK.add;\n                return;\n            case '<':\n                p++;\n                if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.lessOrEqual; // <=\n                }\n                else if (*p == '<')\n                {\n                    p++;\n                    if (*p == '=')\n                    {\n                        p++;\n                        t.value = TOK.leftShiftAssign; // <<=\n                    }\n                    else\n                        t.value = TOK.leftShift; // <<\n                }\n                else\n                    t.value = TOK.lessThan; // <\n                return;\n            case '>':\n                p++;\n                if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.greaterOrEqual; // >=\n                }\n                else if (*p == '>')\n                {\n                    p++;\n                    if (*p == '=')\n                    {\n                        p++;\n                        t.value = TOK.rightShiftAssign; // >>=\n                    }\n                    else if (*p == '>')\n                    {\n                        p++;\n                        if (*p == '=')\n                        {\n                            p++;\n                            t.value = TOK.unsignedRightShiftAssign; // >>>=\n                        }\n                        else\n                            t.value = TOK.unsignedRightShift; // >>>\n                    }\n                    else\n                        t.value = TOK.rightShift; // >>\n                }\n                else\n                    t.value = TOK.greaterThan; // >\n                return;\n            case '!':\n                p++;\n                if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.notEqual; // !=\n                }\n                else\n                    t.value = TOK.not; // !\n                return;\n            case '=':\n                p++;\n                if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.equal; // ==\n                }\n                else if (*p == '>')\n                {\n                    p++;\n                    t.value = TOK.goesTo; // =>\n                }\n                else\n                    t.value = TOK.assign; // =\n                return;\n            case '~':\n                p++;\n                if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.concatenateAssign; // ~=\n                }\n                else\n                    t.value = TOK.tilde; // ~\n                return;\n            case '^':\n                p++;\n                if (*p == '^')\n                {\n                    p++;\n                    if (*p == '=')\n                    {\n                        p++;\n                        t.value = TOK.powAssign; // ^^=\n                    }\n                    else\n                        t.value = TOK.pow; // ^^\n                }\n                else if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.xorAssign; // ^=\n                }\n                else\n                    t.value = TOK.xor; // ^\n                return;\n            case '(':\n                p++;\n                t.value = TOK.leftParentheses;\n                return;\n            case ')':\n                p++;\n                t.value = TOK.rightParentheses;\n                return;\n            case '[':\n                p++;\n                t.value = TOK.leftBracket;\n                return;\n            case ']':\n                p++;\n                t.value = TOK.rightBracket;\n                return;\n            case '{':\n                p++;\n                t.value = TOK.leftCurly;\n                return;\n            case '}':\n                p++;\n                t.value = TOK.rightCurly;\n                return;\n            case '?':\n                p++;\n                t.value = TOK.question;\n                return;\n            case ',':\n                p++;\n                t.value = TOK.comma;\n                return;\n            case ';':\n                p++;\n                t.value = TOK.semicolon;\n                return;\n            case ':':\n                p++;\n                t.value = TOK.colon;\n                return;\n            case '$':\n                p++;\n                t.value = TOK.dollar;\n                return;\n            case '@':\n                p++;\n                t.value = TOK.at;\n                return;\n            case '*':\n                p++;\n                if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.mulAssign;\n                }\n                else\n                    t.value = TOK.mul;\n                return;\n            case '%':\n                p++;\n                if (*p == '=')\n                {\n                    p++;\n                    t.value = TOK.modAssign;\n                }\n                else\n                    t.value = TOK.mod;\n                return;\n            case '#':\n                {\n                    p++;\n                    Token n;\n                    scan(&n);\n                    if (n.value == TOK.identifier)\n                    {\n                        if (n.ident == Id.line)\n                        {\n                            poundLine();\n                            continue;\n                        }\n                        else\n                        {\n                            const locx = loc();\n                            warning(locx, \"C preprocessor directive `#%s` is not supported\", n.ident.toChars());\n                        }\n                    }\n                    else if (n.value == TOK.if_)\n                    {\n                        error(\"C preprocessor directive `#if` is not supported, use `version` or `static if`\");\n                    }\n                    t.value = TOK.pound;\n                    return;\n                }\n            default:\n                {\n                    dchar c = *p;\n                    if (c & 0x80)\n                    {\n                        c = decodeUTF();\n                        // Check for start of unicode identifier\n                        if (isUniAlpha(c))\n                            goto case_ident;\n                        if (c == PS || c == LS)\n                        {\n                            endOfLine();\n                            p++;\n                            continue;\n                        }\n                    }\n                    if (c < 0x80 && isprint(c))\n                        error(\"character '%c' is not a valid token\", c);\n                    else\n                        error(\"character 0x%02x is not a valid token\", c);\n                    p++;\n                    continue;\n                }\n            }\n        }\n    }\n\n    final Token* peek(Token* ct)\n    {\n        Token* t;\n        if (ct.next)\n            t = ct.next;\n        else\n        {\n            t = Token.alloc();\n            scan(t);\n            ct.next = t;\n        }\n        return t;\n    }\n\n    /*********************************\n     * tk is on the opening (.\n     * Look ahead and return token that is past the closing ).\n     */\n    final Token* peekPastParen(Token* tk)\n    {\n        //printf(\"peekPastParen()\\n\");\n        int parens = 1;\n        int curlynest = 0;\n        while (1)\n        {\n            tk = peek(tk);\n            //tk.print();\n            switch (tk.value)\n            {\n            case TOK.leftParentheses:\n                parens++;\n                continue;\n            case TOK.rightParentheses:\n                --parens;\n                if (parens)\n                    continue;\n                tk = peek(tk);\n                break;\n            case TOK.leftCurly:\n                curlynest++;\n                continue;\n            case TOK.rightCurly:\n                if (--curlynest >= 0)\n                    continue;\n                break;\n            case TOK.semicolon:\n                if (curlynest)\n                    continue;\n                break;\n            case TOK.endOfFile:\n                break;\n            default:\n                continue;\n            }\n            return tk;\n        }\n    }\n\n    /*******************************************\n     * Parse escape sequence.\n     */\n    final uint escapeSequence()\n    {\n        return Lexer.escapeSequence(this, p);\n    }\n\n    /**\n    Parse the given string literal escape sequence into a single character.\n    Params:\n        handler = the error handler object\n        sequence = pointer to string with escape sequence to parse. this is a reference\n                   variable that is also used to return the position after the sequence\n    Returns:\n        the escaped sequence as a single character\n    */\n    static dchar escapeSequence(ErrorHandler handler, ref const(char)* sequence)\n    {\n        const(char)* p = sequence; // cache sequence reference on stack\n        scope(exit) sequence = p;\n\n        uint c = *p;\n        int ndigits;\n        switch (c)\n        {\n        case '\\'':\n        case '\"':\n        case '?':\n        case '\\\\':\n        Lconsume:\n            p++;\n            break;\n        case 'a':\n            c = 7;\n            goto Lconsume;\n        case 'b':\n            c = 8;\n            goto Lconsume;\n        case 'f':\n            c = 12;\n            goto Lconsume;\n        case 'n':\n            c = 10;\n            goto Lconsume;\n        case 'r':\n            c = 13;\n            goto Lconsume;\n        case 't':\n            c = 9;\n            goto Lconsume;\n        case 'v':\n            c = 11;\n            goto Lconsume;\n        case 'u':\n            ndigits = 4;\n            goto Lhex;\n        case 'U':\n            ndigits = 8;\n            goto Lhex;\n        case 'x':\n            ndigits = 2;\n        Lhex:\n            p++;\n            c = *p;\n            if (ishex(cast(char)c))\n            {\n                uint v = 0;\n                int n = 0;\n                while (1)\n                {\n                    if (isdigit(cast(char)c))\n                        c -= '0';\n                    else if (islower(c))\n                        c -= 'a' - 10;\n                    else\n                        c -= 'A' - 10;\n                    v = v * 16 + c;\n                    c = *++p;\n                    if (++n == ndigits)\n                        break;\n                    if (!ishex(cast(char)c))\n                    {\n                        handler.error(\"escape hex sequence has %d hex digits instead of %d\", n, ndigits);\n                        break;\n                    }\n                }\n                if (ndigits != 2 && !utf_isValidDchar(v))\n                {\n                    handler.error(\"invalid UTF character \\\\U%08x\", v);\n                    v = '?'; // recover with valid UTF character\n                }\n                c = v;\n            }\n            else\n            {\n                handler.error(\"undefined escape hex sequence \\\\%c%c\", sequence[0], c);\n                p++;\n            }\n            break;\n        case '&':\n            // named character entity\n            for (const idstart = ++p; 1; p++)\n            {\n                switch (*p)\n                {\n                case ';':\n                    c = HtmlNamedEntity(idstart, p - idstart);\n                    if (c == ~0)\n                    {\n                        handler.error(\"unnamed character entity &%.*s;\", cast(int)(p - idstart), idstart);\n                        c = '?';\n                    }\n                    p++;\n                    break;\n                default:\n                    if (isalpha(*p) || (p != idstart && isdigit(*p)))\n                        continue;\n                    handler.error(\"unterminated named entity &%.*s;\", cast(int)(p - idstart + 1), idstart);\n                    c = '?';\n                    break;\n                }\n                break;\n            }\n            break;\n        case 0:\n        case 0x1A:\n            // end of file\n            c = '\\\\';\n            break;\n        default:\n            if (isoctal(cast(char)c))\n            {\n                uint v = 0;\n                int n = 0;\n                do\n                {\n                    v = v * 8 + (c - '0');\n                    c = *++p;\n                }\n                while (++n < 3 && isoctal(cast(char)c));\n                c = v;\n                if (c > 0xFF)\n                    handler.error(\"escape octal sequence \\\\%03o is larger than \\\\377\", c);\n            }\n            else\n            {\n                handler.error(\"undefined escape sequence \\\\%c\", c);\n                p++;\n            }\n            break;\n        }\n        return c;\n    }\n\n    /**\n    Lex a wysiwyg string. `p` must be pointing to the first character before the\n    contents of the string literal. The character pointed to by `p` will be used as\n    the terminating character (i.e. backtick or double-quote).\n    Params:\n        result = pointer to the token that accepts the result\n    */\n    final void wysiwygStringConstant(Token* result)\n    {\n        result.value = TOK.string_;\n        Loc start = loc();\n        auto terminator = p[0];\n        p++;\n        stringbuffer.reset();\n        while (1)\n        {\n            dchar c = p[0];\n            p++;\n            switch (c)\n            {\n            case '\\n':\n                endOfLine();\n                break;\n            case '\\r':\n                if (p[0] == '\\n')\n                    continue; // ignore\n                c = '\\n'; // treat EndOfLine as \\n character\n                endOfLine();\n                break;\n            case 0:\n            case 0x1A:\n                error(\"unterminated string constant starting at %s\", start.toChars());\n                result.setString();\n                // rewind `p` so it points to the EOF character\n                p--;\n                return;\n            default:\n                if (c == terminator)\n                {\n                    result.setString(stringbuffer);\n                    stringPostfix(result);\n                    return;\n                }\n                else if (c & 0x80)\n                {\n                    p--;\n                    const u = decodeUTF();\n                    p++;\n                    if (u == PS || u == LS)\n                        endOfLine();\n                    stringbuffer.writeUTF8(u);\n                    continue;\n                }\n                break;\n            }\n            stringbuffer.writeByte(c);\n        }\n    }\n\n    /**************************************\n     * Lex hex strings:\n     *      x\"0A ae 34FE BD\"\n     */\n    final TOK hexStringConstant(Token* t)\n    {\n        Loc start = loc();\n        uint n = 0;\n        uint v = ~0; // dead assignment, needed to suppress warning\n        p++;\n        stringbuffer.reset();\n        while (1)\n        {\n            dchar c = *p++;\n            switch (c)\n            {\n            case ' ':\n            case '\\t':\n            case '\\v':\n            case '\\f':\n                continue; // skip white space\n            case '\\r':\n                if (*p == '\\n')\n                    continue; // ignore '\\r' if followed by '\\n'\n                // Treat isolated '\\r' as if it were a '\\n'\n                goto case '\\n';\n            case '\\n':\n                endOfLine();\n                continue;\n            case 0:\n            case 0x1A:\n                error(\"unterminated string constant starting at %s\", start.toChars());\n                t.setString();\n                // decrement `p`, because it needs to point to the next token (the 0 or 0x1A character is the TOK.endOfFile token).\n                p--;\n                return TOK.hexadecimalString;\n            case '\"':\n                if (n & 1)\n                {\n                    error(\"odd number (%d) of hex characters in hex string\", n);\n                    stringbuffer.writeByte(v);\n                }\n                t.setString(stringbuffer);\n                stringPostfix(t);\n                return TOK.hexadecimalString;\n            default:\n                if (c >= '0' && c <= '9')\n                    c -= '0';\n                else if (c >= 'a' && c <= 'f')\n                    c -= 'a' - 10;\n                else if (c >= 'A' && c <= 'F')\n                    c -= 'A' - 10;\n                else if (c & 0x80)\n                {\n                    p--;\n                    const u = decodeUTF();\n                    p++;\n                    if (u == PS || u == LS)\n                        endOfLine();\n                    else\n                        error(\"non-hex character \\\\u%04x in hex string\", u);\n                }\n                else\n                    error(\"non-hex character '%c' in hex string\", c);\n                if (n & 1)\n                {\n                    v = (v << 4) | c;\n                    stringbuffer.writeByte(v);\n                }\n                else\n                    v = c;\n                n++;\n                break;\n            }\n        }\n        assert(0); // see bug 15731\n    }\n\n    /**\n    Lex a delimited string. Some examples of delimited strings are:\n    ---\n    q\"(foo(xxx))\"      // \"foo(xxx)\"\n    q\"[foo$(LPAREN)]\"  // \"foo$(LPAREN)\"\n    q\"/foo]/\"          // \"foo]\"\n    q\"HERE\n    foo\n    HERE\"              // \"foo\\n\"\n    ---\n    It is assumed that `p` points to the opening double-quote '\"'.\n    Params:\n        result = pointer to the token that accepts the result\n    */\n    final void delimitedStringConstant(Token* result)\n    {\n        result.value = TOK.string_;\n        Loc start = loc();\n        dchar delimleft = 0;\n        dchar delimright = 0;\n        uint nest = 1;\n        uint nestcount = ~0; // dead assignment, needed to suppress warning\n        Identifier hereid = null;\n        uint blankrol = 0;\n        uint startline = 0;\n        p++;\n        stringbuffer.reset();\n        while (1)\n        {\n            dchar c = *p++;\n            //printf(\"c = '%c'\\n\", c);\n            switch (c)\n            {\n            case '\\n':\n            Lnextline:\n                endOfLine();\n                startline = 1;\n                if (blankrol)\n                {\n                    blankrol = 0;\n                    continue;\n                }\n                if (hereid)\n                {\n                    stringbuffer.writeUTF8(c);\n                    continue;\n                }\n                break;\n            case '\\r':\n                if (*p == '\\n')\n                    continue; // ignore\n                c = '\\n'; // treat EndOfLine as \\n character\n                goto Lnextline;\n            case 0:\n            case 0x1A:\n                error(\"unterminated delimited string constant starting at %s\", start.toChars());\n                result.setString();\n                // decrement `p`, because it needs to point to the next token (the 0 or 0x1A character is the TOK.endOfFile token).\n                p--;\n                return;\n            default:\n                if (c & 0x80)\n                {\n                    p--;\n                    c = decodeUTF();\n                    p++;\n                    if (c == PS || c == LS)\n                        goto Lnextline;\n                }\n                break;\n            }\n            if (delimleft == 0)\n            {\n                delimleft = c;\n                nest = 1;\n                nestcount = 1;\n                if (c == '(')\n                    delimright = ')';\n                else if (c == '{')\n                    delimright = '}';\n                else if (c == '[')\n                    delimright = ']';\n                else if (c == '<')\n                    delimright = '>';\n                else if (isalpha(c) || c == '_' || (c >= 0x80 && isUniAlpha(c)))\n                {\n                    // Start of identifier; must be a heredoc\n                    Token tok;\n                    p--;\n                    scan(&tok); // read in heredoc identifier\n                    if (tok.value != TOK.identifier)\n                    {\n                        error(\"identifier expected for heredoc, not %s\", tok.toChars());\n                        delimright = c;\n                    }\n                    else\n                    {\n                        hereid = tok.ident;\n                        //printf(\"hereid = '%s'\\n\", hereid.toChars());\n                        blankrol = 1;\n                    }\n                    nest = 0;\n                }\n                else\n                {\n                    delimright = c;\n                    nest = 0;\n                    if (isspace(c))\n                        error(\"delimiter cannot be whitespace\");\n                }\n            }\n            else\n            {\n                if (blankrol)\n                {\n                    error(\"heredoc rest of line should be blank\");\n                    blankrol = 0;\n                    continue;\n                }\n                if (nest == 1)\n                {\n                    if (c == delimleft)\n                        nestcount++;\n                    else if (c == delimright)\n                    {\n                        nestcount--;\n                        if (nestcount == 0)\n                            goto Ldone;\n                    }\n                }\n                else if (c == delimright)\n                    goto Ldone;\n                if (startline && (isalpha(c) || c == '_' || (c >= 0x80 && isUniAlpha(c))) && hereid)\n                {\n                    Token tok;\n                    auto psave = p;\n                    p--;\n                    scan(&tok); // read in possible heredoc identifier\n                    //printf(\"endid = '%s'\\n\", tok.ident.toChars());\n                    if (tok.value == TOK.identifier && tok.ident.equals(hereid))\n                    {\n                        /* should check that rest of line is blank\n                         */\n                        goto Ldone;\n                    }\n                    p = psave;\n                }\n                stringbuffer.writeUTF8(c);\n                startline = 0;\n            }\n        }\n    Ldone:\n        if (*p == '\"')\n            p++;\n        else if (hereid)\n            error(\"delimited string must end in %s\\\"\", hereid.toChars());\n        else\n            error(\"delimited string must end in %c\\\"\", delimright);\n        result.setString(stringbuffer);\n        stringPostfix(result);\n    }\n\n    /**\n    Lex a token string. Some examples of token strings are:\n    ---\n    q{ foo(xxx) }    // \" foo(xxx) \"\n    q{foo$(LPAREN)}  // \"foo$(LPAREN)\"\n    q{{foo}\"}\"}      // \"{foo}\"}\"\"\n    ---\n    It is assumed that `p` points to the opening curly-brace '{'.\n    Params:\n        result = pointer to the token that accepts the result\n    */\n    final void tokenStringConstant(Token* result)\n    {\n        result.value = TOK.string_;\n\n        uint nest = 1;\n        const start = loc();\n        const pstart = ++p;\n        while (1)\n        {\n            Token tok;\n            scan(&tok);\n            switch (tok.value)\n            {\n            case TOK.leftCurly:\n                nest++;\n                continue;\n            case TOK.rightCurly:\n                if (--nest == 0)\n                {\n                    result.setString(pstart, p - 1 - pstart);\n                    stringPostfix(result);\n                    return;\n                }\n                continue;\n            case TOK.endOfFile:\n                error(\"unterminated token string constant starting at %s\", start.toChars());\n                result.setString();\n                return;\n            default:\n                continue;\n            }\n        }\n    }\n\n    /**\n    Scan a double-quoted string while building the processed string value by\n    handling escape sequences. The result is returned in the given `t` token.\n    This function assumes that `p` currently points to the opening double-quote\n    of the string.\n    Params:\n        t = the token to set the resulting string to\n    */\n    final void escapeStringConstant(Token* t)\n    {\n        t.value = TOK.string_;\n\n        const start = loc();\n        p++;\n        stringbuffer.reset();\n        while (1)\n        {\n            dchar c = *p++;\n            switch (c)\n            {\n            case '\\\\':\n                switch (*p)\n                {\n                case 'u':\n                case 'U':\n                case '&':\n                    c = escapeSequence();\n                    stringbuffer.writeUTF8(c);\n                    continue;\n                default:\n                    c = escapeSequence();\n                    break;\n                }\n                break;\n            case '\\n':\n                endOfLine();\n                break;\n            case '\\r':\n                if (*p == '\\n')\n                    continue; // ignore\n                c = '\\n'; // treat EndOfLine as \\n character\n                endOfLine();\n                break;\n            case '\"':\n                t.setString(stringbuffer);\n                stringPostfix(t);\n                return;\n            case 0:\n            case 0x1A:\n                // decrement `p`, because it needs to point to the next token (the 0 or 0x1A character is the TOK.endOfFile token).\n                p--;\n                error(\"unterminated string constant starting at %s\", start.toChars());\n                t.setString();\n                return;\n            default:\n                if (c & 0x80)\n                {\n                    p--;\n                    c = decodeUTF();\n                    if (c == LS || c == PS)\n                    {\n                        c = '\\n';\n                        endOfLine();\n                    }\n                    p++;\n                    stringbuffer.writeUTF8(c);\n                    continue;\n                }\n                break;\n            }\n            stringbuffer.writeByte(c);\n        }\n    }\n\n    /**************************************\n     */\n    final TOK charConstant(Token* t)\n    {\n        TOK tk = TOK.charLiteral;\n        //printf(\"Lexer::charConstant\\n\");\n        p++;\n        dchar c = *p++;\n        switch (c)\n        {\n        case '\\\\':\n            switch (*p)\n            {\n            case 'u':\n                t.unsvalue = escapeSequence();\n                tk = TOK.wcharLiteral;\n                break;\n            case 'U':\n            case '&':\n                t.unsvalue = escapeSequence();\n                tk = TOK.dcharLiteral;\n                break;\n            default:\n                t.unsvalue = escapeSequence();\n                break;\n            }\n            break;\n        case '\\n':\n        L1:\n            endOfLine();\n            goto case;\n        case '\\r':\n            goto case '\\'';\n        case 0:\n        case 0x1A:\n            // decrement `p`, because it needs to point to the next token (the 0 or 0x1A character is the TOK.endOfFile token).\n            p--;\n            goto case;\n        case '\\'':\n            error(\"unterminated character constant\");\n            t.unsvalue = '?';\n            return tk;\n        default:\n            if (c & 0x80)\n            {\n                p--;\n                c = decodeUTF();\n                p++;\n                if (c == LS || c == PS)\n                    goto L1;\n                if (c < 0xD800 || (c >= 0xE000 && c < 0xFFFE))\n                    tk = TOK.wcharLiteral;\n                else\n                    tk = TOK.dcharLiteral;\n            }\n            t.unsvalue = c;\n            break;\n        }\n        if (*p != '\\'')\n        {\n            error(\"unterminated character constant\");\n            t.unsvalue = '?';\n            return tk;\n        }\n        p++;\n        return tk;\n    }\n\n    /***************************************\n     * Get postfix of string literal.\n     */\n    final void stringPostfix(Token* t)\n    {\n        switch (*p)\n        {\n        case 'c':\n        case 'w':\n        case 'd':\n            t.postfix = *p;\n            p++;\n            break;\n        default:\n            t.postfix = 0;\n            break;\n        }\n    }\n\n    /**************************************\n     * Read in a number.\n     * If it's an integer, store it in tok.TKutok.Vlong.\n     *      integers can be decimal, octal or hex\n     *      Handle the suffixes U, UL, LU, L, etc.\n     * If it's double, store it in tok.TKutok.Vdouble.\n     * Returns:\n     *      TKnum\n     *      TKdouble,...\n     */\n    final TOK number(Token* t)\n    {\n        int base = 10;\n        const start = p;\n        uinteger_t n = 0; // unsigned >=64 bit integer type\n        int d;\n        bool err = false;\n        bool overflow = false;\n        bool anyBinaryDigitsUS = false;\n        bool anyHexDigitsNoSingleUS = false;\n        dchar c = *p;\n        if (c == '0')\n        {\n            ++p;\n            c = *p;\n            switch (c)\n            {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n                base = 8;\n                break;\n            case 'x':\n            case 'X':\n                ++p;\n                base = 16;\n                break;\n            case 'b':\n            case 'B':\n                ++p;\n                base = 2;\n                break;\n            case '.':\n                if (p[1] == '.')\n                    goto Ldone; // if \"..\"\n                if (isalpha(p[1]) || p[1] == '_' || p[1] & 0x80)\n                    goto Ldone; // if \".identifier\" or \".unicode\"\n                goto Lreal; // '.' is part of current token\n            case 'i':\n            case 'f':\n            case 'F':\n                goto Lreal;\n            case '_':\n                ++p;\n                base = 8;\n                break;\n            case 'L':\n                if (p[1] == 'i')\n                    goto Lreal;\n                break;\n            default:\n                break;\n            }\n        }\n        while (1)\n        {\n            c = *p;\n            switch (c)\n            {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n                ++p;\n                d = c - '0';\n                break;\n            case 'a':\n            case 'b':\n            case 'c':\n            case 'd':\n            case 'e':\n            case 'f':\n            case 'A':\n            case 'B':\n            case 'C':\n            case 'D':\n            case 'E':\n            case 'F':\n                ++p;\n                if (base != 16)\n                {\n                    if (c == 'e' || c == 'E' || c == 'f' || c == 'F')\n                        goto Lreal;\n                }\n                if (c >= 'a')\n                    d = c + 10 - 'a';\n                else\n                    d = c + 10 - 'A';\n                break;\n            case 'L':\n                if (p[1] == 'i')\n                    goto Lreal;\n                goto Ldone;\n            case '.':\n                if (p[1] == '.')\n                    goto Ldone; // if \"..\"\n                if (base == 10 && (isalpha(p[1]) || p[1] == '_' || p[1] & 0x80))\n                    goto Ldone; // if \".identifier\" or \".unicode\"\n                goto Lreal; // otherwise as part of a floating point literal\n            case 'p':\n            case 'P':\n            case 'i':\n            Lreal:\n                p = start;\n                return inreal(t);\n            case '_':\n                anyBinaryDigitsUS = true;\n                ++p;\n                continue;\n            default:\n                goto Ldone;\n            }\n            // got a digit here, set any necessary flags, check for errors\n            anyHexDigitsNoSingleUS = true;\n            anyBinaryDigitsUS = true;\n            if (!err && d >= base)\n            {\n                error(\"%s digit expected, not `%c`\", base == 2 ? \"binary\".ptr :\n                                                     base == 8 ? \"octal\".ptr :\n                                                     \"decimal\".ptr, c);\n                err = true;\n            }\n            // Avoid expensive overflow check if we aren't at risk of overflow\n            if (n <= 0x0FFF_FFFF_FFFF_FFFFUL)\n                n = n * base + d;\n            else\n            {\n                import core.checkedint : mulu, addu;\n\n                n = mulu(n, base, overflow);\n                n = addu(n, d, overflow);\n            }\n        }\n    Ldone:\n        if (overflow && !err)\n        {\n            error(\"integer overflow\");\n            err = true;\n        }\n        // Deprecated in 2018-06.\n        // Change to error in 2019-06.\n        // @@@DEPRECATED_2019-06@@@\n        if ((base == 2 && !anyBinaryDigitsUS) ||\n            (base == 16 && !anyHexDigitsNoSingleUS))\n            deprecation(\"`%.*s` isn't a valid integer literal, use `%.*s0` instead\", cast(int)(p - start), start, 2, start);\n        enum FLAGS : int\n        {\n            none = 0,\n            decimal = 1, // decimal\n            unsigned = 2, // u or U suffix\n            long_ = 4, // L suffix\n        }\n\n        FLAGS flags = (base == 10) ? FLAGS.decimal : FLAGS.none;\n        // Parse trailing 'u', 'U', 'l' or 'L' in any combination\n        const psuffix = p;\n        while (1)\n        {\n            FLAGS f;\n            switch (*p)\n            {\n            case 'U':\n            case 'u':\n                f = FLAGS.unsigned;\n                goto L1;\n            case 'l':\n                f = FLAGS.long_;\n                error(\"lower case integer suffix 'l' is not allowed. Please use 'L' instead\");\n                goto L1;\n            case 'L':\n                f = FLAGS.long_;\n            L1:\n                p++;\n                if ((flags & f) && !err)\n                {\n                    error(\"unrecognized token\");\n                    err = true;\n                }\n                flags = cast(FLAGS)(flags | f);\n                continue;\n            default:\n                break;\n            }\n            break;\n        }\n        if (base == 8 && n >= 8)\n        {\n            if (err)\n                // can't translate invalid octal value, just show a generic message\n                error(\"octal literals larger than 7 are no longer supported\");\n            else\n                error(\"octal literals `0%llo%.*s` are no longer supported, use `std.conv.octal!%llo%.*s` instead\", n, p - psuffix, psuffix, n, p - psuffix, psuffix);\n        }\n        TOK result;\n        switch (flags)\n        {\n        case FLAGS.none:\n            /* Octal or Hexadecimal constant.\n             * First that fits: int, uint, long, ulong\n             */\n            if (n & 0x8000000000000000L)\n                result = TOK.uns64Literal;\n            else if (n & 0xFFFFFFFF00000000L)\n                result = TOK.int64Literal;\n            else if (n & 0x80000000)\n                result = TOK.uns32Literal;\n            else\n                result = TOK.int32Literal;\n            break;\n        case FLAGS.decimal:\n            /* First that fits: int, long, long long\n             */\n            if (n & 0x8000000000000000L)\n            {\n                if (!err)\n                {\n                    error(\"signed integer overflow\");\n                    err = true;\n                }\n                result = TOK.uns64Literal;\n            }\n            else if (n & 0xFFFFFFFF80000000L)\n                result = TOK.int64Literal;\n            else\n                result = TOK.int32Literal;\n            break;\n        case FLAGS.unsigned:\n        case FLAGS.decimal | FLAGS.unsigned:\n            /* First that fits: uint, ulong\n             */\n            if (n & 0xFFFFFFFF00000000L)\n                result = TOK.uns64Literal;\n            else\n                result = TOK.uns32Literal;\n            break;\n        case FLAGS.decimal | FLAGS.long_:\n            if (n & 0x8000000000000000L)\n            {\n                if (!err)\n                {\n                    error(\"signed integer overflow\");\n                    err = true;\n                }\n                result = TOK.uns64Literal;\n            }\n            else\n                result = TOK.int64Literal;\n            break;\n        case FLAGS.long_:\n            if (n & 0x8000000000000000L)\n                result = TOK.uns64Literal;\n            else\n                result = TOK.int64Literal;\n            break;\n        case FLAGS.unsigned | FLAGS.long_:\n        case FLAGS.decimal | FLAGS.unsigned | FLAGS.long_:\n            result = TOK.uns64Literal;\n            break;\n        default:\n            debug\n            {\n                printf(\"%x\\n\", flags);\n            }\n            assert(0);\n        }\n        t.unsvalue = n;\n        return result;\n    }\n\n    /**************************************\n     * Read in characters, converting them to real.\n     * Bugs:\n     *      Exponent overflow not detected.\n     *      Too much requested precision is not detected.\n     */\n    final TOK inreal(Token* t)\n    {\n        //printf(\"Lexer::inreal()\\n\");\n        debug\n        {\n            assert(*p == '.' || isdigit(*p));\n        }\n        bool isWellformedString = true;\n        stringbuffer.reset();\n        auto pstart = p;\n        bool hex = false;\n        dchar c = *p++;\n        // Leading '0x'\n        if (c == '0')\n        {\n            c = *p++;\n            if (c == 'x' || c == 'X')\n            {\n                hex = true;\n                c = *p++;\n            }\n        }\n        // Digits to left of '.'\n        while (1)\n        {\n            if (c == '.')\n            {\n                c = *p++;\n                break;\n            }\n            if (isdigit(c) || (hex && isxdigit(c)) || c == '_')\n            {\n                c = *p++;\n                continue;\n            }\n            break;\n        }\n        // Digits to right of '.'\n        while (1)\n        {\n            if (isdigit(c) || (hex && isxdigit(c)) || c == '_')\n            {\n                c = *p++;\n                continue;\n            }\n            break;\n        }\n        if (c == 'e' || c == 'E' || (hex && (c == 'p' || c == 'P')))\n        {\n            c = *p++;\n            if (c == '-' || c == '+')\n            {\n                c = *p++;\n            }\n            bool anyexp = false;\n            while (1)\n            {\n                if (isdigit(c))\n                {\n                    anyexp = true;\n                    c = *p++;\n                    continue;\n                }\n                if (c == '_')\n                {\n                    c = *p++;\n                    continue;\n                }\n                if (!anyexp)\n                {\n                    error(\"missing exponent\");\n                    isWellformedString = false;\n                }\n                break;\n            }\n        }\n        else if (hex)\n        {\n            error(\"exponent required for hex float\");\n            isWellformedString = false;\n        }\n        --p;\n        while (pstart < p)\n        {\n            if (*pstart != '_')\n                stringbuffer.writeByte(*pstart);\n            ++pstart;\n        }\n        stringbuffer.writeByte(0);\n        auto sbufptr = cast(const(char)*)stringbuffer.data;\n        TOK result;\n        bool isOutOfRange = false;\n        t.floatvalue = (isWellformedString ? CTFloat.parse(sbufptr, &isOutOfRange) : CTFloat.zero);\n        switch (*p)\n        {\n        case 'F':\n        case 'f':\n            if (isWellformedString && !isOutOfRange)\n                isOutOfRange = Port.isFloat32LiteralOutOfRange(sbufptr);\n            result = TOK.float32Literal;\n            p++;\n            break;\n        default:\n            if (isWellformedString && !isOutOfRange)\n                isOutOfRange = Port.isFloat64LiteralOutOfRange(sbufptr);\n            result = TOK.float64Literal;\n            break;\n        case 'l':\n            error(\"use 'L' suffix instead of 'l'\");\n            goto case 'L';\n        case 'L':\n            result = TOK.float80Literal;\n            p++;\n            break;\n        }\n        if (*p == 'i' || *p == 'I')\n        {\n            if (*p == 'I')\n                error(\"use 'i' suffix instead of 'I'\");\n            p++;\n            switch (result)\n            {\n            case TOK.float32Literal:\n                result = TOK.imaginary32Literal;\n                break;\n            case TOK.float64Literal:\n                result = TOK.imaginary64Literal;\n                break;\n            case TOK.float80Literal:\n                result = TOK.imaginary80Literal;\n                break;\n            default:\n                break;\n            }\n        }\n        const isLong = (result == TOK.float80Literal || result == TOK.imaginary80Literal);\n        if (isOutOfRange && !isLong)\n        {\n            const char* suffix = (result == TOK.float32Literal || result == TOK.imaginary32Literal) ? \"f\" : \"\";\n            error(scanloc, \"number `%s%s` is not representable\", sbufptr, suffix);\n        }\n        debug\n        {\n            switch (result)\n            {\n            case TOK.float32Literal:\n            case TOK.float64Literal:\n            case TOK.float80Literal:\n            case TOK.imaginary32Literal:\n            case TOK.imaginary64Literal:\n            case TOK.imaginary80Literal:\n                break;\n            default:\n                assert(0);\n            }\n        }\n        return result;\n    }\n\n    final Loc loc()\n    {\n        scanloc.charnum = cast(uint)(1 + p - line);\n        return scanloc;\n    }\n\n    final override void error(const(char)* format, ...)\n    {\n        va_list ap;\n        va_start(ap, format);\n        .verror(token.loc, format, ap);\n        va_end(ap);\n        errors = true;\n    }\n\n    final override void error(Loc loc, const(char)* format, ...)\n    {\n        va_list ap;\n        va_start(ap, format);\n        .verror(loc, format, ap);\n        va_end(ap);\n        errors = true;\n    }\n\n    final void deprecation(const(char)* format, ...)\n    {\n        va_list ap;\n        va_start(ap, format);\n        .vdeprecation(token.loc, format, ap);\n        va_end(ap);\n        if (global.params.useDeprecated == Diagnostic.error)\n            errors = true;\n    }\n\n    /*********************************************\n     * parse:\n     *      #line linnum [filespec]\n     * also allow __LINE__ for linnum, and __FILE__ for filespec\n     */\n    final void poundLine()\n    {\n        auto linnum = this.scanloc.linnum;\n        const(char)* filespec = null;\n        const loc = this.loc();\n        Token tok;\n        scan(&tok);\n        if (tok.value == TOK.int32Literal || tok.value == TOK.int64Literal)\n        {\n            const lin = cast(int)(tok.unsvalue - 1);\n            if (lin != tok.unsvalue - 1)\n                error(\"line number `%lld` out of range\", cast(ulong)tok.unsvalue);\n            else\n                linnum = lin;\n        }\n        else if (tok.value == TOK.line)\n        {\n        }\n        else\n            goto Lerr;\n        while (1)\n        {\n            switch (*p)\n            {\n            case 0:\n            case 0x1A:\n            case '\\n':\n            Lnewline:\n                this.scanloc.linnum = linnum;\n                if (filespec)\n                    this.scanloc.filename = filespec;\n                return;\n            case '\\r':\n                p++;\n                if (*p != '\\n')\n                {\n                    p--;\n                    goto Lnewline;\n                }\n                continue;\n            case ' ':\n            case '\\t':\n            case '\\v':\n            case '\\f':\n                p++;\n                continue; // skip white space\n            case '_':\n                if (memcmp(p, \"__FILE__\".ptr, 8) == 0)\n                {\n                    p += 8;\n                    filespec = mem.xstrdup(scanloc.filename);\n                    continue;\n                }\n                goto Lerr;\n            case '\"':\n                if (filespec)\n                    goto Lerr;\n                stringbuffer.reset();\n                p++;\n                while (1)\n                {\n                    uint c;\n                    c = *p;\n                    switch (c)\n                    {\n                    case '\\n':\n                    case '\\r':\n                    case 0:\n                    case 0x1A:\n                        goto Lerr;\n                    case '\"':\n                        stringbuffer.writeByte(0);\n                        filespec = mem.xstrdup(cast(const(char)*)stringbuffer.data);\n                        p++;\n                        break;\n                    default:\n                        if (c & 0x80)\n                        {\n                            uint u = decodeUTF();\n                            if (u == PS || u == LS)\n                                goto Lerr;\n                        }\n                        stringbuffer.writeByte(c);\n                        p++;\n                        continue;\n                    }\n                    break;\n                }\n                continue;\n            default:\n                if (*p & 0x80)\n                {\n                    uint u = decodeUTF();\n                    if (u == PS || u == LS)\n                        goto Lnewline;\n                }\n                goto Lerr;\n            }\n        }\n    Lerr:\n        error(loc, \"#line integer [\\\"filespec\\\"]\\\\n expected\");\n    }\n\n    /********************************************\n     * Decode UTF character.\n     * Issue error messages for invalid sequences.\n     * Return decoded character, advance p to last character in UTF sequence.\n     */\n    final uint decodeUTF()\n    {\n        const s = p;\n        assert(*s & 0x80);\n        // Check length of remaining string up to 6 UTF-8 characters\n        size_t len;\n        for (len = 1; len < 6 && s[len]; len++)\n        {\n        }\n        size_t idx = 0;\n        dchar u;\n        const msg = utf_decodeChar(s, len, idx, u);\n        p += idx - 1;\n        if (msg)\n        {\n            error(\"%s\", msg);\n        }\n        return u;\n    }\n\n    /***************************************************\n     * Parse doc comment embedded between t.ptr and p.\n     * Remove trailing blanks and tabs from lines.\n     * Replace all newlines with \\n.\n     * Remove leading comment character from each line.\n     * Decide if it's a lineComment or a blockComment.\n     * Append to previous one for this token.\n     *\n     * If newParagraph is true, an extra newline will be\n     * added between adjoining doc comments.\n     */\n    final void getDocComment(Token* t, uint lineComment, bool newParagraph)\n    {\n        /* ct tells us which kind of comment it is: '/', '*', or '+'\n         */\n        const ct = t.ptr[2];\n        /* Start of comment text skips over / * *, / + +, or / / /\n         */\n        const(char)* q = t.ptr + 3; // start of comment text\n        const(char)* qend = p;\n        if (ct == '*' || ct == '+')\n            qend -= 2;\n        /* Scan over initial row of ****'s or ++++'s or ////'s\n         */\n        for (; q < qend; q++)\n        {\n            if (*q != ct)\n                break;\n        }\n        /* Remove leading spaces until start of the comment\n         */\n        int linestart = 0;\n        if (ct == '/')\n        {\n            while (q < qend && (*q == ' ' || *q == '\\t'))\n                ++q;\n        }\n        else if (q < qend)\n        {\n            if (*q == '\\r')\n            {\n                ++q;\n                if (q < qend && *q == '\\n')\n                    ++q;\n                linestart = 1;\n            }\n            else if (*q == '\\n')\n            {\n                ++q;\n                linestart = 1;\n            }\n        }\n        /* Remove trailing row of ****'s or ++++'s\n         */\n        if (ct != '/')\n        {\n            for (; q < qend; qend--)\n            {\n                if (qend[-1] != ct)\n                    break;\n            }\n        }\n        /* Comment is now [q .. qend].\n         * Canonicalize it into buf[].\n         */\n        OutBuffer buf;\n\n        void trimTrailingWhitespace()\n        {\n            const s = buf.peekSlice();\n            auto len = s.length;\n            while (len && (s[len - 1] == ' ' || s[len - 1] == '\\t'))\n                --len;\n            buf.setsize(len);\n        }\n\n        for (; q < qend; q++)\n        {\n            char c = *q;\n            switch (c)\n            {\n            case '*':\n            case '+':\n                if (linestart && c == ct)\n                {\n                    linestart = 0;\n                    /* Trim preceding whitespace up to preceding \\n\n                     */\n                    trimTrailingWhitespace();\n                    continue;\n                }\n                break;\n            case ' ':\n            case '\\t':\n                break;\n            case '\\r':\n                if (q[1] == '\\n')\n                    continue; // skip the \\r\n                goto Lnewline;\n            default:\n                if (c == 226)\n                {\n                    // If LS or PS\n                    if (q[1] == 128 && (q[2] == 168 || q[2] == 169))\n                    {\n                        q += 2;\n                        goto Lnewline;\n                    }\n                }\n                linestart = 0;\n                break;\n            Lnewline:\n                c = '\\n'; // replace all newlines with \\n\n                goto case;\n            case '\\n':\n                linestart = 1;\n                /* Trim trailing whitespace\n                 */\n                trimTrailingWhitespace();\n                break;\n            }\n            buf.writeByte(c);\n        }\n        /* Trim trailing whitespace (if the last line does not have newline)\n         */\n        trimTrailingWhitespace();\n\n        // Always end with a newline\n        const s = buf.peekSlice();\n        if (s.length == 0 || s[$ - 1] != '\\n')\n            buf.writeByte('\\n');\n\n        // It's a line comment if the start of the doc comment comes\n        // after other non-whitespace on the same line.\n        auto dc = (lineComment && anyToken) ? &t.lineComment : &t.blockComment;\n        // Combine with previous doc comment, if any\n        if (*dc)\n            *dc = combineComments(*dc, buf.peekString(), newParagraph);\n        else\n            *dc = buf.extractString();\n    }\n\n    /********************************************\n     * Combine two document comments into one,\n     * separated by an extra newline if newParagraph is true.\n     */\n    static const(char)* combineComments(const(char)* c1, const(char)* c2, bool newParagraph)\n    {\n        //printf(\"Lexer::combineComments('%s', '%s', '%i')\\n\", c1, c2, newParagraph);\n        auto c = c2;\n        const(int) newParagraphSize = newParagraph ? 1 : 0; // Size of the combining '\\n'\n        if (c1)\n        {\n            c = c1;\n            if (c2)\n            {\n                size_t len1 = strlen(c1);\n                size_t len2 = strlen(c2);\n                int insertNewLine = 0;\n                if (len1 && c1[len1 - 1] != '\\n')\n                {\n                    ++len1;\n                    insertNewLine = 1;\n                }\n                auto p = cast(char*)mem.xmalloc(len1 + newParagraphSize + len2 + 1);\n                memcpy(p, c1, len1 - insertNewLine);\n                if (insertNewLine)\n                    p[len1 - 1] = '\\n';\n                if (newParagraph)\n                    p[len1] = '\\n';\n                memcpy(p + len1 + newParagraphSize, c2, len2);\n                p[len1 + newParagraphSize + len2] = 0;\n                c = p;\n            }\n        }\n        return c;\n    }\n\nprivate:\n    void endOfLine()\n    {\n        scanloc.linnum++;\n        line = p;\n    }\n}\n\nunittest\n{\n    static class AssertErrorHandler : ErrorHandler\n    {\n        override final void error(const(char)* format, ...) { assert(0); }\n        override final void error(Loc loc, const(char)* format, ...) { assert(0); }\n    }\n    static void test(T)(string sequence, T expected)\n    {\n        scope assertOnError = new AssertErrorHandler();\n        auto p = cast(const(char)*)sequence.ptr;\n        assert(expected == Lexer.escapeSequence(assertOnError, p));\n        assert(p == sequence.ptr + sequence.length);\n    }\n\n    test(`'`, '\\'');\n    test(`\"`, '\"');\n    test(`?`, '?');\n    test(`\\`, '\\\\');\n    test(`0`, '\\0');\n    test(`a`, '\\a');\n    test(`b`, '\\b');\n    test(`f`, '\\f');\n    test(`n`, '\\n');\n    test(`r`, '\\r');\n    test(`t`, '\\t');\n    test(`v`, '\\v');\n\n    test(`x00`, 0x00);\n    test(`xff`, 0xff);\n    test(`xFF`, 0xff);\n    test(`xa7`, 0xa7);\n    test(`x3c`, 0x3c);\n    test(`xe2`, 0xe2);\n\n    test(`1`, '\\1');\n    test(`42`, '\\42');\n    test(`357`, '\\357');\n\n    test(`u1234`, '\\u1234');\n    test(`uf0e4`, '\\uf0e4');\n\n    test(`U0001f603`, '\\U0001f603');\n\n    test(`&quot;`, '\"');\n    test(`&lt;`, '<');\n    test(`&gt;`, '>');\n}\nunittest\n{\n    static class ExpectErrorHandler : ErrorHandler\n    {\n        string expected;\n        bool gotError;\n        this(string expected) { this.expected = expected; }\n        override final void error(const(char)* format, ...)\n        {\n            gotError = true;\n            char[100] buffer;\n            va_list ap;\n            va_start(ap, format);\n            auto actual = buffer[0 .. vsprintf(buffer.ptr, format, ap)];\n            va_end(ap);\n            assert(expected == actual);\n        }\n        override final void error(Loc loc, const(char)* format, ...) { assert(0); }\n    }\n    static void test(string sequence, string expectedError, dchar expectedReturnValue, uint expectedScanLength)\n    {\n        scope handler = new ExpectErrorHandler(expectedError);\n        auto p = cast(const(char)*)sequence.ptr;\n        auto actualReturnValue = Lexer.escapeSequence(handler, p);\n        assert(handler.gotError);\n        assert(expectedReturnValue == actualReturnValue);\n\n        auto actualScanLength = p - sequence.ptr;\n        assert(expectedScanLength == actualScanLength);\n    }\n\n    test(\"c\", `undefined escape sequence \\c`, 'c', 1);\n    test(\"!\", `undefined escape sequence \\!`, '!', 1);\n\n    test(\"x1\", `escape hex sequence has 1 hex digits instead of 2`, '\\x01', 2);\n\n    test(\"u1\"  , `escape hex sequence has 1 hex digits instead of 4`,   0x1, 2);\n    test(\"u12\" , `escape hex sequence has 2 hex digits instead of 4`,  0x12, 3);\n    test(\"u123\", `escape hex sequence has 3 hex digits instead of 4`, 0x123, 4);\n\n    test(\"U0\"      , `escape hex sequence has 1 hex digits instead of 8`,       0x0, 2);\n    test(\"U00\"     , `escape hex sequence has 2 hex digits instead of 8`,      0x00, 3);\n    test(\"U000\"    , `escape hex sequence has 3 hex digits instead of 8`,     0x000, 4);\n    test(\"U0000\"   , `escape hex sequence has 4 hex digits instead of 8`,    0x0000, 5);\n    test(\"U0001f\"  , `escape hex sequence has 5 hex digits instead of 8`,   0x0001f, 6);\n    test(\"U0001f6\" , `escape hex sequence has 6 hex digits instead of 8`,  0x0001f6, 7);\n    test(\"U0001f60\", `escape hex sequence has 7 hex digits instead of 8`, 0x0001f60, 8);\n\n    test(\"ud800\"    , `invalid UTF character \\U0000d800`, '?', 5);\n    test(\"udfff\"    , `invalid UTF character \\U0000dfff`, '?', 5);\n    test(\"U00110000\", `invalid UTF character \\U00110000`, '?', 9);\n\n    test(\"xg0\"      , `undefined escape hex sequence \\xg`, 'g', 2);\n    test(\"ug000\"    , `undefined escape hex sequence \\ug`, 'g', 2);\n    test(\"Ug0000000\", `undefined escape hex sequence \\Ug`, 'g', 2);\n\n    test(\"&BAD;\", `unnamed character entity &BAD;`  , '?', 5);\n    test(\"&quot\", `unterminated named entity &quot;`, '?', 5);\n\n    test(\"400\", `escape octal sequence \\400 is larger than \\377`, 0x100, 3);\n}\n"
  },
  {
    "path": "gcc/d/dmd/mangle.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/mangle.h\n */\n\n#pragma once\n\nclass Dsymbol;\nclass Expression;\nclass FuncDeclaration;\nclass TemplateInstance;\nclass Type;\nstruct OutBuffer;\n\n// In cppmangle.d\nconst char *toCppMangleItanium(Dsymbol *s);\nconst char *cppTypeInfoMangleItanium(Dsymbol *s);\n\n// In cppmanglewin.d\nconst char *toCppMangleMSVC(Dsymbol *s);\nconst char *cppTypeInfoMangleMSVC(Dsymbol *s);\n\n// In dmangle.d\nconst char *mangleExact(FuncDeclaration *fd);\nvoid mangleToBuffer(Type *s, OutBuffer *buf);\nvoid mangleToBuffer(Expression *s, OutBuffer *buf);\nvoid mangleToBuffer(Dsymbol *s, OutBuffer *buf);\nvoid mangleToBuffer(TemplateInstance *s, OutBuffer *buf);\n"
  },
  {
    "path": "gcc/d/dmd/mars.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/mars.h\n */\n\n#pragma once\n\n/*\nIt is very important to use version control macros correctly - the\nidea is that host and target are independent. If these are done\ncorrectly, cross compilers can be built.\nThe host compiler and host operating system are also different,\nand are predefined by the host compiler. The ones used in\ndmd are:\n\nMacros defined by the compiler, not the code:\n\n    Compiler:\n        __DMC__             Digital Mars compiler\n        _MSC_VER            Microsoft compiler\n        __GNUC__            Gnu compiler\n        __clang__           Clang compiler\n\n    Host operating system:\n        _WIN32              Microsoft NT, Windows 95, Windows 98, Win32s,\n                            Windows 2000, Win XP, Vista\n        _WIN64              Windows for AMD64\n        __linux__           Linux\n        __APPLE__           Mac OSX\n        __FreeBSD__         FreeBSD\n        __OpenBSD__         OpenBSD\n        __DragonFly__       DragonFlyBSD\n        __sun               Solaris, OpenSolaris, SunOS, OpenIndiana, etc\n\nFor the target systems, there are the target operating system and\nthe target object file format:\n\n    Target operating system:\n        TARGET_WINDOS       Covers 32 bit windows and 64 bit windows\n        TARGET_LINUX        Covers 32 and 64 bit linux\n        TARGET_OSX          Covers 32 and 64 bit Mac OSX\n        TARGET_FREEBSD      Covers 32 and 64 bit FreeBSD\n        TARGET_OPENBSD      Covers 32 and 64 bit OpenBSD\n        TARGET_DRAGONFLYBSD Covers 64 bit DragonFlyBSD\n        TARGET_SOLARIS      Covers 32 and 64 bit Solaris\n\n    It is expected that the compiler for each platform will be able\n    to generate 32 and 64 bit code from the same compiler binary.\n\n    There are currently no macros for byte endianness order.\n */\n\n\n#include <stdio.h>\n#include <stdint.h>\n#include <stdarg.h>\n\n#ifdef __DMC__\n#ifdef DEBUG\n#undef assert\n#define assert(e) (static_cast<void>((e) || (printf(\"assert %s(%d) %s\\n\", __FILE__, __LINE__, #e), halt())))\n#endif\n#endif\n\nvoid unittests();\n\nstruct OutBuffer;\n\n#include \"globals.h\"\n\n#include \"root/ctfloat.h\"\n\n#include \"complex_t.h\"\n\n#include \"errors.h\"\n\nclass Dsymbol;\nclass Library;\nstruct File;\nvoid obj_start(const char *srcfile);\nvoid obj_end(Library *library, File *objfile);\nvoid obj_append(Dsymbol *s);\nvoid obj_write_deferred(Library *library);\n\n/// Utility functions used by both main and frontend.\nvoid readFile(Loc loc, File *f);\nvoid writeFile(Loc loc, File *f);\nvoid ensurePathToNameExists(Loc loc, const char *name);\n\n/// Little helper function for writing out deps.\nvoid escapePath(OutBuffer *buf, const char *fname);\n"
  },
  {
    "path": "gcc/d/dmd/module.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/module.h\n */\n\n#pragma once\n\n#include \"dsymbol.h\"\n\nstruct ModuleDeclaration;\nstruct Macro;\nstruct Escape;\n\nenum PKG\n{\n    PKGunknown, // not yet determined whether it's a package.d or not\n    PKGmodule,  // already determined that's an actual package.d\n    PKGpackage  // already determined that's an actual package\n};\n\nclass Package : public ScopeDsymbol\n{\npublic:\n    PKG isPkgMod;\n    unsigned tag;       // auto incremented tag, used to mask package tree in scopes\n    Module *mod;        // != NULL if isPkgMod == PKGmodule\n\n    const char *kind() const;\n\n    Package *isPackage() { return this; }\n\n    bool isAncestorPackageOf(const Package * const pkg) const;\n\n    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);\n    void accept(Visitor *v) { v->visit(this); }\n\n    Module *isPackageMod();\n};\n\nclass Module : public Package\n{\npublic:\n    static Module *rootModule;\n    static DsymbolTable *modules;       // symbol table of all modules\n    static Modules amodules;            // array of all modules\n    static Dsymbols deferred;   // deferred Dsymbol's needing semantic() run on them\n    static Dsymbols deferred2;  // deferred Dsymbol's needing semantic2() run on them\n    static Dsymbols deferred3;  // deferred Dsymbol's needing semantic3() run on them\n    static unsigned dprogress;  // progress resolving the deferred list\n\n    static void _init();\n\n    static AggregateDeclaration *moduleinfo;\n\n\n    const char *arg;    // original argument name\n    ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration\n    File *srcfile;      // input source file\n    File *objfile;      // output .obj file\n    File *hdrfile;      // 'header' file\n    File *docfile;      // output documentation file\n    unsigned errors;    // if any errors in file\n    unsigned numlines;  // number of lines in source file\n    int isDocFile;      // if it is a documentation input file, not D source\n    bool isPackageFile; // if it is a package.d\n    Strings contentImportedFiles;  // array of files whose content was imported\n    int needmoduleinfo;\n    int selfimports;            // 0: don't know, 1: does not, 2: does\n    bool selfImports();         // returns true if module imports itself\n\n    int rootimports;            // 0: don't know, 1: does not, 2: does\n    bool rootImports();         // returns true if module imports root module\n\n    int insearch;\n    Identifier *searchCacheIdent;\n    Dsymbol *searchCacheSymbol; // cached value of search\n    int searchCacheFlags;       // cached flags\n\n    // module from command line we're imported from,\n    // i.e. a module that will be taken all the\n    // way to an object file\n    Module *importedFrom;\n\n    Dsymbols *decldefs;         // top level declarations for this Module\n\n    Modules aimports;             // all imported modules\n\n    unsigned debuglevel;        // debug level\n    Strings *debugids;      // debug identifiers\n    Strings *debugidsNot;       // forward referenced debug identifiers\n\n    unsigned versionlevel;      // version level\n    Strings *versionids;    // version identifiers\n    Strings *versionidsNot;     // forward referenced version identifiers\n\n    Macro *macrotable;          // document comment macros\n    Escape *escapetable;        // document comment escapes\n\n    size_t nameoffset;          // offset of module name from start of ModuleInfo\n    size_t namelen;             // length of module name in characters\n\n    static Module* create(const char *arg, Identifier *ident, int doDocComment, int doHdrGen);\n\n    static Module *load(Loc loc, Identifiers *packages, Identifier *ident);\n\n    const char *kind() const;\n    File *setOutfile(const char *name, const char *dir, const char *arg, const char *ext);\n    void setDocfile();\n    bool read(Loc loc); // read file, returns 'true' if succeed, 'false' otherwise.\n    Module *parse();    // syntactic parse\n    void importAll(Scope *sc);\n    int needModuleInfo();\n    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);\n    bool isPackageAccessible(Package *p, Prot protection, int flags = 0);\n    Dsymbol *symtabInsert(Dsymbol *s);\n    void deleteObjFile();\n    static void addDeferredSemantic(Dsymbol *s);\n    static void addDeferredSemantic2(Dsymbol *s);\n    static void addDeferredSemantic3(Dsymbol *s);\n    static void runDeferredSemantic();\n    static void runDeferredSemantic2();\n    static void runDeferredSemantic3();\n    static void clearCache();\n    int imports(Module *m);\n\n    bool isRoot() { return this->importedFrom == this; }\n    // true if the module source file is directly\n    // listed in command line.\n    bool isCoreModule(Identifier *ident);\n\n    // Back end\n\n    int doppelganger;           // sub-module\n    Symbol *cov;                // private uint[] __coverage;\n    unsigned *covb;             // bit array of valid code line numbers\n\n    Symbol *sictor;             // module order independent constructor\n    Symbol *sctor;              // module constructor\n    Symbol *sdtor;              // module destructor\n    Symbol *ssharedctor;        // module shared constructor\n    Symbol *sshareddtor;        // module shared destructor\n    Symbol *stest;              // module unit test\n\n    Symbol *sfilename;          // symbol for filename\n\n    Module *isModule() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n\nstruct ModuleDeclaration\n{\n    Loc loc;\n    Identifier *id;\n    Identifiers *packages;            // array of Identifier's representing packages\n    bool isdeprecated;  // if it is a deprecated module\n    Expression *msg;\n\n    const char *toChars() const;\n};\n"
  },
  {
    "path": "gcc/d/dmd/mtype.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/mtype.d, _mtype.d)\n * Documentation:  https://dlang.org/phobos/dmd_mtype.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/mtype.d\n */\n\nmodule dmd.mtype;\n\nimport core.checkedint;\nimport core.stdc.stdarg;\nimport core.stdc.stdio;\nimport core.stdc.stdlib;\nimport core.stdc.string;\n\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.attrib;\nimport dmd.gluelayer;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dmangle;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.opover;\nimport dmd.root.ctfloat;\nimport dmd.root.outbuffer;\nimport dmd.root.rmem;\nimport dmd.root.rootobject;\nimport dmd.root.stringtable;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.visitor;\n\nenum LOGDOTEXP = 0;         // log ::dotExp()\nenum LOGDEFAULTINIT = 0;    // log ::defaultInit()\n\nextern (C++) __gshared int Tsize_t = Tuns32;\nextern (C++) __gshared int Tptrdiff_t = Tint32;\n\nenum SIZE_INVALID = (~cast(d_uns64)0);   // error return from size() functions\n\n\n/***************************\n * Return !=0 if modfrom can be implicitly converted to modto\n */\nbool MODimplicitConv(MOD modfrom, MOD modto) pure nothrow @nogc @safe\n{\n    if (modfrom == modto)\n        return true;\n\n    //printf(\"MODimplicitConv(from = %x, to = %x)\\n\", modfrom, modto);\n    auto X(T, U)(T m, U n)\n    {\n        return ((m << 4) | n);\n    }\n\n    switch (X(modfrom & ~MODFlags.shared_, modto & ~MODFlags.shared_))\n    {\n    case X(0, MODFlags.const_):\n    case X(MODFlags.wild, MODFlags.const_):\n    case X(MODFlags.wild, MODFlags.wildconst):\n    case X(MODFlags.wildconst, MODFlags.const_):\n        return (modfrom & MODFlags.shared_) == (modto & MODFlags.shared_);\n\n    case X(MODFlags.immutable_, MODFlags.const_):\n    case X(MODFlags.immutable_, MODFlags.wildconst):\n        return true;\n    default:\n        return false;\n    }\n}\n\n/***************************\n * Return MATCH.exact or MATCH.constant if a method of type '() modfrom' can call a method of type '() modto'.\n */\nMATCH MODmethodConv(MOD modfrom, MOD modto) pure nothrow @nogc @safe\n{\n    if (modfrom == modto)\n        return MATCH.exact;\n    if (MODimplicitConv(modfrom, modto))\n        return MATCH.constant;\n\n    auto X(T, U)(T m, U n)\n    {\n        return ((m << 4) | n);\n    }\n\n    switch (X(modfrom, modto))\n    {\n    case X(0, MODFlags.wild):\n    case X(MODFlags.immutable_, MODFlags.wild):\n    case X(MODFlags.const_, MODFlags.wild):\n    case X(MODFlags.wildconst, MODFlags.wild):\n    case X(MODFlags.shared_, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.shared_ | MODFlags.immutable_, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.shared_ | MODFlags.const_, MODFlags.shared_ | MODFlags.wild):\n    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.shared_ | MODFlags.wild):\n        return MATCH.constant;\n\n    default:\n        return MATCH.nomatch;\n    }\n}\n\n/***************************\n * Merge mod bits to form common mod.\n */\nMOD MODmerge(MOD mod1, MOD mod2) pure nothrow @nogc @safe\n{\n    if (mod1 == mod2)\n        return mod1;\n\n    //printf(\"MODmerge(1 = %x, 2 = %x)\\n\", mod1, mod2);\n    MOD result = 0;\n    if ((mod1 | mod2) & MODFlags.shared_)\n    {\n        // If either type is shared, the result will be shared\n        result |= MODFlags.shared_;\n        mod1 &= ~MODFlags.shared_;\n        mod2 &= ~MODFlags.shared_;\n    }\n    if (mod1 == 0 || mod1 == MODFlags.mutable || mod1 == MODFlags.const_ || mod2 == 0 || mod2 == MODFlags.mutable || mod2 == MODFlags.const_)\n    {\n        // If either type is mutable or const, the result will be const.\n        result |= MODFlags.const_;\n    }\n    else\n    {\n        // MODFlags.immutable_ vs MODFlags.wild\n        // MODFlags.immutable_ vs MODFlags.wildconst\n        //      MODFlags.wild vs MODFlags.wildconst\n        assert(mod1 & MODFlags.wild || mod2 & MODFlags.wild);\n        result |= MODFlags.wildconst;\n    }\n    return result;\n}\n\n/*********************************\n * Store modifier name into buf.\n */\nvoid MODtoBuffer(OutBuffer* buf, MOD mod) nothrow\n{\n    buf.writestring(MODtoString(mod));\n}\n\n/*********************************\n * Returns:\n *   a human readable representation of `mod`,\n *   which is the token `mod` corresponds to\n */\nconst(char)* MODtoChars(MOD mod) nothrow\n{\n    /// Works because we return a literal\n    return MODtoString(mod).ptr;\n}\n\n/// Ditto\nstring MODtoString(MOD mod) nothrow\n{\n    final switch (mod)\n    {\n    case 0:\n        return \"\";\n\n    case MODFlags.immutable_:\n        return \"immutable\";\n\n    case MODFlags.shared_:\n        return \"shared\";\n\n    case MODFlags.shared_ | MODFlags.const_:\n        return \"shared const\";\n\n    case MODFlags.const_:\n        return \"const\";\n\n    case MODFlags.shared_ | MODFlags.wild:\n        return \"shared inout\";\n\n    case MODFlags.wild:\n        return \"inout\";\n\n    case MODFlags.shared_ | MODFlags.wildconst:\n        return \"shared inout const\";\n\n    case MODFlags.wildconst:\n        return \"inout const\";\n    }\n}\n\n\n/************************************\n * Convert MODxxxx to STCxxx\n */\nStorageClass ModToStc(uint mod) pure nothrow @nogc @safe\n{\n    StorageClass stc = 0;\n    if (mod & MODFlags.immutable_)\n        stc |= STC.immutable_;\n    if (mod & MODFlags.const_)\n        stc |= STC.const_;\n    if (mod & MODFlags.wild)\n        stc |= STC.wild;\n    if (mod & MODFlags.shared_)\n        stc |= STC.shared_;\n    return stc;\n}\n\nprivate enum TFlags\n{\n    integral     = 1,\n    floating     = 2,\n    unsigned     = 4,\n    real_        = 8,\n    imaginary    = 0x10,\n    complex      = 0x20,\n}\n\nenum ENUMTY : int\n{\n    Tarray,     // slice array, aka T[]\n    Tsarray,    // static array, aka T[dimension]\n    Taarray,    // associative array, aka T[type]\n    Tpointer,\n    Treference,\n    Tfunction,\n    Tident,\n    Tclass,\n    Tstruct,\n    Tenum,\n\n    Tdelegate,\n    Tnone,\n    Tvoid,\n    Tint8,\n    Tuns8,\n    Tint16,\n    Tuns16,\n    Tint32,\n    Tuns32,\n    Tint64,\n\n    Tuns64,\n    Tfloat32,\n    Tfloat64,\n    Tfloat80,\n    Timaginary32,\n    Timaginary64,\n    Timaginary80,\n    Tcomplex32,\n    Tcomplex64,\n    Tcomplex80,\n\n    Tbool,\n    Tchar,\n    Twchar,\n    Tdchar,\n    Terror,\n    Tinstance,\n    Ttypeof,\n    Ttuple,\n    Tslice,\n    Treturn,\n\n    Tnull,\n    Tvector,\n    Tint128,\n    Tuns128,\n    TMAX,\n}\n\nalias Tarray = ENUMTY.Tarray;\nalias Tsarray = ENUMTY.Tsarray;\nalias Taarray = ENUMTY.Taarray;\nalias Tpointer = ENUMTY.Tpointer;\nalias Treference = ENUMTY.Treference;\nalias Tfunction = ENUMTY.Tfunction;\nalias Tident = ENUMTY.Tident;\nalias Tclass = ENUMTY.Tclass;\nalias Tstruct = ENUMTY.Tstruct;\nalias Tenum = ENUMTY.Tenum;\nalias Tdelegate = ENUMTY.Tdelegate;\nalias Tnone = ENUMTY.Tnone;\nalias Tvoid = ENUMTY.Tvoid;\nalias Tint8 = ENUMTY.Tint8;\nalias Tuns8 = ENUMTY.Tuns8;\nalias Tint16 = ENUMTY.Tint16;\nalias Tuns16 = ENUMTY.Tuns16;\nalias Tint32 = ENUMTY.Tint32;\nalias Tuns32 = ENUMTY.Tuns32;\nalias Tint64 = ENUMTY.Tint64;\nalias Tuns64 = ENUMTY.Tuns64;\nalias Tfloat32 = ENUMTY.Tfloat32;\nalias Tfloat64 = ENUMTY.Tfloat64;\nalias Tfloat80 = ENUMTY.Tfloat80;\nalias Timaginary32 = ENUMTY.Timaginary32;\nalias Timaginary64 = ENUMTY.Timaginary64;\nalias Timaginary80 = ENUMTY.Timaginary80;\nalias Tcomplex32 = ENUMTY.Tcomplex32;\nalias Tcomplex64 = ENUMTY.Tcomplex64;\nalias Tcomplex80 = ENUMTY.Tcomplex80;\nalias Tbool = ENUMTY.Tbool;\nalias Tchar = ENUMTY.Tchar;\nalias Twchar = ENUMTY.Twchar;\nalias Tdchar = ENUMTY.Tdchar;\nalias Terror = ENUMTY.Terror;\nalias Tinstance = ENUMTY.Tinstance;\nalias Ttypeof = ENUMTY.Ttypeof;\nalias Ttuple = ENUMTY.Ttuple;\nalias Tslice = ENUMTY.Tslice;\nalias Treturn = ENUMTY.Treturn;\nalias Tnull = ENUMTY.Tnull;\nalias Tvector = ENUMTY.Tvector;\nalias Tint128 = ENUMTY.Tint128;\nalias Tuns128 = ENUMTY.Tuns128;\nalias TMAX = ENUMTY.TMAX;\n\nalias TY = ubyte;\n\nenum MODFlags : int\n{\n    const_       = 1,    // type is const\n    immutable_   = 4,    // type is immutable\n    shared_      = 2,    // type is shared\n    wild         = 8,    // type is wild\n    wildconst    = (MODFlags.wild | MODFlags.const_), // type is wild const\n    mutable      = 0x10, // type is mutable (only used in wildcard matching)\n}\n\nalias MOD = ubyte;\n\n/****************\n * dotExp() bit flags\n */\nenum DotExpFlag\n{\n    gag     = 1,    // don't report \"not a property\" error and just return null\n    noDeref = 2,    // the use of the expression will not attempt a dereference\n}\n\n/***********************************************************\n */\nextern (C++) abstract class Type : RootObject\n{\n    TY ty;\n    MOD mod; // modifiers MODxxxx\n    char* deco;\n\n    /* These are cached values that are lazily evaluated by constOf(), immutableOf(), etc.\n     * They should not be referenced by anybody but mtype.c.\n     * They can be NULL if not lazily evaluated yet.\n     * Note that there is no \"shared immutable\", because that is just immutable\n     * Naked == no MOD bits\n     */\n    Type cto;       // MODFlags.const_                 ? naked version of this type : const version\n    Type ito;       // MODFlags.immutable_             ? naked version of this type : immutable version\n    Type sto;       // MODFlags.shared_                ? naked version of this type : shared mutable version\n    Type scto;      // MODFlags.shared_ | MODFlags.const_     ? naked version of this type : shared const version\n    Type wto;       // MODFlags.wild                  ? naked version of this type : wild version\n    Type wcto;      // MODFlags.wildconst             ? naked version of this type : wild const version\n    Type swto;      // MODFlags.shared_ | MODFlags.wild      ? naked version of this type : shared wild version\n    Type swcto;     // MODFlags.shared_ | MODFlags.wildconst ? naked version of this type : shared wild const version\n\n    Type pto;       // merged pointer to this type\n    Type rto;       // reference to this type\n    Type arrayof;   // array of this type\n\n    TypeInfoDeclaration vtinfo;     // TypeInfo object for this Type\n\n    type* ctype;                    // for back end\n\n    extern (C++) __gshared Type tvoid;\n    extern (C++) __gshared Type tint8;\n    extern (C++) __gshared Type tuns8;\n    extern (C++) __gshared Type tint16;\n    extern (C++) __gshared Type tuns16;\n    extern (C++) __gshared Type tint32;\n    extern (C++) __gshared Type tuns32;\n    extern (C++) __gshared Type tint64;\n    extern (C++) __gshared Type tuns64;\n    extern (C++) __gshared Type tint128;\n    extern (C++) __gshared Type tuns128;\n    extern (C++) __gshared Type tfloat32;\n    extern (C++) __gshared Type tfloat64;\n    extern (C++) __gshared Type tfloat80;\n    extern (C++) __gshared Type timaginary32;\n    extern (C++) __gshared Type timaginary64;\n    extern (C++) __gshared Type timaginary80;\n    extern (C++) __gshared Type tcomplex32;\n    extern (C++) __gshared Type tcomplex64;\n    extern (C++) __gshared Type tcomplex80;\n    extern (C++) __gshared Type tbool;\n    extern (C++) __gshared Type tchar;\n    extern (C++) __gshared Type twchar;\n    extern (C++) __gshared Type tdchar;\n\n    // Some special types\n    extern (C++) __gshared Type tshiftcnt;\n    extern (C++) __gshared Type tvoidptr;    // void*\n    extern (C++) __gshared Type tstring;     // immutable(char)[]\n    extern (C++) __gshared Type twstring;    // immutable(wchar)[]\n    extern (C++) __gshared Type tdstring;    // immutable(dchar)[]\n    extern (C++) __gshared Type tvalist;     // va_list alias\n    extern (C++) __gshared Type terror;      // for error recovery\n    extern (C++) __gshared Type tnull;       // for null type\n\n    extern (C++) __gshared Type tsize_t;     // matches size_t alias\n    extern (C++) __gshared Type tptrdiff_t;  // matches ptrdiff_t alias\n    extern (C++) __gshared Type thash_t;     // matches hash_t alias\n\n    extern (C++) __gshared ClassDeclaration dtypeinfo;\n    extern (C++) __gshared ClassDeclaration typeinfoclass;\n    extern (C++) __gshared ClassDeclaration typeinfointerface;\n    extern (C++) __gshared ClassDeclaration typeinfostruct;\n    extern (C++) __gshared ClassDeclaration typeinfopointer;\n    extern (C++) __gshared ClassDeclaration typeinfoarray;\n    extern (C++) __gshared ClassDeclaration typeinfostaticarray;\n    extern (C++) __gshared ClassDeclaration typeinfoassociativearray;\n    extern (C++) __gshared ClassDeclaration typeinfovector;\n    extern (C++) __gshared ClassDeclaration typeinfoenum;\n    extern (C++) __gshared ClassDeclaration typeinfofunction;\n    extern (C++) __gshared ClassDeclaration typeinfodelegate;\n    extern (C++) __gshared ClassDeclaration typeinfotypelist;\n    extern (C++) __gshared ClassDeclaration typeinfoconst;\n    extern (C++) __gshared ClassDeclaration typeinfoinvariant;\n    extern (C++) __gshared ClassDeclaration typeinfoshared;\n    extern (C++) __gshared ClassDeclaration typeinfowild;\n\n    extern (C++) __gshared TemplateDeclaration rtinfo;\n\n    extern (C++) __gshared Type[TMAX] basic;\n\n    extern (D) __gshared StringTable stringtable;\n    extern (D) private __gshared ubyte[TMAX] sizeTy = ()\n        {\n            ubyte[TMAX] sizeTy = __traits(classInstanceSize, TypeBasic);\n            sizeTy[Tsarray] = __traits(classInstanceSize, TypeSArray);\n            sizeTy[Tarray] = __traits(classInstanceSize, TypeDArray);\n            sizeTy[Taarray] = __traits(classInstanceSize, TypeAArray);\n            sizeTy[Tpointer] = __traits(classInstanceSize, TypePointer);\n            sizeTy[Treference] = __traits(classInstanceSize, TypeReference);\n            sizeTy[Tfunction] = __traits(classInstanceSize, TypeFunction);\n            sizeTy[Tdelegate] = __traits(classInstanceSize, TypeDelegate);\n            sizeTy[Tident] = __traits(classInstanceSize, TypeIdentifier);\n            sizeTy[Tinstance] = __traits(classInstanceSize, TypeInstance);\n            sizeTy[Ttypeof] = __traits(classInstanceSize, TypeTypeof);\n            sizeTy[Tenum] = __traits(classInstanceSize, TypeEnum);\n            sizeTy[Tstruct] = __traits(classInstanceSize, TypeStruct);\n            sizeTy[Tclass] = __traits(classInstanceSize, TypeClass);\n            sizeTy[Ttuple] = __traits(classInstanceSize, TypeTuple);\n            sizeTy[Tslice] = __traits(classInstanceSize, TypeSlice);\n            sizeTy[Treturn] = __traits(classInstanceSize, TypeReturn);\n            sizeTy[Terror] = __traits(classInstanceSize, TypeError);\n            sizeTy[Tnull] = __traits(classInstanceSize, TypeNull);\n            sizeTy[Tvector] = __traits(classInstanceSize, TypeVector);\n            return sizeTy;\n        }();\n\n    final extern (D) this(TY ty)\n    {\n        this.ty = ty;\n    }\n\n    const(char)* kind() const nothrow pure @nogc @safe\n    {\n        assert(false); // should be overridden\n    }\n\n    final Type copy() nothrow\n    {\n        Type t = cast(Type)mem.xmalloc(sizeTy[ty]);\n        memcpy(cast(void*)t, cast(void*)this, sizeTy[ty]);\n        return t;\n    }\n\n    Type syntaxCopy()\n    {\n        fprintf(stderr, \"this = %s, ty = %d\\n\", toChars(), ty);\n        assert(0);\n    }\n\n    override bool equals(RootObject o) const\n    {\n        Type t = cast(Type)o;\n        //printf(\"Type::equals(%s, %s)\\n\", toChars(), t.toChars());\n        // deco strings are unique\n        // and semantic() has been run\n        if (this == o || ((t && deco == t.deco) && deco !is null))\n        {\n            //printf(\"deco = '%s', t.deco = '%s'\\n\", deco, t.deco);\n            return true;\n        }\n        //if (deco && t && t.deco) printf(\"deco = '%s', t.deco = '%s'\\n\", deco, t.deco);\n        return false;\n    }\n\n    final bool equivalent(Type t)\n    {\n        return immutableOf().equals(t.immutableOf());\n    }\n\n    // kludge for template.isType()\n    override final DYNCAST dyncast() const\n    {\n        return DYNCAST.type;\n    }\n\n    /*******************************\n     * Covariant means that 'this' can substitute for 't',\n     * i.e. a pure function is a match for an impure type.\n     * Params:\n     *      t = type 'this' is covariant with\n     *      pstc = if not null, store STCxxxx which would make it covariant\n     *      fix17349 = enable fix https://issues.dlang.org/show_bug.cgi?id=17349\n     * Returns:\n     *      0       types are distinct\n     *      1       this is covariant with t\n     *      2       arguments match as far as overloading goes,\n     *              but types are not covariant\n     *      3       cannot determine covariance because of forward references\n     *      *pstc   STCxxxx which would make it covariant\n     */\n    final int covariant(Type t, StorageClass* pstc = null, bool fix17349 = true)\n    {\n        version (none)\n        {\n            printf(\"Type::covariant(t = %s) %s\\n\", t.toChars(), toChars());\n            printf(\"deco = %p, %p\\n\", deco, t.deco);\n            //    printf(\"ty = %d\\n\", next.ty);\n            printf(\"mod = %x, %x\\n\", mod, t.mod);\n        }\n        if (pstc)\n            *pstc = 0;\n        StorageClass stc = 0;\n\n        bool notcovariant = false;\n\n        TypeFunction t1;\n        TypeFunction t2;\n\n        if (equals(t))\n            return 1; // covariant\n\n        if (ty != Tfunction || t.ty != Tfunction)\n            goto Ldistinct;\n\n        t1 = cast(TypeFunction)this;\n        t2 = cast(TypeFunction)t;\n\n        if (t1.varargs != t2.varargs)\n            goto Ldistinct;\n\n        if (t1.parameters && t2.parameters)\n        {\n            size_t dim = Parameter.dim(t1.parameters);\n            if (dim != Parameter.dim(t2.parameters))\n                goto Ldistinct;\n\n            for (size_t i = 0; i < dim; i++)\n            {\n                Parameter fparam1 = Parameter.getNth(t1.parameters, i);\n                Parameter fparam2 = Parameter.getNth(t2.parameters, i);\n\n                if (!fparam1.type.equals(fparam2.type))\n                {\n                    if (!fix17349)\n                        goto Ldistinct;\n                    Type tp1 = fparam1.type;\n                    Type tp2 = fparam2.type;\n                    if (tp1.ty == tp2.ty)\n                    {\n                        if (tp1.ty == Tclass)\n                        {\n                            if ((cast(TypeClass)tp1).sym == (cast(TypeClass)tp2).sym && MODimplicitConv(tp2.mod, tp1.mod))\n                                goto Lcov;\n                        }\n                        else if (tp1.ty == Tstruct)\n                        {\n                            if ((cast(TypeStruct)tp1).sym == (cast(TypeStruct)tp2).sym && MODimplicitConv(tp2.mod, tp1.mod))\n                                goto Lcov;\n                        }\n                        else if (tp1.ty == Tpointer)\n                        {\n                            if (tp2.implicitConvTo(tp1))\n                                goto Lcov;\n                        }\n                        else if (tp1.ty == Tarray)\n                        {\n                            if (tp2.implicitConvTo(tp1))\n                                goto Lcov;\n                        }\n                        else if (tp1.ty == Tdelegate)\n                        {\n                            if (tp1.implicitConvTo(tp2))\n                                goto Lcov;\n                        }\n                    }\n                    goto Ldistinct;\n                }\n            Lcov:\n                notcovariant |= !fparam1.isCovariant(t1.isref, fparam2);\n            }\n        }\n        else if (t1.parameters != t2.parameters)\n        {\n            size_t dim1 = !t1.parameters ? 0 : t1.parameters.dim;\n            size_t dim2 = !t2.parameters ? 0 : t2.parameters.dim;\n            if (dim1 || dim2)\n                goto Ldistinct;\n        }\n\n        // The argument lists match\n        if (notcovariant)\n            goto Lnotcovariant;\n        if (t1.linkage != t2.linkage)\n            goto Lnotcovariant;\n\n        {\n            // Return types\n            Type t1n = t1.next;\n            Type t2n = t2.next;\n\n            if (!t1n || !t2n) // happens with return type inference\n                goto Lnotcovariant;\n\n            if (t1n.equals(t2n))\n                goto Lcovariant;\n            if (t1n.ty == Tclass && t2n.ty == Tclass)\n            {\n                /* If same class type, but t2n is const, then it's\n                 * covariant. Do this test first because it can work on\n                 * forward references.\n                 */\n                if ((cast(TypeClass)t1n).sym == (cast(TypeClass)t2n).sym && MODimplicitConv(t1n.mod, t2n.mod))\n                    goto Lcovariant;\n\n                // If t1n is forward referenced:\n                ClassDeclaration cd = (cast(TypeClass)t1n).sym;\n                if (cd.semanticRun < PASS.semanticdone && !cd.isBaseInfoComplete())\n                    cd.dsymbolSemantic(null);\n                if (!cd.isBaseInfoComplete())\n                {\n                    return 3; // forward references\n                }\n            }\n            if (t1n.ty == Tstruct && t2n.ty == Tstruct)\n            {\n                if ((cast(TypeStruct)t1n).sym == (cast(TypeStruct)t2n).sym && MODimplicitConv(t1n.mod, t2n.mod))\n                    goto Lcovariant;\n            }\n            else if (t1n.ty == t2n.ty && t1n.implicitConvTo(t2n))\n                goto Lcovariant;\n            else if (t1n.ty == Tnull && t1n.implicitConvTo(t2n) && t1n.size() == t2n.size())\n                goto Lcovariant;\n        }\n        goto Lnotcovariant;\n\n    Lcovariant:\n        if (t1.isref != t2.isref)\n            goto Lnotcovariant;\n\n        if (!t1.isref && (t1.isscope || t2.isscope))\n        {\n            StorageClass stc1 = t1.isscope ? STC.scope_ : 0;\n            StorageClass stc2 = t2.isscope ? STC.scope_ : 0;\n            if (t1.isreturn)\n            {\n                stc1 |= STC.return_;\n                if (!t1.isscope)\n                    stc1 |= STC.ref_;\n            }\n            if (t2.isreturn)\n            {\n                stc2 |= STC.return_;\n                if (!t2.isscope)\n                    stc2 |= STC.ref_;\n            }\n            if (!Parameter.isCovariantScope(t1.isref, stc1, stc2))\n                goto Lnotcovariant;\n        }\n\n        // We can subtract 'return ref' from 'this', but cannot add it\n        else if (t1.isreturn && !t2.isreturn)\n            goto Lnotcovariant;\n\n        /* Can convert mutable to const\n         */\n        if (!MODimplicitConv(t2.mod, t1.mod))\n        {\n            version (none)\n            {\n                //stop attribute inference with const\n                // If adding 'const' will make it covariant\n                if (MODimplicitConv(t2.mod, MODmerge(t1.mod, MODFlags.const_)))\n                    stc |= STC.const_;\n                else\n                    goto Lnotcovariant;\n            }\n            else\n            {\n                goto Ldistinct;\n            }\n        }\n\n        /* Can convert pure to impure, nothrow to throw, and nogc to gc\n         */\n        if (!t1.purity && t2.purity)\n            stc |= STC.pure_;\n\n        if (!t1.isnothrow && t2.isnothrow)\n            stc |= STC.nothrow_;\n\n        if (!t1.isnogc && t2.isnogc)\n            stc |= STC.nogc;\n\n        /* Can convert safe/trusted to system\n         */\n        if (t1.trust <= TRUST.system && t2.trust >= TRUST.trusted)\n        {\n            // Should we infer trusted or safe? Go with safe.\n            stc |= STC.safe;\n        }\n\n        if (stc)\n        {\n            if (pstc)\n                *pstc = stc;\n            goto Lnotcovariant;\n        }\n\n        //printf(\"\\tcovaraint: 1\\n\");\n        return 1;\n\n    Ldistinct:\n        //printf(\"\\tcovaraint: 0\\n\");\n        return 0;\n\n    Lnotcovariant:\n        //printf(\"\\tcovaraint: 2\\n\");\n        return 2;\n    }\n\n    /********************************\n     * For pretty-printing a type.\n     */\n    final override const(char)* toChars()\n    {\n        OutBuffer buf;\n        buf.reserve(16);\n        HdrGenState hgs;\n        hgs.fullQual = (ty == Tclass && !mod);\n\n        .toCBuffer(this, &buf, null, &hgs);\n        return buf.extractString();\n    }\n\n    /// ditto\n    final char* toPrettyChars(bool QualifyTypes = false)\n    {\n        OutBuffer buf;\n        buf.reserve(16);\n        HdrGenState hgs;\n        hgs.fullQual = QualifyTypes;\n\n        .toCBuffer(this, &buf, null, &hgs);\n        return buf.extractString();\n    }\n\n    static void _init()\n    {\n        stringtable._init(14000);\n\n        // Set basic types\n        __gshared TY* basetab =\n        [\n            Tvoid,\n            Tint8,\n            Tuns8,\n            Tint16,\n            Tuns16,\n            Tint32,\n            Tuns32,\n            Tint64,\n            Tuns64,\n            Tint128,\n            Tuns128,\n            Tfloat32,\n            Tfloat64,\n            Tfloat80,\n            Timaginary32,\n            Timaginary64,\n            Timaginary80,\n            Tcomplex32,\n            Tcomplex64,\n            Tcomplex80,\n            Tbool,\n            Tchar,\n            Twchar,\n            Tdchar,\n            Terror\n        ];\n\n        for (size_t i = 0; basetab[i] != Terror; i++)\n        {\n            Type t = new TypeBasic(basetab[i]);\n            t = t.merge();\n            basic[basetab[i]] = t;\n        }\n        basic[Terror] = new TypeError();\n\n        tvoid = basic[Tvoid];\n        tint8 = basic[Tint8];\n        tuns8 = basic[Tuns8];\n        tint16 = basic[Tint16];\n        tuns16 = basic[Tuns16];\n        tint32 = basic[Tint32];\n        tuns32 = basic[Tuns32];\n        tint64 = basic[Tint64];\n        tuns64 = basic[Tuns64];\n        tint128 = basic[Tint128];\n        tuns128 = basic[Tuns128];\n        tfloat32 = basic[Tfloat32];\n        tfloat64 = basic[Tfloat64];\n        tfloat80 = basic[Tfloat80];\n\n        timaginary32 = basic[Timaginary32];\n        timaginary64 = basic[Timaginary64];\n        timaginary80 = basic[Timaginary80];\n\n        tcomplex32 = basic[Tcomplex32];\n        tcomplex64 = basic[Tcomplex64];\n        tcomplex80 = basic[Tcomplex80];\n\n        tbool = basic[Tbool];\n        tchar = basic[Tchar];\n        twchar = basic[Twchar];\n        tdchar = basic[Tdchar];\n\n        tshiftcnt = tint32;\n        terror = basic[Terror];\n        tnull = basic[Tnull];\n        tnull = new TypeNull();\n        tnull.deco = tnull.merge().deco;\n\n        tvoidptr = tvoid.pointerTo();\n        tstring = tchar.immutableOf().arrayOf();\n        twstring = twchar.immutableOf().arrayOf();\n        tdstring = tdchar.immutableOf().arrayOf();\n        tvalist = Target.va_listType();\n\n        if (global.params.isLP64)\n        {\n            Tsize_t = Tuns64;\n            Tptrdiff_t = Tint64;\n        }\n        else\n        {\n            Tsize_t = Tuns32;\n            Tptrdiff_t = Tint32;\n        }\n\n        tsize_t = basic[Tsize_t];\n        tptrdiff_t = basic[Tptrdiff_t];\n        thash_t = tsize_t;\n    }\n\n    final d_uns64 size()\n    {\n        return size(Loc.initial);\n    }\n\n    d_uns64 size(const ref Loc loc)\n    {\n        error(loc, \"no size for type `%s`\", toChars());\n        return SIZE_INVALID;\n    }\n\n    uint alignsize()\n    {\n        return cast(uint)size(Loc.initial);\n    }\n\n    final Type trySemantic(const ref Loc loc, Scope* sc)\n    {\n        //printf(\"+trySemantic(%s) %d\\n\", toChars(), global.errors);\n\n        // Needed to display any deprecations that were gagged\n        auto tcopy = this.syntaxCopy();\n\n        uint errors = global.startGagging();\n        Type t = typeSemantic(this, loc, sc);\n        if (global.endGagging(errors) || t.ty == Terror) // if any errors happened\n        {\n            t = null;\n        }\n        else\n        {\n            // If `typeSemantic` succeeded, there may have been deprecations that\n            // were gagged due the the `startGagging` above.  Run again to display\n            // those deprecations.  https://issues.dlang.org/show_bug.cgi?id=19107\n            if (global.gaggedWarnings > 0)\n                typeSemantic(tcopy, loc, sc);\n        }\n        //printf(\"-trySemantic(%s) %d\\n\", toChars(), global.errors);\n        return t;\n    }\n\n    /*************************************\n     * This version does a merge even if the deco is already computed.\n     * Necessary for types that have a deco, but are not merged.\n     */\n    final Type merge2()\n    {\n        //printf(\"merge2(%s)\\n\", toChars());\n        Type t = this;\n        assert(t);\n        if (!t.deco)\n            return t.merge();\n\n        StringValue* sv = stringtable.lookup(t.deco, strlen(t.deco));\n        if (sv && sv.ptrvalue)\n        {\n            t = cast(Type)sv.ptrvalue;\n            assert(t.deco);\n        }\n        else\n            assert(0);\n        return t;\n    }\n\n    /*********************************\n     * Store this type's modifier name into buf.\n     */\n    final void modToBuffer(OutBuffer* buf) nothrow\n    {\n        if (mod)\n        {\n            buf.writeByte(' ');\n            MODtoBuffer(buf, mod);\n        }\n    }\n\n    /*********************************\n     * Return this type's modifier name.\n     */\n    final char* modToChars() nothrow\n    {\n        OutBuffer buf;\n        buf.reserve(16);\n        modToBuffer(&buf);\n        return buf.extractString();\n    }\n\n    bool isintegral()\n    {\n        return false;\n    }\n\n    // real, imaginary, or complex\n    bool isfloating()\n    {\n        return false;\n    }\n\n    bool isreal()\n    {\n        return false;\n    }\n\n    bool isimaginary()\n    {\n        return false;\n    }\n\n    bool iscomplex()\n    {\n        return false;\n    }\n\n    bool isscalar()\n    {\n        return false;\n    }\n\n    bool isunsigned()\n    {\n        return false;\n    }\n\n    bool isscope()\n    {\n        return false;\n    }\n\n    bool isString()\n    {\n        return false;\n    }\n\n    /**************************\n     * When T is mutable,\n     * Given:\n     *      T a, b;\n     * Can we bitwise assign:\n     *      a = b;\n     * ?\n     */\n    bool isAssignable()\n    {\n        return true;\n    }\n\n    /**************************\n     * Returns true if T can be converted to boolean value.\n     */\n    bool isBoolean()\n    {\n        return isscalar();\n    }\n\n    /*********************************\n     * Check type to see if it is based on a deprecated symbol.\n     */\n    void checkDeprecated(const ref Loc loc, Scope* sc)\n    {\n        if (Dsymbol s = toDsymbol(sc))\n        {\n            s.checkDeprecated(loc, sc);\n        }\n    }\n\n    final bool isConst() const nothrow pure @nogc @safe\n    {\n        return (mod & MODFlags.const_) != 0;\n    }\n\n    final bool isImmutable() const nothrow pure @nogc @safe\n    {\n        return (mod & MODFlags.immutable_) != 0;\n    }\n\n    final bool isMutable() const nothrow pure @nogc @safe\n    {\n        return (mod & (MODFlags.const_ | MODFlags.immutable_ | MODFlags.wild)) == 0;\n    }\n\n    final bool isShared() const nothrow pure @nogc @safe\n    {\n        return (mod & MODFlags.shared_) != 0;\n    }\n\n    final bool isSharedConst() const nothrow pure @nogc @safe\n    {\n        return (mod & (MODFlags.shared_ | MODFlags.const_)) == (MODFlags.shared_ | MODFlags.const_);\n    }\n\n    final bool isWild() const nothrow pure @nogc @safe\n    {\n        return (mod & MODFlags.wild) != 0;\n    }\n\n    final bool isWildConst() const nothrow pure @nogc @safe\n    {\n        return (mod & MODFlags.wildconst) == MODFlags.wildconst;\n    }\n\n    final bool isSharedWild() const nothrow pure @nogc @safe\n    {\n        return (mod & (MODFlags.shared_ | MODFlags.wild)) == (MODFlags.shared_ | MODFlags.wild);\n    }\n\n    final bool isNaked() const nothrow pure @nogc @safe\n    {\n        return mod == 0;\n    }\n\n    /********************************\n     * Return a copy of this type with all attributes null-initialized.\n     * Useful for creating a type with different modifiers.\n     */\n    final Type nullAttributes() nothrow\n    {\n        uint sz = sizeTy[ty];\n        Type t = cast(Type)mem.xmalloc(sz);\n        memcpy(cast(void*)t, cast(void*)this, sz);\n        // t.mod = NULL;  // leave mod unchanged\n        t.deco = null;\n        t.arrayof = null;\n        t.pto = null;\n        t.rto = null;\n        t.cto = null;\n        t.ito = null;\n        t.sto = null;\n        t.scto = null;\n        t.wto = null;\n        t.wcto = null;\n        t.swto = null;\n        t.swcto = null;\n        t.vtinfo = null;\n        t.ctype = null;\n        if (t.ty == Tstruct)\n            (cast(TypeStruct)t).att = AliasThisRec.fwdref;\n        if (t.ty == Tclass)\n            (cast(TypeClass)t).att = AliasThisRec.fwdref;\n        return t;\n    }\n\n    /********************************\n     * Convert to 'const'.\n     */\n    final Type constOf()\n    {\n        //printf(\"Type::constOf() %p %s\\n\", this, toChars());\n        if (mod == MODFlags.const_)\n            return this;\n        if (cto)\n        {\n            assert(cto.mod == MODFlags.const_);\n            return cto;\n        }\n        Type t = makeConst();\n        t = t.merge();\n        t.fixTo(this);\n        //printf(\"-Type::constOf() %p %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    /********************************\n     * Convert to 'immutable'.\n     */\n    final Type immutableOf()\n    {\n        //printf(\"Type::immutableOf() %p %s\\n\", this, toChars());\n        if (isImmutable())\n            return this;\n        if (ito)\n        {\n            assert(ito.isImmutable());\n            return ito;\n        }\n        Type t = makeImmutable();\n        t = t.merge();\n        t.fixTo(this);\n        //printf(\"\\t%p\\n\", t);\n        return t;\n    }\n\n    /********************************\n     * Make type mutable.\n     */\n    final Type mutableOf()\n    {\n        //printf(\"Type::mutableOf() %p, %s\\n\", this, toChars());\n        Type t = this;\n        if (isImmutable())\n        {\n            t = ito; // immutable => naked\n            assert(!t || (t.isMutable() && !t.isShared()));\n        }\n        else if (isConst())\n        {\n            if (isShared())\n            {\n                if (isWild())\n                    t = swcto; // shared wild const -> shared\n                else\n                    t = sto; // shared const => shared\n            }\n            else\n            {\n                if (isWild())\n                    t = wcto; // wild const -> naked\n                else\n                    t = cto; // const => naked\n            }\n            assert(!t || t.isMutable());\n        }\n        else if (isWild())\n        {\n            if (isShared())\n                t = sto; // shared wild => shared\n            else\n                t = wto; // wild => naked\n            assert(!t || t.isMutable());\n        }\n        if (!t)\n        {\n            t = makeMutable();\n            t = t.merge();\n            t.fixTo(this);\n        }\n        else\n            t = t.merge();\n        assert(t.isMutable());\n        return t;\n    }\n\n    final Type sharedOf()\n    {\n        //printf(\"Type::sharedOf() %p, %s\\n\", this, toChars());\n        if (mod == MODFlags.shared_)\n            return this;\n        if (sto)\n        {\n            assert(sto.mod == MODFlags.shared_);\n            return sto;\n        }\n        Type t = makeShared();\n        t = t.merge();\n        t.fixTo(this);\n        //printf(\"\\t%p\\n\", t);\n        return t;\n    }\n\n    final Type sharedConstOf()\n    {\n        //printf(\"Type::sharedConstOf() %p, %s\\n\", this, toChars());\n        if (mod == (MODFlags.shared_ | MODFlags.const_))\n            return this;\n        if (scto)\n        {\n            assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));\n            return scto;\n        }\n        Type t = makeSharedConst();\n        t = t.merge();\n        t.fixTo(this);\n        //printf(\"\\t%p\\n\", t);\n        return t;\n    }\n\n    /********************************\n     * Make type unshared.\n     *      0            => 0\n     *      const        => const\n     *      immutable    => immutable\n     *      shared       => 0\n     *      shared const => const\n     *      wild         => wild\n     *      wild const   => wild const\n     *      shared wild  => wild\n     *      shared wild const => wild const\n     */\n    final Type unSharedOf()\n    {\n        //printf(\"Type::unSharedOf() %p, %s\\n\", this, toChars());\n        Type t = this;\n\n        if (isShared())\n        {\n            if (isWild())\n            {\n                if (isConst())\n                    t = wcto; // shared wild const => wild const\n                else\n                    t = wto; // shared wild => wild\n            }\n            else\n            {\n                if (isConst())\n                    t = cto; // shared const => const\n                else\n                    t = sto; // shared => naked\n            }\n            assert(!t || !t.isShared());\n        }\n\n        if (!t)\n        {\n            t = this.nullAttributes();\n            t.mod = mod & ~MODFlags.shared_;\n            t.ctype = ctype;\n            t = t.merge();\n            t.fixTo(this);\n        }\n        else\n            t = t.merge();\n        assert(!t.isShared());\n        return t;\n    }\n\n    /********************************\n     * Convert to 'wild'.\n     */\n    final Type wildOf()\n    {\n        //printf(\"Type::wildOf() %p %s\\n\", this, toChars());\n        if (mod == MODFlags.wild)\n            return this;\n        if (wto)\n        {\n            assert(wto.mod == MODFlags.wild);\n            return wto;\n        }\n        Type t = makeWild();\n        t = t.merge();\n        t.fixTo(this);\n        //printf(\"\\t%p %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    final Type wildConstOf()\n    {\n        //printf(\"Type::wildConstOf() %p %s\\n\", this, toChars());\n        if (mod == MODFlags.wildconst)\n            return this;\n        if (wcto)\n        {\n            assert(wcto.mod == MODFlags.wildconst);\n            return wcto;\n        }\n        Type t = makeWildConst();\n        t = t.merge();\n        t.fixTo(this);\n        //printf(\"\\t%p %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    final Type sharedWildOf()\n    {\n        //printf(\"Type::sharedWildOf() %p, %s\\n\", this, toChars());\n        if (mod == (MODFlags.shared_ | MODFlags.wild))\n            return this;\n        if (swto)\n        {\n            assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));\n            return swto;\n        }\n        Type t = makeSharedWild();\n        t = t.merge();\n        t.fixTo(this);\n        //printf(\"\\t%p %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    final Type sharedWildConstOf()\n    {\n        //printf(\"Type::sharedWildConstOf() %p, %s\\n\", this, toChars());\n        if (mod == (MODFlags.shared_ | MODFlags.wildconst))\n            return this;\n        if (swcto)\n        {\n            assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));\n            return swcto;\n        }\n        Type t = makeSharedWildConst();\n        t = t.merge();\n        t.fixTo(this);\n        //printf(\"\\t%p %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    /**********************************\n     * For our new type 'this', which is type-constructed from t,\n     * fill in the cto, ito, sto, scto, wto shortcuts.\n     */\n    final void fixTo(Type t)\n    {\n        // If fixing this: immutable(T*) by t: immutable(T)*,\n        // cache t to this.xto won't break transitivity.\n        Type mto = null;\n        Type tn = nextOf();\n        if (!tn || ty != Tsarray && tn.mod == t.nextOf().mod)\n        {\n            switch (t.mod)\n            {\n            case 0:\n                mto = t;\n                break;\n\n            case MODFlags.const_:\n                cto = t;\n                break;\n\n            case MODFlags.wild:\n                wto = t;\n                break;\n\n            case MODFlags.wildconst:\n                wcto = t;\n                break;\n\n            case MODFlags.shared_:\n                sto = t;\n                break;\n\n            case MODFlags.shared_ | MODFlags.const_:\n                scto = t;\n                break;\n\n            case MODFlags.shared_ | MODFlags.wild:\n                swto = t;\n                break;\n\n            case MODFlags.shared_ | MODFlags.wildconst:\n                swcto = t;\n                break;\n\n            case MODFlags.immutable_:\n                ito = t;\n                break;\n\n            default:\n                break;\n            }\n        }\n        assert(mod != t.mod);\n\n        auto X(T, U)(T m, U n)\n        {\n            return ((m << 4) | n);\n        }\n\n        switch (mod)\n        {\n        case 0:\n            break;\n\n        case MODFlags.const_:\n            cto = mto;\n            t.cto = this;\n            break;\n\n        case MODFlags.wild:\n            wto = mto;\n            t.wto = this;\n            break;\n\n        case MODFlags.wildconst:\n            wcto = mto;\n            t.wcto = this;\n            break;\n\n        case MODFlags.shared_:\n            sto = mto;\n            t.sto = this;\n            break;\n\n        case MODFlags.shared_ | MODFlags.const_:\n            scto = mto;\n            t.scto = this;\n            break;\n\n        case MODFlags.shared_ | MODFlags.wild:\n            swto = mto;\n            t.swto = this;\n            break;\n\n        case MODFlags.shared_ | MODFlags.wildconst:\n            swcto = mto;\n            t.swcto = this;\n            break;\n\n        case MODFlags.immutable_:\n            t.ito = this;\n            if (t.cto)\n                t.cto.ito = this;\n            if (t.sto)\n                t.sto.ito = this;\n            if (t.scto)\n                t.scto.ito = this;\n            if (t.wto)\n                t.wto.ito = this;\n            if (t.wcto)\n                t.wcto.ito = this;\n            if (t.swto)\n                t.swto.ito = this;\n            if (t.swcto)\n                t.swcto.ito = this;\n            break;\n\n        default:\n            assert(0);\n        }\n\n        check();\n        t.check();\n        //printf(\"fixTo: %s, %s\\n\", toChars(), t.toChars());\n    }\n\n    /***************************\n     * Look for bugs in constructing types.\n     */\n    final void check()\n    {\n        switch (mod)\n        {\n        case 0:\n            if (cto)\n                assert(cto.mod == MODFlags.const_);\n            if (ito)\n                assert(ito.mod == MODFlags.immutable_);\n            if (sto)\n                assert(sto.mod == MODFlags.shared_);\n            if (scto)\n                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));\n            if (wto)\n                assert(wto.mod == MODFlags.wild);\n            if (wcto)\n                assert(wcto.mod == MODFlags.wildconst);\n            if (swto)\n                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));\n            if (swcto)\n                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));\n            break;\n\n        case MODFlags.const_:\n            if (cto)\n                assert(cto.mod == 0);\n            if (ito)\n                assert(ito.mod == MODFlags.immutable_);\n            if (sto)\n                assert(sto.mod == MODFlags.shared_);\n            if (scto)\n                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));\n            if (wto)\n                assert(wto.mod == MODFlags.wild);\n            if (wcto)\n                assert(wcto.mod == MODFlags.wildconst);\n            if (swto)\n                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));\n            if (swcto)\n                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));\n            break;\n\n        case MODFlags.wild:\n            if (cto)\n                assert(cto.mod == MODFlags.const_);\n            if (ito)\n                assert(ito.mod == MODFlags.immutable_);\n            if (sto)\n                assert(sto.mod == MODFlags.shared_);\n            if (scto)\n                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));\n            if (wto)\n                assert(wto.mod == 0);\n            if (wcto)\n                assert(wcto.mod == MODFlags.wildconst);\n            if (swto)\n                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));\n            if (swcto)\n                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));\n            break;\n\n        case MODFlags.wildconst:\n            assert(!cto || cto.mod == MODFlags.const_);\n            assert(!ito || ito.mod == MODFlags.immutable_);\n            assert(!sto || sto.mod == MODFlags.shared_);\n            assert(!scto || scto.mod == (MODFlags.shared_ | MODFlags.const_));\n            assert(!wto || wto.mod == MODFlags.wild);\n            assert(!wcto || wcto.mod == 0);\n            assert(!swto || swto.mod == (MODFlags.shared_ | MODFlags.wild));\n            assert(!swcto || swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));\n            break;\n\n        case MODFlags.shared_:\n            if (cto)\n                assert(cto.mod == MODFlags.const_);\n            if (ito)\n                assert(ito.mod == MODFlags.immutable_);\n            if (sto)\n                assert(sto.mod == 0);\n            if (scto)\n                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));\n            if (wto)\n                assert(wto.mod == MODFlags.wild);\n            if (wcto)\n                assert(wcto.mod == MODFlags.wildconst);\n            if (swto)\n                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));\n            if (swcto)\n                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));\n            break;\n\n        case MODFlags.shared_ | MODFlags.const_:\n            if (cto)\n                assert(cto.mod == MODFlags.const_);\n            if (ito)\n                assert(ito.mod == MODFlags.immutable_);\n            if (sto)\n                assert(sto.mod == MODFlags.shared_);\n            if (scto)\n                assert(scto.mod == 0);\n            if (wto)\n                assert(wto.mod == MODFlags.wild);\n            if (wcto)\n                assert(wcto.mod == MODFlags.wildconst);\n            if (swto)\n                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));\n            if (swcto)\n                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));\n            break;\n\n        case MODFlags.shared_ | MODFlags.wild:\n            if (cto)\n                assert(cto.mod == MODFlags.const_);\n            if (ito)\n                assert(ito.mod == MODFlags.immutable_);\n            if (sto)\n                assert(sto.mod == MODFlags.shared_);\n            if (scto)\n                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));\n            if (wto)\n                assert(wto.mod == MODFlags.wild);\n            if (wcto)\n                assert(wcto.mod == MODFlags.wildconst);\n            if (swto)\n                assert(swto.mod == 0);\n            if (swcto)\n                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));\n            break;\n\n        case MODFlags.shared_ | MODFlags.wildconst:\n            assert(!cto || cto.mod == MODFlags.const_);\n            assert(!ito || ito.mod == MODFlags.immutable_);\n            assert(!sto || sto.mod == MODFlags.shared_);\n            assert(!scto || scto.mod == (MODFlags.shared_ | MODFlags.const_));\n            assert(!wto || wto.mod == MODFlags.wild);\n            assert(!wcto || wcto.mod == MODFlags.wildconst);\n            assert(!swto || swto.mod == (MODFlags.shared_ | MODFlags.wild));\n            assert(!swcto || swcto.mod == 0);\n            break;\n\n        case MODFlags.immutable_:\n            if (cto)\n                assert(cto.mod == MODFlags.const_);\n            if (ito)\n                assert(ito.mod == 0);\n            if (sto)\n                assert(sto.mod == MODFlags.shared_);\n            if (scto)\n                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));\n            if (wto)\n                assert(wto.mod == MODFlags.wild);\n            if (wcto)\n                assert(wcto.mod == MODFlags.wildconst);\n            if (swto)\n                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));\n            if (swcto)\n                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));\n            break;\n\n        default:\n            assert(0);\n        }\n\n        Type tn = nextOf();\n        if (tn && ty != Tfunction && tn.ty != Tfunction && ty != Tenum)\n        {\n            // Verify transitivity\n            switch (mod)\n            {\n            case 0:\n            case MODFlags.const_:\n            case MODFlags.wild:\n            case MODFlags.wildconst:\n            case MODFlags.shared_:\n            case MODFlags.shared_ | MODFlags.const_:\n            case MODFlags.shared_ | MODFlags.wild:\n            case MODFlags.shared_ | MODFlags.wildconst:\n            case MODFlags.immutable_:\n                assert(tn.mod == MODFlags.immutable_ || (tn.mod & mod) == mod);\n                break;\n\n            default:\n                assert(0);\n            }\n            tn.check();\n        }\n    }\n\n    /*************************************\n     * Apply STCxxxx bits to existing type.\n     * Use *before* semantic analysis is run.\n     */\n    final Type addSTC(StorageClass stc)\n    {\n        Type t = this;\n        if (t.isImmutable())\n        {\n        }\n        else if (stc & STC.immutable_)\n        {\n            t = t.makeImmutable();\n        }\n        else\n        {\n            if ((stc & STC.shared_) && !t.isShared())\n            {\n                if (t.isWild())\n                {\n                    if (t.isConst())\n                        t = t.makeSharedWildConst();\n                    else\n                        t = t.makeSharedWild();\n                }\n                else\n                {\n                    if (t.isConst())\n                        t = t.makeSharedConst();\n                    else\n                        t = t.makeShared();\n                }\n            }\n            if ((stc & STC.const_) && !t.isConst())\n            {\n                if (t.isShared())\n                {\n                    if (t.isWild())\n                        t = t.makeSharedWildConst();\n                    else\n                        t = t.makeSharedConst();\n                }\n                else\n                {\n                    if (t.isWild())\n                        t = t.makeWildConst();\n                    else\n                        t = t.makeConst();\n                }\n            }\n            if ((stc & STC.wild) && !t.isWild())\n            {\n                if (t.isShared())\n                {\n                    if (t.isConst())\n                        t = t.makeSharedWildConst();\n                    else\n                        t = t.makeSharedWild();\n                }\n                else\n                {\n                    if (t.isConst())\n                        t = t.makeWildConst();\n                    else\n                        t = t.makeWild();\n                }\n            }\n        }\n        return t;\n    }\n\n    /************************************\n     * Apply MODxxxx bits to existing type.\n     */\n    final Type castMod(MOD mod)\n    {\n        Type t;\n        switch (mod)\n        {\n        case 0:\n            t = unSharedOf().mutableOf();\n            break;\n\n        case MODFlags.const_:\n            t = unSharedOf().constOf();\n            break;\n\n        case MODFlags.wild:\n            t = unSharedOf().wildOf();\n            break;\n\n        case MODFlags.wildconst:\n            t = unSharedOf().wildConstOf();\n            break;\n\n        case MODFlags.shared_:\n            t = mutableOf().sharedOf();\n            break;\n\n        case MODFlags.shared_ | MODFlags.const_:\n            t = sharedConstOf();\n            break;\n\n        case MODFlags.shared_ | MODFlags.wild:\n            t = sharedWildOf();\n            break;\n\n        case MODFlags.shared_ | MODFlags.wildconst:\n            t = sharedWildConstOf();\n            break;\n\n        case MODFlags.immutable_:\n            t = immutableOf();\n            break;\n\n        default:\n            assert(0);\n        }\n        return t;\n    }\n\n    /************************************\n     * Add MODxxxx bits to existing type.\n     * We're adding, not replacing, so adding const to\n     * a shared type => \"shared const\"\n     */\n    final Type addMod(MOD mod)\n    {\n        /* Add anything to immutable, and it remains immutable\n         */\n        Type t = this;\n        if (!t.isImmutable())\n        {\n            //printf(\"addMod(%x) %s\\n\", mod, toChars());\n            switch (mod)\n            {\n            case 0:\n                break;\n\n            case MODFlags.const_:\n                if (isShared())\n                {\n                    if (isWild())\n                        t = sharedWildConstOf();\n                    else\n                        t = sharedConstOf();\n                }\n                else\n                {\n                    if (isWild())\n                        t = wildConstOf();\n                    else\n                        t = constOf();\n                }\n                break;\n\n            case MODFlags.wild:\n                if (isShared())\n                {\n                    if (isConst())\n                        t = sharedWildConstOf();\n                    else\n                        t = sharedWildOf();\n                }\n                else\n                {\n                    if (isConst())\n                        t = wildConstOf();\n                    else\n                        t = wildOf();\n                }\n                break;\n\n            case MODFlags.wildconst:\n                if (isShared())\n                    t = sharedWildConstOf();\n                else\n                    t = wildConstOf();\n                break;\n\n            case MODFlags.shared_:\n                if (isWild())\n                {\n                    if (isConst())\n                        t = sharedWildConstOf();\n                    else\n                        t = sharedWildOf();\n                }\n                else\n                {\n                    if (isConst())\n                        t = sharedConstOf();\n                    else\n                        t = sharedOf();\n                }\n                break;\n\n            case MODFlags.shared_ | MODFlags.const_:\n                if (isWild())\n                    t = sharedWildConstOf();\n                else\n                    t = sharedConstOf();\n                break;\n\n            case MODFlags.shared_ | MODFlags.wild:\n                if (isConst())\n                    t = sharedWildConstOf();\n                else\n                    t = sharedWildOf();\n                break;\n\n            case MODFlags.shared_ | MODFlags.wildconst:\n                t = sharedWildConstOf();\n                break;\n\n            case MODFlags.immutable_:\n                t = immutableOf();\n                break;\n\n            default:\n                assert(0);\n            }\n        }\n        return t;\n    }\n\n    /************************************\n     * Add storage class modifiers to type.\n     */\n    Type addStorageClass(StorageClass stc)\n    {\n        /* Just translate to MOD bits and let addMod() do the work\n         */\n        MOD mod = 0;\n        if (stc & STC.immutable_)\n            mod = MODFlags.immutable_;\n        else\n        {\n            if (stc & (STC.const_ | STC.in_))\n                mod |= MODFlags.const_;\n            if (stc & STC.wild)\n                mod |= MODFlags.wild;\n            if (stc & STC.shared_)\n                mod |= MODFlags.shared_;\n        }\n        return addMod(mod);\n    }\n\n    final Type pointerTo()\n    {\n        if (ty == Terror)\n            return this;\n        if (!pto)\n        {\n            Type t = new TypePointer(this);\n            if (ty == Tfunction)\n            {\n                t.deco = t.merge().deco;\n                pto = t;\n            }\n            else\n                pto = t.merge();\n        }\n        return pto;\n    }\n\n    final Type referenceTo()\n    {\n        if (ty == Terror)\n            return this;\n        if (!rto)\n        {\n            Type t = new TypeReference(this);\n            rto = t.merge();\n        }\n        return rto;\n    }\n\n    final Type arrayOf()\n    {\n        if (ty == Terror)\n            return this;\n        if (!arrayof)\n        {\n            Type t = new TypeDArray(this);\n            arrayof = t.merge();\n        }\n        return arrayof;\n    }\n\n    // Make corresponding static array type without semantic\n    final Type sarrayOf(dinteger_t dim)\n    {\n        assert(deco);\n        Type t = new TypeSArray(this, new IntegerExp(Loc.initial, dim, Type.tsize_t));\n        // according to TypeSArray::semantic()\n        t = t.addMod(mod);\n        t = t.merge();\n        return t;\n    }\n\n    final Type aliasthisOf()\n    {\n        auto ad = isAggregate(this);\n        if (!ad || !ad.aliasthis)\n            return null;\n\n        auto s = ad.aliasthis;\n        if (s.isAliasDeclaration())\n            s = s.toAlias();\n\n        if (s.isTupleDeclaration())\n            return null;\n\n        if (auto vd = s.isVarDeclaration())\n        {\n            auto t = vd.type;\n            if (vd.needThis())\n                t = t.addMod(this.mod);\n            return t;\n        }\n        if (auto fd = s.isFuncDeclaration())\n        {\n            fd = resolveFuncCall(Loc.initial, null, fd, null, this, null, 1);\n            if (!fd || fd.errors || !fd.functionSemantic())\n                return Type.terror;\n\n            auto t = fd.type.nextOf();\n            if (!t) // issue 14185\n                return Type.terror;\n            t = t.substWildTo(mod == 0 ? MODFlags.mutable : mod);\n            return t;\n        }\n        if (auto d = s.isDeclaration())\n        {\n            assert(d.type);\n            return d.type;\n        }\n        if (auto ed = s.isEnumDeclaration())\n        {\n            return ed.type;\n        }\n        if (auto td = s.isTemplateDeclaration())\n        {\n            assert(td._scope);\n            auto fd = resolveFuncCall(Loc.initial, null, td, null, this, null, 1);\n            if (!fd || fd.errors || !fd.functionSemantic())\n                return Type.terror;\n\n            auto t = fd.type.nextOf();\n            if (!t)\n                return Type.terror;\n            t = t.substWildTo(mod == 0 ? MODFlags.mutable : mod);\n            return t;\n        }\n\n        //printf(\"%s\\n\", s.kind());\n        return null;\n    }\n\n    extern (D) final bool checkAliasThisRec()\n    {\n        Type tb = toBasetype();\n        AliasThisRec* pflag;\n        if (tb.ty == Tstruct)\n            pflag = &(cast(TypeStruct)tb).att;\n        else if (tb.ty == Tclass)\n            pflag = &(cast(TypeClass)tb).att;\n        else\n            return false;\n\n        AliasThisRec flag = cast(AliasThisRec)(*pflag & AliasThisRec.typeMask);\n        if (flag == AliasThisRec.fwdref)\n        {\n            Type att = aliasthisOf();\n            flag = att && att.implicitConvTo(this) ? AliasThisRec.yes : AliasThisRec.no;\n        }\n        *pflag = cast(AliasThisRec)(flag | (*pflag & ~AliasThisRec.typeMask));\n        return flag == AliasThisRec.yes;\n    }\n\n    Type makeConst()\n    {\n        //printf(\"Type::makeConst() %p, %s\\n\", this, toChars());\n        if (cto)\n            return cto;\n        Type t = this.nullAttributes();\n        t.mod = MODFlags.const_;\n        //printf(\"-Type::makeConst() %p, %s\\n\", t, toChars());\n        return t;\n    }\n\n    Type makeImmutable()\n    {\n        if (ito)\n            return ito;\n        Type t = this.nullAttributes();\n        t.mod = MODFlags.immutable_;\n        return t;\n    }\n\n    Type makeShared()\n    {\n        if (sto)\n            return sto;\n        Type t = this.nullAttributes();\n        t.mod = MODFlags.shared_;\n        return t;\n    }\n\n    Type makeSharedConst()\n    {\n        if (scto)\n            return scto;\n        Type t = this.nullAttributes();\n        t.mod = MODFlags.shared_ | MODFlags.const_;\n        return t;\n    }\n\n    Type makeWild()\n    {\n        if (wto)\n            return wto;\n        Type t = this.nullAttributes();\n        t.mod = MODFlags.wild;\n        return t;\n    }\n\n    Type makeWildConst()\n    {\n        if (wcto)\n            return wcto;\n        Type t = this.nullAttributes();\n        t.mod = MODFlags.wildconst;\n        return t;\n    }\n\n    Type makeSharedWild()\n    {\n        if (swto)\n            return swto;\n        Type t = this.nullAttributes();\n        t.mod = MODFlags.shared_ | MODFlags.wild;\n        return t;\n    }\n\n    Type makeSharedWildConst()\n    {\n        if (swcto)\n            return swcto;\n        Type t = this.nullAttributes();\n        t.mod = MODFlags.shared_ | MODFlags.wildconst;\n        return t;\n    }\n\n    Type makeMutable()\n    {\n        Type t = this.nullAttributes();\n        t.mod = mod & MODFlags.shared_;\n        return t;\n    }\n\n    Dsymbol toDsymbol(Scope* sc)\n    {\n        return null;\n    }\n\n    /*******************************\n     * If this is a shell around another type,\n     * get that other type.\n     */\n    Type toBasetype()\n    {\n        return this;\n    }\n\n    bool isBaseOf(Type t, int* poffset)\n    {\n        return 0; // assume not\n    }\n\n    /********************************\n     * Determine if 'this' can be implicitly converted\n     * to type 'to'.\n     * Returns:\n     *      MATCH.nomatch, MATCH.convert, MATCH.constant, MATCH.exact\n     */\n    MATCH implicitConvTo(Type to)\n    {\n        //printf(\"Type::implicitConvTo(this=%p, to=%p)\\n\", this, to);\n        //printf(\"from: %s\\n\", toChars());\n        //printf(\"to  : %s\\n\", to.toChars());\n        if (this.equals(to))\n            return MATCH.exact;\n        return MATCH.nomatch;\n    }\n\n    /*******************************\n     * Determine if converting 'this' to 'to' is an identity operation,\n     * a conversion to const operation, or the types aren't the same.\n     * Returns:\n     *      MATCH.exact      'this' == 'to'\n     *      MATCH.constant      'to' is const\n     *      MATCH.nomatch    conversion to mutable or invariant\n     */\n    MATCH constConv(Type to)\n    {\n        //printf(\"Type::constConv(this = %s, to = %s)\\n\", toChars(), to.toChars());\n        if (equals(to))\n            return MATCH.exact;\n        if (ty == to.ty && MODimplicitConv(mod, to.mod))\n            return MATCH.constant;\n        return MATCH.nomatch;\n    }\n\n    /***************************************\n     * Compute MOD bits matching `this` argument type to wild parameter type.\n     * Params:\n     *  t = corresponding parameter type\n     *  isRef = parameter is `ref` or `out`\n     * Returns:\n     *  MOD bits\n     */\n    MOD deduceWild(Type t, bool isRef)\n    {\n        //printf(\"Type::deduceWild this = '%s', tprm = '%s'\\n\", toChars(), tprm.toChars());\n        if (t.isWild())\n        {\n            if (isImmutable())\n                return MODFlags.immutable_;\n            else if (isWildConst())\n            {\n                if (t.isWildConst())\n                    return MODFlags.wild;\n                else\n                    return MODFlags.wildconst;\n            }\n            else if (isWild())\n                return MODFlags.wild;\n            else if (isConst())\n                return MODFlags.const_;\n            else if (isMutable())\n                return MODFlags.mutable;\n            else\n                assert(0);\n        }\n        return 0;\n    }\n\n    Type substWildTo(uint mod)\n    {\n        //printf(\"+Type::substWildTo this = %s, mod = x%x\\n\", toChars(), mod);\n        Type t;\n\n        if (Type tn = nextOf())\n        {\n            // substitution has no effect on function pointer type.\n            if (ty == Tpointer && tn.ty == Tfunction)\n            {\n                t = this;\n                goto L1;\n            }\n\n            t = tn.substWildTo(mod);\n            if (t == tn)\n                t = this;\n            else\n            {\n                if (ty == Tpointer)\n                    t = t.pointerTo();\n                else if (ty == Tarray)\n                    t = t.arrayOf();\n                else if (ty == Tsarray)\n                    t = new TypeSArray(t, (cast(TypeSArray)this).dim.syntaxCopy());\n                else if (ty == Taarray)\n                {\n                    t = new TypeAArray(t, (cast(TypeAArray)this).index.syntaxCopy());\n                    (cast(TypeAArray)t).sc = (cast(TypeAArray)this).sc; // duplicate scope\n                }\n                else if (ty == Tdelegate)\n                {\n                    t = new TypeDelegate(t);\n                }\n                else\n                    assert(0);\n\n                t = t.merge();\n            }\n        }\n        else\n            t = this;\n\n    L1:\n        if (isWild())\n        {\n            if (mod == MODFlags.immutable_)\n            {\n                t = t.immutableOf();\n            }\n            else if (mod == MODFlags.wildconst)\n            {\n                t = t.wildConstOf();\n            }\n            else if (mod == MODFlags.wild)\n            {\n                if (isWildConst())\n                    t = t.wildConstOf();\n                else\n                    t = t.wildOf();\n            }\n            else if (mod == MODFlags.const_)\n            {\n                t = t.constOf();\n            }\n            else\n            {\n                if (isWildConst())\n                    t = t.constOf();\n                else\n                    t = t.mutableOf();\n            }\n        }\n        if (isConst())\n            t = t.addMod(MODFlags.const_);\n        if (isShared())\n            t = t.addMod(MODFlags.shared_);\n\n        //printf(\"-Type::substWildTo t = %s\\n\", t.toChars());\n        return t;\n    }\n\n    final Type unqualify(uint m)\n    {\n        Type t = mutableOf().unSharedOf();\n\n        Type tn = ty == Tenum ? null : nextOf();\n        if (tn && tn.ty != Tfunction)\n        {\n            Type utn = tn.unqualify(m);\n            if (utn != tn)\n            {\n                if (ty == Tpointer)\n                    t = utn.pointerTo();\n                else if (ty == Tarray)\n                    t = utn.arrayOf();\n                else if (ty == Tsarray)\n                    t = new TypeSArray(utn, (cast(TypeSArray)this).dim);\n                else if (ty == Taarray)\n                {\n                    t = new TypeAArray(utn, (cast(TypeAArray)this).index);\n                    (cast(TypeAArray)t).sc = (cast(TypeAArray)this).sc; // duplicate scope\n                }\n                else\n                    assert(0);\n\n                t = t.merge();\n            }\n        }\n        t = t.addMod(mod & ~m);\n        return t;\n    }\n\n    /**************************\n     * Return type with the top level of it being mutable.\n     */\n    Type toHeadMutable()\n    {\n        if (!mod)\n            return this;\n        return mutableOf();\n    }\n\n    inout(ClassDeclaration) isClassHandle() inout\n    {\n        return null;\n    }\n\n    /************************************\n     * Return alignment to use for this type.\n     */\n    structalign_t alignment()\n    {\n        return STRUCTALIGN_DEFAULT;\n    }\n\n    /***************************************\n     * Use when we prefer the default initializer to be a literal,\n     * rather than a global immutable variable.\n     */\n    Expression defaultInitLiteral(const ref Loc loc)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"Type::defaultInitLiteral() '%s'\\n\", toChars());\n        }\n        return defaultInit(this, loc);\n    }\n\n    // if initializer is 0\n    bool isZeroInit(const ref Loc loc)\n    {\n        return false; // assume not\n    }\n\n    final Identifier getTypeInfoIdent()\n    {\n        // _init_10TypeInfo_%s\n        OutBuffer buf;\n        buf.reserve(32);\n        mangleToBuffer(this, &buf);\n\n        const slice = buf.peekSlice();\n\n        // Allocate buffer on stack, fail over to using malloc()\n        char[128] namebuf;\n        const namelen = 19 + size_t.sizeof * 3 + slice.length + 1;\n        auto name = namelen <= namebuf.length ? namebuf.ptr : cast(char*)malloc(namelen);\n        assert(name);\n\n        const length = sprintf(name, \"_D%lluTypeInfo_%.*s6__initZ\",\n                cast(ulong)(9 + slice.length), cast(int)slice.length, slice.ptr);\n        //printf(\"%p %s, deco = %s, name = %s\\n\", this, toChars(), deco, name);\n        assert(0 < length && length < namelen); // don't overflow the buffer\n\n        auto id = Identifier.idPool(name, length);\n\n        if (name != namebuf.ptr)\n            free(name);\n        return id;\n    }\n\n    /***************************************\n     * Normalize `e` as the result of Type.resolve() process.\n     */\n    final void resolveExp(Expression e, Type *pt, Expression *pe, Dsymbol* ps)\n    {\n        *pt = null;\n        *pe = null;\n        *ps = null;\n\n        Dsymbol s;\n        switch (e.op)\n        {\n            case TOK.error:\n                *pt = Type.terror;\n                return;\n\n            case TOK.type:\n                *pt = e.type;\n                return;\n\n            case TOK.variable:\n                s = (cast(VarExp)e).var;\n                if (s.isVarDeclaration())\n                    goto default;\n                //if (s.isOverDeclaration())\n                //    todo;\n                break;\n\n            case TOK.template_:\n                // TemplateDeclaration\n                s = (cast(TemplateExp)e).td;\n                break;\n\n            case TOK.scope_:\n                s = (cast(ScopeExp)e).sds;\n                // TemplateDeclaration, TemplateInstance, Import, Package, Module\n                break;\n\n            case TOK.function_:\n                s = getDsymbol(e);\n                break;\n\n            case TOK.dotTemplateDeclaration:\n                s = (cast(DotTemplateExp)e).td;\n                break;\n\n            //case TOK.this_:\n            //case TOK.super_:\n\n            //case TOK.tuple:\n\n            //case TOK.overloadSet:\n\n            //case TOK.dotVariable:\n            //case TOK.dotTemplateInstance:\n            //case TOK.dotType:\n            //case TOK.dotIdentifier:\n\n            default:\n                *pe = e;\n                return;\n        }\n\n        *ps = s;\n    }\n\n    /***************************************\n     * Return !=0 if the type or any of its subtypes is wild.\n     */\n    int hasWild() const\n    {\n        return mod & MODFlags.wild;\n    }\n\n    /***************************************\n     * Return !=0 if type has pointers that need to\n     * be scanned by the GC during a collection cycle.\n     */\n    bool hasPointers()\n    {\n        //printf(\"Type::hasPointers() %s, %d\\n\", toChars(), ty);\n        return false;\n    }\n\n    /*************************************\n     * Detect if type has pointer fields that are initialized to void.\n     * Local stack variables with such void fields can remain uninitialized,\n     * leading to pointer bugs.\n     * Returns:\n     *  true if so\n     */\n    bool hasVoidInitPointers()\n    {\n        return false;\n    }\n\n    /*************************************\n     * If this is a type of something, return that something.\n     */\n    Type nextOf()\n    {\n        return null;\n    }\n\n    /*************************************\n     * If this is a type of static array, return its base element type.\n     */\n    final Type baseElemOf()\n    {\n        Type t = toBasetype();\n        while (t.ty == Tsarray)\n            t = (cast(TypeSArray)t).next.toBasetype();\n        return t;\n    }\n\n    /*******************************************\n     * Compute number of elements for a (possibly multidimensional) static array,\n     * or 1 for other types.\n     * Params:\n     *  loc = for error message\n     * Returns:\n     *  number of elements, uint.max on overflow\n     */\n    final uint numberOfElems(const ref Loc loc)\n    {\n        //printf(\"Type::numberOfElems()\\n\");\n        uinteger_t n = 1;\n        Type tb = this;\n        while ((tb = tb.toBasetype()).ty == Tsarray)\n        {\n            bool overflow = false;\n            n = mulu(n, (cast(TypeSArray)tb).dim.toUInteger(), overflow);\n            if (overflow || n >= uint.max)\n            {\n                error(loc, \"static array `%s` size overflowed to %llu\", toChars(), cast(ulong)n);\n                return uint.max;\n            }\n            tb = (cast(TypeSArray)tb).next;\n        }\n        return cast(uint)n;\n    }\n\n    /****************************************\n     * Return the mask that an integral type will\n     * fit into.\n     */\n    final uinteger_t sizemask()\n    {\n        uinteger_t m;\n        switch (toBasetype().ty)\n        {\n        case Tbool:\n            m = 1;\n            break;\n        case Tchar:\n        case Tint8:\n        case Tuns8:\n            m = 0xFF;\n            break;\n        case Twchar:\n        case Tint16:\n        case Tuns16:\n            m = 0xFFFFU;\n            break;\n        case Tdchar:\n        case Tint32:\n        case Tuns32:\n            m = 0xFFFFFFFFU;\n            break;\n        case Tint64:\n        case Tuns64:\n            m = 0xFFFFFFFFFFFFFFFFUL;\n            break;\n        default:\n            assert(0);\n        }\n        return m;\n    }\n\n    /********************************\n     * true if when type goes out of scope, it needs a destructor applied.\n     * Only applies to value types, not ref types.\n     */\n    bool needsDestruction()\n    {\n        return false;\n    }\n\n    /*********************************\n     *\n     */\n    bool needsNested()\n    {\n        return false;\n    }\n\n    /*************************************\n     * https://issues.dlang.org/show_bug.cgi?id=14488\n     * Check if the inner most base type is complex or imaginary.\n     * Should only give alerts when set to emit transitional messages.\n     * Params:\n     *  loc = The source location.\n     *  sc = scope of the type\n     */\n    extern (D) final bool checkComplexTransition(const ref Loc loc, Scope* sc)\n    {\n        if (sc.isDeprecated())\n            return false;\n\n        Type t = baseElemOf();\n        while (t.ty == Tpointer || t.ty == Tarray)\n            t = t.nextOf().baseElemOf();\n\n        // Basetype is an opaque enum, nothing to check.\n        if (t.ty == Tenum && !(cast(TypeEnum)t).sym.memtype)\n            return false;\n\n        if (t.isimaginary() || t.iscomplex())\n        {\n            Type rt;\n            switch (t.ty)\n            {\n            case Tcomplex32:\n            case Timaginary32:\n                rt = Type.tfloat32;\n                break;\n\n            case Tcomplex64:\n            case Timaginary64:\n                rt = Type.tfloat64;\n                break;\n\n            case Tcomplex80:\n            case Timaginary80:\n                rt = Type.tfloat80;\n                break;\n\n            default:\n                assert(0);\n            }\n            if (t.iscomplex())\n            {\n                deprecation(loc, \"use of complex type `%s` is deprecated, use `std.complex.Complex!(%s)` instead\",\n                    toChars(), rt.toChars());\n                return true;\n            }\n            else\n            {\n                deprecation(loc, \"use of imaginary type `%s` is deprecated, use `%s` instead\",\n                    toChars(), rt.toChars());\n                return true;\n            }\n        }\n        return false;\n    }\n\n    // For eliminating dynamic_cast\n    TypeBasic isTypeBasic()\n    {\n        return null;\n    }\n\n    void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    final TypeFunction toTypeFunction()\n    {\n        if (ty != Tfunction)\n            assert(0);\n        return cast(TypeFunction)this;\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeError : Type\n{\n    extern (D) this()\n    {\n        super(Terror);\n    }\n\n    override Type syntaxCopy()\n    {\n        // No semantic analysis done, no need to copy\n        return this;\n    }\n\n    override d_uns64 size(const ref Loc loc)\n    {\n        return SIZE_INVALID;\n    }\n\n    override Expression defaultInitLiteral(const ref Loc loc)\n    {\n        return new ErrorExp();\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) abstract class TypeNext : Type\n{\n    Type next;\n\n    final extern (D) this(TY ty, Type next)\n    {\n        super(ty);\n        this.next = next;\n    }\n\n    override final void checkDeprecated(const ref Loc loc, Scope* sc)\n    {\n        Type.checkDeprecated(loc, sc);\n        if (next) // next can be NULL if TypeFunction and auto return type\n            next.checkDeprecated(loc, sc);\n    }\n\n    override final int hasWild() const\n    {\n        if (ty == Tfunction)\n            return 0;\n        if (ty == Tdelegate)\n            return Type.hasWild();\n        return mod & MODFlags.wild || (next && next.hasWild());\n    }\n\n    /*******************************\n     * For TypeFunction, nextOf() can return NULL if the function return\n     * type is meant to be inferred, and semantic() hasn't yet ben run\n     * on the function. After semantic(), it must no longer be NULL.\n     */\n    override final Type nextOf()\n    {\n        return next;\n    }\n\n    override final Type makeConst()\n    {\n        //printf(\"TypeNext::makeConst() %p, %s\\n\", this, toChars());\n        if (cto)\n        {\n            assert(cto.mod == MODFlags.const_);\n            return cto;\n        }\n        TypeNext t = cast(TypeNext)Type.makeConst();\n        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())\n        {\n            if (next.isShared())\n            {\n                if (next.isWild())\n                    t.next = next.sharedWildConstOf();\n                else\n                    t.next = next.sharedConstOf();\n            }\n            else\n            {\n                if (next.isWild())\n                    t.next = next.wildConstOf();\n                else\n                    t.next = next.constOf();\n            }\n        }\n        //printf(\"TypeNext::makeConst() returns %p, %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    override final Type makeImmutable()\n    {\n        //printf(\"TypeNext::makeImmutable() %s\\n\", toChars());\n        if (ito)\n        {\n            assert(ito.isImmutable());\n            return ito;\n        }\n        TypeNext t = cast(TypeNext)Type.makeImmutable();\n        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())\n        {\n            t.next = next.immutableOf();\n        }\n        return t;\n    }\n\n    override final Type makeShared()\n    {\n        //printf(\"TypeNext::makeShared() %s\\n\", toChars());\n        if (sto)\n        {\n            assert(sto.mod == MODFlags.shared_);\n            return sto;\n        }\n        TypeNext t = cast(TypeNext)Type.makeShared();\n        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())\n        {\n            if (next.isWild())\n            {\n                if (next.isConst())\n                    t.next = next.sharedWildConstOf();\n                else\n                    t.next = next.sharedWildOf();\n            }\n            else\n            {\n                if (next.isConst())\n                    t.next = next.sharedConstOf();\n                else\n                    t.next = next.sharedOf();\n            }\n        }\n        //printf(\"TypeNext::makeShared() returns %p, %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    override final Type makeSharedConst()\n    {\n        //printf(\"TypeNext::makeSharedConst() %s\\n\", toChars());\n        if (scto)\n        {\n            assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));\n            return scto;\n        }\n        TypeNext t = cast(TypeNext)Type.makeSharedConst();\n        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())\n        {\n            if (next.isWild())\n                t.next = next.sharedWildConstOf();\n            else\n                t.next = next.sharedConstOf();\n        }\n        //printf(\"TypeNext::makeSharedConst() returns %p, %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    override final Type makeWild()\n    {\n        //printf(\"TypeNext::makeWild() %s\\n\", toChars());\n        if (wto)\n        {\n            assert(wto.mod == MODFlags.wild);\n            return wto;\n        }\n        TypeNext t = cast(TypeNext)Type.makeWild();\n        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())\n        {\n            if (next.isShared())\n            {\n                if (next.isConst())\n                    t.next = next.sharedWildConstOf();\n                else\n                    t.next = next.sharedWildOf();\n            }\n            else\n            {\n                if (next.isConst())\n                    t.next = next.wildConstOf();\n                else\n                    t.next = next.wildOf();\n            }\n        }\n        //printf(\"TypeNext::makeWild() returns %p, %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    override final Type makeWildConst()\n    {\n        //printf(\"TypeNext::makeWildConst() %s\\n\", toChars());\n        if (wcto)\n        {\n            assert(wcto.mod == MODFlags.wildconst);\n            return wcto;\n        }\n        TypeNext t = cast(TypeNext)Type.makeWildConst();\n        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())\n        {\n            if (next.isShared())\n                t.next = next.sharedWildConstOf();\n            else\n                t.next = next.wildConstOf();\n        }\n        //printf(\"TypeNext::makeWildConst() returns %p, %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    override final Type makeSharedWild()\n    {\n        //printf(\"TypeNext::makeSharedWild() %s\\n\", toChars());\n        if (swto)\n        {\n            assert(swto.isSharedWild());\n            return swto;\n        }\n        TypeNext t = cast(TypeNext)Type.makeSharedWild();\n        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())\n        {\n            if (next.isConst())\n                t.next = next.sharedWildConstOf();\n            else\n                t.next = next.sharedWildOf();\n        }\n        //printf(\"TypeNext::makeSharedWild() returns %p, %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    override final Type makeSharedWildConst()\n    {\n        //printf(\"TypeNext::makeSharedWildConst() %s\\n\", toChars());\n        if (swcto)\n        {\n            assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));\n            return swcto;\n        }\n        TypeNext t = cast(TypeNext)Type.makeSharedWildConst();\n        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())\n        {\n            t.next = next.sharedWildConstOf();\n        }\n        //printf(\"TypeNext::makeSharedWildConst() returns %p, %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    override final Type makeMutable()\n    {\n        //printf(\"TypeNext::makeMutable() %p, %s\\n\", this, toChars());\n        TypeNext t = cast(TypeNext)Type.makeMutable();\n        if (ty == Tsarray)\n        {\n            t.next = next.mutableOf();\n        }\n        //printf(\"TypeNext::makeMutable() returns %p, %s\\n\", t, t.toChars());\n        return t;\n    }\n\n    override MATCH constConv(Type to)\n    {\n        //printf(\"TypeNext::constConv from = %s, to = %s\\n\", toChars(), to.toChars());\n        if (equals(to))\n            return MATCH.exact;\n\n        if (!(ty == to.ty && MODimplicitConv(mod, to.mod)))\n            return MATCH.nomatch;\n\n        Type tn = to.nextOf();\n        if (!(tn && next.ty == tn.ty))\n            return MATCH.nomatch;\n\n        MATCH m;\n        if (to.isConst()) // whole tail const conversion\n        {\n            // Recursive shared level check\n            m = next.constConv(tn);\n            if (m == MATCH.exact)\n                m = MATCH.constant;\n        }\n        else\n        {\n            //printf(\"\\tnext => %s, to.next => %s\\n\", next.toChars(), tn.toChars());\n            m = next.equals(tn) ? MATCH.constant : MATCH.nomatch;\n        }\n        return m;\n    }\n\n    override final MOD deduceWild(Type t, bool isRef)\n    {\n        if (ty == Tfunction)\n            return 0;\n\n        ubyte wm;\n\n        Type tn = t.nextOf();\n        if (!isRef && (ty == Tarray || ty == Tpointer) && tn)\n        {\n            wm = next.deduceWild(tn, true);\n            if (!wm)\n                wm = Type.deduceWild(t, true);\n        }\n        else\n        {\n            wm = Type.deduceWild(t, isRef);\n            if (!wm && tn)\n                wm = next.deduceWild(tn, true);\n        }\n\n        return wm;\n    }\n\n    final void transitive()\n    {\n        /* Invoke transitivity of type attributes\n         */\n        next = next.addMod(mod);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeBasic : Type\n{\n    const(char)* dstring;\n    uint flags;\n\n    extern (D) this(TY ty)\n    {\n        super(ty);\n        const(char)* d;\n        uint flags = 0;\n        switch (ty)\n        {\n        case Tvoid:\n            d = Token.toChars(TOK.void_);\n            break;\n\n        case Tint8:\n            d = Token.toChars(TOK.int8);\n            flags |= TFlags.integral;\n            break;\n\n        case Tuns8:\n            d = Token.toChars(TOK.uns8);\n            flags |= TFlags.integral | TFlags.unsigned;\n            break;\n\n        case Tint16:\n            d = Token.toChars(TOK.int16);\n            flags |= TFlags.integral;\n            break;\n\n        case Tuns16:\n            d = Token.toChars(TOK.uns16);\n            flags |= TFlags.integral | TFlags.unsigned;\n            break;\n\n        case Tint32:\n            d = Token.toChars(TOK.int32);\n            flags |= TFlags.integral;\n            break;\n\n        case Tuns32:\n            d = Token.toChars(TOK.uns32);\n            flags |= TFlags.integral | TFlags.unsigned;\n            break;\n\n        case Tfloat32:\n            d = Token.toChars(TOK.float32);\n            flags |= TFlags.floating | TFlags.real_;\n            break;\n\n        case Tint64:\n            d = Token.toChars(TOK.int64);\n            flags |= TFlags.integral;\n            break;\n\n        case Tuns64:\n            d = Token.toChars(TOK.uns64);\n            flags |= TFlags.integral | TFlags.unsigned;\n            break;\n\n        case Tint128:\n            d = Token.toChars(TOK.int128);\n            flags |= TFlags.integral;\n            break;\n\n        case Tuns128:\n            d = Token.toChars(TOK.uns128);\n            flags |= TFlags.integral | TFlags.unsigned;\n            break;\n\n        case Tfloat64:\n            d = Token.toChars(TOK.float64);\n            flags |= TFlags.floating | TFlags.real_;\n            break;\n\n        case Tfloat80:\n            d = Token.toChars(TOK.float80);\n            flags |= TFlags.floating | TFlags.real_;\n            break;\n\n        case Timaginary32:\n            d = Token.toChars(TOK.imaginary32);\n            flags |= TFlags.floating | TFlags.imaginary;\n            break;\n\n        case Timaginary64:\n            d = Token.toChars(TOK.imaginary64);\n            flags |= TFlags.floating | TFlags.imaginary;\n            break;\n\n        case Timaginary80:\n            d = Token.toChars(TOK.imaginary80);\n            flags |= TFlags.floating | TFlags.imaginary;\n            break;\n\n        case Tcomplex32:\n            d = Token.toChars(TOK.complex32);\n            flags |= TFlags.floating | TFlags.complex;\n            break;\n\n        case Tcomplex64:\n            d = Token.toChars(TOK.complex64);\n            flags |= TFlags.floating | TFlags.complex;\n            break;\n\n        case Tcomplex80:\n            d = Token.toChars(TOK.complex80);\n            flags |= TFlags.floating | TFlags.complex;\n            break;\n\n        case Tbool:\n            d = \"bool\";\n            flags |= TFlags.integral | TFlags.unsigned;\n            break;\n\n        case Tchar:\n            d = Token.toChars(TOK.char_);\n            flags |= TFlags.integral | TFlags.unsigned;\n            break;\n\n        case Twchar:\n            d = Token.toChars(TOK.wchar_);\n            flags |= TFlags.integral | TFlags.unsigned;\n            break;\n\n        case Tdchar:\n            d = Token.toChars(TOK.dchar_);\n            flags |= TFlags.integral | TFlags.unsigned;\n            break;\n\n        default:\n            assert(0);\n        }\n        this.dstring = d;\n        this.flags = flags;\n        merge(this);\n    }\n\n    override const(char)* kind() const\n    {\n        return dstring;\n    }\n\n    override Type syntaxCopy()\n    {\n        // No semantic analysis done on basic types, no need to copy\n        return this;\n    }\n\n    override d_uns64 size(const ref Loc loc) const\n    {\n        uint size;\n        //printf(\"TypeBasic::size()\\n\");\n        switch (ty)\n        {\n        case Tint8:\n        case Tuns8:\n            size = 1;\n            break;\n\n        case Tint16:\n        case Tuns16:\n            size = 2;\n            break;\n\n        case Tint32:\n        case Tuns32:\n        case Tfloat32:\n        case Timaginary32:\n            size = 4;\n            break;\n\n        case Tint64:\n        case Tuns64:\n        case Tfloat64:\n        case Timaginary64:\n            size = 8;\n            break;\n\n        case Tfloat80:\n        case Timaginary80:\n            size = Target.realsize;\n            break;\n\n        case Tcomplex32:\n            size = 8;\n            break;\n\n        case Tcomplex64:\n        case Tint128:\n        case Tuns128:\n            size = 16;\n            break;\n\n        case Tcomplex80:\n            size = Target.realsize * 2;\n            break;\n\n        case Tvoid:\n            //size = Type::size();      // error message\n            size = 1;\n            break;\n\n        case Tbool:\n            size = 1;\n            break;\n\n        case Tchar:\n            size = 1;\n            break;\n\n        case Twchar:\n            size = 2;\n            break;\n\n        case Tdchar:\n            size = 4;\n            break;\n\n        default:\n            assert(0);\n        }\n        //printf(\"TypeBasic::size() = %d\\n\", size);\n        return size;\n    }\n\n    override uint alignsize()\n    {\n        return Target.alignsize(this);\n    }\n\n    override bool isintegral()\n    {\n        //printf(\"TypeBasic::isintegral('%s') x%x\\n\", toChars(), flags);\n        return (flags & TFlags.integral) != 0;\n    }\n\n    override bool isfloating() const\n    {\n        return (flags & TFlags.floating) != 0;\n    }\n\n    override bool isreal() const\n    {\n        return (flags & TFlags.real_) != 0;\n    }\n\n    override bool isimaginary() const\n    {\n        return (flags & TFlags.imaginary) != 0;\n    }\n\n    override bool iscomplex() const\n    {\n        return (flags & TFlags.complex) != 0;\n    }\n\n    override bool isscalar() const\n    {\n        return (flags & (TFlags.integral | TFlags.floating)) != 0;\n    }\n\n    override bool isunsigned() const\n    {\n        return (flags & TFlags.unsigned) != 0;\n    }\n\n    override MATCH implicitConvTo(Type to)\n    {\n        //printf(\"TypeBasic::implicitConvTo(%s) from %s\\n\", to.toChars(), toChars());\n        if (this == to)\n            return MATCH.exact;\n\n        if (ty == to.ty)\n        {\n            if (mod == to.mod)\n                return MATCH.exact;\n            else if (MODimplicitConv(mod, to.mod))\n                return MATCH.constant;\n            else if (!((mod ^ to.mod) & MODFlags.shared_)) // for wild matching\n                return MATCH.constant;\n            else\n                return MATCH.convert;\n        }\n\n        if (ty == Tvoid || to.ty == Tvoid)\n            return MATCH.nomatch;\n        if (to.ty == Tbool)\n            return MATCH.nomatch;\n\n        TypeBasic tob;\n        if (to.ty == Tvector && to.deco)\n        {\n            TypeVector tv = cast(TypeVector)to;\n            tob = tv.elementType();\n        }\n        else if (to.ty == Tenum)\n        {\n            EnumDeclaration ed = (cast(TypeEnum)to).sym;\n            if (ed.isSpecial())\n            {\n                /* Special enums that allow implicit conversions to them.  */\n                tob = to.toBasetype().isTypeBasic();\n                if (tob)\n                    return implicitConvTo(tob);\n            }\n            else\n                return MATCH.nomatch;\n        }\n        else\n            tob = to.isTypeBasic();\n        if (!tob)\n            return MATCH.nomatch;\n\n        if (flags & TFlags.integral)\n        {\n            // Disallow implicit conversion of integers to imaginary or complex\n            if (tob.flags & (TFlags.imaginary | TFlags.complex))\n                return MATCH.nomatch;\n\n            // If converting from integral to integral\n            if (tob.flags & TFlags.integral)\n            {\n                d_uns64 sz = size(Loc.initial);\n                d_uns64 tosz = tob.size(Loc.initial);\n\n                /* Can't convert to smaller size\n                 */\n                if (sz > tosz)\n                    return MATCH.nomatch;\n                /* Can't change sign if same size\n                 */\n                //if (sz == tosz && (flags ^ tob.flags) & TFlags.unsigned)\n                //    return MATCH.nomatch;\n            }\n        }\n        else if (flags & TFlags.floating)\n        {\n            // Disallow implicit conversion of floating point to integer\n            if (tob.flags & TFlags.integral)\n                return MATCH.nomatch;\n\n            assert(tob.flags & TFlags.floating || to.ty == Tvector);\n\n            // Disallow implicit conversion from complex to non-complex\n            if (flags & TFlags.complex && !(tob.flags & TFlags.complex))\n                return MATCH.nomatch;\n\n            // Disallow implicit conversion of real or imaginary to complex\n            if (flags & (TFlags.real_ | TFlags.imaginary) && tob.flags & TFlags.complex)\n                return MATCH.nomatch;\n\n            // Disallow implicit conversion to-from real and imaginary\n            if ((flags & (TFlags.real_ | TFlags.imaginary)) != (tob.flags & (TFlags.real_ | TFlags.imaginary)))\n                return MATCH.nomatch;\n        }\n        return MATCH.convert;\n    }\n\n    override bool isZeroInit(const ref Loc loc) const\n    {\n        switch (ty)\n        {\n        case Tchar:\n        case Twchar:\n        case Tdchar:\n        case Timaginary32:\n        case Timaginary64:\n        case Timaginary80:\n        case Tfloat32:\n        case Tfloat64:\n        case Tfloat80:\n        case Tcomplex32:\n        case Tcomplex64:\n        case Tcomplex80:\n            return false; // no\n        default:\n            return true; // yes\n        }\n    }\n\n    // For eliminating dynamic_cast\n    override TypeBasic isTypeBasic()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * The basetype must be one of:\n *   byte[16],ubyte[16],short[8],ushort[8],int[4],uint[4],long[2],ulong[2],float[4],double[2]\n * For AVX:\n *   byte[32],ubyte[32],short[16],ushort[16],int[8],uint[8],long[4],ulong[4],float[8],double[4]\n */\nextern (C++) final class TypeVector : Type\n{\n    Type basetype;\n\n    extern (D) this(Type basetype)\n    {\n        super(Tvector);\n        this.basetype = basetype;\n    }\n\n    static TypeVector create(Type basetype)\n    {\n        return new TypeVector(basetype);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"vector\";\n    }\n\n    override Type syntaxCopy()\n    {\n        return new TypeVector(basetype.syntaxCopy());\n    }\n\n    override d_uns64 size(const ref Loc loc)\n    {\n        return basetype.size();\n    }\n\n    override uint alignsize()\n    {\n        return cast(uint)basetype.size();\n    }\n\n    override bool isintegral()\n    {\n        //printf(\"TypeVector::isintegral('%s') x%x\\n\", toChars(), flags);\n        return basetype.nextOf().isintegral();\n    }\n\n    override bool isfloating()\n    {\n        return basetype.nextOf().isfloating();\n    }\n\n    override bool isscalar()\n    {\n        return basetype.nextOf().isscalar();\n    }\n\n    override bool isunsigned()\n    {\n        return basetype.nextOf().isunsigned();\n    }\n\n    override bool isBoolean() const\n    {\n        return false;\n    }\n\n    override MATCH implicitConvTo(Type to)\n    {\n        //printf(\"TypeVector::implicitConvTo(%s) from %s\\n\", to.toChars(), toChars());\n        if (this == to)\n            return MATCH.exact;\n        if (to.ty == Tvector)\n        {\n            TypeVector tv = cast(TypeVector)to;\n            assert(basetype.ty == Tsarray && tv.basetype.ty == Tsarray);\n\n            // Can't convert to a vector which has different size.\n            if (basetype.size() != tv.basetype.size())\n                return MATCH.nomatch;\n\n            // Allow conversion to void[]\n            if (tv.basetype.nextOf().ty == Tvoid)\n                return MATCH.convert;\n\n            // Otherwise implicitly convertible only if basetypes are.\n            return basetype.implicitConvTo(tv.basetype);\n        }\n        return MATCH.nomatch;\n    }\n\n    override Expression defaultInitLiteral(const ref Loc loc)\n    {\n        //printf(\"TypeVector::defaultInitLiteral()\\n\");\n        assert(basetype.ty == Tsarray);\n        Expression e = basetype.defaultInitLiteral(loc);\n        auto ve = new VectorExp(loc, e, this);\n        ve.type = this;\n        ve.dim = cast(int)(basetype.size(loc) / elementType().size(loc));\n        return ve;\n    }\n\n    TypeBasic elementType()\n    {\n        assert(basetype.ty == Tsarray);\n        TypeSArray t = cast(TypeSArray)basetype;\n        TypeBasic tb = t.nextOf().isTypeBasic();\n        assert(tb);\n        return tb;\n    }\n\n    override bool isZeroInit(const ref Loc loc)\n    {\n        return basetype.isZeroInit(loc);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class TypeArray : TypeNext\n{\n    final extern (D) this(TY ty, Type next)\n    {\n        super(ty, next);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Static array, one with a fixed dimension\n */\nextern (C++) final class TypeSArray : TypeArray\n{\n    Expression dim;\n\n    extern (D) this(Type t, Expression dim)\n    {\n        super(Tsarray, t);\n        //printf(\"TypeSArray(%s)\\n\", dim.toChars());\n        this.dim = dim;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"sarray\";\n    }\n\n    override Type syntaxCopy()\n    {\n        Type t = next.syntaxCopy();\n        Expression e = dim.syntaxCopy();\n        t = new TypeSArray(t, e);\n        t.mod = mod;\n        return t;\n    }\n\n    override d_uns64 size(const ref Loc loc)\n    {\n        //printf(\"TypeSArray::size()\\n\");\n        const n = numberOfElems(loc);\n        const elemsize = baseElemOf().size(loc);\n        bool overflow = false;\n        const sz = mulu(n, elemsize, overflow);\n        if (overflow || sz >= uint.max)\n        {\n            if (elemsize != SIZE_INVALID && n != uint.max)\n                error(loc, \"static array `%s` size overflowed to %lld\", toChars(), cast(long)sz);\n            return SIZE_INVALID;\n        }\n        return sz;\n    }\n\n    override uint alignsize()\n    {\n        return next.alignsize();\n    }\n\n    override bool isString()\n    {\n        TY nty = next.toBasetype().ty;\n        return nty == Tchar || nty == Twchar || nty == Tdchar;\n    }\n\n    override bool isZeroInit(const ref Loc loc)\n    {\n        return next.isZeroInit(loc);\n    }\n\n    override structalign_t alignment()\n    {\n        return next.alignment();\n    }\n\n    override MATCH constConv(Type to)\n    {\n        if (to.ty == Tsarray)\n        {\n            TypeSArray tsa = cast(TypeSArray)to;\n            if (!dim.equals(tsa.dim))\n                return MATCH.nomatch;\n        }\n        return TypeNext.constConv(to);\n    }\n\n    override MATCH implicitConvTo(Type to)\n    {\n        //printf(\"TypeSArray::implicitConvTo(to = %s) this = %s\\n\", to.toChars(), toChars());\n        if (to.ty == Tarray)\n        {\n            TypeDArray ta = cast(TypeDArray)to;\n            if (!MODimplicitConv(next.mod, ta.next.mod))\n                return MATCH.nomatch;\n\n            /* Allow conversion to void[]\n             */\n            if (ta.next.ty == Tvoid)\n            {\n                return MATCH.convert;\n            }\n\n            MATCH m = next.constConv(ta.next);\n            if (m > MATCH.nomatch)\n            {\n                return MATCH.convert;\n            }\n            return MATCH.nomatch;\n        }\n        if (to.ty == Tsarray)\n        {\n            if (this == to)\n                return MATCH.exact;\n\n            TypeSArray tsa = cast(TypeSArray)to;\n            if (dim.equals(tsa.dim))\n            {\n                /* Since static arrays are value types, allow\n                 * conversions from const elements to non-const\n                 * ones, just like we allow conversion from const int\n                 * to int.\n                 */\n                MATCH m = next.implicitConvTo(tsa.next);\n                if (m >= MATCH.constant)\n                {\n                    if (mod != to.mod)\n                        m = MATCH.constant;\n                    return m;\n                }\n            }\n        }\n        return MATCH.nomatch;\n    }\n\n    override Expression defaultInitLiteral(const ref Loc loc)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeSArray::defaultInitLiteral() '%s'\\n\", toChars());\n        }\n        size_t d = cast(size_t)dim.toInteger();\n        Expression elementinit;\n        if (next.ty == Tvoid)\n            elementinit = tuns8.defaultInitLiteral(loc);\n        else\n            elementinit = next.defaultInitLiteral(loc);\n        auto elements = new Expressions(d);\n        for (size_t i = 0; i < d; i++)\n            (*elements)[i] = null;\n        auto ae = new ArrayLiteralExp(Loc.initial, this, elementinit, elements);\n        return ae;\n    }\n\n    override bool hasPointers()\n    {\n        /* Don't want to do this, because:\n         *    struct S { T* array[0]; }\n         * may be a variable length struct.\n         */\n        //if (dim.toInteger() == 0)\n        //    return false;\n\n        if (next.ty == Tvoid)\n        {\n            // Arrays of void contain arbitrary data, which may include pointers\n            return true;\n        }\n        else\n            return next.hasPointers();\n    }\n\n    override bool needsDestruction()\n    {\n        return next.needsDestruction();\n    }\n\n    /*********************************\n     *\n     */\n    override bool needsNested()\n    {\n        return next.needsNested();\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Dynamic array, no dimension\n */\nextern (C++) final class TypeDArray : TypeArray\n{\n    extern (D) this(Type t)\n    {\n        super(Tarray, t);\n        //printf(\"TypeDArray(t = %p)\\n\", t);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"darray\";\n    }\n\n    override Type syntaxCopy()\n    {\n        Type t = next.syntaxCopy();\n        if (t == next)\n            t = this;\n        else\n        {\n            t = new TypeDArray(t);\n            t.mod = mod;\n        }\n        return t;\n    }\n\n    override d_uns64 size(const ref Loc loc) const\n    {\n        //printf(\"TypeDArray::size()\\n\");\n        return Target.ptrsize * 2;\n    }\n\n    override uint alignsize() const\n    {\n        // A DArray consists of two ptr-sized values, so align it on pointer size\n        // boundary\n        return Target.ptrsize;\n    }\n\n    override bool isString()\n    {\n        TY nty = next.toBasetype().ty;\n        return nty == Tchar || nty == Twchar || nty == Tdchar;\n    }\n\n    override bool isZeroInit(const ref Loc loc) const\n    {\n        return true;\n    }\n\n    override bool isBoolean() const\n    {\n        return true;\n    }\n\n    override MATCH implicitConvTo(Type to)\n    {\n        //printf(\"TypeDArray::implicitConvTo(to = %s) this = %s\\n\", to.toChars(), toChars());\n        if (equals(to))\n            return MATCH.exact;\n\n        if (to.ty == Tarray)\n        {\n            TypeDArray ta = cast(TypeDArray)to;\n\n            if (!MODimplicitConv(next.mod, ta.next.mod))\n                return MATCH.nomatch; // not const-compatible\n\n            /* Allow conversion to void[]\n             */\n            if (next.ty != Tvoid && ta.next.ty == Tvoid)\n            {\n                return MATCH.convert;\n            }\n\n            MATCH m = next.constConv(ta.next);\n            if (m > MATCH.nomatch)\n            {\n                if (m == MATCH.exact && mod != to.mod)\n                    m = MATCH.constant;\n                return m;\n            }\n        }\n        return Type.implicitConvTo(to);\n    }\n\n    override bool hasPointers() const\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeAArray : TypeArray\n{\n    Type index;     // key type\n    Loc loc;\n    Scope* sc;\n\n    extern (D) this(Type t, Type index)\n    {\n        super(Taarray, t);\n        this.index = index;\n    }\n\n    static TypeAArray create(Type t, Type index)\n    {\n        return new TypeAArray(t, index);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"aarray\";\n    }\n\n    override Type syntaxCopy()\n    {\n        Type t = next.syntaxCopy();\n        Type ti = index.syntaxCopy();\n        if (t == next && ti == index)\n            t = this;\n        else\n        {\n            t = new TypeAArray(t, ti);\n            t.mod = mod;\n        }\n        return t;\n    }\n\n    override d_uns64 size(const ref Loc loc)\n    {\n        return Target.ptrsize;\n    }\n\n    override bool isZeroInit(const ref Loc loc) const\n    {\n        return true;\n    }\n\n    override bool isBoolean() const\n    {\n        return true;\n    }\n\n    override bool hasPointers() const\n    {\n        return true;\n    }\n\n    override MATCH implicitConvTo(Type to)\n    {\n        //printf(\"TypeAArray::implicitConvTo(to = %s) this = %s\\n\", to.toChars(), toChars());\n        if (equals(to))\n            return MATCH.exact;\n\n        if (to.ty == Taarray)\n        {\n            TypeAArray ta = cast(TypeAArray)to;\n\n            if (!MODimplicitConv(next.mod, ta.next.mod))\n                return MATCH.nomatch; // not const-compatible\n\n            if (!MODimplicitConv(index.mod, ta.index.mod))\n                return MATCH.nomatch; // not const-compatible\n\n            MATCH m = next.constConv(ta.next);\n            MATCH mi = index.constConv(ta.index);\n            if (m > MATCH.nomatch && mi > MATCH.nomatch)\n            {\n                return MODimplicitConv(mod, to.mod) ? MATCH.constant : MATCH.nomatch;\n            }\n        }\n        return Type.implicitConvTo(to);\n    }\n\n    override MATCH constConv(Type to)\n    {\n        if (to.ty == Taarray)\n        {\n            TypeAArray taa = cast(TypeAArray)to;\n            MATCH mindex = index.constConv(taa.index);\n            MATCH mkey = next.constConv(taa.next);\n            // Pick the worst match\n            return mkey < mindex ? mkey : mindex;\n        }\n        return Type.constConv(to);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypePointer : TypeNext\n{\n    extern (D) this(Type t)\n    {\n        super(Tpointer, t);\n    }\n\n    static TypePointer create(Type t)\n    {\n        return new TypePointer(t);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"pointer\";\n    }\n\n    override Type syntaxCopy()\n    {\n        Type t = next.syntaxCopy();\n        if (t == next)\n            t = this;\n        else\n        {\n            t = new TypePointer(t);\n            t.mod = mod;\n        }\n        return t;\n    }\n\n    override d_uns64 size(const ref Loc loc) const\n    {\n        return Target.ptrsize;\n    }\n\n    override MATCH implicitConvTo(Type to)\n    {\n        //printf(\"TypePointer::implicitConvTo(to = %s) %s\\n\", to.toChars(), toChars());\n        if (equals(to))\n            return MATCH.exact;\n\n        if (next.ty == Tfunction)\n        {\n            if (to.ty == Tpointer)\n            {\n                TypePointer tp = cast(TypePointer)to;\n                if (tp.next.ty == Tfunction)\n                {\n                    if (next.equals(tp.next))\n                        return MATCH.constant;\n\n                    if (next.covariant(tp.next) == 1)\n                    {\n                        Type tret = this.next.nextOf();\n                        Type toret = tp.next.nextOf();\n                        if (tret.ty == Tclass && toret.ty == Tclass)\n                        {\n                            /* https://issues.dlang.org/show_bug.cgi?id=10219\n                             * Check covariant interface return with offset tweaking.\n                             * interface I {}\n                             * class C : Object, I {}\n                             * I function() dg = function C() {}    // should be error\n                             */\n                            int offset = 0;\n                            if (toret.isBaseOf(tret, &offset) && offset != 0)\n                                return MATCH.nomatch;\n                        }\n                        return MATCH.convert;\n                    }\n                }\n                else if (tp.next.ty == Tvoid)\n                {\n                    // Allow conversions to void*\n                    return MATCH.convert;\n                }\n            }\n            return MATCH.nomatch;\n        }\n        else if (to.ty == Tpointer)\n        {\n            TypePointer tp = cast(TypePointer)to;\n            assert(tp.next);\n\n            if (!MODimplicitConv(next.mod, tp.next.mod))\n                return MATCH.nomatch; // not const-compatible\n\n            /* Alloc conversion to void*\n             */\n            if (next.ty != Tvoid && tp.next.ty == Tvoid)\n            {\n                return MATCH.convert;\n            }\n\n            MATCH m = next.constConv(tp.next);\n            if (m > MATCH.nomatch)\n            {\n                if (m == MATCH.exact && mod != to.mod)\n                    m = MATCH.constant;\n                return m;\n            }\n        }\n        return MATCH.nomatch;\n    }\n\n    override MATCH constConv(Type to)\n    {\n        if (next.ty == Tfunction)\n        {\n            if (to.nextOf() && next.equals((cast(TypeNext)to).next))\n                return Type.constConv(to);\n            else\n                return MATCH.nomatch;\n        }\n        return TypeNext.constConv(to);\n    }\n\n    override bool isscalar() const\n    {\n        return true;\n    }\n\n    override bool isZeroInit(const ref Loc loc) const\n    {\n        return true;\n    }\n\n    override bool hasPointers() const\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeReference : TypeNext\n{\n    extern (D) this(Type t)\n    {\n        super(Treference, t);\n        // BUG: what about references to static arrays?\n    }\n\n    override const(char)* kind() const\n    {\n        return \"reference\";\n    }\n\n    override Type syntaxCopy()\n    {\n        Type t = next.syntaxCopy();\n        if (t == next)\n            t = this;\n        else\n        {\n            t = new TypeReference(t);\n            t.mod = mod;\n        }\n        return t;\n    }\n\n    override d_uns64 size(const ref Loc loc) const\n    {\n        return Target.ptrsize;\n    }\n\n    override bool isZeroInit(const ref Loc loc) const\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\nenum RET : int\n{\n    regs         = 1,    // returned in registers\n    stack        = 2,    // returned on stack\n}\n\nenum TRUST : int\n{\n    default_   = 0,\n    system     = 1,    // @system (same as TRUST.default)\n    trusted    = 2,    // @trusted\n    safe       = 3,    // @safe\n}\n\nenum TRUSTformat : int\n{\n    TRUSTformatDefault,     // do not emit @system when trust == TRUST.default_\n    TRUSTformatSystem,      // emit @system when trust == TRUST.default_\n}\n\nalias TRUSTformatDefault = TRUSTformat.TRUSTformatDefault;\nalias TRUSTformatSystem = TRUSTformat.TRUSTformatSystem;\n\nenum PURE : int\n{\n    impure      = 0,    // not pure at all\n    fwdref      = 1,    // it's pure, but not known which level yet\n    weak        = 2,    // no mutable globals are read or written\n    const_      = 3,    // parameters are values or const\n    strong      = 4,    // parameters are values or immutable\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeFunction : TypeNext\n{\n    // .next is the return type\n\n    Parameters* parameters;     // function parameters\n    int varargs;                // 1: T t, ...) style for variable number of arguments\n                                // 2: T t ...) style for variable number of arguments\n    bool isnothrow;             // true: nothrow\n    bool isnogc;                // true: is @nogc\n    bool isproperty;            // can be called without parentheses\n    bool isref;                 // true: returns a reference\n    bool isreturn;              // true: 'this' is returned by ref\n    bool isscope;               // true: 'this' is scope\n    bool isscopeinferred;       // true: 'this' is scope from inference\n    LINK linkage;               // calling convention\n    TRUST trust;                // level of trust\n    PURE purity = PURE.impure;\n    ubyte iswild;               // bit0: inout on params, bit1: inout on qualifier\n    Expressions* fargs;         // function arguments\n    int inuse;\n\n    extern (D) this(Parameters* parameters, Type treturn, int varargs, LINK linkage, StorageClass stc = 0)\n    {\n        super(Tfunction, treturn);\n        //if (!treturn) *(char*)0=0;\n        //    assert(treturn);\n        assert(0 <= varargs && varargs <= 2);\n        this.parameters = parameters;\n        this.varargs = varargs;\n        this.linkage = linkage;\n\n        if (stc & STC.pure_)\n            this.purity = PURE.fwdref;\n        if (stc & STC.nothrow_)\n            this.isnothrow = true;\n        if (stc & STC.nogc)\n            this.isnogc = true;\n        if (stc & STC.property)\n            this.isproperty = true;\n\n        if (stc & STC.ref_)\n            this.isref = true;\n        if (stc & STC.return_)\n            this.isreturn = true;\n        if (stc & STC.scope_)\n            this.isscope = true;\n        if (stc & STC.scopeinferred)\n            this.isscopeinferred = true;\n\n        this.trust = TRUST.default_;\n        if (stc & STC.safe)\n            this.trust = TRUST.safe;\n        if (stc & STC.system)\n            this.trust = TRUST.system;\n        if (stc & STC.trusted)\n            this.trust = TRUST.trusted;\n    }\n\n    static TypeFunction create(Parameters* parameters, Type treturn, int varargs, LINK linkage, StorageClass stc = 0)\n    {\n        return new TypeFunction(parameters, treturn, varargs, linkage, stc);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"function\";\n    }\n\n    override Type syntaxCopy()\n    {\n        Type treturn = next ? next.syntaxCopy() : null;\n        Parameters* params = Parameter.arraySyntaxCopy(parameters);\n        auto t = new TypeFunction(params, treturn, varargs, linkage);\n        t.mod = mod;\n        t.isnothrow = isnothrow;\n        t.isnogc = isnogc;\n        t.purity = purity;\n        t.isproperty = isproperty;\n        t.isref = isref;\n        t.isreturn = isreturn;\n        t.isscope = isscope;\n        t.isscopeinferred = isscopeinferred;\n        t.iswild = iswild;\n        t.trust = trust;\n        t.fargs = fargs;\n        return t;\n    }\n\n    /********************************************\n     * Set 'purity' field of 'this'.\n     * Do this lazily, as the parameter types might be forward referenced.\n     */\n    void purityLevel()\n    {\n        TypeFunction tf = this;\n        if (tf.purity != PURE.fwdref)\n            return;\n\n        /* Determine purity level based on mutability of t\n         * and whether it is a 'ref' type or not.\n         */\n        static PURE purityOfType(bool isref, Type t)\n        {\n            if (isref)\n            {\n                if (t.mod & MODFlags.immutable_)\n                    return PURE.strong;\n                if (t.mod & (MODFlags.const_ | MODFlags.wild))\n                    return PURE.const_;\n                return PURE.weak;\n            }\n\n            t = t.baseElemOf();\n\n            if (!t.hasPointers() || t.mod & MODFlags.immutable_)\n                return PURE.strong;\n\n            /* Accept immutable(T)[] and immutable(T)* as being strongly pure\n             */\n            if (t.ty == Tarray || t.ty == Tpointer)\n            {\n                Type tn = t.nextOf().toBasetype();\n                if (tn.mod & MODFlags.immutable_)\n                    return PURE.strong;\n                if (tn.mod & (MODFlags.const_ | MODFlags.wild))\n                    return PURE.const_;\n            }\n\n            /* The rest of this is too strict; fix later.\n             * For example, the only pointer members of a struct may be immutable,\n             * which would maintain strong purity.\n             * (Just like for dynamic arrays and pointers above.)\n             */\n            if (t.mod & (MODFlags.const_ | MODFlags.wild))\n                return PURE.const_;\n\n            /* Should catch delegates and function pointers, and fold in their purity\n             */\n            return PURE.weak;\n        }\n\n        purity = PURE.strong; // assume strong until something weakens it\n\n        /* Evaluate what kind of purity based on the modifiers for the parameters\n         */\n        const dim = Parameter.dim(tf.parameters);\n    Lloop: foreach (i; 0 .. dim)\n        {\n            Parameter fparam = Parameter.getNth(tf.parameters, i);\n            Type t = fparam.type;\n            if (!t)\n                continue;\n\n            if (fparam.storageClass & (STC.lazy_ | STC.out_))\n            {\n                purity = PURE.weak;\n                break;\n            }\n            switch (purityOfType((fparam.storageClass & STC.ref_) != 0, t))\n            {\n                case PURE.weak:\n                    purity = PURE.weak;\n                    break Lloop; // since PURE.weak, no need to check further\n\n                case PURE.const_:\n                    purity = PURE.const_;\n                    continue;\n\n                case PURE.strong:\n                    continue;\n\n                default:\n                    assert(0);\n            }\n        }\n\n        if (purity > PURE.weak && tf.nextOf())\n        {\n            /* Adjust purity based on mutability of return type.\n             * https://issues.dlang.org/show_bug.cgi?id=15862\n             */\n            const purity2 = purityOfType(tf.isref, tf.nextOf());\n            if (purity2 < purity)\n                purity = purity2;\n        }\n        tf.purity = purity;\n    }\n\n    /********************************************\n     * Return true if there are lazy parameters.\n     */\n    bool hasLazyParameters()\n    {\n        size_t dim = Parameter.dim(parameters);\n        for (size_t i = 0; i < dim; i++)\n        {\n            Parameter fparam = Parameter.getNth(parameters, i);\n            if (fparam.storageClass & STC.lazy_)\n                return true;\n        }\n        return false;\n    }\n\n    /***************************\n     * Examine function signature for parameter p and see if\n     * the value of p can 'escape' the scope of the function.\n     * This is useful to minimize the needed annotations for the parameters.\n     * Params:\n     *  tthis = type of `this` parameter, null if none\n     *  p = parameter to this function\n     * Returns:\n     *  true if escapes via assignment to global or through a parameter\n     */\n    bool parameterEscapes(Type tthis, Parameter p)\n    {\n        /* Scope parameters do not escape.\n         * Allow 'lazy' to imply 'scope' -\n         * lazy parameters can be passed along\n         * as lazy parameters to the next function, but that isn't\n         * escaping.\n         */\n        if (parameterStorageClass(tthis, p) & (STC.scope_ | STC.lazy_))\n            return false;\n        return true;\n    }\n\n    /************************************\n     * Take the specified storage class for p,\n     * and use the function signature to infer whether\n     * STC.scope_ and STC.return_ should be OR'd in.\n     * (This will not affect the name mangling.)\n     * Params:\n     *  tthis = type of `this` parameter, null if none\n     *  p = parameter to this function\n     * Returns:\n     *  storage class with STC.scope_ or STC.return_ OR'd in\n     */\n    StorageClass parameterStorageClass(Type tthis, Parameter p)\n    {\n        //printf(\"parameterStorageClass(p: %s)\\n\", p.toChars());\n        auto stc = p.storageClass;\n        if (!global.params.vsafe)\n            return stc;\n\n        if (stc & (STC.scope_ | STC.return_ | STC.lazy_) || purity == PURE.impure)\n            return stc;\n\n        /* If haven't inferred the return type yet, can't infer storage classes\n         */\n        if (!nextOf())\n            return stc;\n\n        purityLevel();\n\n        // See if p can escape via any of the other parameters\n        if (purity == PURE.weak)\n        {\n            // Check escaping through parameters\n            const dim = Parameter.dim(parameters);\n            foreach (const i; 0 .. dim)\n            {\n                Parameter fparam = Parameter.getNth(parameters, i);\n                if (fparam == p)\n                    continue;\n                Type t = fparam.type;\n                if (!t)\n                    continue;\n                t = t.baseElemOf();\n                if (t.isMutable() && t.hasPointers())\n                {\n                    if (fparam.storageClass & (STC.ref_ | STC.out_))\n                    {\n                    }\n                    else if (t.ty == Tarray || t.ty == Tpointer)\n                    {\n                        Type tn = t.nextOf().toBasetype();\n                        if (!(tn.isMutable() && tn.hasPointers()))\n                            continue;\n                    }\n                    return stc;\n                }\n            }\n\n            // Check escaping through `this`\n            if (tthis && tthis.isMutable())\n            {\n                auto tb = tthis.toBasetype();\n                AggregateDeclaration ad;\n                if (tb.ty == Tclass)\n                    ad = (cast(TypeClass)tb).sym;\n                else if (tb.ty == Tstruct)\n                    ad = (cast(TypeStruct)tb).sym;\n                else\n                    assert(0);\n                foreach (VarDeclaration v; ad.fields)\n                {\n                    if (v.hasPointers())\n                        return stc;\n                }\n            }\n        }\n\n        stc |= STC.scope_;\n\n        /* Inferring STC.return_ here has false positives\n         * for pure functions, producing spurious error messages\n         * about escaping references.\n         * Give up on it for now.\n         */\n        version (none)\n        {\n            Type tret = nextOf().toBasetype();\n            if (isref || tret.hasPointers())\n            {\n                /* The result has references, so p could be escaping\n                 * that way.\n                 */\n                stc |= STC.return_;\n            }\n        }\n\n        return stc;\n    }\n\n    override Type addStorageClass(StorageClass stc)\n    {\n        //printf(\"addStorageClass(%llx) %d\\n\", stc, (stc & STC.scope_) != 0);\n        TypeFunction t = Type.addStorageClass(stc).toTypeFunction();\n        if ((stc & STC.pure_ && !t.purity) ||\n            (stc & STC.nothrow_ && !t.isnothrow) ||\n            (stc & STC.nogc && !t.isnogc) ||\n            (stc & STC.scope_ && !t.isscope) ||\n            (stc & STC.safe && t.trust < TRUST.trusted))\n        {\n            // Klunky to change these\n            auto tf = new TypeFunction(t.parameters, t.next, t.varargs, t.linkage, 0);\n            tf.mod = t.mod;\n            tf.fargs = fargs;\n            tf.purity = t.purity;\n            tf.isnothrow = t.isnothrow;\n            tf.isnogc = t.isnogc;\n            tf.isproperty = t.isproperty;\n            tf.isref = t.isref;\n            tf.isreturn = t.isreturn;\n            tf.isscope = t.isscope;\n            tf.isscopeinferred = t.isscopeinferred;\n            tf.trust = t.trust;\n            tf.iswild = t.iswild;\n\n            if (stc & STC.pure_)\n                tf.purity = PURE.fwdref;\n            if (stc & STC.nothrow_)\n                tf.isnothrow = true;\n            if (stc & STC.nogc)\n                tf.isnogc = true;\n            if (stc & STC.safe)\n                tf.trust = TRUST.safe;\n            if (stc & STC.scope_)\n            {\n                tf.isscope = true;\n                if (stc & STC.scopeinferred)\n                    tf.isscopeinferred = true;\n            }\n\n            tf.deco = tf.merge().deco;\n            t = tf;\n        }\n        return t;\n    }\n\n    override Type substWildTo(uint)\n    {\n        if (!iswild && !(mod & MODFlags.wild))\n            return this;\n\n        // Substitude inout qualifier of function type to mutable or immutable\n        // would break type system. Instead substitude inout to the most weak\n        // qualifer - const.\n        uint m = MODFlags.const_;\n\n        assert(next);\n        Type tret = next.substWildTo(m);\n        Parameters* params = parameters;\n        if (mod & MODFlags.wild)\n            params = parameters.copy();\n        for (size_t i = 0; i < params.dim; i++)\n        {\n            Parameter p = (*params)[i];\n            Type t = p.type.substWildTo(m);\n            if (t == p.type)\n                continue;\n            if (params == parameters)\n                params = parameters.copy();\n            (*params)[i] = new Parameter(p.storageClass, t, null, null, null);\n        }\n        if (next == tret && params == parameters)\n            return this;\n\n        // Similar to TypeFunction::syntaxCopy;\n        auto t = new TypeFunction(params, tret, varargs, linkage);\n        t.mod = ((mod & MODFlags.wild) ? (mod & ~MODFlags.wild) | MODFlags.const_ : mod);\n        t.isnothrow = isnothrow;\n        t.isnogc = isnogc;\n        t.purity = purity;\n        t.isproperty = isproperty;\n        t.isref = isref;\n        t.isreturn = isreturn;\n        t.isscope = isscope;\n        t.isscopeinferred = isscopeinferred;\n        t.iswild = 0;\n        t.trust = trust;\n        t.fargs = fargs;\n        return t.merge();\n    }\n\n    // arguments get specially formatted\n    private const(char)* getParamError(Expression arg, Parameter par)\n    {\n        if (global.gag && !global.params.showGaggedErrors)\n            return null;\n        // show qualification when toChars() is the same but types are different\n        auto at = arg.type.toChars();\n        bool qual = !arg.type.equals(par.type) && strcmp(at, par.type.toChars()) == 0;\n        if (qual)\n            at = arg.type.toPrettyChars(true);\n        OutBuffer buf;\n        // only mention rvalue if it's relevant\n        const rv = !arg.isLvalue() && par.storageClass & (STC.ref_ | STC.out_);\n        buf.printf(\"cannot pass %sargument `%s` of type `%s` to parameter `%s`\",\n            rv ? \"rvalue \".ptr : \"\".ptr, arg.toChars(), at,\n            parameterToChars(par, this, qual));\n        return buf.extractString();\n    }\n\n    /********************************\n     * 'args' are being matched to function 'this'\n     * Determine match level.\n     * Input:\n     *      flag    1       performing a partial ordering match\n     *      pMessage        address to store error message, or null\n     * Returns:\n     *      MATCHxxxx\n     */\n    extern (D) MATCH callMatch(Type tthis, Expressions* args, int flag = 0, const(char)** pMessage = null)\n    {\n        //printf(\"TypeFunction::callMatch() %s\\n\", toChars());\n        MATCH match = MATCH.exact; // assume exact match\n        ubyte wildmatch = 0;\n\n        if (tthis)\n        {\n            Type t = tthis;\n            if (t.toBasetype().ty == Tpointer)\n                t = t.toBasetype().nextOf(); // change struct* to struct\n            if (t.mod != mod)\n            {\n                if (MODimplicitConv(t.mod, mod))\n                    match = MATCH.constant;\n                else if ((mod & MODFlags.wild) && MODimplicitConv(t.mod, (mod & ~MODFlags.wild) | MODFlags.const_))\n                {\n                    match = MATCH.constant;\n                }\n                else\n                    return MATCH.nomatch;\n            }\n            if (isWild())\n            {\n                if (t.isWild())\n                    wildmatch |= MODFlags.wild;\n                else if (t.isConst())\n                    wildmatch |= MODFlags.const_;\n                else if (t.isImmutable())\n                    wildmatch |= MODFlags.immutable_;\n                else\n                    wildmatch |= MODFlags.mutable;\n            }\n        }\n\n        size_t nparams = Parameter.dim(parameters);\n        size_t nargs = args ? args.dim : 0;\n        if (nparams == nargs)\n        {\n        }\n        else if (nargs > nparams)\n        {\n            if (varargs == 0)\n                goto Nomatch;\n            // too many args; no match\n            match = MATCH.convert; // match ... with a \"conversion\" match level\n        }\n\n        for (size_t u = 0; u < nargs; u++)\n        {\n            if (u >= nparams)\n                break;\n            Parameter p = Parameter.getNth(parameters, u);\n            Expression arg = (*args)[u];\n            assert(arg);\n            Type tprm = p.type;\n            Type targ = arg.type;\n\n            if (!(p.storageClass & STC.lazy_ && tprm.ty == Tvoid && targ.ty != Tvoid))\n            {\n                bool isRef = (p.storageClass & (STC.ref_ | STC.out_)) != 0;\n                wildmatch |= targ.deduceWild(tprm, isRef);\n            }\n        }\n        if (wildmatch)\n        {\n            /* Calculate wild matching modifier\n             */\n            if (wildmatch & MODFlags.const_ || wildmatch & (wildmatch - 1))\n                wildmatch = MODFlags.const_;\n            else if (wildmatch & MODFlags.immutable_)\n                wildmatch = MODFlags.immutable_;\n            else if (wildmatch & MODFlags.wild)\n                wildmatch = MODFlags.wild;\n            else\n            {\n                assert(wildmatch & MODFlags.mutable);\n                wildmatch = MODFlags.mutable;\n            }\n        }\n\n        for (size_t u = 0; u < nparams; u++)\n        {\n            MATCH m;\n\n            Parameter p = Parameter.getNth(parameters, u);\n            assert(p);\n            if (u >= nargs)\n            {\n                if (p.defaultArg)\n                    continue;\n                goto L1;\n                // try typesafe variadics\n            }\n            {\n                Expression arg = (*args)[u];\n                assert(arg);\n                //printf(\"arg: %s, type: %s\\n\", arg.toChars(), arg.type.toChars());\n\n                Type targ = arg.type;\n                Type tprm = wildmatch ? p.type.substWildTo(wildmatch) : p.type;\n\n                if (p.storageClass & STC.lazy_ && tprm.ty == Tvoid && targ.ty != Tvoid)\n                    m = MATCH.convert;\n                else\n                {\n                    //printf(\"%s of type %s implicitConvTo %s\\n\", arg.toChars(), targ.toChars(), tprm.toChars());\n                    if (flag)\n                    {\n                        // for partial ordering, value is an irrelevant mockup, just look at the type\n                        m = targ.implicitConvTo(tprm);\n                    }\n                    else\n                        m = arg.implicitConvTo(tprm);\n                    //printf(\"match %d\\n\", m);\n                }\n\n                // Non-lvalues do not match ref or out parameters\n                if (p.storageClass & (STC.ref_ | STC.out_))\n                {\n                    // https://issues.dlang.org/show_bug.cgi?id=13783\n                    // Don't use toBasetype() to handle enum types.\n                    Type ta = targ;\n                    Type tp = tprm;\n                    //printf(\"fparam[%d] ta = %s, tp = %s\\n\", u, ta.toChars(), tp.toChars());\n\n                    if (m && !arg.isLvalue())\n                    {\n                        if (p.storageClass & STC.out_)\n                        {\n                            if (pMessage) *pMessage = getParamError(arg, p);\n                            goto Nomatch;\n                        }\n\n                        if (arg.op == TOK.string_ && tp.ty == Tsarray)\n                        {\n                            if (ta.ty != Tsarray)\n                            {\n                                Type tn = tp.nextOf().castMod(ta.nextOf().mod);\n                                dinteger_t dim = (cast(StringExp)arg).len;\n                                ta = tn.sarrayOf(dim);\n                            }\n                        }\n                        else if (arg.op == TOK.slice && tp.ty == Tsarray)\n                        {\n                            // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]\n                            if (ta.ty != Tsarray)\n                            {\n                                Type tn = ta.nextOf();\n                                dinteger_t dim = (cast(TypeSArray)tp).dim.toUInteger();\n                                ta = tn.sarrayOf(dim);\n                            }\n                        }\n                        else\n                        {\n                            if (pMessage) *pMessage = getParamError(arg, p);\n                            goto Nomatch;\n                        }\n                    }\n\n                    /* Find most derived alias this type being matched.\n                     * https://issues.dlang.org/show_bug.cgi?id=15674\n                     * Allow on both ref and out parameters.\n                     */\n                    while (1)\n                    {\n                        Type tab = ta.toBasetype();\n                        Type tat = tab.aliasthisOf();\n                        if (!tat || !tat.implicitConvTo(tprm))\n                            break;\n                        if (tat == tab)\n                            break;\n                        ta = tat;\n                    }\n\n                    /* A ref variable should work like a head-const reference.\n                     * e.g. disallows:\n                     *  ref T      <- an lvalue of const(T) argument\n                     *  ref T[dim] <- an lvalue of const(T[dim]) argument\n                     */\n                    if (!ta.constConv(tp))\n                    {\n                        if (pMessage) *pMessage = getParamError(arg, p);\n                        goto Nomatch;\n                    }\n                }\n            }\n\n            /* prefer matching the element type rather than the array\n             * type when more arguments are present with T[]...\n             */\n            if (varargs == 2 && u + 1 == nparams && nargs > nparams)\n                goto L1;\n\n            //printf(\"\\tm = %d\\n\", m);\n            if (m == MATCH.nomatch) // if no match\n            {\n            L1:\n                if (varargs == 2 && u + 1 == nparams) // if last varargs param\n                {\n                    Type tb = p.type.toBasetype();\n                    TypeSArray tsa;\n                    dinteger_t sz;\n\n                    switch (tb.ty)\n                    {\n                    case Tsarray:\n                        tsa = cast(TypeSArray)tb;\n                        sz = tsa.dim.toInteger();\n                        if (sz != nargs - u)\n                            goto Nomatch;\n                        goto case Tarray;\n                    case Tarray:\n                        {\n                            TypeArray ta = cast(TypeArray)tb;\n                            for (; u < nargs; u++)\n                            {\n                                Expression arg = (*args)[u];\n                                assert(arg);\n\n                                /* If lazy array of delegates,\n                                 * convert arg(s) to delegate(s)\n                                 */\n                                Type tret = p.isLazyArray();\n                                if (tret)\n                                {\n                                    if (ta.next.equals(arg.type))\n                                        m = MATCH.exact;\n                                    else if (tret.toBasetype().ty == Tvoid)\n                                        m = MATCH.convert;\n                                    else\n                                    {\n                                        m = arg.implicitConvTo(tret);\n                                        if (m == MATCH.nomatch)\n                                            m = arg.implicitConvTo(ta.next);\n                                    }\n                                }\n                                else\n                                    m = arg.implicitConvTo(ta.next);\n\n                                if (m == MATCH.nomatch)\n                                {\n                                    if (pMessage) *pMessage = getParamError(arg, p);\n                                    goto Nomatch;\n                                }\n                                if (m < match)\n                                    match = m;\n                            }\n                            goto Ldone;\n                        }\n                    case Tclass:\n                        // Should see if there's a constructor match?\n                        // Or just leave it ambiguous?\n                        goto Ldone;\n\n                    default:\n                        break;\n                    }\n                }\n                if (pMessage && u < nargs)\n                    *pMessage = getParamError((*args)[u], p);\n                goto Nomatch;\n            }\n            if (m < match)\n                match = m; // pick worst match\n        }\n\n    Ldone:\n        //printf(\"match = %d\\n\", match);\n        return match;\n\n    Nomatch:\n        //printf(\"no match\\n\");\n        return MATCH.nomatch;\n    }\n\n    extern (D) bool checkRetType(const ref Loc loc)\n    {\n        Type tb = next.toBasetype();\n        if (tb.ty == Tfunction)\n        {\n            error(loc, \"functions cannot return a function\");\n            next = Type.terror;\n        }\n        if (tb.ty == Ttuple)\n        {\n            error(loc, \"functions cannot return a tuple\");\n            next = Type.terror;\n        }\n        if (!isref && (tb.ty == Tstruct || tb.ty == Tsarray))\n        {\n            Type tb2 = tb.baseElemOf();\n            if (tb2.ty == Tstruct && !(cast(TypeStruct)tb2).sym.members)\n            {\n                error(loc, \"functions cannot return opaque type `%s` by value\", tb.toChars());\n                next = Type.terror;\n            }\n        }\n        if (tb.ty == Terror)\n            return true;\n        return false;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeDelegate : TypeNext\n{\n    // .next is a TypeFunction\n\n    extern (D) this(Type t)\n    {\n        super(Tfunction, t);\n        ty = Tdelegate;\n    }\n\n    static TypeDelegate create(Type t)\n    {\n        return new TypeDelegate(t);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"delegate\";\n    }\n\n    override Type syntaxCopy()\n    {\n        Type t = next.syntaxCopy();\n        if (t == next)\n            t = this;\n        else\n        {\n            t = new TypeDelegate(t);\n            t.mod = mod;\n        }\n        return t;\n    }\n\n    override Type addStorageClass(StorageClass stc)\n    {\n        TypeDelegate t = cast(TypeDelegate)Type.addStorageClass(stc);\n        if (!global.params.vsafe)\n            return t;\n\n        /* The rest is meant to add 'scope' to a delegate declaration if it is of the form:\n         *  alias dg_t = void* delegate();\n         *  scope dg_t dg = ...;\n         */\n        if(stc & STC.scope_)\n        {\n            auto n = t.next.addStorageClass(STC.scope_ | STC.scopeinferred);\n            if (n != t.next)\n            {\n                t.next = n;\n                t.deco = t.merge().deco; // mangling supposed to not be changed due to STC.scope_inferrred\n            }\n        }\n        return t;\n    }\n\n    override d_uns64 size(const ref Loc loc) const\n    {\n        return Target.ptrsize * 2;\n    }\n\n    override uint alignsize() const\n    {\n        return Target.ptrsize;\n    }\n\n    override MATCH implicitConvTo(Type to)\n    {\n        //printf(\"TypeDelegate.implicitConvTo(this=%p, to=%p)\\n\", this, to);\n        //printf(\"from: %s\\n\", toChars());\n        //printf(\"to  : %s\\n\", to.toChars());\n        if (this == to)\n            return MATCH.exact;\n\n        version (all)\n        {\n            // not allowing covariant conversions because it interferes with overriding\n            if (to.ty == Tdelegate && this.nextOf().covariant(to.nextOf()) == 1)\n            {\n                Type tret = this.next.nextOf();\n                Type toret = (cast(TypeDelegate)to).next.nextOf();\n                if (tret.ty == Tclass && toret.ty == Tclass)\n                {\n                    /* https://issues.dlang.org/show_bug.cgi?id=10219\n                     * Check covariant interface return with offset tweaking.\n                     * interface I {}\n                     * class C : Object, I {}\n                     * I delegate() dg = delegate C() {}    // should be error\n                     */\n                    int offset = 0;\n                    if (toret.isBaseOf(tret, &offset) && offset != 0)\n                        return MATCH.nomatch;\n                }\n                return MATCH.convert;\n            }\n        }\n\n        return MATCH.nomatch;\n    }\n\n    override bool isZeroInit(const ref Loc loc) const\n    {\n        return true;\n    }\n\n    override bool isBoolean() const\n    {\n        return true;\n    }\n\n    override bool hasPointers() const\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) abstract class TypeQualified : Type\n{\n    Loc loc;\n\n    // array of Identifier and TypeInstance,\n    // representing ident.ident!tiargs.ident. ... etc.\n    Objects idents;\n\n    final extern (D) this(TY ty, Loc loc)\n    {\n        super(ty);\n        this.loc = loc;\n    }\n\n    final void syntaxCopyHelper(TypeQualified t)\n    {\n        //printf(\"TypeQualified::syntaxCopyHelper(%s) %s\\n\", t.toChars(), toChars());\n        idents.setDim(t.idents.dim);\n        for (size_t i = 0; i < idents.dim; i++)\n        {\n            RootObject id = t.idents[i];\n            if (id.dyncast() == DYNCAST.dsymbol)\n            {\n                TemplateInstance ti = cast(TemplateInstance)id;\n                ti = cast(TemplateInstance)ti.syntaxCopy(null);\n                id = ti;\n            }\n            else if (id.dyncast() == DYNCAST.expression)\n            {\n                Expression e = cast(Expression)id;\n                e = e.syntaxCopy();\n                id = e;\n            }\n            else if (id.dyncast() == DYNCAST.type)\n            {\n                Type tx = cast(Type)id;\n                tx = tx.syntaxCopy();\n                id = tx;\n            }\n            idents[i] = id;\n        }\n    }\n\n    final void addIdent(Identifier ident)\n    {\n        idents.push(ident);\n    }\n\n    final void addInst(TemplateInstance inst)\n    {\n        idents.push(inst);\n    }\n\n    final void addIndex(RootObject e)\n    {\n        idents.push(e);\n    }\n\n    override d_uns64 size(const ref Loc loc)\n    {\n        error(this.loc, \"size of type `%s` is not known\", toChars());\n        return SIZE_INVALID;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeIdentifier : TypeQualified\n{\n    Identifier ident;\n\n    // The symbol representing this identifier, before alias resolution\n    Dsymbol originalSymbol;\n\n    extern (D) this(const ref Loc loc, Identifier ident)\n    {\n        super(Tident, loc);\n        this.ident = ident;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"identifier\";\n    }\n\n    override Type syntaxCopy()\n    {\n        auto t = new TypeIdentifier(loc, ident);\n        t.syntaxCopyHelper(this);\n        t.mod = mod;\n        return t;\n    }\n\n    /*****************************************\n     * See if type resolves to a symbol, if so,\n     * return that symbol.\n     */\n    override Dsymbol toDsymbol(Scope* sc)\n    {\n        //printf(\"TypeIdentifier::toDsymbol('%s')\\n\", toChars());\n        if (!sc)\n            return null;\n\n        Type t;\n        Expression e;\n        Dsymbol s;\n        resolve(this, loc, sc, &e, &t, &s);\n        if (t && t.ty != Tident)\n            s = t.toDsymbol(sc);\n        if (e)\n            s = getDsymbol(e);\n\n        return s;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Similar to TypeIdentifier, but with a TemplateInstance as the root\n */\nextern (C++) final class TypeInstance : TypeQualified\n{\n    TemplateInstance tempinst;\n\n    extern (D) this(const ref Loc loc, TemplateInstance tempinst)\n    {\n        super(Tinstance, loc);\n        this.tempinst = tempinst;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"instance\";\n    }\n\n    override Type syntaxCopy()\n    {\n        //printf(\"TypeInstance::syntaxCopy() %s, %d\\n\", toChars(), idents.dim);\n        auto t = new TypeInstance(loc, cast(TemplateInstance)tempinst.syntaxCopy(null));\n        t.syntaxCopyHelper(this);\n        t.mod = mod;\n        return t;\n    }\n\n    override Dsymbol toDsymbol(Scope* sc)\n    {\n        Type t;\n        Expression e;\n        Dsymbol s;\n        //printf(\"TypeInstance::semantic(%s)\\n\", toChars());\n        resolve(this, loc, sc, &e, &t, &s);\n        if (t && t.ty != Tinstance)\n            s = t.toDsymbol(sc);\n        return s;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeTypeof : TypeQualified\n{\n    Expression exp;\n    int inuse;\n\n    extern (D) this(const ref Loc loc, Expression exp)\n    {\n        super(Ttypeof, loc);\n        this.exp = exp;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"typeof\";\n    }\n\n    override Type syntaxCopy()\n    {\n        //printf(\"TypeTypeof::syntaxCopy() %s\\n\", toChars());\n        auto t = new TypeTypeof(loc, exp.syntaxCopy());\n        t.syntaxCopyHelper(this);\n        t.mod = mod;\n        return t;\n    }\n\n    override Dsymbol toDsymbol(Scope* sc)\n    {\n        //printf(\"TypeTypeof::toDsymbol('%s')\\n\", toChars());\n        Expression e;\n        Type t;\n        Dsymbol s;\n        resolve(this, loc, sc, &e, &t, &s);\n        return s;\n    }\n\n    override d_uns64 size(const ref Loc loc)\n    {\n        if (exp.type)\n            return exp.type.size(loc);\n        else\n            return TypeQualified.size(loc);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeReturn : TypeQualified\n{\n    extern (D) this(const ref Loc loc)\n    {\n        super(Treturn, loc);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"return\";\n    }\n\n    override Type syntaxCopy()\n    {\n        auto t = new TypeReturn(loc);\n        t.syntaxCopyHelper(this);\n        t.mod = mod;\n        return t;\n    }\n\n    override Dsymbol toDsymbol(Scope* sc)\n    {\n        Expression e;\n        Type t;\n        Dsymbol s;\n        resolve(this, loc, sc, &e, &t, &s);\n        return s;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n// Whether alias this dependency is recursive or not.\nenum AliasThisRec : int\n{\n    no           = 0,    // no alias this recursion\n    yes          = 1,    // alias this has recursive dependency\n    fwdref       = 2,    // not yet known\n    typeMask     = 3,    // mask to read no/yes/fwdref\n    tracing      = 0x4,  // mark in progress of implicitConvTo/deduceWild\n    tracingDT    = 0x8,  // mark in progress of deduceType\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeStruct : Type\n{\n    StructDeclaration sym;\n    AliasThisRec att = AliasThisRec.fwdref;\n    CPPMANGLE cppmangle = CPPMANGLE.def;\n\n    extern (D) this(StructDeclaration sym)\n    {\n        super(Tstruct);\n        this.sym = sym;\n    }\n\n    static TypeStruct create(StructDeclaration sym)\n    {\n        return new TypeStruct(sym);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"struct\";\n    }\n\n    override d_uns64 size(const ref Loc loc)\n    {\n        return sym.size(loc);\n    }\n\n    override uint alignsize()\n    {\n        sym.size(Loc.initial); // give error for forward references\n        return sym.alignsize;\n    }\n\n    override Type syntaxCopy()\n    {\n        return this;\n    }\n\n    override Dsymbol toDsymbol(Scope* sc)\n    {\n        return sym;\n    }\n\n    override structalign_t alignment()\n    {\n        if (sym.alignment == 0)\n            sym.size(sym.loc);\n        return sym.alignment;\n    }\n\n    /***************************************\n     * Use when we prefer the default initializer to be a literal,\n     * rather than a global immutable variable.\n     */\n    override Expression defaultInitLiteral(const ref Loc loc)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeStruct::defaultInitLiteral() '%s'\\n\", toChars());\n        }\n        sym.size(loc);\n        if (sym.sizeok != Sizeok.done)\n            return new ErrorExp();\n\n        auto structelems = new Expressions(sym.fields.dim - sym.isNested());\n        uint offset = 0;\n        for (size_t j = 0; j < structelems.dim; j++)\n        {\n            VarDeclaration vd = sym.fields[j];\n            Expression e;\n            if (vd.inuse)\n            {\n                error(loc, \"circular reference to `%s`\", vd.toPrettyChars());\n                return new ErrorExp();\n            }\n            if (vd.offset < offset || vd.type.size() == 0)\n                e = null;\n            else if (vd._init)\n            {\n                if (vd._init.isVoidInitializer())\n                    e = null;\n                else\n                    e = vd.getConstInitializer(false);\n            }\n            else\n                e = vd.type.defaultInitLiteral(loc);\n            if (e && e.op == TOK.error)\n                return e;\n            if (e)\n                offset = vd.offset + cast(uint)vd.type.size();\n            (*structelems)[j] = e;\n        }\n        auto structinit = new StructLiteralExp(loc, sym, structelems);\n\n        /* Copy from the initializer symbol for larger symbols,\n         * otherwise the literals expressed as code get excessively large.\n         */\n        if (size(loc) > Target.ptrsize * 4 && !needsNested())\n            structinit.useStaticInit = true;\n\n        structinit.type = this;\n        return structinit;\n    }\n\n    override bool isZeroInit(const ref Loc loc) const\n    {\n        return sym.zeroInit;\n    }\n\n    override bool isAssignable()\n    {\n        bool assignable = true;\n        uint offset = ~0; // dead-store initialize to prevent spurious warning\n\n        /* If any of the fields are const or immutable,\n         * then one cannot assign this struct.\n         */\n        for (size_t i = 0; i < sym.fields.dim; i++)\n        {\n            VarDeclaration v = sym.fields[i];\n            //printf(\"%s [%d] v = (%s) %s, v.offset = %d, v.parent = %s\", sym.toChars(), i, v.kind(), v.toChars(), v.offset, v.parent.kind());\n            if (i == 0)\n            {\n            }\n            else if (v.offset == offset)\n            {\n                /* If any fields of anonymous union are assignable,\n                 * then regard union as assignable.\n                 * This is to support unsafe things like Rebindable templates.\n                 */\n                if (assignable)\n                    continue;\n            }\n            else\n            {\n                if (!assignable)\n                    return false;\n            }\n            assignable = v.type.isMutable() && v.type.isAssignable();\n            offset = v.offset;\n            //printf(\" -> assignable = %d\\n\", assignable);\n        }\n\n        return assignable;\n    }\n\n    override bool isBoolean() const\n    {\n        return false;\n    }\n\n    override bool needsDestruction() const\n    {\n        return sym.dtor !is null;\n    }\n\n    override bool needsNested()\n    {\n        if (sym.isNested())\n            return true;\n\n        for (size_t i = 0; i < sym.fields.dim; i++)\n        {\n            VarDeclaration v = sym.fields[i];\n            if (!v.isDataseg() && v.type.needsNested())\n                return true;\n        }\n        return false;\n    }\n\n    override bool hasPointers()\n    {\n        // Probably should cache this information in sym rather than recompute\n        StructDeclaration s = sym;\n\n        sym.size(Loc.initial); // give error for forward references\n        foreach (VarDeclaration v; s.fields)\n        {\n            if (v.storage_class & STC.ref_ || v.hasPointers())\n                return true;\n        }\n        return false;\n    }\n\n    override bool hasVoidInitPointers()\n    {\n        // Probably should cache this information in sym rather than recompute\n        StructDeclaration s = sym;\n\n        sym.size(Loc.initial); // give error for forward references\n        foreach (VarDeclaration v; s.fields)\n        {\n            if (v._init && v._init.isVoidInitializer() && v.type.hasPointers())\n                return true;\n            if (!v._init && v.type.hasVoidInitPointers())\n                return true;\n        }\n        return false;\n    }\n\n    override MATCH implicitConvTo(Type to)\n    {\n        MATCH m;\n\n        //printf(\"TypeStruct::implicitConvTo(%s => %s)\\n\", toChars(), to.toChars());\n        if (ty == to.ty && sym == (cast(TypeStruct)to).sym)\n        {\n            m = MATCH.exact; // exact match\n            if (mod != to.mod)\n            {\n                m = MATCH.constant;\n                if (MODimplicitConv(mod, to.mod))\n                {\n                }\n                else\n                {\n                    /* Check all the fields. If they can all be converted,\n                     * allow the conversion.\n                     */\n                    uint offset = ~0; // dead-store to prevent spurious warning\n                    for (size_t i = 0; i < sym.fields.dim; i++)\n                    {\n                        VarDeclaration v = sym.fields[i];\n                        if (i == 0)\n                        {\n                        }\n                        else if (v.offset == offset)\n                        {\n                            if (m > MATCH.nomatch)\n                                continue;\n                        }\n                        else\n                        {\n                            if (m <= MATCH.nomatch)\n                                return m;\n                        }\n\n                        // 'from' type\n                        Type tvf = v.type.addMod(mod);\n\n                        // 'to' type\n                        Type tv = v.type.addMod(to.mod);\n\n                        // field match\n                        MATCH mf = tvf.implicitConvTo(tv);\n                        //printf(\"\\t%s => %s, match = %d\\n\", v.type.toChars(), tv.toChars(), mf);\n\n                        if (mf <= MATCH.nomatch)\n                            return mf;\n                        if (mf < m) // if field match is worse\n                            m = mf;\n                        offset = v.offset;\n                    }\n                }\n            }\n        }\n        else if (sym.aliasthis && !(att & AliasThisRec.tracing))\n        {\n            if (auto ato = aliasthisOf())\n            {\n                att = cast(AliasThisRec)(att | AliasThisRec.tracing);\n                m = ato.implicitConvTo(to);\n                att = cast(AliasThisRec)(att & ~AliasThisRec.tracing);\n            }\n            else\n                m = MATCH.nomatch; // no match\n        }\n        else\n            m = MATCH.nomatch; // no match\n        return m;\n    }\n\n    override MATCH constConv(Type to)\n    {\n        if (equals(to))\n            return MATCH.exact;\n        if (ty == to.ty && sym == (cast(TypeStruct)to).sym && MODimplicitConv(mod, to.mod))\n            return MATCH.constant;\n        return MATCH.nomatch;\n    }\n\n    override MOD deduceWild(Type t, bool isRef)\n    {\n        if (ty == t.ty && sym == (cast(TypeStruct)t).sym)\n            return Type.deduceWild(t, isRef);\n\n        ubyte wm = 0;\n\n        if (t.hasWild() && sym.aliasthis && !(att & AliasThisRec.tracing))\n        {\n            if (auto ato = aliasthisOf())\n            {\n                att = cast(AliasThisRec)(att | AliasThisRec.tracing);\n                wm = ato.deduceWild(t, isRef);\n                att = cast(AliasThisRec)(att & ~AliasThisRec.tracing);\n            }\n        }\n\n        return wm;\n    }\n\n    override Type toHeadMutable()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeEnum : Type\n{\n    EnumDeclaration sym;\n\n    extern (D) this(EnumDeclaration sym)\n    {\n        super(Tenum);\n        this.sym = sym;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"enum\";\n    }\n\n    override Type syntaxCopy()\n    {\n        return this;\n    }\n\n    override d_uns64 size(const ref Loc loc)\n    {\n        return sym.getMemtype(loc).size(loc);\n    }\n\n    override uint alignsize()\n    {\n        Type t = sym.getMemtype(Loc.initial);\n        if (t.ty == Terror)\n            return 4;\n        return t.alignsize();\n    }\n\n    override Dsymbol toDsymbol(Scope* sc)\n    {\n        return sym;\n    }\n\n    override bool isintegral()\n    {\n        return sym.getMemtype(Loc.initial).isintegral();\n    }\n\n    override bool isfloating()\n    {\n        return sym.getMemtype(Loc.initial).isfloating();\n    }\n\n    override bool isreal()\n    {\n        return sym.getMemtype(Loc.initial).isreal();\n    }\n\n    override bool isimaginary()\n    {\n        return sym.getMemtype(Loc.initial).isimaginary();\n    }\n\n    override bool iscomplex()\n    {\n        return sym.getMemtype(Loc.initial).iscomplex();\n    }\n\n    override bool isscalar()\n    {\n        return sym.getMemtype(Loc.initial).isscalar();\n    }\n\n    override bool isunsigned()\n    {\n        return sym.getMemtype(Loc.initial).isunsigned();\n    }\n\n    override bool isBoolean()\n    {\n        return sym.getMemtype(Loc.initial).isBoolean();\n    }\n\n    override bool isString()\n    {\n        return sym.getMemtype(Loc.initial).isString();\n    }\n\n    override bool isAssignable()\n    {\n        return sym.getMemtype(Loc.initial).isAssignable();\n    }\n\n    override bool needsDestruction()\n    {\n        return sym.getMemtype(Loc.initial).needsDestruction();\n    }\n\n    override bool needsNested()\n    {\n        return sym.getMemtype(Loc.initial).needsNested();\n    }\n\n    override MATCH implicitConvTo(Type to)\n    {\n        MATCH m;\n        //printf(\"TypeEnum::implicitConvTo()\\n\");\n        if (ty == to.ty && sym == (cast(TypeEnum)to).sym)\n            m = (mod == to.mod) ? MATCH.exact : MATCH.constant;\n        else if (sym.getMemtype(Loc.initial).implicitConvTo(to))\n            m = MATCH.convert; // match with conversions\n        else\n            m = MATCH.nomatch; // no match\n        return m;\n    }\n\n    override MATCH constConv(Type to)\n    {\n        if (equals(to))\n            return MATCH.exact;\n        if (ty == to.ty && sym == (cast(TypeEnum)to).sym && MODimplicitConv(mod, to.mod))\n            return MATCH.constant;\n        return MATCH.nomatch;\n    }\n\n    override Type toBasetype()\n    {\n        if (!sym.members && !sym.memtype)\n            return this;\n        auto tb = sym.getMemtype(Loc.initial).toBasetype();\n        return tb.castMod(mod);         // retain modifier bits from 'this'\n    }\n\n    override bool isZeroInit(const ref Loc loc)\n    {\n        return sym.getDefaultValue(loc).isBool(false);\n    }\n\n    override bool hasPointers()\n    {\n        return sym.getMemtype(Loc.initial).hasPointers();\n    }\n\n    override bool hasVoidInitPointers()\n    {\n        return sym.getMemtype(Loc.initial).hasVoidInitPointers();\n    }\n\n    override Type nextOf()\n    {\n        return sym.getMemtype(Loc.initial).nextOf();\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeClass : Type\n{\n    ClassDeclaration sym;\n    AliasThisRec att = AliasThisRec.fwdref;\n    CPPMANGLE cppmangle = CPPMANGLE.def;\n\n    extern (D) this(ClassDeclaration sym)\n    {\n        super(Tclass);\n        this.sym = sym;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"class\";\n    }\n\n    override d_uns64 size(const ref Loc loc) const\n    {\n        return Target.ptrsize;\n    }\n\n    override Type syntaxCopy()\n    {\n        return this;\n    }\n\n    override Dsymbol toDsymbol(Scope* sc)\n    {\n        return sym;\n    }\n\n    override inout(ClassDeclaration) isClassHandle() inout\n    {\n        return sym;\n    }\n\n    override bool isBaseOf(Type t, int* poffset)\n    {\n        if (t && t.ty == Tclass)\n        {\n            ClassDeclaration cd = (cast(TypeClass)t).sym;\n            if (sym.isBaseOf(cd, poffset))\n                return true;\n        }\n        return false;\n    }\n\n    override MATCH implicitConvTo(Type to)\n    {\n        //printf(\"TypeClass::implicitConvTo(to = '%s') %s\\n\", to.toChars(), toChars());\n        MATCH m = constConv(to);\n        if (m > MATCH.nomatch)\n            return m;\n\n        ClassDeclaration cdto = to.isClassHandle();\n        if (cdto)\n        {\n            //printf(\"TypeClass::implicitConvTo(to = '%s') %s, isbase = %d %d\\n\", to.toChars(), toChars(), cdto.isBaseInfoComplete(), sym.isBaseInfoComplete());\n            if (cdto.semanticRun < PASS.semanticdone && !cdto.isBaseInfoComplete())\n                cdto.dsymbolSemantic(null);\n            if (sym.semanticRun < PASS.semanticdone && !sym.isBaseInfoComplete())\n                sym.dsymbolSemantic(null);\n            if (cdto.isBaseOf(sym, null) && MODimplicitConv(mod, to.mod))\n            {\n                //printf(\"'to' is base\\n\");\n                return MATCH.convert;\n            }\n        }\n\n        m = MATCH.nomatch;\n        if (sym.aliasthis && !(att & AliasThisRec.tracing))\n        {\n            if (auto ato = aliasthisOf())\n            {\n                att = cast(AliasThisRec)(att | AliasThisRec.tracing);\n                m = ato.implicitConvTo(to);\n                att = cast(AliasThisRec)(att & ~AliasThisRec.tracing);\n            }\n        }\n\n        return m;\n    }\n\n    override MATCH constConv(Type to)\n    {\n        if (equals(to))\n            return MATCH.exact;\n        if (ty == to.ty && sym == (cast(TypeClass)to).sym && MODimplicitConv(mod, to.mod))\n            return MATCH.constant;\n\n        /* Conversion derived to const(base)\n         */\n        int offset = 0;\n        if (to.isBaseOf(this, &offset) && offset == 0 && MODimplicitConv(mod, to.mod))\n        {\n            // Disallow:\n            //  derived to base\n            //  inout(derived) to inout(base)\n            if (!to.isMutable() && !to.isWild())\n                return MATCH.convert;\n        }\n\n        return MATCH.nomatch;\n    }\n\n    override MOD deduceWild(Type t, bool isRef)\n    {\n        ClassDeclaration cd = t.isClassHandle();\n        if (cd && (sym == cd || cd.isBaseOf(sym, null)))\n            return Type.deduceWild(t, isRef);\n\n        ubyte wm = 0;\n\n        if (t.hasWild() && sym.aliasthis && !(att & AliasThisRec.tracing))\n        {\n            if (auto ato = aliasthisOf())\n            {\n                att = cast(AliasThisRec)(att | AliasThisRec.tracing);\n                wm = ato.deduceWild(t, isRef);\n                att = cast(AliasThisRec)(att & ~AliasThisRec.tracing);\n            }\n        }\n\n        return wm;\n    }\n\n    override Type toHeadMutable()\n    {\n        return this;\n    }\n\n    override bool isZeroInit(const ref Loc loc) const\n    {\n        return true;\n    }\n\n    override bool isscope() const\n    {\n        return sym.stack;\n    }\n\n    override bool isBoolean() const\n    {\n        return true;\n    }\n\n    override bool hasPointers() const\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeTuple : Type\n{\n    Parameters* arguments;  // types making up the tuple\n\n    extern (D) this(Parameters* arguments)\n    {\n        super(Ttuple);\n        //printf(\"TypeTuple(this = %p)\\n\", this);\n        this.arguments = arguments;\n        //printf(\"TypeTuple() %p, %s\\n\", this, toChars());\n        debug\n        {\n            if (arguments)\n            {\n                for (size_t i = 0; i < arguments.dim; i++)\n                {\n                    Parameter arg = (*arguments)[i];\n                    assert(arg && arg.type);\n                }\n            }\n        }\n    }\n\n    /****************\n     * Form TypeTuple from the types of the expressions.\n     * Assume exps[] is already tuple expanded.\n     */\n    extern (D) this(Expressions* exps)\n    {\n        super(Ttuple);\n        auto arguments = new Parameters();\n        if (exps)\n        {\n            arguments.setDim(exps.dim);\n            for (size_t i = 0; i < exps.dim; i++)\n            {\n                Expression e = (*exps)[i];\n                if (e.type.ty == Ttuple)\n                    e.error(\"cannot form tuple of tuples\");\n                auto arg = new Parameter(STC.undefined_, e.type, null, null, null);\n                (*arguments)[i] = arg;\n            }\n        }\n        this.arguments = arguments;\n        //printf(\"TypeTuple() %p, %s\\n\", this, toChars());\n    }\n\n    static TypeTuple create(Parameters* arguments)\n    {\n        return new TypeTuple(arguments);\n    }\n\n    /*******************************************\n     * Type tuple with 0, 1 or 2 types in it.\n     */\n    extern (D) this()\n    {\n        super(Ttuple);\n        arguments = new Parameters();\n    }\n\n    extern (D) this(Type t1)\n    {\n        super(Ttuple);\n        arguments = new Parameters();\n        arguments.push(new Parameter(0, t1, null, null, null));\n    }\n\n    extern (D) this(Type t1, Type t2)\n    {\n        super(Ttuple);\n        arguments = new Parameters();\n        arguments.push(new Parameter(0, t1, null, null, null));\n        arguments.push(new Parameter(0, t2, null, null, null));\n    }\n\n    override const(char)* kind() const\n    {\n        return \"tuple\";\n    }\n\n    override Type syntaxCopy()\n    {\n        Parameters* args = Parameter.arraySyntaxCopy(arguments);\n        Type t = new TypeTuple(args);\n        t.mod = mod;\n        return t;\n    }\n\n    override bool equals(RootObject o) const\n    {\n        Type t = cast(Type)o;\n        //printf(\"TypeTuple::equals(%s, %s)\\n\", toChars(), t.toChars());\n        if (this == t)\n            return true;\n        if (t.ty == Ttuple)\n        {\n            TypeTuple tt = cast(TypeTuple)t;\n            if (arguments.dim == tt.arguments.dim)\n            {\n                for (size_t i = 0; i < tt.arguments.dim; i++)\n                {\n                    const Parameter arg1 = (*arguments)[i];\n                    Parameter arg2 = (*tt.arguments)[i];\n                    if (!arg1.type.equals(arg2.type))\n                        return false;\n                }\n                return true;\n            }\n        }\n        return false;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * This is so we can slice a TypeTuple\n */\nextern (C++) final class TypeSlice : TypeNext\n{\n    Expression lwr;\n    Expression upr;\n\n    extern (D) this(Type next, Expression lwr, Expression upr)\n    {\n        super(Tslice, next);\n        //printf(\"TypeSlice[%s .. %s]\\n\", lwr.toChars(), upr.toChars());\n        this.lwr = lwr;\n        this.upr = upr;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"slice\";\n    }\n\n    override Type syntaxCopy()\n    {\n        Type t = new TypeSlice(next.syntaxCopy(), lwr.syntaxCopy(), upr.syntaxCopy());\n        t.mod = mod;\n        return t;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TypeNull : Type\n{\n    extern (D) this()\n    {\n        //printf(\"TypeNull %p\\n\", this);\n        super(Tnull);\n    }\n\n    override const(char)* kind() const\n    {\n        return \"null\";\n    }\n\n    override Type syntaxCopy()\n    {\n        // No semantic analysis done, no need to copy\n        return this;\n    }\n\n    override MATCH implicitConvTo(Type to)\n    {\n        //printf(\"TypeNull::implicitConvTo(this=%p, to=%p)\\n\", this, to);\n        //printf(\"from: %s\\n\", toChars());\n        //printf(\"to  : %s\\n\", to.toChars());\n        MATCH m = Type.implicitConvTo(to);\n        if (m != MATCH.nomatch)\n            return m;\n\n        // NULL implicitly converts to any pointer type or dynamic array\n        //if (type.ty == Tpointer && type.nextOf().ty == Tvoid)\n        {\n            Type tb = to.toBasetype();\n            if (tb.ty == Tnull || tb.ty == Tpointer || tb.ty == Tarray || tb.ty == Taarray || tb.ty == Tclass || tb.ty == Tdelegate)\n                return MATCH.constant;\n        }\n\n        return MATCH.nomatch;\n    }\n\n    override bool isBoolean() const\n    {\n        return true;\n    }\n\n    override d_uns64 size(const ref Loc loc) const\n    {\n        return tvoidptr.size(loc);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class Parameter : RootObject\n{\n    import dmd.attrib : UserAttributeDeclaration;\n\n    StorageClass storageClass;\n    Type type;\n    Identifier ident;\n    Expression defaultArg;\n    UserAttributeDeclaration userAttribDecl; // user defined attributes\n\n    extern (D) this(StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl)\n    {\n        this.type = type;\n        this.ident = ident;\n        this.storageClass = storageClass;\n        this.defaultArg = defaultArg;\n        this.userAttribDecl = userAttribDecl;\n    }\n\n    static Parameter create(StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl)\n    {\n        return new Parameter(storageClass, type, ident, defaultArg, userAttribDecl);\n    }\n\n    Parameter syntaxCopy()\n    {\n        return new Parameter(storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null, userAttribDecl ? cast(UserAttributeDeclaration) userAttribDecl.syntaxCopy(null) : null);\n    }\n\n    /****************************************************\n     * Determine if parameter is a lazy array of delegates.\n     * If so, return the return type of those delegates.\n     * If not, return NULL.\n     *\n     * Returns T if the type is one of the following forms:\n     *      T delegate()[]\n     *      T delegate()[dim]\n     */\n    Type isLazyArray()\n    {\n        Type tb = type.toBasetype();\n        if (tb.ty == Tsarray || tb.ty == Tarray)\n        {\n            Type tel = (cast(TypeArray)tb).next.toBasetype();\n            if (tel.ty == Tdelegate)\n            {\n                TypeDelegate td = cast(TypeDelegate)tel;\n                TypeFunction tf = td.next.toTypeFunction();\n                if (!tf.varargs && Parameter.dim(tf.parameters) == 0)\n                {\n                    return tf.next; // return type of delegate\n                }\n            }\n        }\n        return null;\n    }\n\n    // kludge for template.isType()\n    override DYNCAST dyncast() const\n    {\n        return DYNCAST.parameter;\n    }\n\n    void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    extern (D) static Parameters* arraySyntaxCopy(Parameters* parameters)\n    {\n        Parameters* params = null;\n        if (parameters)\n        {\n            params = new Parameters(parameters.dim);\n            for (size_t i = 0; i < params.dim; i++)\n                (*params)[i] = (*parameters)[i].syntaxCopy();\n        }\n        return params;\n    }\n\n    /***************************************\n     * Determine number of arguments, folding in tuples.\n     */\n    static size_t dim(Parameters* parameters)\n    {\n        size_t nargs = 0;\n\n        int dimDg(size_t n, Parameter p)\n        {\n            ++nargs;\n            return 0;\n        }\n\n        _foreach(parameters, &dimDg);\n        return nargs;\n    }\n\n    /***************************************\n     * Get nth Parameter, folding in tuples.\n     * Returns:\n     *      Parameter*      nth Parameter\n     *      NULL            not found, *pn gets incremented by the number\n     *                      of Parameters\n     */\n    static Parameter getNth(Parameters* parameters, size_t nth, size_t* pn = null)\n    {\n        Parameter param;\n\n        int getNthParamDg(size_t n, Parameter p)\n        {\n            if (n == nth)\n            {\n                param = p;\n                return 1;\n            }\n            return 0;\n        }\n\n        int res = _foreach(parameters, &getNthParamDg);\n        return res ? param : null;\n    }\n\n    alias ForeachDg = extern (D) int delegate(size_t paramidx, Parameter param);\n\n    /***************************************\n     * Expands tuples in args in depth first order. Calls\n     * dg(void *ctx, size_t argidx, Parameter *arg) for each Parameter.\n     * If dg returns !=0, stops and returns that value else returns 0.\n     * Use this function to avoid the O(N + N^2/2) complexity of\n     * calculating dim and calling N times getNth.\n     */\n    extern (D) static int _foreach(Parameters* parameters, scope ForeachDg dg, size_t* pn = null)\n    {\n        assert(dg);\n        if (!parameters)\n            return 0;\n\n        size_t n = pn ? *pn : 0; // take over index\n        int result = 0;\n        foreach (i; 0 .. parameters.dim)\n        {\n            Parameter p = (*parameters)[i];\n            Type t = p.type.toBasetype();\n\n            if (t.ty == Ttuple)\n            {\n                TypeTuple tu = cast(TypeTuple)t;\n                result = _foreach(tu.arguments, dg, &n);\n            }\n            else\n                result = dg(n++, p);\n\n            if (result)\n                break;\n        }\n\n        if (pn)\n            *pn = n; // update index\n        return result;\n    }\n\n    override const(char)* toChars() const\n    {\n        return ident ? ident.toChars() : \"__anonymous_param\";\n    }\n\n    /*********************************\n     * Compute covariance of parameters `this` and `p`\n     * as determined by the storage classes of both.\n     * Params:\n     *  returnByRef = true if the function returns by ref\n     *  p = Parameter to compare with\n     * Returns:\n     *  true = `this` can be used in place of `p`\n     *  false = nope\n     */\n    bool isCovariant(bool returnByRef, const Parameter p) const pure nothrow @nogc @safe\n    {\n        enum stc = STC.ref_ | STC.in_ | STC.out_ | STC.lazy_;\n        if ((this.storageClass & stc) != (p.storageClass & stc))\n            return false;\n        return isCovariantScope(returnByRef, this.storageClass, p.storageClass);\n    }\n\n    extern (D) private static bool isCovariantScope(bool returnByRef, StorageClass from, StorageClass to) pure nothrow @nogc @safe\n    {\n        if (from == to)\n            return true;\n\n        /* Shrinking the representation is necessary because StorageClass is so wide\n         * Params:\n         *   returnByRef = true if the function returns by ref\n         *   stc = storage class of parameter\n         */\n        static uint buildSR(bool returnByRef, StorageClass stc) pure nothrow @nogc @safe\n        {\n            uint result;\n            final switch (stc & (STC.ref_ | STC.scope_ | STC.return_))\n            {\n                case 0:                    result = SR.None;        break;\n                case STC.ref_:               result = SR.Ref;         break;\n                case STC.scope_:             result = SR.Scope;       break;\n                case STC.return_ | STC.ref_:   result = SR.ReturnRef;   break;\n                case STC.return_ | STC.scope_: result = SR.ReturnScope; break;\n                case STC.ref_    | STC.scope_: result = SR.RefScope;    break;\n                case STC.return_ | STC.ref_ | STC.scope_:\n                    result = returnByRef ? SR.ReturnRef_Scope : SR.Ref_ReturnScope;\n                    break;\n            }\n            return result;\n        }\n\n        /* result is true if the 'from' can be used as a 'to'\n         */\n\n        if ((from ^ to) & STC.ref_)               // differing in 'ref' means no covariance\n            return false;\n\n        return covariant[buildSR(returnByRef, from)][buildSR(returnByRef, to)];\n    }\n\n    /* Classification of 'scope-return-ref' possibilities\n     */\n    private enum SR\n    {\n        None,\n        Scope,\n        ReturnScope,\n        Ref,\n        ReturnRef,\n        RefScope,\n        ReturnRef_Scope,\n        Ref_ReturnScope,\n    }\n\n    extern (D) private static bool[SR.max + 1][SR.max + 1] covariantInit() pure nothrow @nogc @safe\n    {\n        /* Initialize covariant[][] with this:\n\n             From\\To           n   rs  s\n             None              X\n             ReturnScope       X   X\n             Scope             X   X   X\n\n             From\\To           r   rr  rs  rr-s r-rs\n             Ref               X   X\n             ReturnRef             X\n             RefScope          X   X   X   X    X\n             ReturnRef-Scope       X       X\n             Ref-ReturnScope   X   X            X\n        */\n        bool[SR.max + 1][SR.max + 1] covariant;\n\n        foreach (i; 0 .. SR.max + 1)\n        {\n            covariant[i][i] = true;\n            covariant[SR.RefScope][i] = true;\n        }\n        covariant[SR.ReturnScope][SR.None]        = true;\n        covariant[SR.Scope      ][SR.None]        = true;\n        covariant[SR.Scope      ][SR.ReturnScope] = true;\n\n        covariant[SR.Ref            ][SR.ReturnRef] = true;\n        covariant[SR.ReturnRef_Scope][SR.ReturnRef] = true;\n        covariant[SR.Ref_ReturnScope][SR.Ref      ] = true;\n        covariant[SR.Ref_ReturnScope][SR.ReturnRef] = true;\n\n        return covariant;\n    }\n\n    extern (D) private static immutable bool[SR.max + 1][SR.max + 1] covariant = covariantInit();\n}\n\n/*************************************************************\n * For printing two types with qualification when necessary.\n * Params:\n *    t1 = The first type to receive the type name for\n *    t2 = The second type to receive the type name for\n * Returns:\n *    The fully-qualified names of both types if the two type names are not the same,\n *    or the unqualified names of both types if the two type names are the same.\n */\nconst(char*)[2] toAutoQualChars(Type t1, Type t2)\n{\n    auto s1 = t1.toChars();\n    auto s2 = t2.toChars();\n    // show qualification only if it's different\n    if (!t1.equals(t2) && strcmp(s1, s2) == 0)\n    {\n        s1 = t1.toPrettyChars(true);\n        s2 = t2.toPrettyChars(true);\n    }\n    return [s1, s2];\n}\n\n\n/**\n * For each active modifier (MODFlags.const_, MODFlags.immutable_, etc) call `fp` with a\n * void* for the work param and a string representation of the attribute.\n */\nint modifiersApply(TypeFunction tf, void* param, int function(void*, string) fp)\n{\n    immutable ubyte[4] modsArr = [MODFlags.const_, MODFlags.immutable_, MODFlags.wild, MODFlags.shared_];\n\n    foreach (modsarr; modsArr)\n    {\n        if (tf.mod & modsarr)\n        {\n            if (int res = fp(param, MODtoString(modsarr)))\n                return res;\n        }\n    }\n\n    return 0;\n}\n\n/**\n * For each active attribute (ref/const/nogc/etc) call `fp` with a void* for the\n * work param and a string representation of the attribute.\n */\nint attributesApply(TypeFunction tf, void* param, int function(void*, string) fp, TRUSTformat trustFormat = TRUSTformatDefault)\n{\n    int res = 0;\n    if (tf.purity)\n        res = fp(param, \"pure\");\n    if (res)\n        return res;\n\n    if (tf.isnothrow)\n        res = fp(param, \"nothrow\");\n    if (res)\n        return res;\n\n    if (tf.isnogc)\n        res = fp(param, \"@nogc\");\n    if (res)\n        return res;\n\n    if (tf.isproperty)\n        res = fp(param, \"@property\");\n    if (res)\n        return res;\n\n    if (tf.isref)\n        res = fp(param, \"ref\");\n    if (res)\n        return res;\n\n    if (tf.isreturn)\n        res = fp(param, \"return\");\n    if (res)\n        return res;\n\n    if (tf.isscope && !tf.isscopeinferred)\n        res = fp(param, \"scope\");\n    if (res)\n        return res;\n\n    TRUST trustAttrib = tf.trust;\n\n    if (trustAttrib == TRUST.default_)\n    {\n        // Print out \"@system\" when trust equals TRUST.default_ (if desired).\n        if (trustFormat == TRUSTformatSystem)\n            trustAttrib = TRUST.system;\n        else\n            return res; // avoid calling with an empty string\n    }\n\n    return fp(param, trustToString(trustAttrib));\n}\n"
  },
  {
    "path": "gcc/d/dmd/mtype.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/mtype.h\n */\n\n#pragma once\n\n#include \"root/rmem.h\" // for d_size_t\n\n#include \"arraytypes.h\"\n#include \"globals.h\"\n#include \"visitor.h\"\n\nstruct Scope;\nclass Identifier;\nclass Expression;\nclass StructDeclaration;\nclass ClassDeclaration;\nclass EnumDeclaration;\nclass TypeInfoDeclaration;\nclass Dsymbol;\nclass TemplateInstance;\nclass TemplateDeclaration;\n\nclass TypeBasic;\nclass Parameter;\n\n// Back end\n#ifdef IN_GCC\ntypedef union tree_node type;\n#else\ntypedef struct TYPE type;\n#endif\n\nvoid semanticTypeInfo(Scope *sc, Type *t);\nMATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm = NULL, size_t inferStart = 0);\nStorageClass ModToStc(unsigned mod);\n\nenum ENUMTY\n{\n    Tarray,             // slice array, aka T[]\n    Tsarray,            // static array, aka T[dimension]\n    Taarray,            // associative array, aka T[type]\n    Tpointer,\n    Treference,\n    Tfunction,\n    Tident,\n    Tclass,\n    Tstruct,\n    Tenum,\n\n    Tdelegate,\n    Tnone,\n    Tvoid,\n    Tint8,\n    Tuns8,\n    Tint16,\n    Tuns16,\n    Tint32,\n    Tuns32,\n    Tint64,\n\n    Tuns64,\n    Tfloat32,\n    Tfloat64,\n    Tfloat80,\n    Timaginary32,\n    Timaginary64,\n    Timaginary80,\n    Tcomplex32,\n    Tcomplex64,\n    Tcomplex80,\n\n    Tbool,\n    Tchar,\n    Twchar,\n    Tdchar,\n    Terror,\n    Tinstance,\n    Ttypeof,\n    Ttuple,\n    Tslice,\n    Treturn,\n\n    Tnull,\n    Tvector,\n    Tint128,\n    Tuns128,\n    TMAX\n};\ntypedef unsigned char TY;       // ENUMTY\n\nextern int Tsize_t;\nextern int Tptrdiff_t;\n\n#define SIZE_INVALID (~(d_uns64)0)   // error return from size() functions\n\n\n/**\n * type modifiers\n * pick this order of numbers so switch statements work better\n */\nenum MODFlags\n{\n    MODconst     = 1, // type is const\n    MODimmutable = 4, // type is immutable\n    MODshared    = 2, // type is shared\n    MODwild      = 8, // type is wild\n    MODwildconst = (MODwild | MODconst), // type is wild const\n    MODmutable   = 0x10       // type is mutable (only used in wildcard matching)\n};\ntypedef unsigned char MOD;\n\n// These tables are for implicit conversion of binary ops;\n// the indices are the type of operand one, followed by operand two.\nextern unsigned char impcnvResult[TMAX][TMAX];\nextern unsigned char impcnvType1[TMAX][TMAX];\nextern unsigned char impcnvType2[TMAX][TMAX];\n\n// If !=0, give warning on implicit conversion\nextern unsigned char impcnvWarn[TMAX][TMAX];\n\nclass Type : public RootObject\n{\npublic:\n    TY ty;\n    MOD mod;  // modifiers MODxxxx\n    char *deco;\n\n    /* These are cached values that are lazily evaluated by constOf(), immutableOf(), etc.\n     * They should not be referenced by anybody but mtype.c.\n     * They can be NULL if not lazily evaluated yet.\n     * Note that there is no \"shared immutable\", because that is just immutable\n     * Naked == no MOD bits\n     */\n\n    Type *cto;          // MODconst                 ? naked version of this type : const version\n    Type *ito;          // MODimmutable             ? naked version of this type : immutable version\n    Type *sto;          // MODshared                ? naked version of this type : shared mutable version\n    Type *scto;         // MODshared | MODconst     ? naked version of this type : shared const version\n    Type *wto;          // MODwild                  ? naked version of this type : wild version\n    Type *wcto;         // MODwildconst             ? naked version of this type : wild const version\n    Type *swto;         // MODshared | MODwild      ? naked version of this type : shared wild version\n    Type *swcto;        // MODshared | MODwildconst ? naked version of this type : shared wild const version\n\n    Type *pto;          // merged pointer to this type\n    Type *rto;          // reference to this type\n    Type *arrayof;      // array of this type\n    TypeInfoDeclaration *vtinfo;        // TypeInfo object for this Type\n\n    type *ctype;        // for back end\n\n    static Type *tvoid;\n    static Type *tint8;\n    static Type *tuns8;\n    static Type *tint16;\n    static Type *tuns16;\n    static Type *tint32;\n    static Type *tuns32;\n    static Type *tint64;\n    static Type *tuns64;\n    static Type *tint128;\n    static Type *tuns128;\n    static Type *tfloat32;\n    static Type *tfloat64;\n    static Type *tfloat80;\n\n    static Type *timaginary32;\n    static Type *timaginary64;\n    static Type *timaginary80;\n\n    static Type *tcomplex32;\n    static Type *tcomplex64;\n    static Type *tcomplex80;\n\n    static Type *tbool;\n    static Type *tchar;\n    static Type *twchar;\n    static Type *tdchar;\n\n    // Some special types\n    static Type *tshiftcnt;\n    static Type *tvoidptr;              // void*\n    static Type *tstring;               // immutable(char)[]\n    static Type *twstring;              // immutable(wchar)[]\n    static Type *tdstring;              // immutable(dchar)[]\n    static Type *tvalist;               // va_list alias\n    static Type *terror;                // for error recovery\n    static Type *tnull;                 // for null type\n\n    static Type *tsize_t;               // matches size_t alias\n    static Type *tptrdiff_t;            // matches ptrdiff_t alias\n    static Type *thash_t;               // matches hash_t alias\n\n    static ClassDeclaration *dtypeinfo;\n    static ClassDeclaration *typeinfoclass;\n    static ClassDeclaration *typeinfointerface;\n    static ClassDeclaration *typeinfostruct;\n    static ClassDeclaration *typeinfopointer;\n    static ClassDeclaration *typeinfoarray;\n    static ClassDeclaration *typeinfostaticarray;\n    static ClassDeclaration *typeinfoassociativearray;\n    static ClassDeclaration *typeinfovector;\n    static ClassDeclaration *typeinfoenum;\n    static ClassDeclaration *typeinfofunction;\n    static ClassDeclaration *typeinfodelegate;\n    static ClassDeclaration *typeinfotypelist;\n    static ClassDeclaration *typeinfoconst;\n    static ClassDeclaration *typeinfoinvariant;\n    static ClassDeclaration *typeinfoshared;\n    static ClassDeclaration *typeinfowild;\n\n    static TemplateDeclaration *rtinfo;\n\n    static Type *basic[TMAX];\n\n    virtual const char *kind();\n    Type *copy();\n    virtual Type *syntaxCopy();\n    bool equals(RootObject *o);\n    bool equivalent(Type *t);\n    // kludge for template.isType()\n    int dyncast() const { return DYNCAST_TYPE; }\n    int covariant(Type *t, StorageClass *pstc = NULL, bool fix17349 = true);\n    const char *toChars();\n    char *toPrettyChars(bool QualifyTypes = false);\n    static void _init();\n\n    d_uns64 size();\n    virtual d_uns64 size(const Loc &loc);\n    virtual unsigned alignsize();\n    Type *trySemantic(const Loc &loc, Scope *sc);\n    Type *merge2();\n    void modToBuffer(OutBuffer *buf);\n    char *modToChars();\n\n    virtual bool isintegral();\n    virtual bool isfloating();   // real, imaginary, or complex\n    virtual bool isreal();\n    virtual bool isimaginary();\n    virtual bool iscomplex();\n    virtual bool isscalar();\n    virtual bool isunsigned();\n    virtual bool isscope();\n    virtual bool isString();\n    virtual bool isAssignable();\n    virtual bool isBoolean();\n    virtual void checkDeprecated(const Loc &loc, Scope *sc);\n    bool isConst() const       { return (mod & MODconst) != 0; }\n    bool isImmutable() const   { return (mod & MODimmutable) != 0; }\n    bool isMutable() const     { return (mod & (MODconst | MODimmutable | MODwild)) == 0; }\n    bool isShared() const      { return (mod & MODshared) != 0; }\n    bool isSharedConst() const { return (mod & (MODshared | MODconst)) == (MODshared | MODconst); }\n    bool isWild() const        { return (mod & MODwild) != 0; }\n    bool isWildConst() const   { return (mod & MODwildconst) == MODwildconst; }\n    bool isSharedWild() const  { return (mod & (MODshared | MODwild)) == (MODshared | MODwild); }\n    bool isNaked() const       { return mod == 0; }\n    Type *nullAttributes();\n    Type *constOf();\n    Type *immutableOf();\n    Type *mutableOf();\n    Type *sharedOf();\n    Type *sharedConstOf();\n    Type *unSharedOf();\n    Type *wildOf();\n    Type *wildConstOf();\n    Type *sharedWildOf();\n    Type *sharedWildConstOf();\n    void fixTo(Type *t);\n    void check();\n    Type *addSTC(StorageClass stc);\n    Type *castMod(MOD mod);\n    Type *addMod(MOD mod);\n    virtual Type *addStorageClass(StorageClass stc);\n    Type *pointerTo();\n    Type *referenceTo();\n    Type *arrayOf();\n    Type *sarrayOf(dinteger_t dim);\n    Type *aliasthisOf();\n    virtual Type *makeConst();\n    virtual Type *makeImmutable();\n    virtual Type *makeShared();\n    virtual Type *makeSharedConst();\n    virtual Type *makeWild();\n    virtual Type *makeWildConst();\n    virtual Type *makeSharedWild();\n    virtual Type *makeSharedWildConst();\n    virtual Type *makeMutable();\n    virtual Dsymbol *toDsymbol(Scope *sc);\n    virtual Type *toBasetype();\n    virtual bool isBaseOf(Type *t, int *poffset);\n    virtual MATCH implicitConvTo(Type *to);\n    virtual MATCH constConv(Type *to);\n    virtual unsigned char deduceWild(Type *t, bool isRef);\n    virtual Type *substWildTo(unsigned mod);\n\n    Type *unqualify(unsigned m);\n\n    virtual Type *toHeadMutable();\n    virtual ClassDeclaration *isClassHandle();\n    virtual structalign_t alignment();\n    virtual Expression *defaultInitLiteral(const Loc &loc);\n    virtual bool isZeroInit(const Loc &loc = Loc());                // if initializer is 0\n    Identifier *getTypeInfoIdent();\n    void resolveExp(Expression *e, Type **pt, Expression **pe, Dsymbol **ps);\n    virtual int hasWild() const;\n    virtual bool hasPointers();\n    virtual bool hasVoidInitPointers();\n    virtual Type *nextOf();\n    Type *baseElemOf();\n    uinteger_t sizemask();\n    virtual bool needsDestruction();\n    virtual bool needsNested();\n\n    // For eliminating dynamic_cast\n    virtual TypeBasic *isTypeBasic();\n    virtual void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeError : public Type\n{\npublic:\n    Type *syntaxCopy();\n\n    d_uns64 size(const Loc &loc);\n    Expression *defaultInitLiteral(const Loc &loc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeNext : public Type\n{\npublic:\n    Type *next;\n\n    void checkDeprecated(const Loc &loc, Scope *sc);\n    int hasWild() const;\n    Type *nextOf();\n    Type *makeConst();\n    Type *makeImmutable();\n    Type *makeShared();\n    Type *makeSharedConst();\n    Type *makeWild();\n    Type *makeWildConst();\n    Type *makeSharedWild();\n    Type *makeSharedWildConst();\n    Type *makeMutable();\n    MATCH constConv(Type *to);\n    unsigned char deduceWild(Type *t, bool isRef);\n    void transitive();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeBasic : public Type\n{\npublic:\n    const char *dstring;\n    unsigned flags;\n\n    const char *kind();\n    Type *syntaxCopy();\n    d_uns64 size(const Loc &loc) /*const*/;\n    unsigned alignsize();\n    bool isintegral();\n    bool isfloating() /*const*/;\n    bool isreal() /*const*/;\n    bool isimaginary() /*const*/;\n    bool iscomplex() /*const*/;\n    bool isscalar() /*const*/;\n    bool isunsigned() /*const*/;\n    MATCH implicitConvTo(Type *to);\n    bool isZeroInit(const Loc &loc) /*const*/;\n\n    // For eliminating dynamic_cast\n    TypeBasic *isTypeBasic();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeVector : public Type\n{\npublic:\n    Type *basetype;\n\n    static TypeVector *create(Type *basetype);\n    const char *kind();\n    Type *syntaxCopy();\n    d_uns64 size(const Loc &loc);\n    unsigned alignsize();\n    bool isintegral();\n    bool isfloating();\n    bool isscalar();\n    bool isunsigned();\n    bool isBoolean() /*const*/;\n    MATCH implicitConvTo(Type *to);\n    Expression *defaultInitLiteral(const Loc &loc);\n    TypeBasic *elementType();\n    bool isZeroInit(const Loc &loc);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeArray : public TypeNext\n{\npublic:\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// Static array, one with a fixed dimension\nclass TypeSArray : public TypeArray\n{\npublic:\n    Expression *dim;\n\n    const char *kind();\n    Type *syntaxCopy();\n    d_uns64 size(const Loc &loc);\n    unsigned alignsize();\n    bool isString();\n    bool isZeroInit(const Loc &loc);\n    structalign_t alignment();\n    MATCH constConv(Type *to);\n    MATCH implicitConvTo(Type *to);\n    Expression *defaultInitLiteral(const Loc &loc);\n    bool hasPointers();\n    bool needsDestruction();\n    bool needsNested();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// Dynamic array, no dimension\nclass TypeDArray : public TypeArray\n{\npublic:\n    const char *kind();\n    Type *syntaxCopy();\n    d_uns64 size(const Loc &loc) /*const*/;\n    unsigned alignsize() /*const*/;\n    bool isString();\n    bool isZeroInit(const Loc &loc) /*const*/;\n    bool isBoolean() /*const*/;\n    MATCH implicitConvTo(Type *to);\n    bool hasPointers() /*const*/;\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeAArray : public TypeArray\n{\npublic:\n    Type *index;                // key type\n    Loc loc;\n    Scope *sc;\n\n    static TypeAArray *create(Type *t, Type *index);\n    const char *kind();\n    Type *syntaxCopy();\n    d_uns64 size(const Loc &loc);\n    bool isZeroInit(const Loc &loc) /*const*/;\n    bool isBoolean() /*const*/;\n    bool hasPointers() /*const*/;\n    MATCH implicitConvTo(Type *to);\n    MATCH constConv(Type *to);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypePointer : public TypeNext\n{\npublic:\n    static TypePointer *create(Type *t);\n    const char *kind();\n    Type *syntaxCopy();\n    d_uns64 size(const Loc &loc) /*const*/;\n    MATCH implicitConvTo(Type *to);\n    MATCH constConv(Type *to);\n    bool isscalar() /*const*/;\n    bool isZeroInit(const Loc &loc) /*const*/;\n    bool hasPointers() /*const*/;\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeReference : public TypeNext\n{\npublic:\n    const char *kind();\n    Type *syntaxCopy();\n    d_uns64 size(const Loc &loc) /*const*/;\n    bool isZeroInit(const Loc &loc) /*const*/;\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nenum RET\n{\n    RETregs     = 1,    // returned in registers\n    RETstack    = 2     // returned on stack\n};\n\nenum TRUST\n{\n    TRUSTdefault = 0,\n    TRUSTsystem = 1,    // @system (same as TRUSTdefault)\n    TRUSTtrusted = 2,   // @trusted\n    TRUSTsafe = 3       // @safe\n};\n\nenum TRUSTformat\n{\n    TRUSTformatDefault,  // do not emit @system when trust == TRUSTdefault\n    TRUSTformatSystem    // emit @system when trust == TRUSTdefault\n};\n\nenum PURE\n{\n    PUREimpure = 0,     // not pure at all\n    PUREfwdref = 1,     // it's pure, but not known which level yet\n    PUREweak = 2,       // no mutable globals are read or written\n    PUREconst = 3,      // parameters are values or const\n    PUREstrong = 4      // parameters are values or immutable\n};\n\nclass TypeFunction : public TypeNext\n{\npublic:\n    // .next is the return type\n\n    Parameters *parameters;     // function parameters\n    int varargs;        // 1: T t, ...) style for variable number of arguments\n                        // 2: T t ...) style for variable number of arguments\n    bool isnothrow;     // true: nothrow\n    bool isnogc;        // true: is @nogc\n    bool isproperty;    // can be called without parentheses\n    bool isref;         // true: returns a reference\n    bool isreturn;      // true: 'this' is returned by ref\n    bool isscope;       // true: 'this' is scope\n    bool isscopeinferred; // true: 'this' is scope from inference\n    LINK linkage;  // calling convention\n    TRUST trust;   // level of trust\n    PURE purity;   // PURExxxx\n    unsigned char iswild;   // bit0: inout on params, bit1: inout on qualifier\n    Expressions *fargs; // function arguments\n\n    int inuse;\n\n    static TypeFunction *create(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc = 0);\n    const char *kind();\n    Type *syntaxCopy();\n    void purityLevel();\n    bool hasLazyParameters();\n    bool parameterEscapes(Parameter *p);\n    StorageClass parameterStorageClass(Parameter *p);\n    Type *addStorageClass(StorageClass stc);\n\n    Type *substWildTo(unsigned mod);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeDelegate : public TypeNext\n{\npublic:\n    // .next is a TypeFunction\n\n    static TypeDelegate *create(Type *t);\n    const char *kind();\n    Type *syntaxCopy();\n    Type *addStorageClass(StorageClass stc);\n    d_uns64 size(const Loc &loc) /*const*/;\n    unsigned alignsize() /*const*/;\n    MATCH implicitConvTo(Type *to);\n    bool isZeroInit(const Loc &loc) /*const*/;\n    bool isBoolean() /*const*/;\n    bool hasPointers() /*const*/;\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeQualified : public Type\n{\npublic:\n    Loc loc;\n    // array of Identifier and TypeInstance,\n    // representing ident.ident!tiargs.ident. ... etc.\n    Objects idents;\n\n    void syntaxCopyHelper(TypeQualified *t);\n    void addIdent(Identifier *ident);\n    void addInst(TemplateInstance *inst);\n    void addIndex(RootObject *expr);\n    d_uns64 size(const Loc &loc);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeIdentifier : public TypeQualified\n{\npublic:\n    Identifier *ident;\n    Dsymbol *originalSymbol; // The symbol representing this identifier, before alias resolution\n\n    const char *kind();\n    Type *syntaxCopy();\n    Dsymbol *toDsymbol(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/* Similar to TypeIdentifier, but with a TemplateInstance as the root\n */\nclass TypeInstance : public TypeQualified\n{\npublic:\n    TemplateInstance *tempinst;\n\n    const char *kind();\n    Type *syntaxCopy();\n    Dsymbol *toDsymbol(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeTypeof : public TypeQualified\n{\npublic:\n    Expression *exp;\n    int inuse;\n\n    const char *kind();\n    Type *syntaxCopy();\n    Dsymbol *toDsymbol(Scope *sc);\n    d_uns64 size(const Loc &loc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeReturn : public TypeQualified\n{\npublic:\n    const char *kind();\n    Type *syntaxCopy();\n    Dsymbol *toDsymbol(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// Whether alias this dependency is recursive or not.\nenum AliasThisRec\n{\n    RECno = 0,      // no alias this recursion\n    RECyes = 1,     // alias this has recursive dependency\n    RECfwdref = 2,  // not yet known\n    RECtypeMask = 3,// mask to read no/yes/fwdref\n\n    RECtracing = 0x4, // mark in progress of implicitConvTo/deduceWild\n    RECtracingDT = 0x8  // mark in progress of deduceType\n};\n\nclass TypeStruct : public Type\n{\npublic:\n    StructDeclaration *sym;\n    AliasThisRec att;\n    CPPMANGLE cppmangle;\n\n    static TypeStruct *create(StructDeclaration *sym);\n    const char *kind();\n    d_uns64 size(const Loc &loc);\n    unsigned alignsize();\n    Type *syntaxCopy();\n    Dsymbol *toDsymbol(Scope *sc);\n    structalign_t alignment();\n    Expression *defaultInitLiteral(const Loc &loc);\n    bool isZeroInit(const Loc &loc) /*const*/;\n    bool isAssignable();\n    bool isBoolean() /*const*/;\n    bool needsDestruction() /*const*/;\n    bool needsNested();\n    bool hasPointers();\n    bool hasVoidInitPointers();\n    MATCH implicitConvTo(Type *to);\n    MATCH constConv(Type *to);\n    unsigned char deduceWild(Type *t, bool isRef);\n    Type *toHeadMutable();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeEnum : public Type\n{\npublic:\n    EnumDeclaration *sym;\n\n    const char *kind();\n    Type *syntaxCopy();\n    d_uns64 size(const Loc &loc);\n    unsigned alignsize();\n    Dsymbol *toDsymbol(Scope *sc);\n    bool isintegral();\n    bool isfloating();\n    bool isreal();\n    bool isimaginary();\n    bool iscomplex();\n    bool isscalar();\n    bool isunsigned();\n    bool isBoolean();\n    bool isString();\n    bool isAssignable();\n    bool needsDestruction();\n    bool needsNested();\n    MATCH implicitConvTo(Type *to);\n    MATCH constConv(Type *to);\n    Type *toBasetype();\n    bool isZeroInit(const Loc &loc);\n    bool hasPointers();\n    bool hasVoidInitPointers();\n    Type *nextOf();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeClass : public Type\n{\npublic:\n    ClassDeclaration *sym;\n    AliasThisRec att;\n    CPPMANGLE cppmangle;\n\n    const char *kind();\n    d_uns64 size(const Loc &loc) /*const*/;\n    Type *syntaxCopy();\n    Dsymbol *toDsymbol(Scope *sc);\n    ClassDeclaration *isClassHandle();\n    bool isBaseOf(Type *t, int *poffset);\n    MATCH implicitConvTo(Type *to);\n    MATCH constConv(Type *to);\n    unsigned char deduceWild(Type *t, bool isRef);\n    Type *toHeadMutable();\n    bool isZeroInit(const Loc &loc) /*const*/;\n    bool isscope() /*const*/;\n    bool isBoolean() /*const*/;\n    bool hasPointers() /*const*/;\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeTuple : public Type\n{\npublic:\n    Parameters *arguments;      // types making up the tuple\n\n    static TypeTuple *create(Parameters *arguments);\n    const char *kind();\n    Type *syntaxCopy();\n    bool equals(RootObject *o);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeSlice : public TypeNext\n{\npublic:\n    Expression *lwr;\n    Expression *upr;\n\n    const char *kind();\n    Type *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TypeNull : public Type\n{\npublic:\n    const char *kind();\n\n    Type *syntaxCopy();\n    MATCH implicitConvTo(Type *to);\n    bool isBoolean() /*const*/;\n\n    d_uns64 size(const Loc &loc) /*const*/;\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/**************************************************************/\n\n//enum InOut { None, In, Out, InOut, Lazy };\n\nclass Parameter : public RootObject\n{\npublic:\n    //enum InOut inout;\n    StorageClass storageClass;\n    Type *type;\n    Identifier *ident;\n    Expression *defaultArg;\n    UserAttributeDeclaration *userAttribDecl;   // user defined attributes\n\n    static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident,\n                             Expression *defaultArg, UserAttributeDeclaration *userAttribDecl);\n    Parameter *syntaxCopy();\n    Type *isLazyArray();\n    // kludge for template.isType()\n    int dyncast() const { return DYNCAST_PARAMETER; }\n    virtual void accept(Visitor *v) { v->visit(this); }\n\n    static size_t dim(Parameters *parameters);\n    static Parameter *getNth(Parameters *parameters, d_size_t nth, d_size_t *pn = NULL);\n    const char *toChars();\n    bool isCovariant(bool returnByRef, const Parameter *p) const;\n};\n\nbool arrayTypeCompatible(Loc loc, Type *t1, Type *t2);\nbool arrayTypeCompatibleWithoutCasting(Type *t1, Type *t2);\n"
  },
  {
    "path": "gcc/d/dmd/nogc.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/nogc.d, _nogc.d)\n * Documentation:  https://dlang.org/phobos/dmd_nogc.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/nogc.d\n */\n\nmodule dmd.nogc;\n\nimport dmd.aggregate;\nimport dmd.apply;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.expression;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.init;\nimport dmd.mtype;\nimport dmd.tokens;\nimport dmd.visitor;\n\n/**************************************\n * Look for GC-allocations\n */\nextern (C++) final class NOGCVisitor : StoppableVisitor\n{\n    alias visit = typeof(super).visit;\npublic:\n    FuncDeclaration f;\n    bool err;\n\n    extern (D) this(FuncDeclaration f)\n    {\n        this.f = f;\n    }\n\n    void doCond(Expression exp)\n    {\n        if (exp)\n            walkPostorder(exp, this);\n    }\n\n    override void visit(Expression e)\n    {\n    }\n\n    override void visit(DeclarationExp e)\n    {\n        // Note that, walkPostorder does not support DeclarationExp today.\n        VarDeclaration v = e.declaration.isVarDeclaration();\n        if (v && !(v.storage_class & STC.manifest) && !v.isDataseg() && v._init)\n        {\n            if (ExpInitializer ei = v._init.isExpInitializer())\n            {\n                doCond(ei.exp);\n            }\n        }\n    }\n\n    override void visit(CallExp e)\n    {\n    }\n\n    override void visit(ArrayLiteralExp e)\n    {\n        if (e.type.ty != Tarray || !e.elements || !e.elements.dim)\n            return;\n        if (f.setGC())\n        {\n            e.error(\"array literal in `@nogc` %s `%s` may cause a GC allocation\",\n                f.kind(), f.toPrettyChars());\n            err = true;\n            return;\n        }\n        f.printGCUsage(e.loc, \"array literal may cause a GC allocation\");\n    }\n\n    override void visit(AssocArrayLiteralExp e)\n    {\n        if (!e.keys.dim)\n            return;\n        if (f.setGC())\n        {\n            e.error(\"associative array literal in `@nogc` %s `%s` may cause a GC allocation\",\n                f.kind(), f.toPrettyChars());\n            err = true;\n            return;\n        }\n        f.printGCUsage(e.loc, \"associative array literal may cause a GC allocation\");\n    }\n\n    override void visit(NewExp e)\n    {\n        if (e.member && !e.member.isNogc() && f.setGC())\n        {\n            // @nogc-ness is already checked in NewExp::semantic\n            return;\n        }\n        if (e.onstack)\n            return;\n        if (e.allocator)\n            return;\n        if (global.params.ehnogc && e.thrownew)\n            return;                     // separate allocator is called for this, not the GC\n        if (f.setGC())\n        {\n            e.error(\"cannot use `new` in `@nogc` %s `%s`\",\n                f.kind(), f.toPrettyChars());\n            err = true;\n            return;\n        }\n        f.printGCUsage(e.loc, \"`new` causes a GC allocation\");\n    }\n\n    override void visit(DeleteExp e)\n    {\n        if (e.e1.op == TOK.variable)\n        {\n            VarDeclaration v = (cast(VarExp)e.e1).var.isVarDeclaration();\n            if (v && v.onstack)\n                return; // delete for scope allocated class object\n        }\n\n        Type tb = e.e1.type.toBasetype();\n        AggregateDeclaration ad = null;\n        switch (tb.ty)\n        {\n        case Tclass:\n            ad = (cast(TypeClass)tb).sym;\n            break;\n\n        case Tpointer:\n            tb = (cast(TypePointer)tb).next.toBasetype();\n            if (tb.ty == Tstruct)\n                ad = (cast(TypeStruct)tb).sym;\n            break;\n\n        default:\n            break;\n        }\n        if (ad && ad.aggDelete)\n            return;\n\n        if (f.setGC())\n        {\n            e.error(\"cannot use `delete` in `@nogc` %s `%s`\",\n                f.kind(), f.toPrettyChars());\n            err = true;\n            return;\n        }\n        f.printGCUsage(e.loc, \"`delete` requires the GC\");\n    }\n\n    override void visit(IndexExp e)\n    {\n        Type t1b = e.e1.type.toBasetype();\n        if (t1b.ty == Taarray)\n        {\n            if (f.setGC())\n            {\n                e.error(\"indexing an associative array in `@nogc` %s `%s` may cause a GC allocation\",\n                    f.kind(), f.toPrettyChars());\n                err = true;\n                return;\n            }\n            f.printGCUsage(e.loc, \"indexing an associative array may cause a GC allocation\");\n        }\n    }\n\n    override void visit(AssignExp e)\n    {\n        if (e.e1.op == TOK.arrayLength)\n        {\n            if (f.setGC())\n            {\n                e.error(\"setting `length` in `@nogc` %s `%s` may cause a GC allocation\",\n                    f.kind(), f.toPrettyChars());\n                err = true;\n                return;\n            }\n            f.printGCUsage(e.loc, \"setting `length` may cause a GC allocation\");\n        }\n    }\n\n    override void visit(CatAssignExp e)\n    {\n        if (f.setGC())\n        {\n            e.error(\"cannot use operator `~=` in `@nogc` %s `%s`\",\n                f.kind(), f.toPrettyChars());\n            err = true;\n            return;\n        }\n        f.printGCUsage(e.loc, \"operator `~=` may cause a GC allocation\");\n    }\n\n    override void visit(CatExp e)\n    {\n        if (f.setGC())\n        {\n            e.error(\"cannot use operator `~` in `@nogc` %s `%s`\",\n                f.kind(), f.toPrettyChars());\n            err = true;\n            return;\n        }\n        f.printGCUsage(e.loc, \"operator `~` may cause a GC allocation\");\n    }\n}\n\nExpression checkGC(Scope* sc, Expression e)\n{\n    FuncDeclaration f = sc.func;\n    if (e && e.op != TOK.error && f && sc.intypeof != 1 && !(sc.flags & SCOPE.ctfe) &&\n           (f.type.ty == Tfunction &&\n            (cast(TypeFunction)f.type).isnogc || (f.flags & FUNCFLAG.nogcInprocess) || global.params.vgc) &&\n           !(sc.flags & SCOPE.debug_))\n    {\n        scope NOGCVisitor gcv = new NOGCVisitor(f);\n        walkPostorder(e, gcv);\n        if (gcv.err)\n            return new ErrorExp();\n    }\n    return e;\n}\n"
  },
  {
    "path": "gcc/d/dmd/nspace.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/nspace.d, _nspace.d)\n * Documentation:  https://dlang.org/phobos/dmd_nspace.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/nspace.d\n */\n\nmodule dmd.nspace;\n\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.globals;\nimport dmd.identifier;\nimport dmd.visitor;\nimport core.stdc.stdio;\n\nprivate enum LOG = false;\n\n/***********************************************************\n * A namespace corresponding to a C++ namespace.\n * Implies extern(C++).\n */\nextern (C++) final class Nspace : ScopeDsymbol\n{\n    /**\n     * Determines whether the symbol for this namespace should be included in the symbol table.\n     */\n    bool mangleOnly;\n\n    extern (D) this(const ref Loc loc, Identifier ident, Dsymbols* members, bool mangleOnly)\n    {\n        super(ident);\n        //printf(\"Nspace::Nspace(ident = %s)\\n\", ident.toChars());\n        this.loc = loc;\n        this.members = members;\n        this.mangleOnly = mangleOnly;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        auto ns = new Nspace(loc, ident, null, mangleOnly);\n        return ScopeDsymbol.syntaxCopy(ns);\n    }\n\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        if(!mangleOnly)\n            ScopeDsymbol.addMember(sc, sds);\n        if (members)\n        {\n            if (!symtab)\n                symtab = new DsymbolTable();\n            // The namespace becomes 'imported' into the enclosing scope\n            for (Scope* sce = sc; 1; sce = sce.enclosing)\n            {\n                ScopeDsymbol sds2 = sce.scopesym;\n                if (sds2)\n                {\n                    sds2.importScope(this, Prot(Prot.Kind.public_));\n                    break;\n                }\n            }\n            assert(sc);\n            sc = sc.push(this);\n            sc.linkage = LINK.cpp; // namespaces default to C++ linkage\n            sc.parent = this;\n            foreach (s; *members)\n            {\n                //printf(\"add %s to scope %s\\n\", s.toChars(), toChars());\n                s.addMember(sc, this);\n            }\n            sc.pop();\n        }\n    }\n\n    override void setScope(Scope* sc)\n    {\n        ScopeDsymbol.setScope(sc);\n        if (members)\n        {\n            assert(sc);\n            sc = sc.push(this);\n            sc.linkage = LINK.cpp; // namespaces default to C++ linkage\n            sc.parent = this;\n            foreach (s; *members)\n            {\n                s.setScope(sc);\n            }\n            sc.pop();\n        }\n    }\n\n    override bool oneMember(Dsymbol* ps, Identifier ident)\n    {\n        return Dsymbol.oneMember(ps, ident);\n    }\n\n    override Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)\n    {\n        //printf(\"%s.Nspace.search('%s')\\n\", toChars(), ident.toChars());\n        if (_scope && !symtab)\n            dsymbolSemantic(this, _scope);\n\n        if (!members || !symtab) // opaque or semantic() is not yet called\n        {\n            error(\"is forward referenced when looking for `%s`\", ident.toChars());\n            return null;\n        }\n\n        return ScopeDsymbol.search(loc, ident, flags);\n    }\n\n    override int apply(Dsymbol_apply_ft_t fp, void* param)\n    {\n        if (members)\n        {\n            foreach (s; *members)\n            {\n                if (s)\n                {\n                    if (s.apply(fp, param))\n                        return 1;\n                }\n            }\n        }\n        return 0;\n    }\n\n    override bool hasPointers()\n    {\n        //printf(\"Nspace::hasPointers() %s\\n\", toChars());\n        if (members)\n        {\n            foreach (s; *members)\n            {\n                //printf(\" s = %s %s\\n\", s.kind(), s.toChars());\n                if (s.hasPointers())\n                {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    override void setFieldOffset(AggregateDeclaration ad, uint* poffset, bool isunion)\n    {\n        //printf(\"Nspace::setFieldOffset() %s\\n\", toChars());\n        if (_scope) // if fwd reference\n            dsymbolSemantic(this, null); // try to resolve it\n        if (members)\n        {\n            foreach (s; *members)\n            {\n                //printf(\"\\t%s\\n\", s.toChars());\n                s.setFieldOffset(ad, poffset, isunion);\n            }\n        }\n    }\n\n    override const(char)* kind() const\n    {\n        return \"namespace\";\n    }\n\n    override inout(Nspace) isNspace() inout\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/nspace.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/nspace.h\n */\n\n#pragma once\n\n#include \"dsymbol.h\"\n\n/* A namespace corresponding to a C++ namespace.\n * Implies extern(C++).\n */\n\nclass Nspace : public ScopeDsymbol\n{\n  public:\n    bool mangleOnly;\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    void addMember(Scope *sc, ScopeDsymbol *sds);\n    void setScope(Scope *sc);\n    bool oneMember(Dsymbol **ps, Identifier *ident);\n    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);\n    int apply(Dsymbol_apply_ft_t fp, void *param);\n    bool hasPointers();\n    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);\n    const char *kind() const;\n    Nspace *isNspace() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n"
  },
  {
    "path": "gcc/d/dmd/objc.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/objc.d, _objc.d)\n * Documentation:  https://dlang.org/phobos/dmd_objc.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/objc.d\n */\n\nmodule dmd.objc;\n\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.cond;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dmangle;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.gluelayer;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.root.outbuffer;\nimport dmd.root.stringtable;\n\nstruct ObjcSelector\n{\n    // MARK: Selector\n    private __gshared StringTable stringtable;\n    private __gshared StringTable vTableDispatchSelectors;\n    private __gshared int incnum = 0;\n    const(char)* stringvalue;\n    size_t stringlen;\n    size_t paramCount;\n\n    extern (C++) static void _init()\n    {\n        stringtable._init();\n    }\n\n    extern (D) this(const(char)* sv, size_t len, size_t pcount)\n    {\n        stringvalue = sv;\n        stringlen = len;\n        paramCount = pcount;\n    }\n\n    extern (D) static ObjcSelector* lookup(const(char)* s)\n    {\n        size_t len = 0;\n        size_t pcount = 0;\n        const(char)* i = s;\n        while (*i != 0)\n        {\n            ++len;\n            if (*i == ':')\n                ++pcount;\n            ++i;\n        }\n        return lookup(s, len, pcount);\n    }\n\n    extern (D) static ObjcSelector* lookup(const(char)* s, size_t len, size_t pcount)\n    {\n        StringValue* sv = stringtable.update(s, len);\n        ObjcSelector* sel = cast(ObjcSelector*)sv.ptrvalue;\n        if (!sel)\n        {\n            sel = new ObjcSelector(sv.toDchars(), len, pcount);\n            sv.ptrvalue = cast(char*)sel;\n        }\n        return sel;\n    }\n\n    extern (C++) static ObjcSelector* create(FuncDeclaration fdecl)\n    {\n        OutBuffer buf;\n        size_t pcount = 0;\n        TypeFunction ftype = cast(TypeFunction)fdecl.type;\n        const id = fdecl.ident.toString();\n        // Special case: property setter\n        if (ftype.isproperty && ftype.parameters && ftype.parameters.dim == 1)\n        {\n            // rewrite \"identifier\" as \"setIdentifier\"\n            char firstChar = id[0];\n            if (firstChar >= 'a' && firstChar <= 'z')\n                firstChar = cast(char)(firstChar - 'a' + 'A');\n            buf.writestring(\"set\");\n            buf.writeByte(firstChar);\n            buf.write(id.ptr + 1, id.length - 1);\n            buf.writeByte(':');\n            goto Lcomplete;\n        }\n        // write identifier in selector\n        buf.write(id.ptr, id.length);\n        // add mangled type and colon for each parameter\n        if (ftype.parameters && ftype.parameters.dim)\n        {\n            buf.writeByte('_');\n            Parameters* arguments = ftype.parameters;\n            size_t dim = Parameter.dim(arguments);\n            for (size_t i = 0; i < dim; i++)\n            {\n                Parameter arg = Parameter.getNth(arguments, i);\n                mangleToBuffer(arg.type, &buf);\n                buf.writeByte(':');\n            }\n            pcount = dim;\n        }\n    Lcomplete:\n        buf.writeByte('\\0');\n        return lookup(cast(const(char)*)buf.data, buf.size, pcount);\n    }\n\n    extern (D) const(char)[] toString() const pure\n    {\n        return stringvalue[0 .. stringlen];\n    }\n}\n\nprivate __gshared Objc _objc;\n\nObjc objc()\n{\n    return _objc;\n}\n\n\n/**\n * Contains all data for a class declaration that is needed for the Objective-C\n * integration.\n */\nstruct ObjcClassDeclaration\n{\n    /// `true` if this class is a metaclass.\n    bool isMeta = false;\n\n    /// The metaclass of this class.\n    ClassDeclaration metaclass;\n}\n\n// Should be an interface\nextern(C++) abstract class Objc\n{\n    static void _init()\n    {\n        if (global.params.isOSX && global.params.is64bit)\n            _objc = new Supported;\n        else\n            _objc = new Unsupported;\n    }\n\n    abstract void setObjc(ClassDeclaration cd);\n    abstract void setObjc(InterfaceDeclaration);\n\n    abstract void setSelector(FuncDeclaration, Scope* sc);\n    abstract void validateSelector(FuncDeclaration fd);\n    abstract void checkLinkage(FuncDeclaration fd);\n\n    /**\n     * Returns the `this` pointer of the given function declaration.\n     *\n     * This is only used for class/static methods. For instance methods, no\n     * Objective-C specialization is necessary.\n     *\n     * Params:\n     *  funcDeclaration = the function declaration to get the `this` pointer for\n     *\n     * Returns: the `this` pointer of the given function declaration, or `null`\n     *  if the given function declaration is not an Objective-C method.\n     */\n    abstract inout(AggregateDeclaration) isThis(inout FuncDeclaration funcDeclaration) const;\n\n    /**\n     * Creates and sets the metaclass on the given class/interface declaration.\n     *\n     * Will only be performed on regular Objective-C classes, not on metaclasses.\n     *\n     * Params:\n     *  classDeclaration = the class/interface declaration to set the metaclass on\n     */\n    abstract void setMetaclass(InterfaceDeclaration interfaceDeclaration) const;\n\n    /// ditto\n    abstract void setMetaclass(ClassDeclaration classDeclaration) const;\n\n\n    /**\n     * Returns Objective-C runtime metaclass of the given class declaration.\n     *\n     * `ClassDeclaration.ObjcClassDeclaration.metaclass` contains the metaclass\n     * from the semantic point of view. This function returns the metaclass from\n     * the Objective-C runtime's point of view. Here, the metaclass of a\n     * metaclass is the root metaclass, not `null`. The root metaclass's\n     * metaclass is itself.\n     *\n     * Params:\n     *  classDeclaration = The class declaration to return the metaclass of\n     *\n     * Returns: the Objective-C runtime metaclass of the given class declaration\n     */\n    abstract ClassDeclaration getRuntimeMetaclass(ClassDeclaration classDeclaration) const;\n\n    /**\n     * Issues a compile time error if the `.offsetof`/`.tupleof` property is\n     * used on a field of an Objective-C class.\n     *\n     * To solve the fragile base class problem in Objective-C, fields have a\n     * dynamic offset instead of a static offset. The compiler outputs a\n     * statically known offset which later the dynamic loader can update, if\n     * necessary, when the application is loaded. Due to this behavior it\n     * doesn't make sense to be able to get the offset of a field at compile\n     * time, because this offset might not actually be the same at runtime.\n     *\n     * To get the offset of a field that is correct at runtime, functionality\n     * from the Objective-C runtime can be used instead.\n     *\n     * Params:\n     *  expression = the `.offsetof`/`.tupleof` expression\n     *  aggregateDeclaration = the aggregate declaration the field of the\n     *      `.offsetof`/`.tupleof` expression belongs to\n     *  type = the type of the receiver of the `.tupleof` expression\n     *\n     * See_Also:\n     *  $(LINK2 https://en.wikipedia.org/wiki/Fragile_binary_interface_problem,\n     *      Fragile Binary Interface Problem)\n     *\n     * See_Also:\n     *  $(LINK2 https://developer.apple.com/documentation/objectivec/objective_c_runtime,\n     *      Objective-C Runtime)\n     */\n    abstract void checkOffsetof(Expression expression, AggregateDeclaration aggregateDeclaration) const;\n\n    /// ditto\n    abstract void checkTupleof(Expression expression, TypeClass type) const;\n}\n\nextern(C++) private final class Unsupported : Objc\n{\n    extern(D) final this()\n    {\n        ObjcGlue.initialize();\n    }\n\n    override void setObjc(ClassDeclaration cd)\n    {\n        cd.error(\"Objective-C classes not supported\");\n    }\n\n    override void setObjc(InterfaceDeclaration id)\n    {\n        id.error(\"Objective-C interfaces not supported\");\n    }\n\n    override void setSelector(FuncDeclaration, Scope*)\n    {\n        // noop\n    }\n\n    override void validateSelector(FuncDeclaration)\n    {\n        // noop\n    }\n\n    override void checkLinkage(FuncDeclaration)\n    {\n        // noop\n    }\n\n    override inout(AggregateDeclaration) isThis(inout FuncDeclaration funcDeclaration) const\n    {\n        return null;\n    }\n\n    override void setMetaclass(InterfaceDeclaration) const\n    {\n        // noop\n    }\n\n    override void setMetaclass(ClassDeclaration) const\n    {\n        // noop\n    }\n\n    override ClassDeclaration getRuntimeMetaclass(ClassDeclaration classDeclaration) const\n    {\n        assert(0, \"Should never be called when Objective-C is not supported\");\n    }\n\n    override void checkOffsetof(Expression expression, AggregateDeclaration aggregateDeclaration) const\n    {\n        // noop\n    }\n\n    override void checkTupleof(Expression expression, TypeClass type) const\n    {\n        // noop\n    }\n}\n\nextern(C++) private final class Supported : Objc\n{\n    extern(D) final this()\n    {\n        VersionCondition.addPredefinedGlobalIdent(\"D_ObjectiveC\");\n\n        ObjcGlue.initialize();\n        ObjcSelector._init();\n    }\n\n    override void setObjc(ClassDeclaration cd)\n    {\n        cd.classKind = ClassKind.objc;\n    }\n\n    override void setObjc(InterfaceDeclaration id)\n    {\n        id.classKind = ClassKind.objc;\n    }\n\n    override void setSelector(FuncDeclaration fd, Scope* sc)\n    {\n        import dmd.tokens;\n\n        if (!fd.userAttribDecl)\n            return;\n        Expressions* udas = fd.userAttribDecl.getAttributes();\n        arrayExpressionSemantic(udas, sc, true);\n        for (size_t i = 0; i < udas.dim; i++)\n        {\n            Expression uda = (*udas)[i];\n            assert(uda);\n            if (uda.op != TOK.tuple)\n                continue;\n            Expressions* exps = (cast(TupleExp)uda).exps;\n            for (size_t j = 0; j < exps.dim; j++)\n            {\n                Expression e = (*exps)[j];\n                assert(e);\n                if (e.op != TOK.structLiteral)\n                    continue;\n                StructLiteralExp literal = cast(StructLiteralExp)e;\n                assert(literal.sd);\n                if (!isUdaSelector(literal.sd))\n                    continue;\n                if (fd.selector)\n                {\n                    fd.error(\"can only have one Objective-C selector per method\");\n                    return;\n                }\n                assert(literal.elements.dim == 1);\n                StringExp se = (*literal.elements)[0].toStringExp();\n                assert(se);\n                fd.selector = ObjcSelector.lookup(cast(const(char)*)se.toUTF8(sc).string);\n            }\n        }\n    }\n\n    override void validateSelector(FuncDeclaration fd)\n    {\n        if (!fd.selector)\n            return;\n        TypeFunction tf = cast(TypeFunction)fd.type;\n        if (fd.selector.paramCount != tf.parameters.dim)\n            fd.error(\"number of colons in Objective-C selector must match number of parameters\");\n        if (fd.parent && fd.parent.isTemplateInstance())\n            fd.error(\"template cannot have an Objective-C selector attached\");\n    }\n\n    override void checkLinkage(FuncDeclaration fd)\n    {\n        if (fd.linkage != LINK.objc && fd.selector)\n            fd.error(\"must have Objective-C linkage to attach a selector\");\n    }\n\n    override inout(AggregateDeclaration) isThis(inout FuncDeclaration funcDeclaration) const\n    {\n        with(funcDeclaration)\n        {\n            if (!selector)\n                return null;\n\n            // Use Objective-C class object as 'this'\n            auto cd = isMember2().isClassDeclaration();\n\n            if (cd.classKind == ClassKind.objc)\n            {\n                if (!cd.objc.isMeta)\n                    return cd.objc.metaclass;\n            }\n\n            return null;\n        }\n    }\n\n    override void setMetaclass(InterfaceDeclaration interfaceDeclaration) const\n    {\n        static auto newMetaclass(Loc loc, BaseClasses* metaBases)\n        {\n            return new InterfaceDeclaration(loc, Id.Class, metaBases);\n        }\n\n        .setMetaclass!newMetaclass(interfaceDeclaration);\n    }\n\n    override void setMetaclass(ClassDeclaration classDeclaration) const\n    {\n        auto newMetaclass(Loc loc, BaseClasses* metaBases)\n        {\n            auto members = new Dsymbols();\n            members.push(classDeclaration);\n            return new ClassDeclaration(loc, Id.Class, metaBases, members, 0);\n        }\n\n        .setMetaclass!newMetaclass(classDeclaration);\n    }\n\n    override ClassDeclaration getRuntimeMetaclass(ClassDeclaration classDeclaration) const\n    {\n        if (!classDeclaration.objc.metaclass && classDeclaration.objc.isMeta)\n        {\n            if (classDeclaration.baseClass)\n                return getRuntimeMetaclass(classDeclaration.baseClass);\n            else\n                return classDeclaration;\n        }\n        else\n            return classDeclaration.objc.metaclass;\n    }\n\n    override void checkOffsetof(Expression expression, AggregateDeclaration aggregateDeclaration) const\n    {\n        if (aggregateDeclaration.classKind != ClassKind.objc)\n            return;\n\n        enum errorMessage = \"no property `offsetof` for member `%s` of type \" ~\n            \"`%s`\";\n\n        enum supplementalMessage = \"`offsetof` is not available for members \" ~\n            \"of Objective-C classes. Please use the Objective-C runtime instead\";\n\n        expression.error(errorMessage, expression.toChars(),\n            expression.type.toChars());\n        expression.errorSupplemental(supplementalMessage);\n    }\n\n    override void checkTupleof(Expression expression, TypeClass type) const\n    {\n        if (type.sym.classKind != ClassKind.objc)\n            return;\n\n        expression.error(\"no property `tupleof` for type `%s`\", type.toChars());\n        expression.errorSupplemental(\"`tupleof` is not available for members \" ~\n            \"of Objective-C classes. Please use the Objective-C runtime instead\");\n    }\n\n    extern(D) private bool isUdaSelector(StructDeclaration sd)\n    {\n        if (sd.ident != Id.udaSelector || !sd.parent)\n            return false;\n        Module _module = sd.parent.isModule();\n        return _module && _module.isCoreModule(Id.attribute);\n    }\n}\n\n/*\n * Creates and sets the metaclass on the given class/interface declaration.\n *\n * Will only be performed on regular Objective-C classes, not on metaclasses.\n *\n * Params:\n *  newMetaclass = a function that returns the metaclass to set. This should\n *      return the same type as `T`.\n *  classDeclaration = the class/interface declaration to set the metaclass on\n */\nprivate void setMetaclass(alias newMetaclass, T)(T classDeclaration)\nif (is(T == ClassDeclaration) || is(T == InterfaceDeclaration))\n{\n    static if (is(T == ClassDeclaration))\n        enum errorType = \"class\";\n    else\n        enum errorType = \"interface\";\n\n    with (classDeclaration)\n    {\n        if (classKind != ClassKind.objc || objc.isMeta || objc.metaclass)\n            return;\n\n        auto metaBases = new BaseClasses();\n\n        foreach (base ; baseclasses.opSlice)\n        {\n            auto baseCd = base.sym;\n            assert(baseCd);\n\n            if (baseCd.classKind == ClassKind.objc)\n            {\n                assert(baseCd.objc.metaclass);\n                assert(baseCd.objc.metaclass.objc.isMeta);\n                assert(baseCd.objc.metaclass.type.ty == Tclass);\n\n                auto metaBase = new BaseClass(baseCd.objc.metaclass.type);\n                metaBase.sym = baseCd.objc.metaclass;\n                metaBases.push(metaBase);\n            }\n            else\n            {\n                error(\"base \" ~ errorType ~ \" for an Objective-C \" ~\n                      errorType ~ \" must be `extern (Objective-C)`\");\n            }\n        }\n\n        objc.metaclass = newMetaclass(loc, metaBases);\n        objc.metaclass.storage_class |= STC.static_;\n        objc.metaclass.classKind = ClassKind.objc;\n        objc.metaclass.objc.isMeta = true;\n        objc.metaclass.members = new Dsymbols();\n        members.push(objc.metaclass);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/objc.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 2015-2018 by The D Language Foundation, All Rights Reserved\n * written by Michel Fortin\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/objc.h\n */\n\n#pragma once\n\nclass AggregateDeclaration;\nclass FuncDeclaration;\nclass ClassDeclaration;\nclass InterfaceDeclaration;\nstruct Scope;\n\nstruct ObjcSelector\n{\n    const char *stringvalue;\n    size_t stringlen;\n    size_t paramCount;\n\n    static void _init();\n\n    ObjcSelector(const char *sv, size_t len, size_t pcount);\n\n    static ObjcSelector *create(FuncDeclaration *fdecl);\n};\n\nstruct ObjcClassDeclaration\n{\n    bool isMeta;\n    ClassDeclaration* metaclass;\n};\n\nclass Objc\n{\npublic:\n    static void _init();\n\n    virtual void setObjc(ClassDeclaration* cd) = 0;\n    virtual void setObjc(InterfaceDeclaration*) = 0;\n\n    virtual void setSelector(FuncDeclaration*, Scope* sc) = 0;\n    virtual void validateSelector(FuncDeclaration* fd) = 0;\n    virtual void checkLinkage(FuncDeclaration* fd) = 0;\n    virtual AggregateDeclaration* isThis(FuncDeclaration* fd) = 0;\n\n    virtual void setMetaclass(InterfaceDeclaration* id) = 0;\n    virtual void setMetaclass(ClassDeclaration* id) = 0;\n    virtual ClassDeclaration* getRuntimeMetaclass(ClassDeclaration* cd) = 0;\n};\n"
  },
  {
    "path": "gcc/d/dmd/opover.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/opover.d, _opover.d)\n * Documentation:  https://dlang.org/phobos/dmd_opover.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/opover.d\n */\n\nmodule dmd.opover;\n\nimport core.stdc.stdio;\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arraytypes;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.statement;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.visitor;\n\n/***********************************\n * Determine if operands of binary op can be reversed\n * to fit operator overload.\n */\nbool isCommutative(TOK op)\n{\n    switch (op)\n    {\n    case TOK.add:\n    case TOK.mul:\n    case TOK.and:\n    case TOK.or:\n    case TOK.xor:\n    // EqualExp\n    case TOK.equal:\n    case TOK.notEqual:\n    // CmpExp\n    case TOK.lessThan:\n    case TOK.lessOrEqual:\n    case TOK.greaterThan:\n    case TOK.greaterOrEqual:\n        return true;\n    default:\n        break;\n    }\n    return false;\n}\n\n/***********************************\n * Get Identifier for operator overload.\n */\nprivate Identifier opId(Expression e)\n{\n    extern (C++) final class OpIdVisitor : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        Identifier id;\n\n        override void visit(Expression e)\n        {\n            assert(0);\n        }\n\n        override void visit(UAddExp e)\n        {\n            id = Id.uadd;\n        }\n\n        override void visit(NegExp e)\n        {\n            id = Id.neg;\n        }\n\n        override void visit(ComExp e)\n        {\n            id = Id.com;\n        }\n\n        override void visit(CastExp e)\n        {\n            id = Id._cast;\n        }\n\n        override void visit(InExp e)\n        {\n            id = Id.opIn;\n        }\n\n        override void visit(PostExp e)\n        {\n            id = (e.op == TOK.plusPlus) ? Id.postinc : Id.postdec;\n        }\n\n        override void visit(AddExp e)\n        {\n            id = Id.add;\n        }\n\n        override void visit(MinExp e)\n        {\n            id = Id.sub;\n        }\n\n        override void visit(MulExp e)\n        {\n            id = Id.mul;\n        }\n\n        override void visit(DivExp e)\n        {\n            id = Id.div;\n        }\n\n        override void visit(ModExp e)\n        {\n            id = Id.mod;\n        }\n\n        override void visit(PowExp e)\n        {\n            id = Id.pow;\n        }\n\n        override void visit(ShlExp e)\n        {\n            id = Id.shl;\n        }\n\n        override void visit(ShrExp e)\n        {\n            id = Id.shr;\n        }\n\n        override void visit(UshrExp e)\n        {\n            id = Id.ushr;\n        }\n\n        override void visit(AndExp e)\n        {\n            id = Id.iand;\n        }\n\n        override void visit(OrExp e)\n        {\n            id = Id.ior;\n        }\n\n        override void visit(XorExp e)\n        {\n            id = Id.ixor;\n        }\n\n        override void visit(CatExp e)\n        {\n            id = Id.cat;\n        }\n\n        override void visit(AssignExp e)\n        {\n            id = Id.assign;\n        }\n\n        override void visit(AddAssignExp e)\n        {\n            id = Id.addass;\n        }\n\n        override void visit(MinAssignExp e)\n        {\n            id = Id.subass;\n        }\n\n        override void visit(MulAssignExp e)\n        {\n            id = Id.mulass;\n        }\n\n        override void visit(DivAssignExp e)\n        {\n            id = Id.divass;\n        }\n\n        override void visit(ModAssignExp e)\n        {\n            id = Id.modass;\n        }\n\n        override void visit(AndAssignExp e)\n        {\n            id = Id.andass;\n        }\n\n        override void visit(OrAssignExp e)\n        {\n            id = Id.orass;\n        }\n\n        override void visit(XorAssignExp e)\n        {\n            id = Id.xorass;\n        }\n\n        override void visit(ShlAssignExp e)\n        {\n            id = Id.shlass;\n        }\n\n        override void visit(ShrAssignExp e)\n        {\n            id = Id.shrass;\n        }\n\n        override void visit(UshrAssignExp e)\n        {\n            id = Id.ushrass;\n        }\n\n        override void visit(CatAssignExp e)\n        {\n            id = Id.catass;\n        }\n\n        override void visit(PowAssignExp e)\n        {\n            id = Id.powass;\n        }\n\n        override void visit(EqualExp e)\n        {\n            id = Id.eq;\n        }\n\n        override void visit(CmpExp e)\n        {\n            id = Id.cmp;\n        }\n\n        override void visit(ArrayExp e)\n        {\n            id = Id.index;\n        }\n\n        override void visit(PtrExp e)\n        {\n            id = Id.opStar;\n        }\n    }\n\n    scope OpIdVisitor v = new OpIdVisitor();\n    e.accept(v);\n    return v.id;\n}\n\n/***********************************\n * Get Identifier for reverse operator overload,\n * NULL if not supported for this operator.\n */\nprivate Identifier opId_r(Expression e)\n{\n    extern (C++) final class OpIdRVisitor : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        Identifier id;\n\n        override void visit(Expression e)\n        {\n            id = null;\n        }\n\n        override void visit(InExp e)\n        {\n            id = Id.opIn_r;\n        }\n\n        override void visit(AddExp e)\n        {\n            id = Id.add_r;\n        }\n\n        override void visit(MinExp e)\n        {\n            id = Id.sub_r;\n        }\n\n        override void visit(MulExp e)\n        {\n            id = Id.mul_r;\n        }\n\n        override void visit(DivExp e)\n        {\n            id = Id.div_r;\n        }\n\n        override void visit(ModExp e)\n        {\n            id = Id.mod_r;\n        }\n\n        override void visit(PowExp e)\n        {\n            id = Id.pow_r;\n        }\n\n        override void visit(ShlExp e)\n        {\n            id = Id.shl_r;\n        }\n\n        override void visit(ShrExp e)\n        {\n            id = Id.shr_r;\n        }\n\n        override void visit(UshrExp e)\n        {\n            id = Id.ushr_r;\n        }\n\n        override void visit(AndExp e)\n        {\n            id = Id.iand_r;\n        }\n\n        override void visit(OrExp e)\n        {\n            id = Id.ior_r;\n        }\n\n        override void visit(XorExp e)\n        {\n            id = Id.ixor_r;\n        }\n\n        override void visit(CatExp e)\n        {\n            id = Id.cat_r;\n        }\n    }\n\n    scope OpIdRVisitor v = new OpIdRVisitor();\n    e.accept(v);\n    return v.id;\n}\n\n/************************************\n * If type is a class or struct, return the symbol for it,\n * else NULL\n */\nAggregateDeclaration isAggregate(Type t)\n{\n    t = t.toBasetype();\n    if (t.ty == Tclass)\n    {\n        return (cast(TypeClass)t).sym;\n    }\n    else if (t.ty == Tstruct)\n    {\n        return (cast(TypeStruct)t).sym;\n    }\n    return null;\n}\n\n/*******************************************\n * Helper function to turn operator into template argument list\n */\nObjects* opToArg(Scope* sc, TOK op)\n{\n    /* Remove the = from op=\n     */\n    switch (op)\n    {\n    case TOK.addAssign:\n        op = TOK.add;\n        break;\n    case TOK.minAssign:\n        op = TOK.min;\n        break;\n    case TOK.mulAssign:\n        op = TOK.mul;\n        break;\n    case TOK.divAssign:\n        op = TOK.div;\n        break;\n    case TOK.modAssign:\n        op = TOK.mod;\n        break;\n    case TOK.andAssign:\n        op = TOK.and;\n        break;\n    case TOK.orAssign:\n        op = TOK.or;\n        break;\n    case TOK.xorAssign:\n        op = TOK.xor;\n        break;\n    case TOK.leftShiftAssign:\n        op = TOK.leftShift;\n        break;\n    case TOK.rightShiftAssign:\n        op = TOK.rightShift;\n        break;\n    case TOK.unsignedRightShiftAssign:\n        op = TOK.unsignedRightShift;\n        break;\n    case TOK.concatenateAssign:\n        op = TOK.concatenate;\n        break;\n    case TOK.powAssign:\n        op = TOK.pow;\n        break;\n    default:\n        break;\n    }\n    Expression e = new StringExp(Loc.initial, cast(char*)Token.toChars(op));\n    e = e.expressionSemantic(sc);\n    auto tiargs = new Objects();\n    tiargs.push(e);\n    return tiargs;\n}\n\n// Try alias this on first operand\nprivate Expression checkAliasThisForLhs(AggregateDeclaration ad, Scope* sc, BinExp e)\n{\n    if (!ad || !ad.aliasthis)\n        return null;\n\n    /* Rewrite (e1 op e2) as:\n     *      (e1.aliasthis op e2)\n     */\n    if (e.att1 && e.e1.type == e.att1)\n        return null;\n    //printf(\"att %s e1 = %s\\n\", Token::toChars(e.op), e.e1.type.toChars());\n    Expression e1 = new DotIdExp(e.loc, e.e1, ad.aliasthis.ident);\n    BinExp be = cast(BinExp)e.copy();\n    if (!be.att1 && e.e1.type.checkAliasThisRec())\n        be.att1 = e.e1.type;\n    be.e1 = e1;\n    return be.trySemantic(sc);\n}\n\n// Try alias this on second operand\nprivate Expression checkAliasThisForRhs(AggregateDeclaration ad, Scope* sc, BinExp e)\n{\n    if (!ad || !ad.aliasthis)\n        return null;\n    /* Rewrite (e1 op e2) as:\n     *      (e1 op e2.aliasthis)\n     */\n    if (e.att2 && e.e2.type == e.att2)\n        return null;\n    //printf(\"att %s e2 = %s\\n\", Token::toChars(e.op), e.e2.type.toChars());\n    Expression e2 = new DotIdExp(e.loc, e.e2, ad.aliasthis.ident);\n    BinExp be = cast(BinExp)e.copy();\n    if (!be.att2 && e.e2.type.checkAliasThisRec())\n        be.att2 = e.e2.type;\n    be.e2 = e2;\n    return be.trySemantic(sc);\n}\n\n/************************************\n * Operator overload.\n * Check for operator overload, if so, replace\n * with function call.\n * Return NULL if not an operator overload.\n */\nExpression op_overload(Expression e, Scope* sc)\n{\n    extern (C++) final class OpOverload : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        Scope* sc;\n        Expression result;\n\n        extern (D) this(Scope* sc)\n        {\n            this.sc = sc;\n        }\n\n        override void visit(Expression e)\n        {\n            assert(0);\n        }\n\n        override void visit(UnaExp e)\n        {\n            //printf(\"UnaExp::op_overload() (%s)\\n\", e.toChars());\n            if (e.e1.op == TOK.array)\n            {\n                ArrayExp ae = cast(ArrayExp)e.e1;\n                ae.e1 = ae.e1.expressionSemantic(sc);\n                ae.e1 = resolveProperties(sc, ae.e1);\n                Expression ae1old = ae.e1;\n                const(bool) maybeSlice = (ae.arguments.dim == 0 || ae.arguments.dim == 1 && (*ae.arguments)[0].op == TOK.interval);\n                IntervalExp ie = null;\n                if (maybeSlice && ae.arguments.dim)\n                {\n                    assert((*ae.arguments)[0].op == TOK.interval);\n                    ie = cast(IntervalExp)(*ae.arguments)[0];\n                }\n                while (true)\n                {\n                    if (ae.e1.op == TOK.error)\n                    {\n                        result = ae.e1;\n                        return;\n                    }\n                    Expression e0 = null;\n                    Expression ae1save = ae.e1;\n                    ae.lengthVar = null;\n                    Type t1b = ae.e1.type.toBasetype();\n                    AggregateDeclaration ad = isAggregate(t1b);\n                    if (!ad)\n                        break;\n                    if (search_function(ad, Id.opIndexUnary))\n                    {\n                        // Deal with $\n                        result = resolveOpDollar(sc, ae, &e0);\n                        if (!result) // op(a[i..j]) might be: a.opSliceUnary!(op)(i, j)\n                            goto Lfallback;\n                        if (result.op == TOK.error)\n                            return;\n                        /* Rewrite op(a[arguments]) as:\n                         *      a.opIndexUnary!(op)(arguments)\n                         */\n                        Expressions* a = ae.arguments.copy();\n                        Objects* tiargs = opToArg(sc, e.op);\n                        result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opIndexUnary, tiargs);\n                        result = new CallExp(e.loc, result, a);\n                        if (maybeSlice) // op(a[]) might be: a.opSliceUnary!(op)()\n                            result = result.trySemantic(sc);\n                        else\n                            result = result.expressionSemantic(sc);\n                        if (result)\n                        {\n                            result = Expression.combine(e0, result);\n                            return;\n                        }\n                    }\n                Lfallback:\n                    if (maybeSlice && search_function(ad, Id.opSliceUnary))\n                    {\n                        // Deal with $\n                        result = resolveOpDollar(sc, ae, ie, &e0);\n                        if (result.op == TOK.error)\n                            return;\n                        /* Rewrite op(a[i..j]) as:\n                         *      a.opSliceUnary!(op)(i, j)\n                         */\n                        auto a = new Expressions();\n                        if (ie)\n                        {\n                            a.push(ie.lwr);\n                            a.push(ie.upr);\n                        }\n                        Objects* tiargs = opToArg(sc, e.op);\n                        result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opSliceUnary, tiargs);\n                        result = new CallExp(e.loc, result, a);\n                        result = result.expressionSemantic(sc);\n                        result = Expression.combine(e0, result);\n                        return;\n                    }\n                    // Didn't find it. Forward to aliasthis\n                    if (ad.aliasthis && t1b != ae.att1)\n                    {\n                        if (!ae.att1 && t1b.checkAliasThisRec())\n                            ae.att1 = t1b;\n                        /* Rewrite op(a[arguments]) as:\n                         *      op(a.aliasthis[arguments])\n                         */\n                        ae.e1 = resolveAliasThis(sc, ae1save, true);\n                        if (ae.e1)\n                            continue;\n                    }\n                    break;\n                }\n                ae.e1 = ae1old; // recovery\n                ae.lengthVar = null;\n            }\n            e.e1 = e.e1.expressionSemantic(sc);\n            e.e1 = resolveProperties(sc, e.e1);\n            if (e.e1.op == TOK.error)\n            {\n                result = e.e1;\n                return;\n            }\n            AggregateDeclaration ad = isAggregate(e.e1.type);\n            if (ad)\n            {\n                Dsymbol fd = null;\n                version (all)\n                {\n                    // Old way, kept for compatibility with D1\n                    if (e.op != TOK.prePlusPlus && e.op != TOK.preMinusMinus)\n                    {\n                        fd = search_function(ad, opId(e));\n                        if (fd)\n                        {\n                            // Rewrite +e1 as e1.add()\n                            result = build_overload(e.loc, sc, e.e1, null, fd);\n                            return;\n                        }\n                    }\n                }\n                /* Rewrite as:\n                 *      e1.opUnary!(op)()\n                 */\n                fd = search_function(ad, Id.opUnary);\n                if (fd)\n                {\n                    Objects* tiargs = opToArg(sc, e.op);\n                    result = new DotTemplateInstanceExp(e.loc, e.e1, fd.ident, tiargs);\n                    result = new CallExp(e.loc, result);\n                    result = result.expressionSemantic(sc);\n                    return;\n                }\n                // Didn't find it. Forward to aliasthis\n                if (ad.aliasthis && e.e1.type != e.att1)\n                {\n                    /* Rewrite op(e1) as:\n                     *      op(e1.aliasthis)\n                     */\n                    //printf(\"att una %s e1 = %s\\n\", Token::toChars(op), this.e1.type.toChars());\n                    Expression e1 = new DotIdExp(e.loc, e.e1, ad.aliasthis.ident);\n                    UnaExp ue = cast(UnaExp)e.copy();\n                    if (!ue.att1 && e.e1.type.checkAliasThisRec())\n                        ue.att1 = e.e1.type;\n                    ue.e1 = e1;\n                    result = ue.trySemantic(sc);\n                    return;\n                }\n            }\n        }\n\n        override void visit(ArrayExp ae)\n        {\n            //printf(\"ArrayExp::op_overload() (%s)\\n\", ae.toChars());\n            ae.e1 = ae.e1.expressionSemantic(sc);\n            ae.e1 = resolveProperties(sc, ae.e1);\n            Expression ae1old = ae.e1;\n            const(bool) maybeSlice = (ae.arguments.dim == 0 || ae.arguments.dim == 1 && (*ae.arguments)[0].op == TOK.interval);\n            IntervalExp ie = null;\n            if (maybeSlice && ae.arguments.dim)\n            {\n                assert((*ae.arguments)[0].op == TOK.interval);\n                ie = cast(IntervalExp)(*ae.arguments)[0];\n            }\n            while (true)\n            {\n                if (ae.e1.op == TOK.error)\n                {\n                    result = ae.e1;\n                    return;\n                }\n                Expression e0 = null;\n                Expression ae1save = ae.e1;\n                ae.lengthVar = null;\n                Type t1b = ae.e1.type.toBasetype();\n                AggregateDeclaration ad = isAggregate(t1b);\n                if (!ad)\n                {\n                    // If the non-aggregate expression ae.e1 is indexable or sliceable,\n                    // convert it to the corresponding concrete expression.\n                    if (t1b.ty == Tpointer || t1b.ty == Tsarray || t1b.ty == Tarray || t1b.ty == Taarray ||\n                        t1b.ty == Ttuple || t1b.ty == Tvector || ae.e1.op == TOK.type)\n                    {\n                        // Convert to SliceExp\n                        if (maybeSlice)\n                        {\n                            result = new SliceExp(ae.loc, ae.e1, ie);\n                            result = result.expressionSemantic(sc);\n                            return;\n                        }\n                        // Convert to IndexExp\n                        if (ae.arguments.dim == 1)\n                        {\n                            result = new IndexExp(ae.loc, ae.e1, (*ae.arguments)[0]);\n                            result = result.expressionSemantic(sc);\n                            return;\n                        }\n                    }\n                    break;\n                }\n                if (search_function(ad, Id.index))\n                {\n                    // Deal with $\n                    result = resolveOpDollar(sc, ae, &e0);\n                    if (!result) // a[i..j] might be: a.opSlice(i, j)\n                        goto Lfallback;\n                    if (result.op == TOK.error)\n                        return;\n                    /* Rewrite e1[arguments] as:\n                     *      e1.opIndex(arguments)\n                     */\n                    Expressions* a = ae.arguments.copy();\n                    result = new DotIdExp(ae.loc, ae.e1, Id.index);\n                    result = new CallExp(ae.loc, result, a);\n                    if (maybeSlice) // a[] might be: a.opSlice()\n                        result = result.trySemantic(sc);\n                    else\n                        result = result.expressionSemantic(sc);\n                    if (result)\n                    {\n                        result = Expression.combine(e0, result);\n                        return;\n                    }\n                }\n            Lfallback:\n                if (maybeSlice && ae.e1.op == TOK.type)\n                {\n                    result = new SliceExp(ae.loc, ae.e1, ie);\n                    result = result.expressionSemantic(sc);\n                    result = Expression.combine(e0, result);\n                    return;\n                }\n                if (maybeSlice && search_function(ad, Id.slice))\n                {\n                    // Deal with $\n                    result = resolveOpDollar(sc, ae, ie, &e0);\n                    if (result.op == TOK.error)\n                        return;\n                    /* Rewrite a[i..j] as:\n                     *      a.opSlice(i, j)\n                     */\n                    auto a = new Expressions();\n                    if (ie)\n                    {\n                        a.push(ie.lwr);\n                        a.push(ie.upr);\n                    }\n                    result = new DotIdExp(ae.loc, ae.e1, Id.slice);\n                    result = new CallExp(ae.loc, result, a);\n                    result = result.expressionSemantic(sc);\n                    result = Expression.combine(e0, result);\n                    return;\n                }\n                // Didn't find it. Forward to aliasthis\n                if (ad.aliasthis && t1b != ae.att1)\n                {\n                    if (!ae.att1 && t1b.checkAliasThisRec())\n                        ae.att1 = t1b;\n                    //printf(\"att arr e1 = %s\\n\", this.e1.type.toChars());\n                    /* Rewrite op(a[arguments]) as:\n                     *      op(a.aliasthis[arguments])\n                     */\n                    ae.e1 = resolveAliasThis(sc, ae1save, true);\n                    if (ae.e1)\n                        continue;\n                }\n                break;\n            }\n            ae.e1 = ae1old; // recovery\n            ae.lengthVar = null;\n        }\n\n        /***********************************************\n         * This is mostly the same as UnaryExp::op_overload(), but has\n         * a different rewrite.\n         */\n        override void visit(CastExp e)\n        {\n            //printf(\"CastExp::op_overload() (%s)\\n\", e.toChars());\n            AggregateDeclaration ad = isAggregate(e.e1.type);\n            if (ad)\n            {\n                Dsymbol fd = null;\n                /* Rewrite as:\n                 *      e1.opCast!(T)()\n                 */\n                fd = search_function(ad, Id._cast);\n                if (fd)\n                {\n                    version (all)\n                    {\n                        // Backwards compatibility with D1 if opCast is a function, not a template\n                        if (fd.isFuncDeclaration())\n                        {\n                            // Rewrite as:  e1.opCast()\n                            result = build_overload(e.loc, sc, e.e1, null, fd);\n                            return;\n                        }\n                    }\n                    auto tiargs = new Objects();\n                    tiargs.push(e.to);\n                    result = new DotTemplateInstanceExp(e.loc, e.e1, fd.ident, tiargs);\n                    result = new CallExp(e.loc, result);\n                    result = result.expressionSemantic(sc);\n                    return;\n                }\n                // Didn't find it. Forward to aliasthis\n                if (ad.aliasthis)\n                {\n                    /* Rewrite op(e1) as:\n                     *      op(e1.aliasthis)\n                     */\n                    Expression e1 = new DotIdExp(e.loc, e.e1, ad.aliasthis.ident);\n                    result = e.copy();\n                    (cast(UnaExp)result).e1 = e1;\n                    result = result.trySemantic(sc);\n                    return;\n                }\n            }\n        }\n\n        override void visit(BinExp e)\n        {\n            //printf(\"BinExp::op_overload() (%s)\\n\", e.toChars());\n            Identifier id = opId(e);\n            Identifier id_r = opId_r(e);\n            Expressions args1;\n            Expressions args2;\n            int argsset = 0;\n            AggregateDeclaration ad1 = isAggregate(e.e1.type);\n            AggregateDeclaration ad2 = isAggregate(e.e2.type);\n            if (e.op == TOK.assign && ad1 == ad2)\n            {\n                StructDeclaration sd = ad1.isStructDeclaration();\n                if (sd && !sd.hasIdentityAssign)\n                {\n                    /* This is bitwise struct assignment. */\n                    return;\n                }\n            }\n            Dsymbol s = null;\n            Dsymbol s_r = null;\n            version (all)\n            {\n                // the old D1 scheme\n                if (ad1 && id)\n                {\n                    s = search_function(ad1, id);\n                }\n                if (ad2 && id_r)\n                {\n                    s_r = search_function(ad2, id_r);\n                    // https://issues.dlang.org/show_bug.cgi?id=12778\n                    // If both x.opBinary(y) and y.opBinaryRight(x) found,\n                    // and they are exactly same symbol, x.opBinary(y) should be preferred.\n                    if (s_r && s_r == s)\n                        s_r = null;\n                }\n            }\n            Objects* tiargs = null;\n            if (e.op == TOK.plusPlus || e.op == TOK.minusMinus)\n            {\n                // Bug4099 fix\n                if (ad1 && search_function(ad1, Id.opUnary))\n                    return;\n            }\n            if (!s && !s_r && e.op != TOK.equal && e.op != TOK.notEqual && e.op != TOK.assign && e.op != TOK.plusPlus && e.op != TOK.minusMinus)\n            {\n                /* Try the new D2 scheme, opBinary and opBinaryRight\n                 */\n                if (ad1)\n                {\n                    s = search_function(ad1, Id.opBinary);\n                    if (s && !s.isTemplateDeclaration())\n                    {\n                        e.e1.error(\"`%s.opBinary` isn't a template\", e.e1.toChars());\n                        result = new ErrorExp();\n                        return;\n                    }\n                }\n                if (ad2)\n                {\n                    s_r = search_function(ad2, Id.opBinaryRight);\n                    if (s_r && !s_r.isTemplateDeclaration())\n                    {\n                        e.e2.error(\"`%s.opBinaryRight` isn't a template\", e.e2.toChars());\n                        result = new ErrorExp();\n                        return;\n                    }\n                    if (s_r && s_r == s) // https://issues.dlang.org/show_bug.cgi?id=12778\n                        s_r = null;\n                }\n                // Set tiargs, the template argument list, which will be the operator string\n                if (s || s_r)\n                {\n                    id = Id.opBinary;\n                    id_r = Id.opBinaryRight;\n                    tiargs = opToArg(sc, e.op);\n                }\n            }\n            if (s || s_r)\n            {\n                /* Try:\n                 *      a.opfunc(b)\n                 *      b.opfunc_r(a)\n                 * and see which is better.\n                 */\n                args1.setDim(1);\n                args1[0] = e.e1;\n                expandTuples(&args1);\n                args2.setDim(1);\n                args2[0] = e.e2;\n                expandTuples(&args2);\n                argsset = 1;\n                Match m;\n                m.last = MATCH.nomatch;\n                if (s)\n                {\n                    functionResolve(&m, s, e.loc, sc, tiargs, e.e1.type, &args2);\n                    if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors))\n                    {\n                        result = new ErrorExp();\n                        return;\n                    }\n                }\n                FuncDeclaration lastf = m.lastf;\n                if (s_r)\n                {\n                    functionResolve(&m, s_r, e.loc, sc, tiargs, e.e2.type, &args1);\n                    if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors))\n                    {\n                        result = new ErrorExp();\n                        return;\n                    }\n                }\n                if (m.count > 1)\n                {\n                    // Error, ambiguous\n                    e.error(\"overloads `%s` and `%s` both match argument list for `%s`\", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars());\n                }\n                else if (m.last <= MATCH.nomatch)\n                {\n                    m.lastf = m.anyf;\n                    if (tiargs)\n                        goto L1;\n                }\n                if (e.op == TOK.plusPlus || e.op == TOK.minusMinus)\n                {\n                    // Kludge because operator overloading regards e++ and e--\n                    // as unary, but it's implemented as a binary.\n                    // Rewrite (e1 ++ e2) as e1.postinc()\n                    // Rewrite (e1 -- e2) as e1.postdec()\n                    result = build_overload(e.loc, sc, e.e1, null, m.lastf ? m.lastf : s);\n                }\n                else if (lastf && m.lastf == lastf || !s_r && m.last <= MATCH.nomatch)\n                {\n                    // Rewrite (e1 op e2) as e1.opfunc(e2)\n                    result = build_overload(e.loc, sc, e.e1, e.e2, m.lastf ? m.lastf : s);\n                }\n                else\n                {\n                    // Rewrite (e1 op e2) as e2.opfunc_r(e1)\n                    result = build_overload(e.loc, sc, e.e2, e.e1, m.lastf ? m.lastf : s_r);\n                }\n                return;\n            }\n        L1:\n            version (all)\n            {\n                // Retained for D1 compatibility\n                if (isCommutative(e.op) && !tiargs)\n                {\n                    s = null;\n                    s_r = null;\n                    if (ad1 && id_r)\n                    {\n                        s_r = search_function(ad1, id_r);\n                    }\n                    if (ad2 && id)\n                    {\n                        s = search_function(ad2, id);\n                        if (s && s == s_r) // https://issues.dlang.org/show_bug.cgi?id=12778\n                            s = null;\n                    }\n                    if (s || s_r)\n                    {\n                        /* Try:\n                         *  a.opfunc_r(b)\n                         *  b.opfunc(a)\n                         * and see which is better.\n                         */\n                        if (!argsset)\n                        {\n                            args1.setDim(1);\n                            args1[0] = e.e1;\n                            expandTuples(&args1);\n                            args2.setDim(1);\n                            args2[0] = e.e2;\n                            expandTuples(&args2);\n                        }\n                        Match m;\n                        m.last = MATCH.nomatch;\n                        if (s_r)\n                        {\n                            functionResolve(&m, s_r, e.loc, sc, tiargs, e.e1.type, &args2);\n                            if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors))\n                            {\n                                result = new ErrorExp();\n                                return;\n                            }\n                        }\n                        FuncDeclaration lastf = m.lastf;\n                        if (s)\n                        {\n                            functionResolve(&m, s, e.loc, sc, tiargs, e.e2.type, &args1);\n                            if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors))\n                            {\n                                result = new ErrorExp();\n                                return;\n                            }\n                        }\n                        if (m.count > 1)\n                        {\n                            // Error, ambiguous\n                            e.error(\"overloads `%s` and `%s` both match argument list for `%s`\", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars());\n                        }\n                        else if (m.last <= MATCH.nomatch)\n                        {\n                            m.lastf = m.anyf;\n                        }\n                        if (lastf && m.lastf == lastf || !s && m.last <= MATCH.nomatch)\n                        {\n                            // Rewrite (e1 op e2) as e1.opfunc_r(e2)\n                            result = build_overload(e.loc, sc, e.e1, e.e2, m.lastf ? m.lastf : s_r);\n                        }\n                        else\n                        {\n                            // Rewrite (e1 op e2) as e2.opfunc(e1)\n                            result = build_overload(e.loc, sc, e.e2, e.e1, m.lastf ? m.lastf : s);\n                        }\n                        // When reversing operands of comparison operators,\n                        // need to reverse the sense of the op\n                        switch (e.op)\n                        {\n                        case TOK.lessThan:\n                            e.op = TOK.greaterThan;\n                            break;\n                        case TOK.greaterThan:\n                            e.op = TOK.lessThan;\n                            break;\n                        case TOK.lessOrEqual:\n                            e.op = TOK.greaterOrEqual;\n                            break;\n                        case TOK.greaterOrEqual:\n                            e.op = TOK.lessOrEqual;\n                            break;\n                        default:\n                            break;\n                        }\n                        return;\n                    }\n                }\n            }\n\n            if (!(e.op == TOK.assign && ad2 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943\n            {\n                result = checkAliasThisForLhs(ad1, sc, e);\n                if (result)\n                    return;\n            }\n            if (!(e.op == TOK.assign && ad1 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943\n            {\n                result = checkAliasThisForRhs(ad2, sc, e);\n                return;\n            }\n        }\n\n        override void visit(EqualExp e)\n        {\n            //printf(\"EqualExp::op_overload() (%s)\\n\", e.toChars());\n            Type t1 = e.e1.type.toBasetype();\n            Type t2 = e.e2.type.toBasetype();\n\n            /* Check for array equality.\n             */\n            if ((t1.ty == Tarray || t1.ty == Tsarray) &&\n                (t2.ty == Tarray || t2.ty == Tsarray))\n            {\n                bool needsDirectEq()\n                {\n                    Type t1n = t1.nextOf().toBasetype();\n                    Type t2n = t2.nextOf().toBasetype();\n                    if (((t1n.ty == Tchar || t1n.ty == Twchar || t1n.ty == Tdchar) &&\n                         (t2n.ty == Tchar || t2n.ty == Twchar || t2n.ty == Tdchar)) ||\n                        (t1n.ty == Tvoid || t2n.ty == Tvoid))\n                    {\n                        return false;\n                    }\n                    if (t1n.constOf() != t2n.constOf())\n                        return true;\n\n                    Type t = t1n;\n                    while (t.toBasetype().nextOf())\n                        t = t.nextOf().toBasetype();\n                    if (t.ty != Tstruct)\n                        return false;\n\n                    if (global.params.useTypeInfo && Type.dtypeinfo)\n                        semanticTypeInfo(sc, t);\n\n                    return (cast(TypeStruct)t).sym.hasIdentityEquals;\n                }\n\n                if (needsDirectEq() && !(t1.ty == Tarray && t2.ty == Tarray))\n                {\n                    /* Rewrite as:\n                     *      __ArrayEq(e1, e2)\n                     */\n                    Expression eeq = new IdentifierExp(e.loc, Id.__ArrayEq);\n                    result = new CallExp(e.loc, eeq, e.e1, e.e2);\n                    if (e.op == TOK.notEqual)\n                        result = new NotExp(e.loc, result);\n                    result = result.trySemantic(sc); // for better error message\n                    if (!result)\n                    {\n                        e.error(\"cannot compare `%s` and `%s`\", t1.toChars(), t2.toChars());\n                        result = new ErrorExp();\n                    }\n                    return;\n                }\n            }\n\n            /* Check for class equality with null literal or typeof(null).\n             */\n            if (t1.ty == Tclass && e.e2.op == TOK.null_ ||\n                t2.ty == Tclass && e.e1.op == TOK.null_)\n            {\n                e.error(\"use `%s` instead of `%s` when comparing with `null`\",\n                    Token.toChars(e.op == TOK.equal ? TOK.identity : TOK.notIdentity),\n                    Token.toChars(e.op));\n                result = new ErrorExp();\n                return;\n            }\n            if (t1.ty == Tclass && t2.ty == Tnull ||\n                t1.ty == Tnull && t2.ty == Tclass)\n            {\n                // Comparing a class with typeof(null) should not call opEquals\n                return;\n            }\n\n            /* Check for class equality.\n             */\n            if (t1.ty == Tclass && t2.ty == Tclass)\n            {\n                ClassDeclaration cd1 = t1.isClassHandle();\n                ClassDeclaration cd2 = t2.isClassHandle();\n                if (!(cd1.classKind == ClassKind.cpp || cd2.classKind == ClassKind.cpp))\n                {\n                    /* Rewrite as:\n                     *      .object.opEquals(e1, e2)\n                     */\n                    Expression e1x = e.e1;\n                    Expression e2x = e.e2;\n\n                    /* The explicit cast is necessary for interfaces\n                     * https://issues.dlang.org/show_bug.cgi?id=4088\n                     */\n                    Type to = ClassDeclaration.object.getType();\n                    if (cd1.isInterfaceDeclaration())\n                        e1x = new CastExp(e.loc, e.e1, t1.isMutable() ? to : to.constOf());\n                    if (cd2.isInterfaceDeclaration())\n                        e2x = new CastExp(e.loc, e.e2, t2.isMutable() ? to : to.constOf());\n\n                    result = new IdentifierExp(e.loc, Id.empty);\n                    result = new DotIdExp(e.loc, result, Id.object);\n                    result = new DotIdExp(e.loc, result, Id.eq);\n                    result = new CallExp(e.loc, result, e1x, e2x);\n                    if (e.op == TOK.notEqual)\n                        result = new NotExp(e.loc, result);\n                    result = result.expressionSemantic(sc);\n                    return;\n                }\n            }\n\n            result = compare_overload(e, sc, Id.eq);\n            if (result)\n            {\n                if (result.op == TOK.call && e.op == TOK.notEqual)\n                {\n                    result = new NotExp(result.loc, result);\n                    result = result.expressionSemantic(sc);\n                }\n                return;\n            }\n\n            if (t1.ty == Tarray && t2.ty == Tarray)\n                return;\n\n            /* Check for pointer equality.\n             */\n            if (t1.ty == Tpointer || t2.ty == Tpointer)\n            {\n                /* Rewrite:\n                 *      ptr1 == ptr2\n                 * as:\n                 *      ptr1 is ptr2\n                 *\n                 * This is just a rewriting for deterministic AST representation\n                 * as the backend input.\n                 */\n                auto op2 = e.op == TOK.equal ? TOK.identity : TOK.notIdentity;\n                result = new IdentityExp(op2, e.loc, e.e1, e.e2);\n                result = result.expressionSemantic(sc);\n                return;\n            }\n\n            /* Check for struct equality without opEquals.\n             */\n            if (t1.ty == Tstruct && t2.ty == Tstruct)\n            {\n                auto sd = (cast(TypeStruct)t1).sym;\n                if (sd != (cast(TypeStruct)t2).sym)\n                    return;\n\n                import dmd.clone : needOpEquals;\n                if (!needOpEquals(sd))\n                {\n                    // Use bitwise equality.\n                    auto op2 = e.op == TOK.equal ? TOK.identity : TOK.notIdentity;\n                    result = new IdentityExp(op2, e.loc, e.e1, e.e2);\n                    result = result.expressionSemantic(sc);\n                    return;\n                }\n\n                /* Do memberwise equality.\n                 * Rewrite:\n                 *      e1 == e2\n                 * as:\n                 *      e1.tupleof == e2.tupleof\n                 *\n                 * If sd is a nested struct, and if it's nested in a class, it will\n                 * also compare the parent class's equality. Otherwise, compares\n                 * the identity of parent context through void*.\n                 */\n                if (e.att1 && t1 == e.att1) return;\n                if (e.att2 && t2 == e.att2) return;\n\n                e = cast(EqualExp)e.copy();\n                if (!e.att1) e.att1 = t1;\n                if (!e.att2) e.att2 = t2;\n                e.e1 = new DotIdExp(e.loc, e.e1, Id._tupleof);\n                e.e2 = new DotIdExp(e.loc, e.e2, Id._tupleof);\n                result = e.expressionSemantic(sc);\n\n                /* https://issues.dlang.org/show_bug.cgi?id=15292\n                 * if the rewrite result is same with the original,\n                 * the equality is unresolvable because it has recursive definition.\n                 */\n                if (result.op == e.op &&\n                    (cast(EqualExp)result).e1.type.toBasetype() == t1)\n                {\n                    e.error(\"cannot compare `%s` because its auto generated member-wise equality has recursive definition\",\n                        t1.toChars());\n                    result = new ErrorExp();\n                }\n                return;\n            }\n\n            /* Check for tuple equality.\n             */\n            if (e.e1.op == TOK.tuple && e.e2.op == TOK.tuple)\n            {\n                auto tup1 = cast(TupleExp)e.e1;\n                auto tup2 = cast(TupleExp)e.e2;\n                size_t dim = tup1.exps.dim;\n                if (dim != tup2.exps.dim)\n                {\n                    e.error(\"mismatched tuple lengths, `%d` and `%d`\",\n                        cast(int)dim, cast(int)tup2.exps.dim);\n                    result = new ErrorExp();\n                    return;\n                }\n\n                if (dim == 0)\n                {\n                    // zero-length tuple comparison should always return true or false.\n                    result = new IntegerExp(e.loc, (e.op == TOK.equal), Type.tbool);\n                }\n                else\n                {\n                    for (size_t i = 0; i < dim; i++)\n                    {\n                        auto ex1 = (*tup1.exps)[i];\n                        auto ex2 = (*tup2.exps)[i];\n                        auto eeq = new EqualExp(e.op, e.loc, ex1, ex2);\n                        eeq.att1 = e.att1;\n                        eeq.att2 = e.att2;\n\n                        if (!result)\n                            result = eeq;\n                        else if (e.op == TOK.equal)\n                            result = new LogicalExp(e.loc, TOK.andAnd, result, eeq);\n                        else\n                            result = new LogicalExp(e.loc, TOK.orOr, result, eeq);\n                    }\n                    assert(result);\n                }\n                result = Expression.combine(tup1.e0, tup2.e0, result);\n                result = result.expressionSemantic(sc);\n\n                return;\n            }\n        }\n\n        override void visit(CmpExp e)\n        {\n            //printf(\"CmpExp:: () (%s)\\n\", e.toChars());\n            result = compare_overload(e, sc, Id.cmp);\n        }\n\n        /*********************************\n         * Operator overloading for op=\n         */\n        override void visit(BinAssignExp e)\n        {\n            //printf(\"BinAssignExp::op_overload() (%s)\\n\", e.toChars());\n            if (e.e1.op == TOK.array)\n            {\n                ArrayExp ae = cast(ArrayExp)e.e1;\n                ae.e1 = ae.e1.expressionSemantic(sc);\n                ae.e1 = resolveProperties(sc, ae.e1);\n                Expression ae1old = ae.e1;\n                const(bool) maybeSlice = (ae.arguments.dim == 0 || ae.arguments.dim == 1 && (*ae.arguments)[0].op == TOK.interval);\n                IntervalExp ie = null;\n                if (maybeSlice && ae.arguments.dim)\n                {\n                    assert((*ae.arguments)[0].op == TOK.interval);\n                    ie = cast(IntervalExp)(*ae.arguments)[0];\n                }\n                while (true)\n                {\n                    if (ae.e1.op == TOK.error)\n                    {\n                        result = ae.e1;\n                        return;\n                    }\n                    Expression e0 = null;\n                    Expression ae1save = ae.e1;\n                    ae.lengthVar = null;\n                    Type t1b = ae.e1.type.toBasetype();\n                    AggregateDeclaration ad = isAggregate(t1b);\n                    if (!ad)\n                        break;\n                    if (search_function(ad, Id.opIndexOpAssign))\n                    {\n                        // Deal with $\n                        result = resolveOpDollar(sc, ae, &e0);\n                        if (!result) // (a[i..j] op= e2) might be: a.opSliceOpAssign!(op)(e2, i, j)\n                            goto Lfallback;\n                        if (result.op == TOK.error)\n                            return;\n                        result = e.e2.expressionSemantic(sc);\n                        if (result.op == TOK.error)\n                            return;\n                        e.e2 = result;\n                        /* Rewrite a[arguments] op= e2 as:\n                         *      a.opIndexOpAssign!(op)(e2, arguments)\n                         */\n                        Expressions* a = ae.arguments.copy();\n                        a.insert(0, e.e2);\n                        Objects* tiargs = opToArg(sc, e.op);\n                        result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opIndexOpAssign, tiargs);\n                        result = new CallExp(e.loc, result, a);\n                        if (maybeSlice) // (a[] op= e2) might be: a.opSliceOpAssign!(op)(e2)\n                            result = result.trySemantic(sc);\n                        else\n                            result = result.expressionSemantic(sc);\n                        if (result)\n                        {\n                            result = Expression.combine(e0, result);\n                            return;\n                        }\n                    }\n                Lfallback:\n                    if (maybeSlice && search_function(ad, Id.opSliceOpAssign))\n                    {\n                        // Deal with $\n                        result = resolveOpDollar(sc, ae, ie, &e0);\n                        if (result.op == TOK.error)\n                            return;\n                        result = e.e2.expressionSemantic(sc);\n                        if (result.op == TOK.error)\n                            return;\n                        e.e2 = result;\n                        /* Rewrite (a[i..j] op= e2) as:\n                         *      a.opSliceOpAssign!(op)(e2, i, j)\n                         */\n                        auto a = new Expressions();\n                        a.push(e.e2);\n                        if (ie)\n                        {\n                            a.push(ie.lwr);\n                            a.push(ie.upr);\n                        }\n                        Objects* tiargs = opToArg(sc, e.op);\n                        result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opSliceOpAssign, tiargs);\n                        result = new CallExp(e.loc, result, a);\n                        result = result.expressionSemantic(sc);\n                        result = Expression.combine(e0, result);\n                        return;\n                    }\n                    // Didn't find it. Forward to aliasthis\n                    if (ad.aliasthis && t1b != ae.att1)\n                    {\n                        if (!ae.att1 && t1b.checkAliasThisRec())\n                            ae.att1 = t1b;\n                        /* Rewrite (a[arguments] op= e2) as:\n                         *      a.aliasthis[arguments] op= e2\n                         */\n                        ae.e1 = resolveAliasThis(sc, ae1save, true);\n                        if (ae.e1)\n                            continue;\n                    }\n                    break;\n                }\n                ae.e1 = ae1old; // recovery\n                ae.lengthVar = null;\n            }\n            result = e.binSemanticProp(sc);\n            if (result)\n                return;\n            // Don't attempt 'alias this' if an error occurred\n            if (e.e1.type.ty == Terror || e.e2.type.ty == Terror)\n            {\n                result = new ErrorExp();\n                return;\n            }\n            Identifier id = opId(e);\n            Expressions args2;\n            AggregateDeclaration ad1 = isAggregate(e.e1.type);\n            Dsymbol s = null;\n            version (all)\n            {\n                // the old D1 scheme\n                if (ad1 && id)\n                {\n                    s = search_function(ad1, id);\n                }\n            }\n            Objects* tiargs = null;\n            if (!s)\n            {\n                /* Try the new D2 scheme, opOpAssign\n                 */\n                if (ad1)\n                {\n                    s = search_function(ad1, Id.opOpAssign);\n                    if (s && !s.isTemplateDeclaration())\n                    {\n                        e.error(\"`%s.opOpAssign` isn't a template\", e.e1.toChars());\n                        result = new ErrorExp();\n                        return;\n                    }\n                }\n                // Set tiargs, the template argument list, which will be the operator string\n                if (s)\n                {\n                    id = Id.opOpAssign;\n                    tiargs = opToArg(sc, e.op);\n                }\n            }\n            if (s)\n            {\n                /* Try:\n                 *      a.opOpAssign(b)\n                 */\n                args2.setDim(1);\n                args2[0] = e.e2;\n                expandTuples(&args2);\n                Match m;\n                m.last = MATCH.nomatch;\n                if (s)\n                {\n                    functionResolve(&m, s, e.loc, sc, tiargs, e.e1.type, &args2);\n                    if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors))\n                    {\n                        result = new ErrorExp();\n                        return;\n                    }\n                }\n                if (m.count > 1)\n                {\n                    // Error, ambiguous\n                    e.error(\"overloads `%s` and `%s` both match argument list for `%s`\", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars());\n                }\n                else if (m.last <= MATCH.nomatch)\n                {\n                    m.lastf = m.anyf;\n                    if (tiargs)\n                        goto L1;\n                }\n                // Rewrite (e1 op e2) as e1.opOpAssign(e2)\n                result = build_overload(e.loc, sc, e.e1, e.e2, m.lastf ? m.lastf : s);\n                return;\n            }\n        L1:\n            result = checkAliasThisForLhs(ad1, sc, e);\n            if (result)\n                return;\n\n            result = checkAliasThisForRhs(isAggregate(e.e2.type), sc, e);\n        }\n    }\n\n    scope OpOverload v = new OpOverload(sc);\n    e.accept(v);\n    return v.result;\n}\n\n/******************************************\n * Common code for overloading of EqualExp and CmpExp\n */\nprivate Expression compare_overload(BinExp e, Scope* sc, Identifier id)\n{\n    //printf(\"BinExp::compare_overload(id = %s) %s\\n\", id.toChars(), e.toChars());\n    AggregateDeclaration ad1 = isAggregate(e.e1.type);\n    AggregateDeclaration ad2 = isAggregate(e.e2.type);\n    Dsymbol s = null;\n    Dsymbol s_r = null;\n    if (ad1)\n    {\n        s = search_function(ad1, id);\n    }\n    if (ad2)\n    {\n        s_r = search_function(ad2, id);\n        if (s == s_r)\n            s_r = null;\n    }\n    Objects* tiargs = null;\n    if (s || s_r)\n    {\n        /* Try:\n         *      a.opEquals(b)\n         *      b.opEquals(a)\n         * and see which is better.\n         */\n        Expressions args1 = Expressions(1);\n        args1[0] = e.e1;\n        expandTuples(&args1);\n        Expressions args2 = Expressions(1);\n        args2[0] = e.e2;\n        expandTuples(&args2);\n        Match m;\n        m.last = MATCH.nomatch;\n        if (0 && s && s_r)\n        {\n            printf(\"s  : %s\\n\", s.toPrettyChars());\n            printf(\"s_r: %s\\n\", s_r.toPrettyChars());\n        }\n        if (s)\n        {\n            functionResolve(&m, s, e.loc, sc, tiargs, e.e1.type, &args2);\n            if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors))\n                return new ErrorExp();\n        }\n        FuncDeclaration lastf = m.lastf;\n        int count = m.count;\n        if (s_r)\n        {\n            functionResolve(&m, s_r, e.loc, sc, tiargs, e.e2.type, &args1);\n            if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors))\n                return new ErrorExp();\n        }\n        if (m.count > 1)\n        {\n            /* The following if says \"not ambiguous\" if there's one match\n             * from s and one from s_r, in which case we pick s.\n             * This doesn't follow the spec, but is a workaround for the case\n             * where opEquals was generated from templates and we cannot figure\n             * out if both s and s_r came from the same declaration or not.\n             * The test case is:\n             *   import std.typecons;\n             *   void main() {\n             *    assert(tuple(\"has a\", 2u) == tuple(\"has a\", 1));\n             *   }\n             */\n            if (!(m.lastf == lastf && m.count == 2 && count == 1))\n            {\n                // Error, ambiguous\n                e.error(\"overloads `%s` and `%s` both match argument list for `%s`\", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars());\n            }\n        }\n        else if (m.last <= MATCH.nomatch)\n        {\n            m.lastf = m.anyf;\n        }\n        Expression result;\n        if (lastf && m.lastf == lastf || !s_r && m.last <= MATCH.nomatch)\n        {\n            // Rewrite (e1 op e2) as e1.opfunc(e2)\n            result = build_overload(e.loc, sc, e.e1, e.e2, m.lastf ? m.lastf : s);\n        }\n        else\n        {\n            // Rewrite (e1 op e2) as e2.opfunc_r(e1)\n            result = build_overload(e.loc, sc, e.e2, e.e1, m.lastf ? m.lastf : s_r);\n            // When reversing operands of comparison operators,\n            // need to reverse the sense of the op\n            switch (e.op)\n            {\n            case TOK.lessThan:\n                e.op = TOK.greaterThan;\n                break;\n            case TOK.greaterThan:\n                e.op = TOK.lessThan;\n                break;\n            case TOK.lessOrEqual:\n                e.op = TOK.greaterOrEqual;\n                break;\n            case TOK.greaterOrEqual:\n                e.op = TOK.lessOrEqual;\n                break;\n            default:\n                break;\n            }\n        }\n        return result;\n    }\n    Expression result = checkAliasThisForLhs(ad1, sc, e);\n    return result ? result : checkAliasThisForRhs(isAggregate(e.e2.type), sc, e);\n}\n\n/***********************************\n * Utility to build a function call out of this reference and argument.\n */\nExpression build_overload(const ref Loc loc, Scope* sc, Expression ethis, Expression earg, Dsymbol d)\n{\n    assert(d);\n    Expression e;\n    Declaration decl = d.isDeclaration();\n    if (decl)\n        e = new DotVarExp(loc, ethis, decl, false);\n    else\n        e = new DotIdExp(loc, ethis, d.ident);\n    e = new CallExp(loc, e, earg);\n    e = e.expressionSemantic(sc);\n    return e;\n}\n\n/***************************************\n * Search for function funcid in aggregate ad.\n */\nDsymbol search_function(ScopeDsymbol ad, Identifier funcid)\n{\n    Dsymbol s = ad.search(Loc.initial, funcid);\n    if (s)\n    {\n        //printf(\"search_function: s = '%s'\\n\", s.kind());\n        Dsymbol s2 = s.toAlias();\n        //printf(\"search_function: s2 = '%s'\\n\", s2.kind());\n        FuncDeclaration fd = s2.isFuncDeclaration();\n        if (fd && fd.type.ty == Tfunction)\n            return fd;\n        TemplateDeclaration td = s2.isTemplateDeclaration();\n        if (td)\n            return td;\n    }\n    return null;\n}\n\n/**************************************\n * Figure out what is being foreach'd over by looking at the ForeachAggregate.\n * Params:\n *      sc = context\n *      isForeach = true for foreach, false for foreach_reverse\n *      feaggr = ForeachAggregate\n *      sapply = set to function opApply/opApplyReverse, or delegate, or null.\n *               Overload resolution is not done.\n * Returns:\n *      true if successfully figured it out; feaggr updated with semantic analysis.\n *      false for failed, which is an error.\n */\nbool inferForeachAggregate(Scope* sc, bool isForeach, ref Expression feaggr, out Dsymbol sapply)\n{\n    //printf(\"inferForeachAggregate(%s)\\n\", feaggr.toChars());\n    bool sliced;\n    Type att = null;\n    auto aggr = feaggr;\n    while (1)\n    {\n        aggr = aggr.expressionSemantic(sc);\n        aggr = resolveProperties(sc, aggr);\n        aggr = aggr.optimize(WANTvalue);\n        if (!aggr.type || aggr.op == TOK.error)\n            return false;\n        Type tab = aggr.type.toBasetype();\n        switch (tab.ty)\n        {\n        case Tarray:            // https://dlang.org/spec/statement.html#foreach_over_arrays\n        case Tsarray:           // https://dlang.org/spec/statement.html#foreach_over_arrays\n        case Ttuple:            // https://dlang.org/spec/statement.html#foreach_over_tuples\n        case Taarray:           // https://dlang.org/spec/statement.html#foreach_over_associative_arrays\n            break;\n\n        case Tclass:\n        case Tstruct:\n        {\n            AggregateDeclaration ad = (tab.ty == Tclass) ? (cast(TypeClass)tab).sym\n                                                         : (cast(TypeStruct)tab).sym;\n            if (!sliced)\n            {\n                sapply = search_function(ad, isForeach ? Id.apply : Id.applyReverse);\n                if (sapply)\n                {\n                    // https://dlang.org/spec/statement.html#foreach_over_struct_and_classes\n                    // opApply aggregate\n                    break;\n                }\n                if (feaggr.op != TOK.type)\n                {\n                    /* See if rewriting `aggr` to `aggr[]` will work\n                     */\n                    Expression rinit = new ArrayExp(aggr.loc, feaggr);\n                    rinit = rinit.trySemantic(sc);\n                    if (rinit) // if it worked\n                    {\n                        aggr = rinit;\n                        sliced = true;  // only try it once\n                        continue;\n                    }\n                }\n            }\n            if (ad.search(Loc.initial, isForeach ? Id.Ffront : Id.Fback))\n            {\n                // https://dlang.org/spec/statement.html#foreach-with-ranges\n                // range aggregate\n                break;\n            }\n            if (ad.aliasthis)\n            {\n                if (att == tab)         // error, circular alias this\n                    return false;\n                if (!att && tab.checkAliasThisRec())\n                    att = tab;\n                aggr = resolveAliasThis(sc, aggr);\n                continue;\n            }\n            return false;\n        }\n\n        case Tdelegate:        // https://dlang.org/spec/statement.html#foreach_over_delegates\n            if (aggr.op == TOK.delegate_)\n            {\n                sapply = (cast(DelegateExp)aggr).func;\n            }\n            break;\n\n        case Terror:\n            break;\n\n        default:\n            return false;\n        }\n        feaggr = aggr;\n        return true;\n    }\n    assert(0);\n}\n\n/*****************************************\n * Given array of foreach parameters and an aggregate type,\n * find best opApply overload,\n * if any of the parameter types are missing, attempt to infer\n * them from the aggregate type.\n * Params:\n *      fes = the foreach statement\n *      sc = context\n *      sapply = null or opApply or delegate\n * Returns:\n *      false for errors\n */\nbool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)\n{\n    if (!fes.parameters || !fes.parameters.dim)\n        return false;\n    if (sapply) // prefer opApply\n    {\n        foreach (Parameter p; *fes.parameters)\n        {\n            if (p.type)\n            {\n                p.type = p.type.typeSemantic(fes.loc, sc);\n                p.type = p.type.addStorageClass(p.storageClass);\n            }\n        }\n\n        // Determine ethis for sapply\n        Expression ethis;\n        Type tab = fes.aggr.type.toBasetype();\n        if (tab.ty == Tclass || tab.ty == Tstruct)\n            ethis = fes.aggr;\n        else\n        {\n            assert(tab.ty == Tdelegate && fes.aggr.op == TOK.delegate_);\n            ethis = (cast(DelegateExp)fes.aggr).e1;\n        }\n\n        /* Look for like an\n         *  int opApply(int delegate(ref Type [, ...]) dg);\n         * overload\n         */\n        if (FuncDeclaration fd = sapply.isFuncDeclaration())\n        {\n            auto fdapply = findBestOpApplyMatch(ethis, fd, fes.parameters);\n            if (fdapply)\n            {\n                // Fill in any missing types on foreach parameters[]\n                matchParamsToOpApply(cast(TypeFunction)fdapply.type, fes.parameters, true);\n                sapply = fdapply;\n                return true;\n            }\n            return false;\n        }\n        return sapply !is null;\n    }\n\n    Parameter p = (*fes.parameters)[0];\n    Type taggr = fes.aggr.type;\n    assert(taggr);\n    Type tab = taggr.toBasetype();\n    switch (tab.ty)\n    {\n    case Tarray:\n    case Tsarray:\n    case Ttuple:\n        if (fes.parameters.dim == 2)\n        {\n            if (!p.type)\n            {\n                p.type = Type.tsize_t; // key type\n                p.type = p.type.addStorageClass(p.storageClass);\n            }\n            p = (*fes.parameters)[1];\n        }\n        if (!p.type && tab.ty != Ttuple)\n        {\n            p.type = tab.nextOf(); // value type\n            p.type = p.type.addStorageClass(p.storageClass);\n        }\n        break;\n\n    case Taarray:\n        {\n            TypeAArray taa = cast(TypeAArray)tab;\n            if (fes.parameters.dim == 2)\n            {\n                if (!p.type)\n                {\n                    p.type = taa.index; // key type\n                    p.type = p.type.addStorageClass(p.storageClass);\n                    if (p.storageClass & STC.ref_) // key must not be mutated via ref\n                        p.type = p.type.addMod(MODFlags.const_);\n                }\n                p = (*fes.parameters)[1];\n            }\n            if (!p.type)\n            {\n                p.type = taa.next; // value type\n                p.type = p.type.addStorageClass(p.storageClass);\n            }\n            break;\n        }\n\n    case Tclass:\n    case Tstruct:\n    {\n        AggregateDeclaration ad = (tab.ty == Tclass) ? (cast(TypeClass)tab).sym\n                                                     : (cast(TypeStruct)tab).sym;\n        if (fes.parameters.dim == 1)\n        {\n            if (!p.type)\n            {\n                /* Look for a front() or back() overload\n                 */\n                Identifier id = (fes.op == TOK.foreach_) ? Id.Ffront : Id.Fback;\n                Dsymbol s = ad.search(Loc.initial, id);\n                FuncDeclaration fd = s ? s.isFuncDeclaration() : null;\n                if (fd)\n                {\n                    // Resolve inout qualifier of front type\n                    p.type = fd.type.nextOf();\n                    if (p.type)\n                    {\n                        p.type = p.type.substWildTo(tab.mod);\n                        p.type = p.type.addStorageClass(p.storageClass);\n                    }\n                }\n                else if (s && s.isTemplateDeclaration())\n                {\n                }\n                else if (s && s.isDeclaration())\n                    p.type = (cast(Declaration)s).type;\n                else\n                    break;\n            }\n            break;\n        }\n        break;\n    }\n\n    case Tdelegate:\n        if (!matchParamsToOpApply(cast(TypeFunction)tab.nextOf(), fes.parameters, true))\n            return false;\n        break;\n\n    default:\n        break; // ignore error, caught later\n    }\n    return true;\n}\n\n/*********************************************\n * Find best overload match on fstart given ethis and parameters[].\n * Params:\n *      ethis = expression to use for `this`\n *      fstart = opApply or foreach delegate\n *      parameters = ForeachTypeList (i.e. foreach parameters)\n * Returns:\n *      best match if there is one, null if error\n */\nprivate FuncDeclaration findBestOpApplyMatch(Expression ethis, FuncDeclaration fstart, Parameters* parameters)\n{\n    MOD mod = ethis.type.mod;\n    MATCH match = MATCH.nomatch;\n    FuncDeclaration fd_best;\n    FuncDeclaration fd_ambig;\n\n    overloadApply(fstart, (Dsymbol s)\n    {\n        auto f = s.isFuncDeclaration();\n        if (!f)\n            return 0;           // continue\n        auto tf = cast(TypeFunction)f.type;\n        MATCH m = MATCH.exact;\n        if (f.isThis())\n        {\n            if (!MODimplicitConv(mod, tf.mod))\n                m = MATCH.nomatch;\n            else if (mod != tf.mod)\n                m = MATCH.constant;\n        }\n        if (!matchParamsToOpApply(tf, parameters, false))\n            m = MATCH.nomatch;\n        if (m > match)\n        {\n            fd_best = f;\n            fd_ambig = null;\n            match = m;\n        }\n        else if (m == match && m > MATCH.nomatch)\n        {\n            assert(fd_best);\n            /* Ignore covariant matches, as later on it can be redone\n             * after the opApply delegate has its attributes inferred.\n             */\n            if (tf.covariant(fd_best.type) != 1 &&\n                fd_best.type.covariant(tf) != 1)\n                fd_ambig = f;                           // not covariant, so ambiguous\n        }\n        return 0;               // continue\n    });\n\n    if (fd_ambig)\n    {\n        .error(ethis.loc, \"`%s.%s` matches more than one declaration:\\n`%s`:     `%s`\\nand:\\n`%s`:     `%s`\",\n            ethis.toChars(), fstart.ident.toChars(),\n            fd_best.loc.toChars(), fd_best.type.toChars(),\n            fd_ambig.loc.toChars(), fd_ambig.type.toChars());\n        return null;\n    }\n\n    return fd_best;\n}\n\n/******************************\n * Determine if foreach parameters match opApply parameters.\n * Infer missing foreach parameter types from type of opApply delegate.\n * Params:\n *      tf = type of opApply or delegate\n *      parameters = foreach parameters\n *      infer = infer missing parameter types\n * Returns:\n *      true for match for this function\n *      false for no match for this function\n */\nprivate bool matchParamsToOpApply(TypeFunction tf, Parameters* parameters, bool infer)\n{\n    enum nomatch = false;\n\n    /* opApply/delegate has exactly one parameter, and that parameter\n     * is a delegate that looks like:\n     *     int opApply(int delegate(ref Type [, ...]) dg);\n     */\n    if (Parameter.dim(tf.parameters) != 1)\n        return nomatch;\n\n    /* Get the type of opApply's dg parameter\n     */\n    Parameter p0 = Parameter.getNth(tf.parameters, 0);\n    if (p0.type.ty != Tdelegate)\n        return nomatch;\n    TypeFunction tdg = cast(TypeFunction)p0.type.nextOf();\n    assert(tdg.ty == Tfunction);\n\n    /* We now have tdg, the type of the delegate.\n     * tdg's parameters must match that of the foreach arglist (i.e. parameters).\n     * Fill in missing types in parameters.\n     */\n    const nparams = Parameter.dim(tdg.parameters);\n    if (nparams == 0 || nparams != parameters.dim || tdg.varargs)\n        return nomatch; // parameter mismatch\n\n    foreach (u, p; *parameters)\n    {\n        Parameter param = Parameter.getNth(tdg.parameters, u);\n        if (p.type)\n        {\n            if (!p.type.equals(param.type))\n                return nomatch;\n        }\n        else if (infer)\n        {\n            p.type = param.type;\n            p.type = p.type.addStorageClass(p.storageClass);\n        }\n    }\n    return true;\n}\n"
  },
  {
    "path": "gcc/d/dmd/optimize.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/optimize.d, _optimize.d)\n * Documentation:  https://dlang.org/phobos/dmd_optimize.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/optimize.d\n */\n\nmodule dmd.optimize;\n\nimport core.stdc.stdio;\n\nimport dmd.constfold;\nimport dmd.ctfeexpr;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.globals;\nimport dmd.init;\nimport dmd.mtype;\nimport dmd.root.ctfloat;\nimport dmd.sideeffect;\nimport dmd.tokens;\nimport dmd.visitor;\n\n/*************************************\n * If variable has a const initializer,\n * return that initializer.\n * Returns:\n *      initializer if there is one,\n *      null if not,\n *      ErrorExp if error\n */\nExpression expandVar(int result, VarDeclaration v)\n{\n    //printf(\"expandVar(result = %d, v = %p, %s)\\n\", result, v, v ? v.toChars() : \"null\");\n\n    /********\n     * Params:\n     *  e = initializer expression\n     */\n    Expression initializerReturn(Expression e)\n    {\n        if (e.type != v.type)\n        {\n            e = e.castTo(null, v.type);\n        }\n        v.inuse++;\n        e = e.optimize(result);\n        v.inuse--;\n        //if (e) printf(\"\\te = %p, %s, e.type = %d, %s\\n\", e, e.toChars(), e.type.ty, e.type.toChars());\n        return e;\n    }\n\n    static Expression nullReturn()\n    {\n        return null;\n    }\n\n    static Expression errorReturn()\n    {\n        return new ErrorExp();\n    }\n\n    if (!v)\n        return nullReturn();\n    if (!v.originalType && v.semanticRun < PASS.semanticdone) // semantic() not yet run\n        v.dsymbolSemantic(null);\n    if (v.type &&\n        (v.isConst() || v.isImmutable() || v.storage_class & STC.manifest))\n    {\n        Type tb = v.type.toBasetype();\n        if (v.storage_class & STC.manifest ||\n            tb.isscalar() ||\n            ((result & WANTexpand) && (tb.ty != Tsarray && tb.ty != Tstruct)))\n        {\n            if (v._init)\n            {\n                if (v.inuse)\n                {\n                    if (v.storage_class & STC.manifest)\n                    {\n                        v.error(\"recursive initialization of constant\");\n                        return errorReturn();\n                    }\n                    return nullReturn();\n                }\n                Expression ei = v.getConstInitializer();\n                if (!ei)\n                {\n                    if (v.storage_class & STC.manifest)\n                    {\n                        v.error(\"enum cannot be initialized with `%s`\", v._init.toChars());\n                        return errorReturn();\n                    }\n                    return nullReturn();\n                }\n                if (ei.op == TOK.construct || ei.op == TOK.blit)\n                {\n                    AssignExp ae = cast(AssignExp)ei;\n                    ei = ae.e2;\n                    if (ei.isConst() == 1)\n                    {\n                    }\n                    else if (ei.op == TOK.string_)\n                    {\n                        // https://issues.dlang.org/show_bug.cgi?id=14459\n                        // Do not constfold the string literal\n                        // if it's typed as a C string, because the value expansion\n                        // will drop the pointer identity.\n                        if (!(result & WANTexpand) && ei.type.toBasetype().ty == Tpointer)\n                            return nullReturn();\n                    }\n                    else\n                        return nullReturn();\n                    if (ei.type == v.type)\n                    {\n                        // const variable initialized with const expression\n                    }\n                    else if (ei.implicitConvTo(v.type) >= MATCH.constant)\n                    {\n                        // const var initialized with non-const expression\n                        ei = ei.implicitCastTo(null, v.type);\n                        ei = ei.expressionSemantic(null);\n                    }\n                    else\n                        return nullReturn();\n                }\n                else if (!(v.storage_class & STC.manifest) &&\n                         ei.isConst() != 1 &&\n                         ei.op != TOK.string_ &&\n                         ei.op != TOK.address)\n                {\n                    return nullReturn();\n                }\n\n                if (!ei.type)\n                {\n                    return nullReturn();\n                }\n                else\n                {\n                    // Should remove the copy() operation by\n                    // making all mods to expressions copy-on-write\n                    return initializerReturn(ei.copy());\n                }\n            }\n            else\n            {\n                // v does not have an initializer\n                version (all)\n                {\n                    return nullReturn();\n                }\n                else\n                {\n                    // BUG: what if const is initialized in constructor?\n                    auto e = v.type.defaultInit();\n                    e.loc = e1.loc;\n                    return initializerReturn(e);\n                }\n            }\n            assert(0);\n        }\n    }\n    return nullReturn();\n}\n\nprivate Expression fromConstInitializer(int result, Expression e1)\n{\n    //printf(\"fromConstInitializer(result = %x, %s)\\n\", result, e1.toChars());\n    //static int xx; if (xx++ == 10) assert(0);\n    Expression e = e1;\n    if (e1.op == TOK.variable)\n    {\n        VarExp ve = cast(VarExp)e1;\n        VarDeclaration v = ve.var.isVarDeclaration();\n        e = expandVar(result, v);\n        if (e)\n        {\n            // If it is a comma expression involving a declaration, we mustn't\n            // perform a copy -- we'd get two declarations of the same variable.\n            // See bugzilla 4465.\n            if (e.op == TOK.comma && (cast(CommaExp)e).e1.op == TOK.declaration)\n                e = e1;\n            else if (e.type != e1.type && e1.type && e1.type.ty != Tident)\n            {\n                // Type 'paint' operation\n                e = e.copy();\n                e.type = e1.type;\n            }\n            e.loc = e1.loc;\n        }\n        else\n        {\n            e = e1;\n        }\n    }\n    return e;\n}\n\n/* It is possible for constant folding to change an array expression of\n * unknown length, into one where the length is known.\n * If the expression 'arr' is a literal, set lengthVar to be its length.\n */\npackage void setLengthVarIfKnown(VarDeclaration lengthVar, Expression arr)\n{\n    if (!lengthVar)\n        return;\n    if (lengthVar._init && !lengthVar._init.isVoidInitializer())\n        return; // we have previously calculated the length\n    size_t len;\n    if (arr.op == TOK.string_)\n        len = (cast(StringExp)arr).len;\n    else if (arr.op == TOK.arrayLiteral)\n        len = (cast(ArrayLiteralExp)arr).elements.dim;\n    else\n    {\n        Type t = arr.type.toBasetype();\n        if (t.ty == Tsarray)\n            len = cast(size_t)(cast(TypeSArray)t).dim.toInteger();\n        else\n            return; // we don't know the length yet\n    }\n    Expression dollar = new IntegerExp(Loc.initial, len, Type.tsize_t);\n    lengthVar._init = new ExpInitializer(Loc.initial, dollar);\n    lengthVar.storage_class |= STC.static_ | STC.const_;\n}\n\n/* Same as above, but determines the length from 'type'. */\npackage void setLengthVarIfKnown(VarDeclaration lengthVar, Type type)\n{\n    if (!lengthVar)\n        return;\n    if (lengthVar._init && !lengthVar._init.isVoidInitializer())\n        return; // we have previously calculated the length\n    size_t len;\n    Type t = type.toBasetype();\n    if (t.ty == Tsarray)\n        len = cast(size_t)(cast(TypeSArray)t).dim.toInteger();\n    else\n        return; // we don't know the length yet\n    Expression dollar = new IntegerExp(Loc.initial, len, Type.tsize_t);\n    lengthVar._init = new ExpInitializer(Loc.initial, dollar);\n    lengthVar.storage_class |= STC.static_ | STC.const_;\n}\n\n/*********************************\n * Constant fold an Expression.\n * Params:\n *      e = expression to const fold; this may get modified in-place\n *      result = WANTvalue, WANTexpand, or both\n *      keepLvalue = `e` is an lvalue, and keep it as an lvalue since it is\n *                   an argument to a `ref` or `out` parameter, or the operand of `&` operator\n * Returns:\n *      Constant folded version of `e`\n */\nExpression Expression_optimize(Expression e, int result, bool keepLvalue)\n{\n    extern (C++) final class OptimizeVisitor : Visitor\n    {\n        alias visit = Visitor.visit;\n\n        Expression ret;\n        private const int result;\n        private const bool keepLvalue;\n\n        extern (D) this(Expression e, int result, bool keepLvalue)\n        {\n            this.ret = e;               // default result is original expression\n            this.result = result;\n            this.keepLvalue = keepLvalue;\n        }\n\n        void error()\n        {\n            ret = new ErrorExp();\n        }\n\n        bool expOptimize(ref Expression e, int flags, bool keepLvalue = false)\n        {\n            if (!e)\n                return false;\n            Expression ex = Expression_optimize(e, flags, keepLvalue);\n            if (ex.op == TOK.error)\n            {\n                ret = ex; // store error result\n                return true;\n            }\n            else\n            {\n                e = ex; // modify original\n                return false;\n            }\n        }\n\n        bool unaOptimize(UnaExp e, int flags)\n        {\n            return expOptimize(e.e1, flags);\n        }\n\n        bool binOptimize(BinExp e, int flags)\n        {\n            expOptimize(e.e1, flags);\n            expOptimize(e.e2, flags);\n            return ret.op == TOK.error;\n        }\n\n        override void visit(Expression e)\n        {\n            //printf(\"Expression::optimize(result = x%x) %s\\n\", result, e.toChars());\n        }\n\n        override void visit(VarExp e)\n        {\n            if (keepLvalue)\n            {\n                VarDeclaration v = e.var.isVarDeclaration();\n                if (v && !(v.storage_class & STC.manifest))\n                    return;\n            }\n            ret = fromConstInitializer(result, e);\n        }\n\n        override void visit(TupleExp e)\n        {\n            expOptimize(e.e0, WANTvalue);\n            for (size_t i = 0; i < e.exps.dim; i++)\n            {\n                expOptimize((*e.exps)[i], WANTvalue);\n            }\n        }\n\n        override void visit(ArrayLiteralExp e)\n        {\n            if (e.elements)\n            {\n                expOptimize(e.basis, result & WANTexpand);\n                for (size_t i = 0; i < e.elements.dim; i++)\n                {\n                    expOptimize((*e.elements)[i], result & WANTexpand);\n                }\n            }\n        }\n\n        override void visit(AssocArrayLiteralExp e)\n        {\n            assert(e.keys.dim == e.values.dim);\n            for (size_t i = 0; i < e.keys.dim; i++)\n            {\n                expOptimize((*e.keys)[i], result & WANTexpand);\n                expOptimize((*e.values)[i], result & WANTexpand);\n            }\n        }\n\n        override void visit(StructLiteralExp e)\n        {\n            if (e.stageflags & stageOptimize)\n                return;\n            int old = e.stageflags;\n            e.stageflags |= stageOptimize;\n            if (e.elements)\n            {\n                for (size_t i = 0; i < e.elements.dim; i++)\n                {\n                    expOptimize((*e.elements)[i], result & WANTexpand);\n                }\n            }\n            e.stageflags = old;\n        }\n\n        override void visit(UnaExp e)\n        {\n            //printf(\"UnaExp::optimize() %s\\n\", e.toChars());\n            if (unaOptimize(e, result))\n                return;\n        }\n\n        override void visit(NegExp e)\n        {\n            if (unaOptimize(e, result))\n                return;\n            if (e.e1.isConst() == 1)\n            {\n                ret = Neg(e.type, e.e1).copy();\n            }\n        }\n\n        override void visit(ComExp e)\n        {\n            if (unaOptimize(e, result))\n                return;\n            if (e.e1.isConst() == 1)\n            {\n                ret = Com(e.type, e.e1).copy();\n            }\n        }\n\n        override void visit(NotExp e)\n        {\n            if (unaOptimize(e, result))\n                return;\n            if (e.e1.isConst() == 1)\n            {\n                ret = Not(e.type, e.e1).copy();\n            }\n        }\n\n        override void visit(SymOffExp e)\n        {\n            assert(e.var);\n        }\n\n        override void visit(AddrExp e)\n        {\n            //printf(\"AddrExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            /* Rewrite &(a,b) as (a,&b)\n             */\n            if (e.e1.op == TOK.comma)\n            {\n                CommaExp ce = cast(CommaExp)e.e1;\n                auto ae = new AddrExp(e.loc, ce.e2, e.type);\n                ret = new CommaExp(ce.loc, ce.e1, ae);\n                ret.type = e.type;\n                return;\n            }\n            // Keep lvalue-ness\n            if (expOptimize(e.e1, result, true))\n                return;\n            // Convert &*ex to ex\n            if (e.e1.op == TOK.star)\n            {\n                Expression ex = (cast(PtrExp)e.e1).e1;\n                if (e.type.equals(ex.type))\n                    ret = ex;\n                else if (e.type.toBasetype().equivalent(ex.type.toBasetype()))\n                {\n                    ret = ex.copy();\n                    ret.type = e.type;\n                }\n                return;\n            }\n            if (e.e1.op == TOK.variable)\n            {\n                VarExp ve = cast(VarExp)e.e1;\n                if (!ve.var.isOut() && !ve.var.isRef() && !ve.var.isImportedSymbol())\n                {\n                    ret = new SymOffExp(e.loc, ve.var, 0, ve.hasOverloads);\n                    ret.type = e.type;\n                    return;\n                }\n            }\n            if (e.e1.op == TOK.index)\n            {\n                // Convert &array[n] to &array+n\n                IndexExp ae = cast(IndexExp)e.e1;\n                if (ae.e2.op == TOK.int64 && ae.e1.op == TOK.variable)\n                {\n                    sinteger_t index = ae.e2.toInteger();\n                    VarExp ve = cast(VarExp)ae.e1;\n                    if (ve.type.ty == Tsarray && !ve.var.isImportedSymbol())\n                    {\n                        TypeSArray ts = cast(TypeSArray)ve.type;\n                        sinteger_t dim = ts.dim.toInteger();\n                        if (index < 0 || index >= dim)\n                        {\n                            e.error(\"array index %lld is out of bounds `[0..%lld]`\", index, dim);\n                            return error();\n                        }\n\n                        import core.checkedint : mulu;\n                        bool overflow;\n                        const offset = mulu(index, ts.nextOf().size(e.loc), overflow);\n                        if (overflow)\n                        {\n                            e.error(\"array offset overflow\");\n                            return error();\n                        }\n\n                        ret = new SymOffExp(e.loc, ve.var, offset);\n                        ret.type = e.type;\n                        return;\n                    }\n                }\n            }\n        }\n\n        override void visit(PtrExp e)\n        {\n            //printf(\"PtrExp::optimize(result = x%x) %s\\n\", result, e.toChars());\n            if (expOptimize(e.e1, result))\n                return;\n            // Convert *&ex to ex\n            // But only if there is no type punning involved\n            if (e.e1.op == TOK.address)\n            {\n                Expression ex = (cast(AddrExp)e.e1).e1;\n                if (e.type.equals(ex.type))\n                    ret = ex;\n                else if (e.type.toBasetype().equivalent(ex.type.toBasetype()))\n                {\n                    ret = ex.copy();\n                    ret.type = e.type;\n                }\n            }\n            if (keepLvalue)\n                return;\n            // Constant fold *(&structliteral + offset)\n            if (e.e1.op == TOK.add)\n            {\n                Expression ex = Ptr(e.type, e.e1).copy();\n                if (!CTFEExp.isCantExp(ex))\n                {\n                    ret = ex;\n                    return;\n                }\n            }\n            if (e.e1.op == TOK.symbolOffset)\n            {\n                SymOffExp se = cast(SymOffExp)e.e1;\n                VarDeclaration v = se.var.isVarDeclaration();\n                Expression ex = expandVar(result, v);\n                if (ex && ex.op == TOK.structLiteral)\n                {\n                    StructLiteralExp sle = cast(StructLiteralExp)ex;\n                    ex = sle.getField(e.type, cast(uint)se.offset);\n                    if (ex && !CTFEExp.isCantExp(ex))\n                    {\n                        ret = ex;\n                        return;\n                    }\n                }\n            }\n        }\n\n        override void visit(DotVarExp e)\n        {\n            //printf(\"DotVarExp::optimize(result = x%x) %s\\n\", result, e.toChars());\n            if (expOptimize(e.e1, result))\n                return;\n            if (keepLvalue)\n                return;\n            Expression ex = e.e1;\n            if (ex.op == TOK.variable)\n            {\n                VarExp ve = cast(VarExp)ex;\n                VarDeclaration v = ve.var.isVarDeclaration();\n                ex = expandVar(result, v);\n            }\n            if (ex && ex.op == TOK.structLiteral)\n            {\n                StructLiteralExp sle = cast(StructLiteralExp)ex;\n                VarDeclaration vf = e.var.isVarDeclaration();\n                if (vf && !vf.overlapped)\n                {\n                    /* https://issues.dlang.org/show_bug.cgi?id=13021\n                     * Prevent optimization if vf has overlapped fields.\n                     */\n                    ex = sle.getField(e.type, vf.offset);\n                    if (ex && !CTFEExp.isCantExp(ex))\n                    {\n                        ret = ex;\n                        return;\n                    }\n                }\n            }\n        }\n\n        override void visit(NewExp e)\n        {\n            expOptimize(e.thisexp, WANTvalue);\n            // Optimize parameters\n            if (e.newargs)\n            {\n                for (size_t i = 0; i < e.newargs.dim; i++)\n                {\n                    expOptimize((*e.newargs)[i], WANTvalue);\n                }\n            }\n            if (e.arguments)\n            {\n                for (size_t i = 0; i < e.arguments.dim; i++)\n                {\n                    expOptimize((*e.arguments)[i], WANTvalue);\n                }\n            }\n        }\n\n        override void visit(CallExp e)\n        {\n            //printf(\"CallExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            // Optimize parameters with keeping lvalue-ness\n            if (expOptimize(e.e1, result))\n                return;\n            if (e.arguments)\n            {\n                Type t1 = e.e1.type.toBasetype();\n                if (t1.ty == Tdelegate)\n                    t1 = t1.nextOf();\n                assert(t1.ty == Tfunction);\n                TypeFunction tf = cast(TypeFunction)t1;\n                for (size_t i = 0; i < e.arguments.dim; i++)\n                {\n                    Parameter p = Parameter.getNth(tf.parameters, i);\n                    bool keep = p && (p.storageClass & (STC.ref_ | STC.out_)) != 0;\n                    expOptimize((*e.arguments)[i], WANTvalue, keep);\n                }\n            }\n        }\n\n        override void visit(CastExp e)\n        {\n            //printf(\"CastExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            //printf(\"from %s to %s\\n\", e.type.toChars(), e.to.toChars());\n            //printf(\"from %s\\n\", e.type.toChars());\n            //printf(\"e1.type %s\\n\", e.e1.type.toChars());\n            //printf(\"type = %p\\n\", e.type);\n            assert(e.type);\n            TOK op1 = e.e1.op;\n            Expression e1old = e.e1;\n            if (expOptimize(e.e1, result))\n                return;\n            e.e1 = fromConstInitializer(result, e.e1);\n            if (e.e1 == e1old && e.e1.op == TOK.arrayLiteral && e.type.toBasetype().ty == Tpointer && e.e1.type.toBasetype().ty != Tsarray)\n            {\n                // Casting this will result in the same expression, and\n                // infinite loop because of Expression::implicitCastTo()\n                return; // no change\n            }\n            if ((e.e1.op == TOK.string_ || e.e1.op == TOK.arrayLiteral) &&\n                (e.type.ty == Tpointer || e.type.ty == Tarray))\n            {\n                const esz  = e.type.nextOf().size(e.loc);\n                const e1sz = e.e1.type.toBasetype().nextOf().size(e.e1.loc);\n                if (esz == SIZE_INVALID || e1sz == SIZE_INVALID)\n                    return error();\n\n                if (e1sz == esz)\n                {\n                    // https://issues.dlang.org/show_bug.cgi?id=12937\n                    // If target type is void array, trying to paint\n                    // e.e1 with that type will cause infinite recursive optimization.\n                    if (e.type.nextOf().ty == Tvoid)\n                        return;\n                    ret = e.e1.castTo(null, e.type);\n                    //printf(\" returning1 %s\\n\", ret.toChars());\n                    return;\n                }\n            }\n\n            if (e.e1.op == TOK.structLiteral && e.e1.type.implicitConvTo(e.type) >= MATCH.constant)\n            {\n                //printf(\" returning2 %s\\n\", e.e1.toChars());\n            L1:\n                // Returning e1 with changing its type\n                ret = (e1old == e.e1 ? e.e1.copy() : e.e1);\n                ret.type = e.type;\n                return;\n            }\n            /* The first test here is to prevent infinite loops\n             */\n            if (op1 != TOK.arrayLiteral && e.e1.op == TOK.arrayLiteral)\n            {\n                ret = e.e1.castTo(null, e.to);\n                return;\n            }\n            if (e.e1.op == TOK.null_ && (e.type.ty == Tpointer || e.type.ty == Tclass || e.type.ty == Tarray))\n            {\n                //printf(\" returning3 %s\\n\", e.e1.toChars());\n                goto L1;\n            }\n            if (e.type.ty == Tclass && e.e1.type.ty == Tclass)\n            {\n                import dmd.aggregate : Sizeok;\n\n                // See if we can remove an unnecessary cast\n                ClassDeclaration cdfrom = e.e1.type.isClassHandle();\n                ClassDeclaration cdto = e.type.isClassHandle();\n                if (cdto == ClassDeclaration.object && !cdfrom.isInterfaceDeclaration())\n                    goto L1;    // can always convert a class to Object\n                // Need to determine correct offset before optimizing away the cast.\n                // https://issues.dlang.org/show_bug.cgi?id=16980\n                cdfrom.size(e.loc);\n                assert(cdfrom.sizeok == Sizeok.done);\n                assert(cdto.sizeok == Sizeok.done || !cdto.isBaseOf(cdfrom, null));\n                int offset;\n                if (cdto.isBaseOf(cdfrom, &offset) && offset == 0)\n                {\n                    //printf(\" returning4 %s\\n\", e.e1.toChars());\n                    goto L1;\n                }\n            }\n            // We can convert 'head const' to mutable\n            if (e.to.mutableOf().constOf().equals(e.e1.type.mutableOf().constOf()))\n            {\n                //printf(\" returning5 %s\\n\", e.e1.toChars());\n                goto L1;\n            }\n            if (e.e1.isConst())\n            {\n                if (e.e1.op == TOK.symbolOffset)\n                {\n                    if (e.type.toBasetype().ty != Tsarray)\n                    {\n                        const esz = e.type.size(e.loc);\n                        const e1sz = e.e1.type.size(e.e1.loc);\n                        if (esz == SIZE_INVALID ||\n                            e1sz == SIZE_INVALID)\n                            return error();\n\n                        if (esz == e1sz)\n                            goto L1;\n                    }\n                    return;\n                }\n                if (e.to.toBasetype().ty != Tvoid)\n                {\n                    if (e.e1.type.equals(e.type) && e.type.equals(e.to))\n                        ret = e.e1;\n                    else\n                        ret = Cast(e.loc, e.type, e.to, e.e1).copy();\n                }\n            }\n            //printf(\" returning6 %s\\n\", ret.toChars());\n        }\n\n        override void visit(BinExp e)\n        {\n            //printf(\"BinExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            // don't replace const variable with its initializer in e1\n            bool e2only = (e.op == TOK.construct || e.op == TOK.blit);\n            if (e2only ? expOptimize(e.e2, result) : binOptimize(e, result))\n                return;\n            if (e.op == TOK.leftShiftAssign || e.op == TOK.rightShiftAssign || e.op == TOK.unsignedRightShiftAssign)\n            {\n                if (e.e2.isConst() == 1)\n                {\n                    sinteger_t i2 = e.e2.toInteger();\n                    d_uns64 sz = e.e1.type.size(e.e1.loc);\n                    assert(sz != SIZE_INVALID);\n                    sz *= 8;\n                    if (i2 < 0 || i2 >= sz)\n                    {\n                        e.error(\"shift assign by %lld is outside the range `0..%llu`\", i2, cast(ulong)sz - 1);\n                        return error();\n                    }\n                }\n            }\n        }\n\n        override void visit(AddExp e)\n        {\n            //printf(\"AddExp::optimize(%s)\\n\", e.toChars());\n            if (binOptimize(e, result))\n                return;\n            if (e.e1.isConst() && e.e2.isConst())\n            {\n                if (e.e1.op == TOK.symbolOffset && e.e2.op == TOK.symbolOffset)\n                    return;\n                ret = Add(e.loc, e.type, e.e1, e.e2).copy();\n            }\n        }\n\n        override void visit(MinExp e)\n        {\n            if (binOptimize(e, result))\n                return;\n            if (e.e1.isConst() && e.e2.isConst())\n            {\n                if (e.e2.op == TOK.symbolOffset)\n                    return;\n                ret = Min(e.loc, e.type, e.e1, e.e2).copy();\n            }\n        }\n\n        override void visit(MulExp e)\n        {\n            //printf(\"MulExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            if (binOptimize(e, result))\n                return;\n            if (e.e1.isConst() == 1 && e.e2.isConst() == 1)\n            {\n                ret = Mul(e.loc, e.type, e.e1, e.e2).copy();\n            }\n        }\n\n        override void visit(DivExp e)\n        {\n            //printf(\"DivExp::optimize(%s)\\n\", e.toChars());\n            if (binOptimize(e, result))\n                return;\n            if (e.e1.isConst() == 1 && e.e2.isConst() == 1)\n            {\n                ret = Div(e.loc, e.type, e.e1, e.e2).copy();\n            }\n        }\n\n        override void visit(ModExp e)\n        {\n            if (binOptimize(e, result))\n                return;\n            if (e.e1.isConst() == 1 && e.e2.isConst() == 1)\n            {\n                ret = Mod(e.loc, e.type, e.e1, e.e2).copy();\n            }\n        }\n\n        extern (D) void shift_optimize(BinExp e, UnionExp function(const ref Loc, Type, Expression, Expression) shift)\n        {\n            if (binOptimize(e, result))\n                return;\n            if (e.e2.isConst() == 1)\n            {\n                sinteger_t i2 = e.e2.toInteger();\n                d_uns64 sz = e.e1.type.size(e.e1.loc);\n                assert(sz != SIZE_INVALID);\n                sz *= 8;\n                if (i2 < 0 || i2 >= sz)\n                {\n                    e.error(\"shift by %lld is outside the range `0..%llu`\", i2, cast(ulong)sz - 1);\n                    return error();\n                }\n                if (e.e1.isConst() == 1)\n                    ret = (*shift)(e.loc, e.type, e.e1, e.e2).copy();\n            }\n        }\n\n        override void visit(ShlExp e)\n        {\n            //printf(\"ShlExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            shift_optimize(e, &Shl);\n        }\n\n        override void visit(ShrExp e)\n        {\n            //printf(\"ShrExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            shift_optimize(e, &Shr);\n        }\n\n        override void visit(UshrExp e)\n        {\n            //printf(\"UshrExp::optimize(result = %d) %s\\n\", result, toChars());\n            shift_optimize(e, &Ushr);\n        }\n\n        override void visit(AndExp e)\n        {\n            if (binOptimize(e, result))\n                return;\n            if (e.e1.isConst() == 1 && e.e2.isConst() == 1)\n                ret = And(e.loc, e.type, e.e1, e.e2).copy();\n        }\n\n        override void visit(OrExp e)\n        {\n            if (binOptimize(e, result))\n                return;\n            if (e.e1.isConst() == 1 && e.e2.isConst() == 1)\n                ret = Or(e.loc, e.type, e.e1, e.e2).copy();\n        }\n\n        override void visit(XorExp e)\n        {\n            if (binOptimize(e, result))\n                return;\n            if (e.e1.isConst() == 1 && e.e2.isConst() == 1)\n                ret = Xor(e.loc, e.type, e.e1, e.e2).copy();\n        }\n\n        override void visit(PowExp e)\n        {\n            if (binOptimize(e, result))\n                return;\n            // Replace 1 ^^ x or 1.0^^x by (x, 1)\n            if ((e.e1.op == TOK.int64 && e.e1.toInteger() == 1) || (e.e1.op == TOK.float64 && e.e1.toReal() == CTFloat.one))\n            {\n                ret = new CommaExp(e.loc, e.e2, e.e1);\n                ret.type = e.type;\n                return;\n            }\n            // Replace -1 ^^ x by (x&1) ? -1 : 1, where x is integral\n            if (e.e2.type.isintegral() && e.e1.op == TOK.int64 && cast(sinteger_t)e.e1.toInteger() == -1)\n            {\n                ret = new AndExp(e.loc, e.e2, new IntegerExp(e.loc, 1, e.e2.type));\n                ret.type = e.e2.type;\n                ret = new CondExp(e.loc, ret, new IntegerExp(e.loc, -1, e.type), new IntegerExp(e.loc, 1, e.type));\n                ret.type = e.type;\n                return;\n            }\n            // Replace x ^^ 0 or x^^0.0 by (x, 1)\n            if ((e.e2.op == TOK.int64 && e.e2.toInteger() == 0) || (e.e2.op == TOK.float64 && e.e2.toReal() == CTFloat.zero))\n            {\n                if (e.e1.type.isintegral())\n                    ret = new IntegerExp(e.loc, 1, e.e1.type);\n                else\n                    ret = new RealExp(e.loc, CTFloat.one, e.e1.type);\n                ret = new CommaExp(e.loc, e.e1, ret);\n                ret.type = e.type;\n                return;\n            }\n            // Replace x ^^ 1 or x^^1.0 by (x)\n            if ((e.e2.op == TOK.int64 && e.e2.toInteger() == 1) || (e.e2.op == TOK.float64 && e.e2.toReal() == CTFloat.one))\n            {\n                ret = e.e1;\n                return;\n            }\n            // Replace x ^^ -1.0 by (1.0 / x)\n            if (e.e2.op == TOK.float64 && e.e2.toReal() == CTFloat.minusone)\n            {\n                ret = new DivExp(e.loc, new RealExp(e.loc, CTFloat.one, e.e2.type), e.e1);\n                ret.type = e.type;\n                return;\n            }\n            // All other negative integral powers are illegal\n            if (e.e1.type.isintegral() && (e.e2.op == TOK.int64) && cast(sinteger_t)e.e2.toInteger() < 0)\n            {\n                e.error(\"cannot raise `%s` to a negative integer power. Did you mean `(cast(real)%s)^^%s` ?\", e.e1.type.toBasetype().toChars(), e.e1.toChars(), e.e2.toChars());\n                return error();\n            }\n            // If e2 *could* have been an integer, make it one.\n            if (e.e2.op == TOK.float64)\n            {\n                if (e.e2.toReal() == real_t(cast(sinteger_t)e.e2.toReal()))\n                    e.e2 = new IntegerExp(e.loc, e.e2.toInteger(), Type.tint64);\n            }\n            if (e.e1.isConst() == 1 && e.e2.isConst() == 1)\n            {\n                Expression ex = Pow(e.loc, e.type, e.e1, e.e2).copy();\n                if (!CTFEExp.isCantExp(ex))\n                {\n                    ret = ex;\n                    return;\n                }\n            }\n            // (2 ^^ n) ^^ p -> 1 << n * p\n            if (e.e1.op == TOK.int64 && e.e1.toInteger() > 0 && !((e.e1.toInteger() - 1) & e.e1.toInteger()) && e.e2.type.isintegral() && e.e2.type.isunsigned())\n            {\n                dinteger_t i = e.e1.toInteger();\n                dinteger_t mul = 1;\n                while ((i >>= 1) > 1)\n                    mul++;\n                Expression shift = new MulExp(e.loc, e.e2, new IntegerExp(e.loc, mul, e.e2.type));\n                shift.type = e.e2.type;\n                shift = shift.castTo(null, Type.tshiftcnt);\n                ret = new ShlExp(e.loc, new IntegerExp(e.loc, 1, e.e1.type), shift);\n                ret.type = e.type;\n                return;\n            }\n        }\n\n        override void visit(CommaExp e)\n        {\n            //printf(\"CommaExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            // Comma needs special treatment, because it may\n            // contain compiler-generated declarations. We can interpret them, but\n            // otherwise we must NOT attempt to constant-fold them.\n            // In particular, if the comma returns a temporary variable, it needs\n            // to be an lvalue (this is particularly important for struct constructors)\n            expOptimize(e.e1, WANTvalue);\n            expOptimize(e.e2, result, keepLvalue);\n            if (ret.op == TOK.error)\n                return;\n            if (!e.e1 || e.e1.op == TOK.int64 || e.e1.op == TOK.float64 || !hasSideEffect(e.e1))\n            {\n                ret = e.e2;\n                if (ret)\n                    ret.type = e.type;\n            }\n            //printf(\"-CommaExp::optimize(result = %d) %s\\n\", result, e.e.toChars());\n        }\n\n        override void visit(ArrayLengthExp e)\n        {\n            //printf(\"ArrayLengthExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            if (unaOptimize(e, WANTexpand))\n                return;\n            // CTFE interpret static immutable arrays (to get better diagnostics)\n            if (e.e1.op == TOK.variable)\n            {\n                VarDeclaration v = (cast(VarExp)e.e1).var.isVarDeclaration();\n                if (v && (v.storage_class & STC.static_) && (v.storage_class & STC.immutable_) && v._init)\n                {\n                    if (Expression ci = v.getConstInitializer())\n                        e.e1 = ci;\n                }\n            }\n            if (e.e1.op == TOK.string_ || e.e1.op == TOK.arrayLiteral || e.e1.op == TOK.assocArrayLiteral || e.e1.type.toBasetype().ty == Tsarray)\n            {\n                ret = ArrayLength(e.type, e.e1).copy();\n            }\n        }\n\n        override void visit(EqualExp e)\n        {\n            //printf(\"EqualExp::optimize(result = %x) %s\\n\", result, e.toChars());\n            if (binOptimize(e, WANTvalue))\n                return;\n            Expression e1 = fromConstInitializer(result, e.e1);\n            Expression e2 = fromConstInitializer(result, e.e2);\n            if (e1.op == TOK.error)\n            {\n                ret = e1;\n                return;\n            }\n            if (e2.op == TOK.error)\n            {\n                ret = e2;\n                return;\n            }\n            ret = Equal(e.op, e.loc, e.type, e1, e2).copy();\n            if (CTFEExp.isCantExp(ret))\n                ret = e;\n        }\n\n        override void visit(IdentityExp e)\n        {\n            //printf(\"IdentityExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            if (binOptimize(e, WANTvalue))\n                return;\n            if ((e.e1.isConst() && e.e2.isConst()) || (e.e1.op == TOK.null_ && e.e2.op == TOK.null_))\n            {\n                ret = Identity(e.op, e.loc, e.type, e.e1, e.e2).copy();\n                if (CTFEExp.isCantExp(ret))\n                    ret = e;\n            }\n        }\n\n        override void visit(IndexExp e)\n        {\n            //printf(\"IndexExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            if (expOptimize(e.e1, result & WANTexpand))\n                return;\n            Expression ex = fromConstInitializer(result, e.e1);\n            // We might know $ now\n            setLengthVarIfKnown(e.lengthVar, ex);\n            if (expOptimize(e.e2, WANTvalue))\n                return;\n            if (keepLvalue)\n                return;\n            ret = Index(e.type, ex, e.e2).copy();\n            if (CTFEExp.isCantExp(ret))\n                ret = e;\n        }\n\n        override void visit(SliceExp e)\n        {\n            //printf(\"SliceExp::optimize(result = %d) %s\\n\", result, e.toChars());\n            if (expOptimize(e.e1, result & WANTexpand))\n                return;\n            if (!e.lwr)\n            {\n                if (e.e1.op == TOK.string_)\n                {\n                    // Convert slice of string literal into dynamic array\n                    Type t = e.e1.type.toBasetype();\n                    if (Type tn = t.nextOf())\n                        ret = e.e1.castTo(null, tn.arrayOf());\n                }\n            }\n            else\n            {\n                e.e1 = fromConstInitializer(result, e.e1);\n                // We might know $ now\n                setLengthVarIfKnown(e.lengthVar, e.e1);\n                expOptimize(e.lwr, WANTvalue);\n                expOptimize(e.upr, WANTvalue);\n                if (ret.op == TOK.error)\n                    return;\n                ret = Slice(e.type, e.e1, e.lwr, e.upr).copy();\n                if (CTFEExp.isCantExp(ret))\n                    ret = e;\n            }\n            // https://issues.dlang.org/show_bug.cgi?id=14649\n            // Leave the slice form so it might be\n            // a part of array operation.\n            // Assume that the backend codegen will handle the form `e[]`\n            // as an equal to `e` itself.\n            if (ret.op == TOK.string_)\n            {\n                e.e1 = ret;\n                e.lwr = null;\n                e.upr = null;\n                ret = e;\n            }\n            //printf(\"-SliceExp::optimize() %s\\n\", ret.toChars());\n        }\n\n        override void visit(LogicalExp e)\n        {\n            //printf(\"LogicalExp::optimize(%d) %s\\n\", result, e.toChars());\n            if (expOptimize(e.e1, WANTvalue))\n                return;\n            const oror = e.op == TOK.orOr;\n            if (e.e1.isBool(oror))\n            {\n                // Replace with (e1, oror)\n                ret = new IntegerExp(e.loc, oror, Type.tbool);\n                ret = Expression.combine(e.e1, ret);\n                if (e.type.toBasetype().ty == Tvoid)\n                {\n                    ret = new CastExp(e.loc, ret, Type.tvoid);\n                    ret.type = e.type;\n                }\n                ret = Expression_optimize(ret, result, false);\n                return;\n            }\n            if (expOptimize(e.e2, WANTvalue))\n                return;\n            if (e.e1.isConst())\n            {\n                if (e.e2.isConst())\n                {\n                    bool n1 = e.e1.isBool(true);\n                    bool n2 = e.e2.isBool(true);\n                    ret = new IntegerExp(e.loc, oror ? (n1 || n2) : (n1 && n2), e.type);\n                }\n                else if (e.e1.isBool(!oror))\n                {\n                    if (e.type.toBasetype().ty == Tvoid)\n                        ret = e.e2;\n                    else\n                    {\n                        ret = new CastExp(e.loc, e.e2, e.type);\n                        ret.type = e.type;\n                    }\n                }\n            }\n        }\n\n        override void visit(CmpExp e)\n        {\n            //printf(\"CmpExp::optimize() %s\\n\", e.toChars());\n            if (binOptimize(e, WANTvalue))\n                return;\n            Expression e1 = fromConstInitializer(result, e.e1);\n            Expression e2 = fromConstInitializer(result, e.e2);\n            ret = Cmp(e.op, e.loc, e.type, e1, e2).copy();\n            if (CTFEExp.isCantExp(ret))\n                ret = e;\n        }\n\n        override void visit(CatExp e)\n        {\n            //printf(\"CatExp::optimize(%d) %s\\n\", result, e.toChars());\n            if (binOptimize(e, result))\n                return;\n            if (e.e1.op == TOK.concatenate)\n            {\n                // https://issues.dlang.org/show_bug.cgi?id=12798\n                // optimize ((expr ~ str1) ~ str2)\n                CatExp ce1 = cast(CatExp)e.e1;\n                scope CatExp cex = new CatExp(e.loc, ce1.e2, e.e2);\n                cex.type = e.type;\n                Expression ex = Expression_optimize(cex, result, false);\n                if (ex != cex)\n                {\n                    e.e1 = ce1.e1;\n                    e.e2 = ex;\n                }\n            }\n            // optimize \"str\"[] -> \"str\"\n            if (e.e1.op == TOK.slice)\n            {\n                SliceExp se1 = cast(SliceExp)e.e1;\n                if (se1.e1.op == TOK.string_ && !se1.lwr)\n                    e.e1 = se1.e1;\n            }\n            if (e.e2.op == TOK.slice)\n            {\n                SliceExp se2 = cast(SliceExp)e.e2;\n                if (se2.e1.op == TOK.string_ && !se2.lwr)\n                    e.e2 = se2.e1;\n            }\n            ret = Cat(e.type, e.e1, e.e2).copy();\n            if (CTFEExp.isCantExp(ret))\n                ret = e;\n        }\n\n        override void visit(CondExp e)\n        {\n            if (expOptimize(e.econd, WANTvalue))\n                return;\n            if (e.econd.isBool(true))\n                ret = Expression_optimize(e.e1, result, keepLvalue);\n            else if (e.econd.isBool(false))\n                ret = Expression_optimize(e.e2, result, keepLvalue);\n            else\n            {\n                expOptimize(e.e1, result, keepLvalue);\n                expOptimize(e.e2, result, keepLvalue);\n            }\n        }\n    }\n\n    scope OptimizeVisitor v = new OptimizeVisitor(e, result, keepLvalue);\n\n    // Optimize the expression until it can no longer be simplified.\n    while (1)\n    {\n        auto ex = v.ret;\n        ex.accept(v);\n        if (ex == v.ret)\n            break;\n    }\n    return v.ret;\n}\n"
  },
  {
    "path": "gcc/d/dmd/parse.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/parse.d, _parse.d)\n * Documentation:  https://dlang.org/phobos/dmd_parse.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/parse.d\n */\n\nmodule dmd.parse;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.lexer;\nimport dmd.errors;\nimport dmd.root.filename;\nimport dmd.root.outbuffer;\nimport dmd.root.rmem;\nimport dmd.root.rootobject;\nimport dmd.tokens;\n\n// How multiple declarations are parsed.\n// If 1, treat as C.\n// If 0, treat:\n//      int *p, i;\n// as:\n//      int* p;\n//      int* i;\nenum CDECLSYNTAX = 0;\n\n// Support C cast syntax:\n//      (type)(expression)\nenum CCASTSYNTAX = 1;\n\n// Support postfix C array declarations, such as\n//      int a[3][4];\nenum CARRAYDECL = 1;\n\n/**********************************\n * Set operator precedence for each operator.\n */\n__gshared PREC[TOK.max_] precedence =\n[\n    TOK.type : PREC.expr,\n    TOK.error : PREC.expr,\n\n    TOK.typeof_ : PREC.primary,\n    TOK.mixin_ : PREC.primary,\n\n    TOK.import_ : PREC.primary,\n    TOK.dotVariable : PREC.primary,\n    TOK.scope_ : PREC.primary,\n    TOK.identifier : PREC.primary,\n    TOK.this_ : PREC.primary,\n    TOK.super_ : PREC.primary,\n    TOK.int64 : PREC.primary,\n    TOK.float64 : PREC.primary,\n    TOK.complex80 : PREC.primary,\n    TOK.null_ : PREC.primary,\n    TOK.string_ : PREC.primary,\n    TOK.arrayLiteral : PREC.primary,\n    TOK.assocArrayLiteral : PREC.primary,\n    TOK.classReference : PREC.primary,\n    TOK.file : PREC.primary,\n    TOK.fileFullPath : PREC.primary,\n    TOK.line : PREC.primary,\n    TOK.moduleString : PREC.primary,\n    TOK.functionString : PREC.primary,\n    TOK.prettyFunction : PREC.primary,\n    TOK.typeid_ : PREC.primary,\n    TOK.is_ : PREC.primary,\n    TOK.assert_ : PREC.primary,\n    TOK.halt : PREC.primary,\n    TOK.template_ : PREC.primary,\n    TOK.dSymbol : PREC.primary,\n    TOK.function_ : PREC.primary,\n    TOK.variable : PREC.primary,\n    TOK.symbolOffset : PREC.primary,\n    TOK.structLiteral : PREC.primary,\n    TOK.arrayLength : PREC.primary,\n    TOK.delegatePointer : PREC.primary,\n    TOK.delegateFunctionPointer : PREC.primary,\n    TOK.remove : PREC.primary,\n    TOK.tuple : PREC.primary,\n    TOK.traits : PREC.primary,\n    TOK.default_ : PREC.primary,\n    TOK.overloadSet : PREC.primary,\n    TOK.void_ : PREC.primary,\n\n    // post\n    TOK.dotTemplateInstance : PREC.primary,\n    TOK.dotIdentifier : PREC.primary,\n    TOK.dotTemplateDeclaration : PREC.primary,\n    TOK.dot : PREC.primary,\n    TOK.dotType : PREC.primary,\n    TOK.plusPlus : PREC.primary,\n    TOK.minusMinus : PREC.primary,\n    TOK.prePlusPlus : PREC.primary,\n    TOK.preMinusMinus : PREC.primary,\n    TOK.call : PREC.primary,\n    TOK.slice : PREC.primary,\n    TOK.array : PREC.primary,\n    TOK.index : PREC.primary,\n\n    TOK.delegate_ : PREC.unary,\n    TOK.address : PREC.unary,\n    TOK.star : PREC.unary,\n    TOK.negate : PREC.unary,\n    TOK.uadd : PREC.unary,\n    TOK.not : PREC.unary,\n    TOK.tilde : PREC.unary,\n    TOK.delete_ : PREC.unary,\n    TOK.new_ : PREC.unary,\n    TOK.newAnonymousClass : PREC.unary,\n    TOK.cast_ : PREC.unary,\n\n    TOK.vector : PREC.unary,\n    TOK.pow : PREC.pow,\n\n    TOK.mul : PREC.mul,\n    TOK.div : PREC.mul,\n    TOK.mod : PREC.mul,\n\n    TOK.add : PREC.add,\n    TOK.min : PREC.add,\n    TOK.concatenate : PREC.add,\n\n    TOK.leftShift : PREC.shift,\n    TOK.rightShift : PREC.shift,\n    TOK.unsignedRightShift : PREC.shift,\n\n    TOK.lessThan : PREC.rel,\n    TOK.lessOrEqual : PREC.rel,\n    TOK.greaterThan : PREC.rel,\n    TOK.greaterOrEqual : PREC.rel,\n    TOK.in_ : PREC.rel,\n\n    /* Note that we changed precedence, so that < and != have the same\n     * precedence. This change is in the parser, too.\n     */\n    TOK.equal : PREC.rel,\n    TOK.notEqual : PREC.rel,\n    TOK.identity : PREC.rel,\n    TOK.notIdentity : PREC.rel,\n\n    TOK.and : PREC.and,\n    TOK.xor : PREC.xor,\n    TOK.or : PREC.or,\n\n    TOK.andAnd : PREC.andand,\n    TOK.orOr : PREC.oror,\n\n    TOK.question : PREC.cond,\n\n    TOK.assign : PREC.assign,\n    TOK.construct : PREC.assign,\n    TOK.blit : PREC.assign,\n    TOK.addAssign : PREC.assign,\n    TOK.minAssign : PREC.assign,\n    TOK.concatenateAssign : PREC.assign,\n    TOK.concatenateElemAssign : PREC.assign,\n    TOK.concatenateDcharAssign : PREC.assign,\n    TOK.mulAssign : PREC.assign,\n    TOK.divAssign : PREC.assign,\n    TOK.modAssign : PREC.assign,\n    TOK.powAssign : PREC.assign,\n    TOK.leftShiftAssign : PREC.assign,\n    TOK.rightShiftAssign : PREC.assign,\n    TOK.unsignedRightShiftAssign : PREC.assign,\n    TOK.andAssign : PREC.assign,\n    TOK.orAssign : PREC.assign,\n    TOK.xorAssign : PREC.assign,\n\n    TOK.comma : PREC.expr,\n    TOK.declaration : PREC.expr,\n\n    TOK.interval : PREC.assign,\n];\n\nenum ParseStatementFlags : int\n{\n    semi          = 1,        // empty ';' statements are allowed, but deprecated\n    scope_        = 2,        // start a new scope\n    curly         = 4,        // { } statement is required\n    curlyScope    = 8,        // { } starts a new scope\n    semiOk        = 0x10,     // empty ';' are really ok\n}\n\nstruct PrefixAttributes(AST)\n{\n    StorageClass storageClass;\n    AST.Expression depmsg;\n    LINK link;\n    AST.Prot protection;\n    bool setAlignment;\n    AST.Expression ealign;\n    AST.Expressions* udas;\n    const(char)* comment;\n}\n\n/*****************************\n * Destructively extract storage class from pAttrs.\n */\nprivate StorageClass getStorageClass(AST)(PrefixAttributes!(AST)* pAttrs)\n{\n    StorageClass stc = AST.STC.undefined_;\n    if (pAttrs)\n    {\n        stc = pAttrs.storageClass;\n        pAttrs.storageClass = AST.STC.undefined_;\n    }\n    return stc;\n}\n\n/***********************************************************\n */\nfinal class Parser(AST) : Lexer\n{\n    AST.Module mod;\n    AST.ModuleDeclaration* md;\n    LINK linkage;\n    CPPMANGLE cppmangle;\n    Loc endloc; // set to location of last right curly\n    int inBrackets; // inside [] of array index or slice\n    Loc lookingForElse; // location of lonely if looking for an else\n\n    /*********************\n     * Use this constructor for string mixins.\n     * Input:\n     *      loc     location in source file of mixin\n     */\n    extern (D) this(const ref Loc loc, AST.Module _module, const(char)[] input, bool doDocComment)\n    {\n        super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false);\n\n        //printf(\"Parser::Parser()\\n\");\n        scanloc = loc;\n\n        if (loc.filename)\n        {\n            /* Create a pseudo-filename for the mixin string, as it may not even exist\n             * in the source file.\n             */\n            char* filename = cast(char*)mem.xmalloc(strlen(loc.filename) + 7 + (loc.linnum).sizeof * 3 + 1);\n            sprintf(filename, \"%s-mixin-%d\", loc.filename, cast(int)loc.linnum);\n            scanloc.filename = filename;\n        }\n\n        mod = _module;\n        linkage = LINK.d;\n        //nextToken();              // start up the scanner\n    }\n\n    extern (D) this(AST.Module _module, const(char)[] input, bool doDocComment)\n    {\n        super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false);\n\n        //printf(\"Parser::Parser()\\n\");\n        mod = _module;\n        linkage = LINK.d;\n        //nextToken();              // start up the scanner\n    }\n\n    AST.Dsymbols* parseModule()\n    {\n        const comment = token.blockComment;\n        bool isdeprecated = false;\n        AST.Expression msg = null;\n        AST.Expressions* udas = null;\n        AST.Dsymbols* decldefs;\n        AST.Dsymbol lastDecl = mod; // for attaching ddoc unittests to module decl\n\n        Token* tk;\n        if (skipAttributes(&token, &tk) && tk.value == TOK.module_)\n        {\n            while (token.value != TOK.module_)\n            {\n                switch (token.value)\n                {\n                case TOK.deprecated_:\n                    {\n                        // deprecated (...) module ...\n                        if (isdeprecated)\n                        {\n                            error(\"there is only one deprecation attribute allowed for module declaration\");\n                        }\n                        else\n                        {\n                            isdeprecated = true;\n                        }\n                        nextToken();\n                        if (token.value == TOK.leftParentheses)\n                        {\n                            check(TOK.leftParentheses);\n                            msg = parseAssignExp();\n                            check(TOK.rightParentheses);\n                        }\n                        break;\n                    }\n                case TOK.at:\n                    {\n                        AST.Expressions* exps = null;\n                        const stc = parseAttribute(&exps);\n                        if (stc == AST.STC.property || stc == AST.STC.nogc\n                          || stc == AST.STC.disable || stc == AST.STC.safe\n                          || stc == AST.STC.trusted || stc == AST.STC.system)\n                        {\n                            error(\"`@%s` attribute for module declaration is not supported\", token.toChars());\n                        }\n                        else\n                        {\n                            udas = AST.UserAttributeDeclaration.concat(udas, exps);\n                        }\n                        if (stc)\n                            nextToken();\n                        break;\n                    }\n                default:\n                    {\n                        error(\"`module` expected instead of `%s`\", token.toChars());\n                        nextToken();\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (udas)\n        {\n            auto a = new AST.Dsymbols();\n            auto udad = new AST.UserAttributeDeclaration(udas, a);\n            mod.userAttribDecl = udad;\n        }\n\n        // ModuleDeclation leads off\n        if (token.value == TOK.module_)\n        {\n            const loc = token.loc;\n\n            nextToken();\n            if (token.value != TOK.identifier)\n            {\n                error(\"identifier expected following `module`\");\n                goto Lerr;\n            }\n            else\n            {\n                AST.Identifiers* a = null;\n                Identifier id = token.ident;\n\n                while (nextToken() == TOK.dot)\n                {\n                    if (!a)\n                        a = new AST.Identifiers();\n                    a.push(id);\n                    nextToken();\n                    if (token.value != TOK.identifier)\n                    {\n                        error(\"identifier expected following `package`\");\n                        goto Lerr;\n                    }\n                    id = token.ident;\n                }\n\n                md = new AST.ModuleDeclaration(loc, a, id, msg, isdeprecated);\n\n                if (token.value != TOK.semicolon)\n                    error(\"`;` expected following module declaration instead of `%s`\", token.toChars());\n                nextToken();\n                addComment(mod, comment);\n            }\n        }\n\n        decldefs = parseDeclDefs(0, &lastDecl);\n        if (token.value != TOK.endOfFile)\n        {\n            error(token.loc, \"unrecognized declaration\");\n            goto Lerr;\n        }\n        return decldefs;\n\n    Lerr:\n        while (token.value != TOK.semicolon && token.value != TOK.endOfFile)\n            nextToken();\n        nextToken();\n        return new AST.Dsymbols();\n    }\n\n    private StorageClass parseDeprecatedAttribute(ref AST.Expression msg)\n    {\n        if (peek(&token).value != TOK.leftParentheses)\n            return AST.STC.deprecated_;\n\n        nextToken();\n        check(TOK.leftParentheses);\n        AST.Expression e = parseAssignExp();\n        check(TOK.rightParentheses);\n        if (msg)\n        {\n            error(\"conflicting storage class `deprecated(%s)` and `deprecated(%s)`\", msg.toChars(), e.toChars());\n        }\n        msg = e;\n        return AST.STC.undefined_;\n    }\n\n    AST.Dsymbols* parseDeclDefs(int once, AST.Dsymbol* pLastDecl = null, PrefixAttributes!AST* pAttrs = null)\n    {\n        AST.Dsymbol lastDecl = null; // used to link unittest to its previous declaration\n        if (!pLastDecl)\n            pLastDecl = &lastDecl;\n\n        const linksave = linkage; // save global state\n\n        //printf(\"Parser::parseDeclDefs()\\n\");\n        auto decldefs = new AST.Dsymbols();\n        do\n        {\n            // parse result\n            AST.Dsymbol s = null;\n            AST.Dsymbols* a = null;\n\n            PrefixAttributes!AST attrs;\n            if (!once || !pAttrs)\n            {\n                pAttrs = &attrs;\n                pAttrs.comment = token.blockComment;\n            }\n            AST.Prot.Kind prot;\n            StorageClass stc;\n            AST.Condition condition;\n\n            linkage = linksave;\n\n            switch (token.value)\n            {\n            case TOK.enum_:\n                {\n                    /* Determine if this is a manifest constant declaration,\n                     * or a conventional enum.\n                     */\n                    Token* t = peek(&token);\n                    if (t.value == TOK.leftCurly || t.value == TOK.colon)\n                        s = parseEnum();\n                    else if (t.value != TOK.identifier)\n                        goto Ldeclaration;\n                    else\n                    {\n                        t = peek(t);\n                        if (t.value == TOK.leftCurly || t.value == TOK.colon || t.value == TOK.semicolon)\n                            s = parseEnum();\n                        else\n                            goto Ldeclaration;\n                    }\n                    break;\n                }\n            case TOK.import_:\n                a = parseImport();\n                // keep pLastDecl\n                break;\n\n            case TOK.template_:\n                s = cast(AST.Dsymbol)parseTemplateDeclaration();\n                break;\n\n            case TOK.mixin_:\n                {\n                    const loc = token.loc;\n                    switch (peekNext())\n                    {\n                    case TOK.leftParentheses:\n                        {\n                            // mixin(string)\n                            nextToken();\n                            auto exps = parseArguments();\n                            check(TOK.semicolon);\n                            s = new AST.CompileDeclaration(loc, exps);\n                            break;\n                        }\n                    case TOK.template_:\n                        // mixin template\n                        nextToken();\n                        s = cast(AST.Dsymbol)parseTemplateDeclaration(true);\n                        break;\n\n                    default:\n                        s = parseMixin();\n                        break;\n                    }\n                    break;\n                }\n            case TOK.wchar_:\n            case TOK.dchar_:\n            case TOK.bool_:\n            case TOK.char_:\n            case TOK.int8:\n            case TOK.uns8:\n            case TOK.int16:\n            case TOK.uns16:\n            case TOK.int32:\n            case TOK.uns32:\n            case TOK.int64:\n            case TOK.uns64:\n            case TOK.int128:\n            case TOK.uns128:\n            case TOK.float32:\n            case TOK.float64:\n            case TOK.float80:\n            case TOK.imaginary32:\n            case TOK.imaginary64:\n            case TOK.imaginary80:\n            case TOK.complex32:\n            case TOK.complex64:\n            case TOK.complex80:\n            case TOK.void_:\n            case TOK.alias_:\n            case TOK.identifier:\n            case TOK.super_:\n            case TOK.typeof_:\n            case TOK.dot:\n            case TOK.vector:\n            case TOK.struct_:\n            case TOK.union_:\n            case TOK.class_:\n            case TOK.interface_:\n            Ldeclaration:\n                a = parseDeclarations(false, pAttrs, pAttrs.comment);\n                if (a && a.dim)\n                    *pLastDecl = (*a)[a.dim - 1];\n                break;\n\n            case TOK.this_:\n                if (peekNext() == TOK.dot)\n                    goto Ldeclaration;\n                else\n                    s = parseCtor(pAttrs);\n                break;\n\n            case TOK.tilde:\n                s = parseDtor(pAttrs);\n                break;\n\n            case TOK.invariant_:\n                {\n                    Token* t = peek(&token);\n                    if (t.value == TOK.leftParentheses || t.value == TOK.leftCurly)\n                    {\n                        // invariant { statements... }\n                        // invariant() { statements... }\n                        // invariant (expression);\n                        s = parseInvariant(pAttrs);\n                    }\n                    else\n                    {\n                        error(\"invariant body expected, not `%s`\", token.toChars());\n                        goto Lerror;\n                    }\n                    break;\n                }\n            case TOK.unittest_:\n                if (global.params.useUnitTests || global.params.doDocComments || global.params.doHdrGeneration)\n                {\n                    s = parseUnitTest(pAttrs);\n                    if (*pLastDecl)\n                        (*pLastDecl).ddocUnittest = cast(AST.UnitTestDeclaration)s;\n                }\n                else\n                {\n                    // Skip over unittest block by counting { }\n                    Loc loc = token.loc;\n                    int braces = 0;\n                    while (1)\n                    {\n                        nextToken();\n                        switch (token.value)\n                        {\n                        case TOK.leftCurly:\n                            ++braces;\n                            continue;\n\n                        case TOK.rightCurly:\n                            if (--braces)\n                                continue;\n                            nextToken();\n                            break;\n\n                        case TOK.endOfFile:\n                            /* { */\n                            error(loc, \"closing `}` of unittest not found before end of file\");\n                            goto Lerror;\n\n                        default:\n                            continue;\n                        }\n                        break;\n                    }\n                    // Workaround 14894. Add an empty unittest declaration to keep\n                    // the number of symbols in this scope independent of -unittest.\n                    s = new AST.UnitTestDeclaration(loc, token.loc, AST.STC.undefined_, null);\n                }\n                break;\n\n            case TOK.new_:\n                s = parseNew(pAttrs);\n                break;\n\n            case TOK.delete_:\n                s = parseDelete(pAttrs);\n                break;\n\n            case TOK.colon:\n            case TOK.leftCurly:\n                error(\"declaration expected, not `%s`\", token.toChars());\n                goto Lerror;\n\n            case TOK.rightCurly:\n            case TOK.endOfFile:\n                if (once)\n                    error(\"declaration expected, not `%s`\", token.toChars());\n                return decldefs;\n\n            case TOK.static_:\n                {\n                    const next = peekNext();\n                    if (next == TOK.this_)\n                        s = parseStaticCtor(pAttrs);\n                    else if (next == TOK.tilde)\n                        s = parseStaticDtor(pAttrs);\n                    else if (next == TOK.assert_)\n                        s = parseStaticAssert();\n                    else if (next == TOK.if_)\n                    {\n                        condition = parseStaticIfCondition();\n                        AST.Dsymbols* athen;\n                        if (token.value == TOK.colon)\n                            athen = parseBlock(pLastDecl);\n                        else\n                        {\n                            const lookingForElseSave = lookingForElse;\n                            lookingForElse = token.loc;\n                            athen = parseBlock(pLastDecl);\n                            lookingForElse = lookingForElseSave;\n                        }\n                        AST.Dsymbols* aelse = null;\n                        if (token.value == TOK.else_)\n                        {\n                            const elseloc = token.loc;\n                            nextToken();\n                            aelse = parseBlock(pLastDecl);\n                            checkDanglingElse(elseloc);\n                        }\n                        s = new AST.StaticIfDeclaration(condition, athen, aelse);\n                    }\n                    else if (next == TOK.import_)\n                    {\n                        a = parseImport();\n                        // keep pLastDecl\n                    }\n                    else if (next == TOK.foreach_ || next == TOK.foreach_reverse_)\n                    {\n                        s = parseForeach!(true,true)(loc, pLastDecl);\n                    }\n                    else\n                    {\n                        stc = AST.STC.static_;\n                        goto Lstc;\n                    }\n                    break;\n                }\n            case TOK.const_:\n                if (peekNext() == TOK.leftParentheses)\n                    goto Ldeclaration;\n                stc = AST.STC.const_;\n                goto Lstc;\n\n            case TOK.immutable_:\n                if (peekNext() == TOK.leftParentheses)\n                    goto Ldeclaration;\n                stc = AST.STC.immutable_;\n                goto Lstc;\n\n            case TOK.shared_:\n                {\n                    const next = peekNext();\n                    if (next == TOK.leftParentheses)\n                        goto Ldeclaration;\n                    if (next == TOK.static_)\n                    {\n                        TOK next2 = peekNext2();\n                        if (next2 == TOK.this_)\n                        {\n                            s = parseSharedStaticCtor(pAttrs);\n                            break;\n                        }\n                        if (next2 == TOK.tilde)\n                        {\n                            s = parseSharedStaticDtor(pAttrs);\n                            break;\n                        }\n                    }\n                    stc = AST.STC.shared_;\n                    goto Lstc;\n                }\n            case TOK.inout_:\n                if (peekNext() == TOK.leftParentheses)\n                    goto Ldeclaration;\n                stc = AST.STC.wild;\n                goto Lstc;\n\n            case TOK.final_:\n                stc = AST.STC.final_;\n                goto Lstc;\n\n            case TOK.auto_:\n                stc = AST.STC.auto_;\n                goto Lstc;\n\n            case TOK.scope_:\n                stc = AST.STC.scope_;\n                goto Lstc;\n\n            case TOK.override_:\n                stc = AST.STC.override_;\n                goto Lstc;\n\n            case TOK.abstract_:\n                stc = AST.STC.abstract_;\n                goto Lstc;\n\n            case TOK.synchronized_:\n                stc = AST.STC.synchronized_;\n                goto Lstc;\n\n            case TOK.nothrow_:\n                stc = AST.STC.nothrow_;\n                goto Lstc;\n\n            case TOK.pure_:\n                stc = AST.STC.pure_;\n                goto Lstc;\n\n            case TOK.ref_:\n                stc = AST.STC.ref_;\n                goto Lstc;\n\n            case TOK.gshared:\n                stc = AST.STC.gshared;\n                goto Lstc;\n\n            //case TOK.manifest:   stc = STC.manifest;     goto Lstc;\n\n            case TOK.at:\n                {\n                    AST.Expressions* exps = null;\n                    stc = parseAttribute(&exps);\n                    if (stc)\n                        goto Lstc; // it's a predefined attribute\n                    // no redundant/conflicting check for UDAs\n                    pAttrs.udas = AST.UserAttributeDeclaration.concat(pAttrs.udas, exps);\n                    goto Lautodecl;\n                }\n            Lstc:\n                pAttrs.storageClass = appendStorageClass(pAttrs.storageClass, stc);\n                nextToken();\n\n            Lautodecl:\n                Token* tk;\n\n                /* Look for auto initializers:\n                 *      storage_class identifier = initializer;\n                 *      storage_class identifier(...) = initializer;\n                 */\n                if (token.value == TOK.identifier && skipParensIf(peek(&token), &tk) && tk.value == TOK.assign)\n                {\n                    a = parseAutoDeclarations(getStorageClass!AST(pAttrs), pAttrs.comment);\n                    if (a && a.dim)\n                        *pLastDecl = (*a)[a.dim - 1];\n                    if (pAttrs.udas)\n                    {\n                        s = new AST.UserAttributeDeclaration(pAttrs.udas, a);\n                        pAttrs.udas = null;\n                    }\n                    break;\n                }\n\n                /* Look for return type inference for template functions.\n                 */\n                if (token.value == TOK.identifier && skipParens(peek(&token), &tk) && skipAttributes(tk, &tk) &&\n                    (tk.value == TOK.leftParentheses || tk.value == TOK.leftCurly || tk.value == TOK.in_ ||\n                     tk.value == TOK.out_ || tk.value == TOK.do_ ||\n                     tk.value == TOK.identifier && tk.ident == Id._body))\n                {\n                    a = parseDeclarations(true, pAttrs, pAttrs.comment);\n                    if (a && a.dim)\n                        *pLastDecl = (*a)[a.dim - 1];\n                    if (pAttrs.udas)\n                    {\n                        s = new AST.UserAttributeDeclaration(pAttrs.udas, a);\n                        pAttrs.udas = null;\n                    }\n                    break;\n                }\n\n                a = parseBlock(pLastDecl, pAttrs);\n                auto stc2 = getStorageClass!AST(pAttrs);\n                if (stc2 != AST.STC.undefined_)\n                {\n                    s = new AST.StorageClassDeclaration(stc2, a);\n                }\n                if (pAttrs.udas)\n                {\n                    if (s)\n                    {\n                        a = new AST.Dsymbols();\n                        a.push(s);\n                    }\n                    s = new AST.UserAttributeDeclaration(pAttrs.udas, a);\n                    pAttrs.udas = null;\n                }\n                break;\n\n            case TOK.deprecated_:\n                {\n                    AST.Expression e;\n                    if (StorageClass _stc = parseDeprecatedAttribute(pAttrs.depmsg))\n                    {\n                        stc = _stc;\n                        goto Lstc;\n                    }\n                    a = parseBlock(pLastDecl, pAttrs);\n                    if (pAttrs.depmsg)\n                    {\n                        s = new AST.DeprecatedDeclaration(pAttrs.depmsg, a);\n                        pAttrs.depmsg = null;\n                    }\n                    break;\n                }\n            case TOK.leftBracket:\n                {\n                    if (peekNext() == TOK.rightBracket)\n                        error(\"empty attribute list is not allowed\");\n                    error(\"use `@(attributes)` instead of `[attributes]`\");\n                    AST.Expressions* exps = parseArguments();\n                    // no redundant/conflicting check for UDAs\n\n                    pAttrs.udas = AST.UserAttributeDeclaration.concat(pAttrs.udas, exps);\n                    a = parseBlock(pLastDecl, pAttrs);\n                    if (pAttrs.udas)\n                    {\n                        s = new AST.UserAttributeDeclaration(pAttrs.udas, a);\n                        pAttrs.udas = null;\n                    }\n                    break;\n                }\n            case TOK.extern_:\n                {\n                    if (peek(&token).value != TOK.leftParentheses)\n                    {\n                        stc = AST.STC.extern_;\n                        goto Lstc;\n                    }\n\n                    const linkLoc = token.loc;\n                    AST.Identifiers* idents = null;\n                    CPPMANGLE cppmangle;\n                    bool cppMangleOnly = false;\n                    const link = parseLinkage(&idents, cppmangle, cppMangleOnly);\n                    if (pAttrs.link != LINK.default_)\n                    {\n                        if (pAttrs.link != link)\n                        {\n                            error(\"conflicting linkage `extern (%s)` and `extern (%s)`\", AST.linkageToChars(pAttrs.link), AST.linkageToChars(link));\n                        }\n                        else if (idents)\n                        {\n                            // Allow:\n                            //      extern(C++, foo) extern(C++, bar) void foo();\n                            // to be equivalent with:\n                            //      extern(C++, foo.bar) void foo();\n                        }\n                        else\n                            error(\"redundant linkage `extern (%s)`\", AST.linkageToChars(pAttrs.link));\n                    }\n                    pAttrs.link = link;\n                    this.linkage = link;\n                    a = parseBlock(pLastDecl, pAttrs);\n                    if (idents)\n                    {\n                        assert(link == LINK.cpp);\n                        assert(idents.dim);\n                        for (size_t i = idents.dim; i;)\n                        {\n                            Identifier id = (*idents)[--i];\n                            if (s)\n                            {\n                                a = new AST.Dsymbols();\n                                a.push(s);\n                            }\n                            s = new AST.Nspace(linkLoc, id, a, cppMangleOnly);\n                        }\n                        pAttrs.link = LINK.default_;\n                    }\n                    else if (cppmangle != CPPMANGLE.def)\n                    {\n                        assert(link == LINK.cpp);\n                        s = new AST.CPPMangleDeclaration(cppmangle, a);\n                    }\n                    else if (pAttrs.link != LINK.default_)\n                    {\n                        s = new AST.LinkDeclaration(pAttrs.link, a);\n                        pAttrs.link = LINK.default_;\n                    }\n                    break;\n                }\n\n            case TOK.private_:\n                prot = AST.Prot.Kind.private_;\n                goto Lprot;\n\n            case TOK.package_:\n                prot = AST.Prot.Kind.package_;\n                goto Lprot;\n\n            case TOK.protected_:\n                prot = AST.Prot.Kind.protected_;\n                goto Lprot;\n\n            case TOK.public_:\n                prot = AST.Prot.Kind.public_;\n                goto Lprot;\n\n            case TOK.export_:\n                prot = AST.Prot.Kind.export_;\n                goto Lprot;\n            Lprot:\n                {\n                    if (pAttrs.protection.kind != AST.Prot.Kind.undefined)\n                    {\n                        if (pAttrs.protection.kind != prot)\n                            error(\"conflicting protection attribute `%s` and `%s`\", AST.protectionToChars(pAttrs.protection.kind), AST.protectionToChars(prot));\n                        else\n                            error(\"redundant protection attribute `%s`\", AST.protectionToChars(prot));\n                    }\n                    pAttrs.protection.kind = prot;\n\n                    nextToken();\n\n                    // optional qualified package identifier to bind\n                    // protection to\n                    AST.Identifiers* pkg_prot_idents = null;\n                    if (pAttrs.protection.kind == AST.Prot.Kind.package_ && token.value == TOK.leftParentheses)\n                    {\n                        pkg_prot_idents = parseQualifiedIdentifier(\"protection package\");\n                        if (pkg_prot_idents)\n                            check(TOK.rightParentheses);\n                        else\n                        {\n                            while (token.value != TOK.semicolon && token.value != TOK.endOfFile)\n                                nextToken();\n                            nextToken();\n                            break;\n                        }\n                    }\n\n                    const attrloc = token.loc;\n                    a = parseBlock(pLastDecl, pAttrs);\n                    if (pAttrs.protection.kind != AST.Prot.Kind.undefined)\n                    {\n                        if (pAttrs.protection.kind == AST.Prot.Kind.package_ && pkg_prot_idents)\n                            s = new AST.ProtDeclaration(attrloc, pkg_prot_idents, a);\n                        else\n                            s = new AST.ProtDeclaration(attrloc, pAttrs.protection, a);\n\n                        pAttrs.protection = AST.Prot(AST.Prot.Kind.undefined);\n                    }\n                    break;\n                }\n            case TOK.align_:\n                {\n                    const attrLoc = token.loc;\n\n                    nextToken();\n\n                    AST.Expression e = null; // default\n                    if (token.value == TOK.leftParentheses)\n                    {\n                        nextToken();\n                        e = parseAssignExp();\n                        check(TOK.rightParentheses);\n                    }\n\n                    if (pAttrs.setAlignment)\n                    {\n                        if (e)\n                            error(\"redundant alignment attribute `align(%s)`\", e.toChars());\n                        else\n                            error(\"redundant alignment attribute `align`\");\n                    }\n\n                    pAttrs.setAlignment = true;\n                    pAttrs.ealign = e;\n                    a = parseBlock(pLastDecl, pAttrs);\n                    if (pAttrs.setAlignment)\n                    {\n                        s = new AST.AlignDeclaration(attrLoc, pAttrs.ealign, a);\n                        pAttrs.setAlignment = false;\n                        pAttrs.ealign = null;\n                    }\n                    break;\n                }\n            case TOK.pragma_:\n                {\n                    AST.Expressions* args = null;\n                    const loc = token.loc;\n\n                    nextToken();\n                    check(TOK.leftParentheses);\n                    if (token.value != TOK.identifier)\n                    {\n                        error(\"`pragma(identifier)` expected\");\n                        goto Lerror;\n                    }\n                    Identifier ident = token.ident;\n                    nextToken();\n                    if (token.value == TOK.comma && peekNext() != TOK.rightParentheses)\n                        args = parseArguments(); // pragma(identifier, args...)\n                    else\n                        check(TOK.rightParentheses); // pragma(identifier)\n\n                    AST.Dsymbols* a2 = null;\n                    if (token.value == TOK.semicolon)\n                    {\n                        /* https://issues.dlang.org/show_bug.cgi?id=2354\n                         * Accept single semicolon as an empty\n                         * DeclarationBlock following attribute.\n                         *\n                         * Attribute DeclarationBlock\n                         * Pragma    DeclDef\n                         *           ;\n                         */\n                        nextToken();\n                    }\n                    else\n                        a2 = parseBlock(pLastDecl);\n                    s = new AST.PragmaDeclaration(loc, ident, args, a2);\n                    break;\n                }\n            case TOK.debug_:\n                nextToken();\n                if (token.value == TOK.assign)\n                {\n                    nextToken();\n                    if (token.value == TOK.identifier)\n                        s = new AST.DebugSymbol(token.loc, token.ident);\n                    else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)\n                        s = new AST.DebugSymbol(token.loc, cast(uint)token.unsvalue);\n                    else\n                    {\n                        error(\"identifier or integer expected, not `%s`\", token.toChars());\n                        s = null;\n                    }\n                    nextToken();\n                    if (token.value != TOK.semicolon)\n                        error(\"semicolon expected\");\n                    nextToken();\n                    break;\n                }\n\n                condition = parseDebugCondition();\n                goto Lcondition;\n\n            case TOK.version_:\n                nextToken();\n                if (token.value == TOK.assign)\n                {\n                    nextToken();\n                    if (token.value == TOK.identifier)\n                        s = new AST.VersionSymbol(token.loc, token.ident);\n                    else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)\n                        s = new AST.VersionSymbol(token.loc, cast(uint)token.unsvalue);\n                    else\n                    {\n                        error(\"identifier or integer expected, not `%s`\", token.toChars());\n                        s = null;\n                    }\n                    nextToken();\n                    if (token.value != TOK.semicolon)\n                        error(\"semicolon expected\");\n                    nextToken();\n                    break;\n                }\n                condition = parseVersionCondition();\n                goto Lcondition;\n\n            Lcondition:\n                {\n                    AST.Dsymbols* athen;\n                    if (token.value == TOK.colon)\n                        athen = parseBlock(pLastDecl);\n                    else\n                    {\n                        const lookingForElseSave = lookingForElse;\n                        lookingForElse = token.loc;\n                        athen = parseBlock(pLastDecl);\n                        lookingForElse = lookingForElseSave;\n                    }\n                    AST.Dsymbols* aelse = null;\n                    if (token.value == TOK.else_)\n                    {\n                        const elseloc = token.loc;\n                        nextToken();\n                        aelse = parseBlock(pLastDecl);\n                        checkDanglingElse(elseloc);\n                    }\n                    s = new AST.ConditionalDeclaration(condition, athen, aelse);\n                    break;\n                }\n            case TOK.semicolon:\n                // empty declaration\n                //error(\"empty declaration\");\n                nextToken();\n                continue;\n\n            default:\n                error(\"declaration expected, not `%s`\", token.toChars());\n            Lerror:\n                while (token.value != TOK.semicolon && token.value != TOK.endOfFile)\n                    nextToken();\n                nextToken();\n                s = null;\n                continue;\n            }\n\n            if (s)\n            {\n                if (!s.isAttribDeclaration())\n                    *pLastDecl = s;\n                decldefs.push(s);\n                addComment(s, pAttrs.comment);\n            }\n            else if (a && a.dim)\n            {\n                decldefs.append(a);\n            }\n        }\n        while (!once);\n\n        linkage = linksave;\n\n        return decldefs;\n    }\n\n    /*****************************************\n     * Parse auto declarations of the form:\n     *   storageClass ident = init, ident = init, ... ;\n     * and return the array of them.\n     * Starts with token on the first ident.\n     * Ends with scanner past closing ';'\n     */\n    AST.Dsymbols* parseAutoDeclarations(StorageClass storageClass, const(char)* comment)\n    {\n        //printf(\"parseAutoDeclarations\\n\");\n        Token* tk;\n        auto a = new AST.Dsymbols();\n\n        while (1)\n        {\n            const loc = token.loc;\n            Identifier ident = token.ident;\n            nextToken(); // skip over ident\n\n            AST.TemplateParameters* tpl = null;\n            if (token.value == TOK.leftParentheses)\n                tpl = parseTemplateParameterList();\n\n            check(TOK.assign);   // skip over '='\n            AST.Initializer _init = parseInitializer();\n            auto v = new AST.VarDeclaration(loc, null, ident, _init, storageClass);\n\n            AST.Dsymbol s = v;\n            if (tpl)\n            {\n                auto a2 = new AST.Dsymbols();\n                a2.push(v);\n                auto tempdecl = new AST.TemplateDeclaration(loc, ident, tpl, null, a2, 0);\n                s = tempdecl;\n            }\n            a.push(s);\n            switch (token.value)\n            {\n            case TOK.semicolon:\n                nextToken();\n                addComment(s, comment);\n                break;\n\n            case TOK.comma:\n                nextToken();\n                if (!(token.value == TOK.identifier && skipParensIf(peek(&token), &tk) && tk.value == TOK.assign))\n                {\n                    error(\"identifier expected following comma\");\n                    break;\n                }\n                addComment(s, comment);\n                continue;\n\n            default:\n                error(\"semicolon expected following auto declaration, not `%s`\", token.toChars());\n                break;\n            }\n            break;\n        }\n        return a;\n    }\n\n    /********************************************\n     * Parse declarations after an align, protection, or extern decl.\n     */\n    AST.Dsymbols* parseBlock(AST.Dsymbol* pLastDecl, PrefixAttributes!AST* pAttrs = null)\n    {\n        AST.Dsymbols* a = null;\n\n        //printf(\"parseBlock()\\n\");\n        switch (token.value)\n        {\n        case TOK.semicolon:\n            error(\"declaration expected following attribute, not `;`\");\n            nextToken();\n            break;\n\n        case TOK.endOfFile:\n            error(\"declaration expected following attribute, not end of file\");\n            break;\n\n        case TOK.leftCurly:\n            {\n                const lookingForElseSave = lookingForElse;\n                lookingForElse = Loc();\n\n                nextToken();\n                a = parseDeclDefs(0, pLastDecl);\n                if (token.value != TOK.rightCurly)\n                {\n                    /* { */\n                    error(\"matching `}` expected, not `%s`\", token.toChars());\n                }\n                else\n                    nextToken();\n                lookingForElse = lookingForElseSave;\n                break;\n            }\n        case TOK.colon:\n            nextToken();\n            a = parseDeclDefs(0, pLastDecl); // grab declarations up to closing curly bracket\n            break;\n\n        default:\n            a = parseDeclDefs(1, pLastDecl, pAttrs);\n            break;\n        }\n        return a;\n    }\n\n    /*********************************************\n     * Give error on redundant/conflicting storage class.\n     */\n    StorageClass appendStorageClass(StorageClass storageClass, StorageClass stc)\n    {\n        if ((storageClass & stc) || (storageClass & AST.STC.in_ && stc & (AST.STC.const_ | AST.STC.scope_)) || (stc & AST.STC.in_ && storageClass & (AST.STC.const_ | AST.STC.scope_)))\n        {\n            OutBuffer buf;\n            AST.stcToBuffer(&buf, stc);\n            error(\"redundant attribute `%s`\", buf.peekString());\n            return storageClass | stc;\n        }\n\n        storageClass |= stc;\n\n        if (stc & (AST.STC.const_ | AST.STC.immutable_ | AST.STC.manifest))\n        {\n            StorageClass u = storageClass & (AST.STC.const_ | AST.STC.immutable_ | AST.STC.manifest);\n            if (u & (u - 1))\n                error(\"conflicting attribute `%s`\", Token.toChars(token.value));\n        }\n        if (stc & (AST.STC.gshared | AST.STC.shared_ | AST.STC.tls))\n        {\n            StorageClass u = storageClass & (AST.STC.gshared | AST.STC.shared_ | AST.STC.tls);\n            if (u & (u - 1))\n                error(\"conflicting attribute `%s`\", Token.toChars(token.value));\n        }\n        if (stc & (AST.STC.safe | AST.STC.system | AST.STC.trusted))\n        {\n            StorageClass u = storageClass & (AST.STC.safe | AST.STC.system | AST.STC.trusted);\n            if (u & (u - 1))\n                error(\"conflicting attribute `@%s`\", token.toChars());\n        }\n\n        return storageClass;\n    }\n\n    /***********************************************\n     * Parse attribute, lexer is on '@'.\n     * Input:\n     *      pudas           array of UDAs to append to\n     * Returns:\n     *      storage class   if a predefined attribute; also scanner remains on identifier.\n     *      0               if not a predefined attribute\n     *      *pudas          set if user defined attribute, scanner is past UDA\n     *      *pudas          NULL if not a user defined attribute\n     */\n    StorageClass parseAttribute(AST.Expressions** pudas)\n    {\n        nextToken();\n        AST.Expressions* udas = null;\n        StorageClass stc = 0;\n        if (token.value == TOK.identifier)\n        {\n            if (token.ident == Id.property)\n                stc = AST.STC.property;\n            else if (token.ident == Id.nogc)\n                stc = AST.STC.nogc;\n            else if (token.ident == Id.safe)\n                stc = AST.STC.safe;\n            else if (token.ident == Id.trusted)\n                stc = AST.STC.trusted;\n            else if (token.ident == Id.system)\n                stc = AST.STC.system;\n            else if (token.ident == Id.disable)\n                stc = AST.STC.disable;\n            else if (token.ident == Id.future)\n                stc = AST.STC.future;\n            else\n            {\n                // Allow identifier, template instantiation, or function call\n                AST.Expression exp = parsePrimaryExp();\n                if (token.value == TOK.leftParentheses)\n                {\n                    const loc = token.loc;\n                    exp = new AST.CallExp(loc, exp, parseArguments());\n                }\n\n                udas = new AST.Expressions();\n                udas.push(exp);\n            }\n        }\n        else if (token.value == TOK.leftParentheses)\n        {\n            // @( ArgumentList )\n            // Concatenate with existing\n            if (peekNext() == TOK.rightParentheses)\n                error(\"empty attribute list is not allowed\");\n            udas = parseArguments();\n        }\n        else\n        {\n            error(\"@identifier or @(ArgumentList) expected, not `@%s`\", token.toChars());\n        }\n\n        if (stc)\n        {\n        }\n        else if (udas)\n        {\n            *pudas = AST.UserAttributeDeclaration.concat(*pudas, udas);\n        }\n        else\n            error(\"valid attributes are `@property`, `@safe`, `@trusted`, `@system`, `@disable`, `@nogc`\");\n        return stc;\n    }\n\n    /***********************************************\n     * Parse const/immutable/shared/inout/nothrow/pure postfix\n     */\n    StorageClass parsePostfix(StorageClass storageClass, AST.Expressions** pudas)\n    {\n        while (1)\n        {\n            StorageClass stc;\n            switch (token.value)\n            {\n            case TOK.const_:\n                stc = AST.STC.const_;\n                break;\n\n            case TOK.immutable_:\n                stc = AST.STC.immutable_;\n                break;\n\n            case TOK.shared_:\n                stc = AST.STC.shared_;\n                break;\n\n            case TOK.inout_:\n                stc = AST.STC.wild;\n                break;\n\n            case TOK.nothrow_:\n                stc = AST.STC.nothrow_;\n                break;\n\n            case TOK.pure_:\n                stc = AST.STC.pure_;\n                break;\n\n            case TOK.return_:\n                stc = AST.STC.return_;\n                break;\n\n            case TOK.scope_:\n                stc = AST.STC.scope_;\n                break;\n\n            case TOK.at:\n                {\n                    AST.Expressions* udas = null;\n                    stc = parseAttribute(&udas);\n                    if (udas)\n                    {\n                        if (pudas)\n                            *pudas = AST.UserAttributeDeclaration.concat(*pudas, udas);\n                        else\n                        {\n                            // Disallow:\n                            //      void function() @uda fp;\n                            //      () @uda { return 1; }\n                            error(\"user-defined attributes cannot appear as postfixes\");\n                        }\n                        continue;\n                    }\n                    break;\n                }\n            default:\n                return storageClass;\n            }\n            storageClass = appendStorageClass(storageClass, stc);\n            nextToken();\n        }\n    }\n\n    StorageClass parseTypeCtor()\n    {\n        StorageClass storageClass = AST.STC.undefined_;\n\n        while (1)\n        {\n            if (peek(&token).value == TOK.leftParentheses)\n                return storageClass;\n\n            StorageClass stc;\n            switch (token.value)\n            {\n            case TOK.const_:\n                stc = AST.STC.const_;\n                break;\n\n            case TOK.immutable_:\n                stc = AST.STC.immutable_;\n                break;\n\n            case TOK.shared_:\n                stc = AST.STC.shared_;\n                break;\n\n            case TOK.inout_:\n                stc = AST.STC.wild;\n                break;\n\n            default:\n                return storageClass;\n            }\n            storageClass = appendStorageClass(storageClass, stc);\n            nextToken();\n        }\n    }\n\n    /**************************************\n     * Parse constraint.\n     * Constraint is of the form:\n     *      if ( ConstraintExpression )\n     */\n    AST.Expression parseConstraint()\n    {\n        AST.Expression e = null;\n        if (token.value == TOK.if_)\n        {\n            nextToken(); // skip over 'if'\n            check(TOK.leftParentheses);\n            e = parseExpression();\n            check(TOK.rightParentheses);\n        }\n        return e;\n    }\n\n    /**************************************\n     * Parse a TemplateDeclaration.\n     */\n    AST.TemplateDeclaration parseTemplateDeclaration(bool ismixin = false)\n    {\n        AST.TemplateDeclaration tempdecl;\n        Identifier id;\n        AST.TemplateParameters* tpl;\n        AST.Dsymbols* decldefs;\n        AST.Expression constraint = null;\n        const loc = token.loc;\n\n        nextToken();\n        if (token.value != TOK.identifier)\n        {\n            error(\"identifier expected following `template`\");\n            goto Lerr;\n        }\n        id = token.ident;\n        nextToken();\n        tpl = parseTemplateParameterList();\n        if (!tpl)\n            goto Lerr;\n\n        constraint = parseConstraint();\n\n        if (token.value != TOK.leftCurly)\n        {\n            error(\"members of template declaration expected\");\n            goto Lerr;\n        }\n        else\n            decldefs = parseBlock(null);\n\n        tempdecl = new AST.TemplateDeclaration(loc, id, tpl, constraint, decldefs, ismixin);\n        return tempdecl;\n\n    Lerr:\n        return null;\n    }\n\n    /******************************************\n     * Parse template parameter list.\n     * Input:\n     *      flag    0: parsing \"( list )\"\n     *              1: parsing non-empty \"list $(RPAREN)\"\n     */\n    AST.TemplateParameters* parseTemplateParameterList(int flag = 0)\n    {\n        auto tpl = new AST.TemplateParameters();\n\n        if (!flag && token.value != TOK.leftParentheses)\n        {\n            error(\"parenthesized template parameter list expected following template identifier\");\n            goto Lerr;\n        }\n        nextToken();\n\n        // Get array of TemplateParameters\n        if (flag || token.value != TOK.rightParentheses)\n        {\n            int isvariadic = 0;\n            while (token.value != TOK.rightParentheses)\n            {\n                AST.TemplateParameter tp;\n                Loc loc;\n                Identifier tp_ident = null;\n                AST.Type tp_spectype = null;\n                AST.Type tp_valtype = null;\n                AST.Type tp_defaulttype = null;\n                AST.Expression tp_specvalue = null;\n                AST.Expression tp_defaultvalue = null;\n                Token* t;\n\n                // Get TemplateParameter\n\n                // First, look ahead to see if it is a TypeParameter or a ValueParameter\n                t = peek(&token);\n                if (token.value == TOK.alias_)\n                {\n                    // AliasParameter\n                    nextToken();\n                    loc = token.loc; // todo\n                    AST.Type spectype = null;\n                    if (isDeclaration(&token, NeedDeclaratorId.must, TOK.reserved, null))\n                    {\n                        spectype = parseType(&tp_ident);\n                    }\n                    else\n                    {\n                        if (token.value != TOK.identifier)\n                        {\n                            error(\"identifier expected for template alias parameter\");\n                            goto Lerr;\n                        }\n                        tp_ident = token.ident;\n                        nextToken();\n                    }\n                    RootObject spec = null;\n                    if (token.value == TOK.colon) // : Type\n                    {\n                        nextToken();\n                        if (isDeclaration(&token, NeedDeclaratorId.no, TOK.reserved, null))\n                            spec = parseType();\n                        else\n                            spec = parseCondExp();\n                    }\n                    RootObject def = null;\n                    if (token.value == TOK.assign) // = Type\n                    {\n                        nextToken();\n                        if (isDeclaration(&token, NeedDeclaratorId.no, TOK.reserved, null))\n                            def = parseType();\n                        else\n                            def = parseCondExp();\n                    }\n                    tp = new AST.TemplateAliasParameter(loc, tp_ident, spectype, spec, def);\n                }\n                else if (t.value == TOK.colon || t.value == TOK.assign || t.value == TOK.comma || t.value == TOK.rightParentheses)\n                {\n                    // TypeParameter\n                    if (token.value != TOK.identifier)\n                    {\n                        error(\"identifier expected for template type parameter\");\n                        goto Lerr;\n                    }\n                    loc = token.loc;\n                    tp_ident = token.ident;\n                    nextToken();\n                    if (token.value == TOK.colon) // : Type\n                    {\n                        nextToken();\n                        tp_spectype = parseType();\n                    }\n                    if (token.value == TOK.assign) // = Type\n                    {\n                        nextToken();\n                        tp_defaulttype = parseType();\n                    }\n                    tp = new AST.TemplateTypeParameter(loc, tp_ident, tp_spectype, tp_defaulttype);\n                }\n                else if (token.value == TOK.identifier && t.value == TOK.dotDotDot)\n                {\n                    // ident...\n                    if (isvariadic)\n                        error(\"variadic template parameter must be last\");\n                    isvariadic = 1;\n                    loc = token.loc;\n                    tp_ident = token.ident;\n                    nextToken();\n                    nextToken();\n                    tp = new AST.TemplateTupleParameter(loc, tp_ident);\n                }\n                else if (token.value == TOK.this_)\n                {\n                    // ThisParameter\n                    nextToken();\n                    if (token.value != TOK.identifier)\n                    {\n                        error(\"identifier expected for template this parameter\");\n                        goto Lerr;\n                    }\n                    loc = token.loc;\n                    tp_ident = token.ident;\n                    nextToken();\n                    if (token.value == TOK.colon) // : Type\n                    {\n                        nextToken();\n                        tp_spectype = parseType();\n                    }\n                    if (token.value == TOK.assign) // = Type\n                    {\n                        nextToken();\n                        tp_defaulttype = parseType();\n                    }\n                    tp = new AST.TemplateThisParameter(loc, tp_ident, tp_spectype, tp_defaulttype);\n                }\n                else\n                {\n                    // ValueParameter\n                    loc = token.loc; // todo\n                    tp_valtype = parseType(&tp_ident);\n                    if (!tp_ident)\n                    {\n                        error(\"identifier expected for template value parameter\");\n                        tp_ident = Identifier.idPool(\"error\");\n                    }\n                    if (token.value == TOK.colon) // : CondExpression\n                    {\n                        nextToken();\n                        tp_specvalue = parseCondExp();\n                    }\n                    if (token.value == TOK.assign) // = CondExpression\n                    {\n                        nextToken();\n                        tp_defaultvalue = parseDefaultInitExp();\n                    }\n                    tp = new AST.TemplateValueParameter(loc, tp_ident, tp_valtype, tp_specvalue, tp_defaultvalue);\n                }\n                tpl.push(tp);\n                if (token.value != TOK.comma)\n                    break;\n                nextToken();\n            }\n        }\n        check(TOK.rightParentheses);\n\n    Lerr:\n        return tpl;\n    }\n\n    /******************************************\n     * Parse template mixin.\n     *      mixin Foo;\n     *      mixin Foo!(args);\n     *      mixin a.b.c!(args).Foo!(args);\n     *      mixin Foo!(args) identifier;\n     *      mixin typeof(expr).identifier!(args);\n     */\n    AST.Dsymbol parseMixin()\n    {\n        AST.TemplateMixin tm;\n        Identifier id;\n        AST.Objects* tiargs;\n\n        //printf(\"parseMixin()\\n\");\n        const locMixin = token.loc;\n        nextToken(); // skip 'mixin'\n\n        auto loc = token.loc;\n        AST.TypeQualified tqual = null;\n        if (token.value == TOK.dot)\n        {\n            id = Id.empty;\n        }\n        else\n        {\n            if (token.value == TOK.typeof_)\n            {\n                tqual = parseTypeof();\n                check(TOK.dot);\n            }\n            if (token.value != TOK.identifier)\n            {\n                error(\"identifier expected, not `%s`\", token.toChars());\n                id = Id.empty;\n            }\n            else\n                id = token.ident;\n            nextToken();\n        }\n\n        while (1)\n        {\n            tiargs = null;\n            if (token.value == TOK.not)\n            {\n                tiargs = parseTemplateArguments();\n            }\n\n            if (tiargs && token.value == TOK.dot)\n            {\n                auto tempinst = new AST.TemplateInstance(loc, id, tiargs);\n                if (!tqual)\n                    tqual = new AST.TypeInstance(loc, tempinst);\n                else\n                    tqual.addInst(tempinst);\n                tiargs = null;\n            }\n            else\n            {\n                if (!tqual)\n                    tqual = new AST.TypeIdentifier(loc, id);\n                else\n                    tqual.addIdent(id);\n            }\n\n            if (token.value != TOK.dot)\n                break;\n\n            nextToken();\n            if (token.value != TOK.identifier)\n            {\n                error(\"identifier expected following `.` instead of `%s`\", token.toChars());\n                break;\n            }\n            loc = token.loc;\n            id = token.ident;\n            nextToken();\n        }\n\n        if (token.value == TOK.identifier)\n        {\n            id = token.ident;\n            nextToken();\n        }\n        else\n            id = null;\n\n        tm = new AST.TemplateMixin(locMixin, id, tqual, tiargs);\n        if (token.value != TOK.semicolon)\n            error(\"`;` expected after mixin\");\n        nextToken();\n\n        return tm;\n    }\n\n    /******************************************\n     * Parse template arguments.\n     * Input:\n     *      current token is opening '!'\n     * Output:\n     *      current token is one after closing '$(RPAREN)'\n     */\n    AST.Objects* parseTemplateArguments()\n    {\n        AST.Objects* tiargs;\n\n        nextToken();\n        if (token.value == TOK.leftParentheses)\n        {\n            // ident!(template_arguments)\n            tiargs = parseTemplateArgumentList();\n        }\n        else\n        {\n            // ident!template_argument\n            tiargs = parseTemplateSingleArgument();\n        }\n        if (token.value == TOK.not)\n        {\n            TOK tok = peekNext();\n            if (tok != TOK.is_ && tok != TOK.in_)\n            {\n                error(\"multiple ! arguments are not allowed\");\n            Lagain:\n                nextToken();\n                if (token.value == TOK.leftParentheses)\n                    parseTemplateArgumentList();\n                else\n                    parseTemplateSingleArgument();\n                if (token.value == TOK.not && (tok = peekNext()) != TOK.is_ && tok != TOK.in_)\n                    goto Lagain;\n            }\n        }\n        return tiargs;\n    }\n\n    /******************************************\n     * Parse template argument list.\n     * Input:\n     *      current token is opening '$(LPAREN)',\n     *          or ',' for __traits\n     * Output:\n     *      current token is one after closing '$(RPAREN)'\n     */\n    AST.Objects* parseTemplateArgumentList()\n    {\n        //printf(\"Parser::parseTemplateArgumentList()\\n\");\n        auto tiargs = new AST.Objects();\n        TOK endtok = TOK.rightParentheses;\n        assert(token.value == TOK.leftParentheses || token.value == TOK.comma);\n        nextToken();\n\n        // Get TemplateArgumentList\n        while (token.value != endtok)\n        {\n            // See if it is an Expression or a Type\n            if (isDeclaration(&token, NeedDeclaratorId.no, TOK.reserved, null))\n            {\n                // Template argument is a type\n                AST.Type ta = parseType();\n                tiargs.push(ta);\n            }\n            else\n            {\n                // Template argument is an expression\n                AST.Expression ea = parseAssignExp();\n                tiargs.push(ea);\n            }\n            if (token.value != TOK.comma)\n                break;\n            nextToken();\n        }\n        check(endtok, \"template argument list\");\n        return tiargs;\n    }\n\n    /*****************************\n     * Parse single template argument, to support the syntax:\n     *      foo!arg\n     * Input:\n     *      current token is the arg\n     */\n    AST.Objects* parseTemplateSingleArgument()\n    {\n        //printf(\"parseTemplateSingleArgument()\\n\");\n        auto tiargs = new AST.Objects();\n        AST.Type ta;\n        switch (token.value)\n        {\n        case TOK.identifier:\n            ta = new AST.TypeIdentifier(token.loc, token.ident);\n            goto LabelX;\n\n        case TOK.vector:\n            ta = parseVector();\n            goto LabelX;\n\n        case TOK.void_:\n            ta = AST.Type.tvoid;\n            goto LabelX;\n\n        case TOK.int8:\n            ta = AST.Type.tint8;\n            goto LabelX;\n\n        case TOK.uns8:\n            ta = AST.Type.tuns8;\n            goto LabelX;\n\n        case TOK.int16:\n            ta = AST.Type.tint16;\n            goto LabelX;\n\n        case TOK.uns16:\n            ta = AST.Type.tuns16;\n            goto LabelX;\n\n        case TOK.int32:\n            ta = AST.Type.tint32;\n            goto LabelX;\n\n        case TOK.uns32:\n            ta = AST.Type.tuns32;\n            goto LabelX;\n\n        case TOK.int64:\n            ta = AST.Type.tint64;\n            goto LabelX;\n\n        case TOK.uns64:\n            ta = AST.Type.tuns64;\n            goto LabelX;\n\n        case TOK.int128:\n            ta = AST.Type.tint128;\n            goto LabelX;\n\n        case TOK.uns128:\n            ta = AST.Type.tuns128;\n            goto LabelX;\n\n        case TOK.float32:\n            ta = AST.Type.tfloat32;\n            goto LabelX;\n\n        case TOK.float64:\n            ta = AST.Type.tfloat64;\n            goto LabelX;\n\n        case TOK.float80:\n            ta = AST.Type.tfloat80;\n            goto LabelX;\n\n        case TOK.imaginary32:\n            ta = AST.Type.timaginary32;\n            goto LabelX;\n\n        case TOK.imaginary64:\n            ta = AST.Type.timaginary64;\n            goto LabelX;\n\n        case TOK.imaginary80:\n            ta = AST.Type.timaginary80;\n            goto LabelX;\n\n        case TOK.complex32:\n            ta = AST.Type.tcomplex32;\n            goto LabelX;\n\n        case TOK.complex64:\n            ta = AST.Type.tcomplex64;\n            goto LabelX;\n\n        case TOK.complex80:\n            ta = AST.Type.tcomplex80;\n            goto LabelX;\n\n        case TOK.bool_:\n            ta = AST.Type.tbool;\n            goto LabelX;\n\n        case TOK.char_:\n            ta = AST.Type.tchar;\n            goto LabelX;\n\n        case TOK.wchar_:\n            ta = AST.Type.twchar;\n            goto LabelX;\n\n        case TOK.dchar_:\n            ta = AST.Type.tdchar;\n            goto LabelX;\n        LabelX:\n            tiargs.push(ta);\n            nextToken();\n            break;\n\n        case TOK.int32Literal:\n        case TOK.uns32Literal:\n        case TOK.int64Literal:\n        case TOK.uns64Literal:\n        case TOK.int128Literal:\n        case TOK.uns128Literal:\n        case TOK.float32Literal:\n        case TOK.float64Literal:\n        case TOK.float80Literal:\n        case TOK.imaginary32Literal:\n        case TOK.imaginary64Literal:\n        case TOK.imaginary80Literal:\n        case TOK.null_:\n        case TOK.true_:\n        case TOK.false_:\n        case TOK.charLiteral:\n        case TOK.wcharLiteral:\n        case TOK.dcharLiteral:\n        case TOK.string_:\n        case TOK.hexadecimalString:\n        case TOK.file:\n        case TOK.fileFullPath:\n        case TOK.line:\n        case TOK.moduleString:\n        case TOK.functionString:\n        case TOK.prettyFunction:\n        case TOK.this_:\n            {\n                // Template argument is an expression\n                AST.Expression ea = parsePrimaryExp();\n                tiargs.push(ea);\n                break;\n            }\n        default:\n            error(\"template argument expected following `!`\");\n            break;\n        }\n        return tiargs;\n    }\n\n    /**********************************\n     * Parse a static assertion.\n     * Current token is 'static'.\n     */\n    AST.StaticAssert parseStaticAssert()\n    {\n        const loc = token.loc;\n        AST.Expression exp;\n        AST.Expression msg = null;\n\n        //printf(\"parseStaticAssert()\\n\");\n        nextToken();\n        nextToken();\n        check(TOK.leftParentheses);\n        exp = parseAssignExp();\n        if (token.value == TOK.comma)\n        {\n            nextToken();\n            if (token.value != TOK.rightParentheses)\n            {\n                msg = parseAssignExp();\n                if (token.value == TOK.comma)\n                    nextToken();\n            }\n        }\n        check(TOK.rightParentheses);\n        check(TOK.semicolon);\n        return new AST.StaticAssert(loc, exp, msg);\n    }\n\n    /***********************************\n     * Parse typeof(expression).\n     * Current token is on the 'typeof'.\n     */\n    AST.TypeQualified parseTypeof()\n    {\n        AST.TypeQualified t;\n        const loc = token.loc;\n\n        nextToken();\n        check(TOK.leftParentheses);\n        if (token.value == TOK.return_) // typeof(return)\n        {\n            nextToken();\n            t = new AST.TypeReturn(loc);\n        }\n        else\n        {\n            AST.Expression exp = parseExpression(); // typeof(expression)\n            t = new AST.TypeTypeof(loc, exp);\n        }\n        check(TOK.rightParentheses);\n        return t;\n    }\n\n    /***********************************\n     * Parse __vector(type).\n     * Current token is on the '__vector'.\n     */\n    AST.Type parseVector()\n    {\n        nextToken();\n        check(TOK.leftParentheses);\n        AST.Type tb = parseType();\n        check(TOK.rightParentheses);\n        return new AST.TypeVector(tb);\n    }\n\n    /***********************************\n     * Parse:\n     *      extern (linkage)\n     *      extern (C++, namespaces)\n     *      extern (C++, \"namespace\", \"namespaces\", ...)\n     * The parser is on the 'extern' token.\n     */\n    LINK parseLinkage(AST.Identifiers** pidents, out CPPMANGLE cppmangle, out bool cppMangleOnly)\n    {\n        AST.Identifiers* idents = null;\n        cppmangle = CPPMANGLE.def;\n        LINK link = LINK.default_;\n        nextToken();\n        assert(token.value == TOK.leftParentheses);\n        nextToken();\n        if (token.value == TOK.identifier)\n        {\n            Identifier id = token.ident;\n            nextToken();\n            if (id == Id.Windows)\n                link = LINK.windows;\n            else if (id == Id.Pascal)\n                link = LINK.pascal;\n            else if (id == Id.D)\n                link = LINK.d;\n            else if (id == Id.C)\n            {\n                link = LINK.c;\n                if (token.value == TOK.plusPlus)\n                {\n                    link = LINK.cpp;\n                    nextToken();\n                    if (token.value == TOK.comma) // , namespaces or class or struct\n                    {\n                        nextToken();\n                        if (token.value == TOK.class_ || token.value == TOK.struct_)\n                        {\n                            cppmangle = token.value == TOK.class_ ? CPPMANGLE.asClass : CPPMANGLE.asStruct;\n                            nextToken();\n                        }\n                        else if (token.value == TOK.string_) // extern(C++, \"namespace\", \"namespaces\")\n                        {\n                            cppMangleOnly = true;\n                            idents = new AST.Identifiers();\n\n                            while (1)\n                            {\n                                AST.StringExp stringExp = cast(AST.StringExp)parsePrimaryExp();\n                                const(char)[] name = stringExp.toStringz();\n                                if (name.length == 0)\n                                {\n                                    error(\"invalid zero length C++ namespace\");\n                                    idents = null;\n                                    break;\n                                }\n                                else if (!Identifier.isValidIdentifier(name))\n                                {\n                                    error(\"expected valid identifer for C++ namespace but got `%s`\", name.ptr);\n                                    idents = null;\n                                    break;\n                                }\n                                idents.push(Identifier.idPool(name));\n                                if (token.value == TOK.comma)\n                                {\n                                    nextToken();\n                                    if (token.value != TOK.string_)\n                                    {\n                                        error(\"string expected following `,` for C++ namespace, not `%s`\", token.toChars());\n                                        idents = null;\n                                        break;\n                                    }\n                                }\n                                else\n                                    break;\n                            }\n                        }\n                        else\n                        {\n                            idents = new AST.Identifiers();\n                            while (1)\n                            {\n                                if (token.value == TOK.identifier)\n                                {\n                                    Identifier idn = token.ident;\n                                    idents.push(idn);\n                                    nextToken();\n                                    if (token.value == TOK.dot)\n                                    {\n                                        nextToken();\n                                        continue;\n                                    }\n                                }\n                                else\n                                {\n                                    error(\"identifier expected for C++ namespace\");\n                                    idents = null;  // error occurred, invalidate list of elements.\n                                }\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n            else if (id == Id.Objective) // Looking for tokens \"Objective-C\"\n            {\n                if (token.value == TOK.min)\n                {\n                    nextToken();\n                    if (token.ident == Id.C)\n                    {\n                        link = LINK.objc;\n                        nextToken();\n                    }\n                    else\n                        goto LinvalidLinkage;\n                }\n                else\n                    goto LinvalidLinkage;\n            }\n            else if (id == Id.System)\n            {\n                link = LINK.system;\n            }\n            else\n            {\n            LinvalidLinkage:\n                error(\"valid linkage identifiers are `D`, `C`, `C++`, `Objective-C`, `Pascal`, `Windows`, `System`\");\n                link = LINK.d;\n            }\n        }\n        else\n        {\n            link = LINK.d; // default\n        }\n        check(TOK.rightParentheses);\n        *pidents = idents;\n        return link;\n    }\n\n    /***********************************\n     * Parse ident1.ident2.ident3\n     *\n     * Params:\n     *  entity = what qualified identifier is expected to resolve into.\n     *     Used only for better error message\n     *\n     * Returns:\n     *     array of identifiers with actual qualified one stored last\n     */\n    AST.Identifiers* parseQualifiedIdentifier(const(char)* entity)\n    {\n        AST.Identifiers* qualified = null;\n\n        do\n        {\n            nextToken();\n            if (token.value != TOK.identifier)\n            {\n                error(\"`%s` expected as dot-separated identifiers, got `%s`\", entity, token.toChars());\n                return null;\n            }\n\n            Identifier id = token.ident;\n            if (!qualified)\n                qualified = new AST.Identifiers();\n            qualified.push(id);\n\n            nextToken();\n        }\n        while (token.value == TOK.dot);\n\n        return qualified;\n    }\n\n    /**************************************\n     * Parse a debug conditional\n     */\n    AST.Condition parseDebugCondition()\n    {\n        uint level = 1;\n        Identifier id = null;\n\n        if (token.value == TOK.leftParentheses)\n        {\n            nextToken();\n\n            if (token.value == TOK.identifier)\n                id = token.ident;\n            else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)\n                level = cast(uint)token.unsvalue;\n            else\n                error(\"identifier or integer expected inside debug(...), not `%s`\", token.toChars());\n            nextToken();\n            check(TOK.rightParentheses);\n        }\n        return new AST.DebugCondition(mod, level, id);\n    }\n\n    /**************************************\n     * Parse a version conditional\n     */\n    AST.Condition parseVersionCondition()\n    {\n        uint level = 1;\n        Identifier id = null;\n\n        if (token.value == TOK.leftParentheses)\n        {\n            nextToken();\n            /* Allow:\n             *    version (unittest)\n             *    version (assert)\n             * even though they are keywords\n             */\n            if (token.value == TOK.identifier)\n                id = token.ident;\n            else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)\n                level = cast(uint)token.unsvalue;\n            else if (token.value == TOK.unittest_)\n                id = Identifier.idPool(Token.toString(TOK.unittest_));\n            else if (token.value == TOK.assert_)\n                id = Identifier.idPool(Token.toString(TOK.assert_));\n            else\n                error(\"identifier or integer expected inside version(...), not `%s`\", token.toChars());\n            nextToken();\n            check(TOK.rightParentheses);\n        }\n        else\n            error(\"(condition) expected following `version`\");\n        return new AST.VersionCondition(mod, level, id);\n    }\n\n    /***********************************************\n     *      static if (expression)\n     *          body\n     *      else\n     *          body\n     * Current token is 'static'.\n     */\n    AST.Condition parseStaticIfCondition()\n    {\n        AST.Expression exp;\n        AST.Condition condition;\n        const loc = token.loc;\n\n        nextToken();\n        nextToken();\n        if (token.value == TOK.leftParentheses)\n        {\n            nextToken();\n            exp = parseAssignExp();\n            check(TOK.rightParentheses);\n        }\n        else\n        {\n            error(\"(expression) expected following `static if`\");\n            exp = null;\n        }\n        condition = new AST.StaticIfCondition(loc, exp);\n        return condition;\n    }\n\n    /*****************************************\n     * Parse a constructor definition:\n     *      this(parameters) { body }\n     * or postblit:\n     *      this(this) { body }\n     * or constructor template:\n     *      this(templateparameters)(parameters) { body }\n     * Current token is 'this'.\n     */\n    AST.Dsymbol parseCtor(PrefixAttributes!AST* pAttrs)\n    {\n        AST.Expressions* udas = null;\n        const loc = token.loc;\n        StorageClass stc = getStorageClass!AST(pAttrs);\n\n        nextToken();\n        if (token.value == TOK.leftParentheses && peekNext() == TOK.this_ && peekNext2() == TOK.rightParentheses)\n        {\n            // this(this) { ... }\n            nextToken();\n            nextToken();\n            check(TOK.rightParentheses);\n\n            stc = parsePostfix(stc, &udas);\n            if (stc & AST.STC.immutable_)\n                deprecation(\"`immutable` postblit is deprecated. Please use an unqualified postblit.\");\n            if (stc & AST.STC.shared_)\n                deprecation(\"`shared` postblit is deprecated. Please use an unqualified postblit.\");\n            if (stc & AST.STC.const_)\n                deprecation(\"`const` postblit is deprecated. Please use an unqualified postblit.\");\n            if (stc & AST.STC.static_)\n                error(loc, \"postblit cannot be `static`\");\n\n            auto f = new AST.PostBlitDeclaration(loc, Loc.initial, stc, Id.postblit);\n            AST.Dsymbol s = parseContracts(f);\n            if (udas)\n            {\n                auto a = new AST.Dsymbols();\n                a.push(f);\n                s = new AST.UserAttributeDeclaration(udas, a);\n            }\n            return s;\n        }\n\n        /* Look ahead to see if:\n         *   this(...)(...)\n         * which is a constructor template\n         */\n        AST.TemplateParameters* tpl = null;\n        if (token.value == TOK.leftParentheses && peekPastParen(&token).value == TOK.leftParentheses)\n        {\n            tpl = parseTemplateParameterList();\n        }\n\n        /* Just a regular constructor\n         */\n        int varargs;\n        AST.Parameters* parameters = parseParameters(&varargs);\n        stc = parsePostfix(stc, &udas);\n        if (varargs != 0 || AST.Parameter.dim(parameters) != 0)\n        {\n            if (stc & AST.STC.static_)\n                error(loc, \"constructor cannot be static\");\n        }\n        else if (StorageClass ss = stc & (AST.STC.shared_ | AST.STC.static_)) // this()\n        {\n            if (ss == AST.STC.static_)\n                error(loc, \"use `static this()` to declare a static constructor\");\n            else if (ss == (AST.STC.shared_ | AST.STC.static_))\n                error(loc, \"use `shared static this()` to declare a shared static constructor\");\n        }\n\n        AST.Expression constraint = tpl ? parseConstraint() : null;\n\n        AST.Type tf = new AST.TypeFunction(parameters, null, varargs, linkage, stc); // RetrunType -> auto\n        tf = tf.addSTC(stc);\n\n        auto f = new AST.CtorDeclaration(loc, Loc.initial, stc, tf);\n        AST.Dsymbol s = parseContracts(f);\n        if (udas)\n        {\n            auto a = new AST.Dsymbols();\n            a.push(f);\n            s = new AST.UserAttributeDeclaration(udas, a);\n        }\n\n        if (tpl)\n        {\n            // Wrap a template around it\n            auto decldefs = new AST.Dsymbols();\n            decldefs.push(s);\n            s = new AST.TemplateDeclaration(loc, f.ident, tpl, constraint, decldefs);\n        }\n\n        return s;\n    }\n\n    /*****************************************\n     * Parse a destructor definition:\n     *      ~this() { body }\n     * Current token is '~'.\n     */\n    AST.Dsymbol parseDtor(PrefixAttributes!AST* pAttrs)\n    {\n        AST.Expressions* udas = null;\n        const loc = token.loc;\n        StorageClass stc = getStorageClass!AST(pAttrs);\n\n        nextToken();\n        check(TOK.this_);\n        check(TOK.leftParentheses);\n        check(TOK.rightParentheses);\n\n        stc = parsePostfix(stc, &udas);\n        if (StorageClass ss = stc & (AST.STC.shared_ | AST.STC.static_))\n        {\n            if (ss == AST.STC.static_)\n                error(loc, \"use `static ~this()` to declare a static destructor\");\n            else if (ss == (AST.STC.shared_ | AST.STC.static_))\n                error(loc, \"use `shared static ~this()` to declare a shared static destructor\");\n        }\n\n        auto f = new AST.DtorDeclaration(loc, Loc.initial, stc, Id.dtor);\n        AST.Dsymbol s = parseContracts(f);\n        if (udas)\n        {\n            auto a = new AST.Dsymbols();\n            a.push(f);\n            s = new AST.UserAttributeDeclaration(udas, a);\n        }\n        return s;\n    }\n\n    /*****************************************\n     * Parse a static constructor definition:\n     *      static this() { body }\n     * Current token is 'static'.\n     */\n    AST.Dsymbol parseStaticCtor(PrefixAttributes!AST* pAttrs)\n    {\n        //Expressions *udas = NULL;\n        const loc = token.loc;\n        StorageClass stc = getStorageClass!AST(pAttrs);\n\n        nextToken();\n        nextToken();\n        check(TOK.leftParentheses);\n        check(TOK.rightParentheses);\n\n        stc = parsePostfix(stc & ~AST.STC.TYPECTOR, null) | stc;\n        if (stc & AST.STC.shared_)\n            error(loc, \"use `shared static this()` to declare a shared static constructor\");\n        else if (stc & AST.STC.static_)\n            appendStorageClass(stc, AST.STC.static_); // complaint for the redundancy\n        else if (StorageClass modStc = stc & AST.STC.TYPECTOR)\n        {\n            OutBuffer buf;\n            AST.stcToBuffer(&buf, modStc);\n            error(loc, \"static constructor cannot be `%s`\", buf.peekString());\n        }\n        stc &= ~(AST.STC.static_ | AST.STC.TYPECTOR);\n\n        auto f = new AST.StaticCtorDeclaration(loc, Loc.initial, stc);\n        AST.Dsymbol s = parseContracts(f);\n        return s;\n    }\n\n    /*****************************************\n     * Parse a static destructor definition:\n     *      static ~this() { body }\n     * Current token is 'static'.\n     */\n    AST.Dsymbol parseStaticDtor(PrefixAttributes!AST* pAttrs)\n    {\n        AST.Expressions* udas = null;\n        const loc = token.loc;\n        StorageClass stc = getStorageClass!AST(pAttrs);\n\n        nextToken();\n        nextToken();\n        check(TOK.this_);\n        check(TOK.leftParentheses);\n        check(TOK.rightParentheses);\n\n        stc = parsePostfix(stc & ~AST.STC.TYPECTOR, &udas) | stc;\n        if (stc & AST.STC.shared_)\n            error(loc, \"use `shared static ~this()` to declare a shared static destructor\");\n        else if (stc & AST.STC.static_)\n            appendStorageClass(stc, AST.STC.static_); // complaint for the redundancy\n        else if (StorageClass modStc = stc & AST.STC.TYPECTOR)\n        {\n            OutBuffer buf;\n            AST.stcToBuffer(&buf, modStc);\n            error(loc, \"static destructor cannot be `%s`\", buf.peekString());\n        }\n        stc &= ~(AST.STC.static_ | AST.STC.TYPECTOR);\n\n        auto f = new AST.StaticDtorDeclaration(loc, Loc.initial, stc);\n        AST.Dsymbol s = parseContracts(f);\n        if (udas)\n        {\n            auto a = new AST.Dsymbols();\n            a.push(f);\n            s = new AST.UserAttributeDeclaration(udas, a);\n        }\n        return s;\n    }\n\n    /*****************************************\n     * Parse a shared static constructor definition:\n     *      shared static this() { body }\n     * Current token is 'shared'.\n     */\n    AST.Dsymbol parseSharedStaticCtor(PrefixAttributes!AST* pAttrs)\n    {\n        //Expressions *udas = NULL;\n        const loc = token.loc;\n        StorageClass stc = getStorageClass!AST(pAttrs);\n\n        nextToken();\n        nextToken();\n        nextToken();\n        check(TOK.leftParentheses);\n        check(TOK.rightParentheses);\n\n        stc = parsePostfix(stc & ~AST.STC.TYPECTOR, null) | stc;\n        if (StorageClass ss = stc & (AST.STC.shared_ | AST.STC.static_))\n            appendStorageClass(stc, ss); // complaint for the redundancy\n        else if (StorageClass modStc = stc & AST.STC.TYPECTOR)\n        {\n            OutBuffer buf;\n            AST.stcToBuffer(&buf, modStc);\n            error(loc, \"shared static constructor cannot be `%s`\", buf.peekString());\n        }\n        stc &= ~(AST.STC.static_ | AST.STC.TYPECTOR);\n\n        auto f = new AST.SharedStaticCtorDeclaration(loc, Loc.initial, stc);\n        AST.Dsymbol s = parseContracts(f);\n        return s;\n    }\n\n    /*****************************************\n     * Parse a shared static destructor definition:\n     *      shared static ~this() { body }\n     * Current token is 'shared'.\n     */\n    AST.Dsymbol parseSharedStaticDtor(PrefixAttributes!AST* pAttrs)\n    {\n        AST.Expressions* udas = null;\n        const loc = token.loc;\n        StorageClass stc = getStorageClass!AST(pAttrs);\n\n        nextToken();\n        nextToken();\n        nextToken();\n        check(TOK.this_);\n        check(TOK.leftParentheses);\n        check(TOK.rightParentheses);\n\n        stc = parsePostfix(stc & ~AST.STC.TYPECTOR, &udas) | stc;\n        if (StorageClass ss = stc & (AST.STC.shared_ | AST.STC.static_))\n            appendStorageClass(stc, ss); // complaint for the redundancy\n        else if (StorageClass modStc = stc & AST.STC.TYPECTOR)\n        {\n            OutBuffer buf;\n            AST.stcToBuffer(&buf, modStc);\n            error(loc, \"shared static destructor cannot be `%s`\", buf.peekString());\n        }\n        stc &= ~(AST.STC.static_ | AST.STC.TYPECTOR);\n\n        auto f = new AST.SharedStaticDtorDeclaration(loc, Loc.initial, stc);\n        AST.Dsymbol s = parseContracts(f);\n        if (udas)\n        {\n            auto a = new AST.Dsymbols();\n            a.push(f);\n            s = new AST.UserAttributeDeclaration(udas, a);\n        }\n        return s;\n    }\n\n    /*****************************************\n     * Parse an invariant definition:\n     *      invariant { statements... }\n     *      invariant() { statements... }\n     *      invariant (expression);\n     * Current token is 'invariant'.\n     */\n    AST.Dsymbol parseInvariant(PrefixAttributes!AST* pAttrs)\n    {\n        const loc = token.loc;\n        StorageClass stc = getStorageClass!AST(pAttrs);\n\n        nextToken();\n        if (token.value == TOK.leftParentheses) // optional () or invariant (expression);\n        {\n            nextToken();\n            if (token.value != TOK.rightParentheses) // invariant (expression);\n            {\n                AST.Expression e = parseAssignExp(), msg = null;\n                if (token.value == TOK.comma)\n                {\n                    nextToken();\n                    if (token.value != TOK.rightParentheses)\n                    {\n                        msg = parseAssignExp();\n                        if (token.value == TOK.comma)\n                            nextToken();\n                    }\n                }\n                check(TOK.rightParentheses);\n                check(TOK.semicolon);\n                e = new AST.AssertExp(loc, e, msg);\n                auto fbody = new AST.ExpStatement(loc, e);\n                auto f = new AST.InvariantDeclaration(loc, token.loc, stc, null, fbody);\n                return f;\n            }\n            else\n            {\n                nextToken();\n            }\n        }\n\n        auto fbody = parseStatement(ParseStatementFlags.curly);\n        auto f = new AST.InvariantDeclaration(loc, token.loc, stc, null, fbody);\n        return f;\n    }\n\n    /*****************************************\n     * Parse a unittest definition:\n     *      unittest { body }\n     * Current token is 'unittest'.\n     */\n    AST.Dsymbol parseUnitTest(PrefixAttributes!AST* pAttrs)\n    {\n        const loc = token.loc;\n        StorageClass stc = getStorageClass!AST(pAttrs);\n\n        nextToken();\n\n        const(char)* begPtr = token.ptr + 1; // skip '{'\n        const(char)* endPtr = null;\n        AST.Statement sbody = parseStatement(ParseStatementFlags.curly, &endPtr);\n\n        /** Extract unittest body as a string. Must be done eagerly since memory\n         will be released by the lexer before doc gen. */\n        char* docline = null;\n        if (global.params.doDocComments && endPtr > begPtr)\n        {\n            /* Remove trailing whitespaces */\n            for (const(char)* p = endPtr - 1; begPtr <= p && (*p == ' ' || *p == '\\r' || *p == '\\n' || *p == '\\t'); --p)\n            {\n                endPtr = p;\n            }\n\n            size_t len = endPtr - begPtr;\n            if (len > 0)\n            {\n                docline = cast(char*)mem.xmalloc(len + 2);\n                memcpy(docline, begPtr, len);\n                docline[len] = '\\n'; // Terminate all lines by LF\n                docline[len + 1] = '\\0';\n            }\n        }\n\n        auto f = new AST.UnitTestDeclaration(loc, token.loc, stc, docline);\n        f.fbody = sbody;\n        return f;\n    }\n\n    /*****************************************\n     * Parse a new definition:\n     *      new(parameters) { body }\n     * Current token is 'new'.\n     */\n    AST.Dsymbol parseNew(PrefixAttributes!AST* pAttrs)\n    {\n        const loc = token.loc;\n        StorageClass stc = getStorageClass!AST(pAttrs);\n\n        nextToken();\n\n        int varargs;\n        AST.Parameters* parameters = parseParameters(&varargs);\n        auto f = new AST.NewDeclaration(loc, Loc.initial, stc, parameters, varargs);\n        AST.Dsymbol s = parseContracts(f);\n        return s;\n    }\n\n    /*****************************************\n     * Parse a delete definition:\n     *      delete(parameters) { body }\n     * Current token is 'delete'.\n     */\n    AST.Dsymbol parseDelete(PrefixAttributes!AST* pAttrs)\n    {\n        const loc = token.loc;\n        StorageClass stc = getStorageClass!AST(pAttrs);\n\n        nextToken();\n\n        int varargs;\n        AST.Parameters* parameters = parseParameters(&varargs);\n        if (varargs)\n            error(\"`...` not allowed in delete function parameter list\");\n        auto f = new AST.DeleteDeclaration(loc, Loc.initial, stc, parameters);\n        AST.Dsymbol s = parseContracts(f);\n        return s;\n    }\n\n    /**********************************************\n     * Parse parameter list.\n     */\n    AST.Parameters* parseParameters(int* pvarargs, AST.TemplateParameters** tpl = null)\n    {\n        auto parameters = new AST.Parameters();\n        int varargs = 0;\n        int hasdefault = 0;\n\n        check(TOK.leftParentheses);\n        while (1)\n        {\n            Identifier ai = null;\n            AST.Type at;\n            StorageClass storageClass = 0;\n            StorageClass stc;\n            AST.Expression ae;\n            AST.Expressions* udas = null;\n            for (; 1; nextToken())\n            {\n            L3:\n                switch (token.value)\n                {\n                case TOK.rightParentheses:\n                    break;\n\n                case TOK.dotDotDot:\n                    varargs = 1;\n                    nextToken();\n                    break;\n\n                case TOK.const_:\n                    if (peek(&token).value == TOK.leftParentheses)\n                        goto default;\n                    stc = AST.STC.const_;\n                    goto L2;\n\n                case TOK.immutable_:\n                    if (peek(&token).value == TOK.leftParentheses)\n                        goto default;\n                    stc = AST.STC.immutable_;\n                    goto L2;\n\n                case TOK.shared_:\n                    if (peek(&token).value == TOK.leftParentheses)\n                        goto default;\n                    stc = AST.STC.shared_;\n                    goto L2;\n\n                case TOK.inout_:\n                    if (peek(&token).value == TOK.leftParentheses)\n                        goto default;\n                    stc = AST.STC.wild;\n                    goto L2;\n                case TOK.at:\n                    {\n                        AST.Expressions* exps = null;\n                        StorageClass stc2 = parseAttribute(&exps);\n                        if (stc2 == AST.STC.property || stc2 == AST.STC.nogc ||\n                            stc2 == AST.STC.disable || stc2 == AST.STC.safe ||\n                            stc2 == AST.STC.trusted || stc2 == AST.STC.system)\n                        {\n                            error(\"`@%s` attribute for function parameter is not supported\", token.toChars());\n                        }\n                        else\n                        {\n                            udas = AST.UserAttributeDeclaration.concat(udas, exps);\n                        }\n                        if (token.value == TOK.dotDotDot)\n                            error(\"variadic parameter cannot have user-defined attributes\");\n                        if (stc2)\n                            nextToken();\n                        goto L3;\n                        // Don't call nextToken again.\n                    }\n                case TOK.in_:\n                    stc = AST.STC.in_;\n                    goto L2;\n\n                case TOK.out_:\n                    stc = AST.STC.out_;\n                    goto L2;\n\n                case TOK.ref_:\n                    stc = AST.STC.ref_;\n                    goto L2;\n\n                case TOK.lazy_:\n                    stc = AST.STC.lazy_;\n                    goto L2;\n\n                case TOK.scope_:\n                    stc = AST.STC.scope_;\n                    goto L2;\n\n                case TOK.final_:\n                    stc = AST.STC.final_;\n                    goto L2;\n\n                case TOK.auto_:\n                    stc = AST.STC.auto_;\n                    goto L2;\n\n                case TOK.return_:\n                    stc = AST.STC.return_;\n                    goto L2;\n                L2:\n                    storageClass = appendStorageClass(storageClass, stc);\n                    continue;\n\n                    version (none)\n                    {\n                    case TOK.static_:\n                        stc = STC.static_;\n                        goto L2;\n\n                    case TOK.auto_:\n                        storageClass = STC.auto_;\n                        goto L4;\n\n                    case TOK.alias_:\n                        storageClass = STC.alias_;\n                        goto L4;\n                    L4:\n                        nextToken();\n                        if (token.value == TOK.identifier)\n                        {\n                            ai = token.ident;\n                            nextToken();\n                        }\n                        else\n                            ai = null;\n                        at = null; // no type\n                        ae = null; // no default argument\n                        if (token.value == TOK.assign) // = defaultArg\n                        {\n                            nextToken();\n                            ae = parseDefaultInitExp();\n                            hasdefault = 1;\n                        }\n                        else\n                        {\n                            if (hasdefault)\n                                error(\"default argument expected for `alias %s`\", ai ? ai.toChars() : \"\");\n                        }\n                        goto L3;\n                    }\n                default:\n                    {\n                        stc = storageClass & (AST.STC.in_ | AST.STC.out_ | AST.STC.ref_ | AST.STC.lazy_);\n                        // if stc is not a power of 2\n                        if (stc & (stc - 1) && !(stc == (AST.STC.in_ | AST.STC.ref_)))\n                            error(\"incompatible parameter storage classes\");\n                        //if ((storageClass & STC.scope_) && (storageClass & (STC.ref_ | STC.out_)))\n                            //error(\"scope cannot be ref or out\");\n\n                        if (tpl && token.value == TOK.identifier)\n                        {\n                            Token* t = peek(&token);\n                            if (t.value == TOK.comma || t.value == TOK.rightParentheses || t.value == TOK.dotDotDot)\n                            {\n                                Identifier id = Identifier.generateId(\"__T\");\n                                const loc = token.loc;\n                                at = new AST.TypeIdentifier(loc, id);\n                                if (!*tpl)\n                                    *tpl = new AST.TemplateParameters();\n                                AST.TemplateParameter tp = new AST.TemplateTypeParameter(loc, id, null, null);\n                                (*tpl).push(tp);\n\n                                ai = token.ident;\n                                nextToken();\n                            }\n                            else goto _else;\n                        }\n                        else\n                        {\n                        _else:\n                            at = parseType(&ai);\n                        }\n                        ae = null;\n                        if (token.value == TOK.assign) // = defaultArg\n                        {\n                            nextToken();\n                            ae = parseDefaultInitExp();\n                            hasdefault = 1;\n                        }\n                        else\n                        {\n                            if (hasdefault)\n                                error(\"default argument expected for `%s`\", ai ? ai.toChars() : at.toChars());\n                        }\n                        auto param = new AST.Parameter(storageClass, at, ai, ae, null);\n                        if (udas)\n                        {\n                            auto a = new AST.Dsymbols();\n                            auto udad = new AST.UserAttributeDeclaration(udas, a);\n                            param.userAttribDecl = udad;\n                        }\n                        if (token.value == TOK.at)\n                        {\n                            AST.Expressions* exps = null;\n                            StorageClass stc2 = parseAttribute(&exps);\n                            if (stc2 == AST.STC.property || stc2 == AST.STC.nogc ||\n                                stc2 == AST.STC.disable || stc2 == AST.STC.safe ||\n                                stc2 == AST.STC.trusted || stc2 == AST.STC.system)\n                            {\n                                error(\"`@%s` attribute for function parameter is not supported\", token.toChars());\n                            }\n                            else\n                            {\n                                error(\"user-defined attributes cannot appear as postfixes\", token.toChars());\n                            }\n                            if (stc2)\n                                nextToken();\n                        }\n                        if (token.value == TOK.dotDotDot)\n                        {\n                            /* This is:\n                             *      at ai ...\n                             */\n                            if (storageClass & (AST.STC.out_ | AST.STC.ref_))\n                                error(\"variadic argument cannot be `out` or `ref`\");\n                            varargs = 2;\n                            parameters.push(param);\n                            nextToken();\n                            break;\n                        }\n                        parameters.push(param);\n                        if (token.value == TOK.comma)\n                        {\n                            nextToken();\n                            goto L1;\n                        }\n                        break;\n                    }\n                }\n                break;\n            }\n            break;\n\n        L1:\n        }\n        check(TOK.rightParentheses);\n        *pvarargs = varargs;\n        return parameters;\n    }\n\n    /*************************************\n     */\n    AST.EnumDeclaration parseEnum()\n    {\n        AST.EnumDeclaration e;\n        Identifier id;\n        AST.Type memtype;\n        auto loc = token.loc;\n\n        // printf(\"Parser::parseEnum()\\n\");\n        nextToken();\n        if (token.value == TOK.identifier)\n        {\n            id = token.ident;\n            nextToken();\n        }\n        else\n            id = null;\n\n        if (token.value == TOK.colon)\n        {\n            nextToken();\n            int alt = 0;\n            const typeLoc = token.loc;\n            memtype = parseBasicType();\n            memtype = parseDeclarator(memtype, &alt, null);\n            checkCstyleTypeSyntax(typeLoc, memtype, alt, null);\n        }\n        else\n            memtype = null;\n\n        e = new AST.EnumDeclaration(loc, id, memtype);\n        if (token.value == TOK.semicolon && id)\n            nextToken();\n        else if (token.value == TOK.leftCurly)\n        {\n            bool isAnonymousEnum = !id;\n\n            //printf(\"enum definition\\n\");\n            e.members = new AST.Dsymbols();\n            nextToken();\n            const(char)* comment = token.blockComment;\n            while (token.value != TOK.rightCurly)\n            {\n                /* Can take the following forms...\n                 *  1. ident\n                 *  2. ident = value\n                 *  3. type ident = value\n                 *  ... prefixed by valid attributes\n                 */\n                loc = token.loc;\n\n                AST.Type type = null;\n                Identifier ident = null;\n\n                AST.Expressions* udas;\n                StorageClass stc;\n                AST.Expression deprecationMessage;\n                enum attributeErrorMessage = \"`%s` is not a valid attribute for enum members\";\n                while(token.value != TOK.rightCurly\n                    && token.value != TOK.comma\n                    && token.value != TOK.assign)\n                {\n                    switch(token.value)\n                    {\n                        case TOK.at:\n                            if (StorageClass _stc = parseAttribute(&udas))\n                            {\n                                if (_stc == AST.STC.disable)\n                                    stc |= _stc;\n                                else\n                                {\n                                    OutBuffer buf;\n                                    AST.stcToBuffer(&buf, _stc);\n                                    error(attributeErrorMessage, buf.peekString());\n                                }\n                                nextToken();\n                            }\n                            break;\n                        case TOK.deprecated_:\n                            if (StorageClass _stc = parseDeprecatedAttribute(deprecationMessage))\n                            {\n                                stc |= _stc;\n                                nextToken();\n                            }\n                            break;\n                        case TOK.identifier:\n                            Token* tp = peek(&token);\n                            if (tp.value == TOK.assign || tp.value == TOK.comma || tp.value == TOK.rightCurly)\n                            {\n                                ident = token.ident;\n                                type = null;\n                                nextToken();\n                            }\n                            else\n                            {\n                                goto default;\n                            }\n                            break;\n                        default:\n                            if (isAnonymousEnum)\n                            {\n                                type = parseType(&ident, null);\n                                if (type == AST.Type.terror)\n                                {\n                                    type = null;\n                                    nextToken();\n                                }\n                            }\n                            else\n                            {\n                                error(attributeErrorMessage, token.toChars());\n                                nextToken();\n                            }\n                            break;\n                    }\n                }\n\n                if (type && type != AST.Type.terror)\n                {\n                    if (!ident)\n                        error(\"no identifier for declarator `%s`\", type.toChars());\n                    if (!isAnonymousEnum)\n                        error(\"type only allowed if anonymous enum and no enum type\");\n                }\n\n                AST.Expression value;\n                if (token.value == TOK.assign)\n                {\n                    nextToken();\n                    value = parseAssignExp();\n                }\n                else\n                {\n                    value = null;\n                    if (type && type != AST.Type.terror && isAnonymousEnum)\n                        error(\"if type, there must be an initializer\");\n                }\n\n                AST.UserAttributeDeclaration uad;\n                if (udas)\n                    uad = new AST.UserAttributeDeclaration(udas, null);\n\n                AST.DeprecatedDeclaration dd;\n                if (deprecationMessage)\n                {\n                    dd = new AST.DeprecatedDeclaration(deprecationMessage, null);\n                    stc |= AST.STC.deprecated_;\n                }\n\n                auto em = new AST.EnumMember(loc, ident, value, type, stc, uad, dd);\n                e.members.push(em);\n\n                if (token.value == TOK.rightCurly)\n                {\n                }\n                else\n                {\n                    addComment(em, comment);\n                    comment = null;\n                    check(TOK.comma);\n                }\n                addComment(em, comment);\n                comment = token.blockComment;\n\n                if (token.value == TOK.endOfFile)\n                {\n                    error(\"premature end of file\");\n                    break;\n                }\n            }\n            nextToken();\n        }\n        else\n            error(\"enum declaration is invalid\");\n\n        //printf(\"-parseEnum() %s\\n\", e.toChars());\n        return e;\n    }\n\n    /********************************\n     * Parse struct, union, interface, class.\n     */\n    AST.Dsymbol parseAggregate()\n    {\n        AST.TemplateParameters* tpl = null;\n        AST.Expression constraint;\n        const loc = token.loc;\n        TOK tok = token.value;\n\n        //printf(\"Parser::parseAggregate()\\n\");\n        nextToken();\n        Identifier id;\n        if (token.value != TOK.identifier)\n        {\n            id = null;\n        }\n        else\n        {\n            id = token.ident;\n            nextToken();\n\n            if (token.value == TOK.leftParentheses)\n            {\n                // struct/class template declaration.\n                tpl = parseTemplateParameterList();\n                constraint = parseConstraint();\n            }\n        }\n\n        // Collect base class(es)\n        AST.BaseClasses* baseclasses = null;\n        if (token.value == TOK.colon)\n        {\n            if (tok != TOK.interface_ && tok != TOK.class_)\n                error(\"base classes are not allowed for `%s`, did you mean `;`?\", Token.toChars(tok));\n            nextToken();\n            baseclasses = parseBaseClasses();\n        }\n\n        if (token.value == TOK.if_)\n        {\n            if (constraint)\n                error(\"template constraints appear both before and after BaseClassList, put them before\");\n            constraint = parseConstraint();\n        }\n        if (constraint)\n        {\n            if (!id)\n                error(\"template constraints not allowed for anonymous `%s`\", Token.toChars(tok));\n            if (!tpl)\n                error(\"template constraints only allowed for templates\");\n        }\n\n        AST.Dsymbols* members = null;\n        if (token.value == TOK.leftCurly)\n        {\n            //printf(\"aggregate definition\\n\");\n            const lookingForElseSave = lookingForElse;\n            lookingForElse = Loc();\n            nextToken();\n            members = parseDeclDefs(0);\n            lookingForElse = lookingForElseSave;\n            if (token.value != TOK.rightCurly)\n            {\n                /* { */\n                error(\"`}` expected following members in `%s` declaration at %s\",\n                    Token.toChars(tok), loc.toChars());\n            }\n            nextToken();\n        }\n        else if (token.value == TOK.semicolon && id)\n        {\n            if (baseclasses || constraint)\n                error(\"members expected\");\n            nextToken();\n        }\n        else\n        {\n            error(\"{ } expected following `%s` declaration\", Token.toChars(tok));\n        }\n\n        AST.AggregateDeclaration a;\n        switch (tok)\n        {\n        case TOK.interface_:\n            if (!id)\n                error(loc, \"anonymous interfaces not allowed\");\n            a = new AST.InterfaceDeclaration(loc, id, baseclasses);\n            a.members = members;\n            break;\n\n        case TOK.class_:\n            if (!id)\n                error(loc, \"anonymous classes not allowed\");\n            bool inObject = md && !md.packages && md.id == Id.object;\n            a = new AST.ClassDeclaration(loc, id, baseclasses, members, inObject);\n            break;\n\n        case TOK.struct_:\n            if (id)\n            {\n                bool inObject = md && !md.packages && md.id == Id.object;\n                a = new AST.StructDeclaration(loc, id, inObject);\n                a.members = members;\n            }\n            else\n            {\n                /* Anonymous structs/unions are more like attributes.\n                 */\n                assert(!tpl);\n                return new AST.AnonDeclaration(loc, false, members);\n            }\n            break;\n\n        case TOK.union_:\n            if (id)\n            {\n                a = new AST.UnionDeclaration(loc, id);\n                a.members = members;\n            }\n            else\n            {\n                /* Anonymous structs/unions are more like attributes.\n                 */\n                assert(!tpl);\n                return new AST.AnonDeclaration(loc, true, members);\n            }\n            break;\n\n        default:\n            assert(0);\n        }\n\n        if (tpl)\n        {\n            // Wrap a template around the aggregate declaration\n            auto decldefs = new AST.Dsymbols();\n            decldefs.push(a);\n            auto tempdecl = new AST.TemplateDeclaration(loc, id, tpl, constraint, decldefs);\n            return tempdecl;\n        }\n        return a;\n    }\n\n    /*******************************************\n     */\n    AST.BaseClasses* parseBaseClasses()\n    {\n        auto baseclasses = new AST.BaseClasses();\n\n        for (; 1; nextToken())\n        {\n            auto b = new AST.BaseClass(parseBasicType());\n            baseclasses.push(b);\n            if (token.value != TOK.comma)\n                break;\n        }\n        return baseclasses;\n    }\n\n    AST.Dsymbols* parseImport()\n    {\n        auto decldefs = new AST.Dsymbols();\n        Identifier aliasid = null;\n\n        int isstatic = token.value == TOK.static_;\n        if (isstatic)\n            nextToken();\n\n        //printf(\"Parser::parseImport()\\n\");\n        do\n        {\n        L1:\n            nextToken();\n            if (token.value != TOK.identifier)\n            {\n                error(\"identifier expected following `import`\");\n                break;\n            }\n\n            const loc = token.loc;\n            Identifier id = token.ident;\n            AST.Identifiers* a = null;\n            nextToken();\n            if (!aliasid && token.value == TOK.assign)\n            {\n                aliasid = id;\n                goto L1;\n            }\n            while (token.value == TOK.dot)\n            {\n                if (!a)\n                    a = new AST.Identifiers();\n                a.push(id);\n                nextToken();\n                if (token.value != TOK.identifier)\n                {\n                    error(\"identifier expected following `package`\");\n                    break;\n                }\n                id = token.ident;\n                nextToken();\n            }\n\n            auto s = new AST.Import(loc, a, id, aliasid, isstatic);\n            decldefs.push(s);\n\n            /* Look for\n             *      : alias=name, alias=name;\n             * syntax.\n             */\n            if (token.value == TOK.colon)\n            {\n                do\n                {\n                    nextToken();\n                    if (token.value != TOK.identifier)\n                    {\n                        error(\"identifier expected following `:`\");\n                        break;\n                    }\n                    Identifier _alias = token.ident;\n                    Identifier name;\n                    nextToken();\n                    if (token.value == TOK.assign)\n                    {\n                        nextToken();\n                        if (token.value != TOK.identifier)\n                        {\n                            error(\"identifier expected following `%s=`\", _alias.toChars());\n                            break;\n                        }\n                        name = token.ident;\n                        nextToken();\n                    }\n                    else\n                    {\n                        name = _alias;\n                        _alias = null;\n                    }\n                    s.addAlias(name, _alias);\n                }\n                while (token.value == TOK.comma);\n                break; // no comma-separated imports of this form\n            }\n            aliasid = null;\n        }\n        while (token.value == TOK.comma);\n\n        if (token.value == TOK.semicolon)\n            nextToken();\n        else\n        {\n            error(\"`;` expected\");\n            nextToken();\n        }\n\n        return decldefs;\n    }\n\n    AST.Type parseType(Identifier* pident = null, AST.TemplateParameters** ptpl = null)\n    {\n        /* Take care of the storage class prefixes that\n         * serve as type attributes:\n         *               const type\n         *           immutable type\n         *              shared type\n         *               inout type\n         *         inout const type\n         *        shared const type\n         *        shared inout type\n         *  shared inout const type\n         */\n        StorageClass stc = 0;\n        while (1)\n        {\n            switch (token.value)\n            {\n            case TOK.const_:\n                if (peekNext() == TOK.leftParentheses)\n                    break; // const as type constructor\n                stc |= AST.STC.const_; // const as storage class\n                nextToken();\n                continue;\n\n            case TOK.immutable_:\n                if (peekNext() == TOK.leftParentheses)\n                    break;\n                stc |= AST.STC.immutable_;\n                nextToken();\n                continue;\n\n            case TOK.shared_:\n                if (peekNext() == TOK.leftParentheses)\n                    break;\n                stc |= AST.STC.shared_;\n                nextToken();\n                continue;\n\n            case TOK.inout_:\n                if (peekNext() == TOK.leftParentheses)\n                    break;\n                stc |= AST.STC.wild;\n                nextToken();\n                continue;\n\n            default:\n                break;\n            }\n            break;\n        }\n\n        const typeLoc = token.loc;\n\n        AST.Type t;\n        t = parseBasicType();\n\n        int alt = 0;\n        t = parseDeclarator(t, &alt, pident, ptpl);\n        checkCstyleTypeSyntax(typeLoc, t, alt, pident ? *pident : null);\n\n        t = t.addSTC(stc);\n        return t;\n    }\n\n    AST.Type parseBasicType(bool dontLookDotIdents = false)\n    {\n        AST.Type t;\n        Loc loc;\n        Identifier id;\n        //printf(\"parseBasicType()\\n\");\n        switch (token.value)\n        {\n        case TOK.void_:\n            t = AST.Type.tvoid;\n            goto LabelX;\n\n        case TOK.int8:\n            t = AST.Type.tint8;\n            goto LabelX;\n\n        case TOK.uns8:\n            t = AST.Type.tuns8;\n            goto LabelX;\n\n        case TOK.int16:\n            t = AST.Type.tint16;\n            goto LabelX;\n\n        case TOK.uns16:\n            t = AST.Type.tuns16;\n            goto LabelX;\n\n        case TOK.int32:\n            t = AST.Type.tint32;\n            goto LabelX;\n\n        case TOK.uns32:\n            t = AST.Type.tuns32;\n            goto LabelX;\n\n        case TOK.int64:\n            t = AST.Type.tint64;\n            nextToken();\n            if (token.value == TOK.int64)   // if `long long`\n            {\n                error(\"use `long` for a 64 bit integer instead of `long long`\");\n                nextToken();\n            }\n            else if (token.value == TOK.float64)   // if `long double`\n            {\n                error(\"use `real` instead of `long double`\");\n                t = AST.Type.tfloat80;\n                nextToken();\n            }\n            break;\n\n        case TOK.uns64:\n            t = AST.Type.tuns64;\n            goto LabelX;\n\n        case TOK.int128:\n            t = AST.Type.tint128;\n            goto LabelX;\n\n        case TOK.uns128:\n            t = AST.Type.tuns128;\n            goto LabelX;\n\n        case TOK.float32:\n            t = AST.Type.tfloat32;\n            goto LabelX;\n\n        case TOK.float64:\n            t = AST.Type.tfloat64;\n            goto LabelX;\n\n        case TOK.float80:\n            t = AST.Type.tfloat80;\n            goto LabelX;\n\n        case TOK.imaginary32:\n            t = AST.Type.timaginary32;\n            goto LabelX;\n\n        case TOK.imaginary64:\n            t = AST.Type.timaginary64;\n            goto LabelX;\n\n        case TOK.imaginary80:\n            t = AST.Type.timaginary80;\n            goto LabelX;\n\n        case TOK.complex32:\n            t = AST.Type.tcomplex32;\n            goto LabelX;\n\n        case TOK.complex64:\n            t = AST.Type.tcomplex64;\n            goto LabelX;\n\n        case TOK.complex80:\n            t = AST.Type.tcomplex80;\n            goto LabelX;\n\n        case TOK.bool_:\n            t = AST.Type.tbool;\n            goto LabelX;\n\n        case TOK.char_:\n            t = AST.Type.tchar;\n            goto LabelX;\n\n        case TOK.wchar_:\n            t = AST.Type.twchar;\n            goto LabelX;\n\n        case TOK.dchar_:\n            t = AST.Type.tdchar;\n            goto LabelX;\n        LabelX:\n            nextToken();\n            break;\n\n        case TOK.this_:\n        case TOK.super_:\n        case TOK.identifier:\n            loc = token.loc;\n            id = token.ident;\n            nextToken();\n            if (token.value == TOK.not)\n            {\n                // ident!(template_arguments)\n                auto tempinst = new AST.TemplateInstance(loc, id, parseTemplateArguments());\n                t = parseBasicTypeStartingAt(new AST.TypeInstance(loc, tempinst), dontLookDotIdents);\n            }\n            else\n            {\n                t = parseBasicTypeStartingAt(new AST.TypeIdentifier(loc, id), dontLookDotIdents);\n            }\n            break;\n\n        case TOK.dot:\n            // Leading . as in .foo\n            t = parseBasicTypeStartingAt(new AST.TypeIdentifier(token.loc, Id.empty), dontLookDotIdents);\n            break;\n\n        case TOK.typeof_:\n            // typeof(expression)\n            t = parseBasicTypeStartingAt(parseTypeof(), dontLookDotIdents);\n            break;\n\n        case TOK.vector:\n            t = parseVector();\n            break;\n\n        case TOK.const_:\n            // const(type)\n            nextToken();\n            check(TOK.leftParentheses);\n            t = parseType().addSTC(AST.STC.const_);\n            check(TOK.rightParentheses);\n            break;\n\n        case TOK.immutable_:\n            // immutable(type)\n            nextToken();\n            check(TOK.leftParentheses);\n            t = parseType().addSTC(AST.STC.immutable_);\n            check(TOK.rightParentheses);\n            break;\n\n        case TOK.shared_:\n            // shared(type)\n            nextToken();\n            check(TOK.leftParentheses);\n            t = parseType().addSTC(AST.STC.shared_);\n            check(TOK.rightParentheses);\n            break;\n\n        case TOK.inout_:\n            // wild(type)\n            nextToken();\n            check(TOK.leftParentheses);\n            t = parseType().addSTC(AST.STC.wild);\n            check(TOK.rightParentheses);\n            break;\n\n        default:\n            error(\"basic type expected, not `%s`\", token.toChars());\n            if (token.value == TOK.else_)\n                errorSupplemental(token.loc, \"There's no `static else`, use `else` instead.\");\n            t = AST.Type.terror;\n            break;\n        }\n        return t;\n    }\n\n    AST.Type parseBasicTypeStartingAt(AST.TypeQualified tid, bool dontLookDotIdents)\n    {\n        AST.Type maybeArray = null;\n        // See https://issues.dlang.org/show_bug.cgi?id=1215\n        // A basic type can look like MyType (typical case), but also:\n        //  MyType.T -> A type\n        //  MyType[expr] -> Either a static array of MyType or a type (iif MyType is a Ttuple)\n        //  MyType[expr].T -> A type.\n        //  MyType[expr].T[expr] ->  Either a static array of MyType[expr].T or a type\n        //                           (iif MyType[expr].T is a Ttuple)\n        while (1)\n        {\n            switch (token.value)\n            {\n            case TOK.dot:\n                {\n                    nextToken();\n                    if (token.value != TOK.identifier)\n                    {\n                        error(\"identifier expected following `.` instead of `%s`\", token.toChars());\n                        break;\n                    }\n                    if (maybeArray)\n                    {\n                        // This is actually a TypeTuple index, not an {a/s}array.\n                        // We need to have a while loop to unwind all index taking:\n                        // T[e1][e2].U   ->  T, addIndex(e1), addIndex(e2)\n                        AST.Objects dimStack;\n                        AST.Type t = maybeArray;\n                        while (true)\n                        {\n                            if (t.ty == AST.Tsarray)\n                            {\n                                // The index expression is an Expression.\n                                AST.TypeSArray a = cast(AST.TypeSArray)t;\n                                dimStack.push(a.dim.syntaxCopy());\n                                t = a.next.syntaxCopy();\n                            }\n                            else if (t.ty == AST.Taarray)\n                            {\n                                // The index expression is a Type. It will be interpreted as an expression at semantic time.\n                                AST.TypeAArray a = cast(AST.TypeAArray)t;\n                                dimStack.push(a.index.syntaxCopy());\n                                t = a.next.syntaxCopy();\n                            }\n                            else\n                            {\n                                break;\n                            }\n                        }\n                        assert(dimStack.dim > 0);\n                        // We're good. Replay indices in the reverse order.\n                        tid = cast(AST.TypeQualified)t;\n                        while (dimStack.dim)\n                        {\n                            tid.addIndex(dimStack.pop());\n                        }\n                        maybeArray = null;\n                    }\n                    const loc = token.loc;\n                    Identifier id = token.ident;\n                    nextToken();\n                    if (token.value == TOK.not)\n                    {\n                        auto tempinst = new AST.TemplateInstance(loc, id, parseTemplateArguments());\n                        tid.addInst(tempinst);\n                    }\n                    else\n                        tid.addIdent(id);\n                    continue;\n                }\n            case TOK.leftBracket:\n                {\n                    if (dontLookDotIdents) // workaround for https://issues.dlang.org/show_bug.cgi?id=14911\n                        goto Lend;\n\n                    nextToken();\n                    AST.Type t = maybeArray ? maybeArray : cast(AST.Type)tid;\n                    if (token.value == TOK.rightBracket)\n                    {\n                        // It's a dynamic array, and we're done:\n                        // T[].U does not make sense.\n                        t = new AST.TypeDArray(t);\n                        nextToken();\n                        return t;\n                    }\n                    else if (isDeclaration(&token, NeedDeclaratorId.no, TOK.rightBracket, null))\n                    {\n                        // This can be one of two things:\n                        //  1 - an associative array declaration, T[type]\n                        //  2 - an associative array declaration, T[expr]\n                        // These  can only be disambiguated later.\n                        AST.Type index = parseType(); // [ type ]\n                        maybeArray = new AST.TypeAArray(t, index);\n                        check(TOK.rightBracket);\n                    }\n                    else\n                    {\n                        // This can be one of three things:\n                        //  1 - an static array declaration, T[expr]\n                        //  2 - a slice, T[expr .. expr]\n                        //  3 - a template parameter pack index expression, T[expr].U\n                        // 1 and 3 can only be disambiguated later.\n                        //printf(\"it's type[expression]\\n\");\n                        inBrackets++;\n                        AST.Expression e = parseAssignExp(); // [ expression ]\n                        if (token.value == TOK.slice)\n                        {\n                            // It's a slice, and we're done.\n                            nextToken();\n                            AST.Expression e2 = parseAssignExp(); // [ exp .. exp ]\n                            t = new AST.TypeSlice(t, e, e2);\n                            inBrackets--;\n                            check(TOK.rightBracket);\n                            return t;\n                        }\n                        else\n                        {\n                            maybeArray = new AST.TypeSArray(t, e);\n                            inBrackets--;\n                            check(TOK.rightBracket);\n                            continue;\n                        }\n                    }\n                    break;\n                }\n            default:\n                goto Lend;\n            }\n        }\n    Lend:\n        return maybeArray ? maybeArray : cast(AST.Type)tid;\n    }\n\n    /******************************************\n     * Parse things that follow the initial type t.\n     *      t *\n     *      t []\n     *      t [type]\n     *      t [expression]\n     *      t [expression .. expression]\n     *      t function\n     *      t delegate\n     */\n    AST.Type parseBasicType2(AST.Type t)\n    {\n        //printf(\"parseBasicType2()\\n\");\n        while (1)\n        {\n            switch (token.value)\n            {\n            case TOK.mul:\n                t = new AST.TypePointer(t);\n                nextToken();\n                continue;\n\n            case TOK.leftBracket:\n                // Handle []. Make sure things like\n                //     int[3][1] a;\n                // is (array[1] of array[3] of int)\n                nextToken();\n                if (token.value == TOK.rightBracket)\n                {\n                    t = new AST.TypeDArray(t); // []\n                    nextToken();\n                }\n                else if (isDeclaration(&token, NeedDeclaratorId.no, TOK.rightBracket, null))\n                {\n                    // It's an associative array declaration\n                    //printf(\"it's an associative array\\n\");\n                    AST.Type index = parseType(); // [ type ]\n                    t = new AST.TypeAArray(t, index);\n                    check(TOK.rightBracket);\n                }\n                else\n                {\n                    //printf(\"it's type[expression]\\n\");\n                    inBrackets++;\n                    AST.Expression e = parseAssignExp(); // [ expression ]\n                    if (token.value == TOK.slice)\n                    {\n                        nextToken();\n                        AST.Expression e2 = parseAssignExp(); // [ exp .. exp ]\n                        t = new AST.TypeSlice(t, e, e2);\n                    }\n                    else\n                    {\n                        t = new AST.TypeSArray(t, e);\n                    }\n                    inBrackets--;\n                    check(TOK.rightBracket);\n                }\n                continue;\n\n            case TOK.delegate_:\n            case TOK.function_:\n                {\n                    // Handle delegate declaration:\n                    //      t delegate(parameter list) nothrow pure\n                    //      t function(parameter list) nothrow pure\n                    TOK save = token.value;\n                    nextToken();\n\n                    int varargs;\n                    AST.Parameters* parameters = parseParameters(&varargs);\n\n                    StorageClass stc = parsePostfix(AST.STC.undefined_, null);\n                    auto tf = new AST.TypeFunction(parameters, t, varargs, linkage, stc);\n                    if (stc & (AST.STC.const_ | AST.STC.immutable_ | AST.STC.shared_ | AST.STC.wild | AST.STC.return_))\n                    {\n                        if (save == TOK.function_)\n                            error(\"`const`/`immutable`/`shared`/`inout`/`return` attributes are only valid for non-static member functions\");\n                        else\n                            tf = cast(AST.TypeFunction)tf.addSTC(stc);\n                    }\n\n                    if (save == TOK.delegate_)\n                        t = new AST.TypeDelegate(tf);\n                    else\n                        t = new AST.TypePointer(tf); // pointer to function\n                    continue;\n                }\n            default:\n                return t;\n            }\n            assert(0);\n        }\n        assert(0);\n    }\n\n    AST.Type parseDeclarator(AST.Type t, int* palt, Identifier* pident, AST.TemplateParameters** tpl = null, StorageClass storageClass = 0, int* pdisable = null, AST.Expressions** pudas = null)\n    {\n        //printf(\"parseDeclarator(tpl = %p)\\n\", tpl);\n        t = parseBasicType2(t);\n        AST.Type ts;\n        switch (token.value)\n        {\n        case TOK.identifier:\n            if (pident)\n                *pident = token.ident;\n            else\n                error(\"unexpected identifier `%s` in declarator\", token.ident.toChars());\n            ts = t;\n            nextToken();\n            break;\n\n        case TOK.leftParentheses:\n            {\n                // like: T (*fp)();\n                // like: T ((*fp))();\n                if (peekNext() == TOK.mul || peekNext() == TOK.leftParentheses)\n                {\n                    /* Parse things with parentheses around the identifier, like:\n                     *  int (*ident[3])[]\n                     * although the D style would be:\n                     *  int[]*[3] ident\n                     */\n                    *palt |= 1;\n                    nextToken();\n                    ts = parseDeclarator(t, palt, pident);\n                    check(TOK.rightParentheses);\n                    break;\n                }\n                ts = t;\n\n                Token* peekt = &token;\n                /* Completely disallow C-style things like:\n                 *   T (a);\n                 * Improve error messages for the common bug of a missing return type\n                 * by looking to see if (a) looks like a parameter list.\n                 */\n                if (isParameters(&peekt))\n                {\n                    error(\"function declaration without return type. (Note that constructors are always named `this`)\");\n                }\n                else\n                    error(\"unexpected `(` in declarator\");\n                break;\n            }\n        default:\n            ts = t;\n            break;\n        }\n\n        // parse DeclaratorSuffixes\n        while (1)\n        {\n            switch (token.value)\n            {\n                static if (CARRAYDECL)\n                {\n                    /* Support C style array syntax:\n                     *   int ident[]\n                     * as opposed to D-style:\n                     *   int[] ident\n                     */\n                case TOK.leftBracket:\n                    {\n                        // This is the old C-style post [] syntax.\n                        AST.TypeNext ta;\n                        nextToken();\n                        if (token.value == TOK.rightBracket)\n                        {\n                            // It's a dynamic array\n                            ta = new AST.TypeDArray(t); // []\n                            nextToken();\n                            *palt |= 2;\n                        }\n                        else if (isDeclaration(&token, NeedDeclaratorId.no, TOK.rightBracket, null))\n                        {\n                            // It's an associative array\n                            //printf(\"it's an associative array\\n\");\n                            AST.Type index = parseType(); // [ type ]\n                            check(TOK.rightBracket);\n                            ta = new AST.TypeAArray(t, index);\n                            *palt |= 2;\n                        }\n                        else\n                        {\n                            //printf(\"It's a static array\\n\");\n                            AST.Expression e = parseAssignExp(); // [ expression ]\n                            ta = new AST.TypeSArray(t, e);\n                            check(TOK.rightBracket);\n                            *palt |= 2;\n                        }\n\n                        /* Insert ta into\n                         *   ts -> ... -> t\n                         * so that\n                         *   ts -> ... -> ta -> t\n                         */\n                        AST.Type* pt;\n                        for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next)\n                        {\n                        }\n                        *pt = ta;\n                        continue;\n                    }\n                }\n            case TOK.leftParentheses:\n                {\n                    if (tpl)\n                    {\n                        Token* tk = peekPastParen(&token);\n                        if (tk.value == TOK.leftParentheses)\n                        {\n                            /* Look ahead to see if this is (...)(...),\n                             * i.e. a function template declaration\n                             */\n                            //printf(\"function template declaration\\n\");\n\n                            // Gather template parameter list\n                            *tpl = parseTemplateParameterList();\n                        }\n                        else if (tk.value == TOK.assign)\n                        {\n                            /* or (...) =,\n                             * i.e. a variable template declaration\n                             */\n                            //printf(\"variable template declaration\\n\");\n                            *tpl = parseTemplateParameterList();\n                            break;\n                        }\n                    }\n\n                    int varargs;\n                    AST.Parameters* parameters = parseParameters(&varargs);\n\n                    /* Parse const/immutable/shared/inout/nothrow/pure/return postfix\n                     */\n                    // merge prefix storage classes\n                    StorageClass stc = parsePostfix(storageClass, pudas);\n\n                    AST.Type tf = new AST.TypeFunction(parameters, t, varargs, linkage, stc);\n                    tf = tf.addSTC(stc);\n                    if (pdisable)\n                        *pdisable = stc & AST.STC.disable ? 1 : 0;\n\n                    /* Insert tf into\n                     *   ts -> ... -> t\n                     * so that\n                     *   ts -> ... -> tf -> t\n                     */\n                    AST.Type* pt;\n                    for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next)\n                    {\n                    }\n                    *pt = tf;\n                    break;\n                }\n            default:\n                break;\n            }\n            break;\n        }\n        return ts;\n    }\n\n    void parseStorageClasses(ref StorageClass storage_class, ref LINK link,\n        ref bool setAlignment, ref AST.Expression ealign, ref AST.Expressions* udas)\n    {\n        StorageClass stc;\n        bool sawLinkage = false; // seen a linkage declaration\n\n        while (1)\n        {\n            switch (token.value)\n            {\n            case TOK.const_:\n                if (peek(&token).value == TOK.leftParentheses)\n                    break; // const as type constructor\n                stc = AST.STC.const_; // const as storage class\n                goto L1;\n\n            case TOK.immutable_:\n                if (peek(&token).value == TOK.leftParentheses)\n                    break;\n                stc = AST.STC.immutable_;\n                goto L1;\n\n            case TOK.shared_:\n                if (peek(&token).value == TOK.leftParentheses)\n                    break;\n                stc = AST.STC.shared_;\n                goto L1;\n\n            case TOK.inout_:\n                if (peek(&token).value == TOK.leftParentheses)\n                    break;\n                stc = AST.STC.wild;\n                goto L1;\n\n            case TOK.static_:\n                stc = AST.STC.static_;\n                goto L1;\n\n            case TOK.final_:\n                stc = AST.STC.final_;\n                goto L1;\n\n            case TOK.auto_:\n                stc = AST.STC.auto_;\n                goto L1;\n\n            case TOK.scope_:\n                stc = AST.STC.scope_;\n                goto L1;\n\n            case TOK.override_:\n                stc = AST.STC.override_;\n                goto L1;\n\n            case TOK.abstract_:\n                stc = AST.STC.abstract_;\n                goto L1;\n\n            case TOK.synchronized_:\n                stc = AST.STC.synchronized_;\n                goto L1;\n\n            case TOK.deprecated_:\n                stc = AST.STC.deprecated_;\n                goto L1;\n\n            case TOK.nothrow_:\n                stc = AST.STC.nothrow_;\n                goto L1;\n\n            case TOK.pure_:\n                stc = AST.STC.pure_;\n                goto L1;\n\n            case TOK.ref_:\n                stc = AST.STC.ref_;\n                goto L1;\n\n            case TOK.gshared:\n                stc = AST.STC.gshared;\n                goto L1;\n\n            case TOK.enum_:\n                {\n                    Token* t = peek(&token);\n                    if (t.value == TOK.leftCurly || t.value == TOK.colon)\n                        break;\n                    else if (t.value == TOK.identifier)\n                    {\n                        t = peek(t);\n                        if (t.value == TOK.leftCurly || t.value == TOK.colon || t.value == TOK.semicolon)\n                            break;\n                    }\n                    stc = AST.STC.manifest;\n                    goto L1;\n                }\n\n            case TOK.at:\n                {\n                    stc = parseAttribute(&udas);\n                    if (stc)\n                        goto L1;\n                    continue;\n                }\n            L1:\n                storage_class = appendStorageClass(storage_class, stc);\n                nextToken();\n                continue;\n\n            case TOK.extern_:\n                {\n                    if (peek(&token).value != TOK.leftParentheses)\n                    {\n                        stc = AST.STC.extern_;\n                        goto L1;\n                    }\n\n                    if (sawLinkage)\n                        error(\"redundant linkage declaration\");\n                    sawLinkage = true;\n                    AST.Identifiers* idents = null;\n                    CPPMANGLE cppmangle;\n                    bool cppMangleOnly = false;\n                    link = parseLinkage(&idents, cppmangle, cppMangleOnly);\n                    if (idents)\n                    {\n                        error(\"C++ name spaces not allowed here\");\n                    }\n                    if (cppmangle != CPPMANGLE.def)\n                    {\n                        error(\"C++ mangle declaration not allowed here\");\n                    }\n                    continue;\n                }\n            case TOK.align_:\n                {\n                    nextToken();\n                    setAlignment = true;\n                    if (token.value == TOK.leftParentheses)\n                    {\n                        nextToken();\n                        ealign = parseExpression();\n                        check(TOK.rightParentheses);\n                    }\n                    continue;\n                }\n            default:\n                break;\n            }\n            break;\n        }\n    }\n\n    /**********************************\n     * Parse Declarations.\n     * These can be:\n     *      1. declarations at global/class level\n     *      2. declarations at statement level\n     * Return array of Declaration *'s.\n     */\n    AST.Dsymbols* parseDeclarations(bool autodecl, PrefixAttributes!AST* pAttrs, const(char)* comment)\n    {\n        StorageClass storage_class = AST.STC.undefined_;\n        AST.Type ts;\n        AST.Type t;\n        AST.Type tfirst;\n        Identifier ident;\n        TOK tok = TOK.reserved;\n        LINK link = linkage;\n        bool setAlignment = false;\n        AST.Expression ealign;\n        auto loc = token.loc;\n        AST.Expressions* udas = null;\n        Token* tk;\n\n        //printf(\"parseDeclarations() %s\\n\", token.toChars());\n        if (!comment)\n            comment = token.blockComment;\n\n        if (autodecl)\n        {\n            ts = null; // infer type\n            goto L2;\n        }\n\n        if (token.value == TOK.alias_)\n        {\n            tok = token.value;\n            nextToken();\n\n            /* Look for:\n             *   alias identifier this;\n             */\n            if (token.value == TOK.identifier && peekNext() == TOK.this_)\n            {\n                auto s = new AST.AliasThis(loc, token.ident);\n                nextToken();\n                check(TOK.this_);\n                check(TOK.semicolon);\n                auto a = new AST.Dsymbols();\n                a.push(s);\n                addComment(s, comment);\n                return a;\n            }\n            version (none)\n            {\n                /* Look for:\n                 *  alias this = identifier;\n                 */\n                if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier)\n                {\n                    check(TOK.this_);\n                    check(TOK.assign);\n                    auto s = new AliasThis(loc, token.ident);\n                    nextToken();\n                    check(TOK.semicolon);\n                    auto a = new Dsymbols();\n                    a.push(s);\n                    addComment(s, comment);\n                    return a;\n                }\n            }\n            /* Look for:\n             *  alias identifier = type;\n             *  alias identifier(...) = type;\n             */\n            if (token.value == TOK.identifier && skipParensIf(peek(&token), &tk) && tk.value == TOK.assign)\n            {\n                auto a = new AST.Dsymbols();\n                while (1)\n                {\n                    ident = token.ident;\n                    nextToken();\n                    AST.TemplateParameters* tpl = null;\n                    if (token.value == TOK.leftParentheses)\n                        tpl = parseTemplateParameterList();\n                    check(TOK.assign);\n\n                    bool hasParsedAttributes;\n                    void parseAttributes()\n                    {\n                        if (hasParsedAttributes) // only parse once\n                            return;\n                        hasParsedAttributes = true;\n                        udas = null;\n                        storage_class = AST.STC.undefined_;\n                        link = linkage;\n                        setAlignment = false;\n                        ealign = null;\n                        parseStorageClasses(storage_class, link, setAlignment, ealign, udas);\n                    }\n\n                    if (token.value == TOK.at)\n                        parseAttributes;\n\n                    AST.Declaration v;\n                    if (token.value == TOK.function_ ||\n                        token.value == TOK.delegate_ ||\n                        token.value == TOK.leftParentheses &&\n                            skipAttributes(peekPastParen(&token), &tk) &&\n                            (tk.value == TOK.goesTo || tk.value == TOK.leftCurly) ||\n                        token.value == TOK.leftCurly ||\n                        token.value == TOK.identifier && peekNext() == TOK.goesTo\n                       )\n                    {\n                        // function (parameters) { statements... }\n                        // delegate (parameters) { statements... }\n                        // (parameters) { statements... }\n                        // (parameters) => expression\n                        // { statements... }\n                        // identifier => expression\n\n                        AST.Dsymbol s = parseFunctionLiteral();\n\n                        if (udas !is null)\n                        {\n                            if (storage_class != 0)\n                                error(\"Cannot put a storage-class in an alias declaration.\");\n                            // parseAttributes shouldn't have set these variables\n                            assert(link == linkage && !setAlignment && ealign is null);\n                            auto tpl_ = cast(AST.TemplateDeclaration) s;\n                            assert(tpl_ !is null && tpl_.members.dim == 1);\n                            auto fd = cast(AST.FuncLiteralDeclaration) (*tpl_.members)[0];\n                            auto tf = cast(AST.TypeFunction) fd.type;\n                            assert(tf.parameters.dim > 0);\n                            auto as = new AST.Dsymbols();\n                            (*tf.parameters)[0].userAttribDecl = new AST.UserAttributeDeclaration(udas, as);\n                        }\n\n                        v = new AST.AliasDeclaration(loc, ident, s);\n                    }\n                    else\n                    {\n                        parseAttributes();\n                        // StorageClasses type\n                        if (udas)\n                            error(\"user-defined attributes not allowed for `%s` declarations\", Token.toChars(tok));\n\n                        t = parseType();\n                        v = new AST.AliasDeclaration(loc, ident, t);\n                    }\n                    v.storage_class = storage_class;\n\n                    AST.Dsymbol s = v;\n                    if (tpl)\n                    {\n                        auto a2 = new AST.Dsymbols();\n                        a2.push(s);\n                        auto tempdecl = new AST.TemplateDeclaration(loc, ident, tpl, null, a2);\n                        s = tempdecl;\n                    }\n                    if (link != linkage)\n                    {\n                        auto a2 = new AST.Dsymbols();\n                        a2.push(s);\n                        s = new AST.LinkDeclaration(link, a2);\n                    }\n                    a.push(s);\n\n                    switch (token.value)\n                    {\n                    case TOK.semicolon:\n                        nextToken();\n                        addComment(s, comment);\n                        break;\n\n                    case TOK.comma:\n                        nextToken();\n                        addComment(s, comment);\n                        if (token.value != TOK.identifier)\n                        {\n                            error(\"identifier expected following comma, not `%s`\", token.toChars());\n                            break;\n                        }\n                        if (peekNext() != TOK.assign && peekNext() != TOK.leftParentheses)\n                        {\n                            error(\"`=` expected following identifier\");\n                            nextToken();\n                            break;\n                        }\n                        continue;\n\n                    default:\n                        error(\"semicolon expected to close `%s` declaration\", Token.toChars(tok));\n                        break;\n                    }\n                    break;\n                }\n                return a;\n            }\n\n            // alias StorageClasses type ident;\n        }\n\n        parseStorageClasses(storage_class, link, setAlignment, ealign, udas);\n\n        if (token.value == TOK.enum_)\n        {\n            AST.Dsymbol d = parseEnum();\n            auto a = new AST.Dsymbols();\n            a.push(d);\n\n            if (udas)\n            {\n                d = new AST.UserAttributeDeclaration(udas, a);\n                a = new AST.Dsymbols();\n                a.push(d);\n            }\n\n            addComment(d, comment);\n            return a;\n        }\n        else if (token.value == TOK.struct_ ||\n            token.value == TOK.union_ ||\n            token.value == TOK.class_ ||\n            token.value == TOK.interface_)\n        {\n            AST.Dsymbol s = parseAggregate();\n            auto a = new AST.Dsymbols();\n            a.push(s);\n\n            if (storage_class)\n            {\n                s = new AST.StorageClassDeclaration(storage_class, a);\n                a = new AST.Dsymbols();\n                a.push(s);\n            }\n            if (setAlignment)\n            {\n                s = new AST.AlignDeclaration(s.loc, ealign, a);\n                a = new AST.Dsymbols();\n                a.push(s);\n            }\n            if (link != linkage)\n            {\n                s = new AST.LinkDeclaration(link, a);\n                a = new AST.Dsymbols();\n                a.push(s);\n            }\n            if (udas)\n            {\n                s = new AST.UserAttributeDeclaration(udas, a);\n                a = new AST.Dsymbols();\n                a.push(s);\n            }\n\n            addComment(s, comment);\n            return a;\n        }\n\n        /* Look for auto initializers:\n         *  storage_class identifier = initializer;\n         *  storage_class identifier(...) = initializer;\n         */\n        if ((storage_class || udas) && token.value == TOK.identifier && skipParensIf(peek(&token), &tk) && tk.value == TOK.assign)\n        {\n            AST.Dsymbols* a = parseAutoDeclarations(storage_class, comment);\n            if (udas)\n            {\n                AST.Dsymbol s = new AST.UserAttributeDeclaration(udas, a);\n                a = new AST.Dsymbols();\n                a.push(s);\n            }\n            return a;\n        }\n\n        /* Look for return type inference for template functions.\n         */\n        if ((storage_class || udas) && token.value == TOK.identifier && skipParens(peek(&token), &tk) &&\n            skipAttributes(tk, &tk) &&\n            (tk.value == TOK.leftParentheses || tk.value == TOK.leftCurly || tk.value == TOK.in_ || tk.value == TOK.out_ ||\n             tk.value == TOK.do_ || tk.value == TOK.identifier && tk.ident == Id._body))\n        {\n            ts = null;\n        }\n        else\n        {\n            ts = parseBasicType();\n            ts = parseBasicType2(ts);\n        }\n\n    L2:\n        tfirst = null;\n        auto a = new AST.Dsymbols();\n\n        if (pAttrs)\n        {\n            storage_class |= pAttrs.storageClass;\n            //pAttrs.storageClass = STC.undefined_;\n        }\n\n        while (1)\n        {\n            AST.TemplateParameters* tpl = null;\n            int disable;\n            int alt = 0;\n\n            loc = token.loc;\n            ident = null;\n            t = parseDeclarator(ts, &alt, &ident, &tpl, storage_class, &disable, &udas);\n            assert(t);\n            if (!tfirst)\n                tfirst = t;\n            else if (t != tfirst)\n                error(\"multiple declarations must have the same type, not `%s` and `%s`\", tfirst.toChars(), t.toChars());\n\n            bool isThis = (t.ty == AST.Tident && (cast(AST.TypeIdentifier)t).ident == Id.This && token.value == TOK.assign);\n            if (ident)\n                checkCstyleTypeSyntax(loc, t, alt, ident);\n            else if (!isThis && (t != AST.Type.terror))\n                error(\"no identifier for declarator `%s`\", t.toChars());\n\n            if (tok == TOK.alias_)\n            {\n                AST.Declaration v;\n                AST.Initializer _init = null;\n\n                /* Aliases can no longer have multiple declarators, storage classes,\n                 * linkages, or auto declarations.\n                 * These never made any sense, anyway.\n                 * The code below needs to be fixed to reject them.\n                 * The grammar has already been fixed to preclude them.\n                 */\n\n                if (udas)\n                    error(\"user-defined attributes not allowed for `%s` declarations\", Token.toChars(tok));\n\n                if (token.value == TOK.assign)\n                {\n                    nextToken();\n                    _init = parseInitializer();\n                }\n                if (_init)\n                {\n                    if (isThis)\n                        error(\"cannot use syntax `alias this = %s`, use `alias %s this` instead\", _init.toChars(), _init.toChars());\n                    else\n                        error(\"alias cannot have initializer\");\n                }\n                v = new AST.AliasDeclaration(loc, ident, t);\n\n                v.storage_class = storage_class;\n                if (pAttrs)\n                {\n                    /* AliasDeclaration distinguish @safe, @system, @trusted attributes\n                     * on prefix and postfix.\n                     *   @safe alias void function() FP1;\n                     *   alias @safe void function() FP2;    // FP2 is not @safe\n                     *   alias void function() @safe FP3;\n                     */\n                    pAttrs.storageClass &= (AST.STC.safe | AST.STC.system | AST.STC.trusted);\n                }\n                AST.Dsymbol s = v;\n\n                if (link != linkage)\n                {\n                    auto ax = new AST.Dsymbols();\n                    ax.push(v);\n                    s = new AST.LinkDeclaration(link, ax);\n                }\n                a.push(s);\n                switch (token.value)\n                {\n                case TOK.semicolon:\n                    nextToken();\n                    addComment(s, comment);\n                    break;\n\n                case TOK.comma:\n                    nextToken();\n                    addComment(s, comment);\n                    continue;\n\n                default:\n                    error(\"semicolon expected to close `%s` declaration\", Token.toChars(tok));\n                    break;\n                }\n            }\n            else if (t.ty == AST.Tfunction)\n            {\n                AST.Expression constraint = null;\n                //printf(\"%s funcdecl t = %s, storage_class = x%lx\\n\", loc.toChars(), t.toChars(), storage_class);\n                auto f = new AST.FuncDeclaration(loc, Loc.initial, ident, storage_class | (disable ? AST.STC.disable : 0), t);\n                if (pAttrs)\n                    pAttrs.storageClass = AST.STC.undefined_;\n                if (tpl)\n                    constraint = parseConstraint();\n                AST.Dsymbol s = parseContracts(f);\n                auto tplIdent = s.ident;\n\n                if (link != linkage)\n                {\n                    auto ax = new AST.Dsymbols();\n                    ax.push(s);\n                    s = new AST.LinkDeclaration(link, ax);\n                }\n                if (udas)\n                {\n                    auto ax = new AST.Dsymbols();\n                    ax.push(s);\n                    s = new AST.UserAttributeDeclaration(udas, ax);\n                }\n\n                /* A template parameter list means it's a function template\n                 */\n                if (tpl)\n                {\n                    // Wrap a template around the function declaration\n                    auto decldefs = new AST.Dsymbols();\n                    decldefs.push(s);\n                    auto tempdecl = new AST.TemplateDeclaration(loc, tplIdent, tpl, constraint, decldefs);\n                    s = tempdecl;\n\n                    if (storage_class & AST.STC.static_)\n                    {\n                        assert(f.storage_class & AST.STC.static_);\n                        f.storage_class &= ~AST.STC.static_;\n                        auto ax = new AST.Dsymbols();\n                        ax.push(s);\n                        s = new AST.StorageClassDeclaration(AST.STC.static_, ax);\n                    }\n                }\n                a.push(s);\n                addComment(s, comment);\n            }\n            else if (ident)\n            {\n                AST.Initializer _init = null;\n                if (token.value == TOK.assign)\n                {\n                    nextToken();\n                    _init = parseInitializer();\n                }\n\n                auto v = new AST.VarDeclaration(loc, t, ident, _init);\n                v.storage_class = storage_class;\n                if (pAttrs)\n                    pAttrs.storageClass = AST.STC.undefined_;\n\n                AST.Dsymbol s = v;\n\n                if (tpl && _init)\n                {\n                    auto a2 = new AST.Dsymbols();\n                    a2.push(s);\n                    auto tempdecl = new AST.TemplateDeclaration(loc, ident, tpl, null, a2, 0);\n                    s = tempdecl;\n                }\n                if (setAlignment)\n                {\n                    auto ax = new AST.Dsymbols();\n                    ax.push(s);\n                    s = new AST.AlignDeclaration(v.loc, ealign, ax);\n                }\n                if (link != linkage)\n                {\n                    auto ax = new AST.Dsymbols();\n                    ax.push(s);\n                    s = new AST.LinkDeclaration(link, ax);\n                }\n                if (udas)\n                {\n                    auto ax = new AST.Dsymbols();\n                    ax.push(s);\n                    s = new AST.UserAttributeDeclaration(udas, ax);\n                }\n                a.push(s);\n                switch (token.value)\n                {\n                case TOK.semicolon:\n                    nextToken();\n                    addComment(s, comment);\n                    break;\n\n                case TOK.comma:\n                    nextToken();\n                    addComment(s, comment);\n                    continue;\n\n                default:\n                    error(\"semicolon expected, not `%s`\", token.toChars());\n                    break;\n                }\n            }\n            break;\n        }\n        return a;\n    }\n\n    AST.Dsymbol parseFunctionLiteral()\n    {\n        const loc = token.loc;\n        AST.TemplateParameters* tpl = null;\n        AST.Parameters* parameters = null;\n        int varargs = 0;\n        AST.Type tret = null;\n        StorageClass stc = 0;\n        TOK save = TOK.reserved;\n\n        switch (token.value)\n        {\n        case TOK.function_:\n        case TOK.delegate_:\n            save = token.value;\n            nextToken();\n            if (token.value != TOK.leftParentheses && token.value != TOK.leftCurly)\n            {\n                // function type (parameters) { statements... }\n                // delegate type (parameters) { statements... }\n                tret = parseBasicType();\n                tret = parseBasicType2(tret); // function return type\n            }\n\n            if (token.value == TOK.leftParentheses)\n            {\n                // function (parameters) { statements... }\n                // delegate (parameters) { statements... }\n            }\n            else\n            {\n                // function { statements... }\n                // delegate { statements... }\n                break;\n            }\n            goto case TOK.leftParentheses;\n\n        case TOK.leftParentheses:\n            {\n                // (parameters) => expression\n                // (parameters) { statements... }\n                parameters = parseParameters(&varargs, &tpl);\n                stc = parsePostfix(AST.STC.undefined_, null);\n                if (StorageClass modStc = stc & AST.STC.TYPECTOR)\n                {\n                    if (save == TOK.function_)\n                    {\n                        OutBuffer buf;\n                        AST.stcToBuffer(&buf, modStc);\n                        error(\"function literal cannot be `%s`\", buf.peekString());\n                    }\n                    else\n                        save = TOK.delegate_;\n                }\n                break;\n            }\n        case TOK.leftCurly:\n            // { statements... }\n            break;\n\n        case TOK.identifier:\n            {\n                // identifier => expression\n                parameters = new AST.Parameters();\n                Identifier id = Identifier.generateId(\"__T\");\n                AST.Type t = new AST.TypeIdentifier(loc, id);\n                parameters.push(new AST.Parameter(0, t, token.ident, null, null));\n\n                tpl = new AST.TemplateParameters();\n                AST.TemplateParameter tp = new AST.TemplateTypeParameter(loc, id, null, null);\n                tpl.push(tp);\n\n                nextToken();\n                break;\n            }\n        default:\n            assert(0);\n        }\n\n        if (!parameters)\n            parameters = new AST.Parameters();\n        auto tf = new AST.TypeFunction(parameters, tret, varargs, linkage, stc);\n        tf = cast(AST.TypeFunction)tf.addSTC(stc);\n        auto fd = new AST.FuncLiteralDeclaration(loc, Loc.initial, tf, save, null);\n\n        if (token.value == TOK.goesTo)\n        {\n            check(TOK.goesTo);\n            const returnloc = token.loc;\n            AST.Expression ae = parseAssignExp();\n            fd.fbody = new AST.ReturnStatement(returnloc, ae);\n            fd.endloc = token.loc;\n        }\n        else\n        {\n            parseContracts(fd);\n        }\n\n        if (tpl)\n        {\n            // Wrap a template around function fd\n            auto decldefs = new AST.Dsymbols();\n            decldefs.push(fd);\n            return new AST.TemplateDeclaration(fd.loc, fd.ident, tpl, null, decldefs, false, true);\n        }\n        else\n            return fd;\n    }\n\n    /*****************************************\n     * Parse contracts following function declaration.\n     */\n    AST.FuncDeclaration parseContracts(AST.FuncDeclaration f)\n    {\n        LINK linksave = linkage;\n\n        bool literal = f.isFuncLiteralDeclaration() !is null;\n\n        // The following is irrelevant, as it is overridden by sc.linkage in\n        // TypeFunction::semantic\n        linkage = LINK.d; // nested functions have D linkage\n        bool requireDo = false;\n    L1:\n        switch (token.value)\n        {\n        case TOK.leftCurly:\n            if (requireDo)\n                error(\"missing `do { ... }` after `in` or `out`\");\n            f.fbody = parseStatement(ParseStatementFlags.semi);\n            f.endloc = endloc;\n            break;\n\n        case TOK.identifier:\n            if (token.ident == Id._body)\n                goto case TOK.do_;\n            goto default;\n\n        case TOK.do_:\n            nextToken();\n            f.fbody = parseStatement(ParseStatementFlags.curly);\n            f.endloc = endloc;\n            break;\n\n            version (none)\n            {\n                // Do we want this for function declarations, so we can do:\n                // int x, y, foo(), z;\n            case TOK.comma:\n                nextToken();\n                continue;\n            }\n\n            version (none)\n            {\n                // Dumped feature\n            case TOK.throw_:\n                if (!f.fthrows)\n                    f.fthrows = new Types();\n                nextToken();\n                check(TOK.leftParentheses);\n                while (1)\n                {\n                    Type tb = parseBasicType();\n                    f.fthrows.push(tb);\n                    if (token.value == TOK.comma)\n                    {\n                        nextToken();\n                        continue;\n                    }\n                    break;\n                }\n                check(TOK.rightParentheses);\n                goto L1;\n            }\n\n        case TOK.in_:\n            // in { statements... }\n            // in (expression)\n            auto loc = token.loc;\n            nextToken();\n            if (!f.frequires)\n            {\n                f.frequires = new AST.Statements;\n            }\n            if (token.value == TOK.leftParentheses)\n            {\n                nextToken();\n                AST.Expression e = parseAssignExp(), msg = null;\n                if (token.value == TOK.comma)\n                {\n                    nextToken();\n                    if (token.value != TOK.rightParentheses)\n                    {\n                        msg = parseAssignExp();\n                        if (token.value == TOK.comma)\n                            nextToken();\n                    }\n                }\n                check(TOK.rightParentheses);\n                e = new AST.AssertExp(loc, e, msg);\n                f.frequires.push(new AST.ExpStatement(loc, e));\n                requireDo = false;\n            }\n            else\n            {\n                f.frequires.push(parseStatement(ParseStatementFlags.curly | ParseStatementFlags.scope_));\n                requireDo = true;\n            }\n            goto L1;\n\n        case TOK.out_:\n            // out { statements... }\n            // out (; expression)\n            // out (identifier) { statements... }\n            // out (identifier; expression)\n            auto loc = token.loc;\n            nextToken();\n            if (!f.fensures)\n            {\n                f.fensures = new AST.Ensures;\n            }\n            Identifier id = null;\n            if (token.value != TOK.leftCurly)\n            {\n                check(TOK.leftParentheses);\n                if (token.value != TOK.identifier && token.value != TOK.semicolon)\n                    error(\"`(identifier) { ... }` or `(identifier; expression)` following `out` expected, not `%s`\", token.toChars());\n                if (token.value != TOK.semicolon)\n                {\n                    id = token.ident;\n                    nextToken();\n                }\n                if (token.value == TOK.semicolon)\n                {\n                    nextToken();\n                    AST.Expression e = parseAssignExp(), msg = null;\n                    if (token.value == TOK.comma)\n                    {\n                        nextToken();\n                        if (token.value != TOK.rightParentheses)\n                        {\n                            msg = parseAssignExp();\n                            if (token.value == TOK.comma)\n                                nextToken();\n                        }\n                    }\n                    check(TOK.rightParentheses);\n                    e = new AST.AssertExp(loc, e, msg);\n                    f.fensures.push(AST.Ensure(id, new AST.ExpStatement(loc, e)));\n                    requireDo = false;\n                    goto L1;\n                }\n                check(TOK.rightParentheses);\n            }\n            f.fensures.push(AST.Ensure(id, parseStatement(ParseStatementFlags.curly | ParseStatementFlags.scope_)));\n            requireDo = true;\n            goto L1;\n\n        case TOK.semicolon:\n            if (!literal)\n            {\n                // https://issues.dlang.org/show_bug.cgi?id=15799\n                // Semicolon becomes a part of function declaration\n                // only when 'do' is not required\n                if (!requireDo)\n                    nextToken();\n                break;\n            }\n            goto default;\n\n        default:\n            if (literal)\n            {\n                const(char)* sbody = requireDo ? \"do \" : \"\";\n                error(\"missing `%s{ ... }` for function literal\", sbody);\n            }\n            else if (!requireDo) // allow contracts even with no body\n            {\n                TOK t = token.value;\n                if (t == TOK.const_ || t == TOK.immutable_ || t == TOK.inout_ || t == TOK.return_ ||\n                        t == TOK.shared_ || t == TOK.nothrow_ || t == TOK.pure_)\n                    error(\"'%s' cannot be placed after a template constraint\", token.toChars);\n                else if (t == TOK.at)\n                    error(\"attributes cannot be placed after a template constraint\");\n                else if (t == TOK.if_)\n                    error(\"cannot use function constraints for non-template functions. Use `static if` instead\");\n                else\n                    error(\"semicolon expected following function declaration\");\n            }\n            break;\n        }\n        if (literal && !f.fbody)\n        {\n            // Set empty function body for error recovery\n            f.fbody = new AST.CompoundStatement(Loc.initial, cast(AST.Statement)null);\n        }\n\n        linkage = linksave;\n\n        return f;\n    }\n\n    /*****************************************\n     */\n    void checkDanglingElse(Loc elseloc)\n    {\n        if (token.value != TOK.else_ && token.value != TOK.catch_ && token.value != TOK.finally_ && lookingForElse.linnum != 0)\n        {\n            warning(elseloc, \"else is dangling, add { } after condition at %s\", lookingForElse.toChars());\n        }\n    }\n\n    void checkCstyleTypeSyntax(Loc loc, AST.Type t, int alt, Identifier ident)\n    {\n        if (!alt)\n            return;\n\n        const(char)* sp = !ident ? \"\" : \" \";\n        const(char)* s = !ident ? \"\" : ident.toChars();\n        error(loc, \"instead of C-style syntax, use D-style `%s%s%s`\", t.toChars(), sp, s);\n    }\n\n    /*****************************************\n     * Determines additional argument types for parseForeach.\n     */\n    private template ParseForeachArgs(bool isStatic, bool isDecl)\n    {\n        static alias Seq(T...) = T;\n        static if(isDecl)\n        {\n            alias ParseForeachArgs = Seq!(AST.Dsymbol*);\n        }\n        else\n        {\n            alias ParseForeachArgs = Seq!();\n        }\n    }\n    /*****************************************\n     * Determines the result type for parseForeach.\n     */\n    private template ParseForeachRet(bool isStatic, bool isDecl)\n    {\n        static if(!isStatic)\n        {\n            alias ParseForeachRet = AST.Statement;\n        }\n        else static if(isDecl)\n        {\n            alias ParseForeachRet = AST.StaticForeachDeclaration;\n        }\n        else\n        {\n            alias ParseForeachRet = AST.StaticForeachStatement;\n        }\n    }\n    /*****************************************\n     * Parses `foreach` statements, `static foreach` statements and\n     * `static foreach` declarations.  The template parameter\n     * `isStatic` is true, iff a `static foreach` should be parsed.\n     * If `isStatic` is true, `isDecl` can be true to indicate that a\n     * `static foreach` declaration should be parsed.\n     */\n    ParseForeachRet!(isStatic, isDecl) parseForeach(bool isStatic, bool isDecl)(Loc loc, ParseForeachArgs!(isStatic, isDecl) args)\n    {\n        static if(isDecl)\n        {\n            static assert(isStatic);\n        }\n        static if(isStatic)\n        {\n            nextToken();\n            static if(isDecl) auto pLastDecl = args[0];\n        }\n\n        TOK op = token.value;\n\n        nextToken();\n        check(TOK.leftParentheses);\n\n        auto parameters = new AST.Parameters();\n        while (1)\n        {\n            Identifier ai = null;\n            AST.Type at;\n\n            StorageClass storageClass = 0;\n            StorageClass stc = 0;\n        Lagain:\n            if (stc)\n            {\n                storageClass = appendStorageClass(storageClass, stc);\n                nextToken();\n            }\n            switch (token.value)\n            {\n                case TOK.ref_:\n                    stc = AST.STC.ref_;\n                    goto Lagain;\n\n                case TOK.enum_:\n                    stc = AST.STC.manifest;\n                    goto Lagain;\n\n                case TOK.alias_:\n                    storageClass = appendStorageClass(storageClass, AST.STC.alias_);\n                    nextToken();\n                    break;\n\n                case TOK.const_:\n                    if (peekNext() != TOK.leftParentheses)\n                    {\n                        stc = AST.STC.const_;\n                        goto Lagain;\n                    }\n                    break;\n\n                case TOK.immutable_:\n                    if (peekNext() != TOK.leftParentheses)\n                    {\n                        stc = AST.STC.immutable_;\n                        goto Lagain;\n                    }\n                    break;\n\n                case TOK.shared_:\n                    if (peekNext() != TOK.leftParentheses)\n                    {\n                        stc = AST.STC.shared_;\n                        goto Lagain;\n                    }\n                    break;\n\n                case TOK.inout_:\n                    if (peekNext() != TOK.leftParentheses)\n                    {\n                        stc = AST.STC.wild;\n                        goto Lagain;\n                    }\n                    break;\n\n                default:\n                    break;\n            }\n            if (token.value == TOK.identifier)\n            {\n                Token* t = peek(&token);\n                if (t.value == TOK.comma || t.value == TOK.semicolon)\n                {\n                    ai = token.ident;\n                    at = null; // infer argument type\n                    nextToken();\n                    goto Larg;\n                }\n            }\n            at = parseType(&ai);\n            if (!ai)\n                error(\"no identifier for declarator `%s`\", at.toChars());\n        Larg:\n            auto p = new AST.Parameter(storageClass, at, ai, null, null);\n            parameters.push(p);\n            if (token.value == TOK.comma)\n            {\n                nextToken();\n                continue;\n            }\n            break;\n        }\n        check(TOK.semicolon);\n\n        AST.Expression aggr = parseExpression();\n        if (token.value == TOK.slice && parameters.dim == 1)\n        {\n            AST.Parameter p = (*parameters)[0];\n            nextToken();\n            AST.Expression upr = parseExpression();\n            check(TOK.rightParentheses);\n            Loc endloc;\n            static if (!isDecl)\n            {\n                AST.Statement _body = parseStatement(0, null, &endloc);\n            }\n            else\n            {\n                AST.Statement _body = null;\n            }\n            auto rangefe = new AST.ForeachRangeStatement(loc, op, p, aggr, upr, _body, endloc);\n            static if (!isStatic)\n            {\n                return rangefe;\n            }\n            else static if(isDecl)\n            {\n                return new AST.StaticForeachDeclaration(new AST.StaticForeach(loc, null, rangefe), parseBlock(pLastDecl));\n            }\n            else\n            {\n                return new AST.StaticForeachStatement(loc, new AST.StaticForeach(loc, null, rangefe));\n            }\n        }\n        else\n        {\n            check(TOK.rightParentheses);\n            Loc endloc;\n            static if (!isDecl)\n            {\n                AST.Statement _body = parseStatement(0, null, &endloc);\n            }\n            else\n            {\n                AST.Statement _body = null;\n            }\n            auto aggrfe = new AST.ForeachStatement(loc, op, parameters, aggr, _body, endloc);\n            static if(!isStatic)\n            {\n                return aggrfe;\n            }\n            else static if(isDecl)\n            {\n                return new AST.StaticForeachDeclaration(new AST.StaticForeach(loc, aggrfe, null), parseBlock(pLastDecl));\n            }\n            else\n            {\n                return new AST.StaticForeachStatement(loc, new AST.StaticForeach(loc, aggrfe, null));\n            }\n        }\n\n    }\n\n    /*****************************************\n     * Input:\n     *      flags   PSxxxx\n     * Output:\n     *      pEndloc if { ... statements ... }, store location of closing brace, otherwise loc of last token of statement\n     */\n    AST.Statement parseStatement(int flags, const(char)** endPtr = null, Loc* pEndloc = null)\n    {\n        AST.Statement s;\n        AST.Condition cond;\n        AST.Statement ifbody;\n        AST.Statement elsebody;\n        bool isfinal;\n        const loc = token.loc;\n\n        //printf(\"parseStatement()\\n\");\n        if (flags & ParseStatementFlags.curly && token.value != TOK.leftCurly)\n            error(\"statement expected to be `{ }`, not `%s`\", token.toChars());\n\n        switch (token.value)\n        {\n        case TOK.identifier:\n            {\n                /* A leading identifier can be a declaration, label, or expression.\n                 * The easiest case to check first is label:\n                 */\n                Token* t = peek(&token);\n                if (t.value == TOK.colon)\n                {\n                    Token* nt = peek(t);\n                    if (nt.value == TOK.colon)\n                    {\n                        // skip ident::\n                        nextToken();\n                        nextToken();\n                        nextToken();\n                        error(\"use `.` for member lookup, not `::`\");\n                        break;\n                    }\n                    // It's a label\n                    Identifier ident = token.ident;\n                    nextToken();\n                    nextToken();\n                    if (token.value == TOK.rightCurly)\n                        s = null;\n                    else if (token.value == TOK.leftCurly)\n                        s = parseStatement(ParseStatementFlags.curly | ParseStatementFlags.scope_);\n                    else\n                        s = parseStatement(ParseStatementFlags.semiOk);\n                    s = new AST.LabelStatement(loc, ident, s);\n                    break;\n                }\n                goto case TOK.dot;\n            }\n        case TOK.dot:\n        case TOK.typeof_:\n        case TOK.vector:\n            /* https://issues.dlang.org/show_bug.cgi?id=15163\n             * If tokens can be handled as\n             * old C-style declaration or D expression, prefer the latter.\n             */\n            if (isDeclaration(&token, NeedDeclaratorId.mustIfDstyle, TOK.reserved, null))\n                goto Ldeclaration;\n            else\n                goto Lexp;\n\n        case TOK.assert_:\n        case TOK.this_:\n        case TOK.super_:\n        case TOK.int32Literal:\n        case TOK.uns32Literal:\n        case TOK.int64Literal:\n        case TOK.uns64Literal:\n        case TOK.int128Literal:\n        case TOK.uns128Literal:\n        case TOK.float32Literal:\n        case TOK.float64Literal:\n        case TOK.float80Literal:\n        case TOK.imaginary32Literal:\n        case TOK.imaginary64Literal:\n        case TOK.imaginary80Literal:\n        case TOK.charLiteral:\n        case TOK.wcharLiteral:\n        case TOK.dcharLiteral:\n        case TOK.null_:\n        case TOK.true_:\n        case TOK.false_:\n        case TOK.string_:\n        case TOK.hexadecimalString:\n        case TOK.leftParentheses:\n        case TOK.cast_:\n        case TOK.mul:\n        case TOK.min:\n        case TOK.add:\n        case TOK.tilde:\n        case TOK.not:\n        case TOK.plusPlus:\n        case TOK.minusMinus:\n        case TOK.new_:\n        case TOK.delete_:\n        case TOK.delegate_:\n        case TOK.function_:\n        case TOK.typeid_:\n        case TOK.is_:\n        case TOK.leftBracket:\n        case TOK.traits:\n        case TOK.file:\n        case TOK.fileFullPath:\n        case TOK.line:\n        case TOK.moduleString:\n        case TOK.functionString:\n        case TOK.prettyFunction:\n        Lexp:\n            {\n                AST.Expression exp = parseExpression();\n                check(TOK.semicolon, \"statement\");\n                s = new AST.ExpStatement(loc, exp);\n                break;\n            }\n        case TOK.static_:\n            {\n                // Look ahead to see if it's static assert() or static if()\n                Token* t = peek(&token);\n                if (t.value == TOK.assert_)\n                {\n                    s = new AST.StaticAssertStatement(parseStaticAssert());\n                    break;\n                }\n                if (t.value == TOK.if_)\n                {\n                    cond = parseStaticIfCondition();\n                    goto Lcondition;\n                }\n                else if(t.value == TOK.foreach_ || t.value == TOK.foreach_reverse_)\n                {\n                    s = parseForeach!(true,false)(loc);\n                    if (flags & ParseStatementFlags.scope_)\n                        s = new AST.ScopeStatement(loc, s, token.loc);\n                    break;\n                }\n                if (t.value == TOK.import_)\n                {\n                    AST.Dsymbols* imports = parseImport();\n                    s = new AST.ImportStatement(loc, imports);\n                    if (flags & ParseStatementFlags.scope_)\n                        s = new AST.ScopeStatement(loc, s, token.loc);\n                    break;\n                }\n                goto Ldeclaration;\n            }\n        case TOK.final_:\n            if (peekNext() == TOK.switch_)\n            {\n                nextToken();\n                isfinal = true;\n                goto Lswitch;\n            }\n            goto Ldeclaration;\n\n        case TOK.wchar_:\n        case TOK.dchar_:\n        case TOK.bool_:\n        case TOK.char_:\n        case TOK.int8:\n        case TOK.uns8:\n        case TOK.int16:\n        case TOK.uns16:\n        case TOK.int32:\n        case TOK.uns32:\n        case TOK.int64:\n        case TOK.uns64:\n        case TOK.int128:\n        case TOK.uns128:\n        case TOK.float32:\n        case TOK.float64:\n        case TOK.float80:\n        case TOK.imaginary32:\n        case TOK.imaginary64:\n        case TOK.imaginary80:\n        case TOK.complex32:\n        case TOK.complex64:\n        case TOK.complex80:\n        case TOK.void_:\n            // bug 7773: int.max is always a part of expression\n            if (peekNext() == TOK.dot)\n                goto Lexp;\n            if (peekNext() == TOK.leftParentheses)\n                goto Lexp;\n            goto case;\n\n        case TOK.alias_:\n        case TOK.const_:\n        case TOK.auto_:\n        case TOK.abstract_:\n        case TOK.extern_:\n        case TOK.align_:\n        case TOK.immutable_:\n        case TOK.shared_:\n        case TOK.inout_:\n        case TOK.deprecated_:\n        case TOK.nothrow_:\n        case TOK.pure_:\n        case TOK.ref_:\n        case TOK.gshared:\n        case TOK.at:\n        case TOK.struct_:\n        case TOK.union_:\n        case TOK.class_:\n        case TOK.interface_:\n        Ldeclaration:\n            {\n                AST.Dsymbols* a = parseDeclarations(false, null, null);\n                if (a.dim > 1)\n                {\n                    auto as = new AST.Statements();\n                    as.reserve(a.dim);\n                    foreach (i; 0 .. a.dim)\n                    {\n                        AST.Dsymbol d = (*a)[i];\n                        s = new AST.ExpStatement(loc, d);\n                        as.push(s);\n                    }\n                    s = new AST.CompoundDeclarationStatement(loc, as);\n                }\n                else if (a.dim == 1)\n                {\n                    AST.Dsymbol d = (*a)[0];\n                    s = new AST.ExpStatement(loc, d);\n                }\n                else\n                    s = new AST.ExpStatement(loc, cast(AST.Expression)null);\n                if (flags & ParseStatementFlags.scope_)\n                    s = new AST.ScopeStatement(loc, s, token.loc);\n                break;\n            }\n        case TOK.enum_:\n            {\n                /* Determine if this is a manifest constant declaration,\n                 * or a conventional enum.\n                 */\n                AST.Dsymbol d;\n                Token* t = peek(&token);\n                if (t.value == TOK.leftCurly || t.value == TOK.colon)\n                    d = parseEnum();\n                else if (t.value != TOK.identifier)\n                    goto Ldeclaration;\n                else\n                {\n                    t = peek(t);\n                    if (t.value == TOK.leftCurly || t.value == TOK.colon || t.value == TOK.semicolon)\n                        d = parseEnum();\n                    else\n                        goto Ldeclaration;\n                }\n                s = new AST.ExpStatement(loc, d);\n                if (flags & ParseStatementFlags.scope_)\n                    s = new AST.ScopeStatement(loc, s, token.loc);\n                break;\n            }\n        case TOK.mixin_:\n            {\n                Token* t = peek(&token);\n                if (t.value == TOK.leftParentheses)\n                {\n                    // mixin(string)\n                    AST.Expression e = parseAssignExp();\n                    check(TOK.semicolon);\n                    if (e.op == TOK.mixin_)\n                    {\n                        AST.CompileExp cpe = cast(AST.CompileExp)e;\n                        s = new AST.CompileStatement(loc, cpe.exps);\n                    }\n                    else\n                    {\n                        s = new AST.ExpStatement(loc, e);\n                    }\n                    break;\n                }\n                AST.Dsymbol d = parseMixin();\n                s = new AST.ExpStatement(loc, d);\n                if (flags & ParseStatementFlags.scope_)\n                    s = new AST.ScopeStatement(loc, s, token.loc);\n                break;\n            }\n        case TOK.leftCurly:\n            {\n                const lookingForElseSave = lookingForElse;\n                lookingForElse = Loc.initial;\n\n                nextToken();\n                //if (token.value == TOK.semicolon)\n                //    error(\"use `{ }` for an empty statement, not `;`\");\n                auto statements = new AST.Statements();\n                while (token.value != TOK.rightCurly && token.value != TOK.endOfFile)\n                {\n                    statements.push(parseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope));\n                }\n                if (endPtr)\n                    *endPtr = token.ptr;\n                endloc = token.loc;\n                if (pEndloc)\n                {\n                    *pEndloc = token.loc;\n                    pEndloc = null; // don't set it again\n                }\n                s = new AST.CompoundStatement(loc, statements);\n                if (flags & (ParseStatementFlags.scope_ | ParseStatementFlags.curlyScope))\n                    s = new AST.ScopeStatement(loc, s, token.loc);\n                check(TOK.rightCurly, \"compound statement\");\n                lookingForElse = lookingForElseSave;\n                break;\n            }\n        case TOK.while_:\n            {\n                nextToken();\n                check(TOK.leftParentheses);\n                AST.Expression condition = parseExpression();\n                check(TOK.rightParentheses);\n                Loc endloc;\n                AST.Statement _body = parseStatement(ParseStatementFlags.scope_, null, &endloc);\n                s = new AST.WhileStatement(loc, condition, _body, endloc);\n                break;\n            }\n        case TOK.semicolon:\n            if (!(flags & ParseStatementFlags.semiOk))\n            {\n                if (flags & ParseStatementFlags.semi)\n                    deprecation(\"use `{ }` for an empty statement, not `;`\");\n                else\n                    error(\"use `{ }` for an empty statement, not `;`\");\n            }\n            nextToken();\n            s = new AST.ExpStatement(loc, cast(AST.Expression)null);\n            break;\n\n        case TOK.do_:\n            {\n                AST.Statement _body;\n                AST.Expression condition;\n\n                nextToken();\n                const lookingForElseSave = lookingForElse;\n                lookingForElse = Loc.initial;\n                _body = parseStatement(ParseStatementFlags.scope_);\n                lookingForElse = lookingForElseSave;\n                check(TOK.while_);\n                check(TOK.leftParentheses);\n                condition = parseExpression();\n                check(TOK.rightParentheses);\n                if (token.value == TOK.semicolon)\n                    nextToken();\n                else\n                    error(\"terminating `;` required after do-while statement\");\n                s = new AST.DoStatement(loc, _body, condition, token.loc);\n                break;\n            }\n        case TOK.for_:\n            {\n                AST.Statement _init;\n                AST.Expression condition;\n                AST.Expression increment;\n\n                nextToken();\n                check(TOK.leftParentheses);\n                if (token.value == TOK.semicolon)\n                {\n                    _init = null;\n                    nextToken();\n                }\n                else\n                {\n                    const lookingForElseSave = lookingForElse;\n                    lookingForElse = Loc.initial;\n                    _init = parseStatement(0);\n                    lookingForElse = lookingForElseSave;\n                }\n                if (token.value == TOK.semicolon)\n                {\n                    condition = null;\n                    nextToken();\n                }\n                else\n                {\n                    condition = parseExpression();\n                    check(TOK.semicolon, \"`for` condition\");\n                }\n                if (token.value == TOK.rightParentheses)\n                {\n                    increment = null;\n                    nextToken();\n                }\n                else\n                {\n                    increment = parseExpression();\n                    check(TOK.rightParentheses);\n                }\n                Loc endloc;\n                AST.Statement _body = parseStatement(ParseStatementFlags.scope_, null, &endloc);\n                s = new AST.ForStatement(loc, _init, condition, increment, _body, endloc);\n                break;\n            }\n        case TOK.foreach_:\n        case TOK.foreach_reverse_:\n            {\n                s = parseForeach!(false,false)(loc);\n                break;\n            }\n        case TOK.if_:\n            {\n                AST.Parameter param = null;\n                AST.Expression condition;\n\n                nextToken();\n                check(TOK.leftParentheses);\n\n                StorageClass storageClass = 0;\n                StorageClass stc = 0;\n            LagainStc:\n                if (stc)\n                {\n                    storageClass = appendStorageClass(storageClass, stc);\n                    nextToken();\n                }\n                switch (token.value)\n                {\n                case TOK.ref_:\n                    stc = AST.STC.ref_;\n                    goto LagainStc;\n\n                case TOK.auto_:\n                    stc = AST.STC.auto_;\n                    goto LagainStc;\n\n                case TOK.const_:\n                    if (peekNext() != TOK.leftParentheses)\n                    {\n                        stc = AST.STC.const_;\n                        goto LagainStc;\n                    }\n                    break;\n\n                case TOK.immutable_:\n                    if (peekNext() != TOK.leftParentheses)\n                    {\n                        stc = AST.STC.immutable_;\n                        goto LagainStc;\n                    }\n                    break;\n\n                case TOK.shared_:\n                    if (peekNext() != TOK.leftParentheses)\n                    {\n                        stc = AST.STC.shared_;\n                        goto LagainStc;\n                    }\n                    break;\n\n                case TOK.inout_:\n                    if (peekNext() != TOK.leftParentheses)\n                    {\n                        stc = AST.STC.wild;\n                        goto LagainStc;\n                    }\n                    break;\n\n                default:\n                    break;\n                }\n                if (storageClass != 0 && token.value == TOK.identifier && peek(&token).value == TOK.assign)\n                {\n                    Identifier ai = token.ident;\n                    AST.Type at = null; // infer parameter type\n                    nextToken();\n                    check(TOK.assign);\n                    param = new AST.Parameter(storageClass, at, ai, null, null);\n                }\n                else if (isDeclaration(&token, NeedDeclaratorId.must, TOK.assign, null))\n                {\n                    Identifier ai;\n                    AST.Type at = parseType(&ai);\n                    check(TOK.assign);\n                    param = new AST.Parameter(storageClass, at, ai, null, null);\n                }\n\n                condition = parseExpression();\n                check(TOK.rightParentheses);\n                {\n                    const lookingForElseSave = lookingForElse;\n                    lookingForElse = loc;\n                    ifbody = parseStatement(ParseStatementFlags.scope_);\n                    lookingForElse = lookingForElseSave;\n                }\n                if (token.value == TOK.else_)\n                {\n                    const elseloc = token.loc;\n                    nextToken();\n                    elsebody = parseStatement(ParseStatementFlags.scope_);\n                    checkDanglingElse(elseloc);\n                }\n                else\n                    elsebody = null;\n                if (condition && ifbody)\n                    s = new AST.IfStatement(loc, param, condition, ifbody, elsebody, token.loc);\n                else\n                    s = null; // don't propagate parsing errors\n                break;\n            }\n\n        case TOK.else_:\n            error(\"found `else` without a corresponding `if`, `version` or `debug` statement\");\n            goto Lerror;\n\n        case TOK.scope_:\n            if (peek(&token).value != TOK.leftParentheses)\n                goto Ldeclaration; // scope used as storage class\n            nextToken();\n            check(TOK.leftParentheses);\n            if (token.value != TOK.identifier)\n            {\n                error(\"scope identifier expected\");\n                goto Lerror;\n            }\n            else\n            {\n                TOK t = TOK.onScopeExit;\n                Identifier id = token.ident;\n                if (id == Id.exit)\n                    t = TOK.onScopeExit;\n                else if (id == Id.failure)\n                    t = TOK.onScopeFailure;\n                else if (id == Id.success)\n                    t = TOK.onScopeSuccess;\n                else\n                    error(\"valid scope identifiers are `exit`, `failure`, or `success`, not `%s`\", id.toChars());\n                nextToken();\n                check(TOK.rightParentheses);\n                AST.Statement st = parseStatement(ParseStatementFlags.scope_);\n                s = new AST.OnScopeStatement(loc, t, st);\n                break;\n            }\n\n        case TOK.debug_:\n            nextToken();\n            if (token.value == TOK.assign)\n            {\n                error(\"debug conditions can only be declared at module scope\");\n                nextToken();\n                nextToken();\n                goto Lerror;\n            }\n            cond = parseDebugCondition();\n            goto Lcondition;\n\n        case TOK.version_:\n            nextToken();\n            if (token.value == TOK.assign)\n            {\n                error(\"version conditions can only be declared at module scope\");\n                nextToken();\n                nextToken();\n                goto Lerror;\n            }\n            cond = parseVersionCondition();\n            goto Lcondition;\n\n        Lcondition:\n            {\n                const lookingForElseSave = lookingForElse;\n                lookingForElse = loc;\n                ifbody = parseStatement(0);\n                lookingForElse = lookingForElseSave;\n            }\n            elsebody = null;\n            if (token.value == TOK.else_)\n            {\n                const elseloc = token.loc;\n                nextToken();\n                elsebody = parseStatement(0);\n                checkDanglingElse(elseloc);\n            }\n            s = new AST.ConditionalStatement(loc, cond, ifbody, elsebody);\n            if (flags & ParseStatementFlags.scope_)\n                s = new AST.ScopeStatement(loc, s, token.loc);\n            break;\n\n        case TOK.pragma_:\n            {\n                Identifier ident;\n                AST.Expressions* args = null;\n                AST.Statement _body;\n\n                nextToken();\n                check(TOK.leftParentheses);\n                if (token.value != TOK.identifier)\n                {\n                    error(\"`pragma(identifier)` expected\");\n                    goto Lerror;\n                }\n                ident = token.ident;\n                nextToken();\n                if (token.value == TOK.comma && peekNext() != TOK.rightParentheses)\n                    args = parseArguments(); // pragma(identifier, args...);\n                else\n                    check(TOK.rightParentheses); // pragma(identifier);\n                if (token.value == TOK.semicolon)\n                {\n                    nextToken();\n                    _body = null;\n                }\n                else\n                    _body = parseStatement(ParseStatementFlags.semi);\n                s = new AST.PragmaStatement(loc, ident, args, _body);\n                break;\n            }\n        case TOK.switch_:\n            isfinal = false;\n            goto Lswitch;\n\n        Lswitch:\n            {\n                nextToken();\n                check(TOK.leftParentheses);\n                AST.Expression condition = parseExpression();\n                check(TOK.rightParentheses);\n                AST.Statement _body = parseStatement(ParseStatementFlags.scope_);\n                s = new AST.SwitchStatement(loc, condition, _body, isfinal);\n                break;\n            }\n        case TOK.case_:\n            {\n                AST.Expression exp;\n                AST.Expressions cases; // array of Expression's\n                AST.Expression last = null;\n\n                while (1)\n                {\n                    nextToken();\n                    exp = parseAssignExp();\n                    cases.push(exp);\n                    if (token.value != TOK.comma)\n                        break;\n                }\n                check(TOK.colon);\n\n                /* case exp: .. case last:\n                 */\n                if (token.value == TOK.slice)\n                {\n                    if (cases.dim > 1)\n                        error(\"only one `case` allowed for start of case range\");\n                    nextToken();\n                    check(TOK.case_);\n                    last = parseAssignExp();\n                    check(TOK.colon);\n                }\n\n                if (flags & ParseStatementFlags.curlyScope)\n                {\n                    auto statements = new AST.Statements();\n                    while (token.value != TOK.case_ && token.value != TOK.default_ && token.value != TOK.endOfFile && token.value != TOK.rightCurly)\n                    {\n                        statements.push(parseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope));\n                    }\n                    s = new AST.CompoundStatement(loc, statements);\n                }\n                else\n                {\n                    s = parseStatement(ParseStatementFlags.semi);\n                }\n                s = new AST.ScopeStatement(loc, s, token.loc);\n\n                if (last)\n                {\n                    s = new AST.CaseRangeStatement(loc, exp, last, s);\n                }\n                else\n                {\n                    // Keep cases in order by building the case statements backwards\n                    for (size_t i = cases.dim; i; i--)\n                    {\n                        exp = cases[i - 1];\n                        s = new AST.CaseStatement(loc, exp, s);\n                    }\n                }\n                break;\n            }\n        case TOK.default_:\n            {\n                nextToken();\n                check(TOK.colon);\n\n                if (flags & ParseStatementFlags.curlyScope)\n                {\n                    auto statements = new AST.Statements();\n                    while (token.value != TOK.case_ && token.value != TOK.default_ && token.value != TOK.endOfFile && token.value != TOK.rightCurly)\n                    {\n                        statements.push(parseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope));\n                    }\n                    s = new AST.CompoundStatement(loc, statements);\n                }\n                else\n                    s = parseStatement(ParseStatementFlags.semi);\n                s = new AST.ScopeStatement(loc, s, token.loc);\n                s = new AST.DefaultStatement(loc, s);\n                break;\n            }\n        case TOK.return_:\n            {\n                AST.Expression exp;\n                nextToken();\n                if (token.value == TOK.semicolon)\n                    exp = null;\n                else\n                    exp = parseExpression();\n                check(TOK.semicolon, \"`return` statement\");\n                s = new AST.ReturnStatement(loc, exp);\n                break;\n            }\n        case TOK.break_:\n            {\n                Identifier ident;\n                nextToken();\n                if (token.value == TOK.identifier)\n                {\n                    ident = token.ident;\n                    nextToken();\n                }\n                else\n                    ident = null;\n                check(TOK.semicolon, \"`break` statement\");\n                s = new AST.BreakStatement(loc, ident);\n                break;\n            }\n        case TOK.continue_:\n            {\n                Identifier ident;\n                nextToken();\n                if (token.value == TOK.identifier)\n                {\n                    ident = token.ident;\n                    nextToken();\n                }\n                else\n                    ident = null;\n                check(TOK.semicolon, \"`continue` statement\");\n                s = new AST.ContinueStatement(loc, ident);\n                break;\n            }\n        case TOK.goto_:\n            {\n                Identifier ident;\n                nextToken();\n                if (token.value == TOK.default_)\n                {\n                    nextToken();\n                    s = new AST.GotoDefaultStatement(loc);\n                }\n                else if (token.value == TOK.case_)\n                {\n                    AST.Expression exp = null;\n                    nextToken();\n                    if (token.value != TOK.semicolon)\n                        exp = parseExpression();\n                    s = new AST.GotoCaseStatement(loc, exp);\n                }\n                else\n                {\n                    if (token.value != TOK.identifier)\n                    {\n                        error(\"identifier expected following `goto`\");\n                        ident = null;\n                    }\n                    else\n                    {\n                        ident = token.ident;\n                        nextToken();\n                    }\n                    s = new AST.GotoStatement(loc, ident);\n                }\n                check(TOK.semicolon, \"`goto` statement\");\n                break;\n            }\n        case TOK.synchronized_:\n            {\n                AST.Expression exp;\n                AST.Statement _body;\n\n                Token* t = peek(&token);\n                if (skipAttributes(t, &t) && t.value == TOK.class_)\n                    goto Ldeclaration;\n\n                nextToken();\n                if (token.value == TOK.leftParentheses)\n                {\n                    nextToken();\n                    exp = parseExpression();\n                    check(TOK.rightParentheses);\n                }\n                else\n                    exp = null;\n                _body = parseStatement(ParseStatementFlags.scope_);\n                s = new AST.SynchronizedStatement(loc, exp, _body);\n                break;\n            }\n        case TOK.with_:\n            {\n                AST.Expression exp;\n                AST.Statement _body;\n                Loc endloc = loc;\n\n                nextToken();\n                check(TOK.leftParentheses);\n                exp = parseExpression();\n                check(TOK.rightParentheses);\n                _body = parseStatement(ParseStatementFlags.scope_, null, &endloc);\n                s = new AST.WithStatement(loc, exp, _body, endloc);\n                break;\n            }\n        case TOK.try_:\n            {\n                AST.Statement _body;\n                AST.Catches* catches = null;\n                AST.Statement finalbody = null;\n\n                nextToken();\n                const lookingForElseSave = lookingForElse;\n                lookingForElse = Loc.initial;\n                _body = parseStatement(ParseStatementFlags.scope_);\n                lookingForElse = lookingForElseSave;\n                while (token.value == TOK.catch_)\n                {\n                    AST.Statement handler;\n                    AST.Catch c;\n                    AST.Type t;\n                    Identifier id;\n                    const catchloc = token.loc;\n\n                    nextToken();\n                    if (token.value == TOK.leftCurly || token.value != TOK.leftParentheses)\n                    {\n                        t = null;\n                        id = null;\n                    }\n                    else\n                    {\n                        check(TOK.leftParentheses);\n                        id = null;\n                        t = parseType(&id);\n                        check(TOK.rightParentheses);\n                    }\n                    handler = parseStatement(0);\n                    c = new AST.Catch(catchloc, t, id, handler);\n                    if (!catches)\n                        catches = new AST.Catches();\n                    catches.push(c);\n                }\n\n                if (token.value == TOK.finally_)\n                {\n                    nextToken();\n                    finalbody = parseStatement(ParseStatementFlags.scope_);\n                }\n\n                s = _body;\n                if (!catches && !finalbody)\n                    error(\"`catch` or `finally` expected following `try`\");\n                else\n                {\n                    if (catches)\n                        s = new AST.TryCatchStatement(loc, _body, catches);\n                    if (finalbody)\n                        s = new AST.TryFinallyStatement(loc, s, finalbody);\n                }\n                break;\n            }\n        case TOK.throw_:\n            {\n                AST.Expression exp;\n                nextToken();\n                exp = parseExpression();\n                check(TOK.semicolon, \"`throw` statement\");\n                s = new AST.ThrowStatement(loc, exp);\n                break;\n            }\n\n        case TOK.asm_:\n            {\n                // Parse the asm block into a sequence of AsmStatements,\n                // each AsmStatement is one instruction.\n                // Separate out labels.\n                // Defer parsing of AsmStatements until semantic processing.\n\n                Loc labelloc;\n\n                nextToken();\n                StorageClass stc = parsePostfix(AST.STC.undefined_, null);\n                if (stc & (AST.STC.const_ | AST.STC.immutable_ | AST.STC.shared_ | AST.STC.wild))\n                    error(\"`const`/`immutable`/`shared`/`inout` attributes are not allowed on `asm` blocks\");\n\n                check(TOK.leftCurly);\n                Token* toklist = null;\n                Token** ptoklist = &toklist;\n                Identifier label = null;\n                auto statements = new AST.Statements();\n                size_t nestlevel = 0;\n                while (1)\n                {\n                    switch (token.value)\n                    {\n                    case TOK.identifier:\n                        if (!toklist)\n                        {\n                            // Look ahead to see if it is a label\n                            Token* t = peek(&token);\n                            if (t.value == TOK.colon)\n                            {\n                                // It's a label\n                                label = token.ident;\n                                labelloc = token.loc;\n                                nextToken();\n                                nextToken();\n                                continue;\n                            }\n                        }\n                        goto default;\n\n                    case TOK.leftCurly:\n                        ++nestlevel;\n                        goto default;\n\n                    case TOK.rightCurly:\n                        if (nestlevel > 0)\n                        {\n                            --nestlevel;\n                            goto default;\n                        }\n                        if (toklist || label)\n                        {\n                            error(\"`asm` statements must end in `;`\");\n                        }\n                        break;\n\n                    case TOK.semicolon:\n                        if (nestlevel != 0)\n                            error(\"mismatched number of curly brackets\");\n\n                        s = null;\n                        if (toklist || label)\n                        {\n                            // Create AsmStatement from list of tokens we've saved\n                            s = new AST.AsmStatement(token.loc, toklist);\n                            toklist = null;\n                            ptoklist = &toklist;\n                            if (label)\n                            {\n                                s = new AST.LabelStatement(labelloc, label, s);\n                                label = null;\n                            }\n                            statements.push(s);\n                        }\n                        nextToken();\n                        continue;\n\n                    case TOK.endOfFile:\n                        /* { */\n                        error(\"matching `}` expected, not end of file\");\n                        goto Lerror;\n\n                    default:\n                        *ptoklist = Token.alloc();\n                        memcpy(*ptoklist, &token, Token.sizeof);\n                        ptoklist = &(*ptoklist).next;\n                        *ptoklist = null;\n                        nextToken();\n                        continue;\n                    }\n                    break;\n                }\n                s = new AST.CompoundAsmStatement(loc, statements, stc);\n                nextToken();\n                break;\n            }\n        case TOK.import_:\n            {\n                /* https://issues.dlang.org/show_bug.cgi?id=16088\n                 *\n                 * At this point it can either be an\n                 * https://dlang.org/spec/grammar.html#ImportExpression\n                 * or an\n                 * https://dlang.org/spec/grammar.html#ImportDeclaration.\n                 * See if the next token after `import` is a `(`; if so,\n                 * then it is an import expression.\n                 */\n                if (peekNext() == TOK.leftParentheses)\n                {\n                    AST.Expression e = parseExpression();\n                    check(TOK.semicolon);\n                    s = new AST.ExpStatement(loc, e);\n                }\n                else\n                {\n                    AST.Dsymbols* imports = parseImport();\n                    s = new AST.ImportStatement(loc, imports);\n                    if (flags & ParseStatementFlags.scope_)\n                        s = new AST.ScopeStatement(loc, s, token.loc);\n                }\n                break;\n            }\n        case TOK.template_:\n            {\n                AST.Dsymbol d = parseTemplateDeclaration();\n                s = new AST.ExpStatement(loc, d);\n                break;\n            }\n        default:\n            error(\"found `%s` instead of statement\", token.toChars());\n            goto Lerror;\n\n        Lerror:\n            while (token.value != TOK.rightCurly && token.value != TOK.semicolon && token.value != TOK.endOfFile)\n                nextToken();\n            if (token.value == TOK.semicolon)\n                nextToken();\n            s = null;\n            break;\n        }\n        if (pEndloc)\n            *pEndloc = prevloc;\n        return s;\n    }\n\n    /*****************************************\n     * Parse initializer for variable declaration.\n     */\n    AST.Initializer parseInitializer()\n    {\n        AST.StructInitializer _is;\n        AST.ArrayInitializer ia;\n        AST.ExpInitializer ie;\n        AST.Expression e;\n        Identifier id;\n        AST.Initializer value;\n        int comma;\n        const loc = token.loc;\n        Token* t;\n        int braces;\n        int brackets;\n\n        switch (token.value)\n        {\n        case TOK.leftCurly:\n            /* Scan ahead to discern between a struct initializer and\n             * parameterless function literal.\n             *\n             * We'll scan the topmost curly bracket level for statement-related\n             * tokens, thereby ruling out a struct initializer.  (A struct\n             * initializer which itself contains function literals may have\n             * statements at nested curly bracket levels.)\n             *\n             * It's important that this function literal check not be\n             * pendantic, otherwise a function having the slightest syntax\n             * error would emit confusing errors when we proceed to parse it\n             * as a struct initializer.\n             *\n             * The following two ambiguous cases will be treated as a struct\n             * initializer (best we can do without type info):\n             *     {}\n             *     {{statements...}}  - i.e. it could be struct initializer\n             *        with one function literal, or function literal having an\n             *        extra level of curly brackets\n             * If a function literal is intended in these cases (unlikely),\n             * source can use a more explicit function literal syntax\n             * (e.g. prefix with \"()\" for empty parameter list).\n             */\n            braces = 1;\n            for (t = peek(&token); 1; t = peek(t))\n            {\n                switch (t.value)\n                {\n                /* Look for a semicolon or keyword of statements which don't\n                 * require a semicolon (typically containing BlockStatement).\n                 * Tokens like \"else\", \"catch\", etc. are omitted where the\n                 * leading token of the statement is sufficient.\n                 */\n                case TOK.asm_:\n                case TOK.class_:\n                case TOK.debug_:\n                case TOK.enum_:\n                case TOK.if_:\n                case TOK.interface_:\n                case TOK.pragma_:\n                case TOK.scope_:\n                case TOK.semicolon:\n                case TOK.struct_:\n                case TOK.switch_:\n                case TOK.synchronized_:\n                case TOK.try_:\n                case TOK.union_:\n                case TOK.version_:\n                case TOK.while_:\n                case TOK.with_:\n                    if (braces == 1)\n                        goto Lexpression;\n                    continue;\n\n                case TOK.leftCurly:\n                    braces++;\n                    continue;\n\n                case TOK.rightCurly:\n                    if (--braces == 0)\n                        break;\n                    continue;\n\n                case TOK.endOfFile:\n                    break;\n\n                default:\n                    continue;\n                }\n                break;\n            }\n\n            _is = new AST.StructInitializer(loc);\n            nextToken();\n            comma = 2;\n            while (1)\n            {\n                switch (token.value)\n                {\n                case TOK.identifier:\n                    if (comma == 1)\n                        error(\"comma expected separating field initializers\");\n                    t = peek(&token);\n                    if (t.value == TOK.colon)\n                    {\n                        id = token.ident;\n                        nextToken();\n                        nextToken(); // skip over ':'\n                    }\n                    else\n                    {\n                        id = null;\n                    }\n                    value = parseInitializer();\n                    _is.addInit(id, value);\n                    comma = 1;\n                    continue;\n\n                case TOK.comma:\n                    if (comma == 2)\n                        error(\"expression expected, not `,`\");\n                    nextToken();\n                    comma = 2;\n                    continue;\n\n                case TOK.rightCurly: // allow trailing comma's\n                    nextToken();\n                    break;\n\n                case TOK.endOfFile:\n                    error(\"found end of file instead of initializer\");\n                    break;\n\n                default:\n                    if (comma == 1)\n                        error(\"comma expected separating field initializers\");\n                    value = parseInitializer();\n                    _is.addInit(null, value);\n                    comma = 1;\n                    continue;\n                    //error(\"found `%s` instead of field initializer\", token.toChars());\n                    //break;\n                }\n                break;\n            }\n            return _is;\n\n        case TOK.leftBracket:\n            /* Scan ahead to see if it is an array initializer or\n             * an expression.\n             * If it ends with a ';' ',' or '}', it is an array initializer.\n             */\n            brackets = 1;\n            for (t = peek(&token); 1; t = peek(t))\n            {\n                switch (t.value)\n                {\n                case TOK.leftBracket:\n                    brackets++;\n                    continue;\n\n                case TOK.rightBracket:\n                    if (--brackets == 0)\n                    {\n                        t = peek(t);\n                        if (t.value != TOK.semicolon && t.value != TOK.comma && t.value != TOK.rightBracket && t.value != TOK.rightCurly)\n                            goto Lexpression;\n                        break;\n                    }\n                    continue;\n\n                case TOK.endOfFile:\n                    break;\n\n                default:\n                    continue;\n                }\n                break;\n            }\n\n            ia = new AST.ArrayInitializer(loc);\n            nextToken();\n            comma = 2;\n            while (1)\n            {\n                switch (token.value)\n                {\n                default:\n                    if (comma == 1)\n                    {\n                        error(\"comma expected separating array initializers, not `%s`\", token.toChars());\n                        nextToken();\n                        break;\n                    }\n                    e = parseAssignExp();\n                    if (!e)\n                        break;\n                    if (token.value == TOK.colon)\n                    {\n                        nextToken();\n                        value = parseInitializer();\n                    }\n                    else\n                    {\n                        value = new AST.ExpInitializer(e.loc, e);\n                        e = null;\n                    }\n                    ia.addInit(e, value);\n                    comma = 1;\n                    continue;\n\n                case TOK.leftCurly:\n                case TOK.leftBracket:\n                    if (comma == 1)\n                        error(\"comma expected separating array initializers, not `%s`\", token.toChars());\n                    value = parseInitializer();\n                    if (token.value == TOK.colon)\n                    {\n                        nextToken();\n                        AST.ExpInitializer expInit = value.isExpInitializer();\n                        assert(expInit);\n                        e = expInit.exp;\n                        value = parseInitializer();\n                    }\n                    else\n                        e = null;\n                    ia.addInit(e, value);\n                    comma = 1;\n                    continue;\n\n                case TOK.comma:\n                    if (comma == 2)\n                        error(\"expression expected, not `,`\");\n                    nextToken();\n                    comma = 2;\n                    continue;\n\n                case TOK.rightBracket: // allow trailing comma's\n                    nextToken();\n                    break;\n\n                case TOK.endOfFile:\n                    error(\"found `%s` instead of array initializer\", token.toChars());\n                    break;\n                }\n                break;\n            }\n            return ia;\n\n        case TOK.void_:\n            t = peek(&token);\n            if (t.value == TOK.semicolon || t.value == TOK.comma)\n            {\n                nextToken();\n                return new AST.VoidInitializer(loc);\n            }\n            goto Lexpression;\n\n        default:\n        Lexpression:\n            e = parseAssignExp();\n            ie = new AST.ExpInitializer(loc, e);\n            return ie;\n        }\n    }\n\n    /*****************************************\n     * Parses default argument initializer expression that is an assign expression,\n     * with special handling for __FILE__, __FILE_DIR__, __LINE__, __MODULE__, __FUNCTION__, and __PRETTY_FUNCTION__.\n     */\n    AST.Expression parseDefaultInitExp()\n    {\n        if (token.value == TOK.file || token.value == TOK.fileFullPath || token.value == TOK.line\n            || token.value == TOK.moduleString || token.value == TOK.functionString || token.value == TOK.prettyFunction)\n        {\n            Token* t = peek(&token);\n            if (t.value == TOK.comma || t.value == TOK.rightParentheses)\n            {\n                AST.Expression e = null;\n                if (token.value == TOK.file)\n                    e = new AST.FileInitExp(token.loc, TOK.file);\n                else if (token.value == TOK.fileFullPath)\n                    e = new AST.FileInitExp(token.loc, TOK.fileFullPath);\n                else if (token.value == TOK.line)\n                    e = new AST.LineInitExp(token.loc);\n                else if (token.value == TOK.moduleString)\n                    e = new AST.ModuleInitExp(token.loc);\n                else if (token.value == TOK.functionString)\n                    e = new AST.FuncInitExp(token.loc);\n                else if (token.value == TOK.prettyFunction)\n                    e = new AST.PrettyFuncInitExp(token.loc);\n                else\n                    assert(0);\n                nextToken();\n                return e;\n            }\n        }\n        AST.Expression e = parseAssignExp();\n        return e;\n    }\n\n    void check(Loc loc, TOK value)\n    {\n        if (token.value != value)\n            error(loc, \"found `%s` when expecting `%s`\", token.toChars(), Token.toChars(value));\n        nextToken();\n    }\n\n    void check(TOK value)\n    {\n        check(token.loc, value);\n    }\n\n    void check(TOK value, const(char)* string)\n    {\n        if (token.value != value)\n            error(\"found `%s` when expecting `%s` following %s\", token.toChars(), Token.toChars(value), string);\n        nextToken();\n    }\n\n    void checkParens(TOK value, AST.Expression e)\n    {\n        if (precedence[e.op] == PREC.rel && !e.parens)\n            error(e.loc, \"`%s` must be surrounded by parentheses when next to operator `%s`\", e.toChars(), Token.toChars(value));\n    }\n\n    ///\n    enum NeedDeclaratorId\n    {\n        no,             // Declarator part must have no identifier\n        opt,            // Declarator part identifier is optional\n        must,           // Declarator part must have identifier\n        mustIfDstyle,   // Declarator part must have identifier, but don't recognize old C-style syntax\n    }\n\n    /************************************\n     * Determine if the scanner is sitting on the start of a declaration.\n     * Params:\n     *      t       = current token of the scanner\n     *      needId  = flag with additional requirements for a declaration\n     *      endtok  = ending token\n     *      pt      = will be set ending token (if not null)\n     * Output:\n     *      true if the token `t` is a declaration, false otherwise\n     */\n    bool isDeclaration(Token* t, NeedDeclaratorId needId, TOK endtok, Token** pt)\n    {\n        //printf(\"isDeclaration(needId = %d)\\n\", needId);\n        int haveId = 0;\n        int haveTpl = 0;\n\n        while (1)\n        {\n            if ((t.value == TOK.const_ || t.value == TOK.immutable_ || t.value == TOK.inout_ || t.value == TOK.shared_) && peek(t).value != TOK.leftParentheses)\n            {\n                /* const type\n                 * immutable type\n                 * shared type\n                 * wild type\n                 */\n                t = peek(t);\n                continue;\n            }\n            break;\n        }\n\n        if (!isBasicType(&t))\n        {\n            goto Lisnot;\n        }\n        if (!isDeclarator(&t, &haveId, &haveTpl, endtok, needId != NeedDeclaratorId.mustIfDstyle))\n            goto Lisnot;\n        if ((needId == NeedDeclaratorId.no && !haveId) ||\n            (needId == NeedDeclaratorId.opt) ||\n            (needId == NeedDeclaratorId.must && haveId) ||\n            (needId == NeedDeclaratorId.mustIfDstyle && haveId))\n        {\n            if (pt)\n                *pt = t;\n            goto Lis;\n        }\n        else\n            goto Lisnot;\n\n    Lis:\n        //printf(\"\\tis declaration, t = %s\\n\", t.toChars());\n        return true;\n\n    Lisnot:\n        //printf(\"\\tis not declaration\\n\");\n        return false;\n    }\n\n    bool isBasicType(Token** pt)\n    {\n        // This code parallels parseBasicType()\n        Token* t = *pt;\n        switch (t.value)\n        {\n        case TOK.wchar_:\n        case TOK.dchar_:\n        case TOK.bool_:\n        case TOK.char_:\n        case TOK.int8:\n        case TOK.uns8:\n        case TOK.int16:\n        case TOK.uns16:\n        case TOK.int32:\n        case TOK.uns32:\n        case TOK.int64:\n        case TOK.uns64:\n        case TOK.int128:\n        case TOK.uns128:\n        case TOK.float32:\n        case TOK.float64:\n        case TOK.float80:\n        case TOK.imaginary32:\n        case TOK.imaginary64:\n        case TOK.imaginary80:\n        case TOK.complex32:\n        case TOK.complex64:\n        case TOK.complex80:\n        case TOK.void_:\n            t = peek(t);\n            break;\n\n        case TOK.identifier:\n        L5:\n            t = peek(t);\n            if (t.value == TOK.not)\n            {\n                goto L4;\n            }\n            goto L3;\n            while (1)\n            {\n            L2:\n                t = peek(t);\n            L3:\n                if (t.value == TOK.dot)\n                {\n                Ldot:\n                    t = peek(t);\n                    if (t.value != TOK.identifier)\n                        goto Lfalse;\n                    t = peek(t);\n                    if (t.value != TOK.not)\n                        goto L3;\n                L4:\n                    /* Seen a !\n                     * Look for:\n                     * !( args ), !identifier, etc.\n                     */\n                    t = peek(t);\n                    switch (t.value)\n                    {\n                    case TOK.identifier:\n                        goto L5;\n\n                    case TOK.leftParentheses:\n                        if (!skipParens(t, &t))\n                            goto Lfalse;\n                        goto L3;\n\n                    case TOK.wchar_:\n                    case TOK.dchar_:\n                    case TOK.bool_:\n                    case TOK.char_:\n                    case TOK.int8:\n                    case TOK.uns8:\n                    case TOK.int16:\n                    case TOK.uns16:\n                    case TOK.int32:\n                    case TOK.uns32:\n                    case TOK.int64:\n                    case TOK.uns64:\n                    case TOK.int128:\n                    case TOK.uns128:\n                    case TOK.float32:\n                    case TOK.float64:\n                    case TOK.float80:\n                    case TOK.imaginary32:\n                    case TOK.imaginary64:\n                    case TOK.imaginary80:\n                    case TOK.complex32:\n                    case TOK.complex64:\n                    case TOK.complex80:\n                    case TOK.void_:\n                    case TOK.int32Literal:\n                    case TOK.uns32Literal:\n                    case TOK.int64Literal:\n                    case TOK.uns64Literal:\n                    case TOK.int128Literal:\n                    case TOK.uns128Literal:\n                    case TOK.float32Literal:\n                    case TOK.float64Literal:\n                    case TOK.float80Literal:\n                    case TOK.imaginary32Literal:\n                    case TOK.imaginary64Literal:\n                    case TOK.imaginary80Literal:\n                    case TOK.null_:\n                    case TOK.true_:\n                    case TOK.false_:\n                    case TOK.charLiteral:\n                    case TOK.wcharLiteral:\n                    case TOK.dcharLiteral:\n                    case TOK.string_:\n                    case TOK.hexadecimalString:\n                    case TOK.file:\n                    case TOK.fileFullPath:\n                    case TOK.line:\n                    case TOK.moduleString:\n                    case TOK.functionString:\n                    case TOK.prettyFunction:\n                        goto L2;\n\n                    default:\n                        goto Lfalse;\n                    }\n                }\n                else\n                    break;\n            }\n            break;\n\n        case TOK.dot:\n            goto Ldot;\n\n        case TOK.typeof_:\n        case TOK.vector:\n            /* typeof(exp).identifier...\n             */\n            t = peek(t);\n            if (!skipParens(t, &t))\n                goto Lfalse;\n            goto L3;\n\n        case TOK.const_:\n        case TOK.immutable_:\n        case TOK.shared_:\n        case TOK.inout_:\n            // const(type)  or  immutable(type)  or  shared(type)  or  wild(type)\n            t = peek(t);\n            if (t.value != TOK.leftParentheses)\n                goto Lfalse;\n            t = peek(t);\n            if (!isDeclaration(t, NeedDeclaratorId.no, TOK.rightParentheses, &t))\n            {\n                goto Lfalse;\n            }\n            t = peek(t);\n            break;\n\n        default:\n            goto Lfalse;\n        }\n        *pt = t;\n        //printf(\"is\\n\");\n        return true;\n\n    Lfalse:\n        //printf(\"is not\\n\");\n        return false;\n    }\n\n    bool isDeclarator(Token** pt, int* haveId, int* haveTpl, TOK endtok, bool allowAltSyntax = true)\n    {\n        // This code parallels parseDeclarator()\n        Token* t = *pt;\n        int parens;\n\n        //printf(\"Parser::isDeclarator() %s\\n\", t.toChars());\n        if (t.value == TOK.assign)\n            return false;\n\n        while (1)\n        {\n            parens = false;\n            switch (t.value)\n            {\n            case TOK.mul:\n            //case TOK.and:\n                t = peek(t);\n                continue;\n\n            case TOK.leftBracket:\n                t = peek(t);\n                if (t.value == TOK.rightBracket)\n                {\n                    t = peek(t);\n                }\n                else if (isDeclaration(t, NeedDeclaratorId.no, TOK.rightBracket, &t))\n                {\n                    // It's an associative array declaration\n                    t = peek(t);\n\n                    // ...[type].ident\n                    if (t.value == TOK.dot && peek(t).value == TOK.identifier)\n                    {\n                        t = peek(t);\n                        t = peek(t);\n                    }\n                }\n                else\n                {\n                    // [ expression ]\n                    // [ expression .. expression ]\n                    if (!isExpression(&t))\n                        return false;\n                    if (t.value == TOK.slice)\n                    {\n                        t = peek(t);\n                        if (!isExpression(&t))\n                            return false;\n                        if (t.value != TOK.rightBracket)\n                            return false;\n                        t = peek(t);\n                    }\n                    else\n                    {\n                        if (t.value != TOK.rightBracket)\n                            return false;\n                        t = peek(t);\n                        // ...[index].ident\n                        if (t.value == TOK.dot && peek(t).value == TOK.identifier)\n                        {\n                            t = peek(t);\n                            t = peek(t);\n                        }\n                    }\n                }\n                continue;\n\n            case TOK.identifier:\n                if (*haveId)\n                    return false;\n                *haveId = true;\n                t = peek(t);\n                break;\n\n            case TOK.leftParentheses:\n                if (!allowAltSyntax)\n                    return false;   // Do not recognize C-style declarations.\n\n                t = peek(t);\n                if (t.value == TOK.rightParentheses)\n                    return false; // () is not a declarator\n\n                /* Regard ( identifier ) as not a declarator\n                 * BUG: what about ( *identifier ) in\n                 *      f(*p)(x);\n                 * where f is a class instance with overloaded () ?\n                 * Should we just disallow C-style function pointer declarations?\n                 */\n                if (t.value == TOK.identifier)\n                {\n                    Token* t2 = peek(t);\n                    if (t2.value == TOK.rightParentheses)\n                        return false;\n                }\n\n                if (!isDeclarator(&t, haveId, null, TOK.rightParentheses))\n                    return false;\n                t = peek(t);\n                parens = true;\n                break;\n\n            case TOK.delegate_:\n            case TOK.function_:\n                t = peek(t);\n                if (!isParameters(&t))\n                    return false;\n                skipAttributes(t, &t);\n                continue;\n\n            default:\n                break;\n            }\n            break;\n        }\n\n        while (1)\n        {\n            switch (t.value)\n            {\n                static if (CARRAYDECL)\n                {\n                case TOK.leftBracket:\n                    parens = false;\n                    t = peek(t);\n                    if (t.value == TOK.rightBracket)\n                    {\n                        t = peek(t);\n                    }\n                    else if (isDeclaration(t, NeedDeclaratorId.no, TOK.rightBracket, &t))\n                    {\n                        // It's an associative array declaration\n                        t = peek(t);\n                    }\n                    else\n                    {\n                        // [ expression ]\n                        if (!isExpression(&t))\n                            return false;\n                        if (t.value != TOK.rightBracket)\n                            return false;\n                        t = peek(t);\n                    }\n                    continue;\n                }\n\n            case TOK.leftParentheses:\n                parens = false;\n                if (Token* tk = peekPastParen(t))\n                {\n                    if (tk.value == TOK.leftParentheses)\n                    {\n                        if (!haveTpl)\n                            return false;\n                        *haveTpl = 1;\n                        t = tk;\n                    }\n                    else if (tk.value == TOK.assign)\n                    {\n                        if (!haveTpl)\n                            return false;\n                        *haveTpl = 1;\n                        *pt = tk;\n                        return true;\n                    }\n                }\n                if (!isParameters(&t))\n                    return false;\n                while (1)\n                {\n                    switch (t.value)\n                    {\n                    case TOK.const_:\n                    case TOK.immutable_:\n                    case TOK.shared_:\n                    case TOK.inout_:\n                    case TOK.pure_:\n                    case TOK.nothrow_:\n                    case TOK.return_:\n                    case TOK.scope_:\n                        t = peek(t);\n                        continue;\n\n                    case TOK.at:\n                        t = peek(t); // skip '@'\n                        t = peek(t); // skip identifier\n                        continue;\n\n                    default:\n                        break;\n                    }\n                    break;\n                }\n                continue;\n\n            // Valid tokens that follow a declaration\n            case TOK.rightParentheses:\n            case TOK.rightBracket:\n            case TOK.assign:\n            case TOK.comma:\n            case TOK.dotDotDot:\n            case TOK.semicolon:\n            case TOK.leftCurly:\n            case TOK.in_:\n            case TOK.out_:\n            case TOK.do_:\n                // The !parens is to disallow unnecessary parentheses\n                if (!parens && (endtok == TOK.reserved || endtok == t.value))\n                {\n                    *pt = t;\n                    return true;\n                }\n                return false;\n\n            case TOK.identifier:\n                if (t.ident == Id._body)\n                    goto case TOK.do_;\n                goto default;\n\n            case TOK.if_:\n                return haveTpl ? true : false;\n\n            default:\n                return false;\n            }\n        }\n        assert(0);\n    }\n\n    bool isParameters(Token** pt)\n    {\n        // This code parallels parseParameters()\n        Token* t = *pt;\n\n        //printf(\"isParameters()\\n\");\n        if (t.value != TOK.leftParentheses)\n            return false;\n\n        t = peek(t);\n        for (; 1; t = peek(t))\n        {\n        L1:\n            switch (t.value)\n            {\n            case TOK.rightParentheses:\n                break;\n\n            case TOK.dotDotDot:\n                t = peek(t);\n                break;\n\n            case TOK.in_:\n            case TOK.out_:\n            case TOK.ref_:\n            case TOK.lazy_:\n            case TOK.scope_:\n            case TOK.final_:\n            case TOK.auto_:\n            case TOK.return_:\n                continue;\n\n            case TOK.const_:\n            case TOK.immutable_:\n            case TOK.shared_:\n            case TOK.inout_:\n                t = peek(t);\n                if (t.value == TOK.leftParentheses)\n                {\n                    t = peek(t);\n                    if (!isDeclaration(t, NeedDeclaratorId.no, TOK.rightParentheses, &t))\n                        return false;\n                    t = peek(t); // skip past closing ')'\n                    goto L2;\n                }\n                goto L1;\n\n                version (none)\n                {\n                case TOK.static_:\n                    continue;\n                case TOK.auto_:\n                case TOK.alias_:\n                    t = peek(t);\n                    if (t.value == TOK.identifier)\n                        t = peek(t);\n                    if (t.value == TOK.assign)\n                    {\n                        t = peek(t);\n                        if (!isExpression(&t))\n                            return false;\n                    }\n                    goto L3;\n                }\n\n            default:\n                {\n                    if (!isBasicType(&t))\n                        return false;\n                L2:\n                    int tmp = false;\n                    if (t.value != TOK.dotDotDot && !isDeclarator(&t, &tmp, null, TOK.reserved))\n                        return false;\n                    if (t.value == TOK.assign)\n                    {\n                        t = peek(t);\n                        if (!isExpression(&t))\n                            return false;\n                    }\n                    if (t.value == TOK.dotDotDot)\n                    {\n                        t = peek(t);\n                        break;\n                    }\n                }\n                if (t.value == TOK.comma)\n                {\n                    continue;\n                }\n                break;\n            }\n            break;\n        }\n        if (t.value != TOK.rightParentheses)\n            return false;\n        t = peek(t);\n        *pt = t;\n        return true;\n    }\n\n    bool isExpression(Token** pt)\n    {\n        // This is supposed to determine if something is an expression.\n        // What it actually does is scan until a closing right bracket\n        // is found.\n\n        Token* t = *pt;\n        int brnest = 0;\n        int panest = 0;\n        int curlynest = 0;\n\n        for (;; t = peek(t))\n        {\n            switch (t.value)\n            {\n            case TOK.leftBracket:\n                brnest++;\n                continue;\n\n            case TOK.rightBracket:\n                if (--brnest >= 0)\n                    continue;\n                break;\n\n            case TOK.leftParentheses:\n                panest++;\n                continue;\n\n            case TOK.comma:\n                if (brnest || panest)\n                    continue;\n                break;\n\n            case TOK.rightParentheses:\n                if (--panest >= 0)\n                    continue;\n                break;\n\n            case TOK.leftCurly:\n                curlynest++;\n                continue;\n\n            case TOK.rightCurly:\n                if (--curlynest >= 0)\n                    continue;\n                return false;\n\n            case TOK.slice:\n                if (brnest)\n                    continue;\n                break;\n\n            case TOK.semicolon:\n                if (curlynest)\n                    continue;\n                return false;\n\n            case TOK.endOfFile:\n                return false;\n\n            default:\n                continue;\n            }\n            break;\n        }\n\n        *pt = t;\n        return true;\n    }\n\n    /*******************************************\n     * Skip parens, brackets.\n     * Input:\n     *      t is on opening $(LPAREN)\n     * Output:\n     *      *pt is set to closing token, which is '$(RPAREN)' on success\n     * Returns:\n     *      true    successful\n     *      false   some parsing error\n     */\n    bool skipParens(Token* t, Token** pt)\n    {\n        if (t.value != TOK.leftParentheses)\n            return false;\n\n        int parens = 0;\n\n        while (1)\n        {\n            switch (t.value)\n            {\n            case TOK.leftParentheses:\n                parens++;\n                break;\n\n            case TOK.rightParentheses:\n                parens--;\n                if (parens < 0)\n                    goto Lfalse;\n                if (parens == 0)\n                    goto Ldone;\n                break;\n\n            case TOK.endOfFile:\n                goto Lfalse;\n\n            default:\n                break;\n            }\n            t = peek(t);\n        }\n    Ldone:\n        if (pt)\n            *pt = peek(t); // skip found rparen\n        return true;\n\n    Lfalse:\n        return false;\n    }\n\n    bool skipParensIf(Token* t, Token** pt)\n    {\n        if (t.value != TOK.leftParentheses)\n        {\n            if (pt)\n                *pt = t;\n            return true;\n        }\n        return skipParens(t, pt);\n    }\n\n    /*******************************************\n     * Skip attributes.\n     * Input:\n     *      t is on a candidate attribute\n     * Output:\n     *      *pt is set to first non-attribute token on success\n     * Returns:\n     *      true    successful\n     *      false   some parsing error\n     */\n    bool skipAttributes(Token* t, Token** pt)\n    {\n        while (1)\n        {\n            switch (t.value)\n            {\n            case TOK.const_:\n            case TOK.immutable_:\n            case TOK.shared_:\n            case TOK.inout_:\n            case TOK.final_:\n            case TOK.auto_:\n            case TOK.scope_:\n            case TOK.override_:\n            case TOK.abstract_:\n            case TOK.synchronized_:\n                break;\n\n            case TOK.deprecated_:\n                if (peek(t).value == TOK.leftParentheses)\n                {\n                    t = peek(t);\n                    if (!skipParens(t, &t))\n                        goto Lerror;\n                    // t is on the next of closing parenthesis\n                    continue;\n                }\n                break;\n\n            case TOK.nothrow_:\n            case TOK.pure_:\n            case TOK.ref_:\n            case TOK.gshared:\n            case TOK.return_:\n            //case TOK.manifest:\n                break;\n\n            case TOK.at:\n                t = peek(t);\n                if (t.value == TOK.identifier)\n                {\n                    /* @identifier\n                     * @identifier!arg\n                     * @identifier!(arglist)\n                     * any of the above followed by (arglist)\n                     * @predefined_attribute\n                     */\n                    if (t.ident == Id.property || t.ident == Id.nogc || t.ident == Id.safe || t.ident == Id.trusted || t.ident == Id.system || t.ident == Id.disable)\n                        break;\n                    t = peek(t);\n                    if (t.value == TOK.not)\n                    {\n                        t = peek(t);\n                        if (t.value == TOK.leftParentheses)\n                        {\n                            // @identifier!(arglist)\n                            if (!skipParens(t, &t))\n                                goto Lerror;\n                            // t is on the next of closing parenthesis\n                        }\n                        else\n                        {\n                            // @identifier!arg\n                            // Do low rent skipTemplateArgument\n                            if (t.value == TOK.vector)\n                            {\n                                // identifier!__vector(type)\n                                t = peek(t);\n                                if (!skipParens(t, &t))\n                                    goto Lerror;\n                            }\n                            else\n                                t = peek(t);\n                        }\n                    }\n                    if (t.value == TOK.leftParentheses)\n                    {\n                        if (!skipParens(t, &t))\n                            goto Lerror;\n                        // t is on the next of closing parenthesis\n                        continue;\n                    }\n                    continue;\n                }\n                if (t.value == TOK.leftParentheses)\n                {\n                    // @( ArgumentList )\n                    if (!skipParens(t, &t))\n                        goto Lerror;\n                    // t is on the next of closing parenthesis\n                    continue;\n                }\n                goto Lerror;\n\n            default:\n                goto Ldone;\n            }\n            t = peek(t);\n        }\n    Ldone:\n        if (pt)\n            *pt = t;\n        return true;\n\n    Lerror:\n        return false;\n    }\n\n    AST.Expression parseExpression()\n    {\n        auto loc = token.loc;\n\n        //printf(\"Parser::parseExpression() loc = %d\\n\", loc.linnum);\n        auto e = parseAssignExp();\n        while (token.value == TOK.comma)\n        {\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.CommaExp(loc, e, e2, false);\n            loc = token.loc;\n        }\n        return e;\n    }\n\n    /********************************* Expression Parser ***************************/\n\n    AST.Expression parsePrimaryExp()\n    {\n        AST.Expression e;\n        AST.Type t;\n        Identifier id;\n        const loc = token.loc;\n\n        //printf(\"parsePrimaryExp(): loc = %d\\n\", loc.linnum);\n        switch (token.value)\n        {\n        case TOK.identifier:\n            {\n                Token* t1 = peek(&token);\n                Token* t2 = peek(t1);\n                if (t1.value == TOK.min && t2.value == TOK.greaterThan)\n                {\n                    // skip ident.\n                    nextToken();\n                    nextToken();\n                    nextToken();\n                    error(\"use `.` for member lookup, not `->`\");\n                    goto Lerr;\n                }\n\n                if (peekNext() == TOK.goesTo)\n                    goto case_delegate;\n\n                id = token.ident;\n                nextToken();\n                TOK save;\n                if (token.value == TOK.not && (save = peekNext()) != TOK.is_ && save != TOK.in_)\n                {\n                    // identifier!(template-argument-list)\n                    auto tempinst = new AST.TemplateInstance(loc, id, parseTemplateArguments());\n                    e = new AST.ScopeExp(loc, tempinst);\n                }\n                else\n                    e = new AST.IdentifierExp(loc, id);\n                break;\n            }\n        case TOK.dollar:\n            if (!inBrackets)\n                error(\"`$` is valid only inside [] of index or slice\");\n            e = new AST.DollarExp(loc);\n            nextToken();\n            break;\n\n        case TOK.dot:\n            // Signal global scope '.' operator with \"\" identifier\n            e = new AST.IdentifierExp(loc, Id.empty);\n            break;\n\n        case TOK.this_:\n            e = new AST.ThisExp(loc);\n            nextToken();\n            break;\n\n        case TOK.super_:\n            e = new AST.SuperExp(loc);\n            nextToken();\n            break;\n\n        case TOK.int32Literal:\n            e = new AST.IntegerExp(loc, cast(d_int32)token.intvalue, AST.Type.tint32);\n            nextToken();\n            break;\n\n        case TOK.uns32Literal:\n            e = new AST.IntegerExp(loc, cast(d_uns32)token.unsvalue, AST.Type.tuns32);\n            nextToken();\n            break;\n\n        case TOK.int64Literal:\n            e = new AST.IntegerExp(loc, token.intvalue, AST.Type.tint64);\n            nextToken();\n            break;\n\n        case TOK.uns64Literal:\n            e = new AST.IntegerExp(loc, token.unsvalue, AST.Type.tuns64);\n            nextToken();\n            break;\n\n        case TOK.float32Literal:\n            e = new AST.RealExp(loc, token.floatvalue, AST.Type.tfloat32);\n            nextToken();\n            break;\n\n        case TOK.float64Literal:\n            e = new AST.RealExp(loc, token.floatvalue, AST.Type.tfloat64);\n            nextToken();\n            break;\n\n        case TOK.float80Literal:\n            e = new AST.RealExp(loc, token.floatvalue, AST.Type.tfloat80);\n            nextToken();\n            break;\n\n        case TOK.imaginary32Literal:\n            e = new AST.RealExp(loc, token.floatvalue, AST.Type.timaginary32);\n            nextToken();\n            break;\n\n        case TOK.imaginary64Literal:\n            e = new AST.RealExp(loc, token.floatvalue, AST.Type.timaginary64);\n            nextToken();\n            break;\n\n        case TOK.imaginary80Literal:\n            e = new AST.RealExp(loc, token.floatvalue, AST.Type.timaginary80);\n            nextToken();\n            break;\n\n        case TOK.null_:\n            e = new AST.NullExp(loc);\n            nextToken();\n            break;\n\n        case TOK.file:\n            {\n                const(char)* s = loc.filename ? loc.filename : mod.ident.toChars();\n                e = new AST.StringExp(loc, cast(char*)s);\n                nextToken();\n                break;\n            }\n        case TOK.fileFullPath:\n            assert(loc.isValid(), \"__FILE_FULL_PATH__ does not work with an invalid location\");\n            e = new AST.StringExp(loc, cast(char*)FileName.toAbsolute(loc.filename));\n            nextToken();\n            break;\n\n        case TOK.line:\n            e = new AST.IntegerExp(loc, loc.linnum, AST.Type.tint32);\n            nextToken();\n            break;\n\n        case TOK.moduleString:\n            {\n                const(char)* s = md ? md.toChars() : mod.toChars();\n                e = new AST.StringExp(loc, cast(char*)s);\n                nextToken();\n                break;\n            }\n        case TOK.functionString:\n            e = new AST.FuncInitExp(loc);\n            nextToken();\n            break;\n\n        case TOK.prettyFunction:\n            e = new AST.PrettyFuncInitExp(loc);\n            nextToken();\n            break;\n\n        case TOK.true_:\n            e = new AST.IntegerExp(loc, 1, AST.Type.tbool);\n            nextToken();\n            break;\n\n        case TOK.false_:\n            e = new AST.IntegerExp(loc, 0, AST.Type.tbool);\n            nextToken();\n            break;\n\n        case TOK.charLiteral:\n            e = new AST.IntegerExp(loc, cast(d_uns8)token.unsvalue, AST.Type.tchar);\n            nextToken();\n            break;\n\n        case TOK.wcharLiteral:\n            e = new AST.IntegerExp(loc, cast(d_uns16)token.unsvalue, AST.Type.twchar);\n            nextToken();\n            break;\n\n        case TOK.dcharLiteral:\n            e = new AST.IntegerExp(loc, cast(d_uns32)token.unsvalue, AST.Type.tdchar);\n            nextToken();\n            break;\n\n        case TOK.string_:\n        case TOK.hexadecimalString:\n            {\n                // cat adjacent strings\n                auto s = token.ustring;\n                auto len = token.len;\n                auto postfix = token.postfix;\n                while (1)\n                {\n                    const prev = token;\n                    nextToken();\n                    if (token.value == TOK.string_ || token.value == TOK.hexadecimalString)\n                    {\n                        if (token.postfix)\n                        {\n                            if (token.postfix != postfix)\n                                error(\"mismatched string literal postfixes `'%c'` and `'%c'`\", postfix, token.postfix);\n                            postfix = token.postfix;\n                        }\n\n                        error(\"Implicit string concatenation is deprecated, use %s ~ %s instead\",\n                                    prev.toChars(), token.toChars());\n\n                        const len1 = len;\n                        const len2 = token.len;\n                        len = len1 + len2;\n                        auto s2 = cast(char*)mem.xmalloc(len * char.sizeof);\n                        memcpy(s2, s, len1 * char.sizeof);\n                        memcpy(s2 + len1, token.ustring, len2 * char.sizeof);\n                        s = s2;\n                    }\n                    else\n                        break;\n                }\n                e = new AST.StringExp(loc, cast(char*)s, len, postfix);\n                break;\n            }\n        case TOK.void_:\n            t = AST.Type.tvoid;\n            goto LabelX;\n\n        case TOK.int8:\n            t = AST.Type.tint8;\n            goto LabelX;\n\n        case TOK.uns8:\n            t = AST.Type.tuns8;\n            goto LabelX;\n\n        case TOK.int16:\n            t = AST.Type.tint16;\n            goto LabelX;\n\n        case TOK.uns16:\n            t = AST.Type.tuns16;\n            goto LabelX;\n\n        case TOK.int32:\n            t = AST.Type.tint32;\n            goto LabelX;\n\n        case TOK.uns32:\n            t = AST.Type.tuns32;\n            goto LabelX;\n\n        case TOK.int64:\n            t = AST.Type.tint64;\n            goto LabelX;\n\n        case TOK.uns64:\n            t = AST.Type.tuns64;\n            goto LabelX;\n\n        case TOK.int128:\n            t = AST.Type.tint128;\n            goto LabelX;\n\n        case TOK.uns128:\n            t = AST.Type.tuns128;\n            goto LabelX;\n\n        case TOK.float32:\n            t = AST.Type.tfloat32;\n            goto LabelX;\n\n        case TOK.float64:\n            t = AST.Type.tfloat64;\n            goto LabelX;\n\n        case TOK.float80:\n            t = AST.Type.tfloat80;\n            goto LabelX;\n\n        case TOK.imaginary32:\n            t = AST.Type.timaginary32;\n            goto LabelX;\n\n        case TOK.imaginary64:\n            t = AST.Type.timaginary64;\n            goto LabelX;\n\n        case TOK.imaginary80:\n            t = AST.Type.timaginary80;\n            goto LabelX;\n\n        case TOK.complex32:\n            t = AST.Type.tcomplex32;\n            goto LabelX;\n\n        case TOK.complex64:\n            t = AST.Type.tcomplex64;\n            goto LabelX;\n\n        case TOK.complex80:\n            t = AST.Type.tcomplex80;\n            goto LabelX;\n\n        case TOK.bool_:\n            t = AST.Type.tbool;\n            goto LabelX;\n\n        case TOK.char_:\n            t = AST.Type.tchar;\n            goto LabelX;\n\n        case TOK.wchar_:\n            t = AST.Type.twchar;\n            goto LabelX;\n\n        case TOK.dchar_:\n            t = AST.Type.tdchar;\n            goto LabelX;\n        LabelX:\n            nextToken();\n            if (token.value == TOK.leftParentheses)\n            {\n                e = new AST.TypeExp(loc, t);\n                e = new AST.CallExp(loc, e, parseArguments());\n                break;\n            }\n            check(TOK.dot, t.toChars());\n            if (token.value != TOK.identifier)\n            {\n                error(\"found `%s` when expecting identifier following `%s`.\", token.toChars(), t.toChars());\n                goto Lerr;\n            }\n            e = new AST.DotIdExp(loc, new AST.TypeExp(loc, t), token.ident);\n            nextToken();\n            break;\n\n        case TOK.typeof_:\n            {\n                t = parseTypeof();\n                e = new AST.TypeExp(loc, t);\n                break;\n            }\n        case TOK.vector:\n            {\n                t = parseVector();\n                e = new AST.TypeExp(loc, t);\n                break;\n            }\n        case TOK.typeid_:\n            {\n                nextToken();\n                check(TOK.leftParentheses, \"`typeid`\");\n                RootObject o;\n                if (isDeclaration(&token, NeedDeclaratorId.no, TOK.reserved, null))\n                {\n                    // argument is a type\n                    o = parseType();\n                }\n                else\n                {\n                    // argument is an expression\n                    o = parseAssignExp();\n                }\n                check(TOK.rightParentheses);\n                e = new AST.TypeidExp(loc, o);\n                break;\n            }\n        case TOK.traits:\n            {\n                /* __traits(identifier, args...)\n                 */\n                Identifier ident;\n                AST.Objects* args = null;\n\n                nextToken();\n                check(TOK.leftParentheses);\n                if (token.value != TOK.identifier)\n                {\n                    error(\"`__traits(identifier, args...)` expected\");\n                    goto Lerr;\n                }\n                ident = token.ident;\n                nextToken();\n                if (token.value == TOK.comma)\n                    args = parseTemplateArgumentList(); // __traits(identifier, args...)\n                else\n                    check(TOK.rightParentheses); // __traits(identifier)\n\n                e = new AST.TraitsExp(loc, ident, args);\n                break;\n            }\n        case TOK.is_:\n            {\n                AST.Type targ;\n                Identifier ident = null;\n                AST.Type tspec = null;\n                TOK tok = TOK.reserved;\n                TOK tok2 = TOK.reserved;\n                AST.TemplateParameters* tpl = null;\n\n                nextToken();\n                if (token.value == TOK.leftParentheses)\n                {\n                    nextToken();\n                    targ = parseType(&ident);\n                    if (token.value == TOK.colon || token.value == TOK.equal)\n                    {\n                        tok = token.value;\n                        nextToken();\n                        if (tok == TOK.equal && (token.value == TOK.struct_ || token.value == TOK.union_\n                            || token.value == TOK.class_ || token.value == TOK.super_ || token.value == TOK.enum_\n                            || token.value == TOK.interface_ || token.value == TOK.argumentTypes\n                            || token.value == TOK.parameters || token.value == TOK.const_ && peek(&token).value == TOK.rightParentheses\n                            || token.value == TOK.immutable_ && peek(&token).value == TOK.rightParentheses\n                            || token.value == TOK.shared_ && peek(&token).value == TOK.rightParentheses\n                            || token.value == TOK.inout_ && peek(&token).value == TOK.rightParentheses || token.value == TOK.function_\n                            || token.value == TOK.delegate_ || token.value == TOK.return_\n                            || (token.value == TOK.vector && peek(&token).value == TOK.rightParentheses)))\n                        {\n                            tok2 = token.value;\n                            nextToken();\n                        }\n                        else\n                        {\n                            tspec = parseType();\n                        }\n                    }\n                    if (tspec)\n                    {\n                        if (token.value == TOK.comma)\n                            tpl = parseTemplateParameterList(1);\n                        else\n                        {\n                            tpl = new AST.TemplateParameters();\n                            check(TOK.rightParentheses);\n                        }\n                    }\n                    else\n                        check(TOK.rightParentheses);\n                }\n                else\n                {\n                    error(\"`type identifier : specialization` expected following `is`\");\n                    goto Lerr;\n                }\n                e = new AST.IsExp(loc, targ, ident, tok, tspec, tok2, tpl);\n                break;\n            }\n        case TOK.assert_:\n            {\n                // https://dlang.org/spec/expression.html#assert_expressions\n                AST.Expression msg = null;\n\n                nextToken();\n                check(TOK.leftParentheses, \"`assert`\");\n                e = parseAssignExp();\n                if (token.value == TOK.comma)\n                {\n                    nextToken();\n                    if (token.value != TOK.rightParentheses)\n                    {\n                        msg = parseAssignExp();\n                        if (token.value == TOK.comma)\n                            nextToken();\n                    }\n                }\n                check(TOK.rightParentheses);\n                e = new AST.AssertExp(loc, e, msg);\n                break;\n            }\n        case TOK.mixin_:\n            {\n                // https://dlang.org/spec/expression.html#mixin_expressions\n                nextToken();\n                if (token.value != TOK.leftParentheses)\n                    error(\"found `%s` when expecting `%s` following %s\", token.toChars(), Token.toChars(TOK.leftParentheses), \"`mixin`\".ptr);\n                auto exps = parseArguments();\n                e = new AST.CompileExp(loc, exps);\n                break;\n            }\n        case TOK.import_:\n            {\n                nextToken();\n                check(TOK.leftParentheses, \"`import`\");\n                e = parseAssignExp();\n                check(TOK.rightParentheses);\n                e = new AST.ImportExp(loc, e);\n                break;\n            }\n        case TOK.new_:\n            e = parseNewExp(null);\n            break;\n\n        case TOK.leftParentheses:\n            {\n                Token* tk = peekPastParen(&token);\n                if (skipAttributes(tk, &tk) && (tk.value == TOK.goesTo || tk.value == TOK.leftCurly))\n                {\n                    // (arguments) => expression\n                    // (arguments) { statements... }\n                    goto case_delegate;\n                }\n\n                // ( expression )\n                nextToken();\n                e = parseExpression();\n                e.parens = 1;\n                check(loc, TOK.rightParentheses);\n                break;\n            }\n        case TOK.leftBracket:\n            {\n                /* Parse array literals and associative array literals:\n                 *  [ value, value, value ... ]\n                 *  [ key:value, key:value, key:value ... ]\n                 */\n                auto values = new AST.Expressions();\n                AST.Expressions* keys = null;\n\n                nextToken();\n                while (token.value != TOK.rightBracket && token.value != TOK.endOfFile)\n                {\n                    e = parseAssignExp();\n                    if (token.value == TOK.colon && (keys || values.dim == 0))\n                    {\n                        nextToken();\n                        if (!keys)\n                            keys = new AST.Expressions();\n                        keys.push(e);\n                        e = parseAssignExp();\n                    }\n                    else if (keys)\n                    {\n                        error(\"`key:value` expected for associative array literal\");\n                        keys = null;\n                    }\n                    values.push(e);\n                    if (token.value == TOK.rightBracket)\n                        break;\n                    check(TOK.comma);\n                }\n                check(loc, TOK.rightBracket);\n\n                if (keys)\n                    e = new AST.AssocArrayLiteralExp(loc, keys, values);\n                else\n                    e = new AST.ArrayLiteralExp(loc, null, values);\n                break;\n            }\n        case TOK.leftCurly:\n        case TOK.function_:\n        case TOK.delegate_:\n        case_delegate:\n            {\n                AST.Dsymbol s = parseFunctionLiteral();\n                e = new AST.FuncExp(loc, s);\n                break;\n            }\n        default:\n            error(\"expression expected, not `%s`\", token.toChars());\n        Lerr:\n            // Anything for e, as long as it's not NULL\n            e = new AST.IntegerExp(loc, 0, AST.Type.tint32);\n            nextToken();\n            break;\n        }\n        return e;\n    }\n\n    AST.Expression parseUnaryExp()\n    {\n        AST.Expression e;\n        const loc = token.loc;\n\n        switch (token.value)\n        {\n        case TOK.and:\n            nextToken();\n            e = parseUnaryExp();\n            e = new AST.AddrExp(loc, e);\n            break;\n\n        case TOK.plusPlus:\n            nextToken();\n            e = parseUnaryExp();\n            //e = new AddAssignExp(loc, e, new IntegerExp(loc, 1, Type::tint32));\n            e = new AST.PreExp(TOK.prePlusPlus, loc, e);\n            break;\n\n        case TOK.minusMinus:\n            nextToken();\n            e = parseUnaryExp();\n            //e = new MinAssignExp(loc, e, new IntegerExp(loc, 1, Type::tint32));\n            e = new AST.PreExp(TOK.preMinusMinus, loc, e);\n            break;\n\n        case TOK.mul:\n            nextToken();\n            e = parseUnaryExp();\n            e = new AST.PtrExp(loc, e);\n            break;\n\n        case TOK.min:\n            nextToken();\n            e = parseUnaryExp();\n            e = new AST.NegExp(loc, e);\n            break;\n\n        case TOK.add:\n            nextToken();\n            e = parseUnaryExp();\n            e = new AST.UAddExp(loc, e);\n            break;\n\n        case TOK.not:\n            nextToken();\n            e = parseUnaryExp();\n            e = new AST.NotExp(loc, e);\n            break;\n\n        case TOK.tilde:\n            nextToken();\n            e = parseUnaryExp();\n            e = new AST.ComExp(loc, e);\n            break;\n\n        case TOK.delete_:\n            nextToken();\n            e = parseUnaryExp();\n            e = new AST.DeleteExp(loc, e, false);\n            break;\n\n        case TOK.cast_: // cast(type) expression\n            {\n                nextToken();\n                check(TOK.leftParentheses);\n                /* Look for cast(), cast(const), cast(immutable),\n                 * cast(shared), cast(shared const), cast(wild), cast(shared wild)\n                 */\n                ubyte m = 0;\n                while (1)\n                {\n                    switch (token.value)\n                    {\n                    case TOK.const_:\n                        if (peekNext() == TOK.leftParentheses)\n                            break; // const as type constructor\n                        m |= AST.MODFlags.const_; // const as storage class\n                        nextToken();\n                        continue;\n\n                    case TOK.immutable_:\n                        if (peekNext() == TOK.leftParentheses)\n                            break;\n                        m |= AST.MODFlags.immutable_;\n                        nextToken();\n                        continue;\n\n                    case TOK.shared_:\n                        if (peekNext() == TOK.leftParentheses)\n                            break;\n                        m |= AST.MODFlags.shared_;\n                        nextToken();\n                        continue;\n\n                    case TOK.inout_:\n                        if (peekNext() == TOK.leftParentheses)\n                            break;\n                        m |= AST.MODFlags.wild;\n                        nextToken();\n                        continue;\n\n                    default:\n                        break;\n                    }\n                    break;\n                }\n                if (token.value == TOK.rightParentheses)\n                {\n                    nextToken();\n                    e = parseUnaryExp();\n                    e = new AST.CastExp(loc, e, m);\n                }\n                else\n                {\n                    AST.Type t = parseType(); // cast( type )\n                    t = t.addMod(m); // cast( const type )\n                    check(TOK.rightParentheses);\n                    e = parseUnaryExp();\n                    e = new AST.CastExp(loc, e, t);\n                }\n                break;\n            }\n        case TOK.inout_:\n        case TOK.shared_:\n        case TOK.const_:\n        case TOK.immutable_: // immutable(type)(arguments) / immutable(type).init\n            {\n                StorageClass stc = parseTypeCtor();\n\n                AST.Type t = parseBasicType();\n                t = t.addSTC(stc);\n\n                if (stc == 0 && token.value == TOK.dot)\n                {\n                    nextToken();\n                    if (token.value != TOK.identifier)\n                    {\n                        error(\"identifier expected following `(type)`.\");\n                        return null;\n                    }\n                    e = new AST.DotIdExp(loc, new AST.TypeExp(loc, t), token.ident);\n                    nextToken();\n                    e = parsePostExp(e);\n                }\n                else\n                {\n                    e = new AST.TypeExp(loc, t);\n                    if (token.value != TOK.leftParentheses)\n                    {\n                        error(\"`(arguments)` expected following `%s`\", t.toChars());\n                        return e;\n                    }\n                    e = new AST.CallExp(loc, e, parseArguments());\n                }\n                break;\n            }\n        case TOK.leftParentheses:\n            {\n                auto tk = peek(&token);\n                static if (CCASTSYNTAX)\n                {\n                    // If cast\n                    if (isDeclaration(tk, NeedDeclaratorId.no, TOK.rightParentheses, &tk))\n                    {\n                        tk = peek(tk); // skip over right parenthesis\n                        switch (tk.value)\n                        {\n                        case TOK.not:\n                            tk = peek(tk);\n                            if (tk.value == TOK.is_ || tk.value == TOK.in_) // !is or !in\n                                break;\n                            goto case;\n\n                        case TOK.dot:\n                        case TOK.plusPlus:\n                        case TOK.minusMinus:\n                        case TOK.delete_:\n                        case TOK.new_:\n                        case TOK.leftParentheses:\n                        case TOK.identifier:\n                        case TOK.this_:\n                        case TOK.super_:\n                        case TOK.int32Literal:\n                        case TOK.uns32Literal:\n                        case TOK.int64Literal:\n                        case TOK.uns64Literal:\n                        case TOK.int128Literal:\n                        case TOK.uns128Literal:\n                        case TOK.float32Literal:\n                        case TOK.float64Literal:\n                        case TOK.float80Literal:\n                        case TOK.imaginary32Literal:\n                        case TOK.imaginary64Literal:\n                        case TOK.imaginary80Literal:\n                        case TOK.null_:\n                        case TOK.true_:\n                        case TOK.false_:\n                        case TOK.charLiteral:\n                        case TOK.wcharLiteral:\n                        case TOK.dcharLiteral:\n                        case TOK.string_:\n                            version (none)\n                            {\n                            case TOK.tilde:\n                            case TOK.and:\n                            case TOK.mul:\n                            case TOK.min:\n                            case TOK.add:\n                            }\n                        case TOK.function_:\n                        case TOK.delegate_:\n                        case TOK.typeof_:\n                        case TOK.vector:\n                        case TOK.file:\n                        case TOK.fileFullPath:\n                        case TOK.line:\n                        case TOK.moduleString:\n                        case TOK.functionString:\n                        case TOK.prettyFunction:\n                        case TOK.wchar_:\n                        case TOK.dchar_:\n                        case TOK.bool_:\n                        case TOK.char_:\n                        case TOK.int8:\n                        case TOK.uns8:\n                        case TOK.int16:\n                        case TOK.uns16:\n                        case TOK.int32:\n                        case TOK.uns32:\n                        case TOK.int64:\n                        case TOK.uns64:\n                        case TOK.int128:\n                        case TOK.uns128:\n                        case TOK.float32:\n                        case TOK.float64:\n                        case TOK.float80:\n                        case TOK.imaginary32:\n                        case TOK.imaginary64:\n                        case TOK.imaginary80:\n                        case TOK.complex32:\n                        case TOK.complex64:\n                        case TOK.complex80:\n                        case TOK.void_:\n                            {\n                                // (type) una_exp\n                                nextToken();\n                                auto t = parseType();\n                                check(TOK.rightParentheses);\n\n                                // if .identifier\n                                // or .identifier!( ... )\n                                if (token.value == TOK.dot)\n                                {\n                                    if (peekNext() != TOK.identifier && peekNext() != TOK.new_)\n                                    {\n                                        error(\"identifier or new keyword expected following `(...)`.\");\n                                        return null;\n                                    }\n                                    e = new AST.TypeExp(loc, t);\n                                    e = parsePostExp(e);\n                                }\n                                else\n                                {\n                                    e = parseUnaryExp();\n                                    e = new AST.CastExp(loc, e, t);\n                                    error(\"C style cast illegal, use `%s`\", e.toChars());\n                                }\n                                return e;\n                            }\n                        default:\n                            break;\n                        }\n                    }\n                }\n                e = parsePrimaryExp();\n                e = parsePostExp(e);\n                break;\n            }\n        default:\n            e = parsePrimaryExp();\n            e = parsePostExp(e);\n            break;\n        }\n        assert(e);\n\n        // ^^ is right associative and has higher precedence than the unary operators\n        while (token.value == TOK.pow)\n        {\n            nextToken();\n            AST.Expression e2 = parseUnaryExp();\n            e = new AST.PowExp(loc, e, e2);\n        }\n\n        return e;\n    }\n\n    AST.Expression parsePostExp(AST.Expression e)\n    {\n        while (1)\n        {\n            const loc = token.loc;\n            switch (token.value)\n            {\n            case TOK.dot:\n                nextToken();\n                if (token.value == TOK.identifier)\n                {\n                    Identifier id = token.ident;\n\n                    nextToken();\n                    if (token.value == TOK.not && peekNext() != TOK.is_ && peekNext() != TOK.in_)\n                    {\n                        AST.Objects* tiargs = parseTemplateArguments();\n                        e = new AST.DotTemplateInstanceExp(loc, e, id, tiargs);\n                    }\n                    else\n                        e = new AST.DotIdExp(loc, e, id);\n                    continue;\n                }\n                else if (token.value == TOK.new_)\n                {\n                    e = parseNewExp(e);\n                    continue;\n                }\n                else\n                    error(\"identifier expected following `.`, not `%s`\", token.toChars());\n                break;\n\n            case TOK.plusPlus:\n                e = new AST.PostExp(TOK.plusPlus, loc, e);\n                break;\n\n            case TOK.minusMinus:\n                e = new AST.PostExp(TOK.minusMinus, loc, e);\n                break;\n\n            case TOK.leftParentheses:\n                e = new AST.CallExp(loc, e, parseArguments());\n                continue;\n\n            case TOK.leftBracket:\n                {\n                    // array dereferences:\n                    //      array[index]\n                    //      array[]\n                    //      array[lwr .. upr]\n                    AST.Expression index;\n                    AST.Expression upr;\n                    auto arguments = new AST.Expressions();\n\n                    inBrackets++;\n                    nextToken();\n                    while (token.value != TOK.rightBracket && token.value != TOK.endOfFile)\n                    {\n                        index = parseAssignExp();\n                        if (token.value == TOK.slice)\n                        {\n                            // array[..., lwr..upr, ...]\n                            nextToken();\n                            upr = parseAssignExp();\n                            arguments.push(new AST.IntervalExp(loc, index, upr));\n                        }\n                        else\n                            arguments.push(index);\n                        if (token.value == TOK.rightBracket)\n                            break;\n                        check(TOK.comma);\n                    }\n                    check(TOK.rightBracket);\n                    inBrackets--;\n                    e = new AST.ArrayExp(loc, e, arguments);\n                    continue;\n                }\n            default:\n                return e;\n            }\n            nextToken();\n        }\n    }\n\n    AST.Expression parseMulExp()\n    {\n        const loc = token.loc;\n        auto e = parseUnaryExp();\n\n        while (1)\n        {\n            switch (token.value)\n            {\n            case TOK.mul:\n                nextToken();\n                auto e2 = parseUnaryExp();\n                e = new AST.MulExp(loc, e, e2);\n                continue;\n\n            case TOK.div:\n                nextToken();\n                auto e2 = parseUnaryExp();\n                e = new AST.DivExp(loc, e, e2);\n                continue;\n\n            case TOK.mod:\n                nextToken();\n                auto e2 = parseUnaryExp();\n                e = new AST.ModExp(loc, e, e2);\n                continue;\n\n            default:\n                break;\n            }\n            break;\n        }\n        return e;\n    }\n\n    AST.Expression parseAddExp()\n    {\n        const loc = token.loc;\n        auto e = parseMulExp();\n\n        while (1)\n        {\n            switch (token.value)\n            {\n            case TOK.add:\n                nextToken();\n                auto e2 = parseMulExp();\n                e = new AST.AddExp(loc, e, e2);\n                continue;\n\n            case TOK.min:\n                nextToken();\n                auto e2 = parseMulExp();\n                e = new AST.MinExp(loc, e, e2);\n                continue;\n\n            case TOK.tilde:\n                nextToken();\n                auto e2 = parseMulExp();\n                e = new AST.CatExp(loc, e, e2);\n                continue;\n\n            default:\n                break;\n            }\n            break;\n        }\n        return e;\n    }\n\n    AST.Expression parseShiftExp()\n    {\n        const loc = token.loc;\n        auto e = parseAddExp();\n\n        while (1)\n        {\n            switch (token.value)\n            {\n            case TOK.leftShift:\n                nextToken();\n                auto e2 = parseAddExp();\n                e = new AST.ShlExp(loc, e, e2);\n                continue;\n\n            case TOK.rightShift:\n                nextToken();\n                auto e2 = parseAddExp();\n                e = new AST.ShrExp(loc, e, e2);\n                continue;\n\n            case TOK.unsignedRightShift:\n                nextToken();\n                auto e2 = parseAddExp();\n                e = new AST.UshrExp(loc, e, e2);\n                continue;\n\n            default:\n                break;\n            }\n            break;\n        }\n        return e;\n    }\n\n    AST.Expression parseCmpExp()\n    {\n        const loc = token.loc;\n\n        auto e = parseShiftExp();\n        TOK op = token.value;\n\n        switch (op)\n        {\n        case TOK.equal:\n        case TOK.notEqual:\n            nextToken();\n            auto e2 = parseShiftExp();\n            e = new AST.EqualExp(op, loc, e, e2);\n            break;\n\n        case TOK.is_:\n            op = TOK.identity;\n            goto L1;\n\n        case TOK.not:\n        {\n            // Attempt to identify '!is'\n            auto t = peek(&token);\n            if (t.value == TOK.in_)\n            {\n                nextToken();\n                nextToken();\n                auto e2 = parseShiftExp();\n                e = new AST.InExp(loc, e, e2);\n                e = new AST.NotExp(loc, e);\n                break;\n            }\n            if (t.value != TOK.is_)\n                break;\n            nextToken();\n            op = TOK.notIdentity;\n            goto L1;\n        }\n        L1:\n            nextToken();\n            auto e2 = parseShiftExp();\n            e = new AST.IdentityExp(op, loc, e, e2);\n            break;\n\n        case TOK.lessThan:\n        case TOK.lessOrEqual:\n        case TOK.greaterThan:\n        case TOK.greaterOrEqual:\n            nextToken();\n            auto e2 = parseShiftExp();\n            e = new AST.CmpExp(op, loc, e, e2);\n            break;\n\n        case TOK.in_:\n            nextToken();\n            auto e2 = parseShiftExp();\n            e = new AST.InExp(loc, e, e2);\n            break;\n\n        default:\n            break;\n        }\n        return e;\n    }\n\n    AST.Expression parseAndExp()\n    {\n        Loc loc = token.loc;\n        auto e = parseCmpExp();\n        while (token.value == TOK.and)\n        {\n            checkParens(TOK.and, e);\n            nextToken();\n            auto e2 = parseCmpExp();\n            checkParens(TOK.and, e2);\n            e = new AST.AndExp(loc, e, e2);\n            loc = token.loc;\n        }\n        return e;\n    }\n\n    AST.Expression parseXorExp()\n    {\n        const loc = token.loc;\n\n        auto e = parseAndExp();\n        while (token.value == TOK.xor)\n        {\n            checkParens(TOK.xor, e);\n            nextToken();\n            auto e2 = parseAndExp();\n            checkParens(TOK.xor, e2);\n            e = new AST.XorExp(loc, e, e2);\n        }\n        return e;\n    }\n\n    AST.Expression parseOrExp()\n    {\n        const loc = token.loc;\n\n        auto e = parseXorExp();\n        while (token.value == TOK.or)\n        {\n            checkParens(TOK.or, e);\n            nextToken();\n            auto e2 = parseXorExp();\n            checkParens(TOK.or, e2);\n            e = new AST.OrExp(loc, e, e2);\n        }\n        return e;\n    }\n\n    AST.Expression parseAndAndExp()\n    {\n        const loc = token.loc;\n\n        auto e = parseOrExp();\n        while (token.value == TOK.andAnd)\n        {\n            nextToken();\n            auto e2 = parseOrExp();\n            e = new AST.LogicalExp(loc, TOK.andAnd, e, e2);\n        }\n        return e;\n    }\n\n    AST.Expression parseOrOrExp()\n    {\n        const loc = token.loc;\n\n        auto e = parseAndAndExp();\n        while (token.value == TOK.orOr)\n        {\n            nextToken();\n            auto e2 = parseAndAndExp();\n            e = new AST.LogicalExp(loc, TOK.orOr, e, e2);\n        }\n        return e;\n    }\n\n    AST.Expression parseCondExp()\n    {\n        const loc = token.loc;\n\n        auto e = parseOrOrExp();\n        if (token.value == TOK.question)\n        {\n            nextToken();\n            auto e1 = parseExpression();\n            check(TOK.colon);\n            auto e2 = parseCondExp();\n            e = new AST.CondExp(loc, e, e1, e2);\n        }\n        return e;\n    }\n\n    AST.Expression parseAssignExp()\n    {\n        auto e = parseCondExp();\n            // require parens for e.g. `t ? a = 1 : b = 2`\n            // Deprecated in 2018-05.\n            // @@@DEPRECATED_2.091@@@.\n            if (e.op == TOK.question && !e.parens && precedence[token.value] == PREC.assign)\n                dmd.errors.deprecation(e.loc, \"`%s` must be surrounded by parentheses when next to operator `%s`\",\n                    e.toChars(), Token.toChars(token.value));\n\n        const loc = token.loc;\n        switch (token.value)\n        {\n        case TOK.assign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.AssignExp(loc, e, e2);\n            break;\n\n        case TOK.addAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.AddAssignExp(loc, e, e2);\n            break;\n\n        case TOK.minAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.MinAssignExp(loc, e, e2);\n            break;\n\n        case TOK.mulAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.MulAssignExp(loc, e, e2);\n            break;\n\n        case TOK.divAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.DivAssignExp(loc, e, e2);\n            break;\n\n        case TOK.modAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.ModAssignExp(loc, e, e2);\n            break;\n\n        case TOK.powAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.PowAssignExp(loc, e, e2);\n            break;\n\n        case TOK.andAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.AndAssignExp(loc, e, e2);\n            break;\n\n        case TOK.orAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.OrAssignExp(loc, e, e2);\n            break;\n\n        case TOK.xorAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.XorAssignExp(loc, e, e2);\n            break;\n\n        case TOK.leftShiftAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.ShlAssignExp(loc, e, e2);\n            break;\n\n        case TOK.rightShiftAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.ShrAssignExp(loc, e, e2);\n            break;\n\n        case TOK.unsignedRightShiftAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.UshrAssignExp(loc, e, e2);\n            break;\n\n        case TOK.concatenateAssign:\n            nextToken();\n            auto e2 = parseAssignExp();\n            e = new AST.CatAssignExp(loc, e, e2);\n            break;\n\n        default:\n            break;\n        }\n\n        return e;\n    }\n\n    /*************************\n     * Collect argument list.\n     * Assume current token is ',', '$(LPAREN)' or '['.\n     */\n    AST.Expressions* parseArguments()\n    {\n        // function call\n        AST.Expressions* arguments;\n        TOK endtok;\n\n        arguments = new AST.Expressions();\n        if (token.value == TOK.leftBracket)\n            endtok = TOK.rightBracket;\n        else\n            endtok = TOK.rightParentheses;\n\n        {\n            nextToken();\n            while (token.value != endtok && token.value != TOK.endOfFile)\n            {\n                auto arg = parseAssignExp();\n                arguments.push(arg);\n                if (token.value == endtok)\n                    break;\n                check(TOK.comma);\n            }\n            check(endtok);\n        }\n        return arguments;\n    }\n\n    /*******************************************\n     */\n    AST.Expression parseNewExp(AST.Expression thisexp)\n    {\n        const loc = token.loc;\n\n        nextToken();\n        AST.Expressions* newargs = null;\n        AST.Expressions* arguments = null;\n        if (token.value == TOK.leftParentheses)\n        {\n            newargs = parseArguments();\n        }\n\n        // An anonymous nested class starts with \"class\"\n        if (token.value == TOK.class_)\n        {\n            nextToken();\n            if (token.value == TOK.leftParentheses)\n                arguments = parseArguments();\n\n            AST.BaseClasses* baseclasses = null;\n            if (token.value != TOK.leftCurly)\n                baseclasses = parseBaseClasses();\n\n            Identifier id = null;\n            AST.Dsymbols* members = null;\n\n            if (token.value != TOK.leftCurly)\n            {\n                error(\"`{ members }` expected for anonymous class\");\n            }\n            else\n            {\n                nextToken();\n                members = parseDeclDefs(0);\n                if (token.value != TOK.rightCurly)\n                    error(\"class member expected\");\n                nextToken();\n            }\n\n            auto cd = new AST.ClassDeclaration(loc, id, baseclasses, members, false);\n            auto e = new AST.NewAnonClassExp(loc, thisexp, newargs, cd, arguments);\n            return e;\n        }\n\n        const stc = parseTypeCtor();\n        auto t = parseBasicType(true);\n        t = parseBasicType2(t);\n        t = t.addSTC(stc);\n        if (t.ty == AST.Taarray)\n        {\n            AST.TypeAArray taa = cast(AST.TypeAArray)t;\n            AST.Type index = taa.index;\n            auto edim = AST.typeToExpression(index);\n            if (!edim)\n            {\n                error(\"need size of rightmost array, not type `%s`\", index.toChars());\n                return new AST.NullExp(loc);\n            }\n            t = new AST.TypeSArray(taa.next, edim);\n        }\n        else if (t.ty == AST.Tsarray)\n        {\n        }\n        else if (token.value == TOK.leftParentheses)\n        {\n            arguments = parseArguments();\n        }\n\n        auto e = new AST.NewExp(loc, thisexp, newargs, t, arguments);\n        return e;\n    }\n\n    /**********************************************\n     */\n    void addComment(AST.Dsymbol s, const(char)* blockComment)\n    {\n        if (s !is null)\n        {\n            s.addComment(combineComments(blockComment, token.lineComment, true));\n            token.lineComment = null;\n        }\n    }\n}\n\nenum PREC : int\n{\n    zero,\n    expr,\n    assign,\n    cond,\n    oror,\n    andand,\n    or,\n    xor,\n    and,\n    equal,\n    rel,\n    shift,\n    add,\n    mul,\n    pow,\n    unary,\n    primary,\n}\n"
  },
  {
    "path": "gcc/d/dmd/parsetimevisitor.d",
    "content": "/**\n * Documentation:  https://dlang.org/phobos/dmd_parsetimevisitor.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/parsetimevisitor.d\n */\n\nmodule dmd.parsetimevisitor;\n\n/** Basic and dumm visitor which implements a visit method for each AST node\n  * implemented in AST. This visitor is the parent of strict, transitive\n  * and permissive visitors.\n  */\nextern (C++) class ParseTimeVisitor(AST)\n{\npublic:\n    void visit(AST.Dsymbol) { assert(0); }\n    void visit(AST.Parameter) { assert(0); }\n    void visit(AST.Statement) { assert(0); }\n    void visit(AST.Type) { assert(0); }\n    void visit(AST.Expression) { assert(0); }\n    void visit(AST.TemplateParameter) { assert(0); }\n    void visit(AST.Condition) { assert(0); }\n    void visit(AST.Initializer) { assert(0); }\n\n    //=======================================================================================\n    // Dsymbols\n    void visit(AST.AliasThis s) { visit(cast(AST.Dsymbol)s); }\n    void visit(AST.Declaration s) { visit(cast(AST.Dsymbol)s); }\n    void visit(AST.ScopeDsymbol s) { visit(cast(AST.Dsymbol)s); }\n    void visit(AST.Import s) { visit(cast(AST.Dsymbol)s); }\n    void visit(AST.AttribDeclaration s) { visit(cast(AST.Dsymbol)s); }\n    void visit(AST.StaticAssert s) { visit(cast(AST.Dsymbol)s); }\n    void visit(AST.DebugSymbol s) { visit(cast(AST.Dsymbol)s); }\n    void visit(AST.VersionSymbol s) { visit(cast(AST.Dsymbol)s); }\n\n    // ScopeDsymbols\n    void visit(AST.Package s) { visit(cast(AST.ScopeDsymbol)s); }\n    void visit(AST.EnumDeclaration s) { visit(cast(AST.ScopeDsymbol)s); }\n    void visit(AST.AggregateDeclaration s) { visit(cast(AST.ScopeDsymbol)s); }\n    void visit(AST.TemplateDeclaration s) { visit(cast(AST.ScopeDsymbol)s); }\n    void visit(AST.TemplateInstance s) { visit(cast(AST.ScopeDsymbol)s); }\n    void visit(AST.Nspace s) { visit(cast(AST.ScopeDsymbol)s); }\n\n    //=========================================================================================\n    // Declarations\n    void visit(AST.VarDeclaration s) { visit(cast(AST.Declaration)s); }\n    void visit(AST.FuncDeclaration s) { visit(cast(AST.Declaration)s); }\n    void visit(AST.AliasDeclaration s) { visit(cast(AST.Declaration)s); }\n    void visit(AST.TupleDeclaration s) { visit(cast(AST.Declaration)s); }\n\n    // FuncDeclarations\n    void visit(AST.FuncLiteralDeclaration s) { visit(cast(AST.FuncDeclaration)s); }\n    void visit(AST.PostBlitDeclaration s) { visit(cast(AST.FuncDeclaration)s); }\n    void visit(AST.CtorDeclaration s) { visit(cast(AST.FuncDeclaration)s); }\n    void visit(AST.DtorDeclaration s) { visit(cast(AST.FuncDeclaration)s); }\n    void visit(AST.InvariantDeclaration s) { visit(cast(AST.FuncDeclaration)s); }\n    void visit(AST.UnitTestDeclaration s) { visit(cast(AST.FuncDeclaration)s); }\n    void visit(AST.NewDeclaration s) { visit(cast(AST.FuncDeclaration)s); }\n    void visit(AST.DeleteDeclaration s) { visit(cast(AST.FuncDeclaration)s); }\n    void visit(AST.StaticCtorDeclaration s) { visit(cast(AST.FuncDeclaration)s); }\n    void visit(AST.StaticDtorDeclaration s) { visit(cast(AST.FuncDeclaration)s); }\n    void visit(AST.SharedStaticCtorDeclaration s) { visit(cast(AST.StaticCtorDeclaration)s); }\n    void visit(AST.SharedStaticDtorDeclaration s) { visit(cast(AST.StaticDtorDeclaration)s); }\n\n    // AttribDeclarations\n    void visit(AST.CompileDeclaration s) { visit(cast(AST.AttribDeclaration)s); }\n    void visit(AST.UserAttributeDeclaration s) { visit(cast(AST.AttribDeclaration)s); }\n    void visit(AST.LinkDeclaration s) { visit(cast(AST.AttribDeclaration)s); }\n    void visit(AST.AnonDeclaration s) { visit(cast(AST.AttribDeclaration)s); }\n    void visit(AST.AlignDeclaration s) { visit(cast(AST.AttribDeclaration)s); }\n    void visit(AST.CPPMangleDeclaration s) { visit(cast(AST.AttribDeclaration)s); }\n    void visit(AST.ProtDeclaration s) { visit(cast(AST.AttribDeclaration)s); }\n    void visit(AST.PragmaDeclaration s) { visit(cast(AST.AttribDeclaration)s); }\n    void visit(AST.StorageClassDeclaration s) { visit(cast(AST.AttribDeclaration)s); }\n    void visit(AST.ConditionalDeclaration s) { visit(cast(AST.AttribDeclaration)s); }\n    void visit(AST.StaticForeachDeclaration s) { visit(cast(AST.AttribDeclaration)s); }\n\n    //==============================================================================================\n    // Miscellaneous\n    void visit(AST.DeprecatedDeclaration s) { visit(cast(AST.StorageClassDeclaration)s); }\n    void visit(AST.StaticIfDeclaration s) { visit(cast(AST.ConditionalDeclaration)s); }\n    void visit(AST.EnumMember s) { visit(cast(AST.VarDeclaration)s); }\n    void visit(AST.Module s) { visit(cast(AST.Package)s); }\n    void visit(AST.StructDeclaration s) { visit(cast(AST.AggregateDeclaration)s); }\n    void visit(AST.UnionDeclaration s) { visit(cast(AST.StructDeclaration)s); }\n    void visit(AST.ClassDeclaration s) { visit(cast(AST.AggregateDeclaration)s); }\n    void visit(AST.InterfaceDeclaration s) { visit(cast(AST.ClassDeclaration)s); }\n    void visit(AST.TemplateMixin s) { visit(cast(AST.TemplateInstance)s); }\n\n    //============================================================================================\n    // Statements\n    void visit(AST.ImportStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.ScopeStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.ReturnStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.LabelStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.StaticAssertStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.CompileStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.WhileStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.ForStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.DoStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.ForeachRangeStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.ForeachStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.IfStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.OnScopeStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.ConditionalStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.StaticForeachStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.PragmaStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.SwitchStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.CaseRangeStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.CaseStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.DefaultStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.BreakStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.ContinueStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.GotoDefaultStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.GotoCaseStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.GotoStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.SynchronizedStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.WithStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.TryCatchStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.TryFinallyStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.ThrowStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.AsmStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.ExpStatement s) { visit(cast(AST.Statement)s); }\n    void visit(AST.CompoundStatement s) { visit(cast(AST.Statement)s); }\n\n    // CompoundStatements\n    void visit(AST.CompoundDeclarationStatement s) { visit(cast(AST.CompoundStatement)s); }\n    void visit(AST.CompoundAsmStatement s) { visit(cast(AST.CompoundStatement)s); }\n\n    // AsmStatements\n    void visit(AST.InlineAsmStatement s) { visit(cast(AST.AsmStatement)s); }\n    void visit(AST.GccAsmStatement s) { visit(cast(AST.AsmStatement)s); }\n\n    //=========================================================================================\n    // Types\n    void visit(AST.TypeBasic t) { visit(cast(AST.Type)t); }\n    void visit(AST.TypeError t) { visit(cast(AST.Type)t); }\n    void visit(AST.TypeNull t) { visit(cast(AST.Type)t); }\n    void visit(AST.TypeVector t) { visit(cast(AST.Type)t); }\n    void visit(AST.TypeEnum t) { visit(cast(AST.Type)t); }\n    void visit(AST.TypeTuple t) { visit(cast(AST.Type)t); }\n    void visit(AST.TypeClass t) { visit(cast(AST.Type)t); }\n    void visit(AST.TypeStruct t) { visit(cast(AST.Type)t); }\n    void visit(AST.TypeNext t) { visit(cast(AST.Type)t); }\n    void visit(AST.TypeQualified t) { visit(cast(AST.Type)t); }\n\n    // TypeNext\n    void visit(AST.TypeReference t) { visit(cast(AST.TypeNext)t); }\n    void visit(AST.TypeSlice t) { visit(cast(AST.TypeNext)t); }\n    void visit(AST.TypeDelegate t) { visit(cast(AST.TypeNext)t); }\n    void visit(AST.TypePointer t) { visit(cast(AST.TypeNext)t); }\n    void visit(AST.TypeFunction t) { visit(cast(AST.TypeNext)t); }\n    void visit(AST.TypeArray t) { visit(cast(AST.TypeNext)t); }\n\n    // TypeArray\n    void visit(AST.TypeDArray t) { visit(cast(AST.TypeArray)t); }\n    void visit(AST.TypeAArray t) { visit(cast(AST.TypeArray)t); }\n    void visit(AST.TypeSArray t) { visit(cast(AST.TypeArray)t); }\n\n    // TypeQualified\n    void visit(AST.TypeIdentifier t) { visit(cast(AST.TypeQualified)t); }\n    void visit(AST.TypeReturn t) { visit(cast(AST.TypeQualified)t); }\n    void visit(AST.TypeTypeof t) { visit(cast(AST.TypeQualified)t); }\n    void visit(AST.TypeInstance t) { visit(cast(AST.TypeQualified)t); }\n\n    //=================================================================================\n    // Expressions\n    void visit(AST.DeclarationExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.IntegerExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.NewAnonClassExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.IsExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.RealExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.NullExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.TypeidExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.TraitsExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.StringExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.NewExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.AssocArrayLiteralExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.ArrayLiteralExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.CompileExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.FuncExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.IntervalExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.TypeExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.ScopeExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.IdentifierExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.UnaExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.DefaultInitExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.BinExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.DsymbolExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.TemplateExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.SymbolExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.TupleExp e) { visit(cast(AST.Expression)e); }\n    void visit(AST.ThisExp e) { visit(cast(AST.Expression)e); }\n\n    // Miscellaneous\n    void visit(AST.VarExp e) { visit(cast(AST.SymbolExp)e); }\n    void visit(AST.DollarExp e) { visit(cast(AST.IdentifierExp)e); }\n    void visit(AST.SuperExp e) { visit(cast(AST.ThisExp)e); }\n\n    // UnaExp\n    void visit(AST.AddrExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.PreExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.PtrExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.NegExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.UAddExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.NotExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.ComExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.DeleteExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.CastExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.CallExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.DotIdExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.AssertExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.ImportExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.DotTemplateInstanceExp e) { visit(cast(AST.UnaExp)e); }\n    void visit(AST.ArrayExp e) { visit(cast(AST.UnaExp)e); }\n\n    // DefaultInitExp\n    void visit(AST.FuncInitExp e) { visit(cast(AST.DefaultInitExp)e); }\n    void visit(AST.PrettyFuncInitExp e) { visit(cast(AST.DefaultInitExp)e); }\n    void visit(AST.FileInitExp e) { visit(cast(AST.DefaultInitExp)e); }\n    void visit(AST.LineInitExp e) { visit(cast(AST.DefaultInitExp)e); }\n    void visit(AST.ModuleInitExp e) { visit(cast(AST.DefaultInitExp)e); }\n\n    // BinExp\n    void visit(AST.CommaExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.PostExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.PowExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.MulExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.DivExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.ModExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.AddExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.MinExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.CatExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.ShlExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.ShrExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.UshrExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.EqualExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.InExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.IdentityExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.CmpExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.AndExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.XorExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.OrExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.LogicalExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.CondExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.AssignExp e) { visit(cast(AST.BinExp)e); }\n    void visit(AST.BinAssignExp e) { visit(cast(AST.BinExp)e); }\n\n    // BinAssignExp\n    void visit(AST.AddAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.MinAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.MulAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.DivAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.ModAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.PowAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.AndAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.OrAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.XorAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.ShlAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.ShrAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.UshrAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n    void visit(AST.CatAssignExp e) { visit(cast(AST.BinAssignExp)e); }\n\n    //===============================================================================\n    // TemplateParameter\n    void visit(AST.TemplateAliasParameter tp) { visit(cast(AST.TemplateParameter)tp); }\n    void visit(AST.TemplateTypeParameter tp) { visit(cast(AST.TemplateParameter)tp); }\n    void visit(AST.TemplateTupleParameter tp) { visit(cast(AST.TemplateParameter)tp); }\n    void visit(AST.TemplateValueParameter tp) { visit(cast(AST.TemplateParameter)tp); }\n\n    void visit(AST.TemplateThisParameter tp) { visit(cast(AST.TemplateTypeParameter)tp); }\n\n    //===============================================================================\n    // Condition\n    void visit(AST.StaticIfCondition c) { visit(cast(AST.Condition)c); }\n    void visit(AST.DVCondition c) { visit(cast(AST.Condition)c); }\n    void visit(AST.DebugCondition c) { visit(cast(AST.DVCondition)c); }\n    void visit(AST.VersionCondition c) { visit(cast(AST.DVCondition)c); }\n\n    //===============================================================================\n    // Initializer\n    void visit(AST.ExpInitializer i) { visit(cast(AST.Initializer)i); }\n    void visit(AST.StructInitializer i) { visit(cast(AST.Initializer)i); }\n    void visit(AST.ArrayInitializer i) { visit(cast(AST.Initializer)i); }\n    void visit(AST.VoidInitializer i) { visit(cast(AST.Initializer)i); }\n}\n"
  },
  {
    "path": "gcc/d/dmd/permissivevisitor.d",
    "content": "/**\n * Documentation:  https://dlang.org/phobos/dmd_permissivevisitor.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/permissivevisitor.d\n */\n\nmodule dmd.permissivevisitor;\n\nimport dmd.parsetimevisitor;\n\n/** PermissiveVisitor overrides all the visit methods in  the parent class\n  * that assert(0) in order to facilitate the traversal of subsets of the AST.\n  * It does not implement any visiting logic.\n  */\nextern(C++) class PermissiveVisitor(AST): ParseTimeVisitor!AST\n{\n    alias visit = ParseTimeVisitor!AST.visit;\n\n    override void visit(AST.Dsymbol){}\n    override void visit(AST.Parameter){}\n    override void visit(AST.Statement){}\n    override void visit(AST.Type){}\n    override void visit(AST.Expression){}\n    override void visit(AST.TemplateParameter){}\n    override void visit(AST.Condition){}\n    override void visit(AST.Initializer){}\n}\n"
  },
  {
    "path": "gcc/d/dmd/readme.txt",
    "content": "This is the source code to the DMD compiler\nfor the D Programming Language defined in the documents at\nhttp://dlang.org/\n\nThese sources are free, they are redistributable and modifiable\nunder the terms of the Boost Software License, Version 1.0.\nThe terms of this license are in the file boostlicense.txt,\nor see http://www.boost.org/LICENSE_1_0.txt.\n\nIf a particular file has a different license in it, that overrides\nthis license for that file.\n\n-Walter Bright\n"
  },
  {
    "path": "gcc/d/dmd/root/aav.d",
    "content": "/**\n * Compiler implementation of the D programming language\n * http://dlang.org\n *\n * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:   Walter Bright, http://www.digitalmars.com\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/aav.d, root/_aav.d)\n * Documentation:  https://dlang.org/phobos/dmd_root_aav.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/aav.d\n */\n\nmodule dmd.root.aav;\n\nimport core.stdc.string;\nimport dmd.root.rmem;\n\nprivate size_t hash(size_t a)\n{\n    a ^= (a >> 20) ^ (a >> 12);\n    return a ^ (a >> 7) ^ (a >> 4);\n}\n\nstruct KeyValueTemplate(K,V)\n{\n    K key;\n    V value;\n}\n\nalias Key = void*;\nalias Value = void*;\n\nalias KeyValue = KeyValueTemplate!(Key, Value);\n\nstruct aaA\n{\n    aaA* next;\n    KeyValue keyValue;\n    alias keyValue this;\n}\n\nstruct AA\n{\n    aaA** b;\n    size_t b_length;\n    size_t nodes; // total number of aaA nodes\n    aaA*[4] binit; // initial value of b[]\n    aaA aafirst; // a lot of these AA's have only one entry\n}\n\n/****************************************************\n * Determine number of entries in associative array.\n */\nprivate size_t dmd_aaLen(const AA* aa) pure\n{\n    return aa ? aa.nodes : 0;\n}\n\n/*************************************************\n * Get pointer to value in associative array indexed by key.\n * Add entry for key if it is not already there, returning a pointer to a null Value.\n * Create the associative array if it does not already exist.\n */\nprivate Value* dmd_aaGet(AA** paa, Key key)\n{\n    //printf(\"paa = %p\\n\", paa);\n    if (!*paa)\n    {\n        AA* a = cast(AA*)mem.xmalloc(AA.sizeof);\n        a.b = cast(aaA**)a.binit;\n        a.b_length = 4;\n        a.nodes = 0;\n        a.binit[0] = null;\n        a.binit[1] = null;\n        a.binit[2] = null;\n        a.binit[3] = null;\n        *paa = a;\n        assert((*paa).b_length == 4);\n    }\n    //printf(\"paa = %p, *paa = %p\\n\", paa, *paa);\n    assert((*paa).b_length);\n    size_t i = hash(cast(size_t)key) & ((*paa).b_length - 1);\n    aaA** pe = &(*paa).b[i];\n    aaA* e;\n    while ((e = *pe) !is null)\n    {\n        if (key == e.key)\n            return &e.value;\n        pe = &e.next;\n    }\n    // Not found, create new elem\n    //printf(\"create new one\\n\");\n    size_t nodes = ++(*paa).nodes;\n    e = (nodes != 1) ? cast(aaA*)mem.xmalloc(aaA.sizeof) : &(*paa).aafirst;\n    //e = new aaA();\n    e.next = null;\n    e.key = key;\n    e.value = null;\n    *pe = e;\n    //printf(\"length = %d, nodes = %d\\n\", (*paa)->b_length, nodes);\n    if (nodes > (*paa).b_length * 2)\n    {\n        //printf(\"rehash\\n\");\n        dmd_aaRehash(paa);\n    }\n    return &e.value;\n}\n\n/*************************************************\n * Get value in associative array indexed by key.\n * Returns NULL if it is not already there.\n */\nprivate Value dmd_aaGetRvalue(AA* aa, Key key)\n{\n    //printf(\"_aaGetRvalue(key = %p)\\n\", key);\n    if (aa)\n    {\n        size_t i;\n        size_t len = aa.b_length;\n        i = hash(cast(size_t)key) & (len - 1);\n        aaA* e = aa.b[i];\n        while (e)\n        {\n            if (key == e.key)\n                return e.value;\n            e = e.next;\n        }\n    }\n    return null; // not found\n}\n\ndebug\n{\n    /**\n    Gets a range of key/values for `aa`.\n\n    Returns: a range of key/values for `aa`.\n    */\n    @property auto asRange(AA* aa)\n    {\n        return AARange!(Key, Value)(aa);\n    }\n\n    private struct AARange(K,V)\n    {\n        AA* aa;\n        // current index into bucket array `aa.b`\n        size_t bIndex;\n        aaA* current;\n\n        this(AA* aa)\n        {\n            if (aa)\n            {\n                this.aa = aa;\n                toNext();\n            }\n        }\n\n        @property bool empty() const { return current is null; }\n\n        @property auto front() { return cast(KeyValueTemplate!(K,V))current.keyValue; }\n\n        void popFront()\n        {\n            if (current.next)\n                current = current.next;\n            else\n            {\n                bIndex++;\n                toNext();\n            }\n        }\n\n        private void toNext()\n        {\n            for (; bIndex < aa.b_length; bIndex++)\n            {\n                if (auto next = aa.b[bIndex])\n                {\n                    current = next;\n                    return;\n                }\n            }\n            current = null;\n        }\n    }\n    unittest\n    {\n        AA* aa = null;\n        foreach(keyValue; aa.asRange)\n            assert(0);\n\n        enum totalKeyLength = 50;\n        foreach (i; 1 .. totalKeyLength + 1)\n        {\n            auto key = cast(void*)i;\n            {\n                auto valuePtr = dmd_aaGet(&aa, key);\n                assert(valuePtr);\n                *valuePtr = key;\n            }\n            bool[totalKeyLength] found;\n            size_t rangeCount = 0;\n            foreach (keyValue; aa.asRange)\n            {\n                assert(keyValue.key <= key);\n                assert(keyValue.key == keyValue.value);\n                rangeCount++;\n                assert(!found[cast(size_t)keyValue.key - 1]);\n                found[cast(size_t)keyValue.key - 1] = true;\n            }\n            assert(rangeCount == i);\n        }\n    }\n}\n\n/********************************************\n * Rehash an array.\n */\nprivate void dmd_aaRehash(AA** paa)\n{\n    //printf(\"Rehash\\n\");\n    if (*paa)\n    {\n        AA* aa = *paa;\n        if (aa)\n        {\n            size_t len = aa.b_length;\n            if (len == 4)\n                len = 32;\n            else\n                len *= 4;\n            aaA** newb = cast(aaA**)mem.xmalloc(aaA.sizeof * len);\n            memset(newb, 0, len * (aaA*).sizeof);\n            for (size_t k = 0; k < aa.b_length; k++)\n            {\n                aaA* e = aa.b[k];\n                while (e)\n                {\n                    aaA* enext = e.next;\n                    size_t j = hash(cast(size_t)e.key) & (len - 1);\n                    e.next = newb[j];\n                    newb[j] = e;\n                    e = enext;\n                }\n            }\n            if (aa.b != cast(aaA**)aa.binit)\n                mem.xfree(aa.b);\n            aa.b = newb;\n            aa.b_length = len;\n        }\n    }\n}\n\nunittest\n{\n    AA* aa = null;\n    Value v = dmd_aaGetRvalue(aa, null);\n    assert(!v);\n    Value* pv = dmd_aaGet(&aa, null);\n    assert(pv);\n    *pv = cast(void*)3;\n    v = dmd_aaGetRvalue(aa, null);\n    assert(v == cast(void*)3);\n}\n\nstruct AssocArray(K,V)\n{\n    private AA* aa;\n\n    /**\n    Returns: The number of key/value pairs.\n    */\n    @property size_t length() const { return dmd_aaLen(aa); }\n\n    /**\n    Lookup value associated with `key` and return the address to it. If the `key`\n    has not been added, it adds it and returns the address to the new value.\n\n    Params:\n        key = key to lookup the value for\n\n    Returns: the address to the value associated with `key`. If `key` does not exist, it\n             is added and the address to the new value is returned.\n    */\n    V* getLvalue(const(K) key)\n    {\n        return cast(V*)dmd_aaGet(&aa, cast(void*)key);\n    }\n\n    /**\n    Lookup and return the value associated with `key`, if the `key` has not been\n    added, it returns null.\n\n    Params:\n        key = key to lookup the value for\n\n    Returns: the value associated with `key` if present, otherwise, null.\n    */\n    V opIndex(const(K) key)\n    {\n        return cast(V)dmd_aaGetRvalue(aa, cast(void*)key);\n    }\n\n    debug\n    {\n        /**\n        Gets a range of key/values for `aa`.\n\n        Returns: a range of key/values for `aa`.\n        */\n        @property auto asRange() { return AARange!(K,V)(aa); }\n    }\n}\n\n///\nunittest\n{\n    auto foo = new Object();\n    auto bar = new Object();\n\n    AssocArray!(Object, Object) aa;\n\n    assert(aa[foo] is null);\n    assert(aa.length == 0);\n\n    auto fooValuePtr = aa.getLvalue(foo);\n    *fooValuePtr = bar;\n\n    assert(aa[foo] is bar);\n    assert(aa.length == 1);\n}\n"
  },
  {
    "path": "gcc/d/dmd/root/array.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/array.d, root/_array.d)\n * Documentation:  https://dlang.org/phobos/dmd_root_array.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/array.d\n */\n\nmodule dmd.root.array;\n\nimport core.stdc.string;\n\nimport dmd.root.rmem;\n\nextern (C++) struct Array(T)\n{\n    size_t dim;\n    T* data;\n\nprivate:\n    size_t allocdim;\n    enum SMALLARRAYCAP = 1;\n    T[SMALLARRAYCAP] smallarray; // inline storage for small arrays\n\npublic:\n    /*******************\n     * Params:\n     *  dim = initial length of array\n     */\n    this(size_t dim)\n    {\n        reserve(dim);\n        this.dim = dim;\n    }\n\n    @disable this(this);\n\n    ~this() nothrow\n    {\n        if (data != &smallarray[0])\n            mem.xfree(data);\n    }\n\n    const(char)* toChars()\n    {\n        static if (is(typeof(T.init.toChars())))\n        {\n            const(char)** buf = cast(const(char)**)mem.xmalloc(dim * (char*).sizeof);\n            size_t len = 2;\n            for (size_t u = 0; u < dim; u++)\n            {\n                buf[u] = data[u].toChars();\n                len += strlen(buf[u]) + 1;\n            }\n            char* str = cast(char*)mem.xmalloc(len);\n\n            str[0] = '[';\n            char* p = str + 1;\n            for (size_t u = 0; u < dim; u++)\n            {\n                if (u)\n                    *p++ = ',';\n                len = strlen(buf[u]);\n                memcpy(p, buf[u], len);\n                p += len;\n            }\n            *p++ = ']';\n            *p = 0;\n            mem.xfree(buf);\n            return str;\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n\n    void push(T ptr) nothrow\n    {\n        reserve(1);\n        data[dim++] = ptr;\n    }\n\n    void append(typeof(this)* a) nothrow\n    {\n        insert(dim, a);\n    }\n\n    void reserve(size_t nentries) nothrow\n    {\n        //printf(\"Array::reserve: dim = %d, allocdim = %d, nentries = %d\\n\", (int)dim, (int)allocdim, (int)nentries);\n        if (allocdim - dim < nentries)\n        {\n            if (allocdim == 0)\n            {\n                // Not properly initialized, someone memset it to zero\n                if (nentries <= SMALLARRAYCAP)\n                {\n                    allocdim = SMALLARRAYCAP;\n                    data = SMALLARRAYCAP ? smallarray.ptr : null;\n                }\n                else\n                {\n                    allocdim = nentries;\n                    data = cast(T*)mem.xmalloc(allocdim * (*data).sizeof);\n                }\n            }\n            else if (allocdim == SMALLARRAYCAP)\n            {\n                allocdim = dim + nentries;\n                data = cast(T*)mem.xmalloc(allocdim * (*data).sizeof);\n                memcpy(data, smallarray.ptr, dim * (*data).sizeof);\n            }\n            else\n            {\n                /* Increase size by 1.5x to avoid excessive memory fragmentation\n                 */\n                auto increment = dim / 2;\n                if (nentries > increment)       // if 1.5 is not enough\n                    increment = nentries;\n                allocdim = dim + increment;\n                data = cast(T*)mem.xrealloc(data, allocdim * (*data).sizeof);\n            }\n        }\n    }\n\n    void remove(size_t i) nothrow\n    {\n        if (dim - i - 1)\n            memmove(data + i, data + i + 1, (dim - i - 1) * (data[0]).sizeof);\n        dim--;\n    }\n\n    void insert(size_t index, typeof(this)* a) nothrow\n    {\n        if (a)\n        {\n            size_t d = a.dim;\n            reserve(d);\n            if (dim != index)\n                memmove(data + index + d, data + index, (dim - index) * (*data).sizeof);\n            memcpy(data + index, a.data, d * (*data).sizeof);\n            dim += d;\n        }\n    }\n\n    void insert(size_t index, T ptr) nothrow\n    {\n        reserve(1);\n        memmove(data + index + 1, data + index, (dim - index) * (*data).sizeof);\n        data[index] = ptr;\n        dim++;\n    }\n\n    void setDim(size_t newdim) nothrow\n    {\n        if (dim < newdim)\n        {\n            reserve(newdim - dim);\n        }\n        dim = newdim;\n    }\n\n    ref inout(T) opIndex(size_t i) inout nothrow pure\n    {\n        return data[i];\n    }\n\n    inout(T)* tdata() inout nothrow\n    {\n        return data;\n    }\n\n    Array!T* copy() const nothrow\n    {\n        auto a = new Array!T();\n        a.setDim(dim);\n        memcpy(a.data, data, dim * (void*).sizeof);\n        return a;\n    }\n\n    void shift(T ptr) nothrow\n    {\n        reserve(1);\n        memmove(data + 1, data, dim * (*data).sizeof);\n        data[0] = ptr;\n        dim++;\n    }\n\n    void zero() nothrow pure\n    {\n        data[0 .. dim] = T.init;\n    }\n\n    T pop() nothrow pure\n    {\n        return data[--dim];\n    }\n\n    extern (D) inout(T)[] opSlice() inout nothrow pure\n    {\n        return data[0 .. dim];\n    }\n\n    extern (D) inout(T)[] opSlice(size_t a, size_t b) inout nothrow pure\n    {\n        assert(a <= b && b <= dim);\n        return data[a .. b];\n    }\n\n    alias opDollar = dim;\n}\n\nstruct BitArray\n{\nnothrow:\n    size_t length() const pure\n    {\n        return len;\n    }\n\n    void length(size_t nlen)\n    {\n        immutable obytes = (len + 7) / 8;\n        immutable nbytes = (nlen + 7) / 8;\n        // bt*() access memory in size_t chunks, so round up.\n        ptr = cast(size_t*)mem.xrealloc(ptr,\n            (nbytes + (size_t.sizeof - 1)) & ~(size_t.sizeof - 1));\n        if (nbytes > obytes)\n            (cast(ubyte*)ptr)[obytes .. nbytes] = 0;\n        len = nlen;\n    }\n\n    bool opIndex(size_t idx) const pure\n    {\n        import core.bitop : bt;\n\n        assert(idx < length);\n        return !!bt(ptr, idx);\n    }\n\n    void opIndexAssign(bool val, size_t idx) pure\n    {\n        import core.bitop : btc, bts;\n\n        assert(idx < length);\n        if (val)\n            bts(ptr, idx);\n        else\n            btc(ptr, idx);\n    }\n\n    @disable this(this);\n\n    ~this()\n    {\n        mem.xfree(ptr);\n    }\n\nprivate:\n    size_t len;\n    size_t *ptr;\n}\n\n/**\n * Exposes the given root Array as a standard D array.\n * Params:\n *  array = the array to expose.\n * Returns:\n *  The given array exposed to a standard D array.\n */\n@property T[] asDArray(T)(ref Array!T array)\n{\n    return array.data[0..array.dim];\n}\n\n/**\n * Splits the array at $(D index) and expands it to make room for $(D length)\n * elements by shifting everything past $(D index) to the right.\n * Params:\n *  array = the array to split.\n *  index = the index to split the array from.\n *  length = the number of elements to make room for starting at $(D index).\n */\nvoid split(T)(ref Array!T array, size_t index, size_t length)\n{\n    if (length > 0)\n    {\n        auto previousDim = array.dim;\n        array.setDim(array.dim + length);\n        for (size_t i = previousDim; i > index;)\n        {\n            i--;\n            array[i + length] = array[i];\n        }\n    }\n}\nunittest\n{\n    auto array = Array!int();\n    array.split(0, 0);\n    assert([] == array.asDArray);\n    array.push(1);\n    array.push(3);\n    array.split(1, 1);\n    array[1] = 2;\n    assert([1, 2, 3] == array.asDArray);\n    array.split(2, 3);\n    array[2] = 8;\n    array[3] = 20;\n    array[4] = 4;\n    assert([1, 2, 8, 20, 4, 3] == array.asDArray);\n    array.split(0, 0);\n    assert([1, 2, 8, 20, 4, 3] == array.asDArray);\n    array.split(0, 1);\n    array[0] = 123;\n    assert([123, 1, 2, 8, 20, 4, 3] == array.asDArray);\n    array.split(0, 3);\n    array[0] = 123;\n    array[1] = 421;\n    array[2] = 910;\n    assert([123, 421, 910, 123, 1, 2, 8, 20, 4, 3] == array.asDArray);\n}\n"
  },
  {
    "path": "gcc/d/dmd/root/array.h",
    "content": "/* Copyright (C) 2011-2018 by The D Language Foundation, All Rights Reserved\n * All Rights Reserved, written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/root/array.h\n */\n\n#pragma once\n\n#include <assert.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"object.h\"\n#include \"rmem.h\"\n\ntemplate <typename TYPE>\nstruct Array\n{\n    d_size_t dim;\n    TYPE *data;\n\n  private:\n    Array(const Array&);\n\n    d_size_t allocdim;\n    #define SMALLARRAYCAP       1\n    TYPE smallarray[SMALLARRAYCAP];    // inline storage for small arrays\n\n  public:\n    Array()\n    {\n        data = SMALLARRAYCAP ? &smallarray[0] : NULL;\n        dim = 0;\n        allocdim = SMALLARRAYCAP;\n    }\n\n    ~Array()\n    {\n        if (data != &smallarray[0])\n            mem.xfree(data);\n    }\n\n    char *toChars()\n    {\n        const char **buf = (const char **)mem.xmalloc(dim * sizeof(const char *));\n        d_size_t len = 2;\n        for (d_size_t u = 0; u < dim; u++)\n        {\n            buf[u] = ((RootObject *)data[u])->toChars();\n            len += strlen(buf[u]) + 1;\n        }\n        char *str = (char *)mem.xmalloc(len);\n\n        str[0] = '[';\n        char *p = str + 1;\n        for (d_size_t u = 0; u < dim; u++)\n        {\n            if (u)\n                *p++ = ',';\n            len = strlen(buf[u]);\n            memcpy(p,buf[u],len);\n            p += len;\n        }\n        *p++ = ']';\n        *p = 0;\n        mem.xfree(buf);\n        return str;\n    }\n\n    void reserve(d_size_t nentries)\n    {\n        //printf(\"Array::reserve: dim = %d, allocdim = %d, nentries = %d\\n\", (int)dim, (int)allocdim, (int)nentries);\n        if (allocdim - dim < nentries)\n        {\n            if (allocdim == 0)\n            {   // Not properly initialized, someone memset it to zero\n                if (nentries <= SMALLARRAYCAP)\n                {   allocdim = SMALLARRAYCAP;\n                    data = SMALLARRAYCAP ? &smallarray[0] : NULL;\n                }\n                else\n                {   allocdim = nentries;\n                    data = (TYPE *)mem.xmalloc(allocdim * sizeof(*data));\n                }\n            }\n            else if (allocdim == SMALLARRAYCAP)\n            {\n                allocdim = dim + nentries;\n                data = (TYPE *)mem.xmalloc(allocdim * sizeof(*data));\n                memcpy(data, &smallarray[0], dim * sizeof(*data));\n            }\n            else\n            {\n                /* Increase size by 1.5x to avoid excessive memory fragmentation\n                 */\n                d_size_t increment = dim / 2;\n                if (nentries > increment)       // if 1.5 is not enough\n                    increment = nentries;\n                allocdim = dim + increment;\n                data = (TYPE *)mem.xrealloc(data, allocdim * sizeof(*data));\n            }\n        }\n    }\n\n    void setDim(d_size_t newdim)\n    {\n        if (dim < newdim)\n        {\n            reserve(newdim - dim);\n        }\n        dim = newdim;\n    }\n\n    TYPE pop()\n    {\n        return data[--dim];\n    }\n\n    void shift(TYPE ptr)\n    {\n        reserve(1);\n        memmove(data + 1, data, dim * sizeof(*data));\n        data[0] = ptr;\n        dim++;\n    }\n\n    void remove(d_size_t i)\n    {\n        if (dim - i - 1)\n            memmove(data + i, data + i + 1, (dim - i - 1) * sizeof(data[0]));\n        dim--;\n    }\n\n    void zero()\n    {\n        memset(data,0,dim * sizeof(data[0]));\n    }\n\n    void sort()\n    {\n        struct ArraySort\n        {\n            static int\n    #if _WIN32\n              __cdecl\n    #endif\n            Array_sort_compare(const void *x, const void *y)\n            {\n                RootObject *ox = *(RootObject **)const_cast<void *>(x);\n                RootObject *oy = *(RootObject **)const_cast<void *>(y);\n\n                return ox->compare(oy);\n            }\n        };\n\n        if (dim)\n        {\n            qsort(data, dim, sizeof(RootObject *), &ArraySort::Array_sort_compare);\n        }\n    }\n\n    TYPE *tdata()\n    {\n        return data;\n    }\n\n    TYPE& operator[] (d_size_t index)\n    {\n#ifdef DEBUG\n        assert(index < dim);\n#endif\n        return data[index];\n    }\n\n    void insert(d_size_t index, TYPE v)\n    {\n        reserve(1);\n        memmove(data + index + 1, data + index, (dim - index) * sizeof(*data));\n        data[index] = v;\n        dim++;\n    }\n\n    void insert(d_size_t index, Array *a)\n    {\n        if (a)\n        {\n            d_size_t d = a->dim;\n            reserve(d);\n            if (dim != index)\n                memmove(data + index + d, data + index, (dim - index) * sizeof(*data));\n            memcpy(data + index, a->data, d * sizeof(*data));\n            dim += d;\n        }\n    }\n\n    void append(Array *a)\n    {\n        insert(dim, a);\n    }\n\n    void push(TYPE a)\n    {\n        reserve(1);\n        data[dim++] = a;\n    }\n\n    Array *copy()\n    {\n        Array *a = new Array();\n        a->setDim(dim);\n        memcpy(a->data, data, dim * sizeof(*data));\n        return a;\n    }\n};\n\nstruct BitArray\n{\n    BitArray()\n      : len(0)\n      , ptr(NULL)\n    {}\n\n    ~BitArray()\n    {\n        mem.xfree(ptr);\n    }\n\n    d_size_t len;\n    d_size_t *ptr;\n\nprivate:\n    BitArray(const BitArray&);\n};\n"
  },
  {
    "path": "gcc/d/dmd/root/ctfloat.d",
    "content": "/* ctfloat.d -- Compile-time floating-pointer helper functions.\n * Copyright (C) 2018 Free Software Foundation, Inc.\n *\n * GCC is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3, or (at your option)\n * any later version.\n *\n * GCC is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with GCC; see the file COPYING3.  If not see\n * <http://www.gnu.org/licenses/>.\n */\n\nmodule dmd.root.ctfloat;\n\nnothrow:\n\n// Type used by the front-end for compile-time reals\npublic import dmd.root.longdouble : real_t = longdouble;\n\n// Compile-time floating-point helper\nextern (C++) struct CTFloat\n{\n  nothrow:\n    enum yl2x_supported = false;\n    enum yl2xp1_supported = false;\n\n    static real_t fabs(real_t x);\n    static real_t ldexp(real_t n, int exp);\n    static bool isIdentical(real_t a, real_t b);\n    static size_t hash(real_t a);\n    static bool isNaN(real_t r);\n    static bool isSNaN(real_t r);\n    static bool isInfinity(real_t r);\n    static real_t parse(const(char)* literal, bool* isOutOfRange = null);\n    static int sprint(char* str, char fmt, real_t x);\n\n    // Constant real values 0, 1, -1 and 0.5.\n    __gshared real_t zero;\n    __gshared real_t one;\n    __gshared real_t minusone;\n    __gshared real_t half;\n\n    static void initialize();\n}\n"
  },
  {
    "path": "gcc/d/dmd/root/ctfloat.h",
    "content": "\n/* Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * All Rights Reserved, written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/root/ctfloat.h\n */\n\n#pragma once\n\n#include \"longdouble.h\"\n\n// Type used by the front-end for compile-time reals\ntypedef longdouble real_t;\n\n// Compile-time floating-point helper\nstruct CTFloat\n{\n    static void yl2x(const real_t *x, const real_t *y, real_t *res);\n    static void yl2xp1(const real_t *x, const real_t *y, real_t *res);\n\n    static real_t sin(real_t x);\n    static real_t cos(real_t x);\n    static real_t tan(real_t x);\n    static real_t sqrt(real_t x);\n    static real_t fabs(real_t x);\n    static real_t ldexp(real_t n, int exp);\n\n    static real_t round(real_t x);\n    static real_t floor(real_t x);\n    static real_t ceil(real_t x);\n    static real_t trunc(real_t x);\n    static real_t log(real_t x);\n    static real_t log2(real_t x);\n    static real_t log10(real_t x);\n    static real_t pow(real_t x, real_t y);\n    static real_t expm1(real_t x);\n    static real_t exp2(real_t x);\n\n    static real_t fmin(real_t x, real_t y);\n    static real_t fmax(real_t x, real_t y);\n    static real_t copysign(real_t x, real_t s);\n\n    static real_t fma(real_t x, real_t y, real_t z);\n\n    static bool isIdentical(real_t a, real_t b);\n    static bool isNaN(real_t r);\n    static bool isSNaN(real_t r);\n    static bool isInfinity(real_t r);\n\n    static real_t parse(const char *literal, bool *isOutOfRange = NULL);\n    static int sprint(char *str, char fmt, real_t x);\n\n    static size_t hash(real_t a);\n\n    // Constant real values 0, 1, -1 and 0.5.\n    static real_t zero;\n    static real_t one;\n    static real_t minusone;\n    static real_t half;\n\n    static void initialize();\n};\n"
  },
  {
    "path": "gcc/d/dmd/root/dcompat.h",
    "content": "\n/* Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/root/dcompat.h\n */\n\n#pragma once\n\n#include <stddef.h>\n\n/// Represents a D [ ] array\ntemplate<typename T>\nstruct DArray\n{\n    size_t length;\n    T *ptr;\n};\n"
  },
  {
    "path": "gcc/d/dmd/root/file.d",
    "content": "/**\n * Compiler implementation of the D programming language\n * http://dlang.org\n *\n * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:   Walter Bright, http://www.digitalmars.com\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/file.d, root/_file.d)\n * Documentation:  https://dlang.org/phobos/dmd_root_file.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/file.d\n */\n\nmodule dmd.root.file;\n\nimport core.stdc.errno;\nimport core.stdc.stdio;\nimport core.stdc.stdlib;\nimport core.sys.posix.fcntl;\nimport core.sys.posix.unistd;\nimport core.sys.windows.windows;\nimport dmd.root.filename;\nimport dmd.root.rmem;\nimport dmd.utils;\n\n/***********************************************************\n */\nstruct File\n{\n    int _ref; // != 0 if this is a reference to someone else's buffer\n    ubyte* buffer; // data for our file\n    size_t len; // amount of data in buffer[]\n    const(FileName) name; // name of our file\n\nnothrow:\n    extern (D) this(const(char)* n)\n    {\n        this(n.toDString());\n    }\n\n    extern (D) this(const(char)[] n)\n    {\n        _ref = 0;\n        buffer = null;\n        len = 0;\n        name = FileName(n);\n    }\n\n    extern (C++) static File* create(const(char)* n)\n    {\n        return new File(n.toDString());\n    }\n\n    extern (C++) ~this()\n    {\n        if (buffer)\n        {\n            if (_ref == 0)\n                mem.xfree(buffer);\n            version (Windows)\n            {\n                if (_ref == 2)\n                    UnmapViewOfFile(buffer);\n            }\n        }\n    }\n\n    extern (C++) const(char)* toChars() const pure nothrow @safe\n    {\n        return name.toChars();\n    }\n\n    const(char)[] toString() const nothrow pure @safe\n    {\n        return name.toString();\n    }\n\n    /**\n     * Read the full content of a file\n     *\n     * Returns:\n     *   `true` if there was an error\n     */\n    extern (C++) bool read()\n    {\n        if (len)\n            return false; // already read the file\n\n        import core.stdc.string : strcmp;\n        const(char)* name = this.name.toChars();\n        if (strcmp(name, \"__stdin.d\") == 0)\n        {\n            /* Read from stdin */\n            enum bufIncrement = 128 * 1024;\n            size_t pos = 0;\n            size_t sz = bufIncrement;\n\n            if (!_ref)\n                .free(buffer);\n\n            buffer = null;\n            L1: for (;;)\n            {\n                buffer = cast(ubyte*).realloc(buffer, sz + 2); // +2 for sentinel\n                if (!buffer)\n                {\n                    printf(\"\\tmalloc error, errno = %d\\n\", errno);\n                    break L1;\n                }\n\n                // Fill up buffer\n                do\n                {\n                    assert(sz > pos);\n                    size_t rlen = fread(buffer + pos, 1, sz - pos, stdin);\n                    pos += rlen;\n                    if (ferror(stdin))\n                    {\n                        printf(\"\\tread error, errno = %d\\n\", errno);\n                        break L1;\n                    }\n                    if (feof(stdin))\n                    {\n                        // We're done\n                        assert(pos < sz + 2);\n                        len = pos;\n                        buffer[pos] = '\\0';\n                        buffer[pos + 1] = '\\0';\n                        return false;\n                    }\n                } while (pos < sz);\n\n                // Buffer full, expand\n                sz += bufIncrement;\n            }\n            .free(buffer);\n            buffer = null;\n            len = 0;\n            return true;\n        }\n\n        version (Posix)\n        {\n            size_t size;\n            stat_t buf;\n            ssize_t numread;\n            //printf(\"File::read('%s')\\n\",name);\n            int fd = open(name, O_RDONLY);\n            if (fd == -1)\n            {\n                //printf(\"\\topen error, errno = %d\\n\",errno);\n                goto err1;\n            }\n            if (!_ref)\n            {\n                .free(buffer);\n                buffer = null;\n            }\n            _ref = 0; // we own the buffer now\n            //printf(\"\\tfile opened\\n\");\n            if (fstat(fd, &buf))\n            {\n                printf(\"\\tfstat error, errno = %d\\n\", errno);\n                goto err2;\n            }\n            size = cast(size_t)buf.st_size;\n            buffer = cast(ubyte*).malloc(size + 2);\n            if (!buffer)\n            {\n                printf(\"\\tmalloc error, errno = %d\\n\", errno);\n                goto err2;\n            }\n            numread = .read(fd, buffer, size);\n            if (numread != size)\n            {\n                printf(\"\\tread error, errno = %d\\n\", errno);\n                goto err2;\n            }\n            if (close(fd) == -1)\n            {\n                printf(\"\\tclose error, errno = %d\\n\", errno);\n                goto err;\n            }\n            len = size;\n            // Always store a wchar ^Z past end of buffer so scanner has a sentinel\n            buffer[size] = 0; // ^Z is obsolete, use 0\n            buffer[size + 1] = 0;\n            return false;\n        err2:\n            close(fd);\n        err:\n            .free(buffer);\n            buffer = null;\n            len = 0;\n        err1:\n            return true;\n        }\n        else version (Windows)\n        {\n            DWORD size;\n            DWORD numread;\n\n            // work around Windows file path length limitation\n            // (see documentation for extendedPathThen).\n            HANDLE h = name.toDString.extendedPathThen!\n                (p => CreateFileW(p.ptr,\n                                  GENERIC_READ,\n                                  FILE_SHARE_READ,\n                                  null,\n                                  OPEN_EXISTING,\n                                  FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,\n                                  null));\n            if (h == INVALID_HANDLE_VALUE)\n                goto err1;\n            if (!_ref)\n                .free(buffer);\n            _ref = 0;\n            size = GetFileSize(h, null);\n            buffer = cast(ubyte*).malloc(size + 2);\n            if (!buffer)\n                goto err2;\n            if (ReadFile(h, buffer, size, &numread, null) != TRUE)\n                goto err2;\n            if (numread != size)\n                goto err2;\n            if (!CloseHandle(h))\n                goto err;\n            len = size;\n            // Always store a wchar ^Z past end of buffer so scanner has a sentinel\n            buffer[size] = 0; // ^Z is obsolete, use 0\n            buffer[size + 1] = 0;\n            return 0;\n        err2:\n            CloseHandle(h);\n        err:\n            .free(buffer);\n            buffer = null;\n            len = 0;\n        err1:\n            return true;\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n\n    /*********************************************\n     * Write a file.\n     * Returns:\n     *      false       success\n     */\n    extern (C++) bool write()\n    {\n        version (Posix)\n        {\n            ssize_t numwritten;\n            const(char)* name = this.name.toChars();\n            int fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, (6 << 6) | (4 << 3) | 4);\n            if (fd == -1)\n                goto err;\n            numwritten = .write(fd, buffer, len);\n            if (len != numwritten)\n                goto err2;\n            if (close(fd) == -1)\n                goto err;\n            return false;\n        err2:\n            close(fd);\n            .remove(name);\n        err:\n            return true;\n        }\n        else version (Windows)\n        {\n            DWORD numwritten; // here because of the gotos\n            const(char)* name = this.name.toChars();\n            // work around Windows file path length limitation\n            // (see documentation for extendedPathThen).\n            HANDLE h = name.toDString.extendedPathThen!\n                (p => CreateFileW(p.ptr,\n                                  GENERIC_WRITE,\n                                  0,\n                                  null,\n                                  CREATE_ALWAYS,\n                                  FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,\n                                  null));\n            if (h == INVALID_HANDLE_VALUE)\n                goto err;\n\n            if (WriteFile(h, buffer, cast(DWORD)len, &numwritten, null) != TRUE)\n                goto err2;\n            if (len != numwritten)\n                goto err2;\n            if (!CloseHandle(h))\n                goto err;\n            return false;\n        err2:\n            CloseHandle(h);\n            DeleteFileA(name);\n        err:\n            return true;\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n\n    /* Set buffer\n     */\n    extern (C++) void setbuffer(void* buffer, size_t len)\n    {\n        this.buffer = cast(ubyte*)buffer;\n        this.len = len;\n    }\n\n    // delete file\n    extern (C++) void remove()\n    {\n        version (Posix)\n        {\n            int dummy = .remove(this.name.toChars());\n        }\n        else version (Windows)\n        {\n            DeleteFileA(this.name.toChars());\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/root/file.h",
    "content": "\n/* Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * All Rights Reserved, written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/root/file.h\n */\n\n#pragma once\n\n#include <stddef.h>\n\n#include \"array.h\"\n#include \"filename.h\"\n\ntypedef Array<struct File *> Files;\n\nstruct File\n{\n    int ref;                    // != 0 if this is a reference to someone else's buffer\n    unsigned char *buffer;      // data for our file\n    size_t len;                 // amount of data in buffer[]\n\n    FileName name;              // name of our file\n\n    static File *create(const char *);\n    ~File();\n\n    const char *toChars() const;\n\n    /* Read file, return true if error\n     */\n\n    bool read();\n\n    /* Write file, return true if error\n     */\n\n    bool write();\n\n    /* Set buffer\n     */\n\n    void setbuffer(void *buffer, size_t len)\n    {\n        this->buffer = (unsigned char *)buffer;\n        this->len = len;\n    }\n\n    void remove();              // delete file\n};\n"
  },
  {
    "path": "gcc/d/dmd/root/filename.d",
    "content": "/**\n * Compiler implementation of the D programming language\n * http://dlang.org\n *\n * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:   Walter Bright, http://www.digitalmars.com\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/filename.d, root/_filename.d)\n * Documentation:  https://dlang.org/phobos/dmd_root_filename.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/filename.d\n */\n\nmodule dmd.root.filename;\n\nimport core.stdc.ctype;\nimport core.stdc.errno;\nimport core.stdc.string;\nimport core.sys.posix.stdlib;\nimport core.sys.posix.sys.stat;\nimport core.sys.windows.windows;\nimport dmd.root.array;\nimport dmd.root.file;\nimport dmd.root.outbuffer;\nimport dmd.root.port;\nimport dmd.root.rmem;\nimport dmd.root.rootobject;\nimport dmd.utils;\n\nnothrow\n{\nversion (Windows) extern (Windows) DWORD GetFullPathNameW(LPCWSTR, DWORD, LPWSTR, LPWSTR*) @nogc;\nversion (Windows) extern (Windows) void SetLastError(DWORD) @nogc;\nversion (Windows) extern (C) char* getcwd(char* buffer, size_t maxlen);\nversion (Posix) extern (C) char* canonicalize_file_name(const char*);\nversion (Posix) import core.sys.posix.unistd : getcwd;\n}\nalias Strings = Array!(const(char)*);\nalias Files = Array!(File*);\n\n/***********************************************************\n * Encapsulate path and file names.\n */\nstruct FileName\n{\nnothrow:\n    private const(char)[] str;\n\n    ///\n    extern (D) this(const(char)[] str)\n    {\n        this.str = str.xarraydup;\n    }\n\n    /// Compare two name according to the platform's rules (case sensitive or not)\n    extern (C++) static bool equals(const(char)* name1, const(char)* name2) pure\n    {\n        return equals(name1.toDString, name2.toDString);\n    }\n\n    /// Ditto\n    extern (D) static bool equals(const(char)[] name1, const(char)[] name2) pure\n    {\n        if (name1.length != name2.length)\n            return false;\n\n        version (Windows)\n        {\n            return Port.memicmp(name1.ptr, name2.ptr, name1.length) == 0;\n        }\n        else\n        {\n            return name1 == name2;\n        }\n    }\n\n    /************************************\n     * Determine if path is absolute.\n     * Params:\n     *  name = path\n     * Returns:\n     *  true if absolute path name.\n     */\n    extern (C++) static bool absolute(const(char)* name) pure\n    {\n        return absolute(name.toDString);\n    }\n\n    /// Ditto\n    extern (D) static bool absolute(const(char)[] name) pure\n    {\n        if (!name.length)\n            return false;\n\n        version (Windows)\n        {\n            return (name[0] == '\\\\') || (name[0] == '/')\n                || (name.length >= 2 && name[1] == ':');\n        }\n        else version (Posix)\n        {\n            return (name[0] == '/');\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n\n    unittest\n    {\n        assert(absolute(\"/\"[]) == true);\n        assert(absolute(\"\"[]) == false);\n    }\n\n    /**\n    Return the given name as an absolute path\n\n    Params:\n        name = path\n        base = the absolute base to prefix name with if it is relative\n\n    Returns: name as an absolute path relative to base\n    */\n    extern (C++) static const(char)* toAbsolute(const(char)* name, const(char)* base = null)\n    {\n        const name_ = name.toDString();\n        const base_ = base ? base.toDString() : getcwd(null, 0).toDString();\n        return absolute(name_) ? name : combine(base_, name_).ptr;\n    }\n\n    /********************************\n     * Determine file name extension as slice of input.\n     * Params:\n     *  str = file name\n     * Returns:\n     *  filename extension (read-only).\n     *  Points past '.' of extension.\n     *  If there isn't one, return null.\n     */\n    extern (C++) static const(char)* ext(const(char)* str) pure\n    {\n        return ext(str.toDString).ptr;\n    }\n\n    /// Ditto\n    extern (D) static const(char)[] ext(const(char)[] str) nothrow pure @safe @nogc\n    {\n        foreach_reverse (idx, char e; str)\n        {\n            switch (e)\n            {\n            case '.':\n                return str[idx + 1 .. $];\n            version (Posix)\n            {\n            case '/':\n                return null;\n            }\n            version (Windows)\n            {\n            case '\\\\':\n            case ':':\n            case '/':\n                return null;\n            }\n            default:\n                continue;\n            }\n        }\n        return null;\n    }\n\n    unittest\n    {\n        assert(ext(\"/foo/bar/dmd.conf\"[]) == \"conf\");\n        assert(ext(\"object.o\"[]) == \"o\");\n        assert(ext(\"/foo/bar/dmd\"[]) == null);\n        assert(ext(\".objdir.o/object\"[]) == null);\n        assert(ext([]) == null);\n    }\n\n    extern (C++) const(char)* ext() const pure\n    {\n        return ext(str).ptr;\n    }\n\n    /********************************\n     * Return file name without extension.\n     *\n     * TODO:\n     * Once slice are used everywhere and `\\0` is not assumed,\n     * this can be turned into a simple slicing.\n     *\n     * Params:\n     *  str = file name\n     *\n     * Returns:\n     *  mem.xmalloc'd filename with extension removed.\n     */\n    extern (C++) static const(char)* removeExt(const(char)* str)\n    {\n        return removeExt(str.toDString).ptr;\n    }\n\n    /// Ditto\n    extern (D) static const(char)[] removeExt(const(char)[] str)\n    {\n        auto e = ext(str);\n        if (e.length)\n        {\n            const len = (str.length - e.length) - 1; // -1 for the dot\n            char* n = cast(char*)mem.xmalloc(len + 1);\n            memcpy(n, str.ptr, len);\n            n[len] = 0;\n            return n[0 .. len];\n        }\n        return mem.xstrdup(str.ptr)[0 .. str.length];\n    }\n\n    unittest\n    {\n        assert(removeExt(\"/foo/bar/object.d\"[]) == \"/foo/bar/object\");\n        assert(removeExt(\"/foo/bar/frontend.di\"[]) == \"/foo/bar/frontend\");\n    }\n\n    /********************************\n     * Return filename name excluding path (read-only).\n     */\n    extern (C++) static const(char)* name(const(char)* str) pure\n    {\n        return name(str.toDString).ptr;\n    }\n\n    /// Ditto\n    extern (D) static const(char)[] name(const(char)[] str) pure\n    {\n        foreach_reverse (idx, char e; str)\n        {\n            switch (e)\n            {\n                version (Posix)\n                {\n                case '/':\n                    return str[idx + 1 .. $];\n                }\n                version (Windows)\n                {\n                case '/':\n                case '\\\\':\n                    return str[idx + 1 .. $];\n                case ':':\n                    /* The ':' is a drive letter only if it is the second\n                     * character or the last character,\n                     * otherwise it is an ADS (Alternate Data Stream) separator.\n                     * Consider ADS separators as part of the file name.\n                     */\n                    if (idx == 1 || idx == str.length - 1)\n                        return str[idx + 1 .. $];\n                    break;\n                }\n            default:\n                break;\n            }\n        }\n        return str;\n    }\n\n    extern (C++) const(char)* name() const pure\n    {\n        return name(str).ptr;\n    }\n\n    unittest\n    {\n        assert(name(\"/foo/bar/object.d\"[]) == \"object.d\");\n        assert(name(\"/foo/bar/frontend.di\"[]) == \"frontend.di\");\n    }\n\n    /**************************************\n     * Return path portion of str.\n     * Path will does not include trailing path separator.\n     */\n    extern (C++) static const(char)* path(const(char)* str)\n    {\n        return path(str.toDString).ptr;\n    }\n\n    /// Ditto\n    extern (D) static const(char)[] path(const(char)[] str)\n    {\n        const n = name(str);\n        bool hasTrailingSlash;\n        if (n.length < str.length)\n        {\n            version (Posix)\n            {\n                if (str[$ - n.length - 1] == '/')\n                    hasTrailingSlash = true;\n            }\n            else version (Windows)\n            {\n                if (str[$ - n.length - 1] == '\\\\' || str[$ - n.length - 1] == '/')\n                    hasTrailingSlash = true;\n            }\n            else\n            {\n                assert(0);\n            }\n        }\n        const pathlen = str.length - n.length - (hasTrailingSlash ? 1 : 0);\n        char* path = cast(char*)mem.xmalloc(pathlen + 1);\n        memcpy(path, str.ptr, pathlen);\n        path[pathlen] = 0;\n        return path[0 .. pathlen];\n    }\n\n    unittest\n    {\n        assert(path(\"/foo/bar\"[]) == \"/foo\");\n        assert(path(\"foo\"[]) == \"\");\n    }\n\n    /**************************************\n     * Replace filename portion of path.\n     */\n    extern (D) static const(char)[] replaceName(const(char)[] path, const(char)[] name)\n    {\n        if (absolute(name))\n            return name;\n        auto n = FileName.name(path);\n        if (n == path)\n            return name;\n        return combine(path[0 .. $ - n.length], name);\n    }\n\n    /**\n       Combine a `path` and a file `name`\n\n       Params:\n         path = Path to append to\n         name = Name to append to path\n\n       Returns:\n         The `\\0` terminated string which is the combination of `path` and `name`\n         and a valid path.\n    */\n    extern (C++) static const(char)* combine(const(char)* path, const(char)* name)\n    {\n        if (!path)\n            return name;\n        return combine(path.toDString, name.toDString).ptr;\n    }\n\n    /// Ditto\n    extern(D) static const(char)[] combine(const(char)[] path, const(char)[] name)\n    {\n        if (!path.length)\n            return name;\n\n        char* f = cast(char*)mem.xmalloc(path.length + 1 + name.length + 1);\n        memcpy(f, path.ptr, path.length);\n        bool trailingSlash = false;\n        version (Posix)\n        {\n            if (path[$ - 1] != '/')\n            {\n                f[path.length] = '/';\n                trailingSlash = true;\n            }\n        }\n        else version (Windows)\n        {\n            if (path[$ - 1] != '\\\\' && path[$ - 1] != '/' && path[$ - 1] != ':')\n            {\n                f[path.length] = '\\\\';\n                trailingSlash = true;\n            }\n        }\n        else\n        {\n            assert(0);\n        }\n        const len = path.length + trailingSlash;\n        memcpy(f + len, name.ptr, name.length);\n        // Note: At the moment `const(char)*` are being transitioned to\n        // `const(char)[]`. To avoid bugs crippling in, we `\\0` terminate\n        // slices, but don't include it in the slice so `.ptr` can be used.\n        f[len + name.length] = '\\0';\n        return f[0 .. len + name.length];\n    }\n\n    unittest\n    {\n        version (Windows)\n            assert(combine(\"foo\"[], \"bar\"[]) == \"foo\\\\bar\");\n        else\n            assert(combine(\"foo\"[], \"bar\"[]) == \"foo/bar\");\n        assert(combine(\"foo/\"[], \"bar\"[]) == \"foo/bar\");\n    }\n\n    static const(char)* buildPath(const(char)* path, const(char)*[] names...)\n    {\n        foreach (const(char)* name; names)\n            path = combine(path, name);\n        return path;\n    }\n\n    // Split a path into an Array of paths\n    extern (C++) static Strings* splitPath(const(char)* path)\n    {\n        char c = 0; // unnecessary initializer is for VC /W4\n        const(char)* p;\n        OutBuffer buf;\n        Strings* array;\n        array = new Strings();\n        if (path)\n        {\n            p = path;\n            do\n            {\n                char instring = 0;\n                while (isspace(cast(char)*p)) // skip leading whitespace\n                    p++;\n                buf.reserve(strlen(p) + 1); // guess size of path\n                for (;; p++)\n                {\n                    c = *p;\n                    switch (c)\n                    {\n                    case '\"':\n                        instring ^= 1; // toggle inside/outside of string\n                        continue;\n                        version (OSX)\n                        {\n                        case ',':\n                        }\n                        version (Windows)\n                        {\n                        case ';':\n                        }\n                        version (Posix)\n                        {\n                        case ':':\n                        }\n                        p++;\n                        break;\n                        // note that ; cannot appear as part\n                        // of a path, quotes won't protect it\n                    case 0x1A:\n                        // ^Z means end of file\n                    case 0:\n                        break;\n                    case '\\r':\n                        continue;\n                        // ignore carriage returns\n                        version (Posix)\n                        {\n                        case '~':\n                            {\n                                char* home = getenv(\"HOME\");\n                                if (home)\n                                    buf.writestring(home);\n                                else\n                                    buf.writestring(\"~\");\n                                continue;\n                            }\n                        }\n                        version (none)\n                        {\n                        case ' ':\n                        case '\\t':\n                            // tabs in filenames?\n                            if (!instring) // if not in string\n                                break;\n                            // treat as end of path\n                        }\n                    default:\n                        buf.writeByte(c);\n                        continue;\n                    }\n                    break;\n                }\n                if (buf.offset) // if path is not empty\n                {\n                    array.push(buf.extractString());\n                }\n            }\n            while (c);\n        }\n        return array;\n    }\n\n    /**\n     * Add the extension `ext` to `name`, regardless of the content of `name`\n     *\n     * Params:\n     *   name = Path to append the extension to\n     *   ext  = Extension to add (should not include '.')\n     *\n     * Returns:\n     *   A newly allocated string (free with `FileName.free`)\n     */\n    extern(D) static char[] addExt(const(char)[] name, const(char)[] ext)\n    {\n        const len = name.length + ext.length + 2;\n        auto s = cast(char*)mem.xmalloc(len);\n        s[0 .. name.length] = name[];\n        s[name.length] = '.';\n        s[name.length + 1 .. len - 1] = ext[];\n        s[len - 1] = '\\0';\n        return s[0 .. len - 1];\n    }\n\n\n    /***************************\n     * Free returned value with FileName::free()\n     */\n    extern (C++) static const(char)* defaultExt(const(char)* name, const(char)* ext)\n    {\n        return defaultExt(name.toDString, ext.toDString).ptr;\n    }\n\n    /// Ditto\n    extern (D) static const(char)[] defaultExt(const(char)[] name, const(char)[] ext)\n    {\n        auto e = FileName.ext(name);\n        if (e.length) // it already has an extension\n            return name.xarraydup;\n        return addExt(name, ext);\n    }\n\n    unittest\n    {\n        assert(defaultExt(\"/foo/object.d\"[], \"d\") == \"/foo/object.d\");\n        assert(defaultExt(\"/foo/object\"[], \"d\") == \"/foo/object.d\");\n        assert(defaultExt(\"/foo/bar.d\"[], \"o\") == \"/foo/bar.d\");\n    }\n\n    /***************************\n     * Free returned value with FileName::free()\n     */\n    extern (C++) static const(char)* forceExt(const(char)* name, const(char)* ext)\n    {\n        return forceExt(name.toDString, ext.toDString).ptr;\n    }\n\n    /// Ditto\n    extern (D) static const(char)[] forceExt(const(char)[] name, const(char)[] ext)\n    {\n        if (auto e = FileName.ext(name))\n            return addExt(name[0 .. $ - e.length - 1], ext);\n        return defaultExt(name, ext); // doesn't have one\n    }\n\n    unittest\n    {\n        assert(forceExt(\"/foo/object.d\"[], \"d\") == \"/foo/object.d\");\n        assert(forceExt(\"/foo/object\"[], \"d\") == \"/foo/object.d\");\n        assert(forceExt(\"/foo/bar.d\"[], \"o\") == \"/foo/bar.o\");\n    }\n\n    /// Returns:\n    ///   `true` if `name`'s extension is `ext`\n    extern (C++) static bool equalsExt(const(char)* name, const(char)* ext) pure\n    {\n        return equalsExt(name.toDString, ext.toDString);\n    }\n\n    /// Ditto\n    extern (D) static bool equalsExt(const(char)[] name, const(char)[] ext) pure\n    {\n        auto e = FileName.ext(name);\n        if (!e.length && !ext.length)\n            return true;\n        if (!e.length || !ext.length)\n            return false;\n        return FileName.equals(e, ext);\n    }\n\n    unittest\n    {\n        assert(!equalsExt(\"foo.bar\"[], \"d\"));\n        assert(equalsExt(\"foo.bar\"[], \"bar\"));\n        assert(equalsExt(\"object.d\"[], \"d\"));\n        assert(!equalsExt(\"object\"[], \"d\"));\n    }\n\n    /******************************\n     * Return !=0 if extensions match.\n     */\n    extern (C++) bool equalsExt(const(char)* ext) const pure\n    {\n        return equalsExt(str, ext.toDString());\n    }\n\n    /*************************************\n     * Search Path for file.\n     * Input:\n     *      cwd     if true, search current directory before searching path\n     */\n    extern (C++) static const(char)* searchPath(Strings* path, const(char)* name, bool cwd)\n    {\n        return searchPath(path, name.toDString, cwd).ptr;\n    }\n\n    extern (D) static const(char)[] searchPath(Strings* path, const(char)[] name, bool cwd)\n    {\n        if (absolute(name))\n        {\n            return exists(name) ? name : null;\n        }\n        if (cwd)\n        {\n            if (exists(name))\n                return name;\n        }\n        if (path)\n        {\n            foreach (p; *path)\n            {\n                auto n = combine(p.toDString, name);\n                if (exists(n))\n                    return n;\n            }\n        }\n        return null;\n    }\n\n    /*************************************\n     * Search Path for file in a safe manner.\n     *\n     * Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory\n     * ('Path Traversal') attacks.\n     *      http://cwe.mitre.org/data/definitions/22.html\n     * More info:\n     *      https://www.securecoding.cert.org/confluence/display/c/FIO02-C.+Canonicalize+path+names+originating+from+tainted+sources\n     * Returns:\n     *      NULL    file not found\n     *      !=NULL  mem.xmalloc'd file name\n     */\n    extern (C++) static const(char)* safeSearchPath(Strings* path, const(char)* name)\n    {\n        version (Windows)\n        {\n            // don't allow leading / because it might be an absolute\n            // path or UNC path or something we'd prefer to just not deal with\n            if (*name == '/')\n            {\n                return null;\n            }\n            /* Disallow % \\ : and .. in name characters\n             * We allow / for compatibility with subdirectories which is allowed\n             * on dmd/posix. With the leading / blocked above and the rest of these\n             * conservative restrictions, we should be OK.\n             */\n            for (const(char)* p = name; *p; p++)\n            {\n                char c = *p;\n                if (c == '\\\\' || c == ':' || c == '%' || (c == '.' && p[1] == '.') || (c == '/' && p[1] == '/'))\n                {\n                    return null;\n                }\n            }\n            return FileName.searchPath(path, name, false);\n        }\n        else version (Posix)\n        {\n            /* Even with realpath(), we must check for // and disallow it\n             */\n            for (const(char)* p = name; *p; p++)\n            {\n                char c = *p;\n                if (c == '/' && p[1] == '/')\n                {\n                    return null;\n                }\n            }\n            if (path)\n            {\n                /* Each path is converted to a cannonical name and then a check is done to see\n                 * that the searched name is really a child one of the the paths searched.\n                 */\n                for (size_t i = 0; i < path.dim; i++)\n                {\n                    const(char)* cname = null;\n                    const(char)* cpath = canonicalName((*path)[i]);\n                    //printf(\"FileName::safeSearchPath(): name=%s; path=%s; cpath=%s\\n\",\n                    //      name, (char *)path.data[i], cpath);\n                    if (cpath is null)\n                        goto cont;\n                    cname = canonicalName(combine(cpath, name));\n                    //printf(\"FileName::safeSearchPath(): cname=%s\\n\", cname);\n                    if (cname is null)\n                        goto cont;\n                    //printf(\"FileName::safeSearchPath(): exists=%i \"\n                    //      \"strncmp(cpath, cname, %i)=%i\\n\", exists(cname),\n                    //      strlen(cpath), strncmp(cpath, cname, strlen(cpath)));\n                    // exists and name is *really* a \"child\" of path\n                    if (exists(cname) && strncmp(cpath, cname, strlen(cpath)) == 0)\n                    {\n                        .free(cast(void*)cpath);\n                        const(char)* p = mem.xstrdup(cname);\n                        .free(cast(void*)cname);\n                        return p;\n                    }\n                cont:\n                    if (cpath)\n                        .free(cast(void*)cpath);\n                    if (cname)\n                        .free(cast(void*)cname);\n                }\n            }\n            return null;\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n\n    /**\n       Check if the file the `path` points to exists\n\n       Returns:\n         0 if it does not exists\n         1 if it exists and is not a directory\n         2 if it exists and is a directory\n     */\n    extern (C++) static int exists(const(char)* name)\n    {\n        return exists(name.toDString);\n    }\n\n    /// Ditto\n    extern (D) static int exists(const(char)[] name)\n    {\n        if (!name.length)\n            return 0;\n        version (Posix)\n        {\n            stat_t st;\n            if (name.toCStringThen!((v) => stat(v.ptr, &st)) < 0)\n                return 0;\n            if (S_ISDIR(st.st_mode))\n                return 2;\n            return 1;\n        }\n        else version (Windows)\n        {\n            return name.toCStringThen!((cstr) => cstr.toWStringzThen!((wname)\n            {\n                const dw = GetFileAttributesW(&wname[0]);\n                if (dw == -1)\n                    return 0;\n                else if (dw & FILE_ATTRIBUTE_DIRECTORY)\n                    return 2;\n                else\n                    return 1;\n            }));\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n\n    /**\n       Ensure that the provided path exists\n\n       Accepts a path to either a file or a directory.\n       In the former case, the basepath (path to the containing directory)\n       will be checked for existence, and created if it does not exists.\n       In the later case, the directory pointed to will be checked for existence\n       and created if needed.\n\n       Params:\n         path = a path to a file or a directory\n\n       Returns:\n         `true` if the directory exists or was successfully created\n     */\n    extern (C++) static bool ensurePathExists(const(char)* path)\n    {\n        //printf(\"FileName::ensurePathExists(%s)\\n\", path ? path : \"\");\n        if (!path || !(*path))\n            return true;\n        if (exists(path))\n            return true;\n\n        // We were provided with a file name\n        // We need to call ourselves recursively to ensure parent dir exist\n        const(char)* p = FileName.path(path);\n        if (*p)\n        {\n            version (Windows)\n            {\n                const len = strlen(path);\n                const plen = strlen(p);\n                // Note: Windows filename comparison should be case-insensitive,\n                // however p is a subslice of path so we don't need it\n                if (len == plen ||\n                    (len > 2 && path[1] == ':' && path[2 .. len] == p[0 .. plen]))\n                {\n                    mem.xfree(cast(void*)p);\n                    return true;\n                }\n            }\n            const r = ensurePathExists(p);\n            mem.xfree(cast(void*)p);\n\n            if (!r)\n                return r;\n        }\n\n        version (Windows)\n            const r = _mkdir(path.toDString);\n        version (Posix)\n        {\n            errno = 0;\n            const r = mkdir(path, (7 << 6) | (7 << 3) | 7);\n        }\n\n        if (r == 0)\n            return true;\n\n        // Don't error out if another instance of dmd just created\n        // this directory\n        version (Windows)\n        {\n            import core.sys.windows.winerror : ERROR_ALREADY_EXISTS;\n            if (GetLastError() == ERROR_ALREADY_EXISTS)\n                return true;\n        }\n        version (Posix)\n        {\n            if (errno == EEXIST)\n                return true;\n        }\n\n        return false;\n    }\n\n    /******************************************\n     * Return canonical version of name in a malloc'd buffer.\n     * This code is high risk.\n     */\n    extern (C++) static const(char)* canonicalName(const(char)* name)\n    {\n        return canonicalName(name.toDString).ptr;\n    }\n\n    /// Ditto\n    extern (D) static const(char)[] canonicalName(const(char)[] name)\n    {\n        version (Posix)\n        {\n            // NULL destination buffer is allowed and preferred\n            return name.toCStringThen!((n) => realpath(n.ptr, null)).toDString;\n        }\n        else version (Windows)\n        {\n            // Convert to wstring first since otherwise the Win32 APIs have a character limit\n            return name.toWStringzThen!((wname)\n            {\n                /* Apparently, there is no good way to do this on Windows.\n                 * GetFullPathName isn't it, but use it anyway.\n                 */\n                // First find out how long the buffer has to be.\n                auto fullPathLength = GetFullPathNameW(&wname[0], 0, null, null);\n                if (!fullPathLength) return null;\n                auto fullPath = new wchar[fullPathLength];\n\n                // Actually get the full path name\n                const fullPathLengthNoTerminator = GetFullPathNameW(\n                    &wname[0], cast(uint)fullPath.length, &fullPath[0], null /*filePart*/);\n                // Unfortunately, when the buffer is large enough the return value is the number of characters\n                // _not_ counting the null terminator, so fullPathLengthNoTerminator should be smaller\n                assert(fullPathLength > fullPathLengthNoTerminator);\n\n                // Find out size of the converted string\n                const retLength = WideCharToMultiByte(\n                    0 /*codepage*/, 0 /*flags*/, &fullPath[0], fullPathLength, null, 0, null, null);\n                auto ret = new char[retLength];\n\n                // Actually convert to char\n                const retLength2 = WideCharToMultiByte(\n                    0 /*codepage*/, 0 /*flags*/, &fullPath[0], cast(int)fullPath.length, &ret[0], cast(int)ret.length, null, null);\n                assert(retLength == retLength2);\n\n                return ret;\n            });\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n\n    /********************************\n     * Free memory allocated by FileName routines\n     */\n    extern (C++) static void free(const(char)* str)\n    {\n        if (str)\n        {\n            assert(str[0] != cast(char)0xAB);\n            memset(cast(void*)str, 0xAB, strlen(str) + 1); // stomp\n        }\n        mem.xfree(cast(void*)str);\n    }\n\n    extern (C++) const(char)* toChars() const pure nothrow @trusted\n    {\n        // Since we can return an empty slice (but '\\0' terminated),\n        // we don't do bounds check (as `&str[0]` does)\n        return str.ptr;\n    }\n\n    const(char)[] toString() const pure nothrow @trusted\n    {\n        return str;\n    }\n}\n\nversion(Windows)\n{\n    /****************************************************************\n     * The code before used the POSIX function `mkdir` on Windows. That\n     * function is now deprecated and fails with long paths, so instead\n     * we use the newer `CreateDirectoryW`.\n     *\n     * `CreateDirectoryW` is the unicode version of the generic macro\n     * `CreateDirectory`.  `CreateDirectoryA` has a file path\n     *  limitation of 248 characters, `mkdir` fails with less and might\n     *  fail due to the number of consecutive `..`s in the\n     *  path. `CreateDirectoryW` also normally has a 248 character\n     * limit, unless the path is absolute and starts with `\\\\?\\`. Note\n     * that this is different from starting with the almost identical\n     * `\\\\?`.\n     *\n     * Params:\n     *  path = The path to create.\n     *\n     * Returns:\n     *  0 on success, 1 on failure.\n     *\n     * References:\n     *  https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx\n     */\n    private int _mkdir(const(char)[] path) nothrow\n    {\n        const createRet = path.extendedPathThen!(\n            p => CreateDirectoryW(&p[0], null /*securityAttributes*/));\n        // different conventions for CreateDirectory and mkdir\n        return createRet == 0 ? 1 : 0;\n    }\n\n    /**************************************\n     * Converts a path to one suitable to be passed to Win32 API\n     * functions that can deal with paths longer than 248\n     * characters then calls the supplied function on it.\n     *\n     * Params:\n     *  path = The Path to call F on.\n     *\n     * Returns:\n     *  The result of calling F on path.\n     *\n     * References:\n     *  https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx\n     */\n    package auto extendedPathThen(alias F)(const(char)[] path)\n    {\n        if (!path.length)\n            return F((wchar[]).init);\n        return path.toWStringzThen!((wpath)\n        {\n            // GetFullPathNameW expects a sized buffer to store the result in. Since we don't\n            // know how large it has to be, we pass in null and get the needed buffer length\n            // as the return code.\n            const pathLength = GetFullPathNameW(&wpath[0],\n                                                0 /*length8*/,\n                                                null /*output buffer*/,\n                                                null /*filePartBuffer*/);\n            if (pathLength == 0)\n            {\n                return F((wchar[]).init);\n            }\n\n            // wpath is the UTF16 version of path, but to be able to use\n            // extended paths, we need to prefix with `\\\\?\\` and the absolute\n            // path.\n            static immutable prefix = `\\\\?\\`w;\n\n            // prefix only needed for long names and non-UNC names\n            const needsPrefix = pathLength >= MAX_PATH && (wpath[0] != '\\\\' || wpath[1] != '\\\\');\n            const prefixLength = needsPrefix ? prefix.length : 0;\n\n            // +1 for the null terminator\n            const bufferLength = pathLength + prefixLength + 1;\n\n            wchar[1024] absBuf = void;\n            wchar[] absPath = bufferLength > absBuf.length\n                ? new wchar[bufferLength] : absBuf[0 .. bufferLength];\n\n            absPath[0 .. prefixLength] = prefix[0 .. prefixLength];\n\n            const absPathRet = GetFullPathNameW(&wpath[0],\n                cast(uint)(absPath.length - prefixLength - 1),\n                &absPath[prefixLength],\n                null /*filePartBuffer*/);\n\n            if (absPathRet == 0 || absPathRet > absPath.length - prefixLength)\n            {\n                return F((wchar[]).init);\n            }\n\n            absPath[$ - 1] = '\\0';\n            // Strip null terminator from the slice\n            return F(absPath[0 .. $ - 1]);\n        });\n    }\n\n    /**********************************\n     * Converts a slice of UTF-8 characters to an array of wchar that's null\n     * terminated so it can be passed to Win32 APIs then calls the supplied\n     * function on it.\n     *\n     * Params:\n     *  str = The string to convert.\n     *\n     * Returns:\n     *  The result of calling F on the UTF16 version of str.\n     */\n    private auto toWStringzThen(alias F)(const(char)[] str) nothrow\n    {\n        if (!str.length) return F(\"\"w.ptr);\n\n        import core.stdc.string: strlen;\n        import core.stdc.stdlib: malloc, free;\n        import core.sys.windows.winnls: MultiByteToWideChar;\n        wchar[1024] buf;\n        // first find out how long the buffer must be to store the result\n\n        const length = MultiByteToWideChar(0 /*codepage*/, 0 /*flags*/, &str[0], cast(int)str.length, null, 0);\n        if (!length) return F(\"\"w);\n\n        wchar[] ret = length >= buf.length\n            ? (cast(wchar*)malloc(length * wchar.sizeof))[0 .. length + 1]\n            : buf[0 .. length + 1];\n        scope (exit)\n        {\n            if (&ret[0] != &buf[0])\n                free(&ret[0]);\n        }\n        // actually do the conversion\n        const length2 = MultiByteToWideChar(\n            0 /*codepage*/, 0 /*flags*/, &str[0], cast(int)str.length, &ret[0], cast(int)length);\n        assert(str.length == length2); // should always be true according to the API\n        // Add terminating `\\0`\n        ret[$ - 1] = '\\0';\n\n        return F(ret[0 .. $ - 1]);\n    }\n}\n\nversion (Posix)\n{\n    /**\n    Takes a callable F and applies it to the result of converting\n    `fileName` to an absolute file path (char*)\n\n    Params:\n        fileName = The file name to be converted to an absolute path\n    Returns: Whatever `F` returns.\n    */\n    auto absPathThen(alias F)(const(char)[] fileName)\n    {\n        import core.sys.posix.stdlib: realpath, free;\n        char* absPath = fileName.toCStringThen!((fn) => realpath(&fn[0], null /* realpath allocates */));\n        scope(exit) free(absPath);\n        return F(absPath.toDString());\n    }\n}\nelse\n{\n    /**\n    Takes a callable F and applies it to the result of converting\n    `fileName` to an absolute file path (char*)\n\n    Params:\n        fileName = The file name to be converted to an absolute path\n    Returns: Whatever `F` returns.\n     */\n    auto absPathThen(alias F)(const(char)[] fileName)\n    {\n        import core.sys.windows.winnls: WideCharToMultiByte;\n        import core.stdc.stdlib: malloc, free;\n\n        return fileName.extendedPathThen!((wpath) {\n                // first find out how long the buffer must be to store the result\n                const length = WideCharToMultiByte(0,    // code page\n                                                   0,    // flags\n                                                   &wpath[0],\n                                                   -1,   // wpath len, -1 is null terminated\n                                                   null, // multibyte output ptr\n                                                   0,    // multibyte output length\n                                                   null, // default char\n                                                   null, // if used default char\n                );\n\n                if (!length) return F((char[]).init);\n\n                char[1024] buf = void;\n\n                scope multibyteBuf = length > buf.length\n                    ? (cast(char*)malloc(length * char.sizeof))[0 .. length]\n                    : buf[0 .. length];\n                scope (exit)\n                {\n                    if (multibyteBuf.ptr != buf.ptr)\n                        free(multibyteBuf.ptr);\n                }\n\n                // now store the result\n                const length2 = WideCharToMultiByte(0,    // code page\n                                                    0,    // flags\n                                                    &wpath[0],\n                                                    -1,   // wpath len, -1 is null terminated\n                                                    multibyteBuf.ptr,\n                                                    length,\n                                                    null, // default char\n                                                    null, // if used default char\n                );\n\n                assert(length == length2);\n\n                return F(multibyteBuf[0 .. length - 1]);\n        });\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/root/filename.h",
    "content": "\n/* Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * All Rights Reserved, written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/root/filename.h\n */\n\n#pragma once\n\n#include \"array.h\"\n#include \"dcompat.h\"\n\ntypedef Array<const char *> Strings;\n\nstruct FileName\n{\nprivate:\n    DArray<const char> str;\npublic:\n    static bool equals(const char *name1, const char *name2);\n    static bool absolute(const char *name);\n    static const char *toAbsolute(const char *name, const char *base = NULL);\n    static const char *ext(const char *);\n    const char *ext();\n    static const char *removeExt(const char *str);\n    static const char *name(const char *);\n    const char *name();\n    static const char *path(const char *);\n\n    static const char *combine(const char *path, const char *name);\n    static Strings *splitPath(const char *path);\n    static const char *defaultExt(const char *name, const char *ext);\n    static const char *forceExt(const char *name, const char *ext);\n    static bool equalsExt(const char *name, const char *ext);\n\n    bool equalsExt(const char *ext);\n\n    static const char *searchPath(Strings *path, const char *name, bool cwd);\n    static const char *safeSearchPath(Strings *path, const char *name);\n    static int exists(const char *name);\n    static bool ensurePathExists(const char *path);\n    static const char *canonicalName(const char *name);\n\n    static void free(const char *str);\n    const char *toChars() const;\n};\n"
  },
  {
    "path": "gcc/d/dmd/root/hash.d",
    "content": "/**\n * Compiler implementation of the D programming language\n * http://dlang.org\n *\n * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:   Martin Nowak, Walter Bright, http://www.digitalmars.com\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/hash.d, root/_hash.d)\n * Documentation:  https://dlang.org/phobos/dmd_root_hash.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/hash.d\n */\n\nmodule dmd.root.hash;\n\n// MurmurHash2 was written by Austin Appleby, and is placed in the public\n// domain. The author hereby disclaims copyright to this source code.\n// https://sites.google.com/site/murmurhash/\nuint calcHash(const(char)* data, size_t len) pure nothrow @nogc\n{\n    return calcHash(cast(const(ubyte)*)data, len);\n}\n\nuint calcHash(const(ubyte)* data, size_t len) pure nothrow @nogc\n{\n    // 'm' and 'r' are mixing constants generated offline.\n    // They're not really 'magic', they just happen to work well.\n    enum uint m = 0x5bd1e995;\n    enum int r = 24;\n    // Initialize the hash to a 'random' value\n    uint h = cast(uint)len;\n    // Mix 4 bytes at a time into the hash\n    while (len >= 4)\n    {\n        uint k = data[3] << 24 | data[2] << 16 | data[1] << 8 | data[0];\n        k *= m;\n        k ^= k >> r;\n        h = (h * m) ^ (k * m);\n        data += 4;\n        len -= 4;\n    }\n    // Handle the last few bytes of the input array\n    switch (len & 3)\n    {\n    case 3:\n        h ^= data[2] << 16;\n        goto case;\n    case 2:\n        h ^= data[1] << 8;\n        goto case;\n    case 1:\n        h ^= data[0];\n        h *= m;\n        goto default;\n    default:\n        break;\n    }\n    // Do a few final mixes of the hash to ensure the last few\n    // bytes are well-incorporated.\n    h ^= h >> 13;\n    h *= m;\n    h ^= h >> 15;\n    return h;\n}\n\n// combine and mix two words (boost::hash_combine)\nsize_t mixHash(size_t h, size_t k)\n{\n    return h ^ (k + 0x9e3779b9 + (h << 6) + (h >> 2));\n}\n"
  },
  {
    "path": "gcc/d/dmd/root/longdouble.d",
    "content": "/* longdouble.d -- Software floating point emulation for the D frontend.\n * Copyright (C) 2018 Free Software Foundation, Inc.\n *\n * GCC is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3, or (at your option)\n * any later version.\n *\n * GCC is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with GCC; see the file COPYING3.  If not see\n * <http://www.gnu.org/licenses/>.\n */\n\nmodule dmd.root.longdouble;\n\nimport core.stdc.config;\nimport core.stdc.stdint;\n\nnothrow:\n@nogc:\n\n// Type used by the front-end for compile-time reals\nstruct longdouble\n{\n    this(T)(T r)\n    {\n        this.set(r);\n    }\n\n    // No constructor to be able to use this class in a union.\n    longdouble opAssign(T)(T r)\n        if (is (T : longdouble))\n    {\n        this.realvalue = r.realvalue; \n        return this;\n    }\n\n    longdouble opAssign(T)(T r)\n        if (!is (T : longdouble))\n    {\n        this.set(r);\n        return this;\n    }\n\n    // Arithmetic operators.\n    longdouble opBinary(string op, T)(T r) const\n        if ((op == \"+\" || op == \"-\" || op == \"*\" || op == \"/\" || op == \"%\")\n            && is (T : longdouble))\n    {\n        static if (op == \"+\")\n            return this.add(r);\n        else static if (op == \"-\")\n            return this.sub(r);\n        else static if (op == \"*\")\n            return this.mul(r);\n        else static if (op == \"/\")\n            return this.div(r);\n        else static if (op == \"%\")\n            return this.mod(r);\n    }\n\n    longdouble opUnary(string op)() const\n        if (op == \"-\")\n    {\n        return this.neg();\n    }\n\n    int opCmp(longdouble r) const\n    {\n        return this.cmp(r);\n    }\n\n    int opEquals(longdouble r) const\n    {\n        return this.equals(r);\n    }\n\n    bool opCast(T : bool)() const\n    {\n        return this.to_bool();\n    }\n\n    T opCast(T)() const\n    {\n        static if (__traits(isUnsigned, T))\n            return cast (T) this.to_uint();\n        else\n            return cast(T) this.to_int();\n    }\n\n    extern (C++):\n\n    void set(int8_t d);\n    void set(int16_t d);\n    void set(int32_t d);\n    void set(int64_t d);\n    void set(uint8_t d);\n    void set(uint16_t d);\n    void set(uint32_t d);\n    void set(uint64_t d);\n    void set(bool d);\n\n    int64_t to_int() const;\n    uint64_t to_uint() const;\n    bool to_bool() const;\n\n    longdouble add(const ref longdouble r) const;\n    longdouble sub(const ref longdouble r) const;\n    longdouble mul(const ref longdouble r) const;\n    longdouble div(const ref longdouble r) const;\n    longdouble mod(const ref longdouble r) const;\n    longdouble neg() const;\n    int cmp(const ref longdouble t) const;\n    int equals(const ref longdouble t) const;\n\nprivate:\n    // Statically allocate enough space for REAL_VALUE_TYPE.\n    enum realvalue_size = (2 + (16 + c_long.sizeof) / c_long.sizeof);\n    c_long [realvalue_size] realvalue;\n}\n\n"
  },
  {
    "path": "gcc/d/dmd/root/object.h",
    "content": "\n/* Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * All Rights Reserved, written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/root/object.h\n */\n\n#pragma once\n\n#define POSIX (__linux__ || __GLIBC__ || __gnu_hurd__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun)\n\n#include \"dcompat.h\"\n#include <stddef.h>\n\ntypedef size_t hash_t;\n\nstruct OutBuffer;\n\nenum DYNCAST\n{\n    DYNCAST_OBJECT,\n    DYNCAST_EXPRESSION,\n    DYNCAST_DSYMBOL,\n    DYNCAST_TYPE,\n    DYNCAST_IDENTIFIER,\n    DYNCAST_TUPLE,\n    DYNCAST_PARAMETER,\n    DYNCAST_STATEMENT,\n    DYNCAST_TEMPLATEPARAMETER\n};\n\n/*\n * Root of our class library.\n */\nclass RootObject\n{\npublic:\n    RootObject() { }\n\n    virtual bool equals(RootObject *o);\n\n    /**\n     * Return <0, ==0, or >0 if this is less than, equal to, or greater than obj.\n     * Useful for sorting Objects.\n     */\n    virtual int compare(RootObject *obj);\n\n    /**\n     * Pretty-print an Object. Useful for debugging the old-fashioned way.\n     */\n    virtual const char *toChars();\n    /// This function is `extern(D)` and should not be called from C++,\n    /// as the ABI does not match on some platforms\n    virtual DArray<const char> toString();\n    virtual void toBuffer(OutBuffer *buf);\n\n    /**\n     * Used as a replacement for dynamic_cast. Returns a unique number\n     * defined by the library user. For Object, the return value is 0.\n     */\n    virtual int dyncast() const;\n};\n"
  },
  {
    "path": "gcc/d/dmd/root/outbuffer.d",
    "content": "/**\n * Compiler implementation of the D programming language\n * http://dlang.org\n *\n * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:   Walter Bright, http://www.digitalmars.com\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/outbuffer.d, root/_outbuffer.d)\n * Documentation: https://dlang.org/phobos/dmd_root_outbuffer.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/outbuffer.d\n */\n\nmodule dmd.root.outbuffer;\n\nimport core.stdc.stdarg;\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.root.rmem;\nimport dmd.root.rootobject;\n\nstruct OutBuffer\n{\n    ubyte* data;\n    size_t offset;\n    size_t size;\n    int level;\n    bool doindent;\n    private bool notlinehead;\n\n    extern (C++) ~this() nothrow\n    {\n        mem.xfree(data);\n    }\n\n    extern (C++) char* extractData() nothrow\n    {\n        char* p;\n        p = cast(char*)data;\n        data = null;\n        offset = 0;\n        size = 0;\n        return p;\n    }\n\n    extern (C++) void reserve(size_t nbytes) nothrow\n    {\n        //printf(\"OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\\n\", size, offset, nbytes);\n        if (size - offset < nbytes)\n        {\n            /* Increase by factor of 1.5; round up to 16 bytes.\n             * The odd formulation is so it will map onto single x86 LEA instruction.\n             */\n            size = (((offset + nbytes) * 3 + 30) / 2) & ~15;\n            data = cast(ubyte*)mem.xrealloc(data, size);\n        }\n    }\n\n    extern (C++) void setsize(size_t size) nothrow\n    {\n        offset = size;\n    }\n\n    extern (C++) void reset() nothrow\n    {\n        offset = 0;\n    }\n\n    private void indent() nothrow\n    {\n        if (level)\n        {\n            reserve(level);\n            data[offset .. offset + level] = '\\t';\n            offset += level;\n        }\n        notlinehead = true;\n    }\n\n    extern (C++) void write(const(void)* data, size_t nbytes) nothrow\n    {\n        if (doindent && !notlinehead)\n            indent();\n        reserve(nbytes);\n        memcpy(this.data + offset, data, nbytes);\n        offset += nbytes;\n    }\n\n    extern (C++) void writestring(const(char)* string) nothrow\n    {\n        write(string, strlen(string));\n    }\n\n    void writestring(const(char)[] s) nothrow\n    {\n        write(s.ptr, s.length);\n    }\n\n    void writestring(string s) nothrow\n    {\n        write(s.ptr, s.length);\n    }\n\n    extern (C++) void prependstring(const(char)* string) nothrow\n    {\n        size_t len = strlen(string);\n        reserve(len);\n        memmove(data + len, data, offset);\n        memcpy(data, string, len);\n        offset += len;\n    }\n\n    // write newline\n    extern (C++) void writenl() nothrow\n    {\n        version (Windows)\n        {\n            writeword(0x0A0D); // newline is CR,LF on Microsoft OS's\n        }\n        else\n        {\n            writeByte('\\n');\n        }\n        if (doindent)\n            notlinehead = false;\n    }\n\n    extern (C++) void writeByte(uint b) nothrow\n    {\n        if (doindent && !notlinehead && b != '\\n')\n            indent();\n        reserve(1);\n        this.data[offset] = cast(ubyte)b;\n        offset++;\n    }\n\n    extern (C++) void writeUTF8(uint b) nothrow\n    {\n        reserve(6);\n        if (b <= 0x7F)\n        {\n            this.data[offset] = cast(ubyte)b;\n            offset++;\n        }\n        else if (b <= 0x7FF)\n        {\n            this.data[offset + 0] = cast(ubyte)((b >> 6) | 0xC0);\n            this.data[offset + 1] = cast(ubyte)((b & 0x3F) | 0x80);\n            offset += 2;\n        }\n        else if (b <= 0xFFFF)\n        {\n            this.data[offset + 0] = cast(ubyte)((b >> 12) | 0xE0);\n            this.data[offset + 1] = cast(ubyte)(((b >> 6) & 0x3F) | 0x80);\n            this.data[offset + 2] = cast(ubyte)((b & 0x3F) | 0x80);\n            offset += 3;\n        }\n        else if (b <= 0x1FFFFF)\n        {\n            this.data[offset + 0] = cast(ubyte)((b >> 18) | 0xF0);\n            this.data[offset + 1] = cast(ubyte)(((b >> 12) & 0x3F) | 0x80);\n            this.data[offset + 2] = cast(ubyte)(((b >> 6) & 0x3F) | 0x80);\n            this.data[offset + 3] = cast(ubyte)((b & 0x3F) | 0x80);\n            offset += 4;\n        }\n        else if (b <= 0x3FFFFFF)\n        {\n            this.data[offset + 0] = cast(ubyte)((b >> 24) | 0xF8);\n            this.data[offset + 1] = cast(ubyte)(((b >> 18) & 0x3F) | 0x80);\n            this.data[offset + 2] = cast(ubyte)(((b >> 12) & 0x3F) | 0x80);\n            this.data[offset + 3] = cast(ubyte)(((b >> 6) & 0x3F) | 0x80);\n            this.data[offset + 4] = cast(ubyte)((b & 0x3F) | 0x80);\n            offset += 5;\n        }\n        else if (b <= 0x7FFFFFFF)\n        {\n            this.data[offset + 0] = cast(ubyte)((b >> 30) | 0xFC);\n            this.data[offset + 1] = cast(ubyte)(((b >> 24) & 0x3F) | 0x80);\n            this.data[offset + 2] = cast(ubyte)(((b >> 18) & 0x3F) | 0x80);\n            this.data[offset + 3] = cast(ubyte)(((b >> 12) & 0x3F) | 0x80);\n            this.data[offset + 4] = cast(ubyte)(((b >> 6) & 0x3F) | 0x80);\n            this.data[offset + 5] = cast(ubyte)((b & 0x3F) | 0x80);\n            offset += 6;\n        }\n        else\n            assert(0);\n    }\n\n    extern (C++) void prependbyte(uint b) nothrow\n    {\n        reserve(1);\n        memmove(data + 1, data, offset);\n        data[0] = cast(ubyte)b;\n        offset++;\n    }\n\n    extern (C++) void writewchar(uint w) nothrow\n    {\n        version (Windows)\n        {\n            writeword(w);\n        }\n        else\n        {\n            write4(w);\n        }\n    }\n\n    extern (C++) void writeword(uint w) nothrow\n    {\n        version (Windows)\n        {\n            uint newline = 0x0A0D;\n        }\n        else\n        {\n            uint newline = '\\n';\n        }\n        if (doindent && !notlinehead && w != newline)\n            indent();\n\n        reserve(2);\n        *cast(ushort*)(this.data + offset) = cast(ushort)w;\n        offset += 2;\n    }\n\n    extern (C++) void writeUTF16(uint w) nothrow\n    {\n        reserve(4);\n        if (w <= 0xFFFF)\n        {\n            *cast(ushort*)(this.data + offset) = cast(ushort)w;\n            offset += 2;\n        }\n        else if (w <= 0x10FFFF)\n        {\n            *cast(ushort*)(this.data + offset) = cast(ushort)((w >> 10) + 0xD7C0);\n            *cast(ushort*)(this.data + offset + 2) = cast(ushort)((w & 0x3FF) | 0xDC00);\n            offset += 4;\n        }\n        else\n            assert(0);\n    }\n\n    extern (C++) void write4(uint w) nothrow\n    {\n        version (Windows)\n        {\n            bool notnewline = w != 0x000A000D;\n        }\n        else\n        {\n            bool notnewline = true;\n        }\n        if (doindent && !notlinehead && notnewline)\n            indent();\n        reserve(4);\n        *cast(uint*)(this.data + offset) = w;\n        offset += 4;\n    }\n\n    extern (C++) void write(const OutBuffer* buf) nothrow\n    {\n        if (buf)\n        {\n            reserve(buf.offset);\n            memcpy(data + offset, buf.data, buf.offset);\n            offset += buf.offset;\n        }\n    }\n\n    extern (C++) void write(RootObject obj) /*nothrow*/\n    {\n        if (obj)\n        {\n            writestring(obj.toChars());\n        }\n    }\n\n    extern (C++) void fill0(size_t nbytes) nothrow\n    {\n        reserve(nbytes);\n        memset(data + offset, 0, nbytes);\n        offset += nbytes;\n    }\n\n    extern (C++) void vprintf(const(char)* format, va_list args) nothrow\n    {\n        int count;\n        if (doindent)\n            write(null, 0); // perform indent\n        uint psize = 128;\n        for (;;)\n        {\n            reserve(psize);\n            version (Windows)\n            {\n                count = _vsnprintf(cast(char*)data + offset, psize, format, args);\n                if (count != -1)\n                    break;\n                psize *= 2;\n            }\n            else version (Posix)\n            {\n                va_list va;\n                va_copy(va, args);\n                /*\n                 The functions vprintf(), vfprintf(), vsprintf(), vsnprintf()\n                 are equivalent to the functions printf(), fprintf(), sprintf(),\n                 snprintf(), respectively, except that they are called with a\n                 va_list instead of a variable number of arguments. These\n                 functions do not call the va_end macro. Consequently, the value\n                 of ap is undefined after the call. The application should call\n                 va_end(ap) itself afterwards.\n                 */\n                count = vsnprintf(cast(char*)data + offset, psize, format, va);\n                va_end(va);\n                if (count == -1)\n                    psize *= 2;\n                else if (count >= psize)\n                    psize = count + 1;\n                else\n                    break;\n            }\n            else\n            {\n                assert(0);\n            }\n        }\n        offset += count;\n    }\n\n    extern (C++) void printf(const(char)* format, ...) nothrow\n    {\n        va_list ap;\n        va_start(ap, format);\n        vprintf(format, ap);\n        va_end(ap);\n    }\n\n    /**************************************\n     * Convert `u` to a string and append it to the buffer.\n     * Params:\n     *  u = integral value to append\n     */\n    extern (C++) void print(ulong u) nothrow\n    {\n        //import core.internal.string;  // not available\n        UnsignedStringBuf buf = void;\n        writestring(unsignedToTempString(u, buf));\n    }\n\n    extern (C++) void bracket(char left, char right) nothrow\n    {\n        reserve(2);\n        memmove(data + 1, data, offset);\n        data[0] = left;\n        data[offset + 1] = right;\n        offset += 2;\n    }\n\n    /******************\n     * Insert left at i, and right at j.\n     * Return index just past right.\n     */\n    extern (C++) size_t bracket(size_t i, const(char)* left, size_t j, const(char)* right) nothrow\n    {\n        size_t leftlen = strlen(left);\n        size_t rightlen = strlen(right);\n        reserve(leftlen + rightlen);\n        insert(i, left, leftlen);\n        insert(j + leftlen, right, rightlen);\n        return j + leftlen + rightlen;\n    }\n\n    extern (C++) void spread(size_t offset, size_t nbytes) nothrow\n    {\n        reserve(nbytes);\n        memmove(data + offset + nbytes, data + offset, this.offset - offset);\n        this.offset += nbytes;\n    }\n\n    /****************************************\n     * Returns: offset + nbytes\n     */\n    extern (C++) size_t insert(size_t offset, const(void)* p, size_t nbytes) nothrow\n    {\n        spread(offset, nbytes);\n        memmove(data + offset, p, nbytes);\n        return offset + nbytes;\n    }\n\n    size_t insert(size_t offset, const(char)[] s) nothrow\n    {\n        return insert(offset, s.ptr, s.length);\n    }\n\n    extern (C++) void remove(size_t offset, size_t nbytes) nothrow\n    {\n        memmove(data + offset, data + offset + nbytes, this.offset - (offset + nbytes));\n        this.offset -= nbytes;\n    }\n\n    extern (D) const(char)[] peekSlice() nothrow\n    {\n        return (cast(const char*)data)[0 .. offset];\n    }\n\n    // Append terminating null if necessary and get view of internal buffer\n    extern (C++) char* peekString() nothrow\n    {\n        if (!offset || data[offset - 1] != '\\0')\n        {\n            writeByte(0);\n            offset--; // allow appending more\n        }\n        return cast(char*)data;\n    }\n\n    // Append terminating null if necessary and take ownership of data\n    extern (C++) char* extractString() nothrow\n    {\n        if (!offset || data[offset - 1] != '\\0')\n            writeByte(0);\n        return extractData();\n    }\n}\n\n/****** copied from core.internal.string *************/\n\nprivate:\npure:\nnothrow:\n@nogc:\n\nalias UnsignedStringBuf = char[20];\n\nchar[] unsignedToTempString(ulong value, char[] buf, uint radix = 10) @safe\n{\n    size_t i = buf.length;\n    do\n    {\n        if (value < radix)\n        {\n            ubyte x = cast(ubyte)value;\n            buf[--i] = cast(char)((x < 10) ? x + '0' : x - 10 + 'a');\n            break;\n        }\n        else\n        {\n            ubyte x = cast(ubyte)(value % radix);\n            value = value / radix;\n            buf[--i] = cast(char)((x < 10) ? x + '0' : x - 10 + 'a');\n        }\n    } while (value);\n    return buf[i .. $];\n}\n"
  },
  {
    "path": "gcc/d/dmd/root/outbuffer.h",
    "content": "\n/* Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * All Rights Reserved, written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/root/outbuffer.h\n */\n\n#pragma once\n\n#include <stdlib.h>\n#include <stdarg.h>\n#include <string.h>\n#include <assert.h>\n#include \"rmem.h\"\n\nclass RootObject;\n\nstruct OutBuffer\n{\n    unsigned char *data;\n    size_t offset;\n    size_t size;\n\n    int level;\n    bool doindent;\nprivate:\n    bool notlinehead;\npublic:\n\n    OutBuffer()\n    {\n        data = NULL;\n        offset = 0;\n        size = 0;\n\n        doindent = 0;\n        level = 0;\n        notlinehead = 0;\n    }\n    ~OutBuffer()\n    {\n        mem.xfree(data);\n    }\n    char *extractData();\n\n    void reserve(size_t nbytes);\n    void setsize(size_t size);\n    void reset();\n    void write(const void *data, d_size_t nbytes);\n    void writestring(const char *string);\n    void prependstring(const char *string);\n    void writenl();                     // write newline\n    void writeByte(unsigned b);\n    void writeUTF8(unsigned b);\n    void prependbyte(unsigned b);\n    void writewchar(unsigned w);\n    void writeword(unsigned w);\n    void writeUTF16(unsigned w);\n    void write4(unsigned w);\n    void write(OutBuffer *buf);\n    void write(RootObject *obj);\n    void fill0(size_t nbytes);\n    void vprintf(const char *format, va_list args);\n    void printf(const char *format, ...);\n    void bracket(char left, char right);\n    size_t bracket(size_t i, const char *left, size_t j, const char *right);\n    void spread(size_t offset, size_t nbytes);\n    size_t insert(size_t offset, const void *data, size_t nbytes);\n    void remove(size_t offset, size_t nbytes);\n    // Append terminating null if necessary and get view of internal buffer\n    char *peekString();\n    // Append terminating null if necessary and take ownership of data\n    char *extractString();\n};\n"
  },
  {
    "path": "gcc/d/dmd/root/port.d",
    "content": "/* port.d -- A mini library for doing compiler/system specific things.\n * Copyright (C) 2018 Free Software Foundation, Inc.\n *\n * GCC is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3, or (at your option)\n * any later version.\n *\n * GCC is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with GCC; see the file COPYING3.  If not see\n * <http://www.gnu.org/licenses/>.\n */\n\nmodule dmd.root.port;\n\nnothrow @nogc:\n\nextern (C++) struct Port\n{\n    nothrow @nogc:\n\n    static int memicmp(scope const char* s1, scope const char* s2, size_t n) pure;\n    static char* strupr(char* s) pure;\n    static bool isFloat32LiteralOutOfRange(scope const(char)* s);\n    static bool isFloat64LiteralOutOfRange(scope const(char)* s);\n    static void writelongLE(uint value, scope void* buffer) pure;\n    static uint readlongLE(scope void* buffer) pure;\n    static void writelongBE(uint value, scope void* buffer) pure;\n    static uint readlongBE(scope void* buffer) pure;\n    static uint readwordLE(scope void* buffer) pure;\n    static uint readwordBE(scope void* buffer) pure;\n    static void valcpy(scope void *dst, ulong val, size_t size) pure;\n}\n"
  },
  {
    "path": "gcc/d/dmd/root/port.h",
    "content": "\n/* Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * All Rights Reserved, written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/root/port.h\n */\n\n#pragma once\n\n// Portable wrapper around compiler/system specific things.\n// The idea is to minimize #ifdef's in the app code.\n\n#include <stddef.h>\n#include <stdint.h>\n\ntypedef unsigned char utf8_t;\n\nstruct Port\n{\n    static int memicmp(const char *s1, const char *s2, size_t n);\n    static char *strupr(char *s);\n\n    static bool isFloat32LiteralOutOfRange(const char *s);\n    static bool isFloat64LiteralOutOfRange(const char *s);\n\n    static void writelongLE(unsigned value, void *buffer);\n    static unsigned readlongLE(void *buffer);\n    static void writelongBE(unsigned value, void *buffer);\n    static unsigned readlongBE(void *buffer);\n    static unsigned readwordLE(void *buffer);\n    static unsigned readwordBE(void *buffer);\n    static void valcpy(void *dst, uint64_t val, size_t size);\n};\n"
  },
  {
    "path": "gcc/d/dmd/root/rmem.d",
    "content": "/**\n * Compiler implementation of the D programming language\n * http://dlang.org\n *\n * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:   Walter Bright, http://www.digitalmars.com\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/rmem.d, root/_rmem.d)\n * Documentation:  https://dlang.org/phobos/dmd_root_rmem.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/rmem.d\n */\n\nmodule dmd.root.rmem;\n\nimport core.stdc.string;\n\nversion (GC)\n{\n    import core.memory : GC;\n\n    extern (C++) struct Mem\n    {\n        static char* xstrdup(const(char)* p) nothrow\n        {\n            return p[0 .. strlen(p) + 1].dup.ptr;\n        }\n\n        static void xfree(void* p) nothrow\n        {\n            return GC.free(p);\n        }\n\n        static void* xmalloc(size_t n) nothrow\n        {\n            return GC.malloc(n);\n        }\n\n        static void* xcalloc(size_t size, size_t n) nothrow\n        {\n            return GC.calloc(size * n);\n        }\n\n        static void* xrealloc(void* p, size_t size) nothrow\n        {\n            return GC.realloc(p, size);\n        }\n\n        static void error() nothrow\n        {\n            import core.stdc.stdlib : exit, EXIT_FAILURE;\n            import core.stdc.stdio : printf;\n\n            printf(\"Error: out of memory\\n\");\n            exit(EXIT_FAILURE);\n        }\n    }\n\n    extern (C) void* allocmemory(size_t m_size) nothrow\n    {\n        return GC.malloc(m_size);\n    }\n\n    extern (C++) const __gshared Mem mem;\n}\nelse\n{\n    import core.stdc.stdlib;\n    import core.stdc.stdio;\n\n    extern (C++) struct Mem\n    {\n        static char* xstrdup(const(char)* s) nothrow\n        {\n            if (s)\n            {\n                auto p = .strdup(s);\n                if (p)\n                    return p;\n                error();\n            }\n            return null;\n        }\n\n        static void xfree(void* p) nothrow\n        {\n            if (p)\n                .free(p);\n        }\n\n        static void* xmalloc(size_t size) nothrow\n        {\n            if (!size)\n                return null;\n\n            auto p = .malloc(size);\n            if (!p)\n                error();\n            return p;\n        }\n\n        static void* xcalloc(size_t size, size_t n) nothrow\n        {\n            if (!size || !n)\n                return null;\n\n            auto p = .calloc(size, n);\n            if (!p)\n                error();\n            return p;\n        }\n\n        static void* xrealloc(void* p, size_t size) nothrow\n        {\n            if (!size)\n            {\n                if (p)\n                    .free(p);\n                return null;\n            }\n\n            if (!p)\n            {\n                p = .malloc(size);\n                if (!p)\n                    error();\n                return p;\n            }\n\n            p = .realloc(p, size);\n            if (!p)\n                error();\n            return p;\n        }\n\n        static void error() nothrow\n        {\n            printf(\"Error: out of memory\\n\");\n            exit(EXIT_FAILURE);\n        }\n    }\n\n    extern (C++) const __gshared Mem mem;\n\n    enum CHUNK_SIZE = (256 * 4096 - 64);\n\n    __gshared size_t heapleft = 0;\n    __gshared void* heapp;\n\n    extern (C) void* allocmemory(size_t m_size) nothrow\n    {\n        // 16 byte alignment is better (and sometimes needed) for doubles\n        m_size = (m_size + 15) & ~15;\n\n        // The layout of the code is selected so the most common case is straight through\n        if (m_size <= heapleft)\n        {\n        L1:\n            heapleft -= m_size;\n            auto p = heapp;\n            heapp = cast(void*)(cast(char*)heapp + m_size);\n            return p;\n        }\n\n        if (m_size > CHUNK_SIZE)\n        {\n            auto p = malloc(m_size);\n            if (p)\n            {\n                return p;\n            }\n            printf(\"Error: out of memory\\n\");\n            exit(EXIT_FAILURE);\n        }\n\n        heapleft = CHUNK_SIZE;\n        heapp = malloc(CHUNK_SIZE);\n        if (!heapp)\n        {\n            printf(\"Error: out of memory\\n\");\n            exit(EXIT_FAILURE);\n        }\n        goto L1;\n    }\n\n    version (DigitalMars)\n    {\n        enum OVERRIDE_MEMALLOC = true;\n    }\n    else version (LDC)\n    {\n        // Memory allocation functions gained weak linkage when the @weak attribute was introduced.\n        import ldc.attributes;\n        enum OVERRIDE_MEMALLOC = is(typeof(ldc.attributes.weak));\n    }\n    else\n    {\n        enum OVERRIDE_MEMALLOC = false;\n    }\n\n    static if (OVERRIDE_MEMALLOC)\n    {\n        extern (C) void* _d_allocmemory(size_t m_size) nothrow\n        {\n            return allocmemory(m_size);\n        }\n\n        extern (C) Object _d_newclass(const ClassInfo ci) nothrow\n        {\n            auto p = allocmemory(ci.initializer.length);\n            p[0 .. ci.initializer.length] = cast(void[])ci.initializer[];\n            return cast(Object)p;\n        }\n\n        version (LDC)\n        {\n            extern (C) Object _d_allocclass(const ClassInfo ci) nothrow\n            {\n                return cast(Object)allocmemory(ci.initializer.length);\n            }\n        }\n\n        extern (C) void* _d_newitemT(TypeInfo ti) nothrow\n        {\n            auto p = allocmemory(ti.tsize);\n            (cast(ubyte*)p)[0 .. ti.initializer.length] = 0;\n            return p;\n        }\n\n        extern (C) void* _d_newitemiT(TypeInfo ti) nothrow\n        {\n            auto p = allocmemory(ti.tsize);\n            p[0 .. ti.initializer.length] = ti.initializer[];\n            return p;\n        }\n\n        // TypeInfo.initializer for compilers older than 2.070\n        static if(!__traits(hasMember, TypeInfo, \"initializer\"))\n        private const(void[]) initializer(T : TypeInfo)(const T t)\n        nothrow pure @safe @nogc\n        {\n            return t.init;\n        }\n    }\n}\n/**\nMakes a null-terminated copy of the given string on newly allocated memory.\nThe null-terminator won't be part of the returned string slice. It will be\nat position `n` where `n` is the length of the input string.\n\nParams:\n    s = string to copy\n\nReturns: A null-terminated copy of the input array.\n*/\nextern (D) char[] xarraydup(const(char)[] s) nothrow\n{\n    if (!s)\n        return null;\n\n    auto p = cast(char*)mem.xmalloc(s.length + 1);\n    char[] a = p[0 .. s.length];\n    a[] = s[0 .. s.length];\n    p[s.length] = 0;    // preserve 0 terminator semantics\n    return a;\n}\n\n///\nunittest\n{\n    auto s1 = \"foo\";\n    auto s2 = s1.xarraydup;\n    s2[0] = 'b';\n    assert(s1 == \"foo\");\n    assert(s2 == \"boo\");\n    assert(*(s2.ptr + s2.length) == '\\0');\n    string sEmpty;\n    assert(sEmpty.xarraydup is null);\n}\n\n/**\nMakes a copy of the given array on newly allocated memory.\n\nParams:\n    s = array to copy\n\nReturns: A copy of the input array.\n*/\nextern (D) T[] arraydup(T)(const scope T[] s) nothrow\n{\n    if (!s)\n        return null;\n\n    const dim = s.length;\n    auto p = (cast(T*)mem.xmalloc(T.sizeof * dim))[0 .. dim];\n    p[] = s;\n    return p;\n}\n\n///\nunittest\n{\n    auto s1 = [0, 1, 2];\n    auto s2 = s1.arraydup;\n    s2[0] = 4;\n    assert(s1 == [0, 1, 2]);\n    assert(s2 == [4, 1, 2]);\n    string sEmpty;\n    assert(sEmpty.arraydup is null);\n}\n"
  },
  {
    "path": "gcc/d/dmd/root/rmem.h",
    "content": "\n/* Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * All Rights Reserved, written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/root/rmem.h\n */\n\n#pragma once\n\n#include <stddef.h>     // for size_t\n\n#if __APPLE__ && __i386__\n    /* size_t is 'unsigned long', which makes it mangle differently\n     * than D's 'uint'\n     */\n    typedef unsigned d_size_t;\n#else\n    typedef size_t d_size_t;\n#endif\n\nstruct Mem\n{\n    Mem() { }\n\n    static char *xstrdup(const char *s);\n    static void *xmalloc(d_size_t size);\n    static void *xcalloc(d_size_t size, d_size_t n);\n    static void *xrealloc(void *p, d_size_t size);\n    static void xfree(void *p);\n    static void *xmallocdup(void *o, d_size_t size);\n    static void error();\n};\n\nextern Mem mem;\n"
  },
  {
    "path": "gcc/d/dmd/root/root.h",
    "content": "\n/* Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * All Rights Reserved, written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/root/root.h\n */\n\n#pragma once\n\n#include \"object.h\"\n\n#include \"filename.h\"\n\n#include \"file.h\"\n\n#include \"outbuffer.h\"\n\n#include \"array.h\"\n"
  },
  {
    "path": "gcc/d/dmd/root/rootobject.d",
    "content": "/**\n * Compiler implementation of the D programming language\n * http://dlang.org\n *\n * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:   Walter Bright, http://www.digitalmars.com\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/rootobject.d, root/_rootobject.d)\n * Documentation:  https://dlang.org/phobos/dmd_root_rootobject.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/rootobject.d\n */\n\nmodule dmd.root.rootobject;\n\nimport core.stdc.stdio;\n\nimport dmd.root.outbuffer;\n\n/***********************************************************\n */\n\nenum DYNCAST : int\n{\n    object,\n    expression,\n    dsymbol,\n    type,\n    identifier,\n    tuple,\n    parameter,\n    statement,\n    condition,\n    templateparameter,\n}\n\n/***********************************************************\n */\n\nextern (C++) class RootObject\n{\n    this() nothrow pure @nogc @safe\n    {\n    }\n\n    bool equals(RootObject o)\n    {\n        return o is this;\n    }\n\n    int compare(RootObject)\n    {\n        assert(0);\n    }\n\n    const(char)* toChars()\n    {\n        assert(0);\n    }\n\n    ///\n    extern(D) const(char)[] toString()\n    {\n        import core.stdc.string : strlen;\n        auto p = this.toChars();\n        return p[0 .. strlen(p)];\n    }\n\n    void toBuffer(OutBuffer* buf) nothrow pure @nogc @safe\n    {\n        assert(0);\n    }\n\n    DYNCAST dyncast() const nothrow pure @nogc @safe\n    {\n        return DYNCAST.object;\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/root/speller.d",
    "content": "/**\n * Compiler implementation of the D programming language\n * http://dlang.org\n *\n * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:   Walter Bright, http://www.digitalmars.com\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/speller.d, root/_speller.d)\n * Documentation:  https://dlang.org/phobos/dmd_root_speller.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/speller.d\n */\n\nmodule dmd.root.speller;\n\nimport core.stdc.limits;\nimport core.stdc.stdlib;\nimport core.stdc.string;\n\nalias dg_speller_t = void* delegate(const(char)*, ref int);\n\n__gshared const(char)* idchars = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_\";\n\n/**************************************************\n * combine a new result from the spell checker to\n * find the one with the closest symbol with\n * respect to the cost defined by the search function\n * Input/Output:\n *      p       best found spelling (NULL if none found yet)\n *      cost    cost of p (INT_MAX if none found yet)\n * Input:\n *      np      new found spelling (NULL if none found)\n *      ncost   cost of np if non-NULL\n * Returns:\n *      true    if the cost is less or equal 0\n *      false   otherwise\n */\nprivate bool combineSpellerResult(ref void* p, ref int cost, void* np, int ncost)\n{\n    if (np && ncost < cost)\n    {\n        p = np;\n        cost = ncost;\n        if (cost <= 0)\n            return true;\n    }\n    return false;\n}\n\nprivate void* spellerY(const(char)* seed, size_t seedlen, dg_speller_t dg, const(char)* charset, size_t index, int* cost)\n{\n    if (!seedlen)\n        return null;\n    assert(seed[seedlen] == 0);\n    char[30] tmp;\n    char* buf;\n    if (seedlen <= tmp.sizeof - 2)\n        buf = tmp.ptr;\n    else\n    {\n        buf = cast(char*)alloca(seedlen + 2); // leave space for extra char\n        if (!buf)\n            return null; // no matches\n    }\n    memcpy(buf, seed, index);\n    *cost = INT_MAX;\n    void* p = null;\n    int ncost;\n    /* Delete at seed[index] */\n    if (index < seedlen)\n    {\n        memcpy(buf + index, seed + index + 1, seedlen - index);\n        assert(buf[seedlen - 1] == 0);\n        void* np = dg(buf, ncost);\n        if (combineSpellerResult(p, *cost, np, ncost))\n            return p;\n    }\n    if (charset && *charset)\n    {\n        /* Substitutions */\n        if (index < seedlen)\n        {\n            memcpy(buf, seed, seedlen + 1);\n            for (const(char)* s = charset; *s; s++)\n            {\n                buf[index] = *s;\n                //printf(\"sub buf = '%s'\\n\", buf);\n                void* np = dg(buf, ncost);\n                if (combineSpellerResult(p, *cost, np, ncost))\n                    return p;\n            }\n            assert(buf[seedlen] == 0);\n        }\n        /* Insertions */\n        memcpy(buf + index + 1, seed + index, seedlen + 1 - index);\n        for (const(char)* s = charset; *s; s++)\n        {\n            buf[index] = *s;\n            //printf(\"ins buf = '%s'\\n\", buf);\n            void* np = dg(buf, ncost);\n            if (combineSpellerResult(p, *cost, np, ncost))\n                return p;\n        }\n        assert(buf[seedlen + 1] == 0);\n    }\n    return p; // return \"best\" result\n}\n\nprivate void* spellerX(const(char)* seed, size_t seedlen, dg_speller_t dg, const(char)* charset, int flag)\n{\n    if (!seedlen)\n        return null;\n    char[30] tmp;\n    char* buf;\n    if (seedlen <= tmp.sizeof - 2)\n        buf = tmp.ptr;\n    else\n    {\n        buf = cast(char*)alloca(seedlen + 2); // leave space for extra char\n        if (!buf)\n            return null; // no matches\n    }\n    int cost = INT_MAX, ncost;\n    void* p = null, np;\n    /* Deletions */\n    memcpy(buf, seed + 1, seedlen);\n    for (size_t i = 0; i < seedlen; i++)\n    {\n        //printf(\"del buf = '%s'\\n\", buf);\n        if (flag)\n            np = spellerY(buf, seedlen - 1, dg, charset, i, &ncost);\n        else\n            np = dg(buf, ncost);\n        if (combineSpellerResult(p, cost, np, ncost))\n            return p;\n        buf[i] = seed[i];\n    }\n    /* Transpositions */\n    if (!flag)\n    {\n        memcpy(buf, seed, seedlen + 1);\n        for (size_t i = 0; i + 1 < seedlen; i++)\n        {\n            // swap [i] and [i + 1]\n            buf[i] = seed[i + 1];\n            buf[i + 1] = seed[i];\n            //printf(\"tra buf = '%s'\\n\", buf);\n            if (combineSpellerResult(p, cost, dg(buf, ncost), ncost))\n                return p;\n            buf[i] = seed[i];\n        }\n    }\n    if (charset && *charset)\n    {\n        /* Substitutions */\n        memcpy(buf, seed, seedlen + 1);\n        for (size_t i = 0; i < seedlen; i++)\n        {\n            for (const(char)* s = charset; *s; s++)\n            {\n                buf[i] = *s;\n                //printf(\"sub buf = '%s'\\n\", buf);\n                if (flag)\n                    np = spellerY(buf, seedlen, dg, charset, i + 1, &ncost);\n                else\n                    np = dg(buf, ncost);\n                if (combineSpellerResult(p, cost, np, ncost))\n                    return p;\n            }\n            buf[i] = seed[i];\n        }\n        /* Insertions */\n        memcpy(buf + 1, seed, seedlen + 1);\n        for (size_t i = 0; i <= seedlen; i++) // yes, do seedlen+1 iterations\n        {\n            for (const(char)* s = charset; *s; s++)\n            {\n                buf[i] = *s;\n                //printf(\"ins buf = '%s'\\n\", buf);\n                if (flag)\n                    np = spellerY(buf, seedlen + 1, dg, charset, i + 1, &ncost);\n                else\n                    np = dg(buf, ncost);\n                if (combineSpellerResult(p, cost, np, ncost))\n                    return p;\n            }\n            buf[i] = seed[i]; // going past end of seed[] is ok, as we hit the 0\n        }\n    }\n    return p; // return \"best\" result\n}\n\n/**************************************************\n * Looks for correct spelling.\n * Currently only looks a 'distance' of one from the seed[].\n * This does an exhaustive search, so can potentially be very slow.\n * Params:\n *      seed = wrongly spelled word\n *      dg = search delegate\n *      charset = character set\n * Returns:\n *      null = no correct spellings found, otherwise\n *      the value returned by dg() for first possible correct spelling\n */\nvoid* speller(const(char)* seed, scope dg_speller_t dg, const(char)* charset)\n{\n    size_t seedlen = strlen(seed);\n    size_t maxdist = seedlen < 4 ? seedlen / 2 : 2;\n    for (int distance = 0; distance < maxdist; distance++)\n    {\n        void* p = spellerX(seed, seedlen, dg, charset, distance);\n        if (p)\n            return p;\n        //      if (seedlen > 10)\n        //          break;\n    }\n    return null; // didn't find it\n}\n\nunittest\n{\n    __gshared const(char)*** cases =\n    [\n        [\"hello\", \"hell\", \"y\"],\n        [\"hello\", \"hel\", \"y\"],\n        [\"hello\", \"ello\", \"y\"],\n        [\"hello\", \"llo\", \"y\"],\n        [\"hello\", \"hellox\", \"y\"],\n        [\"hello\", \"helloxy\", \"y\"],\n        [\"hello\", \"xhello\", \"y\"],\n        [\"hello\", \"xyhello\", \"y\"],\n        [\"hello\", \"ehllo\", \"y\"],\n        [\"hello\", \"helol\", \"y\"],\n        [\"hello\", \"abcd\", \"n\"],\n        [\"hello\", \"helxxlo\", \"y\"],\n        [\"hello\", \"ehlxxlo\", \"n\"],\n        [\"hello\", \"heaao\", \"y\"],\n        [\"_123456789_123456789_123456789_123456789\", \"_123456789_123456789_123456789_12345678\", \"y\"],\n        [null, null, null]\n    ];\n    //printf(\"unittest_speller()\\n\");\n\n    void* dgarg;\n\n    void* speller_test(const(char)* s, ref int cost)\n    {\n        //printf(\"speller_test(%s, %s)\\n\", dgarg, s);\n        cost = 0;\n        if (strcmp(cast(char*)dgarg, s) == 0)\n            return dgarg;\n        return null;\n    }\n\n    dgarg = cast(char*)\"hell\";\n    const(void)* p = speller(cast(const(char)*)\"hello\", &speller_test, idchars);\n    assert(p !is null);\n    for (int i = 0; cases[i][0]; i++)\n    {\n        //printf(\"case [%d]\\n\", i);\n        dgarg = cast(void*)cases[i][1];\n        void* p2 = speller(cases[i][0], &speller_test, idchars);\n        if (p2)\n            assert(cases[i][2][0] == 'y');\n        else\n            assert(cases[i][2][0] == 'n');\n    }\n    //printf(\"unittest_speller() success\\n\");\n}\n"
  },
  {
    "path": "gcc/d/dmd/root/stringtable.d",
    "content": "/**\n * Compiler implementation of the D programming language\n * http://dlang.org\n *\n * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:   Walter Bright, http://www.digitalmars.com\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/stringtable.d, root/_stringtable.d)\n * Documentation:  https://dlang.org/phobos/dmd_root_stringtable.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/stringtable.d\n */\n\nmodule dmd.root.stringtable;\n\nimport core.stdc.string;\nimport dmd.root.rmem, dmd.root.hash;\n\nenum POOL_BITS = 12;\nenum POOL_SIZE = (1U << POOL_BITS);\n\nprivate size_t nextpow2(size_t val) pure nothrow @nogc @safe\n{\n    size_t res = 1;\n    while (res < val)\n        res <<= 1;\n    return res;\n}\n\nenum loadFactor = 0.8;\n\nstruct StringEntry\n{\n    uint hash;\n    uint vptr;\n}\n\n// StringValue is a variable-length structure. It has neither proper c'tors nor a\n// factory method because the only thing which should be creating these is StringTable.\nstruct StringValue\n{\n    void* ptrvalue;\n    size_t length;\n\nnothrow:\npure:\n    char* lstring()\n    {\n        return cast(char*)(&this + 1);\n    }\n\n    size_t len() const\n    {\n        return length;\n    }\n\n    const(char)* toDchars() const\n    {\n        return cast(const(char)*)(&this + 1);\n    }\n\n    /// Returns: The content of this entry as a D slice\n    inout(char)[] toString() inout\n    {\n        return (cast(inout(char)*)(&this + 1))[0 .. length];\n    }\n}\n\nstruct StringTable\n{\nprivate:\n    StringEntry* table;\n    size_t tabledim;\n    ubyte** pools;\n    size_t npools;\n    size_t nfill;\n    size_t count;\n\npublic:\n    void _init(size_t size = 0) nothrow\n    {\n        size = nextpow2(cast(size_t)(size / loadFactor));\n        if (size < 32)\n            size = 32;\n        table = cast(StringEntry*)mem.xcalloc(size, (table[0]).sizeof);\n        tabledim = size;\n        pools = null;\n        npools = nfill = 0;\n        count = 0;\n    }\n\n    void reset(size_t size = 0) nothrow\n    {\n        for (size_t i = 0; i < npools; ++i)\n            mem.xfree(pools[i]);\n        mem.xfree(table);\n        mem.xfree(pools);\n        table = null;\n        pools = null;\n        _init(size);\n    }\n\n    ~this() nothrow\n    {\n        for (size_t i = 0; i < npools; ++i)\n            mem.xfree(pools[i]);\n        mem.xfree(table);\n        mem.xfree(pools);\n        table = null;\n        pools = null;\n    }\n\n    /**\n    Looks up the given string in the string table and returns its associated\n    value.\n\n    Params:\n     s = the string to look up\n     length = the length of $(D_PARAM s)\n     str = the string to look up\n\n    Returns: the string's associated value, or `null` if the string doesn't\n     exist in the string table\n    */\n    inout(StringValue)* lookup(const(char)* s, size_t length) inout nothrow pure\n    {\n        const(hash_t) hash = calcHash(s, length);\n        const(size_t) i = findSlot(hash, s, length);\n        // printf(\"lookup %.*s %p\\n\", (int)length, s, table[i].value ?: NULL);\n        return getValue(table[i].vptr);\n    }\n\n    /// ditto\n    inout(StringValue)* lookup(const(char)[] str) inout nothrow pure\n    {\n        return lookup(str.ptr, str.length);\n    }\n\n    /**\n    Inserts the given string and the given associated value into the string\n    table.\n\n    Params:\n     s = the string to insert\n     length = the length of $(D_PARAM s)\n     ptrvalue = the value to associate with the inserted string\n     str = the string to insert\n     value = the value to associate with the inserted string\n\n    Returns: the newly inserted value, or `null` if the string table already\n     contains the string\n    */\n    StringValue* insert(const(char)* s, size_t length, void* ptrvalue) nothrow\n    {\n        const(hash_t) hash = calcHash(s, length);\n        size_t i = findSlot(hash, s, length);\n        if (table[i].vptr)\n            return null; // already in table\n        if (++count > tabledim * loadFactor)\n        {\n            grow();\n            i = findSlot(hash, s, length);\n        }\n        table[i].hash = hash;\n        table[i].vptr = allocValue(s, length, ptrvalue);\n        // printf(\"insert %.*s %p\\n\", (int)length, s, table[i].value ?: NULL);\n        return getValue(table[i].vptr);\n    }\n\n    /// ditto\n    StringValue* insert(const(char)[] str, void* value) nothrow\n    {\n        return insert(str.ptr, str.length, value);\n    }\n\n    StringValue* update(const(char)* s, size_t length) nothrow\n    {\n        const(hash_t) hash = calcHash(s, length);\n        size_t i = findSlot(hash, s, length);\n        if (!table[i].vptr)\n        {\n            if (++count > tabledim * loadFactor)\n            {\n                grow();\n                i = findSlot(hash, s, length);\n            }\n            table[i].hash = hash;\n            table[i].vptr = allocValue(s, length, null);\n        }\n        // printf(\"update %.*s %p\\n\", (int)length, s, table[i].value ?: NULL);\n        return getValue(table[i].vptr);\n    }\n\n    StringValue* update(const(char)[] name) nothrow\n    {\n        return update(name.ptr, name.length);\n    }\n\n    /********************************\n     * Walk the contents of the string table,\n     * calling fp for each entry.\n     * Params:\n     *      fp = function to call. Returns !=0 to stop\n     * Returns:\n     *      last return value of fp call\n     */\n    int apply(int function(const(StringValue)*) fp)\n    {\n        foreach (const se; table[0 .. tabledim])\n        {\n            if (!se.vptr)\n                continue;\n            const sv = getValue(se.vptr);\n            int result = (*fp)(sv);\n            if (result)\n                return result;\n        }\n        return 0;\n    }\n\nprivate:\nnothrow:\n    uint allocValue(const(char)* s, size_t length, void* ptrvalue)\n    {\n        const(size_t) nbytes = StringValue.sizeof + length + 1;\n        if (!npools || nfill + nbytes > POOL_SIZE)\n        {\n            pools = cast(ubyte**)mem.xrealloc(pools, ++npools * (pools[0]).sizeof);\n            pools[npools - 1] = cast(ubyte*)mem.xmalloc(nbytes > POOL_SIZE ? nbytes : POOL_SIZE);\n            nfill = 0;\n        }\n        StringValue* sv = cast(StringValue*)&pools[npools - 1][nfill];\n        sv.ptrvalue = ptrvalue;\n        sv.length = length;\n        .memcpy(sv.lstring(), s, length);\n        sv.lstring()[length] = 0;\n        const(uint) vptr = cast(uint)(npools << POOL_BITS | nfill);\n        nfill += nbytes + (-nbytes & 7); // align to 8 bytes\n        return vptr;\n    }\n\n    inout(StringValue)* getValue(uint vptr) inout pure\n    {\n        if (!vptr)\n            return null;\n        const(size_t) idx = (vptr >> POOL_BITS) - 1;\n        const(size_t) off = vptr & POOL_SIZE - 1;\n        return cast(inout(StringValue)*)&pools[idx][off];\n    }\n\n    size_t findSlot(hash_t hash, const(char)* s, size_t length) const pure\n    {\n        // quadratic probing using triangular numbers\n        // http://stackoverflow.com/questions/2348187/moving-from-linear-probing-to-quadratic-probing-hash-collisons/2349774#2349774\n        for (size_t i = hash & (tabledim - 1), j = 1;; ++j)\n        {\n            const(StringValue)* sv;\n            auto vptr = table[i].vptr;\n            if (!vptr || table[i].hash == hash && (sv = getValue(vptr)).length == length && .memcmp(s, sv.toDchars(), length) == 0)\n                return i;\n            i = (i + j) & (tabledim - 1);\n        }\n    }\n\n    void grow()\n    {\n        const odim = tabledim;\n        auto otab = table;\n        tabledim *= 2;\n        table = cast(StringEntry*)mem.xcalloc(tabledim, (table[0]).sizeof);\n        foreach (const se; otab[0 .. odim])\n        {\n            if (!se.vptr)\n                continue;\n            const sv = getValue(se.vptr);\n            table[findSlot(se.hash, sv.toDchars(), sv.length)] = se;\n        }\n        mem.xfree(otab);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/safe.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/safe.d, _safe.d)\n * Documentation:  https://dlang.org/phobos/dmd_safe.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/safe.d\n */\n\nmodule dmd.safe;\n\nimport core.stdc.stdio;\n\nimport dmd.aggregate;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.expression;\nimport dmd.mtype;\nimport dmd.target;\nimport dmd.tokens;\n\n\n/*************************************************************\n * Check for unsafe access in @safe code:\n * 1. read overlapped pointers\n * 2. write misaligned pointers\n * 3. write overlapped storage classes\n * Print error if unsafe.\n * Params:\n *      sc = scope\n *      e = expression to check\n *      readonly = if access is read-only\n *      printmsg = print error message if true\n * Returns:\n *      true if error\n */\n\nbool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg)\n{\n    //printf(\"checkUnsafeAccess(e: '%s', readonly: %d, printmsg: %d)\\n\", e.toChars(), readonly, printmsg);\n    if (e.op != TOK.dotVariable)\n        return false;\n    DotVarExp dve = cast(DotVarExp)e;\n    if (VarDeclaration v = dve.var.isVarDeclaration())\n    {\n        if (sc.intypeof || !sc.func || !sc.func.isSafeBypassingInference())\n            return false;\n\n        auto ad = v.toParent2().isAggregateDeclaration();\n        if (!ad)\n            return false;\n\n        const hasPointers = v.type.hasPointers();\n        if (hasPointers)\n        {\n            if (ad.sizeok != Sizeok.done)\n                ad.determineSize(ad.loc);       // needed to set v.overlapped\n\n            if (v.overlapped && sc.func.setUnsafe())\n            {\n                if (printmsg)\n                    e.error(\"field `%s.%s` cannot access pointers in `@safe` code that overlap other fields\",\n                        ad.toChars(), v.toChars());\n                return true;\n            }\n        }\n\n        if (readonly || !e.type.isMutable())\n            return false;\n\n        if (hasPointers && v.type.toBasetype().ty != Tstruct)\n        {\n            if ((ad.type.alignment() < Target.ptrsize ||\n                 (v.offset & (Target.ptrsize - 1))) &&\n                sc.func.setUnsafe())\n            {\n                if (printmsg)\n                    e.error(\"field `%s.%s` cannot modify misaligned pointers in `@safe` code\",\n                        ad.toChars(), v.toChars());\n                return true;\n            }\n        }\n\n        if (v.overlapUnsafe && sc.func.setUnsafe())\n        {\n             if (printmsg)\n                 e.error(\"field `%s.%s` cannot modify fields in `@safe` code that overlap fields with other storage classes\",\n                    ad.toChars(), v.toChars());\n             return true;\n        }\n    }\n    return false;\n}\n\n\n/**********************************************\n * Determine if it is @safe to cast e from tfrom to tto.\n * Params:\n *      e = expression to be cast\n *      tfrom = type of e\n *      tto = type to cast e to\n * Returns:\n *      true if @safe\n */\nbool isSafeCast(Expression e, Type tfrom, Type tto)\n{\n    // Implicit conversions are always safe\n    if (tfrom.implicitConvTo(tto))\n        return true;\n\n    if (!tto.hasPointers())\n        return true;\n\n    auto tfromb = tfrom.toBasetype();\n    auto ttob = tto.toBasetype();\n\n    if (ttob.ty == Tclass && tfromb.ty == Tclass)\n    {\n        ClassDeclaration cdfrom = tfromb.isClassHandle();\n        ClassDeclaration cdto = ttob.isClassHandle();\n\n        int offset;\n        if (!cdfrom.isBaseOf(cdto, &offset))\n            return false;\n\n        if (cdfrom.isCPPinterface() || cdto.isCPPinterface())\n            return false;\n\n        if (!MODimplicitConv(tfromb.mod, ttob.mod))\n            return false;\n        return true;\n    }\n\n    if (ttob.ty == Tarray && tfromb.ty == Tsarray) // https://issues.dlang.org/show_bug.cgi?id=12502\n        tfromb = tfromb.nextOf().arrayOf();\n\n    if (ttob.ty == Tarray   && tfromb.ty == Tarray ||\n        ttob.ty == Tpointer && tfromb.ty == Tpointer)\n    {\n        Type ttobn = ttob.nextOf().toBasetype();\n        Type tfromn = tfromb.nextOf().toBasetype();\n\n        /* From void[] to anything mutable is unsafe because:\n         *  int*[] api;\n         *  void[] av = api;\n         *  int[] ai = cast(int[]) av;\n         *  ai[0] = 7;\n         *  *api[0] crash!\n         */\n        if (tfromn.ty == Tvoid && ttobn.isMutable())\n        {\n            if (ttob.ty == Tarray && e.op == TOK.arrayLiteral)\n                return true;\n            return false;\n        }\n\n        // If the struct is opaque we don't know about the struct members then the cast becomes unsafe\n        if (ttobn.ty == Tstruct && !(cast(TypeStruct)ttobn).sym.members ||\n            tfromn.ty == Tstruct && !(cast(TypeStruct)tfromn).sym.members)\n            return false;\n\n        const frompointers = tfromn.hasPointers();\n        const topointers = ttobn.hasPointers();\n\n        if (frompointers && !topointers && ttobn.isMutable())\n            return false;\n\n        if (!frompointers && topointers)\n            return false;\n\n        if (!topointers &&\n            ttobn.ty != Tfunction && tfromn.ty != Tfunction &&\n            (ttob.ty == Tarray || ttobn.size() <= tfromn.size()) &&\n            MODimplicitConv(tfromn.mod, ttobn.mod))\n        {\n            return true;\n        }\n    }\n    return false;\n}\n\n"
  },
  {
    "path": "gcc/d/dmd/sapply.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/sparse.d, _sparse.d)\n * Documentation:  https://dlang.org/phobos/dmd_sapply.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/sapply.d\n */\n\nmodule dmd.sapply;\n\nimport dmd.statement;\nimport dmd.visitor;\n\n/**************************************\n * A Statement tree walker that will visit each Statement s in the tree,\n * in depth-first evaluation order, and call fp(s,param) on it.\n * fp() signals whether the walking continues with its return value:\n * Returns:\n *      0       continue\n *      1       done\n * It's a bit slower than using virtual functions, but more encapsulated and less brittle.\n * Creating an iterator for this would be much more complex.\n */\nextern (C++) final class PostorderStatementVisitor : StoppableVisitor\n{\n    alias visit = typeof(super).visit;\npublic:\n    StoppableVisitor v;\n\n    extern (D) this(StoppableVisitor v)\n    {\n        this.v = v;\n    }\n\n    bool doCond(Statement s)\n    {\n        if (!stop && s)\n            s.accept(this);\n        return stop;\n    }\n\n    bool applyTo(Statement s)\n    {\n        s.accept(v);\n        stop = v.stop;\n        return true;\n    }\n\n    override void visit(Statement s)\n    {\n        applyTo(s);\n    }\n\n    override void visit(PeelStatement s)\n    {\n        doCond(s.s) || applyTo(s);\n    }\n\n    override void visit(CompoundStatement s)\n    {\n        for (size_t i = 0; i < s.statements.dim; i++)\n            if (doCond((*s.statements)[i]))\n                return;\n        applyTo(s);\n    }\n\n    override void visit(UnrolledLoopStatement s)\n    {\n        for (size_t i = 0; i < s.statements.dim; i++)\n            if (doCond((*s.statements)[i]))\n                return;\n        applyTo(s);\n    }\n\n    override void visit(ScopeStatement s)\n    {\n        doCond(s.statement) || applyTo(s);\n    }\n\n    override void visit(WhileStatement s)\n    {\n        doCond(s._body) || applyTo(s);\n    }\n\n    override void visit(DoStatement s)\n    {\n        doCond(s._body) || applyTo(s);\n    }\n\n    override void visit(ForStatement s)\n    {\n        doCond(s._init) || doCond(s._body) || applyTo(s);\n    }\n\n    override void visit(ForeachStatement s)\n    {\n        doCond(s._body) || applyTo(s);\n    }\n\n    override void visit(ForeachRangeStatement s)\n    {\n        doCond(s._body) || applyTo(s);\n    }\n\n    override void visit(IfStatement s)\n    {\n        doCond(s.ifbody) || doCond(s.elsebody) || applyTo(s);\n    }\n\n    override void visit(PragmaStatement s)\n    {\n        doCond(s._body) || applyTo(s);\n    }\n\n    override void visit(SwitchStatement s)\n    {\n        doCond(s._body) || applyTo(s);\n    }\n\n    override void visit(CaseStatement s)\n    {\n        doCond(s.statement) || applyTo(s);\n    }\n\n    override void visit(DefaultStatement s)\n    {\n        doCond(s.statement) || applyTo(s);\n    }\n\n    override void visit(SynchronizedStatement s)\n    {\n        doCond(s._body) || applyTo(s);\n    }\n\n    override void visit(WithStatement s)\n    {\n        doCond(s._body) || applyTo(s);\n    }\n\n    override void visit(TryCatchStatement s)\n    {\n        if (doCond(s._body))\n            return;\n        for (size_t i = 0; i < s.catches.dim; i++)\n            if (doCond((*s.catches)[i].handler))\n                return;\n        applyTo(s);\n    }\n\n    override void visit(TryFinallyStatement s)\n    {\n        doCond(s._body) || doCond(s.finalbody) || applyTo(s);\n    }\n\n    override void visit(OnScopeStatement s)\n    {\n        doCond(s.statement) || applyTo(s);\n    }\n\n    override void visit(DebugStatement s)\n    {\n        doCond(s.statement) || applyTo(s);\n    }\n\n    override void visit(LabelStatement s)\n    {\n        doCond(s.statement) || applyTo(s);\n    }\n}\n\nbool walkPostorder(Statement s, StoppableVisitor v)\n{\n    scope PostorderStatementVisitor pv = new PostorderStatementVisitor(v);\n    s.accept(pv);\n    return v.stop;\n}\n"
  },
  {
    "path": "gcc/d/dmd/scope.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/scope.h\n */\n\n#pragma once\n\nclass Identifier;\nclass Module;\nclass Statement;\nclass SwitchStatement;\nclass TryFinallyStatement;\nclass LabelStatement;\nclass ForeachStatement;\nclass ClassDeclaration;\nclass AggregateDeclaration;\nclass FuncDeclaration;\nclass UserAttributeDeclaration;\nstruct DocComment;\nstruct AA;\nclass TemplateInstance;\n\n#include \"dsymbol.h\"\n\n#define CSXthis_ctor    1       // called this()\n#define CSXsuper_ctor   2       // called super()\n#define CSXthis         4       // referenced this\n#define CSXsuper        8       // referenced super\n#define CSXlabel        0x10    // seen a label\n#define CSXreturn       0x20    // seen a return statement\n#define CSXany_ctor     0x40    // either this() or super() was called\n#define CSXhalt         0x80    // assert(0)\n\n// Flags that would not be inherited beyond scope nesting\n#define SCOPEctor           0x0001  // constructor type\n#define SCOPEcondition      0x0004  // inside static if/assert condition\n#define SCOPEdebug          0x0008  // inside debug conditional\n\n// Flags that would be inherited beyond scope nesting\n#define SCOPEnoaccesscheck  0x0002  // don't do access checks\n#define SCOPEconstraint     0x0010  // inside template constraint\n#define SCOPEinvariant      0x0020  // inside invariant code\n#define SCOPErequire        0x0040  // inside in contract code\n#define SCOPEensure         0x0060  // inside out contract code\n#define SCOPEcontract       0x0060  // [mask] we're inside contract code\n#define SCOPEctfe           0x0080  // inside a ctfe-only expression\n#define SCOPEcompile        0x0100  // inside __traits(compile)\n#define SCOPEignoresymbolvisibility 0x0200  // ignore symbol visibility (Bugzilla 15907)\n#define SCOPEfullinst       0x1000  // fully instantiate templates\n\n#define SCOPEfree           0x8000  // is on free list\n\nstruct Scope\n{\n    Scope *enclosing;           // enclosing Scope\n\n    Module *_module;            // Root module\n    ScopeDsymbol *scopesym;     // current symbol\n    FuncDeclaration *func;      // function we are in\n    Dsymbol *parent;            // parent to use\n    LabelStatement *slabel;     // enclosing labelled statement\n    SwitchStatement *sw;        // enclosing switch statement\n    TryFinallyStatement *tf;    // enclosing try finally statement\n    OnScopeStatement *os;       // enclosing scope(xxx) statement\n    Statement *sbreak;          // enclosing statement that supports \"break\"\n    Statement *scontinue;       // enclosing statement that supports \"continue\"\n    ForeachStatement *fes;      // if nested function for ForeachStatement, this is it\n    Scope *callsc;              // used for __FUNCTION__, __PRETTY_FUNCTION__ and __MODULE__\n    bool inunion;               // true if processing members of a union\n    bool nofree;                // true if shouldn't free it\n    bool inLoop;                // true if inside a loop (where constructor calls aren't allowed)\n    int intypeof;               // in typeof(exp)\n    VarDeclaration *lastVar;    // Previous symbol used to prevent goto-skips-init\n\n    /* If  minst && !tinst, it's in definitely non-speculative scope (eg. module member scope).\n     * If !minst && !tinst, it's in definitely speculative scope (eg. template constraint).\n     * If  minst &&  tinst, it's in instantiated code scope without speculation.\n     * If !minst &&  tinst, it's in instantiated code scope with speculation.\n     */\n    Module *minst;              // root module where the instantiated templates should belong to\n    TemplateInstance *tinst;    // enclosing template instance\n\n    unsigned char callSuper;    // primitive flow analysis for constructors\n    unsigned char *fieldinit;\n    size_t fieldinit_dim;\n\n    AlignDeclaration *aligndecl;    // alignment for struct members\n\n    LINK linkage;               // linkage for external functions\n    CPPMANGLE cppmangle;        // C++ mangle type\n    PINLINE inlining;            // inlining strategy for functions\n\n    Prot protection;            // protection for class members\n    int explicitProtection;     // set if in an explicit protection attribute\n\n    StorageClass stc;           // storage class\n\n    DeprecatedDeclaration *depdecl; // customized deprecation message\n\n    unsigned flags;\n\n    UserAttributeDeclaration *userAttribDecl;   // user defined attributes\n\n    DocComment *lastdc;         // documentation comment for last symbol at this scope\n    AA *anchorCounts;           // lookup duplicate anchor name count\n    Identifier *prevAnchor;     // qualified symbol name of last doc anchor\n\n    Scope();\n\n    Scope *copy();\n\n    Scope *push();\n    Scope *push(ScopeDsymbol *ss);\n    Scope *pop();\n\n    Scope *startCTFE();\n    Scope *endCTFE();\n\n    void mergeCallSuper(Loc loc, unsigned cs);\n\n    unsigned *saveFieldInit();\n    void mergeFieldInit(Loc loc, unsigned *cses);\n\n    Module *instantiatingModule();\n\n    Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym, int flags = IgnoreNone);\n    Dsymbol *search_correct(Identifier *ident);\n    Dsymbol *insert(Dsymbol *s);\n\n    ClassDeclaration *getClassScope();\n    AggregateDeclaration *getStructClassScope();\n    void setNoFree();\n\n    structalign_t alignment();\n\n    bool isDeprecated();\n};\n"
  },
  {
    "path": "gcc/d/dmd/semantic2.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/semantic2.d, _semantic2.d)\n * Documentation:  https://dlang.org/phobos/dmd_semantic2.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/semantic2.d\n */\n\nmodule dmd.semantic2;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\n\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arraytypes;\nimport dmd.astcodegen;\nimport dmd.attrib;\nimport dmd.blockexit;\nimport dmd.clone;\nimport dmd.dcast;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dimport;\nimport dmd.dinterpret;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.dversion;\nimport dmd.errors;\nimport dmd.escape;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.initsem;\nimport dmd.hdrgen;\nimport dmd.mtype;\nimport dmd.nogc;\nimport dmd.nspace;\nimport dmd.objc;\nimport dmd.opover;\nimport dmd.parse;\nimport dmd.root.filename;\nimport dmd.root.outbuffer;\nimport dmd.root.rmem;\nimport dmd.root.rootobject;\nimport dmd.sideeffect;\nimport dmd.statementsem;\nimport dmd.staticassert;\nimport dmd.tokens;\nimport dmd.utf;\nimport dmd.utils;\nimport dmd.statement;\nimport dmd.target;\nimport dmd.templateparamsem;\nimport dmd.typesem;\nimport dmd.visitor;\n\nenum LOG = false;\n\n\n/*************************************\n * Does semantic analysis on initializers and members of aggregates.\n */\nextern(C++) void semantic2(Dsymbol dsym, Scope* sc)\n{\n    scope v = new Semantic2Visitor(sc);\n    dsym.accept(v);\n}\n\nprivate extern(C++) final class Semantic2Visitor : Visitor\n{\n    alias visit = Visitor.visit;\n    Scope* sc;\n    this(Scope* sc)\n    {\n        this.sc = sc;\n    }\n\n    override void visit(Dsymbol) {}\n\n    override void visit(StaticAssert sa)\n    {\n        //printf(\"StaticAssert::semantic2() %s\\n\", sa.toChars());\n        auto sds = new ScopeDsymbol();\n        sc = sc.push(sds);\n        sc.tinst = null;\n        sc.minst = null;\n\n        import dmd.staticcond;\n        bool errors;\n        bool result = evalStaticCondition(sc, sa.exp, sa.exp, errors);\n        sc = sc.pop();\n        if (errors)\n        {\n            errorSupplemental(sa.loc, \"while evaluating: `static assert(%s)`\", sa.exp.toChars());\n        }\n        else if (!result)\n        {\n            if (sa.msg)\n            {\n                sc = sc.startCTFE();\n                sa.msg = sa.msg.expressionSemantic(sc);\n                sa.msg = resolveProperties(sc, sa.msg);\n                sc = sc.endCTFE();\n                sa.msg = sa.msg.ctfeInterpret();\n                if (StringExp se = sa.msg.toStringExp())\n                {\n                    // same with pragma(msg)\n                    se = se.toUTF8(sc);\n                    error(sa.loc, \"static assert:  \\\"%.*s\\\"\", cast(int)se.len, se.string);\n                }\n                else\n                    error(sa.loc, \"static assert:  %s\", sa.msg.toChars());\n            }\n            else\n                error(sa.loc, \"static assert:  `%s` is false\", sa.exp.toChars());\n            if (sc.tinst)\n                sc.tinst.printInstantiationTrace();\n            if (!global.gag)\n                fatal();\n        }\n    }\n\n    override void visit(TemplateInstance tempinst)\n    {\n        if (tempinst.semanticRun >= PASS.semantic2)\n            return;\n        tempinst.semanticRun = PASS.semantic2;\n        static if (LOG)\n        {\n            printf(\"+TemplateInstance.semantic2('%s')\\n\", tempinst.toChars());\n        }\n        if (!tempinst.errors && tempinst.members)\n        {\n            TemplateDeclaration tempdecl = tempinst.tempdecl.isTemplateDeclaration();\n            assert(tempdecl);\n\n            sc = tempdecl._scope;\n            assert(sc);\n            sc = sc.push(tempinst.argsym);\n            sc = sc.push(tempinst);\n            sc.tinst = tempinst;\n            sc.minst = tempinst.minst;\n\n            int needGagging = (tempinst.gagged && !global.gag);\n            uint olderrors = global.errors;\n            int oldGaggedErrors = -1; // dead-store to prevent spurious warning\n            if (needGagging)\n                oldGaggedErrors = global.startGagging();\n\n            for (size_t i = 0; i < tempinst.members.dim; i++)\n            {\n                Dsymbol s = (*tempinst.members)[i];\n                static if (LOG)\n                {\n                    printf(\"\\tmember '%s', kind = '%s'\\n\", s.toChars(), s.kind());\n                }\n                s.semantic2(sc);\n                if (tempinst.gagged && global.errors != olderrors)\n                    break;\n            }\n\n            if (global.errors != olderrors)\n            {\n                if (!tempinst.errors)\n                {\n                    if (!tempdecl.literal)\n                        tempinst.error(tempinst.loc, \"error instantiating\");\n                    if (tempinst.tinst)\n                        tempinst.tinst.printInstantiationTrace();\n                }\n                tempinst.errors = true;\n            }\n            if (needGagging)\n                global.endGagging(oldGaggedErrors);\n\n            sc = sc.pop();\n            sc.pop();\n        }\n        static if (LOG)\n        {\n            printf(\"-TemplateInstance.semantic2('%s')\\n\", tempinst.toChars());\n        }\n    }\n\n    override void visit(TemplateMixin tmix)\n    {\n        if (tmix.semanticRun >= PASS.semantic2)\n            return;\n        tmix.semanticRun = PASS.semantic2;\n        static if (LOG)\n        {\n            printf(\"+TemplateMixin.semantic2('%s')\\n\", tmix.toChars());\n        }\n        if (tmix.members)\n        {\n            assert(sc);\n            sc = sc.push(tmix.argsym);\n            sc = sc.push(tmix);\n            for (size_t i = 0; i < tmix.members.dim; i++)\n            {\n                Dsymbol s = (*tmix.members)[i];\n                static if (LOG)\n                {\n                    printf(\"\\tmember '%s', kind = '%s'\\n\", s.toChars(), s.kind());\n                }\n                s.semantic2(sc);\n            }\n            sc = sc.pop();\n            sc.pop();\n        }\n        static if (LOG)\n        {\n            printf(\"-TemplateMixin.semantic2('%s')\\n\", tmix.toChars());\n        }\n    }\n\n    override void visit(VarDeclaration vd)\n    {\n        if (vd.semanticRun < PASS.semanticdone && vd.inuse)\n            return;\n\n        //printf(\"VarDeclaration::semantic2('%s')\\n\", toChars());\n\n        if (vd.aliassym)        // if it's a tuple\n        {\n            vd.aliassym.accept(this);\n            vd.semanticRun = PASS.semantic2done;\n            return;\n        }\n\n        if (vd._init && !vd.toParent().isFuncDeclaration())\n        {\n            vd.inuse++;\n            // https://issues.dlang.org/show_bug.cgi?id=14166\n            // Don't run CTFE for the temporary variables inside typeof\n            vd._init = vd._init.initializerSemantic(sc, vd.type, sc.intypeof == 1 ? INITnointerpret : INITinterpret);\n            vd.inuse--;\n        }\n        if (vd._init && vd.storage_class & STC.manifest)\n        {\n            /* Cannot initializer enums with CTFE classreferences and addresses of struct literals.\n             * Scan initializer looking for them. Issue error if found.\n             */\n            if (ExpInitializer ei = vd._init.isExpInitializer())\n            {\n                static bool hasInvalidEnumInitializer(Expression e)\n                {\n                    static bool arrayHasInvalidEnumInitializer(Expressions* elems)\n                    {\n                        foreach (e; *elems)\n                        {\n                            if (e && hasInvalidEnumInitializer(e))\n                                return true;\n                        }\n                        return false;\n                    }\n\n                    if (e.op == TOK.classReference)\n                        return true;\n                    if (e.op == TOK.address && (cast(AddrExp)e).e1.op == TOK.structLiteral)\n                        return true;\n                    if (e.op == TOK.arrayLiteral)\n                        return arrayHasInvalidEnumInitializer((cast(ArrayLiteralExp)e).elements);\n                    if (e.op == TOK.structLiteral)\n                        return arrayHasInvalidEnumInitializer((cast(StructLiteralExp)e).elements);\n                    if (e.op == TOK.assocArrayLiteral)\n                    {\n                        AssocArrayLiteralExp ae = cast(AssocArrayLiteralExp)e;\n                        return arrayHasInvalidEnumInitializer(ae.values) ||\n                               arrayHasInvalidEnumInitializer(ae.keys);\n                    }\n                    return false;\n                }\n\n                if (hasInvalidEnumInitializer(ei.exp))\n                    vd.error(\": Unable to initialize enum with class or pointer to struct. Use static const variable instead.\");\n            }\n        }\n        else if (vd._init && vd.isThreadlocal())\n        {\n            // Cannot initialize a thread-local class or pointer to struct variable with a literal\n            // that itself is a thread-local reference and would need dynamic initialization also.\n            if ((vd.type.ty == Tclass) && vd.type.isMutable() && !vd.type.isShared())\n            {\n                ExpInitializer ei = vd._init.isExpInitializer();\n                if (ei && ei.exp.op == TOK.classReference)\n                    vd.error(\"is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.\");\n            }\n            else if (vd.type.ty == Tpointer && vd.type.nextOf().ty == Tstruct && vd.type.nextOf().isMutable() && !vd.type.nextOf().isShared())\n            {\n                ExpInitializer ei = vd._init.isExpInitializer();\n                if (ei && ei.exp.op == TOK.address && (cast(AddrExp)ei.exp).e1.op == TOK.structLiteral)\n                    vd.error(\"is a thread-local pointer to struct and cannot have a static initializer. Use `static this()` to initialize instead.\");\n            }\n        }\n        vd.semanticRun = PASS.semantic2done;\n    }\n\n    override void visit(Module mod)\n    {\n        //printf(\"Module::semantic2('%s'): parent = %p\\n\", toChars(), parent);\n        if (mod.semanticRun != PASS.semanticdone) // semantic() not completed yet - could be recursive call\n            return;\n        mod.semanticRun = PASS.semantic2;\n        // Note that modules get their own scope, from scratch.\n        // This is so regardless of where in the syntax a module\n        // gets imported, it is unaffected by context.\n        Scope* sc = Scope.createGlobal(mod); // create root scope\n        //printf(\"Module = %p\\n\", sc.scopesym);\n        // Pass 2 semantic routines: do initializers and function bodies\n        for (size_t i = 0; i < mod.members.dim; i++)\n        {\n            Dsymbol s = (*mod.members)[i];\n            s.semantic2(sc);\n        }\n        if (mod.userAttribDecl)\n        {\n            mod.userAttribDecl.semantic2(sc);\n        }\n        sc = sc.pop();\n        sc.pop();\n        mod.semanticRun = PASS.semantic2done;\n        //printf(\"-Module::semantic2('%s'): parent = %p\\n\", toChars(), parent);\n    }\n\n    override void visit(FuncDeclaration fd)\n    {\n        import dmd.dmangle : mangleToFuncSignature;\n\n        if (fd.semanticRun >= PASS.semantic2done)\n            return;\n        assert(fd.semanticRun <= PASS.semantic2);\n        fd.semanticRun = PASS.semantic2;\n\n        //printf(\"FuncDeclaration::semantic2 [%s] fd0 = %s %s\\n\", loc.toChars(), toChars(), type.toChars());\n\n        // https://issues.dlang.org/show_bug.cgi?id=18385\n        // Disable for 2.079, s.t. a deprecation cycle can be started with 2.080\n        if (0)\n        if (fd.overnext && !fd.errors)\n        {\n            OutBuffer buf1;\n            OutBuffer buf2;\n\n            // Always starts the lookup from 'this', because the conflicts with\n            // previous overloads are already reported.\n            auto f1 = fd;\n            mangleToFuncSignature(buf1, f1);\n\n            overloadApply(f1, (Dsymbol s)\n            {\n                auto f2 = s.isFuncDeclaration();\n                if (!f2 || f1 == f2 || f2.errors)\n                    return 0;\n\n                // Don't have to check conflict between declaration and definition.\n                if ((f1.fbody !is null) != (f2.fbody !is null))\n                    return 0;\n\n                /* Check for overload merging with base class member functions.\n                 *\n                 *  class B { void foo() {} }\n                 *  class D : B {\n                 *    override void foo() {}    // B.foo appears as f2\n                 *    alias foo = B.foo;\n                 *  }\n                 */\n                if (f1.overrides(f2))\n                    return 0;\n\n                // extern (C) functions always conflict each other.\n                if (f1.ident == f2.ident &&\n                    f1.toParent2() == f2.toParent2() &&\n                    (f1.linkage != LINK.d && f1.linkage != LINK.cpp) &&\n                    (f2.linkage != LINK.d && f2.linkage != LINK.cpp))\n                {\n                    /* Allow the hack that is actually used in druntime,\n                     * to ignore function attributes for extern (C) functions.\n                     * TODO: Must be reconsidered in the future.\n                     *  BUG: https://issues.dlang.org/show_bug.cgi?id=18206\n                     *\n                     *  extern(C):\n                     *  alias sigfn_t  = void function(int);\n                     *  alias sigfn_t2 = void function(int) nothrow @nogc;\n                     *  sigfn_t  bsd_signal(int sig, sigfn_t  func);\n                     *  sigfn_t2 bsd_signal(int sig, sigfn_t2 func) nothrow @nogc;  // no error\n                     */\n                    if (f1.fbody is null || f2.fbody is null)\n                        return 0;\n\n                    auto tf1 = cast(TypeFunction)f1.type;\n                    auto tf2 = cast(TypeFunction)f2.type;\n                    error(f2.loc, \"%s `%s%s` cannot be overloaded with %s`extern(%s)` function at %s\",\n                            f2.kind(),\n                            f2.toPrettyChars(),\n                            parametersTypeToChars(tf2.parameters, tf2.varargs),\n                            (f1.linkage == f2.linkage ? \"another \" : \"\").ptr,\n                            linkageToChars(f1.linkage), f1.loc.toChars());\n                    f2.type = Type.terror;\n                    f2.errors = true;\n                    return 0;\n                }\n\n                buf2.reset();\n                mangleToFuncSignature(buf2, f2);\n\n                auto s1 = buf1.peekString();\n                auto s2 = buf2.peekString();\n\n                //printf(\"+%s\\n\\ts1 = %s\\n\\ts2 = %s @ [%s]\\n\", toChars(), s1, s2, f2.loc.toChars());\n                if (strcmp(s1, s2) == 0)\n                {\n                    auto tf2 = cast(TypeFunction)f2.type;\n                    error(f2.loc, \"%s `%s%s` conflicts with previous declaration at %s\",\n                            f2.kind(),\n                            f2.toPrettyChars(),\n                            parametersTypeToChars(tf2.parameters, tf2.varargs),\n                            f1.loc.toChars());\n                    f2.type = Type.terror;\n                    f2.errors = true;\n                }\n                return 0;\n            });\n        }\n        objc.setSelector(fd, sc);\n        objc.validateSelector(fd);\n        if (ClassDeclaration cd = fd.parent.isClassDeclaration())\n        {\n            objc.checkLinkage(fd);\n        }\n        if (!fd.type || fd.type.ty != Tfunction)\n            return;\n        TypeFunction f = cast(TypeFunction) fd.type;\n        if (!f.parameters)\n            return;\n        size_t nparams = Parameter.dim(f.parameters);\n        //semantic for parameters' UDAs\n        foreach (i; 0..nparams)\n        {\n            Parameter param = Parameter.getNth(f.parameters, i);\n            if (param && param.userAttribDecl)\n                param.userAttribDecl.semantic2(sc);\n        }\n    }\n\n    override void visit(Import i)\n    {\n        //printf(\"Import::semantic2('%s')\\n\", toChars());\n        if (i.mod)\n        {\n            i.mod.semantic2(null);\n            if (i.mod.needmoduleinfo)\n            {\n                //printf(\"module5 %s because of %s\\n\", sc.module.toChars(), mod.toChars());\n                if (sc)\n                    sc._module.needmoduleinfo = 1;\n            }\n        }\n    }\n\n    override void visit(Nspace ns)\n    {\n        if (ns.semanticRun >= PASS.semantic2)\n            return;\n        ns.semanticRun = PASS.semantic2;\n        static if (LOG)\n        {\n            printf(\"+Nspace::semantic2('%s')\\n\", ns.toChars());\n        }\n        if (ns.members)\n        {\n            assert(sc);\n            sc = sc.push(ns);\n            sc.linkage = LINK.cpp;\n            foreach (s; *ns.members)\n            {\n                static if (LOG)\n                {\n                    printf(\"\\tmember '%s', kind = '%s'\\n\", s.toChars(), s.kind());\n                }\n                s.semantic2(sc);\n            }\n            sc.pop();\n        }\n        static if (LOG)\n        {\n            printf(\"-Nspace::semantic2('%s')\\n\", ns.toChars());\n        }\n    }\n\n    override void visit(AttribDeclaration ad)\n    {\n        Dsymbols* d = ad.include(sc);\n        if (d)\n        {\n            Scope* sc2 = ad.newScope(sc);\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                s.semantic2(sc2);\n            }\n            if (sc2 != sc)\n                sc2.pop();\n        }\n    }\n\n    /**\n     * Run the DeprecatedDeclaration's semantic2 phase then its members.\n     *\n     * The message set via a `DeprecatedDeclaration` can be either of:\n     * - a string literal\n     * - an enum\n     * - a static immutable\n     * So we need to call ctfe to resolve it.\n     * Afterward forwards to the members' semantic2.\n     */\n    override void visit(DeprecatedDeclaration dd)\n    {\n        getMessage(dd);\n        visit(cast(AttribDeclaration)dd);\n    }\n\n    override void visit(AlignDeclaration ad)\n    {\n        ad.getAlignment(sc);\n        visit(cast(AttribDeclaration)ad);\n    }\n\n    override void visit(UserAttributeDeclaration uad)\n    {\n        if (uad.decl && uad.atts && uad.atts.dim && uad._scope)\n        {\n            static void eval(Scope* sc, Expressions* exps)\n            {\n                foreach (ref Expression e; *exps)\n                {\n                    if (e)\n                    {\n                        e = e.expressionSemantic(sc);\n                        if (definitelyValueParameter(e))\n                            e = e.ctfeInterpret();\n                        if (e.op == TOK.tuple)\n                        {\n                            TupleExp te = cast(TupleExp)e;\n                            eval(sc, te.exps);\n                        }\n                    }\n                }\n            }\n\n            uad._scope = null;\n            eval(sc, uad.atts);\n        }\n        visit(cast(AttribDeclaration)uad);\n    }\n\n    override void visit(AggregateDeclaration ad)\n    {\n        //printf(\"AggregateDeclaration::semantic2(%s) type = %s, errors = %d\\n\", ad.toChars(), ad.type.toChars(), ad.errors);\n        if (!ad.members)\n            return;\n\n        if (ad._scope)\n        {\n            ad.error(\"has forward references\");\n            return;\n        }\n\n        auto sc2 = ad.newScope(sc);\n\n        ad.determineSize(ad.loc);\n\n        for (size_t i = 0; i < ad.members.dim; i++)\n        {\n            Dsymbol s = (*ad.members)[i];\n            //printf(\"\\t[%d] %s\\n\", i, s.toChars());\n            s.semantic2(sc2);\n        }\n\n        sc2.pop();\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/semantic3.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/semantic3.d, _semantic3.d)\n * Documentation:  https://dlang.org/phobos/dmd_semantic3.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/semantic3.d\n */\n\nmodule dmd.semantic3;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\n\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arraytypes;\nimport dmd.astcodegen;\nimport dmd.attrib;\nimport dmd.blockexit;\nimport dmd.clone;\nimport dmd.ctorflow;\nimport dmd.dcast;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dimport;\nimport dmd.dinterpret;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.dversion;\nimport dmd.errors;\nimport dmd.escape;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.initsem;\nimport dmd.hdrgen;\nimport dmd.mtype;\nimport dmd.nogc;\nimport dmd.nspace;\nimport dmd.objc;\nimport dmd.opover;\nimport dmd.parse;\nimport dmd.root.filename;\nimport dmd.root.outbuffer;\nimport dmd.root.rmem;\nimport dmd.root.rootobject;\nimport dmd.sideeffect;\nimport dmd.statementsem;\nimport dmd.staticassert;\nimport dmd.tokens;\nimport dmd.utf;\nimport dmd.utils;\nimport dmd.semantic2;\nimport dmd.statement;\nimport dmd.target;\nimport dmd.templateparamsem;\nimport dmd.typesem;\nimport dmd.visitor;\n\nenum LOG = false;\n\n\n/*************************************\n * Does semantic analysis on function bodies.\n */\nextern(C++) void semantic3(Dsymbol dsym, Scope* sc)\n{\n    scope v = new Semantic3Visitor(sc);\n    dsym.accept(v);\n}\n\nprivate extern(C++) final class Semantic3Visitor : Visitor\n{\n    alias visit = Visitor.visit;\n\n    Scope* sc;\n    this(Scope* sc)\n    {\n        this.sc = sc;\n    }\n\n    override void visit(Dsymbol) {}\n\n    override void visit(TemplateInstance tempinst)\n    {\n        static if (LOG)\n        {\n            printf(\"TemplateInstance.semantic3('%s'), semanticRun = %d\\n\", tempinst.toChars(), tempinst.semanticRun);\n        }\n        //if (toChars()[0] == 'D') *(char*)0=0;\n        if (tempinst.semanticRun >= PASS.semantic3)\n            return;\n        tempinst.semanticRun = PASS.semantic3;\n        if (!tempinst.errors && tempinst.members)\n        {\n            TemplateDeclaration tempdecl = tempinst.tempdecl.isTemplateDeclaration();\n            assert(tempdecl);\n\n            sc = tempdecl._scope;\n            sc = sc.push(tempinst.argsym);\n            sc = sc.push(tempinst);\n            sc.tinst = tempinst;\n            sc.minst = tempinst.minst;\n\n            int needGagging = (tempinst.gagged && !global.gag);\n            uint olderrors = global.errors;\n            int oldGaggedErrors = -1; // dead-store to prevent spurious warning\n            /* If this is a gagged instantiation, gag errors.\n             * Future optimisation: If the results are actually needed, errors\n             * would already be gagged, so we don't really need to run semantic\n             * on the members.\n             */\n            if (needGagging)\n                oldGaggedErrors = global.startGagging();\n\n            for (size_t i = 0; i < tempinst.members.dim; i++)\n            {\n                Dsymbol s = (*tempinst.members)[i];\n                s.semantic3(sc);\n                if (tempinst.gagged && global.errors != olderrors)\n                    break;\n            }\n\n            if (global.errors != olderrors)\n            {\n                if (!tempinst.errors)\n                {\n                    if (!tempdecl.literal)\n                        tempinst.error(tempinst.loc, \"error instantiating\");\n                    if (tempinst.tinst)\n                        tempinst.tinst.printInstantiationTrace();\n                }\n                tempinst.errors = true;\n            }\n            if (needGagging)\n                global.endGagging(oldGaggedErrors);\n\n            sc = sc.pop();\n            sc.pop();\n        }\n    }\n\n    override void visit(TemplateMixin tmix)\n    {\n        if (tmix.semanticRun >= PASS.semantic3)\n            return;\n        tmix.semanticRun = PASS.semantic3;\n        static if (LOG)\n        {\n            printf(\"TemplateMixin.semantic3('%s')\\n\", tmix.toChars());\n        }\n        if (tmix.members)\n        {\n            sc = sc.push(tmix.argsym);\n            sc = sc.push(tmix);\n            for (size_t i = 0; i < tmix.members.dim; i++)\n            {\n                Dsymbol s = (*tmix.members)[i];\n                s.semantic3(sc);\n            }\n            sc = sc.pop();\n            sc.pop();\n        }\n    }\n\n    override void visit(Module mod)\n    {\n        //printf(\"Module::semantic3('%s'): parent = %p\\n\", toChars(), parent);\n        if (mod.semanticRun != PASS.semantic2done)\n            return;\n        mod.semanticRun = PASS.semantic3;\n        // Note that modules get their own scope, from scratch.\n        // This is so regardless of where in the syntax a module\n        // gets imported, it is unaffected by context.\n        Scope* sc = Scope.createGlobal(mod); // create root scope\n        //printf(\"Module = %p\\n\", sc.scopesym);\n        // Pass 3 semantic routines: do initializers and function bodies\n        for (size_t i = 0; i < mod.members.dim; i++)\n        {\n            Dsymbol s = (*mod.members)[i];\n            //printf(\"Module %s: %s.semantic3()\\n\", toChars(), s.toChars());\n            s.semantic3(sc);\n\n            mod.runDeferredSemantic2();\n        }\n        if (mod.userAttribDecl)\n        {\n            mod.userAttribDecl.semantic3(sc);\n        }\n        sc = sc.pop();\n        sc.pop();\n        mod.semanticRun = PASS.semantic3done;\n    }\n\n    override void visit(FuncDeclaration funcdecl)\n    {\n        /* Determine if function should add `return 0;`\n         */\n        bool addReturn0()\n        {\n            TypeFunction f = cast(TypeFunction)funcdecl.type;\n\n            return f.next.ty == Tvoid &&\n                (funcdecl.isMain() || global.params.betterC && funcdecl.isCMain());\n        }\n\n        VarDeclaration _arguments = null;\n\n        if (!funcdecl.parent)\n        {\n            if (global.errors)\n                return;\n            //printf(\"FuncDeclaration::semantic3(%s '%s', sc = %p)\\n\", kind(), toChars(), sc);\n            assert(0);\n        }\n        if (funcdecl.errors || isError(funcdecl.parent))\n        {\n            funcdecl.errors = true;\n            return;\n        }\n        //printf(\"FuncDeclaration::semantic3('%s.%s', %p, sc = %p, loc = %s)\\n\", funcdecl.parent.toChars(), funcdecl.toChars(), funcdecl, sc, funcdecl.loc.toChars());\n        //fflush(stdout);\n        //printf(\"storage class = x%x %x\\n\", sc.stc, storage_class);\n        //{ static int x; if (++x == 2) *(char*)0=0; }\n        //printf(\"\\tlinkage = %d\\n\", sc.linkage);\n\n        if (funcdecl.ident == Id.assign && !funcdecl.inuse)\n        {\n            if (funcdecl.storage_class & STC.inference)\n            {\n                /* https://issues.dlang.org/show_bug.cgi?id=15044\n                 * For generated opAssign function, any errors\n                 * from its body need to be gagged.\n                 */\n                uint oldErrors = global.startGagging();\n                ++funcdecl.inuse;\n                funcdecl.semantic3(sc);\n                --funcdecl.inuse;\n                if (global.endGagging(oldErrors))   // if errors happened\n                {\n                    // Disable generated opAssign, because some members forbid identity assignment.\n                    funcdecl.storage_class |= STC.disable;\n                    funcdecl.fbody = null;   // remove fbody which contains the error\n                    funcdecl.semantic3Errors = false;\n                }\n                return;\n            }\n        }\n\n        //printf(\" sc.incontract = %d\\n\", (sc.flags & SCOPE.contract));\n        if (funcdecl.semanticRun >= PASS.semantic3)\n            return;\n        funcdecl.semanticRun = PASS.semantic3;\n        funcdecl.semantic3Errors = false;\n\n        if (!funcdecl.type || funcdecl.type.ty != Tfunction)\n            return;\n        TypeFunction f = cast(TypeFunction)funcdecl.type;\n        if (!funcdecl.inferRetType && f.next.ty == Terror)\n            return;\n\n        if (!funcdecl.fbody && funcdecl.inferRetType && !f.next)\n        {\n            funcdecl.error(\"has no function body with return type inference\");\n            return;\n        }\n\n        uint oldErrors = global.errors;\n        auto fds = FuncDeclSem3(funcdecl,sc);\n\n        fds.checkInContractOverrides();\n\n        // Remember whether we need to generate an 'out' contract.\n        immutable bool needEnsure = FuncDeclaration.needsFensure(funcdecl);\n\n        if (funcdecl.fbody || funcdecl.frequires || needEnsure)\n        {\n            /* Symbol table into which we place parameters and nested functions,\n             * solely to diagnose name collisions.\n             */\n            funcdecl.localsymtab = new DsymbolTable();\n\n            // Establish function scope\n            auto ss = new ScopeDsymbol();\n            // find enclosing scope symbol, might skip symbol-less CTFE and/or FuncExp scopes\n            for (auto scx = sc; ; scx = scx.enclosing)\n            {\n                if (scx.scopesym)\n                {\n                    ss.parent = scx.scopesym;\n                    break;\n                }\n            }\n            ss.loc = funcdecl.loc;\n            ss.endlinnum = funcdecl.endloc.linnum;\n            Scope* sc2 = sc.push(ss);\n            sc2.func = funcdecl;\n            sc2.parent = funcdecl;\n            sc2.ctorflow.callSuper = CSX.none;\n            sc2.sbreak = null;\n            sc2.scontinue = null;\n            sc2.sw = null;\n            sc2.fes = funcdecl.fes;\n            sc2.linkage = LINK.d;\n            sc2.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.abstract_ | STC.deprecated_ | STC.override_ | STC.TYPECTOR | STC.final_ | STC.tls | STC.gshared | STC.ref_ | STC.return_ | STC.property | STC.nothrow_ | STC.pure_ | STC.safe | STC.trusted | STC.system);\n            sc2.protection = Prot(Prot.Kind.public_);\n            sc2.explicitProtection = 0;\n            sc2.aligndecl = null;\n            if (funcdecl.ident != Id.require && funcdecl.ident != Id.ensure)\n                sc2.flags = sc.flags & ~SCOPE.contract;\n            sc2.flags &= ~SCOPE.compile;\n            sc2.tf = null;\n            sc2.os = null;\n            sc2.inLoop = false;\n            sc2.userAttribDecl = null;\n            if (sc2.intypeof == 1)\n                sc2.intypeof = 2;\n            sc2.ctorflow.fieldinit = null;\n\n            /* Note: When a lambda is defined immediately under aggregate member\n             * scope, it should be contextless due to prevent interior pointers.\n             * e.g.\n             *      // dg points 'this' - it's interior pointer\n             *      class C { int x; void delegate() dg = (){ this.x = 1; }; }\n             *\n             * However, lambdas could be used inside typeof, in order to check\n             * some expressions validity at compile time. For such case the lambda\n             * body can access aggregate instance members.\n             * e.g.\n             *      class C { int x; static assert(is(typeof({ this.x = 1; }))); }\n             *\n             * To properly accept it, mark these lambdas as member functions.\n             */\n            if (auto fld = funcdecl.isFuncLiteralDeclaration())\n            {\n                if (auto ad = funcdecl.isMember2())\n                {\n                    if (!sc.intypeof)\n                    {\n                        if (fld.tok == TOK.delegate_)\n                            funcdecl.error(\"cannot be %s members\", ad.kind());\n                        else\n                            fld.tok = TOK.function_;\n                    }\n                    else\n                    {\n                        if (fld.tok != TOK.function_)\n                            fld.tok = TOK.delegate_;\n                    }\n                }\n            }\n\n            // Declare 'this'\n            auto ad = funcdecl.isThis();\n            funcdecl.vthis = funcdecl.declareThis(sc2, ad);\n            //printf(\"[%s] ad = %p vthis = %p\\n\", loc.toChars(), ad, vthis);\n            //if (vthis) printf(\"\\tvthis.type = %s\\n\", vthis.type.toChars());\n\n            // Declare hidden variable _arguments[] and _argptr\n            if (f.varargs == 1)\n            {\n                if (f.linkage == LINK.d)\n                {\n                    // Declare _arguments[]\n                    funcdecl.v_arguments = new VarDeclaration(Loc.initial, Type.typeinfotypelist.type, Id._arguments_typeinfo, null);\n                    funcdecl.v_arguments.storage_class |= STC.temp | STC.parameter;\n                    funcdecl.v_arguments.dsymbolSemantic(sc2);\n                    sc2.insert(funcdecl.v_arguments);\n                    funcdecl.v_arguments.parent = funcdecl;\n\n                    //Type *t = Type::typeinfo.type.constOf().arrayOf();\n                    Type t = Type.dtypeinfo.type.arrayOf();\n                    _arguments = new VarDeclaration(Loc.initial, t, Id._arguments, null);\n                    _arguments.storage_class |= STC.temp;\n                    _arguments.dsymbolSemantic(sc2);\n                    sc2.insert(_arguments);\n                    _arguments.parent = funcdecl;\n                }\n                if (f.linkage == LINK.d || (f.parameters && Parameter.dim(f.parameters)))\n                {\n                    // Declare _argptr\n                    Type t = Type.tvalist;\n                    // Init is handled in FuncDeclaration_toObjFile\n                    funcdecl.v_argptr = new VarDeclaration(Loc.initial, t, Id._argptr, new VoidInitializer(funcdecl.loc));\n                    funcdecl.v_argptr.storage_class |= STC.temp;\n                    funcdecl.v_argptr.dsymbolSemantic(sc2);\n                    sc2.insert(funcdecl.v_argptr);\n                    funcdecl.v_argptr.parent = funcdecl;\n                }\n            }\n\n            /* Declare all the function parameters as variables\n             * and install them in parameters[]\n             */\n            size_t nparams = Parameter.dim(f.parameters);\n            if (nparams)\n            {\n                /* parameters[] has all the tuples removed, as the back end\n                 * doesn't know about tuples\n                 */\n                funcdecl.parameters = new VarDeclarations();\n                funcdecl.parameters.reserve(nparams);\n                for (size_t i = 0; i < nparams; i++)\n                {\n                    Parameter fparam = Parameter.getNth(f.parameters, i);\n                    Identifier id = fparam.ident;\n                    StorageClass stc = 0;\n                    if (!id)\n                    {\n                        /* Generate identifier for un-named parameter,\n                         * because we need it later on.\n                         */\n                        fparam.ident = id = Identifier.generateId(\"_param_\", i);\n                        stc |= STC.temp;\n                    }\n                    Type vtype = fparam.type;\n                    auto v = new VarDeclaration(funcdecl.loc, vtype, id, null);\n                    //printf(\"declaring parameter %s of type %s\\n\", v.toChars(), v.type.toChars());\n                    stc |= STC.parameter;\n                    if (f.varargs == 2 && i + 1 == nparams)\n                    {\n                        stc |= STC.variadic;\n                        auto vtypeb = vtype.toBasetype();\n                        if (vtypeb.ty == Tarray)\n                        {\n                            /* Since it'll be pointing into the stack for the array\n                             * contents, it needs to be `scope`\n                             */\n                            stc |= STC.scope_;\n                        }\n                    }\n                    if (funcdecl.flags & FUNCFLAG.inferScope && !(fparam.storageClass & STC.scope_))\n                        stc |= STC.maybescope;\n                    stc |= fparam.storageClass & (STC.in_ | STC.out_ | STC.ref_ | STC.return_ | STC.scope_ | STC.lazy_ | STC.final_ | STC.TYPECTOR | STC.nodtor);\n                    v.storage_class = stc;\n                    v.dsymbolSemantic(sc2);\n                    if (!sc2.insert(v))\n                    {\n                        funcdecl.error(\"parameter `%s.%s` is already defined\", funcdecl.toChars(), v.toChars());\n                        funcdecl.errors = true;\n                    }\n                    else\n                        funcdecl.parameters.push(v);\n                    funcdecl.localsymtab.insert(v);\n                    v.parent = funcdecl;\n                    if (fparam.userAttribDecl)\n                        v.userAttribDecl = fparam.userAttribDecl;\n                }\n            }\n\n            // Declare the tuple symbols and put them in the symbol table,\n            // but not in parameters[].\n            if (f.parameters)\n            {\n                for (size_t i = 0; i < f.parameters.dim; i++)\n                {\n                    Parameter fparam = (*f.parameters)[i];\n                    if (!fparam.ident)\n                        continue; // never used, so ignore\n                    if (fparam.type.ty == Ttuple)\n                    {\n                        TypeTuple t = cast(TypeTuple)fparam.type;\n                        size_t dim = Parameter.dim(t.arguments);\n                        auto exps = new Objects(dim);\n                        for (size_t j = 0; j < dim; j++)\n                        {\n                            Parameter narg = Parameter.getNth(t.arguments, j);\n                            assert(narg.ident);\n                            VarDeclaration v = sc2.search(Loc.initial, narg.ident, null).isVarDeclaration();\n                            assert(v);\n                            Expression e = new VarExp(v.loc, v);\n                            (*exps)[j] = e;\n                        }\n                        assert(fparam.ident);\n                        auto v = new TupleDeclaration(funcdecl.loc, fparam.ident, exps);\n                        //printf(\"declaring tuple %s\\n\", v.toChars());\n                        v.isexp = true;\n                        if (!sc2.insert(v))\n                            funcdecl.error(\"parameter `%s.%s` is already defined\", funcdecl.toChars(), v.toChars());\n                        funcdecl.localsymtab.insert(v);\n                        v.parent = funcdecl;\n                    }\n                }\n            }\n\n            // Precondition invariant\n            Statement fpreinv = null;\n            if (funcdecl.addPreInvariant())\n            {\n                Expression e = addInvariant(funcdecl.loc, sc, ad, funcdecl.vthis);\n                if (e)\n                    fpreinv = new ExpStatement(Loc.initial, e);\n            }\n\n            // Postcondition invariant\n            Statement fpostinv = null;\n            if (funcdecl.addPostInvariant())\n            {\n                Expression e = addInvariant(funcdecl.loc, sc, ad, funcdecl.vthis);\n                if (e)\n                    fpostinv = new ExpStatement(Loc.initial, e);\n            }\n\n            // Pre/Postcondition contract\n            if (!funcdecl.fbody)\n                funcdecl.buildEnsureRequire();\n\n            Scope* scout = null;\n            if (needEnsure || funcdecl.addPostInvariant())\n            {\n                /* https://issues.dlang.org/show_bug.cgi?id=3657\n                 * Set the correct end line number for fensure scope.\n                 */\n                uint fensure_endlin = funcdecl.endloc.linnum;\n                if (funcdecl.fensure)\n                    if (auto s = funcdecl.fensure.isScopeStatement())\n                        fensure_endlin = s.endloc.linnum;\n\n                if ((needEnsure && global.params.useOut) || fpostinv)\n                {\n                    funcdecl.returnLabel = new LabelDsymbol(Id.returnLabel);\n                }\n\n                // scope of out contract (need for vresult.semantic)\n                auto sym = new ScopeDsymbol();\n                sym.parent = sc2.scopesym;\n                sym.loc = funcdecl.loc;\n                sym.endlinnum = fensure_endlin;\n                scout = sc2.push(sym);\n            }\n\n            if (funcdecl.fbody)\n            {\n                auto sym = new ScopeDsymbol();\n                sym.parent = sc2.scopesym;\n                sym.loc = funcdecl.loc;\n                sym.endlinnum = funcdecl.endloc.linnum;\n                sc2 = sc2.push(sym);\n\n                auto ad2 = funcdecl.isMember2();\n\n                /* If this is a class constructor\n                 */\n                if (ad2 && funcdecl.isCtorDeclaration())\n                {\n                    sc2.ctorflow.allocFieldinit(ad2.fields.dim);\n                    foreach (v; ad2.fields)\n                    {\n                        v.ctorinit = 0;\n                    }\n                }\n\n                if (!funcdecl.inferRetType && !Target.isReturnOnStack(f, funcdecl.needThis()))\n                    funcdecl.nrvo_can = 0;\n\n                bool inferRef = (f.isref && (funcdecl.storage_class & STC.auto_));\n\n                funcdecl.fbody = funcdecl.fbody.statementSemantic(sc2);\n                if (!funcdecl.fbody)\n                    funcdecl.fbody = new CompoundStatement(Loc.initial, new Statements());\n\n                if (funcdecl.naked)\n                {\n                    fpreinv = null;         // can't accommodate with no stack frame\n                    fpostinv = null;\n                }\n\n                assert(funcdecl.type == f || (funcdecl.type.ty == Tfunction && f.purity == PURE.impure && (cast(TypeFunction)funcdecl.type).purity >= PURE.fwdref));\n                f = cast(TypeFunction)funcdecl.type;\n\n                if (funcdecl.inferRetType)\n                {\n                    // If no return type inferred yet, then infer a void\n                    if (!f.next)\n                        f.next = Type.tvoid;\n                    if (f.checkRetType(funcdecl.loc))\n                        funcdecl.fbody = new ErrorStatement();\n                }\n                if (global.params.vcomplex && f.next !is null)\n                    f.next.checkComplexTransition(funcdecl.loc, sc);\n\n                if (funcdecl.returns && !funcdecl.fbody.isErrorStatement())\n                {\n                    for (size_t i = 0; i < funcdecl.returns.dim;)\n                    {\n                        Expression exp = (*funcdecl.returns)[i].exp;\n                        if (exp.op == TOK.variable && (cast(VarExp)exp).var == funcdecl.vresult)\n                        {\n                            if (addReturn0())\n                                exp.type = Type.tint32;\n                            else\n                                exp.type = f.next;\n                            // Remove `return vresult;` from returns\n                            funcdecl.returns.remove(i);\n                            continue;\n                        }\n                        if (inferRef && f.isref && !exp.type.constConv(f.next)) // https://issues.dlang.org/show_bug.cgi?id=13336\n                            f.isref = false;\n                        i++;\n                    }\n                }\n                if (f.isref) // Function returns a reference\n                {\n                    if (funcdecl.storage_class & STC.auto_)\n                        funcdecl.storage_class &= ~STC.auto_;\n                }\n                if (!Target.isReturnOnStack(f, funcdecl.needThis()))\n                    funcdecl.nrvo_can = 0;\n\n                if (funcdecl.fbody.isErrorStatement())\n                {\n                }\n                else if (funcdecl.isStaticCtorDeclaration())\n                {\n                    /* It's a static constructor. Ensure that all\n                     * ctor consts were initialized.\n                     */\n                    ScopeDsymbol pd = funcdecl.toParent().isScopeDsymbol();\n                    for (size_t i = 0; i < pd.members.dim; i++)\n                    {\n                        Dsymbol s = (*pd.members)[i];\n                        s.checkCtorConstInit();\n                    }\n                }\n                else if (ad2 && funcdecl.isCtorDeclaration())\n                {\n                    ClassDeclaration cd = ad2.isClassDeclaration();\n\n                    // Verify that all the ctorinit fields got initialized\n                    if (!(sc2.ctorflow.callSuper & CSX.this_ctor))\n                    {\n                        foreach (i, v; ad2.fields)\n                        {\n                            if (v.isThisDeclaration())\n                                continue;\n                            if (v.ctorinit == 0)\n                            {\n                                /* Current bugs in the flow analysis:\n                                 * 1. union members should not produce error messages even if\n                                 *    not assigned to\n                                 * 2. structs should recognize delegating opAssign calls as well\n                                 *    as delegating calls to other constructors\n                                 */\n                                if (v.isCtorinit() && !v.type.isMutable() && cd)\n                                    funcdecl.error(\"missing initializer for %s field `%s`\", MODtoChars(v.type.mod), v.toChars());\n                                else if (v.storage_class & STC.nodefaultctor)\n                                    error(funcdecl.loc, \"field `%s` must be initialized in constructor\", v.toChars());\n                                else if (v.type.needsNested())\n                                    error(funcdecl.loc, \"field `%s` must be initialized in constructor, because it is nested struct\", v.toChars());\n                            }\n                            else\n                            {\n                                bool mustInit = (v.storage_class & STC.nodefaultctor || v.type.needsNested());\n                                if (mustInit && !(sc2.ctorflow.fieldinit[i].csx & CSX.this_ctor))\n                                {\n                                    funcdecl.error(\"field `%s` must be initialized but skipped\", v.toChars());\n                                }\n                            }\n                        }\n                    }\n                    sc2.ctorflow.freeFieldinit();\n\n                    if (cd && !(sc2.ctorflow.callSuper & CSX.any_ctor) && cd.baseClass && cd.baseClass.ctor)\n                    {\n                        sc2.ctorflow.callSuper = CSX.none;\n\n                        // Insert implicit super() at start of fbody\n                        FuncDeclaration fd = resolveFuncCall(Loc.initial, sc2, cd.baseClass.ctor, null, funcdecl.vthis.type, null, 1);\n                        if (!fd)\n                        {\n                            funcdecl.error(\"no match for implicit `super()` call in constructor\");\n                        }\n                        else if (fd.storage_class & STC.disable)\n                        {\n                            funcdecl.error(\"cannot call `super()` implicitly because it is annotated with `@disable`\");\n                        }\n                        else\n                        {\n                            Expression e1 = new SuperExp(Loc.initial);\n                            Expression e = new CallExp(Loc.initial, e1);\n                            e = e.expressionSemantic(sc2);\n                            Statement s = new ExpStatement(Loc.initial, e);\n                            funcdecl.fbody = new CompoundStatement(Loc.initial, s, funcdecl.fbody);\n                        }\n                    }\n                    //printf(\"ctorflow.callSuper = x%x\\n\", sc2.ctorflow.callSuper);\n                }\n\n                /* https://issues.dlang.org/show_bug.cgi?id=17502\n                 * Wait until after the return type has been inferred before\n                 * generating the contracts for this function, and merging contracts\n                 * from overrides.\n                 *\n                 * https://issues.dlang.org/show_bug.cgi?id=17893\n                 * However should take care to generate this before inferered\n                 * function attributes are applied, such as 'nothrow'.\n                 *\n                 * This was originally at the end of the first semantic pass, but\n                 * required a fix-up to be done here for the '__result' variable\n                 * type of __ensure() inside auto functions, but this didn't work\n                 * if the out parameter was implicit.\n                 */\n                funcdecl.buildEnsureRequire();\n\n                // Check for errors related to 'nothrow'.\n                const blockexit = funcdecl.fbody.blockExit(funcdecl, f.isnothrow);\n                if (f.isnothrow && blockexit & BE.throw_)\n                    error(funcdecl.loc, \"`nothrow` %s `%s` may throw\", funcdecl.kind(), funcdecl.toPrettyChars());\n\n                if (!(blockexit & (BE.throw_ | BE.halt) || funcdecl.flags & FUNCFLAG.hasCatches))\n                {\n                    /* Disable optimization on Win32 due to\n                     * https://issues.dlang.org/show_bug.cgi?id=17997\n                     */\n//                    if (!global.params.isWindows || global.params.is64bit)\n                        funcdecl.eh_none = true;         // don't generate unwind tables for this function\n                }\n\n                if (funcdecl.flags & FUNCFLAG.nothrowInprocess)\n                {\n                    if (funcdecl.type == f)\n                        f = cast(TypeFunction)f.copy();\n                    f.isnothrow = !(blockexit & BE.throw_);\n                }\n\n                if (funcdecl.fbody.isErrorStatement())\n                {\n                }\n                else if (ad2 && funcdecl.isCtorDeclaration())\n                {\n                    /* Append:\n                     *  return this;\n                     * to function body\n                     */\n                    if (blockexit & BE.fallthru)\n                    {\n                        Statement s = new ReturnStatement(funcdecl.loc, null);\n                        s = s.statementSemantic(sc2);\n                        funcdecl.fbody = new CompoundStatement(funcdecl.loc, funcdecl.fbody, s);\n                        funcdecl.hasReturnExp |= (funcdecl.hasReturnExp & 1 ? 16 : 1);\n                    }\n                }\n                else if (funcdecl.fes)\n                {\n                    // For foreach(){} body, append a return 0;\n                    if (blockexit & BE.fallthru)\n                    {\n                        Expression e = new IntegerExp(0);\n                        Statement s = new ReturnStatement(Loc.initial, e);\n                        funcdecl.fbody = new CompoundStatement(Loc.initial, funcdecl.fbody, s);\n                        funcdecl.hasReturnExp |= (funcdecl.hasReturnExp & 1 ? 16 : 1);\n                    }\n                    assert(!funcdecl.returnLabel);\n                }\n                else\n                {\n                    const(bool) inlineAsm = (funcdecl.hasReturnExp & 8) != 0;\n                    if ((blockexit & BE.fallthru) && f.next.ty != Tvoid && !inlineAsm)\n                    {\n                        Expression e;\n                        if (!funcdecl.hasReturnExp)\n                            funcdecl.error(\"has no `return` statement, but is expected to return a value of type `%s`\", f.next.toChars());\n                        else\n                            funcdecl.error(\"no `return exp;` or `assert(0);` at end of function\");\n                        if (global.params.useAssert == CHECKENABLE.on && !global.params.useInline)\n                        {\n                            /* Add an assert(0, msg); where the missing return\n                             * should be.\n                             */\n                            e = new AssertExp(funcdecl.endloc, new IntegerExp(0), new StringExp(funcdecl.loc, cast(char*)\"missing return expression\"));\n                        }\n                        else\n                            e = new HaltExp(funcdecl.endloc);\n                        e = new CommaExp(Loc.initial, e, f.next.defaultInit(Loc.initial));\n                        e = e.expressionSemantic(sc2);\n                        Statement s = new ExpStatement(Loc.initial, e);\n                        funcdecl.fbody = new CompoundStatement(Loc.initial, funcdecl.fbody, s);\n                    }\n                }\n\n                if (funcdecl.returns)\n                {\n                    bool implicit0 = addReturn0();\n                    Type tret = implicit0 ? Type.tint32 : f.next;\n                    assert(tret.ty != Tvoid);\n                    if (funcdecl.vresult || funcdecl.returnLabel)\n                        funcdecl.buildResultVar(scout ? scout : sc2, tret);\n\n                    /* Cannot move this loop into NrvoWalker, because\n                     * returns[i] may be in the nested delegate for foreach-body.\n                     */\n                    for (size_t i = 0; i < funcdecl.returns.dim; i++)\n                    {\n                        ReturnStatement rs = (*funcdecl.returns)[i];\n                        Expression exp = rs.exp;\n                        if (exp.op == TOK.error)\n                            continue;\n                        if (tret.ty == Terror)\n                        {\n                            // https://issues.dlang.org/show_bug.cgi?id=13702\n                            exp = checkGC(sc2, exp);\n                            continue;\n                        }\n\n                        if (!exp.implicitConvTo(tret) && funcdecl.isTypeIsolated(exp.type))\n                        {\n                            if (exp.type.immutableOf().implicitConvTo(tret))\n                                exp = exp.castTo(sc2, exp.type.immutableOf());\n                            else if (exp.type.wildOf().implicitConvTo(tret))\n                                exp = exp.castTo(sc2, exp.type.wildOf());\n                        }\n                        exp = exp.implicitCastTo(sc2, tret);\n\n                        if (f.isref)\n                        {\n                            // Function returns a reference\n                            exp = exp.toLvalue(sc2, exp);\n                            checkReturnEscapeRef(sc2, exp, false);\n                        }\n                        else\n                        {\n                            exp = exp.optimize(WANTvalue);\n\n                            /* https://issues.dlang.org/show_bug.cgi?id=10789\n                             * If NRVO is not possible, all returned lvalues should call their postblits.\n                             */\n                            if (!funcdecl.nrvo_can)\n                                exp = doCopyOrMove(sc2, exp);\n\n                            if (tret.hasPointers())\n                                checkReturnEscape(sc2, exp, false);\n                        }\n\n                        exp = checkGC(sc2, exp);\n\n                        if (funcdecl.vresult)\n                        {\n                            // Create: return vresult = exp;\n                            exp = new BlitExp(rs.loc, funcdecl.vresult, exp);\n                            exp.type = funcdecl.vresult.type;\n\n                            if (rs.caseDim)\n                                exp = Expression.combine(exp, new IntegerExp(rs.caseDim));\n                        }\n                        else if (funcdecl.tintro && !tret.equals(funcdecl.tintro.nextOf()))\n                        {\n                            exp = exp.implicitCastTo(sc2, funcdecl.tintro.nextOf());\n                        }\n                        rs.exp = exp;\n                    }\n                }\n                if (funcdecl.nrvo_var || funcdecl.returnLabel)\n                {\n                    scope NrvoWalker nw = new NrvoWalker();\n                    nw.fd = funcdecl;\n                    nw.sc = sc2;\n                    nw.visitStmt(funcdecl.fbody);\n                }\n\n                sc2 = sc2.pop();\n            }\n\n            funcdecl.frequire = funcdecl.mergeFrequire(funcdecl.frequire);\n            funcdecl.fensure = funcdecl.mergeFensure(funcdecl.fensure, Id.result);\n\n            Statement freq = funcdecl.frequire;\n            Statement fens = funcdecl.fensure;\n\n            /* Do the semantic analysis on the [in] preconditions and\n             * [out] postconditions.\n             */\n            if (freq)\n            {\n                /* frequire is composed of the [in] contracts\n                 */\n                auto sym = new ScopeDsymbol();\n                sym.parent = sc2.scopesym;\n                sym.loc = funcdecl.loc;\n                sym.endlinnum = funcdecl.endloc.linnum;\n                sc2 = sc2.push(sym);\n                sc2.flags = (sc2.flags & ~SCOPE.contract) | SCOPE.require;\n\n                // BUG: need to error if accessing out parameters\n                // BUG: need to disallow returns and throws\n                // BUG: verify that all in and ref parameters are read\n                freq = freq.statementSemantic(sc2);\n                freq.blockExit(funcdecl, false);\n\n                funcdecl.eh_none = false;\n\n                sc2 = sc2.pop();\n\n                if (!global.params.useIn)\n                    freq = null;\n            }\n            if (fens)\n            {\n                /* fensure is composed of the [out] contracts\n                 */\n                if (f.next.ty == Tvoid && funcdecl.fensures)\n                {\n                    foreach (e; *funcdecl.fensures)\n                    {\n                        if (e.id)\n                        {\n                            funcdecl.error(e.ensure.loc, \"`void` functions have no result\");\n                            //fens = null;\n                        }\n                    }\n                }\n\n                sc2 = scout; //push\n                sc2.flags = (sc2.flags & ~SCOPE.contract) | SCOPE.ensure;\n\n                // BUG: need to disallow returns and throws\n\n                if (funcdecl.fensure && f.next.ty != Tvoid)\n                    funcdecl.buildResultVar(scout, f.next);\n\n                fens = fens.statementSemantic(sc2);\n                fens.blockExit(funcdecl, false);\n\n                funcdecl.eh_none = false;\n\n                sc2 = sc2.pop();\n\n                if (!global.params.useOut)\n                    fens = null;\n            }\n            if (funcdecl.fbody && funcdecl.fbody.isErrorStatement())\n            {\n            }\n            else\n            {\n                auto a = new Statements();\n                // Merge in initialization of 'out' parameters\n                if (funcdecl.parameters)\n                {\n                    for (size_t i = 0; i < funcdecl.parameters.dim; i++)\n                    {\n                        VarDeclaration v = (*funcdecl.parameters)[i];\n                        if (v.storage_class & STC.out_)\n                        {\n                            if (!v._init)\n                            {\n                                v.error(\"Zero-length `out` parameters are not allowed.\");\n                                return;\n                            }\n                            ExpInitializer ie = v._init.isExpInitializer();\n                            assert(ie);\n                            if (ie.exp.op == TOK.construct)\n                                ie.exp.op = TOK.assign; // construction occurred in parameter processing\n                            a.push(new ExpStatement(Loc.initial, ie.exp));\n                        }\n                    }\n                }\n\n                if (_arguments)\n                {\n                    /* Advance to elements[] member of TypeInfo_Tuple with:\n                     *  _arguments = v_arguments.elements;\n                     */\n                    Expression e = new VarExp(Loc.initial, funcdecl.v_arguments);\n                    e = new DotIdExp(Loc.initial, e, Id.elements);\n                    e = new ConstructExp(Loc.initial, _arguments, e);\n                    e = e.expressionSemantic(sc2);\n\n                    _arguments._init = new ExpInitializer(Loc.initial, e);\n                    auto de = new DeclarationExp(Loc.initial, _arguments);\n                    a.push(new ExpStatement(Loc.initial, de));\n                }\n\n                // Merge contracts together with body into one compound statement\n\n                if (freq || fpreinv)\n                {\n                    if (!freq)\n                        freq = fpreinv;\n                    else if (fpreinv)\n                        freq = new CompoundStatement(Loc.initial, freq, fpreinv);\n\n                    a.push(freq);\n                }\n\n                if (funcdecl.fbody)\n                    a.push(funcdecl.fbody);\n\n                if (fens || fpostinv)\n                {\n                    if (!fens)\n                        fens = fpostinv;\n                    else if (fpostinv)\n                        fens = new CompoundStatement(Loc.initial, fpostinv, fens);\n\n                    auto ls = new LabelStatement(Loc.initial, Id.returnLabel, fens);\n                    funcdecl.returnLabel.statement = ls;\n                    a.push(funcdecl.returnLabel.statement);\n\n                    if (f.next.ty != Tvoid && funcdecl.vresult)\n                    {\n                        // Create: return vresult;\n                        Expression e = new VarExp(Loc.initial, funcdecl.vresult);\n                        if (funcdecl.tintro)\n                        {\n                            e = e.implicitCastTo(sc, funcdecl.tintro.nextOf());\n                            e = e.expressionSemantic(sc);\n                        }\n                        auto s = new ReturnStatement(Loc.initial, e);\n                        a.push(s);\n                    }\n                }\n                if (addReturn0())\n                {\n                    // Add a return 0; statement\n                    Statement s = new ReturnStatement(Loc.initial, new IntegerExp(0));\n                    a.push(s);\n                }\n\n                Statement sbody = new CompoundStatement(Loc.initial, a);\n\n                /* Append destructor calls for parameters as finally blocks.\n                 */\n                if (funcdecl.parameters)\n                {\n                    foreach (v; *funcdecl.parameters)\n                    {\n                        if (v.storage_class & (STC.ref_ | STC.out_ | STC.lazy_))\n                            continue;\n                        if (v.needsScopeDtor())\n                        {\n                            // same with ExpStatement.scopeCode()\n                            Statement s = new DtorExpStatement(Loc.initial, v.edtor, v);\n                            v.storage_class |= STC.nodtor;\n\n                            s = s.statementSemantic(sc2);\n\n                            bool isnothrow = f.isnothrow & !(funcdecl.flags & FUNCFLAG.nothrowInprocess);\n                            const blockexit = s.blockExit(funcdecl, isnothrow);\n                            if (blockexit & BE.throw_)\n                                funcdecl.eh_none = false;\n                            if (f.isnothrow && isnothrow && blockexit & BE.throw_)\n                                error(funcdecl.loc, \"`nothrow` %s `%s` may throw\", funcdecl.kind(), funcdecl.toPrettyChars());\n                            if (funcdecl.flags & FUNCFLAG.nothrowInprocess && blockexit & BE.throw_)\n                                f.isnothrow = false;\n\n                            if (sbody.blockExit(funcdecl, f.isnothrow) == BE.fallthru)\n                                sbody = new CompoundStatement(Loc.initial, sbody, s);\n                            else\n                                sbody = new TryFinallyStatement(Loc.initial, sbody, s);\n                        }\n                    }\n                }\n                // from this point on all possible 'throwers' are checked\n                funcdecl.flags &= ~FUNCFLAG.nothrowInprocess;\n\n                if (funcdecl.isSynchronized())\n                {\n                    /* Wrap the entire function body in a synchronized statement\n                     */\n                    ClassDeclaration cd = funcdecl.isThis() ? funcdecl.isThis().isClassDeclaration() : funcdecl.parent.isClassDeclaration();\n                    if (cd)\n                    {\n                        if (!global.params.is64bit && global.params.isWindows && !funcdecl.isStatic() && !sbody.usesEH() && !global.params.trace)\n                        {\n                            /* The back end uses the \"jmonitor\" hack for syncing;\n                             * no need to do the sync at this level.\n                             */\n                        }\n                        else\n                        {\n                            Expression vsync;\n                            if (funcdecl.isStatic())\n                            {\n                                // The monitor is in the ClassInfo\n                                vsync = new DotIdExp(funcdecl.loc, resolve(funcdecl.loc, sc2, cd, false), Id.classinfo);\n                            }\n                            else\n                            {\n                                // 'this' is the monitor\n                                vsync = new VarExp(funcdecl.loc, funcdecl.vthis);\n                            }\n                            sbody = new PeelStatement(sbody); // don't redo semantic()\n                            sbody = new SynchronizedStatement(funcdecl.loc, vsync, sbody);\n                            sbody = sbody.statementSemantic(sc2);\n                        }\n                    }\n                    else\n                    {\n                        funcdecl.error(\"synchronized function `%s` must be a member of a class\", funcdecl.toChars());\n                    }\n                }\n\n                // If declaration has no body, don't set sbody to prevent incorrect codegen.\n                if (funcdecl.fbody || funcdecl.allowsContractWithoutBody())\n                    funcdecl.fbody = sbody;\n            }\n\n            // Fix up forward-referenced gotos\n            if (funcdecl.gotos)\n            {\n                for (size_t i = 0; i < funcdecl.gotos.dim; ++i)\n                {\n                    (*funcdecl.gotos)[i].checkLabel();\n                }\n            }\n\n            if (funcdecl.naked && (funcdecl.fensures || funcdecl.frequires))\n                funcdecl.error(\"naked assembly functions with contracts are not supported\");\n\n            sc2.ctorflow.callSuper = CSX.none;\n            sc2.pop();\n        }\n\n        if (funcdecl.checkClosure())\n        {\n            // We should be setting errors here instead of relying on the global error count.\n            //errors = true;\n        }\n\n        /* If function survived being marked as impure, then it is pure\n         */\n        if (funcdecl.flags & FUNCFLAG.purityInprocess)\n        {\n            funcdecl.flags &= ~FUNCFLAG.purityInprocess;\n            if (funcdecl.type == f)\n                f = cast(TypeFunction)f.copy();\n            f.purity = PURE.fwdref;\n        }\n\n        if (funcdecl.flags & FUNCFLAG.safetyInprocess)\n        {\n            funcdecl.flags &= ~FUNCFLAG.safetyInprocess;\n            if (funcdecl.type == f)\n                f = cast(TypeFunction)f.copy();\n            f.trust = TRUST.safe;\n        }\n\n        if (funcdecl.flags & FUNCFLAG.nogcInprocess)\n        {\n            funcdecl.flags &= ~FUNCFLAG.nogcInprocess;\n            if (funcdecl.type == f)\n                f = cast(TypeFunction)f.copy();\n            f.isnogc = true;\n        }\n\n        if (funcdecl.flags & FUNCFLAG.returnInprocess)\n        {\n            funcdecl.flags &= ~FUNCFLAG.returnInprocess;\n            if (funcdecl.storage_class & STC.return_)\n            {\n                if (funcdecl.type == f)\n                    f = cast(TypeFunction)f.copy();\n                f.isreturn = true;\n            }\n        }\n\n        funcdecl.flags &= ~FUNCFLAG.inferScope;\n\n        // Eliminate maybescope's\n        {\n            // Create and fill array[] with maybe candidates from the `this` and the parameters\n            VarDeclaration[] array = void;\n\n            VarDeclaration[10] tmp = void;\n            size_t dim = (funcdecl.vthis !is null) + (funcdecl.parameters ? funcdecl.parameters.dim : 0);\n            if (dim <= tmp.length)\n                array = tmp[0 .. dim];\n            else\n            {\n                auto ptr = cast(VarDeclaration*)mem.xmalloc(dim * VarDeclaration.sizeof);\n                array = ptr[0 .. dim];\n            }\n            size_t n = 0;\n            if (funcdecl.vthis)\n                array[n++] = funcdecl.vthis;\n            if (funcdecl.parameters)\n            {\n                foreach (v; *funcdecl.parameters)\n                {\n                    array[n++] = v;\n                }\n            }\n\n            eliminateMaybeScopes(array[0 .. n]);\n\n            if (dim > tmp.length)\n                mem.xfree(array.ptr);\n        }\n\n        // Infer STC.scope_\n        if (funcdecl.parameters && !funcdecl.errors)\n        {\n            size_t nfparams = Parameter.dim(f.parameters);\n            assert(nfparams == funcdecl.parameters.dim);\n            foreach (u, v; *funcdecl.parameters)\n            {\n                if (v.storage_class & STC.maybescope)\n                {\n                    //printf(\"Inferring scope for %s\\n\", v.toChars());\n                    Parameter p = Parameter.getNth(f.parameters, u);\n                    notMaybeScope(v);\n                    v.storage_class |= STC.scope_ | STC.scopeinferred;\n                    p.storageClass |= STC.scope_ | STC.scopeinferred;\n                    assert(!(p.storageClass & STC.maybescope));\n                }\n            }\n        }\n\n        if (funcdecl.vthis && funcdecl.vthis.storage_class & STC.maybescope)\n        {\n            notMaybeScope(funcdecl.vthis);\n            funcdecl.vthis.storage_class |= STC.scope_ | STC.scopeinferred;\n            f.isscope = true;\n            f.isscopeinferred = true;\n        }\n\n        // reset deco to apply inference result to mangled name\n        if (f != funcdecl.type)\n            f.deco = null;\n\n        // Do semantic type AFTER pure/nothrow inference.\n        if (!f.deco && funcdecl.ident != Id.xopEquals && funcdecl.ident != Id.xopCmp)\n        {\n            sc = sc.push();\n            if (funcdecl.isCtorDeclaration()) // https://issues.dlang.org/show_bug.cgi?id=#15665\n                sc.flags |= SCOPE.ctor;\n            sc.stc = 0;\n            sc.linkage = funcdecl.linkage; // https://issues.dlang.org/show_bug.cgi?id=8496\n            funcdecl.type = f.typeSemantic(funcdecl.loc, sc);\n            sc = sc.pop();\n        }\n\n        /* If this function had instantiated with gagging, error reproduction will be\n         * done by TemplateInstance::semantic.\n         * Otherwise, error gagging should be temporarily ungagged by functionSemantic3.\n         */\n        funcdecl.semanticRun = PASS.semantic3done;\n        funcdecl.semantic3Errors = (global.errors != oldErrors) || (funcdecl.fbody && funcdecl.fbody.isErrorStatement());\n        if (funcdecl.type.ty == Terror)\n            funcdecl.errors = true;\n        //printf(\"-FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\\n\", parent.toChars(), toChars(), sc, loc.toChars());\n        //fflush(stdout);\n    }\n\n    override void visit(CtorDeclaration ctor)\n    {\n        //printf(\"CtorDeclaration()\\n%s\\n\", ctor.fbody.toChars());\n        if (ctor.semanticRun >= PASS.semantic3)\n            return;\n\n        /* If any of the fields of the aggregate have a destructor, add\n         *   scope (failure) { this.fieldDtor(); }\n         * as the first statement. It is not necessary to add it after\n         * each initialization of a field, because destruction of .init constructed\n         * structs should be benign.\n         * https://issues.dlang.org/show_bug.cgi?id=14246\n         */\n        AggregateDeclaration ad = ctor.toParent2().isAggregateDeclaration();\n        if (ad && ad.fieldDtor && global.params.dtorFields)\n        {\n            /* Generate:\n             *   this.fieldDtor()\n             */\n            Expression e = new ThisExp(ctor.loc);\n            e.type = ad.type.mutableOf();\n            e = new DotVarExp(ctor.loc, e, ad.fieldDtor, false);\n            e = new CallExp(ctor.loc, e);\n            auto sexp = new ExpStatement(ctor.loc, e);\n            auto ss = new ScopeStatement(ctor.loc, sexp, ctor.loc);\n\n            version (all)\n            {\n                /* Generate:\n                 *   try { ctor.fbody; }\n                 *   catch (Exception __o)\n                 *   { this.fieldDtor(); throw __o; }\n                 * This differs from the alternate scope(failure) version in that an Exception\n                 * is caught rather than a Throwable. This enables the optimization whereby\n                 * the try-catch can be removed if ctor.fbody is nothrow. (nothrow only\n                 * applies to Exception.)\n                 */\n                Identifier id = Identifier.generateId(\"__o\");\n                auto ts = new ThrowStatement(ctor.loc, new IdentifierExp(ctor.loc, id));\n                auto handler = new CompoundStatement(ctor.loc, ss, ts);\n\n                auto catches = new Catches();\n                auto ctch = new Catch(ctor.loc, getException(), id, handler);\n                catches.push(ctch);\n\n                ctor.fbody = new TryCatchStatement(ctor.loc, ctor.fbody, catches);\n            }\n            else\n            {\n                /* Generate:\n                 *   scope (failure) { this.fieldDtor(); }\n                 * Hopefully we can use this version someday when scope(failure) catches\n                 * Exception instead of Throwable.\n                 */\n                auto s = new OnScopeStatement(ctor.loc, TOK.onScopeFailure, ss);\n                ctor.fbody = new CompoundStatement(ctor.loc, s, ctor.fbody);\n            }\n        }\n        visit(cast(FuncDeclaration)ctor);\n    }\n\n\n    override void visit(Nspace ns)\n    {\n        if (ns.semanticRun >= PASS.semantic3)\n            return;\n        ns.semanticRun = PASS.semantic3;\n        static if (LOG)\n        {\n            printf(\"Nspace::semantic3('%s')\\n\", ns.toChars());\n        }\n        if (ns.members)\n        {\n            sc = sc.push(ns);\n            sc.linkage = LINK.cpp;\n            foreach (s; *ns.members)\n            {\n                s.semantic3(sc);\n            }\n            sc.pop();\n        }\n    }\n\n    override void visit(AttribDeclaration ad)\n    {\n        Dsymbols* d = ad.include(sc);\n        if (d)\n        {\n            Scope* sc2 = ad.newScope(sc);\n            for (size_t i = 0; i < d.dim; i++)\n            {\n                Dsymbol s = (*d)[i];\n                s.semantic3(sc2);\n            }\n            if (sc2 != sc)\n                sc2.pop();\n        }\n    }\n\n    override void visit(AggregateDeclaration ad)\n    {\n        //printf(\"AggregateDeclaration::semantic3(sc=%p, %s) type = %s, errors = %d\\n\", sc, toChars(), type.toChars(), errors);\n        if (!ad.members)\n            return;\n\n        StructDeclaration sd = ad.isStructDeclaration();\n        if (!sc) // from runDeferredSemantic3 for TypeInfo generation\n        {\n            assert(sd);\n            sd.semanticTypeInfoMembers();\n            return;\n        }\n\n        auto sc2 = ad.newScope(sc);\n\n        for (size_t i = 0; i < ad.members.dim; i++)\n        {\n            Dsymbol s = (*ad.members)[i];\n            s.semantic3(sc2);\n        }\n\n        sc2.pop();\n\n        // don't do it for unused deprecated types\n        // or error ypes\n        if (!ad.getRTInfo && Type.rtinfo && (!ad.isDeprecated() || global.params.useDeprecated != Diagnostic.error) && (ad.type && ad.type.ty != Terror))\n        {\n            // Evaluate: RTinfo!type\n            auto tiargs = new Objects();\n            tiargs.push(ad.type);\n            auto ti = new TemplateInstance(ad.loc, Type.rtinfo, tiargs);\n\n            Scope* sc3 = ti.tempdecl._scope.startCTFE();\n            sc3.tinst = sc.tinst;\n            sc3.minst = sc.minst;\n            if (ad.isDeprecated())\n                sc3.stc |= STC.deprecated_;\n\n            ti.dsymbolSemantic(sc3);\n            ti.semantic2(sc3);\n            ti.semantic3(sc3);\n            auto e = resolve(Loc.initial, sc3, ti.toAlias(), false);\n\n            sc3.endCTFE();\n\n            e = e.ctfeInterpret();\n            ad.getRTInfo = e;\n        }\n        if (sd)\n            sd.semanticTypeInfoMembers();\n        ad.semanticRun = PASS.semantic3done;\n    }\n}\n\nprivate struct FuncDeclSem3\n{\n    // The FuncDeclaration subject to Semantic analysis\n    FuncDeclaration funcdecl;\n\n    // Scope of analysis\n    Scope* sc;\n    this(FuncDeclaration fd,Scope* s)\n    {\n        funcdecl = fd;\n        sc = s;\n    }\n\n    /* Checks that the overriden functions (if any) have in contracts if\n     * funcdecl has an in contract.\n     */\n    void checkInContractOverrides()\n    {\n        if (funcdecl.frequires)\n        {\n            for (size_t i = 0; i < funcdecl.foverrides.dim; i++)\n            {\n                FuncDeclaration fdv = funcdecl.foverrides[i];\n                if (fdv.fbody && !fdv.frequires)\n                {\n                    funcdecl.error(\"cannot have an in contract when overridden function `%s` does not have an in contract\", fdv.toPrettyChars());\n                    break;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/sideeffect.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/sideeffect.d, _sideeffect.d)\n * Documentation:  https://dlang.org/phobos/dmd_sideeffect.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/sideeffect.d\n */\n\nmodule dmd.sideeffect;\n\nimport dmd.apply;\nimport dmd.declaration;\nimport dmd.dscope;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.mtype;\nimport dmd.tokens;\nimport dmd.visitor;\n\n/**************************************************\n * Front-end expression rewriting should create temporary variables for\n * non trivial sub-expressions in order to:\n *  1. save evaluation order\n *  2. prevent sharing of sub-expression in AST\n */\nextern (C++) bool isTrivialExp(Expression e)\n{\n    extern (C++) final class IsTrivialExp : StoppableVisitor\n    {\n        alias visit = typeof(super).visit;\n    public:\n        extern (D) this()\n        {\n        }\n\n        override void visit(Expression e)\n        {\n            /* https://issues.dlang.org/show_bug.cgi?id=11201\n             * CallExp is always non trivial expression,\n             * especially for inlining.\n             */\n            if (e.op == TOK.call)\n            {\n                stop = true;\n                return;\n            }\n            // stop walking if we determine this expression has side effects\n            stop = lambdaHasSideEffect(e);\n        }\n    }\n\n    scope IsTrivialExp v = new IsTrivialExp();\n    return walkPostorder(e, v) == false;\n}\n\n/********************************************\n * Determine if Expression has any side effects.\n */\nextern (C++) bool hasSideEffect(Expression e)\n{\n    extern (C++) final class LambdaHasSideEffect : StoppableVisitor\n    {\n        alias visit = typeof(super).visit;\n    public:\n        extern (D) this()\n        {\n        }\n\n        override void visit(Expression e)\n        {\n            // stop walking if we determine this expression has side effects\n            stop = lambdaHasSideEffect(e);\n        }\n    }\n\n    scope LambdaHasSideEffect v = new LambdaHasSideEffect();\n    return walkPostorder(e, v);\n}\n\n/********************************************\n * Determine if the call of f, or function type or delegate type t1, has any side effects.\n * Returns:\n *      0   has any side effects\n *      1   nothrow + constant purity\n *      2   nothrow + strong purity\n */\nint callSideEffectLevel(FuncDeclaration f)\n{\n    /* https://issues.dlang.org/show_bug.cgi?id=12760\n     * ctor call always has side effects.\n     */\n    if (f.isCtorDeclaration())\n        return 0;\n    assert(f.type.ty == Tfunction);\n    TypeFunction tf = cast(TypeFunction)f.type;\n    if (tf.isnothrow)\n    {\n        PURE purity = f.isPure();\n        if (purity == PURE.strong)\n            return 2;\n        if (purity == PURE.const_)\n            return 1;\n    }\n    return 0;\n}\n\nint callSideEffectLevel(Type t)\n{\n    t = t.toBasetype();\n    TypeFunction tf;\n    if (t.ty == Tdelegate)\n        tf = cast(TypeFunction)(cast(TypeDelegate)t).next;\n    else\n    {\n        assert(t.ty == Tfunction);\n        tf = cast(TypeFunction)t;\n    }\n    if (!tf.isnothrow)  // function can throw\n        return 0;\n\n    tf.purityLevel();\n    PURE purity = tf.purity;\n    if (t.ty == Tdelegate && purity > PURE.weak)\n    {\n        if (tf.isMutable())\n            purity = PURE.weak;\n        else if (!tf.isImmutable())\n            purity = PURE.const_;\n    }\n\n    if (purity == PURE.strong)\n        return 2;\n    if (purity == PURE.const_)\n        return 1;\n    return 0;\n}\n\nprivate bool lambdaHasSideEffect(Expression e)\n{\n    switch (e.op)\n    {\n    // Sort the cases by most frequently used first\n    case TOK.assign:\n    case TOK.plusPlus:\n    case TOK.minusMinus:\n    case TOK.declaration:\n    case TOK.construct:\n    case TOK.blit:\n    case TOK.addAssign:\n    case TOK.minAssign:\n    case TOK.concatenateAssign:\n    case TOK.concatenateElemAssign:\n    case TOK.concatenateDcharAssign:\n    case TOK.mulAssign:\n    case TOK.divAssign:\n    case TOK.modAssign:\n    case TOK.leftShiftAssign:\n    case TOK.rightShiftAssign:\n    case TOK.unsignedRightShiftAssign:\n    case TOK.andAssign:\n    case TOK.orAssign:\n    case TOK.xorAssign:\n    case TOK.powAssign:\n    case TOK.in_:\n    case TOK.remove:\n    case TOK.assert_:\n    case TOK.halt:\n    case TOK.delete_:\n    case TOK.new_:\n    case TOK.newAnonymousClass:\n        return true;\n    case TOK.call:\n        {\n            CallExp ce = cast(CallExp)e;\n            /* Calling a function or delegate that is pure nothrow\n             * has no side effects.\n             */\n            if (ce.e1.type)\n            {\n                Type t = ce.e1.type.toBasetype();\n                if (t.ty == Tdelegate)\n                    t = (cast(TypeDelegate)t).next;\n                if (t.ty == Tfunction && (ce.f ? callSideEffectLevel(ce.f) : callSideEffectLevel(ce.e1.type)) > 0)\n                {\n                }\n                else\n                    return true;\n            }\n            break;\n        }\n    case TOK.cast_:\n        {\n            CastExp ce = cast(CastExp)e;\n            /* if:\n             *  cast(classtype)func()  // because it may throw\n             */\n            if (ce.to.ty == Tclass && ce.e1.op == TOK.call && ce.e1.type.ty == Tclass)\n                return true;\n            break;\n        }\n    default:\n        break;\n    }\n    return false;\n}\n\n/***********************************\n * The result of this expression will be discarded.\n * Print error messages if the operation has no side effects (and hence is meaningless).\n * Returns:\n *      true if expression has no side effects\n */\nbool discardValue(Expression e)\n{\n    if (lambdaHasSideEffect(e)) // check side-effect shallowly\n        return false;\n    switch (e.op)\n    {\n    case TOK.cast_:\n        {\n            CastExp ce = cast(CastExp)e;\n            if (ce.to.equals(Type.tvoid))\n            {\n                /*\n                 * Don't complain about an expression with no effect if it was cast to void\n                 */\n                return false;\n            }\n            break; // complain\n        }\n    case TOK.error:\n        return false;\n    case TOK.variable:\n        {\n            VarDeclaration v = (cast(VarExp)e).var.isVarDeclaration();\n            if (v && (v.storage_class & STC.temp))\n            {\n                // https://issues.dlang.org/show_bug.cgi?id=5810\n                // Don't complain about an internal generated variable.\n                return false;\n            }\n            break;\n        }\n    case TOK.call:\n        /* Issue 3882: */\n        if (global.params.warnings != Diagnostic.off && !global.gag)\n        {\n            CallExp ce = cast(CallExp)e;\n            if (e.type.ty == Tvoid)\n            {\n                /* Don't complain about calling void-returning functions with no side-effect,\n                 * because purity and nothrow are inferred, and because some of the\n                 * runtime library depends on it. Needs more investigation.\n                 *\n                 * One possible solution is to restrict this message to only be called in hierarchies that\n                 * never call assert (and or not called from inside unittest blocks)\n                 */\n            }\n            else if (ce.e1.type)\n            {\n                Type t = ce.e1.type.toBasetype();\n                if (t.ty == Tdelegate)\n                    t = (cast(TypeDelegate)t).next;\n                if (t.ty == Tfunction && (ce.f ? callSideEffectLevel(ce.f) : callSideEffectLevel(ce.e1.type)) > 0)\n                {\n                    const(char)* s;\n                    if (ce.f)\n                        s = ce.f.toPrettyChars();\n                    else if (ce.e1.op == TOK.star)\n                    {\n                        // print 'fp' if ce.e1 is (*fp)\n                        s = (cast(PtrExp)ce.e1).e1.toChars();\n                    }\n                    else\n                        s = ce.e1.toChars();\n                    e.warning(\"calling %s without side effects discards return value of type %s, prepend a cast(void) if intentional\", s, e.type.toChars());\n                }\n            }\n        }\n        return false;\n    case TOK.andAnd:\n    case TOK.orOr:\n        {\n            LogicalExp aae = cast(LogicalExp)e;\n            return discardValue(aae.e2);\n        }\n    case TOK.question:\n        {\n            CondExp ce = cast(CondExp)e;\n            /* https://issues.dlang.org/show_bug.cgi?id=6178\n             * https://issues.dlang.org/show_bug.cgi?id=14089\n             * Either CondExp::e1 or e2 may have\n             * redundant expression to make those types common. For example:\n             *\n             *  struct S { this(int n); int v; alias v this; }\n             *  S[int] aa;\n             *  aa[1] = 0;\n             *\n             * The last assignment statement will be rewitten to:\n             *\n             *  1 in aa ? aa[1].value = 0 : (aa[1] = 0, aa[1].this(0)).value;\n             *\n             * The last DotVarExp is necessary to take assigned value.\n             *\n             *  int value = (aa[1] = 0);    // value = aa[1].value\n             *\n             * To avoid false error, discardValue() should be called only when\n             * the both tops of e1 and e2 have actually no side effects.\n             */\n            if (!lambdaHasSideEffect(ce.e1) && !lambdaHasSideEffect(ce.e2))\n            {\n                return discardValue(ce.e1) |\n                       discardValue(ce.e2);\n            }\n            return false;\n        }\n    case TOK.comma:\n        {\n            CommaExp ce = cast(CommaExp)e;\n            /* Check for compiler-generated code of the form  auto __tmp, e, __tmp;\n             * In such cases, only check e for side effect (it's OK for __tmp to have\n             * no side effect).\n             * See https://issues.dlang.org/show_bug.cgi?id=4231 for discussion\n             */\n            auto fc = firstComma(ce);\n            if (fc.op == TOK.declaration && ce.e2.op == TOK.variable && (cast(DeclarationExp)fc).declaration == (cast(VarExp)ce.e2).var)\n            {\n                return false;\n            }\n            // Don't check e1 until we cast(void) the a,b code generation\n            //discardValue(ce.e1);\n            return discardValue(ce.e2);\n        }\n    case TOK.tuple:\n        /* Pass without complaint if any of the tuple elements have side effects.\n         * Ideally any tuple elements with no side effects should raise an error,\n         * this needs more investigation as to what is the right thing to do.\n         */\n        if (!hasSideEffect(e))\n            break;\n        return false;\n    default:\n        break;\n    }\n    e.error(\"`%s` has no effect\", e.toChars());\n    return true;\n}\n\n/**************************************************\n * Build a temporary variable to copy the value of e into.\n * Params:\n *  stc = storage classes will be added to the made temporary variable\n *  name = name for temporary variable\n *  e = original expression\n * Returns:\n *  Newly created temporary variable.\n */\nVarDeclaration copyToTemp(StorageClass stc, const char* name, Expression e)\n{\n    assert(name[0] == '_' && name[1] == '_');\n    auto vd = new VarDeclaration(e.loc, e.type,\n        Identifier.generateId(name),\n        new ExpInitializer(e.loc, e));\n    vd.storage_class = stc | STC.temp | STC.ctfe; // temporary is always CTFEable\n    return vd;\n}\n\n/**************************************************\n * Build a temporary variable to extract e's evaluation, if e is not trivial.\n * Params:\n *  sc = scope\n *  name = name for temporary variable\n *  e0 = a new side effect part will be appended to it.\n *  e = original expression\n *  alwaysCopy = if true, build new temporary variable even if e is trivial.\n * Returns:\n *  When e is trivial and alwaysCopy == false, e itself is returned.\n *  Otherwise, a new VarExp is returned.\n * Note:\n *  e's lvalue-ness will be handled well by STC.ref_ or STC.rvalue.\n */\nExpression extractSideEffect(Scope* sc, const char* name,\n    ref Expression e0, Expression e, bool alwaysCopy = false)\n{\n    if (!alwaysCopy && isTrivialExp(e))\n        return e;\n\n    auto vd = copyToTemp(0, name, e);\n    vd.storage_class |= e.isLvalue() ? STC.ref_ : STC.rvalue;\n\n    e0 = Expression.combine(e0, new DeclarationExp(vd.loc, vd)\n                                .expressionSemantic(sc));\n\n    return new VarExp(vd.loc, vd)\n           .expressionSemantic(sc);\n}\n"
  },
  {
    "path": "gcc/d/dmd/statement.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statement.d, _statement.d)\n * Documentation:  https://dlang.org/phobos/dmd_statement.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/statement.d\n */\n\nmodule dmd.statement;\n\nimport core.stdc.stdarg;\nimport core.stdc.stdio;\n\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.attrib;\nimport dmd.astcodegen;\nimport dmd.gluelayer;\nimport dmd.canthrow;\nimport dmd.cond;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dimport;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.dinterpret;\nimport dmd.mtype;\nimport dmd.parse;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.sapply;\nimport dmd.sideeffect;\nimport dmd.staticassert;\nimport dmd.tokens;\nimport dmd.visitor;\n\n/**\n * Returns:\n *     `TypeIdentifier` corresponding to `object.Throwable`\n */\nTypeIdentifier getThrowable()\n{\n    auto tid = new TypeIdentifier(Loc.initial, Id.empty);\n    tid.addIdent(Id.object);\n    tid.addIdent(Id.Throwable);\n    return tid;\n}\n\n/**\n * Returns:\n *      TypeIdentifier corresponding to `object.Exception`\n */\nTypeIdentifier getException()\n{\n    auto tid = new TypeIdentifier(Loc.initial, Id.empty);\n    tid.addIdent(Id.object);\n    tid.addIdent(Id.Exception);\n    return tid;\n}\n\n\n/***********************************************************\n * Specification: http://dlang.org/spec/statement.html\n */\nextern (C++) abstract class Statement : RootObject\n{\n    Loc loc;\n\n    override final DYNCAST dyncast() const\n    {\n        return DYNCAST.statement;\n    }\n\n    final extern (D) this(const ref Loc loc)\n    {\n        this.loc = loc;\n        // If this is an in{} contract scope statement (skip for determining\n        //  inlineStatus of a function body for header content)\n    }\n\n    Statement syntaxCopy()\n    {\n        assert(0);\n    }\n\n    /*************************************\n     * Do syntax copy of an array of Statement's.\n     */\n    static Statements* arraySyntaxCopy(Statements* a)\n    {\n        Statements* b = null;\n        if (a)\n        {\n            b = a.copy();\n            foreach (i, s; *a)\n            {\n                (*b)[i] = s ? s.syntaxCopy() : null;\n            }\n        }\n        return b;\n    }\n\n    override final const(char)* toChars()\n    {\n        HdrGenState hgs;\n        OutBuffer buf;\n        .toCBuffer(this, &buf, &hgs);\n        return buf.extractString();\n    }\n\n    final void error(const(char)* format, ...)\n    {\n        va_list ap;\n        va_start(ap, format);\n        .verror(loc, format, ap);\n        va_end(ap);\n    }\n\n    final void warning(const(char)* format, ...)\n    {\n        va_list ap;\n        va_start(ap, format);\n        .vwarning(loc, format, ap);\n        va_end(ap);\n    }\n\n    final void deprecation(const(char)* format, ...)\n    {\n        va_list ap;\n        va_start(ap, format);\n        .vdeprecation(loc, format, ap);\n        va_end(ap);\n    }\n\n    Statement getRelatedLabeled()\n    {\n        return this;\n    }\n\n    /****************************\n     * Determine if an enclosed `break` would apply to this\n     * statement, such as if it is a loop or switch statement.\n     * Returns:\n     *     `true` if it does\n     */\n    bool hasBreak()\n    {\n        //printf(\"Statement::hasBreak()\\n\");\n        return false;\n    }\n\n    /****************************\n     * Determine if an enclosed `continue` would apply to this\n     * statement, such as if it is a loop statement.\n     * Returns:\n     *     `true` if it does\n     */\n    bool hasContinue()\n    {\n        return false;\n    }\n\n    /**********************************\n     * Returns:\n     *     `true` if statement uses exception handling\n     */\n    final bool usesEH()\n    {\n        extern (C++) final class UsesEH : StoppableVisitor\n        {\n            alias visit = typeof(super).visit;\n        public:\n            override void visit(Statement s)\n            {\n            }\n\n            override void visit(TryCatchStatement s)\n            {\n                stop = true;\n            }\n\n            override void visit(TryFinallyStatement s)\n            {\n                stop = true;\n            }\n\n            override void visit(OnScopeStatement s)\n            {\n                stop = true;\n            }\n\n            override void visit(SynchronizedStatement s)\n            {\n                stop = true;\n            }\n        }\n\n        scope UsesEH ueh = new UsesEH();\n        return walkPostorder(this, ueh);\n    }\n\n    /**********************************\n     * Returns:\n     *   `true` if statement 'comes from' somewhere else, like a goto\n     */\n    final bool comeFrom()\n    {\n        extern (C++) final class ComeFrom : StoppableVisitor\n        {\n            alias visit = typeof(super).visit;\n        public:\n            override void visit(Statement s)\n            {\n            }\n\n            override void visit(CaseStatement s)\n            {\n                stop = true;\n            }\n\n            override void visit(DefaultStatement s)\n            {\n                stop = true;\n            }\n\n            override void visit(LabelStatement s)\n            {\n                stop = true;\n            }\n\n            override void visit(AsmStatement s)\n            {\n                stop = true;\n            }\n        }\n\n        scope ComeFrom cf = new ComeFrom();\n        return walkPostorder(this, cf);\n    }\n\n    /**********************************\n     * Returns:\n     *   `true` if statement has executable code.\n     */\n    final bool hasCode()\n    {\n        extern (C++) final class HasCode : StoppableVisitor\n        {\n            alias visit = typeof(super).visit;\n        public:\n            override void visit(Statement s)\n            {\n                stop = true;\n            }\n\n            override void visit(ExpStatement s)\n            {\n                if (s.exp !is null)\n                {\n                    stop = s.exp.hasCode();\n                }\n            }\n\n            override void visit(CompoundStatement s)\n            {\n            }\n\n            override void visit(ScopeStatement s)\n            {\n            }\n\n            override void visit(ImportStatement s)\n            {\n            }\n        }\n\n        scope HasCode hc = new HasCode();\n        return walkPostorder(this, hc);\n    }\n\n    /****************************************\n     * If this statement has code that needs to run in a finally clause\n     * at the end of the current scope, return that code in the form of\n     * a Statement.\n     * Params:\n     *     sc = context\n     *     sentry     = set to code executed upon entry to the scope\n     *     sexception = set to code executed upon exit from the scope via exception\n     *     sfinally   = set to code executed in finally block\n     * Returns:\n     *    code to be run in the finally clause\n     */\n    Statement scopeCode(Scope* sc, Statement* sentry, Statement* sexception, Statement* sfinally)\n    {\n        //printf(\"Statement::scopeCode()\\n\");\n        *sentry = null;\n        *sexception = null;\n        *sfinally = null;\n        return this;\n    }\n\n    /*********************************\n     * Flatten out the scope by presenting the statement\n     * as an array of statements.\n     * Params:\n     *     sc = context\n     * Returns:\n     *     The array of `Statements`, or `null` if no flattening necessary\n     */\n    Statements* flatten(Scope* sc)\n    {\n        return null;\n    }\n\n    /*******************************\n     * Find last statement in a sequence of statements.\n     * Returns:\n     *  the last statement, or `null` if there isn't one\n     */\n    inout(Statement) last() inout nothrow pure\n    {\n        return this;\n    }\n\n    /********************\n     * A cheaper method of doing downcasting of Statements.\n     * Returns:\n     *    the downcast statement if it can be downcasted, otherwise `null`\n     */\n    ErrorStatement isErrorStatement()\n    {\n        return null;\n    }\n\n    /// ditto\n    inout(ScopeStatement) isScopeStatement() inout nothrow pure\n    {\n        return null;\n    }\n\n    /// ditto\n    ExpStatement isExpStatement()\n    {\n        return null;\n    }\n\n    /// ditto\n    inout(CompoundStatement) isCompoundStatement() inout nothrow pure\n    {\n        return null;\n    }\n\n    /// ditto\n    inout(ReturnStatement) isReturnStatement() inout nothrow pure\n    {\n        return null;\n    }\n\n    /// ditto\n    IfStatement isIfStatement()\n    {\n        return null;\n    }\n\n    /// ditto\n    CaseStatement isCaseStatement()\n    {\n        return null;\n    }\n\n    /// ditto\n    DefaultStatement isDefaultStatement()\n    {\n        return null;\n    }\n\n    /// ditto\n    LabelStatement isLabelStatement()\n    {\n        return null;\n    }\n\n    /// ditto\n    GotoDefaultStatement isGotoDefaultStatement() pure\n    {\n        return null;\n    }\n\n    /// ditto\n    GotoCaseStatement isGotoCaseStatement() pure\n    {\n        return null;\n    }\n\n    /// ditto\n    inout(BreakStatement) isBreakStatement() inout nothrow pure\n    {\n        return null;\n    }\n\n    /// ditto\n    DtorExpStatement isDtorExpStatement()\n    {\n        return null;\n    }\n\n    /// ditto\n    ForwardingStatement isForwardingStatement()\n    {\n        return null;\n    }\n\n    /**************************\n     * Support Visitor Pattern\n     * Params:\n     *  v = visitor\n     */\n    void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Any Statement that fails semantic() or has a component that is an ErrorExp or\n * a TypeError should return an ErrorStatement from semantic().\n */\nextern (C++) final class ErrorStatement : Statement\n{\n    extern (D) this()\n    {\n        super(Loc.initial);\n        assert(global.gaggedErrors || global.errors);\n    }\n\n    override Statement syntaxCopy()\n    {\n        return this;\n    }\n\n    override ErrorStatement isErrorStatement()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class PeelStatement : Statement\n{\n    Statement s;\n\n    extern (D) this(Statement s)\n    {\n        super(s.loc);\n        this.s = s;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Convert TemplateMixin members (== Dsymbols) to Statements.\n */\nprivate Statement toStatement(Dsymbol s)\n{\n    extern (C++) final class ToStmt : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        Statement result;\n\n        Statement visitMembers(Loc loc, Dsymbols* a)\n        {\n            if (!a)\n                return null;\n\n            auto statements = new Statements();\n            foreach (s; *a)\n            {\n                statements.push(toStatement(s));\n            }\n            return new CompoundStatement(loc, statements);\n        }\n\n        override void visit(Dsymbol s)\n        {\n            .error(Loc.initial, \"Internal Compiler Error: cannot mixin %s `%s`\\n\", s.kind(), s.toChars());\n            result = new ErrorStatement();\n        }\n\n        override void visit(TemplateMixin tm)\n        {\n            auto a = new Statements();\n            foreach (m; *tm.members)\n            {\n                Statement s = toStatement(m);\n                if (s)\n                    a.push(s);\n            }\n            result = new CompoundStatement(tm.loc, a);\n        }\n\n        /* An actual declaration symbol will be converted to DeclarationExp\n         * with ExpStatement.\n         */\n        Statement declStmt(Dsymbol s)\n        {\n            auto de = new DeclarationExp(s.loc, s);\n            de.type = Type.tvoid; // avoid repeated semantic\n            return new ExpStatement(s.loc, de);\n        }\n\n        override void visit(VarDeclaration d)\n        {\n            result = declStmt(d);\n        }\n\n        override void visit(AggregateDeclaration d)\n        {\n            result = declStmt(d);\n        }\n\n        override void visit(FuncDeclaration d)\n        {\n            result = declStmt(d);\n        }\n\n        override void visit(EnumDeclaration d)\n        {\n            result = declStmt(d);\n        }\n\n        override void visit(AliasDeclaration d)\n        {\n            result = declStmt(d);\n        }\n\n        override void visit(TemplateDeclaration d)\n        {\n            result = declStmt(d);\n        }\n\n        /* All attributes have been already picked by the semantic analysis of\n         * 'bottom' declarations (function, struct, class, etc).\n         * So we don't have to copy them.\n         */\n        override void visit(StorageClassDeclaration d)\n        {\n            result = visitMembers(d.loc, d.decl);\n        }\n\n        override void visit(DeprecatedDeclaration d)\n        {\n            result = visitMembers(d.loc, d.decl);\n        }\n\n        override void visit(LinkDeclaration d)\n        {\n            result = visitMembers(d.loc, d.decl);\n        }\n\n        override void visit(ProtDeclaration d)\n        {\n            result = visitMembers(d.loc, d.decl);\n        }\n\n        override void visit(AlignDeclaration d)\n        {\n            result = visitMembers(d.loc, d.decl);\n        }\n\n        override void visit(UserAttributeDeclaration d)\n        {\n            result = visitMembers(d.loc, d.decl);\n        }\n\n        override void visit(StaticAssert s)\n        {\n        }\n\n        override void visit(Import s)\n        {\n        }\n\n        override void visit(PragmaDeclaration d)\n        {\n        }\n\n        override void visit(ConditionalDeclaration d)\n        {\n            result = visitMembers(d.loc, d.include(null));\n        }\n\n        override void visit(StaticForeachDeclaration d)\n        {\n            assert(d.sfe && !!d.sfe.aggrfe ^ !!d.sfe.rangefe);\n            (d.sfe.aggrfe ? d.sfe.aggrfe._body : d.sfe.rangefe._body) = visitMembers(d.loc, d.decl);\n            result = new StaticForeachStatement(d.loc, d.sfe);\n        }\n\n        override void visit(CompileDeclaration d)\n        {\n            result = visitMembers(d.loc, d.include(null));\n        }\n    }\n\n    if (!s)\n        return null;\n\n    scope ToStmt v = new ToStmt();\n    s.accept(v);\n    return v.result;\n}\n\n/***********************************************************\n */\nextern (C++) class ExpStatement : Statement\n{\n    Expression exp;\n\n    final extern (D) this(const ref Loc loc, Expression exp)\n    {\n        super(loc);\n        this.exp = exp;\n    }\n\n    final extern (D) this(const ref Loc loc, Dsymbol declaration)\n    {\n        super(loc);\n        this.exp = new DeclarationExp(loc, declaration);\n    }\n\n    static ExpStatement create(Loc loc, Expression exp)\n    {\n        return new ExpStatement(loc, exp);\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new ExpStatement(loc, exp ? exp.syntaxCopy() : null);\n    }\n\n    override final Statement scopeCode(Scope* sc, Statement* sentry, Statement* sexception, Statement* sfinally)\n    {\n        //printf(\"ExpStatement::scopeCode()\\n\");\n\n        *sentry = null;\n        *sexception = null;\n        *sfinally = null;\n\n        if (exp && exp.op == TOK.declaration)\n        {\n            auto de = cast(DeclarationExp)exp;\n            auto v = de.declaration.isVarDeclaration();\n            if (v && !v.isDataseg())\n            {\n                if (v.needsScopeDtor())\n                {\n                    *sfinally = new DtorExpStatement(loc, v.edtor, v);\n                    v.storage_class |= STC.nodtor; // don't add in dtor again\n                }\n            }\n        }\n        return this;\n    }\n\n    override final Statements* flatten(Scope* sc)\n    {\n        /* https://issues.dlang.org/show_bug.cgi?id=14243\n         * expand template mixin in statement scope\n         * to handle variable destructors.\n         */\n        if (exp && exp.op == TOK.declaration)\n        {\n            Dsymbol d = (cast(DeclarationExp)exp).declaration;\n            if (TemplateMixin tm = d.isTemplateMixin())\n            {\n                Expression e = exp.expressionSemantic(sc);\n                if (e.op == TOK.error || tm.errors)\n                {\n                    auto a = new Statements();\n                    a.push(new ErrorStatement());\n                    return a;\n                }\n                assert(tm.members);\n\n                Statement s = toStatement(tm);\n                version (none)\n                {\n                    OutBuffer buf;\n                    buf.doindent = 1;\n                    HdrGenState hgs;\n                    hgs.hdrgen = true;\n                    toCBuffer(s, &buf, &hgs);\n                    printf(\"tm ==> s = %s\\n\", buf.peekString());\n                }\n                auto a = new Statements();\n                a.push(s);\n                return a;\n            }\n        }\n        return null;\n    }\n\n    override final ExpStatement isExpStatement()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DtorExpStatement : ExpStatement\n{\n    // Wraps an expression that is the destruction of 'var'\n    VarDeclaration var;\n\n    extern (D) this(const ref Loc loc, Expression exp, VarDeclaration v)\n    {\n        super(loc, exp);\n        this.var = v;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new DtorExpStatement(loc, exp ? exp.syntaxCopy() : null, var);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n\n    override DtorExpStatement isDtorExpStatement()\n    {\n        return this;\n    }\n}\n\n/***********************************************************\n * https://dlang.org/spec/statement.html#mixin-statement\n */\nextern (C++) final class CompileStatement : Statement\n{\n    Expressions* exps;\n\n    extern (D) this(const ref Loc loc, Expression exp)\n    {\n        Expressions* exps = new Expressions();\n        exps.push(exp);\n        this(loc, exps);\n    }\n\n    extern (D) this(const ref Loc loc, Expressions* exps)\n    {\n        super(loc);\n        this.exps = exps;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new CompileStatement(loc, Expression.arraySyntaxCopy(exps));\n    }\n\n    private Statements* compileIt(Scope* sc)\n    {\n        //printf(\"CompileStatement::compileIt() %s\\n\", exp.toChars());\n\n        auto errorStatements()\n        {\n            auto a = new Statements();\n            a.push(new ErrorStatement());\n            return a;\n        }\n\n\n        OutBuffer buf;\n        if (exps)\n        {\n            foreach (ex; *exps)\n            {\n                sc = sc.startCTFE();\n                auto e = ex.expressionSemantic(sc);\n                e = resolveProperties(sc, e);\n                sc = sc.endCTFE();\n\n                // allowed to contain types as well as expressions\n                e = ctfeInterpretForPragmaMsg(e);\n                if (e.op == TOK.error)\n                {\n                    //errorSupplemental(exp.loc, \"while evaluating `mixin(%s)`\", ex.toChars());\n                    return errorStatements();\n                }\n                StringExp se = e.toStringExp();\n                if (se)\n                {\n                    se = se.toUTF8(sc);\n                    buf.printf(\"%.*s\", cast(int)se.len, se.string);\n                }\n                else\n                    buf.printf(\"%s\", e.toChars());\n            }\n        }\n\n        const errors = global.errors;\n        const len = buf.offset;\n        const str = buf.extractString()[0 .. len];\n        scope p = new Parser!ASTCodegen(loc, sc._module, str, false);\n        p.nextToken();\n\n        auto a = new Statements();\n        while (p.token.value != TOK.endOfFile)\n        {\n            Statement s = p.parseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope);\n            if (!s || p.errors)\n            {\n                assert(!p.errors || global.errors != errors); // make sure we caught all the cases\n                return errorStatements();\n            }\n            a.push(s);\n        }\n        return a;\n    }\n\n    override Statements* flatten(Scope* sc)\n    {\n        //printf(\"CompileStatement::flatten() %s\\n\", exp.toChars());\n        return compileIt(sc);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class CompoundStatement : Statement\n{\n    Statements* statements;\n\n    /**\n     * Construct a `CompoundStatement` using an already existing\n     * array of `Statement`s\n     *\n     * Params:\n     *   loc = Instantiation information\n     *   s   = An array of `Statement`s, that will referenced by this class\n     */\n    final extern (D) this(const ref Loc loc, Statements* s)\n    {\n        super(loc);\n        statements = s;\n    }\n\n    /**\n     * Construct a `CompoundStatement` from an array of `Statement`s\n     *\n     * Params:\n     *   loc = Instantiation information\n     *   sts   = A variadic array of `Statement`s, that will copied in this class\n     *         The entries themselves will not be copied.\n     */\n    final extern (D) this(const ref Loc loc, Statement[] sts...)\n    {\n        super(loc);\n        statements = new Statements();\n        statements.reserve(sts.length);\n        foreach (s; sts)\n            statements.push(s);\n    }\n\n    static CompoundStatement create(Loc loc, Statement s1, Statement s2)\n    {\n        return new CompoundStatement(loc, s1, s2);\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new CompoundStatement(loc, Statement.arraySyntaxCopy(statements));\n    }\n\n    override Statements* flatten(Scope* sc)\n    {\n        return statements;\n    }\n\n    override final inout(ReturnStatement) isReturnStatement() inout nothrow pure\n    {\n        ReturnStatement rs = null;\n        foreach (s; *statements)\n        {\n            if (s)\n            {\n                rs = cast(ReturnStatement)s.isReturnStatement();\n                if (rs)\n                    break;\n            }\n        }\n        return cast(inout)rs;\n    }\n\n    override final inout(Statement) last() inout nothrow pure\n    {\n        Statement s = null;\n        for (size_t i = statements.dim; i; --i)\n        {\n            s = cast(Statement)(*statements)[i - 1];\n            if (s)\n            {\n                s = cast(Statement)s.last();\n                if (s)\n                    break;\n            }\n        }\n        return cast(inout)s;\n    }\n\n    override final inout(CompoundStatement) isCompoundStatement() inout nothrow pure\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class CompoundDeclarationStatement : CompoundStatement\n{\n    extern (D) this(const ref Loc loc, Statements* s)\n    {\n        super(loc, s);\n        statements = s;\n    }\n\n    override Statement syntaxCopy()\n    {\n        auto a = new Statements(statements.dim);\n        foreach (i, s; *statements)\n        {\n            (*a)[i] = s ? s.syntaxCopy() : null;\n        }\n        return new CompoundDeclarationStatement(loc, a);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * The purpose of this is so that continue will go to the next\n * of the statements, and break will go to the end of the statements.\n */\nextern (C++) final class UnrolledLoopStatement : Statement\n{\n    Statements* statements;\n\n    extern (D) this(const ref Loc loc, Statements* s)\n    {\n        super(loc);\n        statements = s;\n    }\n\n    override Statement syntaxCopy()\n    {\n        auto a = new Statements(statements.dim);\n        foreach (i, s; *statements)\n        {\n            (*a)[i] = s ? s.syntaxCopy() : null;\n        }\n        return new UnrolledLoopStatement(loc, a);\n    }\n\n    override bool hasBreak()\n    {\n        return true;\n    }\n\n    override bool hasContinue()\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class ScopeStatement : Statement\n{\n    Statement statement;\n    Loc endloc;                 // location of closing curly bracket\n\n    extern (D) this(const ref Loc loc, Statement s, Loc endloc)\n    {\n        super(loc);\n        this.statement = s;\n        this.endloc = endloc;\n    }\n    override Statement syntaxCopy()\n    {\n        return new ScopeStatement(loc, statement ? statement.syntaxCopy() : null, endloc);\n    }\n\n    override inout(ScopeStatement) isScopeStatement() inout nothrow pure\n    {\n        return this;\n    }\n\n    override inout(ReturnStatement) isReturnStatement() inout nothrow pure\n    {\n        if (statement)\n            return statement.isReturnStatement();\n        return null;\n    }\n\n    override bool hasBreak()\n    {\n        //printf(\"ScopeStatement::hasBreak() %s\\n\", toChars());\n        return statement ? statement.hasBreak() : false;\n    }\n\n    override bool hasContinue()\n    {\n        return statement ? statement.hasContinue() : false;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Statement whose symbol table contains foreach index variables in a\n * local scope and forwards other members to the parent scope.  This\n * wraps a statement.\n *\n * Also see: `dmd.attrib.ForwardingAttribDeclaration`\n */\nextern (C++) final class ForwardingStatement : Statement\n{\n    /// The symbol containing the `static foreach` variables.\n    ForwardingScopeDsymbol sym = null;\n    /// The wrapped statement.\n    Statement statement;\n\n    extern (D) this(const ref Loc loc, ForwardingScopeDsymbol sym, Statement s)\n    {\n        super(loc);\n        this.sym = sym;\n        assert(s);\n        statement = s;\n    }\n\n    extern (D) this(const ref Loc loc, Statement s)\n    {\n        auto sym = new ForwardingScopeDsymbol(null);\n        sym.symtab = new DsymbolTable();\n        this(loc, sym, s);\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new ForwardingStatement(loc, statement.syntaxCopy());\n    }\n\n    /***********************\n     * ForwardingStatements are distributed over the flattened\n     * sequence of statements. This prevents flattening to be\n     * \"blocked\" by a ForwardingStatement and is necessary, for\n     * example, to support generating scope guards with `static\n     * foreach`:\n     *\n     *     static foreach(i; 0 .. 10) scope(exit) writeln(i);\n     *     writeln(\"this is printed first\");\n     *     // then, it prints 10, 9, 8, 7, ...\n     */\n\n    override Statements* flatten(Scope* sc)\n    {\n        if (!statement)\n        {\n            return null;\n        }\n        sc = sc.push(sym);\n        auto a = statement.flatten(sc);\n        sc = sc.pop();\n        if (!a)\n        {\n            return a;\n        }\n        auto b = new Statements(a.dim);\n        foreach (i, s; *a)\n        {\n            (*b)[i] = s ? new ForwardingStatement(s.loc, sym, s) : null;\n        }\n        return b;\n    }\n\n    override ForwardingStatement isForwardingStatement()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n\n/***********************************************************\n */\nextern (C++) final class WhileStatement : Statement\n{\n    Expression condition;\n    Statement _body;\n    Loc endloc;             // location of closing curly bracket\n\n    extern (D) this(const ref Loc loc, Expression c, Statement b, Loc endloc)\n    {\n        super(loc);\n        condition = c;\n        _body = b;\n        this.endloc = endloc;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new WhileStatement(loc,\n            condition.syntaxCopy(),\n            _body ? _body.syntaxCopy() : null,\n            endloc);\n    }\n\n    override bool hasBreak()\n    {\n        return true;\n    }\n\n    override bool hasContinue()\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DoStatement : Statement\n{\n    Statement _body;\n    Expression condition;\n    Loc endloc;                 // location of ';' after while\n\n    extern (D) this(const ref Loc loc, Statement b, Expression c, Loc endloc)\n    {\n        super(loc);\n        _body = b;\n        condition = c;\n        this.endloc = endloc;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new DoStatement(loc,\n            _body ? _body.syntaxCopy() : null,\n            condition.syntaxCopy(),\n            endloc);\n    }\n\n    override bool hasBreak()\n    {\n        return true;\n    }\n\n    override bool hasContinue()\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ForStatement : Statement\n{\n    Statement _init;\n    Expression condition;\n    Expression increment;\n    Statement _body;\n    Loc endloc;             // location of closing curly bracket\n\n    // When wrapped in try/finally clauses, this points to the outermost one,\n    // which may have an associated label. Internal break/continue statements\n    // treat that label as referring to this loop.\n    Statement relatedLabeled;\n\n    extern (D) this(const ref Loc loc, Statement _init, Expression condition, Expression increment, Statement _body, Loc endloc)\n    {\n        super(loc);\n        this._init = _init;\n        this.condition = condition;\n        this.increment = increment;\n        this._body = _body;\n        this.endloc = endloc;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new ForStatement(loc,\n            _init ? _init.syntaxCopy() : null,\n            condition ? condition.syntaxCopy() : null,\n            increment ? increment.syntaxCopy() : null,\n            _body.syntaxCopy(),\n            endloc);\n    }\n\n    override Statement scopeCode(Scope* sc, Statement* sentry, Statement* sexception, Statement* sfinally)\n    {\n        //printf(\"ForStatement::scopeCode()\\n\");\n        Statement.scopeCode(sc, sentry, sexception, sfinally);\n        return this;\n    }\n\n    override Statement getRelatedLabeled()\n    {\n        return relatedLabeled ? relatedLabeled : this;\n    }\n\n    override bool hasBreak()\n    {\n        //printf(\"ForStatement::hasBreak()\\n\");\n        return true;\n    }\n\n    override bool hasContinue()\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * https://dlang.org/spec/statement.html#foreach-statement\n */\nextern (C++) final class ForeachStatement : Statement\n{\n    TOK op;                     // TOK.foreach_ or TOK.foreach_reverse_\n    Parameters* parameters;     // array of Parameters, one for each ForeachType\n    Expression aggr;            // ForeachAggregate\n    Statement _body;            // NoScopeNonEmptyStatement\n    Loc endloc;                 // location of closing curly bracket\n\n    VarDeclaration key;\n    VarDeclaration value;\n\n    FuncDeclaration func;       // function we're lexically in\n\n    Statements* cases;          // put breaks, continues, gotos and returns here\n    ScopeStatements* gotos;     // forward referenced goto's go here\n\n    extern (D) this(const ref Loc loc, TOK op, Parameters* parameters, Expression aggr, Statement _body, Loc endloc)\n    {\n        super(loc);\n        this.op = op;\n        this.parameters = parameters;\n        this.aggr = aggr;\n        this._body = _body;\n        this.endloc = endloc;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new ForeachStatement(loc, op,\n            Parameter.arraySyntaxCopy(parameters),\n            aggr.syntaxCopy(),\n            _body ? _body.syntaxCopy() : null,\n            endloc);\n    }\n\n    override bool hasBreak()\n    {\n        return true;\n    }\n\n    override bool hasContinue()\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ForeachRangeStatement : Statement\n{\n    TOK op;                 // TOK.foreach_ or TOK.foreach_reverse_\n    Parameter prm;          // loop index variable\n    Expression lwr;\n    Expression upr;\n    Statement _body;\n    Loc endloc;             // location of closing curly bracket\n\n    VarDeclaration key;\n\n    extern (D) this(const ref Loc loc, TOK op, Parameter prm, Expression lwr, Expression upr, Statement _body, Loc endloc)\n    {\n        super(loc);\n        this.op = op;\n        this.prm = prm;\n        this.lwr = lwr;\n        this.upr = upr;\n        this._body = _body;\n        this.endloc = endloc;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new ForeachRangeStatement(loc, op, prm.syntaxCopy(), lwr.syntaxCopy(), upr.syntaxCopy(), _body ? _body.syntaxCopy() : null, endloc);\n    }\n\n    override bool hasBreak()\n    {\n        return true;\n    }\n\n    override bool hasContinue()\n    {\n        return true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class IfStatement : Statement\n{\n    Parameter prm;\n    Expression condition;\n    Statement ifbody;\n    Statement elsebody;\n    VarDeclaration match;   // for MatchExpression results\n    Loc endloc;                 // location of closing curly bracket\n\n    extern (D) this(const ref Loc loc, Parameter prm, Expression condition, Statement ifbody, Statement elsebody, Loc endloc)\n    {\n        super(loc);\n        this.prm = prm;\n        this.condition = condition;\n        this.ifbody = ifbody;\n        this.elsebody = elsebody;\n        this.endloc = endloc;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new IfStatement(loc,\n            prm ? prm.syntaxCopy() : null,\n            condition.syntaxCopy(),\n            ifbody ? ifbody.syntaxCopy() : null,\n            elsebody ? elsebody.syntaxCopy() : null,\n            endloc);\n    }\n\n    override IfStatement isIfStatement()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ConditionalStatement : Statement\n{\n    Condition condition;\n    Statement ifbody;\n    Statement elsebody;\n\n    extern (D) this(const ref Loc loc, Condition condition, Statement ifbody, Statement elsebody)\n    {\n        super(loc);\n        this.condition = condition;\n        this.ifbody = ifbody;\n        this.elsebody = elsebody;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new ConditionalStatement(loc, condition.syntaxCopy(), ifbody.syntaxCopy(), elsebody ? elsebody.syntaxCopy() : null);\n    }\n\n    override Statements* flatten(Scope* sc)\n    {\n        Statement s;\n\n        //printf(\"ConditionalStatement::flatten()\\n\");\n        if (condition.include(sc))\n        {\n            DebugCondition dc = condition.isDebugCondition();\n            if (dc)\n                s = new DebugStatement(loc, ifbody);\n            else\n                s = ifbody;\n        }\n        else\n            s = elsebody;\n\n        auto a = new Statements();\n        a.push(s);\n        return a;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * Static foreach statements, like:\n *      void main()\n *      {\n *           static foreach(i; 0 .. 10)\n *           {\n *               pragma(msg, i);\n *           }\n *      }\n */\nextern (C++) final class StaticForeachStatement : Statement\n{\n    StaticForeach sfe;\n\n    extern (D) this(const ref Loc loc, StaticForeach sfe)\n    {\n        super(loc);\n        this.sfe = sfe;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new StaticForeachStatement(loc,sfe.syntaxCopy());\n    }\n\n    override Statements* flatten(Scope* sc)\n    {\n        sfe.prepare(sc);\n        if (sfe.ready())\n        {\n            import dmd.statementsem;\n            auto s = makeTupleForeach!(true,false)(sc, sfe.aggrfe,sfe.needExpansion);\n            auto result = s.flatten(sc);\n            if (result)\n            {\n                return result;\n            }\n            result = new Statements();\n            result.push(s);\n            return result;\n        }\n        else\n        {\n            auto result = new Statements();\n            result.push(new ErrorStatement());\n            return result;\n        }\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class PragmaStatement : Statement\n{\n    Identifier ident;\n    Expressions* args;      // array of Expression's\n    Statement _body;\n\n    extern (D) this(const ref Loc loc, Identifier ident, Expressions* args, Statement _body)\n    {\n        super(loc);\n        this.ident = ident;\n        this.args = args;\n        this._body = _body;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new PragmaStatement(loc, ident, Expression.arraySyntaxCopy(args), _body ? _body.syntaxCopy() : null);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class StaticAssertStatement : Statement\n{\n    StaticAssert sa;\n\n    extern (D) this(StaticAssert sa)\n    {\n        super(sa.loc);\n        this.sa = sa;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new StaticAssertStatement(cast(StaticAssert)sa.syntaxCopy(null));\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class SwitchStatement : Statement\n{\n    Expression condition;           /// switch(condition)\n    Statement _body;                ///\n    bool isFinal;                   ///\n\n    DefaultStatement sdefault;      /// default:\n    TryFinallyStatement tf;         ///\n    GotoCaseStatements gotoCases;   /// array of unresolved GotoCaseStatement's\n    CaseStatements* cases;          /// array of CaseStatement's\n    int hasNoDefault;               /// !=0 if no default statement\n    int hasVars;                    /// !=0 if has variable case values\n    VarDeclaration lastVar;         /// last observed variable declaration in this statement\n\n    extern (D) this(const ref Loc loc, Expression c, Statement b, bool isFinal)\n    {\n        super(loc);\n        this.condition = c;\n        this._body = b;\n        this.isFinal = isFinal;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new SwitchStatement(loc, condition.syntaxCopy(), _body.syntaxCopy(), isFinal);\n    }\n\n    override bool hasBreak()\n    {\n        return true;\n    }\n\n    /************************************\n     * Returns:\n     *  true if error\n     */\n    extern (D) bool checkLabel()\n    {\n        /*\n         * Checks the scope of a label for existing variable declaration.\n         * Params:\n         *   vd = last variable declared before this case/default label\n         * Returns: `true` if the variables declared in this label would be skipped.\n         */\n        bool checkVar(VarDeclaration vd)\n        {\n            for (auto v = vd; v && v != lastVar; v = v.lastVar)\n            {\n                if (v.isDataseg() || (v.storage_class & (STC.manifest | STC.temp)) || v._init.isVoidInitializer())\n                    continue;\n                if (vd.ident == Id.withSym)\n                    error(\"`switch` skips declaration of `with` temporary at %s\", v.loc.toChars());\n                else\n                    error(\"`switch` skips declaration of variable `%s` at %s\", v.toPrettyChars(), v.loc.toChars());\n                return true;\n            }\n            return false;\n        }\n\n        enum error = true;\n\n        if (sdefault && checkVar(sdefault.lastVar))\n            return !error; // return error once fully deprecated\n\n        foreach (scase; *cases)\n        {\n            if (scase && checkVar(scase.lastVar))\n                return !error; // return error once fully deprecated\n        }\n        return !error;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class CaseStatement : Statement\n{\n    Expression exp;\n    Statement statement;\n    int index;              // which case it is (since we sort this)\n    VarDeclaration lastVar;\n\n    extern (D) this(const ref Loc loc, Expression exp, Statement s)\n    {\n        super(loc);\n        this.exp = exp;\n        this.statement = s;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new CaseStatement(loc, exp.syntaxCopy(), statement.syntaxCopy());\n    }\n\n    override int compare(RootObject obj)\n    {\n        // Sort cases so we can do an efficient lookup\n        CaseStatement cs2 = cast(CaseStatement)obj;\n        return exp.compare(cs2.exp);\n    }\n\n    override CaseStatement isCaseStatement()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class CaseRangeStatement : Statement\n{\n    Expression first;\n    Expression last;\n    Statement statement;\n\n    extern (D) this(const ref Loc loc, Expression first, Expression last, Statement s)\n    {\n        super(loc);\n        this.first = first;\n        this.last = last;\n        this.statement = s;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new CaseRangeStatement(loc, first.syntaxCopy(), last.syntaxCopy(), statement.syntaxCopy());\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DefaultStatement : Statement\n{\n    Statement statement;\n    VarDeclaration lastVar;\n\n    extern (D) this(const ref Loc loc, Statement s)\n    {\n        super(loc);\n        this.statement = s;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new DefaultStatement(loc, statement.syntaxCopy());\n    }\n\n    override DefaultStatement isDefaultStatement()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class GotoDefaultStatement : Statement\n{\n    SwitchStatement sw;\n\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc);\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new GotoDefaultStatement(loc);\n    }\n\n    override GotoDefaultStatement isGotoDefaultStatement() pure\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class GotoCaseStatement : Statement\n{\n    Expression exp;     // null, or which case to goto\n    CaseStatement cs;   // case statement it resolves to\n\n    extern (D) this(const ref Loc loc, Expression exp)\n    {\n        super(loc);\n        this.exp = exp;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new GotoCaseStatement(loc, exp ? exp.syntaxCopy() : null);\n    }\n\n    override GotoCaseStatement isGotoCaseStatement() pure\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class SwitchErrorStatement : Statement\n{\n    Expression exp;\n\n    extern (D) this(const ref Loc loc)\n    {\n        super(loc);\n    }\n\n    final extern (D) this(const ref Loc loc, Expression exp)\n    {\n        super(loc);\n        this.exp = exp;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ReturnStatement : Statement\n{\n    Expression exp;\n    size_t caseDim;\n\n    extern (D) this(const ref Loc loc, Expression exp)\n    {\n        super(loc);\n        this.exp = exp;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new ReturnStatement(loc, exp ? exp.syntaxCopy() : null);\n    }\n\n    override inout(ReturnStatement) isReturnStatement() inout nothrow pure\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class BreakStatement : Statement\n{\n    Identifier ident;\n\n    extern (D) this(const ref Loc loc, Identifier ident)\n    {\n        super(loc);\n        this.ident = ident;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new BreakStatement(loc, ident);\n    }\n\n    override inout(BreakStatement) isBreakStatement() inout nothrow pure\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ContinueStatement : Statement\n{\n    Identifier ident;\n\n    extern (D) this(const ref Loc loc, Identifier ident)\n    {\n        super(loc);\n        this.ident = ident;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new ContinueStatement(loc, ident);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class SynchronizedStatement : Statement\n{\n    Expression exp;\n    Statement _body;\n\n    extern (D) this(const ref Loc loc, Expression exp, Statement _body)\n    {\n        super(loc);\n        this.exp = exp;\n        this._body = _body;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new SynchronizedStatement(loc, exp ? exp.syntaxCopy() : null, _body ? _body.syntaxCopy() : null);\n    }\n\n    override bool hasBreak()\n    {\n        return false; //true;\n    }\n\n    override bool hasContinue()\n    {\n        return false; //true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class WithStatement : Statement\n{\n    Expression exp;\n    Statement _body;\n    VarDeclaration wthis;\n    Loc endloc;\n\n    extern (D) this(const ref Loc loc, Expression exp, Statement _body, Loc endloc)\n    {\n        super(loc);\n        this.exp = exp;\n        this._body = _body;\n        this.endloc = endloc;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new WithStatement(loc, exp.syntaxCopy(), _body ? _body.syntaxCopy() : null, endloc);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TryCatchStatement : Statement\n{\n    Statement _body;\n    Catches* catches;\n\n    extern (D) this(const ref Loc loc, Statement _body, Catches* catches)\n    {\n        super(loc);\n        this._body = _body;\n        this.catches = catches;\n    }\n\n    override Statement syntaxCopy()\n    {\n        auto a = new Catches(catches.dim);\n        foreach (i, c; *catches)\n        {\n            (*a)[i] = c.syntaxCopy();\n        }\n        return new TryCatchStatement(loc, _body.syntaxCopy(), a);\n    }\n\n    override bool hasBreak()\n    {\n        return false;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class Catch : RootObject\n{\n    Loc loc;\n    Type type;\n    Identifier ident;\n    VarDeclaration var;\n    Statement handler;\n\n    bool errors;                // set if semantic processing errors\n\n    // was generated by the compiler, wasn't present in source code\n    bool internalCatch;\n\n    extern (D) this(const ref Loc loc, Type t, Identifier id, Statement handler)\n    {\n        //printf(\"Catch(%s, loc = %s)\\n\", id.toChars(), loc.toChars());\n        this.loc = loc;\n        this.type = t;\n        this.ident = id;\n        this.handler = handler;\n    }\n\n    Catch syntaxCopy()\n    {\n        auto c = new Catch(loc, type ? type.syntaxCopy() : getThrowable(), ident, (handler ? handler.syntaxCopy() : null));\n        c.internalCatch = internalCatch;\n        return c;\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class TryFinallyStatement : Statement\n{\n    Statement _body;\n    Statement finalbody;\n\n    bool bodyFallsThru;         // true if _body falls through to finally\n\n    extern (D) this(const ref Loc loc, Statement _body, Statement finalbody)\n    {\n        super(loc);\n        this._body = _body;\n        this.finalbody = finalbody;\n        this.bodyFallsThru = true;      // assume true until statementSemantic()\n    }\n\n    static TryFinallyStatement create(Loc loc, Statement _body, Statement finalbody)\n    {\n        return new TryFinallyStatement(loc, _body, finalbody);\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new TryFinallyStatement(loc, _body.syntaxCopy(), finalbody.syntaxCopy());\n    }\n\n    override bool hasBreak()\n    {\n        return false; //true;\n    }\n\n    override bool hasContinue()\n    {\n        return false; //true;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class OnScopeStatement : Statement\n{\n    TOK tok;\n    Statement statement;\n\n    extern (D) this(const ref Loc loc, TOK tok, Statement statement)\n    {\n        super(loc);\n        this.tok = tok;\n        this.statement = statement;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new OnScopeStatement(loc, tok, statement.syntaxCopy());\n    }\n\n    override Statement scopeCode(Scope* sc, Statement* sentry, Statement* sexception, Statement* sfinally)\n    {\n        //printf(\"OnScopeStatement::scopeCode()\\n\");\n        *sentry = null;\n        *sexception = null;\n        *sfinally = null;\n\n        Statement s = new PeelStatement(statement);\n\n        switch (tok)\n        {\n        case TOK.onScopeExit:\n            *sfinally = s;\n            break;\n\n        case TOK.onScopeFailure:\n            *sexception = s;\n            break;\n\n        case TOK.onScopeSuccess:\n            {\n                /* Create:\n                 *  sentry:   bool x = false;\n                 *  sexception:    x = true;\n                 *  sfinally: if (!x) statement;\n                 */\n                auto v = copyToTemp(0, \"__os\", new IntegerExp(Loc.initial, 0, Type.tbool));\n                v.dsymbolSemantic(sc);\n                *sentry = new ExpStatement(loc, v);\n\n                Expression e = new IntegerExp(Loc.initial, 1, Type.tbool);\n                e = new AssignExp(Loc.initial, new VarExp(Loc.initial, v), e);\n                *sexception = new ExpStatement(Loc.initial, e);\n\n                e = new VarExp(Loc.initial, v);\n                e = new NotExp(Loc.initial, e);\n                *sfinally = new IfStatement(Loc.initial, null, e, s, null, Loc.initial);\n\n                break;\n            }\n        default:\n            assert(0);\n        }\n        return null;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ThrowStatement : Statement\n{\n    Expression exp;\n\n    // was generated by the compiler, wasn't present in source code\n    bool internalThrow;\n\n    extern (D) this(const ref Loc loc, Expression exp)\n    {\n        super(loc);\n        this.exp = exp;\n    }\n\n    override Statement syntaxCopy()\n    {\n        auto s = new ThrowStatement(loc, exp.syntaxCopy());\n        s.internalThrow = internalThrow;\n        return s;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class DebugStatement : Statement\n{\n    Statement statement;\n\n    extern (D) this(const ref Loc loc, Statement statement)\n    {\n        super(loc);\n        this.statement = statement;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new DebugStatement(loc, statement ? statement.syntaxCopy() : null);\n    }\n\n    override Statements* flatten(Scope* sc)\n    {\n        Statements* a = statement ? statement.flatten(sc) : null;\n        if (a)\n        {\n            foreach (ref s; *a)\n            {\n                s = new DebugStatement(loc, s);\n            }\n        }\n        return a;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class GotoStatement : Statement\n{\n    Identifier ident;\n    LabelDsymbol label;\n    TryFinallyStatement tf;\n    OnScopeStatement os;\n    VarDeclaration lastVar;\n\n    extern (D) this(const ref Loc loc, Identifier ident)\n    {\n        super(loc);\n        this.ident = ident;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new GotoStatement(loc, ident);\n    }\n\n    extern (D) bool checkLabel()\n    {\n        if (!label.statement)\n        {\n            error(\"label `%s` is undefined\", label.toChars());\n            return true;\n        }\n\n        if (label.statement.os != os)\n        {\n            if (os && os.tok == TOK.onScopeFailure && !label.statement.os)\n            {\n                // Jump out from scope(failure) block is allowed.\n            }\n            else\n            {\n                if (label.statement.os)\n                    error(\"cannot `goto` in to `%s` block\", Token.toChars(label.statement.os.tok));\n                else\n                    error(\"cannot `goto` out of `%s` block\", Token.toChars(os.tok));\n                return true;\n            }\n        }\n\n        if (label.statement.tf != tf)\n        {\n            error(\"cannot `goto` in or out of `finally` block\");\n            return true;\n        }\n\n        VarDeclaration vd = label.statement.lastVar;\n        if (!vd || vd.isDataseg() || (vd.storage_class & STC.manifest))\n            return false;\n\n        VarDeclaration last = lastVar;\n        while (last && last != vd)\n            last = last.lastVar;\n        if (last == vd)\n        {\n            // All good, the label's scope has no variables\n        }\n        else if (vd.storage_class & STC.exptemp)\n        {\n            // Lifetime ends at end of expression, so no issue with skipping the statement\n        }\n        else if (vd.ident == Id.withSym)\n        {\n            error(\"`goto` skips declaration of `with` temporary at %s\", vd.loc.toChars());\n            return true;\n        }\n        else\n        {\n            error(\"`goto` skips declaration of variable `%s` at %s\", vd.toPrettyChars(), vd.loc.toChars());\n            return true;\n        }\n\n        return false;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class LabelStatement : Statement\n{\n    Identifier ident;\n    Statement statement;\n    TryFinallyStatement tf;\n    OnScopeStatement os;\n    VarDeclaration lastVar;\n    Statement gotoTarget;       // interpret\n    bool breaks;                // someone did a 'break ident'\n\n    extern (D) this(const ref Loc loc, Identifier ident, Statement statement)\n    {\n        super(loc);\n        this.ident = ident;\n        this.statement = statement;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new LabelStatement(loc, ident, statement ? statement.syntaxCopy() : null);\n    }\n\n    override Statements* flatten(Scope* sc)\n    {\n        Statements* a = null;\n        if (statement)\n        {\n            a = statement.flatten(sc);\n            if (a)\n            {\n                if (!a.dim)\n                {\n                    a.push(new ExpStatement(loc, cast(Expression)null));\n                }\n\n                // reuse 'this' LabelStatement\n                this.statement = (*a)[0];\n                (*a)[0] = this;\n            }\n        }\n        return a;\n    }\n\n    override Statement scopeCode(Scope* sc, Statement* sentry, Statement* sexit, Statement* sfinally)\n    {\n        //printf(\"LabelStatement::scopeCode()\\n\");\n        if (statement)\n            statement = statement.scopeCode(sc, sentry, sexit, sfinally);\n        else\n        {\n            *sentry = null;\n            *sexit = null;\n            *sfinally = null;\n        }\n        return this;\n    }\n\n    override LabelStatement isLabelStatement()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class LabelDsymbol : Dsymbol\n{\n    LabelStatement statement;\n\n    extern (D) this(Identifier ident)\n    {\n        super(ident);\n    }\n\n    static LabelDsymbol create(Identifier ident)\n    {\n        return new LabelDsymbol(ident);\n    }\n\n    // is this a LabelDsymbol()?\n    override LabelDsymbol isLabel()\n    {\n        return this;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) class AsmStatement : Statement\n{\n    Token* tokens;\n\n    extern (D) this(const ref Loc loc, Token* tokens)\n    {\n        super(loc);\n        this.tokens = tokens;\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new AsmStatement(loc, tokens);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * https://dlang.org/spec/iasm.html\n */\nextern (C++) final class InlineAsmStatement : AsmStatement\n{\n    code* asmcode;\n    uint asmalign;  // alignment of this statement\n    uint regs;      // mask of registers modified (must match regm_t in back end)\n    bool refparam;  // true if function parameter is referenced\n    bool naked;     // true if function is to be naked\n\n    extern (D) this(const ref Loc loc, Token* tokens)\n    {\n        super(loc, tokens);\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new InlineAsmStatement(loc, tokens);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html\n * Assembler instructions with D expression operands.\n */\nextern (C++) final class GccAsmStatement : AsmStatement\n{\n    StorageClass stc;           // attributes of the asm {} block\n    Expression insn;            // string expression that is the template for assembler code\n    Expressions* args;          // input and output operands of the statement\n    uint outputargs;            // of the operands in 'args', the number of output operands\n    Identifiers* names;         // list of symbolic names for the operands\n    Expressions* constraints;   // list of string constants specifying constraints on operands\n    Expressions* clobbers;      // list of string constants specifying clobbers and scratch registers\n    Identifiers* labels;        // list of goto labels\n    GotoStatements* gotos;      // of the goto labels, the equivalent statements they represent\n\n    extern (D) this(const ref Loc loc, Token* tokens)\n    {\n        super(loc, tokens);\n    }\n\n    override Statement syntaxCopy()\n    {\n        return new GccAsmStatement(loc, tokens);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n * a complete asm {} block\n */\nextern (C++) final class CompoundAsmStatement : CompoundStatement\n{\n    StorageClass stc; // postfix attributes like nothrow/pure/@trusted\n\n    extern (D) this(const ref Loc loc, Statements* s, StorageClass stc)\n    {\n        super(loc, s);\n        this.stc = stc;\n    }\n\n    override CompoundAsmStatement syntaxCopy()\n    {\n        auto a = new Statements(statements.dim);\n        foreach (i, s; *statements)\n        {\n            (*a)[i] = s ? s.syntaxCopy() : null;\n        }\n        return new CompoundAsmStatement(loc, a, stc);\n    }\n\n    override Statements* flatten(Scope* sc)\n    {\n        return null;\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n\n/***********************************************************\n */\nextern (C++) final class ImportStatement : Statement\n{\n    Dsymbols* imports;      // Array of Import's\n\n    extern (D) this(const ref Loc loc, Dsymbols* imports)\n    {\n        super(loc);\n        this.imports = imports;\n    }\n\n    override Statement syntaxCopy()\n    {\n        auto m = new Dsymbols(imports.dim);\n        foreach (i, s; *imports)\n        {\n            (*m)[i] = s.syntaxCopy(null);\n        }\n        return new ImportStatement(loc, m);\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/statement.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/statement.h\n */\n\n#pragma once\n\n#include \"arraytypes.h\"\n#include \"dsymbol.h\"\n#include \"visitor.h\"\n#include \"tokens.h\"\n\nstruct Scope;\nclass Expression;\nclass LabelDsymbol;\nclass Identifier;\nclass IfStatement;\nclass ExpStatement;\nclass DefaultStatement;\nclass VarDeclaration;\nclass Condition;\nclass ErrorStatement;\nclass ReturnStatement;\nclass CompoundStatement;\nclass Parameter;\nclass StaticAssert;\nclass AsmStatement;\nclass GotoStatement;\nclass ScopeStatement;\nclass TryCatchStatement;\nclass TryFinallyStatement;\nclass CaseStatement;\nclass DefaultStatement;\nclass LabelStatement;\nclass StaticForeach;\n\n// Back end\nstruct code;\n\nbool inferAggregate(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply);\nbool inferApplyArgTypes(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply);\n\n/* How a statement exits; this is returned by blockExit()\n */\nenum BE\n{\n    BEnone =     0,\n    BEfallthru = 1,\n    BEthrow =    2,\n    BEreturn =   4,\n    BEgoto =     8,\n    BEhalt =     0x10,\n    BEbreak =    0x20,\n    BEcontinue = 0x40,\n    BEerrthrow = 0x80,\n    BEany = (BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt)\n};\n\nclass Statement : public RootObject\n{\npublic:\n    Loc loc;\n\n    virtual Statement *syntaxCopy();\n\n    const char *toChars();\n\n    void error(const char *format, ...);\n    void warning(const char *format, ...);\n    void deprecation(const char *format, ...);\n    virtual Statement *getRelatedLabeled() { return this; }\n    virtual bool hasBreak();\n    virtual bool hasContinue();\n    bool usesEH();\n    bool comeFrom();\n    bool hasCode();\n    virtual Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);\n    virtual Statements *flatten(Scope *sc);\n    virtual Statement *last();\n\n    // Avoid dynamic_cast\n    virtual ErrorStatement *isErrorStatement() { return NULL; }\n    virtual ScopeStatement *isScopeStatement() { return NULL; }\n    virtual ExpStatement *isExpStatement() { return NULL; }\n    virtual CompoundStatement *isCompoundStatement() { return NULL; }\n    virtual ReturnStatement *isReturnStatement() { return NULL; }\n    virtual IfStatement *isIfStatement() { return NULL; }\n    virtual CaseStatement *isCaseStatement() { return NULL; }\n    virtual DefaultStatement *isDefaultStatement() { return NULL; }\n    virtual LabelStatement *isLabelStatement() { return NULL; }\n    virtual GotoDefaultStatement *isGotoDefaultStatement() { return NULL; }\n    virtual GotoCaseStatement *isGotoCaseStatement() { return NULL; }\n    virtual BreakStatement *isBreakStatement() { return NULL; }\n    virtual DtorExpStatement *isDtorExpStatement() { return NULL; }\n    virtual ForwardingStatement *isForwardingStatement() { return NULL; }\n    virtual void accept(Visitor *v) { v->visit(this); }\n};\n\n/** Any Statement that fails semantic() or has a component that is an ErrorExp or\n * a TypeError should return an ErrorStatement from semantic().\n */\nclass ErrorStatement : public Statement\n{\npublic:\n    Statement *syntaxCopy();\n\n    ErrorStatement *isErrorStatement() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass PeelStatement : public Statement\n{\npublic:\n    Statement *s;\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ExpStatement : public Statement\n{\npublic:\n    Expression *exp;\n\n    static ExpStatement *create(Loc loc, Expression *exp);\n    Statement *syntaxCopy();\n    Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);\n    Statements *flatten(Scope *sc);\n\n    ExpStatement *isExpStatement() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DtorExpStatement : public ExpStatement\n{\npublic:\n    /* Wraps an expression that is the destruction of 'var'\n     */\n\n    VarDeclaration *var;\n\n    Statement *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n\n    DtorExpStatement *isDtorExpStatement() { return this; }\n};\n\nclass CompileStatement : public Statement\n{\npublic:\n    Expressions *exps;\n\n    Statement *syntaxCopy();\n    Statements *flatten(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass CompoundStatement : public Statement\n{\npublic:\n    Statements *statements;\n\n    static CompoundStatement *create(Loc loc, Statement *s1, Statement *s2);\n    Statement *syntaxCopy();\n    Statements *flatten(Scope *sc);\n    ReturnStatement *isReturnStatement();\n    Statement *last();\n\n    CompoundStatement *isCompoundStatement() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass CompoundDeclarationStatement : public CompoundStatement\n{\npublic:\n    Statement *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/* The purpose of this is so that continue will go to the next\n * of the statements, and break will go to the end of the statements.\n */\nclass UnrolledLoopStatement : public Statement\n{\npublic:\n    Statements *statements;\n\n    Statement *syntaxCopy();\n    bool hasBreak();\n    bool hasContinue();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ScopeStatement : public Statement\n{\npublic:\n    Statement *statement;\n    Loc endloc;                 // location of closing curly bracket\n\n    Statement *syntaxCopy();\n    ScopeStatement *isScopeStatement() { return this; }\n    ReturnStatement *isReturnStatement();\n    bool hasBreak();\n    bool hasContinue();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ForwardingStatement : public Statement\n{\n    ForwardingScopeDsymbol *sym;\n    Statement *statement;\n\n    Statement *syntaxCopy();\n    Statements *flatten(Scope *sc);\n    ForwardingStatement *isForwardingStatement() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass WhileStatement : public Statement\n{\npublic:\n    Expression *condition;\n    Statement *_body;\n    Loc endloc;                 // location of closing curly bracket\n\n    Statement *syntaxCopy();\n    bool hasBreak();\n    bool hasContinue();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DoStatement : public Statement\n{\npublic:\n    Statement *_body;\n    Expression *condition;\n    Loc endloc;                 // location of ';' after while\n\n    Statement *syntaxCopy();\n    bool hasBreak();\n    bool hasContinue();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ForStatement : public Statement\n{\npublic:\n    Statement *_init;\n    Expression *condition;\n    Expression *increment;\n    Statement *_body;\n    Loc endloc;                 // location of closing curly bracket\n\n    // When wrapped in try/finally clauses, this points to the outermost one,\n    // which may have an associated label. Internal break/continue statements\n    // treat that label as referring to this loop.\n    Statement *relatedLabeled;\n\n    Statement *syntaxCopy();\n    Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);\n    Statement *getRelatedLabeled() { return relatedLabeled ? relatedLabeled : this; }\n    bool hasBreak();\n    bool hasContinue();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ForeachStatement : public Statement\n{\npublic:\n    TOK op;                     // TOKforeach or TOKforeach_reverse\n    Parameters *parameters;     // array of Parameter*'s\n    Expression *aggr;\n    Statement *_body;\n    Loc endloc;                 // location of closing curly bracket\n\n    VarDeclaration *key;\n    VarDeclaration *value;\n\n    FuncDeclaration *func;      // function we're lexically in\n\n    Statements *cases;          // put breaks, continues, gotos and returns here\n    ScopeStatements *gotos;     // forward referenced goto's go here\n\n    Statement *syntaxCopy();\n    bool hasBreak();\n    bool hasContinue();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ForeachRangeStatement : public Statement\n{\npublic:\n    TOK op;                     // TOKforeach or TOKforeach_reverse\n    Parameter *prm;             // loop index variable\n    Expression *lwr;\n    Expression *upr;\n    Statement *_body;\n    Loc endloc;                 // location of closing curly bracket\n\n    VarDeclaration *key;\n\n    Statement *syntaxCopy();\n    bool hasBreak();\n    bool hasContinue();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass IfStatement : public Statement\n{\npublic:\n    Parameter *prm;\n    Expression *condition;\n    Statement *ifbody;\n    Statement *elsebody;\n    VarDeclaration *match;      // for MatchExpression results\n    Loc endloc;                 // location of closing curly bracket\n\n    Statement *syntaxCopy();\n    IfStatement *isIfStatement() { return this; }\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ConditionalStatement : public Statement\n{\npublic:\n    Condition *condition;\n    Statement *ifbody;\n    Statement *elsebody;\n\n    Statement *syntaxCopy();\n    Statements *flatten(Scope *sc);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StaticForeachStatement : public Statement\n{\npublic:\n    StaticForeach *sfe;\n\n    Statement *syntaxCopy();\n    Statements *flatten(Scope *sc);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass PragmaStatement : public Statement\n{\npublic:\n    Identifier *ident;\n    Expressions *args;          // array of Expression's\n    Statement *_body;\n\n    Statement *syntaxCopy();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass StaticAssertStatement : public Statement\n{\npublic:\n    StaticAssert *sa;\n\n    Statement *syntaxCopy();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass SwitchStatement : public Statement\n{\npublic:\n    Expression *condition;\n    Statement *_body;\n    bool isFinal;\n\n    DefaultStatement *sdefault;\n    TryFinallyStatement *tf;\n    GotoCaseStatements gotoCases;  // array of unresolved GotoCaseStatement's\n    CaseStatements *cases;         // array of CaseStatement's\n    int hasNoDefault;           // !=0 if no default statement\n    int hasVars;                // !=0 if has variable case values\n    VarDeclaration *lastVar;\n\n    Statement *syntaxCopy();\n    bool hasBreak();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass CaseStatement : public Statement\n{\npublic:\n    Expression *exp;\n    Statement *statement;\n\n    int index;          // which case it is (since we sort this)\n    VarDeclaration *lastVar;\n\n    Statement *syntaxCopy();\n    int compare(RootObject *obj);\n    CaseStatement *isCaseStatement() { return this; }\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n\nclass CaseRangeStatement : public Statement\n{\npublic:\n    Expression *first;\n    Expression *last;\n    Statement *statement;\n\n    Statement *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n\nclass DefaultStatement : public Statement\n{\npublic:\n    Statement *statement;\n    VarDeclaration *lastVar;\n\n    Statement *syntaxCopy();\n    DefaultStatement *isDefaultStatement() { return this; }\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass GotoDefaultStatement : public Statement\n{\npublic:\n    SwitchStatement *sw;\n\n    Statement *syntaxCopy();\n    GotoDefaultStatement *isGotoDefaultStatement() { return this; }\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass GotoCaseStatement : public Statement\n{\npublic:\n    Expression *exp;            // NULL, or which case to goto\n    CaseStatement *cs;          // case statement it resolves to\n\n    Statement *syntaxCopy();\n    GotoCaseStatement *isGotoCaseStatement() { return this; }\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass SwitchErrorStatement : public Statement\n{\npublic:\n    Expression *exp;\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ReturnStatement : public Statement\n{\npublic:\n    Expression *exp;\n    size_t caseDim;\n\n    Statement *syntaxCopy();\n\n    ReturnStatement *isReturnStatement() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass BreakStatement : public Statement\n{\npublic:\n    Identifier *ident;\n\n    Statement *syntaxCopy();\n\n    BreakStatement *isBreakStatement() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ContinueStatement : public Statement\n{\npublic:\n    Identifier *ident;\n\n    Statement *syntaxCopy();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass SynchronizedStatement : public Statement\n{\npublic:\n    Expression *exp;\n    Statement *_body;\n\n    Statement *syntaxCopy();\n    bool hasBreak();\n    bool hasContinue();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass WithStatement : public Statement\n{\npublic:\n    Expression *exp;\n    Statement *_body;\n    VarDeclaration *wthis;\n    Loc endloc;\n\n    Statement *syntaxCopy();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TryCatchStatement : public Statement\n{\npublic:\n    Statement *_body;\n    Catches *catches;\n\n    Statement *syntaxCopy();\n    bool hasBreak();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass Catch : public RootObject\n{\npublic:\n    Loc loc;\n    Type *type;\n    Identifier *ident;\n    VarDeclaration *var;\n    Statement *handler;\n\n    // set if semantic processing errors\n    bool errors;\n\n    // was generated by the compiler,\n    // wasn't present in source code\n    bool internalCatch;\n\n    Catch *syntaxCopy();\n};\n\nclass TryFinallyStatement : public Statement\n{\npublic:\n    Statement *_body;\n    Statement *finalbody;\n\n    bool bodyFallsThru;         // true if _body falls through to finally\n\n    static TryFinallyStatement *create(Loc loc, Statement *body, Statement *finalbody);\n    Statement *syntaxCopy();\n    bool hasBreak();\n    bool hasContinue();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass OnScopeStatement : public Statement\n{\npublic:\n    TOK tok;\n    Statement *statement;\n\n    Statement *syntaxCopy();\n    Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ThrowStatement : public Statement\n{\npublic:\n    Expression *exp;\n    // was generated by the compiler,\n    // wasn't present in source code\n    bool internalThrow;\n\n    Statement *syntaxCopy();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass DebugStatement : public Statement\n{\npublic:\n    Statement *statement;\n\n    Statement *syntaxCopy();\n    Statements *flatten(Scope *sc);\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass GotoStatement : public Statement\n{\npublic:\n    Identifier *ident;\n    LabelDsymbol *label;\n    TryFinallyStatement *tf;\n    OnScopeStatement *os;\n    VarDeclaration *lastVar;\n\n    Statement *syntaxCopy();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass LabelStatement : public Statement\n{\npublic:\n    Identifier *ident;\n    Statement *statement;\n    TryFinallyStatement *tf;\n    OnScopeStatement *os;\n    VarDeclaration *lastVar;\n    Statement *gotoTarget;      // interpret\n\n    bool breaks;                // someone did a 'break ident'\n\n    Statement *syntaxCopy();\n    Statements *flatten(Scope *sc);\n    Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);\n\n    LabelStatement *isLabelStatement() { return this; }\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass LabelDsymbol : public Dsymbol\n{\npublic:\n    LabelStatement *statement;\n\n    static LabelDsymbol *create(Identifier *ident);\n    LabelDsymbol *isLabel();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nStatement* asmSemantic(AsmStatement *s, Scope *sc);\n\nclass AsmStatement : public Statement\n{\npublic:\n    Token *tokens;\n\n    Statement *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass InlineAsmStatement : public AsmStatement\n{\npublic:\n    code *asmcode;\n    unsigned asmalign;          // alignment of this statement\n    unsigned regs;              // mask of registers modified (must match regm_t in back end)\n    bool refparam;              // true if function parameter is referenced\n    bool naked;                 // true if function is to be naked\n\n    Statement *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// A GCC asm statement - assembler instructions with D expression operands\nclass GccAsmStatement : public AsmStatement\n{\npublic:\n    StorageClass stc;           // attributes of the asm {} block\n    Expression *insn;           // string expression that is the template for assembler code\n    Expressions *args;          // input and output operands of the statement\n    unsigned outputargs;        // of the operands in 'args', the number of output operands\n    Identifiers *names;         // list of symbolic names for the operands\n    Expressions *constraints;   // list of string constants specifying constraints on operands\n    Expressions *clobbers;      // list of string constants specifying clobbers and scratch registers\n    Identifiers *labels;        // list of goto labels\n    GotoStatements *gotos;      // of the goto labels, the equivalent statements they represent\n\n    Statement *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n// a complete asm {} block\nclass CompoundAsmStatement : public CompoundStatement\n{\npublic:\n    StorageClass stc; // postfix attributes like nothrow/pure/@trusted\n\n    CompoundAsmStatement *syntaxCopy();\n    Statements *flatten(Scope *sc);\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass ImportStatement : public Statement\n{\npublic:\n    Dsymbols *imports;          // Array of Import's\n\n    Statement *syntaxCopy();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n"
  },
  {
    "path": "gcc/d/dmd/statement_rewrite_walker.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statement_rewrite_walker.d, _statement_rewrite_walker.d)\n * Documentation:  https://dlang.org/phobos/dmd_statement_rewrite_walker.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/statement_rewrite_walker.d\n */\n\nmodule dmd.statement_rewrite_walker;\n\nimport core.stdc.stdio;\n\nimport dmd.statement;\nimport dmd.visitor;\n\n\n/** A visitor to walk entire statements and provides ability to replace any sub-statements.\n */\nextern (C++) class StatementRewriteWalker : SemanticTimePermissiveVisitor\n{\n    alias visit = SemanticTimePermissiveVisitor.visit;\n\n    /* Point the currently visited statement.\n     * By using replaceCurrent() method, you can replace AST during walking.\n     */\n    Statement* ps;\n\npublic:\n    final void visitStmt(ref Statement s)\n    {\n        ps = &s;\n        s.accept(this);\n    }\n\n    final void replaceCurrent(Statement s)\n    {\n        *ps = s;\n    }\n\n    override void visit(PeelStatement s)\n    {\n        if (s.s)\n            visitStmt(s.s);\n    }\n\n    override void visit(CompoundStatement s)\n    {\n        if (s.statements && s.statements.dim)\n        {\n            for (size_t i = 0; i < s.statements.dim; i++)\n            {\n                if ((*s.statements)[i])\n                    visitStmt((*s.statements)[i]);\n            }\n        }\n    }\n\n    override void visit(CompoundDeclarationStatement s)\n    {\n        visit(cast(CompoundStatement)s);\n    }\n\n    override void visit(UnrolledLoopStatement s)\n    {\n        if (s.statements && s.statements.dim)\n        {\n            for (size_t i = 0; i < s.statements.dim; i++)\n            {\n                if ((*s.statements)[i])\n                    visitStmt((*s.statements)[i]);\n            }\n        }\n    }\n\n    override void visit(ScopeStatement s)\n    {\n        if (s.statement)\n            visitStmt(s.statement);\n    }\n\n    override void visit(WhileStatement s)\n    {\n        if (s._body)\n            visitStmt(s._body);\n    }\n\n    override void visit(DoStatement s)\n    {\n        if (s._body)\n            visitStmt(s._body);\n    }\n\n    override void visit(ForStatement s)\n    {\n        if (s._init)\n            visitStmt(s._init);\n        if (s._body)\n            visitStmt(s._body);\n    }\n\n    override void visit(ForeachStatement s)\n    {\n        if (s._body)\n            visitStmt(s._body);\n    }\n\n    override void visit(ForeachRangeStatement s)\n    {\n        if (s._body)\n            visitStmt(s._body);\n    }\n\n    override void visit(IfStatement s)\n    {\n        if (s.ifbody)\n            visitStmt(s.ifbody);\n        if (s.elsebody)\n            visitStmt(s.elsebody);\n    }\n\n    override void visit(SwitchStatement s)\n    {\n        if (s._body)\n            visitStmt(s._body);\n    }\n\n    override void visit(CaseStatement s)\n    {\n        if (s.statement)\n            visitStmt(s.statement);\n    }\n\n    override void visit(CaseRangeStatement s)\n    {\n        if (s.statement)\n            visitStmt(s.statement);\n    }\n\n    override void visit(DefaultStatement s)\n    {\n        if (s.statement)\n            visitStmt(s.statement);\n    }\n\n    override void visit(SynchronizedStatement s)\n    {\n        if (s._body)\n            visitStmt(s._body);\n    }\n\n    override void visit(WithStatement s)\n    {\n        if (s._body)\n            visitStmt(s._body);\n    }\n\n    override void visit(TryCatchStatement s)\n    {\n        if (s._body)\n            visitStmt(s._body);\n        if (s.catches && s.catches.dim)\n        {\n            for (size_t i = 0; i < s.catches.dim; i++)\n            {\n                Catch c = (*s.catches)[i];\n                if (c && c.handler)\n                    visitStmt(c.handler);\n            }\n        }\n    }\n\n    override void visit(TryFinallyStatement s)\n    {\n        if (s._body)\n            visitStmt(s._body);\n        if (s.finalbody)\n            visitStmt(s.finalbody);\n    }\n\n    override void visit(DebugStatement s)\n    {\n        if (s.statement)\n            visitStmt(s.statement);\n    }\n\n    override void visit(LabelStatement s)\n    {\n        if (s.statement)\n            visitStmt(s.statement);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/statementsem.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statementsem.d, _statementsem.d)\n * Documentation:  https://dlang.org/phobos/dmd_statementsem.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/statementsem.d\n */\n\nmodule dmd.statementsem;\n\nimport core.stdc.stdio;\n\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arrayop;\nimport dmd.arraytypes;\nimport dmd.blockexit;\nimport dmd.clone;\nimport dmd.cond;\nimport dmd.ctorflow;\nimport dmd.dcast;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dimport;\nimport dmd.dinterpret;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.escape;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.gluelayer;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.init;\nimport dmd.intrange;\nimport dmd.mtype;\nimport dmd.nogc;\nimport dmd.opover;\nimport dmd.root.outbuffer;\nimport dmd.semantic2;\nimport dmd.sideeffect;\nimport dmd.statement;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.visitor;\n\n/*****************************************\n * CTFE requires FuncDeclaration::labtab for the interpretation.\n * So fixing the label name inside in/out contracts is necessary\n * for the uniqueness in labtab.\n * Params:\n *      sc = context\n *      ident = statement label name to be adjusted\n * Returns:\n *      adjusted label name\n */\nprivate Identifier fixupLabelName(Scope* sc, Identifier ident)\n{\n    uint flags = (sc.flags & SCOPE.contract);\n    const id = ident.toString();\n    if (flags && flags != SCOPE.invariant_ &&\n        !(id.length >= 2 && id[0] == '_' && id[1] == '_'))  // does not start with \"__\"\n    {\n        OutBuffer buf;\n        buf.writestring(flags == SCOPE.require ? \"__in_\" : \"__out_\");\n        buf.writestring(ident.toString());\n\n        ident = Identifier.idPool(buf.peekSlice());\n    }\n    return ident;\n}\n\n/*******************************************\n * Check to see if statement is the innermost labeled statement.\n * Params:\n *      sc = context\n *      statement = Statement to check\n * Returns:\n *      if `true`, then the `LabelStatement`, otherwise `null`\n */\nprivate LabelStatement checkLabeledLoop(Scope* sc, Statement statement)\n{\n    if (sc.slabel && sc.slabel.statement == statement)\n    {\n        return sc.slabel;\n    }\n    return null;\n}\n\n/***********************************************************\n * Check an assignment is used as a condition.\n * Intended to be use before the `semantic` call on `e`.\n * Params:\n *  e = condition expression which is not yet run semantic analysis.\n * Returns:\n *  `e` or ErrorExp.\n */\nprivate Expression checkAssignmentAsCondition(Expression e)\n{\n    auto ec = lastComma(e);\n    if (ec.op == TOK.assign)\n    {\n        ec.error(\"assignment cannot be used as a condition, perhaps `==` was meant?\");\n        return new ErrorExp();\n    }\n    return e;\n}\n\n// Performs semantic analysis in Statement AST nodes\nextern(C++) Statement statementSemantic(Statement s, Scope* sc)\n{\n    scope v = new StatementSemanticVisitor(sc);\n    s.accept(v);\n    return v.result;\n}\n\nprivate extern (C++) final class StatementSemanticVisitor : Visitor\n{\n    alias visit = Visitor.visit;\n\n    Statement result;\n    Scope* sc;\n\n    this(Scope* sc)\n    {\n        this.sc = sc;\n    }\n\n    private void setError()\n    {\n        result = new ErrorStatement();\n    }\n\n    override void visit(Statement s)\n    {\n        result = s;\n    }\n\n    override void visit(ErrorStatement s)\n    {\n        result = s;\n    }\n\n    override void visit(PeelStatement s)\n    {\n        /* \"peel\" off this wrapper, and don't run semantic()\n         * on the result.\n         */\n        result = s.s;\n    }\n\n    override void visit(ExpStatement s)\n    {\n        /* https://dlang.org/spec/statement.html#expression-statement\n         */\n\n        if (s.exp)\n        {\n            //printf(\"ExpStatement::semantic() %s\\n\", exp.toChars());\n\n            // Allow CommaExp in ExpStatement because return isn't used\n            CommaExp.allow(s.exp);\n\n            s.exp = s.exp.expressionSemantic(sc);\n            s.exp = resolveProperties(sc, s.exp);\n            s.exp = s.exp.addDtorHook(sc);\n            if (checkNonAssignmentArrayOp(s.exp))\n                s.exp = new ErrorExp();\n            if (auto f = isFuncAddress(s.exp))\n            {\n                if (f.checkForwardRef(s.exp.loc))\n                    s.exp = new ErrorExp();\n            }\n            if (discardValue(s.exp))\n                s.exp = new ErrorExp();\n\n            s.exp = s.exp.optimize(WANTvalue);\n            s.exp = checkGC(sc, s.exp);\n            if (s.exp.op == TOK.error)\n                return setError();\n        }\n        result = s;\n    }\n\n    override void visit(CompileStatement cs)\n    {\n        /* https://dlang.org/spec/statement.html#mixin-statement\n         */\n\n        //printf(\"CompileStatement::semantic() %s\\n\", exp.toChars());\n        Statements* a = cs.flatten(sc);\n        if (!a)\n            return;\n        Statement s = new CompoundStatement(cs.loc, a);\n        result = s.statementSemantic(sc);\n    }\n\n    override void visit(CompoundStatement cs)\n    {\n        //printf(\"CompoundStatement::semantic(this = %p, sc = %p)\\n\", cs, sc);\n        version (none)\n        {\n            foreach (i, s; cs.statements)\n            {\n                if (s)\n                    printf(\"[%d]: %s\", i, s.toChars());\n            }\n        }\n\n        for (size_t i = 0; i < cs.statements.dim;)\n        {\n            Statement s = (*cs.statements)[i];\n            if (s)\n            {\n                Statements* flt = s.flatten(sc);\n                if (flt)\n                {\n                    cs.statements.remove(i);\n                    cs.statements.insert(i, flt);\n                    continue;\n                }\n                s = s.statementSemantic(sc);\n                (*cs.statements)[i] = s;\n                if (s)\n                {\n                    Statement sentry;\n                    Statement sexception;\n                    Statement sfinally;\n\n                    (*cs.statements)[i] = s.scopeCode(sc, &sentry, &sexception, &sfinally);\n                    if (sentry)\n                    {\n                        sentry = sentry.statementSemantic(sc);\n                        cs.statements.insert(i, sentry);\n                        i++;\n                    }\n                    if (sexception)\n                        sexception = sexception.statementSemantic(sc);\n                    if (sexception)\n                    {\n                        /* Returns: true if statements[] are empty statements\n                         */\n                        static bool isEmpty(const Statement[] statements)\n                        {\n                            foreach (s; statements)\n                            {\n                                if (const cs = s.isCompoundStatement())\n                                {\n                                    if (!isEmpty((*cs.statements)[]))\n                                        return false;\n                                }\n                                else\n                                    return false;\n                            }\n                            return true;\n                        }\n\n                        if (!sfinally && isEmpty((*cs.statements)[i + 1 .. cs.statements.dim]))\n                        {\n                        }\n                        else\n                        {\n                            /* Rewrite:\n                             *      s; s1; s2;\n                             * As:\n                             *      s;\n                             *      try { s1; s2; }\n                             *      catch (Throwable __o)\n                             *      { sexception; throw __o; }\n                             */\n                            auto a = new Statements();\n                            foreach (j; i + 1 .. cs.statements.dim)\n                            {\n                                a.push((*cs.statements)[j]);\n                            }\n                            Statement _body = new CompoundStatement(Loc.initial, a);\n                            _body = new ScopeStatement(Loc.initial, _body, Loc.initial);\n\n                            Identifier id = Identifier.generateId(\"__o\");\n\n                            Statement handler = new PeelStatement(sexception);\n                            if (sexception.blockExit(sc.func, false) & BE.fallthru)\n                            {\n                                auto ts = new ThrowStatement(Loc.initial, new IdentifierExp(Loc.initial, id));\n                                ts.internalThrow = true;\n                                handler = new CompoundStatement(Loc.initial, handler, ts);\n                            }\n\n                            auto catches = new Catches();\n                            auto ctch = new Catch(Loc.initial, getThrowable(), id, handler);\n                            ctch.internalCatch = true;\n                            catches.push(ctch);\n\n                            s = new TryCatchStatement(Loc.initial, _body, catches);\n                            if (sfinally)\n                                s = new TryFinallyStatement(Loc.initial, s, sfinally);\n                            s = s.statementSemantic(sc);\n\n                            cs.statements.setDim(i + 1);\n                            cs.statements.push(s);\n                            break;\n                        }\n                    }\n                    else if (sfinally)\n                    {\n                        if (0 && i + 1 == cs.statements.dim)\n                        {\n                            cs.statements.push(sfinally);\n                        }\n                        else\n                        {\n                            /* Rewrite:\n                             *      s; s1; s2;\n                             * As:\n                             *      s; try { s1; s2; } finally { sfinally; }\n                             */\n                            auto a = new Statements();\n                            foreach (j; i + 1 .. cs.statements.dim)\n                            {\n                                a.push((*cs.statements)[j]);\n                            }\n                            Statement _body = new CompoundStatement(Loc.initial, a);\n                            s = new TryFinallyStatement(Loc.initial, _body, sfinally);\n                            s = s.statementSemantic(sc);\n                            cs.statements.setDim(i + 1);\n                            cs.statements.push(s);\n                            break;\n                        }\n                    }\n                }\n                else\n                {\n                    /* Remove NULL statements from the list.\n                     */\n                    cs.statements.remove(i);\n                    continue;\n                }\n            }\n            i++;\n        }\n        foreach (i; 0 .. cs.statements.dim)\n        {\n        Lagain:\n            Statement s = (*cs.statements)[i];\n            if (!s)\n                continue;\n\n            Statement se = s.isErrorStatement();\n            if (se)\n            {\n                result = se;\n                return;\n            }\n\n            /* https://issues.dlang.org/show_bug.cgi?id=11653\n             * 'semantic' may return another CompoundStatement\n             * (eg. CaseRangeStatement), so flatten it here.\n             */\n            Statements* flt = s.flatten(sc);\n            if (flt)\n            {\n                cs.statements.remove(i);\n                cs.statements.insert(i, flt);\n                if (cs.statements.dim <= i)\n                    break;\n                goto Lagain;\n            }\n        }\n        if (cs.statements.dim == 1)\n        {\n            result = (*cs.statements)[0];\n            return;\n        }\n        result = cs;\n    }\n\n    override void visit(UnrolledLoopStatement uls)\n    {\n        //printf(\"UnrolledLoopStatement::semantic(this = %p, sc = %p)\\n\", uls, sc);\n        Scope* scd = sc.push();\n        scd.sbreak = uls;\n        scd.scontinue = uls;\n\n        Statement serror = null;\n        foreach (i, ref s; *uls.statements)\n        {\n            if (s)\n            {\n                //printf(\"[%d]: %s\\n\", i, s.toChars());\n                s = s.statementSemantic(scd);\n                if (s && !serror)\n                    serror = s.isErrorStatement();\n            }\n        }\n\n        scd.pop();\n        result = serror ? serror : uls;\n    }\n\n    override void visit(ScopeStatement ss)\n    {\n        //printf(\"ScopeStatement::semantic(sc = %p)\\n\", sc);\n        if (ss.statement)\n        {\n            ScopeDsymbol sym = new ScopeDsymbol();\n            sym.parent = sc.scopesym;\n            sym.endlinnum = ss.endloc.linnum;\n            sc = sc.push(sym);\n\n            Statements* a = ss.statement.flatten(sc);\n            if (a)\n            {\n                ss.statement = new CompoundStatement(ss.loc, a);\n            }\n\n            ss.statement = ss.statement.statementSemantic(sc);\n            if (ss.statement)\n            {\n                if (ss.statement.isErrorStatement())\n                {\n                    sc.pop();\n                    result = ss.statement;\n                    return;\n                }\n\n                Statement sentry;\n                Statement sexception;\n                Statement sfinally;\n                ss.statement = ss.statement.scopeCode(sc, &sentry, &sexception, &sfinally);\n                assert(!sentry);\n                assert(!sexception);\n                if (sfinally)\n                {\n                    //printf(\"adding sfinally\\n\");\n                    sfinally = sfinally.statementSemantic(sc);\n                    ss.statement = new CompoundStatement(ss.loc, ss.statement, sfinally);\n                }\n            }\n\n            sc.pop();\n        }\n        result = ss;\n    }\n\n    override void visit(ForwardingStatement ss)\n    {\n        assert(ss.sym);\n        for (Scope* csc = sc; !ss.sym.forward; csc = csc.enclosing)\n        {\n            assert(csc);\n            ss.sym.forward = csc.scopesym;\n        }\n        sc = sc.push(ss.sym);\n        sc.sbreak = ss;\n        sc.scontinue = ss;\n        ss.statement = ss.statement.statementSemantic(sc);\n        sc = sc.pop();\n        result = ss.statement;\n    }\n\n    override void visit(WhileStatement ws)\n    {\n        /* Rewrite as a for(;condition;) loop\n         * https://dlang.org/spec/statement.html#while-statement\n         */\n        Statement s = new ForStatement(ws.loc, null, ws.condition, null, ws._body, ws.endloc);\n        s = s.statementSemantic(sc);\n        result = s;\n    }\n\n    override void visit(DoStatement ds)\n    {\n        /* https://dlang.org/spec/statement.html#do-statement\n         */\n        const inLoopSave = sc.inLoop;\n        sc.inLoop = true;\n        if (ds._body)\n            ds._body = ds._body.semanticScope(sc, ds, ds);\n        sc.inLoop = inLoopSave;\n\n        if (ds.condition.op == TOK.dotIdentifier)\n            (cast(DotIdExp)ds.condition).noderef = true;\n\n        // check in syntax level\n        ds.condition = checkAssignmentAsCondition(ds.condition);\n\n        ds.condition = ds.condition.expressionSemantic(sc);\n        ds.condition = resolveProperties(sc, ds.condition);\n        if (checkNonAssignmentArrayOp(ds.condition))\n            ds.condition = new ErrorExp();\n        ds.condition = ds.condition.optimize(WANTvalue);\n        ds.condition = checkGC(sc, ds.condition);\n\n        ds.condition = ds.condition.toBoolean(sc);\n\n        if (ds.condition.op == TOK.error)\n            return setError();\n        if (ds._body && ds._body.isErrorStatement())\n        {\n            result = ds._body;\n            return;\n        }\n\n        result = ds;\n    }\n\n    override void visit(ForStatement fs)\n    {\n        /* https://dlang.org/spec/statement.html#for-statement\n         */\n        //printf(\"ForStatement::semantic %s\\n\", fs.toChars());\n\n        if (fs._init)\n        {\n            /* Rewrite:\n             *  for (auto v1 = i1, v2 = i2; condition; increment) { ... }\n             * to:\n             *  { auto v1 = i1, v2 = i2; for (; condition; increment) { ... } }\n             * then lowered to:\n             *  auto v1 = i1;\n             *  try {\n             *    auto v2 = i2;\n             *    try {\n             *      for (; condition; increment) { ... }\n             *    } finally { v2.~this(); }\n             *  } finally { v1.~this(); }\n             */\n            auto ainit = new Statements();\n            ainit.push(fs._init);\n            fs._init = null;\n            ainit.push(fs);\n            Statement s = new CompoundStatement(fs.loc, ainit);\n            s = new ScopeStatement(fs.loc, s, fs.endloc);\n            s = s.statementSemantic(sc);\n            if (!s.isErrorStatement())\n            {\n                if (LabelStatement ls = checkLabeledLoop(sc, fs))\n                    ls.gotoTarget = fs;\n                fs.relatedLabeled = s;\n            }\n            result = s;\n            return;\n        }\n        assert(fs._init is null);\n\n        auto sym = new ScopeDsymbol();\n        sym.parent = sc.scopesym;\n        sym.endlinnum = fs.endloc.linnum;\n        sc = sc.push(sym);\n        sc.inLoop = true;\n\n        if (fs.condition)\n        {\n            if (fs.condition.op == TOK.dotIdentifier)\n                (cast(DotIdExp)fs.condition).noderef = true;\n\n            // check in syntax level\n            fs.condition = checkAssignmentAsCondition(fs.condition);\n\n            fs.condition = fs.condition.expressionSemantic(sc);\n            fs.condition = resolveProperties(sc, fs.condition);\n            if (checkNonAssignmentArrayOp(fs.condition))\n                fs.condition = new ErrorExp();\n            fs.condition = fs.condition.optimize(WANTvalue);\n            fs.condition = checkGC(sc, fs.condition);\n\n            fs.condition = fs.condition.toBoolean(sc);\n        }\n        if (fs.increment)\n        {\n            CommaExp.allow(fs.increment);\n            fs.increment = fs.increment.expressionSemantic(sc);\n            fs.increment = resolveProperties(sc, fs.increment);\n            if (checkNonAssignmentArrayOp(fs.increment))\n                fs.increment = new ErrorExp();\n            fs.increment = fs.increment.optimize(WANTvalue);\n            fs.increment = checkGC(sc, fs.increment);\n        }\n\n        sc.sbreak = fs;\n        sc.scontinue = fs;\n        if (fs._body)\n            fs._body = fs._body.semanticNoScope(sc);\n\n        sc.pop();\n\n        if (fs.condition && fs.condition.op == TOK.error ||\n            fs.increment && fs.increment.op == TOK.error ||\n            fs._body && fs._body.isErrorStatement())\n            return setError();\n        result = fs;\n    }\n\n    /*******************\n     * Determines the return type of makeTupleForeach.\n     */\n    private static template MakeTupleForeachRet(bool isDecl)\n    {\n        static if(isDecl)\n        {\n            alias MakeTupleForeachRet = Dsymbols*;\n        }\n        else\n        {\n            alias MakeTupleForeachRet = void;\n        }\n    }\n\n    /*******************\n     * Type check and unroll `foreach` over an expression tuple as well\n     * as `static foreach` statements and `static foreach`\n     * declarations. For `static foreach` statements and `static\n     * foreach` declarations, the visitor interface is used (and the\n     * result is written into the `result` field.) For `static\n     * foreach` declarations, the resulting Dsymbols* are returned\n     * directly.\n     *\n     * The unrolled body is wrapped into a\n     *  - UnrolledLoopStatement, for `foreach` over an expression tuple.\n     *  - ForwardingStatement, for `static foreach` statements.\n     *  - ForwardingAttribDeclaration, for `static foreach` declarations.\n     *\n     * `static foreach` variables are declared as `STC.local`, such\n     * that they are inserted into the local symbol tables of the\n     * forwarding constructs instead of forwarded. For `static\n     * foreach` with multiple foreach loop variables whose aggregate\n     * has been lowered into a sequence of tuples, this function\n     * expands the tuples into multiple `STC.local` `static foreach`\n     * variables.\n     */\n    MakeTupleForeachRet!isDecl makeTupleForeach(bool isStatic, bool isDecl)(ForeachStatement fs, TupleForeachArgs!(isStatic, isDecl) args)\n    {\n        auto returnEarly()\n        {\n            static if (isDecl)\n            {\n                return null;\n            }\n            else\n            {\n                result = new ErrorStatement();\n                return;\n            }\n        }\n        static if(isDecl)\n        {\n            static assert(isStatic);\n            auto dbody = args[0];\n        }\n        static if(isStatic)\n        {\n            auto needExpansion = args[$-1];\n            assert(sc);\n            auto previous = sc.scopesym;\n        }\n        alias s = fs;\n\n        auto loc = fs.loc;\n        size_t dim = fs.parameters.dim;\n        static if(isStatic) bool skipCheck = needExpansion;\n        else enum skipCheck = false;\n        if (!skipCheck && (dim < 1 || dim > 2))\n        {\n            fs.error(\"only one (value) or two (key,value) arguments for tuple `foreach`\");\n            setError();\n            return returnEarly();\n        }\n\n        Type paramtype = (*fs.parameters)[dim - 1].type;\n        if (paramtype)\n        {\n            paramtype = paramtype.typeSemantic(loc, sc);\n            if (paramtype.ty == Terror)\n            {\n                setError();\n                return returnEarly();\n            }\n        }\n\n        Type tab = fs.aggr.type.toBasetype();\n        TypeTuple tuple = cast(TypeTuple)tab;\n        static if(!isDecl)\n        {\n            auto statements = new Statements();\n        }\n        else\n        {\n            auto declarations = new Dsymbols();\n        }\n        //printf(\"aggr: op = %d, %s\\n\", fs.aggr.op, fs.aggr.toChars());\n        size_t n;\n        TupleExp te = null;\n        if (fs.aggr.op == TOK.tuple) // expression tuple\n        {\n            te = cast(TupleExp)fs.aggr;\n            n = te.exps.dim;\n        }\n        else if (fs.aggr.op == TOK.type) // type tuple\n        {\n            n = Parameter.dim(tuple.arguments);\n        }\n        else\n            assert(0);\n        foreach (j; 0 .. n)\n        {\n            size_t k = (fs.op == TOK.foreach_) ? j : n - 1 - j;\n            Expression e = null;\n            Type t = null;\n            if (te)\n                e = (*te.exps)[k];\n            else\n                t = Parameter.getNth(tuple.arguments, k).type;\n            Parameter p = (*fs.parameters)[0];\n            static if(!isDecl)\n            {\n                auto st = new Statements();\n            }\n            else\n            {\n                auto st = new Dsymbols();\n            }\n\n            static if(isStatic) bool skip = needExpansion;\n            else enum skip = false;\n            if (!skip && dim == 2)\n            {\n                // Declare key\n                if (p.storageClass & (STC.out_ | STC.ref_ | STC.lazy_))\n                {\n                    fs.error(\"no storage class for key `%s`\", p.ident.toChars());\n                    setError();\n                    return returnEarly();\n                }\n                static if(isStatic)\n                {\n                    if(!p.type)\n                    {\n                        p.type = Type.tsize_t;\n                    }\n                }\n                p.type = p.type.typeSemantic(loc, sc);\n                TY keyty = p.type.ty;\n                if (keyty != Tint32 && keyty != Tuns32)\n                {\n                    if (global.params.isLP64)\n                    {\n                        if (keyty != Tint64 && keyty != Tuns64)\n                        {\n                            fs.error(\"`foreach`: key type must be `int` or `uint`, `long` or `ulong`, not `%s`\", p.type.toChars());\n                            setError();\n                            return returnEarly();\n                        }\n                    }\n                    else\n                    {\n                        fs.error(\"`foreach`: key type must be `int` or `uint`, not `%s`\", p.type.toChars());\n                        setError();\n                        return returnEarly();\n                    }\n                }\n                Initializer ie = new ExpInitializer(Loc.initial, new IntegerExp(k));\n                auto var = new VarDeclaration(loc, p.type, p.ident, ie);\n                var.storage_class |= STC.manifest;\n                static if(isStatic) var.storage_class |= STC.local;\n                static if(!isDecl)\n                {\n                    st.push(new ExpStatement(loc, var));\n                }\n                else\n                {\n                    st.push(var);\n                }\n                p = (*fs.parameters)[1]; // value\n            }\n            /***********************\n             * Declares a unrolled `foreach` loop variable or a `static foreach` variable.\n             *\n             * Params:\n             *     storageClass = The storage class of the variable.\n             *     type = The declared type of the variable.\n             *     ident = The name of the variable.\n             *     e = The initializer of the variable (i.e. the current element of the looped over aggregate).\n             *     t = The type of the initializer.\n             * Returns:\n             *     `true` iff the declaration was successful.\n             */\n            bool declareVariable(StorageClass storageClass, Type type, Identifier ident, Expression e, Type t)\n            {\n                if (storageClass & (STC.out_ | STC.lazy_) ||\n                    storageClass & STC.ref_ && !te)\n                {\n                    fs.error(\"no storage class for value `%s`\", ident.toChars());\n                    setError();\n                    return false;\n                }\n                Declaration var;\n                if (e)\n                {\n                    Type tb = e.type.toBasetype();\n                    Dsymbol ds = null;\n                    if (!(storageClass & STC.manifest))\n                    {\n                        if ((isStatic || tb.ty == Tfunction || tb.ty == Tsarray || storageClass&STC.alias_) && e.op == TOK.variable)\n                            ds = (cast(VarExp)e).var;\n                        else if (e.op == TOK.template_)\n                            ds = (cast(TemplateExp)e).td;\n                        else if (e.op == TOK.scope_)\n                            ds = (cast(ScopeExp)e).sds;\n                        else if (e.op == TOK.function_)\n                        {\n                            auto fe = cast(FuncExp)e;\n                            ds = fe.td ? cast(Dsymbol)fe.td : fe.fd;\n                        }\n                        else if (e.op == TOK.overloadSet)\n                            ds = (cast(OverExp)e).vars;\n                    }\n                    else if (storageClass & STC.alias_)\n                    {\n                        fs.error(\"`foreach` loop variable cannot be both `enum` and `alias`\");\n                        setError();\n                        return false;\n                    }\n\n                    if (ds)\n                    {\n                        var = new AliasDeclaration(loc, ident, ds);\n                        if (storageClass & STC.ref_)\n                        {\n                            fs.error(\"symbol `%s` cannot be `ref`\", ds.toChars());\n                            setError();\n                            return false;\n                        }\n                        if (paramtype)\n                        {\n                            fs.error(\"cannot specify element type for symbol `%s`\", ds.toChars());\n                            setError();\n                            return false;\n                        }\n                    }\n                    else if (e.op == TOK.type)\n                    {\n                        var = new AliasDeclaration(loc, ident, e.type);\n                        if (paramtype)\n                        {\n                            fs.error(\"cannot specify element type for type `%s`\", e.type.toChars());\n                            setError();\n                            return false;\n                        }\n                    }\n                    else\n                    {\n                        e = resolveProperties(sc, e);\n                        type = e.type;\n                        if (paramtype)\n                            type = paramtype;\n                        Initializer ie = new ExpInitializer(Loc.initial, e);\n                        auto v = new VarDeclaration(loc, type, ident, ie);\n                        if (storageClass & STC.ref_)\n                            v.storage_class |= STC.ref_ | STC.foreach_;\n                        if (isStatic || storageClass&STC.manifest || e.isConst() ||\n                            e.op == TOK.string_ ||\n                            e.op == TOK.structLiteral ||\n                            e.op == TOK.arrayLiteral)\n                        {\n                            if (v.storage_class & STC.ref_)\n                            {\n                                static if (!isStatic)\n                                {\n                                    fs.error(\"constant value `%s` cannot be `ref`\", ie.toChars());\n                                }\n                                else\n                                {\n                                    if (!needExpansion)\n                                    {\n                                        fs.error(\"constant value `%s` cannot be `ref`\", ie.toChars());\n                                    }\n                                    else\n                                    {\n                                        fs.error(\"constant value `%s` cannot be `ref`\", ident.toChars());\n                                    }\n                                }\n                                setError();\n                                return false;\n                            }\n                            else\n                                v.storage_class |= STC.manifest;\n                        }\n                        var = v;\n                    }\n                }\n                else\n                {\n                    var = new AliasDeclaration(loc, ident, t);\n                    if (paramtype)\n                    {\n                        fs.error(\"cannot specify element type for symbol `%s`\", s.toChars());\n                        setError();\n                        return false;\n                    }\n                }\n                static if (isStatic)\n                {\n                    var.storage_class |= STC.local;\n                }\n                static if (!isDecl)\n                {\n                    st.push(new ExpStatement(loc, var));\n                }\n                else\n                {\n                    st.push(var);\n                }\n                return true;\n            }\n            static if (!isStatic)\n            {\n                // Declare value\n                if (!declareVariable(p.storageClass, p.type, p.ident, e, t))\n                {\n                    return returnEarly();\n                }\n            }\n            else\n            {\n                if (!needExpansion)\n                {\n                    // Declare value\n                    if (!declareVariable(p.storageClass, p.type, p.ident, e, t))\n                    {\n                        return returnEarly();\n                    }\n                }\n                else\n                { // expand tuples into multiple `static foreach` variables.\n                    assert(e && !t);\n                    auto ident = Identifier.generateId(\"__value\");\n                    declareVariable(0, e.type, ident, e, null);\n                    import dmd.cond: StaticForeach;\n                    auto field = Identifier.idPool(StaticForeach.tupleFieldName.ptr,StaticForeach.tupleFieldName.length);\n                    Expression access = new DotIdExp(loc, e, field);\n                    access = expressionSemantic(access, sc);\n                    if (!tuple) return returnEarly();\n                    //printf(\"%s\\n\",tuple.toChars());\n                    foreach (l; 0 .. dim)\n                    {\n                        auto cp = (*fs.parameters)[l];\n                        Expression init_ = new IndexExp(loc, access, new IntegerExp(loc, l, Type.tsize_t));\n                        init_ = init_.expressionSemantic(sc);\n                        assert(init_.type);\n                        declareVariable(p.storageClass, init_.type, cp.ident, init_, null);\n                    }\n                }\n            }\n\n            static if (!isDecl)\n            {\n                if (fs._body) // https://issues.dlang.org/show_bug.cgi?id=17646\n                    st.push(fs._body.syntaxCopy());\n                Statement res = new CompoundStatement(loc, st);\n            }\n            else\n            {\n                st.append(Dsymbol.arraySyntaxCopy(dbody));\n            }\n            static if (!isStatic)\n            {\n                res = new ScopeStatement(loc, res, fs.endloc);\n            }\n            else static if (!isDecl)\n            {\n                auto fwd = new ForwardingStatement(loc, res);\n                previous = fwd.sym;\n                res = fwd;\n            }\n            else\n            {\n                import dmd.attrib: ForwardingAttribDeclaration;\n                auto res = new ForwardingAttribDeclaration(st);\n                previous = res.sym;\n            }\n            static if (!isDecl)\n            {\n                statements.push(res);\n            }\n            else\n            {\n                declarations.push(res);\n            }\n        }\n\n        static if (!isStatic)\n        {\n            Statement res = new UnrolledLoopStatement(loc, statements);\n            if (LabelStatement ls = checkLabeledLoop(sc, fs))\n                ls.gotoTarget = res;\n            if (te && te.e0)\n                res = new CompoundStatement(loc, new ExpStatement(te.e0.loc, te.e0), res);\n        }\n        else static if (!isDecl)\n        {\n            Statement res = new CompoundStatement(loc, statements);\n        }\n        else\n        {\n            auto res = declarations;\n        }\n        static if (!isDecl)\n        {\n            result = res;\n        }\n        else\n        {\n            return res;\n        }\n    }\n\n    override void visit(ForeachStatement fs)\n    {\n        /* https://dlang.org/spec/statement.html#foreach-statement\n         */\n\n        //printf(\"ForeachStatement::semantic() %p\\n\", fs);\n\n        /******\n         * Issue error if any of the ForeachTypes were not supplied and could not be inferred.\n         * Returns:\n         *      true if error issued\n         */\n        static bool checkForArgTypes(ForeachStatement fs)\n        {\n            bool result = false;\n            foreach (p; *fs.parameters)\n            {\n                if (!p.type)\n                {\n                    fs.error(\"cannot infer type for `foreach` variable `%s`, perhaps set it explicitly\", p.ident.toChars());\n                    p.type = Type.terror;\n                    result = true;\n                }\n            }\n            return result;\n        }\n\n        const loc = fs.loc;\n        const dim = fs.parameters.dim;\n        TypeAArray taa = null;\n\n        Type tn = null;\n        Type tnv = null;\n\n        fs.func = sc.func;\n        if (fs.func.fes)\n            fs.func = fs.func.fes.func;\n\n        VarDeclaration vinit = null;\n        fs.aggr = fs.aggr.expressionSemantic(sc);\n        fs.aggr = resolveProperties(sc, fs.aggr);\n        fs.aggr = fs.aggr.optimize(WANTvalue);\n        if (fs.aggr.op == TOK.error)\n            return setError();\n        Expression oaggr = fs.aggr;\n        if (fs.aggr.type && fs.aggr.type.toBasetype().ty == Tstruct &&\n            (cast(TypeStruct)(fs.aggr.type.toBasetype())).sym.dtor &&\n            fs.aggr.op != TOK.type && !fs.aggr.isLvalue())\n        {\n            // https://issues.dlang.org/show_bug.cgi?id=14653\n            // Extend the life of rvalue aggregate till the end of foreach.\n            vinit = copyToTemp(STC.rvalue, \"__aggr\", fs.aggr);\n            vinit.endlinnum = fs.endloc.linnum;\n            vinit.dsymbolSemantic(sc);\n            fs.aggr = new VarExp(fs.aggr.loc, vinit);\n        }\n\n        Dsymbol sapply = null;                  // the inferred opApply() or front() function\n        if (!inferForeachAggregate(sc, fs.op == TOK.foreach_, fs.aggr, sapply))\n        {\n            const(char)* msg = \"\";\n            if (fs.aggr.type && isAggregate(fs.aggr.type))\n            {\n                msg = \", define `opApply()`, range primitives, or use `.tupleof`\";\n            }\n            fs.error(\"invalid `foreach` aggregate `%s`%s\", oaggr.toChars(), msg);\n            return setError();\n        }\n\n        Dsymbol sapplyOld = sapply; // 'sapply' will be NULL if and after 'inferApplyArgTypes' errors\n\n        /* Check for inference errors\n         */\n        if (!inferApplyArgTypes(fs, sc, sapply))\n        {\n            /**\n             Try and extract the parameter count of the opApply callback function, e.g.:\n             int opApply(int delegate(int, float)) => 2 args\n             */\n            bool foundMismatch = false;\n            size_t foreachParamCount = 0;\n            if (sapplyOld)\n            {\n                if (FuncDeclaration fd = sapplyOld.isFuncDeclaration())\n                {\n                    int fvarargs; // ignored (opApply shouldn't take variadics)\n                    Parameters* fparameters = fd.getParameters(&fvarargs);\n\n                    if (Parameter.dim(fparameters) == 1)\n                    {\n                        // first param should be the callback function\n                        Parameter fparam = Parameter.getNth(fparameters, 0);\n                        if ((fparam.type.ty == Tpointer ||\n                             fparam.type.ty == Tdelegate) &&\n                            fparam.type.nextOf().ty == Tfunction)\n                        {\n                            TypeFunction tf = cast(TypeFunction)fparam.type.nextOf();\n                            foreachParamCount = Parameter.dim(tf.parameters);\n                            foundMismatch = true;\n                        }\n                    }\n                }\n            }\n\n            //printf(\"dim = %d, parameters.dim = %d\\n\", dim, parameters.dim);\n            if (foundMismatch && dim != foreachParamCount)\n            {\n                const(char)* plural = foreachParamCount > 1 ? \"s\" : \"\";\n                fs.error(\"cannot infer argument types, expected %d argument%s, not %d\",\n                    foreachParamCount, plural, dim);\n            }\n            else\n                fs.error(\"cannot uniquely infer `foreach` argument types\");\n\n            return setError();\n        }\n\n        Type tab = fs.aggr.type.toBasetype();\n\n        if (tab.ty == Ttuple) // don't generate new scope for tuple loops\n        {\n            makeTupleForeach!(false,false)(fs);\n            if (vinit)\n                result = new CompoundStatement(loc, new ExpStatement(loc, vinit), result);\n            result = result.statementSemantic(sc);\n            return;\n        }\n\n        auto sym = new ScopeDsymbol();\n        sym.parent = sc.scopesym;\n        sym.endlinnum = fs.endloc.linnum;\n        auto sc2 = sc.push(sym);\n        sc2.inLoop = true;\n\n        foreach (Parameter p; *fs.parameters)\n        {\n            if (p.storageClass & STC.manifest)\n            {\n                fs.error(\"cannot declare `enum` loop variables for non-unrolled foreach\");\n            }\n            if (p.storageClass & STC.alias_)\n            {\n                fs.error(\"cannot declare `alias` loop variables for non-unrolled foreach\");\n            }\n        }\n\n        Statement s = fs;\n        switch (tab.ty)\n        {\n        case Tarray:\n        case Tsarray:\n            {\n                if (checkForArgTypes(fs))\n                    goto case Terror;\n\n                if (dim < 1 || dim > 2)\n                {\n                    fs.error(\"only one or two arguments for array `foreach`\");\n                    goto case Terror;\n                }\n\n                /* Look for special case of parsing char types out of char type\n                 * array.\n                 */\n                tn = tab.nextOf().toBasetype();\n                if (tn.ty == Tchar || tn.ty == Twchar || tn.ty == Tdchar)\n                {\n                    int i = (dim == 1) ? 0 : 1; // index of value\n                    Parameter p = (*fs.parameters)[i];\n                    p.type = p.type.typeSemantic(loc, sc2);\n                    p.type = p.type.addStorageClass(p.storageClass);\n                    tnv = p.type.toBasetype();\n                    if (tnv.ty != tn.ty &&\n                        (tnv.ty == Tchar || tnv.ty == Twchar || tnv.ty == Tdchar))\n                    {\n                        if (p.storageClass & STC.ref_)\n                        {\n                            fs.error(\"`foreach`: value of UTF conversion cannot be `ref`\");\n                            goto case Terror;\n                        }\n                        if (dim == 2)\n                        {\n                            p = (*fs.parameters)[0];\n                            if (p.storageClass & STC.ref_)\n                            {\n                                fs.error(\"`foreach`: key cannot be `ref`\");\n                                goto case Terror;\n                            }\n                        }\n                        goto Lapply;\n                    }\n                }\n\n                foreach (i; 0 .. dim)\n                {\n                    // Declare parameters\n                    Parameter p = (*fs.parameters)[i];\n                    p.type = p.type.typeSemantic(loc, sc2);\n                    p.type = p.type.addStorageClass(p.storageClass);\n                    VarDeclaration var;\n\n                    if (dim == 2 && i == 0)\n                    {\n                        var = new VarDeclaration(loc, p.type.mutableOf(), Identifier.generateId(\"__key\"), null);\n                        var.storage_class |= STC.temp | STC.foreach_;\n                        if (var.storage_class & (STC.ref_ | STC.out_))\n                            var.storage_class |= STC.nodtor;\n\n                        fs.key = var;\n                        if (p.storageClass & STC.ref_)\n                        {\n                            if (var.type.constConv(p.type) <= MATCH.nomatch)\n                            {\n                                fs.error(\"key type mismatch, `%s` to `ref %s`\",\n                                    var.type.toChars(), p.type.toChars());\n                                goto case Terror;\n                            }\n                        }\n                        if (tab.ty == Tsarray)\n                        {\n                            TypeSArray ta = cast(TypeSArray)tab;\n                            IntRange dimrange = getIntRange(ta.dim);\n                            if (!IntRange.fromType(var.type).contains(dimrange))\n                            {\n                                fs.error(\"index type `%s` cannot cover index range 0..%llu\",\n                                    p.type.toChars(), ta.dim.toInteger());\n                                goto case Terror;\n                            }\n                            fs.key.range = new IntRange(SignExtendedNumber(0), dimrange.imax);\n                        }\n                    }\n                    else\n                    {\n                        var = new VarDeclaration(loc, p.type, p.ident, null);\n                        var.storage_class |= STC.foreach_;\n                        var.storage_class |= p.storageClass & (STC.in_ | STC.out_ | STC.ref_ | STC.TYPECTOR);\n                        if (var.storage_class & (STC.ref_ | STC.out_))\n                            var.storage_class |= STC.nodtor;\n\n                        fs.value = var;\n                        if (var.storage_class & STC.ref_)\n                        {\n                            if (fs.aggr.checkModifiable(sc2, 1) == 2)\n                                var.storage_class |= STC.ctorinit;\n\n                            Type t = tab.nextOf();\n                            if (t.constConv(p.type) <= MATCH.nomatch)\n                            {\n                                fs.error(\"argument type mismatch, `%s` to `ref %s`\",\n                                    t.toChars(), p.type.toChars());\n                                goto case Terror;\n                            }\n                        }\n                    }\n                }\n\n                /* Convert to a ForStatement\n                 *   foreach (key, value; a) body =>\n                 *   for (T[] tmp = a[], size_t key; key < tmp.length; ++key)\n                 *   { T value = tmp[k]; body }\n                 *\n                 *   foreach_reverse (key, value; a) body =>\n                 *   for (T[] tmp = a[], size_t key = tmp.length; key--; )\n                 *   { T value = tmp[k]; body }\n                 */\n                auto id = Identifier.generateId(\"__r\");\n                auto ie = new ExpInitializer(loc, new SliceExp(loc, fs.aggr, null, null));\n                VarDeclaration tmp;\n                if (fs.aggr.op == TOK.arrayLiteral &&\n                    !((*fs.parameters)[dim - 1].storageClass & STC.ref_))\n                {\n                    auto ale = cast(ArrayLiteralExp)fs.aggr;\n                    size_t edim = ale.elements ? ale.elements.dim : 0;\n                    auto telem = (*fs.parameters)[dim - 1].type;\n\n                    // https://issues.dlang.org/show_bug.cgi?id=12936\n                    // if telem has been specified explicitly,\n                    // converting array literal elements to telem might make it @nogc.\n                    fs.aggr = fs.aggr.implicitCastTo(sc, telem.sarrayOf(edim));\n                    if (fs.aggr.op == TOK.error)\n                        goto case Terror;\n\n                    // for (T[edim] tmp = a, ...)\n                    tmp = new VarDeclaration(loc, fs.aggr.type, id, ie);\n                }\n                else\n                    tmp = new VarDeclaration(loc, tab.nextOf().arrayOf(), id, ie);\n                tmp.storage_class |= STC.temp;\n\n                Expression tmp_length = new DotIdExp(loc, new VarExp(loc, tmp), Id.length);\n\n                if (!fs.key)\n                {\n                    Identifier idkey = Identifier.generateId(\"__key\");\n                    fs.key = new VarDeclaration(loc, Type.tsize_t, idkey, null);\n                    fs.key.storage_class |= STC.temp;\n                }\n                if (fs.op == TOK.foreach_reverse_)\n                    fs.key._init = new ExpInitializer(loc, tmp_length);\n                else\n                    fs.key._init = new ExpInitializer(loc, new IntegerExp(loc, 0, fs.key.type));\n\n                auto cs = new Statements();\n                if (vinit)\n                    cs.push(new ExpStatement(loc, vinit));\n                cs.push(new ExpStatement(loc, tmp));\n                cs.push(new ExpStatement(loc, fs.key));\n                Statement forinit = new CompoundDeclarationStatement(loc, cs);\n\n                Expression cond;\n                if (fs.op == TOK.foreach_reverse_)\n                {\n                    // key--\n                    cond = new PostExp(TOK.minusMinus, loc, new VarExp(loc, fs.key));\n                }\n                else\n                {\n                    // key < tmp.length\n                    cond = new CmpExp(TOK.lessThan, loc, new VarExp(loc, fs.key), tmp_length);\n                }\n\n                Expression increment = null;\n                if (fs.op == TOK.foreach_)\n                {\n                    // key += 1\n                    increment = new AddAssignExp(loc, new VarExp(loc, fs.key), new IntegerExp(loc, 1, fs.key.type));\n                }\n\n                // T value = tmp[key];\n                IndexExp indexExp = new IndexExp(loc, new VarExp(loc, tmp), new VarExp(loc, fs.key));\n                indexExp.indexIsInBounds = true; // disabling bounds checking in foreach statements.\n                fs.value._init = new ExpInitializer(loc, indexExp);\n                Statement ds = new ExpStatement(loc, fs.value);\n\n                if (dim == 2)\n                {\n                    Parameter p = (*fs.parameters)[0];\n                    if ((p.storageClass & STC.ref_) && p.type.equals(fs.key.type))\n                    {\n                        fs.key.range = null;\n                        auto v = new AliasDeclaration(loc, p.ident, fs.key);\n                        fs._body = new CompoundStatement(loc, new ExpStatement(loc, v), fs._body);\n                    }\n                    else\n                    {\n                        auto ei = new ExpInitializer(loc, new IdentifierExp(loc, fs.key.ident));\n                        auto v = new VarDeclaration(loc, p.type, p.ident, ei);\n                        v.storage_class |= STC.foreach_ | (p.storageClass & STC.ref_);\n                        fs._body = new CompoundStatement(loc, new ExpStatement(loc, v), fs._body);\n                        if (fs.key.range && !p.type.isMutable())\n                        {\n                            /* Limit the range of the key to the specified range\n                             */\n                            v.range = new IntRange(fs.key.range.imin, fs.key.range.imax - SignExtendedNumber(1));\n                        }\n                    }\n                }\n                fs._body = new CompoundStatement(loc, ds, fs._body);\n\n                s = new ForStatement(loc, forinit, cond, increment, fs._body, fs.endloc);\n                if (auto ls = checkLabeledLoop(sc, fs))   // https://issues.dlang.org/show_bug.cgi?id=15450\n                                                          // don't use sc2\n                    ls.gotoTarget = s;\n                s = s.statementSemantic(sc2);\n                break;\n            }\n        case Taarray:\n            if (fs.op == TOK.foreach_reverse_)\n                fs.warning(\"cannot use `foreach_reverse` with an associative array\");\n            if (checkForArgTypes(fs))\n                goto case Terror;\n\n            taa = cast(TypeAArray)tab;\n            if (dim < 1 || dim > 2)\n            {\n                fs.error(\"only one or two arguments for associative array `foreach`\");\n                goto case Terror;\n            }\n            goto Lapply;\n\n        case Tclass:\n        case Tstruct:\n            /* Prefer using opApply, if it exists\n             */\n            if (sapply)\n                goto Lapply;\n            {\n                /* Look for range iteration, i.e. the properties\n                 * .empty, .popFront, .popBack, .front and .back\n                 *    foreach (e; aggr) { ... }\n                 * translates to:\n                 *    for (auto __r = aggr[]; !__r.empty; __r.popFront()) {\n                 *        auto e = __r.front;\n                 *        ...\n                 *    }\n                 */\n                auto ad = (tab.ty == Tclass) ?\n                    cast(AggregateDeclaration)(cast(TypeClass)tab).sym :\n                    cast(AggregateDeclaration)(cast(TypeStruct)tab).sym;\n                Identifier idfront;\n                Identifier idpopFront;\n                if (fs.op == TOK.foreach_)\n                {\n                    idfront = Id.Ffront;\n                    idpopFront = Id.FpopFront;\n                }\n                else\n                {\n                    idfront = Id.Fback;\n                    idpopFront = Id.FpopBack;\n                }\n                auto sfront = ad.search(Loc.initial, idfront);\n                if (!sfront)\n                    goto Lapply;\n\n                /* Generate a temporary __r and initialize it with the aggregate.\n                 */\n                VarDeclaration r;\n                Statement _init;\n                if (vinit && fs.aggr.op == TOK.variable && (cast(VarExp)fs.aggr).var == vinit)\n                {\n                    r = vinit;\n                    _init = new ExpStatement(loc, vinit);\n                }\n                else\n                {\n                    r = copyToTemp(0, \"__r\", fs.aggr);\n                    r.dsymbolSemantic(sc);\n                    _init = new ExpStatement(loc, r);\n                    if (vinit)\n                        _init = new CompoundStatement(loc, new ExpStatement(loc, vinit), _init);\n                }\n\n                // !__r.empty\n                Expression e = new VarExp(loc, r);\n                e = new DotIdExp(loc, e, Id.Fempty);\n                Expression condition = new NotExp(loc, e);\n\n                // __r.idpopFront()\n                e = new VarExp(loc, r);\n                Expression increment = new CallExp(loc, new DotIdExp(loc, e, idpopFront));\n\n                /* Declaration statement for e:\n                 *    auto e = __r.idfront;\n                 */\n                e = new VarExp(loc, r);\n                Expression einit = new DotIdExp(loc, e, idfront);\n                Statement makeargs, forbody;\n                if (dim == 1)\n                {\n                    auto p = (*fs.parameters)[0];\n                    auto ve = new VarDeclaration(loc, p.type, p.ident, new ExpInitializer(loc, einit));\n                    ve.storage_class |= STC.foreach_;\n                    ve.storage_class |= p.storageClass & (STC.in_ | STC.out_ | STC.ref_ | STC.TYPECTOR);\n\n                    makeargs = new ExpStatement(loc, ve);\n                }\n                else\n                {\n                    auto vd = copyToTemp(STC.ref_, \"__front\", einit);\n                    vd.dsymbolSemantic(sc);\n                    makeargs = new ExpStatement(loc, vd);\n\n                    Type tfront;\n                    if (auto fd = sfront.isFuncDeclaration())\n                    {\n                        if (!fd.functionSemantic())\n                            goto Lrangeerr;\n                        tfront = fd.type;\n                    }\n                    else if (auto td = sfront.isTemplateDeclaration())\n                    {\n                        Expressions a;\n                        if (auto f = resolveFuncCall(loc, sc, td, null, tab, &a, 1))\n                            tfront = f.type;\n                    }\n                    else if (auto d = sfront.isDeclaration())\n                    {\n                        tfront = d.type;\n                    }\n                    if (!tfront || tfront.ty == Terror)\n                        goto Lrangeerr;\n                    if (tfront.toBasetype().ty == Tfunction)\n                        tfront = tfront.toBasetype().nextOf();\n                    if (tfront.ty == Tvoid)\n                    {\n                        fs.error(\"`%s.front` is `void` and has no value\", oaggr.toChars());\n                        goto case Terror;\n                    }\n\n                    // Resolve inout qualifier of front type\n                    tfront = tfront.substWildTo(tab.mod);\n\n                    Expression ve = new VarExp(loc, vd);\n                    ve.type = tfront;\n\n                    auto exps = new Expressions();\n                    exps.push(ve);\n                    int pos = 0;\n                    while (exps.dim < dim)\n                    {\n                        pos = expandAliasThisTuples(exps, pos);\n                        if (pos == -1)\n                            break;\n                    }\n                    if (exps.dim != dim)\n                    {\n                        const(char)* plural = exps.dim > 1 ? \"s\" : \"\";\n                        fs.error(\"cannot infer argument types, expected %d argument%s, not %d\",\n                            exps.dim, plural, dim);\n                        goto case Terror;\n                    }\n\n                    foreach (i; 0 .. dim)\n                    {\n                        auto p = (*fs.parameters)[i];\n                        auto exp = (*exps)[i];\n                        version (none)\n                        {\n                            printf(\"[%d] p = %s %s, exp = %s %s\\n\", i,\n                                p.type ? p.type.toChars() : \"?\", p.ident.toChars(),\n                                exp.type.toChars(), exp.toChars());\n                        }\n                        if (!p.type)\n                            p.type = exp.type;\n                        p.type = p.type.addStorageClass(p.storageClass).typeSemantic(loc, sc2);\n                        if (!exp.implicitConvTo(p.type))\n                            goto Lrangeerr;\n\n                        auto var = new VarDeclaration(loc, p.type, p.ident, new ExpInitializer(loc, exp));\n                        var.storage_class |= STC.ctfe | STC.ref_ | STC.foreach_;\n                        makeargs = new CompoundStatement(loc, makeargs, new ExpStatement(loc, var));\n                    }\n                }\n\n                forbody = new CompoundStatement(loc, makeargs, fs._body);\n\n                s = new ForStatement(loc, _init, condition, increment, forbody, fs.endloc);\n                if (auto ls = checkLabeledLoop(sc, fs))\n                    ls.gotoTarget = s;\n\n                version (none)\n                {\n                    printf(\"init: %s\\n\", _init.toChars());\n                    printf(\"condition: %s\\n\", condition.toChars());\n                    printf(\"increment: %s\\n\", increment.toChars());\n                    printf(\"body: %s\\n\", forbody.toChars());\n                }\n                s = s.statementSemantic(sc2);\n                break;\n\n            Lrangeerr:\n                fs.error(\"cannot infer argument types\");\n                goto case Terror;\n            }\n        case Tdelegate:\n            if (fs.op == TOK.foreach_reverse_)\n                fs.deprecation(\"cannot use `foreach_reverse` with a delegate\");\n        Lapply:\n            {\n                if (checkForArgTypes(fs))\n                    goto case Terror;\n\n                TypeFunction tfld = null;\n                if (sapply)\n                {\n                    FuncDeclaration fdapply = sapply.isFuncDeclaration();\n                    if (fdapply)\n                    {\n                        assert(fdapply.type && fdapply.type.ty == Tfunction);\n                        tfld = cast(TypeFunction)fdapply.type.typeSemantic(loc, sc2);\n                        goto Lget;\n                    }\n                    else if (tab.ty == Tdelegate)\n                    {\n                        tfld = cast(TypeFunction)tab.nextOf();\n                    Lget:\n                        //printf(\"tfld = %s\\n\", tfld.toChars());\n                        if (tfld.parameters.dim == 1)\n                        {\n                            Parameter p = Parameter.getNth(tfld.parameters, 0);\n                            if (p.type && p.type.ty == Tdelegate)\n                            {\n                                auto t = p.type.typeSemantic(loc, sc2);\n                                assert(t.ty == Tdelegate);\n                                tfld = cast(TypeFunction)t.nextOf();\n                            }\n                            //printf(\"tfld = %s\\n\", tfld.toChars());\n                        }\n                    }\n                }\n\n                FuncExp flde = foreachBodyToFunction(sc2, fs, tfld);\n                if (!flde)\n                    goto case Terror;\n\n                // Resolve any forward referenced goto's\n                foreach (i; 0 .. fs.gotos.dim)\n                {\n                    GotoStatement gs = cast(GotoStatement)(*fs.gotos)[i].statement;\n                    if (!gs.label.statement)\n                    {\n                        // 'Promote' it to this scope, and replace with a return\n                        fs.cases.push(gs);\n                        s = new ReturnStatement(Loc.initial, new IntegerExp(fs.cases.dim + 1));\n                        (*fs.gotos)[i].statement = s;\n                    }\n                }\n\n                Expression e = null;\n                Expression ec;\n                if (vinit)\n                {\n                    e = new DeclarationExp(loc, vinit);\n                    e = e.expressionSemantic(sc2);\n                    if (e.op == TOK.error)\n                        goto case Terror;\n                }\n\n                if (taa)\n                {\n                    // Check types\n                    Parameter p = (*fs.parameters)[0];\n                    bool isRef = (p.storageClass & STC.ref_) != 0;\n                    Type ta = p.type;\n                    if (dim == 2)\n                    {\n                        Type ti = (isRef ? taa.index.addMod(MODFlags.const_) : taa.index);\n                        if (isRef ? !ti.constConv(ta) : !ti.implicitConvTo(ta))\n                        {\n                            fs.error(\"`foreach`: index must be type `%s`, not `%s`\",\n                                ti.toChars(), ta.toChars());\n                            goto case Terror;\n                        }\n                        p = (*fs.parameters)[1];\n                        isRef = (p.storageClass & STC.ref_) != 0;\n                        ta = p.type;\n                    }\n                    Type taav = taa.nextOf();\n                    if (isRef ? !taav.constConv(ta) : !taav.implicitConvTo(ta))\n                    {\n                        fs.error(\"`foreach`: value must be type `%s`, not `%s`\",\n                            taav.toChars(), ta.toChars());\n                        goto case Terror;\n                    }\n\n                    /* Call:\n                     *  extern(C) int _aaApply(void*, in size_t, int delegate(void*))\n                     *      _aaApply(aggr, keysize, flde)\n                     *\n                     *  extern(C) int _aaApply2(void*, in size_t, int delegate(void*, void*))\n                     *      _aaApply2(aggr, keysize, flde)\n                     */\n                    __gshared const(char)** name = [\"_aaApply\", \"_aaApply2\"];\n                    __gshared FuncDeclaration* fdapply = [null, null];\n                    __gshared TypeDelegate* fldeTy = [null, null];\n\n                    ubyte i = (dim == 2 ? 1 : 0);\n                    if (!fdapply[i])\n                    {\n                        auto params = new Parameters();\n                        params.push(new Parameter(0, Type.tvoid.pointerTo(), null, null, null));\n                        params.push(new Parameter(STC.in_, Type.tsize_t, null, null, null));\n                        auto dgparams = new Parameters();\n                        dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));\n                        if (dim == 2)\n                            dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));\n                        fldeTy[i] = new TypeDelegate(new TypeFunction(dgparams, Type.tint32, 0, LINK.d));\n                        params.push(new Parameter(0, fldeTy[i], null, null, null));\n                        fdapply[i] = FuncDeclaration.genCfunc(params, Type.tint32, name[i]);\n                    }\n\n                    auto exps = new Expressions();\n                    exps.push(fs.aggr);\n                    auto keysize = taa.index.size();\n                    if (keysize == SIZE_INVALID)\n                        goto case Terror;\n                    assert(keysize < keysize.max - Target.ptrsize);\n                    keysize = (keysize + (Target.ptrsize - 1)) & ~(Target.ptrsize - 1);\n                    // paint delegate argument to the type runtime expects\n                    Expression fexp = flde;\n                    if (!fldeTy[i].equals(flde.type))\n                    {\n                        fexp = new CastExp(loc, flde, flde.type);\n                        fexp.type = fldeTy[i];\n                    }\n                    exps.push(new IntegerExp(Loc.initial, keysize, Type.tsize_t));\n                    exps.push(fexp);\n                    ec = new VarExp(Loc.initial, fdapply[i], false);\n                    ec = new CallExp(loc, ec, exps);\n                    ec.type = Type.tint32; // don't run semantic() on ec\n                }\n                else if (tab.ty == Tarray || tab.ty == Tsarray)\n                {\n                    /* Call:\n                     *      _aApply(aggr, flde)\n                     */\n                    __gshared const(char)** fntab =\n                    [\n                        \"cc\", \"cw\", \"cd\",\n                        \"wc\", \"cc\", \"wd\",\n                        \"dc\", \"dw\", \"dd\"\n                    ];\n\n                    const(size_t) BUFFER_LEN = 7 + 1 + 2 + dim.sizeof * 3 + 1;\n                    char[BUFFER_LEN] fdname;\n                    int flag;\n\n                    switch (tn.ty)\n                    {\n                    case Tchar:     flag = 0;   break;\n                    case Twchar:    flag = 3;   break;\n                    case Tdchar:    flag = 6;   break;\n                    default:\n                        assert(0);\n                    }\n                    switch (tnv.ty)\n                    {\n                    case Tchar:     flag += 0;  break;\n                    case Twchar:    flag += 1;  break;\n                    case Tdchar:    flag += 2;  break;\n                    default:\n                        assert(0);\n                    }\n                    const(char)* r = (fs.op == TOK.foreach_reverse_) ? \"R\" : \"\";\n                    int j = sprintf(fdname.ptr, \"_aApply%s%.*s%llu\", r, 2, fntab[flag], cast(ulong)dim);\n                    assert(j < BUFFER_LEN);\n\n                    FuncDeclaration fdapply;\n                    TypeDelegate dgty;\n                    auto params = new Parameters();\n                    params.push(new Parameter(STC.in_, tn.arrayOf(), null, null, null));\n                    auto dgparams = new Parameters();\n                    dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));\n                    if (dim == 2)\n                        dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));\n                    dgty = new TypeDelegate(new TypeFunction(dgparams, Type.tint32, 0, LINK.d));\n                    params.push(new Parameter(0, dgty, null, null, null));\n                    fdapply = FuncDeclaration.genCfunc(params, Type.tint32, fdname.ptr);\n\n                    if (tab.ty == Tsarray)\n                        fs.aggr = fs.aggr.castTo(sc2, tn.arrayOf());\n                    // paint delegate argument to the type runtime expects\n                    Expression fexp = flde;\n                    if (!dgty.equals(flde.type))\n                    {\n                        fexp = new CastExp(loc, flde, flde.type);\n                        fexp.type = dgty;\n                    }\n                    ec = new VarExp(Loc.initial, fdapply, false);\n                    ec = new CallExp(loc, ec, fs.aggr, fexp);\n                    ec.type = Type.tint32; // don't run semantic() on ec\n                }\n                else if (tab.ty == Tdelegate)\n                {\n                    /* Call:\n                     *      aggr(flde)\n                     */\n                    if (fs.aggr.op == TOK.delegate_ && (cast(DelegateExp)fs.aggr).func.isNested())\n                    {\n                        // https://issues.dlang.org/show_bug.cgi?id=3560\n                        fs.aggr = (cast(DelegateExp)fs.aggr).e1;\n                    }\n                    ec = new CallExp(loc, fs.aggr, flde);\n                    ec = ec.expressionSemantic(sc2);\n                    if (ec.op == TOK.error)\n                        goto case Terror;\n                    if (ec.type != Type.tint32)\n                    {\n                        fs.error(\"`opApply()` function for `%s` must return an `int`\", tab.toChars());\n                        goto case Terror;\n                    }\n                }\n                else\n                {\nversion (none)\n{\n                    if (global.params.vsafe)\n                    {\n                        message(loc, \"To enforce `@safe`, the compiler allocates a closure unless `opApply()` uses `scope`\");\n                    }\n                    flde.fd.tookAddressOf = 1;\n}\nelse\n{\n                    if (global.params.vsafe)\n                        ++flde.fd.tookAddressOf;  // allocate a closure unless the opApply() uses 'scope'\n}\n                    assert(tab.ty == Tstruct || tab.ty == Tclass);\n                    assert(sapply);\n                    /* Call:\n                     *  aggr.apply(flde)\n                     */\n                    ec = new DotIdExp(loc, fs.aggr, sapply.ident);\n                    ec = new CallExp(loc, ec, flde);\n                    ec = ec.expressionSemantic(sc2);\n                    if (ec.op == TOK.error)\n                        goto case Terror;\n                    if (ec.type != Type.tint32)\n                    {\n                        fs.error(\"`opApply()` function for `%s` must return an `int`\", tab.toChars());\n                        goto case Terror;\n                    }\n                }\n                e = Expression.combine(e, ec);\n\n                if (!fs.cases.dim)\n                {\n                    // Easy case, a clean exit from the loop\n                    e = new CastExp(loc, e, Type.tvoid); // https://issues.dlang.org/show_bug.cgi?id=13899\n                    s = new ExpStatement(loc, e);\n                }\n                else\n                {\n                    // Construct a switch statement around the return value\n                    // of the apply function.\n                    auto a = new Statements();\n\n                    // default: break; takes care of cases 0 and 1\n                    s = new BreakStatement(Loc.initial, null);\n                    s = new DefaultStatement(Loc.initial, s);\n                    a.push(s);\n\n                    // cases 2...\n                    foreach (i, c; *fs.cases)\n                    {\n                        s = new CaseStatement(Loc.initial, new IntegerExp(i + 2), c);\n                        a.push(s);\n                    }\n\n                    s = new CompoundStatement(loc, a);\n                    s = new SwitchStatement(loc, e, s, false);\n                }\n                s = s.statementSemantic(sc2);\n                break;\n            }\n            assert(0);\n\n        case Terror:\n            s = new ErrorStatement();\n            break;\n\n        default:\n            fs.error(\"`foreach`: `%s` is not an aggregate type\", fs.aggr.type.toChars());\n            goto case Terror;\n        }\n        sc2.pop();\n        result = s;\n    }\n\n    /*************************************\n     * Turn foreach body into the function literal:\n     *  int delegate(ref T param) { body }\n     * Params:\n     *  sc = context\n     *  fs = ForeachStatement\n     *  tfld = type of function literal to be created, can be null\n     * Returns:\n     *  Function literal created, as an expression\n     *  null if error.\n     */\n    static FuncExp foreachBodyToFunction(Scope* sc, ForeachStatement fs, TypeFunction tfld)\n    {\n        auto params = new Parameters();\n        foreach (i; 0 .. fs.parameters.dim)\n        {\n            Parameter p = (*fs.parameters)[i];\n            StorageClass stc = STC.ref_;\n            Identifier id;\n\n            p.type = p.type.typeSemantic(fs.loc, sc);\n            p.type = p.type.addStorageClass(p.storageClass);\n            if (tfld)\n            {\n                Parameter prm = Parameter.getNth(tfld.parameters, i);\n                //printf(\"\\tprm = %s%s\\n\", (prm.storageClass&STC.ref_?\"ref \":\"\").ptr, prm.ident.toChars());\n                stc = prm.storageClass & STC.ref_;\n                id = p.ident; // argument copy is not need.\n                if ((p.storageClass & STC.ref_) != stc)\n                {\n                    if (!stc)\n                    {\n                        fs.error(\"`foreach`: cannot make `%s` `ref`\", p.ident.toChars());\n                        return null;\n                    }\n                    goto LcopyArg;\n                }\n            }\n            else if (p.storageClass & STC.ref_)\n            {\n                // default delegate parameters are marked as ref, then\n                // argument copy is not need.\n                id = p.ident;\n            }\n            else\n            {\n                // Make a copy of the ref argument so it isn't\n                // a reference.\n            LcopyArg:\n                id = Identifier.generateId(\"__applyArg\", cast(int)i);\n\n                Initializer ie = new ExpInitializer(fs.loc, new IdentifierExp(fs.loc, id));\n                auto v = new VarDeclaration(fs.loc, p.type, p.ident, ie);\n                v.storage_class |= STC.temp;\n                Statement s = new ExpStatement(fs.loc, v);\n                fs._body = new CompoundStatement(fs.loc, s, fs._body);\n            }\n            params.push(new Parameter(stc, p.type, id, null, null));\n        }\n        // https://issues.dlang.org/show_bug.cgi?id=13840\n        // Throwable nested function inside nothrow function is acceptable.\n        StorageClass stc = mergeFuncAttrs(STC.safe | STC.pure_ | STC.nogc, fs.func);\n        auto tf = new TypeFunction(params, Type.tint32, 0, LINK.d, stc);\n        fs.cases = new Statements();\n        fs.gotos = new ScopeStatements();\n        auto fld = new FuncLiteralDeclaration(fs.loc, fs.endloc, tf, TOK.delegate_, fs);\n        fld.fbody = fs._body;\n        Expression flde = new FuncExp(fs.loc, fld);\n        flde = flde.expressionSemantic(sc);\n        fld.tookAddressOf = 0;\n        if (flde.op == TOK.error)\n            return null;\n        return cast(FuncExp)flde;\n    }\n\n    override void visit(ForeachRangeStatement fs)\n    {\n        /* https://dlang.org/spec/statement.html#foreach-range-statement\n         */\n\n        //printf(\"ForeachRangeStatement::semantic() %p\\n\", fs);\n        auto loc = fs.loc;\n        fs.lwr = fs.lwr.expressionSemantic(sc);\n        fs.lwr = resolveProperties(sc, fs.lwr);\n        fs.lwr = fs.lwr.optimize(WANTvalue);\n        if (!fs.lwr.type)\n        {\n            fs.error(\"invalid range lower bound `%s`\", fs.lwr.toChars());\n            return setError();\n        }\n\n        fs.upr = fs.upr.expressionSemantic(sc);\n        fs.upr = resolveProperties(sc, fs.upr);\n        fs.upr = fs.upr.optimize(WANTvalue);\n        if (!fs.upr.type)\n        {\n            fs.error(\"invalid range upper bound `%s`\", fs.upr.toChars());\n            return setError();\n        }\n\n        if (fs.prm.type)\n        {\n            fs.prm.type = fs.prm.type.typeSemantic(loc, sc);\n            fs.prm.type = fs.prm.type.addStorageClass(fs.prm.storageClass);\n            fs.lwr = fs.lwr.implicitCastTo(sc, fs.prm.type);\n\n            if (fs.upr.implicitConvTo(fs.prm.type) || (fs.prm.storageClass & STC.ref_))\n            {\n                fs.upr = fs.upr.implicitCastTo(sc, fs.prm.type);\n            }\n            else\n            {\n                // See if upr-1 fits in prm.type\n                Expression limit = new MinExp(loc, fs.upr, new IntegerExp(1));\n                limit = limit.expressionSemantic(sc);\n                limit = limit.optimize(WANTvalue);\n                if (!limit.implicitConvTo(fs.prm.type))\n                {\n                    fs.upr = fs.upr.implicitCastTo(sc, fs.prm.type);\n                }\n            }\n        }\n        else\n        {\n            /* Must infer types from lwr and upr\n             */\n            Type tlwr = fs.lwr.type.toBasetype();\n            if (tlwr.ty == Tstruct || tlwr.ty == Tclass)\n            {\n                /* Just picking the first really isn't good enough.\n                 */\n                fs.prm.type = fs.lwr.type;\n            }\n            else if (fs.lwr.type == fs.upr.type)\n            {\n                /* Same logic as CondExp ?lwr:upr\n                 */\n                fs.prm.type = fs.lwr.type;\n            }\n            else\n            {\n                scope AddExp ea = new AddExp(loc, fs.lwr, fs.upr);\n                if (typeCombine(ea, sc))\n                    return setError();\n                fs.prm.type = ea.type;\n                fs.lwr = ea.e1;\n                fs.upr = ea.e2;\n            }\n            fs.prm.type = fs.prm.type.addStorageClass(fs.prm.storageClass);\n        }\n        if (fs.prm.type.ty == Terror || fs.lwr.op == TOK.error || fs.upr.op == TOK.error)\n        {\n            return setError();\n        }\n\n        /* Convert to a for loop:\n         *  foreach (key; lwr .. upr) =>\n         *  for (auto key = lwr, auto tmp = upr; key < tmp; ++key)\n         *\n         *  foreach_reverse (key; lwr .. upr) =>\n         *  for (auto tmp = lwr, auto key = upr; key-- > tmp;)\n         */\n        auto ie = new ExpInitializer(loc, (fs.op == TOK.foreach_) ? fs.lwr : fs.upr);\n        fs.key = new VarDeclaration(loc, fs.upr.type.mutableOf(), Identifier.generateId(\"__key\"), ie);\n        fs.key.storage_class |= STC.temp;\n        SignExtendedNumber lower = getIntRange(fs.lwr).imin;\n        SignExtendedNumber upper = getIntRange(fs.upr).imax;\n        if (lower <= upper)\n        {\n            fs.key.range = new IntRange(lower, upper);\n        }\n\n        Identifier id = Identifier.generateId(\"__limit\");\n        ie = new ExpInitializer(loc, (fs.op == TOK.foreach_) ? fs.upr : fs.lwr);\n        auto tmp = new VarDeclaration(loc, fs.upr.type, id, ie);\n        tmp.storage_class |= STC.temp;\n\n        auto cs = new Statements();\n        // Keep order of evaluation as lwr, then upr\n        if (fs.op == TOK.foreach_)\n        {\n            cs.push(new ExpStatement(loc, fs.key));\n            cs.push(new ExpStatement(loc, tmp));\n        }\n        else\n        {\n            cs.push(new ExpStatement(loc, tmp));\n            cs.push(new ExpStatement(loc, fs.key));\n        }\n        Statement forinit = new CompoundDeclarationStatement(loc, cs);\n\n        Expression cond;\n        if (fs.op == TOK.foreach_reverse_)\n        {\n            cond = new PostExp(TOK.minusMinus, loc, new VarExp(loc, fs.key));\n            if (fs.prm.type.isscalar())\n            {\n                // key-- > tmp\n                cond = new CmpExp(TOK.greaterThan, loc, cond, new VarExp(loc, tmp));\n            }\n            else\n            {\n                // key-- != tmp\n                cond = new EqualExp(TOK.notEqual, loc, cond, new VarExp(loc, tmp));\n            }\n        }\n        else\n        {\n            if (fs.prm.type.isscalar())\n            {\n                // key < tmp\n                cond = new CmpExp(TOK.lessThan, loc, new VarExp(loc, fs.key), new VarExp(loc, tmp));\n            }\n            else\n            {\n                // key != tmp\n                cond = new EqualExp(TOK.notEqual, loc, new VarExp(loc, fs.key), new VarExp(loc, tmp));\n            }\n        }\n\n        Expression increment = null;\n        if (fs.op == TOK.foreach_)\n        {\n            // key += 1\n            //increment = new AddAssignExp(loc, new VarExp(loc, fs.key), new IntegerExp(1));\n            increment = new PreExp(TOK.prePlusPlus, loc, new VarExp(loc, fs.key));\n        }\n        if ((fs.prm.storageClass & STC.ref_) && fs.prm.type.equals(fs.key.type))\n        {\n            fs.key.range = null;\n            auto v = new AliasDeclaration(loc, fs.prm.ident, fs.key);\n            fs._body = new CompoundStatement(loc, new ExpStatement(loc, v), fs._body);\n        }\n        else\n        {\n            ie = new ExpInitializer(loc, new CastExp(loc, new VarExp(loc, fs.key), fs.prm.type));\n            auto v = new VarDeclaration(loc, fs.prm.type, fs.prm.ident, ie);\n            v.storage_class |= STC.temp | STC.foreach_ | (fs.prm.storageClass & STC.ref_);\n            fs._body = new CompoundStatement(loc, new ExpStatement(loc, v), fs._body);\n            if (fs.key.range && !fs.prm.type.isMutable())\n            {\n                /* Limit the range of the key to the specified range\n                 */\n                v.range = new IntRange(fs.key.range.imin, fs.key.range.imax - SignExtendedNumber(1));\n            }\n        }\n        if (fs.prm.storageClass & STC.ref_)\n        {\n            if (fs.key.type.constConv(fs.prm.type) <= MATCH.nomatch)\n            {\n                fs.error(\"argument type mismatch, `%s` to `ref %s`\", fs.key.type.toChars(), fs.prm.type.toChars());\n                return setError();\n            }\n        }\n\n        auto s = new ForStatement(loc, forinit, cond, increment, fs._body, fs.endloc);\n        if (LabelStatement ls = checkLabeledLoop(sc, fs))\n            ls.gotoTarget = s;\n        result = s.statementSemantic(sc);\n    }\n\n    override void visit(IfStatement ifs)\n    {\n        /* https://dlang.org/spec/statement.html#IfStatement\n         */\n\n        // check in syntax level\n        ifs.condition = checkAssignmentAsCondition(ifs.condition);\n\n        auto sym = new ScopeDsymbol();\n        sym.parent = sc.scopesym;\n        sym.endlinnum = ifs.endloc.linnum;\n        Scope* scd = sc.push(sym);\n        if (ifs.prm)\n        {\n            /* Declare prm, which we will set to be the\n             * result of condition.\n             */\n            auto ei = new ExpInitializer(ifs.loc, ifs.condition);\n            ifs.match = new VarDeclaration(ifs.loc, ifs.prm.type, ifs.prm.ident, ei);\n            ifs.match.parent = scd.func;\n            ifs.match.storage_class |= ifs.prm.storageClass;\n            ifs.match.dsymbolSemantic(scd);\n\n            auto de = new DeclarationExp(ifs.loc, ifs.match);\n            auto ve = new VarExp(ifs.loc, ifs.match);\n            ifs.condition = new CommaExp(ifs.loc, de, ve);\n            ifs.condition = ifs.condition.expressionSemantic(scd);\n\n            if (ifs.match.edtor)\n            {\n                Statement sdtor = new DtorExpStatement(ifs.loc, ifs.match.edtor, ifs.match);\n                sdtor = new OnScopeStatement(ifs.loc, TOK.onScopeExit, sdtor);\n                ifs.ifbody = new CompoundStatement(ifs.loc, sdtor, ifs.ifbody);\n                ifs.match.storage_class |= STC.nodtor;\n            }\n        }\n        else\n        {\n            if (ifs.condition.op == TOK.dotIdentifier)\n                (cast(DotIdExp)ifs.condition).noderef = true;\n\n            ifs.condition = ifs.condition.expressionSemantic(scd);\n            ifs.condition = resolveProperties(scd, ifs.condition);\n            ifs.condition = ifs.condition.addDtorHook(scd);\n        }\n        if (checkNonAssignmentArrayOp(ifs.condition))\n            ifs.condition = new ErrorExp();\n        ifs.condition = checkGC(scd, ifs.condition);\n\n        // Convert to boolean after declaring prm so this works:\n        //  if (S prm = S()) {}\n        // where S is a struct that defines opCast!bool.\n        ifs.condition = ifs.condition.toBoolean(scd);\n\n        // If we can short-circuit evaluate the if statement, don't do the\n        // semantic analysis of the skipped code.\n        // This feature allows a limited form of conditional compilation.\n        ifs.condition = ifs.condition.optimize(WANTvalue);\n\n        // Save 'root' of two branches (then and else) at the point where it forks\n        CtorFlow ctorflow_root = scd.ctorflow.clone();\n\n        ifs.ifbody = ifs.ifbody.semanticNoScope(scd);\n        scd.pop();\n\n        CtorFlow ctorflow_then = sc.ctorflow;   // move flow results\n        sc.ctorflow = ctorflow_root;            // reset flow analysis back to root\n        if (ifs.elsebody)\n            ifs.elsebody = ifs.elsebody.semanticScope(sc, null, null);\n\n        // Merge 'then' results into 'else' results\n        sc.merge(ifs.loc, ctorflow_then);\n\n        ctorflow_then.freeFieldinit();          // free extra copy of the data\n\n        if (ifs.condition.op == TOK.error ||\n            (ifs.ifbody && ifs.ifbody.isErrorStatement()) ||\n            (ifs.elsebody && ifs.elsebody.isErrorStatement()))\n        {\n            return setError();\n        }\n        result = ifs;\n    }\n\n    override void visit(ConditionalStatement cs)\n    {\n        //printf(\"ConditionalStatement::semantic()\\n\");\n\n        // If we can short-circuit evaluate the if statement, don't do the\n        // semantic analysis of the skipped code.\n        // This feature allows a limited form of conditional compilation.\n        if (cs.condition.include(sc))\n        {\n            DebugCondition dc = cs.condition.isDebugCondition();\n            if (dc)\n            {\n                sc = sc.push();\n                sc.flags |= SCOPE.debug_;\n                cs.ifbody = cs.ifbody.statementSemantic(sc);\n                sc.pop();\n            }\n            else\n                cs.ifbody = cs.ifbody.statementSemantic(sc);\n            result = cs.ifbody;\n        }\n        else\n        {\n            if (cs.elsebody)\n                cs.elsebody = cs.elsebody.statementSemantic(sc);\n            result = cs.elsebody;\n        }\n    }\n\n    override void visit(PragmaStatement ps)\n    {\n        /* https://dlang.org/spec/statement.html#pragma-statement\n         */\n        // Should be merged with PragmaDeclaration\n\n        //printf(\"PragmaStatement::semantic() %s\\n\", ps.toChars());\n        //printf(\"body = %p\\n\", ps._body);\n        if (ps.ident == Id.msg)\n        {\n            if (ps.args)\n            {\n                foreach (arg; *ps.args)\n                {\n                    sc = sc.startCTFE();\n                    auto e = arg.expressionSemantic(sc);\n                    e = resolveProperties(sc, e);\n                    sc = sc.endCTFE();\n\n                    // pragma(msg) is allowed to contain types as well as expressions\n                    e = ctfeInterpretForPragmaMsg(e);\n                    if (e.op == TOK.error)\n                    {\n                        errorSupplemental(ps.loc, \"while evaluating `pragma(msg, %s)`\", arg.toChars());\n                        return setError();\n                    }\n                    StringExp se = e.toStringExp();\n                    if (se)\n                    {\n                        se = se.toUTF8(sc);\n                        fprintf(stderr, \"%.*s\", cast(int)se.len, se.string);\n                    }\n                    else\n                        fprintf(stderr, \"%s\", e.toChars());\n                }\n                fprintf(stderr, \"\\n\");\n            }\n        }\n        else if (ps.ident == Id.lib)\n        {\n            version (all)\n            {\n                /* Should this be allowed?\n                 */\n                ps.error(\"`pragma(lib)` not allowed as statement\");\n                return setError();\n            }\n            else\n            {\n                if (!ps.args || ps.args.dim != 1)\n                {\n                    ps.error(\"`string` expected for library name\");\n                    return setError();\n                }\n                else\n                {\n                    auto se = semanticString(sc, (*ps.args)[0], \"library name\");\n                    if (!se)\n                        return setError();\n\n                    if (global.params.verbose)\n                    {\n                        message(\"library   %.*s\", cast(int)se.len, se.string);\n                    }\n                }\n            }\n        }\n        else if (ps.ident == Id.linkerDirective)\n        {\n            /* Should this be allowed?\n             */\n            ps.error(\"`pragma(linkerDirective)` not allowed as statement\");\n            return setError();\n        }\n        else if (ps.ident == Id.startaddress)\n        {\n            if (!ps.args || ps.args.dim != 1)\n                ps.error(\"function name expected for start address\");\n            else\n            {\n                Expression e = (*ps.args)[0];\n                sc = sc.startCTFE();\n                e = e.expressionSemantic(sc);\n                e = resolveProperties(sc, e);\n                sc = sc.endCTFE();\n\n                e = e.ctfeInterpret();\n                (*ps.args)[0] = e;\n                Dsymbol sa = getDsymbol(e);\n                if (!sa || !sa.isFuncDeclaration())\n                {\n                    ps.error(\"function name expected for start address, not `%s`\", e.toChars());\n                    return setError();\n                }\n                if (ps._body)\n                {\n                    ps._body = ps._body.statementSemantic(sc);\n                    if (ps._body.isErrorStatement())\n                    {\n                        result = ps._body;\n                        return;\n                    }\n                }\n                result = ps;\n                return;\n            }\n        }\n        else if (ps.ident == Id.Pinline)\n        {\n            PINLINE inlining = PINLINE.default_;\n            if (!ps.args || ps.args.dim == 0)\n                inlining = PINLINE.default_;\n            else if (!ps.args || ps.args.dim != 1)\n            {\n                ps.error(\"boolean expression expected for `pragma(inline)`\");\n                return setError();\n            }\n            else\n            {\n                Expression e = (*ps.args)[0];\n                if (e.op != TOK.int64 || !e.type.equals(Type.tbool))\n                {\n                    ps.error(\"pragma(inline, true or false) expected, not `%s`\", e.toChars());\n                    return setError();\n                }\n\n                if (e.isBool(true))\n                    inlining = PINLINE.always;\n                else if (e.isBool(false))\n                    inlining = PINLINE.never;\n\n                    FuncDeclaration fd = sc.func;\n                if (!fd)\n                {\n                    ps.error(\"`pragma(inline)` is not inside a function\");\n                    return setError();\n                }\n                fd.inlining = inlining;\n            }\n        }\n        else if (!global.params.ignoreUnsupportedPragmas)\n        {\n            ps.error(\"unrecognized `pragma(%s)`\", ps.ident.toChars());\n            return setError();\n        }\n\n        if (ps._body)\n        {\n            if (ps.ident == Id.msg || ps.ident == Id.startaddress)\n            {\n                ps.error(\"`pragma(%s)` is missing a terminating `;`\", ps.ident.toChars());\n                return setError();\n            }\n            ps._body = ps._body.statementSemantic(sc);\n        }\n        result = ps._body;\n    }\n\n    override void visit(StaticAssertStatement s)\n    {\n        s.sa.semantic2(sc);\n    }\n\n    override void visit(SwitchStatement ss)\n    {\n        /* https://dlang.org/spec/statement.html#switch-statement\n         */\n\n        //printf(\"SwitchStatement::semantic(%p)\\n\", ss);\n        ss.tf = sc.tf;\n        if (ss.cases)\n        {\n            result = ss; // already run\n            return;\n        }\n\n        bool conditionError = false;\n        ss.condition = ss.condition.expressionSemantic(sc);\n        ss.condition = resolveProperties(sc, ss.condition);\n\n        Type att = null;\n        TypeEnum te = null;\n        while (ss.condition.op != TOK.error)\n        {\n            // preserve enum type for final switches\n            if (ss.condition.type.ty == Tenum)\n                te = cast(TypeEnum)ss.condition.type;\n            if (ss.condition.type.isString())\n            {\n                // If it's not an array, cast it to one\n                if (ss.condition.type.ty != Tarray)\n                {\n                    ss.condition = ss.condition.implicitCastTo(sc, ss.condition.type.nextOf().arrayOf());\n                }\n                ss.condition.type = ss.condition.type.constOf();\n                break;\n            }\n            ss.condition = integralPromotions(ss.condition, sc);\n            if (ss.condition.op != TOK.error && ss.condition.type.isintegral())\n                break;\n\n            auto ad = isAggregate(ss.condition.type);\n            if (ad && ad.aliasthis && ss.condition.type != att)\n            {\n                if (!att && ss.condition.type.checkAliasThisRec())\n                    att = ss.condition.type;\n                if (auto e = resolveAliasThis(sc, ss.condition, true))\n                {\n                    ss.condition = e;\n                    continue;\n                }\n            }\n\n            if (ss.condition.op != TOK.error)\n            {\n                ss.error(\"`%s` must be of integral or string type, it is a `%s`\",\n                    ss.condition.toChars(), ss.condition.type.toChars());\n                conditionError = true;\n                break;\n            }\n        }\n        if (checkNonAssignmentArrayOp(ss.condition))\n            ss.condition = new ErrorExp();\n        ss.condition = ss.condition.optimize(WANTvalue);\n        ss.condition = checkGC(sc, ss.condition);\n        if (ss.condition.op == TOK.error)\n            conditionError = true;\n\n        bool needswitcherror = false;\n\n        ss.lastVar = sc.lastVar;\n\n        sc = sc.push();\n        sc.sbreak = ss;\n        sc.sw = ss;\n\n        ss.cases = new CaseStatements();\n        const inLoopSave = sc.inLoop;\n        sc.inLoop = true;        // BUG: should use Scope::mergeCallSuper() for each case instead\n        ss._body = ss._body.statementSemantic(sc);\n        sc.inLoop = inLoopSave;\n\n        if (conditionError || ss._body.isErrorStatement())\n        {\n            sc.pop();\n            return setError();\n        }\n\n        // Resolve any goto case's with exp\n      Lgotocase:\n        foreach (gcs; ss.gotoCases)\n        {\n            if (!gcs.exp)\n            {\n                gcs.error(\"no `case` statement following `goto case;`\");\n                sc.pop();\n                return setError();\n            }\n\n            for (Scope* scx = sc; scx; scx = scx.enclosing)\n            {\n                if (!scx.sw)\n                    continue;\n                foreach (cs; *scx.sw.cases)\n                {\n                    if (cs.exp.equals(gcs.exp))\n                    {\n                        gcs.cs = cs;\n                        continue Lgotocase;\n                    }\n                }\n            }\n            gcs.error(\"`case %s` not found\", gcs.exp.toChars());\n            sc.pop();\n            return setError();\n        }\n\n        if (ss.isFinal)\n        {\n            Type t = ss.condition.type;\n            Dsymbol ds;\n            EnumDeclaration ed = null;\n            if (t && ((ds = t.toDsymbol(sc)) !is null))\n                ed = ds.isEnumDeclaration(); // typedef'ed enum\n            if (!ed && te && ((ds = te.toDsymbol(sc)) !is null))\n                ed = ds.isEnumDeclaration();\n            if (ed)\n            {\n              Lmembers:\n                foreach (es; *ed.members)\n                {\n                    EnumMember em = es.isEnumMember();\n                    if (em)\n                    {\n                        foreach (cs; *ss.cases)\n                        {\n                            if (cs.exp.equals(em.value) || (!cs.exp.type.isString() && !em.value.type.isString() && cs.exp.toInteger() == em.value.toInteger()))\n                                continue Lmembers;\n                        }\n                        ss.error(\"`enum` member `%s` not represented in `final switch`\", em.toChars());\n                        sc.pop();\n                        return setError();\n                    }\n                }\n            }\n            else\n                needswitcherror = true;\n        }\n\n        if (!sc.sw.sdefault && (!ss.isFinal || needswitcherror || global.params.useAssert == CHECKENABLE.on))\n        {\n            ss.hasNoDefault = 1;\n\n            if (!ss.isFinal && !ss._body.isErrorStatement())\n                ss.error(\"`switch` statement without a `default`; use `final switch` or add `default: assert(0);` or add `default: break;`\");\n\n            // Generate runtime error if the default is hit\n            auto a = new Statements();\n            CompoundStatement cs;\n            Statement s;\n\n            if (global.params.useSwitchError == CHECKENABLE.on &&\n                global.params.checkAction != CHECKACTION.halt)\n            {\n                if (global.params.checkAction == CHECKACTION.C)\n                {\n                    /* Rewrite as an assert(0) and let e2ir generate\n                     * the call to the C assert failure function\n                     */\n                    s = new ExpStatement(ss.loc, new AssertExp(ss.loc, new IntegerExp(ss.loc, 0, Type.tint32)));\n                }\n                else\n                {\n                    Expression sl = new IdentifierExp(ss.loc, Id.empty);\n                    sl = new DotIdExp(ss.loc, sl, Id.object);\n                    sl = new DotIdExp(ss.loc, sl, Id.__switch_error);\n\n                    Expressions* args = new Expressions();\n                    args.push(new StringExp(ss.loc, cast(char*) ss.loc.filename));\n                    args.push(new IntegerExp(ss.loc.linnum));\n\n                    sl = new CallExp(ss.loc, sl, args);\n                    sl.expressionSemantic(sc);\n\n                    s = new SwitchErrorStatement(ss.loc, sl);\n                }\n            }\n            else\n                s = new ExpStatement(ss.loc, new HaltExp(ss.loc));\n\n            a.reserve(2);\n            sc.sw.sdefault = new DefaultStatement(ss.loc, s);\n            a.push(ss._body);\n            if (ss._body.blockExit(sc.func, false) & BE.fallthru)\n                a.push(new BreakStatement(Loc.initial, null));\n            a.push(sc.sw.sdefault);\n            cs = new CompoundStatement(ss.loc, a);\n            ss._body = cs;\n        }\n\n        if (ss.checkLabel())\n        {\n            sc.pop();\n            return setError();\n        }\n\n\n        if (ss.condition.type.isString())\n        {\n            // Transform a switch with string labels into a switch with integer labels.\n\n            // The integer value of each case corresponds to the index of each label\n            // string in the sorted array of label strings.\n\n            // The value of the integer condition is obtained by calling the druntime template\n            // switch(object.__switch(cond, options...)) {0: {...}, 1: {...}, ...}\n\n            // We sort a copy of the array of labels because we want to do a binary search in object.__switch,\n            // without modifying the order of the case blocks here in the compiler.\n\n            size_t numcases = 0;\n            if (ss.cases)\n                numcases = ss.cases.dim;\n\n            for (size_t i = 0; i < numcases; i++)\n            {\n                CaseStatement cs = (*ss.cases)[i];\n                cs.index = cast(int)i;\n            }\n\n            // Make a copy of all the cases so that qsort doesn't scramble the actual\n            // data we pass to codegen (the order of the cases in the switch).\n            CaseStatements *csCopy = (*ss.cases).copy();\n\n            extern (C) static int sort_compare(const(void*) x, const(void*) y) @trusted\n            {\n                CaseStatement ox = *cast(CaseStatement *)x;\n                CaseStatement oy = *cast(CaseStatement*)y;\n\n                return ox.compare(oy);\n            }\n\n            if (numcases)\n            {\n                import core.stdc.stdlib;\n                qsort(csCopy.data, numcases, CaseStatement.sizeof, cast(_compare_fp_t)&sort_compare);\n            }\n\n            // The actual lowering\n            auto arguments = new Expressions();\n            arguments.push(ss.condition);\n\n            auto compileTimeArgs = new Objects();\n\n            // The type & label no.\n            compileTimeArgs.push(new TypeExp(ss.loc, ss.condition.type.nextOf()));\n\n            // The switch labels\n            foreach (caseString; *csCopy)\n            {\n                compileTimeArgs.push(caseString.exp);\n            }\n\n            Expression sl = new IdentifierExp(ss.loc, Id.empty);\n            sl = new DotIdExp(ss.loc, sl, Id.object);\n            sl = new DotTemplateInstanceExp(ss.loc, sl, Id.__switch, compileTimeArgs);\n\n            sl = new CallExp(ss.loc, sl, arguments);\n            sl.expressionSemantic(sc);\n            ss.condition = sl;\n\n            auto i = 0;\n            foreach (c; *csCopy)\n            {\n                (*ss.cases)[c.index].exp = new IntegerExp(i++);\n            }\n\n            //printf(\"%s\\n\", ss._body.toChars());\n            ss.statementSemantic(sc);\n        }\n\n        sc.pop();\n        result = ss;\n    }\n\n    override void visit(CaseStatement cs)\n    {\n        SwitchStatement sw = sc.sw;\n        bool errors = false;\n\n        //printf(\"CaseStatement::semantic() %s\\n\", toChars());\n        sc = sc.startCTFE();\n        cs.exp = cs.exp.expressionSemantic(sc);\n        cs.exp = resolveProperties(sc, cs.exp);\n        sc = sc.endCTFE();\n\n        if (sw)\n        {\n            cs.exp = cs.exp.implicitCastTo(sc, sw.condition.type);\n            cs.exp = cs.exp.optimize(WANTvalue | WANTexpand);\n\n            Expression e = cs.exp;\n            // Remove all the casts the user and/or implicitCastTo may introduce\n            // otherwise we'd sometimes fail the check below.\n            while (e.op == TOK.cast_)\n                e = (cast(CastExp)e).e1;\n\n            /* This is where variables are allowed as case expressions.\n             */\n            if (e.op == TOK.variable)\n            {\n                VarExp ve = cast(VarExp)e;\n                VarDeclaration v = ve.var.isVarDeclaration();\n                Type t = cs.exp.type.toBasetype();\n                if (v && (t.isintegral() || t.ty == Tclass))\n                {\n                    /* Flag that we need to do special code generation\n                     * for this, i.e. generate a sequence of if-then-else\n                     */\n                    sw.hasVars = 1;\n\n                    /* TODO check if v can be uninitialized at that point.\n                     */\n                    if (!v.isConst() && !v.isImmutable())\n                    {\n                        cs.deprecation(\"`case` variables have to be `const` or `immutable`\");\n                    }\n\n                    if (sw.isFinal)\n                    {\n                        cs.error(\"`case` variables not allowed in `final switch` statements\");\n                        errors = true;\n                    }\n\n                    /* Find the outermost scope `scx` that set `sw`.\n                     * Then search scope `scx` for a declaration of `v`.\n                     */\n                    for (Scope* scx = sc; scx; scx = scx.enclosing)\n                    {\n                        if (scx.enclosing && scx.enclosing.sw == sw)\n                            continue;\n                        assert(scx.sw == sw);\n\n                        if (!scx.search(cs.exp.loc, v.ident, null))\n                        {\n                            cs.error(\"`case` variable `%s` declared at %s cannot be declared in `switch` body\",\n                                v.toChars(), v.loc.toChars());\n                            errors = true;\n                        }\n                        break;\n                    }\n                    goto L1;\n                }\n            }\n            else\n                cs.exp = cs.exp.ctfeInterpret();\n\n            if (StringExp se = cs.exp.toStringExp())\n                cs.exp = se;\n            else if (cs.exp.op != TOK.int64 && cs.exp.op != TOK.error)\n            {\n                cs.error(\"`case` must be a `string` or an integral constant, not `%s`\", cs.exp.toChars());\n                errors = true;\n            }\n\n        L1:\n            foreach (cs2; *sw.cases)\n            {\n                //printf(\"comparing '%s' with '%s'\\n\", exp.toChars(), cs.exp.toChars());\n                if (cs2.exp.equals(cs.exp))\n                {\n                    cs.error(\"duplicate `case %s` in `switch` statement\", cs.exp.toChars());\n                    errors = true;\n                    break;\n                }\n            }\n\n            sw.cases.push(cs);\n\n            // Resolve any goto case's with no exp to this case statement\n            for (size_t i = 0; i < sw.gotoCases.dim;)\n            {\n                GotoCaseStatement gcs = sw.gotoCases[i];\n                if (!gcs.exp)\n                {\n                    gcs.cs = cs;\n                    sw.gotoCases.remove(i); // remove from array\n                    continue;\n                }\n                i++;\n            }\n\n            if (sc.sw.tf != sc.tf)\n            {\n                cs.error(\"`switch` and `case` are in different `finally` blocks\");\n                errors = true;\n            }\n        }\n        else\n        {\n            cs.error(\"`case` not in `switch` statement\");\n            errors = true;\n        }\n\n        sc.ctorflow.orCSX(CSX.label);\n        cs.statement = cs.statement.statementSemantic(sc);\n        if (cs.statement.isErrorStatement())\n        {\n            result = cs.statement;\n            return;\n        }\n        if (errors || cs.exp.op == TOK.error)\n            return setError();\n\n        cs.lastVar = sc.lastVar;\n        result = cs;\n    }\n\n    override void visit(CaseRangeStatement crs)\n    {\n        SwitchStatement sw = sc.sw;\n        if (sw is null)\n        {\n            crs.error(\"case range not in `switch` statement\");\n            return setError();\n        }\n\n        //printf(\"CaseRangeStatement::semantic() %s\\n\", toChars());\n        bool errors = false;\n        if (sw.isFinal)\n        {\n            crs.error(\"case ranges not allowed in `final switch`\");\n            errors = true;\n        }\n\n        sc = sc.startCTFE();\n        crs.first = crs.first.expressionSemantic(sc);\n        crs.first = resolveProperties(sc, crs.first);\n        sc = sc.endCTFE();\n        crs.first = crs.first.implicitCastTo(sc, sw.condition.type);\n        crs.first = crs.first.ctfeInterpret();\n\n        sc = sc.startCTFE();\n        crs.last = crs.last.expressionSemantic(sc);\n        crs.last = resolveProperties(sc, crs.last);\n        sc = sc.endCTFE();\n        crs.last = crs.last.implicitCastTo(sc, sw.condition.type);\n        crs.last = crs.last.ctfeInterpret();\n\n        if (crs.first.op == TOK.error || crs.last.op == TOK.error || errors)\n        {\n            if (crs.statement)\n                crs.statement.statementSemantic(sc);\n            return setError();\n        }\n\n        uinteger_t fval = crs.first.toInteger();\n        uinteger_t lval = crs.last.toInteger();\n        if ((crs.first.type.isunsigned() && fval > lval) || (!crs.first.type.isunsigned() && cast(sinteger_t)fval > cast(sinteger_t)lval))\n        {\n            crs.error(\"first `case %s` is greater than last `case %s`\", crs.first.toChars(), crs.last.toChars());\n            errors = true;\n            lval = fval;\n        }\n\n        if (lval - fval > 256)\n        {\n            crs.error(\"had %llu cases which is more than 256 cases in case range\", lval - fval);\n            errors = true;\n            lval = fval + 256;\n        }\n\n        if (errors)\n            return setError();\n\n        /* This works by replacing the CaseRange with an array of Case's.\n         *\n         * case a: .. case b: s;\n         *    =>\n         * case a:\n         *   [...]\n         * case b:\n         *   s;\n         */\n\n        auto statements = new Statements();\n        for (uinteger_t i = fval; i != lval + 1; i++)\n        {\n            Statement s = crs.statement;\n            if (i != lval) // if not last case\n                s = new ExpStatement(crs.loc, cast(Expression)null);\n            Expression e = new IntegerExp(crs.loc, i, crs.first.type);\n            Statement cs = new CaseStatement(crs.loc, e, s);\n            statements.push(cs);\n        }\n        Statement s = new CompoundStatement(crs.loc, statements);\n        sc.ctorflow.orCSX(CSX.label);\n        s = s.statementSemantic(sc);\n        result = s;\n    }\n\n    override void visit(DefaultStatement ds)\n    {\n        //printf(\"DefaultStatement::semantic()\\n\");\n        bool errors = false;\n        if (sc.sw)\n        {\n            if (sc.sw.sdefault)\n            {\n                ds.error(\"`switch` statement already has a default\");\n                errors = true;\n            }\n            sc.sw.sdefault = ds;\n\n            if (sc.sw.tf != sc.tf)\n            {\n                ds.error(\"`switch` and `default` are in different `finally` blocks\");\n                errors = true;\n            }\n            if (sc.sw.isFinal)\n            {\n                ds.error(\"`default` statement not allowed in `final switch` statement\");\n                errors = true;\n            }\n        }\n        else\n        {\n            ds.error(\"`default` not in `switch` statement\");\n            errors = true;\n        }\n\n        sc.ctorflow.orCSX(CSX.label);\n        ds.statement = ds.statement.statementSemantic(sc);\n        if (errors || ds.statement.isErrorStatement())\n            return setError();\n\n        ds.lastVar = sc.lastVar;\n        result = ds;\n    }\n\n    override void visit(GotoDefaultStatement gds)\n    {\n        /* https://dlang.org/spec/statement.html#goto-statement\n         */\n\n        gds.sw = sc.sw;\n        if (!gds.sw)\n        {\n            gds.error(\"`goto default` not in `switch` statement\");\n            return setError();\n        }\n        if (gds.sw.isFinal)\n        {\n            gds.error(\"`goto default` not allowed in `final switch` statement\");\n            return setError();\n        }\n        result = gds;\n    }\n\n    override void visit(GotoCaseStatement gcs)\n    {\n        /* https://dlang.org/spec/statement.html#goto-statement\n         */\n\n        if (!sc.sw)\n        {\n            gcs.error(\"`goto case` not in `switch` statement\");\n            return setError();\n        }\n\n        if (gcs.exp)\n        {\n            gcs.exp = gcs.exp.expressionSemantic(sc);\n            gcs.exp = gcs.exp.implicitCastTo(sc, sc.sw.condition.type);\n            gcs.exp = gcs.exp.optimize(WANTvalue);\n            if (gcs.exp.op == TOK.error)\n                return setError();\n        }\n\n        sc.sw.gotoCases.push(gcs);\n        result = gcs;\n    }\n\n    override void visit(ReturnStatement rs)\n    {\n        /* https://dlang.org/spec/statement.html#return-statement\n         */\n\n        //printf(\"ReturnStatement.dsymbolSemantic() %p, %s\\n\", rs, rs.toChars());\n\n        FuncDeclaration fd = sc.parent.isFuncDeclaration();\n        if (fd.fes)\n            fd = fd.fes.func; // fd is now function enclosing foreach\n\n            TypeFunction tf = cast(TypeFunction)fd.type;\n        assert(tf.ty == Tfunction);\n\n        if (rs.exp && rs.exp.op == TOK.variable && (cast(VarExp)rs.exp).var == fd.vresult)\n        {\n            // return vresult;\n            if (sc.fes)\n            {\n                assert(rs.caseDim == 0);\n                sc.fes.cases.push(rs);\n                result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.dim + 1));\n                return;\n            }\n            if (fd.returnLabel)\n            {\n                auto gs = new GotoStatement(rs.loc, Id.returnLabel);\n                gs.label = fd.returnLabel;\n                result = gs;\n                return;\n            }\n\n            if (!fd.returns)\n                fd.returns = new ReturnStatements();\n            fd.returns.push(rs);\n            result = rs;\n            return;\n        }\n\n        Type tret = tf.next;\n        Type tbret = tret ? tret.toBasetype() : null;\n\n        bool inferRef = (tf.isref && (fd.storage_class & STC.auto_));\n        Expression e0 = null;\n\n        bool errors = false;\n        if (sc.flags & SCOPE.contract)\n        {\n            rs.error(\"`return` statements cannot be in contracts\");\n            errors = true;\n        }\n        if (sc.os && sc.os.tok != TOK.onScopeFailure)\n        {\n            rs.error(\"`return` statements cannot be in `%s` bodies\", Token.toChars(sc.os.tok));\n            errors = true;\n        }\n        if (sc.tf)\n        {\n            rs.error(\"`return` statements cannot be in `finally` bodies\");\n            errors = true;\n        }\n\n        if (fd.isCtorDeclaration())\n        {\n            if (rs.exp)\n            {\n                rs.error(\"cannot return expression from constructor\");\n                errors = true;\n            }\n\n            // Constructors implicitly do:\n            //      return this;\n            rs.exp = new ThisExp(Loc.initial);\n            rs.exp.type = tret;\n        }\n        else if (rs.exp)\n        {\n            fd.hasReturnExp |= (fd.hasReturnExp & 1 ? 16 : 1);\n\n            FuncLiteralDeclaration fld = fd.isFuncLiteralDeclaration();\n            if (tret)\n                rs.exp = inferType(rs.exp, tret);\n            else if (fld && fld.treq)\n                rs.exp = inferType(rs.exp, fld.treq.nextOf().nextOf());\n\n            rs.exp = rs.exp.expressionSemantic(sc);\n\n            // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684\n            if (rs.exp.op == TOK.type)\n                rs.exp = resolveAliasThis(sc, rs.exp);\n\n            rs.exp = resolveProperties(sc, rs.exp);\n            if (rs.exp.checkType())\n                rs.exp = new ErrorExp();\n            if (auto f = isFuncAddress(rs.exp))\n            {\n                if (fd.inferRetType && f.checkForwardRef(rs.exp.loc))\n                    rs.exp = new ErrorExp();\n            }\n            if (checkNonAssignmentArrayOp(rs.exp))\n                rs.exp = new ErrorExp();\n\n            // Extract side-effect part\n            rs.exp = Expression.extractLast(rs.exp, e0);\n            if (rs.exp.op == TOK.call)\n                rs.exp = valueNoDtor(rs.exp);\n\n            if (e0)\n                e0 = e0.optimize(WANTvalue);\n\n            /* Void-return function can have void typed expression\n             * on return statement.\n             */\n            if (tbret && tbret.ty == Tvoid || rs.exp.type.ty == Tvoid)\n            {\n                if (rs.exp.type.ty != Tvoid)\n                {\n                    rs.error(\"cannot return non-void from `void` function\");\n                    errors = true;\n                    rs.exp = new CastExp(rs.loc, rs.exp, Type.tvoid);\n                    rs.exp = rs.exp.expressionSemantic(sc);\n                }\n\n                /* Replace:\n                 *      return exp;\n                 * with:\n                 *      exp; return;\n                 */\n                e0 = Expression.combine(e0, rs.exp);\n                rs.exp = null;\n            }\n            if (e0)\n                e0 = checkGC(sc, e0);\n        }\n\n        if (rs.exp)\n        {\n            if (fd.inferRetType) // infer return type\n            {\n                if (!tret)\n                {\n                    tf.next = rs.exp.type;\n                }\n                else if (tret.ty != Terror && !rs.exp.type.equals(tret))\n                {\n                    int m1 = rs.exp.type.implicitConvTo(tret);\n                    int m2 = tret.implicitConvTo(rs.exp.type);\n                    //printf(\"exp.type = %s m2<-->m1 tret %s\\n\", exp.type.toChars(), tret.toChars());\n                    //printf(\"m1 = %d, m2 = %d\\n\", m1, m2);\n\n                    if (m1 && m2)\n                    {\n                    }\n                    else if (!m1 && m2)\n                        tf.next = rs.exp.type;\n                    else if (m1 && !m2)\n                    {\n                    }\n                    else if (rs.exp.op != TOK.error)\n                    {\n                        rs.error(\"mismatched function return type inference of `%s` and `%s`\", rs.exp.type.toChars(), tret.toChars());\n                        errors = true;\n                        tf.next = Type.terror;\n                    }\n                }\n\n                tret = tf.next;\n                tbret = tret.toBasetype();\n            }\n\n            if (inferRef) // deduce 'auto ref'\n            {\n                /* Determine \"refness\" of function return:\n                 * if it's an lvalue, return by ref, else return by value\n                 * https://dlang.org/spec/function.html#auto-ref-functions\n                 */\n\n                void turnOffRef()\n                {\n                    tf.isref = false;    // return by value\n                    tf.isreturn = false; // ignore 'return' attribute, whether explicit or inferred\n                    fd.storage_class &= ~STC.return_;\n                }\n\n                if (rs.exp.isLvalue())\n                {\n                    /* May return by ref\n                     */\n                    if (checkReturnEscapeRef(sc, rs.exp, true))\n                        turnOffRef();\n                    else if (!rs.exp.type.constConv(tf.next))\n                        turnOffRef();\n                }\n                else\n                    turnOffRef();\n\n                /* The \"refness\" is determined by all of return statements.\n                 * This means:\n                 *    return 3; return x;  // ok, x can be a value\n                 *    return x; return 3;  // ok, x can be a value\n                 */\n            }\n\n            // handle NRVO\n            if (fd.nrvo_can && rs.exp.op == TOK.variable)\n            {\n                VarExp ve = cast(VarExp)rs.exp;\n                VarDeclaration v = ve.var.isVarDeclaration();\n                if (tf.isref)\n                {\n                    // Function returns a reference\n                    if (!inferRef)\n                        fd.nrvo_can = 0;\n                }\n                else if (!v || v.isOut() || v.isRef())\n                    fd.nrvo_can = 0;\n                else if (fd.nrvo_var is null)\n                {\n                    if (!v.isDataseg() && !v.isParameter() && v.toParent2() == fd)\n                    {\n                        //printf(\"Setting nrvo to %s\\n\", v.toChars());\n                        fd.nrvo_var = v;\n                    }\n                    else\n                        fd.nrvo_can = 0;\n                }\n                else if (fd.nrvo_var != v)\n                    fd.nrvo_can = 0;\n            }\n            else //if (!exp.isLvalue())    // keep NRVO-ability\n                fd.nrvo_can = 0;\n        }\n        else\n        {\n            // handle NRVO\n            fd.nrvo_can = 0;\n\n            // infer return type\n            if (fd.inferRetType)\n            {\n                if (tf.next && tf.next.ty != Tvoid)\n                {\n                    if (tf.next.ty != Terror)\n                    {\n                        rs.error(\"mismatched function return type inference of `void` and `%s`\", tf.next.toChars());\n                    }\n                    errors = true;\n                    tf.next = Type.terror;\n                }\n                else\n                    tf.next = Type.tvoid;\n\n                    tret = tf.next;\n                tbret = tret.toBasetype();\n            }\n\n            if (inferRef) // deduce 'auto ref'\n                tf.isref = false;\n\n            if (tbret.ty != Tvoid) // if non-void return\n            {\n                if (tbret.ty != Terror)\n                    rs.error(\"`return` expression expected\");\n                errors = true;\n            }\n            else if (fd.isMain())\n            {\n                // main() returns 0, even if it returns void\n                rs.exp = new IntegerExp(0);\n            }\n        }\n\n        // If any branches have called a ctor, but this branch hasn't, it's an error\n        if (sc.ctorflow.callSuper & CSX.any_ctor && !(sc.ctorflow.callSuper & (CSX.this_ctor | CSX.super_ctor)))\n        {\n            rs.error(\"`return` without calling constructor\");\n            errors = true;\n        }\n\n        if (sc.ctorflow.fieldinit.length)       // if aggregate fields are being constructed\n        {\n            auto ad = fd.isMember2();\n            assert(ad);\n            foreach (i, v; ad.fields)\n            {\n                bool mustInit = (v.storage_class & STC.nodefaultctor || v.type.needsNested());\n                if (mustInit && !(sc.ctorflow.fieldinit[i].csx & CSX.this_ctor))\n                {\n                    rs.error(\"an earlier `return` statement skips field `%s` initialization\", v.toChars());\n                    errors = true;\n                }\n            }\n        }\n        sc.ctorflow.orCSX(CSX.return_);\n\n        if (errors)\n            return setError();\n\n        if (sc.fes)\n        {\n            if (!rs.exp)\n            {\n                // Send out \"case receiver\" statement to the foreach.\n                //  return exp;\n                Statement s = new ReturnStatement(Loc.initial, rs.exp);\n                sc.fes.cases.push(s);\n\n                // Immediately rewrite \"this\" return statement as:\n                //  return cases.dim+1;\n                rs.exp = new IntegerExp(sc.fes.cases.dim + 1);\n                if (e0)\n                {\n                    result = new CompoundStatement(rs.loc, new ExpStatement(rs.loc, e0), rs);\n                    return;\n                }\n                result = rs;\n                return;\n            }\n            else\n            {\n                fd.buildResultVar(null, rs.exp.type);\n                bool r = fd.vresult.checkNestedReference(sc, Loc.initial);\n                assert(!r); // vresult should be always accessible\n\n                // Send out \"case receiver\" statement to the foreach.\n                //  return vresult;\n                Statement s = new ReturnStatement(Loc.initial, new VarExp(Loc.initial, fd.vresult));\n                sc.fes.cases.push(s);\n\n                // Save receiver index for the later rewriting from:\n                //  return exp;\n                // to:\n                //  vresult = exp; retrun caseDim;\n                rs.caseDim = sc.fes.cases.dim + 1;\n            }\n        }\n        if (rs.exp)\n        {\n            if (!fd.returns)\n                fd.returns = new ReturnStatements();\n            fd.returns.push(rs);\n        }\n        if (e0)\n        {\n            result = new CompoundStatement(rs.loc, new ExpStatement(rs.loc, e0), rs);\n            return;\n        }\n        result = rs;\n    }\n\n    override void visit(BreakStatement bs)\n    {\n        /* https://dlang.org/spec/statement.html#break-statement\n         */\n\n        //printf(\"BreakStatement::semantic()\\n\");\n\n        // If:\n        //  break Identifier;\n        if (bs.ident)\n        {\n            bs.ident = fixupLabelName(sc, bs.ident);\n\n            FuncDeclaration thisfunc = sc.func;\n\n            for (Scope* scx = sc; scx; scx = scx.enclosing)\n            {\n                if (scx.func != thisfunc) // if in enclosing function\n                {\n                    if (sc.fes) // if this is the body of a foreach\n                    {\n                        /* Post this statement to the fes, and replace\n                         * it with a return value that caller will put into\n                         * a switch. Caller will figure out where the break\n                         * label actually is.\n                         * Case numbers start with 2, not 0, as 0 is continue\n                         * and 1 is break.\n                         */\n                        sc.fes.cases.push(bs);\n                        result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.dim + 1));\n                        return;\n                    }\n                    break; // can't break to it\n                }\n\n                LabelStatement ls = scx.slabel;\n                if (ls && ls.ident == bs.ident)\n                {\n                    Statement s = ls.statement;\n                    if (!s || !s.hasBreak())\n                        bs.error(\"label `%s` has no `break`\", bs.ident.toChars());\n                    else if (ls.tf != sc.tf)\n                        bs.error(\"cannot break out of `finally` block\");\n                    else\n                    {\n                        ls.breaks = true;\n                        result = bs;\n                        return;\n                    }\n                    return setError();\n                }\n            }\n            bs.error(\"enclosing label `%s` for `break` not found\", bs.ident.toChars());\n            return setError();\n        }\n        else if (!sc.sbreak)\n        {\n            if (sc.os && sc.os.tok != TOK.onScopeFailure)\n            {\n                bs.error(\"`break` is not inside `%s` bodies\", Token.toChars(sc.os.tok));\n            }\n            else if (sc.fes)\n            {\n                // Replace break; with return 1;\n                result = new ReturnStatement(Loc.initial, new IntegerExp(1));\n                return;\n            }\n            else\n                bs.error(\"`break` is not inside a loop or `switch`\");\n            return setError();\n        }\n        else if (sc.sbreak.isForwardingStatement())\n        {\n            bs.error(\"must use labeled `break` within `static foreach`\");\n        }\n        result = bs;\n    }\n\n    override void visit(ContinueStatement cs)\n    {\n        /* https://dlang.org/spec/statement.html#continue-statement\n         */\n\n        //printf(\"ContinueStatement::semantic() %p\\n\", cs);\n        if (cs.ident)\n        {\n            cs.ident = fixupLabelName(sc, cs.ident);\n\n            Scope* scx;\n            FuncDeclaration thisfunc = sc.func;\n\n            for (scx = sc; scx; scx = scx.enclosing)\n            {\n                LabelStatement ls;\n                if (scx.func != thisfunc) // if in enclosing function\n                {\n                    if (sc.fes) // if this is the body of a foreach\n                    {\n                        for (; scx; scx = scx.enclosing)\n                        {\n                            ls = scx.slabel;\n                            if (ls && ls.ident == cs.ident && ls.statement == sc.fes)\n                            {\n                                // Replace continue ident; with return 0;\n                                result = new ReturnStatement(Loc.initial, new IntegerExp(0));\n                                return;\n                            }\n                        }\n\n                        /* Post this statement to the fes, and replace\n                         * it with a return value that caller will put into\n                         * a switch. Caller will figure out where the break\n                         * label actually is.\n                         * Case numbers start with 2, not 0, as 0 is continue\n                         * and 1 is break.\n                         */\n                        sc.fes.cases.push(cs);\n                        result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.dim + 1));\n                        return;\n                    }\n                    break; // can't continue to it\n                }\n\n                ls = scx.slabel;\n                if (ls && ls.ident == cs.ident)\n                {\n                    Statement s = ls.statement;\n                    if (!s || !s.hasContinue())\n                        cs.error(\"label `%s` has no `continue`\", cs.ident.toChars());\n                    else if (ls.tf != sc.tf)\n                        cs.error(\"cannot continue out of `finally` block\");\n                    else\n                    {\n                        result = cs;\n                        return;\n                    }\n                    return setError();\n                }\n            }\n            cs.error(\"enclosing label `%s` for `continue` not found\", cs.ident.toChars());\n            return setError();\n        }\n        else if (!sc.scontinue)\n        {\n            if (sc.os && sc.os.tok != TOK.onScopeFailure)\n            {\n                cs.error(\"`continue` is not inside `%s` bodies\", Token.toChars(sc.os.tok));\n            }\n            else if (sc.fes)\n            {\n                // Replace continue; with return 0;\n                result = new ReturnStatement(Loc.initial, new IntegerExp(0));\n                return;\n            }\n            else\n                cs.error(\"`continue` is not inside a loop\");\n            return setError();\n        }\n        else if (sc.scontinue.isForwardingStatement())\n        {\n            cs.error(\"must use labeled `continue` within `static foreach`\");\n        }\n        result = cs;\n    }\n\n    override void visit(SynchronizedStatement ss)\n    {\n        /* https://dlang.org/spec/statement.html#synchronized-statement\n         */\n\n        if (ss.exp)\n        {\n            ss.exp = ss.exp.expressionSemantic(sc);\n            ss.exp = resolveProperties(sc, ss.exp);\n            ss.exp = ss.exp.optimize(WANTvalue);\n            ss.exp = checkGC(sc, ss.exp);\n            if (ss.exp.op == TOK.error)\n            {\n                if (ss._body)\n                    ss._body = ss._body.statementSemantic(sc);\n                return setError();\n            }\n\n            ClassDeclaration cd = ss.exp.type.isClassHandle();\n            if (!cd)\n            {\n                ss.error(\"can only `synchronize` on class objects, not `%s`\", ss.exp.type.toChars());\n                return setError();\n            }\n            else if (cd.isInterfaceDeclaration())\n            {\n                /* Cast the interface to an object, as the object has the monitor,\n                 * not the interface.\n                 */\n                if (!ClassDeclaration.object)\n                {\n                    ss.error(\"missing or corrupt object.d\");\n                    fatal();\n                }\n\n                Type t = ClassDeclaration.object.type;\n                t = t.typeSemantic(Loc.initial, sc).toBasetype();\n                assert(t.ty == Tclass);\n\n                ss.exp = new CastExp(ss.loc, ss.exp, t);\n                ss.exp = ss.exp.expressionSemantic(sc);\n            }\n            version (all)\n            {\n                /* Rewrite as:\n                 *  auto tmp = exp;\n                 *  _d_monitorenter(tmp);\n                 *  try { body } finally { _d_monitorexit(tmp); }\n                 */\n                auto tmp = copyToTemp(0, \"__sync\", ss.exp);\n                tmp.dsymbolSemantic(sc);\n\n                auto cs = new Statements();\n                cs.push(new ExpStatement(ss.loc, tmp));\n\n                auto args = new Parameters();\n                args.push(new Parameter(0, ClassDeclaration.object.type, null, null, null));\n\n                FuncDeclaration fdenter = FuncDeclaration.genCfunc(args, Type.tvoid, Id.monitorenter);\n                Expression e = new CallExp(ss.loc, fdenter, new VarExp(ss.loc, tmp));\n                e.type = Type.tvoid; // do not run semantic on e\n\n                cs.push(new ExpStatement(ss.loc, e));\n                FuncDeclaration fdexit = FuncDeclaration.genCfunc(args, Type.tvoid, Id.monitorexit);\n                e = new CallExp(ss.loc, fdexit, new VarExp(ss.loc, tmp));\n                e.type = Type.tvoid; // do not run semantic on e\n                Statement s = new ExpStatement(ss.loc, e);\n                s = new TryFinallyStatement(ss.loc, ss._body, s);\n                cs.push(s);\n\n                s = new CompoundStatement(ss.loc, cs);\n                result = s.statementSemantic(sc);\n            }\n        }\n        else\n        {\n            /* Generate our own critical section, then rewrite as:\n             *  static shared align(D_CRITICAL_SECTION.alignof) byte[D_CRITICAL_SECTION.sizeof] __critsec;\n             *  _d_criticalenter(&__critsec[0]);\n             *  try { body } finally { _d_criticalexit(&__critsec[0]); }\n             */\n            auto id = Identifier.generateId(\"__critsec\");\n            auto t = Type.tint8.sarrayOf(Target.ptrsize + Target.critsecsize());\n            auto tmp = new VarDeclaration(ss.loc, t, id, null);\n            tmp.storage_class |= STC.temp | STC.shared_ | STC.static_;\n            Expression tmpExp = new VarExp(ss.loc, tmp);\n\n            auto cs = new Statements();\n            cs.push(new ExpStatement(ss.loc, tmp));\n\n            /* This is just a dummy variable for \"goto skips declaration\" error.\n             * Backend optimizer could remove this unused variable.\n             */\n            auto v = new VarDeclaration(ss.loc, Type.tvoidptr, Identifier.generateId(\"__sync\"), null);\n            v.dsymbolSemantic(sc);\n            cs.push(new ExpStatement(ss.loc, v));\n\n            auto args = new Parameters();\n            args.push(new Parameter(0, t.pointerTo(), null, null, null));\n\n            FuncDeclaration fdenter = FuncDeclaration.genCfunc(args, Type.tvoid, Id.criticalenter, STC.nothrow_);\n            Expression int0 = new IntegerExp(ss.loc, dinteger_t(0), Type.tint8);\n            Expression e = new AddrExp(ss.loc, new IndexExp(ss.loc, tmpExp, int0));\n            e = e.expressionSemantic(sc);\n            e = new CallExp(ss.loc, fdenter, e);\n            e.type = Type.tvoid; // do not run semantic on e\n            cs.push(new ExpStatement(ss.loc, e));\n\n            FuncDeclaration fdexit = FuncDeclaration.genCfunc(args, Type.tvoid, Id.criticalexit, STC.nothrow_);\n            e = new AddrExp(ss.loc, new IndexExp(ss.loc, tmpExp, int0));\n            e = e.expressionSemantic(sc);\n            e = new CallExp(ss.loc, fdexit, e);\n            e.type = Type.tvoid; // do not run semantic on e\n            Statement s = new ExpStatement(ss.loc, e);\n            s = new TryFinallyStatement(ss.loc, ss._body, s);\n            cs.push(s);\n\n            s = new CompoundStatement(ss.loc, cs);\n            result = s.statementSemantic(sc);\n\n            // set the explicit __critsec alignment after semantic()\n            tmp.alignment = Target.ptrsize;\n        }\n    }\n\n    override void visit(WithStatement ws)\n    {\n        /* https://dlang.org/spec/statement.html#with-statement\n         */\n\n        ScopeDsymbol sym;\n        Initializer _init;\n\n        //printf(\"WithStatement::semantic()\\n\");\n        ws.exp = ws.exp.expressionSemantic(sc);\n        ws.exp = resolveProperties(sc, ws.exp);\n        ws.exp = ws.exp.optimize(WANTvalue);\n        ws.exp = checkGC(sc, ws.exp);\n        if (ws.exp.op == TOK.error)\n            return setError();\n        if (ws.exp.op == TOK.scope_)\n        {\n            sym = new WithScopeSymbol(ws);\n            sym.parent = sc.scopesym;\n            sym.endlinnum = ws.endloc.linnum;\n        }\n        else if (ws.exp.op == TOK.type)\n        {\n            Dsymbol s = (cast(TypeExp)ws.exp).type.toDsymbol(sc);\n            if (!s || !s.isScopeDsymbol())\n            {\n                ws.error(\"`with` type `%s` has no members\", ws.exp.toChars());\n                return setError();\n            }\n            sym = new WithScopeSymbol(ws);\n            sym.parent = sc.scopesym;\n            sym.endlinnum = ws.endloc.linnum;\n        }\n        else\n        {\n            Type t = ws.exp.type.toBasetype();\n\n            Expression olde = ws.exp;\n            if (t.ty == Tpointer)\n            {\n                ws.exp = new PtrExp(ws.loc, ws.exp);\n                ws.exp = ws.exp.expressionSemantic(sc);\n                t = ws.exp.type.toBasetype();\n            }\n\n            assert(t);\n            t = t.toBasetype();\n            if (t.isClassHandle())\n            {\n                _init = new ExpInitializer(ws.loc, ws.exp);\n                ws.wthis = new VarDeclaration(ws.loc, ws.exp.type, Id.withSym, _init);\n                ws.wthis.dsymbolSemantic(sc);\n\n                sym = new WithScopeSymbol(ws);\n                sym.parent = sc.scopesym;\n                sym.endlinnum = ws.endloc.linnum;\n            }\n            else if (t.ty == Tstruct)\n            {\n                if (!ws.exp.isLvalue())\n                {\n                    /* Re-write to\n                     * {\n                     *   auto __withtmp = exp\n                     *   with(__withtmp)\n                     *   {\n                     *     ...\n                     *   }\n                     * }\n                     */\n                    auto tmp = copyToTemp(0, \"__withtmp\", ws.exp);\n                    tmp.dsymbolSemantic(sc);\n                    auto es = new ExpStatement(ws.loc, tmp);\n                    ws.exp = new VarExp(ws.loc, tmp);\n                    Statement ss = new ScopeStatement(ws.loc, new CompoundStatement(ws.loc, es, ws), ws.endloc);\n                    result = ss.statementSemantic(sc);\n                    return;\n                }\n                Expression e = ws.exp.addressOf();\n                _init = new ExpInitializer(ws.loc, e);\n                ws.wthis = new VarDeclaration(ws.loc, e.type, Id.withSym, _init);\n                ws.wthis.dsymbolSemantic(sc);\n                sym = new WithScopeSymbol(ws);\n                // Need to set the scope to make use of resolveAliasThis\n                sym.setScope(sc);\n                sym.parent = sc.scopesym;\n                sym.endlinnum = ws.endloc.linnum;\n            }\n            else\n            {\n                ws.error(\"`with` expressions must be aggregate types or pointers to them, not `%s`\", olde.type.toChars());\n                return setError();\n            }\n        }\n\n        if (ws._body)\n        {\n            sym._scope = sc;\n            sc = sc.push(sym);\n            sc.insert(sym);\n            ws._body = ws._body.statementSemantic(sc);\n            sc.pop();\n            if (ws._body && ws._body.isErrorStatement())\n            {\n                result = ws._body;\n                return;\n            }\n        }\n\n        result = ws;\n    }\n\n    // https://dlang.org/spec/statement.html#TryStatement\n    override void visit(TryCatchStatement tcs)\n    {\n        //printf(\"TryCatchStatement.semantic()\\n\");\n\n        if (!global.params.useExceptions)\n        {\n            tcs.error(\"Cannot use try-catch statements with -betterC\");\n            return setError();\n        }\n\n        if (!ClassDeclaration.throwable)\n        {\n            tcs.error(\"Cannot use try-catch statements because `object.Throwable` was not declared\");\n            return setError();\n        }\n\n        uint flags;\n        enum FLAGcpp = 1;\n        enum FLAGd = 2;\n\n        tcs._body = tcs._body.semanticScope(sc, null, null);\n        assert(tcs._body);\n\n        /* Even if body is empty, still do semantic analysis on catches\n         */\n        bool catchErrors = false;\n        foreach (i, c; *tcs.catches)\n        {\n            c.catchSemantic(sc);\n            if (c.errors)\n            {\n                catchErrors = true;\n                continue;\n            }\n            auto cd = c.type.toBasetype().isClassHandle();\n            flags |= cd.isCPPclass() ? FLAGcpp : FLAGd;\n\n            // Determine if current catch 'hides' any previous catches\n            foreach (j; 0 .. i)\n            {\n                Catch cj = (*tcs.catches)[j];\n                const si = c.loc.toChars();\n                const sj = cj.loc.toChars();\n                if (c.type.toBasetype().implicitConvTo(cj.type.toBasetype()))\n                {\n                    tcs.error(\"`catch` at %s hides `catch` at %s\", sj, si);\n                    catchErrors = true;\n                }\n            }\n        }\n\n        if (sc.func)\n        {\n            sc.func.flags |= FUNCFLAG.hasCatches;\n            if (flags == (FLAGcpp | FLAGd))\n            {\n                tcs.error(\"cannot mix catching D and C++ exceptions in the same try-catch\");\n                catchErrors = true;\n            }\n        }\n\n        if (catchErrors)\n            return setError();\n\n        if (tcs._body.isErrorStatement())\n        {\n            result = tcs._body;\n            return;\n        }\n\n        /* If the try body never throws, we can eliminate any catches\n         * of recoverable exceptions.\n         */\n        if (!(tcs._body.blockExit(sc.func, false) & BE.throw_) && ClassDeclaration.exception)\n        {\n            foreach_reverse (i; 0 .. tcs.catches.dim)\n            {\n                Catch c = (*tcs.catches)[i];\n\n                /* If catch exception type is derived from Exception\n                 */\n                if (c.type.toBasetype().implicitConvTo(ClassDeclaration.exception.type) &&\n                    (!c.handler || !c.handler.comeFrom()))\n                {\n                    // Remove c from the array of catches\n                    tcs.catches.remove(i);\n                }\n            }\n        }\n\n        if (tcs.catches.dim == 0)\n        {\n            result = tcs._body.hasCode() ? tcs._body : null;\n            return;\n        }\n\n        result = tcs;\n    }\n\n    override void visit(TryFinallyStatement tfs)\n    {\n        //printf(\"TryFinallyStatement::semantic()\\n\");\n        tfs._body = tfs._body.statementSemantic(sc);\n\n        sc = sc.push();\n        sc.tf = tfs;\n        sc.sbreak = null;\n        sc.scontinue = null; // no break or continue out of finally block\n        tfs.finalbody = tfs.finalbody.semanticNoScope(sc);\n        sc.pop();\n\n        if (!tfs._body)\n        {\n            result = tfs.finalbody;\n            return;\n        }\n        if (!tfs.finalbody)\n        {\n            result = tfs._body;\n            return;\n        }\n\n        auto blockexit = tfs._body.blockExit(sc.func, false);\n\n        // if not worrying about exceptions\n        if (!(global.params.useExceptions && ClassDeclaration.throwable))\n            blockexit &= ~BE.throw_;            // don't worry about paths that otherwise may throw\n\n        // Don't care about paths that halt, either\n        if ((blockexit & ~BE.halt) == BE.fallthru)\n        {\n            result = new CompoundStatement(tfs.loc, tfs._body, tfs.finalbody);\n            return;\n        }\n        tfs.bodyFallsThru = (blockexit & BE.fallthru) != 0;\n        result = tfs;\n    }\n\n    override void visit(OnScopeStatement oss)\n    {\n        /* https://dlang.org/spec/statement.html#scope-guard-statement\n         */\n\n        if (oss.tok != TOK.onScopeExit)\n        {\n            // scope(success) and scope(failure) are rewritten to try-catch(-finally) statement,\n            // so the generated catch block cannot be placed in finally block.\n            // See also Catch::semantic.\n            if (sc.os && sc.os.tok != TOK.onScopeFailure)\n            {\n                // If enclosing is scope(success) or scope(exit), this will be placed in finally block.\n                oss.error(\"cannot put `%s` statement inside `%s`\", Token.toChars(oss.tok), Token.toChars(sc.os.tok));\n                return setError();\n            }\n            if (sc.tf)\n            {\n                oss.error(\"cannot put `%s` statement inside `finally` block\", Token.toChars(oss.tok));\n                return setError();\n            }\n        }\n\n        sc = sc.push();\n        sc.tf = null;\n        sc.os = oss;\n        if (oss.tok != TOK.onScopeFailure)\n        {\n            // Jump out from scope(failure) block is allowed.\n            sc.sbreak = null;\n            sc.scontinue = null;\n        }\n        oss.statement = oss.statement.semanticNoScope(sc);\n        sc.pop();\n\n        if (!oss.statement || oss.statement.isErrorStatement())\n        {\n            result = oss.statement;\n            return;\n        }\n        result = oss;\n    }\n\n    override void visit(ThrowStatement ts)\n    {\n        /* https://dlang.org/spec/statement.html#throw-statement\n         */\n\n        //printf(\"ThrowStatement::semantic()\\n\");\n\n        if (!global.params.useExceptions)\n        {\n            ts.error(\"Cannot use `throw` statements with -betterC\");\n            return setError();\n        }\n\n        if (!ClassDeclaration.throwable)\n        {\n            ts.error(\"Cannot use `throw` statements because `object.Throwable` was not declared\");\n            return setError();\n        }\n\n        FuncDeclaration fd = sc.parent.isFuncDeclaration();\n        fd.hasReturnExp |= 2;\n\n        if (ts.exp.op == TOK.new_)\n        {\n            NewExp ne = cast(NewExp)ts.exp;\n            ne.thrownew = true;\n        }\n\n        ts.exp = ts.exp.expressionSemantic(sc);\n        ts.exp = resolveProperties(sc, ts.exp);\n        ts.exp = checkGC(sc, ts.exp);\n        if (ts.exp.op == TOK.error)\n            return setError();\n\n        checkThrowEscape(sc, ts.exp, false);\n\n        ClassDeclaration cd = ts.exp.type.toBasetype().isClassHandle();\n        if (!cd || ((cd != ClassDeclaration.throwable) && !ClassDeclaration.throwable.isBaseOf(cd, null)))\n        {\n            ts.error(\"can only throw class objects derived from `Throwable`, not type `%s`\", ts.exp.type.toChars());\n            return setError();\n        }\n\n        result = ts;\n    }\n\n    override void visit(DebugStatement ds)\n    {\n        if (ds.statement)\n        {\n            sc = sc.push();\n            sc.flags |= SCOPE.debug_;\n            ds.statement = ds.statement.statementSemantic(sc);\n            sc.pop();\n        }\n        result = ds.statement;\n    }\n\n    override void visit(GotoStatement gs)\n    {\n        /* https://dlang.org/spec/statement.html#goto-statement\n         */\n\n        //printf(\"GotoStatement::semantic()\\n\");\n        FuncDeclaration fd = sc.func;\n\n        gs.ident = fixupLabelName(sc, gs.ident);\n        gs.label = fd.searchLabel(gs.ident);\n        gs.tf = sc.tf;\n        gs.os = sc.os;\n        gs.lastVar = sc.lastVar;\n\n        if (!gs.label.statement && sc.fes)\n        {\n            /* Either the goto label is forward referenced or it\n             * is in the function that the enclosing foreach is in.\n             * Can't know yet, so wrap the goto in a scope statement\n             * so we can patch it later, and add it to a 'look at this later'\n             * list.\n             */\n            auto ss = new ScopeStatement(gs.loc, gs, gs.loc);\n            sc.fes.gotos.push(ss); // 'look at this later' list\n            result = ss;\n            return;\n        }\n\n        // Add to fwdref list to check later\n        if (!gs.label.statement)\n        {\n            if (!fd.gotos)\n                fd.gotos = new GotoStatements();\n            fd.gotos.push(gs);\n        }\n        else if (gs.checkLabel())\n            return setError();\n\n        result = gs;\n    }\n\n    override void visit(LabelStatement ls)\n    {\n        //printf(\"LabelStatement::semantic()\\n\");\n        FuncDeclaration fd = sc.parent.isFuncDeclaration();\n\n        ls.ident = fixupLabelName(sc, ls.ident);\n        ls.tf = sc.tf;\n        ls.os = sc.os;\n        ls.lastVar = sc.lastVar;\n\n        LabelDsymbol ls2 = fd.searchLabel(ls.ident);\n        if (ls2.statement)\n        {\n            ls.error(\"label `%s` already defined\", ls2.toChars());\n            return setError();\n        }\n        else\n            ls2.statement = ls;\n\n        sc = sc.push();\n        sc.scopesym = sc.enclosing.scopesym;\n\n        sc.ctorflow.orCSX(CSX.label);\n\n        sc.slabel = ls;\n        if (ls.statement)\n            ls.statement = ls.statement.statementSemantic(sc);\n        sc.pop();\n\n        result = ls;\n    }\n\n    override void visit(AsmStatement s)\n    {\n        /* https://dlang.org/spec/statement.html#asm\n         */\n\n        result = asmSemantic(s, sc);\n    }\n\n    override void visit(CompoundAsmStatement cas)\n    {\n        // Apply postfix attributes of the asm block to each statement.\n        sc = sc.push();\n        sc.stc |= cas.stc;\n        foreach (ref s; *cas.statements)\n        {\n            s = s ? s.statementSemantic(sc) : null;\n        }\n\n        assert(sc.func);\n        // use setImpure/setGC when the deprecation cycle is over\n        PURE purity;\n        if (!(cas.stc & STC.pure_) && (purity = sc.func.isPureBypassingInference()) != PURE.impure && purity != PURE.fwdref)\n            cas.deprecation(\"`asm` statement is assumed to be impure - mark it with `pure` if it is not\");\n        if (!(cas.stc & STC.nogc) && sc.func.isNogcBypassingInference())\n            cas.deprecation(\"`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not\");\n        if (!(cas.stc & (STC.trusted | STC.safe)) && sc.func.setUnsafe())\n            cas.error(\"`asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not\");\n\n        sc.pop();\n        result = cas;\n    }\n\n    override void visit(ImportStatement imps)\n    {\n        /* https://dlang.org/spec/module.html#ImportDeclaration\n         */\n\n        foreach (i; 0 .. imps.imports.dim)\n        {\n            Import s = (*imps.imports)[i].isImport();\n            assert(!s.aliasdecls.dim);\n            foreach (j, name; s.names)\n            {\n                Identifier _alias = s.aliases[j];\n                if (!_alias)\n                    _alias = name;\n\n                auto tname = new TypeIdentifier(s.loc, name);\n                auto ad = new AliasDeclaration(s.loc, _alias, tname);\n                ad._import = s;\n                s.aliasdecls.push(ad);\n            }\n\n            s.dsymbolSemantic(sc);\n            Module.addDeferredSemantic2(s);     // https://issues.dlang.org/show_bug.cgi?id=14666\n            sc.insert(s);\n\n            foreach (aliasdecl; s.aliasdecls)\n            {\n                sc.insert(aliasdecl);\n            }\n        }\n        result = imps;\n    }\n}\n\nvoid catchSemantic(Catch c, Scope* sc)\n{\n    //printf(\"Catch::semantic(%s)\\n\", ident.toChars());\n\n    if (sc.os && sc.os.tok != TOK.onScopeFailure)\n    {\n        // If enclosing is scope(success) or scope(exit), this will be placed in finally block.\n        error(c.loc, \"cannot put `catch` statement inside `%s`\", Token.toChars(sc.os.tok));\n        c.errors = true;\n    }\n    if (sc.tf)\n    {\n        /* This is because the _d_local_unwind() gets the stack munged\n         * up on this. The workaround is to place any try-catches into\n         * a separate function, and call that.\n         * To fix, have the compiler automatically convert the finally\n         * body into a nested function.\n         */\n        error(c.loc, \"cannot put `catch` statement inside `finally` block\");\n        c.errors = true;\n    }\n\n    auto sym = new ScopeDsymbol();\n    sym.parent = sc.scopesym;\n    sc = sc.push(sym);\n\n    if (!c.type)\n    {\n        error(c.loc, \"`catch` statement without an exception specification is deprecated\");\n        errorSupplemental(c.loc, \"use `catch(Throwable)` for old behavior\");\n        c.errors = true;\n\n        // reference .object.Throwable\n        c.type = getThrowable();\n    }\n    c.type = c.type.typeSemantic(c.loc, sc);\n    if (c.type == Type.terror)\n        c.errors = true;\n    else\n    {\n        StorageClass stc;\n        auto cd = c.type.toBasetype().isClassHandle();\n        if (!cd)\n        {\n            error(c.loc, \"can only catch class objects, not `%s`\", c.type.toChars());\n            c.errors = true;\n        }\n        else if (cd.isCPPclass())\n        {\n            if (!Target.cppExceptions)\n            {\n                error(c.loc, \"catching C++ class objects not supported for this target\");\n                c.errors = true;\n            }\n            if (sc.func && !sc.intypeof && !c.internalCatch && sc.func.setUnsafe())\n            {\n                error(c.loc, \"cannot catch C++ class objects in `@safe` code\");\n                c.errors = true;\n            }\n        }\n        else if (cd != ClassDeclaration.throwable && !ClassDeclaration.throwable.isBaseOf(cd, null))\n        {\n            error(c.loc, \"can only catch class objects derived from `Throwable`, not `%s`\", c.type.toChars());\n            c.errors = true;\n        }\n        else if (sc.func && !sc.intypeof && !c.internalCatch && ClassDeclaration.exception &&\n                 cd != ClassDeclaration.exception && !ClassDeclaration.exception.isBaseOf(cd, null) &&\n                 sc.func.setUnsafe())\n        {\n            error(c.loc, \"can only catch class objects derived from `Exception` in `@safe` code, not `%s`\", c.type.toChars());\n            c.errors = true;\n        }\n        else if (global.params.ehnogc)\n        {\n            stc |= STC.scope_;\n        }\n\n        if (c.ident)\n        {\n            c.var = new VarDeclaration(c.loc, c.type, c.ident, null, stc);\n            c.var.iscatchvar = true;\n            c.var.dsymbolSemantic(sc);\n            sc.insert(c.var);\n\n            if (global.params.ehnogc && stc & STC.scope_)\n            {\n                /* Add a destructor for c.var\n                 * try { handler } finally { if (!__ctfe) _d_delThrowable(var); }\n                 */\n                assert(!c.var.edtor);           // ensure we didn't create one in callScopeDtor()\n\n                Loc loc = c.loc;\n                Expression e = new VarExp(loc, c.var);\n                e = new CallExp(loc, new IdentifierExp(loc, Id._d_delThrowable), e);\n\n                Expression ec = new IdentifierExp(loc, Id.ctfe);\n                ec = new NotExp(loc, ec);\n                Statement s = new IfStatement(loc, null, ec, new ExpStatement(loc, e), null, loc);\n                c.handler = new TryFinallyStatement(loc, c.handler, s);\n            }\n\n        }\n        c.handler = c.handler.statementSemantic(sc);\n        if (c.handler && c.handler.isErrorStatement())\n            c.errors = true;\n    }\n\n    sc.pop();\n}\n\nStatement semanticNoScope(Statement s, Scope* sc)\n{\n    //printf(\"Statement::semanticNoScope() %s\\n\", toChars());\n    if (!s.isCompoundStatement() && !s.isScopeStatement())\n    {\n        s = new CompoundStatement(s.loc, s); // so scopeCode() gets called\n    }\n    s = s.statementSemantic(sc);\n    return s;\n}\n\n// Same as semanticNoScope(), but do create a new scope\nStatement semanticScope(Statement s, Scope* sc, Statement sbreak, Statement scontinue)\n{\n    auto sym = new ScopeDsymbol();\n    sym.parent = sc.scopesym;\n    Scope* scd = sc.push(sym);\n    if (sbreak)\n        scd.sbreak = sbreak;\n    if (scontinue)\n        scd.scontinue = scontinue;\n    s = s.semanticNoScope(scd);\n    scd.pop();\n    return s;\n}\n\n\n/*******************\n * Determines additional argument types for makeTupleForeach.\n */\nstatic template TupleForeachArgs(bool isStatic, bool isDecl)\n{\n    alias Seq(T...)=T;\n    static if(isStatic) alias T = Seq!(bool);\n    else alias T = Seq!();\n    static if(!isDecl) alias TupleForeachArgs = T;\n    else alias TupleForeachArgs = Seq!(Dsymbols*,T);\n}\n\n/*******************\n * Determines the return type of makeTupleForeach.\n */\nstatic template TupleForeachRet(bool isStatic, bool isDecl)\n{\n    alias Seq(T...)=T;\n    static if(!isDecl) alias TupleForeachRet = Statement;\n    else alias TupleForeachRet = Dsymbols*;\n}\n\n\n/*******************\n * See StatementSemanticVisitor.makeTupleForeach.  This is a simple\n * wrapper that returns the generated statements/declarations.\n */\nTupleForeachRet!(isStatic, isDecl) makeTupleForeach(bool isStatic, bool isDecl)(Scope* sc, ForeachStatement fs, TupleForeachArgs!(isStatic, isDecl) args)\n{\n    scope v = new StatementSemanticVisitor(sc);\n    static if(!isDecl)\n    {\n        v.makeTupleForeach!(isStatic, isDecl)(fs, args);\n        return v.result;\n    }\n    else\n    {\n        return v.makeTupleForeach!(isStatic, isDecl)(fs, args);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/staticassert.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/staticassert.d, _staticassert.d)\n * Documentation:  https://dlang.org/phobos/dmd_staticassert.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/staticassert.d\n */\n\nmodule dmd.staticassert;\n\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.expression;\nimport dmd.globals;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.visitor;\n\n/***********************************************************\n */\nextern (C++) final class StaticAssert : Dsymbol\n{\n    Expression exp;\n    Expression msg;\n\n    extern (D) this(const ref Loc loc, Expression exp, Expression msg)\n    {\n        super(Id.empty);\n        this.loc = loc;\n        this.exp = exp;\n        this.msg = msg;\n    }\n\n    override Dsymbol syntaxCopy(Dsymbol s)\n    {\n        assert(!s);\n        return new StaticAssert(loc, exp.syntaxCopy(), msg ? msg.syntaxCopy() : null);\n    }\n\n    override void addMember(Scope* sc, ScopeDsymbol sds)\n    {\n        // we didn't add anything\n    }\n\n    override bool oneMember(Dsymbol* ps, Identifier ident)\n    {\n        //printf(\"StaticAssert::oneMember())\\n\");\n        *ps = null;\n        return true;\n    }\n\n    override const(char)* kind() const\n    {\n        return \"static assert\";\n    }\n\n    override void accept(Visitor v)\n    {\n        v.visit(this);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/staticcond.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/staticcond.d, _staticcond.d)\n * Documentation:  https://dlang.org/phobos/dmd_staticcond.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/staticcond.d\n */\n\nmodule dmd.staticcond;\n\nimport dmd.aliasthis;\nimport dmd.arraytypes;\nimport dmd.dmodule;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.globals;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.tokens;\nimport dmd.utils;\n\n\n\n/********************************************\n * Semantically analyze and then evaluate a static condition at compile time.\n * This is special because short circuit operators &&, || and ?: at the top\n * level are not semantically analyzed if the result of the expression is not\n * necessary.\n * Params:\n *      sc  = instantiating scope\n *      exp = original expression, for error messages\n *      e =  resulting expression\n *      errors = set to `true` if errors occurred\n * Returns:\n *      true if evaluates to true\n */\n\nbool evalStaticCondition(Scope* sc, Expression exp, Expression e, ref bool errors)\n{\n    if (e.op == TOK.andAnd || e.op == TOK.orOr)\n    {\n        LogicalExp aae = cast(LogicalExp)e;\n        bool result = evalStaticCondition(sc, exp, aae.e1, errors);\n        if (errors)\n            return false;\n        if (e.op == TOK.andAnd)\n        {\n            if (!result)\n                return false;\n        }\n        else\n        {\n            if (result)\n                return true;\n        }\n        result = evalStaticCondition(sc, exp, aae.e2, errors);\n        return !errors && result;\n    }\n\n    if (e.op == TOK.question)\n    {\n        CondExp ce = cast(CondExp)e;\n        bool result = evalStaticCondition(sc, exp, ce.econd, errors);\n        if (errors)\n            return false;\n        Expression leg = result ? ce.e1 : ce.e2;\n        result = evalStaticCondition(sc, exp, leg, errors);\n        return !errors && result;\n    }\n\n    uint nerrors = global.errors;\n\n    sc = sc.startCTFE();\n    sc.flags |= SCOPE.condition;\n\n    e = e.expressionSemantic(sc);\n    e = resolveProperties(sc, e);\n\n    sc = sc.endCTFE();\n    e = e.optimize(WANTvalue);\n\n    if (nerrors != global.errors ||\n        e.op == TOK.error ||\n        e.type.toBasetype() == Type.terror)\n    {\n        errors = true;\n        return false;\n    }\n\n    e = resolveAliasThis(sc, e);\n\n    if (!e.type.isBoolean())\n    {\n        exp.error(\"expression `%s` of type `%s` does not have a boolean value\", exp.toChars(), e.type.toChars());\n        errors = true;\n        return false;\n    }\n\n    e = e.ctfeInterpret();\n\n    if (e.isBool(true))\n        return true;\n    else if (e.isBool(false))\n        return false;\n\n    e.error(\"expression `%s` is not constant\", e.toChars());\n    errors = true;\n    return false;\n}\n"
  },
  {
    "path": "gcc/d/dmd/target.d",
    "content": "/* target.d -- Target interface for the D front end.\n * Copyright (C) 2018 Free Software Foundation, Inc.\n *\n * GCC is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3, or (at your option)\n * any later version.\n *\n * GCC is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with GCC; see the file COPYING3.  If not see\n * <http://www.gnu.org/licenses/>.\n */\n\nmodule dmd.target;\n\nimport dmd.argtypes;\nimport dmd.dclass;\nimport dmd.dsymbol;\nimport dmd.expression;\nimport dmd.globals;\nimport dmd.mtype;\nimport dmd.tokens : TOK;\nimport dmd.root.ctfloat;\nimport dmd.root.outbuffer;\n\n/**\n * Describes a back-end target. At present it is incomplete, but in the future\n * it should grow to contain most or all target machine and target O/S specific\n * information.\n *\n * In many cases, calls to sizeof() can't be used directly for getting data type\n * sizes since cross compiling is supported and would end up using the host\n * sizes rather than the target sizes.\n */\nstruct Target\n{\n    extern (C++) __gshared\n    {\n        // D ABI\n        uint ptrsize;             /// size of a pointer in bytes\n        uint realsize;            /// size a real consumes in memory\n        uint realpad;             /// padding added to the CPU real size to bring it up to realsize\n        uint realalignsize;       /// alignment for reals\n        uint classinfosize;       /// size of `ClassInfo`\n        ulong maxStaticDataSize;  /// maximum size of static data\n\n        // C ABI\n        uint c_longsize;          /// size of a C `long` or `unsigned long` type\n        uint c_long_doublesize;   /// size of a C `long double`\n\n        // C++ ABI\n        bool reverseCppOverloads; /// set if overloaded functions are grouped and in reverse order (such as in dmc and cl)\n        bool cppExceptions;       /// set if catching C++ exceptions is supported\n        bool twoDtorInVtable;     /// target C++ ABI puts deleting and non-deleting destructor into vtable\n    }\n\n    /**\n     * Values representing all properties for floating point types\n     */\n    extern (C++) struct FPTypeProperties(T)\n    {\n        __gshared\n        {\n            real_t max;                         /// largest representable value that's not infinity\n            real_t min_normal;                  /// smallest representable normalized value that's not 0\n            real_t nan;                         /// NaN value\n            real_t snan;                        /// signalling NaN value\n            real_t infinity;                    /// infinity value\n            real_t epsilon;                     /// smallest increment to the value 1\n\n            d_int64 dig;                        /// number of decimal digits of precision\n            d_int64 mant_dig;                   /// number of bits in mantissa\n            d_int64 max_exp;                    /// maximum int value such that 2$(SUPERSCRIPT `max_exp-1`) is representable\n            d_int64 min_exp;                    /// minimum int value such that 2$(SUPERSCRIPT `min_exp-1`) is representable as a normalized value\n            d_int64 max_10_exp;                 /// maximum int value such that 10$(SUPERSCRIPT `max_10_exp` is representable)\n            d_int64 min_10_exp;                 /// minimum int value such that 10$(SUPERSCRIPT `min_10_exp`) is representable as a normalized value\n        }\n    }\n\n    ///\n    alias FloatProperties = FPTypeProperties!float;\n    ///\n    alias DoubleProperties = FPTypeProperties!double;\n    ///\n    alias RealProperties = FPTypeProperties!real_t;\n\n    /**\n     * Initialize the Target\n     */\n    extern (C++) static void _init();\n\n    /**\n     * Requested target memory alignment size of the given type.\n     * Params:\n     *      type = type to inspect\n     * Returns:\n     *      alignment in bytes\n     */\n    extern (C++) static uint alignsize(Type type);\n\n    /**\n     * Requested target field alignment size of the given type.\n     * Params:\n     *      type = type to inspect\n     * Returns:\n     *      alignment in bytes\n     */\n    extern (C++) static uint fieldalign(Type type);\n\n    /**\n     * Size of the target OS critical section.\n     * Returns:\n     *      size in bytes\n     */\n    extern (C++) static uint critsecsize();\n\n    /**\n     * Type for the `va_list` type for the target.\n     * NOTE: For Posix/x86_64 this returns the type which will really\n     * be used for passing an argument of type va_list.\n     * Returns:\n     *      `Type` that represents `va_list`.\n     */\n    extern (C++) static Type va_listType();\n\n    /**\n     * Checks whether the target supports a vector type.\n     * Params:\n     *      sz   = vector type size in bytes\n     *      type = vector element type\n     * Returns:\n     *      0   vector type is supported,\n     *      1   vector type is not supported on the target at all\n     *      2   vector element type is not supported\n     *      3   vector size is not supported\n     */\n    extern (C++) static int isVectorTypeSupported(int sz, Type type);\n\n    /**\n     * Checks whether the target supports the given operation for vectors.\n     * Params:\n     *      type = target type of operation\n     *      op   = the unary or binary op being done on the `type`\n     *      t2   = type of second operand if `op` is a binary operation\n     * Returns:\n     *      true if the operation is supported or type is not a vector\n     */\n    extern (C++) static bool isVectorOpSupported(Type type, TOK op, Type t2 = null);\n\n    /**\n     * Mangle the given symbol for C++ ABI.\n     * Params:\n     *      s = declaration with C++ linkage\n     * Returns:\n     *      string mangling of symbol\n     */\n    extern (C++) static const(char)* toCppMangle(Dsymbol s);\n\n    /**\n     * Get RTTI mangling of the given class declaration for C++ ABI.\n     * Params:\n     *      cd = class with C++ linkage\n     * Returns:\n     *      string mangling of C++ typeinfo\n     */\n    extern (C++) static const(char)* cppTypeInfoMangle(ClassDeclaration cd);\n\n    /**\n     * Gets vendor-specific type mangling for C++ ABI.\n     * Params:\n     *      t = type to inspect\n     * Returns:\n     *      string if type is mangled specially on target\n     *      null if unhandled\n     */\n    extern (C++) static const(char)* cppTypeMangle(Type t);\n\n    /**\n     * Get the type that will really be used for passing the given argument\n     * to an `extern(C++)` function.\n     * Params:\n     *      p = parameter to be passed.\n     * Returns:\n     *      `Type` to use for parameter `p`.\n     */\n    extern (C++) static Type cppParameterType(Parameter p);\n\n    /**\n     * Default system linkage for the target.\n     * Returns:\n     *      `LINK` to use for `extern(System)`\n     */\n    extern (C++) static LINK systemLinkage();\n\n    /**\n     * Describes how an argument type is passed to a function on target.\n     * Params:\n     *      t = type to break down\n     * Returns:\n     *      tuple of types if type is passed in one or more registers\n     *      empty tuple if type is always passed on the stack\n     */\n    extern (C++) static TypeTuple toArgTypes(Type t)\n    {\n        return .toArgTypes(t);\n    }\n\n    /**\n     * Determine return style of function - whether in registers or\n     * through a hidden pointer to the caller's stack.\n     * Params:\n     *   tf = function type to check\n     *   needsThis = true if the function type is for a non-static member function\n     * Returns:\n     *   true if return value from function is on the stack\n     */\n    extern (C++) static bool isReturnOnStack(TypeFunction tf, bool needsThis);\n\n    /***\n     * Determine the size a value of type `t` will be when it\n     * is passed on the function parameter stack.\n     * Params:\n     *  loc = location to use for error messages\n     *  t = type of parameter\n     * Returns:\n     *  size used on parameter stack\n     */\n    extern (C++) static ulong parameterSize(const ref Loc loc, Type t);\n\n    /**\n     * Get targetInfo by key\n     * Params:\n     *  name = name of targetInfo to get\n     *  loc = location to use for error messages\n     * Returns:\n     *  Expression for the requested targetInfo\n     */\n    extern (C++) static Expression getTargetInfo(const(char)* name, const ref Loc loc);\n}\n"
  },
  {
    "path": "gcc/d/dmd/target.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 2013-2018 by The D Language Foundation, All Rights Reserved\n * written by Iain Buclaw\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/target.h\n */\n\n#pragma once\n\n// This file contains a data structure that describes a back-end target.\n// At present it is incomplete, but in future it should grow to contain\n// most or all target machine and target O/S specific information.\n#include \"globals.h\"\n#include \"tokens.h\"\n\nclass ClassDeclaration;\nclass Dsymbol;\nclass Expression;\nclass Parameter;\nclass Type;\nclass TypeTuple;\nclass TypeFunction;\n\nstruct Target\n{\n    // D ABI\n    static unsigned ptrsize;\n    static unsigned realsize;           // size a real consumes in memory\n    static unsigned realpad;            // 'padding' added to the CPU real size to bring it up to realsize\n    static unsigned realalignsize;      // alignment for reals\n    static unsigned classinfosize;      // size of 'ClassInfo'\n    static unsigned long long maxStaticDataSize;  // maximum size of static data\n\n    // C ABI\n    static unsigned c_longsize;         // size of a C 'long' or 'unsigned long' type\n    static unsigned c_long_doublesize;  // size of a C 'long double'\n\n    // C++ ABI\n    static bool reverseCppOverloads;    // with dmc and cl, overloaded functions are grouped and in reverse order\n    static bool cppExceptions;          // set if catching C++ exceptions is supported\n    static bool twoDtorInVtable;        // target C++ ABI puts deleting and non-deleting destructor into vtable\n\n    template <typename T>\n    struct FPTypeProperties\n    {\n        static real_t max;\n        static real_t min_normal;\n        static real_t nan;\n        static real_t snan;\n        static real_t infinity;\n        static real_t epsilon;\n\n        static d_int64 dig;\n        static d_int64 mant_dig;\n        static d_int64 max_exp;\n        static d_int64 min_exp;\n        static d_int64 max_10_exp;\n        static d_int64 min_10_exp;\n    };\n\n    typedef FPTypeProperties<float> FloatProperties;\n    typedef FPTypeProperties<double> DoubleProperties;\n    typedef FPTypeProperties<real_t> RealProperties;\n\n    static void _init();\n    // Type sizes and support.\n    static unsigned alignsize(Type *type);\n    static unsigned fieldalign(Type *type);\n    static unsigned critsecsize();\n    static Type *va_listType();  // get type of va_list\n    static int isVectorTypeSupported(int sz, Type *type);\n    static bool isVectorOpSupported(Type *type, TOK op, Type *t2 = NULL);\n    // ABI and backend.\n    static const char *toCppMangle(Dsymbol *s);\n    static const char *cppTypeInfoMangle(ClassDeclaration *cd);\n    static const char *cppTypeMangle(Type *t);\n    static Type *cppParameterType(Parameter *p);\n    static LINK systemLinkage();\n    static TypeTuple *toArgTypes(Type *t);\n    static bool isReturnOnStack(TypeFunction *tf, bool needsThis);\n    static d_uns64 parameterSize(const Loc& loc, Type *t);\n    static Expression *getTargetInfo(const char* name, const Loc& loc);\n};\n"
  },
  {
    "path": "gcc/d/dmd/template.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/template.h\n */\n\n#pragma once\n\n#include \"arraytypes.h\"\n#include \"dsymbol.h\"\n\nclass Identifier;\nclass TemplateInstance;\nclass TemplateParameter;\nclass TemplateTypeParameter;\nclass TemplateThisParameter;\nclass TemplateValueParameter;\nclass TemplateAliasParameter;\nclass TemplateTupleParameter;\nclass Type;\nclass TypeQualified;\nstruct Scope;\nclass Expression;\nclass FuncDeclaration;\nclass Parameter;\n\nclass Tuple : public RootObject\n{\npublic:\n    Objects objects;\n\n    // kludge for template.isType()\n    int dyncast() const { return DYNCAST_TUPLE; }\n\n    const char *toChars() { return objects.toChars(); }\n};\n\nstruct TemplatePrevious\n{\n    TemplatePrevious *prev;\n    Scope *sc;\n    Objects *dedargs;\n};\n\nclass TemplateDeclaration : public ScopeDsymbol\n{\npublic:\n    TemplateParameters *parameters;     // array of TemplateParameter's\n\n    TemplateParameters *origParameters; // originals for Ddoc\n    Expression *constraint;\n\n    // Hash table to look up TemplateInstance's of this TemplateDeclaration\n    void *instances;\n\n    TemplateDeclaration *overnext;      // next overloaded TemplateDeclaration\n    TemplateDeclaration *overroot;      // first in overnext list\n    FuncDeclaration *funcroot;          // first function in unified overload list\n\n    Dsymbol *onemember;         // if !=NULL then one member of this template\n\n    bool literal;               // this template declaration is a literal\n    bool ismixin;               // template declaration is only to be used as a mixin\n    bool isstatic;              // this is static template declaration\n    Prot protection;\n    int inuse;                  // for recursive expansion detection\n\n    TemplatePrevious *previous;         // threaded list of previous instantiation attempts on stack\n\n    Dsymbol *syntaxCopy(Dsymbol *);\n    bool overloadInsert(Dsymbol *s);\n    bool hasStaticCtorOrDtor();\n    const char *kind() const;\n    const char *toChars();\n\n    Prot prot();\n\n    MATCH leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs);\n    RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o);\n\n    TemplateDeclaration *isTemplateDeclaration() { return this; }\n\n    TemplateTupleParameter *isVariadic();\n    bool isOverloadable();\n\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/* For type-parameter:\n *  template Foo(ident)             // specType is set to NULL\n *  template Foo(ident : specType)\n * For value-parameter:\n *  template Foo(valType ident)     // specValue is set to NULL\n *  template Foo(valType ident : specValue)\n * For alias-parameter:\n *  template Foo(alias ident)\n * For this-parameter:\n *  template Foo(this ident)\n */\nclass TemplateParameter : public RootObject\n{\npublic:\n    Loc loc;\n    Identifier *ident;\n\n    /* True if this is a part of precedent parameter specialization pattern.\n     *\n     *  template A(T : X!TL, alias X, TL...) {}\n     *  // X and TL are dependent template parameter\n     *\n     * A dependent template parameter should return MATCHexact in matchArg()\n     * to respect the match level of the corresponding precedent parameter.\n     */\n    bool dependent;\n\n    virtual TemplateTypeParameter  *isTemplateTypeParameter();\n    virtual TemplateValueParameter *isTemplateValueParameter();\n    virtual TemplateAliasParameter *isTemplateAliasParameter();\n    virtual TemplateThisParameter *isTemplateThisParameter();\n    virtual TemplateTupleParameter *isTemplateTupleParameter();\n\n    virtual TemplateParameter *syntaxCopy() = 0;\n    virtual bool declareParameter(Scope *sc) = 0;\n    virtual void print(RootObject *oarg, RootObject *oded) = 0;\n    virtual RootObject *specialization() = 0;\n    virtual RootObject *defaultArg(Loc instLoc, Scope *sc) = 0;\n    virtual bool hasDefaultArg() = 0;\n\n    /* Match actual argument against parameter.\n     */\n    virtual MATCH matchArg(Loc instLoc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);\n    virtual MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0;\n\n    /* Create dummy argument based on parameter.\n     */\n    virtual void *dummyArg() = 0;\n    virtual void accept(Visitor *v) { v->visit(this); }\n};\n\n/* Syntax:\n *  ident : specType = defaultType\n */\nclass TemplateTypeParameter : public TemplateParameter\n{\n    using TemplateParameter::matchArg;\npublic:\n    Type *specType;     // type parameter: if !=NULL, this is the type specialization\n    Type *defaultType;\n\n    TemplateTypeParameter *isTemplateTypeParameter();\n    TemplateParameter *syntaxCopy();\n    bool declareParameter(Scope *sc);\n    void print(RootObject *oarg, RootObject *oded);\n    RootObject *specialization();\n    RootObject *defaultArg(Loc instLoc, Scope *sc);\n    bool hasDefaultArg();\n    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);\n    void *dummyArg();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/* Syntax:\n *  this ident : specType = defaultType\n */\nclass TemplateThisParameter : public TemplateTypeParameter\n{\npublic:\n    TemplateThisParameter *isTemplateThisParameter();\n    TemplateParameter *syntaxCopy();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/* Syntax:\n *  valType ident : specValue = defaultValue\n */\nclass TemplateValueParameter : public TemplateParameter\n{\n    using TemplateParameter::matchArg;\npublic:\n    Type *valType;\n    Expression *specValue;\n    Expression *defaultValue;\n\n    TemplateValueParameter *isTemplateValueParameter();\n    TemplateParameter *syntaxCopy();\n    bool declareParameter(Scope *sc);\n    void print(RootObject *oarg, RootObject *oded);\n    RootObject *specialization();\n    RootObject *defaultArg(Loc instLoc, Scope *sc);\n    bool hasDefaultArg();\n    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);\n    void *dummyArg();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/* Syntax:\n *  specType ident : specAlias = defaultAlias\n */\nclass TemplateAliasParameter : public TemplateParameter\n{\n    using TemplateParameter::matchArg;\npublic:\n    Type *specType;\n    RootObject *specAlias;\n    RootObject *defaultAlias;\n\n    TemplateAliasParameter *isTemplateAliasParameter();\n    TemplateParameter *syntaxCopy();\n    bool declareParameter(Scope *sc);\n    void print(RootObject *oarg, RootObject *oded);\n    RootObject *specialization();\n    RootObject *defaultArg(Loc instLoc, Scope *sc);\n    bool hasDefaultArg();\n    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);\n    void *dummyArg();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/* Syntax:\n *  ident ...\n */\nclass TemplateTupleParameter : public TemplateParameter\n{\npublic:\n    TemplateTupleParameter *isTemplateTupleParameter();\n    TemplateParameter *syntaxCopy();\n    bool declareParameter(Scope *sc);\n    void print(RootObject *oarg, RootObject *oded);\n    RootObject *specialization();\n    RootObject *defaultArg(Loc instLoc, Scope *sc);\n    bool hasDefaultArg();\n    MATCH matchArg(Loc loc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);\n    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);\n    void *dummyArg();\n    void accept(Visitor *v) { v->visit(this); }\n};\n\n/* Given:\n *  foo!(args) =>\n *      name = foo\n *      tiargs = args\n */\nclass TemplateInstance : public ScopeDsymbol\n{\npublic:\n    Identifier *name;\n\n    // Array of Types/Expressions of template\n    // instance arguments [int*, char, 10*10]\n    Objects *tiargs;\n\n    // Array of Types/Expressions corresponding\n    // to TemplateDeclaration.parameters\n    // [int, char, 100]\n    Objects tdtypes;\n\n    Dsymbol *tempdecl;                  // referenced by foo.bar.abc\n    Dsymbol *enclosing;                 // if referencing local symbols, this is the context\n    Dsymbol *aliasdecl;                 // !=NULL if instance is an alias for its sole member\n    TemplateInstance *inst;             // refer to existing instance\n    ScopeDsymbol *argsym;               // argument symbol table\n    int inuse;                          // for recursive expansion detection\n    int nest;                           // for recursive pretty printing detection\n    bool semantictiargsdone;            // has semanticTiargs() been done?\n    bool havetempdecl;                  // if used second constructor\n    bool gagged;                        // if the instantiation is done with error gagging\n    hash_t hash;                        // cached result of toHash()\n    Expressions *fargs;                 // for function template, these are the function arguments\n\n    TemplateInstances* deferred;\n\n    Module *memberOf;                   // if !null, then this TemplateInstance appears in memberOf.members[]\n\n    // Used to determine the instance needs code generation.\n    // Note that these are inaccurate until semantic analysis phase completed.\n    TemplateInstance *tinst;            // enclosing template instance\n    TemplateInstance *tnext;            // non-first instantiated instances\n    Module *minst;                      // the top module that instantiated this instance\n\n    Dsymbol *syntaxCopy(Dsymbol *);\n    Dsymbol *toAlias();                 // resolve real symbol\n    const char *kind() const;\n    bool oneMember(Dsymbol **ps, Identifier *ident);\n    const char *toChars();\n    const char* toPrettyCharsHelper();\n    void printInstantiationTrace();\n    Identifier *getIdent();\n    int compare(RootObject *o);\n    hash_t toHash();\n\n    bool needsCodegen();\n\n    TemplateInstance *isTemplateInstance() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nclass TemplateMixin : public TemplateInstance\n{\npublic:\n    TypeQualified *tqual;\n\n    Dsymbol *syntaxCopy(Dsymbol *s);\n    const char *kind() const;\n    bool oneMember(Dsymbol **ps, Identifier *ident);\n    int apply(Dsymbol_apply_ft_t fp, void *param);\n    bool hasPointers();\n    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);\n    const char *toChars();\n\n    TemplateMixin *isTemplateMixin() { return this; }\n    void accept(Visitor *v) { v->visit(this); }\n};\n\nExpression *isExpression(RootObject *o);\nDsymbol *isDsymbol(RootObject *o);\nType *isType(RootObject *o);\nTuple *isTuple(RootObject *o);\nParameter *isParameter(RootObject *o);\nTemplateParameter *isTemplateParameter(RootObject *o);\nbool arrayObjectIsError(const Objects *args);\nbool isError(const RootObject *const o);\nType *getType(RootObject *o);\nDsymbol *getDsymbol(RootObject *o);\n\nRootObject *objectSyntaxCopy(RootObject *o);\n"
  },
  {
    "path": "gcc/d/dmd/templateparamsem.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Template implementation.\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/templateparamsem.d, _templateparamsem.d)\n * Documentation:  https://dlang.org/phobos/dmd_templateparamsem.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/templateparamsem.d\n */\n\nmodule dmd.templateparamsem;\n\nimport dmd.arraytypes;\nimport dmd.dsymbol;\nimport dmd.dscope;\nimport dmd.dtemplate;\nimport dmd.globals;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.root.rootobject;\nimport dmd.mtype;\nimport dmd.typesem;\nimport dmd.visitor;\n\n/************************************************\n * Performs semantic on TemplateParameter AST nodes.\n *\n * Params:\n *      tp = element of `parameters` to be semantically analyzed\n *      sc = context\n *      parameters = array of `TemplateParameters` supplied to the `TemplateDeclaration`\n * Returns:\n *      `true` if no errors\n */\nextern(C++) bool tpsemantic(TemplateParameter tp, Scope* sc, TemplateParameters* parameters)\n{\n    scope v = new TemplateParameterSemanticVisitor(sc, parameters);\n    tp.accept(v);\n    return v.result;\n}\n\n\nprivate extern (C++) final class TemplateParameterSemanticVisitor : Visitor\n{\n    alias visit = Visitor.visit;\n\n    Scope* sc;\n    TemplateParameters* parameters;\n    bool result;\n\n    this(Scope* sc, TemplateParameters* parameters)\n    {\n        this.sc = sc;\n        this.parameters = parameters;\n    }\n\n    override void visit(TemplateTypeParameter ttp)\n    {\n        //printf(\"TemplateTypeParameter.semantic('%s')\\n\", ident.toChars());\n        if (ttp.specType && !reliesOnTident(ttp.specType, parameters))\n        {\n            ttp.specType = ttp.specType.typeSemantic(ttp.loc, sc);\n        }\n        version (none)\n        {\n            // Don't do semantic() until instantiation\n            if (ttp.defaultType)\n            {\n                ttp.defaultType = ttp.defaultType.typeSemantic(ttp.loc, sc);\n            }\n        }\n        result = !(ttp.specType && isError(ttp.specType));\n    }\n\n    override void visit(TemplateValueParameter tvp)\n    {\n        tvp.valType = tvp.valType.typeSemantic(tvp.loc, sc);\n        version (none)\n        {\n            // defer semantic analysis to arg match\n            if (tvp.specValue)\n            {\n                Expression e = tvp.specValue;\n                sc = sc.startCTFE();\n                e = e.semantic(sc);\n                sc = sc.endCTFE();\n                e = e.implicitCastTo(sc, tvp.valType);\n                e = e.ctfeInterpret();\n                if (e.op == TOK.int64 || e.op == TOK.float64 ||\n                    e.op == TOK.complex80 || e.op == TOK.null_ || e.op == TOK.string_)\n                    tvp.specValue = e;\n            }\n\n            if (tvp.defaultValue)\n            {\n                Expression e = defaultValue;\n                sc = sc.startCTFE();\n                e = e.semantic(sc);\n                sc = sc.endCTFE();\n                e = e.implicitCastTo(sc, tvp.valType);\n                e = e.ctfeInterpret();\n                if (e.op == TOK.int64)\n                    tvp.defaultValue = e;\n            }\n        }\n        result = !isError(tvp.valType);\n    }\n\n    override void visit(TemplateAliasParameter tap)\n    {\n        if (tap.specType && !reliesOnTident(tap.specType, parameters))\n        {\n            tap.specType = tap.specType.typeSemantic(tap.loc, sc);\n        }\n        tap.specAlias = aliasParameterSemantic(tap.loc, sc, tap.specAlias, parameters);\n        version (none)\n        {\n            // Don't do semantic() until instantiation\n            if (tap.defaultAlias)\n                tap.defaultAlias = tap.defaultAlias.semantic(tap.loc, sc);\n        }\n        result = !(tap.specType && isError(tap.specType)) && !(tap.specAlias && isError(tap.specAlias));\n    }\n\n    override void visit(TemplateTupleParameter ttp)\n    {\n        result = true;\n    }\n}\n\n/***********************************************\n * Support function for performing semantic analysis on `TemplateAliasParameter`.\n *\n * Params:\n *      loc = location (for error messages)\n *      sc = context\n *      o = object to run semantic() on, the `TemplateAliasParameter`s `specAlias` or `defaultAlias`\n *      parameters = array of `TemplateParameters` supplied to the `TemplateDeclaration`\n * Returns:\n *      object resulting from running `semantic` on `o`\n */\nRootObject aliasParameterSemantic(Loc loc, Scope* sc, RootObject o, TemplateParameters* parameters)\n{\n    if (o)\n    {\n        Expression ea = isExpression(o);\n        Type ta = isType(o);\n        if (ta && (!parameters || !reliesOnTident(ta, parameters)))\n        {\n            Dsymbol s = ta.toDsymbol(sc);\n            if (s)\n                o = s;\n            else\n                o = ta.typeSemantic(loc, sc);\n        }\n        else if (ea)\n        {\n            sc = sc.startCTFE();\n            ea = ea.expressionSemantic(sc);\n            sc = sc.endCTFE();\n            o = ea.ctfeInterpret();\n        }\n    }\n    return o;\n}\n"
  },
  {
    "path": "gcc/d/dmd/tokens.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/tokens.d, _tokens.d)\n * Documentation:  https://dlang.org/phobos/dmd_tokens.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/tokens.d\n */\n\nmodule dmd.tokens;\n\nimport core.stdc.ctype;\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport dmd.globals;\nimport dmd.identifier;\nimport dmd.root.ctfloat;\nimport dmd.root.outbuffer;\nimport dmd.root.rmem;\nimport dmd.utf;\n\nenum TOK : int\n{\n    reserved,\n\n    // Other\n    leftParentheses,\n    rightParentheses,\n    leftBracket,\n    rightBracket,\n    leftCurly,\n    rightCurly,\n    colon,\n    negate,\n    semicolon,\n    dotDotDot,\n    endOfFile,\n    cast_,\n    null_,\n    assert_,\n    true_,\n    false_,\n    array,\n    call,\n    address,\n    type,\n    throw_,\n    new_,\n    delete_,\n    star,\n    symbolOffset,\n    variable,\n    dotVariable,\n    dotIdentifier,\n    dotTemplateInstance,\n    dotType,\n    slice,\n    arrayLength,\n    version_,\n    module_,\n    dollar,\n    template_,\n    dotTemplateDeclaration,\n    declaration,\n    typeof_,\n    pragma_,\n    dSymbol,\n    typeid_,\n    uadd,\n    remove,\n    newAnonymousClass,\n    comment,\n    arrayLiteral,\n    assocArrayLiteral,\n    structLiteral,\n    classReference,\n    thrownException,\n    delegatePointer,\n    delegateFunctionPointer,\n\n    // Operators\n    lessThan = 54,\n    greaterThan,\n    lessOrEqual,\n    greaterOrEqual,\n    equal,\n    notEqual,\n    identity,\n    notIdentity,\n    index,\n    is_,\n\n    leftShift = 64,\n    rightShift,\n    leftShiftAssign,\n    rightShiftAssign,\n    unsignedRightShift,\n    unsignedRightShiftAssign,\n    concatenate,\n    concatenateAssign, // ~=\n    concatenateElemAssign,\n    concatenateDcharAssign,\n    add,\n    min,\n    addAssign,\n    minAssign,\n    mul,\n    div,\n    mod,\n    mulAssign,\n    divAssign,\n    modAssign,\n    and,\n    or,\n    xor,\n    andAssign,\n    orAssign,\n    xorAssign,\n    assign,\n    not,\n    tilde,\n    plusPlus,\n    minusMinus,\n    construct,\n    blit,\n    dot,\n    arrow,\n    comma,\n    question,\n    andAnd,\n    orOr,\n    prePlusPlus,\n    preMinusMinus,\n\n    // Numeric literals\n    int32Literal = 105,\n    uns32Literal,\n    int64Literal,\n    uns64Literal,\n    int128Literal,\n    uns128Literal,\n    float32Literal,\n    float64Literal,\n    float80Literal,\n    imaginary32Literal,\n    imaginary64Literal,\n    imaginary80Literal,\n\n    // Char constants\n    charLiteral = 117,\n    wcharLiteral,\n    dcharLiteral,\n\n    // Leaf operators\n    identifier = 120,\n    string_,\n    hexadecimalString,\n    this_,\n    super_,\n    halt,\n    tuple,\n    error,\n\n    // Basic types\n    void_ = 128,\n    int8,\n    uns8,\n    int16,\n    uns16,\n    int32,\n    uns32,\n    int64,\n    uns64,\n    int128,\n    uns128,\n    float32,\n    float64,\n    float80,\n    imaginary32,\n    imaginary64,\n    imaginary80,\n    complex32,\n    complex64,\n    complex80,\n    char_,\n    wchar_,\n    dchar_,\n    bool_,\n\n    // Aggregates\n    struct_ = 152,\n    class_,\n    interface_,\n    union_,\n    enum_,\n    import_,\n    alias_,\n    override_,\n    delegate_,\n    function_,\n    mixin_,\n    align_,\n    extern_,\n    private_,\n    protected_,\n    public_,\n    export_,\n    static_,\n    final_,\n    const_,\n    abstract_,\n    debug_,\n    deprecated_,\n    in_,\n    out_,\n    inout_,\n    lazy_,\n    auto_,\n    package_,\n    manifest,\n    immutable_,\n\n    // Statements\n    if_ = 183,\n    else_,\n    while_,\n    for_,\n    do_,\n    switch_,\n    case_,\n    default_,\n    break_,\n    continue_,\n    with_,\n    synchronized_,\n    return_,\n    goto_,\n    try_,\n    catch_,\n    finally_,\n    asm_,\n    foreach_,\n    foreach_reverse_,\n    scope_,\n    onScopeExit,\n    onScopeFailure,\n    onScopeSuccess,\n\n    // Contracts\n    invariant_ = 207,\n\n    // Testing\n    unittest_,\n\n    // Added after 1.0\n    argumentTypes,\n    ref_,\n    macro_,\n\n    parameters = 212,\n    traits,\n    overloadSet,\n    pure_,\n    nothrow_,\n    gshared,\n    line,\n    file,\n    fileFullPath,\n    moduleString,\n    functionString,\n    prettyFunction,\n    shared_,\n    at,\n    pow,\n    powAssign,\n    goesTo,\n    vector,\n    pound,\n\n    interval = 231,\n    voidExpression,\n    cantExpression,\n    showCtfeContext,\n\n    objcClassReference,\n\n    max_,\n}\n\n// Assert that all token enum members have consecutive values and\n// that none of them overlap\nstatic assert(() {\n    foreach (idx, enumName; __traits(allMembers, TOK)) {\n       static if (idx != __traits(getMember, TOK, enumName)) {\n           pragma(msg, \"Error: Expected TOK.\", enumName, \" to be \", idx, \" but is \", __traits(getMember, TOK, enumName));\n           static assert(0);\n       }\n    }\n    return true;\n}());\n\n\n/****************************************\n */\n\nprivate immutable TOK[] keywords =\n[\n    TOK.this_,\n    TOK.super_,\n    TOK.assert_,\n    TOK.null_,\n    TOK.true_,\n    TOK.false_,\n    TOK.cast_,\n    TOK.new_,\n    TOK.delete_,\n    TOK.throw_,\n    TOK.module_,\n    TOK.pragma_,\n    TOK.typeof_,\n    TOK.typeid_,\n    TOK.template_,\n    TOK.void_,\n    TOK.int8,\n    TOK.uns8,\n    TOK.int16,\n    TOK.uns16,\n    TOK.int32,\n    TOK.uns32,\n    TOK.int64,\n    TOK.uns64,\n    TOK.int128,\n    TOK.uns128,\n    TOK.float32,\n    TOK.float64,\n    TOK.float80,\n    TOK.bool_,\n    TOK.char_,\n    TOK.wchar_,\n    TOK.dchar_,\n    TOK.imaginary32,\n    TOK.imaginary64,\n    TOK.imaginary80,\n    TOK.complex32,\n    TOK.complex64,\n    TOK.complex80,\n    TOK.delegate_,\n    TOK.function_,\n    TOK.is_,\n    TOK.if_,\n    TOK.else_,\n    TOK.while_,\n    TOK.for_,\n    TOK.do_,\n    TOK.switch_,\n    TOK.case_,\n    TOK.default_,\n    TOK.break_,\n    TOK.continue_,\n    TOK.synchronized_,\n    TOK.return_,\n    TOK.goto_,\n    TOK.try_,\n    TOK.catch_,\n    TOK.finally_,\n    TOK.with_,\n    TOK.asm_,\n    TOK.foreach_,\n    TOK.foreach_reverse_,\n    TOK.scope_,\n    TOK.struct_,\n    TOK.class_,\n    TOK.interface_,\n    TOK.union_,\n    TOK.enum_,\n    TOK.import_,\n    TOK.mixin_,\n    TOK.static_,\n    TOK.final_,\n    TOK.const_,\n    TOK.alias_,\n    TOK.override_,\n    TOK.abstract_,\n    TOK.debug_,\n    TOK.deprecated_,\n    TOK.in_,\n    TOK.out_,\n    TOK.inout_,\n    TOK.lazy_,\n    TOK.auto_,\n    TOK.align_,\n    TOK.extern_,\n    TOK.private_,\n    TOK.package_,\n    TOK.protected_,\n    TOK.public_,\n    TOK.export_,\n    TOK.invariant_,\n    TOK.unittest_,\n    TOK.version_,\n    TOK.argumentTypes,\n    TOK.parameters,\n    TOK.ref_,\n    TOK.macro_,\n    TOK.pure_,\n    TOK.nothrow_,\n    TOK.gshared,\n    TOK.traits,\n    TOK.vector,\n    TOK.overloadSet,\n    TOK.file,\n    TOK.fileFullPath,\n    TOK.line,\n    TOK.moduleString,\n    TOK.functionString,\n    TOK.prettyFunction,\n    TOK.shared_,\n    TOK.immutable_,\n];\n\n/***********************************************************\n */\nextern (C++) struct Token\n{\n    Token* next;\n    Loc loc;\n    const(char)* ptr; // pointer to first character of this token within buffer\n    TOK value;\n    const(char)* blockComment; // doc comment string prior to this token\n    const(char)* lineComment; // doc comment for previous token\n\n    union\n    {\n        // Integers\n        sinteger_t intvalue;\n        uinteger_t unsvalue;\n        // Floats\n        real_t floatvalue;\n\n        struct\n        {\n            const(char)* ustring; // UTF8 string\n            uint len;\n            ubyte postfix; // 'c', 'w', 'd'\n        }\n\n        Identifier ident;\n    }\n\n    extern (D) private __gshared immutable string[TOK.max_] tochars =\n    [\n        // Keywords\n        TOK.this_: \"this\",\n        TOK.super_: \"super\",\n        TOK.assert_: \"assert\",\n        TOK.null_: \"null\",\n        TOK.true_: \"true\",\n        TOK.false_: \"false\",\n        TOK.cast_: \"cast\",\n        TOK.new_: \"new\",\n        TOK.delete_: \"delete\",\n        TOK.throw_: \"throw\",\n        TOK.module_: \"module\",\n        TOK.pragma_: \"pragma\",\n        TOK.typeof_: \"typeof\",\n        TOK.typeid_: \"typeid\",\n        TOK.template_: \"template\",\n        TOK.void_: \"void\",\n        TOK.int8: \"byte\",\n        TOK.uns8: \"ubyte\",\n        TOK.int16: \"short\",\n        TOK.uns16: \"ushort\",\n        TOK.int32: \"int\",\n        TOK.uns32: \"uint\",\n        TOK.int64: \"long\",\n        TOK.uns64: \"ulong\",\n        TOK.int128: \"cent\",\n        TOK.uns128: \"ucent\",\n        TOK.float32: \"float\",\n        TOK.float64: \"double\",\n        TOK.float80: \"real\",\n        TOK.bool_: \"bool\",\n        TOK.char_: \"char\",\n        TOK.wchar_: \"wchar\",\n        TOK.dchar_: \"dchar\",\n        TOK.imaginary32: \"ifloat\",\n        TOK.imaginary64: \"idouble\",\n        TOK.imaginary80: \"ireal\",\n        TOK.complex32: \"cfloat\",\n        TOK.complex64: \"cdouble\",\n        TOK.complex80: \"creal\",\n        TOK.delegate_: \"delegate\",\n        TOK.function_: \"function\",\n        TOK.is_: \"is\",\n        TOK.if_: \"if\",\n        TOK.else_: \"else\",\n        TOK.while_: \"while\",\n        TOK.for_: \"for\",\n        TOK.do_: \"do\",\n        TOK.switch_: \"switch\",\n        TOK.case_: \"case\",\n        TOK.default_: \"default\",\n        TOK.break_: \"break\",\n        TOK.continue_: \"continue\",\n        TOK.synchronized_: \"synchronized\",\n        TOK.return_: \"return\",\n        TOK.goto_: \"goto\",\n        TOK.try_: \"try\",\n        TOK.catch_: \"catch\",\n        TOK.finally_: \"finally\",\n        TOK.with_: \"with\",\n        TOK.asm_: \"asm\",\n        TOK.foreach_: \"foreach\",\n        TOK.foreach_reverse_: \"foreach_reverse\",\n        TOK.scope_: \"scope\",\n        TOK.struct_: \"struct\",\n        TOK.class_: \"class\",\n        TOK.interface_: \"interface\",\n        TOK.union_: \"union\",\n        TOK.enum_: \"enum\",\n        TOK.import_: \"import\",\n        TOK.mixin_: \"mixin\",\n        TOK.static_: \"static\",\n        TOK.final_: \"final\",\n        TOK.const_: \"const\",\n        TOK.alias_: \"alias\",\n        TOK.override_: \"override\",\n        TOK.abstract_: \"abstract\",\n        TOK.debug_: \"debug\",\n        TOK.deprecated_: \"deprecated\",\n        TOK.in_: \"in\",\n        TOK.out_: \"out\",\n        TOK.inout_: \"inout\",\n        TOK.lazy_: \"lazy\",\n        TOK.auto_: \"auto\",\n        TOK.align_: \"align\",\n        TOK.extern_: \"extern\",\n        TOK.private_: \"private\",\n        TOK.package_: \"package\",\n        TOK.protected_: \"protected\",\n        TOK.public_: \"public\",\n        TOK.export_: \"export\",\n        TOK.invariant_: \"invariant\",\n        TOK.unittest_: \"unittest\",\n        TOK.version_: \"version\",\n        TOK.argumentTypes: \"__argTypes\",\n        TOK.parameters: \"__parameters\",\n        TOK.ref_: \"ref\",\n        TOK.macro_: \"macro\",\n        TOK.pure_: \"pure\",\n        TOK.nothrow_: \"nothrow\",\n        TOK.gshared: \"__gshared\",\n        TOK.traits: \"__traits\",\n        TOK.vector: \"__vector\",\n        TOK.overloadSet: \"__overloadset\",\n        TOK.file: \"__FILE__\",\n        TOK.fileFullPath: \"__FILE_FULL_PATH__\",\n        TOK.line: \"__LINE__\",\n        TOK.moduleString: \"__MODULE__\",\n        TOK.functionString: \"__FUNCTION__\",\n        TOK.prettyFunction: \"__PRETTY_FUNCTION__\",\n        TOK.shared_: \"shared\",\n        TOK.immutable_: \"immutable\",\n\n        TOK.endOfFile: \"End of File\",\n        TOK.leftCurly: \"{\",\n        TOK.rightCurly: \"}\",\n        TOK.leftParentheses: \"(\",\n        TOK.rightParentheses: \")\",\n        TOK.leftBracket: \"[\",\n        TOK.rightBracket: \"]\",\n        TOK.semicolon: \";\",\n        TOK.colon: \":\",\n        TOK.comma: \",\",\n        TOK.dot: \".\",\n        TOK.xor: \"^\",\n        TOK.xorAssign: \"^=\",\n        TOK.assign: \"=\",\n        TOK.construct: \"=\",\n        TOK.blit: \"=\",\n        TOK.lessThan: \"<\",\n        TOK.greaterThan: \">\",\n        TOK.lessOrEqual: \"<=\",\n        TOK.greaterOrEqual: \">=\",\n        TOK.equal: \"==\",\n        TOK.notEqual: \"!=\",\n        TOK.not: \"!\",\n        TOK.leftShift: \"<<\",\n        TOK.rightShift: \">>\",\n        TOK.unsignedRightShift: \">>>\",\n        TOK.add: \"+\",\n        TOK.min: \"-\",\n        TOK.mul: \"*\",\n        TOK.div: \"/\",\n        TOK.mod: \"%\",\n        TOK.slice: \"..\",\n        TOK.dotDotDot: \"...\",\n        TOK.and: \"&\",\n        TOK.andAnd: \"&&\",\n        TOK.or: \"|\",\n        TOK.orOr: \"||\",\n        TOK.array: \"[]\",\n        TOK.index: \"[i]\",\n        TOK.address: \"&\",\n        TOK.star: \"*\",\n        TOK.tilde: \"~\",\n        TOK.dollar: \"$\",\n        TOK.plusPlus: \"++\",\n        TOK.minusMinus: \"--\",\n        TOK.prePlusPlus: \"++\",\n        TOK.preMinusMinus: \"--\",\n        TOK.type: \"type\",\n        TOK.question: \"?\",\n        TOK.negate: \"-\",\n        TOK.uadd: \"+\",\n        TOK.variable: \"var\",\n        TOK.addAssign: \"+=\",\n        TOK.minAssign: \"-=\",\n        TOK.mulAssign: \"*=\",\n        TOK.divAssign: \"/=\",\n        TOK.modAssign: \"%=\",\n        TOK.leftShiftAssign: \"<<=\",\n        TOK.rightShiftAssign: \">>=\",\n        TOK.unsignedRightShiftAssign: \">>>=\",\n        TOK.andAssign: \"&=\",\n        TOK.orAssign: \"|=\",\n        TOK.concatenateAssign: \"~=\",\n        TOK.concatenateElemAssign: \"~=\",\n        TOK.concatenateDcharAssign: \"~=\",\n        TOK.concatenate: \"~\",\n        TOK.call: \"call\",\n        TOK.identity: \"is\",\n        TOK.notIdentity: \"!is\",\n        TOK.identifier: \"identifier\",\n        TOK.at: \"@\",\n        TOK.pow: \"^^\",\n        TOK.powAssign: \"^^=\",\n        TOK.goesTo: \"=>\",\n        TOK.pound: \"#\",\n\n        // For debugging\n        TOK.error: \"error\",\n        TOK.dotIdentifier: \"dotid\",\n        TOK.dotTemplateDeclaration: \"dottd\",\n        TOK.dotTemplateInstance: \"dotti\",\n        TOK.dotVariable: \"dotvar\",\n        TOK.dotType: \"dottype\",\n        TOK.symbolOffset: \"symoff\",\n        TOK.arrayLength: \"arraylength\",\n        TOK.arrayLiteral: \"arrayliteral\",\n        TOK.assocArrayLiteral: \"assocarrayliteral\",\n        TOK.structLiteral: \"structliteral\",\n        TOK.string_: \"string\",\n        TOK.dSymbol: \"symbol\",\n        TOK.tuple: \"tuple\",\n        TOK.declaration: \"declaration\",\n        TOK.onScopeExit: \"scope(exit)\",\n        TOK.onScopeSuccess: \"scope(success)\",\n        TOK.onScopeFailure: \"scope(failure)\",\n        TOK.delegatePointer: \"delegateptr\",\n\n        // Finish up\n        TOK.reserved: \"reserved\",\n        TOK.remove: \"remove\",\n        TOK.newAnonymousClass: \"newanonclass\",\n        TOK.comment: \"comment\",\n        TOK.classReference: \"classreference\",\n        TOK.thrownException: \"thrownexception\",\n        TOK.delegateFunctionPointer: \"delegatefuncptr\",\n        TOK.arrow: \"arrow\",\n        TOK.int32Literal: \"int32v\",\n        TOK.uns32Literal: \"uns32v\",\n        TOK.int64Literal: \"int64v\",\n        TOK.uns64Literal: \"uns64v\",\n        TOK.int128Literal: \"int128v\",\n        TOK.uns128Literal: \"uns128v\",\n        TOK.float32Literal: \"float32v\",\n        TOK.float64Literal: \"float64v\",\n        TOK.float80Literal: \"float80v\",\n        TOK.imaginary32Literal: \"imaginary32v\",\n        TOK.imaginary64Literal: \"imaginary64v\",\n        TOK.imaginary80Literal: \"imaginary80v\",\n        TOK.charLiteral: \"charv\",\n        TOK.wcharLiteral: \"wcharv\",\n        TOK.dcharLiteral: \"dcharv\",\n\n        TOK.halt: \"halt\",\n        TOK.hexadecimalString: \"xstring\",\n        TOK.manifest: \"manifest\",\n\n        TOK.interval: \"interval\",\n        TOK.voidExpression: \"voidexp\",\n        TOK.cantExpression: \"cantexp\",\n        TOK.showCtfeContext : \"showCtfeContext\",\n\n        TOK.objcClassReference: \"class\",\n    ];\n\n    static assert(() {\n        foreach (s; tochars)\n            assert(s.length);\n        return true;\n    }());\n\n    shared static this()\n    {\n        Identifier.initTable();\n        foreach (kw; keywords)\n        {\n            //printf(\"keyword[%d] = '%s'\\n\",kw, tochars[kw].ptr);\n            Identifier.idPool(tochars[kw].ptr, tochars[kw].length, cast(uint)kw);\n        }\n    }\n\n    extern (D) private __gshared Token* freelist = null;\n\n    extern (D) static Token* alloc()\n    {\n        if (Token.freelist)\n        {\n            Token* t = freelist;\n            freelist = t.next;\n            t.next = null;\n            return t;\n        }\n        return new Token();\n    }\n\n    void free()\n    {\n        next = freelist;\n        freelist = &this;\n    }\n\n    int isKeyword() const\n    {\n        foreach (kw; keywords)\n        {\n            if (kw == value)\n                return 1;\n        }\n        return 0;\n    }\n\n    /****\n     * Set to contents of ptr[0..length]\n     * Params:\n     *  ptr = pointer to string\n     *  length = length of string\n     */\n    void setString(const(char)* ptr, size_t length)\n    {\n        auto s = cast(char*)mem.xmalloc(length + 1);\n        memcpy(s, ptr, length);\n        s[length] = 0;\n        ustring = s;\n        len = cast(uint)length;\n        postfix = 0;\n    }\n\n    /****\n     * Set to contents of buf\n     * Params:\n     *  buf = string (not zero terminated)\n     */\n    void setString(const ref OutBuffer buf)\n    {\n        setString(cast(const(char)*)buf.data, buf.offset);\n    }\n\n    /****\n     * Set to empty string\n     */\n    void setString()\n    {\n        ustring = \"\";\n        len = 0;\n        postfix = 0;\n    }\n\n    extern (C++) const(char)* toChars() const\n    {\n        __gshared char[3 + 3 * floatvalue.sizeof + 1] buffer;\n        const(char)* p = &buffer[0];\n        switch (value)\n        {\n        case TOK.int32Literal:\n            sprintf(&buffer[0], \"%d\", cast(d_int32)intvalue);\n            break;\n        case TOK.uns32Literal:\n        case TOK.charLiteral:\n        case TOK.wcharLiteral:\n        case TOK.dcharLiteral:\n            sprintf(&buffer[0], \"%uU\", cast(d_uns32)unsvalue);\n            break;\n        case TOK.int64Literal:\n            sprintf(&buffer[0], \"%lldL\", cast(long)intvalue);\n            break;\n        case TOK.uns64Literal:\n            sprintf(&buffer[0], \"%lluUL\", cast(ulong)unsvalue);\n            break;\n        case TOK.float32Literal:\n            CTFloat.sprint(&buffer[0], 'g', floatvalue);\n            strcat(&buffer[0], \"f\");\n            break;\n        case TOK.float64Literal:\n            CTFloat.sprint(&buffer[0], 'g', floatvalue);\n            break;\n        case TOK.float80Literal:\n            CTFloat.sprint(&buffer[0], 'g', floatvalue);\n            strcat(&buffer[0], \"L\");\n            break;\n        case TOK.imaginary32Literal:\n            CTFloat.sprint(&buffer[0], 'g', floatvalue);\n            strcat(&buffer[0], \"fi\");\n            break;\n        case TOK.imaginary64Literal:\n            CTFloat.sprint(&buffer[0], 'g', floatvalue);\n            strcat(&buffer[0], \"i\");\n            break;\n        case TOK.imaginary80Literal:\n            CTFloat.sprint(&buffer[0], 'g', floatvalue);\n            strcat(&buffer[0], \"Li\");\n            break;\n        case TOK.string_:\n            {\n                OutBuffer buf;\n                buf.writeByte('\"');\n                for (size_t i = 0; i < len;)\n                {\n                    dchar c;\n                    utf_decodeChar(ustring, len, i, c);\n                    switch (c)\n                    {\n                    case 0:\n                        break;\n                    case '\"':\n                    case '\\\\':\n                        buf.writeByte('\\\\');\n                        goto default;\n                    default:\n                        if (c <= 0x7F)\n                        {\n                            if (isprint(c))\n                                buf.writeByte(c);\n                            else\n                                buf.printf(\"\\\\x%02x\", c);\n                        }\n                        else if (c <= 0xFFFF)\n                            buf.printf(\"\\\\u%04x\", c);\n                        else\n                            buf.printf(\"\\\\U%08x\", c);\n                        continue;\n                    }\n                    break;\n                }\n                buf.writeByte('\"');\n                if (postfix)\n                    buf.writeByte(postfix);\n                p = buf.extractString();\n            }\n            break;\n        case TOK.hexadecimalString:\n            {\n                OutBuffer buf;\n                buf.writeByte('x');\n                buf.writeByte('\"');\n                foreach (size_t i; 0 .. len)\n                {\n                    if (i)\n                        buf.writeByte(' ');\n                    buf.printf(\"%02x\", ustring[i]);\n                }\n                buf.writeByte('\"');\n                if (postfix)\n                    buf.writeByte(postfix);\n                buf.writeByte(0);\n                p = buf.extractData();\n                break;\n            }\n        case TOK.identifier:\n        case TOK.enum_:\n        case TOK.struct_:\n        case TOK.import_:\n        case TOK.wchar_:\n        case TOK.dchar_:\n        case TOK.bool_:\n        case TOK.char_:\n        case TOK.int8:\n        case TOK.uns8:\n        case TOK.int16:\n        case TOK.uns16:\n        case TOK.int32:\n        case TOK.uns32:\n        case TOK.int64:\n        case TOK.uns64:\n        case TOK.int128:\n        case TOK.uns128:\n        case TOK.float32:\n        case TOK.float64:\n        case TOK.float80:\n        case TOK.imaginary32:\n        case TOK.imaginary64:\n        case TOK.imaginary80:\n        case TOK.complex32:\n        case TOK.complex64:\n        case TOK.complex80:\n        case TOK.void_:\n            p = ident.toChars();\n            break;\n        default:\n            p = toChars(value);\n            break;\n        }\n        return p;\n    }\n\n    extern (D) static const(char)* toChars(TOK value)\n    {\n        return toString(value).ptr;\n    }\n\n    extern (D) static string toString(TOK value) pure nothrow @nogc @safe\n    {\n        return tochars[value];\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/tokens.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * written by Walter Bright\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/tokens.h\n */\n\n#pragma once\n\n#include \"root/port.h\"\n#include \"globals.h\"\n\nclass Identifier;\n\n/* Tokens:\n        (       )\n        [       ]\n        {       }\n        <       >       <=      >=      ==      !=      ===     !==\n        <<      >>      <<=     >>=     >>>     >>>=\n        +       -       +=      -=\n        *       /       %       *=      /=      %=\n        &       |       ^       &=      |=      ^=\n        =       !       ~       @\n        ^^      ^^=\n        ++      --\n        .       ->      :       ,       =>\n        ?       &&      ||\n */\n\nenum TOK\n{\n        TOKreserved,\n\n        // Other\n        TOKlparen,      TOKrparen,\n        TOKlbracket,    TOKrbracket,\n        TOKlcurly,      TOKrcurly,\n        TOKcolon,       TOKneg,\n        TOKsemicolon,   TOKdotdotdot,\n        TOKeof,         TOKcast,\n        TOKnull,        TOKassert,\n        TOKtrue,        TOKfalse,\n        TOKarray,       TOKcall,\n        TOKaddress,\n        TOKtype,        TOKthrow,\n        TOKnew,         TOKdelete,\n        TOKstar,        TOKsymoff,\n        TOKvar,         TOKdotvar,\n        TOKdotid,       TOKdotti,\n        TOKdottype,     TOKslice,\n        TOKarraylength, TOKversion,\n        TOKmodule,      TOKdollar,\n        TOKtemplate,    TOKdottd,\n        TOKdeclaration, TOKtypeof,\n        TOKpragma,      TOKdsymbol,\n        TOKtypeid,      TOKuadd,\n        TOKremove,\n        TOKnewanonclass, TOKcomment,\n        TOKarrayliteral, TOKassocarrayliteral,\n        TOKstructliteral,\n        TOKclassreference,\n        TOKthrownexception,\n        TOKdelegateptr,\n        TOKdelegatefuncptr,\n\n// 54\n        // Operators\n        TOKlt,          TOKgt,\n        TOKle,          TOKge,\n        TOKequal,       TOKnotequal,\n        TOKidentity,    TOKnotidentity,\n        TOKindex,       TOKis,\n\n// 64\n        TOKshl,         TOKshr,\n        TOKshlass,      TOKshrass,\n        TOKushr,        TOKushrass,\n        TOKcat,         TOKcatass,      TOKcatelemass,  TOKcatdcharass,     // ~ ~=\n        TOKadd,         TOKmin,         TOKaddass,      TOKminass,\n        TOKmul,         TOKdiv,         TOKmod,\n        TOKmulass,      TOKdivass,      TOKmodass,\n        TOKand,         TOKor,          TOKxor,\n        TOKandass,      TOKorass,       TOKxorass,\n        TOKassign,      TOKnot,         TOKtilde,\n        TOKplusplus,    TOKminusminus,  TOKconstruct,   TOKblit,\n        TOKdot,         TOKarrow,       TOKcomma,\n        TOKquestion,    TOKandand,      TOKoror,\n        TOKpreplusplus, TOKpreminusminus,\n\n// 105\n        // Numeric literals\n        TOKint32v, TOKuns32v,\n        TOKint64v, TOKuns64v,\n        TOKint128v, TOKuns128v,\n        TOKfloat32v, TOKfloat64v, TOKfloat80v,\n        TOKimaginary32v, TOKimaginary64v, TOKimaginary80v,\n\n        // Char constants\n        TOKcharv, TOKwcharv, TOKdcharv,\n\n        // Leaf operators\n        TOKidentifier,  TOKstring, TOKxstring,\n        TOKthis,        TOKsuper,\n        TOKhalt,        TOKtuple,\n        TOKerror,\n\n        // Basic types\n        TOKvoid,\n        TOKint8, TOKuns8,\n        TOKint16, TOKuns16,\n        TOKint32, TOKuns32,\n        TOKint64, TOKuns64,\n        TOKint128, TOKuns128,\n        TOKfloat32, TOKfloat64, TOKfloat80,\n        TOKimaginary32, TOKimaginary64, TOKimaginary80,\n        TOKcomplex32, TOKcomplex64, TOKcomplex80,\n        TOKchar, TOKwchar, TOKdchar, TOKbool,\n\n// 152\n        // Aggregates\n        TOKstruct, TOKclass, TOKinterface, TOKunion, TOKenum, TOKimport,\n        TOKalias, TOKoverride, TOKdelegate, TOKfunction,\n        TOKmixin,\n\n        TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,\n        TOKstatic, TOKfinal, TOKconst, TOKabstract,\n        TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,\n        TOKauto, TOKpackage, TOKmanifest, TOKimmutable,\n\n// 183\n        // Statements\n        TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,\n        TOKcase, TOKdefault, TOKbreak, TOKcontinue, TOKwith,\n        TOKsynchronized, TOKreturn, TOKgoto, TOKtry, TOKcatch, TOKfinally,\n        TOKasm, TOKforeach, TOKforeach_reverse,\n        TOKscope,\n        TOKon_scope_exit, TOKon_scope_failure, TOKon_scope_success,\n\n// 207\n        // Contracts\n        TOKinvariant,\n\n        // Testing\n        TOKunittest,\n\n        // Added after 1.0\n        TOKargTypes,\n        TOKref,\n        TOKmacro,\n\n// 212\n        TOKparameters,\n        TOKtraits,\n        TOKoverloadset,\n        TOKpure,\n        TOKnothrow,\n        TOKgshared,\n        TOKline,\n        TOKfile,\n        TOKfilefullpath,\n        TOKmodulestring,\n        TOKfuncstring,\n        TOKprettyfunc,\n        TOKshared,\n        TOKat,\n        TOKpow,\n        TOKpowass,\n        TOKgoesto,\n        TOKvector,\n        TOKpound,\n\n// 231\n        TOKinterval,\n        TOKvoidexp,\n        TOKcantexp,\n        TOKshowctfecontext,\n\n        TOKobjc_class_reference,\n\n        TOKMAX\n};\n\n#define TOKwild TOKinout\n\n// Token has an anonymous struct, which is not strict ISO C++.\n#if defined(__GNUC__)\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wpedantic\"\n#endif\n\nstruct Token\n{\n    Token *next;\n    Loc loc;\n    const utf8_t *ptr;         // pointer to first character of this token within buffer\n    TOK value;\n    const utf8_t *blockComment; // doc comment string prior to this token\n    const utf8_t *lineComment;  // doc comment for previous token\n    union\n    {\n        // Integers\n        sinteger_t intvalue;\n        uinteger_t unsvalue;\n\n        // Floats\n        real_t floatvalue;\n\n        struct\n        {   utf8_t *ustring;     // UTF8 string\n            unsigned len;\n            unsigned char postfix;      // 'c', 'w', 'd'\n        };\n\n        Identifier *ident;\n    };\n\n    void free();\n\n    Token() : next(NULL) {}\n    int isKeyword();\n    const char *toChars() const;\n};\n\n#if defined(__GNUC__)\n#pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "gcc/d/dmd/traits.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/traits.d, _traits.d)\n * Documentation:  https://dlang.org/phobos/dmd_traits.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/traits.d\n */\n\nmodule dmd.traits;\n\nimport core.stdc.stdio;\nimport core.stdc.string;\n\nimport dmd.aggregate;\nimport dmd.arraytypes;\nimport dmd.attrib;\nimport dmd.canthrow;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dscope;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.mtype;\nimport dmd.nogc;\nimport dmd.root.array;\nimport dmd.root.speller;\nimport dmd.root.stringtable;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.typesem;\nimport dmd.visitor;\nimport dmd.root.rootobject;\n\nenum LOGSEMANTIC = false;\n\n/************************ TraitsExp ************************************/\n\n// callback for TypeFunction::attributesApply\nstruct PushAttributes\n{\n    Expressions* mods;\n\n    extern (D) static int fp(void* param, string str)\n    {\n        PushAttributes* p = cast(PushAttributes*)param;\n        p.mods.push(new StringExp(Loc.initial, cast(char*)str.ptr, str.length));\n        return 0;\n    }\n}\n\n/**************************************\n * Convert `Expression` or `Type` to corresponding `Dsymbol`, additionally\n * stripping off expression contexts.\n *\n * Some symbol related `__traits` ignore arguments expression contexts.\n * For example:\n * ----\n *  struct S { void f() {} }\n *  S s;\n *  pragma(msg, __traits(isNested, s.f));\n *  // s.f is `DotVarExp`, but `__traits(isNested)`` needs a `FuncDeclaration`.\n * ----\n *\n * This is used for that common `__traits` behavior.\n *\n * Input:\n *      oarg     object to get the symbol for\n * Returns:\n *      Dsymbol  the corresponding symbol for oarg\n */\nprivate Dsymbol getDsymbolWithoutExpCtx(RootObject oarg)\n{\n    if (auto e = isExpression(oarg))\n    {\n        if (e.op == TOK.dotVariable)\n            return (cast(DotVarExp)e).var;\n        if (e.op == TOK.dotTemplateDeclaration)\n            return (cast(DotTemplateExp)e).td;\n    }\n    return getDsymbol(oarg);\n}\n\nprivate __gshared StringTable traitsStringTable;\n\nshared static this()\n{\n    static immutable string[] names =\n    [\n        \"isAbstractClass\",\n        \"isArithmetic\",\n        \"isAssociativeArray\",\n        \"isDisabled\",\n        \"isDeprecated\",\n        \"isFuture\",\n        \"isFinalClass\",\n        \"isPOD\",\n        \"isNested\",\n        \"isFloating\",\n        \"isIntegral\",\n        \"isScalar\",\n        \"isStaticArray\",\n        \"isUnsigned\",\n        \"isVirtualFunction\",\n        \"isVirtualMethod\",\n        \"isAbstractFunction\",\n        \"isFinalFunction\",\n        \"isOverrideFunction\",\n        \"isStaticFunction\",\n        \"isRef\",\n        \"isOut\",\n        \"isLazy\",\n        \"isReturnOnStack\",\n        \"hasMember\",\n        \"identifier\",\n        \"getProtection\",\n        \"parent\",\n        \"getLinkage\",\n        \"getMember\",\n        \"getOverloads\",\n        \"getVirtualFunctions\",\n        \"getVirtualMethods\",\n        \"classInstanceSize\",\n        \"allMembers\",\n        \"derivedMembers\",\n        \"isSame\",\n        \"compiles\",\n        \"parameters\",\n        \"getAliasThis\",\n        \"getAttributes\",\n        \"getFunctionAttributes\",\n        \"getFunctionVariadicStyle\",\n        \"getParameterStorageClasses\",\n        \"getUnitTests\",\n        \"getVirtualIndex\",\n        \"getPointerBitmap\",\n        \"isZeroInit\",\n        \"getTargetInfo\"\n    ];\n\n    traitsStringTable._init(48);\n\n    foreach (s; names)\n    {\n        auto sv = traitsStringTable.insert(s.ptr, s.length, cast(void*)s.ptr);\n        assert(sv);\n    }\n}\n\n/**\n * get an array of size_t values that indicate possible pointer words in memory\n *  if interpreted as the type given as argument\n * Returns: the size of the type in bytes, d_uns64.max on error\n */\nd_uns64 getTypePointerBitmap(Loc loc, Type t, Array!(d_uns64)* data)\n{\n    d_uns64 sz;\n    if (t.ty == Tclass && !(cast(TypeClass)t).sym.isInterfaceDeclaration())\n        sz = (cast(TypeClass)t).sym.AggregateDeclaration.size(loc);\n    else\n        sz = t.size(loc);\n    if (sz == SIZE_INVALID)\n        return d_uns64.max;\n\n    const sz_size_t = Type.tsize_t.size(loc);\n    if (sz > sz.max - sz_size_t)\n    {\n        error(loc, \"size overflow for type `%s`\", t.toChars());\n        return d_uns64.max;\n    }\n\n    d_uns64 bitsPerWord = sz_size_t * 8;\n    d_uns64 cntptr = (sz + sz_size_t - 1) / sz_size_t;\n    d_uns64 cntdata = (cntptr + bitsPerWord - 1) / bitsPerWord;\n\n    data.setDim(cast(size_t)cntdata);\n    data.zero();\n\n    extern (C++) final class PointerBitmapVisitor : Visitor\n    {\n        alias visit = Visitor.visit;\n    public:\n        extern (D) this(Array!(d_uns64)* _data, d_uns64 _sz_size_t)\n        {\n            this.data = _data;\n            this.sz_size_t = _sz_size_t;\n        }\n\n        void setpointer(d_uns64 off)\n        {\n            d_uns64 ptroff = off / sz_size_t;\n            (*data)[cast(size_t)(ptroff / (8 * sz_size_t))] |= 1L << (ptroff % (8 * sz_size_t));\n        }\n\n        override void visit(Type t)\n        {\n            Type tb = t.toBasetype();\n            if (tb != t)\n                tb.accept(this);\n        }\n\n        override void visit(TypeError t)\n        {\n            visit(cast(Type)t);\n        }\n\n        override void visit(TypeNext t)\n        {\n            assert(0);\n        }\n\n        override void visit(TypeBasic t)\n        {\n            if (t.ty == Tvoid)\n                setpointer(offset);\n        }\n\n        override void visit(TypeVector t)\n        {\n        }\n\n        override void visit(TypeArray t)\n        {\n            assert(0);\n        }\n\n        override void visit(TypeSArray t)\n        {\n            d_uns64 arrayoff = offset;\n            d_uns64 nextsize = t.next.size();\n            if (nextsize == SIZE_INVALID)\n                error = true;\n            d_uns64 dim = t.dim.toInteger();\n            for (d_uns64 i = 0; i < dim; i++)\n            {\n                offset = arrayoff + i * nextsize;\n                t.next.accept(this);\n            }\n            offset = arrayoff;\n        }\n\n        override void visit(TypeDArray t)\n        {\n            setpointer(offset + sz_size_t);\n        }\n\n        // dynamic array is {length,ptr}\n        override void visit(TypeAArray t)\n        {\n            setpointer(offset);\n        }\n\n        override void visit(TypePointer t)\n        {\n            if (t.nextOf().ty != Tfunction) // don't mark function pointers\n                setpointer(offset);\n        }\n\n        override void visit(TypeReference t)\n        {\n            setpointer(offset);\n        }\n\n        override void visit(TypeClass t)\n        {\n            setpointer(offset);\n        }\n\n        override void visit(TypeFunction t)\n        {\n        }\n\n        override void visit(TypeDelegate t)\n        {\n            setpointer(offset);\n        }\n\n        // delegate is {context, function}\n        override void visit(TypeQualified t)\n        {\n            assert(0);\n        }\n\n        // assume resolved\n        override void visit(TypeIdentifier t)\n        {\n            assert(0);\n        }\n\n        override void visit(TypeInstance t)\n        {\n            assert(0);\n        }\n\n        override void visit(TypeTypeof t)\n        {\n            assert(0);\n        }\n\n        override void visit(TypeReturn t)\n        {\n            assert(0);\n        }\n\n        override void visit(TypeEnum t)\n        {\n            visit(cast(Type)t);\n        }\n\n        override void visit(TypeTuple t)\n        {\n            visit(cast(Type)t);\n        }\n\n        override void visit(TypeSlice t)\n        {\n            assert(0);\n        }\n\n        override void visit(TypeNull t)\n        {\n            // always a null pointer\n        }\n\n        override void visit(TypeStruct t)\n        {\n            d_uns64 structoff = offset;\n            foreach (v; t.sym.fields)\n            {\n                offset = structoff + v.offset;\n                if (v.type.ty == Tclass)\n                    setpointer(offset);\n                else\n                    v.type.accept(this);\n            }\n            offset = structoff;\n        }\n\n        // a \"toplevel\" class is treated as an instance, while TypeClass fields are treated as references\n        void visitClass(TypeClass t)\n        {\n            d_uns64 classoff = offset;\n            // skip vtable-ptr and monitor\n            if (t.sym.baseClass)\n                visitClass(cast(TypeClass)t.sym.baseClass.type);\n            foreach (v; t.sym.fields)\n            {\n                offset = classoff + v.offset;\n                v.type.accept(this);\n            }\n            offset = classoff;\n        }\n\n        Array!(d_uns64)* data;\n        d_uns64 offset;\n        d_uns64 sz_size_t;\n        bool error;\n    }\n\n    scope PointerBitmapVisitor pbv = new PointerBitmapVisitor(data, sz_size_t);\n    if (t.ty == Tclass)\n        pbv.visitClass(cast(TypeClass)t);\n    else\n        t.accept(pbv);\n    return pbv.error ? d_uns64.max : sz;\n}\n\n/**\n * get an array of size_t values that indicate possible pointer words in memory\n *  if interpreted as the type given as argument\n * the first array element is the size of the type for independent interpretation\n *  of the array\n * following elements bits represent one word (4/8 bytes depending on the target\n *  architecture). If set the corresponding memory might contain a pointer/reference.\n *\n *  Returns: [T.sizeof, pointerbit0-31/63, pointerbit32/64-63/128, ...]\n */\nprivate Expression pointerBitmap(TraitsExp e)\n{\n    if (!e.args || e.args.dim != 1)\n    {\n        error(e.loc, \"a single type expected for trait pointerBitmap\");\n        return new ErrorExp();\n    }\n\n    Type t = getType((*e.args)[0]);\n    if (!t)\n    {\n        error(e.loc, \"`%s` is not a type\", (*e.args)[0].toChars());\n        return new ErrorExp();\n    }\n\n    Array!(d_uns64) data;\n    d_uns64 sz = getTypePointerBitmap(e.loc, t, &data);\n    if (sz == d_uns64.max)\n        return new ErrorExp();\n\n    auto exps = new Expressions();\n    exps.push(new IntegerExp(e.loc, sz, Type.tsize_t));\n    foreach (d_uns64 i; 0 .. data.dim)\n        exps.push(new IntegerExp(e.loc, data[cast(size_t)i], Type.tsize_t));\n\n    auto ale = new ArrayLiteralExp(e.loc, Type.tsize_t.sarrayOf(data.dim + 1), exps);\n    return ale;\n}\n\nExpression semanticTraits(TraitsExp e, Scope* sc)\n{\n    static if (LOGSEMANTIC)\n    {\n        printf(\"TraitsExp::semantic() %s\\n\", e.toChars());\n    }\n\n    if (e.ident != Id.compiles &&\n        e.ident != Id.isSame &&\n        e.ident != Id.identifier &&\n        e.ident != Id.getProtection &&\n        e.ident != Id.getAttributes)\n    {\n        if (!TemplateInstance.semanticTiargs(e.loc, sc, e.args, 1))\n            return new ErrorExp();\n    }\n    size_t dim = e.args ? e.args.dim : 0;\n\n    Expression dimError(int expected)\n    {\n        e.error(\"expected %d arguments for `%s` but had %d\", expected, e.ident.toChars(), cast(int)dim);\n        return new ErrorExp();\n    }\n\n    IntegerExp True()\n    {\n        return new IntegerExp(e.loc, true, Type.tbool);\n    }\n\n    IntegerExp False()\n    {\n        return new IntegerExp(e.loc, false, Type.tbool);\n    }\n\n    /********\n     * Gets the function type from a given AST node\n     * if the node is a function of some sort.\n     * Params:\n     *   o = an AST node to check for a `TypeFunction`\n     *   fdp = if `o` is a FuncDeclaration then fdp is set to that, otherwise `null`\n     * Returns:\n     *   a type node if `o` is a declaration of\n     *   a delegate, function, function-pointer or a variable of the former.\n     *   Otherwise, `null`.\n     */\n    static TypeFunction toTypeFunction(RootObject o, out FuncDeclaration fdp)\n    {\n        Type t;\n        if (auto s = getDsymbolWithoutExpCtx(o))\n        {\n            if (auto fd = s.isFuncDeclaration())\n            {\n                t = fd.type;\n                fdp = fd;\n            }\n            else if (auto vd = s.isVarDeclaration())\n                t = vd.type;\n            else\n                t = isType(o);\n        }\n        else\n            t = isType(o);\n\n        if (t)\n        {\n            if (t.ty == Tfunction)\n                return cast(TypeFunction)t;\n            else if (t.ty == Tdelegate)\n                return cast(TypeFunction)t.nextOf();\n            else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)\n                return cast(TypeFunction)t.nextOf();\n        }\n\n        return null;\n    }\n\n    IntegerExp isX(T)(bool function(T) fp)\n    {\n        if (!dim)\n            return False();\n        foreach (o; *e.args)\n        {\n            static if (is(T == Type))\n                auto y = getType(o);\n\n            static if (is(T : Dsymbol))\n            {\n                auto s = getDsymbolWithoutExpCtx(o);\n                if (!s)\n                    return False();\n            }\n            static if (is(T == Dsymbol))\n                alias y = s;\n            static if (is(T == Declaration))\n                auto y = s.isDeclaration();\n            static if (is(T == FuncDeclaration))\n                auto y = s.isFuncDeclaration();\n            static if (is(T == EnumMember))\n                auto y = s.isEnumMember();\n\n            if (!y || !fp(y))\n                return False();\n        }\n        return True();\n    }\n\n    alias isTypeX = isX!Type;\n    alias isDsymX = isX!Dsymbol;\n    alias isDeclX = isX!Declaration;\n    alias isFuncX = isX!FuncDeclaration;\n    alias isEnumMemX = isX!EnumMember;\n\n    if (e.ident == Id.isArithmetic)\n    {\n        return isTypeX(t => t.isintegral() || t.isfloating());\n    }\n    if (e.ident == Id.isFloating)\n    {\n        return isTypeX(t => t.isfloating());\n    }\n    if (e.ident == Id.isIntegral)\n    {\n        return isTypeX(t => t.isintegral());\n    }\n    if (e.ident == Id.isScalar)\n    {\n        return isTypeX(t => t.isscalar());\n    }\n    if (e.ident == Id.isUnsigned)\n    {\n        return isTypeX(t => t.isunsigned());\n    }\n    if (e.ident == Id.isAssociativeArray)\n    {\n        return isTypeX(t => t.toBasetype().ty == Taarray);\n    }\n    if (e.ident == Id.isDeprecated)\n    {\n        if (global.params.vcomplex)\n        {\n            if (isTypeX(t => t.iscomplex() || t.isimaginary()).isBool(true))\n                return True();\n        }\n        return isDsymX(t => t.isDeprecated());\n    }\n    if (e.ident == Id.isFuture)\n    {\n       return isDeclX(t => t.isFuture());\n    }\n    if (e.ident == Id.isStaticArray)\n    {\n        return isTypeX(t => t.toBasetype().ty == Tsarray);\n    }\n    if (e.ident == Id.isAbstractClass)\n    {\n        return isTypeX(t => t.toBasetype().ty == Tclass &&\n                            (cast(TypeClass)t.toBasetype()).sym.isAbstract());\n    }\n    if (e.ident == Id.isFinalClass)\n    {\n        return isTypeX(t => t.toBasetype().ty == Tclass &&\n                            ((cast(TypeClass)t.toBasetype()).sym.storage_class & STC.final_) != 0);\n    }\n    if (e.ident == Id.isTemplate)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        return isDsymX((s)\n        {\n            if (!s.toAlias().isOverloadable())\n                return false;\n            return overloadApply(s,\n                sm => sm.isTemplateDeclaration() !is null) != 0;\n        });\n    }\n    if (e.ident == Id.isPOD)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        auto o = (*e.args)[0];\n        auto t = isType(o);\n        if (!t)\n        {\n            e.error(\"type expected as second argument of __traits `%s` instead of `%s`\",\n                e.ident.toChars(), o.toChars());\n            return new ErrorExp();\n        }\n\n        Type tb = t.baseElemOf();\n        if (auto sd = tb.ty == Tstruct ? (cast(TypeStruct)tb).sym : null)\n        {\n            return sd.isPOD() ? True() : False();\n        }\n        return True();\n    }\n    if (e.ident == Id.isNested)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        auto o = (*e.args)[0];\n        auto s = getDsymbolWithoutExpCtx(o);\n        if (!s)\n        {\n        }\n        else if (auto ad = s.isAggregateDeclaration())\n        {\n            return ad.isNested() ? True() : False();\n        }\n        else if (auto fd = s.isFuncDeclaration())\n        {\n            return fd.isNested() ? True() : False();\n        }\n\n        e.error(\"aggregate or function expected instead of `%s`\", o.toChars());\n        return new ErrorExp();\n    }\n    if (e.ident == Id.isDisabled)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        return isDeclX(f => f.isDisabled());\n    }\n    if (e.ident == Id.isAbstractFunction)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        return isFuncX(f => f.isAbstract());\n    }\n    if (e.ident == Id.isVirtualFunction)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        return isFuncX(f => f.isVirtual());\n    }\n    if (e.ident == Id.isVirtualMethod)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        return isFuncX(f => f.isVirtualMethod());\n    }\n    if (e.ident == Id.isFinalFunction)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        return isFuncX(f => f.isFinalFunc());\n    }\n    if (e.ident == Id.isOverrideFunction)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        return isFuncX(f => f.isOverride());\n    }\n    if (e.ident == Id.isStaticFunction)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        return isFuncX(f => !f.needThis() && !f.isNested());\n    }\n    if (e.ident == Id.isRef)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        return isDeclX(d => d.isRef());\n    }\n    if (e.ident == Id.isOut)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        return isDeclX(d => d.isOut());\n    }\n    if (e.ident == Id.isLazy)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        return isDeclX(d => (d.storage_class & STC.lazy_) != 0);\n    }\n    if (e.ident == Id.identifier)\n    {\n        // Get identifier for symbol as a string literal\n        /* Specify 0 for bit 0 of the flags argument to semanticTiargs() so that\n         * a symbol should not be folded to a constant.\n         * Bit 1 means don't convert Parameter to Type if Parameter has an identifier\n         */\n        if (!TemplateInstance.semanticTiargs(e.loc, sc, e.args, 2))\n            return new ErrorExp();\n        if (dim != 1)\n            return dimError(1);\n\n        auto o = (*e.args)[0];\n        Identifier id;\n        if (auto po = isParameter(o))\n        {\n            if (!po.ident)\n            {\n                e.error(\"argument `%s` has no identifier\", po.type.toChars());\n                return new ErrorExp();\n            }\n            id = po.ident;\n        }\n        else\n        {\n            Dsymbol s = getDsymbolWithoutExpCtx(o);\n            if (!s || !s.ident)\n            {\n                e.error(\"argument `%s` has no identifier\", o.toChars());\n                return new ErrorExp();\n            }\n            id = s.ident;\n        }\n\n        auto se = new StringExp(e.loc, cast(char*)id.toChars());\n        return se.expressionSemantic(sc);\n    }\n    if (e.ident == Id.getProtection)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        Scope* sc2 = sc.push();\n        sc2.flags = sc.flags | SCOPE.noaccesscheck;\n        bool ok = TemplateInstance.semanticTiargs(e.loc, sc2, e.args, 1);\n        sc2.pop();\n        if (!ok)\n            return new ErrorExp();\n\n        auto o = (*e.args)[0];\n        auto s = getDsymbolWithoutExpCtx(o);\n        if (!s)\n        {\n            if (!isError(o))\n                e.error(\"argument `%s` has no protection\", o.toChars());\n            return new ErrorExp();\n        }\n        if (s.semanticRun == PASS.init)\n            s.dsymbolSemantic(null);\n\n        auto protName = protectionToChars(s.prot().kind); // TODO: How about package(names)\n        assert(protName);\n        auto se = new StringExp(e.loc, cast(char*)protName);\n        return se.expressionSemantic(sc);\n    }\n    if (e.ident == Id.parent)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        auto o = (*e.args)[0];\n        auto s = getDsymbolWithoutExpCtx(o);\n        if (s)\n        {\n            // https://issues.dlang.org/show_bug.cgi?id=12496\n            // Consider:\n            // class T1\n            // {\n            //     class C(uint value) { }\n            // }\n            // __traits(parent, T1.C!2)\n            if (auto ad = s.isAggregateDeclaration())  // `s` is `C`\n            {\n                if (ad.isNested())                     // `C` is nested\n                {\n                    if (auto p = s.toParent())         // `C`'s parent is `C!2`, believe it or not\n                    {\n                        if (p.isTemplateInstance())    // `C!2` is a template instance\n                            s = p;                     // `C!2`'s parent is `T1`\n                    }\n                }\n            }\n\n            if (auto fd = s.isFuncDeclaration()) // https://issues.dlang.org/show_bug.cgi?id=8943\n                s = fd.toAliasFunc();\n            if (!s.isImport()) // https://issues.dlang.org/show_bug.cgi?id=8922\n                s = s.toParent();\n        }\n        if (!s || s.isImport())\n        {\n            e.error(\"argument `%s` has no parent\", o.toChars());\n            return new ErrorExp();\n        }\n\n        if (auto f = s.isFuncDeclaration())\n        {\n            if (auto td = getFuncTemplateDecl(f))\n            {\n                if (td.overroot) // if not start of overloaded list of TemplateDeclaration's\n                    td = td.overroot; // then get the start\n                Expression ex = new TemplateExp(e.loc, td, f);\n                ex = ex.expressionSemantic(sc);\n                return ex;\n            }\n            if (auto fld = f.isFuncLiteralDeclaration())\n            {\n                // Directly translate to VarExp instead of FuncExp\n                Expression ex = new VarExp(e.loc, fld, true);\n                return ex.expressionSemantic(sc);\n            }\n        }\n        return resolve(e.loc, sc, s, false);\n    }\n    if (e.ident == Id.hasMember ||\n        e.ident == Id.getMember ||\n        e.ident == Id.getOverloads ||\n        e.ident == Id.getVirtualMethods ||\n        e.ident == Id.getVirtualFunctions)\n    {\n        if (dim != 2 && !(dim == 3 && e.ident == Id.getOverloads))\n            return dimError(2);\n\n        auto o = (*e.args)[0];\n        auto ex = isExpression((*e.args)[1]);\n        if (!ex)\n        {\n            e.error(\"expression expected as second argument of __traits `%s`\", e.ident.toChars());\n            return new ErrorExp();\n        }\n        ex = ex.ctfeInterpret();\n\n        bool includeTemplates = false;\n        if (dim == 3 && e.ident == Id.getOverloads)\n        {\n            auto b = isExpression((*e.args)[2]);\n            b = b.ctfeInterpret();\n            if (!b.type.equals(Type.tbool))\n            {\n                e.error(\"`bool` expected as third argument of `__traits(getOverloads)`, not `%s` of type `%s`\", b.toChars(), b.type.toChars());\n                return new ErrorExp();\n            }\n            includeTemplates = b.isBool(true);\n        }\n\n        StringExp se = ex.toStringExp();\n        if (!se || se.len == 0)\n        {\n            e.error(\"string expected as second argument of __traits `%s` instead of `%s`\", e.ident.toChars(), ex.toChars());\n            return new ErrorExp();\n        }\n        se = se.toUTF8(sc);\n\n        if (se.sz != 1)\n        {\n            e.error(\"string must be chars\");\n            return new ErrorExp();\n        }\n        auto id = Identifier.idPool(se.peekSlice());\n\n        /* Prefer dsymbol, because it might need some runtime contexts.\n         */\n        Dsymbol sym = getDsymbol(o);\n        if (sym)\n        {\n            if (e.ident == Id.hasMember)\n            {\n                if (auto sm = sym.search(e.loc, id))\n                    return True();\n            }\n            ex = new DsymbolExp(e.loc, sym);\n            ex = new DotIdExp(e.loc, ex, id);\n        }\n        else if (auto t = isType(o))\n            ex = typeDotIdExp(e.loc, t, id);\n        else if (auto ex2 = isExpression(o))\n            ex = new DotIdExp(e.loc, ex2, id);\n        else\n        {\n            e.error(\"invalid first argument\");\n            return new ErrorExp();\n        }\n\n        // ignore symbol visibility for these traits, should disable access checks as well\n        Scope* scx = sc.push();\n        scx.flags |= SCOPE.ignoresymbolvisibility;\n        scope (exit) scx.pop();\n\n        if (e.ident == Id.hasMember)\n        {\n            /* Take any errors as meaning it wasn't found\n             */\n            ex = ex.trySemantic(scx);\n            return ex ? True() : False();\n        }\n        else if (e.ident == Id.getMember)\n        {\n            if (ex.op == TOK.dotIdentifier)\n                // Prevent semantic() from replacing Symbol with its initializer\n                (cast(DotIdExp)ex).wantsym = true;\n            ex = ex.expressionSemantic(scx);\n            return ex;\n        }\n        else if (e.ident == Id.getVirtualFunctions ||\n                 e.ident == Id.getVirtualMethods ||\n                 e.ident == Id.getOverloads)\n        {\n            uint errors = global.errors;\n            Expression eorig = ex;\n            ex = ex.expressionSemantic(scx);\n            if (errors < global.errors)\n                e.error(\"`%s` cannot be resolved\", eorig.toChars());\n\n            /* Create tuple of functions of ex\n             */\n            auto exps = new Expressions();\n            Dsymbol f;\n            if (ex.op == TOK.variable)\n            {\n                VarExp ve = cast(VarExp)ex;\n                f = ve.var.isFuncDeclaration();\n                ex = null;\n            }\n            else if (ex.op == TOK.dotVariable)\n            {\n                DotVarExp dve = cast(DotVarExp)ex;\n                f = dve.var.isFuncDeclaration();\n                if (dve.e1.op == TOK.dotType || dve.e1.op == TOK.this_)\n                    ex = null;\n                else\n                    ex = dve.e1;\n            }\n            else if (ex.op == TOK.template_)\n            {\n                VarExp ve = cast(VarExp)ex;\n                auto td = ve.var.isTemplateDeclaration();\n                f = td;\n                if (td && td.funcroot)\n                    f = td.funcroot;\n                ex = null;\n            }\n\n            bool[string] funcTypeHash;\n\n            /* Compute the function signature and insert it in the\n             * hashtable, if not present. This is needed so that\n             * traits(getOverlods, F3, \"visit\") does not count `int visit(int)`\n             * twice in the following example:\n             *\n             * =============================================\n             * interface F1 { int visit(int);}\n             * interface F2 { int visit(int); void visit(); }\n             * interface F3 : F2, F1 {}\n             *==============================================\n             */\n            void insertInterfaceInheritedFunction(FuncDeclaration fd, Expression e)\n            {\n                auto funcType = fd.type.toChars();\n                auto len = strlen(funcType);\n                string signature = funcType[0 .. len].idup;\n                //printf(\"%s - %s\\n\", fd.toChars, signature);\n                if (signature !in funcTypeHash)\n                {\n                    funcTypeHash[signature] = true;\n                    exps.push(e);\n                }\n            }\n\n            int dg(Dsymbol s)\n            {\n                if (includeTemplates)\n                {\n                    exps.push(new DsymbolExp(Loc.initial, s, false));\n                    return 0;\n                }\n                auto fd = s.isFuncDeclaration();\n                if (!fd)\n                    return 0;\n                if (e.ident == Id.getVirtualFunctions && !fd.isVirtual())\n                    return 0;\n                if (e.ident == Id.getVirtualMethods && !fd.isVirtualMethod())\n                    return 0;\n\n                auto fa = new FuncAliasDeclaration(fd.ident, fd, false);\n                fa.protection = fd.protection;\n\n                auto e = ex ? new DotVarExp(Loc.initial, ex, fa, false)\n                            : new DsymbolExp(Loc.initial, fa, false);\n\n                // if the parent is an interface declaration\n                // we must check for functions with the same signature\n                // in different inherited interfaces\n                if (sym && sym.isInterfaceDeclaration())\n                    insertInterfaceInheritedFunction(fd, e);\n                else\n                    exps.push(e);\n                return 0;\n            }\n\n            InterfaceDeclaration ifd = null;\n            if (sym)\n                ifd = sym.isInterfaceDeclaration();\n            // If the symbol passed as a parameter is an\n            // interface that inherits other interfaces\n            overloadApply(f, &dg);\n            if (ifd && ifd.interfaces && f)\n            {\n                // check the overloads of each inherited interface individually\n                foreach (bc; ifd.interfaces)\n                {\n                    if (auto fd = bc.sym.search(e.loc, f.ident))\n                        overloadApply(fd, &dg);\n                }\n            }\n\n            auto tup = new TupleExp(e.loc, exps);\n            return tup.expressionSemantic(scx);\n        }\n        else\n            assert(0);\n    }\n    if (e.ident == Id.classInstanceSize)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        auto o = (*e.args)[0];\n        auto s = getDsymbol(o);\n        auto cd = s ? s.isClassDeclaration() : null;\n        if (!cd)\n        {\n            e.error(\"first argument is not a class\");\n            return new ErrorExp();\n        }\n        if (cd.sizeok != Sizeok.done)\n        {\n            cd.size(e.loc);\n        }\n        if (cd.sizeok != Sizeok.done)\n        {\n            e.error(\"%s `%s` is forward referenced\", cd.kind(), cd.toChars());\n            return new ErrorExp();\n        }\n\n        return new IntegerExp(e.loc, cd.structsize, Type.tsize_t);\n    }\n    if (e.ident == Id.getAliasThis)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        auto o = (*e.args)[0];\n        auto s = getDsymbol(o);\n        auto ad = s ? s.isAggregateDeclaration() : null;\n        if (!ad)\n        {\n            e.error(\"argument is not an aggregate type\");\n            return new ErrorExp();\n        }\n\n        auto exps = new Expressions();\n        if (ad.aliasthis)\n            exps.push(new StringExp(e.loc, cast(char*)ad.aliasthis.ident.toChars()));\n        Expression ex = new TupleExp(e.loc, exps);\n        ex = ex.expressionSemantic(sc);\n        return ex;\n    }\n    if (e.ident == Id.getAttributes)\n    {\n        /* Specify 0 for bit 0 of the flags argument to semanticTiargs() so that\n         * a symbol should not be folded to a constant.\n         * Bit 1 means don't convert Parameter to Type if Parameter has an identifier\n         */\n        if (!TemplateInstance.semanticTiargs(e.loc, sc, e.args, 3))\n            return new ErrorExp();\n\n        if (dim != 1)\n            return dimError(1);\n\n        auto o = (*e.args)[0];\n        auto po = isParameter(o);\n        auto s = getDsymbolWithoutExpCtx(o);\n        UserAttributeDeclaration udad = null;\n        if (po)\n        {\n            udad = po.userAttribDecl;\n        }\n        else if (s)\n        {\n            if (s.isImport())\n            {\n                s = s.isImport().mod;\n            }\n            //printf(\"getAttributes %s, attrs = %p, scope = %p\\n\", s.toChars(), s.userAttribDecl, s.scope);\n            udad = s.userAttribDecl;\n        }\n        else\n        {\n            version (none)\n            {\n                Expression x = isExpression(o);\n                Type t = isType(o);\n                if (x)\n                    printf(\"e = %s %s\\n\", Token.toChars(x.op), x.toChars());\n                if (t)\n                    printf(\"t = %d %s\\n\", t.ty, t.toChars());\n            }\n            e.error(\"first argument is not a symbol\");\n            return new ErrorExp();\n        }\n\n        auto exps = udad ? udad.getAttributes() : new Expressions();\n        auto tup = new TupleExp(e.loc, exps);\n        return tup.expressionSemantic(sc);\n    }\n    if (e.ident == Id.getFunctionAttributes)\n    {\n        /* Extract all function attributes as a tuple (const/shared/inout/pure/nothrow/etc) except UDAs.\n         * https://dlang.org/spec/traits.html#getFunctionAttributes\n         */\n        if (dim != 1)\n            return dimError(1);\n\n        FuncDeclaration fd;\n        TypeFunction tf = toTypeFunction((*e.args)[0], fd);\n\n        if (!tf)\n        {\n            e.error(\"first argument is not a function\");\n            return new ErrorExp();\n        }\n\n        auto mods = new Expressions();\n        PushAttributes pa;\n        pa.mods = mods;\n        tf.modifiersApply(&pa, &PushAttributes.fp);\n        tf.attributesApply(&pa, &PushAttributes.fp, TRUSTformatSystem);\n\n        auto tup = new TupleExp(e.loc, mods);\n        return tup.expressionSemantic(sc);\n    }\n    if (e.ident == Id.isReturnOnStack)\n    {\n        /* Extract as a boolean if function return value is on the stack\n         * https://dlang.org/spec/traits.html#isReturnOnStack\n         */\n        if (dim != 1)\n            return dimError(1);\n\n        RootObject o = (*e.args)[0];\n        FuncDeclaration fd;\n        TypeFunction tf = toTypeFunction(o, fd);\n\n        if (!tf)\n        {\n            e.error(\"argument to `__traits(isReturnOnStack, %s)` is not a function\", o.toChars());\n            return new ErrorExp();\n        }\n\n        bool value = Target.isReturnOnStack(tf, fd && fd.needThis());\n        return new IntegerExp(e.loc, value, Type.tbool);\n    }\n    if (e.ident == Id.getFunctionVariadicStyle)\n    {\n        /* Accept a symbol or a type. Returns one of the following:\n         *  \"none\"      not a variadic function\n         *  \"argptr\"    extern(D) void dstyle(...), use `__argptr` and `__arguments`\n         *  \"stdarg\"    extern(C) void cstyle(int, ...), use core.stdc.stdarg\n         *  \"typesafe\"  void typesafe(T[] ...)\n         */\n        // get symbol linkage as a string\n        if (dim != 1)\n            return dimError(1);\n\n        LINK link;\n        int varargs;\n        auto o = (*e.args)[0];\n\n        FuncDeclaration fd;\n        TypeFunction tf = toTypeFunction(o, fd);\n\n        if (tf)\n        {\n            link = tf.linkage;\n            varargs = tf.varargs;\n        }\n        else\n        {\n            if (!fd)\n            {\n                e.error(\"argument to `__traits(getFunctionVariadicStyle, %s)` is not a function\", o.toChars());\n                return new ErrorExp();\n            }\n            link = fd.linkage;\n            fd.getParameters(&varargs);\n        }\n        string style;\n        switch (varargs)\n        {\n            case 0: style = \"none\";                       break;\n            case 1: style = (link == LINK.d) ? \"argptr\"\n                                             : \"stdarg\";  break;\n            case 2:     style = \"typesafe\";               break;\n            default:\n                assert(0);\n        }\n        auto se = new StringExp(e.loc, cast(char*)style);\n        return se.expressionSemantic(sc);\n    }\n    if (e.ident == Id.getParameterStorageClasses)\n    {\n        /* Accept a function symbol or a type, followed by a parameter index.\n         * Returns a tuple of strings of the parameter's storage classes.\n         */\n        // get symbol linkage as a string\n        if (dim != 2)\n            return dimError(2);\n\n        auto o = (*e.args)[0];\n        auto o1 = (*e.args)[1];\n\n        FuncDeclaration fd;\n        TypeFunction tf = toTypeFunction(o, fd);\n\n        Parameters* fparams;\n        if (tf)\n        {\n            fparams = tf.parameters;\n        }\n        else\n        {\n            if (!fd)\n            {\n                e.error(\"first argument to `__traits(getParameterStorageClasses, %s, %s)` is not a function\",\n                    o.toChars(), o1.toChars());\n                return new ErrorExp();\n            }\n            fparams = fd.getParameters(null);\n        }\n\n        StorageClass stc;\n\n        // Set stc to storage class of the ith parameter\n        auto ex = isExpression((*e.args)[1]);\n        if (!ex)\n        {\n            e.error(\"expression expected as second argument of `__traits(getParameterStorageClasses, %s, %s)`\",\n                o.toChars(), o1.toChars());\n            return new ErrorExp();\n        }\n        ex = ex.ctfeInterpret();\n        auto ii = ex.toUInteger();\n        if (ii >= Parameter.dim(fparams))\n        {\n            e.error(\"parameter index must be in range 0..%u not %s\", cast(uint)Parameter.dim(fparams), ex.toChars());\n            return new ErrorExp();\n        }\n\n        uint n = cast(uint)ii;\n        Parameter p = Parameter.getNth(fparams, n);\n        stc = p.storageClass;\n\n        // This mirrors hdrgen.visit(Parameter p)\n        if (p.type && p.type.mod & MODFlags.shared_)\n            stc &= ~STC.shared_;\n\n        auto exps = new Expressions;\n\n        void push(string s)\n        {\n            exps.push(new StringExp(e.loc, cast(char*)s.ptr, cast(uint)s.length));\n        }\n\n        if (stc & STC.auto_)\n            push(\"auto\");\n        if (stc & STC.return_)\n            push(\"return\");\n\n        if (stc & STC.out_)\n            push(\"out\");\n        else if (stc & STC.ref_)\n            push(\"ref\");\n        else if (stc & STC.in_)\n            push(\"in\");\n        else if (stc & STC.lazy_)\n            push(\"lazy\");\n        else if (stc & STC.alias_)\n            push(\"alias\");\n\n        if (stc & STC.const_)\n            push(\"const\");\n        if (stc & STC.immutable_)\n            push(\"immutable\");\n        if (stc & STC.wild)\n            push(\"inout\");\n        if (stc & STC.shared_)\n            push(\"shared\");\n        if (stc & STC.scope_ && !(stc & STC.scopeinferred))\n            push(\"scope\");\n\n        auto tup = new TupleExp(e.loc, exps);\n        return tup.expressionSemantic(sc);\n    }\n    if (e.ident == Id.getLinkage)\n    {\n        // get symbol linkage as a string\n        if (dim != 1)\n            return dimError(1);\n\n        LINK link;\n        auto o = (*e.args)[0];\n\n        FuncDeclaration fd;\n        TypeFunction tf = toTypeFunction(o, fd);\n\n        if (tf)\n            link = tf.linkage;\n        else\n        {\n            auto s = getDsymbol(o);\n            Declaration d;\n            AggregateDeclaration agg;\n            if (!s || ((d = s.isDeclaration()) is null && (agg = s.isAggregateDeclaration()) is null))\n            {\n                e.error(\"argument to `__traits(getLinkage, %s)` is not a declaration\", o.toChars());\n                return new ErrorExp();\n            }\n            if (d !is null)\n                link = d.linkage;\n            else final switch (agg.classKind)\n            {\n                case ClassKind.d:\n                    link = LINK.d;\n                    break;\n                case ClassKind.cpp:\n                    link = LINK.cpp;\n                    break;\n                case ClassKind.objc:\n                    link = LINK.objc;\n                    break;\n            }\n        }\n        auto linkage = linkageToChars(link);\n        auto se = new StringExp(e.loc, cast(char*)linkage);\n        return se.expressionSemantic(sc);\n    }\n    if (e.ident == Id.allMembers ||\n        e.ident == Id.derivedMembers)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        auto o = (*e.args)[0];\n        auto s = getDsymbol(o);\n        if (!s)\n        {\n            e.error(\"argument has no members\");\n            return new ErrorExp();\n        }\n        if (auto imp = s.isImport())\n        {\n            // https://issues.dlang.org/show_bug.cgi?id=9692\n            s = imp.mod;\n        }\n\n        auto sds = s.isScopeDsymbol();\n        if (!sds || sds.isTemplateDeclaration())\n        {\n            e.error(\"%s `%s` has no members\", s.kind(), s.toChars());\n            return new ErrorExp();\n        }\n\n        auto idents = new Identifiers();\n\n        int pushIdentsDg(size_t n, Dsymbol sm)\n        {\n            if (!sm)\n                return 1;\n\n            // skip local symbols, such as static foreach loop variables\n            if (auto decl = sm.isDeclaration())\n            {\n                if (decl.storage_class & STC.local)\n                {\n                    return 0;\n                }\n            }\n\n            //printf(\"\\t[%i] %s %s\\n\", i, sm.kind(), sm.toChars());\n            if (sm.ident)\n            {\n                const idx = sm.ident.toChars();\n                if (idx[0] == '_' &&\n                    idx[1] == '_' &&\n                    sm.ident != Id.ctor &&\n                    sm.ident != Id.dtor &&\n                    sm.ident != Id.__xdtor &&\n                    sm.ident != Id.postblit &&\n                    sm.ident != Id.__xpostblit)\n                {\n                    return 0;\n                }\n                if (sm.ident == Id.empty)\n                {\n                    return 0;\n                }\n                if (sm.isTypeInfoDeclaration()) // https://issues.dlang.org/show_bug.cgi?id=15177\n                    return 0;\n                if (!sds.isModule() && sm.isImport()) // https://issues.dlang.org/show_bug.cgi?id=17057\n                    return 0;\n\n                //printf(\"\\t%s\\n\", sm.ident.toChars());\n\n                /* Skip if already present in idents[]\n                 */\n                foreach (id; *idents)\n                {\n                    if (id == sm.ident)\n                        return 0;\n\n                    // Avoid using strcmp in the first place due to the performance impact in an O(N^2) loop.\n                    debug assert(strcmp(id.toChars(), sm.ident.toChars()) != 0);\n                }\n                idents.push(sm.ident);\n            }\n            else if (auto ed = sm.isEnumDeclaration())\n            {\n                ScopeDsymbol._foreach(null, ed.members, &pushIdentsDg);\n            }\n            return 0;\n        }\n\n        ScopeDsymbol._foreach(sc, sds.members, &pushIdentsDg);\n        auto cd = sds.isClassDeclaration();\n        if (cd && e.ident == Id.allMembers)\n        {\n            if (cd.semanticRun < PASS.semanticdone)\n                cd.dsymbolSemantic(null); // https://issues.dlang.org/show_bug.cgi?id=13668\n                                   // Try to resolve forward reference\n\n            void pushBaseMembersDg(ClassDeclaration cd)\n            {\n                for (size_t i = 0; i < cd.baseclasses.dim; i++)\n                {\n                    auto cb = (*cd.baseclasses)[i].sym;\n                    assert(cb);\n                    ScopeDsymbol._foreach(null, cb.members, &pushIdentsDg);\n                    if (cb.baseclasses.dim)\n                        pushBaseMembersDg(cb);\n                }\n            }\n\n            pushBaseMembersDg(cd);\n        }\n\n        // Turn Identifiers into StringExps reusing the allocated array\n        assert(Expressions.sizeof == Identifiers.sizeof);\n        auto exps = cast(Expressions*)idents;\n        foreach (i, id; *idents)\n        {\n            auto se = new StringExp(e.loc, cast(char*)id.toChars());\n            (*exps)[i] = se;\n        }\n\n        /* Making this a tuple is more flexible, as it can be statically unrolled.\n         * To make an array literal, enclose __traits in [ ]:\n         *   [ __traits(allMembers, ...) ]\n         */\n        Expression ex = new TupleExp(e.loc, exps);\n        ex = ex.expressionSemantic(sc);\n        return ex;\n    }\n    if (e.ident == Id.compiles)\n    {\n        /* Determine if all the objects - types, expressions, or symbols -\n         * compile without error\n         */\n        if (!dim)\n            return False();\n\n        foreach (o; *e.args)\n        {\n            uint errors = global.startGagging();\n            Scope* sc2 = sc.push();\n            sc2.tinst = null;\n            sc2.minst = null;\n            sc2.flags = (sc.flags & ~(SCOPE.ctfe | SCOPE.condition)) | SCOPE.compile | SCOPE.fullinst;\n\n            bool err = false;\n\n            auto t = isType(o);\n            auto ex = t ? t.typeToExpression() : isExpression(o);\n            if (!ex && t)\n            {\n                Dsymbol s;\n                t.resolve(e.loc, sc2, &ex, &t, &s);\n                if (t)\n                {\n                    t.typeSemantic(e.loc, sc2);\n                    if (t.ty == Terror)\n                        err = true;\n                }\n                else if (s && s.errors)\n                    err = true;\n            }\n            if (ex)\n            {\n                ex = ex.expressionSemantic(sc2);\n                ex = resolvePropertiesOnly(sc2, ex);\n                ex = ex.optimize(WANTvalue);\n                if (sc2.func && sc2.func.type.ty == Tfunction)\n                {\n                    const tf = cast(TypeFunction)sc2.func.type;\n                    err |= tf.isnothrow && canThrow(ex, sc2.func, false);\n                }\n                ex = checkGC(sc2, ex);\n                if (ex.op == TOK.error)\n                    err = true;\n            }\n\n            // Carefully detach the scope from the parent and throw it away as\n            // we only need it to evaluate the expression\n            // https://issues.dlang.org/show_bug.cgi?id=15428\n            sc2.detach();\n\n            if (global.endGagging(errors) || err)\n            {\n                return False();\n            }\n        }\n        return True();\n    }\n    if (e.ident == Id.isSame)\n    {\n        /* Determine if two symbols are the same\n         */\n        if (dim != 2)\n            return dimError(2);\n\n        if (!TemplateInstance.semanticTiargs(e.loc, sc, e.args, 0))\n            return new ErrorExp();\n\n\n        auto o1 = (*e.args)[0];\n        auto o2 = (*e.args)[1];\n\n        static FuncLiteralDeclaration isLambda(RootObject oarg)\n        {\n            if (auto t = isDsymbol(oarg))\n            {\n                if (auto td = t.isTemplateDeclaration())\n                {\n                    if (td.members && td.members.dim == 1)\n                    {\n                        if (auto fd = (*td.members)[0].isFuncLiteralDeclaration())\n                            return fd;\n                    }\n                }\n            }\n            else if (auto ea = isExpression(oarg))\n            {\n                if (ea.op == TOK.function_)\n                {\n                    if (auto fe = cast(FuncExp)ea)\n                        return fe.fd;\n                }\n            }\n\n            return null;\n        }\n\n        auto l1 = isLambda(o1);\n        auto l2 = isLambda(o2);\n\n        if (l1 && l2)\n        {\n            import dmd.lambdacomp : isSameFuncLiteral;\n            if (isSameFuncLiteral(l1, l2, sc))\n                return True();\n        }\n\n        auto s1 = getDsymbol(o1);\n        auto s2 = getDsymbol(o2);\n        //printf(\"isSame: %s, %s\\n\", o1.toChars(), o2.toChars());\n        version (none)\n        {\n            printf(\"o1: %p\\n\", o1);\n            printf(\"o2: %p\\n\", o2);\n            if (!s1)\n            {\n                if (auto ea = isExpression(o1))\n                    printf(\"%s\\n\", ea.toChars());\n                if (auto ta = isType(o1))\n                    printf(\"%s\\n\", ta.toChars());\n                return False();\n            }\n            else\n                printf(\"%s %s\\n\", s1.kind(), s1.toChars());\n        }\n        if (!s1 && !s2)\n        {\n            auto ea1 = isExpression(o1);\n            auto ea2 = isExpression(o2);\n            if (ea1 && ea2)\n            {\n                if (ea1.equals(ea2))\n                    return True();\n            }\n        }\n        if (!s1 || !s2)\n            return False();\n\n        s1 = s1.toAlias();\n        s2 = s2.toAlias();\n\n        if (auto fa1 = s1.isFuncAliasDeclaration())\n            s1 = fa1.toAliasFunc();\n        if (auto fa2 = s2.isFuncAliasDeclaration())\n            s2 = fa2.toAliasFunc();\n\n        // https://issues.dlang.org/show_bug.cgi?id=11259\n        // compare import symbol to a package symbol\n        static bool cmp(Dsymbol s1, Dsymbol s2)\n        {\n            auto imp = s1.isImport();\n            return imp && imp.pkg && imp.pkg == s2.isPackage();\n        }\n\n        if (cmp(s1,s2) || cmp(s2,s1))\n            return True();\n\n        if (s1 == s2)\n            return True();\n\n        // https://issues.dlang.org/show_bug.cgi?id=18771\n        // OverloadSets are equal if they contain the same functions\n        auto overSet1 = s1.isOverloadSet();\n        if (!overSet1)\n            return False();\n\n        auto overSet2 = s2.isOverloadSet();\n        if (!overSet2)\n            return False();\n\n        if (overSet1.a.dim != overSet2.a.dim)\n            return False();\n\n        // OverloadSets contain array of Dsymbols => O(n*n)\n        // to compare for equality as the order of overloads\n        // might not be the same\nLnext:\n        foreach(overload1; overSet1.a)\n        {\n            foreach(overload2; overSet2.a)\n            {\n                if (overload1 == overload2)\n                    continue Lnext;\n            }\n            return False();\n        }\n        return True();\n    }\n    if (e.ident == Id.getUnitTests)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        auto o = (*e.args)[0];\n        auto s = getDsymbolWithoutExpCtx(o);\n        if (!s)\n        {\n            e.error(\"argument `%s` to __traits(getUnitTests) must be a module or aggregate\",\n                o.toChars());\n            return new ErrorExp();\n        }\n        if (auto imp = s.isImport()) // https://issues.dlang.org/show_bug.cgi?id=10990\n            s = imp.mod;\n\n        auto sds = s.isScopeDsymbol();\n        if (!sds)\n        {\n            e.error(\"argument `%s` to __traits(getUnitTests) must be a module or aggregate, not a %s\",\n                s.toChars(), s.kind());\n            return new ErrorExp();\n        }\n\n        auto exps = new Expressions();\n        if (global.params.useUnitTests)\n        {\n            bool[void*] uniqueUnitTests;\n\n            void collectUnitTests(Dsymbols* a)\n            {\n                if (!a)\n                    return;\n                foreach (s; *a)\n                {\n                    if (auto atd = s.isAttribDeclaration())\n                    {\n                        collectUnitTests(atd.include(null));\n                        continue;\n                    }\n                    if (auto ud = s.isUnitTestDeclaration())\n                    {\n                        if (cast(void*)ud in uniqueUnitTests)\n                            continue;\n\n                        auto ad = new FuncAliasDeclaration(ud.ident, ud, false);\n                        ad.protection = ud.protection;\n\n                        auto e = new DsymbolExp(Loc.initial, ad, false);\n                        exps.push(e);\n\n                        uniqueUnitTests[cast(void*)ud] = true;\n                    }\n                }\n            }\n\n            collectUnitTests(sds.members);\n        }\n        auto te = new TupleExp(e.loc, exps);\n        return te.expressionSemantic(sc);\n    }\n    if (e.ident == Id.getVirtualIndex)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        auto o = (*e.args)[0];\n        auto s = getDsymbolWithoutExpCtx(o);\n\n        auto fd = s ? s.isFuncDeclaration() : null;\n        if (!fd)\n        {\n            e.error(\"first argument to __traits(getVirtualIndex) must be a function\");\n            return new ErrorExp();\n        }\n\n        fd = fd.toAliasFunc(); // Necessary to support multiple overloads.\n        return new IntegerExp(e.loc, fd.vtblIndex, Type.tptrdiff_t);\n    }\n    if (e.ident == Id.getPointerBitmap)\n    {\n        return pointerBitmap(e);\n    }\n    if (e.ident == Id.isZeroInit)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        auto o = (*e.args)[0];\n        Type t = isType(o);\n        if (!t)\n        {\n            e.error(\"type expected as second argument of __traits `%s` instead of `%s`\",\n                e.ident.toChars(), o.toChars());\n            return new ErrorExp();\n        }\n\n        Type tb = t.baseElemOf();\n        return tb.isZeroInit(e.loc) ? True() : False();\n    }\n    if (e.ident == Id.getTargetInfo)\n    {\n        if (dim != 1)\n            return dimError(1);\n\n        auto ex = isExpression((*e.args)[0]);\n        StringExp se = ex ? ex.ctfeInterpret().toStringExp() : null;\n        if (!ex || !se || se.len == 0)\n        {\n            e.error(\"string expected as argument of __traits `%s` instead of `%s`\", e.ident.toChars(), ex.toChars());\n            return new ErrorExp();\n        }\n        se = se.toUTF8(sc);\n\n        Expression r = Target.getTargetInfo(se.toPtr(), e.loc);\n        if (!r)\n        {\n            e.error(\"`getTargetInfo` key `\\\"%s\\\"` not supported by this implementation\", se.toPtr());\n            return new ErrorExp();\n        }\n        return r.expressionSemantic(sc);\n    }\n\n    extern (D) void* trait_search_fp(const(char)* seed, ref int cost)\n    {\n        //printf(\"trait_search_fp('%s')\\n\", seed);\n        size_t len = strlen(seed);\n        if (!len)\n            return null;\n        cost = 0;\n        StringValue* sv = traitsStringTable.lookup(seed, len);\n        return sv ? sv.ptrvalue : null;\n    }\n\n    if (auto sub = cast(const(char)*)speller(e.ident.toChars(), &trait_search_fp, idchars))\n        e.error(\"unrecognized trait `%s`, did you mean `%s`?\", e.ident.toChars(), sub);\n    else\n        e.error(\"unrecognized trait `%s`\", e.ident.toChars());\n    return new ErrorExp();\n}\n"
  },
  {
    "path": "gcc/d/dmd/transitivevisitor.d",
    "content": "/**\n * Documentation:  https://dlang.org/phobos/dmd_transitivevisitor.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/transitivevisitor.d\n */\n\nmodule dmd.transitivevisitor;\n\nimport dmd.permissivevisitor;\nimport dmd.tokens;\nimport dmd.root.rootobject;\n\nimport core.stdc.stdio;\n\n/** Visitor that implements the AST traversal logic. The nodes just accept their children.\n  */\nextern(C++) class ParseTimeTransitiveVisitor(AST) : PermissiveVisitor!AST\n{\n    alias visit = PermissiveVisitor!AST.visit;\n    mixin ParseVisitMethods!AST;\n}\n\n/* This mixin implements the AST traversal logic for parse time AST nodes. The same code\n * is used for semantic time AST node traversal, so in order to not duplicate the code,\n * the template mixin is used.\n */\npackage mixin template ParseVisitMethods(AST)\n{\n\n//   Statement Nodes\n//===========================================================\n    override void visit(AST.ExpStatement s)\n    {\n        //printf(\"Visiting ExpStatement\\n\");\n        if (s.exp && s.exp.op == TOK.declaration)\n        {\n            (cast(AST.DeclarationExp)s.exp).declaration.accept(this);\n            return;\n        }\n        if (s.exp)\n            s.exp.accept(this);\n    }\n\n    override void visit(AST.CompileStatement s)\n    {\n        //printf(\"Visiting CompileStatement\\n\");\n        visitArgs(s.exps);\n    }\n\n    override void visit(AST.CompoundStatement s)\n    {\n        //printf(\"Visiting CompoundStatement\\n\");\n        foreach (sx; *s.statements)\n        {\n            if (sx)\n                sx.accept(this);\n        }\n    }\n\n    void visitVarDecl(AST.VarDeclaration v)\n    {\n        //printf(\"Visiting VarDeclaration\\n\");\n        if (v.type)\n            visitType(v.type);\n        if (v._init)\n        {\n            auto ie = v._init.isExpInitializer();\n            if (ie && (ie.exp.op == TOK.construct || ie.exp.op == TOK.blit))\n                (cast(AST.AssignExp)ie.exp).e2.accept(this);\n            else\n                v._init.accept(this);\n        }\n    }\n\n    override void visit(AST.CompoundDeclarationStatement s)\n    {\n        //printf(\"Visiting CompoundDeclarationStatement\\n\");\n        foreach (sx; *s.statements)\n        {\n            auto ds = sx ? sx.isExpStatement() : null;\n            if (ds && ds.exp.op == TOK.declaration)\n            {\n                auto d = (cast(AST.DeclarationExp)ds.exp).declaration;\n                assert(d.isDeclaration());\n                if (auto v = d.isVarDeclaration())\n                    visitVarDecl(v);\n                else\n                    d.accept(this);\n            }\n        }\n    }\n\n    override void visit(AST.ScopeStatement s)\n    {\n        //printf(\"Visiting ScopeStatement\\n\");\n        if (s.statement)\n            s.statement.accept(this);\n    }\n\n    override void visit(AST.WhileStatement s)\n    {\n        //printf(\"Visiting WhileStatement\\n\");\n        s.condition.accept(this);\n        if (s._body)\n            s._body.accept(this);\n    }\n\n    override void visit(AST.DoStatement s)\n    {\n        //printf(\"Visiting DoStatement\\n\");\n        if (s._body)\n            s._body.accept(this);\n        s.condition.accept(this);\n    }\n\n    override void visit(AST.ForStatement s)\n    {\n        //printf(\"Visiting ForStatement\\n\");\n        if (s._init)\n            s._init.accept(this);\n        if (s.condition)\n            s.condition.accept(this);\n        if (s.increment)\n            s.increment.accept(this);\n        if (s._body)\n            s._body.accept(this);\n    }\n\n    override void visit(AST.ForeachStatement s)\n    {\n        //printf(\"Visiting ForeachStatement\\n\");\n        foreach (p; *s.parameters)\n            if (p.type)\n                visitType(p.type);\n        s.aggr.accept(this);\n        if (s._body)\n            s._body.accept(this);\n    }\n\n    override void visit(AST.ForeachRangeStatement s)\n    {\n        //printf(\"Visiting ForeachRangeStatement\\n\");\n        if (s.prm.type)\n            visitType(s.prm.type);\n        s.lwr.accept(this);\n        s.upr.accept(this);\n        if (s._body)\n            s._body.accept(this);\n    }\n\n    override void visit(AST.IfStatement s)\n    {\n        //printf(\"Visiting IfStatement\\n\");\n        if (s.prm && s.prm.type)\n            visitType(s.prm.type);\n        s.condition.accept(this);\n        s.ifbody.accept(this);\n        if (s.elsebody)\n            s.elsebody.accept(this);\n    }\n\n    override void visit(AST.ConditionalStatement s)\n    {\n        //printf(\"Visiting ConditionalStatement\\n\");\n        s.condition.accept(this);\n        if (s.ifbody)\n            s.ifbody.accept(this);\n        if (s.elsebody)\n            s.elsebody.accept(this);\n    }\n\n    void visitArgs(AST.Expressions* expressions, AST.Expression basis = null)\n    {\n        if (!expressions || !expressions.dim)\n            return;\n        foreach (el; *expressions)\n        {\n            if (!el)\n                el = basis;\n            if (el)\n                el.accept(this);\n        }\n    }\n\n    override void visit(AST.PragmaStatement s)\n    {\n        //printf(\"Visiting PragmaStatement\\n\");\n        if (s.args && s.args.dim)\n            visitArgs(s.args);\n        if (s._body)\n            s._body.accept(this);\n    }\n\n    override void visit(AST.StaticAssertStatement s)\n    {\n        //printf(\"Visiting StaticAssertStatement\\n\");\n        s.sa.accept(this);\n    }\n\n    override void visit(AST.SwitchStatement s)\n    {\n        //printf(\"Visiting SwitchStatement\\n\");\n        s.condition.accept(this);\n        if (s._body)\n            s._body.accept(this);\n    }\n\n    override void visit(AST.CaseStatement s)\n    {\n        //printf(\"Visiting CaseStatement\\n\");\n        s.exp.accept(this);\n        s.statement.accept(this);\n    }\n\n    override void visit(AST.CaseRangeStatement s)\n    {\n        //printf(\"Visiting CaseRangeStatement\\n\");\n        s.first.accept(this);\n        s.last.accept(this);\n        s.statement.accept(this);\n    }\n\n    override void visit(AST.DefaultStatement s)\n    {\n        //printf(\"Visiting DefaultStatement\\n\");\n        s.statement.accept(this);\n    }\n\n    override void visit(AST.GotoCaseStatement s)\n    {\n        //printf(\"Visiting GotoCaseStatement\\n\");\n        if (s.exp)\n            s.exp.accept(this);\n    }\n\n    override void visit(AST.ReturnStatement s)\n    {\n        //printf(\"Visiting ReturnStatement\\n\");\n        if (s.exp)\n            s.exp.accept(this);\n    }\n\n    override void visit(AST.SynchronizedStatement s)\n    {\n        //printf(\"Visiting SynchronizedStatement\\n\");\n        if (s.exp)\n            s.exp.accept(this);\n        if (s._body)\n            s._body.accept(this);\n    }\n\n    override void visit(AST.WithStatement s)\n    {\n        //printf(\"Visiting WithStatement\\n\");\n        s.exp.accept(this);\n        if (s._body)\n            s._body.accept(this);\n    }\n\n    override void visit(AST.TryCatchStatement s)\n    {\n        //printf(\"Visiting TryCatchStatement\\n\");\n        if (s._body)\n            s._body.accept(this);\n        foreach (c; *s.catches)\n            visit(c);\n    }\n\n    override void visit(AST.TryFinallyStatement s)\n    {\n        //printf(\"Visiting TryFinallyStatement\\n\");\n        s._body.accept(this);\n        s.finalbody.accept(this);\n    }\n\n    override void visit(AST.OnScopeStatement s)\n    {\n        //printf(\"Visiting OnScopeStatement\\n\");\n        s.statement.accept(this);\n    }\n\n    override void visit(AST.ThrowStatement s)\n    {\n        //printf(\"Visiting ThrowStatement\\n\");\n        s.exp.accept(this);\n    }\n\n    override void visit(AST.LabelStatement s)\n    {\n        //printf(\"Visiting LabelStatement\\n\");\n        if (s.statement)\n            s.statement.accept(this);\n    }\n\n    override void visit(AST.ImportStatement s)\n    {\n        //printf(\"Visiting ImportStatement\\n\");\n        foreach (imp; *s.imports)\n            imp.accept(this);\n    }\n\n    void visit(AST.Catch c)\n    {\n        //printf(\"Visiting Catch\\n\");\n        if (c.type)\n            visitType(c.type);\n        if (c.handler)\n            c.handler.accept(this);\n    }\n\n//   Type Nodes\n//============================================================\n\n    void visitType(AST.Type t)\n    {\n        //printf(\"Visiting Type\\n\");\n        if (!t)\n            return;\n        if (t.ty == AST.Tfunction)\n        {\n            visitFunctionType(cast(AST.TypeFunction)t, null);\n            return;\n        }\n        else\n            t.accept(this);\n    }\n\n    void visitFunctionType(AST.TypeFunction t, AST.TemplateDeclaration td)\n    {\n        if (t.next)\n            visitType(t.next);\n        if (td)\n        {\n            foreach (p; *td.origParameters)\n                p.accept(this);\n        }\n        visitParameters(t.parameters);\n    }\n\n    void visitParameters(AST.Parameters* parameters)\n    {\n        if (parameters)\n        {\n            size_t dim = AST.Parameter.dim(parameters);\n            foreach(i; 0..dim)\n            {\n                AST.Parameter fparam = AST.Parameter.getNth(parameters, i);\n                fparam.accept(this);\n            }\n        }\n    }\n\n    override void visit(AST.TypeVector t)\n    {\n        //printf(\"Visiting TypeVector\\n\");\n        if (!t.basetype)\n            return;\n        t.basetype.accept(this);\n    }\n\n    override void visit(AST.TypeSArray t)\n    {\n        //printf(\"Visiting TypeSArray\\n\");\n        t.next.accept(this);\n    }\n\n    override void visit(AST.TypeDArray t)\n    {\n        //printf(\"Visiting TypeDArray\\n\");\n        t.next.accept(this);\n    }\n\n    override void visit(AST.TypeAArray t)\n    {\n        //printf(\"Visiting TypeAArray\\n\");\n        t.next.accept(this);\n        t.index.accept(this);\n    }\n\n    override void visit(AST.TypePointer t)\n    {\n        //printf(\"Visiting TypePointer\\n\");\n        if (t.next.ty == AST.Tfunction)\n        {\n            visitFunctionType(cast(AST.TypeFunction)t.next, null);\n        }\n        else\n            t.next.accept(this);\n    }\n\n    override void visit(AST.TypeReference t)\n    {\n        //printf(\"Visiting TypeReference\\n\");\n        t.next.accept(this);\n    }\n\n    override void visit(AST.TypeFunction t)\n    {\n        //printf(\"Visiting TypeFunction\\n\");\n        visitFunctionType(t, null);\n    }\n\n    override void visit(AST.TypeDelegate t)\n    {\n        //printf(\"Visiting TypeDelegate\\n\");\n        visitFunctionType(cast(AST.TypeFunction)t.next, null);\n    }\n\n    void visitTypeQualified(AST.TypeQualified t)\n    {\n        //printf(\"Visiting TypeQualified\\n\");\n        foreach (id; t.idents)\n        {\n            if (id.dyncast() == DYNCAST.dsymbol)\n                (cast(AST.TemplateInstance)id).accept(this);\n            else if (id.dyncast() == DYNCAST.expression)\n                (cast(AST.Expression)id).accept(this);\n            else if (id.dyncast() == DYNCAST.type)\n                (cast(AST.Type)id).accept(this);\n        }\n    }\n\n    override void visit(AST.TypeIdentifier t)\n    {\n        //printf(\"Visiting TypeIdentifier\\n\");\n        visitTypeQualified(t);\n    }\n\n    override void visit(AST.TypeInstance t)\n    {\n        //printf(\"Visiting TypeInstance\\n\");\n        t.tempinst.accept(this);\n        visitTypeQualified(t);\n    }\n\n    override void visit(AST.TypeTypeof t)\n    {\n        //printf(\"Visiting TypeTypeof\\n\");\n        t.exp.accept(this);\n        visitTypeQualified(t);\n    }\n\n    override void visit(AST.TypeReturn t)\n    {\n        //printf(\"Visiting TypeReturn\\n\");\n        visitTypeQualified(t);\n    }\n\n    override void visit(AST.TypeTuple t)\n    {\n        //printf(\"Visiting TypeTuple\\n\");\n        visitParameters(t.arguments);\n    }\n\n    override void visit(AST.TypeSlice t)\n    {\n        //printf(\"Visiting TypeSlice\\n\");\n        t.next.accept(this);\n        t.lwr.accept(this);\n        t.upr.accept(this);\n    }\n\n//      Miscellaneous\n//========================================================\n\n    override void visit(AST.StaticAssert s)\n    {\n        //printf(\"Visiting StaticAssert\\n\");\n        s.exp.accept(this);\n        if (s.msg)\n            s.msg.accept(this);\n    }\n\n    override void visit(AST.EnumMember em)\n    {\n        //printf(\"Visiting EnumMember\\n\");\n        if (em.type)\n            visitType(em.type);\n        if (em.value)\n            em.value.accept(this);\n    }\n\n//      Declarations\n//=========================================================\n    void visitAttribDeclaration(AST.AttribDeclaration d)\n    {\n        if (d.decl)\n            foreach (de; *d.decl)\n                de.accept(this);\n    }\n\n    override void visit(AST.AttribDeclaration d)\n    {\n        //printf(\"Visiting AttribDeclaration\\n\");\n        visitAttribDeclaration(d);\n    }\n\n    override void visit(AST.StorageClassDeclaration d)\n    {\n        //printf(\"Visiting StorageClassDeclaration\\n\");\n        visitAttribDeclaration(cast(AST.AttribDeclaration)d);\n    }\n\n    override void visit(AST.DeprecatedDeclaration d)\n    {\n        //printf(\"Visiting DeprecatedDeclaration\\n\");\n        d.msg.accept(this);\n        visitAttribDeclaration(cast(AST.AttribDeclaration)d);\n    }\n\n    override void visit(AST.LinkDeclaration d)\n    {\n        //printf(\"Visiting LinkDeclaration\\n\");\n        visitAttribDeclaration(cast(AST.AttribDeclaration)d);\n    }\n\n    override void visit(AST.CPPMangleDeclaration d)\n    {\n        //printf(\"Visiting CPPMangleDeclaration\\n\");\n        visitAttribDeclaration(cast(AST.AttribDeclaration)d);\n    }\n\n    override void visit(AST.ProtDeclaration d)\n    {\n        //printf(\"Visiting ProtDeclaration\\n\");\n        visitAttribDeclaration(cast(AST.AttribDeclaration)d);\n    }\n\n    override void visit(AST.AlignDeclaration d)\n    {\n        //printf(\"Visiting AlignDeclaration\\n\");\n        visitAttribDeclaration(cast(AST.AttribDeclaration)d);\n    }\n\n    override void visit(AST.AnonDeclaration d)\n    {\n        //printf(\"Visiting AnonDeclaration\\n\");\n        visitAttribDeclaration(cast(AST.AttribDeclaration)d);\n    }\n\n    override void visit(AST.PragmaDeclaration d)\n    {\n        //printf(\"Visiting PragmaDeclaration\\n\");\n        if (d.args && d.args.dim)\n            visitArgs(d.args);\n        visitAttribDeclaration(cast(AST.AttribDeclaration)d);\n    }\n\n    override void visit(AST.ConditionalDeclaration d)\n    {\n        //printf(\"Visiting ConditionalDeclaration\\n\");\n        d.condition.accept(this);\n        if (d.decl)\n            foreach (de; *d.decl)\n                de.accept(this);\n        if (d.elsedecl)\n            foreach (de; *d.elsedecl)\n                de.accept(this);\n    }\n\n    override void visit(AST.CompileDeclaration d)\n    {\n        //printf(\"Visiting compileDeclaration\\n\");\n        visitArgs(d.exps);\n    }\n\n    override void visit(AST.UserAttributeDeclaration d)\n    {\n        //printf(\"Visiting UserAttributeDeclaration\\n\");\n        visitArgs(d.atts);\n        visitAttribDeclaration(cast(AST.AttribDeclaration)d);\n    }\n\n    void visitFuncBody(AST.FuncDeclaration f)\n    {\n        //printf(\"Visiting funcBody\\n\");\n        if (f.frequires)\n        {\n            foreach (frequire; *f.frequires)\n            {\n                frequire.accept(this);\n            }\n        }\n        if (f.fensures)\n        {\n            foreach (fensure; *f.fensures)\n            {\n                fensure.ensure.accept(this);\n            }\n        }\n        if (f.fbody)\n        {\n            f.fbody.accept(this);\n        }\n    }\n\n    void visitBaseClasses(AST.ClassDeclaration d)\n    {\n        //printf(\"Visiting ClassDeclaration\\n\");\n        if (!d || !d.baseclasses.dim)\n            return;\n        foreach (b; *d.baseclasses)\n            visitType(b.type);\n    }\n\n    bool visitEponymousMember(AST.TemplateDeclaration d)\n    {\n        //printf(\"Visiting EponymousMember\\n\");\n        if (!d.members || d.members.dim != 1)\n            return false;\n        AST.Dsymbol onemember = (*d.members)[0];\n        if (onemember.ident != d.ident)\n            return false;\n\n        if (AST.FuncDeclaration fd = onemember.isFuncDeclaration())\n        {\n            assert(fd.type);\n            visitFunctionType(cast(AST.TypeFunction)fd.type, d);\n            if (d.constraint)\n                d.constraint.accept(this);\n            visitFuncBody(fd);\n\n            return true;\n        }\n\n        if (AST.AggregateDeclaration ad = onemember.isAggregateDeclaration())\n        {\n            visitTemplateParameters(d.parameters);\n            if (d.constraint)\n                d.constraint.accept(this);\n            visitBaseClasses(ad.isClassDeclaration());\n\n            if (ad.members)\n                foreach (s; *ad.members)\n                    s.accept(this);\n\n            return true;\n        }\n\n        if (AST.VarDeclaration vd = onemember.isVarDeclaration())\n        {\n            if (d.constraint)\n                return false;\n            if (vd.type)\n                visitType(vd.type);\n            visitTemplateParameters(d.parameters);\n            if (vd._init)\n            {\n                AST.ExpInitializer ie = vd._init.isExpInitializer();\n                if (ie && (ie.exp.op == TOK.construct || ie.exp.op == TOK.blit))\n                    (cast(AST.AssignExp)ie.exp).e2.accept(this);\n                else\n                    vd._init.accept(this);\n\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    void visitTemplateParameters(AST.TemplateParameters* parameters)\n    {\n        if (!parameters || !parameters.dim)\n            return;\n        foreach (p; *parameters)\n            p.accept(this);\n    }\n\n    override void visit(AST.TemplateDeclaration d)\n    {\n        //printf(\"Visiting TemplateDeclaration\\n\");\n        if (visitEponymousMember(d))\n            return;\n\n        visitTemplateParameters(d.parameters);\n        if (d.constraint)\n            d.constraint.accept(this);\n\n        foreach (s; *d.members)\n            s.accept(this);\n    }\n\n    void visitObject(RootObject oarg)\n    {\n        if (auto t = AST.isType(oarg))\n        {\n            visitType(t);\n        }\n        else if (auto e = AST.isExpression(oarg))\n        {\n            e.accept(this);\n        }\n        else if (auto v = AST.isTuple(oarg))\n        {\n            auto args = &v.objects;\n            foreach (arg; *args)\n                visitObject(arg);\n        }\n    }\n\n    void visitTiargs(AST.TemplateInstance ti)\n    {\n        //printf(\"Visiting tiargs\\n\");\n        if (!ti.tiargs)\n            return;\n        foreach (arg; *ti.tiargs)\n        {\n            visitObject(arg);\n        }\n    }\n\n    override void visit(AST.TemplateInstance ti)\n    {\n        //printf(\"Visiting TemplateInstance\\n\");\n        visitTiargs(ti);\n    }\n\n    override void visit(AST.TemplateMixin tm)\n    {\n        //printf(\"Visiting TemplateMixin\\n\");\n        visitType(tm.tqual);\n        visitTiargs(tm);\n    }\n\n    override void visit(AST.EnumDeclaration d)\n    {\n        //printf(\"Visiting EnumDeclaration\\n\");\n        if (d.memtype)\n            visitType(d.memtype);\n        if (!d.members)\n            return;\n        foreach (em; *d.members)\n        {\n            if (!em)\n                continue;\n            em.accept(this);\n        }\n    }\n\n    override void visit(AST.Nspace d)\n    {\n        //printf(\"Visiting Nspace\\n\");\n        foreach(s; *d.members)\n            s.accept(this);\n    }\n\n    override void visit(AST.StructDeclaration d)\n    {\n        //printf(\"Visiting StructDeclaration\\n\");\n        if (!d.members)\n            return;\n        foreach (s; *d.members)\n            s.accept(this);\n    }\n\n    override void visit(AST.ClassDeclaration d)\n    {\n        //printf(\"Visiting ClassDeclaration\\n\");\n        visitBaseClasses(d);\n        if (d.members)\n            foreach (s; *d.members)\n                s.accept(this);\n    }\n\n    override void visit(AST.AliasDeclaration d)\n    {\n        //printf(\"Visting AliasDeclaration\\n\");\n        if (d.aliassym)\n            d.aliassym.accept(this);\n        else\n            visitType(d.type);\n    }\n\n    override void visit(AST.VarDeclaration d)\n    {\n        //printf(\"Visiting VarDeclaration\\n\");\n        visitVarDecl(d);\n    }\n\n    override void visit(AST.FuncDeclaration f)\n    {\n        //printf(\"Visiting FuncDeclaration\\n\");\n        auto tf = cast(AST.TypeFunction)f.type;\n        visitType(tf);\n        visitFuncBody(f);\n    }\n\n    override void visit(AST.FuncLiteralDeclaration f)\n    {\n        //printf(\"Visiting FuncLiteralDeclaration\\n\");\n        if (f.type.ty == AST.Terror)\n            return;\n        AST.TypeFunction tf = cast(AST.TypeFunction)f.type;\n        if (!f.inferRetType && tf.next)\n            visitType(tf.next);\n        visitParameters(tf.parameters);\n        AST.CompoundStatement cs = f.fbody.isCompoundStatement();\n        AST.Statement s = !cs ? f.fbody : null;\n        AST.ReturnStatement rs = s ? s.isReturnStatement() : null;\n        if (rs && rs.exp)\n            rs.exp.accept(this);\n        else\n            visitFuncBody(f);\n    }\n\n    override void visit(AST.PostBlitDeclaration d)\n    {\n        //printf(\"Visiting PostBlitDeclaration\\n\");\n        visitFuncBody(d);\n    }\n\n    override void visit(AST.DtorDeclaration d)\n    {\n        //printf(\"Visiting DtorDeclaration\\n\");\n        visitFuncBody(d);\n    }\n\n    override void visit(AST.StaticCtorDeclaration d)\n    {\n        //printf(\"Visiting StaticCtorDeclaration\\n\");\n        visitFuncBody(d);\n    }\n\n    override void visit(AST.StaticDtorDeclaration d)\n    {\n        //printf(\"Visiting StaticDtorDeclaration\\n\");\n        visitFuncBody(d);\n    }\n\n    override void visit(AST.InvariantDeclaration d)\n    {\n        //printf(\"Visiting InvariantDeclaration\\n\");\n        visitFuncBody(d);\n    }\n\n    override void visit(AST.UnitTestDeclaration d)\n    {\n        //printf(\"Visiting UnitTestDeclaration\\n\");\n        visitFuncBody(d);\n    }\n\n    override void visit(AST.NewDeclaration d)\n    {\n        //printf(\"Visiting NewDeclaration\\n\");\n        visitParameters(d.parameters);\n        visitFuncBody(d);\n    }\n\n    override void visit(AST.DeleteDeclaration d)\n    {\n        //printf(\"Visiting DeleteDeclaration\\n\");\n        visitParameters(d.parameters);\n        visitFuncBody(d);\n    }\n\n//   Initializers\n//============================================================\n\n    override void visit(AST.StructInitializer si)\n    {\n        //printf(\"Visiting StructInitializer\\n\");\n        foreach (i, const id; si.field)\n            if (auto iz = si.value[i])\n                iz.accept(this);\n    }\n\n    override void visit(AST.ArrayInitializer ai)\n    {\n        //printf(\"Visiting ArrayInitializer\\n\");\n        foreach (i, ex; ai.index)\n        {\n            if (ex)\n                ex.accept(this);\n            if (auto iz = ai.value[i])\n                iz.accept(this);\n        }\n    }\n\n    override void visit(AST.ExpInitializer ei)\n    {\n        //printf(\"Visiting ExpInitializer\\n\");\n        ei.exp.accept(this);\n    }\n\n//      Expressions\n//===================================================\n\n    override void visit(AST.ArrayLiteralExp e)\n    {\n        //printf(\"Visiting ArrayLiteralExp\\n\");\n        visitArgs(e.elements, e.basis);\n    }\n\n    override void visit(AST.AssocArrayLiteralExp e)\n    {\n        //printf(\"Visiting AssocArrayLiteralExp\\n\");\n        foreach (i, key; *e.keys)\n        {\n            key.accept(this);\n            ((*e.values)[i]).accept(this);\n        }\n    }\n\n    override void visit(AST.TypeExp e)\n    {\n        //printf(\"Visiting TypeExp\\n\");\n        visitType(e.type);\n    }\n\n    override void visit(AST.ScopeExp e)\n    {\n        //printf(\"Visiting ScopeExp\\n\");\n        if (e.sds.isTemplateInstance())\n            e.sds.accept(this);\n    }\n\n    override void visit(AST.NewExp e)\n    {\n        //printf(\"Visiting NewExp\\n\");\n        if (e.thisexp)\n            e.thisexp.accept(this);\n        if (e.newargs && e.newargs.dim)\n            visitArgs(e.newargs);\n        visitType(e.newtype);\n        if (e.arguments && e.arguments.dim)\n            visitArgs(e.arguments);\n    }\n\n    override void visit(AST.NewAnonClassExp e)\n    {\n        //printf(\"Visiting NewAnonClassExp\\n\");\n        if (e.thisexp)\n            e.thisexp.accept(this);\n        if (e.newargs && e.newargs.dim)\n            visitArgs(e.newargs);\n        if (e.arguments && e.arguments.dim)\n            visitArgs(e.arguments);\n        if (e.cd)\n            e.cd.accept(this);\n    }\n\n    override void visit(AST.TupleExp e)\n    {\n        //printf(\"Visiting TupleExp\\n\");\n        if (e.e0)\n            e.e0.accept(this);\n        visitArgs(e.exps);\n    }\n\n    override void visit(AST.FuncExp e)\n    {\n        //printf(\"Visiting FuncExp\\n\");\n        e.fd.accept(this);\n    }\n\n    override void visit(AST.DeclarationExp e)\n    {\n        //printf(\"Visiting DeclarationExp\\n\");\n        if (auto v = e.declaration.isVarDeclaration())\n            visitVarDecl(v);\n        else\n            e.declaration.accept(this);\n    }\n\n    override void visit(AST.TypeidExp e)\n    {\n        //printf(\"Visiting TypeidExp\\n\");\n        visitObject(e.obj);\n    }\n\n    override void visit(AST.TraitsExp e)\n    {\n        //printf(\"Visiting TraitExp\\n\");\n        if (e.args)\n            foreach (arg; *e.args)\n                visitObject(arg);\n    }\n\n    override void visit(AST.IsExp e)\n    {\n        //printf(\"Visiting IsExp\\n\");\n        visitType(e.targ);\n        if (e.tspec)\n            visitType(e.tspec);\n        if (e.parameters && e.parameters.dim)\n            visitTemplateParameters(e.parameters);\n    }\n\n    override void visit(AST.UnaExp e)\n    {\n        //printf(\"Visiting UnaExp\\n\");\n        e.e1.accept(this);\n    }\n\n    override void visit(AST.BinExp e)\n    {\n        //printf(\"Visiting BinExp\\n\");\n        e.e1.accept(this);\n        e.e2.accept(this);\n    }\n\n    override void visit(AST.CompileExp e)\n    {\n        //printf(\"Visiting CompileExp\\n\");\n        visitArgs(e.exps);\n    }\n\n    override void visit(AST.ImportExp e)\n    {\n        //printf(\"Visiting ImportExp\\n\");\n        e.e1.accept(this);\n    }\n\n    override void visit(AST.AssertExp e)\n    {\n        //printf(\"Visiting AssertExp\\n\");\n        e.e1.accept(this);\n        if (e.msg)\n            e.msg.accept(this);\n    }\n\n    override void visit(AST.DotIdExp e)\n    {\n        //printf(\"Visiting DotIdExp\\n\");\n        e.e1.accept(this);\n    }\n\n    override void visit(AST.DotTemplateInstanceExp e)\n    {\n        //printf(\"Visiting DotTemplateInstanceExp\\n\");\n        e.e1.accept(this);\n        e.ti.accept(this);\n    }\n\n    override void visit(AST.CallExp e)\n    {\n        //printf(\"Visiting CallExp\\n\");\n        e.e1.accept(this);\n        visitArgs(e.arguments);\n    }\n\n    override void visit(AST.PtrExp e)\n    {\n        //printf(\"Visiting PtrExp\\n\");\n        e.e1.accept(this);\n    }\n\n    override void visit(AST.DeleteExp e)\n    {\n        //printf(\"Visiting DeleteExp\\n\");\n        e.e1.accept(this);\n    }\n\n    override void visit(AST.CastExp e)\n    {\n        //printf(\"Visiting CastExp\\n\");\n        if (e.to)\n            visitType(e.to);\n        e.e1.accept(this);\n    }\n\n    override void visit(AST.IntervalExp e)\n    {\n        //printf(\"Visiting IntervalExp\\n\");\n        e.lwr.accept(this);\n        e.upr.accept(this);\n    }\n\n    override void visit(AST.ArrayExp e)\n    {\n        //printf(\"Visiting ArrayExp\\n\");\n        e.e1.accept(this);\n        visitArgs(e.arguments);\n    }\n\n    override void visit(AST.PostExp e)\n    {\n        //printf(\"Visiting PostExp\\n\");\n        e.e1.accept(this);\n    }\n\n    override void visit(AST.CondExp e)\n    {\n        //printf(\"Visiting CondExp\\n\");\n        e.econd.accept(this);\n        e.e1.accept(this);\n        e.e2.accept(this);\n    }\n\n// Template Parameter\n//===========================================================\n\n    override void visit(AST.TemplateTypeParameter tp)\n    {\n        //printf(\"Visiting TemplateTypeParameter\\n\");\n        if (tp.specType)\n            visitType(tp.specType);\n        if (tp.defaultType)\n            visitType(tp.defaultType);\n    }\n\n    override void visit(AST.TemplateThisParameter tp)\n    {\n        //printf(\"Visiting TemplateThisParameter\\n\");\n        visit(cast(AST.TemplateTypeParameter)tp);\n    }\n\n    override void visit(AST.TemplateAliasParameter tp)\n    {\n        //printf(\"Visiting TemplateAliasParameter\\n\");\n        if (tp.specType)\n            visitType(tp.specType);\n        if (tp.specAlias)\n            visitObject(tp.specAlias);\n        if (tp.defaultAlias)\n            visitObject(tp.defaultAlias);\n    }\n\n    override void visit(AST.TemplateValueParameter tp)\n    {\n        //printf(\"Visiting TemplateValueParameter\\n\");\n        visitType(tp.valType);\n        if (tp.specValue)\n            tp.specValue.accept(this);\n        if (tp.defaultValue)\n            tp.defaultValue.accept(this);\n    }\n\n//===========================================================\n\n    override void visit(AST.StaticIfCondition c)\n    {\n        //printf(\"Visiting StaticIfCondition\\n\");\n        c.exp.accept(this);\n    }\n\n    override void visit(AST.Parameter p)\n    {\n        //printf(\"Visiting Parameter\\n\");\n        visitType(p.type);\n        if (p.defaultArg)\n            p.defaultArg.accept(this);\n    }\n\n    override void visit(AST.Module m)\n    {\n        //printf(\"Visiting Module\\n\");\n        foreach (s; *m.members)\n        {\n           s.accept(this);\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/typesem.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/typesem.d, _typesem.d)\n * Documentation:  https://dlang.org/phobos/dmd_typesem.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/typesem.d\n */\n\nmodule dmd.typesem;\n\nimport core.checkedint;\nimport core.stdc.string;\nimport core.stdc.stdio;\n\nimport dmd.access;\nimport dmd.aggregate;\nimport dmd.aliasthis;\nimport dmd.arrayop;\nimport dmd.arraytypes;\nimport dmd.complex;\nimport dmd.dcast;\nimport dmd.dclass;\nimport dmd.declaration;\nimport dmd.denum;\nimport dmd.dimport;\nimport dmd.dmangle;\nimport dmd.dscope;\nimport dmd.dstruct;\nimport dmd.dsymbol;\nimport dmd.dsymbolsem;\nimport dmd.dtemplate;\nimport dmd.errors;\nimport dmd.expression;\nimport dmd.expressionsem;\nimport dmd.func;\nimport dmd.globals;\nimport dmd.hdrgen;\nimport dmd.id;\nimport dmd.identifier;\nimport dmd.imphint;\nimport dmd.init;\nimport dmd.initsem;\nimport dmd.visitor;\nimport dmd.mtype;\nimport dmd.objc;\nimport dmd.opover;\nimport dmd.root.ctfloat;\nimport dmd.root.rmem;\nimport dmd.root.outbuffer;\nimport dmd.root.rootobject;\nimport dmd.root.stringtable;\nimport dmd.semantic3;\nimport dmd.sideeffect;\nimport dmd.target;\nimport dmd.tokens;\nimport dmd.typesem;\n\n/**************************\n * This evaluates exp while setting length to be the number\n * of elements in the tuple t.\n */\nprivate Expression semanticLength(Scope* sc, Type t, Expression exp)\n{\n    if (t.ty == Ttuple)\n    {\n        ScopeDsymbol sym = new ArrayScopeSymbol(sc, cast(TypeTuple)t);\n        sym.parent = sc.scopesym;\n        sc = sc.push(sym);\n        sc = sc.startCTFE();\n        exp = exp.expressionSemantic(sc);\n        sc = sc.endCTFE();\n        sc.pop();\n    }\n    else\n    {\n        sc = sc.startCTFE();\n        exp = exp.expressionSemantic(sc);\n        sc = sc.endCTFE();\n    }\n    return exp;\n}\n\nprivate Expression semanticLength(Scope* sc, TupleDeclaration tup, Expression exp)\n{\n    ScopeDsymbol sym = new ArrayScopeSymbol(sc, tup);\n    sym.parent = sc.scopesym;\n\n    sc = sc.push(sym);\n    sc = sc.startCTFE();\n    exp = exp.expressionSemantic(sc);\n    sc = sc.endCTFE();\n    sc.pop();\n\n    return exp;\n}\n\n/*************************************\n * Resolve a tuple index.\n */\nprivate void resolveTupleIndex(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymbol s, Expression* pe, Type* pt, Dsymbol* ps, RootObject oindex)\n{\n    *pt = null;\n    *ps = null;\n    *pe = null;\n\n    auto tup = s.isTupleDeclaration();\n\n    auto eindex = isExpression(oindex);\n    auto tindex = isType(oindex);\n    auto sindex = isDsymbol(oindex);\n\n    if (!tup)\n    {\n        // It's really an index expression\n        if (tindex)\n            eindex = new TypeExp(loc, tindex);\n        else if (sindex)\n            eindex = dmd.expressionsem.resolve(loc, sc, sindex, false);\n        Expression e = new IndexExp(loc, dmd.expressionsem.resolve(loc, sc, s, false), eindex);\n        e = e.expressionSemantic(sc);\n        mt.resolveExp(e, pt, pe, ps);\n        return;\n    }\n\n    // Convert oindex to Expression, then try to resolve to constant.\n    if (tindex)\n        tindex.resolve(loc, sc, &eindex, &tindex, &sindex);\n    if (sindex)\n        eindex = dmd.expressionsem.resolve(loc, sc, sindex, false);\n    if (!eindex)\n    {\n        .error(loc, \"index `%s` is not an expression\", oindex.toChars());\n        *pt = Type.terror;\n        return;\n    }\n\n    eindex = semanticLength(sc, tup, eindex);\n    eindex = eindex.ctfeInterpret();\n    if (eindex.op == TOK.error)\n    {\n        *pt = Type.terror;\n        return;\n    }\n    const(uinteger_t) d = eindex.toUInteger();\n    if (d >= tup.objects.dim)\n    {\n        .error(loc, \"tuple index `%llu` exceeds length %u\", d, tup.objects.dim);\n        *pt = Type.terror;\n        return;\n    }\n\n    RootObject o = (*tup.objects)[cast(size_t)d];\n    *pt = isType(o);\n    *ps = isDsymbol(o);\n    *pe = isExpression(o);\n    if (*pt)\n        *pt = (*pt).typeSemantic(loc, sc);\n    if (*pe)\n        mt.resolveExp(*pe, pt, pe, ps);\n}\n\n/*************************************\n * Takes an array of Identifiers and figures out if\n * it represents a Type or an Expression.\n * Output:\n *      if expression, *pe is set\n *      if type, *pt is set\n */\nprivate void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymbol s, Dsymbol scopesym,\n    Expression* pe, Type* pt, Dsymbol* ps, bool intypeid = false)\n{\n    version (none)\n    {\n        printf(\"TypeQualified::resolveHelper(sc = %p, idents = '%s')\\n\", sc, mt.toChars());\n        if (scopesym)\n            printf(\"\\tscopesym = '%s'\\n\", scopesym.toChars());\n    }\n    *pe = null;\n    *pt = null;\n    *ps = null;\n    if (s)\n    {\n        //printf(\"\\t1: s = '%s' %p, kind = '%s'\\n\",s.toChars(), s, s.kind());\n        Declaration d = s.isDeclaration();\n        if (d && (d.storage_class & STC.templateparameter))\n            s = s.toAlias();\n        else\n        {\n            // check for deprecated or disabled aliases\n            s.checkDeprecated(loc, sc);\n            if (d)\n                d.checkDisabled(loc, sc, true);\n        }\n        s = s.toAlias();\n        //printf(\"\\t2: s = '%s' %p, kind = '%s'\\n\",s.toChars(), s, s.kind());\n        for (size_t i = 0; i < mt.idents.dim; i++)\n        {\n            RootObject id = mt.idents[i];\n            if (id.dyncast() == DYNCAST.expression ||\n                id.dyncast() == DYNCAST.type)\n            {\n                Type tx;\n                Expression ex;\n                Dsymbol sx;\n                resolveTupleIndex(mt, loc, sc, s, &ex, &tx, &sx, id);\n                if (sx)\n                {\n                    s = sx.toAlias();\n                    continue;\n                }\n                if (tx)\n                    ex = new TypeExp(loc, tx);\n                assert(ex);\n\n                ex = typeToExpressionHelper(mt, ex, i + 1);\n                ex = ex.expressionSemantic(sc);\n                mt.resolveExp(ex, pt, pe, ps);\n                return;\n            }\n\n            Type t = s.getType(); // type symbol, type alias, or type tuple?\n            uint errorsave = global.errors;\n            int flags = t is null ? SearchLocalsOnly : IgnorePrivateImports;\n\n            Dsymbol sm = s.searchX(loc, sc, id, flags);\n            if (sm && !(sc.flags & SCOPE.ignoresymbolvisibility) && !symbolIsVisible(sc, sm))\n            {\n                .deprecation(loc, \"`%s` is not visible from module `%s`\", sm.toPrettyChars(), sc._module.toChars());\n                // sm = null;\n            }\n            if (global.errors != errorsave)\n            {\n                *pt = Type.terror;\n                return;\n            }\n            //printf(\"\\t3: s = %p %s %s, sm = %p\\n\", s, s.kind(), s.toChars(), sm);\n            if (intypeid && !t && sm && sm.needThis())\n                goto L3;\n            if (VarDeclaration v = s.isVarDeclaration())\n            {\n                if (v.storage_class & (STC.const_ | STC.immutable_ | STC.manifest) ||\n                    v.type.isConst() || v.type.isImmutable())\n                {\n                    // https://issues.dlang.org/show_bug.cgi?id=13087\n                    // this.field is not constant always\n                    if (!v.isThisDeclaration())\n                        goto L3;\n                }\n            }\n            if (!sm)\n            {\n                if (!t)\n                {\n                    if (s.isDeclaration()) // var, func, or tuple declaration?\n                    {\n                        t = s.isDeclaration().type;\n                        if (!t && s.isTupleDeclaration()) // expression tuple?\n                            goto L3;\n                    }\n                    else if (s.isTemplateInstance() ||\n                             s.isImport() || s.isPackage() || s.isModule())\n                    {\n                        goto L3;\n                    }\n                }\n                if (t)\n                {\n                    sm = t.toDsymbol(sc);\n                    if (sm && id.dyncast() == DYNCAST.identifier)\n                    {\n                        sm = sm.search(loc, cast(Identifier)id /*, IgnorePrivateImports*/);\n                        // Deprecated in 2018-01.\n                        // Change to error by deleting the deprecation line and uncommenting\n                        // the above parameter. The error will be issued in Type.getProperty.\n                        // The deprecation is highlighted here to avoid a redundant call to\n                        // ScopeDsymbol.search.\n                        // @@@DEPRECATED_2019-01@@@.\n                        if (sm)\n                        {\n                            .deprecation(loc, \"`%s` is not visible from module `%s`\", sm.toPrettyChars(), sc._module.toChars());\n                            goto L2;\n                        }\n                    }\n                L3:\n                    Expression e;\n                    VarDeclaration v = s.isVarDeclaration();\n                    FuncDeclaration f = s.isFuncDeclaration();\n                    if (intypeid || !v && !f)\n                        e = dmd.expressionsem.resolve(loc, sc, s, true);\n                    else\n                        e = new VarExp(loc, s.isDeclaration(), true);\n\n                    e = typeToExpressionHelper(mt, e, i);\n                    e = e.expressionSemantic(sc);\n                    mt.resolveExp(e, pt, pe, ps);\n                    return;\n                }\n                else\n                {\n                    if (id.dyncast() == DYNCAST.dsymbol)\n                    {\n                        // searchX already handles errors for template instances\n                        assert(global.errors);\n                    }\n                    else\n                    {\n                        assert(id.dyncast() == DYNCAST.identifier);\n                        sm = s.search_correct(cast(Identifier)id);\n                        if (sm)\n                            error(loc, \"identifier `%s` of `%s` is not defined, did you mean %s `%s`?\", id.toChars(), mt.toChars(), sm.kind(), sm.toChars());\n                        else\n                            error(loc, \"identifier `%s` of `%s` is not defined\", id.toChars(), mt.toChars());\n                    }\n                    *pe = new ErrorExp();\n                }\n                return;\n            }\n        L2:\n            s = sm.toAlias();\n        }\n\n        if (auto em = s.isEnumMember())\n        {\n            // It's not a type, it's an expression\n            *pe = em.getVarExp(loc, sc);\n            return;\n        }\n        if (auto v = s.isVarDeclaration())\n        {\n            /* This is mostly same with DsymbolExp::semantic(), but we cannot use it\n             * because some variables used in type context need to prevent lowering\n             * to a literal or contextful expression. For example:\n             *\n             *  enum a = 1; alias b = a;\n             *  template X(alias e){ alias v = e; }  alias x = X!(1);\n             *  struct S { int v; alias w = v; }\n             *      // TypeIdentifier 'a', 'e', and 'v' should be TOK.variable,\n             *      // because getDsymbol() need to work in AliasDeclaration::semantic().\n             */\n            if (!v.type ||\n                !v.type.deco && v.inuse)\n            {\n                if (v.inuse) // https://issues.dlang.org/show_bug.cgi?id=9494\n                    error(loc, \"circular reference to %s `%s`\", v.kind(), v.toPrettyChars());\n                else\n                    error(loc, \"forward reference to %s `%s`\", v.kind(), v.toPrettyChars());\n                *pt = Type.terror;\n                return;\n            }\n            if (v.type.ty == Terror)\n                *pt = Type.terror;\n            else\n                *pe = new VarExp(loc, v);\n            return;\n        }\n        if (auto fld = s.isFuncLiteralDeclaration())\n        {\n            //printf(\"'%s' is a function literal\\n\", fld.toChars());\n            *pe = new FuncExp(loc, fld);\n            *pe = (*pe).expressionSemantic(sc);\n            return;\n        }\n        version (none)\n        {\n            if (FuncDeclaration fd = s.isFuncDeclaration())\n            {\n                *pe = new DsymbolExp(loc, fd);\n                return;\n            }\n        }\n\n    L1:\n        Type t = s.getType();\n        if (!t)\n        {\n            // If the symbol is an import, try looking inside the import\n            if (Import si = s.isImport())\n            {\n                s = si.search(loc, s.ident);\n                if (s && s != si)\n                    goto L1;\n                s = si;\n            }\n            *ps = s;\n            return;\n        }\n        if (t.ty == Tinstance && t != mt && !t.deco)\n        {\n            if (!(cast(TypeInstance)t).tempinst.errors)\n                error(loc, \"forward reference to `%s`\", t.toChars());\n            *pt = Type.terror;\n            return;\n        }\n\n        if (t.ty == Ttuple)\n            *pt = t;\n        else\n            *pt = t.merge();\n    }\n    if (!s)\n    {\n        /* Look for what user might have intended\n         */\n        const p = mt.mutableOf().unSharedOf().toChars();\n        auto id = Identifier.idPool(p, cast(uint)strlen(p));\n        if (const n = importHint(id.toString()))\n            error(loc, \"`%s` is not defined, perhaps `import %.*s;` ?\", p, cast(int)n.length, n.ptr);\n        else if (auto s2 = sc.search_correct(id))\n            error(loc, \"undefined identifier `%s`, did you mean %s `%s`?\", p, s2.kind(), s2.toChars());\n        else if (const q = Scope.search_correct_C(id))\n            error(loc, \"undefined identifier `%s`, did you mean `%s`?\", p, q);\n        else\n            error(loc, \"undefined identifier `%s`\", p);\n\n        *pt = Type.terror;\n    }\n}\n\n/************************************\n * Transitively search a type for all function types.\n * If any function types with parameters are found that have parameter identifiers\n * or default arguments, remove those and create a new type stripped of those.\n * This is used to determine the \"canonical\" version of a type which is useful for\n * comparisons.\n * Params:\n *      t = type to scan\n * Returns:\n *      `t` if no parameter identifiers or default arguments found, otherwise a new type that is\n *      the same as t but with no parameter identifiers or default arguments.\n */\nprivate Type stripDefaultArgs(Type t)\n{\n    static Parameters* stripParams(Parameters* parameters)\n    {\n        static Parameter stripParameter(Parameter p)\n        {\n            Type t = stripDefaultArgs(p.type);\n            return (t != p.type || p.defaultArg || p.ident || p.userAttribDecl)\n                ? new Parameter(p.storageClass, t, null, null, null)\n                : null;\n        }\n\n        if (parameters)\n        {\n            foreach (i, p; *parameters)\n            {\n                Parameter ps = stripParameter(p);\n                if (ps)\n                {\n                    // Replace params with a copy we can modify\n                    Parameters* nparams = new Parameters(parameters.dim);\n\n                    foreach (j, ref np; *nparams)\n                    {\n                        Parameter pj = (*parameters)[j];\n                        if (j < i)\n                            np = pj;\n                        else if (j == i)\n                            np = ps;\n                        else\n                        {\n                            Parameter nps = stripParameter(pj);\n                            np = nps ? nps : pj;\n                        }\n                    }\n                    return nparams;\n                }\n            }\n        }\n        return parameters;\n    }\n\n    if (t is null)\n        return t;\n\n    if (t.ty == Tfunction)\n    {\n        TypeFunction tf = cast(TypeFunction)t;\n        Type tret = stripDefaultArgs(tf.next);\n        Parameters* params = stripParams(tf.parameters);\n        if (tret == tf.next && params == tf.parameters)\n            return t;\n        TypeFunction tr = cast(TypeFunction)tf.copy();\n        tr.parameters = params;\n        tr.next = tret;\n        //printf(\"strip %s\\n   <- %s\\n\", tr.toChars(), t.toChars());\n        return tr;\n    }\n    else if (t.ty == Ttuple)\n    {\n        TypeTuple tt = cast(TypeTuple)t;\n        Parameters* args = stripParams(tt.arguments);\n        if (args == tt.arguments)\n            return t;\n        TypeTuple tr = cast(TypeTuple)t.copy();\n        tr.arguments = args;\n        return tr;\n    }\n    else if (t.ty == Tenum)\n    {\n        // TypeEnum::nextOf() may be != NULL, but it's not necessary here.\n        return t;\n    }\n    else\n    {\n        Type tn = t.nextOf();\n        Type n = stripDefaultArgs(tn);\n        if (n == tn)\n            return t;\n        TypeNext tr = cast(TypeNext)t.copy();\n        tr.next = n;\n        return tr;\n    }\n}\n\n/******************************************\n * Perform semantic analysis on a type.\n * Params:\n *      t = Type AST node\n *      loc = the location of the type\n *      sc = context\n * Returns:\n *      `Type` with completed semantic analysis, `Terror` if errors\n *      were encountered\n */\nextern(C++) Type typeSemantic(Type t, Loc loc, Scope* sc)\n{\n    scope v = new TypeSemanticVisitor(loc, sc);\n    t.accept(v);\n    return  v.result;\n}\n\nprivate extern (C++) final class TypeToExpressionVisitor : Visitor\n{\n    alias visit = Visitor.visit;\n\n    Expression result;\n    Type itype;\n\n    this() {}\n\n    this(Type itype)\n    {\n        this.itype = itype;\n    }\n\n    override void visit(Type t)\n    {\n        result = null;\n    }\n\n    override void visit(TypeSArray t)\n    {\n        Expression e = t.next.typeToExpression();\n        if (e)\n            e = new ArrayExp(t.dim.loc, e, t.dim);\n        result = e;\n    }\n\n    override void visit(TypeAArray t)\n    {\n        Expression e = t.next.typeToExpression();\n        if (e)\n        {\n            Expression ei = t.index.typeToExpression();\n            if (ei)\n            {\n                result = new ArrayExp(t.loc, e, ei);\n                return;\n            }\n        }\n        result = null;\n    }\n\n    override void visit(TypeIdentifier t)\n    {\n        result = typeToExpressionHelper(t, new IdentifierExp(t.loc, t.ident));\n    }\n\n    override void visit(TypeInstance t)\n    {\n        result = typeToExpressionHelper(t, new ScopeExp(t.loc, t.tempinst));\n    }\n}\n\n/* We've mistakenly parsed this as a type.\n * Redo it as an Expression.\n * NULL if cannot.\n */\nExpression typeToExpression(Type t)\n{\n    scope v = new TypeToExpressionVisitor();\n    t.accept(v);\n    return v.result;\n}\n\n/* Helper function for `typeToExpression`. Contains common code\n * for TypeQualified derived classes.\n */\nExpression typeToExpressionHelper(TypeQualified t, Expression e, size_t i = 0)\n{\n    //printf(\"toExpressionHelper(e = %s %s)\\n\", Token.toChars(e.op), e.toChars());\n    foreach (id; t.idents[i .. t.idents.dim])\n    {\n        //printf(\"\\t[%d] e: '%s', id: '%s'\\n\", i, e.toChars(), id.toChars());\n\n        final switch (id.dyncast())\n        {\n            // ... '. ident'\n            case DYNCAST.identifier:\n                e = new DotIdExp(e.loc, e, cast(Identifier)id);\n                break;\n\n            // ... '. name!(tiargs)'\n            case DYNCAST.dsymbol:\n                auto ti = (cast(Dsymbol)id).isTemplateInstance();\n                assert(ti);\n                e = new DotTemplateInstanceExp(e.loc, e, ti.name, ti.tiargs);\n                break;\n\n            // ... '[type]'\n            case DYNCAST.type:          // https://issues.dlang.org/show_bug.cgi?id=1215\n                e = new ArrayExp(t.loc, e, new TypeExp(t.loc, cast(Type)id));\n                break;\n\n            // ... '[expr]'\n            case DYNCAST.expression:    // https://issues.dlang.org/show_bug.cgi?id=1215\n                e = new ArrayExp(t.loc, e, cast(Expression)id);\n                break;\n\n            case DYNCAST.object:\n            case DYNCAST.tuple:\n            case DYNCAST.parameter:\n            case DYNCAST.statement:\n            case DYNCAST.condition:\n            case DYNCAST.templateparameter:\n                assert(0);\n        }\n    }\n    return e;\n}\n\nprivate extern (C++) final class TypeSemanticVisitor : Visitor\n{\n    alias visit = Visitor.visit;\n    Loc loc;\n    Scope* sc;\n    Type result;\n\n    this(Loc loc, Scope* sc)\n    {\n        this.loc = loc;\n        this.sc = sc;\n    }\n\n    void error()\n    {\n        result = Type.terror;\n    }\n\n    override void visit(Type t)\n    {\n        if (t.ty == Tint128 || t.ty == Tuns128)\n        {\n            .error(loc, \"`cent` and `ucent` types not implemented\");\n            return error();\n        }\n\n        result = t.merge();\n    }\n\n    override void visit(TypeVector mtype)\n    {\n        uint errors = global.errors;\n        mtype.basetype = mtype.basetype.typeSemantic(loc, sc);\n        if (errors != global.errors)\n            return error();\n        mtype.basetype = mtype.basetype.toBasetype().mutableOf();\n        if (mtype.basetype.ty != Tsarray)\n        {\n            .error(loc, \"T in __vector(T) must be a static array, not `%s`\", mtype.basetype.toChars());\n            return error();\n        }\n        TypeSArray t = cast(TypeSArray)mtype.basetype;\n        const sz = cast(int)t.size(loc);\n        final switch (Target.isVectorTypeSupported(sz, t.nextOf()))\n        {\n        case 0:\n            // valid\n            break;\n\n        case 1:\n            // no support at all\n            .error(loc, \"SIMD vector types not supported on this platform\");\n            return error();\n\n        case 2:\n            // invalid base type\n            .error(loc, \"vector type `%s` is not supported on this platform\", mtype.toChars());\n            return error();\n\n        case 3:\n            // invalid size\n            if (sz == 32)\n                deprecation(loc, \"%d byte vector types are only supported with -mcpu=avx\", sz, mtype.toChars());\n            else\n            {\n                .error(loc, \"%d byte vector type `%s` is not supported on this platform\", sz, mtype.toChars());\n                return error();\n            }\n            break;\n        }\n        result = merge(mtype);\n    }\n\n    override void visit(TypeSArray mtype)\n    {\n        //printf(\"TypeSArray::semantic() %s\\n\", toChars());\n        Type t;\n        Expression e;\n        Dsymbol s;\n        mtype.next.resolve(loc, sc, &e, &t, &s);\n\n        if (auto tup = s ? s.isTupleDeclaration() : null)\n        {\n            mtype.dim = semanticLength(sc, tup, mtype.dim);\n            mtype.dim = mtype.dim.ctfeInterpret();\n            if (mtype.dim.op == TOK.error)\n                return error();\n\n            uinteger_t d = mtype.dim.toUInteger();\n            if (d >= tup.objects.dim)\n            {\n                .error(loc, \"tuple index %llu exceeds %llu\", cast(ulong)d, cast(ulong)tup.objects.dim);\n                return error();\n            }\n\n            RootObject o = (*tup.objects)[cast(size_t)d];\n            if (o.dyncast() != DYNCAST.type)\n            {\n                .error(loc, \"`%s` is not a type\", mtype.toChars());\n                return error();\n            }\n            result = (cast(Type)o).addMod(mtype.mod);\n            return;\n        }\n\n        Type tn = mtype.next.typeSemantic(loc, sc);\n        if (tn.ty == Terror)\n            return error();\n\n        Type tbn = tn.toBasetype();\n        if (mtype.dim)\n        {\n            auto errors = global.errors;\n            mtype.dim = semanticLength(sc, tbn, mtype.dim);\n            if (errors != global.errors)\n                return error();\n\n            mtype.dim = mtype.dim.optimize(WANTvalue);\n            mtype.dim = mtype.dim.ctfeInterpret();\n            if (mtype.dim.op == TOK.error)\n                return error();\n\n            errors = global.errors;\n            dinteger_t d1 = mtype.dim.toInteger();\n            if (errors != global.errors)\n                return error();\n\n            mtype.dim = mtype.dim.implicitCastTo(sc, Type.tsize_t);\n            mtype.dim = mtype.dim.optimize(WANTvalue);\n            if (mtype.dim.op == TOK.error)\n                return error();\n\n            errors = global.errors;\n            dinteger_t d2 = mtype.dim.toInteger();\n            if (errors != global.errors)\n                return error();\n\n            if (mtype.dim.op == TOK.error)\n                return error();\n\n            void overflowError()\n            {\n                .error(loc, \"`%s` size %llu * %llu exceeds 0x%llx size limit for static array\",\n                        mtype.toChars(), cast(ulong)tbn.size(loc), cast(ulong)d1, Target.maxStaticDataSize);\n                return error();\n            }\n\n            if (d1 != d2)\n                return overflowError();\n\n            Type tbx = tbn.baseElemOf();\n            if (tbx.ty == Tstruct && !(cast(TypeStruct)tbx).sym.members || tbx.ty == Tenum && !(cast(TypeEnum)tbx).sym.members)\n            {\n                /* To avoid meaningless error message, skip the total size limit check\n                 * when the bottom of element type is opaque.\n                 */\n            }\n            else if (tbn.isintegral() || tbn.isfloating() || tbn.ty == Tpointer || tbn.ty == Tarray || tbn.ty == Tsarray || tbn.ty == Taarray || (tbn.ty == Tstruct && ((cast(TypeStruct)tbn).sym.sizeok == Sizeok.done)) || tbn.ty == Tclass)\n            {\n                /* Only do this for types that don't need to have semantic()\n                 * run on them for the size, since they may be forward referenced.\n                 */\n                bool overflow = false;\n                if (mulu(tbn.size(loc), d2, overflow) >= Target.maxStaticDataSize || overflow)\n                    return overflowError();\n            }\n        }\n        switch (tbn.ty)\n        {\n        case Ttuple:\n            {\n                // Index the tuple to get the type\n                assert(mtype.dim);\n                TypeTuple tt = cast(TypeTuple)tbn;\n                uinteger_t d = mtype.dim.toUInteger();\n                if (d >= tt.arguments.dim)\n                {\n                    .error(loc, \"tuple index %llu exceeds %llu\", cast(ulong)d, cast(ulong)tt.arguments.dim);\n                    return error();\n                }\n                Type telem = (*tt.arguments)[cast(size_t)d].type;\n                result = telem.addMod(mtype.mod);\n                return;\n            }\n\n        case Tfunction:\n        case Tnone:\n            .error(loc, \"cannot have array of `%s`\", tbn.toChars());\n            return error();\n\n        default:\n            break;\n        }\n        if (tbn.isscope())\n        {\n            .error(loc, \"cannot have array of scope `%s`\", tbn.toChars());\n            return error();\n        }\n\n        /* Ensure things like const(immutable(T)[3]) become immutable(T[3])\n         * and const(T)[3] become const(T[3])\n         */\n        mtype.next = tn;\n        mtype.transitive();\n        result = mtype.addMod(tn.mod).merge();\n    }\n\n    override void visit(TypeDArray mtype)\n    {\n        Type tn = mtype.next.typeSemantic(loc, sc);\n        Type tbn = tn.toBasetype();\n        switch (tbn.ty)\n        {\n        case Ttuple:\n            result = tbn;\n            return;\n\n        case Tfunction:\n        case Tnone:\n            .error(loc, \"cannot have array of `%s`\", tbn.toChars());\n            return error();\n\n        case Terror:\n            return error();\n\n        default:\n            break;\n        }\n        if (tn.isscope())\n        {\n            .error(loc, \"cannot have array of scope `%s`\", tn.toChars());\n            return error();\n        }\n        mtype.next = tn;\n        mtype.transitive();\n        result = merge(mtype);\n    }\n\n    override void visit(TypeAArray mtype)\n    {\n        //printf(\"TypeAArray::semantic() %s index.ty = %d\\n\", mtype.toChars(), mtype.index.ty);\n        if (mtype.deco)\n        {\n            result = mtype;\n            return;\n        }\n\n        mtype.loc = loc;\n        mtype.sc = sc;\n        if (sc)\n            sc.setNoFree();\n\n        // Deal with the case where we thought the index was a type, but\n        // in reality it was an expression.\n        if (mtype.index.ty == Tident || mtype.index.ty == Tinstance || mtype.index.ty == Tsarray || mtype.index.ty == Ttypeof || mtype.index.ty == Treturn)\n        {\n            Expression e;\n            Type t;\n            Dsymbol s;\n            mtype.index.resolve(loc, sc, &e, &t, &s);\n            if (e)\n            {\n                // It was an expression -\n                // Rewrite as a static array\n                auto tsa = new TypeSArray(mtype.next, e);\n                result = tsa.typeSemantic(loc, sc);\n                return;\n            }\n            else if (t)\n                mtype.index = t.typeSemantic(loc, sc);\n            else\n            {\n                .error(loc, \"index is not a type or an expression\");\n                return error();\n            }\n        }\n        else\n            mtype.index = mtype.index.typeSemantic(loc, sc);\n        mtype.index = mtype.index.merge2();\n\n        if (mtype.index.nextOf() && !mtype.index.nextOf().isImmutable())\n        {\n            mtype.index = mtype.index.constOf().mutableOf();\n            version (none)\n            {\n                printf(\"index is %p %s\\n\", mtype.index, mtype.index.toChars());\n                mtype.index.check();\n                printf(\"index.mod = x%x\\n\", mtype.index.mod);\n                printf(\"index.ito = x%x\\n\", mtype.index.ito);\n                if (mtype.index.ito)\n                {\n                    printf(\"index.ito.mod = x%x\\n\", mtype.index.ito.mod);\n                    printf(\"index.ito.ito = x%x\\n\", mtype.index.ito.ito);\n                }\n            }\n        }\n\n        switch (mtype.index.toBasetype().ty)\n        {\n        case Tfunction:\n        case Tvoid:\n        case Tnone:\n        case Ttuple:\n            .error(loc, \"cannot have associative array key of `%s`\", mtype.index.toBasetype().toChars());\n            goto case Terror;\n        case Terror:\n            return error();\n\n        default:\n            break;\n        }\n        Type tbase = mtype.index.baseElemOf();\n        while (tbase.ty == Tarray)\n            tbase = tbase.nextOf().baseElemOf();\n        if (tbase.ty == Tstruct)\n        {\n            /* AA's need typeid(index).equals() and getHash(). Issue error if not correctly set up.\n             */\n            StructDeclaration sd = (cast(TypeStruct)tbase).sym;\n            if (sd.semanticRun < PASS.semanticdone)\n                sd.dsymbolSemantic(null);\n\n            // duplicate a part of StructDeclaration::semanticTypeInfoMembers\n            //printf(\"AA = %s, key: xeq = %p, xerreq = %p xhash = %p\\n\", toChars(), sd.xeq, sd.xerreq, sd.xhash);\n            if (sd.xeq && sd.xeq._scope && sd.xeq.semanticRun < PASS.semantic3done)\n            {\n                uint errors = global.startGagging();\n                sd.xeq.semantic3(sd.xeq._scope);\n                if (global.endGagging(errors))\n                    sd.xeq = sd.xerreq;\n            }\n\n            //printf(\"AA = %s, key: xeq = %p, xhash = %p\\n\", toChars(), sd.xeq, sd.xhash);\n            const(char)* s = (mtype.index.toBasetype().ty != Tstruct) ? \"bottom of \" : \"\";\n            if (!sd.xeq)\n            {\n                // If sd.xhash != NULL:\n                //   sd or its fields have user-defined toHash.\n                //   AA assumes that its result is consistent with bitwise equality.\n                // else:\n                //   bitwise equality & hashing\n            }\n            else if (sd.xeq == sd.xerreq)\n            {\n                if (search_function(sd, Id.eq))\n                {\n                    .error(loc, \"%sAA key type `%s` does not have `bool opEquals(ref const %s) const`\", s, sd.toChars(), sd.toChars());\n                }\n                else\n                {\n                    .error(loc, \"%sAA key type `%s` does not support const equality\", s, sd.toChars());\n                }\n                return error();\n            }\n            else if (!sd.xhash)\n            {\n                if (search_function(sd, Id.eq))\n                {\n                    .error(loc, \"%sAA key type `%s` should have `size_t toHash() const nothrow @safe` if `opEquals` defined\", s, sd.toChars());\n                }\n                else\n                {\n                    .error(loc, \"%sAA key type `%s` supports const equality but doesn't support const hashing\", s, sd.toChars());\n                }\n                return error();\n            }\n            else\n            {\n                // defined equality & hashing\n                assert(sd.xeq && sd.xhash);\n\n                /* xeq and xhash may be implicitly defined by compiler. For example:\n                 *   struct S { int[] arr; }\n                 * With 'arr' field equality and hashing, compiler will implicitly\n                 * generate functions for xopEquals and xtoHash in TypeInfo_Struct.\n                 */\n            }\n        }\n        else if (tbase.ty == Tclass && !(cast(TypeClass)tbase).sym.isInterfaceDeclaration())\n        {\n            ClassDeclaration cd = (cast(TypeClass)tbase).sym;\n            if (cd.semanticRun < PASS.semanticdone)\n                cd.dsymbolSemantic(null);\n\n            if (!ClassDeclaration.object)\n            {\n                .error(Loc.initial, \"missing or corrupt object.d\");\n                fatal();\n            }\n\n            __gshared FuncDeclaration feq = null;\n            __gshared FuncDeclaration fcmp = null;\n            __gshared FuncDeclaration fhash = null;\n            if (!feq)\n                feq = search_function(ClassDeclaration.object, Id.eq).isFuncDeclaration();\n            if (!fcmp)\n                fcmp = search_function(ClassDeclaration.object, Id.cmp).isFuncDeclaration();\n            if (!fhash)\n                fhash = search_function(ClassDeclaration.object, Id.tohash).isFuncDeclaration();\n            assert(fcmp && feq && fhash);\n\n            if (feq.vtblIndex < cd.vtbl.dim && cd.vtbl[feq.vtblIndex] == feq)\n            {\n                version (all)\n                {\n                    if (fcmp.vtblIndex < cd.vtbl.dim && cd.vtbl[fcmp.vtblIndex] != fcmp)\n                    {\n                        const(char)* s = (mtype.index.toBasetype().ty != Tclass) ? \"bottom of \" : \"\";\n                        .error(loc, \"%sAA key type `%s` now requires equality rather than comparison\", s, cd.toChars());\n                        errorSupplemental(loc, \"Please override `Object.opEquals` and `Object.toHash`.\");\n                    }\n                }\n            }\n        }\n        mtype.next = mtype.next.typeSemantic(loc, sc).merge2();\n        mtype.transitive();\n\n        switch (mtype.next.toBasetype().ty)\n        {\n        case Tfunction:\n        case Tvoid:\n        case Tnone:\n        case Ttuple:\n            .error(loc, \"cannot have associative array of `%s`\", mtype.next.toChars());\n            goto case Terror;\n        case Terror:\n            return error();\n        default:\n            break;\n        }\n        if (mtype.next.isscope())\n        {\n            .error(loc, \"cannot have array of scope `%s`\", mtype.next.toChars());\n            return error();\n        }\n        result = merge(mtype);\n    }\n\n    override void visit(TypePointer mtype)\n    {\n        //printf(\"TypePointer::semantic() %s\\n\", toChars());\n        if (mtype.deco)\n        {\n            result = mtype;\n            return;\n        }\n        Type n = mtype.next.typeSemantic(loc, sc);\n        switch (n.toBasetype().ty)\n        {\n        case Ttuple:\n            .error(loc, \"cannot have pointer to `%s`\", n.toChars());\n            goto case Terror;\n        case Terror:\n            return error();\n        default:\n            break;\n        }\n        if (n != mtype.next)\n        {\n            mtype.deco = null;\n        }\n        mtype.next = n;\n        if (mtype.next.ty != Tfunction)\n        {\n            mtype.transitive();\n            result = merge(mtype);\n            return;\n        }\n        version (none)\n        {\n            result = merge(mtype);\n            return;\n        }\n        else\n        {\n            mtype.deco = merge(mtype).deco;\n            /* Don't return merge(), because arg identifiers and default args\n             * can be different\n             * even though the types match\n             */\n            result = mtype;\n            return;\n        }\n    }\n\n    override void visit(TypeReference mtype)\n    {\n        //printf(\"TypeReference::semantic()\\n\");\n        Type n = mtype.next.typeSemantic(loc, sc);\n        if (n != mtype.next)\n           mtype.deco = null;\n        mtype.next = n;\n        mtype.transitive();\n        result = merge(mtype);\n    }\n\n    override void visit(TypeFunction mtype)\n    {\n        if (mtype.deco) // if semantic() already run\n        {\n            //printf(\"already done\\n\");\n            result = mtype;\n            return;\n        }\n        //printf(\"TypeFunction::semantic() this = %p\\n\", this);\n        //printf(\"TypeFunction::semantic() %s, sc.stc = %llx, fargs = %p\\n\", toChars(), sc.stc, fargs);\n\n        bool errors = false;\n\n        if (mtype.inuse > 500)\n        {\n            mtype.inuse = 0;\n            .error(loc, \"recursive type\");\n            return error();\n        }\n\n        /* Copy in order to not mess up original.\n         * This can produce redundant copies if inferring return type,\n         * as semantic() will get called again on this.\n         */\n        TypeFunction tf = mtype.copy().toTypeFunction();\n        if (mtype.parameters)\n        {\n            tf.parameters = mtype.parameters.copy();\n            for (size_t i = 0; i < mtype.parameters.dim; i++)\n            {\n                Parameter p = cast(Parameter)mem.xmalloc(__traits(classInstanceSize, Parameter));\n                memcpy(cast(void*)p, cast(void*)(*mtype.parameters)[i], __traits(classInstanceSize, Parameter));\n                (*tf.parameters)[i] = p;\n            }\n        }\n\n        if (sc.stc & STC.pure_)\n            tf.purity = PURE.fwdref;\n        if (sc.stc & STC.nothrow_)\n            tf.isnothrow = true;\n        if (sc.stc & STC.nogc)\n            tf.isnogc = true;\n        if (sc.stc & STC.ref_)\n            tf.isref = true;\n        if (sc.stc & STC.return_)\n            tf.isreturn = true;\n        if (sc.stc & STC.scope_)\n            tf.isscope = true;\n        if (sc.stc & STC.scopeinferred)\n            tf.isscopeinferred = true;\n\n//        if (tf.isreturn && !tf.isref)\n//            tf.isscope = true;                                  // return by itself means 'return scope'\n\n        if (tf.trust == TRUST.default_)\n        {\n            if (sc.stc & STC.safe)\n                tf.trust = TRUST.safe;\n            else if (sc.stc & STC.system)\n                tf.trust = TRUST.system;\n            else if (sc.stc & STC.trusted)\n                tf.trust = TRUST.trusted;\n        }\n\n        if (sc.stc & STC.property)\n            tf.isproperty = true;\n\n        tf.linkage = sc.linkage;\n        version (none)\n        {\n            /* If the parent is @safe, then this function defaults to safe\n             * too.\n             * If the parent's @safe-ty is inferred, then this function's @safe-ty needs\n             * to be inferred first.\n             */\n            if (tf.trust == TRUST.default_)\n                for (Dsymbol p = sc.func; p; p = p.toParent2())\n                {\n                    FuncDeclaration fd = p.isFuncDeclaration();\n                    if (fd)\n                    {\n                        if (fd.isSafeBypassingInference())\n                            tf.trust = TRUST.safe; // default to @safe\n                        break;\n                    }\n                }\n        }\n\n        bool wildreturn = false;\n        if (tf.next)\n        {\n            sc = sc.push();\n            sc.stc &= ~(STC.TYPECTOR | STC.FUNCATTR);\n            tf.next = tf.next.typeSemantic(loc, sc);\n            sc = sc.pop();\n            errors |= tf.checkRetType(loc);\n            if (tf.next.isscope() && !(sc.flags & SCOPE.ctor))\n            {\n                .error(loc, \"functions cannot return `scope %s`\", tf.next.toChars());\n                errors = true;\n            }\n            if (tf.next.hasWild())\n                wildreturn = true;\n\n            if (tf.isreturn && !tf.isref && !tf.next.hasPointers())\n            {\n                tf.isreturn = false;\n            }\n        }\n\n        ubyte wildparams = 0;\n        if (tf.parameters)\n        {\n            /* Create a scope for evaluating the default arguments for the parameters\n             */\n            Scope* argsc = sc.push();\n            argsc.stc = 0; // don't inherit storage class\n            argsc.protection = Prot(Prot.Kind.public_);\n            argsc.func = null;\n\n            size_t dim = Parameter.dim(tf.parameters);\n            for (size_t i = 0; i < dim; i++)\n            {\n                Parameter fparam = Parameter.getNth(tf.parameters, i);\n                mtype.inuse++;\n                fparam.type = fparam.type.typeSemantic(loc, argsc);\n                mtype.inuse--;\n                if (fparam.type.ty == Terror)\n                {\n                    errors = true;\n                    continue;\n                }\n\n                fparam.type = fparam.type.addStorageClass(fparam.storageClass);\n\n                if (fparam.storageClass & (STC.auto_ | STC.alias_ | STC.static_))\n                {\n                    if (!fparam.type)\n                        continue;\n                }\n\n                Type t = fparam.type.toBasetype();\n\n                if (t.ty == Tfunction)\n                {\n                    .error(loc, \"cannot have parameter of function type `%s`\", fparam.type.toChars());\n                    errors = true;\n                }\n                else if (!(fparam.storageClass & (STC.ref_ | STC.out_)) &&\n                         (t.ty == Tstruct || t.ty == Tsarray || t.ty == Tenum))\n                {\n                    Type tb2 = t.baseElemOf();\n                    if (tb2.ty == Tstruct && !(cast(TypeStruct)tb2).sym.members ||\n                        tb2.ty == Tenum && !(cast(TypeEnum)tb2).sym.memtype)\n                    {\n                        .error(loc, \"cannot have parameter of opaque type `%s` by value\", fparam.type.toChars());\n                        errors = true;\n                    }\n                }\n                else if (!(fparam.storageClass & STC.lazy_) && t.ty == Tvoid)\n                {\n                    .error(loc, \"cannot have parameter of type `%s`\", fparam.type.toChars());\n                    errors = true;\n                }\n\n                if ((fparam.storageClass & (STC.ref_ | STC.wild)) == (STC.ref_ | STC.wild))\n                {\n                    // 'ref inout' implies 'return'\n                    fparam.storageClass |= STC.return_;\n                }\n\n                if (fparam.storageClass & STC.return_)\n                {\n                    if (fparam.storageClass & (STC.ref_ | STC.out_))\n                    {\n                        // Disabled for the moment awaiting improvement to allow return by ref\n                        // to be transformed into return by scope.\n                        if (0 && !tf.isref)\n                        {\n                            auto stc = fparam.storageClass & (STC.ref_ | STC.out_);\n                            .error(loc, \"parameter `%s` is `return %s` but function does not return by `ref`\",\n                                fparam.ident ? fparam.ident.toChars() : \"\",\n                                stcToChars(stc));\n                            errors = true;\n                        }\n                    }\n                    else\n                    {\n                        fparam.storageClass |= STC.scope_;        // 'return' implies 'scope'\n                        if (tf.isref)\n                        {\n                        }\n                        else if (tf.next && !tf.next.hasPointers())\n                        {\n                            fparam.storageClass &= ~STC.return_;   // https://issues.dlang.org/show_bug.cgi?id=18963\n                        }\n                    }\n                }\n\n                if (fparam.storageClass & (STC.ref_ | STC.lazy_))\n                {\n                }\n                else if (fparam.storageClass & STC.out_)\n                {\n                    if (ubyte m = fparam.type.mod & (MODFlags.immutable_ | MODFlags.const_ | MODFlags.wild))\n                    {\n                        .error(loc, \"cannot have `%s out` parameter of type `%s`\", MODtoChars(m), t.toChars());\n                        errors = true;\n                    }\n                    else\n                    {\n                        Type tv = t;\n                        while (tv.ty == Tsarray)\n                            tv = tv.nextOf().toBasetype();\n                        if (tv.ty == Tstruct && (cast(TypeStruct)tv).sym.noDefaultCtor)\n                        {\n                            .error(loc, \"cannot have `out` parameter of type `%s` because the default construction is disabled\", fparam.type.toChars());\n                            errors = true;\n                        }\n                    }\n                }\n\n                if (fparam.storageClass & STC.scope_ && !fparam.type.hasPointers() && fparam.type.ty != Ttuple)\n                {\n                    fparam.storageClass &= ~STC.scope_;\n                    if (!(fparam.storageClass & STC.ref_))\n                        fparam.storageClass &= ~STC.return_;\n                }\n\n                if (t.hasWild())\n                {\n                    wildparams |= 1;\n                    //if (tf.next && !wildreturn)\n                    //    error(loc, \"inout on parameter means inout must be on return type as well (if from D1 code, replace with `ref`)\");\n                }\n\n                if (fparam.defaultArg)\n                {\n                    Expression e = fparam.defaultArg;\n                    if (fparam.storageClass & (STC.ref_ | STC.out_))\n                    {\n                        e = e.expressionSemantic(argsc);\n                        e = resolveProperties(argsc, e);\n                    }\n                    else\n                    {\n                        e = inferType(e, fparam.type);\n                        Initializer iz = new ExpInitializer(e.loc, e);\n                        iz = iz.initializerSemantic(argsc, fparam.type, INITnointerpret);\n                        e = iz.initializerToExpression();\n                    }\n                    if (e.op == TOK.function_) // https://issues.dlang.org/show_bug.cgi?id=4820\n                    {\n                        FuncExp fe = cast(FuncExp)e;\n                        // Replace function literal with a function symbol,\n                        // since default arg expression must be copied when used\n                        // and copying the literal itself is wrong.\n                        e = new VarExp(e.loc, fe.fd, false);\n                        e = new AddrExp(e.loc, e);\n                        e = e.expressionSemantic(argsc);\n                    }\n                    e = e.implicitCastTo(argsc, fparam.type);\n\n                    // default arg must be an lvalue\n                    if (fparam.storageClass & (STC.out_ | STC.ref_))\n                        e = e.toLvalue(argsc, e);\n\n                    fparam.defaultArg = e;\n                    if (e.op == TOK.error)\n                        errors = true;\n                }\n\n                /* If fparam after semantic() turns out to be a tuple, the number of parameters may\n                 * change.\n                 */\n                if (t.ty == Ttuple)\n                {\n                    /* TypeFunction::parameter also is used as the storage of\n                     * Parameter objects for FuncDeclaration. So we should copy\n                     * the elements of TypeTuple::arguments to avoid unintended\n                     * sharing of Parameter object among other functions.\n                     */\n                    TypeTuple tt = cast(TypeTuple)t;\n                    if (tt.arguments && tt.arguments.dim)\n                    {\n                        /* Propagate additional storage class from tuple parameters to their\n                         * element-parameters.\n                         * Make a copy, as original may be referenced elsewhere.\n                         */\n                        size_t tdim = tt.arguments.dim;\n                        auto newparams = new Parameters(tdim);\n                        for (size_t j = 0; j < tdim; j++)\n                        {\n                            Parameter narg = (*tt.arguments)[j];\n\n                            // https://issues.dlang.org/show_bug.cgi?id=12744\n                            // If the storage classes of narg\n                            // conflict with the ones in fparam, it's ignored.\n                            StorageClass stc  = fparam.storageClass | narg.storageClass;\n                            StorageClass stc1 = fparam.storageClass & (STC.ref_ | STC.out_ | STC.lazy_);\n                            StorageClass stc2 =   narg.storageClass & (STC.ref_ | STC.out_ | STC.lazy_);\n                            if (stc1 && stc2 && stc1 != stc2)\n                            {\n                                OutBuffer buf1;  stcToBuffer(&buf1, stc1 | ((stc1 & STC.ref_) ? (fparam.storageClass & STC.auto_) : 0));\n                                OutBuffer buf2;  stcToBuffer(&buf2, stc2);\n\n                                .error(loc, \"incompatible parameter storage classes `%s` and `%s`\",\n                                    buf1.peekString(), buf2.peekString());\n                                errors = true;\n                                stc = stc1 | (stc & ~(STC.ref_ | STC.out_ | STC.lazy_));\n                            }\n\n                            (*newparams)[j] = new Parameter(\n                                stc, narg.type, narg.ident, narg.defaultArg, narg.userAttribDecl);\n                        }\n                        fparam.type = new TypeTuple(newparams);\n                    }\n                    fparam.storageClass = 0;\n\n                    /* Reset number of parameters, and back up one to do this fparam again,\n                     * now that it is a tuple\n                     */\n                    dim = Parameter.dim(tf.parameters);\n                    i--;\n                    continue;\n                }\n\n                /* Resolve \"auto ref\" storage class to be either ref or value,\n                 * based on the argument matching the parameter\n                 */\n                if (fparam.storageClass & STC.auto_)\n                {\n                    if (mtype.fargs && i < mtype.fargs.dim && (fparam.storageClass & STC.ref_))\n                    {\n                        Expression farg = (*mtype.fargs)[i];\n                        if (farg.isLvalue())\n                        {\n                            // ref parameter\n                        }\n                        else\n                            fparam.storageClass &= ~STC.ref_; // value parameter\n                        fparam.storageClass &= ~STC.auto_;    // https://issues.dlang.org/show_bug.cgi?id=14656\n                        fparam.storageClass |= STC.autoref;\n                    }\n                    else\n                    {\n                        .error(loc, \"`auto` can only be used as part of `auto ref` for template function parameters\");\n                        errors = true;\n                    }\n                }\n\n                // Remove redundant storage classes for type, they are already applied\n                fparam.storageClass &= ~(STC.TYPECTOR | STC.in_);\n            }\n            argsc.pop();\n        }\n        if (tf.isWild())\n            wildparams |= 2;\n\n        if (wildreturn && !wildparams)\n        {\n            .error(loc, \"`inout` on `return` means `inout` must be on a parameter as well for `%s`\", mtype.toChars());\n            errors = true;\n        }\n        tf.iswild = wildparams;\n\n        if (tf.isproperty && (tf.varargs || Parameter.dim(tf.parameters) > 2))\n        {\n            .error(loc, \"properties can only have zero, one, or two parameter\");\n            errors = true;\n        }\n\n        if (tf.varargs == 1 && tf.linkage != LINK.d && Parameter.dim(tf.parameters) == 0)\n        {\n            .error(loc, \"variadic functions with non-D linkage must have at least one parameter\");\n            errors = true;\n        }\n\n        if (errors)\n            return error();\n\n        if (tf.next)\n            tf.deco = tf.merge().deco;\n\n        /* Don't return merge(), because arg identifiers and default args\n         * can be different\n         * even though the types match\n         */\n        result = tf;\n    }\n\n    override void visit(TypeDelegate mtype)\n    {\n        //printf(\"TypeDelegate::semantic() %s\\n\", toChars());\n        if (mtype.deco) // if semantic() already run\n        {\n            //printf(\"already done\\n\");\n            result = mtype;\n            return;\n        }\n        mtype.next = mtype.next.typeSemantic(loc, sc);\n        if (mtype.next.ty != Tfunction)\n            return error();\n\n        /* In order to deal with https://issues.dlang.org/show_bug.cgi?id=4028\n         * perhaps default arguments should\n         * be removed from next before the merge.\n         */\n        version (none)\n        {\n            result = mtype.merge();\n            return;\n        }\n        else\n        {\n            /* Don't return merge(), because arg identifiers and default args\n             * can be different\n             * even though the types match\n             */\n            mtype.deco = mtype.merge().deco;\n            result = mtype;\n        }\n    }\n\n    override void visit(TypeIdentifier mtype)\n    {\n        Type t;\n        Expression e;\n        Dsymbol s;\n        //printf(\"TypeIdentifier::semantic(%s)\\n\", toChars());\n        mtype.resolve(loc, sc, &e, &t, &s);\n        if (t)\n        {\n            //printf(\"\\tit's a type %d, %s, %s\\n\", t.ty, t.toChars(), t.deco);\n            result = t.addMod(mtype.mod);\n        }\n        else\n        {\n            if (s)\n            {\n                auto td = s.isTemplateDeclaration;\n                if (td && td.onemember && td.onemember.isAggregateDeclaration)\n                    .error(loc, \"template %s `%s` is used as a type without instantiation\"\n                        ~ \"; to instantiate it use `%s!(arguments)`\",\n                        s.kind, s.toPrettyChars, s.ident.toChars);\n                else\n                    .error(loc, \"%s `%s` is used as a type\", s.kind, s.toPrettyChars);\n                //assert(0);\n            }\n            else\n                .error(loc, \"`%s` is used as a type\", mtype.toChars());\n            return error();\n        }\n    }\n\n    override void visit(TypeInstance mtype)\n    {\n        Type t;\n        Expression e;\n        Dsymbol s;\n\n        //printf(\"TypeInstance::semantic(%p, %s)\\n\", this, toChars());\n        {\n            const errors = global.errors;\n            mtype.resolve(loc, sc, &e, &t, &s);\n            // if we had an error evaluating the symbol, suppress further errors\n            if (!t && errors != global.errors)\n            {\n                result = Type.terror;\n                return;\n            }\n        }\n\n        if (!t)\n        {\n            if (!e && s && s.errors)\n            {\n                // if there was an error evaluating the symbol, it might actually\n                // be a type. Avoid misleading error messages.\n               .error(loc, \"`%s` had previous errors\", mtype.toChars());\n            }\n            else\n               .error(loc, \"`%s` is used as a type\", mtype.toChars());\n            return error();\n        }\n        result = t;\n    }\n\n    override void visit(TypeTypeof mtype)\n    {\n        //printf(\"TypeTypeof::semantic() %s\\n\", toChars());\n        Expression e;\n        Type t;\n        Dsymbol s;\n        mtype.resolve(loc, sc, &e, &t, &s);\n        if (s && (t = s.getType()) !is null)\n            t = t.addMod(mtype.mod);\n        if (!t)\n        {\n            .error(loc, \"`%s` is used as a type\", mtype.toChars());\n            return error();\n        }\n        result = t;\n    }\n\n    override void visit(TypeReturn mtype)\n    {\n        //printf(\"TypeReturn::semantic() %s\\n\", toChars());\n        Expression e;\n        Type t;\n        Dsymbol s;\n        mtype.resolve(loc, sc, &e, &t, &s);\n        if (s && (t = s.getType()) !is null)\n            t = t.addMod(mtype.mod);\n        if (!t)\n        {\n            .error(loc, \"`%s` is used as a type\", mtype.toChars());\n            return error();\n        }\n        result = t;\n    }\n\n    override void visit(TypeStruct mtype)\n    {\n        //printf(\"TypeStruct::semantic('%s')\\n\", mtype.toChars());\n        if (mtype.deco)\n        {\n            if (sc && sc.cppmangle != CPPMANGLE.def)\n            {\n                if (mtype.cppmangle == CPPMANGLE.def)\n                    mtype.cppmangle = sc.cppmangle;\n            }\n            result = mtype;\n            return;\n        }\n\n        /* Don't semantic for sym because it should be deferred until\n         * sizeof needed or its members accessed.\n         */\n        // instead, parent should be set correctly\n        assert(mtype.sym.parent);\n\n        if (mtype.sym.type.ty == Terror)\n            return error();\n\n        if (sc && sc.cppmangle != CPPMANGLE.def)\n            mtype.cppmangle = sc.cppmangle;\n        else\n            mtype.cppmangle = CPPMANGLE.asStruct;\n\n        result = merge(mtype);\n    }\n\n    override void visit(TypeEnum mtype)\n    {\n        //printf(\"TypeEnum::semantic() %s\\n\", toChars());\n        result = mtype.deco ? mtype : merge(mtype);\n    }\n\n    override void visit(TypeClass mtype)\n    {\n        //printf(\"TypeClass::semantic(%s)\\n\", mtype.toChars());\n        if (mtype.deco)\n        {\n            if (sc && sc.cppmangle != CPPMANGLE.def)\n            {\n                if (mtype.cppmangle == CPPMANGLE.def)\n                    mtype.cppmangle = sc.cppmangle;\n            }\n            result = mtype;\n            return;\n        }\n\n        /* Don't semantic for sym because it should be deferred until\n         * sizeof needed or its members accessed.\n         */\n        // instead, parent should be set correctly\n        assert(mtype.sym.parent);\n\n        if (mtype.sym.type.ty == Terror)\n            return error();\n\n        if (sc && sc.cppmangle != CPPMANGLE.def)\n            mtype.cppmangle = sc.cppmangle;\n        else\n            mtype.cppmangle = CPPMANGLE.asClass;\n\n        result = merge(mtype);\n    }\n\n    override void visit(TypeTuple mtype)\n    {\n        //printf(\"TypeTuple::semantic(this = %p)\\n\", this);\n        //printf(\"TypeTuple::semantic() %p, %s\\n\", this, toChars());\n        if (!mtype.deco)\n            mtype.deco = merge(mtype).deco;\n\n        /* Don't return merge(), because a tuple with one type has the\n         * same deco as that type.\n         */\n        result = mtype;\n    }\n\n    override void visit(TypeSlice mtype)\n    {\n        //printf(\"TypeSlice::semantic() %s\\n\", toChars());\n        Type tn = mtype.next.typeSemantic(loc, sc);\n        //printf(\"next: %s\\n\", tn.toChars());\n\n        Type tbn = tn.toBasetype();\n        if (tbn.ty != Ttuple)\n        {\n            .error(loc, \"can only slice tuple types, not `%s`\", tbn.toChars());\n            return error();\n        }\n        TypeTuple tt = cast(TypeTuple)tbn;\n\n        mtype.lwr = semanticLength(sc, tbn, mtype.lwr);\n        mtype.upr = semanticLength(sc, tbn, mtype.upr);\n        mtype.lwr = mtype.lwr.ctfeInterpret();\n        mtype.upr = mtype.upr.ctfeInterpret();\n        if (mtype.lwr.op == TOK.error || mtype.upr.op == TOK.error)\n            return error();\n\n        uinteger_t i1 = mtype.lwr.toUInteger();\n        uinteger_t i2 = mtype.upr.toUInteger();\n        if (!(i1 <= i2 && i2 <= tt.arguments.dim))\n        {\n            .error(loc, \"slice `[%llu..%llu]` is out of range of `[0..%llu]`\",\n                cast(ulong)i1, cast(ulong)i2, cast(ulong)tt.arguments.dim);\n            return error();\n        }\n\n        mtype.next = tn;\n        mtype.transitive();\n\n        auto args = new Parameters();\n        args.reserve(cast(size_t)(i2 - i1));\n        foreach (arg; (*tt.arguments)[cast(size_t)i1 .. cast(size_t)i2])\n        {\n            args.push(arg);\n        }\n        Type t = new TypeTuple(args);\n        result = t.typeSemantic(loc, sc);\n    }\n\n}\n\n/************************************\n * If an identical type to `type` is in `type.stringtable`, return\n * the latter one. Otherwise, add it to `type.stringtable`.\n * Some types don't get merged and are returned as-is.\n * Params:\n *      type = Type to check against existing types\n * Returns:\n *      the type that was merged\n */\nType merge(Type type)\n{\n    switch (type.ty)\n    {\n        case Terror:\n        case Ttypeof:\n        case Tident:\n        case Tinstance:\n            return type;\n\n        case Tenum:\n            break;\n\n        case Taarray:\n            if (!(cast(TypeAArray)type).index.merge().deco)\n                return type;\n            goto default;\n\n        default:\n            if (type.nextOf() && !type.nextOf().deco)\n                return type;\n            break;\n    }\n\n    //printf(\"merge(%s)\\n\", toChars());\n    if (!type.deco)\n    {\n        OutBuffer buf;\n        buf.reserve(32);\n\n        mangleToBuffer(type, &buf);\n\n        StringValue* sv = type.stringtable.update(cast(char*)buf.data, buf.offset);\n        if (sv.ptrvalue)\n        {\n            Type t = cast(Type)sv.ptrvalue;\n            debug\n            {\n                import core.stdc.stdio;\n                if (!t.deco)\n                    printf(\"t = %s\\n\", t.toChars());\n            }\n            assert(t.deco);\n            //printf(\"old value, deco = '%s' %p\\n\", t.deco, t.deco);\n            return t;\n        }\n        else\n        {\n            Type t = stripDefaultArgs(type);\n            sv.ptrvalue = cast(char*)t;\n            type.deco = t.deco = cast(char*)sv.toDchars();\n            //printf(\"new value, deco = '%s' %p\\n\", t.deco, t.deco);\n            return t;\n        }\n    }\n    return type;\n}\n\n/***************************************\n * Calculate built-in properties which just the type is necessary.\n *\n * Params:\n *  t = the type for which the property is calculated\n *  loc = the location where the property is encountered\n *  ident = the identifier of the property\n *  flag = if flag & 1, don't report \"not a property\" error and just return NULL.\n */\nExpression getProperty(Type t, const ref Loc loc, Identifier ident, int flag)\n{\n    scope v = new GetPropertyVisitor(loc, ident, flag);\n    t.accept(v);\n    return  v.result;\n}\n\nprivate extern (C++) final class GetPropertyVisitor : Visitor\n{\n    alias visit = typeof(super).visit;\n    Loc loc;\n    Identifier ident;\n    int flag;\n    Expression result;\n\n    this(const ref Loc loc, Identifier ident, int flag)\n    {\n        this.loc = loc;\n        this.ident = ident;\n        this.flag = flag;\n    }\n\n    override void visit(Type mt)\n    {\n        Expression e;\n        static if (LOGDOTEXP)\n        {\n            printf(\"Type::getProperty(type = '%s', ident = '%s')\\n\", mt.toChars(), ident.toChars());\n        }\n        if (ident == Id.__sizeof)\n        {\n            d_uns64 sz = mt.size(loc);\n            if (sz == SIZE_INVALID)\n            {\n                result = new ErrorExp();\n                return;\n            }\n            e = new IntegerExp(loc, sz, Type.tsize_t);\n        }\n        else if (ident == Id.__xalignof)\n        {\n            const explicitAlignment = mt.alignment();\n            const naturalAlignment = mt.alignsize();\n            const actualAlignment = (explicitAlignment == STRUCTALIGN_DEFAULT ? naturalAlignment : explicitAlignment);\n            e = new IntegerExp(loc, actualAlignment, Type.tsize_t);\n        }\n        else if (ident == Id._init)\n        {\n            Type tb = mt.toBasetype();\n            e = mt.defaultInitLiteral(loc);\n            if (tb.ty == Tstruct && tb.needsNested())\n            {\n                StructLiteralExp se = cast(StructLiteralExp)e;\n                se.useStaticInit = true;\n            }\n        }\n        else if (ident == Id._mangleof)\n        {\n            if (!mt.deco)\n            {\n                error(loc, \"forward reference of type `%s.mangleof`\", mt.toChars());\n                e = new ErrorExp();\n            }\n            else\n            {\n                e = new StringExp(loc, mt.deco);\n                Scope sc;\n                e = e.expressionSemantic(&sc);\n            }\n        }\n        else if (ident == Id.stringof)\n        {\n            const s = mt.toChars();\n            e = new StringExp(loc, cast(char*)s);\n            Scope sc;\n            e = e.expressionSemantic(&sc);\n        }\n        else if (flag && mt != Type.terror)\n        {\n            result = null;\n            return;\n        }\n        else\n        {\n            Dsymbol s = null;\n            if (mt.ty == Tstruct || mt.ty == Tclass || mt.ty == Tenum)\n                s = mt.toDsymbol(null);\n            if (s)\n                s = s.search_correct(ident);\n            if (mt != Type.terror)\n            {\n                if (s)\n                    error(loc, \"no property `%s` for type `%s`, did you mean `%s`?\", ident.toChars(), mt.toChars(), s.toPrettyChars());\n                else\n                {\n                    if (ident == Id.call && mt.ty == Tclass)\n                        error(loc, \"no property `%s` for type `%s`, did you mean `new %s`?\", ident.toChars(), mt.toChars(), mt.toPrettyChars());\n                    else\n                        error(loc, \"no property `%s` for type `%s`\", ident.toChars(), mt.toChars());\n                }\n            }\n            e = new ErrorExp();\n        }\n        result = e;\n    }\n\n    override void visit(TypeError)\n    {\n        result = new ErrorExp();\n    }\n\n    override void visit(TypeBasic mt)\n    {\n        Expression e;\n        dinteger_t ivalue;\n        real_t fvalue;\n        //printf(\"TypeBasic::getProperty('%s')\\n\", ident.toChars());\n        if (ident == Id.max)\n        {\n            switch (mt.ty)\n            {\n            case Tint8:\n                ivalue = 0x7F;\n                goto Livalue;\n            case Tuns8:\n                ivalue = 0xFF;\n                goto Livalue;\n            case Tint16:\n                ivalue = 0x7FFFU;\n                goto Livalue;\n            case Tuns16:\n                ivalue = 0xFFFFU;\n                goto Livalue;\n            case Tint32:\n                ivalue = 0x7FFFFFFFU;\n                goto Livalue;\n            case Tuns32:\n                ivalue = 0xFFFFFFFFU;\n                goto Livalue;\n            case Tint64:\n                ivalue = 0x7FFFFFFFFFFFFFFFL;\n                goto Livalue;\n            case Tuns64:\n                ivalue = 0xFFFFFFFFFFFFFFFFUL;\n                goto Livalue;\n            case Tbool:\n                ivalue = 1;\n                goto Livalue;\n            case Tchar:\n                ivalue = 0xFF;\n                goto Livalue;\n            case Twchar:\n                ivalue = 0xFFFFU;\n                goto Livalue;\n            case Tdchar:\n                ivalue = 0x10FFFFU;\n                goto Livalue;\n            case Tcomplex32:\n            case Timaginary32:\n            case Tfloat32:\n                fvalue = Target.FloatProperties.max;\n                goto Lfvalue;\n            case Tcomplex64:\n            case Timaginary64:\n            case Tfloat64:\n                fvalue = Target.DoubleProperties.max;\n                goto Lfvalue;\n            case Tcomplex80:\n            case Timaginary80:\n            case Tfloat80:\n                fvalue = Target.RealProperties.max;\n                goto Lfvalue;\n            default:\n                break;\n            }\n        }\n        else if (ident == Id.min)\n        {\n            switch (mt.ty)\n            {\n            case Tint8:\n                ivalue = -128;\n                goto Livalue;\n            case Tuns8:\n                ivalue = 0;\n                goto Livalue;\n            case Tint16:\n                ivalue = -32768;\n                goto Livalue;\n            case Tuns16:\n                ivalue = 0;\n                goto Livalue;\n            case Tint32:\n                ivalue = -2147483647 - 1;\n                goto Livalue;\n            case Tuns32:\n                ivalue = 0;\n                goto Livalue;\n            case Tint64:\n                ivalue = (-9223372036854775807L - 1L);\n                goto Livalue;\n            case Tuns64:\n                ivalue = 0;\n                goto Livalue;\n            case Tbool:\n                ivalue = 0;\n                goto Livalue;\n            case Tchar:\n                ivalue = 0;\n                goto Livalue;\n            case Twchar:\n                ivalue = 0;\n                goto Livalue;\n            case Tdchar:\n                ivalue = 0;\n                goto Livalue;\n            default:\n                break;\n            }\n        }\n        else if (ident == Id.min_normal)\n        {\n        Lmin_normal:\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n            case Timaginary32:\n            case Tfloat32:\n                fvalue = Target.FloatProperties.min_normal;\n                goto Lfvalue;\n            case Tcomplex64:\n            case Timaginary64:\n            case Tfloat64:\n                fvalue = Target.DoubleProperties.min_normal;\n                goto Lfvalue;\n            case Tcomplex80:\n            case Timaginary80:\n            case Tfloat80:\n                fvalue = Target.RealProperties.min_normal;\n                goto Lfvalue;\n            default:\n                break;\n            }\n        }\n        else if (ident == Id.nan)\n        {\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n            case Tcomplex64:\n            case Tcomplex80:\n            case Timaginary32:\n            case Timaginary64:\n            case Timaginary80:\n            case Tfloat32:\n            case Tfloat64:\n            case Tfloat80:\n                fvalue = Target.RealProperties.nan;\n                goto Lfvalue;\n            default:\n                break;\n            }\n        }\n        else if (ident == Id.infinity)\n        {\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n            case Tcomplex64:\n            case Tcomplex80:\n            case Timaginary32:\n            case Timaginary64:\n            case Timaginary80:\n            case Tfloat32:\n            case Tfloat64:\n            case Tfloat80:\n                fvalue = Target.RealProperties.infinity;\n                goto Lfvalue;\n            default:\n                break;\n            }\n        }\n        else if (ident == Id.dig)\n        {\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n            case Timaginary32:\n            case Tfloat32:\n                ivalue = Target.FloatProperties.dig;\n                goto Lint;\n            case Tcomplex64:\n            case Timaginary64:\n            case Tfloat64:\n                ivalue = Target.DoubleProperties.dig;\n                goto Lint;\n            case Tcomplex80:\n            case Timaginary80:\n            case Tfloat80:\n                ivalue = Target.RealProperties.dig;\n                goto Lint;\n            default:\n                break;\n            }\n        }\n        else if (ident == Id.epsilon)\n        {\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n            case Timaginary32:\n            case Tfloat32:\n                fvalue = Target.FloatProperties.epsilon;\n                goto Lfvalue;\n            case Tcomplex64:\n            case Timaginary64:\n            case Tfloat64:\n                fvalue = Target.DoubleProperties.epsilon;\n                goto Lfvalue;\n            case Tcomplex80:\n            case Timaginary80:\n            case Tfloat80:\n                fvalue = Target.RealProperties.epsilon;\n                goto Lfvalue;\n            default:\n                break;\n            }\n        }\n        else if (ident == Id.mant_dig)\n        {\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n            case Timaginary32:\n            case Tfloat32:\n                ivalue = Target.FloatProperties.mant_dig;\n                goto Lint;\n            case Tcomplex64:\n            case Timaginary64:\n            case Tfloat64:\n                ivalue = Target.DoubleProperties.mant_dig;\n                goto Lint;\n            case Tcomplex80:\n            case Timaginary80:\n            case Tfloat80:\n                ivalue = Target.RealProperties.mant_dig;\n                goto Lint;\n            default:\n                break;\n            }\n        }\n        else if (ident == Id.max_10_exp)\n        {\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n            case Timaginary32:\n            case Tfloat32:\n                ivalue = Target.FloatProperties.max_10_exp;\n                goto Lint;\n            case Tcomplex64:\n            case Timaginary64:\n            case Tfloat64:\n                ivalue = Target.DoubleProperties.max_10_exp;\n                goto Lint;\n            case Tcomplex80:\n            case Timaginary80:\n            case Tfloat80:\n                ivalue = Target.RealProperties.max_10_exp;\n                goto Lint;\n            default:\n                break;\n            }\n        }\n        else if (ident == Id.max_exp)\n        {\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n            case Timaginary32:\n            case Tfloat32:\n                ivalue = Target.FloatProperties.max_exp;\n                goto Lint;\n            case Tcomplex64:\n            case Timaginary64:\n            case Tfloat64:\n                ivalue = Target.DoubleProperties.max_exp;\n                goto Lint;\n            case Tcomplex80:\n            case Timaginary80:\n            case Tfloat80:\n                ivalue = Target.RealProperties.max_exp;\n                goto Lint;\n            default:\n                break;\n            }\n        }\n        else if (ident == Id.min_10_exp)\n        {\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n            case Timaginary32:\n            case Tfloat32:\n                ivalue = Target.FloatProperties.min_10_exp;\n                goto Lint;\n            case Tcomplex64:\n            case Timaginary64:\n            case Tfloat64:\n                ivalue = Target.DoubleProperties.min_10_exp;\n                goto Lint;\n            case Tcomplex80:\n            case Timaginary80:\n            case Tfloat80:\n                ivalue = Target.RealProperties.min_10_exp;\n                goto Lint;\n            default:\n                break;\n            }\n        }\n        else if (ident == Id.min_exp)\n        {\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n            case Timaginary32:\n            case Tfloat32:\n                ivalue = Target.FloatProperties.min_exp;\n                goto Lint;\n            case Tcomplex64:\n            case Timaginary64:\n            case Tfloat64:\n                ivalue = Target.DoubleProperties.min_exp;\n                goto Lint;\n            case Tcomplex80:\n            case Timaginary80:\n            case Tfloat80:\n                ivalue = Target.RealProperties.min_exp;\n                goto Lint;\n            default:\n                break;\n            }\n        }\n        visit(cast(Type)mt);\n        return;\n\n    Livalue:\n        e = new IntegerExp(loc, ivalue, mt);\n        result = e;\n        return;\n\n    Lfvalue:\n        if (mt.isreal() || mt.isimaginary())\n            e = new RealExp(loc, fvalue, mt);\n        else\n        {\n            const cvalue = complex_t(fvalue, fvalue);\n            //for (int i = 0; i < 20; i++)\n            //    printf(\"%02x \", ((unsigned char *)&cvalue)[i]);\n            //printf(\"\\n\");\n            e = new ComplexExp(loc, cvalue, mt);\n        }\n        result = e;\n        return;\n\n    Lint:\n        e = new IntegerExp(loc, ivalue, Type.tint32);\n        result = e;\n    }\n\n    override void visit(TypeVector mt)\n    {\n        visit(cast(Type)mt);\n    }\n\n    override void visit(TypeEnum mt)\n    {\n        Expression e;\n        if (ident == Id.max || ident == Id.min)\n        {\n            result = mt.sym.getMaxMinValue(loc, ident);\n            return;\n        }\n        else if (ident == Id._init)\n        {\n            e = mt.defaultInitLiteral(loc);\n        }\n        else if (ident == Id.stringof)\n        {\n            const s = mt.toChars();\n            e = new StringExp(loc, cast(char*)s);\n            Scope sc;\n            e = e.expressionSemantic(&sc);\n        }\n        else if (ident == Id._mangleof)\n        {\n            visit(cast(Type)mt);\n            e = result;\n        }\n        else\n        {\n            e = mt.toBasetype().getProperty(loc, ident, flag);\n        }\n        result = e;\n    }\n\n    override void visit(TypeTuple mt)\n    {\n        Expression e;\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeTuple::getProperty(type = '%s', ident = '%s')\\n\", mt.toChars(), ident.toChars());\n        }\n        if (ident == Id.length)\n        {\n            e = new IntegerExp(loc, mt.arguments.dim, Type.tsize_t);\n        }\n        else if (ident == Id._init)\n        {\n            e = mt.defaultInitLiteral(loc);\n        }\n        else if (flag)\n        {\n            e = null;\n        }\n        else\n        {\n            error(loc, \"no property `%s` for tuple `%s`\", ident.toChars(), mt.toChars());\n            e = new ErrorExp();\n        }\n        result = e;\n    }\n}\n\n/************************************\n * Resolve type 'mt' to either type, symbol, or expression.\n * If errors happened, resolved to Type.terror.\n *\n * Params:\n *  mt = type to be resolved\n *  loc = the location where the type is encountered\n *  sc = the scope of the type\n *  pe = is set if t is an expression\n *  pt = is set if t is a type\n *  ps = is set if t is a symbol\n *  intypeid = true if in type id\n */\nvoid resolve(Type mt, const ref Loc loc, Scope* sc, Expression* pe, Type* pt, Dsymbol* ps, bool intypeid = false)\n{\n    scope v = new ResolveVisitor(loc, sc, pe, pt, ps, intypeid);\n    mt.accept(v);\n}\n\nprivate extern(C++) final class ResolveVisitor : Visitor\n{\n    alias visit = typeof(super).visit;\n    Loc loc;\n    Scope* sc;\n    Expression* pe;\n    Type* pt;\n    Dsymbol* ps;\n    bool intypeid;\n\n    this(const ref Loc loc, Scope* sc, Expression* pe, Type* pt, Dsymbol* ps, bool intypeid)\n    {\n        this.loc = loc;\n        this.sc = sc;\n        this.pe = pe;\n        this.pt = pt;\n        this.ps = ps;\n        this.intypeid = intypeid;\n    }\n\n    override void visit(Type mt)\n    {\n        //printf(\"Type::resolve() %s, %d\\n\", mt.toChars(), mt.ty);\n        Type t = typeSemantic(mt, loc, sc);\n        assert(t);\n        *pt = t;\n        *pe = null;\n        *ps = null;\n    }\n\n    override void visit(TypeSArray mt)\n    {\n        //printf(\"TypeSArray::resolve() %s\\n\", mt.toChars());\n        mt.next.resolve(loc, sc, pe, pt, ps, intypeid);\n        //printf(\"s = %p, e = %p, t = %p\\n\", *ps, *pe, *pt);\n        if (*pe)\n        {\n            // It's really an index expression\n            if (Dsymbol s = getDsymbol(*pe))\n                *pe = new DsymbolExp(loc, s);\n            *pe = new ArrayExp(loc, *pe, mt.dim);\n        }\n        else if (*ps)\n        {\n            Dsymbol s = *ps;\n            if (auto tup = s.isTupleDeclaration())\n            {\n                mt.dim = semanticLength(sc, tup, mt.dim);\n                mt.dim = mt.dim.ctfeInterpret();\n                if (mt.dim.op == TOK.error)\n                {\n                    *ps = null;\n                    *pt = Type.terror;\n                    return;\n                }\n                uinteger_t d = mt.dim.toUInteger();\n                if (d >= tup.objects.dim)\n                {\n                    error(loc, \"tuple index `%llu` exceeds length %u\", d, tup.objects.dim);\n                    *ps = null;\n                    *pt = Type.terror;\n                    return;\n                }\n\n                RootObject o = (*tup.objects)[cast(size_t)d];\n                if (o.dyncast() == DYNCAST.dsymbol)\n                {\n                    *ps = cast(Dsymbol)o;\n                    return;\n                }\n                if (o.dyncast() == DYNCAST.expression)\n                {\n                    Expression e = cast(Expression)o;\n                    if (e.op == TOK.dSymbol)\n                    {\n                        *ps = (cast(DsymbolExp)e).s;\n                        *pe = null;\n                    }\n                    else\n                    {\n                        *ps = null;\n                        *pe = e;\n                    }\n                    return;\n                }\n                if (o.dyncast() == DYNCAST.type)\n                {\n                    *ps = null;\n                    *pt = (cast(Type)o).addMod(mt.mod);\n                    return;\n                }\n\n                /* Create a new TupleDeclaration which\n                 * is a slice [d..d+1] out of the old one.\n                 * Do it this way because TemplateInstance::semanticTiargs()\n                 * can handle unresolved Objects this way.\n                 */\n                auto objects = new Objects(1);\n                (*objects)[0] = o;\n                *ps = new TupleDeclaration(loc, tup.ident, objects);\n            }\n            else\n                goto Ldefault;\n        }\n        else\n        {\n            if ((*pt).ty != Terror)\n                mt.next = *pt; // prevent re-running semantic() on 'next'\n        Ldefault:\n            visit(cast(Type)mt);\n        }\n\n    }\n\n    override void visit(TypeDArray mt)\n    {\n        //printf(\"TypeDArray::resolve() %s\\n\", mt.toChars());\n        mt.next.resolve(loc, sc, pe, pt, ps, intypeid);\n        //printf(\"s = %p, e = %p, t = %p\\n\", *ps, *pe, *pt);\n        if (*pe)\n        {\n            // It's really a slice expression\n            if (Dsymbol s = getDsymbol(*pe))\n                *pe = new DsymbolExp(loc, s);\n            *pe = new ArrayExp(loc, *pe);\n        }\n        else if (*ps)\n        {\n            if (auto tup = (*ps).isTupleDeclaration())\n            {\n                // keep *ps\n            }\n            else\n                goto Ldefault;\n        }\n        else\n        {\n            if ((*pt).ty != Terror)\n                mt.next = *pt; // prevent re-running semantic() on 'next'\n        Ldefault:\n            visit(cast(Type)mt);\n        }\n    }\n\n    override void visit(TypeAArray mt)\n    {\n        //printf(\"TypeAArray::resolve() %s\\n\", mt.toChars());\n        // Deal with the case where we thought the index was a type, but\n        // in reality it was an expression.\n        if (mt.index.ty == Tident || mt.index.ty == Tinstance || mt.index.ty == Tsarray)\n        {\n            Expression e;\n            Type t;\n            Dsymbol s;\n            mt.index.resolve(loc, sc, &e, &t, &s, intypeid);\n            if (e)\n            {\n                // It was an expression -\n                // Rewrite as a static array\n                auto tsa = new TypeSArray(mt.next, e);\n                tsa.mod = mt.mod; // just copy mod field so tsa's semantic is not yet done\n                return tsa.resolve(loc, sc, pe, pt, ps, intypeid);\n            }\n            else if (t)\n                mt.index = t;\n            else\n                .error(loc, \"index is not a type or an expression\");\n        }\n        visit(cast(Type)mt);\n    }\n\n    /*************************************\n     * Takes an array of Identifiers and figures out if\n     * it represents a Type or an Expression.\n     * Output:\n     *      if expression, *pe is set\n     *      if type, *pt is set\n     */\n    override void visit(TypeIdentifier mt)\n    {\n        //printf(\"TypeIdentifier::resolve(sc = %p, idents = '%s')\\n\", sc, mt.toChars());\n        if ((mt.ident.equals(Id._super) || mt.ident.equals(Id.This)) && !hasThis(sc))\n        {\n            // @@@DEPRECATED_v2.086@@@.\n            if (mt.ident.equals(Id._super))\n            {\n                deprecation(mt.loc, \"Using `super` as a type is deprecated. Use `typeof(super)` instead\");\n            }\n            // @@@DEPRECATED_v2.086@@@.\n            if (mt.ident.equals(Id.This))\n            {\n                deprecation(mt.loc, \"Using `this` as a type is deprecated. Use `typeof(this)` instead\");\n            }\n            AggregateDeclaration ad = sc.getStructClassScope();\n            if (ad)\n            {\n                ClassDeclaration cd = ad.isClassDeclaration();\n                if (cd)\n                {\n                    if (mt.ident.equals(Id.This))\n                        mt.ident = cd.ident;\n                    else if (cd.baseClass && mt.ident.equals(Id._super))\n                        mt.ident = cd.baseClass.ident;\n                }\n                else\n                {\n                    StructDeclaration sd = ad.isStructDeclaration();\n                    if (sd && mt.ident.equals(Id.This))\n                        mt.ident = sd.ident;\n                }\n            }\n        }\n        if (mt.ident == Id.ctfe)\n        {\n            error(loc, \"variable `__ctfe` cannot be read at compile time\");\n            *pe = null;\n            *ps = null;\n            *pt = Type.terror;\n            return;\n        }\n\n        Dsymbol scopesym;\n        Dsymbol s = sc.search(loc, mt.ident, &scopesym);\n\n        if (s)\n        {\n            // https://issues.dlang.org/show_bug.cgi?id=16042\n            // If `f` is really a function template, then replace `f`\n            // with the function template declaration.\n            if (auto f = s.isFuncDeclaration())\n            {\n                if (auto td = getFuncTemplateDecl(f))\n                {\n                    // If not at the beginning of the overloaded list of\n                    // `TemplateDeclaration`s, then get the beginning\n                    if (td.overroot)\n                        td = td.overroot;\n                    s = td;\n                }\n            }\n        }\n\n        mt.resolveHelper(loc, sc, s, scopesym, pe, pt, ps, intypeid);\n        if (*pt)\n            (*pt) = (*pt).addMod(mt.mod);\n    }\n\n    override void visit(TypeInstance mt)\n    {\n        // Note close similarity to TypeIdentifier::resolve()\n        *pe = null;\n        *pt = null;\n        *ps = null;\n\n        //printf(\"TypeInstance::resolve(sc = %p, tempinst = '%s')\\n\", sc, mt.tempinst.toChars());\n        mt.tempinst.dsymbolSemantic(sc);\n        if (!global.gag && mt.tempinst.errors)\n        {\n            *pt = Type.terror;\n            return;\n        }\n\n        mt.resolveHelper(loc, sc, mt.tempinst, null, pe, pt, ps, intypeid);\n        if (*pt)\n            *pt = (*pt).addMod(mt.mod);\n        //if (*pt) printf(\"*pt = %d '%s'\\n\", (*pt).ty, (*pt).toChars());\n    }\n\n    override void visit(TypeTypeof mt)\n    {\n        *pe = null;\n        *pt = null;\n        *ps = null;\n\n        //printf(\"TypeTypeof::resolve(this = %p, sc = %p, idents = '%s')\\n\", mt, sc, mt.toChars());\n        //static int nest; if (++nest == 50) *(char*)0=0;\n        if (sc is null)\n        {\n            *pt = Type.terror;\n            error(loc, \"Invalid scope.\");\n            return;\n        }\n        if (mt.inuse)\n        {\n            mt.inuse = 2;\n            error(loc, \"circular `typeof` definition\");\n        Lerr:\n            *pt = Type.terror;\n            mt.inuse--;\n            return;\n        }\n        mt.inuse++;\n\n        /* Currently we cannot evaluate 'exp' in speculative context, because\n         * the type implementation may leak to the final execution. Consider:\n         *\n         * struct S(T) {\n         *   string toString() const { return \"x\"; }\n         * }\n         * void main() {\n         *   alias X = typeof(S!int());\n         *   assert(typeid(X).toString() == \"x\");\n         * }\n         */\n        Scope* sc2 = sc.push();\n        sc2.intypeof = 1;\n        auto exp2 = mt.exp.expressionSemantic(sc2);\n        exp2 = resolvePropertiesOnly(sc2, exp2);\n        sc2.pop();\n\n        if (exp2.op == TOK.error)\n        {\n            if (!global.gag)\n                mt.exp = exp2;\n            goto Lerr;\n        }\n        mt.exp = exp2;\n\n        if (mt.exp.op == TOK.type ||\n            mt.exp.op == TOK.scope_)\n        {\n            if (mt.exp.checkType())\n                goto Lerr;\n\n            /* Today, 'typeof(func)' returns void if func is a\n             * function template (TemplateExp), or\n             * template lambda (FuncExp).\n             * It's actually used in Phobos as an idiom, to branch code for\n             * template functions.\n             */\n        }\n        if (auto f = mt.exp.op == TOK.variable    ? (cast(   VarExp)mt.exp).var.isFuncDeclaration()\n                   : mt.exp.op == TOK.dotVariable ? (cast(DotVarExp)mt.exp).var.isFuncDeclaration() : null)\n        {\n            if (f.checkForwardRef(loc))\n                goto Lerr;\n        }\n        if (auto f = isFuncAddress(mt.exp))\n        {\n            if (f.checkForwardRef(loc))\n                goto Lerr;\n        }\n\n        Type t = mt.exp.type;\n        if (!t)\n        {\n            error(loc, \"expression `%s` has no type\", mt.exp.toChars());\n            goto Lerr;\n        }\n        if (t.ty == Ttypeof)\n        {\n            error(loc, \"forward reference to `%s`\", mt.toChars());\n            goto Lerr;\n        }\n        if (mt.idents.dim == 0)\n            *pt = t;\n        else\n        {\n            if (Dsymbol s = t.toDsymbol(sc))\n                mt.resolveHelper(loc, sc, s, null, pe, pt, ps, intypeid);\n            else\n            {\n                auto e = typeToExpressionHelper(mt, new TypeExp(loc, t));\n                e = e.expressionSemantic(sc);\n                mt.resolveExp(e, pt, pe, ps);\n            }\n        }\n        if (*pt)\n            (*pt) = (*pt).addMod(mt.mod);\n        mt.inuse--;\n        return;\n    }\n\n    override void visit(TypeReturn mt)\n    {\n        *pe = null;\n        *pt = null;\n        *ps = null;\n\n        //printf(\"TypeReturn::resolve(sc = %p, idents = '%s')\\n\", sc, mt.toChars());\n        Type t;\n        {\n            FuncDeclaration func = sc.func;\n            if (!func)\n            {\n                error(loc, \"`typeof(return)` must be inside function\");\n                goto Lerr;\n            }\n            if (func.fes)\n                func = func.fes.func;\n            t = func.type.nextOf();\n            if (!t)\n            {\n                error(loc, \"cannot use `typeof(return)` inside function `%s` with inferred return type\", sc.func.toChars());\n                goto Lerr;\n            }\n        }\n        if (mt.idents.dim == 0)\n            *pt = t;\n        else\n        {\n            if (Dsymbol s = t.toDsymbol(sc))\n               mt.resolveHelper(loc, sc, s, null, pe, pt, ps, intypeid);\n            else\n            {\n                auto e = typeToExpressionHelper(mt, new TypeExp(loc, t));\n                e = e.expressionSemantic(sc);\n                mt.resolveExp(e, pt, pe, ps);\n            }\n        }\n        if (*pt)\n            (*pt) = (*pt).addMod(mt.mod);\n        return;\n\n    Lerr:\n        *pt = Type.terror;\n    }\n\n    override void visit(TypeSlice mt)\n    {\n        mt.next.resolve(loc, sc, pe, pt, ps, intypeid);\n        if (*pe)\n        {\n            // It's really a slice expression\n            if (Dsymbol s = getDsymbol(*pe))\n                *pe = new DsymbolExp(loc, s);\n            *pe = new ArrayExp(loc, *pe, new IntervalExp(loc, mt.lwr, mt.upr));\n        }\n        else if (*ps)\n        {\n            Dsymbol s = *ps;\n            TupleDeclaration td = s.isTupleDeclaration();\n            if (td)\n            {\n                /* It's a slice of a TupleDeclaration\n                 */\n                ScopeDsymbol sym = new ArrayScopeSymbol(sc, td);\n                sym.parent = sc.scopesym;\n                sc = sc.push(sym);\n                sc = sc.startCTFE();\n                mt.lwr = mt.lwr.expressionSemantic(sc);\n                mt.upr = mt.upr.expressionSemantic(sc);\n                sc = sc.endCTFE();\n                sc = sc.pop();\n\n                mt.lwr = mt.lwr.ctfeInterpret();\n                mt.upr = mt.upr.ctfeInterpret();\n                uinteger_t i1 = mt.lwr.toUInteger();\n                uinteger_t i2 = mt.upr.toUInteger();\n                if (!(i1 <= i2 && i2 <= td.objects.dim))\n                {\n                    error(loc, \"slice `[%llu..%llu]` is out of range of [0..%u]\", i1, i2, td.objects.dim);\n                    *ps = null;\n                    *pt = Type.terror;\n                    return;\n                }\n\n                if (i1 == 0 && i2 == td.objects.dim)\n                {\n                    *ps = td;\n                    return;\n                }\n\n                /* Create a new TupleDeclaration which\n                 * is a slice [i1..i2] out of the old one.\n                 */\n                auto objects = new Objects(cast(size_t)(i2 - i1));\n                for (size_t i = 0; i < objects.dim; i++)\n                {\n                    (*objects)[i] = (*td.objects)[cast(size_t)i1 + i];\n                }\n\n                auto tds = new TupleDeclaration(loc, td.ident, objects);\n                *ps = tds;\n            }\n            else\n                goto Ldefault;\n        }\n        else\n        {\n            if ((*pt).ty != Terror)\n                mt.next = *pt; // prevent re-running semantic() on 'next'\n        Ldefault:\n            visit(cast(Type)mt);\n        }\n    }\n}\n\n/************************\n * Access the members of the object e. This type is same as e.type.\n * Params:\n *  mt = type for which the dot expression is used\n *  sc = instantiating scope\n *  e = expression to convert\n *  ident = identifier being used\n *  flag = DotExpFlag bit flags\n *\n * Returns:\n *  resulting expression with e.ident resolved\n */\nExpression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)\n{\n    scope v = new DotExpVisitor(sc, e, ident, flag);\n    mt.accept(v);\n    return v.result;\n}\n\nprivate extern(C++) final class DotExpVisitor : Visitor\n{\n    alias visit = typeof(super).visit;\n    Scope *sc;\n    Expression e;\n    Identifier ident;\n    int flag;\n    Expression result;\n\n    this(Scope* sc, Expression e, Identifier ident, int flag)\n    {\n        this.sc = sc;\n        this.e = e;\n        this.ident = ident;\n        this.flag = flag;\n    }\n\n    override void visit(Type mt)\n    {\n        VarDeclaration v = null;\n        static if (LOGDOTEXP)\n        {\n            printf(\"Type::dotExp(e = '%s', ident = '%s')\\n\", e.toChars(), ident.toChars());\n        }\n        Expression ex = e;\n        while (ex.op == TOK.comma)\n            ex = (cast(CommaExp)ex).e2;\n        if (ex.op == TOK.dotVariable)\n        {\n            DotVarExp dv = cast(DotVarExp)ex;\n            v = dv.var.isVarDeclaration();\n        }\n        else if (ex.op == TOK.variable)\n        {\n            VarExp ve = cast(VarExp)ex;\n            v = ve.var.isVarDeclaration();\n        }\n        if (v)\n        {\n            if (ident == Id.offsetof)\n            {\n                if (v.isField())\n                {\n                    auto ad = v.toParent().isAggregateDeclaration();\n                    objc.checkOffsetof(e, ad);\n                    ad.size(e.loc);\n                    if (ad.sizeok != Sizeok.done)\n                    {\n                        result = new ErrorExp();\n                        return;\n                    }\n                    e = new IntegerExp(e.loc, v.offset, Type.tsize_t);\n                    result = e;\n                    return;\n                }\n            }\n            else if (ident == Id._init)\n            {\n                Type tb = mt.toBasetype();\n                e = mt.defaultInitLiteral(e.loc);\n                if (tb.ty == Tstruct && tb.needsNested())\n                {\n                    StructLiteralExp se = cast(StructLiteralExp)e;\n                    se.useStaticInit = true;\n                }\n                goto Lreturn;\n            }\n        }\n        if (ident == Id.stringof)\n        {\n            /* https://issues.dlang.org/show_bug.cgi?id=3796\n             * this should demangle e.type.deco rather than\n             * pretty-printing the type.\n             */\n            const s = e.toChars();\n            e = new StringExp(e.loc, cast(char*)s);\n        }\n        else\n            e = mt.getProperty(e.loc, ident, flag & DotExpFlag.gag);\n\n    Lreturn:\n        if (e)\n            e = e.expressionSemantic(sc);\n        result = e;\n    }\n\n    override void visit(TypeError)\n    {\n        result = new ErrorExp();\n    }\n\n    override void visit(TypeBasic mt)\n    {\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeBasic::dotExp(e = '%s', ident = '%s')\\n\", e.toChars(), ident.toChars());\n        }\n        Type t;\n        if (ident == Id.re)\n        {\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n                t = mt.tfloat32;\n                goto L1;\n\n            case Tcomplex64:\n                t = mt.tfloat64;\n                goto L1;\n\n            case Tcomplex80:\n                t = mt.tfloat80;\n                goto L1;\n            L1:\n                e = e.castTo(sc, t);\n                break;\n\n            case Tfloat32:\n            case Tfloat64:\n            case Tfloat80:\n                break;\n\n            case Timaginary32:\n                t = mt.tfloat32;\n                goto L2;\n\n            case Timaginary64:\n                t = mt.tfloat64;\n                goto L2;\n\n            case Timaginary80:\n                t = mt.tfloat80;\n                goto L2;\n            L2:\n                e = new RealExp(e.loc, CTFloat.zero, t);\n                break;\n\n            default:\n                e = mt.Type.getProperty(e.loc, ident, flag);\n                break;\n            }\n        }\n        else if (ident == Id.im)\n        {\n            Type t2;\n            switch (mt.ty)\n            {\n            case Tcomplex32:\n                t = mt.timaginary32;\n                t2 = mt.tfloat32;\n                goto L3;\n\n            case Tcomplex64:\n                t = mt.timaginary64;\n                t2 = mt.tfloat64;\n                goto L3;\n\n            case Tcomplex80:\n                t = mt.timaginary80;\n                t2 = mt.tfloat80;\n                goto L3;\n            L3:\n                e = e.castTo(sc, t);\n                e.type = t2;\n                break;\n\n            case Timaginary32:\n                t = mt.tfloat32;\n                goto L4;\n\n            case Timaginary64:\n                t = mt.tfloat64;\n                goto L4;\n\n            case Timaginary80:\n                t = mt.tfloat80;\n                goto L4;\n            L4:\n                e = e.copy();\n                e.type = t;\n                break;\n\n            case Tfloat32:\n            case Tfloat64:\n            case Tfloat80:\n                e = new RealExp(e.loc, CTFloat.zero, mt);\n                break;\n\n            default:\n                e = mt.Type.getProperty(e.loc, ident, flag);\n                break;\n            }\n        }\n        else\n        {\n            visit(cast(Type)mt);\n            return;\n        }\n        if (!(flag & 1) || e)\n            e = e.expressionSemantic(sc);\n        result = e;\n    }\n\n    override void visit(TypeVector mt)\n    {\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeVector::dotExp(e = '%s', ident = '%s')\\n\", e.toChars(), ident.toChars());\n        }\n        if (ident == Id.ptr && e.op == TOK.call)\n        {\n            /* The trouble with TOK.call is the return ABI for float[4] is different from\n             * __vector(float[4]), and a type paint won't do.\n             */\n            e = new AddrExp(e.loc, e);\n            e = e.expressionSemantic(sc);\n            e = e.castTo(sc, mt.basetype.nextOf().pointerTo());\n            result = e;\n            return;\n        }\n        if (ident == Id.array)\n        {\n            //e = e.castTo(sc, basetype);\n            // Keep lvalue-ness\n            e = e.copy();\n            e.type = mt.basetype;\n            result = e;\n            return;\n        }\n        if (ident == Id._init || ident == Id.offsetof || ident == Id.stringof || ident == Id.__xalignof)\n        {\n            // init should return a new VectorExp\n            // https://issues.dlang.org/show_bug.cgi?id=12776\n            // offsetof does not work on a cast expression, so use e directly\n            // stringof should not add a cast to the output\n            visit(cast(Type)mt);\n            return;\n        }\n        result = mt.basetype.dotExp(sc, e.castTo(sc, mt.basetype), ident, flag);\n    }\n\n    override void visit(TypeArray mt)\n    {\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeArray::dotExp(e = '%s', ident = '%s')\\n\", e.toChars(), ident.toChars());\n        }\n\n        visit(cast(Type)mt);\n        e = result;\n\n        if (!(flag & 1) || e)\n            e = e.expressionSemantic(sc);\n        result = e;\n    }\n\n    override void visit(TypeSArray mt)\n    {\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeSArray::dotExp(e = '%s', ident = '%s')\\n\", e.toChars(), ident.toChars());\n        }\n        if (ident == Id.length)\n        {\n            Loc oldLoc = e.loc;\n            e = mt.dim.copy();\n            e.loc = oldLoc;\n        }\n        else if (ident == Id.ptr)\n        {\n            if (e.op == TOK.type)\n            {\n                e.error(\"`%s` is not an expression\", e.toChars());\n                result = new ErrorExp();\n                return;\n            }\n            else if (!(flag & DotExpFlag.noDeref) && sc.func && !sc.intypeof && sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n            {\n                e.error(\"`%s.ptr` cannot be used in `@safe` code, use `&%s[0]` instead\", e.toChars(), e.toChars());\n                result = new ErrorExp();\n                return;\n            }\n            e = e.castTo(sc, e.type.nextOf().pointerTo());\n        }\n        else\n        {\n            visit(cast(TypeArray)mt);\n            e = result;\n        }\n        if (!(flag & 1) || e)\n            e = e.expressionSemantic(sc);\n        result = e;\n    }\n\n    override void visit(TypeDArray mt)\n    {\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeDArray::dotExp(e = '%s', ident = '%s')\\n\", e.toChars(), ident.toChars());\n        }\n        if (e.op == TOK.type && (ident == Id.length || ident == Id.ptr))\n        {\n            e.error(\"`%s` is not an expression\", e.toChars());\n            result = new ErrorExp();\n            return;\n        }\n        if (ident == Id.length)\n        {\n            if (e.op == TOK.string_)\n            {\n                StringExp se = cast(StringExp)e;\n                result = new IntegerExp(se.loc, se.len, Type.tsize_t);\n                return;\n            }\n            if (e.op == TOK.null_)\n            {\n                result = new IntegerExp(e.loc, 0, Type.tsize_t);\n                return;\n            }\n            if (checkNonAssignmentArrayOp(e))\n            {\n                result = new ErrorExp();\n                return;\n            }\n            e = new ArrayLengthExp(e.loc, e);\n            e.type = Type.tsize_t;\n            result = e;\n            return;\n        }\n        else if (ident == Id.ptr)\n        {\n            if (!(flag & DotExpFlag.noDeref) && sc.func && !sc.intypeof && sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n            {\n                e.error(\"`%s.ptr` cannot be used in `@safe` code, use `&%s[0]` instead\", e.toChars(), e.toChars());\n                    result = new ErrorExp();\n                    return;\n            }\n            e = e.castTo(sc, mt.next.pointerTo());\n            result = e;\n            return;\n        }\n        else\n        {\n            visit(cast(TypeArray)mt);\n            e = result;\n        }\n        result = e;\n    }\n\n    override void visit(TypeAArray mt)\n    {\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeAArray::dotExp(e = '%s', ident = '%s')\\n\", e.toChars(), ident.toChars());\n        }\n        if (ident == Id.length)\n        {\n            __gshared FuncDeclaration fd_aaLen = null;\n            if (fd_aaLen is null)\n            {\n                auto fparams = new Parameters();\n                fparams.push(new Parameter(STC.in_, mt, null, null, null));\n                fd_aaLen = FuncDeclaration.genCfunc(fparams, Type.tsize_t, Id.aaLen);\n                TypeFunction tf = fd_aaLen.type.toTypeFunction();\n                tf.purity = PURE.const_;\n                tf.isnothrow = true;\n                tf.isnogc = false;\n            }\n            Expression ev = new VarExp(e.loc, fd_aaLen, false);\n            e = new CallExp(e.loc, ev, e);\n            e.type = fd_aaLen.type.toTypeFunction().next;\n        }\n        else\n        {\n            visit(cast(Type)mt);\n            e = result;\n        }\n        result = e;\n    }\n\n    override void visit(TypeReference mt)\n    {\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeReference::dotExp(e = '%s', ident = '%s')\\n\", e.toChars(), ident.toChars());\n        }\n        // References just forward things along\n        result = mt.next.dotExp(sc, e, ident, flag);\n    }\n\n    override void visit(TypeDelegate mt)\n    {\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeDelegate::dotExp(e = '%s', ident = '%s')\\n\", e.toChars(), ident.toChars());\n        }\n        if (ident == Id.ptr)\n        {\n            e = new DelegatePtrExp(e.loc, e);\n            e = e.expressionSemantic(sc);\n        }\n        else if (ident == Id.funcptr)\n        {\n            if (!(flag & DotExpFlag.noDeref) && sc.func && !sc.intypeof && sc.func.setUnsafe() && !(sc.flags & SCOPE.debug_))\n            {\n                e.error(\"`%s.funcptr` cannot be used in `@safe` code\", e.toChars());\n                result = new ErrorExp();\n                return;\n            }\n            e = new DelegateFuncptrExp(e.loc, e);\n            e = e.expressionSemantic(sc);\n        }\n        else\n        {\n            visit(cast(Type)mt);\n            e = result;\n        }\n        result = e;\n    }\n\n    /***************************************\n     * Figures out what to do with an undefined member reference\n     * for classes and structs.\n     *\n     * If flag & 1, don't report \"not a property\" error and just return NULL.\n     */\n    Expression noMember(Type mt, Scope* sc, Expression e, Identifier ident, int flag)\n    {\n        //printf(\"Type.noMember(e: %s ident: %s flag: %d)\\n\", e.toChars(), ident.toChars(), flag);\n\n        bool gagError = flag & 1;\n\n        __gshared int nest;      // https://issues.dlang.org/show_bug.cgi?id=17380\n\n        static Expression returnExp(Expression e)\n        {\n            --nest;\n            return e;\n        }\n\n        if (++nest > 500)\n        {\n            .error(e.loc, \"cannot resolve identifier `%s`\", ident.toChars());\n            return returnExp(gagError ? null : new ErrorExp());\n        }\n\n\n        assert(mt.ty == Tstruct || mt.ty == Tclass);\n        auto sym = mt.toDsymbol(sc).isAggregateDeclaration();\n        assert(sym);\n        if (ident != Id.__sizeof &&\n            ident != Id.__xalignof &&\n            ident != Id._init &&\n            ident != Id._mangleof &&\n            ident != Id.stringof &&\n            ident != Id.offsetof &&\n            // https://issues.dlang.org/show_bug.cgi?id=15045\n            // Don't forward special built-in member functions.\n            ident != Id.ctor &&\n            ident != Id.dtor &&\n            ident != Id.__xdtor &&\n            ident != Id.postblit &&\n            ident != Id.__xpostblit)\n        {\n            /* Look for overloaded opDot() to see if we should forward request\n             * to it.\n             */\n            if (auto fd = search_function(sym, Id.opDot))\n            {\n                /* Rewrite e.ident as:\n                 *  e.opDot().ident\n                 */\n                e = build_overload(e.loc, sc, e, null, fd);\n                // @@@DEPRECATED_2.087@@@.\n                e.deprecation(\"`opDot` is deprecated. Use `alias this`\");\n                e = new DotIdExp(e.loc, e, ident);\n                return returnExp(e.expressionSemantic(sc));\n            }\n\n            /* Look for overloaded opDispatch to see if we should forward request\n             * to it.\n             */\n            if (auto fd = search_function(sym, Id.opDispatch))\n            {\n                /* Rewrite e.ident as:\n                 *  e.opDispatch!(\"ident\")\n                 */\n                TemplateDeclaration td = fd.isTemplateDeclaration();\n                if (!td)\n                {\n                    fd.error(\"must be a template `opDispatch(string s)`, not a %s\", fd.kind());\n                    return returnExp(new ErrorExp());\n                }\n                auto se = new StringExp(e.loc, cast(char*)ident.toChars());\n                auto tiargs = new Objects();\n                tiargs.push(se);\n                auto dti = new DotTemplateInstanceExp(e.loc, e, Id.opDispatch, tiargs);\n                dti.ti.tempdecl = td;\n                /* opDispatch, which doesn't need IFTI,  may occur instantiate error.\n                 * e.g.\n                 *  template opDispatch(name) if (isValid!name) { ... }\n                 */\n                uint errors = gagError ? global.startGagging() : 0;\n                e = dti.semanticY(sc, 0);\n                if (gagError && global.endGagging(errors))\n                    e = null;\n                return returnExp(e);\n            }\n\n            /* See if we should forward to the alias this.\n             */\n            auto alias_e = resolveAliasThis(sc, e, gagError);\n            if (alias_e && alias_e != e)\n            {\n                /* Rewrite e.ident as:\n                 *  e.aliasthis.ident\n                 */\n                auto die = new DotIdExp(e.loc, alias_e, ident);\n\n                auto errors = gagError ? 0 : global.startGagging();\n                auto exp = die.semanticY(sc, gagError);\n                if (!gagError)\n                {\n                    global.endGagging(errors);\n                    if (exp && exp.op == TOK.error)\n                        exp = null;\n                }\n\n                if (exp && gagError)\n                    // now that we know that the alias this leads somewhere useful,\n                    // go back and print deprecations/warnings that we skipped earlier due to the gag\n                    resolveAliasThis(sc, e, false);\n\n                return returnExp(exp);\n            }\n        }\n        visit(cast(Type)mt);\n        return returnExp(result);\n    }\n\n    override void visit(TypeStruct mt)\n    {\n        Dsymbol s;\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeStruct::dotExp(e = '%s', ident = '%s')\\n\", e.toChars(), ident.toChars());\n        }\n        assert(e.op != TOK.dot);\n\n        // https://issues.dlang.org/show_bug.cgi?id=14010\n        if (ident == Id._mangleof)\n        {\n            result = mt.getProperty(e.loc, ident, flag & 1);\n            return;\n        }\n\n        /* If e.tupleof\n         */\n        if (ident == Id._tupleof)\n        {\n            /* Create a TupleExp out of the fields of the struct e:\n             * (e.field0, e.field1, e.field2, ...)\n             */\n            e = e.expressionSemantic(sc); // do this before turning on noaccesscheck\n\n            if (!mt.sym.determineFields())\n            {\n                error(e.loc, \"unable to determine fields of `%s` because of forward references\", mt.toChars());\n            }\n\n            Expression e0;\n            Expression ev = e.op == TOK.type ? null : e;\n            if (ev)\n                ev = extractSideEffect(sc, \"__tup\", e0, ev);\n\n            auto exps = new Expressions();\n            exps.reserve(mt.sym.fields.dim);\n            for (size_t i = 0; i < mt.sym.fields.dim; i++)\n            {\n                VarDeclaration v = mt.sym.fields[i];\n                Expression ex;\n                if (ev)\n                    ex = new DotVarExp(e.loc, ev, v);\n                else\n                {\n                    ex = new VarExp(e.loc, v);\n                    ex.type = ex.type.addMod(e.type.mod);\n                }\n                exps.push(ex);\n            }\n\n            e = new TupleExp(e.loc, e0, exps);\n            Scope* sc2 = sc.push();\n            sc2.flags |= global.params.vsafe ? SCOPE.onlysafeaccess : SCOPE.noaccesscheck;\n            e = e.expressionSemantic(sc2);\n            sc2.pop();\n            result = e;\n            return;\n        }\n\n        Dsymbol searchSym()\n        {\n            int flags = sc.flags & SCOPE.ignoresymbolvisibility ? IgnoreSymbolVisibility : 0;\n\n            Dsymbol sold = void;\n            if (global.params.bug10378 || global.params.check10378)\n            {\n                sold = mt.sym.search(e.loc, ident, flags);\n                if (!global.params.check10378)\n                    return sold;\n            }\n\n            auto s = mt.sym.search(e.loc, ident, flags | IgnorePrivateImports);\n            if (global.params.check10378)\n            {\n                alias snew = s;\n                if (sold !is snew)\n                    Scope.deprecation10378(e.loc, sold, snew);\n                if (global.params.bug10378)\n                    s = sold;\n            }\n            return s;\n        }\n\n        s = searchSym();\n    L1:\n        if (!s)\n        {\n            result = noMember(mt, sc, e, ident, flag);\n            return;\n        }\n        if (!(sc.flags & SCOPE.ignoresymbolvisibility) && !symbolIsVisible(sc, s))\n        {\n            .deprecation(e.loc, \"`%s` is not visible from module `%s`\", s.toPrettyChars(), sc._module.toPrettyChars());\n            // return noMember(sc, e, ident, flag);\n        }\n        if (!s.isFuncDeclaration()) // because of overloading\n        {\n            s.checkDeprecated(e.loc, sc);\n            if (auto d = s.isDeclaration())\n                d.checkDisabled(e.loc, sc);\n        }\n        s = s.toAlias();\n\n        if (auto em = s.isEnumMember())\n        {\n            result = em.getVarExp(e.loc, sc);\n            return;\n        }\n        if (auto v = s.isVarDeclaration())\n        {\n            if (!v.type ||\n                !v.type.deco && v.inuse)\n            {\n                if (v.inuse) // https://issues.dlang.org/show_bug.cgi?id=9494\n                    e.error(\"circular reference to %s `%s`\", v.kind(), v.toPrettyChars());\n                else\n                    e.error(\"forward reference to %s `%s`\", v.kind(), v.toPrettyChars());\n                result = new ErrorExp();\n                return;\n            }\n            if (v.type.ty == Terror)\n            {\n                result = new ErrorExp();\n                return;\n            }\n\n            if ((v.storage_class & STC.manifest) && v._init)\n            {\n                if (v.inuse)\n                {\n                    e.error(\"circular initialization of %s `%s`\", v.kind(), v.toPrettyChars());\n                    result = new ErrorExp();\n                    return;\n                }\n                checkAccess(e.loc, sc, null, v);\n                Expression ve = new VarExp(e.loc, v);\n                if (!isTrivialExp(e))\n                {\n                    ve = new CommaExp(e.loc, e, ve);\n                }\n                ve = ve.expressionSemantic(sc);\n                result = ve;\n                return;\n            }\n        }\n\n        if (auto t = s.getType())\n        {\n            result = (new TypeExp(e.loc, t)).expressionSemantic(sc);\n            return;\n        }\n\n        TemplateMixin tm = s.isTemplateMixin();\n        if (tm)\n        {\n            Expression de = new DotExp(e.loc, e, new ScopeExp(e.loc, tm));\n            de.type = e.type;\n            result = de;\n            return;\n        }\n\n        TemplateDeclaration td = s.isTemplateDeclaration();\n        if (td)\n        {\n            if (e.op == TOK.type)\n                e = new TemplateExp(e.loc, td);\n            else\n                e = new DotTemplateExp(e.loc, e, td);\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n\n        TemplateInstance ti = s.isTemplateInstance();\n        if (ti)\n        {\n            if (!ti.semanticRun)\n            {\n                ti.dsymbolSemantic(sc);\n                if (!ti.inst || ti.errors) // if template failed to expand\n                {\n                    result = new ErrorExp();\n                    return;\n                }\n            }\n            s = ti.inst.toAlias();\n            if (!s.isTemplateInstance())\n                goto L1;\n            if (e.op == TOK.type)\n                e = new ScopeExp(e.loc, ti);\n            else\n                e = new DotExp(e.loc, e, new ScopeExp(e.loc, ti));\n            result = e.expressionSemantic(sc);\n            return;\n        }\n\n        if (s.isImport() || s.isModule() || s.isPackage())\n        {\n            e = dmd.expressionsem.resolve(e.loc, sc, s, false);\n            result = e;\n            return;\n        }\n\n        OverloadSet o = s.isOverloadSet();\n        if (o)\n        {\n            auto oe = new OverExp(e.loc, o);\n            if (e.op == TOK.type)\n            {\n                result = oe;\n                return;\n            }\n            result = new DotExp(e.loc, e, oe);\n            return;\n        }\n\n        Declaration d = s.isDeclaration();\n        if (!d)\n        {\n            e.error(\"`%s.%s` is not a declaration\", e.toChars(), ident.toChars());\n            result = new ErrorExp();\n            return;\n        }\n\n        if (e.op == TOK.type)\n        {\n            /* It's:\n             *    Struct.d\n             */\n            if (TupleDeclaration tup = d.isTupleDeclaration())\n            {\n                e = new TupleExp(e.loc, tup);\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n            if (d.needThis() && sc.intypeof != 1)\n            {\n                /* Rewrite as:\n                 *  this.d\n                 */\n                if (hasThis(sc))\n                {\n                    e = new DotVarExp(e.loc, new ThisExp(e.loc), d);\n                    e = e.expressionSemantic(sc);\n                    result = e;\n                    return;\n                }\n            }\n            if (d.semanticRun == PASS.init)\n                d.dsymbolSemantic(null);\n            checkAccess(e.loc, sc, e, d);\n            auto ve = new VarExp(e.loc, d);\n            if (d.isVarDeclaration() && d.needThis())\n                ve.type = d.type.addMod(e.type.mod);\n            result = ve;\n            return;\n        }\n\n        bool unreal = e.op == TOK.variable && (cast(VarExp)e).var.isField();\n        if (d.isDataseg() || unreal && d.isField())\n        {\n            // (e, d)\n            checkAccess(e.loc, sc, e, d);\n            Expression ve = new VarExp(e.loc, d);\n            e = unreal ? ve : new CommaExp(e.loc, e, ve);\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n\n        e = new DotVarExp(e.loc, e, d);\n        e = e.expressionSemantic(sc);\n        result = e;\n    }\n\n    override void visit(TypeEnum mt)\n    {\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\\n\", e.toChars(), ident.toChars(), mt.toChars());\n        }\n        // https://issues.dlang.org/show_bug.cgi?id=14010\n        if (ident == Id._mangleof)\n        {\n            result = mt.getProperty(e.loc, ident, flag & 1);\n            return;\n        }\n\n        if (mt.sym.semanticRun < PASS.semanticdone)\n            mt.sym.dsymbolSemantic(null);\n        if (!mt.sym.members)\n        {\n            if (mt.sym.isSpecial())\n            {\n                /* Special enums forward to the base type\n                 */\n                e = mt.sym.memtype.dotExp(sc, e, ident, flag);\n            }\n            else if (!(flag & 1))\n            {\n                mt.sym.error(\"is forward referenced when looking for `%s`\", ident.toChars());\n                e = new ErrorExp();\n            }\n            else\n                e = null;\n            result = e;\n            return;\n        }\n\n        Dsymbol s = mt.sym.search(e.loc, ident);\n        if (!s)\n        {\n            if (ident == Id.max || ident == Id.min || ident == Id._init)\n            {\n                result = mt.getProperty(e.loc, ident, flag & 1);\n                return;\n            }\n\n            Expression res = mt.sym.getMemtype(Loc.initial).dotExp(sc, e, ident, 1);\n            if (!(flag & 1) && !res)\n            {\n                if (auto ns = mt.sym.search_correct(ident))\n                    e.error(\"no property `%s` for type `%s`. Did you mean `%s.%s` ?\", ident.toChars(), mt.toChars(), mt.toChars(),\n                        ns.toChars());\n                else\n                    e.error(\"no property `%s` for type `%s`\", ident.toChars(),\n                        mt.toChars());\n\n                result = new ErrorExp();\n                return;\n            }\n            result = res;\n            return;\n        }\n        EnumMember m = s.isEnumMember();\n        result = m.getVarExp(e.loc, sc);\n    }\n\n    override void visit(TypeClass mt)\n    {\n        Dsymbol s;\n        static if (LOGDOTEXP)\n        {\n            printf(\"TypeClass::dotExp(e = '%s', ident = '%s')\\n\", e.toChars(), ident.toChars());\n        }\n        assert(e.op != TOK.dot);\n\n        // https://issues.dlang.org/show_bug.cgi?id=12543\n        if (ident == Id.__sizeof || ident == Id.__xalignof || ident == Id._mangleof)\n        {\n            result = mt.Type.getProperty(e.loc, ident, 0);\n            return;\n        }\n\n        /* If e.tupleof\n         */\n        if (ident == Id._tupleof)\n        {\n            objc.checkTupleof(e, mt);\n\n            /* Create a TupleExp\n             */\n            e = e.expressionSemantic(sc); // do this before turning on noaccesscheck\n\n            mt.sym.size(e.loc); // do semantic of type\n\n            Expression e0;\n            Expression ev = e.op == TOK.type ? null : e;\n            if (ev)\n                ev = extractSideEffect(sc, \"__tup\", e0, ev);\n\n            auto exps = new Expressions();\n            exps.reserve(mt.sym.fields.dim);\n            for (size_t i = 0; i < mt.sym.fields.dim; i++)\n            {\n                VarDeclaration v = mt.sym.fields[i];\n                // Don't include hidden 'this' pointer\n                if (v.isThisDeclaration())\n                    continue;\n                Expression ex;\n                if (ev)\n                    ex = new DotVarExp(e.loc, ev, v);\n                else\n                {\n                    ex = new VarExp(e.loc, v);\n                    ex.type = ex.type.addMod(e.type.mod);\n                }\n                exps.push(ex);\n            }\n\n            e = new TupleExp(e.loc, e0, exps);\n            Scope* sc2 = sc.push();\n            sc2.flags |= global.params.vsafe ? SCOPE.onlysafeaccess : SCOPE.noaccesscheck;\n            e = e.expressionSemantic(sc2);\n            sc2.pop();\n            result = e;\n            return;\n        }\n\n        Dsymbol searchSym()\n        {\n            int flags = sc.flags & SCOPE.ignoresymbolvisibility ? IgnoreSymbolVisibility : 0;\n            Dsymbol sold = void;\n            if (global.params.bug10378 || global.params.check10378)\n            {\n                sold = mt.sym.search(e.loc, ident, flags | IgnoreSymbolVisibility);\n                if (!global.params.check10378)\n                    return sold;\n            }\n\n            auto s = mt.sym.search(e.loc, ident, flags | SearchLocalsOnly);\n            if (!s && !(flags & IgnoreSymbolVisibility))\n            {\n                s = mt.sym.search(e.loc, ident, flags | SearchLocalsOnly | IgnoreSymbolVisibility);\n                if (s && !(flags & IgnoreErrors))\n                    .deprecation(e.loc, \"`%s` is not visible from class `%s`\", s.toPrettyChars(), mt.sym.toChars());\n            }\n            if (global.params.check10378)\n            {\n                alias snew = s;\n                if (sold !is snew)\n                    Scope.deprecation10378(e.loc, sold, snew);\n                if (global.params.bug10378)\n                    s = sold;\n            }\n            return s;\n        }\n\n        s = searchSym();\n    L1:\n        if (!s)\n        {\n            // See if it's 'this' class or a base class\n            if (mt.sym.ident == ident)\n            {\n                if (e.op == TOK.type)\n                {\n                    result = mt.Type.getProperty(e.loc, ident, 0);\n                    return;\n                }\n                e = new DotTypeExp(e.loc, e, mt.sym);\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n            if (auto cbase = mt.sym.searchBase(ident))\n            {\n                if (e.op == TOK.type)\n                {\n                    result = mt.Type.getProperty(e.loc, ident, 0);\n                    return;\n                }\n                if (auto ifbase = cbase.isInterfaceDeclaration())\n                    e = new CastExp(e.loc, e, ifbase.type);\n                else\n                    e = new DotTypeExp(e.loc, e, cbase);\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n\n            if (ident == Id.classinfo)\n            {\n                assert(Type.typeinfoclass);\n                Type t = Type.typeinfoclass.type;\n                if (e.op == TOK.type || e.op == TOK.dotType)\n                {\n                    /* For type.classinfo, we know the classinfo\n                     * at compile time.\n                     */\n                    if (!mt.sym.vclassinfo)\n                        mt.sym.vclassinfo = new TypeInfoClassDeclaration(mt.sym.type);\n                    e = new VarExp(e.loc, mt.sym.vclassinfo);\n                    e = e.addressOf();\n                    e.type = t; // do this so we don't get redundant dereference\n                }\n                else\n                {\n                    /* For class objects, the classinfo reference is the first\n                     * entry in the vtbl[]\n                     */\n                    e = new PtrExp(e.loc, e);\n                    e.type = t.pointerTo();\n                    if (mt.sym.isInterfaceDeclaration())\n                    {\n                        if (mt.sym.isCPPinterface())\n                        {\n                            /* C++ interface vtbl[]s are different in that the\n                             * first entry is always pointer to the first virtual\n                             * function, not classinfo.\n                             * We can't get a .classinfo for it.\n                             */\n                            error(e.loc, \"no `.classinfo` for C++ interface objects\");\n                        }\n                        /* For an interface, the first entry in the vtbl[]\n                         * is actually a pointer to an instance of struct Interface.\n                         * The first member of Interface is the .classinfo,\n                         * so add an extra pointer indirection.\n                         */\n                        e.type = e.type.pointerTo();\n                        e = new PtrExp(e.loc, e);\n                        e.type = t.pointerTo();\n                    }\n                    e = new PtrExp(e.loc, e, t);\n                }\n                result = e;\n                return;\n            }\n\n            if (ident == Id.__vptr)\n            {\n                /* The pointer to the vtbl[]\n                 * *cast(immutable(void*)**)e\n                 */\n                e = e.castTo(sc, mt.tvoidptr.immutableOf().pointerTo().pointerTo());\n                e = new PtrExp(e.loc, e);\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n\n            if (ident == Id.__monitor)\n            {\n                /* The handle to the monitor (call it a void*)\n                 * *(cast(void**)e + 1)\n                 */\n                e = e.castTo(sc, mt.tvoidptr.pointerTo());\n                e = new AddExp(e.loc, e, new IntegerExp(1));\n                e = new PtrExp(e.loc, e);\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n\n            if (ident == Id.outer && mt.sym.vthis)\n            {\n                if (mt.sym.vthis.semanticRun == PASS.init)\n                    mt.sym.vthis.dsymbolSemantic(null);\n\n                if (auto cdp = mt.sym.toParent2().isClassDeclaration())\n                {\n                    auto dve = new DotVarExp(e.loc, e, mt.sym.vthis);\n                    dve.type = cdp.type.addMod(e.type.mod);\n                    result = dve;\n                    return;\n                }\n\n                /* https://issues.dlang.org/show_bug.cgi?id=15839\n                 * Find closest parent class through nested functions.\n                 */\n                for (auto p = mt.sym.toParent2(); p; p = p.toParent2())\n                {\n                    auto fd = p.isFuncDeclaration();\n                    if (!fd)\n                        break;\n                    if (fd.isNested())\n                        continue;\n                    auto ad = fd.isThis();\n                    if (!ad)\n                        break;\n                    if (auto cdp = ad.isClassDeclaration())\n                    {\n                        auto ve = new ThisExp(e.loc);\n\n                        ve.var = fd.vthis;\n                        const nestedError = fd.vthis.checkNestedReference(sc, e.loc);\n                        assert(!nestedError);\n\n                        ve.type = fd.vthis.type.addMod(e.type.mod);\n                        result = ve;\n                        return;\n                    }\n                    break;\n                }\n\n                // Continue to show enclosing function's frame (stack or closure).\n                auto dve = new DotVarExp(e.loc, e, mt.sym.vthis);\n                dve.type = mt.sym.vthis.type.addMod(e.type.mod);\n                result = dve;\n                return;\n            }\n\n            result = noMember(mt, sc, e, ident, flag & 1);\n            return;\n        }\n        if (!(sc.flags & SCOPE.ignoresymbolvisibility) && !symbolIsVisible(sc, s))\n        {\n            .deprecation(e.loc, \"`%s` is not visible from module `%s`\", s.toPrettyChars(), sc._module.toPrettyChars());\n            // return noMember(sc, e, ident, flag);\n        }\n        if (!s.isFuncDeclaration()) // because of overloading\n        {\n            s.checkDeprecated(e.loc, sc);\n            if (auto d = s.isDeclaration())\n                d.checkDisabled(e.loc, sc);\n        }\n        s = s.toAlias();\n\n        if (auto em = s.isEnumMember())\n        {\n            result = em.getVarExp(e.loc, sc);\n            return;\n        }\n        if (auto v = s.isVarDeclaration())\n        {\n            if (!v.type ||\n                !v.type.deco && v.inuse)\n            {\n                if (v.inuse) // https://issues.dlang.org/show_bug.cgi?id=9494\n                    e.error(\"circular reference to %s `%s`\", v.kind(), v.toPrettyChars());\n                else\n                    e.error(\"forward reference to %s `%s`\", v.kind(), v.toPrettyChars());\n                result = new ErrorExp();\n                return;\n            }\n            if (v.type.ty == Terror)\n            {\n                result = new ErrorExp();\n                return;\n            }\n\n            if ((v.storage_class & STC.manifest) && v._init)\n            {\n                if (v.inuse)\n                {\n                    e.error(\"circular initialization of %s `%s`\", v.kind(), v.toPrettyChars());\n                    result = new ErrorExp();\n                    return;\n                }\n                checkAccess(e.loc, sc, null, v);\n                Expression ve = new VarExp(e.loc, v);\n                ve = ve.expressionSemantic(sc);\n                result = ve;\n                return;\n            }\n        }\n\n        if (auto t = s.getType())\n        {\n            result = (new TypeExp(e.loc, t)).expressionSemantic(sc);\n            return;\n        }\n\n        TemplateMixin tm = s.isTemplateMixin();\n        if (tm)\n        {\n            Expression de = new DotExp(e.loc, e, new ScopeExp(e.loc, tm));\n            de.type = e.type;\n            result = de;\n            return;\n        }\n\n        TemplateDeclaration td = s.isTemplateDeclaration();\n        if (td)\n        {\n            if (e.op == TOK.type)\n                e = new TemplateExp(e.loc, td);\n            else\n                e = new DotTemplateExp(e.loc, e, td);\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n\n        TemplateInstance ti = s.isTemplateInstance();\n        if (ti)\n        {\n            if (!ti.semanticRun)\n            {\n                ti.dsymbolSemantic(sc);\n                if (!ti.inst || ti.errors) // if template failed to expand\n                {\n                    result = new ErrorExp();\n                    return;\n                }\n            }\n            s = ti.inst.toAlias();\n            if (!s.isTemplateInstance())\n                goto L1;\n            if (e.op == TOK.type)\n                e = new ScopeExp(e.loc, ti);\n            else\n                e = new DotExp(e.loc, e, new ScopeExp(e.loc, ti));\n            result = e.expressionSemantic(sc);\n            return;\n        }\n\n        if (s.isImport() || s.isModule() || s.isPackage())\n        {\n            e = dmd.expressionsem.resolve(e.loc, sc, s, false);\n            result = e;\n            return;\n        }\n\n        OverloadSet o = s.isOverloadSet();\n        if (o)\n        {\n            auto oe = new OverExp(e.loc, o);\n            if (e.op == TOK.type)\n            {\n                result = oe;\n                return;\n            }\n            result = new DotExp(e.loc, e, oe);\n            return;\n        }\n\n        Declaration d = s.isDeclaration();\n        if (!d)\n        {\n            e.error(\"`%s.%s` is not a declaration\", e.toChars(), ident.toChars());\n            result = new ErrorExp();\n            return;\n        }\n\n        if (e.op == TOK.type)\n        {\n            /* It's:\n             *    Class.d\n             */\n            if (TupleDeclaration tup = d.isTupleDeclaration())\n            {\n                e = new TupleExp(e.loc, tup);\n                e = e.expressionSemantic(sc);\n                result = e;\n                return;\n            }\n\n            if (mt.sym.classKind == ClassKind.objc\n                && d.isFuncDeclaration()\n                && d.isFuncDeclaration().isStatic\n                && d.isFuncDeclaration().selector)\n            {\n                auto classRef = new ObjcClassReferenceExp(e.loc, mt.sym);\n                result = new DotVarExp(e.loc, classRef, d).expressionSemantic(sc);\n                return;\n            }\n            else if (d.needThis() && sc.intypeof != 1)\n            {\n                /* Rewrite as:\n                 *  this.d\n                 */\n                if (hasThis(sc))\n                {\n                    // This is almost same as getRightThis() in expression.c\n                    Expression e1 = new ThisExp(e.loc);\n                    e1 = e1.expressionSemantic(sc);\n                L2:\n                    Type t = e1.type.toBasetype();\n                    ClassDeclaration cd = e.type.isClassHandle();\n                    ClassDeclaration tcd = t.isClassHandle();\n                    if (cd && tcd && (tcd == cd || cd.isBaseOf(tcd, null)))\n                    {\n                        e = new DotTypeExp(e1.loc, e1, cd);\n                        e = new DotVarExp(e.loc, e, d);\n                        e = e.expressionSemantic(sc);\n                        result = e;\n                        return;\n                    }\n                    if (tcd && tcd.isNested())\n                    {\n                        /* e1 is the 'this' pointer for an inner class: tcd.\n                         * Rewrite it as the 'this' pointer for the outer class.\n                         */\n                        e1 = new DotVarExp(e.loc, e1, tcd.vthis);\n                        e1.type = tcd.vthis.type;\n                        e1.type = e1.type.addMod(t.mod);\n                        // Do not call ensureStaticLinkTo()\n                        //e1 = e1.expressionSemantic(sc);\n\n                        // Skip up over nested functions, and get the enclosing\n                        // class type.\n                        int n = 0;\n                        for (s = tcd.toParent(); s && s.isFuncDeclaration(); s = s.toParent())\n                        {\n                            FuncDeclaration f = s.isFuncDeclaration();\n                            if (f.vthis)\n                            {\n                                //printf(\"rewriting e1 to %s's this\\n\", f.toChars());\n                                n++;\n                                e1 = new VarExp(e.loc, f.vthis);\n                            }\n                            else\n                            {\n                                e = new VarExp(e.loc, d);\n                                result = e;\n                                return;\n                            }\n                        }\n                        if (s && s.isClassDeclaration())\n                        {\n                            e1.type = s.isClassDeclaration().type;\n                            e1.type = e1.type.addMod(t.mod);\n                            if (n > 1)\n                                e1 = e1.expressionSemantic(sc);\n                        }\n                        else\n                            e1 = e1.expressionSemantic(sc);\n                        goto L2;\n                    }\n                }\n            }\n            //printf(\"e = %s, d = %s\\n\", e.toChars(), d.toChars());\n            if (d.semanticRun == PASS.init)\n                d.dsymbolSemantic(null);\n\n            // If static function, get the most visible overload.\n            // Later on the call is checked for correctness.\n            // https://issues.dlang.org/show_bug.cgi?id=12511\n            if (auto fd = d.isFuncDeclaration())\n            {\n                import dmd.access : mostVisibleOverload;\n                d = cast(Declaration)mostVisibleOverload(fd, sc._module);\n            }\n\n            checkAccess(e.loc, sc, e, d);\n            auto ve = new VarExp(e.loc, d);\n            if (d.isVarDeclaration() && d.needThis())\n                ve.type = d.type.addMod(e.type.mod);\n            result = ve;\n            return;\n        }\n\n        bool unreal = e.op == TOK.variable && (cast(VarExp)e).var.isField();\n        if (d.isDataseg() || unreal && d.isField())\n        {\n            // (e, d)\n            checkAccess(e.loc, sc, e, d);\n            Expression ve = new VarExp(e.loc, d);\n            e = unreal ? ve : new CommaExp(e.loc, e, ve);\n            e = e.expressionSemantic(sc);\n            result = e;\n            return;\n        }\n\n        e = new DotVarExp(e.loc, e, d);\n        e = e.expressionSemantic(sc);\n        result = e;\n    }\n}\n\n\n/************************\n * Get the the default initialization expression for a type.\n * Params:\n *  mt = the type for which the init expression is returned\n *  loc = the location where the expression needs to be evaluated\n *\n * Returns:\n *  The initialization expression for the type.\n */\nExpression defaultInit(Type mt, const ref Loc loc)\n{\n    scope v = new DefaultInitVisitor(loc);\n    mt.accept(v);\n    return v.result;\n}\n\nprivate extern(C++) final class DefaultInitVisitor : Visitor\n{\n    alias visit = typeof(super).visit;\n    const Loc loc;\n    Expression result;\n\n    this(const ref Loc loc)\n    {\n        this.loc = loc;\n    }\n\n    override void visit(Type mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"Type::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        result = null;\n    }\n\n    override void visit(TypeError mt)\n    {\n        result = new ErrorExp();\n    }\n\n    override void visit(TypeBasic mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeBasic::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        dinteger_t value = 0;\n\n        switch (mt.ty)\n        {\n        case Tchar:\n            value = 0xFF;\n            break;\n\n        case Twchar:\n        case Tdchar:\n            value = 0xFFFF;\n            break;\n\n        case Timaginary32:\n        case Timaginary64:\n        case Timaginary80:\n        case Tfloat32:\n        case Tfloat64:\n        case Tfloat80:\n            result = new RealExp(loc, Target.RealProperties.snan, mt);\n            return;\n\n        case Tcomplex32:\n        case Tcomplex64:\n        case Tcomplex80:\n            {\n                // Can't use fvalue + I*fvalue (the im part becomes a quiet NaN).\n                const cvalue = complex_t(Target.RealProperties.snan, Target.RealProperties.snan);\n                result = new ComplexExp(loc, cvalue, mt);\n                return;\n            }\n\n        case Tvoid:\n            error(loc, \"`void` does not have a default initializer\");\n            result = new ErrorExp();\n            return;\n\n        default:\n            break;\n        }\n        result = new IntegerExp(loc, value, mt);\n    }\n\n    override void visit(TypeVector mt)\n    {\n        //printf(\"TypeVector::defaultInit()\\n\");\n        assert(mt.basetype.ty == Tsarray);\n        Expression e = mt.basetype.defaultInit(loc);\n        auto ve = new VectorExp(loc, e, mt);\n        ve.type = mt;\n        ve.dim = cast(int)(mt.basetype.size(loc) / mt.elementType().size(loc));\n        result = ve;\n    }\n\n    override void visit(TypeSArray mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeSArray::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        if (mt.next.ty == Tvoid)\n            result = mt.tuns8.defaultInit(loc);\n        else\n            result = mt.next.defaultInit(loc);\n    }\n\n    override void visit(TypeDArray mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeDArray::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        result = new NullExp(loc, mt);\n    }\n\n    override void visit(TypeAArray mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeAArray::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        result = new NullExp(loc, mt);\n    }\n\n    override void visit(TypePointer mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypePointer::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        result = new NullExp(loc, mt);\n    }\n\n    override void visit(TypeReference mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeReference::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        result = new NullExp(loc, mt);\n    }\n\n    override void visit(TypeFunction mt)\n    {\n        error(loc, \"`function` does not have a default initializer\");\n        result = new ErrorExp();\n    }\n\n    override void visit(TypeDelegate mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeDelegate::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        result = new NullExp(loc, mt);\n    }\n\n    override void visit(TypeStruct mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeStruct::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        Declaration d = new SymbolDeclaration(mt.sym.loc, mt.sym);\n        assert(d);\n        d.type = mt;\n        d.storage_class |= STC.rvalue; // https://issues.dlang.org/show_bug.cgi?id=14398\n        result = new VarExp(mt.sym.loc, d);\n    }\n\n    override void visit(TypeEnum mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeEnum::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        // Initialize to first member of enum\n        Expression e = mt.sym.getDefaultValue(loc);\n        e = e.copy();\n        e.loc = loc;\n        e.type = mt; // to deal with const, immutable, etc., variants\n        result = e;\n    }\n\n    override void visit(TypeClass mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeClass::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        result = new NullExp(loc, mt);\n    }\n\n    override void visit(TypeTuple mt)\n    {\n        static if (LOGDEFAULTINIT)\n        {\n            printf(\"TypeTuple::defaultInit() '%s'\\n\", mt.toChars());\n        }\n        auto exps = new Expressions(mt.arguments.dim);\n        for (size_t i = 0; i < mt.arguments.dim; i++)\n        {\n            Parameter p = (*mt.arguments)[i];\n            assert(p.type);\n            Expression e = p.type.defaultInitLiteral(loc);\n            if (e.op == TOK.error)\n            {\n                result = e;\n                return;\n            }\n            (*exps)[i] = e;\n        }\n        result = new TupleExp(loc, exps);\n    }\n\n    override void visit(TypeNull mt)\n    {\n        result = new NullExp(Loc.initial, Type.tnull);\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/typinf.d",
    "content": "/* typinf.d -- D runtime type identification\n * Copyright (C) 2018 Free Software Foundation, Inc.\n *\n * GCC is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3, or (at your option)\n * any later version.\n *\n * GCC is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with GCC; see the file COPYING3.  If not see\n * <http://www.gnu.org/licenses/>.\n */\n\nmodule dmd.typinf;\n\nimport dmd.dscope;\nimport dmd.globals;\nimport dmd.mtype;\n\n/****************************************************\n * Gets the type of the `TypeInfo` object associated with `t`\n * Params:\n *      loc = the location for reporting line nunbers in errors\n *      t   = the type to get the type of the `TypeInfo` object for\n *      sc  = the scope\n * Returns:\n *      The type of the `TypeInfo` object associated with `t`\n */\nextern (C++) Type getTypeInfoType(Loc loc, Type t, Scope* sc);\n\n"
  },
  {
    "path": "gcc/d/dmd/utf.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/utf.d, _utf.d)\n * Documentation:  https://dlang.org/phobos/dmd_utf.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/utf.d\n */\n\nmodule dmd.utf;\n\nnothrow pure @nogc:\n\n/// The Unicode code space is the range of code points [0x000000,0x10FFFF]\n/// except the UTF-16 surrogate pairs in the range [0xD800,0xDFFF]\nbool utf_isValidDchar(dchar c)\n{\n    // TODO: Whether non-char code points should be rejected is pending review.\n    // 0xFFFE and 0xFFFF are valid for internal use, like Phobos std.utf.isValidDChar\n    // See also https://issues.dlang.org/show_bug.cgi?id=1357\n    if (c < 0xD800) // Almost all characters in a typical document.\n        return true;\n    if (c > 0xDFFF && c <= 0x10FFFF)\n        return true;\n    return false;\n}\n\n/*******************************\n * Return !=0 if unicode alpha.\n * Use table from C99 Appendix D.\n */\nbool isUniAlpha(dchar c)\n{\n    static immutable wchar[2][] ALPHA_TABLE =\n    [\n        [0x00AA, 0x00AA],\n        [0x00B5, 0x00B5],\n        [0x00B7, 0x00B7],\n        [0x00BA, 0x00BA],\n        [0x00C0, 0x00D6],\n        [0x00D8, 0x00F6],\n        [0x00F8, 0x01F5],\n        [0x01FA, 0x0217],\n        [0x0250, 0x02A8],\n        [0x02B0, 0x02B8],\n        [0x02BB, 0x02BB],\n        [0x02BD, 0x02C1],\n        [0x02D0, 0x02D1],\n        [0x02E0, 0x02E4],\n        [0x037A, 0x037A],\n        [0x0386, 0x0386],\n        [0x0388, 0x038A],\n        [0x038C, 0x038C],\n        [0x038E, 0x03A1],\n        [0x03A3, 0x03CE],\n        [0x03D0, 0x03D6],\n        [0x03DA, 0x03DA],\n        [0x03DC, 0x03DC],\n        [0x03DE, 0x03DE],\n        [0x03E0, 0x03E0],\n        [0x03E2, 0x03F3],\n        [0x0401, 0x040C],\n        [0x040E, 0x044F],\n        [0x0451, 0x045C],\n        [0x045E, 0x0481],\n        [0x0490, 0x04C4],\n        [0x04C7, 0x04C8],\n        [0x04CB, 0x04CC],\n        [0x04D0, 0x04EB],\n        [0x04EE, 0x04F5],\n        [0x04F8, 0x04F9],\n        [0x0531, 0x0556],\n        [0x0559, 0x0559],\n        [0x0561, 0x0587],\n        [0x05B0, 0x05B9],\n        [0x05BB, 0x05BD],\n        [0x05BF, 0x05BF],\n        [0x05C1, 0x05C2],\n        [0x05D0, 0x05EA],\n        [0x05F0, 0x05F2],\n        [0x0621, 0x063A],\n        [0x0640, 0x0652],\n        [0x0660, 0x0669],\n        [0x0670, 0x06B7],\n        [0x06BA, 0x06BE],\n        [0x06C0, 0x06CE],\n        [0x06D0, 0x06DC],\n        [0x06E5, 0x06E8],\n        [0x06EA, 0x06ED],\n        [0x06F0, 0x06F9],\n        [0x0901, 0x0903],\n        [0x0905, 0x0939],\n        [0x093D, 0x094D],\n        [0x0950, 0x0952],\n        [0x0958, 0x0963],\n        [0x0966, 0x096F],\n        [0x0981, 0x0983],\n        [0x0985, 0x098C],\n        [0x098F, 0x0990],\n        [0x0993, 0x09A8],\n        [0x09AA, 0x09B0],\n        [0x09B2, 0x09B2],\n        [0x09B6, 0x09B9],\n        [0x09BE, 0x09C4],\n        [0x09C7, 0x09C8],\n        [0x09CB, 0x09CD],\n        [0x09DC, 0x09DD],\n        [0x09DF, 0x09E3],\n        [0x09E6, 0x09F1],\n        [0x0A02, 0x0A02],\n        [0x0A05, 0x0A0A],\n        [0x0A0F, 0x0A10],\n        [0x0A13, 0x0A28],\n        [0x0A2A, 0x0A30],\n        [0x0A32, 0x0A33],\n        [0x0A35, 0x0A36],\n        [0x0A38, 0x0A39],\n        [0x0A3E, 0x0A42],\n        [0x0A47, 0x0A48],\n        [0x0A4B, 0x0A4D],\n        [0x0A59, 0x0A5C],\n        [0x0A5E, 0x0A5E],\n        [0x0A66, 0x0A6F],\n        [0x0A74, 0x0A74],\n        [0x0A81, 0x0A83],\n        [0x0A85, 0x0A8B],\n        [0x0A8D, 0x0A8D],\n        [0x0A8F, 0x0A91],\n        [0x0A93, 0x0AA8],\n        [0x0AAA, 0x0AB0],\n        [0x0AB2, 0x0AB3],\n        [0x0AB5, 0x0AB9],\n        [0x0ABD, 0x0AC5],\n        [0x0AC7, 0x0AC9],\n        [0x0ACB, 0x0ACD],\n        [0x0AD0, 0x0AD0],\n        [0x0AE0, 0x0AE0],\n        [0x0AE6, 0x0AEF],\n        [0x0B01, 0x0B03],\n        [0x0B05, 0x0B0C],\n        [0x0B0F, 0x0B10],\n        [0x0B13, 0x0B28],\n        [0x0B2A, 0x0B30],\n        [0x0B32, 0x0B33],\n        [0x0B36, 0x0B39],\n        [0x0B3D, 0x0B43],\n        [0x0B47, 0x0B48],\n        [0x0B4B, 0x0B4D],\n        [0x0B5C, 0x0B5D],\n        [0x0B5F, 0x0B61],\n        [0x0B66, 0x0B6F],\n        [0x0B82, 0x0B83],\n        [0x0B85, 0x0B8A],\n        [0x0B8E, 0x0B90],\n        [0x0B92, 0x0B95],\n        [0x0B99, 0x0B9A],\n        [0x0B9C, 0x0B9C],\n        [0x0B9E, 0x0B9F],\n        [0x0BA3, 0x0BA4],\n        [0x0BA8, 0x0BAA],\n        [0x0BAE, 0x0BB5],\n        [0x0BB7, 0x0BB9],\n        [0x0BBE, 0x0BC2],\n        [0x0BC6, 0x0BC8],\n        [0x0BCA, 0x0BCD],\n        [0x0BE7, 0x0BEF],\n        [0x0C01, 0x0C03],\n        [0x0C05, 0x0C0C],\n        [0x0C0E, 0x0C10],\n        [0x0C12, 0x0C28],\n        [0x0C2A, 0x0C33],\n        [0x0C35, 0x0C39],\n        [0x0C3E, 0x0C44],\n        [0x0C46, 0x0C48],\n        [0x0C4A, 0x0C4D],\n        [0x0C60, 0x0C61],\n        [0x0C66, 0x0C6F],\n        [0x0C82, 0x0C83],\n        [0x0C85, 0x0C8C],\n        [0x0C8E, 0x0C90],\n        [0x0C92, 0x0CA8],\n        [0x0CAA, 0x0CB3],\n        [0x0CB5, 0x0CB9],\n        [0x0CBE, 0x0CC4],\n        [0x0CC6, 0x0CC8],\n        [0x0CCA, 0x0CCD],\n        [0x0CDE, 0x0CDE],\n        [0x0CE0, 0x0CE1],\n        [0x0CE6, 0x0CEF],\n        [0x0D02, 0x0D03],\n        [0x0D05, 0x0D0C],\n        [0x0D0E, 0x0D10],\n        [0x0D12, 0x0D28],\n        [0x0D2A, 0x0D39],\n        [0x0D3E, 0x0D43],\n        [0x0D46, 0x0D48],\n        [0x0D4A, 0x0D4D],\n        [0x0D60, 0x0D61],\n        [0x0D66, 0x0D6F],\n        [0x0E01, 0x0E3A],\n        [0x0E40, 0x0E5B],\n        [0x0E81, 0x0E82],\n        [0x0E84, 0x0E84],\n        [0x0E87, 0x0E88],\n        [0x0E8A, 0x0E8A],\n        [0x0E8D, 0x0E8D],\n        [0x0E94, 0x0E97],\n        [0x0E99, 0x0E9F],\n        [0x0EA1, 0x0EA3],\n        [0x0EA5, 0x0EA5],\n        [0x0EA7, 0x0EA7],\n        [0x0EAA, 0x0EAB],\n        [0x0EAD, 0x0EAE],\n        [0x0EB0, 0x0EB9],\n        [0x0EBB, 0x0EBD],\n        [0x0EC0, 0x0EC4],\n        [0x0EC6, 0x0EC6],\n        [0x0EC8, 0x0ECD],\n        [0x0ED0, 0x0ED9],\n        [0x0EDC, 0x0EDD],\n        [0x0F00, 0x0F00],\n        [0x0F18, 0x0F19],\n        [0x0F20, 0x0F33],\n        [0x0F35, 0x0F35],\n        [0x0F37, 0x0F37],\n        [0x0F39, 0x0F39],\n        [0x0F3E, 0x0F47],\n        [0x0F49, 0x0F69],\n        [0x0F71, 0x0F84],\n        [0x0F86, 0x0F8B],\n        [0x0F90, 0x0F95],\n        [0x0F97, 0x0F97],\n        [0x0F99, 0x0FAD],\n        [0x0FB1, 0x0FB7],\n        [0x0FB9, 0x0FB9],\n        [0x10A0, 0x10C5],\n        [0x10D0, 0x10F6],\n        [0x1E00, 0x1E9B],\n        [0x1EA0, 0x1EF9],\n        [0x1F00, 0x1F15],\n        [0x1F18, 0x1F1D],\n        [0x1F20, 0x1F45],\n        [0x1F48, 0x1F4D],\n        [0x1F50, 0x1F57],\n        [0x1F59, 0x1F59],\n        [0x1F5B, 0x1F5B],\n        [0x1F5D, 0x1F5D],\n        [0x1F5F, 0x1F7D],\n        [0x1F80, 0x1FB4],\n        [0x1FB6, 0x1FBC],\n        [0x1FBE, 0x1FBE],\n        [0x1FC2, 0x1FC4],\n        [0x1FC6, 0x1FCC],\n        [0x1FD0, 0x1FD3],\n        [0x1FD6, 0x1FDB],\n        [0x1FE0, 0x1FEC],\n        [0x1FF2, 0x1FF4],\n        [0x1FF6, 0x1FFC],\n        [0x203F, 0x2040],\n        [0x207F, 0x207F],\n        [0x2102, 0x2102],\n        [0x2107, 0x2107],\n        [0x210A, 0x2113],\n        [0x2115, 0x2115],\n        [0x2118, 0x211D],\n        [0x2124, 0x2124],\n        [0x2126, 0x2126],\n        [0x2128, 0x2128],\n        [0x212A, 0x2131],\n        [0x2133, 0x2138],\n        [0x2160, 0x2182],\n        [0x3005, 0x3007],\n        [0x3021, 0x3029],\n        [0x3041, 0x3093],\n        [0x309B, 0x309C],\n        [0x30A1, 0x30F6],\n        [0x30FB, 0x30FC],\n        [0x3105, 0x312C],\n        [0x4E00, 0x9FA5],\n        [0xAC00, 0xD7A3]\n    ];\n\n    size_t high = ALPHA_TABLE.length - 1;\n    // Shortcut search if c is out of range\n    size_t low = (c < ALPHA_TABLE[0][0] || ALPHA_TABLE[high][1] < c) ? high + 1 : 0;\n    // Binary search\n    while (low <= high)\n    {\n        size_t mid = (low + high) >> 1;\n        if (c < ALPHA_TABLE[mid][0])\n            high = mid - 1;\n        else if (ALPHA_TABLE[mid][1] < c)\n            low = mid + 1;\n        else\n        {\n            assert(ALPHA_TABLE[mid][0] <= c && c <= ALPHA_TABLE[mid][1]);\n            return true;\n        }\n    }\n    return false;\n}\n\n/**\n * Returns the code length of c in code units.\n */\nint utf_codeLengthChar(dchar c)\n{\n    if (c <= 0x7F)\n        return 1;\n    if (c <= 0x7FF)\n        return 2;\n    if (c <= 0xFFFF)\n        return 3;\n    if (c <= 0x10FFFF)\n        return 4;\n    assert(false);\n}\n\nint utf_codeLengthWchar(dchar c)\n{\n    return c <= 0xFFFF ? 1 : 2;\n}\n\n/**\n * Returns the code length of c in code units for the encoding.\n * sz is the encoding: 1 = utf8, 2 = utf16, 4 = utf32.\n */\nint utf_codeLength(int sz, dchar c)\n{\n    if (sz == 1)\n        return utf_codeLengthChar(c);\n    if (sz == 2)\n        return utf_codeLengthWchar(c);\n    assert(sz == 4);\n    return 1;\n}\n\nvoid utf_encodeChar(char* s, dchar c)\n{\n    assert(s !is null);\n    assert(utf_isValidDchar(c));\n    if (c <= 0x7F)\n    {\n        s[0] = cast(char)c;\n    }\n    else if (c <= 0x07FF)\n    {\n        s[0] = cast(char)(0xC0 | (c >> 6));\n        s[1] = cast(char)(0x80 | (c & 0x3F));\n    }\n    else if (c <= 0xFFFF)\n    {\n        s[0] = cast(char)(0xE0 | (c >> 12));\n        s[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n        s[2] = cast(char)(0x80 | (c & 0x3F));\n    }\n    else if (c <= 0x10FFFF)\n    {\n        s[0] = cast(char)(0xF0 | (c >> 18));\n        s[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));\n        s[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n        s[3] = cast(char)(0x80 | (c & 0x3F));\n    }\n    else\n        assert(0);\n}\n\nvoid utf_encodeWchar(wchar* s, dchar c)\n{\n    assert(s !is null);\n    assert(utf_isValidDchar(c));\n    if (c <= 0xFFFF)\n    {\n        s[0] = cast(wchar)c;\n    }\n    else\n    {\n        s[0] = cast(wchar)((((c - 0x010000) >> 10) & 0x03FF) + 0xD800);\n        s[1] = cast(wchar)(((c - 0x010000) & 0x03FF) + 0xDC00);\n    }\n}\n\nvoid utf_encode(int sz, void* s, dchar c)\n{\n    if (sz == 1)\n        utf_encodeChar(cast(char*)s, c);\n    else if (sz == 2)\n        utf_encodeWchar(cast(wchar*)s, c);\n    else\n    {\n        assert(sz == 4);\n        *(cast(dchar*)s) = c;\n    }\n}\n\n/********************************************\n * Decode a UTF-8 sequence as a single UTF-32 code point.\n * Params:\n *      s = UTF-8 sequence\n *      len = number of code units in s[]\n *      ridx = starting index in s[], updated to reflect number of code units decoded\n *      rresult = set to character decoded\n * Returns:\n *      null on success, otherwise error message string\n */\nimmutable(char*) utf_decodeChar(const(char)* s, size_t len, ref size_t ridx, out dchar rresult)\n{\n    // UTF-8 decoding errors\n    static immutable char* UTF8_DECODE_OK = null; // no error\n    static immutable char* UTF8_DECODE_OUTSIDE_CODE_SPACE = \"Outside Unicode code space\";\n    static immutable char* UTF8_DECODE_TRUNCATED_SEQUENCE = \"Truncated UTF-8 sequence\";\n    static immutable char* UTF8_DECODE_OVERLONG = \"Overlong UTF-8 sequence\";\n    static immutable char* UTF8_DECODE_INVALID_TRAILER = \"Invalid trailing code unit\";\n    static immutable char* UTF8_DECODE_INVALID_CODE_POINT = \"Invalid code point decoded\";\n\n    /* The following encodings are valid, except for the 5 and 6 byte\n     * combinations:\n     *      0xxxxxxx\n     *      110xxxxx 10xxxxxx\n     *      1110xxxx 10xxxxxx 10xxxxxx\n     *      11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n     *      111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n     *      1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n     */\n    static immutable uint[] UTF8_STRIDE =\n    [\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        1,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        0xFF,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        2,\n        3,\n        3,\n        3,\n        3,\n        3,\n        3,\n        3,\n        3,\n        3,\n        3,\n        3,\n        3,\n        3,\n        3,\n        3,\n        3,\n        4,\n        4,\n        4,\n        4,\n        4,\n        4,\n        4,\n        4,\n        5,\n        5,\n        5,\n        5,\n        6,\n        6,\n        0xFF,\n        0xFF\n    ];\n\n    assert(s !is null);\n    size_t i = ridx++;\n    assert(i < len);\n    char u = s[i];\n    // Pre-stage results for ASCII and error cases\n    rresult = u;\n    //printf(\"utf_decodeChar(s = %02x, %02x, %02x len = %d)\\n\", u, s[1], s[2], len);\n    // Get expected sequence length\n    size_t n = UTF8_STRIDE[u];\n    switch (n)\n    {\n    case 1:\n        // ASCII\n        return UTF8_DECODE_OK;\n    case 2:\n    case 3:\n    case 4:\n        // multi-byte UTF-8\n        break;\n    default:\n        // 5- or 6-byte sequence\n        return UTF8_DECODE_OUTSIDE_CODE_SPACE;\n    }\n    if (len < i + n) // source too short\n        return UTF8_DECODE_TRUNCATED_SEQUENCE;\n    // Pick off 7 - n low bits from first code unit\n    dchar c = u & ((1 << (7 - n)) - 1);\n    /* The following combinations are overlong, and illegal:\n     *      1100000x (10xxxxxx)\n     *      11100000 100xxxxx (10xxxxxx)\n     *      11110000 1000xxxx (10xxxxxx 10xxxxxx)\n     *      11111000 10000xxx (10xxxxxx 10xxxxxx 10xxxxxx)\n     *      11111100 100000xx (10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx)\n     */\n    char u2 = s[++i];\n    // overlong combination\n    if ((u & 0xFE) == 0xC0 || (u == 0xE0 && (u2 & 0xE0) == 0x80) || (u == 0xF0 && (u2 & 0xF0) == 0x80) || (u == 0xF8 && (u2 & 0xF8) == 0x80) || (u == 0xFC && (u2 & 0xFC) == 0x80))\n        return UTF8_DECODE_OVERLONG;\n    // Decode remaining bits\n    for (n += i - 1; i != n; ++i)\n    {\n        u = s[i];\n        if ((u & 0xC0) != 0x80) // trailing bytes are 10xxxxxx\n            return UTF8_DECODE_INVALID_TRAILER;\n        c = (c << 6) | (u & 0x3F);\n    }\n    if (!utf_isValidDchar(c))\n        return UTF8_DECODE_INVALID_CODE_POINT;\n    ridx = i;\n    rresult = c;\n    return UTF8_DECODE_OK;\n}\n\n/********************************************\n * Decode a UTF-16 sequence as a single UTF-32 code point.\n * Params:\n *      s = UTF-16 sequence\n *      len = number of code units in s[]\n *      ridx = starting index in s[], updated to reflect number of code units decoded\n *      rresult = set to character decoded\n * Returns:\n *      null on success, otherwise error message string\n */\nimmutable(char*) utf_decodeWchar(const(wchar)* s, size_t len, ref size_t ridx, out dchar rresult)\n{\n    // UTF-16 decoding errors\n    static immutable char* UTF16_DECODE_OK = null; // no error\n    static immutable char* UTF16_DECODE_TRUNCATED_SEQUENCE = \"Truncated UTF-16 sequence\";\n    static immutable char* UTF16_DECODE_INVALID_SURROGATE = \"Invalid low surrogate\";\n    static immutable char* UTF16_DECODE_UNPAIRED_SURROGATE = \"Unpaired surrogate\";\n    static immutable char* UTF16_DECODE_INVALID_CODE_POINT = \"Invalid code point decoded\";\n\n    assert(s !is null);\n    size_t i = ridx++;\n    assert(i < len);\n    // Pre-stage results for ASCII and error cases\n    dchar u = rresult = s[i];\n    if (u < 0x80) // ASCII\n        return UTF16_DECODE_OK;\n    if (0xD800 <= u && u <= 0xDBFF) // Surrogate pair\n    {\n        if (len <= i + 1)\n            return UTF16_DECODE_TRUNCATED_SEQUENCE;\n        wchar u2 = s[i + 1];\n        if (u2 < 0xDC00 || 0xDFFF < u)\n            return UTF16_DECODE_INVALID_SURROGATE;\n        u = ((u - 0xD7C0) << 10) + (u2 - 0xDC00);\n        ++ridx;\n    }\n    else if (0xDC00 <= u && u <= 0xDFFF)\n        return UTF16_DECODE_UNPAIRED_SURROGATE;\n    if (!utf_isValidDchar(u))\n        return UTF16_DECODE_INVALID_CODE_POINT;\n    rresult = u;\n    return UTF16_DECODE_OK;\n}\n"
  },
  {
    "path": "gcc/d/dmd/utils.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n * Utility functions for DMD.\n *\n * This modules defines some utility functions for DMD.\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/utils.d, _utils.d)\n * Documentation:  https://dlang.org/phobos/dmd_utils.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/utils.d\n */\n\nmodule dmd.utils;\n\nimport core.stdc.string;\nimport dmd.errors;\nimport dmd.globals;\nimport dmd.root.file;\nimport dmd.root.filename;\nimport dmd.root.outbuffer;\nimport dmd.root.rmem;\n\n\n/**\n * Normalize path by turning forward slashes into backslashes\n *\n * Params:\n *   src = Source path, using unix-style ('/') path separators\n *\n * Returns:\n *   A newly-allocated string with '/' turned into backslashes\n */\nconst(char)* toWinPath(const(char)* src)\n{\n    if (src is null)\n        return null;\n    char* result = strdup(src);\n    char* p = result;\n    while (*p != '\\0')\n    {\n        if (*p == '/')\n            *p = '\\\\';\n        p++;\n    }\n    return result;\n}\n\n\n/**\n * Reads a file, terminate the program on error\n *\n * Params:\n *   loc = The line number information from where the call originates\n *   f = a `dmd.root.file.File` handle to read\n */\nextern (C++) void readFile(Loc loc, File* f)\n{\n    if (f.read())\n    {\n        error(loc, \"Error reading file '%s'\", f.name.toChars());\n        fatal();\n    }\n}\n\n\n/**\n * Writes a file, terminate the program on error\n *\n * Params:\n *   loc = The line number information from where the call originates\n *   f = a `dmd.root.file.File` handle to write\n */\nextern (C++) void writeFile(Loc loc, File* f)\n{\n    if (f.write())\n    {\n        error(loc, \"Error writing file '%s'\", f.name.toChars());\n        fatal();\n    }\n}\n\n\n/**\n * Ensure the root path (the path minus the name) of the provided path\n * exists, and terminate the process if it doesn't.\n *\n * Params:\n *   loc = The line number information from where the call originates\n *   name = a path to check (the name is stripped)\n */\nextern (C++) void ensurePathToNameExists(Loc loc, const(char)* name)\n{\n    const(char)* pt = FileName.path(name);\n    if (*pt)\n    {\n        if (!FileName.ensurePathExists(pt))\n        {\n            error(loc, \"cannot create directory %s\", pt);\n            fatal();\n        }\n    }\n    FileName.free(pt);\n}\n\n\n/**\n * Takes a path, and escapes '(', ')' and backslashes\n *\n * Params:\n *   buf = Buffer to write the escaped path to\n *   fname = Path to escape\n */\nextern (C++) void escapePath(OutBuffer* buf, const(char)* fname)\n{\n    while (1)\n    {\n        switch (*fname)\n        {\n        case 0:\n            return;\n        case '(':\n        case ')':\n        case '\\\\':\n            buf.writeByte('\\\\');\n            goto default;\n        default:\n            buf.writeByte(*fname);\n            break;\n        }\n        fname++;\n    }\n}\n\n/// Slices a `\\0`-terminated C-string, excluding the terminator\ninout(char)[] toDString (inout(char)* s) pure nothrow @nogc\n{\n    return s ? s[0 .. strlen(s)] : null;\n}\n\n/**\nCompare two slices for equality, in a case-insensitive way\n\nComparison is based on `char` and does not do decoding.\nAs a result, it's only really accurate for plain ASCII strings.\n\nParams:\ns1 = string to compare\ns2 = string to compare\n\nReturns:\n`true` if `s1 == s2` regardless of case\n*/\nextern(D) static bool iequals(const(char)[] s1, const(char)[] s2)\n{\n    import core.stdc.ctype : toupper;\n\n    if (s1.length != s2.length)\n        return false;\n\n    int result = 0;\n    foreach (idx, c1; s1)\n    {\n        // Since we did a length check, it is safe to bypass bounds checking\n        const c2 = s2.ptr[idx];\n        if (c1 != c2)\n            if (toupper(c1) != toupper(c2))\n                return false;\n    }\n    return true;\n}\n\n/**\nCopy the content of `src` into a C-string ('\\0' terminated) then call `dg`\n\nThe intent of this function is to provide an allocation-less\nway to call a C function using a D slice.\nThe function internally allocates a buffer if needed, but frees it on exit.\n\nNote:\nThe argument to `dg` is `scope`. To keep the data around after `dg` exits,\none has to copy it.\n\nParams:\nsrc = Slice to use to call the C function\ndg  = Delegate to call afterwards\n\nReturns:\nThe return value of `T`\n*/\nauto toCStringThen(alias dg)(const(char)[] src) nothrow\n{\n    const len = src.length + 1;\n    char[512] small = void;\n    scope ptr = (src.length < (small.length - 1))\n                    ? small[0 .. len]\n                    : (cast(char*)mem.xmalloc(len))[0 .. len];\n    scope (exit)\n    {\n        if (&ptr[0] != &small[0])\n            mem.xfree(&ptr[0]);\n    }\n    ptr[0 .. src.length] = src[];\n    ptr[src.length] = '\\0';\n    return dg(ptr);\n}\n\nunittest\n{\n    assert(\"Hello world\".toCStringThen!((v) => v == \"Hello world\\0\"));\n    assert(\"Hello world\\0\".toCStringThen!((v) => v == \"Hello world\\0\\0\"));\n    assert(null.toCStringThen!((v) => v == \"\\0\"));\n}\n"
  },
  {
    "path": "gcc/d/dmd/visitor.d",
    "content": "/**\n * Compiler implementation of the\n * $(LINK2 http://www.dlang.org, D programming language).\n *\n * Copyright:   Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved\n * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)\n * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/visitor.d, _visitor.d)\n * Documentation:  https://dlang.org/phobos/dmd_visitor.html\n * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/visitor.d\n */\n\nmodule dmd.visitor;\n\nimport dmd.astcodegen;\nimport dmd.parsetimevisitor;\nimport dmd.tokens;\nimport dmd.transitivevisitor;\nimport dmd.expression;\nimport dmd.root.rootobject;\n\n/**\n * Classic Visitor class which implements visit methods for all the AST\n * nodes present in the compiler. The visit methods for AST nodes\n * created at parse time are inherited while the visiting methods\n * for AST nodes created at semantic time are implemented.\n */\nextern (C++) class Visitor : ParseTimeVisitor!ASTCodegen\n{\n    alias visit = ParseTimeVisitor!ASTCodegen.visit;\npublic:\n    void visit(ASTCodegen.ErrorStatement s) { visit(cast(ASTCodegen.Statement)s); }\n    void visit(ASTCodegen.PeelStatement s) { visit(cast(ASTCodegen.Statement)s); }\n    void visit(ASTCodegen.UnrolledLoopStatement s) { visit(cast(ASTCodegen.Statement)s); }\n    void visit(ASTCodegen.SwitchErrorStatement s) { visit(cast(ASTCodegen.Statement)s); }\n    void visit(ASTCodegen.DebugStatement s) { visit(cast(ASTCodegen.Statement)s); }\n    void visit(ASTCodegen.DtorExpStatement s) { visit(cast(ASTCodegen.ExpStatement)s); }\n    void visit(ASTCodegen.ForwardingStatement s) { visit(cast(ASTCodegen.Statement)s); }\n    void visit(ASTCodegen.OverloadSet s) { visit(cast(ASTCodegen.Dsymbol)s); }\n    void visit(ASTCodegen.LabelDsymbol s) { visit(cast(ASTCodegen.Dsymbol)s); }\n    void visit(ASTCodegen.WithScopeSymbol s) { visit(cast(ASTCodegen.ScopeDsymbol)s); }\n    void visit(ASTCodegen.ArrayScopeSymbol s) { visit(cast(ASTCodegen.ScopeDsymbol)s); }\n    void visit(ASTCodegen.OverDeclaration s) { visit(cast(ASTCodegen.Declaration)s); }\n    void visit(ASTCodegen.SymbolDeclaration s) { visit(cast(ASTCodegen.Declaration)s); }\n    void visit(ASTCodegen.ThisDeclaration s) { visit(cast(ASTCodegen.VarDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoDeclaration s) { visit(cast(ASTCodegen.VarDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoStructDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoClassDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoInterfaceDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoPointerDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoArrayDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoStaticArrayDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoAssociativeArrayDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoEnumDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoFunctionDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoDelegateDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoTupleDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoConstDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoInvariantDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoSharedDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoWildDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.TypeInfoVectorDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }\n    void visit(ASTCodegen.FuncAliasDeclaration s) { visit(cast(ASTCodegen.FuncDeclaration)s); }\n    void visit(ASTCodegen.ErrorInitializer i) { visit(cast(ASTCodegen.Initializer)i); }\n    void visit(ASTCodegen.ErrorExp e) { visit(cast(ASTCodegen.Expression)e); }\n    void visit(ASTCodegen.ComplexExp e) { visit(cast(ASTCodegen.Expression)e); }\n    void visit(ASTCodegen.StructLiteralExp e) { visit(cast(ASTCodegen.Expression)e); }\n    void visit(ASTCodegen.ObjcClassReferenceExp e) { visit(cast(ASTCodegen.Expression)e); }\n    void visit(ASTCodegen.SymOffExp e) { visit(cast(ASTCodegen.SymbolExp)e); }\n    void visit(ASTCodegen.OverExp e) { visit(cast(ASTCodegen.Expression)e); }\n    void visit(ASTCodegen.HaltExp e) { visit(cast(ASTCodegen.Expression)e); }\n    void visit(ASTCodegen.DotTemplateExp e) { visit(cast(ASTCodegen.UnaExp)e); }\n    void visit(ASTCodegen.DotVarExp e) { visit(cast(ASTCodegen.UnaExp)e); }\n    void visit(ASTCodegen.DelegateExp e) { visit(cast(ASTCodegen.UnaExp)e); }\n    void visit(ASTCodegen.DotTypeExp e) { visit(cast(ASTCodegen.UnaExp)e); }\n    void visit(ASTCodegen.VectorExp e) { visit(cast(ASTCodegen.UnaExp)e); }\n    void visit(ASTCodegen.SliceExp e) { visit(cast(ASTCodegen.UnaExp)e); }\n    void visit(ASTCodegen.ArrayLengthExp e) { visit(cast(ASTCodegen.UnaExp)e); }\n    void visit(ASTCodegen.DelegatePtrExp e) { visit(cast(ASTCodegen.UnaExp)e); }\n    void visit(ASTCodegen.DelegateFuncptrExp e) { visit(cast(ASTCodegen.UnaExp)e); }\n    void visit(ASTCodegen.DotExp e) { visit(cast(ASTCodegen.BinExp)e); }\n    void visit(ASTCodegen.IndexExp e) { visit(cast(ASTCodegen.BinExp)e); }\n    void visit(ASTCodegen.ConstructExp e) { visit(cast(ASTCodegen.AssignExp)e); }\n    void visit(ASTCodegen.BlitExp e) { visit(cast(ASTCodegen.AssignExp)e); }\n    void visit(ASTCodegen.RemoveExp e) { visit(cast(ASTCodegen.BinExp)e); }\n    void visit(ASTCodegen.ClassReferenceExp e) { visit(cast(ASTCodegen.Expression)e); }\n    void visit(ASTCodegen.VoidInitExp e) { visit(cast(ASTCodegen.Expression)e); }\n    void visit(ASTCodegen.ThrownExceptionExp e) { visit(cast(ASTCodegen.Expression)e); }\n}\n\n/**\n * The PermissiveVisitor overrides the root AST nodes with\n * empty visiting methods.\n */\nextern (C++) class SemanticTimePermissiveVisitor : Visitor\n{\n    alias visit = Visitor.visit;\n\n    override void visit(ASTCodegen.Dsymbol){}\n    override void visit(ASTCodegen.Parameter){}\n    override void visit(ASTCodegen.Statement){}\n    override void visit(ASTCodegen.Type){}\n    override void visit(ASTCodegen.Expression){}\n    override void visit(ASTCodegen.TemplateParameter){}\n    override void visit(ASTCodegen.Condition){}\n    override void visit(ASTCodegen.Initializer){}\n}\n\n/**\n * The TransitiveVisitor implements the AST traversal logic for all AST nodes.\n */\nextern (C++) class SemanticTimeTransitiveVisitor : SemanticTimePermissiveVisitor\n{\n    alias visit = SemanticTimePermissiveVisitor.visit;\n\n    mixin ParseVisitMethods!ASTCodegen __methods;\n    alias visit = __methods.visit;\n\n    override void visit(ASTCodegen.PeelStatement s)\n    {\n        if (s.s)\n            s.s.accept(this);\n    }\n\n    override void visit(ASTCodegen.UnrolledLoopStatement s)\n    {\n        foreach(sx; *s.statements)\n        {\n            if (sx)\n                sx.accept(this);\n        }\n    }\n\n    override void visit(ASTCodegen.DebugStatement s)\n    {\n        if (s.statement)\n            s.statement.accept(this);\n    }\n\n    override void visit(ASTCodegen.ForwardingStatement s)\n    {\n        if (s.statement)\n            s.statement.accept(this);\n    }\n\n    override void visit(ASTCodegen.StructLiteralExp e)\n    {\n        // CTFE can generate struct literals that contain an AddrExp pointing to themselves,\n        // need to avoid infinite recursion.\n        if (!(e.stageflags & stageToCBuffer))\n        {\n            int old = e.stageflags;\n            e.stageflags |= stageToCBuffer;\n            foreach (el; *e.elements)\n                if (el)\n                    el.accept(this);\n            e.stageflags = old;\n        }\n    }\n\n    override void visit(ASTCodegen.DotTemplateExp e)\n    {\n        e.e1.accept(this);\n    }\n\n    override void visit(ASTCodegen.DotVarExp e)\n    {\n        e.e1.accept(this);\n    }\n\n    override void visit(ASTCodegen.DelegateExp e)\n    {\n        if (!e.func.isNested())\n            e.e1.accept(this);\n    }\n\n    override void visit(ASTCodegen.DotTypeExp e)\n    {\n        e.e1.accept(this);\n    }\n\n    override void visit(ASTCodegen.VectorExp e)\n    {\n        visitType(e.to);\n        e.e1.accept(this);\n    }\n\n    override void visit(ASTCodegen.SliceExp e)\n    {\n        e.e1.accept(this);\n        if (e.upr)\n            e.upr.accept(this);\n        if (e.lwr)\n            e.lwr.accept(this);\n    }\n\n    override void visit(ASTCodegen.ArrayLengthExp e)\n    {\n        e.e1.accept(this);\n    }\n\n    override void visit(ASTCodegen.DelegatePtrExp e)\n    {\n        e.e1.accept(this);\n    }\n\n    override void visit(ASTCodegen.DelegateFuncptrExp e)\n    {\n        e.e1.accept(this);\n    }\n\n    override void visit(ASTCodegen.DotExp e)\n    {\n        e.e1.accept(this);\n        e.e2.accept(this);\n    }\n\n    override void visit(ASTCodegen.IndexExp e)\n    {\n        e.e1.accept(this);\n        e.e2.accept(this);\n    }\n\n    override void visit(ASTCodegen.RemoveExp e)\n    {\n        e.e1.accept(this);\n        e.e2.accept(this);\n    }\n}\n\nextern (C++) class StoppableVisitor : Visitor\n{\n    alias visit = Visitor.visit;\npublic:\n    bool stop;\n\n    final extern (D) this()\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/d/dmd/visitor.h",
    "content": "\n/* Compiler implementation of the D programming language\n * Copyright (C) 2013-2018 by The D Language Foundation, All Rights Reserved\n * http://www.digitalmars.com\n * Distributed under the Boost Software License, Version 1.0.\n * http://www.boost.org/LICENSE_1_0.txt\n * https://github.com/dlang/dmd/blob/master/src/dmd/visitor.h\n */\n\n#pragma once\n\n#include <assert.h>\n\nclass Statement;\nclass ErrorStatement;\nclass PeelStatement;\nclass ExpStatement;\nclass DtorExpStatement;\nclass CompileStatement;\nclass CompoundStatement;\nclass CompoundDeclarationStatement;\nclass UnrolledLoopStatement;\nclass ScopeStatement;\nclass ForwardingStatement;\nclass WhileStatement;\nclass DoStatement;\nclass ForStatement;\nclass ForeachStatement;\nclass ForeachRangeStatement;\nclass StaticForeachStatement;\nclass IfStatement;\nclass ConditionalStatement;\nclass PragmaStatement;\nclass StaticAssertStatement;\nclass SwitchStatement;\nclass CaseStatement;\nclass CaseRangeStatement;\nclass DefaultStatement;\nclass GotoDefaultStatement;\nclass GotoCaseStatement;\nclass SwitchErrorStatement;\nclass ReturnStatement;\nclass BreakStatement;\nclass ContinueStatement;\nclass SynchronizedStatement;\nclass WithStatement;\nclass TryCatchStatement;\nclass TryFinallyStatement;\nclass OnScopeStatement;\nclass ThrowStatement;\nclass DebugStatement;\nclass GotoStatement;\nclass LabelStatement;\nclass AsmStatement;\nclass InlineAsmStatement;\nclass GccAsmStatement;\nclass CompoundAsmStatement;\nclass ImportStatement;\n\nclass Type;\nclass TypeError;\nclass TypeNext;\nclass TypeBasic;\nclass TypeVector;\nclass TypeArray;\nclass TypeSArray;\nclass TypeDArray;\nclass TypeAArray;\nclass TypePointer;\nclass TypeReference;\nclass TypeFunction;\nclass TypeDelegate;\nclass TypeQualified;\nclass TypeIdentifier;\nclass TypeInstance;\nclass TypeTypeof;\nclass TypeReturn;\nclass TypeStruct;\nclass TypeEnum;\nclass TypeClass;\nclass TypeTuple;\nclass TypeSlice;\nclass TypeNull;\n\nclass Dsymbol;\n\nclass StaticAssert;\nclass DebugSymbol;\nclass VersionSymbol;\nclass EnumMember;\nclass Import;\nclass OverloadSet;\nclass LabelDsymbol;\nclass AliasThis;\n\nclass AttribDeclaration;\nclass StorageClassDeclaration;\nclass DeprecatedDeclaration;\nclass LinkDeclaration;\nclass CPPMangleDeclaration;\nclass ProtDeclaration;\nclass AlignDeclaration;\nclass AnonDeclaration;\nclass PragmaDeclaration;\nclass ConditionalDeclaration;\nclass StaticIfDeclaration;\nclass CompileDeclaration;\nclass StaticForeachDeclaration;\nclass UserAttributeDeclaration;\n\nclass ScopeDsymbol;\nclass TemplateDeclaration;\nclass TemplateInstance;\nclass TemplateMixin;\nclass EnumDeclaration;\nclass Package;\nclass Module;\nclass WithScopeSymbol;\nclass ArrayScopeSymbol;\nclass Nspace;\n\nclass AggregateDeclaration;\nclass StructDeclaration;\nclass UnionDeclaration;\nclass ClassDeclaration;\nclass InterfaceDeclaration;\n\nclass Declaration;\nclass TupleDeclaration;\nclass AliasDeclaration;\nclass OverDeclaration;\nclass VarDeclaration;\nclass SymbolDeclaration;\nclass ThisDeclaration;\n\nclass TypeInfoDeclaration;\nclass TypeInfoStructDeclaration;\nclass TypeInfoClassDeclaration;\nclass TypeInfoInterfaceDeclaration;\nclass TypeInfoPointerDeclaration;\nclass TypeInfoArrayDeclaration;\nclass TypeInfoStaticArrayDeclaration;\nclass TypeInfoAssociativeArrayDeclaration;\nclass TypeInfoEnumDeclaration;\nclass TypeInfoFunctionDeclaration;\nclass TypeInfoDelegateDeclaration;\nclass TypeInfoTupleDeclaration;\nclass TypeInfoConstDeclaration;\nclass TypeInfoInvariantDeclaration;\nclass TypeInfoSharedDeclaration;\nclass TypeInfoWildDeclaration;\nclass TypeInfoVectorDeclaration;\n\nclass FuncDeclaration;\nclass FuncAliasDeclaration;\nclass FuncLiteralDeclaration;\nclass CtorDeclaration;\nclass PostBlitDeclaration;\nclass DtorDeclaration;\nclass StaticCtorDeclaration;\nclass SharedStaticCtorDeclaration;\nclass StaticDtorDeclaration;\nclass SharedStaticDtorDeclaration;\nclass InvariantDeclaration;\nclass UnitTestDeclaration;\nclass NewDeclaration;\nclass DeleteDeclaration;\n\nclass Initializer;\nclass VoidInitializer;\nclass ErrorInitializer;\nclass StructInitializer;\nclass ArrayInitializer;\nclass ExpInitializer;\n\nclass Expression;\nclass IntegerExp;\nclass ErrorExp;\nclass RealExp;\nclass ComplexExp;\nclass IdentifierExp;\nclass DollarExp;\nclass DsymbolExp;\nclass ThisExp;\nclass SuperExp;\nclass NullExp;\nclass StringExp;\nclass TupleExp;\nclass ArrayLiteralExp;\nclass AssocArrayLiteralExp;\nclass StructLiteralExp;\nclass ObjcClassReferenceExp;\nclass TypeExp;\nclass ScopeExp;\nclass TemplateExp;\nclass NewExp;\nclass NewAnonClassExp;\nclass SymbolExp;\nclass SymOffExp;\nclass VarExp;\nclass OverExp;\nclass FuncExp;\nclass DeclarationExp;\nclass TypeidExp;\nclass TraitsExp;\nclass HaltExp;\nclass IsExp;\nclass UnaExp;\nclass BinExp;\nclass BinAssignExp;\nclass CompileExp;\nclass ImportExp;\nclass AssertExp;\nclass DotIdExp;\nclass DotTemplateExp;\nclass DotVarExp;\nclass DotTemplateInstanceExp;\nclass DelegateExp;\nclass DotTypeExp;\nclass CallExp;\nclass AddrExp;\nclass PtrExp;\nclass NegExp;\nclass UAddExp;\nclass ComExp;\nclass NotExp;\nclass DeleteExp;\nclass CastExp;\nclass VectorExp;\nclass SliceExp;\nclass ArrayLengthExp;\nclass IntervalExp;\nclass DelegatePtrExp;\nclass DelegateFuncptrExp;\nclass ArrayExp;\nclass DotExp;\nclass CommaExp;\nclass IndexExp;\nclass PostExp;\nclass PreExp;\nclass AssignExp;\nclass ConstructExp;\nclass BlitExp;\nclass AddAssignExp;\nclass MinAssignExp;\nclass MulAssignExp;\nclass DivAssignExp;\nclass ModAssignExp;\nclass AndAssignExp;\nclass OrAssignExp;\nclass XorAssignExp;\nclass PowAssignExp;\nclass ShlAssignExp;\nclass ShrAssignExp;\nclass UshrAssignExp;\nclass CatAssignExp;\nclass AddExp;\nclass MinExp;\nclass CatExp;\nclass MulExp;\nclass DivExp;\nclass ModExp;\nclass PowExp;\nclass ShlExp;\nclass ShrExp;\nclass UshrExp;\nclass AndExp;\nclass OrExp;\nclass XorExp;\nclass LogicalExp;\nclass CmpExp;\nclass InExp;\nclass RemoveExp;\nclass EqualExp;\nclass IdentityExp;\nclass CondExp;\nclass DefaultInitExp;\nclass FileInitExp;\nclass LineInitExp;\nclass ModuleInitExp;\nclass FuncInitExp;\nclass PrettyFuncInitExp;\nclass ClassReferenceExp;\nclass VoidInitExp;\nclass ThrownExceptionExp;\n\nclass TemplateParameter;\nclass TemplateTypeParameter;\nclass TemplateThisParameter;\nclass TemplateValueParameter;\nclass TemplateAliasParameter;\nclass TemplateTupleParameter;\n\nclass Condition;\nclass DVCondition;\nclass DebugCondition;\nclass VersionCondition;\nclass StaticIfCondition;\n\nclass Parameter;\n\nclass ParseTimeVisitor\n{\npublic:\n    virtual void visit(Dsymbol *) { assert(0); }\n    virtual void visit(Parameter *) { assert(0); }\n    virtual void visit(Statement *) { assert(0); }\n    virtual void visit(Type *) { assert(0); }\n    virtual void visit(Expression *) { assert(0); }\n    virtual void visit(TemplateParameter *) { assert(0); }\n    virtual void visit(Condition *) { assert(0); }\n    virtual void visit(Initializer *) { assert(0); }\n\n    // Dsymbols\n    virtual void visit(AliasThis *s) { visit((Dsymbol *)s); }\n    virtual void visit(Declaration *s) { visit((Dsymbol *)s); }\n    virtual void visit(ScopeDsymbol *s) { visit((Dsymbol *)s); }\n    virtual void visit(Import *s) { visit((Dsymbol *)s); }\n    virtual void visit(AttribDeclaration *s) { visit((Dsymbol *)s); }\n    virtual void visit(StaticAssert *s) { visit((Dsymbol *)s); }\n    virtual void visit(DebugSymbol *s) { visit((Dsymbol *)s); }\n    virtual void visit(VersionSymbol *s) { visit((Dsymbol *)s); }\n\n    // ScopeDsymbols\n    virtual void visit(Package *s) { visit((ScopeDsymbol *)s); }\n    virtual void visit(EnumDeclaration *s) { visit((ScopeDsymbol *)s); }\n    virtual void visit(AggregateDeclaration *s) { visit((ScopeDsymbol *)s); }\n    virtual void visit(TemplateDeclaration *s) { visit((ScopeDsymbol *)s); }\n    virtual void visit(TemplateInstance *s) { visit((ScopeDsymbol *)s); }\n    virtual void visit(Nspace *s) { visit((ScopeDsymbol *)s); }\n\n    // Declarations\n    virtual void visit(VarDeclaration *s) { visit((Declaration *)s); }\n    virtual void visit(FuncDeclaration *s) { visit((Declaration *)s); }\n    virtual void visit(AliasDeclaration *s) { visit((Declaration *)s); }\n    virtual void visit(TupleDeclaration *s) { visit((Declaration *)s); }\n\n    // FuncDeclarations\n    virtual void visit(FuncLiteralDeclaration *s) { visit((FuncDeclaration *)s); }\n    virtual void visit(PostBlitDeclaration *s) { visit((FuncDeclaration *)s); }\n    virtual void visit(CtorDeclaration *s) { visit((FuncDeclaration *)s); }\n    virtual void visit(DtorDeclaration *s) { visit((FuncDeclaration *)s); }\n    virtual void visit(InvariantDeclaration *s) { visit((FuncDeclaration *)s); }\n    virtual void visit(UnitTestDeclaration *s) { visit((FuncDeclaration *)s); }\n    virtual void visit(NewDeclaration *s) { visit((FuncDeclaration *)s); }\n    virtual void visit(DeleteDeclaration *s) { visit((FuncDeclaration *)s); }\n    virtual void visit(StaticCtorDeclaration *s) { visit((FuncDeclaration *)s); }\n    virtual void visit(StaticDtorDeclaration *s) { visit((FuncDeclaration *)s); }\n    virtual void visit(SharedStaticCtorDeclaration *s) { visit((StaticCtorDeclaration *)s); }\n    virtual void visit(SharedStaticDtorDeclaration *s) { visit((StaticDtorDeclaration *)s); }\n\n    // AttribDeclarations\n    virtual void visit(CompileDeclaration *s) { visit((AttribDeclaration *)s); }\n    virtual void visit(UserAttributeDeclaration *s) { visit((AttribDeclaration *)s); }\n    virtual void visit(LinkDeclaration *s) { visit((AttribDeclaration *)s); }\n    virtual void visit(AnonDeclaration *s) { visit((AttribDeclaration *)s); }\n    virtual void visit(AlignDeclaration *s) { visit((AttribDeclaration *)s); }\n    virtual void visit(CPPMangleDeclaration *s) { visit((AttribDeclaration *)s); }\n    virtual void visit(ProtDeclaration *s) { visit((AttribDeclaration *)s); }\n    virtual void visit(PragmaDeclaration *s) { visit((AttribDeclaration *)s); }\n    virtual void visit(StorageClassDeclaration *s) { visit((AttribDeclaration *)s); }\n    virtual void visit(ConditionalDeclaration *s) { visit((AttribDeclaration *)s); }\n    virtual void visit(StaticForeachDeclaration *s) { visit((AttribDeclaration *)s); }\n\n    // Miscellaneous\n    virtual void visit(DeprecatedDeclaration *s) { visit((StorageClassDeclaration *)s); }\n    virtual void visit(StaticIfDeclaration *s) { visit((ConditionalDeclaration *)s); }\n    virtual void visit(EnumMember *s) { visit((VarDeclaration *)s); }\n    virtual void visit(Module *s) { visit((Package *)s); }\n    virtual void visit(StructDeclaration *s) { visit((AggregateDeclaration *)s); }\n    virtual void visit(UnionDeclaration *s) { visit((StructDeclaration *)s); }\n    virtual void visit(ClassDeclaration *s) { visit((AggregateDeclaration *)s); }\n    virtual void visit(InterfaceDeclaration *s) { visit((ClassDeclaration *)s); }\n    virtual void visit(TemplateMixin *s) { visit((TemplateInstance *)s); }\n\n    // Statements\n    virtual void visit(ImportStatement *s) { visit((Statement *)s); }\n    virtual void visit(ScopeStatement *s) { visit((Statement *)s); }\n    virtual void visit(ReturnStatement *s) { visit((Statement *)s); }\n    virtual void visit(LabelStatement *s) { visit((Statement *)s); }\n    virtual void visit(StaticAssertStatement *s) { visit((Statement *)s); }\n    virtual void visit(CompileStatement *s) { visit((Statement *)s); }\n    virtual void visit(WhileStatement *s) { visit((Statement *)s); }\n    virtual void visit(ForStatement *s) { visit((Statement *)s); }\n    virtual void visit(DoStatement *s) { visit((Statement *)s); }\n    virtual void visit(ForeachRangeStatement *s) { visit((Statement *)s); }\n    virtual void visit(ForeachStatement *s) { visit((Statement *)s); }\n    virtual void visit(IfStatement *s) { visit((Statement *)s); }\n    virtual void visit(OnScopeStatement *s) { visit((Statement *)s); }\n    virtual void visit(ConditionalStatement *s) { visit((Statement *)s); }\n    virtual void visit(StaticForeachStatement *s) { visit((Statement *)s); }\n    virtual void visit(PragmaStatement *s) { visit((Statement *)s); }\n    virtual void visit(SwitchStatement *s) { visit((Statement *)s); }\n    virtual void visit(CaseRangeStatement *s) { visit((Statement *)s); }\n    virtual void visit(CaseStatement *s) { visit((Statement *)s); }\n    virtual void visit(DefaultStatement *s) { visit((Statement *)s); }\n    virtual void visit(BreakStatement *s) { visit((Statement *)s); }\n    virtual void visit(ContinueStatement *s) { visit((Statement *)s); }\n    virtual void visit(GotoDefaultStatement *s) { visit((Statement *)s); }\n    virtual void visit(GotoCaseStatement *s) { visit((Statement *)s); }\n    virtual void visit(GotoStatement *s) { visit((Statement *)s); }\n    virtual void visit(SynchronizedStatement *s) { visit((Statement *)s); }\n    virtual void visit(WithStatement *s) { visit((Statement *)s); }\n    virtual void visit(TryCatchStatement *s) { visit((Statement *)s); }\n    virtual void visit(TryFinallyStatement *s) { visit((Statement *)s); }\n    virtual void visit(ThrowStatement *s) { visit((Statement *)s); }\n    virtual void visit(AsmStatement *s) { visit((Statement *)s); }\n    virtual void visit(ExpStatement *s) { visit((Statement *)s); }\n    virtual void visit(CompoundStatement *s) { visit((Statement *)s); }\n\n    // CompoundStatements\n    virtual void visit(CompoundDeclarationStatement *s) { visit((CompoundStatement *)s); }\n    virtual void visit(CompoundAsmStatement *s) { visit((CompoundStatement *)s); }\n\n    // AsmStatements\n    virtual void visit(InlineAsmStatement *s) { visit((AsmStatement *)s); }\n    virtual void visit(GccAsmStatement *s) { visit((AsmStatement *)s); }\n\n    // Types\n    virtual void visit(TypeBasic *t) { visit((Type *)t); }\n    virtual void visit(TypeError *t) { visit((Type *)t); }\n    virtual void visit(TypeNull *t) { visit((Type *)t); }\n    virtual void visit(TypeVector *t) { visit((Type *)t); }\n    virtual void visit(TypeEnum *t) { visit((Type *)t); }\n    virtual void visit(TypeTuple *t) { visit((Type *)t); }\n    virtual void visit(TypeClass *t) { visit((Type *)t); }\n    virtual void visit(TypeStruct *t) { visit((Type *)t); }\n    virtual void visit(TypeNext *t) { visit((Type *)t); }\n    virtual void visit(TypeQualified *t) { visit((Type *)t); }\n\n    // TypeNext\n    virtual void visit(TypeReference *t) { visit((TypeNext *)t); }\n    virtual void visit(TypeSlice *t) { visit((TypeNext *)t); }\n    virtual void visit(TypeDelegate *t) { visit((TypeNext *)t); }\n    virtual void visit(TypePointer *t) { visit((TypeNext *)t); }\n    virtual void visit(TypeFunction *t) { visit((TypeNext *)t); }\n    virtual void visit(TypeArray *t) { visit((TypeNext *)t); }\n\n    // TypeArray\n    virtual void visit(TypeDArray *t) { visit((TypeArray *)t); }\n    virtual void visit(TypeAArray *t) { visit((TypeArray *)t); }\n    virtual void visit(TypeSArray *t) { visit((TypeArray *)t); }\n\n    // TypeQualified\n    virtual void visit(TypeIdentifier *t) { visit((TypeQualified *)t); }\n    virtual void visit(TypeReturn *t) { visit((TypeQualified *)t); }\n    virtual void visit(TypeTypeof *t) { visit((TypeQualified *)t); }\n    virtual void visit(TypeInstance *t) { visit((TypeQualified *)t); }\n\n    // Expressions\n    virtual void visit(DeclarationExp *e) { visit((Expression *)e); }\n    virtual void visit(IntegerExp *e) { visit((Expression *)e); }\n    virtual void visit(NewAnonClassExp *e) { visit((Expression *)e); }\n    virtual void visit(IsExp *e) { visit((Expression *)e); }\n    virtual void visit(RealExp *e) { visit((Expression *)e); }\n    virtual void visit(NullExp *e) { visit((Expression *)e); }\n    virtual void visit(TypeidExp *e) { visit((Expression *)e); }\n    virtual void visit(TraitsExp *e) { visit((Expression *)e); }\n    virtual void visit(StringExp *e) { visit((Expression *)e); }\n    virtual void visit(NewExp *e) { visit((Expression *)e); }\n    virtual void visit(AssocArrayLiteralExp *e) { visit((Expression *)e); }\n    virtual void visit(ArrayLiteralExp *e) { visit((Expression *)e); }\n    virtual void visit(CompileExp *e) { visit((Expression *)e); }\n    virtual void visit(FuncExp *e) { visit((Expression *)e); }\n    virtual void visit(IntervalExp *e) { visit((Expression *)e); }\n    virtual void visit(TypeExp *e) { visit((Expression *)e); }\n    virtual void visit(ScopeExp *e) { visit((Expression *)e); }\n    virtual void visit(IdentifierExp *e) { visit((Expression *)e); }\n    virtual void visit(UnaExp *e) { visit((Expression *)e); }\n    virtual void visit(DefaultInitExp *e) { visit((Expression *)e); }\n    virtual void visit(BinExp *e) { visit((Expression *)e); }\n    virtual void visit(DsymbolExp *e) { visit((Expression *)e); }\n    virtual void visit(TemplateExp *e) { visit((Expression *)e); }\n    virtual void visit(SymbolExp *e) { visit((Expression *)e); }\n    virtual void visit(TupleExp *e) { visit((Expression *)e); }\n    virtual void visit(ThisExp *e) { visit((Expression *)e); }\n\n    // Miscellaneous\n    virtual void visit(VarExp *e) { visit((SymbolExp *)e); }\n    virtual void visit(DollarExp *e) { visit((IdentifierExp *)e); }\n    virtual void visit(SuperExp *e) { visit((ThisExp *)e); }\n\n    // UnaExp\n    virtual void visit(AddrExp *e) { visit((UnaExp *)e); }\n    virtual void visit(PreExp *e) { visit((UnaExp *)e); }\n    virtual void visit(PtrExp *e) { visit((UnaExp *)e); }\n    virtual void visit(NegExp *e) { visit((UnaExp *)e); }\n    virtual void visit(UAddExp *e) { visit((UnaExp *)e); }\n    virtual void visit(NotExp *e) { visit((UnaExp *)e); }\n    virtual void visit(ComExp *e) { visit((UnaExp *)e); }\n    virtual void visit(DeleteExp *e) { visit((UnaExp *)e); }\n    virtual void visit(CastExp *e) { visit((UnaExp *)e); }\n    virtual void visit(CallExp *e) { visit((UnaExp *)e); }\n    virtual void visit(DotIdExp *e) { visit((UnaExp *)e); }\n    virtual void visit(AssertExp *e) { visit((UnaExp *)e); }\n    virtual void visit(ImportExp *e) { visit((UnaExp *)e); }\n    virtual void visit(DotTemplateInstanceExp *e) { visit((UnaExp *)e); }\n    virtual void visit(ArrayExp *e) { visit((UnaExp *)e); }\n\n    // DefaultInitExp\n    virtual void visit(FuncInitExp *e) { visit((DefaultInitExp *)e); }\n    virtual void visit(PrettyFuncInitExp *e) { visit((DefaultInitExp *)e); }\n    virtual void visit(FileInitExp *e) { visit((DefaultInitExp *)e); }\n    virtual void visit(LineInitExp *e) { visit((DefaultInitExp *)e); }\n    virtual void visit(ModuleInitExp *e) { visit((DefaultInitExp *)e); }\n\n    // BinExp\n    virtual void visit(CommaExp *e) { visit((BinExp *)e); }\n    virtual void visit(PostExp *e) { visit((BinExp *)e); }\n    virtual void visit(PowExp *e) { visit((BinExp *)e); }\n    virtual void visit(MulExp *e) { visit((BinExp *)e); }\n    virtual void visit(DivExp *e) { visit((BinExp *)e); }\n    virtual void visit(ModExp *e) { visit((BinExp *)e); }\n    virtual void visit(AddExp *e) { visit((BinExp *)e); }\n    virtual void visit(MinExp *e) { visit((BinExp *)e); }\n    virtual void visit(CatExp *e) { visit((BinExp *)e); }\n    virtual void visit(ShlExp *e) { visit((BinExp *)e); }\n    virtual void visit(ShrExp *e) { visit((BinExp *)e); }\n    virtual void visit(UshrExp *e) { visit((BinExp *)e); }\n    virtual void visit(EqualExp *e) { visit((BinExp *)e); }\n    virtual void visit(InExp *e) { visit((BinExp *)e); }\n    virtual void visit(IdentityExp *e) { visit((BinExp *)e); }\n    virtual void visit(CmpExp *e) { visit((BinExp *)e); }\n    virtual void visit(AndExp *e) { visit((BinExp *)e); }\n    virtual void visit(XorExp *e) { visit((BinExp *)e); }\n    virtual void visit(OrExp *e) { visit((BinExp *)e); }\n    virtual void visit(LogicalExp *e) { visit((BinExp *)e); }\n    virtual void visit(CondExp *e) { visit((BinExp *)e); }\n    virtual void visit(AssignExp *e) { visit((BinExp *)e); }\n    virtual void visit(BinAssignExp *e) { visit((BinExp *)e); }\n\n    // BinAssignExp\n    virtual void visit(AddAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(MinAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(MulAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(DivAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(ModAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(PowAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(AndAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(OrAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(XorAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(ShlAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(ShrAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(UshrAssignExp *e) { visit((BinAssignExp *)e); }\n    virtual void visit(CatAssignExp *e) { visit((BinAssignExp *)e); }\n\n    // TemplateParameter\n    virtual void visit(TemplateAliasParameter *tp) { visit((TemplateParameter *)tp); }\n    virtual void visit(TemplateTypeParameter *tp) { visit((TemplateParameter *)tp); }\n    virtual void visit(TemplateTupleParameter *tp) { visit((TemplateParameter *)tp); }\n    virtual void visit(TemplateValueParameter *tp) { visit((TemplateParameter *)tp); }\n\n    virtual void visit(TemplateThisParameter *tp) { visit((TemplateTypeParameter *)tp); }\n\n    // Condition\n    virtual void visit(StaticIfCondition *c) { visit((Condition *)c); }\n    virtual void visit(DVCondition *c) { visit((Condition *)c); }\n    virtual void visit(DebugCondition *c) { visit((DVCondition *)c); }\n    virtual void visit(VersionCondition *c) { visit((DVCondition *)c); }\n\n    // Initializer\n    virtual void visit(ExpInitializer *i) { visit((Initializer *)i); }\n    virtual void visit(StructInitializer *i) { visit((Initializer *)i); }\n    virtual void visit(ArrayInitializer *i) { visit((Initializer *)i); }\n    virtual void visit(VoidInitializer *i) { visit((Initializer *)i); }\n};\n\nclass Visitor : public ParseTimeVisitor\n{\npublic:\n    using ParseTimeVisitor::visit;\n\n    // Miscellaneous\n    virtual void visit(ErrorStatement *s) { visit((Statement *)s); }\n    virtual void visit(PeelStatement *s) { visit((Statement *)s); }\n    virtual void visit(UnrolledLoopStatement *s) { visit((Statement *)s); }\n    virtual void visit(SwitchErrorStatement *s) { visit((Statement *)s); }\n    virtual void visit(DebugStatement *s) { visit((Statement *)s); }\n    virtual void visit(DtorExpStatement *s) { visit((ExpStatement *)s); }\n    virtual void visit(ForwardingStatement *s) { visit((Statement *)s); }\n    virtual void visit(OverloadSet *s) { visit((Dsymbol *)s); }\n    virtual void visit(LabelDsymbol *s) { visit((Dsymbol *)s); }\n    virtual void visit(WithScopeSymbol *s) { visit((ScopeDsymbol *)s); }\n    virtual void visit(ArrayScopeSymbol *s) { visit((ScopeDsymbol *)s); }\n    virtual void visit(OverDeclaration *s) { visit((Declaration *)s); }\n    virtual void visit(SymbolDeclaration *s) { visit((Declaration *)s); }\n    virtual void visit(ThisDeclaration *s) { visit((VarDeclaration *)s); }\n    virtual void visit(TypeInfoDeclaration *s) { visit((VarDeclaration *)s); }\n    virtual void visit(TypeInfoStructDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoClassDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoInterfaceDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoPointerDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoArrayDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoStaticArrayDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoAssociativeArrayDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoEnumDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoFunctionDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoDelegateDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoTupleDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoConstDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoInvariantDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoSharedDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoWildDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(TypeInfoVectorDeclaration *s) { visit((TypeInfoDeclaration *)s); }\n    virtual void visit(FuncAliasDeclaration *s) { visit((FuncDeclaration *)s); }\n    virtual void visit(ErrorInitializer *i) { visit((Initializer *)i); }\n    virtual void visit(ErrorExp *e) { visit((Expression *)e); }\n    virtual void visit(ComplexExp *e) { visit((Expression *)e); }\n    virtual void visit(StructLiteralExp *e) { visit((Expression *)e); }\n    virtual void visit(ObjcClassReferenceExp *e) { visit((Expression *)e); }\n    virtual void visit(SymOffExp *e) { visit((SymbolExp *)e); }\n    virtual void visit(OverExp *e) { visit((Expression *)e); }\n    virtual void visit(HaltExp *e) { visit((Expression *)e); }\n    virtual void visit(DotTemplateExp *e) { visit((UnaExp *)e); }\n    virtual void visit(DotVarExp *e) { visit((UnaExp *)e); }\n    virtual void visit(DelegateExp *e) { visit((UnaExp *)e); }\n    virtual void visit(DotTypeExp *e) { visit((UnaExp *)e); }\n    virtual void visit(VectorExp *e) { visit((UnaExp *)e); }\n    virtual void visit(SliceExp *e) { visit((UnaExp *)e); }\n    virtual void visit(ArrayLengthExp *e) { visit((UnaExp *)e); }\n    virtual void visit(DelegatePtrExp *e) { visit((UnaExp *)e); }\n    virtual void visit(DelegateFuncptrExp *e) { visit((UnaExp *)e); }\n    virtual void visit(DotExp *e) { visit((BinExp *)e); }\n    virtual void visit(IndexExp *e) { visit((BinExp *)e); }\n    virtual void visit(ConstructExp *e) { visit((AssignExp *)e); }\n    virtual void visit(BlitExp *e) { visit((AssignExp *)e); }\n    virtual void visit(RemoveExp *e) { visit((BinExp *)e); }\n    virtual void visit(ClassReferenceExp *e) { visit((Expression *)e); }\n    virtual void visit(VoidInitExp *e) { visit((Expression *)e); }\n    virtual void visit(ThrownExceptionExp *e) { visit((Expression *)e); }\n};\n\nclass StoppableVisitor : public Visitor\n{\npublic:\n    bool stop;\n    StoppableVisitor() : stop(false) {}\n};\n"
  },
  {
    "path": "gcc/d/expr.cc",
    "content": "/* expr.cc -- Lower D frontend expressions to GCC trees.\n   Copyright (C) 2015-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/aggregate.h\"\n#include \"dmd/ctfe.h\"\n#include \"dmd/declaration.h\"\n#include \"dmd/expression.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/init.h\"\n#include \"dmd/module.h\"\n#include \"dmd/mtype.h\"\n#include \"dmd/template.h\"\n\n#include \"tree.h\"\n#include \"fold-const.h\"\n#include \"diagnostic.h\"\n#include \"langhooks.h\"\n#include \"tm.h\"\n#include \"function.h\"\n#include \"toplev.h\"\n#include \"varasm.h\"\n#include \"predict.h\"\n#include \"stor-layout.h\"\n\n#include \"d-tree.h\"\n\n\n/* Implements the visitor interface to build the GCC trees of all Expression\n   AST classes emitted from the D Front-end.\n   All visit methods accept one parameter E, which holds the frontend AST\n   of the expression to compile.  They also don't return any value, instead\n   generated code is cached in RESULT_ and returned from the caller.  */\n\nclass ExprVisitor : public Visitor\n{\n  using Visitor::visit;\n\n  tree result_;\n  bool constp_;\n\n  /* Determine if type is a struct that has a postblit.  */\n\n  bool needs_postblit (Type *t)\n  {\n    t = t->baseElemOf ();\n\n    if (t->ty == Tstruct)\n      {\n\tStructDeclaration *sd = ((TypeStruct *) t)->sym;\n\tif (sd->postblit)\n\t  return true;\n      }\n\n    return false;\n  }\n\n  /* Determine if type is a struct that has a destructor.  */\n\n  bool needs_dtor (Type *t)\n  {\n    t = t->baseElemOf ();\n\n    if (t->ty == Tstruct)\n      {\n\tStructDeclaration *sd = ((TypeStruct *) t)->sym;\n\tif (sd->dtor)\n\t  return true;\n      }\n\n    return false;\n  }\n\n  /* Determine if expression is suitable lvalue.  */\n\n  bool lvalue_p (Expression *e)\n  {\n    return ((e->op != TOKslice && e->isLvalue ())\n\t    || (e->op == TOKslice && ((UnaExp *) e)->e1->isLvalue ())\n\t    || (e->op == TOKcast && ((UnaExp *) e)->e1->isLvalue ()));\n  }\n\n  /* Build an expression of code CODE, data type TYPE, and operands ARG0 and\n     ARG1.  Perform relevant conversions needed for correct code operations.  */\n\n  tree binary_op (tree_code code, tree type, tree arg0, tree arg1)\n  {\n    tree t0 = TREE_TYPE (arg0);\n    tree t1 = TREE_TYPE (arg1);\n    tree ret = NULL_TREE;\n\n    bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1);\n\n    /* Deal with float mod expressions immediately.  */\n    if (code == FLOAT_MOD_EXPR)\n      return build_float_modulus (type, arg0, arg1);\n\n    if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))\n      return build_nop (type, build_offset_op (code, arg0, arg1));\n\n    if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))\n      return build_nop (type, build_offset_op (code, arg1, arg0));\n\n    if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))\n      {\n\tgcc_assert (code == MINUS_EXPR);\n\ttree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);\n\n\t/* POINTER_DIFF_EXPR requires a signed integer type of the same size as\n\t   pointers.  If some platform cannot provide that, or has a larger\n\t   ptrdiff_type to support differences larger than half the address\n\t   space, cast the pointers to some larger integer type and do the\n\t   computations in that type.  */\n\tif (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))\n\t  ret = fold_build2 (MINUS_EXPR, ptrtype,\n\t\t\t     d_convert (ptrtype, arg0),\n\t\t\t     d_convert (ptrtype, arg1));\n\telse\n\t  ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);\n      }\n    else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp))\n      {\n\ttree inttype = (unsignedp)\n\t  ? d_unsigned_type (type) : d_signed_type (type);\n\tret = fold_build2 (code, inttype, arg0, arg1);\n      }\n    else\n      {\n\t/* If the operation needs excess precision.  */\n\ttree eptype = excess_precision_type (type);\n\tif (eptype != NULL_TREE)\n\t  {\n\t    arg0 = d_convert (eptype, arg0);\n\t    arg1 = d_convert (eptype, arg1);\n\t  }\n\telse\n\t  {\n\t    /* Front-end does not do this conversion and GCC does not\n\t       always do it right.  */\n\t    if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))\n\t      arg1 = d_convert (t0, arg1);\n\t    else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))\n\t      arg0 = d_convert (t1, arg0);\n\n\t    eptype = type;\n\t  }\n\n\tret = fold_build2 (code, eptype, arg0, arg1);\n      }\n\n    return d_convert (type, ret);\n  }\n\n  /* Build a binary expression of code CODE, assigning the result into E1.  */\n\n  tree binop_assignment (tree_code code, Expression *e1, Expression *e2)\n  {\n    /* Skip casts for lhs assignment.  */\n    Expression *e1b = e1;\n    while (e1b->op == TOKcast)\n      {\n\tCastExp *ce = (CastExp *) e1b;\n\tgcc_assert (same_type_p (ce->type, ce->to));\n\te1b = ce->e1;\n      }\n\n    /* Stabilize LHS for assignment.  */\n    tree lhs = build_expr (e1b);\n    tree lexpr = stabilize_expr (&lhs);\n\n    /* The LHS expression could be an assignment, to which its operation gets\n       lost during gimplification.  */\n    if (TREE_CODE (lhs) == MODIFY_EXPR)\n      {\n\t/* If LHS has side effects, call stabilize_reference on it, so it can\n\t   be evaluated multiple times.  */\n\tif (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))\n\t  lhs = build_assign (MODIFY_EXPR,\n\t\t\t      stabilize_reference (TREE_OPERAND (lhs, 0)),\n\t\t\t      TREE_OPERAND (lhs, 1));\n\n\tlexpr = compound_expr (lexpr, lhs);\n\tlhs = TREE_OPERAND (lhs, 0);\n      }\n\n    lhs = stabilize_reference (lhs);\n\n    /* Save RHS, to ensure that the expression is evaluated before LHS.  */\n    tree rhs = build_expr (e2);\n    tree rexpr = d_save_expr (rhs);\n\n    rhs = this->binary_op (code, build_ctype (e1->type),\n\t\t\t   convert_expr (lhs, e1b->type, e1->type), rexpr);\n    if (TREE_SIDE_EFFECTS (rhs))\n      rhs = compound_expr (rexpr, rhs);\n\n    tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));\n    return compound_expr (lexpr, expr);\n  }\n\npublic:\n  ExprVisitor (bool constp)\n  {\n    this->result_ = NULL_TREE;\n    this->constp_ = constp;\n  }\n\n  tree result (void)\n  {\n    return this->result_;\n  }\n\n  /* Visitor interfaces, each Expression class should have\n     overridden the default.  */\n\n  void visit (Expression *)\n  {\n    gcc_unreachable ();\n  }\n\n  /* Build a conditional expression.  If either the second or third\n     expression is void, then the resulting type is void.  Otherwise\n     they are implicitly converted to a common type.  */\n\n  void visit (CondExp *e)\n  {\n    tree cond = convert_for_condition (build_expr (e->econd),\n\t\t\t\t       e->econd->type);\n    tree t1 = build_expr (e->e1);\n    tree t2 = build_expr (e->e2);\n\n    if (e->type->ty != Tvoid)\n      {\n\tt1 = convert_expr (t1, e->e1->type, e->type);\n\tt2 = convert_expr (t2, e->e2->type, e->type);\n      }\n\n    this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);\n  }\n\n  /* Build an identity comparison expression.  Operands go through the\n     usual conversions to bring them to a common type before comparison.\n     The result type is bool.  */\n\n  void visit (IdentityExp *e)\n  {\n    tree_code code = (e->op == TOKidentity) ? EQ_EXPR : NE_EXPR;\n    Type *tb1 = e->e1->type->toBasetype ();\n    Type *tb2 = e->e2->type->toBasetype ();\n\n    if ((tb1->ty == Tsarray || tb1->ty == Tarray)\n\t&& (tb2->ty == Tsarray || tb2->ty == Tarray))\n      {\n\t/* For static and dynamic arrays, identity is defined as referring to\n\t   the same array elements and the same number of elements.  */\n\ttree t1 = d_array_convert (e->e1);\n\ttree t2 = d_array_convert (e->e2);\n\tthis->result_ = d_convert (build_ctype (e->type),\n\t\t\t\t   build_boolop (code, t1, t2));\n      }\n    else if (tb1->isfloating () && tb1->ty != Tvector)\n      {\n\t/* For floating-point values, identity is defined as the bits in the\n\t   operands being identical.  */\n\ttree t1 = d_save_expr (build_expr (e->e1));\n\ttree t2 = d_save_expr (build_expr (e->e2));\n\n\ttree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);\n\ttree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);\n\n\ttree result = build_call_expr (tmemcmp, 3, build_address (t1),\n\t\t\t\t       build_address (t2), size);\n\tthis->result_ = build_boolop (code, result, integer_zero_node);\n      }\n    else if (tb1->ty == Tstruct)\n      {\n\t/* For struct objects, identity is defined as bits in operands being\n\t   identical also.  Alignment holes in structs are ignored.  */\n\tStructDeclaration *sd = ((TypeStruct *) tb1)->sym;\n\ttree t1 = build_expr (e->e1);\n\ttree t2 = build_expr (e->e2);\n\n\tgcc_assert (same_type_p (tb1, tb2));\n\n\tthis->result_ = build_struct_comparison (code, sd, t1, t2);\n      }\n    else\n      {\n\t/* For operands of other types, identity is defined as being the\n\t   same as equality expressions.  */\n\ttree t1 = build_expr (e->e1);\n\ttree t2 = build_expr (e->e2);\n\tthis->result_ = d_convert (build_ctype (e->type),\n\t\t\t\t   build_boolop (code, t1, t2));\n      }\n  }\n\n  /* Build an equality expression, which compare the two operands for either\n     equality or inequality.  Operands go through the usual conversions to bring\n     them to a common type before comparison.  The result type is bool.  */\n\n  void visit (EqualExp *e)\n  {\n    Type *tb1 = e->e1->type->toBasetype ();\n    Type *tb2 = e->e2->type->toBasetype ();\n    tree_code code = (e->op == TOKequal) ? EQ_EXPR : NE_EXPR;\n\n    if ((tb1->ty == Tsarray || tb1->ty == Tarray)\n\t&& (tb2->ty == Tsarray || tb2->ty == Tarray))\n      {\n\t/* For static and dynamic arrays, equality is defined as the lengths of\n\t   the arrays matching, and all the elements are equal.  */\n\tType *t1elem = tb1->nextOf ()->toBasetype ();\n\tType *t2elem = tb1->nextOf ()->toBasetype ();\n\n\t/* Check if comparisons of arrays can be optimized using memcmp.\n\t   This will inline EQ expressions as:\n\t\te1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;\n\t    Or when generating a NE expression:\n\t\te1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0;  */\n\tif ((t1elem->isintegral () || t1elem->ty == Tvoid\n\t     || (t1elem->ty == Tstruct && !((TypeStruct *)t1elem)->sym->xeq))\n\t    && t1elem->ty == t2elem->ty)\n\t  {\n\t    tree t1 = d_array_convert (e->e1);\n\t    tree t2 = d_array_convert (e->e2);\n\t    tree result;\n\n\t    /* Make temporaries to prevent multiple evaluations.  */\n\t    tree t1saved = d_save_expr (t1);\n\t    tree t2saved = d_save_expr (t2);\n\n\t    /* Length of arrays, for comparisons done before calling memcmp.  */\n\t    tree t1len = d_array_length (t1saved);\n\t    tree t2len = d_array_length (t2saved);\n\n\t    /* Reference to array data.  */\n\t    tree t1ptr = d_array_ptr (t1saved);\n\t    tree t2ptr = d_array_ptr (t2saved);\n\n\t    /* Compare arrays using memcmp if possible, otherwise for structs,\n\t       each field is compared inline.  */\n\t    if (t1elem->ty != Tstruct\n\t\t|| identity_compare_p (((TypeStruct *) t1elem)->sym))\n\t      {\n\t\ttree size = size_mult_expr (t1len, size_int (t1elem->size ()));\n\t\ttree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);\n\n\t\tresult = build_call_expr (tmemcmp, 3, t1ptr, t2ptr, size);\n\t\tresult = build_boolop (code, result, integer_zero_node);\n\t      }\n\t    else\n\t      {\n\t\tStructDeclaration *sd = ((TypeStruct *) t1elem)->sym;\n\n\t\tresult = build_array_struct_comparison (code, sd, t1len,\n\t\t\t\t\t\t\tt1ptr, t2ptr);\n\t      }\n\n\t    /* Check array length first before passing to memcmp.\n\t       For equality expressions, this becomes:\n\t\t    (e1.length == 0 || memcmp);\n\t       Otherwise for inequality:\n\t\t    (e1.length != 0 && memcmp);  */\n\t    tree tsizecmp = build_boolop (code, t1len, size_zero_node);\n\t    if (e->op == TOKequal)\n\t      result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);\n\t    else\n\t      result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);\n\n\t    /* Finally, check if lengths of both arrays match if dynamic.\n\t       The frontend should have already guaranteed that static arrays\n\t       have same size.  */\n\t    if (tb1->ty == Tsarray && tb2->ty == Tsarray)\n\t      gcc_assert (tb1->size () == tb2->size ());\n\t    else\n\t      {\n\t\ttree tlencmp = build_boolop (code, t1len, t2len);\n\t\tif (e->op == TOKequal)\n\t\t  result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);\n\t\telse\n\t\t  result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);\n\t      }\n\n\t    /* Ensure left-to-right order of evaluation.  */\n\t    if (TREE_SIDE_EFFECTS (t2))\n\t      result = compound_expr (t2saved, result);\n\n\t    if (TREE_SIDE_EFFECTS (t1))\n\t      result = compound_expr (t1saved, result);\n\n\t    this->result_ = result;\n\t  }\n\telse\n\t  {\n\t    /* Use _adEq2() to compare each element.  */\n\t    Type *t1array = t1elem->arrayOf ();\n\t    tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,\n\t\t\t\t\t d_array_convert (e->e1),\n\t\t\t\t\t d_array_convert (e->e2),\n\t\t\t\t\t build_typeinfo (e->loc, t1array));\n\n\t    if (e->op == TOKnotequal)\n\t      result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);\n\n\t    this->result_ = result;\n\t  }\n      }\n    else if (tb1->ty == Tstruct)\n      {\n\t/* Equality for struct objects means the logical product of all\n\t   equality results of the corresponding object fields.  */\n\tStructDeclaration *sd = ((TypeStruct *) tb1)->sym;\n\ttree t1 = build_expr (e->e1);\n\ttree t2 = build_expr (e->e2);\n\n\tgcc_assert (same_type_p (tb1, tb2));\n\n\tthis->result_ = build_struct_comparison (code, sd, t1, t2);\n      }\n    else if (tb1->ty == Taarray && tb2->ty == Taarray)\n      {\n\t/* Use _aaEqual() for associative arrays.  */\n\tTypeAArray *taa1 = (TypeAArray *) tb1;\n\ttree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,\n\t\t\t\t     build_typeinfo (e->loc, taa1),\n\t\t\t\t     build_expr (e->e1),\n\t\t\t\t     build_expr (e->e2));\n\n\tif (e->op == TOKnotequal)\n\t  result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);\n\n\tthis->result_ = result;\n      }\n    else\n      {\n\t/* For operands of other types, equality is defined as the bit pattern\n\t   of the type matches exactly.  */\n\ttree t1 = build_expr (e->e1);\n\ttree t2 = build_expr (e->e2);\n\n\tthis->result_ = d_convert (build_ctype (e->type),\n\t\t\t\t   build_boolop (code, t1, t2));\n      }\n  }\n\n  /* Build an `in' expression.  This is a condition to see if an element\n     exists in an associative array.  The result is a pointer to the\n     element, or null if false.  */\n\n  void visit (InExp *e)\n  {\n    Type *tb2 = e->e2->type->toBasetype ();\n    gcc_assert (tb2->ty == Taarray);\n\n    Type *tkey = ((TypeAArray *) tb2)->index->toBasetype ();\n    tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);\n\n    /* Build a call to _aaInX().  */\n    this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,\n\t\t\t\t   build_expr (e->e2),\n\t\t\t\t   build_typeinfo (e->loc, tkey),\n\t\t\t\t   build_address (key));\n  }\n\n  /* Build a relational expression.  The result type is bool.  */\n\n  void visit (CmpExp *e)\n  {\n    Type *tb1 = e->e1->type->toBasetype ();\n    Type *tb2 = e->e2->type->toBasetype ();\n\n    tree result;\n    tree_code code;\n\n    switch (e->op)\n      {\n      case TOKle:\n\tcode = LE_EXPR;\n\tbreak;\n\n      case TOKlt:\n\tcode = LT_EXPR;\n\tbreak;\n\n      case TOKge:\n\tcode = GE_EXPR;\n\tbreak;\n\n      case TOKgt:\n\tcode = GT_EXPR;\n\tbreak;\n\n      default:\n\tgcc_unreachable ();\n      }\n\n    /* For static and dynamic arrays, the relational op is turned into a\n       library call.  It is not lowered during codegen.  */\n    if ((tb1->ty == Tsarray || tb1->ty == Tarray)\n\t&& (tb2->ty == Tsarray || tb2->ty == Tarray))\n      {\n\terror (\"cannot handle comparison of type %<%s == %s%>\",\n\t       tb1->toChars (), tb2->toChars ());\n\tgcc_unreachable ();\n      }\n\n    /* Simple comparison.  */\n    result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));\n    this->result_ = d_convert (build_ctype (e->type), result);\n  }\n\n  /* Build a logical `and if' or `or if' expression.  If the right operand\n     expression is void, then the resulting type is void.  Otherwise the\n     result is bool.  */\n\n  void visit (LogicalExp *e)\n  {\n    tree_code code = (e->op == TOKandand) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;\n\n    if (e->e2->type->toBasetype ()->ty != Tvoid)\n      {\n\ttree t1 = build_expr (e->e1);\n\ttree t2 = build_expr (e->e2);\n\n\tt1 = convert_for_condition (t1, e->e1->type);\n\tt2 = convert_for_condition (t2, e->e2->type);\n\n\tthis->result_ = d_convert (build_ctype (e->type),\n\t\t\t\t   build_boolop (code, t1, t2));\n      }\n    else\n      {\n\ttree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);\n\ttree t2 = build_expr_dtor (e->e2);\n\n\t/* Invert condition for logical or if expression.  */\n\tif (e->op == TOKoror)\n\t  t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);\n\n\tthis->result_ = build_condition (build_ctype (e->type),\n\t\t\t\t\t t1, t2, void_node);\n      }\n  }\n\n  /* Build a binary operand expression.  Operands go through usual arithmetic\n     conversions to bring them to a common type before evaluating.  */\n\n  void visit (BinExp *e)\n  {\n    tree_code code;\n\n    switch (e->op)\n      {\n      case TOKadd:\n      case TOKmin:\n\tif ((e->e1->type->isreal () && e->e2->type->isimaginary ())\n\t    || (e->e1->type->isimaginary () && e->e2->type->isreal ()))\n\t  {\n\t    /* If the result is complex, then we can shortcut binary_op.\n\t       Frontend should have already validated types and sizes.  */\n\t    tree t1 = build_expr (e->e1);\n\t    tree t2 = build_expr (e->e2);\n\n\t    if (e->op == TOKmin)\n\t      t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);\n\n\t    if (e->e1->type->isreal ())\n\t      this->result_ = complex_expr (build_ctype (e->type), t1, t2);\n\t    else\n\t      this->result_ = complex_expr (build_ctype (e->type), t2, t1);\n\n\t    return;\n\t  }\n\telse\n\t  code = (e->op == TOKadd)\n\t    ? PLUS_EXPR : MINUS_EXPR;\n\tbreak;\n\n      case TOKmul:\n\tcode = MULT_EXPR;\n\tbreak;\n\n      case TOKdiv:\n\tcode = e->e1->type->isintegral ()\n\t  ? TRUNC_DIV_EXPR : RDIV_EXPR;\n\tbreak;\n\n      case TOKmod:\n\tcode = e->e1->type->isfloating ()\n\t  ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;\n\tbreak;\n\n      case TOKand:\n\tcode = BIT_AND_EXPR;\n\tbreak;\n\n      case TOKor:\n\tcode = BIT_IOR_EXPR;\n\tbreak;\n\n      case TOKxor:\n\tcode = BIT_XOR_EXPR;\n\tbreak;\n\n      case TOKshl:\n\tcode = LSHIFT_EXPR;\n\t  break;\n\n      case TOKshr:\n\tcode = RSHIFT_EXPR;\n\tbreak;\n\n      case TOKushr:\n\tcode = UNSIGNED_RSHIFT_EXPR;\n\tbreak;\n\n      default:\n\tgcc_unreachable ();\n      }\n\n    this->result_ = this->binary_op (code, build_ctype (e->type),\n\t\t\t\t     build_expr (e->e1), build_expr (e->e2));\n  }\n\n\n  /* Build a concat expression, which concatenates two or more arrays of the\n     same type, producing a dynamic array with the result.  If one operand\n     is an element type, that element is converted to an array of length 1.  */\n\n  void visit (CatExp *e)\n  {\n    Type *tb1 = e->e1->type->toBasetype ();\n    Type *tb2 = e->e2->type->toBasetype ();\n    Type *etype;\n\n    if (tb1->ty == Tarray || tb1->ty == Tsarray)\n      etype = tb1->nextOf ();\n    else\n      etype = tb2->nextOf ();\n\n    vec<tree, va_gc> *elemvars = NULL;\n    tree result;\n\n    if (e->e1->op == TOKcat)\n      {\n\t/* Flatten multiple concatenations to an array.\n\t   So the expression ((a ~ b) ~ c) becomes [a, b, c]  */\n\tint ndims = 2;\n\n\tfor (Expression *ex = e->e1; ex->op == TOKcat;)\n\t  {\n\t    if (ex->op == TOKcat)\n\t      {\n\t\tex = ((CatExp *) ex)->e1;\n\t\tndims++;\n\t      }\n\t  }\n\n\t/* Store all concatenation args to a temporary byte[][ndims] array.  */\n\tType *targselem = Type::tint8->arrayOf ();\n\ttree var = create_temporary_var (make_array_type (targselem, ndims));\n\ttree init = build_constructor (TREE_TYPE (var), NULL);\n\tvec_safe_push (elemvars, var);\n\n\t/* Loop through each concatenation from right to left.  */\n\tvec<constructor_elt, va_gc> *elms = NULL;\n\tCatExp *ce = e;\n\tint dim = ndims - 1;\n\n\tfor (Expression *oe = ce->e2; oe != NULL;\n\t     (ce->e1->op != TOKcat\n\t      ? (oe = ce->e1)\n\t      : (ce = (CatExp *)ce->e1, oe = ce->e2)))\n\t  {\n\t    tree arg = d_array_convert (etype, oe, &elemvars);\n\t    tree index = size_int (dim);\n\t    CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));\n\n\t    /* Finished pushing all arrays.  */\n\t    if (oe == ce->e1)\n\t      break;\n\n\t    dim -= 1;\n\t  }\n\n\t/* Check there is no logic bug in constructing byte[][] of arrays.  */\n\tgcc_assert (dim == 0);\n\tCONSTRUCTOR_ELTS (init) = elms;\n\tDECL_INITIAL (var) = init;\n\n\ttree arrs = d_array_value (build_ctype (targselem->arrayOf ()),\n\t\t\t\t   size_int (ndims), build_address (var));\n\n\tresult = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,\n\t\t\t\tbuild_typeinfo (e->loc, e->type), arrs);\n      }\n    else\n      {\n\t/* Handle single concatenation (a ~ b).  */\n\tresult = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,\n\t\t\t\tbuild_typeinfo (e->loc, e->type),\n\t\t\t\td_array_convert (etype, e->e1, &elemvars),\n\t\t\t\td_array_convert (etype, e->e2, &elemvars));\n      }\n\n    for (size_t i = 0; i < vec_safe_length (elemvars); ++i)\n      result = bind_expr ((*elemvars)[i], result);\n\n    this->result_ = result;\n  }\n\n  /* Build an assignment operator expression.  The right operand is implicitly\n     converted to the type of the left operand, and assigned to it.  */\n\n  void visit (BinAssignExp *e)\n  {\n    tree_code code;\n    Expression *e1b = e->e1;\n\n    switch (e->op)\n      {\n      case TOKaddass:\n\tcode = PLUS_EXPR;\n\tbreak;\n\n      case TOKminass:\n\tcode = MINUS_EXPR;\n\tbreak;\n\n      case TOKmulass:\n\tcode = MULT_EXPR;\n\tbreak;\n\n      case TOKdivass:\n\tcode = e->e1->type->isintegral ()\n\t  ? TRUNC_DIV_EXPR : RDIV_EXPR;\n\tbreak;\n\n      case TOKmodass:\n\tcode = e->e1->type->isfloating ()\n\t  ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;\n\tbreak;\n\n      case TOKandass:\n\tcode = BIT_AND_EXPR;\n\tbreak;\n\n      case TOKorass:\n\tcode = BIT_IOR_EXPR;\n\tbreak;\n\n      case TOKxorass:\n\tcode = BIT_XOR_EXPR;\n\tbreak;\n\n      case TOKpowass:\n\tgcc_unreachable ();\n\n      case TOKshlass:\n\tcode = LSHIFT_EXPR;\n\tbreak;\n\n      case TOKshrass:\n      case TOKushrass:\n\t/* Use the original lhs type before it was promoted.  The left operand\n\t   of `>>>=' does not undergo integral promotions before shifting.\n\t   Strip off casts just incase anyway.  */\n\twhile (e1b->op == TOKcast)\n\t  {\n\t    CastExp *ce = (CastExp *) e1b;\n\t    gcc_assert (same_type_p (ce->type, ce->to));\n\t    e1b = ce->e1;\n\t  }\n\tcode = (e->op == TOKshrass) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;\n\tbreak;\n\n      default:\n\tgcc_unreachable ();\n      }\n\n    tree exp = this->binop_assignment (code, e1b, e->e2);\n    this->result_ = convert_expr (exp, e1b->type, e->type);\n  }\n\n  /* Build a concat assignment expression.  The right operand is appended\n     to the the left operand.  */\n\n  void visit (CatAssignExp *e)\n  {\n    Type *tb1 = e->e1->type->toBasetype ();\n    Type *tb2 = e->e2->type->toBasetype ();\n    Type *etype = tb1->nextOf ()->toBasetype ();\n\n    if (tb1->ty == Tarray && tb2->ty == Tdchar\n\t&& (etype->ty == Tchar || etype->ty == Twchar))\n      {\n\t/* Append a dchar to a char[] or wchar[]  */\n\tlibcall_fn libcall = (etype->ty == Tchar)\n\t  ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;\n\n\tthis->result_ = build_libcall (libcall, e->type, 2,\n\t\t\t\t       build_address (build_expr (e->e1)),\n\t\t\t\t       build_expr (e->e2));\n      }\n    else\n      {\n\tgcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray);\n\n\ttree tinfo = build_typeinfo (e->loc, e->type);\n\ttree ptr = build_address (build_expr (e->e1));\n\n\tif ((tb2->ty == Tarray || tb2->ty == Tsarray)\n\t    && same_type_p (etype, tb2->nextOf ()->toBasetype ()))\n\t  {\n\t    /* Append an array.  */\n\t    this->result_ = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,\n\t\t\t\t\t   tinfo, ptr, d_array_convert (e->e2));\n\n\t  }\n\telse if (same_type_p (etype, tb2))\n\t  {\n\t    /* Append an element.  */\n\t    tree result = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,\n\t\t\t\t\t tinfo, ptr, size_one_node);\n\t    result = d_save_expr (result);\n\n\t    /* Assign e2 to last element.  */\n\t    tree offexp = d_array_length (result);\n\t    offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),\n\t\t\t     offexp, size_one_node);\n\t    offexp = d_save_expr (offexp);\n\n\t    tree ptrexp = d_array_ptr (result);\n\t    ptrexp = void_okay_p (ptrexp);\n\t    ptrexp = build_array_index (ptrexp, offexp);\n\n\t    /* Evaluate expression before appending.  */\n\t    tree t2 = build_expr (e->e2);\n\t    tree expr = stabilize_expr (&t2);\n\n\t    t2 = d_save_expr (t2);\n\t    result = modify_expr (build_deref (ptrexp), t2);\n\t    result = compound_expr (t2, result);\n\n\t    this->result_ = compound_expr (expr, result);\n\t  }\n\telse\n\t  gcc_unreachable ();\n      }\n  }\n\n  /* Build an assignment expression.  The right operand is implicitly\n     converted to the type of the left operand, and assigned to it.  */\n\n  void visit (AssignExp *e)\n  {\n    /* First, handle special assignment semantics.  */\n\n    /* Look for array.length = n;  */\n    if (e->e1->op == TOKarraylength)\n      {\n\t/* Assignment to an array's length property; resize the array.  */\n\tArrayLengthExp *ale = (ArrayLengthExp *) e->e1;\n\ttree newlength = convert_expr (build_expr (e->e2), e->e2->type,\n\t\t\t\t       Type::tsize_t);\n\ttree ptr = build_address (build_expr (ale->e1));\n\n\t/* Don't want the basetype for the element type.  */\n\tType *etype = ale->e1->type->toBasetype ()->nextOf ();\n\tlibcall_fn libcall = etype->isZeroInit ()\n\t  ? LIBCALL_ARRAYSETLENGTHT : LIBCALL_ARRAYSETLENGTHIT;\n\n\ttree result = build_libcall (libcall, ale->e1->type, 3,\n\t\t\t\t     build_typeinfo (ale->loc, ale->e1->type),\n\t\t\t\t     newlength, ptr);\n\n\tthis->result_ = d_array_length (result);\n\treturn;\n      }\n\n    /* Look for array[] = n;  */\n    if (e->e1->op == TOKslice)\n      {\n\tSliceExp *se = (SliceExp *) e->e1;\n\tType *stype = se->e1->type->toBasetype ();\n\tType *etype = stype->nextOf ()->toBasetype ();\n\n\t/* Determine if we need to run postblit or dtor.  */\n\tbool postblit = this->needs_postblit (etype) && this->lvalue_p (e->e2);\n\tbool destructor = this->needs_dtor (etype);\n\n\tif (e->memset & blockAssign)\n\t  {\n\t    /* Set a range of elements to one value.  */\n\t    tree t1 = d_save_expr (build_expr (e->e1));\n\t    tree t2 = build_expr (e->e2);\n\t    tree result;\n\n\t    if ((postblit || destructor) && e->op != TOKblit)\n\t      {\n\t\tlibcall_fn libcall = (e->op == TOKconstruct)\n\t\t  ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN;\n\t\t/* So we can call postblits on const/immutable objects.  */\n\t\tType *tm = etype->unSharedOf ()->mutableOf ();\n\t\ttree ti = build_typeinfo (e->loc, tm);\n\n\t\ttree result = build_libcall (libcall, Type::tvoid, 4,\n\t\t\t\t\t     d_array_ptr (t1),\n\t\t\t\t\t     build_address (t2),\n\t\t\t\t\t     d_array_length (t1), ti);\n\t\tthis->result_ = compound_expr (result, t1);\n\t\treturn;\n\t      }\n\n\t    if (integer_zerop (t2))\n\t      {\n\t\ttree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);\n\t\ttree size = size_mult_expr (d_array_length (t1),\n\t\t\t\t\t    size_int (etype->size ()));\n\n\t\tresult = build_call_expr (tmemset, 3, d_array_ptr (t1),\n\t\t\t\t\t  integer_zero_node, size);\n\t      }\n\t    else\n\t      result = build_array_set (d_array_ptr (t1),\n\t\t\t\t\td_array_length (t1), t2);\n\n\t    this->result_ = compound_expr (result, t1);\n\t  }\n\telse\n\t  {\n\t    /* Perform a memcpy operation.  */\n\t    gcc_assert (e->e2->type->ty != Tpointer);\n\n\t    if (!postblit && !destructor && !array_bounds_check ())\n\t      {\n\t\ttree t1 = d_save_expr (d_array_convert (e->e1));\n\t\ttree t2 = d_array_convert (e->e2);\n\t\ttree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);\n\t\ttree size = size_mult_expr (d_array_length (t1),\n\t\t\t\t\t    size_int (etype->size ()));\n\n\t\ttree result = build_call_expr (tmemcpy, 3, d_array_ptr (t1),\n\t\t\t\t\t       d_array_ptr (t2), size);\n\t\tthis->result_ = compound_expr (result, t1);\n\t      }\n\t    else if ((postblit || destructor) && e->op != TOKblit)\n\t      {\n\t\t/* Generate: _d_arrayassign(ti, from, to)\n\t\t\t or: _d_arrayctor(ti, from, to)  */\n\t\tlibcall_fn libcall = (e->op == TOKconstruct)\n\t\t  ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN;\n\n\t\tthis->result_ = build_libcall (libcall, e->type, 3,\n\t\t\t\t\t       build_typeinfo (e->loc, etype),\n\t\t\t\t\t       d_array_convert (e->e2),\n\t\t\t\t\t       d_array_convert (e->e1));\n\t      }\n\t    else\n\t      {\n\t\t/* Generate: _d_arraycopy()  */\n\t\tthis->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,\n\t\t\t\t\t       size_int (etype->size ()),\n\t\t\t\t\t       d_array_convert (e->e2),\n\t\t\t\t\t       d_array_convert (e->e1));\n\t      }\n\t  }\n\n\treturn;\n      }\n\n    /* Look for reference initializations.  */\n    if (e->memset & referenceInit)\n      {\n\tgcc_assert (e->op == TOKconstruct || e->op == TOKblit);\n\tgcc_assert (e->e1->op == TOKvar);\n\n\tDeclaration *decl = ((VarExp *) e->e1)->var;\n\tif (decl->storage_class & (STCout | STCref))\n\t  {\n\t    tree t2 = convert_for_assignment (build_expr (e->e2),\n\t\t\t\t\t      e->e2->type, e->e1->type);\n\t    tree t1 = build_expr (e->e1);\n\t    /* Want reference to lhs, not indirect ref.  */\n\t    t1 = TREE_OPERAND (t1, 0);\n\t    t2 = build_address (t2);\n\n\t    this->result_ = indirect_ref (build_ctype (e->type),\n\t\t\t\t\t  build_assign (INIT_EXPR, t1, t2));\n\t    return;\n\t  }\n      }\n\n    /* Other types of assignments that may require post construction.  */\n    Type *tb1 = e->e1->type->toBasetype ();\n    tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR;\n\n    /* Look for struct assignment.  */\n    if (tb1->ty == Tstruct)\n      {\n\ttree t1 = build_expr (e->e1);\n\ttree t2 = convert_for_assignment (build_expr (e->e2),\n\t\t\t\t\t  e->e2->type, e->e1->type);\n\n\t/* Look for struct = 0.  */\n\tif (e->e2->op == TOKint64)\n\t  {\n\t    /* Use memset to fill struct.  */\n\t    gcc_assert (e->op == TOKblit);\n\t    StructDeclaration *sd = ((TypeStruct *) tb1)->sym;\n\n\t    tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);\n\t    tree result = build_call_expr (tmemset, 3, build_address (t1),\n\t\t\t\t\t   t2, size_int (sd->structsize));\n\n\t    /* Maybe set-up hidden pointer to outer scope context.  */\n\t    if (sd->isNested ())\n\t      {\n\t\ttree field = get_symbol_decl (sd->vthis);\n\t\ttree value = build_vthis (sd);\n\n\t\ttree vthis_exp = modify_expr (component_ref (t1, field), value);\n\t\tresult = compound_expr (result, vthis_exp);\n\t      }\n\n\t    this->result_ = compound_expr (result, t1);\n\t  }\n\telse\n\t  this->result_ = build_assign (modifycode, t1, t2);\n\n\treturn;\n      }\n\n    /* Look for static array assignment.  */\n    if (tb1->ty == Tsarray)\n      {\n\t/* Look for array = 0.  */\n\tif (e->e2->op == TOKint64)\n\t  {\n\t    /* Use memset to fill the array.  */\n\t    gcc_assert (e->op == TOKblit);\n\n\t    tree t1 = build_expr (e->e1);\n\t    tree t2 = convert_for_assignment (build_expr (e->e2),\n\t\t\t\t\t      e->e2->type, e->e1->type);\n\t    tree size = size_int (e->e1->type->size ());\n\n\t    tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);\n\t    this->result_ = build_call_expr (tmemset, 3, build_address (t1),\n\t\t\t\t\t     t2, size);\n\t    return;\n\t  }\n\n\tType *etype = tb1->nextOf ();\n\tgcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);\n\n\t/* Determine if we need to run postblit.  */\n\tbool postblit = this->needs_postblit (etype);\n\tbool destructor = this->needs_dtor (etype);\n\tbool lvalue_p = this->lvalue_p (e->e2);\n\n\t/* Even if the elements in rhs are all rvalues and don't have\n\t   to call postblits, this assignment should call dtors on old\n\t   assigned elements.  */\n\tif ((!postblit && !destructor)\n\t    || (e->op == TOKconstruct && !lvalue_p && postblit)\n\t    || (e->op == TOKblit || e->e1->type->size () == 0))\n\t  {\n\t    tree t1 = build_expr (e->e1);\n\t    tree t2 = convert_for_assignment (build_expr (e->e2),\n\t\t\t\t\t      e->e2->type, e->e1->type);\n\n\t    this->result_ = build_assign (modifycode, t1, t2);\n\t    return;\n\t  }\n\n\tType *arrtype = (e->type->ty == Tsarray) ? etype->arrayOf () : e->type;\n\ttree result;\n\n\tif (e->op == TOKconstruct)\n\t  {\n\t    /* Generate: _d_arrayctor(ti, from, to)  */\n\t    result = build_libcall (LIBCALL_ARRAYCTOR, arrtype, 3,\n\t\t\t\t    build_typeinfo (e->loc, etype),\n\t\t\t\t    d_array_convert (e->e2),\n\t\t\t\t    d_array_convert (e->e1));\n\t  }\n\telse\n\t  {\n\t    /* Generate: _d_arrayassign_l()\n\t\t     or: _d_arrayassign_r()  */\n\t    libcall_fn libcall = (lvalue_p)\n\t      ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;\n\t    tree elembuf = build_local_temp (build_ctype (etype));\n\n\t    result = build_libcall (libcall, arrtype, 4,\n\t\t\t\t    build_typeinfo (e->loc, etype),\n\t\t\t\t    d_array_convert (e->e2),\n\t\t\t\t    d_array_convert (e->e1),\n\t\t\t\t    build_address (elembuf));\n\t  }\n\n\t/* Cast the libcall result back to a static array.  */\n\tif (e->type->ty == Tsarray)\n\t  result = indirect_ref (build_ctype (e->type),\n\t\t\t\t d_array_ptr (result));\n\n\tthis->result_ = result;\n\treturn;\n      }\n\n    /* Simple assignment.  */\n    tree t1 = build_expr (e->e1);\n    tree t2 = convert_for_assignment (build_expr (e->e2),\n\t\t\t\t      e->e2->type, e->e1->type);\n\n    this->result_ = build_assign (modifycode, t1, t2);\n  }\n\n  /* Build a postfix expression.  */\n\n  void visit (PostExp *e)\n  {\n    tree result;\n\n    if (e->op == TOKplusplus)\n      {\n\tresult = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),\n\t\t\t build_expr (e->e1), build_expr (e->e2));\n      }\n    else if (e->op == TOKminusminus)\n      {\n\tresult = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),\n\t\t\t build_expr (e->e1), build_expr (e->e2));\n      }\n    else\n      gcc_unreachable ();\n\n    TREE_SIDE_EFFECTS (result) = 1;\n    this->result_ = result;\n  }\n\n  /* Build an index expression.  */\n\n  void visit (IndexExp *e)\n  {\n    Type *tb1 = e->e1->type->toBasetype ();\n\n    if (tb1->ty == Taarray)\n      {\n\t/* Get the key for the associative array.  */\n\tType *tkey = ((TypeAArray *) tb1)->index->toBasetype ();\n\ttree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);\n\tlibcall_fn libcall;\n\ttree tinfo, ptr;\n\n\tif (e->modifiable)\n\t  {\n\t    libcall = LIBCALL_AAGETY;\n\t    ptr = build_address (build_expr (e->e1));\n\t    tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());\n\t  }\n\telse\n\t  {\n\t    libcall = LIBCALL_AAGETRVALUEX;\n\t    ptr = build_expr (e->e1);\n\t    tinfo = build_typeinfo (e->loc, tkey);\n\t  }\n\n\t/* Index the associative array.  */\n\ttree result = build_libcall (libcall, e->type->pointerTo (), 4,\n\t\t\t\t     ptr, tinfo,\n\t\t\t\t     size_int (tb1->nextOf ()->size ()),\n\t\t\t\t     build_address (key));\n\n\tif (!e->indexIsInBounds && array_bounds_check ())\n\t  {\n\t    tree tassert = (global.params.checkAction == CHECKACTION_C)\n\t      ? build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0)\n\t      : d_assert_call (e->loc, LIBCALL_ARRAY_BOUNDS);\n\n\t    result = d_save_expr (result);\n\t    result = build_condition (TREE_TYPE (result),\n\t\t\t\t      d_truthvalue_conversion (result),\n\t\t\t\t      result, tassert);\n\t  }\n\n\tthis->result_ = indirect_ref (build_ctype (e->type), result);\n      }\n    else\n      {\n\t/* Get the data pointer and length for static and dynamic arrays.  */\n\ttree array = d_save_expr (build_expr (e->e1));\n\ttree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());\n\n\ttree length = NULL_TREE;\n\tif (tb1->ty != Tpointer)\n\t  length = get_array_length (array, tb1);\n\telse\n\t  gcc_assert (e->lengthVar == NULL);\n\n\t/* The __dollar variable just becomes a placeholder for the\n\t   actual length.  */\n\tif (e->lengthVar)\n\t  e->lengthVar->csym = length;\n\n\t/* Generate the index.  */\n\ttree index = build_expr (e->e2);\n\n\t/* If it's a static array and the index is constant, the front end has\n\t   already checked the bounds.  */\n\tif (tb1->ty != Tpointer && !e->indexIsInBounds)\n\t  index = build_bounds_condition (e->e2->loc, index, length, false);\n\n\t/* Index the .ptr.  */\n\tptr = void_okay_p (ptr);\n\tthis->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),\n\t\t\t\t      build_array_index (ptr, index));\n      }\n  }\n\n  /* Build a comma expression.  The type is the type of the right operand.  */\n\n  void visit (CommaExp *e)\n  {\n    tree t1 = build_expr (e->e1);\n    tree t2 = build_expr (e->e2);\n    tree type = e->type ? build_ctype (e->type) : void_type_node;\n\n    this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);\n  }\n\n  /* Build an array length expression.  Returns the number of elements\n     in the array.  The result is of type size_t.  */\n\n  void visit (ArrayLengthExp *e)\n  {\n    if (e->e1->type->toBasetype ()->ty == Tarray)\n      this->result_ = d_array_length (build_expr (e->e1));\n    else\n      {\n\t/* Static arrays have already been handled by the front-end.  */\n\terror (\"unexpected type for array length: %qs\", e->type->toChars ());\n\tthis->result_ = error_mark_node;\n      }\n  }\n\n  /* Build a delegate pointer expression.  This will return the frame\n     pointer value as a type void*.  */\n\n  void visit (DelegatePtrExp *e)\n  {\n    tree t1 = build_expr (e->e1);\n    this->result_ = delegate_object (t1);\n  }\n\n  /* Build a delegate function pointer expression.  This will return the\n     function pointer value as a function type.  */\n\n  void visit (DelegateFuncptrExp *e)\n  {\n    tree t1 = build_expr (e->e1);\n    this->result_ = delegate_method (t1);\n  }\n\n  /* Build a slice expression.  */\n\n  void visit (SliceExp *e)\n  {\n    Type *tb = e->type->toBasetype ();\n    Type *tb1 = e->e1->type->toBasetype ();\n    gcc_assert (tb->ty == Tarray || tb->ty == Tsarray);\n\n    /* Use convert-to-dynamic-array code if possible.  */\n    if (!e->lwr)\n      {\n\ttree result = build_expr (e->e1);\n\tif (e->e1->type->toBasetype ()->ty == Tsarray)\n\t  result = convert_expr (result, e->e1->type, e->type);\n\n\tthis->result_ = result;\n\treturn;\n      }\n    else\n      gcc_assert (e->upr != NULL);\n\n    /* Get the data pointer and length for static and dynamic arrays.  */\n    tree array = d_save_expr (build_expr (e->e1));\n    tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());\n    tree length = NULL_TREE;\n\n    /* Our array is already a SAVE_EXPR if necessary, so we don't make length\n       a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array.  */\n    if (tb1->ty != Tpointer)\n      length = get_array_length (array, tb1);\n    else\n      gcc_assert (e->lengthVar == NULL);\n\n    /* The __dollar variable just becomes a placeholder for the\n       actual length.  */\n    if (e->lengthVar)\n      e->lengthVar->csym = length;\n\n    /* Generate upper and lower bounds.  */\n    tree lwr_tree = d_save_expr (build_expr (e->lwr));\n    tree upr_tree = d_save_expr (build_expr (e->upr));\n\n    /* If the upper bound has any side effects, then the lower bound should be\n       copied to a temporary always.  */\n    if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)\n      lwr_tree = save_expr (lwr_tree);\n\n    /* Adjust the .ptr offset.  */\n    if (!integer_zerop (lwr_tree))\n      {\n\ttree ptrtype = TREE_TYPE (ptr);\n\tptr = build_array_index (void_okay_p (ptr), lwr_tree);\n\tptr = build_nop (ptrtype, ptr);\n      }\n    else\n      lwr_tree = NULL_TREE;\n\n    /* Nothing more to do for static arrays, their bounds checking has been\n       done at compile-time.  */\n    if (tb->ty == Tsarray)\n      {\n\tthis->result_ = indirect_ref (build_ctype (e->type), ptr);\n\treturn;\n      }\n    else\n      gcc_assert (tb->ty == Tarray);\n\n    /* Generate bounds checking code.  */\n    tree newlength;\n\n    if (!e->upperIsInBounds)\n      {\n\tif (length)\n\t  {\n\t    newlength = build_bounds_condition (e->upr->loc, upr_tree,\n\t\t\t\t\t\tlength, true);\n\t  }\n\telse\n\t  {\n\t    /* Still need to check bounds lwr <= upr for pointers.  */\n\t    gcc_assert (tb1->ty == Tpointer);\n\t    newlength = upr_tree;\n\t  }\n      }\n    else\n      newlength = upr_tree;\n\n    if (lwr_tree)\n      {\n\t/* Enforces lwr <= upr.  No need to check lwr <= length as\n\t   we've already ensured that upr <= length.  */\n\tif (!e->lowerIsLessThanUpper)\n\t  {\n\t    tree cond = build_bounds_condition (e->lwr->loc, lwr_tree,\n\t\t\t\t\t\tupr_tree, true);\n\n\t    /* When bounds checking is off, the index value is\n\t       returned directly.  */\n\t    if (cond != lwr_tree)\n\t      newlength = compound_expr (cond, newlength);\n\t  }\n\n\t/* Need to ensure lwr always gets evaluated first, as it may be a\n\t   function call.  Generates (lwr, upr) - lwr.  */\n\tnewlength = fold_build2 (MINUS_EXPR, TREE_TYPE (newlength),\n\t\t\t\t compound_expr (lwr_tree, newlength), lwr_tree);\n      }\n\n    tree result = d_array_value (build_ctype (e->type), newlength, ptr);\n    this->result_ = compound_expr (array, result);\n  }\n\n  /* Build a cast expression, which converts the given unary expression to the\n     type of result.  */\n\n  void visit (CastExp *e)\n  {\n    Type *ebtype = e->e1->type->toBasetype ();\n    Type *tbtype = e->to->toBasetype ();\n    tree result = build_expr (e->e1, this->constp_);\n\n    /* Just evaluate e1 if it has any side effects.  */\n    if (tbtype->ty == Tvoid)\n      this->result_ = build_nop (build_ctype (tbtype), result);\n    else\n      this->result_ = convert_expr (result, ebtype, tbtype);\n  }\n\n  /* Build a delete expression.  */\n\n  void visit (DeleteExp *e)\n  {\n    tree t1 = build_expr (e->e1);\n    Type *tb1 = e->e1->type->toBasetype ();\n\n    if (tb1->ty == Tclass)\n      {\n\t/* For class object references, if there is a destructor for that class,\n\t   the destructor is called for the object instance.  */\n\tlibcall_fn libcall;\n\n\tif (e->e1->op == TOKvar)\n\t  {\n\t    VarDeclaration *v = ((VarExp *) e->e1)->var->isVarDeclaration ();\n\t    if (v && v->onstack)\n\t      {\n\t\tlibcall = tb1->isClassHandle ()->isInterfaceDeclaration ()\n\t\t  ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;\n\n\t\tthis->result_ = build_libcall (libcall, Type::tvoid, 1, t1);\n\t\treturn;\n\t      }\n\t  }\n\n\t/* Otherwise, the garbage collector is called to immediately free the\n\t   memory allocated for the class instance.  */\n\tlibcall = tb1->isClassHandle ()->isInterfaceDeclaration ()\n\t  ? LIBCALL_DELINTERFACE : LIBCALL_DELCLASS;\n\n\tt1 = build_address (t1);\n\tthis->result_ = build_libcall (libcall, Type::tvoid, 1, t1);\n      }\n    else if (tb1->ty == Tarray)\n      {\n\t/* For dynamic arrays, the garbage collector is called to immediately\n\t   release the memory.  */\n\tType *telem = tb1->nextOf ()->baseElemOf ();\n\ttree ti = null_pointer_node;\n\n\tif (telem->ty == Tstruct)\n\t  {\n\t    /* Might need to run destructor on array contents.  */\n\t    TypeStruct *ts = (TypeStruct *) telem;\n\t    if (ts->sym->dtor)\n\t      ti = build_typeinfo (e->loc, tb1->nextOf ());\n\t  }\n\n\t/* Generate: _delarray_t (&t1, ti);  */\n\tthis->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,\n\t\t\t\t       build_address (t1), ti);\n      }\n    else if (tb1->ty == Tpointer)\n      {\n\t/* For pointers to a struct instance, if the struct has overloaded\n\t   operator delete, then that operator is called.  */\n\tt1 = build_address (t1);\n\tType *tnext = ((TypePointer *)tb1)->next->toBasetype ();\n\n\tif (tnext->ty == Tstruct)\n\t  {\n\t    TypeStruct *ts = (TypeStruct *)tnext;\n\t    if (ts->sym->dtor)\n\t      {\n\t\ttree ti = build_typeinfo (e->loc, tnext);\n\t\tthis->result_ = build_libcall (LIBCALL_DELSTRUCT, Type::tvoid,\n\t\t\t\t\t       2, t1, ti);\n\t\treturn;\n\t      }\n\t  }\n\n\t/* Otherwise, the garbage collector is called to immediately free the\n\t   memory allocated for the pointer.  */\n\tthis->result_ = build_libcall (LIBCALL_DELMEMORY, Type::tvoid, 1, t1);\n      }\n    else\n      {\n\terror (\"don't know how to delete %qs\", e->e1->toChars ());\n\tthis->result_ = error_mark_node;\n      }\n  }\n\n  /* Build a remove expression, which removes a particular key from an\n     associative array.  */\n\n  void visit (RemoveExp *e)\n  {\n    /* Check that the array is actually an associative array.  */\n    if (e->e1->type->toBasetype ()->ty == Taarray)\n      {\n\tType *tb = e->e1->type->toBasetype ();\n\tType *tkey = ((TypeAArray *) tb)->index->toBasetype ();\n\ttree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);\n\n\tthis->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,\n\t\t\t\t       build_expr (e->e1),\n\t\t\t\t       build_typeinfo (e->loc, tkey),\n\t\t\t\t       build_address (index));\n      }\n    else\n      {\n\terror (\"%qs is not an associative array\", e->e1->toChars ());\n\tthis->result_ = error_mark_node;\n      }\n  }\n\n  /* Build an unary not expression.  */\n\n  void visit (NotExp *e)\n  {\n    tree result = convert_for_condition (build_expr (e->e1), e->e1->type);\n    /* Need to convert to boolean type or this will fail.  */\n    result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);\n\n    this->result_ = d_convert (build_ctype (e->type), result);\n  }\n\n  /* Build a compliment expression, where all the bits in the value are\n     complemented.  Note: unlike in C, the usual integral promotions\n     are not performed prior to the complement operation.  */\n\n  void visit (ComExp *e)\n  {\n    TY ty1 = e->e1->type->toBasetype ()->ty;\n    gcc_assert (ty1 != Tarray && ty1 != Tsarray);\n\n    this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),\n\t\t\t\t build_expr (e->e1));\n  }\n\n  /* Build an unary negation expression.  */\n\n  void visit (NegExp *e)\n  {\n    TY ty1 = e->e1->type->toBasetype ()->ty;\n    gcc_assert (ty1 != Tarray && ty1 != Tsarray);\n\n    tree type = build_ctype (e->type);\n    tree expr = build_expr (e->e1);\n\n    /* If the operation needs excess precision.  */\n    tree eptype = excess_precision_type (type);\n    if (eptype != NULL_TREE)\n      expr = d_convert (eptype, expr);\n    else\n      eptype = type;\n\n    tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);\n    this->result_ = d_convert (type, ret);\n  }\n\n  /* Build a pointer index expression.  */\n\n  void visit (PtrExp *e)\n  {\n    Type *tnext = NULL;\n    size_t offset;\n    tree result;\n\n    if (e->e1->op == TOKadd)\n      {\n\tBinExp *be = (BinExp *) e->e1;\n\tif (be->e1->op == TOKaddress\n\t    && be->e2->isConst () && be->e2->type->isintegral ())\n\t  {\n\t    Expression *ae = ((AddrExp *) be->e1)->e1;\n\t    tnext = ae->type->toBasetype ();\n\t    result = build_expr (ae);\n\t    offset = be->e2->toUInteger ();\n\t  }\n      }\n    else if (e->e1->op == TOKsymoff)\n      {\n\tSymOffExp *se = (SymOffExp *) e->e1;\n\tif (!declaration_reference_p (se->var))\n\t  {\n\t    tnext = se->var->type->toBasetype ();\n\t    result = get_decl_tree (se->var);\n\t    offset = se->offset;\n\t  }\n      }\n\n    /* Produce better code by converting *(#record + n) to\n       COMPONENT_REFERENCE.  Otherwise, the variable will always be\n       allocated in memory because its address is taken.  */\n    if (tnext && tnext->ty == Tstruct)\n      {\n\tStructDeclaration *sd = ((TypeStruct *) tnext)->sym;\n\n\tfor (size_t i = 0; i < sd->fields.dim; i++)\n\t  {\n\t    VarDeclaration *field = sd->fields[i];\n\n\t    if (field->offset == offset\n\t\t&& same_type_p (field->type, e->type))\n\t      {\n\t\t/* Catch errors, backend will ICE otherwise.  */\n\t\tif (error_operand_p (result))\n\t\t  this->result_ = result;\n\t\telse\n\t\t  {\n\t\t    result  = component_ref (result, get_symbol_decl (field));\n\t\t    this->result_ = result;\n\t\t  }\n\t\treturn;\n\t      }\n\t    else if (field->offset > offset)\n\t      break;\n\t  }\n      }\n\n    this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));\n  }\n\n  /* Build an unary address expression.  */\n\n  void visit (AddrExp *e)\n  {\n    tree type = build_ctype (e->type);\n    tree exp;\n\n    /* The frontend optimizer can convert const symbol into a struct literal.\n       Taking the address of a struct literal is otherwise illegal.  */\n    if (e->e1->op == TOKstructliteral)\n      {\n\tStructLiteralExp *sle = ((StructLiteralExp *) e->e1)->origin;\n\tgcc_assert (sle != NULL);\n\n\t/* Build the reference symbol, the decl is built first as the\n\t   initializer may have recursive references.  */\n\tif (!sle->sym)\n\t  {\n\t    sle->sym = build_artificial_decl (build_ctype (sle->type),\n\t\t\t\t\t      NULL_TREE, \"S\");\n\t    DECL_INITIAL (sle->sym) = build_expr (sle, true);\n\t    d_pushdecl (sle->sym);\n\t    rest_of_decl_compilation (sle->sym, 1, 0);\n\t  }\n\n\texp = sle->sym;\n      }\n    else\n      exp = build_expr (e->e1, this->constp_);\n\n    TREE_CONSTANT (exp) = 0;\n    this->result_ = d_convert (type, build_address (exp));\n  }\n\n  /* Build a function call expression.  */\n\n  void visit (CallExp *e)\n  {\n    Type *tb = e->e1->type->toBasetype ();\n    Expression *e1b = e->e1;\n\n    tree callee = NULL_TREE;\n    tree object = NULL_TREE;\n    tree cleanup = NULL_TREE;\n    TypeFunction *tf = NULL;\n\n    /* Calls to delegates can sometimes look like this.  */\n    if (e1b->op == TOKcomma)\n      {\n\te1b = ((CommaExp *) e1b)->e2;\n\tgcc_assert (e1b->op == TOKvar);\n\n\tDeclaration *var = ((VarExp *) e1b)->var;\n\tgcc_assert (var->isFuncDeclaration () && !var->needThis ());\n      }\n\n    if (e1b->op == TOKdotvar && tb->ty != Tdelegate)\n      {\n\tDotVarExp *dve = (DotVarExp *) e1b;\n\n\t/* Don't modify the static initializer for struct literals.  */\n\tif (dve->e1->op == TOKstructliteral)\n\t  {\n\t    StructLiteralExp *sle = (StructLiteralExp *) dve->e1;\n\t    sle->useStaticInit = false;\n\t  }\n\n\tFuncDeclaration *fd = dve->var->isFuncDeclaration ();\n\tif (fd != NULL)\n\t  {\n\t    /* Get the correct callee from the DotVarExp object.  */\n\t    tree fndecl = get_symbol_decl (fd);\n\t    AggregateDeclaration *ad = fd->isThis ();\n\n\t    /* Static method; ignore the object instance.  */\n\t    if (!ad)\n\t      callee = build_address (fndecl);\n\t    else\n\t      {\n\t\ttree thisexp = build_expr (dve->e1);\n\n\t\t/* When constructing temporaries, if the constructor throws,\n\t\t   then the object is destructed even though it is not a fully\n\t\t   constructed object yet.  And so this call will need to be\n\t\t   moved inside the TARGET_EXPR_INITIAL slot.  */\n\t\tif (fd->isCtorDeclaration ()\n\t\t    && TREE_CODE (thisexp) == COMPOUND_EXPR\n\t\t    && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR\n\t\t    && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))\n\t\t  {\n\t\t    cleanup = TREE_OPERAND (thisexp, 0);\n\t\t    thisexp = TREE_OPERAND (thisexp, 1);\n\t\t  }\n\n\t\t/* Want reference to 'this' object.  */\n\t\tif (!POINTER_TYPE_P (TREE_TYPE (thisexp)))\n\t\t  thisexp = build_address (thisexp);\n\n\t\t/* Make the callee a virtual call.  */\n\t\tif (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)\n\t\t  {\n\t\t    tree fntype = build_pointer_type (TREE_TYPE (fndecl));\n\t\t    tree thistype = build_ctype (ad->handleType ());\n\t\t    thisexp = build_nop (thistype, d_save_expr (thisexp));\n\t\t    fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);\n\t\t  }\n\t\telse\n\t\t  fndecl = build_address (fndecl);\n\n\t\tcallee = build_method_call (fndecl, thisexp, fd->type);\n\t      }\n\t  }\n      }\n\n    if (callee == NULL_TREE)\n      callee = build_expr (e1b);\n\n    if (METHOD_CALL_EXPR (callee))\n      {\n\t/* This could be a delegate expression (TY == Tdelegate), but not\n\t   actually a delegate variable.  */\n\tif (e1b->op == TOKdotvar)\n\t  {\n\t    /* This gets the true function type, getting the function type\n\t       from e1->type can sometimes be incorrect, such as when calling\n\t       a 'ref' return function.  */\n\t    tf = get_function_type (((DotVarExp *) e1b)->var->type);\n\t  }\n\telse\n\t  tf = get_function_type (tb);\n\n\textract_from_method_call (callee, callee, object);\n      }\n    else if (tb->ty == Tdelegate)\n      {\n\t/* Delegate call, extract .object and .funcptr from var.  */\n\tcallee = d_save_expr (callee);\n\ttf = get_function_type (tb);\n\tobject = delegate_object (callee);\n\tcallee = delegate_method (callee);\n      }\n    else if (e1b->op == TOKvar)\n      {\n\tFuncDeclaration *fd = ((VarExp *) e1b)->var->isFuncDeclaration ();\n\tgcc_assert (fd != NULL);\n\ttf = get_function_type (fd->type);\n\n\tif (fd->isNested ())\n\t  {\n\t    /* Maybe re-evaluate symbol storage treating 'fd' as public.  */\n\t    if (call_by_alias_p (d_function_chain->function, fd))\n\t      TREE_PUBLIC (callee) = 1;\n\n\t    object = get_frame_for_symbol (fd);\n\t  }\n\telse if (fd->needThis ())\n\t  {\n\t    error_at (make_location_t (e1b->loc),\n\t\t      \"need %<this%> to access member %qs\", fd->toChars ());\n\t    /* Continue compiling...  */\n\t    object = null_pointer_node;\n\t  }\n      }\n    else\n      {\n\t/* Normal direct function call.  */\n\ttf = get_function_type (tb);\n      }\n\n    gcc_assert (tf != NULL);\n\n    /* Now we have the type, callee and maybe object reference,\n       build the call expression.  */\n    tree exp = d_build_call (tf, callee, object, e->arguments);\n\n    if (tf->isref)\n      exp = build_deref (exp);\n\n    /* Some library calls are defined to return a generic type.\n       this->type is the real type we want to return.  */\n    if (e->type->isTypeBasic ())\n      exp = d_convert (build_ctype (e->type), exp);\n\n    /* If this call was found to be a constructor for a temporary with a\n       cleanup, then move the call inside the TARGET_EXPR.  The original\n       initializer is turned into an assignment, to keep its side effect.  */\n    if (cleanup != NULL_TREE)\n      {\n\ttree init = TARGET_EXPR_INITIAL (cleanup);\n\ttree slot = TARGET_EXPR_SLOT (cleanup);\n\td_mark_addressable (slot);\n\tinit = build_assign (INIT_EXPR, slot, init);\n\n\tTARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);\n\texp = cleanup;\n      }\n\n    this->result_ = exp;\n  }\n\n  /* Build a delegate expression.  */\n\n  void visit (DelegateExp *e)\n  {\n    if (e->func->semanticRun == PASSsemantic3done)\n      {\n\t/* Add the function as nested function if it belongs to this module.\n\t   ie: it is a member of this module, or it is a template instance.  */\n\tDsymbol *owner = e->func->toParent ();\n\twhile (!owner->isTemplateInstance () && owner->toParent ())\n\t  owner = owner->toParent ();\n\tif (owner->isTemplateInstance () || owner == d_function_chain->module)\n\t  build_decl_tree (e->func);\n      }\n\n    tree fndecl;\n    tree object;\n\n    if (e->func->isNested ())\n      {\n\tif (e->e1->op == TOKnull)\n\t  object = build_expr (e->e1);\n\telse\n\t  object = get_frame_for_symbol (e->func);\n\n\tfndecl = build_address (get_symbol_decl (e->func));\n      }\n    else\n      {\n\tif (!e->func->isThis ())\n\t  {\n\t    error (\"delegates are only for non-static functions\");\n\t    this->result_ = error_mark_node;\n\t    return;\n\t  }\n\n\tobject = build_expr (e->e1);\n\n\t/* Want reference to `this' object.  */\n\tif (e->e1->type->ty != Tclass && e->e1->type->ty != Tpointer)\n\t  object = build_address (object);\n\n\t/* Object reference could be the outer `this' field of a class or\n\t   closure of type `void*'.  Cast it to the right type.  */\n\tif (e->e1->type->ty == Tclass)\n\t  object = d_convert (build_ctype (e->e1->type), object);\n\n\tfndecl = get_symbol_decl (e->func);\n\n\t/* Get pointer to function out of the virtual table.  */\n\tif (e->func->isVirtual () && !e->func->isFinalFunc ()\n\t    && e->e1->op != TOKsuper && e->e1->op != TOKdottype)\n\t  {\n\t    tree fntype = build_pointer_type (TREE_TYPE (fndecl));\n\t    object = d_save_expr (object);\n\t    fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);\n\t  }\n\telse\n\t  fndecl = build_address (fndecl);\n      }\n\n    this->result_ = build_method_call (fndecl, object, e->type);\n  }\n\n  /* Build a type component expression.  */\n\n  void visit (DotTypeExp *e)\n  {\n    /* Just a pass through to underlying expression.  */\n    this->result_ = build_expr (e->e1);\n  }\n\n  /* Build a component reference expression.  */\n\n  void visit (DotVarExp *e)\n  {\n    VarDeclaration *vd = e->var->isVarDeclaration ();\n\n    /* This could also be a function, but relying on that being taken\n       care of by the visitor interface for CallExp.  */\n    if (vd != NULL)\n      {\n\tif (!vd->isField ())\n\t  this->result_ = get_decl_tree (vd);\n\telse\n\t  {\n\t    tree object = build_expr (e->e1);\n\n\t    if (e->e1->type->toBasetype ()->ty != Tstruct)\n\t      object = build_deref (object);\n\n\t    this->result_ = component_ref (object, get_symbol_decl (vd));\n\t  }\n      }\n    else\n      {\n\terror (\"%qs is not a field, but a %qs\",\n\t       e->var->toChars (), e->var->kind ());\n\tthis->result_ = error_mark_node;\n      }\n  }\n\n  /* Build an assert expression, used to declare conditions that must hold at\n     that a given point in the program.  */\n\n  void visit (AssertExp *e)\n  {\n    Type *tb1 = e->e1->type->toBasetype ();\n    tree arg = build_expr (e->e1);\n    tree tmsg = NULL_TREE;\n    tree assert_pass = void_node;\n    tree assert_fail;\n\n    if (global.params.useAssert == CHECKENABLEon\n\t&& global.params.checkAction == CHECKACTION_D)\n      {\n\t/* Generate: ((bool) e1  ? (void)0 : _d_assert (...))\n\t\t or: (e1 != null ? e1._invariant() : _d_assert (...))  */\n\tbool unittest_p = d_function_chain->function->isUnitTestDeclaration ();\n\tlibcall_fn libcall;\n\n\tif (e->msg)\n\t  {\n\t    tmsg = build_expr_dtor (e->msg);\n\t    libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;\n\t  }\n\telse\n\t  libcall = unittest_p ? LIBCALL_UNITTEST : LIBCALL_ASSERT;\n\n\t/* Build a call to _d_assert().  */\n\tassert_fail = d_assert_call (e->loc, libcall, tmsg);\n\n\tif (global.params.useInvariants)\n\t  {\n\t    /* If the condition is a D class or struct object with an invariant,\n\t       call it if the condition result is true.  */\n\t    if (tb1->ty == Tclass)\n\t      {\n\t\tClassDeclaration *cd = tb1->isClassHandle ();\n\t\tif (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())\n\t\t  {\n\t\t    arg = d_save_expr (arg);\n\t\t    assert_pass = build_libcall (LIBCALL_INVARIANT,\n\t\t\t\t\t\t Type::tvoid, 1, arg);\n\t\t  }\n\t      }\n\t    else if (tb1->ty == Tpointer && tb1->nextOf ()->ty == Tstruct)\n\t      {\n\t\tStructDeclaration *sd = ((TypeStruct *) tb1->nextOf ())->sym;\n\t\tif (sd->inv != NULL)\n\t\t  {\n\t\t    Expressions args;\n\t\t    arg = d_save_expr (arg);\n\t\t    assert_pass = d_build_call_expr (sd->inv, arg, &args);\n\t\t  }\n\t      }\n\t  }\n      }\n    else if (global.params.useAssert == CHECKENABLEon\n\t     && global.params.checkAction == CHECKACTION_C)\n      {\n\t/* Generate: __builtin_trap()  */\n\ttree fn = builtin_decl_explicit (BUILT_IN_TRAP);\n\tassert_fail = build_call_expr (fn, 0);\n      }\n    else\n      {\n\t/* Assert contracts are turned off, if the contract condition has no\n\t   side effects can still use it as a predicate for the optimizer.  */\n\tif (TREE_SIDE_EFFECTS (arg))\n\t  {\n\t    this->result_ = void_node;\n\t    return;\n\t  }\n\n\tassert_fail = build_predict_expr (PRED_NORETURN, NOT_TAKEN);\n      }\n\n    /* Build condition that we are asserting in this contract.  */\n    tree condition = convert_for_condition (arg, e->e1->type);\n\n    /* We expect the condition to always be true, as what happens if an assert\n       contract is false is undefined behavior.  */\n    tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);\n    tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));\n    tree pred_type = TREE_VALUE (arg_types);\n    tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));\n\n    condition = build_call_expr (fn, 2, d_convert (pred_type, condition),\n\t\t\t\t build_int_cst (expected_type, 1));\n    condition = d_truthvalue_conversion (condition);\n\n    this->result_ = build_vcondition (condition, assert_pass, assert_fail);\n  }\n\n  /* Build a declaration expression.  */\n\n  void visit (DeclarationExp *e)\n  {\n    /* Compile the declaration.  */\n    push_stmt_list ();\n    build_decl_tree (e->declaration);\n    tree result = pop_stmt_list ();\n\n    /* Construction of an array for typesafe-variadic function arguments\n       can cause an empty STMT_LIST here.  This can causes problems\n       during gimplification.  */\n    if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))\n      result = build_empty_stmt (input_location);\n\n    this->result_ = result;\n  }\n\n  /* Build a typeid expression.  Returns an instance of class TypeInfo\n     corresponding to.  */\n\n  void visit (TypeidExp *e)\n  {\n    if (Type *tid = isType (e->obj))\n      {\n\ttree ti = build_typeinfo (e->loc, tid);\n\n\t/* If the typeinfo is at an offset.  */\n\tif (tid->vtinfo->offset)\n\t  ti = build_offset (ti, size_int (tid->vtinfo->offset));\n\n\tthis->result_ = build_nop (build_ctype (e->type), ti);\n      }\n    else if (Expression *tid = isExpression (e->obj))\n      {\n\tType *type = tid->type->toBasetype ();\n\tassert (type->ty == Tclass);\n\n\t/* Generate **classptr to get the classinfo.  */\n\ttree ci = build_expr (tid);\n\tci = indirect_ref (ptr_type_node, ci);\n\tci = indirect_ref (ptr_type_node, ci);\n\n\t/* Add extra indirection for interfaces.  */\n\tif (((TypeClass *) type)->sym->isInterfaceDeclaration ())\n\t  ci = indirect_ref (ptr_type_node, ci);\n\n\tthis->result_ = build_nop (build_ctype (e->type), ci);\n      }\n    else\n      gcc_unreachable ();\n  }\n\n  /* Build a function/lambda expression.  */\n\n  void visit (FuncExp *e)\n  {\n    Type *ftype = e->type->toBasetype ();\n\n    /* This check is for lambda's, remove 'vthis' as function isn't nested.  */\n    if (e->fd->tok == TOKreserved && ftype->ty == Tpointer)\n      {\n\te->fd->tok = TOKfunction;\n\te->fd->vthis = NULL;\n      }\n\n    /* Compile the function literal body.  */\n    build_decl_tree (e->fd);\n\n    /* If nested, this will be a trampoline.  */\n    if (e->fd->isNested ())\n      {\n\ttree func = build_address (get_symbol_decl (e->fd));\n\ttree object;\n\n\tif (this->constp_)\n\t  {\n\t    /* Static delegate variables have no context pointer.  */\n\t    object = null_pointer_node;\n\t    this->result_ = build_method_call (func, object, e->fd->type);\n\t    TREE_CONSTANT (this->result_) = 1;\n\t  }\n\telse\n\t  {\n\t    object = get_frame_for_symbol (e->fd);\n\t    this->result_ = build_method_call (func, object, e->fd->type);\n\t  }\n      }\n    else\n      {\n\tthis->result_ = build_nop (build_ctype (e->type),\n\t\t\t\t   build_address (get_symbol_decl (e->fd)));\n      }\n  }\n\n  /* Build a halt expression.  */\n\n  void visit (HaltExp *)\n  {\n    /* Should we use trap() or abort()?  */\n    tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);\n    this->result_ = build_call_expr (ttrap, 0);\n  }\n\n  /* Build a symbol pointer offset expression.  */\n\n  void visit (SymOffExp *e)\n  {\n    /* Build the address and offset of the symbol.  */\n    size_t soffset = ((SymOffExp *) e)->offset;\n    tree result = get_decl_tree (e->var);\n    TREE_USED (result) = 1;\n\n    if (declaration_reference_p (e->var))\n      gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));\n    else\n      result = build_address (result);\n\n    if (!soffset)\n      result = d_convert (build_ctype (e->type), result);\n    else\n      {\n\ttree offset = size_int (soffset);\n\tresult = build_nop (build_ctype (e->type),\n\t\t\t    build_offset (result, offset));\n      }\n\n    this->result_ = result;\n  }\n\n  /* Build a variable expression.  */\n\n  void visit (VarExp *e)\n  {\n    if (e->var->needThis ())\n      {\n\terror (\"need %<this%> to access member %qs\", e->var->ident->toChars ());\n\tthis->result_ = error_mark_node;\n\treturn;\n      }\n    else if (e->var->ident == Identifier::idPool (\"__ctfe\"))\n      {\n\t/* __ctfe is always false at run-time.  */\n\tthis->result_ = integer_zero_node;\n\treturn;\n      }\n\n    /* This check is same as is done in FuncExp for lambdas.  */\n    FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();\n    if (fld != NULL)\n      {\n\tif (fld->tok == TOKreserved)\n\t  {\n\t    fld->tok = TOKfunction;\n\t    fld->vthis = NULL;\n\t  }\n\n\t/* Compiler the function literal body.  */\n\tbuild_decl_tree (fld);\n      }\n\n    if (this->constp_)\n      {\n\t/* Want the initializer, not the expression.  */\n\tVarDeclaration *var = e->var->isVarDeclaration ();\n\tSymbolDeclaration *sd = e->var->isSymbolDeclaration ();\n\ttree init = NULL_TREE;\n\n\tif (var && (var->isConst () || var->isImmutable ())\n\t    && e->type->toBasetype ()->ty != Tsarray && var->_init)\n\t  {\n\t    if (var->inuse)\n\t      error_at (make_location_t (e->loc), \"recursive reference %qs\",\n\t\t\te->toChars ());\n\t    else\n\t      {\n\t\tvar->inuse++;\n\t\tinit = build_expr (initializerToExpression (var->_init), true);\n\t\tvar->inuse--;\n\t      }\n\t  }\n\telse if (sd && sd->dsym)\n\t  init = layout_struct_initializer (sd->dsym);\n\telse\n\t  error_at (make_location_t (e->loc), \"non-constant expression %qs\",\n\t\t    e->toChars ());\n\n\tif (init != NULL_TREE)\n\t  this->result_ = init;\n\telse\n\t  this->result_ = error_mark_node;\n      }\n    else\n      {\n\ttree result = get_decl_tree (e->var);\n\tTREE_USED (result) = 1;\n\n\t/* For variables that are references - currently only out/inout\n\t   arguments; objects don't count - evaluating the variable means\n\t   we want what it refers to.  */\n\tif (declaration_reference_p (e->var))\n\t  result = indirect_ref (build_ctype (e->var->type), result);\n\n\tthis->result_ = result;\n      }\n  }\n\n  /* Build a this variable expression.  */\n\n  void visit (ThisExp *e)\n  {\n    FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;\n    tree result = NULL_TREE;\n\n    if (e->var)\n      result = get_decl_tree (e->var);\n    else\n      {\n\tgcc_assert (fd && fd->vthis);\n\tresult = get_decl_tree (fd->vthis);\n      }\n\n    if (e->type->ty == Tstruct)\n      result = build_deref (result);\n\n    this->result_ = result;\n  }\n\n  /* Build a new expression, which allocates memory either on the garbage\n     collected heap or by using a class or struct specific allocator.  */\n\n  void visit (NewExp *e)\n  {\n    Type *tb = e->type->toBasetype ();\n    tree result;\n\n    if (e->allocator)\n      gcc_assert (e->newargs);\n\n    if (tb->ty == Tclass)\n      {\n\t/* Allocating a new class.  */\n\ttb = e->newtype->toBasetype ();\n\tgcc_assert (tb->ty == Tclass);\n\n\tClassDeclaration *cd = ((TypeClass *) tb)->sym;\n\ttree type = build_ctype (tb);\n\ttree setup_exp = NULL_TREE;\n\ttree new_call;\n\n\tif (e->onstack)\n\t  {\n\t    /* If being used as an initializer for a local variable with scope\n\t       storage class, then the instance is allocated on the stack\n\t       rather than the heap or using the class specific allocator.  */\n\t    tree var = build_local_temp (TREE_TYPE (type));\n\t    new_call = build_nop (type, build_address (var));\n\t    setup_exp = modify_expr (var, aggregate_initializer_decl (cd));\n\t  }\n\telse if (e->allocator)\n\t  {\n\t    /* Call class allocator, and copy the initializer into memory.  */\n\t    new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);\n\t    new_call = d_save_expr (new_call);\n\t    new_call = build_nop (type, new_call);\n\t    setup_exp = modify_expr (build_deref (new_call),\n\t\t\t\t     aggregate_initializer_decl (cd));\n\t  }\n\telse\n\t  {\n\t    /* Generate: _d_newclass()  */\n\t    tree arg = build_address (get_classinfo_decl (cd));\n\t    new_call = build_libcall (LIBCALL_NEWCLASS, tb, 1, arg);\n\t  }\n\n\t/* Set the context pointer for nested classes.  */\n\tif (cd->isNested ())\n\t  {\n\t    tree field = get_symbol_decl (cd->vthis);\n\t    tree value = NULL_TREE;\n\n\t    if (e->thisexp)\n\t      {\n\t\tClassDeclaration *tcd = e->thisexp->type->isClassHandle ();\n\t\tDsymbol *outer = cd->toParent2 ();\n\t\tint offset = 0;\n\n\t\tvalue = build_expr (e->thisexp);\n\t\tif (outer != tcd)\n\t\t  {\n\t\t    ClassDeclaration *ocd = outer->isClassDeclaration ();\n\t\t    gcc_assert (ocd->isBaseOf (tcd, &offset));\n\t\t    /* Could just add offset...  */\n\t\t    value = convert_expr (value, e->thisexp->type, ocd->type);\n\t\t  }\n\t      }\n\t    else\n\t      value = build_vthis (cd);\n\n\t    if (value != NULL_TREE)\n\t      {\n\t\t/* Generate: (new())->vthis = this;  */\n\t\tnew_call = d_save_expr (new_call);\n\t\tfield = component_ref (build_deref (new_call), field);\n\t\tsetup_exp = compound_expr (setup_exp,\n\t\t\t\t\t   modify_expr (field, value));\n\t      }\n\t  }\n\tnew_call = compound_expr (setup_exp, new_call);\n\n\t/* Call the class constructor.  */\n\tif (e->member)\n\t  result = d_build_call_expr (e->member, new_call, e->arguments);\n\telse\n\t  result = new_call;\n\n\tif (e->argprefix)\n\t  result = compound_expr (build_expr (e->argprefix), result);\n      }\n    else if (tb->ty == Tpointer && tb->nextOf ()->toBasetype ()->ty == Tstruct)\n      {\n\t/* Allocating memory for a new struct.  */\n\tType *htype = e->newtype->toBasetype ();\n\tgcc_assert (htype->ty == Tstruct);\n\tgcc_assert (!e->onstack);\n\n\tTypeStruct *stype = (TypeStruct *) htype;\n\tStructDeclaration *sd = stype->sym;\n\ttree new_call;\n\n\t/* Cannot new an opaque struct.  */\n\tif (sd->size (e->loc) == 0)\n\t  {\n\t    this->result_ = d_convert (build_ctype (e->type),\n\t\t\t\t       integer_zero_node);\n\t    return;\n\t  }\n\n\tif (e->allocator)\n\t  {\n\t    /* Call struct allocator.  */\n\t    new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);\n\t    new_call = build_nop (build_ctype (tb), new_call);\n\t  }\n\telse\n\t  {\n\t    /* Generate: _d_newitemT()  */\n\t    libcall_fn libcall = htype->isZeroInit ()\n\t      ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;\n\t    tree arg = build_typeinfo (e->loc, e->newtype);\n\t    new_call = build_libcall (libcall, tb, 1, arg);\n\t  }\n\n\tif (e->member || !e->arguments)\n\t  {\n\t    /* Set the context pointer for nested structs.  */\n\t    if (sd->isNested ())\n\t      {\n\t\ttree value = build_vthis (sd);\n\t\ttree field = get_symbol_decl (sd->vthis);\n\t\ttree type = build_ctype (stype);\n\n\t\tnew_call = d_save_expr (new_call);\n\t\tfield = component_ref (indirect_ref (type, new_call), field);\n\t\tnew_call = compound_expr (modify_expr (field, value), new_call);\n\t      }\n\n\t    /* Call the struct constructor.  */\n\t    if (e->member)\n\t      result = d_build_call_expr (e->member, new_call, e->arguments);\n\t    else\n\t      result = new_call;\n\t  }\n\telse\n\t  {\n\t    /* If we have a user supplied initializer, then set-up with a\n\t       struct literal.  */\n\t    if (e->arguments != NULL && sd->fields.dim != 0)\n\t      {\n\t\tStructLiteralExp *se = StructLiteralExp::create (e->loc, sd,\n\t\t\t\t\t\t\t\t e->arguments,\n\t\t\t\t\t\t\t\t htype);\n\t\tnew_call = d_save_expr (new_call);\n\t\tse->type = sd->type;\n\t\tse->sym = new_call;\n\t\tresult = compound_expr (build_expr (se), new_call);\n\t      }\n\t    else\n\t      result = new_call;\n\t  }\n\n\tif (e->argprefix)\n\t  result = compound_expr (build_expr (e->argprefix), result);\n      }\n    else if (tb->ty == Tarray)\n      {\n\t/* Allocating memory for a new D array.  */\n\ttb = e->newtype->toBasetype ();\n\tgcc_assert (tb->ty == Tarray);\n\tTypeDArray *tarray = (TypeDArray *) tb;\n\n\tgcc_assert (!e->allocator);\n\tgcc_assert (e->arguments && e->arguments->dim >= 1);\n\n\tif (e->arguments->dim == 1)\n\t  {\n\t    /* Single dimension array allocations.  */\n\t    Expression *arg = (*e->arguments)[0];\n\n\t    if (tarray->next->size () == 0)\n\t      {\n\t\t/* Array element size is unknown.  */\n\t\tthis->result_ = d_array_value (build_ctype (e->type),\n\t\t\t\t\t       size_int (0), null_pointer_node);\n\t\treturn;\n\t      }\n\n\t    libcall_fn libcall = tarray->next->isZeroInit ()\n\t      ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;\n\t    result = build_libcall (libcall, tb, 2,\n\t\t\t\t    build_typeinfo (e->loc, e->type),\n\t\t\t\t    build_expr (arg));\n\t  }\n\telse\n\t  {\n\t    /* Multidimensional array allocations.  */\n\t    vec<constructor_elt, va_gc> *elms = NULL;\n\t    Type *telem = e->newtype->toBasetype ();\n\t    tree tarray = make_array_type (Type::tsize_t, e->arguments->dim);\n\t    tree var = create_temporary_var (tarray);\n\t    tree init = build_constructor (TREE_TYPE (var), NULL);\n\n\t    for (size_t i = 0; i < e->arguments->dim; i++)\n\t      {\n\t\tExpression *arg = (*e->arguments)[i];\n\t\tCONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));\n\n\t\tgcc_assert (telem->ty == Tarray);\n\t\ttelem = telem->toBasetype ()->nextOf ();\n\t\tgcc_assert (telem);\n\t      }\n\n\t    CONSTRUCTOR_ELTS (init) = elms;\n\t    DECL_INITIAL (var) = init;\n\n\t    /* Generate: _d_newarraymTX(ti, dims)\n\t\t     or: _d_newarraymiTX(ti, dims)  */\n\t    libcall_fn libcall = telem->isZeroInit ()\n\t      ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;\n\n\t    tree tinfo = build_typeinfo (e->loc, e->type);\n\t    tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),\n\t\t\t\t       size_int (e->arguments->dim),\n\t\t\t\t       build_address (var));\n\n\t    result = build_libcall (libcall, tb, 2, tinfo, dims);\n\t    result = bind_expr (var, result);\n\t  }\n\n\tif (e->argprefix)\n\t  result = compound_expr (build_expr (e->argprefix), result);\n      }\n    else if (tb->ty == Tpointer)\n      {\n\t/* Allocating memory for a new pointer.  */\n\tTypePointer *tpointer = (TypePointer *) tb;\n\n\tif (tpointer->next->size () == 0)\n\t  {\n\t    /* Pointer element size is unknown.  */\n\t    this->result_ = d_convert (build_ctype (e->type),\n\t\t\t\t       integer_zero_node);\n\t    return;\n\t  }\n\n\tlibcall_fn libcall = tpointer->next->isZeroInit (e->loc)\n\t  ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;\n\n\ttree arg = build_typeinfo (e->loc, e->newtype);\n\tresult = build_libcall (libcall, tb, 1, arg);\n\n\tif (e->arguments && e->arguments->dim == 1)\n\t  {\n\t    result = d_save_expr (result);\n\t    tree init = modify_expr (build_deref (result),\n\t\t\t\t     build_expr ((*e->arguments)[0]));\n\t    result = compound_expr (init, result);\n\t  }\n\n\tif (e->argprefix)\n\t  result = compound_expr (build_expr (e->argprefix), result);\n      }\n    else\n      gcc_unreachable ();\n\n    this->result_ = convert_expr (result, tb, e->type);\n  }\n\n  /* Build an integer literal.  */\n\n  void visit (IntegerExp *e)\n  {\n    tree ctype = build_ctype (e->type->toBasetype ());\n    this->result_ = build_integer_cst (e->value, ctype);\n  }\n\n  /* Build a floating-point literal.  */\n\n  void visit (RealExp *e)\n  {\n    this->result_ = build_float_cst (e->value, e->type->toBasetype ());\n  }\n\n  /* Build a complex literal.  */\n\n  void visit (ComplexExp *e)\n  {\n    Type *tnext;\n\n    switch (e->type->toBasetype ()->ty)\n      {\n      case Tcomplex32:\n\ttnext = (TypeBasic *) Type::tfloat32;\n\tbreak;\n\n      case Tcomplex64:\n\ttnext = (TypeBasic *) Type::tfloat64;\n\tbreak;\n\n      case Tcomplex80:\n\ttnext = (TypeBasic *) Type::tfloat80;\n\tbreak;\n\n      default:\n\tgcc_unreachable ();\n      }\n\n    this->result_ = build_complex (build_ctype (e->type),\n\t\t\t\t   build_float_cst (creall (e->value), tnext),\n\t\t\t\t   build_float_cst (cimagl (e->value), tnext));\n  }\n\n  /* Build a string literal, all strings are null terminated except for\n     static arrays.  */\n\n  void visit (StringExp *e)\n  {\n    Type *tb = e->type->toBasetype ();\n    tree type = build_ctype (e->type);\n\n    if (tb->ty == Tsarray)\n      {\n\t/* Turn the string into a constructor for the static array.  */\n\tvec<constructor_elt, va_gc> *elms = NULL;\n\tvec_safe_reserve (elms, e->len);\n\ttree etype = TREE_TYPE (type);\n\n\tfor (size_t i = 0; i < e->len; i++)\n\t  {\n\t    tree value = build_integer_cst (e->charAt (i), etype);\n\t    CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);\n\t  }\n\n\ttree ctor = build_constructor (type, elms);\n\tTREE_CONSTANT (ctor) = 1;\n\tthis->result_ = ctor;\n      }\n    else\n      {\n\t/* Copy the string contents to a null terminated string.  */\n\tdinteger_t length = (e->len * e->sz);\n\tchar *string = XALLOCAVEC (char, length + 1);\n\tmemcpy (string, e->string, length);\n\tstring[length] = '\\0';\n\n\t/* String value and type includes the null terminator.  */\n\ttree value = build_string (length, string);\n\tTREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);\n\tvalue = build_address (value);\n\n\tif (tb->ty == Tarray)\n\t  value = d_array_value (type, size_int (e->len), value);\n\n\tTREE_CONSTANT (value) = 1;\n\tthis->result_ = d_convert (type, value);\n      }\n  }\n\n  /* Build a tuple literal.  Just an argument list that may have\n     side effects that need evaluation.  */\n\n  void visit (TupleExp *e)\n  {\n    tree result = NULL_TREE;\n\n    if (e->e0)\n      result = build_expr (e->e0);\n\n    for (size_t i = 0; i < e->exps->dim; ++i)\n      {\n\tExpression *exp = (*e->exps)[i];\n\tresult = compound_expr (result, build_expr (exp));\n      }\n\n    if (result == NULL_TREE)\n      result = void_node;\n\n    this->result_ = result;\n  }\n\n  /* Build an array literal.  The common type of the all elements is taken to\n     be the type of the array element, and all elements are implicitly\n     converted to that type.  */\n\n  void visit (ArrayLiteralExp *e)\n  {\n    Type *tb = e->type->toBasetype ();\n\n    /* Implicitly convert void[n] to ubyte[n].  */\n    if (tb->ty == Tsarray && tb->nextOf ()->toBasetype ()->ty == Tvoid)\n      tb = Type::tuns8->sarrayOf (((TypeSArray *) tb)->dim->toUInteger ());\n\n    gcc_assert (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tpointer);\n\n    /* Handle empty array literals.  */\n    if (e->elements->dim == 0)\n      {\n\tif (tb->ty == Tarray)\n\t  this->result_ = d_array_value (build_ctype (e->type),\n\t\t\t\t\t size_int (0), null_pointer_node);\n\telse\n\t  this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),\n\t\t\t\t\t     NULL);\n\n\treturn;\n      }\n\n    /* Build an expression that assigns the expressions in ELEMENTS to\n       a constructor.  */\n    vec<constructor_elt, va_gc> *elms = NULL;\n    vec_safe_reserve (elms, e->elements->dim);\n    bool constant_p = true;\n    tree saved_elems = NULL_TREE;\n\n    Type *etype = tb->nextOf ();\n    tree satype = make_array_type (etype, e->elements->dim);\n\n    for (size_t i = 0; i < e->elements->dim; i++)\n      {\n\tExpression *expr = e->getElement (i);\n\ttree value = build_expr (expr, this->constp_);\n\n\t/* Only append nonzero values, the backend will zero out the rest\n\t   of the constructor as we don't set CONSTRUCTOR_NO_CLEARING.  */\n\tif (!initializer_zerop (value))\n\t  {\n\t    if (!TREE_CONSTANT (value))\n\t      constant_p = false;\n\n\t    /* Split construction of values out of the constructor if there\n\t       may be side effects.  */\n\t    tree init = stabilize_expr (&value);\n\t    if (init != NULL_TREE)\n\t      saved_elems = compound_expr (saved_elems, init);\n\n\t    CONSTRUCTOR_APPEND_ELT (elms, size_int (i),\n\t\t\t\t    convert_expr (value, expr->type, etype));\n\t  }\n      }\n\n    /* Now return the constructor as the correct type.  For static arrays there\n       is nothing else to do.  For dynamic arrays, return a two field struct.\n       For pointers, return the address.  */\n    tree ctor = build_constructor (satype, elms);\n    tree type = build_ctype (e->type);\n\n    /* Nothing else to do for static arrays.  */\n    if (tb->ty == Tsarray || this->constp_)\n      {\n\t/* Can't take the address of the constructor, so create an anonymous\n\t   static symbol, and then refer to it.  */\n\tif (tb->ty != Tsarray)\n\t  {\n\t    tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, \"A\");\n\t    ctor = build_address (decl);\n\t    if (tb->ty == Tarray)\n\t      ctor = d_array_value (type, size_int (e->elements->dim), ctor);\n\n\t    d_pushdecl (decl);\n\t    rest_of_decl_compilation (decl, 1, 0);\n\t  }\n\n\t/* If the array literal is readonly or static.  */\n\tif (constant_p)\n\t  TREE_CONSTANT (ctor) = 1;\n\tif (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))\n\t  TREE_STATIC (ctor) = 1;\n\n\tthis->result_ = compound_expr (saved_elems, d_convert (type, ctor));\n      }\n    else\n      {\n\t/* Allocate space on the memory managed heap.  */\n\ttree mem = build_libcall (LIBCALL_ARRAYLITERALTX,\n\t\t\t\t  etype->pointerTo (), 2,\n\t\t\t\t  build_typeinfo (e->loc, etype->arrayOf ()),\n\t\t\t\t  size_int (e->elements->dim));\n\tmem = d_save_expr (mem);\n\n\t/* Now copy the constructor into memory.  */\n\ttree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);\n\ttree size = size_mult_expr (size_int (e->elements->dim),\n\t\t\t\t    size_int (tb->nextOf ()->size ()));\n\n\ttree result = build_call_expr (tmemcpy, 3, mem,\n\t\t\t\t       build_address (ctor), size);\n\n\t/* Return the array pointed to by MEM.  */\n\tresult = compound_expr (result, mem);\n\n\tif (tb->ty == Tarray)\n\t  result = d_array_value (type, size_int (e->elements->dim), result);\n\n\tthis->result_ = compound_expr (saved_elems, result);\n      }\n  }\n\n  /* Build an associative array literal.  The common type of the all keys is\n     taken to be the key type, and common type of all values the value type.\n     All keys and values are then implicitly converted as needed.  */\n\n  void visit (AssocArrayLiteralExp *e)\n  {\n    /* Want the mutable type for typeinfo reference.  */\n    Type *tb = e->type->toBasetype ()->mutableOf ();\n    gcc_assert (tb->ty == Taarray);\n\n    /* Handle empty assoc array literals.  */\n    TypeAArray *ta = (TypeAArray *) tb;\n    if (e->keys->dim == 0)\n      {\n\tthis->result_ = build_constructor (build_ctype (ta), NULL);\n\treturn;\n      }\n\n    /* Build an expression that assigns all expressions in KEYS\n       to a constructor.  */\n    vec<constructor_elt, va_gc> *kelts = NULL;\n    vec_safe_reserve (kelts, e->keys->dim);\n    for (size_t i = 0; i < e->keys->dim; i++)\n      {\n\tExpression *key = (*e->keys)[i];\n\ttree t = build_expr (key);\n\tCONSTRUCTOR_APPEND_ELT (kelts, size_int (i),\n\t\t\t\tconvert_expr (t, key->type, ta->index));\n      }\n    tree tkeys = make_array_type (ta->index, e->keys->dim);\n    tree akeys = build_constructor (tkeys, kelts);\n\n    /* Do the same with all expressions in VALUES.  */\n    vec<constructor_elt, va_gc> *velts = NULL;\n    vec_safe_reserve (velts, e->values->dim);\n    for (size_t i = 0; i < e->values->dim; i++)\n      {\n\tExpression *value = (*e->values)[i];\n\ttree t = build_expr (value);\n\tCONSTRUCTOR_APPEND_ELT (velts, size_int (i),\n\t\t\t\tconvert_expr (t, value->type, ta->next));\n      }\n    tree tvals = make_array_type (ta->next, e->values->dim);\n    tree avals = build_constructor (tvals, velts);\n\n    /* Generate: _d_assocarrayliteralTX (ti, keys, vals);  */\n    tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),\n\t\t\t       size_int (e->keys->dim), build_address (akeys));\n    tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),\n\t\t\t       size_int (e->values->dim),\n\t\t\t       build_address (avals));\n\n    tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,\n\t\t\t      build_typeinfo (e->loc, ta), keys, vals);\n\n    /* Return an associative array pointed to by MEM.  */\n    tree aatype = build_ctype (ta);\n    vec<constructor_elt, va_gc> *ce = NULL;\n    CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);\n\n    this->result_ = build_nop (build_ctype (e->type),\n\t\t\t       build_constructor (aatype, ce));\n  }\n\n  /* Build a struct literal.  */\n\n  void visit (StructLiteralExp *e)\n  {\n    /* Handle empty struct literals.  */\n    if (e->elements == NULL || e->sd->fields.dim == 0)\n      {\n\tthis->result_ = build_constructor (build_ctype (e->type), NULL);\n\treturn;\n      }\n\n    /* Building sinit trees are delayed until after frontend semantic\n       processing has complete.  Build the static initializer now.  */\n    if (e->useStaticInit && !this->constp_)\n      {\n\tthis->result_ = aggregate_initializer_decl (e->sd);\n\treturn;\n      }\n\n    /* Build a constructor that assigns the expressions in ELEMENTS\n       at each field index that has been filled in.  */\n    vec<constructor_elt, va_gc> *ve = NULL;\n    tree saved_elems = NULL_TREE;\n\n    /* CTFE may fill the hidden pointer by NullExp.  */\n    gcc_assert (e->elements->dim <= e->sd->fields.dim);\n\n    Type *tb = e->type->toBasetype ();\n    gcc_assert (tb->ty == Tstruct);\n\n    for (size_t i = 0; i < e->elements->dim; i++)\n      {\n\tExpression *exp = (*e->elements)[i];\n\tif (!exp)\n\t  continue;\n\n\tVarDeclaration *field = e->sd->fields[i];\n\tType *type = exp->type->toBasetype ();\n\tType *ftype = field->type->toBasetype ();\n\ttree value = NULL_TREE;\n\n\tif (ftype->ty == Tsarray && !same_type_p (type, ftype))\n\t  {\n\t    /* Initialize a static array with a single element.  */\n\t    tree elem = build_expr (exp, this->constp_);\n\t    elem = d_save_expr (elem);\n\n\t    if (initializer_zerop (elem))\n\t      value = build_constructor (build_ctype (ftype), NULL);\n\t    else\n\t      value = build_array_from_val (ftype, elem);\n\t  }\n\telse\n\t  {\n\t    value = convert_expr (build_expr (exp, this->constp_),\n\t\t\t\t  exp->type, field->type);\n\t  }\n\n\t/* Split construction of values out of the constructor.  */\n\ttree init = stabilize_expr (&value);\n\tif (init != NULL_TREE)\n\t  saved_elems = compound_expr (saved_elems, init);\n\n\tCONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);\n      }\n\n    /* Maybe setup hidden pointer to outer scope context.  */\n    if (e->sd->isNested () && e->elements->dim != e->sd->fields.dim\n\t&& this->constp_ == false)\n      {\n\ttree field = get_symbol_decl (e->sd->vthis);\n\ttree value = build_vthis (e->sd);\n\tCONSTRUCTOR_APPEND_ELT (ve, field, value);\n\tgcc_assert (e->useStaticInit == false);\n      }\n\n    /* Build a constructor in the correct shape of the aggregate type.  */\n    tree ctor = build_struct_literal (build_ctype (e->type), ve);\n\n    /* Nothing more to do for constant literals.  */\n    if (this->constp_)\n      {\n\t/* If the struct literal is a valid for static data.  */\n\tif (TREE_CONSTANT (ctor)\n\t    && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))\n\t  TREE_STATIC (ctor) = 1;\n\n\tthis->result_ = compound_expr (saved_elems, ctor);\n\treturn;\n      }\n\n    if (e->sym != NULL)\n      {\n\ttree var = build_deref (e->sym);\n\tctor = compound_expr (modify_expr (var, ctor), var);\n\tthis->result_ = compound_expr (saved_elems, ctor);\n      }\n    else if (e->sd->isUnionDeclaration ())\n      {\n\t/* For unions, use memset to fill holes in the object.  */\n\ttree var = build_local_temp (TREE_TYPE (ctor));\n\ttree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);\n\ttree init = build_call_expr (tmemset, 3, build_address (var),\n\t\t\t\t     size_zero_node,\n\t\t\t\t     size_int (e->sd->structsize));\n\n\tinit = compound_expr (init, saved_elems);\n\tinit = compound_expr (init, modify_expr (var, ctor));\n\tthis->result_  = compound_expr (init, var);\n      }\n    else\n      this->result_ = compound_expr (saved_elems, ctor);\n  }\n\n  /* Build a null literal.  */\n\n  void visit (NullExp *e)\n  {\n    Type *tb = e->type->toBasetype ();\n    tree value;\n\n    /* Handle certain special case conversions, where the underlying type is an\n       aggregate with a nullable interior pointer.  */\n    if (tb->ty == Tarray)\n      {\n\t/* For dynamic arrays, set length and pointer fields to zero.  */\n\tvalue = d_array_value (build_ctype (e->type), size_int (0),\n\t\t\t       null_pointer_node);\n      }\n    else if (tb->ty == Taarray)\n      {\n\t/* For associative arrays, set the pointer field to null.  */\n\tvalue = build_constructor (build_ctype (e->type), NULL);\n      }\n    else if (tb->ty == Tdelegate)\n      {\n\t/* For delegates, set the frame and function pointer to null.  */\n\tvalue = build_delegate_cst (null_pointer_node,\n\t\t\t\t    null_pointer_node, e->type);\n      }\n    else\n      value = d_convert (build_ctype (e->type), integer_zero_node);\n\n    TREE_CONSTANT (value) = 1;\n    this->result_ = value;\n  }\n\n  /* Build a vector literal.  */\n\n  void visit (VectorExp *e)\n  {\n    tree type = build_ctype (e->type);\n    tree etype = TREE_TYPE (type);\n\n    /* First handle array literal expressions.  */\n    if (e->e1->op == TOKarrayliteral)\n      {\n\tArrayLiteralExp *ale = ((ArrayLiteralExp *) e->e1);\n\tvec<constructor_elt, va_gc> *elms = NULL;\n\tbool constant_p = true;\n\n\tvec_safe_reserve (elms, ale->elements->dim);\n\tfor (size_t i = 0; i < ale->elements->dim; i++)\n\t  {\n\t    Expression *expr = ale->getElement (i);\n\t    tree value = d_convert (etype, build_expr (expr, this->constp_));\n\t    if (!CONSTANT_CLASS_P (value))\n\t      constant_p = false;\n\n\t    CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);\n\t  }\n\n\t/* Build a VECTOR_CST from a constant vector constructor.  */\n\tif (constant_p)\n\t  this->result_ = build_vector_from_ctor (type, elms);\n\telse\n\t  this->result_ = build_constructor (type, elms);\n      }\n    else\n      {\n\t/* Build constructor from single value.  */\n\ttree val = d_convert (etype, build_expr (e->e1, this->constp_));\n\tthis->result_ = build_vector_from_val (type, val);\n      }\n  }\n\n  /* Build a static class literal, return its reference.  */\n\n  void visit (ClassReferenceExp *e)\n  {\n    /* The result of build_new_class_expr is a RECORD_TYPE, we want\n       the reference.  */\n    tree var = build_address (build_new_class_expr (e));\n\n    /* If the type of this literal is an interface, the we must add the\n       interface offset to symbol.  */\n    if (this->constp_)\n      {\n\tTypeClass *tc = (TypeClass *) e->type;\n\tInterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();\n\n\tif (to != NULL)\n\t  {\n\t    ClassDeclaration *from = e->originalClass ();\n\t    int offset = 0;\n\n\t    gcc_assert (to->isBaseOf (from, &offset) != 0);\n\n\t    if (offset != 0)\n\t      var = build_offset (var, size_int (offset));\n\t  }\n      }\n\n    this->result_ = var;\n  }\n\n  /* These expressions are mainly just a placeholders in the frontend.\n     We shouldn't see them here.  */\n\n  void visit (ScopeExp *e)\n  {\n    error_at (make_location_t (e->loc), \"%qs is not an expression\",\n\t      e->toChars ());\n    this->result_ = error_mark_node;\n  }\n\n  void visit (TypeExp *e)\n  {\n    error_at (make_location_t (e->loc), \"type %qs is not an expression\",\n\t      e->toChars ());\n    this->result_ = error_mark_node;\n  }\n};\n\n\n/* Main entry point for ExprVisitor interface to generate code for\n   the Expression AST class E.  If CONST_P is true, then E is a\n   constant expression.  */\n\ntree\nbuild_expr (Expression *e, bool const_p)\n{\n  ExprVisitor v = ExprVisitor (const_p);\n  location_t saved_location = input_location;\n\n  input_location = make_location_t (e->loc);\n  e->accept (&v);\n  tree expr = v.result ();\n  input_location = saved_location;\n\n  /* Check if initializer expression is valid constant.  */\n  if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))\n    {\n      error_at (make_location_t (e->loc), \"non-constant expression %qs\",\n\t\te->toChars ());\n      return error_mark_node;\n    }\n\n  return expr;\n}\n\n/* Same as build_expr, but also calls destructors on any temporaries.  */\n\ntree\nbuild_expr_dtor (Expression *e)\n{\n  /* Codegen can be improved by determining if no exceptions can be thrown\n     between the ctor and dtor, and eliminating the ctor and dtor.  */\n  size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);\n  tree result = build_expr (e);\n\n  if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))\n    {\n      result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);\n      vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);\n    }\n\n  return result;\n}\n\n/* Same as build_expr_dtor, but handles the result of E as a return value.  */\n\ntree\nbuild_return_dtor (Expression *e, Type *type, TypeFunction *tf)\n{\n  size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);\n  tree result = build_expr (e);\n\n  /* Convert for initializing the DECL_RESULT.  */\n  result = convert_expr (result, e->type, type);\n\n  /* If we are returning a reference, take the address.  */\n  if (tf->isref)\n    result = build_address (result);\n\n  /* The decl to store the return expression.  */\n  tree decl = DECL_RESULT (cfun->decl);\n\n  /* Split comma expressions, so that the result is returned directly.  */\n  tree expr = stabilize_expr (&result);\n  result = build_assign (INIT_EXPR, decl, result);\n  result = compound_expr (expr, return_expr (result));\n\n  /* May nest the return expression inside the try/finally expression.  */\n  if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))\n    {\n      result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);\n      vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);\n    }\n\n  return result;\n}\n\n"
  },
  {
    "path": "gcc/d/gdc.texi",
    "content": "\\input texinfo @c -*-texinfo-*-\n@setfilename gdc.info\n@settitle The GNU D Compiler\n\n@c Merge the standard indexes into a single one.\n@syncodeindex fn cp\n@syncodeindex vr cp\n@syncodeindex ky cp\n@syncodeindex pg cp\n@syncodeindex tp cp\n\n@include gcc-common.texi\n\n@c Copyright years for this manual.\n@set copyrights-d 2006-2018\n\n@copying\n@c man begin COPYRIGHT\nCopyright @copyright{} @value{copyrights-d} Free Software Foundation, Inc.\n\nPermission is granted to copy, distribute and/or modify this document\nunder the terms of the GNU Free Documentation License, Version 1.3 or\nany later version published by the Free Software Foundation; with no\nInvariant Sections, no Front-Cover Texts, and no Back-Cover Texts.\nA copy of the license is included in the\n@c man end\nsection entitled ``GNU Free Documentation License''.\n@ignore\n@c man begin COPYRIGHT\nman page gfdl(7).\n@c man end\n@end ignore\n@end copying\n\n@ifinfo\n@format\n@dircategory Software development\n@direntry\n* gdc: (gdc).               A GCC-based compiler for the D language\n@end direntry\n@end format\n\n@insertcopying\n@end ifinfo\n\n@titlepage\n@title The GNU D Compiler\n@versionsubtitle\n@author David Friedman, Iain Buclaw\n\n@page\n@vskip 0pt plus 1filll\nPublished by the Free Software Foundation @*\n51 Franklin Street, Fifth Floor@*\nBoston, MA 02110-1301, USA@*\n@sp 1\n@insertcopying\n@end titlepage\n@contents\n@page\n\n@node Top\n@top Introduction\n\nThis manual describes how to use @command{gdc}, the GNU compiler for\nthe D programming language.  This manual is specifically about\n@command{gdc}.  For more information about the D programming\nlanguage in general, including language specifications and standard\npackage documentation, see @uref{http://dlang.org/}.\n\n@menu\n* Copying::                     The GNU General Public License.\n* GNU Free Documentation License::\n                                How you can share and copy this manual.\n* Invoking gdc::                How to run gdc.\n* Index::                       Index.\n@end menu\n\n\n@include gpl_v3.texi\n\n@include fdl.texi\n\n\n@node Invoking gdc\n@chapter Invoking gdc\n\n@c man title gdc A GCC-based compiler for the D language\n\n@ignore\n@c man begin SYNOPSIS gdc\ngdc [@option{-c}|@option{-S}] [@option{-g}] [@option{-pg}]\n    [@option{-O}@var{level}] [@option{-W}@var{warn}@dots{}]\n    [@option{-I}@var{dir}@dots{}] [@option{-L}@var{dir}@dots{}]\n    [@option{-f}@var{option}@dots{}] [@option{-m}@var{machine-option}@dots{}]\n    [@option{-o} @var{outfile}] [@@@var{file}] @var{infile}@dots{}\n\nOnly the most useful options are listed here; see below for the\nremainder.\n@c man end\n@c man begin SEEALSO\ngpl(7), gfdl(7), fsf-funding(7), gcc(1)\nand the Info entries for @file{gdc} and @file{gcc}.\n@c man end\n@end ignore\n\n@c man begin DESCRIPTION gdc\n\nThe @command{gdc} command is the GNU compiler for the D language and\nsupports many of the same options as @command{gcc}.  @xref{Option Summary, ,\nOption Summary, gcc, Using the GNU Compiler Collection (GCC)}.\nThis manual only documents the options specific to @command{gdc}.\n\n@c man end\n\n@menu\n* Input and Output files::  Controlling the kind of output:\n                            an executable, object files, assembler files,\n* Runtime Options::         Options controlling runtime behavior\n* Directory Options::       Where to find module files\n* Code Generation::         Options controlling the output of gdc\n* Warnings::                Options controlling warnings specific to gdc\n* Linking::                 Options influencing the linking step\n* Developer Options::       Options useful for developers of gdc\n@end menu\n\n@c man begin OPTIONS\n\n@node Input and Output files\n@section Input and Output files\n@cindex suffixes for D source\n@cindex D source file suffixes\n\nFor any given input file, the file name suffix determines what kind of\ncompilation is done.  The following kinds of input file names are supported:\n\n@table @gcctabopt\n@item @var{file}.d\nD source files.\n@item @var{file}.dd\nDdoc source files.\n@item @var{file}.di\nD interface files.\n@end table\n\nYou can specify more than one input file on the @command{gdc} command line,\neach being compiled separately in the compilation process.  If you specify a\n@code{-o @var{file}} option, all the input files are compiled together,\nproducing a single output file, named @var{file}.  This is allowed even\nwhen using @code{-S} or @code{-c}.\n\n@cindex D interface files.\nA D interface file contains only what an import of the module needs,\nrather than the whole implementation of that module.  They can be created\nby @command{gdc} from a D source file by using the @code{-H} option.\nWhen the compiler resolves an import declaration, it searches for matching\n@file{.di} files first, then for @file{.d}.\n\n@cindex Ddoc source files.\nA Ddoc source file contains code in the D macro processor language.  It is\nprimarily designed for use in producing user documentation from embedded\ncomments, with a slight affinity towards HTML generation.  If a @file{.d}\nsource file starts with the string @code{Ddoc} then it is treated as general\npurpose documentation, not as a D source file.\n\n@node Runtime Options\n@section Runtime Options\n@cindex options, runtime\n\nThese options affect the runtime behavior of programs compiled with\n@command{gdc}.\n\n@table @gcctabopt\n\n@item -fall-instantiations\n@cindex @option{-fall-instantiations}\n@cindex @option{-fno-all-instantiations}\nGenerate code for all template instantiations.  The default template emission\nstrategy is to not generate code for declarations that were either\ninstantiated speculatively, such as from @code{__traits(compiles, ...)}, or\nthat come from an imported module not being compiled.\n\n@item -fno-assert\n@cindex @option{-fassert}\n@cindex @option{-fno-assert}\nTurn off code generation for @code{assert} contracts.\n\n@item -fno-bounds-check\n@cindex @option{-fbounds-check}\n@cindex @option{-fno-bounds-check}\nTurns off array bounds checking for all functions, which can improve\nperformance for code that uses arrays extensively.  Note that this\ncan result in unpredictable behavior if the code in question actually\ndoes violate array bounds constraints.  It is safe to use this option\nif you are sure that your code never throws a @code{RangeError}.\n\n@item -fbounds-check=@var{value}\n@cindex @option{-fbounds-check=}\nAn alternative to @option{-fbounds-check} that allows more control\nas to where bounds checking is turned on or off.  The following values\nare supported:\n\n@table @samp\n@item on\nTurns on array bounds checking for all functions.\n@item safeonly\nTurns on array bounds checking only for @code{@@safe} functions.\n@item off\nTurns off array bounds checking completely.\n@end table\n\n@item -fno-builtin\n@cindex @option{-fbuiltin}\n@cindex @option{-fno-builtin}\nDon't recognize built-in functions unless they begin with the prefix\n@samp{__builtin_}.  By default, the compiler will recognize when a\nfunction in the @code{core.stdc} package is a built-in function.\n\n@item -fdebug\n@item -fdebug=@var{value}\n@cindex @option{-fdebug}\n@cindex @option{-fno-debug}\nTurn on compilation of conditional @code{debug} code into the program.\nThe @option{-fdebug} option itself sets the debug level to @code{1},\nwhile @option{-fdebug=} enables @code{debug} code that are identified\nby any of the following values:\n\n@table @samp\n@item level\nSets the debug level to @var{level}, any @code{debug} code <= @var{level}\nis compiled into the program.\n@item ident\nTurns on compilation of any @code{debug} code identified by @var{ident}.\n@end table\n\n@item -fno-invariants\n@cindex @option{-finvariants}\n@cindex @option{-fno-invariants}\nTurns off code generation for class @code{invariant} contracts.\n\n@item -fno-moduleinfo\n@cindex @option{-fmoduleinfo}\n@cindex @option{-fno-moduleinfo}\nTurns off generation of the @code{ModuleInfo} and related functions\nthat would become unreferenced without it, which may allow linking\nto programs not written in D.  Functions that are not be generated\ninclude module constructors and destructors (@code{static this} and\n@code{static ~this}), @code{unittest} code, and @code{DSO} registry\nfunctions for dynamically linked code.\n\n@item -fonly=@var{filename}\n@cindex @option{-fonly}\nTells the compiler to parse and run semantic analysis on all modules\non the command line, but only generate code for the module specified\nby @var{filename}.\n\n@item -fno-postconditions\n@cindex @option{-fpostconditions}\n@cindex @option{-fno-postconditions}\nTurns off code generation for postcondition @code{out} contracts.\n\n@item -fno-preconditions\n@cindex @option{-fpreconditions}\n@cindex @option{-fno-preconditions}\nTurns off code generation for precondition @code{in} contracts.\n\n@item -frelease\n@cindex @option{-frelease}\n@cindex @option{-fno-release}\nTurns on compiling in release mode, which means not emitting runtime\nchecks for contracts and asserts.  Array bounds checking is not done\nfor @code{@@system} and @code{@@trusted} functions, and assertion\nfailures are undefined behavior.\n\nThis is equivalent to compiling with the following options:\n\n@example\ngdc -fno-assert -fbounds-check=safe -fno-invariants \\\n    -fno-postconditions -fno-preconditions -fno-switch-errors\n@end example\n\n@item -fno-switch-errors\n@cindex @option{-fswitch-errors}\n@cindex @option{-fno-switch-errors}\nThis option controls what code is generated when no case is matched\nin a @code{final switch} statement.  The default run time behavior\nis to throw a @code{SwitchError}.  Turning off @option{-fswitch-errors}\nmeans that instead the execution of the program is immediately halted.\n\n@item -funittest\n@cindex @option{-funittest}\n@cindex @option{-fno-unittest}\nTurns on compilation of @code{unittest} code, and turns on the\n@code{version(unittest)} identifier.  This implies @option{-fassert}.\n\n@item -fversion=@var{value}\n@cindex @option{-fversion}\nTurns on compilation of conditional @code{version} code into the program\nidentified by any of the following values:\n\n@table @samp\n@item level\nSets the version level to @var{level}, any @code{version} code >= @var{level}\nis compiled into the program.\n@item ident\nTurns on compilation of @code{version} code identified by @var{ident}.\n@end table\n\n@item -fno-weak\n@cindex @option{-fweak}\n@cindex @option{-fno-weak}\nTurns off emission of instantiated declarations that can be defined in multiple\nobjects as weak or one-only symbols.  The default is to emit all public symbols\nas weak, unless the target lacks support for weak symbols.  Disabling this\noption means that common symbols are instead put in COMDAT or become private.\n\n@end table\n\n@node Directory Options\n@section Options for Directory Search\n@cindex directory options\n@cindex options, directory search\n@cindex search path\n\nThese options specify directories to search for files, libraries, and\nother parts of the compiler:\n\n@table @gcctabopt\n\n@item -I@var{dir}\n@cindex @option{-I}\nSpecify a directory to use when searching for imported modules at\ncompile time.  Multiple @option{-I} options can be used, and the\npaths are searched in the same order.\n\n@item -J@var{dir}\n@cindex @option{-J}\nSpecify a directory to use when searching for files in string imports\nat compile time.  This switch is required in order to use\n@code{import(file)} expressions.  Multiple @option{-J} options can be\nused, and the paths are searched in the same order.\n\n@item -L@var{dir}\n@cindex @option{-L}\nWhen linking, specify a library search directory, as with @command{gcc}.\n\n@item -B@var{dir}\n@cindex @option{-B}\nThis option specifies where to find the executables, libraries,\nsource files, and data files of the compiler itself, as with @command{gcc}.\n\n@item -fmodule-file=@var{module}=@var{spec}\n@cindex @option{-fmodule-file}\nThis option manipulates file paths of imported modules, such that if an\nimported module matches all or the leftmost part of @var{module}, the file\npath in @var{spec} is used as the location to search for D sources.\nThis is used when the source file path and names are not the same as the\npackage and module hierarchy.  Consider the following examples:\n\n@example\ngdc test.d -fmodule-file=A.B=foo.d -fmodule-file=C=bar\n@end example\n\nThis will tell the compiler to search in all import paths for the source\nfile @var{foo.d} when importing @var{A.B}, and the directory @var{bar/}\nwhen importing @var{C}, as annotated in the following D code:\n\n@example\nmodule test;\nimport A.B;     // Matches A.B, searches for foo.d\nimport C.D.E;   // Matches C, searches for bar/D/E.d\nimport A.B.C;   // No match, searches for A/B/C.d\n@end example\n\n@item -imultilib @var{dir}\n@cindex @option{-imultilib}\nUse @var{dir} as a subdirectory of the gcc directory containing\ntarget-specific D sources and interfaces.\n\n@item -iprefix @var{prefix}\n@cindex @option{-iprefix}\nSpecify @var{prefix} as the prefix for the gcc directory containing\ntarget-specific D sources and interfaces.  If the @var{prefix} represents\na directory, you should include the final @code{'/'}.\n\n@item -nostdinc\n@cindex @option{-nostdinc}\nDo not search the standard system directories for D source and interface\nfiles.  Only the directories that have been specified with @option{-I} options\n(and the directory of the current file, if appropriate) are searched.\n\n@end table\n\n@node Code Generation\n@section Code Generation\n@cindex options, code generation\n\nIn addition to the many @command{gcc} options controlling code generation,\n@command{gdc} has several options specific to itself.\n\n@table @gcctabopt\n\n@item -H\n@cindex @option{-H}\nGenerates D interface files for all modules being compiled.  The compiler\ndetermines the output file based on the name of the input file, removes\nany directory components and suffix, and applies the @file{.di} suffix.\n\n@item -Hd @var{dir}\n@cindex @option{-Hd}\nSame as @option{-H}, but writes interface files to directory @var{dir}.\nThis option can be used with @option{-Hf @var{file}} to independently set the\noutput file and directory path.\n\n@item -Hf @var{file}\n@cindex @option{-Hf}\nSame as @option{-H} but writes interface files to @var{file}.  This option can\nbe used with @option{-Hd @var{dir}} to independently set the output file and\ndirectory path.\n\n@item -M\n@cindex @option{-M}\nOutput the module dependencies of all source files being compiled in a\nformat suitable for @command{make}.  The compiler outputs one\n@command{make} rule containing the object file name for that source file,\na colon, and the names of all imported files.\n\n@item -MM\n@cindex @option{-MM}\nLike @option{-M} but does not mention imported modules from the D standard\nlibrary package directories.\n\n@item -MF @var{file}\n@cindex @option{-MF}\nWhen used with @option{-M} or @option{-MM}, specifies a @var{file} to write\nthe dependencies to.  When used with the driver options @option{-MD} or\n@option{-MMD}, @option{-MF} overrides the default dependency output file.\n\n@item -MG\n@cindex @option{-MG}\nThis option is for compatibility with @command{gcc}, and is ignored by the\ncompiler.\n\n@item -MP\n@cindex @option{-MP}\nOutputs a phony target for each dependency other than the modules being\ncompiled, causing each to depend on nothing.\n\n@item -MT @var{target}\n@cindex @option{-MT}\nChange the @var{target} of the rule emitted by dependency generation\nto be exactly the string you specify.  If you want multiple targets,\nyou can specify them as a single argument to @option{-MT}, or use\nmultiple @option{-MT} options.\n\n@item -MQ @var{target}\n@cindex @option{-MQ}\nSame as @option{-MT}, but it quotes any characters which are special to\n@command{make}.\n\n@item -MD\n@cindex @option{-MD}\nThis option is equivalent to @option{-M -MF @var{file}}.  The driver\ndetermines @var{file} by removing any directory components and suffix\nfrom the input file, and then adding a @file{.deps} suffix.\n\n@item -MMD\n@cindex @option{-MMD}\nLike @option{-MD} but does not mention imported modules from the D standard\nlibrary package directories.\n\n@item -X\n@cindex @option{-X}\nOutput information describing the contents of all source files being\ncompiled in JSON format to a file.  The driver determines @var{file} by\nremoving any directory components and suffix from the input file, and then\nadding a @file{.json} suffix.\n\n@item -Xf @var{file}\n@cindex @option{-Xf}\nSame as @option{-X}, but writes all JSON contents to the specified\n@var{file}.\n\n@item -fdoc\n@cindex @option{-fdoc}\nGenerates @code{Ddoc} documentation and writes it to a file.  The compiler\ndetermines @var{file} by removing any directory components and suffix\nfrom the input file, and then adding a @file{.html} suffix.\n\n@item -fdoc-dir=@var{dir}\n@cindex @option{-fdoc-dir}\nSame as @option{-fdoc}, but writes documentation to directory @var{dir}.\nThis option can be used with @option{-fdoc-file=@var{file}} to\nindependently set the output file and directory path.\n\n@item -fdoc-file=@var{file}\n@cindex @option{-fdoc-file}\nSame as @option{-fdoc}, but writes documentation to @var{file}.  This\noption can be used with @option{-fdoc-dir=@var{dir}} to independently\nset the output file and directory path.\n\n@item -fdoc-inc=@var{file}\n@cindex @option{-fdoc-inc}\nSpecify @var{file} as a @var{Ddoc} macro file to be read.  Multiple\n@option{-fdoc-inc} options can be used, and files are read and processed\nin the same order.\n\n@end table\n\n@node Warnings\n@section Warnings\n@cindex options to control warnings\n@cindex warning messages\n@cindex messages, warning\n@cindex suppressing warnings\n\nWarnings are diagnostic messages that report constructions that\nare not inherently erroneous but that are risky or suggest there\nis likely to be a bug in the program.  Unless @option{-Werror} is\nspecified, they do not prevent compilation of the program.\n\n@table @gcctabopt\n\n@item -Wall\n@cindex @option{-Wall}\n@cindex @option{-Wno-all}\nTurns on all warnings messages.  Warnings are not a defined part of\nthe D language, and all constructs for which this may generate a\nwarning message are valid code.\n\n@item -Walloca\n@cindex @option{-Walloca}\nThis option warns on all uses of \"alloca\" in the source.\n\n@item -Walloca-larger-than=@var{n}\n@cindex @option{-Walloca-larger-than}\n@cindex @option{-Wno-alloca-larger-than}\nWarn on unbounded uses of alloca, and on bounded uses of alloca\nwhose bound can be larger than @var{n} bytes.\n@option{-Wno-alloca-larger-than} disables\n@option{-Walloca-larger-than} warning and is equivalent to\n@option{-Walloca-larger-than=@var{SIZE_MAX}} or larger.\n\n@item -Wcast-result\n@cindex @option{-Wcast-result}\n@cindex @option{-Wno-cast-result}\nWarn about casts that will produce a null or zero result.  Currently\nthis is only done for casting between an imaginary and non-imaginary\ndata type, or casting between a D and C++ class.\n\n@item -Wno-deprecated\n@cindex @option{-Wdeprecated}\n@cindex @option{-Wno-deprecated}\nDo not warn about usage of deprecated features and symbols with\n@code{deprecated} attributes.\n\n@item -Werror\n@cindex @option{-Werror}\n@cindex @option{-Wno-error}\nTurns all warnings into errors.\n\n@item -Wspeculative\n@cindex @option{-Wspeculative}\n@cindex @option{-Wno-speculative}\nList all error messages from speculative compiles, such as\n@code{__traits(compiles, ...)}.  This option does not report\nmessages as warnings, and these messages therefore never become\nerrors when the @option{-Werror} option is also used.\n\n@item -Wtemplates\n@cindex @option{-Wtemplates}\n@cindex @option{-Wno-templates}\nWarn when a template instantiation is encountered.  Some coding\nrules disallow templates, and this may be used to enforce that rule.\n\n@item -Wunknown-pragmas\n@cindex @option{-Wunknown-pragmas}\n@cindex @option{-Wno-unknown-pragmas}\nWarn when a @code{pragma()} is encountered that is not understood by\n@command{gdc}.  This differs from @option{-fignore-unknown-pragmas}\nwhere a pragma that is part of the D language, but not implemented by\nthe compiler, won't get reported.\n\n@item -fignore-unknown-pragmas\n@cindex @option{-fignore-unknown-pragmas}\n@cindex @option{-fno-ignore-unknown-pragmas}\nTurns off errors for unsupported pragmas.\n\n@item -fmax-errors=@var{n}\n@cindex @option{-fmax-errors}\nLimits the maximum number of error messages to @var{n}, at which point\n@command{gdc} bails out rather than attempting to continue processing the\nsource code.  If @var{n} is 0 (the default), there is no limit on the\nnumber of error messages produced.\n\n@item -fsyntax-only\n@cindex @option{-fsyntax-only}\n@cindex @option{-fno-syntax-only}\nCheck the code for syntax errors, but do not actually compile it.  This\ncan be used in conjunction with @option{-fdoc} or @option{-H} to generate\nfiles for each module present on the command-line, but no other output\nfile.\n\n@item -ftransition=@var{id}\n@cindex @option{-ftransition}\nReport additional information about D language changes identified by\n@var{id}.  The following values are supported:\n\n@table @samp\n@item all\nList information on all language changes.\n@item checkimports\nGive deprecation messages about @option{-ftransition=import} anomalies.\n@item complex\nList all usages of complex or imaginary types.\n@item dip1000\nImplements @uref{http://wiki.dlang.org/DIP1000} (experimental).\n@item dip25\nImplements @uref{http://wiki.dlang.org/DIP25} (experimental).\n@item field\nList all non-mutable fields which occupy an object instance.\n@item import\nTells the compiler to revert to using an old lookup behavior for resolving\nunqualified symbol names, where this was done in a single pass, ignoring\nany protection attributes.  The default name lookup strategy is to use two\npasses, the first ignoring imported declarations, and the second only\nlooking at imports.  The protection (@code{private}, @code{package},\n@code{protected}) of symbols is also enforced to resolve any conflicts\nbetween private and public symbols.\n@item nogc\nList all hidden GC allocations.\n@item tls\nList all variables going into thread local storage.\n@end table\n\n@end table\n\n@node Linking\n@section Options for Linking\n@cindex options, linking\n@cindex linking, static\n\nThese options come into play when the compiler links object files into an\nexecutable output file.  They are meaningless if the compiler is not doing\na link step.\n\n@table @gcctabopt\n\n@item -defaultlib @var{libname}\n@cindex @option{-defaultlib}\nSpecify the library to use instead of libphobos when linking.  Options\nspecifying the linkage of libphobos, such as @option{-static-libphobos}\nor @option{-shared-libphobos}, are ignored.\n\n@item -debuglib\n@cindex @option{-debuglib}\nSpecify the debug library to use instead of libphobos when linking.\nThis option has no effect unless the @option{-g} option was also given\non the command line.  Options specifying the linkage of libphobos, such\nas @option{-static-libphobos} or @option{-shared-libphobos}, are ignored.\n\n@item -nophoboslib\n@cindex @option{-nophoboslib}\nDo not use the Phobos or D runtime library when linking.  Options specifying\nthe linkage of libphobos, such as @option{-static-libphobos} or\n@option{-shared-libphobos}, are ignored.  The standard system libraries are\nused normally, unless @option{-nostdlib} or @option{-nodefaultlibs} is used.\n\n@item -shared-libphobos\n@cindex @option{-shared-libphobos}\nOn systems that provide @file{libgphobos} and @file{libgdruntime} as a\nshared and a static library, this option forces the use of the shared\nversion.  If no shared version was built when the compiler was configured,\nthis option has no effect.\n\n@item -static-libphobos\n@cindex @option{-static-libphobos}\nOn systems that provide @file{libgphobos} and @file{libgdruntime} as a\nshared and a static library, this option forces the use of the static\nversion.  If no static version was built when the compiler was configured,\nthis option has no effect.\n\n@end table\n\n@node Developer Options\n@section Developer Options\n@cindex developer options\n@cindex debug dump options\n@cindex dump options\n\nThis section describes command-line options that are primarily of\ninterest to developers or language tooling.\n\n@table @gcctabopt\n\n@item -fdump-d-original\n@cindex @option{-fdump-d-original}\nOutput the internal front-end AST after the @code{semantic3} stage.\nThis option is only useful for debugging the GNU D compiler itself.\n\n@item -v\n@cindex @option{-v}\nDump information about the compiler language processing stages as the source\nprogram is being compiled.  This includes listing all modules that are\nprocessed through the @code{parse}, @code{semantic}, @code{semantic2}, and\n@code{semantic3} stages; all @code{import} modules and their file paths;\nand all @code{function} bodies that are being compiled.\n\n@end table\n\n@c man end\n\n@node Index\n@unnumbered Index\n\n@printindex cp\n\n@bye\n"
  },
  {
    "path": "gcc/d/imports.cc",
    "content": "/* imports.cc -- Build imported modules/declarations.\n   Copyright (C) 2014-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/aggregate.h\"\n#include \"dmd/declaration.h\"\n#include \"dmd/enum.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/import.h\"\n#include \"dmd/module.h\"\n\n#include \"tree.h\"\n#include \"stringpool.h\"\n\n#include \"d-tree.h\"\n\n\n/* Implements the visitor interface to build debug trees for all\n   module and import declarations, where ISYM holds the cached\n   back-end representation to be returned.  */\nclass ImportVisitor : public Visitor\n{\n  using Visitor::visit;\n\n  /* Build the declaration DECL as an imported symbol.  */\n  tree make_import (tree decl)\n  {\n    gcc_assert (decl != NULL_TREE);\n\n    tree import = build_decl (input_location, IMPORTED_DECL,\n\t\t\t      DECL_NAME (decl), void_type_node);\n    IMPORTED_DECL_ASSOCIATED_DECL (import) = decl;\n    d_keep (import);\n\n    return import;\n  }\n\npublic:\n  ImportVisitor (void)\n  {\n  }\n\n  /* This should be overridden by each symbol class.  */\n  void visit (Dsymbol *)\n  {\n    gcc_unreachable ();\n  }\n\n  /* Build the module decl for M, this is considered toplevel, regardless\n     of whether there are any parent packages in the module system.  */\n  void visit (Module *m)\n  {\n    Loc loc = (m->md != NULL) ? m->md->loc\n      : Loc (m->srcfile->toChars (), 1, 0);\n\n    m->isym = build_decl (make_location_t (loc), NAMESPACE_DECL,\n\t\t\t  get_identifier (m->toPrettyChars ()),\n\t\t\t  void_type_node);\n    d_keep (m->isym);\n\n    if (!m->isRoot ())\n      DECL_EXTERNAL (m->isym) = 1;\n\n    TREE_PUBLIC (m->isym) = 1;\n    DECL_CONTEXT (m->isym) = NULL_TREE;\n  }\n\n  /* Build an import of another module symbol.  */\n\n  void visit (Import *m)\n  {\n    tree module = build_import_decl (m->mod);\n    m->isym = this->make_import (module);\n  }\n\n  /* Build an import for any kind of user defined type.\n     Use the TYPE_DECL associated with the type symbol.  */\n  void visit (EnumDeclaration *d)\n  {\n    tree type = build_ctype (d->type);\n    /* Not all kinds of D enums create a TYPE_DECL.  */\n    if (TREE_CODE (type) == ENUMERAL_TYPE)\n      d->isym = this->make_import (TYPE_STUB_DECL (type));\n  }\n\n  void visit (AggregateDeclaration *d)\n  {\n    tree type = build_ctype (d->type);\n    d->isym = this->make_import (TYPE_STUB_DECL (type));\n  }\n\n  void visit (ClassDeclaration *d)\n  {\n    /* Want the RECORD_TYPE, not POINTER_TYPE.  */\n    tree type = TREE_TYPE (build_ctype (d->type));\n    d->isym = this->make_import (TYPE_STUB_DECL (type));\n  }\n\n  /* For now, ignore importing other kinds of dsymbols.  */\n  void visit (ScopeDsymbol *)\n  {\n  }\n\n  /* Alias symbols aren't imported, but their targets are.  */\n  void visit (AliasDeclaration *d)\n  {\n    Dsymbol *dsym = d->toAlias ();\n\n    if (dsym == d)\n      {\n\tType *type = d->getType ();\n\n\t/* Type imports should really be part of their own visit method.  */\n\tif (type != NULL)\n\t  {\n\t    if (type->ty == Tenum)\n\t      dsym = ((TypeEnum *) type)->sym;\n\t    else if (type->ty == Tstruct)\n\t      dsym = ((TypeStruct *) type)->sym;\n\t    else if (type->ty == Tclass)\n\t      dsym = ((TypeClass *) type)->sym;\n\t  }\n      }\n\n    /* This symbol is really an alias for another, visit the other.  */\n    if (dsym != d)\n      {\n\tdsym->accept (this);\n\td->isym = dsym->isym;\n      }\n  }\n\n  /* Visit the underlying alias symbol of overloadable aliases.  */\n  void visit (OverDeclaration *d)\n  {\n    if (d->aliassym != NULL)\n      {\n\td->aliassym->accept (this);\n\td->isym = d->aliassym->isym;\n      }\n  }\n\n  /* Function aliases are the same as alias symbols.  */\n  void visit (FuncAliasDeclaration *d)\n  {\n    FuncDeclaration *fd = d->toAliasFunc ();\n\n    if (fd != NULL)\n      {\n\tfd->accept (this);\n\td->isym = fd->isym;\n      }\n  }\n\n  /* Skip over importing templates and tuples.  */\n  void visit (TemplateDeclaration *)\n  {\n  }\n\n  void visit (TupleDeclaration *)\n  {\n  }\n\n  /* Import any other kind of declaration.  If the class does not implement\n     symbol generation routines, the compiler will throw an error.  */\n  void visit (Declaration *d)\n  {\n    d->isym = this->make_import (get_symbol_decl (d));\n  }\n};\n\n\n/* Build a declaration for the symbol D that can be used for the\n   debug_hook imported_module_or_decl.  */\ntree\nbuild_import_decl (Dsymbol *d)\n{\n  if (!d->isym)\n    {\n      location_t saved_location = input_location;\n      ImportVisitor v;\n\n      input_location = make_location_t (d->loc);\n      d->accept (&v);\n      input_location = saved_location;\n    }\n\n  /* Not all visitors set 'isym'.  */\n  return d->isym ? d->isym : NULL_TREE;\n}\n\n"
  },
  {
    "path": "gcc/d/intrinsics.cc",
    "content": "/* intrinsics.cc -- D language compiler intrinsics.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/declaration.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/mangle.h\"\n#include \"dmd/module.h\"\n#include \"dmd/template.h\"\n\n#include \"tm.h\"\n#include \"function.h\"\n#include \"tree.h\"\n#include \"fold-const.h\"\n#include \"stringpool.h\"\n#include \"builtins.h\"\n\n#include \"d-tree.h\"\n\n\n/* An internal struct used to hold information on D intrinsics.  */\n\nstruct intrinsic_decl\n{\n  /* The DECL_FUNCTION_CODE of this decl.  */\n  intrinsic_code code;\n\n  /* The name of the intrinsic.  */\n  const char *name;\n\n  /* The module where the intrinsic is located.  */\n  const char *module;\n\n  /* The mangled signature decoration of the intrinsic.  */\n  const char *deco;\n\n  /* True if the intrinsic is only handled in CTFE.  */\n  bool ctfeonly;\n};\n\nstatic const intrinsic_decl intrinsic_decls[] =\n{\n#define DEF_D_INTRINSIC(CODE, ALIAS, NAME, MODULE, DECO, CTFE) \\\n    { INTRINSIC_ ## ALIAS, NAME, MODULE, DECO, CTFE },\n\n#include \"intrinsics.def\"\n\n#undef DEF_D_INTRINSIC\n};\n\n/* Checks if DECL is an intrinsic or run time library function that requires\n   special processing.  Sets DECL_INTRINSIC_CODE so it can be identified\n   later in maybe_expand_intrinsic.  */\n\nvoid\nmaybe_set_intrinsic (FuncDeclaration *decl)\n{\n  if (!decl->ident || decl->builtin != BUILTINunknown)\n    return;\n\n  /* The builtin flag is updated only if we can evaluate the intrinsic\n     at compile-time.  Such as the math or bitop intrinsics.  */\n  decl->builtin = BUILTINno;\n\n  /* Check if it's a compiler intrinsic.  We only require that any\n     internally recognised intrinsics are declared in a module with\n     an explicit module declaration.  */\n  Module *m = decl->getModule ();\n\n  if (!m || !m->md)\n    return;\n\n  TemplateInstance *ti = decl->isInstantiated ();\n  TemplateDeclaration *td = ti ? ti->tempdecl->isTemplateDeclaration () : NULL;\n\n  const char *tname = decl->ident->toChars ();\n  const char *tmodule = m->md->toChars ();\n  const char *tdeco = (td == NULL) ? decl->type->deco : NULL;\n\n  /* Look through all D intrinsics.  */\n  for (size_t i = 0; i < (int) INTRINSIC_LAST; i++)\n    {\n      if (!intrinsic_decls[i].name)\n\tcontinue;\n\n      if (strcmp (intrinsic_decls[i].name, tname) != 0\n\t  || strcmp (intrinsic_decls[i].module, tmodule) != 0)\n\tcontinue;\n\n      /* Instantiated functions would have the wrong type deco, get it from the\n\t template member instead.  */\n      if (tdeco == NULL)\n\t{\n\t  if (!td || !td->onemember)\n\t    return;\n\n\t  FuncDeclaration *fd = td->onemember->isFuncDeclaration ();\n\t  if (fd == NULL)\n\t    return;\n\n\t  OutBuffer buf;\n\t  mangleToBuffer (fd->type, &buf);\n\t  tdeco = buf.extractString ();\n\t}\n\n      /* Matching the type deco may be a bit too strict, as it means that all\n\t function attributes that end up in the signature must be kept aligned\n\t between the compiler and library declaration.  */\n      if (strcmp (intrinsic_decls[i].deco, tdeco) == 0)\n\t{\n\t  intrinsic_code code = intrinsic_decls[i].code;\n\n\t  if (decl->csym == NULL)\n\t    get_symbol_decl (decl);\n\n\t  /* If there is no function body, then the implementation is always\n\t     provided by the compiler.  */\n\t  if (!decl->fbody)\n\t    {\n\t      DECL_BUILT_IN_CLASS (decl->csym) = BUILT_IN_FRONTEND;\n\t      DECL_FUNCTION_CODE (decl->csym) = (built_in_function) code;\n\t    }\n\n\t  /* Infer whether the intrinsic can be used for CTFE, let the\n\t     front-end know that it can be evaluated at compile-time.  */\n\t  switch (code)\n\t    {\n\t    case INTRINSIC_VA_ARG:\n\t    case INTRINSIC_C_VA_ARG:\n\t    case INTRINSIC_VASTART:\n\t    case INTRINSIC_ADDS:\n\t    case INTRINSIC_SUBS:\n\t    case INTRINSIC_MULS:\n\t    case INTRINSIC_NEGS:\n\t    case INTRINSIC_VLOAD:\n\t    case INTRINSIC_VSTORE:\n\t      break;\n\n\t    case INTRINSIC_POW:\n\t    {\n\t      /* Check that this overload of pow() is has an equivalent\n\t\t built-in function.  It could be `int pow(int, int)'.  */\n\t      tree rettype = TREE_TYPE (TREE_TYPE (decl->csym));\n\t      if (mathfn_built_in (rettype, BUILT_IN_POW) != NULL_TREE)\n\t\tdecl->builtin = BUILTINyes;\n\t      break;\n\t    }\n\n\t    default:\n\t      decl->builtin = BUILTINyes;\n\t      break;\n\t    }\n\n\t  /* The intrinsic was marked as CTFE-only.  */\n\t  if (intrinsic_decls[i].ctfeonly)\n\t    DECL_BUILT_IN_CTFE (decl->csym) = 1;\n\n\t  DECL_INTRINSIC_CODE (decl->csym) = code;\n\t  break;\n\t}\n    }\n}\n\n/* Construct a function call to the built-in function CODE, N is the number of\n   arguments, and the `...' parameters are the argument expressions.\n   The original call expression is held in CALLEXP.  */\n\nstatic tree\ncall_builtin_fn (tree callexp, built_in_function code, int n, ...)\n{\n  tree *argarray = XALLOCAVEC (tree, n);\n  va_list ap;\n\n  va_start (ap, n);\n  for (int i = 0; i < n; i++)\n    argarray[i] = va_arg (ap, tree);\n  va_end (ap);\n\n  tree exp = build_call_expr_loc_array (EXPR_LOCATION (callexp),\n\t\t\t\t\tbuiltin_decl_explicit (code),\n\t\t\t\t\tn, argarray);\n  return convert (TREE_TYPE (callexp), fold (exp));\n}\n\n/* Expand a front-end instrinsic call to bsf().  This takes one argument,\n   the signature to which can be either:\n\n\tint bsf (uint arg);\n\tint bsf (ulong arg);\n\n   This scans all bits in the given argument starting with the first,\n   returning the bit number of the first bit set.  The original call\n   expression is held in CALLEXP.  */\n\nstatic tree\nexpand_intrinsic_bsf (tree callexp)\n{\n  /* The bsr() intrinsic gets turned into __builtin_ctz(arg).\n     The return value is supposed to be undefined if arg is zero.  */\n  tree arg = CALL_EXPR_ARG (callexp, 0);\n  int argsize = TYPE_PRECISION (TREE_TYPE (arg));\n\n  /* Which variant of __builtin_ctz* should we call?  */\n  built_in_function code = (argsize <= INT_TYPE_SIZE) ? BUILT_IN_CTZ\n    : (argsize <= LONG_TYPE_SIZE) ? BUILT_IN_CTZL\n    : (argsize <= LONG_LONG_TYPE_SIZE) ? BUILT_IN_CTZLL\n    : END_BUILTINS;\n\n  gcc_assert (code != END_BUILTINS);\n\n  return call_builtin_fn (callexp, code, 1, arg);\n}\n\n/* Expand a front-end instrinsic call to bsr().  This takes one argument,\n   the signature to which can be either:\n\n\tint bsr (uint arg);\n\tint bsr (ulong arg);\n\n   This scans all bits in the given argument from the most significant bit\n   to the least significant, returning the bit number of the first bit set.\n   The original call expression is held in CALLEXP.  */\n\nstatic tree\nexpand_intrinsic_bsr (tree callexp)\n{\n  /* The bsr() intrinsic gets turned into (size - 1) - __builtin_clz(arg).\n     The return value is supposed to be undefined if arg is zero.  */\n  tree arg = CALL_EXPR_ARG (callexp, 0);\n  tree type = TREE_TYPE (arg);\n  int argsize = TYPE_PRECISION (type);\n\n  /* Which variant of __builtin_clz* should we call?  */\n  built_in_function code = (argsize <= INT_TYPE_SIZE) ? BUILT_IN_CLZ\n    : (argsize <= LONG_TYPE_SIZE) ? BUILT_IN_CLZL\n    : (argsize <= LONG_LONG_TYPE_SIZE) ? BUILT_IN_CLZLL\n    : END_BUILTINS;\n\n  gcc_assert (code != END_BUILTINS);\n\n  tree result = call_builtin_fn (callexp, code, 1, arg);\n\n  /* Handle int -> long conversions.  */\n  if (TREE_TYPE (result) != type)\n    result = fold_convert (type, result);\n\n  result = fold_build2 (MINUS_EXPR, type,\n\t\t\tbuild_integer_cst (argsize - 1, type), result);\n  return fold_convert (TREE_TYPE (callexp), result);\n}\n\n/* Expand a front-end intrinsic call to INTRINSIC, which is either a call to\n   bt(), btc(), btr(), or bts().  These intrinsics expect to take two arguments,\n   the signature to which is:\n\n\tint bt (size_t* ptr, size_t bitnum);\n\n   All intrinsics test if a bit is set and return the result of that condition.\n   Variants of `bt' will then update that bit. `btc' compliments the bit, `bts'\n   sets the bit, and `btr' resets the bit.  The original call expression is\n   held in CALLEXP.  */\n\nstatic tree\nexpand_intrinsic_bt (intrinsic_code intrinsic, tree callexp)\n{\n  tree ptr = CALL_EXPR_ARG (callexp, 0);\n  tree bitnum = CALL_EXPR_ARG (callexp, 1);\n  tree type = TREE_TYPE (TREE_TYPE (ptr));\n\n  /* size_t bitsize = sizeof(*ptr) * BITS_PER_UNIT;  */\n  tree bitsize = fold_convert (type, TYPE_SIZE (type));\n\n  /* ptr[bitnum / bitsize]  */\n  ptr = build_array_index (ptr, fold_build2 (TRUNC_DIV_EXPR, type,\n\t\t\t\t\t     bitnum, bitsize));\n  ptr = indirect_ref (type, ptr);\n\n  /* mask = 1 << (bitnum % bitsize);  */\n  bitnum = fold_build2 (TRUNC_MOD_EXPR, type, bitnum, bitsize);\n  bitnum = fold_build2 (LSHIFT_EXPR, type, size_one_node, bitnum);\n\n  /* cond = ptr[bitnum / size] & mask;  */\n  tree cond = fold_build2 (BIT_AND_EXPR, type, ptr, bitnum);\n\n  /* cond ? -1 : 0;  */\n  cond = build_condition (TREE_TYPE (callexp), d_truthvalue_conversion (cond),\n\t\t\t integer_minus_one_node, integer_zero_node);\n\n  /* Update the bit as needed, only testing the bit for bt().  */\n  if (intrinsic == INTRINSIC_BT)\n    return cond;\n\n  tree_code code = (intrinsic == INTRINSIC_BTC) ? BIT_XOR_EXPR\n    : (intrinsic == INTRINSIC_BTR) ? BIT_AND_EXPR\n    : (intrinsic == INTRINSIC_BTS) ? BIT_IOR_EXPR\n    : ERROR_MARK;\n  gcc_assert (code != ERROR_MARK);\n\n  /* ptr[bitnum / size] op= mask;  */\n  if (intrinsic == INTRINSIC_BTR)\n    bitnum = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (bitnum), bitnum);\n\n  ptr = modify_expr (ptr, fold_build2 (code, TREE_TYPE (ptr), ptr, bitnum));\n\n  /* Store the condition result in a temporary, and return expressions in\n     correct order of evaluation.  */\n  tree tmp = build_local_temp (TREE_TYPE (callexp));\n  cond = modify_expr (tmp, cond);\n\n  return compound_expr (cond, compound_expr (ptr, tmp));\n}\n\n/* Expand a front-end intrinsic call to bswap().  This takes one argument, the\n   signature to which can be either:\n\n\tint bswap (uint arg);\n\tint bswap (ulong arg);\n\n   This swaps all bytes in an N byte type end-to-end.  The original call\n   expression is held in CALLEXP.  */\n\nstatic tree\nexpand_intrinsic_bswap (tree callexp)\n{\n  tree arg = CALL_EXPR_ARG (callexp, 0);\n  int argsize = TYPE_PRECISION (TREE_TYPE (arg));\n\n  /* Which variant of __builtin_bswap* should we call?  */\n  built_in_function code = (argsize == 32) ? BUILT_IN_BSWAP32\n    : (argsize == 64) ? BUILT_IN_BSWAP64\n    : END_BUILTINS;\n\n  gcc_assert (code != END_BUILTINS);\n\n  return call_builtin_fn (callexp, code, 1, arg);\n}\n\n/* Expand a front-end intrinsic call to popcnt().  This takes one argument, the\n   signature to which can be either:\n\n\tint popcnt (uint arg);\n\tint popcnt (ulong arg);\n\n   Calculates the number of set bits in an integer.  The original call\n   expression is held in CALLEXP.  */\n\nstatic tree\nexpand_intrinsic_popcnt (tree callexp)\n{\n  tree arg = CALL_EXPR_ARG (callexp, 0);\n  int argsize = TYPE_PRECISION (TREE_TYPE (arg));\n\n  /* Which variant of __builtin_popcount* should we call?  */\n  built_in_function code = (argsize <= INT_TYPE_SIZE) ? BUILT_IN_POPCOUNT\n    : (argsize <= LONG_TYPE_SIZE) ? BUILT_IN_POPCOUNTL\n    : (argsize <= LONG_LONG_TYPE_SIZE) ? BUILT_IN_POPCOUNTLL\n    : END_BUILTINS;\n\n  gcc_assert (code != END_BUILTINS);\n\n  return call_builtin_fn (callexp, code, 1, arg);\n}\n\n/* Expand a front-end intrinsic call to INTRINSIC, which is either a call to\n   sqrt(), sqrtf(), sqrtl().  These intrinsics expect to take one argument,\n   the signature to which can be either:\n\n\tfloat sqrt (float arg);\n\tdouble sqrt (double arg);\n\treal sqrt (real arg);\n\n   This computes the square root of the given argument.  The original call\n   expression is held in CALLEXP.  */\n\nstatic tree\nexpand_intrinsic_sqrt (intrinsic_code intrinsic, tree callexp)\n{\n  tree arg = CALL_EXPR_ARG (callexp, 0);\n\n  /* Which variant of __builtin_sqrt* should we call?  */\n  built_in_function code = (intrinsic == INTRINSIC_SQRT) ? BUILT_IN_SQRT\n    : (intrinsic == INTRINSIC_SQRTF) ? BUILT_IN_SQRTF\n    : (intrinsic == INTRINSIC_SQRTL) ? BUILT_IN_SQRTL\n    : END_BUILTINS;\n\n  gcc_assert (code != END_BUILTINS);\n  return call_builtin_fn (callexp, code, 1, arg);\n}\n\n/* Expand a front-end intrinsic call to copysign().  This takes two arguments,\n   the signature to which can be either:\n\n\tfloat copysign (T to, float from);\n\tdouble copysign (T to, double from);\n\treal copysign (T to, real from);\n\n   This computes a value composed of TO with the sign bit of FROM.  The original\n   call expression is held in CALLEXP.  */\n\nstatic tree\nexpand_intrinsic_copysign (tree callexp)\n{\n  tree to = CALL_EXPR_ARG (callexp, 0);\n  tree from = CALL_EXPR_ARG (callexp, 1);\n  tree type = TREE_TYPE (to);\n\n  /* Convert parameters to the same type.  Prefer the first parameter unless it\n     is an integral type.  */\n  if (INTEGRAL_TYPE_P (type))\n    {\n      to = fold_convert (TREE_TYPE (from), to);\n      type = TREE_TYPE (to);\n    }\n  else\n    from = fold_convert (type, from);\n\n  /* Which variant of __builtin_copysign* should we call?  */\n  tree builtin = mathfn_built_in (type, BUILT_IN_COPYSIGN);\n  gcc_assert (builtin != NULL_TREE);\n\n  return call_builtin_fn (callexp, DECL_FUNCTION_CODE (builtin), 2,\n\t\t\t  to, from);\n}\n\n/* Expand a front-end intrinsic call to pow().  This takes two arguments, the\n   signature to which can be either:\n\n\tfloat pow (float base, T exponent);\n\tdouble pow (double base, T exponent);\n\treal pow (real base, T exponent);\n\n   This computes the value of BASE raised to the power of EXPONENT.\n   The original call expression is held in CALLEXP.  */\n\nstatic tree\nexpand_intrinsic_pow (tree callexp)\n{\n  tree base = CALL_EXPR_ARG (callexp, 0);\n  tree exponent = CALL_EXPR_ARG (callexp, 1);\n  tree exptype = TREE_TYPE (exponent);\n\n  /* Which variant of __builtin_pow* should we call?  */\n  built_in_function code = SCALAR_FLOAT_TYPE_P (exptype) ? BUILT_IN_POW\n    : INTEGRAL_TYPE_P (exptype) ? BUILT_IN_POWI\n    : END_BUILTINS;\n  gcc_assert (code != END_BUILTINS);\n\n  tree builtin = mathfn_built_in (TREE_TYPE (base), code);\n  gcc_assert (builtin != NULL_TREE);\n\n  return call_builtin_fn (callexp, DECL_FUNCTION_CODE (builtin), 2,\n\t\t\t  base, exponent);\n}\n\n/* Expand a front-end intrinsic call to va_arg().  This takes either one or two\n   arguments, the signature to which can be either:\n\n\tT va_arg(T) (ref va_list ap);\n\tvoid va_arg(T) (va_list ap, ref T parmn);\n\n   This retrieves the next variadic parameter that is type T from the given\n   va_list.  If also given, store the value into parmn, otherwise return it.\n   The original call expression is held in CALLEXP.  */\n\nstatic tree\nexpand_intrinsic_vaarg (tree callexp)\n{\n  tree ap = CALL_EXPR_ARG (callexp, 0);\n  tree parmn = NULL_TREE;\n  tree type;\n\n  STRIP_NOPS (ap);\n\n  if (call_expr_nargs (callexp) == 1)\n    type = TREE_TYPE (callexp);\n  else\n    {\n      parmn = CALL_EXPR_ARG (callexp, 1);\n      STRIP_NOPS (parmn);\n      gcc_assert (TREE_CODE (parmn) == ADDR_EXPR);\n      parmn = TREE_OPERAND (parmn, 0);\n      type = TREE_TYPE (parmn);\n    }\n\n  /* (T) VA_ARG_EXP<ap>;  */\n  tree exp = build1 (VA_ARG_EXPR, type, ap);\n\n  /* parmn = (T) VA_ARG_EXP<ap>;  */\n  if (parmn != NULL_TREE)\n    exp = modify_expr (parmn, exp);\n\n  return exp;\n}\n\n/* Expand a front-end intrinsic call to va_start(), which takes two arguments,\n   the signature to which is:\n\n\tvoid va_start(T) (out va_list ap, ref T parmn);\n\n   This initializes the va_list type, where parmn should be the last named\n   parameter.  The original call expression is held in CALLEXP.  */\n\nstatic tree\nexpand_intrinsic_vastart (tree callexp)\n{\n  tree ap = CALL_EXPR_ARG (callexp, 0);\n  tree parmn = CALL_EXPR_ARG (callexp, 1);\n\n  STRIP_NOPS (ap);\n  STRIP_NOPS (parmn);\n\n  /* The va_list argument should already have its address taken.  The second\n     argument, however, is inout and that needs to be fixed to prevent a\n     warning.  Could be casting, so need to check type too?  */\n  gcc_assert (TREE_CODE (ap) == ADDR_EXPR && TREE_CODE (parmn) == ADDR_EXPR);\n\n  /* Assuming nobody tries to change the return type.  */\n  parmn = TREE_OPERAND (parmn, 0);\n\n  return call_builtin_fn (callexp, BUILT_IN_VA_START, 2, ap, parmn);\n}\n\n/* Expand a front-end instrinsic call to INTRINSIC, which is either a call to\n   adds(), addu(), subs(), subu(), negs(), muls(), or mulu().  These intrinsics\n   expect to take two or three arguments, the signature to which can be either:\n\n\tint adds (int x, int y, ref bool overflow);\n\tlong adds (long x, long y, ref bool overflow);\n\tint negs (int x, ref bool overflow);\n\tlong negs (long x, ref bool overflow);\n\n   This performs an operation on two signed or unsigned integers, checking for\n   overflow.  The overflow is sticky, meaning that a sequence of operations\n   can be done and overflow need only be checked at the end.  The original call\n   expression is held in CALLEXP.  */\n\nstatic tree\nexpand_intrinsic_checkedint (intrinsic_code intrinsic, tree callexp)\n{\n  tree type = TREE_TYPE (callexp);\n  tree x;\n  tree y;\n  tree overflow;\n\n  /* The negs() intrinsic gets turned into SUB_OVERFLOW (0, y).  */\n  if (intrinsic == INTRINSIC_NEGS)\n    {\n      x = fold_convert (type, integer_zero_node);\n      y = CALL_EXPR_ARG (callexp, 0);\n      overflow = CALL_EXPR_ARG (callexp, 1);\n    }\n  else\n    {\n      x = CALL_EXPR_ARG (callexp, 0);\n      y = CALL_EXPR_ARG (callexp, 1);\n      overflow = CALL_EXPR_ARG (callexp, 2);\n    }\n\n  /* Which variant of *_OVERFLOW should we generate?  */\n  internal_fn icode = (intrinsic == INTRINSIC_ADDS) ? IFN_ADD_OVERFLOW\n    : (intrinsic == INTRINSIC_SUBS) ? IFN_SUB_OVERFLOW\n    : (intrinsic == INTRINSIC_MULS) ? IFN_MUL_OVERFLOW\n    : (intrinsic == INTRINSIC_NEGS) ? IFN_SUB_OVERFLOW\n    : IFN_LAST;\n  gcc_assert (icode != IFN_LAST);\n\n  tree result\n    = build_call_expr_internal_loc (EXPR_LOCATION (callexp), icode,\n\t\t\t\t    build_complex_type (type), 2, x, y);\n\n  STRIP_NOPS (overflow);\n  overflow = build_deref (overflow);\n\n  /* Assign returned result to overflow parameter, however if overflow is\n     already true, maintain its value.  */\n  type = TREE_TYPE (overflow);\n  result = save_expr (result);\n\n  tree exp = fold_build2 (BIT_IOR_EXPR, type, overflow,\n\t\t\t  fold_convert (type, imaginary_part (result)));\n  exp = modify_expr (overflow, exp);\n\n  /* Return the value of result.  */\n  return compound_expr (exp, real_part (result));\n}\n\n/* Expand a front-end instrinsic call to volatileLoad().  This takes one\n   argument, the signature to which can be either:\n\n\tubyte volatileLoad (ubyte* ptr);\n\tushort volatileLoad (ushort* ptr);\n\tuint volatileLoad (uint* ptr);\n\tulong volatileLoad (ulong* ptr);\n\n   This reads a value from the memory location indicated by ptr.  Calls to\n   them are be guaranteed to not be removed (such as during DCE) or reordered\n   in the same thread.  The original call expression is held in CALLEXP.  */\n\nstatic tree\nexpand_volatile_load (tree callexp)\n{\n  tree ptr = CALL_EXPR_ARG (callexp, 0);\n  tree ptrtype = TREE_TYPE (ptr);\n  gcc_assert (POINTER_TYPE_P (ptrtype));\n\n  /* (T) *(volatile T *) ptr;  */\n  tree type = build_qualified_type (TREE_TYPE (ptrtype), TYPE_QUAL_VOLATILE);\n  tree result = indirect_ref (type, ptr);\n  TREE_THIS_VOLATILE (result) = 1;\n\n  return result;\n}\n\n/* Expand a front-end instrinsic call to volatileStore().  This takes two\n   arguments, the signature to which can be either:\n\n\tvoid volatileStore (ubyte* ptr, ubyte value);\n\tvoid volatileStore (ushort* ptr, ushort value);\n\tvoid volatileStore (uint* ptr, uint value);\n\tvoid volatileStore (ulong* ptr, ulong value);\n\n   This writes a value to the memory location indicated by ptr.  Calls to\n   them are be guaranteed to not be removed (such as during DCE) or reordered\n   in the same thread.  The original call expression is held in CALLEXP.  */\n\nstatic tree\nexpand_volatile_store (tree callexp)\n{\n  tree ptr = CALL_EXPR_ARG (callexp, 0);\n  tree ptrtype = TREE_TYPE (ptr);\n  gcc_assert (POINTER_TYPE_P (ptrtype));\n\n  /* (T) *(volatile T *) ptr;  */\n  tree type = build_qualified_type (TREE_TYPE (ptrtype), TYPE_QUAL_VOLATILE);\n  tree result = indirect_ref (type, ptr);\n  TREE_THIS_VOLATILE (result) = 1;\n\n  /* (*(volatile T *) ptr) = value;  */\n  tree value = CALL_EXPR_ARG (callexp, 1);\n  return modify_expr (result, value);\n}\n\n/* If CALLEXP is for an intrinsic , expand and return inlined compiler\n   generated instructions.  Most map directly to GCC builtins, others\n   require a little extra work around them.  */\n\ntree\nmaybe_expand_intrinsic (tree callexp)\n{\n  tree callee = CALL_EXPR_FN (callexp);\n\n  if (TREE_CODE (callee) == ADDR_EXPR)\n    callee = TREE_OPERAND (callee, 0);\n\n  if (TREE_CODE (callee) != FUNCTION_DECL)\n    return callexp;\n\n  /* Don't expand CTFE-only intrinsics outside of semantic processing.  */\n  if (DECL_BUILT_IN_CTFE (callee) && !doing_semantic_analysis_p)\n    return callexp;\n\n  intrinsic_code intrinsic = DECL_INTRINSIC_CODE (callee);\n  built_in_function code;\n\n  switch (intrinsic)\n    {\n    case INTRINSIC_NONE:\n      return callexp;\n\n    case INTRINSIC_BSF:\n      return expand_intrinsic_bsf (callexp);\n\n    case INTRINSIC_BSR:\n      return expand_intrinsic_bsr (callexp);\n\n    case INTRINSIC_BT:\n    case INTRINSIC_BTC:\n    case INTRINSIC_BTR:\n    case INTRINSIC_BTS:\n      return expand_intrinsic_bt (intrinsic, callexp);\n\n    case INTRINSIC_BSWAP:\n      return expand_intrinsic_bswap (callexp);\n\n    case INTRINSIC_POPCNT:\n      return expand_intrinsic_popcnt (callexp);\n\n    case INTRINSIC_COS:\n      return call_builtin_fn (callexp, BUILT_IN_COSL, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_SIN:\n      return call_builtin_fn (callexp, BUILT_IN_SINL, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_RNDTOL:\n      /* Not sure if llroundl stands as a good replacement for the\n\t expected behavior of rndtol.  */\n      return call_builtin_fn (callexp, BUILT_IN_LLROUNDL, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_SQRT:\n    case INTRINSIC_SQRTF:\n    case INTRINSIC_SQRTL:\n      return expand_intrinsic_sqrt (intrinsic, callexp);\n\n    case INTRINSIC_LDEXP:\n      return call_builtin_fn (callexp, BUILT_IN_LDEXPL, 2,\n\t\t\t      CALL_EXPR_ARG (callexp, 0),\n\t\t\t      CALL_EXPR_ARG (callexp, 1));\n\n    case INTRINSIC_FABS:\n      return call_builtin_fn (callexp, BUILT_IN_FABSL, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_RINT:\n      return call_builtin_fn (callexp, BUILT_IN_RINTL, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_TAN:\n      return call_builtin_fn (callexp, BUILT_IN_TANL, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_ISNAN:\n      return call_builtin_fn (callexp, BUILT_IN_ISNAN, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_ISINFINITY:\n      return call_builtin_fn (callexp, BUILT_IN_ISINF, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_ISFINITE:\n      return call_builtin_fn (callexp, BUILT_IN_ISFINITE, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_EXP:\n      return call_builtin_fn (callexp, BUILT_IN_EXPL, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_EXPM1:\n      return call_builtin_fn (callexp, BUILT_IN_EXPM1L, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_EXP2:\n      return call_builtin_fn (callexp, BUILT_IN_EXP2L, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_LOG:\n      return call_builtin_fn (callexp, BUILT_IN_LOGL, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_LOG2:\n      return call_builtin_fn (callexp, BUILT_IN_LOG2L, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_LOG10:\n      return call_builtin_fn (callexp, BUILT_IN_LOG10L, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_ROUND:\n      return call_builtin_fn (callexp, BUILT_IN_ROUNDL, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_FLOORF:\n    case INTRINSIC_FLOOR:\n    case INTRINSIC_FLOORL:\n      code = (intrinsic == INTRINSIC_FLOOR) ? BUILT_IN_FLOOR\n\t: (intrinsic == INTRINSIC_FLOORF) ? BUILT_IN_FLOORF\n\t: BUILT_IN_FLOORL;\n      return call_builtin_fn (callexp, code, 1, CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_CEILF:\n    case INTRINSIC_CEIL:\n    case INTRINSIC_CEILL:\n      code = (intrinsic == INTRINSIC_CEIL) ? BUILT_IN_CEIL\n\t: (intrinsic == INTRINSIC_CEILF) ? BUILT_IN_CEILF\n\t: BUILT_IN_CEILL;\n      return call_builtin_fn (callexp, code, 1, CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_TRUNC:\n      return call_builtin_fn (callexp, BUILT_IN_TRUNCL, 1,\n\t\t\t      CALL_EXPR_ARG (callexp, 0));\n\n    case INTRINSIC_FMIN:\n      return call_builtin_fn (callexp, BUILT_IN_FMINL, 2,\n\t\t\t      CALL_EXPR_ARG (callexp, 0),\n\t\t\t      CALL_EXPR_ARG (callexp, 1));\n\n    case INTRINSIC_FMAX:\n      return call_builtin_fn (callexp, BUILT_IN_FMAXL, 2,\n\t\t\t      CALL_EXPR_ARG (callexp, 0),\n\t\t\t      CALL_EXPR_ARG (callexp, 1));\n\n    case INTRINSIC_COPYSIGN:\n      return expand_intrinsic_copysign (callexp);\n\n    case INTRINSIC_POW:\n      return expand_intrinsic_pow (callexp);\n\n    case INTRINSIC_FMA:\n      return call_builtin_fn (callexp, BUILT_IN_FMAL, 3,\n\t\t\t      CALL_EXPR_ARG (callexp, 0),\n\t\t\t      CALL_EXPR_ARG (callexp, 1),\n\t\t\t      CALL_EXPR_ARG (callexp, 2));\n\n    case INTRINSIC_VA_ARG:\n    case INTRINSIC_C_VA_ARG:\n      return expand_intrinsic_vaarg (callexp);\n\n    case INTRINSIC_VASTART:\n      return expand_intrinsic_vastart (callexp);\n\n    case INTRINSIC_ADDS:\n    case INTRINSIC_SUBS:\n    case INTRINSIC_MULS:\n    case INTRINSIC_NEGS:\n      return expand_intrinsic_checkedint (intrinsic, callexp);\n\n    case INTRINSIC_VLOAD:\n      return expand_volatile_load (callexp);\n\n    case INTRINSIC_VSTORE:\n      return expand_volatile_store (callexp);\n\n    default:\n      gcc_unreachable ();\n    }\n}\n"
  },
  {
    "path": "gcc/d/intrinsics.def",
    "content": "/* intrinsics.def -- Definitions for D compiler intrinsics.\n   Copyright (C) 2014-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n/* DEF_D_INTRINSIC (CODE, ALIAS, NAME, MODULE, DECO, CTFE)\n   CODE\t    The enum code used to refer to this intrinsic.\n   ALIAS    The enum code used to reference the function DECL_FUNCTION_CODE,\n\t    if there are multiple modules or decos for a single intrinsic,\n\t    they would all refer to this code.\n   NAME\t    The name of this intrinsic as a string.\n   MODULE   The name of the module which the intrinsic belongs to as a string.\n   DECO\t    The function signature decoration of the intrinsic.\n   CTFE\t    True if the function is only handled as a built-in during CTFE,\n\t    otherwise the runtime implementation is used.\n\n   Used for declaring internally recognized functions that either map to a\n   GCC builtin, or are specially handled by the compiler.  */\n\n/* A D built-in that has no runtime implementation.  */\n#define DEF_D_BUILTIN(C, A, N, M, D) \\\n  DEF_D_INTRINSIC (C, A, N, M, D, false)\n\n/* A D built-in that is specially recognized only during CTFE.  */\n#define DEF_CTFE_BUILTIN(C, A, N, M, D) \\\n  DEF_D_INTRINSIC (C, A, N, M, D, true)\n\nDEF_D_BUILTIN (NONE, NONE, 0, 0, 0)\n\n/* core.bitop intrinsics.  */\n\nDEF_D_BUILTIN (BSF, BSF, \"bsf\", \"core.bitop\", \"FNaNbNiNfkZi\")\nDEF_D_BUILTIN (BSR, BSR, \"bsr\", \"core.bitop\", \"FNaNbNiNfkZi\")\nDEF_D_BUILTIN (BT, BT, \"bt\", \"core.bitop\", \"FNaNbNixPkkZi\")\nDEF_D_BUILTIN (BTC, BTC, \"btc\", \"core.bitop\", \"FNaNbNiPkkZi\")\nDEF_D_BUILTIN (BTR, BTR, \"btr\", \"core.bitop\", \"FNaNbNiPkkZi\")\nDEF_D_BUILTIN (BTS, BTS, \"bts\", \"core.bitop\", \"FNaNbNiPkkZi\")\nDEF_D_BUILTIN (BSF64, BSF, \"bsf\", \"core.bitop\", \"FNaNbNiNfmZi\")\nDEF_D_BUILTIN (BSR64, BSR, \"bsr\", \"core.bitop\", \"FNaNbNiNfmZi\")\nDEF_D_BUILTIN (BT64, BT, \"bt\", \"core.bitop\", \"FNaNbNixPmmZi\")\nDEF_D_BUILTIN (BTC64, BTC, \"btc\", \"core.bitop\", \"FNaNbNiPmmZi\")\nDEF_D_BUILTIN (BTR64, BTR, \"btr\", \"core.bitop\", \"FNaNbNiPmmZi\")\nDEF_D_BUILTIN (BTS64, BTS, \"bts\", \"core.bitop\", \"FNaNbNiPmmZi\")\nDEF_D_BUILTIN (BSWAP, BSWAP, \"bswap\", \"core.bitop\", \"FNaNbNiNfkZk\")\nDEF_D_BUILTIN (BSWAP64, BSWAP, \"bswap\", \"core.bitop\", \"FNaNbNiNfmZm\")\nDEF_D_BUILTIN (POPCNT, POPCNT, \"popcnt\", \"core.bitop\", \"FNaNbNiNfkZi\")\nDEF_D_BUILTIN (POPCNT64, POPCNT, \"popcnt\", \"core.bitop\", \"FNaNbNiNfmZi\")\nDEF_D_BUILTIN (VLOAD, VLOAD, \"volatileLoad\", \"core.bitop\", \"FNbNiNfPhZh\")\nDEF_D_BUILTIN (VLOAD16, VLOAD, \"volatileLoad\", \"core.bitop\", \"FNbNiNfPtZt\")\nDEF_D_BUILTIN (VLOAD32, VLOAD, \"volatileLoad\", \"core.bitop\", \"FNbNiNfPkZk\")\nDEF_D_BUILTIN (VLOAD64, VLOAD, \"volatileLoad\", \"core.bitop\", \"FNbNiNfPmZm\")\nDEF_D_BUILTIN (VSTORE, VSTORE, \"volatileStore\", \"core.bitop\", \"FNbNiNfPhhZv\")\nDEF_D_BUILTIN (VSTORE16, VSTORE, \"volatileStore\", \"core.bitop\", \"FNbNiNfPttZv\")\nDEF_D_BUILTIN (VSTORE32, VSTORE, \"volatileStore\", \"core.bitop\", \"FNbNiNfPkkZv\")\nDEF_D_BUILTIN (VSTORE64, VSTORE, \"volatileStore\", \"core.bitop\", \"FNbNiNfPmmZv\")\n\n/* core.checkedint intrinsics.  */\n\nDEF_D_BUILTIN (ADDS, ADDS, \"adds\", \"core.checkedint\", \"FNaNbNiNfiiKbZi\")\nDEF_D_BUILTIN (ADDSL, ADDS, \"adds\", \"core.checkedint\", \"FNaNbNiNfllKbZl\")\nDEF_D_BUILTIN (ADDU, ADDS, \"addu\", \"core.checkedint\", \"FNaNbNiNfkkKbZk\")\nDEF_D_BUILTIN (ADDUL, ADDS, \"addu\", \"core.checkedint\", \"FNaNbNiNfmmKbZm\")\nDEF_D_BUILTIN (SUBS, SUBS, \"subs\", \"core.checkedint\", \"FNaNbNiNfiiKbZi\")\nDEF_D_BUILTIN (SUBSL, SUBS, \"subs\", \"core.checkedint\", \"FNaNbNiNfllKbZl\")\nDEF_D_BUILTIN (SUBU, SUBS, \"subu\", \"core.checkedint\", \"FNaNbNiNfkkKbZk\")\nDEF_D_BUILTIN (SUBUL, SUBS, \"subu\", \"core.checkedint\", \"FNaNbNiNfmmKbZm\")\nDEF_D_BUILTIN (MULS, MULS, \"muls\", \"core.checkedint\", \"FNaNbNiNfiiKbZi\")\nDEF_D_BUILTIN (MULSL, MULS, \"muls\", \"core.checkedint\", \"FNaNbNiNfllKbZl\")\nDEF_D_BUILTIN (MULU, MULS, \"mulu\", \"core.checkedint\", \"FNaNbNiNfkkKbZk\")\nDEF_D_BUILTIN (MULUI, MULS, \"mulu\", \"core.checkedint\", \"FNaNbNiNfmkKbZm\")\nDEF_D_BUILTIN (MULUL, MULS, \"mulu\", \"core.checkedint\", \"FNaNbNiNfmmKbZm\")\nDEF_D_BUILTIN (NEGS, NEGS, \"negs\", \"core.checkedint\", \"FNaNbNiNfiKbZi\")\nDEF_D_BUILTIN (NEGSL, NEGS, \"negs\", \"core.checkedint\", \"FNaNbNiNflKbZl\")\n\n/* core.math intrinsics.  */\n\nDEF_D_BUILTIN (COS, COS, \"cos\", \"core.math\", \"FNaNbNiNfeZe\")\nDEF_D_BUILTIN (FABS, FABS, \"fabs\", \"core.math\", \"FNaNbNiNfeZe\")\nDEF_D_BUILTIN (LDEXP, LDEXP, \"ldexp\", \"core.math\", \"FNaNbNiNfeiZe\")\nDEF_D_BUILTIN (RINT, RINT, \"rint\", \"core.math\", \"FNaNbNiNfeZe\")\nDEF_D_BUILTIN (RNDTOL, RNDTOL, \"rndtol\", \"core.math\", \"FNaNbNiNfeZl\")\nDEF_D_BUILTIN (SIN, SIN, \"sin\", \"core.math\", \"FNaNbNiNfeZe\")\nDEF_D_BUILTIN (SQRTF, SQRTF, \"sqrt\", \"core.math\", \"FNaNbNiNffZf\")\nDEF_D_BUILTIN (SQRT, SQRT, \"sqrt\", \"core.math\", \"FNaNbNiNfdZd\")\nDEF_D_BUILTIN (SQRTL, SQRTL, \"sqrt\", \"core.math\", \"FNaNbNiNfeZe\")\n\n/* std.math intrinsics.  */\n\nDEF_D_BUILTIN (STD_COS, COS, \"cos\", \"std.math\", \"FNaNbNiNfeZe\")\nDEF_D_BUILTIN (STD_FABS, FABS, \"fabs\", \"std.math\", \"FNaNbNiNfeZe\")\nDEF_D_BUILTIN (STD_LDEXP, LDEXP, \"ldexp\", \"std.math\", \"FNaNbNiNfeiZe\")\nDEF_D_BUILTIN (STD_RINT, RINT, \"rint\", \"std.math\", \"FNaNbNiNfeZe\")\nDEF_D_BUILTIN (STD_RNDTOL, RNDTOL, \"rndtol\", \"std.math\", \"FNaNbNiNfeZl\")\nDEF_D_BUILTIN (STD_SIN, SIN, \"sin\", \"std.math\", \"FNaNbNiNfeZe\")\nDEF_D_BUILTIN (STD_SQRTF, SQRTF, \"sqrt\", \"std.math\", \"FNaNbNiNffZf\")\nDEF_D_BUILTIN (STD_SQRT, SQRT, \"sqrt\", \"std.math\", \"FNaNbNiNfdZd\")\nDEF_D_BUILTIN (STD_SQRTL, SQRTL, \"sqrt\", \"std.math\", \"FNaNbNiNfeZe\")\n\nDEF_CTFE_BUILTIN (TAN, TAN, \"tan\", \"std.math\", \"FNaNbNiNeeZe\")\nDEF_CTFE_BUILTIN (ISNAN, ISNAN, \"isNaN\", \"std.math\", \"FNaNbNiNeI1XZb\")\nDEF_CTFE_BUILTIN (ISINFINITY, ISINFINITY, \"isInfinity\", \"std.math\",\n\t\t  \"FNaNbNiNeI1XZb\")\nDEF_CTFE_BUILTIN (ISFINITE, ISFINITE, \"isFinite\", \"std.math\", \"FNaNbNiNeI1XZb\")\n\nDEF_CTFE_BUILTIN (EXP, EXP, \"exp\", \"std.math\", \"FNaNbNiNeeZe\")\nDEF_CTFE_BUILTIN (EXPM1, EXPM1, \"expm1\", \"std.math\", \"FNaNbNiNeeZe\")\nDEF_CTFE_BUILTIN (EXP2, EXP2, \"exp2\", \"std.math\", \"FNaNbNiNeeZe\")\n\nDEF_CTFE_BUILTIN (LOG, LOG, \"log\", \"std.math\", \"FNaNbNiNfeZe\")\nDEF_CTFE_BUILTIN (LOG2, LOG2, \"log2\", \"std.math\", \"FNaNbNiNfeZe\")\nDEF_CTFE_BUILTIN (LOG10, LOG10, \"log10\", \"std.math\", \"FNaNbNiNfeZe\")\n\nDEF_CTFE_BUILTIN (ROUND, ROUND, \"round\", \"std.math\", \"FNaNbNiNeeZe\")\nDEF_CTFE_BUILTIN (FLOORF, FLOORF, \"floor\", \"std.math\", \"FNaNbNiNefZf\")\nDEF_CTFE_BUILTIN (FLOOR, FLOOR, \"floor\", \"std.math\", \"FNaNbNiNedZd\")\nDEF_CTFE_BUILTIN (FLOORL, FLOORL, \"floor\", \"std.math\", \"FNaNbNiNeeZe\")\nDEF_CTFE_BUILTIN (CEILF, CEILF, \"ceil\", \"std.math\", \"FNaNbNiNefZf\")\nDEF_CTFE_BUILTIN (CEIL, CEIL, \"ceil\", \"std.math\", \"FNaNbNiNedZd\")\nDEF_CTFE_BUILTIN (CEILL, CEILL, \"ceil\", \"std.math\", \"FNaNbNiNeeZe\")\n\nDEF_CTFE_BUILTIN (TRUNC, TRUNC, \"trunc\", \"std.math\", \"FNaNbNiNeeZe\")\nDEF_CTFE_BUILTIN (FMIN, FMIN, \"fmin\", \"std.math\", \"FNaNbNiNfeeZe\")\nDEF_CTFE_BUILTIN (FMAX, FMAX, \"fmax\", \"std.math\", \"FNaNbNiNfeeZe\")\nDEF_CTFE_BUILTIN (COPYSIGN, COPYSIGN, \"copysign\", \"std.math\",\n\t\t  \"FNaNbNiNeI1RI1XZI1R\")\nDEF_CTFE_BUILTIN (COPYSIGNI, COPYSIGN, \"copysign\", \"std.math\",\n\t\t  \"FNaNbNiNeI1XI1RZI1R\")\n\nDEF_CTFE_BUILTIN (POW, POW, \"pow\", \"std.math\", \"FNaNbNiNeI1FI1GZ@\")\nDEF_CTFE_BUILTIN (FMA, FMA, \"fma\", \"std.math\", \"FNaNbNiNfeeeZe\")\n\n/* core.stdc.stdarg intrinsics.  */\n\nDEF_D_BUILTIN (VA_ARG, VA_ARG, \"va_arg\", \"core.stdc.stdarg\",\n\t       \"FKI7va_listKI1TZv\")\nDEF_D_BUILTIN (C_VA_ARG, C_VA_ARG, \"va_arg\", \"core.stdc.stdarg\",\n\t       \"FKI7va_listZI1T\")\nDEF_D_BUILTIN (VASTART, VASTART, \"va_start\", \"core.stdc.stdarg\",\n\t       \"FJI7va_listKI1TZv\")\n\n#undef DEF_D_BUILTIN\n#undef DEF_CTFE_BUILTIN\n"
  },
  {
    "path": "gcc/d/lang-specs.h",
    "content": "/* lang-specs.h -- GCC driver specs for D frontend.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify it under\nthe terms of the GNU General Public License as published by the Free\nSoftware Foundation; either version 3, or (at your option) any later\nversion.\n\nGCC is distributed in the hope that it will be useful, but WITHOUT ANY\nWARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nfor more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n/* This is the contribution to the `default_compilers' array in gcc.c\n   for the D language.  */\n\n{\".d\", \"@d\", 0, 1, 0 },\n{\".dd\", \"@d\", 0, 1, 0 },\n{\".di\", \"@d\", 0, 1, 0 },\n{\"@d\",\n  \"%{!E:d21 %i %(cc1_options) %I %{nostdinc*} %{i*} %{I*} %{J*} \\\n    %{H} %{Hd*} %{Hf*} %{MD:-MD %b.deps} %{MMD:-MMD %b.deps} \\\n    %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*} \\\n    %{X:-Xf %b.json} %{Xf*} \\\n    %{v} %{!fsyntax-only:%(invoke_as)}}\", 0, 1, 0 },\n"
  },
  {
    "path": "gcc/d/lang.opt",
    "content": "; lang.opt -- Options for the D front end.\n; Copyright (C) 2006-2018 Free Software Foundation, Inc.\n;\n; GCC is free software; you can redistribute it and/or modify it under\n; the terms of the GNU General Public License as published by the Free\n; Software Foundation; either version 3, or (at your option) any later\n; version.\n;\n; GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n; WARRANTY; without even the implied warranty of MERCHANTABILITY or\n; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n; for more details.\n;\n; You should have received a copy of the GNU General Public License\n; along with GCC; see the file COPYING3.  If not see\n; <http://www.gnu.org/licenses/>.\n\n; See the GCC internals manual for a description of this file's format.\n\n; Please try to keep this file in ASCII collating order.\n\nLanguage\nD\n\n-dependencies\nD Alias(M)\n; Documented in C\n\n-print-missing-file-dependencies\nD Alias(MG)\n; Documented in C\n\n-user-dependencies\nD Alias(MM)\n; Documented in C\n\n-write-dependencies\nD NoDriverArg Separate Alias(MD)\n; Documented in C\n\n-write-user-dependencies\nD NoDriverArg Separate Alias(MMD)\n; Documented in C\n\nH\nD\n; Different from documented use in C.\n\nHd\nD Joined Separate\n-Hd <dir>\tWrite D interface files to directory <dir>.\n\nHf\nD Joined Separate\n-Hf <file>\tWrite D interface to <file>.\n\nI\nD Joined Separate\n; Documented in C\n\nJ\nD Joined Separate\n; Different from documented use in Fortran.\n\nM\nD\n; Documented in C\n\nMD\nD Separate NoDriverArg\n; Documented in C\n\nMF\nD Joined Separate\n; Documented in C\n\nMG\nD\n; Documented in C\n\nMM\nD\n; Documented in C\n\nMMD\nD Separate NoDriverArg\n; Documented in C\n\nMP\nD\n; Documented in C\n\nMT\nD Joined Separate\n; Documented in C\n\nMQ\nD Joined Separate\n; Documented in C\n\nWaddress\nD Warning Var(warn_address)\n; Documented in C\n\nWall\nD\n; Documented in C\n\nWcast-result\nD Warning Var(warn_cast_result)\nWarn about casts that will produce a null result.\n\nWdeprecated\nD\n; Documented in C\n\nWerror\nD\n; Documented in common.opt\n\nWalloca\nD\n; Documented in C\n\nWalloca-larger-than=\nD\n; Documented in C\n\nWno-alloca-larger-than\nD\n; Documented in C\n\nWspeculative\nD\nWarn from speculative compiles such as __traits(compiles).\n\nWtemplates\nD\n; Documented in C\n\nWunknown-pragmas\nD LangEnabledBy(D, Wall)\n; Documented in C\n\nX\nD\nGenerate JSON file.\n\nXf\nD Joined Separate\n-Xf <file>\tWrite JSON output to the given <file>.\n\ndebuglib=\nDriver Joined\nDebug library to use instead of phobos.\n\ndefaultlib=\nDriver Joined\nDefault library to use instead of phobos.\n\n-verbose\nD Alias(v)\n\nfall-instantiations\nD\nGenerate code for all template instantiations.\n\nfassert\nD Var(flag_assert)\nGenerate code for assert contracts.\n\nfbounds-check\nD\n; Documented in common.opt\n\nfbounds-check=\nD Joined RejectNegative Enum(bounds_check) Var(flag_bounds_check)\n-fbounds-check=[on|safeonly|off]\tTurn array bounds checks on, in @safe code only, or off.\n\nEnum\nName(bounds_check) Type(int) UnknownError(unknown array bounds setting %qs)\n\nEnumValue\nEnum(bounds_check) String(off) Value(0)\n\nEnumValue\nEnum(bounds_check) String(safeonly) Value(1)\n\nEnumValue\nEnum(bounds_check) String(on) Value(2)\n\nfbuiltin\nD Var(flag_no_builtin, 0)\n; Documented in C\n\nfdebug\nD\nCompile in debug code.\n\nfdebug=\nD Joined RejectNegative\n-fdebug=<level|ident>\tCompile in debug code, code <= <level>, or code identified by <ident>.\n\nfdoc\nD\nGenerate documentation.\n\nfdoc-dir=\nD Joined RejectNegative\n-fdoc-dir=<dir>\tWrite documentation file to directory <dir>.\n\nfdoc-file=\nD Joined RejectNegative\n-fdoc-file=<file>\tWrite documentation to <file>.\n\nfdoc-inc=\nD Joined RejectNegative\n-fdoc-inc=<file>\tInclude a Ddoc macro <file>.\n\nfdruntime\nD\nAssume that standard D runtime libraries and \\\"D main\\\" exist.\n\nfdump-d-original\nD\nDisplay the frontend AST after parsing and semantic passes.\n\nfignore-unknown-pragmas\nD\nIgnore unsupported pragmas.\n\nfinvariants\nD Var(flag_invariants)\nGenerate code for class invariant contracts.\n\nfmain\nD RejectNegative\nGenerate a default D main() function when compiling.\n\nfmodule-file=\nD Joined RejectNegative\n-fmodule-file=<package.module>=<filespec>\tuse <filespec> as source file for <package.module>.\n\nfmoduleinfo\nD Var(flag_moduleinfo)\nGenerate ModuleInfo struct for output module.\n\nfonly=\nD Joined RejectNegative\nProcess all modules specified on the command line, but only generate code for the module specified by the argument.\n\nfpostconditions\nD Var(flag_postconditions)\nGenerate code for postcondition contracts.\n\nfpreconditions\nD Var(flag_preconditions)\nGenerate code for precondition contracts.\n\nfrelease\nD\nCompile release version.\n\nfrtti\nD\n; Documented in C\n\nfswitch-errors\nD Var(flag_switch_errors)\nGenerate code for switches without a default case.\n\nftransition=all\nD RejectNegative\nList information on all language changes.\n\nftransition=checkimports\nD RejectNegative\nGive deprecation messages about -ftransition=import anomalies.\n\nftransition=complex\nD RejectNegative\nList all usages of complex or imaginary types.\n\nftransition=dip1000\nD RejectNegative\nImplement DIP1000: Scoped pointers (experimental).\n\nftransition=dip1008\nD RejectNegative\nImplement DIP1008: Allow exceptions in @nogc code (experimental).\n\nftransition=dip25\nD RejectNegative\nImplement DIP25: Sealed references (experimental).\n\nftransition=dtorfields\nD RejectNegative\nDestruct fields of partially constructed objects.\n\nftransition=field\nD RejectNegative\nList all non-mutable fields which occupy an object instance.\n\nftransition=import\nD RejectNegative\nRevert to single phase name lookup.\n\nftransition=intpromote\nD RejectNegative\nUse C-style integral promotion for unary '+', '-' and '~'.\n\nftransition=nogc\nD RejectNegative\nList all hidden GC allocations.\n\nftransition=tls\nD RejectNegative\nList all variables going into thread local storage.\n\nfunittest\nD\nCompile in unittest code.\n\nfversion=\nD Joined RejectNegative\n-fversion=<level|ident>\tCompile in version code >= <level> or identified by <ident>.\n\nfweak\nD Var(flag_weak) Init(1)\nEmit common-like symbols as weak symbols.\n\nimultilib\nD Joined Separate\n; Documented in C\n\niprefix\nD Joined Separate\n; Documented in C\n\nisysroot\nD Joined Separate\n; Documented in C\n\nisystem\nD Joined Separate\n; Documented in C\n\nnophoboslib\nDriver\nDo not link the standard D library in the compilation.\n\nnostdinc\nD\n; Documented in C\n\nstatic-libphobos\nDriver\nLink the standard D library statically in the compilation.\n\nshared-libphobos\nDriver\nLink the standard D library dynamically in the compilation.\n\nv\nD\n; Documented in C\n"
  },
  {
    "path": "gcc/d/longdouble.h",
    "content": "/* longdouble.h -- Definitions of floating-point access for the frontend.\n   Copyright (C) 2015-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#ifndef GCC_D_LONGDOUBLE_H\n#define GCC_D_LONGDOUBLE_H\n\nstruct real_value;\nclass Type;\n\nstruct longdouble\n{\npublic:\n  /* Return the hidden real_value from the longdouble type.  */\n  const real_value& rv (void) const\n  { return *(const real_value *) this; }\n\n  real_value& rv (void)\n  { return *(real_value *) this; }\n\n  /* Normalize the value to be the precision supported by target.  */\n  longdouble normalize (void);\n\n  /* No constructor to be able to use this class in a union.  */\n  template<typename T> longdouble& operator = (T x)\n  { set (x); return *this; }\n\n  /* Lvalue operators.  */\n  void set (real_value& d);\n  void set (int32_t d);\n  void set (int64_t d);\n  void set (uint32_t d);\n  void set (uint64_t d);\n  void set (bool d);\n\n  /* Rvalue operators.  */\n  bool to_bool () const;\n  int64_t to_int () const;\n  uint64_t to_uint () const;\n\n  operator int32_t (void)\n  { return (int32_t) this->to_int (); }\n\n  operator int64_t (void)\n  { return this->to_int (); }\n\n  operator uint32_t (void)\n  { return (uint32_t) this->to_uint (); }\n\n  operator uint64_t (void)\n  { return this->to_uint (); }\n\n  operator bool (void)\n  { return this->to_bool (); }\n\n  /* Arithmetic operators.  */\n  longdouble add (const longdouble& r) const;\n  longdouble sub (const longdouble& r) const;\n  longdouble mul (const longdouble& r) const;\n  longdouble div (const longdouble& r) const;\n  longdouble mod (const longdouble& r) const;\n  longdouble neg () const;\n\n  longdouble operator + (const longdouble& r)\n  { return this->add (r); }\n\n  longdouble operator - (const longdouble& r)\n  { return this->sub (r); }\n\n  longdouble operator * (const longdouble& r)\n  { return this->mul (r); }\n\n  longdouble operator / (const longdouble& r)\n  { return this->div (r); }\n\n  longdouble operator % (const longdouble& r)\n  { return this->mod (r); }\n\n  longdouble operator -()\n  { return this->neg (); }\n\n  /* Comparison operators.  */\n  int cmp (const longdouble& t) const;\n  int equals (const longdouble& t) const;\n\n  bool operator < (const longdouble& r)\n  { return this->cmp (r) < 0; }\n\n  bool operator <= (const longdouble& r)\n  { return this->cmp (r) <= 0; }\n\n  bool operator > (const longdouble& r)\n  { return this->cmp (r) > 0; }\n\n  bool operator >= (const longdouble& r)\n  { return this->cmp (r) >= 0; }\n\n  bool operator == (const longdouble& r)\n  { return this->equals (r); }\n\n  bool operator != (const longdouble& r)\n  { return !this->equals (r); }\n\nprivate:\n  /* Including gcc/real.h presents too many problems, so just\n     statically allocate enough space for REAL_VALUE_TYPE.  */\n  long realvalue[(2 + (16 + sizeof (long)) / sizeof (long))];\n};\n\n/* Declared, but \"volatile\" is not required.  */\ntypedef longdouble volatile_longdouble;\n\n/* Use ldouble() to explicitly create a longdouble value.  */\ntemplate<typename T>\ninline longdouble\nldouble (T x)\n{\n  longdouble d;\n  d.set (x);\n  return d;\n}\n\n#endif  /* GCC_D_LONGDOUBLE_H  */\n"
  },
  {
    "path": "gcc/d/modules.cc",
    "content": "/* modules.cc -- D module initialization and termination.\n   Copyright (C) 2013-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/declaration.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/module.h\"\n\n#include \"tree.h\"\n#include \"fold-const.h\"\n#include \"tm.h\"\n#include \"function.h\"\n#include \"cgraph.h\"\n#include \"stor-layout.h\"\n#include \"toplev.h\"\n#include \"target.h\"\n#include \"common/common-target.h\"\n#include \"stringpool.h\"\n\n#include \"d-tree.h\"\n\n\n/* D generates module information to inform the runtime library which modules\n   need some kind of special handling.  All `static this()', `static ~this()',\n   and `unittest' functions for a given module are aggregated into a single\n   function - one for each kind - and a pointer to that function is inserted\n   into the ModuleInfo instance for that module.\n\n   Module information for a particular module is indicated with an ABI defined\n   structure derived from ModuleInfo.  ModuleInfo is a variably sized struct\n   with two fixed base fields.  The first field `flags' determines what\n   information is packed immediately after the record type.\n\n   Like TypeInfo, the runtime library provides the definitions of the ModuleInfo\n   structure, as well as accessors for the variadic fields.  So we only define\n   layout compatible POD_structs for ModuleInfo.  */\n\n/* The internally represented ModuleInfo and CompilerDSO types.  */\nstatic tree moduleinfo_type;\nstatic tree compiler_dso_type;\nstatic tree dso_registry_fn;\n\n/* The DSO slot for use by the druntime implementation.  */\nstatic tree dso_slot_node;\n\n/* For registering and deregistering DSOs with druntime, we have one global\n   constructor and destructor per object that calls _d_dso_registry with the\n   respective DSO record.  To ensure that this is only done once, a\n   `dso_initialized' variable is introduced to guard repeated calls.  */\nstatic tree dso_initialized_node;\n\n/* The beginning and end of the `minfo' section.  */\nstatic tree start_minfo_node;\nstatic tree stop_minfo_node;\n\n/* Record information about module initialization, termination,\n   unit testing, and thread local storage in the compilation.  */\n\nstruct GTY(()) module_info\n{\n  vec<tree, va_gc> *ctors;\n  vec<tree, va_gc> *dtors;\n  vec<tree, va_gc> *ctorgates;\n\n  vec<tree, va_gc> *sharedctors;\n  vec<tree, va_gc> *shareddtors;\n  vec<tree, va_gc> *sharedctorgates;\n\n  vec<tree, va_gc> *unitTests;\n};\n\n/* These must match the values in libdruntime/object_.d.  */\n\nenum module_info_flags\n{\n  MIctorstart\t    = 0x1,\n  MIctordone\t    = 0x2,\n  MIstandalone\t    = 0x4,\n  MItlsctor\t    = 0x8,\n  MItlsdtor\t    = 0x10,\n  MIctor\t    = 0x20,\n  MIdtor\t    = 0x40,\n  MIxgetMembers\t    = 0x80,\n  MIictor\t    = 0x100,\n  MIunitTest\t    = 0x200,\n  MIimportedModules = 0x400,\n  MIlocalClasses    = 0x800,\n  MIname\t    = 0x1000\n};\n\n/* The ModuleInfo information structure for the module currently being compiled.\n   Assuming that only ever process one at a time.  */\n\nstatic module_info *current_moduleinfo;\n\n/* The declaration of the current module being compiled.  */\n\nstatic Module *current_module_decl;\n\n/* Static constructors and destructors (not D `static this').  */\n\nstatic GTY(()) vec<tree, va_gc> *static_ctor_list;\nstatic GTY(()) vec<tree, va_gc> *static_dtor_list;\n\n/* Returns an internal function identified by IDENT.  This is used\n   by both module initialization and dso handlers.  */\n\nstatic FuncDeclaration *\nget_internal_fn (tree ident)\n{\n  Module *mod = current_module_decl;\n  const char *name = IDENTIFIER_POINTER (ident);\n\n  if (!mod)\n    mod = Module::rootModule;\n\n  if (name[0] == '*')\n    {\n      tree s = mangle_internal_decl (mod, name + 1, \"FZv\");\n      name = IDENTIFIER_POINTER (s);\n    }\n\n  FuncDeclaration *fd = FuncDeclaration::genCfunc (NULL, Type::tvoid,\n\t\t\t\t\t\t   Identifier::idPool (name));\n  fd->loc = Loc (mod->srcfile->toChars (), 1, 0);\n  fd->parent = mod;\n  fd->protection.kind = Prot::private_;\n  fd->semanticRun = PASSsemantic3done;\n\n  return fd;\n}\n\n/* Generate an internal function identified by IDENT.\n   The function body to add is in EXPR.  */\n\nstatic tree\nbuild_internal_fn (tree ident, tree expr)\n{\n  FuncDeclaration *fd = get_internal_fn (ident);\n  tree decl = get_symbol_decl (fd);\n\n  tree old_context = start_function (fd);\n  rest_of_decl_compilation (decl, 1, 0);\n  add_stmt (expr);\n  finish_function (old_context);\n\n  /* D static ctors, static dtors, unittests, and the ModuleInfo\n     chain function are always private.  */\n  TREE_PUBLIC (decl) = 0;\n  TREE_USED (decl) = 1;\n  DECL_ARTIFICIAL (decl) = 1;\n\n  return decl;\n}\n\n/* Build and emit a function identified by IDENT that increments (in order)\n   all variables in GATES, then calls the list of functions in FUNCTIONS.  */\n\nstatic tree\nbuild_funcs_gates_fn (tree ident, vec<tree, va_gc> *functions,\n\t\t      vec<tree, va_gc> *gates)\n{\n  tree expr_list = NULL_TREE;\n\n  /* Increment gates first.  */\n  for (size_t i = 0; i < vec_safe_length (gates); i++)\n    {\n      tree decl = (*gates)[i];\n      tree value = build2 (PLUS_EXPR, TREE_TYPE (decl),\n\t\t\t   decl, integer_one_node);\n      tree var_expr = modify_expr (decl, value);\n      expr_list = compound_expr (expr_list, var_expr);\n    }\n\n  /* Call Functions.  */\n  for (size_t i = 0; i < vec_safe_length (functions); i++)\n    {\n      tree decl = (*functions)[i];\n      tree call_expr = build_call_expr (decl, 0);\n      expr_list = compound_expr (expr_list, call_expr);\n    }\n\n  if (expr_list)\n    return build_internal_fn (ident, expr_list);\n\n  return NULL_TREE;\n}\n\n/* Return the type for ModuleInfo, create it if it doesn't already exist.  */\n\nstatic tree\nget_moduleinfo_type (void)\n{\n  if (moduleinfo_type)\n    return moduleinfo_type;\n\n  /* Layout of ModuleInfo is:\n\tuint flags;\n\tuint index;  */\n  tree fields = create_field_decl (d_uint_type, NULL, 1, 1);\n  DECL_CHAIN (fields) = create_field_decl (d_uint_type, NULL, 1, 1);\n\n  moduleinfo_type = make_node (RECORD_TYPE);\n  finish_builtin_struct (moduleinfo_type, \"ModuleInfo\", fields, NULL_TREE);\n\n  return moduleinfo_type;\n}\n\n/* Get the VAR_DECL of the ModuleInfo for DECL.  If this does not yet exist,\n   create it.  The ModuleInfo decl is used to keep track of constructors,\n   destructors, unittests, members, classes, and imports for the given module.\n   This is used by the D runtime for module initialization and termination.  */\n\nstatic tree\nget_moduleinfo_decl (Module *decl)\n{\n  if (decl->csym)\n    return decl->csym;\n\n  tree ident = mangle_internal_decl (decl, \"__ModuleInfo\", \"Z\");\n  tree type = get_moduleinfo_type ();\n\n  decl->csym = declare_extern_var (ident, type);\n  DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (NULL);\n\n  DECL_CONTEXT (decl->csym) = build_import_decl (decl);\n  /* Not readonly, moduleinit depends on this.  */\n  TREE_READONLY (decl->csym) = 0;\n\n  return decl->csym;\n}\n\n/* Return the type for CompilerDSOData, create it if it doesn't exist.  */\n\nstatic tree\nget_compiler_dso_type (void)\n{\n  if (compiler_dso_type)\n    return compiler_dso_type;\n\n  /* Layout of CompilerDSOData is:\n\tsize_t version;\n\tvoid** slot;\n\tModuleInfo** _minfo_beg;\n\tModuleInfo** _minfo_end;\n\tFuncTable* _deh_beg;\n\tFuncTable* _deh_end;\n\n     Note, finish_builtin_struct() expects these fields in reverse order.  */\n  tree fields = create_field_decl (ptr_type_node, NULL, 1, 1);\n  tree field = create_field_decl (ptr_type_node, NULL, 1, 1);\n  DECL_CHAIN (field) = fields;\n  fields = field;\n\n  field = create_field_decl (build_pointer_type (get_moduleinfo_type ()),\n\t\t\t     NULL, 1, 1);\n  DECL_CHAIN (field) = fields;\n  fields = field;\n  field = create_field_decl (build_pointer_type (get_moduleinfo_type ()),\n\t\t\t     NULL, 1, 1);\n  DECL_CHAIN (field) = fields;\n  fields = field;\n\n  field = create_field_decl (build_pointer_type (ptr_type_node), NULL, 1, 1);\n  DECL_CHAIN (field) = fields;\n  fields = field;\n\n  field = create_field_decl (size_type_node, NULL, 1, 1);\n  DECL_CHAIN (field) = fields;\n  fields = field;\n\n  compiler_dso_type = make_node (RECORD_TYPE);\n  finish_builtin_struct (compiler_dso_type, \"CompilerDSOData\",\n\t\t\t fields, NULL_TREE);\n\n  return compiler_dso_type;\n}\n\n/* Returns the _d_dso_registry FUNCTION_DECL.  */\n\nstatic tree\nget_dso_registry_fn (void)\n{\n  if (dso_registry_fn)\n    return dso_registry_fn;\n\n  tree dso_type = get_compiler_dso_type ();\n  tree fntype = build_function_type_list (void_type_node,\n\t\t\t\t\t  build_pointer_type (dso_type),\n\t\t\t\t\t  NULL_TREE);\n  dso_registry_fn = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,\n\t\t\t\tget_identifier (\"_d_dso_registry\"), fntype);\n  TREE_PUBLIC (dso_registry_fn) = 1;\n  DECL_EXTERNAL (dso_registry_fn) = 1;\n\n  return dso_registry_fn;\n}\n\n/* Depending on CTOR_P, builds and emits eiter a constructor or destructor\n   calling _d_dso_registry if `dso_initialized' is `false' in a constructor\n   or `true' in a destructor.  */\n\nstatic tree\nbuild_dso_cdtor_fn (bool ctor_p)\n{\n  const char *name = ctor_p ? GDC_PREFIX (\"dso_ctor\") : GDC_PREFIX (\"dso_dtor\");\n  tree condition = ctor_p ? boolean_true_node : boolean_false_node;\n\n  /* Declaration of dso_ctor/dso_dtor is:\n\n     extern(C) void dso_{c,d}tor (void)\n     {\n\tif (dso_initialized != condition)\n\t{\n\t    dso_initialized = condition;\n\t    CompilerDSOData dso = {1, &dsoSlot, &__start_minfo, &__stop_minfo};\n\t    _d_dso_registry (&dso);\n\t}\n    }\n   */\n  FuncDeclaration *fd = get_internal_fn (get_identifier (name));\n  tree decl = get_symbol_decl (fd);\n\n  TREE_PUBLIC (decl) = 1;\n  DECL_ARTIFICIAL (decl) = 1;\n  DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;\n  DECL_VISIBILITY_SPECIFIED (decl) = 1;\n\n  d_comdat_linkage (decl);\n\n  /* Start laying out the body.  */\n  tree old_context = start_function (fd);\n  rest_of_decl_compilation (decl, 1, 0);\n\n  /* if (dso_initialized != condition).  */\n  tree if_cond = build_boolop (NE_EXPR, dso_initialized_node, condition);\n\n  /* dso_initialized = condition;  */\n  tree expr_list = modify_expr (dso_initialized_node, condition);\n\n  /* CompilerDSOData dso = {1, &dsoSlot, &__start_minfo, &__stop_minfo};  */\n  tree dso_type = get_compiler_dso_type ();\n  tree dso = build_local_temp (dso_type);\n\n  vec<constructor_elt, va_gc> *ve = NULL;\n  CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_integer_cst (1, size_type_node));\n  CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (dso_slot_node));\n  CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (start_minfo_node));\n  CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (stop_minfo_node));\n\n  tree assign_expr = modify_expr (dso, build_struct_literal (dso_type, ve));\n  expr_list = compound_expr (expr_list, assign_expr);\n\n  /* _d_dso_registry (&dso);  */\n  tree call_expr = build_call_expr (get_dso_registry_fn (), 1,\n\t\t\t\t    build_address (dso));\n  expr_list = compound_expr (expr_list, call_expr);\n\n  add_stmt (build_vcondition (if_cond, expr_list, void_node));\n  finish_function (old_context);\n\n  return decl;\n}\n\n/* Build a variable used in the dso_registry code identified by NAME,\n   and data type TYPE.  The variable always has VISIBILITY_HIDDEN and\n   TREE_PUBLIC flags set.  */\n\nstatic tree\nbuild_dso_registry_var (const char * name, tree type)\n{\n  tree var = declare_extern_var (get_identifier (name), type);\n  DECL_VISIBILITY (var) = VISIBILITY_HIDDEN;\n  DECL_VISIBILITY_SPECIFIED (var) = 1;\n  return var;\n}\n\n/* Place a reference to the ModuleInfo symbol MINFO for DECL into the\n   `minfo' section.  Then create the global ctors/dtors to call the\n   _d_dso_registry function if necessary.  */\n\nstatic void\nregister_moduleinfo (Module *decl, tree minfo)\n{\n  gcc_assert (targetm_common.have_named_sections);\n\n  /* Build the ModuleInfo reference, this is done once for every Module.  */\n  tree ident = mangle_internal_decl (decl, \"__moduleRef\", \"Z\");\n  tree mref = declare_extern_var (ident, ptr_type_node);\n\n  /* Build the initializer and emit.  Do not start section with a `.' character\n     so that the linker will provide a __start_ and __stop_ symbol to indicate\n     the start and end address of the section respectively.\n     https://sourceware.org/binutils/docs-2.26/ld/Orphan-Sections.html.  */\n  DECL_INITIAL (mref) = build_address (minfo);\n  DECL_EXTERNAL (mref) = 0;\n  DECL_PRESERVE_P (mref) = 1;\n\n  set_decl_section_name (mref, \"minfo\");\n  d_pushdecl (mref);\n  rest_of_decl_compilation (mref, 1, 0);\n\n  /* Only for the first D module being emitted do we need to generate a static\n     constructor and destructor for.  These are only required once per shared\n     library, so it's safe to emit them only once per object file.  */\n  static bool first_module = true;\n  if (!first_module)\n    return;\n\n  start_minfo_node = build_dso_registry_var (\"__start_minfo\", ptr_type_node);\n  rest_of_decl_compilation (start_minfo_node, 1, 0);\n\n  stop_minfo_node = build_dso_registry_var (\"__stop_minfo\", ptr_type_node);\n  rest_of_decl_compilation (stop_minfo_node, 1, 0);\n\n  /* Declare dso_slot and dso_initialized.  */\n  dso_slot_node = build_dso_registry_var (GDC_PREFIX (\"dso_slot\"),\n\t\t\t\t\t  ptr_type_node);\n  DECL_EXTERNAL (dso_slot_node) = 0;\n  d_comdat_linkage (dso_slot_node);\n  rest_of_decl_compilation (dso_slot_node, 1, 0);\n\n  dso_initialized_node = build_dso_registry_var (GDC_PREFIX (\"dso_initialized\"),\n\t\t\t\t\t\t boolean_type_node);\n  DECL_EXTERNAL (dso_initialized_node) = 0;\n  d_comdat_linkage (dso_initialized_node);\n  rest_of_decl_compilation (dso_initialized_node, 1, 0);\n\n  /* Declare dso_ctor() and dso_dtor().  */\n  tree dso_ctor = build_dso_cdtor_fn (true);\n  vec_safe_push (static_ctor_list, dso_ctor);\n\n  tree dso_dtor = build_dso_cdtor_fn (false);\n  vec_safe_push (static_dtor_list, dso_dtor);\n\n  first_module = false;\n}\n\n/* Convenience function for layout_moduleinfo_fields.  Adds a field of TYPE to\n   the moduleinfo record at OFFSET, incrementing the offset to the next field\n   position.  No alignment is taken into account, all fields are packed.  */\n\nstatic void\nlayout_moduleinfo_field (tree type, tree rec_type, HOST_WIDE_INT& offset)\n{\n  tree field = create_field_decl (type, NULL, 1, 1);\n  insert_aggregate_field (rec_type, field, offset);\n  offset += int_size_in_bytes (type);\n}\n\n/* Layout fields that immediately come after the moduleinfo TYPE for DECL.\n   Data relating to the module is packed into the type on an as-needed\n   basis, this is done to keep its size to a minimum.  */\n\nstatic tree\nlayout_moduleinfo_fields (Module *decl, tree type)\n{\n  HOST_WIDE_INT offset = int_size_in_bytes (type);\n  type = copy_aggregate_type (type);\n\n  /* First fields added are all the function pointers.  */\n  if (decl->sctor)\n    layout_moduleinfo_field (ptr_type_node, type, offset);\n\n  if (decl->sdtor)\n    layout_moduleinfo_field (ptr_type_node, type, offset);\n\n  if (decl->ssharedctor)\n    layout_moduleinfo_field (ptr_type_node, type, offset);\n\n  if (decl->sshareddtor)\n    layout_moduleinfo_field (ptr_type_node, type, offset);\n\n  if (decl->findGetMembers ())\n    layout_moduleinfo_field (ptr_type_node, type, offset);\n\n  if (decl->sictor)\n    layout_moduleinfo_field (ptr_type_node, type, offset);\n\n  if (decl->stest)\n    layout_moduleinfo_field (ptr_type_node, type, offset);\n\n  /* Array of module imports is laid out as a length field, followed by\n     a static array of ModuleInfo pointers.  */\n  size_t aimports_dim = decl->aimports.dim;\n  for (size_t i = 0; i < decl->aimports.dim; i++)\n    {\n      Module *mi = decl->aimports[i];\n      if (!mi->needmoduleinfo)\n\taimports_dim--;\n    }\n\n  if (aimports_dim)\n    {\n      layout_moduleinfo_field (size_type_node, type, offset);\n      layout_moduleinfo_field (make_array_type (Type::tvoidptr, aimports_dim),\n\t\t\t       type, offset);\n    }\n\n  /* Array of local ClassInfo decls are laid out in the same way.  */\n  ClassDeclarations aclasses;\n  for (size_t i = 0; i < decl->members->dim; i++)\n    {\n      Dsymbol *member = (*decl->members)[i];\n      member->addLocalClass (&aclasses);\n    }\n\n  if (aclasses.dim)\n    {\n      layout_moduleinfo_field (size_type_node, type, offset);\n      layout_moduleinfo_field (make_array_type (Type::tvoidptr, aclasses.dim),\n\t\t\t       type, offset);\n    }\n\n  /* Lastly, the name of the module is a static char array.  */\n  size_t namelen = strlen (decl->toPrettyChars ()) + 1;\n  layout_moduleinfo_field (make_array_type (Type::tchar, namelen),\n\t\t\t   type, offset);\n\n  finish_aggregate_type (offset, 1, type, NULL);\n\n  return type;\n}\n\n/* Output the ModuleInfo for module DECL and register it with druntime.  */\n\nstatic void\nlayout_moduleinfo (Module *decl)\n{\n  ClassDeclarations aclasses;\n  FuncDeclaration *sgetmembers;\n\n  for (size_t i = 0; i < decl->members->dim; i++)\n    {\n      Dsymbol *member = (*decl->members)[i];\n      member->addLocalClass (&aclasses);\n    }\n\n  size_t aimports_dim = decl->aimports.dim;\n  for (size_t i = 0; i < decl->aimports.dim; i++)\n    {\n      Module *mi = decl->aimports[i];\n      if (!mi->needmoduleinfo)\n\taimports_dim--;\n    }\n\n  sgetmembers = decl->findGetMembers ();\n\n  size_t flags = 0;\n  if (decl->sctor)\n    flags |= MItlsctor;\n  if (decl->sdtor)\n    flags |= MItlsdtor;\n  if (decl->ssharedctor)\n    flags |= MIctor;\n  if (decl->sshareddtor)\n    flags |= MIdtor;\n  if (sgetmembers)\n    flags |= MIxgetMembers;\n  if (decl->sictor)\n    flags |= MIictor;\n  if (decl->stest)\n    flags |= MIunitTest;\n  if (aimports_dim)\n    flags |= MIimportedModules;\n  if (aclasses.dim)\n    flags |= MIlocalClasses;\n  if (!decl->needmoduleinfo)\n    flags |= MIstandalone;\n\n  flags |= MIname;\n\n  tree minfo = get_moduleinfo_decl (decl);\n  tree type = layout_moduleinfo_fields (decl, TREE_TYPE (minfo));\n\n  /* Put out the two named fields in a ModuleInfo decl:\n\tuint flags;\n\tuint index;  */\n  vec<constructor_elt, va_gc> *minit = NULL;\n\n  CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,\n\t\t\t  build_integer_cst (flags, d_uint_type));\n\n  CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,\n\t\t\t  build_integer_cst (0, d_uint_type));\n\n  /* Order of appearance, depending on flags:\n\tvoid function() tlsctor;\n\tvoid function() tlsdtor;\n\tvoid* function() xgetMembers;\n\tvoid function() ctor;\n\tvoid function() dtor;\n\tvoid function() ictor;\n\tvoid function() unitTest;\n\tModuleInfo*[] importedModules;\n\tTypeInfo_Class[] localClasses;\n\tchar[N] name;\n   */\n  if (flags & MItlsctor)\n    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sctor));\n\n  if (flags & MItlsdtor)\n    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sdtor));\n\n  if (flags & MIctor)\n    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,\n\t\t\t    build_address (decl->ssharedctor));\n\n  if (flags & MIdtor)\n    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,\n\t\t\t    build_address (decl->sshareddtor));\n\n  if (flags & MIxgetMembers)\n    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,\n\t\t\t    build_address (get_symbol_decl (sgetmembers)));\n\n  if (flags & MIictor)\n    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sictor));\n\n  if (flags & MIunitTest)\n    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->stest));\n\n  if (flags & MIimportedModules)\n    {\n      vec<constructor_elt, va_gc> *elms = NULL;\n      tree satype = make_array_type (Type::tvoidptr, aimports_dim);\n      size_t idx = 0;\n\n      for (size_t i = 0; i < decl->aimports.dim; i++)\n\t{\n\t  Module *mi = decl->aimports[i];\n\t  if (mi->needmoduleinfo)\n\t    {\n\t      CONSTRUCTOR_APPEND_ELT (elms, size_int (idx),\n\t\t\t\t      build_address (get_moduleinfo_decl (mi)));\n\t      idx++;\n\t    }\n\t}\n\n      CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aimports_dim));\n      CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,\n\t\t\t      build_constructor (satype, elms));\n    }\n\n  if (flags & MIlocalClasses)\n    {\n      vec<constructor_elt, va_gc> *elms = NULL;\n      tree satype = make_array_type (Type::tvoidptr, aclasses.dim);\n\n      for (size_t i = 0; i < aclasses.dim; i++)\n\t{\n\t  ClassDeclaration *cd = aclasses[i];\n\t  CONSTRUCTOR_APPEND_ELT (elms, size_int (i),\n\t\t\t\t  build_address (get_classinfo_decl (cd)));\n\t}\n\n      CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aclasses.dim));\n      CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,\n\t\t\t      build_constructor (satype, elms));\n    }\n\n  if (flags & MIname)\n    {\n      /* Put out module name as a 0-terminated C-string, to save bytes.  */\n      const char *name = decl->toPrettyChars ();\n      size_t namelen = strlen (name) + 1;\n      tree strtree = build_string (namelen, name);\n      TREE_TYPE (strtree) = make_array_type (Type::tchar, namelen);\n      CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, strtree);\n    }\n\n  TREE_TYPE (minfo) = type;\n  DECL_INITIAL (minfo) = build_struct_literal (type, minit);\n  d_finish_decl (minfo);\n\n  /* Register the module against druntime.  */\n  register_moduleinfo (decl, minfo);\n}\n\n/* Send the Module AST class DECL to GCC back-end.  */\n\nvoid\nbuild_module_tree (Module *decl)\n{\n  /* There may be more than one module per object file, but should only\n     ever compile them one at a time.  */\n  assert (!current_moduleinfo && !current_module_decl);\n\n  module_info mi = module_info ();\n\n  current_moduleinfo = &mi;\n  current_module_decl = decl;\n\n  /* Layout module members.  */\n  if (decl->members)\n    {\n      for (size_t i = 0; i < decl->members->dim; i++)\n\t{\n\t  Dsymbol *s = (*decl->members)[i];\n\t  build_decl_tree (s);\n\t}\n    }\n\n  /* Default behavior is to always generate module info because of templates.\n     Can be switched off for not compiling against runtime library.  */\n  if (global.params.useModuleInfo\n      && Module::moduleinfo != NULL\n      && decl->ident != Identifier::idPool (\"__entrypoint\"))\n    {\n      if (mi.ctors || mi.ctorgates)\n\tdecl->sctor = build_funcs_gates_fn (get_identifier (\"*__modctor\"),\n\t\t\t\t\t    mi.ctors, mi.ctorgates);\n\n      if (mi.dtors)\n\tdecl->sdtor = build_funcs_gates_fn (get_identifier (\"*__moddtor\"),\n\t\t\t\t\t    mi.dtors, NULL);\n\n      if (mi.sharedctors || mi.sharedctorgates)\n\tdecl->ssharedctor\n\t  = build_funcs_gates_fn (get_identifier (\"*__modsharedctor\"),\n\t\t\t\t  mi.sharedctors, mi.sharedctorgates);\n\n      if (mi.shareddtors)\n\tdecl->sshareddtor\n\t  = build_funcs_gates_fn (get_identifier (\"*__modshareddtor\"),\n\t\t\t\t  mi.shareddtors, NULL);\n\n      if (mi.unitTests)\n\tdecl->stest = build_funcs_gates_fn (get_identifier (\"*__modtest\"),\n\t\t\t\t\t    mi.unitTests, NULL);\n\n      layout_moduleinfo (decl);\n    }\n\n  current_moduleinfo = NULL;\n  current_module_decl = NULL;\n}\n\n/* Returns the current function or module context for the purpose\n   of imported_module_or_decl.  */\n\ntree\nd_module_context (void)\n{\n  if (cfun != NULL)\n    return current_function_decl;\n\n  gcc_assert (current_module_decl != NULL);\n  return build_import_decl (current_module_decl);\n}\n\n/* Maybe record declaration D against our module information structure.  */\n\nvoid\nregister_module_decl (Declaration *d)\n{\n  FuncDeclaration *fd = d->isFuncDeclaration ();\n  if (fd != NULL)\n    {\n      tree decl = get_symbol_decl (fd);\n\n      /* If a static constructor, push into the current ModuleInfo.\n\t Checks for `shared' first because it derives from the non-shared\n\t constructor type in the front-end.  */\n      if (fd->isSharedStaticCtorDeclaration ())\n\tvec_safe_push (current_moduleinfo->sharedctors, decl);\n      else if (fd->isStaticCtorDeclaration ())\n\tvec_safe_push (current_moduleinfo->ctors, decl);\n\n      /* If a static destructor, do same as with constructors, but also\n\t increment the destructor's vgate at construction time.  */\n      if (fd->isSharedStaticDtorDeclaration ())\n\t{\n\t  VarDeclaration *vgate = ((SharedStaticDtorDeclaration *) fd)->vgate;\n\t  if (vgate != NULL)\n\t    {\n\t      tree gate = get_symbol_decl (vgate);\n\t      vec_safe_push (current_moduleinfo->sharedctorgates, gate);\n\t    }\n\t  vec_safe_insert (current_moduleinfo->shareddtors, 0, decl);\n\t}\n      else if (fd->isStaticDtorDeclaration ())\n\t{\n\t  VarDeclaration *vgate = ((StaticDtorDeclaration *) fd)->vgate;\n\t  if (vgate != NULL)\n\t    {\n\t      tree gate = get_symbol_decl (vgate);\n\t      vec_safe_push (current_moduleinfo->ctorgates, gate);\n\t    }\n\t  vec_safe_insert (current_moduleinfo->dtors, 0, decl);\n\t}\n\n      /* If a unittest function.  */\n      if (fd->isUnitTestDeclaration ())\n\tvec_safe_push (current_moduleinfo->unitTests, decl);\n    }\n}\n\n/* Wrapup all global declarations and start the final compilation.  */\n\nvoid\nd_finish_compilation (tree *vec, int len)\n{\n  /* Complete all generated thunks.  */\n  symtab->process_same_body_aliases ();\n\n  /* Process all file scopes in this compilation, and the external_scope,\n     through wrapup_global_declarations.  */\n  for (int i = 0; i < len; i++)\n    {\n      tree decl = vec[i];\n      wrapup_global_declarations (&decl, 1);\n    }\n\n  /* If the target does not directly support static constructors,\n     static_ctor_list contains a list of all static constructors defined\n     so far.  This routine will create a function to call all of those\n     and is picked up by collect2.  */\n  if (static_ctor_list)\n    {\n      tree decl = build_funcs_gates_fn (get_file_function_name (\"I\"),\n\t\t\t\t\tstatic_ctor_list, NULL);\n      DECL_STATIC_CONSTRUCTOR (decl) = 1;\n      decl_init_priority_insert (decl, DEFAULT_INIT_PRIORITY);\n    }\n\n  if (static_dtor_list)\n    {\n      tree decl = build_funcs_gates_fn (get_file_function_name (\"D\"),\n\t\t\t\t\tstatic_dtor_list, NULL);\n      DECL_STATIC_DESTRUCTOR (decl) = 1;\n      decl_fini_priority_insert (decl, DEFAULT_INIT_PRIORITY);\n    }\n}\n\n\n#include \"gt-d-modules.h\"\n"
  },
  {
    "path": "gcc/d/patches/patch-gcc-9.patch",
    "content": "This implements D language support in the GCC back end, and adds\nrelevant documentation about the GDC front end.\n---\n\n--- a/gcc/config/powerpcspe/powerpcspe.c\n+++ b/gcc/config/powerpcspe/powerpcspe.c\n@@ -31965,11 +31965,12 @@ rs6000_output_function_epilogue (FILE *f\n \t use language_string.\n \t C is 0.  Fortran is 1.  Ada is 3.  C++ is 9.\n \t Java is 13.  Objective-C is 14.  Objective-C++ isn't assigned\n-\t a number, so for now use 9.  LTO, Go and JIT aren't assigned numbers\n-\t either, so for now use 0.  */\n+\t a number, so for now use 9.  LTO, Go, D and JIT aren't assigned\n+\t numbers either, so for now use 0.  */\n       if (lang_GNU_C ()\n \t  || ! strcmp (language_string, \"GNU GIMPLE\")\n \t  || ! strcmp (language_string, \"GNU Go\")\n+\t  || ! strcmp (language_string, \"GNU D\")\n \t  || ! strcmp (language_string, \"libgccjit\"))\n \ti = 0;\n       else if (! strcmp (language_string, \"GNU F77\")\n--- a/gcc/config/rs6000/rs6000.c\n+++ b/gcc/config/rs6000/rs6000.c\n@@ -28630,11 +28630,12 @@ rs6000_output_function_epilogue (FILE *f\n \t use language_string.\n \t C is 0.  Fortran is 1.  Ada is 3.  C++ is 9.\n \t Java is 13.  Objective-C is 14.  Objective-C++ isn't assigned\n-\t a number, so for now use 9.  LTO, Go and JIT aren't assigned numbers\n-\t either, so for now use 0.  */\n+\t a number, so for now use 9.  LTO, Go, D, and JIT aren't assigned\n+\t numbers either, so for now use 0.  */\n       if (lang_GNU_C ()\n \t  || ! strcmp (language_string, \"GNU GIMPLE\")\n \t  || ! strcmp (language_string, \"GNU Go\")\n+\t  || ! strcmp (language_string, \"GNU D\")\n \t  || ! strcmp (language_string, \"libgccjit\"))\n \ti = 0;\n       else if (! strcmp (language_string, \"GNU F77\")\n--- a/gcc/doc/frontends.texi\n+++ b/gcc/doc/frontends.texi\n@@ -9,6 +9,7 @@\n @cindex GNU Compiler Collection\n @cindex GNU C Compiler\n @cindex Ada\n+@cindex D\n @cindex Fortran\n @cindex Go\n @cindex Objective-C\n@@ -16,7 +17,7 @@\n GCC stands for ``GNU Compiler Collection''.  GCC is an integrated\n distribution of compilers for several major programming languages.  These\n languages currently include C, C++, Objective-C, Objective-C++,\n-Fortran, Ada, Go, and BRIG (HSAIL).\n+Fortran, Ada, D, Go, and BRIG (HSAIL).\n \n The abbreviation @dfn{GCC} has multiple meanings in common use.  The\n current official meaning is ``GNU Compiler Collection'', which refers\n--- a/gcc/doc/install.texi\n+++ b/gcc/doc/install.texi\n@@ -921,7 +921,7 @@ only for the listed packages.  For other\n will be built.  Package names currently recognized in the GCC tree are\n @samp{libgcc} (also known as @samp{gcc}), @samp{libstdc++} (not\n @samp{libstdc++-v3}), @samp{libffi}, @samp{zlib}, @samp{boehm-gc},\n-@samp{ada}, @samp{libada}, @samp{libgo}, and @samp{libobjc}.\n+@samp{ada}, @samp{libada}, @samp{libgo}, @samp{libobjc}, and @samp{libphobos}.\n Note @samp{libiberty} does not support shared libraries at all.\n \n Use @option{--disable-shared} to build only static libraries.  Note that\n@@ -1622,12 +1622,12 @@ their runtime libraries should be built.\n grep ^language= */config-lang.in\n @end smallexample\n Currently, you can use any of the following:\n-@code{all}, @code{default}, @code{ada}, @code{c}, @code{c++}, @code{fortran},\n-@code{go}, @code{jit}, @code{lto}, @code{objc}, @code{obj-c++}.\n+@code{all}, @code{default}, @code{ada}, @code{c}, @code{c++}, @code{d},\n+@code{fortran}, @code{go}, @code{jit}, @code{lto}, @code{objc}, @code{obj-c++}.\n Building the Ada compiler has special requirements, see below.\n If you do not pass this flag, or specify the option @code{default}, then the\n default languages available in the @file{gcc} sub-tree will be configured.\n-Ada, Go, Jit, and Objective-C++ are not default languages.  LTO is not a\n+Ada, D, Go, Jit, and Objective-C++ are not default languages.  LTO is not a\n default language, but is built by default because @option{--enable-lto} is\n enabled by default.  The other languages are default languages.  If\n @code{all} is specified, then all available languages are built.  An\n@@ -2771,7 +2771,7 @@ on a simulator as described at @uref{htt\n \n In order to run sets of tests selectively, there are targets\n @samp{make check-gcc} and language specific @samp{make check-c},\n-@samp{make check-c++}, @samp{make check-fortran},\n+@samp{make check-c++}, @samp{make check-d} @samp{make check-fortran},\n @samp{make check-ada}, @samp{make check-objc}, @samp{make check-obj-c++},\n @samp{make check-lto}\n in the @file{gcc} subdirectory of the object directory.  You can also\n--- a/gcc/doc/invoke.texi\n+++ b/gcc/doc/invoke.texi\n@@ -1439,6 +1439,15 @@ Go source code.\n @item @var{file}.brig\n BRIG files (binary representation of HSAIL).\n \n+@item @var{file}.d\n+D source code.\n+\n+@item @var{file}.di\n+D interface file.\n+\n+@item @var{file}.dd\n+D documentation code (Ddoc).\n+\n @item @var{file}.ads\n Ada source code file that contains a library unit declaration (a\n declaration of a package, subprogram, or generic, or a generic\n@@ -1482,6 +1491,7 @@ objective-c  objective-c-header  objecti\n objective-c++ objective-c++-header objective-c++-cpp-output\n assembler  assembler-with-cpp\n ada\n+d\n f77  f77-cpp-input f95  f95-cpp-input\n go\n brig\n--- a/gcc/doc/sourcebuild.texi\n+++ b/gcc/doc/sourcebuild.texi\n@@ -106,6 +106,10 @@ The Objective-C and Objective-C++ runtim\n @item libquadmath\n The runtime support library for quad-precision math operations.\n \n+@item libphobos\n+The D standard and runtime library.  The bulk of this library is mirrored\n+from the @uref{https://github.com/@/dlang, master D repositories}.\n+\n @item libssp\n The Stack protector runtime library.\n \n--- a/gcc/doc/standards.texi\n+++ b/gcc/doc/standards.texi\n@@ -320,6 +320,12 @@ capability is typically utilized to impl\n finalization extension for a gcc supported processor. HSA standards are\n freely available at @uref{http://www.hsafoundation.com/standards/}.\n \n+@section D language\n+\n+GCC supports the D 2.0 programming language.  The D language itself is\n+currently defined by its reference implementation and supporting language\n+specification, described at @uref{https://dlang.org/spec/spec.html}.\n+\n @section References for Other Languages\n \n @xref{Top, GNAT Reference Manual, About This Guide, gnat_rm,\n--- a/gcc/dwarf2out.c\n+++ b/gcc/dwarf2out.c\n@@ -5437,6 +5437,16 @@ is_ada (void)\n   return lang == DW_LANG_Ada95 || lang == DW_LANG_Ada83;\n }\n \n+/* Return TRUE if the language is D.  */\n+\n+static inline bool\n+is_dlang (void)\n+{\n+  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);\n+\n+  return lang == DW_LANG_D;\n+}\n+\n /* Remove the specified attribute if present.  Return TRUE if removal\n    was successful.  */\n \n@@ -24450,6 +24460,8 @@ gen_compile_unit_die (const char *filena\n \tlanguage = DW_LANG_ObjC;\n       else if (strcmp (language_string, \"GNU Objective-C++\") == 0)\n \tlanguage = DW_LANG_ObjC_plus_plus;\n+      else if (strcmp (language_string, \"GNU D\") == 0)\n+\tlanguage = DW_LANG_D;\n       else if (dwarf_version >= 5 || !dwarf_strict)\n \t{\n \t  if (strcmp (language_string, \"GNU Go\") == 0)\n@@ -26034,7 +26046,7 @@ declare_in_namespace (tree thing, dw_die\n \n   if (ns_context != context_die)\n     {\n-      if (is_fortran ())\n+      if (is_fortran () || is_dlang ())\n \treturn ns_context;\n       if (DECL_P (thing))\n \tgen_decl_die (thing, NULL, NULL, ns_context);\n@@ -26057,7 +26069,7 @@ gen_namespace_die (tree decl, dw_die_ref\n     {\n       /* Output a real namespace or module.  */\n       context_die = setup_namespace_context (decl, comp_unit_die ());\n-      namespace_die = new_die (is_fortran ()\n+      namespace_die = new_die (is_fortran () || is_dlang ()\n \t\t\t       ? DW_TAG_module : DW_TAG_namespace,\n \t\t\t       context_die, decl);\n       /* For Fortran modules defined in different CU don't add src coords.  */\n@@ -26123,7 +26135,7 @@ gen_decl_die (tree decl, tree origin, st\n       break;\n \n     case CONST_DECL:\n-      if (!is_fortran () && !is_ada ())\n+      if (!is_fortran () && !is_ada () && !is_dlang ())\n \t{\n \t  /* The individual enumerators of an enum type get output when we output\n \t     the Dwarf representation of the relevant enum type itself.  */\n@@ -26723,7 +26735,7 @@ dwarf2out_decl (tree decl)\n     case CONST_DECL:\n       if (debug_info_level <= DINFO_LEVEL_TERSE)\n \treturn;\n-      if (!is_fortran () && !is_ada ())\n+      if (!is_fortran () && !is_ada () && !is_dlang ())\n \treturn;\n       if (TREE_STATIC (decl) && decl_function_context (decl))\n \tcontext_die = lookup_decl_die (DECL_CONTEXT (decl));\n@@ -29126,6 +29138,7 @@ prune_unused_types_walk_local_classes (d\n     case DW_TAG_structure_type:\n     case DW_TAG_union_type:\n     case DW_TAG_class_type:\n+    case DW_TAG_interface_type:\n       break;\n \n     case DW_TAG_subprogram:\n@@ -29159,6 +29172,7 @@ prune_unused_types_walk (dw_die_ref die)\n     case DW_TAG_structure_type:\n     case DW_TAG_union_type:\n     case DW_TAG_class_type:\n+    case DW_TAG_interface_type:\n       if (die->die_perennial_p)\n \tbreak;\n \n@@ -29185,7 +29199,6 @@ prune_unused_types_walk (dw_die_ref die)\n     case DW_TAG_volatile_type:\n     case DW_TAG_typedef:\n     case DW_TAG_array_type:\n-    case DW_TAG_interface_type:\n     case DW_TAG_friend:\n     case DW_TAG_enumeration_type:\n     case DW_TAG_subroutine_type:\n--- a/gcc/gcc.c\n+++ b/gcc/gcc.c\n@@ -1305,6 +1305,7 @@ static const struct compiler default_com\n   {\".f08\", \"#Fortran\", 0, 0, 0}, {\".F08\", \"#Fortran\", 0, 0, 0},\n   {\".r\", \"#Ratfor\", 0, 0, 0},\n   {\".go\", \"#Go\", 0, 1, 0},\n+  {\".d\", \"#D\", 0, 1, 0}, {\".dd\", \"#D\", 0, 1, 0}, {\".di\", \"#D\", 0, 1, 0},\n   /* Next come the entries for C.  */\n   {\".c\", \"@c\", 0, 0, 1},\n   {\"@c\",\n--- a/gcc/testsuite/gcc.misc-tests/help.exp\n+++ b/gcc/testsuite/gcc.misc-tests/help.exp\n@@ -115,7 +115,7 @@ check_for_options c \"--help=joined,undoc\n # subsystem.  Do this one help class at a time to make it easier to\n # find the source a failure.\n \n-foreach cls { \"ada\" \"c\" \"c++\" \"fortran\" \"go\" \\\n+foreach cls { \"ada\" \"c\" \"c++\" \"d\" \"fortran\" \"go\" \\\n \t\t    \"optimizers\" \"param\" \"target\" \"warnings\" } {\n \n     check_for_options c \"--help=$cls\" \"\" \"^ +-.*\\[^:.\\]$\" \"\"\n"
  },
  {
    "path": "gcc/d/patches/patch-gcc-ddmd-9.patch",
    "content": "This implements building of self hosted D compiler in GCC back end.\n---\n\n--- a/gcc/Makefile.in\n+++ b/gcc/Makefile.in\n@@ -1068,6 +1068,10 @@ SYSLIBS = @GNAT_LIBEXC@\n GNATBIND = @GNATBIND@\n GNATMAKE = @GNATMAKE@\n \n+# Used from d/Make-lang.in\n+GDC = @GDC@\n+GDCFLAGS = @GDCFLAGS@\n+\n # Libs needed (at present) just for jcf-dump.\n LDEXP_LIB = @LDEXP_LIB@\n \n--- a/gcc/configure\n+++ b/gcc/configure\n@@ -807,6 +807,8 @@ EGREP\n GREP\n CXXCPP\n PICFLAG_FOR_TARGET\n+GDCFLAGS\n+GDC\n GNATMAKE\n GNATBIND\n ac_ct_CXX\n@@ -5022,6 +5024,106 @@ else\n fi\n \n \n+\n+if test -n \"$ac_tool_prefix\"; then\n+  # Extract the first word of \"${ac_tool_prefix}gdc\", so it can be a program name with args.\n+set dummy ${ac_tool_prefix}gdc; ac_word=$2\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n+$as_echo_n \"checking for $ac_word... \" >&6; }\n+if test \"${ac_cv_prog_GDC+set}\" = set; then :\n+  $as_echo_n \"(cached) \" >&6\n+else\n+  if test -n \"$GDC\"; then\n+  ac_cv_prog_GDC=\"$GDC\" # Let the user override the test.\n+else\n+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\n+for as_dir in $PATH\n+do\n+  IFS=$as_save_IFS\n+  test -z \"$as_dir\" && as_dir=.\n+    for ac_exec_ext in '' $ac_executable_extensions; do\n+  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n+    ac_cv_prog_GDC=\"${ac_tool_prefix}gdc\"\n+    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n+    break 2\n+  fi\n+done\n+  done\n+IFS=$as_save_IFS\n+\n+fi\n+fi\n+GDC=$ac_cv_prog_GDC\n+if test -n \"$GDC\"; then\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $GDC\" >&5\n+$as_echo \"$GDC\" >&6; }\n+else\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n+$as_echo \"no\" >&6; }\n+fi\n+\n+\n+fi\n+if test -z \"$ac_cv_prog_GDC\"; then\n+  ac_ct_GDC=$GDC\n+  # Extract the first word of \"gdc\", so it can be a program name with args.\n+set dummy gdc; ac_word=$2\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n+$as_echo_n \"checking for $ac_word... \" >&6; }\n+if test \"${ac_cv_prog_ac_ct_GDC+set}\" = set; then :\n+  $as_echo_n \"(cached) \" >&6\n+else\n+  if test -n \"$ac_ct_GDC\"; then\n+  ac_cv_prog_ac_ct_GDC=\"$ac_ct_GDC\" # Let the user override the test.\n+else\n+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\n+for as_dir in $PATH\n+do\n+  IFS=$as_save_IFS\n+  test -z \"$as_dir\" && as_dir=.\n+    for ac_exec_ext in '' $ac_executable_extensions; do\n+  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n+    ac_cv_prog_ac_ct_GDC=\"gdc\"\n+    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n+    break 2\n+  fi\n+done\n+  done\n+IFS=$as_save_IFS\n+\n+fi\n+fi\n+ac_ct_GDC=$ac_cv_prog_ac_ct_GDC\n+if test -n \"$ac_ct_GDC\"; then\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_GDC\" >&5\n+$as_echo \"$ac_ct_GDC\" >&6; }\n+else\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n+$as_echo \"no\" >&6; }\n+fi\n+\n+  if test \"x$ac_ct_GDC\" = x; then\n+    GDC=\"no\"\n+  else\n+    case $cross_compiling:$ac_tool_warned in\n+yes:)\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n+$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\n+ac_tool_warned=yes ;;\n+esac\n+    GDC=$ac_ct_GDC\n+  fi\n+else\n+  GDC=\"$ac_cv_prog_GDC\"\n+fi\n+\n+if test \"x$GDC\" != xno; then\n+  have_gdc=yes\n+else\n+  have_gdc=no\n+fi\n+\n+\n # Do configure tests with the C++ compiler, since that's what we build with.\n ac_ext=cpp\n ac_cpp='$CXXCPP $CPPFLAGS'\n@@ -18510,7 +18612,7 @@ else\n   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2\n   lt_status=$lt_dlunknown\n   cat > conftest.$ac_ext <<_LT_EOF\n-#line 18513 \"configure\"\n+#line 18615 \"configure\"\n #include \"confdefs.h\"\n \n #if HAVE_DLFCN_H\n@@ -18616,7 +18718,7 @@ else\n   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2\n   lt_status=$lt_dlunknown\n   cat > conftest.$ac_ext <<_LT_EOF\n-#line 18619 \"configure\"\n+#line 18721 \"configure\"\n #include \"confdefs.h\"\n \n #if HAVE_DLFCN_H\n--- a/gcc/configure.ac\n+++ b/gcc/configure.ac\n@@ -363,6 +363,7 @@ rm -f a.out a.exe b.out\n AC_PROG_CC\n AC_PROG_CXX\n ACX_PROG_GNAT([-I\"$srcdir\"/ada/libgnat])\n+ACX_PROG_GDC([-I\"$srcdir\"/d])\n \n # Do configure tests with the C++ compiler, since that's what we build with.\n AC_LANG(C++)\n@@ -376,6 +377,7 @@ case \"$CC\" in\n esac\n AC_SUBST(CFLAGS)\n AC_SUBST(CXXFLAGS)\n+AC_SUBST(GDCFLAGS)\n \n # Determine PICFLAG for target gnatlib.\n GCC_PICFLAG_FOR_TARGET\n"
  },
  {
    "path": "gcc/d/patches/patch-targetdm-9.patch",
    "content": "This patch implements the support for the D language specific target hooks.\n\nThe following versions are available for all supported architectures.\n* D_HardFloat\n* D_SoftFloat\n\nThe following CPU versions are implemented:\n* ARM\n** Thumb (deprecated)\n** ARM_Thumb\n** ARM_HardFloat\n** ARM_SoftFloat\n** ARM_SoftFP\n* AArch64\n* Alpha\n** Alpha_SoftFloat\n** Alpha_HardFloat\n* X86\n* X86_64\n** D_X32\n* MIPS32\n* MIPS64\n** MIPS_O32\n** MIPS_O64\n** MIPS_N32\n** MIPS_N64\n** MIPS_EABI\n** MIPS_HardFloat\n** MIPS_SoftFloat\n* PPC\n* PPC64\n** PPC_HardFloat\n** PPC_SoftFloat\n* S390\n* S390X (deprecated)\n* SystemZ\n* SPARC\n* SPARC64\n* SPARC_V8Plus\n** SPARC_HardFloat\n** SPARC_SoftFloat\n\nThe following OS versions are implemented:\n* linux\n* Posix\n* Hurd\n* Android\n* CRuntime_Bionic\n* CRuntime_Glibc\n* CRuntime_Musl\n* CRuntime_UClibc\n---\n \n--- a/gcc/Makefile.in\n+++ b/gcc/Makefile.in\n@@ -554,6 +554,8 @@ tm_include_list=@tm_include_list@\n tm_defines=@tm_defines@\n tm_p_file_list=@tm_p_file_list@\n tm_p_include_list=@tm_p_include_list@\n+tm_d_file_list=@tm_d_file_list@\n+tm_d_include_list=@tm_d_include_list@\n build_xm_file_list=@build_xm_file_list@\n build_xm_include_list=@build_xm_include_list@\n build_xm_defines=@build_xm_defines@\n@@ -848,6 +850,7 @@ BCONFIG_H = bconfig.h $(build_xm_file_li\n CONFIG_H  = config.h  $(host_xm_file_list)\n TCONFIG_H = tconfig.h $(xm_file_list)\n TM_P_H    = tm_p.h    $(tm_p_file_list)\n+TM_D_H    = tm_d.h    $(tm_d_file_list)\n GTM_H     = tm.h      $(tm_file_list) insn-constants.h\n TM_H      = $(GTM_H) insn-flags.h $(OPTIONS_H)\n \n@@ -905,9 +908,11 @@ EXCEPT_H = except.h $(HASHTAB_H)\n TARGET_DEF = target.def target-hooks-macros.h target-insns.def\n C_TARGET_DEF = c-family/c-target.def target-hooks-macros.h\n COMMON_TARGET_DEF = common/common-target.def target-hooks-macros.h\n+D_TARGET_DEF = d/d-target.def target-hooks-macros.h\n TARGET_H = $(TM_H) target.h $(TARGET_DEF) insn-modes.h insn-codes.h\n C_TARGET_H = c-family/c-target.h $(C_TARGET_DEF)\n COMMON_TARGET_H = common/common-target.h $(INPUT_H) $(COMMON_TARGET_DEF)\n+D_TARGET_H = d/d-target.h $(D_TARGET_DEF)\n MACHMODE_H = machmode.h mode-classes.def\n HOOKS_H = hooks.h\n HOSTHOOKS_DEF_H = hosthooks-def.h $(HOOKS_H)\n@@ -1191,6 +1196,9 @@ C_TARGET_OBJS=@c_target_objs@\n # Target specific, C++ specific object file\n CXX_TARGET_OBJS=@cxx_target_objs@\n \n+# Target specific, D specific object file\n+D_TARGET_OBJS=@d_target_objs@\n+\n # Target specific, Fortran specific object file\n FORTRAN_TARGET_OBJS=@fortran_target_objs@\n \n@@ -1790,6 +1798,7 @@ bconfig.h: cs-bconfig.h ; @true\n tconfig.h: cs-tconfig.h ; @true\n tm.h: cs-tm.h ; @true\n tm_p.h: cs-tm_p.h ; @true\n+tm_d.h: cs-tm_d.h ; @true\n \n cs-config.h: Makefile\n \tTARGET_CPU_DEFAULT=\"\" \\\n@@ -1816,6 +1825,11 @@ cs-tm_p.h: Makefile\n \tHEADERS=\"$(tm_p_include_list)\" DEFINES=\"\" \\\n \t$(SHELL) $(srcdir)/mkconfig.sh tm_p.h\n \n+cs-tm_d.h: Makefile\n+\tTARGET_CPU_DEFAULT=\"\" \\\n+\tHEADERS=\"$(tm_d_include_list)\" DEFINES=\"\" \\\n+\t$(SHELL) $(srcdir)/mkconfig.sh tm_d.h\n+\n # Don't automatically run autoconf, since configure.ac might be accidentally\n # newer than configure.  Also, this writes into the source directory which\n # might be on a read-only file system.  If configured for maintainer mode\n@@ -2140,6 +2154,12 @@ default-c.o: config/default-c.c\n CFLAGS-prefix.o += -DPREFIX=\\\"$(prefix)\\\" -DBASEVER=$(BASEVER_s)\n prefix.o: $(BASEVER)\n \n+# Files used by the D language front end.\n+\n+default-d.o: config/default-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n+\n # Language-independent files.\n \n DRIVER_DEFINES = \\\n@@ -2436,6 +2456,15 @@ s-common-target-hooks-def-h: build/genho\n \t\t\t\t\t     common/common-target-hooks-def.h\n \t$(STAMP) s-common-target-hooks-def-h\n \n+d/d-target-hooks-def.h: s-d-target-hooks-def-h; @true\n+\n+s-d-target-hooks-def-h: build/genhooks$(build_exeext)\n+\t$(RUN_GEN) build/genhooks$(build_exeext) \"D Target Hook\" \\\n+\t\t\t\t\t     > tmp-d-target-hooks-def.h\n+\t$(SHELL) $(srcdir)/../move-if-change tmp-d-target-hooks-def.h \\\n+\t\t\t\t\t     d/d-target-hooks-def.h\n+\t$(STAMP) s-d-target-hooks-def-h\n+\n # check if someone mistakenly only changed tm.texi.\n # We use a different pathname here to avoid a circular dependency.\n s-tm-texi: $(srcdir)/doc/../doc/tm.texi\n@@ -2459,6 +2488,7 @@ s-tm-texi: build/genhooks$(build_exeext)\n \t  && ( test $(srcdir)/doc/tm.texi -nt $(srcdir)/target.def \\\n \t    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/c-family/c-target.def \\\n \t    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/common/common-target.def \\\n+\t    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/d/d-target.def \\\n \t  ); then \\\n \t  echo >&2 ; \\\n \t  echo You should edit $(srcdir)/doc/tm.texi.in rather than $(srcdir)/doc/tm.texi . >&2 ; \\\n@@ -2596,14 +2626,15 @@ s-gtype: build/gengtype$(build_exeext) $\n                     -r gtype.state\n \t$(STAMP) s-gtype\n \n-generated_files = config.h tm.h $(TM_P_H) $(TM_H) multilib.h \\\n+generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_H) multilib.h \\\n        $(simple_generated_h) specs.h \\\n        tree-check.h genrtl.h insn-modes.h insn-modes-inline.h \\\n        tm-preds.h tm-constrs.h \\\n        $(ALL_GTFILES_H) gtype-desc.c gtype-desc.h gcov-iov.h \\\n        options.h target-hooks-def.h insn-opinit.h \\\n        common/common-target-hooks-def.h pass-instances.def \\\n-       c-family/c-target-hooks-def.h params.list params.options case-cfn-macros.h \\\n+       c-family/c-target-hooks-def.h d/d-target-hooks-def.h \\\n+       params.list params.options case-cfn-macros.h \\\n        cfn-operators.pd\n \n #\f\n@@ -2747,7 +2778,7 @@ build/genrecog.o : genrecog.c $(RTL_BASE\n   $(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H)\t\t\\\n   $(HASH_TABLE_H) inchash.h\n build/genhooks.o : genhooks.c $(TARGET_DEF) $(C_TARGET_DEF)\t\t\\\n-  $(COMMON_TARGET_DEF) $(BCONFIG_H) $(SYSTEM_H) errors.h\n+  $(COMMON_TARGET_DEF) $(D_TARGET_DEF) $(BCONFIG_H) $(SYSTEM_H) errors.h\n build/genmddump.o : genmddump.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)\t\\\n   $(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H)\n build/genmatch.o : genmatch.c $(BCONFIG_H) $(SYSTEM_H) \\\n--- a/gcc/config.gcc\n+++ b/gcc/config.gcc\n@@ -86,6 +86,9 @@\n #  tm_p_file\t\tLocation of file with declarations for functions\n #\t\t\tin $out_file.\n #\n+#  tm_d_file\t\tA list of headers with definitions of target hook\n+#\t\t\tmacros for the D compiler.\n+#\n #  out_file\t\tThe name of the machine description C support\n #\t\t\tfile, if different from \"$cpu_type/$cpu_type.c\".\n #\n@@ -139,6 +142,9 @@\n #  cxx_target_objs\tList of extra target-dependent objects that be\n #\t\t\tlinked into the C++ compiler only.\n #\n+#  d_target_objs\tList of extra target-dependent objects that be\n+#\t\t\tlinked into the D compiler only.\n+#\n #  fortran_target_objs\tList of extra target-dependent objects that be\n #\t\t\tlinked into the fortran compiler only.\n #\n@@ -191,6 +197,9 @@\n #\n #  target_has_targetm_common\tSet to yes or no depending on whether the\n #\t\t\ttarget has its own definition of targetm_common.\n+#\n+#  target_has_targetdm\tSet to yes or no depending on whether the target\n+#\t\t\thas its own definition of targetdm.\n \n out_file=\n common_out_file=\n@@ -206,9 +215,11 @@ extra_gcc_objs=\n extra_options=\n c_target_objs=\n cxx_target_objs=\n+d_target_objs=\n fortran_target_objs=\n target_has_targetcm=no\n target_has_targetm_common=yes\n+target_has_targetdm=no\n tm_defines=\n xm_defines=\n # Set this to force installation and use of collect2.\n@@ -305,12 +316,14 @@ aarch64*-*-*)\n \textra_headers=\"arm_fp16.h arm_neon.h arm_acle.h\"\n \tc_target_objs=\"aarch64-c.o\"\n \tcxx_target_objs=\"aarch64-c.o\"\n+\td_target_objs=\"aarch64-d.o\"\n \textra_objs=\"aarch64-builtins.o aarch-common.o cortex-a57-fma-steering.o aarch64-speculation.o falkor-tag-collision-avoidance.o\"\n \ttarget_gtfiles=\"\\$(srcdir)/config/aarch64/aarch64-builtins.c\"\n \ttarget_has_targetm_common=yes\n \t;;\n alpha*-*-*)\n \tcpu_type=alpha\n+\td_target_objs=\"alpha-d.o\"\n \textra_options=\"${extra_options} g.opt\"\n \t;;\n am33_2.0-*-linux*)\n@@ -330,6 +343,7 @@ arm*-*-*)\n \ttarget_type_format_char='%'\n \tc_target_objs=\"arm-c.o\"\n \tcxx_target_objs=\"arm-c.o\"\n+\td_target_objs=\"arm-d.o\"\n \textra_options=\"${extra_options} arm/arm-tables.opt\"\n \ttarget_gtfiles=\"\\$(srcdir)/config/arm/arm-builtins.c\"\n \t;;\n@@ -362,6 +376,7 @@ i[34567]86-*-*)\n \tcpu_type=i386\n \tc_target_objs=\"i386-c.o\"\n \tcxx_target_objs=\"i386-c.o\"\n+\td_target_objs=\"i386-d.o\"\n \textra_objs=\"x86-tune-sched.o x86-tune-sched-bd.o x86-tune-sched-atom.o x86-tune-sched-core.o\"\n \textra_options=\"${extra_options} fused-madd.opt\"\n \textra_headers=\"cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h\n@@ -392,6 +407,7 @@ x86_64-*-*)\n \tcpu_type=i386\n \tc_target_objs=\"i386-c.o\"\n \tcxx_target_objs=\"i386-c.o\"\n+\td_target_objs=\"i386-d.o\"\n \textra_options=\"${extra_options} fused-madd.opt\"\n \textra_objs=\"x86-tune-sched.o x86-tune-sched-bd.o x86-tune-sched-atom.o x86-tune-sched-core.o\"\n \textra_headers=\"cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h\n@@ -442,6 +458,7 @@ microblaze*-*-*)\n         ;;\n mips*-*-*)\n \tcpu_type=mips\n+\td_target_objs=\"mips-d.o\"\n \textra_headers=\"loongson.h msa.h\"\n \textra_objs=\"frame-header-opt.o\"\n \textra_options=\"${extra_options} g.opt fused-madd.opt mips/mips-tables.opt\"\n@@ -507,6 +524,7 @@ sparc*-*-*)\n \tcpu_type=sparc\n \tc_target_objs=\"sparc-c.o\"\n \tcxx_target_objs=\"sparc-c.o\"\n+\td_target_objs=\"sparc-d.o\"\n \textra_headers=\"visintrin.h\"\n \t;;\n spu*-*-*)\n@@ -514,6 +532,7 @@ spu*-*-*)\n \t;;\n s390*-*-*)\n \tcpu_type=s390\n+\td_target_objs=\"s390-d.o\"\n \textra_options=\"${extra_options} fused-madd.opt\"\n \textra_headers=\"s390intrin.h htmintrin.h htmxlintrin.h vecintrin.h\"\n \t;;\n@@ -543,10 +562,13 @@ tilepro*-*-*)\n esac\n \n tm_file=${cpu_type}/${cpu_type}.h\n+tm_d_file=${cpu_type}/${cpu_type}.h\n if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-protos.h\n then\n \ttm_p_file=${cpu_type}/${cpu_type}-protos.h\n+\ttm_d_file=\"${tm_d_file} ${cpu_type}/${cpu_type}-protos.h\"\n fi\n+\n extra_modes=\n if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-modes.def\n then\n@@ -810,8 +832,10 @@ case ${target} in\n   esac\n   c_target_objs=\"${c_target_objs} glibc-c.o\"\n   cxx_target_objs=\"${cxx_target_objs} glibc-c.o\"\n+  d_target_objs=\"${d_target_objs} glibc-d.o\"\n   tmake_file=\"${tmake_file} t-glibc\"\n   target_has_targetcm=yes\n+  target_has_targetdm=yes\n   ;;\n *-*-netbsd*)\n   tm_p_file=\"${tm_p_file} netbsd-protos.h\"\n@@ -3232,6 +3256,10 @@ if [ \"$common_out_file\" = \"\" ]; then\n   fi\n fi\n \n+if [ \"$target_has_targetdm\" = \"no\" ]; then\n+  d_target_objs=\"$d_target_objs default-d.o\"\n+fi\n+\n # Support for --with-cpu and related options (and a few unrelated options,\n # too).\n case ${with_cpu} in\n@@ -4858,6 +4886,7 @@ case ${target} in\n \t\tout_file=\"${cpu_type}/${cpu_type}.c\"\n \t\tc_target_objs=\"${c_target_objs} ${cpu_type}-c.o\"\n \t\tcxx_target_objs=\"${cxx_target_objs} ${cpu_type}-c.o\"\n+\t\td_target_objs=\"${d_target_objs} ${cpu_type}-d.o\"\n \t\ttmake_file=\"${cpu_type}/t-${cpu_type} ${tmake_file}\"\n \t\t;;\n \n--- /dev/null\n+++ b/gcc/config/aarch64/aarch64-d.c\n@@ -0,0 +1,39 @@\n+/* Subroutines for the D front end on the AArch64 architecture.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for AArch64 targets.  */\n+\n+void\n+aarch64_d_target_versions (void)\n+{\n+  d_add_builtin_version (\"AArch64\");\n+  d_add_builtin_version (\"D_HardFloat\");\n+}\n+\n+/* Implement TARGET_D_FLOAT_ABI_TYPE for AArch64 targets.  */\n+\n+const char *\n+aarch64_d_float_abi_type (void)\n+{\n+  return \"hard\";\n+}\n--- a/gcc/config/aarch64/aarch64-linux.h\n+++ b/gcc/config/aarch64/aarch64-linux.h\n@@ -81,6 +81,8 @@\n     }\t\t\t\t\t\t\\\n   while (0)\n \n+#define GNU_USER_TARGET_D_CRITSEC_SIZE 48\n+\n #define TARGET_ASM_FILE_END file_end_indicate_exec_stack\n \n /* Uninitialized common symbols in non-PIE executables, even with\n--- a/gcc/config/aarch64/aarch64-protos.h\n+++ b/gcc/config/aarch64/aarch64-protos.h\n@@ -620,6 +620,10 @@ enum aarch64_parse_opt_result aarch64_pa\n std::string aarch64_get_extension_string_for_isa_flags (unsigned long,\n \t\t\t\t\t\t\tunsigned long);\n \n+/* Defined in aarch64-d.c  */\n+extern void aarch64_d_target_versions (void);\n+extern const char *aarch64_d_float_abi_type (void);\n+\n rtl_opt_pass *make_pass_fma_steering (gcc::context *);\n rtl_opt_pass *make_pass_track_speculation (gcc::context *);\n rtl_opt_pass *make_pass_tag_collision_avoidance (gcc::context *);\n--- a/gcc/config/aarch64/aarch64.h\n+++ b/gcc/config/aarch64/aarch64.h\n@@ -30,6 +30,10 @@\n \n #define REGISTER_TARGET_PRAGMAS() aarch64_register_pragmas ()\n \n+/* Target hooks for D language.  */\n+#define TARGET_D_CPU_VERSIONS aarch64_d_target_versions\n+#define TARGET_D_FLOAT_ABI_TYPE aarch64_d_float_abi_type\n+\n /* Target machine storage layout.  */\n \n #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)\t\\\n--- a/gcc/config/aarch64/t-aarch64\n+++ b/gcc/config/aarch64/t-aarch64\n@@ -56,6 +56,10 @@ aarch64-c.o: $(srcdir)/config/aarch64/aa\n \t$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \\\n \t\t$(srcdir)/config/aarch64/aarch64-c.c\n \n+aarch64-d.o: $(srcdir)/config/aarch64/aarch64-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n+\n PASSES_EXTRA += $(srcdir)/config/aarch64/aarch64-passes.def\n \n cortex-a57-fma-steering.o: $(srcdir)/config/aarch64/cortex-a57-fma-steering.c \\\n--- /dev/null\n+++ b/gcc/config/alpha/alpha-d.c\n@@ -0,0 +1,49 @@\n+/* Subroutines for the D front end on the Alpha architecture.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for Alpha targets.  */\n+\n+void\n+alpha_d_target_versions (void)\n+{\n+  d_add_builtin_version (\"Alpha\");\n+  if (TARGET_SOFT_FP)\n+    {\n+      d_add_builtin_version (\"D_SoftFloat\");\n+      d_add_builtin_version (\"Alpha_SoftFloat\");\n+    }\n+  else\n+    {\n+      d_add_builtin_version (\"D_HardFloat\");\n+      d_add_builtin_version (\"Alpha_HardFloat\");\n+    }\n+}\n+\n+/* Implement TARGET_D_FLOAT_ABI_TYPE for Alpha targets.  */\n+\n+const char *\n+alpha_d_float_abi_type (void)\n+{\n+  return (TARGET_SOFT_FP) ? \"soft\" : \"hard\";\n+}\n--- a/gcc/config/alpha/alpha-protos.h\n+++ b/gcc/config/alpha/alpha-protos.h\n@@ -118,3 +118,7 @@ class rtl_opt_pass;\n \n extern rtl_opt_pass *make_pass_handle_trap_shadows (gcc::context *);\n extern rtl_opt_pass *make_pass_align_insns (gcc::context *);\n+\n+/* Routines implemented in alpha-d.c  */\n+extern void alpha_d_target_versions (void);\n+extern const char *alpha_d_float_abi_type (void);\n--- a/gcc/config/alpha/alpha.h\n+++ b/gcc/config/alpha/alpha.h\n@@ -94,6 +94,10 @@ along with GCC; see the file COPYING3.\n   while (0)\n #endif\n \n+/* Target hooks for D language.  */\n+#define TARGET_D_CPU_VERSIONS alpha_d_target_versions\n+#define TARGET_D_FLOAT_ABI_TYPE alpha_d_float_abi_type\n+\n /* Run-time compilation parameters selecting different hardware subsets.  */\n \n /* Which processor to schedule for. The cpu attribute defines a list that\n--- a/gcc/config/alpha/linux.h\n+++ b/gcc/config/alpha/linux.h\n@@ -33,6 +33,19 @@ along with GCC; see the file COPYING3.\n \t  builtin_define (\"_GNU_SOURCE\");\t\t\t\\\n     } while (0)\n \n+#define GNU_USER_TARGET_D_OS_VERSIONS()\t\t\t\t\\\n+    do {\t\t\t\t\t\t\t\\\n+\tbuiltin_version (\"linux\");\t\t\t\t\\\n+\tif (OPTION_GLIBC)\t\t\t\t\t\\\n+\t  builtin_version (\"CRuntime_Glibc\");\t\t\t\\\n+\telse if (OPTION_UCLIBC)\t\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_UClibc\");\t\t\\\n+\telse if (OPTION_BIONIC)\t\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Bionic\");\t\t\\\n+\telse if (OPTION_MUSL)\t\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Musl\");\t\t\\\n+    } while (0)\n+\n #undef LIB_SPEC\n #define LIB_SPEC \\\n   \"%{pthread:-lpthread} \\\n--- a/gcc/config/alpha/t-alpha\n+++ b/gcc/config/alpha/t-alpha\n@@ -16,4 +16,8 @@\n # along with GCC; see the file COPYING3.  If not see\n # <http://www.gnu.org/licenses/>.\n \n+alpha-d.o: $(srcdir)/config/alpha/alpha-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n+\n PASSES_EXTRA += $(srcdir)/config/alpha/alpha-passes.def\n--- /dev/null\n+++ b/gcc/config/arm/arm-d.c\n@@ -0,0 +1,71 @@\n+/* Subroutines for the D front end on the ARM architecture.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm.h\"\n+#include \"tm_p.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for ARM targets.  */\n+\n+void\n+arm_d_target_versions (void)\n+{\n+  d_add_builtin_version (\"ARM\");\n+\n+  if (TARGET_THUMB || TARGET_THUMB2)\n+    {\n+      d_add_builtin_version (\"Thumb\");\n+      d_add_builtin_version (\"ARM_Thumb\");\n+    }\n+\n+  if (arm_float_abi == ARM_FLOAT_ABI_HARD)\n+    d_add_builtin_version (\"ARM_HardFloat\");\n+  else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)\n+    d_add_builtin_version (\"ARM_SoftFloat\");\n+  else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)\n+    d_add_builtin_version (\"ARM_SoftFP\");\n+\n+  if (TARGET_SOFT_FLOAT)\n+    d_add_builtin_version (\"D_SoftFloat\");\n+  else if (TARGET_HARD_FLOAT)\n+    d_add_builtin_version (\"D_HardFloat\");\n+}\n+\n+/* Implement TARGET_D_FLOAT_ABI_TYPE for ARM targets.  */\n+\n+const char *\n+arm_d_float_abi_type (void)\n+{\n+  switch (arm_float_abi)\n+    {\n+    case ARM_FLOAT_ABI_HARD:\n+      return \"hard\";\n+\n+    case ARM_FLOAT_ABI_SOFT:\n+      return \"soft\";\n+\n+    case ARM_FLOAT_ABI_SOFTFP:\n+      return \"softfp\";\n+\n+    default:\n+      return NULL;\n+    }\n+}\n--- a/gcc/config/arm/arm-protos.h\n+++ b/gcc/config/arm/arm-protos.h\n@@ -375,6 +375,10 @@ extern void arm_lang_object_attributes_i\n extern void arm_register_target_pragmas (void);\n extern void arm_cpu_cpp_builtins (struct cpp_reader *);\n \n+/* Defined in arm-d.c  */\n+extern void arm_d_target_versions (void);\n+extern const char *arm_d_float_abi_type (void);\n+\n extern bool arm_is_constant_pool_ref (rtx);\n \n /* The bits in this mask specify which instruction scheduling options should\n--- a/gcc/config/arm/arm.h\n+++ b/gcc/config/arm/arm.h\n@@ -47,6 +47,10 @@ extern char arm_arch_name[];\n /* Target CPU builtins.  */\n #define TARGET_CPU_CPP_BUILTINS() arm_cpu_cpp_builtins (pfile)\n \n+/* Target hooks for D language.  */\n+#define TARGET_D_CPU_VERSIONS arm_d_target_versions\n+#define TARGET_D_FLOAT_ABI_TYPE arm_d_float_abi_type\n+\n #include \"config/arm/arm-opts.h\"\n \n /* The processor for which instructions should be scheduled.  */\n--- a/gcc/config/arm/linux-eabi.h\n+++ b/gcc/config/arm/linux-eabi.h\n@@ -30,6 +30,9 @@\n     }\t\t\t\t\t\t\\\n   while (false)\n \n+#define EXTRA_TARGET_D_OS_VERSIONS()\t\t\\\n+  ANDROID_TARGET_D_OS_VERSIONS();\n+\n /* We default to a soft-float ABI so that binaries can run on all\n    target hardware.  If you override this to use the hard-float ABI then\n    change the setting of GLIBC_DYNAMIC_LINKER_DEFAULT as well.  */\n--- a/gcc/config/arm/t-arm\n+++ b/gcc/config/arm/t-arm\n@@ -152,6 +152,10 @@ arm-c.o: $(srcdir)/config/arm/arm-c.c $(\n \t$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \\\n \t\t$(srcdir)/config/arm/arm-c.c\n \n+arm-d.o: $(srcdir)/config/arm/arm-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n+\n arm-common.o: arm-cpu-cdata.h\n \n driver-arm.o: arm-native.h\n--- /dev/null\n+++ b/gcc/config/default-d.c\n@@ -0,0 +1,25 @@\n+/* Default D language target hooks initializer.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify it under\n+the terms of the GNU General Public License as published by the Free\n+Software Foundation; either version 3, or (at your option) any later\n+version.\n+\n+GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n+for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm_d.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;\n--- /dev/null\n+++ b/gcc/config/glibc-d.c\n@@ -0,0 +1,75 @@\n+/* Glibc support needed only by D front-end.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify it under\n+the terms of the GNU General Public License as published by the Free\n+Software Foundation; either version 3, or (at your option) any later\n+version.\n+\n+GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n+for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm.h\"\n+#include \"memmodel.h\"\n+#include \"tm_p.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_OS_VERSIONS for Glibc targets.  */\n+\n+static void\n+glibc_d_os_builtins (void)\n+{\n+  d_add_builtin_version (\"Posix\");\n+\n+#define builtin_version(TXT) d_add_builtin_version (TXT)\n+\n+#ifdef GNU_USER_TARGET_D_OS_VERSIONS\n+  GNU_USER_TARGET_D_OS_VERSIONS ();\n+#endif\n+\n+#ifdef EXTRA_TARGET_D_OS_VERSIONS\n+  EXTRA_TARGET_D_OS_VERSIONS ();\n+#endif\n+}\n+\n+/* Implement TARGET_D_CRITSEC_SIZE for Glibc targets.  */\n+\n+static unsigned\n+glibc_d_critsec_size (void)\n+{\n+  /* This is the sizeof pthread_mutex_t.  */\n+#ifdef GNU_USER_TARGET_D_CRITSEC_SIZE\n+  return GNU_USER_TARGET_D_CRITSEC_SIZE;\n+#else\n+  return (POINTER_SIZE == 64) ? 40 : 24;\n+#endif\n+}\n+\n+/* Implement TARGET_D_OBJECT_FORMAT for Glibc targets.  */\n+\n+const char *\n+glibc_d_object_format (void)\n+{\n+  return \"elf\";\n+}\n+\n+#undef TARGET_D_OS_VERSIONS\n+#define TARGET_D_OS_VERSIONS glibc_d_os_builtins\n+\n+#undef TARGET_D_CRITSEC_SIZE\n+#define TARGET_D_CRITSEC_SIZE glibc_d_critsec_size\n+\n+#undef TARGET_D_OBJECT_FORMAT\n+#define TARGET_D_OBJECT_FORMAT glibc_d_object_format\n+\n+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;\n--- a/gcc/config/gnu.h\n+++ b/gcc/config/gnu.h\n@@ -31,3 +31,9 @@ along with GCC.  If not, see <http://www\n \tbuiltin_assert (\"system=unix\");\t\t\\\n \tbuiltin_assert (\"system=posix\");\t\\\n     } while (0)\n+\n+#define GNU_USER_TARGET_D_OS_VERSIONS()\t\t\\\n+    do {\t\t\t\t\t\\\n+\tbuiltin_version (\"Hurd\");\t\t\\\n+\tbuiltin_version (\"CRuntime_Glibc\");\t\\\n+    } while (0)\n--- /dev/null\n+++ b/gcc/config/i386/i386-d.c\n@@ -0,0 +1,55 @@\n+/* Subroutines for the D front end on the x86 architecture.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for x86 targets.  */\n+\n+void\n+ix86_d_target_versions (void)\n+{\n+  if (TARGET_64BIT)\n+    {\n+      d_add_builtin_version (\"X86_64\");\n+\n+      if (TARGET_X32)\n+\td_add_builtin_version (\"D_X32\");\n+    }\n+  else\n+    d_add_builtin_version (\"X86\");\n+\n+  if (TARGET_80387)\n+    d_add_builtin_version (\"D_HardFloat\");\n+  else\n+    d_add_builtin_version (\"D_SoftFloat\");\n+}\n+\n+/* Implement TARGET_D_FLOAT_ABI_TYPE for x86 targets.  */\n+\n+const char *\n+ix86_d_float_abi_type (void)\n+{\n+  if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))\n+    return \"soft\";\n+\n+  return \"hard\";\n+}\n--- a/gcc/config/i386/i386-protos.h\n+++ b/gcc/config/i386/i386-protos.h\n@@ -236,6 +236,10 @@ extern void ix86_expand_sse2_abs (rtx, r\n extern void ix86_target_macros (void);\n extern void ix86_register_pragmas (void);\n \n+/* In i386-d.c  */\n+extern void ix86_d_target_versions (void);\n+extern const char *ix86_d_float_abi_type (void);\n+\n /* In winnt.c  */\n extern void i386_pe_unique_section (tree, int);\n extern void i386_pe_declare_function_type (FILE *, const char *, int);\n--- a/gcc/config/i386/i386.h\n+++ b/gcc/config/i386/i386.h\n@@ -718,6 +718,10 @@ extern const char *host_detect_local_cpu\n /* Target Pragmas.  */\n #define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()\n \n+/* Target hooks for D language.  */\n+#define TARGET_D_CPU_VERSIONS ix86_d_target_versions\n+#define TARGET_D_FLOAT_ABI_TYPE ix86_d_float_abi_type\n+\n #ifndef CC1_SPEC\n #define CC1_SPEC \"%(cc1_cpu) \"\n #endif\n--- a/gcc/config/i386/linux-common.h\n+++ b/gcc/config/i386/linux-common.h\n@@ -27,6 +27,12 @@ along with GCC; see the file COPYING3.\n     }                                          \\\n   while (0)\n \n+#define EXTRA_TARGET_D_OS_VERSIONS()\t\t\\\n+  ANDROID_TARGET_D_OS_VERSIONS();\n+\n+#define GNU_USER_TARGET_D_CRITSEC_SIZE\t\t\\\n+  (TARGET_64BIT ? (POINTER_SIZE == 64 ? 40 : 32) : 24)\n+\n #undef CC1_SPEC\n #define CC1_SPEC \\\n   LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \\\n--- a/gcc/config/i386/t-i386\n+++ b/gcc/config/i386/t-i386\n@@ -40,6 +40,10 @@ x86-tune-sched-core.o: $(srcdir)/config/\n \t  $(COMPILE) $<\n \t  $(POSTCOMPILE)\n \n+i386-d.o: $(srcdir)/config/i386/i386-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n+\n i386.o: i386-builtin-types.inc\n \n i386-builtin-types.inc: s-i386-bt ; @true\n--- a/gcc/config/kfreebsd-gnu.h\n+++ b/gcc/config/kfreebsd-gnu.h\n@@ -29,6 +29,12 @@ along with GCC; see the file COPYING3.\n     }\t\t\t\t\t\t\\\n   while (0)\n \n+#define GNU_USER_TARGET_D_OS_VERSIONS()\t\t\\\n+    do {\t\t\t\t\t\\\n+\tbuiltin_version (\"FreeBSD\");\t\t\\\n+\tbuiltin_version (\"CRuntime_Glibc\");\t\\\n+    } while (0)\n+\n #define GNU_USER_DYNAMIC_LINKER        GLIBC_DYNAMIC_LINKER\n #define GNU_USER_DYNAMIC_LINKER32      GLIBC_DYNAMIC_LINKER32\n #define GNU_USER_DYNAMIC_LINKER64      GLIBC_DYNAMIC_LINKER64\n--- a/gcc/config/kopensolaris-gnu.h\n+++ b/gcc/config/kopensolaris-gnu.h\n@@ -30,5 +30,11 @@ along with GCC; see the file COPYING3.\n     }\t\t\t\t\t\t\\\n   while (0)\n \n+#define GNU_USER_TARGET_D_OS_VERSIONS()\t\t\\\n+    do {\t\t\t\t\t\\\n+\tbuiltin_version (\"Solaris\");\t\t\\\n+\tbuiltin_version (\"CRuntime_Glibc\");\t\\\n+    } while (0)\n+\n #undef GNU_USER_DYNAMIC_LINKER\n #define GNU_USER_DYNAMIC_LINKER \"/lib/ld.so.1\"\n--- a/gcc/config/linux-android.h\n+++ b/gcc/config/linux-android.h\n@@ -25,6 +25,12 @@\n \t  builtin_define (\"__ANDROID__\");\t\t\t\\\n     } while (0)\n \n+#define ANDROID_TARGET_D_OS_VERSIONS()\t\t\t\t\\\n+    do {\t\t\t\t\t\t\t\\\n+\tif (TARGET_ANDROID)\t\t\t\t\t\\\n+\t  builtin_version (\"Android\");\t\t\t\t\\\n+    } while (0)\n+\n #if ANDROID_DEFAULT\n # define NOANDROID \"mno-android\"\n #else\n--- a/gcc/config/linux.h\n+++ b/gcc/config/linux.h\n@@ -53,6 +53,19 @@ see the files COPYING3 and COPYING.RUNTI\n \tbuiltin_assert (\"system=posix\");\t\t\t\\\n     } while (0)\n \n+#define GNU_USER_TARGET_D_OS_VERSIONS()\t\t\t\t\\\n+    do {\t\t\t\t\t\t\t\\\n+\tbuiltin_version (\"linux\");\t\t\t\t\\\n+\tif (OPTION_GLIBC)\t\t\t\t\t\\\n+\t  builtin_version (\"CRuntime_Glibc\");\t\t\t\\\n+\telse if (OPTION_UCLIBC)\t\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_UClibc\");\t\t\\\n+\telse if (OPTION_BIONIC)\t\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Bionic\");\t\t\\\n+\telse if (OPTION_MUSL)\t\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Musl\");\t\t\\\n+    } while (0)\n+\n /* Determine which dynamic linker to use depending on whether GLIBC or\n    uClibc or Bionic or musl is the default C library and whether\n    -muclibc or -mglibc or -mbionic or -mmusl has been passed to change\n--- a/gcc/config/mips/linux-common.h\n+++ b/gcc/config/mips/linux-common.h\n@@ -27,6 +27,9 @@ along with GCC; see the file COPYING3.\n     ANDROID_TARGET_OS_CPP_BUILTINS();\t\t\t\t\\\n   } while (0)\n \n+#define EXTRA_TARGET_D_OS_VERSIONS()\t\t\t\t\\\n+  ANDROID_TARGET_D_OS_VERSIONS();\n+\n #undef  LINK_SPEC\n #define LINK_SPEC\t\t\t\t\t\t\t\\\n   LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LINK_SPEC,\t\t\t\\\n--- /dev/null\n+++ b/gcc/config/mips/mips-d.c\n@@ -0,0 +1,69 @@\n+/* Subroutines for the D front end on the MIPS architecture.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for MIPS targets.  */\n+\n+void\n+mips_d_target_versions (void)\n+{\n+  if (TARGET_64BIT)\n+    d_add_builtin_version (\"MIPS64\");\n+  else\n+    d_add_builtin_version (\"MIPS32\");\n+\n+  if (mips_abi == ABI_32)\n+    d_add_builtin_version (\"MIPS_O32\");\n+  else if (mips_abi == ABI_EABI)\n+    d_add_builtin_version (\"MIPS_EABI\");\n+  else if (mips_abi == ABI_N32)\n+    d_add_builtin_version (\"MIPS_N32\");\n+  else if (mips_abi == ABI_64)\n+    d_add_builtin_version (\"MIPS_N64\");\n+  else if (mips_abi == ABI_O64)\n+    d_add_builtin_version (\"MIPS_O64\");\n+\n+  if (TARGET_HARD_FLOAT_ABI)\n+    {\n+      d_add_builtin_version (\"MIPS_HardFloat\");\n+      d_add_builtin_version (\"D_HardFloat\");\n+    }\n+  else if (TARGET_SOFT_FLOAT_ABI)\n+    {\n+      d_add_builtin_version (\"MIPS_SoftFloat\");\n+      d_add_builtin_version (\"D_SoftFloat\");\n+    }\n+}\n+\n+/* Implement TARGET_D_FLOAT_ABI_TYPE for MIPS targets.  */\n+\n+const char *\n+mips_d_float_abi_type (void)\n+{\n+  if (TARGET_HARD_FLOAT_ABI)\n+    return \"hard\";\n+  else if (TARGET_SOFT_FLOAT_ABI)\n+    return \"soft\";\n+\n+  return NULL;\n+}\n--- a/gcc/config/mips/mips-protos.h\n+++ b/gcc/config/mips/mips-protos.h\n@@ -385,4 +385,8 @@ extern mulsidi3_gen_fn mips_mulsidi3_gen\n extern void mips_register_frame_header_opt (void);\n extern void mips_expand_vec_cond_expr (machine_mode, machine_mode, rtx *);\n \n+/* Routines implemented in mips-d.c  */\n+extern void mips_d_target_versions (void);\n+extern const char *mips_d_float_abi_type (void);\n+\n #endif /* ! GCC_MIPS_PROTOS_H */\n--- a/gcc/config/mips/mips.h\n+++ b/gcc/config/mips/mips.h\n@@ -645,6 +645,10 @@ struct mips_cpu_info {\n     }\t\t\t\t\t\t\t\t\t\\\n   while (0)\n \n+/* Target hooks for D language.  */\n+#define TARGET_D_CPU_VERSIONS mips_d_target_versions\n+#define TARGET_D_FLOAT_ABI_TYPE mips_d_float_abi_type\n+\n /* Default target_flags if no switches are specified  */\n \n #ifndef TARGET_DEFAULT\n--- a/gcc/config/mips/t-mips\n+++ b/gcc/config/mips/t-mips\n@@ -24,3 +24,7 @@ $(srcdir)/config/mips/mips-tables.opt: $\n frame-header-opt.o: $(srcdir)/config/mips/frame-header-opt.c\n \t$(COMPILE) $<\n \t$(POSTCOMPILE)\n+\n+mips-d.o: $(srcdir)/config/mips/mips-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n--- a/gcc/config/powerpcspe/linux.h\n+++ b/gcc/config/powerpcspe/linux.h\n@@ -57,6 +57,19 @@\n     }\t\t\t\t\t\t\\\n   while (0)\n \n+#define GNU_USER_TARGET_D_OS_VERSIONS()\t\t\t\\\n+    do {\t\t\t\t\t\t\\\n+\tbuiltin_version (\"linux\");\t\t\t\\\n+\tif (OPTION_GLIBC)\t\t\t\t\\\n+\t  builtin_version (\"CRuntime_Glibc\");\t\t\\\n+\telse if (OPTION_UCLIBC)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_UClibc\");\t\\\n+\telse if (OPTION_BIONIC)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Bionic\");\t\\\n+\telse if (OPTION_MUSL)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Musl\");\t\\\n+    } while (0)\n+\n #undef\tCPP_OS_DEFAULT_SPEC\n #define CPP_OS_DEFAULT_SPEC \"%(cpp_os_linux)\"\n \n--- a/gcc/config/powerpcspe/linux64.h\n+++ b/gcc/config/powerpcspe/linux64.h\n@@ -391,6 +391,19 @@ extern int dot_symbols;\n     }\t\t\t\t\t\t\t\\\n   while (0)\n \n+#define GNU_USER_TARGET_D_OS_VERSIONS()\t\t\t\\\n+    do {\t\t\t\t\t\t\\\n+\tbuiltin_version (\"linux\");\t\t\t\\\n+\tif (OPTION_GLIBC)\t\t\t\t\\\n+\t  builtin_version (\"CRuntime_Glibc\");\t\t\\\n+\telse if (OPTION_UCLIBC)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_UClibc\");\t\\\n+\telse if (OPTION_BIONIC)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Bionic\");\t\\\n+\telse if (OPTION_MUSL)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Musl\");\t\\\n+    } while (0)\n+\n #undef  CPP_OS_DEFAULT_SPEC\n #define CPP_OS_DEFAULT_SPEC \"%(cpp_os_linux) %(include_extra)\"\n \n--- /dev/null\n+++ b/gcc/config/powerpcspe/powerpcspe-d.c\n@@ -0,0 +1,58 @@\n+/* Subroutines for the D front end on the PowerPC architecture.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for PowerPC targets.  */\n+\n+void\n+rs6000_d_target_versions (void)\n+{\n+  if (TARGET_64BIT)\n+    d_add_builtin_version (\"PPC64\");\n+  else\n+    d_add_builtin_version (\"PPC\");\n+\n+  if (TARGET_HARD_FLOAT)\n+    {\n+      d_add_builtin_version (\"PPC_HardFloat\");\n+      d_add_builtin_version (\"D_HardFloat\");\n+    }\n+  else if (TARGET_SOFT_FLOAT)\n+    {\n+      d_add_builtin_version (\"PPC_SoftFloat\");\n+      d_add_builtin_version (\"D_SoftFloat\");\n+    }\n+}\n+\n+/* Implement TARGET_D_FLOAT_ABI_TYPE for PowerPC targets.  */\n+\n+const char *\n+rs6000_d_float_abi_type (void)\n+{\n+  if (TARGET_HARD_FLOAT)\n+    return \"hard\";\n+  else if (TARGET_SOFT_FLOAT)\n+    return \"soft\";\n+\n+  return NULL;\n+}\n--- a/gcc/config/powerpcspe/powerpcspe-protos.h\n+++ b/gcc/config/powerpcspe/powerpcspe-protos.h\n@@ -231,6 +231,10 @@ extern void rs6000_target_modify_macros\n extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT,\n \t\t\t\t\t\tHOST_WIDE_INT);\n \n+/* Declare functions in powerpcspe-d.c  */\n+extern void rs6000_d_target_versions (void);\n+extern const char *rs6000_d_float_abi_type (void);\n+\n #if TARGET_MACHO\n char *output_call (rtx_insn *, rtx *, int, int);\n #endif\n--- a/gcc/config/powerpcspe/powerpcspe.h\n+++ b/gcc/config/powerpcspe/powerpcspe.h\n@@ -702,6 +702,10 @@ extern unsigned char rs6000_recip_bits[]\n #define TARGET_CPU_CPP_BUILTINS() \\\n   rs6000_cpu_cpp_builtins (pfile)\n \n+/* Target hooks for D language.  */\n+#define TARGET_D_CPU_VERSIONS rs6000_d_target_versions\n+#define TARGET_D_FLOAT_ABI_TYPE rs6000_d_float_abi_type\n+\n /* This is used by rs6000_cpu_cpp_builtins to indicate the byte order\n    we're compiling for.  Some configurations may need to override it.  */\n #define RS6000_CPU_CPP_ENDIAN_BUILTINS()\t\\\n--- a/gcc/config/powerpcspe/t-powerpcspe\n+++ b/gcc/config/powerpcspe/t-powerpcspe\n@@ -26,6 +26,10 @@ powerpcspe-c.o: $(srcdir)/config/powerpc\n \t$(COMPILE) $<\n \t$(POSTCOMPILE)\n \n+powerpcspe-d.o: $(srcdir)/config/powerpcspe/powerpcspe-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n+\n $(srcdir)/config/powerpcspe/powerpcspe-tables.opt: $(srcdir)/config/powerpcspe/genopt.sh \\\n   $(srcdir)/config/powerpcspe/powerpcspe-cpus.def\n \t$(SHELL) $(srcdir)/config/powerpcspe/genopt.sh $(srcdir)/config/powerpcspe > \\\n--- a/gcc/config/rs6000/linux.h\n+++ b/gcc/config/rs6000/linux.h\n@@ -57,6 +57,19 @@\n     }\t\t\t\t\t\t\\\n   while (0)\n \n+#define GNU_USER_TARGET_D_OS_VERSIONS()\t\t\t\\\n+    do {\t\t\t\t\t\t\\\n+\tbuiltin_version (\"linux\");\t\t\t\\\n+\tif (OPTION_GLIBC)\t\t\t\t\\\n+\t  builtin_version (\"CRuntime_Glibc\");\t\t\\\n+\telse if (OPTION_UCLIBC)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_UClibc\");\t\\\n+\telse if (OPTION_BIONIC)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Bionic\");\t\\\n+\telse if (OPTION_MUSL)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Musl\");\t\\\n+    } while (0)\n+\n #undef\tCPP_OS_DEFAULT_SPEC\n #define CPP_OS_DEFAULT_SPEC \"%(cpp_os_linux)\"\n \n--- a/gcc/config/rs6000/linux64.h\n+++ b/gcc/config/rs6000/linux64.h\n@@ -391,6 +391,19 @@ extern int dot_symbols;\n     }\t\t\t\t\t\t\t\\\n   while (0)\n \n+#define GNU_USER_TARGET_D_OS_VERSIONS()\t\t\t\\\n+    do {\t\t\t\t\t\t\\\n+\tbuiltin_version (\"linux\");\t\t\t\\\n+\tif (OPTION_GLIBC)\t\t\t\t\\\n+\t  builtin_version (\"CRuntime_Glibc\");\t\t\\\n+\telse if (OPTION_UCLIBC)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_UClibc\");\t\\\n+\telse if (OPTION_BIONIC)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Bionic\");\t\\\n+\telse if (OPTION_MUSL)\t\t\t\t\\\n+\t  d_add_builtin_version (\"CRuntime_Musl\");\t\\\n+    } while (0)\n+\n #undef  CPP_OS_DEFAULT_SPEC\n #define CPP_OS_DEFAULT_SPEC \"%(cpp_os_linux) %(include_extra)\"\n \n--- /dev/null\n+++ b/gcc/config/rs6000/rs6000-d.c\n@@ -0,0 +1,58 @@\n+/* Subroutines for the D front end on the PowerPC architecture.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for PowerPC targets.  */\n+\n+void\n+rs6000_d_target_versions (void)\n+{\n+  if (TARGET_64BIT)\n+    d_add_builtin_version (\"PPC64\");\n+  else\n+    d_add_builtin_version (\"PPC\");\n+\n+  if (TARGET_HARD_FLOAT)\n+    {\n+      d_add_builtin_version (\"PPC_HardFloat\");\n+      d_add_builtin_version (\"D_HardFloat\");\n+    }\n+  else if (TARGET_SOFT_FLOAT)\n+    {\n+      d_add_builtin_version (\"PPC_SoftFloat\");\n+      d_add_builtin_version (\"D_SoftFloat\");\n+    }\n+}\n+\n+/* Implement TARGET_D_FLOAT_ABI_TYPE for PowerPC targets.  */\n+\n+const char *\n+rs6000_d_float_abi_type (void)\n+{\n+  if (TARGET_HARD_FLOAT)\n+    return \"hard\";\n+  else if (TARGET_SOFT_FLOAT)\n+    return \"soft\";\n+\n+  return NULL;\n+}\n--- a/gcc/config/rs6000/rs6000-protos.h\n+++ b/gcc/config/rs6000/rs6000-protos.h\n@@ -224,6 +224,10 @@ extern void rs6000_target_modify_macros\n extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT,\n \t\t\t\t\t\tHOST_WIDE_INT);\n \n+/* Declare functions in rs6000-d.c  */\n+extern void rs6000_d_target_versions (void);\n+extern const char *rs6000_d_float_abi_type (void);\n+\n #if TARGET_MACHO\n char *output_call (rtx_insn *, rtx *, int, int);\n #endif\n--- a/gcc/config/rs6000/rs6000.h\n+++ b/gcc/config/rs6000/rs6000.h\n@@ -613,6 +613,10 @@ extern unsigned char rs6000_recip_bits[]\n #define TARGET_CPU_CPP_BUILTINS() \\\n   rs6000_cpu_cpp_builtins (pfile)\n \n+/* Target hooks for D language.  */\n+#define TARGET_D_CPU_VERSIONS rs6000_d_target_versions\n+#define TARGET_D_FLOAT_ABI_TYPE rs6000_d_float_abi_type\n+\n /* This is used by rs6000_cpu_cpp_builtins to indicate the byte order\n    we're compiling for.  Some configurations may need to override it.  */\n #define RS6000_CPU_CPP_ENDIAN_BUILTINS()\t\\\n--- a/gcc/config/rs6000/t-rs6000\n+++ b/gcc/config/rs6000/t-rs6000\n@@ -35,6 +35,10 @@ rs6000-p8swap.o: $(srcdir)/config/rs6000\n \t$(COMPILE) $<\n \t$(POSTCOMPILE)\n \n+rs6000-d.o: $(srcdir)/config/rs6000/rs6000-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n+\n $(srcdir)/config/rs6000/rs6000-tables.opt: $(srcdir)/config/rs6000/genopt.sh \\\n   $(srcdir)/config/rs6000/rs6000-cpus.def\n \t$(SHELL) $(srcdir)/config/rs6000/genopt.sh $(srcdir)/config/rs6000 > \\\n--- /dev/null\n+++ b/gcc/config/s390/s390-d.c\n@@ -0,0 +1,54 @@\n+/* Subroutines for the D front end on the IBM S/390 and zSeries architectures.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for S/390 and zSeries targets.  */\n+\n+void\n+s390_d_target_versions (void)\n+{\n+  if (TARGET_ZARCH)\n+    d_add_builtin_version (\"SystemZ\");\n+  else if (TARGET_64BIT)\n+    d_add_builtin_version (\"S390X\");\n+  else\n+    d_add_builtin_version (\"S390\");\n+\n+  if (TARGET_SOFT_FLOAT)\n+    d_add_builtin_version (\"D_SoftFloat\");\n+  else if (TARGET_HARD_FLOAT)\n+    d_add_builtin_version (\"D_HardFloat\");\n+}\n+\n+/* Implement TARGET_D_FLOAT_ABI_TYPE for S/390 and zSeries targets.  */\n+\n+const char *\n+s390_d_float_abi_type (void)\n+{\n+  if (TARGET_HARD_FLOAT)\n+    return \"hard\";\n+  else if (TARGET_SOFT_FLOAT)\n+    return \"soft\";\n+\n+  return NULL;\n+}\n--- a/gcc/config/s390/s390-protos.h\n+++ b/gcc/config/s390/s390-protos.h\n@@ -166,6 +166,10 @@ extern void s390_register_target_pragmas\n /* Routines for s390-c.c */\n extern bool s390_const_operand_ok (tree, int, int, tree);\n \n+/* Routines for s390-d.c  */\n+extern void s390_d_target_versions (void);\n+extern const char *s390_d_float_abi_type (void);\n+\n /* Pass management.  */\n namespace gcc { class context; }\n class rtl_opt_pass;\n--- a/gcc/config/s390/s390.h\n+++ b/gcc/config/s390/s390.h\n@@ -200,6 +200,10 @@ enum processor_flags\n /* Target CPU builtins.  */\n #define TARGET_CPU_CPP_BUILTINS() s390_cpu_cpp_builtins (pfile)\n \n+/* Target hooks for D language.  */\n+#define TARGET_D_CPU_VERSIONS s390_d_target_versions\n+#define TARGET_D_FLOAT_ABI_TYPE s390_d_float_abi_type\n+\n #ifdef DEFAULT_TARGET_64BIT\n #define TARGET_DEFAULT     (MASK_64BIT | MASK_ZARCH | MASK_HARD_DFP\t\\\n \t\t\t    | MASK_OPT_HTM | MASK_OPT_VX)\n--- a/gcc/config/s390/t-s390\n+++ b/gcc/config/s390/t-s390\n@@ -26,3 +26,7 @@ s390-c.o: $(srcdir)/config/s390/s390-c.c\n   $(TARGET_H) $(TARGET_DEF_H) $(CPPLIB_H) $(C_PRAGMA_H)\n \t$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \\\n \t\t$(srcdir)/config/s390/s390-c.c\n+\n+s390-d.o: $(srcdir)/config/s390/s390-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n--- /dev/null\n+++ b/gcc/config/sparc/sparc-d.c\n@@ -0,0 +1,56 @@\n+/* Subroutines for the D front end on the SPARC architecture.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for SPARC targets.  */\n+\n+void\n+sparc_d_target_versions (void)\n+{\n+  if (TARGET_64BIT)\n+    d_add_builtin_version (\"SPARC64\");\n+  else\n+    d_add_builtin_version (\"SPARC\");\n+\n+  if (TARGET_V8PLUS)\n+    d_add_builtin_version (\"SPARC_V8Plus\");\n+\n+  if (TARGET_FPU)\n+    {\n+      d_add_builtin_version (\"D_HardFloat\");\n+      d_add_builtin_version (\"SPARC_HardFloat\");\n+    }\n+  else\n+    {\n+      d_add_builtin_version (\"D_SoftFloat\");\n+      d_add_builtin_version (\"SPARC_SoftFloat\");\n+    }\n+}\n+\n+/* Implement TARGET_D_FLOAT_ABI_TYPE for SPARC targets.  */\n+\n+const char *\n+sparc_d_float_abi_type (void)\n+{\n+  return (TARGET_FPU) ? \"hard\" : \"soft\";\n+}\n--- a/gcc/config/sparc/sparc-protos.h\n+++ b/gcc/config/sparc/sparc-protos.h\n@@ -111,4 +111,8 @@ unsigned int sparc_regmode_natural_size\n \n extern rtl_opt_pass *make_pass_work_around_errata (gcc::context *);\n \n+/* Routines implemented in sparc-d.c  */\n+extern void sparc_d_target_versions (void);\n+extern const char *sparc_d_float_abi_type (void);\n+\n #endif /* __SPARC_PROTOS_H__ */\n--- a/gcc/config/sparc/sparc.h\n+++ b/gcc/config/sparc/sparc.h\n@@ -27,6 +27,10 @@ along with GCC; see the file COPYING3.\n \n #define TARGET_CPU_CPP_BUILTINS() sparc_target_macros ()\n \n+/* Target hooks for D language.  */\n+#define TARGET_D_CPU_VERSIONS sparc_d_target_versions\n+#define TARGET_D_FLOAT_ABI_TYPE sparc_d_float_abi_type\n+\n /* Specify this in a cover file to provide bi-architecture (32/64) support.  */\n /* #define SPARC_BI_ARCH */\n \n--- a/gcc/config/sparc/t-sparc\n+++ b/gcc/config/sparc/t-sparc\n@@ -23,3 +23,7 @@ PASSES_EXTRA += $(srcdir)/config/sparc/s\n sparc-c.o: $(srcdir)/config/sparc/sparc-c.c\n \t$(COMPILE) $<\n \t$(POSTCOMPILE)\n+\n+sparc-d.o: $(srcdir)/config/sparc/sparc-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n--- a/gcc/config/t-glibc\n+++ b/gcc/config/t-glibc\n@@ -19,3 +19,7 @@\n glibc-c.o: config/glibc-c.c\n \t$(COMPILE) $<\n \t$(POSTCOMPILE)\n+\n+glibc-d.o: config/glibc-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n--- a/gcc/configure\n+++ b/gcc/configure\n@@ -612,6 +612,7 @@ ISLLIBS\n GMPINC\n GMPLIBS\n target_cpu_default\n+d_target_objs\n fortran_target_objs\n cxx_target_objs\n c_target_objs\n@@ -619,6 +620,8 @@ use_gcc_stdint\n xm_defines\n xm_include_list\n xm_file_list\n+tm_d_include_list\n+tm_d_file_list\n tm_p_include_list\n tm_p_file_list\n tm_defines\n@@ -5142,6 +5145,7 @@ esac\n \n \n \n+\n # Determine PICFLAG for target gnatlib.\n \n \n@@ -11960,6 +11964,7 @@ fi\n \n tm_file=\"${tm_file} defaults.h\"\n tm_p_file=\"${tm_p_file} tm-preds.h\"\n+tm_d_file=\"${tm_d_file} defaults.h\"\n host_xm_file=\"auto-host.h ansidecl.h ${host_xm_file}\"\n build_xm_file=\"${build_auto} ansidecl.h ${build_xm_file}\"\n # We don't want ansidecl.h in target files, write code there in ISO/GNU C.\n@@ -12343,6 +12348,21 @@ for f in $tm_p_file; do\n   esac\n done\n \n+tm_d_file_list=\n+tm_d_include_list=\"options.h insn-constants.h\"\n+for f in $tm_d_file; do\n+  case $f in\n+    defaults.h )\n+       tm_d_file_list=\"${tm_d_file_list} \\$(srcdir)/$f\"\n+       tm_d_include_list=\"${tm_d_include_list} $f\"\n+       ;;\n+    * )\n+       tm_d_file_list=\"${tm_d_file_list} \\$(srcdir)/config/$f\"\n+       tm_d_include_list=\"${tm_d_include_list} config/$f\"\n+       ;;\n+  esac\n+done\n+\n xm_file_list=\n xm_include_list=\n for f in $xm_file; do\n@@ -18612,7 +18632,7 @@ else\n   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2\n   lt_status=$lt_dlunknown\n   cat > conftest.$ac_ext <<_LT_EOF\n-#line 18615 \"configure\"\n+#line 18634 \"configure\"\n #include \"confdefs.h\"\n \n #if HAVE_DLFCN_H\n@@ -18718,7 +18738,7 @@ else\n   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2\n   lt_status=$lt_dlunknown\n   cat > conftest.$ac_ext <<_LT_EOF\n-#line 18721 \"configure\"\n+#line 18740 \"configure\"\n #include \"confdefs.h\"\n \n #if HAVE_DLFCN_H\n@@ -29526,6 +29546,9 @@ fi\n \n \n \n+\n+\n+\n \n \n \n--- a/gcc/configure.ac\n+++ b/gcc/configure.ac\n@@ -1754,6 +1754,7 @@ AC_SUBST(build_subdir)\n \n tm_file=\"${tm_file} defaults.h\"\n tm_p_file=\"${tm_p_file} tm-preds.h\"\n+tm_d_file=\"${tm_d_file} defaults.h\"\n host_xm_file=\"auto-host.h ansidecl.h ${host_xm_file}\"\n build_xm_file=\"${build_auto} ansidecl.h ${build_xm_file}\"\n # We don't want ansidecl.h in target files, write code there in ISO/GNU C.\n@@ -1986,6 +1987,21 @@ for f in $tm_p_file; do\n   esac\n done\n \n+tm_d_file_list=\n+tm_d_include_list=\"options.h insn-constants.h\"\n+for f in $tm_d_file; do\n+  case $f in\n+    defaults.h )\n+       tm_d_file_list=\"${tm_d_file_list} \\$(srcdir)/$f\"\n+       tm_d_include_list=\"${tm_d_include_list} $f\"\n+       ;;\n+    * )\n+       tm_d_file_list=\"${tm_d_file_list} \\$(srcdir)/config/$f\"\n+       tm_d_include_list=\"${tm_d_include_list} config/$f\"\n+       ;;\n+  esac\n+done\n+\n xm_file_list=\n xm_include_list=\n for f in $xm_file; do\n@@ -6323,6 +6339,8 @@ AC_SUBST(tm_include_list)\n AC_SUBST(tm_defines)\n AC_SUBST(tm_p_file_list)\n AC_SUBST(tm_p_include_list)\n+AC_SUBST(tm_d_file_list)\n+AC_SUBST(tm_d_include_list)\n AC_SUBST(xm_file_list)\n AC_SUBST(xm_include_list)\n AC_SUBST(xm_defines)\n@@ -6330,6 +6348,7 @@ AC_SUBST(use_gcc_stdint)\n AC_SUBST(c_target_objs)\n AC_SUBST(cxx_target_objs)\n AC_SUBST(fortran_target_objs)\n+AC_SUBST(d_target_objs)\n AC_SUBST(target_cpu_default)\n \n AC_SUBST_FILE(language_hooks)\n--- a/gcc/doc/tm.texi\n+++ b/gcc/doc/tm.texi\n@@ -52,6 +52,7 @@ through the macros defined in the @file{\n * MIPS Coprocessors::   MIPS coprocessor support and how to customize it.\n * PCH Target::          Validity checking for precompiled headers.\n * C++ ABI::             Controlling C++ ABI changes.\n+* D Language and ABI::  Controlling D ABI changes.\n * Named Address Spaces:: Adding support for named address spaces\n * Misc::                Everything else.\n @end menu\n@@ -106,6 +107,14 @@ documented as ``Common Target Hook''.  T\n @code{target_has_targetm_common=yes} in @file{config.gcc}; otherwise a\n default definition is used.\n \n+Similarly, there is a @code{targetdm} variable for hooks that are\n+specific to the D language front end, documented as ``D Target Hook''.\n+This is declared in @file{d/d-target.h}, the initializer\n+@code{TARGETDM_INITIALIZER} in @file{d/d-target-def.h}.  If targets\n+initialize @code{targetdm} themselves, they should set\n+@code{target_has_targetdm=yes} in @file{config.gcc}; otherwise a default\n+definition is used.\n+\n @node Driver\n @section Controlling the Compilation Driver, @file{gcc}\n @cindex driver\n@@ -10667,6 +10676,40 @@ unloaded. The default is to return false\n Return target-specific mangling context of @var{decl} or @code{NULL_TREE}.\n @end deftypefn\n \n+@node D Language and ABI\n+@section D ABI parameters\n+@cindex parameters, d abi\n+\n+@deftypefn {D Target Hook} void TARGET_D_CPU_VERSIONS (void)\n+Declare all environmental version identifiers relating to the target CPU\n+using the function @code{builtin_version}, which takes a string representing\n+the name of the version.  Version identifiers predefined by this hook apply\n+to all modules that are being compiled and imported.\n+@end deftypefn\n+\n+@deftypefn {D Target Hook} void TARGET_D_OS_VERSIONS (void)\n+Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions\n+relating to the target operating system.\n+@end deftypefn\n+\n+@deftypefn {D Target Hook} unsigned TARGET_D_CRITSEC_SIZE (void)\n+Returns the size of the data structure used by the target operating system\n+for critical sections and monitors.  For example, on Microsoft Windows this\n+would return the @code{sizeof(CRITICAL_SECTION)}, while other platforms that\n+implement pthreads would return @code{sizeof(pthread_mutex_t)}.\n+@end deftypefn\n+\n+@deftypefn {D Target Hook} {const char *} TARGET_D_FLOAT_ABI_TYPE (void)\n+Returns a string specifying which floating-point ABI is in use, or whether\n+floating-point value types are passed in FPU registers.  For most targets,\n+this would be described as either \"hard\" or \"soft\".\n+@end deftypefn\n+\n+@deftypefn {D Target Hook} {const char *} TARGET_D_OBJECT_FORMAT (void)\n+Returns a string specifying the executable object format of the platform\n+the compiler is generating code for.\n+@end deftypefn\n+\n @node Named Address Spaces\n @section Adding support for named address spaces\n @cindex named address spaces\n--- a/gcc/doc/tm.texi.in\n+++ b/gcc/doc/tm.texi.in\n@@ -52,6 +52,7 @@ through the macros defined in the @file{\n * MIPS Coprocessors::   MIPS coprocessor support and how to customize it.\n * PCH Target::          Validity checking for precompiled headers.\n * C++ ABI::             Controlling C++ ABI changes.\n+* D Language and ABI::  Controlling D ABI changes.\n * Named Address Spaces:: Adding support for named address spaces\n * Misc::                Everything else.\n @end menu\n@@ -106,6 +107,14 @@ documented as ``Common Target Hook''.  T\n @code{target_has_targetm_common=yes} in @file{config.gcc}; otherwise a\n default definition is used.\n \n+Similarly, there is a @code{targetdm} variable for hooks that are\n+specific to the D language front end, documented as ``D Target Hook''.\n+This is declared in @file{d/d-target.h}, the initializer\n+@code{TARGETDM_INITIALIZER} in @file{d/d-target-def.h}.  If targets\n+initialize @code{targetdm} themselves, they should set\n+@code{target_has_targetdm=yes} in @file{config.gcc}; otherwise a default\n+definition is used.\n+\n @node Driver\n @section Controlling the Compilation Driver, @file{gcc}\n @cindex driver\n@@ -7310,6 +7319,20 @@ floating-point support; they are not inc\n \n @hook TARGET_CXX_DECL_MANGLING_CONTEXT\n \n+@node D Language and ABI\n+@section D ABI parameters\n+@cindex parameters, d abi\n+\n+@hook TARGET_D_CPU_VERSIONS\n+\n+@hook TARGET_D_OS_VERSIONS\n+\n+@hook TARGET_D_CRITSEC_SIZE\n+\n+@hook TARGET_D_FLOAT_ABI_TYPE\n+\n+@hook TARGET_D_OBJECT_FORMAT\n+\n @node Named Address Spaces\n @section Adding support for named address spaces\n @cindex named address spaces\n--- a/gcc/genhooks.c\n+++ b/gcc/genhooks.c\n@@ -34,6 +34,7 @@ static struct hook_desc hook_array[] = {\n #include \"target.def\"\n #include \"c-family/c-target.def\"\n #include \"common/common-target.def\"\n+#include \"d/d-target.def\"\n #undef DEFHOOK\n };\n \n"
  },
  {
    "path": "gcc/d/patches/patch-targetdm-untested-9.patch",
    "content": "This patch implements the support for the D language specific target hooks.\n\nThe following versions are available for all supported architectures.\n* D_HardFloat\n* D_SoftFloat\n\nThe following CPU versions are implemented:\n* Epiphany\n* HPPA\n* HPPA64\n* IA64\n* NVPTX\n* NVPTX64\n* RISCV32\n* RISCV64\n* SH\n\nThe following OS versions are implemented:\n* Windows\n** Win32\n** Win64\n** Cygwin\n** MinGW\n* OSX\n** darwin (deprecated)\n* FreeBSD\n* OpenBSD\n* NetBSD\n* DragonFlyBSD\n* Solaris\n* Posix\n\nThese official OS versions are not implemented:\n* AIX\n* BSD (other BSDs)\n* Haiku\n* PlayStation\n* PlayStation4\n* SkyOS\n* SysV3\n* SysV4\n* CRuntime_DigitalMars\n* CRuntime_Microsoft\n---\n \n--- a/gcc/config.gcc\n+++ b/gcc/config.gcc\n@@ -356,6 +356,9 @@ bfin*-*)\n crisv32-*)\n \tcpu_type=cris\n \t;;\n+epiphany-*-* )\n+\td_target_objs=\"epiphany-d.o\"\n+\t;;\n frv*)\tcpu_type=frv\n \textra_options=\"${extra_options} g.opt\"\n \t;;\n@@ -429,6 +432,7 @@ x86_64-*-*)\n \t\t       avx512vpopcntdqvlintrin.h avx512bitalgintrin.h\"\n \t;;\n ia64-*-*)\n+\td_target_objs=\"ia64-d.o\"\n \textra_headers=ia64intrin.h\n \textra_options=\"${extra_options} g.opt fused-madd.opt\"\n \t;;\n@@ -468,6 +472,7 @@ nios2-*-*)\n \t;;\n nvptx-*-*)\n \tcpu_type=nvptx\n+\td_target_objs=\"nvptx-d.o\"\n \t;;\n powerpc*-*-*spe*)\n \tcpu_type=powerpcspe\n@@ -499,6 +504,7 @@ powerpc*-*-*)\n riscv*)\n \tcpu_type=riscv\n \textra_objs=\"riscv-builtins.o riscv-c.o\"\n+\td_target_objs=\"riscv-d.o\"\n \t;;\n rs6000*-*-*)\n \textra_options=\"${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt\"\n@@ -685,8 +691,10 @@ case ${target} in\n   extra_options=\"${extra_options} darwin.opt\"\n   c_target_objs=\"${c_target_objs} darwin-c.o\"\n   cxx_target_objs=\"${cxx_target_objs} darwin-c.o\"\n+  d_target_objs=\"${d_target_objs} darwin-d.o\"\n   fortran_target_objs=\"darwin-f.o\"\n   target_has_targetcm=yes\n+  target_has_targetdm=yes\n   extra_objs=\"${extra_objs} darwin.o\"\n   extra_gcc_objs=\"darwin-driver.o\"\n   default_use_cxa_atexit=yes\n@@ -711,6 +719,9 @@ case ${target} in\n       exit 1\n       ;;\n   esac\n+  d_target_objs=\"${d_target_objs} dragonfly-d.o\"\n+  target_has_targetdm=yes\n+  tmake_file=\"${tmake_file} t-dragonfly\"\n   extra_options=\"$extra_options rpath.opt dragonfly.opt\"\n   default_use_cxa_atexit=yes\n   use_gcc_stdint=wrap\n@@ -754,6 +765,9 @@ case ${target} in\n       ;;\n   esac\n   fbsd_tm_file=\"${fbsd_tm_file} freebsd-spec.h freebsd.h freebsd-stdint.h\"\n+  d_target_objs=\"${d_target_objs} freebsd-d.o\"\n+  target_has_targetdm=yes\n+  tmake_file=\"${tmake_file} t-freebsd\"\n   extra_options=\"$extra_options rpath.opt freebsd.opt\"\n   case ${target} in\n     *-*-freebsd[345].*)\n@@ -830,6 +844,8 @@ case ${target} in\n   tm_p_file=\"${tm_p_file} netbsd-protos.h\"\n   tmake_file=\"t-netbsd t-slibgcc\"\n   extra_objs=\"${extra_objs} netbsd.o\"\n+  d_target_objs=\"${d_target_objs} netbsd-d.o\"\n+  target_has_targetdm=yes\n   gas=yes\n   gnu_ld=yes\n   use_gcc_stdint=wrap\n@@ -841,6 +857,8 @@ case ${target} in\n   ;;\n *-*-openbsd*)\n   tmake_file=\"t-openbsd\"\n+  d_target_objs=\"${d_target_objs} netbsd-d.o\"\n+  target_has_targetdm=yes\n   case ${enable_threads} in\n     yes)\n       thread_file='posix'\n@@ -906,6 +924,8 @@ case ${target} in\n   tmake_file=\"${tmake_file} t-sol2 t-slibgcc\"\n   c_target_objs=\"${c_target_objs} sol2-c.o\"\n   cxx_target_objs=\"${cxx_target_objs} sol2-c.o sol2-cxx.o\"\n+  d_target_objs=\"${d_target_objs} sol2-d.o\"\n+  target_has_targetdm=\"yes\"\n   extra_objs=\"${extra_objs} sol2.o sol2-stubs.o\"\n   extra_options=\"${extra_options} sol2.opt\"\n   case ${enable_threads}:${have_pthread_h}:${have_thread_h} in\n@@ -1768,7 +1788,9 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)\n \txm_file=i386/xm-mingw32.h\n \tc_target_objs=\"${c_target_objs} winnt-c.o\"\n \tcxx_target_objs=\"${cxx_target_objs} winnt-c.o\"\n+\td_target_objs=\"${d_target_objs} winnt-d.o\"\n \ttarget_has_targetcm=\"yes\"\n+\ttarget_has_targetdm=\"yes\"\n \tcase ${target} in\n \t\tx86_64-*-* | *-w64-*)\n \t\t\tneed_64bit_isa=yes\n@@ -4606,6 +4628,8 @@ case ${target} in\n \t\tthen\n \t\t\ttarget_cpu_default2=\"MASK_GAS\"\n \t\tfi\n+\t\td_target_objs=\"${d_target_objs} pa-d.o\"\n+\t\ttmake_file=\"pa/t-pa ${tmake_file}\"\n \t\t;;\n \n \tfido*-*-* | m68k*-*-*)\n@@ -4699,6 +4723,7 @@ case ${target} in\n \tsh[123456ble]*-*-* | sh-*-*)\n \t\tc_target_objs=\"${c_target_objs} sh-c.o\"\n \t\tcxx_target_objs=\"${cxx_target_objs} sh-c.o\"\n+\t\td_target_objs=\"${d_target_objs} sh-d.o\"\n \t\t;;\n \n \tsparc*-*-*)\n--- /dev/null\n+++ b/gcc/config/darwin-d.c\n@@ -0,0 +1,55 @@\n+/* Darwin support needed only by D front-end.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify it under\n+the terms of the GNU General Public License as published by the Free\n+Software Foundation; either version 3, or (at your option) any later\n+version.\n+\n+GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n+for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm_d.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_OS_VERSIONS for Darwin targets.  */\n+\n+static void\n+darwin_d_os_builtins (void)\n+{\n+  d_add_builtin_version (\"OSX\");\n+  d_add_builtin_version (\"darwin\");\n+  d_add_builtin_version (\"Posix\");\n+}\n+\n+/* Implement TARGET_D_CRITSEC_SIZE for Darwin targets.  */\n+\n+static unsigned\n+darwin_d_critsec_size (void)\n+{\n+  /* This is the sizeof pthread_mutex_t.  */\n+  if (TYPE_PRECISION (long_integer_type_node) == 64\n+      && POINTER_SIZE == 64\n+      && TYPE_PRECISION (integer_type_node) == 32)\n+    return 64;\n+  else\n+    return 44;\n+}\n+\n+#undef TARGET_D_OS_VERSIONS\n+#define TARGET_D_OS_VERSIONS darwin_d_os_builtins\n+\n+#undef TARGET_D_CRITSEC_SIZE\n+#define TARGET_D_CRITSEC_SIZE darwin_d_critsec_size\n+\n+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;\n--- /dev/null\n+++ b/gcc/config/dragonfly-d.c\n@@ -0,0 +1,49 @@\n+/* DragonFly support needed only by D front-end.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify it under\n+the terms of the GNU General Public License as published by the Free\n+Software Foundation; either version 3, or (at your option) any later\n+version.\n+\n+GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n+for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm_d.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_OS_VERSIONS for DragonFly targets.  */\n+\n+static void\n+dragonfly_d_os_builtins (void)\n+{\n+  d_add_builtin_version (\"DragonFlyBSD\");\n+  d_add_builtin_version (\"Posix\");\n+}\n+\n+/* Implement TARGET_D_CRITSEC_SIZE for DragonFly targets.  */\n+\n+static unsigned\n+dragonfly_d_critsec_size (void)\n+{\n+  /* This is the sizeof pthread_mutex_t, an opaque pointer.  */\n+  return POINTER_SIZE_UNITS;\n+}\n+\n+#undef TARGET_D_OS_VERSIONS\n+#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins\n+\n+#undef TARGET_D_CRITSEC_SIZE\n+#define TARGET_D_CRITSEC_SIZE dragonfly_d_critsec_size\n+\n+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;\n--- /dev/null\n+++ b/gcc/config/epiphany/epiphany-d.c\n@@ -0,0 +1,31 @@\n+/* Subroutines for the D front end on the EPIPHANY architecture.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for EPIPHANY targets.  */\n+\n+void\n+epiphany_d_target_versions (void)\n+{\n+  d_add_builtin_version (\"Epiphany\");\n+  d_add_builtin_version (\"D_HardFloat\");\n+}\n--- a/gcc/config/epiphany/epiphany-protos.h\n+++ b/gcc/config/epiphany/epiphany-protos.h\n@@ -60,3 +60,5 @@ extern bool epiphany_regno_rename_ok (un\n    it uses peephole2 predicates without having all the necessary headers.  */\n extern int get_attr_sched_use_fpu (rtx_insn *);\n \n+/* Routines implemented in epiphany-d.c  */\n+extern void epiphany_d_target_versions (void);\n--- a/gcc/config/epiphany/epiphany.h\n+++ b/gcc/config/epiphany/epiphany.h\n@@ -41,6 +41,9 @@ along with GCC; see the file COPYING3.\n \tbuiltin_assert (\"machine=epiphany\");\t\\\n     } while (0)\n \n+/* Target CPU versions for D.  */\n+#define TARGET_D_CPU_VERSIONS epiphany_d_target_versions\n+\n /* Pick up the libgloss library. One day we may do this by linker script, but\n    for now its static.\n    libgloss might use errno/__errno, which might not have been needed when we\n--- a/gcc/config/epiphany/t-epiphany\n+++ b/gcc/config/epiphany/t-epiphany\n@@ -36,3 +36,7 @@ specs: specs.install\n \tsed -e 's,epiphany_library_extra_spec,epiphany_library_stub_spec,' \\\n \t-e 's,epiphany_library_build_spec,epiphany_library_extra_spec,' \\\n \t  < specs.install > $@ ; \\\n+\n+epiphany-d.o: $(srcdir)/config/epiphany/epiphany-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n--- /dev/null\n+++ b/gcc/config/freebsd-d.c\n@@ -0,0 +1,49 @@\n+/* FreeBSD support needed only by D front-end.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify it under\n+the terms of the GNU General Public License as published by the Free\n+Software Foundation; either version 3, or (at your option) any later\n+version.\n+\n+GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n+for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm_d.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_OS_VERSIONS for FreeBSD targets.  */\n+\n+static void\n+freebsd_d_os_builtins (void)\n+{\n+  d_add_builtin_version (\"FreeBSD\");\n+  d_add_builtin_version (\"Posix\");\n+}\n+\n+/* Implement TARGET_D_CRITSEC_SIZE for FreeBSD targets.  */\n+\n+static unsigned\n+freebsd_d_critsec_size (void)\n+{\n+  /* This is the sizeof pthread_mutex_t, an opaque pointer.  */\n+  return POINTER_SIZE_UNITS;\n+}\n+\n+#undef TARGET_D_OS_VERSIONS\n+#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins\n+\n+#undef TARGET_D_CRITSEC_SIZE\n+#define TARGET_D_CRITSEC_SIZE freebsd_d_critsec_size\n+\n+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;\n--- a/gcc/config/i386/cygwin.h\n+++ b/gcc/config/i386/cygwin.h\n@@ -29,6 +29,12 @@ along with GCC; see the file COPYING3.\n     }\t\t\t\t\t\t\t\t\\\n   while (0)\n \n+#define EXTRA_TARGET_D_OS_VERSIONS()\t\t\t\t\\\n+    do {\t\t\t\t\t\t\t\\\n+      builtin_version (\"Cygwin\");\t\t\t\t\\\n+      builtin_version (\"Posix\");\t\t\t\t\\\n+    } while (0)\n+\n #undef CPP_SPEC\n #define CPP_SPEC \"%(cpp_cpu) %{posix:-D_POSIX_SOURCE} \\\n   %{!ansi:-Dunix} \\\n--- a/gcc/config/i386/mingw32.h\n+++ b/gcc/config/i386/mingw32.h\n@@ -53,6 +53,16 @@ along with GCC; see the file COPYING3.\n     }\t\t\t\t\t\t\t\t\\\n   while (0)\n \n+#define EXTRA_TARGET_D_OS_VERSIONS()\t\t\t\t\\\n+    do {\t\t\t\t\t\t\t\\\n+      builtin_version (\"MinGW\");\t\t\t\t\\\n+\t\t\t\t\t\t\t\t\\\n+      if (TARGET_64BIT && ix86_abi == MS_ABI)\t\t\t\\\n+\t  builtin_version (\"Win64\");\t\t\t\t\\\n+      else if (!TARGET_64BIT)\t\t\t\t\t\\\n+        builtin_version (\"Win32\");\t\t\t\t\\\n+    } while (0)\n+\n #ifndef TARGET_USE_PTHREAD_BY_DEFAULT\n #define SPEC_PTHREAD1 \"pthread\"\n #define SPEC_PTHREAD2 \"!no-pthread\"\n--- a/gcc/config/i386/t-cygming\n+++ b/gcc/config/i386/t-cygming\n@@ -32,6 +32,9 @@ winnt-cxx.o: $(srcdir)/config/i386/winnt\n \t$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \\\n \t$(srcdir)/config/i386/winnt-cxx.c\n \n+winnt-d.o: config/winnt-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n \n winnt-stubs.o: $(srcdir)/config/i386/winnt-stubs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \\\n   $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \\\n--- /dev/null\n+++ b/gcc/config/i386/winnt-d.c\n@@ -0,0 +1,60 @@\n+/* Windows support needed only by D front-end.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify it under\n+the terms of the GNU General Public License as published by the Free\n+Software Foundation; either version 3, or (at your option) any later\n+version.\n+\n+GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n+for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"target.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+#include \"tm_p.h\"\n+\n+/* Implement TARGET_D_OS_VERSIONS for Windows targets.  */\n+\n+static void\n+winnt_d_os_builtins (void)\n+{\n+  d_add_builtin_version (\"Windows\");\n+\n+#define builtin_version(TXT) d_add_builtin_version (TXT)\n+\n+#ifdef EXTRA_TARGET_D_OS_VERSIONS\n+  EXTRA_TARGET_D_OS_VERSIONS ();\n+#endif\n+}\n+\n+/* Implement TARGET_D_CRITSEC_SIZE for Windows targets.  */\n+\n+static unsigned\n+winnt_d_critsec_size (void)\n+{\n+  /* This is the sizeof CRITICAL_SECTION.  */\n+  if (TYPE_PRECISION (long_integer_type_node) == 64\n+      && POINTER_SIZE == 64\n+      && TYPE_PRECISION (integer_type_node) == 32)\n+    return 40;\n+  else\n+    return 24;\n+}\n+\n+#undef TARGET_D_OS_VERSIONS\n+#define TARGET_D_OS_VERSIONS winnt_d_os_builtins\n+\n+#undef TARGET_D_CRITSEC_SIZE\n+#define TARGET_D_CRITSEC_SIZE winnt_d_critsec_size\n+\n+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;\n--- /dev/null\n+++ b/gcc/config/ia64/ia64-d.c\n@@ -0,0 +1,31 @@\n+/* Subroutines for the D front end on the IA64 architecture.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for IA64 targets.  */\n+\n+void\n+ia64_d_target_versions (void)\n+{\n+  d_add_builtin_version (\"IA64\");\n+  d_add_builtin_version (\"D_HardFloat\");\n+}\n--- a/gcc/config/ia64/ia64-protos.h\n+++ b/gcc/config/ia64/ia64-protos.h\n@@ -92,6 +92,9 @@ extern void ia64_hpux_handle_builtin_pra\n extern void ia64_output_function_profiler (FILE *, int);\n extern void ia64_profile_hook (int);\n \n+/* Routines implemented in ia64-d.c  */\n+extern void ia64_d_target_versions (void);\n+\n extern void ia64_init_expanders (void);\n \n extern rtx ia64_dconst_0_5 (void);\n--- a/gcc/config/ia64/ia64.h\n+++ b/gcc/config/ia64/ia64.h\n@@ -40,6 +40,9 @@ do {\t\t\t\t\t\t\\\n \t  builtin_define(\"__BIG_ENDIAN__\");\t\\\n } while (0)\n \n+/* Target CPU versions for D.  */\n+#define TARGET_D_CPU_VERSIONS ia64_d_target_versions\n+\n #ifndef SUBTARGET_EXTRA_SPECS\n #define SUBTARGET_EXTRA_SPECS\n #endif\n--- a/gcc/config/ia64/t-ia64\n+++ b/gcc/config/ia64/t-ia64\n@@ -21,6 +21,10 @@ ia64-c.o: $(srcdir)/config/ia64/ia64-c.c\n \t$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \\\n \t\t$(srcdir)/config/ia64/ia64-c.c\n \n+ia64-d.o: $(srcdir)/config/ia64/ia64-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n+\n # genattrtab generates very long string literals.\n insn-attrtab.o-warn = -Wno-error\n \n--- /dev/null\n+++ b/gcc/config/netbsd-d.c\n@@ -0,0 +1,49 @@\n+/* NetBSD support needed only by D front-end.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify it under\n+the terms of the GNU General Public License as published by the Free\n+Software Foundation; either version 3, or (at your option) any later\n+version.\n+\n+GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n+for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm_d.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_OS_VERSIONS for NetBSD targets.  */\n+\n+static void\n+netbsd_d_os_builtins (void)\n+{\n+  d_add_builtin_version (\"NetBSD\");\n+  d_add_builtin_version (\"Posix\");\n+}\n+\n+/* Implement TARGET_D_CRITSEC_SIZE for NetBSD targets.  */\n+\n+static unsigned\n+netbsd_d_critsec_size (void)\n+{\n+  /* This is the sizeof pthread_mutex_t.  */\n+  return 48;\n+}\n+\n+#undef TARGET_D_OS_VERSIONS\n+#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins\n+\n+#undef TARGET_D_CRITSEC_SIZE\n+#define TARGET_D_CRITSEC_SIZE netbsd_d_critsec_size\n+\n+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;\n--- /dev/null\n+++ b/gcc/config/nvptx/nvptx-d.c\n@@ -0,0 +1,34 @@\n+/* Subroutines for the D front end on the NVPTX architecture.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"target.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for NVPTX targets.  */\n+\n+void\n+nvptx_d_target_versions (void)\n+{\n+  if (TARGET_ABI64)\n+    d_add_builtin_version (\"NVPTX64\");\n+  else\n+    d_add_builtin_version (\"NVPTX\");\n+}\n--- a/gcc/config/nvptx/nvptx-protos.h\n+++ b/gcc/config/nvptx/nvptx-protos.h\n@@ -43,6 +43,9 @@ extern void nvptx_output_ascii (FILE *,\n extern void nvptx_register_pragmas (void);\n extern unsigned int nvptx_data_alignment (const_tree, unsigned int);\n \n+/* Routines implemented in nvptx-d.c  */\n+extern void nvptx_d_target_versions (void);\n+\n #ifdef RTX_CODE\n extern void nvptx_expand_oacc_fork (unsigned);\n extern void nvptx_expand_oacc_join (unsigned);\n--- a/gcc/config/nvptx/nvptx.h\n+++ b/gcc/config/nvptx/nvptx.h\n@@ -37,6 +37,9 @@\n         builtin_define (\"__nvptx_unisimt__\");\t\\\n     } while (0)\n \n+/* Target CPU versions for D.  */\n+#define TARGET_D_CPU_VERSIONS nvptx_d_target_versions\n+\n /* Avoid the default in ../../gcc.c, which adds \"-pthread\", which is not\n    supported for nvptx.  */\n #define GOMP_SELF_SPECS \"\"\n--- a/gcc/config/nvptx/t-nvptx\n+++ b/gcc/config/nvptx/t-nvptx\n@@ -10,3 +10,7 @@ mkoffload$(exeext): mkoffload.o collect-\n \t  mkoffload.o collect-utils.o libcommon-target.a $(LIBIBERTY) $(LIBS)\n \n MULTILIB_OPTIONS = mgomp\n+\n+nvptx-d.o: $(srcdir)/config/nvptx/nvptx-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n--- /dev/null\n+++ b/gcc/config/openbsd-d.c\n@@ -0,0 +1,49 @@\n+/* OpenBSD support needed only by D front-end.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify it under\n+the terms of the GNU General Public License as published by the Free\n+Software Foundation; either version 3, or (at your option) any later\n+version.\n+\n+GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n+for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm_d.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_OS_VERSIONS for OpenBSD targets.  */\n+\n+static void\n+openbsd_d_os_builtins (void)\n+{\n+  d_add_builtin_version (\"OpenBSD\");\n+  d_add_builtin_version (\"Posix\");\n+}\n+\n+/* Implement TARGET_D_CRITSEC_SIZE for OpenBSD targets.  */\n+\n+static unsigned\n+openbsd_d_critsec_size (void)\n+{\n+  /* This is the sizeof pthread_mutex_t, an opaque pointer.  */\n+  return POINTER_SIZE_UNITS;\n+}\n+\n+#undef TARGET_D_OS_VERSIONS\n+#define TARGET_D_OS_VERSIONS openbsd_d_os_builtins\n+\n+#undef TARGET_D_CRITSEC_SIZE\n+#define TARGET_D_CRITSEC_SIZE openbsd_d_critsec_size\n+\n+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;\n--- /dev/null\n+++ b/gcc/config/pa/pa-d.c\n@@ -0,0 +1,39 @@\n+/* Subroutines for the D front end on the HPPA architecture.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for HPPA targets.  */\n+\n+void\n+pa_d_target_versions (void)\n+{\n+  if (TARGET_64BIT)\n+    d_add_builtin_version (\"HPPA64\");\n+  else\n+    d_add_builtin_version(\"HPPA\");\n+\n+  if (TARGET_SOFT_FLOAT)\n+    d_add_builtin_version (\"D_SoftFloat\");\n+  else\n+    d_add_builtin_version (\"D_HardFloat\");\n+}\n--- a/gcc/config/pa/pa-linux.h\n+++ b/gcc/config/pa/pa-linux.h\n@@ -27,6 +27,8 @@ along with GCC; see the file COPYING3.\n     }\t\t\t\t\t\t\\\n   while (0)\n \n+#define GNU_USER_TARGET_D_CRITSEC_SIZE 48\n+\n #undef CPP_SPEC\n #define CPP_SPEC \"%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}\"\n \n--- a/gcc/config/pa/pa-protos.h\n+++ b/gcc/config/pa/pa-protos.h\n@@ -110,3 +110,6 @@ extern HOST_WIDE_INT pa_initial_eliminat\n extern HOST_WIDE_INT pa_function_arg_size (machine_mode, const_tree);\n \n extern const int pa_magic_milli[];\n+\n+/* Routines implemented in pa-d.c  */\n+extern void pa_d_target_versions (void);\n--- a/gcc/config/pa/pa.h\n+++ b/gcc/config/pa/pa.h\n@@ -196,6 +196,9 @@ do {\t\t\t\t\t\t\t\t\\\n     }\t\t\t\t\t\t\t\t\\\n   while (0)\n \n+/* Target CPU versions for D.  */\n+#define TARGET_D_CPU_VERSIONS pa_d_target_versions\n+\n #define CC1_SPEC \"%{pg:} %{p:}\"\n \n #define LINK_SPEC \"%{mlinker-opt:-O} %{!shared:-u main} %{shared:-b}\"\n--- /dev/null\n+++ b/gcc/config/pa/t-pa\n@@ -0,0 +1,3 @@\n+pa-d.o: $(srcdir)/config/pa/pa-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n--- /dev/null\n+++ b/gcc/config/riscv/riscv-d.c\n@@ -0,0 +1,39 @@\n+/* Subroutines for the D front end on the RISC-V architecture.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"target.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for RISC-V targets.  */\n+\n+void\n+riscv_d_target_versions (void)\n+{\n+  if (TARGET_64BIT)\n+    d_add_builtin_version (\"RISCV64\");\n+  else\n+    d_add_builtin_version (\"RISCV32\");\n+\n+  if (TARGET_HARDFLOAT)\n+    d_add_builtin_version (\"D_HardFloat\");\n+  else\n+    d_add_builtin_version (\"D_SoftFloat\");\n+}\n--- a/gcc/config/riscv/riscv-protos.h\n+++ b/gcc/config/riscv/riscv-protos.h\n@@ -74,6 +74,9 @@ extern bool riscv_expand_block_move (rtx\n /* Routines implemented in riscv-c.c.  */\n void riscv_cpu_cpp_builtins (cpp_reader *);\n \n+/* Routines implemented in riscv-d.c  */\n+extern void riscv_d_target_versions (void);\n+\n /* Routines implemented in riscv-builtins.c.  */\n extern void riscv_atomic_assign_expand_fenv (tree *, tree *, tree *);\n extern rtx riscv_expand_builtin (tree, rtx, rtx, machine_mode, int);\n--- a/gcc/config/riscv/riscv.h\n+++ b/gcc/config/riscv/riscv.h\n@@ -27,6 +27,9 @@ along with GCC; see the file COPYING3.\n /* Target CPU builtins.  */\n #define TARGET_CPU_CPP_BUILTINS() riscv_cpu_cpp_builtins (pfile)\n \n+/* Target CPU versions for D.  */\n+#define TARGET_D_CPU_VERSIONS riscv_d_target_versions\n+\n /* Default target_flags if no switches are specified  */\n \n #ifndef TARGET_DEFAULT\n--- a/gcc/config/riscv/t-riscv\n+++ b/gcc/config/riscv/t-riscv\n@@ -9,3 +9,7 @@ riscv-c.o: $(srcdir)/config/riscv/riscv-\n     coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H) $(TARGET_H)\n \t$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \\\n \t\t$(srcdir)/config/riscv/riscv-c.c\n+\n+riscv-d.o: $(srcdir)/config/riscv/riscv-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n--- /dev/null\n+++ b/gcc/config/sh/sh-d.c\n@@ -0,0 +1,36 @@\n+/* Subroutines for the D front end on the SuperH architecture.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify\n+it under the terms of the GNU General Public License as published by\n+the Free Software Foundation; either version 3, or (at your option)\n+any later version.\n+\n+GCC is distributed in the hope that it will be useful,\n+but WITHOUT ANY WARRANTY; without even the implied warranty of\n+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+GNU General Public License for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_CPU_VERSIONS for SuperH targets.  */\n+\n+void\n+sh_d_target_versions (void)\n+{\n+  d_add_builtin_version (\"SH\");\n+\n+  if (TARGET_FPU_ANY)\n+    d_add_builtin_version (\"D_HardFloat\");\n+  else\n+    d_add_builtin_version (\"D_SoftFloat\");\n+}\n--- a/gcc/config/sh/sh-protos.h\n+++ b/gcc/config/sh/sh-protos.h\n@@ -363,4 +363,7 @@ extern machine_mode sh_hard_regno_caller\n \t\t\t\t\t\t    machine_mode);\n extern bool sh_can_use_simple_return_p (void);\n extern rtx sh_load_function_descriptor (rtx);\n+\n+/* Routines implemented in sh-d.c  */\n+extern void sh_d_target_versions (void);\n #endif /* ! GCC_SH_PROTOS_H */\n--- a/gcc/config/sh/sh.h\n+++ b/gcc/config/sh/sh.h\n@@ -31,6 +31,9 @@ extern int code_for_indirect_jump_scratc\n \n #define TARGET_CPU_CPP_BUILTINS() sh_cpu_cpp_builtins (pfile)\n \n+/* Target CPU versions for D.  */\n+#define TARGET_D_CPU_VERSIONS sh_d_target_versions\n+\n /* Value should be nonzero if functions must have frame pointers.\n    Zero means the frame pointer need not be set up (and parms may be accessed\n    via the stack pointer) in functions that seem suitable.  */\n--- a/gcc/config/sh/t-sh\n+++ b/gcc/config/sh/t-sh\n@@ -25,6 +25,10 @@ sh-c.o: $(srcdir)/config/sh/sh-c.c \\\n \t$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \\\n \t\t$(srcdir)/config/sh/sh-c.c\n \n+sh-d.o: $(srcdir)/config/sh/sh-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n+\n sh_treg_combine.o: $(srcdir)/config/sh/sh_treg_combine.cc \\\n   $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h\n \t$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<\n--- /dev/null\n+++ b/gcc/config/sol2-d.c\n@@ -0,0 +1,49 @@\n+/* Solaris support needed only by D front-end.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+\n+GCC is free software; you can redistribute it and/or modify it under\n+the terms of the GNU General Public License as published by the Free\n+Software Foundation; either version 3, or (at your option) any later\n+version.\n+\n+GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n+for more details.\n+\n+You should have received a copy of the GNU General Public License\n+along with GCC; see the file COPYING3.  If not see\n+<http://www.gnu.org/licenses/>.  */\n+\n+#include \"config.h\"\n+#include \"system.h\"\n+#include \"coretypes.h\"\n+#include \"tm_d.h\"\n+#include \"d/d-target.h\"\n+#include \"d/d-target-def.h\"\n+\n+/* Implement TARGET_D_OS_VERSIONS for Solaris targets.  */\n+\n+static void\n+solaris_d_os_builtins (void)\n+{\n+  d_add_builtin_version (\"Solaris\");\n+  d_add_builtin_version (\"Posix\");\n+}\n+\n+/* Implement TARGET_D_CRITSEC_SIZE for Solaris targets.  */\n+\n+static unsigned\n+solaris_d_critsec_size (void)\n+{\n+  /* This is the sizeof pthread_mutex_t.  */\n+  return 24;\n+}\n+\n+#undef TARGET_D_OS_VERSIONS\n+#define TARGET_D_OS_VERSIONS solaris_d_os_builtins\n+\n+#undef TARGET_D_CRITSEC_SIZE\n+#define TARGET_D_CRITSEC_SIZE solaris_d_critsec_size\n+\n+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;\n--- a/gcc/config/t-darwin\n+++ b/gcc/config/t-darwin\n@@ -26,6 +26,9 @@ darwin-c.o: $(srcdir)/config/darwin-c.c\n \t$(COMPILE) $(PREPROCESSOR_DEFINES) $<\n \t$(POSTCOMPILE)\n \n+darwin-d.o: $(srcdir)/config/darwin-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n \n darwin-f.o: $(srcdir)/config/darwin-f.c\n \t$(COMPILE) $<\n--- /dev/null\n+++ b/gcc/config/t-dragonfly\n@@ -0,0 +1,3 @@\n+dragonfly-d.o: config/dragonfly-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n--- /dev/null\n+++ b/gcc/config/t-freebsd\n@@ -0,0 +1,3 @@\n+freebsd-d.o: config/freebsd-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n--- a/gcc/config/t-netbsd\n+++ b/gcc/config/t-netbsd\n@@ -1,3 +1,6 @@\n+netbsd-d.o: config/netbsd-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n # Copyright (C) 2017-2018 Free Software Foundation, Inc.\n #\n # This file is part of GCC.\n--- a/gcc/config/t-openbsd\n+++ b/gcc/config/t-openbsd\n@@ -1,2 +1,6 @@\n # We don't need GCC's own include files.\n USER_H = $(EXTRA_HEADERS)\n+\n+openbsd-d.o: config/openbsd-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n--- a/gcc/config/t-sol2\n+++ b/gcc/config/t-sol2\n@@ -26,6 +26,11 @@ sol2-cxx.o: $(srcdir)/config/sol2-cxx.c\n \t$(COMPILE) $<\n \t$(POSTCOMPILE)\n \n+# Solaris-specific D support.\n+sol2-d.o: $(srcdir)/config/sol2-d.c\n+\t$(COMPILE) $<\n+\t$(POSTCOMPILE)\n+\n # Corresponding stub routines.\n sol2-stubs.o: $(srcdir)/config/sol2-stubs.c\n \t$(COMPILE) $<\n"
  },
  {
    "path": "gcc/d/patches/patch-toplev-9.patch",
    "content": "This implements building of libphobos library in GCC.\n---\n\n--- a/Makefile.def\n+++ b/Makefile.def\n@@ -153,6 +153,8 @@ target_modules = { module= libgfortran;\n target_modules = { module= libobjc; };\n target_modules = { module= libgo; };\n target_modules = { module= libhsail-rt; };\n+target_modules = { module= libphobos;\n+\t\t   lib_path=src/.libs; };\n target_modules = { module= libtermcap; no_check=true;\n                    missing=mostlyclean;\n                    missing=clean;\n@@ -265,6 +267,8 @@ flags_to_pass = { flag= STAGE1_CHECKING\n flags_to_pass = { flag= STAGE1_LANGUAGES ; };\n flags_to_pass = { flag= GNATBIND ; };\n flags_to_pass = { flag= GNATMAKE ; };\n+flags_to_pass = { flag= GDC ; };\n+flags_to_pass = { flag= GDCFLAGS ; };\n \n // Target tools\n flags_to_pass = { flag= AR_FOR_TARGET ; };\n@@ -278,6 +282,8 @@ flags_to_pass = { flag= FLAGS_FOR_TARGET\n flags_to_pass = { flag= GFORTRAN_FOR_TARGET ; };\n flags_to_pass = { flag= GOC_FOR_TARGET ; };\n flags_to_pass = { flag= GOCFLAGS_FOR_TARGET ; };\n+flags_to_pass = { flag= GDC_FOR_TARGET ; };\n+flags_to_pass = { flag= GDCFLAGS_FOR_TARGET ; };\n flags_to_pass = { flag= LD_FOR_TARGET ; };\n flags_to_pass = { flag= LIPO_FOR_TARGET ; };\n flags_to_pass = { flag= LDFLAGS_FOR_TARGET ; };\n@@ -544,6 +550,11 @@ dependencies = { module=configure-target\n dependencies = { module=all-target-libgo; on=all-target-libbacktrace; };\n dependencies = { module=all-target-libgo; on=all-target-libffi; };\n dependencies = { module=all-target-libgo; on=all-target-libatomic; };\n+dependencies = { module=configure-target-libphobos; on=configure-target-libbacktrace; };\n+dependencies = { module=configure-target-libphobos; on=configure-target-zlib; };\n+dependencies = { module=all-target-libphobos; on=all-target-libbacktrace; };\n+dependencies = { module=all-target-libphobos; on=all-target-zlib; };\n+dependencies = { module=all-target-libphobos; on=all-target-libatomic; };\n dependencies = { module=configure-target-libstdc++-v3; on=configure-target-libgomp; };\n dependencies = { module=configure-target-liboffloadmic; on=configure-target-libgomp; };\n dependencies = { module=configure-target-libsanitizer; on=all-target-libstdc++-v3; };\n@@ -557,6 +568,7 @@ dependencies = { module=all-target-libof\n dependencies = { module=install-target-libgo; on=install-target-libatomic; };\n dependencies = { module=install-target-libgfortran; on=install-target-libquadmath; };\n dependencies = { module=install-target-libgfortran; on=install-target-libgcc; };\n+dependencies = { module=install-target-libphobos; on=install-target-libatomic; };\n dependencies = { module=install-target-libsanitizer; on=install-target-libstdc++-v3; };\n dependencies = { module=install-target-libsanitizer; on=install-target-libgcc; };\n dependencies = { module=install-target-libvtv; on=install-target-libstdc++-v3; };\n@@ -598,6 +610,8 @@ languages = { language=go;\tgcc-check-tar\n \t\t\t\tlib-check-target=check-gotools; };\n languages = { language=brig;\tgcc-check-target=check-brig;\n \t\t\t\tlib-check-target=check-target-libhsail-rt; };\n+languages = { language=d;\tgcc-check-target=check-d;\n+\t\t\t\tlib-check-target=check-target-libphobos; };\n \n // Toplevel bootstrap\n bootstrap_stage = { id=1 ; };\n--- a/Makefile.in\n+++ b/Makefile.in\n@@ -156,6 +156,8 @@ BUILD_EXPORTS = \\\n \tGFORTRAN=\"$(GFORTRAN_FOR_BUILD)\"; export GFORTRAN; \\\n \tGOC=\"$(GOC_FOR_BUILD)\"; export GOC; \\\n \tGOCFLAGS=\"$(GOCFLAGS_FOR_BUILD)\"; export GOCFLAGS; \\\n+\tGDC=\"$(GDC_FOR_BUILD)\"; export GDC; \\\n+\tGDCFLAGS=\"$(GDCFLAGS_FOR_BUILD)\"; export GDCFLAGS; \\\n \tDLLTOOL=\"$(DLLTOOL_FOR_BUILD)\"; export DLLTOOL; \\\n \tLD=\"$(LD_FOR_BUILD)\"; export LD; \\\n \tLDFLAGS=\"$(LDFLAGS_FOR_BUILD)\"; export LDFLAGS; \\\n@@ -192,6 +194,7 @@ HOST_EXPORTS = \\\n \tCXXFLAGS=\"$(CXXFLAGS)\"; export CXXFLAGS; \\\n \tGFORTRAN=\"$(GFORTRAN)\"; export GFORTRAN; \\\n \tGOC=\"$(GOC)\"; export GOC; \\\n+\tGDC=\"$(GDC)\"; export GDC; \\\n \tAR=\"$(AR)\"; export AR; \\\n \tAS=\"$(AS)\"; export AS; \\\n \tCC_FOR_BUILD=\"$(CC_FOR_BUILD)\"; export CC_FOR_BUILD; \\\n@@ -256,6 +259,15 @@ POSTSTAGE1_HOST_EXPORTS = \\\n \tCC_FOR_BUILD=\"$$CC\"; export CC_FOR_BUILD; \\\n \t$(POSTSTAGE1_CXX_EXPORT) \\\n \t$(LTO_EXPORTS) \\\n+\tGDC=\"$$r/$(HOST_SUBDIR)/prev-gcc/gdc$(exeext) -B$$r/$(HOST_SUBDIR)/prev-gcc/ \\\n+\t  -B$(build_tooldir)/bin/ $(GDCFLAGS_FOR_TARGET) \\\n+\t  -B$$r/prev-$(TARGET_SUBDIR)/libphobos/src \\\n+\t  -I$$r/prev-$(TARGET_SUBDIR)/libphobos/libdruntime -I$$s/libphobos/libdruntime \\\n+\t  -L$$r/prev-$(TARGET_SUBDIR)/libphobos/src/.libs \\\n+\t  -L$$r/prev-$(TARGET_SUBDIR)/libphobos/libdruntime/.libs \\\n+\t  -L$$r/prev-$(TARGET_SUBDIR)/libstdc++-v3/src/.libs\"; \\\n+\texport GDC; \\\n+\tGDC_FOR_BUILD=\"$$GDC\"; export GDC_FOR_BUILD; \\\n \tGNATBIND=\"$$r/$(HOST_SUBDIR)/prev-gcc/gnatbind\"; export GNATBIND; \\\n \tLDFLAGS=\"$(POSTSTAGE1_LDFLAGS) $(BOOT_LDFLAGS)\"; export LDFLAGS; \\\n \tHOST_LIBS=\"$(POSTSTAGE1_LIBS)\"; export HOST_LIBS;\n@@ -278,6 +290,7 @@ BASE_TARGET_EXPORTS = \\\n \tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n \tGFORTRAN=\"$(GFORTRAN_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS\"; export GFORTRAN; \\\n \tGOC=\"$(GOC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS\"; export GOC; \\\n+\tGDC=\"$(GDC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS\"; export GDC; \\\n \tDLLTOOL=\"$(DLLTOOL_FOR_TARGET)\"; export DLLTOOL; \\\n \tLD=\"$(COMPILER_LD_FOR_TARGET)\"; export LD; \\\n \tLDFLAGS=\"$(LDFLAGS_FOR_TARGET)\"; export LDFLAGS; \\\n@@ -342,6 +355,7 @@ CXX_FOR_BUILD = @CXX_FOR_BUILD@\n DLLTOOL_FOR_BUILD = @DLLTOOL_FOR_BUILD@\n GFORTRAN_FOR_BUILD = @GFORTRAN_FOR_BUILD@\n GOC_FOR_BUILD = @GOC_FOR_BUILD@\n+GDC_FOR_BUILD = @GDC_FOR_BUILD@\n LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@\n LD_FOR_BUILD = @LD_FOR_BUILD@\n NM_FOR_BUILD = @NM_FOR_BUILD@\n@@ -399,6 +413,7 @@ STRIP = @STRIP@\n WINDRES = @WINDRES@\n WINDMC = @WINDMC@\n \n+GDC = @GDC@\n GNATBIND = @GNATBIND@\n GNATMAKE = @GNATMAKE@\n \n@@ -408,6 +423,7 @@ LIBCFLAGS = $(CFLAGS)\n CXXFLAGS = @CXXFLAGS@\n LIBCXXFLAGS = $(CXXFLAGS) -fno-implicit-templates\n GOCFLAGS = $(CFLAGS)\n+GDCFLAGS = $(CFLAGS)\n \n CREATE_GCOV = create_gcov\n \n@@ -574,6 +590,7 @@ CXX_FOR_TARGET=$(STAGE_CC_WRAPPER) @CXX_\n RAW_CXX_FOR_TARGET=$(STAGE_CC_WRAPPER) @RAW_CXX_FOR_TARGET@\n GFORTRAN_FOR_TARGET=$(STAGE_CC_WRAPPER) @GFORTRAN_FOR_TARGET@\n GOC_FOR_TARGET=$(STAGE_CC_WRAPPER) @GOC_FOR_TARGET@\n+GDC_FOR_TARGET=$(STAGE_CC_WRAPPER) @GDC_FOR_TARGET@\n DLLTOOL_FOR_TARGET=@DLLTOOL_FOR_TARGET@\n LD_FOR_TARGET=@LD_FOR_TARGET@\n \n@@ -598,6 +615,7 @@ LIBCFLAGS_FOR_TARGET = $(CFLAGS_FOR_TARG\n LIBCXXFLAGS_FOR_TARGET = $(CXXFLAGS_FOR_TARGET) -fno-implicit-templates\n LDFLAGS_FOR_TARGET = @LDFLAGS_FOR_TARGET@\n GOCFLAGS_FOR_TARGET = -O2 -g\n+GDCFLAGS_FOR_TARGET = -O2 -g\n \n FLAGS_FOR_TARGET = @FLAGS_FOR_TARGET@\n SYSROOT_CFLAGS_FOR_TARGET = @SYSROOT_CFLAGS_FOR_TARGET@\n@@ -622,7 +640,7 @@ all:\n \n # This is the list of directories that may be needed in RPATH_ENVVAR\n # so that programs built for the target machine work.\n-TARGET_LIB_PATH = $(TARGET_LIB_PATH_libstdc++-v3)$(TARGET_LIB_PATH_libsanitizer)$(TARGET_LIB_PATH_libvtv)$(TARGET_LIB_PATH_liboffloadmic)$(TARGET_LIB_PATH_libssp)$(TARGET_LIB_PATH_libgomp)$(TARGET_LIB_PATH_libitm)$(TARGET_LIB_PATH_libatomic)$(HOST_LIB_PATH_gcc)\n+TARGET_LIB_PATH = $(TARGET_LIB_PATH_libstdc++-v3)$(TARGET_LIB_PATH_libsanitizer)$(TARGET_LIB_PATH_libvtv)$(TARGET_LIB_PATH_liboffloadmic)$(TARGET_LIB_PATH_libssp)$(TARGET_LIB_PATH_libphobos)$(TARGET_LIB_PATH_libgomp)$(TARGET_LIB_PATH_libitm)$(TARGET_LIB_PATH_libatomic)$(HOST_LIB_PATH_gcc)\n \n @if target-libstdc++-v3\n TARGET_LIB_PATH_libstdc++-v3 = $$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs:\n@@ -644,6 +662,10 @@ TARGET_LIB_PATH_liboffloadmic = $$r/$(TA\n TARGET_LIB_PATH_libssp = $$r/$(TARGET_SUBDIR)/libssp/.libs:\n @endif target-libssp\n \n+@if target-libphobos\n+TARGET_LIB_PATH_libphobos = $$r/$(TARGET_SUBDIR)/libphobos/src/.libs:\n+@endif target-libphobos\n+\n @if target-libgomp\n TARGET_LIB_PATH_libgomp = $$r/$(TARGET_SUBDIR)/libgomp/.libs:\n @endif target-libgomp\n@@ -778,6 +800,8 @@ BASE_FLAGS_TO_PASS = \\\n \t\"STAGE1_LANGUAGES=$(STAGE1_LANGUAGES)\" \\\n \t\"GNATBIND=$(GNATBIND)\" \\\n \t\"GNATMAKE=$(GNATMAKE)\" \\\n+\t\"GDC=$(GDC)\" \\\n+\t\"GDCFLAGS=$(GDCFLAGS)\" \\\n \t\"AR_FOR_TARGET=$(AR_FOR_TARGET)\" \\\n \t\"AS_FOR_TARGET=$(AS_FOR_TARGET)\" \\\n \t\"CC_FOR_TARGET=$(CC_FOR_TARGET)\" \\\n@@ -789,6 +813,8 @@ BASE_FLAGS_TO_PASS = \\\n \t\"GFORTRAN_FOR_TARGET=$(GFORTRAN_FOR_TARGET)\" \\\n \t\"GOC_FOR_TARGET=$(GOC_FOR_TARGET)\" \\\n \t\"GOCFLAGS_FOR_TARGET=$(GOCFLAGS_FOR_TARGET)\" \\\n+\t\"GDC_FOR_TARGET=$(GDC_FOR_TARGET)\" \\\n+\t\"GDCFLAGS_FOR_TARGET=$(GDCFLAGS_FOR_TARGET)\" \\\n \t\"LD_FOR_TARGET=$(LD_FOR_TARGET)\" \\\n \t\"LIPO_FOR_TARGET=$(LIPO_FOR_TARGET)\" \\\n \t\"LDFLAGS_FOR_TARGET=$(LDFLAGS_FOR_TARGET)\" \\\n@@ -851,6 +877,7 @@ EXTRA_HOST_FLAGS = \\\n \t'DLLTOOL=$(DLLTOOL)' \\\n \t'GFORTRAN=$(GFORTRAN)' \\\n \t'GOC=$(GOC)' \\\n+\t'GDC=$(GDC)' \\\n \t'LD=$(LD)' \\\n \t'LIPO=$(LIPO)' \\\n \t'NM=$(NM)' \\\n@@ -875,6 +902,7 @@ STAGE1_FLAGS_TO_PASS = \\\n POSTSTAGE1_FLAGS_TO_PASS = \\\n \tCC=\"$${CC}\" CC_FOR_BUILD=\"$${CC_FOR_BUILD}\" \\\n \tCXX=\"$${CXX}\" CXX_FOR_BUILD=\"$${CXX_FOR_BUILD}\" \\\n+\tGDC=\"$${GDC}\" GDC_FOR_BUILD=\"$${GDC_FOR_BUILD}\" \\\n \tGNATBIND=\"$${GNATBIND}\" \\\n \tLDFLAGS=\"$${LDFLAGS}\" \\\n \tHOST_LIBS=\"$${HOST_LIBS}\" \\\n@@ -907,6 +935,8 @@ EXTRA_TARGET_FLAGS = \\\n \t'GFORTRAN=$$(GFORTRAN_FOR_TARGET) $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \\\n \t'GOC=$$(GOC_FOR_TARGET) $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \\\n \t'GOCFLAGS=$$(GOCFLAGS_FOR_TARGET)' \\\n+\t'GDC=$$(GDC_FOR_TARGET) $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \\\n+\t'GDCFLAGS=$$(GDCFLAGS_FOR_TARGET)' \\\n \t'LD=$(COMPILER_LD_FOR_TARGET)' \\\n \t'LDFLAGS=$$(LDFLAGS_FOR_TARGET)' \\\n \t'LIBCFLAGS=$$(LIBCFLAGS_FOR_TARGET)' \\\n@@ -1008,6 +1038,7 @@ configure-target:  \\\n     maybe-configure-target-libobjc \\\n     maybe-configure-target-libgo \\\n     maybe-configure-target-libhsail-rt \\\n+    maybe-configure-target-libphobos \\\n     maybe-configure-target-libtermcap \\\n     maybe-configure-target-winsup \\\n     maybe-configure-target-libgloss \\\n@@ -1170,6 +1201,7 @@ all-target: maybe-all-target-libgfortran\n all-target: maybe-all-target-libobjc\n all-target: maybe-all-target-libgo\n all-target: maybe-all-target-libhsail-rt\n+all-target: maybe-all-target-libphobos\n all-target: maybe-all-target-libtermcap\n all-target: maybe-all-target-winsup\n all-target: maybe-all-target-libgloss\n@@ -1261,6 +1293,7 @@ info-target: maybe-info-target-libgfortr\n info-target: maybe-info-target-libobjc\n info-target: maybe-info-target-libgo\n info-target: maybe-info-target-libhsail-rt\n+info-target: maybe-info-target-libphobos\n info-target: maybe-info-target-libtermcap\n info-target: maybe-info-target-winsup\n info-target: maybe-info-target-libgloss\n@@ -1345,6 +1378,7 @@ dvi-target: maybe-dvi-target-libgfortran\n dvi-target: maybe-dvi-target-libobjc\n dvi-target: maybe-dvi-target-libgo\n dvi-target: maybe-dvi-target-libhsail-rt\n+dvi-target: maybe-dvi-target-libphobos\n dvi-target: maybe-dvi-target-libtermcap\n dvi-target: maybe-dvi-target-winsup\n dvi-target: maybe-dvi-target-libgloss\n@@ -1429,6 +1463,7 @@ pdf-target: maybe-pdf-target-libgfortran\n pdf-target: maybe-pdf-target-libobjc\n pdf-target: maybe-pdf-target-libgo\n pdf-target: maybe-pdf-target-libhsail-rt\n+pdf-target: maybe-pdf-target-libphobos\n pdf-target: maybe-pdf-target-libtermcap\n pdf-target: maybe-pdf-target-winsup\n pdf-target: maybe-pdf-target-libgloss\n@@ -1513,6 +1548,7 @@ html-target: maybe-html-target-libgfortr\n html-target: maybe-html-target-libobjc\n html-target: maybe-html-target-libgo\n html-target: maybe-html-target-libhsail-rt\n+html-target: maybe-html-target-libphobos\n html-target: maybe-html-target-libtermcap\n html-target: maybe-html-target-winsup\n html-target: maybe-html-target-libgloss\n@@ -1597,6 +1633,7 @@ TAGS-target: maybe-TAGS-target-libgfortr\n TAGS-target: maybe-TAGS-target-libobjc\n TAGS-target: maybe-TAGS-target-libgo\n TAGS-target: maybe-TAGS-target-libhsail-rt\n+TAGS-target: maybe-TAGS-target-libphobos\n TAGS-target: maybe-TAGS-target-libtermcap\n TAGS-target: maybe-TAGS-target-winsup\n TAGS-target: maybe-TAGS-target-libgloss\n@@ -1681,6 +1718,7 @@ install-info-target: maybe-install-info-\n install-info-target: maybe-install-info-target-libobjc\n install-info-target: maybe-install-info-target-libgo\n install-info-target: maybe-install-info-target-libhsail-rt\n+install-info-target: maybe-install-info-target-libphobos\n install-info-target: maybe-install-info-target-libtermcap\n install-info-target: maybe-install-info-target-winsup\n install-info-target: maybe-install-info-target-libgloss\n@@ -1765,6 +1803,7 @@ install-pdf-target: maybe-install-pdf-ta\n install-pdf-target: maybe-install-pdf-target-libobjc\n install-pdf-target: maybe-install-pdf-target-libgo\n install-pdf-target: maybe-install-pdf-target-libhsail-rt\n+install-pdf-target: maybe-install-pdf-target-libphobos\n install-pdf-target: maybe-install-pdf-target-libtermcap\n install-pdf-target: maybe-install-pdf-target-winsup\n install-pdf-target: maybe-install-pdf-target-libgloss\n@@ -1849,6 +1888,7 @@ install-html-target: maybe-install-html-\n install-html-target: maybe-install-html-target-libobjc\n install-html-target: maybe-install-html-target-libgo\n install-html-target: maybe-install-html-target-libhsail-rt\n+install-html-target: maybe-install-html-target-libphobos\n install-html-target: maybe-install-html-target-libtermcap\n install-html-target: maybe-install-html-target-winsup\n install-html-target: maybe-install-html-target-libgloss\n@@ -1933,6 +1973,7 @@ installcheck-target: maybe-installcheck-\n installcheck-target: maybe-installcheck-target-libobjc\n installcheck-target: maybe-installcheck-target-libgo\n installcheck-target: maybe-installcheck-target-libhsail-rt\n+installcheck-target: maybe-installcheck-target-libphobos\n installcheck-target: maybe-installcheck-target-libtermcap\n installcheck-target: maybe-installcheck-target-winsup\n installcheck-target: maybe-installcheck-target-libgloss\n@@ -2017,6 +2058,7 @@ mostlyclean-target: maybe-mostlyclean-ta\n mostlyclean-target: maybe-mostlyclean-target-libobjc\n mostlyclean-target: maybe-mostlyclean-target-libgo\n mostlyclean-target: maybe-mostlyclean-target-libhsail-rt\n+mostlyclean-target: maybe-mostlyclean-target-libphobos\n mostlyclean-target: maybe-mostlyclean-target-libtermcap\n mostlyclean-target: maybe-mostlyclean-target-winsup\n mostlyclean-target: maybe-mostlyclean-target-libgloss\n@@ -2101,6 +2143,7 @@ clean-target: maybe-clean-target-libgfor\n clean-target: maybe-clean-target-libobjc\n clean-target: maybe-clean-target-libgo\n clean-target: maybe-clean-target-libhsail-rt\n+clean-target: maybe-clean-target-libphobos\n clean-target: maybe-clean-target-libtermcap\n clean-target: maybe-clean-target-winsup\n clean-target: maybe-clean-target-libgloss\n@@ -2185,6 +2228,7 @@ distclean-target: maybe-distclean-target\n distclean-target: maybe-distclean-target-libobjc\n distclean-target: maybe-distclean-target-libgo\n distclean-target: maybe-distclean-target-libhsail-rt\n+distclean-target: maybe-distclean-target-libphobos\n distclean-target: maybe-distclean-target-libtermcap\n distclean-target: maybe-distclean-target-winsup\n distclean-target: maybe-distclean-target-libgloss\n@@ -2269,6 +2313,7 @@ maintainer-clean-target: maybe-maintaine\n maintainer-clean-target: maybe-maintainer-clean-target-libobjc\n maintainer-clean-target: maybe-maintainer-clean-target-libgo\n maintainer-clean-target: maybe-maintainer-clean-target-libhsail-rt\n+maintainer-clean-target: maybe-maintainer-clean-target-libphobos\n maintainer-clean-target: maybe-maintainer-clean-target-libtermcap\n maintainer-clean-target: maybe-maintainer-clean-target-winsup\n maintainer-clean-target: maybe-maintainer-clean-target-libgloss\n@@ -2409,6 +2454,7 @@ check-target:  \\\n     maybe-check-target-libobjc \\\n     maybe-check-target-libgo \\\n     maybe-check-target-libhsail-rt \\\n+    maybe-check-target-libphobos \\\n     maybe-check-target-libtermcap \\\n     maybe-check-target-winsup \\\n     maybe-check-target-libgloss \\\n@@ -2589,6 +2635,7 @@ install-target:  \\\n     maybe-install-target-libobjc \\\n     maybe-install-target-libgo \\\n     maybe-install-target-libhsail-rt \\\n+    maybe-install-target-libphobos \\\n     maybe-install-target-libtermcap \\\n     maybe-install-target-winsup \\\n     maybe-install-target-libgloss \\\n@@ -2693,6 +2740,7 @@ install-strip-target:  \\\n     maybe-install-strip-target-libobjc \\\n     maybe-install-strip-target-libgo \\\n     maybe-install-strip-target-libhsail-rt \\\n+    maybe-install-strip-target-libphobos \\\n     maybe-install-strip-target-libtermcap \\\n     maybe-install-strip-target-winsup \\\n     maybe-install-strip-target-libgloss \\\n@@ -46944,6 +46992,464 @@ maintainer-clean-target-libhsail-rt:\n \n \n \n+.PHONY: configure-target-libphobos maybe-configure-target-libphobos\n+maybe-configure-target-libphobos:\n+@if gcc-bootstrap\n+configure-target-libphobos: stage_current\n+@endif gcc-bootstrap\n+@if target-libphobos\n+maybe-configure-target-libphobos: configure-target-libphobos\n+configure-target-libphobos: \n+\t@: $(MAKE); $(unstage)\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\techo \"Checking multilib configuration for libphobos...\"; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libphobos/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libphobos/Makefile || exit 0; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos; \\\n+\t$(NORMAL_TARGET_EXPORTS)  \\\n+\techo Configuring in $(TARGET_SUBDIR)/libphobos; \\\n+\tcd \"$(TARGET_SUBDIR)/libphobos\" || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libphobos/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libphobos; \\\n+\trm -f no-such-file || : ; \\\n+\tCONFIG_SITE=no-such-file $(SHELL) \\\n+\t  $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias}  \\\n+\t  || exit 1\n+@endif target-libphobos\n+\n+\n+\n+\n+\n+.PHONY: all-target-libphobos maybe-all-target-libphobos\n+maybe-all-target-libphobos:\n+@if gcc-bootstrap\n+all-target-libphobos: stage_current\n+@endif gcc-bootstrap\n+@if target-libphobos\n+TARGET-target-libphobos=all\n+maybe-all-target-libphobos: all-target-libphobos\n+all-target-libphobos: configure-target-libphobos\n+\t@: $(MAKE); $(unstage)\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS)  \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_TARGET_FLAGS)   \\\n+\t\t$(TARGET-target-libphobos))\n+@endif target-libphobos\n+\n+\n+\n+\n+\n+.PHONY: check-target-libphobos maybe-check-target-libphobos\n+maybe-check-target-libphobos:\n+@if target-libphobos\n+maybe-check-target-libphobos: check-target-libphobos\n+\n+check-target-libphobos:\n+\t@: $(MAKE); $(unstage)\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(TARGET_FLAGS_TO_PASS)   check)\n+\n+@endif target-libphobos\n+\n+.PHONY: install-target-libphobos maybe-install-target-libphobos\n+maybe-install-target-libphobos:\n+@if target-libphobos\n+maybe-install-target-libphobos: install-target-libphobos\n+\n+install-target-libphobos: installdirs\n+\t@: $(MAKE); $(unstage)\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(TARGET_FLAGS_TO_PASS)  install)\n+\n+@endif target-libphobos\n+\n+.PHONY: install-strip-target-libphobos maybe-install-strip-target-libphobos\n+maybe-install-strip-target-libphobos:\n+@if target-libphobos\n+maybe-install-strip-target-libphobos: install-strip-target-libphobos\n+\n+install-strip-target-libphobos: installdirs\n+\t@: $(MAKE); $(unstage)\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(TARGET_FLAGS_TO_PASS)  install-strip)\n+\n+@endif target-libphobos\n+\n+# Other targets (info, dvi, pdf, etc.)\n+\n+.PHONY: maybe-info-target-libphobos info-target-libphobos\n+maybe-info-target-libphobos:\n+@if target-libphobos\n+maybe-info-target-libphobos: info-target-libphobos\n+\n+info-target-libphobos: \\\n+    configure-target-libphobos \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing info in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           info) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-dvi-target-libphobos dvi-target-libphobos\n+maybe-dvi-target-libphobos:\n+@if target-libphobos\n+maybe-dvi-target-libphobos: dvi-target-libphobos\n+\n+dvi-target-libphobos: \\\n+    configure-target-libphobos \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing dvi in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           dvi) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-pdf-target-libphobos pdf-target-libphobos\n+maybe-pdf-target-libphobos:\n+@if target-libphobos\n+maybe-pdf-target-libphobos: pdf-target-libphobos\n+\n+pdf-target-libphobos: \\\n+    configure-target-libphobos \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing pdf in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           pdf) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-html-target-libphobos html-target-libphobos\n+maybe-html-target-libphobos:\n+@if target-libphobos\n+maybe-html-target-libphobos: html-target-libphobos\n+\n+html-target-libphobos: \\\n+    configure-target-libphobos \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing html in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           html) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-TAGS-target-libphobos TAGS-target-libphobos\n+maybe-TAGS-target-libphobos:\n+@if target-libphobos\n+maybe-TAGS-target-libphobos: TAGS-target-libphobos\n+\n+TAGS-target-libphobos: \\\n+    configure-target-libphobos \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing TAGS in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           TAGS) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-install-info-target-libphobos install-info-target-libphobos\n+maybe-install-info-target-libphobos:\n+@if target-libphobos\n+maybe-install-info-target-libphobos: install-info-target-libphobos\n+\n+install-info-target-libphobos: \\\n+    configure-target-libphobos \\\n+    info-target-libphobos \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing install-info in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           install-info) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-install-pdf-target-libphobos install-pdf-target-libphobos\n+maybe-install-pdf-target-libphobos:\n+@if target-libphobos\n+maybe-install-pdf-target-libphobos: install-pdf-target-libphobos\n+\n+install-pdf-target-libphobos: \\\n+    configure-target-libphobos \\\n+    pdf-target-libphobos \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing install-pdf in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           install-pdf) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-install-html-target-libphobos install-html-target-libphobos\n+maybe-install-html-target-libphobos:\n+@if target-libphobos\n+maybe-install-html-target-libphobos: install-html-target-libphobos\n+\n+install-html-target-libphobos: \\\n+    configure-target-libphobos \\\n+    html-target-libphobos \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing install-html in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           install-html) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-installcheck-target-libphobos installcheck-target-libphobos\n+maybe-installcheck-target-libphobos:\n+@if target-libphobos\n+maybe-installcheck-target-libphobos: installcheck-target-libphobos\n+\n+installcheck-target-libphobos: \\\n+    configure-target-libphobos \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing installcheck in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           installcheck) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-mostlyclean-target-libphobos mostlyclean-target-libphobos\n+maybe-mostlyclean-target-libphobos:\n+@if target-libphobos\n+maybe-mostlyclean-target-libphobos: mostlyclean-target-libphobos\n+\n+mostlyclean-target-libphobos: \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing mostlyclean in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           mostlyclean) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-clean-target-libphobos clean-target-libphobos\n+maybe-clean-target-libphobos:\n+@if target-libphobos\n+maybe-clean-target-libphobos: clean-target-libphobos\n+\n+clean-target-libphobos: \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing clean in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           clean) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-distclean-target-libphobos distclean-target-libphobos\n+maybe-distclean-target-libphobos:\n+@if target-libphobos\n+maybe-distclean-target-libphobos: distclean-target-libphobos\n+\n+distclean-target-libphobos: \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing distclean in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           distclean) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+.PHONY: maybe-maintainer-clean-target-libphobos maintainer-clean-target-libphobos\n+maybe-maintainer-clean-target-libphobos:\n+@if target-libphobos\n+maybe-maintainer-clean-target-libphobos: maintainer-clean-target-libphobos\n+\n+maintainer-clean-target-libphobos: \n+\t@: $(MAKE); $(unstage)\n+\t@[ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\techo \"Doing maintainer-clean in $(TARGET_SUBDIR)/libphobos\"; \\\n+\tfor flag in $(EXTRA_TARGET_FLAGS); do \\\n+\t  eval `echo \"$$flag\" | sed -e \"s|^\\([^=]*\\)=\\(.*\\)|\\1='\\2'; export \\1|\"`; \\\n+\tdone; \\\n+\t(cd $(TARGET_SUBDIR)/libphobos && \\\n+\t  $(MAKE) $(BASE_FLAGS_TO_PASS) \"AR=$${AR}\" \"AS=$${AS}\" \\\n+\t          \"CC=$${CC}\" \"CXX=$${CXX}\" \"LD=$${LD}\" \"NM=$${NM}\" \\\n+\t          \"RANLIB=$${RANLIB}\" \\\n+\t          \"DLLTOOL=$${DLLTOOL}\" \"WINDRES=$${WINDRES}\" \"WINDMC=$${WINDMC}\" \\\n+\t           maintainer-clean) \\\n+\t  || exit 1\n+\n+@endif target-libphobos\n+\n+\n+\n+\n+\n .PHONY: configure-target-libtermcap maybe-configure-target-libtermcap\n maybe-configure-target-libtermcap:\n @if gcc-bootstrap\n@@ -52329,6 +52835,14 @@ check-gcc-brig:\n \t(cd gcc && $(MAKE) $(GCC_FLAGS_TO_PASS) check-brig);\n check-brig: check-gcc-brig check-target-libhsail-rt\n \n+.PHONY: check-gcc-d check-d\n+check-gcc-d:\n+\tr=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\t$(HOST_EXPORTS) \\\n+\t(cd gcc && $(MAKE) $(GCC_FLAGS_TO_PASS) check-d);\n+check-d: check-gcc-d check-target-libphobos\n+\n \n # The gcc part of install-no-fixedincludes, which relies on an intimate\n # knowledge of how a number of gcc internal targets (inter)operate.  Delegate.\n@@ -55521,6 +56035,7 @@ configure-target-libgfortran: stage_last\n configure-target-libobjc: stage_last\n configure-target-libgo: stage_last\n configure-target-libhsail-rt: stage_last\n+configure-target-libphobos: stage_last\n configure-target-libtermcap: stage_last\n configure-target-winsup: stage_last\n configure-target-libgloss: stage_last\n@@ -55555,6 +56070,7 @@ configure-target-libgfortran: maybe-all-\n configure-target-libobjc: maybe-all-gcc\n configure-target-libgo: maybe-all-gcc\n configure-target-libhsail-rt: maybe-all-gcc\n+configure-target-libphobos: maybe-all-gcc\n configure-target-libtermcap: maybe-all-gcc\n configure-target-winsup: maybe-all-gcc\n configure-target-libgloss: maybe-all-gcc\n@@ -56550,6 +57066,11 @@ configure-target-libgo: maybe-configure-\n all-target-libgo: maybe-all-target-libbacktrace\n all-target-libgo: maybe-all-target-libffi\n all-target-libgo: maybe-all-target-libatomic\n+configure-target-libphobos: maybe-configure-target-libbacktrace\n+configure-target-libphobos: maybe-configure-target-zlib\n+all-target-libphobos: maybe-all-target-libbacktrace\n+all-target-libphobos: maybe-all-target-zlib\n+all-target-libphobos: maybe-all-target-libatomic\n configure-target-libstdc++-v3: maybe-configure-target-libgomp\n configure-stage1-target-libstdc++-v3: maybe-configure-stage1-target-libgomp\n configure-stage2-target-libstdc++-v3: maybe-configure-stage2-target-libgomp\n@@ -56593,6 +57114,7 @@ all-stageautofeedback-target-libstdc++-v\n install-target-libgo: maybe-install-target-libatomic\n install-target-libgfortran: maybe-install-target-libquadmath\n install-target-libgfortran: maybe-install-target-libgcc\n+install-target-libphobos: maybe-install-target-libatomic\n install-target-libsanitizer: maybe-install-target-libstdc++-v3\n install-target-libsanitizer: maybe-install-target-libgcc\n install-target-libvtv: maybe-install-target-libstdc++-v3\n@@ -56717,6 +57239,7 @@ configure-target-libgfortran: maybe-all-\n configure-target-libobjc: maybe-all-target-libgcc\n configure-target-libgo: maybe-all-target-libgcc\n configure-target-libhsail-rt: maybe-all-target-libgcc\n+configure-target-libphobos: maybe-all-target-libgcc\n configure-target-libtermcap: maybe-all-target-libgcc\n configure-target-winsup: maybe-all-target-libgcc\n configure-target-libgloss: maybe-all-target-libgcc\n@@ -56755,6 +57278,8 @@ configure-target-libgo: maybe-all-target\n \n configure-target-libhsail-rt: maybe-all-target-newlib maybe-all-target-libgloss\n \n+configure-target-libphobos: maybe-all-target-newlib maybe-all-target-libgloss\n+\n configure-target-libtermcap: maybe-all-target-newlib maybe-all-target-libgloss\n \n configure-target-winsup: maybe-all-target-newlib maybe-all-target-libgloss\n--- a/Makefile.tpl\n+++ b/Makefile.tpl\n@@ -159,6 +159,8 @@ BUILD_EXPORTS = \\\n \tGFORTRAN=\"$(GFORTRAN_FOR_BUILD)\"; export GFORTRAN; \\\n \tGOC=\"$(GOC_FOR_BUILD)\"; export GOC; \\\n \tGOCFLAGS=\"$(GOCFLAGS_FOR_BUILD)\"; export GOCFLAGS; \\\n+\tGDC=\"$(GDC_FOR_BUILD)\"; export GDC; \\\n+\tGDCFLAGS=\"$(GDCFLAGS_FOR_BUILD)\"; export GDCFLAGS; \\\n \tDLLTOOL=\"$(DLLTOOL_FOR_BUILD)\"; export DLLTOOL; \\\n \tLD=\"$(LD_FOR_BUILD)\"; export LD; \\\n \tLDFLAGS=\"$(LDFLAGS_FOR_BUILD)\"; export LDFLAGS; \\\n@@ -195,6 +197,7 @@ HOST_EXPORTS = \\\n \tCXXFLAGS=\"$(CXXFLAGS)\"; export CXXFLAGS; \\\n \tGFORTRAN=\"$(GFORTRAN)\"; export GFORTRAN; \\\n \tGOC=\"$(GOC)\"; export GOC; \\\n+\tGDC=\"$(GDC)\"; export GDC; \\\n \tAR=\"$(AR)\"; export AR; \\\n \tAS=\"$(AS)\"; export AS; \\\n \tCC_FOR_BUILD=\"$(CC_FOR_BUILD)\"; export CC_FOR_BUILD; \\\n@@ -259,6 +262,15 @@ POSTSTAGE1_HOST_EXPORTS = \\\n \tCC_FOR_BUILD=\"$$CC\"; export CC_FOR_BUILD; \\\n \t$(POSTSTAGE1_CXX_EXPORT) \\\n \t$(LTO_EXPORTS) \\\n+\tGDC=\"$$r/$(HOST_SUBDIR)/prev-gcc/gdc$(exeext) -B$$r/$(HOST_SUBDIR)/prev-gcc/ \\\n+\t  -B$(build_tooldir)/bin/ $(GDCFLAGS_FOR_TARGET) \\\n+\t  -B$$r/prev-$(TARGET_SUBDIR)/libphobos/src \\\n+\t  -I$$r/prev-$(TARGET_SUBDIR)/libphobos/libdruntime -I$$s/libphobos/libdruntime \\\n+\t  -L$$r/prev-$(TARGET_SUBDIR)/libphobos/src/.libs \\\n+\t  -L$$r/prev-$(TARGET_SUBDIR)/libphobos/libdruntime/.libs \\\n+\t  -L$$r/prev-$(TARGET_SUBDIR)/libstdc++-v3/src/.libs\"; \\\n+\texport GDC; \\\n+\tGDC_FOR_BUILD=\"$$GDC\"; export GDC_FOR_BUILD; \\\n \tGNATBIND=\"$$r/$(HOST_SUBDIR)/prev-gcc/gnatbind\"; export GNATBIND; \\\n \tLDFLAGS=\"$(POSTSTAGE1_LDFLAGS) $(BOOT_LDFLAGS)\"; export LDFLAGS; \\\n \tHOST_LIBS=\"$(POSTSTAGE1_LIBS)\"; export HOST_LIBS;\n@@ -281,6 +293,7 @@ BASE_TARGET_EXPORTS = \\\n \tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n \tGFORTRAN=\"$(GFORTRAN_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS\"; export GFORTRAN; \\\n \tGOC=\"$(GOC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS\"; export GOC; \\\n+\tGDC=\"$(GDC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS\"; export GDC; \\\n \tDLLTOOL=\"$(DLLTOOL_FOR_TARGET)\"; export DLLTOOL; \\\n \tLD=\"$(COMPILER_LD_FOR_TARGET)\"; export LD; \\\n \tLDFLAGS=\"$(LDFLAGS_FOR_TARGET)\"; export LDFLAGS; \\\n@@ -345,6 +358,7 @@ CXX_FOR_BUILD = @CXX_FOR_BUILD@\n DLLTOOL_FOR_BUILD = @DLLTOOL_FOR_BUILD@\n GFORTRAN_FOR_BUILD = @GFORTRAN_FOR_BUILD@\n GOC_FOR_BUILD = @GOC_FOR_BUILD@\n+GDC_FOR_BUILD = @GDC_FOR_BUILD@\n LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@\n LD_FOR_BUILD = @LD_FOR_BUILD@\n NM_FOR_BUILD = @NM_FOR_BUILD@\n@@ -402,6 +416,7 @@ STRIP = @STRIP@\n WINDRES = @WINDRES@\n WINDMC = @WINDMC@\n \n+GDC = @GDC@\n GNATBIND = @GNATBIND@\n GNATMAKE = @GNATMAKE@\n \n@@ -411,6 +426,7 @@ LIBCFLAGS = $(CFLAGS)\n CXXFLAGS = @CXXFLAGS@\n LIBCXXFLAGS = $(CXXFLAGS) -fno-implicit-templates\n GOCFLAGS = $(CFLAGS)\n+GDCFLAGS = $(CFLAGS)\n \n CREATE_GCOV = create_gcov\n \n@@ -497,6 +513,7 @@ CXX_FOR_TARGET=$(STAGE_CC_WRAPPER) @CXX_\n RAW_CXX_FOR_TARGET=$(STAGE_CC_WRAPPER) @RAW_CXX_FOR_TARGET@\n GFORTRAN_FOR_TARGET=$(STAGE_CC_WRAPPER) @GFORTRAN_FOR_TARGET@\n GOC_FOR_TARGET=$(STAGE_CC_WRAPPER) @GOC_FOR_TARGET@\n+GDC_FOR_TARGET=$(STAGE_CC_WRAPPER) @GDC_FOR_TARGET@\n DLLTOOL_FOR_TARGET=@DLLTOOL_FOR_TARGET@\n LD_FOR_TARGET=@LD_FOR_TARGET@\n \n@@ -521,6 +538,7 @@ LIBCFLAGS_FOR_TARGET = $(CFLAGS_FOR_TARG\n LIBCXXFLAGS_FOR_TARGET = $(CXXFLAGS_FOR_TARGET) -fno-implicit-templates\n LDFLAGS_FOR_TARGET = @LDFLAGS_FOR_TARGET@\n GOCFLAGS_FOR_TARGET = -O2 -g\n+GDCFLAGS_FOR_TARGET = -O2 -g\n \n FLAGS_FOR_TARGET = @FLAGS_FOR_TARGET@\n SYSROOT_CFLAGS_FOR_TARGET = @SYSROOT_CFLAGS_FOR_TARGET@\n@@ -622,6 +640,7 @@ EXTRA_HOST_FLAGS = \\\n \t'DLLTOOL=$(DLLTOOL)' \\\n \t'GFORTRAN=$(GFORTRAN)' \\\n \t'GOC=$(GOC)' \\\n+\t'GDC=$(GDC)' \\\n \t'LD=$(LD)' \\\n \t'LIPO=$(LIPO)' \\\n \t'NM=$(NM)' \\\n@@ -646,6 +665,7 @@ STAGE1_FLAGS_TO_PASS = \\\n POSTSTAGE1_FLAGS_TO_PASS = \\\n \tCC=\"$${CC}\" CC_FOR_BUILD=\"$${CC_FOR_BUILD}\" \\\n \tCXX=\"$${CXX}\" CXX_FOR_BUILD=\"$${CXX_FOR_BUILD}\" \\\n+\tGDC=\"$${GDC}\" GDC_FOR_BUILD=\"$${GDC_FOR_BUILD}\" \\\n \tGNATBIND=\"$${GNATBIND}\" \\\n \tLDFLAGS=\"$${LDFLAGS}\" \\\n \tHOST_LIBS=\"$${HOST_LIBS}\" \\\n@@ -678,6 +698,8 @@ EXTRA_TARGET_FLAGS = \\\n \t'GFORTRAN=$$(GFORTRAN_FOR_TARGET) $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \\\n \t'GOC=$$(GOC_FOR_TARGET) $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \\\n \t'GOCFLAGS=$$(GOCFLAGS_FOR_TARGET)' \\\n+\t'GDC=$$(GDC_FOR_TARGET) $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \\\n+\t'GDCFLAGS=$$(GDCFLAGS_FOR_TARGET)' \\\n \t'LD=$(COMPILER_LD_FOR_TARGET)' \\\n \t'LDFLAGS=$$(LDFLAGS_FOR_TARGET)' \\\n \t'LIBCFLAGS=$$(LIBCFLAGS_FOR_TARGET)' \\\n--- a/config-ml.in\n+++ b/config-ml.in\n@@ -512,6 +512,7 @@ multi-do:\n \t\t\t\tprefix=\"$(prefix)\" \\\n \t\t\t\texec_prefix=\"$(exec_prefix)\" \\\n \t\t\t\tGOCFLAGS=\"$(GOCFLAGS) $${flags}\" \\\n+\t\t\t\tGDCFLAGS=\"$(GDCFLAGS) $${flags}\" \\\n \t\t\t\tCXXFLAGS=\"$(CXXFLAGS) $${flags}\" \\\n \t\t\t\tLIBCFLAGS=\"$(LIBCFLAGS) $${flags}\" \\\n \t\t\t\tLIBCXXFLAGS=\"$(LIBCXXFLAGS) $${flags}\" \\\n@@ -745,7 +746,7 @@ if [ -n \"${multidirs}\" ] && [ -z \"${ml_n\n         break\n       fi\n     done\n-    ml_config_env='CC=\"${CC_}$flags\" CXX=\"${CXX_}$flags\" F77=\"${F77_}$flags\" GFORTRAN=\"${GFORTRAN_}$flags\" GOC=\"${GOC_}$flags\"'\n+    ml_config_env='CC=\"${CC_}$flags\" CXX=\"${CXX_}$flags\" F77=\"${F77_}$flags\" GFORTRAN=\"${GFORTRAN_}$flags\" GOC=\"${GOC_}$flags\" GDC=\"${GDC_}$flags\"'\n \n     if [ \"${with_target_subdir}\" = \".\" ]; then\n \tCC_=$CC' '\n@@ -753,6 +754,7 @@ if [ -n \"${multidirs}\" ] && [ -z \"${ml_n\n \tF77_=$F77' '\n \tGFORTRAN_=$GFORTRAN' '\n \tGOC_=$GOC' '\n+\tGDC_=$GDC' '\n     else\n \t# Create a regular expression that matches any string as long\n \t# as ML_POPDIR.\n@@ -817,6 +819,18 @@ if [ -n \"${multidirs}\" ] && [ -z \"${ml_n\n \t  esac\n \tdone\n \n+\tGDC_=\n+\tfor arg in ${GDC}; do\n+\t  case $arg in\n+\t  -[BIL]\"${ML_POPDIR}\"/*)\n+\t    GDC_=\"${GDC_}\"`echo \"X${arg}\" | sed -n \"s/X\\\\(-[BIL]${popdir_rx}\\\\).*/\\\\1/p\"`/${ml_dir}`echo \"X${arg}\" | sed -n \"s/X-[BIL]${popdir_rx}\\\\(.*\\\\)/\\\\1/p\"`' ' ;;\n+\t  \"${ML_POPDIR}\"/*)\n+\t    GDC_=\"${GDC_}\"`echo \"X${arg}\" | sed -n \"s/X\\\\(${popdir_rx}\\\\).*/\\\\1/p\"`/${ml_dir}`echo \"X${arg}\" | sed -n \"s/X${popdir_rx}\\\\(.*\\\\)/\\\\1/p\"`' ' ;;\n+\t  *)\n+\t    GDC_=\"${GDC_}${arg} \" ;;\n+\t  esac\n+\tdone\n+\n \tif test \"x${LD_LIBRARY_PATH+set}\" = xset; then\n \t  LD_LIBRARY_PATH_=\n \t  for arg in `echo \"$LD_LIBRARY_PATH\" | tr ':' ' '`; do\n--- a/config/multi.m4\n+++ b/config/multi.m4\n@@ -64,4 +64,5 @@ multi_basedir=\"$multi_basedir\"\n CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}\n CC=\"$CC\"\n CXX=\"$CXX\"\n-GFORTRAN=\"$GFORTRAN\"])])dnl\n+GFORTRAN=\"$GFORTRAN\"\n+GDC=\"$GDC\"])])dnl\n--- a/configure\n+++ b/configure\n@@ -580,6 +580,7 @@ LD_FOR_TARGET\n DLLTOOL_FOR_TARGET\n AS_FOR_TARGET\n AR_FOR_TARGET\n+GDC_FOR_TARGET\n GOC_FOR_TARGET\n GFORTRAN_FOR_TARGET\n GCC_FOR_TARGET\n@@ -612,6 +613,7 @@ RANLIB_FOR_BUILD\n NM_FOR_BUILD\n LD_FOR_BUILD\n LDFLAGS_FOR_BUILD\n+GDC_FOR_BUILD\n GOC_FOR_BUILD\n GFORTRAN_FOR_BUILD\n DLLTOOL_FOR_BUILD\n@@ -830,6 +832,7 @@ CXX_FOR_TARGET\n GCC_FOR_TARGET\n GFORTRAN_FOR_TARGET\n GOC_FOR_TARGET\n+GDC_FOR_TARGET\n AR_FOR_TARGET\n AS_FOR_TARGET\n DLLTOOL_FOR_TARGET\n@@ -1613,6 +1616,8 @@ Some influential environment variables:\n               GFORTRAN for the target\n   GOC_FOR_TARGET\n               GOC for the target\n+  GDC_FOR_TARGET\n+              GDC for the target\n   AR_FOR_TARGET\n               AR for the target\n   AS_FOR_TARGET\n@@ -2764,7 +2769,8 @@ target_libraries=\"target-libgcc \\\n \t\ttarget-libffi \\\n \t\ttarget-libobjc \\\n \t\ttarget-libada \\\n-\t\ttarget-libgo\"\n+\t\ttarget-libgo \\\n+\t\ttarget-libphobos\"\n \n # these tools are built using the target libraries, and are intended to\n # run only in the target environment\n@@ -3920,6 +3926,7 @@ if test \"${build}\" != \"${host}\" ; then\n   CXX_FOR_BUILD=${CXX_FOR_BUILD-g++}\n   GFORTRAN_FOR_BUILD=${GFORTRAN_FOR_BUILD-gfortran}\n   GOC_FOR_BUILD=${GOC_FOR_BUILD-gccgo}\n+  GDC_FOR_BUILD=${GDC_FOR_BUILD-gdc}\n   DLLTOOL_FOR_BUILD=${DLLTOOL_FOR_BUILD-dlltool}\n   LD_FOR_BUILD=${LD_FOR_BUILD-ld}\n   NM_FOR_BUILD=${NM_FOR_BUILD-nm}\n@@ -3933,6 +3940,7 @@ else\n   CXX_FOR_BUILD=\"\\$(CXX)\"\n   GFORTRAN_FOR_BUILD=\"\\$(GFORTRAN)\"\n   GOC_FOR_BUILD=\"\\$(GOC)\"\n+  GDC_FOR_BUILD=\"\\$(GDC)\"\n   DLLTOOL_FOR_BUILD=\"\\$(DLLTOOL)\"\n   LD_FOR_BUILD=\"\\$(LD)\"\n   NM_FOR_BUILD=\"\\$(NM)\"\n@@ -6331,7 +6339,7 @@ $as_echo \"$as_me: WARNING: ${language} n\n \t\t  *) stage1_languages=\"${stage1_languages}${language},\" ;;\n \t\tesac\n \t\t# We need to bootstrap any supporting libraries.\n-\t\tbootstrap_target_libs=\"${bootstrap_target_libs}${target_libs},\"\n+\t\tbootstrap_target_libs=`echo \"${bootstrap_target_libs}${target_libs},\" | sed \"s/ /,/g\"`\n \t\t;;\n \t    esac\n \t    ;;\n@@ -7650,6 +7658,7 @@ done\n \n \n \n+\n # Generate default definitions for YACC, M4, LEX and other programs that run\n # on the build machine.  These are used if the Makefile can't locate these\n # programs in objdir.\n@@ -10704,6 +10713,167 @@ fi\n \n \n \n+if test -n \"$GDC_FOR_TARGET\"; then\n+  ac_cv_prog_GDC_FOR_TARGET=$GDC_FOR_TARGET\n+elif test -n \"$ac_cv_prog_GDC_FOR_TARGET\"; then\n+  GDC_FOR_TARGET=$ac_cv_prog_GDC_FOR_TARGET\n+fi\n+\n+if test -n \"$ac_cv_prog_GDC_FOR_TARGET\"; then\n+  for ncn_progname in gdc; do\n+    # Extract the first word of \"${ncn_progname}\", so it can be a program name with args.\n+set dummy ${ncn_progname}; ac_word=$2\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n+$as_echo_n \"checking for $ac_word... \" >&6; }\n+if test \"${ac_cv_prog_GDC_FOR_TARGET+set}\" = set; then :\n+  $as_echo_n \"(cached) \" >&6\n+else\n+  if test -n \"$GDC_FOR_TARGET\"; then\n+  ac_cv_prog_GDC_FOR_TARGET=\"$GDC_FOR_TARGET\" # Let the user override the test.\n+else\n+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\n+for as_dir in $PATH\n+do\n+  IFS=$as_save_IFS\n+  test -z \"$as_dir\" && as_dir=.\n+    for ac_exec_ext in '' $ac_executable_extensions; do\n+  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n+    ac_cv_prog_GDC_FOR_TARGET=\"${ncn_progname}\"\n+    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n+    break 2\n+  fi\n+done\n+  done\n+IFS=$as_save_IFS\n+\n+fi\n+fi\n+GDC_FOR_TARGET=$ac_cv_prog_GDC_FOR_TARGET\n+if test -n \"$GDC_FOR_TARGET\"; then\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $GDC_FOR_TARGET\" >&5\n+$as_echo \"$GDC_FOR_TARGET\" >&6; }\n+else\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n+$as_echo \"no\" >&6; }\n+fi\n+\n+\n+  done\n+fi\n+\n+if test -z \"$ac_cv_prog_GDC_FOR_TARGET\" && test -n \"$with_build_time_tools\"; then\n+  for ncn_progname in gdc; do\n+    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ${ncn_progname} in $with_build_time_tools\" >&5\n+$as_echo_n \"checking for ${ncn_progname} in $with_build_time_tools... \" >&6; }\n+    if test -x $with_build_time_tools/${ncn_progname}; then\n+      ac_cv_prog_GDC_FOR_TARGET=$with_build_time_tools/${ncn_progname}\n+      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n+$as_echo \"yes\" >&6; }\n+      break\n+    else\n+      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n+$as_echo \"no\" >&6; }\n+    fi\n+  done\n+fi\n+\n+if test -z \"$ac_cv_prog_GDC_FOR_TARGET\"; then\n+  for ncn_progname in gdc; do\n+    if test -n \"$ncn_target_tool_prefix\"; then\n+      # Extract the first word of \"${ncn_target_tool_prefix}${ncn_progname}\", so it can be a program name with args.\n+set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n+$as_echo_n \"checking for $ac_word... \" >&6; }\n+if test \"${ac_cv_prog_GDC_FOR_TARGET+set}\" = set; then :\n+  $as_echo_n \"(cached) \" >&6\n+else\n+  if test -n \"$GDC_FOR_TARGET\"; then\n+  ac_cv_prog_GDC_FOR_TARGET=\"$GDC_FOR_TARGET\" # Let the user override the test.\n+else\n+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\n+for as_dir in $PATH\n+do\n+  IFS=$as_save_IFS\n+  test -z \"$as_dir\" && as_dir=.\n+    for ac_exec_ext in '' $ac_executable_extensions; do\n+  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n+    ac_cv_prog_GDC_FOR_TARGET=\"${ncn_target_tool_prefix}${ncn_progname}\"\n+    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n+    break 2\n+  fi\n+done\n+  done\n+IFS=$as_save_IFS\n+\n+fi\n+fi\n+GDC_FOR_TARGET=$ac_cv_prog_GDC_FOR_TARGET\n+if test -n \"$GDC_FOR_TARGET\"; then\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $GDC_FOR_TARGET\" >&5\n+$as_echo \"$GDC_FOR_TARGET\" >&6; }\n+else\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n+$as_echo \"no\" >&6; }\n+fi\n+\n+\n+    fi\n+    if test -z \"$ac_cv_prog_GDC_FOR_TARGET\" && test $build = $target ; then\n+      # Extract the first word of \"${ncn_progname}\", so it can be a program name with args.\n+set dummy ${ncn_progname}; ac_word=$2\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n+$as_echo_n \"checking for $ac_word... \" >&6; }\n+if test \"${ac_cv_prog_GDC_FOR_TARGET+set}\" = set; then :\n+  $as_echo_n \"(cached) \" >&6\n+else\n+  if test -n \"$GDC_FOR_TARGET\"; then\n+  ac_cv_prog_GDC_FOR_TARGET=\"$GDC_FOR_TARGET\" # Let the user override the test.\n+else\n+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\n+for as_dir in $PATH\n+do\n+  IFS=$as_save_IFS\n+  test -z \"$as_dir\" && as_dir=.\n+    for ac_exec_ext in '' $ac_executable_extensions; do\n+  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n+    ac_cv_prog_GDC_FOR_TARGET=\"${ncn_progname}\"\n+    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n+    break 2\n+  fi\n+done\n+  done\n+IFS=$as_save_IFS\n+\n+fi\n+fi\n+GDC_FOR_TARGET=$ac_cv_prog_GDC_FOR_TARGET\n+if test -n \"$GDC_FOR_TARGET\"; then\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $GDC_FOR_TARGET\" >&5\n+$as_echo \"$GDC_FOR_TARGET\" >&6; }\n+else\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n+$as_echo \"no\" >&6; }\n+fi\n+\n+\n+    fi\n+    test -n \"$ac_cv_prog_GDC_FOR_TARGET\" && break\n+  done\n+fi\n+\n+if test -z \"$ac_cv_prog_GDC_FOR_TARGET\" ; then\n+  set dummy gdc\n+  if test $build = $target ; then\n+    GDC_FOR_TARGET=\"$2\"\n+  else\n+    GDC_FOR_TARGET=\"${ncn_target_tool_prefix}$2\"\n+  fi\n+else\n+  GDC_FOR_TARGET=\"$ac_cv_prog_GDC_FOR_TARGET\"\n+fi\n+\n+\n+\n cat > conftest.c << \\EOF\n #ifdef __GNUC__\n   gcc_yay;\n@@ -14094,6 +14264,51 @@ $as_echo \"pre-installed in $ac_dir\" >&6;\n     { $as_echo \"$as_me:${as_lineno-$LINENO}: result: host tool\" >&5\n $as_echo \"host tool\" >&6; }\n   else\n+    # We need a cross tool\n+    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: pre-installed\" >&5\n+$as_echo \"pre-installed\" >&6; }\n+  fi\n+fi\n+\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking where to find the target gdc\" >&5\n+$as_echo_n \"checking where to find the target gdc... \" >&6; }\n+if test \"x${build}\" != \"x${host}\" ; then\n+  if expr \"x$GDC_FOR_TARGET\" : \"x/\" > /dev/null; then\n+    # We already found the complete path\n+    ac_dir=`dirname $GDC_FOR_TARGET`\n+    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: pre-installed in $ac_dir\" >&5\n+$as_echo \"pre-installed in $ac_dir\" >&6; }\n+  else\n+    # Canadian cross, just use what we found\n+    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: pre-installed\" >&5\n+$as_echo \"pre-installed\" >&6; }\n+  fi\n+else\n+  ok=yes\n+  case \" ${configdirs} \" in\n+    *\" gcc \"*) ;;\n+    *) ok=no ;;\n+  esac\n+  case ,${enable_languages}, in\n+    *,d,*) ;;\n+    *) ok=no ;;\n+  esac\n+  if test $ok = yes; then\n+    # An in-tree tool is available and we can use it\n+    GDC_FOR_TARGET='$$r/$(HOST_SUBDIR)/gcc/gdc -B$$r/$(HOST_SUBDIR)/gcc/'\n+    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: just compiled\" >&5\n+$as_echo \"just compiled\" >&6; }\n+  elif expr \"x$GDC_FOR_TARGET\" : \"x/\" > /dev/null; then\n+    # We already found the complete path\n+    ac_dir=`dirname $GDC_FOR_TARGET`\n+    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: pre-installed in $ac_dir\" >&5\n+$as_echo \"pre-installed in $ac_dir\" >&6; }\n+  elif test \"x$target\" = \"x$host\"; then\n+    # We can use an host tool\n+    GDC_FOR_TARGET='$(GDC)'\n+    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: host tool\" >&5\n+$as_echo \"host tool\" >&6; }\n+  else\n     # We need a cross tool\n     { $as_echo \"$as_me:${as_lineno-$LINENO}: result: pre-installed\" >&5\n $as_echo \"pre-installed\" >&6; }\n--- a/configure.ac\n+++ b/configure.ac\n@@ -163,7 +163,8 @@ target_libraries=\"target-libgcc \\\n \t\ttarget-libffi \\\n \t\ttarget-libobjc \\\n \t\ttarget-libada \\\n-\t\ttarget-libgo\"\n+\t\ttarget-libgo \\\n+\t\ttarget-libphobos\"\n \n # these tools are built using the target libraries, and are intended to\n # run only in the target environment\n@@ -1235,6 +1236,7 @@ if test \"${build}\" != \"${host}\" ; then\n   CXX_FOR_BUILD=${CXX_FOR_BUILD-g++}\n   GFORTRAN_FOR_BUILD=${GFORTRAN_FOR_BUILD-gfortran}\n   GOC_FOR_BUILD=${GOC_FOR_BUILD-gccgo}\n+  GDC_FOR_BUILD=${GDC_FOR_BUILD-gdc}\n   DLLTOOL_FOR_BUILD=${DLLTOOL_FOR_BUILD-dlltool}\n   LD_FOR_BUILD=${LD_FOR_BUILD-ld}\n   NM_FOR_BUILD=${NM_FOR_BUILD-nm}\n@@ -1248,6 +1250,7 @@ else\n   CXX_FOR_BUILD=\"\\$(CXX)\"\n   GFORTRAN_FOR_BUILD=\"\\$(GFORTRAN)\"\n   GOC_FOR_BUILD=\"\\$(GOC)\"\n+  GDC_FOR_BUILD=\"\\$(GDC)\"\n   DLLTOOL_FOR_BUILD=\"\\$(DLLTOOL)\"\n   LD_FOR_BUILD=\"\\$(LD)\"\n   NM_FOR_BUILD=\"\\$(NM)\"\n@@ -2006,7 +2009,7 @@ directories, to avoid imposing the perfo\n \t\t  *) stage1_languages=\"${stage1_languages}${language},\" ;;\n \t\tesac\n \t\t# We need to bootstrap any supporting libraries.\n-\t\tbootstrap_target_libs=\"${bootstrap_target_libs}${target_libs},\"\n+\t\tbootstrap_target_libs=`echo \"${bootstrap_target_libs}${target_libs},\" | sed \"s/ /,/g\"`\n \t\t;;\n \t    esac\n \t    ;;\n@@ -3235,6 +3238,7 @@ AC_SUBST(CXX_FOR_BUILD)\n AC_SUBST(DLLTOOL_FOR_BUILD)\n AC_SUBST(GFORTRAN_FOR_BUILD)\n AC_SUBST(GOC_FOR_BUILD)\n+AC_SUBST(GDC_FOR_BUILD)\n AC_SUBST(LDFLAGS_FOR_BUILD)\n AC_SUBST(LD_FOR_BUILD)\n AC_SUBST(NM_FOR_BUILD)\n@@ -3344,6 +3348,7 @@ NCN_STRICT_CHECK_TARGET_TOOLS(CXX_FOR_TA\n NCN_STRICT_CHECK_TARGET_TOOLS(GCC_FOR_TARGET, gcc, ${CC_FOR_TARGET})\n NCN_STRICT_CHECK_TARGET_TOOLS(GFORTRAN_FOR_TARGET, gfortran)\n NCN_STRICT_CHECK_TARGET_TOOLS(GOC_FOR_TARGET, gccgo)\n+NCN_STRICT_CHECK_TARGET_TOOLS(GDC_FOR_TARGET, gdc)\n \n ACX_CHECK_INSTALLED_TARGET_TOOL(AR_FOR_TARGET, ar)\n ACX_CHECK_INSTALLED_TARGET_TOOL(AS_FOR_TARGET, as)\n@@ -3377,6 +3382,8 @@ GCC_TARGET_TOOL(gfortran, GFORTRAN_FOR_T\n \t\t[gcc/gfortran -B$$r/$(HOST_SUBDIR)/gcc/], fortran)\n GCC_TARGET_TOOL(gccgo, GOC_FOR_TARGET, GOC,\n \t\t[gcc/gccgo -B$$r/$(HOST_SUBDIR)/gcc/], go)\n+GCC_TARGET_TOOL(gdc, GDC_FOR_TARGET, GDC,\n+\t\t[gcc/gdc -B$$r/$(HOST_SUBDIR)/gcc/], d)\n GCC_TARGET_TOOL(ld, LD_FOR_TARGET, LD, [ld/ld-new])\n GCC_TARGET_TOOL(lipo, LIPO_FOR_TARGET, LIPO)\n GCC_TARGET_TOOL(nm, NM_FOR_TARGET, NM, [binutils/nm-new])\n"
  },
  {
    "path": "gcc/d/patches/patch-toplev-ddmd-9.patch",
    "content": "This implements building of self hosted D compiler in GCC.\n---\n\n--- a/Makefile.def\n+++ b/Makefile.def\n@@ -147,13 +147,14 @@ target_modules = { module= liboffloadmic\n target_modules = { module= libssp; lib_path=.libs; };\n target_modules = { module= newlib; };\n target_modules = { module= libgcc; bootstrap=true; no_check=true; };\n-target_modules = { module= libbacktrace; };\n+target_modules = { module= libbacktrace; bootstrap=true; };\n target_modules = { module= libquadmath; };\n target_modules = { module= libgfortran; };\n target_modules = { module= libobjc; };\n target_modules = { module= libgo; };\n target_modules = { module= libhsail-rt; };\n target_modules = { module= libphobos;\n+\t\t   bootstrap=true;\n \t\t   lib_path=src/.libs; };\n target_modules = { module= libtermcap; no_check=true;\n                    missing=mostlyclean;\n@@ -168,7 +169,7 @@ target_modules = { module= rda; };\n target_modules = { module= libada; };\n target_modules = { module= libgomp; bootstrap= true; lib_path=.libs; };\n target_modules = { module= libitm; lib_path=.libs; };\n-target_modules = { module= libatomic; lib_path=.libs; };\n+target_modules = { module= libatomic; bootstrap=true; lib_path=.libs; };\n \n // These are (some of) the make targets to be done in each subdirectory.\n // Not all; these are the ones which don't have special options.\n--- a/Makefile.in\n+++ b/Makefile.in\n@@ -1195,13 +1195,17 @@ all-target: maybe-all-target-newlib\n @if target-libgcc-no-bootstrap\n all-target: maybe-all-target-libgcc\n @endif target-libgcc-no-bootstrap\n+@if target-libbacktrace-no-bootstrap\n all-target: maybe-all-target-libbacktrace\n+@endif target-libbacktrace-no-bootstrap\n all-target: maybe-all-target-libquadmath\n all-target: maybe-all-target-libgfortran\n all-target: maybe-all-target-libobjc\n all-target: maybe-all-target-libgo\n all-target: maybe-all-target-libhsail-rt\n+@if target-libphobos-no-bootstrap\n all-target: maybe-all-target-libphobos\n+@endif target-libphobos-no-bootstrap\n all-target: maybe-all-target-libtermcap\n all-target: maybe-all-target-winsup\n all-target: maybe-all-target-libgloss\n@@ -1213,7 +1217,9 @@ all-target: maybe-all-target-libada\n all-target: maybe-all-target-libgomp\n @endif target-libgomp-no-bootstrap\n all-target: maybe-all-target-libitm\n+@if target-libatomic-no-bootstrap\n all-target: maybe-all-target-libatomic\n+@endif target-libatomic-no-bootstrap\n \n # Do a target for all the subdirectories.  A ``make do-X'' will do a\n # ``make X'' in all subdirectories (because, in general, there is a\n@@ -44252,7 +44258,6 @@ configure-target-libbacktrace: stage_cur\n @if target-libbacktrace\n maybe-configure-target-libbacktrace: configure-target-libbacktrace\n configure-target-libbacktrace: \n-\t@: $(MAKE); $(unstage)\n \t@r=`${PWD_COMMAND}`; export r; \\\n \ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n \techo \"Checking multilib configuration for libbacktrace...\"; \\\n@@ -44290,6 +44295,412 @@ configure-target-libbacktrace:\n \n \n \n+.PHONY: configure-stage1-target-libbacktrace maybe-configure-stage1-target-libbacktrace\n+maybe-configure-stage1-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-configure-stage1-target-libbacktrace: configure-stage1-target-libbacktrace\n+configure-stage1-target-libbacktrace:\n+\t@[ $(current_stage) = stage1 ] || $(MAKE) stage1-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE1_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libbacktrace...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libbacktrace/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libbacktrace/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 1 in $(TARGET_SUBDIR)/libbacktrace; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libbacktrace/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libbacktrace; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t   \\\n+\t  $(STAGE1_CONFIGURE_FLAGS)\n+@endif target-libbacktrace-bootstrap\n+\n+.PHONY: configure-stage2-target-libbacktrace maybe-configure-stage2-target-libbacktrace\n+maybe-configure-stage2-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-configure-stage2-target-libbacktrace: configure-stage2-target-libbacktrace\n+configure-stage2-target-libbacktrace:\n+\t@[ $(current_stage) = stage2 ] || $(MAKE) stage2-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE2_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libbacktrace...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libbacktrace/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libbacktrace/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 2 in $(TARGET_SUBDIR)/libbacktrace; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libbacktrace/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libbacktrace; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGE2_CONFIGURE_FLAGS)\n+@endif target-libbacktrace-bootstrap\n+\n+.PHONY: configure-stage3-target-libbacktrace maybe-configure-stage3-target-libbacktrace\n+maybe-configure-stage3-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-configure-stage3-target-libbacktrace: configure-stage3-target-libbacktrace\n+configure-stage3-target-libbacktrace:\n+\t@[ $(current_stage) = stage3 ] || $(MAKE) stage3-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE3_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libbacktrace...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libbacktrace/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libbacktrace/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 3 in $(TARGET_SUBDIR)/libbacktrace; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libbacktrace/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libbacktrace; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGE3_CONFIGURE_FLAGS)\n+@endif target-libbacktrace-bootstrap\n+\n+.PHONY: configure-stage4-target-libbacktrace maybe-configure-stage4-target-libbacktrace\n+maybe-configure-stage4-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-configure-stage4-target-libbacktrace: configure-stage4-target-libbacktrace\n+configure-stage4-target-libbacktrace:\n+\t@[ $(current_stage) = stage4 ] || $(MAKE) stage4-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE4_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libbacktrace...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libbacktrace/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libbacktrace/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 4 in $(TARGET_SUBDIR)/libbacktrace; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libbacktrace/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libbacktrace; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGE4_CONFIGURE_FLAGS)\n+@endif target-libbacktrace-bootstrap\n+\n+.PHONY: configure-stageprofile-target-libbacktrace maybe-configure-stageprofile-target-libbacktrace\n+maybe-configure-stageprofile-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-configure-stageprofile-target-libbacktrace: configure-stageprofile-target-libbacktrace\n+configure-stageprofile-target-libbacktrace:\n+\t@[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEprofile_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libbacktrace...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libbacktrace/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libbacktrace/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage profile in $(TARGET_SUBDIR)/libbacktrace; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libbacktrace/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libbacktrace; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEprofile_CONFIGURE_FLAGS)\n+@endif target-libbacktrace-bootstrap\n+\n+.PHONY: configure-stagetrain-target-libbacktrace maybe-configure-stagetrain-target-libbacktrace\n+maybe-configure-stagetrain-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-configure-stagetrain-target-libbacktrace: configure-stagetrain-target-libbacktrace\n+configure-stagetrain-target-libbacktrace:\n+\t@[ $(current_stage) = stagetrain ] || $(MAKE) stagetrain-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEtrain_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libbacktrace...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libbacktrace/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libbacktrace/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage train in $(TARGET_SUBDIR)/libbacktrace; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libbacktrace/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libbacktrace; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEtrain_CONFIGURE_FLAGS)\n+@endif target-libbacktrace-bootstrap\n+\n+.PHONY: configure-stagefeedback-target-libbacktrace maybe-configure-stagefeedback-target-libbacktrace\n+maybe-configure-stagefeedback-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-configure-stagefeedback-target-libbacktrace: configure-stagefeedback-target-libbacktrace\n+configure-stagefeedback-target-libbacktrace:\n+\t@[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEfeedback_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libbacktrace...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libbacktrace/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libbacktrace/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage feedback in $(TARGET_SUBDIR)/libbacktrace; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libbacktrace/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libbacktrace; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEfeedback_CONFIGURE_FLAGS)\n+@endif target-libbacktrace-bootstrap\n+\n+.PHONY: configure-stageautoprofile-target-libbacktrace maybe-configure-stageautoprofile-target-libbacktrace\n+maybe-configure-stageautoprofile-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-configure-stageautoprofile-target-libbacktrace: configure-stageautoprofile-target-libbacktrace\n+configure-stageautoprofile-target-libbacktrace:\n+\t@[ $(current_stage) = stageautoprofile ] || $(MAKE) stageautoprofile-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautoprofile_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libbacktrace...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libbacktrace/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libbacktrace/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage autoprofile in $(TARGET_SUBDIR)/libbacktrace; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libbacktrace/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libbacktrace; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEautoprofile_CONFIGURE_FLAGS)\n+@endif target-libbacktrace-bootstrap\n+\n+.PHONY: configure-stageautofeedback-target-libbacktrace maybe-configure-stageautofeedback-target-libbacktrace\n+maybe-configure-stageautofeedback-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-configure-stageautofeedback-target-libbacktrace: configure-stageautofeedback-target-libbacktrace\n+configure-stageautofeedback-target-libbacktrace:\n+\t@[ $(current_stage) = stageautofeedback ] || $(MAKE) stageautofeedback-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautofeedback_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libbacktrace...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libbacktrace/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libbacktrace/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libbacktrace/multilib.tmp $(TARGET_SUBDIR)/libbacktrace/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libbacktrace/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage autofeedback in $(TARGET_SUBDIR)/libbacktrace; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libbacktrace; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libbacktrace/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libbacktrace; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEautofeedback_CONFIGURE_FLAGS)\n+@endif target-libbacktrace-bootstrap\n+\n+\n+\n \n \n .PHONY: all-target-libbacktrace maybe-all-target-libbacktrace\n@@ -44301,7 +44712,6 @@ all-target-libbacktrace: stage_current\n TARGET-target-libbacktrace=all\n maybe-all-target-libbacktrace: all-target-libbacktrace\n all-target-libbacktrace: configure-target-libbacktrace\n-\t@: $(MAKE); $(unstage)\n \t@r=`${PWD_COMMAND}`; export r; \\\n \ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n \t$(NORMAL_TARGET_EXPORTS)  \\\n@@ -44312,6 +44722,387 @@ all-target-libbacktrace: configure-targe\n \n \n \n+.PHONY: all-stage1-target-libbacktrace maybe-all-stage1-target-libbacktrace\n+.PHONY: clean-stage1-target-libbacktrace maybe-clean-stage1-target-libbacktrace\n+maybe-all-stage1-target-libbacktrace:\n+maybe-clean-stage1-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-all-stage1-target-libbacktrace: all-stage1-target-libbacktrace\n+all-stage1: all-stage1-target-libbacktrace\n+TARGET-stage1-target-libbacktrace = $(TARGET-target-libbacktrace)\n+all-stage1-target-libbacktrace: configure-stage1-target-libbacktrace\n+\t@[ $(current_stage) = stage1 ] || $(MAKE) stage1-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE1_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS)  \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)  \\\n+\t\t  \\\n+\t\tTFLAGS=\"$(STAGE1_TFLAGS)\"  \\\n+\t\t$(TARGET-stage1-target-libbacktrace)\n+\n+maybe-clean-stage1-target-libbacktrace: clean-stage1-target-libbacktrace\n+clean-stage1: clean-stage1-target-libbacktrace\n+clean-stage1-target-libbacktrace:\n+\t@if [ $(current_stage) = stage1 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libbacktrace/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage1-libbacktrace/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage1-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)  \\\n+\t  clean\n+@endif target-libbacktrace-bootstrap\n+\n+\n+.PHONY: all-stage2-target-libbacktrace maybe-all-stage2-target-libbacktrace\n+.PHONY: clean-stage2-target-libbacktrace maybe-clean-stage2-target-libbacktrace\n+maybe-all-stage2-target-libbacktrace:\n+maybe-clean-stage2-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-all-stage2-target-libbacktrace: all-stage2-target-libbacktrace\n+all-stage2: all-stage2-target-libbacktrace\n+TARGET-stage2-target-libbacktrace = $(TARGET-target-libbacktrace)\n+all-stage2-target-libbacktrace: configure-stage2-target-libbacktrace\n+\t@[ $(current_stage) = stage2 ] || $(MAKE) stage2-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE2_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGE2_TFLAGS)\"  \\\n+\t\t$(TARGET-stage2-target-libbacktrace)\n+\n+maybe-clean-stage2-target-libbacktrace: clean-stage2-target-libbacktrace\n+clean-stage2: clean-stage2-target-libbacktrace\n+clean-stage2-target-libbacktrace:\n+\t@if [ $(current_stage) = stage2 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libbacktrace/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage2-libbacktrace/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage2-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libbacktrace-bootstrap\n+\n+\n+.PHONY: all-stage3-target-libbacktrace maybe-all-stage3-target-libbacktrace\n+.PHONY: clean-stage3-target-libbacktrace maybe-clean-stage3-target-libbacktrace\n+maybe-all-stage3-target-libbacktrace:\n+maybe-clean-stage3-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-all-stage3-target-libbacktrace: all-stage3-target-libbacktrace\n+all-stage3: all-stage3-target-libbacktrace\n+TARGET-stage3-target-libbacktrace = $(TARGET-target-libbacktrace)\n+all-stage3-target-libbacktrace: configure-stage3-target-libbacktrace\n+\t@[ $(current_stage) = stage3 ] || $(MAKE) stage3-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE3_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGE3_TFLAGS)\"  \\\n+\t\t$(TARGET-stage3-target-libbacktrace)\n+\n+maybe-clean-stage3-target-libbacktrace: clean-stage3-target-libbacktrace\n+clean-stage3: clean-stage3-target-libbacktrace\n+clean-stage3-target-libbacktrace:\n+\t@if [ $(current_stage) = stage3 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libbacktrace/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage3-libbacktrace/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage3-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libbacktrace-bootstrap\n+\n+\n+.PHONY: all-stage4-target-libbacktrace maybe-all-stage4-target-libbacktrace\n+.PHONY: clean-stage4-target-libbacktrace maybe-clean-stage4-target-libbacktrace\n+maybe-all-stage4-target-libbacktrace:\n+maybe-clean-stage4-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-all-stage4-target-libbacktrace: all-stage4-target-libbacktrace\n+all-stage4: all-stage4-target-libbacktrace\n+TARGET-stage4-target-libbacktrace = $(TARGET-target-libbacktrace)\n+all-stage4-target-libbacktrace: configure-stage4-target-libbacktrace\n+\t@[ $(current_stage) = stage4 ] || $(MAKE) stage4-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE4_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGE4_TFLAGS)\"  \\\n+\t\t$(TARGET-stage4-target-libbacktrace)\n+\n+maybe-clean-stage4-target-libbacktrace: clean-stage4-target-libbacktrace\n+clean-stage4: clean-stage4-target-libbacktrace\n+clean-stage4-target-libbacktrace:\n+\t@if [ $(current_stage) = stage4 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libbacktrace/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage4-libbacktrace/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage4-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libbacktrace-bootstrap\n+\n+\n+.PHONY: all-stageprofile-target-libbacktrace maybe-all-stageprofile-target-libbacktrace\n+.PHONY: clean-stageprofile-target-libbacktrace maybe-clean-stageprofile-target-libbacktrace\n+maybe-all-stageprofile-target-libbacktrace:\n+maybe-clean-stageprofile-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-all-stageprofile-target-libbacktrace: all-stageprofile-target-libbacktrace\n+all-stageprofile: all-stageprofile-target-libbacktrace\n+TARGET-stageprofile-target-libbacktrace = $(TARGET-target-libbacktrace)\n+all-stageprofile-target-libbacktrace: configure-stageprofile-target-libbacktrace\n+\t@[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEprofile_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEprofile_TFLAGS)\"  \\\n+\t\t$(TARGET-stageprofile-target-libbacktrace)\n+\n+maybe-clean-stageprofile-target-libbacktrace: clean-stageprofile-target-libbacktrace\n+clean-stageprofile: clean-stageprofile-target-libbacktrace\n+clean-stageprofile-target-libbacktrace:\n+\t@if [ $(current_stage) = stageprofile ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libbacktrace/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stageprofile-libbacktrace/Makefile ] || exit 0; \\\n+\t  $(MAKE) stageprofile-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libbacktrace-bootstrap\n+\n+\n+.PHONY: all-stagetrain-target-libbacktrace maybe-all-stagetrain-target-libbacktrace\n+.PHONY: clean-stagetrain-target-libbacktrace maybe-clean-stagetrain-target-libbacktrace\n+maybe-all-stagetrain-target-libbacktrace:\n+maybe-clean-stagetrain-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-all-stagetrain-target-libbacktrace: all-stagetrain-target-libbacktrace\n+all-stagetrain: all-stagetrain-target-libbacktrace\n+TARGET-stagetrain-target-libbacktrace = $(TARGET-target-libbacktrace)\n+all-stagetrain-target-libbacktrace: configure-stagetrain-target-libbacktrace\n+\t@[ $(current_stage) = stagetrain ] || $(MAKE) stagetrain-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEtrain_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEtrain_TFLAGS)\"  \\\n+\t\t$(TARGET-stagetrain-target-libbacktrace)\n+\n+maybe-clean-stagetrain-target-libbacktrace: clean-stagetrain-target-libbacktrace\n+clean-stagetrain: clean-stagetrain-target-libbacktrace\n+clean-stagetrain-target-libbacktrace:\n+\t@if [ $(current_stage) = stagetrain ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libbacktrace/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stagetrain-libbacktrace/Makefile ] || exit 0; \\\n+\t  $(MAKE) stagetrain-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libbacktrace-bootstrap\n+\n+\n+.PHONY: all-stagefeedback-target-libbacktrace maybe-all-stagefeedback-target-libbacktrace\n+.PHONY: clean-stagefeedback-target-libbacktrace maybe-clean-stagefeedback-target-libbacktrace\n+maybe-all-stagefeedback-target-libbacktrace:\n+maybe-clean-stagefeedback-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-all-stagefeedback-target-libbacktrace: all-stagefeedback-target-libbacktrace\n+all-stagefeedback: all-stagefeedback-target-libbacktrace\n+TARGET-stagefeedback-target-libbacktrace = $(TARGET-target-libbacktrace)\n+all-stagefeedback-target-libbacktrace: configure-stagefeedback-target-libbacktrace\n+\t@[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEfeedback_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEfeedback_TFLAGS)\"  \\\n+\t\t$(TARGET-stagefeedback-target-libbacktrace)\n+\n+maybe-clean-stagefeedback-target-libbacktrace: clean-stagefeedback-target-libbacktrace\n+clean-stagefeedback: clean-stagefeedback-target-libbacktrace\n+clean-stagefeedback-target-libbacktrace:\n+\t@if [ $(current_stage) = stagefeedback ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libbacktrace/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stagefeedback-libbacktrace/Makefile ] || exit 0; \\\n+\t  $(MAKE) stagefeedback-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libbacktrace-bootstrap\n+\n+\n+.PHONY: all-stageautoprofile-target-libbacktrace maybe-all-stageautoprofile-target-libbacktrace\n+.PHONY: clean-stageautoprofile-target-libbacktrace maybe-clean-stageautoprofile-target-libbacktrace\n+maybe-all-stageautoprofile-target-libbacktrace:\n+maybe-clean-stageautoprofile-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-all-stageautoprofile-target-libbacktrace: all-stageautoprofile-target-libbacktrace\n+all-stageautoprofile: all-stageautoprofile-target-libbacktrace\n+TARGET-stageautoprofile-target-libbacktrace = $(TARGET-target-libbacktrace)\n+all-stageautoprofile-target-libbacktrace: configure-stageautoprofile-target-libbacktrace\n+\t@[ $(current_stage) = stageautoprofile ] || $(MAKE) stageautoprofile-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautoprofile_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t$$s/gcc/config/i386/$(AUTO_PROFILE) \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEautoprofile_TFLAGS)\"  \\\n+\t\t$(TARGET-stageautoprofile-target-libbacktrace)\n+\n+maybe-clean-stageautoprofile-target-libbacktrace: clean-stageautoprofile-target-libbacktrace\n+clean-stageautoprofile: clean-stageautoprofile-target-libbacktrace\n+clean-stageautoprofile-target-libbacktrace:\n+\t@if [ $(current_stage) = stageautoprofile ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libbacktrace/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stageautoprofile-libbacktrace/Makefile ] || exit 0; \\\n+\t  $(MAKE) stageautoprofile-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libbacktrace-bootstrap\n+\n+\n+.PHONY: all-stageautofeedback-target-libbacktrace maybe-all-stageautofeedback-target-libbacktrace\n+.PHONY: clean-stageautofeedback-target-libbacktrace maybe-clean-stageautofeedback-target-libbacktrace\n+maybe-all-stageautofeedback-target-libbacktrace:\n+maybe-clean-stageautofeedback-target-libbacktrace:\n+@if target-libbacktrace-bootstrap\n+maybe-all-stageautofeedback-target-libbacktrace: all-stageautofeedback-target-libbacktrace\n+all-stageautofeedback: all-stageautofeedback-target-libbacktrace\n+TARGET-stageautofeedback-target-libbacktrace = $(TARGET-target-libbacktrace)\n+all-stageautofeedback-target-libbacktrace: configure-stageautofeedback-target-libbacktrace\n+\t@[ $(current_stage) = stageautofeedback ] || $(MAKE) stageautofeedback-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautofeedback_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEautofeedback_TFLAGS)\" PERF_DATA=perf.data \\\n+\t\t$(TARGET-stageautofeedback-target-libbacktrace)\n+\n+maybe-clean-stageautofeedback-target-libbacktrace: clean-stageautofeedback-target-libbacktrace\n+clean-stageautofeedback: clean-stageautofeedback-target-libbacktrace\n+clean-stageautofeedback-target-libbacktrace:\n+\t@if [ $(current_stage) = stageautofeedback ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libbacktrace/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stageautofeedback-libbacktrace/Makefile ] || exit 0; \\\n+\t  $(MAKE) stageautofeedback-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libbacktrace && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libbacktrace-bootstrap\n+\n+\n+\n+\n \n \n .PHONY: check-target-libbacktrace maybe-check-target-libbacktrace\n@@ -47000,7 +47791,6 @@ configure-target-libphobos: stage_curren\n @if target-libphobos\n maybe-configure-target-libphobos: configure-target-libphobos\n configure-target-libphobos: \n-\t@: $(MAKE); $(unstage)\n \t@r=`${PWD_COMMAND}`; export r; \\\n \ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n \techo \"Checking multilib configuration for libphobos...\"; \\\n@@ -47038,6 +47828,412 @@ configure-target-libphobos:\n \n \n \n+.PHONY: configure-stage1-target-libphobos maybe-configure-stage1-target-libphobos\n+maybe-configure-stage1-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-configure-stage1-target-libphobos: configure-stage1-target-libphobos\n+configure-stage1-target-libphobos:\n+\t@[ $(current_stage) = stage1 ] || $(MAKE) stage1-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE1_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libphobos...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libphobos/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libphobos/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 1 in $(TARGET_SUBDIR)/libphobos; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos; \\\n+\tcd $(TARGET_SUBDIR)/libphobos || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libphobos/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libphobos; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t   \\\n+\t  $(STAGE1_CONFIGURE_FLAGS)\n+@endif target-libphobos-bootstrap\n+\n+.PHONY: configure-stage2-target-libphobos maybe-configure-stage2-target-libphobos\n+maybe-configure-stage2-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-configure-stage2-target-libphobos: configure-stage2-target-libphobos\n+configure-stage2-target-libphobos:\n+\t@[ $(current_stage) = stage2 ] || $(MAKE) stage2-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE2_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libphobos...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libphobos/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libphobos/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 2 in $(TARGET_SUBDIR)/libphobos; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos; \\\n+\tcd $(TARGET_SUBDIR)/libphobos || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libphobos/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libphobos; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGE2_CONFIGURE_FLAGS)\n+@endif target-libphobos-bootstrap\n+\n+.PHONY: configure-stage3-target-libphobos maybe-configure-stage3-target-libphobos\n+maybe-configure-stage3-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-configure-stage3-target-libphobos: configure-stage3-target-libphobos\n+configure-stage3-target-libphobos:\n+\t@[ $(current_stage) = stage3 ] || $(MAKE) stage3-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE3_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libphobos...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libphobos/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libphobos/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 3 in $(TARGET_SUBDIR)/libphobos; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos; \\\n+\tcd $(TARGET_SUBDIR)/libphobos || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libphobos/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libphobos; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGE3_CONFIGURE_FLAGS)\n+@endif target-libphobos-bootstrap\n+\n+.PHONY: configure-stage4-target-libphobos maybe-configure-stage4-target-libphobos\n+maybe-configure-stage4-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-configure-stage4-target-libphobos: configure-stage4-target-libphobos\n+configure-stage4-target-libphobos:\n+\t@[ $(current_stage) = stage4 ] || $(MAKE) stage4-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE4_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libphobos...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libphobos/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libphobos/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 4 in $(TARGET_SUBDIR)/libphobos; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos; \\\n+\tcd $(TARGET_SUBDIR)/libphobos || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libphobos/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libphobos; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGE4_CONFIGURE_FLAGS)\n+@endif target-libphobos-bootstrap\n+\n+.PHONY: configure-stageprofile-target-libphobos maybe-configure-stageprofile-target-libphobos\n+maybe-configure-stageprofile-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-configure-stageprofile-target-libphobos: configure-stageprofile-target-libphobos\n+configure-stageprofile-target-libphobos:\n+\t@[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEprofile_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libphobos...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libphobos/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libphobos/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage profile in $(TARGET_SUBDIR)/libphobos; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos; \\\n+\tcd $(TARGET_SUBDIR)/libphobos || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libphobos/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libphobos; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEprofile_CONFIGURE_FLAGS)\n+@endif target-libphobos-bootstrap\n+\n+.PHONY: configure-stagetrain-target-libphobos maybe-configure-stagetrain-target-libphobos\n+maybe-configure-stagetrain-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-configure-stagetrain-target-libphobos: configure-stagetrain-target-libphobos\n+configure-stagetrain-target-libphobos:\n+\t@[ $(current_stage) = stagetrain ] || $(MAKE) stagetrain-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEtrain_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libphobos...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libphobos/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libphobos/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage train in $(TARGET_SUBDIR)/libphobos; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos; \\\n+\tcd $(TARGET_SUBDIR)/libphobos || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libphobos/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libphobos; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEtrain_CONFIGURE_FLAGS)\n+@endif target-libphobos-bootstrap\n+\n+.PHONY: configure-stagefeedback-target-libphobos maybe-configure-stagefeedback-target-libphobos\n+maybe-configure-stagefeedback-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-configure-stagefeedback-target-libphobos: configure-stagefeedback-target-libphobos\n+configure-stagefeedback-target-libphobos:\n+\t@[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEfeedback_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libphobos...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libphobos/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libphobos/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage feedback in $(TARGET_SUBDIR)/libphobos; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos; \\\n+\tcd $(TARGET_SUBDIR)/libphobos || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libphobos/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libphobos; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEfeedback_CONFIGURE_FLAGS)\n+@endif target-libphobos-bootstrap\n+\n+.PHONY: configure-stageautoprofile-target-libphobos maybe-configure-stageautoprofile-target-libphobos\n+maybe-configure-stageautoprofile-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-configure-stageautoprofile-target-libphobos: configure-stageautoprofile-target-libphobos\n+configure-stageautoprofile-target-libphobos:\n+\t@[ $(current_stage) = stageautoprofile ] || $(MAKE) stageautoprofile-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautoprofile_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libphobos...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libphobos/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libphobos/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage autoprofile in $(TARGET_SUBDIR)/libphobos; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos; \\\n+\tcd $(TARGET_SUBDIR)/libphobos || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libphobos/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libphobos; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEautoprofile_CONFIGURE_FLAGS)\n+@endif target-libphobos-bootstrap\n+\n+.PHONY: configure-stageautofeedback-target-libphobos maybe-configure-stageautofeedback-target-libphobos\n+maybe-configure-stageautofeedback-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-configure-stageautofeedback-target-libphobos: configure-stageautofeedback-target-libphobos\n+configure-stageautofeedback-target-libphobos:\n+\t@[ $(current_stage) = stageautofeedback ] || $(MAKE) stageautofeedback-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautofeedback_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libphobos...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libphobos/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libphobos/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libphobos/multilib.tmp $(TARGET_SUBDIR)/libphobos/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libphobos/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage autofeedback in $(TARGET_SUBDIR)/libphobos; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libphobos; \\\n+\tcd $(TARGET_SUBDIR)/libphobos || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libphobos/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libphobos; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEautofeedback_CONFIGURE_FLAGS)\n+@endif target-libphobos-bootstrap\n+\n+\n+\n \n \n .PHONY: all-target-libphobos maybe-all-target-libphobos\n@@ -47049,7 +48245,6 @@ all-target-libphobos: stage_current\n TARGET-target-libphobos=all\n maybe-all-target-libphobos: all-target-libphobos\n all-target-libphobos: configure-target-libphobos\n-\t@: $(MAKE); $(unstage)\n \t@r=`${PWD_COMMAND}`; export r; \\\n \ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n \t$(NORMAL_TARGET_EXPORTS)  \\\n@@ -47060,6 +48255,387 @@ all-target-libphobos: configure-target-l\n \n \n \n+.PHONY: all-stage1-target-libphobos maybe-all-stage1-target-libphobos\n+.PHONY: clean-stage1-target-libphobos maybe-clean-stage1-target-libphobos\n+maybe-all-stage1-target-libphobos:\n+maybe-clean-stage1-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-all-stage1-target-libphobos: all-stage1-target-libphobos\n+all-stage1: all-stage1-target-libphobos\n+TARGET-stage1-target-libphobos = $(TARGET-target-libphobos)\n+all-stage1-target-libphobos: configure-stage1-target-libphobos\n+\t@[ $(current_stage) = stage1 ] || $(MAKE) stage1-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE1_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS)  \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)  \\\n+\t\t  \\\n+\t\tTFLAGS=\"$(STAGE1_TFLAGS)\"  \\\n+\t\t$(TARGET-stage1-target-libphobos)\n+\n+maybe-clean-stage1-target-libphobos: clean-stage1-target-libphobos\n+clean-stage1: clean-stage1-target-libphobos\n+clean-stage1-target-libphobos:\n+\t@if [ $(current_stage) = stage1 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage1-libphobos/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage1-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)  \\\n+\t  clean\n+@endif target-libphobos-bootstrap\n+\n+\n+.PHONY: all-stage2-target-libphobos maybe-all-stage2-target-libphobos\n+.PHONY: clean-stage2-target-libphobos maybe-clean-stage2-target-libphobos\n+maybe-all-stage2-target-libphobos:\n+maybe-clean-stage2-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-all-stage2-target-libphobos: all-stage2-target-libphobos\n+all-stage2: all-stage2-target-libphobos\n+TARGET-stage2-target-libphobos = $(TARGET-target-libphobos)\n+all-stage2-target-libphobos: configure-stage2-target-libphobos\n+\t@[ $(current_stage) = stage2 ] || $(MAKE) stage2-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE2_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGE2_TFLAGS)\"  \\\n+\t\t$(TARGET-stage2-target-libphobos)\n+\n+maybe-clean-stage2-target-libphobos: clean-stage2-target-libphobos\n+clean-stage2: clean-stage2-target-libphobos\n+clean-stage2-target-libphobos:\n+\t@if [ $(current_stage) = stage2 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage2-libphobos/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage2-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libphobos-bootstrap\n+\n+\n+.PHONY: all-stage3-target-libphobos maybe-all-stage3-target-libphobos\n+.PHONY: clean-stage3-target-libphobos maybe-clean-stage3-target-libphobos\n+maybe-all-stage3-target-libphobos:\n+maybe-clean-stage3-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-all-stage3-target-libphobos: all-stage3-target-libphobos\n+all-stage3: all-stage3-target-libphobos\n+TARGET-stage3-target-libphobos = $(TARGET-target-libphobos)\n+all-stage3-target-libphobos: configure-stage3-target-libphobos\n+\t@[ $(current_stage) = stage3 ] || $(MAKE) stage3-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE3_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGE3_TFLAGS)\"  \\\n+\t\t$(TARGET-stage3-target-libphobos)\n+\n+maybe-clean-stage3-target-libphobos: clean-stage3-target-libphobos\n+clean-stage3: clean-stage3-target-libphobos\n+clean-stage3-target-libphobos:\n+\t@if [ $(current_stage) = stage3 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage3-libphobos/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage3-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libphobos-bootstrap\n+\n+\n+.PHONY: all-stage4-target-libphobos maybe-all-stage4-target-libphobos\n+.PHONY: clean-stage4-target-libphobos maybe-clean-stage4-target-libphobos\n+maybe-all-stage4-target-libphobos:\n+maybe-clean-stage4-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-all-stage4-target-libphobos: all-stage4-target-libphobos\n+all-stage4: all-stage4-target-libphobos\n+TARGET-stage4-target-libphobos = $(TARGET-target-libphobos)\n+all-stage4-target-libphobos: configure-stage4-target-libphobos\n+\t@[ $(current_stage) = stage4 ] || $(MAKE) stage4-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE4_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGE4_TFLAGS)\"  \\\n+\t\t$(TARGET-stage4-target-libphobos)\n+\n+maybe-clean-stage4-target-libphobos: clean-stage4-target-libphobos\n+clean-stage4: clean-stage4-target-libphobos\n+clean-stage4-target-libphobos:\n+\t@if [ $(current_stage) = stage4 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage4-libphobos/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage4-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libphobos-bootstrap\n+\n+\n+.PHONY: all-stageprofile-target-libphobos maybe-all-stageprofile-target-libphobos\n+.PHONY: clean-stageprofile-target-libphobos maybe-clean-stageprofile-target-libphobos\n+maybe-all-stageprofile-target-libphobos:\n+maybe-clean-stageprofile-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-all-stageprofile-target-libphobos: all-stageprofile-target-libphobos\n+all-stageprofile: all-stageprofile-target-libphobos\n+TARGET-stageprofile-target-libphobos = $(TARGET-target-libphobos)\n+all-stageprofile-target-libphobos: configure-stageprofile-target-libphobos\n+\t@[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEprofile_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEprofile_TFLAGS)\"  \\\n+\t\t$(TARGET-stageprofile-target-libphobos)\n+\n+maybe-clean-stageprofile-target-libphobos: clean-stageprofile-target-libphobos\n+clean-stageprofile: clean-stageprofile-target-libphobos\n+clean-stageprofile-target-libphobos:\n+\t@if [ $(current_stage) = stageprofile ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stageprofile-libphobos/Makefile ] || exit 0; \\\n+\t  $(MAKE) stageprofile-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libphobos-bootstrap\n+\n+\n+.PHONY: all-stagetrain-target-libphobos maybe-all-stagetrain-target-libphobos\n+.PHONY: clean-stagetrain-target-libphobos maybe-clean-stagetrain-target-libphobos\n+maybe-all-stagetrain-target-libphobos:\n+maybe-clean-stagetrain-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-all-stagetrain-target-libphobos: all-stagetrain-target-libphobos\n+all-stagetrain: all-stagetrain-target-libphobos\n+TARGET-stagetrain-target-libphobos = $(TARGET-target-libphobos)\n+all-stagetrain-target-libphobos: configure-stagetrain-target-libphobos\n+\t@[ $(current_stage) = stagetrain ] || $(MAKE) stagetrain-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEtrain_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEtrain_TFLAGS)\"  \\\n+\t\t$(TARGET-stagetrain-target-libphobos)\n+\n+maybe-clean-stagetrain-target-libphobos: clean-stagetrain-target-libphobos\n+clean-stagetrain: clean-stagetrain-target-libphobos\n+clean-stagetrain-target-libphobos:\n+\t@if [ $(current_stage) = stagetrain ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stagetrain-libphobos/Makefile ] || exit 0; \\\n+\t  $(MAKE) stagetrain-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libphobos-bootstrap\n+\n+\n+.PHONY: all-stagefeedback-target-libphobos maybe-all-stagefeedback-target-libphobos\n+.PHONY: clean-stagefeedback-target-libphobos maybe-clean-stagefeedback-target-libphobos\n+maybe-all-stagefeedback-target-libphobos:\n+maybe-clean-stagefeedback-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-all-stagefeedback-target-libphobos: all-stagefeedback-target-libphobos\n+all-stagefeedback: all-stagefeedback-target-libphobos\n+TARGET-stagefeedback-target-libphobos = $(TARGET-target-libphobos)\n+all-stagefeedback-target-libphobos: configure-stagefeedback-target-libphobos\n+\t@[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEfeedback_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEfeedback_TFLAGS)\"  \\\n+\t\t$(TARGET-stagefeedback-target-libphobos)\n+\n+maybe-clean-stagefeedback-target-libphobos: clean-stagefeedback-target-libphobos\n+clean-stagefeedback: clean-stagefeedback-target-libphobos\n+clean-stagefeedback-target-libphobos:\n+\t@if [ $(current_stage) = stagefeedback ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stagefeedback-libphobos/Makefile ] || exit 0; \\\n+\t  $(MAKE) stagefeedback-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libphobos-bootstrap\n+\n+\n+.PHONY: all-stageautoprofile-target-libphobos maybe-all-stageautoprofile-target-libphobos\n+.PHONY: clean-stageautoprofile-target-libphobos maybe-clean-stageautoprofile-target-libphobos\n+maybe-all-stageautoprofile-target-libphobos:\n+maybe-clean-stageautoprofile-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-all-stageautoprofile-target-libphobos: all-stageautoprofile-target-libphobos\n+all-stageautoprofile: all-stageautoprofile-target-libphobos\n+TARGET-stageautoprofile-target-libphobos = $(TARGET-target-libphobos)\n+all-stageautoprofile-target-libphobos: configure-stageautoprofile-target-libphobos\n+\t@[ $(current_stage) = stageautoprofile ] || $(MAKE) stageautoprofile-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautoprofile_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t$$s/gcc/config/i386/$(AUTO_PROFILE) \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEautoprofile_TFLAGS)\"  \\\n+\t\t$(TARGET-stageautoprofile-target-libphobos)\n+\n+maybe-clean-stageautoprofile-target-libphobos: clean-stageautoprofile-target-libphobos\n+clean-stageautoprofile: clean-stageautoprofile-target-libphobos\n+clean-stageautoprofile-target-libphobos:\n+\t@if [ $(current_stage) = stageautoprofile ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stageautoprofile-libphobos/Makefile ] || exit 0; \\\n+\t  $(MAKE) stageautoprofile-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libphobos-bootstrap\n+\n+\n+.PHONY: all-stageautofeedback-target-libphobos maybe-all-stageautofeedback-target-libphobos\n+.PHONY: clean-stageautofeedback-target-libphobos maybe-clean-stageautofeedback-target-libphobos\n+maybe-all-stageautofeedback-target-libphobos:\n+maybe-clean-stageautofeedback-target-libphobos:\n+@if target-libphobos-bootstrap\n+maybe-all-stageautofeedback-target-libphobos: all-stageautofeedback-target-libphobos\n+all-stageautofeedback: all-stageautofeedback-target-libphobos\n+TARGET-stageautofeedback-target-libphobos = $(TARGET-target-libphobos)\n+all-stageautofeedback-target-libphobos: configure-stageautofeedback-target-libphobos\n+\t@[ $(current_stage) = stageautofeedback ] || $(MAKE) stageautofeedback-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautofeedback_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEautofeedback_TFLAGS)\" PERF_DATA=perf.data \\\n+\t\t$(TARGET-stageautofeedback-target-libphobos)\n+\n+maybe-clean-stageautofeedback-target-libphobos: clean-stageautofeedback-target-libphobos\n+clean-stageautofeedback: clean-stageautofeedback-target-libphobos\n+clean-stageautofeedback-target-libphobos:\n+\t@if [ $(current_stage) = stageautofeedback ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libphobos/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stageautofeedback-libphobos/Makefile ] || exit 0; \\\n+\t  $(MAKE) stageautofeedback-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libphobos && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libphobos-bootstrap\n+\n+\n+\n+\n \n \n .PHONY: check-target-libphobos maybe-check-target-libphobos\n@@ -52285,7 +53861,6 @@ configure-target-libatomic: stage_curren\n @if target-libatomic\n maybe-configure-target-libatomic: configure-target-libatomic\n configure-target-libatomic: \n-\t@: $(MAKE); $(unstage)\n \t@r=`${PWD_COMMAND}`; export r; \\\n \ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n \techo \"Checking multilib configuration for libatomic...\"; \\\n@@ -52323,6 +53898,412 @@ configure-target-libatomic:\n \n \n \n+.PHONY: configure-stage1-target-libatomic maybe-configure-stage1-target-libatomic\n+maybe-configure-stage1-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-configure-stage1-target-libatomic: configure-stage1-target-libatomic\n+configure-stage1-target-libatomic:\n+\t@[ $(current_stage) = stage1 ] || $(MAKE) stage1-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE1_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libatomic...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libatomic/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libatomic/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 1 in $(TARGET_SUBDIR)/libatomic; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic; \\\n+\tcd $(TARGET_SUBDIR)/libatomic || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libatomic/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libatomic; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t   \\\n+\t  $(STAGE1_CONFIGURE_FLAGS)\n+@endif target-libatomic-bootstrap\n+\n+.PHONY: configure-stage2-target-libatomic maybe-configure-stage2-target-libatomic\n+maybe-configure-stage2-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-configure-stage2-target-libatomic: configure-stage2-target-libatomic\n+configure-stage2-target-libatomic:\n+\t@[ $(current_stage) = stage2 ] || $(MAKE) stage2-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE2_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libatomic...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libatomic/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libatomic/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 2 in $(TARGET_SUBDIR)/libatomic; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic; \\\n+\tcd $(TARGET_SUBDIR)/libatomic || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libatomic/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libatomic; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGE2_CONFIGURE_FLAGS)\n+@endif target-libatomic-bootstrap\n+\n+.PHONY: configure-stage3-target-libatomic maybe-configure-stage3-target-libatomic\n+maybe-configure-stage3-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-configure-stage3-target-libatomic: configure-stage3-target-libatomic\n+configure-stage3-target-libatomic:\n+\t@[ $(current_stage) = stage3 ] || $(MAKE) stage3-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE3_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libatomic...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libatomic/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libatomic/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 3 in $(TARGET_SUBDIR)/libatomic; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic; \\\n+\tcd $(TARGET_SUBDIR)/libatomic || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libatomic/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libatomic; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGE3_CONFIGURE_FLAGS)\n+@endif target-libatomic-bootstrap\n+\n+.PHONY: configure-stage4-target-libatomic maybe-configure-stage4-target-libatomic\n+maybe-configure-stage4-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-configure-stage4-target-libatomic: configure-stage4-target-libatomic\n+configure-stage4-target-libatomic:\n+\t@[ $(current_stage) = stage4 ] || $(MAKE) stage4-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE4_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libatomic...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libatomic/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libatomic/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage 4 in $(TARGET_SUBDIR)/libatomic; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic; \\\n+\tcd $(TARGET_SUBDIR)/libatomic || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libatomic/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libatomic; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGE4_CONFIGURE_FLAGS)\n+@endif target-libatomic-bootstrap\n+\n+.PHONY: configure-stageprofile-target-libatomic maybe-configure-stageprofile-target-libatomic\n+maybe-configure-stageprofile-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-configure-stageprofile-target-libatomic: configure-stageprofile-target-libatomic\n+configure-stageprofile-target-libatomic:\n+\t@[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEprofile_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libatomic...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libatomic/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libatomic/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage profile in $(TARGET_SUBDIR)/libatomic; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic; \\\n+\tcd $(TARGET_SUBDIR)/libatomic || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libatomic/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libatomic; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEprofile_CONFIGURE_FLAGS)\n+@endif target-libatomic-bootstrap\n+\n+.PHONY: configure-stagetrain-target-libatomic maybe-configure-stagetrain-target-libatomic\n+maybe-configure-stagetrain-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-configure-stagetrain-target-libatomic: configure-stagetrain-target-libatomic\n+configure-stagetrain-target-libatomic:\n+\t@[ $(current_stage) = stagetrain ] || $(MAKE) stagetrain-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEtrain_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libatomic...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libatomic/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libatomic/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage train in $(TARGET_SUBDIR)/libatomic; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic; \\\n+\tcd $(TARGET_SUBDIR)/libatomic || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libatomic/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libatomic; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEtrain_CONFIGURE_FLAGS)\n+@endif target-libatomic-bootstrap\n+\n+.PHONY: configure-stagefeedback-target-libatomic maybe-configure-stagefeedback-target-libatomic\n+maybe-configure-stagefeedback-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-configure-stagefeedback-target-libatomic: configure-stagefeedback-target-libatomic\n+configure-stagefeedback-target-libatomic:\n+\t@[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEfeedback_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libatomic...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libatomic/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libatomic/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage feedback in $(TARGET_SUBDIR)/libatomic; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic; \\\n+\tcd $(TARGET_SUBDIR)/libatomic || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libatomic/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libatomic; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEfeedback_CONFIGURE_FLAGS)\n+@endif target-libatomic-bootstrap\n+\n+.PHONY: configure-stageautoprofile-target-libatomic maybe-configure-stageautoprofile-target-libatomic\n+maybe-configure-stageautoprofile-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-configure-stageautoprofile-target-libatomic: configure-stageautoprofile-target-libatomic\n+configure-stageautoprofile-target-libatomic:\n+\t@[ $(current_stage) = stageautoprofile ] || $(MAKE) stageautoprofile-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautoprofile_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libatomic...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libatomic/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libatomic/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage autoprofile in $(TARGET_SUBDIR)/libatomic; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic; \\\n+\tcd $(TARGET_SUBDIR)/libatomic || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libatomic/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libatomic; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEautoprofile_CONFIGURE_FLAGS)\n+@endif target-libatomic-bootstrap\n+\n+.PHONY: configure-stageautofeedback-target-libatomic maybe-configure-stageautofeedback-target-libatomic\n+maybe-configure-stageautofeedback-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-configure-stageautofeedback-target-libatomic: configure-stageautofeedback-target-libatomic\n+configure-stageautofeedback-target-libatomic:\n+\t@[ $(current_stage) = stageautofeedback ] || $(MAKE) stageautofeedback-start\n+\t@$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautofeedback_TFLAGS)\"; \\\n+\techo \"Checking multilib configuration for libatomic...\"; \\\n+\t$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libatomic/multilib.tmp 2> /dev/null; \\\n+\tif test -r $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t  if cmp -s $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; then \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/multilib.tmp; \\\n+\t  else \\\n+\t    rm -f $(TARGET_SUBDIR)/libatomic/Makefile; \\\n+\t    mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\t  fi; \\\n+\telse \\\n+\t  mv $(TARGET_SUBDIR)/libatomic/multilib.tmp $(TARGET_SUBDIR)/libatomic/multilib.out; \\\n+\tfi; \\\n+\ttest ! -f $(TARGET_SUBDIR)/libatomic/Makefile || exit 0; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t \\\n+\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\"; export CFLAGS; \\\n+\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\"; export CXXFLAGS; \\\n+\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\"; export LIBCFLAGS;  \\\n+\techo Configuring stage autofeedback in $(TARGET_SUBDIR)/libatomic; \\\n+\t$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libatomic; \\\n+\tcd $(TARGET_SUBDIR)/libatomic || exit 1; \\\n+\tcase $(srcdir) in \\\n+\t  /* | [A-Za-z]:[\\\\/]*) topdir=$(srcdir) ;; \\\n+\t  *) topdir=`echo $(TARGET_SUBDIR)/libatomic/ | \\\n+\t\tsed -e 's,\\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \\\n+\tesac; \\\n+\tmodule_srcdir=libatomic; \\\n+\t$(SHELL) $$s/$$module_srcdir/configure \\\n+\t  --srcdir=$${topdir}/$$module_srcdir \\\n+\t  $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \\\n+\t  --target=${target_alias} \\\n+\t  --with-build-libsubdir=$(HOST_SUBDIR) \\\n+\t  $(STAGEautofeedback_CONFIGURE_FLAGS)\n+@endif target-libatomic-bootstrap\n+\n+\n+\n \n \n .PHONY: all-target-libatomic maybe-all-target-libatomic\n@@ -52334,7 +54315,6 @@ all-target-libatomic: stage_current\n TARGET-target-libatomic=all\n maybe-all-target-libatomic: all-target-libatomic\n all-target-libatomic: configure-target-libatomic\n-\t@: $(MAKE); $(unstage)\n \t@r=`${PWD_COMMAND}`; export r; \\\n \ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n \t$(NORMAL_TARGET_EXPORTS)  \\\n@@ -52345,6 +54325,387 @@ all-target-libatomic: configure-target-l\n \n \n \n+.PHONY: all-stage1-target-libatomic maybe-all-stage1-target-libatomic\n+.PHONY: clean-stage1-target-libatomic maybe-clean-stage1-target-libatomic\n+maybe-all-stage1-target-libatomic:\n+maybe-clean-stage1-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-all-stage1-target-libatomic: all-stage1-target-libatomic\n+all-stage1: all-stage1-target-libatomic\n+TARGET-stage1-target-libatomic = $(TARGET-target-libatomic)\n+all-stage1-target-libatomic: configure-stage1-target-libatomic\n+\t@[ $(current_stage) = stage1 ] || $(MAKE) stage1-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE1_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS)  \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)  \\\n+\t\t  \\\n+\t\tTFLAGS=\"$(STAGE1_TFLAGS)\"  \\\n+\t\t$(TARGET-stage1-target-libatomic)\n+\n+maybe-clean-stage1-target-libatomic: clean-stage1-target-libatomic\n+clean-stage1: clean-stage1-target-libatomic\n+clean-stage1-target-libatomic:\n+\t@if [ $(current_stage) = stage1 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libatomic/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage1-libatomic/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage1-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)  \\\n+\t  clean\n+@endif target-libatomic-bootstrap\n+\n+\n+.PHONY: all-stage2-target-libatomic maybe-all-stage2-target-libatomic\n+.PHONY: clean-stage2-target-libatomic maybe-clean-stage2-target-libatomic\n+maybe-all-stage2-target-libatomic:\n+maybe-clean-stage2-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-all-stage2-target-libatomic: all-stage2-target-libatomic\n+all-stage2: all-stage2-target-libatomic\n+TARGET-stage2-target-libatomic = $(TARGET-target-libatomic)\n+all-stage2-target-libatomic: configure-stage2-target-libatomic\n+\t@[ $(current_stage) = stage2 ] || $(MAKE) stage2-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE2_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGE2_TFLAGS)\"  \\\n+\t\t$(TARGET-stage2-target-libatomic)\n+\n+maybe-clean-stage2-target-libatomic: clean-stage2-target-libatomic\n+clean-stage2: clean-stage2-target-libatomic\n+clean-stage2-target-libatomic:\n+\t@if [ $(current_stage) = stage2 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libatomic/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage2-libatomic/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage2-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libatomic-bootstrap\n+\n+\n+.PHONY: all-stage3-target-libatomic maybe-all-stage3-target-libatomic\n+.PHONY: clean-stage3-target-libatomic maybe-clean-stage3-target-libatomic\n+maybe-all-stage3-target-libatomic:\n+maybe-clean-stage3-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-all-stage3-target-libatomic: all-stage3-target-libatomic\n+all-stage3: all-stage3-target-libatomic\n+TARGET-stage3-target-libatomic = $(TARGET-target-libatomic)\n+all-stage3-target-libatomic: configure-stage3-target-libatomic\n+\t@[ $(current_stage) = stage3 ] || $(MAKE) stage3-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE3_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGE3_TFLAGS)\"  \\\n+\t\t$(TARGET-stage3-target-libatomic)\n+\n+maybe-clean-stage3-target-libatomic: clean-stage3-target-libatomic\n+clean-stage3: clean-stage3-target-libatomic\n+clean-stage3-target-libatomic:\n+\t@if [ $(current_stage) = stage3 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libatomic/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage3-libatomic/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage3-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libatomic-bootstrap\n+\n+\n+.PHONY: all-stage4-target-libatomic maybe-all-stage4-target-libatomic\n+.PHONY: clean-stage4-target-libatomic maybe-clean-stage4-target-libatomic\n+maybe-all-stage4-target-libatomic:\n+maybe-clean-stage4-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-all-stage4-target-libatomic: all-stage4-target-libatomic\n+all-stage4: all-stage4-target-libatomic\n+TARGET-stage4-target-libatomic = $(TARGET-target-libatomic)\n+all-stage4-target-libatomic: configure-stage4-target-libatomic\n+\t@[ $(current_stage) = stage4 ] || $(MAKE) stage4-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGE4_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGE4_TFLAGS)\"  \\\n+\t\t$(TARGET-stage4-target-libatomic)\n+\n+maybe-clean-stage4-target-libatomic: clean-stage4-target-libatomic\n+clean-stage4: clean-stage4-target-libatomic\n+clean-stage4-target-libatomic:\n+\t@if [ $(current_stage) = stage4 ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libatomic/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stage4-libatomic/Makefile ] || exit 0; \\\n+\t  $(MAKE) stage4-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libatomic-bootstrap\n+\n+\n+.PHONY: all-stageprofile-target-libatomic maybe-all-stageprofile-target-libatomic\n+.PHONY: clean-stageprofile-target-libatomic maybe-clean-stageprofile-target-libatomic\n+maybe-all-stageprofile-target-libatomic:\n+maybe-clean-stageprofile-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-all-stageprofile-target-libatomic: all-stageprofile-target-libatomic\n+all-stageprofile: all-stageprofile-target-libatomic\n+TARGET-stageprofile-target-libatomic = $(TARGET-target-libatomic)\n+all-stageprofile-target-libatomic: configure-stageprofile-target-libatomic\n+\t@[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEprofile_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEprofile_TFLAGS)\"  \\\n+\t\t$(TARGET-stageprofile-target-libatomic)\n+\n+maybe-clean-stageprofile-target-libatomic: clean-stageprofile-target-libatomic\n+clean-stageprofile: clean-stageprofile-target-libatomic\n+clean-stageprofile-target-libatomic:\n+\t@if [ $(current_stage) = stageprofile ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libatomic/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stageprofile-libatomic/Makefile ] || exit 0; \\\n+\t  $(MAKE) stageprofile-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libatomic-bootstrap\n+\n+\n+.PHONY: all-stagetrain-target-libatomic maybe-all-stagetrain-target-libatomic\n+.PHONY: clean-stagetrain-target-libatomic maybe-clean-stagetrain-target-libatomic\n+maybe-all-stagetrain-target-libatomic:\n+maybe-clean-stagetrain-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-all-stagetrain-target-libatomic: all-stagetrain-target-libatomic\n+all-stagetrain: all-stagetrain-target-libatomic\n+TARGET-stagetrain-target-libatomic = $(TARGET-target-libatomic)\n+all-stagetrain-target-libatomic: configure-stagetrain-target-libatomic\n+\t@[ $(current_stage) = stagetrain ] || $(MAKE) stagetrain-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEtrain_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEtrain_TFLAGS)\"  \\\n+\t\t$(TARGET-stagetrain-target-libatomic)\n+\n+maybe-clean-stagetrain-target-libatomic: clean-stagetrain-target-libatomic\n+clean-stagetrain: clean-stagetrain-target-libatomic\n+clean-stagetrain-target-libatomic:\n+\t@if [ $(current_stage) = stagetrain ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libatomic/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stagetrain-libatomic/Makefile ] || exit 0; \\\n+\t  $(MAKE) stagetrain-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libatomic-bootstrap\n+\n+\n+.PHONY: all-stagefeedback-target-libatomic maybe-all-stagefeedback-target-libatomic\n+.PHONY: clean-stagefeedback-target-libatomic maybe-clean-stagefeedback-target-libatomic\n+maybe-all-stagefeedback-target-libatomic:\n+maybe-clean-stagefeedback-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-all-stagefeedback-target-libatomic: all-stagefeedback-target-libatomic\n+all-stagefeedback: all-stagefeedback-target-libatomic\n+TARGET-stagefeedback-target-libatomic = $(TARGET-target-libatomic)\n+all-stagefeedback-target-libatomic: configure-stagefeedback-target-libatomic\n+\t@[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEfeedback_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEfeedback_TFLAGS)\"  \\\n+\t\t$(TARGET-stagefeedback-target-libatomic)\n+\n+maybe-clean-stagefeedback-target-libatomic: clean-stagefeedback-target-libatomic\n+clean-stagefeedback: clean-stagefeedback-target-libatomic\n+clean-stagefeedback-target-libatomic:\n+\t@if [ $(current_stage) = stagefeedback ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libatomic/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stagefeedback-libatomic/Makefile ] || exit 0; \\\n+\t  $(MAKE) stagefeedback-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libatomic-bootstrap\n+\n+\n+.PHONY: all-stageautoprofile-target-libatomic maybe-all-stageautoprofile-target-libatomic\n+.PHONY: clean-stageautoprofile-target-libatomic maybe-clean-stageautoprofile-target-libatomic\n+maybe-all-stageautoprofile-target-libatomic:\n+maybe-clean-stageautoprofile-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-all-stageautoprofile-target-libatomic: all-stageautoprofile-target-libatomic\n+all-stageautoprofile: all-stageautoprofile-target-libatomic\n+TARGET-stageautoprofile-target-libatomic = $(TARGET-target-libatomic)\n+all-stageautoprofile-target-libatomic: configure-stageautoprofile-target-libatomic\n+\t@[ $(current_stage) = stageautoprofile ] || $(MAKE) stageautoprofile-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautoprofile_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t$$s/gcc/config/i386/$(AUTO_PROFILE) \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEautoprofile_TFLAGS)\"  \\\n+\t\t$(TARGET-stageautoprofile-target-libatomic)\n+\n+maybe-clean-stageautoprofile-target-libatomic: clean-stageautoprofile-target-libatomic\n+clean-stageautoprofile: clean-stageautoprofile-target-libatomic\n+clean-stageautoprofile-target-libatomic:\n+\t@if [ $(current_stage) = stageautoprofile ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libatomic/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stageautoprofile-libatomic/Makefile ] || exit 0; \\\n+\t  $(MAKE) stageautoprofile-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libatomic-bootstrap\n+\n+\n+.PHONY: all-stageautofeedback-target-libatomic maybe-all-stageautofeedback-target-libatomic\n+.PHONY: clean-stageautofeedback-target-libatomic maybe-clean-stageautofeedback-target-libatomic\n+maybe-all-stageautofeedback-target-libatomic:\n+maybe-clean-stageautofeedback-target-libatomic:\n+@if target-libatomic-bootstrap\n+maybe-all-stageautofeedback-target-libatomic: all-stageautofeedback-target-libatomic\n+all-stageautofeedback: all-stageautofeedback-target-libatomic\n+TARGET-stageautofeedback-target-libatomic = $(TARGET-target-libatomic)\n+all-stageautofeedback-target-libatomic: configure-stageautofeedback-target-libatomic\n+\t@[ $(current_stage) = stageautofeedback ] || $(MAKE) stageautofeedback-start\n+\t@r=`${PWD_COMMAND}`; export r; \\\n+\ts=`cd $(srcdir); ${PWD_COMMAND}`; export s; \\\n+\tTFLAGS=\"$(STAGEautofeedback_TFLAGS)\"; \\\n+\t$(NORMAL_TARGET_EXPORTS) \\\n+\t  \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t \\\n+\t$(MAKE) $(BASE_FLAGS_TO_PASS) \\\n+\t\tCFLAGS=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\tCFLAGS_FOR_TARGET=\"$(CFLAGS_FOR_TARGET)\" \\\n+\t\tCXXFLAGS_FOR_TARGET=\"$(CXXFLAGS_FOR_TARGET)\" \\\n+\t\tLIBCFLAGS_FOR_TARGET=\"$(LIBCFLAGS_FOR_TARGET)\" \\\n+\t\t$(EXTRA_TARGET_FLAGS)   \\\n+\t\tTFLAGS=\"$(STAGEautofeedback_TFLAGS)\" PERF_DATA=perf.data \\\n+\t\t$(TARGET-stageautofeedback-target-libatomic)\n+\n+maybe-clean-stageautofeedback-target-libatomic: clean-stageautofeedback-target-libatomic\n+clean-stageautofeedback: clean-stageautofeedback-target-libatomic\n+clean-stageautofeedback-target-libatomic:\n+\t@if [ $(current_stage) = stageautofeedback ]; then \\\n+\t  [ -f $(TARGET_SUBDIR)/libatomic/Makefile ] || exit 0; \\\n+\telse \\\n+\t  [ -f $(TARGET_SUBDIR)/stageautofeedback-libatomic/Makefile ] || exit 0; \\\n+\t  $(MAKE) stageautofeedback-start; \\\n+\tfi; \\\n+\tcd $(TARGET_SUBDIR)/libatomic && \\\n+\t$(MAKE) $(EXTRA_TARGET_FLAGS)   clean\n+@endif target-libatomic-bootstrap\n+\n+\n+\n+\n \n \n .PHONY: check-target-libatomic maybe-check-target-libatomic\n@@ -56029,13 +58390,29 @@ configure-stagetrain-target-libgcc: mayb\n configure-stagefeedback-target-libgcc: maybe-all-stagefeedback-gcc\n configure-stageautoprofile-target-libgcc: maybe-all-stageautoprofile-gcc\n configure-stageautofeedback-target-libgcc: maybe-all-stageautofeedback-gcc\n-configure-target-libbacktrace: stage_last\n+configure-stage1-target-libbacktrace: maybe-all-stage1-gcc\n+configure-stage2-target-libbacktrace: maybe-all-stage2-gcc\n+configure-stage3-target-libbacktrace: maybe-all-stage3-gcc\n+configure-stage4-target-libbacktrace: maybe-all-stage4-gcc\n+configure-stageprofile-target-libbacktrace: maybe-all-stageprofile-gcc\n+configure-stagetrain-target-libbacktrace: maybe-all-stagetrain-gcc\n+configure-stagefeedback-target-libbacktrace: maybe-all-stagefeedback-gcc\n+configure-stageautoprofile-target-libbacktrace: maybe-all-stageautoprofile-gcc\n+configure-stageautofeedback-target-libbacktrace: maybe-all-stageautofeedback-gcc\n configure-target-libquadmath: stage_last\n configure-target-libgfortran: stage_last\n configure-target-libobjc: stage_last\n configure-target-libgo: stage_last\n configure-target-libhsail-rt: stage_last\n-configure-target-libphobos: stage_last\n+configure-stage1-target-libphobos: maybe-all-stage1-gcc\n+configure-stage2-target-libphobos: maybe-all-stage2-gcc\n+configure-stage3-target-libphobos: maybe-all-stage3-gcc\n+configure-stage4-target-libphobos: maybe-all-stage4-gcc\n+configure-stageprofile-target-libphobos: maybe-all-stageprofile-gcc\n+configure-stagetrain-target-libphobos: maybe-all-stagetrain-gcc\n+configure-stagefeedback-target-libphobos: maybe-all-stagefeedback-gcc\n+configure-stageautoprofile-target-libphobos: maybe-all-stageautoprofile-gcc\n+configure-stageautofeedback-target-libphobos: maybe-all-stageautofeedback-gcc\n configure-target-libtermcap: stage_last\n configure-target-winsup: stage_last\n configure-target-libgloss: stage_last\n@@ -56053,7 +58430,15 @@ configure-stagefeedback-target-libgomp:\n configure-stageautoprofile-target-libgomp: maybe-all-stageautoprofile-gcc\n configure-stageautofeedback-target-libgomp: maybe-all-stageautofeedback-gcc\n configure-target-libitm: stage_last\n-configure-target-libatomic: stage_last\n+configure-stage1-target-libatomic: maybe-all-stage1-gcc\n+configure-stage2-target-libatomic: maybe-all-stage2-gcc\n+configure-stage3-target-libatomic: maybe-all-stage3-gcc\n+configure-stage4-target-libatomic: maybe-all-stage4-gcc\n+configure-stageprofile-target-libatomic: maybe-all-stageprofile-gcc\n+configure-stagetrain-target-libatomic: maybe-all-stagetrain-gcc\n+configure-stagefeedback-target-libatomic: maybe-all-stagefeedback-gcc\n+configure-stageautoprofile-target-libatomic: maybe-all-stageautoprofile-gcc\n+configure-stageautofeedback-target-libatomic: maybe-all-stageautofeedback-gcc\n @endif gcc-bootstrap\n \n @if gcc-no-bootstrap\n@@ -57063,14 +59448,39 @@ all-m4: maybe-all-build-texinfo\n configure-target-fastjar: maybe-configure-target-zlib\n all-target-fastjar: maybe-all-target-zlib\n configure-target-libgo: maybe-configure-target-libffi\n-all-target-libgo: maybe-all-target-libbacktrace\n all-target-libgo: maybe-all-target-libffi\n-all-target-libgo: maybe-all-target-libatomic\n configure-target-libphobos: maybe-configure-target-libbacktrace\n+configure-stage1-target-libphobos: maybe-configure-stage1-target-libbacktrace\n+configure-stage2-target-libphobos: maybe-configure-stage2-target-libbacktrace\n+configure-stage3-target-libphobos: maybe-configure-stage3-target-libbacktrace\n+configure-stage4-target-libphobos: maybe-configure-stage4-target-libbacktrace\n+configure-stageprofile-target-libphobos: maybe-configure-stageprofile-target-libbacktrace\n+configure-stagetrain-target-libphobos: maybe-configure-stagetrain-target-libbacktrace\n+configure-stagefeedback-target-libphobos: maybe-configure-stagefeedback-target-libbacktrace\n+configure-stageautoprofile-target-libphobos: maybe-configure-stageautoprofile-target-libbacktrace\n+configure-stageautofeedback-target-libphobos: maybe-configure-stageautofeedback-target-libbacktrace\n configure-target-libphobos: maybe-configure-target-zlib\n all-target-libphobos: maybe-all-target-libbacktrace\n+all-stage1-target-libphobos: maybe-all-stage1-target-libbacktrace\n+all-stage2-target-libphobos: maybe-all-stage2-target-libbacktrace\n+all-stage3-target-libphobos: maybe-all-stage3-target-libbacktrace\n+all-stage4-target-libphobos: maybe-all-stage4-target-libbacktrace\n+all-stageprofile-target-libphobos: maybe-all-stageprofile-target-libbacktrace\n+all-stagetrain-target-libphobos: maybe-all-stagetrain-target-libbacktrace\n+all-stagefeedback-target-libphobos: maybe-all-stagefeedback-target-libbacktrace\n+all-stageautoprofile-target-libphobos: maybe-all-stageautoprofile-target-libbacktrace\n+all-stageautofeedback-target-libphobos: maybe-all-stageautofeedback-target-libbacktrace\n all-target-libphobos: maybe-all-target-zlib\n all-target-libphobos: maybe-all-target-libatomic\n+all-stage1-target-libphobos: maybe-all-stage1-target-libatomic\n+all-stage2-target-libphobos: maybe-all-stage2-target-libatomic\n+all-stage3-target-libphobos: maybe-all-stage3-target-libatomic\n+all-stage4-target-libphobos: maybe-all-stage4-target-libatomic\n+all-stageprofile-target-libphobos: maybe-all-stageprofile-target-libatomic\n+all-stagetrain-target-libphobos: maybe-all-stagetrain-target-libatomic\n+all-stagefeedback-target-libphobos: maybe-all-stagefeedback-target-libatomic\n+all-stageautoprofile-target-libphobos: maybe-all-stageautoprofile-target-libatomic\n+all-stageautofeedback-target-libphobos: maybe-all-stageautofeedback-target-libatomic\n configure-target-libstdc++-v3: maybe-configure-target-libgomp\n configure-stage1-target-libstdc++-v3: maybe-configure-stage1-target-libgomp\n configure-stage2-target-libstdc++-v3: maybe-configure-stage2-target-libgomp\n@@ -57127,7 +59537,6 @@ install-target-libstdc++-v3: maybe-insta\n all-target-libgloss: maybe-all-target-newlib\n all-target-winsup: maybe-all-target-libtermcap\n configure-target-libgfortran: maybe-all-target-libquadmath\n-configure-target-libgfortran: maybe-all-target-libbacktrace\n \n \n @if gcc-bootstrap\n@@ -57176,10 +59585,13 @@ all-bison: maybe-all-intl\n all-flex: maybe-all-intl\n all-m4: maybe-all-intl\n configure-target-libgo: maybe-all-target-libstdc++-v3\n+all-target-libgo: maybe-all-target-libbacktrace\n+all-target-libgo: maybe-all-target-libatomic\n configure-target-liboffloadmic: maybe-configure-target-libgomp\n all-target-liboffloadmic: maybe-all-target-libgomp\n configure-target-newlib: maybe-all-binutils\n configure-target-newlib: maybe-all-ld\n+configure-target-libgfortran: maybe-all-target-libbacktrace\n @endunless gcc-bootstrap\n \n # Dependencies for target modules on other target modules are\n@@ -57215,6 +59627,24 @@ configure-stagetrain-target-libvtv: mayb\n configure-stagefeedback-target-libvtv: maybe-all-stagefeedback-target-libgcc\n configure-stageautoprofile-target-libvtv: maybe-all-stageautoprofile-target-libgcc\n configure-stageautofeedback-target-libvtv: maybe-all-stageautofeedback-target-libgcc\n+configure-stage1-target-libbacktrace: maybe-all-stage1-target-libgcc\n+configure-stage2-target-libbacktrace: maybe-all-stage2-target-libgcc\n+configure-stage3-target-libbacktrace: maybe-all-stage3-target-libgcc\n+configure-stage4-target-libbacktrace: maybe-all-stage4-target-libgcc\n+configure-stageprofile-target-libbacktrace: maybe-all-stageprofile-target-libgcc\n+configure-stagetrain-target-libbacktrace: maybe-all-stagetrain-target-libgcc\n+configure-stagefeedback-target-libbacktrace: maybe-all-stagefeedback-target-libgcc\n+configure-stageautoprofile-target-libbacktrace: maybe-all-stageautoprofile-target-libgcc\n+configure-stageautofeedback-target-libbacktrace: maybe-all-stageautofeedback-target-libgcc\n+configure-stage1-target-libphobos: maybe-all-stage1-target-libgcc\n+configure-stage2-target-libphobos: maybe-all-stage2-target-libgcc\n+configure-stage3-target-libphobos: maybe-all-stage3-target-libgcc\n+configure-stage4-target-libphobos: maybe-all-stage4-target-libgcc\n+configure-stageprofile-target-libphobos: maybe-all-stageprofile-target-libgcc\n+configure-stagetrain-target-libphobos: maybe-all-stagetrain-target-libgcc\n+configure-stagefeedback-target-libphobos: maybe-all-stagefeedback-target-libgcc\n+configure-stageautoprofile-target-libphobos: maybe-all-stageautoprofile-target-libgcc\n+configure-stageautofeedback-target-libphobos: maybe-all-stageautofeedback-target-libgcc\n configure-stage1-target-libgomp: maybe-all-stage1-target-libgcc\n configure-stage2-target-libgomp: maybe-all-stage2-target-libgcc\n configure-stage3-target-libgomp: maybe-all-stage3-target-libgcc\n@@ -57224,6 +59654,15 @@ configure-stagetrain-target-libgomp: may\n configure-stagefeedback-target-libgomp: maybe-all-stagefeedback-target-libgcc\n configure-stageautoprofile-target-libgomp: maybe-all-stageautoprofile-target-libgcc\n configure-stageautofeedback-target-libgomp: maybe-all-stageautofeedback-target-libgcc\n+configure-stage1-target-libatomic: maybe-all-stage1-target-libgcc\n+configure-stage2-target-libatomic: maybe-all-stage2-target-libgcc\n+configure-stage3-target-libatomic: maybe-all-stage3-target-libgcc\n+configure-stage4-target-libatomic: maybe-all-stage4-target-libgcc\n+configure-stageprofile-target-libatomic: maybe-all-stageprofile-target-libgcc\n+configure-stagetrain-target-libatomic: maybe-all-stagetrain-target-libgcc\n+configure-stagefeedback-target-libatomic: maybe-all-stagefeedback-target-libgcc\n+configure-stageautoprofile-target-libatomic: maybe-all-stageautoprofile-target-libgcc\n+configure-stageautofeedback-target-libatomic: maybe-all-stageautofeedback-target-libgcc\n @endif gcc-bootstrap\n \n @if gcc-no-bootstrap\n--- a/config/acx.m4\n+++ b/config/acx.m4\n@@ -420,6 +420,18 @@ else\n fi\n ])\n \n+# Test for D.\n+AC_DEFUN([ACX_PROG_GDC],\n+[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])\n+AC_REQUIRE([AC_PROG_CC])\n+AC_CHECK_TOOL(GDC, gdc, no)\n+if test \"x$GDC\" != xno; then\n+  have_gdc=yes\n+else\n+  have_gdc=no\n+fi\n+])\n+\n dnl 'make compare' can be significantly faster, if cmp itself can\n dnl skip bytes instead of using tail.  The test being performed is\n dnl \"if cmp --ignore-initial=2 t1 t2 && ! cmp --ignore-initial=1 t1 t2\"\n--- a/configure\n+++ b/configure\n@@ -662,6 +662,7 @@ extra_mpfr_configure_flags\n gmpinc\n gmplibs\n do_compare\n+GDC\n GNATMAKE\n GNATBIND\n ac_ct_CXX\n@@ -5252,6 +5253,106 @@ else\n   have_gnat=no\n fi\n \n+\n+\n+if test -n \"$ac_tool_prefix\"; then\n+  # Extract the first word of \"${ac_tool_prefix}gdc\", so it can be a program name with args.\n+set dummy ${ac_tool_prefix}gdc; ac_word=$2\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n+$as_echo_n \"checking for $ac_word... \" >&6; }\n+if test \"${ac_cv_prog_GDC+set}\" = set; then :\n+  $as_echo_n \"(cached) \" >&6\n+else\n+  if test -n \"$GDC\"; then\n+  ac_cv_prog_GDC=\"$GDC\" # Let the user override the test.\n+else\n+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\n+for as_dir in $PATH\n+do\n+  IFS=$as_save_IFS\n+  test -z \"$as_dir\" && as_dir=.\n+    for ac_exec_ext in '' $ac_executable_extensions; do\n+  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n+    ac_cv_prog_GDC=\"${ac_tool_prefix}gdc\"\n+    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n+    break 2\n+  fi\n+done\n+  done\n+IFS=$as_save_IFS\n+\n+fi\n+fi\n+GDC=$ac_cv_prog_GDC\n+if test -n \"$GDC\"; then\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $GDC\" >&5\n+$as_echo \"$GDC\" >&6; }\n+else\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n+$as_echo \"no\" >&6; }\n+fi\n+\n+\n+fi\n+if test -z \"$ac_cv_prog_GDC\"; then\n+  ac_ct_GDC=$GDC\n+  # Extract the first word of \"gdc\", so it can be a program name with args.\n+set dummy gdc; ac_word=$2\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n+$as_echo_n \"checking for $ac_word... \" >&6; }\n+if test \"${ac_cv_prog_ac_ct_GDC+set}\" = set; then :\n+  $as_echo_n \"(cached) \" >&6\n+else\n+  if test -n \"$ac_ct_GDC\"; then\n+  ac_cv_prog_ac_ct_GDC=\"$ac_ct_GDC\" # Let the user override the test.\n+else\n+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\n+for as_dir in $PATH\n+do\n+  IFS=$as_save_IFS\n+  test -z \"$as_dir\" && as_dir=.\n+    for ac_exec_ext in '' $ac_executable_extensions; do\n+  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n+    ac_cv_prog_ac_ct_GDC=\"gdc\"\n+    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n+    break 2\n+  fi\n+done\n+  done\n+IFS=$as_save_IFS\n+\n+fi\n+fi\n+ac_ct_GDC=$ac_cv_prog_ac_ct_GDC\n+if test -n \"$ac_ct_GDC\"; then\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_GDC\" >&5\n+$as_echo \"$ac_ct_GDC\" >&6; }\n+else\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n+$as_echo \"no\" >&6; }\n+fi\n+\n+  if test \"x$ac_ct_GDC\" = x; then\n+    GDC=\"no\"\n+  else\n+    case $cross_compiling:$ac_tool_warned in\n+yes:)\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n+$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\n+ac_tool_warned=yes ;;\n+esac\n+    GDC=$ac_ct_GDC\n+  fi\n+else\n+  GDC=\"$ac_cv_prog_GDC\"\n+fi\n+\n+if test \"x$GDC\" != xno; then\n+  have_gdc=yes\n+else\n+  have_gdc=no\n+fi\n+\n { $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to compare bootstrapped objects\" >&5\n $as_echo_n \"checking how to compare bootstrapped objects... \" >&6; }\n if test \"${gcc_cv_prog_cmp_skip+set}\" = set; then :\n@@ -6277,6 +6378,23 @@ $as_echo \"$as_me: WARNING: GNAT is requi\n             ;;\n         esac\n \n+        # Disable D if no preexisting GDC is available.\n+        case ${add_this_lang}:${language}:${have_gdc} in\n+          yes:d:no)\n+            # Specifically requested language; tell them.\n+            as_fn_error \"GDC is required to build $language\" \"$LINENO\" 5\n+           ;;\n+          all:d:no)\n+            { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: GDC is required to build $language\" >&5\n+$as_echo \"$as_me: WARNING: GDC is required to build $language\" >&2;}\n+            add_this_lang=unsupported\n+            ;;\n+          *:d:no)\n+            # Silently disable.\n+            add_this_lang=unsupported\n+            ;;\n+        esac\n+\n         # Disable jit if -enable-host-shared not specified\n         case ${add_this_lang}:${language}:${host_shared} in\n           yes:jit:no)\n@@ -7098,6 +7216,16 @@ if echo \" ${target_configdirs} \" | grep\n   bootstrap_target_libs=${bootstrap_target_libs}target-libvtv,\n fi\n \n+# If we are building libatomic and the list of enabled languages includes the\n+# D frontend, bootstrap it.\n+if echo \" ${target_configdirs} \" | grep \" libatomic \" > /dev/null 2>&1; then\n+  case ,${enable_languages}, in\n+    *,d,*)\n+      bootstrap_target_libs=${bootstrap_target_libs}target-libatomic,\n+      ;;\n+  esac\n+fi\n+\n # Determine whether gdb needs tk/tcl or not.\n # Use 'maybe' since enable_gdbtk might be true even if tk isn't available\n # and in that case we want gdb to be built without tk.  Ugh!\n--- a/configure.ac\n+++ b/configure.ac\n@@ -1302,6 +1302,7 @@ int main() {}],\n fi\n \n ACX_PROG_GNAT\n+ACX_PROG_GDC\n ACX_PROG_CMP_IGNORE_INITIAL\n \n AC_ARG_ENABLE([bootstrap],\n@@ -1949,6 +1950,22 @@ if test -d ${srcdir}/gcc; then\n             ;;\n         esac\n \n+        # Disable D if no preexisting GDC is available.\n+        case ${add_this_lang}:${language}:${have_gdc} in\n+          yes:d:no)\n+            # Specifically requested language; tell them.\n+            AC_MSG_ERROR([GDC is required to build $language])\n+           ;;\n+          all:d:no)\n+            AC_MSG_WARN([GDC is required to build $language])\n+            add_this_lang=unsupported\n+            ;;\n+          *:d:no)\n+            # Silently disable.\n+            add_this_lang=unsupported\n+            ;;\n+        esac\n+\n         # Disable jit if -enable-host-shared not specified\n         case ${add_this_lang}:${language}:${host_shared} in\n           yes:jit:no)\n@@ -2682,6 +2699,16 @@ if echo \" ${target_configdirs} \" | grep\n   bootstrap_target_libs=${bootstrap_target_libs}target-libvtv,\n fi\n \n+# If we are building libatomic and the list of enabled languages includes the\n+# D frontend, bootstrap it.\n+if echo \" ${target_configdirs} \" | grep \" libatomic \" > /dev/null 2>&1; then\n+  case ,${enable_languages}, in\n+    *,d,*)\n+      bootstrap_target_libs=${bootstrap_target_libs}target-libatomic,\n+      ;;\n+  esac\n+fi\n+\n # Determine whether gdb needs tk/tcl or not.\n # Use 'maybe' since enable_gdbtk might be true even if tk isn't available\n # and in that case we want gdb to be built without tk.  Ugh!\n"
  },
  {
    "path": "gcc/d/runtime.cc",
    "content": "/* runtime.cc -- D runtime functions called by generated code.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/aggregate.h\"\n#include \"dmd/mtype.h\"\n\n#include \"tree.h\"\n#include \"fold-const.h\"\n#include \"stringpool.h\"\n\n#include \"d-tree.h\"\n\n\n/* During the codegen pass, the compiler may do lowering of expressions to call\n   various runtime library functions.  Most are implemented in the `rt' package.\n   We represent them in the frontend here, however there's no guarantee that\n   the compiler implementation actually matches the actual implementation.  */\n\nenum libcall_type\n{\n  LCT_VOID,\t\t    /* void\t\t    */\n  LCT_BYTE,\t\t    /* byte\t\t    */\n  LCT_INT,\t\t    /* int\t\t    */\n  LCT_UINT,\t\t    /* uint\t\t    */\n  LCT_BOOL,\t\t    /* bool\t\t    */\n  LCT_DCHAR,\t\t    /* dchar\t\t    */\n  LCT_VOIDPTR,\t\t    /* void*\t\t    */\n  LCT_STRING,\t\t    /* string\t\t    */\n  LCT_WSTRING,\t\t    /* wstring\t\t    */\n  LCT_DSTRING,\t\t    /* dstring\t\t    */\n  LCT_SIZE_T,\t\t    /* size_t\t\t    */\n  LCT_ASSOCARRAY,\t    /* void[void]\t    */\n  LCT_ARRAY_VOID,\t    /* void[]\t\t    */\n  LCT_ARRAY_SIZE_T,\t    /* size_t[]\t\t    */\n  LCT_ARRAY_BYTE,\t    /* byte[]\t\t    */\n  LCT_ARRAY_STRING,\t    /* string[]\t\t    */\n  LCT_ARRAY_WSTRING,\t    /* wstring[]\t    */\n  LCT_ARRAY_DSTRING,\t    /* dstring[]\t    */\n  LCT_ARRAYARRAY_BYTE,\t    /* byte[][]\t\t    */\n  LCT_POINTER_ASSOCARRAY,   /* void[void]*\t    */\n  LCT_POINTER_VOIDPTR,\t    /* void**\t\t    */\n  LCT_ARRAYPTR_VOID,\t    /* void[]*\t\t    */\n  LCT_ARRAYPTR_BYTE,\t    /* byte[]*\t\t    */\n  LCT_TYPEINFO,\t\t    /* TypeInfo\t\t    */\n  LCT_CLASSINFO,\t    /* TypeInfo_Class\t    */\n  LCT_OBJECT,\t\t    /* Object\t\t    */\n  LCT_CONST_TYPEINFO,\t    /* const(TypeInfo)\t    */\n  LCT_CONST_CLASSINFO,\t    /* const(ClassInfo)\t    */\n  LCT_END\n};\n\n/* An array of all types that are used by the runtime functions we need.  */\n\nstatic Type *libcall_types[LCT_END];\n\n/* Our internal list of library functions.  */\n\nstatic tree libcall_decls[LIBCALL_LAST];\n\n\n/* Return the frontend Type that is described by TYPE.  Most are readily cached\n   by the frontend proper, and likewise the use of pointerTo(), constOf(), and\n   arrayOf() will return cached types if they have been requested before.  */\n\nstatic Type *\nget_libcall_type (libcall_type type)\n{\n  if (libcall_types[type])\n    return libcall_types[type];\n\n  switch (type)\n    {\n    case LCT_VOID:\n      libcall_types[type] = Type::tvoid;\n      break;\n\n    case LCT_BYTE:\n      libcall_types[type] = Type::tint8;\n      break;\n\n    case LCT_INT:\n      libcall_types[type] = Type::tint32;\n      break;\n\n    case LCT_UINT:\n      libcall_types[type] = Type::tuns32;\n      break;\n\n    case LCT_BOOL:\n      libcall_types[type] = Type::tbool;\n      break;\n\n    case LCT_DCHAR:\n      libcall_types[type] = Type::tdchar;\n      break;\n\n    case LCT_VOIDPTR:\n      libcall_types[type] = Type::tvoidptr;\n      break;\n\n    case LCT_STRING:\n      libcall_types[type] = Type::tstring;\n      break;\n\n    case LCT_WSTRING:\n      libcall_types[type] = Type::twstring;\n      break;\n\n    case LCT_DSTRING:\n      libcall_types[type] = Type::tdstring;\n      break;\n\n    case LCT_SIZE_T:\n      libcall_types[type] = Type::tsize_t;\n      break;\n\n    case LCT_ASSOCARRAY:\n      libcall_types[type] = TypeAArray::create (Type::tvoid, Type::tvoid);\n      break;\n\n    case LCT_TYPEINFO:\n      libcall_types[type] = Type::dtypeinfo->type;\n      break;\n\n    case LCT_CLASSINFO:\n      libcall_types[type] = Type::typeinfoclass->type;\n      break;\n\n    case LCT_OBJECT:\n      libcall_types[type] = get_object_type ();\n      break;\n\n    case LCT_CONST_TYPEINFO:\n      libcall_types[type] = Type::dtypeinfo->type->constOf ();\n      break;\n\n    case LCT_CONST_CLASSINFO:\n      libcall_types[type] = Type::typeinfoclass->type->constOf ();\n      break;\n\n    case LCT_ARRAY_VOID:\n      libcall_types[type] = Type::tvoid->arrayOf ();\n      break;\n\n    case LCT_ARRAY_SIZE_T:\n      libcall_types[type] = Type::tsize_t->arrayOf ();\n      break;\n\n    case LCT_ARRAY_BYTE:\n      libcall_types[type] = Type::tint8->arrayOf ();\n      break;\n\n    case LCT_ARRAY_STRING:\n      libcall_types[type] = Type::tstring->arrayOf ();\n      break;\n\n    case LCT_ARRAY_WSTRING:\n      libcall_types[type] = Type::twstring->arrayOf ();\n      break;\n\n    case LCT_ARRAY_DSTRING:\n      libcall_types[type] = Type::tdstring->arrayOf ();\n      break;\n\n    case LCT_ARRAYARRAY_BYTE:\n      libcall_types[type] = Type::tint8->arrayOf ()->arrayOf ();\n      break;\n\n    case LCT_POINTER_ASSOCARRAY:\n      libcall_types[type] = get_libcall_type (LCT_ASSOCARRAY)->pointerTo ();\n      break;\n\n    case LCT_POINTER_VOIDPTR:\n      libcall_types[type] = Type::tvoidptr->arrayOf ();\n      break;\n\n    case LCT_ARRAYPTR_VOID:\n      libcall_types[type] = Type::tvoid->arrayOf ()->pointerTo ();\n      break;\n\n    case LCT_ARRAYPTR_BYTE:\n      libcall_types[type] = Type::tint8->arrayOf ()->pointerTo ();\n      break;\n\n    default:\n      gcc_unreachable ();\n    }\n\n  return libcall_types[type];\n}\n\n/* Builds and returns function declaration named NAME.  The RETURN_TYPE is\n   the type returned, FLAGS are the expression call flags, and NPARAMS is\n   the number of arguments, the types of which are provided in `...'.  */\n\nstatic tree\nbuild_libcall_decl (const char *name, libcall_type return_type,\n\t\t    int flags, int nparams, ...)\n{\n  tree *args = XALLOCAVEC (tree, nparams);\n  bool varargs = false;\n  tree fntype;\n\n  /* Add parameter types, using 'void' as the last parameter type\n     to mean this function accepts a variable list of arguments.  */\n  va_list ap;\n  va_start (ap, nparams);\n\n  for (int i = 0; i < nparams; i++)\n    {\n      libcall_type ptype = (libcall_type) va_arg (ap, int);\n      Type *type = get_libcall_type (ptype);\n\n      if (type == Type::tvoid)\n\t{\n\t  varargs = true;\n\t  nparams = i;\n\t}\n      else\n\targs[i] = build_ctype (type);\n    }\n\n  va_end (ap);\n\n  /* Build the function.  */\n  tree tret = build_ctype (get_libcall_type (return_type));\n  if (varargs)\n    fntype = build_varargs_function_type_array (tret, nparams, args);\n  else\n    fntype = build_function_type_array (tret, nparams, args);\n\n  tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,\n\t\t\t  get_identifier (name), fntype);\n  DECL_EXTERNAL (decl) = 1;\n  TREE_PUBLIC (decl) = 1;\n  DECL_ARTIFICIAL (decl) = 1;\n  DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;\n  DECL_VISIBILITY_SPECIFIED (decl) = 1;\n\n  /* Set any attributes on the function, such as malloc or noreturn.  */\n  set_call_expr_flags (decl, flags);\n\n  return decl;\n}\n\n/* Return or create the runtime library function declaration for LIBCALL.\n   Library functions are generated as needed.  This could probably be changed in\n   the future to be done in the compiler init stage, like GCC builtin trees are,\n   however we depend on run-time initialization of types whose definitions are\n   in the library such as `Object' or `TypeInfo'.  */\n\nstatic tree\nget_libcall (libcall_fn libcall)\n{\n  if (libcall_decls[libcall])\n    return libcall_decls[libcall];\n\n  switch (libcall)\n    {\n#define DEF_D_RUNTIME(CODE, NAME, TYPE, PARAMS, FLAGS) \\\n    case LIBCALL_ ## CODE:\t\\\n      libcall_decls[libcall] = build_libcall_decl (NAME, TYPE, FLAGS, PARAMS); \\\n      break;\n\n#include \"runtime.def\"\n\n#undef DEF_D_RUNTIME\n\n    default:\n      gcc_unreachable ();\n    }\n\n  return libcall_decls[libcall];\n}\n\n/* Generate a call to LIBCALL, returning the result as TYPE.  NARGS is the\n   number of call arguments, the expressions of which are provided in `...'.\n   This does not perform conversions or promotions on the arguments.  */\n\ntree\nbuild_libcall (libcall_fn libcall, Type *type, int nargs, ...)\n{\n  /* Build the call expression to the runtime function.  */\n  tree decl = get_libcall (libcall);\n  tree *args = XALLOCAVEC (tree, nargs);\n  va_list ap;\n\n  va_start (ap, nargs);\n  for (int i = 0; i < nargs; i++)\n    args[i] = va_arg (ap, tree);\n  va_end (ap);\n\n  tree result = build_call_expr_loc_array (input_location, decl, nargs, args);\n\n  /* Assumes caller knows what it is doing.  */\n  return convert (build_ctype (type), result);\n}\n"
  },
  {
    "path": "gcc/d/runtime.def",
    "content": "/* runtime.def -- Definitions for D runtime functions.\n   Copyright (C) 2014-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n/* D runtime library functions.  */\n\n/* DEF_D_RUNTIME (CODE, NAME, FLAGS)\n   CODE\t    The enum code used to refer to this function.\n   NAME\t    The name of this function as a string.\n   FLAGS    ECF flags to describe attributes of the function.\n\n   Used for declaring functions that are called by generated code.  Most are\n   extern(C) - for those that are not, ensure to use correct mangling.  */\n\n/* Helper macros for parameter building.  */\n#define P0()\t\t    0\n#define P1(T1)\t\t    1, LCT_ ## T1\n#define P2(T1, T2)\t    2, LCT_ ## T1, LCT_ ## T2\n#define P3(T1, T2, T3)\t    3, LCT_ ## T1, LCT_ ## T2, LCT_ ## T3\n#define P4(T1, T2, T3, T4)  4, LCT_ ## T1, LCT_ ## T2, LCT_ ## T3, LCT_ ## T4\n#define RT(T1)\t\t    LCT_ ## T1\n\n/* Used when an assert() contract fails.  */\nDEF_D_RUNTIME (ASSERT, \"_d_assert\", RT(VOID), P2(STRING, UINT), ECF_NORETURN)\nDEF_D_RUNTIME (ASSERT_MSG, \"_d_assert_msg\", RT(VOID), P3(STRING, STRING, UINT),\n\t       ECF_NORETURN)\n\n/* Used when an assert() contract fails in a unittest function.  */\nDEF_D_RUNTIME (UNITTEST, \"_d_unittest\", RT(VOID), P2(STRING, UINT),\n\t       ECF_NORETURN)\nDEF_D_RUNTIME (UNITTEST_MSG, \"_d_unittest_msg\", RT(VOID),\n\t       P3(STRING, STRING, UINT), ECF_NORETURN)\n\n/* Used when an array index outside the bounds of its range.  */\nDEF_D_RUNTIME (ARRAY_BOUNDS, \"_d_arraybounds\", RT(VOID), P2(STRING, UINT),\n\t       ECF_NORETURN)\n\n/* Used when calling new on a class.  */\nDEF_D_RUNTIME (NEWCLASS, \"_d_newclass\", RT(OBJECT), P1(CONST_CLASSINFO), 0)\n\n/* Used when calling delete on a class or interface.  */\nDEF_D_RUNTIME (DELCLASS, \"_d_delclass\", RT(VOID), P1(VOIDPTR), 0)\nDEF_D_RUNTIME (DELINTERFACE, \"_d_delinterface\", RT(VOID), P1(VOIDPTR), 0)\n\n/* Same as deleting a class, but used for stack-allocated classes.  */\nDEF_D_RUNTIME (CALLFINALIZER, \"_d_callfinalizer\", RT(VOID), P1(VOIDPTR), 0)\nDEF_D_RUNTIME (CALLINTERFACEFINALIZER, \"_d_callinterfacefinalizer\", RT(VOID),\n\t       P1(VOIDPTR), 0)\n\n/* Used for casting to a class or interface.  */\nDEF_D_RUNTIME (DYNAMIC_CAST, \"_d_dynamic_cast\", RT(OBJECT),\n\t       P2(OBJECT, CLASSINFO), 0)\nDEF_D_RUNTIME (INTERFACE_CAST, \"_d_interface_cast\", RT(OBJECT),\n\t       P2(OBJECT, CLASSINFO), 0)\n\n/* Used when calling new on a pointer.  The `i' variant is for when the\n   initializer is nonzero.  */\nDEF_D_RUNTIME (NEWITEMT, \"_d_newitemT\", RT(VOIDPTR), P1(CONST_TYPEINFO), 0)\nDEF_D_RUNTIME (NEWITEMIT, \"_d_newitemiT\", RT(VOIDPTR), P1(CONST_TYPEINFO), 0)\n\n/* Used when calling delete on a pointer.  */\nDEF_D_RUNTIME (DELMEMORY, \"_d_delmemory\", RT(VOID), P1(POINTER_VOIDPTR), 0)\nDEF_D_RUNTIME (DELSTRUCT, \"_d_delstruct\", RT(VOID),\n\t       P2(POINTER_VOIDPTR, TYPEINFO), 0)\n\n/* Used when calling new on an array.  The `i' variant is for when the\n   initializer is nonzero, and the `m' variant is when initializing a\n   multi-dimensional array.  */\nDEF_D_RUNTIME (NEWARRAYT, \"_d_newarrayT\", RT(ARRAY_VOID),\n\t       P2(CONST_TYPEINFO, SIZE_T), 0)\nDEF_D_RUNTIME (NEWARRAYIT, \"_d_newarrayiT\", RT(ARRAY_VOID),\n\t       P2(CONST_TYPEINFO, SIZE_T), 0)\nDEF_D_RUNTIME (NEWARRAYMTX, \"_d_newarraymTX\", RT(ARRAY_VOID),\n\t       P2(CONST_TYPEINFO, ARRAY_SIZE_T), 0)\nDEF_D_RUNTIME (NEWARRAYMITX, \"_d_newarraymiTX\", RT(ARRAY_VOID),\n\t       P2(CONST_TYPEINFO, ARRAY_SIZE_T), 0)\n\n/* Used for allocating an array literal on the GC heap.  */\nDEF_D_RUNTIME (ARRAYLITERALTX, \"_d_arrayliteralTX\", RT(VOIDPTR),\n\t       P2(CONST_TYPEINFO, SIZE_T), 0)\n\n/* Used when calling delete on an array.  */\nDEF_D_RUNTIME (DELARRAYT, \"_d_delarray_t\", RT(VOID),\n\t       P2(ARRAYPTR_VOID, CONST_TYPEINFO), 0)\n\n/* Used for value equality (x == y) and comparisons (x < y) of non-trivial\n   arrays.  Such as an array of structs or classes.  */\nDEF_D_RUNTIME (ADEQ2, \"_adEq2\", RT(INT),\n\t       P3(ARRAY_VOID, ARRAY_VOID, CONST_TYPEINFO), 0)\n\n/* Used when casting from one array type to another where the index type\n   sizes differ.  Such as from int[] to short[].  */\nDEF_D_RUNTIME (ARRAYCAST, \"_d_arraycast\", RT(ARRAY_VOID),\n\t       P3(SIZE_T, SIZE_T, ARRAY_VOID), 0)\n\n/* Used for (array.length = n) expressions.  The `i' variant is for when the\n   initializer is nonzero.  */\nDEF_D_RUNTIME (ARRAYSETLENGTHT, \"_d_arraysetlengthT\", RT(ARRAY_VOID),\n\t       P3(CONST_TYPEINFO, SIZE_T, ARRAYPTR_VOID), 0)\nDEF_D_RUNTIME (ARRAYSETLENGTHIT, \"_d_arraysetlengthiT\", RT(ARRAY_VOID),\n\t       P3(CONST_TYPEINFO, SIZE_T, ARRAYPTR_VOID), 0)\n\n/* Used for allocating closures on the GC heap.  */\nDEF_D_RUNTIME (ALLOCMEMORY, \"_d_allocmemory\", RT(VOIDPTR), P1(SIZE_T),\n\t       ECF_MALLOC)\n\n/* Used for copying an array into a slice, adds an enforcment that the source\n   and destination are equal in size and do not overlap.  */\nDEF_D_RUNTIME (ARRAYCOPY, \"_d_arraycopy\", RT(ARRAY_VOID),\n\t       P3(SIZE_T, ARRAY_VOID, ARRAY_VOID), 0)\n\n/* Used for array assignments from an existing array.  The `set' variant is for\n   when the assignment value is a single element.  */\nDEF_D_RUNTIME (ARRAYASSIGN, \"_d_arrayassign\", RT(ARRAY_VOID),\n\t       P3(CONST_TYPEINFO, ARRAY_VOID, ARRAY_VOID), 0)\nDEF_D_RUNTIME (ARRAYASSIGN_L, \"_d_arrayassign_l\", RT(ARRAY_VOID),\n\t       P4(CONST_TYPEINFO, ARRAY_VOID, ARRAY_VOID, VOIDPTR), 0)\nDEF_D_RUNTIME (ARRAYASSIGN_R, \"_d_arrayassign_r\", RT(ARRAY_VOID),\n\t       P4(CONST_TYPEINFO, ARRAY_VOID, ARRAY_VOID, VOIDPTR), 0)\nDEF_D_RUNTIME (ARRAYSETASSIGN, \"_d_arraysetassign\", RT(VOIDPTR),\n\t       P4(VOIDPTR, VOIDPTR, SIZE_T, CONST_TYPEINFO), 0)\n\n/* Used for constructing a new array from an existing array.  The `set' variant\n   is for when the constructor value is a single element.  */\nDEF_D_RUNTIME (ARRAYCTOR, \"_d_arrayctor\", RT(ARRAY_VOID),\n\t       P3(CONST_TYPEINFO, ARRAY_VOID, ARRAY_VOID), 0)\nDEF_D_RUNTIME (ARRAYSETCTOR, \"_d_arraysetctor\", RT(VOIDPTR),\n\t       P4(VOIDPTR, VOIDPTR, SIZE_T, CONST_TYPEINFO), 0)\n\n/* Used for concatenating two or more arrays together.  Then `n' variant is\n   for when there is more than two arrays to handle.  */\nDEF_D_RUNTIME (ARRAYCATT, \"_d_arraycatT\", RT(ARRAY_BYTE),\n\t       P3(CONST_TYPEINFO, ARRAY_BYTE, ARRAY_BYTE), 0)\nDEF_D_RUNTIME (ARRAYCATNTX, \"_d_arraycatnTX\", RT(ARRAY_VOID),\n\t       P2(CONST_TYPEINFO, ARRAYARRAY_BYTE), 0)\n\n/* Used for appending a single element to an array.  */\nDEF_D_RUNTIME (ARRAYAPPENDCTX, \"_d_arrayappendcTX\", RT(ARRAY_BYTE),\n\t       P3(CONST_TYPEINFO, ARRAYPTR_BYTE, SIZE_T), 0)\n\n/* Same as appending a single element to an array, but specific for when the\n   source is a UTF-32 character, and the destination is a UTF-8 or 16 array.  */\nDEF_D_RUNTIME (ARRAYAPPENDCD, \"_d_arrayappendcd\", RT(ARRAY_VOID),\n\t       P2(ARRAYPTR_BYTE, DCHAR), 0)\nDEF_D_RUNTIME (ARRAYAPPENDWD, \"_d_arrayappendwd\", RT(ARRAY_VOID),\n\t       P2(ARRAYPTR_BYTE, DCHAR), 0)\n\n/* Used for appending an existing array to another.  */\nDEF_D_RUNTIME (ARRAYAPPENDT, \"_d_arrayappendT\", RT(ARRAY_VOID),\n\t       P3(TYPEINFO, ARRAYPTR_BYTE, ARRAY_BYTE), 0)\n\n/* Used for allocating a new associative array.  */\nDEF_D_RUNTIME (ASSOCARRAYLITERALTX, \"_d_assocarrayliteralTX\", RT(VOIDPTR),\n\t       P3(CONST_TYPEINFO, ARRAY_VOID, ARRAY_VOID), 0)\n\n/* Used for value equality of two associative arrays.  */\nDEF_D_RUNTIME (AAEQUAL, \"_aaEqual\", RT(INT),\n\t       P3(CONST_TYPEINFO, ASSOCARRAY, ASSOCARRAY), 0)\n\n/* Used to determine is a key exists in an associative array.  */\nDEF_D_RUNTIME (AAINX, \"_aaInX\", RT(VOIDPTR),\n\t       P3(ASSOCARRAY, CONST_TYPEINFO, VOIDPTR), 0)\n\n/* Used to retrieve a value from an associative array index by a key.  The\n   `Rvalue' variant returns null if the key is not found, where as aaGetY\n   will create new key entry for assignment.  */\nDEF_D_RUNTIME (AAGETY, \"_aaGetY\", RT(VOIDPTR),\n\t       P4(POINTER_ASSOCARRAY, CONST_TYPEINFO, SIZE_T, VOIDPTR), 0)\nDEF_D_RUNTIME (AAGETRVALUEX, \"_aaGetRvalueX\", RT(VOIDPTR),\n\t       P4(ASSOCARRAY, CONST_TYPEINFO, SIZE_T, VOIDPTR), 0)\n\n/* Used when calling delete on a key entry in an associative array.  */\nDEF_D_RUNTIME (AADELX, \"_aaDelX\", RT(BOOL),\n\t       P3(ASSOCARRAY, CONST_TYPEINFO, VOIDPTR), 0)\n\n/* Used for throw() expressions.  */\nDEF_D_RUNTIME (THROW, \"_d_throw\", RT(VOID), P1(OBJECT), ECF_NORETURN)\nDEF_D_RUNTIME (BEGIN_CATCH, \"__gdc_begin_catch\", RT(VOIDPTR), P1(VOIDPTR), 0)\n\n/* C++ exception handlers.  */\nDEF_D_RUNTIME (CXA_BEGIN_CATCH, \"__cxa_begin_catch\", RT(VOIDPTR), P1(VOIDPTR),\n\t       ECF_NOTHROW)\nDEF_D_RUNTIME (CXA_END_CATCH, \"__cxa_end_catch\", RT(VOID), P0(), 0)\n\n/* When invariant() contracts are turned on, used after testing whether a\n   class != null for validating the state of a class.  */\nDEF_D_RUNTIME (INVARIANT, \"_D9invariant12_d_invariantFC6ObjectZv\", RT(VOID),\n\t       P1(OBJECT), 0)\n\n#undef P0\n#undef P1\n#undef P2\n#undef P3\n#undef P4\n#undef RT\n"
  },
  {
    "path": "gcc/d/toir.cc",
    "content": "/* toir.cc -- Lower D frontend statements to GCC trees.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/aggregate.h\"\n#include \"dmd/declaration.h\"\n#include \"dmd/expression.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/init.h\"\n#include \"dmd/statement.h\"\n\n#include \"tree.h\"\n#include \"tree-iterator.h\"\n#include \"options.h\"\n#include \"stmt.h\"\n#include \"fold-const.h\"\n#include \"diagnostic.h\"\n#include \"stringpool.h\"\n#include \"function.h\"\n#include \"toplev.h\"\n\n#include \"d-tree.h\"\n\n\n/* Update data for defined and undefined labels when leaving a scope.  */\n\nbool\npop_binding_label (Statement * const &, d_label_entry *ent, binding_level *bl)\n{\n  binding_level *obl = bl->level_chain;\n\n  if (ent->level == bl)\n    {\n      if (bl->kind == level_try)\n\tent->in_try_scope = true;\n      else if (bl->kind == level_catch)\n\tent->in_catch_scope = true;\n\n      ent->level = obl;\n    }\n  else if (ent->fwdrefs)\n    {\n      for (d_label_use_entry *ref = ent->fwdrefs; ref; ref = ref->next)\n\tref->level = obl;\n    }\n\n  return true;\n}\n\n/* At the end of a function, all labels declared within the function\n   go out of scope.  BLOCK is the top-level block for the function.  */\n\nbool\npop_label (Statement * const &s, d_label_entry *ent, tree block)\n{\n  if (!ent->bc_label)\n    {\n      /* Put the labels into the \"variables\" of the top-level block,\n\t so debugger can see them.  */\n      if (DECL_NAME (ent->label))\n\t{\n\t  gcc_assert (DECL_INITIAL (ent->label) != NULL_TREE);\n\t  DECL_CHAIN (ent->label) = BLOCK_VARS (block);\n\t  BLOCK_VARS (block) = ent->label;\n\t}\n    }\n\n  d_function_chain->labels->remove (s);\n\n  return true;\n}\n\n/* The D front-end does not use the 'binding level' system for a symbol table,\n   however it has been the goto structure for tracking code flow.\n   Primarily it is only needed to get debugging information for local variables\n   and otherwise support the back-end.  */\n\nvoid\npush_binding_level (level_kind kind)\n{\n  /* Add it to the front of currently active scopes stack.  */\n  binding_level *new_level = ggc_cleared_alloc<binding_level> ();\n  new_level->level_chain = current_binding_level;\n  new_level->kind = kind;\n\n  current_binding_level = new_level;\n}\n\ntree\npop_binding_level (void)\n{\n  binding_level *level = current_binding_level;\n  current_binding_level = level->level_chain;\n\n  tree block = make_node (BLOCK);\n  BLOCK_VARS (block) = level->names;\n  BLOCK_SUBBLOCKS (block) = level->blocks;\n\n  /* In each subblock, record that this is its superior.  */\n  for (tree t = level->blocks; t; t = BLOCK_CHAIN (t))\n    BLOCK_SUPERCONTEXT (t) = block;\n\n  if (level->kind == level_function)\n    {\n      /* Dispose of the block that we just made inside some higher level.  */\n      DECL_INITIAL (current_function_decl) = block;\n      BLOCK_SUPERCONTEXT (block) = current_function_decl;\n\n      /* Pop all the labels declared in the function.  */\n      if (d_function_chain->labels)\n\td_function_chain->labels->traverse<tree, &pop_label> (block);\n    }\n  else\n    {\n      /* Any uses of undefined labels, and any defined labels, now operate\n\t under constraints of next binding contour.  */\n      if (d_function_chain && d_function_chain->labels)\n\t{\n\t  language_function *f = d_function_chain;\n\t  f->labels->traverse<binding_level *, &pop_binding_label> (level);\n\t}\n\n      current_binding_level->blocks\n\t= block_chainon (current_binding_level->blocks, block);\n    }\n\n  TREE_USED (block) = 1;\n  return block;\n}\n\n/* Create an empty statement tree rooted at T.  */\n\nvoid\npush_stmt_list (void)\n{\n  tree t = alloc_stmt_list ();\n  vec_safe_push (d_function_chain->stmt_list, t);\n  d_keep (t);\n}\n\n/* Finish the statement tree rooted at T.  */\n\ntree\npop_stmt_list (void)\n{\n  tree t = d_function_chain->stmt_list->pop ();\n\n  /* If the statement list is completely empty, just return it.  This is just\n     as good as build_empty_stmt, with the advantage that statement lists\n     are merged when they are appended to one another.  So using the\n     STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P statements.  */\n  if (TREE_SIDE_EFFECTS (t))\n    {\n      /* If the statement list contained exactly one statement, then extract\n\t it immediately.  */\n      tree_stmt_iterator i = tsi_start (t);\n\n      if (tsi_one_before_end_p (i))\n\t{\n\t  tree u = tsi_stmt (i);\n\t  tsi_delink (&i);\n\t  free_stmt_list (t);\n\t  t = u;\n\t}\n    }\n\n  return t;\n}\n\n/* T is an expression statement.  Add it to the statement-tree.  */\n\nvoid\nadd_stmt (tree t)\n{\n  /* Ignore (void) 0; expression statements received from the frontend.\n     Likewise void_node is used when contracts become nops in release code.  */\n  if (t == void_node || IS_EMPTY_STMT (t))\n    return;\n\n  /* At this point, we no longer care about the value of expressions,\n     so if there's no side-effects, then don't add it.  */\n  if (!TREE_SIDE_EFFECTS (t))\n    return;\n\n  if (TREE_CODE (t) == COMPOUND_EXPR)\n    {\n      /* Push out each comma expressions as separate statements.  */\n      add_stmt (TREE_OPERAND (t, 0));\n      add_stmt (TREE_OPERAND (t, 1));\n    }\n  else\n    {\n      /* Force the type to be void so we don't need to create a temporary\n\t variable to hold the inner expression.  */\n      if (TREE_CODE (t) == CLEANUP_POINT_EXPR)\n\tTREE_TYPE (t) = void_type_node;\n\n      /* Append the expression to the statement list.\n\t Make sure it has a proper location.  */\n      if (EXPR_P (t) && !EXPR_HAS_LOCATION (t))\n\tSET_EXPR_LOCATION (t, input_location);\n\n      tree stmt_list = d_function_chain->stmt_list->last ();\n      append_to_statement_list_force (t, &stmt_list);\n    }\n}\n\n/* Implements the visitor interface to build the GCC trees of all Statement\n   AST classes emitted from the D Front-end.\n   All visit methods accept one parameter S, which holds the frontend AST\n   of the statement to compile.  They also don't return any value, instead\n   generated code are pushed to add_stmt(), which appends them to the\n   statement list in the current_binding_level.  */\n\nclass IRVisitor : public Visitor\n{\n  using Visitor::visit;\n\n  FuncDeclaration *func_;\n\n  /* Stack of labels which are targets for \"break\" and \"continue\",\n     linked through TREE_CHAIN.  */\n  tree break_label_;\n  tree continue_label_;\n\npublic:\n  IRVisitor (FuncDeclaration *fd)\n  {\n    this->func_ = fd;\n    this->break_label_ = NULL_TREE;\n    this->continue_label_ = NULL_TREE;\n  }\n\n  /* Helper for generating code for the statement AST class S.\n     Sets up the location of the statement before lowering.  */\n\n  void build_stmt (Statement *s)\n  {\n    location_t saved_location = input_location;\n    input_location = make_location_t (s->loc);\n    s->accept (this);\n    input_location = saved_location;\n  }\n\n  /* Start a new scope for a KIND statement.\n     Each user-declared variable will have a binding contour that begins\n     where the variable is declared and ends at its containing scope.  */\n\n  void start_scope (level_kind kind)\n  {\n    push_binding_level (kind);\n    push_stmt_list ();\n  }\n\n  /* Leave scope pushed by start_scope, returning a new bind_expr if\n     any variables where declared in the scope.  */\n\n  tree end_scope (void)\n  {\n    tree block = pop_binding_level ();\n    tree body = pop_stmt_list ();\n\n    if (! BLOCK_VARS (block))\n      return body;\n\n    tree bind = build3 (BIND_EXPR, void_type_node,\n\t\t\tBLOCK_VARS (block), body, block);\n    TREE_SIDE_EFFECTS (bind) = 1;\n    return bind;\n  }\n\n  /* Like end_scope, but also push it into the outer statement-tree.  */\n\n  void finish_scope (void)\n  {\n    tree scope = this->end_scope ();\n    add_stmt (scope);\n  }\n\n  /* Return TRUE if IDENT is the current function return label.  */\n\n  bool is_return_label (Identifier *ident)\n  {\n    if (this->func_->returnLabel)\n      return this->func_->returnLabel->ident == ident;\n\n    return false;\n  }\n\n  /* Define a label, specifying the location in the source file.\n     Return the LABEL_DECL node for the label.  */\n\n  tree define_label (Statement *s, Identifier *ident = NULL)\n  {\n    tree label = this->lookup_label (s, ident);\n    gcc_assert (DECL_INITIAL (label) == NULL_TREE);\n\n    d_label_entry *ent = d_function_chain->labels->get (s);\n    gcc_assert (ent != NULL);\n\n    /* Mark label as having been defined.  */\n    DECL_INITIAL (label) = error_mark_node;\n\n    ent->level = current_binding_level;\n\n    for (d_label_use_entry *ref = ent->fwdrefs; ref ; ref = ref->next)\n      this->check_previous_goto (ent->statement, ref);\n    ent->fwdrefs = NULL;\n\n    return label;\n  }\n\n  /* Emit a LABEL expression.  */\n\n  void do_label (tree label)\n  {\n    /* Don't write out label unless it is marked as used by the frontend.\n       This makes auto-vectorization possible in conditional loops.\n       The only excemption to this is in the LabelStatement visitor,\n       in which all computed labels are marked regardless.  */\n    if (TREE_USED (label))\n      add_stmt (build1 (LABEL_EXPR, void_type_node, label));\n  }\n\n  /* Emit a goto expression to LABEL.  */\n\n  void do_jump (tree label)\n  {\n    add_stmt (fold_build1 (GOTO_EXPR, void_type_node, label));\n    TREE_USED (label) = 1;\n  }\n\n  /* Check that a new jump at statement scope FROM to a label declared in\n     statement scope TO is valid.  */\n\n  void check_goto (Statement *from, Statement *to)\n  {\n    d_label_entry *ent = d_function_chain->labels->get (to);\n    gcc_assert (ent != NULL);\n\n    /* If the label hasn't been defined yet, defer checking.  */\n    if (! DECL_INITIAL (ent->label))\n      {\n\td_label_use_entry *fwdref = ggc_alloc<d_label_use_entry> ();\n\tfwdref->level = current_binding_level;\n\tfwdref->statement = from;\n\tfwdref->next = ent->fwdrefs;\n\tent->fwdrefs = fwdref;\n\treturn;\n      }\n\n    if (ent->in_try_scope)\n      error_at (make_location_t (from->loc), \"cannot goto into try block\");\n    else if (ent->in_catch_scope)\n      error_at (make_location_t (from->loc), \"cannot goto into catch block\");\n  }\n\n  /* Check that a previously seen jump to a newly defined label is valid.\n     S is the label statement; FWDREF is the jump context.  This is called\n     for both user-defined and case labels.  */\n\n  void check_previous_goto (Statement *s, d_label_use_entry *fwdref)\n  {\n    for (binding_level *b = current_binding_level; b ; b = b->level_chain)\n      {\n\tif (b == fwdref->level)\n\t  break;\n\n\tif (b->kind == level_try || b->kind == level_catch)\n\t  {\n\t    location_t location;\n\n\t    if (s->isLabelStatement ())\n\t      {\n\t\tlocation = make_location_t (fwdref->statement->loc);\n\t\tif (b->kind == level_try)\n\t\t  error_at (location, \"cannot goto into try block\");\n\t\telse\n\t\t  error_at (location, \"cannot goto into catch block\");\n\t      }\n\t    else if (s->isCaseStatement ())\n\t      {\n\t\tlocation = make_location_t (s->loc);\n\t\terror_at (location, \"case cannot be in different \"\n\t\t\t  \"try block level from switch\");\n\t      }\n\t    else if (s->isDefaultStatement ())\n\t      {\n\t\tlocation = make_location_t (s->loc);\n\t\terror_at (location, \"default cannot be in different \"\n\t\t\t  \"try block level from switch\");\n\t      }\n\t    else\n\t      gcc_unreachable ();\n\t  }\n      }\n  }\n\n  /* Get or build LABEL_DECL using the IDENT and statement block S given.  */\n\n  tree lookup_label (Statement *s, Identifier *ident = NULL)\n  {\n    /* You can't use labels at global scope.  */\n    if (d_function_chain == NULL)\n      {\n\terror (\"label %s referenced outside of any function\",\n\t       ident ? ident->toChars () : \"(unnamed)\");\n\treturn NULL_TREE;\n      }\n\n    /* Create the label htab for the function on demand.  */\n    if (!d_function_chain->labels)\n      {\n\td_function_chain->labels\n\t  = hash_map<Statement *, d_label_entry>::create_ggc (13);\n      }\n\n    d_label_entry *ent = d_function_chain->labels->get (s);\n    if (ent != NULL)\n      return ent->label;\n    else\n      {\n\ttree name = ident ? get_identifier (ident->toChars ()) : NULL_TREE;\n\ttree decl = build_decl (make_location_t (s->loc), LABEL_DECL,\n\t\t\t\tname, void_type_node);\n\tDECL_CONTEXT (decl) = current_function_decl;\n\tDECL_MODE (decl) = VOIDmode;\n\n\t/* Create new empty slot.  */\n\tent = ggc_cleared_alloc<d_label_entry> ();\n\tent->statement = s;\n\tent->label = decl;\n\n\tbool existed = d_function_chain->labels->put (s, *ent);\n\tgcc_assert (!existed);\n\n\treturn decl;\n      }\n  }\n\n  /* Get the LABEL_DECL to represent a break or continue for the\n     statement S given.  BC indicates which.  */\n\n  tree lookup_bc_label (Statement *s, bc_kind bc)\n  {\n    tree vec = this->lookup_label (s);\n\n    /* The break and continue labels are put into a TREE_VEC.  */\n    if (TREE_CODE (vec) == LABEL_DECL)\n      {\n\td_label_entry *ent = d_function_chain->labels->get (s);\n\tgcc_assert (ent != NULL);\n\n\tvec = make_tree_vec (2);\n\tTREE_VEC_ELT (vec, bc_break) = ent->label;\n\n\t/* Build the continue label.  */\n\ttree label = build_decl (make_location_t (s->loc), LABEL_DECL,\n\t\t\t\t NULL_TREE, void_type_node);\n\tDECL_CONTEXT (label) = current_function_decl;\n\tDECL_MODE (label) = VOIDmode;\n\tTREE_VEC_ELT (vec, bc_continue) = label;\n\n\tent->label = vec;\n\tent->bc_label = true;\n      }\n\n    return TREE_VEC_ELT (vec, bc);\n  }\n\n  /* Set and return the current break label for the current block.  */\n\n  tree push_break_label (Statement *s)\n  {\n    tree label = this->lookup_bc_label (s->getRelatedLabeled (), bc_break);\n    DECL_CHAIN (label) = this->break_label_;\n    this->break_label_ = label;\n    return label;\n  }\n\n  /* Finish with the current break label.  */\n\n  void pop_break_label (tree label)\n  {\n    gcc_assert (this->break_label_ == label);\n    this->break_label_ = DECL_CHAIN (this->break_label_);\n    this->do_label (label);\n  }\n\n  /* Set and return the continue label for the current block.  */\n\n  tree push_continue_label (Statement *s)\n  {\n    tree label = this->lookup_bc_label (s->getRelatedLabeled (), bc_continue);\n    DECL_CHAIN (label) = this->continue_label_;\n    this->continue_label_ = label;\n    return label;\n  }\n\n  /* Finish with the current continue label.  */\n\n  void pop_continue_label (tree label)\n  {\n    gcc_assert (this->continue_label_ == label);\n    this->continue_label_ = DECL_CHAIN (this->continue_label_);\n    this->do_label (label);\n  }\n\n  /* Visitor interfaces.  */\n\n\n  /* This should be overridden by each statement class.  */\n\n  void visit (Statement *)\n  {\n    gcc_unreachable ();\n  }\n\n  /* The frontend lowers `scope (exit/failure/success)' statements as\n     try/catch/finally.  At this point, this statement is just an empty\n     placeholder.  Maybe the frontend shouldn't leak these.  */\n\n  void visit (OnScopeStatement *)\n  {\n  }\n\n  /* If statements provide simple conditional execution of statements.  */\n\n  void visit (IfStatement *s)\n  {\n    this->start_scope (level_cond);\n\n    /* Build the outer 'if' condition, which may produce temporaries\n       requiring scope destruction.  */\n    tree ifcond = convert_for_condition (build_expr_dtor (s->condition),\n\t\t\t\t\t s->condition->type);\n    tree ifbody = void_node;\n    tree elsebody = void_node;\n\n    /* Build the 'then' branch.  */\n    if (s->ifbody)\n      {\n\tpush_stmt_list ();\n\tthis->build_stmt (s->ifbody);\n\tifbody = pop_stmt_list ();\n      }\n\n    /* Now build the 'else' branch, which may have nested 'else if' parts.  */\n    if (s->elsebody)\n      {\n\tpush_stmt_list ();\n\tthis->build_stmt (s->elsebody);\n\telsebody = pop_stmt_list ();\n      }\n\n    /* Wrap up our constructed if condition into a COND_EXPR.  */\n    tree cond = build_vcondition (ifcond, ifbody, elsebody);\n    add_stmt (cond);\n\n    /* Finish the if-then scope.  */\n    this->finish_scope ();\n  }\n\n  /* Should there be any `pragma (...)' statements requiring code generation,\n     here would be the place to do it.  For now, all pragmas are handled\n     by the frontend.  */\n\n  void visit (PragmaStatement *)\n  {\n  }\n\n  /* The frontend lowers `while (...)' statements as `for (...)' loops.\n     This visitor is not strictly required other than to enforce that\n     these kinds of statements never reach here.  */\n\n  void visit (WhileStatement *)\n  {\n    gcc_unreachable ();\n  }\n\n  /* Do while statments implement simple loops.  The body is executed, then\n     the condition is evaluated.  */\n\n  void visit (DoStatement *s)\n  {\n    tree lbreak = this->push_break_label (s);\n\n    this->start_scope (level_loop);\n    if (s->_body)\n      {\n\ttree lcontinue = this->push_continue_label (s);\n\tthis->build_stmt (s->_body);\n\tthis->pop_continue_label (lcontinue);\n      }\n\n    /* Build the outer 'while' condition, which may produce temporaries\n       requiring scope destruction.  */\n    tree exitcond = convert_for_condition (build_expr_dtor (s->condition),\n\t\t\t\t\t   s->condition->type);\n    add_stmt (build_vcondition (exitcond, void_node,\n\t\t\t\tbuild1 (GOTO_EXPR, void_type_node, lbreak)));\n    TREE_USED (lbreak) = 1;\n\n    tree body = this->end_scope ();\n    add_stmt (build1 (LOOP_EXPR, void_type_node, body));\n\n    this->pop_break_label (lbreak);\n  }\n\n  /* For statements implement loops with initialization, test, and\n     increment clauses.  */\n\n  void visit (ForStatement *s)\n  {\n    tree lbreak = this->push_break_label (s);\n    this->start_scope (level_loop);\n\n    if (s->_init)\n      this->build_stmt (s->_init);\n\n    if (s->condition)\n      {\n\ttree exitcond = convert_for_condition (build_expr_dtor (s->condition),\n\t\t\t\t\t       s->condition->type);\n\tadd_stmt (build_vcondition (exitcond, void_node,\n\t\t\t\t    build1 (GOTO_EXPR, void_type_node,\n\t\t\t\t\t    lbreak)));\n\tTREE_USED (lbreak) = 1;\n      }\n\n    if (s->_body)\n      {\n\ttree lcontinue = this->push_continue_label (s);\n\tthis->build_stmt (s->_body);\n\tthis->pop_continue_label (lcontinue);\n      }\n\n    if (s->increment)\n      {\n\t/* Force side effects?  */\n\tadd_stmt (build_expr_dtor (s->increment));\n      }\n\n    tree body = this->end_scope ();\n    add_stmt (build1 (LOOP_EXPR, void_type_node, body));\n\n    this->pop_break_label (lbreak);\n  }\n\n  /* The frontend lowers `foreach (...)' statements as `for (...)' loops.\n     This visitor is not strictly required other than to enforce that\n     these kinds of statements never reach here.  */\n\n  void visit (ForeachStatement *)\n  {\n    gcc_unreachable ();\n  }\n\n  /* The frontend lowers `foreach (...; [x..y])' statements as `for (...)'\n     loops.  This visitor is not strictly required other than to enforce that\n     these kinds of statements never reach here.  */\n\n  void visit (ForeachRangeStatement *)\n  {\n    gcc_unreachable ();\n  }\n\n  /* Jump to the associated exit label for the current loop.  If IDENT\n     for the Statement is not null, then the label is user defined.  */\n\n  void visit (BreakStatement *s)\n  {\n    if (s->ident)\n      {\n\t/* The break label may actually be some levels up.\n\t   eg: on a try/finally wrapping a loop.  */\n\tLabelStatement *label = this->func_->searchLabel (s->ident)->statement;\n\tgcc_assert (label != NULL);\n\tStatement *stmt = label->statement->getRelatedLabeled ();\n\tthis->do_jump (this->lookup_bc_label (stmt, bc_break));\n      }\n    else\n      this->do_jump (this->break_label_);\n  }\n\n  /* Jump to the associated continue label for the current loop.  If IDENT\n     for the Statement is not null, then the label is user defined.  */\n\n  void visit (ContinueStatement *s)\n  {\n    if (s->ident)\n      {\n\tLabelStatement *label = this->func_->searchLabel (s->ident)->statement;\n\tgcc_assert (label != NULL);\n\tthis->do_jump (this->lookup_bc_label (label->statement,\n\t\t\t\t\t      bc_continue));\n      }\n    else\n      this->do_jump (this->continue_label_);\n  }\n\n  /* A goto statement jumps to the statement identified by the given label.  */\n\n  void visit (GotoStatement *s)\n  {\n    gcc_assert (s->label->statement != NULL);\n    gcc_assert (s->tf == s->label->statement->tf);\n\n    /* If no label found, there was an error.  */\n    tree label = this->lookup_label (s->label->statement, s->label->ident);\n    this->do_jump (label);\n\n    /* Need to error if the goto is jumping into a try or catch block.  */\n    this->check_goto (s, s->label->statement);\n  }\n\n  /* Statements can be labeled.  A label is an identifier that precedes\n     a statement.  */\n\n  void visit (LabelStatement *s)\n  {\n    LabelDsymbol *sym;\n\n    if (this->is_return_label (s->ident))\n      sym = this->func_->returnLabel;\n    else\n      sym = this->func_->searchLabel (s->ident);\n\n    /* If no label found, there was an error.  */\n    tree label = this->define_label (sym->statement, sym->ident);\n    TREE_USED (label) = 1;\n\n    this->do_label (label);\n\n    if (this->is_return_label (s->ident) && this->func_->fensure != NULL)\n      this->build_stmt (this->func_->fensure);\n    else if (s->statement)\n      this->build_stmt (s->statement);\n  }\n\n  /* A switch statement goes to one of a collection of case statements\n     depending on the value of the switch expression.  */\n\n  void visit (SwitchStatement *s)\n  {\n    this->start_scope (level_switch);\n    tree lbreak = this->push_break_label (s);\n\n    tree condition = build_expr_dtor (s->condition);\n    Type *condtype = s->condition->type->toBasetype ();\n\n    /* A switch statement on a string gets turned into a library call.\n       It is not lowered during codegen.  */\n    if (!condtype->isscalar ())\n      {\n\terror (\"cannot handle switch condition of type %s\",\n\t       condtype->toChars ());\n\tgcc_unreachable ();\n      }\n\n    condition = fold (condition);\n\n    /* Build LABEL_DECLs now so they can be refered to by goto case.\n       Also checking the jump from the switch to the label is allowed.  */\n    if (s->cases)\n      {\n\tfor (size_t i = 0; i < s->cases->dim; i++)\n\t  {\n\t    CaseStatement *cs = (*s->cases)[i];\n\t    tree caselabel = this->lookup_label (cs);\n\n\t    /* Write cases as a series of if-then-else blocks.\n\t       if (condition == case)\n\t\t goto caselabel;  */\n\t    if (s->hasVars)\n\t      {\n\t\ttree ifcase = build2 (EQ_EXPR, build_ctype (condtype),\n\t\t\t\t      condition, build_expr_dtor (cs->exp));\n\t\ttree ifbody = fold_build1 (GOTO_EXPR, void_type_node,\n\t\t\t\t\t   caselabel);\n\t\ttree cond = build_vcondition (ifcase, ifbody, void_node);\n\t\tTREE_USED (caselabel) = 1;\n\t\tLABEL_VARIABLE_CASE (caselabel) = 1;\n\t\tadd_stmt (cond);\n\t      }\n\n\t    this->check_goto (s, cs);\n\t  }\n\n\tif (s->sdefault)\n\t  {\n\t    tree defaultlabel = this->lookup_label (s->sdefault);\n\n\t    /* The default label is the last 'else' block.  */\n\t    if (s->hasVars)\n\t      {\n\t\tthis->do_jump (defaultlabel);\n\t\tLABEL_VARIABLE_CASE (defaultlabel) = 1;\n\t      }\n\n\t    this->check_goto (s, s->sdefault);\n\t  }\n      }\n\n    /* Switch body goes in its own statement list.  */\n    push_stmt_list ();\n    if (s->_body)\n      this->build_stmt (s->_body);\n\n    tree casebody = pop_stmt_list ();\n\n    /* Wrap up constructed body into a switch_expr, unless it was\n       converted to an if-then-else expression.  */\n    if (s->hasVars)\n      add_stmt (casebody);\n    else\n      {\n\ttree switchexpr = build2 (SWITCH_EXPR, TREE_TYPE (condition),\n\t\t\t\t  condition, casebody);\n\tadd_stmt (switchexpr);\n\tSWITCH_ALL_CASES_P (switchexpr) = 1;\n      }\n\n    SWITCH_BREAK_LABEL_P (lbreak) = 1;\n\n    /* If the switch had any 'break' statements, emit the label now.  */\n    this->pop_break_label (lbreak);\n    this->finish_scope ();\n  }\n\n  /* Declare the case label associated with the current SwitchStatement.  */\n\n  void visit (CaseStatement *s)\n  {\n    /* Emit the case label.  */\n    tree label = this->define_label (s);\n\n    if (LABEL_VARIABLE_CASE (label))\n      this->do_label (label);\n    else\n      {\n\ttree casevalue;\n\tif (s->exp->type->isscalar ())\n\t  casevalue = build_expr (s->exp);\n\telse\n\t  casevalue = build_integer_cst (s->index, build_ctype (Type::tint32));\n\n\ttree caselabel = build_case_label (casevalue, NULL_TREE, label);\n\tadd_stmt (caselabel);\n      }\n\n    /* Now do the body.  */\n    if (s->statement)\n      this->build_stmt (s->statement);\n  }\n\n  /* Declare the default label associated with the current SwitchStatement.  */\n\n  void visit (DefaultStatement *s)\n  {\n    /* Emit the default case label.  */\n    tree label = this->define_label (s);\n\n    if (LABEL_VARIABLE_CASE (label))\n      this->do_label (label);\n    else\n      {\n\ttree caselabel = build_case_label (NULL_TREE, NULL_TREE, label);\n\tadd_stmt (caselabel);\n      }\n\n    /* Now do the body.  */\n    if (s->statement)\n      this->build_stmt (s->statement);\n  }\n\n  /* Implements 'goto default' by jumping to the label associated with\n     the DefaultStatement in a switch block.  */\n\n  void visit (GotoDefaultStatement *s)\n  {\n    tree label = this->lookup_label (s->sw->sdefault);\n    this->do_jump (label);\n  }\n\n  /* Implements 'goto case' by jumping to the label associated with the\n     CaseStatement in a switch block.  */\n\n  void visit (GotoCaseStatement *s)\n  {\n    tree label = this->lookup_label (s->cs);\n    this->do_jump (label);\n  }\n\n  /* Throw a SwitchError exception, called when a switch statement has\n     no DefaultStatement, yet none of the cases match.  */\n\n  void visit (SwitchErrorStatement *s)\n  {\n    /* A throw SwitchError statement gets turned into a library call.\n       The call is wrapped in the enclosed expression.  */\n    gcc_assert (s->exp != NULL);\n    add_stmt (build_expr (s->exp));\n  }\n\n  /* A return statement exits the current function and supplies its return\n     value, if the return type is not void.  */\n\n  void visit (ReturnStatement *s)\n  {\n    if (s->exp == NULL || s->exp->type->toBasetype ()->ty == Tvoid)\n      {\n\t/* Return has no value.  */\n\tadd_stmt (return_expr (NULL_TREE));\n\treturn;\n      }\n\n    TypeFunction *tf = (TypeFunction *)this->func_->type;\n    Type *type = this->func_->tintro != NULL\n      ? this->func_->tintro->nextOf () : tf->nextOf ();\n\n    if ((this->func_->isMain () || this->func_->isCMain ())\n\t&& type->toBasetype ()->ty == Tvoid)\n      type = Type::tint32;\n\n    if (this->func_->nrvo_can && this->func_->nrvo_var)\n      {\n\t/* Just refer to the DECL_RESULT; this differs from using\n\t   NULL_TREE in that it indicates that we care about the value\n\t   of the DECL_RESULT.  */\n\ttree decl = DECL_RESULT (get_symbol_decl (this->func_));\n\tadd_stmt (return_expr (decl));\n      }\n    else\n      {\n\t/* Convert for initializing the DECL_RESULT.  */\n\ttree expr = build_return_dtor (s->exp, type, tf);\n\tadd_stmt (expr);\n      }\n  }\n\n  /* Evaluate the enclosed expression, and add it to the statement list.  */\n\n  void visit (ExpStatement *s)\n  {\n    if (s->exp)\n      {\n\t/* Expression may produce temporaries requiring scope destruction.  */\n\ttree exp = build_expr_dtor (s->exp);\n\tadd_stmt (exp);\n      }\n  }\n\n  /* Evaluate all enclosed statements.  */\n\n  void visit (CompoundStatement *s)\n  {\n    if (s->statements == NULL)\n      return;\n\n    for (size_t i = 0; i < s->statements->dim; i++)\n      {\n\tStatement *statement = (*s->statements)[i];\n\n\tif (statement != NULL)\n\t  this->build_stmt (statement);\n      }\n  }\n\n  /* The frontend lowers `foreach (Tuple!(...))' statements as an unrolled loop.\n     These are compiled down as a `do ... while (0)', where each unrolled loop\n     is nested inside and given their own continue label to jump to.  */\n\n  void visit (UnrolledLoopStatement *s)\n  {\n    if (s->statements == NULL)\n      return;\n\n    tree lbreak = this->push_break_label (s);\n    this->start_scope (level_loop);\n\n    for (size_t i = 0; i < s->statements->dim; i++)\n      {\n\tStatement *statement = (*s->statements)[i];\n\n\tif (statement != NULL)\n\t  {\n\t    tree lcontinue = this->push_continue_label (statement);\n\t    this->build_stmt (statement);\n\t    this->pop_continue_label (lcontinue);\n\t  }\n      }\n\n    this->do_jump (this->break_label_);\n\n    tree body = this->end_scope ();\n    add_stmt (build1 (LOOP_EXPR, void_type_node, body));\n\n    this->pop_break_label (lbreak);\n  }\n\n  /* Start a new scope and visit all nested statements, wrapping\n     them up into a BIND_EXPR at the end of the scope.  */\n\n  void visit (ScopeStatement *s)\n  {\n    if (s->statement == NULL)\n      return;\n\n    this->start_scope (level_block);\n    this->build_stmt (s->statement);\n    this->finish_scope ();\n  }\n\n  /* A with statement is a way to simplify repeated references to the same\n     object, where the handle is either a class or struct instance.  */\n\n  void visit (WithStatement *s)\n  {\n    this->start_scope (level_with);\n\n    if (s->wthis)\n      {\n\t/* Perform initialisation of the 'with' handle.  */\n\tExpInitializer *ie = s->wthis->_init->isExpInitializer ();\n\tgcc_assert (ie != NULL);\n\n\tdeclare_local_var (s->wthis);\n\ttree init = build_expr_dtor (ie->exp);\n\tadd_stmt (init);\n      }\n\n    if (s->_body)\n      this->build_stmt (s->_body);\n\n    this->finish_scope ();\n  }\n\n  /* Implements 'throw Object'.  Frontend already checks that the object\n     thrown is a class type, but does not check if it is derived from\n     Object.  Foreign objects are not currently supported at run-time.  */\n\n  void visit (ThrowStatement *s)\n  {\n    ClassDeclaration *cd = s->exp->type->toBasetype ()->isClassHandle ();\n    InterfaceDeclaration *id = cd->isInterfaceDeclaration ();\n    tree arg = build_expr_dtor (s->exp);\n\n    if (!global.params.useExceptions)\n      {\n\tstatic int warned = 0;\n\tif (!warned)\n\t  {\n\t    error_at (make_location_t (s->loc), \"exception handling disabled, \"\n\t\t      \"use -fexceptions to enable\");\n\t    warned = 1;\n\t  }\n      }\n\n    if (cd->isCPPclass () || (id != NULL && id->isCPPclass ()))\n      error_at (make_location_t (s->loc), \"cannot throw C++ classes\");\n    else if (cd->com || (id != NULL && id->com))\n      error_at (make_location_t (s->loc), \"cannot throw COM objects\");\n    else\n      arg = build_nop (build_ctype (get_object_type ()), arg);\n\n    add_stmt (build_libcall (LIBCALL_THROW, Type::tvoid, 1, arg));\n  }\n\n  /* Build a try-catch statement, one of the building blocks for exception\n     handling generated by the frontend.  This is also used to implement\n     `scope (failure)' statements.  */\n\n  void visit (TryCatchStatement *s)\n  {\n    this->start_scope (level_try);\n    if (s->_body)\n      this->build_stmt (s->_body);\n\n    tree trybody = this->end_scope ();\n\n    /* Try handlers go in their own statement list.  */\n    push_stmt_list ();\n\n    if (s->catches)\n      {\n\tfor (size_t i = 0; i < s->catches->dim; i++)\n\t  {\n\t    Catch *vcatch = (*s->catches)[i];\n\n\t    this->start_scope (level_catch);\n\n\t    tree ehptr = builtin_decl_explicit (BUILT_IN_EH_POINTER);\n\t    tree catchtype = build_ctype (vcatch->type);\n\t    tree object = NULL_TREE;\n\n\t    ehptr = build_call_expr (ehptr, 1, integer_zero_node);\n\n\t    /* Retrieve the internal exception object, which could be for a\n\t       D or C++ catch handler.  This is different from the generic\n\t       exception pointer returned from gcc runtime.  */\n\t    Type *tcatch = vcatch->type->toBasetype ();\n\t    ClassDeclaration *cd = tcatch->isClassHandle ();\n\n\t    libcall_fn libcall = (cd->isCPPclass ()) ? LIBCALL_CXA_BEGIN_CATCH\n\t      : LIBCALL_BEGIN_CATCH;\n\t    object = build_libcall (libcall, vcatch->type, 1, ehptr);\n\n\t    if (vcatch->var)\n\t      {\n\t\ttree var = get_symbol_decl (vcatch->var);\n\t\ttree init = build_assign (INIT_EXPR, var, object);\n\n\t\tdeclare_local_var (vcatch->var);\n\t\tadd_stmt (init);\n\t      }\n\t    else\n\t      {\n\t\t/* Still need to emit a call to __gdc_begin_catch() to\n\t\t   remove the object from the uncaught exceptions list.  */\n\t\tadd_stmt (object);\n\t      }\n\n\t    if (vcatch->handler)\n\t      this->build_stmt (vcatch->handler);\n\n\t    tree catchbody = this->end_scope ();\n\n\t    /* Need to wrap C++ handlers in a try/finally block to signal\n\t       the end catch callback.  */\n\t    if (cd->isCPPclass ())\n\t      {\n\t\ttree endcatch = build_libcall (LIBCALL_CXA_END_CATCH,\n\t\t\t\t\t       Type::tvoid, 0);\n\t\tcatchbody = build2 (TRY_FINALLY_EXPR, void_type_node,\n\t\t\t\t    catchbody, endcatch);\n\t      }\n\n\t    add_stmt (build2 (CATCH_EXPR, void_type_node,\n\t\t\t      catchtype, catchbody));\n\t  }\n      }\n\n    tree catches = pop_stmt_list ();\n\n    /* Back-end expects all catches in a TRY_CATCH_EXPR to be enclosed in a\n       statement list, however pop_stmt_list may optimize away the list\n       if there is only a single catch to push.  */\n    if (TREE_CODE (catches) != STATEMENT_LIST)\n      {\n\ttree stmt_list = alloc_stmt_list ();\n\tappend_to_statement_list_force (catches, &stmt_list);\n\tcatches = stmt_list;\n      }\n\n    add_stmt (build2 (TRY_CATCH_EXPR, void_type_node, trybody, catches));\n  }\n\n  /* Build a try-finally statement, one of the building blocks for exception\n     handling generated by the frontend.  This is also used to implement\n     `scope (exit)' statements.  */\n\n  void visit (TryFinallyStatement *s)\n  {\n    this->start_scope (level_try);\n    if (s->_body)\n      this->build_stmt (s->_body);\n\n    tree trybody = this->end_scope ();\n\n    this->start_scope (level_finally);\n    if (s->finalbody)\n      this->build_stmt (s->finalbody);\n\n    tree finally = this->end_scope ();\n\n    add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node, trybody, finally));\n  }\n\n  /* The frontend lowers `synchronized (...)' statements as a call to\n     monitor/critical enter and exit wrapped around try/finally.\n     This visitor is not strictly required other than to enforce that\n     these kinds of statements never reach here.  */\n\n  void visit (SynchronizedStatement *)\n  {\n    gcc_unreachable ();\n  }\n\n  /* D Inline Assembler is not implemented, as it would require writing\n     an assembly parser for each supported target.  Instead we leverage\n     GCC extended assembler using the GccAsmStatement class.  */\n\n  void visit (AsmStatement *)\n  {\n    sorry (\"D inline assembler statements are not supported in GDC.\");\n  }\n\n  /* Build a GCC extended assembler expression, whose components are\n     an INSN string, some OUTPUTS, some INPUTS, and some CLOBBERS.  */\n\n  void visit (GccAsmStatement *s)\n  {\n    StringExp *insn = (StringExp *)s->insn;\n    tree outputs = NULL_TREE;\n    tree inputs = NULL_TREE;\n    tree clobbers = NULL_TREE;\n    tree labels = NULL_TREE;\n\n    /* Collect all arguments, which may be input or output operands.  */\n    if (s->args)\n      {\n\tfor (size_t i = 0; i < s->args->dim; i++)\n\t  {\n\t    Identifier *name = (*s->names)[i];\n\t    const char *sname = name ? name->toChars () : NULL;\n\t    tree id = name ? build_string (strlen (sname), sname) : NULL_TREE;\n\n\t    StringExp *constr = (StringExp *)(*s->constraints)[i];\n\t    const char *cstring = (const char *)(constr->len\n\t\t\t\t\t\t ? constr->string : \"\");\n\t    tree str = build_string (constr->len, cstring);\n\n\t    Expression *earg = (*s->args)[i];\n\t    tree val = build_expr (earg);\n\n\t    if (i < s->outputargs)\n\t      {\n\t\ttree arg = build_tree_list (id, str);\n\t\toutputs = chainon (outputs, build_tree_list (arg, val));\n\t      }\n\t    else\n\t      {\n\t\ttree arg = build_tree_list (id, str);\n\t\tinputs = chainon (inputs, build_tree_list (arg, val));\n\t      }\n\t  }\n      }\n\n    /* Collect all clobber arguments.  */\n    if (s->clobbers)\n      {\n\tfor (size_t i = 0; i < s->clobbers->dim; i++)\n\t  {\n\t    StringExp *clobber = (StringExp *)(*s->clobbers)[i];\n\t    const char *cstring = (const char *)(clobber->len\n\t\t\t\t\t\t ? clobber->string : \"\");\n\n\t    tree val = build_string (clobber->len, cstring);\n\t    clobbers = chainon (clobbers, build_tree_list (0, val));\n\t  }\n      }\n\n    /* Collect all goto labels, these should have been already checked\n       by the front-end, so pass down the label symbol to the back-end.  */\n    if (s->labels)\n      {\n\tfor (size_t i = 0; i < s->labels->dim; i++)\n\t  {\n\t    Identifier *ident = (*s->labels)[i];\n\t    GotoStatement *gs = (*s->gotos)[i];\n\n\t    gcc_assert (gs->label->statement != NULL);\n\t    gcc_assert (gs->tf == gs->label->statement->tf);\n\n\t    const char *sident = ident->toChars ();\n\t    tree name = build_string (strlen (sident), sident);\n\t    tree label = this->lookup_label (gs->label->statement,\n\t\t\t\t\t     gs->label->ident);\n\t    TREE_USED (label) = 1;\n\n\t    labels = chainon (labels, build_tree_list (name, label));\n\t  }\n      }\n\n    /* Do some extra validation on all input and output operands.  */\n    const char *insnstring = (const char *)(insn->len ? insn->string : \"\");\n    tree string = build_string (insn->len, insnstring);\n    string = resolve_asm_operand_names (string, outputs, inputs, labels);\n\n    if (s->args)\n      {\n\tunsigned noutputs = s->outputargs;\n\tunsigned ninputs = (s->args->dim - noutputs);\n\tconst char **oconstraints = XALLOCAVEC (const char *, noutputs);\n\tbool allows_mem, allows_reg, is_inout;\n\tsize_t i;\n\ttree t;\n\n\tfor (i = 0, t = outputs; t != NULL_TREE; t = TREE_CHAIN (t), i++)\n\t  {\n\t    tree output = TREE_VALUE (t);\n\t    const char *constraint\n\t      = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));\n\n\t    oconstraints[i] = constraint;\n\n\t    if (parse_output_constraint (&constraint, i, ninputs, noutputs,\n\t\t\t\t\t &allows_mem, &allows_reg, &is_inout))\n\t      {\n\t\t/* If the output argument is going to end up in memory.  */\n\t\tif (!allows_reg)\n\t\t  d_mark_addressable (output);\n\t      }\n\t    else\n\t      output = error_mark_node;\n\n\t    TREE_VALUE (t) = output;\n\t  }\n\n\tfor (i = 0, t = inputs; t != NULL_TREE; t = TREE_CHAIN (t), i++)\n\t  {\n\t    tree input = TREE_VALUE (t);\n\t    const char *constraint\n\t      = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));\n\n\t    if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,\n\t\t\t\t\toconstraints, &allows_mem, &allows_reg))\n\t      {\n\t\t/* If the input argument is going to end up in memory.  */\n\t\tif (!allows_reg && allows_mem)\n\t\t  d_mark_addressable (input);\n\t      }\n\t    else\n\t      input = error_mark_node;\n\n\t    TREE_VALUE (t) = input;\n\t  }\n      }\n\n    tree exp = build5 (ASM_EXPR, void_type_node, string,\n\t\t       outputs, inputs, clobbers, labels);\n    SET_EXPR_LOCATION (exp, make_location_t (s->loc));\n\n    /* If the extended syntax was not used, mark the ASM_EXPR.  */\n    if (s->args == NULL && s->clobbers == NULL)\n      ASM_INPUT_P (exp) = 1;\n\n    /* Asm statements are treated as volatile unless 'pure'.  */\n    ASM_VOLATILE_P (exp) = !(s->stc & STCpure);\n\n    add_stmt (exp);\n  }\n\n  /* Import symbols from another module.  */\n\n  void visit (ImportStatement *s)\n  {\n    if (s->imports == NULL)\n      return;\n\n    for (size_t i = 0; i < s->imports->dim; i++)\n      {\n\tDsymbol *dsym = (*s->imports)[i];\n\n\tif (dsym != NULL)\n\t  build_decl_tree (dsym);\n      }\n  }\n};\n\n/* Main entry point for the IRVisitor interface to generate\n   code for the body of function FD.  */\n\nvoid\nbuild_function_body (FuncDeclaration *fd)\n{\n  IRVisitor v = IRVisitor (fd);\n  location_t saved_location = input_location;\n  input_location = make_location_t (fd->loc);\n  v.build_stmt (fd->fbody);\n  input_location = saved_location;\n}\n"
  },
  {
    "path": "gcc/d/typeinfo.cc",
    "content": "/* typeinfo.cc -- D runtime type identification.\n   Copyright (C) 2013-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/aggregate.h\"\n#include \"dmd/enum.h\"\n#include \"dmd/errors.h\"\n#include \"dmd/expression.h\"\n#include \"dmd/globals.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/module.h\"\n#include \"dmd/mtype.h\"\n#include \"dmd/template.h\"\n#include \"dmd/target.h\"\n\n#include \"tree.h\"\n#include \"options.h\"\n#include \"fold-const.h\"\n#include \"diagnostic.h\"\n#include \"stringpool.h\"\n#include \"toplev.h\"\n#include \"stor-layout.h\"\n\n#include \"d-tree.h\"\n#include \"d-target.h\"\n\n\n/* D returns type information to the user as TypeInfo class objects, and can\n   be retrieved for any type using `typeid()'.  We also use type information\n   to implement many runtime library helpers, including `new', `delete', most\n   dynamic array operations, and all associative array operations.\n\n   Type information for a particular type is indicated with an ABI defined\n   structure derived from TypeInfo.  This would all be very straight forward,\n   but for the fact that the runtime library provides the definitions of the\n   TypeInfo structure and the ABI defined derived classes in `object.d', as\n   well as having specific implementations of TypeInfo for built-in types\n   in `rt/typeinfo`.  We cannot build declarations of these directly in the\n   compiler, but we need to layout objects of their type.\n\n   To get around this, we define layout compatible POD-structs and generate the\n   appropriate initializations for them.  When we have to provide a TypeInfo to\n   the user, we cast the internal compiler type to TypeInfo.\n\n   It is only required that TypeInfo has a definition in `object.d'.  It could\n   happen that we are generating a type information for a TypeInfo object that\n   has no declaration.  We however only need the addresses of such incomplete\n   TypeInfo objects for static initialization.  */\n\nenum tinfo_kind\n{\n  TK_TYPEINFO_TYPE,\t\t/* object.TypeInfo  */\n  TK_CLASSINFO_TYPE,\t\t/* object.TypeInfo_Class  */\n  TK_INTERFACE_TYPE,\t\t/* object.TypeInfo_Interface  */\n  TK_STRUCT_TYPE,\t\t/* object.TypeInfo_Struct  */\n  TK_POINTER_TYPE,\t\t/* object.TypeInfo_Pointer  */\n  TK_ARRAY_TYPE,\t\t/* object.TypeInfo_Array  */\n  TK_STATICARRAY_TYPE,\t\t/* object.TypeInfo_StaticArray  */\n  TK_ASSOCIATIVEARRAY_TYPE,\t/* object.TypeInfo_AssociativeArray  */\n  TK_VECTOR_TYPE,\t\t/* object.TypeInfo_Vector  */\n  TK_ENUMERAL_TYPE,\t\t/* object.TypeInfo_Enum  */\n  TK_FUNCTION_TYPE,\t\t/* object.TypeInfo_Function  */\n  TK_DELEGATE_TYPE,\t\t/* object.TypeInfo_Delegate  */\n  TK_TYPELIST_TYPE,\t\t/* object.TypeInfo_Tuple  */\n  TK_CONST_TYPE,\t\t/* object.TypeInfo_Const  */\n  TK_IMMUTABLE_TYPE,\t\t/* object.TypeInfo_Invariant  */\n  TK_SHARED_TYPE,\t\t/* object.TypeInfo_Shared  */\n  TK_INOUT_TYPE,\t\t/* object.TypeInfo_Inout  */\n  TK_CPPTI_TYPE,\t\t/* object.__cpp_type_info_ptr  */\n  TK_END\n};\n\n/* An array of all internal TypeInfo derived types we need.\n   The TypeInfo and ClassInfo types are created early, the\n   remainder are generated as needed.  */\n\nstatic GTY(()) tree tinfo_types[TK_END];\n\n/* Return the kind of TypeInfo used to describe TYPE.  */\n\nstatic tinfo_kind\nget_typeinfo_kind (Type *type)\n{\n  /* Check head shared/const modifiers first.  */\n  if (type->isShared ())\n    return TK_SHARED_TYPE;\n  else if (type->isConst ())\n    return TK_CONST_TYPE;\n  else if (type->isImmutable ())\n    return TK_IMMUTABLE_TYPE;\n  else if (type->isWild ())\n    return TK_INOUT_TYPE;\n\n  switch (type->ty)\n    {\n    case Tpointer:\n      return TK_POINTER_TYPE;\n\n    case  Tarray:\n      return TK_ARRAY_TYPE;\n\n    case Tsarray:\n      return TK_STATICARRAY_TYPE;\n\n    case Taarray:\n      return TK_ASSOCIATIVEARRAY_TYPE;\n\n    case Tstruct:\n      return TK_STRUCT_TYPE;\n\n    case Tvector:\n      return TK_VECTOR_TYPE;\n\n    case Tenum:\n      return TK_ENUMERAL_TYPE;\n\n    case Tfunction:\n      return TK_FUNCTION_TYPE;\n\n    case Tdelegate:\n      return TK_DELEGATE_TYPE;\n\n    case Ttuple:\n      return TK_TYPELIST_TYPE;\n\n    case Tclass:\n      if (((TypeClass *) type)->sym->isInterfaceDeclaration ())\n\treturn TK_INTERFACE_TYPE;\n      else\n\treturn TK_CLASSINFO_TYPE;\n\n    default:\n      return TK_TYPEINFO_TYPE;\n    }\n}\n\n/* Generate the RECORD_TYPE containing the data layout of a TypeInfo derivative\n   as used by the runtime.  This layout must be consistent with that defined in\n   the `object.d' module.  */\n\nstatic void\nmake_internal_typeinfo (tinfo_kind tk, Identifier *ident, ...)\n{\n  va_list ap;\n\n  va_start (ap, ident);\n\n  /* First two fields are from the TypeInfo base class.\n     Note, finish_builtin_struct() expects these fields in reverse order.  */\n  tree fields = create_field_decl (ptr_type_node, NULL, 1, 1);\n  DECL_CHAIN (fields) = create_field_decl (vtbl_ptr_type_node, NULL, 1, 1);\n\n  /* Now add the derived fields.  */\n  tree field_type = va_arg (ap, tree);\n  while (field_type != NULL_TREE)\n    {\n      tree field = create_field_decl (field_type, NULL, 1, 1);\n      DECL_CHAIN (field) = fields;\n      fields = field;\n      field_type = va_arg (ap, tree);\n    }\n\n  /* Create the TypeInfo type.  */\n  tree type = make_node (RECORD_TYPE);\n  finish_builtin_struct (type, ident->toChars (), fields, NULL_TREE);\n\n  tinfo_types[tk] = type;\n\n  va_end (ap);\n}\n\n/* Helper for create_tinfo_types.  Creates a typeinfo class declaration\n   incase one wasn't supplied by reading `object.d'.  */\n\nstatic void\nmake_frontend_typeinfo (Module *mod, Identifier *ident,\n\t\t\tClassDeclaration *base = NULL)\n{\n  if (!base)\n    base = Type::dtypeinfo;\n\n  /* Create object module in order to complete the semantic.  */\n  if (!mod->_scope)\n    mod->importAll (NULL);\n\n  /* Assignment of global typeinfo variables is managed by the ClassDeclaration\n     constructor, so only need to new the declaration here.  */\n  Loc loc = (mod->md) ? mod->md->loc : mod->loc;\n  ClassDeclaration *tinfo = ClassDeclaration::create (loc, ident, NULL, NULL,\n\t\t\t\t\t\t      true);\n  tinfo->parent = mod;\n  tinfo->members = new Dsymbols;\n  dsymbolSemantic (tinfo, mod->_scope);\n  tinfo->baseClass = base;\n  /* This is a compiler generated class, and shouldn't be mistaken for being\n     the type declared in the runtime library.  */\n  tinfo->storage_class |= STCtemp;\n}\n\n/* Make sure the required builtin types exist for generating the TypeInfo\n   variable definitions.  */\n\nvoid\ncreate_tinfo_types (Module *mod)\n{\n  /* Build the internal TypeInfo and ClassInfo types.\n     See TypeInfoVisitor for documentation of field layout.  */\n  make_internal_typeinfo (TK_TYPEINFO_TYPE, Identifier::idPool (\"TypeInfo\"),\n\t\t\t  NULL);\n\n  make_internal_typeinfo (TK_CLASSINFO_TYPE,\n\t\t\t  Identifier::idPool (\"TypeInfo_Class\"),\n\t\t\t  array_type_node, array_type_node, array_type_node,\n\t\t\t  array_type_node, ptr_type_node, ptr_type_node,\n\t\t\t  ptr_type_node, d_uint_type, ptr_type_node,\n\t\t\t  array_type_node, ptr_type_node, ptr_type_node, NULL);\n\n  /* Create all frontend TypeInfo classes declarations.  We rely on all\n     existing, even if only just as stubs.  */\n  if (!Type::dtypeinfo)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo\"),\n\t\t\t    ClassDeclaration::object);\n\n  if (!Type::typeinfoclass)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Class\"));\n\n  if (!Type::typeinfointerface)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Interface\"));\n\n  if (!Type::typeinfostruct)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Struct\"));\n\n  if (!Type::typeinfopointer)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Pointer\"));\n\n  if (!Type::typeinfoarray)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Array\"));\n\n  if (!Type::typeinfostaticarray)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_StaticArray\"));\n\n  if (!Type::typeinfoassociativearray)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_AssociativeArray\"));\n\n  if (!Type::typeinfoenum)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Enum\"));\n\n  if (!Type::typeinfofunction)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Function\"));\n\n  if (!Type::typeinfodelegate)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Delegate\"));\n\n  if (!Type::typeinfotypelist)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Tuple\"));\n\n  if (!Type::typeinfoconst)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Const\"));\n\n  if (!Type::typeinfoinvariant)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Invariant\"),\n\t\t\t    Type::typeinfoconst);\n\n  if (!Type::typeinfoshared)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Shared\"),\n\t\t\t    Type::typeinfoconst);\n\n  if (!Type::typeinfowild)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Wild\"),\n\t\t\t    Type::typeinfoconst);\n\n  if (!Type::typeinfovector)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"TypeInfo_Vector\"));\n\n  if (!ClassDeclaration::cpp_type_info_ptr)\n    make_frontend_typeinfo (mod, Identifier::idPool (\"__cpp_type_info_ptr\"),\n\t\t\t    ClassDeclaration::object);\n}\n\n/* Return true if TypeInfo class TINFO is available in the runtime library.  */\n\nbool\nhave_typeinfo_p (ClassDeclaration *tinfo)\n{\n  /* Run-time typeinfo disabled on command line.  */\n  if (!global.params.useTypeInfo)\n    return false;\n\n  /* Can't layout TypeInfo if type is not declared, or is an opaque\n     declaration in the object module.  */\n  if (!tinfo || !tinfo->members)\n    return false;\n\n  /* Typeinfo is compiler-generated.  */\n  if (tinfo->storage_class & STCtemp)\n    return false;\n\n  return true;\n}\n\n/* Implements the visitor interface to build the TypeInfo layout of all\n   TypeInfoDeclaration AST classes emitted from the D Front-end.\n   All visit methods accept one parameter D, which holds the frontend AST\n   of the TypeInfo class.  They also don't return any value, instead the\n   generated symbol is cached internally and returned from the caller.  */\n\nclass TypeInfoVisitor : public Visitor\n{\n  using Visitor::visit;\n\n  tree type_;\n  vec<constructor_elt, va_gc> *init_;\n\n  /* Add VALUE to the constructor values list.  */\n\n  void layout_field (tree value)\n  {\n    CONSTRUCTOR_APPEND_ELT (this->init_, NULL_TREE, value);\n  }\n\n  /* Write out STR as a static D string literal.  */\n\n  void layout_string (const char *str)\n  {\n    unsigned len = strlen (str);\n    tree value = build_string (len, str);\n\n    TREE_TYPE (value) = make_array_type (Type::tchar, len);\n    TREE_CONSTANT (value) = 1;\n    TREE_READONLY (value) = 1;\n    TREE_STATIC (value) = 1;\n\n    /* Taking the address, so assign the literal to a static var.  */\n    tree decl = build_artificial_decl (TREE_TYPE (value), value);\n    TREE_READONLY (decl) = 1;\n    DECL_EXTERNAL (decl) = 0;\n    d_pushdecl (decl);\n\n    value = d_array_value (build_ctype (Type::tchar->arrayOf ()),\n\t\t\t   size_int (len), build_address (decl));\n    this->layout_field (value);\n  }\n\n  /* Write out the __vptr and __monitor fields of class CD.  */\n\n  void layout_base (ClassDeclaration *cd)\n  {\n    gcc_assert (cd != NULL);\n\n    if (have_typeinfo_p (cd))\n      this->layout_field (build_address (get_vtable_decl (cd)));\n    else\n      this->layout_field (null_pointer_node);\n\n    this->layout_field (null_pointer_node);\n  }\n\n  /* Write out the interfaces field of class CD.\n     Returns the array of interfaces that the field is pointing to.  */\n\n  tree layout_interfaces (ClassDeclaration *cd)\n  {\n    size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);\n    tree csym = build_address (get_classinfo_decl (cd));\n\n    /* Put out the offset to where vtblInterfaces are written.  */\n    tree value = d_array_value (array_type_node,\n\t\t\t\tsize_int (cd->vtblInterfaces->dim),\n\t\t\t\tbuild_offset (csym, size_int (offset)));\n    this->layout_field (value);\n\n    /* Internally, the compiler sees Interface as:\n\tvoid*[4] interface;\n\n       The run-time layout of Interface is:\n\tTypeInfo_Class classinfo;\n\tvoid*[] vtbl;\n\tsize_t offset;  */\n    vec<constructor_elt, va_gc> *elms = NULL;\n\n    for (size_t i = 0; i < cd->vtblInterfaces->dim; i++)\n      {\n\tBaseClass *b = (*cd->vtblInterfaces)[i];\n\tClassDeclaration *id = b->sym;\n\tvec<constructor_elt, va_gc> *v = NULL;\n\n\t/* Fill in the vtbl[].  */\n\tif (!cd->isInterfaceDeclaration ())\n\t  b->fillVtbl (cd, &b->vtbl, 1);\n\n\t/* ClassInfo for the interface.  */\n\tvalue = build_address (get_classinfo_decl (id));\n\tCONSTRUCTOR_APPEND_ELT (v, size_int (0), value);\n\n\tif (!cd->isInterfaceDeclaration ())\n\t  {\n\t    /* The vtable of the interface length and ptr.  */\n\t    unsigned voffset = base_vtable_offset (cd, b);\n\t    gcc_assert (voffset != 0u);\n\t    value = build_offset (csym, size_int (voffset));\n\n\t    CONSTRUCTOR_APPEND_ELT (v, size_int (1), size_int (id->vtbl.dim));\n\t    CONSTRUCTOR_APPEND_ELT (v, size_int (2), value);\n\t  }\n\n\t/* The 'this' offset.  */\n\tCONSTRUCTOR_APPEND_ELT (v, size_int (3), size_int (b->offset));\n\n\t/* Add to the array of interfaces.  */\n\tvalue = build_constructor (vtbl_interface_type_node, v);\n\tCONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);\n      }\n\n    tree domain = size_int (cd->vtblInterfaces->dim - 1);\n    tree arrtype = build_array_type (vtbl_interface_type_node,\n\t\t\t\t     build_index_type (domain));\n    return build_constructor (arrtype, elms);\n  }\n\n  /* Write out the interfacing vtable[] of base class BCD that will be accessed\n     from the overriding class CD.  If both are the same class, then this will\n     be its own vtable.  INDEX is the offset in the interfaces array of the\n     base class where the Interface reference can be found.\n     This must be mirrored with base_vtable_offset().  */\n\n  void layout_base_vtable (ClassDeclaration *cd, ClassDeclaration *bcd,\n\t\t\t   size_t index)\n  {\n    BaseClass *bs = (*bcd->vtblInterfaces)[index];\n    ClassDeclaration *id = bs->sym;\n    vec<constructor_elt, va_gc> *elms = NULL;\n    FuncDeclarations bvtbl;\n\n    if (id->vtbl.dim == 0 || base_vtable_offset (cd, bs) == ~0u)\n      return;\n\n    /* Fill bvtbl with the functions we want to put out.  */\n    if (cd != bcd && !bs->fillVtbl (cd, &bvtbl, 0))\n      return;\n\n    /* First entry is struct Interface reference.  */\n    if (id->vtblOffset ())\n      {\n\tsize_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);\n\toffset += (index * int_size_in_bytes (vtbl_interface_type_node));\n\ttree value = build_offset (build_address (get_classinfo_decl (bcd)),\n\t\t\t\t   size_int (offset));\n\tCONSTRUCTOR_APPEND_ELT (elms, size_zero_node, value);\n      }\n\n    for (size_t i = id->vtblOffset () ? 1 : 0; i < id->vtbl.dim; i++)\n      {\n\tFuncDeclaration *fd = (cd == bcd) ? bs->vtbl[i] : bvtbl[i];\n\tif (fd != NULL)\n\t  {\n\t    tree value = build_address (make_thunk (fd, bs->offset));\n\t    CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);\n\t  }\n      }\n\n    tree vtbldomain = build_index_type (size_int (id->vtbl.dim - 1));\n    tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);\n    tree value = build_constructor (vtbltype, elms);\n    this->layout_field (value);\n  }\n\n\npublic:\n  TypeInfoVisitor (tree type)\n  {\n    this->type_ = type;\n    this->init_ = NULL;\n  }\n\n  /* Return the completed constructor for the TypeInfo record.  */\n\n  tree result (void)\n  {\n    return build_struct_literal (this->type_, this->init_);\n  }\n\n  /* Layout of TypeInfo is:\n\tvoid **__vptr;\n\tvoid *__monitor;  */\n\n  void visit (TypeInfoDeclaration *)\n  {\n    /* The vtable for TypeInfo.  */\n    this->layout_base (Type::dtypeinfo);\n  }\n\n  /* Layout of TypeInfo_Const is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo base;  */\n\n  void visit (TypeInfoConstDeclaration *d)\n  {\n    Type *tm = d->tinfo->mutableOf ();\n    tm = tm->merge2 ();\n\n    /* The vtable for TypeInfo_Const.  */\n    this->layout_base (Type::typeinfoconst);\n\n    /* TypeInfo for the mutable type.  */\n    this->layout_field (build_typeinfo (d->loc, tm));\n  }\n\n  /* Layout of TypeInfo_Immutable is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo base;  */\n\n  void visit (TypeInfoInvariantDeclaration *d)\n  {\n    Type *tm = d->tinfo->mutableOf ();\n    tm = tm->merge2 ();\n\n    /* The vtable for TypeInfo_Invariant.  */\n    this->layout_base (Type::typeinfoinvariant);\n\n    /* TypeInfo for the mutable type.  */\n    this->layout_field (build_typeinfo (d->loc, tm));\n  }\n\n  /* Layout of TypeInfo_Shared is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo base;  */\n\n  void visit (TypeInfoSharedDeclaration *d)\n  {\n    Type *tm = d->tinfo->unSharedOf ();\n    tm = tm->merge2 ();\n\n    /* The vtable for TypeInfo_Shared.  */\n    this->layout_base (Type::typeinfoshared);\n\n    /* TypeInfo for the unshared type.  */\n    this->layout_field (build_typeinfo (d->loc, tm));\n  }\n\n  /* Layout of TypeInfo_Inout is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo base;  */\n\n  void visit (TypeInfoWildDeclaration *d)\n  {\n    Type *tm = d->tinfo->mutableOf ();\n    tm = tm->merge2 ();\n\n    /* The vtable for TypeInfo_Inout.  */\n    this->layout_base (Type::typeinfowild);\n\n    /* TypeInfo for the mutable type.  */\n    this->layout_field (build_typeinfo (d->loc, tm));\n  }\n\n  /* Layout of TypeInfo_Enum is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo base;\n\tstring name;\n\tvoid[] m_init;  */\n\n  void visit (TypeInfoEnumDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Tenum);\n    TypeEnum *ti = (TypeEnum *) d->tinfo;\n    EnumDeclaration *ed = ti->sym;\n\n    /* The vtable for TypeInfo_Enum.  */\n    this->layout_base (Type::typeinfoenum);\n\n    /* TypeInfo for enum members.  */\n    tree memtype = (ed->memtype) ? build_typeinfo (d->loc, ed->memtype)\n      : null_pointer_node;\n    this->layout_field (memtype);\n\n    /* Name of the enum declaration.  */\n    this->layout_string (ed->toPrettyChars ());\n\n    /* Default initializer for enum.  */\n    if (ed->members && !d->tinfo->isZeroInit ())\n      {\n\ttree length = size_int (ed->type->size ());\n\ttree ptr = build_address (enum_initializer_decl (ed));\n\tthis->layout_field (d_array_value (array_type_node, length, ptr));\n      }\n    else\n      this->layout_field (null_array_node);\n  }\n\n  /* Layout of TypeInfo_Pointer is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo m_next;  */\n\n  void visit (TypeInfoPointerDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Tpointer);\n    TypePointer *ti = (TypePointer *) d->tinfo;\n\n    /* The vtable for TypeInfo_Pointer.  */\n    this->layout_base (Type::typeinfopointer);\n\n    /* TypeInfo for pointer-to type.  */\n    this->layout_field (build_typeinfo (d->loc, ti->next));\n  }\n\n  /* Layout of TypeInfo_Array is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo value;  */\n\n  void visit (TypeInfoArrayDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Tarray);\n    TypeDArray *ti = (TypeDArray *) d->tinfo;\n\n    /* The vtable for TypeInfo_Array.  */\n    this->layout_base (Type::typeinfoarray);\n\n    /* TypeInfo for array of type.  */\n    this->layout_field (build_typeinfo (d->loc, ti->next));\n  }\n\n  /* Layout of TypeInfo_StaticArray is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo value;\n\tsize_t len;  */\n\n  void visit (TypeInfoStaticArrayDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Tsarray);\n    TypeSArray *ti = (TypeSArray *) d->tinfo;\n\n    /* The vtable for TypeInfo_StaticArray.  */\n    this->layout_base (Type::typeinfostaticarray);\n\n    /* TypeInfo for array of type.  */\n    this->layout_field (build_typeinfo (d->loc, ti->next));\n\n    /* Static array length.  */\n    this->layout_field (size_int (ti->dim->toInteger ()));\n  }\n\n  /* Layout of TypeInfo_AssociativeArray is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo value;\n\tTypeInfo key;  */\n\n  void visit (TypeInfoAssociativeArrayDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Taarray);\n    TypeAArray *ti = (TypeAArray *) d->tinfo;\n\n    /* The vtable for TypeInfo_AssociativeArray.  */\n    this->layout_base (Type::typeinfoassociativearray);\n\n    /* TypeInfo for value of type.  */\n    this->layout_field (build_typeinfo (d->loc, ti->next));\n\n    /* TypeInfo for index of type.  */\n    this->layout_field (build_typeinfo (d->loc, ti->index));\n  }\n\n  /* Layout of TypeInfo_Vector is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo base;  */\n\n  void visit (TypeInfoVectorDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Tvector);\n    TypeVector *ti = (TypeVector *) d->tinfo;\n\n    /* The vtable for TypeInfo_Vector.  */\n    this->layout_base (Type::typeinfovector);\n\n    /* TypeInfo for equivalent static array.  */\n    this->layout_field (build_typeinfo (d->loc, ti->basetype));\n  }\n\n  /* Layout of TypeInfo_Function is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo next;\n\tstring deco;  */\n\n  void visit (TypeInfoFunctionDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Tfunction && d->tinfo->deco != NULL);\n    TypeFunction *ti = (TypeFunction *) d->tinfo;\n\n    /* The vtable for TypeInfo_Function.  */\n    this->layout_base (Type::typeinfofunction);\n\n    /* TypeInfo for function return value.  */\n    this->layout_field (build_typeinfo (d->loc, ti->next));\n\n    /* Mangled name of function declaration.  */\n    this->layout_string (d->tinfo->deco);\n  }\n\n  /* Layout of TypeInfo_Delegate is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo next;\n\tstring deco;  */\n\n  void visit (TypeInfoDelegateDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Tdelegate && d->tinfo->deco != NULL);\n    TypeDelegate *ti = (TypeDelegate *) d->tinfo;\n\n    /* The vtable for TypeInfo_Delegate.  */\n    this->layout_base (Type::typeinfodelegate);\n\n    /* TypeInfo for delegate return value.  */\n    this->layout_field (build_typeinfo (d->loc, ti->next));\n\n    /* Mangled name of delegate declaration.  */\n    this->layout_string (d->tinfo->deco);\n  }\n\n  /* Layout of ClassInfo/TypeInfo_Class is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tbyte[] m_init;\n\tstring name;\n\tvoid*[] vtbl;\n\tInterface[] interfaces;\n\tTypeInfo_Class base;\n\tvoid *destructor;\n\tvoid function(Object) classInvariant;\n\tClassFlags m_flags;\n\tvoid *deallocator;\n\tOffsetTypeInfo[] m_offTi;\n\tvoid function(Object) defaultConstructor;\n\timmutable(void)* m_RTInfo;\n\n     Information relating to interfaces, and their vtables are laid out\n     immediately after the named fields, if there is anything to write.  */\n\n  void visit (TypeInfoClassDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Tclass);\n    TypeClass *ti = (TypeClass *) d->tinfo;\n    ClassDeclaration *cd = ti->sym;\n\n    /* The vtable for ClassInfo.  */\n    this->layout_base (Type::typeinfoclass);\n\n    if (!cd->members)\n      return;\n\n    tree interfaces = NULL_TREE;\n\n    if (!cd->isInterfaceDeclaration ())\n      {\n\t/* Default initializer for class.  */\n\ttree init = aggregate_initializer_decl (cd);\n\ttree value = d_array_value (array_type_node, size_int (cd->structsize),\n\t\t\t\t    build_address (init));\n\tthis->layout_field (value);\n\n\t/* Name of the class declaration.  */\n\tconst char *name = cd->ident->toChars ();\n\tif (!(strlen (name) > 9 && memcmp (name, \"TypeInfo_\", 9) == 0))\n\t  name = cd->toPrettyChars ();\n\tthis->layout_string (name);\n\n\t/* The vtable of the class declaration.  */\n\tvalue = d_array_value (array_type_node, size_int (cd->vtbl.dim),\n\t\t\t       build_address (get_vtable_decl (cd)));\n\tthis->layout_field (value);\n\n\t/* Array of base interfaces that have their own vtable.  */\n\tif (cd->vtblInterfaces->dim)\n\t  interfaces = this->layout_interfaces (cd);\n\telse\n\t  this->layout_field (null_array_node);\n\n\t/* TypeInfo_Class base;  */\n\ttree base = (cd->baseClass)\n\t  ? build_address (get_classinfo_decl (cd->baseClass))\n\t  : null_pointer_node;\n\tthis->layout_field (base);\n\n\t/* void *destructor;  */\n\ttree dtor = (cd->tidtor) ? build_address (get_symbol_decl (cd->tidtor))\n\t  : null_pointer_node;\n\tthis->layout_field (dtor);\n\n\t/* void function(Object) classInvariant;  */\n\ttree inv = (cd->inv) ? build_address (get_symbol_decl (cd->inv))\n\t  : null_pointer_node;\n\tthis->layout_field (inv);\n\n\t/* ClassFlags m_flags;  */\n\tint flags = ClassFlags::hasOffTi;\n\tif (cd->isCOMclass ())\n\t  flags |= ClassFlags::isCOMclass;\n\n\tif (cd->isCPPclass ())\n\t  flags |= ClassFlags::isCPPclass;\n\n\tflags |= ClassFlags::hasGetMembers;\n\tflags |= ClassFlags::hasTypeInfo;\n\n\tif (cd->ctor)\n\t  flags |= ClassFlags::hasCtor;\n\n\tfor (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)\n\t  {\n\t    if (bcd->dtor)\n\t      {\n\t\tflags |= ClassFlags::hasDtor;\n\t\tbreak;\n\t      }\n\t  }\n\n\tif (cd->isAbstract ())\n\t  flags |= ClassFlags::isAbstract;\n\n\tfor (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)\n\t  {\n\t    if (!bcd->members)\n\t      continue;\n\n\t    for (size_t i = 0; i < bcd->members->dim; i++)\n\t      {\n\t\tDsymbol *sm = (*bcd->members)[i];\n\t\tif (sm->hasPointers ())\n\t\t  goto Lhaspointers;\n\t      }\n\t  }\n\n\tflags |= ClassFlags::noPointers;\n\n    Lhaspointers:\n\tthis->layout_field (size_int (flags));\n\n\t/* void *deallocator;  */\n\ttree ddtor = (cd->aggDelete)\n\t  ? build_address (get_symbol_decl (cd->aggDelete))\n\t  : null_pointer_node;\n\tthis->layout_field (ddtor);\n\n\t/* OffsetTypeInfo[] m_offTi;  (not implemented)  */\n\tthis->layout_field (null_array_node);\n\n\t/* void function(Object) defaultConstructor;  */\n\tif (cd->defaultCtor && !(cd->defaultCtor->storage_class & STCdisable))\n\t  {\n\t    tree dctor = get_symbol_decl (cd->defaultCtor);\n\t    this->layout_field (build_address (dctor));\n\t  }\n\telse\n\t  this->layout_field (null_pointer_node);\n\n\t/* immutable(void)* m_RTInfo;  */\n\tif (cd->getRTInfo)\n\t  this->layout_field (build_expr (cd->getRTInfo, true));\n\telse if (!(flags & ClassFlags::noPointers))\n\t  this->layout_field (size_one_node);\n\telse\n\t  this->layout_field (null_pointer_node);\n      }\n    else\n      {\n\t/* No initializer for interface.  */\n\tthis->layout_field (null_array_node);\n\n\t/* Name of the interface declaration.  */\n\tthis->layout_string (cd->toPrettyChars ());\n\n\t/* No vtable for interface declaration.  */\n\tthis->layout_field (null_array_node);\n\n\t/* Array of base interfaces that have their own vtable.  */\n\tif (cd->vtblInterfaces->dim)\n\t  interfaces = this->layout_interfaces (cd);\n\telse\n\t  this->layout_field (null_array_node);\n\n\t/* TypeInfo_Class base;\n\t   void *destructor;\n\t   void function(Object) classInvariant;  */\n\tthis->layout_field (null_pointer_node);\n\tthis->layout_field (null_pointer_node);\n\tthis->layout_field (null_pointer_node);\n\n\t/* ClassFlags m_flags;  */\n\tint flags = ClassFlags::hasOffTi;\n\tflags |= ClassFlags::hasTypeInfo;\n\tif (cd->isCOMinterface ())\n\t  flags |= ClassFlags::isCOMclass;\n\n\tthis->layout_field (size_int (flags));\n\n\t/* void *deallocator;\n\t   OffsetTypeInfo[] m_offTi;  (not implemented)\n\t   void function(Object) defaultConstructor;  */\n\tthis->layout_field (null_pointer_node);\n\tthis->layout_field (null_array_node);\n\tthis->layout_field (null_pointer_node);\n\n\t/* immutable(void)* m_RTInfo;  */\n\tif (cd->getRTInfo)\n\t  this->layout_field (build_expr (cd->getRTInfo, true));\n\telse\n\t  this->layout_field (null_pointer_node);\n      }\n\n    /* Put out array of Interfaces.  */\n    if (interfaces != NULL_TREE)\n      this->layout_field (interfaces);\n\n    if (!cd->isInterfaceDeclaration ())\n      {\n\t/* Put out this class' interface vtables[].  */\n\tfor (size_t i = 0; i < cd->vtblInterfaces->dim; i++)\n\t  this->layout_base_vtable (cd, cd, i);\n\n\t/* Put out the overriding interface vtables[].  */\n\tfor (ClassDeclaration *bcd = cd->baseClass; bcd; bcd = bcd->baseClass)\n\t  {\n\t    for (size_t i = 0; i < bcd->vtblInterfaces->dim; i++)\n\t      this->layout_base_vtable (cd, bcd, i);\n\t  }\n      }\n  }\n\n  /* Layout of TypeInfo_Interface is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo_Class info;  */\n\n  void visit (TypeInfoInterfaceDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Tclass);\n    TypeClass *ti = (TypeClass *) d->tinfo;\n\n    if (!ti->sym->vclassinfo)\n      ti->sym->vclassinfo = TypeInfoClassDeclaration::create (ti);\n\n    /* The vtable for TypeInfo_Interface.  */\n    this->layout_base (Type::typeinfointerface);\n\n    /* TypeInfo for class inheriting the interface.  */\n    tree tidecl = get_typeinfo_decl (ti->sym->vclassinfo);\n    this->layout_field (build_address (tidecl));\n  }\n\n  /* Layout of TypeInfo_Struct is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tstring name;\n\tvoid[] m_init;\n\thash_t function(in void*) xtoHash;\n\tbool function(in void*, in void*) xopEquals;\n\tint function(in void*, in void*) xopCmp;\n\tstring function(const(void)*) xtoString;\n\tStructFlags m_flags;\n\tvoid function(void*) xdtor;\n\tvoid function(void*) xpostblit;\n\tuint m_align;\n\tversion (X86_64)\n\t    TypeInfo m_arg1;\n\t    TypeInfo m_arg2;\n\timmutable(void)* xgetRTInfo;  */\n\n  void visit (TypeInfoStructDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Tstruct);\n    TypeStruct *ti = (TypeStruct *) d->tinfo;\n    StructDeclaration *sd = ti->sym;\n\n    /* The vtable for TypeInfo_Struct.  */\n    this->layout_base (Type::typeinfostruct);\n\n    if (!sd->members)\n      return;\n\n    /* Name of the struct declaration.  */\n    this->layout_string (sd->toPrettyChars ());\n\n    /* Default initializer for struct.  */\n    tree ptr = (sd->zeroInit) ? null_pointer_node\n      : build_address (aggregate_initializer_decl (sd));\n    this->layout_field (d_array_value (array_type_node,\n\t\t\t\t       size_int (sd->structsize), ptr));\n\n    /* hash_t function (in void*) xtoHash;  */\n    tree xhash = (sd->xhash) ? build_address (get_symbol_decl (sd->xhash))\n      : null_pointer_node;\n    this->layout_field (xhash);\n\n    if (sd->xhash)\n      {\n\tTypeFunction *tf = (TypeFunction *) sd->xhash->type;\n\tgcc_assert (tf->ty == Tfunction);\n\tif (!tf->isnothrow || tf->trust == TRUSTsystem)\n\t  {\n\t    warning (sd->xhash->loc, \"toHash() must be declared as \"\n\t\t     \"extern (D) size_t toHash() const nothrow @safe, \"\n\t\t     \"not %s\", tf->toChars ());\n\t  }\n      }\n\n    /* bool function(in void*, in void*) xopEquals;  */\n    tree xeq = (sd->xeq) ? build_address (get_symbol_decl (sd->xeq))\n      : null_pointer_node;\n    this->layout_field (xeq);\n\n    /* int function(in void*, in void*) xopCmp;  */\n    tree xcmp = (sd->xcmp) ? build_address (get_symbol_decl (sd->xcmp))\n      : null_pointer_node;\n    this->layout_field (xcmp);\n\n    /* string function(const(void)*) xtoString;  */\n    FuncDeclaration *fdx = search_toString (sd);\n    if (fdx)\n      this->layout_field (build_address (get_symbol_decl (fdx)));\n    else\n      this->layout_field (null_pointer_node);\n\n    /* StructFlags m_flags;  */\n    int m_flags = StructFlags::none;\n    if (ti->hasPointers ())\n      m_flags |= StructFlags::hasPointers;\n    this->layout_field (size_int (m_flags));\n\n    /* void function(void*) xdtor;  */\n    tree dtor = (sd->tidtor) ? build_address (get_symbol_decl (sd->tidtor))\n      : null_pointer_node;\n    this->layout_field (dtor);\n\n    /* void function(void*) xpostblit;  */\n    if (sd->postblit && !(sd->postblit->storage_class & STCdisable))\n      this->layout_field (build_address (get_symbol_decl (sd->postblit)));\n    else\n      this->layout_field (null_pointer_node);\n\n    /* uint m_align;  */\n    this->layout_field (size_int (ti->alignsize ()));\n\n    if (global.params.is64bit)\n      {\n\t/* TypeInfo m_arg1;  */\n\ttree arg1type = (sd->arg1type) ? build_typeinfo (d->loc, sd->arg1type)\n\t  : null_pointer_node;\n\tthis->layout_field (arg1type);\n\n\t/* TypeInfo m_arg2;  */\n\ttree arg2type = (sd->arg2type) ? build_typeinfo (d->loc, sd->arg2type)\n\t  : null_pointer_node;\n\tthis->layout_field (arg2type);\n      }\n\n    /* immutable(void)* xgetRTInfo;  */\n    if (sd->getRTInfo)\n      this->layout_field (build_expr (sd->getRTInfo, true));\n    else if (m_flags & StructFlags::hasPointers)\n      this->layout_field (size_one_node);\n  }\n\n  /* Layout of TypeInfo_Tuple is:\n\tvoid **__vptr;\n\tvoid *__monitor;\n\tTypeInfo[] elements;  */\n\n  void visit (TypeInfoTupleDeclaration *d)\n  {\n    gcc_assert (d->tinfo->ty == Ttuple);\n    TypeTuple *ti = (TypeTuple *) d->tinfo;\n\n    /* The vtable for TypeInfo_Tuple.  */\n    this->layout_base (Type::typeinfotypelist);\n\n    /* TypeInfo[] elements;  */\n    Type *satype = Type::tvoidptr->sarrayOf (ti->arguments->dim);\n    vec<constructor_elt, va_gc> *elms = NULL;\n    for (size_t i = 0; i < ti->arguments->dim; i++)\n      {\n\tParameter *arg = (*ti->arguments)[i];\n\tCONSTRUCTOR_APPEND_ELT (elms, size_int (i),\n\t\t\t\tbuild_typeinfo (d->loc, arg->type));\n      }\n    tree ctor = build_constructor (build_ctype (satype), elms);\n    tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor);\n\n    /* The internal pointer reference should be public, but not visible outside\n       the compilation unit, as it's referencing COMDAT decls.  */\n    TREE_PUBLIC (decl) = 1;\n    DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;\n    DECL_COMDAT (decl) = 1;\n\n    tree length = size_int (ti->arguments->dim);\n    tree ptr = build_address (decl);\n    this->layout_field (d_array_value (array_type_node, length, ptr));\n\n    d_pushdecl (decl);\n    rest_of_decl_compilation (decl, 1, 0);\n  }\n};\n\n\n/* Main entry point for TypeInfoVisitor interface to generate\n   TypeInfo constructor for the TypeInfoDeclaration AST class D.  */\n\ntree\nlayout_typeinfo (TypeInfoDeclaration *d)\n{\n  tree type = TREE_TYPE (get_typeinfo_decl (d));\n  TypeInfoVisitor v = TypeInfoVisitor (type);\n  d->accept (&v);\n  return v.result ();\n}\n\n/* Like layout_typeinfo, but generates the TypeInfo_Class for\n   the class or interface declaration CD.  */\n\ntree\nlayout_classinfo (ClassDeclaration *cd)\n{\n  TypeInfoClassDeclaration *d = TypeInfoClassDeclaration::create (cd->type);\n  tree type = TREE_TYPE (get_classinfo_decl (cd));\n  TypeInfoVisitor v = TypeInfoVisitor (type);\n  d->accept (&v);\n  return v.result ();\n}\n\n/* Layout fields that immediately come after the classinfo type for DECL if\n   there's any interfaces or interface vtables to be added.\n   This must be mirrored with base_vtable_offset().  */\n\nstatic tree\nlayout_classinfo_interfaces (ClassDeclaration *decl)\n{\n  tree type = tinfo_types[TK_CLASSINFO_TYPE];\n  size_t structsize = int_size_in_bytes (type);\n\n  if (decl->vtblInterfaces->dim)\n    {\n      size_t interfacesize = int_size_in_bytes (vtbl_interface_type_node);\n      tree field;\n\n      type = copy_aggregate_type (type);\n\n      /* First layout the static array of Interface, which provides information\n\t about the vtables that follow.  */\n      tree domain = size_int (decl->vtblInterfaces->dim - 1);\n      tree arrtype = build_array_type (vtbl_interface_type_node,\n\t\t\t\t       build_index_type (domain));\n      field = create_field_decl (arrtype, NULL, 1, 1);\n      insert_aggregate_field (type, field, structsize);\n      structsize += decl->vtblInterfaces->dim * interfacesize;\n\n      /* For each interface, layout each vtable.  */\n      for (size_t i = 0; i < decl->vtblInterfaces->dim; i++)\n\t{\n\t  BaseClass *b = (*decl->vtblInterfaces)[i];\n\t  ClassDeclaration *id = b->sym;\n\t  unsigned offset = base_vtable_offset (decl, b);\n\n\t  if (id->vtbl.dim && offset != ~0u)\n\t    {\n\t      tree vtbldomain = build_index_type (size_int (id->vtbl.dim - 1));\n\t      tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);\n\n\t      field = create_field_decl (vtbltype, NULL, 1, 1);\n\t      insert_aggregate_field (type, field, offset);\n\t      structsize += id->vtbl.dim * Target::ptrsize;\n\t    }\n\t}\n    }\n\n  /* Layout the arrays of overriding interface vtables.  */\n  for (ClassDeclaration *bcd = decl->baseClass; bcd; bcd = bcd->baseClass)\n    {\n      for (size_t i = 0; i < bcd->vtblInterfaces->dim; i++)\n\t{\n\t  BaseClass *b = (*bcd->vtblInterfaces)[i];\n\t  ClassDeclaration *id = b->sym;\n\t  unsigned offset = base_vtable_offset (decl, b);\n\n\t  if (id->vtbl.dim && offset != ~0u)\n\t    {\n\t      if (type == tinfo_types[TK_CLASSINFO_TYPE])\n\t\ttype = copy_aggregate_type (type);\n\n\t      tree vtbldomain = build_index_type (size_int (id->vtbl.dim - 1));\n\t      tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);\n\n\t      tree field = create_field_decl (vtbltype, NULL, 1, 1);\n\t      insert_aggregate_field (type, field, offset);\n\t      structsize += id->vtbl.dim * Target::ptrsize;\n\t    }\n\t}\n    }\n\n  /* Update the type size and record mode for the classinfo type.  */\n  if (type != tinfo_types[TK_CLASSINFO_TYPE])\n    finish_aggregate_type (structsize, TYPE_ALIGN_UNIT (type), type, NULL);\n\n  return type;\n}\n\n/* Returns true if the TypeInfo for TYPE should be placed in\n   the runtime library.  */\n\nstatic bool\nbuiltin_typeinfo_p (Type *type)\n{\n  if (type->isTypeBasic () || type->ty == Tclass || type->ty == Tnull)\n    return !type->mod;\n\n  if (type->ty == Tarray)\n    {\n      /* Strings are so common, make them builtin.  */\n      Type *next = type->nextOf ();\n      return !type->mod\n\t&& ((next->isTypeBasic () != NULL && !next->mod)\n\t    || (next->ty == Tchar && next->mod == MODimmutable)\n\t    || (next->ty == Tchar && next->mod == MODconst));\n    }\n\n  return false;\n}\n\n/* Implements a visitor interface to create the decl tree for TypeInfo decls.\n   TypeInfo_Class objects differ in that they also have information about\n   the class type packed immediately after the TypeInfo symbol.\n\n   If the frontend had an interface to allow distinguishing being these two\n   AST types, then that would be better for us.  */\n\nclass TypeInfoDeclVisitor : public Visitor\n{\n  using Visitor::visit;\n\npublic:\n  TypeInfoDeclVisitor (void)\n  {\n  }\n\n  void visit (TypeInfoDeclaration *tid)\n  {\n    tree ident = get_identifier (tid->ident->toChars ());\n    tree type = tinfo_types[get_typeinfo_kind (tid->tinfo)];\n    gcc_assert (type != NULL_TREE);\n\n    tid->csym = declare_extern_var (ident, type);\n    DECL_LANG_SPECIFIC (tid->csym) = build_lang_decl (tid);\n\n    DECL_CONTEXT (tid->csym) = d_decl_context (tid);\n    TREE_READONLY (tid->csym) = 1;\n\n    /* Built-in typeinfo will be referenced as one-only.  */\n    gcc_assert (!tid->isInstantiated ());\n\n    if (builtin_typeinfo_p (tid->tinfo))\n      d_linkonce_linkage (tid->csym);\n    else\n      d_comdat_linkage (tid->csym);\n  }\n\n  void visit (TypeInfoClassDeclaration *tid)\n  {\n    gcc_assert (tid->tinfo->ty == Tclass);\n    TypeClass *tc = (TypeClass *) tid->tinfo;\n    tid->csym = get_classinfo_decl (tc->sym);\n  }\n};\n\n/* Get the VAR_DECL of the TypeInfo for DECL.  If this does not yet exist,\n   create it.  The TypeInfo decl provides information about the type of a given\n   expression or object.  */\n\ntree\nget_typeinfo_decl (TypeInfoDeclaration *decl)\n{\n  if (decl->csym)\n    return decl->csym;\n\n  gcc_assert (decl->tinfo->ty != Terror);\n\n  TypeInfoDeclVisitor v = TypeInfoDeclVisitor ();\n  decl->accept (&v);\n  gcc_assert (decl->csym != NULL_TREE);\n\n  return decl->csym;\n}\n\n/* Get the VAR_DECL of the ClassInfo for DECL.  If this does not yet exist,\n   create it.  The ClassInfo decl provides information about the dynamic type\n   of a given class type or object.  */\n\ntree\nget_classinfo_decl (ClassDeclaration *decl)\n{\n  if (decl->csym)\n    return decl->csym;\n\n  InterfaceDeclaration *id = decl->isInterfaceDeclaration ();\n  tree ident = mangle_internal_decl (decl, id ? \"__Interface\" : \"__Class\", \"Z\");\n  tree type = layout_classinfo_interfaces (decl);\n\n  decl->csym = declare_extern_var (ident, type);\n  DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (NULL);\n\n  /* Class is a reference, want the record type.  */\n  DECL_CONTEXT (decl->csym) = TREE_TYPE (build_ctype (decl->type));\n  /* ClassInfo cannot be const data, because we use the monitor on it.  */\n  TREE_READONLY (decl->csym) = 0;\n\n  return decl->csym;\n}\n\n/* Returns typeinfo reference for TYPE.  */\n\ntree\nbuild_typeinfo (const Loc& loc, Type *type)\n{\n  if (!global.params.useTypeInfo)\n    {\n      static int warned = 0;\n\n      if (!warned)\n\t{\n\t  error_at (make_location_t (loc),\n\t\t    \"%<object.TypeInfo%> cannot be used with -fno-rtti\");\n\t  warned = 1;\n\t}\n    }\n\n  gcc_assert (type->ty != Terror);\n  create_typeinfo (type, NULL);\n  return build_address (get_typeinfo_decl (type->vtinfo));\n}\n\n/* Like layout_classinfo, but generates an Object that wraps around a\n   pointer to C++ type_info so it can be distinguished from D TypeInfo.  */\n\nvoid\nlayout_cpp_typeinfo (ClassDeclaration *cd)\n{\n  gcc_assert (cd->isCPPclass ());\n\n  tree decl = get_cpp_typeinfo_decl (cd);\n  vec<constructor_elt, va_gc> *init = NULL;\n\n  /* Use the vtable of __cpp_type_info_ptr, the EH personality routine\n     expects this, as it uses .classinfo identity comparison to test for\n     C++ catch handlers.  */\n  tree vptr = get_vtable_decl (ClassDeclaration::cpp_type_info_ptr);\n  CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (vptr));\n  CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, null_pointer_node);\n\n  /* Let C++ do the RTTI generation, and just reference the symbol as\n     extern, knowing the underlying type is not required.  */\n  const char *ident = Target::cppTypeInfoMangle (cd);\n  tree typeinfo = declare_extern_var (get_identifier (ident),\n\t\t\t\t      unknown_type_node);\n  TREE_READONLY (typeinfo) = 1;\n  CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (typeinfo));\n\n  /* Build the initializer and emit.  */\n  DECL_INITIAL (decl) = build_struct_literal (TREE_TYPE (decl), init);\n  DECL_EXTERNAL (decl) = 0;\n  d_pushdecl (decl);\n  rest_of_decl_compilation (decl, 1, 0);\n}\n\n/* Get the VAR_DECL of the __cpp_type_info_ptr for DECL.  If this does not yet\n   exist, create it.  The __cpp_type_info_ptr decl is then initialized with a\n   pointer to the C++ type_info for the given class.  */\n\ntree\nget_cpp_typeinfo_decl (ClassDeclaration *decl)\n{\n  gcc_assert (decl->isCPPclass ());\n\n  if (decl->cpp_type_info_ptr_sym)\n    return decl->cpp_type_info_ptr_sym;\n\n  if (!tinfo_types[TK_CPPTI_TYPE])\n    make_internal_typeinfo (TK_CPPTI_TYPE,\n\t\t\t    Identifier::idPool (\"__cpp_type_info_ptr\"),\n\t\t\t    ptr_type_node, NULL);\n\n  tree ident = mangle_internal_decl (decl, \"_cpp_type_info_ptr\", \"\");\n  tree type = tinfo_types[TK_CPPTI_TYPE];\n\n  decl->cpp_type_info_ptr_sym = declare_extern_var (ident, type);\n  DECL_LANG_SPECIFIC (decl->cpp_type_info_ptr_sym) = build_lang_decl (NULL);\n\n  /* Class is a reference, want the record type.  */\n  DECL_CONTEXT (decl->cpp_type_info_ptr_sym)\n    = TREE_TYPE (build_ctype (decl->type));\n  TREE_READONLY (decl->cpp_type_info_ptr_sym) = 1;\n\n  d_comdat_linkage (decl->cpp_type_info_ptr_sym);\n\n  /* Layout the initializer and emit the symbol.  */\n  layout_cpp_typeinfo (decl);\n\n  return decl->cpp_type_info_ptr_sym;\n}\n\n/* Get the exact TypeInfo for TYPE, if it doesn't exist, create it.  */\n\nvoid\ncreate_typeinfo (Type *type, Module *mod)\n{\n  /* Do this since not all Type's are merged.  */\n  Type *t = type->merge2 ();\n  Identifier *ident;\n\n  if (!t->vtinfo)\n    {\n      tinfo_kind tk = get_typeinfo_kind (t);\n      switch (tk)\n\t{\n\tcase TK_SHARED_TYPE:\n\tcase TK_CONST_TYPE:\n\tcase TK_IMMUTABLE_TYPE:\n\tcase TK_INOUT_TYPE:\n\tcase TK_POINTER_TYPE:\n\tcase TK_ARRAY_TYPE:\n\tcase TK_VECTOR_TYPE:\n\tcase TK_INTERFACE_TYPE:\n\t  /* Kinds of TypeInfo that add one extra pointer field.  */\n\t  if (tk == TK_SHARED_TYPE)\n\t    {\n\t      /* Does both 'shared' and 'shared const'.  */\n\t      t->vtinfo = TypeInfoSharedDeclaration::create (t);\n\t      ident = Identifier::idPool (\"TypeInfo_Shared\");\n\t    }\n\t  else if (tk == TK_CONST_TYPE)\n\t    {\n\t      t->vtinfo = TypeInfoConstDeclaration::create (t);\n\t      ident = Identifier::idPool (\"TypeInfo_Const\");\n\t    }\n\t  else if (tk == TK_IMMUTABLE_TYPE)\n\t    {\n\t      t->vtinfo = TypeInfoInvariantDeclaration::create (t);\n\t      ident = Identifier::idPool (\"TypeInfo_Invariant\");\n\t    }\n\t  else if (tk == TK_INOUT_TYPE)\n\t    {\n\t      t->vtinfo = TypeInfoWildDeclaration::create (t);\n\t      ident = Identifier::idPool (\"TypeInfo_Wild\");\n\t    }\n\t  else if (tk == TK_POINTER_TYPE)\n\t    {\n\t      t->vtinfo = TypeInfoPointerDeclaration::create (t);\n\t      ident = Identifier::idPool (\"TypeInfo_Pointer\");\n\t    }\n\t  else if (tk == TK_ARRAY_TYPE)\n\t    {\n\t      t->vtinfo = TypeInfoArrayDeclaration::create (t);\n\t      ident = Identifier::idPool (\"TypeInfo_Array\");\n\t    }\n\t  else if (tk == TK_VECTOR_TYPE)\n\t    {\n\t      t->vtinfo = TypeInfoVectorDeclaration::create (t);\n\t      ident = Identifier::idPool (\"TypeInfo_Vector\");\n\t    }\n\t  else if (tk == TK_INTERFACE_TYPE)\n\t    {\n\t      t->vtinfo = TypeInfoInterfaceDeclaration::create (t);\n\t      ident = Identifier::idPool (\"TypeInfo_Interface\");\n\t    }\n\t  else\n\t    gcc_unreachable ();\n\n\t  if (!tinfo_types[tk])\n\t    make_internal_typeinfo (tk, ident, ptr_type_node, NULL);\n\t  break;\n\n\tcase TK_STATICARRAY_TYPE:\n\t  if (!tinfo_types[tk])\n\t    {\n\t      ident = Identifier::idPool (\"TypeInfo_StaticArray\");\n\t      make_internal_typeinfo (tk, ident, ptr_type_node, size_type_node,\n\t\t\t\t      NULL);\n\t    }\n\t  t->vtinfo = TypeInfoStaticArrayDeclaration::create (t);\n\t  break;\n\n\tcase TK_ASSOCIATIVEARRAY_TYPE:\n\t  if (!tinfo_types[tk])\n\t    {\n\t      ident = Identifier::idPool (\"TypeInfo_AssociativeArray\");\n\t      make_internal_typeinfo (tk, ident, ptr_type_node, ptr_type_node,\n\t\t\t\t      NULL);\n\t    }\n\t  t->vtinfo = TypeInfoAssociativeArrayDeclaration::create (t);\n\t  break;\n\n\tcase TK_STRUCT_TYPE:\n\t  if (!tinfo_types[tk])\n\t    {\n\t      /* Some ABIs add extra TypeInfo fields on the end.  */\n\t      tree argtype = global.params.is64bit ? ptr_type_node : NULL_TREE;\n\n\t      ident = Identifier::idPool (\"TypeInfo_Struct\");\n\t      make_internal_typeinfo (tk, ident,\n\t\t\t\t      array_type_node, array_type_node,\n\t\t\t\t      ptr_type_node, ptr_type_node,\n\t\t\t\t      ptr_type_node, ptr_type_node,\n\t\t\t\t      size_type_node, ptr_type_node,\n\t\t\t\t      ptr_type_node, size_type_node,\n\t\t\t\t      ptr_type_node, argtype, argtype, NULL);\n\t    }\n\t  t->vtinfo = TypeInfoStructDeclaration::create (t);\n\t  break;\n\n\tcase TK_ENUMERAL_TYPE:\n\t  if (!tinfo_types[tk])\n\t    {\n\t      ident = Identifier::idPool (\"TypeInfo_Enum\");\n\t      make_internal_typeinfo (tk, ident,\n\t\t\t\t      ptr_type_node, array_type_node,\n\t\t\t\t      array_type_node, NULL);\n\t    }\n\t  t->vtinfo = TypeInfoEnumDeclaration::create (t);\n\t  break;\n\n\tcase TK_FUNCTION_TYPE:\n\tcase TK_DELEGATE_TYPE:\n\t  /* Functions and delegates share a common TypeInfo layout.  */\n\t  if (tk == TK_FUNCTION_TYPE)\n\t    {\n\t      t->vtinfo = TypeInfoFunctionDeclaration::create (t);\n\t      ident = Identifier::idPool (\"TypeInfo_Function\");\n\t    }\n\t  else if (tk == TK_DELEGATE_TYPE)\n\t    {\n\t      t->vtinfo = TypeInfoDelegateDeclaration::create (t);\n\t      ident = Identifier::idPool (\"TypeInfo_Delegate\");\n\t    }\n\t  else\n\t    gcc_unreachable ();\n\n\t  if (!tinfo_types[tk])\n\t    make_internal_typeinfo (tk, ident, ptr_type_node,\n\t\t\t\t    array_type_node, NULL);\n\t  break;\n\n\tcase TK_TYPELIST_TYPE:\n\t  if (!tinfo_types[tk])\n\t    {\n\t      ident = Identifier::idPool (\"TypeInfo_Tuple\");\n\t      make_internal_typeinfo (tk, ident, array_type_node, NULL);\n\t    }\n\t  t->vtinfo = TypeInfoTupleDeclaration::create (t);\n\t  break;\n\n\tcase TK_CLASSINFO_TYPE:\n\t  t->vtinfo = TypeInfoClassDeclaration::create (t);\n\t  break;\n\n\tdefault:\n\t  t->vtinfo = TypeInfoDeclaration::create (t);\n\t}\n      gcc_assert (t->vtinfo);\n\n      /* If this has a custom implementation in rt/typeinfo, then\n\t do not generate a COMDAT for it.  */\n      if (!builtin_typeinfo_p (t))\n\t{\n\t  /* Find module that will go all the way to an object file.  */\n\t  if (mod)\n\t    mod->members->push (t->vtinfo);\n\t  else\n\t    build_decl_tree (t->vtinfo);\n\t}\n    }\n  /* Types aren't merged, but we can share the vtinfo's.  */\n  if (!type->vtinfo)\n    type->vtinfo = t->vtinfo;\n\n  gcc_assert (type->vtinfo != NULL);\n}\n\n/* Implements a visitor interface to check whether a type is speculative.\n   TypeInfo_Struct would reference the members of the struct it is representing\n   (e.g: opEquals via xopEquals field), so if it's instantiated in speculative\n   context, TypeInfo creation should also be stopped to avoid possible\n   `unresolved symbol' linker errors.  */\n\nclass SpeculativeTypeVisitor : public Visitor\n{\n  using Visitor::visit;\n\n  bool result_;\n\npublic:\n  SpeculativeTypeVisitor (void)\n  {\n    this->result_ = false;\n  }\n\n  bool result (void)\n  {\n    return this->result_;\n  }\n\n  void visit (Type *t)\n  {\n    Type *tb = t->toBasetype ();\n    if (tb != t)\n      tb->accept (this);\n  }\n\n  void visit (TypeNext *t)\n  {\n    if (t->next)\n      t->next->accept (this);\n  }\n\n  void visit (TypeBasic *)\n  {\n  }\n\n  void visit (TypeVector *t)\n  {\n    t->basetype->accept (this);\n  }\n\n  void visit (TypeAArray *t)\n  {\n    t->index->accept (this);\n    visit ((TypeNext *)t);\n  }\n\n  void visit (TypeFunction *t)\n  {\n    visit ((TypeNext *)t);\n  }\n\n  void visit (TypeStruct *t)\n  {\n    StructDeclaration *sd = t->sym;\n    if (TemplateInstance *ti = sd->isInstantiated ())\n      {\n\tif (!ti->needsCodegen ())\n\t  {\n\t    if (ti->minst || sd->requestTypeInfo)\n\t      return;\n\n\t    this->result_ |= true;\n\t  }\n      }\n  }\n\n  void visit (TypeClass *t)\n  {\n    ClassDeclaration *cd = t->sym;\n    if (TemplateInstance *ti = cd->isInstantiated ())\n      {\n\tif (!ti->needsCodegen () && !ti->minst)\n\t  {\n\t    this->result_ |= true;\n\t  }\n      }\n  }\n\n  void visit (TypeTuple *t)\n  {\n    if (!t->arguments)\n      return;\n\n    for (size_t i = 0; i < t->arguments->dim; i++)\n      {\n\tType *tprm = (*t->arguments)[i]->type;\n\tif (tprm)\n\t  tprm->accept (this);\n\tif (this->result_)\n\t  return;\n      }\n  }\n};\n\n/* Return true if type was instantiated in a speculative context.  */\n\nbool\nspeculative_type_p (Type *t)\n{\n  SpeculativeTypeVisitor v = SpeculativeTypeVisitor ();\n  t->accept (&v);\n  return v.result ();\n}\n\n#include \"gt-d-typeinfo.h\"\n"
  },
  {
    "path": "gcc/d/types.cc",
    "content": "/* types.cc -- Lower D frontend types to GCC trees.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3, or (at your option)\nany later version.\n\nGCC is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GCC; see the file COPYING3.  If not see\n<http://www.gnu.org/licenses/>.  */\n\n#include \"config.h\"\n#include \"system.h\"\n#include \"coretypes.h\"\n\n#include \"dmd/attrib.h\"\n#include \"dmd/aggregate.h\"\n#include \"dmd/enum.h\"\n#include \"dmd/expression.h\"\n#include \"dmd/identifier.h\"\n#include \"dmd/mtype.h\"\n#include \"dmd/target.h\"\n\n#include \"tree.h\"\n#include \"fold-const.h\"\n#include \"diagnostic.h\"\n#include \"langhooks.h\"\n#include \"tm.h\"\n#include \"function.h\"\n#include \"toplev.h\"\n#include \"target.h\"\n#include \"stringpool.h\"\n#include \"stor-layout.h\"\n#include \"attribs.h\"\n\n#include \"d-tree.h\"\n\n\n/* Return TRUE if TYPE is a static array va_list.  This is for compatibility\n   with the C ABI, where va_list static arrays are passed by reference.\n   However for every other case in D, static arrays are passed by value.  */\n\nbool\nvalist_array_p (Type *type)\n{\n  if (Type::tvalist->ty == Tsarray)\n    {\n      Type *tb = type->toBasetype ();\n      if (same_type_p (tb, Type::tvalist))\n\treturn true;\n    }\n\n  return false;\n}\n\n/* Returns true if TYPE contains no actual data, just various\n   possible combinations of empty aggregates.  */\n\nbool\nempty_aggregate_p (tree type)\n{\n  if (!AGGREGATE_TYPE_P (type))\n    return false;\n\n  /* Want the element type for arrays.  */\n  if (TREE_CODE (type) == ARRAY_TYPE)\n    return empty_aggregate_p (TREE_TYPE (type));\n\n  /* Recursively check all fields.  */\n  for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))\n    {\n      if (TREE_CODE (field) == FIELD_DECL\n\t  && !empty_aggregate_p (TREE_TYPE (field)))\n\treturn false;\n    }\n\n  return true;\n}\n\n/* Returns true if T1 and T2 are related to each other.  */\n\nbool\nsame_type_p (Type *t1, Type *t2)\n{\n  /* Types are equal.  */\n  if (t1 == t2)\n    return true;\n\n  /* Types derive from the same base.  */\n  Type *tb1 = t1->toBasetype ();\n  Type *tb2 = t2->toBasetype ();\n  if (tb1 == tb2)\n    return true;\n\n  /* Types are mutably the same type.  */\n  if (tb1->ty == tb2->ty && tb1->equivalent (tb2))\n    return true;\n\n  return false;\n}\n\n/* Returns 'Object' type which all D classes are derived from.  */\n\nType *\nget_object_type (void)\n{\n  if (ClassDeclaration::object)\n    return ClassDeclaration::object->type;\n\n  error (\"missing or corrupt object.d\");\n  return Type::terror;\n}\n\n\n/* Returns a static array of TYPE which has SIZE number of elements.  */\n\ntree\nmake_array_type (Type *type, unsigned HOST_WIDE_INT size)\n{\n  /* In [arrays/void-arrays], void arrays can also be static, the length is\n     specified in bytes.  */\n  if (type->toBasetype ()->ty == Tvoid)\n    type = Type::tuns8;\n\n  /* In [arrays/static-arrays], a static array with a dimension of 0 is allowed,\n     but no space is allocated for it.  */\n  if (size == 0)\n    {\n      tree range = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),\n\t\t\t\t\t\t   TYPE_UNSIGNED (sizetype));\n      tree index = build_range_type (range, size_zero_node, NULL_TREE);\n\n      tree t = build_array_type (build_ctype (type), index);\n      TYPE_SIZE (t) = bitsize_zero_node;\n      TYPE_SIZE_UNIT (t) = size_zero_node;\n      return t;\n    }\n\n  return build_array_type (build_ctype (type),\n\t\t\t   build_index_type (size_int (size - 1)));\n}\n\n/* Builds a record type whose name is NAME.  NFIELDS is the number of fields,\n   provided as field ident/type pairs.  */\n\ntree\nmake_struct_type (const char *name, int nfields, ...)\n{\n  tree fields = NULL_TREE;\n  va_list ap;\n\n  va_start (ap, nfields);\n\n  for (int i = 0; i < nfields; i++)\n    {\n      tree ident = va_arg (ap, tree);\n      tree type = va_arg (ap, tree);\n      tree field = build_decl (BUILTINS_LOCATION, FIELD_DECL, ident, type);\n      DECL_CHAIN (field) = fields;\n      fields = field;\n    }\n\n  va_end (ap);\n\n  tree type = make_node (RECORD_TYPE);\n  finish_builtin_struct (type, name, fields, NULL_TREE);\n\n  return type;\n}\n\n/* Return qualified type variant of TYPE determined by modifier value MOD.  */\n\ntree\ninsert_type_modifiers (tree type, unsigned mod)\n{\n  int quals = 0;\n\n  switch (mod)\n    {\n    case MODconst:\n    case MODwild:\n    case MODwildconst:\n    case MODimmutable:\n    case MODshared | MODconst:\n    case MODshared | MODwild:\n    case MODshared | MODwildconst:\n      quals |= TYPE_QUAL_CONST;\n      break;\n\n    case 0:\n    case MODshared:\n      break;\n\n    default:\n      gcc_unreachable ();\n    }\n\n  tree qualtype = build_qualified_type (type, quals);\n\n  /* Mark whether the type is qualified 'shared'.  */\n  if (mod & MODshared)\n    TYPE_SHARED (qualtype) = 1;\n\n  return qualtype;\n}\n\n/* Adds FIELD into the aggregate TYPE at OFFSET.  */\n\nvoid\ninsert_aggregate_field (tree type, tree field, size_t offset)\n{\n  DECL_FIELD_CONTEXT (field) = type;\n  SET_DECL_OFFSET_ALIGN (field, TYPE_ALIGN (TREE_TYPE (field)));\n  DECL_FIELD_OFFSET (field) = size_int (offset);\n  DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;\n\n  TREE_ADDRESSABLE (field) = TYPE_SHARED (TREE_TYPE (field));\n\n  layout_decl (field, 0);\n  TYPE_FIELDS (type) = chainon (TYPE_FIELDS (type), field);\n}\n\n/* For all decls in the FIELDS chain, adjust their field offset by OFFSET.\n   This is done as the frontend puts fields into the outer struct, and so\n   their offset is from the beginning of the aggregate.\n   We want the offset to be from the beginning of the anonymous aggregate.  */\n\nstatic void\nfixup_anonymous_offset (tree fields, tree offset)\n{\n  while (fields != NULL_TREE)\n    {\n      /* Traverse all nested anonymous aggregates to update their offset.\n\t Set the anonymous decl offset to its first member.  */\n      tree ftype = TREE_TYPE (fields);\n      if (TYPE_NAME (ftype) && anon_aggrname_p (TYPE_IDENTIFIER (ftype)))\n\t{\n\t  tree vfields = TYPE_FIELDS (ftype);\n\t  fixup_anonymous_offset (vfields, offset);\n\t  DECL_FIELD_OFFSET (fields) = DECL_FIELD_OFFSET (vfields);\n\t}\n      else\n\t{\n\t  tree voffset = DECL_FIELD_OFFSET (fields);\n\t  DECL_FIELD_OFFSET (fields) = size_binop (MINUS_EXPR, voffset, offset);\n\t}\n\n      fields = DECL_CHAIN (fields);\n    }\n}\n\n/* Iterate over all MEMBERS of an aggregate, and add them as fields to CONTEXT.\n   If INHERITED_P is true, then the members derive from a base class.\n   Returns the number of fields found.  */\n\nstatic size_t\nlayout_aggregate_members (Dsymbols *members, tree context, bool inherited_p)\n{\n  size_t fields = 0;\n\n  for (size_t i = 0; i < members->dim; i++)\n    {\n      Dsymbol *sym = (*members)[i];\n      VarDeclaration *var = sym->isVarDeclaration ();\n      if (var != NULL)\n\t{\n\t  /* Skip fields that have already been added.  */\n\t  if (!inherited_p && var->csym != NULL)\n\t    continue;\n\n\t  /* If this variable was really a tuple, add all tuple fields.  */\n\t  if (var->aliassym)\n\t    {\n\t      TupleDeclaration *td = var->aliassym->isTupleDeclaration ();\n\t      Dsymbols tmembers;\n\t      /* No other way to coerce the underlying type out of the tuple.\n\t\t Frontend should have already validated this.  */\n\t      for (size_t j = 0; j < td->objects->dim; j++)\n\t\t{\n\t\t  RootObject *ro = (*td->objects)[j];\n\t\t  gcc_assert (ro->dyncast () == DYNCAST_EXPRESSION);\n\t\t  Expression *e = (Expression *) ro;\n\t\t  gcc_assert (e->op == TOKdsymbol);\n\t\t  DsymbolExp *se = (DsymbolExp *) e;\n\n\t\t  tmembers.push (se->s);\n\t\t}\n\n\t      fields += layout_aggregate_members (&tmembers, context,\n\t\t\t\t\t\t  inherited_p);\n\t      continue;\n\t    }\n\n\t  /* Insert the field declaration at its given offset.  */\n\t  if (var->isField ())\n\t    {\n\t      const char *ident = var->ident ? var->ident->toChars () : NULL;\n\t      tree field = create_field_decl (declaration_type (var), ident,\n\t\t\t\t\t      inherited_p, inherited_p);\n\t      insert_aggregate_field (context, field, var->offset);\n\n\t      /* Because the front-end shares field decls across classes, don't\n\t\t create the corresponding back-end symbol unless we are adding\n\t\t it to the aggregate it is defined in.  */\n\t      if (!inherited_p)\n\t\t{\n\t\t  DECL_LANG_SPECIFIC (field) = build_lang_decl (var);\n\t\t  var->csym = field;\n\t\t}\n\n\t      fields += 1;\n\t      continue;\n\t    }\n\t}\n\n      /* Anonymous struct/union are flattened by the frontend.  However, we\n\t want to keep the record layout in-tact when building the type.  */\n      AnonDeclaration *ad = sym->isAnonDeclaration ();\n      if (ad != NULL)\n\t{\n\t  /* Use a counter to create anonymous type names.  */\n\t  static int anon_cnt = 0;\n\t  char buf[32];\n\t  sprintf (buf, anon_aggrname_format (), anon_cnt++);\n\n\t  tree ident = get_identifier (buf);\n\t  tree type = make_node (ad->isunion ? UNION_TYPE : RECORD_TYPE);\n\t  ANON_AGGR_TYPE_P (type) = 1;\n\t  d_keep (type);\n\n\t  /* Build the type declaration.  */\n\t  tree decl = build_decl (make_location_t (ad->loc),\n\t\t\t\t  TYPE_DECL, ident, type);\n\t  DECL_CONTEXT (decl) = context;\n\t  DECL_ARTIFICIAL (decl) = 1;\n\n\t  TYPE_CONTEXT (type) = context;\n\t  TYPE_NAME (type) = decl;\n\t  TYPE_STUB_DECL (type) = decl;\n\n\t  /* Recursively iterator over the anonymous members.  */\n\t  fields += layout_aggregate_members (ad->decl, type, inherited_p);\n\n\t  /* Remove from the anon fields the base offset of this anonymous\n\t     aggregate.  Undoes what is set-up in setFieldOffset, but doesn't\n\t     affect field accesses.  */\n\t  tree offset = size_int (ad->anonoffset);\n\t  fixup_anonymous_offset (TYPE_FIELDS (type), offset);\n\n\t  finish_aggregate_type (ad->anonstructsize, ad->anonalignsize,\n\t\t\t\t type, NULL);\n\n\t  /* And make the corresponding data member.  */\n\t  tree field = create_field_decl (type, NULL, 0, 0);\n\t  insert_aggregate_field (context, field, ad->anonoffset);\n\t  continue;\n\t}\n\n      /* Other kinds of attributes don't create a scope.  */\n      AttribDeclaration *attrib = sym->isAttribDeclaration ();\n      if (attrib != NULL)\n\t{\n\t  Dsymbols *decls = attrib->include (NULL);\n\t  if (decls != NULL)\n\t    {\n\t      fields += layout_aggregate_members (decls, context, inherited_p);\n\t      continue;\n\t    }\n\t}\n\n      /* Same with template mixins and namespaces.  */\n      if (sym->isTemplateMixin () || sym->isNspace ())\n\t{\n\t  ScopeDsymbol *scopesym = sym->isScopeDsymbol ();\n\t  if (scopesym->members)\n\t    {\n\t      fields += layout_aggregate_members (scopesym->members, context,\n\t\t\t\t\t\t  inherited_p);\n\t      continue;\n\t    }\n\t}\n    }\n\n  return fields;\n}\n\n/* Write out all fields for aggregate BASE.  For classes, write out all\n   interfaces first, then the base class fields.  */\n\nstatic void\nlayout_aggregate_type (AggregateDeclaration *decl, tree type,\n\t\t       AggregateDeclaration *base)\n{\n  ClassDeclaration *cd = base->isClassDeclaration ();\n  bool inherited_p = (decl != base);\n\n  if (cd != NULL)\n    {\n      if (cd->baseClass)\n\tlayout_aggregate_type (decl, type, cd->baseClass);\n      else\n\t{\n\t  /* This is the base class (Object) or interface.  */\n\t  tree objtype = TREE_TYPE (build_ctype (cd->type));\n\n\t  /* Add the vtable pointer, and optionally the monitor fields.  */\n\t  InterfaceDeclaration *id = cd->isInterfaceDeclaration ();\n\t  if (!id || id->vtblInterfaces->dim == 0)\n\t    {\n\t      tree field = create_field_decl (vtbl_ptr_type_node, \"__vptr\", 1,\n\t\t\t\t\t      inherited_p);\n\t      DECL_VIRTUAL_P (field) = 1;\n\t      TYPE_VFIELD (type) = field;\n\t      DECL_FCONTEXT (field) = objtype;\n\t      insert_aggregate_field (type, field, 0);\n\t    }\n\n\t  if (!id && !cd->isCPPclass ())\n\t    {\n\t      tree field = create_field_decl (ptr_type_node, \"__monitor\", 1,\n\t\t\t\t\t      inherited_p);\n\t      insert_aggregate_field (type, field, Target::ptrsize);\n\t    }\n\t}\n\n      if (cd->vtblInterfaces)\n\t{\n\t  for (size_t i = 0; i < cd->vtblInterfaces->dim; i++)\n\t    {\n\t      BaseClass *bc = (*cd->vtblInterfaces)[i];\n\t      tree field = create_field_decl (vtbl_ptr_type_node, NULL, 1, 1);\n\t      insert_aggregate_field (type, field, bc->offset);\n\t    }\n\t}\n    }\n\n  if (base->members)\n    {\n      size_t fields = layout_aggregate_members (base->members, type,\n\t\t\t\t\t\tinherited_p);\n      gcc_assert (fields == base->fields.dim);\n\n      /* Make sure that all fields have been created.  */\n      if (!inherited_p)\n\t{\n\t  for (size_t i = 0; i < base->fields.dim; i++)\n\t    {\n\t      VarDeclaration *var = base->fields[i];\n\t      gcc_assert (var->csym != NULL);\n\t    }\n\t}\n    }\n}\n\n/* Given a record type TYPE, whose size and alignment are determined by\n   STRUCTSIZE and ALIGNSIZE.  Apply any type attributes ATTRS and compute\n   the finalized record mode.  */\n\nvoid\nfinish_aggregate_type (unsigned structsize, unsigned alignsize,\n\t\t       tree type, UserAttributeDeclaration *attrs)\n{\n  TYPE_SIZE (type) = NULL_TREE;\n\n  /* Write out any GCC attributes that were applied to the type declaration.  */\n  if (attrs)\n    {\n      Expressions *eattrs = attrs->getAttributes ();\n      decl_attributes (&type, build_attributes (eattrs),\n\t\t       ATTR_FLAG_TYPE_IN_PLACE);\n    }\n\n  /* Set size and alignment as requested by frontend.  */\n  TYPE_SIZE (type) = bitsize_int (structsize * BITS_PER_UNIT);\n  TYPE_SIZE_UNIT (type) = size_int (structsize);\n  SET_TYPE_ALIGN (type, alignsize * BITS_PER_UNIT);\n  TYPE_PACKED (type) = (alignsize == 1);\n\n  /* Set the back-end type mode.  */\n  compute_record_mode (type);\n\n  /* Fix up all variants of this aggregate type.  */\n  for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))\n    {\n      if (t == type)\n\tcontinue;\n\n      TYPE_FIELDS (t) = TYPE_FIELDS (type);\n      TYPE_LANG_SPECIFIC (t) = TYPE_LANG_SPECIFIC (type);\n      SET_TYPE_ALIGN (t, TYPE_ALIGN (type));\n      TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (type);\n      gcc_assert (TYPE_MODE (t) == TYPE_MODE (type));\n    }\n}\n\n\n/* Implements the visitor interface to build the GCC trees of all\n   Type AST classes emitted from the D Front-end, where CTYPE holds\n   the cached back-end representation to be returned.  */\n\nclass TypeVisitor : public Visitor\n{\n  using Visitor::visit;\n\npublic:\n  TypeVisitor (void)\n  {\n  }\n\n  /* This should be overridden by each type class.  */\n\n  void visit (Type *)\n  {\n    gcc_unreachable ();\n  }\n\n  /* Type assigned to erroneous expressions or constructs that\n     failed during the semantic stage.  */\n\n  void visit (TypeError *t)\n  {\n    t->ctype = error_mark_node;\n  }\n\n  /* Type assigned to generic nullable types.  */\n\n  void visit (TypeNull *t)\n  {\n    t->ctype = ptr_type_node;\n  }\n\n\n  /* Basic Data Types.  */\n\n  void visit (TypeBasic *t)\n  {\n    /* [type/basic-data-types]\n\n       void\tno type.\n       bool\t8-bit boolean value.\n       byte\t8-bit signed value.\n       ubyte\t8-bit unsigned value.\n       short\t16-bit signed value.\n       ushort\t16-bit unsigned value.\n       int\t32-bit signed value.\n       uint\t32-bit unsigned value.\n       long\t64-bit signed value.\n       ulong\t64-bit unsigned value.\n       cent\t128-bit signed value.\n       ucent\t128-bit unsigned value.\n       float\t32-bit IEEE 754 floating-point value.\n       double\t64-bit IEEE 754 floating-point value.\n       real\tlargest FP size implemented in hardware.\n       ifloat\timaginary float.\n       idouble\timaginary double.\n       ireal\timaginary real.\n       cfloat\tcomplex float.\n       cdouble\tcomplex double.\n       creal\tcomplex real.\n       char\tUTF-8 code unit.\n       wchar\tUTF-16 code unit.\n       dchar\tUTF-32 code unit.  */\n\n    switch (t->ty)\n      {\n      case Tvoid:\t  t->ctype = void_type_node; break;\n      case Tbool:\t  t->ctype = d_bool_type; break;\n      case Tint8:\t  t->ctype = d_byte_type; break;\n      case Tuns8:\t  t->ctype = d_ubyte_type; break;\n      case Tint16:\t  t->ctype = d_short_type; break;\n      case Tuns16:\t  t->ctype = d_ushort_type; break;\n      case Tint32:\t  t->ctype = d_int_type; break;\n      case Tuns32:\t  t->ctype = d_uint_type; break;\n      case Tint64:\t  t->ctype = d_long_type; break;\n      case Tuns64:\t  t->ctype = d_ulong_type; break;\n      case Tint128:\t  t->ctype = d_cent_type; break;\n      case Tuns128:\t  t->ctype = d_ucent_type; break;\n      case Tfloat32:\t  t->ctype = float_type_node; break;\n      case Tfloat64:\t  t->ctype = double_type_node; break;\n      case Tfloat80:\t  t->ctype = long_double_type_node; break;\n      case Timaginary32:  t->ctype = ifloat_type_node; break;\n      case Timaginary64:  t->ctype = idouble_type_node; break;\n      case Timaginary80:  t->ctype = ireal_type_node; break;\n      case Tcomplex32:\t  t->ctype = complex_float_type_node; break;\n      case Tcomplex64:\t  t->ctype = complex_double_type_node; break;\n      case Tcomplex80:\t  t->ctype = complex_long_double_type_node; break;\n      case Tchar:\t  t->ctype = char8_type_node; break;\n      case Twchar:\t  t->ctype = char16_type_node; break;\n      case Tdchar:\t  t->ctype = char32_type_node; break;\n      default:\t\t  gcc_unreachable ();\n      }\n\n    TYPE_NAME (t->ctype) = get_identifier (t->toChars ());\n  }\n\n\n  /* Derived Data Types.  */\n\n  /* Build a simple pointer to data type, analogous to C pointers.  */\n\n  void visit (TypePointer *t)\n  {\n    t->ctype = build_pointer_type (build_ctype (t->next));\n  }\n\n  /* Build a dynamic array type, consisting of a length and a pointer\n     to the array data.  */\n\n  void visit (TypeDArray *t)\n  {\n    /* In [abi/arrays], dynamic array layout is:\n\t.length\tarray dimension.\n\t.ptr\tpointer to array data.  */\n    t->ctype = make_struct_type (t->toChars (), 2,\n\t\t\t\t get_identifier (\"length\"),\n\t\t\t\t build_ctype (Type::tsize_t),\n\t\t\t\t get_identifier (\"ptr\"),\n\t\t\t\t build_pointer_type (build_ctype (t->next)));\n    TYPE_DYNAMIC_ARRAY (t->ctype) = 1;\n    TYPE_LANG_SPECIFIC (t->ctype) = build_lang_type (t);\n    d_keep (t->ctype);\n  }\n\n  /* Build a static array type, distinguished from dynamic arrays by\n     having a length fixed at compile-time, analogous to C arrays.  */\n\n  void visit (TypeSArray *t)\n  {\n    if (t->dim->isConst () && t->dim->type->isintegral ())\n      {\n\tuinteger_t size = t->dim->toUInteger ();\n\tt->ctype = make_array_type (t->next, size);\n      }\n    else\n      {\n\terror (\"invalid expression for static array dimension: %s\",\n\t       t->dim->toChars ());\n\tgcc_unreachable ();\n      }\n  }\n\n  /* Build a vector type, a fixed array of floating or integer types.  */\n\n  void visit (TypeVector *t)\n  {\n    int nunits = ((TypeSArray *) t->basetype)->dim->toUInteger ();\n    tree inner = build_ctype (t->elementType ());\n\n    /* Same rationale as void static arrays.  */\n    if (inner == void_type_node)\n      inner = build_ctype (Type::tuns8);\n\n    t->ctype = build_vector_type (inner, nunits);\n    TYPE_NAME (t->ctype) = get_identifier (t->toChars ());\n    layout_type (t->ctype);\n  }\n\n  /* Build an associative array type, distinguished from arrays by having an\n     index that's not necessarily an integer, and can be sparsely populated.  */\n\n  void visit (TypeAArray *t)\n  {\n    /* In [abi/associative-arrays], associative arrays are a struct that only\n       consist of a pointer to an opaque, implementation defined type.  */\n    t->ctype = make_struct_type (t->toChars (), 1,\n\t\t\t\t get_identifier (\"ptr\"), ptr_type_node);\n    TYPE_ASSOCIATIVE_ARRAY (t->ctype) = 1;\n    TYPE_LANG_SPECIFIC (t->ctype) = build_lang_type (t);\n    d_keep (t->ctype);\n  }\n\n  /* Build type for a function declaration, which consists of a return type,\n     and a list of parameter types, and a linkage attribute.  */\n\n  void visit (TypeFunction *t)\n  {\n    tree fnparams = NULL_TREE;\n    tree fntype;\n\n    /* [function/variadic]\n\n       Variadic functions with D linkage have an additional hidden argument\n       with the name _arguments passed to the function.  */\n    if (t->varargs == 1 && t->linkage == LINKd)\n      {\n\ttree type = build_ctype (Type::typeinfotypelist->type);\n\tfnparams = chainon (fnparams, build_tree_list (0, type));\n      }\n\n    if (t->parameters)\n      {\n\tsize_t n_args = Parameter::dim (t->parameters);\n\n\tfor (size_t i = 0; i < n_args; i++)\n\t  {\n\t    tree type = type_passed_as (Parameter::getNth (t->parameters, i));\n\t    fnparams = chainon (fnparams, build_tree_list (0, type));\n\t  }\n      }\n\n    /* When the last parameter is void_list_node, that indicates a fixed length\n       parameter list, otherwise function is treated as variadic.  */\n    if (t->varargs != 1)\n      fnparams = chainon (fnparams, void_list_node);\n\n    if (t->next != NULL)\n      {\n\tfntype = build_ctype (t->next);\n\tif (t->isref)\n\t  fntype = build_reference_type (fntype);\n      }\n    else\n      fntype = void_type_node;\n\n    /* Could the function type be self referenced by parameters?  */\n    t->ctype = build_function_type (fntype, fnparams);\n    TYPE_LANG_SPECIFIC (t->ctype) = build_lang_type (t);\n    d_keep (t->ctype);\n\n    /* Handle any special support for calling conventions.  */\n    switch (t->linkage)\n      {\n      case LINKpascal:\n      case LINKwindows:\n\t/* [attribute/linkage]\n\n\t   The Windows convention is distinct from the C convention only\n\t   on Win32, where it is equivalent to the stdcall convention.  */\n\tif (!global.params.is64bit)\n\t  t->ctype = insert_type_attribute (t->ctype, \"stdcall\");\n\tbreak;\n\n      case LINKc:\n      case LINKcpp:\n      case LINKd:\n      case LINKobjc:\n\t/* [abi/function-calling-conventions]\n\n\t  The extern (C) and extern (D) calling convention matches\n\t  the C calling convention used by the supported C compiler\n\t  on the host system.  */\n\tbreak;\n\n      default:\n\tgcc_unreachable ();\n      }\n  }\n\n  /* Build a delegate type, an aggregate of two pieces of data, an object\n     reference and a pointer to a non-static member function, or a pointer\n     to a closure and a pointer to a nested function.  */\n\n  void visit (TypeDelegate *t)\n  {\n    /* In [abi/delegates], delegate layout is:\n\t.ptr\t    context pointer.\n\t.funcptr    pointer to function.  */\n    tree fntype = build_ctype (t->next);\n    tree dgtype = build_vthis_function (void_type_node, fntype);\n\n    TYPE_ATTRIBUTES (dgtype) = TYPE_ATTRIBUTES (fntype);\n    TYPE_LANG_SPECIFIC (dgtype) = TYPE_LANG_SPECIFIC (fntype);\n\n    t->ctype = make_struct_type (t->toChars (), 2,\n\t\t\t\t get_identifier (\"ptr\"),\n\t\t\t\t build_ctype (Type::tvoidptr),\n\t\t\t\t get_identifier (\"funcptr\"),\n\t\t\t\t build_pointer_type (dgtype));\n    TYPE_DELEGATE (t->ctype) = 1;\n    TYPE_LANG_SPECIFIC (t->ctype) = build_lang_type (t);\n    d_keep (t->ctype);\n  }\n\n\n  /* User Defined Types.  */\n\n  /* Build a named enum type, a distinct value whose values are restrict to\n     a group of constants of the same underlying base type.  */\n\n  void visit (TypeEnum *t)\n  {\n    tree basetype = (t->sym->memtype)\n      ? build_ctype (t->sym->memtype) : void_type_node;\n\n    if (!INTEGRAL_TYPE_P (basetype) || TREE_CODE (basetype) == BOOLEAN_TYPE)\n      {\n\t/* Enums in D2 can have a base type that is not necessarily integral.\n\t   For these, we simplify this a little by using the base type directly\n\t   instead of building an ENUMERAL_TYPE.  */\n\tt->ctype = build_variant_type_copy (basetype);\n      }\n    else\n      {\n\tt->ctype = make_node (ENUMERAL_TYPE);\n\tENUM_IS_SCOPED (t->ctype) = 1;\n\tTYPE_LANG_SPECIFIC (t->ctype) = build_lang_type (t);\n\td_keep (t->ctype);\n\n\tif (flag_short_enums)\n\t  TYPE_PACKED (t->ctype) = 1;\n\n\tTYPE_PRECISION (t->ctype) = t->size (t->sym->loc) * 8;\n\tTYPE_SIZE (t->ctype) = 0;\n\n\tTYPE_MIN_VALUE (t->ctype) = TYPE_MIN_VALUE (basetype);\n\tTYPE_MAX_VALUE (t->ctype) = TYPE_MAX_VALUE (basetype);\n\tlayout_type (t->ctype);\n\n\ttree values = NULL_TREE;\n\tif (t->sym->members)\n\t  {\n\t    for (size_t i = 0; i < t->sym->members->dim; i++)\n\t      {\n\t\tEnumMember *member = (*t->sym->members)[i]->isEnumMember ();\n\t\t/* Templated functions can seep through to the back-end\n\t\t   just ignore for now.  */\n\t\tif (member == NULL)\n\t\t  continue;\n\n\t\ttree ident = get_identifier (member->ident->toChars ());\n\t\ttree value = build_integer_cst (member->value ()->toInteger (),\n\t\t\t\t\t\tbasetype);\n\n\t\t/* Build an identifier for the enumeration constant.  */\n\t\ttree decl = build_decl (make_location_t (member->loc),\n\t\t\t\t\tCONST_DECL, ident, basetype);\n\t\tDECL_CONTEXT (decl) = t->ctype;\n\t\tTREE_CONSTANT (decl) = 1;\n\t\tTREE_READONLY (decl) = 1;\n\t\tDECL_INITIAL (decl) = value;\n\n\t\t/* Add this enumeration constant to the list for this type.  */\n\t\tvalues = chainon (values, build_tree_list (ident, decl));\n\t      }\n\t  }\n\n\tTYPE_VALUES (t->ctype) = values;\n\tTYPE_UNSIGNED (t->ctype) = TYPE_UNSIGNED (basetype);\n\tbuild_type_decl (t->ctype, t->sym);\n      }\n\n    if (t->sym->userAttribDecl)\n      {\n\tExpressions *eattrs = t->sym->userAttribDecl->getAttributes ();\n\tdecl_attributes (&t->ctype, build_attributes (eattrs),\n\t\t\t ATTR_FLAG_TYPE_IN_PLACE);\n      }\n  }\n\n  /* Build a struct or union type.  Layout should be exactly represented\n     as an equivalent C struct, except for non-POD or nested structs.  */\n\n  void visit (TypeStruct *t)\n  {\n    /* Merge types in the back-end if the frontend did not itself do so.  */\n    tree deco = get_identifier (mangle_decl (t->sym));\n    if (IDENTIFIER_DAGGREGATE (deco))\n      {\n\tAggregateDeclaration *ad = IDENTIFIER_DAGGREGATE (deco);\n\tgcc_assert (ad->isStructDeclaration ());\n\n\t/* Non-templated variables shouldn't be defined twice.  */\n\tif (!t->sym->isInstantiated ())\n\t  ScopeDsymbol::multiplyDefined (t->sym->loc, t->sym, ad);\n\n\tt->ctype = build_ctype (ad->type);\n\treturn;\n      }\n\n    /* Need to set this right away in case of self-references.  */\n    t->ctype = make_node (t->sym->isUnionDeclaration ()\n\t\t\t  ? UNION_TYPE : RECORD_TYPE);\n    d_keep (t->ctype);\n    IDENTIFIER_DAGGREGATE (deco) = t->sym;\n    TYPE_LANG_SPECIFIC (t->ctype) = build_lang_type (t);\n\n    if (t->sym->members)\n      {\n\t/* Must set up the overall size and alignment before determining\n\t   the context or laying out fields as those types may make\n\t   recursive references to this type.  */\n\tunsigned structsize = t->sym->structsize;\n\tunsigned alignsize = (t->sym->alignment != STRUCTALIGN_DEFAULT)\n\t  ? t->sym->alignment : t->sym->alignsize;\n\n\tTYPE_SIZE (t->ctype) = bitsize_int (structsize * BITS_PER_UNIT);\n\tTYPE_SIZE_UNIT (t->ctype) = size_int (structsize);\n\tSET_TYPE_ALIGN (t->ctype, alignsize * BITS_PER_UNIT);\n\tTYPE_PACKED (t->ctype) = (alignsize == 1);\n\tcompute_record_mode (t->ctype);\n\n\t/* Put out all fields.  */\n\tlayout_aggregate_type (t->sym, t->ctype, t->sym);\n\tfinish_aggregate_type (structsize, alignsize, t->ctype,\n\t\t\t       t->sym->userAttribDecl);\n      }\n\n    TYPE_CONTEXT (t->ctype) = d_decl_context (t->sym);\n    build_type_decl (t->ctype, t->sym);\n\n    /* For structs with a user defined postblit or a destructor,\n       also set TREE_ADDRESSABLE on the type and all variants.\n       This will make the struct be passed around by reference.  */\n    if (t->sym->postblit || t->sym->dtor)\n      {\n\tfor (tree tv = t->ctype; tv != NULL_TREE; tv = TYPE_NEXT_VARIANT (tv))\n\t  TREE_ADDRESSABLE (tv) = 1;\n      }\n  }\n\n  /* Build a class type.  Whereas structs are value types, classes are\n     reference types, with all the object-orientated features.  */\n\n  void visit (TypeClass *t)\n  {\n    /* Merge types in the back-end if the frontend did not itself do so.  */\n    tree deco = get_identifier (mangle_decl (t->sym));\n    if (IDENTIFIER_DAGGREGATE (deco))\n      {\n\tAggregateDeclaration *ad = IDENTIFIER_DAGGREGATE (deco);\n\tgcc_assert (ad->isClassDeclaration ());\n\n\t/* Non-templated variables shouldn't be defined twice.  */\n\tif (!t->sym->isInstantiated ())\n\t  ScopeDsymbol::multiplyDefined (t->sym->loc, t->sym, ad);\n\n\tt->ctype = build_ctype (ad->type);\n\treturn;\n      }\n\n    /* Need to set ctype right away in case of self-references to\n       the type during this call.  */\n    tree basetype = make_node (RECORD_TYPE);\n    t->ctype = build_pointer_type (basetype);\n    d_keep (t->ctype);\n    IDENTIFIER_DAGGREGATE (deco) = t->sym;\n\n    /* Note that lang_specific data is assigned to both the reference\n       and the underlying record type.  */\n    TYPE_LANG_SPECIFIC (t->ctype) = build_lang_type (t);\n    TYPE_LANG_SPECIFIC (basetype) = TYPE_LANG_SPECIFIC (t->ctype);\n    CLASS_TYPE_P (basetype) = 1;\n\n    /* Put out all fields, including from each base class.  */\n    layout_aggregate_type (t->sym, basetype, t->sym);\n    finish_aggregate_type (t->sym->structsize, t->sym->alignsize,\n\t\t\t   basetype, t->sym->userAttribDecl);\n\n    /* Classes only live in memory, so always set the TREE_ADDRESSABLE bit.  */\n    for (tree tv = basetype; tv != NULL_TREE; tv = TYPE_NEXT_VARIANT (tv))\n      TREE_ADDRESSABLE (tv) = 1;\n\n    /* Type is final, there are no derivations.  */\n    if (t->sym->storage_class & STCfinal)\n      TYPE_FINAL_P (basetype) = 1;\n\n    /* Create BINFO even if debugging is off.  This is needed to keep\n       references to inherited types.  */\n    if (!t->sym->isInterfaceDeclaration ())\n      TYPE_BINFO (basetype) = build_class_binfo (NULL_TREE, t->sym);\n    else\n      {\n\tunsigned offset = 0;\n\n\tTYPE_BINFO (basetype) = build_interface_binfo (NULL_TREE, t->sym,\n\t\t\t\t\t\t       offset);\n      }\n\n    /* Associate all virtual methods with the class too.  */\n    for (size_t i = 0; i < t->sym->vtbl.dim; i++)\n      {\n\tFuncDeclaration *fd = t->sym->vtbl[i]->isFuncDeclaration ();\n\ttree method = fd ? get_symbol_decl (fd) : error_mark_node;\n\n\tif (!error_operand_p (method)\n\t    && DECL_CONTEXT (method) == basetype\n\t    && !chain_member (method, TYPE_FIELDS (basetype)))\n\t  TYPE_FIELDS (basetype) = chainon (TYPE_FIELDS (basetype), method);\n      }\n\n    TYPE_CONTEXT (basetype) = d_decl_context (t->sym);\n    build_type_decl (basetype, t->sym);\n  }\n};\n\n\n/* Build a tree from a frontend Type.  */\n\ntree\nbuild_ctype (Type *t)\n{\n  if (!t->ctype)\n    {\n      TypeVisitor v;\n\n      /* Strip const modifiers from type before building.  This is done\n\t to ensure that back-end treats e.g: const (T) as a variant of T,\n\t and not as two distinct types.  */\n      if (t->isNaked ())\n\tt->accept (&v);\n      else\n\t{\n\t  Type *tb = t->castMod (0);\n\t  if (!tb->ctype)\n\t    tb->accept (&v);\n\t  t->ctype = insert_type_modifiers (tb->ctype, t->mod);\n\t}\n    }\n\n  return t->ctype;\n}\n"
  },
  {
    "path": "gcc/d/verstr.h",
    "content": "\"2.083.0\"\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/asan/asan.exp",
    "content": "#   Copyright (C) 2017 Free Software Foundation, Inc.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\n# Load support procs.\nload_lib gdc-dg.exp\nload_lib asan-dg.exp\n\n# Initialize `dg'.\ndg-init\nasan_init\n\n# Main loop.\nif [check_effective_target_fsanitize_address] {\n  gdc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.d]] \"\" \"\"\n}\n\n# All done.\nasan_finish\ndg-finish\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/asan/gdc272.d",
    "content": "/* { dg-options \"-fsanitize=address\" } */\n/* { dg-do compile } */\n\nmodule asantests;\n\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=272\n\nextern(C) void my_memcmp(const(void) *s1, const(void) *s2);\n\nvoid bug(const(char)* p)\n{\n        my_memcmp(p, \"__FILE__\".ptr);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/compilable.d",
    "content": "// { dg-options \"-I $srcdir/gdc.dg -I $srcdir/gdc.dg/imports\" }\n// { dg-additional-sources \"imports/gdc27.d imports/gdc231.d\" }\n// { dg-do compile }\n\nimport core.simd;\nimport gcc.attribute;\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=27\n\nimport imports.gdc27;\n\ninterface I_B : I_A\n{\n    void b();\n}\n\nabstract class C_B : C_A, I_B\n{\n    abstract void b();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=108\n\n@attribute(\"forceinline\")\nvoid forceinline108()\n{\n}\n\n@attribute(\"noinline\")\nvoid noinline108()\n{\n}\n\n@attribute(\"flatten\")\nvoid flatten108()\n{\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=170\n\nimport imports.gdc170;\n\nvoid test170()\n{\n    foo!void.foo1!void();\n    foo!void.foo2!void();\n    foo!void.foo3();\n    foo!void.foo3!void();\n    foo!void.foo4();\n    foo!void.foo4!void();\n    foo!void.foo5!void(null);\n    foo!void.foo6!void(null);\n    foo!void.foo7(null);\n    foo!void.foo7!void(null);\n    foo!void.foo8(null);\n    foo!void.foo8!void(null);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=212\n\ntemplate hasElaborateAssign212(S)\n{\n    enum hasElaborateAssign212 = is(typeof(S.init.opAssign(rvalueOf212!S))) ||\n        is(typeof(lvalueOf212!S)) ;\n}\n\nT rvalueOf212(T)();\n\nT lvalueOf212(T)();\n\n\ntemplate TypeTuple212(TList...)\n{\n    alias TypeTuple212 = TList;\n}\n\ntemplate Tuple212()\n{\n    struct Tuple212\n    {\n        void opAssign(R)(R)\n        {\n            if (hasElaborateAssign212!R)\n            {\n            }\n        }\n    }\n}\n\nref emplaceRef212()\n{\n    static if (!hasElaborateAssign212!(Tuple212!()))\n        chunk;\n}\n\nclass TaskPool212\n{\n    void reduce()\n    {\n        Tuple212!() seed = void;\n        Tuple212!()[] results;\n        foreach(i; TypeTuple212!(0, 1))\n            results[i] = seed;\n    }\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=213\n\nstruct S213\n{\n    int4 vec;\n}\n\nvoid test213()\n{\n    S213 s, b;\n\n    assert(s == b);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=218\n\nstruct S218a\n{\n    this(int* pdata_)\n    {\n        pdata = pdata_;\n    }\n\n    void opIndexAssign(int, size_t) { }\n    int* pdata;\n};\n\nstruct S218\n{\n    S218a getS218a()\n    {\n        return S218a(data.ptr);\n    }\n\n    int[] data;\n    int[] tab2;\n};\n\nS218 f()\n{\n    S218 r;\n\n    for(int i = 0; i < 1; ++i)\n        r.getS218a()[0] = 0;\n\n    return r;\n}\n\nS218 var;\n\nstatic this()\n{\n    var = f();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=223\n\nstruct S223\n{\n    long[8] field;\n}\n\nclass C223\n{\n    long[8] field;\n}\n\nS223 test223_1();\nreal test223_2();\nstring[long[8]] test223_3();\nC223 test223_4();\nlong test223_5();\nlong[] test223_6();\nlong[8] test223_7();\nC223[8] test223_8();\nvoid delegate() test223_9();\n\nbool test223()\n{\n    return test223_1() == test223_1() &&\n           test223_1() is test223_1() &&\n           test223_2() == test223_2() &&\n           test223_2() is test223_2() &&\n           test223_3() == test223_3() &&\n           test223_3() is test223_3() &&\n           test223_4() == test223_4() &&\n           test223_4() is test223_4() &&\n           test223_5() == test223_5() &&\n           test223_5() is test223_5() &&\n           test223_6() == test223_6() &&\n           test223_6() is test223_6() &&\n           test223_7() == test223_7() &&\n           test223_7() is test223_7() &&\n           test223_8() == test223_8() &&\n           test223_8() is test223_8() &&\n           test223_9() == test223_9() &&\n           test223_9() is test223_9();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=231\n\nimport imports.gdc231;\n\nclass Range231 : Widget231\n{\n    override void* getStruct()\n    {\n        return null;\n    }\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=239\n\nimport imports.gdc239;\n\nclass C239\n{\n    C239a *foo;\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=240\n\ninterface I204\n{\n      void f();\n}\n\nclass C204 : I204\n{\n      void f();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=241\n\nimport imports.gdc241a;\nimport imports.gdc241b : S241, C241, E241, N241;\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=242\n\nstruct S242a\n{\n    enum M = S242a();\n    void iter() { }\n}\n\nvoid test242a()\n{\n    return S242a.M.iter;\n}\n\nstruct S242b\n{\n    enum M = S242b();\n    void iter() { }\n}\n\nvoid test242b()\n{\n    S242b.M.iter;\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=251\n\nimport imports.gdc251a;\nimport imports.gdc251b : C251;\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=253\n\nimport imports.gdc253;\n\nclass C253 : C253a\n{\n    void test253() { }\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=255\n\nclass C255\n{\n    void f2()\n    {\n        class C1\n        {\n            void f1()\n            {\n                void f0()\n                {\n                    class C0\n                    {\n                        void test255()\n                        {\n                            f2();\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nclass C255a\n{\n    void f3()\n    {\n        class C1\n        {\n            void f2()\n            {\n                void f1()\n                {\n                    void f0()\n                    {\n                        class C0\n                        {\n                            void test255a()\n                            {\n                                f3();\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nclass C255b\n{\n    void f4()\n    {\n        class C2\n        {\n            void f3()\n            {\n                void f2()\n                {\n                    class C1\n                    {\n                        void f1()\n                        {\n                            void f0()\n                            {\n                                class C0\n                                {\n                                    void test255b()\n                                    {\n                                        f4();\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=256\n\nimport imports.gdcpkg256 : gdc256;\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=261\n\nvoid test261()\n{\n    class C1\n    {\n        void f1()\n        {\n            class C2\n            {\n                void f2()\n                {\n                    auto v = &f1;\n                }\n            }\n        }\n    }\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=280\n\nstruct RBNode280\n{\n    RBNode280* _parent;\n\n    @property left(RBNode280*)\n    {\n        _parent = &this;\n    }\n}\n\nclass RedBlackTree280\n{\n    RBNode280* _end;\n    RBNode280* _begin;\n\n    this(int[] elems...)\n    {\n        _end = new RBNode280;\n\n        foreach (e; elems)\n        {\n            _end.left = _begin;\n        }\n    }\n}\n\n__gshared s = new RedBlackTree280('h');\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=284\n\nalias v284 = __vector(int[2]);\n\nv284 test284(v284 a, ...)\n{\n    return a + a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/dg.exp",
    "content": "#   Copyright (C) 2017 Free Software Foundation, Inc.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\n# GCC testsuite that uses the `dg.exp' driver.\n\n# Load support procs.\nload_lib gdc-dg.exp\n\n# The default option list can be overridden by\n# TORTURE_OPTIONS=\"{ { list1 } ... { listN } }\"\n\nif ![info exists TORTURE_OPTIONS] {\n    set TORTURE_OPTIONS [list \\\n        { -O0 } { -O1 } { -O2 } { -O3 } { -Os } \\\n        { -O0 -frelease } { -O0 -g } { -O0 -frelease -g } \\\n        { -O1 -frelease } { -O1 -g } { -O1 -frelease -g } \\\n        { -O2 -frelease } { -O2 -g } { -O2 -frelease -g } \\\n        { -O3 -frelease } { -O3 -g } { -O3 -frelease -g } \\\n        { -Os -frelease } { -Os -g } { -Os -frelease -g }]\n}\n\n# Initialize `dg'.\ndg-init\n\n# Initialize use of torture lists.\ntorture-init\nset-torture-options $TORTURE_OPTIONS\n\n# Main loop.\ngdc-dg-runtest [lsort \\\n       [glob -nocomplain $srcdir/$subdir/*.d ] ] \"\" \"\"\n\n# Finalize use of torture lists.\ntorture-finish\n\n# All done.\ndg-finish\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/gdc254.d",
    "content": "// https://bugzilla.gdcproject.org/show_bug.cgi?id=254\n// { dg-options \"-I $srcdir/gdc.dg\" }\n// { dg-shouldfail \"interface function is not implemented\" }\n// { dg-do compile }\n\nimport imports.gdc254a;\n\ninterface A254\n{\n    void F();\n}\n\nclass C254 : B254, A254  // { dg-error \"interface function '\\[^\\n\\r]*' is not implemented\" }\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/gdc260.d",
    "content": "// https://bugzilla.gdcproject.org/show_bug.cgi?id=260\n// { dg-options \"-Wall -Werror\" }\n// { dg-do compile }\n\nimport gcc.builtins;\n\nchar *bug260(char *buffer)\n{\n  return __builtin_strcat(&buffer[0], \"Li\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/gdc270a.d",
    "content": "// https://bugzilla.gdcproject.org/show_bug.cgi?id=270\n// { dg-do compile }\n\nmodule gdc270;\n\nvoid foo()\n{\n}\n\n/* { dg-final { scan-assembler \"_GLOBAL__D_6gdc270\" } } */\n/* { dg-final { scan-assembler \"_GLOBAL__I_6gdc270\" } } */\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/gdc270b.d",
    "content": "// https://bugzilla.gdcproject.org/show_bug.cgi?id=270\n// { dg-do compile }\n\nmodule gdc270;\n\n/* { dg-final { scan-assembler \"_GLOBAL__D_6gdc270\" } } */\n/* { dg-final { scan-assembler \"_GLOBAL__I_6gdc270\" } } */\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/gdc282.d",
    "content": "// https://bugzilla.gdcproject.org/show_bug.cgi?id=282\n// { dg-shouldfail \"conflicting methods in class\" }\n// { dg-do compile }\n\nclass C282a\n{\n    void fun()\n    {\n    }\n\n    void f282()\n    {\n    }\n\n    void f282() // { dg-error \"conflicts with 'gdc282.C282a.f282'\" }\n    {\n    }\n}\n\nclass C282b\n{\n    struct S282b\n    {\n    }\n\n    void f282()\n    {\n    }\n\n    void f282() // { dg-error \"conflicts with 'gdc282.C282b.f282'\" }\n    {\n    }\n}\n\nclass C282c\n{\n    class C282c\n    {\n    }\n\n    void f282()\n    {\n    }\n\n    void f282() // { dg-error \"conflicts with 'gdc282.C282c.f282'\" }\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/gdc283.d",
    "content": "// https://bugzilla.gdcproject.org/show_bug.cgi?id=283\n// { dg-do run { target hw } }\n\nstruct Impl\n{\n    size_t _count;\n}\n\nstruct RefCountedStore\n{\n    Impl* _store;\n\n    void initialize()\n    {\n        import core.stdc.stdlib : malloc;\n        _store = cast(Impl*) malloc(Impl.sizeof);\n        _store._count = 1;\n    }\n\n    bool isInitialized()\n    {\n        return _store !is null;\n    }\n\n    void ensureInitialized()\n    {\n        if (!isInitialized)\n            initialize();\n    }\n}\n\nstruct RefCounted14443\n{\n    RefCountedStore _refCounted;\n\n    this(int)\n    {\n        _refCounted.initialize();\n    }\n\n    this(this)\n    {\n        ++_refCounted._store._count;\n    }\n\n    ~this()\n    {\n        if (--_refCounted._store._count)\n            return;\n\n        import core.stdc.stdlib : free;\n        free(_refCounted._store);\n        _refCounted._store = null;\n    }\n\n    int refCountedPayload()\n    {\n        _refCounted.ensureInitialized();\n        return 1;\n    }\n}\n\nstruct PathRange14443\n{\n    RefCounted14443 path;\n\n    @property PathElement14443 front()\n    {\n        return PathElement14443(this, path.refCountedPayload());\n    }\n}\n\nstruct PathElement14443\n{\n    PathRange14443 range;\n\n    this(PathRange14443 range, int)\n    {\n        this.range = range;\n    }\n}\n\nvoid main()\n{\n    auto path = RefCounted14443(12);\n    if (path._refCounted._store._count != 1)\n        assert(0);\n    {\n        auto _r = PathRange14443(path);\n        if (path._refCounted._store._count != 2)\n            assert(0);\n        {\n            auto element = _r.front;\n            if (path._refCounted._store._count != 3)\n                assert(0);\n        }\n        if (path._refCounted._store._count != 2)\n            assert(0);\n    }\n    if (path._refCounted._store._count != 1)\n        assert(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdc170.d",
    "content": "module imports.gdc170;\n\nclass bar(T)\n{\n    void undefined_reference() {}\n}\n\ntemplate foo(T)\n{\n    bar!T foo1(T2)() if (true) body { return null; }\n    bar!T foo2(T2)() { return null; }\n    bar!T foo3(T2 = void)() if (true) body { return null; }\n    bar!T foo4(T2 = void)() { return null; }\n    void foo5(T2)(bar!T x) if (true) body {}\n    void foo6(T2)(bar!T x) {}\n    void foo7(T2 = void)(bar!T x) if (true) body {}\n    void foo8(T2 = void)(bar!T x) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdc231.d",
    "content": "module imports.gdc231;\n\ninterface ImplementorIF\n{\n    void* getImplementorStruct();\n    void* getStruct();\n}\n\ntemplate ImplementorT()\n{\n    void* getImplementorStruct()\n    {\n        return null;\n    }\n}\n\nclass Widget231 : ImplementorIF\n{\n    mixin ImplementorT;\n    void* getStruct()\n    {\n        return null;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdc239.d",
    "content": "import std.path : buildNormalizedPath;\n\nclass C239a\n{\n    auto bar()\n    {\n        auto path = buildNormalizedPath(\"/\", \"foo\");\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdc241a.d",
    "content": "import compilable;\n\nS241 *s241;     // Use indirectly imported struct\nC241 *c241;     // Use indirectly imported class\nE241 *e241;     // Use indirectly imported enum\nN241.T *n241;   // Use indirectly imported namespace\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdc241b.d",
    "content": "\nclass C241 { }\n\nenum E241 { a }\n\nstruct S241 { }\n\nextern(C++, N241) { struct T { } }\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdc251a.d",
    "content": "module imports.gdc251a;\n\nimport imports.gdc251b;\nimport compilable;\n\nC251 config;\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdc251b.d",
    "content": "module imports.gdc251b;\n\nclass C251 { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdc253.d",
    "content": "module imports.gdc253;\n\ninterface I253a\n{\n}\n\ninterface I253b\n{\n    size_t printf(...);\n    void flush();\n}\n\nclass C253a : I253a , I253b\n{\n    size_t printf(...)\n    {\n        return 0;\n    }\n\n    void flush()\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdc254a.d",
    "content": "module imports.gdc254a;\n\nclass B254\n{\n    void F()\n    {\n        if (Error) return;\n    }\n\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdc256.d",
    "content": "module gdc256;\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdc27.d",
    "content": "module imports.gdc27;\n\ninterface I_A\n{\n    bool a();\n}\n\nclass C_A : I_A\n{\n    bool a()\n    {\n        return false;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/gdcpkg256/package.d",
    "content": "module imports.gdcpkg256;\n\npublic import gdc256;\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/imports/runnable.d",
    "content": "module imports.runnable;\n\nprivate import runnable;\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=36\n\nvoid test36d_1()\n{\n    auto parser = Parser!(char[])();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=253\n\nclass B253 : A253\n{\n    void test253(int[int] a)\n    {\n        if (a.get(0, 1))\n            return;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/link.d",
    "content": "// { dg-do link { target arm*-*-* i?86-*-* x86_64-*-* } }\n\n/******************************************/\n\nclass C1()\n{\n    static struct S1 { A1 a; }\n}\n\nenum E1 = is(C1!());\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=300\n\nstruct S300(Range)\n{\n    double test(size_t remaining)\n    {\n        double r;\n        return r ^^ remaining;\n    }\n}\n\nauto link300a(Range)(Range)\n{\n    return S300!(Range)();\n}\n\nvoid link300()\n{\n    struct I {}\n    static assert(is(typeof(link300a(I())) == struct));\n    auto sample = link300a(I());\n    sample.test(5);\n}\n\n/******************************************/\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/lto/lto.exp",
    "content": "#   Copyright (C) 2017 Free Software Foundation, Inc.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\n# Test link-time optimization across multiple files.\n#\n# Programs are broken into multiple files.  Each one is compiled\n# separately with LTO information.  The final executable is generated\n# by collecting all the generated object files using regular LTO or WHOPR.\n\nif $tracelevel then {\n    strace $tracelevel\n}\n\n# Load procedures from common libraries.\nload_lib standard.exp\nload_lib gdc-dg.exp\n\n# Load the language-independent compabibility support procedures.\nload_lib lto.exp\n\n# If LTO has not been enabled, bail.\nif { ![check_effective_target_lto] } {\n    return\n}\n\nlto_init no-mathlib\n\n# Define an identifier for use with this suite to avoid name conflicts\n# with other lto tests running at the same time.\nset sid \"d_lto\"\n\n# Main loop.\nforeach src [lsort [find $srcdir/$subdir *_0.d]] {\n    # If we're only testing specific files and this isn't one of them, skip it.\n    if ![runtest_file_p $runtests $src] then {\n        continue\n    }\n\n    lto-execute $src $sid\n}\n\nlto_finish\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/lto/ltotests_0.d",
    "content": "// { dg-lto-do link }\nmodule ltotests_0;\n\nimport core.stdc.stdio;\n\n\n/******************************************/\n\ninterface I284\n{\n   void m284();\n}\n\nclass C284 : I284\n{\n   void m284() { }\n}\n\n/******************************************/\n\nclass C304\n{\n}\n\nC304 c304;\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=61\n\nstruct S61a\n{\n    void a() { }\n    void b() { }\n}\n\nstruct S61b\n{\n    S61a other;\n\n    void foo()\n    {\n        bar();\n    }\n\n    void bar()\n    {\n        try\n            other.a();\n        catch (Exception)\n            other.b();\n    }\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=88\n\nextern(C) int test88a();\n\nvoid test88()\n{\n    test88a();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=252\n\nclass C252\n{\n    struct S252\n    {\n        int i;\n        ubyte u;\n    }\n    S252 s;\n}\n\nvoid test252()\n{\n    C252 c = new C252();\n}\n\n/******************************************/\n\nvoid main(string[])\n{\n    test88();\n    test252();\n\n    printf(\"Success!\\n\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/lto/ltotests_1.d",
    "content": "module ltotests_1;\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=88\n\nextern(C) int test88a()\n{\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/runnable.d",
    "content": "// { dg-additional-sources \"imports/runnable.d\" }\n// { dg-do run { target hw } }\n\nmodule runnable;\n\nimport imports.runnable;\nimport core.stdc.stdio;\nimport gcc.attribute;\n\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=2\n\nstruct S\n{\n    string toString() { return \"foo\"; }\n}\n\nvoid test2()\n{\n    import std.string : format;\n    assert(format(\"%s\", S()) == \"foo\");\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=4\n\nvoid test4()\n{\n    string str = \"allo\";\n    static assert(!__traits(compiles, str.reverse));\n    static assert(!__traits(compiles, str.sort));\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=15\n\nclass B\n{\n    class A { }\n    A a;\n}\n\nclass C\n{\n    void visit(B b)\n    {\n        import std.algorithm : map;\n        auto as = [b.a];\n        as.map!(d => d);\n    }\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=16\n\nvoid test16()\n{\n    import std.parallelism : taskPool;\n\n    taskPool.reduce!\"a+b\"([0, 1, 2, 3]);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=17\n\n/**\n * Parameters are not copied into a frame to be accessed from\n * the method's __require function.\n */\nvoid contractTest(string path)\n{\n    assert(path[0] == 't');\n    assert(path.length == 9);\n    assert(path[8] == 'i');\n}\n\ninterface ModuleSaver\n{\n    void save(string str)\n    in\n    {\n        contractTest(str);\n    }\n}\n\nclass ModuleWriter : ModuleSaver\n{\n    void save (string str)\n    in {}\n    body\n    {\n    }\n}\n\nvoid test17()\n{\n  (new ModuleWriter()).save (\"test.0.mci\");\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=18\n\nclass C18\n{\n    struct Link\n    {\n        int x;\n        int y;\n    }\n\n    void sort_links()\n    {\n        import std.algorithm : sort;\n        import std.array : empty;\n        import std.exception : enforce;\n\n        enforce(!_link.empty);\n\n        bool lt(Link a, Link b)\n        {\n            if(a.x > b.x)\n                return false;\n            if(a.x < b.x)\n                return true;\n            if(a.y >= b.y)\n                return false;\n            else\n                return true;\n        }\n        sort!(lt)(_link);\n    }\n\n    this()\n    {\n        _link ~= Link(8, 3);\n        _link ~= Link(4, 7);\n        _link ~= Link(4, 6);\n        _link ~= Link(3, 7);\n        _link ~= Link(2, 7);\n        _link ~= Link(2, 2);\n        _link ~= Link(4, 1);\n    }\n\n    Link[] _link;\n}\n\nvoid test18()\n{\n    C18 foo = new C18;\n    foo.sort_links();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=19\n\nvoid test19()\n{\n   byte b;\n   --b = b;\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=24\n\nvoid test24()\n{\n    struct S24\n    {\n        char[1] b;\n    }\n\n    S24 a;\n\n    if (*a.b.ptr)\n        return;\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=29\n\nvoid test29()\n{\n    import std.string : format;\n    import std.conv : text;\n\n    string s;\n    for (auto i = 0; i < 100000; i++)\n    {\n        s = format(\"%d\", i);\n        s = text(i);\n    }\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=31\n\nclass RedBlackTree(T, alias less)\n{\n    struct Range\n    {\n        @property empty() { }\n    }\n\n    Range opSlice()\n    {\n        return Range();\n    }\n}\n\nauto redBlackTree(alias less, E)()\n{\n    return new RedBlackTree!(E, less);\n}\n\nvoid test31()\n{\n    redBlackTree!((a){}, double)();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=35\n\n/**\n * Here the BinaryHeap instance uses an alias parameter and therefore\n * the instance's functions (percolateDown) need to be generated in\n * topNIndex->BinaryHeap scope and not in the declaration scope\n * (module->BinaryHeap).\n */\nvoid topNIndex()()\n{\n    bool indirectLess(int a, int b)\n    {\n        return a > b;\n    }\n\n    auto a = BinaryHeap!(indirectLess)();\n}\n\nstruct BinaryHeap(alias less)\n{\n    void percolateDown()\n    {\n        less(0, 1);\n    }\n}\n\nvoid test35a()\n{\n    topNIndex();\n}\n\n/*\n * Similar as test35a but with an additional indirection.\n * The nested function chain for percolateDown should look like this:\n * topNIndex2->BinaryHeap2->percolateDown.\n */\nvoid topNIndex2()()\n{\n    bool indirectLess(int a, int b)\n    {\n        return a > b;\n    }\n    auto a = BinaryHeap2!(S35b!(indirectLess)())();\n}\n\nstruct S35b(alias a)\n{\n    void foo()\n    {\n        a(0, 0);\n    }\n}\n\nstruct BinaryHeap2(alias less)\n{\n    void percolateDown()\n    {\n        less.foo();\n    }\n}\n\nvoid test35b()\n{\n    topNIndex2();\n}\n\nvoid test35()\n{\n    test35a();\n    test35b();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=36\n\n/**\n * Here getChar is a function in a template where template.isnested == false\n * but getChar still is a nested function and needs to get a static chain\n * containing test36a.\n */\nvoid test36a()(char val)\n{\n    void error()\n    {\n    }\n\n    void getChar()()\n    {\n        error();\n    }\n\n    void parseString()\n    {\n        getChar();\n    }\n}\n\n/**\n * Similar as test36a, but a little more complicated:\n * Here getChar is nested in a struct template which is nested in a function.\n * getChar's static chain still needs to contain test36b.\n */\nvoid test36b()(char val)\n{\n    void error()\n    {\n    }\n\n    struct S(T)\n    {\n        void getChar()\n        {\n            error();\n        }\n    }\n\n\n    void parseString()\n    {\n        S!(int)().getChar();\n    }\n}\n\n/**\n * If g had accessed a, the frontend would have generated a closure.\n *\n * As we do not access it, there's no closure. We have to be careful\n * not to set a static chain for g containing test36c_1 though,\n * as g can be called from outside (here from test1c). In the end\n * we have to treat this as if everything in test36c_1 was declared\n * at module scope.\n */\nauto test36c_1()\n{\n    int a;\n    void c() {};\n    class Result\n    {\n        int b;\n        void g() { c(); /*a = 42;*/ }\n    }\n\n    return new Result();\n}\n\nvoid test36c()\n{\n    test36c_1().g();\n}\n\n/**\n * empty is a (private) function which is nested in lightPostprocess.\n * At the same time it's a template instance, so it has to be declared as\n * weak or otherwise one-only. imports/runnable.d creates another instance\n * of Regex!char to verify that.\n */\nstruct Parser(R)\n{\n    @property program()\n    {\n        return Regex!char();\n    }\n}\n\nstruct Regex(Char)\n{\n    @trusted lightPostprocess()\n    {\n        struct FixedStack(T)\n        {\n            @property empty() { return false; }\n        }\n        auto counterRange = FixedStack!uint();\n    }\n}\n\nvoid test36d()\n{\n    auto parser = Parser!(char[])();\n    imports.runnable.test36d_1;\n}\n\nvoid test36()\n{\n  test36a('n');\n  test36b('n');\n  test36c();\n  test36d();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=37\n\nstruct S37\n{\n    int bar(const S37 s)\n    {\n        return 0;\n    }\n}\n\nint test37()\n{\n    S37 s;\n    return s.bar(s);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=43\n\nvoid test43()\n{\n    import core.vararg;\n    import core.stdc.stdio;\n\n    void formatArray(ref va_list argptr)\n    {\n        auto a = va_arg!(const(float)[])(argptr);\n        foreach(f; a)\n        {\n            printf(\"%f\\n\", f);\n        }\n    }\n\n    void doFormat(TypeInfo[] arguments, va_list argptr)\n    {\n        formatArray(argptr);\n    }\n\n    void format(...)\n    {\n        doFormat(_arguments, _argptr);\n    }\n\n    format([1.0f, 2.0f, 3.0f]);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=47\n\ntemplate Foo47()\n{\n    void test47()\n    {\n        asm { \"nop\"; }\n    }\n}\n\nmixin Foo47!();\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=51\n\nstruct S51\n{\n    int x;\n    int pad;\n\n    this(this)\n    {\n        ++x;\n    }\n}\n\nvoid test51()\n{\n    S51 s;\n    auto sarr = new S51[1];\n    auto sarr2 = sarr;\n\n    // postblit all fields.\n    sarr2 ~= s;\n\n    assert (sarr2[0].x == 1);\n    assert (sarr2[1].x == 1);\n    assert (sarr[0].x == 0);\n    assert (s.x == 0);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=52\n\nclass C52\n{\n    C52 a;\n\n    this()\n    {\n        printf(\"Construct: this=%p\\n\", cast(void*)this);\n        a = this;\n    }\n\n    bool check()\n    {\n        printf(\"Check: this=%p a=%p\\n\", cast(void*)this, cast(void*)a);\n        return this is a;\n    }\n}\n\nauto test52a()\n{\n    import std.conv, std.traits;\n\n    struct Scoped\n    {\n        void[__traits (classInstanceSize, C52) ] Scoped_store = void;\n\n        inout(C52) Scoped_payload() inout\n        {\n            void* alignedStore = cast(void*) Scoped_store.ptr;\n            return cast(inout (C52)) alignedStore;\n        }\n        alias Scoped_payload this;\n    }\n\n    Scoped result;\n    emplace!(Unqual!C52)(result.Scoped_store);\n    assert(result.Scoped_payload().check);\n    return result;\n}\n\nvoid test52()\n{\n    auto a1 = test52a();\n    assert(a1.Scoped_payload().check);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=57\n\nstruct S57\n{\n    int a;\n    long b;\n    // Doesn't happen for bigger structs\n}\n\nS57 bar57()\n{\n    return S57(4, 42);\n}\n\nvoid test57()\n{\n    S57 s = bar57();\n    assert (s is S57(4, 42));\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=66\n\nvoid test66()\n{\n    int pos = 0;\n\n    foreach(x; 0 .. 64)\n    {\n        ++pos %= 4;\n        assert (pos != 4);\n    }\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=67\n\n__vector(float[4])[2] d;  // ICE\n\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=71\n\nstruct Leaf\n{\n    ubyte symbol;\n    ubyte codeLen;\n}\n\nstruct CanonicalHuffman\n{\n    Leaf[] table;\n\n    void print()\n    {\n        import std.algorithm;\n        import std.range;\n\n        auto list = zip(iota(table.length), table.dup).array\n            .sort!((a, b) => a[1].symbol < b[1].symbol)\n            .uniq!((a, b) => (a[0] & (1 << a[1].codeLen) - 1) == (b[0] & (1 << b[1].codeLen) - 1));\n    }\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=77\n\nvoid fun(ubyte[3] buf)\n{\n    import std.bitmanip : bigEndianToNative;\n    bigEndianToNative!ushort(buf[0..2]);\n}\n\nvoid test77()\n{\n    fun([1,2,3]);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=108\n\n@attribute(\"forceinline\")\nvoid test108()\n{\n    import std.stdio : writeln;\n    writeln(\"Here\");\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=115\n\nvoid test115()\n{\n    union U\n    {\n        float f;\n        uint i;\n    }\n    float a = 123.0;\n    const l = U(a);\n\n    assert(l.i == U(a).i);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=121\n\nimmutable char C121 = void; // ICE\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=122\n\nvoid test122()\n{\n    import std.algorithm : map;\n    import std.parallelism : taskPool;\n    import std.range : iota;\n\n    immutable n = 10000;\n    enum delta = 1.0 / n;       // XBUG: was 'immutable delta' https://issues.dlang.org/show_bug.cgi?id=17092\n    immutable pi = 4.0 * delta * taskPool.reduce!\"a + b\"(\n        map!((int i) { immutable x = (i - 0.5) * delta; return 1.0 / (1.0 + x * x); })(iota(n)));\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=127\n\nint[0] test127a;     // OK\nint[1][0] test127b;  // OK\nint[0][1] test127c;  // ICE\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=131\n\nstruct S131\n{\n    this(string ) { }\n    string opAssign(string v) { return v; }\n}\n\nvoid test131()\n{\n    S131[string] s;\n    s[\"foo\"] = \"bar\";\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=133\n\nvoid delegate()[] D133;\n\nvoid test133a(void delegate() dg)\n{\n    D133 ~= dg;\n}\n\nvoid test133()\n{\n    void nested()\n    {}\n    test133a(&nested);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=141\n\nbool test141a(int a)\n{\n    return a > (a + 1);\n}\n\nvoid test141()\n{\n    assert(test141a(int.min) == false);\n    assert(test141a(int.max) == true);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=142\n\n@attribute(\"noinline\")\nint test142a()()\n{\n    return 142;\n}\n\nvoid test142()\n{\n    enum E142 = test142a();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=171\n\nvoid test171a()\n{\n    int count = 0;\n    short a = -1;\n    while (a != 0)\n    {\n        a >>>= 1;\n        count++;\n        assert(count <= 16);\n    }\n}\n\nvoid test171b()\n{\n    uint[3] lhs = [99, 201, 300],\n            rhs = [-1, 0, 0];\n    long t = 0;\n\n    for (int i = 0; i < 3; i++)\n    {\n        t += lhs[i];\n        t -= rhs[i];\n        lhs[i] = cast(uint) t;\n        t >>= uint.sizeof * 8;\n    }\n\n    assert(lhs == [100, 200, 300]);\n}\n\nvoid test171()\n{\n    test171a();\n    test171b();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=179\n\nstruct S179a\n{\n    @disable this(this);\n}\n\nstruct S179b\n{\n    S179a s1;\n    void connect() { printf(\"this=%p\\n\", &this); }\n}\n\nclass C179\n{\n    private S179b s2;\n    ref S179b value() @property\n    {\n        printf(\"this=%p\\n\", &s2);\n        return s2;\n    }\n}\n\nvoid test179()\n{\n    C179 a = new C179;\n    a.value.connect();\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=183\n\nstruct S183a\n{\n    union I183a\n    {\n        struct\n        {\n            double x, y, z;\n        }\n        struct\n        {\n            double a, b, c;\n        }\n    }\n\n    I183a inner;\n\n    this(double x, double y, double z)\n    {\n        this.inner.x = x;\n        this.inner.y = y;\n        this.inner.z = z;\n    }\n}\n\nstruct S183b\n{\n    @property get()\n    {\n        union Buf\n        {\n            void[0] result;\n        }\n        const Buf buf = { };\n        return buf.result;\n    }\n}\n\nstruct S183c\n{\n    @property get()\n    {\n        union Buf\n        {\n            TypeInfo info;\n            void[0] result;\n        }\n        const Buf buf = { };\n        return buf.result;\n    }\n}\n\nvoid test183()\n{\n    auto v1 = S183a(0, 0, 0);\n    auto v2 = S183b().get;\n    auto v3 = S183c().get;\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=186\n\nstruct S186\n{\n    union\n    {\n        struct\n        {\n            ubyte fieldA;\n            byte  fieldB = -1;\n            byte fieldC = -1;\n        }\n        size_t _complete;\n    }\n\n    this(size_t complete)\n    {\n        this._complete = complete;\n    }\n}\n\nvoid check186(in S186 obj, byte fieldB)\n{\n    assert(obj.fieldA == 2);\n    assert(obj.fieldB == 0);\n    assert(obj.fieldC == 0);\n    assert(obj._complete == 2);\n    assert(fieldB == 0);\n}\n\nvoid test186a(size_t val)\n{\n    S186 obj = S186(val);\n    check186(obj, obj.fieldB);\n\n    assert(obj.fieldA == 2);\n    assert(obj.fieldB == 0);\n    assert(obj.fieldC == 0);\n    assert(obj._complete == 2);\n\n    obj = S186(val);\n    check186(obj, obj.fieldB);\n\n    assert(obj.fieldA == 2);\n    assert(obj.fieldB == 0);\n    assert(obj.fieldC == 0);\n    assert(obj._complete == 2);\n}\n\nvoid test186()\n{\n    test186a(2);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=187\n\nalign(1) struct S187b\n{\n    align(1)\n    {\n        uint unpaddedA;\n        ushort unpaddedB;\n    }\n}\n\nstruct S187a\n{\n    S187b[3] unpaddedArray;\n    ubyte wontInitialize = ubyte.init;\n}\n\nstruct S187\n{\n    S187a interesting;\n}\n\n\nvoid prepareStack()\n{\n    byte[255] stackGarbage;\n    foreach(i, ref b; stackGarbage)\n    {\n        b  = cast(byte)(-i);\n    }\n}\n\nvoid test187()\n{\n    prepareStack();\n    auto a = S187(S187a());\n    assert(a.interesting.wontInitialize == 0);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=191\n\nclass C191\n{\n    int count = 0;\n\n    void testA()\n    {\n        class Inner\n        {\n            void test()\n            {\n                void localFunction()\n                {\n                    if (++count != 5)\n                        testA();\n                }\n                localFunction();\n            }\n        }\n        scope ic = new Inner();\n        ic.test();\n    }\n\n    void testB()\n    {\n        class Inner\n        {\n            void test()\n            {\n                void localFunction()\n                {\n                    void anotherLocalFunction()\n                    {\n                        if (++count != 10)\n                            testB();\n                    }\n                    anotherLocalFunction();\n                }\n                localFunction();\n            }\n        }\n        scope ic = new Inner();\n        ic.test();\n    }\n\n    void testC()\n    {\n        class Inner\n        {\n            int a = 1;\n\n            void test()\n            {\n                void localFunction()\n                {\n                    count += a;\n                    if (count != 15)\n                        testC();\n                    assert(a == 1);\n                }\n                localFunction();\n            }\n        }\n        scope ic = new Inner();\n        ic.test();\n    }\n\n    void testD()\n    {\n        class Inner\n        {\n            void test()\n            {\n                int a = 1;\n\n                void localFunction()\n                {\n                    count += a;\n                    if (count != 20)\n                        testD();\n                    assert(a == 1);\n                }\n                localFunction();\n            }\n        }\n        scope ic = new Inner();\n        ic.test();\n    }\n\n    void testE()\n    {\n        class Inner\n        {\n            int a = 1;\n\n            void test()\n            {\n                void localFunction()\n                {\n                    void anotherLocalFunction()\n                    {\n                        count += a;\n                        if (count != 25)\n                            testE();\n                        assert(a == 1);\n                    }\n\n                    anotherLocalFunction();\n                }\n\n                localFunction();\n            }\n        }\n        scope ic = new Inner();\n        ic.test();\n    }\n\n    void testF()\n    {\n        class Inner\n        {\n            void test()\n            {\n                int a = 1;\n\n                void localFunction()\n                {\n                    void anotherLocalFunction()\n                    {\n                        count += a;\n                        if (count != 30)\n                            testF();\n                        assert(a == 1);\n                    }\n\n                    anotherLocalFunction();\n                }\n\n                localFunction();\n            }\n        }\n        scope ic = new Inner();\n        ic.test();\n    }\n\n    void testG()\n    {\n        class Inner\n        {\n            void test()\n            {\n                void localFunction()\n                {\n                    int a = 1;\n\n                    void anotherLocalFunction()\n                    {\n                        count += a;\n                        if (count != 35)\n                            testG();\n                        assert(a == 1);\n                    }\n\n                    anotherLocalFunction();\n                }\n\n                localFunction();\n            }\n        }\n        scope ic = new Inner();\n        ic.test();\n    }\n}\n\nvoid test191()\n{\n    scope oc = new C191();\n    oc.testA();\n    assert(oc.count == 5);\n\n    oc.testB();\n    assert(oc.count == 10);\n\n    oc.testC();\n    assert(oc.count == 15);\n\n    oc.testD();\n    assert(oc.count == 20);\n\n    oc.testE();\n    assert(oc.count == 25);\n\n    oc.testF();\n    assert(oc.count == 30);\n\n    oc.testG();\n    assert(oc.count == 35);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=194\n\nauto test194(ref bool overflow)\n{\n    import core.checkedint;\n\n    return adds(1, 1, overflow);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=196\n\nclass C196\n{\n    int a;\n}\n\nstruct S196\n{\n    int a;\n}\n\nvoid test196()\n{\n    __gshared c = new C196();\n    __gshared s = new S196(0);\n    c.a = 1;\n    s.a = 1;\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=198\n\nstruct S198a\n{\n    union\n    {\n        float[3] v;\n        struct\n        {\n            float x;\n            float y;\n            float z;\n        }\n    }\n\n    this(float x_, float y_, float z_)\n    {\n        x = x_;\n        y = y_;\n        z = z_;\n    }\n\n    ref S198a opOpAssign(string op)(S198a operand)\n    if (op == \"+\")\n    {\n        x += operand.x;\n        y += operand.y;\n        z += operand.z;\n        return this;\n    }\n}\n\nstruct S198b\n{\n    @property get()\n    {\n        union Buf\n        {\n            void[0] result;\n        }\n        const Buf buf = { };\n        return buf.result;\n    }\n}\n\nstruct S198c\n{\n    @property get()\n    {\n        union Buf\n        {\n            TypeInfo info;\n            void[0] result;\n        }\n        const Buf buf = { };\n        return buf.result;\n    }\n}\n\n\nauto test198()\n{\n    S198a sum = S198a(0, 0, 0);\n\n    foreach(size_t v; 0 .. 3)\n        sum += S198a(1, 2, 3);\n\n    assert(sum.v == [3, 6, 9]);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=200\n\nvoid test200a(double x, double y)\n{\n  const double y2 = x + 1.0;\n  assert(y == y2);\n}\n\nvoid test200()\n{\n  const double x = .012;\n  const double y = x + 1.0;\n  test200a(x, y);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=210\n\nstruct S210\n{\n    ubyte a;\n    uint b;\n}\n\nunion U210\n{\n    S210 a;\n    uint b;\n}\n\nS210 test210a()\n{\n    S210 s = S210(1, 2);\n    return s;\n}\n\nS210[2] test210b()\n{\n    S210[2] s = [S210(1, 2), S210(3, 4)];\n    return s;\n}\n\nU210 test210c()\n{\n    U210 s = U210(S210(1, 2));\n    return s;\n}\n\nU210[2] test210d()\n{\n    U210[2] s = [U210(S210(1, 2)), U210(S210(3, 4))];\n    return s;\n}\n\nvoid test210()\n{\n    S210 a = S210(1, 2);\n    assert(a == S210(1, 2));\n    assert(a == test210a());\n    assert(a != S210(2, 1));\n\n    S210[2] b = [S210(1, 2), S210(3, 4)];\n    assert(b == [S210(1, 2), S210(3, 4)]);\n    assert(b == test210b());\n    assert(b != [S210(2, 1), S210(3, 4)]);\n\n    U210 c = U210(S210(1, 2));\n    assert(c == U210(S210(1, 2)));\n    assert(c == test210c());\n    assert(c != U210(S210(2, 1)));\n\n    U210[2] d = [U210(S210(1, 2)), U210(S210(3, 4))];\n    assert(d == [U210(S210(1, 2)), U210(S210(3, 4))]);\n    assert(d == test210d());\n    assert(d != [U210(S210(2, 1)), U210(S210(3, 4))]);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=240\n\nvoid test240a(int a, int b)\n{\n    assert(a == 0);\n    assert(b == 0);\n}\n\nvoid test240()\n{\n    int a = 0;\n    test240a(a, a++);\n    assert(a == 1);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=242\n\nstruct S242\n{\n    enum M = S242();\n    int a = 42;\n\n    auto iter()\n    {\n        this.a = 24;\n        return this;\n    }\n}\n\nS242 test242a()\n{\n    return S242.M.iter;\n}\n\nvoid test242()\n{\n    assert(test242a() == S242(24));\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=248\n\nclass C248b\n{\n    bool isintegral()\n    {\n        return false;\n    }\n}\n\nclass C248a\n{\n    int count = 0;\n\n    C248b getMemtype()\n    {\n        count++;\n        return new C248b();\n    }\n}\n\nclass C248\n{\n    C248a sym;\n\n    this()\n    {\n        this.sym = new C248a();\n    }\n\n    bool isintegral()\n    {\n        return sym.getMemtype().isintegral();\n    }\n}\n\nvoid test248()\n{\n    C248 e = new C248();\n    e.isintegral();\n    assert(e.sym.count == 1);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=250\n\nvoid test250()\n{\n    struct S\n    {\n        string data;\n    }\n\n    auto a = S(\"hello\");\n    auto b = S(\"hello\".dup);\n\n    assert(a.data == b.data);\n    assert(a == b);\n    assert([a] == [b]);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=253\n\ninterface A253\n{\n    void test253(int[int]);\n}\n\ninterface C253 : A253\n{\n}\n\nclass D253 : B253, C253\n{\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=273\n\nclass B273\n{\n    B273[] members;\n}\n\nclass D273 : B273\n{\n}\n\nvoid test273()\n{\n    auto noPointers = ClassInfo.ClassFlags.noPointers;\n    assert((B273.classinfo.m_flags & noPointers) == 0);\n    assert((D273.classinfo.m_flags & noPointers) == 0);\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=285\n\ninout(char)[] test285a(inout(char)* s) @nogc @system pure nothrow\n{\n    import core.stdc.string : strlen;\n    return s ? s[0 .. strlen(s)] : null;\n}\n\nvoid test285()\n{\n    assert(test285a(null) == null);\n    assert(test285a(\"foo\") == \"foo\");\n}\n\n/******************************************/\n// https://bugzilla.gdcproject.org/show_bug.cgi?id=286\n\nvoid test286()\n{\n    struct K286\n    {\n        int count;\n        this(this)\n        {\n            count++;\n        }\n    }\n\n    struct S286\n    {\n        int data;\n        this(K286 key)\n        {\n            data = key.count;\n        }\n    }\n\n    S286 getData(K286 key)\n    {\n        static S286[K286] getCache;\n        auto p = key in getCache;\n        if (p)\n            return *p;\n        return (getCache[key] = S286(key));\n    }\n\n    auto s = getData(K286());\n    if (s.data == 0)\n        assert(0);\n}\n\n/******************************************/\n\nvoid main()\n{\n    test2();\n    test4();\n    test16();\n    test17();\n    test18();\n    test35();\n    test36();\n    test43();\n    test51();\n    test52();\n    test57();\n    test66();\n    test77();\n    test108();\n    test115();\n    test131();\n    test133();\n    test141();\n    test179();\n    test186();\n    test187();\n    test191();\n    test196();\n    test198();\n    test200();\n    test210();\n    test240();\n    test242();\n    test248();\n    test250();\n    test273();\n    test285();\n    test286();\n\n    printf(\"Success!\\n\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.dg/simd.d",
    "content": "// { dg-do run { target hw } }\nimport core.simd;\nimport core.stdc.string;\nimport std.stdio;\n\nalias TypeTuple(T...) = T;\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16087\n\nstatic assert(void8.sizeof == 8);\nstatic assert(float2.sizeof == 8);\nstatic assert(byte8.sizeof == 8);\nstatic assert(ubyte8.sizeof == 8);\nstatic assert(short4.sizeof == 8);\nstatic assert(ushort4.sizeof == 8);\nstatic assert(int2.sizeof == 8);\nstatic assert(uint2.sizeof == 8);\n\nstatic assert(void16.alignof == 16);\nstatic assert(double2.alignof == 16);\nstatic assert(float4.alignof == 16);\nstatic assert(byte16.alignof == 16);\nstatic assert(ubyte16.alignof == 16);\nstatic assert(short8.alignof == 16);\nstatic assert(ushort8.alignof == 16);\nstatic assert(int4.alignof == 16);\nstatic assert(uint4.alignof == 16);\nstatic assert(long2.alignof == 16);\nstatic assert(ulong2.alignof == 16);\n\nstatic assert(void16.sizeof == 16);\nstatic assert(double2.sizeof == 16);\nstatic assert(float4.sizeof == 16);\nstatic assert(byte16.sizeof == 16);\nstatic assert(ubyte16.sizeof == 16);\nstatic assert(short8.sizeof == 16);\nstatic assert(ushort8.sizeof == 16);\nstatic assert(int4.sizeof == 16);\nstatic assert(uint4.sizeof == 16);\nstatic assert(long2.sizeof == 16);\nstatic assert(ulong2.sizeof == 16);\n\nstatic assert(void32.alignof == 32);\nstatic assert(double4.alignof == 32);\nstatic assert(float8.alignof == 32);\nstatic assert(byte32.alignof == 32);\nstatic assert(ubyte32.alignof == 32);\nstatic assert(short16.alignof == 32);\nstatic assert(ushort16.alignof == 32);\nstatic assert(int8.alignof == 32);\nstatic assert(uint8.alignof == 32);\nstatic assert(long4.alignof == 32);\nstatic assert(ulong4.alignof == 32);\n\nstatic assert(void32.sizeof == 32);\nstatic assert(double4.sizeof == 32);\nstatic assert(float8.sizeof == 32);\nstatic assert(byte32.sizeof == 32);\nstatic assert(ubyte32.sizeof == 32);\nstatic assert(short16.sizeof == 32);\nstatic assert(ushort16.sizeof == 32);\nstatic assert(int8.sizeof == 32);\nstatic assert(uint8.sizeof == 32);\nstatic assert(long4.sizeof == 32);\nstatic assert(ulong4.sizeof == 32);\n\n/*****************************************/\n\nvoid test1()\n{\n    void16 v1 = void,v2 = void;\n    byte16 b;\n    v2 = b;\n    v1 = v2;\n    static assert(!__traits(compiles, v1 + v2));\n    static assert(!__traits(compiles, v1 - v2));\n    static assert(!__traits(compiles, v1 * v2));\n    static assert(!__traits(compiles, v1 / v2));\n    static assert(!__traits(compiles, v1 % v2));\n    static assert(!__traits(compiles, v1 & v2));\n    static assert(!__traits(compiles, v1 | v2));\n    static assert(!__traits(compiles, v1 ^ v2));\n    static assert(!__traits(compiles, v1 ~ v2));\n    static assert(!__traits(compiles, v1 ^^ v2));\n    static assert(!__traits(compiles, v1 is v2));\n    static assert(!__traits(compiles, v1 !is v2));\n    static assert(!__traits(compiles, v1 == v2));\n    static assert(!__traits(compiles, v1 != v2));\n    static assert(!__traits(compiles, v1 < v2));\n    static assert(!__traits(compiles, v1 > v2));\n    static assert(!__traits(compiles, v1 <= v2));\n    static assert(!__traits(compiles, v1 >= v2));\n    static assert(!__traits(compiles, v1 << 1));\n    static assert(!__traits(compiles, v1 >> 1));\n    static assert(!__traits(compiles, v1 >>> 1));\n    static assert(!__traits(compiles, v1 && v2));\n    static assert(!__traits(compiles, v1 || v2));\n    static assert(!__traits(compiles, ~v1));\n    static assert(!__traits(compiles, -v1));\n    static assert(!__traits(compiles, +v1));\n    static assert(!__traits(compiles, !v1));\n\n    static assert(!__traits(compiles, v1 += v2));\n    static assert(!__traits(compiles, v1 -= v2));\n    static assert(!__traits(compiles, v1 *= v2));\n    static assert(!__traits(compiles, v1 /= v2));\n    static assert(!__traits(compiles, v1 %= v2));\n    static assert(!__traits(compiles, v1 &= v2));\n    static assert(!__traits(compiles, v1 |= v2));\n    static assert(!__traits(compiles, v1 ^= v2));\n    static assert(!__traits(compiles, v1 ~= v2));\n    static assert(!__traits(compiles, v1 ^^= v2));\n    static assert(!__traits(compiles, v1 <<= 1));\n    static assert(!__traits(compiles, v1 >>= 1));\n    static assert(!__traits(compiles, v1 >>>= 1));\n\n    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.\n    static assert(!__traits(compiles, cast(byte)v1));       // 1byte\n    static assert(!__traits(compiles, cast(short)v1));      // 2byte\n    static assert(!__traits(compiles, cast(int)v1));        // 4byte\n    static assert(!__traits(compiles, cast(long)v1));       // 8byte\n    static assert(!__traits(compiles, cast(float)v1));      // 4byte\n    static assert(!__traits(compiles, cast(double)v1));     // 8byte\n    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray\n    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK\n    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK\n}\n\n/*****************************************/\n\nvoid test2()\n{\n    byte16 v1, v2 = 1, v3 = 1;\n    v1 = v2;\n    v1 = v2 + v3;\n    v1 = v2 - v3;\n    v1 = v2 * v3;\n    v1 = v2 / v3;\n    v1 = v2 % v3;\n    v1 = v2 & v3;\n    v1 = v2 | v3;\n    v1 = v2 ^ v3;\n    static assert(!__traits(compiles, v1 ~ v2));\n    static assert(!__traits(compiles, v1 ^^ v2));\n    static assert(!__traits(compiles, v1 is v2));\n    static assert(!__traits(compiles, v1 !is v2));\n    static assert(!__traits(compiles, v1 == v2));\n    static assert(!__traits(compiles, v1 != v2));\n    static assert(!__traits(compiles, v1 < v2));\n    static assert(!__traits(compiles, v1 > v2));\n    static assert(!__traits(compiles, v1 <= v2));\n    static assert(!__traits(compiles, v1 >= v2));\n    v1 = v2 << 1;\n    v1 = v2 >> 1;\n    v1 = v2 >>> 1;\n    static assert(!__traits(compiles, v1 && v2));\n    static assert(!__traits(compiles, v1 || v2));\n    v1 = ~v2;\n    v1 = -v2;\n    v1 = +v2;\n    static assert(!__traits(compiles, !v1));\n\n    v1 += v2;\n    v1 -= v2;\n    v1 *= v2;\n    v1 /= v2;\n    v1 %= v2;\n    v1 &= v2;\n    v1 |= v2;\n    v1 ^= v2;\n    static assert(!__traits(compiles, v1 ~= v2));\n    static assert(!__traits(compiles, v1 ^^= v2));\n    v1 <<= 1;\n    v1 >>= 1;\n    v1 >>>= 1;\n\n    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.\n    static assert(!__traits(compiles, cast(byte)v1));       // 1byte\n    static assert(!__traits(compiles, cast(short)v1));      // 2byte\n    static assert(!__traits(compiles, cast(int)v1));        // 4byte\n    static assert(!__traits(compiles, cast(long)v1));       // 8byte\n    static assert(!__traits(compiles, cast(float)v1));      // 4byte\n    static assert(!__traits(compiles, cast(double)v1));     // 8byte\n    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray\n    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK\n    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK\n}\n\n/*****************************************/\n\nvoid test2b()\n{\n    ubyte16 v1, v2 = 1, v3 = 1;\n    v1 = v2;\n    v1 = v2 + v3;\n    v1 = v2 - v3;\n    v1 = v2 * v3;\n    v1 = v2 / v3;\n    v1 = v2 % v3;\n    v1 = v2 & v3;\n    v1 = v2 | v3;\n    v1 = v2 ^ v3;\n    static assert(!__traits(compiles, v1 ~ v2));\n    static assert(!__traits(compiles, v1 ^^ v2));\n    static assert(!__traits(compiles, v1 is v2));\n    static assert(!__traits(compiles, v1 !is v2));\n    static assert(!__traits(compiles, v1 == v2));\n    static assert(!__traits(compiles, v1 != v2));\n    static assert(!__traits(compiles, v1 < v2));\n    static assert(!__traits(compiles, v1 > v2));\n    static assert(!__traits(compiles, v1 <= v2));\n    static assert(!__traits(compiles, v1 >= v2));\n    v1 = v2 << 1;\n    v1 = v2 >> 1;\n    v1 = v2 >>> 1;\n    static assert(!__traits(compiles, v1 && v2));\n    static assert(!__traits(compiles, v1 || v2));\n    v1 = ~v2;\n    v1 = -v2;\n    v1 = +v2;\n    static assert(!__traits(compiles, !v1));\n\n    v1 += v2;\n    v1 -= v2;\n    v1 *= v2;\n    v1 /= v2;\n    v1 %= v2;\n    v1 &= v2;\n    v1 |= v2;\n    v1 ^= v2;\n    static assert(!__traits(compiles, v1 ~= v2));\n    static assert(!__traits(compiles, v1 ^^= v2));\n    v1 <<= 1;\n    v1 >>= 1;\n    v1 >>>= 1;\n\n    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.\n    static assert(!__traits(compiles, cast(byte)v1));       // 1byte\n    static assert(!__traits(compiles, cast(short)v1));      // 2byte\n    static assert(!__traits(compiles, cast(int)v1));        // 4byte\n    static assert(!__traits(compiles, cast(long)v1));       // 8byte\n    static assert(!__traits(compiles, cast(float)v1));      // 4byte\n    static assert(!__traits(compiles, cast(double)v1));     // 8byte\n    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray\n    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK\n    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK\n}\n\n/*****************************************/\n\nvoid test2c()\n{\n    short8 v1, v2 = 1, v3 = 1;\n    v1 = v2;\n    v1 = v2 + v3;\n    v1 = v2 - v3;\n    v1 = v2 * v3;\n    v1 = v2 / v3;\n    v1 = v2 % v3;\n    v1 = v2 & v3;\n    v1 = v2 | v3;\n    v1 = v2 ^ v3;\n    static assert(!__traits(compiles, v1 ~ v2));\n    static assert(!__traits(compiles, v1 ^^ v2));\n    static assert(!__traits(compiles, v1 is v2));\n    static assert(!__traits(compiles, v1 !is v2));\n    static assert(!__traits(compiles, v1 == v2));\n    static assert(!__traits(compiles, v1 != v2));\n    static assert(!__traits(compiles, v1 < v2));\n    static assert(!__traits(compiles, v1 > v2));\n    static assert(!__traits(compiles, v1 <= v2));\n    static assert(!__traits(compiles, v1 >= v2));\n    v1 = v2 << 1;\n    v1 = v2 >> 1;\n    v1 = v2 >>> 1;\n    static assert(!__traits(compiles, v1 && v2));\n    static assert(!__traits(compiles, v1 || v2));\n    v1 = ~v2;\n    v1 = -v2;\n    v1 = +v2;\n    static assert(!__traits(compiles, !v1));\n\n    v1 += v2;\n    v1 -= v2;\n    v1 *= v2;\n    v1 /= v2;\n    v1 %= v2;\n    v1 &= v2;\n    v1 |= v2;\n    v1 ^= v2;\n    static assert(!__traits(compiles, v1 ~= v2));\n    static assert(!__traits(compiles, v1 ^^= v2));\n    v1 <<= 1;\n    v1 >>= 1;\n    v1 >>>= 1;\n    v1 = v1 * 3;\n\n    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.\n    static assert(!__traits(compiles, cast(byte)v1));       // 1byte\n    static assert(!__traits(compiles, cast(short)v1));      // 2byte\n    static assert(!__traits(compiles, cast(int)v1));        // 4byte\n    static assert(!__traits(compiles, cast(long)v1));       // 8byte\n    static assert(!__traits(compiles, cast(float)v1));      // 4byte\n    static assert(!__traits(compiles, cast(double)v1));     // 8byte\n    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray\n    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK\n    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK\n}\n\n/*****************************************/\n\nvoid test2d()\n{\n    ushort8 v1, v2 = 1, v3 = 1;\n    v1 = v2;\n    v1 = v2 + v3;\n    v1 = v2 - v3;\n    v1 = v2 * v3;\n    v1 = v2 / v3;\n    v1 = v2 % v3;\n    v1 = v2 & v3;\n    v1 = v2 | v3;\n    v1 = v2 ^ v3;\n    static assert(!__traits(compiles, v1 ~ v2));\n    static assert(!__traits(compiles, v1 ^^ v2));\n    static assert(!__traits(compiles, v1 is v2));\n    static assert(!__traits(compiles, v1 !is v2));\n    static assert(!__traits(compiles, v1 == v2));\n    static assert(!__traits(compiles, v1 != v2));\n    static assert(!__traits(compiles, v1 < v2));\n    static assert(!__traits(compiles, v1 > v2));\n    static assert(!__traits(compiles, v1 <= v2));\n    static assert(!__traits(compiles, v1 >= v2));\n    v1 = v2 << 1;\n    v1 = v2 >> 1;\n    v1 = v2 >>> 1;\n    static assert(!__traits(compiles, v1 && v2));\n    static assert(!__traits(compiles, v1 || v2));\n    v1 = ~v2;\n    v1 = -v2;\n    v1 = +v2;\n    static assert(!__traits(compiles, !v1));\n\n    v1 += v2;\n    v1 -= v2;\n    v1 *= v2;\n    v1 /= v2;\n    v1 %= v2;\n    v1 &= v2;\n    v1 |= v2;\n    v1 ^= v2;\n    static assert(!__traits(compiles, v1 ~= v2));\n    static assert(!__traits(compiles, v1 ^^= v2));\n    v1 <<= 1;\n    v1 >>= 1;\n    v1 >>>= 1;\n\n    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.\n    static assert(!__traits(compiles, cast(byte)v1));       // 1byte\n    static assert(!__traits(compiles, cast(short)v1));      // 2byte\n    static assert(!__traits(compiles, cast(int)v1));        // 4byte\n    static assert(!__traits(compiles, cast(long)v1));       // 8byte\n    static assert(!__traits(compiles, cast(float)v1));      // 4byte\n    static assert(!__traits(compiles, cast(double)v1));     // 8byte\n    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray\n    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK\n    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK\n}\n\n/*****************************************/\n\nvoid test2e()\n{\n    int4 v1, v2 = 1, v3 = 1;\n    v1 = v2;\n    v1 = v2 + v3;\n    v1 = v2 - v3;\n    v1 = v2 * v3;\n    v1 = v2 / v3;\n    v1 = v2 % v3;\n    v1 = v2 & v3;\n    v1 = v2 | v3;\n    v1 = v2 ^ v3;\n    static assert(!__traits(compiles, v1 ~ v2));\n    static assert(!__traits(compiles, v1 ^^ v2));\n    static assert(!__traits(compiles, v1 is v2));\n    static assert(!__traits(compiles, v1 !is v2));\n    static assert(!__traits(compiles, v1 == v2));\n    static assert(!__traits(compiles, v1 != v2));\n    static assert(!__traits(compiles, v1 < v2));\n    static assert(!__traits(compiles, v1 > v2));\n    static assert(!__traits(compiles, v1 <= v2));\n    static assert(!__traits(compiles, v1 >= v2));\n    v1 = v2 << 1;\n    v1 = v2 >> 1;\n    v1 = v2 >>> 1;\n    static assert(!__traits(compiles, v1 && v2));\n    static assert(!__traits(compiles, v1 || v2));\n    v1 = ~v2;\n    v1 = -v2;\n    v1 = +v2;\n    static assert(!__traits(compiles, !v1));\n\n    v1 += v2;\n    v1 -= v2;\n    v1 *= v2;\n    v1 /= v2;\n    v1 %= v2;\n    v1 &= v2;\n    v1 |= v2;\n    v1 ^= v2;\n    static assert(!__traits(compiles, v1 ~= v2));\n    static assert(!__traits(compiles, v1 ^^= v2));\n    v1 <<= 1;\n    v1 >>= 1;\n    v1 >>>= 1;\n\n    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.\n    static assert(!__traits(compiles, cast(byte)v1));       // 1byte\n    static assert(!__traits(compiles, cast(short)v1));      // 2byte\n    static assert(!__traits(compiles, cast(int)v1));        // 4byte\n    static assert(!__traits(compiles, cast(long)v1));       // 8byte\n    static assert(!__traits(compiles, cast(float)v1));      // 4byte\n    static assert(!__traits(compiles, cast(double)v1));     // 8byte\n    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray\n    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK\n    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK\n}\n\n/*****************************************/\n\nvoid test2f()\n{\n    uint4 v1, v2 = 1, v3 = 1;\n    v1 = v2;\n    v1 = v2 + v3;\n    v1 = v2 - v3;\n    v1 = v2 * v3;\n    v1 = v2 / v3;\n    v1 = v2 % v3;\n    v1 = v2 & v3;\n    v1 = v2 | v3;\n    v1 = v2 ^ v3;\n    static assert(!__traits(compiles, v1 ~ v2));\n    static assert(!__traits(compiles, v1 ^^ v2));\n    static assert(!__traits(compiles, v1 is v2));\n    static assert(!__traits(compiles, v1 !is v2));\n    static assert(!__traits(compiles, v1 == v2));\n    static assert(!__traits(compiles, v1 != v2));\n    static assert(!__traits(compiles, v1 < v2));\n    static assert(!__traits(compiles, v1 > v2));\n    static assert(!__traits(compiles, v1 <= v2));\n    static assert(!__traits(compiles, v1 >= v2));\n    v1 = v2 << 1;\n    v1 = v2 >> 1;\n    v1 = v2 >>> 1;\n    static assert(!__traits(compiles, v1 && v2));\n    static assert(!__traits(compiles, v1 || v2));\n    v1 = ~v2;\n    v1 = -v2;\n    v1 = +v2;\n    static assert(!__traits(compiles, !v1));\n\n    v1 += v2;\n    v1 -= v2;\n    v1 *= v2;\n    v1 /= v2;\n    v1 %= v2;\n    v1 &= v2;\n    v1 |= v2;\n    v1 ^= v2;\n    static assert(!__traits(compiles, v1 ~= v2));\n    static assert(!__traits(compiles, v1 ^^= v2));\n    v1 <<= 1;\n    v1 >>= 1;\n    v1 >>>= 1;\n\n    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.\n    static assert(!__traits(compiles, cast(byte)v1));       // 1byte\n    static assert(!__traits(compiles, cast(short)v1));      // 2byte\n    static assert(!__traits(compiles, cast(int)v1));        // 4byte\n    static assert(!__traits(compiles, cast(long)v1));       // 8byte\n    static assert(!__traits(compiles, cast(float)v1));      // 4byte\n    static assert(!__traits(compiles, cast(double)v1));     // 8byte\n    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray\n    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK\n    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK\n}\n\n/*****************************************/\n\nvoid test2g()\n{\n    long2 v1, v2 = 1, v3 = 1;\n    v1 = v2;\n    v1 = v2 + v3;\n    v1 = v2 - v3;\n    v1 = v2 * v3;\n    v1 = v2 / v3;\n    v1 = v2 % v3;\n    v1 = v2 & v3;\n    v1 = v2 | v3;\n    v1 = v2 ^ v3;\n    static assert(!__traits(compiles, v1 ~ v2));\n    static assert(!__traits(compiles, v1 ^^ v2));\n    static assert(!__traits(compiles, v1 is v2));\n    static assert(!__traits(compiles, v1 !is v2));\n    static assert(!__traits(compiles, v1 == v2));\n    static assert(!__traits(compiles, v1 != v2));\n    static assert(!__traits(compiles, v1 < v2));\n    static assert(!__traits(compiles, v1 > v2));\n    static assert(!__traits(compiles, v1 <= v2));\n    static assert(!__traits(compiles, v1 >= v2));\n    v1 = v2 << 1;\n    v1 = v2 >> 1;\n    v1 = v2 >>> 1;\n    static assert(!__traits(compiles, v1 && v2));\n    static assert(!__traits(compiles, v1 || v2));\n    v1 = ~v2;\n    v1 = -v2;\n    v1 = +v2;\n    static assert(!__traits(compiles, !v1));\n\n    v1 += v2;\n    v1 -= v2;\n    v1 *= v2;\n    v1 /= v2;\n    v1 %= v2;\n    v1 &= v2;\n    v1 |= v2;\n    v1 ^= v2;\n    static assert(!__traits(compiles, v1 ~= v2));\n    static assert(!__traits(compiles, v1 ^^= v2));\n    v1 <<= 1;\n    v1 >>= 1;\n    v1 >>>= 1;\n\n    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.\n    static assert(!__traits(compiles, cast(byte)v1));       // 1byte\n    static assert(!__traits(compiles, cast(short)v1));      // 2byte\n    static assert(!__traits(compiles, cast(int)v1));        // 4byte\n    static assert(!__traits(compiles, cast(long)v1));       // 8byte\n    static assert(!__traits(compiles, cast(float)v1));      // 4byte\n    static assert(!__traits(compiles, cast(double)v1));     // 8byte\n    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray\n    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK\n    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK\n}\n\n/*****************************************/\n\nvoid test2h()\n{\n    ulong2 v1, v2 = 1, v3 = 1;\n    v1 = v2;\n    v1 = v2 + v3;\n    v1 = v2 - v3;\n    v1 = v2 * v3;\n    v1 = v2 / v3;\n    v1 = v2 % v3;\n    v1 = v2 & v3;\n    v1 = v2 | v3;\n    v1 = v2 ^ v3;\n    static assert(!__traits(compiles, v1 ~ v2));\n    static assert(!__traits(compiles, v1 ^^ v2));\n    static assert(!__traits(compiles, v1 is v2));\n    static assert(!__traits(compiles, v1 !is v2));\n    static assert(!__traits(compiles, v1 == v2));\n    static assert(!__traits(compiles, v1 != v2));\n    static assert(!__traits(compiles, v1 < v2));\n    static assert(!__traits(compiles, v1 > v2));\n    static assert(!__traits(compiles, v1 <= v2));\n    static assert(!__traits(compiles, v1 >= v2));\n    v1 = v2 << 1;\n    v1 = v2 >> 1;\n    v1 = v2 >>> 1;\n    static assert(!__traits(compiles, v1 && v2));\n    static assert(!__traits(compiles, v1 || v2));\n    v1 = ~v2;\n    v1 = -v2;\n    v1 = +v2;\n    static assert(!__traits(compiles, !v1));\n\n    v1 += v2;\n    v1 -= v2;\n    v1 *= v2;\n    v1 /= v2;\n    v1 %= v2;\n    v1 &= v2;\n    v1 |= v2;\n    v1 ^= v2;\n    static assert(!__traits(compiles, v1 ~= v2));\n    static assert(!__traits(compiles, v1 ^^= v2));\n    v1 <<= 1;\n    v1 >>= 1;\n    v1 >>>= 1;\n\n    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.\n    static assert(!__traits(compiles, cast(byte)v1));       // 1byte\n    static assert(!__traits(compiles, cast(short)v1));      // 2byte\n    static assert(!__traits(compiles, cast(int)v1));        // 4byte\n    static assert(!__traits(compiles, cast(long)v1));       // 8byte\n    static assert(!__traits(compiles, cast(float)v1));      // 4byte\n    static assert(!__traits(compiles, cast(double)v1));     // 8byte\n    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray\n    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK\n    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK\n}\n\n/*****************************************/\n\nvoid test2i()\n{\n    float4 v1, v2 = 1, v3 = 1;\n    v1 = v2;\n    v1 = v2 + v3;\n    v1 = v2 - v3;\n    v1 = v2 * v3;\n    v1 = v2 / v3;\n    static assert(!__traits(compiles, v1 % v2));\n    static assert(!__traits(compiles, v1 & v2));\n    static assert(!__traits(compiles, v1 | v2));\n    static assert(!__traits(compiles, v1 ^ v2));\n    static assert(!__traits(compiles, v1 ~ v2));\n    static assert(!__traits(compiles, v1 ^^ v2));\n    static assert(!__traits(compiles, v1 is v2));\n    static assert(!__traits(compiles, v1 !is v2));\n    static assert(!__traits(compiles, v1 == v2));\n    static assert(!__traits(compiles, v1 != v2));\n    static assert(!__traits(compiles, v1 < v2));\n    static assert(!__traits(compiles, v1 > v2));\n    static assert(!__traits(compiles, v1 <= v2));\n    static assert(!__traits(compiles, v1 >= v2));\n    static assert(!__traits(compiles, v1 << 1));\n    static assert(!__traits(compiles, v1 >> 1));\n    static assert(!__traits(compiles, v1 >>> 1));\n    static assert(!__traits(compiles, v1 && v2));\n    static assert(!__traits(compiles, v1 || v2));\n    static assert(!__traits(compiles, ~v1));\n    v1 = -v2;\n    v1 = +v2;\n    static assert(!__traits(compiles, !v1));\n\n    v1 += v2;\n    v1 -= v2;\n    v1 *= v2;\n    v1 /= v2;\n    static assert(!__traits(compiles, v1 %= v2));\n    static assert(!__traits(compiles, v1 &= v2));\n    static assert(!__traits(compiles, v1 |= v2));\n    static assert(!__traits(compiles, v1 ^= v2));\n    static assert(!__traits(compiles, v1 ~= v2));\n    static assert(!__traits(compiles, v1 ^^= v2));\n    static assert(!__traits(compiles, v1 <<= 1));\n    static assert(!__traits(compiles, v1 >>= 1));\n    static assert(!__traits(compiles, v1 >>>= 1));\n\n    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.\n    static assert(!__traits(compiles, cast(byte)v1));       // 1byte\n    static assert(!__traits(compiles, cast(short)v1));      // 2byte\n    static assert(!__traits(compiles, cast(int)v1));        // 4byte\n    static assert(!__traits(compiles, cast(long)v1));       // 8byte\n    static assert(!__traits(compiles, cast(float)v1));      // 4byte\n    static assert(!__traits(compiles, cast(double)v1));     // 8byte\n    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray\n    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK\n    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK\n}\n\n/*****************************************/\n\nvoid test2j()\n{\n    double2 v1, v2 = 1, v3 = 1;\n    v1 = v2;\n    v1 = v2 + v3;\n    v1 = v2 - v3;\n    v1 = v2 * v3;\n    v1 = v2 / v3;\n    static assert(!__traits(compiles, v1 % v2));\n    static assert(!__traits(compiles, v1 & v2));\n    static assert(!__traits(compiles, v1 | v2));\n    static assert(!__traits(compiles, v1 ^ v2));\n    static assert(!__traits(compiles, v1 ~ v2));\n    static assert(!__traits(compiles, v1 ^^ v2));\n    static assert(!__traits(compiles, v1 is v2));\n    static assert(!__traits(compiles, v1 !is v2));\n    static assert(!__traits(compiles, v1 == v2));\n    static assert(!__traits(compiles, v1 != v2));\n    static assert(!__traits(compiles, v1 < v2));\n    static assert(!__traits(compiles, v1 > v2));\n    static assert(!__traits(compiles, v1 <= v2));\n    static assert(!__traits(compiles, v1 >= v2));\n    static assert(!__traits(compiles, v1 << 1));\n    static assert(!__traits(compiles, v1 >> 1));\n    static assert(!__traits(compiles, v1 >>> 1));\n    static assert(!__traits(compiles, v1 && v2));\n    static assert(!__traits(compiles, v1 || v2));\n    static assert(!__traits(compiles, ~v1));\n    v1 = -v2;\n    v1 = +v2;\n    static assert(!__traits(compiles, !v1));\n\n    v1 += v2;\n    v1 -= v2;\n    v1 *= v2;\n    v1 /= v2;\n    static assert(!__traits(compiles, v1 %= v2));\n    static assert(!__traits(compiles, v1 &= v2));\n    static assert(!__traits(compiles, v1 |= v2));\n    static assert(!__traits(compiles, v1 ^= v2));\n    static assert(!__traits(compiles, v1 ~= v2));\n    static assert(!__traits(compiles, v1 ^^= v2));\n    static assert(!__traits(compiles, v1 <<= 1));\n    static assert(!__traits(compiles, v1 >>= 1));\n    static assert(!__traits(compiles, v1 >>>= 1));\n\n    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.\n    static assert(!__traits(compiles, cast(byte)v1));       // 1byte\n    static assert(!__traits(compiles, cast(short)v1));      // 2byte\n    static assert(!__traits(compiles, cast(int)v1));        // 4byte\n    static assert(!__traits(compiles, cast(long)v1));       // 8byte\n    static assert(!__traits(compiles, cast(float)v1));      // 4byte\n    static assert(!__traits(compiles, cast(double)v1));     // 8byte\n    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray\n    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK\n    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK\n}\n\n/*****************************************/\n\nvoid test4()\n{\n    int4 c = 7;\n    (cast(int[4])c)[3] = 4;\n    (cast(int*)&c)[2] = 4;\n    c.array[1] = 4;\n    c.ptr[3] = 4;\n    assert(c.length == 4);\n}\n\n/*****************************************/\n\nvoid BaseTypeOfVector(T : __vector(T[N]), size_t N)(int i)\n{\n    assert(is(T == int));\n    assert(N == 4);\n}\n\n\nvoid test7411()\n{\n    BaseTypeOfVector!(__vector(int[4]))(3);\n}\n\n/*****************************************/\n// 7951\n\nfloat[4] test7951()\n{\n    float4 v1;\n    float4 v2;\n\n    return cast(float[4])(v1+v2);\n}\n\n/*****************************************/\n\nvoid test7951_2()\n{\n    float[4] v1 = [1,2,3,4];\n    float[4] v2 = [1,2,3,4];\n    float4 f1, f2, f3;\n    f1.array = v1;\n    f2.array = v2;\n    f3 = f1 + f2;\n}\n\n/*****************************************/\n\nimmutable ulong2 gulong2 = 0x8000_0000_0000_0000;\nimmutable uint4 guint4 = 0x8000_0000;\nimmutable ushort8 gushort8 = 0x8000;\nimmutable ubyte16 gubyte16 = 0x80;\n\nimmutable long2 glong2 = 0x7000_0000_0000_0000;\nimmutable int4 gint4 = 0x7000_0000;\nimmutable short8 gshort8 = 0x7000;\nimmutable byte16 gbyte16 = 0x70;\n\nimmutable float4 gfloat4 = 4.0;\nimmutable double2 gdouble2 = 8.0;\n\nvoid test7414()\n{\n    immutable ulong2 lulong2 = 0x8000_0000_0000_0000;\n    assert(memcmp(&lulong2, &gulong2, gulong2.sizeof) == 0);\n\n    immutable uint4 luint4 = 0x8000_0000;\n    assert(memcmp(&luint4, &guint4, guint4.sizeof) == 0);\n\n    immutable ushort8 lushort8 = 0x8000;\n    assert(memcmp(&lushort8, &gushort8, gushort8.sizeof) == 0);\n\n    immutable ubyte16 lubyte16 = 0x80;\n    assert(memcmp(&lubyte16, &gubyte16, gubyte16.sizeof) == 0);\n\n\n    immutable long2 llong2 = 0x7000_0000_0000_0000;\n    assert(memcmp(&llong2, &glong2, glong2.sizeof) == 0);\n\n    immutable int4 lint4 = 0x7000_0000;\n    assert(memcmp(&lint4, &gint4, gint4.sizeof) == 0);\n\n    immutable short8 lshort8 = 0x7000;\n    assert(memcmp(&lshort8, &gshort8, gshort8.sizeof) == 0);\n\n    immutable byte16 lbyte16 = 0x70;\n    assert(memcmp(&lbyte16, &gbyte16, gbyte16.sizeof) == 0);\n\n\n    immutable float4 lfloat4 = 4.0;\n    assert(memcmp(&lfloat4, &gfloat4, gfloat4.sizeof) == 0);\n\n    immutable double2 ldouble2 = 8.0;\n    assert(memcmp(&ldouble2, &gdouble2, gdouble2.sizeof) == 0);\n}\n\n/*****************************************/\n\nvoid test7413()\n{\n    byte16 b = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];\n    assert(b.array[0] == 1);\n    assert(b.array[1] == 2);\n    assert(b.array[2] == 3);\n    assert(b.array[3] == 4);\n    assert(b.array[4] == 5);\n    assert(b.array[5] == 6);\n    assert(b.array[6] == 7);\n    assert(b.array[7] == 8);\n    assert(b.array[8] == 9);\n    assert(b.array[9] == 10);\n    assert(b.array[10] == 11);\n    assert(b.array[11] == 12);\n    assert(b.array[12] == 13);\n    assert(b.array[13] == 14);\n    assert(b.array[14] == 15);\n    assert(b.array[15] == 16);\n\n    ubyte16 ub = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];\n    assert(ub.array[0] == 1);\n    assert(ub.array[1] == 2);\n    assert(ub.array[2] == 3);\n    assert(ub.array[3] == 4);\n    assert(ub.array[4] == 5);\n    assert(ub.array[5] == 6);\n    assert(ub.array[6] == 7);\n    assert(ub.array[7] == 8);\n    assert(ub.array[8] == 9);\n    assert(ub.array[9] == 10);\n    assert(ub.array[10] == 11);\n    assert(ub.array[11] == 12);\n    assert(ub.array[12] == 13);\n    assert(ub.array[13] == 14);\n    assert(ub.array[14] == 15);\n    assert(ub.array[15] == 16);\n\n    short8 s = [1,2,3,4,5,6,7,8];\n    assert(s.array[0] == 1);\n    assert(s.array[1] == 2);\n    assert(s.array[2] == 3);\n    assert(s.array[3] == 4);\n    assert(s.array[4] == 5);\n    assert(s.array[5] == 6);\n    assert(s.array[6] == 7);\n    assert(s.array[7] == 8);\n\n    ushort8 us = [1,2,3,4,5,6,7,8];\n    assert(us.array[0] == 1);\n    assert(us.array[1] == 2);\n    assert(us.array[2] == 3);\n    assert(us.array[3] == 4);\n    assert(us.array[4] == 5);\n    assert(us.array[5] == 6);\n    assert(us.array[6] == 7);\n    assert(us.array[7] == 8);\n\n    int4 i = [1,2,3,4];\n    assert(i.array[0] == 1);\n    assert(i.array[1] == 2);\n    assert(i.array[2] == 3);\n    assert(i.array[3] == 4);\n\n    uint4 ui = [1,2,3,4];\n    assert(ui.array[0] == 1);\n    assert(ui.array[1] == 2);\n    assert(ui.array[2] == 3);\n    assert(ui.array[3] == 4);\n\n    long2 l = [1,2];\n    assert(l.array[0] == 1);\n    assert(l.array[1] == 2);\n\n    ulong2 ul = [1,2];\n    assert(ul.array[0] == 1);\n    assert(ul.array[1] == 2);\n\n    float4 f = [1,2,3,4];\n    assert(f.array[0] == 1);\n    assert(f.array[1] == 2);\n    assert(f.array[2] == 3);\n    assert(f.array[3] == 4);\n\n    double2 d = [1,2];\n    assert(d.array[0] == 1);\n    assert(d.array[1] == 2);\n}\n\n/*****************************************/\n\nbyte16 b = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];\nubyte16 ub = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];\nshort8 s = [1,2,3,4,5,6,7,8];\nushort8 us = [1,2,3,4,5,6,7,8];\nint4 i = [1,2,3,4];\nuint4 ui = [1,2,3,4];\nlong2 l = [1,2];\nulong2 ul = [1,2];\nfloat4 f = [1,2,3,4];\ndouble2 d = [1,2];\n\nvoid test7413_2()\n{\n    assert(b.array[0] == 1);\n    assert(b.array[1] == 2);\n    assert(b.array[2] == 3);\n    assert(b.array[3] == 4);\n    assert(b.array[4] == 5);\n    assert(b.array[5] == 6);\n    assert(b.array[6] == 7);\n    assert(b.array[7] == 8);\n    assert(b.array[8] == 9);\n    assert(b.array[9] == 10);\n    assert(b.array[10] == 11);\n    assert(b.array[11] == 12);\n    assert(b.array[12] == 13);\n    assert(b.array[13] == 14);\n    assert(b.array[14] == 15);\n    assert(b.array[15] == 16);\n\n    assert(ub.array[0] == 1);\n    assert(ub.array[1] == 2);\n    assert(ub.array[2] == 3);\n    assert(ub.array[3] == 4);\n    assert(ub.array[4] == 5);\n    assert(ub.array[5] == 6);\n    assert(ub.array[6] == 7);\n    assert(ub.array[7] == 8);\n    assert(ub.array[8] == 9);\n    assert(ub.array[9] == 10);\n    assert(ub.array[10] == 11);\n    assert(ub.array[11] == 12);\n    assert(ub.array[12] == 13);\n    assert(ub.array[13] == 14);\n    assert(ub.array[14] == 15);\n    assert(ub.array[15] == 16);\n\n    assert(s.array[0] == 1);\n    assert(s.array[1] == 2);\n    assert(s.array[2] == 3);\n    assert(s.array[3] == 4);\n    assert(s.array[4] == 5);\n    assert(s.array[5] == 6);\n    assert(s.array[6] == 7);\n    assert(s.array[7] == 8);\n\n    assert(us.array[0] == 1);\n    assert(us.array[1] == 2);\n    assert(us.array[2] == 3);\n    assert(us.array[3] == 4);\n    assert(us.array[4] == 5);\n    assert(us.array[5] == 6);\n    assert(us.array[6] == 7);\n    assert(us.array[7] == 8);\n\n    assert(i.array[0] == 1);\n    assert(i.array[1] == 2);\n    assert(i.array[2] == 3);\n    assert(i.array[3] == 4);\n\n    assert(ui.array[0] == 1);\n    assert(ui.array[1] == 2);\n    assert(ui.array[2] == 3);\n    assert(ui.array[3] == 4);\n\n    assert(l.array[0] == 1);\n    assert(l.array[1] == 2);\n\n    assert(ul.array[0] == 1);\n    assert(ul.array[1] == 2);\n\n    assert(f.array[0] == 1);\n    assert(f.array[1] == 2);\n    assert(f.array[2] == 3);\n    assert(f.array[3] == 4);\n\n    assert(d.array[0] == 1);\n    assert(d.array[1] == 2);\n}\n\n/*****************************************/\n\nfloat bug8060(float x) {\n    int i = *cast(int*)&x;\n    ++i;\n    return *cast(float*)&i;\n}\n\n/*****************************************/\n/+\n// 9200\n\nvoid bar9200(double[2] a)\n{\n    assert(a[0] == 1);\n    assert(a[1] == 2);\n}\n\ndouble2 * v9200(double2* a)\n{\n    return a;\n}\n\nvoid test9200()\n{\n    double2 a = [1, 2];\n\n    *v9200(&a) = a;\n\n    bar9200(a.array);\n}\n+/\n\n/*****************************************/\n\n// 9304 and 9322\n\nfloat4 foo9304(float4 a)\n{\n    return -a;\n}\n\n\nvoid test9304()\n{\n    auto a = foo9304([0, 1, 2, 3]);\n    //writeln(a.array);\n    assert(a.array == [0,-1,-2,-3]);\n}\n\n/*****************************************/\n\nvoid test9910()\n{\n    float4 f = [1, 1, 1, 1];\n    auto works = f + 3;\n    auto bug = 3 + f;\n\n    assert (works.array == [4,4,4,4]);\n    assert (bug.array == [4,4,4,4]);    // no property 'array' for type 'int'\n}\n\n/*****************************************/\n\nbool normalize(double[] range, double sum = 1)\n{\n    double s = 0;\n    const length = range.length;\n    foreach (e; range)\n    {\n        s += e;\n    }\n    if (s == 0)\n    {\n        return false;\n    }\n    return true;\n}\n\nvoid test12852()\n{\n    double[3] range = [0.0, 0.0, 0.0];\n    assert(normalize(range[]) == false);\n    range[1] = 3.0;\n    assert(normalize(range[]) == true);\n}\n\n/*****************************************/\n\nvoid test9449()\n{\n    ubyte16[1] table;\n}\n\n/*****************************************/\n\nvoid test9449_2()\n{\n    float[4][2] m = [[2.0, 1, 3, 4], [5.0, 6, 7, 8]];   // segfault\n\n    assert(m[0][0] == 2.0);\n    assert(m[0][1] == 1);\n    assert(m[0][2] == 3);\n    assert(m[0][3] == 4);\n\n    assert(m[1][0] == 5.0);\n    assert(m[1][1] == 6);\n    assert(m[1][2] == 7);\n    assert(m[1][3] == 8);\n}\n\n/*****************************************/\n// 13841\n\nvoid test13841()\n{\n    alias Vector16s = TypeTuple!(\n        void16,  byte16,  short8,  int4,  long2,\n                ubyte16, ushort8, uint4, ulong2, float4, double2);\n    foreach (V1; Vector16s)\n    {\n        foreach (V2; Vector16s)\n        {\n            V1 v1 = void;\n            V2 v2 = void;\n            static if (is(V1 == V2))\n            {\n                static assert( is(typeof(true ? v1 : v2) == V1));\n            }\n            else\n            {\n                static assert(!is(typeof(true ? v1 : v2)));\n            }\n        }\n    }\n}\n\n/*****************************************/\n// 12776\n\nvoid test12776()\n{\n    alias Vector16s = TypeTuple!(\n        void16,  byte16,  short8,  int4,  long2,\n                ubyte16, ushort8, uint4, ulong2, float4, double2);\n    foreach (V; Vector16s)\n    {\n        static assert(is(typeof(                   V .init) ==                    V ));\n        static assert(is(typeof(             const(V).init) ==              const(V)));\n        static assert(is(typeof(       inout(      V).init) ==        inout(      V)));\n        static assert(is(typeof(       inout(const V).init) ==        inout(const V)));\n        static assert(is(typeof(shared(            V).init) == shared(            V)));\n        static assert(is(typeof(shared(      const V).init) == shared(      const V)));\n        static assert(is(typeof(shared(inout       V).init) == shared(inout       V)));\n        static assert(is(typeof(shared(inout const V).init) == shared(inout const V)));\n        static assert(is(typeof(         immutable(V).init) ==          immutable(V)));\n    }\n}\n\n/*****************************************/\n\nvoid foo13988(double[] arr)\n{\n    static ulong repr(double d) { return *cast(ulong*)&d; }\n    foreach (x; arr)\n        assert(repr(arr[0]) == *cast(ulong*)&(arr[0]));\n}\n\n\nvoid test13988()\n{\n    double[] arr = [3.0];\n    foo13988(arr);\n}\n\n/*****************************************/\n// 15123\n\nvoid test15123()\n{\n    alias Vector16s = TypeTuple!(\n        void16,  byte16,  short8,  int4,  long2,\n                ubyte16, ushort8, uint4, ulong2, float4, double2);\n    foreach (V; Vector16s)\n    {\n        auto x = V.init;\n    }\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15144\n\nvoid test15144()\n{\n        enum      ubyte16 csXMM1 = ['a','b','c',0,0,0,0,0];\n        __gshared ubyte16 csXMM2 = ['a','b','c',0,0,0,0,0];\n        immutable ubyte16 csXMM3 = ['a','b','c',0,0,0,0,0];\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13927\n\nvoid test13927(ulong2 a)\n{\n    ulong2 b = [long.min, long.min];\n    auto tmp = a - b;\n}\n\n/*****************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=16488\n\nvoid foo_byte16(byte t, byte s)\n{\n    byte16 f = s;\n    auto p = cast(byte*)&f;\n    foreach (i; 0 .. 16)\n        assert(p[i] == s);\n}\n\nvoid foo_ubyte16(ubyte t, ubyte s)\n{\n    ubyte16 f = s;\n    auto p = cast(ubyte*)&f;\n    foreach (i; 0 .. 16)\n        assert(p[i] == s);\n}\n\n\nvoid foo_short8(short t, short s)\n{\n    short8 f = s;\n    auto p = cast(short*)&f;\n    foreach (i; 0 .. 8)\n        assert(p[i] == s);\n}\n\nvoid foo_ushort8(ushort t, ushort s)\n{\n    ushort8 f = s;\n    auto p = cast(ushort*)&f;\n    foreach (i; 0 .. 8)\n        assert(p[i] == s);\n}\n\n\nvoid foo_int4(int t, int s)\n{\n    int4 f = s;\n    auto p = cast(int*)&f;\n    foreach (i; 0 .. 4)\n        assert(p[i] == s);\n}\n\nvoid foo_uint4(uint t, uint s, uint u)\n{\n    uint4 f = s;\n    auto p = cast(uint*)&f;\n    foreach (i; 0 .. 4)\n        assert(p[i] == s);\n}\n\n\nvoid foo_long2(long t, long s, long u)\n{\n    long2 f = s;\n    auto p = cast(long*)&f;\n    foreach (i; 0 .. 2)\n        assert(p[i] == s);\n}\n\nvoid foo_ulong2(ulong t, ulong s)\n{\n    ulong2 f = s;\n    auto p = cast(ulong*)&f;\n    foreach (i; 0 .. 2)\n        assert(p[i] == s);\n}\n\nvoid foo_float4(float t, float s)\n{\n    float4 f = s;\n    auto p = cast(float*)&f;\n    foreach (i; 0 .. 4)\n        assert(p[i] == s);\n}\n\nvoid foo_double2(double t, double s, double u)\n{\n    double2 f = s;\n    auto p = cast(double*)&f;\n    foreach (i; 0 .. 2)\n        assert(p[i] == s);\n}\n\n\nvoid test16448()\n{\n    foo_byte16(5, -10);\n    foo_ubyte16(5, 11);\n\n    foo_short8(5, -6);\n    foo_short8(5, 7);\n\n    foo_int4(5, -6);\n    foo_uint4(5, 0x12345678, 22);\n\n    foo_long2(5, -6, 1);\n    foo_ulong2(5, 0x12345678_87654321L);\n\n    foo_float4(5, -6);\n    foo_double2(5, -6, 2);\n}\n\n/*****************************************/\n\nvoid foo_byte32(byte t, byte s)\n{\n    byte32 f = s;\n    auto p = cast(byte*)&f;\n    foreach (i; 0 .. 32)\n        assert(p[i] == s);\n}\n\nvoid foo_ubyte32(ubyte t, ubyte s)\n{\n    ubyte32 f = s;\n    auto p = cast(ubyte*)&f;\n    foreach (i; 0 .. 32)\n        assert(p[i] == s);\n}\n\nvoid foo_short16(short t, short s)\n{\n    short16 f = s;\n    auto p = cast(short*)&f;\n    foreach (i; 0 .. 16)\n        assert(p[i] == s);\n}\n\nvoid foo_ushort16(ushort t, ushort s)\n{\n    ushort16 f = s;\n    auto p = cast(ushort*)&f;\n    foreach (i; 0 .. 16)\n        assert(p[i] == s);\n}\n\nvoid foo_int8(int t, int s)\n{\n    int8 f = s;\n    auto p = cast(int*)&f;\n    foreach (i; 0 .. 8)\n        assert(p[i] == s);\n}\n\nvoid foo_uint8(uint t, uint s, uint u)\n{\n    uint8 f = s;\n    auto p = cast(uint*)&f;\n    foreach (i; 0 .. 8)\n        assert(p[i] == s);\n}\n\nvoid foo_long4(long t, long s, long u)\n{\n    long4 f = s;\n    auto p = cast(long*)&f;\n    foreach (i; 0 .. 4)\n        assert(p[i] == s);\n}\n\nvoid foo_ulong4(ulong t, ulong s)\n{\n    ulong4 f = s;\n    auto p = cast(ulong*)&f;\n    foreach (i; 0 .. 4)\n        assert(p[i] == s);\n}\n\nvoid foo_float8(float t, float s)\n{\n    float8 f = s;\n    auto p = cast(float*)&f;\n    foreach (i; 0 .. 8)\n        assert(p[i] == s);\n}\n\nvoid foo_double4(double t, double s, double u)\n{\n    double4 f = s;\n    auto p = cast(double*)&f;\n    foreach (i; 0 .. 4)\n        assert(p[i] == s);\n}\n\nvoid test16448_32()\n{\n    import core.cpuid;\n    if (!core.cpuid.avx)\n        return;\n\n    foo_byte32(5, -10);\n    foo_ubyte32(5, 11);\n\n    foo_short16(5, -6);\n    foo_short16(5, 7);\n\n    foo_int8(5, -6);\n    foo_uint8(5, 0x12345678, 22);\n\n    foo_long4(5, -6, 1);\n    foo_ulong4(5, 0x12345678_87654321L);\n\n    foo_float8(5, -6);\n    foo_double4(5, -6, 2);\n}\n\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16703\n\nfloat index(float4 f4, size_t i)\n{\n    return f4[i];\n    //return (*cast(float[4]*)&f4)[2];\n}\n\nfloat[4] slice(float4 f4)\n{\n    return f4[];\n}\n\nfloat slice2(float4 f4, size_t lwr, size_t upr, size_t i)\n{\n    float[] fa = f4[lwr .. upr];\n    return fa[i];\n}\n\nvoid test16703()\n{\n    float4 f4 = [1,2,3,4];\n    assert(index(f4, 0) == 1);\n    assert(index(f4, 1) == 2);\n    assert(index(f4, 2) == 3);\n    assert(index(f4, 3) == 4);\n\n    float[4] fsa = slice(f4);\n    assert(fsa == [1.0f,2,3,4]);\n\n    assert(slice2(f4, 1, 3, 0) == 2);\n    assert(slice2(f4, 1, 3, 1) == 3);\n}\n\n/*****************************************/\n\nstruct Sunsto\n{\n  align (1): // make sure f4 is misaligned\n    byte b;\n    union\n    {\n        float4 f4;\n        ubyte[16] a;\n    }\n}\n\nubyte[16] foounsto()\n{\n    float4 vf = 6;\n    Sunsto s;\n    s.f4 = vf * 2;\n    vf = s.f4;\n\n    return s.a;\n}\n\nvoid testOPvecunsto()\n{\n    auto a = foounsto();\n    assert(a == [0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65]);\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10447\n\nvoid test10447()\n{\n    immutable __vector(double[2]) a = [1.0, 2.0];\n    __vector(double[2]) r;\n    r += a;\n    r = r * a;\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17237\n\nstruct S17237\n{\n    bool a;\n    struct\n    {\n        bool b;\n        int8 c;\n    }\n}\n\nstatic assert(S17237.a.offsetof == 0);\nstatic assert(S17237.b.offsetof == 32);\nstatic assert(S17237.c.offsetof == 64);\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16697\n\nstatic assert(!is(float == __vector));\nstatic assert(!is(float[1] == __vector));\nstatic assert(!is(float[4] == __vector));\nstatic assert( is(__vector(float[4]) == __vector));\nstatic assert(!is(__vector(float[3]) == __vector));\nstatic assert(!is(__vector(float[5]) == __vector));\nstatic assert( is(__vector(float[4]) X == __vector) && is(X == float[4]));\nstatic assert( is(__vector(byte[16]) X == __vector) && is(X == byte[16]));\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17720\n\nvoid test17720()\n{\n    alias Vector16s = TypeTuple!(\n        void16,  byte16,  short8,  int4,  long2,\n                ubyte16, ushort8, uint4, ulong2, float4, double2);\n    alias Vector32s = TypeTuple!(\n        void32,  byte32,  short16,  int8,  long4,\n                ubyte32, ushort16, uint8, ulong4, float8, double4);\n\n    // OK: __vector(T) -> __vector(void[]) of same size.\n    // NG: __vector(T) -> __vector(void[]) of different size.\n    // NG: explicit cast __vector(T) -> __vector(void[]) of different size.\n    foreach (V; Vector16s)\n    {\n        static assert( __traits(compiles, { void16 v = V.init; }));\n        static assert(!__traits(compiles, { void32 v = V.init; }));\n        static assert(!__traits(compiles, { void32 v = cast(void32)V.init; }));\n    }\n    foreach (V; Vector32s)\n    {\n        static assert( __traits(compiles, { void32 v = V.init; }));\n        static assert(!__traits(compiles, { void16 v = V.init; }));\n        static assert(!__traits(compiles, { void16 v = cast(void16)V.init; }));\n    }\n\n    // NG: __vector(T) -> __vector(T) of same size.\n    // OK: explicit cast __vector(T) -> __vector(T) of same size.\n    // NG: __vector(T) -> __vector(T) of different size.\n    // NG: explicit cast __vector(T) -> __vector(T) of different size.\n    foreach (V; Vector16s)\n    {\n        static if (is(V == double2))\n        {\n            static assert(!__traits(compiles, { long2 v = V.init; }));\n            static assert( __traits(compiles, { long2 v = cast(long2)V.init; }));\n        }\n        else\n        {\n            static assert(!__traits(compiles, { double2 v = V.init; }));\n            static assert( __traits(compiles, { double2 v = cast(double2)V.init; }));\n        }\n        static assert(!__traits(compiles, { double4 v = V.init; }));\n        static assert(!__traits(compiles, { double4 v = cast(double4)V.init; }));\n    }\n    foreach (V; Vector32s)\n    {\n        static if (is(V == double4))\n        {\n            static assert(!__traits(compiles, { long4 v = V.init; }));\n            static assert( __traits(compiles, { long4 v = cast(long4)V.init; }));\n        }\n        else\n        {\n            static assert(!__traits(compiles, { double4 v = V.init; }));\n            static assert( __traits(compiles, { double4 v = cast(double4)V.init; }));\n        }\n        static assert(!__traits(compiles, { double2 v = V.init; }));\n        static assert(!__traits(compiles, { double2 v = cast(double2)V.init; }));\n    }\n}\n\n/*****************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=17695\n\nvoid test17695(__vector(ubyte[16]) a)\n{\n    auto b = -a;\n}\n\n/*****************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test2b();\n    test2c();\n    test2d();\n    test2e();\n    test2f();\n    test2g();\n    test2h();\n    test2i();\n    test2j();\n\n    test4();\n    test7411();\n\n    test7951();\n    test7951_2();\n    test7414();\n    test7413();\n    test7413_2();\n//    test9200();\n    test9304();\n    test9910();\n    test12852();\n    test9449();\n    test9449_2();\n    test13988();\n    test16448();\n    test16448_32();\n    test16703();\n    testOPvecunsto();\n    test10447();\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/99bottles.d",
    "content": "// written by Don Clugston:\n//    http://www.digitalmars.com/d/archives/digitalmars/D/announce/4374.html\n//    http://www.99-bottles-of-beer.net/language-d-1212.html\n\n// Displays the \"99 bottles of beer\" song at compile time,\n// using the template metaprograming facilities of D. \n// No executable is generated. No libraries are used.\n// Illustrates template default values, template string value parameters,\n// compile-time concatenation of constant strings, static if.\n\nmodule bottles99;\n\ntemplate decimaldigit(int n) {\n    const string decimaldigit = \"0123456789\"[n..n+1];\n}\n\ntemplate itoa(ulong n)\n{\n    static if ( n < 10L )\n\tconst string itoa = decimaldigit!(n);\n    else\n\tconst string itoa = itoa!( n / 10L ) ~ decimaldigit!( n % 10L );\n}\n\ntemplate showHowMany(int n, string where, bool needcapital = false)\n{\n  static if ( n > 1 ) \n      const string showHowMany = itoa!(n) ~ \" bottles of beer\" ~ where ~ \"\\n\";\n  else static if ( n == 1 )\n      const string showHowMany = \"1 bottle of beer\" ~ where ~ \"\\n\";\n  else static if ( needcapital )\n      const string showHowMany = \"No more bottles of beer\" ~ where ~ \"\\n\";\n  else \n      const string showHowMany = \"no more bottles of beer\" ~ where ~ \"\\n\";\n}\n\ntemplate beer(int maxbeers, int n = maxbeers)\n{\n  static if ( n > 0 )\n    const string beer = showHowMany!(n, \" on the wall,\", true)\n        ~ showHowMany!(n, \".\")\n        ~ \"Take one down and pass it around, \" ~ \"\\n\" \n        ~ showHowMany!( n - 1 , \" on the wall.\") \n        ~ \"\\n\" ~ beer!(maxbeers, n - 1); // recurse for subsequent verses.\n  else\n    const string beer = showHowMany!(n, \" on the wall,\", true)\n        ~ showHowMany!(n, \".\")\n        ~ \"Go to the store and buy some more, \" ~ \"\\n\"\n        ~ showHowMany!( maxbeers, \" on the wall.\");\n}\n\npragma(msg, beer!(99));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/Test16206.d",
    "content": "struct S {\n    static int foo()() { return 0; }\n    static int foo()(int n) { return 1; }\n    static int foo(string s) { return 2; }\n    enum foo(int[] arr) = arr.length;\n}\n\nalias AliasSeq(T...) = T;\n\nalias allFoos = AliasSeq!(__traits(getOverloads, S, \"foo\", true));\n\nstatic assert(allFoos.length == 4);\n\nstatic assert(allFoos[0](\"\") == 2);\nstatic assert(allFoos[1]() == 0);\nstatic assert(allFoos[2](1) == 1);\nalias foo3 = allFoos[3];\nstatic assert(foo3!([]) == 0);\n\nstatic assert(S.foo() == 0);\nstatic assert(S.foo(1) == 1);\nstatic assert(S.foo(\"\") == 2);\nstatic assert(S.foo!([]) == 0);\n\n\nalias fooFuns = AliasSeq!(__traits(getOverloads, S, \"foo\"));\nstatic assert(fooFuns.length == 1);\nstatic assert(fooFuns[0](\"\") == 2);"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/a3682.d",
    "content": "// COMPILED_IMPORTS: imports/b3682.d\n// PERMUTE_ARGS:\n\n// https://issues.dlang.org/show_bug.cgi?id=3682\n\nstruct Tuple(Types...)\n{\n    Tuple!(Types[0..1]) slice()()\n    {\n        Tuple!(Types[0..1]) x;\n        return x;\n    }\n\n    void fail()\n    {\n        Tuple!(float, double, int) a;\n        auto s = a.slice();\n        static assert(is(typeof(s) == Tuple!(float)));\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/aggr_alignment.d",
    "content": "struct S1 // overall alignment: max(1, 1) = 1\n{\n    byte[5] bytes;\n    struct // overall alignment: max(1, 1) = 1\n    {\n        byte byte1;\n        align(1) int int1;\n    }\n}\n\nstatic assert(S1.int1.offsetof == 6);\nstatic assert(S1.alignof == 1);\nstatic assert(S1.sizeof == 10);\n\nclass C2 // overall alignment: max(vtbl.alignof, monitor.alignof, 1, 2)\n{\n    byte[5] bytes;\n    struct // overall alignment: max(1, 2) = 2\n    {\n        byte byte1;\n        align(2) int int1;\n    }\n}\n\nenum payloadOffset = C2.bytes.offsetof;\nstatic assert(C2.int1.offsetof == payloadOffset + 8);\nstatic assert(C2.alignof == size_t.sizeof);\nstatic assert(__traits(classInstanceSize, C2) == payloadOffset + 12);\n\nalign(8) struct PaddedStruct\n{\n    bool flag;\n    align(2) S1 s1;\n}\n\nstatic assert(PaddedStruct.s1.offsetof == 2);\nstatic assert(PaddedStruct.alignof == 8);\nstatic assert(PaddedStruct.sizeof == 16);\n\nalign(1) struct UglyStruct\n{\n    bool flag;\n    int i;\n    ubyte u;\n}\n\nstatic assert(UglyStruct.i.offsetof == 4);\nstatic assert(UglyStruct.alignof == 1);\nstatic assert(UglyStruct.sizeof == 9);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/aliasdecl.d",
    "content": "template Test(T){ alias Type = T; }\n\nalias X1 = int;\nstatic assert(is(X1 == int));\n\nalias X2 = immutable(long)[], X3 = shared const double[int];\nstatic assert(is(X2 == immutable(long)[]));\nstatic assert(is(X3 == shared const double[int]));\n\nalias X4 = void delegate() const, X5 = Test!int;\nstatic assert(is(X4 == void delegate() const));\nstatic assert(is(X5.Type == int));\n\nalias FP5 = extern(C) pure nothrow @safe @nogc void function(),\n      DG5 = extern(D) pure nothrow @safe @nogc void delegate();\nstatic assert(FP5.stringof == \"extern (C) void function() pure nothrow \" /* ~ \"@safe \" */ ~ \"@nogc\");\nstatic assert(DG5.stringof ==            \"void delegate() pure nothrow \" /* ~ \"@safe \" */ ~ \"@nogc\");\n\nvoid main()\n{\n    alias Y1 = int;\n    static assert(is(Y1 == int));\n\n    alias Y2 = immutable(long)[], Y3 = shared const double[int];\n    static assert(is(Y2 == immutable(long)[]));\n    static assert(is(Y3 == shared const double[int]));\n\n    alias Y4 = void delegate() const, Y5 = Test!int;\n    static assert(is(Y4 == void delegate() const));\n    static assert(is(Y5.Type == int));\n\n    // https://issues.dlang.org/show_bug.cgi?id=18429\n    struct S\n    {\n        alias a this;\n        enum a = 1;\n    }\n\n /+ struct S\n    {\n        int value;\n        alias this = value;\n    }\n    auto s = S(10);\n    int n = s;\n    assert(n == 10); +/\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/alignment.d",
    "content": "/* Test alignment of stack variables.\n *\n * This test should be moved to \"runnable\" once DMD implements alignment of stack variables.\n */\n\nvoid main()\n{\n    byte dummy;\n\n    align(32) int align32;\n    assert((cast(size_t)&align32 & cast(size_t)0b11111) == 0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/art4769.d",
    "content": "// http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.bugs&article_id=4769\n\n// COMPILED_IMPORTS: imports/art4769a.d imports/art4769b.d\n// PERMUTE_ARGS:\n\nmodule art4769;\n\nprivate import imports.art4769a;\n\nstruct Vector(T)\n{\n    DataStreamability!(T).footype f;\n\n    static if (DataStreamability!(T).isStreamable)\n\tvoid writeTo()\n\t{\n\t}\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b11118.d",
    "content": "struct X(size_t Z)\n{\n    void set(T)(T[Z] v...)\n    {\n    }\n}\n\nvoid main()\n{\n    X!3 a;\n    a.set(1,2,3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b1215.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -o-\n\nstruct A(Args...)\n{\n    enum i = 1;\n\n    // base use case.\n    Args[0].T mBase;\n    static assert(is(typeof(mBase) == B.T));\n    // chained types\n    Args[0].T.TT mChain;\n    static assert(is(typeof(mChain) == B.T.TT));\n    // chained packs\n    Args[1+1].FArgs[0] mChainPack;\n    static assert(is(typeof(mChainPack) == B));\n    // expr\n    enum mExpr = Args[1].i;\n    static assert(mExpr == B.i);\n    // Nested + index eval\n    Args[Args[0].i2].T mNested;\n    static assert(is(typeof(mNested) == B.T));\n    // index with constexpr\n    Args[i].T mCEIndex;\n    static assert(is(typeof(mCEIndex) == B.T));\n    // Nested + index with constexpr\n    Args[Args[i].i2].T mNestedCE;\n    static assert(is(typeof(mNestedCE) == B.T));\n\n    // alias, base use case\n    alias UBase = Args[0].T;\n    static assert(is(UBase == B.T));\n    // alias, chained types\n    alias UChain = Args[0].T.TT;\n    static assert(is(UChain == B.T.TT));\n    // alias, chained packs\n    alias UChainPack = Args[1+1].FArgs[0];\n    static assert(is(UChainPack == B));\n    // alias, expr\n    alias uExpr = Args[1].i;\n    static assert(uExpr == B.i);\n    // alias, Nested + index eval\n    alias UNested = Args[Args[0].i2].T;\n    static assert(is(UNested == B.T));\n    // alias, index with constexpr\n    alias UCEIndex = Args[i].T;\n    static assert(is(UCEIndex == B.T));\n    // alias, Nested + index with constexpr\n    alias UNextedCE = Args[Args[i].i2].T;\n    static assert(is(UNextedCE == B.T));\n}\n\nstruct B\n{\n    struct T\n    {\n        struct TT\n        {\n        }\n    }\n    enum i = 6;\n    enum i2 = 0;\n}\n\nstruct C(Args...)\n{\n    alias FArgs = Args;\n}\n\nalias Z = A!(B,B,C!(B,B));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14889\n\nstruct A14889(alias Exc)\n{\n    alias ExceptionType = Exc;\n}\nalias TT14889(Args...) = Args;\n\nalias X14889a = TT14889!(A14889!Throwable());\nalias Y14889a = X14889a[0].ExceptionType;\n\nalias X14889b = TT14889!(A14889!Throwable);\nalias Y14889b = X14889b[0].ExceptionType;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14889\n\nalias TypeTuple14900(T...) = T;\n\nstruct S14900\n{\n    alias T = int;\n    alias U = TypeTuple14900!(long,string);\n}\n\nalias Types14900 = TypeTuple14900!(S14900, S14900);\n\nTypes14900[0].T a14900;     // Types[0] == S, then typeof(a) == S.T == int\nTypes14900[0].U[1] b14900;  // Types[0].U == S.U, then typeof(b) == S.U[1] == string\n\nvoid test14900()\n{\n    Types14900[0].T a;      // Types[0] == S, then typeof(a) == S.T == int\n    Types14900[0].U[1] b;   // Types[0].U == S.U, then typeof(b) == S.U[1] == string\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14911\n\nvoid test14911()\n{\n    struct S {}\n\n    int* buf1 = new int[2].ptr; // OK\n    S* buf2 = (new S[2]).ptr;   // OK\n    S* buf3 = new S[2].ptr;     // OK <- broken\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14986\n\nalias Id14986(alias a) = a;\n\nstruct Foo14986\n{\n    int tsize;\n}\nstruct Bar14986\n{\n    enum Foo14986[] arr = [Foo14986()];\n}\n\nBar14986 test14986()\n{\n    Foo14986[] types;\n    auto a1 = new void[types[0].tsize];                 // TypeIdentifier::toExpression\n    auto a2 = new void[Id14986!types[0].tsize];         // TypeInstance::toExpression\n\n    Bar14986 bar;\n    auto a3 = Id14986!(typeof(bar).arr[0].tsize);       // TypeTypeof::resolve\n    auto a4 = Id14986!(typeof(return).arr[0].tsize);    // TypeReturn::resolve\n\n    return Bar14986();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b15428.d",
    "content": "class A\n{\n    this() {}\n}\n\nclass B : A\n{\n    this()\n    {\n        static if (__traits(compiles, super()))\n            super();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b16244.d",
    "content": "struct Foo\n{\n    void bar()(typeof(cast()this) x)\n    {\n    }\n}\n\nvoid main()\n{\n    Foo x;\n    x.bar(x);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b16346.d",
    "content": "enum A { B }\nstatic assert(is(typeof(A.B) == A));\nstatic assert(is(typeof(A(A.B)) == A));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b16355.d",
    "content": "// REQUIRED_ARGS: -c\nstruct S0 { this(this) {} }\nstruct S1 { S0[2] x; }\nstruct S2 { S0[0] x; }\n\n// S0 has an explicit and a compiler-generated postblit\nstatic assert( __traits(hasMember, S0, \"__postblit\"));\nstatic assert( __traits(hasMember, S0, \"__xpostblit\"));\n// S1 has only the compiler-generated postblit\nstatic assert(!__traits(hasMember, S1, \"__postblit\"));\nstatic assert( __traits(hasMember, S1, \"__xpostblit\"));\n// S2 has no postblit at all since the x array has zero length\nstatic assert(!__traits(hasMember, S2, \"__postblit\"));\nstatic assert(!__traits(hasMember, S2, \"__xpostblit\"));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b16382.d",
    "content": "// REQUIRED_ARGS: -c\nstruct S0 {\n    void foo() {\n        pragma(msg, &this);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b16483.d",
    "content": "struct S\n{\n    enum a = is(typeof(false.bar!(x => x))); // The lambda compiles\n    enum b = is(typeof(false.bar!(x => y))); // The lambda doesn't compile\n}\nauto bar(alias foo)(bool var)\n{\n    return foo(var);\n}\nstatic assert(is(typeof(S.a) == bool));\nstatic assert(S.a == true);\nstatic assert(S.b == false);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b16598.d",
    "content": "struct S\n{\n    this(int) {}\n    ~this() {}\n}\n\nint g(S a, S b)\n{\n    return 1;\n}\n\nvoid main()\n{\n    true ? g(S(), S(1)) : {}();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b16697.d",
    "content": "version(D_SIMD)\n{\n    static assert(!is(         float       == __vector)); \n    static assert(!is(         float[1]    == __vector)); \n    static assert(!is(         float[4]    == __vector)); \n    static assert( is(__vector(float[4])   == __vector)); \n    static assert(!is(__vector(float[3])   == __vector)); \n    static assert(!is(__vector(float[5])   == __vector)); \n    static assert( is(__vector(float[4]) X == __vector) &&\n                   is(X == float[4])); \n    static assert( is(__vector(byte[16]) X == __vector) &&\n                   is(X == byte[16])); \n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b16967.d",
    "content": "/* \n * REQUIRED_ARGS: -c\n * TEST_OUTPUT:\n---\ncompilable/b16967.d(16): Deprecation: switch case fallthrough - use 'goto default;' if intended\ncompilable/b16967.d(26): Deprecation: switch case fallthrough - use 'goto default;' if intended\n---\n*/\nint foo(int x)\nin\n{\n    switch (x)\n    {\n        case 1:\n            assert(x != 0);\n        default:\n            break;\n    }\n}\nout(v)\n{\n    switch(v)\n    {\n        case 42:\n            assert(x != 0);\n        default:\n            break;\n    }\n}\nbody\n{\n    return 42;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b17111.d",
    "content": "alias TestType = ubyte;\n\nvoid test()\n{\n    TestType a,b,c;\n\n    switch(c)\n    {\n        case a: break;\n        case (cast(ushort)b): break;\n        default: assert(false);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b18197.d",
    "content": "// REQUIRED_ARGS: -c -m32 -O -inline\n\nstruct A\n{\n    double a;\n}\n\nA makeA(double value)\n{\n    return A(value);\n}\n\ndouble test(double x)\n{\n    ulong p = *cast(ulong *)&x;\n    return makeA(x).a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b18242.d",
    "content": "// REQUIRED_ARGS: -c\n// PERMUTE_ARGS:\nmodule object;\n\nclass Object { }\n\nclass TypeInfo { }\nclass TypeInfo_Class : TypeInfo \n{ \n    version(D_LP64) { ubyte[136] _x; } else { ubyte[68] _x; }\n}\n\nclass Throwable { }\n\nint _d_run_main() \n{\n    try { } catch(Throwable e) { return 1; }\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b18489.d",
    "content": "// REQUIRED_ARGS: -O -m64\nimport core.simd;\n\ndouble dot (double2 a) {\n    return a.ptr[0] * a.ptr[1];\n}\n\nvoid main () { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b33.d",
    "content": "// COMPILED_IMPORTS: imports/b33a.d\n// PERMUTE_ARGS:\n\nmodule b33;\n\nprivate import imports.b33a;\n\nsize_t fn()\n{\n    return find( \"123\" );\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b6227.d",
    "content": "enum X {\n    O,\n    R\n}\nenum Y {\n    U\n}\nstatic assert( (X.O == cast(const)X.O));\nstatic assert( (X.O == X.O));\nstatic assert( (X.O != X.R));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/b6395.d",
    "content": "// REQUIRED_ARGS: -Icompilable/extra-files\n// EXTRA_FILES: extra-files/c6395.d\n\n// https://issues.dlang.org/show_bug.cgi?id=6395\n\nimport c6395;\n\nint regex(string pattern)\n{\n  return 0;\n}\n\nbool match(string r)\n{\n  return true;\n}\n\nvoid applyNoRemoveRegex()\n{\n  void scan(string[] noRemoveStr, string e)\n  {\n    auto a = find!((a){return match(e);})(map!regex(noRemoveStr));\n  }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/betterCarray.d",
    "content": "/* REQUIRED_ARGS: -betterC\n   PERMUTE_ARGS:\n*/\n\nimport core.stdc.stdio;\n\nextern (C) int main(char** argv, int argc) {\n    printf(\"hello world\\n\");\n    int[3] a;\n    foo(a[], 3);\n    return 0;\n}\n\nint foo(int[] a, int i)\n{\n    return a[i];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/betterCswitch.d",
    "content": "import core.stdc.stdio;\n\nextern (C) int main(char** argv, int argc) {\n    printf(\"hello world\\n\");\n    foo(3);\n    return 0;\n}\n\nint foo(int i)\n{\n    final switch (i)\n    {\n\tcase 1: break;\n    }\n    return i;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/betterc.d",
    "content": "/* REQUIRED_ARGS: -betterC\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17787\nversion (D_BetterC)\n{\n}\nelse\n{\n    static assert(0);\n}\n\n// -betterC does not support `ModuleInfo`, `TypeInfo`, or exception handling\nversion (D_ModuleInfo)\n{\n    static assert(0);\n}\n\nversion (D_Exceptions)\n{\n    static assert(0);\n}\n\nversion (D_TypeInfo)\n{\n    static assert(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/bug11735.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nprint string\nprint wstring\nprint dstring\nيطبع الترميز الموحد\nيطبع الترميز الموحد\nيطبع الترميز الموحد\nfoo_str\nfoo_wstr\nfoo_dstr\n---\n*/\n\npragma(msg, \"print string\");\npragma(msg, \"print wstring\"w);\npragma(msg, \"print dstring\"d);\n\npragma(msg, \"يطبع الترميز الموحد\");\npragma(msg, \"يطبع الترميز الموحد\"w);\npragma(msg, \"يطبع الترميز الموحد\"d);\n\nvoid main()\n{\n    enum a = \"foo_str\";\n    enum b = \"foo_wstr\"w;\n    enum c = \"foo_dstr\"d;\n\n    pragma(msg, a);\n    pragma(msg, b);\n    pragma(msg, c);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/bug6963.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS:\n\n/*\nTEST_OUTPUT:\n---\noutput foo: 1e: pure nothrow @nogc @safe void(int x)\noutput foo: 3e: pure nothrow @nogc @safe void(int x)\n---\n*/\n\nalias void function(int) pure nothrow @safe @nogc FuncPtrType;\n\nvoid foo1a(X)(X x) {}\nvoid foo1b(X)(X x) {}\nvoid foo1c(X)(X x) {}\nvoid foo1d(X)(X x) {}\nvoid foo1e(X)(X x) {}\n\n// module level declaration with type inference\nauto fptr1 = &foo1a!int;\nstatic assert(is(typeof(fptr1) == FuncPtrType));\n\n// array initializer\nauto fptrlist1 = [&foo1b!int];\nstatic assert(is(typeof(fptrlist1) == FuncPtrType[]));\n\n// static assert\nstatic assert(is(typeof(&foo1c!int) == FuncPtrType));\n\n// static if\nstatic if(is(typeof(&foo1d!int) PF))\n    static assert(is(PF == FuncPtrType));\nelse\n    static assert(0);\n\n// pragma test\npragma(msg, \"output foo: 1e: \", typeof(foo1e!int).stringof);\n\nvoid foo2a(X)(X x) {}\nvoid foo2b(X)(X x) {}\nvoid foo2c(X)(X x) {}\n\nFuncPtrType fptr3 = &foo2a!int;     // most similar to original issue\n\nFuncPtrType[] fptrlist3 = [&foo2b!int];\n\nstruct S{ FuncPtrType fp; }\nS s = { &foo2c!int };\n\nvoid foo3a(X)(X x) {}\nvoid foo3b(X)(X x) {}\nvoid foo3c(X)(X x) {}\nvoid foo3d(X)(X x) {}\nvoid foo3e(X)(X x) {}\n\nvoid main()\n{\n    auto fptr2 = &foo3a!int;\n    static assert(is(typeof(fptr2) == FuncPtrType));\n\n    auto fptrlist2 = [&foo3b!int];\n    static assert(is(typeof(fptrlist2) == FuncPtrType[]));\n\n    static assert(is(typeof(&foo1c!int) == FuncPtrType));\n\n    static if(is(typeof(&foo1d!int) PF))\n        static assert(is(PF == FuncPtrType));\n    else\n        static assert(0);\n\n    pragma(msg, \"output foo: 3e: \", typeof(foo3e!int));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/callconv.d",
    "content": "// PERMUTE_ARGS:\n\nimport core.stdc.stdarg;\n\nstruct ABC\n{\n\tint[4] x;\n}\n\nABC abc;\n\nint x,y,z;\n\nextern (Pascal):\nABC test1(int xx, int yy, int zz)\n{\n    x = xx;\n    y = yy;\n    z = zz;\n    return abc;\n}\n\nextern (Pascal):\nABC test1v(int xx, int yy, int zz, ...)\n{\n    x = xx;\n    y = yy;\n    z = zz;\n    return abc;\n}\n\nextern (C):\nABC test2v(int xx, int yy, int zz, ...)\n{\n    x = xx;\n    y = yy;\n    z = zz;\n    return abc;\n}\n\nextern (C++):\nABC test3(int xx, int yy, int zz)\n{\n    x = xx;\n    y = yy;\n    z = zz;\n    return abc;\n}\n\nABC test3v(int xx, int yy, int zz, ...)\n{\n    x = xx;\n    y = yy;\n    z = zz;\n    return abc;\n}\n\nextern (D):\nABC test4(int xx, int yy, int zz)\n{\n    x = xx;\n    y = yy;\n    z = zz;\n    return abc;\n}\n\nABC test4v(int xx, int yy, int zz, ...)\n{\n    x = xx;\n    y = yy;\n    z = zz;\n    return abc;\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/checkimports3.d",
    "content": "/*\nREQUIRED_ARGS: -transition=checkimports -de\n*/\nimport imports.checkimports3a;\nimport imports.checkimports3b;\nimport imports.checkimports3c;\n\nvoid test()\n{\n    foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/compile1.d",
    "content": "// PERMUTE_ARGS:\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1748\n// class template with stringof\n\nstruct S1748(T) {}\nstatic assert(S1748!int.stringof == \"S1748!int\");\n\nclass C1748(T) {}\nstatic assert(C1748!int.stringof == \"C1748!int\");\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2354\n// pragma + single semicolon DeclarationBlock\n\nversion(all)\n    pragma(msg, \"true\");\nelse\n    pragma(msg, \"false\");\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2438\n\nalias void delegate() Dg2438;\n\nalias typeof(Dg2438.ptr)     CP2438a;\nalias typeof(Dg2438.funcptr) FP2438a;\nstatic assert(is(CP2438a == void*));\nstatic assert(is(FP2438a == void function()));\n\nalias typeof(Dg2438.init.ptr)     CP2438b;\nalias typeof(Dg2438.init.funcptr) FP2438b;\nstatic assert(is(CP2438b == void*));\nstatic assert(is(FP2438b == void function()));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4225\n\nstruct Foo4225\n{\n    enum x = Foo4225();\n\n    static Foo4225 opCall()\n    {\n        return Foo4225.init;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5996\n// ICE(expression.c)\n\ntemplate T5996(T)\n{\n    auto bug5996() {\n        if (anyOldGarbage) {}\n        return 2;\n    }\n}\nstatic assert(!is(typeof(T5996!(int).bug5996())));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8532\n// segfault(mtype.c) - type inference + pure\n\nauto segfault8532(Y, R ...)(R r, Y val) pure\n{ return segfault8532(r, val); }\n\nstatic assert(!is(typeof( segfault8532(1,2,3))));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8982\n// ICE(ctfeexpr.c) __parameters with error in default value\n\ntemplate ice8982(T)\n{\n    void bug8982(ref const int v = 7){}\n\n    static if (is(typeof(bug8982) P == __parameters)) {\n        pragma(msg, ((P[0..1] g) => g[0])());\n    }\n}\n\nstatic assert(!is(ice8982!(int)));\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8801\n// ICE assigning to __ctfe\n\nstatic assert(!is(typeof( { bool __ctfe= true; })));\nstatic assert(!is(typeof( { __ctfe |= true; })));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5932\n// https://issues.dlang.org/show_bug.cgi?id=6675\n// ICE(s2ir.c), ICE(glue.c)\n\nvoid bug3932(T)() {\n    static assert( 0 );\n    func5932( 7 );\n}\n\nvoid func5932(T)( T val ) {\n    void onStandardMsg() {\n        foreach( t; T ) { }\n    }\n}\n\nstatic assert(!is(typeof(\n    {\n        bug3932!(int)();\n    }()\n)));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6650\n// ICE(glue.c) or wrong-code\n\nauto bug6650(X)(X y)\n{\n    X q;\n    q = \"abc\";\n    return y;\n}\n\nstatic assert(!is(typeof(bug6650!(int)(6))));\nstatic assert(!is(typeof(bug6650!(int)(18))));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14710\n// VC-built DMD crashes on templated variadic function IFTI\n\nvoid bug14710a(T)(T val, T[] arr...)\n{\n}\n\nvoid bug14710b()\n{\n    bug14710a(\"\", \"\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6661\n// Templates instantiated only through is(typeof()) shouldn't cause errors\n\ntemplate bug6661(Q)\n{\n    int qutz(Q y)\n    {\n        Q q = \"abc\";\n        return 67;\n    }\n    static assert(qutz(13).sizeof!=299);\n    const Q blaz = 6;\n}\n\nstatic assert(!is(typeof(bug6661!(int).blaz)));\n\ntemplate bug6661x(Q)\n{\n    int qutz(Q y)\n    {\n        Q q = \"abc\";\n        return 67;\n    }\n}\n// should pass, but doesn't in current\n//static assert(!is(typeof(bug6661x!(int))));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6599\n// ICE(constfold.c) or segfault\n\nstring bug6599extraTest(string x) { return x ~ \"abc\"; }\n\ntemplate Bug6599(X)\n{\n    class Orbit\n    {\n        Repository repository = Repository();\n    }\n\n    struct Repository\n    {\n        string fileProtocol = \"file://\";\n        string blah = bug6599extraTest(\"abc\");\n        string source = fileProtocol ~ \"/usr/local/orbit/repository\";\n    }\n}\n\nstatic assert(!is(typeof(Bug6599!int)));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8422\n// TypeTuple of tuples can't be read at compile time\n\ntemplate TypeTuple8422(TList...)\n{\n    alias TList TypeTuple8422;\n}\n\nstruct S8422 { int x; }\n\nvoid test8422()\n{\n    enum a = S8422(1);\n    enum b = S8422(2);\n    enum c = [1,2,3];\n    foreach(t; TypeTuple8422!(b, a)) {\n        enum u = t;\n    }\n    foreach(t; TypeTuple8422!(c)) {\n        enum v = t;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6096\n// ICE(el.c) with -O\n\ncdouble c6096;\n\nint bug6096()\n{\n    if (c6096) return 0;\n    return 1;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7681\n// Segfault\n\nstatic assert( !is(typeof( (){\n      undefined ~= delegate(){}; return 7;\n  }())));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8639\n// Buffer overflow\n\nvoid t8639(alias a)() {}\nvoid bug8639() {\n  t8639!({auto r = -real.max;})();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7751\n// Segfault\n\nstatic assert( !is(typeof( (){\n    bar[]r; r ~= [];\n     return 7;\n  }())));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7639\n// Segfault\n\nstatic assert( !is(typeof( (){\n    enum foo =\n    [\n        str : \"functions\",\n    ];\n})));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11991\n\nvoid main()\n{\n    int Throwable;\n    int object;\n    try\n    {\n    }\n    catch(.object.Throwable)\n    {\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11939\n\nvoid test11939()\n{\n    scope(failure)\n    {\n        import object : Object;\n    }\n    throw new Exception(\"\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5796\n\ntemplate A(B) {\n    pragma(msg, \"missing ;\")\n    enum X = 0;\n}\n\nstatic assert(!is(typeof(A!(int))));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6720\n\nvoid bug6720() { }\n\nstatic assert(!is(typeof(\ncast(bool)bug6720()\n)));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1099\n\ntemplate Mix1099(int a) {\n   alias typeof(this) ThisType;\n    static assert (ThisType.init.tupleof.length == 2);\n}\n\n\nstruct Foo1099 {\n    mixin Mix1099!(0);\n    int foo;\n    mixin Mix1099!(1);\n    int bar;\n    mixin Mix1099!(2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8788\n// super() and return\n\nclass B8788 {\n        this ( ) { }\n}\n\nclass C8788(int test) : B8788\n{\n    this ( int y )\n    {   // TESTS WHICH SHOULD PASS\n        static if (test == 1) {\n            if (y == 3) {\n                super();\n                return;\n            }\n            super();\n            return;\n        } else static if (test == 2) {\n            if (y == 3) {\n                super();\n                return;\n            }\n            super();\n        } else static if (test == 3) {\n            if (y > 3) {\n                if (y == 7) {\n                   super();\n                   return;\n                }\n                super();\n                return;\n            }\n            super();\n        } else static if (test == 4) {\n            if (y > 3) {\n                if (y == 7) {\n                   super();\n                   return;\n                }\n                else if (y> 5)\n                    super();\n                else super();\n                return;\n            }\n            super();\n        }\n        // TESTS WHICH SHOULD FAIL\n        else static if (test == 5) {\n            if (y == 3) {\n                super();\n                return;\n            }\n            return; // no super\n        } else static if (test == 6) {\n            if (y > 3) {\n                if (y == 7) {\n                   super();\n                   return;\n                }\n                super();\n            }\n            super(); // two calls\n        } else static if (test == 7) {\n            if (y == 3) {\n                return; // no super\n            }\n            super();\n        } else static if (test == 8) {\n            if (y > 3) {\n                if (y == 7) {\n                   return; // no super\n                }\n                super();\n                return;\n            }\n            super();\n        } else static if (test == 9) {\n            if (y > 3) {\n                if (y == 7) {\n                   super();\n                   return;\n                }\n                else if (y> 5)\n                    super();\n                else return; // no super\n                return;\n            }\n            super();\n        }\n    }\n}\n\nstatic assert( is(typeof( { new C8788!(1)(0); } )));\nstatic assert( is(typeof( { new C8788!(2)(0); } )));\nstatic assert( is(typeof( { new C8788!(3)(0); } )));\nstatic assert( is(typeof( { new C8788!(4)(0); } )));\nstatic assert(!is(typeof( { new C8788!(5)(0); } )));\nstatic assert(!is(typeof( { new C8788!(6)(0); } )));\nstatic assert(!is(typeof( { new C8788!(7)(0); } )));\nstatic assert(!is(typeof( { new C8788!(8)(0); } )));\nstatic assert(!is(typeof( { new C8788!(9)(0); } )));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4967\n// https://issues.dlang.org/show_bug.cgi?id=7058\n\nenum Bug7058 bug7058 = { 1.5f, 2};\nstatic assert(bug7058.z == 99);\n\nstruct Bug7058\n{\n     float x = 0;\n     float y = 0;\n     float z = 99;\n}\n\n\n/***************************************************/\n\nvoid test12094()\n{\n    auto n = null;\n    int *a;\n    int[int] b;\n    int[] c;\n    auto u = true ? null : a;\n    auto v = true ? null : b;\n    auto w = true ? null : c;\n    auto x = true ? n : a;\n    auto y = true ? n : b;\n    auto z = true ? n : c;\n    a = n;\n    b = n;\n    c = n;\n}\n\n/***************************************************/\n\ntemplate test8163(T...)\n{\n    struct Point\n    {\n        T fields;\n    }\n\n    enum N = 2; // N>=2 triggers the bug\n    extern Point[N] bar();\n\n    void foo()\n    {\n        Point[N] _ = bar();\n    }\n}\n\nalias test8163!(long) _l;\nalias test8163!(double) _d;\nalias test8163!(float, float) _ff;\nalias test8163!(int, int) _ii;\nalias test8163!(int, float) _if;\nalias test8163!(ushort, ushort, ushort, ushort) _SSSS;\nalias test8163!(ubyte, ubyte, ubyte, ubyte, ubyte, ubyte, ubyte, ubyte) _BBBBBBBB;\nalias test8163!(ubyte, ubyte, ushort, float) _BBSf;\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4757\n\nauto foo4757(T)(T)\n{\n    static struct Bar(T)\n    {\n        void spam()\n        {\n            foo4757(1);\n        }\n    }\n    return Bar!T();\n}\n\nvoid test4757()\n{\n    foo4757(1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9348\n\nvoid test9348()\n{\n    @property Object F(int E)() { return null; }\n\n    assert(F!0 !is null);\n    assert(F!0 !in [new Object():1]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9690\n\n@disable\n{\n    void dep9690() {}\n    void test9690()\n    {\n        dep9690();      // OK\n        void inner()\n        {\n            dep9690();  // OK <- NG\n        }\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9987\n\nstatic if (is(object.ModuleInfo == struct))\n{\n    struct ModuleInfo {}\n\n    static assert(!is(object.ModuleInfo == ModuleInfo));\n    static assert(object.ModuleInfo.sizeof != ModuleInfo.sizeof);\n}\nstatic if (is(object.ModuleInfo == class))\n{\n    class ModuleInfo {}\n\n    static assert(!is(object.ModuleInfo == ModuleInfo));\n    static assert(__traits(classInstanceSize, object.ModuleInfo) !=\n                  __traits(classInstanceSize, ModuleInfo));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10158\n\nclass Outer10158\n{\n    static struct Inner\n    {\n        int f;\n    }\n\n    void test()\n    {\n        static assert( Inner.f .offsetof == 0);  // OK <- NG\n        static assert((Inner.f).offsetof == 0);  // OK\n    }\n}\n\nvoid test10158()\n{\n    static assert(Outer10158.Inner.f.offsetof == 0);  // OK\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10326\n\nclass C10326\n{\n    int val;\n    invariant   { assert(val == 0); }\n    invariant() { assert(val == 0); }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11042\n\nstatic if           ((true  || error) == true ) {} else { static assert(0); }\nstatic if           ((false && error) == false) {} else { static assert(0); }\nstatic assert       ((true  || error) == true );\nstatic assert       ((false && error) == false);\nint f11042a1()() if ((true  || error) == true ) { return 0; }   enum x11042a1 = f11042a1();\nint f11042b1()() if ((false && error) == false) { return 0; }   enum x11042b1 = f11042b1();\n\nstatic if           (is(typeof(true  || error)) == false) {} else { static assert(0); }\nstatic if           (is(typeof(false && error)) == false) {} else { static assert(0); }\nstatic assert       (is(typeof(true  || error)) == false);\nstatic assert       (is(typeof(false && error)) == false);\nint f11042a2()() if (is(typeof(true  || error)) == false) { return 0; }   enum x11042a2 = f11042a2();\nint f11042b2()() if (is(typeof(false && error)) == false) { return 0; }   enum x11042b2 = f11042b2();\n\nstatic if           (__traits(compiles, true  || error) == false) {} else { static assert(0); }\nstatic if           (__traits(compiles, false && error) == false) {} else { static assert(0); }\nstatic assert       (__traits(compiles, true  || error) == false);\nstatic assert       (__traits(compiles, false && error) == false);\nint f11042a3()() if (__traits(compiles, true  || error) == false) { return 0; }   enum x11042a3 = f11042a3();\nint f11042b3()() if (__traits(compiles, false && error) == false) { return 0; }   enum x11042b3 = f11042b3();\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11554\n\nenum E11554;\nstatic assert(is(E11554 == enum));\n\nstruct Bro11554(N...) {}\nstatic assert(!is(E11554 unused : Bro11554!M, M...));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12302\n\ntemplate isCallable12302(T...)\n    if (T.length == 1)\n{\n    static if (is(typeof(& T[0].opCall) == delegate))\n        enum bool isCallable12302 = true;\n    else\n    static if (is(typeof(& T[0].opCall) V : V*) && is(V == function))\n        enum bool isCallable12302 = true;\n    else\n        enum bool isCallable12302 = true;\n}\n\nclass A12302\n{\n    struct X {}\n    X x;\n    auto opDispatch(string s, TArgs...)(TArgs args)\n    {\n        mixin(\"return x.\"~s~\"(args);\");\n    }\n}\n\nA12302 func12302() { return null; }\nenum b12302 = isCallable12302!func12302;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12476\n\ntemplate A12476(T) {  }\n\nstruct S12476(T)\n{\n    alias B = A12476!T;\n}\n\nclass C12476(T)\n{\n    alias B = A12476!T;\n}\n\nstruct Bar12476(alias Foo)\n{\n    Foo!int baz;\n    alias baz this;\n}\n\nalias Identity12476(alias A) = A;\n\nalias sb12476 = Identity12476!(Bar12476!S12476.B);\nalias cb12476 = Identity12476!(Bar12476!C12476.B);\n\nstatic assert(__traits(isSame, sb12476, A12476!int));\nstatic assert(__traits(isSame, cb12476, A12476!int));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12506\n\nimport imports.a12506;\nprivate           bool[9] r12506a = f12506!(i => true)(); // OK\nprivate immutable bool[9] r12506b = f12506!(i => true)(); // OK <- error\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12555\n\nclass A12555(T)\n{\n    Undef12555 error;\n}\n\nstatic assert(!__traits(compiles, {\n    class C : A12555!C  { }\n}));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11622\n\nclass A11622(T)\n{\n    B11622!T foo()\n    {\n        return new B11622!T;\n    }\n}\n\nclass B11622(T) : T\n{\n}\n\nstatic assert(!__traits(compiles, {\n    class C : A11622!C  { }\n}));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12688\n\nvoid writeln12688(A...)(A) {}\n\nstruct S12688\n{\n    int foo() @property { return 1; }\n}\n\nvoid test12688()\n{\n    S12688 s;\n    s.foo.writeln12688;   // ok\n    (s.foo).writeln12688; // ok <- ng\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12703\n\nstruct S12703\n{\n    this(int) {}\n}\n\nfinal class C12703\n{\n    S12703 s = S12703(1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12799\n\nstruct A12799\n{\n    int a;\n    enum C = A12799.sizeof;\n    enum D = C; // OK <- Error\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13236\n\npragma(msg, is(typeof({ struct S { S x; } })));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13280\n\nstruct S13280\n{\n    alias U = ubyte;\n    alias T1 =       ubyte[this.sizeof]; // ok\n    alias T2 = const     U[this.sizeof]; // ok\n    alias T3 = const ubyte[this.sizeof]; // ok <- error\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13481\n\nmixin template Mix13481(void function() callback)\n{\n    static this()\n    {\n        callback();\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13564\n\nclass E13564(T)\n{\n    int pos;\n}\n\nclass C13564(T)\n{\n    struct S\n    {\n        ~this()\n        {\n            C13564!int c;\n            c.element.pos = 0;\n        }\n    }\n\n    E13564!T element;\n}\n\nvoid test13564()\n{\n    auto c = new C13564!int();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14166\n\nstruct Proxy14166(T)\n{\n    T* ptr;\n    ref deref() { return *ptr; }\n    alias deref this;\n}\nstruct Test14166\n{\n    auto opIndex() { return this; }\n    auto opIndex(int) { return 1; }\n}\ntemplate Elem14166a(R) { alias Elem14166a = typeof(R.init[][0]); }\ntemplate Elem14166b(R) { alias Elem14166b = typeof(R.init[0]); }\nvoid test14166()\n{\n    alias T = Proxy14166!Test14166;\n    static assert(is(Elem14166a!T == int));     // rejects-valid case\n    static assert(is(Elem14166b!T == int));     // regression case\n}\n\n// other related cases\nstruct S14166\n{\n    int x;\n    double y;\n    int[] a;\n    S14166 opUnary(string op : \"++\")() { return this;  }\n}\nS14166 s14166;\n\nstruct X14166 { this(int) { } X14166 opAssign(int) { return this; } }\nX14166[int] aa14166;\nX14166[int] makeAA14166() { return aa14166; }\n\nstruct Tup14166(T...) { T field; alias field this; }\nTup14166!(int, int) tup14166;\nTup14166!(int, int) makeTup14166() { return tup14166; }\n\npragma(msg, typeof((s14166.x += 1) = 2));    // ok <- error\npragma(msg, typeof(s14166.a.length += 2));   // ok <- error\npragma(msg, typeof(s14166++));               // ok <- error\npragma(msg, typeof(s14166.x ^^ 2));          // ok <- error\npragma(msg, typeof(s14166.y ^^= 2.5));       // ok <- error\npragma(msg, typeof(makeAA14166()[0] = 1));   // ok <- error\npragma(msg, typeof(tup14166.field = makeTup14166()));   // ok <- error\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14388\n\n@property immutable(T)[] idup14388(T)(T[] a)\n{\n    alias U = immutable(T);\n    U[] res;\n    foreach (ref e; a)\n        res ~= e;\n    return res;\n}\n\nstruct Data14388(A14388 a)\n{\n    auto foo()\n    {\n        return Data14388!a.init;    // [B]\n    }\n}\n\nstruct A14388\n{\n    struct Item {}\n\n    immutable(Item)[] items;\n\n    this(int dummy)\n    {\n        items = [Item()].idup14388;\n    }\n}\n\nvoid test14388()\n{\n    auto test = Data14388!(A14388(42)).init.foo();  // [A]\n    /*\n     * A(42) is interpreter to a struct literal A([immutable(Item)()]).\n     * The internal VarDeclaration with STCmanifest for the Data's template parameteter 'a'\n     * calls syntaxCopy() on its ((ExpInitializer *)init)->exp in VarDeclaration::semantic(),\n     * and 'immutable(Item)()'->syntaxCopy() had incorrectly removed the qualifier.\n     * Then, the arguments of two Data template instances at [A] and [B] had become unmatch,\n     * and the second instantiation had created the AST duplication.\n     */\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15163\n\nvoid function() func15164(int[] arr)\n{\n    return () { };\n}\n\nvoid test15163()\n{\n    auto arr = [[0]];\n    func15164(arr[0])();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3438\n\nimport core.vararg;\nstruct S3438_1 { this(int x, int y = 1) { } }\nstruct S3438_2 { this(int x, ...) { } }\nstruct S3438_3 { this(int x, int[] arr...) { } }\nstruct S3438_4 { this(...) { } }\nstruct S3438_5 { this(int[] arr...) { } }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15362\n\nvoid func15362()\n{\n    assert(true);\n    assert(true,);\n    assert(true, \"So true\");\n    assert(true, \"Very, very true\",);\n    static assert(true);\n    static assert(true,);\n    static assert(true, \"So true\");\n    static assert(true, \"Very, very true\",);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15799\n\ninterface I15799\n{\n    void funA();\n\n    void funB(int n)\n    in {\n        assert(n);\n    }; // Semicolon is not a part of function declaration. It's an empty declaration.\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/const.d",
    "content": "\nstatic assert(2.0  * 3.0  ==  6 );\nstatic assert(2.0  * 3.0i ==  6i);\nstatic assert(2.0i * 3.0  ==  6i);\nstatic assert(2.0i * 3.0i == -6 );\n\nstatic assert(2.0  * (4.0 + 3.0i) ==  8  + 6i);\nstatic assert(2.0i * (4.0 + 3.0i) ==  8i - 6 );\nstatic assert((4.0 + 3.0i) * 2.0  ==  8  + 6i);\nstatic assert((4.0 + 3.0i) * 2.0i ==  8i - 6 );\nstatic assert((4.0 + 3.0i) * (5 + 7i) ==  -1 + 43i );\n\nstatic assert((2.0).re == 2);\nstatic assert((2.0i).re == 0);\nstatic assert((3+2.0i).re == 3);\n\nstatic assert((4.0i).im == 4);\nstatic assert((2.0i).im == 2);\nstatic assert((3+2.0i).im == 2);\n\nstatic assert(6.0 / 2.0 == 3);\nstatic assert(6i / 2i ==  3);\nstatic assert(6  / 2i == -3i);\nstatic assert(6i / 2  ==  3i);\n\nstatic assert((6 + 4i) / 2 == 3 + 2i);\nstatic assert((6 + 4i) / 2i == -3i + 2);\n\n//static assert(2 / (6 + 4i) == -3i);\n//static assert(2i / (6 + 4i)  ==  3i);\n//static assert((1 + 2i) / (6 + 4i)  ==  3i);\n\nstatic assert(6.0 % 2.0 == 0);\nstatic assert(6.0 % 3.0 == 0);\nstatic assert(6.0 % 4.0 == 2);\n\nstatic assert(6.0i % 2.0i == 0);\nstatic assert(6.0i % 3.0i == 0);\nstatic assert(6.0i % 4.0i == 2i);\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/cppmangle.d",
    "content": "\n// Test C++ name mangling.\n// https://issues.dlang.org/show_bug.cgi?id=4059\n// https://issues.dlang.org/show_bug.cgi?id=5148\n// https://issues.dlang.org/show_bug.cgi?id=7024\n// https://issues.dlang.org/show_bug.cgi?id=10058\n\nimport core.stdc.stdio;\n\nextern (C++) int foob(int i, int j, int k);\n\nclass C\n{\n    extern (C++) int bar(int i, int j, int k)\n    {\n        printf(\"this = %p\\n\", this);\n        printf(\"i = %d\\n\", i);\n        printf(\"j = %d\\n\", j);\n        printf(\"k = %d\\n\", k);\n        return 1;\n    }\n}\n\n\nextern (C++)\nint foo(int i, int j, int k)\n{\n    printf(\"i = %d\\n\", i);\n    printf(\"j = %d\\n\", j);\n    printf(\"k = %d\\n\", k);\n    assert(i == 1);\n    assert(j == 2);\n    assert(k == 3);\n    return 1;\n}\n\nvoid test1()\n{\n    foo(1, 2, 3);\n\n    auto i = foob(1, 2, 3);\n    assert(i == 7);\n\n    C c = new C();\n    c.bar(4, 5, 6);\n}\n\nversion (linux)\n{\n    static assert(foo.mangleof == \"_Z3fooiii\");\n    static assert(foob.mangleof == \"_Z4foobiii\");\n    static assert(C.bar.mangleof == \"_ZN1C3barEiii\");\n}\nversion (Win32)\n{\n    static assert(foo.mangleof == \"?foo@@YAHHHH@Z\");\n    static assert(foob.mangleof == \"?foob@@YAHHHH@Z\");\n    static assert(C.bar.mangleof == \"?bar@C@@UAEHHHH@Z\");\n}\nversion (Win64)\n{\n    static assert(foo.mangleof == \"?foo@@YAHHHH@Z\");\n    static assert(foob.mangleof == \"?foob@@YAHHHH@Z\");\n    static assert(C.bar.mangleof == \"?bar@C@@UEAAHHHH@Z\");\n}\n\n/****************************************/\n\nextern (C++)\ninterface D\n{\n    int bar(int i, int j, int k);\n}\n\nextern (C++) D getD();\n\nvoid test2()\n{\n    D d = getD();\n    int i = d.bar(9,10,11);\n    assert(i == 8);\n}\n\nversion (linux)\n{\n    static assert (getD.mangleof == \"_Z4getDv\");\n    static assert (D.bar.mangleof == \"_ZN1D3barEiii\");\n}\n\n/****************************************/\n\nextern (C++) int callE(E);\n\nextern (C++)\ninterface E\n{\n    int bar(int i, int j, int k);\n}\n\nclass F : E\n{\n    extern (C++) int bar(int i, int j, int k)\n    {\n        printf(\"F.bar: i = %d\\n\", i);\n        printf(\"F.bar: j = %d\\n\", j);\n        printf(\"F.bar: k = %d\\n\", k);\n        assert(i == 11);\n        assert(j == 12);\n        assert(k == 13);\n        return 8;\n    }\n}\n\nvoid test3()\n{\n    F f = new F();\n    int i = callE(f);\n    assert(i == 8);\n}\n\nversion (linux)\n{\n    static assert (callE.mangleof == \"_Z5callEP1E\");\n    static assert (E.bar.mangleof == \"_ZN1E3barEiii\");\n    static assert (F.bar.mangleof == \"_ZN1F3barEiii\");\n}\n\n/****************************************/\n\nextern (C++) void foo4(char* p);\n\nvoid test4()\n{\n    foo4(null);\n}\n\nversion (linux)\n{\n    static assert(foo4.mangleof == \"_Z4foo4Pc\");\n}\n\n/****************************************/\n\nextern(C++)\n{\n  struct foo5 { int i; int j; void* p; }\n\n  interface bar5{\n    foo5 getFoo(int i);\n  }\n\n  bar5 newBar();\n}\n\nvoid test5()\n{\n  bar5 b = newBar();\n  foo5 f = b.getFoo(4);\n  printf(\"f.p = %p, b = %p\\n\", f.p, cast(void*)b);\n  assert(f.p == cast(void*)b);\n}\n\nversion (linux)\n{\n    static assert(bar5.getFoo.mangleof == \"_ZN4bar56getFooEi\");\n    static assert (newBar.mangleof == \"_Z6newBarv\");\n}\n\n/****************************************/\n\nextern(C++)\n{\n    struct S6\n    {\n        int i;\n        double d;\n    }\n    S6 foo6();\n}\n\nextern (C) int foosize6();\n\nvoid test6()\n{\n    S6 f = foo6();\n    printf(\"%d %d\\n\", foosize6(), S6.sizeof);\n    assert(foosize6() == S6.sizeof);\n    assert(f.i == 42);\n    printf(\"f.d = %g\\n\", f.d);\n    assert(f.d == 2.5);\n}\n\nversion (linux)\n{\n    static assert (foo6.mangleof == \"_Z4foo6v\");\n}\n\n/****************************************/\n\nextern (C) int foo7();\n\nstruct S\n{\n    int i;\n    long l;\n}\n\nvoid test7()\n{\n    printf(\"%d %d\\n\", foo7(), S.sizeof);\n    assert(foo7() == S.sizeof);\n}\n\n/****************************************/\n\nextern (C++) void foo8(const char *);\n\nvoid test8()\n{\n    char c;\n    foo8(&c);\n}\n\nversion (linux)\n{\n    static assert(foo8.mangleof == \"_Z4foo8PKc\");\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4059\n\nstruct elem9 { }\n\nextern(C++) void foobar9(elem9*, elem9*);\n\nvoid test9()\n{\n    elem9 *a;\n    foobar9(a, a);\n}\n\nversion (linux)\n{\n    static assert(foobar9.mangleof == \"_Z7foobar9P5elem9S0_\");\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5148\n\nextern (C++)\n{\n    void foo10(const char*, const char*);\n    void foo10(const int, const int);\n    void foo10(const char, const char);\n\n    struct MyStructType { }\n    void foo10(const MyStructType s, const MyStructType t);\n\n    enum MyEnumType { onemember }\n    void foo10(const MyEnumType s, const MyEnumType t);\n}\n\nvoid test10()\n{\n    char* p;\n    foo10(p, p);\n    foo10(1,2);\n    foo10('c','d');\n    MyStructType s;\n    foo10(s,s);\n    MyEnumType e;\n    foo10(e,e);\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10058\n\nextern (C++)\n{\n    void test10058a(void*) { }\n    void test10058b(void function(void*)) { }\n    void test10058c(void* function(void*)) { }\n    void test10058d(void function(void*), void*) { }\n    void test10058e(void* function(void*), void*) { }\n    void test10058f(void* function(void*), void* function(void*)) { }\n    void test10058g(void function(void*), void*, void*) { }\n    void test10058h(void* function(void*), void*, void*) { }\n    void test10058i(void* function(void*), void* function(void*), void*) { }\n    void test10058j(void* function(void*), void* function(void*), void* function(void*)) { }\n    void test10058k(void* function(void*), void* function(const (void)*)) { }\n    void test10058l(void* function(void*), void* function(const (void)*), const(void)* function(void*)) { }\n}\n\nversion (linux)\n{\n    static assert(test10058a.mangleof == \"_Z10test10058aPv\");\n    static assert(test10058b.mangleof == \"_Z10test10058bPFvPvE\");\n    static assert(test10058c.mangleof == \"_Z10test10058cPFPvS_E\");\n    static assert(test10058d.mangleof == \"_Z10test10058dPFvPvES_\");\n    static assert(test10058e.mangleof == \"_Z10test10058ePFPvS_ES_\");\n    static assert(test10058f.mangleof == \"_Z10test10058fPFPvS_ES1_\");\n    static assert(test10058g.mangleof == \"_Z10test10058gPFvPvES_S_\");\n    static assert(test10058h.mangleof == \"_Z10test10058hPFPvS_ES_S_\");\n    static assert(test10058i.mangleof == \"_Z10test10058iPFPvS_ES1_S_\");\n    static assert(test10058j.mangleof == \"_Z10test10058jPFPvS_ES1_S1_\");\n    static assert(test10058k.mangleof == \"_Z10test10058kPFPvS_EPFS_PKvE\");\n    static assert(test10058l.mangleof == \"_Z10test10058lPFPvS_EPFS_PKvEPFS3_S_E\");\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11696\n\nclass Expression;\nstruct Loc {}\n\nextern(C++)\nclass CallExp\n{\n    static void test11696a(Loc, Expression, Expression);\n    static void test11696b(Loc, Expression, Expression*);\n    static void test11696c(Loc, Expression*, Expression);\n    static void test11696d(Loc, Expression*, Expression*);\n}\n\nversion (linux)\n{\n    static assert(CallExp.test11696a.mangleof == \"_ZN7CallExp10test11696aE3LocP10ExpressionS2_\");\n    static assert(CallExp.test11696b.mangleof == \"_ZN7CallExp10test11696bE3LocP10ExpressionPS2_\");\n    static assert(CallExp.test11696c.mangleof == \"_ZN7CallExp10test11696cE3LocPP10ExpressionS2_\");\n    static assert(CallExp.test11696d.mangleof == \"_ZN7CallExp10test11696dE3LocPP10ExpressionS3_\");\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13337\n\nextern(C++, N13337a.N13337b.N13337c)\n{\n  struct S13337{}\n  void foo13337(S13337 s);\n}\n\nversion (linux)\n{\n    static assert(foo13337.mangleof == \"_ZN7N13337a7N13337b7N13337c8foo13337ENS1_6S13337E\");\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15789\n\nextern (C++) void test15789a(T...)(T args);\n\nvoid test15789()\n{\n    test15789a(0);\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7030\n\nextern(C++)\n{\n    struct T\n    {\n        void foo(int) const;\n        void bar(int);\n        static __gshared int boo;\n    }\n}\n\nversion (Posix)\n{\n    static assert(T.foo.mangleof == \"_ZNK1T3fooEi\");\n    static assert(T.bar.mangleof == \"_ZN1T3barEi\");\n    static assert(T.boo.mangleof == \"_ZN1T3booE\");\n}\n\n/****************************************/\n\n// Special cases of Itanium mangling\n\nextern (C++, std)\n{\n    struct pair(T1, T2)\n    {\n        void swap(ref pair other);\n    }\n\n    struct allocator(T)\n    {\n        uint fooa() const;\n        uint foob();\n    }\n\n    struct basic_string(T1, T2, T3)\n    {\n        uint fooa();\n    }\n\n    struct basic_istream(T1, T2)\n    {\n        uint fooc();\n    }\n\n    struct basic_ostream(T1, T2)\n    {\n        uint food();\n    }\n\n    struct basic_iostream(T1, T2)\n    {\n        uint fooe();\n    }\n\n    struct char_traits(T)\n    {\n        uint foof();\n    }\n\n    struct vector (T);\n\n    struct test18957 {}\n}\n\nversion (linux)\n{\n    // https://issues.dlang.org/show_bug.cgi?id=17947\n    static assert(std.pair!(void*, void*).swap.mangleof == \"_ZNSt4pairIPvS0_E4swapERS1_\");\n\n    static assert(std.allocator!int.fooa.mangleof == \"_ZNKSaIiE4fooaEv\");\n    static assert(std.allocator!int.foob.mangleof == \"_ZNSaIiE4foobEv\");\n    static assert(std.basic_string!(char,int,uint).fooa.mangleof == \"_ZNSbIcijE4fooaEv\");\n    static assert(std.basic_string!(char, std.char_traits!char, std.allocator!char).fooa.mangleof == \"_ZNSs4fooaEv\");\n    static assert(std.basic_istream!(char, std.char_traits!char).fooc.mangleof == \"_ZNSi4foocEv\");\n    static assert(std.basic_ostream!(char, std.char_traits!char).food.mangleof == \"_ZNSo4foodEv\");\n    static assert(std.basic_iostream!(char, std.char_traits!char).fooe.mangleof == \"_ZNSd4fooeEv\");\n}\n\n/**************************************/\n\nalias T36 = int ********** ********** ********** **********;\n\nextern (C++) void test36(T36, T36*) { }\n\nversion (linux)\n{\n    static assert(test36.mangleof == \"_Z6test36PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPiPS12_\");\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17772\n\nextern(C++, SPACE)\nint test37(T)(){ return 0;}\n\nversion (Posix) // all non-Windows machines\n{\n    static assert(test37!int.mangleof == \"_ZN5SPACE6test37IiEEiv\");\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15388\n\nextern (C++) void test15388(typeof(null));\n\nversion (Posix)\n{\n    static assert(test15388.mangleof == \"_Z9test15388Dn\");\n}\nversion (Windows)\n{\n    static assert(test15388.mangleof == \"?test15388@@YAX$$T@Z\");\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14086\n\nextern (C++) class Test14086\n{\n    this();\n    ~this();\n}\nextern (C++) class Test14086_2\n{\n    final ~this();\n}\nextern (C++) struct Test14086_S\n{\n    this(int);\n    ~this();\n}\n\nversion(Posix)\n{\n    static assert(Test14086.__ctor.mangleof == \"_ZN9Test14086C1Ev\");\n    static assert(Test14086.__dtor.mangleof == \"_ZN9Test14086D1Ev\");\n    static assert(Test14086_2.__dtor.mangleof == \"_ZN11Test14086_2D1Ev\");\n    static assert(Test14086_S.__ctor.mangleof == \"_ZN11Test14086_SC1Ei\");\n    static assert(Test14086_S.__dtor.mangleof == \"_ZN11Test14086_SD1Ev\");\n}\nversion(Win32)\n{\n    static assert(Test14086.__ctor.mangleof == \"??0Test14086@@QAE@XZ\");\n    static assert(Test14086.__dtor.mangleof == \"??1Test14086@@UAE@XZ\");\n    static assert(Test14086_2.__dtor.mangleof == \"??1Test14086_2@@QAE@XZ\");\n    static assert(Test14086_S.__ctor.mangleof == \"??0Test14086_S@@QAE@H@Z\");\n    static assert(Test14086_S.__dtor.mangleof == \"??1Test14086_S@@QAE@XZ\");\n}\nversion(Win64)\n{\n    static assert(Test14086.__ctor.mangleof == \"??0Test14086@@QEAA@XZ\");\n    static assert(Test14086.__dtor.mangleof == \"??1Test14086@@UEAA@XZ\");\n    static assert(Test14086_2.__dtor.mangleof == \"??1Test14086_2@@QEAA@XZ\");\n    static assert(Test14086_S.__ctor.mangleof == \"??0Test14086_S@@QEAA@H@Z\");\n    static assert(Test14086_S.__dtor.mangleof == \"??1Test14086_S@@QEAA@XZ\");\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18888\n\nextern (C++)\nstruct T18888(T)\n{\n    void fun();\n}\n\nextern (C++)\nstruct S18888(alias arg = T18888)\n{\n    alias I = T18888!(arg!int);\n}\n\nversion(Posix)\n{\n    static assert(S18888!().I.fun.mangleof == \"_ZN6T18888IS_IiEE3funEv\");\n}\nversion(Win32)\n{\n    static assert(S18888!().I.fun.mangleof == \"?fun@?$T18888@U?$T18888@H@@@@QAEXXZ\");\n}\nversion(Win64)\n{\n    static assert(S18888!().I.fun.mangleof == \"?fun@?$T18888@U?$T18888@H@@@@QEAAXXZ\");\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18890\n\nextern (C++) class C18890\n{\n    ~this() {}\n}\nextern (C++) class C18890_2\n{\n    ~this() {}\n    extern (C++) struct Agg\n    {\n        ~this() {}\n    }\n    Agg s;\n}\n\nversion (Posix)\n{\n    static assert(C18890.__dtor.mangleof == \"_ZN6C18890D1Ev\");\n    static assert(C18890.__xdtor.mangleof == \"_ZN6C18890D1Ev\");\n    static assert(C18890_2.__dtor.mangleof == \"_ZN8C18890_26__dtorEv\");\n    static assert(C18890_2.__xdtor.mangleof == \"_ZN8C18890_2D1Ev\");\n}\nversion (Win32)\n{\n    static assert(C18890.__dtor.mangleof == \"??1C18890@@UAE@XZ\");\n    static assert(C18890.__xdtor.mangleof == \"??_GC18890@@UAEPAXI@Z\");\n    static assert(C18890_2.__dtor.mangleof == \"?__dtor@C18890_2@@UAEXXZ\");\n    static assert(C18890_2.__xdtor.mangleof == \"??_GC18890_2@@UAEPAXI@Z\");\n}\nversion (Win64)\n{\n    static assert(C18890.__dtor.mangleof == \"??1C18890@@UEAA@XZ\");\n    static assert(C18890.__xdtor.mangleof == \"??_GC18890@@UEAAPEAXI@Z\");\n    static assert(C18890_2.__dtor.mangleof == \"?__dtor@C18890_2@@UEAAXXZ\");\n    static assert(C18890_2.__xdtor.mangleof == \"??_GC18890_2@@UEAAPEAXI@Z\");\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18891\n\nextern (C++) class C18891\n{\n    ~this();\n    extern (C++) struct Agg\n    {\n        ~this() {}\n    }\n    Agg s;\n}\n\nversion (Posix)\n{\n    static assert(C18891.__dtor.mangleof == \"_ZN6C18891D1Ev\");\n    static assert(C18891.__xdtor.mangleof == \"_ZN6C18891D1Ev\");\n}\nversion (Win32)\n{\n    static assert(C18891.__dtor.mangleof == \"??1C18891@@UAE@XZ\");\n    static assert(C18891.__xdtor.mangleof == \"??_GC18891@@UAEPAXI@Z\");\n}\nversion (Win64)\n{\n    static assert(C18891.__dtor.mangleof == \"??1C18891@@UEAA@XZ\");\n    static assert(C18891.__xdtor.mangleof == \"??_GC18891@@UEAAPEAXI@Z\");\n}\n\n/**************************************/\n// Test C++ operator mangling\n\nextern (C++) struct TestOperators\n{\n    int opCast(T)();\n    int opBinary(string op)(int x);\n    int opUnary(string op)();\n    int opOpAssign(string op)(int x);\n    int opIndex(int x);\n    bool opEquals(int x);\n    int opCall(int, float);\n    int opAssign(int);\n}\n\nversion (Posix)\n{\n    static assert(TestOperators.opUnary!\"*\".mangleof     == \"_ZN13TestOperatorsdeEv\");\n    static assert(TestOperators.opUnary!\"++\".mangleof    == \"_ZN13TestOperatorsppEv\");\n    static assert(TestOperators.opUnary!\"--\".mangleof    == \"_ZN13TestOperatorsmmEv\");\n    static assert(TestOperators.opUnary!\"-\".mangleof     == \"_ZN13TestOperatorsngEv\");\n    static assert(TestOperators.opUnary!\"+\".mangleof     == \"_ZN13TestOperatorspsEv\");\n    static assert(TestOperators.opUnary!\"~\".mangleof     == \"_ZN13TestOperatorscoEv\");\n    static assert(TestOperators.opBinary!\">>\".mangleof   == \"_ZN13TestOperatorsrsEi\");\n    static assert(TestOperators.opBinary!\"<<\".mangleof   == \"_ZN13TestOperatorslsEi\");\n    static assert(TestOperators.opBinary!\"*\".mangleof    == \"_ZN13TestOperatorsmlEi\");\n    static assert(TestOperators.opBinary!\"-\".mangleof    == \"_ZN13TestOperatorsmiEi\");\n    static assert(TestOperators.opBinary!\"+\".mangleof    == \"_ZN13TestOperatorsplEi\");\n    static assert(TestOperators.opBinary!\"&\".mangleof    == \"_ZN13TestOperatorsanEi\");\n    static assert(TestOperators.opBinary!\"/\".mangleof    == \"_ZN13TestOperatorsdvEi\");\n    static assert(TestOperators.opBinary!\"%\".mangleof    == \"_ZN13TestOperatorsrmEi\");\n    static assert(TestOperators.opBinary!\"^\".mangleof    == \"_ZN13TestOperatorseoEi\");\n    static assert(TestOperators.opBinary!\"|\".mangleof    == \"_ZN13TestOperatorsorEi\");\n    static assert(TestOperators.opOpAssign!\"*\".mangleof  == \"_ZN13TestOperatorsmLEi\");\n    static assert(TestOperators.opOpAssign!\"+\".mangleof  == \"_ZN13TestOperatorspLEi\");\n    static assert(TestOperators.opOpAssign!\"-\".mangleof  == \"_ZN13TestOperatorsmIEi\");\n    static assert(TestOperators.opOpAssign!\"/\".mangleof  == \"_ZN13TestOperatorsdVEi\");\n    static assert(TestOperators.opOpAssign!\"%\".mangleof  == \"_ZN13TestOperatorsrMEi\");\n    static assert(TestOperators.opOpAssign!\">>\".mangleof == \"_ZN13TestOperatorsrSEi\");\n    static assert(TestOperators.opOpAssign!\"<<\".mangleof == \"_ZN13TestOperatorslSEi\");\n    static assert(TestOperators.opOpAssign!\"&\".mangleof  == \"_ZN13TestOperatorsaNEi\");\n    static assert(TestOperators.opOpAssign!\"|\".mangleof  == \"_ZN13TestOperatorsoREi\");\n    static assert(TestOperators.opOpAssign!\"^\".mangleof  == \"_ZN13TestOperatorseOEi\");\n    static assert(TestOperators.opCast!int.mangleof      == \"_ZN13TestOperatorscviEv\");\n    static assert(TestOperators.opAssign.mangleof        == \"_ZN13TestOperatorsaSEi\");\n    static assert(TestOperators.opEquals.mangleof        == \"_ZN13TestOperatorseqEi\");\n    static assert(TestOperators.opIndex.mangleof         == \"_ZN13TestOperatorsixEi\");\n    static assert(TestOperators.opCall.mangleof          == \"_ZN13TestOperatorsclEif\");\n}\nversion (Win32)\n{\n    static assert(TestOperators.opUnary!\"*\".mangleof     == \"??DTestOperators@@QAEHXZ\");\n    static assert(TestOperators.opUnary!\"++\".mangleof    == \"??ETestOperators@@QAEHXZ\");\n    static assert(TestOperators.opUnary!\"--\".mangleof    == \"??FTestOperators@@QAEHXZ\");\n    static assert(TestOperators.opUnary!\"-\".mangleof     == \"??GTestOperators@@QAEHXZ\");\n    static assert(TestOperators.opUnary!\"+\".mangleof     == \"??HTestOperators@@QAEHXZ\");\n    static assert(TestOperators.opUnary!\"~\".mangleof     == \"??STestOperators@@QAEHXZ\");\n    static assert(TestOperators.opBinary!\">>\".mangleof   == \"??5TestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opBinary!\"<<\".mangleof   == \"??6TestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opBinary!\"*\".mangleof    == \"??DTestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opBinary!\"-\".mangleof    == \"??GTestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opBinary!\"+\".mangleof    == \"??HTestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opBinary!\"&\".mangleof    == \"??ITestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opBinary!\"/\".mangleof    == \"??KTestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opBinary!\"%\".mangleof    == \"??LTestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opBinary!\"^\".mangleof    == \"??TTestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opBinary!\"|\".mangleof    == \"??UTestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opOpAssign!\"*\".mangleof  == \"??XTestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opOpAssign!\"+\".mangleof  == \"??YTestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opOpAssign!\"-\".mangleof  == \"??ZTestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opOpAssign!\"/\".mangleof  == \"??_0TestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opOpAssign!\"%\".mangleof  == \"??_1TestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opOpAssign!\">>\".mangleof == \"??_2TestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opOpAssign!\"<<\".mangleof == \"??_3TestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opOpAssign!\"&\".mangleof  == \"??_4TestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opOpAssign!\"|\".mangleof  == \"??_5TestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opOpAssign!\"^\".mangleof  == \"??_6TestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opCast!int.mangleof      == \"??BTestOperators@@QAEHXZ\");\n    static assert(TestOperators.opAssign.mangleof        == \"??4TestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opEquals.mangleof        == \"??8TestOperators@@QAE_NH@Z\");\n    static assert(TestOperators.opIndex.mangleof         == \"??ATestOperators@@QAEHH@Z\");\n    static assert(TestOperators.opCall.mangleof          == \"??RTestOperators@@QAEHHM@Z\");\n}\nversion (Win64)\n{\n    static assert(TestOperators.opUnary!\"*\".mangleof     == \"??DTestOperators@@QEAAHXZ\");\n    static assert(TestOperators.opUnary!\"++\".mangleof    == \"??ETestOperators@@QEAAHXZ\");\n    static assert(TestOperators.opUnary!\"--\".mangleof    == \"??FTestOperators@@QEAAHXZ\");\n    static assert(TestOperators.opUnary!\"-\".mangleof     == \"??GTestOperators@@QEAAHXZ\");\n    static assert(TestOperators.opUnary!\"+\".mangleof     == \"??HTestOperators@@QEAAHXZ\");\n    static assert(TestOperators.opUnary!\"~\".mangleof     == \"??STestOperators@@QEAAHXZ\");\n    static assert(TestOperators.opBinary!\">>\".mangleof   == \"??5TestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opBinary!\"<<\".mangleof   == \"??6TestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opBinary!\"*\".mangleof    == \"??DTestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opBinary!\"-\".mangleof    == \"??GTestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opBinary!\"+\".mangleof    == \"??HTestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opBinary!\"&\".mangleof    == \"??ITestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opBinary!\"/\".mangleof    == \"??KTestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opBinary!\"%\".mangleof    == \"??LTestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opBinary!\"^\".mangleof    == \"??TTestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opBinary!\"|\".mangleof    == \"??UTestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opOpAssign!\"*\".mangleof  == \"??XTestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opOpAssign!\"+\".mangleof  == \"??YTestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opOpAssign!\"-\".mangleof  == \"??ZTestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opOpAssign!\"/\".mangleof  == \"??_0TestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opOpAssign!\"%\".mangleof  == \"??_1TestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opOpAssign!\">>\".mangleof == \"??_2TestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opOpAssign!\"<<\".mangleof == \"??_3TestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opOpAssign!\"&\".mangleof  == \"??_4TestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opOpAssign!\"|\".mangleof  == \"??_5TestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opOpAssign!\"^\".mangleof  == \"??_6TestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opCast!int.mangleof      == \"??BTestOperators@@QEAAHXZ\");\n    static assert(TestOperators.opAssign.mangleof        == \"??4TestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opEquals.mangleof        == \"??8TestOperators@@QEAA_NH@Z\");\n    static assert(TestOperators.opIndex.mangleof         == \"??ATestOperators@@QEAAHH@Z\");\n    static assert(TestOperators.opCall.mangleof          == \"??RTestOperators@@QEAAHHM@Z\");\n}\n\nextern(C++, Namespace18922)\n{\n    import cppmangle2;\n    void func18922(Struct18922) {}\n\n    version (Posix)\n        static assert(func18922.mangleof == \"_ZN14Namespace189229func18922ENS_11Struct18922E\");\n    else version(Windows)\n        static assert(func18922.mangleof == \"?func18922@Namespace18922@@YAXUStruct18922@1@@Z\");\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18957\n// extern(C++) doesn't mangle 'std' correctly on posix systems\n\nversion (Posix)\n{\n    // https://godbolt.org/z/C5T2LQ\n    /+\n    namespace std\n    {\n    struct test18957 {};\n    }\n    void test18957(const std::test18957& t) {}\n    +/\n    extern (C++) void test18957(ref const(std.test18957) t) {}\n\n    static assert(test18957.mangleof == \"_Z9test18957RKSt9test18957\");\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=19043\n// Incorrect mangling for extern(C++) const template parameter on windows\n\nextern(C++) struct test19043(T) {}\n\nextern(C++) void test19043a(test19043!(const(char)) a) {}\nextern(C++) void test19043b(T)(T a) {}\nversion(Windows)\n{\n    static assert(test19043a.mangleof == \"?test19043a@@YAXU?$test19043@$$CBD@@@Z\");\n    static assert(test19043b!(test19043!(const(char))).mangleof ==\n      \"??$test19043b@U?$test19043@$$CBD@@@@YAXU?$test19043@$$CBD@@@Z\");\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=16479\n//  Missing substitution while mangling C++ template parameter for functions\nversion (Posix) extern (C++)\n{\n    // Make sure aliases are still resolved\n    alias Alias16479 = int;\n    Alias16479 func16479_0 (FuncT1) (FuncT1, Alias16479);\n    static assert(func16479_0!(int).mangleof == `_Z11func16479_0IiEiT_i`);\n\n    // Simple substitution on return type\n    FuncT1* func16479_1 (FuncT1) ();\n    static assert(func16479_1!(int).mangleof == `_Z11func16479_1IiEPT_v`);\n\n    // Simple substitution on parameter\n    void    func16479_2 (FuncT1) (FuncT1);\n    static assert(func16479_2!(int).mangleof == `_Z11func16479_2IiEvT_`);\n\n    // Make sure component substition is prefered over template parameter\n    FuncT1* func16479_3 (FuncT1) (FuncT1);\n    static assert(func16479_3!(int).mangleof == `_Z11func16479_3IiEPT_S0_`);\n\n    struct Array16479 (Arg) { Arg* data; }\n    struct Array16479_2 (Arg, int Size) { Arg[Size] data; }\n    struct Value16479 (int Value1, int Value2) { int data; }\n\n    // Make sure template parameter substitution happens on templated return\n    Array16479!(FuncT2) func16479_4 (FuncT1, FuncT2) (FuncT1);\n    static assert(func16479_4!(int, float).mangleof\n                  == `_Z11func16479_4IifE10Array16479IT0_ET_`);\n\n    // Make sure template parameter substitution happens with values\n    Value16479!(Value2, Value1)* func16479_5 (int Value1, int Value2) ();\n    static assert(func16479_5!(1, 1).mangleof\n                  == `_Z11func16479_5ILi1ELi1EEP10Value16479IXT0_EXT_EEv`);\n\n    // But make sure it's not substituting *too many* values\n    Value16479!(1, 1)* func16479_6 (int Value1, int Value2) ();\n    static assert(func16479_6!(1, 1).mangleof\n                  == `_Z11func16479_6ILi1ELi1EEP10Value16479ILi1ELi1EEv`);\n\n    // Or too many types\n    Array16479!(int) func16479_7 (FuncT1, FuncT2) (FuncT1);\n    static assert(func16479_7!(int, int).mangleof\n                  == `_Z11func16479_7IiiE10Array16479IiET_`);\n\n    // Also must check the parameters for template param substitution\n    void func16479_8 (FuncT1) (Array16479!(FuncT1));\n    static assert(func16479_8!(int).mangleof\n                  == `_Z11func16479_8IiEv10Array16479IT_E`);\n\n    // And non-substitution\n    void func16479_9 (FuncT1) (Array16479!(int));\n    static assert(func16479_9!(int).mangleof\n                  == `_Z11func16479_9IiEv10Array16479IiE`);\n\n    // Now let's have a bit of fun with alias parameters,\n    // starting with C functions\n    // TODO: Why is this mangled by g++:\n    /*\n      extern \"C\"\n      {\n        void externC16479 (int);\n      }\n\n      template<void (*Print)(int)>\n      void func16479_10 ();\n\n      void foo () { func16479_10<externC16479>(); }\n     */\n    extern (C) void externC16479 (int);\n    void func16479_10 (alias Print) ();\n    static assert(func16479_10!(externC16479).mangleof\n                  == `_Z12func16479_10IXadL_Z12externC16479EEEvv`);\n\n    /**\n     * Let's not exclude C++ functions\n     * Note:\n     *   Passing a function as template parameter has an implicit\n     *   `&` operator prepended to it, so the following code:\n     * ---\n     * void CPPPrinter16479(const char*);\n     * template<void (*Print)(const char*)> void func16479_11 ();\n     * void foo () { func16479_11<CPPPrinter16479>(); }\n     * ---\n     * Gets mangled as `func16479_11<&CPPPrinter16479>()` would,\n     * which means the expression part of the template argument is\n     * mangled as `XadL_Z[...]E` not `XL_Z[...]E`\n     * (expressions always begin with a code anyway).\n     */\n    extern(C++) void CPPPrinter16479(const(char)*);\n    extern(C++, Namespace16479) void CPPPrinterNS16479(const(char)*);\n    void func16479_11 (alias Print) ();\n    static assert(func16479_11!(CPPPrinter16479).mangleof\n                  == `_Z12func16479_11IXadL_Z15CPPPrinter16479PKcEEEvv`);\n    static assert(func16479_11!(CPPPrinterNS16479).mangleof\n                  == `_Z12func16479_11IXadL_ZN14Namespace1647917CPPPrinterNS16479EPKcEEEvv`);\n\n    // Functions are fine, but templates are finer\n    // ---\n    // template<template<typename, int> class Container, typename T, int Val>\n    // Container<T, Val> func16479_12 ();\n    // ---\n    Container!(T, Val) func16479_12 (alias Container, T, int Val) ();\n    static assert(func16479_12!(Array16479_2, int, 42).mangleof\n                  == `_Z12func16479_12I12Array16479_2iLi42EET_IT0_XT1_EEv`);\n\n    // Substitution needs to happen on the most specialized type\n    // Iow, `ref T identity (T) (ref T v);` should be mangled as\n    // `_Z8identityIiET_*S1_*`, not as `_Z8identityIiET_*RS0_*`\n    ref FuncT1 func16479_13_1 (FuncT1) (ref FuncT1);\n    FuncT1*    func16479_13_2 (FuncT1) (FuncT1*);\n    void       func16479_13_3 (FuncT1) (FuncT1*, FuncT1*);\n    FuncT1**   func16479_13_4 (FuncT1) (FuncT1*, FuncT1);\n    FuncT1     func16479_13_5 (FuncT1) (FuncT1*, FuncT1**);\n    static assert(func16479_13_1!(int).mangleof == `_Z14func16479_13_1IiERT_S1_`);\n    static assert(func16479_13_2!(float).mangleof == `_Z14func16479_13_2IfEPT_S1_`);\n    static assert(func16479_13_3!(int).mangleof == `_Z14func16479_13_3IiEvPT_S1_`);\n    static assert(func16479_13_4!(int).mangleof == `_Z14func16479_13_4IiEPPT_S1_S0_`);\n    static assert(func16479_13_5!(int).mangleof == `_Z14func16479_13_5IiET_PS0_PS1_`);\n\n    // Opaque types result in a slightly different AST\n    vector!T* func16479_14 (T) (T v);\n    static assert(func16479_14!(int).mangleof == `_Z12func16479_14IiEPSt6vectorIT_ES1_`);\n\n    struct Foo16479_15 (T);\n    struct Baguette16479_15 (T);\n    struct Bar16479_15 (T);\n    struct FooBar16479_15 (A, B);\n    void inst16479_15_2 (A, B) ();\n    void inst16479_15_3 (A, B, C) ();\n\n    static assert(inst16479_15_2!(Bar16479_15!int, int).mangleof\n                  == `_Z14inst16479_15_2I11Bar16479_15IiEiEvv`);\n    static assert(inst16479_15_2!(int, Bar16479_15!int).mangleof\n                  == `_Z14inst16479_15_2Ii11Bar16479_15IiEEvv`);\n    static assert(inst16479_15_2!(Bar16479_15!int, FooBar16479_15!(Bar16479_15!int, Foo16479_15!(Bar16479_15!(Foo16479_15!int)))).mangleof\n                  == `_Z14inst16479_15_2I11Bar16479_15IiE14FooBar16479_15IS1_11Foo16479_15IS0_IS3_IiEEEEEvv`);\n    static assert(inst16479_15_3!(int, Bar16479_15!int, FooBar16479_15!(Bar16479_15!int, Foo16479_15!(Bar16479_15!(Foo16479_15!int)))).mangleof\n                  == `_Z14inst16479_15_3Ii11Bar16479_15IiE14FooBar16479_15IS1_11Foo16479_15IS0_IS3_IiEEEEEvv`);\n\n    static import cppmangle2;\n    cppmangle2.Struct18922* func16479_16_1 (T) (T*);\n    static assert(func16479_16_1!int.mangleof == `_Z14func16479_16_1IiEPN14Namespace1892211Struct18922EPT_`);\n    T* func16479_16_2 (T) (T*);\n    static assert(func16479_16_2!int.mangleof == `_Z14func16479_16_2IiEPT_S1_`);\n    static assert(func16479_16_2!(cppmangle2.vector!int).mangleof == `_Z14func16479_16_2ISt6vectorIiEEPT_S3_`);\n    static assert(func16479_16_2!(cppmangle2.vector!int).mangleof\n                  == func16479_16_2!(cppmangle2.vector!int).mangleof);\n    cppmangle2.vector!T* func16479_16_3 (T) (T*);\n    static assert(func16479_16_3!int.mangleof == `_Z14func16479_16_3IiEPSt6vectorIiEPT_`);\n\n    extern(C++, `fakestd`) {\n        extern (C++, `__1`) {\n            struct allocator16479 (T);\n            struct vector16479(T, alloc = allocator16479!T);\n        }\n    }\n    vector16479!(T, allocator16479!T)* func16479_17_1(T)();\n    vector16479!(T)* func16479_17_2(T)();\n    static assert(func16479_17_1!int.mangleof == `_Z14func16479_17_1IiEPN7fakestd3__111vector16479IT_NS1_14allocator16479IS3_EEEEv`);\n    static assert(func16479_17_2!int.mangleof == `_Z14func16479_17_2IiEPN7fakestd3__111vector16479IT_NS1_14allocator16479IS3_EEEEv`);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/cppmangle2.d",
    "content": "module cppmangle2;\n\nextern(C++, Namespace18922)\n{\n    struct Struct18922 { int i; }\n}\n\nextern(C++, std)\n{\n    struct vector (T);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/cppmangle3.d",
    "content": "\n\nextern(C++, \"true\")\n{\n}\n\nextern(C++, \"__traits\")\n{\n}\n\nextern(C++, \"foo\")\n{\n}\n\nint foo; // no name clashing with above namespace\n\nextern(C++, \"std\", \"chrono\")\n{\n    void func();\n}\n\nversion(Windows) static assert(func.mangleof == \"?func@chrono@std@@YAXXZ\");\nelse             static assert(func.mangleof == \"_ZNSt6chrono4funcEv\");\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ctfe_math.d",
    "content": "// Test CTFE builtins for std.math functions.\n\nimport std.math;\n\nvoid main()\n{\n    static assert(approxEqual(sin(2.0L), 0.9092974L));\n    static assert(approxEqual(cos(2.0), -0.4161468));\n    static assert(approxEqual(tan(2.0f), -2.185040f));\n    static assert(approxEqual(sqrt(2.0L), 1.414214L));\n    static assert(fabs(-2.0) == 2.0);\n    static assert(ldexp(2.5f, 3) == 20.0f);\n\n    static assert(isNaN(real.init));\n    static assert(isNaN(double.nan));\n    static assert(!isNaN(float.infinity));\n\n    static assert(isInfinity(real.infinity));\n    static assert(isInfinity(-double.infinity));\n    static assert(!isInfinity(float.nan));\n\n    static assert(isFinite(1.0L));\n    static assert(!isFinite(double.infinity));\n    static assert(!isFinite(float.nan));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc1.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n// REQUIRED_ARGS: -d\n\n/** This module is for ABC\n * Copyright: Copyright &copy;\n */\n\nmodule abc;\n\nstring foos = \"foo\";\n\nalias int myint; ///\nalias int mytypedefint;\n\n/** windy\n * city\n *\n * paragraph 2 about of F $$(NAME)\n * -----\n * #include <stdio.h>\n  * void main()\n * {\n * \tprintf(\"hello\\n\");\n * }\n * -----\n * Copyright: 1998\n */\nmyint f;\nenum E { e } /// comment1\nint g; /// comment2\nprivate int h; /// comment for H\nstatic int i;\nint j;\nwchar LS = 0x2028;\t/// UTF line separator\nwchar PS = 0x2029;\t/// UTF paragraph separator\n\nwchar _XX;\t/// ditto\nwchar YY;\t/// ditto\n\n/** Function foo takes argument c and adds it to argulid.\n *\n * Then it munges argulid, u <u>underline</u>. <!-- c, argulid, b -->\n * Params:\n *\tc = the character which adds c to argulid\n *\targulid = the argument\n *\tu = the other argument\n */\nint foo(char c, int argulid, char u);\n\nint barr() { return 3; } /// doc for barr()\n\n/++ The Class Bar +/\nclass Bar\n{\n    int x;\t/// member X\n    int y;\t/// member Y\n    protected int z;\t/// member Z\n}\n\n/++ The Enum Easy +/\n\nenum Easy : int\n{\n\tred,\t/// the Red\n\tblue,\t/// the Blue\n\tgreen,\t/// the Green\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc10.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n// https://issues.dlang.org/show_bug.cgi?id=294\n\n/// The foo\nstruct Foo(T) { }\n/// ditto\nstruct Foo(T,U) { }\n\n/** This basic case doesn't work very well. The template signature is\n  * documented twice, but the function signature (argument names and return\n  * type) is not documented at all. This comment is also repeated twice. */\nint func1(T)(T x) {}\n\n\n\n/** This comment is also repeated twice, and the second function signature is\n  * not very well documented. */\nint func2(T,U)(T x, U y) {}\n\n/// ditto\nint func2(T)(T x) {}\n\n/// Separate overload item.\nint func2()() {}\n\n\n///\ntemplate func3(T,U) {\n        /** This used to work adequately and documented both func3 templates\n          * simultaneously. Now, it documents the first template twice and\n          * no longer documents the function argument and return types.*/\n        int func3(T x, U y) {}\n}\n\n/// ditto\ndeprecated template func3(T, U=int, V:long) {\n\tprivate int func3(T x) {}\n}\n\n\n\n/**\n * blah\n */\n\nvoid map(char rs)\n{\n}\n\n/// Ditto\nvoid map(int rs)\n{\n}\n\n\n\n/**\n * blah\n */\n\nvoid map2()(char rs)\n{\n}\n\n/// Ditto\nvoid map2()(int rs)\n{\n}\n\n\n\n/**\n * blah http://www.map3.com map3\n */\n\nvoid map3(char rs)\n{\n}\n\n\n\n\n/**\n * blah http://www.map.com map\n */\n\nvoid map4(string s)(char rs)\n{\n}\n\n\n\n/**\n * blah http://www.map.com map\n */\n\ntemplate map5(string s)\n{\n}\n\n\n/** blah */\nstruct bar6 {\n        int blah;\n}\n\n\n/** template bodies */\nstruct Foo7(T) {\n\n    /**Attempt one:  Doc outside static if.*/\n    static if(is(T == uint)) {\n        /**Attempt two:  Inside.*/\n        void bar() {}\n    }\n    else {\n        /**Attempt two:  else.*/\n        void bar() {}\n    }\n\n    /** the abc function should be static */\n    static void abc() { }\n}\n\n\n/** show abstract */\nabstract class Foo8 { }\n\n/// a stray $(RPAREN) mustn't foul the macros\nvoid bug4878(string a = \")\") {}\n\n/****\n */\nstruct S\n{\n    /****\n     */\n    this(long ticks) const pure nothrow { }\n\n    /****\n     */\n    pure nothrow this(this) { }\n\n    /****\n     */\n    const pure nothrow ~this() { }\n\n    /****\n     */\n    void foo(long ticks) const pure nothrow { }\n}\n\n\n/** Produces something in (a;b] */\nfloat f10(float a, float b) { return (a+b)/2.0; }\n/** Produces something in [a;b) */\nfloat h10(float a, float b) { return (a+b)/2.0; }\n\n\n///\nvoid bug6090(string f=\"$(B b)\", char g=')')(string h=\"$(\", string i=\"$)\") {}\n\n\n/****\n */\nstruct T\n{\n    /****\n     */\n    this(A...)(A args) { }\n    \n    ///\n    this(int){}\n}\n\n\n// https://issues.dlang.org/show_bug.cgi?id=14547\n\n/// doc-comment\nint x14547 = 1;\n\n/// ditto\nenum int y14547 = 2;\n\n/// doc-comment\nenum isInt14547(T) = is(T == int);\n\n/// ditto\nenum bool isString14547(T) = is(T == string);\n\n/// ditto\nstatic immutable typeName14547(T) = T.stringof;\n\n/// ditto\nint storageFor14547(T) = 0;\n\n/// doc-comment\ntemplate foo14547(T)\n{\n    enum int foo14547 = T.stringof.length;\n}\n\n/// ditto\ntemplate bar14547(T) if (is(T == int))\n{\n    enum int bar14547 = T.stringof.length;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc10236.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -wi -o-\n\n/*\nTEST_OUTPUT:\n---\ncompilable/ddoc10236.d(33): Warning: Ddoc: parameter count mismatch\ncompilable/ddoc10236.d(45): Warning: Ddoc: function declaration has no parameter 'y'\ncompilable/ddoc10236.d(57): Warning: Ddoc: function declaration has no parameter 'y'\ncompilable/ddoc10236.d(57): Warning: Ddoc: parameter count mismatch\n---\n*/\n\n/***********************************\n * foo_good does this.\n * Params:\n *\tx =\tis for this\n *\t\tand not for that\n *\ty =\tis for that\n */\n\nvoid foo_good(int x, int y)\n{\n}\n\n/***********************************\n * foo_count_mismatch does this.\n * Params:\n *\tx =\tis for this\n *\t\tand not for that\n */\n\nvoid foo_count_mismatch(int x, int y)\t// Warning: Ddoc: parameter count mismatch\n{\n}\n\n/***********************************\n * foo_no_param_y does this.\n * Params:\n *\tx =\tis for this\n *\t\tand not for that\n *\ty =\tis for that\n */\n\nvoid foo_no_param_y(int x, int z)\t\t// Warning: Ddoc: function declaration has no parameter 'y'\n{\n}\n\n/***********************************\n * foo_count_mismatch_no_param_y does this.\n * Params:\n *\tx =\tis for this\n *\t\tand not for that\n *\ty =\tis for that\n */\n\nvoid foo_count_mismatch_no_param_y(int x)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc10236b.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -wi -o-\n\n/*\nTEST_OUTPUT:\n---\ncompilable/ddoc10236b.d(43): Warning: Ddoc: parameter count mismatch\ncompilable/ddoc10236b.d(55): Warning: Ddoc: function declaration has no parameter 'y'\ncompilable/ddoc10236b.d(67): Warning: Ddoc: function declaration has no parameter 'y'\ncompilable/ddoc10236b.d(67): Warning: Ddoc: parameter count mismatch\n---\n*/\n\n/***********************************\n * foo_good does this.\n * Params:\n *\tx =\tis for this\n *\t\tand not for that\n *\ty =\tis for that\n */\n\nvoid foo_good(int x)(int y)\n{\n}\n\n/***********************************\n * foo_good2 does this.\n * Params:\n *\ty =\tis for that\n */\n\nvoid foo_good2(int x)(int y)\n{\n}\n\n/***********************************\n * foo_count_mismatch does this.\n * Params:\n *\tx =\tis for this\n *\t\tand not for that\n */\n\nvoid foo_count_mismatch(int x)(int y)\t// Warning: Ddoc: parameter count mismatch\n{\n}\n\n/***********************************\n * foo_no_param_y does this.\n * Params:\n *\tx =\tis for this\n *\t\tand not for that\n *\ty =\tis for that\n */\n\nvoid foo_no_param_y(int x)(int z)\t\t// Warning: Ddoc: function declaration has no parameter 'y'\n{\n}\n\n/***********************************\n * foo_count_mismatch_no_param_y does this.\n * Params:\n *\tx =\tis for this\n *\t\tand not for that\n *\ty =\tis for that\n */\n\nvoid foo_count_mismatch_no_param_y(int x)()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc10325.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc10325;\n\n/** */\ntemplate templ(T...)\n    if (someConstraint!T)\n{\n}\n\n/** */\nvoid foo(T)(T t)\n    if (someConstraint!T)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc10334.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc10334;\n\ntemplate Foo10334(T) if (Bar10334!()) {}                ///\ntemplate Foo10334(T) if (Bar10334!100) {}               ///\ntemplate Foo10334(T) if (Bar10334!3.14) {}              ///\ntemplate Foo10334(T) if (Bar10334!\"str\") {}             ///\ntemplate Foo10334(T) if (Bar10334!1.4i) {}              ///\ntemplate Foo10334(T) if (Bar10334!null) {}              ///\ntemplate Foo10334(T) if (Bar10334!true) {}              ///\ntemplate Foo10334(T) if (Bar10334!false) {}             ///\ntemplate Foo10334(T) if (Bar10334!'A') {}               ///\ntemplate Foo10334(T) if (Bar10334!int) {}               ///\ntemplate Foo10334(T) if (Bar10334!string) {}            ///\ntemplate Foo10334(T) if (Bar10334!([1,2,3])) {}         ///\ntemplate Foo10334(T) if (Bar10334!(Baz10334!())) {}     ///\ntemplate Foo10334(T) if (Bar10334!(Baz10334!T)) {}      ///\ntemplate Foo10334(T) if (Bar10334!(Baz10334!100)) {}    ///\ntemplate Foo10334(T) if (Bar10334!(.foo)) {}            ///\ntemplate Foo10334(T) if (Bar10334!(const int)) {}       ///\ntemplate Foo10334(T) if (Bar10334!(shared T)) {}        ///\n\ntemplate Test10334(T...) {}     ///\nmixin Test10334!int a;          ///\nmixin Test10334!(int,long) b;   ///\nmixin Test10334!\"str\" c;        ///\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc10366.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n///\nstruct S(T)\n{\n    ///\n    void method() {}\n\n    public\n    {\n        ///\n        struct Nested\n        {\n            ///\n            void nestedMethod() {}\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc10367.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n// REQUIRED_ARGS: -m32\n// EXTRA_SOURCES: extra-files/ddoc10367.ddoc\n\nmodule ddoc10367;\n\n/// A\nenum A\n{\n    a = 1, /// a\n    b = 2  /// b\n}\n\n/// B\nenum B : long\n{\n    a = 1, /// a\n    b = 2  /// b\n}\n\n/// C\nenum C : string\n{\n    a = \"a\", /// a\n    b = \"b\"  /// b\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc10869.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc10869;\n\n///\nclass C\n{\n    const\n    {\n        ///\n        void c1Foo() const { }\n\n        ///\n        void i1Foo() immutable { }\n    }\n\n    immutable\n    {\n        ///\n        void c2Foo() const { }\n\n        ///\n        void i2Foo() immutable { }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc10870.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n///\ninterface I\n{\n    ///\n    void f();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc11.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/// The various floating point exceptions\nenum\n{\n    FE_INVALID      = 1,        ///\n    FE_DENORMAL     = 2,        ///\n    FE_DIVBYZERO    = 4,        ///\n    FE_OVERFLOW     = 8,        ///\n    FE_UNDERFLOW    = 0x10,     ///\n    FE_INEXACT      = 0x20,     ///\n    FE_ALL_EXCEPT   = 0x3F,     /// Mask of all the exceptions\n}\n\nalias int myint;\n\n///\nmyint bar;\n\n///\nmyint foo(myint x = myint.max)\n{\n    return x;\n}\n\n\n///\nclass Foo\n{\n    ///\n    this(string s) { }\n}\n\n\nextern (C):\n\n///\nstruct div_t { int  quot,rem; }\n///\nstruct ldiv_t { int quot,rem; }\n///\nstruct lldiv_t { long quot,rem; }\n\n    div_t div(int,int);\t///\n    ldiv_t ldiv(int,int); ///\n    lldiv_t lldiv(long, long); ///\n\n\n\n    void *calloc(size_t, size_t);\t/// \n    void *malloc(size_t);\t/// dittx\n\n/**\nExample:\n---\nprivate:\n    int i = 0;\n---\n*/\nvoid test1()\n{\n}\n\n\n\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc11479.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc11479;\n\n///\nstruct S1(T)\n{\n    ///\n    int a;\n\n    ///\nprivate:\n    int x;\n\nprivate:\n    ///\n    int y;\n\n    ///\npublic:\n    int b;\n\npublic:\n    ///\n    int c;\n}\n\n\n///\nstruct S2(T)\n{\n    ///\n    int a;\n\n    ///\n    private int x;\n\n    ///\n    int b;\n\n    ///\n    public int c;\n\n    public\n    ///\n    int d;\n}\n\n\n///\nstruct S3(T)\n{\n    ///\n    int a;\n\n    ///\n    private { int x; }\n\n    ///\n    int b;\n\n    ///\n    private\n    {\n        int y;\n\n        public\n        {\n            int c;\n        }\n    }\n\n    private\n    {\n        int z;\n\n        ///\n        public\n        {\n            int d;\n        }\n    }\n\n    private\n    {\n        int w;\n\n        public\n        {\n            ///\n            int e;\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc11511.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -w -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\nmodule ddoc11511;\n\n/**\nParams:\nabcd = none1\nbcdef = none23\n... = doo\n*/\nvoid foo(int abcd, int bcdef, ...);\n\n/**\nParams:\nabcd = none1\nbcdef = none23\narr = doo\n*/\nvoid foo(int abcd, int bcdef, int[] arr...);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc11823.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\nmodule ddoc11823;\n\n/// file function name is _file, arg defaults to __FILE__ but not __something__\nvoid file(string arg) { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc12.d",
    "content": "﻿// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nint ruhred; /// This documents correctly.\nint rühred; /// This should too\n\n/**\n * BUG: The parameters are not listed under Params in the generated output\n *\n * Params:\n *     ü = first\n *     ş = second\n *     ğ = third\n *\n */\nint foo(int ü, int ş, int ğ)\n{\n    return ğ;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc12706.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n///\nvoid test()(string[] args) if (args[$])\n{\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc12745.d",
    "content": "// EXTRA_SOURCES:\n// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\ni underlined $(BR)\n_i not underlined $(BR)\n__i force underscore $(BR)\n$(BR)\n_0 not underscored $(BR)\n__0 force underscored\n\n1 underscore:\n$(BR)\n1_1 $(BR)\n1_a $(BR)\na_1 $(BR)\na_a $(BR)\n$(BR)\n2 underscores: $(BR)\n1__a $(BR)\n2__b\n*/\nint i;"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc13.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/// struct doc\nstruct Bug4107(T)\n{\n    /// templated function doc\n    void foo(U)(U u) { }\n}\n\n/// alpha\nstruct Bug4107b(T) {\n    /// beta\n    struct B(U) {\n        /// gamma\n        struct C(V) {\n            /// delta\n            struct D(W) {\n                /// epsilon\n                B!W e(X)(C!V c, X[] x...) {}\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc13270.d",
    "content": "// PERMUTE_ARGS: -w\n// REQUIRED_ARGS: -o- -D -Dd${RESULTS_DIR}/compilable\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc13270;\n\n/**\n * My overloaded function.\n *\n * Params:\n *      task = String description of stuff to do.\n *      tasks = Array of descriptions of stuff to do.\n *      maxJobs = Max parallel jobs to run while doing stuff.\n */\nvoid doStuff(string task) {}\n\n/// ditto\nvoid doStuff(string[] tasks, int maxJobs) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc13502.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -wi -o-\n/*\nTEST_OUTPUT:\n---\ncompilable/ddoc13502.d(14): Warning: Ddoc: Stray '('. This may cause incorrect Ddoc output. Use $(LPAREN) instead for unpaired left parentheses.\ncompilable/ddoc13502.d(17): Warning: Ddoc: Stray '('. This may cause incorrect Ddoc output. Use $(LPAREN) instead for unpaired left parentheses.\ncompilable/ddoc13502.d(21): Warning: Ddoc: Stray '('. This may cause incorrect Ddoc output. Use $(LPAREN) instead for unpaired left parentheses.\ncompilable/ddoc13502.d(24): Warning: Ddoc: Stray '('. This may cause incorrect Ddoc output. Use $(LPAREN) instead for unpaired left parentheses.\n---\n*/\n\n/// (\nenum isSomeString(T) = true;\n\n/// (\nenum bool isArray(T) = true;\n\n\n/// (\nextern(C) alias int T1;\n\n/// (\nextern(C) alias T2 = int;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc13645.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\nDocumentation comment on module\n*/\ndeprecated(\"msg\") @(1)\nmodule ddoc13645;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc14.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n\nalias void V;\nalias double* P;\n\n/// -1\nstruct Structure {\n    public P variable;  /// 0\n    V mNone(lazy P p) {}  /// 1\n    pure nothrow V mPrefix(lazy P p) {}   /// 2\n    V mSuffix(lazy P p) pure nothrow {}   /// 3\n//  pure nothrow V mPrefixTemplate(T)(lazy P p, T[] t...) {}   /// 4\n    V mSuffixTemplate(T)(lazy P p, T[] t...) pure nothrow {}   /// 5\n    pure nothrow {\n        V mScoped(lazy P p) {}    /// 6\n    }\n    pure nothrow auto mAutoPrefix(ref P p) { return p; } /// 7\n//  pure nothrow auto mAutoTemplatePrefix(alias T)(ref T t) { return p; } /// 8\n    auto mAutoTemplateSuffix(alias T)(ref T t) pure nothrow { return p; } /// 9\n    pure nothrow:\n    V mColon(lazy P p) {} /// 10\n}\n\n/// -1\nclass Class {\n    public P variable;  /// 0\n    V mNone(lazy P p) {}  /// 1\n    pure nothrow V mPrefix(lazy P p) {}   /// 2\n    V mSuffix(lazy P p) pure nothrow {}   /// 3\n//  pure nothrow V mPrefixTemplate(T)(lazy P p, T[] t...) {}   /// 4\n    V mSuffixTemplate(T)(lazy P p, T[] t...) pure nothrow {}   /// 5\n    pure nothrow {\n        V mScoped(lazy P p) {}    /// 6\n    }\n    pure nothrow auto mAutoPrefix(ref P p) { return p; } /// 7\n//  pure nothrow auto mAutoTemplatePrefix(alias T)(ref T t) { return p; } /// 8\n    auto mAutoTemplateSuffix(alias T)(ref T t) pure nothrow { return p; } /// 9\n    pure nothrow:\n    V mColon(lazy P p) {} /// 10\n}\n\n/+\n/// -1\nstruct StructTemplate() {\n    public P variable;  /// 0\n    V mNone(lazy P p) {}  /// 1\n    pure nothrow V mPrefix(lazy P p) {}   /// 2\n    V mSuffix(lazy P p) pure nothrow {}   /// 3\n//  pure nothrow V mPrefixTemplate(T)(lazy P p, T[] t...) {}   /// 4\n    V mSuffixTemplate(T)(lazy P p, T[] t...) pure nothrow {}   /// 5\n    pure nothrow {\n        V mScoped(lazy P p) {}    /// 6\n    }\n    pure nothrow auto mAutoPrefix(ref P p) { return p; } /// 7\n//  pure nothrow auto mAutoTemplatePrefix(alias T)(ref T t) { return p; } /// 8\n    auto mAutoTemplateSuffix(alias T)(ref T t) pure nothrow { return p; } /// 9\n    pure nothrow:\n    V mColon(lazy P p) {} /// 10\n}\n\n/// -1\ninterface Interface {\n    V mNone(lazy P p) ;  /// 1\n    pure nothrow V mPrefix(lazy P p) ;   /// 2\n    V mSuffix(lazy P p) pure nothrow ;   /// 3\n//  pure nothrow V mPrefixTemplate(T)(lazy P p, T[] t...) ;   /// 4\n    V mSuffixTemplate(T)(lazy P p, T[] t...) pure nothrow ;   /// 5\n    pure nothrow {\n        V mScoped(lazy P p) ;    /// 6\n    }\n//  pure nothrow auto mAutoTemplatePrefix(alias T)(ref T t) { return p; } /// 8\n    auto mAutoTemplateSuffix(alias T)(ref T t) pure nothrow { return p; } /// 9\n    pure nothrow:\n    V mColon(lazy P p) ; /// 10\n}\n+/\n    \npublic P variable;  /// 0\nV mNone(lazy P p) {}  /// 1\npure nothrow V mPrefix(lazy P p) {}   /// 2\nV mSuffix(lazy P p) pure nothrow {}   /// 3\n//  pure nothrow V mPrefixTemplate(T)(lazy P p, T[] t...) {}   /// 4\nV mSuffixTemplate(T)(lazy P p, T[] t...) pure nothrow {}   /// 5\npure nothrow {\n    V mScoped(lazy P p) {}    /// 6\n}\npure nothrow auto mAutoPrefix(ref P p) { return p; } /// 7\n//  pure nothrow auto mAutoTemplatePrefix(alias T)(ref T t) { return p; } /// 8\nauto mAutoTemplateSuffix(alias T)(ref T t) pure nothrow { return p; } /// 9\npure nothrow:\nV mColon(lazy P p) {} /// 10\n\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc14383.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\n * Module docs.\n */\nmodule ddoc14383;\n\n/// Ddoc'd unittest\nunittest\n{\n    int iShouldAppearInTheDocs;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc14413.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc14413;\n\n/// This should\n/// be one\n/// paragraph.\n///\n/// Paragraph 2\nvoid foo(){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc14633.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -w -o-\n\n/*\nTEST_OUTPUT:\n---\n---\n*/\n\n/** Blah\n Params:\n    T = some type\n    test = something\n    overnext = for testing overloaded functions\n*/\ntemplate case1(T)\n{\n  void case1(R)(R test) { }\n  void case1(R)(R test, string overnext) { }\n}\n\n///ditto\nalias case2 = case1!int;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc14778.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc14778;\n\n/// docs for Z\ntemplate Z14778(T)\n{\n    /// docs for E\n    enum E;\n\n    /// docs for x\n    enum x = 1.0;\n\n    /// docs for mv\n    auto mv = 1;\n\n    /// docs for wv\n    inout wv = 3;\n\n    /// doc for cv\n    const cv = \"a\";\n\n    /// docs for wcv\n    inout const wcv = \"ab\";\n\n    /// doc for sv\n    shared sv = 1.4142;\n\n    /// doc for swv\n    shared inout swv = 3.14;\n\n    /// doc for scv\n    shared const scv = new Object();\n\n    /// docs for swcv\n    shared inout const swcv = undefined;\n\n    /// doc for iv\n    immutable iv = [1,2,3];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc15475.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\nMy module\n----\n   // Computes the interval [x,y)\n   auto interval = computeInterval(x, y);\n----\n\nBackslash-escape parentheses with `\\(` and `\\)`.\n\n---\n(\n---\n\n---\n)\n---\n\n---\n    Here are some nested `backticks`\n    // Another interval [x,y)\n---\n\n---\n    This won't end the code block: --- )\n    // Yet another interval [x,y)\n---\n*/\nmodule ddoc15475;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc17697.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/***\n * See:\n *    http://www.fooa.com/test1\n *    http://www.fooa.com/_test1\n *    https://www.foob.com/test1\n *    $(LINK http://www.fooc.com/test1)\n *    $(LINK2 http://www.food.com/test1, test1)\n */\n\n/**\nAlso piggyback a few tests for https://github.com/dlang/dmd/pull/6989\n\nnot_a_tag_because_it_does_not_start_with_uppercase:\n\nnot_a_tag_because_no_whitespace_after_colon:x\n\nTagGalore: yes this is a tag\n\nMoreTag:\nyes the above is also a tag\n*/\n\nmodule test1;\n\nint a;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc18361.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n// REQUIRED_ARGS: -d\n\n// Test notes: 'main' is the symbol being documented (DDOC_AUTO_PSYMBOL),\n// 'arguments' is a parameter (DDOC_AUTO_PARAM), and 'false' is a keyword\n// (DDOC_AUTO_KEYWORD).\n/**\n * The main thing this program does is nothing, and I do _not want to hear any\n * false arguments about that!\n *\n * Macros:\n * DDOC_AUTO_PSYMBOL = $0\n * DDOC_AUTO_KEYWORD = $0\n * DDOC_AUTO_PARAM = $0\n * DDOC_AUTO_PSYMBOL_SUPPRESS = HALPIMBEINGSUPPRESSED $0\n *\n * DDOC = $(BODY)\n * DDOC_DECL = $0\n * DDOC_MEMBER_HEADER =\n * DDOC_MODULE_MEMBERS = $0\n * DDOC_MEMBER = $0\n */\nvoid main(string[] arguments)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc198.d",
    "content": "// EXTRA_SOURCES: extra-files/ddoc198.ddoc\n// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc198;\n\n///\ninterface I1 { }\n\n///\nclass C1 { }\n\n///\nclass Foo : C1, I1 { }\n\n///\nenum X { x = 1 }\n\n///\nenum Y : X { y = X.x }\n\n///\nstruct S1 { }\n\n///\nenum enS : S1 { a = S1() }\n\n// disabled until class enums are possible\n// enum enC : C1 { a = new C1() }\n\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc2.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\n * Summary\n *\n * Description1\n *\n * Description2\n *\n * Description3\n *\n * Macros:\n *\tWIKI = StdStream\n *\tmeemie\n * See_Also:\n *\tThings to see also.\n *\n *\tAnd more things.\n */\n\n/*\n */\n\nmodule std.test;\n\n/// A base class for stream exceptions.\nclass StreamException: Exception {\n  /** Construct a StreamException with given error message msg.\n   * Params:\n   *\tmsg = the $(RED red) $(BLUE blue) $(GREEN green) $(YELLOW yellow).\n   *\tfoo = next parameter which is a much longer\n   *\t\tmessage spanning multiple\n   *\t\tlines.\n   */\n  this(string msg, int foo) { super(msg); }\n\n    /********** stars ***************/\n    int stars;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc2273.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n// REQUIRED_ARGS: -m32\n\nmodule ddoc2273;\n\ninterface A { }\n\ninterface C { }\ninterface D { }\n\n///\ninterface B : C, D { }\n\n///\nclass Foo : A, B { }\n\n///\nMinType!(T1, T2, T) min(T1, T2, T...)(T1 a, T2 b, T xs) { }\n\n///\nTempl!([1, 2, 3]) max(T...)() { }\n\n///\ntemplate Base64Impl(char Map62th, char Map63th, char Padding) { }\n\n///\nint sqlite3_config(int,...);\n\ntemplate staticIndexOf(T, TList...) { alias int staticIndexOf; }\n\n///\nalias staticIndexOf IndexOf;\n\nvoid main() { }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc3.d",
    "content": "// EXTRA_SOURCES: extra-files/ddoc3.ddoc\n// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\n * Summary\n *\n * Description1\n *\n * Description2\n *\n * Description3\n *\n * Macros:\n *\tWIKI = StdStream\n *\tmeemie\n *\tARG0 = $0\n *\tARG1 = $1\n *\tARG2 = $2\n *\tARG3 = $3\n *\tPLUS = $+\n *\tTROW = $(TR $(TCOL $1,$+))\n *\tTCOL = $(TD $1) $(TCOL $+)\n *\tLPAREN = (\n * See_Also:\n *\tThings to see also.\n *\n *\tAnd more things $(BR)\n *\t'arg1, arg2, arg3' : $(ARG0 arg1, arg2, arg3). $(BR)\n *\t'arg2, arg3' : $(PLUS arg1, arg2, arg3). $(BR)\n *\t'arg1' : $(ARG1 arg1, arg2, arg3). $(BR)\n *\t'arg2' : $(ARG2 arg1, arg2, arg3). $(BR)\n *\t'arg3' : $(ARG3 arg1, arg2, arg3). $(BR)\n */\n\n/**\n *\tThings to see also $(HELLO).\n *\n *\t$(TABLE\n *\t$(TROW 1, 2, 3)\n *\t$(TROW 4, 5, 6)\n *\t)\n *\n * $(D_CODE \n      $(B pragma)( $(I name) );\n      $(B pragma)( $(I name) , $(I option) [ $(I option) ] );\n      $(U $(LPAREN))\n  )\n */\n\n/*\n */\n\nmodule std.test;\n\n/// A base class for stream exceptions.\nclass StreamException: Exception {\n  /** Construct a StreamException with given error message msg.\n   * Params:\n   *\tmsg = the $(RED red) $(BLUE blue) $(GREEN green) $(YELLOW yellow).\n   *\tfoo = next parameter which is a much longer\n   *\t\tmessage spanning multiple\n   *\t\tlines.\n   */\n  this(string msg, int foo) { super(msg); }\n\n    /********** stars ***************/\n    int stars;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc4.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\n    a\n*/\nenum\n{\n    ONE\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc4162.d",
    "content": "﻿// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n///\ninterface A\n{\n\t///\n\tstatic void staticHello() { }\n\n\t///\n\tfinal void hello() { }\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc4899.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -wi -o-\n\n/*\nTEST_OUTPUT:\n---\ncompilable/ddoc4899.d(18): Warning: Ddoc: Stray '('. This may cause incorrect Ddoc output. Use $(LPAREN) instead for unpaired left parentheses.\ncompilable/ddoc4899.d(19): Warning: Ddoc: Stray ')'. This may cause incorrect Ddoc output. Use $(RPAREN) instead for unpaired right parentheses.\n---\n*/\n\n/++\n       (See accompanying file LICENSE_1_0.txt or copy at\n        foo:)\n+/\nmodule d;\n\n/** ( */ int a;\n/** ) */ int b;\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc5.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\n\n  Test module\n\n*/\nmodule test;\n\n/// class to test DDOC on members\nclass TestMembers(TemplateArg)\n{\n  public:\n    /**\n\n       a static method \n\n       Params: idx = index\n   \n    */\n    static void PublicStaticMethod(int  idx)\n    {\n    }\n}\n\nvoid main()\n{\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc5446.d",
    "content": "﻿// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\nmodule ddoc5446;\nimport ddoc5446a;\nprivate import ddoc5446b;\n\n/** */\nalias A_Foo This_Foo;\n\n/** */\nalias A_Foo_Alias This_Foo_Alias;\n\n/** */\nalias int This_Int;\n\n/** */\nalias A_Enum This_Enum;\n\n/** */\ndeprecated alias ddoc5446b.A_Enum_New A_Enum_New;\n\nstruct Nested\n{\n}\n\n/** */\nstruct Bar\n{\n    /** */\n    alias A_Foo Bar_A_Foo;\n    \n    /** */\n    alias A_Foo_Alias Bar_A_Foo_Alias;\n    \n    /** */\n    alias A_Int Bar_A_Int;\n    \n    /** */\n    alias This_Foo Bar_This_Foo;\n    \n    /** */\n    alias This_Foo_Alias Bar_This_Foo_Alias;\n    \n    /** */\n    alias This_Int Bar_This_Int;\n    \n    /** */\n    alias Nested Nested_Alias;\n    \n    /** */\n    alias .Nested Fake_Nested;\n    \n    /** */\n    struct Nested\n    {\n        /** */\n        alias Bar Bar_Nested_Bar_Alias;\n        \n        /** */\n        alias .Bar Bar_Alias;\n        \n        /** */\n        struct Bar\n        {\n            \n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc5446a.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\nmodule ddoc5446a;\n\n/** */\nstruct A_Foo { }\n\n/** */\nalias A_Foo A_Foo_Alias;\n\n/** */\nalias int A_Int;\n\n/** */\nenum A_Enum { x }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc5446b.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\nmodule ddoc5446b;\n\n/** */\nenum A_Enum_New { x }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc6.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\n *\n */\nstruct MyStruct(T)\n{\n    static if( true )\n    {\n        void MyStruct() {}\n    }\n}\n\nvoid main()\n{\n}\n\n/+\n23\nC:\\code\\d\\bugs>dmd -D -o- 148_1.d\n148_1.d(6): Error: static if conditional cannot be at global scope\n+/\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc648.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc648;\n\n/// Mixin declaration\nmixin template Mixin1()\n{\n    /// struct S\n    struct S { }\n}\n\n/// class A\nclass A\n{\n    /// field x\n    int x;\n\n    /// no docs for mixin statement (only for expanded members)\n    mixin Mixin1!();\n}\n\n/// class AB\nclass AB\n{\n    /// field x\n    int x;\n\n    // no docs for mixin or its contents, must be a ddoc comment\n    mixin Mixin1!();\n}\n\n/// Mixin declaration2\nmixin template Mixin2()\n{\n    /// struct S2\n    struct S2 { }\n}\n\n/// Mixin declaration3\nmixin template Mixin3()\n{\n    /// another field\n    int f;\n\n    /// no docs for mixin statement (only for expanded members)\n    mixin Mixin2!();\n}\n\n/// class B1\nclass B1\n{\n    /// no docs for mixin statement (only for expanded members)\n    mixin Mixin3!();\n}\n\n\n/// Mixin declaration3\nmixin template Mixin4()\n{\n    /// another field\n    int f;\n\n    // no docs at all for non-ddoc comment\n    mixin Mixin2!();\n}\n\n/// class B2\nclass B2\n{\n    /// no docs for mixin statement (only for expanded members)\n    mixin Mixin4!();\n}\n\n/// no docs for mixin statement (only for expanded members)\nmixin Mixin3!();\n\n///\nstruct TS(T)\n{\n    mixin template MT()\n    {\n    }\n\n    mixin MT;  /// avoid calling semantic\n\n    ///\n    int field;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc6491.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc6491;\n\nimport core.cpuid;\n\nenum int c6491 = 4;\n\n/// test\nvoid bug6491a(int a = ddoc6491.c6491, string b = core.cpuid.vendor);\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc7.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n//-----------------------------------------------\n/// my enum\nenum E1\n{\n    A, /// element a\n    B  /// element b\n}\n\n/// my enum\nenum E2\n{\n    /// element a\n    A,\n    /// element b\n    B\n}\n\n/// my enum\nenum E3\n{\n      A /// element a\n    , B /// element b\n}\n\n/// my enum\nenum E4\n{\n    A /// element a\n    ,\n    B /// element b\n}\n\n/// my enum\nenum E5\n{\n    /// element a\n    A\n    ,\n    /// element b\n    B\n}\n\n/// Some doc\nvoid foo() {}\n\n/// More doc\nalias foo bar;\n\n/// asdf\nclass C\n{\n    /// Some doc\n    abstract void foo();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc7555.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\nmodule ddoc7555;\n\n/**\nDummy doc.\n\n$(X0\n  DelimitedString\n  TokenString)\n\n$(X1\n  DelimitedString\n  TokenString)\n\n$(X2 x,HexString)\n$(X2 x, HexString)\n\n$(X3 x,x,HexString)\n$(X3 x,x, HexString)\n\n$(X4 x,x,x,HexString)\n$(X4 x,x,x, HexString)\n\n$(X5 x,x,x,x,HexString)\n$(X5 x,x,x,x, HexString)\n\n$(X6 x,x,x,x,x,HexString)\n$(X6 x,x,x,x,x, HexString)\n\n$(X7 x,x,x,x,x,x,HexString)\n$(X7 x,x,x,x,x,x, HexString)\n\n$(X8 x,x,x,x,x,x,x,HexString)\n$(X8 x,x,x,x,x,x,x, HexString)\n\n$(X9 x,x,x,x,x,x,x,x,HexString)\n$(X9 x,x,x,x,x,x,x,x, HexString)\n\nMacros:\n    X0=$0\n    X1=$1\n    X2=$2\n    X3=$3\n    X4=$4\n    X5=$5\n    X6=$6\n    X7=$7\n    X8=$8\n    X9=$9\n*/\nvoid dummy();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc7656.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc7656;\n\n/**\n--------\nint x; // This is a $ comment (and here is some\nint y; // more information about that comment)\n--------\n*/\nvoid main() { }\n\n\n/**\n(Regression check)\n\nExample:\n----\nassert(add(1, 1) == 2);\n----\n*/\nint add(int a, int b) { return a + b; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc7715.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc7656;\n\n/**\n&#36;1 &#36;2\n---\nstring s = \"$1$2 $ &#36;4\";\n---\n*/\nvoid foo(){}\n\n///\nvoid test(string a = \")\") {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc7795.d",
    "content": "﻿// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc7795;\n\nstruct TimeValue {\n    this(int hour, int minute, int second = 0, int ms = 0) {}\n}\n\n///\nstruct DateTime {\n    ///\n    this(int x, TimeValue t = TimeValue(0, 0)) {}\n}\n\nvoid main() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc8.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/** foo */\n\nclass Foo(T) : Bar\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc8271.d",
    "content": "﻿// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc8271;\n\n/**\n    $(まくろ)\nMacros:\n    まくろ = $(マクロ)\n    マクロ = Macro\n*/\nvoid ddoc8271()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc8739.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc8739;\n\n///\nvoid delegate(int a) dg;\n\n///\nvoid delegate(int b) dg2;\n\n///\nvoid delegate(int c)[] dg3;\n\n///\nvoid delegate(int d)* dg4;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n// https://issues.dlang.org/show_bug.cgi?id=273\n\n/// Template Documentation (OK)\ntemplate Template(T) { }\n\n/// Function Documentation (Not included at all by DDoc)\nvoid Function(T)(T x) { }\n\n/// Class Documentation (OK)\nclass Class(T) { }\n\n/// Struct Documentation\nstruct Struct(T) { }\n\n/// Union Documentation\nunion Union(T) { }\n\n/// Template documentation with anonymous enum\ntemplate TemplateWithAnonEnum(T)\n{\n    enum { TemplateWithAnonEnum = 1 }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9037.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc9037;\n\n/**\nExample:\n----\nD d = d;\n----\n----\nD d = d;\n----\n*/\nvoid test9037()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9155.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc9155;\n\n/++\n +  Note:\n +     test document note\n +     2nd line\n +  Example:\n +  ---\n +  import std.stdio;   //&\n +  writeln(\"Hello world!\");\n +  if (test) {  \n +    writefln(\"D programming language\");\n +  }\n +\n +      algorithm;\n +  \n +  xxx;    //comment\n +      yyy;\n +  /* test\n +   * comment\n +   */\n +\n + // Create MIME Base64 with CRLF, per line 76.\n +File f = File(\"./text.txt\", \"r\");\n +uint line = 0;\n + // The ElementType of data is not aggregation type\n +foreach (encoded; Base64.encoder(data)) \n +  ---\n +/\n\n/**\n  --------------------------------------------------------\n  wstring ws;\n  transcode(\"hello world\",ws);\n      // transcode from UTF-8 to UTF-16\n      --------------------------------------------------------\n */\n\n/**\n *  Example:\n *  ---\n *  import std.stdio;   //&\n *  writeln(\"Hello world!\");\n *  if (test) {  \n *    writefln(\"D programming language\");\n *  }\n *\n *      algorithm;\n *  \n *  xxx;    //comment\n *      yyy;\n *  /+ test\n *   + comment\n *   +/\n *  ---\n */\n\n/**\n----\n#!/usr/bin/env rdmd\n// Computes average line length for standard input.\nimport std.stdio;\n----\n*/\n\n/**\n\t---\n\twritefln(q\"EOS\n\tThis\n\tis a multi-line\n\theredoc string\n\tEOS\"\n\t);\n\t---\n*/\n\nvoid foo(){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9305.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc9305;\n\n/**\nfoo()\n*/\nvoid foo(alias p = (a => a))() {}\n\n/* ret / prm / body */\n/*  _  /  _  / expr */  template X(alias pred = x => x) {}                                  ///\n/*  _  /  _  / stmt */  template X(alias pred = (x){ int y; return y; }) {}                 /// ditto\n/*  _  /  x  / expr */  template X(alias pred = (int x) => x) {}                            /// ditto\n/*  _  /  x  / stmt */  template X(alias pred = (int x){ int y; return y; }) {}             /// ditto\n/*  x  /  _  / expr */\n/*  x  /  _  / stmt */\n/*  x  /  x  / expr */\n/*  x  /  x  / stmt */\n\n/*  _ /   _  / expr */  template X(alias pred = function (x) => x) {}                       ///\n/*  _ /   _  / stmt */  template X(alias pred = function (x){ return x + 1; }) {}           /// ditto\n/*  _  /  x  / expr */  template X(alias pred = function (int x) => x) {}                   /// ditto\n/*  _  /  x  / stmt */  template X(alias pred = function (int x){ return x + 1; }) {}       /// ditto\n/*  x  /  _  / expr */  template X(alias pred = function int(x) => x) {}                    /// ditto\n/*  x  /  _  / stmt */  template X(alias pred = function int(x){ return x + 1; }) {}        /// ditto\n/*  x  /  x  / expr */  template X(alias pred = function int(int x) => x) {}                /// ditto\n/*  x  /  x  / stmt */  template X(alias pred = function int(int x){ return x + 1; }) {}    /// ditto\n\n/*  _ /   _  / expr */  template X(alias pred = delegate (x) => x) {}                       ///\n/*  _ /   _  / stmt */  template X(alias pred = delegate (x){ return x + 1; }) {}           /// ditto\n/*  _  /  x  / expr */  template X(alias pred = delegate (int x) => x) {}                   /// ditto\n/*  _  /  x  / stmt */  template X(alias pred = delegate (int x){ return x + 1; }) {}       /// ditto\n/*  x  /  _  / expr */  template X(alias pred = delegate int(x) => x) {}                    /// ditto\n/*  x  /  _  / stmt */  template X(alias pred = delegate int(x){ return x + 1; }) {}        /// ditto\n/*  x  /  x  / expr */  template X(alias pred = delegate int(int x) => x) {}                /// ditto\n/*  x  /  x  / stmt */  template X(alias pred = delegate int(int x){ return x + 1; }) {}    /// ditto\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9369.d",
    "content": "// PERMUTE_ARGS:\n// EXTRA_SOURCES: extra-files/ddoc9369.ddoc\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\nSample:\n---\na=1;\nwriteln(&a);\n!\n?\n---\n*/\nvoid foo() { }\n\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9475.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -w -o- -c -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc9475;\n\n/// foo\nvoid foo() { }\n\n///\nunittest\n{\n    // comment 1\n    foreach (i; 0 .. 10)\n    {\n        // comment 2\n        documentedFunction();\n    }\n}\n\n/// bar\nvoid bar() { }\n\n///\nunittest\n{\n    // bar comment\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9497a.d",
    "content": "// EXTRA_SOURCES: extra-files/ddoc9497a.ddoc\n// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\n    foo function.\n    Args: $(XYZ arg1, arg2)\n*/\nvoid foo()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9497b.d",
    "content": "// EXTRA_SOURCES: extra-files/ddoc9497b.ddoc\n// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\n    foo function.\n    Args: $(XYZ arg1, arg2)\n*/\nvoid foo()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9497c.d",
    "content": "// EXTRA_SOURCES: extra-files/ddoc9497c.ddoc\n// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\n    foo function.\n    Args: $(XYZ arg1, arg2)\n*/\nvoid foo()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9497d.d",
    "content": "// EXTRA_SOURCES: extra-files/ddoc9497d.ddoc\n// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/**\n    foo function.\n    Args: $(XYZ arg1, arg2)\n*/\nvoid foo()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9676a.d",
    "content": "// PERMUTE_ARGS:\n// EXTRA_SOURCES: /extra-files/ddoc9676a.ddoc\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc9676a;\n\n///\ndeprecated void foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9676b.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc9676b;\n\n///\ndeprecated void foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9727.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\nmodule ddoc9727;\n\n/** The function foo. */\nvoid foo(int x);\n\n/**  */\nunittest\n{\n    foo(1);\n}\n\n/** foo can be used like this: */\nunittest\n{\n    foo(2);\n}\n\n/** foo can also be used like this: */\nunittest\n{\n    foo(3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9789.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -w -o- -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddoc9789;\n\n///\nstruct S {}\n\n///\nalias A = S;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddoc9903.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/// sss\nstruct S9903X {}\n/// Ditto\nstruct S9903Y {}\n\n/// ccc\nclass C9903X {}\n/// Ditto\nclass C9903Y {}\n\n/// uuu\nunion U9903X {}\n/// Ditto\nunion U9903Y {}\n\n/// iii\ninterface I9903X {}\n/// Ditto\ninterface I9903Y {}\n\n/// eee\nenum E9903X { a }\n/// Ditto\nenum E9903Y { a }\n\n///\nenum {\n    a9903,  /// ea\n    b9903,  /// Ditto\n    c9903,  /// ec\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddocYear.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocYear-postscript.sh\n\n/// $(YEAR)\nint year;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddocbackticks.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\n/++\n        Closely related to std.datetime is <a href=\"core_time.html\">`core.time`</a>,\n    and some of the time types used in std.datetime come from there - such as\n    $(CXREF time, Duration), $(CXREF time, TickDuration), and\n    $(CXREF time, FracSec).\n    core.time is publically imported into std.datetime, it isn't necessary\n    to import it separately.\n+/\nmodule ddocbackticks;\n\n/// This should produce `inline code`.\nvoid test() {}\n\n/// But `this should NOT be inline'\n///\n/// However, restarting on a new line should be `inline again`.\nvoid test2() {}\n\n/// This `int foo;` should show highlight on foo, but not int.\nvoid foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ddocunittest.d",
    "content": "// PERMUTE_ARGS: -unittest\n// REQUIRED_ARGS: -D -w -o- -Dd${RESULTS_DIR}/compilable -o-\n// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh\n\nmodule ddocunittest;\n\n/* Insert test-cases for documented unittests feature here. */\n\n/// foo function - 1 example\nint foo(int a, int b) { return a + b; }\n\n///\nunittest\n{\n    assert(foo(1, 1) == 2);\n}\n\n/// bar function - 1 example\nbool bar() { return true; }\n\n///\nunittest\n{\n    // documented\n    assert(bar());\n}\n\n/// placeholder\nunittest\n{\n}\n\n/// doo function - no examples\nvoid doo() { }\n\n///\nprivate unittest\n{\n    // undocumented\n    doo();\n}\n\nunittest\n{\n    // undocumented\n    doo();\n}\n\n/**\nadd function - 3 examples\n\nExamples:\n\n----\nassert(add(1, 1) == 2);\n----\n*/\nint add(int a, int b) { return a + b; }\n\n///\nunittest\n{\n    // documented\n    assert(add(3, 3) == 6);\n    assert(add(4, 4) == 8);\n}\n\nunittest\n{\n    // undocumented\n    assert(add(2, 2) + add(2, 2) == 8);\n}\n\n///\nunittest\n{\n    // documented\n    assert(add(5, 5) == 10);\n    assert(add(6, 6) == 12);\n}\n\n/// class Foo\nimmutable pure nothrow class Foo\n{\n    int x;\n\n    ///\n    unittest\n    {\n        // another foo example\n        Foo foo = new Foo;\n    }\n}\n\n///\nunittest\n{\n    Foo foo = new Foo;\n}\n\npure\n{\n    const\n    {\n        immutable\n        {\n            /// some class - 1 example\n            class SomeClass {}\n        }\n    }\n}\n\n///\nunittest\n{\n    SomeClass sc = new SomeClass;\n}\n\n/// Outer - 1 example\nclass Outer\n{\n    /// Inner\n    static class Inner\n    {\n    }\n\n    ///\n    unittest\n    {\n        Inner inner = new Inner;\n    }\n}\n\n///\nunittest\n{\n    Outer outer = new Outer;\n}\n\n/** foobar - no examples */\nvoid foobar()\n{\n}\n\nunittest\n{\n    foobar();\n}\n\n/**\nfunc - 4 examples\nExamples:\n---\nfoo(1);\n---\n\nExamples:\n---\nfoo(2);\n---\n*/\nvoid foo(int x) {  }\n\n///\nunittest\n{\n    foo(2);\n}\n\n///\nunittest\n{\n    foo(4);\n}\n\n// ------------------------------------\n// insert import declaration between documented function and unittests\n\n///\nvoid fooImport() {}\nimport core.stdc.stdio;\n/// test\nunittest { fooImport(); }\n\n///\nvoid fooStaticImport() {}\nstatic import core.stdc.stdlib;\n/// test\nunittest { fooStaticImport(); }\n\n///\nvoid fooPublicImport() {}\npublic import core.stdc.string;\n/// test\nunittest { fooPublicImport(); }\n\n///\nvoid fooSelectiveImport() {}\nimport core.stdc.ctype : isalpha;\n/// test\nunittest { fooSelectiveImport(); }\n\n///\nvoid fooRenamedImport() {}\nimport io = core.stdc.stdio;\n/// test\nunittest { fooRenamedImport(); }\n\n// ------------------------------------\n// documented unittest after conditional declarations\n\nstatic if (true)\n  void fooConditionalDecl1a() {} /** */\nunittest { int x1a; }   ///\n\nstatic if (true)\n{ void fooConditionalDecl1b() {} /** */ }\nunittest { int x1b; }   ///\n\nstatic if (false)\n  void fooConditionalDecl2a() {} /** */\nunittest { int x2a; }   ///\n\nstatic if (false)\n{ void fooConditionalDecl2b() {} /** */ }\nunittest { int x2b; }   ///\n\nstatic if (true)\n{ void fooConditionalDecl3a() {} /** */ }\nelse\n{ void barConditionalDecl3a() {} /** */ }\nunittest { int x3a; }   ///\n\nstatic if (true)\n{ void fooConditionalDecl3b() {} /** */ }\nelse\n{ void barConditionalDecl3b() {} /** */ }\nunittest { int x3b; }   ///\n\nstatic if (false)\n  void fooConditionalDecl4a() {} /** */\nelse\n  void barConditionalDecl4a() {} /** */\nunittest { int x4a; }   ///\n\nstatic if (false)\n{ void fooConditionalDecl4b() {} /** */ }\nelse\n{ void barConditionalDecl4b() {} /** */ }\nunittest { int x4b; }   ///\n\nstatic if (true)\n{}\nelse\n  void barConditionalDecl5a() {} /** */\nunittest { int x5a; }   ///\n\nstatic if (true)\n{}\nelse\n{ void barConditionalDecl5b() {} /** */ }\nunittest { int x5b; }   ///\n\nstatic if (false)\n{}\nelse\n  void barConditionalDecl6a() {} /** */\n///\nunittest { int x6a; }\n\nstatic if (false)\n{}\nelse\n{ void barConditionalDecl6b() {} /** */ }\n///\nunittest { int x6b; }\n\n// ------------------------------------\n// https://issues.dlang.org/show_bug.cgi?id=9474\n\n///\nvoid foo9474() { }\n\nversion(none)\nunittest { }\n\n/// Example\nunittest { foo9474(); }\n\n/// doc\nvoid bar9474() { }\n\nversion(none)\nunittest { }\n\n/// Example\nunittest { bar9474(); }\n\n///\nstruct S9474\n{\n}\n///\nunittest { S9474 s; }\n\n///\nauto autovar9474 = 1;\n///\nunittest { int v = autovar9474; }\n\n///\nauto autofun9474() { return 1; }\n///\n    unittest { int n = autofun9474(); }\n\n///\ntemplate Template9474()\n{\n    /// Shouldn't link following unittest to here\n    void foo() {}\n}\n///\nunittest { alias Template9474!() T; }\n\n// ------------------------------------\n// https://issues.dlang.org/show_bug.cgi?id=9713\n\n///\nvoid fooNoDescription() {}\n///\nunittest { fooNoDescription(); }\n///\nunittest { if (true) {fooNoDescription(); } /* comment */ }\n\n// ------------------------------------\n\n/// test for https://issues.dlang.org/show_bug.cgi?id=9757\nvoid foo9757() {}\n/// ditto\nvoid bar9757() {}\n/// ditto\nvoid baz9757() {}\n///\nunittest { foo9757(); bar9757(); }\n///\nunittest { bar9757(); foo9757(); }\n\n/// with template functions\nauto redBlackTree(E)(E[] elems...)\n{\n    return 1;\n}\n/// ditto\nauto redBlackTree(bool allowDuplicates, E)(E[] elems...)\n{\n    return 2;\n}\n/// ditto\nauto redBlackTree(alias less, E)(E[] elems...)\n{\n    return 3;\n}\n///\nunittest\n{\n    auto rbt1 = redBlackTree(0, 1, 5, 7);\n    auto rbt2 = redBlackTree!string(\"hello\", \"world\");\n    auto rbt3 = redBlackTree!true(0, 1, 5, 7, 5);\n    auto rbt4 = redBlackTree!\"a > b\"(0, 1, 5, 7);\n}\n\n// ------------------------------------\n// https://issues.dlang.org/show_bug.cgi?id=9758\n\n/// test\nvoid foo(){}\n\n///\nunittest {  }\n\n// ------------------------------------\n// https://issues.dlang.org/show_bug.cgi?id=10519\n\n///\nbool balancedParens10519(string, char, char) { return true; }\n///\nunittest\n{\n    auto s = \"1 + (2 * (3 + 1 / 2)\";\n    assert(!balancedParens10519(s, '(', ')'));\n}\n\n// ------------------------------------\n// https://issues.dlang.org/show_bug.cgi?id=12097\n\n/// declaration\nstruct S12097\n{\n    /// method\n    void foo() {}\n}\n\n/// ditto\nvoid f12097() {}\n\n/// ddoc code 1\nunittest\n{\n    int a = 1;\n}\n\n/// ditto\nstruct T12097(T) {}\n\n/// ddoc code 2\nunittest\n{\n    int[] arr;\n}\n\n// ------------------------------------\n// https://issues.dlang.org/show_bug.cgi?id=14594\n\n/*******************\n * testA\n */\nvoid fun14594a()() {}\n///\nunittest { fun14594a(); }\n\n/*******************\n * testB\n */\nvoid fun14594b()() {}\n/// ditto\nvoid fun14594b(T)(T) {}\n///\nunittest { fun14594b(); fun14594b(1); }\n\n/*******************\n * testC\n */\nvoid fun14594c()() {}\n///\nunittest { fun14594c(); fun14594c(1); }\n/// ditto\nvoid fun14594c(T)(T) {}\n\n/*******************\n * testD\n */\nvoid fun14594d()() {}\n///\nunittest { fun14594d(); }\n/// ditto\nvoid fun14594d(T)(T) {}\n///\nunittest { fun14594d(1); }\n\n/*******************\n * testE\n */\ntemplate fun14594e()\n{\n    /// concatenated doc-comment fun14594e\n    void fun14594e() {}\n    /// ignored-unittest fun14594e\n    unittest { fun14594e(); }\n}\n/// doc-unittest fun14594e\nunittest { fun14594e(); }\n\n/*******************\n * testF\n */\ntemplate fun14594f()\n{\n    /// concatenated doc-comment fun14594f\n    void fun14594f() {}\n    /// ignored-unittest fun14594f\n    unittest { fun14594f(); }\n}\n/// ditto\ntemplate fun14594f(T)\n{\n    /// ignored doc-comment fun14594f\n    void fun14594f(T) {}\n    /// ignored-unittest fun14594f\n    unittest { fun14594f(1); }\n}\n/// doc-unittest fun14594f\nunittest { fun14594f(); }\n\n// ------------------------------------\n\nvoid main() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/debuginfo.d",
    "content": "// REQUIRED_ARGS: -g\n\nstruct Bug7127a {\n    const(Bug7127a)* self;\n}\n\nstruct Bug7127b {\n    void function(const(Bug7127b) self) foo;\n}\n\nvoid main() {\n    Bug7127a a;\n    Bug7127b b;\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=13975\nstatic immutable int a = 8;\nenum Bar { aa = a }\n\nvoid foo(Bar bar) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/defa.d",
    "content": "// PERMUTE_ARGS:\n\nmodule defa;\n\nprivate import imports.defaa;\n\t\npublic abstract class A\n{\n\tDisplay d;\n\tint style;\n\n\tthis() {}\n\n\tpublic this(A parent, int style)\n\t{\n\t\tthis.style = style;\n\t\td = parent.d;\n\t}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/depmsg.d",
    "content": "// REQUIRED_ARGS: -d\n// PERMUTE_ARGS: -dw\n\nvoid main()\n{\n    class Inner\n    {\n        deprecated(\"With message!\")\n        {\n            struct A { }\n            class B { }\n            interface C { }\n            union D { }\n            enum E { e };\n            //typedef int F;\n            alias int G;\n            static int H;\n            template I() { class I {} }\n        }\n    }\n    with(Inner)\n    {\n        A a;\n        B b;\n        C c;\n        D d;\n        E e;\n        //F f;\n        G g;\n        auto h = H;\n        I!() i;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/deprecate12979a.d",
    "content": "// REQUIRED_ARGS: -dw\n// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\ncompilable/deprecate12979a.d(13): Deprecation: `asm` statement is assumed to throw - mark it with `nothrow` if it does not\n---\n*/\n\nvoid foo() nothrow\n{\n    version(GNU)\n    {\n        asm\n        {\n            \"\";\n        }\n    }\n    else\n    {\n        asm\n        {\n            ret;\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/deprecate14283.d",
    "content": "// REQUIRED_ARGS: -dw\n// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\n---\n*/\n\nclass C\n{\n    void bug()\n    {\n        autoref(this);  // 'auto ref' becomes non-ref parameter\n        autoref(super); // 'auto ref' becomes non-ref parameter\n    }\n}\n\nvoid autoref(T)(auto ref T t) { static assert(__traits(isRef, t) == false); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/depsOutput9948.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -deps=${RESULTS_DIR}/compilable/depsOutput9948.deps\n// POST_SCRIPT: compilable/extra-files/depsOutput.sh \n// EXTRA_SOURCES: /extra-files/depsOutput9948a.d\n\nmodule depsOutput9948;\nimport depsOutput9948a;\n\nvoid main()\n{\n   templateFunc!(\"import std.string;\")();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/derivedarray.d",
    "content": "// PERMUTE_ARGS:\n\nclass C {}\nclass D : C {}\n\nvoid dynamicarrays()\n{\n    C[] a;\n    D[] b;\n    const(C)[] c;\n    const(D)[] d;\n    immutable(C)[] e;\n    immutable(D)[] f;\n\n    static assert( __traits(compiles, a = a));\n    static assert(!__traits(compiles, a = b));\n    static assert(!__traits(compiles, a = c));\n    static assert(!__traits(compiles, a = d));\n    static assert(!__traits(compiles, a = e));\n    static assert(!__traits(compiles, a = f));\n\n    static assert(!__traits(compiles, b = a));\n    static assert( __traits(compiles, b = b));\n    static assert(!__traits(compiles, b = c));\n    static assert(!__traits(compiles, b = d));\n    static assert(!__traits(compiles, b = e));\n    static assert(!__traits(compiles, b = f));\n\n    static assert( __traits(compiles, c = a));\n    static assert( __traits(compiles, c = b));\n    static assert( __traits(compiles, c = c));\n    static assert( __traits(compiles, c = d));\n    static assert( __traits(compiles, c = e));\n    static assert( __traits(compiles, c = f));\n\n    static assert(!__traits(compiles, d = a));\n    static assert( __traits(compiles, d = b));\n    static assert(!__traits(compiles, d = c));\n    static assert( __traits(compiles, d = d));\n    static assert(!__traits(compiles, d = e));\n    static assert( __traits(compiles, d = f));\n\n    static assert(!__traits(compiles, e = a));\n    static assert(!__traits(compiles, e = b));\n    static assert(!__traits(compiles, e = c));\n    static assert(!__traits(compiles, e = d));\n    static assert( __traits(compiles, e = e));\n    static assert( __traits(compiles, e = f));\n\n    static assert(!__traits(compiles, f = a));\n    static assert(!__traits(compiles, f = b));\n    static assert(!__traits(compiles, f = c));\n    static assert(!__traits(compiles, f = d));\n    static assert(!__traits(compiles, f = e));\n    static assert( __traits(compiles, f = f));\n}\n\n\nvoid statictodynamicarrays()\n{\n    C[] a;\n    D[] b;\n    const(C)[] c;\n    const(D)[] d;\n    immutable(C)[] e;\n    immutable(D)[] f;\n\n    C[1] sa;\n    D[1] sb;\n    const(C)[1] sc = void;\n    const(D)[1] sd = void;\n    immutable(C)[1] se = void;\n    immutable(D)[1] sf = void;\n\n    static assert( __traits(compiles, a = sa));\n    static assert(!__traits(compiles, a = sb));\n    static assert(!__traits(compiles, a = sc));\n    static assert(!__traits(compiles, a = sd));\n    static assert(!__traits(compiles, a = se));\n    static assert(!__traits(compiles, a = sf));\n\n    static assert(!__traits(compiles, b = sa));\n    static assert( __traits(compiles, b = sb));\n    static assert(!__traits(compiles, b = sc));\n    static assert(!__traits(compiles, b = sd));\n    static assert(!__traits(compiles, b = se));\n    static assert(!__traits(compiles, b = sf));\n\n    static assert( __traits(compiles, c = sa));\n    static assert( __traits(compiles, c = sb));\n    static assert( __traits(compiles, c = sc));\n    static assert( __traits(compiles, c = sd));\n    static assert( __traits(compiles, c = se));\n    static assert( __traits(compiles, c = sf));\n\n    static assert(!__traits(compiles, d = sa));\n    static assert( __traits(compiles, d = sb));\n    static assert(!__traits(compiles, d = sc));\n    static assert( __traits(compiles, d = sd));\n    static assert(!__traits(compiles, d = se));\n    static assert( __traits(compiles, d = sf));\n\n    static assert(!__traits(compiles, e = sa));\n    static assert(!__traits(compiles, e = sb));\n    static assert(!__traits(compiles, e = sc));\n    static assert(!__traits(compiles, e = sd));\n    static assert( __traits(compiles, e = se));\n    static assert( __traits(compiles, e = sf));\n\n    static assert(!__traits(compiles, f = sa));\n    static assert(!__traits(compiles, f = sb));\n    static assert(!__traits(compiles, f = sc));\n    static assert(!__traits(compiles, f = sd));\n    static assert(!__traits(compiles, f = se));\n    static assert( __traits(compiles, f = sf));\n}\n\nvoid staticarrays()\n{\n    C[1] sa;\n    D[1] sb;\n\n    const(C)[1] sc = sa;\n    const(D)[1] sd = sb;\n\n    sa = sb;\n    static assert(!__traits(compiles, sb = sa));\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/diag11066.d",
    "content": "// REQUIRED_ARGS: -w -profile\n/*\nTEST_OUTPUT:\n---\n---\n*/\n\nvoid main()\n{\n    string s;\n    foreach (dchar c; s) // affected by dchar\n        return;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/diag3243.d",
    "content": "// REQUIRED_ARGS: -vtls\n// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\n---\n*/\n\ntemplate T()\n{\n    static this() {}\n}\n\nclass C\n{\n    alias ti = T!();\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/dip22.d",
    "content": "// REQUIRED_ARGS: -de\nimport imports.dip22;\n\nclass Foo : Base1, Base2\n{\n    void test()\n    {\n        static assert(typeof(bar()).sizeof == 2);\n        static assert(baz == 2);\n        static assert(T.sizeof == 2);\n    }\n}\n\nvoid test()\n{\n    bar(12);\n    baz(12);\n    12.bar();\n    12.baz();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/disable_new.d",
    "content": "class C\n{\n    // force user of a type to use an external allocation strategy\n    @disable new();\n}\n\nstruct S\n{\n    // force user of a type to use an external allocation strategy\n    @disable new();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/empty_file.d",
    "content": ""
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/exception.d",
    "content": "class E2 : Exception { this() { super(null); } }\nclass E3 : Exception { this() { super(null); } }\n\nvoid main()\n{\n    try\n    {\n    }\n    catch (E3)\n    {\n    }\n    catch (E2)\n    {\n    }\n    catch (Exception)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/c6395.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=6395\n\ntemplate map(alias fun) {\n  auto map(Range)(Range r) {\n    struct Result\n    {\n      @property auto ref front()\n      {\n        return fun(\"a\");\n      }\n    }\n    return Result();\n  }\n}\n\nRange find(alias pred, Range)(Range haystack) {\n  pred(haystack.front);\n  return haystack;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/ddoc10367.ddoc",
    "content": "DDOC_ENUM_BASETYPE = $(RED $0)\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/ddoc198.ddoc",
    "content": "DDOC_PSYMBOL = <a name=\"$0\"></a><span style=\"color:OrangeRed\" class=\"ddoc_psymbol\">$0</span>\nDDOC_PSUPER_SYMBOL = <a name=\"$0\"></a><span style=\"color:blue\" class=\"ddoc_psuper_symbol\">$0</span>\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/ddoc3.ddoc",
    "content": "HELLO = world\n\nUNUSED=unused"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/ddoc9369.ddoc",
    "content": "ESCAPES = /&/AddressOf!/\n          /!/Exclamation/\n          /?/QuestionMark/\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/ddoc9497a.ddoc",
    "content": "DDOC_UNDEFINED_MACRO=<!-- $(DOLLAR)($1 $+) -->"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/ddoc9497b.ddoc",
    "content": "DDOC_UNDEFINED_MACRO=$(DOLLAR)($1 $+)\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/ddoc9497c.ddoc",
    "content": "DDOC_UNDEFINED_MACRO=$+\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/ddoc9497d.ddoc",
    "content": "DDOC_UNDEFINED_MACRO=ERROR_UNDEFINED_MACRO: \"$1\"\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/ddoc9676a.ddoc",
    "content": "DEPRECATED = <del>$0</del>\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/ddoc9764.dd",
    "content": "Ddoc\n\nCheck ddoc9764 document.\n----\n// Check ddoc9764 comment.\nddoc9764();\n----\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/depsOutput9948a.d",
    "content": "module depsOutput9948a;\n\nvoid templateFunc(string myImport)()\n{\n   mixin(myImport);\n}"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/e6815.d",
    "content": "bool e(T)(T)\n{\n    f(true);\n    return true;\n}\n\nvoid f(lazy bool) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/emptymain.d",
    "content": "void main() { }"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/example7190/controllers/HomeController.d",
    "content": "module example7190.controllers.HomeController;\n\nimport serenity7190.core.Controller;\n\nclass HomeController : Controller {\n    mixin register!(HomeController);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/example7190/models/HomeModel.d",
    "content": "module example7190.models.HomeModel;\n\nimport serenity7190.core.Model;\n\nstruct Article {\n    ulong id;\n}\n\nclass HomeModel : Model {\n    private SqlitePersister!Article mArticles;\n}"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/header1.d",
    "content": "// REQUIRED_ARGS: -ignore\nmodule foo.bar;\n\nimport core.vararg;\nimport std.stdio;\n\npragma(lib, \"test\");\npragma(msg, \"Hello World\");\npragma(linkerDirective, \"/DEFAULTLIB:test2\");\n\nstatic assert(true, \"message\");\n\nalias double mydbl;\n\nalias fl1 = function ()\n    in {}\n    in (true)\n    out (; true)\n    out (r; true)\n    out\n    {\n    }\n    out (r)\n    {\n    }\n    do\n    {\n        return 2;\n    };\n\nalias fl2 = function ()\n    in (true)\n    out(; true)\n    out(r; true)\n    {\n        return 2;\n    };\n\nint testmain()\nin\n{\n    assert(1+(2+3) == -(1 - 2*3));\n}\nout (result)\n{\n    assert(result == 0);\n}\nbody\n{\n    float f = float.infinity;\n    int i = cast(int) f;\n    writeln(i,1,2);\n    writeln(cast(int)float.max);\n    assert(i == cast(int)float.max);\n    assert(i == 0x80000000);\n    return 0;\n}\n\nstruct S { int m, n; }\n\ntemplate Foo(T, int V)\n{\n    void foo(...)\n    {\n        static if (is(Object _ : X!TL, alias X, TL...)) {}  // https://issues.dlang.org/show_bug.cgi?id=10044\n\n        auto x = __traits(hasMember, Object, \"noMember\");\n        auto y = is(Object : X!TL, alias X, TL...);\n        assert(!x && !y, \"message\");\n\n        S s = { 1,2 };\n        auto a = [1, 2, 3];\n        auto aa = [1:1, 2:2, 3:3];\n\n        int n,m;\n    }\n\n    int bar(double d, int x)\n    {\n    if (d)\n    {   d++;\n    }\n    else\n        d--;\n\n    asm\n    {   naked ;\n        mov EAX, 3;\n    }\n\n    for (;;)\n    {\n        d = d + 1;\n    }\n\n    for (int i = 0; i < 10; i++)\n    {\n        d = i ? d + 1 : 5;\n    }\n\n    char[] s;\n    foreach (char c; s)\n    {\n        d *= 2;\n        if (d)\n        break;\n        else\n        continue;\n    }\n\n    switch (V)\n    {\n        case 1:\n        case 2: break;\n        case 3: goto case 1;\n        case 4: goto default;\n        default:\n        d /= 8;\n        break;\n    }\n\n        enum Label { A, B, C }\n        void fswitch(Label l)\n        {\n            final switch (l)\n            {\n            case A: break;\n            case B: break;\n            case C: break;\n            }\n        }\n\n    loop:\n    while (x)\n    {\n        x--;\n        if (x)\n        break loop;\n        else\n        continue loop;\n    }\n\n    do\n    {\n        x++;\n    } while (x < 10);\n\n    try\n    {\n        bar(1, 2);\n    }\n    catch (Object o)\n    {\n        x++;\n    }\n    finally\n    {\n        x--;\n    }\n\n    try\n        bar(1, 2);\n    catch(Object o)\n        x++;\n    finally\n        x--;\n\n    Object o;\n    synchronized (o)\n    {\n        x = ~x;\n    }\n\n    synchronized\n    {\n        x = x < 3;\n    }\n\n    with (o)\n    {\n        toString();\n    }\n    }\n}\n\nstatic this()\n{\n}\n\nstatic ~this()\n{\n}\n\npure nothrow @safe @nogc static  this() {}\npure nothrow @safe @nogc static ~this() {}\nstatic  this() pure nothrow @safe @nogc {}\nstatic ~this() pure nothrow @safe @nogc {}\n\npure nothrow @safe @nogc shared static  this() {}\npure nothrow @safe @nogc shared static ~this() {}\nshared static  this() pure nothrow @safe @nogc {}\nshared static ~this() pure nothrow @safe @nogc {}\n\ninterface iFoo{}\nclass xFoo: iFoo{}\n\ninterface iFoo2{}\nclass xFoo2: iFoo, iFoo2{}\n\nclass Foo3\n{\n    this(int a, ...){}\n    this(int* a){}\n}\n\nalias int myint;\n\nstatic notquit = 1;\n\nclass Test\n{\n    void a() {}\n    void b() {}\n    void c() {}\n    void d() {}\n    void e() {}\n    void f() {}\n    void g() {}\n    void h() {}\n    void i() {}\n    void j() {}\n    void k() {}\n    void l() {}\n    void m() {}\n    void n() {}\n    void o() {}\n    void p() {}\n    void q() {}\n    void r() {}\n    void s() {}\n    void t() {}\n    void u() {}\n    void v() {}\n    void w() {}\n    void x() {}\n    void y() {}\n    void z() {}\n\n    void aa() {}\n    void bb() {}\n    void cc() {}\n    void dd() {}\n    void ee() {} // Try adding or removing some functions here to see the effect.\n\n    template A(T) { }\n\n    alias A!(uint) getHUint;\n    alias A!(int) getHInt;\n    alias A!(float) getHFloat;\n    alias A!(ulong) getHUlong;\n    alias A!(long) getHLong;\n    alias A!(double) getHDouble;\n    alias A!(byte) getHByte;\n    alias A!(ubyte) getHUbyte;\n    alias A!(short) getHShort;\n    alias A!(ushort) getHUShort;\n    alias A!(real) getHReal;\n\n    alias void F();\n\n    pure nothrow @safe @nogc unittest {}\n    pure nothrow @safe @nogc invariant {}\n    pure nothrow @safe @nogc invariant (true);\n\n    pure nothrow @safe @nogc new (size_t sz) { return null; }\n    pure nothrow @safe @nogc delete (void* p) { }\n}\n\ntemplate templ( T )\n{\n    void templ( T val )\n    {\n        pragma( msg, \"Invalid destination type.\" );\n    }\n}\n\nstatic char[] charArray = [ '\\\"', '\\'' ];\n\nclass Point\n{\n    auto x = 10;\n    uint y = 20;\n}\n\ntemplate Foo2(bool bar)\n{\n    void test()\n    {\n    static if(bar)\n    {\n        int i;\n    }\n    else\n    {\n    }\n    static if(!bar)\n    {\n    }\n    else\n    {\n    }\n    }\n}\n\n\ntemplate Foo4()\n{\n        void bar()\n        {\n        }\n}\n\ntemplate Foo4x( T... ) {}\n\nclass Baz4\n{\n        mixin Foo4 foo;\n        mixin Foo4x!(int, \"str\") foox;\n\n        alias foo.bar baz;\n}\n\nint test(T)(T t)\n{\n        if (auto o = cast(Object)t) return 1;\n        return 0;\n}\n\nenum x6 = 1;\n\nbool foo6(int a, int b, int c, int d)\n{\n    return (a < b) != (c < d);\n}\n\nauto foo7(int x)\n{\n        return 5;\n}\n\nclass D8{}\nvoid func8()\n{\n  scope a= new D8();\n}\n\nT func9(T)() if (true)\n{\n    T i;\n    scope(exit) i= 1;\n    scope(success) i = 2;\n    scope(failure) i = 3;\n    return i;\n}\n\ntemplate V10(T)\n{\n    void func()\n    {\n        for(int i,j=4; i<3;i++)\n        {\n        }\n    }\n}\n\nint foo11(int function() fn)\n{\n    return fn();\n}\n\nint bar11(T)()\n{\n    return foo11(function int (){ return 0; });\n}\n\n\nstruct S6360\n{\n    @property long weeks1() const pure nothrow { return 0; }\n\n    @property const pure nothrow long weeks2() { return 0; }\n}\n\n\nstruct S12\n{\n    /// postfix storage class and constructor\n    this(int n) nothrow{}\n\n    /// prefix storage class (==StorageClassDeclaration) and constructor\n    nothrow this(string s){}\n}\n\n/// dummy\nstruct T12\n{\n    /// postfix storage class and template constructor\n    this()(int args) immutable { }\n\n    /// prefix storage class (==StorageClassDeclaration) and template constructor\n    immutable this(A...)(A args){ }\n}\n\n\n// https://issues.dlang.org/show_bug.cgi?id=6591\nimport std.stdio : writeln, F = File;\n\nvoid foo6591()()\n{\n    import std.stdio : writeln, F = File;\n}\n\n\n// https://issues.dlang.org/show_bug.cgi?id=8081\nversion(unittest) {\n    pure nothrow unittest {}\n    pure nothrow unittest {}\n\n    public unittest {}\n    extern(C) unittest {}\n    align unittest {}\n}\n\n\n// https://issues.dlang.org/show_bug.cgi?id=10334\n\ntemplate Foo10334(T) if (Bar10334!()) {}                ///\ntemplate Foo10334(T) if (Bar10334!100) {}               ///\ntemplate Foo10334(T) if (Bar10334!3.14) {}              ///\ntemplate Foo10334(T) if (Bar10334!\"str\") {}             ///\ntemplate Foo10334(T) if (Bar10334!1.4i) {}              ///\ntemplate Foo10334(T) if (Bar10334!null) {}              ///\ntemplate Foo10334(T) if (Bar10334!true) {}              ///\ntemplate Foo10334(T) if (Bar10334!false) {}             ///\ntemplate Foo10334(T) if (Bar10334!'A') {}               ///\ntemplate Foo10334(T) if (Bar10334!int) {}               ///\ntemplate Foo10334(T) if (Bar10334!string) {}            ///\ntemplate Foo10334(T) if (Bar10334!wstring) {}           ///\ntemplate Foo10334(T) if (Bar10334!dstring) {}           ///\ntemplate Foo10334(T) if (Bar10334!this) {}              ///\ntemplate Foo10334(T) if (Bar10334!([1,2,3])) {}         ///\ntemplate Foo10334(T) if (Bar10334!(Baz10334!())) {}     ///\ntemplate Foo10334(T) if (Bar10334!(Baz10334!T)) {}      ///\ntemplate Foo10334(T) if (Bar10334!(Baz10334!100)) {}    ///\ntemplate Foo10334(T) if (Bar10334!(.foo)) {}            ///\ntemplate Foo10334(T) if (Bar10334!(const int)) {}       ///\ntemplate Foo10334(T) if (Bar10334!(shared T)) {}        ///\n\ntemplate Test10334(T...) {}     ///\nmixin Test10334!int a;          ///\nmixin Test10334!(int,long) b;   ///\nmixin Test10334!\"str\" c;        ///\n\n// https://issues.dlang.org/show_bug.cgi?id=12266\nauto clamp12266a(T1, T2, T3)(T1 x, T2 min_val, T3 max_val)\n{\n    return 0;\n}\npure clamp12266b(T1, T2, T3)(T1 x, T2 min_val, T3 max_val)\n{\n    return 0;\n}\n@disable pure clamp12266c(T1, T2, T3)(T1 x, T2 min_val, T3 max_val)\n{\n    return 0;\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=13832\nalias Dg13832 = ref int delegate();\n\n// https://issues.dlang.org/show_bug.cgi?id=16590\nclass TestClass {\n    int aa;\n    int b1, b2;\n    this(int b1, int b2)\n    {\n        this.b1 = b1;\n        this.b2 = b2;\n    }\n\n    ref foo() {\n        return aa;\n    }\n\n    ref retFunc() return {\n        return aa;\n    }\n\n    ~this() @trusted @disable @nogc {\n    }\n}\n\nclass FooA {\n    protected void method42() {\n\n    }\n\n    ~this() @safe {\n    }\n\n}\n\n\nclass Bar : FooA {\n    override void method42() {\n\n   }\n}\n\ndouble foo() @trusted {\n    int a = 5;\n    return a;\n}\n\nstruct Foo1(size_t Size = 42 / magic()) {\n\n}\n\n\nsize_t magic() {\n    return 42;\n}\n\nclass Foo2A {\n\n    immutable(FooA) Dummy = new immutable(FooA);\n    private immutable pure nothrow @nogc @safe this() {\n\n    }\n\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=15676\nstruct Foo3A(T)\n{\n    @disable this(this);\n    @disable this();\n}\n\n// return ref, return scope, return ref scope\nref int foo(return ref int a) @safe\n{\n    return a;\n}\n\nint* foo(return scope int* a) @safe\n{\n    return a;\n}\n\nref int* foo(scope return ref int* a) @safe\n{\n    return a;\n}\n\nstruct SafeS\n{\n@safe:\n    ref SafeS foo() return\n    {\n        return this;\n    }\n\n    SafeS foo2() return scope\n    {\n        return this;\n    }\n\n    ref SafeS foo3() return scope\n    {\n        return this;\n    }\n\n    int* p;\n}\n\nvoid test13x(@(10) int a, @(20) int, @(30) @(40) int[] arr...) {}\n\nenum Test14UDA1;\nstruct Test14UDA2\n{\n    string str;\n}\n\nTest14UDA2 test14uda3(string name)\n{\n    return Test14UDA2(name);\n}\nstruct Test14UDA4(string v){}\n\nvoid test14x(@Test14UDA1 int, @Test14UDA2(\"1\") int, @test14uda3(\"2\") int, @Test14UDA4!\"3\" int) {}\n\nvoid test15x(@(20) void delegate(int) @safe dg){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/header18365.d",
    "content": "module foo.bar.ba;\nnothrow pure @nogc @safe package(foo) \n{\n\tvoid foo();\n\tnothrow pure @nogc @safe package(foo.bar) void foo2();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/header2.d",
    "content": "// for D 2.0 only\n\nclass C { }\n\nvoid foo(const C c, const(char)[] s, const int* q, const (int*) p)\n{\n}\n\nvoid bar(in void *p)\n{\n}\n\nvoid f(void function() f2);\n\nclass C2;\nvoid foo2(const C2 c);\n\nstruct Foo3\n{\n   int k;\n   ~this() @trusted @disable @nogc { k = 1; }\n   this(this) { k = 2; }\n}\n\n\nclass C3 { @property int get() { return 0; } }\n\nT foo3(T)() {}\n\nstruct S4A(T)\n{\n   T x;\n   ~this() @safe {}\n}\n\nstruct S4B(T) if (1)\n{\n   T x;\n}\n\nunion U4A(T)\n{\n    T x;\n}\n\nunion U4B(T) if (2*4 == 8)\n{\n   T x;\n}\n\nclass C4A(T)\n{\n  T x;\n}\n\nclass C4B(T) if (true) { T x; }\n\nclass C4C(T) : C4A!int if (!false)\n{\n  T x;\n}\n\nclass C4D(T) if (!false) : C4B!long, C4C!(int[])\n{\n    T x;\n}\n\ninterface I4(T) if ((int[1]).length == 1) { T x; }\n\n// eponymous template case\ntemplate MyClass4(T)\n    if (is(typeof(T.subtype)))\n{\n    alias HelperSymbol = T.subtype;\n    class MyClass4 {}\n}\n\nenum isInt(T) = is(T == int);\nenum bool isString(T) = is(T == string);\nstatic immutable typeName(T) = T.stringof;\nint storageFor(T) = 0;\n\ntemplate templateVariableFoo(T)\n{\n    enum int templateVariableFoo = T.stringof.length;\n}\ntemplate templateVariableBar(T) if (is(T == int))\n{\n    enum int templateVariableBar = T.stringof.length;\n}\n\nauto flit = 3 / 2.0;\n\n// https://issues.dlang.org/show_bug.cgi?id=11217\nvoid foo11217()(    const int[] arr) {}\nvoid foo11217()(immutable int[] arr) {}\nvoid foo11217()(      ref int[] arr) {}\nvoid foo11217()(     lazy int[] arr) {}\nvoid foo11217()( auto ref int[] arr) {}\nvoid foo11217()(    scope int[] arr) {}\nvoid foo11217()(       in int[] arr) {}\nvoid foo11217()(    inout int[] arr) {}\n\n// https://issues.dlang.org/show_bug.cgi?id=13275\nvoid test13275()\n{\n    if (        auto n = 1) {}\n    if (       const n = 1) {}\n    if (   immutable n = 1) {}\n    if (shared       n = 1) {}\n    if (shared const n = 1) {}\n\n    if (             int  n = 1) {}\n\n    if (       const int  n = 1) {}\n    if (   immutable int  n = 1) {}\n    if (shared       int  n = 1) {}\n    if (shared const int  n = 1) {}\n\n    if (       const(int) n = 1) {}\n    if (   immutable(int) n = 1) {}\n    if (shared      (int) n = 1) {}\n    if (shared const(int) n = 1) {}\n\n    foreach (             e; [1,2]) {}\n    foreach (       const e; [1,2]) {}\n    foreach (   immutable e; [1,2]) {}\n    foreach (shared       e; [1,2]) {}\n    foreach (shared const e; [1,2]) {}\n\n    foreach (             int e; [1,2]) {}\n    foreach (       const int e; [1,2]) {}\n    foreach (   immutable int e; [1,2]) {}\n    foreach (shared       int e; [1,2]) {}\n    foreach (shared const int e; [1,2]) {}\n\n    foreach (             int e; [1,2]) {}\n    foreach (       const(int) e; [1,2]) {}\n    foreach (   immutable(int) e; [1,2]) {}\n    foreach (shared      (int) e; [1,2]) {}\n    foreach (shared const(int) e; [1,2]) {}\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=9766\nalign (1) struct S9766\n{\nalign (true ? 2 : 3):\n    int var1;\n\nalign:\n    int var2;\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=16649\nvoid leFoo()()\n{\n    sign = a == 2 ? false : (y < 0) ^ sign;\n    sign = a == 2 ? false : sign ^ (y < 0);\n    sign = 2 + 3 | 7 + 5;\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17371\ninterface LeInterface\n{}\nclass LeClass\n{\n    this()\n    {\n        auto foo = new class () LeInterface {};\n    }\n}\nconst levar = new class LeClass, LeInterface {};\n\n// https://issues.dlang.org/show_bug.cgi?id=17663\nprivate:\npublic struct Export {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/header3.d",
    "content": "auto elseifchain()\n{\n    bool a,b,c;\n\n    if (a)\n    {\n    }\n    else if (b)\n    {\n    }\n    else if (c)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/imp12624.d",
    "content": "// typecons.d\ntemplate RebindableCommon(T, U, This)\n{\n        union { U stripped; }\n\n        void opAssign(T another)\n        {\n                stripped = cast() another;\n        }\n\n        this(T initializer)\n        {\n                opAssign(initializer);\n        }\n}\n\n\ntemplate Rebindable(T)\n{\n    static if (is(T == immutable U, U))\n        struct Rebindable\n        {\n                mixin RebindableCommon!(T, U, Rebindable);\n        }\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/imp9057.d",
    "content": "struct BugInt\n{\n    uint[] data = ZEROX;  \n}\nenum uint [] ZEROX = [0];\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/imp9057_2.d",
    "content": "struct BugInt\n{\n    uint[] data = [0];\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/minimal/object.d",
    "content": "module object;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37/datetime/common.d",
    "content": "module pkgDIP37.datetime.common;\n\nvoid def();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37/datetime/package.d",
    "content": "module pkgDIP37.datetime;\npublic import pkgDIP37.datetime.common;\n//alias std.datetime.common.def def;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37/test17629/common.di",
    "content": "module pkgDIP37.test17629.common;\n\nvoid foo17629();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37/test17629/package.di",
    "content": "module pkgDIP37.test17629;\npublic import pkgDIP37.test17629.common;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37_10302/liba.d",
    "content": "module pkgDIP37_10302.liba;\nvoid foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37_10302/libb.d",
    "content": "module pkgDIP37_10302.libb;\nimport pkgDIP37_10302.liba;\nvoid bar()\n{\n    foo();\n\n    // should be error, but unfortunately this works by bug 314 now.\n    //lib.foo();\n\n    pkgDIP37_10302.liba.foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37_10302/package.d",
    "content": "module pkgDIP37_10302;\npublic import pkgDIP37_10302.liba;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37_10354/mbar.d",
    "content": "module pkgDIP37_10354.mbar;\nvoid bar(T)() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37_10354/mfoo.d",
    "content": "module pkgDIP37_10354.mfoo;\nvoid foo(T)() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37_10354/package.d",
    "content": "module pkgDIP37_10354;\npublic import pkgDIP37_10354.mfoo;\npublic import pkgDIP37_10354.mbar;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37_10421/algo/mod.d",
    "content": "module pkgDIP37_10421.algo.mod;\nimport pkgDIP37_10421.algo;     // foo\nimport pkgDIP37_10421.except;   // baz\nvoid test()\n{\n    foo();  // should be accessible\n    baz();  // should be accessible\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37_10421/algo/package.d",
    "content": "module pkgDIP37_10421.algo;\npublic import pkgDIP37_10421.algo.mod;\npackage\n{\n    void foo() {}\n    void bar() { foo(); }   // should be accessible\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/pkgDIP37_10421/except.d",
    "content": "module pkgDIP37_10421.except;\n\npackage void baz() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/serenity7190/core/Controller.d",
    "content": "class Controller {\n    mixin template register(T : Controller) {\n        enum _s_pkg = __traits(parent, __traits(parent, __traits(parent, T))).stringof[\"package \".length .. $];\n\n        enum _s_model = T.stringof[0 .. $-`Controller`.length] ~ `Model`;\n        mixin(q{enum _ = is(} ~ _s_pkg ~ q{.models.} ~ _s_model ~ q{.} ~ _s_model ~ q{ : serenity7190.core.Model.Model);});\n    }\n}"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/serenity7190/core/Model.d",
    "content": "class SqlitePersister(T) {\n    static assert(T.tupleof.length > 0, T.stringof ~ `(` ~ (T.tupleof.length + '0') ~ `): ` ~ T.tupleof.stringof);\n}\n\nclass Model {}"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/test14894a.d",
    "content": "module imports.test14894a;\n\nmixin template Protocol()\n{\n    void onReceive() {}\n}\n\nstruct Foo\n{\n    mixin Protocol!();\n\n    unittest\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/test14894main.d",
    "content": "import test14894a;\n\nvoid main()\n{\n    Foo foo;\n    foo.onReceive();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/test16080b.d",
    "content": "import imp16080;\n\nvoid test2() {\n\tA!() v = A!().a;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/test6461/a.d",
    "content": "module a;\nimport tmpl;\nTypeInfo fun() { return typeid(Tmpl!int()); }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/test6461/b.d",
    "content": "module b;\nimport tmpl;\nTypeInfo fun() { return typeid(Tmpl!long()); }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/test6461/main.d",
    "content": "import a, b;\nvoid main() {\n  auto t1 = a.fun();\n  auto t2 = b.fun();\n  assert(t1 != t2);\n}"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/test6461/tmpl.d",
    "content": "module tmpl;\nstruct Tmpl(T) {\n  T a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/test9680dllmain.d",
    "content": "import core.sys.windows.windows;\nextern (Windows)\nBOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)\n{\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/test9680main.d",
    "content": "void main() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/extra-files/test9680winmain.d",
    "content": "import core.sys.windows.windows;\nextern(Windows)\nint WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)\n{\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/fail260.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -d\n\nstruct Static(uint width2, uint height2)\n{\n    immutable width = width2;\n    immutable height = height2;\n\n    static Static opCall()\n    {\n        Static ret;\n        return ret;\n    }\n\n    alias float E;\n\n    template MultReturn(alias M1, alias M2)\n    {\n        alias Static!(M2.width, M1.height) MultReturn;\n    }\n\n    void opMultVectors(M2)(M2 b)\n    {\n        alias MultReturn!(Static, M2) ret_matrix;\n    }\n}\n\nvoid test()\n{\n    alias Static!(4, 1) matrix_stat;\n    static matrix_stat m4 = matrix_stat();\n\n    alias Static!(1, 4) matrix_stat2;\n    static m6 = matrix_stat2();\n\n    m6.opMultVectors(m4);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/filefullpath_18911.d",
    "content": "// REQUIRED_ARGS: -Icompilable/imports -c -o-\n// EXTRA_FILES: imports/a18911.d\n\nimport a18911;\n\nenum THIS_FILE = __FILE_FULL_PATH__;\nenum suffix_this = \"filefullpath_18911.d\";\n\nstatic assert(THIS_FILE[0..$-suffix_this.length-1] == A_FILE[0..$-suffix_a.length-1]);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/fix17123.d",
    "content": "/*\nPERMUTE_ARGS:\n\nhttps://issues.dlang.org/show_bug.cgi?id=17123\n */\n\nvoid test()\n{\n    char[256] buffer;\n\n    char[] delegate() read = () {\n        return buffer[];\n    };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/fix17335.d",
    "content": "/*\n * PERMUTE_ARGS:\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=17335\n\nbool alwaysFalse() { return false; }\nvoid main()\n{\n\tstatic if (false && a == 1)\n\t{\n\t}\n\tstatic if (\"a\" == \"b\" && b == 1)\n\t{\n\t}\n\tstatic if (alwaysFalse() && c == 1)\n\t{\n\t}\n\tstatic if (!alwaysFalse() || d == 1)\n\t{\n\t}\n\tstatic if (alwaysFalse() ? e == 1 : 1)\n\t{\n\t}\n\tstatic if (!alwaysFalse() ? 1 : f == 1)\n\t{\n\t}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/fix17349.d",
    "content": "/* REQUIRED_ARGS: -dw\n * PERMUTE_ARGS:\n * TEST_OUTPUT:\n---\ncompilable/fix17349.d(37): Deprecation: cannot implicitly override base class method `fix17349.E.foo` with `fix17349.F.foo`; add `override` attribute\n---\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=17349\n\nstruct S { }\n\nclass C {\n    void bar();\n    void foo(void* p);\n    void abc(Object);\n    void def(S);\n}\n\nclass D : C {\n    override void bar() const;\n    override void foo(const void*);\n    override void abc(const Object);\n    override void def(const S);\n}\n\nalias fp_t = void function(int*);\n@safe void abc(const int*);\nfp_t fp = &abc;\n\n\nclass E {\n    void foo(void*);\n}\n\nclass F : E {\n    void foo(const void*);\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/fix17686.d",
    "content": "/* REQUIRED_ARGS:\n * PERMUTE_ARGS:\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=17686\n\ninterface INode\n{\n    @property INode parentNode();\n    @property IDocument ownerDocument();\n}\ninterface IDocument: INode {}\ninterface IEntityReference: INode {}\n\nclass DOMImplementation(T)\n{\n    abstract class Node: INode\n    {\n        override\n        {\n            @property Node parentNode() { return null; }\n            @property Document ownerDocument() { return null; }\n        }\n\n        @property bool readonly() { return true; }\n    }\n    abstract class NodeWithChildren: Node {}\n\n    class Document: NodeWithChildren, IDocument {}\n\n    class EntityReference: NodeWithChildren, IEntityReference\n    {\n        override\n        {\n            @property bool readonly() { return true; }\n        }\n    }\n\n}\n\nvoid main()\n{\n\talias aaa = DOMImplementation!string;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/forward1.d",
    "content": "// REQUIRED_ARGS: -g\n\n// https://issues.dlang.org/show_bug.cgi?id=104\n// fails only with -g\n\nFoofunc f;\nalias int Foo;\nalias int function(Foo) Foofunc;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/future.d",
    "content": "/* PERMUTE_ARGS:\n * TEST_OUTPUT:\n---\ncompilable/future.d(15): Deprecation: `@__future` base class method `future.A.msg` is being overridden by `future.B.msg`; rename the latter\n---\n */\n\nclass A\n{\n    @__future char msg() { return 'a'; }\n}\n\nclass B : A\n{\n    char msg() { return 'b'; }\n}\n\nclass C : B\n{\n    override char msg() { return 'c'; }\n}\n\nclass D : A\n{\n    override char msg() { return 'd'; }\n}\n\nint main()\n{\n    auto a = new A();\n    assert(a.msg() == 'a');\n    auto b = new B();\n    assert(b.msg() == 'b');\n    auto c = new C();\n    assert(c.msg() == 'c');\n    auto d = new D();\n    assert(d.msg() == 'd');\n\n    assert(b.A.msg() == 'a');\n\n    auto ba = cast(A)b;\n    assert(ba.msg() == 'a');\n\n    auto da = cast(A)d;\n    assert(da.msg() == 'd');\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/futurexf.d",
    "content": "/* PERMUTE_ARGS:\n   REQUIRED_ARGS: -Xf${RESULTS_DIR}/compilable/futurexf.json\n */\n\nclass A\n{\n    @__future char msg();\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/header18364.d",
    "content": "// REQUIRED_ARGS: -o- -Hf${RESULTS_DIR}/compilable/header18364.di\n// POST_SCRIPT: compilable/extra-files/header-postscript.sh\nmodule foo.bar.ba;\n@safe pure nothrow @nogc package(foo):\nvoid foo();\n\n@safe pure nothrow @nogc package(foo.bar):\nvoid foo2();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/header18365.d",
    "content": "// REQUIRED_ARGS: -c -o- -Hf${RESULTS_DIR}/compilable/header18365.di\n// POST_SCRIPT: compilable/extra-files/header-postscript.sh\nstruct FullCaseEntry\n{\n    dchar[3] seq;\n    ubyte n, size;\n    ubyte entry_len;\n\n    @property auto value() const @trusted pure nothrow @nogc return\n    {\n        return seq[0 .. entry_len];\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/iasm_labeloperand.d",
    "content": "\nversion (D_InlineAsm_X86)\n    version = TestInlineAsm;\nelse version (D_InlineAsm_X86_64)\n    version = TestInlineAsm;\nelse version (GNU)\n    version = TestInlineAsm;\nelse\n    pragma(msg, \"Inline asm not supported, not testing.\");\n\nversion (TestInlineAsm)\n{\n    void testInlineAsm()\n    {\n        version (GNU)\n        {\n        L1:\n            asm { \"\" : : : : L1; } // Check back references\n            asm { \"\" : : : : L2; } // Check forward references\n        L2:\n            asm { \"\"; }\n        }\n        else\n        {\n            asm\n            {\n\t\tL1:\n\t\t\tnop;\n\t\t\tnop;\n\t\t\tnop;\n\t\t\tnop;\n\t\t\t\n\t\t\tmov EAX, dword ptr L1; // Check back references\n\t\t\tmov EAX, dword ptr L2; // Check forward references\n\t\t\tmov EAX, dword ptr DS:L1; // Not really useful in standard use, but who knows.\n\t\t\tmov EAX, dword ptr FS:L2; // Once again, not really useful, but it is valid.\n\t\t\tmov EAX, dword ptr CS:L1; // This is what the first test case should implicitly be.\n\t\t\t\n\t\tL2:\n\t\t\tnop;\n\t\t\tnop;\n\t\t\tnop;\n\t\t\tnop;\n\t\t\t\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice10040.d",
    "content": "struct MsgProc1 { mixin MsgMixin; }\nstruct MsgProc2 { mixin MsgMixin; }\n\nstruct MsgHeader {}\n\ntemplate MsgMixin()\n{\n    mixin(mixinMembers!(MsgHeader.init));\n}\n\nstring mixinMembers(T ...)()\n{\n    struct Op {}\n    return null;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice10431a.d",
    "content": "mixin ADT!();\n\nstruct Tuple(TL...) { TL expand; }\n\ntemplate Seq(T...) { alias T Seq; }\n\ntemplate ADT()\n{\n    mixin(q{\n        struct ListI\n        {\n            private\n            {\n                size_t tag;\n                union { Seq!(Tuple!()*, Tuple!(int,ListI,)*,) data; }\n            }\n        }\n    });\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice10431b.d",
    "content": "struct X(alias Y)\n{\n}\n\nstruct A\n{\n    int[] data;\n}\n\nalias X!(A([])) X1;\nalias X!(A([])) X2;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice10486.d",
    "content": "void main()\n{\n    typeof(null) null_;\n    int[1] sarr = null_;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice10598.d",
    "content": "// EXTRA_SOURCES: imports/ice10598a.d imports/ice10598b.d\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice11054.d",
    "content": "import imports.ice11054a;\n\nstatic assert(!__traits(compiles, tuple()));\n\nE[] appender(A : E, E)()\n{\n    return E;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice11300.d",
    "content": "// PERMUTE_ARGS:\n\nmodule ice11300;\nimport imports.ice11300a;\nenum value = 42;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice11596.d",
    "content": "// PERMUTE_ARGS: -inline -release -g -O -version=X\n\nversion(X)\n    alias M = real;\nelse\n    alias M = int[2]; /* or other T[n] with n != 1 */\n\nstruct S { M m; }\n\nS f() { assert(false); }\n\nclass C\n{\n    S[1] ss; /* Here, size doesn't matter. */\n\n    this() { ss[] = f(); }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice11610.d",
    "content": "\nstruct Token\n{\n    TokenType type;\n}\n\nenum TokenType : ushort\n{\n    invalid\n}\n\nclass Parser\n{\n    bool peekIsOneOf(TokenType[] types...)\n    {\n        canFind(types, tokens[1].type);\n        return true;\n    }\n\n    Token[] tokens;\n}\n\n/*************************************************/\n// std.algorithm\n\nR find(alias pred = \"a == b\", R, E)(R haystack, E needle)\n{\n    enum isIntegralNeedle = isSomeChar!E/* || isIntegral!E || isBoolean!E*/;\n\n    return haystack;\n}\n\nbool canFind(alias pred = \"a == b\", R, E)(R haystack, E needle)\nif (is(typeof(find!pred(haystack, needle))))        // 1st instantiate of find template with error gagging\n{\n    return find!pred(haystack, needle).length != 0; // 2nd instantiate of find template without gagging\n}\n\n/*************************************************/\n// std.traits\n\ntemplate CharTypeOf(T)\n{\n           inout( char) idx(        inout( char) );\n           inout(wchar) idx(        inout(wchar) );\n           inout(dchar) idx(        inout(dchar) );\n    shared(inout  char) idx( shared(inout  char) );\n    shared(inout wchar) idx( shared(inout wchar) );\n    shared(inout dchar) idx( shared(inout dchar) );\n\n    static if (is(T == enum))\n    {\n        /* This line instantiates CharTypeOf!short and will make error.\n         * But, when CharTypeOf!short is re-instantiated without gagging,\n         * that's for correct error report, its 'members' does not re-created.\n         * so, members' semantic will call FuncDeclaration::overloadInsert of\n         * 'idx' functions, and will make circular linked list of\n         * FuncDeclaration::overnext. Finally, iterating it will cause\n         * infinite recursion and compiler segfault.\n         */\n        alias .CharTypeOf!(OriginalType!T) CharTypeOf;\n    }\n    else static if (is(typeof(idx(T.init)) X))\n    {\n        alias X CharTypeOf;\n    }\n    else\n        static assert(0, T.stringof~\" is not a character type\");\n}\n\ntemplate isSomeChar(T)\n{\n    enum isSomeChar = is(CharTypeOf!T);\n}\n\ntemplate OriginalType(T)\n{\n    alias OriginalType = ushort;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice11777.d",
    "content": "void f(void delegate(int)) {}\n\nclass C\n{\n    int i;\n    this()\n    {\n        f((a){});\n        /* (a){} is a template lambda, so FuncExp::semantic -> TemplateDeclaration::semantic\n         * will save the scope in TemplateDeclaration::scope with fieldinit. Later push/pop\n         * of the scope for template lambda body semantics will violate the assertion in Scope::pop().\n         */\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice11906.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nnothrow /*extern(Windows) */export int GetModuleHandleA(const char* lpModuleName);\n\nvoid main()\n{\n    /*extern(Windows) */int function(const char*) f;\n    assert(f != &GetModuleHandleA);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice11925.d",
    "content": "void test11925a()\n{\n    try\n    {\n        try\n        {\n            L1: {}\n        }\n        finally\n        {\n        }\n    }\n    finally\n    {\n    }\n    goto L1;\n}\n\nvoid test11925b()\n{\n    switch (1)\n    {\n        case 1:\n            goto L1;\n            break;\n\n        default:\n            break;\n    }\n\n    try\n    {\n        L1: { }\n    }\n    finally\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice12002.d",
    "content": "// REQUIRED_ARGS: -inline\n// PERMUTE_ARGS:\n\nvoid doFormat(void delegate(dchar) putc, TypeInfo[] arguments)\n{\n    void formatArg(char fc)\n    {\n        const(char)* prefix = \"\";\n\n        void putstr(const char[] s)\n        {\n            //if (flags & FL0pad)\n            {\n                while (*prefix)\n                    putc(*prefix++);\n            }\n\n            foreach (dchar c; s)\n                putc(c);\n        }\n\n        putstr(null);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice12554.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nvoid main() pure\n{\n    int[] foo;\n\n    // if indirectly instantiated aggregate is struct (== MapResultS)\n    foo.map!(MapResultS, x => foo.map!(MapResultS, y => x).array);\n\n    // if indirectly instantiated aggregate is class (== MapResultC)\n    foo.map!(MapResultC, x => foo.map!(MapResultC, y => x).array);\n}\n\nT array(T)(T a)\n{\n    static int g; g = 1;    // impure operation\n    return a;\n}\n\ntemplate map(alias MapResult, fun...)\n{\n    auto map(Range)(Range r)\n    {\n        alias AppliedReturnType(alias f) = typeof(f(r[0]));\n        static assert(!is(AppliedReturnType!fun == void));\n\n        return MapResult!(fun).init;\n    }\n}\n\nstruct MapResultS(alias fun)\n{\n    @property front()\n    {\n        return fun(1);\n    }\n}\n\nclass MapResultC(alias fun)\n{\n    @property front()\n    {\n        return fun(1);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice12956.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\ntemplate isCallable(T...)\n{\n    static if (is(typeof(& T[0].opCall) == delegate))\n    {\n        enum bool isCallable = true;\n    }\n    else static if (is(typeof(& T[0].opCall) V : V*) && is(V == function))\n    {\n        enum bool isCallable = true;\n    }\n    else\n        enum bool isCallable = false;\n}\n\n@property auto injectChain(Injectors...)()\n{\n    return &ChainTemplates!(Injectors);\n}\n\ntemplate ChainTemplates(Templates...)\n{\n    alias Head = Templates[0];\n    alias Tail = Templates[1..$];\n    alias Head!(Tail) ChainTemplates;\n}\n\nstatic assert(!isCallable!(injectChain));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice13071.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nT foo(T)()\n{\n    __gshared int[] bar = [];\n    return T.init;\n}\n\nvoid main()\n{\n    foo!char();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice13088.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nstruct X\n{\n    void mfoo(this T)() {}\n}\nvoid test()\n{\n    shared const X scx;\n\n    scx.mfoo();\n}\n\nstruct Vec\n{\n    int x;\n    void sc() shared const {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice13245.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\ntemplate T(alias f) {}\nstatic assert(!is(T!( (int x){ return invalid; } )));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice13323.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nstruct UDA {}\n\nstruct S\n{\n  @UDA:\n    import object;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice13403.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -o-\nimport imports.ice13403a;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice13792.d",
    "content": "enum E;\n\nvoid main()\n{\n    E* p;  // ICE in glue layer\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice13874.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\ntemplate FunctionTypeOf(func...)\n    if (func.length == 1)\n{\n    static if (is(typeof(& func[0]) Fsym : Fsym*) && is(Fsym == function) || is(typeof(& func[0]) Fsym == delegate))\n    {\n        alias Fsym FunctionTypeOf;\n    }\n    else static if (is(typeof(& func[0].opCall) Fobj == delegate))\n    {\n        alias Fobj FunctionTypeOf;\n    }\n    else\n        static assert(0);\n}\n\nenum DummyEnum;\nstatic assert(!is(FunctionTypeOf!DummyEnum));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice13886.d",
    "content": "// REQUIRED__ARGS:\n// PERMUTE_ARGS:\n\nstruct Y()\n{\n    this() {}\n    ~this() { this = null; }\n    ref opAssign(S)(S) { }\n}\n\nvoid main()\n{\n    static if (is(typeof({ Y!(); }))) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice13920.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nclass Foo\n{\n    void foo()\n    {\n        foreach (f; __traits(getOverloads, typeof(this), \"bar\"))\n        {\n            auto dg = &f;\n        }\n\n        foreach (f; __traits(getVirtualMethods, typeof(this), \"bar\"))\n        {\n            auto dg = &f;\n        }\n\n        foreach (f; __traits(getVirtualFunctions, typeof(this), \"bar\"))\n        {\n            auto dg = &f;\n        }\n    }\n\n    uint bar() { return 0; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice13968.d",
    "content": "// REQUIRED_ARGS:\n// PERMUTE_ARGS:\n\nunion U\n{\n    bool a;\n    long b;\n}\n\nU test1()\n{\n    return U();\n}\n\nU* test2()\n{\n    return new U();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice14075.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nstruct Foo\n{\n    auto opAssign(this X)(ref typeof(this));\n    auto opAssign(this X, V)(ref V) if (!is(V == typeof(this)));\n}\n\nvoid test()\n{\n    Foo src;\n    const(Foo) target;\n    static if (is(typeof(target = src))) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice14739.d",
    "content": "// REQUIRED_ARGS: -o-\n\nvoid main(string[] args)\n{\n    immutable int a;\n    immutable int b;\n    S!a sa;\n    S!b sb;\n    C!a ca;\n    C!b cb;\n}\n\nstruct S(alias a)\n{\n}\n\nclass C(alias a)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice1524.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=1524\n// ICE(constfold.c) on using \"is\" with strings in CTFE\n\n/* 1524 PATCH Assertion failure: '0' on line 863 in file 'constfold.c'\nconstfold.c\n@@ -845,9 +845,9 @@\n     Loc loc = e1->loc;\n     int cmp;\n\n-    if (e1->op == TOKnull && e2->op == TOKnull)\n+    if (e1->op == TOKnull || e2->op == TOKnull)\n     {\n-        cmp = 1;\n+        cmp = (e1->op == TOKnull && e2->op == TOKnull) ? 1 : 0;\n     }\n     else if (e1->op == TOKsymoff && e2->op == TOKsymoff)\n     {\n*/\nbool isNull(string str)\n{\n    return str is null;\n}\nconst bool test = isNull(\"hello!\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice15333.d",
    "content": "// EXTRA_SOURCES: imports/a15333.d\n\nmodule ice15333;\n\nvoid map(alias fun)() {}\n\nstruct IdentifierResolver(alias handler)\n{\n    void resolve()\n    {\n        map!((a) {});\n        handler(true);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice15760.d",
    "content": "// PERMUTE_ARGS:\n// EXTRA_SOURCES: imports/a15760.d\n\nmodule ice15760;\n\nimport imports.a15760 : Foo;\n\nstruct Bar\n{\n    __gshared Foo foo;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice15789.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nstruct InputRange {}\n\nauto md5OfA(T...)(T ) {}\nauto md5OfB(T...)(T ) {}\n\ntemplate fqnSymA(alias T : X!A, alias X, A...)\n{\n    template fqnTuple(B) { enum fqnTuple = 1; }\n    enum fqnSymA = fqnTuple!A;\n}\ntemplate fqnSymB(alias T : X!A, alias X, A...)\n{\n    template fqnTuple(B) { enum fqnTuple = 1; }\n    enum fqnSymB = fqnTuple!A;\n}\n\nvoid test1()    // OK <- NG\n{\n    md5OfA(InputRange());\n    auto n = fqnSymA!(md5OfA!InputRange);\n}\n\nvoid test2()    // OK\n{\n    auto n = fqnSymB!(md5OfB!InputRange);\n    md5OfB(InputRange());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice15992.d",
    "content": "// PERMUTE_ARGS:\n\nstruct Appender()\n{\n    bool canExtend = false;\n}\n\nstruct CustomFloat()\n{\n    union ToBinary\n    {\n        CustomFloat!() get;\n    }\n\n    void opAssign(F)(F input)\n        if (__traits(compiles, cast(real)input))\n    {\n    }\n\n    real get()()\n    {\n        Appender!() app;\n        assert(false);\n    }\n\n    T opCast(T)() { return get!(); }\n\n    alias g = get!();\n}\n\nvoid f()\n{\n    alias FPTypes = CustomFloat!();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice6538.d",
    "content": "\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6538\n\ntemplate allSatisfy(alias F, T...) { enum bool allSatisfy = true; }\ntemplate isIntegral(T) { enum bool isIntegral = true; }\n\nvoid foo(I...)(I sizes)\nif (allSatisfy!(isIntegral, sizes)) {}\n\nvoid test6538a()\n{\n    foo(42, 86);\n}\n\nvoid bar(T1, T2)(T1 t1, T2 t2)\nif (allSatisfy!(isIntegral, t1, t2)) {}\n\nvoid test6538b()\n{\n    bar(42, 86);\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9361\n\ntemplate Sym(alias A)\n{\n    enum Sym = true;\n}\n\nstruct S\n{\n    void foo()() if (Sym!(this)) {}\n    void bar()() { static assert(Sym!(this)); }   // OK\n}\nvoid test9361a()\n{\n    S s;\n    s.foo();    // fail\n    s.bar();    // OK\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice8392.d",
    "content": "// EXTRA_SOURCES: imports/a8392.d\n\nmodule ice8392;\n\nstruct A\n{\n}\n\nauto fooa(alias handler)(A a)\n{\n    return handler(null);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice854.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=854\n// TypeTuple in anonymous delegate causes ice in glue.c\n\n/* 854 VOTE PATCH (=2863, =2251?) Assertion failure: '0' on line 935 in file 'glue.c'\nI haven't checked this patch myself.\n--- dmd/func.c  2009-03-05 01:56:46.000000000 +0100\n+++ dmd-fixed/func.c        2009-03-30 00:39:41.000000000 +0200\n@@ -756,6 +756,27 @@\n             }\n         }\n\n+        if (f->parameters)\n+        {\n+            for (size_t i = 0; i < Argument::dim(f->parameters); i++)\n+            {\n+                Argument *arg = (Argument *)Argument::getNth(f->parameters, i);\n+                Type* nw = arg->type->semantic(0, sc);\n+                if (arg->type != nw) {\n+                    arg->type = nw;\n+                    // Examine this index again.\n+                    // This is important if it turned into a tuple.\n+                    // In particular, the empty tuple should be handled or the\n+                    // next parameter will be skipped.\n+                    // FIXME: Maybe we only need to do this for tuples,\n+                    //        and can add tuple.length after decrement?\n+                    i--;\n+                }\n+            }\n+            // update nparams to include expanded tuples\n+            nparams = Argument::dim(f->parameters);\n+        }\n+\n         // Propagate storage class from tuple parameters to their element-parameters.\n         if (f->parameters)\n         {\n*/\ntemplate Foo(T...)\n{\n    alias T Foo;\n}\nvoid main()\n{\n    auto y = (Foo!(int) x){ return 0; };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/ice9663.d",
    "content": "// REQUIRED_ARGS: -wi\n\nvoid main()\n{\n    int[1] a;\n    int[] b = [1];\n\n    a = 1;\n\n    b[] = a;\n\n    b = a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a12506.d",
    "content": "module imports.a12506;\n\nauto f12506(alias fun)() { return fun(1); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a12511.d",
    "content": "module a12511;\n\npublic class A\n{\n    private static void foo() {}\n    public static void foo(int) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a12567.d",
    "content": "deprecated(\"This module will be removed in future release.\")\nmodule imports.a12567;\n\nvoid foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a13226.d",
    "content": "module imports.a13226;\n\nenum isFunction(alias f) = is(typeof(f) == function);\nenum isIntField(alias f) = is(typeof(f) == int);\n\nstring t(alias cls, string method)()\n{\n    static if (isFunction!(mixin(\"cls.\"~method)))\n    {}\n    return \"\";\n}\n\nstring u(alias cls, string member)()\n{\n    static if (isIntField!(mixin(\"cls.\"~member)))\n    {}\n    return \"\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a14528.d",
    "content": "module imports.a14528;\n\nvoid foo(alias f)()\n{\n    f();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a15333.d",
    "content": "module imports.a15333;\n\nimport ice15333;\n\nstruct StatementVisitor\n{\n    void visit()\n    {\n        int location;\n        alias IR = IdentifierResolver!((e){ location = 0; });\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a15760.d",
    "content": "module imports.a15760;\n\nimport ice15760;\n\nstruct Foo\n{\n    Bar a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a15856.d",
    "content": "module imports.a15856;\n\nalias int c_long;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a18911.d",
    "content": "enum A_FILE = __FILE_FULL_PATH__;\nenum suffix_a = \"imports/a18911.d\";\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a313.d",
    "content": "module imports.a313;\n\n// adds private package imports\nprivate import imports.b313;\n// adds private package core\nprivate import core.stdc.stdio;\n// adds public alias cstdio\npublic alias cstdio = core.stdc.stdio;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a313templatemixin1.d",
    "content": "void bug()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a313templatemixin2.d",
    "content": "void bug()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a314.d",
    "content": "module imports.pkg.a314; // sub package\n\npackage(imports) static import imports.c314;\npackage(imports) import renamed = imports.c314;\npackage(imports) import imports.c314 : bug;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/a8392.d",
    "content": "module imports.a8392;\n\nimport ice8392;\n\nclass B\n{\n    this(B);\n}\n\nvoid foob(A a, B b)\n{\n    a.fooa!((arg){\n            return new B(b);\n    });\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/art4769a.d",
    "content": "module imports.art4769a;\n\nimport core.stdc.stdio;\n\ntemplate DataStreamability(T)\n{\n     const int isStreamable = true;\n     alias T footype;\n\n     void write()\n     {\n       printf(\"hallo\\n\");\n     }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/art4769b.d",
    "content": "private import imports.art4769a;\nprivate import art4769;\n\nint main(char [][] args)\n{\n   Vector!(wchar) str;\n   return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/b313.d",
    "content": "module imports.b313;\n\nvoid bug()\n{\n    // scope has access to it's own module\n    imports.b313.bug();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/b33a.d",
    "content": "module imports.b33a;\n\nstruct IsEqual( T )\n{\n    bool opCall( char p1, char p2 )\n    {\n\treturn p1 == p2;\n    }\n}    \n\ntemplate find_( Elem, Pred = IsEqual!(Elem) )\n{    \n    size_t fn( char[] buf, Pred pred = Pred.init )\n    {\n        return 3;\n    }\n}\n\ntemplate find()\n{\n    size_t find( char[3] buf )\n    {\n        return find_!(char).fn( buf );\n    }\n}\n\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/b3682.d",
    "content": "module imports.b3682;\n\nimport a3682;\nalias Tuple!(int) tint;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/bug8922.d",
    "content": "module imports.bug8922;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/c314.d",
    "content": "module imports.c314;\n\nvoid bug(string s)\n{}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/checkimports3a.d",
    "content": "void foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/checkimports3b.d",
    "content": "private void foo(int) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/checkimports3c.d",
    "content": "void foo(string) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/defaa.d",
    "content": "\nmodule imports.defaa;\n\nclass Display\n{\n\n\tprivate import imports.defab;\n\n\tB lastHittestB;\n\n\tthis() { }\n}\n\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/defab.d",
    "content": "\nmodule imports.defab;\n\nprivate import defa;\n\npublic class B : A\n{\n\n\tprivate import imports.defad;\n\n\tD parent;\n\n\tthis() {}\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/defac.d",
    "content": "\nmodule imports.defac;\n\nprivate import imports.defab;\n\npublic abstract class C : B\n{\n\tprivate import imports.defad;\n\n\tthis() {}\n\n\tthis(D parent, int style) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/defad.d",
    "content": "\nmodule imports.defad;\n\nprivate import imports.defac;\nprivate import imports.defab;\n\npublic class D : C\n{\n\tB [] tabList;\n\n\tthis() {}\n\n\tthis(D parent, int style){ }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/dip22.d",
    "content": "module imports.dip22;\n\ninterface Base1\n{\n    private ubyte bar() { return 1; }\n    private enum baz = 1;\n    private alias T = byte;\n}\n\ninterface Base2\n{\n    final short bar() { return 2; }\n    enum baz = 2;\n    alias T = short;\n}\n\nprivate void bar() {}\nvoid bar(int) {}\n\nvoid baz(int) {}\nprivate void baz() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/f313.d",
    "content": " // different module declaration not used for access check\nmodule foo.bar;\n\nvoid bug()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/fwdref12201a.d",
    "content": "alias int FILE;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/fwdref2_test17548.d",
    "content": "module fwdref2_test17548;\n\nimport test17548;\n\nstruct S2 {\n    void bar(int arg = .test17548.cnst) {}\n    S1 s;\n    import fwdref2_test17548;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/fwdref9514.d",
    "content": "bool find9514(alias pred, R)(R range)\n{\n    return true;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/g313.d",
    "content": "module imports.g313;\n\n// adds public package imports (see https://issues.dlang.org/show_bug.cgi?id=15900)\npublic import imports.g313public;\n// same w/ deferred semantics\nstatic if (true)\n    public import imports.g313staticif;\nmixin(\"public import imports.g313stringmixin;\");\n\ntemplate impD()\n{\n    public import imports.g313templatemixin;\n}\n\nmixin impD!();\n\nvoid test15900()\n{\n    // publically imported modules should obviously be available in here as well\n    imports.g313public.bug();\n    imports.g313staticif.bug();\n    imports.g313stringmixin.bug();\n    imports.g313templatemixin.bug();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/g313public.d",
    "content": "void bug()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/g313staticif.d",
    "content": "void bug()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/g313stringmixin.d",
    "content": "void bug()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/g313templatemixin.d",
    "content": "void bug()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/ice10598a.d",
    "content": "module imports.ice10598a;\n\ntemplate TypeTuple(TL...) { alias TL TypeTuple; }\n\nalias TypeTuple!(__traits(getMember, imports.ice10598b, (__traits(allMembers, imports.ice10598b)[1])))[0] notImportedType;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/ice10598b.d",
    "content": "module imports.ice10598b;\n\nstruct LocalType {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/ice11054a.d",
    "content": "template Tuple()\n{\n    string injectNamedFields()\n    {\n        formatNthX();\n        return \"\";\n    }\n}\nTuple!T tuple(T...)()\n{\n}\n\nvoid formatNthX(A...)(A)\n{\n    static gencode(size_t count)()\n    {\n        result ~= \"\";   // comment out this line will remove the ICE\n        return \"\";\n    }\n    mixin(gencode!(A.length)());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/ice11300a.d",
    "content": "module imports.ice11300a;\nstatic import ice11300;\nenum value = ice11300.value;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/ice13403a.d",
    "content": "module imports.ice13403a;\n\npackage(imports):\n\ntemplate BacktrackingMatcher()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp12242a.d",
    "content": "module imports.imp12242a;\n\npublic:\nimport imports.imp12242a1;  // std.string\nimport imports.imp12242a2;  // std.algorithm\n\n\nprivate mixin template MixTmp(T, int x)\n{\n    template foo(U) if (is(U == T))\n    {\n        enum foo = x;\n    }\n}\n\nmixin MixTmp!(int,  1);\nmixin MixTmp!(long, 2);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp12242a1.d",
    "content": "module imports.imp12242a1;\n\n// std.string.strip\nint stripA(C)(C[] str) @safe pure\n    if (is(immutable C == immutable char))\n{\n    return 1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp12242a2.d",
    "content": "module imports.imp12242a2;\n\n// std.algorithm.strip\nauto stripA(R, E)(R range, E element)\n{\n    return 2;\n}\nauto stripA(alias pred, R)(R range)\n{\n    return 3;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp12242b.d",
    "content": "module imports.imp12242b;\n\npublic:\nimport imports.imp12242b1;  // std.string\nimport imports.imp12242b2;  // std.algorithm\n\n\nprivate mixin template MixTmp(T, int x)\n{\n    template foo(U) if (is(U == T))\n    {\n        enum foo = x;\n    }\n}\n\nmixin MixTmp!(float, 3);\nmixin MixTmp!(real,  4);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp12242b1.d",
    "content": "module imports.imp12242b1;\n\n// std.string.strip\nint stripB(C)(C[] str) @safe pure\n    if (is(immutable C == immutable char))\n{\n    return 1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp12242b2.d",
    "content": "module imports.imp12242b2;\n\n// std.algorithm.strip\nauto stripB(R, E)(R range, E element)\n{\n    return 2;\n}\nauto stripB(alias pred, R)(R range)\n{\n    return 3;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp15490a.d",
    "content": "module imports.imp15490a;\n\nimport imports.imp15490b;\n\nvoid listenTCP()\n{\n    enum r = regex();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp15490b.d",
    "content": "module imports.imp15490b;\n\nint regex()\n{\n    return regexImpl();\n}\n\nauto regexImpl()\n{\n    int r = 0;\n    return r;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp15907.d",
    "content": "module imports.imp15907;\n\nvoid process(T)(T t)\n{\n    foreach (member; __traits(allMembers, T))\n    {\n        static if (__traits(getProtection, __traits(getMember, t, member)) != \"private\")\n        {\n        }\n    }\n}\n\nenum allMembers(T) = [__traits(allMembers, T)];\n\nstruct PublicStruct\n{\n    private struct S {}\n}\n\nprivate:\n\nstruct PrivateStruct {}\nint privateVar;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp15925.d",
    "content": "enum X = 1;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp16080.d",
    "content": "struct A() {\n\tstatic immutable A a;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp16085.d",
    "content": "struct Pass\n{\n}\n\nstruct S\n{\n    import imports.imp16085b : functionAndFunction, staticFunctionAndFunction,\n        functionAndTemplate, templateAndTemplate; //<- private\n    // public\n    Pass functionAndFunction()\n    {\n        return Pass();\n    }\n\n    static Pass staticFunctionAndFunction()\n    {\n        return Pass();\n    }\n\n    Pass functionAndTemplate()\n    {\n        return Pass();\n    }\n\n    Pass templateAndTemplate()()\n    {\n        return Pass();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp16085b.d",
    "content": "import imp16085 : S;\n\nstruct Fail\n{\n}\n\nFail functionAndFunction(ref S)\n{\n    return Fail();\n}\n\nFail staticFunctionAndFunction(int)\n{\n    return Fail();\n}\n\nFail functionAndTemplate(T)(T)\n{\n    return Fail();\n}\n\nFail templateAndTemplate(T)(T)\n{\n    return Fail();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp16088.d",
    "content": "module imports.imp16088;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp16460.d",
    "content": "module imports.imp16460;\n\npackage enum val = 0;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/imp16798.d",
    "content": "\nmodule its.a.dessert.topping;\n\npragma(msg, \"it's a dessert topping\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/jsonimport1.d",
    "content": "module imports.jsonimport1;\n\nint target1, target2;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/jsonimport2.d",
    "content": "module imports.jsonimport2;\n\nint target1, target2;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/jsonimport3.d",
    "content": "module imports.jsonimport3;\n\nint target1, target2, target3;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/jsonimport4.d",
    "content": "module imports.jsonimport4;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/pkg313/c313.d",
    "content": "module imports.pkg313.c313;\n\nvoid bug()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/pkgmod313/mod.d",
    "content": "module imports.pkgmod313.mod;\n\nvoid bar() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/pkgmod313/package.d",
    "content": "module imports.pkgmod313;\n\npublic import imports.pkgmod313.mod;\n\nvoid foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/protectionimp.d",
    "content": "private\n{\n    void privF() {}\n    class privC {}\n    struct privS {}\n    union privU {}\n    interface privI {}\n    enum privE { foo }\n    mixin template privMT() {}\n\n    void privTF(T)() {}\n    class privTC(T) {}\n    struct privTS(T) {}\n    union privTU(T) {}\n    interface privTI(T) {}\n}\n\nvoid publF(T)() {}\nvoid publFA(alias A)() {}\nprivate alias privC privA;\n\npublic mixin template publMT() {}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14169\n\ntemplate GetName14169(TemplateParam)\n{\n    enum GetName14169 = TemplateParam.Name;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/stdio4003.d",
    "content": "module imports.stdio4003;\n\nimport imports.typecons4003;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test10375a.d",
    "content": "module imports.test10375a;\n\nprivate template Pack(T...)\n{\n    alias T tuple;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test10752.d",
    "content": "module imports.test10752;\nprivate int priv;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test11225b.d",
    "content": "module imports.test11225b;\nimport test11225a;\n\ninterface J : I {} // remove this line to make it work\n\nstatic assert(is(typeof({ import imports.test11225c; }))); // OK\npragma(msg, B!().result); // just instantiates the template\n\ntemplate B()\n{\n    static assert(is(typeof({ import imports.test11225c; }))); // FAILS\n    enum result = \"WORKS\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test11225c.d",
    "content": "module imports.test11225c;\n// empty\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test11563core_bitop.d",
    "content": "module test11563core_bitop;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test11563std_array.d",
    "content": "module imports.test11563std_array;\n\nvoid popFront(S)(ref S str)// @trusted pure nothrow\n{\n    import imports.test11563core_bitop;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test11563std_range.d",
    "content": "module imports.test11563std_range;\n\npublic import imports.test11563std_array;\n\ntemplate isInputRange(R)\n{\n    enum bool isInputRange = is(typeof(\n    {\n        R r = void;\n        r.popFront();\n    }));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test11563std_traits.d",
    "content": "module imports.test11563std_traits;\n\nimport imports.test11563std_range;\n\nbool startsWith(R1, R2)(R1 doesThisStart, R2 withThis)\nif (isInputRange!R1)\n{\n    return true;\n}\n\ntemplate moduleName(alias T)\n{\n    static if (T.stringof.startsWith(\"module \"))\n    {\n        enum moduleName = \"b\";\n    }\n    else\n    {\n        pragma(msg, \"--error--\");\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test1238a.d",
    "content": "module imports.test1238a;\n\nprivate int zuiop;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test1238b.d",
    "content": "module imports.test1238b;\n\npublic int zuiop;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test13242a.d",
    "content": "module imports.test13242a;\n\ntemplate expensiveArgs(alias v)\n{\n    pragma(msg, \"a.expensiveArgs: \", v);\n}\n\ntemplate expensiveTemplate(Args...)\n{\n    pragma(msg, \"a.expensiveTemplate: \", Args[0]);\n}\n\nalias apiSym1 = expensiveTemplate!(1, expensiveArgs!(1));\n\nalias apiSym2 = expensiveTemplate!(2, expensiveArgs!(2));\n\npublic import imports.test13242b : apiSym3;\n\nvoid cheapFunc() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test13242b.d",
    "content": "module imports.test13242b;\n\ntemplate expensiveArgs(alias v)\n{\n    pragma(msg, \"b.expensiveArgs: \", v);\n}\n\ntemplate expensiveTemplate(Args...)\n{\n    pragma(msg, \"b.expensiveTemplate: \", Args[0]);\n}\n\nalias apiSym3 = expensiveTemplate!(3, expensiveArgs!(3));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test14666a.d",
    "content": "module imports.test14666a;\n\nauto getNames()\n{\n    import imports.test14666b;\n    return \"\";\n}\n\nenum Names = getNames;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test14666b.d",
    "content": "module imports.test14666b;\n\nimport test14666;\n\nstruct Token\n{\n    Location location;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test15117a.d",
    "content": "module imports.test15117a;\n\nstruct AssertResult {}\n\nauto test_usr_1()\n{\n    // 2. generate TyepInfoStructDeclaration\n    auto x = typeid(AssertResult);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test15150a.d",
    "content": "module imports.test15150a;\n\nenum\n{\n    x\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test15150b.d",
    "content": "module imports.test15150b;\n\nimport imports.test15150a : x;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test15785.d",
    "content": "module imports.test15785;\n\ninterface IBase2\n{\n    final protected void faz() {}\n}\n\nclass Base\n{\n    protected void foo() {}\n    protected void bar() {}\n    protected alias T = int;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test15857a.d",
    "content": "public import imports.test15857b;\npublic import imports.test15857c;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test15857b.d",
    "content": "void bar15857(int) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test15857c.d",
    "content": "void bar15857(string) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test16348.d",
    "content": "module mypackage.bar;\n\npackage bool bar()\n{\n    return false;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test17541_2.d",
    "content": "module two;\n\nimport one;\n\nstruct ET(bool a)\n{\n    enum e = BB.MAX_NUM_FIBERS;\n}\n\nalias Event = ET!false;\n\nstruct TWOR(size_t M)\n{\n    Event e;\n\n    void open()\n    {\n        bb.foo();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test17541_3.d",
    "content": "module three;\n\nvoid aaa() @nogc\n{\n\n}\n\nstruct TT(T)\n{\n    void insertabcdefg(T) // @nogc  <-- deduction problem\n    {\n        pragma(msg, insertabcdefg.mangleof);\n        aaa();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test1754a.d",
    "content": "module imports.test1754a;\n\nprivate void bar()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test1754b.d",
    "content": "module imports.test1754b;\n\nvoid bar()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test17991a/a.d",
    "content": ""
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test17991a/package.d",
    "content": ""
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test18771a.d",
    "content": "module imports.test18771a;\n\nvoid foo(int) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test18771b.d",
    "content": "module imports.test18771b;\n\nvoid foo(string) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test18771c.d",
    "content": "module imports.test18771c;\n\nimport imports.test18771a, imports.test18771b;\nalias fooC = foo;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test18771d.d",
    "content": "module imports.test18771d;\n\nimport imports.test18771b, imports.test18771a;\nalias fooD = foo;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test19107a.d",
    "content": "module imports.test19107a.d;\n\nalias I(alias A) = A;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test19107b.d",
    "content": "module imports.test19107b;\n\nimport imports.test19107a : I;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test19187.d",
    "content": "module imports.test19187;\nvoid test()() { }\nalias foo = test;\nalias foo = test;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test1imp.d",
    "content": "\n    alias uint DWORD;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test25a.d",
    "content": "module imports.test25a;\n\nimport imports.test25b;\nimport core.stdc.stdio;\n\nclass Afoo\n{\n    static this()\n    {\n\tprintf(\"Afoo()\\n\");\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test25b.d",
    "content": "module imports.test25b;\n\nimport imports.test25a;\n\nimport core.stdc.stdio;\n\nclass Bfoo\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test2991.d",
    "content": "module imports.test2991;\n\nprivate void foo()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test4003a.d",
    "content": "module imports.test4003a;\n\nimport imports.typecons4003;\n\nTuple!(string) t;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test50a.d",
    "content": "module imports.test50a;\n\nclass Foo {\n        protected int a;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test55a.d",
    "content": "module imports.test55a;\n\nimport test55;\n\nclass Arm {\n  alias int ListHead;\n  MessageQueue.ListHead mqueue;\n}\n\nclass Arm2 {\n  alias int ListHead;\n  Queue2.ListHead mqueue;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test59a.d",
    "content": "module imports.test59a;\n\nimport test59;\n\nHRESULT h;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test59b.d",
    "content": "module imports.test59b;\n\nalias int HRESULT;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test6013.d",
    "content": "module imports.test6013;\n\nint value;\nint func() { return 0; };\n\npublic alias value public_alias_value;\nprivate alias value private_alias_value;\npublic alias func public_alias_func;\nprivate alias func private_alias_func;\npublic alias int public_alias_type;\nprivate alias int private_alias_type;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test61a.d",
    "content": "module imports.test61a;\n\nenum FooA { fooA };\nvoid bar(FooA x) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test62a.d",
    "content": "module imports.test62a;\n\nimport test62;\n\nstruct T()\n{\n   struct Nested\n   {\n      S member;\n   }\n}\n\nalias T!() instance;\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test63a.d",
    "content": "module imports.test63a;\n\nprivate import test63;\n\nstruct s {\n\n    char[SIZE] a;\n\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test66a.d",
    "content": "module imports.test66a;\n\nimport test66;\n\nclass A : Lexer\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test67a.d",
    "content": "module imports.test67a;\n\nimport test67;\n\nclass Base\n{\n    I create() {\n        return null;\n    }\n}\n\nclass Derived : Base\n{\n    override SubI create() {\n        return null;\n    }\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test68a.d",
    "content": "module imports.test68a;\n\nclass OtherModuleClass\n{\n        protected void foo()\n        {\n        }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test70.d",
    "content": "module imports.test70;\n\nvoid foo()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test71.d",
    "content": "module imports_test71;\nimport imports = object;\n\nvoid foo()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test72a.d",
    "content": "module imports.test72a;\npublic import imports.test72b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test72b.d",
    "content": "module imports.test72b;\nprivate import imports.test72c : foo;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test72c.d",
    "content": "module imports.test72c;\n\nvoid foo()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test7491a.d",
    "content": "module imports.test7491a;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test7491b.d",
    "content": "module imports.test7491b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9276decl.d",
    "content": "module imports.test9276decl;\n\nimport imports.test9276sem, imports.test9276visitors, imports.test9276util;\n\nclass Declaration\n{\n    mixin DownCastMethods!TemplateDecl;\n}\n\nclass TemplateDecl : OverloadableDecl\n{\n    mixin Visitors;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9276expr.d",
    "content": "module imports.test9276expr;\n\nimport imports.test9276parser;\nimport imports.test9276util;\n\nclass Node\n{\n    mixin DownCastMethods!Declaration;\n\n}\n\nclass Expression : Node\n{\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9276hash.d",
    "content": "module imports.test9276hash;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9276parser.d",
    "content": "module imports.test9276parser;\n\npublic import imports.test9276expr, imports.test9276decl;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9276sem.d",
    "content": "module imports.test9276sem;\n\nclass Declaration\n{\n    mixin Visitors;\n}\n\ntemplate Semantic(T)\n{\nprivate:\n    struct\n    {\n        import imports.test9276hash;\n    }\n\n}\n\n\n\nimport imports.test9276visitors;\n\nclass OverloadableDecl : Declaration\n{\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9276type.d",
    "content": "module imports.test9276type;\n\nimport imports.test9276parser;\n\nclass Type : Expression     // <- note to Walter.\n{\n}\n\nclass BasicType : Type\n{\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9276util.d",
    "content": "module imports.test9276util;\n\nstring _dgliteral(T...)()\n{\n    foreach (t; T)\n        return t.stringof;\n    assert(0);\n}\ntemplate DownCastMethods(T...)\n{\n    enum x = _dgliteral!T;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9276visitors.d",
    "content": "module imports.test9276visitors;\n\ntemplate Visitors()\n{\n    mixin Semantic!(typeof(this));\n    mixin DeepDup!(typeof(this));\n}\n\nimport imports.test9276type;\n\ntemplate DeepDup(T) if (is(T : BasicType))\n{}\n\ntemplate DeepDup(T)\n{}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9399a.d",
    "content": "module imports.test9399a;\n\nvoid call(alias n)() {\n    n();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9436aggr.d",
    "content": "module imports.test9436aggr;\n\nimport imports.test9436type;\n\nclass Aggregate : Type\n{\n}\n\nclass Class\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9436interp.d",
    "content": "module imports.test9436interp;\n\nimport imports.test9436type;\nimport imports.test9436aggr;\n\nclass ReferenceValueT(T)\n{\n    void doCast()\n    {\n        auto x = Type.ConversionFlags.kAllowBaseClass;\n    }\n}\n\nclass ClassValue : ReferenceValueT!Class\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9436node.d",
    "content": "module imports.test9436node;\n\nimport imports.test9436aggr;\n\ntemplate ForwardCtor()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9436type.d",
    "content": "module imports.test9436type;\n\nimport imports.test9436node;\n\nclass Type\n{\n    mixin ForwardCtor!();\n\n    enum ConversionFlags\n    {\n        kAllowBaseClass = 0\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9672a.d",
    "content": "module imports.test9672a;   // interpret\n\nimport test9672;            // node\n\nclass Type\n{\n    mixin ForwardCtor!();\n}\n\n//BasicType only created for standard types associated with tokens\nclass BasicType : Type\n{\n    static Type createType()\n    {\n        return null;\n    }\n}\n\nclass ValueT(T)\n{\n    Type getType()\n    {\n        return BasicType.createType();\n    }\n}\nclass CharValue : ValueT!char\n{\n    string toStr()\n    {\n        return null;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9692b.d",
    "content": "module imports.test9692b;\nint j;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9919a.d",
    "content": "module imports.test9919a;\n\nimport imports.test9919c;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9919b.d",
    "content": "module imports.test9919b;\n\nclass Event\n{\n    mixin genToString;  // @BUG@\n}\n\nclass MouseEvent : Event\n{\n    enum Action { A, B }\n}\n\nmixin template genToString()\n{\n    override string toString()\n    {\n        return \"\";\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/test9919c.d",
    "content": "module imports.test9919c;\n\nimport test9919;\n\nMouseEvent.Action action;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/testcontracts.d",
    "content": "module imports.testcontracts;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3602\n\nclass Base3602\n{\n   void method(int x, int y)\n   in\n   {\n       assert(x > 0);\n       assert(y > 0);\n   }\n   body\n   {\n   }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5230\n\nclass Base5230\n{\n    int method()\n    out (res)\n    {\n    }\n    body\n    {\n        return 42;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/testlambda1.d",
    "content": "module imports.testlambda1;\n\nint bar() { return 7; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/testlambda2.d",
    "content": "module imports.testlambda2;\n\nint bar() { return 7; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/typecons4003.d",
    "content": "module imports.typecons4003;\n\nstruct Tuple(T...)\n{\n    alias T Types;\n    Types field;\n\n    ref Tuple!(Types[from .. to]) slice(uint from, uint to)()\n    {\n        return *cast(typeof(return) *) &(field[from]);\n    }\n\n    void test() //unittest\n    {\n        .Tuple!(int, string, float, double) a;\n        a.field[1] = \"abc\";\n        a.field[2] = 4.5;\n        auto s = a.slice!(1, 3);\n        static assert(is(typeof(s) == Tuple!(string, float)));\n        //assert(s.field[0] == \"abc\" && s.field[1] == 4.5);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/udamodule1.d",
    "content": "@(1) deprecated(\"This module will be removed.\") @(2) module imports.udamodule1;\n\nvoid foo()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/udamodule2.d",
    "content": "@UDA(1) @UDA(2) module imports.udamodule2;\n\nimport imports.udamodule2a;\n\nvoid foo()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/udamodule2a.d",
    "content": "module imports.udamodule2a;\n\nstruct UDA\n{\n    int a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/imports/wax16798.d",
    "content": "module its.a.floorwax.wax16798;\n\npragma(msg, \"it's a floor wax\");\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/interpret3.d",
    "content": "// PERMUTE_ARGS: -inline\n\ntemplate compiles(int T)\n{\n    bool compiles = true;\n}\n\nalias TypeTuple(T...) = T;\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3901\n// Arbitrary struct assignment, ref return\n\nstruct ArrayRet\n{\n    int x;\n}\n\nint arrayRetTest(int z)\n{\n    ArrayRet[6] w;\n    int q = (w[3].x = z);\n    return q;\n}\nstatic assert(arrayRetTest(51) == 51);\n\n// https://issues.dlang.org/show_bug.cgi?id=3842 -- must not segfault\nint ice3842(int z)\n{\n    ArrayRet w;\n    return arrayRetTest((*(&w)).x);\n}\nstatic assert(true || is(typeof(compiles!(ice3842(51)))));\n\nint arrayret2()\n{\n    int[5] a;\n    int[3] b;\n    b[] = a[1 .. $-1] = 5;\n    return b[1];\n}\nstatic assert(arrayret2() == 5);\n\nstruct DotVarTest\n{\n    ArrayRet z;\n}\n\nstruct DotVarTest2\n{\n    ArrayRet z;\n    DotVarTest p;\n}\n\nint dotvar1()\n{\n    DotVarTest w;\n    w.z.x = 3;\n    return w.z.x;\n}\nstatic assert(dotvar1() == 3);\n\nint dotvar2()\n{\n    DotVarTest2[4] m;\n    m[2].z.x = 3;\n    m[1].p.z.x = 5;\n    return m[2].z.x + 7;\n}\nstatic assert(dotvar2() == 10);\n\n\nstruct RetRefStruct\n{\n    int x;\n    char c;\n}\n\n// Return value reference tests, for D2 only.\n\nref RetRefStruct reffunc1(ref RetRefStruct a)\n{\n    int y = a.x;\n    return a;\n}\n\nref RetRefStruct reffunc2(ref RetRefStruct a)\n{\n    RetRefStruct z = a;\n    return reffunc1(a);\n}\n\nref int reffunc7(ref RetRefStruct aa)\n{\n    return reffunc1(aa).x;\n}\n\nref int reffunc3(ref int a)\n{\n    return a;\n}\n\nstruct RefTestStruct\n{\n    RetRefStruct r;\n\n    ref RefTestStruct reffunc4(ref RetRefStruct[3] a)\n    {\n        return this;\n    }\n\n    ref int reffunc6()\n    {\n        return this.r.x;\n    }\n}\n\nref RetRefStruct reffunc5(ref RetRefStruct[3] a)\n{\n    int t = 1;\n    for (int i = 0; i < 10; ++i)\n    {\n        if (i == 7)\n            ++t;\n    }\n    return a[reffunc3(t)];\n}\n\nint retRefTest1()\n{\n    RetRefStruct b = RetRefStruct(0, 'a');\n    reffunc1(b).x = 3;\n    return b.x - 1;\n}\n\nint retRefTest2()\n{\n    RetRefStruct b = RetRefStruct(0, 'a');\n    reffunc2(b).x = 3;\n    RetRefStruct[3] z;\n    RefTestStruct w;\n    w.reffunc4(z).reffunc4(z).r.x = 4;\n    assert(w.r.x == 4);\n    w.reffunc6() = 218;\n    assert(w.r.x == 218);\n    z[2].x = 3;\n    int q = 4;\n    int u = reffunc5(z).x + reffunc3(q);\n    assert(u == 7);\n    reffunc5(z).x += 7;\n    assert(z[2].x == 10);\n    RetRefStruct m = RetRefStruct(7, 'c');\n    m.x = 6;\n    reffunc7(m) += 3;\n    assert(m.x == 9);\n    return b.x - 1;\n}\n\nint retRefTest3()\n{\n    RetRefStruct b = RetRefStruct(0, 'a');\n    auto deleg = function (RetRefStruct a){ return a; };\n    typeof(deleg)[3] z;\n    z[] = deleg;\n    auto y = deleg(b).x + 27;\n    b.x = 5;\n    assert(y == 27);\n    y = z[1](b).x + 22;\n    return y - 1;\n}\n\nint retRefTest4()\n{\n    RetRefStruct b = RetRefStruct(0, 'a');\n    reffunc3(b.x) = 218;\n    assert(b.x == 218);\n    return b.x;\n}\n\nstatic assert(retRefTest1() == 2);\nstatic assert(retRefTest2() == 2);\nstatic assert(retRefTest3() == 26);\nstatic assert(retRefTest4() == 218);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7887\n// assign to returned reference\n\nbool test7887()\n{\n    ref int f(ref int x) { return x; }\n    int a;\n    f(a) = 42;\n    return (a == 42);\n}\nstatic assert(test7887());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7473\n// struct non-ref\n\nstruct S7473\n{\n    int i;\n}\n\nstatic assert({\n    S7473 s = S7473(1);\n    assert(s.i == 1);\n    bug7473(s);\n    assert(s.i == 1);\n    return true;\n}());\n\nvoid bug7473(S7473 s)\n{\n    s.i = 2;\n}\n\nstruct S7473b\n{\n    S7473 m;\n}\n\nstatic assert({\n    S7473b s = S7473b(S7473(7));\n    assert(s.m.i == 7);\n    bug7473b(s);\n    assert(s.m.i == 7);\n    return true;\n}());\n\nvoid bug7473b(S7473b s)\n{\n    s.m.i = 2;\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4389\n\nint bug4389()\n{\n    string s;\n    dchar c = '\\u2348';\n    s ~= c;\n    assert(s.length == 3);\n    dchar d = 'D';\n    s ~= d;\n    assert(s.length == 4);\n    s = \"\";\n    s ~= c;\n    assert(s.length == 3);\n    s ~= d;\n    assert(s.length == 4);\n    string z;\n    wchar w = '\\u0300';\n    z ~= w;\n    assert(z.length == 2);\n    z = \"\";\n    z ~= w;\n    assert(z.length == 2);\n    return 1;\n}\n\nstatic assert(bug4389());\n\n// ICE(constfold.c)\nint ice4389()\n{\n    string s;\n    dchar c = '\\u2348';\n    s ~= c;\n    s = s ~ \"xxx\";\n   return 1;\n}\n\nstatic assert(ice4389());\n\n// ICE(expression.c)\nstring ice4390()\n{\n    string s;\n    dchar c = '`';\n    s ~= c;\n    s ~= c;\n   return s;\n}\n\nstatic assert(mixin(ice4390()) == ``);\n\n// https://issues.dlang.org/show_bug.cgi?id=5248\n// (D1 + D2)\nstruct Leaf5248\n{\n    string Compile_not_ovloaded()\n    {\n        return \"expression\";\n    }\n}\nstruct Matrix5248\n{\n    Leaf5248 Right;\n\n    string Compile()\n    {\n        return Right.Compile_not_ovloaded();\n    }\n};\n\nstatic assert(Matrix5248().Compile());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4837\n// >>>=\n\nbool bug4837()\n{\n    ushort x = 0x89AB;\n    x >>>= 4;\n    assert(x == 0x89A);\n    byte y = 0x7C;\n    y >>>= 2;\n    assert(y == 0x1F);\n    return true;\n}\n\nstatic assert(bug4837());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10252\n// shift out of range\n\nint lshr10252(int shift)\n{\n     int a = 5;\n     return a << shift;\n}\n\nint rshr10252(int shift)\n{\n     int a = 5;\n     return a >> shift;\n}\n\nint ushr10252(int shift)\n{\n     int a = 5;\n     return a >>> shift;\n}\n\nstatic assert( is(typeof(compiles!(lshr10252( 4)))));\nstatic assert(!is(typeof(compiles!(lshr10252(60)))));\nstatic assert( is(typeof(compiles!(rshr10252( 4)))));\nstatic assert(!is(typeof(compiles!(rshr10252(80)))));\nstatic assert( is(typeof(compiles!(ushr10252( 2)))));\nstatic assert(!is(typeof(compiles!(ushr10252(60)))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1982\n// CTFE null problems\n\nenum a1982 = [1, 2, 3];\nstatic assert(a1982 !is null);\n\nstring foo1982() { return null; }\nstatic assert(foo1982() is null);\nstatic assert(!foo1982().length);\n\nstatic assert(null is null);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7988\n// CTFE return values should be allowed in compile-time expressions\n\nclass X7988 { int y; this() { y = 2; } }\nstatic assert((new X7988).y == 2);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8253\n// ICE: calling of member function of non-CTFE class variable\n\nclass Bug8253\n{\n    bool j()\n    {\n        return true;\n    }\n}\nBug8253 m8253;\nstatic assert(!is(typeof(compiles!(m8253.j()))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8285\n// Issue with slice returned from CTFE function\n\nstring foo8285()\n{\n    string s = \"ab\";\n    return s[0 .. $];\n}\n\ntemplate T8285b(string s) { }\n\ntemplate T8285a()\n{\n    enum s = foo8285();\n    alias T8285b!(s) t2;\n}\n\nint bar8285()\n{\n    alias T8285a!() t1;\n    return 0;\n}\n\nint baz8285(int x)\n{\n    return 0;\n}\n\nstatic assert(baz8285(bar8285()) == 0);\n\n// test case 2\n\nstring xbar8285()\n{\n    string s = \"ab\";\n    return s[0 .. $];\n}\n\ntemplate xT8285a()\n{\n    enum xT8285a = xbar8285()[0 .. $];\n}\n\nstring xbaz8285()\n{\n    return xT8285a!();\n}\n\nstring xfoo8285(string s)\n{\n    return s;\n}\n\nstatic assert(xfoo8285(xbaz8285()) == \"ab\");\n\n/**************************************************\n  'this' parameter bug revealed during refactoring\n**************************************************/\n\nint thisbug1(int x) { return x; }\n\nstruct ThisBug1\n{\n    int m = 1;\n    int wut()\n    {\n        return thisbug1(m);\n    }\n}\n\nint thisbug2()\n{\n    ThisBug1 spec;\n    return spec.wut();\n}\n\nstatic assert(thisbug2());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6972\n// ICE with cast()cast()assign\n\nint bug6972()\n{\n    ubyte n = 6;\n    n /= 2u;\n    return n;\n}\nstatic assert(bug6972() == 3);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6164\n\nsize_t bug6164()\n{\n    int[] ctfe2(int n)\n    {\n        int[] r = [];\n        if (n != 0)\n            r ~= [1] ~ ctfe2(n - 1);\n        return r;\n    }\n    return ctfe2(2).length;\n}\nstatic assert(bug6164() == 2);\n\n/**************************************************\n    Interpreter code coverage tests\n**************************************************/\n\nint cov1(int a)\n{\n    a %= 15382;\n    a /= 5;\n    a = ~ a;\n    bool c = (a == 0);\n    bool b = true && c;\n    assert(b == 0);\n    b = false && c;\n    assert(b == 0);\n    b = false || c;\n    assert(b == 0);\n    a ^= 0x45349;\n    a = ~ a;\n    a &= 0xFF3F;\n    a >>>= 1;\n    a = a ^ 0x7393;\n    a = a >> 1;\n    a = a >>> 1;\n    a = a | 0x010101;\n    return a;\n}\nstatic assert(cov1(534564) == 71589);\n\nint cov2()\n{\n    int i = 0;\n    do\n    {\n        goto DOLABEL;\n    DOLABEL:\n        if (i != 0)\n        {\n            goto IFLABEL;\n    IFLABEL:\n            switch(i)\n            {\n            case 3:\n                break;\n            case 6:\n                goto SWITCHLABEL;\n    SWITCHLABEL:\n                i = 27;\n                goto case 3;\n            default:\n                assert(0);\n            }\n            return i;\n        }\n        i = 6;\n    } while(true);\n    return 88; // unreachable\n}\nstatic assert(cov2() == 27);\n\ntemplate CovTuple(T...)\n{\n    alias T CovTuple;\n}\n\nalias CovTuple!(int, long) TCov3;\n\nint cov3(TCov3 t)\n{\n    TCov3 s;\n    s = t;\n    assert(s[0] == 1);\n    assert(s[1] == 2);\n    return 7;\n}\nstatic assert(cov3(1, 2) == 7);\n\nint badassert1(int z)\n{\n    assert(z == 5, \"xyz\");\n    return 1;\n}\n\nsize_t badslice1(int[] z)\n{\n    return z[0 .. 3].length;\n}\n\nsize_t badslice2(int[] z)\n{\n    return z[0 .. badassert1(1)].length;\n}\n\nsize_t badslice3(int[] z)\n{\n    return z[badassert1(1) .. 2].length;\n}\n\nstatic assert(!is(typeof(compiles!(badassert1(67)))));\nstatic assert( is(typeof(compiles!(badassert1(5)))));\nstatic assert(!is(typeof(compiles!(badslice1([1,2])))));\nstatic assert(!is(typeof(compiles!(badslice2([1,2])))));\nstatic assert(!is(typeof(compiles!(badslice3([1,2,3])))));\n\n/*******************************************/\n\nint bug7894()\n{\n    for (int k = 0; k < 2; ++k)\n    {\n        goto Lagain;\nLagain:\n        ;\n    }\n    int m = 1;\n    do\n    {\n        ++m;\n        goto Ldo;\nLdo: ;\n    } while (m < 3);\n    assert(m == 3);\n\n    return 1;\n}\nstatic assert(bug7894());\n\n/*******************************************/\n\nsize_t bug5524(int x, int[] more...)\n{\n    int[0] zz;\n    assert(zz.length == 0);\n    return 7 + more.length + x;\n}\nstatic assert(bug5524(3) == 10);\n\n\n// https://issues.dlang.org/show_bug.cgi?id=5722\n\nstatic assert((\"\" ~ \"\\&copy;\"[0]).length == 1);\nconst char[] null5722 = null;\nstatic assert((null5722 ~ \"\\&copy;\"[0]).length == 1);\nstatic assert((\"\\&copy;\"[0] ~ null5722).length == 1);\n\n/*******************************************\n * Tests for CTFE Array support.\n * https://issues.dlang.org/show_bug.cgi?id=1330\n * https://issues.dlang.org/show_bug.cgi?id=3801\n * https://issues.dlang.org/show_bug.cgi?id=3835\n * https://issues.dlang.org/show_bug.cgi?id=4050\n * https://issues.dlang.org/show_bug.cgi?id=4051\n * https://issues.dlang.org/show_bug.cgi?id=5147\n * and major functionality\n *******************************************/\n\nchar[] bug1330StringIndex()\n{\n    char[] blah = \"foo\".dup;\n    assert(blah == \"foo\");\n    char[] s = blah[0 .. 2];\n    blah[0] = 'h';\n    assert(s == \"ho\");\n    s[0] = 'm';\n    return blah;\n}\nstatic assert(bug1330StringIndex() == \"moo\");\nstatic assert(bug1330StringIndex() == \"moo\"); // check we haven't clobbered any string literals\n\nint[] bug1330ArrayIndex()\n{\n    int[] blah = [1,2,3];\n    int[] s = blah;\n    s = blah[0 .. 2];\n    int z = blah[0] = 6;\n    assert(z == 6);\n    assert(blah[0] == 6);\n    assert(s[0] == 6);\n    assert(s == [6, 2]);\n    s[1] = 4;\n    assert(z == 6);\n    return blah;\n}\nstatic assert(bug1330ArrayIndex() == [6, 4, 3]);\nstatic assert(bug1330ArrayIndex() == [6, 4, 3]); // check we haven't clobbered any literals\n\nchar[] bug1330StringSliceAssign()\n{\n    char[] blah = \"food\".dup;\n    assert(blah == \"food\");\n    char[] s = blah[1 .. 4];\n    blah[0 .. 2] = \"hc\";\n    assert(s == \"cod\");\n    s[0 .. 2] = ['a', 'b'];   // Mix string + array literal\n    assert(blah == \"habd\");\n    s[0 .. 2] = \"mq\";\n    return blah;\n}\nstatic assert(bug1330StringSliceAssign() == \"hmqd\");\nstatic assert(bug1330StringSliceAssign() == \"hmqd\");\n\nint[] bug1330ArraySliceAssign()\n{\n    int[] blah = [1, 2, 3, 4];\n    int[] s = blah[1 .. 4];\n    blah[0 .. 2] = [7, 9];\n    assert(s == [9, 3, 4]);\n    s[0 .. 2] = [8, 15];\n    return blah;\n}\nstatic assert(bug1330ArraySliceAssign() == [7, 8, 15, 4]);\n\nint[] bug1330ArrayBlockAssign()\n{\n    int[] blah = [1, 2, 3, 4, 5];\n    int[] s = blah[1 .. 4];\n    blah[0 .. 2] = 17;\n    assert(s == [17, 3, 4]);\n    s[0 .. 2] = 9;\n    return blah;\n}\nstatic assert(bug1330ArrayBlockAssign() == [17, 9, 9, 4, 5]);\n\nchar[] bug1330StringBlockAssign()\n{\n    char[] blah = \"abcde\".dup;\n    char[] s = blah[1 .. 4];\n    blah[0 .. 2] = 'x';\n    assert(s == \"xcd\");\n    s[0 .. 2] = 'y';\n    return blah;\n}\nstatic assert(bug1330StringBlockAssign() == \"xyyde\");\n\nint assignAA(int x)\n{\n    int[int] aa;\n    int[int] cc = aa;\n    assert(cc.values.length == 0);\n    assert(cc.keys.length == 0);\n    aa[1] = 2;\n    aa[x] = 6;\n    int[int] bb = aa;\n    assert(bb.keys.length == 2);\n    assert(cc.keys.length == 0); // cc is not affected to aa, because it is null\n    aa[500] = 65;\n    assert(bb.keys.length == 3); // but bb is affected by changes to aa\n    return aa[1] + aa[x];\n}\nstatic assert(assignAA(12) == 8);\n\ntemplate Compileable(int z) { bool OK; }\n\nint arraybounds(int j, int k)\n{\n    int[] xxx = [1, 2, 3, 4, 5];\n    int[] s = xxx[1 .. $];\n    s = s[j .. k]; // slice of slice\n    return s[$ - 1];\n}\nstatic assert(!is(typeof(Compileable!(arraybounds(1, 14)))));\nstatic assert(!is(typeof(Compileable!(arraybounds(15, 3)))));\nstatic assert(arraybounds(2, 4) == 5);\n\nint arraybounds2(int j, int k)\n{\n    int[] xxx = [1, 2, 3, 4, 5];\n    int[] s = xxx[j .. k]; // direct slice\n    return 1;\n}\nstatic assert(!is(typeof(Compileable!(arraybounds2(1, 14)))));\nstatic assert(!is(typeof(Compileable!(arraybounds2(15, 3)))));\nstatic assert(arraybounds2(2, 4) == 1);\n\nint bug5147a()\n{\n    int[1][2] a = 37;\n    return a[0][0];\n}\nstatic assert(bug5147a() == 37);\n\nint bug5147b()\n{\n    int[4][2][3][17] a = 37;\n    return a[0][0][0][0];\n}\nstatic assert(bug5147b() == 37);\n\nint setlen()\n{\n    int[][] zzz;\n    zzz.length = 2;\n    zzz[0].length = 10;\n    assert(zzz.length == 2);\n    assert(zzz[0].length == 10);\n    assert(zzz[1].length == 0);\n    return 2;\n}\nstatic assert(setlen() == 2);\n\nint[1][1] bug5147()\n{\n    int[1][1] a = 1;\n    return a;\n}\nstatic assert(bug5147() == [[1]]);\n\nenum int[1][1] enum5147 = bug5147();\nstatic assert(enum5147 == [[1]]);\n\nimmutable int[1][1] bug5147imm = bug5147();\n\n// Index referencing\nint[2][2] indexref1()\n{\n    int[2][2] a = 2;\n    a[0] = 7;\n\n    int[][] b = [null, null];\n    b[0 .. $] = a[0][0 .. 2];\n    assert(b[0][0] == 7);\n    assert(b[0][1] == 7);\n    int[] w;\n    w = a[0];\n    assert(w[0] == 7);\n    w[0 .. $] = 5;\n    assert(a[0] != [7, 7]);\n    assert(a[0] == [5, 5]);\n    assert(b[0] == [5, 5]);\n    return a;\n}\nint[2][2] indexref2()\n{\n    int[2][2] a = 2;\n    a[0] = 7;\n\n    int[][2] b = null;\n    b[0 .. $] = a[0];\n    assert(b[0][0] == 7);\n    assert(b[0][1] == 7);\n    assert(b == [[7, 7], [7, 7]]);\n    int[] w;\n    w = a[0];\n    assert(w[0] == 7);\n    w[0 .. $] = 5;\n    assert(a[0] != [7, 7]);\n    assert(a[0] == [5, 5]);\n    assert(b[0] == [5, 5]);\n    return a;\n}\nint[2][2] indexref3()\n{\n    int[2][2] a = 2;\n    a[0]=7;\n\n    int[][2] b = [null, null];\n    b[0 .. $] = a[0];\n    assert(b[0][0] == 7);\n    assert(b[0][1] == 7);\n    int[] w;\n    w = a[0];\n    assert(w[0] == 7);\n    w[0 .. $] = 5;\n    assert(a[0] != [7, 7]);\n    assert(a[0] == [5, 5]);\n    assert(b[0] == [5, 5]);\n    return a;\n}\nint[2][2] indexref4()\n{\n    int[2][2] a = 2;\n    a[0] = 7;\n\n    int[][2] b =[[1, 2, 3], [1, 2, 3]]; // wrong code\n    b[0] = a[0];\n    assert(b[0][0] == 7);\n    assert(b[0][1] == 7);\n    int[] w;\n    w = a[0]; //[0 .. $];\n    assert(w[0] == 7);\n    w[0 .. $] = 5;\n    assert(a[0] != [7, 7]);\n    assert(a[0] == [5, 5]);\n    assert(b[0] == [5, 5]);\n    return a;\n}\nstatic assert(indexref1() == [[5, 5], [2, 2]]);\nstatic assert(indexref2() == [[5, 5], [2, 2]]);\nstatic assert(indexref3() == [[5, 5], [2, 2]]);\nstatic assert(indexref4() == [[5, 5], [2, 2]]);\n\nint staticdynamic()\n{\n    int[2][1] a = 2;\n    assert(a == [[2, 2]]);\n\n    int[][1] b = a[0][0 .. 1];\n    assert(b[0] == [2]);\n    auto k = b[0];\n    auto m = a[0][0 .. 1];\n    assert(k == [2]);\n    assert(m == k);\n    return 0;\n}\nstatic assert(staticdynamic() == 0);\n\nint chainassign()\n{\n    int[4] x = 6;\n    int[] y = new int[4];\n    auto k = (y[] = (x[] = 2));\n    return k[0];\n}\nstatic assert(chainassign() == 2);\n\n// index assignment\nstruct S3801\n{\n    char c;\n    int[3] arr;\n\n    this(int x, int y)\n    {\n        c = 'x';\n        arr[0] = x;\n        arr[1] = y;\n    }\n}\n\nint bug3801()\n{\n    S3801 xxx = S3801(17, 67);\n    int[] w = xxx.arr;\n    xxx.arr[1] = 89;\n    assert(xxx.arr[0] == 17);\n    assert(w[1] == 89);\n    assert(w == [17, 89, 0]);\n    return xxx.arr[1];\n}\n\nenum : S3801 { bug3801e = S3801(17, 18) }\nstatic assert(bug3801e.arr == [17, 18, 0]);\n\nimmutable S3801 bug3801u = S3801(17, 18);\nstatic assert(bug3801u.arr == [17, 18, 0]);\nstatic assert(bug3801() == 89);\n\nint bug3835()\n{\n    int[4] arr;\n    arr[] = 19;\n    arr[0] = 4;\n    int kk;\n    foreach (ref el; arr)\n    {\n        el += 10;\n        kk = el;\n    }\n    assert(arr[2] == 29);\n    arr[0] += 3;\n    return arr[0];\n}\nstatic assert(bug3835() == 17);\n\nauto bug5852(const(string) s)\n{\n    string[] r;\n    r ~= s;\n    assert(r.length == 1);\n    return r[0].length;\n}\nstatic assert(bug5852(\"abc\") == 3);\n\n// https://issues.dlang.org/show_bug.cgi?id=7217\n\nstruct S7217 { int[] arr; }\n\nbool f7217()\n{\n    auto s = S7217();\n    auto t = s.arr;\n    return true;\n}\nstatic assert(f7217());\n\n/*******************************************\n    Set array length\n*******************************************/\n\nstatic assert(\n{\n    struct W { int[] z; }\n    W w;\n    w.z.length = 2;\n    assert(w.z.length == 2);\n    w.z.length = 6;\n    assert(w.z.length == 6);\n    return true;\n}());\n\n// https://issues.dlang.org/show_bug.cgi?id=7185\n// char[].length = n\n\nbool bug7185()\n{\n    auto arr = new char[2];\n    auto arr2 = new char[2];\n    arr2[] = \"ab\";\n    arr.length = 1;\n    arr2.length = 7;\n    assert(arr.length == 1);\n    assert(arr2.length == 7);\n    assert(arr2[0 .. 2] == \"ab\");\n    return true;\n}\nstatic assert(bug7185());\n\nbool bug9908()\n{\n    static const int[3] sa = 1;\n    return sa == [1, 1, 1];\n}\nstatic assert(bug9908());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6934\n\nstruct Struct6934\n{\n    int[] x = [1, 2];\n}\n\nvoid bar6934(ref int[] p)\n{\n    p[0] = 12;\n    assert(p[0] == 12);\n    p[0 .. 1] = 17;\n    assert(p[0] == 17);\n    p = p[1 .. $];\n}\n\nint bug6934()\n{\n    Struct6934 q;\n    bar6934(q.x);\n    int[][] y = [[2, 5], [3, 6, 8]];\n    bar6934(y[0]);\n    return 1;\n}\nstatic assert(bug6934());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5671\n\nstatic assert(['a', 'b'] ~ \"c\" == \"abc\");\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8624\n\nint evil8624()\n{\n    long  m =  0x1_0000_0000L;\n    assert(m != 0);\n    long[] a = [0x1_0000_0000L];\n    long[] b = [0x4_0000_0000L];\n    assert(a[] != b[]);\n    return 1;\n}\nstatic assert(evil8624());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8644\n// array literal >,<\n\nint bug8644()\n{\n    auto m = \"a\";\n    auto z = ['b'];\n    auto c = \"b7\";\n    auto d = ['b', '6'];\n    assert(m < z);\n    assert(z > m);\n    assert(z <= c);\n    assert(c > z);\n    assert(c > d);\n    assert(d >= d);\n    return true;\n}\nstatic assert(bug8644());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6159\n\nstruct A6159 {}\n\nstatic assert({ return A6159.init is A6159.init; }());\nstatic assert({ return [1] is [1]; }());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5685\n\nstring bug5685()\n{\n    return \"xxx\";\n}\nstruct Bug5865\n{\n    void test1()\n    {\n        enum file2 = (bug5685())[0 .. $];\n    }\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6235\n// Regression ICE on $ in template\n\nstruct Bug6235(R)\n{\n    enum XXX = is(typeof(R.init[0 .. $]) : const ubyte[]);\n}\n\nBug6235!(ubyte[]) bug6235;\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8673\n// ICE\n\nenum dollar8673 = [0][(() => $ - 1)()];\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5840\n\nstruct Bug5840\n{\n    string g;\n    int w;\n}\n\nint bug5840(int u)\n{\n    // check for clobbering\n    Bug5840 x = void;\n    x.w = 4;\n    x.g = \"3gs\";\n    if (u == 1)\n        bug5840(2);\n    if (u == 2)\n    {\n        x.g = \"abc\";\n        x.w = 3465;\n    }\n    else\n    {\n        assert(x.g == \"3gs\");\n        assert(x.w == 4);\n    }\n    return 56;\n}\nstatic assert(bug5840(1) == 56);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7810\n\nint bug7810()\n{\n    int[1][3] x = void;\n    x[0] = [2];\n    x[1] = [7];\n    assert(x[0][0] == 2);\n\n    char[1][3] y = void;\n    y[0] = \"a\";\n    y[1] = \"b\";\n    assert(y[0][0] == 'a');\n\n    return 1;\n}\nstatic assert(bug7810());\n\nstruct Bug7810\n{\n    int w;\n}\nint bug7810b(T)(T[] items...)\n{\n    assert(items[0] == Bug7810(20));\n    return 42;\n}\nstatic assert(bug7810b(Bug7810(20), Bug7810(10)) == 42);\n\n/*******************************************\n    std.datetime ICE (30 April 2011)\n*******************************************/\n\nstruct TimeOfDayZ\n{\npublic:\n    this(int hour) { }\n    invariant() { }\n}\nconst testTODsThrownZ = TimeOfDayZ(0);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5954\n\nstruct Bug5954\n{\n    int x;\n    this(int xx)\n    {\n        this.x = xx;\n    }\n}\nvoid bug5954()\n{\n    enum f = Bug5954(10);\n    static assert(f.x == 10);\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5972\n\nint bug5972()\n{\n    char[] z = \"abc\".dup;\n    char[][] a = [null, null];\n    a[0]  = z[0 .. 2];\n    char[] b = a[0];\n    assert(b == \"ab\");\n    a[0][1] = 'q';\n    assert(a[0] == \"aq\");\n    assert(b == \"aq\");\n    assert(b[1] == 'q');\n    //a[0][0 .. $ - 1][0 .. $] = a[0][0 .. $ - 1][0 .. $];  // overlap\n    return 56;\n}\nstatic assert(bug5972() == 56);\n\n/*******************************************\n    2.053beta [CTFE]ICE 'global errors'\n*******************************************/\n\nint wconcat(wstring replace)\n{\n    wstring value;\n    value  = \"A\"w;\n    value = value ~ replace;\n    return 1;\n}\nstatic assert(wconcat(\"X\"w));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10397\n// string concat\n\nstatic assert(!is(typeof(compiles!(\"abc\" ~ undefined))));\nstatic assert(!is(typeof(compiles!(otherundefined ~ \"abc\"))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9634\n// struct concat\n\nstruct Bug9634\n{\n    int raw;\n}\n\nbool bug9634()\n{\n    Bug9634[] jr = [Bug9634(42)];\n\n    Bug9634[] ir = null ~ jr;\n    Bug9634[] kr = jr ~ null;\n    Bug9634[] mr = jr ~ jr;\n\n    jr[0].raw = 6;\n    assert(ir[0].raw == 42);\n    assert(kr[0].raw == 42);\n    assert(jr[0].raw == 6);\n    assert(&mr[0] != &mr[1]);\n    return true;\n}\n\nstatic assert(bug9634());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4001: A Space Oddity\n\nint space() { return 4001; }\n\nvoid oddity4001(int q)\n{\n    const int bowie = space();\n    static assert(space() == 4001);\n    static assert(bowie == 4001);\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3779\n\nstatic const bug3779 = [\"123\"][0][$ - 1];\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8893\n// ICE with bad struct literal\n\nstruct Foo8893\n{\n    char[3] data;\n}\nint bar8893(Foo8893 f)\n{\n    return f.data[0];\n}\nstatic assert(!is(typeof(compiles!(bar8893(Foo8893(['a','b']))))));\n\n/*******************************************\n    non-Cow struct literals\n*******************************************/\n\nstruct Zadok\n{\n    int[3] z;\n    char[4] s = void;\n    ref int[] fog(ref int[] q) { return q; }\n    int bfg()\n    {\n        z[0] = 56;\n        auto zs = z[];\n        fog(zs) = [56, 6, 8];\n\n        assert(z[0] == 56);\n        assert(z[1] == 61);\n        assert(z[2] == 61);\n\n        assert(zs[0] == 56);\n        assert(zs[1] == 6);\n        return zs[2];\n    }\n}\n\nstruct Vug\n{\n    Zadok p;\n    int[] other;\n}\n\nint quop()\n{\n    int[] heap = new int[5];\n    heap[] = 738;\n    Zadok pong;\n    pong.z = 3;\n    int[] w = pong.z;\n    assert(w[0] == 3);\n    Zadok phong;\n    phong.z = 61;\n    pong = phong;\n    assert(w[0] == 61);\n    Vug b = Vug(Zadok(17, \"abcd\"));\n    b = Vug(Zadok(17, \"abcd\"), heap);\n    b.other[2] = 78;\n    assert(heap[2] == 78);\n    char[] y = b.p.s;\n    assert(y[2] == 'c');\n    phong.s = ['z','x','f', 'g'];\n    w = b.p.z;\n    assert(y[2] == 'c');\n    assert(w[0] == 17);\n    b.p = phong;\n    assert(y[2] == 'f');\n\n    Zadok wok = Zadok(6, \"xyzw\");\n    b.p = wok;\n    assert(y[2] == 'z');\n    b.p = phong;\n    assert(w[0] == 61);\n    Vug q;\n    q.p = pong;\n    return pong.bfg();\n}\n\nstatic assert(quop() == 8);\nstatic assert(quop() == 8); // check for clobbering\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5676\n// tuple assign of struct that has void opAssign\n\nstruct S5676\n{\n    int x;\n    void opAssign(S5676 rhs) { x = rhs.x; }\n}\n\nstruct Tup5676(E...)\n{\n    E g;\n    void foo(E values) { g = values; }\n}\n\nbool ice5676()\n{\n    Tup5676!(S5676) q;\n    q.foo(S5676(3));\n    assert(q.g[0].x == 3);\n    return true;\n}\n\nstatic assert(ice5676());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5682\n// Wrong CTFE with operator overloading\n\nstruct A\n{\n    int n;\n    auto opBinary(string op : \"*\")(A rhs)\n    {\n        return A(n * rhs.n);\n    }\n}\n\nA foo(A[] lhs, A[] rhs)\n{\n    A current;\n    for (size_t k = 0; k < rhs.length; ++k)\n    {\n        current = lhs[k] * rhs[k];\n    }\n    return current;\n}\n\nauto test()\n{\n    return foo([A(1), A(2)], [A(3), A(4)]);\n}\n\nstatic assert(test().n == 8);\n\n/**************************************************\n   Attempt to modify a read-only string literal\n**************************************************/\nstruct Xarg\n{\n    char[] s;\n}\n\nint zfs(int n)\n{\n    char[] m = \"exy\".dup;\n    if (n == 1)\n    {\n        // it's OK to cast to const, then cast back\n        string ss = cast(string)m;\n        m = cast(char[])ss;\n        m[2]='q';\n        return 56;\n    }\n    auto q = Xarg(cast(char[])\"abc\");\n    assert(q.s[1] == 'b');\n    if (n == 2)\n        q.s[1] = 'p';\n    else if (n == 3)\n        q.s[0 .. $] = 'p';\n    char* w = &q.s[2];\n    if (n == 4)\n        *w = 'z';\n    return 76;\n}\n\nstatic assert(!is(typeof(compiles!(zfs(2)))));\nstatic assert(!is(typeof(compiles!(zfs(3)))));\nstatic assert(!is(typeof(compiles!(zfs(4)))));\nstatic assert( is(typeof(compiles!(zfs(1)))));\nstatic assert( is(typeof(compiles!(zfs(5)))));\n\n/**************************************************\n   .dup must protect string literals\n**************************************************/\n\nstring mutateTheImmutable(immutable string _s)\n{\n    char[] s = _s.dup;\n    foreach (ref c; s)\n        c = 'x';\n    return s.idup;\n}\n\nstring doharm(immutable string _name)\n{\n    return mutateTheImmutable(_name[2 .. $].idup);\n}\n\nenum victimLiteral = \"CL_INVALID_CONTEXT\";\n\nenum thug = doharm(victimLiteral);\nstatic assert(victimLiteral == \"CL_INVALID_CONTEXT\");\n\n/**************************************************\n        Use $ in a slice of a dotvar slice\n**************************************************/\n\nint sliceDollar()\n{\n    Xarg z;\n    z.s = new char[20];\n    z.s[] = 'b';\n    z.s = z.s[2 .. $ - 2];\n    z.s[$ - 2] = 'c';\n    return z.s[$ - 2];\n}\nstatic assert(sliceDollar() == 'c');\n\n/**************************************************\n   Variation of 5972 which caused segfault\n**************************************************/\n\nint bug5972crash()\n{\n    char[] z = \"abc\".dup;\n    char[][] a = [null, null];\n    a[0] = z[0 .. 2];\n    a[0][1] = 'q';\n    return 56;\n}\nstatic assert(bug5972crash() == 56);\n\n/**************************************************\n   String slice assignment through ref parameter\n**************************************************/\n\nvoid popft(A)(ref A a)\n{\n    a = a[1 .. $];\n}\n\nint sdfgasf()\n{\n    auto scp = \"abc\".dup;\n    popft(scp);\n    return 1;\n}\nstatic assert(sdfgasf() == 1);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8830\n// slice of slice.ptr\n\nstring bug8830(string s)\n{\n    auto ss = s[1 .. $];\n    return ss.ptr[0 .. 2];\n}\nstatic assert(bug8830(\"hello\") == \"el\");\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8608\n// ICE\n\nvoid bug8608(ref int m) {}\nvoid test8608()\n{\n    int z;\n    int foo(bool b)\n    {\n        if (b)\n            bug8608(z);\n        return 1;\n    }\n    static assert( is(typeof(compiles!(foo(false)))));\n    static assert(!is(typeof(compiles!(foo(true) ))));\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7770\n\nimmutable char[] foo7770 = \"abcde\";\n\nint bug7770a(string a)\n{\n    return 1;\n}\n\nbool bug7770b(char c)\n{\n    return true;\n}\n\nstatic assert(bug7770a(foo7770[0 .. $]));\nstatic assert(bug7770b(foo7770[$ - 2]));\n\nvoid baz7770()\n{\n    static assert(bug7770a(foo7770[0 .. $]));\n    static assert(bug7770b(foo7770[$ - 2]));\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8601\n// ICE\n\ndchar bug8601(dstring s)\n{\n    dstring w = s[1 .. $];\n    return w[0];\n}\n\nenum dstring e8601 = [cast(dchar)'o', 'n'];\nstatic assert(bug8601(e8601) == 'n');\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6015\n\nstruct Foo6015\n{\n    string field;\n}\n\nbool func6015(string input)\n{\n    Foo6015 foo;\n    foo.field = input[0 .. $];\n    assert(foo.field == \"test\");\n    foo.field = \"test2\";\n    assert(foo.field != \"test\");\n    assert(foo.field == \"test2\");\n    return true;\n}\n\nstatic assert(func6015(\"test\"));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6001\n\nvoid bug6001e(ref int[] s)\n{\n    int[] r = s;\n    s ~= 0;\n}\nbool bug6001f()\n{\n    int[] s;\n    bug6001e(s);\n    return true;\n}\nstatic assert(bug6001f());\n\n// Assignment to AAs\n\nvoid blah(int[char] as)\n{\n    auto k = [6: as];\n    as = k[6];\n}\nint blaz()\n{\n    int[char] q;\n    blah(q);\n    return 67;\n}\nstatic assert(blaz() == 67);\n\nvoid bug6001g(ref int[] w)\n{\n    w = [88];\n    bug6001e(w);\n    w[0] = 23;\n}\n\nbool bug6001h()\n{\n    int[] s;\n    bug6001g(s);\n    assert(s.length == 2);\n    assert(s[1] == 0);\n    assert(s[0] == 23);\n    return true;\n}\nstatic assert(bug6001h());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10243\n// wrong code *&arr as ref parameter\n// https://issues.dlang.org/show_bug.cgi?id=10551\n// wrong code (&arr)[0] as ref parameter\n\nvoid bug10243(ref int n)\n{\n    n = 3;\n}\n\nvoid bug10551(int* p)\n{\n    bug10243(p[0]);\n}\n\nbool test10243()\n{\n    int[1] arr;\n    bug10243(*arr.ptr);\n    assert(arr[0] == 3);\n    int[1] arr2;\n    bug10551(arr2.ptr);\n    assert(arr2[0] == 3);\n    int v;\n    bug10551(&v);\n    assert(v == 3);\n    return true;\n}\n\nstatic assert(test10243());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4910\n\nint bug4910(int a)\n{\n    return a;\n}\n\nstatic int var4910;\nstatic assert(!is(typeof(Compiles!(bug4910(var4910)))));\n\nstatic assert(bug4910(123));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5845\n// Regression(2.041)\n\nvoid test5845(ulong cols) {}\n\nuint solve(bool niv, ref ulong cols)\n{\n    if (niv)\n        solve(false, cols);\n    else\n        test5845(cols);\n    return 65;\n}\n\nulong nqueen(int n)\n{\n    ulong cols = 0;\n    return solve(true, cols);\n}\n\nstatic assert(nqueen(2) == 65);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5258\n\nstruct Foo5258 { int x; }\nvoid bar5258(int n, ref Foo5258 fong)\n{\n    if (n)\n        bar5258(n - 1, fong);\n    else\n        fong.x++;\n}\nint bug5258()\n{\n    Foo5258 foo5258 = Foo5258();\n    bar5258(1, foo5258);\n    return 45;\n}\nstatic assert(bug5258() == 45);\n\nstruct Foo5258b { int[2] r; }\nvoid baqopY(int n, ref int[2] fongo)\n{\n    if (n)\n        baqopY(n - 1, fongo);\n    else\n        fongo[0]++;\n}\nint bug5258b()\n{\n    Foo5258b qq;\n    baqopY(1, qq.r);\n    return 618;\n}\nstatic assert(bug5258b() == 618);\n\n// Notice that this case involving reassigning the dynamic array\nstruct Foo5258c { int[] r; }\nvoid baqop(int n, ref int[] fongo)\n{\n    if (n)\n        baqop(n - 1, fongo);\n    else\n    {\n        fongo = new int[20];\n        fongo[0]++;\n    }\n}\nsize_t bug5258c()\n{\n    Foo5258c qq;\n    qq.r = new int[30];\n    baqop(1, qq.r);\n    return qq.r.length;\n}\nstatic assert(bug5258c() == 20);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6049\n\nstruct Bug6049\n{\n    int m;\n    this(int x) {  m = x; }\n    invariant() { }\n}\n\nconst Bug6049[] foo6049 = [Bug6049(6),  Bug6049(17)];\n\nstatic assert(foo6049[0].m == 6);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6052\n\nstruct Bug6052\n{\n    int a;\n}\n\nbool bug6052()\n{\n    Bug6052[2] arr;\n    for (int i = 0; i < 2; ++ i)\n    {\n        Bug6052 el = {i};\n        Bug6052 ek = el;\n        arr[i] = el;\n        el.a = i + 2;\n        assert(ek.a == i);      // ok\n        assert(arr[i].a == i);  // fail\n    }\n    assert(arr[1].a == 1);  // ok\n    assert(arr[0].a == 0);  // fail\n    return true;\n}\n\nstatic assert(bug6052());\n\nbool bug6052b()\n{\n    int[][1] arr;\n    int[1] z = [7];\n    arr[0] = z;\n    assert(arr[0][0] == 7);\n    arr[0] = z;\n    z[0] = 3;\n    assert(arr[0][0] == 3);\n    return true;\n}\n\nstatic assert(bug6052b());\n\nstruct Bug6052c\n{\n    int x;\n    this(int a) { x = a; }\n}\n\nint bug6052c()\n{\n    Bug6052c[] pieces = [];\n    for (int c = 0; c < 2; ++ c)\n        pieces ~= Bug6052c(c);\n    assert(pieces[1].x == 1);\n    assert(pieces[0].x == 0);\n    return 1;\n}\nstatic assert(bug6052c() == 1);\nstatic assert(bug6052c() == 1);\n\n\nstatic assert({\n    Bug6052c[] pieces = [];\n    pieces.length = 2;\n    int c = 0;\n    pieces[0] = Bug6052c(c);\n    ++c;\n    pieces[1] = Bug6052c(c);\n    assert(pieces[0].x == 0);\n    return true;\n}());\n\nstatic assert({\n    int[1][] pieces = [];\n    pieces.length = 2;\n    for (int c = 0; c < 2; ++ c)\n        pieces[c][0] = c;\n    assert(pieces[1][0] == 1);\n    assert(pieces[0][0] == 0);\n    return true;\n}());\n\nstatic assert({\n    Bug6052c[] pieces = [];\n    for (int c = 0; c < 2; ++ c)\n        pieces ~= Bug6052c(c);\n    assert(pieces[1].x == 1);\n    assert(pieces[0].x == 0);\n    return true;\n}());\n\nstatic assert({\n    int[1] z = 7;\n    int[1][] pieces = [z,z];\n    pieces[1][0]=3;\n    assert(pieces[0][0] == 7);\n    pieces = pieces ~ [z,z];\n    pieces[3][0] = 16;\n    assert(pieces[2][0] == 7);\n    pieces = [z,z] ~ pieces;\n    pieces[5][0] = 16;\n    assert(pieces[4][0] == 7);\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6749\n\nstruct CtState\n{\n    string code;\n}\n\nCtState bug6749()\n{\n    CtState[] pieces;\n    CtState r = CtState(\"correct\");\n    pieces ~= r;\n    r = CtState(\"clobbered\");\n    return pieces[0];\n}\nstatic assert(bug6749().code == \"correct\");\n\n/**************************************************\n    Index + slice assign to function returns\n**************************************************/\n\nint[] funcRetArr(int[] a)\n{\n    return a;\n}\n\nint testFuncRetAssign()\n{\n    int[] x = new int[20];\n    funcRetArr(x)[2] = 4;\n    assert(x[2] == 4);\n    funcRetArr(x)[] = 27;\n    assert(x[15] == 27);\n    return 5;\n}\nstatic assert(testFuncRetAssign() == 5);\n\nint keyAssign()\n{\n    int[int] pieces;\n    pieces[3] = 1;\n    pieces.keys[0] = 4;\n    pieces.values[0] = 27;\n    assert(pieces[3] == 1);\n    return 5;\n}\nstatic assert(keyAssign() == 5);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6054\n// AA literals\n\nenum x6054 = {\n    auto p = {\n        int[string] pieces;\n        pieces[['a'].idup] = 1;\n        return pieces;\n    }();\n    return p;\n}();\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6077\n\nenum bug6077 = {\n    string s;\n    string t;\n    return s ~ t;\n}();\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6078\n// Pass null array by ref\n\nstruct Foo6078\n{\n    int[] bar;\n}\n\nstatic assert({\n    Foo6078 f;\n    int i;\n    foreach (ref e; f.bar)\n    {\n        i += e;\n    }\n    return i;\n}() == 0);\n\nint bug6078(ref int[] z)\n{\n    int[] q = z;\n    return 2;\n}\n\nstatic assert({\n    Foo6078 f;\n    return bug6078(f.bar);\n}() == 2);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6079\n// Array bounds checking\n\nstatic assert(!is(typeof(compiles!({\n    int[] x = [1, 2, 3, 4];\n    x[4] = 1;\n    return true;\n}()\n))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6100\n\nstruct S6100\n{\n    int a;\n}\n\nS6100 init6100(int x)\n{\n    S6100 s = S6100(x);\n    return s;\n}\n\nstatic const S6100[2] s6100a = [init6100(1), init6100(2)];\nstatic assert(s6100a[0].a == 1);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4825\n// failed with -inline\n\nint a4825()\n{\n    int r;\n    return r;\n}\n\nint b4825()\n{\n    return a4825();\n}\n\nvoid c4825()\n{\n    void d()\n    {\n        auto e = b4825();\n    }\n    static const int f = b4825();\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5708\n// failed with -inline\n\nstring b5708(string s) { return s; }\nstring a5708(string s) { return b5708(s); }\n\nvoid bug5708()\n{\n    void m() { a5708(\"lit\"); }\n    static assert(a5708(\"foo\") == \"foo\");\n    static assert(a5708(\"bar\") == \"bar\");\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6120\n// failed with -inline\n\nstruct Bug6120(T)\n{\n    this(int x) { }\n}\nstatic assert({\n    auto s = Bug6120!int(0);\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6123\n// failed with -inline\n\nstruct Bug6123(T)\n{\n    void f() {}\n    // can also trigger if the struct is normal but f is template\n}\nstatic assert({\n    auto piece = Bug6123!int();\n    piece.f();\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6053\n// ICE involving pointers\n\nstatic assert({\n    int* a = null;\n    assert(a is null);\n    assert(a == null);\n    return true;\n}());\n\nstatic assert({\n    int b;\n    int* a = &b;\n    assert(a !is null);\n    *a = 7;\n    assert(b == 7);\n    assert(*a == 7);\n    return true;\n}());\n\nint dontbreak6053()\n{\n    auto q = &dontbreak6053;\n    void caz() {}\n    auto tr = &caz;\n    return 5;\n}\nstatic assert(dontbreak6053());\n\nstatic assert({\n    int a;\n    *(&a) = 15;\n    assert(a == 15);\n    assert(*(&a) == 15);\n    return true;\n}());\n\nstatic assert({\n    int a = 5, b = 6, c = 2;\n    assert(*(c ? &a : &b) == 5);\n    assert(*(!c ? &a : &b) == 6);\n    return true;\n}());\n\nstatic assert({\n    int a, b, c;\n    (c ? a : b) = 1;\n    return true;\n}());\n\nstatic assert({\n    int a, b, c = 1;\n    int* p = &a;\n    (c ? *p : b) = 51;\n    assert(a == 51);\n    return true;\n}());\n\n/**************************************************\n  Pointer arithmetic, dereference, and comparison\n**************************************************/\n\n// dereference null pointer\nstatic assert(!is(typeof(compiles!({\n    int a, b, c = 1;\n    int* p;\n    (c ? *p : b) = 51;\n    return 6;\n}()\n))));\nstatic assert(!is(typeof(compiles!({\n    int* a = null;\n    assert(*a != 6);\n    return 72;\n}()\n))));\n\n// cannot <, > compare pointers to different arrays\nstatic assert(!is(typeof(compiles!({\n    int[5] a, b;\n    bool c = (&a[0] > &b[0]);\n    return 72;\n}()\n))));\n\n// can ==, is, !is, != compare pointers for different arrays\nstatic assert({\n    int[5] a;\n    int[5] b;\n    assert(!(&a[0] == &b[0]));\n    assert(&a[0] != &b[0]);\n    assert(!(&a[0] is &b[0]));\n    assert(&a[0] !is &b[0]);\n    return 72;\n}());\n\nstatic assert({\n    int[5] a;\n    a[0] = 25;\n    a[1] = 5;\n    int* b = &a[1];\n    assert(*b == 5);\n    *b = 34;\n    int c = *b;\n    *b += 6;\n    assert(b == &a[1]);\n    assert(b != &a[0]);\n    assert(&a[0] < &a[1]);\n    assert(&a[0] <= &a[1]);\n    assert(!(&a[0] >= &a[1]));\n    assert(&a[4] > &a[0]);\n    assert(c == 34);\n    assert(*b == 40);\n    assert(a[1] == 40);\n    return true;\n}());\n\nstatic assert({\n    int[12] x;\n    int* p = &x[10];\n    int* q = &x[4];\n    return p - q;\n}() == 6);\n\nstatic assert({\n    int[12] x;\n    int* p = &x[10];\n    int* q = &x[4];\n    q = p;\n    assert(p == q);\n    q = &x[4];\n    assert(p != q);\n    q = q + 6;\n    assert(q is p);\n    return 6;\n}() == 6);\n\nstatic assert({\n    int[12] x;\n    int[] y = x[2 .. 8];\n    int* p = &y[4];\n    int* q = &x[6];\n    assert(p == q);\n    p = &y[5];\n    assert(p > q);\n    p = p + 5; // OK, as long as we don't dereference\n    assert(p > q);\n    return 6;\n}() == 6);\n\nstatic assert({\n    char[12] x;\n    const(char)* p = \"abcdef\";\n    const (char)* q = p;\n    q = q + 2;\n    assert(*q == 'c');\n    assert(q > p);\n    assert(q - p == 2);\n    assert(p - q == -2);\n    q = &x[7];\n    p = &x[1];\n    assert(q>p);\n    return 6;\n}() == 6);\n\n// Relations involving null pointers\nbool nullptrcmp()\n{\n    // null tests\n    void* null1 = null, null2 = null;\n    int x = 2;\n    void* p = &x;\n    assert(null1 == null2);\n    assert(null1 is null2);\n    assert(null1 <= null2);\n    assert(null1 >= null2);\n    assert(!(null1 > null2));\n    assert(!(null2 > null1));\n    assert(null1 != p);\n    assert(null1 !is p);\n    assert(p != null1);\n    assert(p !is null1);\n    assert(null1 <= p);\n    assert(p >= null2);\n    assert(p > null1);\n    assert(!(null1 > p));\n    return true;\n}\nstatic assert(nullptrcmp());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10840\n// null pointer in dotvar\n\nstruct Data10840\n{\n    bool xxx;\n}\n\nstruct Bug10840\n{\n    Data10840* _data;\n}\n\nbool bug10840(int n)\n{\n    Bug10840 stack;\n    if (n == 1)\n    {\n        // detect deref through null pointer\n        return stack._data.xxx;\n    }\n    // Wrong-code for ?:\n    return stack._data ? false : true;\n}\n\nstatic assert(bug10840(0));\nstatic assert(!is(typeof(Compileable!(bug10840(1)))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8216\n// ptr inside a pointer range\n\n// Four-pointer relations. Return true if [p1 .. p2] points inside [q1 .. q2]\n// (where the end points don't coincide).\nbool ptr4cmp(void* p1, void* p2, void* q1, void* q2)\n{\n// Each compare can be written with <, <=, >, or >=.\n// Either && or || can be used, giving 32 permutations.\n// Additionally each compare can be negated with !, yielding 128 in total.\n    bool b1 = (p1 > q1 && p2 <= q2);\n    bool b2 = (p1 > q1 && p2 < q2);\n    bool b3 = (p1 >= q1 && p2 <= q2);\n    bool b4 = (p1 >= q1 && p2 < q2);\n\n    bool b5 = (q1 <= p1 && q2 > p2);\n    bool b6 = (q1 <= p1 && q2 >= p2);\n    bool b7 = (p2 <= q2 && p1 > q1);\n    bool b8 = (!(p1 <= q1) && p2 <= q2);\n    bool b9 = (!(p1 <= q1) && !(p2 > q2));\n    bool b10 = (!!!(p1 <= q1) && !(p2 > q2));\n\n    assert(b1 == b2 && b1 == b3 && b1 == b4 && b1 == b5 && b1 == b6);\n    assert(b1 == b7 && b1 == b8 && b1 == b9 && b1 == b10);\n\n    bool c1 = (p1 <= q1 || p2 > q2);\n    assert(c1 == !b1);\n    bool c2 = (p1 < q1 || p2 >= q2);\n    bool c3 = (!(q1 <= p1) || !(q2 >= p2));\n    assert(c1 == c2 && c1 == c3);\n    return b1;\n}\n\nbool bug8216()\n{\n    int[4] a;\n    int[13] b;\n    int v;\n    int* p = &v;\n    assert(!ptr4cmp(&a[0], &a[3], p, p));\n    assert(!ptr4cmp(&b[2], &b[9], &a[1], &a[2]));\n    assert(!ptr4cmp(&b[1], &b[9], &b[2], &b[8]));\n    assert( ptr4cmp(&b[2], &b[8], &b[1], &b[9]));\n    return 1;\n}\nstatic assert(bug8216());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6517\n// ptr++, ptr--\n\nint bug6517()\n{\n    int[] arr = [1, 2, 3];\n    auto startp = arr.ptr;\n    auto endp = arr.ptr + arr.length;\n\n    for (; startp < endp; startp++) {}\n    startp = arr.ptr;\n    assert(startp++ == arr.ptr);\n    assert(startp != arr.ptr);\n    assert(startp-- != arr.ptr);\n    assert(startp == arr.ptr);\n\n    return 84;\n}\nstatic assert(bug6517() == 84);\n\n/**************************************************\n  Out-of-bounds pointer assignment and deference\n**************************************************/\n\nint ptrDeref(int ofs, bool wantDeref)\n{\n    int[5] a;\n    int* b = &a[0];\n    b = b + ofs; // OK\n    if (wantDeref)\n        return *b; // out of bounds\n    return 72;\n}\n\nstatic assert(!is(typeof(compiles!(ptrDeref(-1, true)))));\nstatic assert( is(typeof(compiles!(ptrDeref(4, true)))));\nstatic assert( is(typeof(compiles!(ptrDeref(5, false)))));\nstatic assert(!is(typeof(compiles!(ptrDeref(5, true)))));\nstatic assert(!is(typeof(compiles!(ptrDeref(6, false)))));\nstatic assert(!is(typeof(compiles!(ptrDeref(6, true)))));\n\n/**************************************************\n  Pointer +=\n**************************************************/\nstatic assert({\n    int[12] x;\n    int zzz;\n    assert(&zzz);\n    int* p = &x[10];\n    int* q = &x[4];\n    q = p;\n    assert(p == q);\n    q = &x[4];\n    assert(p != q);\n    q += 4;\n    assert(q == &x[8]);\n    q = q - 2;\n    q = q + 4;\n    assert(q is p);\n    return 6;\n}() == 6);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5615\n\nconst(char)[] passthrough(const(char)[] x)\n{\n    return x;\n}\n\nsizediff_t checkPass(Char1)(const(Char1)[] s)\n{\n    const(Char1)[] balance = s[1 .. $];\n    return passthrough(balance).ptr - s.ptr;\n}\nstatic assert(checkPass(\"foobar\") == 1);\n\n/**************************************************\n  Pointers must not escape from CTFE\n**************************************************/\n\nstruct Toq\n{\n    const(char)* m;\n}\n\nToq ptrRet(bool b)\n{\n    string x = \"abc\";\n    return Toq(b ? x[0 .. 1].ptr : null);\n}\n\nstatic assert(is(typeof(compiles!({\n    enum Toq boz = ptrRet(false); // OK - ptr is null\n    Toq z = ptrRet(true); // OK -- ptr doesn't escape\n    return 4;\n}()\n))));\n\nstatic assert(!is(typeof(compiles!({\n    enum Toq boz = ptrRet(true); // fail - ptr escapes\n    return 4;\n}()\n))));\n\n/**************************************************\n    Pointers to struct members\n**************************************************/\n\nstruct Qoz\n{\n    int w;\n    int[3] yof;\n}\n\nstatic assert({\n    int[3] gaz;\n    gaz[2] = 3156;\n    Toq z = ptrRet(true);\n    auto p = z.m;\n    assert(*z.m == 'a');\n    assert(*p == 'a');\n    auto q = &z.m;\n    assert(*q == p);\n    assert(**q == 'a');\n    Qoz g = Qoz(2, [5, 6, 7]);\n    auto r = &g.w;\n    assert(*r == 2);\n    r = &g.yof[1];\n    assert(*r == 6);\n    g.yof[0] = 15;\n    ++r;\n    assert(*r == 7);\n    r -= 2;\n    assert(*r == 15);\n    r = &gaz[0];\n    r += 2;\n    assert(*r == 3156);\n    return *p;\n}() == 'a');\n\nstruct AList\n{\n    AList* next;\n    int value;\n    static AList* newList()\n    {\n        AList[] z = new AList[1];\n        return &z[0];\n    }\n    static AList* make(int i, int j)\n    {\n        auto r = newList();\n        r.next = (new AList[1]).ptr;\n        r.value = 1;\n        AList* z = r.next;\n        (*z).value = 2;\n        r.next.value = j;\n        assert(r.value == 1);\n        assert(r.next.value == 2);\n        r.next.next = &(new AList[1])[0];\n        assert(r.next.next != null);\n        assert(r.next.next);\n        r.next.next.value = 3;\n        assert(r.next.next.value == 3);\n        r.next.next = newList();\n        r.next.next.value = 9;\n        return r;\n    }\n    static int checkList()\n    {\n        auto r = make(1,2);\n        assert(r.value == 1);\n        assert(r.next.value == 2);\n        assert(r.next.next.value == 9);\n        return 2;\n    }\n}\n\nstatic assert(AList.checkList() == 2);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7194\n// pointers as struct members\n\nstruct S7194 { int* p, p2; }\n\nint f7194()\n{\n    assert(S7194().p == null);\n    assert(!S7194().p);\n    assert(S7194().p == S7194().p2);\n    S7194 s = S7194();\n    assert(!s.p);\n    assert(s.p == null);\n    assert(s.p == s.p2);\n    int x;\n    s.p = &x;\n    s.p2 = s.p;\n    assert(s.p == &x);\n    return 0;\n}\n\nint g7194()\n{\n    auto s = S7194();\n    assert(s.p);  // should fail\n    return 0;\n}\n\nstatic assert(f7194() == 0);\nstatic assert(!is(typeof(compiles!(g7194()))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7248\n// recursive struct pointers in array\n\nstruct S7248 { S7248* ptr; }\n\nbool bug7248()\n{\n    S7248[2] sarr;\n    sarr[0].ptr = &sarr[1];\n    sarr[0].ptr = null;\n    S7248* t = sarr[0].ptr;\n    return true;\n}\nstatic assert(bug7248());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7216\n// calling a struct pointer member\n\nstruct S7216\n{\n    S7216* p;\n    int t;\n\n    void f() { }\n    void g() { ++t; }\n}\n\nbool bug7216()\n{\n    S7216 s0, s1;\n    s1.t = 6;\n    s0.p = &s1;\n    s0.p.f();\n    s0.p.g();\n    assert(s1.t == 7);\n    return true;\n}\n\nstatic assert(bug7216());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10858\n// Wrong code with array of pointers\n\nbool bug10858()\n{\n    int*[4] x;\n    x[0] = null;\n    assert(x[0] == null);\n    return true;\n}\nstatic assert(bug10858());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12528\n// painting inout type for value type literals\n\ninout(T)[] dup12528(T)(inout(T)[] a)\n{\n    inout(T)[] res;\n    foreach (ref e; a)\n        res ~= e;\n    return res;\n}\n\nenum arr12528V1 = dup12528([0]);\nenum arr12528V2 = dup12528([0, 1]);\nstatic assert(arr12528V1 == [0]);\nstatic assert(arr12528V2 == [0, 1]);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9745\n// Allow pointers to static variables\n\nshared int x9745;\nshared int[5] y9745;\n\nshared(int)* bug9745(int m)\n{\n    auto k = &x9745;\n    auto j = &x9745;\n    auto p = &y9745[0];\n    auto q = &y9745[3];\n    assert(j - k == 0);\n    assert(j == k);\n    assert(q - p == 3);\n    --q;\n    int a = 0;\n    assert(p + 2 == q);\n    if (m == 7)\n    {\n        auto z1 = y9745[0 .. 2]; // slice global pointer\n    }\n    if (m == 8)\n        p[1] = 7; // modify through a pointer\n    if (m == 9)\n         a = p[1]; // read from a pointer\n    if (m == 0)\n        return &x9745;\n    return &y9745[1];\n}\n\nint test9745(int m)\n{\n    bug9745(m);\n    // type painting\n    shared int* w = bug9745(0);\n    return 1;\n}\n\nshared int* w9745a = bug9745(0);\nshared int* w9745b = bug9745(1);\nstatic assert( is(typeof(compiles!(test9745(6)))));\nstatic assert(!is(typeof(compiles!(test9745(7)))));\nstatic assert(!is(typeof(compiles!(test9745(8)))));\nstatic assert(!is(typeof(compiles!(test9745(9)))));\n\n// pointers cast from an absolute address\n// (mostly applies to fake pointers, eg Windows HANDLES)\nbool test9745b()\n{\n    void* b6 = cast(void*)0xFEFEFEFE;\n    void* b7 = cast(void*)0xFEFEFEFF;\n    assert(b6 is b6);\n    assert(b7 != b6);\n    return true;\n}\nstatic assert(test9745b());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9364\n// ICE with pointer to local struct\n\nstruct S9364\n{\n    int i;\n}\n\nbool bug9364()\n{\n    S9364 s;\n    auto k = (&s).i;\n    return 1;\n}\n\nstatic assert(bug9364());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10251\n// Pointers to const globals\n\nstatic const int glob10251 = 7;\n\nconst(int)* bug10251()\n{\n   return &glob10251;\n}\n\nstatic a10251 = &glob10251; //  OK\nstatic b10251 = bug10251();\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4065\n// [CTFE] AA \"in\" operator doesn't work\n\nbool bug4065(string s)\n{\n    enum int[string] aa = [\"aa\":14, \"bb\":2];\n    int* p = s in aa;\n    if (s == \"aa\")\n        assert(*p == 14);\n    else if (s == \"bb\")\n        assert(*p == 2);\n    else\n        assert(!p);\n    int[string] zz;\n    assert(!(\"xx\" in zz));\n    bool c = !p;\n    return cast(bool)(s in aa);\n}\n\nstatic assert(!bug4065(\"xx\"));\nstatic assert( bug4065(\"aa\"));\nstatic assert( bug4065(\"bb\"));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12689\n// assigning via pointer from 'in' expression\n\nint g12689()\n{\n    int[int] aa;\n    aa[1] = 13;\n    assert(*(1 in aa) == 13);\n    *(1 in aa) = 42;\n    return aa[1];\n}\nstatic assert(g12689() == 42);\n\n/**************************************************\n    Pointers in ? :\n**************************************************/\n\nstatic assert({\n    int[2] x;\n    int* p = &x[1];\n    return p ? true: false;\n}());\n\n/**************************************************\n    Pointer slicing\n**************************************************/\n\nint ptrSlice()\n{\n    auto arr = new int[5];\n    int* x = &arr[0];\n    int[] y = x[0 .. 5];\n    x[1 .. 3] = 6;\n    ++x;\n    x[1 .. 3] = 14;\n    assert(arr[1] == 6);\n    assert(arr[2] == 14);\n    //x[-1 .. 4] = 5;   // problematic because negative lower boundary will throw RangeError in runtime\n    (x - 1)[0 .. 3] = 5;\n    int[] z = arr[1 .. 2];\n    z.length = 4;\n    z[$ - 1] = 17;\n    assert(arr.length == 5);\n    return 2;\n}\nstatic assert(ptrSlice() == 2);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6344\n// create empty slice from null pointer\n\nstatic assert({\n    char* c = null;\n    auto m = c[0 .. 0];\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8365\n// block assignment of enum arrays\n\nenum E8365 { first = 7, second, third, fourth }\nstatic assert({ E8365[2]       x; return x[0];       }() == E8365.first);\nstatic assert({ E8365[2][2]    x; return x[0][0];    }() == E8365.first);\nstatic assert({ E8365[2][2][2] x; return x[0][0][0]; }() == E8365.first);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4448\n// labelled break + continue\n\nint bug4448()\n{\n    int n = 2;\nL1:\n    do\n    {\n        switch(n)\n        {\n        case 5:\n            return 7;\n        default:\n            n = 5;\n            break L1;\n        }\n        int w = 7;\n    } while (0);\n    return 3;\n}\nstatic assert(bug4448() == 3);\n\nint bug4448b()\n{\n    int n = 2;\nL1:\n    for (n = 2; n < 5; ++n)\n    {\n        for (int m = 1; m < 6; ++m)\n        {\n            if (n < 3)\n            {\n                assert(m == 1);\n                continue L1;\n            }\n        }\n        break;\n    }\n    return 3;\n}\nstatic assert(bug4448b() == 3);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6985\n// non-constant case\n\nint bug6985(int z)\n{\n    int q = z * 2 - 6;\n    switch(z)\n    {\n    case q:\n        q = 87;\n        break;\n    default:\n    }\n    return q;\n}\nstatic assert(bug6985(6) == 87);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6281\n// [CTFE] A null pointer '!is null' returns 'true'\n\nstatic assert(!{\n    auto p = null;\n    return p !is null;\n}());\n\nstatic assert(!{\n    auto p = null;\n    return p != null;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6331\n// evaluate SliceExp on if condition\n\nbool bug6331(string s)\n{\n    if (s[0 .. 1])\n        return true;\n    return false;\n}\nstatic assert(bug6331(\"str\"));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6283\n// assign to AA with slice as index\n\nstatic assert({\n    immutable p = \"pp\";\n    int[string] pieces = [p: 0];\n    pieces[\"qq\"] = 1;\n    return true;\n}());\n\nstatic assert({\n    immutable renames = [0: \"pp\"];\n    int[string] pieces;\n    pieces[true ? renames[0] : \"qq\"] = 1;\n    pieces[\"anything\"] = 1;\n    return true;\n}());\n\nstatic assert({\n    immutable qq = \"qq\";\n    string q = qq;\n    int[string] pieces = [\"a\":1];\n    pieces[q] = 0;\n    string w = \"ab\";\n    int z = pieces[w[0 .. 1]];\n    assert(z == 1);\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6282\n// dereference 'in' of an AA\n\nstatic assert({\n    int[] w = new int[4];\n    w[2] = 6;\n    auto c = [5: w];\n    auto kk  = (*(5 in c))[2];\n    (*(5 in c))[2] = 8;\n    (*(5 in c))[1 .. $ - 2] = 4;\n    auto a = [4:\"1\"];\n    auto n = *(4 in a);\n    return n;\n}() == \"1\");\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6337\n// member function call on struct literal\n\nstruct Bug6337\n{\n    int k;\n    void six()\n    {\n        k = 6;\n    }\n    int ctfe()\n    {\n        six();\n        return k;\n    }\n}\nstatic assert(Bug6337().ctfe() == 6);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6603\n// call manifest function pointer\n\nint f6603(int a) { return a + 5; }\nenum bug6603 = &f6603;\nstatic assert(bug6603(6) == 11);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6375\n\nstruct D6375\n{\n    int[] arr;\n}\nA6375 a6375(int[] array)\n{\n    return A6375(array);\n}\nstruct A6375\n{\n    D6375* _data;\n    this(int[] arr)\n    {\n        _data = new D6375;\n        _data.arr = arr;\n    }\n    int[] data()\n    {\n        return _data.arr;\n    }\n}\nstatic assert({\n    int[] a = [1, 2];\n    auto app2 = a6375(a);\n    auto data = app2.data();\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6280\n// Converting pointers to bool\n\nstatic assert({\n    if ((0 in [0:0])) {}\n    if ((0 in [0:0]) && (0 in [0:0])) {}\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6276\n// ~=\n\nstruct Bug6276\n{\n    int[] i;\n}\nstatic assert({\n    Bug6276 foo;\n    foo.i ~= 1;\n    foo.i ~= 2;\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6374\n// ptr[n] = x, x = ptr[n]\n\nstatic assert({\n    int[] arr = [1];\n    arr.ptr[0] = 2;\n    auto k = arr.ptr[0];\n    assert(k == 2);\n    return arr[0];\n}() == 2);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6306\n// recursion and local variables\n\nvoid recurse6306()\n{\n    bug6306(false);\n}\n\nbool bug6306(bool b)\n{\n    int x = 0;\n    if (b)\n        recurse6306();\n    assert(x == 0);\n    x = 1;\n    return true;\n}\nstatic assert(bug6306(true));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6386\n// ICE on unsafe pointer cast\n\nstatic assert(!is(typeof(compiles!({\n    int x = 123;\n    int* p = &x;\n    float z;\n    float* q = cast(float*)p;\n    return true;\n}()\n))));\n\nstatic assert({\n    int[] x = [123, 456];\n    int* p = &x[0];\n    auto m = cast(const(int)*)p;\n    auto q = p;\n    return *q;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6420\n// ICE on dereference of invalid pointer\n\nstatic assert({\n    // Should compile, but pointer can't be dereferenced\n    int x = 123;\n    int* p = cast(int*)x;\n    auto q = cast(char*)x;\n    auto r = cast(char*)323;\n    // Valid const-changing cast\n    const float *m = cast(immutable float*)[1.2f,2.4f,3f];\n    return true;\n}()\n);\n\nstatic assert(!is(typeof(compiles!({\n    int x = 123;\n    int* p = cast(int*)x;\n    int a = *p;\n    return true;\n}()\n))));\n\nstatic assert(!is(typeof(compiles!({\n    int* p = cast(int*)123;\n    int a = *p;\n    return true;\n}()\n))));\n\nstatic assert(!is(typeof(compiles!({\n    auto k = cast(int*)45;\n    *k = 1;\n    return true;\n}()\n))));\n\nstatic assert(!is(typeof(compiles!({\n    *cast(float*)\"a\" = 4.0;\n    return true;\n}()\n))));\n\nstatic assert(!is(typeof(compiles!({\n    float f = 2.8;\n    long *p = &f;\n    return true;\n}()\n))));\n\nstatic assert(!is(typeof(compiles!({\n    long *p = cast(long*)[1.2f, 2.4f, 3f];\n    return true;\n}()\n))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6250\n// deref pointers to array\n\nint[]* simple6250(int[]* x) { return x; }\n\nvoid swap6250(int[]* lhs, int[]* rhs)\n{\n    int[] kk = *lhs;\n    assert(simple6250(lhs) == lhs);\n    lhs = simple6250(lhs);\n    assert(kk[0] == 18);\n    assert((*lhs)[0] == 18);\n    assert((*rhs)[0] == 19);\n    *lhs = *rhs;\n    assert((*lhs)[0] == 19);\n    *rhs = kk;\n    assert(*rhs == kk);\n    assert(kk[0] == 18);\n    assert((*rhs)[0] == 18);\n}\n\nint ctfeSort6250()\n{\n     int[][2] x;\n     int[3] a = [17, 18, 19];\n     x[0] = a[1 .. 2];\n     x[1] = a[2 .. $];\n     assert(x[0][0] == 18);\n     assert(x[0][1] == 19);\n     swap6250(&x[0], &x[1]);\n     assert(x[0][0] == 19);\n     assert(x[1][0] == 18);\n     a[1] = 57;\n     assert(x[0][0] == 19);\n     return x[1][0];\n}\n\nstatic assert(ctfeSort6250() == 57);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6672\n// circular references in array\n\nvoid bug6672(ref string lhs, ref string rhs)\n{\n    auto tmp = lhs;\n    lhs = rhs;\n    rhs = tmp;\n}\n\nstatic assert({\n    auto kw = [\"a\"];\n    bug6672(kw[0], kw[0]);\n    return true;\n}());\n\nvoid slice6672(ref string[2] agg, ref string lhs)\n{\n    agg[0 .. $] = lhs;\n}\n\nstatic assert({\n    string[2] kw = [\"a\", \"b\"];\n    slice6672(kw, kw[0]);\n    assert(kw[0] == \"a\");\n    assert(kw[1] == \"a\");\n    return true;\n}());\n\n// an unrelated rejects-valid bug\nstatic assert({\n    string[2] kw = [\"a\", \"b\"];\n    kw[0 .. 2] = \"x\";\n    return true;\n}());\n\nvoid bug6672b(ref string lhs, ref string rhs)\n{\n    auto tmp = lhs;\n    assert(tmp == \"a\");\n    lhs = rhs;\n    assert(tmp == \"a\");\n    rhs = tmp;\n}\n\nstatic assert({\n    auto kw=[\"a\", \"b\"];\n    bug6672b(kw[0], kw[1]);\n    assert(kw[0] == \"b\");\n    assert(kw[1] == \"a\");\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6399\n// (*p).length = n\n\nstruct A6399\n{\n    int[] arr;\n    int subLen()\n    {\n        arr = [1, 2, 3, 4, 5];\n        arr.length -= 1;\n        return cast(int)arr.length;\n    }\n}\n\nstatic assert({\n    A6399 a;\n    return a.subLen();\n}() == 4);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7789\n// (*p).length++ where *p is null\n\nstruct S7789\n{\n    size_t foo()\n    {\n        _ary.length += 1;\n        return _ary.length;\n    }\n\n    int[] _ary;\n}\n\nstatic assert(S7789().foo());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6418\n// member named 'length'\n\nstruct Bug6418\n{\n    size_t length() { return 189; }\n}\nstatic assert(Bug6418.init.length == 189);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4021\n// rehash\n\nbool bug4021()\n{\n    int[int] aa = [1: 1];\n    aa.rehash;\n    return true;\n}\nstatic assert(bug4021());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11629\n// crash on AA.rehash\n\nstruct Base11629\n{\n    alias T = ubyte, Char = char;\n    alias String = immutable(Char)[];\n\n    const Char[T] toChar;\n\n    this(int _dummy)\n    {\n        Char[T] toCharTmp = [0:'A'];\n\n        toChar = toCharTmp.rehash;\n    }\n}\nenum ct11629 = Base11629(4);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3512\n// foreach (dchar; string)\n// https://issues.dlang.org/show_bug.cgi?id=6558\n// foreach (int, dchar; string)\n\nbool test3512()\n{\n    string s = \"öhai\";\n    int q = 0;\n\n    foreach (wchar c; s)\n    {\n        if (q == 2)\n            assert(c == 'a');\n        ++q;\n    }\n    assert(q == 4);\n\n    // _aApplycd1\n    foreach (dchar c; s)\n    {\n        ++q;\n        if (c == 'h')\n            break;\n    }\n    assert(q == 6);\n\n    // _aApplycw2\n    foreach (int i, wchar c; s)\n    {\n        assert(i >= 0 && i < s.length);\n    }\n\n    // _aApplycd2\n    foreach (int i, dchar c; s)\n    {\n        assert(i >= 0 && i < s.length);\n    }\n\n    wstring w = \"xüm\";\n\n    // _aApplywc1\n    foreach (char c; w)\n    {\n        ++q;\n    }\n    assert(q == 10);\n\n    // _aApplywd1\n    foreach (dchar c; w)\n    {\n        ++q;\n    }\n    assert(q == 13);\n\n    // _aApplywc2\n    foreach (int i, char c; w)\n    {\n        assert(i >= 0 && i < w.length);\n    }\n\n    // _aApplywd2\n    foreach (int i, dchar c; w)\n    {\n        assert(i >= 0 && i < w.length);\n    }\n\n    dstring d = \"yäq\";\n\n    // _aApplydc1\n    q = 0;\n    foreach (char c; d)\n    {\n        ++q;\n    }\n    assert(q == 4);\n\n    // _aApplydw1\n    q = 0;\n    foreach (wchar c; d)\n    {\n        ++q;\n    }\n    assert(q == 3);\n\n    // _aApplydc2\n    foreach (int i, char c; d)\n    {\n        assert(i >= 0 && i < d.length);\n    }\n    // _aApplydw2\n    foreach (int i, wchar c; d)\n    {\n        assert(i >= 0 && i < d.length);\n    }\n\n    dchar[] dr = \"squop\"d.dup;\n\n    foreach (int n, char c; dr)\n    {\n        if (n == 2)\n            break;\n        assert(c != 'o');\n    }\n\n    // _aApplyRdc1\n    foreach_reverse (char c; dr)\n    {}\n\n    // _aApplyRdw1\n    foreach_reverse (wchar c; dr)\n    {}\n\n    // _aApplyRdc2\n    foreach_reverse (int n, char c; dr)\n    {\n        if (n == 4)\n            break;\n        assert(c != 'o');\n    }\n\n    // _aApplyRdw2\n    foreach_reverse (int i, wchar c; dr)\n    {\n        assert(i >= 0 && i < dr.length);\n    }\n\n    q = 0;\n    wstring w2 = ['x', 'ü', 'm']; // foreach over array literals\n    foreach_reverse (int n, char c; w2)\n    {\n        ++q;\n        if (c == 'm') assert(n == 2 && q == 1);\n        if (c == 'x') assert(n == 0 && q == 4);\n    }\n    return true;\n}\nstatic assert(test3512());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6510\n// ICE only with -inline\n\nstruct Stack6510\n{\n    struct Proxy\n    {\n        void shrink() {}\n    }\n    Proxy stack;\n    void pop()\n    {\n        stack.shrink();\n    }\n}\n\nint bug6510()\n{\n    static int used()\n    {\n        Stack6510 junk;\n        junk.pop();\n        return 3;\n    }\n    return used();\n}\n\nvoid test6510()\n{\n    static assert(bug6510() == 3);\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6511\n// arr[] shouldn't make a copy\n\nT bug6511(T)()\n{\n    T[1] a = [1];\n    a[] += a[];\n    return a[0];\n}\nstatic assert(bug6511!ulong() == 2);\nstatic assert(bug6511!long() == 2);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6512\n// new T[][]\n\nbool bug6512(int m)\n{\n    auto x = new int[2][][](m, 5);\n    assert(x.length == m);\n    assert(x[0].length == 5);\n    assert(x[0][0].length == 2);\n    foreach (i; 0.. m)\n        foreach (j; 0 .. 5)\n            foreach (k; 0 .. 2)\n                x[i][j][k] = k + j*10 + i*100;\n    foreach (i; 0.. m)\n        foreach (j; 0 .. 5)\n            foreach (k; 0 .. 2)\n                assert(x[i][j][k] == k + j*10 + i*100);\n    return true;\n}\nstatic assert(bug6512(3));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6516\n// ICE(constfold.c)\n\ndstring bug6516()\n{\n    return cast(dstring)new dchar[](0);\n}\n\nstatic assert(bug6516() == \"\"d);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6727\n// ICE(interpret.c)\n\nconst(char)* ice6727(const(char)* z) { return z; }\nstatic assert({\n    auto q = ice6727(\"a\".dup.ptr);\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6721\n// Cannot get pointer to start of char[]\n\nstatic assert({\n    char[] c1 = \"\".dup;\n    auto p = c1.ptr;\n    string c2 = \"\";\n    auto p2 = c2.ptr;\n    return 6;\n}() == 6);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6693\n// Assign to null AA\n\nstruct S6693\n{\n    int[int] m;\n}\n\nstatic assert({\n    int[int][int] aaa;\n    aaa[3][1] = 4;\n    int[int][3] aab;\n    aab[2][1] = 4;\n    S6693 s;\n    s.m[2] = 4;\n    return 6693;\n}() == 6693);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7602\n// Segfault AA.keys on null AA\n\nstring[] test7602()\n{\n    int[string] array;\n    return array.keys;\n}\n\nenum bug7602 = test7602();\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6739\n// Nested AA assignment\n\nstatic assert({\n    int[int][int][int] aaa;\n    aaa[3][1][6] = 14;\n    return aaa[3][1][6];\n}() == 14);\n\nstatic assert({\n    int[int][int] aaa;\n    aaa[3][1] = 4;\n    aaa[3][3] = 3;\n    aaa[1][5] = 9;\n    auto kk = aaa[1][5];\n    return kk;\n}() == 9);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6751\n// ref AA assignment\n\nvoid bug6751(ref int[int] aa)\n{\n    aa[1] = 2;\n}\n\nstatic assert({\n    int[int] aa;\n    bug6751(aa);\n    assert(aa[1] == 2);\n    return true;\n}());\n\nvoid bug6751b(ref int[int][int] aa)\n{\n    aa[1][17] = 2;\n}\n\nstruct S6751\n{\n    int[int][int] aa;\n    int[int] bb;\n}\n\nstatic assert({\n    S6751 s;\n    bug6751b(s.aa);\n    assert(s.aa[1][17] == 2);\n    return true;\n}());\n\nstatic assert({\n    S6751 s;\n    s.aa[7][56] = 57;\n    bug6751b(s.aa);\n    assert(s.aa[1][17] == 2);\n    assert(s.aa[7][56] == 57);\n    bug6751c(s.aa);\n    assert(s.aa.keys.length == 1);\n    assert(s.aa.values.length == 1);\n    return true;\n}());\n\nstatic assert({\n    S6751 s;\n    s.bb[19] = 97;\n    bug6751(s.bb);\n    assert(s.bb[1] == 2);\n    assert(s.bb[19] == 97);\n    return true;\n}());\n\nvoid bug6751c(ref int[int][int] aa)\n{\n    aa = [38: [56 : 77]];\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7790\n// AA foreach ref\n\nstruct S7790\n{\n    size_t id;\n}\n\nsize_t bug7790(S7790[string] tree)\n{\n    foreach (k, ref v; tree)\n        v.id = 1;\n    return tree[\"a\"].id;\n}\n\nstatic assert(bug7790([\"a\":S7790(0)]) == 1);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6765\n// null AA.length\n\nstatic assert({\n    int[int] w;\n    return w.length;\n}() == 0);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6769\n// AA.keys, AA.values with -inline\n\nstatic assert({\n    double[char[3]] w = [\"abc\" : 2.3];\n    double[] z = w.values;\n    return w.keys.length;\n}() == 1);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4022\n// AA.get\n\nstatic assert({\n    int[int] aa = [58: 13];\n    int r = aa.get(58, 1000);\n    assert(r == 13);\n    r = aa.get(59, 1000);\n    return r;\n}() == 1000);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6775\n// AA.opApply\n\nstatic assert({\n    int[int] aa = [58: 17, 45:6];\n    int valsum = 0;\n    int keysum = 0;\n    foreach (m; aa)  // aaApply\n    {\n        valsum += m;\n    }\n    assert(valsum == 17 + 6);\n    valsum = 0;\n    foreach (n, m; aa)  // aaApply2\n    {\n        valsum += m;\n        keysum += n;\n    }\n    assert(valsum == 17 + 6);\n    assert(keysum == 58 + 45);\n    // Check empty AA\n    valsum = 0;\n    int[int] bb;\n    foreach (m; bb)\n    {\n        ++valsum;\n    }\n    assert(valsum == 0);\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7890\n// segfault struct with AA field\n\nstruct S7890\n{\n    int[int] tab;\n}\n\nS7890 bug7890()\n{\n    S7890 foo;\n    foo.tab[0] = 0;\n    return foo;\n}\n\nenum e7890 = bug7890();\n\n/**************************************************\n    AA.remove\n**************************************************/\n\nstatic assert({\n    int[int] aa = [58: 17, 45:6];\n    aa.remove(45);\n    assert(aa.length == 1);\n    aa.remove(7);\n    assert(aa.length == 1);\n    aa.remove(58);\n    assert(aa.length == 0);\n    return true;\n}());\n\n/**************************************************\n    try, finally\n**************************************************/\n\nstatic assert({\n    int n = 0;\n\n    try\n    {\n        n = 1;\n    }\n    catch (Exception e)\n    {}\n    assert(n == 1);\n\n    try\n    {\n        n = 2;\n    }\n    catch (Exception e)\n    {}\n    finally\n    {\n        assert(n == 2);\n        n = 3;\n    }\n    assert(n == 3);\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6800\n// bad pointer casts\n\nbool badpointer(int k)\n{\n    int m = 6;\n    int* w =  &m;\n    assert(*w == 6);\n    int[3] a = [17, 2, 21];\n    int* w2 = &a[2];\n    assert(*w2 == 21);\n\n    // cast int* to uint* is OK\n    uint* u1 = cast(uint*)w;\n    assert(*u1 == 6);\n    uint* u2 = cast(uint*)w2;\n    assert(*u2 == 21);\n    uint* u3 = cast(uint*)&m;\n    assert(*u3 == 6);\n    // cast int* to void* is OK\n    void* v1 = cast(void*)w;\n    void* v3 = &m;\n    void* v4 = &a[0];\n    // cast from void* back to int* is OK\n    int* t3 = cast(int*)v3;\n    assert(*t3 == 6);\n    int* t4 = cast(int*)v4;\n    assert(*t4 == 17);\n    // cast from void* to uint* is OK\n    uint* t1 = cast(uint*)v1;\n    assert(*t1 == 6);\n    // and check that they're real pointers\n    m = 18;\n    assert(*t1 == 18);\n    assert(*u3 == 18);\n\n    int** p = &w;\n\n    if (k == 1) // bad reinterpret\n        double *d1 = cast(double*)w;\n    if (k == 3) // bad reinterpret\n        char* d3 = cast(char*)w2;\n    if (k == 4) {\n        void* q1 = cast(void*)p;    // OK-void is int*\n        void* *q = cast(void**)p;   // OK-void is int\n    }\n    if (k == 5)\n        void*** q = cast(void***)p;  // bad: too many *\n    if (k == 6) // bad reinterpret through void*\n        double* d1 = cast(double*)v1;\n    if (k == 7)\n        double* d7 = cast(double*)v4;\n    if (k == 8)\n        ++v4; // can't do pointer arithmetic on void*\n    return true;\n}\nstatic assert(badpointer(4));\nstatic assert(!is(typeof(compiles!(badpointer(1)))));\nstatic assert( is(typeof(compiles!(badpointer(2)))));\nstatic assert(!is(typeof(compiles!(badpointer(3)))));\nstatic assert( is(typeof(compiles!(badpointer(4)))));\nstatic assert(!is(typeof(compiles!(badpointer(5)))));\nstatic assert(!is(typeof(compiles!(badpointer(6)))));\nstatic assert(!is(typeof(compiles!(badpointer(7)))));\nstatic assert(!is(typeof(compiles!(badpointer(8)))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10211\n// Allow casts S**->D**, when S*->D* is OK\n\nint bug10211()\n{\n    int m = 7;\n    int* x = &m;\n    int** y = &x;\n    assert(**y == 7);\n    uint* p = cast(uint*)x;\n    uint** q = cast(uint**)y;\n    return 1;\n}\n\nstatic assert(bug10211());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10568\n// CTFE rejects function pointer safety casts\n\n@safe void safetyDance() {}\n\nint isItSafeToDance()\n{\n    void function() @trusted yourfriends = &safetyDance;\n    void function() @safe nofriendsOfMine = yourfriends;\n    return 1;\n}\n\nstatic assert(isItSafeToDance());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12296\n// CTFE rejects const compatible AA pointer cast\n\nint test12296()\n{\n    immutable x = [5 : 4];\n    auto aa = &x;\n    const(int[int])* y = aa;\n    return 1;\n}\nstatic assert(test12296());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9170\n// Allow reinterpret casts float<->int\n\nint f9170(float x)\n{\n    return *(cast(int*)&x);\n}\n\nfloat i9170(int x)\n{\n    return *(cast(float*)&x);\n}\n\nfloat u9170(uint x)\n{\n    return *(cast(float*)&x);\n}\n\nint f9170arr(float[] x)\n{\n    return *(cast(int*)&(x[1]));\n}\n\nlong d9170(double x)\n{\n    return *(cast(long*)&x);\n}\n\nint fref9170(ref float x)\n{\n    return *(cast(int*)&x);\n}\n\nlong dref9170(ref double x)\n{\n    return *(cast(long*)&x);\n}\n\nbool bug9170()\n{\n    float f = 1.25;\n    double d = 1.25;\n    assert(f9170(f) == 0x3FA0_0000);\n    assert(fref9170(f) == 0x3FA0_0000);\n    assert(d9170(d) == 0x3FF4_0000_0000_0000L);\n    assert(dref9170(d) == 0x3FF4_0000_0000_0000L);\n    float [3] farr = [0, 1.25, 0];\n    assert(f9170arr(farr) == 0x3FA0_0000);\n    int i = 0x3FA0_0000;\n    assert(i9170(i) == 1.25);\n    uint u = 0x3FA0_0000;\n    assert(u9170(u) == 1.25);\n    return true;\n}\n\nstatic assert(bug9170());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6792\n// ICE with pointer cast of indexed array\n\nstruct S6792\n{\n    int i;\n}\n\nstatic assert({\n    {\n        void* p;\n        p = [S6792(1)].ptr;\n        S6792 s = *(cast(S6792*)p);\n        assert(s.i == 1);\n    }\n    {\n        void*[] ary;\n        ary ~= [S6792(2)].ptr;\n        S6792 s = *(cast(S6792*)ary[0]);\n        assert(s.i == 2);\n    }\n    {\n        void*[7] ary;\n        ary[6]= [S6792(2)].ptr;\n        S6792 s = *(cast(S6792*)ary[6]);\n        assert(s.i == 2);\n    }\n    {\n        void* p;\n        p = [S6792(1)].ptr;\n        void*[7] ary;\n        ary[5]= p;\n        S6792 s = *(cast(S6792*)ary[5]);\n        assert(s.i == 1);\n    }\n    {\n        S6792*[string] aa;\n        aa[\"key\"] = [S6792(3)].ptr;\n        const(S6792) s = *(cast(const(S6792)*)aa[\"key\"]);\n        assert(s.i == 3);\n    }\n    {\n        S6792[string] blah;\n        blah[\"abc\"] = S6792(6);\n        S6792*[string] aa;\n        aa[\"kuy\"] = &blah[\"abc\"];\n        const(S6792) s = *(cast(const(S6792)*)aa[\"kuy\"]);\n        assert(s.i == 6);\n\n        void*[7] ary;\n        ary[5]= &blah[\"abc\"];\n        S6792 t = *(cast(S6792*)ary[5]);\n        assert(t.i == 6);\n\n        int q = 6;\n        ary[3]= &q;\n        int gg = *(cast(int*)(ary[3]));\n    }\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7780\n// array cast\n\nint bug7780(int testnum)\n{\n    int[] y = new int[2];\n    y[0] = 2000000;\n    if (testnum == 1)\n    {\n        void[] x = y;\n        return (cast(byte[])x)[1];\n    }\n    if (testnum == 2)\n    {\n        int[] x = y[0 .. 1];\n        return (cast(byte[])x)[1];\n    }\n    return 1;\n}\n\nstatic assert( is(typeof(compiles!(bug7780(0)))));\nstatic assert(!is(typeof(compiles!(bug7780(1)))));\nstatic assert(!is(typeof(compiles!(bug7780(2)))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14028\n// static array pointer that refers existing array elements.\n\nint test14028a(size_t ofs)(bool ct)\n{\n    int[4] a;\n    int[2]* p;\n    int num = ofs;\n\n    if (ct)\n        p = cast(int[2]*)&a[ofs];    // SymOffExp\n    else\n        p = cast(int[2]*)&a[num];    // CastExp + AddrExp\n\n    // pointers comparison\n    assert(cast(void*)a.ptr <= cast(void*)p);\n    assert(cast(void*)a.ptr <= cast(void*)&(*p)[0]);\n    assert(cast(void*)&a[0] <= cast(void*)p);\n\n    return 1;\n}\nstatic assert(test14028a!0(true));\nstatic assert(test14028a!0(false));\nstatic assert(test14028a!3(true));\nstatic assert(test14028a!3(false));\nstatic assert(!is(typeof(compiles!(test14028a!4(true)))));\nstatic assert(!is(typeof(compiles!(test14028a!4(false)))));\n\nint test14028b(int num)\n{\n    int[4] a;\n    int[2]* p;\n\n    if (num == 1)\n    {\n        p = cast(int[2]*)&a[0]; // &a[0..2];\n        (*p)[0] = 1;            // a[0] = 1\n        (*p)[1] = 2;            // a[1] = 2\n        assert(a == [1,2,0,0]);\n        p = p + 1;              // &a[0] -> &a[2]\n        (*p)[0] = 3;            // a[2] = 3\n        (*p)[1] = 4;            // a[3] = 4\n        assert(a == [1,2,3,4]);\n    }\n    if (num == 2)\n    {\n        p = cast(int[2]*)&a[1]; // &a[1..3];\n        (*p)[0] = 1;            // a[1] = 1\n        p = p + 1;              // &a[1..3] -> &a[3..5]\n        (*p)[0] = 2;            // a[3] = 2\n        assert(a == [0,1,0,2]);\n    }\n    if (num == 3)\n    {\n        p = cast(int[2]*)&a[1]; // &a[1..3];\n        (*p)[0] = 1;            // a[1] = 1\n        p = p + 1;              // &a[1..3] -> &a[3..5]\n        (*p)[0] = 2;            // a[3] = 2\n        (*p)[1] = 3;            // a[4] = 3 (CTFE error)\n    }\n    if (num == 4)\n    {\n        p = cast(int[2]*)&a[0]; // &a[0..2];\n        p = p + 1;              // &a[0..2] -> &a[2..4]\n        p = p + 1;              // &a[2..4] -> &a[4..6] (ok)\n    }\n    if (num == 5)\n    {\n        p = cast(int[2]*)&a[1]; // &a[1..3];\n        p = p + 2;              // &a[1..3] -> &a[5..7] (CTFE error)\n    }\n    return 1;\n}\nstatic assert(test14028b(1));\nstatic assert(test14028b(2));\nstatic assert(!is(typeof(compiles!(test14028b(3)))));\nstatic assert(test14028b(4));\nstatic assert(!is(typeof(compiles!(test14028b(5)))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10275\n// cast struct literals to immutable\n\nstruct Bug10275\n{\n    uint[] ivals;\n}\n\nBug10275 bug10275()\n{\n    return Bug10275([1, 2, 3]);\n}\n\nint test10275()\n{\n    immutable(Bug10275) xxx = cast(immutable(Bug10275))bug10275();\n    return 1;\n}\n\nstatic assert(test10275());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6851\n// passing pointer by argument\n\nvoid set6851(int* pn)\n{\n    *pn = 20;\n}\nvoid bug6851()\n{\n    int n = 0;\n    auto pn = &n;\n    *pn = 10;\n    assert(n == 10);\n    set6851(&n);\n}\nstatic assert({ bug6851(); return true; }());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7876\n\nint* bug7876(int n) @system\n{\n    int x;\n    auto ptr = &x;\n    if (n == 2)\n        ptr = null;\n    return ptr;\n}\n\nstruct S7876\n{\n    int* p;\n}\n\nS7876 bug7876b(int n) @system\n{\n    int x;\n    S7876 s;\n    s.p = &x;\n    if (n == 11)\n        s.p = null;\n    return s;\n}\n\nint test7876(int n)\n{\n    if (n >= 10)\n    {\n        S7876 m = bug7876b(n);\n        return 1;\n    }\n    int* p = bug7876(n);\n    return 1;\n}\n\nstatic assert( is(typeof(compiles!(test7876(2)))));\nstatic assert(!is(typeof(compiles!(test7876(0)))));\nstatic assert( is(typeof(compiles!(test7876(11)))));\nstatic assert(!is(typeof(compiles!(test7876(10)))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11824\n\nint f11824(T)()\n{\n    T[] arr = new T[](1);\n    T* getAddr(ref T a)\n    {\n        return &a;\n    }\n    getAddr(arr[0]);\n    return 1;\n}\nstatic assert(f11824!int());        // OK\nstatic assert(f11824!(int[])());    // OK <- NG\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6817\n// if converted to &&, only with -inline\n\nstatic assert({\n    void toggle()\n    {\n        bool b;\n        if (b)\n            b = false;\n    }\n    toggle();\n    return true;\n}());\n\n/**************************************************\n    cast to void\n**************************************************/\n\nstatic assert({\n    cast(void)(71);\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6816\n// nested function can't access this\n\nstruct S6816\n{\n    size_t foo()\n    {\n        return (){ return value +1 ; }();\n    }\n    size_t value;\n}\n\nenum s6816 = S6816().foo();\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7277\n// ICE nestedstruct.init.tupleof\n\nstruct Foo7277\n{\n    int a;\n    int func()\n    {\n        int b;\n        void nested()\n        {\n            b = 7;\n            a = 10;\n        }\n        nested();\n        return a+b;\n    }\n}\n\nstatic assert(Foo7277().func() == 17);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10217\n// ICE. CTFE version of 9315\n\nbool bug10217()\n{\n    struct S\n    {\n        int i;\n        void bar() {}\n    }\n    auto yyy = S.init.tupleof[$ - 1];\n    assert(!yyy);\n    return 1;\n}\n\nstatic assert(bug10217());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8276\n// ICE\n\nvoid bug8676(int n)\n{\n    const int X1 = 4 + n;\n    const int X2 = 4;\n    int X3 = 4;\n    int bar1() { return X1; }\n    int bar2() { return X2; }\n    int bar3() { return X3; }\n    static assert(!is(typeof(compiles!(bar1()))));\n    static assert( is(typeof(compiles!(bar2()))));\n    static assert(!is(typeof(compiles!(bar3()))));\n}\n\n/**************************************************\n    classes and interfaces\n**************************************************/\n\ninterface SomeInterface\n{\n    int daz();\n    float bar(char);\n    int baz();\n}\n\ninterface SomeOtherInterface\n{\n    int xxx();\n}\n\nclass TheBase : SomeInterface, SomeOtherInterface\n{\n    int q = 88;\n    int rad = 61;\n    int a = 14;\n    int somebaseclassfunc() { return 28; }\n    int daz() { return 0; }\n    int baz() { return 0; }\n    int xxx() { return 762; }\n    int foo() { return q; }\n    float bar(char c) { return 3.6; }\n}\n\nclass SomeClass : TheBase, SomeInterface\n{\n    int gab = 9;\n    int fab;\n    int a = 17;\n    int b = 23;\n    override int foo() { return gab + a; }\n    override float bar(char c) { return 2.6; }\n    int something() { return 0; }\n    override int daz() { return 0; }\n    override int baz() { return 0; }\n}\n\nclass Unrelated : TheBase\n{\n    this(int x) { a = x; }\n}\n\nauto classtest1(int n)\n{\n    SomeClass c = new SomeClass;\n    assert(c.a == 17);\n    assert(c.q == 88);\n    TheBase d = c;\n    assert(d.a == 14);\n    assert(d.q == 88);\n    if (n == 7)\n    {\n        // bad cast -- should fail\n        Unrelated u = cast(Unrelated)d;\n        assert(u is null);\n    }\n    SomeClass e = cast(SomeClass)d;\n    d.q = 35;\n    assert(c.q == 35);\n    assert(c.foo() == 9 + 17);\n    ++c.a;\n    assert(c.foo() == 9 + 18);\n    assert(d.foo() == 9 + 18);\n    d = new TheBase;\n    SomeInterface fc = c;\n    SomeOtherInterface ot = c;\n    assert(fc.bar('x') == 2.6);\n    assert(ot.xxx() == 762);\n    fc = d;\n    ot = d;\n    assert(fc.bar('x') == 3.6);\n    assert(ot.xxx() == 762);\n\n    Unrelated u2 = new Unrelated(7);\n    assert(u2.a == 7);\n    return 6;\n}\nstatic assert(classtest1(1));\nstatic assert(classtest1(2));\nstatic assert(classtest1(7)); // https://issues.dlang.org/show_bug.cgi?id=7154\n\n// can't initialize enum with not null class\nSomeClass classtest2(int n)\n{\n    return n == 5 ? (new SomeClass) : null;\n}\nstatic assert( is(typeof((){ enum const(SomeClass) xx = classtest2(2);}())));\nstatic assert(!is(typeof((){ enum const(SomeClass) xx = classtest2(5);}())));\n\nclass RecursiveClass\n{\n   int x;\n   this(int n) { x = n; }\n   RecursiveClass b;\n   void doit() { b = new RecursiveClass(7); b.x = 2;}\n}\n\nint classtest3()\n{\n    RecursiveClass x = new RecursiveClass(17);\n    x.doit();\n    RecursiveClass y = x.b;\n    assert(y.x == 2);\n    assert(x.x == 17);\n    return 1;\n}\n\nstatic assert(classtest3());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12016\n// class cast and qualifier reinterpret\n\nclass B12016 { }\n\nclass C12016 : B12016 { }\n\nbool f12016(immutable B12016 b)\n{\n    assert(b);\n    return true;\n}\n\nstatic assert(f12016(new immutable C12016));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10610\n// ice immutable implicit conversion\n\nclass Bug10610(T)\n{\n    int baz() immutable\n    {\n        return 1;\n    }\n    static immutable(Bug10610!T) min = new Bug10610!T();\n}\n\nvoid ice10610()\n{\n   alias T10610 = Bug10610!(int);\n   static assert (T10610.min.baz());\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13141\n// regression fix caused by 10610\n\nstruct MapResult13141(alias pred)\n{\n    int[] range;\n    @property empty() { return range.length == 0; }\n    @property front() { return pred(range[0]); }\n    void popFront() { range = range[1 .. $]; }\n}\n\nstring[] array13141(R)(R r)\n{\n    typeof(return) result;\n    foreach (e; r)\n        result ~= e;\n    return result;\n}\n\n//immutable string[] splitterNames = [4].map!(e => \"4\").array();\nimmutable string[] splitterNames13141 = MapResult13141!(e => \"4\")([4]).array13141();\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11587\n// AA compare\n\nstatic assert([1:2, 3:4] == [3:4, 1:2]);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14325\n// more AA comparisons\n\nstatic assert([1:1] != [1:2, 2:1]);      // OK\nstatic assert([1:1] != [1:2]);           // OK\nstatic assert([1:1] != [2:1]);           // OK <- Error\nstatic assert([1:1, 2:2] != [3:3, 4:4]); // OK <- Error\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7147\n// typeid()\n\nstatic assert({\n    TypeInfo xxx = typeid(Object);\n    TypeInfo yyy = typeid(new Error(\"xxx\"));\n    return true;\n}());\n\nint bug7147(int n)\n{\n    Error err = n ? new Error(\"xxx\") : null;\n    TypeInfo qqq = typeid(err);\n    return 1;\n}\n\n// Must not segfault if class is null\nstatic assert(!is(typeof(compiles!(bug7147(0)))));\nstatic assert( is(typeof(compiles!(bug7147(1)))));\n\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14123\n// identity TypeInfo objects\n\nstatic assert({\n    bool eq(TypeInfo t1, TypeInfo t2)\n    {\n        return t1 is t2;\n    }\n\n    class C {}\n    struct S {}\n\n    assert( eq(typeid(C), typeid(C)));\n    assert(!eq(typeid(C), typeid(Object)));\n    assert( eq(typeid(S), typeid(S)));\n    assert(!eq(typeid(S), typeid(int)));\n    assert( eq(typeid(int), typeid(int)));\n    assert(!eq(typeid(int), typeid(long)));\n\n    Object o = new Object;\n    Object c = new C;\n    assert( eq(typeid(o), typeid(o)));\n    assert(!eq(typeid(c), typeid(o)));\n    assert(!eq(typeid(o), typeid(S)));\n\n    return 1;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6885\n// wrong code with new array\n\nstruct S6885\n{\n    int p;\n}\n\nint bug6885()\n{\n    auto array = new double[1][2];\n    array[1][0] = 6;\n    array[0][0] = 1;\n    assert(array[1][0] == 6);\n\n    auto barray = new S6885[2];\n    barray[1].p = 5;\n    barray[0].p = 2;\n    assert(barray[1].p == 5);\n    return 1;\n}\n\nstatic assert(bug6885());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6886\n// ICE with new array of dynamic arrays\n\nint bug6886()\n{\n    auto carray = new int[][2];\n    carray[1] = [6];\n    carray[0] = [4];\n    assert(carray[1][0] == 6);\n    return 1;\n}\n\nstatic assert(bug6886());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10198\n// Multidimensional struct block initializer\n\nstruct Block10198\n{\n    int[4][3] val;\n}\n\nint bug10198()\n{\n    Block10198 pp = Block10198(67);\n    assert(pp.val[2][3] == 67);\n    assert(pp.val[1][3] == 67);\n    return 1;\n}\nstatic assert(bug10198());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14440\n// Multidimensional block initialization should create distinct arrays for each elements\n\nstruct Matrix14440(E, size_t row, size_t col)\n{\n    E[col][row] array2D;\n\n    @safe pure nothrow\n    this(E[row * col] numbers...)\n    {\n        foreach (r; 0 .. row)\n        {\n            foreach (c; 0 .. col)\n            {\n                array2D[r][c] = numbers[r * col + c];\n            }\n        }\n    }\n}\n\nvoid test14440()\n{\n    // Replace 'enum' with 'auto' here and it will work fine.\n    enum matrix = Matrix14440!(int, 3, 3)(\n        1, 2, 3,\n        4, 5, 6,\n        7, 8, 9\n    );\n\n    static assert(matrix.array2D[0][0] == 1);\n    static assert(matrix.array2D[0][1] == 2);\n    static assert(matrix.array2D[0][2] == 3);\n    static assert(matrix.array2D[1][0] == 4);\n    static assert(matrix.array2D[1][1] == 5);\n    static assert(matrix.array2D[1][2] == 6);\n    static assert(matrix.array2D[2][0] == 7);\n    static assert(matrix.array2D[2][1] == 8);\n    static assert(matrix.array2D[2][2] == 9);\n}\n\n/****************************************************\n * Exception chaining tests from xtest46.d\n ****************************************************/\n\nclass A75\n{\n    pure static void raise(string s)\n    {\n        throw new Exception(s);\n    }\n}\n\nint test75()\n{\n    int x = 0;\n    try\n    {\n        A75.raise(\"a\");\n    }\n    catch (Exception e)\n    {\n        x = 1;\n    }\n    assert(x == 1);\n    return 1;\n}\nstatic assert(test75());\n\n/****************************************************\n * Exception chaining tests from test4.d\n ****************************************************/\n\nint test4_test54()\n{\n    int status = 0;\n\n    try\n    {\n        try\n        {\n            status++;\n            assert(status == 1);\n            throw new Exception(\"first\");\n        }\n        finally\n        {\n            status++;\n            assert(status == 2);\n            status++;\n            throw new Exception(\"second\");\n        }\n    }\n    catch (Exception e)\n    {\n        assert(e.msg == \"first\");\n        assert(e.next.msg == \"second\");\n    }\n    return true;\n}\n\nstatic assert(test4_test54());\n\nvoid foo55()\n{\n    try\n    {\n        Exception x = new Exception(\"second\");\n        throw x;\n    }\n    catch (Exception e)\n    {\n        assert(e.msg == \"second\");\n    }\n}\n\nint test4_test55()\n{\n    int status = 0;\n    try\n    {\n        try\n        {\n            status++;\n            assert(status == 1);\n            Exception x = new Exception(\"first\");\n            throw x;\n        }\n        finally\n        {\n            status++;\n            assert(status == 2);\n            status++;\n            foo55();\n        }\n    }\n    catch (Exception e)\n    {\n        assert(e.msg == \"first\");\n        assert(status == 3);\n    }\n    return 1;\n}\n\nstatic assert(test4_test55());\n\n/****************************************************\n * Exception chaining tests from eh.d\n ****************************************************/\n\nvoid bug1513outer()\n{\n    int result1513;\n\n    void bug1513a()\n    {\n         throw new Exception(\"d\");\n    }\n\n    void bug1513b()\n    {\n        try\n        {\n            try\n            {\n                bug1513a();\n            }\n            finally\n            {\n                result1513 |= 4;\n                throw new Exception(\"f\");\n            }\n        }\n        catch (Exception e)\n        {\n            assert(e.msg == \"d\");\n            assert(e.next.msg == \"f\");\n            assert(!e.next.next);\n        }\n    }\n\n    void bug1513c()\n    {\n        try\n        {\n            try\n            {\n                throw new Exception(\"a\");\n            }\n            finally\n            {\n                result1513 |= 1;\n                throw new Exception(\"b\");\n            }\n        }\n        finally\n        {\n            bug1513b();\n            result1513 |= 2;\n            throw new Exception(\"c\");\n        }\n    }\n\n    void bug1513()\n    {\n        result1513 = 0;\n        try\n        {\n            bug1513c();\n        }\n        catch (Exception e)\n        {\n            assert(result1513 == 7);\n            assert(e.msg == \"a\");\n            assert(e.next.msg == \"b\");\n            assert(e.next.next.msg == \"c\");\n        }\n    }\n\n    bug1513();\n}\n\nvoid collideone()\n{\n    try\n    {\n        throw new Exception(\"x\");\n    }\n    finally\n    {\n        throw new Exception(\"y\");\n    }\n}\n\nvoid doublecollide()\n{\n    try\n    {\n        try\n        {\n            try\n            {\n                throw new Exception(\"p\");\n            }\n            finally\n            {\n                throw new Exception(\"q\");\n            }\n        }\n        finally\n        {\n            collideone();\n        }\n    }\n    catch (Exception e)\n    {\n        assert(e.msg == \"p\");\n        assert(e.next.msg == \"q\");\n        assert(e.next.next.msg == \"x\");\n        assert(e.next.next.next.msg == \"y\");\n        assert(!e.next.next.next.next);\n    }\n}\n\nvoid collidetwo()\n{\n    try\n    {\n        try\n        {\n            throw new Exception(\"p2\");\n        }\n        finally\n        {\n            throw new Exception(\"q2\");\n        }\n    }\n    finally\n    {\n        collideone();\n    }\n}\n\nvoid collideMixed()\n{\n    int works = 6;\n    try\n    {\n        try\n        {\n            try\n            {\n                throw new Exception(\"e\");\n            }\n            finally\n            {\n                throw new Error(\"t\");\n            }\n        }\n        catch (Exception f)\n        {\n            // Doesn't catch, because Error is chained to it.\n            works += 2;\n        }\n    }\n    catch (Error z)\n    {\n        works += 4;\n        assert(z.msg == \"t\"); // Error comes first\n        assert(z.next is null);\n        assert(z.bypassedException.msg == \"e\");\n    }\n    assert(works == 10);\n}\n\nclass AnotherException : Exception\n{\n    this(string s)\n    {\n        super(s);\n    }\n}\n\nvoid multicollide()\n{\n    try\n    {\n        try\n        {\n            try\n            {\n                try\n                {\n                    throw new Exception(\"m2\");\n                }\n                finally\n                {\n                    throw new AnotherException(\"n2\");\n                }\n            }\n            catch (AnotherException s)\n            {\n                // Not caught -- we needed to catch the root cause \"m2\", not\n                // just the collateral \"n2\" (which would leave m2 uncaught).\n                assert(0);\n            }\n        }\n        finally\n        {\n            collidetwo();\n        }\n    }\n    catch (Exception f)\n    {\n        assert(f.msg == \"m2\");\n        assert(f.next.msg == \"n2\");\n        Throwable e = f.next.next;\n        assert(e.msg == \"p2\");\n        assert(e.next.msg == \"q2\");\n        assert(e.next.next.msg == \"x\");\n        assert(e.next.next.next.msg == \"y\");\n        assert(!e.next.next.next.next);\n    }\n}\n\nint testsFromEH()\n{\n    bug1513outer();\n    doublecollide();\n    collideMixed();\n    multicollide();\n    return 1;\n}\nstatic assert(testsFromEH());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6901\n// With + synchronized statements\n\nstruct With1\n{\n    int a;\n    int b;\n}\n\nclass Foo6\n{\n}\n\nclass Foo32\n{\n    struct Bar\n    {\n        int x;\n    }\n}\n\nclass Base56\n{\n    private string myfoo;\n    private string mybar;\n\n    // Get/set properties that will be overridden.\n    void foo(string s) { myfoo = s; }\n    string foo() { return myfoo; }\n\n    // Get/set properties that will not be overridden.\n    void bar(string s) { mybar = s; }\n    string bar() { return mybar; }\n}\n\nclass Derived56 : Base56\n{\n    alias Base56.foo foo; // Bring in Base56's foo getter.\n    override void foo(string s) { super.foo = s; } // Override foo setter.\n}\n\nint testwith()\n{\n    With1 x = With1(7);\n    with (x)\n    {\n        a = 2;\n    }\n    assert(x.a == 2);\n\n    // from test11.d\n    Foo6 foo6 = new Foo6();\n\n    with (foo6)\n    {\n        int xx;\n        xx = 4;\n    }\n    with (new Foo32)\n    {\n        Bar z;\n        z.x = 5;\n    }\n    Derived56 d = new Derived56;\n    with (d)\n    {\n        foo = \"hi\";\n        d.foo = \"hi\";\n        bar = \"hi\";\n        assert(foo == \"hi\");\n        assert(d.foo == \"hi\");\n        assert(bar == \"hi\");\n    }\n    int w = 7;\n    synchronized\n    {\n        ++w;\n    }\n    assert(w == 8);\n    return 1;\n}\n\nstatic assert(testwith());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9236\n// ICE  switch with(EnumType)\n\nenum Command9236\n{\n    Char,\n    Any,\n};\n\nbool bug9236(Command9236 cmd)\n{\n    int n = 0;\n    with (Command9236) switch (cmd)\n    {\n    case Any:\n        n = 1;\n        break;\n    default:\n        n = 2;\n    }\n    assert(n == 1);\n\n    switch (cmd) with (Command9236)\n    {\n    case Any:\n        return true;\n    default:\n        return false;\n    }\n}\n\nstatic assert(bug9236(Command9236.Any));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6416\n// static struct declaration\n\nstatic assert({\n    static struct S { int y = 7; }\n    S a;\n    a.y += 6;\n    assert(a.y == 13);\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10499\n// static template struct declaration\n\nstatic assert({\n    static struct Result() {}\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13757\n// extern(C) alias declaration\n\nstatic assert({\n    alias FP1 = extern(C) int function();\n    alias extern(C) int function() FP2;\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6522\n// opAssign + foreach ref\n\nstruct Foo6522\n{\n    bool b = false;\n    void opAssign(int x)\n    {\n        this.b = true;\n    }\n}\n\nbool foo6522()\n{\n    Foo6522[1] array;\n    foreach (ref item; array)\n        item = 1;\n    return true;\n}\n\nstatic assert(foo6522());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7245\n// pointers + foreach ref\n\nint bug7245(int testnum)\n{\n    int[3] arr;\n    arr[0] = 4;\n    arr[1] = 6;\n    arr[2] = 8;\n    int* ptr;\n\n    foreach (i, ref p; arr)\n    {\n        if (i == 1)\n            ptr = &p;\n        if (testnum == 1)\n            p = 5;\n    }\n\n    return *ptr;\n}\n\nstatic assert(bug7245(0) == 6);\nstatic assert(bug7245(1) == 5);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8498\n// modifying foreach\n// https://issues.dlang.org/show_bug.cgi?id=7658\n// foreach ref\n// https://issues.dlang.org/show_bug.cgi?id=8539\n// nested funcs, ref param, -inline\n\nint bug8498()\n{\n    foreach (ref i; 0 .. 5)\n    {\n        assert(i == 0);\n        i = 100;\n    }\n    return 1;\n}\nstatic assert(bug8498());\n\nstring bug7658()\n{\n    string[] children = [\"0\"];\n    foreach (ref child; children)\n        child = \"1\";\n    return children[0];\n}\n\nstatic assert(bug7658() == \"1\");\n\nint bug8539()\n{\n    static void one(ref int x)\n    {\n        x = 1;\n    }\n    static void go()\n    {\n        int y;\n        one(y);\n        assert(y == 1); // fails with -inline\n    }\n    go();\n    return 1;\n}\n\nstatic assert(bug8539());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7874\n// https://issues.dlang.org/show_bug.cgi?id=13297\n// https://issues.dlang.org/show_bug.cgi?id=13740\n// better lvalue handling\n\nint bug7874(int x){ return ++x = 1; }\nstatic assert(bug7874(0) == 1);\n\n// ----\n\nstruct S13297\n{\n    int* p;\n}\nvoid f13297(ref int* p)\n{\n    p = cast(int*) 1;\n    assert(p); // passes\n}\nstatic assert(\n{\n    S13297 s;\n    f13297(s.p);\n    return s.p != null; // false\n}());\n\n// ----\n\nclass R13740\n{\n    int e;\n    bool empty = false;\n    @property ref front() { return e; }\n    void popFront() { empty = true; }\n}\nstatic assert({\n    auto r = new R13740();\n    foreach (ref e; r)\n        e = 42;\n    assert(r.e == 42); /* fails in CTFE */\n\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6919\n\nvoid bug6919(int* val)\n{\n    *val = 1;\n}\nvoid test6919()\n{\n    int n;\n    bug6919(&n);\n    assert(n == 1);\n}\nstatic assert({ test6919(); return true; }());\n\nvoid bug6919b(string* val)\n{\n    *val = \"1\";\n}\n\nvoid test6919b()\n{\n    string val;\n    bug6919b(&val);\n    assert(val == \"1\");\n}\nstatic assert({ test6919b(); return true; }());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6995\n\nstruct Foo6995\n{\n    static size_t index(size_t v)()\n    {\n        return v;\n    }\n}\n\nstatic assert(Foo6995.index!(27)() == 27);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7043\n// ref with -inline\n\nint bug7043(S)(ref int x)\n{\n    return x;\n}\n\nstatic assert({\n    int i = 416;\n    return bug7043!(char)(i);\n}() == 416);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6037\n// recursive ref\n\nvoid bug6037(ref int x, bool b)\n{\n    int w = 3;\n    if (b)\n    {\n        bug6037(w, false);\n        assert(w == 6);\n    }\n    else\n    {\n        x = 6;\n        assert(w == 3); // fails\n    }\n}\n\nint bug6037outer()\n{\n    int q;\n    bug6037(q, true);\n    return 401;\n}\n\nstatic assert(bug6037outer() == 401);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14299\n// [REG2.067a], more than one depth of recursive call with ref\n\nstring gen14299(int max, int idx, ref string name)\n{\n    string ret;\n    name = [cast(char)(idx + '0')];\n    ret ~= name;\n    if (idx < max)\n    {\n        string subname;\n        ret ~= gen14299(max, idx + 1, subname);\n    }\n    ret ~= name;\n    return ret;\n}\nstring test14299(int max)\n{\n    string n;\n    return gen14299(max, 0, n);\n}\nstatic assert(test14299(1) ==     \"0110\");      // OK <- fail\nstatic assert(test14299(2) ==    \"012210\");     // OK <- ICE\nstatic assert(test14299(3) ==   \"01233210\");\nstatic assert(test14299(4) ==  \"0123443210\");\nstatic assert(test14299(5) == \"012345543210\");\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7940\n// wrong code for complicated assign\n\nstruct Bug7940\n{\n    int m;\n}\n\nstruct App7940\n{\n    Bug7940[] x;\n}\n\nint bug7940()\n{\n    Bug7940[2] y;\n    App7940 app;\n    app.x = y[0 .. 1];\n    app.x[0].m = 12;\n    assert(y[0].m == 12);\n    assert(app.x[0].m == 12);\n    return 1;\n}\n\nstatic assert(bug7940());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10298\n// wrong code for struct array literal init\n\nstruct Bug10298\n{\n    int m;\n}\n\nint bug10298()\n{\n    Bug10298[1] y = [Bug10298(78)];\n    y[0].m = 6;\n    assert(y[0].m == 6);\n\n    // Root cause\n    Bug10298[1] x;\n    x[] = [cast(const Bug10298)(Bug10298(78))];\n    assert(x[0].m == 78);\n    return 1;\n}\n\nstatic assert(bug10298());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7266\n// dotvar ref parameters\n\nstruct S7266 { int a; }\n\nbool bug7266()\n{\n    S7266 s;\n    s.a = 4;\n    bar7266(s.a);\n    assert(s.a == 5);\n    out7266(s.a);\n    assert(s.a == 7);\n    return true;\n}\n\nvoid bar7266(ref int b)\n{\n    b = 5;\n    assert(b == 5);\n}\n\nvoid out7266(out int b)\n{\n    b = 7;\n    assert(b == 7);\n}\n\nstatic assert(bug7266());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9982\n// dotvar assign through pointer\n\nstruct Bug9982\n{\n    int a;\n}\n\nint test9982()\n{\n    Bug9982 x;\n    int*q = &x.a;\n    *q = 99;\n    assert(x.a == 99);\n    return 1;\n}\n\nstatic assert(test9982());\n\n// https://issues.dlang.org/show_bug.cgi?id=9982\n// rejects-valid case\n\nstruct SS9982\n{\n    Bug9982 s2;\n    this(Bug9982 s1)\n    {\n        s2.a = 6;\n        emplace9982(&s2, s1);\n        assert(s2.a == 3);\n    }\n}\n\nvoid emplace9982(Bug9982* chunk, Bug9982 arg)\n{\n    *chunk = arg;\n}\n\nenum s9982 = Bug9982(3);\nenum p9982 = SS9982(s9982);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11618\n// dotvar assign through casted pointer\n\nstruct Tuple11618(T...)\n{\n    T field;\n    alias field this;\n}\n\nstatic assert({\n    Tuple11618!(immutable dchar) result = void;\n    auto addr = cast(dchar*)&result[0];\n    *addr = dchar.init;\n    return (result[0] == dchar.init);\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7143\n// 'is' for classes\n\nclass C7143\n{\n    int x;\n}\n\nint bug7143(int test)\n{\n    C7143 c = new C7143;\n    C7143 d = new C7143;\n    if (test == 1)\n    {\n        if (c)\n            return c.x + 8;\n        return -1;\n    }\n    if (test == 2)\n    {\n        if (c is null)\n            return -1;\n        return c.x + 45;\n    }\n    if (test == 3)\n    {\n        if (c is c)\n            return 58;\n    }\n    if (test == 4)\n    {\n        if (c !is c)\n            return -1;\n        else\n            return 48;\n    }\n    if (test == 6)\n        d = c;\n    if (test == 5 || test == 6)\n    {\n        if (c is d)\n            return 188;\n        else\n            return 48;\n    }\n    return -1;\n}\n\nstatic assert(bug7143(1) == 8);\nstatic assert(bug7143(2) == 45);\nstatic assert(bug7143(3) == 58);\nstatic assert(bug7143(4) == 48);\nstatic assert(bug7143(5) == 48);\nstatic assert(bug7143(6) == 188);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7147\n// virtual function calls from base class\n\nclass A7147\n{\n    int foo() { return 0; }\n\n    int callfoo()\n    {\n        return foo();\n    }\n}\n\nclass B7147 : A7147\n{\n    override int foo() { return 1; }\n}\n\nint test7147()\n{\n    A7147 a = new B7147;\n    return a.callfoo();\n}\n\nstatic assert(test7147() == 1);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7158\n\nclass C7158\n{\n    bool b() { return true; }\n}\nstruct S7158\n{\n    C7158 c;\n}\n\nbool test7158()\n{\n    S7158 s = S7158(new C7158);\n    return s.c.b;\n}\nstatic assert(test7158());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8484\n\nclass C8484\n{\n    int n;\n    int b() { return n + 3; }\n}\n\nstruct S\n{\n    C8484 c;\n}\n\nint t8484(ref C8484 c)\n{\n    return c.b();\n}\n\nint test8484()\n{\n    auto s = S(new C8484);\n    s.c.n = 4;\n    return t8484(s.c);\n}\nstatic assert(test8484() == 7);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7419\n\nstruct X7419\n{\n    double x;\n    this(double x)\n    {\n        this.x = x;\n    }\n}\n\nvoid bug7419()\n{\n    enum x = {\n        auto p = X7419(3);\n        return p.x;\n    }();\n    static assert(x == 3);\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9445\n// ice\n\ntemplate c9445(T...) { }\n\nvoid ice9445(void delegate() expr, void function() f2)\n{\n    static assert(!is(typeof(c9445!(f2()))));\n    static assert(!is(typeof(c9445!(expr()))));\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10452\n// delegate ==\n\nstruct S10452\n{\n    bool func() { return true; }\n}\n\nstruct Outer10452\n{\n    S10452 inner;\n}\n\nclass C10452\n{\n    bool func() { return true; }\n}\n\nbool delegate() ref10452(ref S10452 s)\n{\n    return &s.func;\n}\n\nbool test10452()\n{\n    bool delegate() bar = () { return true; };\n\n    assert(bar !is null);\n    assert(bar is bar);\n\n    S10452 bag;\n    S10452[6] bad;\n    Outer10452 outer;\n    C10452 tag = new C10452;\n\n    auto rat = &outer.inner.func;\n    assert(rat == rat);\n    auto tat = &tag.func;\n    assert(tat == tat);\n\n    auto bat = &outer.inner.func;\n    auto mat = &bad[2].func;\n    assert(mat is mat);\n    assert(rat == bat);\n\n    auto zat = &bag.func;\n    auto cat = &bag.func;\n    assert(zat == zat);\n    assert(zat == cat);\n\n    auto drat = ref10452(bag);\n    assert(cat == drat);\n    assert(drat == drat);\n    drat = ref10452(bad[2]);\n    assert( drat == mat);\n    assert(tat != rat);\n    assert(zat != rat);\n    assert(rat != cat);\n    assert(zat != bar);\n    assert(tat != cat);\n    cat = bar;\n    assert(cat == bar);\n    return true;\n}\nstatic assert(test10452());\n\n/**************************************************/\n//https://issues.dlang.org/show_bug.cgi?id=7162\n// https://issues.dlang.org/show_bug.cgi?id=4711\n\nvoid f7162() { }\n\nbool ice7162()\n{\n    false && f7162();\n    false || f7162();\n    false && f7162();  // https://issues.dlang.org/show_bug.cgi?id=4711\n    true && f7162();\n    return true;\n}\n\nstatic assert(ice7162());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8857\n// only with -inline (creates an &&)\n\nstruct Result8857 { char[] next; }\n\nvoid bug8857()()\n{\n    Result8857 r;\n    r.next = null;\n    if (true)\n    {\n       auto next = r.next;\n    }\n}\nstatic assert({\n    bug8857();\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7527\n\nstruct Bug7527\n{\n    char[] data;\n}\n\nint bug7527()\n{\n    auto app = Bug7527();\n\n    app.data.ptr[0 .. 1] = \"x\";\n    return 1;\n}\n\nstatic assert(!is(typeof(compiles!(bug7527()))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7527\n\nint bug7380;\n\nstatic assert(!is(typeof( compiles!(\n    (){\n        return &bug7380;\n    }()\n))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7165\n\nstruct S7165\n{\n    int* ptr;\n    bool f() const { return !!ptr; }\n}\n\nstatic assert(!S7165().f());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7187\n\nint[] f7187() { return [0]; }\nint[] f7187b(int n) { return [0]; }\n\nint g7187(int[] r)\n{\n    auto t = r[0 .. 0];\n    return 1;\n}\n\nstatic assert(g7187(f7187()));\nstatic assert(g7187(f7187b(7)));\n\nstruct S7187 { const(int)[] field; }\n\nconst(int)[] f7187c()\n{\n    auto s = S7187([0]);\n    return s.field;\n}\n\nbool g7187c(const(int)[] r)\n{\n    auto t = r[0 .. 0];\n    return true;\n}\n\nstatic assert(g7187c(f7187c()));\n\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6933\n// struct destructors\n\nstruct Bug6933\n{\n    int x = 3;\n    ~this() { }\n}\n\nint test6933()\n{\n    Bug6933 q;\n    assert(q.x == 3);\n    return 3;\n}\n\nstatic assert(test6933());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7197\n\nint foo7197(int[] x...)\n{\n    return 1;\n}\ntemplate bar7197(y...)\n{\n    enum int bar7197 = foo7197(y);\n}\nenum int bug7197 = 7;\nstatic assert(bar7197!(bug7197));\n\n/**************************************************\n    Enum string compare\n**************************************************/\n\nenum EScmp : string { a = \"aaa\" }\n\nbool testEScmp()\n{\n    EScmp x = EScmp.a;\n    assert(x < \"abc\");\n    return true;\n}\n\nstatic assert(testEScmp());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7667\n\nbool baz7667(int[] vars...)\n{\n     return true;\n}\n\nstruct S7667\n{\n    static void his(int n)\n    {\n        static assert(baz7667(2));\n    }\n}\n\nbool bug7667()\n{\n    S7667 unused;\n    unused.his(7);\n    return true;\n}\nenum e7667 = bug7667();\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7536\n\nbool bug7536(string expr)\n{\n    return true;\n}\n\nvoid vop()\n{\n    const string x7536 = \"x\";\n    static assert(bug7536(x7536));\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6681\n// unions\n\nstruct S6681\n{\n    this(int a, int b) { this.a = b; this.b = a; }\n    union\n    {\n        ulong g;\n        struct { int a, b; };\n    }\n}\n\nstatic immutable S6681 s6681 = S6681(0, 1);\n\nbool bug6681(int test)\n{\n    S6681 x = S6681(0, 1);\n    x.g = 5;\n    auto u = &x.g;\n    auto v = &x.a;\n    long w = *u;\n    int  z;\n    assert(w == 5);\n    if (test == 4)\n        z = *v; // error\n    x.a = 2; // invalidate g, and hence u.\n    if (test == 1)\n        w = *u; // error\n    z = *v;\n    assert(z == 2);\n    x.g = 6;\n    w = *u;\n    assert(w == 6);\n    if (test == 3)\n        z = *v;\n    return true;\n}\nstatic assert(bug6681(2));\nstatic assert(!is(typeof(compiles!(bug6681(1)))));\nstatic assert(!is(typeof(compiles!(bug6681(3)))));\nstatic assert(!is(typeof(compiles!(bug6681(4)))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9113\n// ICE with struct in union\n\nunion U9113\n{\n    struct M\n    {\n        int y;\n    }\n    int xx;\n}\n\nint bug9113(T)()\n{\n    U9113 x;\n    x.M.y = 10; // error, need 'this'\n    return 1;\n}\n\nstatic assert(!is(typeof(compiles!(bug9113!(int)()))));\n\n/**************************************************\n    Creation of unions\n**************************************************/\n\nunion UnionTest1\n{\n    int x;\n    float y;\n}\n\nint uniontest1()\n{\n    UnionTest1 u = UnionTest1(1);\n    return 1;\n}\n\nstatic assert(uniontest1());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6438\n// void\n\nstruct S6438\n{\n    int a;\n    int b = void;\n}\n\nvoid fill6438(int[] arr, int testnum)\n{\n    if (testnum == 2)\n    {\n        auto u = arr[0];\n    }\n    foreach (ref x; arr)\n        x = 7;\n    auto r = arr[0];\n    S6438[2] s;\n    auto p = &s[0].b;\n    if (testnum == 3)\n    {\n        auto v = *p;\n    }\n}\n\nbool bug6438(int testnum)\n{\n    int[4] stackSpace = void;\n    fill6438(stackSpace[], testnum);\n    assert(stackSpace == [7, 7, 7, 7]);\n    return true;\n}\n\nstatic assert( is(typeof(compiles!(bug6438(1)))));\nstatic assert(!is(typeof(compiles!(bug6438(2)))));\nstatic assert(!is(typeof(compiles!(bug6438(3)))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10994\n// void static array members\n\nstruct Bug10994\n{\n    ubyte[2] buf = void;\n}\n\nstatic bug10994 = Bug10994.init;\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10937\n// struct inside union\n\nstruct S10937\n{\n    union\n    {\n        ubyte[1] a;\n        struct\n        {\n            ubyte b;\n        }\n    }\n\n    this(ubyte B)\n    {\n        if (B > 6)\n            this.b = B;\n        else\n            this.a[0] = B;\n    }\n}\n\nenum test10937 = S10937(7);\nenum west10937 = S10937(2);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13831\n\nstruct Vector13831()\n{\n}\n\nstruct Coord13831\n{\n    union\n    {\n        struct { short x; }\n        Vector13831!() vector;\n    }\n}\n\nstruct Chunk13831\n{\n    this(Coord13831)\n    {\n        coord = coord;\n    }\n\n    Coord13831 coord;\n\n    static const Chunk13831* unknownChunk = new Chunk13831(Coord13831());\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7732\n\nstruct AssociativeArray\n{\n    int* impl;\n    int f()\n    {\n        if (impl !is null)\n            auto x = *impl;\n        return 1;\n    }\n}\n\nint test7732()\n{\n    AssociativeArray aa;\n    return aa.f;\n}\n\nstatic assert(test7732());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7784\nstruct Foo7784\n{\n    void bug()\n    {\n        tab[\"A\"] = Bar7784(&this);\n        auto pbar = \"A\" in tab;\n        auto bar = *pbar;\n    }\n\n    Bar7784[string] tab;\n}\n\nstruct Bar7784\n{\n    Foo7784* foo;\n    int val;\n}\n\nbool ctfe7784()\n{\n    auto foo = Foo7784();\n    foo.bug();\n    return true;\n}\n\nstatic assert(ctfe7784());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7781\n\nstatic assert(({ return true; }()));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7785\n\nbool bug7785(int n)\n{\n    int val = 7;\n    auto p = &val;\n    if (n == 2)\n    {\n        auto ary = p[0 .. 1];\n    }\n    auto x = p[0];\n    val = 6;\n    assert(x == 7);\n    if (n == 3)\n        p[0 .. 1] = 1;\n    return true;\n}\n\nstatic assert(bug7785(1));\nstatic assert(!is(typeof(compiles!(bug7785(2)))));\nstatic assert(!is(typeof(compiles!(bug7785(3)))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7987\n\nclass C7987\n{\n    int m;\n}\n\nstruct S7987\n{\n    int* p;\n    C7987 c;\n}\n\nbool bug7987()\n{\n    int[7] q;\n    int[][2] b = q[0 .. 5];\n    assert(b == b);\n    assert(b is b);\n    C7987 c1 = new C7987;\n    C7987 c2 = new C7987;\n    S7987 s, t;\n    s.p = &q[0];\n    t.p = &q[1];\n    assert(s != t);\n    s.p = &q[1];\n    /*assert(s == t);*/     assert(s.p == t.p);\n    s.c = c1;\n    t.c = c2;\n    /*assert(s != t);*/     assert(s.c !is t.c);\n    assert(s !is t);\n    s.c = c2;\n    /*assert(s == t);*/     assert(s.p == t.p && s.c is t.c);\n    assert(s is t);\n    return true;\n}\n\nstatic assert(bug7987());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10579\n// typeinfo.func() must not segfault\n\nstatic assert(!is(typeof(compiles!(typeid(int).toString.length))));\n\nclass Bug10579\n{\n    int foo() { return 1; }\n}\nBug10579 uninitialized10579;\n\nstatic assert(!is(typeof(compiles!(uninitialized10579.foo()))));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10804\n// mixin ArrayLiteralExp typed string\n\nvoid test10804()\n{\n    String identity(String)(String a) { return a; }\n\n    string cfun()\n    {\n        char[] s;\n        s.length = 8 + 2 + (2) + 1 + 2;\n        s[] = \"identity(`Ω`c)\"c[];\n        return cast(string)s;   // Return ArrayLiteralExp as the CTFE result\n    }\n    {\n        enum a1 = \"identity(`Ω`c)\"c;\n        enum a2 = cfun();\n        static assert(cast(ubyte[])mixin(a1) == [0xCE, 0xA9]);\n        static assert(cast(ubyte[])mixin(a2) == [0xCE, 0xA9]);  // should pass\n    }\n\n    wstring wfun()\n    {\n        wchar[] s;\n        s.length = 8 + 2 + (2) + 1 + 2;\n        s[] = \"identity(`\\U0002083A`w)\"w[];\n        return cast(wstring)s;  // Return ArrayLiteralExp as the CTFE result\n    }\n    {\n        enum a1 = \"identity(`\\U0002083A`w)\"w;\n        enum a2 = wfun();\n        static assert(cast(ushort[])mixin(a1) == [0xD842, 0xDC3A]);\n        static assert(cast(ushort[])mixin(a2) == [0xD842, 0xDC3A]);\n    }\n\n    dstring dfun()\n    {\n        dchar[] s;\n        s.length = 8 + 2 + (1) + 1 + 2;\n        s[] = \"identity(`\\U00101000`d)\"d[];\n        return cast(dstring)s;  // Return ArrayLiteralExp as the CTFE result\n    }\n    {\n        enum a1 = \"identity(`\\U00101000`d)\"d;\n        enum a2 = dfun();\n        static assert(cast(uint[])mixin(a1) == [0x00101000]);\n        static assert(cast(uint[])mixin(a2) == [0x00101000]);\n    }\n}\n\n/******************************************************/\n\nstruct B73 {}\nstruct C73 { B73 b; }\nC73 func73() { C73 b = void; b.b = B73(); return b; }\nC73 test73 = func73();\n\n/******************************************************/\n\nstruct S74\n{\n    int[1] n;\n    static S74 test(){ S74 ret = void; ret.n[0] = 0; return ret; }\n}\n\nenum Test74 = S74.test();\n\n/******************************************************/\n\nstatic bool bug8865()\nin\n{\n    int x = 0;\nlabel:\n    foreach (i; (++x) .. 3)\n    {\n        if (i == 1)\n            continue label;     // doesn't work.\n        else\n            break label;        // doesn't work.\n    }\n}\nout\n{\n    int x = 0;\nlabel:\n    foreach (i; (++x) .. 3)\n    {\n        if (i == 1)\n            continue label;     // doesn't work.\n        else\n            break label;        // doesn't work.\n    }\n}\nbody\n{\n    int x = 0;\nlabel:\n    foreach (i; (++x) .. 3)\n    {\n        if (i == 1)\n            continue label;     // works.\n        else\n            break label;        // works.\n    }\n\n    return true;\n}\nstatic assert(bug8865());\n\n/******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15450\n// labeled foreach + continue/break\n\nstatic assert({\n  L1:\n    foreach (l; [0])\n        continue L1;\n\n  L2:\n    foreach (l; [0])\n        break L2;\n\n    return true;\n}());\n\nstruct Test75\n{\n    this(int) pure {}\n}\n\n/******************************************************/\n\nstatic assert( __traits(compiles, { static shared(Test75*)   t75 = new shared(Test75)(0);    return t75; }));\nstatic assert( __traits(compiles, { static shared(Test75)*   t75 = new shared(Test75)(0);    return t75; }));\nstatic assert( __traits(compiles, { static __gshared Test75* t75 = new Test75(0);            return t75; }));\nstatic assert( __traits(compiles, { static const(Test75*)    t75 = new const(Test75)(0);     return t75; }));\nstatic assert( __traits(compiles, { static immutable Test75* t75 = new immutable(Test75)(0); return t75; }));\nstatic assert(!__traits(compiles, { static Test75*           t75 = new Test75(0);            return t75; }));\n/+\nstatic assert(!__traits(compiles, { enum                 t75 = new shared(Test75)(0); return t75; }));\nstatic assert(!__traits(compiles, { enum                 t75 = new Test75(0);         return t75; }));\nstatic assert(!__traits(compiles, { enum shared(Test75)* t75 = new shared(Test75)(0); return t75; }));\nstatic assert(!__traits(compiles, { enum Test75*         t75 = new Test75(0);         return t75; }));\n\nstatic assert( __traits(compiles, { enum                    t75 = new const(Test75)(0);     return t75;}));\nstatic assert( __traits(compiles, { enum                    t75 = new immutable(Test75)(0); return t75;}));\nstatic assert( __traits(compiles, { enum const(Test75)*     t75 = new const(Test75)(0);     return t75;}));\nstatic assert( __traits(compiles, { enum immutable(Test75)* t75 = new immutable(Test75)(0); return t75;}));\n+/\n/******************************************************/\n\nclass Test76\n{\n    this(int) pure {}\n}\n/+\nstatic assert(!__traits(compiles, { enum                   t76 = new shared(Test76)(0); return t76;}));\nstatic assert(!__traits(compiles, { enum                   t76 = new Test76(0);         return t76;}));\nstatic assert(!__traits(compiles, { enum shared(Test76)    t76 = new shared(Test76)(0); return t76;}));\nstatic assert(!__traits(compiles, { enum Test76            t76 = new Test76(0);         return t76;}));\n\nstatic assert( __traits(compiles, { enum                   t76 = new const(Test76)(0);     return t76;}));\nstatic assert( __traits(compiles, { enum                   t76 = new immutable(Test76)(0); return t76;}));\nstatic assert( __traits(compiles, { enum const(Test76)     t76 = new const(Test76)(0);     return t76;}));\nstatic assert( __traits(compiles, { enum immutable(Test76) t76 = new immutable(Test76)(0); return t76;}));\n+/\n/******************************************************/\n\nstatic assert( __traits(compiles, { static shared Test76    t76 = new shared(Test76)(0);   return t76; }));\nstatic assert( __traits(compiles, { static shared(Test76)   t76 = new shared(Test76)(0);   return t76; }));\nstatic assert( __traits(compiles, { static __gshared Test76 t76 = new Test76(0);           return t76; }));\nstatic assert( __traits(compiles, { static const Test76     t76 = new const(Test76)(0);    return t76; }));\nstatic assert( __traits(compiles, { static immutable Test76 t76 = new immutable Test76(0); return t76; }));\nstatic assert(!__traits(compiles, { static Test76           t76 = new Test76(0);           return t76; }));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5678\n\nstruct Bug5678\n{\n    this(int) {}\n}\n\nstatic assert(!__traits(compiles, { enum const(Bug5678)* b5678 = new const(Bug5678)(0); return b5678; }));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10782\n// run semantic2 for class field\n\nenum e10782 = 0;\nclass C10782 { int x = e10782; }\nstring f10782()\n{\n    auto c = new C10782();\n    return \"\";\n}\nmixin(f10782());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10929\n// NRVO support in CTFE\n\nstruct S10929\n{\n    this(this)\n    {\n        postblitCount++;\n    }\n    ~this()\n    {\n        dtorCount++;\n    }\n    int payload;\n    int dtorCount;\n    int postblitCount;\n}\n\nauto makeS10929()\n{\n    auto s = S10929(42, 0, 0);\n    return s;\n}\n\nbool test10929()\n{\n    auto s = makeS10929();\n    assert(s.postblitCount == 0);\n    assert(s.dtorCount == 0);\n    return true;\n};\nstatic assert(test10929());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9245\n// support postblit call on array assignments\n\nbool test9245()\n{\n    int postblits = 0;\n    struct S\n    {\n        this(this)\n        {\n            ++postblits;\n        }\n    }\n\n    S s;\n    S[2] a;\n    assert(postblits == 0);\n\n    {\n        S[2] arr = s;\n        assert(postblits == 2);\n        arr[] = s;\n        assert(postblits == 4);\n        postblits = 0;\n\n        S[2] arr2 = arr;\n        assert(postblits == 2);\n        arr2 = arr;\n        assert(postblits == 4);\n        postblits = 0;\n\n        const S[2] constArr = s;\n        assert(postblits == 2);\n        postblits = 0;\n\n        const S[2] constArr2 = arr;\n        assert(postblits == 2);\n        postblits = 0;\n    }\n    {\n        S[2][2] arr = s;\n        assert(postblits == 4);\n        arr[] = a;\n        assert(postblits == 8);\n        postblits = 0;\n\n        S[2][2] arr2 = arr;\n        assert(postblits == 4);\n        arr2 = arr;\n        assert(postblits == 8);\n        postblits = 0;\n\n        const S[2][2] constArr = s;\n        assert(postblits == 4);\n        postblits = 0;\n\n        const S[2][2] constArr2 = arr;\n        assert(postblits == 4);\n        postblits = 0;\n    }\n\n    return true;\n}\nstatic assert(test9245());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12906\n// don't call postblit on blit initializing\n\nstruct S12906 { this(this) { assert(0); } }\n\nstatic assert({\n    S12906[1] arr;\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11510\n// support overlapped field access in CTFE\n\nstruct S11510\n{\n    union\n    {\n        size_t x;\n        int* y; // pointer field\n    }\n}\nbool test11510()\n{\n    S11510 s;\n\n    s.y = [1,2,3].ptr;            // writing overlapped pointer field is OK\n    assert(s.y[0 .. 3] == [1,2,3]); // reading valid field is OK\n\n    s.x = 10;\n    assert(s.x == 10);\n\n    // There's no reinterpretation between S.x and S.y\n    return true;\n}\nstatic assert(test11510());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11534\n// subtitude inout\n\nstruct MultiArray11534\n{\n    void set(size_t[] sizes...)\n    {\n        storage = new size_t[5];\n    }\n\n    @property auto raw_ptr() inout\n    {\n        return storage.ptr + 1;\n    }\n    size_t[] storage;\n}\n\nenum test11534 = () {\n    auto m = MultiArray11534();\n    m.set(3,2,1);\n    auto start = m.raw_ptr;   //this trigger the bug\n    //auto start = m.storage.ptr + 1; //this obviously works\n    return 0;\n}();\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11941\n// Regression of 11534 fix\n\nvoid takeConst11941(const string[]) {}\nstring[] identity11941(string[] x) { return x; }\n\nbool test11941a()\n{\n    struct S { string[] a; }\n    S s;\n\n    takeConst11941(identity11941(s.a));\n    s.a ~= [];\n\n    return true;\n}\nstatic assert(test11941a());\n\nbool test11941b()\n{\n    struct S { string[] a; }\n    S s;\n\n    takeConst11941(identity11941(s.a));\n    s.a ~= \"foo\"; /* Error refers to this line (15), */\n    string[] b = s.a[]; /* but only when this is here. */\n\n    return true;\n}\nstatic assert(test11941b());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11535\n// element-wise assignment from string to ubyte array literal\n\nstruct Hash11535\n{\n    ubyte[6] _buffer;\n\n    void put(scope const(ubyte)[] data...)\n    {\n        uint i = 0, index = 0;\n        auto inputLen = data.length;\n\n        (&_buffer[index])[0 .. inputLen - i] = (&data[i])[0 .. inputLen - i];\n    }\n}\n\nauto md5_digest11535(T...)(scope const T data)\n{\n    Hash11535 hash;\n    hash.put(cast(const(ubyte[]))data[0]);\n    return hash._buffer;\n}\n\nstatic assert(md5_digest11535(`TEST`) == [84, 69, 83, 84, 0, 0]);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11540\n// goto label + try-catch-finally / with statement\n\nstatic assert(()\n{\n    // enter to TryCatchStatement.body\n    {\n        bool c = false;\n        try\n        {\n            if (c)  // need to bypass front-end optimization\n                throw new Exception(\"\");\n            else\n            {\n                goto Lx;\n              L1:\n                c = true;\n            }\n        }\n        catch (Exception e) {}\n\n      Lx:\n        if (!c)\n            goto L1;\n    }\n\n    // jump inside TryCatchStatement.body\n    {\n        bool c = false;\n        try\n        {\n            if (c)  // need to bypass front-end optimization\n                throw new Exception(\"\");\n            else\n                goto L2;\n          L2:\n            ;\n        }\n        catch (Exception e) {}\n    }\n\n    // exit from TryCatchStatement.body\n    {\n        bool c = false;\n        try\n        {\n            if (c)  // need to bypass front-end optimization\n                throw new Exception(\"\");\n            else\n                goto L3;\n        }\n        catch (Exception e) {}\n\n        c = true;\n      L3:\n        assert(!c);\n    }\n\n    return 1;\n}());\n\nstatic assert(()\n{\n    // enter to TryCatchStatement.catches which has no exception variable\n    {\n        bool c = false;\n        goto L1;\n        try\n        {\n            c = true;\n        }\n        catch (Exception/* e*/)\n        {\n          L1:\n            ;\n        }\n        assert(c == false);\n    }\n\n    // jump inside TryCatchStatement.catches\n    {\n        bool c = false;\n        try\n        {\n            throw new Exception(\"\");\n        }\n        catch (Exception e)\n        {\n            goto L2;\n            c = true;\n          L2:\n            ;\n        }\n        assert(c == false);\n    }\n\n    // exit from TryCatchStatement.catches\n    {\n        bool c = false;\n        try\n        {\n            throw new Exception(\"\");\n        }\n        catch (Exception e)\n        {\n            goto L3;\n            c = true;\n        }\n      L3:\n        assert(c == false);\n    }\n\n    return 1;\n}());\n\nstatic assert(()\n{\n    // enter forward to TryFinallyStatement.body\n    {\n        bool c = false;\n        goto L0;\n        c = true;\n        try\n        {\n          L0:\n            ;\n        }\n        finally {}\n        assert(!c);\n    }\n\n    // enter back to TryFinallyStatement.body\n    {\n        bool c = false;\n        try\n        {\n            goto Lx;\n          L1:\n            c = true;\n        }\n        finally {\n        }\n\n      Lx:\n        if (!c)\n            goto L1;\n    }\n\n    // jump inside TryFinallyStatement.body\n    {\n        try\n        {\n            goto L2;\n          L2: ;\n        }\n        finally {}\n    }\n\n    // exit from TryFinallyStatement.body\n    {\n        bool c = false;\n        try\n        {\n            goto L3;\n        }\n        finally {}\n\n        c = true;\n      L3:\n        assert(!c);\n    }\n\n    // enter in / exit out from finally block is rejected in semantic analysis\n\n    // jump inside TryFinallyStatement.finalbody\n    {\n        bool c = false;\n        try\n        {\n        }\n        finally\n        {\n            goto L4;\n            c = true;\n          L4:\n            assert(c == false);\n        }\n    }\n\n    return 1;\n}());\n\nstatic assert(()\n{\n    {\n        bool c = false;\n        with (Object.init)\n        {\n            goto L2;\n            c = true;\n          L2:\n            ;\n        }\n        assert(c == false);\n    }\n\n    {\n        bool c = false;\n        with (Object.init)\n        {\n            goto L3;\n            c = true;\n        }\n      L3:\n        assert(c == false);\n    }\n\n    return 1;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11627\n//cast dchar to char at compile time on AA assignment\n\nbool test11627()\n{\n    char[ubyte] toCharTmp;\n    dchar letter = 'A';\n\n    //char c = cast(char)letter;    // OK\n    toCharTmp[0] = cast(char)letter;    // NG\n\n    return true;\n}\nstatic assert(test11627());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11664\n// ignore function local static variables\n\nbool test11664()\n{\n    static int x;\n    static int y = 1;\n    return true;\n}\nstatic assert(test11664());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12110\n// operand of dereferencing does not need to be an lvalue\n\nstruct SliceOverIndexed12110\n{\n    Uint24Array12110* arr;\n\n    @property front(uint val)\n    {\n        arr.dupThisReference();\n    }\n}\n\nstruct Uint24Array12110\n{\n    ubyte[] data;\n\n    this(ubyte[] range)\n    {\n        data = range;\n        SliceOverIndexed12110(&this).front = 0;\n        assert(data.length == range.length * 2);\n    }\n\n    void dupThisReference()\n    {\n        auto new_data = new ubyte[data.length * 2];\n        data = new_data;\n    }\n}\n\nstatic m12110 = Uint24Array12110([0x80]);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12310\n// heap allocation for built-in sclar types\n\nbool test12310()\n{\n    auto p1 = new int, p2 = p1;\n    assert(*p1 == 0);\n    assert(*p2 == 0);\n    *p1 = 10;\n    assert(*p1 == 10);\n    assert(*p2 == 10);\n\n    auto q1 = new int(3), q2 = q1;\n    assert(*q1 == 3);\n    assert(*q2 == 3);\n    *q1 = 20;\n    assert(*q1 == 20);\n    assert(*q2 == 20);\n\n    return true;\n}\nstatic assert(test12310());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12499\n// initialize TupleDeclaraion in CTFE\n\nauto f12499()\n{\n    //Initialize 3 ints to 5.\n    TypeTuple!(int, int, int) a = 5;\n    return a[0]; //Error: variable _a_field_0 cannot be read at compile time\n}\nstatic assert(f12499() == 5);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12602\n// slice in struct literal members\n\nstruct Result12602\n{\n    uint[] source;\n}\n\nauto wrap12602a(uint[] r)\n{\n    return Result12602(r);\n}\n\nauto wrap12602b(uint[] r)\n{\n    Result12602 x;\n    x.source = r;\n    return x;\n}\n\nauto testWrap12602a()\n{\n    uint[] dest = [1, 2, 3, 4];\n\n    auto ra = wrap12602a(dest[0 .. 2]);\n    auto rb = wrap12602a(dest[2 .. 4]);\n\n    foreach (i; 0 .. 2)\n        rb.source[i] = ra.source[i];\n\n    assert(ra.source == [1,2]);\n    assert(rb.source == [1,2]);\n    assert(&ra.source[0] == &dest[0]);\n    assert(&rb.source[0] == &dest[2]);\n    assert(dest == [1,2,1,2]);\n    return dest;\n}\n\nauto testWrap12602b()\n{\n    uint[] dest = [1, 2, 3, 4];\n\n    auto ra = wrap12602b(dest[0 .. 2]);\n    auto rb = wrap12602b(dest[2 .. 4]);\n\n    foreach (i; 0 .. 2)\n        rb.source[i] = ra.source[i];\n\n    assert(ra.source == [1,2]);\n    assert(rb.source == [1,2]);\n    assert(&ra.source[0] == &dest[0]);\n    assert(&rb.source[0] == &dest[2]);\n    assert(dest == [1,2,1,2]);\n    return dest;\n}\n\nauto testWrap12602c()\n{\n    uint[] dest = [1, 2, 3, 4];\n\n    auto ra = Result12602(dest[0 .. 2]);\n    auto rb = Result12602(dest[2 .. 4]);\n\n    foreach (i; 0 .. 2)\n        rb.source[i] = ra.source[i];\n\n    assert(ra.source == [1,2]);\n    assert(rb.source == [1,2]);\n    assert(&ra.source[0] == &dest[0]);\n    assert(&rb.source[0] == &dest[2]);\n    assert(dest == [1,2,1,2]);\n    return dest;\n}\n\nauto testWrap12602d()\n{\n    uint[] dest = [1, 2, 3, 4];\n\n    Result12602 ra; ra.source = dest[0 .. 2];\n    Result12602 rb; rb.source = dest[2 .. 4];\n\n    foreach (i; 0 .. 2)\n        rb.source[i] = ra.source[i];\n\n    assert(ra.source == [1,2]);\n    assert(rb.source == [1,2]);\n    assert(&ra.source[0] == &dest[0]);\n    assert(&rb.source[0] == &dest[2]);\n    assert(dest == [1,2,1,2]);\n    return dest;\n}\n\nstatic assert(testWrap12602a() == [1,2,1,2]);\nstatic assert(testWrap12602b() == [1,2,1,2]);\nstatic assert(testWrap12602c() == [1,2,1,2]);\nstatic assert(testWrap12602d() == [1,2,1,2]);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12677\n// class type initializing from DotVarExp\n\nfinal class C12677\n{\n    TypeTuple!(Object, int[]) _test;\n    this()\n    {\n        auto t0 = _test[0]; //\n        auto t1 = _test[1]; //\n        assert(t0 is null);\n        assert(t1 is null);\n    }\n}\n\nstruct S12677\n{\n    auto f = new C12677();\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12851\n// interpret function local const static array\n\nvoid test12851()\n{\n    const int[5] arr;\n    alias staticZip = TypeTuple!(arr[0]);\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13630\n// indexing and setting array element via pointer\n\nstruct S13630(T)\n{\n    T[3] arr;\n\n    this(A...)(auto ref in A args)\n    {\n        auto p = arr.ptr;\n\n        foreach (ref v; args)\n        {\n            *p = 0;\n        }\n    }\n}\n\nenum s13630 = S13630!float(1);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13827\n\nstruct Matrix13827(T, uint N)\n{\n    private static defaultMatrix()\n    {\n        T[N] arr;\n        return arr;\n    }\n\n    union\n    {\n        T[N] A = defaultMatrix;\n        T[N] flat;\n    }\n\n    this(A...)(auto ref in A args)\n    {\n        uint k;\n\n        foreach (ref v; args)\n            flat[k++] = cast(T)v;\n    }\n}\nenum m13827 = Matrix13827!(int, 3)(1, 2, 3);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13847\n// support DotTypeExp\n\nclass B13847\n{\n    int foo() { return 1; }\n}\n\nclass C13847 : B13847\n{\n    override int foo() { return 2; }\n\n    final void test(int n)\n    {\n        assert(foo() == n);\n        assert(B13847.foo() == 1);\n        assert(C13847.foo() == 2);\n        assert(this.B13847.foo() == 1);\n        assert(this.C13847.foo() == 2);\n    }\n}\n\nclass D13847 : C13847\n{\n    override int foo() { return 3; }\n}\n\nstatic assert({\n    C13847 c = new C13847();\n    c.test(2);\n    assert(c.B13847.foo() == 1);\n    assert(c.C13847.foo() == 2);\n\n    D13847 d = new D13847();\n    d.test(3);\n    assert(d.B13847.foo() == 1);\n    assert(d.C13847.foo() == 2);\n    assert(d.D13847.foo() == 3);\n\n    c = d;\n    c.test(3);\n    assert(c.B13847.foo() == 1);\n    assert(c.C13847.foo() == 2);\n    return true;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12495\n// cast from string to immutable(ubyte)[]\n\nstring getStr12495()\n{\n    char[1] buf = void;                     // dummy starting point.\n    string s = cast(string)buf[0..0];       // empty slice, .ptr points mutable.\n    assert(buf.ptr == s.ptr);\n    s ~= 'a';                               // this should allocate.\n    assert(buf.ptr != s.ptr);\n    return s.idup;                          // this should allocate again, and\n                                            // definitely point immutable memory.\n}\nauto indexOf12495(string s)\n{\n    auto p1 = s.ptr;\n    auto p2 = (cast(immutable(ubyte)[])s).ptr;\n    assert(cast(void*)p1 == cast(void*)p2); // OK <- fails\n    return cast(void*)p2 - cast(void*)p1;   // OK <- \"cannot subtract pointers ...\"\n}\nstatic assert(indexOf12495(getStr12495()) == 0);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13992\n// Repainting pointer arithmetic result\n\nenum hash13992 = hashOf13992(\"abcd\".ptr);\n\n@trusted hashOf13992(const void* buf)\n{\n    auto data = cast(const(ubyte)*) buf;\n    size_t hash;\n    data += 2;      // problematic pointer arithmetic\n    hash += *data;  // CTFE internal issue was shown by the dereference\n    return hash;\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13739\n// Precise copy for ArrayLiteralExp elements\n\nstatic assert(\n{\n    int[] a1 = [13];\n    int[][] a2 = [a1];\n    assert(a2[0] is a1);            // OK\n    assert(a2[0].ptr is a1.ptr);    // OK <- NG\n\n    a1[0] = 1;\n    assert(a2[0][0] == 1);  // OK <- NG\n\n    a2[0][0] = 2;\n    assert(a1[0] == 2);     // OK <- NG\n\n    return 1;\n}());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14463\n// ICE on slice assignment without postblit\n\nstruct Boo14463\n{\n    private int[1] c;\n    this(int[] x)\n    {\n        c = x;\n    }\n}\nimmutable Boo14463 a14463 = Boo14463([1]);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13295\n// Don't copy struct literal in VarExp::interpret()\n\nstruct S13295\n{\n    int n;\n}\n\nvoid f13295(ref const S13295 s)\n{\n    *cast(int*) &s.n = 1;\n    assert(s.n == 1);     // OK <- fail\n}\n\nstatic assert(\n{\n    S13295 s;\n    f13295(s);\n    return s.n == 1; // true <- false\n}());\n\nint foo14061(int[] a)\n{\n    foreach (immutable x; a)\n    {\n        auto b = a ~ x;\n        return b == [1, 1];\n    }\n    return 0;\n}\nstatic assert(foo14061([1]));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14024\n// CTFE version\n\nbool test14024()\n{\n    string op;\n\n    struct S\n    {\n        char x = 'x';\n        this(this) { op ~= x-0x20; }    // upper case\n        ~this()    { op ~= x; }         // lower case\n    }\n\n    S[4] mem;\n    ref S[2] slice(int a, int b) { return mem[a .. b][0 .. 2]; }\n\n    op = null;\n    mem[0].x = 'a';\n    mem[1].x = 'b';\n    mem[2].x = 'x';\n    mem[3].x = 'y';\n    slice(0, 2) = slice(2, 4);  // [ab] = [xy]\n    assert(op == \"XaYb\", op);\n\n    op = null;\n    mem[0].x = 'x';\n    mem[1].x = 'y';\n    mem[2].x = 'a';\n    mem[3].x = 'b';\n    slice(2, 4) = slice(0, 2);  // [ab] = [xy]\n    assert(op == \"XaYb\", op);\n\n    op = null;\n    mem[0].x = 'a';\n    mem[1].x = 'b';\n    mem[2].x = 'c';\n    slice(0, 2) = slice(1, 3);  // [ab] = [bc]\n    assert(op == \"BaCb\", op);\n\n    op = null;\n    mem[0].x = 'x';\n    mem[1].x = 'y';\n    mem[2].x = 'z';\n    slice(1, 3) = slice(0, 2);  // [yz] = [xy]\n    assert(op == \"YzXy\", op);\n\n    return true;\n}\nstatic assert(test14024());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14304\n// cache of static immutable value\n\nimmutable struct Bug14304\n{\n    string s_name;\n    alias s_name this;\n\n    string fun()()\n    {\n        return \"fun\";\n    }\n}\nclass Buggy14304\n{\n    static string fun(string str)()\n    {\n        return str;\n    }\n    static immutable val = immutable Bug14304(\"val\");\n}\nvoid test14304()\n{\n    enum kt = Buggy14304.fun!(Buggy14304.val);\n    static assert(kt == \"val\");\n    enum bt = Buggy14304.val.fun();\n    static assert(bt == \"fun\");\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14371\n// evaluate BinAssignExp as lvalue\n\nint test14371()\n{\n    int x;\n    ++(x += 1);\n    return x;\n}\nstatic assert(test14371() == 2);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7151\n// [CTFE] cannot compare classes with ==\n\nbool test7151()\n{\n    auto a = new Object;\n    return a == a && a != new Object;\n}\nstatic assert(test7151());\n\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12603\n// [CTFE] goto does not correctly call dtors\n\nstruct S12603\n{\n    this(uint* dtorCalled)\n    {\n        *dtorCalled = 0;\n        this.dtorCalled = dtorCalled;\n    }\n\n    @disable this();\n\n    ~this()\n    {\n        ++*dtorCalled;\n    }\n\n    uint* dtorCalled;\n}\n\n\nauto numDtorCallsByGotoWithinScope()\n{\n    uint dtorCalled;\n    {\n        S12603 s = S12603(&dtorCalled);\n        assert(dtorCalled == 0);\n        goto L_abc;\n        L_abc:\n        assert(dtorCalled == 0);\n    }\n    assert(dtorCalled == 1);\n    return dtorCalled;\n}\nstatic assert(numDtorCallsByGotoWithinScope() == 1);\n\n\nauto numDtorCallsByGotoOutOfScope()\n{\n    uint dtorCalled;\n    {\n        S12603 s = S12603(&dtorCalled);\n        assert(dtorCalled == 0);\n        goto L_abc;\n    }\n    L_abc:\n    assert(dtorCalled == 1);\n    return dtorCalled;\n}\nstatic assert(numDtorCallsByGotoOutOfScope() == 1);\n\n\nuint numDtorCallsByGotoDifferentScopeAfter()\n{\n    uint dtorCalled;\n    {\n        S12603 s = S12603(&dtorCalled);\n        assert(dtorCalled == 0);\n    }\n    assert(dtorCalled == 1);\n    goto L_abc;\n    L_abc:\n    assert(dtorCalled == 1);\n    return dtorCalled;\n}\nstatic assert(numDtorCallsByGotoDifferentScopeAfter() == 1);\n\n\nauto numDtorCallsByGotoDifferentScopeBefore()\n{\n    uint dtorCalled;\n    assert(dtorCalled == 0);\n    goto L_abc;\n    L_abc:\n    assert(dtorCalled == 0);\n    {\n        S12603 s = S12603(&dtorCalled);\n        assert(dtorCalled == 0);\n    }\n    assert(dtorCalled == 1);\n    return dtorCalled;\n}\nstatic assert(numDtorCallsByGotoDifferentScopeBefore() == 1);\n\n\nstruct S12603_2\n{\n    ~this()\n    {\n        dtorCalled = true;\n    }\n\n    bool dtorCalled = false;\n}\n\nauto structInCaseScope()\n{\n    auto charsets = S12603_2();\n    switch(1)\n    {\n    case 0:\n        auto set = charsets;\n        break;\n    default:\n        break;\n    }\n    return charsets.dtorCalled;\n}\n\nstatic assert(!structInCaseScope());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15233\n// ICE in TupleExp, Copy On Write bug\n\nalias TT15233(stuff ...) = stuff;\n\nstruct Tok15233 {}\nenum tup15233 = TT15233!(Tok15233(), \"foo\");\nstatic assert(tup15233[0] == Tok15233());\nstatic assert(tup15233[1] == \"foo\");\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15251\n// void cast in ForStatement.increment\n\nint test15251()\n{\n    for (ubyte lwr = 19;\n        lwr != 20;\n        cast(void)++lwr)    // have to to be evaluated with ctfeNeedNothing\n    {}\n    return 1;\n}\nstatic assert(test15251());\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15998\n// Sagfault caused by memory corruption\n\nimmutable string[2] foo15998 = [\"\",\"\"];\nimmutable string[2][] bar15998a = foo15998 ~ baz15998;\nimmutable string[2][] bar15998b = baz15998 ~ foo15998;\n\nauto baz15998()\n{\n    immutable(string[2])[] r;\n    return r;\n}\n\nstatic assert(bar15998a == [[\"\", \"\"]]);\nstatic assert(bar15998b == [[\"\", \"\"]]);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16094\n// Non-overlapped slice assignment on an aggregate\n\nchar[] f16094a()\n{\n    char[] x = new char[](6);\n    x[3..6] = x[0..3];\n    return x;\n}\n\nint[] f16094b()\n{\n    int[] x = new int[](6);\n    x[3..6] = x[0..3];\n    return x;\n}\n\nenum copy16094a = f16094a();\nenum copy16094b = f16094b();\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17407\n\nbool foo17407()\n{\n    void delegate ( ) longest_convert;\n    return __traits(compiles, longest_convert = &doesNotExists);\n}\n\nstatic assert(!foo17407);\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18057\n// Recursive field initializer causes segfault.\n\nstruct RBNode(T)\n{\n    RBNode!T *copy = new RBNode!T;\n}\n\nstatic assert(!__traits(compiles, { alias bug18057 = RBNode!int; }));\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=19140\n\nvoid test19140()\n{\n    real f19140();\n    static if (__traits(compiles, (){ enum real r = f19140(); })) {}\n}\n\n/**************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=19074\n\nstruct S19074a { }\n\nstruct S19074b\n{\n    S19074a field;\n    this(S19074a) { }\n\n    static const S19074b* data = new S19074b(S19074a());\n}\n\nvoid test19074()\n{\n    auto var = S19074b.data;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/isZeroInit.d",
    "content": "alias AliasSeq(T...) = T;\n\nstruct Holder(T, ubyte val)\n{\n    T x = val;\n}\n\nstruct SArrayHolder(T, ubyte val)\n{\n    T[2] x = val;\n}\n\nstatic foreach (T; AliasSeq!(bool, byte, short, int, long,\n                             ubyte, ushort, uint, ulong,\n                             char, wchar, dchar,\n                             float, double, real))\n{\n    static assert(__traits(isZeroInit, T) == (T.init is T(0)));\n    static assert(__traits(isZeroInit, T[2]) == (T.init is T(0)));\n\n    static assert(!__traits(isZeroInit, Holder!(T, 1)));\n    static assert(__traits(isZeroInit, Holder!(T, 0)));\n\n    static assert(__traits(isZeroInit, SArrayHolder!(T, 0)));\n    static assert(!__traits(isZeroInit, SArrayHolder!(T, 1)));\n\n}\n\nstatic assert(__traits(isZeroInit, void)); // For initializing arrays of element type `void`.\nstatic assert(__traits(isZeroInit, void*));\nstatic assert(__traits(isZeroInit, void[]));\nstatic assert(__traits(isZeroInit, float[]));\nstatic assert(__traits(isZeroInit, Object));\nclass C1 : Object\n{\n    int x = 1;\n}\nstatic assert(__traits(isZeroInit, C1)); // An Object's fields are irrelevant.\n\nstruct S1\n{\n    int[] a;\n    int b;\n}\nstatic assert(__traits(isZeroInit, S1));\n\nstruct S2\n{\n    alias H = Holder!(int, 1);\n    H h;\n    int a;\n}\nstatic assert(!__traits(isZeroInit, S2));\n\nstruct S3\n{\n    S1 h;\n    float f = 0;\n}\nstatic assert(__traits(isZeroInit, S3));\n\nstruct S4\n{\n    S2 h = S2(S2.H(0), 0);\n    int a;\n}\nstatic assert(__traits(isZeroInit, S4));\n\nstruct S5\n{\n    Object o = null;\n}\nstatic assert(__traits(isZeroInit, S5));\n\nversion(D_SIMD):\nimport core.simd : int4;\nstatic assert(__traits(isZeroInit, Holder!(int4, 0)));\nstatic assert(!__traits(isZeroInit, Holder!(int4, 1)));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/issue18097.d",
    "content": "// REQUIRED_ARGS: -unittest\nmodule issue18097;\n\nunittest // this first unittest is needed to trigger the bug\n{\n}\n\nunittest // second unittest\n{\n    auto a = &mixin(__traits(identifier, __traits(parent, {  })));\n    auto b = &__traits(parent, {  });\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/json.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -dip1000 -o- -X -Xf${RESULTS_DIR}/compilable/json.out\n// POST_SCRIPT: compilable/extra-files/json-postscript.sh\n// EXTRA_FILES: imports/jsonimport1.d imports/jsonimport2.d imports/jsonimport3.d imports/jsonimport4.d\n\nmodule json;\n\n\nstatic this() {}\n\nstatic ~this() {}\n\n\nalias int myInt;\nmyInt x; // https://issues.dlang.org/show_bug.cgi?id=3404\n\nstruct Foo(T) { T t; }\nclass  Bar(int T) { int t = T; }\ninterface Baz(T...) { T[0] t() const; } // https://issues.dlang.org/show_bug.cgi?id=3466\n\ntemplate P(alias T) {}\n\nclass Bar2 : Bar!1, Baz!(int, 2, null) {\n    this() {}\n    ~this() {} // https://issues.dlang.org/show_bug.cgi?id=4178\n\n    static foo() {}\n    protected abstract Foo!int baz();\n    override int t() const { return 0; }\n}\n\nclass Bar3 : Bar2 {\n    private int val;\n    this(int i) { val = i; }\n\n    protected override Foo!int baz() { return Foo!int(val); }\n}\n\nstruct Foo2 {\n    Bar2 bar2;\n    union U {\n        struct {\n            short s;\n            int i;\n        }\n        Object o;\n    }\n}\n\nstruct Foo3(bool b) {\n    version(D_Ddoc) {\n        /// Doc 1\n        void method1();\n    }\n    static if (b) {\n        /// Doc 2\n        void method2();\n    } else {\n        /// Doc 3\n        void method3();\n    }\n\n    /// Doc 4\n    void method4();\n}\n\n/++\n + Documentation test\n +/\n@trusted myInt bar(ref uint blah, Bar2 foo = new Bar3(7)) // https://issues.dlang.org/show_bug.cgi?id=4477\n{\n    return -1;\n}\n\n@property int outer() nothrow\nin {\n    assert(true);\n}\nout(result) {\n    assert(result == 18);\n}\nbody {\n    int x = 8;\n    int inner(void* v) nothrow\n    {\n        int y = 2;\n        assert(true);\n        return x + y;\n    }\n    int z = inner(null);\n    return x + z;\n}\n\n/** Issue 9484 - selective and renamed imports */\nimport imports.jsonimport1 : target1, target2;\nimport imports.jsonimport2 : alias1 = target1, alias2 = target2;\nimport imports.jsonimport3 : alias3 = target1, alias4 = target2, target3;\nimport imports.jsonimport4;\n\nstruct S\n{\n    /** Issue 9480 - Template name should be stripped of parameters */\n    this(T)(T t) { }\n}\n\n/** Issue 9755 - Protection not emitted properly for Templates. */\nprivate struct S1_9755(T) { }\npackage struct S2_9755(T) { }\n\nclass C_9755\n{\n    protected static class CI_9755(T) { }\n}\n\n/** Issue 10011 - init property is wrong for object initializer. */\nconst Object c_10011 = new Object();\n\n///\nenum Numbers\n{\n    unspecified1,\n    one  = 2,\n    two  = 3,\n    FILE_NOT_FOUND = 101,\n    unspecified3,\n    unspecified4,\n    four = 4,\n}\n\ntemplate IncludeConstraint(T) if (T == string) {}\n\nstatic foreach(enum i; 0..3)\n{\n    mixin(\"int a\" ~ i.stringof ~ \" = 1;\");\n}\n\nalias Seq(T...) = T;\n\nstatic foreach(int i, alias a; Seq!(a0, a1, a2))\n{\n\tmixin(\"alias b\" ~ i.stringof ~ \" = a;\");\n}\n\n// return ref, return scope, return ref scope\nref int foo(return ref int a) @safe\n{\n\treturn a;\n}\n\nint* foo(return scope int* a) @safe\n{\n\treturn a;\n}\n\nref int* foo(scope return ref int* a) @safe\n{\n\treturn a;\n}\n\nstruct SafeS\n{\n@safe:\n    ref SafeS foo() return\n    {\n        return this;\n    }\n\n    SafeS foo2() return scope\n    {\n        return this;\n    }\n\n    ref SafeS foo3() return scope\n    {\n        return this;\n    }\n\n\tint* p;\n}\n\nextern int vlinkageDefault;\nextern(D) int vlinkageD;\nextern(C) int vlinakgeC;\nextern(C++) __gshared int vlinkageCpp;\nextern(Windows) int vlinkageWindows;\nextern(Pascal) int vlinkagePascal;\nextern(Objective-C) int vlinkageObjc;\n\nextern int flinkageDefault();\nextern(D) int flinkageD();\nextern(C) int linakgeC();\nextern(C++) int flinkageCpp();\nextern(Windows) int flinkageWindows();\nextern(Pascal) int flinkagePascal();\nextern(Objective-C) int flinkageObjc();\n\nmixin template test18211(int n)\n{\n    static foreach (i; 0 .. n>10 ? 10 : n)\n    {\n        mixin(\"enum x\" ~ cast(char)('0' + i));\n    }\n    static if (true) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/line.d",
    "content": "module line;\n\nstatic assert(__LINE__ == 3);\n\nint #line 10\nx;\n\nstatic assert(__LINE__ == 12);\nversion(Windows) {\n    static assert(__FILE__ == \"compilable\\\\line.d\");\n    static assert(__FILE_FULL_PATH__[1..3] == \":\\\\\");\n} else {\n    static assert(__FILE__ == \"compilable/line.d\");\n    static assert(__FILE_FULL_PATH__[0] == '/');\n}\nstatic assert(__FILE_FULL_PATH__[$-__FILE__.length..$] == __FILE__);\n\n#line 100 \"newfile.d\"\n\nstatic assert(__LINE__ == 101);\nstatic assert(__FILE__ == \"newfile.d\");\nstatic assert(__FILE_FULL_PATH__[$ - 9 .. $] == \"newfile.d\");\n\n# line 200\n\nstatic assert(__LINE__ == 201);\nstatic assert(__FILE__ == \"newfile.d\");\nstatic assert(__FILE_FULL_PATH__[$ - 9 .. $] == \"newfile.d\");\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/minimal.d",
    "content": "// DFLAGS:\n// PERMUTE_ARGS:\n// POST_SCRIPT: compilable/extra-files/minimal/verify_symbols.sh\n// REQUIRED_ARGS: -defaultlib=\n// EXTRA_SOURCES: extra-files/minimal/object.d\n\n// This test ensures an empty main with a struct and enum, built with a minimal\n// runtime, does not generate ModuleInfo or exception handling code, and does not\n// require TypeInfo\n\nstruct S { }\n\nenum E \n{\n    e0 = 0,\n    e1 = 1\n}\n\nvoid main() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/minimal2.d",
    "content": "// DFLAGS:\n// REQUIRED_ARGS: -defaultlib=\n// EXTRA_SOURCES: extra-files/minimal/object.d\n\n// This test ensures that interfaces and classes can be used in a minimal\n// runtime as long as they only contain static members.\n\n// This should compile, but will not link and run properly without\n// a thread-local storage (TLS) implementation.\n\ninterface I\n{\n    static int i;\n}\n\nclass A : I\n{\n    static int a;\n}\n\nclass B : A\n{\n    static int b;\n}\n\nvoid main()\n{\n    B.i = 32;\n    B.a = 42;\n    B.b = 52;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/mixintempl.d",
    "content": "\nstruct TypeObj\n{\n    alias This = typeof(this);\n\n    mixin template MixinTempl()\n    {\n        int value;\n    }\n}\n\nref TypeObj Obj()\n{\n    static TypeObj a;\n    return a;\n}\n\nvoid func()\n{\n    mixin Obj.This.MixinTempl; // ok\n    mixin Obj.MixinTempl;      // fixed: \"MixinTempl!()\" is not defined\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/noderef.d",
    "content": "// PERMUTE_ARGS:\n// https://github.com/dlang/dmd/pull/5860\n\nint[] bar() @safe;\n\nvoid foo(int[] a) @safe\n{\n    static int[] as;\n\n    bool b;\n\n    b = a.ptr == null;\n    b = null == (*&as).ptr;\n    b = bar().ptr == null;\n\n    b = a.ptr != null;\n    b = null != (*&as).ptr;\n    b = bar().ptr != null;\n\n    b = a.ptr is null;\n    b = null is (*&as).ptr;\n    b = bar().ptr is null;\n\n    b = a.ptr !is null;\n    b = null !is (*&as).ptr;\n    b = bar().ptr !is null;\n\n    b = !a.ptr;\n    b = !(*&as).ptr;\n    b = !bar().ptr;\n\n    b = cast(bool)a.ptr;\n    b = cast(bool)(*&as).ptr;\n    b = cast(bool)bar().ptr;\n\n    b = a.ptr ? false : true;\n\n    b = a.ptr < null;\n    b = null < a.ptr;\n\n    b = a.ptr && null || a.ptr;\n\n    if (a.ptr)\n\tb = true;\n\n    while (a.ptr)\n\tb = true;\n\n    for (; a.ptr;)\n\tb = true;\n\n//    ptrdiff_t d = a.ptr - a.ptr;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/nogc.d",
    "content": "// REQUIRED_ARGS: -o-\n\n/***************** Covariance ******************/\n\nclass C1\n{\n    void foo() @nogc;\n    void bar();\n}\n\nclass D1 : C1\n{\n    override void foo();        // no error\n    override void bar() @nogc;  // no error\n}\n\n/******************************************/\n// __traits(compiles)\n\nstatic assert(__traits(compiles, new Object()));\n\nvoid foo_compiles() {}\n\n@nogc void test_compiles()\n{\n    auto fp = &foo_compiles;\n    static assert(!__traits(compiles, foo_compiles()));\n    static assert(!__traits(compiles, fp()));\n    static assert(!__traits(compiles, (*fp)()));\n\n    static assert(!__traits(compiles, [1,2,3]));\n    static assert(!__traits(compiles, [1:1, 2:2]));\n\n    struct Struct {}\n    static assert(!__traits(compiles, new int));\n    static assert(!__traits(compiles, new Struct()));\n    static assert(!__traits(compiles, new Object()));\n\n    int* p;\n    static assert(!__traits(compiles, delete p));\n\n    int[int] aa;\n    static assert(!__traits(compiles, aa[0]));\n\n    int[] a;\n    static assert(!__traits(compiles, a.length = 1));\n    static assert(!__traits(compiles, a.length += 1));\n    static assert(!__traits(compiles, a.length -= 1));\n\n    static assert(!__traits(compiles, a ~= 1));\n    static assert(!__traits(compiles, a ~ a));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12630\n\nvoid test12630() @nogc\n{\n    // All of these declarations should cause no errors.\n\n    static const ex1 = new Exception(\"invalid\");\n  //enum         ex2 = new Exception(\"invalid\");\n\n    static const arr1 = [[1,2], [3, 4]];\n    enum         arr2 = [[1,2], [3, 4]];\n\n  //static const aa1 = [1:1, 2:2];\n    enum         aa2 = [1:1, 2:2];\n\n  //static const v1 = aa1[1];\n    enum         v2 = aa2[1];\n\n    Object o;\n    //static const del1 = (delete o).sizeof;\n    //enum         del2 = (delete o).sizeof;\n\n    int[] a;\n    static const len1 = (a.length = 1).sizeof;\n    enum         len2 = (a.length = 1).sizeof;\n\n    static const cata1 = (a ~= 1).sizeof;\n    enum         cata2 = (a ~= 1).sizeof;\n\n    static const cat1 = (a ~ a).sizeof;\n    enum         cat2 = (a ~ a).sizeof;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12642\n\nstatic if (is(__vector(ulong[2])))\n{\n    import core.simd;\n\n    ulong2 test12642() @nogc\n    {\n        return [0, 0];\n    }\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13550\n\nauto foo13550() @nogc\n{\n    static int[] bar()\n    {\n        return new int[2];\n    }\n    return &bar;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/protattr.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\nimport protection.basic.tests;\nimport protection.subpkg.tests;\nimport protection.subpkg2.tests;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/protection/aggregate/mod14275.d",
    "content": "module protection.aggregate.mod14275;\n\npublic struct Foo\n{\n    package(protection) void foo() {}\n    package void foo2() {}\n}\n\npackage(protection) void bar()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/protection/basic/mod1.d",
    "content": "module protection.basic.mod1;\n\npublic void publicFoo() {}\npackage void packageFoo() {}\nprivate void privateFoo() {}\n\nclass Test\n{\n    public void publicFoo();\n    protected void protectedFoo();\n    package void packageFoo();\n    private void privateFoo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/protection/basic/tests.d",
    "content": "module protection.basic.tests;\n\nimport protection.basic.mod1;\n\nstatic assert ( is(typeof(publicFoo())));\nstatic assert ( is(typeof(packageFoo())));\nstatic assert (!is(typeof(privateFoo())));\n\nstatic assert ( is(typeof(Test.init.publicFoo())));\nstatic assert (!is(typeof(Test.init.protectedFoo())));\nstatic assert ( is(typeof(Test.init.packageFoo())));\nstatic assert (!is(typeof(Test.init.privateFoo())));\n\nclass Deriv : Test\n{\n    void stub()\n    {\n        static assert ( is(typeof(this.publicFoo())));\n        static assert ( is(typeof(this.protectedFoo())));\n        static assert ( is(typeof(this.packageFoo())));\n        static assert (!is(typeof(this.privateFoo())));\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/protection/bug/bug14275.d",
    "content": "module protection.bug.bug14275;\n\nimport protection.aggregate.mod14275;\n\n// https://issues.dlang.org/show_bug.cgi?id=14275\n\nvoid main() {\n    Foo f;\n    f.foo();\n    static assert (!is(typeof(f.foo2())));\n    bar();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/protection/subpkg/explicit.d",
    "content": "module protection.subpkg.explicit;\n\npackage(protection) void commonAncestorFoo();\npackage(protection.subpkg) void samePkgFoo();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/protection/subpkg/tests.d",
    "content": "module protection.subpkg.tests;\n\nimport crosspkg = protection.basic.mod1;\n\nstatic assert ( is(typeof(crosspkg.publicFoo())));\nstatic assert (!is(typeof(crosspkg.packageFoo())));\nstatic assert (!is(typeof(crosspkg.privateFoo())));\n\nimport samepkg = protection.subpkg.explicit;\n\nstatic assert ( is(typeof(samepkg.commonAncestorFoo())));\nstatic assert ( is(typeof(samepkg.samePkgFoo())));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/protection/subpkg2/tests.d",
    "content": "module protection.subpkg2.tests;\n\nimport pkg = protection.subpkg.explicit;\n\nstatic assert (is(typeof(pkg.commonAncestorFoo())));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/protection.d",
    "content": "// REQUIRED_ARGS: -de\nimport imports.protectionimp;\n\nalias TypeTuple(T...) = T;\n\nprivate\n{\n    void localF() {}\n    class localC {}\n    struct localS {}\n    union localU {}\n    interface localI {}\n    enum localE { foo }\n    mixin template localMT() {}\n\n    class localTC(T) {}\n    struct localTS(T) {}\n    union localTU(T) {}\n    interface localTI(T) {}\n    void localTF(T)() {}\n}\n\nvoid main()\n{\n    // Private non-template declarations\n    static assert(!__traits(compiles, privF()));\n    static assert(!__traits(compiles, privC));\n    static assert(!__traits(compiles, privS));\n    static assert(!__traits(compiles, privU));\n    static assert(!__traits(compiles, privI));\n    static assert(!__traits(compiles, privE));\n    static assert(!__traits(compiles, privMT));\n\n    // Private local non-template declarations.\n    static assert( __traits(compiles, localF()));\n    static assert( __traits(compiles, localC));\n    static assert( __traits(compiles, localS));\n    static assert( __traits(compiles, localU));\n    static assert( __traits(compiles, localI));\n    static assert( __traits(compiles, localE));\n    static assert( __traits(compiles, localMT));\n\n    // Private template declarations.\n    static assert(!__traits(compiles, privTF!int()));\n    static assert(!__traits(compiles, privTC!int));\n    static assert(!__traits(compiles, privTS!int));\n    static assert(!__traits(compiles, privTU!int));\n    static assert(!__traits(compiles, privTI!int));\n\n    // Private local template declarations.\n    static assert( __traits(compiles, localTF!int()));\n    static assert( __traits(compiles, localTC!int));\n    static assert( __traits(compiles, localTS!int));\n    static assert( __traits(compiles, localTU!int));\n    static assert( __traits(compiles, localTI!int));\n\n    // Public template function with private type parameters.\n    static assert(!__traits(compiles, publF!privC()));\n    static assert(!__traits(compiles, publF!privS()));\n    static assert(!__traits(compiles, publF!privU()));\n    static assert(!__traits(compiles, publF!privI()));\n    static assert(!__traits(compiles, publF!privE()));\n\n    // Public template function with private alias parameters.\n    static assert(!__traits(compiles, publFA!privC()));\n    static assert(!__traits(compiles, publFA!privS()));\n    static assert(!__traits(compiles, publFA!privU()));\n    static assert(!__traits(compiles, publFA!privI()));\n    static assert(!__traits(compiles, publFA!privE()));\n\n    // Private alias.\n    static assert(!__traits(compiles, privA));\n\n    // Public template mixin.\n    static assert( __traits(compiles, publMT));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14169\n\ntemplate staticMap14169(alias fun, T...)\n{\n    static if (T.length > 0)\n        alias staticMap14169 = TypeTuple!(fun!(T[0]), staticMap14169!(fun, T[1..$]));\n    else\n        alias staticMap14169 = TypeTuple!();\n}\n\nclass C14169\n{\n    private struct InnerStruct(string NameS)\n    {\n        alias Name = NameS;\n    }\n    alias DimensionNames = staticMap14169!(GetName14169, InnerStruct!\"A\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/pull6815.d",
    "content": "/* REQUIRED_ARGS: -inline -Icompilable/extra-files\n   EXTRA_FILES: extra-files/e6815.d\n */\n\nvoid b()\n{\n    import e6815 : e;\n    e(\"\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/riia_ctor.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=17494\nstruct S\n{\n    ~this() {}\n}\n\nclass C\n{\n    S s;\n\n    this() nothrow {}\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17505\nstruct Array\n{\n    int[] _payload;\n    ~this()\n    {\n        import core.stdc.stdlib : free;\n        free(_payload.ptr);\n    }\n}\n\nclass Scanner\n{\n    Array arr;\n    this() @safe {}\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17506\nstruct TreeMap\n{\n    this() @disable;\n    this(TTree tree) { this.tree = tree; }\n    TTree tree;\n}\n\nstruct TTree\n{\n    this() @disable;\n    this(int foo) {}\n    ~this() {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/scope.d",
    "content": "/*\n currently fails with extra safety checks\n PERMUTE_FIXME_ARGS: -dip1000\n*/\n\nstruct Cache\n{\n    ubyte[1] v;\n\n    ubyte[] set(ubyte[1] v)\n    {\n        return this.v[] = v[];\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/shared_destructor.d",
    "content": "struct MaybeShared\n{\n    this(this T)()\n    {\n\n    }\n\n    ~this()\n    {\n\n    }\n}\n\nvoid main() {\n    {\n        auto aboutToDie = MaybeShared();\n    }\n    {\n        auto aboutToDie = shared MaybeShared();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/staticforeach.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nstruct Tuple(T...){\n    T expand;\n    alias expand this;\n}\nauto tuple(T...)(T t){ return Tuple!T(t); }\n\n/+struct TupleStaticForeach{ // should work, but is not the fault of the static foreach implementation.\n    //pragma(msg, [tuple(1,\"2\",'3'),tuple(2,\"3\",'4')].map!((x)=>x));\n    static foreach(a,b,c;[tuple(1,\"2\",'3'),tuple(2,\"3\",'4')].map!((x)=>x)){\n        pragma(msg,a,\" \",b,\" \",c);\n    }\n}+/\n\nvoid main(){\n    static foreach(a,b,c;[tuple(1,\"2\",'3'),tuple(2,\"3\",'4')].map!((x)=>x)){\n        pragma(msg, a,\" \",b,\" \",c);\n    }\n    static struct S{\n        // (aggregate scope, forward referencing possible)\n        static assert(stripA(\"123\")==1);\n        static assert(stripA([1],2)==2);\n        static foreach(i;0..2){\n            mixin(`import imports.imp12242a`~text(i+1)~`;`);\n            static assert(stripA(\"123\")==1);\n            static assert(stripA([1],2)==2);\n        }\n        static assert(stripA(\"123\")==1);\n        static assert(stripA([1],2)==2);\n    }\n    static foreach(i;0..2){\n        // (function scope, no forward referencing)\n        mixin(`import imports.imp12242a`~text(i+1)~`;`);\n        static assert(stripA(\"123\")==1);\n        static if(i) static assert(stripA([1],2)==2);\n    }\n    static assert(stripA(\"123\")==1);\n    static assert(stripA([1],2)==2);\n}\n\nauto front(T)(T[] a){ return a[0]; }\nauto popFront(T)(ref T[] a){ a=a[1..$]; }\nauto empty(T)(T[] a){ return !a.length; }\nauto back(T)(T[] a){ return a[$-1]; }\nauto popBack(T)(ref T[] a){ a=a[0..$-1]; }\n\nstruct Iota(T){\n    T s,e;\n    @property bool empty(){ return s>=e; }\n    @property T front(){ return s; }\n    @property T back(){ return cast(T)(e-1); }\n    void popFront(){ s++; }\n    void popBack(){ e--; }\n}\nauto iota(T)(T s, T e){ return Iota!T(s,e); }\n\ntemplate map(alias a){\n    struct Map(R){\n        R r;\n        @property front(){ return a(r.front); }\n        @property back(){ return a(r.back); }\n        @property bool empty(){ return r.empty; }\n        void popFront(){ r.popFront(); }\n        void popBack(){ r.popBack(); }\n    }\n    auto map(R)(R r){ return Map!R(r); }\n}\n\ntemplate to(T:string){\n    string to(S)(S x)if(is(S:int)||is(S:size_t)||is(S:char)){\n        static if(is(S==char)) return cast(string)[x];\n        if(x<0) return \"-\"~to(-x);\n        if(x==0) return \"0\";\n        return (x>=10?to(x/10):\"\")~cast(char)(x%10+'0');\n    }\n}\nauto text(T)(T arg){ return to!string(arg); };\n\ntemplate all(alias a){\n    bool all(R)(R r){\n        foreach(x;r) if(!a(x)) return false;\n        return true;\n    }\n}\ntemplate any(alias a){\n    bool any(R)(R r){\n        foreach(x;r) if(a(x)) return true;\n        return false;\n    }\n}\nauto join(R)(R r,string sep=\"\"){\n    string a;\n    int first=0;\n    foreach(x;r){\n        if(first++) a~=sep;\n        a~=x;\n    }\n    return a;\n}\n\nstatic foreach_reverse(x;iota(0,10).map!(to!string)){\n    pragma(msg, x);\n}\n\n// create struct members iteratively\nstruct S{\n    static foreach(i;a){\n        mixin(\"int x\"~to!string(i)~\";\");\n    }\n    immutable int[] a = [0,1,2];\n}\nenum s=S(1,2,3);\npragma(msg, s);\n\n// loop over struct members\nstatic foreach(member;__traits(allMembers,S)){\n    pragma(msg, member,\": \",mixin(\"s.\"~member));\n}\n\n// print prime numbers using overload sets as state variables.\n/+\nstatic assert(is(typeof(bad57)));\nstatic assert(!is(typeof(bad53)));\n\nstatic foreach(x;iota(2,100)){\n    static foreach(y;iota(2,x)){\n        static if(!(x%y)){\n            mixin(\"void bad\"~to!string(x)~\"();\");\n        }\n    }\n    static if(!is(typeof(mixin(\"bad\"~to!string(x))))){\n        static assert(iota(2,x).all!(y=>!!(x%y)));\n        pragma(msg, x);\n    }else{\n        static assert(iota(2,x).any!(y=>!(x%y)));\n    }\n}\n+/\n\n\nalias Seq(T...)=T;\n\nalias Overloads(alias a) = Seq!(__traits(getOverloads, __traits(parent, a), __traits(identifier, a)));\n\ntemplate Parameters(alias f){\n    static if(is(typeof(f) P == function)) alias Parameters=P;\n}\n\ntemplate forward(alias a){\n    enum x=2;\n    static foreach(f;Overloads!a){\n        auto ref forward(Parameters!f args){\n            return f(args);\n        }\n    }\n    enum y=3;\n}\n\nint foo(int x){ return x; }\nstring foo(string x){ return x; }\n\nstatic assert(forward!foo(2)==2 && forward!foo(\"hi\") == \"hi\");\n\n\n// simple boilerplate-free visitor pattern\nstatic foreach(char T;'A'..'F'){\n    mixin(\"class \"~T~q{{\n        void accept(Visitor v){\n            return v.visit(this);\n        }\n    }});\n}\nalias Types = Seq!(mixin(\"Seq!(\"~iota('A','F').map!(to!string).join(\", \")~\")\"));\nabstract class Visitor{\n    static foreach(T;Types){\n        abstract void visit(T);\n    }\n}\n\nstring testVisitor(){\n    string r;\n    void writeln(T...)(T args){\n        static foreach(x;args) r~=x;\n        r~='\\n';\n    }\n    class Visitor: .Visitor{\n        static foreach(T;Types){\n            override void visit(T){\n                writeln(\"visited: \",T.stringof);\n            }\n        }\n    }\n    void main(){\n        auto v=new Visitor;\n        static foreach(T;Types){\n            v.visit(new T);\n        }\n    }\n    main();\n    return r;\n}\nstatic assert(testVisitor()==\"visited: A\nvisited: B\nvisited: C\nvisited: D\nvisited: E\n\");\n\n// iterative computation over AliasSeq:\ntemplate staticMap(alias F,T...){\n    alias state0=Seq!();\n    static foreach(i,A;T){\n        mixin(\"alias state\"~to!string(i+1)~\" = Seq!(state\"~to!string(i)~\",F!A);\");\n    }\n    alias staticMap = Seq!(mixin(\"state\"~to!string(T.length)));\n}\n\nalias arrayOf(T)=T[];\nstatic assert(is(staticMap!(arrayOf,int,char,bool,Object)==Seq!(int[], char[], bool[], Object[])));\npragma(msg, staticMap!(arrayOf,int,char,bool,Object));\n\n\nstruct StaticForeachLoopVariable{\n    int x;\n    static foreach(i;0..1){\n        mixin(\"enum x\"~text(i)~\" = i;\");\n    }\n    int y;\n    static assert(__traits(allMembers, StaticForeachLoopVariable).length==3);\n    static assert(!is(typeof(StaticForeachLoopVariable.i)));\n    static assert(!is(typeof(__traits(getMember, StaticForeachLoopVariable, \"i\"))));\n}\n\nstruct StaticForeachScopeExit{\nstatic:\n    int[] test(){\n        int[] r;\n        scope(exit) r ~= 1234;\n        {\n            static foreach(i;0..5){\n                scope(exit) r ~= i;\n            }\n            r ~= 5;\n        }\n        return r;\n    }\n    static assert(test()==[5,4,3,2,1,0]);\n}\n\nstruct StaticForeachReverseHiding{\n    static foreach(i;[0]){\n        enum i = 1; // TODO: disallow?\n        static assert(i==0);\n    }\n}\n\nstruct UnrolledForeachReverse{\nstatic:\n    alias Seq(T...)=T;\n    int[] test(){\n        int[] r;\n        foreach_reverse(i;Seq!(0,1,2,3)){\n            r~=i;\n        }\n        return r;\n    }\n    static assert(test()==[3,2,1,0]);\n}\n\nstruct StaticForeachReverse{\nstatic:\n    alias Seq(T...)=T;\n    int[] test(){\n        int[] r;\n        static foreach_reverse(i;0..4){\n            r~=i;\n        }\n        return r;\n    }\n    static assert(test()==[3,2,1,0]);\n\n    int[] test2(){\n        int[] r;\n        static foreach_reverse(i;[0,1,2,3]){\n            r~=i;\n        }\n        return r;\n    }\n    static assert(test2()==[3,2,1,0]);\n\n    int[] test3(){\n        static struct S{\n            int opApplyReverse(scope int delegate(int) dg){\n                foreach_reverse(i;0..4) if(auto r=dg(i)) return r;\n                return 0;\n            }\n        }\n        int[] r;\n        static foreach_reverse(i;S()){\n            r~=i;\n        }\n        return r;\n    }\n    static assert(test3()==[3,2,1,0]);\n\n    int[] test4(){\n        int[] r;\n        static foreach_reverse(i;Seq!(0,1,2,3)){\n            r~=i;\n        }\n        return r;\n    }\n    static assert(test()==[3,2,1,0]);\n}\n\nstruct StaticForeachByAliasDefault{\nstatic:\n    alias Seq(T...)=T;\n\n    int[] test(){\n        int a,b,c;\n        static foreach(i,x;Seq!(a,b,c)) x=i;\n        return [a,b,c];\n    }\n    static assert(test()==[0,1,2]);\n\n    int[] test2(){\n        int x=0;\n        int foo(){ return ++x; }\n        static foreach(y;Seq!foo)\n            return [y,y,y];\n    }\n    static assert(test2()==[1,2,3]);\n\n    void test3(){\n        int x=0;\n        int foo(){ return ++x; }\n        static assert(!is(typeof({\n            static foreach(enum y;Seq!foo)\n                return [y,y,y];\n        })));\n    }\n}\n\nstruct NestedStaticForeach{\n    static:\n    static foreach(i,name;[\"a\"]){\n        static foreach(j,name2;[\"d\"]){\n            mixin(\"enum \"~name~name2~\"=[i,j];\");\n        }\n    }\n    pragma(msg, ad);\n}\n\nstruct TestAliasOutsideFunctionScope{\nstatic:\n    alias Seq(T...)=T;\n    int a;\n    static foreach(alias x;Seq!(a)){\n    }\n}\n\nstruct OpApplyMultipleStaticForeach{\nstatic:\n    struct OpApply{\n        int opApply(scope int delegate(int,int) dg){\n            foreach(i;0..10) if(auto r=dg(i,i*i)) return r;\n            return 0;\n        }\n    }\n    static foreach(a,b;OpApply()){\n        mixin(`enum x`~cast(char)('0'+a)~\"=b;\");\n    }\n    static foreach(i;0..10){\n        static assert(mixin(`x`~cast(char)('0'+i))==i*i);\n    }\n}\n\n\nstruct OpApplyMultipleStaticForeachLowered{\nstatic:\n    struct OpApply{\n        int opApply(scope int delegate(int,int) dg){\n            foreach(i;0..10) if(auto r=dg(i,i*i)) return r;\n            return 0;\n        }\n    }\n    static foreach(x;{\n            static struct S(T...){ this(T k){ this.x=k; } T x; }\n            static s(T...)(T a){ return S!T(a); }\n            typeof({ foreach(a,b;OpApply()){ return s(a,b); } assert(0);}())[] r;\n            foreach(a,b;OpApply()) r~=s(a,b);\n            return r;\n        }()){\n        mixin(`enum x`~cast(char)('0'+x.x[0])~\"=x.x[1];\");\n    }\n    static foreach(i;0..10){\n        static assert(mixin(`x`~cast(char)('0'+i))==i*i);\n    }\n}\n\nstruct RangeStaticForeach{\n    static:\n    struct Range{\n        int x=0;\n        this(int x){ this.x=x; }\n        @property int front(){ return x; }\n        void popFront(){ x += 2; }\n        @property bool empty(){ return x>=10; }\n    }\n    static foreach(i;Range()){\n        mixin(`enum x`~cast(char)('0'+i)~\"=i;\");\n    }\n    static foreach(i;0..5){\n        static assert(mixin(`x`~cast(char)('0'+2*i))==2*i);\n    }\n    static assert(!is(typeof({\n        struct S{\n            static foreach(i,k;Range()){}\n        }\n    })));\n    static foreach(k;Range()){} // ok\n}\n\nstruct OpApplySingleStaticForeach{\n    static:\n    struct OpApply{\n        int opApply(scope int delegate(int) dg){\n            foreach(i;0..10) if(auto r=dg(i)) return r;\n            return 0;\n        }\n    }\n    static foreach(b;OpApply()){\n        mixin(`enum x`~cast(char)('0'+b)~\"=b;\");\n    }\n    static foreach(i;0..10){\n        static assert(mixin(`x`~cast(char)('0'+i))==i);\n    }\n}\n\nstruct TypeStaticForeach{\nstatic:\n    alias Seq(T...)=T;\n    static foreach(i,alias T;Seq!(int,double,char)){\n        mixin(`T x`~cast(char)('0'+i)~\";\");\n    }\n    pragma(msg, \"x0: \",typeof(x0));\n    pragma(msg, \"x1: \",typeof(x1));\n    pragma(msg, \"x2: \",typeof(x2));\n    static assert(is(typeof(x0)==int));\n    static assert(is(typeof(x1)==double));\n    static assert(is(typeof(x2)==char));\n}\n\nstruct AliasForeach{\nstatic:\n    alias Seq(T...)=T;\n    int[] test(){\n        int a,b,c;\n        static foreach(x;Seq!(a,b,c,2)){\n            static if(is(typeof({x=2;}))) x=2;\n        }\n        int x,y,z;\n        static foreach(alias k;Seq!(x,y,z,2)){\n            static if(is(typeof({k=2;}))) k=2;\n        }\n        int j,k,l;\n        static assert(!is(typeof({\n            static foreach(ref x;Seq!(j,k,l,2)){\n                static if(is(typeof({x=2;}))) x=2;\n            }\n        })));\n        return [x,y,z];\n    }\n    static assert(test()==[2,2,2]);\n}\n\nstruct EnumForeach{\nstatic:\n    alias Seq(T...)=T;\n    int a=1;\n    int fun(){ return 1; }\n    int gun(){ return 2; }\n    int hun(){ return 3;}\n    auto test(){\n        static foreach(i,enum x;Seq!(fun,gun,hun)){\n            static assert(i+1==x);\n        }\n        foreach(i,enum x;Seq!(fun,gun,hun)){\n            static assert(i+1==x);\n        }\n    }\n}\n\nstruct TestUninterpretable{\nstatic:\n    alias Seq(T...)=T;\n    auto test(){\n        int k;\n        static assert(!is(typeof({\n            static foreach(x;[k]){}\n        })));\n        static assert(!is(typeof({\n            foreach(enum x;[1,2,3]){}\n        })));\n        static assert(!is(typeof({\n            foreach(alias x;[1,2,3]){}\n        })));\n        foreach(enum x;Seq!(1,2,3)){} // ok\n        foreach(alias x;Seq!(1,2,3)){} // ok\n        static foreach(enum x;[1,2,3]){} // ok\n        static foreach(alias x;[1,2,3]){} // ok\n        static assert(!is(typeof({\n            static foreach(enum alias x;[1,2,3]){}\n        })));\n        int x;\n        static foreach(i;Seq!x){ } // ok\n        static foreach(i,j;Seq!(1,2,x)){ } // ok\n        static assert(!is(typeof({\n            static foreach(ref x;[1,2,3]){}\n        })));\n    }\n}\n\nstruct SeqForeachConstant{\nstatic:\n    alias Seq(T...)=T;\n    static assert(!is(typeof({\n        foreach(x;Seq!1) x=2;\n    })));\n    int test2(){\n        int r=0;\n        foreach(x;Seq!(1,2,3)){\n            enum k=x;\n            r+=k;\n        }\n        return r;\n    }\n    static assert(test2()==6);\n}\n\nstruct SeqForeachBreakContinue{\nstatic:\n    alias Seq(T...)=T;\n    int[] test(){\n        int[] r;\n        foreach(i;Seq!(0,1,2,3,4,5)){\n            if(i==2) continue;\n            if(i==4) break;\n            r~=i;\n        }\n        return r;\n    }\n    static assert(test()==[0,1,3]);\n}\n\nstruct TestStaticForeach{\nstatic:\n    int test(int x){\n        int r=0;\n    label: switch(x){\n            static foreach(i;0..10){\n                case i: r=i; break label; // TODO: remove label when restriction is lifted\n            }\n            default: r=-1; break label;\n        }\n        return r;\n    }\n    static foreach(i;0..15){\n        pragma(msg, \"test(\",i,\")→ \",test(i));\n        static assert(test(i)==(i<10?i:-1));\n    }\n\n    enum x=[1,2,3];\n\n    static foreach(i;x){\n        mixin(\"enum x\"~cast(char)('0'+i)~\"=\"~cast(char)('0'+i)~\";\");\n    }\n\n    static foreach(i;x){\n        pragma(msg, mixin(\"x\"~cast(char)('0'+i)));\n        pragma(msg,x);\n    }\n\n    int[] noBreakNoContinue(){\n        int[] r;\n        static foreach(i;0..1){\n            // if(i==3) continue; // TODO: error?\n            // if(i==7) break; // TODO: error?\n            r~=i;\n        }\n        return r;\n    }\n\n    mixin(\"enum k=3;\");\n}\n\nstatic foreach(i,j;[1,2,3]){\n    pragma(msg, i,\" \",j);\n}\n\nvoid testtest(){\n    static foreach(i,v;[1,2,3]){\n        pragma(msg, i,\" \",v);\n        static assert(i+1 == v);\n    }\n}\n\n\nstatic foreach(i;Seq!(1,2,3,4,int)){\n    static if(!is(i) && i!=2){\n        pragma(msg, i);\n    }\n}\n\nint fun(int x){\n    int r=0;\n    label: switch(x){\n        static foreach(i;Seq!(0,1,2,3,4,5,6)){\n            static if (i < 5)\n                case i: r=i; break label; // TODO: remove label when restriction is lifted\n        }\n        default: r=-1; break label;\n    }\n    return r;\n}\n\nstatic foreach(i;0..10) static assert(fun(i)==(i<5?i:-1));\n\nstatic foreach(i;0..0) { }\nvoid testEmpty(){\n    static foreach(i;0..0) { }\n}\n\nauto bug17660(){\n    int x;\n    static foreach (i; 0 .. 1) { return 3; }\n    return x;\n}\nstatic assert(bug17660()==3);\n\nint breakContinueBan(){\n    static assert(!is(typeof({\n        for(;;){\n            static foreach(i;0..1){\n                break;\n            }\n        }\n    })));\n    static assert(!is(typeof({\n        for(;;){\n            static foreach(i;0..1){\n                continue;\n            }\n        }\n    })));\n    Louter1: for(;;){\n        static foreach(i;0..1){\n            break Louter1;\n        }\n    }\n    Louter2: foreach(i;0..10){\n        static foreach(j;0..1){\n            continue Louter2;\n        }\n        return 0;\n    }\n    static foreach(i;0..1){\n        for(;;){ break; } // ok\n    }\n    return 1;\n}\nstatic assert(breakContinueBan()==1);\n\nmixin template MixinTemplate(){\n    static foreach(i;0..2){\n        mixin(`enum x`~cast(char)('0'+i)~\"=i;\");\n    }\n    static foreach(i;[0,1]){\n        mixin(`enum y`~cast(char)('0'+i)~\"=i;\");\n    }\n}\nvoid testToStatement(){\n    mixin MixinTemplate;\n    static assert(x0==0 && x1==1);\n    static assert(y0==0 && y1==1);\n}\n\nvoid bug17688(){\n    final switch(1) static foreach(x;0..1){ int y=3; case 1: return; }\n    static assert(!is(typeof(y)));\n}\n\nstruct T{ enum n = 1; }\nT foo(T v)@nogc{\n    static foreach(x;0..v.n){ }\n    return T.init;\n}\nT foo2(T v)@nogc{\n    static foreach(_;0..typeof(return).n){ }\n    return T.init;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/sw_transition_complex.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -transition=complex\n\n/*\nTEST_OUTPUT:\n---\ncompilable/sw_transition_complex.d(15): Deprecation: use of complex type `creal` is deprecated, use `std.complex.Complex!(real)` instead\ncompilable/sw_transition_complex.d(16): Deprecation: use of complex type `cdouble` is deprecated, use `std.complex.Complex!(double)` instead\ncompilable/sw_transition_complex.d(17): Deprecation: use of complex type `cfloat` is deprecated, use `std.complex.Complex!(float)` instead\ncompilable/sw_transition_complex.d(19): Deprecation: use of imaginary type `ireal` is deprecated, use `real` instead\ncompilable/sw_transition_complex.d(20): Deprecation: use of imaginary type `idouble` is deprecated, use `double` instead\ncompilable/sw_transition_complex.d(21): Deprecation: use of imaginary type `ifloat` is deprecated, use `float` instead\n---\n*/\ncreal c80value;\ncdouble c64value;\ncfloat c32value;\n\nireal i80value;\nidouble i64value;\nifloat i32value;\n\n/*\nTEST_OUTPUT:\n---\ncompilable/sw_transition_complex.d(34): Deprecation: use of complex type `creal*` is deprecated, use `std.complex.Complex!(real)` instead\ncompilable/sw_transition_complex.d(35): Deprecation: use of complex type `cdouble*` is deprecated, use `std.complex.Complex!(double)` instead\ncompilable/sw_transition_complex.d(36): Deprecation: use of complex type `cfloat*` is deprecated, use `std.complex.Complex!(float)` instead\ncompilable/sw_transition_complex.d(38): Deprecation: use of imaginary type `ireal*` is deprecated, use `real` instead\ncompilable/sw_transition_complex.d(39): Deprecation: use of imaginary type `idouble*` is deprecated, use `double` instead\ncompilable/sw_transition_complex.d(40): Deprecation: use of imaginary type `ifloat*` is deprecated, use `float` instead\n---\n*/\ncreal* c80pointer;\ncdouble* c64pointer;\ncfloat* c32pointer;\n\nireal* i80pointer;\nidouble* i64pointer;\nifloat* i32pointer;\n\n/*\nTEST_OUTPUT:\n---\ncompilable/sw_transition_complex.d(53): Deprecation: use of complex type `creal[]*` is deprecated, use `std.complex.Complex!(real)` instead\ncompilable/sw_transition_complex.d(54): Deprecation: use of complex type `cdouble[]*` is deprecated, use `std.complex.Complex!(double)` instead\ncompilable/sw_transition_complex.d(55): Deprecation: use of complex type `cfloat[]*` is deprecated, use `std.complex.Complex!(float)` instead\ncompilable/sw_transition_complex.d(57): Deprecation: use of imaginary type `ireal[]*` is deprecated, use `real` instead\ncompilable/sw_transition_complex.d(58): Deprecation: use of imaginary type `idouble[]*` is deprecated, use `double` instead\ncompilable/sw_transition_complex.d(59): Deprecation: use of imaginary type `ifloat[]*` is deprecated, use `float` instead\n---\n*/\ncreal[]* c80arrayp;\ncdouble[]* d64arrayp;\ncfloat[]* c32arrayp;\n\nireal[]* i80arrayp;\nidouble[]* i64arrayp;\nifloat[]* i32arrayp;\n\n/*\nTEST_OUTPUT:\n---\ncompilable/sw_transition_complex.d(72): Deprecation: use of complex type `creal[4][]*` is deprecated, use `std.complex.Complex!(real)` instead\ncompilable/sw_transition_complex.d(73): Deprecation: use of complex type `cdouble[4][]*` is deprecated, use `std.complex.Complex!(double)` instead\ncompilable/sw_transition_complex.d(74): Deprecation: use of complex type `cfloat[4][]*` is deprecated, use `std.complex.Complex!(float)` instead\ncompilable/sw_transition_complex.d(76): Deprecation: use of imaginary type `ireal[4][]*` is deprecated, use `real` instead\ncompilable/sw_transition_complex.d(77): Deprecation: use of imaginary type `idouble[4][]*` is deprecated, use `double` instead\ncompilable/sw_transition_complex.d(78): Deprecation: use of imaginary type `ifloat[4][]*` is deprecated, use `float` instead\n---\n*/\ncreal[4][]* c80sarrayp;\ncdouble[4][]* c64sarrayp;\ncfloat[4][]* c32sarrayp;\n\nireal[4][]* i80sarrayp;\nidouble[4][]* i64sarrayp;\nifloat[4][]* i32sarrayp;\n\n/*\nTEST_OUTPUT:\n---\ncompilable/sw_transition_complex.d(96): Deprecation: use of complex type `creal` is deprecated, use `std.complex.Complex!(real)` instead\ncompilable/sw_transition_complex.d(97): Deprecation: use of complex type `creal*` is deprecated, use `std.complex.Complex!(real)` instead\ncompilable/sw_transition_complex.d(98): Deprecation: use of complex type `creal[]` is deprecated, use `std.complex.Complex!(real)` instead\ncompilable/sw_transition_complex.d(99): Deprecation: use of complex type `creal[4]` is deprecated, use `std.complex.Complex!(real)` instead\ncompilable/sw_transition_complex.d(101): Deprecation: use of imaginary type `ireal` is deprecated, use `real` instead\ncompilable/sw_transition_complex.d(102): Deprecation: use of imaginary type `ireal*` is deprecated, use `real` instead\ncompilable/sw_transition_complex.d(103): Deprecation: use of imaginary type `ireal[]` is deprecated, use `real` instead\ncompilable/sw_transition_complex.d(104): Deprecation: use of imaginary type `ireal[4]` is deprecated, use `real` instead\n---\n*/\nalias C14488 = creal;\nalias I14488 = ireal;\n\nC14488 calias1;\nC14488* calias2;\nC14488[] calias3;\nC14488[4] calias4;\n\nI14488 ialias1;\nI14488* ialias2;\nI14488[] ialias3;\nI14488[4] ialias4;\n\n/*\nTEST_OUTPUT:\n---\ncompilable/sw_transition_complex.d(115): Deprecation: use of complex type `cdouble` is deprecated, use `std.complex.Complex!(double)` instead\ncompilable/sw_transition_complex.d(116): Deprecation: use of imaginary type `idouble` is deprecated, use `double` instead\ncompilable/sw_transition_complex.d(117): Deprecation: use of complex type `cdouble` is deprecated, use `std.complex.Complex!(double)` instead\ncompilable/sw_transition_complex.d(118): Deprecation: use of complex type `cdouble[]` is deprecated, use `std.complex.Complex!(double)` instead\n---\n*/\nauto cauto = 1 + 0i;\nauto iauto = 1i;\nsize_t c64sizeof = (cdouble).sizeof;\nTypeInfo c64ti = typeid(cdouble[]);\n\n/*\nTEST_OUTPUT:\n---\ncompilable/sw_transition_complex.d(128): Deprecation: use of complex type `creal*` is deprecated, use `std.complex.Complex!(real)` instead\ncompilable/sw_transition_complex.d(128): Deprecation: use of imaginary type `ireal` is deprecated, use `real` instead\ncompilable/sw_transition_complex.d(132): Deprecation: use of complex type `creal` is deprecated, use `std.complex.Complex!(real)` instead\n---\n*/\nvoid test14488a(creal *p, real r, ireal i)\n{\n}\n\ncreal test14488b()\n{\n    return 1 + 0i;\n}\n\n// Forward referenced types shouldn't cause errors during test for complex or imaginary.\nenum E;\nstruct S;\n\nvoid test14488c(E *e, S *s)\n{\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=18212\n// Usage of cfloat,cdouble,cfloat,ifloat,idouble,ireal shouldn't trigger an error in deprecated code\ndeprecated void test18212(creal c){}\ndeprecated unittest\n{\n    ireal = 2i;\n    creal = 2 + 3i;\n}\ndeprecated struct Foo\n{\n    ifloat a = 2i;\n    cfloat b = 2f + 2i;\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=18218\nstatic assert(__traits(isDeprecated, cfloat));\nstatic assert(__traits(isDeprecated, cdouble));\nstatic assert(__traits(isDeprecated, creal));\nstatic assert(__traits(isDeprecated, ifloat));\nstatic assert(__traits(isDeprecated, idouble));\nstatic assert(__traits(isDeprecated, ireal));\nstatic assert(!__traits(isDeprecated, float));\nstatic assert(!__traits(isDeprecated, double));\nstatic assert(!__traits(isDeprecated, real));\nstatic assert(!__traits(isDeprecated, int));\nstatic assert(!__traits(isDeprecated, long));\nstatic assert(!__traits(isDeprecated, ubyte));\nstatic assert(!__traits(isDeprecated, char));\nstatic assert(!__traits(isDeprecated, bool));\nstatic assert(!__traits(isDeprecated, S));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/sw_transition_field.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -transition=field\n/*\nTEST_OUTPUT:\n---\ncompilable/sw_transition_field.d(15): `sw_transition_field.S1.ix` is `immutable` field\ncompilable/sw_transition_field.d(16): `sw_transition_field.S1.cx` is `const` field\ncompilable/sw_transition_field.d(21): `sw_transition_field.S2!(immutable(int)).S2.f` is `immutable` field\ncompilable/sw_transition_field.d(21): `sw_transition_field.S2!(const(int)).S2.f` is `const` field\n---\n*/\n\nstruct S1\n{\n    immutable int ix = 1;\n    const int cx = 2;\n}\n\nstruct S2(F)\n{\n    F f = F.init;\n}\n\nalias S2!(immutable int) S2I;\nalias S2!(    const int) S2C;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/sw_transition_tls.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -transition=tls\n/*\nTEST_OUTPUT:\n---\ncompilable/sw_transition_tls.d(11): `x` is thread local\ncompilable/sw_transition_tls.d(15): `y` is thread local\n---\n*/\n\nint x;\n\nstruct S\n{\n    static int y;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test1.d",
    "content": "// PERMUTE_ARGS:\n\nclass File\n{\n    import imports.test1imp;\n\n    static char[] read(char[] name)\n    {\n\tDWORD size;\t// DWORD is defined in test1imp\n\treturn null;\n    }\n\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10056.d",
    "content": "void main()\n{\n    alias Zoo = Foo10056!(false, false, 1);\n}\n\nstruct Foo10056(bool S, bool L, size_t N)\n{\n    string bar()\n    {\n        Appender10056!(string) w;\n        char[] buf; put10056(w, buf);\n        return \"\";\n    }\n\n    public bool opEquals(T)(T other) //const\n    //If you add const, also fails to compile with 2.062.\n    {\n        alias Foo10056!(typeof(this), T, \"CMP\") P;\n        return false;\n    }\n}\n\ntemplate Foo10056(T, U, string OP)\n{\n    static if (T.ISEMPTY && U.ISEMPTY)\n        enum bool S = false;\n    else\n        enum bool S = false;\n\n    alias Foo10056 = Foo10056!(false, false, 0);\n}\n\n/**********************************************/\n\nvoid put10056(R, E)(ref R r, E e)\n{\n    static if (is(typeof(r.put(e))))\n    {\n        r.put(e);\n    }\n    else\n    {\n        static assert(false, \"Cannot put a \"~E.stringof~\" into a \"~R.stringof);\n    }\n}\n\nstruct Appender10056(A : T[], T)\n{\n    private template canPutItem(U)\n    {\n        enum bool canPutItem = is(U : T);\n    }\n    private template canPutRange(R)\n    {\n        enum bool canPutRange = is(typeof(Appender10056.init.put(R.init[0])));\n    }\n\n    void put(U)(U item) if (canPutItem!U)\n    {\n        char[T.sizeof == 1 ? 4 : 2] encoded;\n        put(encoded[]);\n    }\n    void put(R)(R items) if (canPutRange!R)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10066.d",
    "content": "void main()\n{\n    alias Zoo = Foo!(1);\n}\n\nstruct Foo(size_t N)\n{\n    string bar()\n    {\n        Appender!(string) w;\n        char[] buf; put(w, buf);\n        return \"\";\n    }\n\n    public bool opEquals(T)(T other) const\n    // Add const, different from bug 10056\n    {\n        alias Foo!(typeof(this), T, \"CMP\") P;\n        return false;\n    }\n}\n\ntemplate Foo(T, U, string OP)\n{\n    static if (T.ISEMPTY && U.ISEMPTY)\n        enum bool S = false;\n    else\n        enum bool S = false;\n\n    alias Foo = Foo!(0);\n}\n\n/**********************************************/\n\nvoid put(R, E)(ref R r, E e)\n{\n    static if (is(typeof(r.put(e))))\n    {\n        r.put(e);\n    }\n    else\n    {\n        static assert(false, \"Cannot put a \"~E.stringof~\" into a \"~R.stringof);\n    }\n}\n\nstruct Appender(A : T[], T)\n{\n    private template canPutItem(U)\n    {\n        enum bool canPutItem = is(U : T);\n    }\n    private template canPutRange(R)\n    {\n        enum bool canPutRange = is(typeof(Appender.init.put(R.init[0])));\n    }\n\n    void put(U)(U item) if (canPutItem!U)\n    {\n        char[T.sizeof == 1 ? 4 : 2] encoded;\n        put(encoded[]);\n    }\n    void put(R)(R items) if (canPutRange!R)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10073.d",
    "content": "struct Arr(T)\n{\n    T[] dArr;\n    alias dArr this;\n    bool opEquals(Arr!T d)\n    {\n        foreach (idx, it; d)\n        {\n            if (this[idx] != it)\n            {\n                return false;\n            }\n        }\n        return true;\n    }\n}\n\nclass Bar\n{\n    Arr!Foo fooQ;\n}\n\nclass Foo {}    // NG\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10186.d",
    "content": "struct S {\n    @disable this();\n\n    this(int i) {\n    }\n}\n\nclass C {\n    this() {\n        s = S(1);\n    }\n\n    S s;\n}\n\nclass CR\n{\n    S s;\n\n    this() {\n        s = S(1);\n    }\n}\n\nvoid main() {\n    auto c = new C;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10312.d",
    "content": "\nversion(D_SIMD)\n{\n    const __vector(float[4]) si = [1f, 1f, 1f, 1f];\n\n    void main()\n    {\n        auto arr = si;\n        return;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10375.d",
    "content": "// REQUIRED_ARGS: -o-\n\nimport imports.test10375a;\n\nvoid packIt(Pack)(Pack p){ }  //3\n\nvoid main()\n{\n    alias p = packIt!(int);\n    p(2);               // OK <- NG\n    packIt(2);          // OK <- NG\n    packIt!(int)(2);    // OK <- NG\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10520.d",
    "content": "// REQUIRED_ARGS: -debug -profile\n\n// https://issues.dlang.org/show_bug.cgi?id=10520\n// [profile+nothrow] Building with profiler results in \"is not nothrow\" error on some contracts\n\nvoid f() { }\n\nvoid g()()\nin { f(); } // OK <- Error: 'main.f' is not nothrow\nbody { }\n\nalias gi = g!();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10695.d",
    "content": "// PERMUTE_ARGS:\nmodule a;\n\nvoid main()\n{\n    mixin(\"string mod1 = __MODULE__;\");\n    mixin(\"enum mod2 = __MODULE__;\");\n    static assert(mod2 == \"a\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10726.d",
    "content": "// PERMUTE_ARGS:\n\npublic struct CirBuff(T)\n{\n    private T[] data;\n    private size_t head = 0;\n    private size_t size = 0;\n    public size_t length() const { return size; }\n\n    public bool opEquals(CirBuff!T d) @trusted\n    {\n        if (length != d.length)\n            return false;\n        for (size_t i=0; i!=size; ++i)\n        {\n            if (this.data[(this.head+i) % this.data.length] !=\n                d.data[(d.head + i) % d.data.length])\n            {\n                return false;\n            }\n        }\n        return true;\n    }\n}\n\nclass Once\n{\n    Foo!Bar _bar;\n}\n\nclass Bar\n{\n    static Once _once;\n    mixin(sync!(Once, \"_once\"));\n}\n\nclass Foo(T = int)\n{\n    CirBuff!T _buff;\n}\n\ntemplate sync(T, string U = \"this\", size_t ITER = 0)\n{\n    static if (ITER == __traits(derivedMembers, T).length)\n        enum sync = \"\";\n    else\n    {\n        enum string mem = __traits(derivedMembers, T)[ITER];\n        enum string sync =\n            \"static if(! __traits(isVirtualMethod, \" ~ U ~ \".\" ~ mem ~ \")) { }\"\n            ~ sync!(T, U, ITER+1);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10752.d",
    "content": "import imports.test10752;\nvoid main()\n{\n    static assert(!__traits(compiles, priv));\n    static assert(!__traits(compiles, priv));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10981.d",
    "content": "void foo(int i)\nin\n{\n    class X1\n    {\n        void in_nested() pure\n        in { assert(i); }   // OK <- NG\n        out { assert(i); }  // OK <- NG\n        body {}\n    }\n}\nout\n{\n    class X2\n    {\n        void out_nested() pure\n        in { assert(i); }   // OK <- NG\n        out { assert(i); }  // OK <- NG\n        body {}\n    }\n}\nbody\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10992.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -unittest\n\nunittest { }\nunittest { }\nunittest { }\n\nvoid main()\n{\n    static assert(__traits(getUnitTests, mixin(__MODULE__)).length == 3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10992b.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -unittest\n\nversion(none)\n{}\nelse\n{\n    unittest { }\n    unittest { }\n    unittest { }\n}\n\nvoid main()\n{\n    static assert(__traits(getUnitTests, mixin(__MODULE__)).length == 3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test10993.d",
    "content": "module test10993;\n\nimport core.demangle : demangleType;\n\nauto foo(T)(T a)\n{\n\tstatic immutable typeof(a) q;\n//\tpragma(msg, \"foo: \" ~ typeof(q).mangleof);\n\treturn q;\n}\n\nstruct test(alias fn)\n{\n\tbool ini = true;\n\tvoid* p;\n}\n\nauto fun()\n{\n\tauto x = foo!()(test!(a=>a)());\n//\tpragma(msg, \"fun: \" ~ typeof(x).mangleof);\n\t\n\treturn x;\n}\n\nvoid main()\n{\n\tconst x = fun();\n\tenum mangle_x = typeof(x).mangleof;\n//\tpragma(msg, \"x  : \" ~ mangle_x);\n\tauto y = cast()x;\n\tenum mangle_y = typeof(y).mangleof;\n//\tpragma(msg, \"y  : \" ~ mangle_y);\n\tenum demangle_x = demangleType(mangle_x);\n\tenum demangle_y = demangleType(mangle_y);\n\tstatic assert (\"immutable(\" ~ demangle_y ~ \")\" == demangle_x);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11169.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\n1: false\n2: true\n3: true\n---\n*/\n\nclass A\n{\n    abstract void foo();\n}\n\ntemplate MixinAbstractBar() { abstract void bar(); }\n\nclass B1 : A\n{\n    // Use pragma instead of static assert, in order to evaluate\n    // __traits during ClassDeclaration.semantic().\n    pragma(msg, \"1: \", __traits(isAbstractClass, typeof(this)));\n    override void foo() {}\n}\n\nclass B2 : A\n{\n    pragma(msg, \"2: \", __traits(isAbstractClass, typeof(this)));\n    override void foo() {}\n    abstract void bar();\n}\n\nclass B3 : A\n{\n    pragma(msg, \"3: \", __traits(isAbstractClass, typeof(this)));\n    override void foo() {}\n    mixin MixinAbstractBar!();\n}\n\nvoid main()\n{\n    static assert( __traits(compiles, { auto b = new B1(); }));\n    static assert(!__traits(compiles, { auto b = new B2(); }));\n    static assert(!__traits(compiles, { auto b = new B3(); }));\n}\n\nclass B : A\n{\n    // __traits(isAbstractClass) is not usable in static if condition.\n\tstatic assert (!__traits(isAbstractClass, typeof(this)));\n\n    override void foo()\n    {\n    }\n}\n\nvoid main2()\n{\n    B b = new B();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11225a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nWORKS\n---\n*/\n\nimport imports.test11225b;\ninterface I {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11237.d",
    "content": "// PERMUTE_ARGS:\n// POST_SCRIPT: compilable/extra-files/test11237.sh\n\nstruct Buffer { ubyte[64 * 1024] buffer; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11259.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=11259\n\nversion (Posix)\n{\n    // smallest druntime module without imports on posix\n    import core.sys.posix.libgen;\n    static assert(__traits(isSame, __traits(parent, core.sys.posix.libgen), core.sys.posix));\n    static assert(__traits(isSame, core.sys.posix, __traits(parent, core.sys.posix.libgen)));\n\n    static assert(__traits(isSame, __traits(parent, core.sys.posix), core.sys));\n    static assert(__traits(isSame, core.sys, __traits(parent, core.sys.posix)));\n}\nelse\n{\n    // smallest module without imports for windows\n    import core.sys.windows.lmuseflg;\n    static assert(__traits(isSame, __traits(parent, core.sys.windows.lmuseflg), core.sys.windows));\n    static assert(__traits(isSame, core.sys.windows, __traits(parent, core.sys.windows.lmuseflg)));\n\n    static assert(__traits(isSame, __traits(parent, core.sys.windows), core.sys));\n    static assert(__traits(isSame, core.sys, __traits(parent, core.sys.windows)));\n}\n\nstatic assert(__traits(isSame, __traits(parent, core.sys), core));\nstatic assert(__traits(isSame, core, __traits(parent, core.sys)));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11371.d",
    "content": "\nversion(D_SIMD)\n{\n    __vector(long[2]) f()\n    {\n        __vector(long[2]) q;\n        return q;\n    }\n\n    enum __vector(long[2]) v = f();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11471.d",
    "content": "// REQUIRED_ARGS: -profile\n\nvoid main() nothrow\n{\n    // Error: asm statements are assumed to throw\n    version(GNU)\n        asm { \"\"; }\n    else\n        asm { nop; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11559upgradeoptlink.d",
    "content": "// REQUIRED_ARGS: -g\n\n// If this is failing, you need optlink 8.00.14 or higher\n\nstring gen()\n{\n    string m;\n    foreach(i; 0..4096)\n        m ~= \"mixin(\\\"assert(0);\\n\\n\\n\\n\\\");\\n\";\n    return m;\n}\n\nvoid main()\n{\n    mixin(gen());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11563.d",
    "content": "import imports.test11563std_traits;\n\ninterface J : I {} // comment out to let compilation succeed\n\nstruct A { }\npragma(msg, moduleName!A);\n\n\ninterface I {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11656.d",
    "content": "\nversion(D_SIMD)\n{\n\tstruct Foo\n\t{\n\t\t__vector(float[4]) x;\n\t}\n\tstatic assert(Foo.x.offsetof == 0);\n\tstatic assert(Foo.x.stringof == \"x\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11824.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nstruct Take(R)\n{\n    public R source;\n    private size_t _maxAvailable;\n\n    alias R Source;\n\n    @property bool empty()\n    {\n        return _maxAvailable == 0 || source.empty;\n    }\n\n    @property auto ref front()\n    {\n        return source.front;\n    }\n\n    void popFront()\n    {\n        source.popFront();\n        --_maxAvailable;\n    }\n\n    @property size_t length() const\n    {\n        return _maxAvailable;\n    }\n}\n\nstruct Repeat(T)\n{\n    private T _value;\n\n    enum bool empty = false;\n    @property inout(T) front() inout { return _value; }\n    void popFront() {}\n}\n\nTake!(Repeat!T) repeat(T)(T value, size_t n)\n{\n    return typeof(return)(Repeat!T(value), n);\n}\n\nauto array(Range)(Range r)\n{\n    alias E = typeof(r.front);\n    //static if (hasLength!Range)\n    {\n        if (r.length == 0)\n            return null;\n\n        auto result = new E[](r.length);\n\n        size_t i;\n        static auto trustedGetAddr(T)(ref T t) @trusted nothrow pure\n        {\n            return &t;\n        }\n        foreach (e; r)\n        {\n            *trustedGetAddr(result[i]) = e;\n            ++i;\n        }\n        return cast(E[])result;\n    }\n}\n\nenum r = [1].repeat(1).array;\nstatic assert(r == [[1]]);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11914.d",
    "content": "// std.array\n@property bool empty(T)(in T[] a) { return !a.length; }\n@property ref T front(T)(T[] a) { return a[0]; }\nvoid popFront(T)(ref T[] a) { a = a[1 .. $]; }\n\n// std.typecons\nstruct Tuple(T...)\n{\n    T field;\n    alias field this;\n}\nTuple!T tuple(T...)(T args) { return typeof(return)(args); }\n\n// std.range\ntemplate ElementType(R)\n{\n    static if (is(typeof(R.init.front.init) T))\n        alias T ElementType;\n    else\n        alias void ElementType;\n}\n\nstruct Repeat(T)\n{\n    private T _value;\n\n    enum bool empty = false;\n    @property inout(T) front() inout { return _value; }\n    void popFront() {}\n}\nRepeat!T repeat(T)(T value) { return Repeat!T(value); }\n\nstruct Zip(R...)\n{\n    //alias Tuple!(staticMap!(.ElementType, R)) ElementType;\n    static if (R.length == 3)\n        alias Tuple!(int, int, int) ElementType;\n    static if (R.length == 2)\n        alias Tuple!(int, int) ElementType;\n\n    R ranges;\n\n    this(R rs)\n    {\n        foreach (i, Unused; R)\n        {\n            ranges[i] = rs[i];\n        }\n    }\n\n    @property bool empty()\n    {\n        foreach (i, Unused; R)\n        {\n            if (ranges[i].empty)\n                return true;\n        }\n        return false;\n    }\n    @property ElementType front()\n    {\n        ElementType result;\n        return result;\n    }\n    void popFront()\n    {\n        foreach (i, Unused; R)\n        {\n            ranges[i].popFront();\n        }\n    }\n\n    ElementType opIndex(size_t n)\n    {\n        ElementType result;\n        return result;\n    }\n}\nauto zip(Rs...)(Rs ranges) { return Zip!Rs(ranges); }\n\n// std.algorithm\ntemplate map(fun...)\n{\n    auto map(Range)(Range r)\n    {\n        return MapResult!(fun, Range)(r);\n    }\n}\nprivate struct MapResult(alias fun, R)\n{\n    R _input;\n\n    this(R input)\n    {\n        _input = input;\n    }\n\n    @property bool empty() { return _input.empty; }\n    @property auto ref front() { return fun(_input.front); }\n    void popFront() { _input.popFront(); }\n}\n\nauto cartesianProduct(R1, R2)(R1 range1, R2 range2)\n{\n    return range2.map!((ElementType!R2 a) => zip(range1, repeat(a)));\n}\nauto cartesianProduct(R1, R2, RR...)(R1 range1, R2 range2, RR otherRanges)\n{\n    return map!(a => tuple(a[0], a[1][0], a[1][1]))(\n        cartesianProduct(range1, cartesianProduct(range2, otherRanges))\n    );\n}\n\n// test\nvoid main()\n{\n    foreach (i, j, k; cartesianProduct([1], [1], [1])) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test11980.d",
    "content": "void start() {}\npragma(startaddress, start);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12009.d",
    "content": "struct RefCounted(T)\n{\n    struct RefCountedStore\n    {\n        private struct Impl\n        {\n            T _payload;\n        }\n\n        private Impl* _store;\n    }\n    RefCountedStore _refCounted;\n\n    ~this()\n    {\n        import core.stdc.stdlib : free;\n    }\n}\n\nstruct GroupBy(R)\n{\n    struct SharedInput\n    {\n        Group unused;\n    }\n\n    struct Group\n    {\n        private RefCounted!SharedInput _allGroups;\n    }\n}\n\nvoid main()\n{\n    GroupBy!(int[]) g1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test1238.d",
    "content": "module test1238;\n\nimport imports.test1238a;\nimport imports.test1238b;\n\nvoid foo()\n{\n    int qwert = zuiop;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12496.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=12496\n\nfinal abstract class T1\n{\n    final abstract class C(uint value) { }\n\n    alias Child = C!2;\n}\n\nvoid main()\n{\n    static assert(__traits(isSame, __traits(parent, T1.Child), T1));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12511.d",
    "content": "module test12511;\n\nimport imports.a12511;\n\npublic class B\n{\n    static void bar()\n    {\n        A.foo(0);\n    }\n}\n\nvoid main()\n{}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12523.d",
    "content": "void test12523(inout(int))\n{\n    void check(T)()\n    {\n        T[] a;\n        foreach (ref e; a)\n            static assert(is(typeof(e) == T));\n    }\n\n    check!(int)();\n    check!(inout(int))();\n    check!(inout(const(int)))();\n    check!(const(int))();\n    check!(immutable(int))();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12527.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=12527\n\n@system:\n    alias Fun = void function() @safe;\n    pragma (msg, Fun.stringof);\n    static assert(Fun.stringof == \"void function() @safe\");\n    alias Del = void delegate() @safe;\n    pragma (msg, Del.stringof);\n    static assert(Del.stringof == \"void delegate() @safe\");\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12567a.d",
    "content": "// REQUIRED_ARGS:\n// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\n---\n*/\ndeprecated\nmodule test12567a;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12567b.d",
    "content": "// REQUIRED_ARGS:\n// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\n---\n*/\ndeprecated(\"message\")\nmodule test12567b;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12567c.d",
    "content": "// REQUIRED_ARGS:\n// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\ncompilable/test12567c.d(9): Deprecation: module `imports.a12567` is deprecated - This module will be removed in future release.\n---\n*/\nimport imports.a12567;\n\nvoid main() { foo(); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12567d.d",
    "content": "// REQUIRED_ARGS: -d\n// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\n---\n*/\nimport imports.a12567;\n\nvoid main() { foo(); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12593.d",
    "content": "int[R] aa;  // Place before the declaration of key struct\n\nstruct R\n{\n    int opCmp(ref const R) const { return 0; }\n\n    //bool opEquals(ref const R) const { return true; }\n    //size_t toHash() const nothrow @safe { return 0; }\n}\n\nvoid main()\n{}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12624.d",
    "content": "// REQUIRED_ARGS: -lib -Icompilable/extra-files\n// EXTRA_FILES: extra-files/imp12624.d\n// https://issues.dlang.org/show_bug.cgi?id=12624\n\nstruct SysTime\n{\n    import imp12624;\n\n    Rebindable!(immutable TimeZone) _timezone = UTC();\n}\n\n\nclass TimeZone\n{\n    this(string , string , string ) immutable {}\n}\n\n\nclass UTC : TimeZone\n{\n    static immutable(UTC) opCall()\n    {\n        return _utc;\n    }\n\n    this() immutable {\n        super(\"UTC\", \"UTC\", \"UTC\");\n    }\n\n    static _utc = new immutable(UTC);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12807.d",
    "content": "void foo(T)(ref T t)\n{\n}\n\nstruct S\n{\n    int impure() {assert(0);}\n    alias impure this;\n}\n\nvoid main() pure\n{\n    S s;\n    foo(s);\n    s.foo(); // triggering alias this violates purity, but ufcs matches\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12967.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nvoid foo() {}\nalias F = typeof(foo);\n\nconst        { void block_c() {} }\nimmutable    { void block_i() {} }\ninout        { void block_w() {} }\nshared       { void block_s() {} }\nshared const { void block_sc() {} }\nshared inout { void block_sw() {} }\n\nstatic assert(is(typeof(block_c) == F));\nstatic assert(is(typeof(block_i) == F));\nstatic assert(is(typeof(block_w) == F));\nstatic assert(is(typeof(block_s) == F));\nstatic assert(is(typeof(block_sc) == F));\nstatic assert(is(typeof(block_sw) == F));\n\nversion (all) { const:        void label_c() {} }\nversion (all) { immutable:    void label_i() {} }\nversion (all) { inout:        void label_w() {} }\nversion (all) { shared:       void label_s() {} }\nversion (all) { shared const: void label_sc() {} }\nversion (all) { shared inout: void label_sw() {} }\n\nstatic assert(is(typeof(label_c) == F));\nstatic assert(is(typeof(label_i) == F));\nstatic assert(is(typeof(label_w) == F));\nstatic assert(is(typeof(label_s) == F));\nstatic assert(is(typeof(label_sc) == F));\nstatic assert(is(typeof(label_sw) == F));\n\nclass C\n{\n    const        { static void block_c() {} }\n    immutable    { static void block_i() {} }\n    inout        { static void block_w() {} }\n    shared       { static void block_s() {} }\n    shared const { static void block_sc() {} }\n    shared inout { static void block_sw() {} }\n\n    static assert(is(typeof(block_c) == F));\n    static assert(is(typeof(block_i) == F));\n    static assert(is(typeof(block_w) == F));\n    static assert(is(typeof(block_s) == F));\n    static assert(is(typeof(block_sc) == F));\n    static assert(is(typeof(block_sw) == F));\n\n    version (all) { const:        static void label_c() {} }\n    version (all) { immutable:    static void label_i() {} }\n    version (all) { inout:        static void label_w() {} }\n    version (all) { shared:       static void label_s() {} }\n    version (all) { shared const: static void label_sc() {} }\n    version (all) { shared inout: static void label_sw() {} }\n\n    static assert(is(typeof(label_c) == F));\n    static assert(is(typeof(label_i) == F));\n    static assert(is(typeof(label_w) == F));\n    static assert(is(typeof(label_s) == F));\n    static assert(is(typeof(label_sc) == F));\n    static assert(is(typeof(label_sw) == F));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12979a.d",
    "content": "void parse()\n{\n    asm pure nothrow @nogc @trusted {}\n    asm @safe {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test12979b.d",
    "content": "// REQUIRED_ARGS: -w -de\n\nvoid foo() pure nothrow @nogc @safe\n{\n    version(GNU)\n    {\n        asm pure nothrow @nogc @trusted\n        {\n            \"\";\n        }\n    }\n    else\n    {\n        asm pure nothrow @nogc @trusted\n        {\n            ret;\n        }\n    }\n}\n\nvoid bar()()\n{\n    version(GNU)\n    {\n        asm pure nothrow @nogc @trusted\n        {\n            \"\";\n        }\n    }\n    else\n    {\n        asm pure nothrow @nogc @trusted\n        {\n            ret;\n        }\n    }\n}\n\nstatic assert(__traits(compiles, () pure nothrow @nogc @safe => bar()));\n\nvoid baz()()\n{\n    version(GNU)\n    {\n        asm\n        {\n            \"\";\n        }\n    }\n    else\n    {\n        asm\n        {\n            ret;\n        }\n    }\n}\n\n// wait for deprecation of asm pure inference\n// static assert(!__traits(compiles, () pure => baz()));\nstatic assert(!__traits(compiles, () nothrow => baz()));\n// wait for deprecation of asm @nogc inference\n// static assert(!__traits(compiles, () @nogc => baz()));\nstatic assert(!__traits(compiles, () @safe => baz()));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13008.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS: -d -de -dw\n/*\nTEST_OUTPUT*\n---\n---\n*/\ndeprecated class Dep { }\ndeprecated Dep depFunc1(); // error\ndeprecated void depFunc2(Dep); // error\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13053.d",
    "content": "// PERMUTE_ARGS: -w -wi\n/*\nTEST_OUTPUT:\n---\n---\n*/\n\n@system:\n\nstruct S\n{\n    int[] a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13193.d",
    "content": "// REQUIRED_ARGS: -O -inline -c\n\n\nfinal class SharedLib {\n    void getSymbol() {return getSymbolImpl();}\n    void getSymbolImpl() {return getSymbol_();}\n    /* add more intermediate functions to go slower */\n    void getSymbol_() {}\n}\n\n\nvoid test13193()\n{\nSharedLib ssllib;\nvoid bindFunc() {ssllib.getSymbol();}\n    bindFunc(); /* add more of these to go slower */\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc(); /* 10 */\n\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc(); /* 20 */\n\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc(); /* 30 */\n\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc(); /* 40 */\n\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc(); /* 50 */\n\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc(); /* 60 */\n\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc(); /* 70 */\n\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc(); /* 80 */\n\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc(); /* 90 */\n\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc();\n    bindFunc(); /* 100 */\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13194.d",
    "content": "module test13194;\n\nclass C13194\n{\n    static Object o = void;\n}\n\nstruct S13194\n{\n    static Object o = void;\n}\n\nunion U13194\n{\n    static Object o = void;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13226.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS: -version=bug\n\nimport imports.a13226;\n\nclass C\n{\n    // class C member m is not accessible\n    version(bug) mixin(t!(typeof(this), \"f\")); else {}\n    version(bug) mixin(u!(typeof(this), \"v\")); else {}\n\n    void f() {}\n    int v;\n\n    // here is ok\n    version(bug) {} else mixin(t!(typeof(this), \"f\"));\n    version(bug) {} else mixin(u!(typeof(this), \"v\"));\n}\n\nstruct S\n{\n    // struct S member m is not accessible\n    version(bug) mixin(t!(typeof(this), \"f\")); else {}\n    version(bug) mixin(u!(typeof(this), \"v\")); else {}\n\n    void f() {}\n    int v;\n\n    // here is ok\n    version(bug) {} else mixin(t!(typeof(this), \"f\"));\n    version(bug) {} else mixin(u!(typeof(this), \"v\"));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13242.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nmain\n+alias apiSym1\na.expensiveArgs: 1\na.expensiveTemplate: 1\n-alias apiSym1\n+alias apiSym3\nb.expensiveArgs: 3\nb.expensiveTemplate: 3\n-alias apiSym3\n---\n*/\n\nimport imports.test13242a;\n\nvoid main()\n{\n    pragma(msg, \"main\");\n\n    cheapFunc();\n\n    pragma(msg, \"+alias apiSym1\");\n    alias apiSym1 = .apiSym1;\n    pragma(msg, \"-alias apiSym1\");\n\n    // imports.test13242a.apiSym2 is not analyzed.\n\n    pragma(msg, \"+alias apiSym3\");\n    alias apiSym3 = .apiSym3;\n    pragma(msg, \"-alias apiSym3\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13281.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\n123\n123u\n123L\n123LU\n123.5\n123.5F\n123.5L\n123.5i\n123.5Fi\n123.5Li\n(123.5+5.5i)\n(123.5F+5.5Fi)\n(123.5L+5.5Li)\n---\n*/\npragma(msg, 123);\npragma(msg, 123u);\npragma(msg, 123L);\npragma(msg, 123uL);\npragma(msg, 123.5);\npragma(msg, 123.5f);\npragma(msg, 123.5L);\npragma(msg, 123.5i);\npragma(msg, 123.5fi);\npragma(msg, 123.5Li);\npragma(msg, 123.5 +5.5i);\npragma(msg, 123.5f+5.5fi);\npragma(msg, 123.5L+5.5Li);\n\nstatic assert((123  ).stringof == \"123\");\nstatic assert((123u ).stringof == \"123u\");\nstatic assert((123L ).stringof == \"123L\");\nstatic assert((123uL).stringof == \"123LU\");\nstatic assert((123.5  ).stringof == \"1.235e+2\");\nstatic assert((123.5f ).stringof == \"1.235e+2F\");\nstatic assert((123.5L ).stringof == \"1.235e+2L\");\nstatic assert((123.5i ).stringof == \"1.235e+2i\");\nstatic assert((123.5fi).stringof == \"1.235e+2Fi\");\nstatic assert((123.5Li).stringof == \"1.235e+2Li\");\nstatic assert((123.5 +5.5i ).stringof == \"1.235e+2 + 5.5e+0i\");\nstatic assert((123.5f+5.5fi).stringof == \"1.235e+2F + 5.5e+0Fi\");\nstatic assert((123.5L+5.5Li).stringof == \"1.235e+2L + 5.5e+0Li\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13512.d",
    "content": "#!/opt/dmd//rdmd\n\nimport std.stdio;\n\n\nvoid main () {\n  writeln(\"we are here!\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test1353.d",
    "content": "\nclass A {}\ninterface B {}\ninterface C {}\ninterface D(X) {}\n\nvoid fun()\n{\n    class T : typeof(new A), .B, const(C), D!int {}\n    version(none)\n    {\n        class U : int, float, __vector(int[3]) {}\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13600.d",
    "content": "// REQUIRED_ARGS: -g\n\nclass Retry\n{\n    alias bool delegate ( lazy void ) SuccessDecider;\n\n    SuccessDecider success_decide;\n\n    void on_retry ( )\n    {\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13668.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\ntuple(\"id\", \"toString\", \"toHash\", \"opCmp\", \"opEquals\", \"Monitor\", \"factory\")\ngenProps\n---\n*/\n\nclass User : Entity!User\n{\n    int id;\n}\n\nclass Entity(T)\n{\n    pragma(msg, generateProperties!T);\n    /* Compiler runs pragma(msg) in semantic() phase, but it does not insert any members\n     * in this class. Therefore getting __traits(allMembers, User) while evaluating\n     * generateProperties!User should work.\n     */\n}\n\ntemplate generateProperties(alias To)\n{\n    string getProperties(alias Ta)()\n    {\n        string toRet = \"genProps\";\n\n        // This line is bad\n        pragma(msg, __traits(allMembers, Ta));\n\n        return toRet;\n    }\n\n    enum generateProperties = getProperties!(To);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13858.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=13858\n\nvoid foo() { assert(0); }\n\nvoid main()\n{\n    int x = 0;\n\n    LSwitch: switch (x)\n    {\n        case 0:\n            break LSwitch;\n\n        default: return;\n    }\n\n    foo();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test13902.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nvoid foo()\n{\n    int a;\n    int* bar() { return &a; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test14275.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nimport protection.bug.bug14275;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test14317.d",
    "content": "\n// REQUIRED_ARGS: -O -profile -inline\n\nstruct Range {\n    private string s;\n    char charAt(int unused1) { return s[0]; }\n}\n\nbool count(Range* r, int* unused2)\n{\n    *unused2 = 0;\n    int unused3;\n    char c = r.charAt(0);\n    return true;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test14375.d",
    "content": "/*\nTEST_OUTPUT:\n---\n---\n */\ninterface IKeysAPI(string greetings) {\n    static assert(greetings == \"Hello world\", greetings);\n}\n\nvoid main() {\n    foreach (method; __traits(allMembers, IKeysAPI!(\"Hello world\"))) {\n        static assert (method.length, \"Empty string from the compiler ??\");\n        pragma(msg, method);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test14528.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMTE_ARGS:\n\nimport imports.a14528;\n\nclass C\n{\n    protected static void func() {}\n\n    void test()\n    {\n        foo!func();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test14666.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\nmodule test14666;\n\nstruct Location\n{\n    import imports.test14666a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test14747.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS: -w\n\nint foo(Args...)()\n{\n    int x;\n\n    foreach (arg; Args)\n    {\n        static if(is(arg == int))\n        {\n            return 0;\n        }\n        static if(is(arg == long))\n        {\n            // fallthrough\n            ++x;    // this statement might be unreachable, but\n                    // UnrollStatement does not warn that.\n        }\n    }\n    // no return\n}\n\nvoid main()\n{\n    auto r1 = foo!(int)();          // return\n    auto r2 = foo!(int, long)();    // return -> fallthrough (it's unreachable)\n    auto r3 = foo!(long, int)();    // fallthough -> return\n    static assert(!__traits(compiles, foo!(long)()));       // fallthough\n    static assert(!__traits(compiles, foo!(long, long)())); // fallthough -> fallthough\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test14781.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nvoid impure() {}    // impure\n\nauto fb1(T)() pure\n{\n    int x;\n    struct A(S)\n    {\n        void fc(T2)()\n        {\n            x = 1;      // accessing pure function context is just ok\n            impure();   // impure function call makes fc as impure\n        }\n        this(S a) {}\n    }\n    return A!int();\n}\nauto fb2(T)() pure\n{\n    int x;\n    struct A(S)\n    {\n        void fc(T2)()\n        {\n            impure();   // impure function call makes fc as impure\n            x = 1;      // accessing pure function context is just ok\n        }\n        this(S a) {}\n    }\n    return A!int();\n}\nvoid test1()\n{\n    fb1!int().fc!int();\n    fb2!int().fc!int();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test14838.d",
    "content": "// PERMUTE_ARGS:\n\nstruct A(T) { ~this() {} }\nclass C { A!int[1] array; }\n\nvoid test14838() pure nothrow @nogc @safe\n{\n    C c;\n    c.__xdtor();    // C.~this() will also be inferred to\n                    // pure nothrow @nogc @safe\n\n    A!int[1] array;\n    // scope destructor call does not cause attribute violation.\n}\n\n// ----\n\n/*\n * This is a reduced test case comes from std.container.Array template,\n * to fix the semantic analysis order issue for correct destructor attribute inference.\n *\n * Before the bugfix:\n *   1. StructDeclaration('Array!int').semantic() instantiates\n *      RangeT!(Array!int) at the `alias Range = ...;`, but\n *      StructDeclaration('RangeT!(Array!int)').semantic() exits\n *      with sizeok == SIZEOKfwd, because the size of _outer_ field is not yet determined.\n *   2. StructDeclaration('Array!int').semantic() succeeds to determine the size\n *      (sizeok = SIZEOKdone).\n *   3. StructDeclaration('Array!int').buildOpAssign() will generate opAssign because\n *      Array!int._data field has identity opAssign member function.\n *   4. The semantic3 will get called for the generated opAssign, then\n *         6-1. Array!int.~this() semantic3, and\n *         6-2. RefCounted!(Array!int.Payload).~this() semantic3\n *      will also get called to infer their attributes.\n *   5. In RefCounted!(Array!int.Payload).~this(), destroy(t) will be instantiated.\n *      At that, TemplateInstance.expandMembers() will invoke runDeferredSemantic()\n *      and it will re-run StructDeclaration('RangeT!(Array!int)').semantic().\n *   6. StructDeclaration('RangeT!(Array!int)').semantic() determines the size\n *      (sizeok = SIZEOKdone). Then, it will generate identity opAssign and run its semantic3.\n *      It will need to infer RangeT!(Array!int).~this() attribute, then it requires the\n *      correct attribute of Array!int.~this().\n *\n *      However, the Array!int.~this() attribute is not yet determined! [bug]\n *      -> it's wongly handled as impure/system/throwable/gc-able.\n *\n *      -> then, the attribute inference results for\n *         RangeT!(Array!int).~this() and Array!int.~this() will be incorrect.\n *\n * After the bugfix:\n *   In 6, StructDeclaration('RangeT!(Array!int)').semantic() will check that:\n *   all base struct types of the instance fields have completed addition of\n *   special functions (dtor, opAssign, etc).\n *   If not, it will defer the completion of its semantic pass.\n */\n\nvoid destroy14838(S)(ref S s) if (is(S == struct))\n{\n    s.__xdtor();\n}\n\nstruct RefCounted14838(T)\n{\n    ~this()\n    {\n        T t;\n        .destroy14838(t);\n    }\n\n    void opAssign(typeof(this) rhs) {}\n}\n\nstruct RangeT14838(A)\n{\n    A[1] _outer_;\n}\n\nstruct Array14838(T)\n{\n    struct Payload\n    {\n        ~this() {}\n    }\n    RefCounted14838!Payload _data;\n\n    alias Range = RangeT14838!Array14838;\n}\n\nclass Test14838\n{\n    Array14838!int[1] field;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test14962.d",
    "content": "template map(fun...)\n{\n    auto map(R)(R r)\n    {\n        return MapResult!(fun, R)(r);\n    }\n}\n\nstruct MapResult(alias fun, R)\n{\n    R _input;\n\n    @property bool empty() { return _input.length == 0; }\n    @property auto front() { return fun(_input[0]); }\n    void popFront() { _input = _input[1..$]; }\n}\n\nstruct Foo\n{\n    int baz(int v)\n    {\n        static int id;\n        return v + id++;\n    }\n    void bar()\n    {\n        auto arr1 = [1, 2, 3];\n        auto arr2 = [4, 5, 6];\n        arr1.map!(\n            // lambda1\n            i =>\n                arr2.map!(\n                    // lambda2\n                    j =>\n                        baz(i + j)\n                )\n        );\n    }\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test14973.d",
    "content": "template map(fun...)\n{\n    auto map(R)(R r)\n    {\n        return MapResult!(fun, R)(r);\n    }\n}\n\nstruct MapResult(alias fun, R)\n{\n    R _input;\n\n    @property bool empty() { return _input.length == 0; }\n    @property auto front() { return fun(_input[0]); }\n    void popFront() { _input = _input[1..$]; }\n}\n\nclass Foo\n{\n    int baz() { return 1; }\n    void bar()\n    {\n        auto s = [1].map!(i => baz()); // compiles\n        auto r = [1].map!(  // returns MapResult-1\n            // lambda1\n            i =>\n                [1].map!(   // returns MapResult-2\n                    // lambda2\n                    j =>\n                        baz()\n                )\n        ); // compiles <- error\n\n        // When lambda1 is called in MapResult-1.front(), it was changed to\n        // TOKfunction in functionResolve. But in that time, MapResult-2 semantic3\n        // was not yet finished, then the lambda2 call in MapResult-2.front()\n        // could not access to enclosing scope frame to call baz().\n        // To fix the issue, MapResult-2 semantic3 should be finished during the\n        // lambda1 body analysis.\n    }\n}\n\nclass Bar\n{\n    int baz;\n    void bar()\n    {\n        auto s = [1].map!(i => baz); // compiles\n        auto r = [1].map!(\n            // lambda1\n            i =>\n                [1].map!(\n                    // lambda2\n                    j =>\n                        baz\n                )\n        ); // compiles <- error\n    }\n}\n\n/*******************************************/\n\nstruct ChunkByImpl(alias eq)\n{\n    struct Group\n    {\n        int[] start;\n        int[] current;\n\n        void popFront()\n        {\n            // In here:\n            //  SortedRange.pred == (a, b) => a  @ test14978b()\n            //  ChunkByImpl.eq == (a, b) => pred(a, b)  @ SortedRange.groupBy()\n            //\n            // The context deduction should be:\n            //  First pred is deduced to function pointer,\n            //  and then, eq is also deduced to function pointer because pred is function pointer.\n            //\n            // Therefore, when ChunkByImpl is instantiated in groupBy(), its semantic3\n            // needs to be invoked to analyze ???\n            eq(start, current);\n        }\n    }\n}\n\nstruct SortedRange(alias pred)\n{\n    int[] input;\n\n    auto groupBy()\n    {\n        ChunkByImpl!(\n            (a, b) => pred(a, b)\n        ) r;\n    }\n}\n\nvoid test14973b()\n{\n    SortedRange!(\n        (a, b) => a\n    ) r;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15019.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=15019\n// dmd -m32 -c all.d\n\nimport std.string;\n\nstruct Color()\n{\n    static fromHex(char[] s)\n    {\n        import std.conv;\n        s.to!ubyte;\n    }\n}\n\nColor!() RGB    ;\n\nstruct Matrix(T, int R, int C)\n{\n        Vector!(T, C) row_t;\n        T[C] v;        // all elements\n\n        /// Covnerts to pretty string.\n        string toString() const\n        {\n            try\n                return format(\"%s\", v);\n            catch\n                assert(false); // should not happen since format is right\n        }\n}\n\n// GLSL is a big inspiration here\n// we defines types with more or less the same names\ntemplate mat2x2(T) { Matrix!(T, 2, 2) mat2x2; }\ntemplate mat3x3(T) { Matrix!(T, 3, 3) mat3x3; }\ntemplate mat4x4(T) { Matrix!(T, 4, 4) mat4x4; }\n\nalias mat2x2 mat2;\nalias mat3x3 mat3;  // shorter names for most common matrices\nalias mat4x4 mat4;\n\nstring definePostfixAliases(string type)\n{\n    return \"alias \" ~ type ~ \"!byte \"   ~ type ~ \"b;\\n\"\n~ \"alias \" ~ type ~ \"!ubyte \"  ~ type ~ \"ub;\\n\"\n~ \"alias \" ~ type ~ \"!short \"  ~ type ~ \"s;\\n\"\n~ \"alias \" ~ type ~ \"!ushort \" ~ type ~ \"us;\\n\"\n~ \"alias \" ~ type ~ \"!int \"    ~ type ~ \"i;\\n\"\n~ \"alias \" ~ type ~ \"!uint \"   ~ type ~ \"ui;\\n\"\n~ \"alias \" ~ type ~ \"!long \"   ~ type ~ \"l;\\n\"\n~ \"alias \" ~ type ~ \"!ulong \"  ~ type ~ \"ul;\\n\"\n~ \"alias \" ~ type ~ \"!float \"  ~ type ~ \"f;\\n\"\n~ \"alias \" ~ type ~ \"!double \" ~ type ~ \"d;\\n\";\n}\n\n// define a lot of type names\nmixin(definePostfixAliases(\"mat2\"));\nmixin(definePostfixAliases(\"mat3\"));\nmixin(definePostfixAliases(\"mat4\"));\nimport std.string;\n\nstruct Vector(T, int N)\n{\n    T[N] v;\n\n    string toString()\n    {\n        try\n            return format(\"%s\", v);\n        catch\n            assert(false);\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15056.d",
    "content": "nothrow:\n\nversion (Windows)\n{\n    version (LP_64)\n        import core.stdc.stdlib;\n    else\n        // doesn't currently work b/c SEH remains present even in nothrow code\n        void* alloca(size_t) { return null; }\n}\nelse\n    import core.stdc.stdlib;\n\nstruct S\n{\n\t~this() nothrow {}\n}\n\nS foo(void* p = alloca(1234))\n{\n\treturn S();\n}\n\nint main()\n{\n\tfoo();\n\treturn 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15150.d",
    "content": "// PERMUTE_ARGS:\n\nmodule test15150;\n\nimport imports.test15150a;\nimport imports.test15150b;\n\nenum y = x;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15177.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n// COMPILED_IMPORTS: imports/test15117a.d\n\nimport users = imports.test15117a;\n\nvoid RunApiTest(T...)()\n{\n    foreach (name; __traits(allMembers, users))\n    {\n        // 3. list the name of TyepInfoStructDeclaration,\n        //    but it's just internal symbol and invisible.\n        mixin(\"alias func = users . \" ~ name ~ \";\");\n    }\n}\n\nvoid main()\n{\n    // 1. run semantic3 of users.test_usr_1\n    users.test_usr_1();\n\n    RunApiTest!();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15326.d",
    "content": "// REQUIRED_ARGS: -w -c -unittest\n\nversion (unittest)\nprivate struct _NestedSym_\n{\n    static if ((void*).sizeof == 8)\n    {\n        pragma(msg, \"64\");\n    }\n    else\n    {\n        pragma(msg, \"32\");\n    }\n\n    version (X86_64)\n    {\n        pragma(msg, \"X86_64\");\n    }\n    else\n    {\n        pragma(msg, \"Not 64\");\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test1537.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=1537\n\nvoid foo(char[] s)\n{\n    int x = -1;\n\n    while (s.length)\n    {\n        char c = s[0];\n\n        if (c == '}')\n           break;\n\n        assert (c >= '0' && c <= '9', s[0..$]);\n\n        if (x == -1)\n            x = 0;\n    }\n}\n\n/**************************************/\n\nenum bug4732 = 42;\nstatic assert( __traits(identifier, bug4732) == \"bug4732\");\n\n/**************************************/\n\ntemplate Compileable(int z) { bool OK=true;}\n\nint bug5245a(U)()\n{\n    { enum   T { a = 5  } T v; }\n    { enum   T { a = 6  } T w; }\n    return 91;\n}\n\nint bug5245b(U)()\n{\n    { struct T { int a = 2; } T v; }\n    { union  T { int a = 3; } T w; }\n    return 91;\n}\n\nint bug5245c(U)()\n{\n    { struct T { int a = 2; } T v; }\n    { class  T { int a = 3; } T w; }\n    return 91;\n}\n\nint bug5245d(U)()\n{\n    { enum  T { a = 3 } T w; }\n    { struct T { int a = 2; } T v; }\n    return 91;\n}\n\n\nstatic assert(!is(typeof(Compileable!(bug5245a!(int)()).OK)));\nstatic assert(!is(typeof(Compileable!(bug5245b!(int)()).OK)));\nstatic assert(!is(typeof(Compileable!(bug5245c!(int)()).OK)));\nstatic assert(!is(typeof(Compileable!(bug5245d!(int)()).OK)));\n\n/**************************************/\n\nclass Bug5349(T) // segfault D2.051\n{\n    int x;\n    static int g()\n    {\n        class B\n        {\n            int inner()\n            {\n                return x; // should not compile\n            }\n        }\n        return (new B).inner();\n    }\n    int y =  g();\n}\n\nstatic assert(!is(typeof(Bug5349!(int))));\n\n/**************************************/\n\nclass Bug4033 {}\n\nclass Template4033(T) {\n    static assert(is(T : Bug4033));\n}\n\nalias Template4033!(Z4033) Bla;\n\nclass Z4033 : Bug4033 { }\n\n/**************************************/\n\nstruct Bug4322 {\n    int[1] a = void;\n}\n\nvoid bug4322() {\n    Bug4322 f = Bug4322();\n    Bug4322 g = Bug4322.init;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15389_x.d",
    "content": "import test15389_y;\n\n//struct ns\nextern (C++, ns)\n{\n    class X { test15389_y.ns.Y a; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15389_y.d",
    "content": "import test15389_x;\n\n//struct ns\nextern (C++, ns)\n{\n    class Y { test15389_x.ns.X b; }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15402.d",
    "content": "// REQUIRED_ARGS: -de\n\nstruct S\n{\n    package int field;\n}\n\nvoid test()\n{\n    S s;\n    s.field = 1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15464.d",
    "content": "class C15464\n{\n    static immutable field = 0;\n}\n\nstruct S15464\n{\n    this(int i)\n    {\n    }\n}\n\nvoid issue15464(T)() @S15464(T.field)\n{\n}\n\nvoid main()\n{\n    issue15464!C15464();\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15490.d",
    "content": "// REQUIRED_ARGS: -o- -inline\n// PERMUTE_ARGS:\nmodule test15490;\n\nimport imports.imp15490a;\nimport imports.imp15490b;\n\nvoid main()\n{\n    regex();\n    listenTCP();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15519_x.d",
    "content": "\nimport test15519_y;\n\nextern(C++, ns)\n{\n class X { test15519_y.ns.Y v; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15519_y.d",
    "content": "\nimport test15519_x: NS = ns;            // fails\n//import test15519_x; alias test15519_x.ns NS;  // works\n\nextern(C++, ns)\n{\n class Y { NS.X v; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15550.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nstruct Vector(T, int N)\n{\n    void opDispatch(string, U)(U)\n    {\n    }\n\n    void baz(string, U)(U)\n    {\n    }\n}\n\nstatic assert(!is(typeof(Vector!(int, 2)._isMatrix)));\nstatic assert(!is(typeof(Vector!(int, 2).baz!\"_isMatrix\")));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15565.d",
    "content": "alias X2 = X;\nextern (C++, ns) struct X {}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15578.d",
    "content": "__gshared private:\n    int j;\n    extern(C++, ns) int k;\n\nvoid f()\n{\n    j = 0; // works as expected\n    k = 0; // Error: variable foo.ns.k is private\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15618.d",
    "content": "class Base\n{\n    ~this() {}\n    size_t x = 4;\n}\n\ninterface Interface\n{\n    int Method();\n}\n\nclass Derived : Base, Interface\n{\n    size_t y = 5;\n    int Method() { return 3; }\n}\n\nstatic assert(Derived.x.offsetof == (void*).sizeof * 2);\nstatic assert(Derived.y.offsetof == (void*).sizeof * 4);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15668.d",
    "content": "void foo ( int line = __LINE__ ) ( string msg = \"\" )\n{\n    static assert (line == 8);\n}\n\nvoid main()\n{\n    foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15762.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=15762\n\nenum Windows1252Char : ubyte { init }\n\nvoid main() @safe {\n\tubyte[] a = [1, 2, 3, 4];\n\tauto aw = cast(Windows1252Char[]) a;\n\tauto caw = cast(const(Windows1252Char)[]) a;\n\tconst(ubyte)[] c = [1, 2, 3, 4];\n\tauto d = cast(const(ubyte)[]) c;\n\tauto e = cast(const(Windows1252Char)[]) c;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15780.d",
    "content": "// PERMUTE_ARGS:\n// https://issues.dlang.org/show_bug.cgi?id=15780\n\nimport std.typecons;\n//import std.stdio;\n\nvoid foo(alias fields)() {\n    foreach(i, field; fields) {\n        enum string a = fields[i];  // OK\n        enum string b = field;      // not OK with 2.069.2 ???\n\t//writeln(field);\n    }\n}\n\nvoid main() {\n    foo!(tuple(\"H\", \"I\"))();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15784.d",
    "content": "// PERMUTE_ARGS:\n\ntemplate AddField(T)\n{\n    T b;\n    this(Args...)(T b, auto ref Args args)\n    {\n        this.b = b;\n        this(args);\n    }\n}\n\ntemplate construcotrs()\n{\n    int a;\n    this(int a)\n    {\n        this.a = a;\n    }\n}\n\nclass B\n{\n    mixin construcotrs;\n    mixin AddField!(string);\n}\n\nclass C : B\n{\n    this(A...)(A args)\n    {\n        // The called super ctor is an overload set.\n        super(args);\n    }\n}\n\nstruct S\n{\n    mixin construcotrs;\n    mixin AddField!(string);\n}\n\nvoid main()\n{\n    auto s = S(\"bar\", 15);\n    auto c = new C(\"bar\", 15);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15785.d",
    "content": "// REQUIRED_ARGS: -de\n// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\n---\n*/\nimport imports.test15785;\n\nclass Derived : Base, IBase2\n{\n    override void foo()\n    {\n        super.foo();\n        bar();\n        // Base.bar(); // doesn't work yet due to a bug in checkAccess\n        faz();\n        // IBase2.faz(); // doesn't work yet due to a bug in checkAccess\n    }\n\n    typeof(super).T t;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15802.d",
    "content": "extern(C++) {\n    template Foo(T) {\n        static int boo();\n    }\n}\n\nvoid main()\n{\n    string s = Foo!(int).boo.mangleof;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15856.d",
    "content": "// REQUIRED_ARGS: -transition=checkimports -de\n// PERMUTE_ARGS:\n/*\nTEST_PUTPUT:\n---\n---\n*/\n\nclass Foo\n{\n    import imports.a15856;\n\n    struct Bar\n    {\n        c_long a;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15898.d",
    "content": "// REQUIRED_ARGS: -O\n// https://issues.dlang.org/show_bug.cgi?id=15898\n\nint addAssignSimple(int[] , const(int)[] )\n{\n    uint c;\n    return c;\n}\n\nvoid mulKaratsuba(int[] result, const(int)[] x, const(int)[] y, int[] )\n{\n    const(int)[] y1 = y;\n    int[] newscratchbuff;\n    int[] resultHigh = result;\n\n    bool ysmaller2 = x.length >= y1.length;\n    newscratchbuff[0..y1.length] = resultHigh;\n    mulKaratsuba(\n        resultHigh[1..$],\n        ysmaller2 ? x[1..$] : y1,\n        ysmaller2 ? y1 : x,\n        newscratchbuff[y1.length..$]\n    );\n\n    addAssignSimple(resultHigh[1..$], newscratchbuff[0..y1.length]);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15907.d",
    "content": "// REQUIRED_ARGS: -de\n// PERMUTE_ARGS:\nimport imports.imp15907;\n\nstruct S\n{\n    private int a;\n}\n\nvoid test()\n{\n    process(S());\n}\n\nstatic assert(allMembers!S == [\"a\"]);\nenum sz = __traits(getMember, imports.imp15907, \"PrivateStruct\").sizeof;\nstatic assert(__traits(hasMember, imports.imp15907, \"privateVar\"));\ntypeof(__traits(getMember, PublicStruct, \"S\").init) s;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test15925.d",
    "content": "/* REQUIRED_ARGS: -transition=import -transition=checkimports\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\ncompilable/test15925.d(17): Deprecation: local import search method found variable `imp15925.X` instead of nothing\n---\n*/\n\nmixin template Import()\n{\n    import imports.imp15925;\n}\n\nclass Foo\n{\n    mixin Import!();\n    static assert(X == 1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16013a.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16013\n\nstruct Impl { S _payload; } /* Only this line has changed from above. */\n\nstruct RefCounted\n{\n    void opAssign(RefCounted rhs) {}\n    void opAssign(S rhs) {}\n    S refCountedPayload() { return S.init; }\n    alias refCountedPayload this;\n}\n\nstruct S { RefCounted s; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16013b.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16013\n\nS s; /* Only this line has changed from above. */\n\nstruct RefCounted\n{\n    void opAssign(RefCounted rhs) {}\n    void opAssign(S rhs) {}\n    S refCountedPayload() { return S.init; }\n    alias refCountedPayload this;\n}\n\nstruct S { RefCounted s; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16031.d",
    "content": "// REQUIRED_ARGS: -fPIC -lib\n// PERMUTE_ARGS:\n// DISABLED: win32 win64\nextern void throwing();\n\nvoid foo()\n{\n    // create plenty of symbols, so that the catch references get a high symbol index\n    static int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,\n        b0, b1, b2, b3, b4, b5, b6, b7, b8, b9,\n        c0, c1, c2, c3, c4, c5, c6, c7, c8, c9,\n        d0, d1, d2, d3, d4, d5, d6, d7, d8, d9;\n    try\n    {\n        throwing();\n    }\n    catch (Exception)\n    {\n    }\n}\n\nvoid bar()\n{\n    try\n    {\n        throwing();\n    }\n    // symbol index for DW.ref._D9Exception7__ClassZ\n    // gets reused for another object and is out of bounds\n    catch (Exception)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16037.d",
    "content": "/* REQUIRED_ARGS: -dip1000\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=16037\n\n@safe:\n\nvoid testXXX () @nogc\n{\n    Object o;\n    scope bool delegate (Object) alwaysFalse = (Object y) { return false; };\n    scope c1 = o !is null ? (Object y) { return o is y; } : alwaysFalse;\n}\n\nauto f() @nogc\n{\n    int a;\n    void g(){ a=1; }\n    scope h=&g;\n    h();\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16080.d",
    "content": "// REQUIRED_ARGS: -lib -Icompilable/imports\n// COMPILED_IMPORTS: extra-files/test16080b.d\n// EXTRA_FILES: imports/imp16080.d\n// https://issues.dlang.org/show_bug.cgi?id=16080\n\nimport imp16080;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16083.d",
    "content": "template Alias(Stuff...)\n{\n    alias Alias = Stuff;\n}\n\nenum A { a = 0 }\nenum B { b = 0 }\n\nenum C { c = \"abc\" }\nenum D { d = \"abc\" }\n\nstatic assert(is(typeof(Alias!(A.a)[0]) == A));\nstatic assert(is(typeof(Alias!(B.b)[0]) == B));\nstatic assert(is(typeof(Alias!(C.c)[0]) == C));\nstatic assert(is(typeof(Alias!(D.d)[0]) == D));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16085.d",
    "content": "// REQUIRED_ARGS: -de\n// PERMUTE_ARGS:\nimport imports.imp16085;\n\nvoid test()\n{\n    S s;\n    assert(s.functionAndFunction() == Pass());\n    assert(s.staticFunctionAndFunction() == Pass());\n    // assert(S.staticFunctionAndFunction() == Pass()); // erroneous not accessible error\n    assert(s.functionAndTemplate() == Pass());\n    assert(s.templateAndTemplate() == Pass());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16088.d",
    "content": "// REQUIRED_ARGS: -Jcompilable/imports/\n// EXTRA_FILES: imports/imp16088.d\n\n// https://issues.dlang.org/show_bug.cgi?id=16088\n\nvoid bar(string x) {}\nauto foo()\n{\n    import(\"imp16088.d\").bar;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16107.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16107\n\nbool check()\n{\n    bool result = false;\n    \n    result |= false;\n    if (result) goto ret;\n    \n    result |= false;\n    if (result) {}\n    \n    ret: return true;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16183.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16183\n\nvoid main()\n{\n    const string g(const string s) { return s; }\n    enum string y = ['f'] ~ g(\"g\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16225.d",
    "content": "// REQUIRED_ARGS: -O -m64\n// PERMUTE_ARGS:\n\n// https://issues.dlang.org/show_bug.cgi?id=16225\n\nstruct C\n{\n    hash_t foo( )\n    {\n        int y;\n        return ((cast(ubyte*)&y)[1]);\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16273.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16273\n\nclass A()\n{\n    alias MyD = D!();\n}\n\nclass B\n{\n    void f() {}\n    alias MyA = A!();\n}\n\nclass C : B\n{\n    override void f() {}\n}\n\nclass D() : A!()\n{\n    void g() { new C; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16292.d",
    "content": "/* PERMUTE_ARGS:\n */\n// https://issues.dlang.org/show_bug.cgi?id=16292\n\nvoid main()\n{\n    goto label;\n    if (makeS()[0])\n    {\n        label:\n    }\n}\n\nS makeS() { return S(); }\n\nstruct S\n{\n    int opIndex(size_t i) { return 0; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16303.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16303\n\nvoid yayf(void function(int*) fp);\nvoid yayd(void delegate(int*) dg);\n\nvoid bar()\n{\n    void function(const(int)* p) fp;\n    yayf(fp);                   // should be good but produces error\n\n    void delegate(const(int)* p) dg;\n    yayd(dg);                   // should be good but produces error\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16340.d",
    "content": "// REQUIRED_ARGS: -w\n\nversion(unittest) template symsToStrs(fields...)\n{\n    static if (fields.length == 0)\n        enum symsToStrs = [\"hello\"];\n    else\n        enum symsToStrs = [\"world\"];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16348.d",
    "content": "// EXTRA_SOURCES: imports/test16348.d\nmodule mypackage.foo;\n\nvoid bug()\n{\n    // removing the if-else also removes the segfault\n    if (true) {}\n    else\n    {\n        import mypackage.bar;\n        auto b = bar();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16460.d",
    "content": "module imports.test16460;\n\nvoid bug()\n{\n    auto d1 = (){\n        import imports.imp16460;\n        return val;\n    };\n    enum d2 = (){\n        import imports.imp16460;\n        return val;\n    };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16492.d",
    "content": "// ARG_SETS: -debug; -o-; -debug -dip1000\n// https://issues.dlang.org/show_bug.cgi?id=16492\n\nvoid mayCallGC();\n\nvoid test() @nogc pure\n{\n    debug new int(1);\n    debug\n    {\n        mayCallGC();\n        auto b = [1, 2, 3];\n        b ~= 4;\n    }\n}\n\nvoid debugSafe() @safe\n{\n    debug unsafeSystem();\n    debug unsafeTemplated();\n}\n\nvoid unsafeSystem() @system {}\nvoid unsafeTemplated()() {\n    int[] arr;\n    auto b = arr.ptr;\n}\n\nvoid debugSafe2() @safe\n{\n    char[] arr1, arr2;\n    debug unsafeDIP1000Lifetime(arr1, arr2);\n\n    char* ptr;\n    char[] arr;\n    debug ptr = arr.ptr;\n}\n\nvoid unsafeDIP1000Lifetime()(ref char[] p, scope char[] s)\n{\n    p = s;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16525.d",
    "content": "static immutable templ(alias var) = 1234;\n\nstruct D\n{\n    int memvar;\n}\n\nextern(C++) struct CPP\n{\n    int memvar;\n}\n\nvoid test()\n{\n    pragma(msg, templ!(D.memvar));\n    pragma(msg, templ!(CPP.memvar));\n    // root cause, C++ member variables have no mangling\n    pragma(msg, CPP.memvar.mangleof);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16540.d",
    "content": "/* REQUIRED_ARGS:\n   PERMUTE_ARGS:\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=16540\n\n@safe:\n\nvoid foo(scope lazy int* f) @nogc {\n}\n\nvoid bar1() @nogc {\n    foo(new int(5)); // It does not understand that the new here is wrapped in an invisible delegate\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16563.d",
    "content": "void test16563()\n{\n    align(1)\n    struct S\n    {\n        uint i;\n        ubyte b;\n        static assert(S.sizeof == 5);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16570.d",
    "content": "static immutable int _a = 0;\n\nenum Regression\n{\n    a = _a,\n}\n\nstatic assert(is(typeof(Regression.a) == immutable(Regression)));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16572.d",
    "content": "class K\n{\n    inout(int) f() inout\n    {\n        return var;\n    }\n\n    void bug()\n    {\n        auto d = &f;\n        d();\n    }\n\n    int var;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16574.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16574\ntemplate Recursive(T) if (is(T == class))\n{\n    // fails because T is still forward referenced\n    // speculative determineSize must not set type to error\n    static assert (!__traits(compiles, { new T; }));\n    // known size of class\n    static assert (is(typeof(T.init) == T));\n\n    alias Recursive = T;\n}\n\n// must be resolvable\nclass C\n{\n    Recursive!C r;\n}\n\ntemplate Recursive(T) if (is(T == struct))\n{\n    // fails because T is still forward referenced\n    // speculative determineSize must not set type to error\n    static assert (!__traits(compiles, { T t; }));\n    // no size yet for struct\n    static assert (!is(typeof(T.init)));\n\n    alias Recursive = T*;\n}\n\n// must be resolvable\nstruct S\n{\n    Recursive!S r;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16578a.d",
    "content": "// REQUIRED_ARGS: -debug\n\n// https://issues.dlang.org/show_bug.cgi?id=16578\n\nstring[string] opts;\n\nvoid main()\n{\n    string arg;\n    switch (arg)\n    {\n        case \"-f\": opts[\"fore\"] = \"\"; break;\n        debug { case \"-throw\": opts[\"throw\"] = \"\"; break; }\n        default:\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16578b.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16578\n\nvoid main()\n{\n    string[string] opts;\n    switch (2)\n    {\n    case 0:\n        opts[\"a\"] = \"\";\n        {\n    case 1:\n            break;\n        }\n    default:\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16607.d",
    "content": "struct A(T)\n{\n    T t; // causes A to be SIZEOKfwd b/c B (passed as T) isn't yet done\n\n     // On the 2nd semantic pass through A, _scope of C got set again,\n     // even though the struct was already done.\n    struct C\n    {\n    }\n}\n\nstruct B\n{\n    A!B* a; // causes instantiation of A!B, but can finish semantic with A!B still being fwdref\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16621.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16621\n\ntemplate xxx()\n{\n    Vector2f xxx()\n    {\n\t return this;\n    }\n}\n\nstruct Vector2f\n{\n    mixin xxx!();\n    alias xxx this;\n}\n\nvoid foo(ref Vector2f pos);\n\nvoid test()\n{\n    Vector2f v;\n    foo(v);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16627.d",
    "content": "void test()\n{\n    int a;\n\n    struct Field\n    {\n        this(this) { ++a; }\n        ~this() { --a; }\n    }\n\n    struct S\n    {\n        Field field; // generates __fieldPostblit, __fieldDtor, and opAssign\n    }\n\n    static assert(__traits(isNested, Field));\n    static assert(!__traits(isNested, S));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16685.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16685\n\nstruct Id { ushort value; }\nenum Id x = Id(5);\nstruct S(ushort A) {}\nalias CannotCreateFromValue = S!(x.value);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test1673.d",
    "content": "module test1673;\n\ntemplate Foo(T...) { }\n\ntemplate Bar(T...)\n{\n    template Doo(T...)\n    {\n    }\n}\n\ntemplate Tuple(T...) { alias Tuple = T; }\n\nvoid main()\n{\n    static assert( __traits(isTemplate, Foo));\n    static assert(!__traits(isTemplate, Foo!int));\n    static assert(!__traits(isTemplate, main));\n\n    static assert( __traits(isTemplate, Bar));\n    static assert(!__traits(isTemplate, Bar!int));\n    static assert( __traits(isTemplate, Bar!(int).Doo));\n    static assert(!__traits(isTemplate, Bar!(int).Doo!int));\n\n    alias Tup = Tuple!(Foo, Foo!int, Bar, Bar!int, Bar!(int).Doo, Bar!(int).Doo!int);\n\n    static assert( __traits(isTemplate, Tup[0]));\n    static assert(!__traits(isTemplate, Tup[1]));\n    static assert( __traits(isTemplate, Tup[2]));\n    static assert(!__traits(isTemplate, Tup[3]));\n    static assert( __traits(isTemplate, Tup[4]));\n    static assert(!__traits(isTemplate, Tup[5]));\n}\n\n/// test overloads\nvoid foo_over() { }\nvoid foo_over(T : int)(T) { }\nvoid foo_over(T : float)(T) { }\nstatic assert(__traits(isTemplate, foo_over));\n\n/// ditto\nvoid bar_over() { }\nvoid bar_over(int) { }\nstatic assert(!__traits(isTemplate, bar_over));\n\n/// alias to overloads\nalias a_foo_over = foo_over;\nstatic assert(__traits(isTemplate, a_foo_over));\n\n/// ditto\nalias a_bar_over = bar_over;\nstatic assert(!__traits(isTemplate, a_bar_over));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16747.d",
    "content": "/*\nPERMUTE_ARGS:\n*/\n\nclass C { @safe ~this() { } }\nclass D : C { }\n\nvoid fwd() @safe\n{\n    scope o = new Object();\n    scope c = new C();\n    scope d = new D();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test16798.d",
    "content": "/*\nREQUIRED_ARGS: -mv=its.a.dessert.topping=imports/imp16798.d -mv=its.a.floorwax=imports/\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nit's a floor wax\nit's a dessert topping\n---\n*/\n\nimport its.a.floorwax.wax16798;\nimport its.a.dessert.topping;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17057.d",
    "content": "// REQUIRED_ARGS: -de\n// PERMUTE_ARGS:\n\nclass LeClass {\n    import std.stdio;\n}\n\nvoid main()\n{\n    static assert([__traits(allMembers, LeClass)] == [\"toString\", \"toHash\", \"opCmp\", \"opEquals\", \"Monitor\", \"factory\"]);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17059.d",
    "content": "mixin template impl()\n{\n    alias T = typeof(this);\n    enum doImplement = is(T : I);\n\n    static if (doImplement)\n    {}\n}\n\ninterface I {}\nclass A : I {mixin impl;}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17130.d",
    "content": "class Base\n{\n    this() shared\n    {}\n\n    this()\n    {}\n}\n\nclass Derived1 : Base\n{\n    this()\n    {\n        // implicit super();\n    }\n}\n\nclass Derived2 : Base\n{\n    // implicit this()\n}\n\nclass Base2\n{\n    this() shared\n    {}\n}\n\nclass Derived3 : Base2\n{\n    // implicit this() shared\n}\n\nvoid test()\n{\n    auto d2 = new Derived2;\n    auto d3 = new shared(Derived3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17143.d",
    "content": "import std.typecons : tuple;\nenum foo = tuple(1, 2).expand;\npragma(msg, typeof(foo).stringof);\npragma(msg, foo.stringof);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17168.d",
    "content": "// REQUIRED_ARGS: -O\n// PERMUTE_ARGS:\n\nvoid fn(uint x){uint a = 0 << x;}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17215.d",
    "content": "// REQUIRED_ARGS: -O\nversion (X86_64):\nalias vec = __vector(int[4]);\n\nvec binop(vec a)\n{\n    vec b = a;\n    return b;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17339.d",
    "content": "void foo(alias param)()\n{\n}\n\nconst CONST1 = 1;\nconst CONST2 = 1;\nstatic assert(&foo!CONST1 !is &foo!CONST2);\nstatic assert(foo!CONST1.mangleof != foo!CONST2.mangleof);\n\nimmutable IMM1 = 1;\nimmutable IMM2 = 1;\nstatic assert(&foo!IMM1 !is &foo!IMM2);\nstatic assert(foo!IMM1.mangleof != foo!IMM2.mangleof);\n\n// Behaves different for manifest constants!\nenum ENUM1 = 1;\nenum ENUM2 = 1;\nstatic assert(&foo!ENUM1 is &foo!ENUM2);\nstatic assert(foo!ENUM1.mangleof == foo!ENUM2.mangleof);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17349.d",
    "content": "\n/* REQUIRED_ARGS:\n   PERMUTE_ARGS:\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=16538\n\nconst(int) retConst1();\nint retConst2();\nauto retConst = [&retConst1, &retConst2];\n\nconst(int*) retConstPtr1();\nconst(int)* retConstPtr2();\nauto retConstPtr = [&retConstPtr1, &retConstPtr2];\n\nvoid constArray1(const(int)[1]);\nvoid constArray2(const(int[1]));\nauto constArray = [&constArray1, &constArray2];\n\nconst(int)[] retConstSlice1();\nconst(int[]) retConstSlice2();\nauto retConstSlice = [&retConstSlice1, &retConstSlice2];\n\nvoid constSlice1(const(int)[]);\nvoid constSlice2(const(int[]));\nauto constSlice = [&constSlice1, &constSlice2];\n\nvoid ptrToConst1(const(int)*);\nvoid ptrToConst2(const(int*));\nauto ptrToConst = [&ptrToConst1, &ptrToConst2];\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17352.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=17352\nvoid bug(Args...)()\n{\n}\n\nvoid test(bool coin)\n{\n    if (coin)\n    {\n        string foobar;\n        bug!foobar();\n    }\n    else\n    {\n        string foobar;\n        bug!foobar();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17373.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=17373\ninterface Foo { void visit (int); }\ninterface Bar { void visit(double); }\ninterface FooBar : Foo, Bar {}\nstatic assert(__traits(getOverloads, FooBar, \"visit\").length == 2);\n\ninterface Fbar { void visit(char); void visit(double); }\ninterface Triple : Foo, Bar, Fbar {}\nstatic assert(__traits(getOverloads, Triple, \"visit\").length == 3);\n\ninterface InheritanceMadness : FooBar, Triple {}\nstatic assert(__traits(getOverloads, Triple, \"visit\").length == 3);\n\ninterface Simple\n{\n    int square(int);\n    real square(real);\n}\nstatic assert(__traits(getOverloads, Simple, \"square\").length == 2);\n\n// https://issues.dlang.org/show_bug.cgi?id=19064\ninterface InputStream {}\ninterface OutputStream{}\ninterface Stream : InputStream, OutputStream{}\ninterface ConnectionStream : Stream\n{\n    @property bool connected() const;\n    void close();\n}\n\nstatic assert(__traits(getOverloads, ConnectionStream, \"connected\").stringof == \"tuple(connected)\");\nstatic assert(__traits(getOverloads, ConnectionStream, \"close\").stringof == \"tuple(close)\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17399.d",
    "content": "/* REQUIRED_ARGS: -inline\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=17399\n\npragma(inline, true)\nuint addu(uint x, uint y, ref bool overflow) {\n    uint r = x + y;\n    if (r < x || r < y)\n        overflow = true;\n    return r;\n}\n\nvoid foo() {\n    uint a, b;\n    bool over;\n    addu(a, b, over);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17419.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=17419\n\n\nextern (C) int fooc();\nalias aliasc = fooc;\n\nstatic assert(__traits(getLinkage, fooc) == \"C\");\nstatic assert(__traits(getLinkage, aliasc) == \"C\");\n\nextern (D) int food();\nextern (C++) int foocpp();\nextern (Windows) int foow();\nextern (Pascal) int foop();\nextern (Objective-C) int fooobjc();\nextern (System) int foos();\n\nstatic assert(__traits(getLinkage, food) == \"D\");\nstatic assert(__traits(getLinkage, foocpp) == \"C++\");\nstatic assert(__traits(getLinkage, foow) == \"Windows\");\nstatic assert(__traits(getLinkage, foop) == \"Pascal\");\nstatic assert(__traits(getLinkage, fooobjc) == \"Objective-C\");\nversion (Windows)\n    static assert(__traits(getLinkage, foos) == \"Windows\");\nelse\n    static assert(__traits(getLinkage, foos) == \"C\");\n\nextern (C) int global;\nstatic assert(__traits(getLinkage, global) == \"C\");\n\nstatic assert(__traits(getLinkage, typeof(fooc)) == \"C\");\nstatic assert(__traits(getLinkage, typeof(&fooc)) == \"C\");\n\nvoid bar()\n{\n    void nested() { }\n    static assert(__traits(getLinkage, typeof(&nested)) == \"D\");\n}\n\nclass FooD {}\ninterface FooDInterface {}\nextern (C++) class FooCpp {}\nextern (C++) struct FooCppStruct {}\nextern (C++) interface FooCppInterface {}\n\nstatic assert(__traits(getLinkage, FooD) == \"D\");\nstatic assert(__traits(getLinkage, FooDInterface) == \"D\");\nstatic assert(__traits(getLinkage, FooCpp) == \"C++\");\nstatic assert(__traits(getLinkage, FooCppStruct) == \"C++\");\nstatic assert(__traits(getLinkage, FooCppInterface) == \"C++\");\n\nversion (D_ObjectiveC)\n{\n    extern (Objective-C) interface FooObjC {}\n    static assert(__traits(getLinkage, FooObjC) == \"Objective-C\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17421.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=17421\n\nimport core.stdc.stdarg;\n\nvoid novar() {}\nextern(C) void cstyle(int, ...) {}\nextern(C++) void cppstyle(int, ...) {}\nvoid dstyle(...) {}\nvoid typesafe(int[]...) {}\n\nstatic assert(__traits(getFunctionVariadicStyle, novar) == \"none\");\nstatic assert(__traits(getFunctionVariadicStyle, cstyle) == \"stdarg\");\nstatic assert(__traits(getFunctionVariadicStyle, cppstyle) == \"stdarg\");\nstatic assert(__traits(getFunctionVariadicStyle, dstyle) == \"argptr\");\nstatic assert(__traits(getFunctionVariadicStyle, typesafe) == \"typesafe\");\n\nstatic assert(__traits(getFunctionVariadicStyle, (int[] a...) {}) == \"typesafe\");\nstatic assert(__traits(getFunctionVariadicStyle, typeof(cstyle)) == \"stdarg\");\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17468.d",
    "content": "// PERMUTE_ARGS:\nstruct S\n{\n        const char* path;\n        @disable this();\n        this(const(char)* path)\n        {\n                this.path = path;\n        }\n}\nconst S CONST_S = S(\"/tmp\".ptr);\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17512.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=17512\n\nstruct A\n{\n    int _value;\n\n    bool _hasValue;\n\n    auto ref getOr(int alternativeValue)\n    {\n        return _hasValue ? _value : alternativeValue;\n    }\n}\n\nA a;\n\n// https://issues.dlang.org/show_bug.cgi?id=18661\n\nstruct S0(T)\n{\n    int a;\n    auto ref immutable(int) getA() { return a; }\n}\n\nalias B = S0!int;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test1754.d",
    "content": "module test1754;\n\nimport imports.test1754a;\nimport imports.test1754b;\n\nvoid foo()\n{\n    bar();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17541.d",
    "content": "/* EXTRA_SOURCES: imports/test17541_2.d imports/test17541_3.d\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=17541\n\nmodule one;\n\nimport two;\nimport three;\n\nstruct BB\n{\n    enum MAX_NUM_FIBERS = 4096;\n\n    TWOR!1 t;\n    TT!(int) tt;\n    auto foo()\n    {\n        tt.insertabcdefg(1);\n    }\n}\n\nBB bb;\n\n@nogc bar()\n{\n    bb.foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17545.d",
    "content": "/* TEST_OUTPUT:\n---\ntuple((Attrib))\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17545\n\nmodule example;\n\nstruct Attrib {}\n\n@Attrib enum TEST = 123;\n\npragma(msg, __traits(getAttributes, \n                     __traits(getMember, example, \"TEST\")));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17548.d",
    "content": "// REQUIRED_ARGS: -c\n\nmodule test17548;\n\nstruct S1 {\n    void foo(scope S2 arg) {}\n    int myField;\n}\n\nenum cnst = 4321;\n\nimport imports.fwdref2_test17548;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17590.d",
    "content": "// REQUIRED_ARGS: -o-\n\nvoid lazyfun(scope lazy int a) @nogc;\n\n// Test that returning a local _static_ struct does not lead to allocation of a closure.\nauto foo_static(int a, bool b) @nogc {\n    static struct SInside {}\n\n    SInside res;\n\n    lazyfun(a);\n\n    return res;\n}\n\n// Test that returning a local _non-static_ struct that does not reference any local variable does not lead to allocation of a closure.\nauto foo_nonstatic(int a, bool b) @nogc {\n    struct SInside {}\n\n    SInside res;\n\n    lazyfun(a);\n\n    return res;\n}\n\n// Test that returning a local non-static struct that references a local variable does lead to allocation of a closure.\nstatic assert(!__traits(compiles, () @nogc => goo(1)));\nstatic assert(__traits(compiles, () => goo(1)));\nauto goo(T)(T a) {\n    struct SInside {\n        T foo() { return a; }\n    }\n\n    SInside res;\n\n    lazyfun(a);\n\n    return res;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17752.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=17752\n// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\n---\n*/\nvoid main (string[] args)\n{\n    switch (args.length)\n    {\n        // initialization not done on purpose is allowed\n        int x = void;\n    default:\n        break;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17782.d",
    "content": "void main() {\n    string str = q\"_DLANG\n123\n_DLANG\";\n    assert( str == \"123\\n\" );\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17791.d",
    "content": "deprecated(\"A deprecated class\") {\nclass DepClass\n{\n}\n}\n\nclass NewClass\n{\n}\n\nvoid main()\n{\n    // test that a symbol (which is not likely to be deprecated)\n    // is not depercated\n    static assert(!__traits(isDeprecated, int));\n    // check that a class marked deprecated \"isDeprecated\"\n    static assert(__traits(isDeprecated, DepClass));\n    // check that a class not marked deprecated is not deprecated\n    static assert(!__traits(isDeprecated, NewClass));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17807.d",
    "content": "// REQUIRED_ARGS: -o- -w\n\nint bug17807(){\n    int y=0;\n    Lswitch: switch(2){\n        { case 0: break; }\n        enum x=0;\n        struct S{ enum x=0; }\n        int foo(){\n            return 0;\n        }\n        default: y=x+S.x+foo();\n        static foreach(i;1..5)\n            case i: break Lswitch;\n    }\n    return y;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17819.d",
    "content": "static if (__traits(allMembers, __traits(parent,{}))[0]==\"object\") {\n\tpragma(msg, \"compiled in!\");\n\tenum test = 0;\n}\n\nstatic foreach (m; __traits(allMembers, __traits(parent,{}))) {\n\tpragma(msg, m.stringof);\n\tmixin(\"enum new\"~m~\"=`\"~m~\"`;\");\n}\n\nstatic assert([__traits(allMembers, __traits(parent,{}))] == [\"object\", \"test\", \"newobject\", \"newWorld\", \"newBuildStuff\", \"World\", \"BuildStuff\"]);\n\nstruct World {\n\tmixin BuildStuff;\n}\n\ntemplate BuildStuff() {\n\tstatic foreach(elem; __traits(allMembers, typeof(this))) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17853.d",
    "content": "// Switch with no braces & empty case should compile\n\nint main() {\n\tint ob = 1;\n\n    final switch (ob)\n    case 0: case 1:\n        break;\n\n    return ob;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17906.d",
    "content": "// REQUIRED_ARGS: -de\n// https://issues.dlang.org/show_bug.cgi?id=18647\ndeprecated void main ()\n{\n    Object o = new Object;\n    delete o;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17908.d",
    "content": "// PERMUTE ARGS:\n\n@disable void foo() {}\nvoid foo(int) {}\nalias g = foo;\n\n// make sure the order of declaration\n// doesn't change anything\nvoid bar(int) {}\n@disable void bar() {}\nalias h = bar;\n\nvoid main()\n{\n    g(10);\n    h(10);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17942.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=17942\n\nalias AliasSeq(TList...) = TList;\n\nvoid test()\n{\n    enum A = AliasSeq!(1);\n    static assert(A[0] == 1);\n    static assert(B[0] == 2);\n}\n\nenum B = AliasSeq!(2);\n\nenum C = AliasSeq!();\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17970.d",
    "content": "shared struct Shared\n{\n    static Shared make()\n    {\n        return Shared();\n    }\n\n    ~this()\n    {\n    }\n}\n\nshared struct Foo\n{\n    ~this()\n    {\n    }\n}\n\nstruct Inner { ~this() {} }\nstruct Outer { shared(Inner) inner; }\n\nvoid main()\n{\n    Foo x = Foo();\n    auto s = Shared.make();\n    Outer _;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test17991.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=17991\nimport imports.test17991a, imports.test17991a.a;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18000.d",
    "content": "// REQUIRED_ARGS: -dip1000\n\n// https://issues.dlang.org/show_bug.cgi?id=18000\n\nstruct File\n{\n@safe @nogc:\n    ~this() scope\n    {\n    }\n\n    void* f;\n}\n\nvoid test() @safe @nogc\n{\n    scope File x;\n    x = File();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18020.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18020\n\nvoid bug(T)(T t)\n{\n    t.opCmp(t);\n}\n\nalias bugi = bug!(typeof(new class{}));"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18030.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18030\n\nstruct S(T)\n{\n\tT var;\n\tpragma(\n\t\tmsg,\n\t\t\"Inside S: func() is \",\n\t\t__traits(getProtection, __traits(getMember, T, \"func\"))\n\t);\n}\n\nclass C\n{\n\talias Al = S!C;\n\t\n\tstatic void func(U)(U var) { }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18099.d",
    "content": "\n/* REQUIRED_ARGS: -betterC\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=18099\n\nstruct D\n{\n    static struct V\n    {\n        ~this() { }\n    }\n\n    V get()\n    {\n        V v;\n        return v;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18115.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18115\n\nint test()\n{\n    if (test.stringof.length > 6 &&\n        test.stringof[$-7..$] == \"1234567\") {}\n    return 0;\n}\n\nenum a = test();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18199.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18199\n\n//\n// struct initializer cases\n//\n\n// original error report\nstruct Bla\n{\n    int delegate(int, int) fun;\n}\nBla bla1 = Bla((int a, int b) { return a + b; });\nBla bla2 = {(int a, int b) { return a + b; }};  // yielded error\n\n// additional error report with memberName:expression syntax\nstruct Foo\n{\n    int function(int) bar;\n    int function(int) bar2;\n}\nFoo foo =\n{\n    bar : function(x) { return 2 * x; },  // yielded error\n    bar2 : (x) => 2 * x,\n};\n\nstruct MyStruct\n{\n    int function() f;\n    int delegate() d;\n}\n\n// confirm that ambiguous cases assume struct initializer\nMyStruct ambiguous_1 = {};\nMyStruct ambiguous_2 =\n{\n    { return 1 + 1; }\n};\n\n// statement-holding function literal variants not covered above\nstatic MyStruct function_and_delegate_keywords =\n{\n    function () { return 1 + 1; },\n    delegate () { return 1 + 1; }\n};\n\n//\n// function literal initializer cases\n//\n\nalias IntFun = int function();\nalias VoidFun = void function();\n\nIntFun colon_at_top_level =\n{\n    return 1 + 1;\n};\n\nIntFun block_statement_only_with_nested_statement =\n{\n    if (true)\n    {\n        return 1 + 1;\n    }\n};\n\nstruct SomeStruct {}\n\n// previously these cases were incorrectly parsed as struct initializer\nVoidFun[] no_semicolon_statements = [\n    { asm {} },\n    { class Foo {} },\n    { debug(foo) {} },\n    { enum Foo { A } },\n    { final switch(5) {} },\n    { if (true) {} },\n    { interface Foo {} },\n    { pragma(inline) {} },\n    { scope(exit) {} },\n    { struct Foo {} },\n    { synchronized {} },\n    { try {} finally {} },\n    { union Foo {} },\n    { version(foo) {} },\n    { while (false) {} },\n    { with (SomeStruct) {} },\n];\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18430.d",
    "content": "template Alias(alias a)\n{\n    alias Alias = a;\n}\n\nvoid main()\n{\n    auto scale = 4;\n    alias edentity = a => a * scale;\n    static assert(__traits(isSame, Alias!edentity, edentity)); // fails in dmd-nightly\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18468.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18468\n@safe void main()\n{\n    synchronized {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18474.d",
    "content": "shared struct A\n{\n    this(this);\n}\n\nstruct B\n{\n    A a;\n}\n\nvoid main()\n{\n    shared B b1;\n    auto b2 = b1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18578.d",
    "content": "enum Foo { foo1 }\nenum Bar : Foo { bar }\n\nvoid main()\n{}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18584.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18584\n\nstruct S {\n    int n;\n    auto fun() { return tmp!(a => n)(); }\n}\n\nstruct tmp(alias fns) {\n    alias fun = fns!int;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18645.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18645\n\nimmutable INIT = 42;\n\nenum A\n{\n    x = INIT,\n    y\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18670.d",
    "content": "// REQUIRED_ARGS: -dip1000\n\n// https://issues.dlang.org/show_bug.cgi?id=18670\n\nvoid foo() {\n    new OVERLAPPED;\n}\n\nunion OVERLAPPED {\n    uint     OffsetHigh;\n    uint     Pointer;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18694.d",
    "content": "struct S { enum int x = 42; }\nstatic S dummy;\npure int fun(int x)\n{\n    return dummy.x + x;\n}\n\nvoid main()\n{}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18737.d",
    "content": "/* REQUIRED_ARGS:\n * PERMUTE_ARGS:\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=18737\n\nstruct S\n{\n    this(char);\n\n    this(int j)\n    {\n        this('a');\n        assert(0);\n        this('b');\n    }\n\n    this(long j)\n    {\n        if (j)\n        {\n            this('c');\n            assert(0);\n        }\n        else if (j + 1)\n        {\n            this('d');\n            return;\n        }\n        this('e');\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18771.d",
    "content": "// REQUIRED_ARGS : -c\n// https://issues.dlang.org/show_bug.cgi?id=18771\n\nimport imports.test18771c, imports.test18771d;\n\nstatic assert(__traits(isSame, fooC, fooD));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18775.d",
    "content": "// REQUIRED_ARGS: -de\n\nstruct Foo { }\n\nstruct Bar {\n    deprecated\n    @property Foo foo() { return Foo.init; }\n\n    alias foo this;\n}\n\nvoid test(Bar bar) { }\n\nvoid main()\n{\n    Bar bar;\n\n    // test lookup will be satisfied via ufcs, not alias, so it must not deprecation warn foo!\n    bar.test;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test1878a.d",
    "content": "void main()\n{\n  ubyte from, to;\n  foreach(i; from..to)\n  {\n    static assert(is(typeof(i) == ubyte));\n  }\n  foreach(i; 'a'..'l')\n  {\n    static assert(is(typeof(i) == char));\n  }\n  foreach(i; 'א' .. 'ת')\n  {\n    static assert(is(typeof(i) == wchar));\n  }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18821.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18821\n\nalign(1) struct epoll_event\n{\n    void* ptr;\n}\ntemplate isAllZeroBits(epoll_event value) {}\nalias isInitAllZeroBits = isAllZeroBits!(epoll_event.init);\n\nepoll_event e = { null };\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18871.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18871\n// and https://issues.dlang.org/show_bug.cgi?id=18819\n\nstruct Problem\n{\n    ~this() {}\n}\nstruct S\n{\n    Problem[1] payload;\n}\nenum theTemplateB = {\n    static foreach (e; S.init.tupleof) {}\n    return true;\n}();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18905.d",
    "content": "/* REQUIRED_ARGS: -betterC\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=18905\n\nextern (C++) class C { } // Error: TypeInfo cannot be used with -betterC\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18936.d",
    "content": "// REQUIRED_ARGS: -fPIC -O -release -inline -m64 -betterC\n// DISABLED: win32 win64\n\n// https://issues.dlang.org/show_bug.cgi?id=18936\n// produces assert failure cgxmm.c line 684\n\nimport core.stdc.math;\n\nstruct S\n{\n    double re, im;\n\n\n    static S sqrtcx(S* z)\n    {\n        S c;\n        real x,y,w,r;\n\n        {\n            x = fabs(z.re);\n            y = fabs(z.im);\n            if (z.re >= 0)\n            {\n                c.im = (z.im >= 0) ? w : -w;\n                c.re = z.im / (c.im + c.im);\n            }\n        }\n        return c;\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18951a.d",
    "content": "module compilable.test18951a;\n\npublic class A\n{\n    package static void foo(Object) {}\n    public static void foo() {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18951b.d",
    "content": "module compilable.test18951b;\n\nimport test18951a;\n\nvoid test()\n{\n    A.foo(new Object);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test18976.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18976\n\nclass Expression : Statement {}\nclass Statement {}\n\nclass AssertSemanticVisitor\n{\n    void visit (const Statement node) { }\n}\n\nclass ExpressionVisitor : AssertSemanticVisitor\n{\n    public void visit (Expression) { }\n\n    alias visit = typeof(super).visit;\n}\n\nclass ExpressionVisitor2 : AssertSemanticVisitor\n{\n    public void visit (Expression) { }\n\n    alias visit = AssertSemanticVisitor.visit;\n}\n\nvoid main ()\n{\n    scope x1 = new ExpressionVisitor;\n    scope x2 = new ExpressionVisitor;\n    scope y = new Statement;\n    x1.visit(y);\n    x2.visit(y);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test19066.d",
    "content": "class C {}\n\nint Object;\n\nstruct S\n{\n    int object;\n    C Object;\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test19081.d",
    "content": "void main() {\n    @(1) enum { A }\n    /// comment\n    @(1) enum X { A }\n    @(2) enum Y;\n    @(1) @(2) enum Z { A }\n\n    struct Test { int test; }\n    @Test(1) enum W { A }\n    @(1) enum V: int { A }\n    X a;\n    static assert(__traits(getAttributes, X).length == 1);\n    static assert(__traits(getAttributes, X)[0] == 1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test19107.d",
    "content": "// REQUIRED_ARGS: -dw\n// EXTRA_FILES: imports/test19107a.d imports/test19107b.d\n/*\nTEST_OUTPUT:\n---\ncompilable/test19107.d(14): Deprecation: `imports.test19107b.I` is not visible from module `test19107`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=19107\n\nimport imports.test19107b;\n\nvoid all(alias pred, T)(T t)\n    if (is(typeof(I!pred(t))))\n{ }\n\nvoid main(string[] args)\n{\n    args.all!(c => c);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test19108.d",
    "content": "// REQUIRED_ARGS: -ignore\n\n// https://issues.dlang.org/show_bug.cgi?id=19108\n\npragma(unknown_global);\nvoid main()\n{\n    pragma(unknown_local); // Error: unrecognized pragma\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test19187.d",
    "content": "// EXTRA_FILES: imports/test19187.d\nimport imports.test19187;\nvoid main()\n{\n    enum test = __traits(compiles, imports.test19187.foo);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test19201.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=19201\nenum __c_long : int;\nenum __c_ulong : uint;\n\nenum __c_longlong : long;\nenum __c_ulonglong : ulong;\n\nvoid test19201a(uint r);\nvoid test19201a(int r);\n\nvoid test19201b(ulong r);\nvoid test19201b(long r);\n\nvoid test19201c(__c_long r);\nvoid test19201c(__c_ulong r);\n\nvoid test19201d(__c_longlong r);\nvoid test19201d(__c_ulonglong r);\n\nvoid test19201()\n{\n    test19201a(0);\n    test19201a(0u);\n    test19201b(0L);\n    test19201b(0UL);\n    test19201c(0);\n    test19201c(0u);\n    test19201d(0L);\n    test19201d(0UL);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test19203.d",
    "content": "//https://issues.dlang.org/show_bug.cgi?id=19203\nstruct BoolWithErr {\n    bool b;\n    string error;\n    alias b this;\n}\n\nstruct Foo {\n    int popBack() { return 0; }\n}\n\nstruct Bar {}\n\ntemplate hasPopBack(T) {\n    static if (!is(typeof(T.init.popBack)))\n        enum hasPopBack = BoolWithErr(false, T.stringof~\" does not have popBack\");\n    else\n        enum hasPopBack = BoolWithErr(true,\"\");\n}\n\nvoid test()\n{\n    static assert( hasPopBack!Foo);\n    static assert(!hasPopBack!Bar);\n    static assert( hasPopBack!Foo && !hasPopBack!Bar);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test19292.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=19292\n\nmixin(\"enum a = \", 87, \";\");\nstatic assert(a == 87);\n\nint test()\n{\n    mixin(\"enum x = \", 7, \";\");\n    return mixin(\"1\", x, 2U);\n}\n\nvoid testit()\n{\n    static assert(test() == 172);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test25.d",
    "content": "// PERMUTE_ARGS:\n\nimport imports.test25a, imports.test25b;\n\nimport std.stdio;\n\nvoid main()\n{\n    std.stdio.writefln(\"hello\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test2991.d",
    "content": "module test2991;\n\nvoid foo()\n{\n}\n\nclass C\n{\n    import imports.test2991;\n\n    void bar() { foo(); }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test313a.d",
    "content": "/*\nREQUIRED_ARGS: -de\n*/\nmodule test313;\n\nimport imports.a313;\n\nvoid test1()\n{\n    import imports.b313;\n    imports.b313.bug();\n}\n\nvoid test2()\n{\n    cstdio.printf(\"\");\n}\n\nimport imports.pkg313.c313;\nvoid test3()\n{\n    imports.pkg313.c313.bug();\n}\n\ntemplate imp()\n{\n    static import imports.a313templatemixin1;\n    import imports.a313templatemixin2;\n}\n\nmixin imp!();\nvoid test4()\n{\n    imports.a313templatemixin1.bug();\n    imports.a313templatemixin2.bug();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test313b.d",
    "content": "// REQUIRED_ARGS: -de\nvoid test1()\n{\n    import core.stdc.stdio;\n    core.stdc.stdio.printf(\"\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test313c.d",
    "content": "// REQUIRED_ARGS: -de\nimport imports.pkgmod313;\n\nvoid test()\n{\n    imports.pkgmod313.foo();\n    imports.pkgmod313.bar();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test313d.d",
    "content": "// first imported as package\n// COMPILED_IMPORTS: imports/pkgmod313/mod.d\n// REQUIRED_ARGS: -de\nimport imports.pkgmod313; // then as package module\n\nvoid test()\n{\n    imports.pkgmod313.foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test313e.d",
    "content": "// first resolved as package, then created as module (with name package)\n// COMPILED_IMPORTS: imports/pkgmod313/mod.d imports/pkgmod313/package.d\n// REQUIRED_ARGS: -de\nimport imports.pkgmod313; // then imported as package module\n\nvoid test()\n{\n    imports.pkgmod313.foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test313f.d",
    "content": "// REQUIRED_ARGS: -de\nimport imports.f313;\n\nvoid test()\n{\n    imports.f313.bug();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test313g.d",
    "content": "// REQUIRED_ARGS: -de\n// COMPILED_IMPORTS: imports/g313.d\nimport imports.g313;\n\nvoid test15900()\n{\n    // publically imported modules from g313 should be available here\n    imports.g313public.bug();\n    imports.g313staticif.bug();\n    imports.g313stringmixin.bug();\n    imports.g313templatemixin.bug();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test314.d",
    "content": "// REQUIRED_ARGS: -de\nmodule imports.test314; // package imports\n\nimport imports.a314;\n\nvoid main()\n{\n    imports.a314.bug(\"This should work.\\n\");\n    renamed.bug(\"This should work.\\n\");\n    bug(\"This should work.\\n\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test3673.d",
    "content": "class Base {}\n\nclass Foo(T)\n    if (is(T == int)) : Base { }\n\nclass Bar(T) : Base\n    if (is(T == bool))\n{ }\n\ninterface OutputRange(T...)\n    if (T.length == 1)\n{\n    void put(T[0] value);\n}\n\ninterface OutputRange(T...) : OutputRange!(T[0]), OutputRange!(T[1 .. $])\n    if (T.length > 1)\n{\n}\n\nalias OutputRange!(int, float) OR;\n\nclass COR : OR\n{\n    void put(int) { }\n    void put(float) { }\n}\n\nclass A {};\nclass B(T) : A if (true) {}\nclass C(T) if (false) : A {}\n\nalias Foo!int FooInt;\nalias Bar!bool BarBool;\n\nstatic assert(!__traits(compiles, Foo!bool));\nstatic assert(!__traits(compiles, Bar!int));\n\nvoid main()\n{\n    auto fi = new FooInt;\n    auto bb = new BarBool;\n    auto cor = new COR;\n\n    auto a = new A();\n    auto b = new B!int();\n    static assert(!__traits(compiles, new C!int()));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test3775.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=3775\n\nstruct Bug3775 {\n  static int byLine()() { return 1; }\n}\n\nstatic assert(cast(int)Bug3775.byLine == 1);\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test4003.d",
    "content": "// COMPILED_IMPORTS: imports/test4003a.d\n// PERMUTE_ARGS:\n\nimport imports.stdio4003;\nvoid main(){}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test4090.d",
    "content": "void test4090a()\n{\n    // for the mutable elements\n    {\n        int[] arr = [1,2,3];\n\n        // inference + qualifier\n        foreach (          x; arr) static assert(is(typeof(x) == int));\n        foreach (    const x; arr) static assert(is(typeof(x) == const int));\n        foreach (immutable x; arr) static assert(is(typeof(x) == immutable int));\n\n        // inference + qualifier + ref\n        foreach (          ref x; arr) static assert(is(typeof(x) == int));\n        foreach (    const ref x; arr) static assert(is(typeof(x) == const int));\n      static assert(!__traits(compiles, {\n        foreach (immutable ref x; arr) {}\n      }));\n\n        // with exact type + qualifier\n        foreach (          int x; arr) static assert(is(typeof(x) == int));\n        foreach (    const int x; arr) static assert(is(typeof(x) == const int));\n        foreach (immutable int x; arr) static assert(is(typeof(x) == immutable int));\n\n        // with exact type + qualifier + ref\n        foreach (          ref int x; arr) static assert(is(typeof(x) == int));\n        foreach (    const ref int x; arr) static assert(is(typeof(x) == const int));\n      static assert(!__traits(compiles, {\n        foreach (immutable ref int x; arr) {}\n      }));\n\n        // convertible type + qualifier\n        foreach (          double x; arr) static assert(is(typeof(x) == double));\n        foreach (    const double x; arr) static assert(is(typeof(x) == const double));\n        foreach (immutable double x; arr) static assert(is(typeof(x) == immutable double));\n\n        // convertible type + qualifier + ref\n      static assert(!__traits(compiles, {\n        foreach (          ref double x; arr) {}\n      }));\n      static assert(!__traits(compiles, {\n        foreach (    const ref double x; arr) {}\n      }));\n      static assert(!__traits(compiles, {\n        foreach (immutable ref double x; arr) {}\n      }));\n    }\n    // for the immutable elements\n    {\n        immutable(int)[] iarr = [1,2,3];\n\n        // inference + qualifier\n        foreach (          x; iarr) static assert(is(typeof(x) == immutable int));  // same as variable declaration\n        foreach (    const x; iarr) static assert(is(typeof(x) == immutable int));  // same as variable declaration\n        foreach (immutable x; iarr) static assert(is(typeof(x) == immutable int));\n\n        // inference + qualifier + ref\n        foreach (          ref x; iarr) static assert(is(typeof(x) == immutable int));  // same as variable declaration\n        foreach (    const ref x; iarr) static assert(is(typeof(x) == immutable int));  // same as variable declaration\n        foreach (immutable ref x; iarr) static assert(is(typeof(x) == immutable int));\n\n        // with exact type + qualifier\n        foreach (          int x; iarr) static assert(is(typeof(x) == int));\n        foreach (    const int x; iarr) static assert(is(typeof(x) == const int));\n        foreach (immutable int x; iarr) static assert(is(typeof(x) == immutable int));\n\n        // with exact type + qualifier + ref\n      static assert(!__traits(compiles, {\n        foreach (          ref int x; iarr) {}\n      }));\n        foreach (    const ref int x; iarr) static assert(is(typeof(x) == const int));\n        foreach (immutable ref int x; iarr) static assert(is(typeof(x) == immutable int));\n\n        // convertible type + qualifier\n        foreach (          double x; iarr) static assert(is(typeof(x) == double));\n        foreach (    const double x; iarr) static assert(is(typeof(x) == const double));\n        foreach (immutable double x; iarr) static assert(is(typeof(x) == immutable double));\n\n        // convertible type + qualifier + ref\n      static assert(!__traits(compiles, {\n        foreach (ref double x; iarr) {}\n      }));\n      static assert(!__traits(compiles, {\n        foreach (const ref double x; iarr) {}\n      }));\n      static assert(!__traits(compiles, {\n        foreach (immutable ref double x; iarr) {}\n      }));\n    }\n}\n\nvoid test4090b()\n{\n    // for the key\n    {\n        int[] arr = [1,2,3];\n\n        // inference + qualifier\n        foreach (          i, x; arr) static assert(is(typeof(i) == size_t));\n        foreach (    const i, x; arr) static assert(is(typeof(i) == const size_t));\n        foreach (immutable i, x; arr) static assert(is(typeof(i) == immutable size_t));\n\n        // inference + qualifier + ref\n        foreach (          ref i, x; arr) static assert(is(typeof(i) == size_t));\n        foreach (    const ref i, x; arr) static assert(is(typeof(i) == const size_t));\n      static assert(!__traits(compiles, {\n        foreach (immutable ref i, x; arr) {}\n      }));\n\n        // with exact type + qualifier\n        foreach (          size_t i, x; arr) static assert(is(typeof(i) == size_t));\n        foreach (    const size_t i, x; arr) static assert(is(typeof(i) == const size_t));\n        foreach (immutable size_t i, x; arr) static assert(is(typeof(i) == immutable size_t));\n\n        // with exact type + qualifier + ref\n        foreach (          ref size_t i, x; arr) static assert(is(typeof(i) == size_t));\n        foreach (    const ref size_t i, x; arr) static assert(is(typeof(i) == const size_t));\n      static assert(!__traits(compiles, {\n        foreach (immutable ref size_t i, x; arr) {}\n      }));\n    }\n\n    // for the mutable elements\n    {\n        int[] arr = [1,2,3];\n\n        // inference + qualifier\n        foreach (i,           x; arr) static assert(is(typeof(x) == int));\n        foreach (i,     const x; arr) static assert(is(typeof(x) == const int));\n        foreach (i, immutable x; arr) static assert(is(typeof(x) == immutable int));\n\n        // inference + qualifier + ref\n        foreach (i,           ref x; arr) static assert(is(typeof(x) == int));\n        foreach (i,     const ref x; arr) static assert(is(typeof(x) == const int));\n      static assert(!__traits(compiles, {\n        foreach (i, immutable ref x; arr) {}\n      }));\n\n        // with exact type + qualifier\n        foreach (i,           int x; arr) static assert(is(typeof(x) == int));\n        foreach (i,     const int x; arr) static assert(is(typeof(x) == const int));\n        foreach (i, immutable int x; arr) static assert(is(typeof(x) == immutable int));\n\n        // with exact type + qualifier + ref\n        foreach (i,           ref int x; arr) static assert(is(typeof(x) == int));\n        foreach (i,     const ref int x; arr) static assert(is(typeof(x) == const int));\n      static assert(!__traits(compiles, {\n        foreach (i, immutable ref int x; arr) {}\n      }));\n\n        // convertible type + qualifier\n        foreach (i,           double x; arr) static assert(is(typeof(x) == double));\n        foreach (i,     const double x; arr) static assert(is(typeof(x) == const double));\n        foreach (i, immutable double x; arr) static assert(is(typeof(x) == immutable double));\n\n        // convertible type + qualifier + ref\n      static assert(!__traits(compiles, {\n        foreach (i,           ref double x; arr) {}\n      }));\n      static assert(!__traits(compiles, {\n        foreach (i,     const ref double x; arr) {}\n      }));\n      static assert(!__traits(compiles, {\n        foreach (i, immutable ref double x; arr) {}\n      }));\n    }\n    // for the immutable elements\n    {\n        immutable(int)[] iarr = [1,2,3];\n\n        // inference + qualifier\n        foreach (i,           x; iarr) static assert(is(typeof(x) == immutable int));  // same as variable declaration\n        foreach (i,     const x; iarr) static assert(is(typeof(x) == immutable int));  // same as variable declaration\n        foreach (i, immutable x; iarr) static assert(is(typeof(x) == immutable int));\n\n        // inference + qualifier + ref\n        foreach (i,           ref x; iarr) static assert(is(typeof(x) == immutable int));  // same as variable declaration\n        foreach (i,     const ref x; iarr) static assert(is(typeof(x) == immutable int));  // same as variable declaration\n        foreach (i, immutable ref x; iarr) static assert(is(typeof(x) == immutable int));\n\n        // with exact type + qualifier\n        foreach (i,           int x; iarr) static assert(is(typeof(x) == int));\n        foreach (i,     const int x; iarr) static assert(is(typeof(x) == const int));\n        foreach (i, immutable int x; iarr) static assert(is(typeof(x) == immutable int));\n\n        // with exact type + qualifier + ref\n      static assert(!__traits(compiles, {\n        foreach (i,           ref int x; iarr) {}\n      }));\n        foreach (i,     const ref int x; iarr) static assert(is(typeof(x) == const int));\n        foreach (i, immutable ref int x; iarr) static assert(is(typeof(x) == immutable int));\n\n        // convertible type + qualifier\n        foreach (i      ,     double x; iarr) static assert(is(typeof(x) == double));\n        foreach (i,     const double x; iarr) static assert(is(typeof(x) == const double));\n        foreach (i, immutable double x; iarr) static assert(is(typeof(x) == immutable double));\n\n        // convertible type + qualifier + ref\n      static assert(!__traits(compiles, {\n        foreach (i, ref double x; iarr) {}\n      }));\n      static assert(!__traits(compiles, {\n        foreach (i, const ref double x; iarr) {}\n      }));\n      static assert(!__traits(compiles, {\n        foreach (i, immutable ref double x; iarr) {}\n      }));\n    }\n}\n\nvoid test4090c()\n{\n    foreach (          x; 1..11) static assert(is(typeof(x) == int));\n    foreach (    const x; 1..11) static assert(is(typeof(x) == const int));\n    foreach (immutable x; 1..11) static assert(is(typeof(x) == immutable int));\n\n    foreach (          int x; 1..11) static assert(is(typeof(x) == int));\n    foreach (    const int x; 1..11) static assert(is(typeof(x) == const int));\n    foreach (immutable int x; 1..11) static assert(is(typeof(x) == immutable int));\n\n    foreach (          ref x; 1..11) static assert(is(typeof(x) == int));\n    foreach (    const ref x; 1..11) static assert(is(typeof(x) == const int));\n  static assert(!__traits(compiles, {\n    foreach (immutable ref x; 1..11) {}\n  }));\n\n    foreach (          double x; 1..11) static assert(is(typeof(x) == double));\n    foreach (    const double x; 1..11) static assert(is(typeof(x) == const double));\n    foreach (immutable double x; 1..11) static assert(is(typeof(x) == immutable double));\n\n    foreach (          ref double x; 1..11) static assert(is(typeof(x) == double));\n    foreach (    const ref double x; 1..11) static assert(is(typeof(x) == const double));\n  static assert(!__traits(compiles, {\n    foreach (immutable ref double x; 1..11) {}\n  }));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test4364.d",
    "content": "struct Object{}\nclass Game {}\n\nvoid main()\n{\n    static assert(is(Object == struct));\n    static assert(is(object.Object == class));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test4375.d",
    "content": "// REQUIRED_ARGS: -unittest\n// https://issues.dlang.org/show_bug.cgi?id=4375\n// disallow dangling else\n\nvoid main() {\n\n\tif (true) {\n\t\tif (false) {\n\t\t\tassert(1);\n\t\t} else {\n\t\t\tassert(2);\n\t\t}\n\t}\n\n\n    if (true) {\n        if (false)\n            assert(7);\n    } else\n        assert(8);\n\n\n    if (true) {\n        if (false)\n            assert(9);\n        else\n            assert(10);\n    }\n\n\n    {\n        if (true)\n            assert(11);\n        else\n            assert(12);\n    }\n\n\n    {\nlabel1:\n        if (true)\n            assert(13);\n        else\n            assert(14);\n    }\n\n\n\tif (true)\n\t\tforeach (i; 0 .. 5) {\n\t\t\tif (true)\n\t\t\t\tassert(17);\n            else\n                assert(18);\n        }\n\n\n\tif (true) {\n\t\tforeach (i; 0 .. 5)\n\t\t\tif (true)\n\t\t\t\tassert(18.1);\n    } else\n        assert(18.2);\n\n\n    if (true)\n        assert(19);\n    else\n        assert(20);\n\n\n    if (true)\n        assert(21);\n    else if (false)\n        assert(22);\n    else\n        assert(23);\n\n\n    version (A) {\n        if (true)\n            assert(26);\n    } else\n        assert(27);\n\n\n    version (A) {\n        if (true)\n            assert(28);\n        else\n            assert(29);\n    }\n\n\n    version (A)\n        assert(30);\n    else version (B)\n        assert(31);\n    else\n        assert(32);\n\n\n    static if (true) {\n        static if (true)\n            assert(35);\n    } else\n        assert(36);\n\n\n    static if (true) {\n        static if (true)\n            assert(37);\n        else\n            assert(38);\n    }\n\n\n    static if (true)\n        assert(39);\n    else static if (true)\n        assert(40);\n    else\n        assert(41);\n\n    switch (4) {\n        case 0:\n            if (true)\n                assert(42);\n            else\n                assert(43);\n            break;\n        case 1: .. case 5:\n            if (true)\n                assert(44);\n            else\n                assert(45);\n            break;\n        default:\n            if (true)\n                assert(46);\n            else\n                assert(47);\n            break;\n    }\n\n    // (o_O)\n    switch (1)\n        default:\n            if (true)\n                assert(113);\n            else\n                assert(114);\n\n    // (o_O)\n    final switch (1)\n        case 1:\n            if (true)\n                assert(117);\n            else\n                assert(118);\n\n    mixin(q{\n        if (true)\n            assert(56);\n        else\n            assert(57);\n    });\n\n\n\n    while (false)\n        if (true)\n            assert(66);\n        else\n            assert(67);\n\n\n    if (true)\n        while (false)\n            assert(68);\n    else\n        assert(69);\n\n\n    do\n        if (true)\n            assert(72);\n        else\n            assert(73);\n    while (false);\n\n\n    if (true)\n        do\n            if (true)\n                assert(74);\n            else\n                assert(75);\n        while (false);\n\n    for (\n        if (true)        // (o_O)\n            assert(78);\n        else\n            assert(79);\n        false; false\n    )\n        if (true)\n            assert(80);\n        else\n            assert(81);\n\n    if (true)\n        for (if (true) assert(84); else assert(85); false;)\n            assert(86);\n\n\n    if (true)\n        if (true)\n            if (true)\n                if (true)\n                    if (true)\n                        assert(87);\n\n    auto x = new C;\n\n\n    if (true)\n        while (false)\n            for (;;)\n                scope (exit)\n                    synchronized (x)\n                        assert(88);\n    else\n        assert(89);\n\n\n    if (true)\n        while (false)\n            for (;;) {\n                scope (exit)\n                    synchronized (x)\n                        if (true)\n                            assert(90);\n                        else\n                            assert(89);\n            }\n\n\n    if (true)\n        while (false)\n            for (;;)\n                scope (exit)\n                    synchronized (x)\n                        if (true)\n                            assert(90);\n                        else\n                            assert(89);\n    else\n        assert(12); \n\n\n    with (x)\n        if (false)\n            assert(92);\n        else\n            assert(93);\n\n\n    try\n        if (true)\n            assert(94);\n        else\n            assert(95);\n    catch (Exception e)\n        if (true)\n            assert(96);\n        else\n            assert(97);\n    finally\n        if (true)\n            assert(98);\n        else\n            assert(99);\n\n\n    if (true)\n        try\n            if (true)\n                assert(100);\n            else\n                assert(101);\n        finally\n            assert(102);\n\n    if (true)\n        try\n            assert(109);\n        catch(Exception e)\n            if (true)\n                assert(110);\n            else\n                assert(112);                \n        finally\n            assert(111);\n\n    static struct F {\n        static if (true)\n            int x;\n        else\n            int y;\n\n        static if (true) {\n            static if (false)\n                int z;\n        } else\n            int w;\n\n        static if (true)\n            int t; \n        else static if (false)\n            int u;\n        else\n            int v;\n    }\n\n    if (true)\n        if (true)\n            assert(113);\n        else\n            assert(114);\n    else\n        assert(115);\n\n    static if (true)\n        static if (true)\n            assert(116);\n        else\n            assert(117);\n    else\n        assert(118);\n\n}\n\nunittest {\n    if (true)\n        assert(50);\n    else\n        assert(51);\n}\n\nclass C {\n    invariant() {\n        if (true)\n            assert(58);\n        else\n            assert(59);\n    }\n\n    int f()\n    in {\n        if (true)\n            assert(60);\n        else\n            assert(61);\n    }\n    out(res) {\n        if (true)\n            assert(62);\n        else\n            assert(63);\n    }\n    body {\n        if (true)\n            assert(64);\n        else\n            assert(65);\n        return 0;\n    }\n}\n\nenum q = q{\n    if(true)\n        if(true)\n            assert(54.1);\n    else\n        assert(55.2);\n};\n\nstatic if (true)\n    struct F0 {}\nelse static if (true)\n    struct F1 {}\nelse\n    struct F2 {}\n\nstatic if (true) {\n    static if (false)\n        struct F3 {}\n} else\n    struct F4 {}\n\nversion(A) {\n    version(B)\n        struct F5 {}\n} else\n    struct F6 {}\n\nversion(A) {\n    version(B)\n        struct F5a {}\n    else\n        struct F5b {}\n}\n\nversion (C)\n    struct F5c {}\nelse\n    struct F5d {}\n\nstruct F7 {\n    static if (true)\n        int x;\n    else\n        float x;\n\nprivate:\n    static if (true)\n        int y;\n    else\n        float y;\n}\n\ntemplate F8() {\n    static if (true)\n        int x;\n    else\n        float x;\n}\n\nstatic if (true)\n    align(1)\n        static if (false)\n            struct F9 {}\n\nstatic if (true)\n    align(1) {\n        extern(C)\n            pure\n                static if (false)\n                    void F10(){}\n                else\n                    void F11(){}\n    }\n\n\nvoid f() {\n    int[] x;\n    static if (5 > 0)\n        version (Y)\n            scope (failure)\n                foreach (i, e; x)\n                    while (i > 20)\n                        with (e)\n                            if (e < 0)\n                                synchronized(e)\n                                    assert(1);\n                            else\n                                assert(2);\n        else\n            x = null;\n    else\n        x = null;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test50.d",
    "content": "// COMPILED_IMPORTS: imports/test50a.d\n// PERMUTE_ARGS:\n\nimport imports.test50a;\n\nclass Bar : Foo {\n        alias typeof(Foo.tupleof) Bleh;\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test5227.d",
    "content": "/*\nREQUIRED_ARGS:\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nlog()\n1.70475L\nlog2()\n2.45943L\nlog10()\n0.740363L\nround()\n6.00000L\nfloor()\n5.00000F\n5.00000\n5.00000L\nceil()\n6.00000F\n6.00000\n6.00000L\ntrunc()\n5.00000L\nexp()\n244.692L\nexpm1()\n243.692L\nexp2()\n45.2548L\nfmin()\n-3.2L\nfmax()\n5.2L\ncopysign()\n-2.5F\n-2.5\n-2.5L\npow()\n9.88212F\n9.88212\n9.88212L\n9.88212\nfma()\n-12.84L\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=5227\n\nimport std.math;\n\npragma(msg, \"log()\");\nenum logf = log(5.5f); //pragma(msg, logf);\nenum logd = log(5.5 ); //pragma(msg, logd);\nenum logr = log(5.5L); pragma(msg, logr);\n\npragma(msg, \"log2()\");\nenum log2f = log2(5.5f); //pragma(msg, log2f);\nenum log2d = log2(5.5 ); //pragma(msg, log2d);\nenum log2r = log2(5.5L); pragma(msg, log2r);\n\npragma(msg, \"log10()\");\nenum log10f = log10(5.5f); //pragma(msg, log10f);\nenum log10d = log10(5.5 ); //pragma(msg, log10d);\nenum log10r = log10(5.5L); pragma(msg, log10r);\n\npragma(msg, \"round()\");\nenum roundf = round(5.5f); //pragma(msg, roundf);\nenum roundd = round(5.5 ); //pragma(msg, roundd);\nenum roundr = round(5.5L); pragma(msg, roundr);\n\npragma(msg, \"floor()\");\nenum floorf = floor(5.5f); pragma(msg, floorf);\nenum floord = floor(5.5 ); pragma(msg, floord);\nenum floorr = floor(5.5L); pragma(msg, floorr);\n\npragma(msg, \"ceil()\");\nenum ceilf = ceil(5.5f); pragma(msg, ceilf);\nenum ceild = ceil(5.5 ); pragma(msg, ceild);\nenum ceilr = ceil(5.5L); pragma(msg, ceilr);\n\npragma(msg, \"trunc()\");\nenum truncf = trunc(5.5f); //pragma(msg, truncf);\nenum truncd = trunc(5.5 ); //pragma(msg, truncd);\nenum truncr = trunc(5.5L); pragma(msg, truncr);\n\npragma(msg, \"exp()\");\nenum expf = exp(5.5f); //pragma(msg, expf);\nenum expd = exp(5.5 ); //pragma(msg, expd);\nenum expr = exp(5.5L); pragma(msg, expr);\n\npragma(msg, \"expm1()\");\nenum expm1f = expm1(5.5f); //pragma(msg, expm1f);\nenum expm1d = expm1(5.5 ); //pragma(msg, expm1d);\nenum expm1r = expm1(5.5L); pragma(msg, expm1r);\n\npragma(msg, \"exp2()\");\nenum exp2f = exp2(5.5f); //pragma(msg, exp2f);\nenum exp2d = exp2(5.5 ); //pragma(msg, exp2d);\nenum exp2r = exp2(5.5L); pragma(msg, exp2r);\n\n\n\npragma(msg, \"fmin()\");\nenum fminf = fmin(-3.2f, 5.2f); //pragma(msg, fminf);\nenum fmind = fmin(-3.2 , 5.2 ); //pragma(msg, fmind);\nenum fminr = fmin(-3.2L, 5.2L); pragma(msg, fminr);\n\npragma(msg, \"fmax()\");\nenum fmaxf = fmax(-3.2f, 5.2f); //pragma(msg, fmaxf);\nenum fmaxd = fmax(-3.2 , 5.2 ); //pragma(msg, fmaxd);\nenum fmaxr = fmax(-3.2L, 5.2L); pragma(msg, fmaxr);\n\npragma(msg, \"copysign()\");\nenum csf = copysign(2.5f, -3.0f); pragma(msg, csf); static assert(csf == -2.5);\nenum csd = copysign(2.5 , -3.0 ); pragma(msg, csd); static assert(csd == -2.5);\nenum csr = copysign(2.5L, -3.0L); pragma(msg, csr); static assert(csr == -2.5);\n\npragma(msg, \"pow()\");\nenum powf = pow(2.5f, 2.5f); pragma(msg, powf);\nenum powd = pow(2.5 , 2.5 ); pragma(msg, powd);\nenum powr = pow(2.5L, 2.5L); pragma(msg, powr);\nenum powctfe = 2.5 ^^ 2.5; pragma(msg, powctfe);\n\n\npragma(msg, \"fma()\");\nenum fmaf = fma(-3.2f, 5.2f, 3.8f); //pragma(msg, fmaf);\nenum fmad = fma(-3.2 , 5.2 , 3.8 ); //pragma(msg, fmad);\nenum fmar = fma(-3.2L, 5.2L, 3.8L); pragma(msg, fmar);\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test55.d",
    "content": "// COMPILE_SEPARATELY\n// COMPILED_IMPORT: imports/test55a.d\n// PERMUTE_ARGS: -dw\n// REQUIRED_ARGS: -d\n\npublic import imports.test55a;\n\nclass Queue {\n  alias int ListHead;\n  Arm a;\n}\n\nclass MessageQueue : Queue {\n}\n\nclass Queue2 {\n  alias int ListHead;\n  Arm2 a;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test59.d",
    "content": "// PERMUTE_ARGS:\n\npublic import imports.test59a;\npublic import imports.test59b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test5973.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=5973\n\nclass A { int a = 1; }\nclass B { int b = 2; }\nclass C : A\n{\n    B obj;\n    alias obj this;\n    this(){ obj = new B(); }\n}\nclass X : C {}\n\nclass D\n{\n    int i;\n}\n\nclass E\n{\n    D x;\n    alias x this;\n}\n\nclass F : E\n{\n    void test()\n    {\n        i = 5;\n    }\n}\n\nvoid main()\n{\n    auto c = new C();\n    assert(c.a == 1);   // lookup C -> A, OK\n    assert(c.b == 2);   // lookup C => B, OK\n\n    auto x = new X();\n    assert(x.a == 1);   // lookup X -> C -> A, OK\n    assert(x.b == 2);   // lookup X -> C => B, NG (Line 17)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test6013.d",
    "content": "// REQUIRED_ARGS: -de\nimport imports.test6013;\n\nstatic assert(__traits(compiles, public_alias_value));\nstatic assert(!__traits(compiles, private_alias_value));\nstatic assert(__traits(compiles, public_alias_func()));\nstatic assert(!__traits(compiles, private_alias_func()));\nstatic assert(__traits(compiles, () { public_alias_type val; }));\nstatic assert(!__traits(compiles, () { private_alias_type val; }));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test602.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\n// Disallow skipping variable decl\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    int x;\n    label: {}\n    assert(!x);\n}));\n\n// Disallow skipping variable in block backwards\nstatic assert(!__traits(compiles, (bool b)\n{\n    {\n        int x;\n        label: {}\n        assert(!x);\n    }\n    if (b) goto label;\n}));\n\n// Disallow skipping backwards int block\nstatic assert(!__traits(compiles, (bool b)\n{\n    {\n    int x;\n    label: {}\n    assert(!x);\n    }\n    if (b) goto label;\n}));\n\n// Variable inside try block\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    try\n    {\n        int x;\n    label: {}\n        assert(!x);\n    }\n    catch(Throwable)\n    {\n    }\n}));\n\n// Variable inside catch block\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    try\n    {\n    }\n    catch(Throwable)\n    {\n        int x;\n    label: {}\n        assert(!x);\n    }\n}));\n\n// Goto into catch block with unnamed exception\nstatic assert(__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    try\n    {\n    }\n    catch(Exception)\n    {\n    label: {}\n    }\n}));\n\n// Goto into catch block with named exception\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    try\n    {\n    }\n    catch(Exception e)\n    {\n    label: {}\n        assert(e);\n    }\n}));\n\n// Goto into finally block\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    try\n    {\n    }\n    finally\n    {\n    label: {}\n    }\n}));\n\n// Goto into variable with block\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    struct S\n    {\n        int x;\n    }\n    with (S())\n    {\n    label: {}\n        assert(!x);\n    }\n}));\n\n// Goto backwards into variable with block\nstatic assert(!__traits(compiles, (bool b)\n{\n    struct S\n    {\n        int x;\n    }\n    with (S())\n    {\n    label: {}\n        assert(!x);\n    }\n    if (b) goto label;\n}));\n\n// Goto into symbolic with block\nstatic assert(__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    struct S\n    {\n        int x;\n    }\n    with (S)\n    {\n    label: {}\n    }\n}));\n\n// Goto backwards into symbolic with block\nstatic assert(__traits(compiles, (bool b)\n{\n    struct S\n    {\n        int x;\n    }\n    with (S)\n    {\n    label: {}\n    }\n    if (b) goto label;\n}));\n\n// Goto into for loop\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    for (int i = 0; i < 8; ++i)\n    {\n    label: {}\n        assert(i);\n    }\n}));\n\n// Goto into for loop backwards\nstatic assert(!__traits(compiles, (bool b)\n{\n    for (int i = 0; i < 8; ++i)\n    {\n    label: {}\n        assert(i);\n    }\n    if (b) goto label;\n}));\n\n// Goto into foreach loop\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    foreach(i; 0..8)\n    {\n    label: {}\n        assert(i);\n    }\n}));\n\n// Goto into foreach loop backwards\nstatic assert(!__traits(compiles, (bool b)\n{\n    foreach(i; 0..8)\n    {\n    label: {}\n        assert(i);\n    }\n    if (b) goto label;\n}));\n\n// Goto into if block with variable\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    if (auto x = b)\n    {\n    label: {}\n        assert(x);\n    }\n}));\n\n// Goto backwards into if block with variable\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (auto x = b)\n    {\n    label: {}\n        assert(x);\n    }\n    if (b) goto label;\n}));\n\n// Goto into if block without variable\nstatic assert(__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    if (b)\n    {\n    label: {}\n    }\n}));\n\n// Goto into else block\nstatic assert(__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    if (auto x = b)\n    {\n    }\n    else\n    {\n    label: {}\n    }\n}));\n\n// Goto backwards into else with variable\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (auto x = b)\n    {\n    }\n    else\n    {\n        int y;\n    label: {}\n    }\n    if (b) goto label;\n}));\n\n// Goto into while block\nstatic assert(__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    while (b)\n    {\n    label: {}\n    }\n}));\n\n// Goto into while block with internal variable\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    while (b)\n    {\n        int x;\n    label: {}\n        assert(!x);\n    }\n}));\n\n// Goto into do block\nstatic assert(__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    do\n    {\n    label: {}\n    }\n    while (b);\n}));\n\n// Goto over switch variable\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    switch(0)\n    {\n    default:\n        break;\n        int x;\n    label: {}\n    }\n}));\n\n// Goto over switch variable\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b) goto label;\n    switch(0)\n    {\n    default:\n        break;\n    case 0:\n        int x;\n    label: {}\n    }\n}));\n\n// Goto into synchronized statement\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b)\n        goto label;\n    synchronized\n    {\n    label: {}\n    }\n}));\n\n// Goto into scope(success) with variable\nstatic assert(!__traits(compiles, (bool b)\n{\n    scope(success) { int x; label: {} assert(!x); }\n    if (b)\n        goto label;\n}));\n\n// Goto into scope(failure)\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b)\n        goto label;\n    scope(failure) { label: {} }\n}));\n\n// Goto into scope(failure) with variable\nstatic assert(!__traits(compiles, (bool b)\n{\n    scope(failure) { int x; label: {} assert(!x); }\n    if (b)\n        goto label;\n}));\n\n// Goto into scope(exit)\nstatic assert(!__traits(compiles, (bool b)\n{\n    if (b)\n        goto label;\n    scope(exit) { label: {} }\n}));\n\n// Goto into scope(exit)\nstatic assert(!__traits(compiles, (bool b)\n{\n    scope(exit) { label: {} }\n    if (b)\n        goto label;\n}));\n\n// Goto into scope(exit) with variable\nstatic assert(!__traits(compiles, (bool b)\n{\n    scope(exit) { int x; label: {} assert(!x); }\n    if (b)\n        goto label;\n}));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11659\n\nint test11659()\n{\n    goto LABEL;\n    enum expr = \"0\";\n LABEL:\n    return mixin(expr);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13321\n\nvoid test13321(bool b)\n{\n    static struct Foo\n    {\n        this(int) {}\n    }\n\n    Foo x;\n    if (b)\n        goto EXIT;\n    x = Foo(1);\n  EXIT:\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test6056a.d",
    "content": "alias const(typeof('c')*) A;\nalias const(typeof(0)*) B;\nstatic assert(is(B == const(int*)));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test6056b.d",
    "content": "template X(T) { alias T X; }\n\nalias const(X!char*) A;\nalias const(X!int*) B;\nstatic assert(is(B == const(int*)));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test6056c.d",
    "content": "alias int T;\nstatic assert( is( T** : const(T**) ));\nstatic assert( is( T*  : const(T* ) ));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test6089.d",
    "content": "// PERMUTE_ARGS:\nvoid main()\n{\n    extern int[1][1] foo;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test61.d",
    "content": "// PERMUTE_ARGS:\n\nimport imports.test61a;\nalias imports.test61a.bar bar;\n\nmixin(`\nenum FooB { fooB };\nvoid bar(FooB x) {}\n`);\n\nvoid test()\n{\n    bar(FooA.fooA);\n    bar(FooB.fooB);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test62.d",
    "content": "// PERMUTE_ARGS:\n\nimport imports.test62a;\n\nstruct S { }\n\nvoid main() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test63.d",
    "content": "// COMPILED_IMPORTS: imports/test63a.d\n// PERMUTE_ARGS:\n\nprivate import imports.test63a;\n\nconst int SIZE = 7;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test6319.d",
    "content": "// REQUIRED_ARGS: -debug\n\nint x;\n\nvoid main() pure\n{\n    debug\n    {\n        {\n            x = 0;\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test6395.d",
    "content": "// REQUIRED_ARGS: -Icompilable/extra-files\n// EXTRA_SOURCES: b6395.d\n\n// https://issues.dlang.org/show_bug.cgi?id=6395\n\nimport c6395;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test6534.d",
    "content": "void main()\n{\n                 class  MC{ int x; }\n           const class  CC{ int x; }    static assert(is(typeof( CC.x) == const));\n       immutable class  IC{ int x; }    static assert(is(typeof( IC.x) == immutable));\n          shared class  SC{ int x; }    static assert(is(typeof( SC.x) == shared));\n    shared const class SCC{ int x; }    static assert(is(typeof(SCC.x) == shared) && is(typeof(SCC.x) == const));\n\n                 struct  MS{ int x; }\n           const struct  CS{ int x; }   static assert(is(typeof( CS.x) == const));\n       immutable struct  IS{ int x; }   static assert(is(typeof( IS.x) == immutable));\n          shared struct  SS{ int x; }   static assert(is(typeof( SS.x) == shared));\n    shared const struct SCS{ int x; }   static assert(is(typeof(SCS.x) == shared) && is(typeof(SCS.x) == const));\n\n                 union  MU{ int x; }\n           const union  CU{ int x; }    static assert(is(typeof( CU.x) == const));\n       immutable union  IU{ int x; }    static assert(is(typeof( IU.x) == immutable));\n          shared union  SU{ int x; }    static assert(is(typeof( SU.x) == shared));\n    shared const union SCU{ int x; }    static assert(is(typeof(SCU.x) == shared) && is(typeof(SCU.x) == const));\n\n\n                 static class  S_MC{ int x; }\n           const static class  S_CC{ int x; }    static assert(is(typeof( S_CC.x) == const));\n       immutable static class  S_IC{ int x; }    static assert(is(typeof( S_IC.x) == immutable));\n          shared static class  S_SC{ int x; }    static assert(is(typeof( S_SC.x) == shared));\n    shared const static class S_SCC{ int x; }    static assert(is(typeof(S_SCC.x) == shared) && is(typeof(S_SCC.x) == const));\n\n                 static struct  S_MS{ int x; }\n           const static struct  S_CS{ int x; }   static assert(is(typeof( S_CS.x) == const));\n       immutable static struct  S_IS{ int x; }   static assert(is(typeof( S_IS.x) == immutable));\n          shared static struct  S_SS{ int x; }   static assert(is(typeof( S_SS.x) == shared));\n    shared const static struct S_SCS{ int x; }   static assert(is(typeof(S_SCS.x) == shared) && is(typeof(S_SCS.x) == const));\n\n                 static union  S_MU{ int x; }\n           const static union  S_CU{ int x; }    static assert(is(typeof( S_CU.x) == const));\n       immutable static union  S_IU{ int x; }    static assert(is(typeof( S_IU.x) == immutable));\n          shared static union  S_SU{ int x; }    static assert(is(typeof( S_SU.x) == shared));\n    shared const static union S_SCU{ int x; }    static assert(is(typeof(S_SCU.x) == shared) && is(typeof(S_SCU.x) == const));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test6552.d",
    "content": "// REQUIRED_ARGS: -w\n\nvoid main()\n{\n    int i;\n    switch (i)\n    {\n        case 1, 2:\n        case 3, 4: break;\n        default: break;\n    }\n\n    char ch;\n    switch (ch)\n    {\n        case 'U', 'u':\n        case 'L', 'l':\n        default:\n    }\n\n    switch (i)\n    {\n        default: case 1:\n        case 3,4:\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test66.d",
    "content": "// PERMUTE_ARGS:\n\nimport imports.test66a;\n\nalias int TOK;\n\nenum\n{\n\tTOKmax\n};\n\nstruct Token\n{\n    static char[][TOKmax] tochars;\n}\n\nclass Lexer\n{\n    Token token;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test67.d",
    "content": "// PERMUTE_ARGS:\n\nimport imports.test67a;\n\ninterface I\n{\n}\n\ninterface SubI : I\n{\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test68.d",
    "content": "// PERMUTE_ARGS:\n\n// https://issues.dlang.org/show_bug.cgi?id=4278\n\nimport imports.test68a;\n\nclass Foo : OtherModuleClass\n{\n        override void foo()\n        {\n                super.foo();\n        }\n}\n\nvoid main()\n{\n        new Foo();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test69.d",
    "content": "// PERMUTE_ARGS:\n\n// ICE(expression.c) DMD 0.110\n// http://www.digitalmars.com/d/archives/digitalmars/D/bugs/2966.html\n\nstring str255() { return \"\\255\"; }\nvoid fromFail49()\n{\n    switch(\"abc\")\n    {\n\tcase \"\":\n\tcase str255():\n\t    break;\n    default:\n        break;\n    }\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=5735\n\nstruct A {}\nvoid b() {}\n\nvoid foo(bool cond) {}\n\nvoid main()\n{\n    A a;\n    int i;\n\n    static assert(!__traits(compiles, assert(a)));\n    static assert(!__traits(compiles, assert(i || a)));\n    static assert(!__traits(compiles, assert(0 || a)));\n    static assert(!__traits(compiles, assert(i && a)));\n    static assert(!__traits(compiles, assert(1 && a)));\n\n    static assert(!__traits(compiles, foo(a)));\n    static assert(!__traits(compiles, foo(i || a)));\n    static assert(!__traits(compiles, foo(0 || a)));\n    static assert(!__traits(compiles, foo(i && a)));\n    static assert(!__traits(compiles, foo(1 && a)));\n\n    static assert(!__traits(compiles, assert(b)));\n    static assert(!__traits(compiles, assert(i || b)));\n    static assert(!__traits(compiles, assert(0 || b)));\n    static assert(!__traits(compiles, assert(i && b)));\n    static assert(!__traits(compiles, assert(1 && b)));\n\n    static assert(!__traits(compiles, foo(b)));\n    static assert(!__traits(compiles, foo(i || b)));\n    static assert(!__traits(compiles, foo(0 || b)));\n    static assert(!__traits(compiles, foo(i && b)));\n    static assert(!__traits(compiles, foo(1 && b)));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test6999.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=6999: inout in front of return type\n\nstruct A\n{\ninout:\n    inout(int) foo()\n    {\n        return 0;\n    }\n}\n\nstruct B\n{\n    inout\n    {\n        inout(int) foo()\n        {\n            return 0;\n        }\n    }\n}\n\nstruct C\n{\n    inout inout(int) foo()\n    {\n        return 0;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test70.d",
    "content": "import imports.test70 : foo;\n\nvoid foo(int) // overloads with selective import\n{\n}\n\nvoid bar()\n{\n    foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test7065.d",
    "content": "void main()\n{\n    align(1)\n    struct X1 { ubyte b; int n; }\n    static assert(X1.sizeof == 8);\n    static assert(X1.b.offsetof == 0);\n    static assert(X1.n.offsetof == 4);\n    //X1 x1;\n    //assert(cast(void*)&x1.b == cast(void*)&x1 + 0);\n    //assert(cast(void*)&x1.n == cast(void*)&x1 + 1);\n\n    struct Y1 { ubyte b; int n; }\n    static assert(Y1.sizeof == 8);\n    static assert(Y1.b.offsetof == 0);\n    static assert(Y1.n.offsetof == 4);\n    //Y1 y1;\n    //assert(cast(void*)&y1.b == cast(void*)&y1 + 0);\n    //assert(cast(void*)&y1.n == cast(void*)&y1 + 4);\n\n    int local;\n\n    align(1)\n    struct X2 { ubyte b; int n; int f(){ return local; } }\n    static assert(X2.sizeof == 8 + (void*).sizeof);\n    static assert(X2.b.offsetof == 0);\n    static assert(X2.n.offsetof == 4);\n    //X2 x2;\n    //assert(cast(void*)&x2.b == cast(void*)&x2 + 0);\n    //assert(cast(void*)&x2.n == cast(void*)&x2 + 1);\n\n    struct Y2 { ubyte b; int n; int f(){ return local; } }\n    static assert(Y2.sizeof == 8 + (void*).sizeof);\n    static assert(Y2.b.offsetof == 0);\n    static assert(Y2.n.offsetof == 4);\n    //Y2 y2;\n    //assert(cast(void*)&y2.b == cast(void*)&y2 + 0);\n    //assert(cast(void*)&y2.n == cast(void*)&y2 + 4);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test71.d",
    "content": "import imports.test71;\n\nvoid bar()\n{\n    imports.test71.foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test7172.d",
    "content": "void main()\n{\n    abstract class AbstractC{}\n    static assert(!__traits(compiles, { new AbstractC(); }));\n\n    final class FinalC{}\n    static assert(!__traits(compiles, { class D : FinalC{} }));\n\n    scope class ScopeC{}\n    static assert(!__traits(compiles, { auto  sc = new ScopeC(); }));\n    static assert( __traits(compiles, { scope sc = new ScopeC(); }));\n\n    synchronized class SyncC{ void f(){} }\n    static assert(SyncC.f.mangleof[$-13..$] == \"5SyncC1fMOFZv\");\n\n    @safe    class SCx{ void f(){} }\n    @trusted class SCy{ void f(){} }\n    @system  class SCz{ void f(){} }\n\n    static assert(SCx.f.mangleof[$-12..$] == \"3SCx1fMFNfZv\");   // Nf: FuncAttrSafe\n    static assert(SCy.f.mangleof[$-12..$] == \"3SCy1fMFNeZv\");   // Ne: FuncAttrTrusted\n    static assert(SCz.f.mangleof[$-10..$] == \"3SCz1fMFZv\");     // (none)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test7190.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -Icompilable/extra-files\n// EXTRA_FILES: extra-files/example7190/controllers/HomeController.d extra-files/example7190/models/HomeModel.d extra-files/serenity7190/core/Controller.d  extra-files/serenity7190/core/Model.d\n\nimport example7190.controllers.HomeController;\nimport example7190.models.HomeModel;\n\nvoid main(){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test72.d",
    "content": "module test72;\n\nimport imports.test72a, imports.test72c;\n\nvoid bar()\n{\n    foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test7252.d",
    "content": "alias char* function() Func;\n\nalias const char* function() CFunc;\n\nvoid to(S)(S) { }\n\nvoid foo(CFunc cFunc)\n{\n    to(cFunc());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test7399.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=7399\nstatic assert(!__traits(compiles, { import non.existing.file; }));\n\n// https://issues.dlang.org/show_bug.cgi?id=7400\nstatic assert(!is(typeof({import non_existing_file;})));\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test7491.d",
    "content": "struct Struct\n{\n    import object;\n    import imports.test7491a;\n    import renamed=imports.test7491b;\n}\n\nstruct AliasThis\n{\n    Struct _struct;\n    alias _struct this;\n}\n\nclass Base\n{\n    import object;\n    import imports.test7491a;\n    import renamed=imports.test7491b;\n}\n\nclass Derived : Base\n{\n}\n\ninterface Interface\n{\n    import object;\n    import imports.test7491a;\n    import renamed=imports.test7491b;\n}\n\nclass Impl : Interface\n{\n}\n\nstatic assert(__traits(compiles, Struct.object));\nstatic assert(__traits(compiles, Struct.imports));\nstatic assert(__traits(compiles, Struct.renamed));\nstatic assert(__traits(compiles, AliasThis.object));\nstatic assert(__traits(compiles, AliasThis.imports));\nstatic assert(__traits(compiles, AliasThis.renamed));\nstatic assert(__traits(compiles, Base.object));\nstatic assert(__traits(compiles, Base.imports));\nstatic assert(__traits(compiles, Base.renamed));\nstatic assert(__traits(compiles, Derived.object));\nstatic assert(__traits(compiles, Derived.imports));\nstatic assert(__traits(compiles, Derived.renamed));\nstatic assert(__traits(compiles, Interface.object));\nstatic assert(__traits(compiles, Interface.imports));\nstatic assert(__traits(compiles, Interface.renamed));\nstatic assert(__traits(compiles, Impl.object));\nstatic assert(__traits(compiles, Impl.imports));\nstatic assert(__traits(compiles, Impl.renamed));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test7524.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=7524\n\n#line __LINE__ \"y.d\"\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test7569.d",
    "content": "template Tuple(T...)\n{\n    alias T Tuple;\n}\n\nvoid main()\n{\n    Tuple!(int, int) tup1 = void;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test7754.d",
    "content": "// REQUIRED_ARGS: -H -Hd${RESULTS_DIR}/compilable\n// POST_SCRIPT: compilable/extra-files/test7754-postscript.sh\n// PERMUTE_ARGS: -d -dw\n\nstruct Foo(T)\n{\n   shared static this()\n   {\n   }\n\n   static this()\n   {\n   }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test7815.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\n---\n*/\n\nmixin template Helpers()\n{\n    static if (is(Flags!Move))\n    {\n        Flags!Move flags;\n    }\n    else\n    {\n        pragma(msg, \"X: \", __traits(derivedMembers, Flags!Move));\n    }\n}\n\ntemplate Flags(T)\n{\n    mixin({\n        int defs = 1;\n        foreach (name; __traits(derivedMembers, Move))\n        {\n            defs++;\n        }\n        if (defs)\n        {\n            return \"struct Flags { bool x; }\";\n        }\n        else\n        {\n            return \"\";\n        }\n    }());\n}\n\nstruct Move\n{\n    int a;\n    mixin Helpers!();\n}\n\nenum a7815 = Move.init.flags;\n\n/+\nThis originally was an invalid case:\nWhen the Move struct member is analyzed:\n1. mixin Helpers!() is instantiated.\n2. In Helpers!(), static if and its condition is(Flags!Move)) evaluated.\n3. In Flags!Move, string mixin evaluates and CTFE lambda.\n4. __traits(derivedMembers, Move) tries to see the member of Move.\n   4a. mixin Helpers!() member is analyzed.\n   4b. `static if (is(Flags!Move))` in Helpers!() is evaluated\n   4c. The Flags!Move instantiation is already in progress, so it cannot be resolved.\n   4d. `static if` fails because Flags!Move cannot be determined as a type.\n5. __traits(derivedMembers, Move) returns a 1-length tuple(\"a\").\n6. The lambda in Flags!Move returns a string \"struct Flags {...}\", then\n   Flags!Move is instantiated to a new struct Flags.\n7. Finally Move struct does not have flags member, then the `enum a7815`\n   definition will fail in its initializer.\n\nNow, static if will behave like a string mixin: it is invisible during its own expansion.\n+/\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test7886.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=7886\n\nstruct A {\n\tstatic assert (__traits(derivedMembers, A).length == 0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8038.d",
    "content": "template t(T){alias T t;}\n\nt!(#line 10\n    t!(\n        int,\n    )\n) i;\n\nt!(\n    t!(#line 10\n        int,\n    )\n) j;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8041.d",
    "content": "// PERMUTE_ARGS:\n\nstruct Foo { }\n\nvoid main()\n{\n    static Foo sf;  // ok\n    __gshared Foo gf;  // was: Error: non-constant expression gf = 0\n    __gshared int[1][1] arr;  // dup: Issue 6089\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8296.d",
    "content": "struct bar2\n{\n  int i;\n  @disable this();\n  this(int i)\n  {\n    this.i = i;\n  }\n}\n\nclass InnerBar {\n  bar2 b;\n  \n  this()\n  {\n    b = bar2(0);\n  }\n}\n\nstruct bar1\n{\n  InnerBar b;\n}\n  \nclass Foo\n{\n  bar1 m_bar1;\n}\n\nvoid main(string[] args)\n{\n  auto foo = new Foo();\n}"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8509.d",
    "content": "module test8509;\nenum E : string { a = \"hello\", b = \"world\" }\nstruct S { E opCat(S s) { return E.a; } E opCat(string s) { return E.a; } }\n\nvoid main()\n{\n    E e3 = S() ~ S();\n    E e4 = S() ~ \"a\";\n    assert(e3 == E.a);\n    assert(e4 == E.a);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8513.d",
    "content": "interface I_Foo { void i_outer(); }\nclass C_Foo { void c_outer() { } }\n\nclass Bar\n{\n    interface I_Foo { void i_inner(); }\n    class C_Foo { void c_inner() { } }\n    \n    class Impl1 : C_Foo, I_Foo\n    {\n        override void i_inner() { }\n        override void c_inner() { }\n    }\n    \n    class Impl2 : C_Foo, .I_Foo\n    {\n        override void i_outer() { }\n        override void c_inner() { }\n    }\n    \n    class Impl3 : .C_Foo, I_Foo\n    {\n        override void i_inner() { }\n        override void c_outer() { }\n    }\n    \n    class Impl4 : .C_Foo, .I_Foo\n    {\n        override void i_outer() { }\n        override void c_outer() { }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8543.d",
    "content": "\nversion (D_SIMD)\n{\n    struct vfloat\n    {\n    public:\n        __vector(float[4]) f32;\n\n        this(float X) nothrow\n        {\n            f32.ptr[0] = X;\n            f32.ptr[1] = X;\n            f32.ptr[2] = X;\n            f32.ptr[3] = X;\n        }\n        this(float X, float Y, float Z, float W) nothrow\n        {\n            f32.array[0] = X;\n            f32.array[1] = Y;\n            f32.array[2] = Z;\n            f32.array[3] = W;\n        }\n        this(float[4] values) nothrow\n        {\n            f32.array = values;\n        }\n    }\n\n    immutable GvfGlobal_ThreeA = vfloat(3.0f);\n    immutable GvfGlobal_ThreeB = vfloat(3.0f, 3.0f, 3.0f, 3.0f);\n    immutable GvfGlobal_ThreeC = vfloat([3.0f, 3.0f, 3.0f, 3.0f]);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8631.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -de\n\nclass B {\n    int foo() immutable { return 2; }\n    int foo() const { return 2; }\n}\nclass D : B {\n    override int foo() immutable { return 2; }\n             int foo() const shared { return 2; }\n    override int foo() const { return 2; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8675.d",
    "content": "class MyError : Error\n{\n    this(string msg)\n    {\n        super(msg);\n    }\n}\n\nvoid foo() nothrow\n{\n    throw new Error(\"Some error\");\n}\n\nvoid bar() nothrow\n{\n    throw new MyError(\"Some error\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8696.d",
    "content": "// REQUIRED_ARGS: -w\n\n// https://issues.dlang.org/show_bug.cgi?id=8696\n// incorrect dangling else with version():\nversion (all):\n\nversion (linux)\n{\n}\nelse version (OSX)\n{\n}\nelse\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8717.d",
    "content": "module test8717;\n\nstruct SPR\n{\nprivate:\n    enum e = 1;\n    immutable int ii = 1;\n    immutable static int sii = 1;\n    static int sf() { return 1; }\n    int f() const { return 1; }\n}\n\nstatic assert(SPR.e == 1);\n//static assert(SPR.ii == 1);\nstatic assert(SPR.sii == 1);\nstatic assert(SPR.sf() == 1);\nstatic assert(SPR.init.e == 1);\nstatic assert(SPR.init.ii == 1);\nstatic assert(SPR.init.sii == 1);\nstatic assert(SPR.sf() == 1);\nstatic assert(SPR.init.f() == 1);\n\nstatic if(SPR.e != 1) { static assert(0); }\n//static if(SPR.ii != 1) { static assert(0); }\nstatic if(SPR.sii != 1) { static assert(0); }\nstatic if(SPR.sf() != 1) { static assert(0); }\nstatic if(SPR.init.e != 1) { static assert(0); }\nstatic if(SPR.init.ii != 1) { static assert(0); }\nstatic if(SPR.init.sii != 1) { static assert(0); }\nstatic if(SPR.sf() != 1) { static assert(0); }\nstatic if(SPR.init.f() != 1) { static assert(0); }\n\nstruct SPT\n{\nprotected:\n    enum e = 1;\n    immutable int ii = 1;\n    immutable static int sii = 1;\n    static int sf() { return 1; }\n    int f() const { return 1; }\n}\n\nstatic assert(SPT.e == 1);\n//static assert(SPT.ii == 1);\nstatic assert(SPT.sii == 1);\nstatic assert(SPT.sf() == 1);\nstatic assert(SPT.init.e == 1);\nstatic assert(SPT.init.ii == 1);\nstatic assert(SPT.init.sii == 1);\nstatic assert(SPT.sf() == 1);\nstatic assert(SPT.init.f() == 1);\n\nstatic if(SPT.e != 1) { static assert(0); }\n//static if(SPT.ii != 1) { static assert(0); }\nstatic if(SPT.sii != 1) { static assert(0); }\nstatic if(SPT.sf() != 1) { static assert(0); }\nstatic if(SPT.init.e != 1) { static assert(0); }\nstatic if(SPT.init.ii != 1) { static assert(0); }\nstatic if(SPT.init.sii != 1) { static assert(0); }\nstatic if(SPT.sf() != 1) { static assert(0); }\nstatic if(SPT.init.f() != 1) { static assert(0); }\n\nvoid main() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8802.d",
    "content": "// PERMUTE_ARGS:\nenum A : typeof(null)*\n{\n    a = null\n}\n\nenum B : typeof(null)**\n{\n    a = null\n}\n\nenum C : void*\n{\n    a = null\n}\n\nenum D : void**\n{\n    a = null\n}\n\nenum NullEn : void*\n{\n    z = null\n}\n\nenum E : NullEn\n{\n    a = null\n}\n\nvoid main()\n{\n    auto a = A.a;\n    auto b = B.a;\n    auto c = C.a;\n    auto d = D.a;\n    auto e = E.a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8898.d",
    "content": "// REQUIRED_ARGS: -w\n// PERMUTE_ARGS:\n\nstatic if (true):\n\nversion (Foo)\n{\n}\nelse\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8922a.d",
    "content": "// PERMUTE_ARGS:\nimport imports.bug8922;\n\nvoid test()\n{\n    static assert(!__traits(compiles, __traits(parent, imports)));\n    enum x = __traits(parent, imports.bug8922).stringof;\n    static assert(x == \"package imports\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8922b.d",
    "content": "// PERMUTE_ARGS:\nvoid test()\n{\n    import imports.bug8922;\n    static assert(!__traits(compiles, __traits(parent, imports)));\n    enum x = __traits(parent, imports.bug8922).stringof;\n    static assert(x == \"package imports\");\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8922c.d",
    "content": "// PERMUTE_ARGS:\nstatic import imports.bug8922;\n\nvoid test()\n{\n    static assert(!__traits(compiles, __traits(parent, imports)));\n    static assert(!__traits(compiles, __traits(parent, bug8922)));\n    enum x = __traits(parent, imports.bug8922).stringof;\n    static assert(x == \"package imports\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8922d.d",
    "content": "// PERMUTE_ARGS:\nvoid test()\n{\n    static import imports.bug8922;\n    static assert(!__traits(compiles, __traits(parent, imports)));\n    static assert(!__traits(compiles, __traits(parent, bug8922)));\n    enum x = __traits(parent, imports.bug8922).stringof;\n    static assert(x == \"package imports\");\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8922e.d",
    "content": "// PERMUTE_ARGS:\nimport renamed = imports.bug8922;\n\nvoid test()\n{\n    enum x = __traits(parent, renamed).stringof;\n    static assert(x == \"package imports\");\n    static assert(!__traits(compiles, __traits(parent, imports)));\n    static assert(!__traits(compiles, __traits(parent, bug8922)));\n    static assert(!__traits(compiles, __traits(parent, imports.bug8922)));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8922f.d",
    "content": "// PERMUTE_ARGS:\nvoid test()\n{\n    import renamed = imports.bug8922;\n    enum x = __traits(parent, renamed).stringof;\n    static assert(x == \"package imports\");\n    static assert(!__traits(compiles, __traits(parent, imports)));\n    static assert(!__traits(compiles, __traits(parent, bug8922)));\n    static assert(!__traits(compiles, __traits(parent, imports.bug8922)));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8937.d",
    "content": "\nmixin template X8937()\n{\n    int value;\n}\n\ndebug = test;\n\nvoid main()\n{\n    // (static) import statement\n    {\n        static assert(!__traits(compiles, cos(0)));\n        if (true)\n        {\n            static assert(!__traits(compiles, cos(0)));\n            import core.stdc.math;\n            static assert( __traits(compiles, cos(0)));\n        }\n        static assert(!__traits(compiles, cos(0)));\n\n        if (true)\n            import core.stdc.math;\n        static assert(!__traits(compiles, cos(0))); // fails\n\n        if (true)\n            static import core.stdc.math;\n        static assert(!__traits(compiles, core.stdc.math.cos(0))); // fails\n    }\n    static assert(!__traits(compiles, cos(0)));\n\n    // mixin statement\n    {\n        if (true)\n            mixin X8937!();\n        static assert(!__traits(compiles, value)); // fails\n    }\n\n    // enum declaration\n    {\n        if (true)\n            enum E { x = 10 }\n        static assert(!__traits(compiles, E)); // fails\n    }\n\n    // conditional declarations\n    {\n        if (true)\n            static if (true) struct S1 {}\n        static assert(!__traits(compiles, S1)); // fails\n\n        if (true)\n            version (all) struct S2 {}\n        static assert(!__traits(compiles, S2)); // fails\n\n        if (true)\n            debug (test) struct S3 {}\n        static assert(!__traits(compiles, S3)); // fails\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test8959.d",
    "content": "/*\nTEST_OUTPUT:\n---\nU1 = int\nU2 = int\nV1 = long, K1 = string\nV2 = long, K2 = string\nTL1 = (int, string)\nTL2 = (int, string)\nU3 = int\nU4 = int\nV3 = long, K3 = string\nV4 = long, K4 = string\nTL3 = (int, string)\nTL4 = (int, string)\n---\n*/\n\nstatic if (is(int* == U1*, U1)) { pragma(msg, \"U1 = \", U1); }\nstatic if (is(int* :  U2*, U2)) { pragma(msg, \"U2 = \", U2); }\nstatic assert(is(int* == U*, U));\nstatic assert(is(int* :  U*, U));\n\nalias AA = long[string];\nstatic if (is(AA == V1[K1], V1, K1)) { pragma(msg, \"V1 = \", V1, \", K1 = \", K1); }\nstatic if (is(AA :  V2[K2], V2, K2)) { pragma(msg, \"V2 = \", V2, \", K2 = \", K2); }\nstatic assert(is(AA == V[K], V, K));\nstatic assert(is(AA :  V[K], V, K));\n\nclass B(TL...) {}\nclass C(TL...) : B!TL {}\nalias X = C!(int, string);\n\nstatic if (is(X == C!TL1, TL1...)) { pragma(msg, \"TL1 = \", TL1); }\nstatic if (is(X :  B!TL2, TL2...)) { pragma(msg, \"TL2 = \", TL2); }\nstatic assert(is(X == C!TL, TL...));\nstatic assert(is(X :  B!TL, TL...));\n\nvoid test8959()\n{\n    static if (is(int* == U3*, U3)) { pragma(msg, \"U3 = \", U3); }\n    static if (is(int* :  U4*, U4)) { pragma(msg, \"U4 = \", U4); }\n    static assert(is(int* == U*, U));\n    static assert(is(int* :  U*, U));\n\n    static if (is(AA == V3[K3], V3, K3)) { pragma(msg, \"V3 = \", V3, \", K3 = \", K3); }\n    static if (is(AA :  V4[K4], V4, K4)) { pragma(msg, \"V4 = \", V4, \", K4 = \", K4); }\n    static assert(is(AA == V[K], V, K));\n    static assert(is(AA :  V[K], V, K));\n\n    static if (is(X == C!TL3, TL3...)) { pragma(msg, \"TL3 = \", TL3); }\n    static if (is(X :  B!TL4, TL4...)) { pragma(msg, \"TL4 = \", TL4); }\n    static assert(is(X == C!TL, TL...));\n    static assert(is(X :  B!TL, TL...));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9057.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -Icompilable/extra-files\n// EXTRA_FILES: extra-files/imp9057.d extra-files/imp9057_2.d\n\nstruct Bug9057(T)\n{\n    T x;\n}\n\nvoid test9507() {\n    import imp9057;\n    Bug9057!(BugInt) xxx;\n}\n\nvoid test9507_2() {\n    import imp9057_2;\n    Bug9057!(BugInt) xxx;\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9209.d",
    "content": "// PERMUTE_ARGS:\n\n// https://issues.dlang.org/show_bug.cgi?id=9209\n\nauto array(T)(T t){ return t; }\n\nauto bar()(in int* x)\n{\n    if (true) return 0;\n    return array(bar(x));\n}\n\nvoid main ()\n{\n    bar(null);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9276.d",
    "content": "// EXTRA_SOURCES: imports/test9276parser.d\n\n\n// This is a dummy module for compilable test\nvoid main()\n{}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9278a.d",
    "content": "// PREMUTE_ARGS:\n\n// Works fine here\nstruct datum { float num = 0.0; }\n\ndatum emitOne()\n{\n    datum t;\n    return t;\n}\nconst dataArr = [emitOne()];\n\n// A very bad day\n//struct datum { float num = 0.0; }\n\nvoid main(){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9278b.d",
    "content": "// PREMUTE_ARGS:\n\n// Works fine here\n//struct datum { float num = 0.0; }\n\ndatum emitOne()\n{\n    datum t;\n    return t;\n}\nconst dataArr = [emitOne()];\n\n// A very bad day\nstruct datum { float num = 0.0; }\n\nvoid main(){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9399.d",
    "content": "// REQUIRED_ARGS: -inline -Icompilable/imports\n// EXTRA_SOURCES: imports/test9399a.d\n\nimport imports.test9399a;\nvoid fun(int a) {\n    void nested() {\n        a = 42;\n    }\n    call!nested();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9434.d",
    "content": "import test9435;//semantic;\n\ntemplate Visitors()\n{\n    mixin Semantic!(typeof(this));\n}\n\nclass Node\n{\n    mixin Visitors;\n}\n\nclass Expression : Node\n{\n}\n\nclass BinaryExp(TokenType op) : Expression\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9435.d",
    "content": "import test9434;//expression;\n\nenum TokenType { Dot }\n\ntemplate Tok(string type)\n{\n    enum Tok = TokenType.Dot;\n}\n\ntemplate Semantic(T)\n{\n    invariant(){}\n}\n\ntemplate Semantic(T) if (is(T == BinaryExp!(Tok!\".\")))\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9436.d",
    "content": "// EXTRA_SOURCES: imports/test9436interp.d\n\n// this is a dummy module for test 9436.\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9526.d",
    "content": "template forward(args...)\n{\n    @property fwd()() { return args[0]; }\n    static assert(__traits(compiles, { auto ex = fwd; }));\n    alias fwd forward;\n}\n\nvoid initializeClassInstance(C, Args...)(C chunk, auto ref Args args)\n{\n    chunk.__ctor(forward!args);\n}\n\nvoid main()\n{\n    static int si = 0;\n    static class C { this(int) { ++si; } }\n    void[__traits(classInstanceSize, C)] buff = void;\n    auto c = cast(C) buff.ptr;\n    initializeClassInstance(c, 0);\n    assert(si);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9554.d",
    "content": "// REQUIRED_ARGS: -o-\n\nmodule pkg.test9554;\nalias mod = pkg.test9554;\n\ntemplate Test(alias name) { enum Test = name; }\nvoid fun() {}\n\nstatic assert(fun.stringof == Test!(fun.stringof));\nstatic assert(fun.stringof == \"fun()\");\nstatic assert(fun.mangleof == Test!(fun.mangleof));\nstatic assert(fun.mangleof == \"_D3pkg8test95543funFZv\");\n\nstatic assert(mod.stringof == Test!(mod.stringof));\nstatic assert(mod.stringof == \"module test9554\");\nstatic assert(mod.mangleof == Test!(mod.mangleof));\nstatic assert(mod.mangleof == \"3pkg8test9554\");\n\nstatic assert(pkg.stringof == Test!(pkg.stringof));\nstatic assert(pkg.stringof == \"package pkg\");\nstatic assert(pkg.mangleof == Test!(pkg.mangleof));\nstatic assert(pkg.mangleof == \"3pkg\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9565.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\ntemplate TypeTuple(T...) { alias TypeTuple = T; }\n\nbool startsWith(string s, string m) { return s[0 .. m.length] == m; }\n\nvoid main()\n{\n    enum string castPrefix = \"cast(\" ~ size_t.stringof ~ \")\";\n\n    // TypeSArray\n    static assert((int[10]).stringof == \"int[10]\", T.stringof);\n\n    int[] arr;\n\n    // IndexExp\n    {\n        // index == IntegerExp\n        static assert((arr[ 4  ]).stringof == \"arr[4]\");\n        static assert((arr[ 4U ]).stringof == \"arr[4]\");\n        static assert((arr[ 4L ]).stringof == \"arr[4]\");\n        static assert((arr[ 4LU]).stringof == \"arr[4]\");\n\n        // index == UAddExp\n        static assert((arr[+4  ]).stringof == \"arr[4]\");\n        static assert((arr[+4U ]).stringof == \"arr[4]\");\n        static assert((arr[+4L ]).stringof == \"arr[4]\");\n        static assert((arr[+4LU]).stringof == \"arr[4]\");\n\n        // index == NegExp\n        static assert((arr[-4  ]).stringof == \"arr[\" ~ castPrefix ~ \"-4]\");\n        static assert((arr[-4U ]).stringof == \"arr[4294967292]\");\n        static assert((arr[int.min] ).stringof == \"arr[\" ~ castPrefix ~ \"-2147483648]\");\n      static if (is(size_t == ulong))\n      {\n        static assert((arr[-4L ]).stringof == \"arr[\" ~ castPrefix ~ \"-4L]\");\n        static assert((arr[-4LU]).stringof == \"arr[-4LU]\");\n\n        // IntegerLiteral needs suffix if the value is greater than long.max\n        static assert((arr[long.max + 0]).stringof == \"arr[9223372036854775807]\");\n        static assert((arr[long.max + 1]).stringof == \"arr[\" ~ castPrefix ~ \"(9223372036854775807L + 1L)]\");\n      }\n\n        foreach (Int; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong))\n        {\n            enum Int p4 = +4;\n            enum string result1 = (arr[p4]).stringof;\n            static assert(result1 == \"arr[4]\");\n\n            enum string result2 = (arr[cast(Int)+4]).stringof;\n            static assert(result2 == \"arr[4]\");\n        }\n        foreach (Int; TypeTuple!(byte, short, int, long))\n        {\n            // keep \"cast(Type)\" in the string representation\n\n            enum Int m4 = -4;\n            static if (is(typeof({ size_t x = m4; })))\n            {\n                enum string result1 = (arr[m4]).stringof;\n                static assert(result1.startsWith(\"arr[\" ~ castPrefix));\n            }\n            else\n                static assert(!__traits(compiles, arr[m4]));\n\n            enum string result2 = (arr[cast(Int)-4]).stringof;\n            static assert(result2.startsWith(\"arr[\" ~ castPrefix));\n        }\n    }\n\n    // SliceExp\n    {\n        // lwr,upr == IntegerExp\n        static assert((arr[4   .. 8  ]).stringof == \"arr[4..8]\");\n        static assert((arr[4U  .. 8U ]).stringof == \"arr[4..8]\");\n        static assert((arr[4L  .. 8L ]).stringof == \"arr[4..8]\");\n        static assert((arr[4LU .. 8LU]).stringof == \"arr[4..8]\");\n\n        // lwr,upr == UAddExp\n        static assert((arr[+4   .. +8  ]).stringof == \"arr[4..8]\");\n        static assert((arr[+4U  .. +8U ]).stringof == \"arr[4..8]\");\n        static assert((arr[+4L  .. +8L ]).stringof == \"arr[4..8]\");\n        static assert((arr[+4LU .. +8LU]).stringof == \"arr[4..8]\");\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9570.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nvoid main()\n{\n    ubyte[256] data;\n\n    foreach (immutable        i; 0..256) data[i] = i;\n    foreach (    const        i; 0..256) data[i] = i;\n    foreach (                 i; 0..256) static assert(!__traits(compiles, (data[i] = i)));\n    foreach (immutable int    i; 0..256) data[i] = i;\n    foreach (    const int    i; 0..256) data[i] = i;\n    foreach (          int    i; 0..256) static assert(!__traits(compiles, (data[i] = i)));\n    foreach (immutable(int)   i; 0..256) data[i] = i;\n    foreach (    const(int)   i; 0..256) data[i] = i;\n    foreach (          int    i; 0..256) static assert(!__traits(compiles, (data[i] = i)));\n    foreach (immutable(ulong) i; 0..256) data[i] = i;\n    foreach (    const(ulong) i; 0..256) data[i] = i;\n    foreach (          ulong  i; 0..256) static assert(!__traits(compiles, (data[i] = i)));\n\n    foreach (immutable        i, x; data) data[i] = i;\n    foreach (    const        i, x; data) data[i] = i;\n    foreach (                 i, x; data) static assert(!__traits(compiles, (data[i] = i)));\n    foreach (immutable int    i, x; data) data[i] = i;\n    foreach (    const int    i, x; data) data[i] = i;\n    foreach (          int    i, x; data) static assert(!__traits(compiles, (data[i] = i)));\n    foreach (immutable(int)   i, x; data) data[i] = i;\n    foreach (    const(int)   i, x; data) data[i] = i;\n    foreach (          int    i, x; data) static assert(!__traits(compiles, (data[i] = i)));\n    foreach (immutable(ulong) i, x; data) data[i] = i;\n    foreach (    const(ulong) i, x; data) data[i] = i;\n    foreach (          ulong  i, x; data) static assert(!__traits(compiles, (data[i] = i)));\n\n    foreach_reverse (immutable        i; 0..256) data[i] = i;\n    foreach_reverse (    const        i; 0..256) data[i] = i;\n    foreach_reverse (                 i; 0..256) static assert(!__traits(compiles, (data[i] = i)));\n    foreach_reverse (immutable int    i; 0..256) data[i] = i;\n    foreach_reverse (    const int    i; 0..256) data[i] = i;\n    foreach_reverse (          int    i; 0..256) static assert(!__traits(compiles, (data[i] = i)));\n    foreach_reverse (immutable(int)   i; 0..256) data[i] = i;\n    foreach_reverse (    const(int)   i; 0..256) data[i] = i;\n    foreach_reverse (          int    i; 0..256) static assert(!__traits(compiles, (data[i] = i)));\n    foreach_reverse (immutable(ulong) i; 0..256) data[i] = i;\n    foreach_reverse (    const(ulong) i; 0..256) data[i] = i;\n    foreach_reverse (          ulong  i; 0..256) static assert(!__traits(compiles, (data[i] = i)));\n\n    foreach_reverse (immutable        i, x; data) data[i] = i;\n    foreach_reverse (    const        i, x; data) data[i] = i;\n    foreach_reverse (                 i, x; data) static assert(!__traits(compiles, (data[i] = i)));\n  //foreach_reverse (immutable int    i, x; data) data[i] = i;\n  //foreach_reverse (    const int    i, x; data) data[i] = i;\n  //foreach_reverse (          int    i, x; data) static assert(!__traits(compiles, (data[i] = i)));\n  //foreach_reverse (immutable(int)   i, x; data) data[i] = i;\n  //foreach_reverse (    const(int)   i, x; data) data[i] = i;\n  //foreach_reverse (          int    i, x; data) static assert(!__traits(compiles, (data[i] = i)));\n    foreach_reverse (immutable(ulong) i, x; data) data[i] = i;\n    foreach_reverse (    const(ulong) i, x; data) data[i] = i;\n    foreach_reverse (          ulong  i, x; data) static assert(!__traits(compiles, (data[i] = i)));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9613.d",
    "content": "// PREMUTE_ARGS:\nstruct S9613\n{\n    int f(\n        const(byte) a = const(byte).init,\n        immutable(byte) b = immutable(byte).init,\n        shared(byte) c = shared(byte).init,\n        inout(byte) d = inout(byte).init,\n    ) inout\n    {\n        assert(a == byte.init);\n        assert(b == byte.init);\n        assert(c == byte.init);\n        assert(d == byte.init);\n        static assert(const(byte).init == byte.init);\n        static assert(immutable(byte).init == byte.init);\n        static assert(shared(byte).init == byte.init);\n        static assert(inout(byte).init == byte.init);\n        return 0;\n    }\n}\n\nvoid main()\n{\n    static assert(const(byte).init == byte.init);\n    static assert(immutable(byte).init == byte.init);\n    static assert(shared(byte).init == byte.init);\n    static assert(const(byte).init.sizeof == byte.sizeof);\n    static assert(const(byte[2]).init[0] == byte.init);\n    enum s = S9613();\n    enum v = s.f();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9639.d",
    "content": "class A { this(A) {} }\nclass B {}\nclass C {}\n\n// two sibling nested functions in main\ntypeof(null) foo(alias fn)(A a) { fn(a); return foo!fn(B.init); }\ntypeof(null) foo(alias fn)(B b) {        return foo!fn(A.init); }\n\n// three sibling nested functions in main\ntypeof(null) bar(alias fn)(A a) { fn(a); return bar!fn(B.init); }\ntypeof(null) bar(alias fn)(B b) {        return bar!fn(C.init); }\ntypeof(null) bar(alias fn)(C c) {        return bar!fn(A.init); }\n\nvoid main()\n{\n    A a;\n    foo!((stuff){ new A(a); })(a);\n    bar!((stuff){ new A(a); })(a);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9672.d",
    "content": "module test9672;            // node\n\nimport imports.test9672a;   // interpret\n\nmixin template ForwardCtor()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9692.d",
    "content": "module test9692;\n\nimport test9692a;\nimport imports.test9692b;\n\nenum x = [__traits(allMembers, imports.test9692b)];  // ok\nenum y = [__traits(allMembers, test9692a)];  // ng: should work\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9692a.d",
    "content": "module test9692a;\nint j;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9701.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=9701\n\ntemplate AliasSeq(TList...)\n{\n    alias AliasSeq = TList;\n}\n\nenum\n{\n    uda4,\n    uda5,\n    uda6,\n    uda8,\n    uda9\n}\n\nenum Enum\n{\n    value0,\n    @(\"uda1\") value1,\n    @(\"uda2\", \"uda3\", 42) value2,\n    @uda4 value3,\n    @uda5 @uda6 value4,\n    @(\"uda7\") @uda8 value5,\n    @uda9 @(\"uda10\") value6,\n    deprecated value7,\n    deprecated(\"message\") value8,\n}\n\n@(\"uda0\")\nenum\n{\n    value0,\n    @(\"uda1\") value1,\n    @(\"uda2\") @(\"uda3\") value2,\n    @uda4 value3,\n    @uda5 @uda6 value4,\n    @(\"uda7\") @uda8 value5,\n    @uda9 @(\"uda10\") value6\n}\n\nstatic assert(__traits(getAttributes, Enum.value0).length == 0);\nstatic assert(__traits(getAttributes, Enum.value1) == AliasSeq!(\"uda1\"));\nstatic assert(__traits(getAttributes, Enum.value2) == AliasSeq!(\"uda2\", \"uda3\", 42));\nstatic assert(__traits(getAttributes, Enum.value3) == AliasSeq!(uda4));\nstatic assert(__traits(getAttributes, Enum.value4) == AliasSeq!(uda5, uda6));\nstatic assert(__traits(getAttributes, Enum.value5) == AliasSeq!(\"uda7\", uda8));\nstatic assert(__traits(getAttributes, Enum.value6) == AliasSeq!(uda9, \"uda10\"));\nstatic assert(__traits(isDeprecated, Enum.value7));\nstatic assert(__traits(isDeprecated, Enum.value8));\n\nstatic assert(__traits(getAttributes, value0) == AliasSeq!(\"uda0\"));\nstatic assert(__traits(getAttributes, value1) == AliasSeq!(\"uda0\", \"uda1\"));\nstatic assert(__traits(getAttributes, value2) == AliasSeq!(\"uda0\", \"uda2\", \"uda3\"));\nstatic assert(__traits(getAttributes, value3) == AliasSeq!(\"uda0\", uda4));\nstatic assert(__traits(getAttributes, value4) == AliasSeq!(\"uda0\", uda5, uda6));\nstatic assert(__traits(getAttributes, value5) == AliasSeq!(\"uda0\", \"uda7\", uda8));\nstatic assert(__traits(getAttributes, value6) == AliasSeq!(\"uda0\", uda9, \"uda10\"));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9766.d",
    "content": "// PERMUTE_ARGS:\n\nsize_t getAlign9766(size_t n) { return n; }\n\nstruct S9766\n{\nalign(getAlign9766(1)):\n    ubyte[5] pad1;\n    ubyte var1;\n\nalign(getAlign9766(2)):\n    ubyte[5] pad2;\n    ubyte var2;\n\nalign(getAlign9766(4)):\n    ubyte[5] pad3;\n    ubyte var3;\n\nalign(getAlign9766(8)):\n    ubyte[5] pad4;\n    ubyte var4;\n}\n\nstatic assert(S9766.pad1.offsetof == 0);\nstatic assert(S9766.var1.offsetof == 5);\n\nstatic assert(S9766.pad2.offsetof == 6);\nstatic assert(S9766.var2.offsetof == 12);\n\nstatic assert(S9766.pad3.offsetof == 16);\nstatic assert(S9766.var3.offsetof == 24);\n\nstatic assert(S9766.pad4.offsetof == 32);\nstatic assert(S9766.var4.offsetof == 40);\n\nunion U9766\n{\n    struct\n    {\n    align(getAlign9766(1)):\n        ubyte[5] pad1;\n        ubyte var1;\n\n    align(getAlign9766(2)):\n        ubyte[5] pad2;\n        ubyte var2;\n\n    align(getAlign9766(4)):\n        ubyte[5] pad3;\n        ubyte var3;\n\n    align(getAlign9766(8)):\n        ubyte[5] pad4;\n        ubyte var4;\n    }\n}\n\nstatic assert(U9766.pad1.offsetof == 0);\nstatic assert(U9766.var1.offsetof == 5);\n\nstatic assert(U9766.pad2.offsetof == 6);\nstatic assert(U9766.var2.offsetof == 12);\n\nstatic assert(U9766.pad3.offsetof == 16);\nstatic assert(U9766.var3.offsetof == 24);\n\nstatic assert(U9766.pad4.offsetof == 32);\nstatic assert(U9766.var4.offsetof == 40);\n\nstruct TestMaxAlign\n{\nalign(1u << 31):\n    ubyte a;\n    ubyte b;\n}\n\nstatic assert(TestMaxAlign.b.offsetof == 2147483648u);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9818.d",
    "content": "/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9818\n\n/*\nTEST_OUTPUT:\n---\nsa1: [1, 1, 1]\nea1: [1, 1, 1]\nsa2: [1, 1, 1]\nea2: [1, 1, 1]\neas: [1, 1, 1]\neac: [1, 1, 1]\nsa3: [1, 1, 1]\nea3: [1, 1, 1]\nsa4: [1, 1, 1]\nea4: [1, 1, 1]\n---\n*/\n\nstatic const int[3] sa1 = 1;\npragma(msg, \"sa1: \", sa1);          // doesn't work\nstatic assert(sa1 == [1, 1, 1]);    // doesn't work\n\nenum int[3] ea1 = 1;\npragma(msg, \"ea1: \", ea1);          // prints \"1\" - bad\nstatic assert(ea1 == [1, 1, 1]);    // doesn't work\n\nstruct X\n{\n    static const int[3] sa2 = 1;\n    pragma(msg, \"sa2: \", sa1);          // doesn't work\n    static assert(sa2 == [1, 1, 1]);    // doesn't work\n\n    enum int[3] ea2 = 1;\n    pragma(msg, \"ea2: \", ea2);          // prints \"1\" - bad\n    static assert(ea2 == [1, 1, 1]);    // doesn't work\n}\n\nstruct S\n{\n    enum int[3] eas = 1;\n}\npragma(msg, \"eas: \", S.eas);\nstatic assert(S.eas == [1, 1, 1]);\nclass C\n{\n    enum int[3] eac = 1;\n}\npragma(msg, \"eac: \", C.eac);\nstatic assert(C.eac == [1, 1, 1]);\n\nvoid test()\n{\n    static const int[3] sa3 = 1;\n    pragma(msg, \"sa3: \", sa3);          // doesn't work\n    static assert(sa3 == [1, 1, 1]);    // doesn't work\n\n    enum int[3] ea3 = 1;\n    pragma(msg, \"ea3: \", ea3);          // prints \"1\" - bad\n    static assert(ea3 == [1, 1, 1]);    // doesn't work\n\n    struct Y\n    {\n        static const int[3] sa4 = 1;\n        pragma(msg, \"sa4: \", sa4);          // doesn't work\n        static assert(sa4 == [1, 1, 1]);    // doesn't work\n\n        enum int[3] ea4 = 1;\n        pragma(msg, \"ea4: \", ea4);          // prints \"1\" - bad\n        static assert(ea4 == [1, 1, 1]);    // doesn't work\n    }\n}\n\n/************************************/\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/test9919.d",
    "content": "// REQUIRED_ARGS: -o-\n\nmodule test9919;\n\npublic\n{\n    import imports.test9919a;\n    import imports.test9919b;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testDIP37.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -Icompilable/extra-files\n// EXTRA_FILES: extra-files/pkgDIP37/datetime/package.d extra-files/pkgDIP37/datetime/common.d extra-files/pkgDIP37/test17629/package.di extra-files/pkgDIP37/test17629/common.di\n\nvoid test1()\n{\n    import pkgDIP37.datetime;\n    def();\n    pkgDIP37.datetime.def();\n    pkgDIP37.datetime.common.def();\n}\n\nvoid test3()\n{\n    import pkgDIP37.datetime.common;\n    def();\n    pkgDIP37.datetime.def();\n    pkgDIP37.datetime.common.def();\n}\n\nvoid test4()\n{\n    import pkgDIP37.datetime : def;\n    def();\n    static assert(!__traits(compiles, pkgDIP37.datetime.def()));\n    static assert(!__traits(compiles, pkgDIP37.datetime.common.def()));\n}\n\nvoid test7()\n{\n    static import pkgDIP37.datetime;\n    static assert(!__traits(compiles, def()));\n    pkgDIP37.datetime.def();\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17629\nvoid test17629()\n{\n    import pkgDIP37.test17629;\n    foo17629();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testDIP37_10302.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -Icompilable/extra-files\n// EXTRA_SOURCES: extra-files/pkgDIP37_10302/liba.d extra-files/pkgDIP37_10302/libb.d\n// EXTRA_FILES: extra-files/pkgDIP37_10302/package.d\n\nmodule test;\nimport pkgDIP37_10302;\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testDIP37_10354.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -o- -Icompilable/extra-files\n// EXTRA_FILES: extra-files/pkgDIP37_10354/mbar.d extra-files/pkgDIP37_10354/mfoo.d extra-files/pkgDIP37_10354/package.d\n\nmodule testDIP37_10354;\nimport pkgDIP37_10354.mfoo;\nvoid main()\n{\n    import pkgDIP37_10354;\n    foo!string();   // OK\n    bar!string();   // OK <- ICE\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testDIP37_10421.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -Icompilable/extra-files\n// COMPILED_IMPORTS: extra-files/pkgDIP37_10421/algo/package.d extra-files/pkgDIP37_10421/algo/mod.d extra-files/pkgDIP37_10421/except.d\n\nmodule testDIP37_10421;\nimport pkgDIP37_10421.algo;\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testDIP37a.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -Icompilable/extra-files\n// COMPILED_IMPORTS: extra-files/pkgDIP37/datetime/package.d\n// COMPILED_IMPORTS: extra-files/pkgDIP37/datetime/common.d\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testDIP42.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\n// enum ident(tpl) = Initializer;\n\nenum isIntegral(T) = is(T == int) || is(T == long);\nstatic assert( isIntegral!int);\nstatic assert( isIntegral!long);\nstatic assert(!isIntegral!double);\nstatic assert(!isIntegral!(int[]));\n\nversion(none)\n{\nenum\n    allSatisfy(alias pred, TL...) =\n        TL.length == 0 || (pred!(TL[0]) && allSatisfy!(pred, TL[1..$])),\n    anySatisfy(alias pred, TL...) =\n        TL.length != 0 && (pred!(TL[0]) || anySatisfy!(pred, TL[1..$])) || false;\nstatic assert( allSatisfy!(isIntegral, int, long));\nstatic assert(!allSatisfy!(isIntegral, int, double));\nstatic assert( anySatisfy!(isIntegral, int, double));\nstatic assert(!anySatisfy!(isIntegral, int[], double));\n}\n\nvoid test1()\n{\n    // statement\n    enum isIntegral2(T) = is(T == int) || is(T == long);\n    static assert(isIntegral2!int);\n}\n\n/******************************************/\n// alias ident(tpl) = Type;\n\nalias TypeTuple(TL...) = TL;\nstatic assert(is(TypeTuple!(int, long)[0] == int));\nstatic assert(is(TypeTuple!(int, long)[1] == long));\n\nalias Id(T) = T, Id(alias A) = A;\nstatic assert(is(Id!int == int));\nstatic assert(__traits(isSame, Id!TypeTuple, TypeTuple));\n\nvoid test2()\n{\n    // statement\n    alias TypeTuple2(TL...) = TL;\n    static assert(is(TypeTuple2!(int, long)[0] == int));\n    static assert(is(TypeTuple2!(int, long)[1] == long));\n\n    alias IdT(T) = T, IdA(alias A) = A;\n    static assert(is(IdT!int == int));\n    static assert(__traits(isSame, IdA!TypeTuple, TypeTuple));\n}\n\n/******************************************/\n// template auto declaration\n\nauto tynameLen(T) = T.stringof.length;\n\nvoid test3()\n{\n    assert(tynameLen!int == 3);\n    assert(tynameLen!long == 4);\n    tynameLen!int = 4;\n    tynameLen!long = 5;\n    assert(tynameLen!int == 4);\n    assert(tynameLen!long == 5);\n\n    // statement\n    auto tynameLen2(T) = T.stringof.length;\n\n    assert(tynameLen2!int == 3);\n    assert(tynameLen2!long == 4);\n    tynameLen2!int = 4;\n    tynameLen2!long = 5;\n    assert(tynameLen2!int == 4);\n    assert(tynameLen2!long == 5);\n}\n\n/******************************************/\n// template variable declaration\n\nstatic T math_pi(T) = cast(T)3.1415;\n\nenum bool isFloatingPoint(T) = is(T == float) || is(T == double);\nstatic assert( isFloatingPoint!double);\nstatic assert(!isFloatingPoint!string);\n\nvoid main()\n{\n    assert(math_pi!int == 3);\n    assert(math_pi!double == 3.1415);\n\n    enum bool isFloatingPoint2(T) = is(T == float) || is(T == double);\n    static assert( isFloatingPoint2!double);\n    static assert(!isFloatingPoint2!string);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testInference.d",
    "content": "\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6265\n\npure nothrow @safe int h6265() {\n    return 1;\n}\nint f6265a(alias g)() {\n    return g();\n}\npure nothrow @safe int i6265a() {\n    return f6265a!h6265();\n}\n\nint f6265b()() {\n    return h6265();\n}\npure nothrow @safe int i6265b() {\n    return f6265b();\n}\n\npure nothrow @safe int i6265c() {\n    return {\n        return h6265();\n    }();\n}\n\n/***************************************************/\n// Make sure a function is not infered as pure if it isn't.\n\nint fNPa() {\n    return 1;\n}\nint gNPa()() {\n    return fNPa();\n}\nstatic assert( __traits(compiles, function int ()         { return gNPa(); }));\nstatic assert(!__traits(compiles, function int () pure    { return gNPa(); }));\nstatic assert(!__traits(compiles, function int () nothrow { return gNPa(); }));\nstatic assert(!__traits(compiles, function int () @safe   { return gNPa(); }));\n\n/***************************************************/\n// Need to ensure the comment in Expression::checkPurity is not violated.\n\nvoid fECPa() {\n    void g()() {\n        void h() {\n        }\n        h();\n    }\n    static assert( is(typeof(&g!()) == void delegate() pure nothrow @nogc @safe));\n    static assert(!is(typeof(&g!()) == void delegate()));\n}\n\nvoid fECPb() {\n    void g()() {\n        void h() {\n        }\n        fECPb();\n    }\n    static assert(!is(typeof(&g!()) == void delegate() pure));\n    static assert( is(typeof(&g!()) == void delegate()));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5635\n\npure bool foo5635(R = int)(string x)\n{\n    bool result = false;\n    foreach (dchar d; x)\n        result = true;\n    return result;\n}\n\nvoid test5635()\n{\n    foo5635(\"hi\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5936\n\nauto bug5936c(R)(R i) @safe pure nothrow {\n    return true;\n}\nstatic assert( bug5936c(0) );\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6351\n\nvoid bug6351(alias dg)()\n{\n    dg();\n}\n\nvoid test6351()\n{\n    void delegate(int[] a...) deleg6351 = (int[] a...){};\n    alias bug6351!(deleg6351) baz6531;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6359\n\nvoid    impure6359()      nothrow @safe @nogc {}\nvoid throwable6359() pure         @safe @nogc {}\nvoid    system6359() pure nothrow       @nogc {}\nvoid    gcable6359() pure nothrow @safe       {}\n\nint global6359;\n\nvoid f6359() pure nothrow @safe @nogc\n{\n    static assert(!__traits(compiles,    impure6359()));\n    static assert(!__traits(compiles, throwable6359()));\n    static assert(!__traits(compiles,    system6359()));\n    static assert(!__traits(compiles,    gcable6359()));\n    static assert(!__traits(compiles,    global6359++));\n\n    static assert(!__traits(compiles, {    impure6359(); }()));\n    static assert(!__traits(compiles, { throwable6359(); }()));\n    static assert(!__traits(compiles, {    system6359(); }()));\n    static assert(!__traits(compiles, {    gcable6359(); }()));\n    static assert(!__traits(compiles, {    global6359++; }()));\n}\n\nvoid g6359()() pure nothrow @safe @nogc\n{\n    static assert(!__traits(compiles,    impure6359()));\n    static assert(!__traits(compiles, throwable6359()));\n    static assert(!__traits(compiles,    system6359()));\n    static assert(!__traits(compiles,    gcable6359()));\n    static assert(!__traits(compiles,    global6359++));\n\n    static assert(!__traits(compiles, {    impure6359(); }()));\n    static assert(!__traits(compiles, { throwable6359(); }()));\n    static assert(!__traits(compiles, {    system6359(); }()));\n    static assert(!__traits(compiles, {    gcable6359(); }()));\n    static assert(!__traits(compiles, {    global6359++; }()));\n}\n\n// attribute inference is not affected by the expressions inside __traits(compiles)\nvoid h6359()()\n{\n    static assert( __traits(compiles,    impure6359()));\n    static assert( __traits(compiles, throwable6359()));\n    static assert( __traits(compiles,    system6359()));\n    static assert( __traits(compiles,    gcable6359()));\n    static assert( __traits(compiles,    global6359++));\n\n    static assert( __traits(compiles, {    impure6359(); }()));\n    static assert( __traits(compiles, { throwable6359(); }()));\n    static assert( __traits(compiles, {    system6359(); }()));\n    static assert( __traits(compiles, {    gcable6359(); }()));\n    static assert( __traits(compiles, {    global6359++; }()));\n}\n\nvoid test6359() pure nothrow @safe @nogc\n{\n    f6359();\n    g6359();\n    h6359();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7017\n\ntemplate map7017(fun...) if (fun.length >= 1)\n{\n    auto map7017()\n    {\n        struct Result {\n            this(int dummy){}   // impure member function -> inferred to pure by fixing issue 10329\n        }\n        return Result(0);   // impure call -> inferred to pure by fixing issue 10329\n    }\n}\n\nint foo7017(immutable int x) pure nothrow { return 1; }\n\nvoid test7017a() pure\n{\n    int bar7017(immutable int x) pure nothrow { return 1; }\n\n    static assert(__traits(compiles, map7017!((){})()));\n    static assert(__traits(compiles, map7017!q{ 1 }()));\n    static assert(__traits(compiles, map7017!foo7017()));\n    static assert(__traits(compiles, map7017!bar7017()));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7017 (little simpler cases)\n\nauto map7017a(alias fun)() { return fun();     }    // depends on purity of fun\nauto map7017b(alias fun)() { return;           }    // always pure\nauto map7017c(alias fun)() { return yyy7017(); }    // always impure\n\nint xxx7017() pure { return 1; }\nint yyy7017() { return 1; }\n\nvoid test7017b() pure\n{\n    static assert( __traits(compiles, map7017a!xxx7017() ));\n    static assert(!__traits(compiles, map7017a!yyy7017() ));\n\n    static assert( __traits(compiles, map7017b!xxx7017() ));\n    static assert( __traits(compiles, map7017b!yyy7017() ));\n\n    static assert(!__traits(compiles, map7017c!xxx7017() ));\n    static assert(!__traits(compiles, map7017c!yyy7017() ));\n}\n\n/***************************************************/\n// Test case from std.process\n\nauto escapeArgumentImpl(alias allocator)()\n{\n    return allocator();\n}\n\nauto escapeShellArgument(alias allocator)()\n{\n    return escapeArgumentImpl!allocator();\n}\n\npure string escapeShellArguments()\n{\n    char[] allocator()\n    {\n        return new char[1];\n    }\n\n    /* Both escape!allocator and escapeImpl!allocator are impure,\n     * but they are nested template function that instantiated here.\n     * Then calling them from here doesn't break purity.\n     */\n    return escapeShellArgument!allocator();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8234\n\nvoid test8234()\n{\n    immutable int x = 0;\n\n    alias FP = typeof({ enum e = x; return e; });\n    static assert(is(FP : int function()));\n\n    auto fp = { enum e = x; return e; };\n    static assert(is(typeof(fp) : int function()));\n\n    alias DG = typeof({ auto e = x; return e; });\n    static assert(is(DG : int delegate()));\n\n    auto dg = { auto e = x; return e; };\n    static assert(is(typeof(dg) : int delegate()));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8504\n\nimport core.demangle : demangle;\n\nvoid foo8504()()\n{\n    static assert(typeof(foo8504!()).stringof == \"void()\");\n    static assert(typeof(foo8504!()).mangleof == \"FZv\");\n    static assert(demangle(foo8504!().mangleof) == \"void testInference.foo8504!().foo8504()\");\n}\n\nauto toDelegate8504a(F)(auto ref F fp) { return fp; }\n   F toDelegate8504b(F)(auto ref F fp) { return fp; }\n\nextern(C) void testC8504() {}\n\nvoid test8504()\n{\n    static assert(typeof(foo8504!()).stringof == \"pure nothrow @nogc @safe void()\");\n    static assert(typeof(foo8504!()).mangleof == \"FNaNbNiNfZv\");\n    static assert(demangle(foo8504!().mangleof) == \"pure nothrow @nogc @safe void testInference.foo8504!().foo8504()\");\n\n    auto fp1 = toDelegate8504a(&testC8504);\n    auto fp2 = toDelegate8504b(&testC8504);\n    static assert(is(typeof(fp1) == typeof(fp2)));\n    static assert(typeof(fp1).stringof == \"extern (C) void function()\");\n    static assert(typeof(fp2).stringof == \"extern (C) void function()\");\n    static assert(typeof(fp1).mangleof == \"PUZv\");\n    static assert(typeof(fp2).mangleof == \"PUZv\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8751\n\nalias bool delegate(in int) pure Bar8751;\nBar8751 foo8751a(immutable int x) pure\n{\n    return y => x > y; // OK\n}\nBar8751 foo8751b(const int x) pure\n{\n    return y => x > y; // error -> OK\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8793\n\nalias bool delegate(in int) pure Dg8793;\nalias bool function(in int) pure Fp8793;\n\nDg8793 foo8793fp1(immutable Fp8793 f) pure { return x => (*f)(x); } // OK\nDg8793 foo8793fp2(    const Fp8793 f) pure { return x => (*f)(x); } // OK\n\nDg8793 foo8793dg1(immutable Dg8793 f) pure { return x => f(x); } // OK\nDg8793 foo8793dg2(    const Dg8793 f) pure { return x => f(x); } // OK <- error\n\nDg8793 foo8793pfp1(immutable Fp8793* f) pure { return x => (*f)(x); } // OK\nDg8793 foo8793pdg1(immutable Dg8793* f) pure { return x => (*f)(x); } // OK\n\nDg8793 foo8793pfp2(const Fp8793* f) pure { return x => (*f)(x); } // OK <- error\nDg8793 foo8793pdg2(const Dg8793* f) pure { return x => (*f)(x); } // OK <- error\n\n// general case for the hasPointer type\nDg8793 foo8793ptr1(immutable int* p) pure { return x => *p == x; } // OK\n\nDg8793 foo8793ptr2(const int* p) pure { return x => *p == x; } // OK <- error\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9072\n\nstruct A9072(T)\n{\n    this(U)(U x) {}\n    ~this() {}\n}\nvoid test9072()\n{\n    A9072!int a = A9072!short();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5933\n// https://issues.dlang.org/show_bug.cgi?id=8504\n// Template attribute inferrence doesn't work\n\nint foo5933()(int a) { return a*a; }\nstruct S5933\n{\n    double foo()(double a) { return a * a; }\n}\n// outside function\nstatic assert(typeof(foo5933!()).stringof == \"pure nothrow @nogc @safe int(int a)\");\nstatic assert(typeof(S5933.init.foo!()).stringof == \"pure nothrow @nogc @safe double(double a)\");\n\nvoid test5933()\n{\n    // inside function\n    static assert(typeof(foo5933!()).stringof == \"pure nothrow @nogc @safe int(int a)\");\n    static assert(typeof(S5933.init.foo!()).stringof == \"pure nothrow @nogc @safe double(double a)\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9148\n\nvoid test9148a() pure\n{\n    static int g;\n    int x;\n\n    void foo1() /+pure+/\n    {\n        static assert(!__traits(compiles, g++));\n        x++;\n    }\n    void foo2() pure\n    {\n        static assert(!__traits(compiles, g++));\n        x++;\n    }\n    foo1();\n    static assert(is(typeof(&foo1) == void delegate() pure nothrow @nogc @safe));\n    foo2();\n    static assert(is(typeof(&foo2) == void delegate() pure nothrow @nogc @safe));\n\n    void bar1() immutable /+pure+/\n    {\n        static assert(!__traits(compiles, g++));\n        static assert(!__traits(compiles, x++));\n    }\n    void bar2() immutable pure\n    {\n        static assert(!__traits(compiles, g++));\n        static assert(!__traits(compiles, x++));\n    }\n    bar1();\n    static assert(is(typeof(&bar1) == void delegate() pure immutable nothrow @nogc @safe));\n    bar2();\n    static assert(is(typeof(&bar2) == void delegate() pure immutable nothrow @nogc @safe));\n\n    struct S\n    {\n        void foo1() /+pure+/\n        {\n            static assert(!__traits(compiles, g++));\n            x++;\n        }\n        void foo2() pure\n        {\n            static assert(!__traits(compiles, g++));\n            x++;\n        }\n        void bar1() immutable /+pure+/\n        {\n            static assert(!__traits(compiles, g++));\n            static assert(!__traits(compiles, x++));\n        }\n        void bar2() immutable pure\n        {\n            static assert(!__traits(compiles, g++));\n            static assert(!__traits(compiles, x++));\n        }\n    }\n\n    S sm;\n    sm.foo1();\n    static assert(is(typeof(&sm.foo1) == void delegate() pure));\n    sm.foo2();\n    static assert(is(typeof(&sm.foo2) == void delegate() pure));\n\n    immutable S si;\n    si.bar1();\n    static assert(is(typeof(&si.bar1) == void delegate() pure immutable));\n    si.bar2();\n    static assert(is(typeof(&si.bar2) == void delegate() pure immutable));\n}\n\n// ----\n// inheritance of pure and @safe\n\nvoid test9148b() pure nothrow @nogc @safe\n{\n    void nf() {}\n    static assert(is(typeof(&nf) == void delegate() pure nothrow @nogc @safe));\n\n    struct NS\n    {\n        void mf() {}\n        static void sf() {}\n    }\n    NS ns;\n    static assert(is(typeof(&ns.mf) == void delegate() pure nothrow @nogc @safe));\n    static assert(is(typeof(&NS.sf) == void function() pure nothrow @nogc @safe));\n\n    static void sf() {}\n    static assert(is(typeof(&sf) == void function() pure nothrow @nogc @safe));\n\n    static struct SS\n    {\n        void mf() {}\n        static void sf() {}\n    }\n    SS ss;\n    static assert(is(typeof(&ss.mf) == void delegate() pure nothrow @nogc @safe));\n    static assert(is(typeof(&SS.sf) == void function() pure nothrow @nogc @safe));\n}\n\nvoid impureSystem9148b() {}\nvoid func9148b()()\n{\n    void bar()  // do not inherit PUREfwdref\n    {\n        static assert(is(typeof(&bar) == void delegate()));\n        impureSystem9148b();\n    }\n    static assert(is(typeof(&bar) == void delegate()));\n}\nstatic assert(is(typeof(&func9148b!()) == void function() pure nothrow @nogc @safe));\n\n// ----\n// from fail_compilation/fail283.d\n\npure int double_sqr9148c(int x)\n{\n    int y = x;\n    void do_sqr() pure { y *= y; }\n    do_sqr();\n    return y;\n}\n\nvoid test9148c()\n{\n    assert(double_sqr9148c(10) == 100);\n}\n\n// ----\n// from fail_compilation/fail348.d\n\nvoid test9148d() pure\n{\n    void g()    // implicitly marked as 'pure'\n    {\n        void h() pure\n        {\n            // i() and j() are implicitly marked as 'pure'\n            void i() { }\n            void j() { i(); g(); }  // can call i() and g()\n        }\n    }\n}\n\nvoid test9148e()\n{\n    int x;\n    static assert(is(typeof((int a){ return a + x; }) == int delegate(int) pure nothrow @nogc @safe));\n\n    auto dg = (int a){ return a + x; };\n    static assert(is(typeof(dg) == int delegate(int) pure nothrow @nogc @safe));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12912\n\nstruct S12912(alias fun)\n{\n    void f() { fun(); }\n}\n\nclass C12912\n{\n    int n;\n\n    void f() pure\n    {\n        S12912!(() => n) s;\n        // Here lambda should be inferred to weak purity.\n\n        s.f();\n        // And this call will be a pure member function call.\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10002\n\nvoid impure10002() {}\nvoid remove10002(alias pred, bool impure = false, Range)(Range range)\n{\n    pred(range[0]);\n    static if (impure) impure10002();\n}\nclass Node10002\n{\n    Node10002 parent;\n    Node10002[] children;\n\n    void foo() pure\n    {\n        parent.children.remove10002!(n => n is parent)();\n        remove10002!(n => n is parent)(parent.children);\n        static assert(!__traits(compiles, parent.children.remove10002x!(n => n is parent, true)()));\n        static assert(!__traits(compiles, remove10002x!(n => n is parent, true)(parent.children)));\n\n        Node10002 p;\n        p.children.remove10002!(n => n is p)();\n        remove10002!(n => n is p)(p.children);\n        static assert(!__traits(compiles, p.children.remove10002x!(n => n is p, true)()));\n        static assert(!__traits(compiles, remove10002x!(n => n is p, true)(p.children)));\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10148\n\nvoid fa10148() {}  // fa is @system\n\nauto fb10148(T)()\n{\n    struct A(S)\n    {\n        // [4] Parent function fb is already inferred to @safe, then\n        // fc is forcely marked @safe on default until 2.052.\n        // But fc should keep attribute inference ability\n        // by overriding the inherited @safe-ty from its parent.\n        void fc(T2)()\n        {\n            // [5] During semantic3 process, fc is not @safe on default.\n            static assert(is(typeof(&fc) == void delegate()));\n            fa10148();\n        }\n        // [1] this is now inferred to @safe by implementing issue 7511\n        this(S a) {}\n    }\n\n    // [2] A!int(0) is now calling @safe function, then fb!T also be inferred to @safe\n    return A!int(0);\n}\n\nvoid test10148()\n{\n    fb10148!int.fc!int;  // [0] instantiate fb\n                         // [3] instantiate fc\n\n    // [6] After semantic3 done, fc!int is deduced to @system.\n    static assert(is(typeof(&fb10148!int.fc!int) == void delegate() @system));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10289\n\nvoid test10289()\n{\n    void foo(E)()\n    {\n        throw new E(\"\");\n    }\n    void bar(E1, E2)()\n    {\n        throw new E1(\"\");\n        throw new E2(\"\");\n    }\n    void baz(E1, E2)(bool cond)\n    {\n        if (cond)\n            throw new E1(\"\");\n        else\n            throw new E2(\"\");\n    }\n\n    import core.exception;\n    static class MyException : Exception\n    {\n        this(string) @safe pure nothrow { super(\"\"); }\n    }\n\n    static assert( __traits(compiles, () nothrow { foo!Error(); }));\n    static assert( __traits(compiles, () nothrow { foo!AssertError(); }));\n\n    static assert(!__traits(compiles, () nothrow { foo!Exception(); }));\n    static assert(!__traits(compiles, () nothrow { foo!MyException(); }));\n\n    static assert( __traits(compiles, () nothrow { bar!(Error, Exception)(); }));\n    static assert(!__traits(compiles, () nothrow { bar!(Exception, Error)(); }));\n\n    static assert(!__traits(compiles, () nothrow { baz!(Error, Exception)(); }));\n    static assert(!__traits(compiles, () nothrow { baz!(Exception, Error)(); }));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10296\n\nvoid foo10296()()\n{\n    int[3] a;\n\n    void bar()() { a[1] = 2; }\n    bar();\n    pragma(msg, typeof(bar!()));    // nothrow @safe void()\n}\npure void test10296()\n{\n    foo10296();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12025\n\nstruct Foo12025\n{\n    int[5] bar;\n}\n\nvoid test12025a() pure\n{\n    enum n1 = typeof(Foo12025.bar).length;  // OK\n    enum n2 =        Foo12025.bar .length;  // OK <- error\n\n    auto x1 = typeof(Foo12025.bar).length;  // OK\n    auto x2 =        Foo12025.bar .length;  // OK <- error\n}\n\nvoid test12025b() pure\n{\n    static int[5] bar;\n\n    enum n1 = typeof(bar).length;  // OK\n    enum n2 =        bar .length;  // OK <- error\n\n    auto x1 = typeof(bar).length;  // OK\n    auto x2 =        bar .length;  // OK <- error\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12542\n\nint logOf12542(T)(T n)\n{\n    if (n)\n        return 1 + logOf12542(n/2);\n    return 0;\n}\n\nvoid test12542() @safe nothrow pure\n{\n    int log = logOf12542(9);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12704\n\nvoid foo12704() @system;\nalias FP12704 = typeof(function() { foo12704(); });\nstatic assert(is(FP12704 == void function() @system));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12970\n\n@system { @safe void f12970a() {} }\n@system { void f12970b() @safe {} }\nstatic assert(is(typeof(&f12970a) == void function() @safe));\nstatic assert(is(typeof(&f12970b) == void function() @safe));\n\n@system { @trusted void f12970c() {} }\n@system { void f12970d() @trusted {} }\nstatic assert(is(typeof(&f12970c) == void function() @trusted));\nstatic assert(is(typeof(&f12970d) == void function() @trusted));\n\n@safe { @system void f12970e() {} }\n@safe { void f12970f() @system {} }\nstatic assert(is(typeof(&f12970e) == void function() @system));\nstatic assert(is(typeof(&f12970f) == void function() @system));\n\n@safe { @trusted void f12970g() {} }\n@safe { void f12970h() @trusted {} }\nstatic assert(is(typeof(&f12970g) == void function() @trusted));\nstatic assert(is(typeof(&f12970h) == void function() @trusted));\n\n@trusted { @safe void f12970i() {} }\n@trusted { void f12970j() @safe {} }\nstatic assert(is(typeof(&f12970i) == void function() @safe));\nstatic assert(is(typeof(&f12970j) == void function() @safe));\n\n@trusted { @system void f12970k() {} }\n@trusted { void f12970l() @system {} }\nstatic assert(is(typeof(&f12970k) == void function() @system));\nstatic assert(is(typeof(&f12970l) == void function() @system));\n\n/***************************************************/\n// Parsing prefix STC_FUNCATTR for variable declaration\n\n__gshared immutable pure nothrow @property @nogc @safe void function() prefix_qualified_fp1;\n__gshared{immutable{pure{nothrow{@property{@nogc{@safe{void function() prefix_qualified_fp2;}}}}}}}\nstatic assert(typeof(prefix_qualified_fp1).stringof == typeof(prefix_qualified_fp2).stringof);\nstatic assert(typeof(prefix_qualified_fp1).stringof\n        == \"immutable(void function() pure nothrow @nogc @property @safe)\");\n\nconst pure nothrow @property @nogc @safe void function()[] prefix_qualified_fp_array1;\nconst{pure{nothrow{@property{@nogc{@safe{void function()[] prefix_qualified_fp_array2;}}}}}}\nstatic assert(typeof(prefix_qualified_fp_array1).stringof == typeof(prefix_qualified_fp_array2).stringof);\nstatic assert(typeof(prefix_qualified_fp_array1).stringof\n        == \"const(void function() pure nothrow @nogc @property @safe[])\");\n\n/***************************************************/\n// Parsing prefix, intermediate, or postfix @safe for alias declaration\n\n@safe alias void function() AliasDecl_FP1;\nalias @safe void function() AliasDecl_FP2;    // is not @safe\nalias void function() @safe AliasDecl_FP3;\nstatic assert(AliasDecl_FP1.stringof == \"void function() @safe\");\nstatic assert(AliasDecl_FP2.stringof == \"void function()\");\nstatic assert(AliasDecl_FP3.stringof == \"void function() @safe\");\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13217\n\nvoid writeln13217(string) {}\n\nnothrow void a13217(T)(T x)\n{\n    try\n    {\n        () { writeln13217(\"a\"); } ();\n    }\n    catch (Exception e) {}\n}\n\nvoid test13217()\n{\n    a13217(1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13840\n\nstruct Foo13840\n{\n    int opApply(int delegate(int))\n    {\n        return 0;\n    }\n}\n\nvoid func13840()\n{\n}\n\nvoid test13840() nothrow\n{\n    try\n    {\n        foreach (i; Foo13840()) // generated delegate is throwable\n        {\n            func13840();        // throwable function call\n        }\n    }\n    catch(Throwable)\n    {}\n}\n\n// Add more tests regarding inferences later.\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testVRP.d",
    "content": "// PERMUTE_ARGS: -O -inline\n\n// Test value-range propagation.\n// https://issues.dlang.org/show_bug.cgi?id=3147\n// https://issues.dlang.org/show_bug.cgi?id=6000\n// https://issues.dlang.org/show_bug.cgi?id=5225\n\nvoid add()\n{\n    byte x, y;\n    short a = x + y;\n}\n\nvoid leftShift()\n{\n    byte x, y;\n    short z = x << 1;\n}\n\nvoid leftShiftFail()\n{\n    ubyte x, y;\n    ushort z;\n    static assert(!__traits(compiles, z = x << y));\n    // 1 << 31 surely overflows the range of 'ushort'.\n}\n\nvoid rightShiftFail()\n{\n    short x;\n    byte y, z;\n    static assert(!__traits(compiles, z = x >> y));\n    // [this passes in 2.053.]\n}\n\nvoid rightShift()\n{\n    ushort x;\n    ubyte y = x >> 16;\n}\n\nvoid unsignedRightShiftFail()\n{\n    int x;\n    ubyte y;\n    static assert(!__traits(compiles, y = x >>> 2));\n    // [this passes in 2.053.]\n}\n\nvoid subtract()\n{\n    ubyte x, y;\n    short z = x - y;\n}\n\nvoid multiply()\n{\n    byte x, y;\n    short z = x * y;\n}\n\nvoid subMulFail()\n{\n    ubyte x, y;\n    ubyte z;\n    static assert(!__traits(compiles, z = x - y));\n    static assert(!__traits(compiles, z = x * y));\n    // [these pass in 2.053.]\n}\n\nvoid multiplyNeg1()\n{\n    byte b;\n    b = -1 + (b * -1);\n    static assert(!__traits(compiles, b = -1 + b * ulong.max));\n}\n\nvoid divide()\n{\n    short w;\n    byte y = w / 300;\n}\n\nvoid divideFail()\n{\n    short w;\n    byte y;\n    static assert(!__traits(compiles, y = w / -1));\n}\n\nvoid plus1Fail()\n{\n    byte u, v;\n    static assert(!__traits(compiles, v = u + 1));\n    // [these pass in 2.053.]\n}\n\nvoid modulus()\n{\n    int x;\n    byte u = x % 128;\n}\n\nvoid modulus_bug6000a()\n{\n    ulong t;\n    uint u = t % 16;\n}\n\nvoid modulus_bug6000b()\n{\n    long n = 10520;\n    ubyte b;\n    static assert(!__traits(compiles, b = n % 10));\n}\n\nvoid modulus2()\n{\n    short s;\n    byte b = byte.max;\n    byte c = s % b;\n}\n\nvoid modulus3()\n{\n    int i;\n    short s = short.max;\n    short t = i % s;\n}\n\nvoid modulus4()\n{\n    uint i;\n    ushort s;\n    short t;\n    static assert(!__traits(compiles, t = i % s));\n}\n\nvoid modulus5()\n{\n    short a;\n    byte foo = (a - short.max - 1) % 127;\n}\n\nvoid modulusFail()\n{\n    int i;\n    short s;\n    byte b;\n    static assert(!__traits(compiles, b = i % s));\n    static assert(!__traits(compiles, b = i % 257));\n    // [these pass in 2.053.]\n}\n\nvoid bitwise()\n{\n    ubyte a, b, c;\n    uint d;\n    c = a & b;\n    c = a | b;\n    c = a ^ b;\n    c = d & 0xff;\n    // [these pass in 2.053.]\n}\n\nvoid bitAnd()\n{\n    byte c;\n    int d;\n    c = (0x3ff_ffffU << (0&c)) & (0x4000_0000U << (0&c));\n    // the result of the above is always 0 :).\n}\n\nvoid bitAndTest()\n{\n    ushort a, b;\n    byte res = ((a % 7) - 6) & ((b % 7) - 6);\n}\n\nvoid bitOrFail()\n{\n    ubyte c;\n    static assert(!__traits(compiles, c = c | 0x100));\n    // [this passes in 2.053.]\n}\n\nvoid bitAndOr()\n{\n    ubyte c;\n    c = (c | 0x1000) & ~0x1000;\n}\n\nvoid bitOrTest()\n{\n    // Tests condition for different signs between min & max\n    // ((imin.negative ^ imax.negative) == 1 && (rhs.imin.negative ^ rhs.imax.negative) == 1\n    ushort a, b;\n    byte res = ((a % 127) - 126) | ((b % 6) - 5);\n}\n\nvoid bitAndFail()\n{\n    int d;\n    short s;\n    byte c;\n    static assert(!__traits(compiles, c = d & s));\n    static assert(!__traits(compiles, c = d & 256));\n    // [these pass in 2.053.]\n}\n\nvoid bitXor()\n{\n    ushort s;\n    ubyte c;\n    c = (0xffff << (s & 0)) ^ 0xff00;\n}\n\nvoid bitComplement()\n{\n    int i;\n    ubyte b = ~(i | ~0xff);\n}\n\nvoid bitComplementFail()\n{\n    ubyte b;\n    static assert(!__traits(compiles, b = ~(b | 1)));\n    // [this passes in 2.053.]\n}\n\nvoid negation()\n{\n    int x;\n    byte b = -(x & 0x7);\n}\n\nvoid negationFail()\n{\n    int x;\n    byte b;\n    static assert(!__traits(compiles, b = -(x & 255)));\n    // [this passes in 2.053.]\n}\n\nshort bug5225(short a) {\n    return a>>1;\n}\n\nshort bug1977_comment5(byte i) {\n  byte t = 1;\n  short o = t - i;\n  return o;\n}\n\nvoid testDchar()\n{\n    dchar d;\n    uint i;\n    /+\n    static assert(!__traits(compiles, d = i));\n    static assert(!__traits(compiles, d = i & 0x1fffff));\n    +/\n    d = i % 0x110000;\n}\n\nvoid bug1977_comment11()\n{\n    uint a;\n    byte b = a & 1;\n    // [this passes in 2.053.]\n}\n\nvoid bug1977_comment20()\n{\n    long a;\n    int b = a % 1000;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9617\n\nvoid test9617()\n{\n    void f1(int) {}\n    void f2(short) {}\n    void f3(byte) {}\n\n    // Why these calls are accepted?\n    static assert(!__traits(compiles, f1(ulong.max)));\n    static assert(!__traits(compiles, f2(ulong.max)));\n    static assert(!__traits(compiles, f3(ulong.max)));\n\n    // But, if argument is not constant value, compilation fails.\n    ulong x;\n    static assert(!__traits(compiles, f1(x)));  // is not callable using argument types (ulong)\n    static assert(!__traits(compiles, f2(x)));  // is not callable using argument types (ulong)\n    static assert(!__traits(compiles, f3(x)));  // is not callable using argument types (ulong)\n\n    void f4(uint) {}\n    void f5(ushort) {}\n    void f6(ubyte) {}\n\n    // If parameter type is unsigned, it is collectly rejected\n    static assert(!__traits(compiles, f4(ulong.max)));  // is not callable using argument types (ulong)\n    static assert(!__traits(compiles, f5(ulong.max)));  // is not callable using argument types (ulong)\n    static assert(!__traits(compiles, f6(ulong.max)));  // is not callable using argument types (ulong)\n}\n\n//import std.typetuple;\ntemplate TypeTuple(T...) { alias TypeTuple = T; }\ntemplate staticIota(size_t end)\n{\n    static if (0 < end)\n        alias staticIota = TypeTuple!(staticIota!(end - 1), end - 1);\n    else\n        alias staticIota = TypeTuple!();\n}\nvoid test9617a()\n{\n    alias Repr = TypeTuple!(\n        byte,   \"127\",      // T and literal representation of T.max\n        ubyte,  \"255\",\n        short,  \"32767\",\n        ushort, \"65535\",\n        int,    \"2147483647\",\n        uint,   \"4294967295\",\n        long,   \"9223372036854775807\",\n        ulong,  \"18446744073709551615\"  // \"\" or \"L\" -> \"signed integral overflow\"\n    );\n    alias Indices = staticIota!(Repr.length / 2);\n\n    foreach (t; Indices)\n    {\n        alias T = Repr[t * 2];\n        void func(T)(T) {}\n        alias func!T f;\n\n        foreach (r; Indices)\n        {\n            alias S = Repr[r * 2];\n            S src = S.max;\n\n            enum x = Repr[r * 2 + 1];\n            foreach (repr; TypeTuple!(S.stringof~\".max\", x~\"\", x~\"U\", x~\"L\", x~\"LU\"))\n            {\n                static if (S.sizeof != T.sizeof)\n                static if (is(typeof(mixin(repr)) R))\n                {\n                    // \"Compilable\" test should be equal, even if\n                    // the given argument is either constant or runtime variable.\n                    enum ct = __traits(compiles, f( mixin(repr) ));\n                    enum rt = __traits(compiles, f( src ));\n\n                    static assert(ct == rt);\n                    //import std.string;\n                    //enum msg = format(\"%6s.max to %-6s variable/constant = %d/%d, constant_repr = (%s) %s\",\n                    //                    S.stringof, T.stringof, rt, ct, R.stringof, repr);\n                    //static if (ct != rt) pragma(msg, msg);\n                }\n            }\n        }\n    }\n}\n\nvoid test10018(ubyte value)\n{\n    const int c = value;\n    ubyte b = c;\n    static assert(!__traits(compiles, b = c - 1));\n    static assert(!__traits(compiles, b = c + 1));\n    immutable int i = value;\n    b = i;\n    static assert(!__traits(compiles, b = i - 1));\n    static assert(!__traits(compiles, b = i + 1));\n}\n\nvoid test13001(bool unknown)\n{\n    foreach (const i; 0..unknown?2:3)\n    {\n        ubyte b = i;\n        static assert(!__traits(compiles, b = i - 1));\n        b = i + 253;\n        static assert(!__traits(compiles, b = i + 254));\n    }\n}\n\nvoid test10310()\n{\n    int y;\n    ubyte x = ((y & 252) ^ 2) + 1;\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=15289\nvoid test15289a()\n{\n    int [] arr = [1, 2, 3, 4];\n    uint foo = 50 / arr.length;\n}\n\nvoid test15289b()\n{\n    int [] arr = [1, 2, 3, 4];\n    uint foo = 50 % arr.length;\n}\n\nvoid testShiftRightOnNegative()\n{\n    int neg = -1;\n    uint[] arr = [1, 2, 3];\n    ubyte b;\n    // Shift with negative value returns value in range [0, ulong.max]\n    static assert(!__traits(compiles, b = arr.length >> neg));\n    static assert(!__traits(compiles, b = arr.length << neg));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testcheckimports.d",
    "content": "// REQUIRED_ARGS: -transition=checkimports -de\n/*\nTEST_OUTPUT:\n---\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=15825\n\ntemplate anySatisfy15825(T...)\n{\n    alias anySatisfy15825 = T[$ - 1];\n}\n\nalias T15825 = anySatisfy15825!(int);\n\n// https://issues.dlang.org/show_bug.cgi?id=15857\n\ntemplate Mix15857(T)\n{\n    void foo15857(T) {}\n}\nmixin Mix15857!int;\nmixin Mix15857!string;\n\n// will find an overloadset on 2nd lookup w/ SearchImportsOnly set\nimport imports.test15857a;\n\nvoid test15857()\n{\n    foo15857(1);\n    bar15857(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testcontracts.d",
    "content": "// EXTRA_SOURCES: imports/testcontracts.d\n\nimport imports.testcontracts;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3602\n\nclass Derived3602 : Base3602\n{\n   override void method(int x, int y)\n   in\n   {\n       assert(x > 0);\n       assert(y > 0);\n   }\n   body\n   {\n   }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5230\n\nclass Derived5230 : Base5230\n{\n    override int method()\n    {\n        return 69;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17502\nclass Foo17502\n{\n    auto foo()\n    out {}\n    body {}\n\n    auto bar()\n    out { assert (__result > 5); }\n    body { return 6; }\n\n    auto bar_2()\n    out (res) { assert (res > 5); }\n    body { return 6; }\n\n    int concrete()\n    out { assert(__result > 5); }\n    body { return 6; }\n\n    int concrete_2()\n    out(res) { assert (res > 5); }\n    body { return 6; }\n\n    void void_foo()\n    out {}\n    body {}\n\n    auto void_auto()\n    out {}\n    body {}\n}\n\n/***************************************************/\n// Order of declaration: (A), (C : B), (B : A)\n\nclass A17502\n{\n    int method(int p)\n    in\n    {\n        assert(p > 5);\n    }\n    out(res)\n    {\n        assert(res > 5);\n    }\n    body\n    {\n        return p;\n    }\n}\n\nclass C17502 : B17502\n{\n    override int method(int p)\n    in\n    {\n        assert(p > 3);\n    }\n    body\n    {\n        return p * 2;\n    }\n}\n\nclass B17502 : A17502\n{\n    override int method(int p)\n    in\n    {\n        assert(p > 2);\n    }\n    body\n    {\n        return p * 3;\n    }\n}\n\n/***************************************************/\n// Order of declaration: (X : Y), (Y : Z), (Z)\n\nclass X17502 : Y17502\n{\n    override int method(int p)\n    in\n    {\n        assert(p > 3);\n    }\n    body\n    {\n        return p * 2;\n    }\n}\n\nclass Y17502 : Z17502\n{\n    override int method(int p)\n    in\n    {\n        assert(p > 2);\n    }\n    body\n    {\n        return p * 3;\n    }\n}\n\nclass Z17502\n{\n    int method(int p)\n    in\n    {\n        assert(p > 5);\n    }\n    out(res)\n    {\n        assert(res > 5);\n    }\n    body\n    {\n        return p;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17893\n\nfinal class Foo17893(T)\n{\n    extern(C) void maythrow();\n\n    void bar()\n    in\n    {\n        maythrow();\n    }\n    body\n    {\n    }\n}\n\nFoo17893!int foo17893;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testdip1008.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -dip1008\n\nint bar()\n{\n    try\n    {\n\tthrow new Exception(\"message\");\n    }\n    catch (Exception e)\n    {\n\treturn 7;\n    }\n}\n\n\nvoid foo()\n{\n    enum r = bar();\n    static assert(r == 7);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testexpression.d",
    "content": "\ntemplate TT(T...) { alias T TT; }\n\nvoid TestOpAssign(Tx, Ux, ops)()\n{\n    foreach(T; Tx.x)\n    foreach(U; Ux.x)\n    foreach(op; ops.x)\n    {\n        T a = cast(T)1;\n        mixin(\"a \" ~ op ~ \" cast(U)1;\");\n    }\n}\n\nvoid TestOpAssignAssign(Tx, Ux, ops)()\n{\n    foreach(T; Tx.x)\n    foreach(U; Ux.x)\n    foreach(op; ops.x)\n    {\n        T a = cast(T)1;\n        U b = cast(U)1;\n        T r;\n        mixin(\"r = a \" ~ op ~ \" cast(U)1;\");\n    }\n}\n\nvoid TestOpAssignAuto(Tx, Ux, ops)()\n{\n    foreach(T; Tx.x)\n    foreach(U; Ux.x)\n    static if (U.sizeof <= T.sizeof)\n    foreach(op; ops.x)\n    {\n        T a = cast(T)1;\n        U b = cast(U)1;\n        mixin(\"auto r = a \" ~ op ~ \" cast(U)1;\");\n    }\n}\n\nvoid TestOpAndAssign(Tx, Ux, ops)()\n{\n    foreach(T; Tx.x)\n    foreach(U; Ux.x)\n    static if (U.sizeof <= T.sizeof && T.sizeof >= 4)\n    foreach(op; ops.x)\n    {\n        T a = cast(T)1;\n        U b = cast(U)1;\n        mixin(\"a = a \" ~ op[0..$-1] ~ \" cast(U)1;\");\n    }\n}\n\nstruct boolean   { alias TT!(bool) x; }\nstruct integral  { alias TT!(byte, ubyte, short, ushort, int, uint, long, ulong) x; }\nstruct floating  { alias TT!(float, double, real) x; }\nstruct imaginary { alias TT!(ifloat, idouble, ireal) x; }\nstruct complex   { alias TT!(cfloat, cdouble, creal) x; }\n\nstruct all       { alias TT!(\"+=\", \"-=\", \"*=\", \"/=\", \"%=\", \"&=\", \"|=\", \"^=\", \"<<=\", \">>=\", \">>>=\") x; }\nstruct arith     { alias TT!(\"+=\", \"-=\", \"*=\", \"/=\", \"%=\") x; }\nstruct bitwise   { alias TT!(\"&=\", \"|=\", \"^=\") x; }\nstruct shift     { alias TT!(\"<<=\", \">>=\", \">>>=\") x; }\nstruct addsub    { alias TT!(\"+=\", \"-=\") x; }\nstruct muldivmod { alias TT!(\"*=\", \"/=\", \"%=\") x; }\nstruct nomod     { alias TT!(\"+=\", \"-=\", \"*=\", \"/=\") x; }\n\nvoid OpAssignCases(alias X)()\n{\n    X!(boolean, boolean, bitwise)();\n\n    X!(integral, boolean, all)();\n    X!(integral, integral, all)();\n    X!(integral, floating, arith)();\n\n    X!(floating, boolean, arith)();\n    X!(floating, integral, arith)();\n    X!(floating, floating, arith)();\n\n    X!(imaginary, boolean, muldivmod)();\n    X!(imaginary, integral, muldivmod)();\n    X!(imaginary, floating, muldivmod)();\n    X!(imaginary, imaginary, addsub)();\n\n    X!(complex, boolean, arith)();\n    X!(complex, integral, arith)();\n    X!(complex, floating, arith)();\n    X!(complex, imaginary, arith)();\n    X!(complex, complex, nomod)();\n}\n\nvoid OpReAssignCases(alias X)()\n{\n    X!(boolean, boolean, bitwise)();\n\n    X!(integral, boolean, all)();\n    X!(integral, integral, all)();\n\n    X!(floating, boolean, arith)();\n    X!(floating, integral, arith)();\n    X!(floating, floating, arith)();\n\n    X!(imaginary, boolean, muldivmod)();\n    X!(imaginary, integral, muldivmod)();\n    X!(imaginary, floating, muldivmod)();\n    X!(imaginary, imaginary, addsub)();\n\n    X!(complex, boolean, arith)();\n    X!(complex, integral, arith)();\n    X!(complex, floating, arith)();\n    X!(complex, imaginary, arith)();\n    X!(complex, complex, nomod)();\n}\n\nvoid main()\n{\n    OpAssignCases!TestOpAssign();\n    OpAssignCases!TestOpAssignAssign(); // was once disabled due to bug 7436\n    OpAssignCases!TestOpAssignAuto(); // https://issues.dlang.org/show_bug.cgi?id=5181\n    OpReAssignCases!TestOpAndAssign();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testfptr.d",
    "content": "// PERMUTE_ARGS:\n\nref int frvv();\nclass A {}\nclass B : A {}\n\nB restrictedfunc(in const(int)) @safe pure nothrow;\nA relaxedfunc(in int);\n\nvoid bug3797()\n{\n    // Cannot convert if the return type or parameters are different\n\n    void function() vv;\n    void function(int) vi;\n    int function() iv;\n    const(int) function() cv;\n    immutable(int) function() xv;\n\n    static assert( is(typeof( vv = vv )));\n    static assert(!is(typeof( vv = vi )));\n    static assert(!is(typeof( vv = iv )));\n    static assert(!is(typeof( vv = cv )));\n    static assert(!is(typeof( vv = xv )));\n\n    static assert(!is(typeof( vi = vv )));\n    static assert( is(typeof( vi = vi )));\n    static assert(!is(typeof( vi = iv )));\n    static assert(!is(typeof( vi = cv )));\n    static assert(!is(typeof( vi = cx )));\n\n    static assert(!is(typeof( iv = vv )));\n    static assert(!is(typeof( iv = vi )));\n    static assert( is(typeof( iv = iv )));\n    static assert( is(typeof( iv = cv )));\n    static assert( is(typeof( iv = xv )));\n\n    static assert(!is(typeof( cv = vv )));\n    static assert( is(typeof( cv = iv )));\n    static assert(!is(typeof( cv = vi )));\n    static assert( is(typeof( cv = cv )));\n    static assert( is(typeof( cv = xv )));\n\n    static assert(!is(typeof( xv = vv )));\n    static assert( is(typeof( xv = iv )));\n    static assert(!is(typeof( xv = vi )));\n    static assert( is(typeof( xv = cv )));\n    static assert( is(typeof( xv = xv )));\n\n    int* function() ipfunc;\n    const(int*) function() cipfunc;\n\n    static assert( is(typeof( cipfunc = ipfunc )) );\n    static assert(!is(typeof( ipfunc = cipfunc )) );\n\n    // functions with different linkages can't convert\n\n    extern(C) void function() cfunc;\n    extern(D) void function() dfunc;\n\n    static assert(!is(typeof( cfunc = dfunc )));\n    static assert(!is(typeof( dfunc = cfunc )));\n\n    // ref return can't convert to non-ref return\n\n    typeof(&frvv) rvv;\n\n    static assert(!is(typeof( rvv = iv )));\n    static assert(!is(typeof( rvv = cv )));\n\n    static assert(!is(typeof( iv = rvv )));\n    static assert(!is(typeof( cv = rvv )));\n\n    // variadic functions don't mix\n\n    void function(...) vf;\n\n    static assert(!is(typeof( vf = vv )));\n    static assert(!is(typeof( vv = vf )));\n\n    // non-nothrow -> nothrow\n\n    void function() nothrow ntf;\n\n    static assert(!is(typeof( ntf = vv )));\n    static assert( is(typeof( vv = ntf )));\n\n    // @safe <-> @trusted -> @system\n\n    void function() @system systemfunc;\n    void function() @trusted trustedfunc;\n    void function() @safe safefunc;\n\n    static assert( is(typeof( trustedfunc = safefunc )));\n    static assert( is(typeof( systemfunc = trustedfunc )));\n    static assert( is(typeof( systemfunc = safefunc )));\n    static assert( is(typeof( safefunc = trustedfunc )));\n\n    static assert(!is(typeof( trustedfunc = systemfunc )));\n    static assert(!is(typeof( safefunc = systemfunc )));\n\n    // pure -> non-pure\n\n    void function() nonpurefunc;\n    void function() pure purefunc;\n\n    static assert(!is(typeof( purefunc = nonpurefunc )));\n    static assert( is(typeof( nonpurefunc = purefunc )));\n\n    // Cannot convert parameter storage classes (except const to in and in to const)\n\n    void function(const(int)) constfunc;\n    void function(in int) infunc;\n    void function(out int) outfunc;\n    void function(ref int) reffunc;\n    void function(lazy int) lazyfunc;\n\n    static assert(is(typeof( infunc = constfunc )));\n    static assert(is(typeof( constfunc = infunc )));\n\n    static assert(!is(typeof( infunc = outfunc )));\n    static assert(!is(typeof( infunc = reffunc )));\n    static assert(!is(typeof( infunc = lazyfunc )));\n\n    static assert(!is(typeof( outfunc = infunc )));\n    static assert(!is(typeof( outfunc = reffunc )));\n    static assert(!is(typeof( outfunc = lazyfunc )));\n\n    static assert(!is(typeof( reffunc = infunc )));\n    static assert(!is(typeof( reffunc = outfunc )));\n    static assert(!is(typeof( reffunc = lazyfunc )));\n\n    static assert(!is(typeof( lazyfunc = infunc )));\n    static assert(!is(typeof( lazyfunc = outfunc )));\n    static assert(!is(typeof( lazyfunc = reffunc )));\n\n    // Test class covariance\n\n    A function() afunc;\n    B function() bfunc;\n\n    static assert( is(typeof( afunc = bfunc )));\n    static assert(!is(typeof( bfunc = afunc )));\n\n    // Test all the conversions at once\n    typeof(&restrictedfunc) prestrictedfunc;\n    typeof(&relaxedfunc) prelaxedfunc = prestrictedfunc;\n}\n\nvoid bug3797dg()\n{\n    ref int frvv() { return *(new int); }\n    B restrictedfunc(in const(int)) @safe pure nothrow { return null; }\n    A relaxedfunc(in int) { return null; }\n    // Cannot convert if the return type or parameters are different\n\n    void delegate() vv;\n    void delegate(int) vi;\n    int delegate() iv;\n    const(int) delegate() cv;\n    immutable(int) delegate() xv;\n\n    static assert( is(typeof( vv = vv )));\n    static assert(!is(typeof( vv = vi )));\n    static assert(!is(typeof( vv = iv )));\n    static assert(!is(typeof( vv = cv )));\n    static assert(!is(typeof( vv = xv )));\n\n    static assert(!is(typeof( vi = vv )));\n    static assert( is(typeof( vi = vi )));\n    static assert(!is(typeof( vi = iv )));\n    static assert(!is(typeof( vi = cv )));\n    static assert(!is(typeof( vi = cx )));\n\n    static assert(!is(typeof( iv = vv )));\n    static assert(!is(typeof( iv = vi )));\n    static assert( is(typeof( iv = iv )));\n    static assert( is(typeof( iv = cv )));\n    static assert( is(typeof( iv = xv )));\n\n    static assert(!is(typeof( cv = vv )));\n    static assert( is(typeof( cv = iv )));\n    static assert(!is(typeof( cv = vi )));\n    static assert( is(typeof( cv = cv )));\n    static assert( is(typeof( cv = xv )));\n\n    static assert(!is(typeof( xv = vv )));\n    static assert( is(typeof( xv = iv )));\n    static assert(!is(typeof( xv = vi )));\n    static assert( is(typeof( xv = cv )));\n    static assert( is(typeof( xv = xv )));\n\n    int* delegate() ipfunc;\n    const(int*) delegate() cipfunc;\n\n    static assert( is(typeof( cipfunc = ipfunc )) );\n    static assert(!is(typeof( ipfunc = cipfunc )) );\n\n    // delegates with different linkages can't convert\n\n    extern(C) void delegate() cfunc;\n    extern(D) void delegate() dfunc;\n\n    static assert(!is(typeof( cfunc = dfunc )));\n    static assert(!is(typeof( dfunc = cfunc )));\n\n    // ref return can't convert to non-ref return\n\n    typeof(&frvv) rvv;\n\n    static assert(!is(typeof( rvv = iv )));\n    static assert(!is(typeof( rvv = cv )));\n\n    static assert(!is(typeof( iv = rvv )));\n    static assert(!is(typeof( cv = rvv )));\n\n    // variadic delegates don't mix\n\n    void delegate(...) vf;\n\n    static assert(!is(typeof( vf = vv )));\n    static assert(!is(typeof( vv = vf )));\n\n    // non-nothrow -> nothrow\n\n    void delegate() nothrow ntf;\n\n    static assert(!is(typeof( ntf = vv )));\n    static assert( is(typeof( vv = ntf )));\n\n    // @safe <-> @trusted -> @system\n\n    void delegate() @system systemfunc;\n    void delegate() @trusted trustedfunc;\n    void delegate() @safe safefunc;\n\n    static assert( is(typeof( trustedfunc = safefunc )));\n    static assert( is(typeof( systemfunc = trustedfunc )));\n    static assert( is(typeof( systemfunc = safefunc )));\n    static assert( is(typeof( safefunc = trustedfunc )));\n\n    static assert(!is(typeof( trustedfunc = systemfunc )));\n    static assert(!is(typeof( safefunc = systemfunc )));\n\n    // pure -> non-pure\n\n    void delegate() nonpurefunc;\n    void delegate() pure purefunc;\n\n    static assert(!is(typeof( purefunc = nonpurefunc )));\n    static assert( is(typeof( nonpurefunc = purefunc )));\n\n    // Cannot convert parameter storage classes (except const to in and in to const)\n\n    void delegate(const(int)) constfunc;\n    void delegate(in int) infunc;\n    void delegate(out int) outfunc;\n    void delegate(ref int) reffunc;\n    void delegate(lazy int) lazyfunc;\n\n    static assert(is(typeof( infunc = constfunc )));\n    static assert(is(typeof( constfunc = infunc )));\n\n    static assert(!is(typeof( infunc = outfunc )));\n    static assert(!is(typeof( infunc = reffunc )));\n    static assert(!is(typeof( infunc = lazyfunc )));\n\n    static assert(!is(typeof( outfunc = infunc )));\n    static assert(!is(typeof( outfunc = reffunc )));\n    static assert(!is(typeof( outfunc = lazyfunc )));\n\n    static assert(!is(typeof( reffunc = infunc )));\n    static assert(!is(typeof( reffunc = outfunc )));\n    static assert(!is(typeof( reffunc = lazyfunc )));\n\n    static assert(!is(typeof( lazyfunc = infunc )));\n    static assert(!is(typeof( lazyfunc = outfunc )));\n    static assert(!is(typeof( lazyfunc = reffunc )));\n\n    // Test class covariance\n\n    A delegate() afunc;\n    B delegate() bfunc;\n\n    static assert( is(typeof( afunc = bfunc )));\n    static assert(!is(typeof( bfunc = afunc )));\n\n    // Test all the conversions at once\n    typeof(&restrictedfunc) prestrictedfunc;\n    typeof(&relaxedfunc) prelaxedfunc = prestrictedfunc;\n}\n\nvoid bug3268()\n{\n    auto a = &bug3268;\n    const b = a;\n    assert(a == a);\n    assert(a == b);\n    assert(b == b);\n    immutable c = cast(immutable)a;\n    assert(a == c);\n    assert(b == c);\n    assert(c == c);\n\n    static assert(is(typeof(*a) == typeof(*b)));\n    static assert(is(typeof(*a) == typeof(*c)));\n}\n\nvoid bug3268dg()\n{\n    void bug3268x() {}\n    auto a = &bug3268x;\n    const b = a;\n    assert(a == a);\n    assert(a == b);\n    assert(b == b);\n    immutable c = cast(immutable)a;\n    assert(a == c);\n    assert(b == c);\n    assert(c == c);\n}\n\nvoid bug3833()\n{\n    bool b;\n\n    void function() func;\n    void function() pure purefunc;\n    void function() nothrow nothrowfunc;\n    void function() @safe safefunc;\n    void function() @trusted trustedfunc;\n\n    static assert( is(typeof( b ? func : purefunc )     == typeof( func )));\n    static assert( is(typeof( b ? func : nothrowfunc )  == typeof( func )));\n    static assert( is(typeof( b ? func : safefunc )     == typeof( func )));\n    static assert( is(typeof( b ? func : trustedfunc )  == typeof( func )));\n\n    static assert( is(typeof( b ? purefunc : nothrowfunc )  == typeof( func )));\n    static assert( is(typeof( b ? purefunc : safefunc )     == typeof( func )));\n    static assert( is(typeof( b ? purefunc : trustedfunc )  == typeof( func )));\n\n    static assert( is(typeof( b ? nothrowfunc : safefunc )      == typeof( func )));\n    static assert( is(typeof( b ? nothrowfunc : trustedfunc )   == typeof( func )));\n\n    static assert( is(typeof( b ? safefunc : trustedfunc )      == typeof( trustedfunc )));\n\n    auto arr = [func, purefunc, nothrowfunc, safefunc, trustedfunc];\n\n    static assert( is(typeof( arr ) == typeof(func)[]) );\n}\n\nvoid bug3833dg()\n{\n    bool b;\n\n    void delegate() func;\n    void delegate() pure purefunc;\n    void delegate() nothrow nothrowfunc;\n    void delegate() @safe safefunc;\n    void delegate() @trusted trustedfunc;\n\n    static assert( is(typeof( b ? func : purefunc )     == typeof( func )));\n    static assert( is(typeof( b ? func : nothrowfunc )  == typeof( func )));\n    static assert( is(typeof( b ? func : safefunc )     == typeof( func )));\n    static assert( is(typeof( b ? func : trustedfunc )  == typeof( func )));\n\n    static assert( is(typeof( b ? purefunc : nothrowfunc )  == typeof( func )));\n    static assert( is(typeof( b ? purefunc : safefunc )     == typeof( func )));\n    static assert( is(typeof( b ? purefunc : trustedfunc )  == typeof( func )));\n\n    static assert( is(typeof( b ? nothrowfunc : safefunc )      == typeof( func )));\n    static assert( is(typeof( b ? nothrowfunc : trustedfunc )   == typeof( func )));\n\n    static assert( is(typeof( b ? safefunc : trustedfunc )      == typeof( trustedfunc )));\n\n    auto arr = [func, purefunc, nothrowfunc, safefunc, trustedfunc];\n\n    static assert( is(typeof( arr ) == typeof(func)[]) );\n}\n\nvoid bug4838()\n{\n    void delegate() const dgc;\n    static assert(typeof(dgc).stringof == \"void delegate() const\");\n\n    void delegate() immutable dgi;\n    static assert(typeof(dgi).stringof == \"void delegate() immutable\");\n\n    void delegate() shared dgs;\n    static assert(typeof(dgs).stringof == \"void delegate() shared\");\n\n    void delegate() shared const dgsc;\n    static assert(typeof(dgsc).stringof == \"void delegate() shared const\");\n\n    void delegate() inout dgw;\n    static assert(typeof(dgw).stringof == \"void delegate() inout\");\n\n    void delegate() shared inout dgsw;\n    static assert(typeof(dgsw).stringof == \"void delegate() shared inout\");\n}\n\nvoid test8822()\n{\n    struct S { void foo() const {} }\n    S s;\n    void delegate() const dg = &s.foo;      // OK\n\n    void foo(void delegate() const dg){}    // OK\n\n    struct Foo(T) {}\n    alias Foo!(void delegate() const) X;    // NG -> OK\n}\n\nvoid main()\n{\n    static assert(is(typeof(&main) P : U*, U));\n    auto x = cast(void*)&main;\n\n    const void * p = &main;\n\n    __gshared void function() gp = null;\n    __gshared void delegate() gp2 = null;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testfwdref.d",
    "content": "// PERMUTE_ARGS:\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6766\n\nclass Foo6766\n{\n    this(int x) { }\n    void test(Foo6766 foo = new Foo6766(1)) { }\n}\n\nstruct Bar6766\n{\n    this(int x) { }\n    void test(Bar6766 bar = Bar6766(1)) { }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8609\n\nstruct Tuple8609(T)\n{\n    T arg;\n}\n\n// ----\n\nstruct Foo8609a\n{\n    Bar8609a b;\n}\nstruct Bar8609a\n{\n    int x;\n    Tuple8609!(Foo8609a) spam() { return Tuple8609!(Foo8609a)(); }\n}\n\n// ----\n\nstruct Foo8609b\n{\n    Bar8609b b;\n}\nstruct Bar8609b\n{\n    int x;\n    Tuple8609!(Foo8609b[1]) spam() { return Tuple8609!(Foo8609b[1])(); }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8698\n\ninterface IRoot8698a {}\ninterface IClass8698a : IRoot8698a { }\nstruct Struct8698a { }\nclass Class8698a : IClass8698a { alias Struct8698a Value; }\nvoid test8698a(Class8698a.Value) { }\n//interface IRoot8698a {}\n\n// ----\n\n//interface IRoot8698b {}\ninterface IClass8698b : IRoot8698b { }\nstruct Struct8698b { }\nclass Class8698b : IClass8698b { alias Struct8698b Value; }\nvoid test8698b(Class8698b.Value) { }\ninterface IRoot8698b {}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9514\n\ntemplate TStructHelpers9514a()\n{\n    void opEquals(Foo9514a)\n    {\n        auto n = FieldNames9514a!();\n    }\n}\n\nstruct Foo9514a\n{\n    mixin TStructHelpers9514a!();\n}\n\nimport imports.fwdref9514 : find9514;  // selective import without aliasing\n\ntemplate FieldNames9514a()\n{\n    static if (find9514!`true`([1])) enum int FieldNames9514a = 1;\n}\n\n// ----\n\ntemplate TStructHelpers9514b()\n{\n    void opEquals(Foo9514b)\n    {\n        auto n = FieldNames9514b!();\n    }\n}\n\nstruct Foo9514b\n{\n    mixin TStructHelpers9514b!();\n}\n\nimport imports.fwdref9514 : foo9514 = find9514;  // selective import with aliasing\n\ntemplate FieldNames9514b()\n{\n    static if (foo9514!`true`([1])) enum int FieldNames9514b = 1;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10015\n\nstruct S10015(T) { alias X = int; }\n\nalias Y10015 = s10015.X;\nS10015!int s10015;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10101\n\nint front10101(int);\n\nmixin template reflectRange10101()\n{\n    static if (is(typeof(this.front10101)))\n    {\n        int x;\n    }\n}\n\nstruct S10101(R)\n{\n    R r_;\n\n    typeof(r_.front10101) front10101() @property { return r_.front10101; }\n\n    mixin reflectRange10101;\n}\n\nvoid test10101()\n{\n    S10101!(int) s;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11019\n\nclass A11019\n{\n    A11019 View() { return null; }\n}\n\nclass B11019 : A11019\n{\n    override D11019 View() { return null; }\n}\n\nclass D11019 : B11019 {}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11166\n\ntemplate Tup11166(T...) { alias Tup11166 = T; }\n\nstruct S11166a\n{\n    enum S11166a a = S11166a(0);\n    enum S11166a b = S11166a(1);\n\n    this(long value) { }\n\n    long value;\n\n    // only triggered when private and a template instance.\n    private alias types = Tup11166!(a, b);\n}\n\nstruct S11166b\n{\n    enum S11166b a = S11166b(0);\n    enum S11166b b = S11166b(1);\n\n    // not at the last of members\n    alias types = Tup11166!(a, b);\n\n    this(long value) { }\n\n    long value;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12152\n\nclass A12152\n{\n    alias Y = B12152.X;\n}\n\nclass B12152 : A12152\n{\n    alias int X;\n}\n\nstatic assert(is(A12152.Y == int));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12201\n\ntemplate T12201()\n{\n    alias imports.fwdref12201a.FILE* FP;\n}\n\nstruct S12201a\n{\n    mixin T12201;\n    import imports.fwdref12201a;\n}\n\nunion U12201\n{\n    mixin T12201;\n    import imports.fwdref12201a;\n}\n\nclass C12201\n{\n    mixin T12201;\n    import imports.fwdref12201a;\n}\n\ninterface I12201\n{\n    mixin T12201;\n    import imports.fwdref12201a;\n}\n\n\ntemplate TI12201()\n{\n    mixin T12201;\n    import imports.fwdref12201a;\n}\nmixin template TM12201()\n{\n    mixin T12201;\n    import imports.fwdref12201a;\n}\nstruct S12201b\n{\n    alias ti = TI12201!();\n\n    mixin TM12201;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12531\n\nstruct Node12531(T)\n{\n    T _val;\n}\n\nvoid test12531()\n{\n    static struct Foo\n    {\n        Node12531!Foo* node;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12543\n\nclass C12543;\nstatic assert(C12543.sizeof == (void*).sizeof);\nstatic assert(C12543.alignof == (void*).sizeof);\nstatic assert(C12543.mangleof == \"C10testfwdref6C12543\");\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14010\n\nenum E14010;\nstatic assert(E14010.mangleof == \"E10testfwdref6E14010\");\n\nstruct S14010;\nstatic assert(S14010.mangleof == \"S10testfwdref6S14010\");\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12983\n\nalias I12983 = int;\nclass B12983(T) { alias MyC = C12983!string; }\n\nclass C12983(T) : B12983!float\n{\n    void m() { f12983(0); }\n}\n\nalias MyB12983 = B12983!float;\n\nvoid f12983();\nvoid f12983(I12983);\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12984\n\nclass B12984a { alias MyD = D12984a!int; }\nclass C12984a : B12984a { }\n\nclass D12984a(T) { alias MyE = E12984a!float; }\nclass E12984a(T) : D12984a!int\n{\n    void m()\n    {\n        auto c = new C12984a();\n    }\n}\n\nstatic assert(__traits(classInstanceSize, B12984a) == (void*).sizeof * 2);\nstatic assert(__traits(classInstanceSize, C12984a) == (void*).sizeof * 2);\n\n// ----\n\nclass B12984b { int b; alias MyD = D12984b!int; }\nclass C12984b : B12984b { int c; }\n\nclass D12984b(T) { int d; alias MyE = E12984b!float; }\nclass E12984b(T) : D12984b!int\n{\n    int e;\n    void m()\n    {\n        auto c = new C12984b();\n    }\n}\n\nstatic assert(__traits(classInstanceSize, B12984b) == (void*).sizeof * 2 + int.sizeof);\nstatic assert(__traits(classInstanceSize, C12984b) == (void*).sizeof * 2 + int.sizeof * 2);\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14390\n\nclass B14390a { alias MyD = D14390a!int; }\nclass C14390a : B14390a { void f(int) {} }\nclass D14390a(T) { alias MyE = E14390a!float; }\nclass E14390a(T) : D14390a!int { void m() { auto c = new C14390a(); } }\n\nclass B14390b { alias MyD = D14390b!int; }\nclass C14390b : B14390b { static struct S {} }\nclass D14390b(T) { alias MyE = E14390b!float; }\nclass E14390b(T) : D14390b!int { void m() { auto c = new C14390b(); } }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13860\n\n/*\nTEST_OUTPUT:\n---\npure nothrow @nogc @safe void()\npure nothrow @nogc @safe void()\n---\n*/\n\nstruct Foo13860(Bar...)\n{\n    Bar bars;\n    auto baz(size_t d)() {}\n    pragma(msg, typeof(baz!0));\n}\n\nauto bar13860(S, R)(S s, R r)\n{\n    pragma(msg, typeof(Foo13860!().baz!0));\n}\n\nvoid test13860()\n{\n    int[] x;\n    int[] y;\n    x.bar13860(y);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14083\n\nclass NBase14083\n{\n    int foo(NA14083 a) { return 1; }\n    int foo(NB14083 a) { return 2; }\n}\nclass NA14083 : NBase14083\n{\n    int v;\n    this(int v) { this.v = v; }\n}\nclass NB14083 : NBase14083\n{\n    override int foo(NA14083 a) { return a.v; }\n}\n\nclass TBase14083(T)\n{\n    int foo(TA14083!T a) { return 1; }\n    int foo(TB14083!T a) { return 2; }\n}\nclass TA14083(T) : TBase14083!T\n{\n    T v;\n    this(T v) { this.v = v; }\n}\nclass TB14083(T) : TBase14083!T\n{\n    override int foo(TA14083!T a) { return a.v; }\n}\n\nstatic assert(\n{\n    NA14083 na = new NA14083(10);\n    NB14083 nb = new NB14083();\n    assert(na.foo(na) == 1);\n    assert(na.foo(nb) == 2);\n    assert(nb.foo(na) == 10);\n\n    TA14083!int ta = new TA14083!int(10);\n    TB14083!int tb = new TB14083!int();\n    assert(ta.foo(ta) == 1);\n    assert(ta.foo(tb) == 2);\n    assert(tb.foo(ta) == 10);\n\n    return true;\n}());\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14549\n\nstring foo14549(T)()\n{\n    static if (T.tupleof.length >= 0)\n        return \"\";\n}\n\nclass Frop14549\n{\n    mixin(foo14549!(typeof(this)));\n\n    static if (__traits(compiles, undefined))\n    {\n    }\n    else\n    {\n        int bar = 0;\n    }\n\n    static if (!__traits(isVirtualMethod, this.bar)) {}\n}\n\n// ----\n// regression case\n\ntemplate Mix14549()\n{\n    mixin(code14549!(typeof(this)));\n}\n\ntemplate code14549(T)\n{\n    enum string code14549 =\n        q{ static if (!__traits(isVirtualMethod, \"boo\")) {} };\n}\n\nclass Bar14549\n{\n    mixin Mix14549;\n    int boo;\n}\n\n// ----\n// https://issues.dlang.org/show_bug.cgi?id=14609\n// regression case\n\ninterface Foo14609(T)\n{\n    static if (is(T == int))\n        public int bar();\n}\nclass Frop14609 : Foo14609!int\n{\n    public int bar() { return 0; }\n}\n\n/***************************************************/\n// test case 1, comes from Phobos\n/*\nTEST_OUTPUT:\n---\n+alias Alias12540\n+anySatisfy, T.length == 1\n+isStaticArray\n+T.stringof in StaticArrayTypeOf\n-T.stringof in StaticArrayTypeOf\n-isStaticArray\n+hasElaborateCpCtor S == struct or else\n-hasElaborateCpCtor S == struct or else\n-anySatisfy, T.length == 1\n-alias Alias12540\n---\n*/\n\ntemplate anySatisfy15726x(alias F, T...)\n{\n    //static if (T.length == 1)\n    //{\n        pragma(msg, \"+anySatisfy, T.length == 1\");\n        enum anySatisfy15726x = F!(T[0]);\n        pragma(msg, \"-anySatisfy, T.length == 1\");\n    //}\n}\n\ntemplate StaticArrayTypeOf15726x(T)\n{\n    alias X = T;\n\n    static if (is(X : E[n], E, size_t n))\n    {\n        //alias StaticArrayTypeOf15726x = X;\n    }\n    else\n    {\n        pragma(msg, \"+T.stringof in StaticArrayTypeOf\");\n        // Fixed: T.stringof (T == Class12540) should not invoke\n        //        T.size() in ClassDeclaration.search().\n        static assert(0, T.stringof~\" is not a static array type\");\n        pragma(msg, \"-T.stringof in StaticArrayTypeOf\");\n    }\n}\n\n//enum bool isStaticArray(T) = is(StaticArrayTypeOf15726x!T);\ntemplate isStaticArray15726x(T)\n{\n    pragma(msg, \"+isStaticArray\");\n    enum bool isStaticArray15726x = is(StaticArrayTypeOf15726x!T);\n    pragma(msg, \"-isStaticArray\");\n}\n\ntemplate hasElaborateCpCtor15726x(S)\n{\n    static if (isStaticArray15726x!S && S.length)\n    {\n        //pragma(msg, \"X+\");\n        enum bool hasElaborateCpCtor15726x =\n            hasElaborateCpCtor15726x!(typeof(S.init[0]));\n        //pragma(msg, \"X-\");\n    }\n    else\n    {\n        pragma(msg, \"+hasElaborateCpCtor S == struct or else\");\n        static if (is(S == struct))\n        {\n            enum bool hasElaborateCpCtor15726x = true;\n            //enum hasElaborateCpCtor15726x = hasMember!(S, \"__postblit\")\n            //    || anySatisfy15726x!(.hasElaborateCpCtor15726x, FieldTypeTuple!S);\n        }\n        else\n        {\n            enum bool hasElaborateCpCtor15726x = false;\n        }\n        pragma(msg, \"-hasElaborateCpCtor S == struct or else\");\n    }\n}\n\nstruct VariantN15726x(AllowedTypesParam...)\n{\n    alias AllowedTypes = AllowedTypesParam;\n\n    static if (!AllowedTypes.length ||\n               anySatisfy15726x!(hasElaborateCpCtor15726x, AllowedTypes))\n    {\n    }\n}\n\ntemplate Algebraic15726x(T)\n{\n    alias Algebraic15726x = VariantN15726x!(T);\n}\n\nvoid test15726x()\n{\n    static struct DummyScope\n    {\n        pragma(msg, \"+alias Alias12540\");\n        alias Alias12540 = Algebraic15726x!Class12540;\n        pragma(msg, \"-alias Alias12540\");\n        static class Class12540\n        {\n            Alias12540 entity;\n        }\n    }\n}\n\n/***************************************************/\n// test case 2, comes from Phobos\n\nstruct RefCounted15726y(T)\n{\n    struct RefCountedStore\n    {\n        struct Impl\n        {\n            T _payload;\n        }\n        Impl* _store;\n    }\n    RefCountedStore _refCounted;\n\n    this(this) {}\n\n    ~this()\n    {\n        _refCounted._store._payload.__xdtor();\n    }\n}\n\nstruct RangeT15726y(A)\n{\n    A[1] _outer_;\n    alias RC = RangeT15726y!(const(A));\n}\n\nstruct Array15726y(T)\n{\n    struct Payload\n    {\n        ~this();\n    }\n\n    alias Data = RefCounted15726y!(Payload);\n    Data _data;\n\n    alias Range = RangeT15726y!Array15726y;\n}\n\nvoid test15726y()\n{\n    alias Range = RangeT15726y!(Array15726y!int);\n    Range r;\n    r = r;  // opAssign\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15726\n\nstruct RC15726(T)\n{\n    struct Impl\n    {\n        T _payload;\n    }\n\n    Impl* _store;\n\n    ~this()\n    {\n        destroy15726a(_store._payload);\n    }\n}\n\n// ----\n\nstruct Con15726a(T)\n{\n    alias Stmt15726a = .Stmt15726a!T;\n}\n\nstruct Stmt15726a(T)\n{\n    alias Con15726a = .Con15726a!T;\n\n    RC15726!Payload data;\n\n    struct Payload\n    {\n        Con15726a con;\n    }\n}\n\nCon15726a!int x15726a;\n\nvoid destroy15726a(T)(ref T obj) @trusted\n{\n    auto buf = (cast(ubyte*)&obj)[0 .. T.sizeof];\n}\n\n// ----\n\nstruct Util15726b(C, S) {}\n\nstruct Con15726b(T)\n{\n    alias Util15726b = .Util15726b!(Con15726b!T, Stmt15726b!T);\n}\n\nstruct Stmt15726b(T)\n{\n    struct Payload\n    {\n        Con15726b!T con;\n    }\n\n    RC15726!Payload data;\n}\n\nCon15726b!int x15726b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testheader1.d",
    "content": "// EXTRA_SOURCES: extra-files/header1.d\n// REQUIRED_ARGS: -o- -unittest -H -Hf${RESULTS_DIR}/compilable/testheader1.di -ignore\n// PERMUTE_ARGS: -d -dw\n// POST_SCRIPT: compilable/extra-files/header-postscript.sh\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testheader12567a.d",
    "content": "// REQUIRED_ARGS: -o- -H -Hf${RESULTS_DIR}/compilable/testheader12567a.di\n// PERMUTE_ARGS:\n// POST_SCRIPT: compilable/extra-files/header-postscript.sh\n\ndeprecated module header12567a;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testheader12567b.d",
    "content": "// REQUIRED_ARGS: -o- -H -Hf${RESULTS_DIR}/compilable/testheader12567b.di\n// PERMUTE_ARGS:\n// POST_SCRIPT: compilable/extra-files/header-postscript.sh\n\ndeprecated(\"message\") module header12567b;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testheader1i.d",
    "content": "// EXTRA_SOURCES: extra-files/header1.d\n// REQUIRED_ARGS: -o- -H -Hf${RESULTS_DIR}/compilable/testheader1i.di -inline -ignore\n// PERMUTE_ARGS: -d -dw\n// POST_SCRIPT: compilable/extra-files/header-postscript.sh\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testheader2.d",
    "content": "// EXTRA_SOURCES: extra-files/header2.d\n// REQUIRED_ARGS: -o- -H -Hf${RESULTS_DIR}/compilable/testheader2.di\n// PERMUTE_ARGS:\n// POST_SCRIPT: compilable/extra-files/header-postscript.sh\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testheader2i.d",
    "content": "// EXTRA_SOURCES: extra-files/header2.d\n// REQUIRED_ARGS: -o- -H -Hf${RESULTS_DIR}/compilable/testheader2i.di -inline\n// PERMUTE_ARGS:\n// POST_SCRIPT: compilable/extra-files/header-postscript.sh\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testheader3.d",
    "content": "// EXTRA_SOURCES: extra-files/header3.d\n// REQUIRED_ARGS: -o- -unittest -H -Hf${RESULTS_DIR}/compilable/testheader3.di\n// PERMUTE_ARGS: -d -dw\n// POST_SCRIPT: compilable/extra-files/header-postscript.sh\n\nvoid main() {}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testheaderudamodule.d",
    "content": "// REQUIRED_ARGS: -o- -H -Hf${RESULTS_DIR}/compilable/testheaderudamodule.di\n// PERMUTE_ARGS:\n// POST_SCRIPT: compilable/extra-files/header-postscript.sh\n\n@(1, UDA(2))\nmodule testheaderudamodule;\n\nstruct UDA\n{\n    int a;\n}\n\nvoid main() {}\n\nvoid foo(@(1) int bar, @UDA(2) string bebe) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testimport12242.d",
    "content": "// PERMUTE_ARGS:\n\nmodule testimport12242;\n\nimport imports.imp12242a;   // test         // stripA == OverloadSet\nimport imports.imp12242a1;  // std.string   // stripA == template\n\nimport imports.imp12242b1;  // std.string   // stripB == template\nimport imports.imp12242b;   // test         // stripB == OverloadSet\n\nvoid main()\n{\n    static assert(stripA(\" af \") == 1);\n    static assert(\" af \".stripA() == 1);    // UFCS (1)\n    static assert(\" af \".stripA == 1);      // UFCS (2)\n\n    static assert(stripB(\" af \") == 1);\n    static assert(\" af \".stripB() == 1);    // UFCS (1)\n    static assert(\" af \".stripB == 1);      // UFCS (2)\n\n\n    static assert(foo!int   == 1);\n    static assert(foo!long  == 2);\n    static assert(foo!float == 3);\n    static assert(foo!real  == 4);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testlambdacomp.d",
    "content": "module testlambdacomp;\n\nvoid test1()\n{\n    static assert(__traits(isSame, (a, b) => a + b, (c, d) => c + d));\n    static assert(__traits(isSame, a => ++a, b => ++b));\n    static assert(!__traits(isSame, (int a, int b) => a + b, (a, b) => a + b));\n    static assert(__traits(isSame, (a, b) => a + b + 10, (c, d) => c + d + 10));\n}\n\nclass Y\n{\n    static int r = 5;\n    int x;\n    this(int x)\n    {\n        this.x = x;\n    }\n}\n\nclass A\n{\n    Y a;\n    this(Y a)\n    {\n        this.a = a;\n    }\n}\n\nvoid foo3(alias pred)()\n{\n    static assert(!__traits(isSame, pred, (A x, A y) => ++x.a.x + (--y.a.x)));\n}\n\nvoid test2()\n{\n\n    int b;\n    static assert(!__traits(isSame, a => a + b, a => a + b));\n\n    int f() { return 3;}\n    static assert(__traits(isSame, a => a + f(), a => a + f()));\n\n    class A\n    {\n        Y a;\n        this(Y a)\n        {\n            this.a = a;\n        }\n    }\n\n    class B\n    {\n        int a;\n        this(int a)\n        {\n            this.a = a;\n        }\n    }\n\n    B q = new B(7);\n    alias pred = (A a, A b) => ++a.a.x + (--b.a.x);\n    foo3!pred();\n    static assert(!__traits(isSame, (A a) => ++a.a.x + 2, (A b) => ++b.a.x + 3));\n    static assert(__traits(isSame,  pred, (A x, A y) => ++x.a.x + (--y.a.x)));\n    static assert(!__traits(isSame, (B a) => ++a.a + 2, (B b) => ++b.a + 3));\n    static assert(__traits(isSame, (B a) => ++a.a, (B a) => ++a.a));\n\n    B cl = new B(7);\n    static assert(!__traits(isSame, a => a + q.a, c => c + cl.a));\n\n    class C(G)\n    {\n        G a;\n        this(int a)\n        {\n            this.a = a;\n        }\n    }\n    static assert(!__traits(isSame, (C!int a) => ++a.a, (C!int a) => ++a.a));\n\n    struct X\n    {\n        int a;\n    }\n    static assert(__traits(isSame, (X a) => a.a + 2, (X b) => b.a + 2));\n\n    struct T(G)\n    {\n        G a;\n    }\n    static assert(!__traits(isSame, (T!int a) => ++a.a, (T!int a) => ++a.a));\n\n}\n\nvoid test3()\n{\n    enum q = 10;\n    static assert(__traits(isSame, (a, b) => a + b + q, (c, d) => c + d + 10));\n\n    struct Bar\n    {\n        int a;\n    }\n    enum r1 = Bar(1);\n    enum r2 = Bar(1);\n    static assert(__traits(isSame, a => a + r1.a, b => b + r2.a));\n\n    enum X { A, B, C}\n    static assert(__traits(isSame, a => a + X.A, a => a + 0));\n}\n\nvoid foo(alias pred)()\n{\n    static assert(__traits(isSame, pred, (c, d) => c + d));\n    static assert(__traits(isSame, (c, d) => c + d, pred));\n}\n\nvoid bar(alias pred)()\n{\n    static assert(__traits(isSame, pred, (c, d) => c < d + 7));\n\n    enum q = 7;\n    static assert(__traits(isSame, pred, (c, d) => c < d + q));\n\n    int r = 7;\n    static assert(!__traits(isSame, pred, (c, d) => c < d + r));\n}\nvoid test4()\n{\n    foo!((a, b) => a + b)();\n    bar!((a, b) => a < b + 7);\n}\n\nint bar()\n{\n    return 2;\n}\n\nvoid testImportedFunctions(alias pred)()\n{\n    // imports.testalambda1.bar != imports.testlambda2.bar\n    import imports.testlambda2 : bar;\n    static assert(!__traits(isSame, pred, (int a) => a + bar()));\n}\n\nvoid testLocalGlobalFunctionScopes(alias pred)()\n{\n    // testlambdacomp.bar != testlambdacomp.test5.bar\n    static assert(!__traits(isSame, pred, (int a) => a + bar()));\n\n    // imports.testlambda1.bar != testlambdacomp.test5.bar\n    import imports.testlambda1 : bar;\n    static assert(!__traits(isSame, pred, (int a) => a + bar()));\n\n    // functions imported from different modules are not equal\n    testImportedFunctions!((int a) => a + bar())();\n}\n\n// lambda functions which contain function calls\nvoid test5()\n{\n\n    int bar()\n    {\n        return 3;\n    }\n\n    // functions in the same scope\n    alias pred = a => a + bar();\n    alias pred2 = b => b + bar();\n    static assert(__traits(isSame, pred, pred2));\n\n    // functions in different scopes\n    testLocalGlobalFunctionScopes!((int a) => a + bar())();\n\n    int foo(int a, int b)\n    {\n        return 2 + a + b;\n    }\n\n    // functions with different kind of parameters\n    alias preda23 = a => a + foo(2, 3);\n    alias predb23 = b => b + foo(2, 3);\n    alias predc24 = c => c + foo(2, 4);\n    alias predd23 = (int d) => d + foo(2, 3);\n    alias prede23 = (int e) => e + foo(2, 3);\n    alias predf24 = (int f) => f + foo(2, 4);\n    static assert(__traits(isSame, preda23, predb23));\n    static assert(!__traits(isSame, predc24, predd23));\n    static assert(__traits(isSame, predd23, prede23));\n    static assert(!__traits(isSame, prede23, predf24));\n\n    // functions with function calls as parameters\n    static assert(!__traits(isSame, (int a, int b) => foo(foo(1, a), foo(1, b)), (int a, int b) => foo(foo(1, a), foo(2, b))));\n    static assert(!__traits(isSame, (a, b) => foo(foo(1, a), foo(1, b)), (int a, int b) => foo(foo(1, a), foo(2, b))));\n\n    float floatFunc(float a, float b)\n    {\n        return a + b;\n    }\n\n    static assert(__traits(isSame, a => floatFunc(a, 1.0), b => floatFunc(b, 1.0)));\n    static assert(!__traits(isSame, a => floatFunc(a, 1.0), b => floatFunc(b, 2.0)));\n}\n\nvoid main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testparse.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -o-\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6719\n\npragma(msg, __traits(compiles, mixin(\"(const(A))[0..0]\")));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9232\n\nstruct Foo9232\n{\n    void bar(T)() {}\n    void baz() {}\n}\n\nvoid test9232()\n{\n    Foo9232 foo;\n    (foo).bar!int();   // OK <- Error: found '!' when expecting ';' following statement\n    ((foo)).bar!int(); // OK\n    foo.bar!int();     // OK\n    (foo).baz();       // OK\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9401\n\nstruct S9401a\n{\n    ~this() nothrow pure @safe { }\n}\n\nstruct S9401b\n{\n    @safe ~this() pure nothrow { }\n}\n\nvoid test9401() nothrow pure @safe\n{\n    S9401a s1;\n    S9401b s2;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9649\n\nclass Outer9649\n{\n    class Inner\n    {\n    }\n}\n\nvoid test9649()\n{\n    Outer9649 outer9649;\n    (outer9649).new Inner();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9679\n\nvoid test9679(inout int = 0)\n{\n    if (        auto n = 1) { static assert(is(typeof(n) ==              int)); }\n    if (       const n = 1) { static assert(is(typeof(n) ==        const int)); }\n    if (   immutable n = 1) { static assert(is(typeof(n) ==    immutable int)); }\n    if (shared       n = 1) { static assert(is(typeof(n) == shared       int)); }\n    if (shared const n = 1) { static assert(is(typeof(n) == shared const int)); }\n    if (       inout n = 1) { static assert(is(typeof(n) ==        inout int)); }\n    if (shared inout n = 1) { static assert(is(typeof(n) == shared inout int)); }\n\n    if (       const int n = 1) { static assert(is(typeof(n) ==        const int)); }\n    if (   immutable int n = 1) { static assert(is(typeof(n) ==    immutable int)); }\n    if (shared       int n = 1) { static assert(is(typeof(n) == shared       int)); }\n    if (shared const int n = 1) { static assert(is(typeof(n) == shared const int)); }\n    if (       inout int n = 1) { static assert(is(typeof(n) ==        inout int)); }\n    if (shared inout int n = 1) { static assert(is(typeof(n) == shared inout int)); }\n\n    if (       const(int) n = 1) { static assert(is(typeof(n) ==        const int)); }\n    if (   immutable(int) n = 1) { static assert(is(typeof(n) ==    immutable int)); }\n    if (shared      (int) n = 1) { static assert(is(typeof(n) == shared       int)); }\n    if (shared const(int) n = 1) { static assert(is(typeof(n) == shared const int)); }\n    if (       inout(int) n = 1) { static assert(is(typeof(n) ==        inout int)); }\n    if (shared inout(int) n = 1) { static assert(is(typeof(n) == shared inout int)); }\n\n    if (immutable(int)[] n = [1]) { static assert(is(typeof(n) == immutable(int)[])); }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9901\n\ntemplate isGood9901(T)\n{\n    enum isGood9901 = true;\n}\nvoid test9901()\n{\n    string foo(R)(R data) if (isGood9901!R)\n    {\n        return \"\";\n    }\n    foo(1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10199\n\nvoid test10199()\n{\n    goto label;\nlabel:\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12460\n\nvoid f12460(T)()\n{\n    static if (is(T == int))\n    {\n        goto end;\n    }\nend:\n}\n\nvoid test12460()\n{\n    f12460!int();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11689\n\nvoid test11689()\n{\n    deprecated void foo() {}\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11751\n\nstatic assert(is(float == typeof(0x0.1p1F)));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11957\n\nextern(C++) class C11957\n{\n    void x() {}\n}\n\nvoid test11957()\n{\n    extern(C++) class D : C11957\n    {\n        override void x() {}\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13049\n\nenum mangle13049(T) = T.mangleof;\nalias FP13049 = void function(scope int);                                       // OK\nstatic assert(mangle13049!FP13049 == mangle13049!(void function(scope int)));   // OK <- NG\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testpostblit.d",
    "content": "struct Test1a\n{\n    this(this)\n    {\n    }\n}\n\nstruct Test1b\n{\n    Test1a a;\n}\n\nstruct Test1c\n{\n    const Test1b b;\n    @disable this(this);\n} \n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/testprofile.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -profile\n\ntemplate LaLa(E...) {\n        class LaLa {\n                this() {\n\n                }\n        }\n}\n\nvoid main() {\n        // doesn't work\n        new LaLa!(\"lala\", \"lalalalala\", \"lala\",\n                \"lala\", \"lala\", \"lala\", \"lalalala\",\n                \"lala\", \"lala\", \"lala\", \"lalala\",\n                \"lala\", \"lala\", \"lala\", \"lala\",\n                \"lala\", \"lala\", \"lala\", \"lala\",\n                \"lala\", \"lala\", \"lala\", \"lala\",\n                \"lala\", \"lala\", \"lala\", \"lala\");\n\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/traits.d",
    "content": "// This file is intended to contain all compilable traits-related tests in an\n// effort to keep the number of files in the `compilable` folder to a minimum.\n\n// https://issues.dlang.org/show_bug.cgi?id=19152\n\nclass C19152\n{\n    int OnExecute()\n    {\n        auto name = __traits(getOverloads, this, \"OnExecute\").stringof;\n        return 0;\n    }\n}\n\nstatic assert(is(typeof(__traits(getTargetInfo, \"cppRuntimeLibrary\")) == string));\nversion (CppRuntime_Microsoft)\n{\n    static assert(__traits(getTargetInfo, \"cppRuntimeLibrary\") == \"libcmt\");\n}\n\nversion (D_HardFloat)\n    static assert(__traits(getTargetInfo, \"floatAbi\") == \"hard\");\n\nversion (Win64)\n    static assert(__traits(getTargetInfo, \"objectFormat\") == \"coff\");\nversion (OSX)\n    static assert(__traits(getTargetInfo, \"objectFormat\") == \"macho\");\nversion (linux)\n    static assert(__traits(getTargetInfo, \"objectFormat\") == \"elf\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/uda.d",
    "content": "/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15180\n// [REG2.069.0-b1] Segfault with empty struct used as UDA\n\nstruct foo { }\n@foo bar () { }\n\n/************************************************/\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/udamodule1.d",
    "content": "// REQUIRED_ARGS:\n// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\ncompilable/udamodule1.d(9): Deprecation: module `imports.udamodule1` is deprecated - This module will be removed.\n---\n*/\nimport imports.udamodule1;\n\nvoid main() { foo(); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/udamodule2.d",
    "content": "import imports.udamodule2;\nimport imports.udamodule2a;\n\nenum Attrib = __traits(getAttributes, imports.udamodule2);\nstatic assert(Attrib[0] == UDA(1) && Attrib[1] == UDA(2));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/verrors_spec.d",
    "content": "/*\nPERMUTE_ARGS:\nREQUIRED_ARGS: -verrors=spec\nTEST_OUTPUT:\n---\n(spec:1) compilable/verrors_spec.d(13): Error: cannot implicitly convert expression `& i` of type `int*` to `int`\n---\n*/\n\nvoid foo(int i)\n{\n    int p;\n    bool b = __traits(compiles, {p = &i;});\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/version.d",
    "content": "/* REQUIRED_ARGS:\n*/\n\nversion (D_ModuleInfo)\n{ }\nelse\n{\n    static assert(0);\n}\n\nversion (D_Exceptions)\n{ }\nelse\n{\n    static assert(0);\n}\n\nversion (D_TypeInfo)\n{ }\nelse\n{\n    static assert(0);\n}"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/vgc1.d",
    "content": "// REQUIRED_ARGS: -vgc -o-\n// PERMUTE_ARGS:\n\n/***************** NewExp *******************/\n\n/*\nTEST_OUTPUT:\n---\ncompilable/vgc1.d(17): Deprecation: class allocators have been deprecated, consider moving the allocation strategy outside of the class\ncompilable/vgc1.d(18): Deprecation: class allocators have been deprecated, consider moving the allocation strategy outside of the class\n---\n*/\n\nstruct S1 { }\nstruct S2 { this(int); }\nstruct S3 { this(int) @nogc; }\nstruct S4 { new(size_t); }\nstruct S5 { @nogc new(size_t); }\n\n/*\nTEST_OUTPUT:\n---\ncompilable/vgc1.d(35): vgc: `new` causes a GC allocation\ncompilable/vgc1.d(37): vgc: `new` causes a GC allocation\ncompilable/vgc1.d(38): vgc: `new` causes a GC allocation\ncompilable/vgc1.d(40): vgc: `new` causes a GC allocation\ncompilable/vgc1.d(41): vgc: `new` causes a GC allocation\ncompilable/vgc1.d(42): vgc: `new` causes a GC allocation\ncompilable/vgc1.d(46): vgc: `new` causes a GC allocation\n---\n*/\n\nvoid testNew()\n{\n    int* p1 = new int;\n\n    int[] a1 = new int[3];\n    int[][] a2 = new int[][](2, 3);\n\n    S1* ps1 = new S1();\n    S2* ps2 = new S2(1);\n    S3* ps3 = new S3(1);\n    S4* ps4 = new S4;   // no error\n    S5* ps5 = new S5;   // no error\n\n    Object o1 = new Object();\n}\n\n/*\nTEST_OUTPUT:\n---\ncompilable/vgc1.d(63): vgc: `new` causes a GC allocation\ncompilable/vgc1.d(65): vgc: `new` causes a GC allocation\ncompilable/vgc1.d(66): vgc: `new` causes a GC allocation\ncompilable/vgc1.d(68): vgc: `new` causes a GC allocation\ncompilable/vgc1.d(69): vgc: `new` causes a GC allocation\ncompilable/vgc1.d(70): vgc: `new` causes a GC allocation\n---\n*/\n\nvoid testNewScope()\n{\n    scope int* p1 = new int;\n\n    scope int[] a1 = new int[3];\n    scope int[][] a2 = new int[][](2, 3);\n\n    scope S1* ps1 = new S1();\n    scope S2* ps2 = new S2(1);\n    scope S3* ps3 = new S3(1);\n    scope S4* ps4 = new S4;             // no error\n    scope S5* ps5 = new S5;             // no error\n\n    scope Object o1 = new Object();     // no error\n    scope o2 = new Object();            // no error\n    scope Object o3;\n    o3 = o2;                            // no error\n}\n\n/***************** DeleteExp *******************/\n\n/*\nTEST_OUTPUT:\n---\ncompilable/vgc1.d(95): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\ncompilable/vgc1.d(95): vgc: `delete` requires the GC\ncompilable/vgc1.d(96): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\ncompilable/vgc1.d(96): vgc: `delete` requires the GC\ncompilable/vgc1.d(97): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\ncompilable/vgc1.d(97): vgc: `delete` requires the GC\n---\n*/\nvoid testDelete(int* p, Object o, S1* s)\n{\n    delete p;\n    delete o;\n    delete s;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/vgc2.d",
    "content": "// REQUIRED_ARGS: -vgc -o-\n// PERMUTE_ARGS:\n\n/***************** CatExp *******************/\n\n/*\nTEST_OUTPUT:\n---\ncompilable/vgc2.d(21): vgc: operator `~` may cause a GC allocation\ncompilable/vgc2.d(22): vgc: operator `~` may cause a GC allocation\ncompilable/vgc2.d(23): vgc: operator `~` may cause a GC allocation\ncompilable/vgc2.d(25): vgc: operator `~` may cause a GC allocation\ncompilable/vgc2.d(26): vgc: operator `~` may cause a GC allocation\ncompilable/vgc2.d(27): vgc: operator `~` may cause a GC allocation\ncompilable/vgc2.d(28): vgc: operator `~` may cause a GC allocation\ncompilable/vgc2.d(29): vgc: operator `~` may cause a GC allocation\n---\n*/\nvoid testCat(int[] a, string s)\n{\n    int[] a1 = a ~ a;\n    int[] a2 = a ~ 1;\n    int[] a3 = 1 ~ a;\n\n    string s1 = s ~ s;\n    string s2 = s ~ \"a\";\n    string s3 = \"a\" ~ s;\n    string s4 = s ~ 'c';\n    string s5 = 'c' ~ s;\n\n    string s6 = \"a\" ~ \"b\";      // no error\n    string s7 = \"a\" ~ 'c';      // no error\n    string s8 = 'c' ~ \"b\";      // no error\n}\n\n/***************** CatAssignExp *******************/\n\n/*\nTEST_OUTPUT:\n---\ncompilable/vgc2.d(48): vgc: operator `~=` may cause a GC allocation\ncompilable/vgc2.d(50): vgc: operator `~=` may cause a GC allocation\ncompilable/vgc2.d(51): vgc: operator `~=` may cause a GC allocation\n---\n*/\nvoid testCatAssign(int[] a, string s)\n{\n    a ~= 1;\n\n    s ~= \"a\";\n    s ~= 'c';\n}\n\n/***************** ArrayLiteralExp *******************/\n\nint* barA();\n\n/*\nTEST_OUTPUT:\n---\ncompilable/vgc2.d(70): vgc: array literal may cause a GC allocation\ncompilable/vgc2.d(71): vgc: array literal may cause a GC allocation\n---\n*/\nvoid testArray()\n{\n    enum arrLiteral = [null, null];\n\n    int* p;\n    auto a = [p, p, barA()];\n    a = arrLiteral;\n}\n\n/***************** AssocArrayLiteralExp *******************/\n\n/*\nTEST_OUTPUT:\n---\ncompilable/vgc2.d(87): vgc: associative array literal may cause a GC allocation\ncompilable/vgc2.d(88): vgc: associative array literal may cause a GC allocation\n---\n*/\nvoid testAssocArray()\n{\n    enum aaLiteral = [10: 100];\n\n    auto aa = [1:1, 2:3, 4:5];\n    aa = aaLiteral;\n}\n\n/***************** IndexExp *******************/\n\n/*\nTEST_OUTPUT:\n---\ncompilable/vgc2.d(102): vgc: indexing an associative array may cause a GC allocation\ncompilable/vgc2.d(103): vgc: indexing an associative array may cause a GC allocation\n---\n*/\nvoid testIndex(int[int] aa)\n{\n    aa[1] = 0;\n    int n = aa[1];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/vgc3.d",
    "content": "// REQUIRED_ARGS: -vgc -o-\n// PERMUTE_ARGS:\n\n/***************** AssignExp *******************/\n\n/*\nTEST_OUTPUT:\n---\ncompilable/vgc3.d(16): vgc: setting `length` may cause a GC allocation\ncompilable/vgc3.d(17): vgc: setting `length` may cause a GC allocation\ncompilable/vgc3.d(18): vgc: setting `length` may cause a GC allocation\n---\n*/\nvoid testArrayLength(int[] a)\n{\n    a.length = 3;\n    a.length += 1;\n    a.length -= 1;\n}\n\n/***************** CallExp *******************/\n\nvoid barCall();\n\n/*\nTEST_OUTPUT:\n---\n---\n*/\n\n\nvoid testCall()\n{\n    auto fp = &barCall;\n    (*fp)();\n    barCall();\n}\n\n/****************** Closure ***********************/\n\n@nogc void takeDelegate2(scope int delegate() dg) {}\n@nogc void takeDelegate3(      int delegate() dg) {}\n\n/*\nTEST_OUTPUT:\n---\ncompilable/vgc3.d(51): vgc: using closure causes GC allocation\ncompilable/vgc3.d(63): vgc: using closure causes GC allocation\n---\n*/\nauto testClosure1()\n{\n    int x;\n    int bar() { return x; }\n    return &bar;\n}\nvoid testClosure2()\n{\n    int x;\n    int bar() { return x; }\n    takeDelegate2(&bar);     // no error\n}\nvoid testClosure3()\n{\n    int x;\n    int bar() { return x; }\n    takeDelegate3(&bar);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/compilable/warn3882.d",
    "content": "// PERMUTE_ARGS: -w -wi -debug\n/*\nTEST_OUTPUT:\n---\n---\n*/\n\n@safe pure nothrow void strictVoidReturn(T)(T x) {}\n@safe pure nothrow void nonstrictVoidReturn(T)(ref T x) {}\n\nvoid test3882()\n{\n    int x = 3;\n    strictVoidReturn(x);\n    nonstrictVoidReturn(x);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12619\n\nextern (C) @system nothrow pure void* memcpy(void* s1, in void* s2, size_t n);\n// -> weakly pure\n\nvoid test12619() pure\n{\n    ubyte[10] a, b;\n    debug memcpy(a.ptr, b.ptr, 5);  // memcpy call should have side effect\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12760\n\nstruct S12760(T)\n{\n    T i;\n    this(T j) inout {}\n}\n\nstruct K12760\n{\n    S12760!int nullable;\n\n    this(int)\n    {\n        nullable = 0;   // weak purity\n    }\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12909\n\nint f12909(immutable(int[])[int] aa) pure nothrow\n{\n    //aa[0] = [];   // fix for https://issues.dlang.org/show_bug.cgi?id=13701\n    return 0;\n}\n\nvoid test12909()\n{\n    immutable(int[])[int] aa;\n    f12909(aa);\n\n    // from 12910\n    const(int[])[int] makeAA() { return null; }  // to make r-value\n    makeAA().rehash();\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13899\n\nconst struct Foo13899\n{\n    int opApply(immutable int delegate(in ref int) pure nothrow dg) pure nothrow\n    {\n        return 1;\n    }\n}\n\nvoid test13899()\n{\n    foreach (x; Foo13899())\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/d_do_test.exp",
    "content": "# Copyright (C) 2012-2018 Free Software Foundation, Inc.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\n# Test using the DMD testsuite.\n# Load support procs.\nload_lib gdc-dg.exp\n\n#\n# Convert DMD arguments to GDC equivalent\n#\n\nproc gdc-convert-args { args } {\n    set out \"\"\n\n    foreach arg [split [lindex $args 0] \" \"] {\n        # List of switches kept in ASCII collated order.\n        if { [regexp -- {^-I([\\w+/-]+)} $arg pattern path] } {\n            lappend out \"-I$path\"\n\n        } elseif { [regexp -- {^-J([\\w+/-]+)} $arg pattern path] } {\n            lappend out \"-J$path\"\n\n        } elseif [string match \"-allinst\" $arg] {\n            lappend out \"-fall-instantiations\"\n\n        } elseif [string match \"-betterC\" $arg] {\n            lappend out \"-fno-druntime\"\n\n        } elseif { [string match \"-boundscheck\" $arg]\n                 || [string match \"-boundscheck=on\" $arg] } {\n            lappend out \"-fbounds-check\"\n\n        } elseif { [string match \"-boundscheck=off\" $arg]\n                   || [string match \"-noboundscheck\" $arg] } {\n            lappend out \"-fno-bounds-check\"\n\n        } elseif [string match \"-boundscheck=safeonly\" $arg] {\n            lappend out \"-fbounds-check=safeonly\"\n\n        } elseif [string match \"-c\" $arg] {\n            lappend out \"-c\"\n\n        } elseif [string match \"-d\" $arg] {\n            lappend out \"-Wno-deprecated\"\n\n        } elseif [string match \"-de\" $arg] {\n            lappend out \"-Wdeprecated\"\n            lappend out \"-Werror\"\n\n        } elseif [string match \"-debug\" $arg] {\n            lappend out \"-fdebug\"\n\n        } elseif [regexp -- {^-debug=(\\w+)} $arg pattern value] {\n            lappend out \"-fdebug=$value\"\n\n        } elseif [string match \"-dip1000\" $arg] {\n            lappend out \"-ftransition=dip1000\"\n\n        } elseif [string match \"-dip25\" $arg] {\n            lappend out \"-ftransition=dip25\"\n\n        } elseif [string match \"-dw\" $arg] {\n            lappend out \"-Wdeprecated\"\n            lappend out \"-Wno-error\"\n\n        } elseif [string match \"-fPIC\" $arg] {\n            lappend out \"-fPIC\"\n\n        } elseif { [string match \"-g\" $arg]\n                   || [string match \"-gc\" $arg] } {\n            lappend out \"-g\"\n\n        } elseif [string match \"-ignore\" $arg] {\n            lappend out \"-fignore-unknown-pragmas\"\n\n        } elseif [string match \"-inline\" $arg] {\n            lappend out \"-finline-functions\"\n\n        } elseif [string match \"-main\" $arg] {\n            lappend out \"-fmain\"\n\n        } elseif [regexp -- {^-mv=([\\w+=./-]+)} $arg pattern value] {\n            lappend out \"-fmodule-file=$value\"\n\n        } elseif [string match \"-O\" $arg] {\n            lappend out \"-O2\"\n\n        } elseif [string match \"-release\" $arg] {\n            lappend out \"-frelease\"\n\n        } elseif [regexp -- {^-transition=(\\w+)} $arg pattern value] {\n            lappend out \"-ftransition=$value\"\n\n        } elseif [string match \"-unittest\" $arg] {\n            lappend out \"-funittest\"\n\n        } elseif [string match \"-verrors=spec\" $arg] {\n            lappend out \"-Wspeculative\"\n\n        } elseif [regexp -- {^-verrors=(\\d+)} $arg pattern num] {\n            lappend out \"-fmax-errors=$num\"\n\n        } elseif [regexp -- {^-version=(\\w+)} $arg pattern value] {\n            lappend out \"-fversion=$value\"\n\n        } elseif [string match \"-vtls\" $arg] {\n            lappend out \"-ftransition=tls\"\n\n        } elseif [string match \"-w\" $arg] {\n            lappend out \"-Wall\"\n            lappend out \"-Werror\"\n\n        } elseif [string match \"-wi\" $arg] {\n            lappend out \"-Wall\"\n            lappend out \"-Wno-error\"\n\n        } else {\n            # print \"Unhandled Argument: $arg\"\n        }\n    }\n\n    return $out\n}\n\nproc gdc-copy-extra { base extra } {\n    # Split base, folder/file.\n    set type [file dirname $extra]\n\n    # print \"Filename: $base - $extra\"\n\n    set fdin [open $base/$extra r]\n    fconfigure $fdin -encoding binary\n\n    file mkdir $type\n    set fdout [open $extra w]\n    fconfigure $fdout -encoding binary\n\n    while { [gets $fdin copy_line] >= 0 } {\n        set out_line $copy_line\n        puts $fdout $out_line\n    }\n\n    close $fdin\n    close $fdout\n\n    return $extra\n}\n\n#\n# Translate DMD test directives to dejagnu equivalent.\n#\n#   COMPILE_SEPARATELY: Not handled.\n#   EXECUTE_ARGS:       Parameters to add to the execution of the test.\n#   COMPILED_IMPORTS:   List of modules files that are imported by the main\n#                       source file that should be included in compilation.\n#                       Currently handled the same as EXTRA_SOURCES.\n#   EXTRA_SOURCES:      List of extra sources to build and link along with\n#                       the test.\n#   EXTRA_FILES:        List of extra files to copy for the test runs.\n#   PERMUTE_ARGS:       The set of arguments to permute in multiple compiler\n#                       invocations.  An empty set means only one permutation\n#                       with no arguments.\n#   TEST_OUTPUT:        The output expected from the compilation.\n#   POST_SCRIPT:        Not handled.\n#   REQUIRED_ARGS:      Arguments to add to the compiler command line.\n#   DISABLED:           Not handled.\n#\n\nproc dmd2dg { base test } {\n    global DEFAULT_DFLAGS\n    global PERMUTE_ARGS\n    global GDC_EXECUTE_ARGS\n\n    set PERMUTE_ARGS $DEFAULT_DFLAGS\n    set GDC_EXECUTE_ARGS \"\"\n\n    # Split base, folder/file.\n    set type [file dirname $test]\n\n    # print \"Filename: $base - $test\"\n\n    set fdin [open $base/$test r]\n    #fconfigure $fdin -encoding binary\n\n    file mkdir $type\n    set fdout [open $test w]\n    #fconfigure $fdout -encoding binary\n\n    while { [gets $fdin copy_line] >= 0 } {\n        set out_line $copy_line\n\n        if [regexp -- {COMPILE_SEPARATELY} $copy_line] {\n            # COMPILE_SEPARATELY is not handled.\n            regsub -- {COMPILE_SEPARATELY.*$} $copy_line \"\" out_line\n\n        } elseif [regexp -- {DISABLED} $copy_line] {\n            # DISABLED is not handled.\n            regsub -- {DISABLED.*$} $copy_line \"\" out_line\n\n        } elseif [regexp -- {POST_SCRIPT} $copy_line] {\n            # POST_SCRIPT is not handled\n            regsub -- {POST_SCRIPT.*$} $copy_line \"\" out_line\n\n        } elseif [regexp -- {PERMUTE_ARGS\\s*:\\s*(.*)} $copy_line match args] {\n            # PERMUTE_ARGS is handled by gdc-do-test.\n            set PERMUTE_ARGS [gdc-convert-args $args]\n            regsub -- {PERMUTE_ARGS.*$} $copy_line \"\" out_line\n\n        } elseif [regexp -- {EXECUTE_ARGS\\s*:\\s*(.*)} $copy_line match args] {\n            # EXECUTE_ARGS is handled by gdc_load.\n            foreach arg $args {\n                lappend GDC_EXECUTE_ARGS $arg\n            }\n            regsub -- {EXECUTE_ARGS.*$} $copy_line \"\" out_line\n\n        } elseif [regexp -- {REQUIRED_ARGS\\s*:\\s*(.*)} $copy_line match args] {\n            # Convert all listed arguments to from dmd to gdc-style.\n            set new_option \"{ dg-additional-options \\\"[gdc-convert-args $args]\\\" }\"\n            regsub -- {REQUIRED_ARGS.*$} $copy_line $new_option out_line\n\n        } elseif [regexp -- {EXTRA_SOURCES\\s*:\\s*(.*)} $copy_line match sources] {\n            # Copy all sources to the testsuite build directory.\n            foreach import $sources {\n                # print \"Import: $base $type/$import\"\n                gdc-copy-extra $base \"$type/$import\"\n            }\n            set new_option \"{ dg-additional-sources \\\"$sources\\\" }\"\n            regsub -- {EXTRA_SOURCES.*$} $copy_line $new_option out_line\n\n        } elseif [regexp -- {EXTRA_CPP_SOURCES\\s*:\\s*(.*)} $copy_line match sources] {\n            # Copy all sources to the testsuite build directory.\n            foreach import $sources {\n                # print \"Import: $base $type/$import\"\n                gdc-copy-extra $base \"$type/$import\"\n            }\n            set new_option \"{ dg-additional-sources \\\"$sources\\\" }\"\n            regsub -- {EXTRA_CPP_SOURCES.*$} $copy_line $new_option out_line\n\n        } elseif [regexp -- {EXTRA_FILES\\s*:\\s*(.*)} $copy_line match files] {\n            # Copy all files to the testsuite build directory.\n            foreach import $files {\n                # print \"Import: $base $type/$import\"\n                gdc-copy-extra $base \"$type/$import\"\n            }\n            set new_option \"{ dg-additional-files \\\"$files\\\" }\"\n            regsub -- {EXTRA_FILES.*$} $copy_line $new_option out_line\n\n        } elseif [regexp -- {COMPILED_IMPORTS\\s*:\\s*(.*)} $copy_line match sources] {\n            # Copy all sources to the testsuite build directory.\n            foreach import $sources {\n                # print \"Import: $base $type/$import\"\n                gdc-copy-extra $base \"$type/$import\"\n            }\n            set new_option \"{ dg-additional-sources \\\"$sources\\\" }\"\n            regsub -- {COMPILED_IMPORTS.*$} $copy_line $new_option out_line\n\n        }\n\n        puts $fdout $out_line\n    }\n\n    # Add specific options for test type\n\n    # DMD's testsuite is extremely verbose, compiler messages from constructs\n    # such as pragma(msg, ...) would otherwise cause tests to fail.\n    set out_line \"// { dg-prune-output .* }\"\n    puts $fdout $out_line\n\n    # Since GCC 6-20160131 blank lines are not allowed in the output by default.\n    dg-allow-blank-lines-in-output { 1 }\n\n    # Compilable files are successful if an output is generated.\n    # Fail compilable are successful if an output is not generated.\n    # Runnable must compile, link, and return 0 to be successful by default.\n    switch [file dirname $test] {\n        runnable {\n            if ![isnative] {\n                set out_line \"// { dg-final { output-exists } }\"\n                puts $fdout $out_line\n            }\n        }\n\n        compilable {\n            set out_line \"// { dg-final { output-exists } }\"\n            puts $fdout $out_line\n        }\n\n        fail_compilation {\n            set out_line \"// { dg-final { output-exists-not } }\"\n            puts $fdout $out_line\n        }\n    }\n\n    close $fdin\n    close $fdout\n\n    return $test\n}\n\nproc gdc-permute-options { options } {\n    set result { }\n    set n [expr 1<<[llength $options]]\n    for { set i 0 } { $i<$n } { incr i } {\n        set option \"\"\n        for { set j 0 } { $j<[llength $options] } { incr j } {\n            if [expr $i & 1 << $j] {\n                append option [lindex $options $j]\n                append option \" \"\n            }\n        }\n        lappend result $option\n\n    }\n    return $result\n}\n\n\nproc gdc-do-test { } {\n    global srcdir subdir\n    global dg-do-what-default\n    global verbose\n\n    # If a testcase doesn't have special options, use these.\n    global DEFAULT_DFLAGS\n    if ![info exists DEFAULT_DFLAGS] then {\n        set DEFAULT_DFLAGS \"-g -O2 -frelease\"\n        #set DEFAULT_DFLAGS \"-O2\"\n    }\n\n    # These are special options to use on testcase, and override DEFAULT_DFLAGS\n    global PERMUTE_ARGS\n\n    # Set if an extra option should be passed to link to shared druntime.\n    global SHARED_OPTION\n\n    # Additional arguments for gdc_load\n    global GDC_EXECUTE_ARGS\n\n    # Initialize `dg'.\n    dg-init\n\n    # Main loop.\n\n    # set verbose 1\n    # set dg-final-code \"\"\n    # Find all tests and pass to routine.\n    foreach test [lsort [find $srcdir/$subdir *]] {\n        regexp -- \"(.*)/(.+)/(.+)\\.(.+)$\" $test match base dir name ext\n\n        # Skip invalid test directory\n        if { [lsearch \"runnable compilable fail_compilation\" $dir] == -1 } {\n            continue\n        }\n\n        # Skip invalid test extensions\n        if { [lsearch \"d\" $ext] == -1 } {\n            continue\n        }\n\n        # Convert to DG test.\n        set imports [format \"-I%s/%s\" $base $dir]\n        set filename [dmd2dg $base $dir/$name.$ext]\n\n        if { $dir == \"runnable\" } {\n            append PERMUTE_ARGS \" $SHARED_OPTION\"\n        }\n        set options [gdc-permute-options $PERMUTE_ARGS]\n\n        switch $dir {\n            runnable {\n                for { set i 0 } { $i<[llength $options] } { incr i } {\n                    set flags [lindex $options $i]\n                    if [isnative] {\n                        set dg-do-what-default \"run\"\n                    } else {\n                        set dg-do-what-default \"link\"\n                    }\n                    gdc-dg-runtest $filename $flags $imports\n                }\n            }\n\n            compilable {\n                for { set i 0 } { $i<[llength $options] } { incr i } {\n                    set flags [lindex $options $i]\n                    #set dg-do-what-default \"compile\"\n                    set dg-do-what-default \"assemble\"\n                    gdc-dg-runtest $filename $flags $imports\n                }\n            }\n\n            fail_compilation {\n                for { set i 0 } { $i<[llength $options] } { incr i } {\n                    set flags [lindex $options $i]\n                    set dg-do-what-default \"assemble\"\n                    gdc-dg-runtest $filename $flags $imports\n                }\n            }\n        }\n\n        # Cleanup\n        #file delete $filename\n    }\n\n    # All done.\n    dg-finish\n}\n\ngdc-do-test\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/aacmp10381.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/aacmp10381.d(12): Error: `>` is not defined for associative arrays\n---\n*/\n\nbool test10381()\n{\n    int[int] aa1 = [0: 1];\n    int[int] aa2 = [0: 1];\n    return aa1 > aa2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/b17918.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/imports/b17918a.d(7): Error: undefined identifier `_listMap`\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=17918\nimport imports.b17918a;\n\nclass Derived : Base\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/b3841.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -w -o-\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/b3841.d-mixin-31(31): Warning: `char += float` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `int += float` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `long += double` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `char -= float` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `int -= float` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `long -= double` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `char *= float` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `int *= float` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `long *= double` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `char /= float` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `int /= float` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `long /= double` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `char %= float` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `int %= float` is performing truncating conversion\nfail_compilation/b3841.d-mixin-31(31): Warning: `long %= double` is performing truncating conversion\n---\n*/\n\n\nvoid f(string op, LHS, RHS)()\n{\n    // pragma(msg, LHS, \" += \", RHS);\n    LHS a;\n    RHS b;\n    mixin(\"a \"~op~\" b;\");\n}\n\ntemplate Ops(T...)\n{\n    alias Ops = T;\n}\n\nvoid main()\n{\n    foreach (string op; Ops!(\"+=\", \"-=\", \"*=\", \"/=\", \"%=\"))\n    {\n        // OK\n        f!(op, int, int)();\n        f!(op, long, int)();\n        f!(op, long, short)();\n        f!(op, float, long)();\n        f!(op, cfloat, long)();\n        f!(op, double, float)();\n        \n        // Should that really be OK ?\n        f!(op, short, int)();\n        f!(op, float, double)();\n\n        // Not OK, truncating conversion.\n        f!(op, char, float)();\n        f!(op, int, float)();\n        f!(op, long, double)();\n    }\n\n    foreach (string op; Ops!(\"+=\", \"-=\"))\n    {\n        // OK\n        f!(op, idouble, ifloat)();\n\n        // Should that really be OK ?\n        f!(op, ifloat, idouble)();\n    }\n    \n    // OK\n    f!(\"^^=\", int, int)();\n    f!(\"^^=\", long, int)();\n    f!(\"^^=\", long, short)();\n    f!(\"^^=\", float, long)();\n    f!(\"^^=\", double, float)();\n    // Should that really be OK ?\n    f!(\"^^=\", float, double)();\n}"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/b6227.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/b6227.d(16): Error: Comparison between different enumeration types `X` and `Y`; If this behavior is intended consider using `std.conv.asOriginalType`\nfail_compilation/b6227.d(16):        while evaluating: `static assert(!false)`\nfail_compilation/b6227.d(17): Error: Comparison between different enumeration types `X` and `Y`; If this behavior is intended consider using `std.conv.asOriginalType`\nfail_compilation/b6227.d(17):        while evaluating: `static assert(cast(X)0 == cast(Y)0)`\n---\n*/\nenum X {\n    O,\n    R\n}\nenum Y {\n    U\n}\nstatic assert(!(X.O != Y.U));\nstatic assert( (X.O == Y.U));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/betterc.d",
    "content": "/* REQUIRED_ARGS: -betterC\n * TEST_OUTPUT:\n---\nfail_compilation/betterc.d(12): Error: Cannot use `throw` statements with -betterC\nfail_compilation/betterc.d(17): Error: Cannot use try-catch statements with -betterC\nfail_compilation/betterc.d(29): Error: `TypeInfo` cannot be used with -betterC\n---\n*/\n\nvoid test()\n{\n    throw new Exception(\"msg\");\n}\n\nvoid test2()\n{\n    try\n    {\n        test();\n    }\n    catch (Exception e)\n    {\n    }\n}\n\nvoid test3()\n{\n    int i;\n    auto ti = typeid(i);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/bug15613.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/bug15613.d(16): Error: function `bug15613.f(int...)` is not callable using argument types `(typeof(null))`\nfail_compilation/bug15613.d(16):        cannot pass argument `null` of type `typeof(null)` to parameter `int...`\nfail_compilation/bug15613.d(17): Error: function `bug15613.g(Object, ...)` is not callable using argument types `(int)`\nfail_compilation/bug15613.d(17):        cannot pass argument `8` of type `int` to parameter `Object`\n---\n*/\n\nvoid f(int...);\nvoid g(Object, ...);\n\nvoid main()\n{\n    f(null);\n    g(8);\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/bug15613.d(32): Error: function `bug15613.h(int[]...)` is not callable using argument types `(int, void function(int[]...))`\nfail_compilation/bug15613.d(32):        cannot pass argument `& h` of type `void function(int[]...)` to parameter `int[]...`\n---\n*/\n\nvoid h(int[]...);\n\nvoid test()\n{\n    h(7, &h);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/bug18743.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/bug18743.d(18): Deprecation: `a ? a = 4 : a` must be surrounded by parentheses when next to operator `=`\nfail_compilation/bug18743.d(19): Deprecation: `a ? --a : a` must be surrounded by parentheses when next to operator `+=`\n---\n*/\n\nvoid main()\n{\n\tint a;\n\n\t// ok\n\t(a ? a = 4 : a) = 5;\n\ta ? a = 4 : (a = 5);\n\n\ta ? a = 4 : a = 5;\n\ta ? --a : a += 1;\n\n\ta ? a = 4 : a++; // ok\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/bug4283.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/bug4283.d(12): Error: declaration expected, not `}`\n---\n*/\n\ntemplate Foo(bool b) {\n    static if (b)\n        enum bool Foo = 1;\n    else\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/bug5.d",
    "content": "// REQUIRED_ARGS:\n\nint test1()\n{\n    if (false)\n        return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/bug5b.d",
    "content": "// REQUIRED_ARGS:\n\nint test1()\n{\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/bug8150a.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=8150: nothrow check doesn't work for constructor\n\nstruct Foo\n{\n    this(int) nothrow\n    {\n        throw new Exception(\"something\");\n    }\n}\n\nvoid main() {\n    Foo(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/bug8150b.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=8150: nothrow check doesn't work for constructor\n\nstruct Foo\n{\n    this()(int) nothrow\n    {\n        throw new Exception(\"something\");\n    }\n}\n\nvoid main() {\n    Foo(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/bug8891.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/bug8891.d(21): Error: need `this` for `opCall` of type `S(int n)`\n---\n*/\n\nstruct S\n{\n    int value = 10;\n    S opCall(int n) // non-static\n    {\n        //printf(\"this.value = %d\\n\", this.value);    // prints garbage!\n        S s;\n        s.value = n;\n        return s;\n    }\n}\nvoid main()\n{\n    S s = 10;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/bug9631.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/bug9631.d(20): Error: cannot implicitly convert expression `F()` of type `bug9631.T1!().F` to `bug9631.T2!().F`\n---\n*/\n\ntemplate T1()\n{\n    struct F { }\n}\n\ntemplate T2()\n{\n    struct F { }\n}\n\nvoid main()\n{\n    T2!().F x = T1!().F();\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/bug9631.d(41): Error: incompatible types for `(x) == (y)`: `bug9631.S` and `bug9631.tem!().S`\n---\n*/\n\nstruct S { char c; }\n\ntemplate tem()\n{\n    struct S { int i; }\n}\n\nvoid equal()\n{\n    S x;\n    auto y = tem!().S();\n    bool b = x == y;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/bug9631.d(55): Error: cannot cast expression `x` of type `bug9631.S` to `bug9631.tem!().S` because of different sizes\nfail_compilation/bug9631.d(58): Error: cannot cast expression `ta` of type `bug9631.tem!().S[1]` to `bug9631.S[1]` because of different sizes\nfail_compilation/bug9631.d(59): Error: cannot cast expression `sa` of type `S[1]` to `S[]` since sizes don't line up\n---\n*/\nvoid test3()\n{\n    S x;\n    auto y = cast(tem!().S)x;\n\n    tem!().S[1] ta;\n    S[1] sa = cast(S[1])ta;\n    auto t2 = cast(tem!().S[])sa;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/bug9631.d(79): Error: function `bug9631.arg.f(int i, S s)` is not callable using argument types `(int, S)`\nfail_compilation/bug9631.d(79):        cannot pass argument `y` of type `bug9631.tem!().S` to parameter `bug9631.S s`\nfail_compilation/bug9631.d(80): Error: function literal `__lambda2(S s)` is not callable using argument types `(S)`\nfail_compilation/bug9631.d(80):        cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S s`\nfail_compilation/bug9631.d(86): Error: constructor `bug9631.arg.A.this(S _param_0)` is not callable using argument types `(S)`\nfail_compilation/bug9631.d(86):        cannot pass argument `S(0)` of type `bug9631.tem!().S` to parameter `bug9631.S _param_0`\n---\n*/\nvoid arg()\n{\n    S x;\n    tem!().S y;\n\n    void f(int i, S s);\n    f(4, y);\n    (tem!().S s){}(x);\n\n    struct A\n    {\n        this(S){}\n    }\n    A(tem!().S());\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/bug9631.d(106): Error: function `bug9631.targ.ft!().ft(S _param_0)` is not callable using argument types `(S)`\nfail_compilation/bug9631.d(106):        cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S _param_0`\nfail_compilation/bug9631.d(107): Error: template `bug9631.targ.ft` cannot deduce function from argument types `!()(S)`, candidates are:\nfail_compilation/bug9631.d(105):        `bug9631.targ.ft()(tem!().S)`\nfail_compilation/bug9631.d(109): Error: template `bug9631.targ.ft2` cannot deduce function from argument types `!()(S, int)`, candidates are:\nfail_compilation/bug9631.d(108):        `bug9631.targ.ft2(T)(S, T)`\n---\n*/\nvoid targ()\n{\n    S x;\n    tem!().S y;\n\n    void ft()(tem!().S){}\n    ft!()(x);\n    ft(x);\n    void ft2(T)(S, T){}\n    ft2(y, 1);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ccast.d",
    "content": "/* \nTEST_OUTPUT:\n---\nfail_compilation/ccast.d(9): Error: C style cast illegal, use `cast(byte)i`\n---\n*/\n\nint i;\nbyte b = (byte)i;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/cerrors.d",
    "content": "/* REQUIRED_ARGS: -wi\nTEST_OUTPUT:\n---\nfail_compilation/cerrors.d(11): Error: C preprocessor directive `#if` is not supported, use `version` or `static if`\nfail_compilation/cerrors.d(11): Error: declaration expected, not `#`\nfail_compilation/cerrors.d(15): Warning: C preprocessor directive `#endif` is not supported\nfail_compilation/cerrors.d(15): Error: declaration expected, not `#`\n---\n*/\n\n#if 1\n\nvoid test(wchar_t u);\n\n#endif\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/checkimports1a.d",
    "content": "// REQUIRED_ARGS: -transition=checkimports -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/checkimports1a.d(16): Deprecation: local import search method found struct `imports.diag12598a.lines` instead of variable `checkimports1a.C.lines`\n---\n*/\n\n\n// new lookup + information\nclass C\n{\n    void f()\n    {\n        import imports.diag12598a;\n        lines ~= \"\";\n    }\n\n    string[] lines;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/checkimports1b.d",
    "content": "// REQUIRED_ARGS: -transition=import -transition=checkimports\n/*\nTEST_OUTPUT:\n---\nfail_compilation/checkimports1b.d(16): Deprecation: local import search method found struct `imports.diag12598a.lines` instead of variable `checkimports1b.C.lines`\nfail_compilation/checkimports1b.d(16): Error: `lines` is a `struct` definition and cannot be modified\n---\n*/\n\n// old lookup + information\nclass C\n{\n    void f()\n    {\n        import imports.diag12598a;\n        lines ~= \"\";\n    }\n\n    string[] lines;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/checkimports1c.d",
    "content": "// REQUIRED_ARGS: -transition=checkimports -transition=import\n/*\nTEST_OUTPUT:\n---\nfail_compilation/checkimports1c.d(16): Deprecation: local import search method found struct `imports.diag12598a.lines` instead of variable `checkimports1c.C.lines`\nfail_compilation/checkimports1c.d(16): Error: `lines` is a `struct` definition and cannot be modified\n---\n*/\n\n// old lookup + information (the order of switches is reverse)\nclass C\n{\n    void f()\n    {\n        import imports.diag12598a;\n        lines ~= \"\";\n    }\n\n    string[] lines;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/checkimports2a.d",
    "content": "// REQUIRED_ARGS: -transition=checkimports\n/*\nTEST_OUTPUT:\n---\nfail_compilation/checkimports2a.d(26): Deprecation: local import search method found variable `imports.imp2.X` instead of variable `checkimports2a.X`\nfail_compilation/checkimports2a.d(32): Deprecation: local import search method found variable `imports.imp2.X` instead of nothing\nfail_compilation/checkimports2a.d(32): Error: no property `X` for type `checkimports2a.B`\nfail_compilation/checkimports2a.d(32):        while evaluating: `static assert((B).X == 0)`\nfail_compilation/checkimports2a.d(33): Deprecation: local import search method found variable `imports.imp2.Y` instead of nothing\nfail_compilation/checkimports2a.d(33): Error: no property `Y` for type `checkimports2a.B`\nfail_compilation/checkimports2a.d(33):        while evaluating: `static assert((B).Y == 2)`\nfail_compilation/checkimports2a.d(35): Deprecation: local import search method found variable `imports.imp2.X` instead of variable `checkimports2a.X`\nfail_compilation/checkimports2a.d(36): Deprecation: local import search method found variable `imports.imp2.Y` instead of variable `imports.imp1.Y`\n---\n*/\n\n// new lookup + information\n\nimport imports.imp1;\n\nenum X = 0;\n\nclass B\n{\n    import imports.imp2;\n    static assert(X == 0);      // imp2.X --> .X\n    int[Y] aa;                  // imp2.Y\n}\n\nclass C : B\n{\n    static assert(B.X == 0);    // imp2.X --> error\n    static assert(B.Y == 2);    // imp2.Y --> error\n\n    static assert(X == 0);      // imp2.X --> .X\n    static assert(Y == 1);      // imp2.Y --> imp1.Y\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/checkimports2b.d",
    "content": "// REQUIRED_ARGS: -transition=import -transition=checkimports -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/checkimports2b.d(27): Deprecation: local import search method found variable `imports.imp2.X` instead of variable `checkimports2b.X`\nfail_compilation/checkimports2b.d(27):        while evaluating: `static assert(2 == 2)`\nfail_compilation/checkimports2b.d(33): Deprecation: local import search method found variable `imports.imp2.X` instead of nothing\nfail_compilation/checkimports2b.d(33):        while evaluating: `static assert(2 == 2)`\nfail_compilation/checkimports2b.d(34): Deprecation: local import search method found variable `imports.imp2.Y` instead of nothing\nfail_compilation/checkimports2b.d(34):        while evaluating: `static assert(2 == 2)`\nfail_compilation/checkimports2b.d(36): Deprecation: local import search method found variable `imports.imp2.X` instead of variable `checkimports2b.X`\nfail_compilation/checkimports2b.d(36):        while evaluating: `static assert(2 == 2)`\nfail_compilation/checkimports2b.d(37): Deprecation: local import search method found variable `imports.imp2.Y` instead of variable `imports.imp1.Y`\nfail_compilation/checkimports2b.d(37):        while evaluating: `static assert(2 == 2)`\n---\n*/\n\n// old lookup + information\n\nimport imports.imp1;\n\nenum X = 0;\n\nclass B\n{\n    import imports.imp2;\n    static assert(X == 2);      // imp2.X --> .X (information)\n    int[Y] aa;                  // imp2.Y\n}\n\nclass C : B\n{\n    static assert(B.X == 2);    // imp2.X --> error (keep old lookup rule)\n    static assert(B.Y == 2);    // imp2.Y --> error (keep old lookup rule)\n\n    static assert(X == 2);      // imp2.X --> .X (information)\n    static assert(Y == 2);      // imp2.Y --> imp1.Y (information)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/checkimports2c.d",
    "content": "// REQUIRED_ARGS: -transition=checkimports -transition=import -de\n/*\nTEST_OUTPUT:\n---\n\nfail_compilation/checkimports2c.d(28): Deprecation: local import search method found variable `imports.imp2.X` instead of variable `checkimports2c.X`\nfail_compilation/checkimports2c.d(28):        while evaluating: `static assert(2 == 2)`\nfail_compilation/checkimports2c.d(34): Deprecation: local import search method found variable `imports.imp2.X` instead of nothing\nfail_compilation/checkimports2c.d(34):        while evaluating: `static assert(2 == 2)`\nfail_compilation/checkimports2c.d(35): Deprecation: local import search method found variable `imports.imp2.Y` instead of nothing\nfail_compilation/checkimports2c.d(35):        while evaluating: `static assert(2 == 2)`\nfail_compilation/checkimports2c.d(37): Deprecation: local import search method found variable `imports.imp2.X` instead of variable `checkimports2c.X`\nfail_compilation/checkimports2c.d(37):        while evaluating: `static assert(2 == 2)`\nfail_compilation/checkimports2c.d(38): Deprecation: local import search method found variable `imports.imp2.Y` instead of variable `imports.imp1.Y`\nfail_compilation/checkimports2c.d(38):        while evaluating: `static assert(2 == 2)`\n---\n*/\n\n// old lookup + information (the order of switches is reverse)\n\nimport imports.imp1;\n\nenum X = 0;\n\nclass B\n{\n    import imports.imp2;\n    static assert(X == 2);      // imp2.X --> .X (information)\n    int[Y] aa;                  // imp2.Y\n}\n\nclass C : B\n{\n    static assert(B.X == 2);    // imp2.X --> error (keep old lookup rule)\n    static assert(B.Y == 2);    // imp2.Y --> error (keep old lookup rule)\n\n    static assert(X == 2);      // imp2.X --> .X (information)\n    static assert(Y == 2);      // imp2.Y --> imp1.Y (information)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/circ10280.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/circ10280.d(11): Error: circular initialization of variable `circ10280.q10280`\nfail_compilation/circ10280.d(10):        called from here: `foo10280()`\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=10280\n\nconst int q10280 = foo10280();\nint foo10280() { return q10280; }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/class1.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/class1.d(11): Error: class `class1.C` identity assignment operator overload is illegal\n---\n*/\n\nclass C\n{\n    // Non-templated identity opAssign\n    void opAssign(C rhs){}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/class2.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/class2.d(11): Error: class `class2.C` identity assignment operator overload is illegal\n---\n*/\n\nclass C\n{\n    // Templated identity opAssign\n    void opAssign(T)(T rhs){}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/commaexp.d",
    "content": "/* REQUIRED_ARGS: -o-\nTEST_OUTPUT:\n---\nfail_compilation/commaexp.d(27): Error: Using the result of a comma expression is not allowed\nfail_compilation/commaexp.d(39): Error: Using the result of a comma expression is not allowed\nfail_compilation/commaexp.d(40): Error: Using the result of a comma expression is not allowed\nfail_compilation/commaexp.d(41): Error: Using the result of a comma expression is not allowed\nfail_compilation/commaexp.d(42): Error: Using the result of a comma expression is not allowed\nfail_compilation/commaexp.d(44): Error: Using the result of a comma expression is not allowed\nfail_compilation/commaexp.d(45): Error: Using the result of a comma expression is not allowed\nfail_compilation/commaexp.d(56): Error: Using the result of a comma expression is not allowed\nfail_compilation/commaexp.d(69): Error: Using the result of a comma expression is not allowed\nfail_compilation/commaexp.d(81): Error: Using the result of a comma expression is not allowed\n---\n*/\n\nclass Entry {}\nclass MyContainerClass { bool append (Entry) { return false; } }\n\nint main () {\n    bool ok;\n    size_t aggr;\n    MyContainerClass mc;\n\n    // https://issues.dlang.org/show_bug.cgi?id=15997\n    enum WINHTTP_ERROR_BASE = 4200;\n    enum ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED = (WINHTTP_ERROR_BASE, + 44);\n\n    // OK\n    for (size_t i; i < 5; ++i, i += 1) {}\n    for (size_t i; i < 5; ++i, i += 1, i++) {}\n    if (!mc)\n        mc = new MyContainerClass, mc.append(new Entry);\n    if (Object o = cast(Object)mc) {} // Lowering\n    ok = true, mc.append(new Entry);\n    assert(ok);\n\n    // NOPE\n    for (size_t i; i < 5; ++i, i += (i++, 1)) {}\n    for (; aggr++, aggr > 5;) {}\n    if (Object o = (ok = true, null)) {}\n    ok = (true, mc.append(new Entry));\n    assert(!ok);\n    ok = true, (ok = (true, false));\n    return 42, 0;\n}\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16022\n\nbool test16022()\n{\n    enum Type { Colon, Comma }\n    Type type;\n    return type == Type.Colon, type == Type.Comma;\n}\n\nbool test16022_structs()\n{\n    struct A\n    {\n        int i;\n        string s;\n    }\n\n    enum Type { Colon = A(0, \"zero\"), Comma = A(1, \"one\") }\n    Type type;\n    return type == Type.Colon, type == Type.Comma;\n}\n\n/********************************************/\n\n\nvoid bar11(int*, int*) { }\n\nvoid test11()\n{\n    static int* p;\n    static int i;\n    bar11((i,p), &i);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/cppeh1.d",
    "content": "// DISABLED: win32 win64\n/*\nTEST_OUTPUT:\n---\nfail_compilation/cppeh1.d(26): Error: cannot catch C++ class objects in `@safe` code\n---\n*/\n\nversion (Windows) static assert(0, \"This test should not run on this platform\");\n\nextern (C++, std)\n{\n    class exception { }\n}\n\n@safe:\nvoid bar();\nvoid abc();\n\nvoid foo()\n{\n    try\n    {\n        bar();\n    }\n    catch (std.exception e)\n    {\n        abc();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/cppeh2.d",
    "content": "// DISABLED: win32 win64\n/*\nTEST_OUTPUT:\n---\nfail_compilation/cppeh2.d(21): Error: cannot mix catching D and C++ exceptions in the same try-catch\n---\n*/\n\nversion(Windows) static assert(0, \"This test should not run on this platform\");\n\nextern (C++, std)\n{\n    class exception { }\n}\n\nvoid bar();\nvoid abc();\n\nvoid foo()\n{\n    try\n    {\n        bar();\n    }\n    catch (std.exception e)\n    {\n        abc();\n    }\n    catch (Exception e)\n    {\n        abc();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/cppmangle.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/cppmangle.d(10): Error: invalid zero length C++ namespace\nfail_compilation/cppmangle.d(14): Error: expected valid identifer for C++ namespace but got `0num`\nfail_compilation/cppmangle.d(18): Error: string expected following `,` for C++ namespace, not `)`\n---\n*/\n\nextern(C++, \"\")\n{\n}\n\nextern(C++, \"0num\")\n{\n}\n\nextern(C++, \"std\", )\n{\n}\n\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ctfe10989.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ctfe10989.d(11): Error: uncaught CTFE exception `object.Exception(\"abc\"c)`\nfail_compilation/ctfe10989.d(14):        called from here: `throwing()`\nfail_compilation/ctfe10989.d(14):        while evaluating: `static assert(throwing())`\n---\n*/\nint throwing()\n{\n    throw new Exception(['a', 'b', 'c']);\n    return 0;\n}\nstatic assert(throwing());\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ctfe10989.d(33): Error: uncaught CTFE exception `object.Exception(\"abc\"c)`\nfail_compilation/ctfe10989.d(36):        called from here: `throwing2()`\nfail_compilation/ctfe10989.d(36):        while evaluating: `static assert(throwing2())`\n---\n*/\nint throwing2()\n{\n    string msg = \"abc\";\n\n    char[] arr;\n    arr.length = msg.length;\n    arr = arr[0 .. $];\n    arr[] = msg;\n\n    throw new Exception(cast(string)arr);\n    return 0;\n}\nstatic assert(throwing2());\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ctfe10995.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ctfe10995.d(19): Error: cannot read uninitialized variable `a` in CTFE\nfail_compilation/ctfe10995.d(25): Error: cannot read uninitialized variable `a` in CTFE\n---\n*/\nstruct T\n{\n    short a = void;\n}\n\nT foo()\n{\n    auto t = T.init;\n    return t;\n}\n\nenum i = foo().a;\n\nstruct T2\n{\n    short a = void;\n}\nenum i2 = T2.init.a;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ctfe11467.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ctfe11467.d(15): Error: overlapping slice assignment `[0..4] = [1..5]`\nfail_compilation/ctfe11467.d(24):        called from here: `test11467a()`\nfail_compilation/ctfe11467.d(24):        while evaluating: `static assert(test11467a())`\nfail_compilation/ctfe11467.d(21): Error: overlapping slice assignment `[1..5] = [0..4]`\nfail_compilation/ctfe11467.d(25):        called from here: `test11467b()`\nfail_compilation/ctfe11467.d(25):        while evaluating: `static assert(test11467b())`\n---\n*/\nint test11467a()\n{\n    auto a = [0, 1, 2, 3, 4];\n    a[0 .. 4] = a[1 .. 5];\n    return 1;\n}\nint test11467b()\n{\n    auto a = [0, 1, 2, 3, 4];\n    a[1 .. 5] = a[0 .. 4];\n    return 1;\n}\nstatic assert(test11467a());\nstatic assert(test11467b());\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ctfe11467.d(41): Error: overlapping slice assignment `[0..4] = [1..5]`\nfail_compilation/ctfe11467.d(50):        called from here: `test11467c()`\nfail_compilation/ctfe11467.d(50):        while evaluating: `static assert(test11467c())`\nfail_compilation/ctfe11467.d(47): Error: overlapping slice assignment `[1..5] = [0..4]`\nfail_compilation/ctfe11467.d(51):        called from here: `test11467d()`\nfail_compilation/ctfe11467.d(51):        while evaluating: `static assert(test11467d())`\n---\n*/\nint test11467c()\n{\n    auto a = \"abcde\".dup;\n    a[0 .. 4] = a[1 .. 5];\n    return 1;\n}\nint test11467d()\n{\n    auto a = \"abcde\".dup;\n    a[1 .. 5] = a[0 .. 4];\n    return 1;\n}\nstatic assert(test11467c());\nstatic assert(test11467d());\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ctfe13612.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ctfe13612.d(15): Error: function `ctfe13612.S.recurse` CTFE recursion limit exceeded\nfail_compilation/ctfe13612.d(20):        called from here: `s.recurse()`\nfail_compilation/ctfe13612.d(15):        1000 recursive calls to function `recurse`\nfail_compilation/ctfe13612.d(23):        called from here: `(new S).recurse()`\nfail_compilation/ctfe13612.d(23):        while evaluating: `static assert((new S).recurse())`\n---\n*/\n\nclass S\n{\n    int x;\n    int recurse()\n    {\n        S s;\n        assert(!x); // Error: class 'this' is null and cannot be dereferenced\n        s = new S();\n        return s.recurse();\n    }\n}\nstatic assert(new S().recurse());\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ctfe14207.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ctfe14207.d(13): Error: cannot convert `&immutable(ulong)` to `ubyte[8]*` at compile time\nfail_compilation/ctfe14207.d(18):        called from here: `nativeToBigEndian()`\nfail_compilation/ctfe14207.d(22):        called from here: `digest()`\n---\n*/\n\nubyte[8] nativeToBigEndian()\n{\n    immutable ulong res = 1;\n    return *cast(ubyte[8]*) &res;\n}\n\nauto digest()\n{\n    ubyte[8] bits = nativeToBigEndian();\n    return bits;\n}\n\nenum h = digest();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ctfe14465.d",
    "content": "/*\r\nTEST_OUTPUT:\r\n---\r\nfail_compilation/ctfe14465.d(19): Error: uncaught CTFE exception `ctfe14465.E(\"message\")`\r\nfail_compilation/ctfe14465.d(22):        called from here: `foo()`\r\nfail_compilation/ctfe14465.d(22):        while evaluating: `static assert(foo())`\r\n---\r\n*/\r\nclass E : Exception\r\n{\r\n    this(string msg)\r\n    {\r\n        super(msg);\r\n    }\r\n}\r\n\r\nbool foo()\r\n{\r\n    throw new E(\"message\");\r\n}\r\n\r\nstatic assert(foo());\r\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ctfe14731.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ctfe14731.d(16): Error: cannot implicitly convert expression `[\"a b\"]` of type `string[]` to `string`\nfail_compilation/ctfe14731.d(17): Error: cannot implicitly convert expression `split(\"a b\")` of type `string[]` to `string`\n---\n*/\n\nstring[] split(string a)\n{\n    return [a];\n}\n\nvoid main()\n{\n    enum string list1 = \"a b\".split();\n         string list2 = \"a b\".split();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ctypes.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ctypes.d(11): Error: use `real` instead of `long double`\nfail_compilation/ctypes.d(12): Error: use `long` for a 64 bit integer instead of `long long`\n---\n*/\n\nvoid test()\n{\n    long double r;\n    long long ll;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/cwords.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/cwords.d(13): Error: undefined identifier `FALSE`, did you mean `false`?\nfail_compilation/cwords.d(14): Error: undefined identifier `TRUE`, did you mean `true`?\nfail_compilation/cwords.d(15): Error: undefined identifier `NULL`, did you mean `null`?\nfail_compilation/cwords.d(16): Error: undefined identifier `unsigned`, did you mean `uint`?\n---\n*/\n\n\nvoid foo()\n{\n    bool a = FALSE;\n    bool b = TRUE;\n    int* p = NULL;\n    unsigned u;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/dephexstrings.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/dephexstrings.d(8): Deprecation: Built-in hex string literals are deprecated, use `std.conv.hexString` instead.\n---\n*/\nenum xstr = x\"60\";\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/depmsg.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/depmsg.d(40): Deprecation: struct `depmsg.main.Inner.A` is deprecated - With message!\nfail_compilation/depmsg.d(40): Deprecation: struct `depmsg.main.Inner.A` is deprecated - With message!\nfail_compilation/depmsg.d(41): Deprecation: class `depmsg.main.Inner.B` is deprecated - With message!\nfail_compilation/depmsg.d(41): Deprecation: class `depmsg.main.Inner.B` is deprecated - With message!\nfail_compilation/depmsg.d(42): Deprecation: interface `depmsg.main.Inner.C` is deprecated - With message!\nfail_compilation/depmsg.d(42): Deprecation: interface `depmsg.main.Inner.C` is deprecated - With message!\nfail_compilation/depmsg.d(43): Deprecation: union `depmsg.main.Inner.D` is deprecated - With message!\nfail_compilation/depmsg.d(43): Deprecation: union `depmsg.main.Inner.D` is deprecated - With message!\nfail_compilation/depmsg.d(44): Deprecation: enum `depmsg.main.Inner.E` is deprecated - With message!\nfail_compilation/depmsg.d(44): Deprecation: enum `depmsg.main.Inner.E` is deprecated - With message!\nfail_compilation/depmsg.d(46): Deprecation: alias `depmsg.main.Inner.G` is deprecated - With message!\nfail_compilation/depmsg.d(47): Deprecation: variable `depmsg.main.Inner.H` is deprecated - With message!\nfail_compilation/depmsg.d(48): Deprecation: class `depmsg.main.Inner.I!().I` is deprecated - With message!\n---\n*/\n\nvoid main()\n{\n    class Inner\n    {\n        deprecated(\"With message!\")\n        {\n            struct A { }\n            class B { }\n            interface C { }\n            union D { }\n            enum E { e };\n            //typedef int F;\n            alias int G;\n            static int H;\n            template I() { class I {} }\n        }\n    }\n    with(Inner)\n    {\n        A a;\n        B b;\n        C c;\n        D d;\n        E e;\n        //F f;\n        G g;\n        auto h = H;\n        I!() i;\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/depmsg.d(94): Deprecation: function `depmsg.test12954.Foo.bar1` is deprecated - [C] Use Foo.bar42 instead\nfail_compilation/depmsg.d(95): Deprecation: function `depmsg.test12954.Foo.bar2` is deprecated - [E] Use Foo.bar42 instead\nfail_compilation/depmsg.d(96): Deprecation: function `depmsg.test12954.Foo.bar3` is deprecated - [S] Use Foo.bar42 instead\nfail_compilation/depmsg.d(97): Deprecation: function `depmsg.test12954.Foo.bar4` is deprecated - [F] Use Foo.bar42 instead\nfail_compilation/depmsg.d(98): Deprecation: variable `depmsg.test12954.Foo.v2` is deprecated - Forward reference\nfail_compilation/depmsg.d(105): Deprecation: class `depmsg.test12954.Obsolete` is deprecated\nfail_compilation/depmsg.d(105): Deprecation: function `depmsg.test12954.Obsolete.obs` is deprecated - Function is obsolete\n---\n*/\nvoid test12954()\n{\n    struct Foo\n    {\n        enum DeprecatedReasonEnum = \"[E] Use Foo.bar42 instead\";\n        static const DeprecatedReasonStatic = \"[S] Use Foo.bar42 instead\";\n        static immutable DeprecatedReasonFunc = reason(\"Foo.bar42\");\n\n        static string reason (string name)\n        {\n            return \"[F] Use \" ~ name ~ \" instead\";\n        }\n\n        deprecated(\"[C] Use \" ~ `Foo.bar42 instead`)\n        void bar1 () {}\n\n        deprecated(DeprecatedReasonEnum)\n        void bar2 () {}\n\n        deprecated(DeprecatedReasonStatic)\n        void bar3 () {}\n\n        deprecated(DeprecatedReasonFunc)\n        void bar4 () {}\n\n        deprecated(Forward ~ Reference) int v2 = 2;\n        enum Forward = \"Forward \", Reference = \"reference\";\n    }\n\n    Foo f;\n    f.bar1;\n    f.bar2;\n    f.bar3;\n    f.bar4;\n    assert(f.v2 == 2);\n\n    deprecated class Obsolete\n    {\n        deprecated(\"Function is obsolete\") void obs() {}\n    }\n\n    (new Obsolete).obs();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/depmsg15814.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/depmsg15814.d(9): Deprecation: function `depmsg15814.get15814` is deprecated - bug15814\n---\n*/\ndeprecated(\"bug15814\") int get15814() { return 0; }\nenum val15814 = get15814();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/depmsg15815.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/depmsg15815.d(23): Deprecation: alias `depmsg15815.Alias!(const(Foo)).Alias` is deprecated - message\nFoo\n---\n*/\n\ntemplate Unqual(T)\n{\n    static if (is(T U == const U)) alias Unqual = U;\n    else alias Unqual = T;\n}\n\ndeprecated(\"message\")\ntemplate Alias(T)\n{\n    alias Alias = Unqual!T;\n}\n\nstruct Foo {}\npragma(msg, Alias!(const(Foo)));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/deprecate12979a.d",
    "content": "// REQUIRED_ARGS: -de\n// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/deprecate12979a.d(14): Deprecation: `asm` statement is assumed to throw - mark it with `nothrow` if it does not\n---\n*/\n\n\nvoid foo() nothrow\n{\n    version(GNU)\n    {\n        asm { \"\"; }\n    }\n    else\n    {\n        asm\n        {\n            ret;\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/deprecate12979b.d",
    "content": "// REQUIRED_ARGS: -de\n// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/deprecate12979b.d(13): Deprecation: `asm` statement is assumed to be impure - mark it with `pure` if it is not\n---\n*/\n\nvoid foo() pure\n{\n    version(GNU)\n    {\n        asm { \"\"; }\n    }\n    else\n    {\n        asm\n        {\n            ret;\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/deprecate12979c.d",
    "content": "// REQUIRED_ARGS: -de\n// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/deprecate12979c.d(13): Deprecation: `asm` statement is assumed to use the GC - mark it with `@nogc` if it does not\n---\n*/\n\nvoid foo() @nogc\n{\n    version(GNU)\n    {\n        asm { \"\"; }\n    }\n    else\n    {\n        asm\n        {\n            ret;\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/deprecate12979d.d",
    "content": "// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/deprecate12979d.d(12): Error: `asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not\n---\n*/\n\nvoid foo() @safe\n{\n    version(GNU)\n    {\n        asm { \"\"; }\n    }\n    else\n    {\n        asm\n        {\n            ret;\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/deprecate1553.d",
    "content": "// REQUIRED_ARGS: -de\n// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/deprecate1553.d(19): Deprecation: cannot use `foreach_reverse` with a delegate\n---\n*/\n\nstruct S\n{\n    int dg(int delegate(ref int a)) { return 0; }\n}\n\nvoid main()\n{\n    S s;\n    foreach_reverse(a; &s.dg) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/deprecated6760.d",
    "content": "// REQUIRED_ARGS: -de\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/deprecated6760.d(13): Deprecation: `deprecated6760.Foo.opEquals` cannot be annotated with `@disable` because it is overriding a function in the base class\nfail_compilation/deprecated6760.d(18): Deprecation: `deprecated6760.Bar.opEquals` cannot be marked as `deprecated` because it is overriding a function in the base class\n---\n*/\n\nclass Foo\n{\n    @disable override bool opEquals(Object);\n}\n\nclass Bar\n{\n    deprecated override bool opEquals(Object);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/deprecateopdot.d",
    "content": "/*\nREQUIRED_ARGS: -de\nTEST_OUTPUT:\n---\nfail_compilation/deprecateopdot.d(27): Deprecation: `opDot` is deprecated. Use `alias this`\nfail_compilation/deprecateopdot.d(28): Deprecation: `opDot` is deprecated. Use `alias this`\nfail_compilation/deprecateopdot.d(29): Deprecation: `opDot` is deprecated. Use `alias this`\n---\n*/\nstruct S6\n{\n    int a, b;\n}\nstruct T6\n{\n    S6 s;\n\n    S6* opDot()\n    {\n        return &s;\n    }\n}\n\nvoid test6()\n{\n    T6 t;\n    t.a = 4;\n    assert(t.a == 4);\n    t.b = 5;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10089.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10089.d(15): Error: undefined identifier `chunks` in package `imports`\nfail_compilation/diag10089.d(17): Error: template `Foo()` does not have property `chunks`\n---\n*/\n\nimport imports.diag10089a, imports.diag10089b;\n\ntemplate Foo() {}\n\nvoid main()\n{\n    imports.chunks(\"abcdef\", 2);\n\n    Foo.chunks(\"abcdef\", 2);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10099.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10099.d(15): Error: variable `diag10099.main.s` default construction is disabled for type `S`\n---\n*/\n\nstruct S\n{\n    @disable this();\n}\n\nvoid main()\n{\n    S s;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10141.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10141.d(9): Error: module `imports.diag10141a` import `unexisting_symbol` not found\n---\n*/\n\nimport imports.diag10141a;\nimport imports.diag10141a : unexisting_symbol;\n\nTuple!(int) fun()\n{\n    return Tuple!(int).init;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10169.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10169.d(12): Deprecation: `imports.a10169.B.x` is not visible from module `diag10169`\nfail_compilation/diag10169.d(12): Error: struct `imports.a10169.B` member `x` is not accessible\n---\n*/\nimport imports.a10169;\n\nvoid main()\n{\n    auto a = B.init.x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10221.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10221.d(10): Error: cannot implicitly convert expression `256` of type `int` to `ubyte`\n---\n*/\n\nvoid main()\n{\n    foreach(ref ubyte i; 0..256) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10221a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10221a.d(10): Error: cannot implicitly convert expression `257` of type `int` to `ubyte`\n---\n*/\n\nvoid main()\n{\n    foreach(ubyte i; 0..257) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10319.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10319.d(27): Error: `pure` function `D main` cannot call impure function `diag10319.foo`\nfail_compilation/diag10319.d(27): Error: `@safe` function `D main` cannot call `@system` function `diag10319.foo`\nfail_compilation/diag10319.d(16):        `diag10319.foo` is declared here\nfail_compilation/diag10319.d(28): Error: `pure` function `D main` cannot call impure function `diag10319.bar!int.bar`\nfail_compilation/diag10319.d(28): Error: `@safe` function `D main` cannot call `@system` function `diag10319.bar!int.bar`\nfail_compilation/diag10319.d(18):        `diag10319.bar!int.bar` is declared here\nfail_compilation/diag10319.d(27): Error: function `diag10319.foo` is not `nothrow`\nfail_compilation/diag10319.d(28): Error: function `diag10319.bar!int.bar` is not `nothrow`\nfail_compilation/diag10319.d(25): Error: `nothrow` function `D main` may throw\n---\n*/\n\nvoid foo() {}\n\nvoid bar(T)()\n{\n    static int g; g = 10;       // impure\n    int x; auto p = &x;         // system\n    throw new Exception(\"\");    // may throw\n}\n\n@safe pure nothrow void main()  // L23\n{\n    foo();      // L25\n    bar!int();  // L26\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10327.d",
    "content": "import imports.test10327;  // package.d missing\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10359.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10359.d(10): Error: pointer slicing not allowed in safe functions\n---\n*/\n\nvoid foo(int* p) @safe\n{\n    auto a = p[0 .. 10];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10405.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10405.d(10): Error: cannot return non-void from `void` function\n---\n*/\n\nvoid main()\n{\n    return 10;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10415.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10415.d(36): Error: none of the overloads of `x` are callable using argument types `(int) const`, candidates are:\nfail_compilation/diag10415.d(13):        `diag10415.C.x()`\nfail_compilation/diag10415.d(18):        `diag10415.C.x(int _param_0)`\nfail_compilation/diag10415.d(39): Error: d.x is not an lvalue\n---\n*/\n\nclass C\n{\n    @property int x() const\n    {\n        return 0;\n    }\n\n    @property void x(int)\n    {\n    }\n}\n\ntemplate AddProp() { @property int x() { return 1; } }\ntemplate AddFunc() { void x(int, int) {} }\n\nclass D\n{\n    // overloadset\n    mixin AddProp;\n    mixin AddFunc;\n}\n\nvoid main()\n{\n    const c = new C();\n    c.x = 1;\n\n    auto d = new D();\n    d.x = 1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10688.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10688.d(12): Error: function `diag10688.Bar.foo` `private` method is not virtual and cannot override\nfail_compilation/diag10688.d(14): Error: function `diag10688.Bar.bar` `package` method is not virtual and cannot override\n---\n*/\n\nclass Bar\n{\nprivate:\n    override void foo() { }\npackage:\n    override void bar() { }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10768.d",
    "content": "// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10768.d(36): Error: cannot implicitly override base class method `diag10768.Frop.frop` with `diag10768.Foo.frop`; add `override` attribute\n---\n*/\n\nstruct CirBuff(T)\n{\n    import std.traits: isArray;\n    CirBuff!T opAssign(R)(R) if (isArray!R)\n    {}\n\n    T[] toArray()\n    {\n        T[] ret; //  = new T[this.length];\n        return ret;\n    }\n    alias toArray this;\n}\n\nclass Bar(T=int)\n{\n    CirBuff!T _bar;\n}\n\nclass Once\n{\n    Bar!Foo _foobar;\n}\n\nclass Foo : Frop\n{\n    // override\n    public int frop() { return 1; }\n}\n\nclass Frop\n{\n    public int frop() { return 0; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10783.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10783.d(14): Error: no property `type` for type `Event`\nfail_compilation/diag10783.d(14): Error: undefined identifier `En`\n---\n*/\n\nstruct Event { }\n\nvoid main()\n{\n    Event event;\n    switch (event.type) with (En)\n    {\n        default:\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10792.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10792.d(9): Error: semicolon expected following auto declaration, not `End of File`\n---\n*/\n\nenum isPred(T) = asdf\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10805.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10805.d(11): Error: delimited string must end in FOO\"\nfail_compilation/diag10805.d(13): Error: unterminated string constant starting at fail_compilation/diag10805.d(13)\nfail_compilation/diag10805.d(13): Error: Implicit string concatenation is deprecated, use \"\" ~ \"\" instead\nfail_compilation/diag10805.d(14): Error: semicolon expected following auto declaration, not `End of File`\n---\n*/\n\nenum s = q\"FOO\nFOO\n\";\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10862.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10862.d(40): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(41): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(42): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(43): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(44): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(46): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(47): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(48): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(49): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(51): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(52): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(53): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(54): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(56): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(57): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(58): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(59): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(61): Error: undefined identifier `semanticError`\nfail_compilation/diag10862.d(71): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d(74): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d-mixin-77(77): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d-mixin-78(78): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d-mixin-79(79): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d-mixin-80(80): Error: Using the result of a comma expression is not allowed\nfail_compilation/diag10862.d-mixin-80(80): Error: assignment cannot be used as a condition, perhaps `==` was meant?\nfail_compilation/diag10862.d-mixin-83(83): Error: `a + b` is not an lvalue and cannot be modified\nfail_compilation/diag10862.d-mixin-84(84): Error: undefined identifier `c`\nfail_compilation/diag10862.d(86): Error: undefined identifier `semanticError`\nfail_compilation/diag10862.d(93): Error: lazy variable `bar` cannot be modified\nfail_compilation/diag10862.d(95): Error: template instance `diag10862.test3.foo!int` error instantiating\n---\n*/\nvoid test1()\n{\n    int a, b;\n\n    if (a = b) {}\n    if ((a = b) = 0) {}\n    if ((a = b) = (a = b)) {}\n    if (a = 0, b = 0) {}        // https://issues.dlang.org/show_bug.cgi?id=15384\n    if (auto x = a = b) {}      // this is error, today\n\n    while (a = b) {}\n    while ((a = b) = 0) {}\n    while ((a = b) = (a = b)) {}\n    while (a = 0, b = 0) {}     // https://issues.dlang.org/show_bug.cgi?id=15384\n\n    do {} while (a = b);\n    do {} while ((a = b) = 0);\n    do {} while ((a = b) = (a = b));\n    do {} while (a = 0, b = 0); // https://issues.dlang.org/show_bug.cgi?id=15384\n\n    for (;  a = b; ) {}\n    for (;  (a = b) = 0; ) {}\n    for (;  (a = b) = (a = b); ) {}\n    for (;  a = 0, b = 0; ) {}  // https://issues.dlang.org/show_bug.cgi?id=15384\n\n    semanticError;\n}\n\nvoid test2()\n{\n    int a, b;\n\n    // (a + b) cannot be an assignment target.\n    // However checkAssignAsCondition specilatively rerites it to EqualExp,\n    // then the pointless error \"is not an lvalue\" would not happen.\n    if (a + b = a * b) {}\n\n    // The suggestion error masks \"undefined identifier\" error\n    if (a = undefinedIdentifier) {}\n\n    // If the condition is a mixin expression\n    if (mixin(\"a = b\")) {}\n    if (mixin(\"(a = b) = 0\")) {}\n    if (mixin(\"(a = b) = (a = b)\")) {}\n    if (mixin(\"a = 0, b = 0\")) {}\n    if (auto x = mixin(\"a = b\")) {}     // Note: no error\n\n    if (mixin(\"a + b = a * b\")) {}      // Note: \"a + b is not an lvalue\"\n    if (mixin(\"a = c\")) {}\n\n    semanticError;\n}\n\nvoid test3()\n{\n    void foo(T)(lazy T bar)\n    {\n        bar = 2;\n    }\n    foo(1 + 1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10926.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10926.d(11): Error: `cast(const(int)[])c` is not an lvalue and cannot be modified\n---\n*/\n\nvoid main() {\n    const(int)[] a, b;\n    int[] c, d;\n    (true ? a : c) ~= 20; // line 6, Error: a is not an lvalue\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag10984.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag10984.d(11): Error: static function diag10984.f.n cannot access frame of function diag10984.f\n---\n*/\n\nvoid f()\n{\n    int x;\n    static void n() { x++; }\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11078.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11078.d(19): Error: none of the overloads of `value` are callable using argument types `(double)`, candidates are:\nfail_compilation/diag11078.d(12):        `diag11078.S1.value()`\nfail_compilation/diag11078.d(13):        `diag11078.S1.value(int n)`\n---\n*/\n\nstruct S1\n{\n    @property int value() { return 1; }\n    @property void value(int n) { }\n}\n\nvoid main()\n{\n    S1 s1;\n    s1.value = 1.0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11132.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11132.d(22): Error: overlapping initialization for field `a` and `b`\n---\n*/\n\nstruct S\n{\n    int x;\n    union\n    {\n        int a;\n        int b;\n    }\n\n    int z;\n}\n\nvoid main()\n{\n    S s = { 1, 2, 3 };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11198.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11198.d(11): Error: version conditions can only be declared at module scope\nfail_compilation/diag11198.d(12): Error: debug conditions can only be declared at module scope\n---\n*/\n\nvoid main()\n{\n    version = blah;\n    debug = blah;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11423.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11423.d(9): Error: undefined identifier `Foo`\n---\n*/\nvoid main()\n{\n    auto foo = new shared Foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11425.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11425.d(13): Error: variable `x` is shadowing variable `diag11425.main.x`\n---\n*/\n\nvoid main()\n{\n    int x;\n\n    {\n        int x = 1;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11727.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11727.d(10): Error: type `n` is not an expression\n---\n*/\nauto returnEnum()\n{\n    enum n;\n    return n;\n}\nvoid main()\n{\n    assert(returnEnum() == 0);\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11727.d(26): Error: type `void` is not an expression\n---\n*/\nauto returnVoid()\n{\n    alias v = void;\n    return v;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11727.d(38): Error: template `t()` has no type\n---\n*/\nauto returnTemplate()\n{\n    template t() {}\n    return t;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11756.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11756.d(15): Error: cannot read uninitialized variable `cnt` in CTFE\nfail_compilation/diag11756.d(34):        called from here: `foo.ptr2.opAssign(Ptr(& n))`\nfail_compilation/diag11756.d(39):        called from here: `test()`\nfail_compilation/diag11756.d(39):        while evaluating: `static assert(test())`\n---\n*/\n\nstruct Ptr\n{\n    void opAssign(Ptr other)\n    {\n        (*cnt)--;   // error\n        cnt = other.cnt;\n        (*cnt)++;\n    }\n    size_t *cnt;\n}\n\nunion Foo\n{\n    size_t *ptr1;\n    Ptr ptr2;\n}\n\nbool test()\n{\n    Foo foo;\n    size_t cnt = 1;\n    foo.ptr1 = &cnt;\n    size_t n;\n    foo.ptr2 = Ptr(&n);\n    assert(cnt == 0);\n\n    return true;\n}\nstatic assert(test());\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11759.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11759.d(8): Error: lower case integer suffix 'l' is not allowed. Please use 'L' instead\n---\n*/\n\nulong x = 123ul;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11769.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11769.d(18): Error: `diag11769.foo!string.bar` called with argument types `(string)` matches both:\nfail_compilation/diag11769.d(13):     `diag11769.foo!string.bar(wstring _param_0)`\nand:\nfail_compilation/diag11769.d(14):     `diag11769.foo!string.bar(dstring _param_0)`\n---\n*/\n\ntemplate foo(T)\n{\n    void bar(wstring) {}\n    void bar(dstring) {}\n}\nvoid main()\n{\n    foo!string.bar(\"abc\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11819a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11819a.d(30): Error: unrecognized trait `DoesNotExist`\nfail_compilation/diag11819a.d(31): Error: unrecognized trait `IsAbstractClass`, did you mean `isAbstractClass`?\nfail_compilation/diag11819a.d(32): Error: unrecognized trait `IsArithmetic`, did you mean `isArithmetic`?\nfail_compilation/diag11819a.d(33): Error: unrecognized trait `IsAssociativeArray`, did you mean `isAssociativeArray`?\nfail_compilation/diag11819a.d(34): Error: unrecognized trait `IsFinalClass`, did you mean `isFinalClass`?\nfail_compilation/diag11819a.d(35): Error: unrecognized trait `IsPOD`, did you mean `isPOD`?\nfail_compilation/diag11819a.d(36): Error: unrecognized trait `IsNested`, did you mean `isNested`?\nfail_compilation/diag11819a.d(37): Error: unrecognized trait `IsFloating`, did you mean `isFloating`?\nfail_compilation/diag11819a.d(38): Error: unrecognized trait `IsIntegral`, did you mean `isIntegral`?\nfail_compilation/diag11819a.d(39): Error: unrecognized trait `IsScalar`, did you mean `isScalar`?\nfail_compilation/diag11819a.d(40): Error: unrecognized trait `IsStaticArray`, did you mean `isStaticArray`?\nfail_compilation/diag11819a.d(41): Error: unrecognized trait `IsUnsigned`, did you mean `isUnsigned`?\nfail_compilation/diag11819a.d(42): Error: unrecognized trait `IsVirtualFunction`, did you mean `isVirtualFunction`?\nfail_compilation/diag11819a.d(43): Error: unrecognized trait `IsVirtualMethod`, did you mean `isVirtualMethod`?\nfail_compilation/diag11819a.d(44): Error: unrecognized trait `IsAbstractFunction`, did you mean `isAbstractFunction`?\nfail_compilation/diag11819a.d(45): Error: unrecognized trait `IsFinalFunction`, did you mean `isFinalFunction`?\nfail_compilation/diag11819a.d(46): Error: unrecognized trait `IsOverrideFunction`, did you mean `isOverrideFunction`?\nfail_compilation/diag11819a.d(47): Error: unrecognized trait `IsStaticFunction`, did you mean `isStaticFunction`?\nfail_compilation/diag11819a.d(48): Error: unrecognized trait `IsRef`, did you mean `isRef`?\nfail_compilation/diag11819a.d(49): Error: unrecognized trait `IsOut`, did you mean `isOut`?\nfail_compilation/diag11819a.d(50): Error: unrecognized trait `IsLazy`, did you mean `isLazy`?\n---\n*/\n\nvoid main()\n{\n    if (__traits(DoesNotExist)) { }\n    if (__traits(IsAbstractClass)) { }\n    if (__traits(IsArithmetic)) { }\n    if (__traits(IsAssociativeArray)) { }\n    if (__traits(IsFinalClass)) { }\n    if (__traits(IsPOD)) { }\n    if (__traits(IsNested)) { }\n    if (__traits(IsFloating)) { }\n    if (__traits(IsIntegral)) { }\n    if (__traits(IsScalar)) { }\n    if (__traits(IsStaticArray)) { }\n    if (__traits(IsUnsigned)) { }\n    if (__traits(IsVirtualFunction)) { }\n    if (__traits(IsVirtualMethod)) { }\n    if (__traits(IsAbstractFunction)) { }\n    if (__traits(IsFinalFunction)) { }\n    if (__traits(IsOverrideFunction)) { }\n    if (__traits(IsStaticFunction)) { }\n    if (__traits(IsRef)) { }\n    if (__traits(IsOut)) { }\n    if (__traits(IsLazy)) { }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11819b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11819b.d(28): Error: unrecognized trait `HasMember`, did you mean `hasMember`?\nfail_compilation/diag11819b.d(29): Error: unrecognized trait `Identifier`, did you mean `identifier`?\nfail_compilation/diag11819b.d(30): Error: unrecognized trait `GetProtection`, did you mean `getProtection`?\nfail_compilation/diag11819b.d(31): Error: unrecognized trait `Parent`, did you mean `parent`?\nfail_compilation/diag11819b.d(32): Error: unrecognized trait `GetMember`, did you mean `getMember`?\nfail_compilation/diag11819b.d(33): Error: unrecognized trait `GetOverloads`, did you mean `getOverloads`?\nfail_compilation/diag11819b.d(34): Error: unrecognized trait `GetVirtualFunctions`, did you mean `getVirtualFunctions`?\nfail_compilation/diag11819b.d(35): Error: unrecognized trait `GetVirtualMethods`, did you mean `getVirtualMethods`?\nfail_compilation/diag11819b.d(36): Error: unrecognized trait `ClassInstanceSize`, did you mean `classInstanceSize`?\nfail_compilation/diag11819b.d(37): Error: unrecognized trait `AllMembers`, did you mean `allMembers`?\nfail_compilation/diag11819b.d(38): Error: unrecognized trait `DerivedMembers`, did you mean `derivedMembers`?\nfail_compilation/diag11819b.d(39): Error: unrecognized trait `IsSame`, did you mean `isSame`?\nfail_compilation/diag11819b.d(40): Error: unrecognized trait `Compiles`, did you mean `compiles`?\nfail_compilation/diag11819b.d(41): Error: unrecognized trait `Parameters`, did you mean `parameters`?\nfail_compilation/diag11819b.d(42): Error: unrecognized trait `GetAliasThis`, did you mean `getAliasThis`?\nfail_compilation/diag11819b.d(43): Error: unrecognized trait `GetAttributes`, did you mean `getAttributes`?\nfail_compilation/diag11819b.d(44): Error: unrecognized trait `GetFunctionAttributes`, did you mean `getFunctionAttributes`?\nfail_compilation/diag11819b.d(45): Error: unrecognized trait `GetUnitTests`, did you mean `getUnitTests`?\nfail_compilation/diag11819b.d(46): Error: unrecognized trait `GetVirtualIndex`, did you mean `getVirtualIndex`?\n---\n*/\n\nvoid main()\n{\n    if (__traits(HasMember)) { }\n    if (__traits(Identifier)) { }\n    if (__traits(GetProtection)) { }\n    if (__traits(Parent)) { }\n    if (__traits(GetMember)) { }\n    if (__traits(GetOverloads)) { }\n    if (__traits(GetVirtualFunctions)) { }\n    if (__traits(GetVirtualMethods)) { }\n    if (__traits(ClassInstanceSize)) { }\n    if (__traits(AllMembers)) { }\n    if (__traits(DerivedMembers)) { }\n    if (__traits(IsSame)) { }\n    if (__traits(Compiles)) { }\n    if (__traits(Parameters)) { }\n    if (__traits(GetAliasThis)) { }\n    if (__traits(GetAttributes)) { }\n    if (__traits(GetFunctionAttributes)) { }\n    if (__traits(GetUnitTests)) { }\n    if (__traits(GetVirtualIndex)) { }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag11840.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag11840.d(12): Error: undefined identifier `i`\nfail_compilation/diag11840.d(12): Error: undefined identifier `j`\n---\n*/\n\nvoid main()\n{\n    int[10] data;\n    data[i .. j] = 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12063.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12063.d(11): Error: no property `max` for type `Foo`\nfail_compilation/diag12063.d(14): Error: incompatible types for `(Foo()) + (1)`: `Bar` and `int`\n---\n*/\n\nstruct Foo {}\n\nenum Bar : Foo\n{\n    a = Foo(),\n    b\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12124.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12124.d(14): Error: struct `diag12124.S1` `static opCall` is hidden by constructors and can never be called\nfail_compilation/diag12124.d(14):        Please use a factory method instead, or replace all constructors with `static opCall`.\nfail_compilation/diag12124.d(20): Error: struct `diag12124.S2` `static opCall` is hidden by constructors and can never be called\nfail_compilation/diag12124.d(20):        Please use a factory method instead, or replace all constructors with `static opCall`.\n---\n*/\n\nstruct S1\n{\n    this(int) {}\n    static S1 opCall() { assert(0); }\n}\n\nstruct S2\n{\n    this(int) {}\n    static S2 opCall()() { assert(0); }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12280.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12280.d(15): Error: undefined identifier `nonexistent`\nfail_compilation/diag12280.d(13): Error: template instance `diag12280.f!10` error instantiating\nfail_compilation/diag12280.d(18):        11 recursive instantiations from here: `f!0`\n---\n*/\n\nvoid f(int i)()\n{\n    static if (i < 10)\n        f!(i + 1);\n    else\n        nonexistent();\n}\n\nalias f0 = f!0;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12312.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12312.d(10): Error: variable `diag12312.main.arr` `void[16]` does not have a default initializer\n---\n*/\n\nvoid main()\n{\n    void[16] arr;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12380.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12380.d(12): Error: cannot implicitly convert expression `cast(E)0` of type `E` to `void*`\n---\n*/\n\nenum E { a, b, }\n\nvoid main()\n{\n    void* a = E.init;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12432.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12432.d(55): Error: cannot infer argument types, expected 1 argument, not 2\nfail_compilation/diag12432.d(56): Error: cannot infer argument types, expected 2 arguments, not 3\nfail_compilation/diag12432.d(57): Error: cannot infer argument types, expected 1 argument, not 2\nfail_compilation/diag12432.d(58): Error: cannot infer argument types, expected 1 argument, not 2\nfail_compilation/diag12432.d(59): Error: cannot infer argument types, expected 2 arguments, not 3\nfail_compilation/diag12432.d(60): Error: cannot infer argument types, expected 2 arguments, not 3\n---\n*/\n\nstruct R1\n{\n    @property int front() { return 0; }\n    enum bool empty = false;\n    void popFront() { }\n}\n\nstruct Tuple(T...)\n{\n    T t;\n    alias t this;\n}\n\nstruct R2\n{\n    @property Tuple!(int, float) front() { return typeof(return).init; }\n    enum bool empty = false;\n    void popFront() { }\n}\n\nstruct OpApply1Func\n{\n    int opApply(int function(int)) { return 0; }\n}\n\nstruct OpApply1Deleg\n{\n    int opApply(int delegate(int)) { return 0; }\n}\n\nstruct OpApply2Func\n{\n    int opApply(int function(int, float)) { return 0; }\n}\n\nstruct OpApply2Deleg\n{\n    int opApply(int delegate(int, float)) { return 0; }\n}\n\nvoid main()\n{\n    foreach (a, b; R1()) { }\n    foreach (a, b, c; R2()) { }\n    foreach (a, b; OpApply1Func()) { }\n    foreach (a, b; OpApply1Deleg()) { }\n    foreach (a, b, c; OpApply2Func()) { }\n    foreach (a, b, c; OpApply2Deleg()) { }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12480.d",
    "content": "// REQUIRED_ARGS: -m32\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12480.d(12): Error: static assert:  `2u == 3u` is false\n---\n*/\n\nmodule diag12480;\n\nstatic immutable arr = [\"a\", \"b\"];\nstatic assert(arr.length == 3);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12487.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12487.d(15): Error: recursive expansion of template instance `diag12487.recTemplate!int`\nfail_compilation/diag12487.d(25): Error: template instance `diag12487.recTemplate!int` error instantiating\nfail_compilation/diag12487.d(18): Error: function `diag12487.recFunction` CTFE recursion limit exceeded\nfail_compilation/diag12487.d(20):        called from here: `recFunction(i)`\nfail_compilation/diag12487.d(18):        1000 recursive calls to function `recFunction`\nfail_compilation/diag12487.d(27):        called from here: `recFunction(0)`\n---\n*/\n\ntemplate recTemplate(T)\n{\n    enum bool recTemplate = recTemplate!T;\n}\n\nbool recFunction(int i)\n{\n    return recFunction(i);\n}\n\nvoid main()\n{\n    enum bool value1 = recTemplate!int;\n\n    enum bool value2 = recFunction(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12598.d",
    "content": "/*\nREQUIRED_ARGS: -transition=import\nTEST_OUTPUT:\n---\nfail_compilation/diag12598.d(14): Error: `lines` is a `struct` definition and cannot be modified\n---\n*/\n\nclass C\n{\n    void f()\n    {\n        import imports.diag12598a;\n        lines ~= \"\";\n    }\n\n    string[] lines;\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12640.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12640.d(14): Error: undefined identifier `asdf`\nfail_compilation/diag12640.d(23): Error: undefined identifier `asdf`\n---\n*/\n\nvoid main()\n{\n    switch (1)\n    {\n        case 0:\n            asdf;\n            break;\n\n        default:\n    }\n\n    switch (1)\n    {\n        default:\n            asdf;\n            break;\n\n        case 0:\n    }\n\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12678.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12678.d(21): Error: const field `cf1` initialized multiple times\nfail_compilation/diag12678.d(20):        Previous initialization is here.\nfail_compilation/diag12678.d(24): Error: immutable field `if1` initialized multiple times\nfail_compilation/diag12678.d(23):        Previous initialization is here.\nfail_compilation/diag12678.d(27): Error: const field `cf2` initialization is not allowed in loops or after labels\n---\n*/\n\nstruct S\n{\n    const int cf1;\n    const int cf2;\n    immutable int if1;\n\n    this(int x)\n    {\n        cf1 = x;\n        cf1 = x;\n\n        if1 = x;\n        if1 = x;\n\n        foreach (i; 0 .. 5)\n            cf2 = x;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12777.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12777.d(14): Error: cannot modify `this.v` in `const` function\nfail_compilation/diag12777.d(15): Error: cannot modify `this.v` in `immutable` function\nfail_compilation/diag12777.d(21): Error: cannot modify `this.v` in `const` function\nfail_compilation/diag12777.d(22): Error: cannot modify `this.v` in `immutable` function\n---\n*/\n\nstruct S\n{\n    int v;\n    void fun() const     { v++; }\n    void gun() immutable { v++; }\n}\n\nclass C\n{\n    int v;\n    void fun() const     { v++; }\n    void gun() immutable { v++; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag12829.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag12829.d(12): Error: function `diag12829.test1` is `@nogc` yet allocates closures with the GC\nfail_compilation/diag12829.d(15):        diag12829.test1.__lambda1 closes over variable x at fail_compilation/diag12829.d(14)\nfail_compilation/diag12829.d(19):        diag12829.test1.bar closes over variable x at fail_compilation/diag12829.d(14)\nfail_compilation/diag12829.d(26): Error: function `diag12829.test2` is `@nogc` yet allocates closures with the GC\nfail_compilation/diag12829.d(31):        diag12829.test2.S.foo closes over variable x at fail_compilation/diag12829.d(28)\n---\n*/\n\nauto test1() @nogc\n{\n    int x;\n    void delegate() @nogc foo = () {\n        int y = x;\n    };\n\n    void bar()\n    {\n        int y = x;\n    }\n    auto dg = &bar;\n}\n\nauto test2() @nogc\n{\n    int x;\n    struct S\n    {\n        void foo()\n        {\n            int y = x;\n        }\n    }\n    return S();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13028.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag13028.d(15): Error: variable `dg` cannot be read at compile time\nfail_compilation/diag13028.d(22): Error: variable `a` cannot be read at compile time\nfail_compilation/diag13028.d(28): Error: CTFE failed because of previous errors in `foo`\nfail_compilation/diag13028.d(28):        while evaluating: `static assert(foo(() => 1) == 1)`\nfail_compilation/diag13028.d(29): Error: CTFE failed because of previous errors in `bar`\nfail_compilation/diag13028.d(29):        while evaluating: `static assert(bar(delegate int() => 1) == 1)`\n---\n*/\n\nint foo(int delegate() dg)\n{\n    enum b = dg();\n    return b;\n}\n\n\nint bar(lazy int a)\n{\n    enum b = a;\n    return a;\n}\n\nvoid main()\n{\n    static assert(foo(() => 1) == 1);\n    static assert(bar(1) == 1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13082.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag13082.d(24): Error: constructor `diag13082.C.this(int a)` is not callable using argument types `(string)`\nfail_compilation/diag13082.d(24):        cannot pass argument `b` of type `string` to parameter `int a`\nfail_compilation/diag13082.d(25): Error: constructor `diag13082.S.this(int a)` is not callable using argument types `(string)`\nfail_compilation/diag13082.d(25):        cannot pass argument `b` of type `string` to parameter `int a`\n---\n*/\n\nclass C\n{\n    this(int a) {}\n}\n\nstruct S\n{\n    this(int a) {}\n}\n\nvoid main()\n{\n    string b;\n    auto c = new C(b);\n    auto s = new S(b);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13142.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag13142.d(25): Error: cannot implicitly convert expression `3` of type `int` to `TYPE`\n---\n*/\n\nclass Button\n{\n    enum TYPE // button type\n    {\n        COMMAND,\n        CHECK,\n        OPTION,\n    }\n}\n\nclass Toolbar\n{\n    enum ButtonTYPE // button type\n    {\n        COMMAND   = Button.TYPE.COMMAND,\n        CHECK     = Button.TYPE.CHECK,\n        OPTION    = Button.TYPE.OPTION,\n        DELIMETER = Button.TYPE.max + 1\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13281.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag13281.d(20): Error: cannot implicitly convert expression `123` of type `int` to `string`\nfail_compilation/diag13281.d(21): Error: cannot implicitly convert expression `123u` of type `uint` to `string`\nfail_compilation/diag13281.d(22): Error: cannot implicitly convert expression `123L` of type `long` to `string`\nfail_compilation/diag13281.d(23): Error: cannot implicitly convert expression `123LU` of type `ulong` to `string`\nfail_compilation/diag13281.d(24): Error: cannot implicitly convert expression `123.4` of type `double` to `int`\nfail_compilation/diag13281.d(25): Error: cannot implicitly convert expression `123.4F` of type `float` to `int`\nfail_compilation/diag13281.d(26): Error: cannot implicitly convert expression `123.4L` of type `real` to `int`\nfail_compilation/diag13281.d(27): Error: cannot implicitly convert expression `123.4i` of type `idouble` to `int`\nfail_compilation/diag13281.d(28): Error: cannot implicitly convert expression `123.4Fi` of type `ifloat` to `int`\nfail_compilation/diag13281.d(29): Error: cannot implicitly convert expression `123.4Li` of type `ireal` to `int`\nfail_compilation/diag13281.d(30): Error: cannot implicitly convert expression `(123.4+5.6i)` of type `cdouble` to `int`\nfail_compilation/diag13281.d(31): Error: cannot implicitly convert expression `(123.4F+5.6Fi)` of type `cfloat` to `int`\nfail_compilation/diag13281.d(32): Error: cannot implicitly convert expression `(123.4L+5.6Li)` of type `creal` to `int`\n---\n*/\n\nstring x1 = 123;\nstring x2 = 123u;\nstring x3 = 123L;\nstring x4 = 123uL;\nint y1 = 123.4;\nint y2 = 123.4f;\nint y3 = 123.4L;\nint y4 = 123.4i;\nint y5 = 123.4fi;\nint y6 = 123.4Li;\nint y7 = 123.4 +5.6i;\nint y8 = 123.4f+5.6fi;\nint y9 = 123.4L+5.6Li;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13320.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag13320.d(13): Error: `f` is not a scalar, it is a `Foo`\n---\n*/\n\nstruct Foo {}\n\nvoid main()\n{\n    Foo f;\n    ++f;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13333.d",
    "content": "/*\nTEST_OUTPUT*\n---\nfail_compilation/diag13333.d(29): Error: template instance `VariantN!(maxSize!(S), T)` recursive template expansion\nfail_compilation/diag13333.d(29): Error: template instance `diag13333.maxSize!(S)` error instantiating\nfail_compilation/diag13333.d(34):        instantiated from here: `Algebraic!(S)`\n---\n*/\n\ntemplate maxSize(T...)\n{\n    static if (T.length == 1)\n    {\n        enum size_t maxSize = T[0].sizeof;\n    }\n    else\n    {\n        enum size_t maxSize = T[0].sizeof >= maxSize!(T[1 .. $])\n            ? T[0].sizeof : maxSize!(T[1 .. $]);\n    }\n}\n\nstruct VariantN(size_t maxDataSize, AllowedTypesX...)\n{\n}\n\ntemplate Algebraic(T...)\n{\n    alias Algebraic = VariantN!(maxSize!T, T);\n}\n\nstruct DummyScope\n{\n    alias A = Algebraic!S;\n\n    static struct S     // <- class\n    {\n        A entity;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13528.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag13528.d(13): Error: value of `this` is not known at compile time\nfail_compilation/diag13528.d(13):        while evaluating `pragma(msg, __traits(getMember, A, \"foo\"))`\n---\n*/\n\nmixin template MyTemplate()\n{\n    void foo()\n    {\n        pragma(msg, __traits(getMember, typeof(this), \"foo\"));\n    }\n}\n\nclass A\n{\n    mixin MyTemplate;\n}\n\nvoid main()\n{\n    auto a = new A();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13609a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag13609a.d(11): Error: `}` expected following members in `class` declaration at fail_compilation/diag13609a.d(8)\n---\n*/\n\nclass C\n{\n    void foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13609b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag13609b.d(10): Error: base classes are not allowed for `struct`, did you mean `;`?\nfail_compilation/diag13609b.d(11): Error: basic type expected, not `End of File`\nfail_compilation/diag13609b.d(11): Error: { } expected following `struct` declaration\n---\n*/\n\nstruct S :\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13787.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag13787.d(12): Error: cannot slice function pointer `& main`\nfail_compilation/diag13787.d(13): Error: cannot index function pointer `& main`\n---\n*/\n\nvoid main()\n{\n    auto a = (&main)[0..1];\n    auto x = (&main)[0];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13884.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag13884.d(14): Error: functions cannot return a tuple\nfail_compilation/diag13884.d(21):        instantiated from here: `MapResult!((t) => t.tupleof, Foo[])`\nfail_compilation/diag13884.d(14):        instantiated from here: `map!(Foo[])`\n---\n*/\n\nstruct Foo { int x; }\n\nvoid main()\n{\n    [Foo(1)].map!(t => t.tupleof);\n}\n\ntemplate map(fun...)\n{\n    auto map(Range)(Range r)\n    {\n        return MapResult!(fun, Range)(r);\n    }\n}\n\nstruct MapResult(alias fun, R)\n{\n    R _input;\n\n    @property auto ref front()\n    {\n        return fun(_input[0]);\n    }\n\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag13942.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag13942.d(18): Error: template instance `isRawStaticArray!()` does not match template declaration `isRawStaticArray(T, A...)`\nfail_compilation/diag13942.d(26): Error: template `diag13942.to!double.to` cannot deduce function from argument types `!()()`, candidates are:\nfail_compilation/diag13942.d(17):        `diag13942.to!double.to(A...)(A args) if (!isRawStaticArray!A)`\n---\n*/\n\ntemplate isRawStaticArray(T, A...)\n{\n    enum isRawStaticArray = false;\n}\n\ntemplate to(T)\n{\n    T to(A...)(A args)\n        if (!isRawStaticArray!A)\n    {\n        return 0;\n    }\n}\n\nvoid main(string[] args)\n{\n    auto t = to!double();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag14102.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag14102.d(14): Error: `-x` is not an lvalue and cannot be modified\nfail_compilation/diag14102.d(15): Error: `-(x -= 1)` is not an lvalue and cannot be modified\nfail_compilation/diag14102.d(16): Error: `-(x -= 1 -= 1)` is not an lvalue and cannot be modified\nfail_compilation/diag14102.d(17): Error: `-(x -= 1 -= 1 -= 1)` is not an lvalue and cannot be modified\n---\n*/\n\nint main()\n{\n    int x;\n    return -- -x;           // error: -x is not an lvalue\n    return -- - --x;        // error: -(x -= 1) is not an lvalue\n    return -- - -- --x;     // error: -((x -= 1 , x) -= 1) is not an lvalue\n    return -- - -- -- --x;  // error: -((ref int __assignop1 = x -= 1 , __assignop1 = x; , __assignop1 -= 1 , __assignop1) -= 1) is not an lvalue\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag14163.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag14163.d(16): Error: constructor `diag14163.Bar.this` cannot call `super()` implicitly because it is annotated with `@disable`\n---\n*/\n\nclass Foo\n{\n    @disable this();\n}\n\nclass Bar : Foo\n{\n    @disable this();\n    this(int i) {}\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag14235.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag14235.d(11): Error: template identifier `Undefined` is not a member of module `imports.a14235`\nfail_compilation/diag14235.d(12): Error: template identifier `Something` is not a member of module `imports.a14235`, did you mean struct `SomeThing(T...)`?\nfail_compilation/diag14235.d(13): Error: `imports.a14235.SomeClass` is not a template, it is a class\n---\n*/\n\nimport imports.a14235;\nimports.a14235.Undefined!Object a;\nimports.a14235.Something!Object b;\nimports.a14235.SomeClass!Object c;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag14818.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag14818.d(34): Error: none of the overloads of `func` are callable using argument types `(string)`, candidates are:\nfail_compilation/diag14818.d(12):        `diag14818.foo(int _param_0)`\nfail_compilation/diag14818.d(13):        `diag14818.bar(double _param_0)`\nfail_compilation/diag14818.d(35): Error: overload alias `diag14818.X` does not match any template declaration\nfail_compilation/diag14818.d(36): Error: overloadset `diag14818.M` does not match any template declaration\n---\n*/\n\nvoid foo(int) {}\nvoid bar(double) {}\nalias func = foo;\nalias func = bar;\n// in here, func is a FuncAliasDeclaration;\n\ntemplate Foo(T) if (is(T == int)) {}\ntemplate Bar(T) if (is(T == double)) {}\n\nalias X = Foo;\nalias X = Bar;\n// in here, X is an OverDeclaration\n\ntemplate Mix1() { alias M = Foo; }\ntemplate Mix2() { alias M = Bar; }\nmixin Mix1;\nmixin Mix2;\nalias Y = M;\n// in here, Y is an OverloadSet\n\nvoid main()\n{\n    func(\"abc\");\n    alias x = X!string;\n    alias y = Y!string;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag14875.d",
    "content": "// REQUIRED_ARGS: -o-\n\ndeprecated class Dep { }\ndeprecated immutable int depVar = 10;\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag14875.d(16): Deprecation: class `diag14875.Dep` is deprecated\n1: Dep\n2: Dep\n3: Dep\n---\n*/\n\nalias X = Foo!Dep;              // deprecation\n\ntemplate Foo(T)\n{\n    pragma(msg, \"1: \", T);      // no message\n    enum Foo = cast(void*)Bar!T;\n}\ntemplate Bar(T)\n{\n    pragma(msg, \"2: \", T);      // no message\n    enum Bar = &Baz!T;\n}\ntemplate Baz(T)\n{\n    pragma(msg, \"3: \", T);      // no message\n    immutable Baz = 1234;\n}\n\n// ---\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag14875.d(47): Deprecation: class `diag14875.Dep` is deprecated\nfail_compilation/diag14875.d(51): Deprecation: variable `diag14875.depVar` is deprecated\n4: Dep\nfail_compilation/diag14875.d(58): Deprecation: variable `diag14875.depVar` is deprecated\nfail_compilation/diag14875.d(59): Deprecation: variable `diag14875.Vaz!(Dep).Vaz` is deprecated\n---\n*/\n\nalias Y = Voo!Dep;              // deprecation\n\ntemplate Voo(T)\n{\n    enum n = depVar;            // deprecation\n    struct A { alias B = T; }   // no message\n    pragma(msg, \"4: \", A.B);    // B is not deprecated\n    enum Voo = cast(void*)Var!T;\n}\ntemplate Var(T)\n{\n    enum n = depVar;            // deprecation\n    enum Var = &Vaz!T;          // deprecation\n}\ndeprecated template Vaz(T)\n{\n    enum n = depVar;            // no message\n    immutable Vaz = 1234;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag14875.d(75): Error: static assert:  `0` is false\n---\n*/\nvoid main()\n{\n    static assert(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag14876.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag14876.d(17): Deprecation: class `diag14876.Dep` is deprecated\nfail_compilation/diag14876.d(18): Deprecation: class `diag14876.Dep` is deprecated\nfail_compilation/diag14876.d(19): Deprecation: class `diag14876.Dep` is deprecated\nfail_compilation/diag14876.d(20): Deprecation: class `diag14876.Dep` is deprecated\nfail_compilation/diag14876.d(21): Deprecation: class `diag14876.Dep` is deprecated\nfail_compilation/diag14876.d(22): Deprecation: class `diag14876.Dep` is deprecated\nfail_compilation/diag14876.d(23): Deprecation: class `diag14876.Dep` is deprecated\nfail_compilation/diag14876.d(23): Error: can only slice tuple types, not `diag14876.Dep`\n---\n*/\n\ndeprecated class Dep { class Mem {} }\n\nalias X1 = Foo!(Dep[]);\nalias X2 = Foo!(Dep[1]);\nalias X3 = Foo!(Dep[int]);\nalias X4 = Foo!(int[Dep]);\nalias X5 = Foo!(Dep*);\nalias X6 = Foo!(Dep.Mem);\nalias X7 = Foo!(Dep[3..4]);\n\ntemplate Foo(T) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag15001.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag15001.d(11): Error: undefined identifier `X`\n---\n*/\n\nvoid main()\n{\n    if (X x = 1)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag15186.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag15186.d(14): Error: use `.` for member lookup, not `::`\nfail_compilation/diag15186.d(15): Error: use `.` for member lookup, not `->`\n---\n*/\n\nvoid main()\n{\n    struct S { static int x; int y; }\n    S* s;\n\n    S::x = 1;\n    s->y = 2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag15209.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag15209.d(18): Error: need `this` for `x` of type `int`\nfail_compilation/diag15209.d(21): Error: need `this` for `x` of type `int`\n---\n*/\n\nclass C1 { int x; }\nstruct S1 { alias y = C1.x; }\n\nstruct S2 { int x; }\nclass C2 { alias y = S2.x; }\n\nvoid main()\n{\n    S1 s1;\n    s1.y = 10;  // invalid field variable access\n\n    auto c2 = new C2();\n    c2.y = 10;  // invalid field variable access\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag15340.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag15340.d(11): Error: undefined identifier `undef1`\nfail_compilation/diag15340.d(12): Error: undefined identifier `undef2`\n---\n*/\n\nclass C\n{\n    auto a = undef1;\n    auto b = undef2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag15411.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag15411.d(13): Error: function diag15411.test15411.__funcliteral1 cannot access frame of function diag15411.test15411\nfail_compilation/diag15411.d(14): Error: function diag15411.test15411.__funcliteral2 cannot access frame of function diag15411.test15411\n---\n*/\n\nvoid test15411()\n{\n    auto i = 0;\n    auto j = (function() { return i; })();\n    auto f =  function() { return i; };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag1566.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag1566.d(23): Error: multiple ! arguments are not allowed\nfail_compilation/diag1566.d(24): Error: multiple ! arguments are not allowed\nfail_compilation/diag1566.d(25): Error: multiple ! arguments are not allowed\nfail_compilation/diag1566.d(26): Error: multiple ! arguments are not allowed\nfail_compilation/diag1566.d(28): Error: multiple ! arguments are not allowed\nfail_compilation/diag1566.d(29): Error: multiple ! arguments are not allowed\n---\n*/\n\ntemplate T(int n)\n{\n    template T(char c)\n    {\n        alias long T;\n    }\n}\n\nvoid main()\n{\n    static assert(is(long == T!(3)!('b')));\n    static assert(is(long == T! 3 ! 'b' ));\n    static assert(is(long == T!(3)! 'b' ));\n    static assert(is(long == T! 3 !('b')));\n\n    static assert(is(long == T!(3)! 'b' !\"s\"));\n    static assert(is(long == T! 3 !('b')!\"s\"));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag15669.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag15669.d(14): Error: variable `__b_field_0` cannot be read at compile time\n---\n*/\n\nalias AliasSeq(A ...) = A;\n\nvoid foo()\n{\n    AliasSeq!int a;\n    AliasSeq!int b;\n    a[b];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag15713.d",
    "content": "/*\n---\nfail_compilation/diag15713.d(18): Error: no property 'widthSign' for type 'Data'\nfail_compilation/diag15713.d(38): Error: template instance test.conwritefImpl!(\"parse-int\", \"width\", \"\\x0a\", Data()) error instantiating\nfail_compilation/diag15713.d(43):        instantiated from here: `conwritefImpl!(\"main\", \"\\x0a\", Data())`\nfail_compilation/diag15713.d(48):        instantiated from here: `fdwritef!()`\n---\n*/\n\nvoid wrWriteWidthChar() {}\n\nauto WrData(int , int )\n{\n    struct Data\n    {\n        auto initInt(string name)()\n        {\n            __traits(getMember, this, name ~ \"Sign\");\n        }\n    }\n    return Data();\n}\n\ntemplate conwritefImpl(string state, string field, string fmt, alias data, AA...)\nif (state == \"parse-int\")\n{\n    enum conwritefImpl = data.initInt!field;\n}\n\ntemplate baz(string state, string fmt, alias data, AA...) {}\ntemplate bar(string state, string fmt, alias data, AA...) {}\n\n    enum a = \"parse-format\";\n\ntemplate conwritefImpl(string state, string fmt, alias data, AA...)\nif (state == \"main\")\n{\n    enum conwritefImpl = conwritefImpl!(\"parse-int\", \"width\", fmt, data);\n}\n\nvoid fdwritef()()\n{\n    conwritefImpl!(\"main\", \"\\n\", WrData(0, 0));\n}\n\nvoid conwriteln()\n{\n    fdwritef();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag15974.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag15974.d(21): Error: variable `f` cannot be read at compile time\nfail_compilation/diag15974.d(21):        called from here: `format(\"%s\", f)`\nfail_compilation/diag15974.d(26): Error: variable `f` cannot be read at compile time\nfail_compilation/diag15974.d(26):        called from here: `format(\"%s\", f)`\n---\n*/\n\nvoid test15974()\n{\n    string format(Args...)(string fmt, Args args)\n    {\n        return \"\";\n    }\n\n    string f = \"vkCreateSampler\";\n\n    // CompileStatement\n    mixin(format(\"%s\", f));\n\n    struct S\n    {\n        // CompileDeclaration\n        mixin(format(\"%s\", f));\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag16499.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag16499.d(22): Error: incompatible types for `(2) in (foo)`: `int` and `A`\nfail_compilation/diag16499.d(24): Error: incompatible types for `(1.00000) in (bar)`: `double` and `B`\n---\n*/\n\nstruct A {}\nstruct B {\n\tvoid* opBinaryRight(string op)(int b) if (op == \"in\")\n\t{\n\t\treturn null;\n\t}\n}\n\nvoid main()\n{\n\tA foo;\n\tB bar;\n\n\t2 in foo;\n\t2 in bar; // OK\n\t1.0 in bar;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag16977.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag16977.d(22): Error: undefined identifier `undefined`, did you mean function `undefinedId`?\nfail_compilation/diag16977.d(23): Error: cannot implicitly convert expression `\"\\x01string\"` of type `string` to `int`\nfail_compilation/diag16977.d(24): Error: template `diag16977.templ` cannot deduce function from argument types `!()(int)`, candidates are:\nfail_compilation/diag16977.d(17):        `diag16977.templ(S)(S s) if (false)`\nfail_compilation/diag16977.d(25): Error: cannot implicitly convert expression `5` of type `int` to `string`\nfail_compilation/diag16977.d(27): Error: template instance `diag16977.test.funcTemplate!string` error instantiating\n---\n*/\n\n// when copying the expression of a default argument, location information is \n//   replaced by the location of the caller to improve debug information\n// verify error messages are displayed for the original location only\n\nstring templ(S)(S s) if(false) { return null; }\n\nvoid test()\n{\n    // local functions to defer evaluation into semantic3 pass\n    void undefinedId(int x, int y = undefined) {}\n    void badOp(int x, int y = 1 ~ \"string\") {}\n    void lazyTemplate(int x, lazy int y = 4.templ) {}\n    void funcTemplate(T)(T y = 5) {}\n    \n    funcTemplate!string();\n    undefinedId(1);\n    badOp(2);\n    lazyTemplate(3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag1730.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag1730.d(51): Error: mutable method `diag1730.S.func` is not callable using a `inout` object\nfail_compilation/diag1730.d(51):        Consider adding `const` or `inout` to diag1730.S.func\nfail_compilation/diag1730.d(53): Error: `immutable` method `diag1730.S.iFunc` is not callable using a `inout` object\nfail_compilation/diag1730.d(54): Error: `shared` mutable method `diag1730.S.sFunc` is not callable using a non-shared `inout` object\nfail_compilation/diag1730.d(54):        Consider adding `const` or `inout` to diag1730.S.sFunc\nfail_compilation/diag1730.d(55): Error: `shared` `const` method `diag1730.S.scFunc` is not callable using a non-shared `inout` object\nfail_compilation/diag1730.d(70): Error: `immutable` method `diag1730.S.iFunc` is not callable using a mutable object\nfail_compilation/diag1730.d(71): Error: `shared` method `diag1730.S.sFunc` is not callable using a non-shared object\nfail_compilation/diag1730.d(72): Error: `shared` `const` method `diag1730.S.scFunc` is not callable using a non-shared mutable object\nfail_compilation/diag1730.d(75): Error: mutable method `diag1730.S.func` is not callable using a `const` object\nfail_compilation/diag1730.d(75):        Consider adding `const` or `inout` to diag1730.S.func\nfail_compilation/diag1730.d(77): Error: `immutable` method `diag1730.S.iFunc` is not callable using a `const` object\nfail_compilation/diag1730.d(78): Error: `shared` mutable method `diag1730.S.sFunc` is not callable using a non-shared `const` object\nfail_compilation/diag1730.d(78):        Consider adding `const` or `inout` to diag1730.S.sFunc\nfail_compilation/diag1730.d(79): Error: `shared` `const` method `diag1730.S.scFunc` is not callable using a non-shared `const` object\nfail_compilation/diag1730.d(82): Error: mutable method `diag1730.S.func` is not callable using a `immutable` object\nfail_compilation/diag1730.d(82):        Consider adding `const` or `inout` to diag1730.S.func\nfail_compilation/diag1730.d(85): Error: `shared` mutable method `diag1730.S.sFunc` is not callable using a `immutable` object\nfail_compilation/diag1730.d(85):        Consider adding `const` or `inout` to diag1730.S.sFunc\nfail_compilation/diag1730.d(89): Error: non-shared method `diag1730.S.func` is not callable using a `shared` object\nfail_compilation/diag1730.d(89):        Consider adding `shared` to diag1730.S.func\nfail_compilation/diag1730.d(90): Error: non-shared `const` method `diag1730.S.cFunc` is not callable using a `shared` mutable object\nfail_compilation/diag1730.d(90):        Consider adding `shared` to diag1730.S.cFunc\nfail_compilation/diag1730.d(91): Error: `immutable` method `diag1730.S.iFunc` is not callable using a `shared` mutable object\nfail_compilation/diag1730.d(94): Error: non-shared `inout` method `diag1730.S.wFunc` is not callable using a `shared` mutable object\nfail_compilation/diag1730.d(94):        Consider adding `shared` to diag1730.S.wFunc\nfail_compilation/diag1730.d(96): Error: non-shared mutable method `diag1730.S.func` is not callable using a `shared` `const` object\nfail_compilation/diag1730.d(96):        Consider adding `shared` to diag1730.S.func\nfail_compilation/diag1730.d(97): Error: non-shared `const` method `diag1730.S.cFunc` is not callable using a `shared` `const` object\nfail_compilation/diag1730.d(97):        Consider adding `shared` to diag1730.S.cFunc\nfail_compilation/diag1730.d(98): Error: `immutable` method `diag1730.S.iFunc` is not callable using a `shared` `const` object\nfail_compilation/diag1730.d(99): Error: `shared` mutable method `diag1730.S.sFunc` is not callable using a `shared` `const` object\nfail_compilation/diag1730.d(99):        Consider adding `const` or `inout` to diag1730.S.sFunc\nfail_compilation/diag1730.d(101): Error: non-shared `inout` method `diag1730.S.wFunc` is not callable using a `shared` `const` object\nfail_compilation/diag1730.d(101):        Consider adding `shared` to diag1730.S.wFunc\n---\n*/\nstruct S\n{\n    void func() { }\n    void cFunc() const { }\n    void iFunc() immutable { }\n    void sFunc() shared { }\n    void scFunc() shared const { }\n    void wFunc() inout { }\n    static void test(inout(S) s)\n    {\n        s.func();   // ng\n        s.cFunc();\n        s.iFunc();  // ng\n        s.sFunc();  // ng\n        s.scFunc(); // ng\n        s.wFunc();\n    }\n}\n\nvoid main()\n{\n    S obj;\n    const(S) cObj;\n    immutable(S) iObj;\n    shared(S) sObj;\n    shared(const(S)) scObj;\n\n    obj.func();\n    obj.cFunc();\n    obj.iFunc();   // ng\n    obj.sFunc();   // ng\n    obj.scFunc();  // ng\n    obj.wFunc();\n\n    cObj.func();   // ng\n    cObj.cFunc();\n    cObj.iFunc();  // ng\n    cObj.sFunc();  // ng\n    cObj.scFunc(); // ng\n    cObj.wFunc();\n\n    iObj.func();   // ng\n    iObj.cFunc();\n    iObj.iFunc();\n    iObj.sFunc();  // ng\n    iObj.scFunc();\n    iObj.wFunc();\n\n    sObj.func();   // ng\n    sObj.cFunc();  // ng\n    sObj.iFunc();  // ng\n    sObj.sFunc();\n    sObj.scFunc();\n    sObj.wFunc();  // ng\n\n    scObj.func();  // ng\n    scObj.cFunc(); // ng\n    scObj.iFunc(); // ng\n    scObj.sFunc(); // ng\n    scObj.scFunc();\n    scObj.wFunc(); // ng\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag18460.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag18460.d(12): Error: no property `opCall` for type `diag18460.Foo`, did you mean `new Foo`?\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=18460\n\nclass Foo {}\n\nvoid main() {\n    auto f = Foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag18574.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag18574.d(16): Error: `diag18574.Test`: multiple class inheritance is not supported. Use multiple interface inheritance and/or composition.\nfail_compilation/diag18574.d(16):        `diag18574.Bar` has no fields, consider making it an `interface`\nfail_compilation/diag18574.d(16):        `diag18574.Baz` has fields, consider making it a member of `diag18574.Test`\nfail_compilation/diag18574.d(16): Error: `diag18574.Test`: base type must be `interface`, not `int`\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=18574\n\nclass Foo {}\nclass Bar {}\nclass Baz { int a; }\n\nclass Test : Foo, Bar, Baz, int {}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag19022.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag19022.d(16): Error: immutable field `b` initialized multiple times\nfail_compilation/diag19022.d(15):        Previous initialization is here.\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=19022\n\nstruct Foo\n{\n    immutable int b;\n    this(int a)\n    {\n        b = 2;\n        b = 2;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag19196.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag19196.d(11): Error: unable to determine fields of `B` because of forward references\nfail_compilation/diag19196.d(15): Error: template instance `diag19196.Foo!(B)` error instantiating\n---\n*/\nmodule diag19196;\nstruct Foo(T)\n{\n    alias F = typeof(T.tupleof);\n}\nstruct B\n{\n    Foo!B b;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag19225.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag19225.d(14): Error: basic type expected, not `else`\nfail_compilation/diag19225.d(14):        There's no `static else`, use `else` instead.\nfail_compilation/diag19225.d(14): Error: found `else` without a corresponding `if`, `version` or `debug` statement\nfail_compilation/diag19225.d(15): Error: unrecognized declaration\n---\n*/\n\nvoid main()\n{\n    static if (true) {}\n    static else {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag2452.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag2452.d(14): Error: class `diag2452.C` interface function `void f(float p)` is not implemented\n---\n*/\n\ninterface I\n{\n    void f(int p);\n    void f(float p);\n}\n\nclass C : I\n{\n    void f(int p) { }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag3013.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag3013.d(11): Error: cannot pass type `string` as a function argument\n---\n*/\n\nint format(string, string, string);\n\nvoid main() {\n    int s = string.format(\"abc\", \"def\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag3438.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag3438.d(16): Deprecation: constructor `diag3438.F1.this` all parameters have default arguments, but structs cannot have default constructors.\nfail_compilation/diag3438.d(17): Deprecation: constructor `diag3438.F2.this` all parameters have default arguments, but structs cannot have default constructors.\nfail_compilation/diag3438.d(20): Deprecation: constructor `diag3438.F5.this` is marked `@disable`, so it cannot have default arguments for all parameters.\nfail_compilation/diag3438.d(20):        Use `@disable this();` if you want to disable default initialization.\nfail_compilation/diag3438.d(21): Deprecation: constructor `diag3438.F6.this` is marked `@disable`, so it cannot have default arguments for all parameters.\nfail_compilation/diag3438.d(21):        Use `@disable this();` if you want to disable default initialization.\n---\n*/\n\nimport core.vararg;\n\nstruct F1 { this(int x = 1) { } }\nstruct F2 { this(int x = 1, ...) { } }\nstruct F3 { this(...) { } } // ok\nstruct F4 { this(int[] x...) { } }  // ok\nstruct F5 { @disable this(int x = 1); }\nstruct F6 { @disable this(int x = 1) { } }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag3438b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag3438b.d(9): Error: default argument expected for `y`\n---\n*/\n\n// Make sure the deprecation doesn't interfere w/ the check for default arguments\nstruct S { this(int x = 1, int y) { } }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag3672.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag3672.d(36): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"+=\"(x, 1)` instead.\nfail_compilation/diag3672.d(37): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"+=\"(x, 1)` instead.\nfail_compilation/diag3672.d(38): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"-=\"(x, 1)` instead.\nfail_compilation/diag3672.d(39): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"-=\"(x, 1)` instead.\nfail_compilation/diag3672.d(40): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"+=\"(x, 1)` instead.\nfail_compilation/diag3672.d(41): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"+=\"(x, 2)` instead.\nfail_compilation/diag3672.d(42): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"-=\"(x, 3)` instead.\nfail_compilation/diag3672.d(43): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"|=\"(x, y)` instead.\nfail_compilation/diag3672.d(44): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"*=\"(x, y)` instead.\nfail_compilation/diag3672.d(45): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"/=\"(x, y)` instead.\nfail_compilation/diag3672.d(46): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"%=\"(x, y)` instead.\nfail_compilation/diag3672.d(47): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"&=\"(x, y)` instead.\nfail_compilation/diag3672.d(48): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"^=\"(x, y)` instead.\nfail_compilation/diag3672.d(49): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"<<=\"(x, y)` instead.\nfail_compilation/diag3672.d(50): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\">>=\"(x, y)` instead.\nfail_compilation/diag3672.d(51): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\">>>=\"(x, y)` instead.\nfail_compilation/diag3672.d(52): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"^^=\"(x, y)` instead.\nfail_compilation/diag3672.d(53): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"+=\"(ptr, 1)` instead.\nfail_compilation/diag3672.d(54): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"+=\"(ptr, 1)` instead.\nfail_compilation/diag3672.d(55): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"-=\"(ptr, 1)` instead.\nfail_compilation/diag3672.d(56): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"-=\"(ptr, 1)` instead.\n---\n*/\nshared int x;\nshared int y;\nshared int* ptr;\nshared static this() { ptr = new int; } // silence null-dereference errors\n\nvoid main()\n{\n    ++x;\n    x++;\n    --x;\n    x--;\n    x += 1;\n    x += 2;\n    x -= 3;\n    x |= y;\n    x *= y;\n    x /= y;\n    x %= y;\n    x &= y;\n    x ^= y;\n    x <<= y;\n    x >>= y;\n    x >>>= y;\n    x ^^= y;\n    ++ptr;\n    ptr++;\n    --ptr;\n    ptr--;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag3672a.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag3672a.d(16): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"+=\"(ns.x, 1)` instead.\nfail_compilation/diag3672a.d(18): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"+=\"(s.sx, 1)` instead.\n---\n*/\nclass NS { shared int x; }\nshared class S { int sx; }\n\nvoid main()\n{\n    NS ns = new NS;\n    ns.x++;\n    S s = new S;\n    s.sx++;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag3672a.d(32): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"+=\"(s.var, 1)` instead.\nfail_compilation/diag3672a.d(33): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"-=\"(s.var, 2)` instead.\n---\n*/\nvoid test13003()\n{\n    struct S { int var; }\n    shared S s;\n    s.var++;\n    s.var -= 2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag3673.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag3673.d(9): Error: template constraints appear both before and after BaseClassList, put them before\n---\n*/\n\nclass A {}\nclass B(T) if(false) : A if (true) { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag3869.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag3869.d(10): Error: template instance `diag3869.sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!(sum!int))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))` recursive expansion\n---\n*/\n\nstruct sum(A)\n{\n    auto blah(int a) { return .sum!(sum)(); }\n}\n\nsum!(int) z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag3913.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag3913.d(12): Error: no property `foobardoo` for type `Foo`\nfail_compilation/diag3913.d(13): Error: no property `secon` for type `Foo`. Did you mean `Foo.second` ?\n---\n*/\n\nvoid main()\n{\n    enum Foo { first, second }\n    auto a = Foo.foobardoo;\n    auto b = Foo.secon;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag4479.d",
    "content": "// EXTRA_SOURCES: imports/fail4479.d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag4479.d(10): Error: module `imports.fail4479mod` from file fail_compilation/imports/fail4479.d must be imported with 'import imports.fail4479mod;'\n---\n*/\n\nmodule diag4479;\nimport imports.fail4479;\nvoid main() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag4528.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag4528.d(14): Error: function `diag4528.Foo.pva` `private` functions cannot be `abstract`\nfail_compilation/diag4528.d(15): Error: function `diag4528.Foo.pka` `package` functions cannot be `abstract`\nfail_compilation/diag4528.d(16): Error: function `diag4528.Foo.pvsa` `static` functions cannot be `abstract`\nfail_compilation/diag4528.d(17): Error: function `diag4528.Foo.pksa` `static` functions cannot be `abstract`\nfail_compilation/diag4528.d(18): Error: function `diag4528.Foo.pbsa` `static` functions cannot be `abstract`\n---\n*/\n\nclass Foo\n{\n    private abstract void pva();\n    package abstract void pka();\n    private static abstract void pvsa();\n    package static abstract void pksa();\n    public static abstract void pbsa();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag4540.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag4540.d(11): Error: `x` must be of integral or string type, it is a `float`\n---\n*/\n\nvoid main()\n{\n    float x;\n    switch (x)\n    {\n        default:\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag4596.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag4596.d(15): Error: `this` is not an lvalue and cannot be modified\nfail_compilation/diag4596.d(16): Error: `1 ? this : this` is not an lvalue and cannot be modified\nfail_compilation/diag4596.d(18): Error: `super` is not an lvalue and cannot be modified\nfail_compilation/diag4596.d(19): Error: `1 ? super : super` is not an lvalue and cannot be modified\n---\n*/\n\nclass NoGo4596\n{\n    void fun()\n    {\n        this = new NoGo4596;\n        (1?this:this) = new NoGo4596;\n\n        super = new Object;\n        (1?super:super) = new Object;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag5385.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag5385.d(27): Deprecation: `imports.fail5385.C.privX` is not visible from module `diag5385`\nfail_compilation/diag5385.d(27): Error: class `imports.fail5385.C` member `privX` is not accessible\nfail_compilation/diag5385.d(28): Deprecation: `imports.fail5385.C.packX` is not visible from module `diag5385`\nfail_compilation/diag5385.d(28): Error: class `imports.fail5385.C` member `packX` is not accessible\nfail_compilation/diag5385.d(29): Deprecation: `imports.fail5385.C.privX2` is not visible from module `diag5385`\nfail_compilation/diag5385.d(29): Error: class `imports.fail5385.C` member `privX2` is not accessible\nfail_compilation/diag5385.d(30): Deprecation: `imports.fail5385.C.packX2` is not visible from module `diag5385`\nfail_compilation/diag5385.d(30): Error: class `imports.fail5385.C` member `packX2` is not accessible\nfail_compilation/diag5385.d(31): Deprecation: `imports.fail5385.S.privX` is not visible from module `diag5385`\nfail_compilation/diag5385.d(31): Error: struct `imports.fail5385.S` member `privX` is not accessible\nfail_compilation/diag5385.d(32): Deprecation: `imports.fail5385.S.packX` is not visible from module `diag5385`\nfail_compilation/diag5385.d(32): Error: struct `imports.fail5385.S` member `packX` is not accessible\nfail_compilation/diag5385.d(33): Deprecation: `imports.fail5385.S.privX2` is not visible from module `diag5385`\nfail_compilation/diag5385.d(33): Error: struct `imports.fail5385.S` member `privX2` is not accessible\nfail_compilation/diag5385.d(34): Deprecation: `imports.fail5385.S.packX2` is not visible from module `diag5385`\nfail_compilation/diag5385.d(34): Error: struct `imports.fail5385.S` member `packX2` is not accessible\n---\n*/\n\nimport imports.fail5385;\n\nvoid main()\n{\n    C.privX = 1;\n    C.packX = 1;\n    C.privX2 = 1;\n    C.packX2 = 1;\n    S.privX = 1;\n    S.packX = 1;\n    S.privX2 = 1;\n    S.packX2 = 1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag5450.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag5450.d(18): Error: class `diag5450.C` cannot implicitly generate a default constructor when base class `diag5450.B` is missing a default constructor\n---\n*/\n\nclass A\n{\n    this() { }\n}\n\nclass B : A\n{\n    this(int f) {}\n}\n\nclass C : B\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag6373.d",
    "content": "/*\nREQUIRED_ARGS: -de\nTEST_OUTPUT:\n---\nfail_compilation/diag6373.d(15): Error: class `diag6373.Bar` use of `diag6373.Foo.method(double x)` is hidden by `Bar`; use `alias method = Foo.method;` to introduce base class overload set\n---\n*/\n\nclass Foo\n{\n    void method(int x) { }\n    void method(double x) { }\n}\n\nclass Bar : Foo\n{\n    override void method(int x) { }\n}\n\nvoid main() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag6539.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag6539.d(21): Error: overloadset `diag6539.Rectangle` is used as a type\n---\n*/\n\nmixin template foo()\n{\n    struct Rectangle(T) {}\n}\n\nmixin template bar()\n{\n    bool Rectangle(bool, int, int, int, int) {}\n}\n\nmixin foo;\nmixin bar;\n\nvoid test(Rectangle rect)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag6677.d",
    "content": "// REQUIRED_ARGS:\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag6677.d(18): Error: static constructor cannot be `const`\nfail_compilation/diag6677.d(19): Error: static constructor cannot be `inout`\nfail_compilation/diag6677.d(20): Error: static constructor cannot be `immutable`\nfail_compilation/diag6677.d(21): Error: use `shared static this()` to declare a shared static constructor\nfail_compilation/diag6677.d(22): Error: use `shared static this()` to declare a shared static constructor\nfail_compilation/diag6677.d(24): Error: shared static constructor cannot be `const`\nfail_compilation/diag6677.d(25): Error: shared static constructor cannot be `inout`\nfail_compilation/diag6677.d(26): Error: shared static constructor cannot be `immutable`\nfail_compilation/diag6677.d(27): Error: redundant attribute `shared`\nfail_compilation/diag6677.d(28): Error: redundant attribute `shared`\n---\n*/\n\nstatic this() const { }\nstatic this() inout { }\nstatic this() immutable { }\nstatic this() shared { }\nstatic this() const shared { }\n\nshared static this() const { }\nshared static this() inout { }\nshared static this() immutable { }\nshared static this() shared { }\nshared static this() const shared { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag6699.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag6699.d(8): Error: no property `x` for type `int`\n---\n*/\nalias int b6699;\nalias b6699.x b6699a;\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag6699.d(18): Error: undefined identifier `junk1`\nfail_compilation/diag6699.d(18): Error: undefined identifier `junk2`\nfail_compilation/diag6699.d(19): Error: undefined identifier `junk3`\n---\n*/\nclass X : junk1, junk2 {}\ninterface X2 : junk3 {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag6707.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag6707.d(17): Error: mutable method `diag6707.Foo.value` is not callable using a `const` object\nfail_compilation/diag6707.d(17):        Consider adding `const` or `inout` to diag6707.Foo.value\n---\n*/\n\nmodule diag6707;\n\nstruct Foo\n{\n    @property bool value() { return true; }\n\n    void test() const\n    {\n        auto x = value;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag6717.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag6717.d(12): Error: end of instruction expected, not `h`\n---\n*/\n\nvoid main()\n{\n    version(GNU)\n    {\n        asm { \"\"h; }\n    }\n    else\n    {\n        asm\n        {\n            mov AX, 12h ;\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag6796.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag6796.d(11): Error: cannot implicitly convert expression `0` of type `int` to `int[]`\nfail_compilation/diag6796.d(11): Error: cannot implicitly convert expression `1` of type `int` to `int[]`\n---\n*/\n\nvoid main()\n{\n    enum int[][] array = [0, 1];\n    array[0] *= 10;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag7050a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag7050a.d(15): Error: `@safe` function `diag7050a.foo` cannot call `@system` constructor `diag7050a.Foo.this`\nfail_compilation/diag7050a.d(11):        `diag7050a.Foo.this` is declared here\n---\n*/\n\nstruct Foo\n{\n    this (int a) {}\n}\n@safe void foo()\n{\n    auto f = Foo(3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag7050b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag7050b.d(12): Error: `pure` function `diag7050b.f.g` cannot call impure function `diag7050b.f`\n---\n*/\n\nvoid f()\n{\n    pure void g()\n    {\n        f();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag7050c.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag7050c.d(14): Error: `@safe` destructor `diag7050c.B.~this` cannot call `@system` destructor `diag7050c.A.~this`\nfail_compilation/diag7050c.d(11):        `diag7050c.A.~this` is declared here\n---\n*/\n\nstruct A\n{\n    ~this(){}\n}\n\n@safe struct B\n{\n    A a;\n}\n\n@safe void f()\n{\n    auto x = B.init;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag7420.d",
    "content": "// REQUIRED_ARGS: -m32\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag7420.d(21): Error: static variable `x` cannot be read at compile time\nfail_compilation/diag7420.d(21):        while evaluating: `static assert(x < 4)`\nfail_compilation/diag7420.d(22): Error: static variable `y` cannot be read at compile time\nfail_compilation/diag7420.d(22):        called from here: `__equals(y, \"abc\")`\nfail_compilation/diag7420.d(22):        while evaluating: `static assert(y == \"abc\")`\nfail_compilation/diag7420.d(23): Error: static variable `y` cannot be read at compile time\nfail_compilation/diag7420.d(23):        while evaluating: `static assert(cast(ubyte[])y != null)`\nfail_compilation/diag7420.d(24): Error: static variable `y` cannot be read at compile time\nfail_compilation/diag7420.d(24):        while evaluating: `static assert(cast(int)y[0] == 1)`\nfail_compilation/diag7420.d(25): Error: static variable `y` cannot be read at compile time\nfail_compilation/diag7420.d(25):        while evaluating: `static assert(y[0..1].length == 1u)`\n---\n*/\n\nint x = 2;\nchar[] y = \"abc\".dup;\nstatic assert(x < 4);\nstatic assert(y == \"abc\");\nstatic assert(cast(ubyte[])y != null);\nstatic assert(y[0] == 1);\nstatic assert(y[0..1].length == 1);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag7477.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag7477.d(13): Error: integral constant must be scalar type, not `Foo`\nfail_compilation/diag7477.d(20): Error: integral constant must be scalar type, not `string`\n---\n*/\n\nstruct Foo { int x; }\n\nenum Bar : Foo\n{\n    a,\n    b,\n    c\n}\n\nenum Baz : string\n{\n    a,\n    b,\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag7747.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag7747.d(8): Error: forward reference to inferred return type of function call `fact(n - 1)`\n---\n*/\n\nauto fact(int n) { return n > 1 ? fact(n - 1) : 0; }\n\nvoid main()\n{\n    fact(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag7998.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag7998.d(10): Error: static assert:  \"abcxe\"\n---\n*/\n\nmodule diag7998;\n\nstatic assert(false, \"abc\" ~['x'] ~ \"e\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8101.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8101.d(56): Error: function `diag8101.f_0(int)` is not callable using argument types `()`\nfail_compilation/diag8101.d(57): Error: none of the overloads of `f_1` are callable using argument types `()`, candidates are:\nfail_compilation/diag8101.d(32):        `diag8101.f_1(int)`\nfail_compilation/diag8101.d(33):        `diag8101.f_1(int, int)`\nfail_compilation/diag8101.d(58): Error: none of the overloads of `f_2` are callable using argument types `()`, candidates are:\nfail_compilation/diag8101.d(35):        `diag8101.f_2(int)`\nfail_compilation/diag8101.d(36):        `diag8101.f_2(int, int)`\nfail_compilation/diag8101.d(37):        `diag8101.f_2(int, int, int)`\nfail_compilation/diag8101.d(38):        `diag8101.f_2(int, int, int, int)`\nfail_compilation/diag8101.d(39):        `diag8101.f_2(int, int, int, int, int)`\nfail_compilation/diag8101.d(58):        ... (1 more, -v to show) ...\nfail_compilation/diag8101.d(60): Error: template `diag8101.t_0` cannot deduce function from argument types `!()()`, candidates are:\nfail_compilation/diag8101.d(42):        `diag8101.t_0(T1)()`\nfail_compilation/diag8101.d(61): Error: template `diag8101.t_1` cannot deduce function from argument types `!()()`, candidates are:\nfail_compilation/diag8101.d(44):        `diag8101.t_1(T1)()`\nfail_compilation/diag8101.d(45):        `diag8101.t_1(T1, T2)()`\nfail_compilation/diag8101.d(62): Error: template `diag8101.t_2` cannot deduce function from argument types `!()()`, candidates are:\nfail_compilation/diag8101.d(47):        `diag8101.t_2(T1)()`\nfail_compilation/diag8101.d(48):        `diag8101.t_2(T1, T2)()`\nfail_compilation/diag8101.d(49):        `diag8101.t_2(T1, T2, T3)()`\nfail_compilation/diag8101.d(50):        `diag8101.t_2(T1, T2, T3, T4)()`\nfail_compilation/diag8101.d(51):        `diag8101.t_2(T1, T2, T3, T4, T5)()`\nfail_compilation/diag8101.d(62):        ... (1 more, -v to show) ...\n---\n*/\n\nvoid f_0(int);\n\nvoid f_1(int);\nvoid f_1(int, int);\n\nvoid f_2(int);\nvoid f_2(int, int);\nvoid f_2(int, int, int);\nvoid f_2(int, int, int, int);\nvoid f_2(int, int, int, int, int);\nvoid f_2(int, int, int, int, int, int);\n\nvoid t_0(T1)();\n\nvoid t_1(T1)();\nvoid t_1(T1, T2)();\n\nvoid t_2(T1)();\nvoid t_2(T1, T2)();\nvoid t_2(T1, T2, T3)();\nvoid t_2(T1, T2, T3, T4)();\nvoid t_2(T1, T2, T3, T4, T5)();\nvoid t_2(T1, T2, T3, T4, T5, T6)();\n\nvoid main()\n{\n    f_0();\n    f_1();\n    f_2();\n\n    t_0();\n    t_1();\n    t_2();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8101b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8101b.d(28): Error: none of the overloads of `foo` are callable using argument types `(double)`, candidates are:\nfail_compilation/diag8101b.d(19):        `diag8101b.S.foo(int _param_0)`\nfail_compilation/diag8101b.d(20):        `diag8101b.S.foo(int _param_0, int _param_1)`\nfail_compilation/diag8101b.d(30): Error: function `diag8101b.S.bar(int _param_0)` is not callable using argument types `(double)`\nfail_compilation/diag8101b.d(30):        cannot pass argument `1.00000` of type `double` to parameter `int _param_0`\nfail_compilation/diag8101b.d(33): Error: none of the overloads of `foo` are callable using a `const` object, candidates are:\nfail_compilation/diag8101b.d(19):        `diag8101b.S.foo(int _param_0)`\nfail_compilation/diag8101b.d(20):        `diag8101b.S.foo(int _param_0, int _param_1)`\nfail_compilation/diag8101b.d(35): Error: mutable method `diag8101b.S.bar` is not callable using a `const` object\nfail_compilation/diag8101b.d(35):        Consider adding `const` or `inout` to diag8101b.S.bar\n---\n*/\n\nstruct S\n{\n    void foo(int) { }\n    void foo(int, int) { }\n\n    void bar(int) { }\n}\n\nvoid main()\n{\n    S s;\n    s.foo(1.0);\n\n    s.bar(1.0);\n\n    const(S) cs;\n    cs.foo(1);\n\n    cs.bar(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8178.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8178.d(14): Error: cannot modify manifest constant `s`\n---\n*/\n\nstruct Foo\n{\n    enum string s = \"\";\n}\nvoid main()\n{\n    Foo.s = \"\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8318.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8318.d(13): Error: function `diag8318.Bar8318.foo` return type inference is not supported if may override base class function\n---\n*/\nclass Foo8318\n{\n    auto foo() { return \"Foo.foo\"; }\n}\nclass Bar8318 : Foo8318\n{\n    override auto foo() { return \"Bar.foo\"; }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8318.d(24): Error: function `diag8318.C10021.makeI` return type inference is not supported if may override base class function\n---\n*/\ninterface I10021 { I10021 makeI(); }\nclass D10021 : I10021 { D10021 makeI() { return this; } }\nclass C10021 : I10021 { auto   makeI() { return this; } }\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8318.d(38): Error: function `diag8318.Bar10195.baz` return type inference is not supported if may override base class function\n---\n*/\ninterface Foo10195\n{\n    int baz();\n}\nclass Bar10195 : Foo10195\n{\n    override auto baz() { return 1; }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8318.d(50): Error: function `diag8318.B14173.foo` does not override any function\n---\n*/\nclass A14173 {}\nclass B14173 : A14173\n{\n    override foo() {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8425.d",
    "content": "/*\nREQUIRED_ARGS: -m64 -o-\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/diag8425.d(13): Error: T in __vector(T) must be a static array, not `void`\nfail_compilation/diag8425.d(14): Error: 1 byte vector type `__vector(void[1])` is not supported on this platform\nfail_compilation/diag8425.d(15): Error: 99 byte vector type `__vector(void[99])` is not supported on this platform\nfail_compilation/diag8425.d(16): Error: vector type `__vector(void*[4])` is not supported on this platform\n---\n*/\n\nalias a = __vector(void); // not static array\nalias b = __vector(void[1]); // wrong size\nalias c = __vector(void[99]); // wrong size\nalias d = __vector(void*[4]); // wrong base type\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8510.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8510.d(10): Error: alias `diag8510.a` conflicts with alias `diag8510.a` at fail_compilation/diag8510.d(9)\nfail_compilation/diag8510.d(15): Error: alias `diag8510.S.a` conflicts with alias `diag8510.S.a` at fail_compilation/diag8510.d(14)\n---\n*/\n\nalias int a;\nalias int a;\n\nint g;\nstruct S {\n    alias g a;\n    alias g a;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8559.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8559.d(12): Error: `void` does not have a default initializer\nfail_compilation/diag8559.d(13): Error: `function` does not have a default initializer\n---\n*/\n\nvoid foo(){}\nvoid main()\n{\n    auto x = void.init;\n    auto y = typeof(foo).init;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8648.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8648.d(18): Error: undefined identifier `X`\nfail_compilation/diag8648.d(29): Error: template `diag8648.foo` cannot deduce function from argument types `!()(Foo!(int, 1))`, candidates are:\nfail_compilation/diag8648.d(18):        `diag8648.foo(T, n)(X!(T, n))`\nfail_compilation/diag8648.d(20): Error: undefined identifier `a`\nfail_compilation/diag8648.d(31): Error: template `diag8648.bar` cannot deduce function from argument types `!()(Foo!(int, 1))`, candidates are:\nfail_compilation/diag8648.d(20):        `diag8648.bar(T)(Foo!(T, a))`\nfail_compilation/diag8648.d(20): Error: undefined identifier `a`\nfail_compilation/diag8648.d(32): Error: template `diag8648.bar` cannot deduce function from argument types `!()(Foo!(int, f))`, candidates are:\nfail_compilation/diag8648.d(20):        `diag8648.bar(T)(Foo!(T, a))`\n---\n*/\n\nstruct Foo(T, alias a) {}\n\nvoid foo(T, n)(X!(T, n) ) {}    // undefined identifier 'X'\n\nvoid bar(T)(Foo!(T, a) ) {}     // undefined identifier 'a'\n\nvoid main()\n{\n    template f() {}\n\n    Foo!(int, 1) x;\n    Foo!(int, f) y;\n\n    foo(x);\n\n    bar(x); // expression '1' vs undefined Type 'a'\n    bar(y); // symbol 'f' vs undefined Type 'a'\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8697.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8697.d(10): Error: no property `Invalid` for type `diag8697.Base`\n---\n*/\ninterface InterBase : InterRoot { }\nclass Base : InterBase { }\n\nvoid test(Base.Invalid) { }\n\ninterface InterRoot { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8714.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8714.d(9): Error: function `diag8714.foo` circular dependency. Functions cannot be interpreted while being compiled\nfail_compilation/diag8714.d(15):        called from here: `foo(\"somestring\")`\n---\n*/\n\nstring foo(string f)\n{\n    if (f == \"somestring\")\n    {\n        return \"got somestring\";\n    }\n    return bar!(foo(\"somestring\"));\n}\n\ntemplate bar(string s)\n{\n    enum bar = s;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8777.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8777.d(12): Error: constructor `diag8777.Foo1.this` missing initializer for immutable field `x`\nfail_compilation/diag8777.d(12): Error: constructor `diag8777.Foo1.this` missing initializer for const field `y`\n---\n*/\nclass Foo1\n{\n    immutable int[5] x;\n    const int[5] y;\n    this() {}\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8777.d(25): Error: cannot modify `immutable` expression `x`\nfail_compilation/diag8777.d(28): Error: cannot modify `const` expression `y`\n---\n*/\nvoid test2()\n{\n    immutable int x;\n    x = 1;\n\n    const int y;\n    y = 1;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8777.d(42): Error: cannot remove key from `immutable` associative array `hashx`\nfail_compilation/diag8777.d(43): Error: cannot remove key from `const` associative array `hashy`\n---\n*/\nimmutable(int[int]) hashx;\nconst(int[int]) hashy;\nvoid test3()\n{\n    hashx.remove(1);\n    hashy.remove(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8787.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8787.d(10): Error: function `diag8787.I.f` function body only allowed in `final` functions in interface `I`\n---\n*/\n\ninterface I\n{\n    void f() { }\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8825.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8825.d(13): Error: undefined identifier `foo`\n---\n*/\n\ntemplate t(alias a){\n    alias int t;\n}\n\nvoid main(){\n    t!(foo // line 13\n\n\n\n\n\n    ) i; // line 19\n    return;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8892.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8892.d(14): Error: cannot implicitly convert expression `['A']` of type `char[]` to `char[2]`\n---\n*/\nstruct Foo\n{\n    char[2] data;\n}\n\nvoid main()\n{\n    auto f = Foo(['A']);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8894.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8894.d(16): Error: no property `x` for type `Foo`\nfail_compilation/diag8894.d(17): Error: no property `y` for type `Foo`\nfail_compilation/diag8894.d(18): Error: no property `x` for type `Foo`\nfail_compilation/diag8894.d(19): Error: no property `x` for type `Foo`\n---\n*/\n\nstruct Foo { }\n\nvoid main()\n{\n    Foo f;\n    f.x;           // UFCS getter1\n    f.y!int;       // UFCS getter2\n    f.x     = 10;  // UFCS setter1\n    f.x!int = 10;  // UFCS setter2\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag8928.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag8928.d(18): Error: class `diag8928.Z` cannot implicitly generate a default constructor when base class `diag8928.X` is missing a default constructor\n---\n*/\n\nclass X\n{\n    this(int n) {}\n}\n\nclass Y : X\n{\n    this() {}\n}\n\nclass Z : X\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9004.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9004.d(21): Error: template `diag9004.bar` cannot deduce function from argument types `!()(Foo!int, int)`, candidates are:\nfail_compilation/diag9004.d(14):        `diag9004.bar(FooT)(FooT foo, FooT.T x)`\n---\n*/\n\nstruct Foo(_T)\n{\n    alias _T T;\n}\n\nvoid bar(FooT)(FooT foo, FooT.T x)\n{\n}\n\nvoid main()\n{\n    Foo!int foo;\n    bar(foo, 1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9148.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9148.d(19): Error: `pure` function `diag9148.test9148a.foo` cannot access mutable static data `g`\nfail_compilation/diag9148.d(23): Error: `pure` function `diag9148.test9148a.bar` cannot access mutable static data `g`\nfail_compilation/diag9148.d(24): Error: `immutable` function `diag9148.test9148a.bar` cannot access mutable data `x`\nfail_compilation/diag9148.d(31): Error: `pure` function `diag9148.test9148a.S.foo` cannot access mutable static data `g`\nfail_compilation/diag9148.d(35): Error: `pure` function `diag9148.test9148a.S.bar` cannot access mutable static data `g`\nfail_compilation/diag9148.d(36): Error: `immutable` function `diag9148.test9148a.S.bar` cannot access mutable data `x`\n---\n*/\nvoid test9148a() pure\n{\n    static int g;\n    int x;\n\n    void foo() /+pure+/\n    {\n        g++;\n    }\n    void bar() immutable /+pure+/\n    {\n        g++;\n        x++;\n    }\n\n    struct S\n    {\n        void foo() /+pure+/\n        {\n            g++;\n        }\n        void bar() immutable /+pure+/\n        {\n            g++;\n            x++;\n        }\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9148.d(53): Error: static function diag9148.test9148b.foo cannot access frame of function diag9148.test9148b\n---\n*/\n\nvoid test9148b()\n{\n    int x;\n    static void foo() pure\n    {\n        int y = x;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9191.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9191.d(16): Error: function `void diag9191.C1.aaa()` does not override any function, did you mean to override `void diag9191.B1.aa()`?\nfail_compilation/diag9191.d(21): Error: function `diag9191.C2.aaa` does not override any function\nfail_compilation/diag9191.d(31): Error: function `void diag9191.C3.foo()` does not override any function, did you mean to override `void diag9191.B2._foo()`?\nfail_compilation/diag9191.d(36): Error: function `void diag9191.C4.toStringa()` does not override any function, did you mean to override `string object.Object.toString()`?\n---\n*/\n\ninterface I1 { void a(); }\nclass B1 { void aa(); }\n\nclass C1 : B1, I1\n{\n    override void aaa();\n}\n\nclass C2 : I1\n{\n    override void aaa();\n}\n\nclass B2\n{\n    void _foo(){}\n}\n\nclass C3 : B2\n{\n    override void foo(){}\n}\n\nclass C4\n{\n    override void toStringa(){}\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9210a.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/diag9210b.d(6): Error: undefined identifier `A`\n---\n*/\n\nimport imports.diag9210b;\ninterface A {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9247.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9247.d(11): Error: functions cannot return opaque type `S` by value\nfail_compilation/diag9247.d(12): Error: functions cannot return opaque type `S` by value\n---\n*/\n\nstruct S;\n\nS foo();\nS function() bar;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9250.d",
    "content": "// REQUIRED_ARGS: -m32\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9250.d(19): Error: cannot implicitly convert expression `10u` of type `uint` to `Foo`\nfail_compilation/diag9250.d(22): Error: cannot implicitly convert expression `10u` of type `uint` to `void*`\n---\n*/\n\nstruct Foo\n{\n    ubyte u;\n}\n\nvoid main()\n{\n    uint[10] bar;\n\n    Foo x = bar.length;  // error here\n\n    void* y = bar.length ?\n              bar.length :  // error here\n              bar.length;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9312.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9312.d(10): Error: `with` expressions must be aggregate types or pointers to them, not `int`\n---\n*/\n\nvoid main()\n{\n    with (1)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9357.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9357.d(14): Error: cannot implicitly convert expression `1.00000` of type `double` to `int`\nfail_compilation/diag9357.d(15): Error: cannot implicitly convert expression `10.0000` of type `double` to `int`\nfail_compilation/diag9357.d(16): Error: cannot implicitly convert expression `11.0000` of type `double` to `int`\nfail_compilation/diag9357.d(17): Error: cannot implicitly convert expression `99.0000` of type `double` to `int`\nfail_compilation/diag9357.d(18): Error: cannot implicitly convert expression `1.04858e+06L` of type `real` to `int`\nfail_compilation/diag9357.d(19): Error: cannot implicitly convert expression `1.04858e+06L` of type `real` to `int`\n---\n*/\nvoid main()\n{\n    { int x = 1.0; }\n    { int x = 10.0; }\n    { int x = 11.0; }\n    { int x = 99.0; }\n    { int x = 1048575.0L; }\n    { int x = 1048576.0L; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9358.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9358.d(12): Error: `x` must be of integral or string type, it is a `double`\nfail_compilation/diag9358.d(14): Error: `case` must be a `string` or an integral constant, not `1.1`\nfail_compilation/diag9358.d(15): Error: `case` must be a `string` or an integral constant, not `2.1`\n---\n*/\nvoid main()\n{\n    double x;\n    switch (x)\n    {\n        case 1.1: break;\n        case 2.1: break;\n        default:\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9398.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9398.d(11): Error: incompatible types for `(f) : (s)`: `float` and `string`\n---\n*/\nvoid main()\n{\n    float f;\n    string s;\n    auto a = (true ? f : s);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9420.d",
    "content": "/*\nTEST_OUTPUT\n---\nfail_compilation/diag9420.d(20): Error: function `diag9420.S.t3!().tx()` is not callable using argument types `(int)`\n---\n*/\n\nmixin template Mixin() { }\nstruct S\n{\n    template t3(T...)\n    {\n        void tx(T){}\n        alias t3 = tx;\n    }\n}\nvoid main()\n{\n    S s1;\n    s1.t3!()(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9451.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9451.d(26): Error: cannot create instance of abstract class `C2`\nfail_compilation/diag9451.d(26):        function `void f1()` is not implemented\nfail_compilation/diag9451.d(26):        function `void f2(int)` is not implemented\nfail_compilation/diag9451.d(26):        function `void f2(float) const` is not implemented\nfail_compilation/diag9451.d(26):        function `int f2(float) pure` is not implemented\n---\n*/\n\nclass C1\n{\n    abstract void f1();\n    abstract void f2(int);\n    abstract void f2(float) const;\n    abstract int f2(float) pure;\n}\n\nclass C2 : C1\n{\n}\n\nvoid main()\n{\n    auto c2 = new C2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9479.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9479.d(10): Error: undefined identifier `something_undefined`\n---\n*/\n\nint delegate() bug9479()\n{\n    return { return something_undefined; };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9574.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9574.d(12): Error: cannot use syntax `alias this = x`, use `alias x this` instead\nfail_compilation/diag9574.d(18): Error: cannot use syntax `alias this = x`, use `alias x this` instead\n---\n*/\n\nstruct S\n{\n    int x;\n    alias this = x;\n}\n\nclass C\n{\n    int x;\n    alias this = x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9620.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9620.d(18): Error: `pure` function `diag9620.main.bar` cannot call impure function `diag9620.foo1`\nfail_compilation/diag9620.d(19): Error: `pure` function `diag9620.main.bar` cannot call impure function `diag9620.foo2!().foo2`\n---\n*/\n\nint x;\n\nvoid foo1() { x = 3; }\nvoid foo2()() { x = 3; }\n\nvoid main() pure\n{\n    void bar()\n    {\n        foo1();\n        foo2();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9635.d",
    "content": "// REQUIRED_ARGS: -m32\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9635.d(17): Error: need `this` for `i` of type `int`\nfail_compilation/diag9635.d(18): Error: need `this` for `foo` of type `pure nothrow @nogc @safe void()`\n---\n*/\n\nstruct Foo\n{\n    int i;\n    void foo()() { }\n\n    static void bar()\n    {\n        i = 4;\n        foo();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9679.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9679.d(11): Error: variable `diag9679.main.n` only parameters or `foreach` declarations can be `ref`\nfail_compilation/diag9679.d(12): Error: variable `diag9679.main.n` storage class `auto` has no effect if type is not inferred, did you mean `scope`?\n---\n*/\n\nvoid main()\n{\n    if (ref n = 1) {}\n    if (auto int n = 1) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9765.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9765.d(9): Error: cannot implicitly convert expression `'x'` of type `char` to `char[]`\n---\n*/\n\nstruct S9765 { char[] x; }\nconst S9765 s9765 = S9765('x');\nconst char s9765b = s9765.x;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9831.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9831.d(12): Error: function diag9831.main.__lambda1 cannot access frame of function D main\n---\n*/\n\nvoid main()\n{\n    immutable int c;\n    int function(int x) func;\n    func = x => c;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9861.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9861.d(8): Error: no property `epsilon` for type `int`\nfail_compilation/diag9861.d(9):        while looking for match for `Foo!int`\n---\n*/\nstruct Foo(T, real x = T.epsilon) {}\nFoo!(int) q;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9880.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9880.d(9): Error: template instance `diag9880.foo!string` does not match template declaration `foo(T)(int) if (is(T == int))`\n---\n*/\n\nvoid foo(T)(int) if (is(T == int)) {}\nvoid main() { alias f = foo!string; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag9961.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag9961.d(11): Error: cannot implicitly convert expression `\"\"` of type `string` to `int`\nfail_compilation/diag9961.d(14): Error: template instance `diag9961.foo!int` error instantiating\nfail_compilation/diag9961.d(11): Error: cannot implicitly convert expression `\"\"` of type `string` to `int`\nfail_compilation/diag9961.d(15): Error: template instance `diag9961.foo!char` error instantiating\n---\n*/\n\nvoid foo(T)(T) { int x = \"\"; }\nvoid main()\n{\n    100.foo();\n    'a'.foo;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag_cstyle.d",
    "content": "// REQUIRED_ARGS:\n/*\nTEST_OUTPUT:\n---\nfail_compilation/diag_cstyle.d(14): Error: instead of C-style syntax, use D-style `int function(int) fp1`\nfail_compilation/diag_cstyle.d(15): Error: instead of C-style syntax, use D-style `int function(int)* fp3`\nfail_compilation/diag_cstyle.d(17): Error: instead of C-style syntax, use D-style `int function(int) FP`\nfail_compilation/diag_cstyle.d(19): Error: instead of C-style syntax, use D-style `int function() fp`\nfail_compilation/diag_cstyle.d(19): Error: instead of C-style syntax, use D-style `int[] arr`\nfail_compilation/diag_cstyle.d(21): Error: instead of C-style syntax, use D-style `string[] result`\n---\n*/\n\nint (*fp1)(int);\nint (*(*fp3))(int);\n\nalias int(*FP)(int);\n\nvoid foo(int(*fp)(), int arr[]) {}\n\nstring result[]() = \"abc\";\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/diag_err1.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/diag_err1.d(21): Error: undefined identifier `x`\nfail_compilation/diag_err1.d(21):        while evaluating `pragma(msg, [1, 2, x].length)`\nfail_compilation/diag_err1.d(22): Error: undefined identifier `x`\nfail_compilation/diag_err1.d(22): Error: undefined identifier `y`\nfail_compilation/diag_err1.d(22):        while evaluating `pragma(msg, (x + y).sizeof)`\nfail_compilation/diag_err1.d(23): Error: undefined identifier `x`\nfail_compilation/diag_err1.d(23):        while evaluating `pragma(msg, (n += x).sizeof)`\nfail_compilation/diag_err1.d(24): Error: incompatible types for `(s) ~ (n)`: `string` and `int`\nfail_compilation/diag_err1.d(24):        while evaluating `pragma(msg, (s ~ n).sizeof)`\n---\n*/\n\nvoid main()\n{\n    int n;\n    string s;\n\n    pragma(msg, [1,2,x].length);\n    pragma(msg, (x + y).sizeof);\n    pragma(msg, (n += x).sizeof);\n    pragma(msg, (s ~ n).sizeof);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/dip22a.d",
    "content": "/*\nREQUIRED_ARGS: -de\nTEST_OUTPUT:\n---\nfail_compilation/dip22a.d(21): Deprecation: `imports.dip22a.Klass.bar` is not visible from module `dip22a`\nfail_compilation/dip22a.d(21): Error: class `imports.dip22a.Klass` member `bar` is not accessible\nfail_compilation/dip22a.d(22): Deprecation: `imports.dip22a.Struct.bar` is not visible from module `dip22a`\nfail_compilation/dip22a.d(22): Error: struct `imports.dip22a.Struct` member `bar` is not accessible\nfail_compilation/dip22a.d(23): Error: `imports.dip22a.bar` is not visible from module `dip22a`\nfail_compilation/dip22a.d(23): Error: function `imports.dip22a.bar` is not accessible from module `dip22a`\nfail_compilation/dip22a.d(24): Error: `imports.dip22a.Template!int.bar` is not visible from module `dip22a`\nfail_compilation/dip22a.d(24): Error: function `imports.dip22a.Template!int.bar` is not accessible from module `dip22a`\nfail_compilation/dip22a.d(25): Deprecation: `imports.dip22a.bar` is not visible from module `dip22a`\nfail_compilation/dip22a.d(25): Error: function `imports.dip22a.bar` is not accessible from module `dip22a`\n---\n*/\nimport imports.dip22a;\n\nvoid test()\n{\n    new Klass().bar();\n    Struct().bar();\n    imports.dip22a.bar();\n    Template!int.bar();\n    12.bar();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/dip22b.d",
    "content": "/*\nREQUIRED_ARGS: -de\nTEST_OUTPUT:\n---\nfail_compilation/dip22b.d(12): Deprecation: `pkg.dip22c.Foo` is not visible from module `dip22`\n---\n*/\nmodule pkg.dip22;\n\nimport imports.dip22b;\n\nFoo foo;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/dip22d.d",
    "content": "/*\nREQUIRED_ARGS: -transition=import\nTEST_OUTPUT:\n---\nfail_compilation/dip22d.d(12): Error: `imports.dip22d.Foo` at fail_compilation/imports/dip22d.d(3) conflicts with `imports.dip22e.Foo` at fail_compilation/imports/dip22e.d(3)\nfail_compilation/dip22d.d(12): Error: module `dip22d` struct `imports.dip22d.Foo` is `private`\n---\n*/\nimport imports.dip22d;\nimport imports.dip22e;\n\nFoo foo;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/dip22e.d",
    "content": "/*\nREQUIRED_ARGS: -transition=checkimports -de\nTEST_OUTPUT:\n---\nfail_compilation/dip22e.d(16): Deprecation: `imports.dip22d.foo` is not visible from module `dip22e`\nfail_compilation/dip22e.d(16): Error: function `imports.dip22d.foo` is not accessible from module `dip22e`\nfail_compilation/dip22e.d(17): Deprecation: local import search method found overloadset `dip22e.bar` (1 overloads) instead of function `imports.dip22e.bar`\n---\n*/\n\nimport imports.dip22d;\nimport imports.dip22e;\n\nvoid test()\n{\n    foo();\n    bar(12);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/disable.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/disable.d(56): Error: function `disable.DisabledOpAssign.opAssign` cannot be used because it is annotated with `@disable`\nfail_compilation/disable.d(59): Error: function `disable.DisabledPostblit.opAssign` cannot be used because it is annotated with `@disable`\nfail_compilation/disable.d(62): Error: function `disable.HasDtor.opAssign` cannot be used because it is annotated with `@disable`\nfail_compilation/disable.d(66): Error: generated function `disable.Nested!(DisabledOpAssign).Nested.opAssign` cannot be used because it is annotated with `@disable`\nfail_compilation/disable.d(69): Error: generated function `disable.Nested!(DisabledPostblit).Nested.opAssign` cannot be used because it is annotated with `@disable`\nfail_compilation/disable.d(72): Error: generated function `disable.Nested!(HasDtor).Nested.opAssign` cannot be used because it is annotated with `@disable`\nfail_compilation/disable.d(76): Error: generated function `disable.NestedDtor!(DisabledOpAssign).NestedDtor.opAssign` cannot be used because it is annotated with `@disable`\nfail_compilation/disable.d(79): Error: generated function `disable.NestedDtor!(DisabledPostblit).NestedDtor.opAssign` cannot be used because it is annotated with `@disable`\nfail_compilation/disable.d(82): Error: generated function `disable.NestedDtor!(HasDtor).NestedDtor.opAssign` cannot be used because it is annotated with `@disable`\nfail_compilation/disable.d(84): Error: enum member `disable.Enum1.value` cannot be used because it is annotated with `@disable`\n---\n */\nstruct DisabledOpAssign {\n    int x;\n    @disable void opAssign(const DisabledOpAssign);\n}\n\nstruct DisabledPostblit {\n    int x;\n    @disable void opAssign(const DisabledPostblit);\n    // Doesn't require opAssign\n    @disable this(this);\n}\n\nstruct HasDtor {\n    int x;\n    @disable void opAssign(const HasDtor);\n    ~this() {} // Makes opAssign mandatory\n}\n\n\nstruct Nested (T)\n{\n    T b;\n}\n\nstruct NestedDtor (T)\n{\n    T b;\n\n    // Requires an identity opAssign\n    ~this() {}\n}\n\nenum Enum1\n{\n    @disable value\n}\n\nvoid main ()\n{\n    DisabledOpAssign o;\n    o = DisabledOpAssign();\n\n    DisabledPostblit p;\n    p = DisabledPostblit();\n\n    HasDtor d;\n    d = HasDtor();\n\n\n    Nested!(DisabledOpAssign) no;\n    no = Nested!(DisabledOpAssign)();\n\n    Nested!(DisabledPostblit) np;\n    np = Nested!(DisabledPostblit)();\n\n    Nested!(HasDtor) nd;\n    nd = Nested!(HasDtor)();\n\n\n    NestedDtor!(DisabledOpAssign) ndo;\n    ndo = NestedDtor!(DisabledOpAssign)();\n\n    NestedDtor!(DisabledPostblit) ndp;\n    ndp = NestedDtor!(DisabledPostblit)();\n\n    NestedDtor!(HasDtor) ndd;\n    ndd = NestedDtor!(HasDtor)();\n\n    auto v1 = Enum1.value;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/disable_new.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/disable_new.d(23): Error: allocator `disable_new.C.new` cannot be used because it is annotated with `@disable`\nfail_compilation/disable_new.d(24): Error: allocator `disable_new.S.new` cannot be used because it is annotated with `@disable`\n---\n*/\n\nclass C\n{\n    // force user of a type to use an external allocation strategy\n    @disable new();\n}\n\nstruct S\n{\n    // force user of a type to use an external allocation strategy\n    @disable new();\n}\n\nvoid main()\n{\n    auto c = new C();\n    auto s = new S();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/enum9921.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/enum9921.d(9): Error: enum `enum9921.X` base type must not be `void`\nfail_compilation/enum9921.d(11): Error: enum `enum9921.Z` base type must not be `void`\n---\n*/\n\nenum X : void;\n\nenum Z : void { Y };\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/extra-files/a14446.d",
    "content": "module a14446;\n\nstruct CDBMaker\n{\n    import ice14446;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/extra-files/bar11453.d",
    "content": "module foo11453.bar11453;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/extra-files/foo11453.d",
    "content": "module foo11453;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/extra-files/minimal/object.d",
    "content": "module object;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/extra-files/no_Throwable/object.d",
    "content": "module object;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/extra-files/no_TypeInfo/object.d",
    "content": "module object;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10.d(18): Error: mixin `Foo!y` cannot resolve forward reference\n---\n*/\n\ntemplate Foo(alias b)\n{\n    int a()\n    {\n        return b;\n    }\n}\n\nvoid test()\n{\n    mixin Foo!(y) y;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail100.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail100.d(24): Error: cannot implicitly convert expression `f` of type `Class[]` to `I[]`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=85\n// Array of classes doesn't function as array of interfaces\ninterface I\n{\n    I[] foo();\n    uint x();\n}\n\nclass Class : I\n{\n    I[] foo()\n    {\n        // changing this to I[] f = new Class[1] fixes the bug\n        Class[] f = new Class[1];\n        //I[] f = new Class[1];\n        f[0] = new Class;\n        return f;\n    }\n\n    uint x()\n    {\n        return 0;\n    }\n}\n\nvoid main()\n{\n    Class c = new Class();\n    assert(c.x == 0);\n    assert(c.foo[0].x == 0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10082.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10082.d(24): Error: cannot infer type from overloaded function symbol `&foo`\n---\n*/\n\nmixin template T()\n{\n    int foo()\n    {\n        return 0;\n    }\n}\n\nclass A\n{\n    mixin T;\n    mixin T;\n}\n\nvoid main()\n{\n    auto x = &A.foo;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail101.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail101.d(8): Error: cannot implicitly convert expression `1` of type `int` to `creal`\n---\n*/\n\ncreal c = 1;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10102.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10102.d(48): Error: variable `fail10102.main.m` default construction is disabled for type `NotNull!(int*)`\nfail_compilation/fail10102.d(49): Error: variable `fail10102.main.a` default construction is disabled for type `NotNull!(int*)[3]`\nfail_compilation/fail10102.d(50): Error: default construction is disabled for type `NotNull!(int*)`\nfail_compilation/fail10102.d(51): Error: field `S.m` must be initialized because it has no default constructor\n---\n*/\n\nstruct NotNull(T)\n{\n    T p;\n\n    alias p this;\n\n    this(T p)\n    {\n        assert(p != null, \"pointer is null\");\n        this.p = p;\n    }\n\n    @disable this();\n\n    NotNull opAssign(T p)\n    {\n        assert(p != null, \"assigning null to NotNull\");\n        this.p = p;\n        return this;\n    }\n}\n\nvoid main()\n{\n    struct S\n    {\n        NotNull!(int *) m;\n        // should fail: an explicit constructor must be required for S\n    }\n\n    int i;\n    NotNull!(int*) n = &i;\n    *n = 3;\n    assert(i == 3);\n    n = &i;\n    n += 1;\n\n    NotNull!(int*) m;               // should fail\n    NotNull!(int*)[3] a;            // should fail\n    auto b = new NotNull!(int*)[3]; // should fail\n    S s = S();                      // should fail\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10115.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10115.d(35): Error: cannot have `out` parameter of type `S` because the default construction is disabled\nfail_compilation/fail10115.d(35): Error: cannot have `out` parameter of type `E` because the default construction is disabled\nfail_compilation/fail10115.d(35): Error: cannot have `out` parameter of type `U` because the default construction is disabled\nfail_compilation/fail10115.d(40): Error: struct `fail10115.S` default construction is disabled\nfail_compilation/fail10115.d(41): Error: struct `fail10115.S` default construction is disabled\nfail_compilation/fail10115.d(42): Error: union `fail10115.U` default construction is disabled\n---\n*/\n\nstruct S\n{\n    int a;\n    @disable this();\n    //this(int) { a = 1; }\n    //~this() { assert(a !is 0); }\n}\n\nenum E : S\n{\n    A = S.init\n}\n\nunion U\n{\n    S s;\n    //this(this) { assert (s.a !is 0); }\n    //~this() { assert (s.a !is 0); }\n}\n\nvoid main()\n{\n    void foo(out S s, out E e, out U u) { }\n\n    S[] a;\n    E[] e;\n    U[] u;\n    a.length = 5;   // compiles -> NG\n    e.length = 5;   // compiles -> NG\n    u.length = 5;   // compiles -> NG\n\n    S[1] x = (S[1]).init;\n    foo(a[0],       // compiles -> NG\n        e[0],       // compiles -> NG\n        u[0]);      // compiles -> NG\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10207.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10207.d(7): Error: user-defined attributes not allowed for `alias` declarations\n---\n*/\nalias @Safe int __externC;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10254.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10254.d(20): Error: `pure` function `fail10254.foo` cannot call impure constructor `fail10254.C.this`\nfail_compilation/fail10254.d(20): Error: `@safe` function `fail10254.foo` cannot call `@system` constructor `fail10254.C.this`\nfail_compilation/fail10254.d(15):        `fail10254.C.this` is declared here\nfail_compilation/fail10254.d(21): Error: `pure` function `fail10254.foo` cannot call impure constructor `fail10254.S.this`\nfail_compilation/fail10254.d(21): Error: `@safe` function `fail10254.foo` cannot call `@system` constructor `fail10254.S.this`\nfail_compilation/fail10254.d(16):        `fail10254.S.this` is declared here\n---\n*/\n\nint a;\n\nclass C { this() { a = 2; } }\nstruct S { this(int) { a = 2; } }\n\nvoid foo() pure @safe\n{\n    auto c = new C; // This line should be a compilation error.\n    auto s = new S(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10277.d",
    "content": "module fail10227;\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/fail10277.d(3): Error: class `TypeInfo` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(4): Error: class `TypeInfo_Class` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(5): Error: class `TypeInfo_Interface` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(6): Error: class `TypeInfo_Struct` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(8): Error: class `TypeInfo_Pointer` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(9): Error: class `TypeInfo_Array` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(10): Error: class `TypeInfo_AssociativeArray` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(11): Error: class `TypeInfo_Enum` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(12): Error: class `TypeInfo_Function` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(13): Error: class `TypeInfo_Delegate` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(14): Error: class `TypeInfo_Tuple` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(15): Error: class `TypeInfo_Const` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(16): Error: class `TypeInfo_Invariant` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(17): Error: class `TypeInfo_Shared` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(18): Error: class `TypeInfo_Inout` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(19): Error: class `TypeInfo_Vector` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(20): Error: class `Object` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(21): Error: class `Throwable` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(22): Error: class `Exception` only object.d can define this reserved class name\nfail_compilation/imports/fail10277.d(23): Error: class `Error` only object.d can define this reserved class name\n---\n*/\n\nimport imports.fail10277;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10285.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10285.d(9): Error: no identifier for declarator `int`\n---\n*/\nenum\n{\n    int = 5\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10299.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10299.d(11): Error: `foo!string` is not an lvalue and cannot be modified\n---\n*/\n\ntemplate foo(T)\n{\n}\nauto fp = &foo!string;    // ICE\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10346.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10346.d(9): Error: undefined identifier `T`\n---\n*/\n\nstruct Foo(T) {}\nvoid bar(T x, T)(Foo!T) {}\nvoid main()\n{\n    Foo!int spam;\n    bar!10(spam);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail104.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=76\n// Using a non-template struct as a template\n// Compiling leads to \"Assertion failure: 's->parent' on line 1694 in file\n// 'template.c'\"\n\nstruct S\n{\n    template T()\n    {\n        void x(int i)\n        {\n        }\n    }\n}\n\nclass C(P)\n{\n    mixin P!().T!();\n}\n\nint main(char[][] args)\n{\n    auto c = new C!(S);\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10481.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10481.d(11): Error: undefined identifier `T1`, did you mean alias `T0`?\nfail_compilation/fail10481.d(15): Error: cannot infer type from template instance `get!(A)`\n---\n*/\n\nstruct A {}\n\nvoid get(T0 = T1.Req, Params...)(Params , T1) {}\n\nvoid main()\n{\n    auto xxx = get!A;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail105.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail105.d(11): Error: cannot cast `\"bar\"` to `int` at compile time\n---\n*/\n\n//int foo = \"foo\";\n\n// just Access Violation happens.\nint bar = cast(int)cast(char*)\"bar\";\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10528.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10528.d(23): Error: module `fail10528` variable `a10528.a` is `private`\nfail_compilation/fail10528.d(23): Deprecation: `a10528.a` is not visible from module `fail10528`\nfail_compilation/fail10528.d(24): Error: `a10528.a` is not visible from module `fail10528`\nfail_compilation/fail10528.d(26): Error: module `fail10528` enum member `a10528.b` is `private`\nfail_compilation/fail10528.d(26): Deprecation: `a10528.b` is not visible from module `fail10528`\nfail_compilation/fail10528.d(27): Error: `a10528.b` is not visible from module `fail10528`\nfail_compilation/fail10528.d(29): Deprecation: `a10528.S.c` is not visible from module `fail10528`\nfail_compilation/fail10528.d(29): Error: variable `a10528.S.c` is not accessible from module `fail10528`\nfail_compilation/fail10528.d(30): Error: variable `a10528.S.c` is not accessible from module `fail10528`\nfail_compilation/fail10528.d(32): Deprecation: `a10528.C.d` is not visible from module `fail10528`\nfail_compilation/fail10528.d(32): Error: variable `a10528.C.d` is not accessible from module `fail10528`\nfail_compilation/fail10528.d(33): Error: variable `a10528.C.d` is not accessible from module `fail10528`\n---\n*/\n\nimport imports.a10528;\n\nvoid main()\n{\n    auto a1 = a;\n    auto a2 = imports.a10528.a;\n\n    auto b1 = b;\n    auto b2 = imports.a10528.b;\n\n    auto c1 = S.c;\n    with (S) auto c2 = c;\n\n    auto d1 = C.d;\n    with (C) auto d2 = d;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10534.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10534.d(28): Error: `a` is not of arithmetic type, it is a `int delegate()`\nfail_compilation/fail10534.d(28): Error: `b` is not of arithmetic type, it is a `int delegate()`\nfail_compilation/fail10534.d(29): Error: `a` is not of arithmetic type, it is a `int delegate()`\nfail_compilation/fail10534.d(29): Error: `b` is not of arithmetic type, it is a `int delegate()`\nfail_compilation/fail10534.d(30): Error: `a` is not of arithmetic type, it is a `int delegate()`\nfail_compilation/fail10534.d(30): Error: `b` is not of arithmetic type, it is a `int delegate()`\nfail_compilation/fail10534.d(31): Error: `a` is not of arithmetic type, it is a `int delegate()`\nfail_compilation/fail10534.d(31): Error: `b` is not of arithmetic type, it is a `int delegate()`\nfail_compilation/fail10534.d(36): Error: `a` is not of arithmetic type, it is a `int function()`\nfail_compilation/fail10534.d(36): Error: `b` is not of arithmetic type, it is a `int function()`\nfail_compilation/fail10534.d(37): Error: `a` is not of arithmetic type, it is a `int function()`\nfail_compilation/fail10534.d(37): Error: `b` is not of arithmetic type, it is a `int function()`\nfail_compilation/fail10534.d(38): Error: `a` is not of arithmetic type, it is a `int function()`\nfail_compilation/fail10534.d(38): Error: `b` is not of arithmetic type, it is a `int function()`\nfail_compilation/fail10534.d(39): Error: `a` is not of arithmetic type, it is a `int function()`\nfail_compilation/fail10534.d(39): Error: `b` is not of arithmetic type, it is a `int function()`\n---\n*/\n\nvoid main()\n{\n    {\n        int delegate() a = ()=>5;\n        int delegate() b = ()=>5;\n        auto c1 = a + b;  // passes (and will crash if c1() called)\n        auto c2 = a - b;  // passes (and will crash if c2() called)\n        auto c3 = a / b;  // a & b not of arithmetic type\n        auto c4 = a * b;  // a & b not of arithmetic type\n    }\n    {\n        int function() a = ()=>5;\n        int function() b = ()=>5;\n        auto c1 = a + b;\n        auto c2 = a - b;\n        auto c3 = a / b;\n        auto c4 = a * b;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail106.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail106.d(12): Error: cannot modify `immutable` expression `'C'`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=239\n// Internal error: changing string literal elements\nvoid main()\n{\n    \"ABC\"[2] = 's';\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10630.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10630.d(12): Error: cannot have `out` parameter of type `S` because the default construction is disabled\n---\n*/\n\nstruct S\n{\n    @disable this();\n}\nvoid foo(out S) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10666.d",
    "content": "// REQUIRED_ARGS: -c\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10666.d(16): Error: variable `fail10666.foo10666.s1` has scoped destruction, cannot build closure\n---\n*/\n\n\nstruct S10666\n{\n    int val;\n    ~this() {}\n}\n\nvoid foo10666(S10666 s1)\n{\n    auto f1 = (){ return () => s1.val; }(); // NG\n\n    S10666 s2;\n    auto f2 = (){ return () => s2.val; }(); // (should be NG)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail109.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail109.d(12): Error: enum member `fail109.Bool.Unknown` initialization with `Bool.True+1` causes overflow for type `bool`\n---\n*/\n\nenum Bool : bool\n{\n    False,\n    True,\n    Unknown\n}\n\n/* https://issues.dlang.org/show_bug.cgi?id=11088\nTEST_OUTPUT:\n---\nfail_compilation/fail109.d(25): Error: enum member `fail109.E.B` initialization with `E.A+1` causes overflow for type `int`\nfail_compilation/fail109.d(31): Error: enum member `fail109.E1.B` initialization with `E1.A+1` causes overflow for type `short`\n---\n*/\nenum E\n{\n    A = int.max,\n    B\n}\n\nenum E1 : short\n{\n    A = short.max,\n    B\n}\n\n/* https://issues.dlang.org/show_bug.cgi?id=14950\nTEST_OUTPUT:\n---\nfail_compilation/fail109.d(50): Error: Comparison between different enumeration types `B` and `C`; If this behavior is intended consider using `std.conv.asOriginalType`\nfail_compilation/fail109.d(50): Error: enum member `fail109.B.end` initialization with `B.start+1` causes overflow for type `C`\n---\n*/\nenum C\n{\n    start,\n    end\n}\n\nenum B\n{\n    start = C.end,\n    end\n}\n\n/* https://issues.dlang.org/show_bug.cgi?id=11849\nTEST_OUTPUT:\n---\nfail_compilation/fail109.d(72): Error: enum `fail109.RegValueType1a` recursive definition of `.max` property\nfail_compilation/fail109.d(79): Error: enum `fail109.RegValueType1b` recursive definition of `.max` property\nfail_compilation/fail109.d(84): Error: enum `fail109.RegValueType2a` recursive definition of `.min` property\nfail_compilation/fail109.d(91): Error: enum `fail109.RegValueType2b` recursive definition of `.min` property\n---\n*/\n\nalias DWORD = uint;\n\nenum : DWORD\n{\n    REG_DWORD = 4\n}\n\nenum RegValueType1a : DWORD\n{\n    Unknown = DWORD.max,\n    DWORD = REG_DWORD,\n}\n\nenum RegValueType1b : DWORD\n{\n    DWORD = REG_DWORD,\n    Unknown = DWORD.max,\n}\n\nenum RegValueType2a : DWORD\n{\n    Unknown = DWORD.min,\n    DWORD = REG_DWORD,\n}\n\nenum RegValueType2b : DWORD\n{\n    DWORD = REG_DWORD,\n    Unknown = DWORD.min,\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10905.d",
    "content": "\nstruct Foo\n{\n    enum __vector(long[2]) y = 1;\n}\n\nstruct Bar\n{\n    __vector(long[2]) x;\n\n    bool spam() const\n    {\n        return x == Foo.y;\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10947.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10947.d(21): Error: cannot have `immutable out` parameter of type `immutable(S)`\nfail_compilation/fail10947.d(22): Error: cannot have `immutable out` parameter of type `immutable(S)`\nfail_compilation/fail10947.d(23): Error: cannot have `immutable out` parameter of type `immutable(S)`\nfail_compilation/fail10947.d(25): Error: cannot have `const out` parameter of type `const(S)`\nfail_compilation/fail10947.d(26): Error: cannot have `const out` parameter of type `const(S)`\nfail_compilation/fail10947.d(27): Error: cannot have `const out` parameter of type `const(S)`\nfail_compilation/fail10947.d(29): Error: cannot have `inout out` parameter of type `inout(S)`\nfail_compilation/fail10947.d(30): Error: cannot have `inout out` parameter of type `inout(S)`\nfail_compilation/fail10947.d(31): Error: cannot have `inout out` parameter of type `inout(S)`\n---\n*/\n\nstruct S {}\nalias SI = immutable S;\nalias SC = const S;\nalias SW = inout S;\n\nvoid fooi1(out SI) {}\nvoid fooi2(out immutable(S)) {}\nvoid fooi3(out immutable S) {}\n\nvoid fooc1(out SC) {}\nvoid fooc2(out const(S)) {}\nvoid fooc3(out const S) {}\n\nvoid foow1(out SW) {}\nvoid foow2(out inout(S)) {}\nvoid foow3(out inout S) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10964.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10964.d(28): Error: function `fail10964.S.__postblit` is not `nothrow`\nfail_compilation/fail10964.d(29): Error: function `fail10964.S.__postblit` is not `nothrow`\nfail_compilation/fail10964.d(30): Error: function `fail10964.S.__postblit` is not `nothrow`\nfail_compilation/fail10964.d(33): Error: function `fail10964.S.__postblit` is not `nothrow`\nfail_compilation/fail10964.d(34): Error: function `fail10964.S.__postblit` is not `nothrow`\nfail_compilation/fail10964.d(35): Error: function `fail10964.S.__postblit` is not `nothrow`\nfail_compilation/fail10964.d(22): Error: `nothrow` function `fail10964.foo` may throw\n---\n*/\n\nstruct S\n{\n    this(this)\n    {\n        throw new Exception(\"BOOM!\");\n    }\n}\n\nvoid foo() nothrow\n{\n    S    ss;\n    S[1] sa;\n\n    // TOKassign\n    ss = ss;\n    sa = ss;\n    sa = sa;\n\n    // TOKconstruct\n    S    ss2 = ss;\n    S[1] sa2 = ss;\n    S[1] sa3 = sa;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10968.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10968.d(39): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(39): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here\nfail_compilation/fail10968.d(40): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(40): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here\nfail_compilation/fail10968.d(41): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(41): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here\nfail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(44): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here\nfail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(45): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here\nfail_compilation/fail10968.d(46): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(46): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`\nfail_compilation/fail10968.d(27):        `fail10968.SA.__postblit` is declared here\n---\n*/\n\nstruct SA\n{\n    this(this)\n    {\n        throw new Exception(\"BOOM!\");\n    }\n}\n\nvoid bar() pure @safe\n{\n    SA    ss;\n    SA[1] sa;\n\n    // TOKassign\n    ss = ss;\n    sa = ss;\n    sa = sa;\n\n    // TOKconstruct\n    SA    ss2 = ss;\n    SA[1] sa2 = ss;\n    SA[1] sa3 = sa;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10968.d(72): Error: struct `fail10968.SD` is not copyable because it is annotated with `@disable`\nfail_compilation/fail10968.d(73): Error: struct `fail10968.SD` is not copyable because it is annotated with `@disable`\nfail_compilation/fail10968.d(74): Error: struct `fail10968.SD` is not copyable because it is annotated with `@disable`\nfail_compilation/fail10968.d(77): Error: struct `fail10968.SD` is not copyable because it is annotated with `@disable`\nfail_compilation/fail10968.d(78): Error: struct `fail10968.SD` is not copyable because it is annotated with `@disable`\nfail_compilation/fail10968.d(79): Error: struct `fail10968.SD` is not copyable because it is annotated with `@disable`\n---\n*/\n\nstruct SD\n{\n    this(this) @disable;\n}\n\nvoid baz()\n{\n    SD    ss;\n    SD[1] sa;\n\n    // TOKassign\n    ss = ss;\n    sa = ss;\n    sa = sa;\n\n    // TOKconstruct\n    SD    ss2 = ss;\n    SD[1] sa2 = ss;\n    SD[1] sa3 = sa;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail10980.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail10980.d(22): Error: variable `fail10980.s1b` of type struct `immutable(S1)` uses `this(this)`, which is not allowed in static initialization\nfail_compilation/fail10980.d(28): Error: variable `fail10980.s1d` of type struct `immutable(S1)` uses `this(this)`, which is not allowed in static initialization\nfail_compilation/fail10980.d(27): Error: static variable `s1x` cannot be read at compile time\nfail_compilation/fail10980.d(28):        called from here: `bar1()`\nfail_compilation/fail10980.d(38): Error: variable `fail10980.s2b` of type struct `immutable(S2)` uses `this(this)`, which is not allowed in static initialization\nfail_compilation/fail10980.d(44): Error: variable `fail10980.s2d` of type struct `immutable(S2)` uses `this(this)`, which is not allowed in static initialization\nfail_compilation/fail10980.d(43): Error: static variable `s2x` cannot be read at compile time\nfail_compilation/fail10980.d(44):        called from here: `bar2()`\n---\n*/\n\nstruct S1\n{\n    this(int) immutable {}\n    this(this) {}\n}\nalias immutable(S1) IS1;\nstatic immutable S1 s1a = IS1(1);   // OK\nstatic immutable S1 s1b = s1a;      // NG\n\nS1 foo1() { S1 s1x; S1 s1y = s1x; return s1y; }\nstatic immutable S1 s1c = foo1();   // OK\n\nref S1 bar1() { static S1 s1x; return s1x; }\nstatic immutable S1 s1d = bar1();   // NG\n\n\nstruct S2\n{\n    int val;\n    this(this) {}\n}\nalias immutable(S2) IS2;\nstatic immutable S2 s2a = IS2(1);   // OK\nstatic immutable S2 s2b = s2a;      // NG\n\nS2 foo2() { S2 s2x; S2 s2y = s2x; return s2y; }\nstatic immutable S2 s2c = foo2();   // OK\n\nref S2 bar2() { static S2 s2x; return s2x; }\nstatic immutable S2 s2d = bar2();   // NG\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11.d(12): Error: `int*` has no effect\n---\n*/\n\n// http://forum.dlang.org/thread/c738o9$1p7i$1@digitaldaemon.com\n\nvoid main()\n{\n    TFoo!(int).t; // should produce a \"no identifier\" error.\n}\ntemplate TFoo(T) { alias T* t; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail110.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail110.d(16): Error: variable `i` is shadowing variable `fail110.main.i`\nfail_compilation/fail110.d(17): Error: variable `i` is shadowing variable `fail110.main.i`\nfail_compilation/fail110.d(18): Error: variable `i` is shadowing variable `fail110.main.i`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=297\n// Shadowing declarations allowed in foreach type lists\nvoid main()\n{\n    int i;\n    int[] a;\n    foreach (i; a) {}\n    foreach (int i, n; a) {}\n    for (int i;;) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11042.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11042.d(8): Error: undefined identifier `error`, did you mean class `Error`?\nfail_compilation/fail11042.d(9): Error: undefined identifier `error`, did you mean class `Error`?\n---\n*/\nstatic if ({ return true  || error; }()) {} // NG\nstatic if ({ return false && error; }()) {} // NG\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail111.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail111.d(12): Error: cannot have array of `int(int)`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=289\n// Compiler allows (and crashes on) dynamic arrays of typedefs of \"immediate\"-function types\nalias int ft(int);\n\nft[] x;  // is allowed\n\nvoid test()\n{\n    x.length = 2;  // crashes DMD\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11125.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11125.d(20): Error: template instance `fail11125.filter!(function (int a) => a + 1)` does not match template declaration `filter(alias predfun) if (is(ReturnType!predfun == bool))`\nfail_compilation/fail11125.d(21): Error: template instance `fail11125.filter!(function (int a) => a + 1)` does not match template declaration `filter(alias predfun) if (is(ReturnType!predfun == bool))`\n---\n*/\n\ntemplate ReturnType(alias fun) { alias int ReturnType; }\n\ntemplate filter(alias predfun)\n    if (is(ReturnType!predfun == bool))\n{\n    static assert(is(ReturnType!predfun == bool));\n    auto filter(Range)(Range r) { }\n}\n\nvoid main()\n{\n    filter!((int a) => a + 1)([1]);  // fails in constraint\n    [1].filter!((int a) => a + 1);   // fails internally in static assert!\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11151.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11151.d(30): Error: overlapping initialization for field `a` and `y`\n---\n*/\n\n//extern(C) int printf(const char*, ...);\n\nunion U\n{\n    struct\n    {\n        align(1) long a;\n        align(1) int b;\n    }\n    struct\n    {\n        align(1) int x;\n        align(1) long y;\n    }\n}\nvoid main()\n{\n    static assert(U.a.offsetof == 0);\n    static assert(U.b.offsetof == 8);\n    static assert(U.x.offsetof == 0);\n    static assert(U.y.offsetof == 4);\n\n    U u = {a:1, y:2};   // overlapped initializing U.a and U.y\n\n    //printf(\"u.a = %lld\\n\", u.a);    // 8589934593 , Wrong!\n    //printf(\"u.b = %d\\n\",   u.b);    // 0\n    //printf(\"u.x = %d\\n\",   u.x);    // 1\n    //printf(\"u.y = %lld\\n\", u.y);    // 2\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11163.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11163.d(12): Error: cannot implicitly convert expression `foo()` of type `int[]` to `immutable(int[])`\nfail_compilation/fail11163.d(13):        while evaluating `pragma(msg, a)`\n---\n*/\nint[] foo() {\n    return [1];\n}\nvoid main() {\n    immutable a = foo();\n    pragma(msg, a);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail113.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail113.d(10): Error: forward reference to `test`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=370\n// Compiler stack overflow on recursive typeof in function declaration.\nvoid test(typeof(test) p) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11355.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11355.d(28): Error: struct `fail11355.A` is not copyable because it is annotated with `@disable`\n---\n*/\n\nT move(T)(ref T source)\n{\n    return T.init;          // Dummy rvalue\n}\n\nstruct A\n{\n    ~this() {}\n    @disable this(this);    // Prevent copying\n}\n\nstruct B\n{\n    A a;\n    alias a this;\n}\n\nvoid main()\n{\n    B b;\n    A a = move(b);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11375.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11375.d(17): Error: constructor `fail11375.D!().D.this` is not `nothrow`\nfail_compilation/fail11375.d(15): Error: `nothrow` function `D main` may throw\n---\n*/\n\nclass B {\n    this() {}\n}\n\nclass D() : B {}\n\nvoid main() nothrow\n{\n    auto d = new D!()();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail114.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail114.d(12): Error: forward reference to `funcA`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=371\n// ICE on mutual recursive typeof in function declarations\nvoid funcA(typeof(&funcB) p) {}\n\nvoid funcB(typeof(&funcA) p) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11426.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11426.d(15): Error: cannot implicitly convert expression `udarr` of type `uint[]` to `int[]`\nfail_compilation/fail11426.d(16): Error: cannot implicitly convert expression `usarr` of type `uint[1]` to `int[]`\nfail_compilation/fail11426.d(18): Error: cannot implicitly convert expression `udarr` of type `uint[]` to `int[]`\nfail_compilation/fail11426.d(19): Error: cannot implicitly convert expression `usarr` of type `uint[1]` to `int[]`\n---\n*/\nvoid main()\n{\n    uint[]  udarr;\n    uint[1] usarr;\n\n    int[1] arr1; arr1 = udarr;  // Error, OK\n    int[1] arr2; arr2 = usarr;  // Error, OK\n\n    int[1] arr3 = udarr;    // accepted, BAD!\n    int[1] arr4 = usarr;    // accepted, BAD!\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11445.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11445.d(11): Error: incompatible types for `(a) + (b)`: both operands are of type `double[string]`\n---\n*/\n\nvoid main() {\n  double[string] a = [ \"foo\" : 22.2 ];\n  double[string] b = [ \"bar\" : 22.2 ];\n  auto c = a + b;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11453a.d",
    "content": "// REQUIRED_ARGS: -Ifail_compilation/extra-files\n// EXTRA_SOURCES: extra-files/foo11453.d extra-files/bar11453.d\n/*\nTEST_OUTPUT\n---\nfail_compilation/extra-files/bar11453.d(1): Error: package name 'foo11453' conflicts with usage as a module name in file fail_compilation/extra-files/foo11453.d\n---\n*/\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11453b.d",
    "content": "// REQUIRED_ARGS: -Ifail_compilation/extra-files\n// EXTRA_SOURCES: extra-files/bar11453.d extra-files/foo11453.d\n/*\nTEST_OUTPUT\n---\nfail_compilation/extra-files/foo11453.d(1): Error: module `foo11453` from file fail_compilation/extra-files/foo11453.d conflicts with package name foo11453\n---\n*/\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail115.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=402\n// compiler crash with mixin and forward reference\n\ntemplate Foo(alias b)\n{\n    int a() { return b; }\n}\n\nvoid main()\n{\n    mixin Foo!(y) y;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11503a.d",
    "content": "struct S\n{\n    immutable(S)* s;\n    this(int) immutable pure\n    {\n        s = &this;\n    }\n    int data;\n}\n\nimmutable(S)* makes() pure\n{\n    return new immutable S(0);\n}\n\nvoid main()\n{\n    S* s = makes(); // s is mutable and contains an immutable reference to itself\n    //s.s.data = 7; // this is immutable\n    s.data = 3; // but this is not!!!\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11503b.d",
    "content": "immutable int[] x = [1, 2, 3];\n\nauto makes() pure\n{\n    return x;\n}\n\nint main()\n{\n    auto a = x;\n    int[] b = makes();\n    return b[1];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11503c.d",
    "content": "struct Data\n{\n    char[256] buffer;\n    @property const(char)[] filename() const pure nothrow\n    {\n        return buffer[];\n    }\n}\n\nvoid main()\n{\n    Data d;\n    string f = d.filename;\n    d.buffer[0] = 'a';\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11503d.d",
    "content": "struct Data2\n{\n    char buffer;\n}\n\n@property const(char)[] filename(const ref Data2 d) pure nothrow\n{\n    return (&d.buffer)[0 .. 1];\n}\n\n@property const(char)[] filename2(const Data2* d) pure nothrow\n{\n    return (&d.buffer)[0 .. 1];\n}\n\nvoid main()\n{\n    Data2 d;\n    string f = d.filename;\n    string g = (&d).filename2;\n    d.buffer = 'a';\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11510.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11510.d(25): Error: reinterpretation through overlapped field `y` is not allowed in CTFE\nfail_compilation/fail11510.d(29):        called from here: `test11510a()`\nfail_compilation/fail11510.d(36): Error: reinterpretation through overlapped field `y` is not allowed in CTFE\nfail_compilation/fail11510.d(40):        called from here: `test11510b()`\n---\n*/\n\nstruct S11510\n{\n    union\n    {\n        size_t x;\n        int* y; // pointer field\n    }\n}\n\nbool test11510a()\n{\n    S11510 s;\n\n    s.y = [1,2,3].ptr;\n    auto x = s.x;   // reinterpretation\n\n    return true;\n}\nenum a = test11510a();\n\nbool test11510b()\n{\n    S11510 s;\n\n    s.x = 10;\n    auto y = s.y;   // reinterpretation\n\n    return true;\n}\nenum b = test11510b();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11532.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11532.d(17): Error: cannot pass static arrays to `extern(C)` vararg functions\nfail_compilation/fail11532.d(18): Error: cannot pass dynamic arrays to `extern(C)` vararg functions\nfail_compilation/fail11532.d(19): Error: cannot pass static arrays to `extern(C++)` vararg functions\nfail_compilation/fail11532.d(20): Error: cannot pass dynamic arrays to `extern(C++)` vararg functions\n---\n*/\n\nextern(C) void cvararg(int, ...);\nextern(C++) void cppvararg(int, ...);\n\nvoid main()\n{\n    int[2] arr = [0x99999999, 0x88888888];\n    cvararg(0, arr);\n    cvararg(0, arr[]);\n    cppvararg(0, arr);\n    cppvararg(0, arr[]);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11542.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11542.d(16): Error: `object.Exception` is thrown but not caught\nfail_compilation/fail11542.d(13): Error: `nothrow` function `fail11542.test_success1` may throw\nfail_compilation/fail11542.d(26): Error: `object.Exception` is thrown but not caught\nfail_compilation/fail11542.d(23): Error: `nothrow` function `fail11542.test_success3` may throw\n---\n*/\nvoid test_success1() nothrow\n{\n    scope(success) {}\n    throw new Exception(\"\");    // error\n}\nvoid test_success2() nothrow\n{\n    scope(success) {}\n    throw new Error(\"\");        // no error\n}\nvoid test_success3() nothrow\n{\n    scope(success) assert(0);\n    throw new Exception(\"\");    // error\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11542.d(39): Error: `object.Exception` is thrown but not caught\nfail_compilation/fail11542.d(36): Error: `nothrow` function `fail11542.test_failure1` may throw\n---\n*/\nvoid test_failure1() nothrow\n{\n    scope(failure) {}\n    throw new Exception(\"\");    // error\n}\nvoid test_failure2() nothrow\n{\n    scope(failure) {}\n    throw new Error(\"\");        // no error\n}\nvoid est_failure3() nothrow\n{\n    scope(failure) assert(0);\n    throw new Exception(\"\");    // no error\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11542.d(62): Error: `object.Exception` is thrown but not caught\nfail_compilation/fail11542.d(59): Error: `nothrow` function `fail11542.test_exit1` may throw\n---\n*/\nvoid test_exit1() nothrow\n{\n    scope(exit) {}\n    throw new Exception(\"\");    // error\n}\nvoid test_exit2() nothrow\n{\n    scope(exit) {}\n    throw new Error(\"\");        // no error\n}\nvoid test_exit3() nothrow\n{\n    scope(exit) assert(0);\n    throw new Exception(\"\");    // no error\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11545.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11545.d(14): Error: need `this` for `x` of type `int`\nfail_compilation/fail11545.d(18): Error: need `this` for `x` of type `int`\n---\n*/\n\nclass C\n{\n    int x = 42;\n\n    int function() f1 = function() {\n        return x;\n    };\n\n    int function() f2 = {\n        return x;\n    };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11552.d",
    "content": "/*\nREQUIRED_ARGS: -o-\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/fail11552.d(12): Error: label `label` is undefined\n---\n*/\n\nvoid main()\n{\n    goto label;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11562.d",
    "content": "/*\nREQUIRED_ARGS: -o-\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/fail11562.d(16): Error: cannot `goto` in or out of `finally` block\nfail_compilation/fail11562.d(37): Error: cannot `goto` in or out of `finally` block\nfail_compilation/fail11562.d(49): Error: cannot `goto` in or out of `finally` block\nfail_compilation/fail11562.d(64): Error: cannot `goto` in or out of `finally` block\n---\n*/\n\n// Goto into finally block (forwards)\nint w(bool b)\n{\n    if (b) goto label;\n    try\n    {\n    }\n    finally\n    {\n    label: {}\n    }\n    return 1;\n}\n\n// // Goto into finally block (backwards)\nint x(bool b)\n{\n    try\n    {\n    }\n    finally\n    {\n    label: {}\n    }\n    if (b) goto label;\n    return 1;\n}\n\n// Goto out of finally block (forwards)\nint y(bool b)\n{\n    try\n    {\n    }\n    finally\n    {\n    if (b) goto label;\n    }\n    label: {}\n    return 1;\n}\n\n// // Goto out of finally block (backwards)\nint z(bool b)\n{\n    label: {}\n    try\n    {\n    }\n    finally\n    {\n    if (b) goto label;\n    }\n    return 1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11591b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11591b.d(16): Error: AA key type `S11591` does not have `bool opEquals(ref const S11591) const`\n---\n*/\n\nstruct S11591\n{\n    bool opEquals(int i) { return false; }\n    Object o; // needed to suppress compiler generated opEquals\n}\n\nvoid test11591()\n{\n    int[S11591] aa;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11591b.d(30): Error: AA key type `S12307a` does not have `bool opEquals(ref const S12307a) const`\nfail_compilation/fail11591b.d(31): Error: AA key type `S12307b` does not have `bool opEquals(ref const S12307b) const`\n---\n*/\nstruct S12307a { bool opEquals(T : typeof(this))(T) { return false; } }\n\nvoid test12307()\n{\n    int[S12307a] aa1;    // a\n    int[S12307b] aa2;    // b\n}\n\nstruct S12307b { bool opEquals(T : typeof(this))(T) { return false; } }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail116.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail116.d(11): Error: circular `typeof` definition\nfail_compilation/fail116.d(16): Error: template instance `square!1.2` does not match template declaration `square(_error_ x)`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=405\n// typeof in TemplateParameterList causes compiletime segmentfault\ntemplate square(typeof(x) x)\n{\n    const square = x * x;\n}\n\nconst b = square!(1.2);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11653.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11653.d(19): Deprecation: switch case fallthrough - use 'goto case;' if intended\nfail_compilation/fail11653.d(24): Deprecation: switch case fallthrough - use 'goto default;' if intended\n---\n*/\n\nvoid main()\n{\n    int test = 12412;\n    int output = 0;\n    switch(test)\n    {\n        case 1:\n            output = 1;\n            //break; //Oops..\n        case 2: .. case 3:\n            output = 2;\n            break;\n        case 4:\n            output = 3;\n        default:\n            output = 4;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail117.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail117.d(35): Error: expression has no value\nfail_compilation/fail117.d(36): Error: expression has no value\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=420\n// mixin make dmd break\n//import std.stdio;\n\ntemplate MGettor(alias Fld)\n{\n    typeof(Fld) opCall()\n    {\n        //writefln(\"getter\");\n        return Fld;\n    }\n}\n\nclass Foo\n{\n    int a = 1,\n        b = 2;\n\n    mixin MGettor!(a) geta;\n    mixin MGettor!(b) getb;\n}\n\nvoid main()\n{\n    auto foo = new Foo;\n\n    int a = foo.geta;\n    int b = foo.getb;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11714.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11714.d(14): Error: variable `fail11714.c` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.\nfail_compilation/fail11714.d(21): Error: variable `fail11714.s` is a thread-local pointer to struct and cannot have a static initializer. Use `static this()` to initialize instead.\n---\n*/\n\nclass C11714\n{\n    int data;\n};\n\nC11714 c = new C11714;  // mutable class reference.\n\nstruct S11714\n{\n    int data;\n};\n\nS11714* s = new S11714; // mutable pointer to struct.\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11717.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11717.d(13): Error: cannot interpret array literal expression `[1, 2, 3, 4] + [1, 2, 3, 4]` at compile time\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=11717\n\nenum int[4] A = [1,2,3,4];\nenum int[4] B = [1,2,3,4];\n// Internal Compiler Error: non-constant value [1, 2, 3, 4]\nenum int[4] C = A[] + B[];\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11720.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11720.d(23): Error: declaration `fail11720.foo!().foo.temp` is already defined in another scope in `foo` at line `23`\nfail_compilation/fail11720.d(13): Error: template instance `fail11720.foo!()` error instantiating\nfail_compilation/fail11720.d(31): Error: declaration `fail11720.bar.temp` is already defined in another scope in `bar` at line `31`\n---\n*/\n\nvoid main()\n{\n    foo();\n    bar();\n}\n\nalias TypeTuple(T...) = T;\n\nvoid foo()()\n{\n    foreach (T; TypeTuple!(int, double))\n    {\n        static temp = T.stringof;\n    }\n}\n\nvoid bar()\n{\n    foreach (T; TypeTuple!(int, double))\n    {\n        static temp = T.stringof;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11746.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11746.d(18): Error: cannot implicitly convert expression `1` of type `int` to `string`\nfail_compilation/fail11746.d(25): Error: cannot implicitly convert expression `1` of type `int` to `string`\nfail_compilation/fail11746.d(26): Error: cannot implicitly convert expression `2` of type `int` to `string`\n---\n*/\n\nstring bb(T, U)(T x, U y)\n{\n    return \"3\";\n}\n\nenum E1\n{\n    foo = bb(bar, baz),\n    bar = 1,\n    baz = \"2\",\n}\n\nenum E2\n{\n    foo = bb(bar, baz),\n    bar = 1,\n    baz = 2\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11748.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11748.d(12): Error: expression `my_function(0)` is `void` and has no value\n---\n*/\n\nvoid main()\n{\n    enum my_template(alias T) = T.stringof;\n    void my_function(int i) { }\n    my_template!(my_function(0));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail11751.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail11751.d(10): Error: missing exponent\nfail_compilation/fail11751.d(10): Error: semicolon expected following auto declaration, not `ABC`\nfail_compilation/fail11751.d(10): Error: no identifier for declarator `ABC`\n---\n*/\n\nauto x = 0x1.FFFFFFFFFFFFFpABC;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail118.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail118.d(26): Error: invalid `foreach` aggregate `Iter`, define `opApply()`, range primitives, or use `.tupleof`\nfail_compilation/fail118.d(27): Error: invalid `foreach` aggregate `Iter`, define `opApply()`, range primitives, or use `.tupleof`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=441\n// Crash on foreach of mixed-in aggregate.\ntemplate opHackedApply()\n{\n    struct Iter\n    {\n    }\n}\n\nclass Foo\n{\n    mixin opHackedApply!() oldIterMix;\n}\n\nvoid main()\n{\n    Foo f = new Foo;\n    foreach (int i; f.oldIterMix.Iter) {}\n    foreach (    i; f.oldIterMix.Iter) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12.d",
    "content": "template Foo(alias b)\n{\n    int abc() { return b; }\n}\n\nvoid main()\n{\n    int y = 8;\n    mixin Foo!(y);\n    mixin Foo!(y);\n    assert(abc() == 8);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail120.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail120.d(12): Error: need `this` for `nodes` of type `int[2]`\nfail_compilation/fail120.d(13): Error: need `this` for `nodes` of type `int[2]`\n---\n*/\n\nclass Foo\n{\n    int[2] nodes;\n    auto left = (){ return nodes[0]; };\n    auto right = (){ return nodes[1]; };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12047.d",
    "content": "// REQUIRED_ARGS: -d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12047.d(15): Error: undefined identifier `asdf`\nfail_compilation/fail12047.d(16): Error: undefined identifier `asdf`\nfail_compilation/fail12047.d(17): Error: undefined identifier `asdf`\nfail_compilation/fail12047.d(18): Error: undefined identifier `asdf`\nfail_compilation/fail12047.d(19): Error: undefined identifier `asdf`\nfail_compilation/fail12047.d(20): Error: undefined identifier `asdf`\nfail_compilation/fail12047.d(21): Error: undefined identifier `asdf`\n---\n*/\n\n@asdf void func() { }\n@asdf int var = 1;\n@asdf enum E : int { a }\n@asdf struct S {}\n@asdf class C {}\n@asdf interface I {}\n@asdf alias int myint;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail121.d",
    "content": "// PERMUTE_ARGS: -d -dw\n// segfault on DMD0.150, never failed if use typeid() instead.\n\nstruct myobject\n{\n    TypeInfo objecttype;\n    void* offset;\n}\n\nmyobject[] list;\n\nvoid foo()\n{\n    int i;\n\n    list[1].typeinfo = i.typeinfo;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail122.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail122.d(12): Error: undefined identifier `y`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=228\n// Crash on inferring function literal return type after prior errors\nvoid main()\n{\n    y = 2;\n    auto x = function(){};\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12236.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12236.d(16): Error: forward reference to inferred return type of function `f1`\nfail_compilation/fail12236.d(16):        while evaluating `pragma(msg, f1.mangleof)`\nfail_compilation/fail12236.d(21): Error: forward reference to inferred return type of function `f2`\nfail_compilation/fail12236.d(21):        while evaluating `pragma(msg, f2(T)(T).mangleof)`\nfail_compilation/fail12236.d(27): Error: template instance `fail12236.f2!int` error instantiating\nfail_compilation/fail12236.d(31): Error: forward reference to inferred return type of function `__lambda1`\nfail_compilation/fail12236.d(31):        while evaluating `pragma(msg, __lambda1.mangleof)`\n---\n*/\n\nauto f1(int)\n{\n    pragma(msg, f1.mangleof);  // forward reference error\n}\n\nauto f2(T)(T)\n{\n    pragma(msg, f2.mangleof);  // error <- weird output: \"v\"\n}\n\nvoid main()\n{\n    f1(1);\n    f2(1);\n\n    (a) {\n        int x;\n        pragma(msg, __traits(parent, x).mangleof);\n    } (1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12255.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12255.d(29): Error: AA key type `SC1` does not have `bool opEquals(ref const SC1) const`\nfail_compilation/fail12255.d(30): Error: AA key type `SC2` does not support const equality\nfail_compilation/fail12255.d(35): Error: AA key type `SD1` should have `size_t toHash() const nothrow @safe` if `opEquals` defined\nfail_compilation/fail12255.d(36): Error: AA key type `SD2` supports const equality but doesn't support const hashing\nfail_compilation/fail12255.d(40): Error: AA key type `SE1` should have `size_t toHash() const nothrow @safe` if `opEquals` defined\nfail_compilation/fail12255.d(41): Error: AA key type `SE2` supports const equality but doesn't support const hashing\n---\n*/\n\nvoid main()\n{\n    /* Key comparison and hashing are based on object bit representation,\n     * and they fully supported in runtime (TypeInfo.equals and TypeInfo.getHash)\n     */\n    int[SA1] a1;    // OK\n    int[SA2] a2;    // OK\n\n    /* If only toHash is defined, AA assumes that is customized object hashing.\n     */\n    int[SB1] b1;    // OK\n    int[SB2] b2;    // OK\n\n    /* If key does not support const equality,\n     * it is disallowed, because TypeInfo.equals will throw Error.\n     */\n    int[SC1] c1;    // NG\n    int[SC2] c2;    // NG\n\n    /* If opEquals defined for const equality, corresponding toHash method\n     * is required to guarantee (a != b || a.toHash() == b.toHash()).\n     */\n    int[SD1] d1;    // NG\n    int[SD2] d2;    // NG\n\n    /* same as SD cases\n     */\n    int[SE1] e1;    // NG\n    int[SE2] e2;    // NG\n}\n\nstruct SA1 { int val; }\nstruct SA2 { SA1 s; }\n\nstruct SB1\n{\n    // AA assumes this is specialized hashing (?)\n    size_t toHash() const nothrow @safe { return 0; }\n}\nstruct SB2\n{\n    SB1 s;\n    // implicit generated toHash() calls s.toHash().\n}\n\nstruct SC1\n{\n    // does not support const equality\n    bool opEquals(typeof(this)) /*const*/ { return true; }\n}\nstruct SC2\n{\n    SC1 s;\n}\n\nstruct SD1\n{\n    // Supports const equality, but\n    // does not have corresponding toHash()\n    bool opEquals(typeof(this)) const { return true; }\n}\nstruct SD2\n{\n    SD1 s;\n}\n\nstruct SE1\n{\n    // Supports const equality, but\n    // does not have corresponding valid toHash()\n    bool opEquals(typeof(this)) const { return true; }\n    size_t toHash() @system { return 0; }\n}\nstruct SE2\n{\n    SE1 s;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12255.d(108): Error: bottom of AA key type `SC1` does not have `bool opEquals(ref const SC1) const`\nfail_compilation/fail12255.d(109): Error: bottom of AA key type `SC2` does not support const equality\nfail_compilation/fail12255.d(110): Error: bottom of AA key type `SD1` should have `size_t toHash() const nothrow @safe` if `opEquals` defined\nfail_compilation/fail12255.d(111): Error: bottom of AA key type `SD2` supports const equality but doesn't support const hashing\nfail_compilation/fail12255.d(112): Error: bottom of AA key type `SE1` should have `size_t toHash() const nothrow @safe` if `opEquals` defined\nfail_compilation/fail12255.d(113): Error: bottom of AA key type `SE2` supports const equality but doesn't support const hashing\n---\n*/\nvoid testSArray()\n{\n    int[SA1[1]] a1;    // OK\n    int[SA2[1]] a2;    // OK\n    int[SB1[1]] b1;    // OK\n    int[SB2[1]] b2;    // OK\n    int[SC1[1]] c1;    // NG\n    int[SC2[1]] c2;    // NG\n    int[SD1[1]] d1;    // NG\n    int[SD2[1]] d2;    // NG\n    int[SE1[1]] e1;    // NG\n    int[SE2[1]] e2;    // NG\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12255.d(133): Error: bottom of AA key type `SC1` does not have `bool opEquals(ref const SC1) const`\nfail_compilation/fail12255.d(134): Error: bottom of AA key type `SC2` does not support const equality\nfail_compilation/fail12255.d(135): Error: bottom of AA key type `SD1` should have `size_t toHash() const nothrow @safe` if `opEquals` defined\nfail_compilation/fail12255.d(136): Error: bottom of AA key type `SD2` supports const equality but doesn't support const hashing\nfail_compilation/fail12255.d(137): Error: bottom of AA key type `SE1` should have `size_t toHash() const nothrow @safe` if `opEquals` defined\nfail_compilation/fail12255.d(138): Error: bottom of AA key type `SE2` supports const equality but doesn't support const hashing\n---\n*/\nvoid testDArray()\n{\n    int[SA1[]] a1;    // OK\n    int[SA2[]] a2;    // OK\n    int[SB1[]] b1;    // OK\n    int[SB2[]] b2;    // OK\n    int[SC1[]] c1;    // NG\n    int[SC2[]] c2;    // NG\n    int[SD1[]] d1;    // NG\n    int[SD2[]] d2;    // NG\n    int[SE1[]] e1;    // NG\n    int[SE2[]] e2;    // NG\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail123.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail123.d(11): Error: undefined identifier `type`\nfail_compilation/fail123.d(17): Error: enum `fail123.foo2` base type must not be `void`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=355\n// ICE from enum : nonexistent type\nenum foo : type\n{\n    blah1,\n    blah2\n}\n\nenum foo2 : void { a, b }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12378.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12378.d(18): Error: undefined identifier `ANYTHING`\nfail_compilation/fail12378.d(18): Error: undefined identifier `GOES`\nfail_compilation/fail12378.d(91):        instantiated from here: `MapResultS!((x0) => ANYTHING - GOES, Result)`\nfail_compilation/fail12378.d(17):        instantiated from here: `mapS!(Result)`\nfail_compilation/fail12378.d(100):        instantiated from here: `__lambda1!int`\nfail_compilation/fail12378.d(91):        instantiated from here: `MapResultS!((y0) => iota(2).mapS!((x0) => ANYTHING - GOES), Result)`\nfail_compilation/fail12378.d(16):        instantiated from here: `mapS!(Result)`\n---\n*/\nvoid testS()\n{\n    auto r =\n    iota(1).mapS!(y0 =>\n        iota(2).mapS!(x0 =>\n            ANYTHING-GOES\n        )\n    );\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12378.d(40): Error: undefined identifier `ANYTHING`\nfail_compilation/fail12378.d(40): Error: undefined identifier `GOES`\nfail_compilation/fail12378.d(112):        instantiated from here: `MapResultC!((x0) => ANYTHING - GOES, Result)`\nfail_compilation/fail12378.d(39):        instantiated from here: `mapC!(Result)`\nfail_compilation/fail12378.d(123):        instantiated from here: `__lambda1!int`\nfail_compilation/fail12378.d(112):        instantiated from here: `MapResultC!((y0) => iota(2).mapC!((x0) => ANYTHING - GOES), Result)`\nfail_compilation/fail12378.d(38):        instantiated from here: `mapC!(Result)`\n---\n*/\nvoid testC()\n{\n    auto r =\n    iota(1).mapC!(y0 =>\n        iota(2).mapC!(x0 =>\n            ANYTHING-GOES\n        )\n    );\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12378.d(64): Error: undefined identifier `ANYTHING`\nfail_compilation/fail12378.d(64): Error: undefined identifier `GOES`\nfail_compilation/fail12378.d(135):        instantiated from here: `MapResultI!((x0) => ANYTHING - GOES, Result)`\nfail_compilation/fail12378.d(63):        instantiated from here: `mapI!(Result)`\nfail_compilation/fail12378.d(143):        instantiated from here: `__lambda1!int`\nfail_compilation/fail12378.d(135):        instantiated from here: `MapResultI!((y0) => iota(2).mapI!((x0) => ANYTHING - GOES), Result)`\nfail_compilation/fail12378.d(62):        instantiated from here: `mapI!(Result)`\n---\n*/\n\n\nvoid testI()\n{\n    auto r =\n    iota(1).mapI!(y0 =>\n        iota(2).mapI!(x0 =>\n            ANYTHING-GOES\n        )\n    );\n}\n\nauto iota(E)(E end)\n{\n    alias Value = E;\n\n    static struct Result\n    {\n        private Value current, pastLast;\n\n        @property inout(Value) front() inout { return current; }\n    }\n\n    return Result(0, end);\n}\n\ntemplate mapS(fun...)\n{\n    auto mapS(R)(R r)\n    {\n        alias AppliedReturnType(alias f) = typeof(f(r.front));\n        static assert(!is(AppliedReturnType!fun == void),\n            \"Mapping function must not return void.\");\n\n        return MapResultS!(fun, R)(r);\n    }\n}\nstruct MapResultS(alias fun, R)\n{\n    R _input;\n\n    @property auto ref front()\n    {\n        return fun(_input.front);\n    }\n}\n\ntemplate mapC(fun...)\n{\n    auto mapC(R)(R r)\n    {\n        alias AppliedReturnType(alias f) = typeof(f(r.front));\n        static assert(!is(AppliedReturnType!fun == void),\n            \"Mapping function must not return void.\");\n\n        return new MapResultC!(fun, R)(r);\n    }\n}\nclass MapResultC(alias fun, R)\n{\n    R _input;\n\n    this(R r) { _input = r; }\n\n    @property auto ref front()\n    {\n        return fun(_input.front);\n    }\n}\n\ntemplate mapI(fun...)\n{\n    auto mapI(R)(R r)\n    {\n        alias AppliedReturnType(alias f) = typeof(f(r.front));\n        static assert(!is(AppliedReturnType!fun == void),\n            \"Mapping function must not return void.\");\n\n        return MapResultI!(fun, R).init;\n    }\n}\ninterface MapResultI(alias fun, R)\n{\n    static @property auto ref front()\n    {\n        R _input;\n        return fun(_input.front);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12390.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12390.d(14): Error: `fun().i == 4` has no effect\n---\n*/\n\nstruct S { int i; }\n\nS fun() { return S(42); }\n\nvoid main()\n{\n    fun().i == 4;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail124.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail124.d(15): Error: class `fail124.CC` inherits from duplicate interface `C`\n---\n*/\n\n//import std.stdio;\n\ninterface C\n{\n    void f();\n}\n\nclass CC : C, C\n{\n    void f() { /*writefln(\"hello\");*/ }\n}\n\nvoid main()\n{\n    CC cc = new CC();\n    cc.f();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12436.d",
    "content": "alias void FuncType();\n\nstruct Opaque;\n\ntemplate Tuple(T...) { alias T Tuple; }\nalias Tuple!(int, int) TupleType;\n\n/******************************************/\n// return type\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12436.d(18): Error: functions cannot return a function\nfail_compilation/fail12436.d(19): Error: functions cannot return a tuple\n---\n*/\nFuncType test1();\nTupleType test2();\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12436.d(28): Error: functions cannot return opaque type `Opaque` by value\nfail_compilation/fail12436.d(29): Error: functions cannot return opaque type `Opaque[1]` by value\n---\n*/\nOpaque    ret12436a();  // error\nOpaque[1] ret12436b();  // error\nOpaque*   ret12436c();  // no error\nOpaque[]  ret12436d();  // no error\nOpaque[]* ret12436e();  // no error\n\nref Opaque    ret12436f();  // no error\nref Opaque[1] ret12436g();  // no error\n\n/******************************************/\n// parameter type\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12436.d(46): Error: cannot have parameter of function type `void()`\n---\n*/\nvoid test3(FuncType) {}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12436.d(55): Error: cannot have parameter of opaque type `Opaque` by value\nfail_compilation/fail12436.d(56): Error: cannot have parameter of opaque type `Opaque[1]` by value\n---\n*/\nvoid param12436a(Opaque);     // error\nvoid param12436b(Opaque[1]);  // error\nvoid param12436c(Opaque*);    // no error\nvoid param12436d(Opaque[]);   // no error\nvoid param12436e(Opaque[]*);  // no error\n\nvoid param12436f(ref Opaque);     // no error\nvoid param12436g(ref Opaque[1]);  // no error\nvoid param12436h(out Opaque);     // no error\nvoid param12436i(out Opaque[1]);  // no error\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12436.d(75): Error: cannot have parameter of opaque type `A14906` by value\nfail_compilation/fail12436.d(76): Error: cannot have parameter of opaque type `A14906[3]` by value\nfail_compilation/fail12436.d(77): Error: cannot have parameter of opaque type `A14906[3][3]` by value\n---\n*/\nenum A14906;\nvoid f14906a(A14906) {}\nvoid f14906b(A14906[3]) {}\nvoid f14906c(A14906[3][3]) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12485.d",
    "content": "void dorecursive()\n{\n    recursive!\"ratherLongSymbolNameToHitTheMaximumSymbolLengthEarlierThanTheTemplateRecursionLimit_\";\n}\n\nvoid recursive(string name)()\n{\n    struct S {} // define type to kick off mangler\n    static if (name.length <= (4 << 20))\n        recursive!(name ~ name);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail125.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail125.d(15): Error: array index `[2]` is outside array bounds `[0 .. 2]`\nfail_compilation/fail125.d(18): Error: template instance `fail125.main.recMove!(1, a, b)` error instantiating\nfail_compilation/fail125.d(25):        instantiated from here: `recMove!(0, a, b)`\n---\n*/\n\n\ntemplate recMove(int i, X...)\n{\n    void recMove()\n    {\n        X[i] = X[i+1];\n        // I know the code is logically wrong, should test (i+2 < X.length)\n        static if (i+1 < X.length)\n            recMove!(i+1, X);\n    }\n}\n\nvoid main()\n{\n    int a, b;\n    recMove!(0, a, b);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12567.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12567.d(8): Error: string expected, not '\"a\" ~ \"b\"'\n---\n*/\ndeprecated(\"a\" ~ \"b\") module fail12567;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail126.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail126.d(8): Error: forward reference to `test`\n---\n*/\n\nvoid test(typeof(test) p)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12604.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12604.d(14): Error: mismatched array lengths, 1 and 3\nfail_compilation/fail12604.d(15): Error: mismatched array lengths, 1 and 3\nfail_compilation/fail12604.d(17): Error: mismatched array lengths, 1 and 3\nfail_compilation/fail12604.d(18): Error: mismatched array lengths, 1 and 3\nfail_compilation/fail12604.d(20): Error: cannot implicitly convert expression `[65536]` of type `int[]` to `short[]`\nfail_compilation/fail12604.d(21): Error: cannot implicitly convert expression `[65536, 2, 3]` of type `int[]` to `short[]`\n---\n*/\nvoid main()\n{\n      int[1] a1 = [1,2,3];\n    short[1] a2 = [1,2,3];\n\n      int[1] b1; b1 = [1,2,3];\n    short[1] b2; b2 = [1,2,3];\n\n    short[1] c = [65536];\n    short[1] d = [65536,2,3];\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12604.d(39): Error: mismatched array lengths, 2 and 3\nfail_compilation/fail12604.d(40): Error: mismatched array lengths, 2 and 3\nfail_compilation/fail12604.d(41): Error: mismatched array lengths, 2 and 3\nfail_compilation/fail12604.d(42): Error: mismatched array lengths, 2 and 3\nfail_compilation/fail12604.d(43): Error: mismatched array lengths, 2 and 3\nfail_compilation/fail12604.d(44): Error: mismatched array lengths, 2 and 3\nfail_compilation/fail12604.d(45): Error: mismatched array lengths, 2 and 3\nfail_compilation/fail12604.d(46): Error: mismatched array lengths, 2 and 3\n---\n*/\nvoid test12606a()   // AssignExp::semantic\n{\n      uint[2] a1 = [1, 2, 3][];\n    ushort[2] a2 = [1, 2, 3][];\n      uint[2] a3 = [1, 2, 3][0 .. 3];\n    ushort[2] a4 = [1, 2, 3][0 .. 3];\n    a1 = [1, 2, 3][];\n    a2 = [1, 2, 3][];\n    a3 = [1, 2, 3][0 .. 3];\n    a4 = [1, 2, 3][0 .. 3];\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12604.d(60): Error: mismatched array lengths, 2 and 3\nfail_compilation/fail12604.d(61): Error: mismatched array lengths, 2 and 3\nfail_compilation/fail12604.d(62): Error: mismatched array lengths, 2 and 3\nfail_compilation/fail12604.d(63): Error: mismatched array lengths, 2 and 3\n---\n*/\nvoid test12606b()   // ExpInitializer::semantic\n{\n    static   uint[2] a1 = [1, 2, 3][];\n    static   uint[2] a2 = [1, 2, 3][0 .. 3];\n    static ushort[2] a3 = [1, 2, 3][];\n    static ushort[2] a4 = [1, 2, 3][0 .. 3];\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12604.d(77): Error: mismatched array lengths, 4 and 3\nfail_compilation/fail12604.d(78): Error: mismatched array lengths, 4 and 3\n---\n*/\nvoid testc()\n{\n    int[4] sa1;\n    int[3] sa2;\n    sa1[0..4] = [1,2,3];\n    sa1[0..4] = sa2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12622.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12622.d(26): Error: `pure` function `fail12622.foo` cannot call impure function pointer `fp`\nfail_compilation/fail12622.d(26): Error: `@nogc` function `fail12622.foo` cannot call non-@nogc function pointer `fp`\nfail_compilation/fail12622.d(26): Error: `@safe` function `fail12622.foo` cannot call `@system` function pointer `fp`\nfail_compilation/fail12622.d(28): Error: `pure` function `fail12622.foo` cannot call impure function pointer `fp`\nfail_compilation/fail12622.d(28): Error: `@nogc` function `fail12622.foo` cannot call non-@nogc function pointer `fp`\nfail_compilation/fail12622.d(28): Error: `@safe` function `fail12622.foo` cannot call `@system` function pointer `fp`\nfail_compilation/fail12622.d(30): Error: `pure` function `fail12622.foo` cannot call impure function `fail12622.bar`\nfail_compilation/fail12622.d(30): Error: `@safe` function `fail12622.foo` cannot call `@system` function `fail12622.bar`\nfail_compilation/fail12622.d(20):        `fail12622.bar` is declared here\nfail_compilation/fail12622.d(30): Error: `@nogc` function `fail12622.foo` cannot call non-@nogc function `fail12622.bar`\n---\n*/\n// Note that, today nothrow violation errors are accidentally hidden.\n\n\n\nvoid bar();\n\npure nothrow @nogc @safe void foo()\n{\n    auto fp = &bar;\n\n    (*fp)();\n\n    fp();\n\n    bar();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12636.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12636.d(13): Error: C++ class `fail12636.C` cannot implement D interface `fail12636.D`\n---\n*/\n\ninterface D\n{\n    void foo();\n}\n\nextern(C++) class C : D\n{\n    extern(D) override void foo() { }\n}\n\nvoid main()\n{\n    auto c = new C;\n    c.foo(); // works\n    D d = c;\n    d.foo(); // segfault\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail127.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail127.d(9): Error: a struct is not a valid initializer for a `char[][]`\nfail_compilation/fail127.d(10): Error: a struct is not a valid initializer for a `string[]`\n---\n*/\n\nchar[][] Level2Text1 = {\"LOW\", \"MEDIUM\", \"HIGH\"};\nstring[] Level2Text2 = {\"LOW\", \"MEDIUM\", \"HIGH\"};    // for D2\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12744.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12744.d(38): Error: incompatible parameter storage classes `ref` and `out`\nfail_compilation/fail12744.d(52): Error: template instance `fail12744.bar12744R!(foo12744O)` error instantiating\nfail_compilation/fail12744.d(38): Error: incompatible parameter storage classes `ref` and `lazy`\nfail_compilation/fail12744.d(53): Error: template instance `fail12744.bar12744R!(foo12744L)` error instantiating\nfail_compilation/fail12744.d(39): Error: incompatible parameter storage classes `out` and `ref`\nfail_compilation/fail12744.d(56): Error: template instance `fail12744.bar12744O!(foo12744R)` error instantiating\nfail_compilation/fail12744.d(39): Error: incompatible parameter storage classes `out` and `lazy`\nfail_compilation/fail12744.d(58): Error: template instance `fail12744.bar12744O!(foo12744L)` error instantiating\nfail_compilation/fail12744.d(40): Error: incompatible parameter storage classes `lazy` and `ref`\nfail_compilation/fail12744.d(61): Error: template instance `fail12744.bar12744L!(foo12744R)` error instantiating\nfail_compilation/fail12744.d(40): Error: incompatible parameter storage classes `lazy` and `out`\nfail_compilation/fail12744.d(62): Error: template instance `fail12744.bar12744L!(foo12744O)` error instantiating\nfail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `out`\nfail_compilation/fail12744.d(67): Error: template `fail12744.bar12744A` cannot deduce function from argument types `!(foo12744O)(int)`, candidates are:\nfail_compilation/fail12744.d(41):        `fail12744.bar12744A(alias f)(auto ref PTT12744!f args)`\nfail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `lazy`\nfail_compilation/fail12744.d(68): Error: template `fail12744.bar12744A` cannot deduce function from argument types `!(foo12744L)(int)`, candidates are:\nfail_compilation/fail12744.d(41):        `fail12744.bar12744A(alias f)(auto ref PTT12744!f args)`\n---\n*/\ntemplate PTT12744(func...)\n{\n    static if (is(typeof(func[0]) P == function))\n        alias PTT12744 = P;\n    else\n        static assert(0);\n}\n\nvoid foo12744N(     int x) {}\nvoid foo12744R( ref int x) {}\nvoid foo12744O( out int x) {}\nvoid foo12744L(lazy int x) {}\n\nvoid bar12744N(alias f)(         PTT12744!f args) {}\nvoid bar12744R(alias f)(     ref PTT12744!f args) {}\nvoid bar12744O(alias f)(     out PTT12744!f args) {}\nvoid bar12744L(alias f)(    lazy PTT12744!f args) {}\nvoid bar12744A(alias f)(auto ref PTT12744!f args) {}\n\nvoid main()\n{\n    alias bNN = bar12744N!foo12744N;\n    alias bNR = bar12744N!foo12744R;\n    alias bNO = bar12744N!foo12744O;\n    alias bNL = bar12744N!foo12744L;\n\n    alias bRN = bar12744R!foo12744N;\n    alias bRR = bar12744R!foo12744R;\n    alias bRO = bar12744R!foo12744O;    // error\n    alias bRL = bar12744R!foo12744L;    // error\n\n    alias bON = bar12744O!foo12744N;\n    alias bOR = bar12744O!foo12744R;    // error\n    alias bOO = bar12744O!foo12744O;\n    alias bOL = bar12744O!foo12744L;    // error\n\n    alias bLN = bar12744L!foo12744N;\n    alias bLR = bar12744L!foo12744R;    // error\n    alias bLO = bar12744L!foo12744O;    // error\n    alias bLL = bar12744L!foo12744L;\n\n    bar12744A!foo12744N(1);\n    bar12744A!foo12744R(1);\n    bar12744A!foo12744O(1);     // error\n    bar12744A!foo12744L(1);     // error\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12749.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12749.d(19): Error: immutable field `inum` initialization is not allowed in foreach loop\nfail_compilation/fail12749.d(20): Error: const field `cnum` initialization is not allowed in foreach loop\nfail_compilation/fail12749.d(25): Error: immutable field `inum` initialization is not allowed in nested function `set`\nfail_compilation/fail12749.d(26): Error: const field `cnum` initialization is not allowed in nested function `set`\n---\n*/\nstruct S\n{\n    immutable int inum;\n    const     int cnum;\n\n    this(int i)\n    {\n        foreach (n; Aggr())\n        {\n            inum = i;\n            cnum = i;\n        }\n\n        void set(int i)\n        {\n            inum = i;\n            cnum = i;\n        }\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12749.d(48): Error: immutable variable `inum` initialization is not allowed in foreach loop\nfail_compilation/fail12749.d(49): Error: const variable `cnum` initialization is not allowed in foreach loop\nfail_compilation/fail12749.d(54): Error: immutable variable `inum` initialization is not allowed in nested function `set`\nfail_compilation/fail12749.d(55): Error: const variable `cnum` initialization is not allowed in nested function `set`\n---\n*/\nimmutable int inum;\nconst     int cnum;\nstatic this()\n{\n    int i = 10;\n\n    foreach (n; Aggr())\n    {\n        inum = i;\n        cnum = i;\n    }\n\n    void set(int i)\n    {\n        inum = i;\n        cnum = i;\n    }\n}\n\nstruct Aggr\n{\n    int opApply(int delegate(int) dg) { return dg(1); }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12764.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=12764\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12764.d(20): Error: field `s` must be initialized in constructor\n---\n*/\n\nstruct S\n{\n    @disable this();\n\n    this(string) { }\n    int f;\n}\n\nclass C\n{\n    this(int)\n    {\n        s.f = 1;  // circumvents default ctor!\n    }\n\n    S s;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12809.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nbool cond;\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12809.d(19): Error: `object.Exception` is thrown but not caught\nfail_compilation/fail12809.d(16): Error: `nothrow` function `fail12809.test_finally1` may throw\nfail_compilation/fail12809.d(35): Error: `object.Exception` is thrown but not caught\nfail_compilation/fail12809.d(39): Error: `object.Exception` is thrown but not caught\nfail_compilation/fail12809.d(32): Error: `nothrow` function `fail12809.test_finally3` may throw\n---\n*/\nvoid test_finally1() nothrow\n{\n    try\n        throw new Exception(\"\");        // error\n    finally\n    {}\n}\n\nvoid test_finally2() nothrow\n{\n    try\n        throw new Exception(\"\");        // no error\n    finally\n        assert(0);  // unconditional halt\n}\n\nvoid test_finally3() nothrow\n{\n    try\n        throw new Exception(\"\");        // error\n    finally\n    {\n        if (cond)\n            throw new Exception(\"\");    // error\n        assert(0);  // conditional halt\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12809.d(59): Error: `object.Exception` is thrown but not caught\nfail_compilation/fail12809.d(54): Error: `nothrow` function `fail12809.test_finally4` may throw\nfail_compilation/fail12809.d(75): Error: `object.Exception` is thrown but not caught\nfail_compilation/fail12809.d(79): Error: `object.Exception` is thrown but not caught\nfail_compilation/fail12809.d(70): Error: `nothrow` function `fail12809.test_finally6` may throw\n---\n*/\nvoid test_finally4() nothrow\n{\n    try\n    {}\n    finally\n        throw new Exception(\"\");        // error\n}\n\nvoid test_finally5() nothrow\n{\n    try\n        assert(0);  // unconditional halt\n    finally\n        throw new Exception(\"\");        // no error\n}\n\nvoid test_finally6() nothrow\n{\n    try\n    {\n        if (cond)\n            throw new Exception(\"\");    // error\n        assert(0);  // conditional halt\n    }\n    finally\n        throw new Exception(\"\");        // error\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail129.d",
    "content": "Ä ä;\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail129.d: Error: module `fail129` source file must start with BOM or ASCII character, not \\xC3\n---\n*/\n\nclass Ä\n{\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12901.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12901.d(11): Error: constructor `fail12901.S.this` `in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract\n---\n*/\n\nstruct S\n{\n    int a;\n    this(int n)\n    in { a = n; }\n    // no body\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12908.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12908.d(14): Error: `pure` delegate `fail12908.main.__foreachbody1` cannot call impure function `fail12908.g`\n---\n*/\n\nvoid g() {}\n\nvoid main() pure\n{\n    foreach (k, v; [\"\": \"\"])\n    {\n        g();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail12932.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail12932.d(11): Error: array literal in `@nogc` function `fail12932.foo` may cause a GC allocation\nfail_compilation/fail12932.d(15): Error: array literal in `@nogc` function `fail12932.foo` may cause a GC allocation\n---\n*/\n\nint* foo() @nogc\n{\n    foreach (ref e; [1,2,3])\n    {\n    }\n\n    foreach (ref e; [1,2,3])\n    {\n        return &e;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13064.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13064.d(8): Error: function `fail13064.f` storage class `auto` has no effect if return type is not inferred\n---\n*/\n\nauto void f() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail131.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail131.d(8): Error: function `D main` parameters must be `main()` or `main(string[] args)`\n---\n*/\n\nint main(lazy char[][] args)\n{\n    return args.length;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13116.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13116.d(14): Error: `this` is not an lvalue and cannot be modified\nfail_compilation/fail13116.d(23): Error: `super` is not an lvalue and cannot be modified\n---\n*/\nstruct S\n{\n    ref S notEvil() { return this; } // this should be accepted\n}\nclass C\n{\n    ref C evil() { return this; } // this should be rejected\n}\nvoid main()\n{\n}\n\nclass Base { }\nclass Derived : Base\n{\n    ref Base evil() { return super; } // should be rejected\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13120.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13120.d(13): Error: `pure` delegate `fail13120.g1.__foreachbody2` cannot call impure function `fail13120.f1`\nfail_compilation/fail13120.d(13): Error: `@nogc` delegate `fail13120.g1.__foreachbody2` cannot call non-@nogc function `fail13120.f1`\n---\n*/\nvoid f1() {}\n\nvoid g1(char[] s) pure @nogc\n{\n    foreach (dchar dc; s)\n        f1();\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13120.d(35): Error: `pure` function `fail13120.h2` cannot call impure function `fail13120.g2!().g2`\nfail_compilation/fail13120.d(35): Error: `@safe` function `fail13120.h2` cannot call `@system` function `fail13120.g2!().g2`\nfail_compilation/fail13120.d(27):        `fail13120.g2!().g2` is declared here\nfail_compilation/fail13120.d(35): Error: `@nogc` function `fail13120.h2` cannot call non-@nogc function `fail13120.g2!().g2`\n---\n*/\nvoid f2() {}\n\nvoid g2()(char[] s)\n{\n    foreach (dchar dc; s)\n        f2();\n}\n\nvoid h2() @safe pure @nogc\n{\n    g2(null);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13187.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13187.d(12): Error: `pure` function `fail13187.test` cannot access mutable static data `my_func_ptr`\n---\n*/\n\nint function(int) pure my_func_ptr;\n\nvoid test() pure\n{\n    my_func_ptr(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail132.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail132.d(19): Error: outer class `A` `this` needed to `new` nested class `B`\n---\n*/\n\n//import std.stdio;\n\nclass A\n{\n    class B\n    {\n    }\n}\n\nvoid main()\n{\n    A.B c = new A.B;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13203.d",
    "content": "int v1, v2;\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13203.d(15): Error: alias `fail13203.FA1!1.T` conflicts with alias `fail13203.FA1!1.T` at fail_compilation/fail13203.d(14)\nfail_compilation/fail13203.d(22): Error: template instance `fail13203.FA1!1` error instantiating\nfail_compilation/fail13203.d(20): Error: alias `fail13203.FA2!1.T` conflicts with alias `fail13203.FA2!1.T` at fail_compilation/fail13203.d(19)\nfail_compilation/fail13203.d(23): Error: template instance `fail13203.FA2!1` error instantiating\n---\n*/\ntemplate FA1(int b)\n{\n    alias T = int;\n    static if (b) alias T = uint;\n}\ntemplate FA2(int b)\n{\n    alias T = v1;\n    static if (b) alias T = v2;\n}\nalias A1 = FA1!1;   // type is not overloadable\nalias A2 = FA2!1;   // variable symbol is not overloadable\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13203.d(36): Error: alias `fail13203.FB1!1.T` conflicts with alias `fail13203.FB1!1.T` at fail_compilation/fail13203.d(37)\nfail_compilation/fail13203.d(44): Error: template instance `fail13203.FB1!1` error instantiating\nfail_compilation/fail13203.d(41): Error: alias `fail13203.FB2!1.T` conflicts with alias `fail13203.FB2!1.T` at fail_compilation/fail13203.d(42)\nfail_compilation/fail13203.d(45): Error: template instance `fail13203.FB2!1` error instantiating\n---\n*/\ntemplate FB1(int b)\n{\n    static if (b) alias T = uint;\n    alias T = int;\n}\ntemplate FB2(int b)\n{\n    static if (b) alias T = v2;\n    alias T = v1;\n}\nalias B1 = FB1!1;\nalias B2 = FB2!1;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail133.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail133.d(13): Error: function `D main` circular dependency. Functions cannot be interpreted while being compiled\nfail_compilation/fail133.d(15):        called from here: `main()`\n---\n*/\n\ntemplate t(int t)\n{\n}\n\nint main()\n{\n    return t!(main() + 8);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13336a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13336a.d(28): Error: `choose(true)` is not an lvalue and cannot be modified\n---\n*/\n\nclass Animal {}\nclass Cat : Animal {}\nclass Dog : Animal {}\n\nAnimal animal;\nCat cat;\n\nauto ref choose(bool f)\n{\n    if (f)\n        return cat;\n    else\n        return animal;\n}\n\nvoid main()\n{\n    //pragma(msg, typeof(&choose));\n    static assert(is(typeof(&choose) == Animal function(bool) nothrow @nogc @safe));    // pass\n\n    choose(true) = new Dog();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13336b.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\nint sx;\ndouble sy;\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13336b.d(17): Error: `cast(double)sx` is not an lvalue and cannot be modified\nfail_compilation/fail13336b.d(25): Error: `cast(double)sx` is not an lvalue and cannot be modified\n---\n*/\nref f1(bool f)\n{\n    if (f)\n        return sx;\n    return sy;\n}\n\nref f2(bool f)\n{\n    if (f)\n        return sy;\n    return sx;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail134.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail134.d(13): Error: template instance `foo!(f)` does not match template declaration `foo(T)`\nfail_compilation/fail134.d(14): Error: template instance `fail134.bar!(f)` error instantiating\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=651\n// Assertion failure: 'global.errors' on line 2622 in file 'template.c'\nvoid f() {}\ntemplate foo(T) {}\ntemplate bar(T...) { alias foo!(T) buz; }\nalias bar!(f) a;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13424.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13424.d(12): Error: delegate `fail13424.S.__lambda2` cannot be struct members\nfail_compilation/fail13424.d(17): Error: delegate `fail13424.U.__lambda2` cannot be union members\nfail_compilation/fail13424.d(22): Error: delegate `fail13424.C.__lambda2` cannot be class members\n---\n*/\n\nstruct S\n{\n    void delegate(dchar) onChar = (dchar) {};\n}\n\nunion U\n{\n    void delegate(dchar) onChar = (dchar) {};\n}\n\nclass C\n{\n    void delegate(dchar) onChar = (dchar) {};\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13434_m32.d",
    "content": "// REQUIRED_ARGS: -m32\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13434_m32.d(13): Error: cannot implicitly convert expression `()` of type `()` to `uint`\n---\n*/\n\nalias tuple(A...) = A;\nvoid main()\n{\n    float[] arr;\n    arr[tuple!()] = 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13434_m64.d",
    "content": "// REQUIRED_ARGS: -m64\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13434_m64.d(13): Error: cannot implicitly convert expression `()` of type `()` to `ulong`\n---\n*/\n\nalias tuple(A...) = A;\nvoid main()\n{\n    float[] arr;\n    arr[tuple!()] = 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13435.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=13435\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13435.d(22): Error: cannot implicitly convert expression `d` of type `int[]` to `S!int`\nfail_compilation/fail13435.d(22):        `this._a = d` is the first assignment of `this._a` therefore it represents its initialization\nfail_compilation/fail13435.d(22):        `opAssign` methods are not used for initialization, but for subsequent assignments\n---\n*/\n\nstruct S(T)\n{\n    void opAssign(T[] arg) {}\n}\n\nclass B\n{\n    this(int[] d)\n    {\n        S!int c;\n        _a = d; // Error: cannot implicitly convert expression (d) of type int[] to S!int\n        c = d; // compiles OK\n    }\n\n    S!int _a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13498.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13498.d(11): Error: cannot implicitly convert expression `\"foo\"` of type `string` to `int`\nfail_compilation/fail13498.d(16): Error: template instance `fail13498.foo!()` error instantiating\n---\n*/\n\nint foo()()\n{\n    return \"foo\"; // should fail as well\n}\n\nvoid main()\n{\n    foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13574.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13574.d(21): Error: cannot modify operator `$`\nfail_compilation/fail13574.d(27): Error: cannot modify operator `$`\n---\n*/\n\nstruct Foo\n{\n    void opSlice(size_t a, size_t b) {  }\n    alias opDollar = length;\n    size_t length;\n}\n\nvoid main()\n{\n    Foo foo;\n    foo[0 .. foo.length = 1];\n    assert(foo.length == 1);\n    foo[0 .. $ = 2]; // assigns to the temporary dollar variable\n    //assert(foo.length == 2);\n\n    int[] arr = [1,2,3];\n    auto x = arr[0 .. arr.length = 1];\n    assert(arr.length == 1);\n    auto y = arr[0 .. $ = 2]; // should also be disallowed\n    //assert(arr.length == 2);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail136.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail136.d(11): Deprecation: Built-in hex string literals are deprecated, use `std.conv.hexString` instead.\nfail_compilation/fail136.d(11): Error: `\"\\xef\\xbb\\xbf\"` has no effect\n---\n*/\n\nvoid main()\n{\n    x\"EF BB BF\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13601.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13601.d(13): Error: variable `__ctfe` cannot be read at compile time\nfail_compilation/fail13601.d(14): Error: variable `__ctfe` cannot be read at compile time\nfail_compilation/fail13601.d(15): Error: variable `__ctfe` cannot be read at compile time\nfail_compilation/fail13601.d(16): Error: variable `__ctfe` cannot be read at compile time\n---\n*/\n\nvoid test()\n{\n    static if (__ctfe) {}\n    enum a = __ctfe ? \"a\" : \"b\";\n    static int b = __ctfe * 2;\n    int[__ctfe] sarr;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail137.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=751\n// Compiler segfault on template expansion\n\n    template TypeTuple( TList... )\n    {\n        alias TList TypeTuple;\n    }\n\n    template IndexOf( T, TList... )\n    {\n        static if( TList.length == 0 )\n            const size_t IndexOf = 1;\n        else static if( is( T == typeof( TList[0] ) ) )\n            const size_t IndexOf = 0;\n        else\n            const size_t IndexOf = 1 + IndexOf!( T, (TList[1 .. $]) );\n    }\n\n    void main()\n    {\n        TypeTuple!(int, long) T;\n        printf( \"%u\\n\", IndexOf!(long, T) );\n    }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13701.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13701.d(16): Error: cannot modify `immutable` expression `this.aa[10]`\nfail_compilation/fail13701.d(23): Error: cannot modify `immutable` expression `aa[10]`\nfail_compilation/fail13701.d(24): Error: cannot modify `immutable` expression `aa[10]`\n---\n*/\n\nstruct S\n{\n    immutable(int)[int] aa;\n    this(int n)\n    {\n        aa[10] = 20;    // initializing\n        aa[10] = 30;    // assignment\n    }\n}\n\nvoid main()\n{\n    immutable(int)[int] aa;\n    aa[10] = 20;\n    aa[10]++;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13756.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13756.d(11): Error: `foreach`: index must be type `const(int)`, not `int`\n---\n*/\n\nvoid maiin()\n{\n    int[int] aa = [1:2];\n    foreach (ref int k, v; aa)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13775.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13775.d(17): Error: cannot cast expression `ubytes[0..2]` of type `ubyte[2]` to `ubyte[1]`\nfail_compilation/fail13775.d(18): Error: cannot cast expression `ubytes[0..2]` of type `ubyte[2]` to `ubyte[3]`\nfail_compilation/fail13775.d(19): Error: cannot cast expression `ubytes[0..2]` of type `ubyte[2]` to `byte[1]`\nfail_compilation/fail13775.d(20): Error: cannot cast expression `ubytes[0..2]` of type `ubyte[2]` to `byte[3]`\n---\n*/\n\nvoid main()\n{\n    ubyte[4] ubytes = [1,2,3,4];\n\n    // CT-known slicing succeeds but sizes cannot match\n    auto ng1 = cast(ubyte[1]) ubytes[0 .. 2];   // ubyte[2] to ubyte[1]\n    auto ng2 = cast(ubyte[3]) ubytes[0 .. 2];   // ubyte[2] to ubyte[3]\n    auto ng3 = cast( byte[1]) ubytes[0 .. 2];   // ubyte[2] to  byte[1]\n    auto ng4 = cast( byte[3]) ubytes[0 .. 2];   // ubyte[2] to  byte[3]\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail139.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail139.d(8): Error: forward reference to `test`\n---\n*/\n\nvoid test(typeof(&test) p)\n{\n}\n\nvoid main()\n{\n    test(null);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail13902.d",
    "content": "// REQUIRED_ARGS: -o- -d -m64\n\nstruct S1 { int v; }\nstruct S2 { int* p; }\nclass C { int v; }\n\n#line 6\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13902.d(45): Error: Using the result of a comma expression is not allowed\nfail_compilation/fail13902.d(32): Error: returning `& x` escapes a reference to local variable `x`\nfail_compilation/fail13902.d(33): Error: returning `&s1.v` escapes a reference to local variable `s1`\nfail_compilation/fail13902.d(38): Error: returning `& sa1` escapes a reference to local variable `sa1`\nfail_compilation/fail13902.d(39): Error: returning `&sa2[0][0]` escapes a reference to local variable `sa2`\nfail_compilation/fail13902.d(40): Error: returning `& x` escapes a reference to local variable `x`\nfail_compilation/fail13902.d(41): Error: returning `(& x+4)` escapes a reference to local variable `x`\nfail_compilation/fail13902.d(42): Error: returning `& x + cast(long)x * 4L` escapes a reference to local variable `x`\nfail_compilation/fail13902.d(45): Error: returning `& y` escapes a reference to local variable `y`\n---\n*/\nint* testEscape1()\n{\n    int x, y;\n    int[] da1;\n    int[][] da2;\n    int[1] sa1;\n    int[1][1] sa2;\n    int* ptr;\n    S1 s1;\n    S2 s2;\n    C  c;\n\n    if (0) return &x;               // VarExp\n    if (0) return &s1.v;            // DotVarExp\n    if (0) return s2.p;             // no error\n    if (0) return &c.v;             // no error\n    if (0) return &da1[0];          // no error\n    if (0) return &da2[0][0];       // no error\n    if (0) return &sa1[0];          // IndexExp\n    if (0) return &sa2[0][0];       // IndexExp\n    if (0) return &x;\n    if (0) return &x + 1;           // optimized to SymOffExp == (& x+4)\n    if (0) return &x + x;\n  //if (0) return ptr += &x + 1;    // semantic error\n    if (0)        ptr -= &x - &y;   // no error\n    if (0) return (&x, &y);         // CommaExp\n\n    return null;    // ok\n}\n\n#line 49\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13902.d(88): Error: Using the result of a comma expression is not allowed\nfail_compilation/fail13902.d(75): Error: returning `& x` escapes a reference to parameter `x`, perhaps annotate with `return`\nfail_compilation/fail13902.d(76): Error: returning `&s1.v` escapes a reference to parameter `s1`, perhaps annotate with `return`\nfail_compilation/fail13902.d(81): Error: returning `& sa1` escapes a reference to parameter `sa1`, perhaps annotate with `return`\nfail_compilation/fail13902.d(82): Error: returning `&sa2[0][0]` escapes a reference to parameter `sa2`, perhaps annotate with `return`\nfail_compilation/fail13902.d(83): Error: returning `& x` escapes a reference to parameter `x`, perhaps annotate with `return`\nfail_compilation/fail13902.d(84): Error: returning `(& x+4)` escapes a reference to parameter `x`, perhaps annotate with `return`\nfail_compilation/fail13902.d(85): Error: returning `& x + cast(long)x * 4L` escapes a reference to parameter `x`, perhaps annotate with `return`\nfail_compilation/fail13902.d(88): Error: returning `& y` escapes a reference to parameter `y`, perhaps annotate with `return`\n---\n*/\nint* testEscape2(\n    int x, int y,\n    int[] da1,\n    int[][] da2,\n    int[1] sa1,\n    int[1][1] sa2,\n    int* ptr,\n    S1 s1,\n    S2 s2,\n    C  c,\n)\n{\n    if (0) return &x;               // VarExp\n    if (0) return &s1.v;            // DotVarExp\n    if (0) return s2.p;             // no error\n    if (0) return &c.v;             // no error\n    if (0) return &da1[0];          // no error\n    if (0) return &da2[0][0];       // no error\n    if (0) return &sa1[0];          // IndexExp\n    if (0) return &sa2[0][0];       // IndexExp\n    if (0) return &x;\n    if (0) return &x + 1;           // optimized to SymOffExp == (& x+4)\n    if (0) return  &x + x;\n  //if (0) return ptr += &x + 1;    // semantic error\n    if (0)        ptr -= &x - &y;   // no error\n    if (0) return (&x, &y);         // CommaExp\n\n    return null;    // ok\n}\n\n#line 92\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13902.d(123): Error: Using the result of a comma expression is not allowed\n---\n*/\nint* testEscape3(\n    ref int x, ref int y,\n    ref int[] da1,\n    ref int[][] da2,\n    ref int[1] sa1,\n    ref int[1][1] sa2,\n    ref int* ptr,\n    ref S1 s1,\n    ref S2 s2,\n    ref C  c,\n)\n{\n    if (0) return &x;               // VarExp\n    if (0) return &s1.v;            // DotVarExp\n    if (0) return s2.p;             // no error\n    if (0) return &c.v;             // no error\n    if (0) return &da1[0];          // no error\n    if (0) return &da2[0][0];       // no error\n    if (0) return &sa1[0];          // IndexExp\n    if (0) return &sa2[0][0];       // IndexExp\n    if (0) return ptr = &x;\n    if (0) return ptr = &x + 1;     // optimized to SymOffExp == (& x+4)\n    if (0) return ptr = &x + x;\n  //if (0) return ptr += &x + 1;    // semantic error\n    if (0) return ptr -= &x - &y;   // no error\n    if (0) return (&x, &y);         // CommaExp\n\n    return null;    // ok\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13902.d(150): Error: returning `cast(int[])sa1` escapes a reference to parameter `sa1`, perhaps annotate with `return`\nfail_compilation/fail13902.d(151): Error: returning `cast(int[])sa1` escapes a reference to parameter `sa1`, perhaps annotate with `return`\nfail_compilation/fail13902.d(152): Error: returning `sa1[]` escapes a reference to parameter `sa1`, perhaps annotate with `return`\nfail_compilation/fail13902.d(155): Error: returning `cast(int[])sa2` escapes a reference to local variable `sa2`\nfail_compilation/fail13902.d(156): Error: returning `cast(int[])sa2` escapes a reference to local variable `sa2`\nfail_compilation/fail13902.d(157): Error: returning `sa2[]` escapes a reference to local variable `sa2`\nfail_compilation/fail13902.d(161): Error: returning `cast(int[])s.sa` escapes a reference to local variable `s`\nfail_compilation/fail13902.d(162): Error: returning `cast(int[])s.sa` escapes a reference to local variable `s`\nfail_compilation/fail13902.d(163): Error: returning `s.sa[]` escapes a reference to local variable `s`\nfail_compilation/fail13902.d(166): Error: escaping reference to stack allocated value returned by `makeSA()`\nfail_compilation/fail13902.d(167): Error: escaping reference to stack allocated value returned by `makeSA()`\nfail_compilation/fail13902.d(168): Error: escaping reference to stack allocated value returned by `makeSA()`\nfail_compilation/fail13902.d(171): Error: escaping reference to stack allocated value returned by `makeS()`\nfail_compilation/fail13902.d(172): Error: escaping reference to stack allocated value returned by `makeS()`\nfail_compilation/fail13902.d(173): Error: escaping reference to stack allocated value returned by `makeS()`\n---\n*/\nint[] testEscape4(int[3] sa1)       // https://issues.dlang.org/show_bug.cgi?id=9279\n{\n    if (0) return sa1;                      // error <- no error\n    if (0) return cast(int[])sa1;           // error <- no error\n    if (0) return sa1[];                    // error\n\n    int[3] sa2;\n    if (0) return sa2;                      // error\n    if (0) return cast(int[])sa2;           // error\n    if (0) return sa2[];                    // error\n\n    struct S { int[3] sa; }\n    S s;\n    if (0) return s.sa;                     // error <- no error\n    if (0) return cast(int[])s.sa;          // error <- no error\n    if (0) return s.sa[];                   // error\n\n    int[3] makeSA() { int[3] ret; return ret; }\n    if (0) return makeSA();                 // error <- no error\n    if (0) return cast(int[])makeSA();      // error <- no error\n    if (0) return makeSA()[];               // error <- no error\n\n    S makeS() { S s; return s; }\n    if (0) return makeS().sa;               // error <- no error\n    if (0) return cast(int[])makeS().sa;    // error <- no error\n    if (0) return makeS().sa[];             // error <- no error\n\n    return null;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13902.d(201): Error: returning `x` escapes a reference to local variable `x`\nfail_compilation/fail13902.d(202): Error: returning `s1.v` escapes a reference to local variable `s1`\nfail_compilation/fail13902.d(206): Error: returning `sa1[0]` escapes a reference to local variable `sa1`\nfail_compilation/fail13902.d(207): Error: returning `sa2[0][0]` escapes a reference to local variable `sa2`\nfail_compilation/fail13902.d(208): Error: returning `x = 1` escapes a reference to local variable `x`\nfail_compilation/fail13902.d(209): Error: returning `x += 1` escapes a reference to local variable `x`\nfail_compilation/fail13902.d(210): Error: returning `s1.v = 1` escapes a reference to local variable `s1`\nfail_compilation/fail13902.d(211): Error: returning `s1.v += 1` escapes a reference to local variable `s1`\n---\n*/\nref int testEscapeRef1()\n{\n    int x;\n    int[] da1;\n    int[][] da2;\n    int[1] sa1;\n    int[1][1] sa2;\n    S1 s1;\n    C  c;\n\n    if (0) return x;            // VarExp\n    if (0) return s1.v;         // DotVarExp\n    if (0) return c.v;          // no error\n    if (0) return da1[0];       // no error\n    if (0) return da2[0][0];    // no error\n    if (0) return sa1[0];       // IndexExp\n    if (0) return sa2[0][0];    // IndexExp\n    if (0) return x = 1;        // AssignExp\n    if (0) return x += 1;       // BinAssignExp\n    if (0) return s1.v = 1;     // AssignExp (e1 is DotVarExp)\n    if (0) return s1.v += 1;    // BinAssignExp (e1 is DotVarExp)\n\n    static int g;\n    return g;       // ok\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13902.d(240): Error: returning `x` escapes a reference to parameter `x`, perhaps annotate with `return`\nfail_compilation/fail13902.d(241): Error: returning `s1.v` escapes a reference to parameter `s1`, perhaps annotate with `return`\nfail_compilation/fail13902.d(245): Error: returning `sa1[0]` escapes a reference to parameter `sa1`, perhaps annotate with `return`\nfail_compilation/fail13902.d(246): Error: returning `sa2[0][0]` escapes a reference to parameter `sa2`, perhaps annotate with `return`\nfail_compilation/fail13902.d(247): Error: returning `x = 1` escapes a reference to parameter `x`, perhaps annotate with `return`\nfail_compilation/fail13902.d(248): Error: returning `x += 1` escapes a reference to parameter `x`, perhaps annotate with `return`\nfail_compilation/fail13902.d(249): Error: returning `s1.v = 1` escapes a reference to parameter `s1`, perhaps annotate with `return`\nfail_compilation/fail13902.d(250): Error: returning `s1.v += 1` escapes a reference to parameter `s1`, perhaps annotate with `return`\n---\n*/\nref int testEscapeRef2(\n    int x,\n    int[] da1,\n    int[][] da2,\n    int[1] sa1,\n    int[1][1] sa2,\n    S1 s1,\n    C  c,\n)\n{\n    if (0) return x;            // VarExp\n    if (0) return s1.v;         // DotVarExp\n    if (0) return c.v;          // no error\n    if (0) return da1[0];       // no error\n    if (0) return da2[0][0];    // no error\n    if (0) return sa1[0];       // IndexExp\n    if (0) return sa2[0][0];    // IndexExp\n    if (0) return x = 1;        // AssignExp\n    if (0) return x += 1;       // BinAssignExp\n    if (0) return s1.v = 1;     // AssignExp (e1 is DotVarExp)\n    if (0) return s1.v += 1;    // BinAssignExp (e1 is DotVarExp)\n\n    static int g;\n    return g;       // ok\n}\n\n/*\nTEST_OUTPUT:\n---\n---\n*/\nref int testEscapeRef2(\n    ref int x,\n    ref int[] da1,\n    ref int[][] da2,\n    ref int[1] sa1,\n    ref int[1][1] sa2,\n    ref S1 s1,\n    ref C  c,\n)\n{\n    if (0) return x;            // VarExp\n    if (0) return s1.v;         // DotVarExp\n    if (0) return c.v;          // no error\n    if (0) return da1[0];       // no error\n    if (0) return da2[0][0];    // no error\n    if (0) return sa1[0];       // IndexExp\n    if (0) return sa2[0][0];    // IndexExp\n    if (0) return x = 1;        // AssignExp\n    if (0) return x += 1;       // BinAssignExp\n    if (0) return s1.v = 1;     // AssignExp (e1 is DotVarExp)\n    if (0) return s1.v += 1;    // BinAssignExp (e1 is DotVarExp)\n\n    static int g;\n    return g;       // ok\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13902.d(294): Error: returning `[& x]` escapes a reference to local variable `x`\nfail_compilation/fail13902.d(295): Error: returning `[& x]` escapes a reference to local variable `x`\n---\n*/\nint*[]  testArrayLiteral1() { int x; return [&x]; }\nint*[1] testArrayLiteral2() { int x; return [&x]; }\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13902.d(304): Error: returning `S2(& x)` escapes a reference to local variable `x`\nfail_compilation/fail13902.d(305): Error: returning `new S2(& x)` escapes a reference to local variable `x`\n---\n*/\nS2  testStructLiteral1() { int x; return     S2(&x); }\nS2* testStructLiteral2() { int x; return new S2(&x); }\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13902.d(314): Error: returning `sa[]` escapes a reference to local variable `sa`\nfail_compilation/fail13902.d(315): Error: returning `sa[cast(ulong)n..2][1..2]` escapes a reference to local variable `sa`\n---\n*/\nint[] testSlice1() { int[3] sa; return sa[]; }\nint[] testSlice2() { int[3] sa; int n; return sa[n..2][1..2]; }\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13902.d(323): Error: returning `vda[0]` escapes a reference to parameter `vda`, perhaps annotate with `return`\n---\n*/\nref int testDynamicArrayVariadic1(int[] vda...) { return vda[0]; }\n@safe int[]   testDynamicArrayVariadic2(int[] vda...) { return vda[]; }\nint[3]  testDynamicArrayVariadic3(int[] vda...) { return vda[0..3]; }   // no error\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail13902.d(334): Error: returning `vsa[0]` escapes a reference to parameter `vsa`, perhaps annotate with `return`\nfail_compilation/fail13902.d(335): Error: returning `vsa[]` escapes a reference to variadic parameter `vsa`\n---\n*/\nref int testStaticArrayVariadic1(int[3] vsa...) { return vsa[0]; }\nint[]   testStaticArrayVariadic2(int[3] vsa...) { return vsa[]; }\nint[3]  testStaticArrayVariadic3(int[3] vsa...) { return vsa[0..3]; }   // no error\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14.d",
    "content": "\nclass A(T)\n{\n    .A!(A) x;\n\n}\n\nvoid main()\n{\n\tA!(int);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14009.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14009.d(12): Error: expression expected not `:`\n---\n*/\n\nvoid main()\n{\n  version(GNU)\n  {\n    asm {\n      \"\" : : \"r\" 1 ? 2 : 3;       // accepted\n      \"\" : : \"r\" 1 ? 2 : : 3;     // rejected\n    }\n  }\n  else\n  {\n    asm {\n      mov EAX, FS: 1 ? 2 : 3;     // accepted\n      mov EAX, FS: 1 ? 2 : : 3;   // rejected\n    }\n  }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14089.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14089.d(41): Error: `1` has no effect\nfail_compilation/fail14089.d(41): Error: `1` has no effect\nfail_compilation/fail14089.d(42): Error: `1` has no effect\nfail_compilation/fail14089.d(42): Error: `n` has no effect\nfail_compilation/fail14089.d(43): Error: `1` has no effect\nfail_compilation/fail14089.d(43): Error: `s.val` has no effect\nfail_compilation/fail14089.d(44): Error: `n` has no effect\nfail_compilation/fail14089.d(44): Error: `1` has no effect\nfail_compilation/fail14089.d(45): Error: `s.val` has no effect\nfail_compilation/fail14089.d(45): Error: `1` has no effect\n---\n*/\n\nbool cond;\n\nvoid main()\n{\n    int foo() { return 0; }\n    int n;\n    struct S { int val; }\n    S s;\n\n    // The whole of each CondExps has side effects, So no error.\n    cond ? foo() : n;\n    cond ? foo() : s.val;\n    cond ? 1     : foo();\n    cond ? n     : foo();\n    cond ? s.val : foo();\n\n    cond ? (n = 1) : 1;\n    cond ? (n = 1) : n;\n    cond ? (n = 1) : s.val;\n    cond ? 1       : (n = 1);\n    cond ? n       : (n = 1);\n    cond ? s.val   : (n = 1);\n\n    // errors\n    cond ? 1     : 1;\n    cond ? 1     : n;\n    cond ? 1     : s.val;\n    cond ? n     : 1;\n    cond ? s.val : 1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail142.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail142.d(20): Error: cannot create instance of abstract class `B`\nfail_compilation/fail142.d(20):        function `void test()` is not implemented\n---\n*/\n\nclass A\n{\n    abstract void test() {}\n}\n\nclass B : A\n{\n}\n\nvoid main()\n{\n    B b = new B();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14249.d",
    "content": "/*\nREQUIRED_ARGS: -unittest\nTEST_OUTPUT:\n---\nfail_compilation/fail14249.d(25): Error: `shared static` constructor can only be member of module/aggregate/template, not function `main`\nfail_compilation/fail14249.d(26): Error: `shared static` destructor can only be member of module/aggregate/template, not function `main`\nfail_compilation/fail14249.d(27): Error: `static` constructor can only be member of module/aggregate/template, not function `main`\nfail_compilation/fail14249.d(28): Error: `static` destructor can only be member of module/aggregate/template, not function `main`\nfail_compilation/fail14249.d(29): Error: `unittest` can only be a member of module/aggregate/template, not function `main`\nfail_compilation/fail14249.d(30): Error: `invariant` can only be a member of aggregate, not function `main`\nfail_compilation/fail14249.d(31): Error: alias this can only be a member of aggregate, not function `main`\nfail_compilation/fail14249.d(32): Deprecation: class allocators have been deprecated, consider moving the allocation strategy outside of the class\nfail_compilation/fail14249.d(32): Error: allocator can only be a member of aggregate, not function `main`\nfail_compilation/fail14249.d(33): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14249.d(33): Error: deallocator can only be a member of aggregate, not function `main`\nfail_compilation/fail14249.d(34): Error: constructor can only be a member of aggregate, not function `main`\nfail_compilation/fail14249.d(35): Error: destructor can only be a member of aggregate, not function `main`\nfail_compilation/fail14249.d(36): Error: postblit can only be a member of struct, not function `main`\nfail_compilation/fail14249.d(37): Error: anonymous union can only be a part of an aggregate, not function `main`\nfail_compilation/fail14249.d(41): Error: mixin `fail14249.main.Mix!()` error instantiating\n---\n*/\nmixin template Mix()\n{\n    shared static this() {}\n    shared static ~this() {}\n    static this() {}    // from fail197.d, 1510 ICE: Assertion failure: 'ad' on line 925 in file 'func.c'\n    static ~this() {}\n    unittest {}\n    invariant {}\n    alias a this;\n    new(size_t sz) { return null; }\n    delete(void* p) { }\n    this() {}           // from fail268.d\n    ~this() {}          // from fail268.d\n    this(this) {}\n    union { int x; double y; }\n}\nvoid main()\n{\n    mixin Mix!();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail143.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail143.d(23): Error: need `this` for `next` of type `uint()`\nfail_compilation/fail143.d(30): Error: template instance `fail143.Foo!int` error instantiating\n---\n*/\n\nclass Quux\n{\n    uint x;\n\n    final uint next()\n    {\n        return x;\n    }\n}\n\ntemplate Foo(T)\n{\n    void bar()\n    {\n        int r = Quux.next;\n    }\n}\n\nint main(char[][] args)\n{\n    auto prng = new Quux();\n    alias Foo!(int).bar baz;\n\n    int x = prng.next;\n    baz();\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14304.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14304.d(26): Error: cannot modify read-only constant `S14304(1)`\nfail_compilation/fail14304.d(58):        called from here: `sle14304.modify()`\nfail_compilation/fail14304.d(35): Error: cannot modify read-only constant `[1:1, 2:2]`\nfail_compilation/fail14304.d(61):        called from here: `modify14304(aae14304)`\nfail_compilation/fail14304.d(41): Error: cannot modify read-only constant `[1, 2, 3]`\nfail_compilation/fail14304.d(64):        called from here: `modify14304(cast(const(int)[])index14304)`\nfail_compilation/fail14304.d(47): Error: cannot modify read-only constant `[1.414, 1.732, 2.00000]`\nfail_compilation/fail14304.d(67):        called from here: `modify14304(cast(const(double)[])slice14304)`\nfail_compilation/fail14304.d(53): Error: cannot modify read-only string literal `\"abc\"`\nfail_compilation/fail14304.d(70):        called from here: `modify14304(cast(const(char)[])str14304)`\n---\n*/\n\nstruct S14304\n{\n    int x;\n\n    int modify() const\n    {\n        assert(x == 1);\n\n        // This force modification must not affect to ghe s14304 value.\n        (cast(S14304*)&this).x = 10;\n\n        assert(x == 10);\n        return x;\n    }\n}\nint modify14304(immutable int[int] aa)\n{\n    auto p = cast(int*)&aa[1];\n    *p = 10;\n    return aa[1];\n}\nint modify14304(const(int)[] arr)\n{\n    auto a = cast(int[])arr;\n    a[0] = 10;\n    return arr[0];\n}\nint modify14304(const(double)[] arr)\n{\n    auto a = cast(double[])arr;\n    a[] = 3.14;\n    return cast(int)arr[0];\n}\nint modify14304(const(char)[] str)\n{\n    auto s = cast(char[])str;\n    s[0] = 'z';\n    return str[0];\n}\n\nstatic immutable sle14304 = immutable S14304(1);\nstatic immutable v14304 = sle14304.modify();\n\nstatic immutable aae14304 = [1:1, 2:2];\nstatic immutable w14304 = modify14304(aae14304);\n\nstatic immutable index14304 = [1, 2, 3];\nstatic immutable x14304 = modify14304(index14304);\n\nstatic immutable slice14304 = [1.414, 1.732, 2];\nstatic immutable y14304 = modify14304(slice14304);\n\nstatic immutable str14304 = \"abc\";\nstatic immutable z14304 = modify14304(str14304);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail144.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail144.d(13): Error: `\"message\"`\nfail_compilation/fail144.d(26):        called from here: `bar(7)`\n---\n*/\n\n//import core.stdc.stdio : printf;\n\nint bar(int i)\n{\n    assert(i < 0, \"message\");\n    foreach_reverse (k, v; \"hello\")\n    {\n        i <<= 1;\n        if (k == 2)\n            break;\n        i += v;\n    }\n    return i;\n}\n\nvoid main()\n{\n    static b = bar(7);\n    auto c = bar(7);\n    //printf(\"b = %d, %d\\n\", b, c);\n    assert(b == 674);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14406.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14406.d-mixin-20(20): Error: variable `fail14406.CFrop.bar_obj` cannot be further field because it will change the determined CFrop size\nfail_compilation/fail14406.d-mixin-25(25): Error: variable `fail14406.IFrop.bar_obj` field not allowed in interface\n---\n*/\n\nclass Foo {}\n\nstring strMixin(T)()\n{\n    static if (T.tupleof.length) {}\n    return \"Bar bar_obj;\n    static class Bar {  Foo foo; }\";\n}\n\nclass CFrop\n{\n    mixin(strMixin!(typeof(this)));\n}\n\ninterface IFrop\n{\n    mixin(strMixin!(typeof(this)));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14407.d",
    "content": "import imports.a14407;\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14407.d(23): Deprecation: class `imports.a14407.C` is deprecated\nfail_compilation/fail14407.d(23): Deprecation: allocator `imports.a14407.C.new` is deprecated\nfail_compilation/fail14407.d(23): Error: `pure` function `fail14407.testC` cannot call impure allocator `imports.a14407.C.new`\nfail_compilation/fail14407.d(23): Error: `@safe` function `fail14407.testC` cannot call `@system` allocator `imports.a14407.C.new`\nfail_compilation/imports/a14407.d(5):        `imports.a14407.C.new` is declared here\nfail_compilation/fail14407.d(23): Error: `@nogc` function `fail14407.testC` cannot call non-@nogc allocator `imports.a14407.C.new`\nfail_compilation/fail14407.d(23): Error: class `imports.a14407.C` member `new` is not accessible\nfail_compilation/fail14407.d(23): Error: `pure` function `fail14407.testC` cannot call impure constructor `imports.a14407.C.this`\nfail_compilation/fail14407.d(23): Error: `@safe` function `fail14407.testC` cannot call `@system` constructor `imports.a14407.C.this`\nfail_compilation/imports/a14407.d(9):        `imports.a14407.C.this` is declared here\nfail_compilation/fail14407.d(23): Error: `@nogc` function `fail14407.testC` cannot call non-@nogc constructor `imports.a14407.C.this`\nfail_compilation/fail14407.d(23): Error: class `imports.a14407.C` member `this` is not accessible\nfail_compilation/fail14407.d(23): Error: allocator `imports.a14407.C.new` is not `nothrow`\n---\n*/\nvoid testC() pure nothrow @safe @nogc\n{\n    new(\"arg\") C(0);\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14407.d(23): Error: constructor `imports.a14407.C.this` is not `nothrow`\nfail_compilation/fail14407.d(21): Error: `nothrow` function `fail14407.testC` may throw\nfail_compilation/fail14407.d(50): Deprecation: struct `imports.a14407.S` is deprecated\nfail_compilation/fail14407.d(50): Deprecation: allocator `imports.a14407.S.new` is deprecated\nfail_compilation/fail14407.d(50): Error: `pure` function `fail14407.testS` cannot call impure allocator `imports.a14407.S.new`\nfail_compilation/fail14407.d(50): Error: `@safe` function `fail14407.testS` cannot call `@system` allocator `imports.a14407.S.new`\nfail_compilation/imports/a14407.d(14):        `imports.a14407.S.new` is declared here\nfail_compilation/fail14407.d(50): Error: `@nogc` function `fail14407.testS` cannot call non-@nogc allocator `imports.a14407.S.new`\nfail_compilation/fail14407.d(50): Error: struct `imports.a14407.S` member `new` is not accessible\nfail_compilation/fail14407.d(50): Error: `pure` function `fail14407.testS` cannot call impure constructor `imports.a14407.S.this`\nfail_compilation/fail14407.d(50): Error: `@safe` function `fail14407.testS` cannot call `@system` constructor `imports.a14407.S.this`\nfail_compilation/imports/a14407.d(18):        `imports.a14407.S.this` is declared here\nfail_compilation/fail14407.d(50): Error: `@nogc` function `fail14407.testS` cannot call non-@nogc constructor `imports.a14407.S.this`\nfail_compilation/fail14407.d(50): Error: struct `imports.a14407.S` member `this` is not accessible\nfail_compilation/fail14407.d(50): Error: allocator `imports.a14407.S.new` is not `nothrow`\nfail_compilation/fail14407.d(50): Error: constructor `imports.a14407.S.this` is not `nothrow`\nfail_compilation/fail14407.d(48): Error: `nothrow` function `fail14407.testS` may throw\n---\n*/\nvoid testS() pure nothrow @safe @nogc\n{\n    new(\"arg\") S(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14416.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14416.d(13): Error: template `S(T)` does not have property `sizeof`\n---\n*/\n\nstruct S(T)\n{\n    int x;\n}\n\nenum n = S.sizeof;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14486.d",
    "content": "// REQUIRED_ARGS: -o-\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14486.d(102): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(103): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(104): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(108): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(109): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(110): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(114): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(115): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(116): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(120): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(121): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(122): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail14486.d(126): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(126): Error: `delete c0` is not `@safe` but is used in `@safe` function `test1a`\nfail_compilation/fail14486.d(127): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(127): Error: `pure` function `fail14486.test1a` cannot call impure destructor `fail14486.C1a.~this`\nfail_compilation/fail14486.d(127): Error: `@safe` function `fail14486.test1a` cannot call `@system` destructor `fail14486.C1a.~this`\nfail_compilation/fail14486.d(101):        `fail14486.C1a.~this` is declared here\nfail_compilation/fail14486.d(127): Error: `@nogc` function `fail14486.test1a` cannot call non-@nogc destructor `fail14486.C1a.~this`\nfail_compilation/fail14486.d(128): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(128): Error: `pure` function `fail14486.test1a` cannot call impure destructor `fail14486.C2a.~this`\nfail_compilation/fail14486.d(128): Error: `@safe` function `fail14486.test1a` cannot call `@system` destructor `fail14486.C2a.~this`\nfail_compilation/fail14486.d(102):        `fail14486.C2a.~this` is declared here\nfail_compilation/fail14486.d(128): Error: `@nogc` function `fail14486.test1a` cannot call non-@nogc destructor `fail14486.C2a.~this`\nfail_compilation/fail14486.d(129): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(129): Error: `pure` function `fail14486.test1a` cannot call impure deallocator `fail14486.C3a.delete`\nfail_compilation/fail14486.d(129): Error: `@safe` function `fail14486.test1a` cannot call `@system` deallocator `fail14486.C3a.delete`\nfail_compilation/fail14486.d(103):        `fail14486.C3a.delete` is declared here\nfail_compilation/fail14486.d(129): Error: `@nogc` function `fail14486.test1a` cannot call non-@nogc deallocator `fail14486.C3a.delete`\nfail_compilation/fail14486.d(130): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(130): Error: `delete c4` is not `@safe` but is used in `@safe` function `test1a`\nfail_compilation/fail14486.d(135): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(136): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(137): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(138): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(139): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(136): Error: destructor `fail14486.C1b.~this` is not `nothrow`\nfail_compilation/fail14486.d(137): Error: destructor `fail14486.C2b.~this` is not `nothrow`\nfail_compilation/fail14486.d(138): Error: deallocator `fail14486.C3b.delete` is not `nothrow`\nfail_compilation/fail14486.d(133): Error: `nothrow` function `fail14486.test1b` may throw\nfail_compilation/fail14486.d(144): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(144): Error: `delete s0` is not `@safe` but is used in `@safe` function `test2a`\nfail_compilation/fail14486.d(145): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(145): Error: `pure` function `fail14486.test2a` cannot call impure destructor `fail14486.S1a.~this`\nfail_compilation/fail14486.d(145): Error: `@safe` function `fail14486.test2a` cannot call `@system` destructor `fail14486.S1a.~this`\nfail_compilation/fail14486.d(113):        `fail14486.S1a.~this` is declared here\nfail_compilation/fail14486.d(145): Error: `@nogc` function `fail14486.test2a` cannot call non-@nogc destructor `fail14486.S1a.~this`\nfail_compilation/fail14486.d(146): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(146): Error: `pure` function `fail14486.test2a` cannot call impure destructor `fail14486.S2a.~this`\nfail_compilation/fail14486.d(146): Error: `@safe` function `fail14486.test2a` cannot call `@system` destructor `fail14486.S2a.~this`\nfail_compilation/fail14486.d(114):        `fail14486.S2a.~this` is declared here\nfail_compilation/fail14486.d(146): Error: `@nogc` function `fail14486.test2a` cannot call non-@nogc destructor `fail14486.S2a.~this`\nfail_compilation/fail14486.d(147): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(147): Error: `pure` function `fail14486.test2a` cannot call impure deallocator `fail14486.S3a.delete`\nfail_compilation/fail14486.d(147): Error: `@safe` function `fail14486.test2a` cannot call `@system` deallocator `fail14486.S3a.delete`\nfail_compilation/fail14486.d(115):        `fail14486.S3a.delete` is declared here\nfail_compilation/fail14486.d(147): Error: `@nogc` function `fail14486.test2a` cannot call non-@nogc deallocator `fail14486.S3a.delete`\nfail_compilation/fail14486.d(148): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(153): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(154): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(155): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(156): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(157): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(154): Error: destructor `fail14486.S1b.~this` is not `nothrow`\nfail_compilation/fail14486.d(155): Error: destructor `fail14486.S2b.~this` is not `nothrow`\nfail_compilation/fail14486.d(156): Error: deallocator `fail14486.S3b.delete` is not `nothrow`\nfail_compilation/fail14486.d(151): Error: `nothrow` function `fail14486.test2b` may throw\nfail_compilation/fail14486.d(162): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(162): Error: `delete a0` is not `@safe` but is used in `@safe` function `test3a`\nfail_compilation/fail14486.d(163): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(163): Error: `pure` function `fail14486.test3a` cannot call impure destructor `fail14486.S1a.~this`\nfail_compilation/fail14486.d(163): Error: `@safe` function `fail14486.test3a` cannot call `@system` destructor `fail14486.S1a.~this`\nfail_compilation/fail14486.d(113):        `fail14486.S1a.~this` is declared here\nfail_compilation/fail14486.d(163): Error: `@nogc` function `fail14486.test3a` cannot call non-@nogc destructor `fail14486.S1a.~this`\nfail_compilation/fail14486.d(164): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(164): Error: `pure` function `fail14486.test3a` cannot call impure destructor `fail14486.S2a.~this`\nfail_compilation/fail14486.d(164): Error: `@safe` function `fail14486.test3a` cannot call `@system` destructor `fail14486.S2a.~this`\nfail_compilation/fail14486.d(114):        `fail14486.S2a.~this` is declared here\nfail_compilation/fail14486.d(164): Error: `@nogc` function `fail14486.test3a` cannot call non-@nogc destructor `fail14486.S2a.~this`\nfail_compilation/fail14486.d(165): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(165): Error: `delete a3` is not `@safe` but is used in `@safe` function `test3a`\nfail_compilation/fail14486.d(166): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(166): Error: `delete a4` is not `@safe` but is used in `@safe` function `test3a`\nfail_compilation/fail14486.d(171): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(172): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(173): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(174): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(175): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail14486.d(172): Error: destructor `fail14486.S1b.~this` is not `nothrow`\nfail_compilation/fail14486.d(173): Error: destructor `fail14486.S2b.~this` is not `nothrow`\nfail_compilation/fail14486.d(169): Error: `nothrow` function `fail14486.test3b` may throw\n---\n*/\n\nclass  C0a { }\nclass  C1a {                  ~this() {} }\nclass  C2a {                  ~this() {}  @nogc pure @safe delete(void* p) {} }\nclass  C3a { @nogc pure @safe ~this() {}                   delete(void* p) {} }\nclass  C4a { @nogc pure @safe ~this() {}  @nogc pure @safe delete(void* p) {} }\n\nclass  C0b { }\nclass  C1b {                  ~this() {} }\nclass  C2b {                  ~this() {}           nothrow delete(void* p) {} }\nclass  C3b {          nothrow ~this() {}                   delete(void* p) {} }\nclass  C4b {          nothrow ~this() {}           nothrow delete(void* p) {} }\n\nstruct S0a { }\nstruct S1a {                  ~this() {} }\nstruct S2a {                  ~this() {}  @nogc pure @safe delete(void* p) {} }\nstruct S3a { @nogc pure @safe ~this() {}                   delete(void* p) {} }\nstruct S4a { @nogc pure @safe ~this() {}  @nogc pure @safe delete(void* p) {} }\n\nstruct S0b { }\nstruct S1b {                  ~this() {} }\nstruct S2b {                  ~this() {}           nothrow delete(void* p) {} }\nstruct S3b {          nothrow ~this() {}                   delete(void* p) {} }\nstruct S4b {          nothrow ~this() {}           nothrow delete(void* p) {} }\n\nvoid test1a() @nogc pure @safe\n{\n    C0a   c0;  delete c0;   // error\n    C1a   c1;  delete c1;   // error\n    C2a   c2;  delete c2;   // error\n    C3a   c3;  delete c3;   // error\n    C4a   c4;  delete c4;   // no error\n}\n\nvoid test1b() nothrow\n{\n    C0b   c0;  delete c0;    // no error\n    C1b   c1;  delete c1;    // error\n    C2b   c2;  delete c2;    // error\n    C3b   c3;  delete c3;    // error\n    C4b   c4;  delete c4;    // no error\n}\n\nvoid test2a() @nogc pure @safe\n{\n    S0a*  s0;  delete s0;   // error\n    S1a*  s1;  delete s1;   // error\n    S2a*  s2;  delete s2;   // error\n    S3a*  s3;  delete s3;   // error\n    S4a*  s4;  delete s4;   // no error\n}\n\nvoid test2b() nothrow\n{\n    S0b*  s0;  delete s0;    // no error\n    S1b*  s1;  delete s1;    // error\n    S2b*  s2;  delete s2;    // error\n    S3b*  s3;  delete s3;    // error\n    S4b*  s4;  delete s4;    // no error\n}\n\nvoid test3a() @nogc pure @safe\n{\n    S0a[] a0;  delete a0;   // error\n    S1a[] a1;  delete a1;   // error\n    S2a[] a2;  delete a2;   // error\n    S3a[] a3;  delete a3;   // error\n    S4a[] a4;  delete a4;   // error\n}\n\nvoid test3b() nothrow\n{\n    S0b[] a0;  delete a0;    // no error\n    S1b[] a1;  delete a1;    // error\n    S2b[] a2;  delete a2;    // error\n    S3b[] a3;  delete a3;    // no error\n    S4b[] a4;  delete a4;    // no error\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail145.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail145.d(13): Error: `assert(i < 0)` failed\nfail_compilation/fail145.d(26):        called from here: `bar(7)`\n---\n*/\n\n//import core.stdc.stdio : printf;\n\nint bar(int i)\n{\n    assert(i < 0);\n    foreach_reverse (k, v; \"hello\")\n    {\n        i <<= 1;\n        if (k == 2)\n            break;\n        i += v;\n    }\n    return i;\n}\n\nvoid main()\n{\n    static b = bar(7);\n    auto c = bar(7);\n    //printf(\"b = %d, %d\\n\", b, c);\n    assert(b == 674);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14554.d",
    "content": "// REQUIRED_ARGS: -o-\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14554.d(28): Error: `fail14554.issue14554_1.foo` called with argument types `(int)` matches both:\nfail_compilation/fail14554.d(17):     `fail14554.issue14554_1.foo!bool.foo(int j)`\nand:\nfail_compilation/fail14554.d(18):     `fail14554.issue14554_1.foo!bool.foo(int j)`\nfail_compilation/fail14554.d(29): Error: `fail14554.issue14554_2.foo` called with argument types `(int)` matches both:\nfail_compilation/fail14554.d(22):     `fail14554.issue14554_2.foo!bool.foo(int j)`\nand:\nfail_compilation/fail14554.d(23):     `fail14554.issue14554_2.foo!bool.foo(int j)`\n---\n*/\nstruct issue14554_1 {\n     void foo(T)(int j) {}\n     static void foo(T)(int j) {}\n}\n\nstruct issue14554_2 {\n     static void foo(T)(int j) {}\n     void foo(T)(int j) {}\n}\n\nvoid test14554()\n{\n     issue14554_1.foo!bool(1);    \n     issue14554_2.foo!bool(1);    \n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14669.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14669.d(11): Error: `auto` can only be used as part of `auto ref` for template function parameters\nfail_compilation/fail14669.d(16): Error: template instance `fail14669.foo1!()` error instantiating\nfail_compilation/fail14669.d(12): Error: `auto` can only be used as part of `auto ref` for template function parameters\nfail_compilation/fail14669.d(17): Error: template `fail14669.foo2` cannot deduce function from argument types `!()(int)`, candidates are:\nfail_compilation/fail14669.d(12):        `fail14669.foo2()(auto int a)`\n---\n*/\nvoid foo1()(auto int a) {}\nvoid foo2()(auto int a) {}\n\nvoid test1()\n{\n    alias f1 = foo1!();\n    foo2(1);\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14669.d(29): Error: `auto` can only be used as part of `auto ref` for template function parameters\nfail_compilation/fail14669.d(38): Error: template instance `fail14669.bar1!int` error instantiating\nfail_compilation/fail14669.d(30): Error: `auto` can only be used as part of `auto ref` for template function parameters\nfail_compilation/fail14669.d(40): Error: template instance `fail14669.bar2!int` error instantiating\n---\n*/\nvoid bar1(T)(auto ref T x) {}\nvoid bar2(T)(auto ref T x) {}\n\nvoid test2()\n{\n    int n;\n\n    bar1(1);\n    bar1(n);\n    alias b1 = bar1!(int);\n\n    alias b2 = bar2!(int);\n    bar2(n);\n    bar2(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14965.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14965.d(19): Error: forward reference to inferred return type of function `foo1`\nfail_compilation/fail14965.d(20): Error: forward reference to inferred return type of function `foo2`\nfail_compilation/fail14965.d(22): Error: forward reference to inferred return type of function `bar1`\nfail_compilation/fail14965.d(23): Error: forward reference to inferred return type of function `bar2`\nfail_compilation/fail14965.d(25): Error: forward reference to inferred return type of function `baz1`\nfail_compilation/fail14965.d(26): Error: forward reference to inferred return type of function `baz2`\nfail_compilation/fail14965.d(30): Error: forward reference to inferred return type of function `foo1`\nfail_compilation/fail14965.d(31): Error: forward reference to inferred return type of function `foo2`\nfail_compilation/fail14965.d(33): Error: forward reference to inferred return type of function `bar1`\nfail_compilation/fail14965.d(34): Error: forward reference to inferred return type of function `bar2`\nfail_compilation/fail14965.d(36): Error: forward reference to inferred return type of function `baz1`\nfail_compilation/fail14965.d(37): Error: forward reference to inferred return type of function `baz2`\n---\n*/\n\nauto foo1() { alias F = typeof(foo1); }     // TypeTypeof\nauto foo2() { alias FP = typeof(&foo2); }   // TypeTypeof\n\nauto bar1() { auto fp = &bar1; }            // ExpInitializer\nauto bar2() { auto fp = cast(void function())&bar2; }   // castTo\n\nauto baz1() { return &baz1; }               // ReturnStatement\nauto baz2() { (&baz2); }                    // ExpStatement\n\nclass C\n{\n    auto foo1() { alias F = typeof(this.foo1); }\n    auto foo2() { alias FP = typeof(&this.foo2); }\n\n    auto bar1() { auto fp = &this.bar1; }\n    auto bar2() { auto dg = cast(void delegate())&this.bar2; }\n\n    auto baz1() { return &baz1; }\n    auto baz2() { (&baz2); }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail14997.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=14997\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail14997.d(19): Error: none of the overloads of `this` are callable using argument types `()`, candidates are:\nfail_compilation/fail14997.d(14):        `fail14997.Foo.this(int a)`\nfail_compilation/fail14997.d(15):        `fail14997.Foo.this(string a)`\n---\n*/\n\nclass Foo\n{\n    this (int a) {}\n    this (string a) {}\n}\nvoid main()\n{\n    auto a = new Foo;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15.d",
    "content": "/*\nSegfault on DMD 0.095\nhttp://www.digitalmars.com/d/archives/digitalmars/D/bugs/926.html\n*/\nmodule test;\n\ntemplate Test()\n{\n    bool opIndex(bool x)\n    {\n        return !x;\n    }\n}\n\nvoid main()\n{\n    mixin Test!() xs;\n    bool x = xs[false];\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail150.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail150.d(22): Error: `.new` is only for allocating nested classes\n---\n*/\n\n//import std.stdio;\n\nclass Class1\n{\n}\n\nclass Foo\n{\n}\n\nint main(char[][] argv)\n{\n    Class1 myclass = new Class1;\n\n    myclass.new Foo();\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15044.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail15044.d(30): Error: generated function `fail15044.V.opAssign` cannot be used because it is annotated with `@disable`\n---\n*/\n\nstruct S\n{\n    void opAssign(S) {}\n}\n\nstruct V\n{\n    // `s` has opAssign, so struct V needs to generate member-wise opAssign.\n    // But S.opAssign is not callable on const object, so V.opAssign should be\n    // @disable.\n    const S s;\n\n    // Here, the initializer of x is evaluated in V.semantic2. But\n    // V.opAssign.semantic3 is not yet invoked, so its attribute should be\n    // lazily inferred in functionSemantic even though it's non-instantiated function.\n    enum int x = ()\n    {\n        // Here, the initializer of x is evaluated in V.semantic2, and\n        // V.opAssign.semantic3 is not yet invoked in this time.\n        // Therefore its @disable attribute needs to be inferred by\n        // functionSemantic, even though it's non-instantiated function.\n        V v;\n        v = v;\n    }();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15068.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail15068.d(17): Error: `T!int` is not a valid template instance, because `T` is not a template declaration but a type (`T == int`)\nfail_compilation/fail15068.d(13): Error: template instance `fail15068.Stuff!int` error instantiating\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=15068\n\nvoid main()\n{\n    Stuff!int s;\n}\nstruct Stuff(T)\n{\n    T!int var;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15089.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail15089.d(10): Error: cannot implicitly convert expression `130` of type `int` to `byte`\n---\n*/\n\nenum Pieces {Rook = 2} /* line 1 */\nimmutable int color = 0b10000000;\nbyte piece = Pieces.Rook ^ color;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail152.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail152.d(15): Error: cannot use type `double` as an operand\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=1028\n// Segfault using tuple inside asm code.\nvoid a(X...)(X expr)\n{\n    alias X[0] var1;\n    version(GNU)\n    {\n        asm {\n            \"\" : \"=m\" (X[0]);\n            \"\" : \"=m\" (var1);\n        }\n    }\n    else\n    {\n        asm {\n            //fld double ptr X[0];   // (1) segfaults\n            fstp double ptr var1;    // (2) ICE\n        }\n    }\n}\n\nvoid main()\n{\n   a(3.6);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15292.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail15292.d(27): Error: cannot compare `S15292` because its auto generated member-wise equality has recursive definition\n---\n*/\n\nstruct NullableRef15292(T)\n{\n    inout(T) get() inout\n    {\n        assert(false);\n    }\n\n    alias get this;\n}\n\nstruct S15292\n{\n    NullableRef15292!S15292 n;\n}\n\nvoid main()\n{\n    S15292 s;\n    assert(s == s);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail153.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail153.d(10): Error: class `fail153.Bar` cannot inherit from class `Foo` because it is `final`\n---\n*/\n\nfinal class Foo { }\n\nclass Bar : Foo { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail154.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail154.d(18): Error: template instance `X!(MYP!int)` does not match template declaration `X(T : Policy!T, alias Policy)`\n---\n*/\n\nclass X(T:Policy!(T), alias Policy)\n{\n    mixin Policy!(T);\n}\n\ntemplate MYP(T)\n{\n    void foo(T);\n}\n\nX!(MYP!(int)) x;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail155.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail155.d(19): Error: overlapping initialization for `y`\n---\n*/\n\nstruct S\n{\n    int i;\n    union\n    {\n        int x;\n        int y;\n    }\n    int j;\n}\n\nS s = S( 1, 2, 3, 4 );\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15535.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail15535.d(17): Error: `goto default` not allowed in `final switch` statement\n---\n*/\n\nvoid test()\n{\n    int i;\n    switch (i)\n    {\n    case 0:\n        final switch (i)\n        {\n        case 1:\n            goto default;\n        }\n    default:\n        break;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15550.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail15550.d(25): Error: partial template instance `foo!int` has no type\nfail_compilation/fail15550.d(26): Error: partial template instance `opDispatch!\"_isMatrix\"` has no type\nfail_compilation/fail15550.d(27): Error: partial template instance `baz!\"_isMatrix\"` has no type\n---\n*/\n\nT foo(T, T2)(T2)\n{\n}\n\nstruct Vector\n{\n    void opDispatch(string, U)(U)\n    {\n    }\n\n    void baz(string, U)(U)\n    {\n    }\n}\n\nalias T1 = typeof(foo!int);\nalias T2 = typeof(Vector._isMatrix);\nalias T3 = typeof(Vector.baz!\"_isMatrix\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail156.d",
    "content": "// REQUIRED_ARGS: -d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail156.d(33): Error: overlapping initialization for `y`\nfail_compilation/fail156.d(40): Error: overlapping initialization for `y`\n---\n*/\n\nalias int myint;\n\nstruct S\n{\n    int i;\n    union\n    {\n        int x = 2;\n        int y;\n    }\n    int j = 3;\n    myint k = 4;\n}\n\nvoid main()\n{\n    S s = S( 1, 5 );\n    assert(s.i == 1);\n    assert(s.x == 5);\n    assert(s.y == 5);\n    assert(s.j == 3);\n    assert(s.k == 4);\n\n    static S t = S( 1, 6, 6 );\n    assert(t.i == 1);\n    assert(t.x == 6);\n    assert(t.y == 6);\n    assert(t.j == 3);\n    assert(t.k == 4);\n\n    S u = S( 1, 5, 6 );\n    assert(u.i == 1);\n    assert(u.x == 5);\n    assert(u.y == 5);\n    assert(u.j == 3);\n    assert(u.k == 4);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15616a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail15616a.d(41): Error: none of the overloads of `foo` are callable using argument types `(double)`, candidates are:\nfail_compilation/fail15616a.d(14):        `fail15616a.foo(int a)`\nfail_compilation/fail15616a.d(17):        `fail15616a.foo(int a, int b)`\nfail_compilation/fail15616a.d(26):        `fail15616a.foo(int a, int b, int c)`\nfail_compilation/fail15616a.d(29):        `fail15616a.foo(string a)`\nfail_compilation/fail15616a.d(32):        `fail15616a.foo(string a, string b)`\nfail_compilation/fail15616a.d(41):        ... (3 more, -v to show) ...\n---\n*/\n\nvoid foo(int a)\n{}\n\nvoid foo(int a, int b)\n{}\n\nvoid foo(T)(T a) if (is(T == float))\n{}\n\nvoid foo(T)(T a) if (is(T == char))\n{}\n\nvoid foo(int a, int b, int c)\n{}\n\nvoid foo(string a)\n{}\n\nvoid foo(string a, string b)\n{}\n\nvoid foo(string a, string b, string c)\n{}\n\n\nvoid main()\n{\n    foo(3.14);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15616b.d",
    "content": "/*\nREQUIRED_ARGS: -v\n---\nfail_compilation/fail15616b.d(43): Error: none of the overloads of `foo` are callable using argument types `(double)`, candidates are:\nfail_compilation/fail15616b.d(16):        `fail15616b.foo(int a)`\nfail_compilation/fail15616b.d(19):        `fail15616b.foo(int a, int b)`\nfail_compilation/fail15616b.d(28):        `fail15616b.foo(int a, int b, int c)`\nfail_compilation/fail15616b.d(31):        `fail15616b.foo(string a)`\nfail_compilation/fail15616b.d(34):        `fail15616b.foo(string a, string b)`\nfail_compilation/fail15616b.d(37):        `fail15616b.foo(string a, string b, string c)`\nfail_compilation/fail15616b.d(22):        `fail15616b.foo(T)(T a) if (is(T == float))`\nfail_compilation/fail15616b.d(25):        `fail15616b.foo(T)(T a) if (is(T == char))`\n---\n*/\n\nvoid foo(int a)\n{}\n\nvoid foo(int a, int b)\n{}\n\nvoid foo(T)(T a) if (is(T == float))\n{}\n\nvoid foo(T)(T a) if (is(T == char))\n{}\n\nvoid foo(int a, int b, int c)\n{}\n\nvoid foo(string a)\n{}\n\nvoid foo(string a, string b)\n{}\n\nvoid foo(string a, string b, string c)\n{}\n\n\nvoid main()\n{\n    foo(3.14);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15626.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail15626.d(12): Error: class `fail15626.D` C++ base class `C` needs at least one virtual function\n---\n*/\n\nextern (C++)\n{\n    class C { }\n    interface I { void f(); }\n    class D : C, I\n    {\n        void f() { }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15667.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/a15667.d(16): Error: basic type expected, not `;`\nfail_compilation/imports/a15667.d(19): Error: declaration expected following attribute, not end of file\n---\n*/\n\nvoid main()\n{\n    import imports.a15667;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15691.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail15691.d(15): Error: `c` is not a member of `Foo`\nfail_compilation/fail15691.d(20): Error: `bc` is not a member of `Foo`, did you mean variable `abc`?\n---\n*/\n\nstruct Foo { int a; int abc; }\n\nvoid main()\n{\n    Foo z = {      // line 13\n            a: 3,\n            c: 4,  // line 15\n        };\n\n    Foo z2 = {     // line 18\n            a: 3,\n            bc: 4, // line 20\n        };\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15755.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail15755.d(28): Error: `tuple(123)` has no effect\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=15755\n\nstruct Foo\n{\n    @(123)\n    int a;\n}\n\ntemplate Attributes(As...)\n{\n    alias Attributes = As;\n}\n\ntemplate getattribute(alias member, alias attrs = Attributes!(__traits(getAttributes, member)))\n{\n    alias getattribute = attrs;\n}\n\nvoid main()\n{\n    getattribute!(__traits(getMember, Foo, \"a\"));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail158.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail158.d(17): Error: more initializers than fields (2) of `S`\n---\n*/\n\nstruct S\n{\n    int i;\n    int j = 3;\n}\n\n\nvoid main()\n{\n    S s = S( 1, 5, 6 );\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail15896.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail15896.d(11): Deprecation: module `imports.imp15896` member `thebar` is not visible from module `fail15896`\nfail_compilation/fail15896.d(11): Deprecation: module `imports.imp15896` member `packagebar` is not visible from module `fail15896`\n---\n*/\n\nimport imports.imp15896 : thebar, packagebar;\n\nint func()\n{\n    thebar +=1;\n    packagebar += 1;\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail159.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail159.d(24): Error: static assert:  `foo(S(1, 5), S(1, 4)) == 0` is false\n---\n*/\n\nstruct S\n{\n    int i;\n    int j = 3;\n\n    int opEquals(S e2) { return 1; }\n}\n\nint foo(S s1, S s2)\n{\n    return s1 == s2;\n}\n\nvoid main()\n{\n    static assert(foo( S(1,5), S(1,5) ) == 1);\n    static assert(foo( S(1,5), S(1,4) ) == 0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail16.d",
    "content": "// ICE(template.c) in DMD0.080\n\nint i;\n\ntemplate bar(T)\n{\n  void bar(int x) {}\n}\n\ntemplate foo(alias X)\n{\n  bar!(typeof(X))(X);\n}\n\n\nvoid main()\n{\n  foo!(i);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail160.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail160.d(22): Error: `typeid(fail160.Foo).vtbl` is not yet implemented at compile time\n---\n*/\n\ninterface Foo\n{\n    void work();\n}\ntemplate Wrapper(B, alias Func, int func)\n{\n    alias typeof(&Func) FuncPtr;\n\n    private static FuncPtr get_funcptr() { return func; }\n} \n\n\nint main(char[][] args)\n{\n    auto x = new Wrapper!(Foo, Foo.work, cast(int)(Foo.classinfo.vtbl[0]))();\n\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail161.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail161.d(15): Error: template instance `MetaString!\"2 == 1\"` does not match template declaration `MetaString(String)`\n---\n*/\n\ntemplate MetaString(String)\n{\n    alias String Value;\n}\n\nvoid main()\n{\n    alias MetaString!(\"2 == 1\") S;\n    assert(mixin(S.Value));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail162.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail162.d(25): Error: template `fail162.testHelper` cannot deduce function from argument types `!()(string, string)`, candidates are:\nfail_compilation/fail162.d(10):        `fail162.testHelper(A...)()`\nfail_compilation/fail162.d(30): Error: template instance `fail162.test!(\"hello\", \"world\")` error instantiating\n---\n*/\n\ntemplate testHelper(A ...)\n{\n    char[] testHelper()\n    {\n        char[] result;\n        foreach (t; a)\n        {\n            result ~= \"int \" ~ t ~ \";\\r\\n\";\n        }\n        return result;\n    }\n}\n\ntemplate test(A...)\n{\n    const char[] test = testHelper(A);\n}\n\nint main(char[][] args)\n{\n    mixin(test!(\"hello\", \"world\"));\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail16206a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail16206a.d(14): Error: `bool` expected as third argument of `__traits(getOverloads)`, not `\"Not a bool\"` of type `string`\n---\n*/\n\nstruct S\n{\n    static int foo()() { return 0; }\n}\n\nalias AliasSeq(T...) = T;\nalias allFoos = AliasSeq!(__traits(getOverloads, S, \"foo\", \"Not a bool\"));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail16206b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail16206b.d(14): Error: expected 2 arguments for `hasMember` but had 3\n---\n*/\n\nstruct S\n{\n    static int foo()() { return 0; }\n}\n\nalias AliasSeq(T...) = T;\nalias allFoos = AliasSeq!(__traits(hasMember, S, \"foo\", true));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail163.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail163.d(11): Error: cannot implicitly convert expression `q` of type `const(char)[]` to `char[]`\n---\n*/\nvoid test1()\n{\n    char[] p;\n    const(char)[] q;\n    p = q;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail163.d(24): Error: cannot implicitly convert expression `p` of type `const(int***)` to `const(int)***`\n---\n*/\nvoid test2()\n{\n    const int*** p;\n    const(int)*** cp;\n    cp = p;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail163.d(37): Error: cannot modify `const` expression `p`\n---\n*/\nvoid test3()\n{\n    const(uint***) p;\n    const(int)*** cp;\n    p = cp;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail163.d(50): Error: cannot implicitly convert expression `cp` of type `const(int)***[]` to `const(uint***)[]`\n---\n*/\nvoid test4()\n{\n    const(uint***)[] p;\n    const(int)***[] cp;\n    p = cp;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail163.d(63): Error: cannot modify `const` expression `*p`\n---\n*/\nvoid test5()\n{\n    int x;\n    const(int)* p = &x;\n    *p = 3;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail163.d(76): Error: cannot implicitly convert expression `& x` of type `int*` to `immutable(int)*`\nfail_compilation/fail163.d(77): Error: cannot modify `immutable` expression `*p`\n---\n*/\nvoid test6()\n{\n    int x;\n    immutable(int)* p = &x;\n    *p = 3;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail163.d(89): Error: cannot implicitly convert expression `& x` of type `const(int)*` to `int*`\n---\n*/\nvoid test7()\n{\n    const(int) x = 3;\n    int* p = &x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail16600.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/fail16600.d(22): Error: `fail16600.S.__ctor` called with argument types `(string) const` matches both:\nfail_compilation/fail16600.d(16):     `fail16600.S.this(string _param_0)`\nand:\nfail_compilation/fail16600.d(17):     `fail16600.S.this(string _param_0) immutable`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=16600\n\nstruct S\n{\n    int i;\n\n    this(string) { i = 1; }\n    this(string) immutable { i = 2; }\n}\n\nvoid main()\n{\n    auto a = const(S)(\"abc\");\n    assert(a.i == 2);\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail169.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail169.d(8): Error: cannot have `const out` parameter of type `const(int)`\n---\n*/\n\nvoid foo(const out int x) { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail16997.d",
    "content": "/*\nREQUIRED_ARGS: -de\nTEST_OUTPUT:\n---\nfail_compilation/fail16997.d(31): Deprecation: integral promotion not done for `~c`, use '-transition=intpromote' switch or `~cast(int)(c)`\nfail_compilation/fail16997.d(32): Deprecation: integral promotion not done for `-c`, use '-transition=intpromote' switch or `-cast(int)(c)`\nfail_compilation/fail16997.d(33): Deprecation: integral promotion not done for `+c`, use '-transition=intpromote' switch or `+cast(int)(c)`\nfail_compilation/fail16997.d(36): Deprecation: integral promotion not done for `~w`, use '-transition=intpromote' switch or `~cast(int)(w)`\nfail_compilation/fail16997.d(37): Deprecation: integral promotion not done for `-w`, use '-transition=intpromote' switch or `-cast(int)(w)`\nfail_compilation/fail16997.d(38): Deprecation: integral promotion not done for `+w`, use '-transition=intpromote' switch or `+cast(int)(w)`\nfail_compilation/fail16997.d(41): Deprecation: integral promotion not done for `~sb`, use '-transition=intpromote' switch or `~cast(int)(sb)`\nfail_compilation/fail16997.d(42): Deprecation: integral promotion not done for `-sb`, use '-transition=intpromote' switch or `-cast(int)(sb)`\nfail_compilation/fail16997.d(43): Deprecation: integral promotion not done for `+sb`, use '-transition=intpromote' switch or `+cast(int)(sb)`\nfail_compilation/fail16997.d(46): Deprecation: integral promotion not done for `~ub`, use '-transition=intpromote' switch or `~cast(int)(ub)`\nfail_compilation/fail16997.d(47): Deprecation: integral promotion not done for `-ub`, use '-transition=intpromote' switch or `-cast(int)(ub)`\nfail_compilation/fail16997.d(48): Deprecation: integral promotion not done for `+ub`, use '-transition=intpromote' switch or `+cast(int)(ub)`\nfail_compilation/fail16997.d(51): Deprecation: integral promotion not done for `~s`, use '-transition=intpromote' switch or `~cast(int)(s)`\nfail_compilation/fail16997.d(52): Deprecation: integral promotion not done for `-s`, use '-transition=intpromote' switch or `-cast(int)(s)`\nfail_compilation/fail16997.d(53): Deprecation: integral promotion not done for `+s`, use '-transition=intpromote' switch or `+cast(int)(s)`\nfail_compilation/fail16997.d(56): Deprecation: integral promotion not done for `~us`, use '-transition=intpromote' switch or `~cast(int)(us)`\nfail_compilation/fail16997.d(57): Deprecation: integral promotion not done for `-us`, use '-transition=intpromote' switch or `-cast(int)(us)`\nfail_compilation/fail16997.d(58): Deprecation: integral promotion not done for `+us`, use '-transition=intpromote' switch or `+cast(int)(us)`\n---\n*/\n\nvoid test()\n{\n    int x;\n\n    char c;\n    x = ~c;\n    x = -c;\n    x = +c;\n\n    wchar w;\n    x = ~w;\n    x = -w;\n    x = +w;\n\n    byte sb;\n    x = ~sb;\n    x = -sb;\n    x = +sb;\n\n    ubyte ub;\n    x = ~ub;\n    x = -ub;\n    x = +ub;\n\n    short s;\n    x = ~s;\n    x = -s;\n    x = +s;\n\n    ushort us;\n    x = ~us;\n    x = -us;\n    x = +us;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17.d",
    "content": "struct A(T)\n{\n    mixin B!(T, A!(T));\n}\n\nA!(int) x;\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail170.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail170.d(8): Error: variable `fail170.foo.x` cannot be `final`, perhaps you meant `const`?\n---\n*/\n\nvoid foo(final out int x) { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail172.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail172.d(25): Error: cannot modify `const` expression `c1.x`\nfail_compilation/fail172.d(26): Error: cannot modify `const` expression `c2.x`\nfail_compilation/fail172.d(30): Error: cannot modify `const` expression `s1.x`\nfail_compilation/fail172.d(31): Error: cannot modify `const` expression `s2.x`\n---\n*/\n\nclass C\n{\n    int x;\n}\n\nstruct S\n{\n    int x;\n}\n\nvoid main()\n{\n    const(C) c1 = new C();\n    const C  c2 = new C();\n    c1.x = 3;\n    c2.x = 3;\n\n    const(S) s1;\n    const S  s2;\n    s1.x = 3;\n    s2.x = 3;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17275.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/fail17275.d(12): Error: undefined identifier `ModuleGroup`, did you mean function `moduleGroup`?\nfail_compilation/fail17275.d(12): Error: `inout` on `return` means `inout` must be on a parameter as well for `inout(ModuleGroup)()`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17275\n\nstruct DSO\n{\n    inout(ModuleGroup) moduleGroup() { }\n}\n\nstruct ThreadDSO\n{\n    DSO* _pdso;\n    void[] _tlsRange;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17354.d",
    "content": "/* REQUIRED_ARGS: -de\n * TEST_OUTPUT:\n---\nfail_compilation/fail17354.d(13): Deprecation: cannot implicitly override base class method `object.Object.opEquals` with `fail17354.Foo.opEquals`; add `override` attribute\nfail_compilation/fail17354.d(18): Deprecation: cannot implicitly override base class method `object.Object.opEquals` with `fail17354.Bar.opEquals`; add `override` attribute\n---\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=17354\n\nfinal class Foo\n{\n    bool opEquals(const Object) const {return true;}\n}\n\nclass Bar\n{\n    bool opEquals(const Object) const {return true;}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17382.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail17382.d(9): Error: Cannot pass argument `main()` to `pragma msg` because it is `void`\n---\n*/\n\nvoid main() {}\npragma(msg, main());\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17419.d",
    "content": "\n// https://issues.dlang.org/show_bug.cgi?id=17419\n/* TEST_OUTPUT:\n---\nfail_compilation/fail17419.d(10): Error: argument to `__traits(getLinkage, 64)` is not a declaration\nfail_compilation/fail17419.d(11): Error: expected 1 arguments for `getLinkage` but had 2\n---\n*/\n\nenum s = __traits(getLinkage, 8 * 8);\nenum t = __traits(getLinkage, 8, 8);\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17421.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/fail17421.d(14): Error: argument to `__traits(getFunctionVariadicStyle, 1)` is not a function\nfail_compilation/fail17421.d(14):        while evaluating: `static assert(__traits(getFunctionVariadicStyle, 1) == \"none\")`\nfail_compilation/fail17421.d(15): Error: argument to `__traits(getFunctionVariadicStyle, int*)` is not a function\nfail_compilation/fail17421.d(15):        while evaluating: `static assert(__traits(getFunctionVariadicStyle, int*) == \"none\")`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17421\n\nalias int* x;\n\nstatic assert(__traits(getFunctionVariadicStyle, 1) == \"none\");\nstatic assert(__traits(getFunctionVariadicStyle, x) == \"none\");\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17491.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/fail17491.d(24): Error: `(S17491).init` is not an lvalue and cannot be modified\nfail_compilation/fail17491.d(25): Error: `S17491(0)` is not an lvalue and cannot be modified\nfail_compilation/fail17491.d(27): Error: cannot modify constant `S17491(0).field`\nfail_compilation/fail17491.d(28): Error: cannot modify constant `*&S17491(0).field`\nfail_compilation/fail17491.d(33): Error: `S17491(0)` is not an lvalue and cannot be modified\nfail_compilation/fail17491.d(34): Error: `S17491(0)` is not an lvalue and cannot be modified\nfail_compilation/fail17491.d(36): Error: cannot modify constant `S17491(0).field`\nfail_compilation/fail17491.d(37): Error: cannot modify constant `*&S17491(0).field`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17491\n\nstruct S17491\n{\n    int field;\n    static int var;\n}\n\nvoid test17491()\n{\n    S17491.init = S17491(42);       // NG\n    *&S17491.init = S17491(42);     // NG\n\n    S17491.init.field = 42;         // NG\n    *&S17491.init.field = 42;       // Should be NG\n\n    S17491.init.var = 42;           // OK\n    *&S17491.init.var = 42;         // OK\n\n    S17491(0) = S17491(42);         // NG\n    *&S17491(0) = S17491(42);       // NG\n\n    S17491(0).field = 42;           // NG\n    *&S17491(0).field = 42;         // Should be NG\n\n    S17491(0).var = 42;             // OK\n    *&S17491(0).var = 42;           // OK\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17492.d",
    "content": "/*\nhttps://issues.dlang.org/show_bug.cgi?id=18385\nDisabled for 2.079, s.t. a deprecation cycle can be started with 2.080\nDISABLED: win32 win64 osx linux freebsd dragonflybsd\nTEST_OUTPUT:\n---\nfail_compilation/fail17492.d(20): Error: class `fail17492.C.testE.I` already exists at fail17492.d(13). Perhaps in another function with the same name?\nfail_compilation/fail17492.d(37): Error: struct `fail17492.S.testE.I` already exists at fail17492.d(30). Perhaps in another function with the same name?\n---\nhttps://issues.dlang.org/show_bug.cgi?id=17492\n*/\n\nclass C\n{\n    void testE()\n    {\n        class I\n        {\n        }\n    }\n\n    void testE()\n    {\n        class I\n        {\n        }\n    }\n}\n\nclass S\n{\n    void testE()\n    {\n        struct I\n        {\n        }\n    }\n\n    void testE()\n    {\n        struct I\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17502.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail17502.d(13): Error: function `fail17502.Foo.foo` `void` functions have no result\nfail_compilation/fail17502.d(13): Error: undefined identifier `res`\nfail_compilation/fail17502.d(17): Error: function `fail17502.Foo.bar` `void` functions have no result\nfail_compilation/fail17502.d(17): Error: undefined identifier `res`\n---\n*/\nclass Foo\n{\n    void foo()\n    out (res) { assert(res > 5); }\n    body {}\n\n    auto bar()\n    out (res) { assert (res > 5); }\n    body { return; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17570.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail17570.d(11): Error: cannot use function constraints for non-template functions. Use `static if` instead\nfail_compilation/fail17570.d(11): Error: declaration expected, not `if`\nfail_compilation/fail17570.d(14): Error: `}` expected following members in `struct` declaration at fail_compilation/fail17570.d(10)\n---\n*/\n\nstruct S(T) {\n    void func() if(isIntegral!T)\n    {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail176.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail176.d(13): Error: cannot modify `immutable` expression `a[1]`\nfail_compilation/fail176.d(16): Error: cannot modify `immutable` expression `b[1]`\nfail_compilation/fail176.d(19): Error: cannot modify `const` expression `c[1]`\n---\n*/\n\nvoid foo()\n{\n    auto a = \"abc\";\n    a[1] = 'd';\n\n    immutable char[3] b = \"abc\";\n    b[1] = 'd';\n\n    const char[3] c = \"abc\";\n    c[1] = 'd';\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17602.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail17602.d(16): Error: cannot implicitly convert expression `cast(Status)0` of type `imports.imp17602.Status` to `fail17602.Status`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17602\n\nimport imports.imp17602;\n\nenum Status { off }\n\nvoid main()\n{\n    Status status = imports.imp17602.Status.on;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17612.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/fail17612.d(14): Error: undefined identifier `string`\nfail_compilation/fail17612.d(17): Error: class `object.TypeInfo` missing or corrupt object.d\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17612\n\nmodule object;\n\nclass Object\n{\n    string toString();\n}\n\nclass TypeInfo {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17625.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail17625.d(16): Deprecation: `b17625.boo` is not visible from module `fail17625`\nfail_compilation/fail17625.d(16): Error: function `b17625.boo` is not accessible from module `fail17625`\n---\n*/\n\nmodule fail17625;\n\nimport imports.a17625;\nimport imports.b17625;\n\nvoid main()\n{\n    boo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17630.d",
    "content": "// REQUIRED_ARGS: -de\n// EXTRA_SOURCES: imports/b17630.d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail17630.d(12): Deprecation: Symbol `b17630.Erase` is not visible from module `fail17630` because it is privately imported in module `a17630`\n---\n*/\n\nvoid main()\n{\n    import imports.a17630 : Erase;\n    assert(Erase == 2);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17646.d",
    "content": "/*\nREQUIRED_ARGS: -o-\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/imports/fail17646.d(10): Error: found `}` instead of statement\nfail_compilation/imports/fail17646.d(7): Error: function `imports.fail17646.allTestData!\"\".allTestData` has no `return` statement, but is expected to return a value of type `const(TestData)[]`\nfail_compilation/fail17646.d(16): Error: template instance `imports.fail17646.allTestData!\"\"` error instantiating\nfail_compilation/fail17646.d(19):        instantiated from here: `runTests!\"\"`\n---\n*/\nint runTests(Modules...)()\n{\n    import imports.fail17646;\n\n    allTestData!Modules;\n}\n\nalias fail = runTests!\"\";\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17689.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail17689.d(10): Error: undefined identifier `x`\n---\n*/\nvoid main(){\n    try{}\n    finally int x=3;\n    assert(x==3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail177.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail177.d(22): Error: cannot modify `immutable` expression `j`\nfail_compilation/fail177.d(24): Error: cannot modify `const` expression `i`\nfail_compilation/fail177.d(26): Error: cannot modify `const` expression `s1.x`\nfail_compilation/fail177.d(27): Error: cannot modify `const` expression `*s1.p`\nfail_compilation/fail177.d(29): Error: cannot modify `const` expression `s2.x`\nfail_compilation/fail177.d(30): Error: cannot modify `const` expression `*s2.p`\n---\n*/\n\nstruct S\n{\n    int x;\n    int* p;\n}\n\nvoid test(const(S) s1, const S s2, const(int) i)\n{\n    immutable int j = 3;\n    j = 4;\n\n    i = 4;\n\n    s1.x = 3;\n    *s1.p = 4;\n\n    s2.x = 3;\n    *s2.p = 4;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17722a.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/fail17722a.d(12): Error: static assert:  `__traits(compiles, a1 && a2)` is false\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17722\n\nvoid fail17722a()\n{\n    byte[16] a1, a2;\n    static assert(__traits(compiles, a1 && a2));  // diagnostic was (__error) && (__error)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17722b.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/fail17722b.d(12): Error: static assert:  `__traits(compiles, a1 || a2)` is false\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17722\n\nvoid fail17722b()\n{\n    byte[16] a1, a2;\n    static assert(__traits(compiles, a1 || a2));  // diagnostic was (__error) || (__error)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17842.d",
    "content": "/* REQUIRED_ARGS: -dip1000\n * TEST_OUTPUT:\n---\nfail_compilation/fail17842.d(14): Error: scope variable `p` assigned to non-scope `*q`\nfail_compilation/fail17842.d(23): Error: scope variable `obj` may not be copied into allocated memory\n---\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=17842\n\nvoid* testp(scope void* p) @safe\n{\n    scope void** q;\n    *q = p;        // error\n    void** t;\n    *t = *q;\n    return *t;\n}\n\nObject testobj(scope Object obj) @safe\n{\n    scope Object[] arr;\n    arr ~= obj;         // error\n    Object[] array;\n    array ~= arr;\n    return array[0];\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail179.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail179.d(11): Error: variable `fail179.main.px` cannot be `final`, perhaps you meant `const`?\n---\n*/\n\nvoid main()\n{\n    int x = 3;\n    final px = &x;\n    *px = 4;\n    auto ppx = &px;\n    **ppx = 5;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17927.d",
    "content": "/* REQUIRED_ARGS: -dip1000\n * TEST_OUTPUT:\n---\nfail_compilation/fail17927.d(13): Error: scope variable `this` may not be returned\nfail_compilation/fail17927.d(21): Error: scope variable `ptr` may not be returned\nfail_compilation/fail17927.d(23): Error: scope variable `ptr` may not be returned\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17927\n\nstruct String {\n    const(char)* mem1() const scope @safe { return ptr; }\n\n    inout(char)* mem2() inout scope @safe { return ptr; } // no error because `ref inout` implies `return`\n\n    char* ptr;\n}\n\n\nconst(char)* foo1(scope const(char)* ptr) @safe { return ptr; }\n\ninout(char)* foo2(scope inout(char)* ptr) @safe { return ptr; }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17955.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=17955\n\nalias Alias(alias a) = a;\n\ntemplate isISOExtStringSerializable(T)\n{\n    enum isISOExtStringSerializable = T.fromISOExtString(\"\");\n}\n\ntemplate RedisObjectCollection(){}\n\nstruct RedisStripped(T, bool strip_id = true)\n{\n    alias unstrippedMemberIndices = indicesOf!(Select!(strip_id,\n            isRedisTypeAndNotID, isRedisType), T.tupleof);\n}\n\ntemplate indicesOf(alias PRED, T...)\n{\n    template impl(size_t i)\n    {\n        static if (PRED!T)\n            impl TypeTuple;\n    }\n\n    alias indicesOf = impl!0;\n}\n\ntemplate isRedisType(alias F)\n{\n    enum isRedisType = toRedis!(typeof(F));\n}\n\ntemplate isRedisTypeAndNotID(){}\n\nstring toRedis(T)()\n{\n    static if (isISOExtStringSerializable!T)\n        return;\n}\n\nstruct User\n{\n    SysTime resetCodeExpireTime;\n}\n\nclass RedisUserManController\n{\n    RedisObjectCollection!(RedisStripped!User) m_users;\n}\n\nclass TimeZone\n{\n    abstract bool hasDST();\n}\n\nclass SimpleTimeZone : TimeZone\n{\n    unittest {}\n\n    immutable(SimpleTimeZone) fromISOExtString(S)(S)\n    {\n        new SimpleTimeZone;\n    }\n}\n\nstruct SysTime\n{\n\n    static fromISOExtString(S)(S)\n    {\n        dstring zoneStr;\n\n        try\n            SimpleTimeZone.fromISOExtString(zoneStr);\n\n        catch DateTimeException;\n    }\n}\n\ntemplate Select(bool condition, T...)\n{\n    alias Select = Alias!(T[condition]);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17969.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/fail17969.d(9): Error: no property `sum` for type `MapResult2!((b) => b)`\n---\n * https://issues.dlang.org/show_bug.cgi?id=17969\n */\n \n\nalias fun = a => MapResult2!(b => b).sum;\n\nint[] e;\nstatic assert(!is(typeof(fun(e)) == void));\nvoid foo() { fun(e); }\n\nstruct MapResult2(alias fun)\n{\n    int[] _input;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail17976.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail17976.d(11): Error: constructor `fail17976.S.this` parameter `this.a` is already defined\nfail_compilation/fail17976.d(11): Error: constructor `fail17976.S.this` parameter `this.a` is already defined\n---\n*/\n\nstruct S\n{\n    this(string a, string a, string a)\n    {\n    }\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18.d(14): Error: need upper and lower bound to slice pointer\n---\n*/\n\n// 7/25\n// Internal error: ..\\ztc\\cgcod.c 1464\n\nvoid main ()\n{\n    int x = 3;\n    int[] a = (&x)[];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail180.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail180.d(23): Error: cannot modify `this.x` in `const` function\nfail_compilation/fail180.d(24): Error: cannot modify `this.x` in `const` function\nfail_compilation/fail180.d(38): Error: cannot modify `this.x` in `const` function\nfail_compilation/fail180.d(39): Error: cannot modify `this.x` in `const` function\nfail_compilation/fail180.d(50): Error: variable `fail180.main.t` cannot be `final`, perhaps you meant `const`?\nfail_compilation/fail180.d(62): Error: variable `fail180.test.d` cannot be `final`, perhaps you meant `const`?\n---\n*/\n\nstruct S59\n{\n    int x;\n\n    void foo()\n    {\n        x = 3;\n    }\n    const void bar()\n    {\n        x = 4;\n        this.x = 5;\n    }\n}\n\nclass C\n{\n    int x;\n\n    void foo()\n    {\n        x = 3;\n    }\n    const void bar()\n    {\n        x = 4;\n        this.x = 5;\n    }\n}\n\nvoid main()\n{\n    S59 s;\n\n    s.foo();\n    s.bar();\n\n    final S59 t;\n    t.foo();\n    t.bar();\n}\n\nvoid test()\n{\n    C c = new C;\n\n    c.foo();\n    c.bar();\n\n    final C d = new C;\n    d.foo();\n    d.bar();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18057.d",
    "content": "/**\nTEST_OUTPUT:\n---\nfail_compilation/fail18057.d(16): Error: template instance `RBNode!int` `RBNode` is not a template declaration, it is a struct\nfail_compilation/fail18057.d(13): Error: variable `fail18057.RBNode.copy` recursive initialization of field\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18057\n// Recursive field initializer causes segfault.\nstruct RBNode\n{\n    RBNode *copy = new RBNode;\n}\n\nalias bug18057 = RBNode!int;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18093.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/fail18093.d(19): Error: function `void fail18093.GenericTransitiveVisitor!(ASTCodegen).GenericTransitiveVisitor.ParseVisitMethods!(ASTCodegen).visit()` does not override any function, did you mean to override `extern (C++) void fail18093.ParseTimeVisitor!(ASTCodegen).ParseTimeVisitor.visit()`?\nfail_compilation/fail18093.d(24): Error: mixin `fail18093.GenericTransitiveVisitor!(ASTCodegen).GenericTransitiveVisitor.ParseVisitMethods!(ASTCodegen)` error instantiating\nfail_compilation/fail18093.d(27): Error: template instance `fail18093.GenericTransitiveVisitor!(ASTCodegen)` error instantiating\n---\n * https://issues.dlang.org/show_bug.cgi?id=18093\n */\n\n\nstruct ASTCodegen {}\n\nextern (C++) class ParseTimeVisitor(AST)\n{\n    void visit() {}\n}\ntemplate ParseVisitMethods(AST)\n{\n    override void visit() {}\n}\n\nclass GenericTransitiveVisitor(AST) : ParseTimeVisitor!AST\n{\n    mixin ParseVisitMethods!AST;\n}\n\nalias SemanticTimeTransitiveVisitor = GenericTransitiveVisitor!ASTCodegen;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18143.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18143.d(20): Error: variable `fail18143.S.a` cannot modify parameter 'this' in contract\nfail_compilation/fail18143.d(21): Error: variable `fail18143.S.a` cannot modify parameter 'this' in contract\nfail_compilation/fail18143.d(25): Error: variable `fail18143.S.a` cannot modify parameter 'this' in contract\nfail_compilation/fail18143.d(26): Error: variable `fail18143.S.a` cannot modify parameter 'this' in contract\nfail_compilation/fail18143.d(35): Error: variable `fail18143.C.a` cannot modify parameter 'this' in contract\nfail_compilation/fail18143.d(36): Error: variable `fail18143.C.a` cannot modify parameter 'this' in contract\nfail_compilation/fail18143.d(40): Error: variable `fail18143.C.a` cannot modify parameter 'this' in contract\nfail_compilation/fail18143.d(41): Error: variable `fail18143.C.a` cannot modify parameter 'this' in contract\n---\n*/\n\nstruct S\n{\n    int a;\n\n    this(int n)\n    in { a = n; }   // error, modifying this.a in contract\n    out { a = n; }  // error, modifying this.a in contract\n    do { }\n\n    void foo(int n)\n    in { a = n; }   // error, modifying this.a in contract\n    out { a = n; }  // error, modifying this.a in contract\n    do { }\n}\n\nclass C\n{\n    int a;\n\n    this(int n)\n    in { a = n; }   // error, modifying this.a in contract\n    out { a = n; }  // error, modifying this.a in contract\n    do { }\n\n    void foo(int n)\n    in { a = n; }   // error, modifying this.a in contract\n    out { a = n; }  // error, modifying this.a in contract\n    do { }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18219.d",
    "content": "// EXTRA_SOURCES: imports/b18219.d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18219.d(15): Deprecation: `b18219.Foobar` is not visible from module `fail18219`\nfail_compilation/fail18219.d(16): Error: no property `Bar` for type `AST`\nfail_compilation/fail18219.d(17): Error: no property `fun` for type `AST`, did you mean `b18219.fun`?\nfail_compilation/fail18219.d(18): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?\n---\n*/\nimport imports.a18219;\n\nvoid main()\n{\n    AST.Foobar t;\n    AST.Bar l;\n    AST.fun();\n    AST.Foobar.smeth();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18228.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18228.d(13): Deprecation: Using `this` as a type is deprecated. Use `typeof(this)` instead\nfail_compilation/fail18228.d(14): Deprecation: Using `this` as a type is deprecated. Use `typeof(this)` instead\nfail_compilation/fail18228.d(15): Deprecation: Using `super` as a type is deprecated. Use `typeof(super)` instead\n---\n*/\n\nclass C\n{\n    this(this a) {}\n    this(int a, this b) {}\n    this(super a) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18236.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18236.d(20): Error: cannot cast expression `V(12)` of type `V` to `int`\n---\n*/\n\nstruct V\n{\n    int a;\n}\n\nstruct S\n{\n    enum A = V(12);\n}\n\nvoid main()\n{\n    int b = cast(int)S.A;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18243.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18243.d(14): Error: none of the overloads of `isNaN` are callable using argument types `!()(float)`\n---\n*/\n\nmodule fail18243;\n\nimport imports.a18243;\n\nvoid main()\n{\n    bool b = isNaN(float.nan);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18266.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18266.d(22): Error: declaration `fail18266.main.S` is already defined in another scope in `main` at line `14`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18266\n\nvoid main()\n{\n    foreach (i; 0 .. 10)\n    {\n        struct S\n        {\n            int x;\n        }\n        auto s = S(i);\n    }\n    foreach (i; 11 .. 20)\n    {\n        struct S\n        {\n            int y;\n        }\n        auto s = S(i);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail183.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail183.d(10): Error: redundant attribute `const`\nfail_compilation/fail183.d(10): Error: redundant attribute `scope`\nfail_compilation/fail183.d(11): Error: redundant attribute `in`\n---\n*/\n\nvoid f(in final const scope int x) {}\nvoid g(final const scope in int x) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail184.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail184.d(8): Error: redundant attribute `final`\n---\n*/\n\nfinal final int x;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18417.d",
    "content": "// REQUIRED_ARGS : -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18417.d(11): Deprecation: `const` postblit is deprecated. Please use an unqualified postblit.\nfail_compilation/fail18417.d(12): Deprecation: `immutable` postblit is deprecated. Please use an unqualified postblit.\nfail_compilation/fail18417.d(13): Deprecation: `shared` postblit is deprecated. Please use an unqualified postblit.\n---\n*/\n\nstruct A { this(this) const {} }\nstruct B { this(this) immutable {} }\nstruct C { this(this) shared {} }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail185.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail185.d(10): Error: static assert:  \"An error message\n\tthat spans multiple lines, and also contains such characters as a tab,\n\\ and \".\"\n---\n*/\n\nstatic assert (false,\n\"An error message\n\\tthat spans multiple lines, and also contains such characters as a tab,\n\\\\ and \\\".\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18620.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18620.d(14): Error: `strlen` cannot be interpreted at compile time, because it has no available source code\nfail_compilation/fail18620.d(19):        compile time context created here\nfail_compilation/fail18620.d(14): Error: `strlen` cannot be interpreted at compile time, because it has no available source code\nfail_compilation/fail18620.d(20):        compile time context created here\n---\n*/\nclass A{\n    this(const(char)* s)\n    {\n        import core.stdc.string;\n        auto a=strlen(s);\n    }\n}\n\nvoid main(){\n    static a = new A(\"a\");\n    __gshared b = new A(\"b\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail187.d",
    "content": "// REQUIRED_ARGS: -d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail187.d(16): Error: `catch` at fail_compilation/fail187.d(20) hides `catch` at fail_compilation/fail187.d(24)\n---\n*/\n\n// On DMD 2.000 bug only with typedef, not alias\n\nalias Exception A;\nalias Exception B;\n\nvoid main()\n{\n    try\n    {\n        throw new A(\"test\");\n    }\n    catch (B)\n    {\n        // this shouldn't happen, but does\n    }\n    catch (A)\n    {\n        // this ought to happen?\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18719.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18719\n\n// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18719.d(29): Deprecation: immutable field `x` was initialized in a previous constructor call\n---\n*/\n\nstruct S\n{\n    int x = -1;\n    this(int y) immutable\n    {\n        x = y;\n        import std.stdio;\n        writeln(\"Ctor called with \", y);\n    }\n    void opAssign(int) immutable;\n}\n\nclass C\n{\n    S x;\n    this() immutable\n    {\n        this(42); /* Initializes x. */\n        x = 13; /* Breaking immutable, or ok? */\n    }\n    this(int x) immutable\n    {\n        this.x = x;\n    }\n}\n\nvoid main()\n{\n    new immutable C;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail188.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail188.d(15): Error: function `fail188.Derived.foo` cannot override `final` function `fail188.Base.foo`\n---\n*/\n\nclass Base\n{\n    final void foo() {}\n}\n\nclass Derived : Base\n{\n    void foo() {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18892.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18892.d(20): Error: no property `foo` for type `MT`\nfail_compilation/fail18892.d(21): Error: no property `foo` for type `MT`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18892\n\nstruct MT\n{\n    int _payload;\n    alias _payload this;\n}\n\nvoid main()\n{\n    MT a;\n    a.foo = 3;\n    MT.foo = 3;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail189.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail189.d(10): Error: undefined identifier `foo`\n---\n*/\n\nvoid bar()\n{\n    foo(); // should fail\n}\n\nversion(none):\nvoid foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18970.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18970.d(22): Error: no property `y` for type `S`\nfail_compilation/fail18970.d(29): Error: no property `yyy` for type `S2`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18970\n\nstruct S\n{\n    auto opDispatch(string name)(int)\n    {\n        alias T = typeof(x);\n        static assert(!is(T.U));\n        return 0;\n    }\n}\nvoid f()\n{\n    S().y(1);\n}\n\nstruct S2\n{\n    this(int)\n    {\n        this.yyy;\n    }\n\n    auto opDispatch(string name)()\n    {\n        alias T = typeof(x);\n        static if(is(T.U)) {}\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18985.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18985.d(16): Error: `foo` is not a scalar, it is a `object.Object`\nfail_compilation/fail18985.d(17): Error: `bar` is not a scalar, it is a `shared(Object)`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18985\n\nObject foo;\nshared Object bar;\n\nvoid main()\n{\n    foo += 1;\n    bar += 1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail18994.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail18994.d(19): Error: struct `fail18994.Type1` is not copyable because it is annotated with `@disable`\n---\n*/\nstruct Type2\n{\n    int opApply(int delegate(ref Type1)) { return 0; }\n}\n\nstruct Type1\n{\n    @disable this(this);\n}\n\nvoid test()\n{\n    foreach(b; Type2()) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail190.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail190.d(9): Error: cannot have pointer to `(int, int, int)`\nfail_compilation/fail190.d(16): Error: template instance `fail190.f!(int, int, int)` error instantiating\n---\n*/\n\nT* f(T...)(T x)\n{\n    return null;\n}\n\nvoid main()\n{\n    auto x = f(2,3,4);\n    *x = *x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail1900.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail1900.d(26): Error: template `fail1900.Mix1a!().Foo` matches more than one template declaration:\nfail_compilation/fail1900.d(13):     `Foo(ubyte x)`\nand\nfail_compilation/fail1900.d(14):     `Foo(byte x)`\n---\n*/\n\ntemplate Mix1a()\n{\n    template Foo(ubyte x) {}\n    template Foo(byte x) {}\n}\ntemplate Mix1b()\n{\n    template Foo(int x) {}\n}\n\nmixin Mix1a;\nmixin Mix1b;\n\nvoid test1900a()\n{\n    alias x = Foo!1;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail1900.d(41): Error: `imports.fail1900b.Bar(short n)` at fail_compilation/imports/fail1900b.d(2) conflicts with `imports.fail1900a.Bar(int n)` at fail_compilation/imports/fail1900a.d(2)\n---\n*/\n\nimport imports.fail1900a;\nimport imports.fail1900b;\n\nvoid test1900b()\n{\n    enum x = Bar!1;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail1900.d(65): Error: `fail1900.Mix2b!().Baz(int x)` at fail_compilation/fail1900.d(57) conflicts with `fail1900.Mix2a!().Baz(byte x)` at fail_compilation/fail1900.d(53)\n---\n*/\n\ntemplate Mix2a()\n{\n    template Baz(byte x) {}\n}\ntemplate Mix2b()\n{\n    template Baz(int x) {}\n}\n\nmixin Mix2a;\nmixin Mix2b;\n\nvoid test1900c()\n{\n    alias x = Baz!1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail19038.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/fail19038.d(21): Error: cannot implicitly convert expression `a` of type `string[][]` to `const(string)[][]`\nfail_compilation/fail19038.d(23): Error: cannot modify `const` expression `c[0]`\n---\n * Credit: yshui\n * https://github.com/dlang/dmd/pull/8413#issuecomment-401104961\n * https://issues.dlang.org/show_bug.cgi?id=19038\n */\n\n\nvoid test()\n{\n    /* string[][] is not implicitly converible to const(string)[][],\n     * and there is good reason why:\n     *\n     * https://stackoverflow.com/questions/5055655/double-pointer-const-correctness-warnings-in-c\n     */\n\n    string[][] a = [[\"Lord\"]];\n    const(string)[][] b = a; // assume this works (and it should not)\n    const(string)[] c = [\"Sauron\"];\n    c[0] = \"Mordor\"; // invalid, because c[0] is const(string)\n\n    b[0] = c; // valid, b[0] is const(string)[]\n    // But now, a[0] has become c\n    a[0][0] = \"Nazgul\"; // valid, because a[0][0] is string\n    // But this also changes c[0], which shouldn't be possible\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail19076.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail19076.d(11): Error: no property `V` for type `fail19076.I`\nfail_compilation/fail19076.d(11): Error: `(I).V` cannot be resolved\n---\n*/\n\ninterface P { }\ninterface I : P { }\nauto F = __traits(getVirtualFunctions, I, \"V\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail19098.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail19098.d(18): Error: cannot modify struct instance `a` of type `A` because it contains `const` or `immutable` members\n---\n*/\n\nstruct A\n{\n    const int a;\n    this(int) {}\n}\n\nvoid main()\n{\n    A a = A(2);\n    A b = A(3);\n    a = b;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail19181.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail19181.d(15): Error: undefined identifier `LanguageError`\n---\n*/\nstruct S\n{\n    void opDispatch(string name, T)(T arg) { }\n}\n\nvoid main()\n{\n    S s;\n    s.foo(LanguageError);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail19182.d",
    "content": "// REQUIRED_ARGS: -c\n/*\nTEST_OUTPUT:\n---\ngigi\nfail_compilation/fail19182.d(12): Error: `pragma(msg)` is missing a terminating `;`\n---\n*/\n\nvoid foo()\n{\n    pragma(msg, \"gigi\") // Here\n    static foreach (e; [])\n    {\n        pragma(msg, \"lili\");\n    }\n\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail192.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail192.d(15): Error: outer function context of `fail192.foo` is needed to `new` nested class `fail192.foo.DummyClass`\nfail_compilation/fail192.d(26): Error: template instance `fail192.X!(DummyClass)` error instantiating\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=1336\n// Internal error when trying to construct a class declared within a unittest from a templated class.\nclass X(T)\n{\n    void bar()\n    {\n        auto t = new T;\n    }\n}\n\nvoid foo()\n{\n    class DummyClass\n    {\n    }\n\n    //auto x = new X!(DummyClass);\n    X!(DummyClass) x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail19209.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail19209.d(16): Error: function `fail19209.Spammer.method()` does not override any function, did you mean to override variable `fail19209.Spam.method`?\nfail_compilation/fail19209.d(16):        Functions are the only declarations that may be overriden\n---\n*/\n\nclass Spam\n{\n    int method;\n}\n\nclass Spammer : Spam\n{\n    override method() {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail193.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail193.d(14): Error: cannot infer type from overloaded function symbol `& foo`\n---\n*/\n\nvoid foo() { }\nvoid foo(int) { }\n\nvoid main()\n{\n    //void function(int) fp = &foo;\n    auto fp = &foo;\n    fp(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail19319a.d",
    "content": "/*\nDFLAGS:\nREQUIRED_ARGS: -conf= -Ifail_compilation/extra-files/minimal\nTEST_OUTPUT:\n---\nfail_compilation/fail19319a.d(16): Error: `7 ^^ g19319` requires `std.math` for `^^` operators\nfail_compilation/fail19319a.d(17): Error: `g19319 ^^ 7` requires `std.math` for `^^` operators\n---\n*/\n\n__gshared int g19319 = 0;\n\nstatic assert(!__traits(compiles, 7 ^^ g19319));\nstatic assert(!__traits(compiles, g19319 ^^= 7));\n\n__gshared int e19319 = 7 ^^ g19319;\n__gshared int a19319 = g19319 ^^= 7;;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail19319b.d",
    "content": "/*\nDFLAGS:\nREQUIRED_ARGS: -conf= -Ifail_compilation/extra-files/minimal\nTEST_OUTPUT:\n---\nfail_compilation/fail19319b.d(16): Error: `7 ^^ x` requires `std.math` for `^^` operators\nfail_compilation/fail19319b.d(17): Error: `x ^^ 7` requires `std.math` for `^^` operators\n---\n*/\n\nvoid test19319(int x)\n{\n    static assert(!__traits(compiles, 7 ^^ x));\n    static assert(!__traits(compiles, x ^^= 7));\n\n    int i = 7 ^^ x;\n    x ^^= 7;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail194.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail194.d(18): Error: function `& foo` is overloaded\n---\n*/\n\nimport core.vararg;\n\nvoid bar(int i, ...) { }\n\nvoid foo() { }\nvoid foo(int) { }\n\nvoid main()\n{\n    //bar(1, cast(void function())&foo);\n    bar(1, &foo);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail195.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail195.d(22): Error: struct `Foo` does not overload ()\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=1384\n// Compiler segfaults when using struct variable like a function with no opCall member.\nstruct Foo\n{\n    union\n    {\n        int a;\n        int b;\n    }\n}\n\nvoid bla()\n{\n    Foo next;\n    next(); // Error: structliteral has no effect in expression (Foo(0))\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail196.d",
    "content": "\nvoid main()\n{\n    string s = q\"(foo(xxx)) \";\n    assert(s == \"foo(xxx)\");\n\n    s = q\"[foo[xxx]]\";\n    assert(s == \"foo[xxx]\");\n\n    s = q\"{foo{xxx}}\";\n    assert(s == \"foo{xxx}\");\n\n    s = q\"<foo<xxx>>\";\n    assert(s == \"foo<xxx>\");\n\n    s = q\"[foo(]\";\n    assert(s == \"foo(\");\n\n    s = q\"/foo]/\";\n    assert(s == \"foo]\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail198.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail198.d(8): Error: template instance `test!42` template `test` is not defined\n---\n*/\n\nint x = test!(42);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail199.d",
    "content": "// REQUIRED_ARGS: -de\n\n//import std.stdio;\n\ndeprecated class DepClass\n{\n    void test()\n    {\n        //writefln(\"Accessing what's deprecated!\");\n    }\n}\n\nclass Derived : DepClass {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail20.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail20.d(16): Error: need member function `opCmp()` for struct `FOO` to compare\n---\n*/\n\n// ICE(cod3) DMD0.080\n\nstruct FOO{}\n\nvoid main()\n{\n    FOO one;\n    FOO two;\n    if (one < two){} // This should tell me that there\n                     // is no opCmp() defined instead \n                     // of crashing.\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail200.d",
    "content": "// REQUIRED_ARGS: -de\n\n//import std.stdio;\n\ndeprecated interface DepClass\n{\n    void test();\n}\n\nclass Derived : DepClass\n{\n    void test()\n    {\n        //writefln(\"Accessing what's deprecated!\");\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail201.d",
    "content": "void main() {\n        int c;\n        c = c >>> 33;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail202.d",
    "content": "void main() {\n        int c;\n        c = c >> 33;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail203.d",
    "content": "void main() {\n        int c;\n        c = c << 33;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail204.d",
    "content": "void main() {\n        long c;\n        c >>= 65;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail205.d",
    "content": "void main() {\n        long c;\n        c <<= 65;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail206.d",
    "content": "void main() {\n        long c;\n        c >>>= 65;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail207.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail207.d(10): Error: found end of file instead of initializer\nfail_compilation/fail207.d(10): Error: semicolon expected, not `End of File`\n---\n*/\n\nint x = {\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail208.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail208.d(18): Error: `return` expression expected\nfail_compilation/fail208.d(21):        called from here: `MakeA()`\n---\n*/\n\n\n// https://issues.dlang.org/show_bug.cgi?id=1593\n// ICE compiler crash empty return statement in function\nstruct A\n{\n}\n\nA MakeA()\n{\n    return ;\n}\n\nstatic const A aInstance = MakeA();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail209.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail209.d(20): Error: incompatible types for `(a) -= (x)`: `float` and `fail209.X`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=725\n// expression.c:6516: virtual Expression* MinAssignExp::semantic(Scope*): Assertion `e2->type->isfloating()' failed\nclass X\n{\n    float a;\n}\n\nvoid main()\n{\n    X x;\n    float a;\n\n    a -= x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail212.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail212.d(14): Error: function `fail212.S.bar` without `this` cannot be `const`\n---\n*/\n\nstruct S\n{\n    void foo() const\n    {\n    }\n\n    static void bar() const\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail213.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail213.d(18): Error: template instance `Foo!int` does not match template declaration `Foo(T : immutable(T))`\nfail_compilation/fail213.d(25): Error: template instance `Foo!(const(int))` does not match template declaration `Foo(T : immutable(T))`\n---\n*/\n\ntemplate Foo(T:immutable(T))\n{\n    alias T Foo;\n}\n\nvoid main()\n{\n  {\n    int x;\n    alias Foo!(typeof(x)) f;\n    //printf(\"%s\\n\", typeid(f).toString().ptr);\n    assert(is(typeof(x) == int));\n    assert(is(f == int));\n  }\n  {\n    const int x;\n    alias Foo!(typeof(x)) f;\n  }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail215.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail215.d(10): Error: function `fail215.b.k` cannot be both `final` and `abstract`\n---\n*/\n\nclass b\n{\n    final abstract void k();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail216.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail216.d(16): Error: expression `foo()` is `void` and has no value\nfail_compilation/fail216.d(14): Error: function `fail216.bar` has no `return` statement, but is expected to return a value of type `int`\nfail_compilation/fail216.d(19):        called from here: `bar()`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=1744\n// CTFE: crash on assigning void-returning function to variable\nvoid foo() {}\n\nint bar()\n{\n    int x = foo();\n}\n\nconst y = bar();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail217.d",
    "content": "\nclass Message\n  {\n    public int notifier;\n\n    this( int notifier_object )\n      {\n        notifier = notifier_object;\n      }\n  }\n\nvoid\nmain()\n  {\n    auto m2 = new immutable(Message)(2);\n    m2.notifier = 3;\n  }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail218.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail218.d(15): Error: cannot modify string literal `\", \"`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=1788\n// dmd segfaults without info\nvoid main()\n{\n    string a = \"abc\";\n    double b = 7.5;\n\n    a ~= \", \" ~= b;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail22.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail22.d(13): Error: no identifier for declarator `char`\n---\n*/\n\n// infinite loop on DMD0.080\n\nvoid main()\n{\n    char[] bug = \"Crash\";\n    foreach(char ; bug) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail220.d",
    "content": "template types (T) {\n    static if (is (T V : V[K], K == class)) {\n        static assert (false, \"assoc\");\n    }\n    static const int types = 4;\n}\n\nint i = types!(int);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail221.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail221.d(11): Error: expression `cast(void)0` is `void` and has no value\n---\n*/\n\nvoid main()\n{\n    void[] data;\n    data ~= cast(void) 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail222.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail222.d(10): Error: template `fail222.getMixin(TArg..., int i = 0)()` template tuple parameter must be last one\nfail_compilation/fail222.d(17): Error: template instance `getMixin!()` does not match template declaration `getMixin(TArg..., int i = 0)()`\nfail_compilation/fail222.d(20): Error: template instance `fail222.Thing!()` error instantiating\n---\n*/\n\nstring getMixin(TArg..., int i = 0)()\n{\n    return ``;\n}\n\nclass Thing(TArg...)\n{\n    mixin(getMixin!(TArg)());\n}\n\npublic Thing!() stuff;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail223.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail223.d(14): Error: cannot modify `this.x` in `const` function\n---\n*/\n\n//import std.stdio;\n\nclass A\n{\npublic:\n    int x = 0;\n    void setX(int nx) const { x = nx; }\n}\n\nvoid foo(const A a) { a.setX(1); }\n\nint main(char[][] args)\n{\n    A a = new A;\n    foo(a);\n    //writefln(a.x);\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail224.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail224.d(22): Error: need `this` of type `A` to access member `x` from static function `f`\n---\n*/\n\nint gi;\n\nclass A\n{\n    int x = 42;\n\n    void am()\n    {\n        static void f()\n        {\n            class B\n            {\n                void bm()\n                {\n                    gi = x;\n                }\n            }\n\n            (new B).bm();\n        }\n\n        f();\n    }\n}\n\nvoid main()\n{\n    (new A).am();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail225.d",
    "content": "struct Struct { \n        char* chptr; \n}\n\nvoid main()\n{\n        char ch = 'd';\n        immutable Struct iStruct = {1, &ch};\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail228.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail228.d(22): Error: undefined identifier `localVariable`\n---\n*/\n\n//import core.stdc.stdio : printf;\n\nint ToTypeString(T : int)()\n{\n    return 1;\n}\n\nint ToTypeString(T : string)()\n{\n    return 2;\n}\n\nvoid main()\n{\n    auto x = ToTypeString!(typeof(localVariable))();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail229.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail229.d(11): Error: array index 18446744073709551615 overflow\nfail_compilation/fail229.d(11): Error: array dimension overflow\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=1936\n// Error with no line number (array dimension overflow)\nstatic int[] x = [-1: 1];\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail23.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail23.d(14): Error: `break` is not inside a loop or `switch`\n---\n*/\n\n// ICE(s2ir.c) DMD0.100\n\nvoid main()\n{\n    try\n    {\n        break;\n    }\n    catch (Throwable)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail231.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail231.d(15): Error: class `fail231.Derived` cannot implicitly generate a default constructor when base class `fail231.Base` is missing a default constructor\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=951\n// Missing line number: no constructor provided for a class derived from a class with no default constructor\nclass Base\n{\n    this(int x) {}\n}\n\nclass Derived : Base\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail232.d",
    "content": "void bug1601() {\n    int i;\n\n    i = i >> 33;\n    i = i << 33;\n    i = i >>> 33;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail233.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail233.d(11): Error: variable `fail233.bug1176.v` `void[1]` does not have a default initializer\n---\n*/\n\nvoid bug1176()\n{\n    void[1] v;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail235.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail235.d(12): Error: expression `typeid(char)` is not a valid template value argument\n---\n*/\ntemplate Tuple(TPL...)\n{\n    alias TPL Tuple;\n}\n\nauto K = Tuple!(typeid(char));\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail235.d(24): Error: expression `typeid(char)` is not a valid template value argument\n---\n*/\ntemplate Alias(alias A)\n{\n    alias A Alias;\n}\nauto A = Alias!(typeid(char));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail236.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail236.d(14): Error: undefined identifier `x`\nfail_compilation/fail236.d(22): Error: template `fail236.Templ2` cannot deduce function from argument types `!()(int)`, candidates are:\nfail_compilation/fail236.d(12):        `fail236.Templ2(alias a)(x)`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=870\n// contradictory error messages for templates\ntemplate Templ2(alias a)\n{\n    void Templ2(x)\n    {\n    }\n}\n\nvoid main()\n{\n    int i;\n    Templ2(i);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail2361.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail2361.d(14): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail2361.d(14): Error: cannot modify `immutable` expression `c`\n---\n*/\n\nclass C {}\n\nvoid main()\n{\n    immutable c = new immutable(C);\n    delete c;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail237.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail237.d(11): Error: undefined identifier `a` in module `fail237`\nfail_compilation/fail237.d(11):        while evaluating: `static assert(module fail237.a!().b)`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=581\n// Error message w/o line number in dot-instantiated template\nstatic assert(.a!().b);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail238_m32.d",
    "content": "// REQUIRED_ARGS: -m32\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail238_m32.d(21): Error: cannot implicitly convert expression `\"a\"` of type `string` to `uint`\nfail_compilation/fail238_m32.d(24): Error: cannot interpret `X!()` at compile time\nfail_compilation/fail238_m32.d(29): Error: template instance `fail238_m32.A!\"a\"` error instantiating\nfail_compilation/fail238_m32.d(35):        instantiated from here: `M!(q)`\nfail_compilation/fail238_m32.d(35):        while evaluating `pragma(msg, M!(q))`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=581\n// Error message w/o line number in dot-instantiated template\ntemplate X(){}\n\ntemplate D(string str){}\n\ntemplate A(string str)\n{\n    static if (D!(str[str]))\n    {}\n    else\n        const string A = .X!();\n}\n\ntemplate M(alias B)\n{\n    const string M = A!(\"a\");\n}\n\nvoid main()\n{\n    int q = 3;\n    pragma(msg, M!(q));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail238_m64.d",
    "content": "// REQUIRED_ARGS: -m64\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail238_m64.d(21): Error: cannot implicitly convert expression `\"a\"` of type `string` to `ulong`\nfail_compilation/fail238_m64.d(24): Error: cannot interpret `X!()` at compile time\nfail_compilation/fail238_m64.d(29): Error: template instance `fail238_m64.A!\"a\"` error instantiating\nfail_compilation/fail238_m64.d(35):        instantiated from here: `M!(q)`\nfail_compilation/fail238_m64.d(35):        while evaluating `pragma(msg, M!(q))`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=581\n// Error message w/o line number in dot-instantiated template\ntemplate X(){}\n\ntemplate D(string str){}\n\ntemplate A(string str)\n{\n    static if (D!(str[str]))\n    {}\n    else\n        const string A = .X!();\n}\n\ntemplate M(alias B)\n{\n    const string M = A!(\"a\");\n}\n\nvoid main()\n{\n    int q = 3;\n    pragma(msg, M!(q));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail239.d",
    "content": "class F { int x; }\nalias typeof(F).x b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail24.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail24.d(11): Error: alias `fail24.strtype` conflicts with alias `fail24.strtype` at fail_compilation/fail24.d(10)\nfail_compilation/fail24.d(12): Error: alias `fail24.strtype` conflicts with alias `fail24.strtype` at fail_compilation/fail24.d(11)\nfail_compilation/fail24.d(13): Error: alias `fail24.strtype` conflicts with alias `fail24.strtype` at fail_compilation/fail24.d(12)\n---\n*/\n\nalias char[]  strtype;\nalias char[64] strtype;\nalias char[128] strtype;\nalias char[256] strtype;\n\nint main()\n{\n    printf(\"%u\", strtype.sizeof);\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail240.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail240.d(9): Error: type `F` is not an expression\n---\n*/\n\nclass F { int x; }\nalias typeof(typeof(F).x) b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail241.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail241.d(18): Error: mutable method `fail241.Foo.f` is not callable using a `const` object\nfail_compilation/fail241.d(18):        Consider adding `const` or `inout` to fail241.Foo.f\nfail_compilation/fail241.d(19): Error: mutable method `fail241.Foo.g` is not callable using a `const` object\nfail_compilation/fail241.d(19):        Consider adding `const` or `inout` to fail241.Foo.g\n---\n*/\n\nclass Foo\n{\n    public void f() { }\n    private void g() { }\n\n    invariant()\n    {\n        f();  // error, cannot call public member function from invariant\n        g();  // ok, g() is not public\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail243.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail243.d(23): Deprecation: class `fail243.DepClass` is deprecated\nfail_compilation/fail243.d(24): Deprecation: struct `fail243.DepStruct` is deprecated\nfail_compilation/fail243.d(25): Deprecation: union `fail243.DepUnion` is deprecated\nfail_compilation/fail243.d(26): Deprecation: enum `fail243.DepEnum` is deprecated\nfail_compilation/fail243.d(27): Deprecation: alias `fail243.DepAlias` is deprecated\n---\n*/\n\ndeprecated\n{\n    class DepClass {}\n    struct DepStruct {}\n    union DepUnion {}\n    enum DepEnum { A }\n    alias int DepAlias;\n    //typedef int DepTypedef;\n}\n\nvoid func(DepClass obj) {}\nvoid func(DepStruct obj) {}\nvoid func(DepUnion obj) {}\nvoid func(DepEnum obj) {}\nvoid func(DepAlias obj) {}\n//void func(DepTypedef obj) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail244.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail244.d(27): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\nfail_compilation/fail244.d(28): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\nfail_compilation/fail244.d(29): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\nfail_compilation/fail244.d(30): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\nfail_compilation/fail244.d(32): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\nfail_compilation/fail244.d(33): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\nfail_compilation/fail244.d(34): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\nfail_compilation/fail244.d(35): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\nfail_compilation/fail244.d(36): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\nfail_compilation/fail244.d(37): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n---\n*/\n\n//import std.stdio;\n\nstruct StructWithDeps\n{\n    deprecated int value;\n    deprecated static int staticValue;\n\n    void test(StructWithDeps obj)\n    {\n        obj.value = 666;\n        this.value = 666;\n        auto n1 = obj.value;\n        auto n2 = this.value;\n\n        obj.staticValue = 102;\n        this.staticValue = 103;\n        StructWithDeps.staticValue = 104;\n        auto n3 = obj.staticValue;\n        auto n4 = this.staticValue;\n        auto n5 = StructWithDeps.staticValue;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail245.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail245.d(27): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\nfail_compilation/fail245.d(28): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\nfail_compilation/fail245.d(29): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\nfail_compilation/fail245.d(30): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\nfail_compilation/fail245.d(32): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\nfail_compilation/fail245.d(33): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\nfail_compilation/fail245.d(34): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\nfail_compilation/fail245.d(35): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\nfail_compilation/fail245.d(36): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\nfail_compilation/fail245.d(37): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n---\n*/\n\n//import std.stdio;\n\nclass ClassWithDeps\n{\n    deprecated int value;\n    deprecated static int staticValue;\n\n    void test(ClassWithDeps obj)\n    {\n        obj.value = 666;\n        this.value = 666;\n        auto n1 = obj.value;\n        auto n2 = this.value;\n\n        obj.staticValue = 102;\n        this.staticValue = 103;\n        ClassWithDeps.staticValue = 104;\n        auto n3 = obj.staticValue;\n        auto n4 = this.staticValue;\n        auto n5 = ClassWithDeps.staticValue;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail2456.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail2456.d(14): Error: cannot put `scope(success)` statement inside `finally` block\n---\n*/\nvoid test_success()\n{\n    try\n    {\n    }\n    finally\n    {\n        scope(success) {}           // NG\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail2456.d(31): Error: cannot put `scope(failure)` statement inside `finally` block\n---\n*/\nvoid test_failure()\n{\n    try\n    {\n    }\n    finally\n    {\n        scope(failure) {}           // NG\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\n---\n*/\nvoid test_exit()\n{\n    try\n    {\n    }\n    finally\n    {\n        scope(exit) {}              // OK\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail2456.d(64): Error: cannot put `scope(success)` statement inside `scope(success)`\nfail_compilation/fail2456.d(65): Error: cannot put `scope(failure)` statement inside `scope(success)`\nfail_compilation/fail2456.d(78): Error: cannot put `scope(success)` statement inside `scope(exit)`\nfail_compilation/fail2456.d(79): Error: cannot put `scope(failure)` statement inside `scope(exit)`\n---\n*/\nvoid test2456a()\n{\n    scope(success)\n    {\n        scope(success) {}   // NG\n        scope(failure) {}   // NG\n        scope(exit) {}      // OK\n    }\n\n    scope(failure)\n    {\n        scope(success) {}   // OK\n        scope(failure) {}   // OK\n        scope(exit) {}      // OK\n    }\n\n    scope(exit)\n    {\n        scope(success) {}   // NG\n        scope(failure) {}   // NG\n        scope(exit) {}      // OK\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail2456.d(96): Error: cannot put `catch` statement inside `scope(success)`\nfail_compilation/fail2456.d(108): Error: cannot put `catch` statement inside `scope(exit)`\n---\n*/\nvoid test2456b()\n{\n    scope(success)\n    {\n        try {}\n        catch (Throwable) {}    // NG\n    }\n\n    scope(failure)\n    {\n        try {}\n        catch (Throwable) {}    // OK\n    }\n\n    scope(exit)\n    {\n        try {}\n        catch (Throwable) {}    // NG\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail246.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail246.d-mixin-11(11): Error: identifier expected, not `End of File`\nfail_compilation/fail246.d-mixin-11(11): Error: `;` expected after mixin\n---\n*/\n\nvoid a()\n{\n    mixin(`mixin`);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail247.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail247.d-mixin-9(9): Error: identifier expected, not `End of File`\nfail_compilation/fail247.d-mixin-9(9): Error: `;` expected after mixin\n---\n*/\n\nmixin(`mixin`);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail248.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail248.d(9): Error: type `int` is not an expression\n---\n*/\n\nalias int foo;\ntypeof(foo) a; // ok\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail249.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail249.d(16): Error: invalid `foreach` aggregate `bar()`\n---\n*/\n\nmodule main;\n\npublic void bar()\n{\n}\n\nvoid main()\n{\n    foreach (Object o; bar())\n    {\n        debug Object foo = null; //error\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail25.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail25.d(14): Error: need `this` for `yuiop` of type `int`\n---\n*/\n\nclass Qwert\n{\n    int yuiop;\n\n    static int asdfg()\n    {\n        return Qwert.yuiop + 105;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail250.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail250.d(10): Error: constructor `fail250.A.this` default constructor for structs only allowed with `@disable`, no body, and no parameters\n---\n*/\n\nstruct A\n{\n    this() {}\n}\n\nvoid main()\n{\n    auto a = A();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail251.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail251.d(12): Error: undefined identifier `xs`\nfail_compilation/fail251.d(16):        called from here: `foo()`\nfail_compilation/fail251.d(16):        while evaluating: `static assert(foo())`\n---\n*/\n\nbool foo()\n{\n    foreach (x; xs) {}\n    return true;\n}\n\nstatic assert(foo());\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail252.d",
    "content": "class Timer {\n    abstract class Task {\n        public abstract void run();\n    }\n    private Task IDLE = new class() Task {\n        int d;\n        public void run(){\n        }\n    };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail253.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail253.d(13): Error: variable `fail253.main.x` `inout` variables can only be declared inside `inout` functions\nfail_compilation/fail253.d(16): Error: cannot modify `inout` expression `x`\n---\n*/\n\nvoid main()\n{\n    foreach (i; 0 .. 2)\n    {\n        foreach (inout char x; \"hola\")\n        {\n            //printf(\"%c\", x);\n            x = '?';\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail254.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail254.d(12): Error: integer overflow\nfail_compilation/fail254.d(13): Error: integer overflow\nfail_compilation/fail254.d(14): Error: integer overflow\nfail_compilation/fail254.d(15): Error: integer overflow\nfail_compilation/fail254.d(16): Error: integer overflow\n---\n*/\n\nulong v1 = 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF;\nulong v2 = 0x1_0000_0000_0000_0000;\nulong v3 = 0x1_FFFF_FFFF_FFFF_FFFF;\nulong v4 = 0x7_FFFF_FFFF_FFFF_FFFF;\nulong v5 = 0x1_0000_FFFF_FFFF_FFFF;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail256.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail256.d(8): Error: incompatible types for `(\"foo\"d) ~ (\"bar\"c)`: `dstring` and `string`\n---\n*/\n\nauto s = \"foo\"d ~ \"bar\"c;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail257.d",
    "content": "pragma(msg, \"foo\"d == \"bar\"c ? \"A\" : \"B\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail258.d",
    "content": "q\"\nX\n\nX\"\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail259.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail259.d(11): Error: function `fail259.C.foo` does not override any function\n---\n*/\n\nclass C\n{\n    final\n        override void foo(){}\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail261.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail261.d(18): Error: invalid `foreach` aggregate `range`, define `opApply()`, range primitives, or use `.tupleof`\n---\n*/\n\n//import std.stdio;\n\nstruct MyRange\n{\n}\n\nvoid main()\n{\n    MyRange range;\n\n    foreach (r; range)\n    {\n        //writefln(\"%s\", r.toString());\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail262.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail262.d(23): Error: function `fail262.B.f` does not override any function\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=1645\n// can override base class' const method with non-const method\nimport core.stdc.stdio;\n\nclass A\n{\n    int x;\n    shared const void f()\n    {\n        printf(\"A\\n\");\n    }\n}\n\nclass B : A\n{\n    override const void f()\n    {\n        //x = 2;\n        printf(\"B\\n\");\n    }\n}\n\nvoid main()\n{\n    A y = new B;\n    y.f;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail263.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail263.d(19): Error: function `fail263.f(byte* p)` is not callable using argument types `(const(byte)*)`\nfail_compilation/fail263.d(19):        cannot pass argument `cast(const(byte)*)A` of type `const(byte)*` to parameter `byte* p`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=2766\n// DMD hangs with 0%cpu\nconst byte[] A = [ cast(byte)0 ];\n\nvoid f(byte* p)\n{\n}\n\nvoid func()\n{\n    f(A.ptr);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail264.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail264.d(10): Error: undefined identifier `undef`\n---\n*/\n\nvoid main()\n{\n    foreach (element; undef)\n    {\n        fn(element);\n    }\n}\n\nvoid fn(int i) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail265.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail265.d-mixin-10(10): Error: found `End of File` instead of statement\n---\n*/\n\nvoid main()\n{\n    mixin(`for(;;)`);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail2656.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail2656.d(21): Error: octal literals `0123` are no longer supported, use `std.conv.octal!123` instead\nfail_compilation/fail2656.d(22): Error: octal literals `01000000000000000000000` are no longer supported, use `std.conv.octal!1000000000000000000000` instead\nfail_compilation/fail2656.d(23): Error: octal literals `0100000L` are no longer supported, use `std.conv.octal!100000L` instead\nfail_compilation/fail2656.d(24): Error: octal literals `01777777777777777777777u` are no longer supported, use `std.conv.octal!1777777777777777777777u` instead\nfail_compilation/fail2656.d(25): Error: octal literals `017777777777uL` are no longer supported, use `std.conv.octal!17777777777uL` instead\nfail_compilation/fail2656.d(26): Error: octal literals `0177777` are no longer supported, use `std.conv.octal!177777` instead\nfail_compilation/fail2656.d(27): Error: octal literals `020000000000L` are no longer supported, use `std.conv.octal!20000000000L` instead\nfail_compilation/fail2656.d(28): Error: octal literals `0200000u` are no longer supported, use `std.conv.octal!200000u` instead\nfail_compilation/fail2656.d(29): Error: octal literals `037777777777uL` are no longer supported, use `std.conv.octal!37777777777uL` instead\nfail_compilation/fail2656.d(30): Error: octal literals `040000000000` are no longer supported, use `std.conv.octal!40000000000` instead\nfail_compilation/fail2656.d(31): Error: octal literals `0777777777777777777777L` are no longer supported, use `std.conv.octal!777777777777777777777L` instead\nfail_compilation/fail2656.d(32): Error: octal literals `077777u` are no longer supported, use `std.conv.octal!77777u` instead\nfail_compilation/fail2656.d(33): Error: octal literals `077777uL` are no longer supported, use `std.conv.octal!77777uL` instead\nfail_compilation/fail2656.d(34): Error: octal literals `077777uL` are no longer supported, use `std.conv.octal!77777uL` instead\n---\n*/\n\nauto a = 0123;\nauto b = 01000000000000000000000;\nauto c = 0100000L;\nauto d = 01777777777777777777777u;\nauto e = 017777777777uL;\nauto f = 0177777;\nauto g = 020000000000L;\nauto h = 0200000u;\nauto i = 037777777777uL;\nauto j = 040000000000;\nauto k = 0777777777777777777777L;\nauto l = 077777u;\nauto m = 077777uL;\nauto n = 0_7_7_7_7_7uL;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail267.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail267.d(15): Error: template `Bar()` does not have property `foo`\n---\n*/\n\nclass C\n{\n    template Bar()\n    {\n    }\n}\n\ntypeof(C.Bar.foo) quux;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail27.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail27.d(15): Error: cannot implicitly convert expression `-32769` of type `int` to `short`\nfail_compilation/fail27.d(16): Error: cannot implicitly convert expression `-129` of type `int` to `byte`\nfail_compilation/fail27.d(17): Error: cannot implicitly convert expression `-1` of type `int` to `char`\nfail_compilation/fail27.d(18): Error: cannot implicitly convert expression `65536` of type `int` to `wchar`\nfail_compilation/fail27.d(19): Error: cannot implicitly convert expression `-1` of type `int` to `wchar`\nfail_compilation/fail27.d(21): Error: cannot implicitly convert expression `-1` of type `int` to `dchar`\n---\n*/\n\nvoid main()\n{\n    short a = -32769; // short.min-1\n    byte  b = -129; // byte.min-1\n    char  c = -1; // char.min-1\n    wchar D = 65536; // wchar.max+1\n    wchar d = -1; // wchar.min-1\n    dchar E = 1114111; // dchar.max+1\n    dchar e = -1; // dchar.min-1\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail270.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail270.d(12): Error: string slice `[1 .. 0]` is out of bounds\nfail_compilation/fail270.d(12): Error: mixin `fail270.Tuple!int.Tuple.Tuple!()` error instantiating\nfail_compilation/fail270.d(14): Error: mixin `fail270.Tuple!int` error instantiating\n---\n*/\n\nstruct Tuple(TList...)\n{\n    mixin .Tuple!((TList[1 .. $])) tail;\n}\nmixin Tuple!(int);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail272.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail272.d(9): Error: circular reference to variable `fail272.Ins!(Ins).Ins`\nfail_compilation/fail272.d(10): Error: template instance `fail272.Ins!(Ins)` error instantiating\n---\n*/\n\ntemplate Ins(alias x) { const Ins = Ins!(Ins); }\nalias Ins!(Ins) x;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail273.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail273.d(10): Error: alias `fail273.b` recursive alias declaration\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=1054\n// regression: circular aliases cause compiler stack overflow\nalias a b;\nalias b a;\nb x;  // ICE #1\na y;  // ICE #2\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail274.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail274.d(10): Error: expression expected not `;`\n---\n*/\n\nvoid main()\n{\n    version(GNU) asm { \"\" : [; }\n    else asm { inc [; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail2740.d",
    "content": "interface IFoo\n{\n\tint foo();\n}\n\nmixin template MFoo(int N)\n{\n\tint foo() { return N; }\n}\n\nclass Foo : IFoo\n{\n\tmixin MFoo!(1) t1;\n\tmixin MFoo!(2) t2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail275.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail275.d(10): Error: circular reference to variable `fail275.C.x`\n---\n*/\n// REQUIRED_ARGS: -d\nstruct C\n{\n    const x = C.x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail276.d",
    "content": "\nclass C\n{\n    this()\n    {\n        auto i = new class()\n        {\n            auto k = new class()\n            {\n                void func()\n                {\n                    this.outer.outer;\n                }\n            };\n        };\n    }\n    int i;\n}\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail278.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail278.d(11): Error: template instance `NONEXISTENT!()` template `NONEXISTENT` is not defined\nfail_compilation/fail278.d(12): Error: template instance `fail278.F!()` error instantiating\nfail_compilation/fail278.d(13):        instantiated from here: `Bar!(Foo)`\n---\n*/\n\ntemplate Id(xs...) { const Id = xs[0]; }\ntemplate Foo() { mixin Id!(NONEXISTENT!()); }\ntemplate Bar(alias F) { const int Bar = F!(); }\nalias Bar!(Foo) x;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail2789.d",
    "content": "/*\nDISABLED: win32 win64 osx linux freebsd dragonflybsd\nhttps://issues.dlang.org/show_bug.cgi?id=18385\nDisabled for 2.079, s.t. a deprecation cycle can be started with 2.080\nTEST_OUTPUT:\n---\nfail_compilation/fail2789.d(15): Error: function `fail2789.A2789.m()` conflicts with previous declaration at fail_compilation/fail2789.d(10)\nfail_compilation/fail2789.d(25): Error: function `fail2789.A2789.m()` conflicts with previous declaration at fail_compilation/fail2789.d(10)\n---\n*/\nclass A2789\n{\n    int m()\n    {\n        return 1;\n    }\n\n    float m()       // conflict\n    {\n        return 2.0;\n    }\n\n    float m() const // doen't conflict\n    {\n        return 3.0;\n    }\n\n    static void m() // conflict\n    {\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail2789.d(46): Error: function `fail2789.f3()` conflicts with previous declaration at fail_compilation/fail2789.d(45)\nfail_compilation/fail2789.d(49): Error: function `fail2789.f4()` conflicts with previous declaration at fail_compilation/fail2789.d(48)\nfail_compilation/fail2789.d(52): Error: function `fail2789.f5()` conflicts with previous declaration at fail_compilation/fail2789.d(51)\nfail_compilation/fail2789.d(55): Error: function `fail2789.f6()` conflicts with previous declaration at fail_compilation/fail2789.d(54)\n---\n*/\nvoid f1();\nvoid f1() {}    // ok\n\nvoid f2() {}\nvoid f2();      // ok\n\nvoid f3();\nvoid f3();      // ok\n\nvoid f4() {}\nvoid f4() {}    // conflict\n\nvoid f5() @safe {}\nvoid f5() @system {}    // conflict\n\nauto f6() { return 10; }    // int()\nauto f6() { return \"\"; }    // string(), conflict\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail2789.d(67): Error: function `fail2789.f_ExternC1()` cannot be overloaded with another `extern(C)` function at fail_compilation/fail2789.d(66)\nfail_compilation/fail2789.d(70): Error: function `fail2789.f_ExternC2(int)` cannot be overloaded with another `extern(C)` function at fail_compilation/fail2789.d(69)\nfail_compilation/fail2789.d(73): Error: function `fail2789.f_ExternC3()` cannot be overloaded with another `extern(C)` function at fail_compilation/fail2789.d(72)\nfail_compilation/fail2789.d(76): Error: function `fail2789.f_MixExtern1()` conflicts with previous declaration at fail_compilation/fail2789.d(75)\n---\n*/\nextern(C) void f_ExternC1() {}\nextern(C) void f_ExternC1() {}      // conflict\n\nextern(C) void f_ExternC2() {}\nextern(C) void f_ExternC2(int) {}   // conflict\n\nextern(C) void f_ExternC3(int) {}\nextern(C) void f_ExternC3() {}      // conflict\n\nextern (D) void f_MixExtern1() {}\nextern (C) void f_MixExtern1() {}   // conflict\n\nextern (D) void f_MixExtern2(int) {}\nextern (C) void f_MixExtern2() {}   // no error\n\nextern (C) void f_ExternC4(int sig);\nextern (C) void f_ExternC4(int sig) @nogc;      // no error\n\nextern (C) void f_ExternC5(int sig) {}\nextern (C) void f_ExternC5(int sig) @nogc;      // no error\n\nextern (C) void f_ExternC6(int sig);\nextern (C) void f_ExternC6(int sig) @nogc {}    // no error\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail2789.d(103): Error: function `fail2789.mul14147(const(int[]) left, const(int[]) right)` conflicts with previous declaration at fail_compilation/fail2789.d(99)\n---\n*/\nstruct S14147(alias func)\n{\n}\npure auto mul14147(const int[] left, const int[] right)\n{\n    S14147!(a => a) s;\n}\npure auto mul14147(const int[] left, const int[] right)\n{\n    S14147!(a => a) s;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail279.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=2920\n// recursive templates blow compiler stack\n// template_16\n\ntemplate Template(int i)\n{\n    mixin Template!(i + 1);\n}\nmixin Template!(0);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail280.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=2920\n// recursive templates blow compiler stack\n// template_17_A.\n\ntemplate t(int i)\n{\n    const int x = t!(i + 1).x;\n}\n\nvoid main()\n{\n    int i = t!(0).x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail281.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=2920\n// recursive templates blow compiler stack\n// template_29_B.\n\ntemplate foo(uint i)\n{\n    static if (i > 0)\n    {\n        const uint bar = foo!(i - 1).bar;\n    }\n    else\n    {\n        const uint bar = 1;\n    }\n}\nint main()\n{\n    return foo!(uint.max).bar;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail282.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail282.d(13): Error: template instance `fail282.Template!500` recursive expansion\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=2920\n// recursive templates blow compiler stack\n// template_class_09.\ntemplate Template(int i)\n{\n    class Class : Template!(i + 1).Class\n    {\n    }\n}\n\nalias Template!(0).Class Class0;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail284.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail284.d(19): Error: `pure` function `fail284.foo` cannot call impure function pointer `a`\n---\n*/\n\nstatic int nasty;\n\nint impure_evil_function(int x)\n{\n    nasty++;\n    return nasty;\n}\n\npure int foo(int x)\n{\n    int function(int) a = &impure_evil_function;\n    return a(x);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail285.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail285.d(19): Error: with symbol `fail285.S.x` is shadowing local symbol `fail285.main.x`\n---\n*/\n\nstruct S\n{\n    int x;\n}\n\nvoid main()\n{\n    int x;\n    S s;\n    with (s)\n    {\n        x++;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail287.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail287.d(14): Error: had 299 cases which is more than 256 cases in case range\n---\n*/\n\n\nvoid main()\n{\n    int i = 2;\n    switch (i)\n    {\n        case 1: .. case 300:\n            i = 5;\n            break;\n    }\n    if (i != 5)\n        assert(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail288.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail288.d(14): Error: case ranges not allowed in `final switch`\n---\n*/\n\nvoid main()\n{\n    enum E { a, b }\n    E i = E.a;\n    final switch (i)\n    {\n        case E.a: .. case E.b:\n            break;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail289.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail289.d(12): Error: cannot cast from function pointer to delegate\n---\n*/\n\nalias void delegate() Dg;\nvoid fun() {}\nvoid gun()\n{\n    Dg d = cast(void delegate())&fun;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail290.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail290.d(15): Error: no `this` to create delegate for `foo`\n---\n*/\n\nstruct Foo\n{\n    void foo(int x) {}\n}\n\nvoid main()\n{\n    void delegate (int) a = &Foo.foo;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail291.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail291.d(9): Error: variable `fail291.X` cannot be declared to be a function\n---\n*/\n\nauto a() { return 0; }\ntypeof(a) X;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail296.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail296.d(10): Error: can only `*` a pointer, not a `int`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=3117\n// dmd crash by *1\nvoid main(){ *1; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail2962.d",
    "content": "// EXTRA_SOURCES: imports/fail2962a.d\n\n// comment 6\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail2962.d(14): Error: variable `y` cannot be read at compile time\nfail_compilation/fail2962.d(14):        while looking for match for `baz6!(int, y)`\nfail_compilation/fail2962.d(22): Error: template instance `fail2962.bar6!int` error instantiating\n---\n*/\nT bar6(T)(T y)\n{\n    return baz6!(T, y)();\n}\nT baz6(T, T z)()\n{\n    return z * z;\n}\nvoid test6()\n{\n    assert(bar6(4) != 0);\n}\n\n// comment 4\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail2962.d(36): Error: variable `x` cannot be read at compile time\nfail_compilation/fail2962.d(36):        while looking for match for `baz4!(int, x)`\nfail_compilation/imports/fail2962a.d(6): Error: template instance `fail2962.bar4!int` error instantiating\n---\n*/\nT bar4(T)(T x)\n{\n    return baz4!(T, x)();\n}\nT baz4(T, T x)()\n{\n    return x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail297.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail297.d(30): Error: incompatible types for `(Bar()) + (baz())`: `Bar` and `const(Bar)`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=1969\n// ICE(cod1.c) using undefined operator with one const operand\n// ICE or wrong-code. D2 only. Internal error: backend\\cod1.c 1673\n/* Root cause: BinExp::typeCombine() is checking for an _exact_ match, but\ntypeMerge() will return success.\n\nPATCH: cast.c BinExp::typeCombine().\nCompare the immutable versions of the types, instead of the types themselves.\n\n    if (op == TOKmin || op == TOKadd)\n    {\n        if (t1->ito == t2->ito && (t1->ty == Tstruct || t1->ty == Tclass))\n            goto Lerror;\n    }\n*/\n\nstruct Bar {}\n\nconst(Bar) baz() { return Bar(); }\n\nvoid foo()\n{\n    Bar result = Bar() + baz();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail298.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail298.d(12): Error: cannot implicitly convert expression `num1 / cast(ulong)num2` of type `ulong` to `int`\n---\n*/\n\nvoid main()\n{\n    ulong num1 = 100;\n    int num2 = 10;\n    int result = num1 / num2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail299.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail299.d(14): Error: more initializers than fields (0) of `Foo`\n---\n*/\n\nstruct Foo {}\n\nvoid foo (Foo b, void delegate ()) {}\n\nvoid main ()\n{\n    foo(Foo(1), (){});\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail3.d(41): Error: incompatible types for `(a) + (b)`: both operands are of type `vec2`\n---\n*/\n\n// DMD 0.79 linux: Internal error: ../ztc/cgcod.c 1459\n\ntemplate vector(T)\n{\n    struct vec2\n    {\n        T x, y;\n    }\n\n    // not struct member\n    vec2 opAdd(vec2 a, vec2 b)\n    {\n        vec2 r;\n        r.x = a.x + b.x;\n        r.y = a.y + b.y;\n        return r;\n    }\n\n    vec2 make2(T x, T y)\n    {\n        vec2 a;\n        a.x = x;\n        a.y = y;\n        return a;\n    }\n}\n\nalias vector!(float).vec2 vec2f;\n\nint main()\n{\n    vec2f a, b;\n    b.x = 3;\n    a = a + b;\n    //printf(\"%f\\n\", a.x);\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail301.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail301.d(11): Error: need `this` for `guard` of type `int`\nfail_compilation/fail301.d(22): Error: template instance `fail301.bug3305!0` error instantiating\n---\n*/\n\nstruct bug3305(alias X = 0)\n{\n    auto guard = bug3305b!(0).guard;\n}\n\nstruct bug3305b(alias X = 0)\n{\n    bug3305!(X) goo;\n    auto guard = 0;\n}\n\nvoid test()\n{\n    bug3305!(0) a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail302.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail302.d(23): Error: cannot implicitly convert expression `1` of type `int` to `Bar`\nfail_compilation/fail302.d(23):        `bar = 1` is the first assignment of `bar` therefore it represents its initialization\nfail_compilation/fail302.d(23):        `opAssign` methods are not used for initialization, but for subsequent assignments\n---\n*/\n\nstruct Bar\n{\n    uint num;\n\n    Bar opAssign(uint otherNum)\n    {\n        num = otherNum;\n        return this;\n    }\n}\n\nvoid main()\n{\n    Bar bar = 1;\t// disallow because construction is not assignment\n    auto x = bar.num;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail303.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail303.d(19): Error: `double /= cdouble` is undefined. Did you mean `double /= cdouble.re`?\nfail_compilation/fail303.d(20): Error: `ireal *= ireal` is an undefined operation\nfail_compilation/fail303.d(21): Error: `ireal *= creal` is undefined. Did you mean `ireal *= creal.im`?\nfail_compilation/fail303.d(22): Error: `ireal %= creal` is undefined. Did you mean `ireal %= creal.im`?\nfail_compilation/fail303.d(23): Error: `ireal += real` is undefined (result is complex)\nfail_compilation/fail303.d(24): Error: `ireal -= creal` is undefined (result is complex)\nfail_compilation/fail303.d(25): Error: `double -= idouble` is undefined (result is complex)\n---\n*/\n\n\nvoid main()\n{\n    ireal x = 3.0i;\n    double y = 3;\n    y /= 2.0 + 6i;\n    x *= 7.0i;\n    x *= 3.0i + 2;\n    x %= (2 + 6.0i);\n    x += 2.0;\n    x -= 1 + 4i;\n    y -= 3.0i;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail304.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail304.d(15): Error: cannot cast expression `foo()` of type `Small` to `Large` because of different sizes\n---\n*/\n\nstruct Small { uint x; }\nstruct Large { uint x, y, z; }\nSmall foo() { return Small(); }\nvoid main()\n{\n    Large l;\n    Small s;\n    l = cast(Large)foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail305.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail305.d(10): Error: cannot return non-void from `void` function\n---\n*/\n\nvoid main()\n{\n    return \"a\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail306.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail306.d(11): Error: cannot perform array operations on `void[]` arrays\n---\n*/\n\nvoid bar()\n{\n    void [] x;\n    x[] = -x[];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail307.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail307.d(11): Error: cannot implicitly convert expression `cast(int)(cast(double)cast(int)b + 6.1)` of type `int` to `short`\n---\n*/\n\nvoid main()\n{\n    ubyte b = 6;\n    short c5 = cast(int)(b + 6.1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail308.d",
    "content": "// REQUIRED_ARGS: -unittest\n\nvoid main()\n{\n    MinHeap!(int) foo = new MinHeap!(int)();\n}\n\nclass MinHeap(NodeType)\n{\n    unittest\n    {\n        struct TestType {}\n        MinHeap!(TestType) foo = new MinHeap!(TestType)();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail309.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail309.d(10): Error: circular reference to variable `fail309.S.x`\n---\n*/\n// REQUIRED_ARGS: -d\nstruct S\n{\n    const x = S.x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail310.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail310.d(10): Error: undefined identifier `Foo`, did you mean function `foo`?\nfail_compilation/fail310.d(14): Error: template instance `fail310.foo!(1, 2)` error instantiating\nfail_compilation/fail310.d(14):        while evaluating: `static assert(foo!(1, 2)())`\n---\n*/\n\nFoo foo(A...)()\n{\n}\n\nstatic assert(foo!(1, 2)());\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail311.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail311.d(16): Error: undefined identifier `undefined`\nfail_compilation/fail311.d(25): Error: template instance `fail311.foo!()` error instantiating\n---\n*/\n\ntemplate Tuple(T...)\n{\n    alias T Tuple;\n}\n\nvoid foo()()\n{\n    undefined x;\n    foreach (i; Tuple!(2))\n    {\n        static assert(true);\n    }\n}\n\nvoid main()\n{\n    foo!()();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail312.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail312.d(13): Error: incompatible types for `(a[]) == (b)`: `int[]` and `short`\nfail_compilation/fail312.d(14): Error: incompatible types for `(a[]) <= (b)`: `int[]` and `short`\n---\n*/\n\nvoid main()\n{\n    int[1] a = 1;\n    short b = 1;\n    assert(a[] == b);\n    assert(a[] <= b);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail313.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail313.d(17): Error: module `imports.b313` is not accessible here, perhaps add `static import imports.b313;`\nfail_compilation/fail313.d(24): Deprecation: `imports.a313.core` is not visible from module `test313`\nfail_compilation/fail313.d(24): Error: package `core.stdc` is not accessible here\nfail_compilation/fail313.d(24): Error: module `core.stdc.stdio` is not accessible here, perhaps add `static import core.stdc.stdio;`\nfail_compilation/fail313.d(29): Error: package `imports.pkg313` is not accessible here, perhaps add `static import imports.pkg313;`\n---\n*/\nmodule test313;\n\nimport imports.a313;\n\nvoid test1()\n{\n    imports.b313.bug();\n    import imports.b313;\n    imports.b313.bug();\n}\n\nvoid test2()\n{\n    core.stdc.stdio.printf(\"\");\n}\n\nvoid test3()\n{\n    imports.pkg313.bug();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail314.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail314.d(11): Error: declaration `T` is already defined\n---\n*/\n\nstruct foo\n{\n    static if (is(int T == int)) {}\n    static if (is(int T == int)) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3144.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail3144.d(12): Error: `break` is not inside a loop or `switch`\nfail_compilation/fail3144.d(15): Error: `break` is not inside a loop or `switch`\n---\n*/\n\nvoid main()\n{\n    switch (1)\n        default: {} break;\n\n    final switch (1)\n        case 1: {} break;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail315.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail315.d-mixin-16(16): Error: found `;` when expecting `,`\nfail_compilation/fail315.d-mixin-16(16): Error: expression expected, not `}`\nfail_compilation/fail315.d-mixin-16(16): Error: found `End of File` when expecting `,`\nfail_compilation/fail315.d-mixin-16(16): Error: found `End of File` when expecting `]`\nfail_compilation/fail315.d-mixin-16(16): Error: found `End of File` when expecting `;` following `return` statement\nfail_compilation/fail315.d-mixin-16(16): Error: found `End of File` when expecting `}` following compound statement\nfail_compilation/fail315.d(21): Error: template instance `fail315.foo!()` error instantiating\n---\n*/\n\nvoid foo(S...)(S u)\n{\n    alias typeof(mixin(\"{ return a[1;}()\")) z;\n}\n\nvoid main()\n{\n    foo!()(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3150.d",
    "content": "// REQUIRED_ARGS: -de\n\nvoid main() {\n    ulong u = cast(ulong)[1,2];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail316.d",
    "content": "template BadImpl(T, alias thename)\n{\n  void a_bad_idea(T t)\n  {\n    thename.a_bad_idea(t);\n  }\n}\n\nclass foo\n{\n  mixin BadImpl!(uint,Mix1) Mix1;\n}\n\nint main()\n{\n  return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail317.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail317.d(10): Error: function `fail317.I.f` has no function body with return type inference\n---\n*/\n\ninterface I\n{\n    auto f()\n    in {}\n    out {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail318.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail318.d(8): Error: function `D main` must return `int` or `void`\n---\n*/\n\nauto main() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail319.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail319.d(13): Error: template instance `fail319.f!(int, int)` does not match template declaration `f(T...)() if (T.length > 20)`\n---\n*/\n\nvoid f(T...)() if (T.length > 20)\n{}\n\nvoid main()\n{\n    f!(int, int)();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail320.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail320.d(10): Error: no overload matches for `foo`\n---\n*/\n\nimport imports.fail320a;\nimport imports.fail320b;\nvoid main() { foo(); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail322.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail322.d(13): Error: function `fail322.digestToString2(ref char[16] digest)` is not callable using argument types `(string)`\nfail_compilation/fail322.d(13):        cannot pass rvalue argument `\"1234567890123456\"` of type `string` to parameter `ref char[16] digest`\nfail_compilation/fail322.d(15): Error: function `fail322.digestToString2(ref char[16] digest)` is not callable using argument types `(const(char[16]))`\nfail_compilation/fail322.d(15):        cannot pass argument `s` of type `const(char[16])` to parameter `ref char[16] digest`\n---\n*/\n\nvoid main()\n{\n    digestToString2(\"1234567890123456\");\n    const char[16] s;\n    digestToString2(s);\n}\n\nvoid digestToString2(ref char[16] digest)\n{\n    assert(digest[0] == 0xc3);\n    assert(digest[15] == 0x3b);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail324.d",
    "content": "/*\ntest_output:\n---\nfail_compilation/fail324.d(16): Error: template instance doStuff!((i){ return i; }) cannot use local `__lambda1` as parameter to non-global template `doStuff(alias fun)()`\n---\n*/\n\nstruct Foo\n{\n    void doStuff(alias fun)() {}\n}\n\nvoid main()\n{\n    Foo foo;\n    foo.doStuff!( (i) { return i; })();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail325.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail325.d(12): Error: template `fun(T = int)(int w, int z)` has no type\n---\n*/\n\nvoid fun(T = int)(int w, int z) {}\n\nvoid main()\n{\n    auto x = cast(void function(int, int))fun;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail327.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail327.d(10): Error: `asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not\n---\n*/\n\n@safe void foo()\n{\n    version(GNU) asm { \"\"; }\n    else asm { xor EAX,EAX; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail328.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail328.d(13): Error: `@safe` function `fail328.foo` cannot call `@system` function `fail328.bar`\nfail_compilation/fail328.d(9):        `fail328.bar` is declared here\n---\n*/\n\nvoid bar();\n\n@safe void foo()\n{\n    bar();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail329.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail329.d(28): Error: variable `fail329.A.foo.__ensure.result` cannot modify result `result` in contract\n---\n*/\n\n//import core.stdc.stdio;\n\n/*******************************************/\n\nclass A\n{\n    int x = 7;\n\n    int foo(int i)\n    in\n    {\n        //printf(\"A.foo.in %d\\n\", i);\n        assert(i == 2);\n        assert(x == 7);\n        //printf(\"A.foo.in pass\\n\");\n    }\n    out (result)\n    {\n        assert(result & 1);\n        assert(x == 7);\n        result++;\n    }\n    body\n    {\n        return i;\n    }\n}\n\nclass B : A\n{\n    override int foo(int i)\n    in\n    {\n        float f;\n        //printf(\"B.foo.in %d\\n\", i);\n        assert(i == 4);\n        assert(x == 7);\n        f = f + i;\n    }\n    out (result)\n    {\n        assert(result < 8);\n        assert(x == 7);\n    }\n    body\n    {\n        return i - 1;\n    }\n}\n\nvoid test1()\n{\n    auto b = new B();\n    b.foo(2);\n    b.foo(4);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3290.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=3290\n\nvoid main()\n{\n    const(int)[] array;\n    foreach (ref int i; array) {\n        //i = 42;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail330.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail330.d(9): Error: variable `fail330.fun.result` cannot modify result `result` in contract\n---\n*/\n\nint fun()\nout(result) { result = 2; }\nbody { return 1; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail331.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail331.d(10): Error: cannot use `typeof(return)` inside function `foo` with inferred return type\n---\n*/\n\nauto foo()\n{\n    typeof(return) result;\n    return result;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail332.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail332.d(14): Error: function `fail332.foo(int _param_0, ...)` is not callable using argument types `()`\n---\n*/\n\nimport core.vararg;\n\nvoid foo(int, ...) {}\n\nvoid bar()\n{\n    foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail333.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail333.d(8): Error: forward reference to `test`\n---\n*/\n\nvoid test(typeof(test) p) { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail334.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail334.d(10): Error: properties can only have zero, one, or two parameter\n---\n*/\n\nstruct S\n{\n    @property int foo(int a, int b, int c) { return 1; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail335.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail335.d(9): Error: cannot overload both property and non-property functions\n---\n*/\n\nvoid foo();\n@property void foo(int);\n\nvoid main()\n{\n    foo(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail336.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail336.d(16): Error: struct `S` has constructors, cannot use `{ initializers }`, use `S( initializers )` instead\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=3476\n// C-style initializer for structs must be disallowed for structs with a constructor\nstruct S\n{\n    int a;\n    this(int) {}\n}\n\nS s = { 1 };\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail337.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail337.d(13): Error: static assert:  `0` is false\nfail_compilation/fail337.d(26):        instantiated from here: `bar!()`\nfail_compilation/fail337.d(33):        100 recursive instantiations from here: `foo!196`\nfail_compilation/fail337.d(41):        253 recursive instantiations from here: `baz!300`\n---\n*/\n\ntemplate bar()\n{\n    static assert(0);\n}\n\ntemplate foo(int N)\n{\n    static if (N > 0)\n    {\n        static if (N & 1)\n            alias foo!(N - 3) foo;\n        else\n            alias foo!(N - 1) foo;\n    }\n    else\n        alias bar!() foo;\n}\n\ntemplate baz(int M)\n{\n    static if (M < 50)\n    {\n        alias foo!(M * 4) baz;\n    }\n    else\n        alias baz!(M - 1) baz;\n}\n\nvoid main()\n{\n    int x = baz!(300);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail34.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail34.d(31): Error: duplicate `case \"123\"` in `switch` statement\n---\n*/\n\n// $HeadURL$\n// $Date$\n// $Author$\n\n// @author@\tThomas Kuehne <thomas-dloop@kuehne.thisisspam.cn>\n// @date@\t2004-11-17\n// @uri@\tnews:u1gr62-kjv.ln1@kuehne.cn\n// @url@\tnntp://digitalmars.com/digitalmars.D.bugs/2288\n\n// duplicate case \"123\" in switch statement\n\nmodule switch_12;\n\nint main()\n{\n    string array = \"123\";\n    switch(array)\n    {\n        case \"123\":\n        {\n            assert(0);\n            break;\n        }\n        case \"123\":\n        {\n            assert(1);\n            break;\n        }\n        default:\n        {\n            return -1; // dummy\n        }\n    }\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail340.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail340.d(18): Error: variable `fail340.w` of type struct `const(CopyTest)` uses `this(this)`, which is not allowed in static initialization\nfail_compilation/fail340.d(19):        while evaluating: `static assert(w.x == 55.0000)`\n---\n*/\n\nstruct CopyTest\n{\n    double x;\n    this(double a) { x = a * 10.0;}\n    this(this) { x += 2.0; }\n}\n\nconst CopyTest z = CopyTest(5.3);\n\nconst CopyTest w = z;\nstatic assert(w.x == 55.0);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail341.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail341.d(26): Error: struct `fail341.S` is not copyable because it is annotated with `@disable`\nfail_compilation/fail341.d(27): Error: function `fail341.foo` cannot be used because it is annotated with `@disable`\n---\n*/\n\nstruct T\n{\n    @disable this(this)\n    {\n    }\n}\n\nstruct S\n{\n    T t;\n}\n\n@disable void foo() { }\n\nvoid main()\n{\n    S s;\n    auto t = s;\n    foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail343.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail343.d(22): Error: function `fail343.TimedApp.run` cannot override `final` function `I.fail343.Timer.run`\nfail_compilation/fail343.d(22): Error: function `fail343.TimedApp.run` cannot override `final` function `Application.fail343.Application.run`\n---\n*/\n\ninterface Timer\n{\n    final void run() { }\n}\n\ninterface I : Timer { }\ninterface Application\n{\n    final void run() { }\n}\nclass TimedApp : I, Application\n{\n    // cannot define run()\n    void run() { }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail344.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=3737\n\nint crayon;\n\nstruct SIB(alias junk)\n{\n    template Alike(V) {\n        enum bool Alike = Q == V.garbage;\n    }\n    void opDispatch(string s)() {\n        static assert(Alike!(SIB!(crayon)));\n    }\n}\n\nvoid main() {\n      SIB!(SIB!(crayon).E)(3.0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail346.d",
    "content": "\nstruct S {\n    int x;\n\n    template T(int val) {\n        const P T = { val }; // the P here is an error it should be S\n    }\n}\n\ntemplate V(R,int val){\n    const R V=R.T!(val);\n}\n\nconst S x = V!(S,0);\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail347.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail347.d(21): Error: undefined identifier `bbr`, did you mean variable `bar`?\nfail_compilation/fail347.d(22): Error: no property `ofo` for type `S`, did you mean `fail347.S.foo`?\nfail_compilation/fail347.d(23): Error: undefined identifier `strlenx`, did you mean function `strlen`?\n---\n*/\n\n//import core.stdc.string;\nimport imports.fail347a;\n\nstruct S\n{\n    int foo;\n}\n\nvoid main()\n{\n    S bar;\n    bbr.foo = 3;\n    bar.ofo = 4;\n    auto s = strlenx(\"hello\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail349.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail349.d(15): Error: function `fail349.bug6109throwing` is not `nothrow`\nfail_compilation/fail349.d(13): Error: `nothrow` function `fail349.bug6109noThrow` may throw\n---\n*/\n\nint bug6109throwing()\n{\n    throw new Exception(\"throws\");\n}\nint bug6109noThrow() nothrow\n{\n    auto g = [4][0 .. bug6109throwing()];\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail35.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail35.d(15): Error: variable `t` cannot be read at compile time\n---\n*/\n\n// http://www.digitalmars.com/d/archives/digitalmars/D/bugs/2372.html\n// allegedly crashes, but cannot reproduce\n\nvoid main()\n{\n    for (int t = 0; t < 33; t++)\n    {\n        size_t n = (bool[t]).sizeof;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail351.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail351.d(14): Error: `cast(uint)this.num[index]` is not an lvalue and cannot be modified\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=2780\n\nstruct Immutable {\n    immutable uint[2] num;\n\n    ref uint opIndex(size_t index) immutable {\n        return num[index];\n    }\n}\n\nvoid main() {\n    immutable Immutable foo;\n    //foo[0]++;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail352.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail352.d(18): Error: cannot infer argument types, expected 1 argument, not 2\n---\n*/\n\nstruct Range\n{\n    bool empty;\n    int front() { return 0; }\n    void popFront() { empty = true; }\n}\n\nvoid main()\n{\n    // no index for range foreach\n    foreach(i, v; Range()) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail354.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail354.d(11): Error: template instance `T!N` template `T` is not defined\nfail_compilation/fail354.d(13): Error: template instance `fail354.S!1` error instantiating\n---\n*/\n\nstruct S(int N)\n{\n    this(T!N) { }\n}\nalias S!1 M; \n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail355.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail355.d(8): Error: module `imports.fail355` import `nonexistent` not found\n---\n*/\n\nimport imports.fail355 : nonexistent;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail356a.d",
    "content": "import imports.fail356;\nint imports; // collides with package name\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail356b.d",
    "content": "import imports.fail356 : bar;\nint bar; // collides with selective import\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail356c.d",
    "content": "import foo = imports.fail356;\nint foo; // collides with renamed import\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3581a.d",
    "content": "\nclass A { void f() {} }\nclass B : A { static override void f() {}; }\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3581b.d",
    "content": "\nclass A { void f() {} }\nclass B : A { private override void f() {}; }\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail359.d",
    "content": "#line 5 _BOOM\nvoid main() { }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail36.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail36.d(13): Error: template `t(int L)` does not have property `a`\nfail_compilation/fail36.d(18): Error: mixin `fail36.func.t!10` error instantiating\n---\n*/\n\ntemplate t(int L)\n{\n    int a;\n    // void foo(int b = t!(L).a) {} // correct\n    void foo(int b = t.a) {} // wrong\n}\n\nvoid func()\n{\n    mixin t!(10);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3672.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail3672.d(27): Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!\"+=\"(*p, 1)` instead.\nfail_compilation/fail3672.d(31): Error: none of the `opOpAssign` overloads of `SF` are callable for `*sfp` of type `shared(SF)`\n---\n*/\n\nstruct SF  // should fail\n{\n    void opOpAssign(string op, T)(T rhs)\n    {\n    }\n}\n\nstruct SK  // ok\n{\n    void opOpAssign(string op, T)(T rhs) shared\n    {\n    }\n}\n\nvoid main()\n{\n    shared int x;\n    auto p = &x;\n    *p += 1;  // fail\n\n    shared SF sf;\n    auto sfp = &sf;\n    *sfp += 1;  // fail\n\n    shared SK sk;\n    auto skp = &sk;\n    sk += 1;  // ok\n    *skp += 1;  // ok\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3673a.d",
    "content": "class A {}\nclass B : A if(false) { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3673b.d",
    "content": "class A {}\nclass B : if(false) A { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3703.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=3703\n// static array assignment\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail3703.d(18): Error: mismatched array lengths, 2 and 1\nfail_compilation/fail3703.d(20): Error: mismatched array lengths, 2 and 1\nfail_compilation/fail3703.d(22): Error: mismatched array lengths, 3 and 2\nfail_compilation/fail3703.d(23): Error: mismatched array lengths, 2 and 3\nfail_compilation/fail3703.d(25): Error: mismatched array lengths, 3 and 2\nfail_compilation/fail3703.d(26): Error: mismatched array lengths, 2 and 3\n---\n*/\n\nvoid main()\n{\n    int[1] a = [1];\n    int[2] b = a;   // should make compile error\n\n    b = a;  // should make compile error\n\n    int[3] sa3 = [1,2][];\n    int[2] sa2 = sa3[][];\n\n    sa3 = [1,2][];\n    sa2 = sa3[][];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3731.d",
    "content": "\nvoid main()\n{\n    class C {}\n    class D : C {}\n    auto x = new immutable(D);\n    C y = x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3753.d",
    "content": "/*\n---\nError: cannot mix core.std.stdlib.alloca() and exception handling in _Dmain()\n---\n*/\n\nimport core.stdc.stdlib : alloca;\nimport core.stdc.stdio;\n\nstruct TheStruct\n{\n    ~this()\n    {\n        printf(\"dtor()\\n\");\n    }\n}\n\nvoid bar()\n{\n    printf(\"bar()\\n\");\n}\n\nvoid main()\n{\n    auto s = TheStruct();\n    bar();\n    auto a = alloca(16);\n    printf(\"test()\\n\");\n    version (DigitalMars)\n    {\n        version (Win32) static assert(0);\n        version (linux)\n        {\n            static assert(0);\n        }\n        version (FreeBSD)\n        {\n            static assert(0);\n        }\n        version (DragonFlyBSD)\n        {\n            static assert(0);\n        }\n        version (OSX)\n        {\n            static assert(0);\n        }\n    }\n    else\n        static assert(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail37_m32.d",
    "content": "// REQUIRED_ARGS: -m32\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail37_m32.d(9): Error: `cast(float)4u / cast(float)8u - cast(float)2147483647` is not of integral type, it is a `float`\n---\n*/\n\nulong[cast(uint)((cast(float)int.sizeof/ulong.sizeof)-int.max>>2)+int.max>>2] hexarray;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail37_m64.d",
    "content": "// REQUIRED_ARGS: -m64\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail37_m64.d(9): Error: `cast(float)4LU / cast(float)8LU - cast(float)2147483647` is not of integral type, it is a `float`\n---\n*/\n\nulong[cast(uint)((cast(float)int.sizeof/ulong.sizeof)-int.max>>2)+int.max>>2] hexarray;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail38.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail38.d(12): Error: `super` is only allowed in non-static class member functions\n---\n*/\n\nint x;\n\nvoid test()\n{\n    super.x = 2;\n}\n\nint main()\n{\n    test();\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3882.d",
    "content": "// REQUIRED_ARGS: -w\n// PERMUTE_ARGS: -debug\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3882\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail3882.d(23): Warning: calling fail3882.strictlyPure!int.strictlyPure without side effects discards return value of type int, prepend a cast(void) if intentional\nfail_compilation/fail3882.d(27): Warning: calling fp without side effects discards return value of type int, prepend a cast(void) if intentional\n---\n*/\n\n@safe pure nothrow T strictlyPure(T)(T x)\n{\n    return x*x;\n}\n\nvoid main()\n{\n    int x = 3;\n    strictlyPure(x);\n\n    // https://issues.dlang.org/show_bug.cgi?id=12649\n    auto fp = &strictlyPure!int;\n    fp(x);\n}\n\n/******************************************/\n// bugfix in TypeFunction::purityLevel\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail3882.d(46): Warning: calling fail3882.f1 without side effects discards return value of type int, prepend a cast(void) if intentional\nfail_compilation/fail3882.d(47): Warning: calling fail3882.f2 without side effects discards return value of type int, prepend a cast(void) if intentional\n---\n*/\n\nnothrow pure int f1(immutable(int)[] a) { return 0; }\nnothrow pure int f2(immutable(int)*  p) { return 0; }\n\nvoid test_bug()\n{\n    f1([]);\n    f2(null);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3895.d",
    "content": "import std.stdio;\n\nvoid main() {\n    double[] stuff = [1.,2.,3.,4.,5.];\n    float[] otherStuff;\n    otherStuff ~= stuff;\n    writeln(otherStuff);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail39.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail39.d(11): Error: function fail39.main.__funcliteral2 cannot access frame of function D main\n---\n*/\n\nvoid main()\n{\n    void foo() {}\n    void function() bar = function void() { foo(); };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail3990.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail3990.d(12): Error: using `*` on an array is no longer supported; use `*(arr1).ptr` instead\nfail_compilation/fail3990.d(14): Error: using `*` on an array is no longer supported; use `*(arr2).ptr` instead\n---\n*/\n\nvoid main()\n{\n    int[] arr1 = [1, 2, 3];\n    assert(*arr1 == 1);\n    int[3] arr2 = [1, 2, 3];\n    assert(*arr2 == 1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail40.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail40.d(11): Error: variable `yuiop` cannot be read at compile time\n---\n*/\n\nstruct Qwert\n{\n    int[20] yuiop;\n    int* asdfg = yuiop.ptr;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4082.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail4082.d(14): Error: destructor `fail4082.Foo.~this` is not `nothrow`\nfail_compilation/fail4082.d(12): Error: `nothrow` function `fail4082.test1` may throw\n---\n*/\nstruct Foo\n{\n    ~this() { throw new Exception(\"\"); }\n}\nnothrow void test1()\n{\n    Foo f;\n\n    goto NEXT;\nNEXT:\n    ;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail4082.d(32): Error: destructor `fail4082.Bar.~this` is not `nothrow`\nfail_compilation/fail4082.d(32): Error: `nothrow` function `fail4082.test2` may throw\n---\n*/\nstruct Bar\n{\n    ~this() { throw new Exception(\"\"); }\n}\nnothrow void test2(Bar t)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail41.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail41.d(17): Error: cannot return non-void from `void` function\n---\n*/\n\nclass MyClass\n{\n}\n\nMyClass[char[]] myarray;\n\nvoid fn()\n{\n    foreach (MyClass mc; myarray)\n        return mc;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail42.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail42.d(22): Error: struct `fail42.Qwert` no size because of forward reference\n---\n*/\n\n/+\nstruct Qwert\n{\n    Qwert asdfg;\n}\n+/\n\nstruct Qwert\n{\n    Yuiop asdfg;\n}\n\nstruct Yuiop\n{\n    Qwert hjkl;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4206.d",
    "content": "\nstruct s {}\nenum var = s;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4269a.d",
    "content": "enum bool WWW = is(typeof(A.x));\n\ninterface A {\n    B blah;\n    void foo(B b){} \n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4269b.d",
    "content": "enum bool WWW = is(typeof(A.x));\n\nstruct A {\n    B blah;\n    void foo(B b){} \n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4269c.d",
    "content": "enum bool WWW = is(typeof(A.x));\n\nclass A {\n    B blah;\n    void foo(B b){} \n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4269d.d",
    "content": "\nstatic if(is(typeof(X6.init))) {}\nalias Y X6;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4269e.d",
    "content": "\nstatic if(is(typeof(X5.init))) {}\ntypedef Y X5;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4269f.d",
    "content": "\nstatic if(is(typeof(X16))) {}\nalias X16 X16;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4269g.d",
    "content": "\nint[2] d;\nstatic if(is(typeof(Xg.init))) {}\nalias d[1] Xg;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4374.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail4374.d(11): Error: terminating `;` required after do-while statement\n---\n*/\n\nvoid main()\n{\n    do {} while(0)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375a.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n\tif (true)\n\t\tif (false)\n\t\t\tassert(3);\n    else\n        assert(4);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375b.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    // disallowed\n\tif (true)\n\t\tforeach (i; 0 .. 5)\n\t\t\tif (true)\n\t\t\t\tassert(5);\n    else\n        assert(6);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375c.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    if (true)\n        if (false) {\n            assert(6.1);\n        }\n    else {\n        assert(6.2);\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375d.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    if (true)\nlabel2:\n        if (true)\n            assert(15);\n    else \n        assert(16);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375e.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    version (A)\n        if (true)\n            assert(24);\n    else\n        assert(25);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375f.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    version (A)\n        version (B)\n            assert(25.1);\n    else\n        assert(25.2);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375g.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    static if (true)\n        static if (true)\n            assert(33);\n    else\n        assert(34);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375h.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    switch (4) {\n        default:\n            if (true)   // disallowed\n                if (false)\n                    assert(48);\n            else\n                assert(49);\n            break;\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375i.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    if (true)\n        switch (1)  // o_O\n            default:\n                if (false)\n                    assert(115);\n    else\n        assert(116);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375j.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    if (true)\n        final switch (1)    // o_O\n            case 1:\n                if (false)\n                    assert(119);\n    else\n        assert(120);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375k.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    mixin(q{\n        if(true)\n            if(true)\n                assert(54);\n        else\n            assert(55);\n    });\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375l.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    if (true)\n        while (false)\n            if (true)\n                assert(70);\n    else\n        assert(71);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375m.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    do\n        if (true)\n            if (true)\n                assert(76);\n        else\n            assert(77);\n    while (false);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375o.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    if (true)\n        for (; false;)\n            if (true)\n                assert(82);\n    else\n        assert(83);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375p.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    if (true)\n        while (false)\n            for (;;)\n                scope (exit)\n                    synchronized (x)\n                        if (true)\n                            assert(90);\n    else\n        assert(89);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375q.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    auto x = 1;\n    if (true)\n        with (x)\n            if (false)\n                assert(90);\n    else\n        assert(91);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375r.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    if (true)\n        try\n            assert(103);\n        finally\n            if (true)\n                assert(104);\n    else\n        assert(105);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375s.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nvoid main() {\n    if (true)\n        try\n            assert(106);\n        catch(Exception e)\n            if (true)\n                assert(107);\n    else\n        assert(108);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375t.d",
    "content": "// REQUIRED_ARGS: -w -unittest\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nunittest {  // disallowed\n    if (true)\n        if (false)\n            assert(52);\n    else\n        assert(53);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375u.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nstatic if (true)\n    static if (false)\n        struct G1 {}\nelse\n    struct G2 {}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375v.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nversion (A)\n    version (B)\n        struct G3 {}\nelse\n    struct G4 {}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375w.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nstatic if (true)\n    version (B)\n        struct G1 {}\nelse\n    struct G2 {}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375x.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nstatic if (true)\nabstract:\n    static if (false)\n        class G5 {}\nelse\n    class G6 {}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4375y.d",
    "content": "// REQUIRED_ARGS: -w\n// https://issues.dlang.org/show_bug.cgi?id=4375: Dangling else\n\nstatic if (true)\n    align(1)\n        extern(C)\n            pure\n                static if (false)\n                    void G10(){}\nelse\n    void G11(){}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail44.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail44.d(18): Error: expression `bar[i]` is `void` and has no value\n---\n*/\n\nvoid Foo()\n{\n  void[] bar;\n  void[] foo;\n\n  bar.length = 50;\n  foo.length = 50;\n\n  for(size_t i=0; i<50; i++)\n  {\n    foo[i] = bar[i];\n  }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4421.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail4421.d(16): Error: function `fail4421.U1.__postblit` destructors, postblits and invariants are not allowed in union `U1`\nfail_compilation/fail4421.d(17): Error: destructor `fail4421.U1.~this` destructors, postblits and invariants are not allowed in union `U1`\nfail_compilation/fail4421.d(18): Error: function `fail4421.U1.__invariant1` destructors, postblits and invariants are not allowed in union `U1`\n---\n\n\n\n\n*/\n\nunion U1\n{\n    this(this);\n    ~this();\n    invariant() { }\n}\n\nstruct S1\n{\n    this(this);\n    ~this();\n    invariant() { }\n}\n\nunion U2\n{\n    S1 s1;\n}\n\nstruct S2\n{\n    union\n    {\n        S1 s1;\n        int j;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4448.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail4448.d(19): Error: label `L1` has no `break`\nfail_compilation/fail4448.d(26):        called from here: `bug4448()`\nfail_compilation/fail4448.d(26):        while evaluating: `static assert(bug4448() == 3)`\n---\n*/\n\nint bug4448()\n{\n    int n=2;\n    L1:{ switch(n)\n    {\n       case 5:\n        return 7;\n       default:\n       n = 5;\n       break L1;\n    }\n    int w = 7;\n    }\n    return 3;\n}\n\nstatic assert(bug4448()==3);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail45.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail45.d(10): Error: variable `fail45.main.O` cannot be declared to be a function\n---\n*/\n\nvoid main()\n{\n    typeof(main) O = 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4510.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=4510\n\nvoid main()\n{\n    float[] arr = [1.0, 2.5, 4.0];\n    foreach (ref double elem; arr) {\n        //elem /= 2;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4511.d",
    "content": "void test72()\n{\n    class A {}\n    class B : A {}\n\n    class X\n    {\n        abstract A func();\n    }\n    class Y : X\n    {\n        B func() { return new A(); }\n    }\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4517.d",
    "content": "\nenum E : ushort\n{\n    A, B\n}\n\nvoid main()\n{\n    E e;\n    final switch(e)\n    {\n        case E.A:\n            break;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4559.d",
    "content": "/*\nREQUIRED_ARGS: -o- -de\nTEST_OUTPUT:\n---\nfail_compilation/fail4559.d(13): Deprecation: use `{ }` for an empty statement, not `;`\nfail_compilation/fail4559.d(19): Deprecation: use `{ }` for an empty statement, not `;`\nfail_compilation/fail4559.d(21): Deprecation: use `{ }` for an empty statement, not `;`\n---\n*/\n\nvoid foo()\n{\n    int x;;\n    enum A\n    {\n        a,\n        b,\n        c\n    };\n\n    void bar() {};\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail46.d",
    "content": "// PERMUTE_ARGS: -inline\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail46.d(19): Error: need `this` for `bug` of type `int()`\n---\n*/\n\nstruct MyStruct\n{\n    int bug()\n    {\n        return 3;\n    }\n}\n\nint main()\n{\n    assert(MyStruct.bug() == 3);\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4611.d",
    "content": "/*\n---\nfail_compilation/fail4611.d(15): Error: `Vec[2147483647]` size 4 * 2147483647 exceeds 0x7fffffff size limit for static array\n---\n*/\n\nstruct Vec\n{\n    int x;\n}\n\nvoid main()\n{\n    Vec[ptrdiff_t.max] a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail47.d",
    "content": "void foo() {}\nint _foo;\nalias _foo foo;\n\nvoid main()\n{\n    foo = 1;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail4958.d",
    "content": "\nenum FloatEnum : float { A = float.max/2, B, C }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail50.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail50.d(12): Error: need `this` for address of `a`\nfail_compilation/fail50.d(12): Error: variable `a` cannot be read at compile time\n---\n*/\n\nstruct Marko\n{\n    int a;\n    int* m = &a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail51.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail51.d(11): Error: interface `fail51.B` circular inheritance of interface\n---\n*/\n\n// interface A { void f(); }\n\ninterface A : B { void f(); }\ninterface B : A { void g(); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail5153.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=5153\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail5153.d(26): Error: cannot implicitly convert expression `new Foo(0)` of type `Foo*` to `Foo`\nfail_compilation/fail5153.d(26):        Perhaps remove the `new` keyword?\n---\n*/\n\nclass Foo2\n{\n    this(int) {}\n}\n\nstruct Foo {\n    int x;\n    this(int x_)\n    {\n        this.x = x_;\n    }\n\n    this(Foo2) {}\n}\nvoid main() {\n    Foo f = new Foo(0);\n    Foo f2 = new Foo2(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail52.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail52.d(10): Error: class `fail52.C` circular inheritance\n---\n*/\n\nclass A : B { void f(); }\nclass B : C { override void g(); }\nclass C : A { void g(); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail53.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail53.d(26): Error: function `object.Object.opEquals(Object o)` is not callable using argument types `(int)`\nfail_compilation/fail53.d(26):        cannot pass argument `i` of type `int` to parameter `Object o`\n---\n*/\n\n// $HeadURL$\n// $Date$\n// $Author$\n\n// @author@\tThomas Kuehne <thomas-dloop@kuehne.thisisspam.cn>\n// @date@\t2005-01-22\n// @uri@\tnews:csvvet$2g4$1@digitaldaemon.com\n// @url@\tnntp://news.digitalmars.com/digitalmars.D.bugs/2741\n\n// __DSTRESS_ELINE__ 17\n\nmodule dstress.nocompile.bug_mtype_507_A;\n\nint main()\n{\n    Object o;\n    int i;\n    if (i == o)\n    {\n        return -1;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail54.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail54.d(22): Error: incompatible types for `(0) == (Exception)`: cannot use `==` with types\n---\n*/\n\n// $HeadURL$\n// $Date$\n// $Author$\n\n// @author@\tzwang <nehzgnaw@gmail.com>\n// @date@\t2005-02-03\n// @uri@\tnews:ctthp6$25b$1@digitaldaemon.com\n\n// __DSTRESS_ELINE__ 14\n\nmodule dstress.nocompile.bug_mtype_507_C;\n\nvoid test()\n{\n    0 == Exception;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail5435.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=5435\n\ntemplate Tuple5435(E...) { alias E Tuple5435; }\nenum Enum5435 { A, B, C };\n\nvoid main()\n{\n    alias Tuple5435!(Enum5435.A, Enum5435.B, Enum5435.C, \"foo\", 3.0) tup;\n\n    foreach (Enum5435 foo; tup) pragma(msg, foo);\n    foreach (  string foo; tup) pragma(msg, foo);\n    foreach (     int foo; tup) pragma(msg, foo);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail55.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail55.d(23): Error: function `object.Object.opCmp(Object o)` is not callable using argument types `(int)`\nfail_compilation/fail55.d(23):        cannot pass argument `0` of type `int` to parameter `Object o`\n---\n*/\n\n// $HeadURL$\n// $Date$\n// $Author$\n\n// @author@ zwang <nehzgnaw@gmail.com>\n// @date@   2005-02-03\n// @uri@    news:cttjjg$4i0$2@digitaldaemon.com\n\n// __DSTRESS_ELINE__ 14\n\nmodule dstress.nocompile.bug_mtype_507_D;\n\nvoid test()\n{\n    0 < Exception;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail56.d",
    "content": "// $HeadURL$\n// $Date$\n// $Author$\n\n// @author@\tRegan Heath <regan@netwin.co.nz>\n// @date@\t2005-03-30\n// @uri@\tnews:opsof4hwgy23k2f5@nrage.netwin.co.nz\n\n// __DSTRESS_ELINE__ 14\n\nmodule dstress.nocompile.bug_20050330_A;\n\ntemplate Blah(int a, alias B){\n\tmixin Blah!(a, B) Foo;\n}\n\nint main(){\n\tint a;\n\tmixin Blah!(5,a);\n\treturn 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail5634.d",
    "content": "void main() { }\nvoid main() { }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail57.d",
    "content": "\nint main()\n{\n    int x = 1 / 0;\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail5733.d",
    "content": "struct Test\n{\n    struct opDispatch(string dummy)\n    { enum opDispatch = 1; }\n}\nauto temp = Test().foo!(int);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail58.d",
    "content": "debug(1) import std.stdio;\nconst int anything = -1000; // Line #2\ndchar[] SomeFunc( dchar[] pText, out int pStopPosn)\n{\n    if (pText.length == 0)\n        pStopPosn = 0;\n    else\n        pStopPosn = -1;\n    debug(1) writefln(\"DEBUG: using '%s' we get %d\", pText, pStopPosn);\n    return pText.dup;\n}\n\nint main(char[][] pArgs)\n{\n    int sp;\n\n    SomeFunc(\"123\", sp);\n    debug(1) writefln(\"DEBUG: got %d\", sp);\n    assert(sp == -1);\n\n    SomeFunc(\"\", sp);\n//    if (sp != 0){} // Line #22\n    debug(1) writefln(\"DEBUG: got %d\", sp);\n    assert(sp == -1);\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail5851.d",
    "content": "\nclass Foo\n{\n    Object o;\n    alias o this;\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail59.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail59.d(50): Error: outer class `C1` `this` needed to `new` nested class `C2`\n---\n*/\n\nclass C1\n{\n    int c1;\n\n    this()\n    {\n        c1 = 2;\n    }\n\n    class C2\n    {\n        class C3\n        {\n            int c3;\n\n            this(int n)\n            {\n                c3 = n + c1 + c2;\n            }\n        }\n\n        int c2;\n\n        C3 foo()\n        {\n            return new C3(8);\n        }\n\n        this(int k)\n        {\n            c2 = k + 7;\n        }\n    }\n\n    C2 bar()\n    {\n        return new C2(17);\n    }\n}\n\nvoid main()\n{\n    C1.C2 q = new C1.C2(3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail5953a1.d",
    "content": "void main()\n{\n    auto a2 = [,];    // invalid, but compiles\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail5953a2.d",
    "content": "void main()\n{\n    auto a3 = [,,,];    // invalid, but compiles\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail5953s1.d",
    "content": "void main()\n{\n    struct S{}\n    S s2 = {,};   // invalid, but compiles\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail5953s2.d",
    "content": "void main()\n{\n    struct S{}\n    S s3 = {,,,}; // invalid, but compiles\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail60.d",
    "content": "class A\n{\n class B\n {\n\n }\n\n B b=new B;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6029.d",
    "content": "struct A\n{\n    static A a;\n    alias a this;\n}\n\nvoid foo(A a)\n{\n}\n\nvoid main()\n{\n//  foo(A);    // Error: type A is not an expression\n    int s = A; // Error: type A has no value + stack overflow\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail61.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail61.d(22): Error: no property `B` for type `fail61.A.B`\nfail_compilation/fail61.d(23): Error: no property `B` for type `fail61.A.B`\nfail_compilation/fail61.d(32): Error: no property `A2` for type `fail61.B2`\nfail_compilation/fail61.d(41): Error: `this` for `foo` needs to be type `B3` not type `fail61.C3`\n---\n*/\n\nclass A\n{\n    class B : A\n    {\n        static const int C = 5;\n    }\n}\n\nvoid main()\n{\n    int n1 = A.B.C;\n    int n2 = A.B.B.C;       // Line22\n    int n3 = A.B.B.B.C;     // Line23\n}\n\nclass A2 { void foo(){ assert(0);} }\nclass B2 : A2 { override void foo(){} }\nclass C2 : B2\n{\n    void bar()\n    {\n        B2.A2.foo();        // Line32\n    }\n}\n\nclass B3 { void foo(){ assert(0); } }\nclass C3\n{\n    void bar()\n    {\n        B3.foo();           // Line41\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6107.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail6107.d(10): Error: variable `fail6107.Foo.__ctor` is not a constructor; identifiers starting with `__` are reserved for the implementation\nfail_compilation/fail6107.d(14): Error: variable `fail6107.Bar.__ctor` is not a constructor; identifiers starting with `__` are reserved for the implementation\n---\n*/\nstruct Foo\n{\n    enum __ctor = 4;\n}\nclass Bar\n{\n    int __ctor = 4;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail62.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail62.d(11): Error: version `Foo` defined after use\n---\n*/\n\nversion (Foo)\n    int x;\n\nversion = Foo;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6242.d",
    "content": "class A { void fun(int) {} }\n\nclass B : A { void fun(int x) in { assert(x > 0); } body {} }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail63.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail63.d(11): Error: debug `Foo` defined after use\n---\n*/\n\ndebug (Foo)\n    int x;\n\ndebug = Foo;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6334.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail6334.d(12): Error: static assert:  `0` is false\n---\n*/\n\nmixin template T1()\n{\n    mixin T2;                       //compiles if these lines\n    mixin T2!(a, bb, ccc, dddd);    //are before T2 declaration\n    mixin template T2() { static assert(0); }\n}\n\nvoid main()\n{\n    mixin T1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6451.d",
    "content": "\nversion(GNU)\n{\n    static assert(0);\n}\nversion(Win64)\n{\n    static assert(0);\n}\nelse version(X86_64)\n{\n    void error(...){}\n}\nelse\n{\n    static assert(0);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6453.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail6453.d(13): Error: struct `fail6453.S6453x` mixing invariants with different `shared`/`synchronized` qualifiers is not supported\nfail_compilation/fail6453.d(18): Error: class `fail6453.C6453y` mixing invariants with different `shared`/`synchronized` qualifiers is not supported\nfail_compilation/fail6453.d(23): Error: class `fail6453.C6453z` mixing invariants with different `shared`/`synchronized` qualifiers is not supported\n---\n*/\n\nstruct S6453x\n{\n           invariant() {}\n    shared invariant() {}\n}\nclass C6453y\n{\n           invariant() {}\n    synchronized invariant() {}\n}\nclass C6453z\n{\n          shared invariant() {}\n    synchronized invariant() {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6458.d",
    "content": "\nvoid main()\n{\n    char d = '';\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6497.d",
    "content": "\nvoid main() @safe\n{\n    int n;\n    auto b = &(0 ? n : n);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6561.d",
    "content": "struct S\n{\n    alias x this;   // should cause undefined identifier error\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail66.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail66.d(11): Error: constructor `fail66.C1.this` missing initializer for const field `y`\n---\n*/\n\nclass C1\n{\n    const int y;\n    this() {}\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail66.d(28): Error: cannot modify `const` expression `c.y`\n---\n*/\nclass C2\n{\n    const int y;\n    this() { y = 7; }\n}\nvoid test2()\n{\n    C2 c = new C2();\n    c.y = 3;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail66.d(43): Error: cannot modify `const` expression `this.y`\n---\n*/\nclass C3\n{\n    const int y;\n    this() { y = 7; }\n    void foo()\n    {\n        y = 6;\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail66.d(59): Error: cannot modify `const` expression `x`\n---\n*/\nclass C4\n{\n    static const int x;\n    static this() { x = 5; }\n    void foo()\n    {\n        x = 4;\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail66.d(73): Error: cannot modify `const` expression `z5`\n---\n*/\nconst int z5;\nstatic this() { z5 = 3; }\nvoid test5()\n{\n    z5 = 4;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail66.d(89): Error: cannot modify `const` expression `c.y`\n---\n*/\nclass C6\n{\n    const int y;\n    this()\n    {\n        C6 c = this;\n        y = 7;\n        c.y = 8;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6611.d",
    "content": "\nvoid main()\n{\n    auto x = new int[](10);\n    x[]++;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6652.d",
    "content": "// PERMUTE_ARGS: -w -dw -de -d\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6652\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail6652.d(20): Error: cannot modify `const` expression `i`\nfail_compilation/fail6652.d(25): Error: cannot modify `const` expression `i`\nfail_compilation/fail6652.d(30): Error: cannot modify `const` expression `i`\nfail_compilation/fail6652.d(35): Error: cannot modify `const` expression `i`\n---\n*/\n\nvoid main()\n{\n    foreach (const i; 0..2)\n    {\n        ++i;\n    }\n\n    foreach (ref const i; 0..2)\n    {\n        ++i;\n    }\n\n    foreach (const i, e; [1,2,3,4,5])\n    {\n        ++i;\n    }\n\n    foreach (ref const i, e; [1,2,3,4,5])\n    {\n        ++i;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6781.d",
    "content": "void bug6781(alias xxx)() {\n    some_error;\n}\nstruct C6781 {\n    void makeSortedIndices() {\n        int greater;\n        bug6781!greater();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6795.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=6795\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail6795.d(12): Error: cannot modify constant `0`\nfail_compilation/fail6795.d(13): Error: cannot modify constant `0`\n---\n*/\n\nvoid main() {\n    enum int[] array = [0];\n    array[0]++;\n    array[0] += 3;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail6795.d(31): Error: cannot modify constant `0`\nfail_compilation/fail6795.d(32): Error: cannot modify constant `0`\nfail_compilation/fail6795.d(33): Error: cannot modify constant `0`\n---\n*/\n\nvoid test_wrong_line_num()\n{\n    enum int[] da = [0];\n    enum int[1] sa = [0];\n    enum int[int] aa = [0:0];\n\n    da[0] += 3;\n    sa[0] += 3;\n    aa[0] += 3;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6889.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail6889.d(16): Error: cannot `goto` out of `scope(success)` block\nfail_compilation/fail6889.d(17): Error: cannot `goto` in to `scope(success)` block\nfail_compilation/fail6889.d(19): Error: `return` statements cannot be in `scope(success)` bodies\nfail_compilation/fail6889.d(23): Error: `continue` is not inside `scope(success)` bodies\nfail_compilation/fail6889.d(24): Error: `break` is not inside `scope(success)` bodies\nfail_compilation/fail6889.d(29): Error: `continue` is not inside `scope(success)` bodies\nfail_compilation/fail6889.d(30): Error: `break` is not inside `scope(success)` bodies\n---\n*/\nvoid test_success()\n{\nL1:\n    scope(success) { L2: goto L1; } // NG\n    goto L2;                        // NG\n\n    scope(success) { return; }      // NG (from fail102.d)\n\n    foreach (i; 0..1)\n    {\n        scope(success) continue;    // NG\n        scope(success) break;       // NG\n    }\n\n    foreach (i; Aggr())\n    {\n        scope(success) continue;    // NG\n        scope(success) break;       // NG\n    }\n  /+\n    // is equivalent with:\n    switch (\n      Aggr().opApply((int i){\n        scope(success) return 0;    // NG\n        scope(success) return 1;    // NG\n        return 0;\n      }))\n    {\n        default: break;\n    }\n  +/\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail6889.d(56): Error: cannot `goto` in to `scope(failure)` block\n---\n*/\nvoid test_failure()\n{\nL1:\n    scope(failure) { L2: goto L1; } // OK\n    goto L2;                        // NG\n\n    scope(failure) { return; }      // OK\n\n    foreach (i; 0..1)\n    {\n        scope(failure) continue;    // OK\n        scope(failure) break;       // OK\n    }\n\n    foreach (i; Aggr())\n    {\n        scope(failure) continue;    // OK\n        scope(failure) break;       // OK\n    }\n  /+\n    // is equivalent with:\n    switch (\n      Aggr().opApply((int i){\n        scope(failure) return 0;    // OK\n        scope(failure) return 1;    // OK\n        return 0;\n      }))\n    {\n        default: break;\n    }\n  +/\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail6889.d(100): Error: cannot `goto` out of `scope(exit)` block\nfail_compilation/fail6889.d(101): Error: cannot `goto` in to `scope(exit)` block\nfail_compilation/fail6889.d(103): Error: `return` statements cannot be in `scope(exit)` bodies\nfail_compilation/fail6889.d(107): Error: `continue` is not inside `scope(exit)` bodies\nfail_compilation/fail6889.d(108): Error: `break` is not inside `scope(exit)` bodies\nfail_compilation/fail6889.d(113): Error: `continue` is not inside `scope(exit)` bodies\nfail_compilation/fail6889.d(114): Error: `break` is not inside `scope(exit)` bodies\n---\n*/\nvoid test_exit()\n{\nL1:\n    scope(exit) { L2: goto L1; }    // NG\n    goto L2;                        // NG\n\n    scope(exit) { return; }         // NG (from fail102.d)\n\n    foreach (i; 0..1)\n    {\n        scope(exit) continue;       // NG\n        scope(exit) break;          // NG\n    }\n\n    foreach (i; Aggr())\n    {\n        scope(exit) continue;       // NG\n        scope(exit) break;          // NG\n    }\n  /+\n    // is equivalent with:\n    switch (\n      Aggr().opApply((int i){\n        scope(exit) return 0;       // NG\n        scope(exit) return 1;       // NG\n        return 0;\n      }))\n    {\n        default: break;\n    }\n  +/\n}\n\nstruct Aggr { int opApply(int delegate(int) dg) { return dg(0); } }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail6968.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=6968\n\ntemplate Pred(A, B)\n{\n    static if(is(B == int))\n        enum bool Pred = true;\n    else\n        enum bool Pred = false;\n}\n\ntemplate PredAny(A, B...)\n{\n    static if(B.length == 0)\n        enum bool PredAny = false;\n    else\n        enum bool PredAny = Pred(A, B[0]) || PredAny(A, B[1..$]);\n}\n\nvoid main()\n{\n    pragma(msg, PredAny!(int, long, float));\n} \n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7077.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail7077.d(11): Error: undefined identifier `x`\n---\n*/\n\nvoid main()\n{\n    if(0) mixin(\"auto x = 2;\");\n    assert(x == 2);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7173.d",
    "content": "struct A{\n\n  A opBinary(string op)(A a){ A rt; return rt; }\n\n  void fun(){ }\n}\n\nstruct B{\n\n  A _a;\n  alias _a this;\n}\n\n\nvoid main(){\n\n  B b1, b2, b3; b3 = (b1 - b2).fun();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7178.d",
    "content": "template populate(overloads...)\n{\n    mixin populate!(.contents);\n}\npublic mixin populate!int;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail72.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail72.d(10): Error: undefined identifier `foo`\n---\n*/\n\nvoid main()\n{\n    synchronized( foo )\n    {\n\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7234.d",
    "content": "\nstruct Contract {\n    void opDispatch()(){}\n}\n\nvoid foo()\n{\n    Contract* r; if (r.empty) {}\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail73.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail73.d(20): Error: `case` not in `switch` statement\n---\n*/\n\n// segfault DMD 0.120\n// http://www.digitalmars.com/d/archives/digitalmars/D/bugs/4634.html\n\nvoid main()\n{\n    int u=2;\n\n    switch(u)\n    {\n        case 1:\n            void j()\n            {\n                case 2:\n                    u++;\n            }\n            break;\n\n        default:\n            break;\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7369.d",
    "content": "struct S7369 {\n    int a;\n    invariant() { a += 5; }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail74.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail74.d(13): Error: cannot append type `C[1]` to type `C[1]`\n---\n*/\n\nclass C\n{\n    C[1] c;\n    this()\n    {\n        c ~= c;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7424b.d",
    "content": "struct S7424b\n{\n    @property int g()() { return 0; }\n    void test() const { int f = g; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7424c.d",
    "content": "struct S7424c\n{\n    @property int g()() { return 0; }\n    void test() immutable { int f = g; }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7424d.d",
    "content": "struct S7424d\n{\n    @property int g()() immutable { return 0; }\n    void test() const { int f = g; }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7424e.d",
    "content": "struct S7424e\n{\n    @property int g()() immutable { return 0; }\n    void test() { int f = g; }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7424f.d",
    "content": "struct S7424f\n{\n    @property int g()() shared { return 0; }\n    void test() { int f = g; }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7424g.d",
    "content": "struct S7424g\n{\n    @property int g()() { return 0; }\n    void test() shared { int f = g; }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7424h.d",
    "content": "struct S7424g\n{\n    @property int g()() { return 0; }\n    void test() inout { int f = g; }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7424i.d",
    "content": "struct S7424g\n{\n    @property int g()() immutable { return 0; }\n    void test() inout { int f = g; }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7443.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail7443.d(12): Deprecation: `static` has no effect on a constructor inside a `static` block. Use `static this()`\nfail_compilation/fail7443.d(13): Deprecation: `shared static` has no effect on a constructor inside a `shared static` block. Use `shared static this()`\n---\n*/\n\nclass Foo\n{\n    public static { this() {}}\n    public shared static { this() {}}\n    public {this() {}}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail75.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail75.d(13): Error: cannot append type `fail75.C` to type `C[1]`\n---\n*/\n\nclass C\n{\n    C[1] c;\n    this()\n    {\n        c ~= this;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7524a.d",
    "content": "\n// https://issues.dlang.org/show_bug.cgi?id=7524\n\n#line 47 __DATE__\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7524b.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=7524\n\n#line 47 __VERSION__\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail76.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail76.d(9): Error: alias `fail76.a` conflicts with alias `fail76.a` at fail_compilation/fail76.d(8)\n---\n*/\n\nalias main a;\nalias void a;\n\nvoid main()\n{\n    a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7603a.d",
    "content": "void test(ref bool val = true) { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7603b.d",
    "content": "void test(out bool val = true) { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7603c.d",
    "content": "enum x = 3;\nvoid test(ref int val = x) { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail77.d",
    "content": "void test()\n{\n    int i;\n    ubyte[4] ub;\n    ub[] = cast(ubyte[4]) &i;\n    //ub[] = (cast(ubyte*) &i)[0..4];\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7702.d",
    "content": "struct S\n{\n   template opDispatch (string name) {}\n}\nvoid main()\n{\n    S s;\n    s.x!int;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7751.d",
    "content": "class Foo(T)\n{\n    T x;\n    Foo y;\n}\nauto foo(T)(T x, Foo!T y=null)\n{\n    return new Foo!T(x, y);\n}\nvoid bar(U)(U foo, U[] spam=[])\n{\n    spam ~= [];\n}\nvoid main()\n{\n    bar(foo(0));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail78.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail78.d(9): Error: undefined identifier `inch`\n---\n*/\n\nauto yd = ft * 3;\nauto ft = inch * 12;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7848.d",
    "content": "// REQUIRED_ARGS: -unittest\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail7848.d(49): Deprecation: class allocators have been deprecated, consider moving the allocation strategy outside of the class\nfail_compilation/fail7848.d(55): Deprecation: class deallocators have been deprecated, consider moving the deallocation strategy outside of the class\nfail_compilation/fail7848.d(41): Error: `pure` function `fail7848.C.__unittest_L39_C30` cannot call impure function `fail7848.func`\nfail_compilation/fail7848.d(41): Error: `@safe` function `fail7848.C.__unittest_L39_C30` cannot call `@system` function `fail7848.func`\nfail_compilation/fail7848.d(35):        `fail7848.func` is declared here\nfail_compilation/fail7848.d(41): Error: `@nogc` function `fail7848.C.__unittest_L39_C30` cannot call non-@nogc function `fail7848.func`\nfail_compilation/fail7848.d(41): Error: function `fail7848.func` is not `nothrow`\nfail_compilation/fail7848.d(39): Error: `nothrow` function `fail7848.C.__unittest_L39_C30` may throw\nfail_compilation/fail7848.d(46): Error: `pure` function `fail7848.C.__invariant1` cannot call impure function `fail7848.func`\nfail_compilation/fail7848.d(46): Error: `@safe` function `fail7848.C.__invariant1` cannot call `@system` function `fail7848.func`\nfail_compilation/fail7848.d(35):        `fail7848.func` is declared here\nfail_compilation/fail7848.d(46): Error: `@nogc` function `fail7848.C.__invariant1` cannot call non-@nogc function `fail7848.func`\nfail_compilation/fail7848.d(46): Error: function `fail7848.func` is not `nothrow`\nfail_compilation/fail7848.d(44): Error: `nothrow` function `fail7848.C.__invariant1` may throw\nfail_compilation/fail7848.d(51): Error: `pure` allocator `fail7848.C.new` cannot call impure function `fail7848.func`\nfail_compilation/fail7848.d(51): Error: `@safe` allocator `fail7848.C.new` cannot call `@system` function `fail7848.func`\nfail_compilation/fail7848.d(35):        `fail7848.func` is declared here\nfail_compilation/fail7848.d(51): Error: `@nogc` allocator `fail7848.C.new` cannot call non-@nogc function `fail7848.func`\nfail_compilation/fail7848.d(51): Error: function `fail7848.func` is not `nothrow`\nfail_compilation/fail7848.d(49): Error: `nothrow` allocator `fail7848.C.new` may throw\nfail_compilation/fail7848.d(57): Error: `pure` deallocator `fail7848.C.delete` cannot call impure function `fail7848.func`\nfail_compilation/fail7848.d(57): Error: `@safe` deallocator `fail7848.C.delete` cannot call `@system` function `fail7848.func`\nfail_compilation/fail7848.d(35):        `fail7848.func` is declared here\nfail_compilation/fail7848.d(57): Error: `@nogc` deallocator `fail7848.C.delete` cannot call non-@nogc function `fail7848.func`\nfail_compilation/fail7848.d(57): Error: function `fail7848.func` is not `nothrow`\nfail_compilation/fail7848.d(55): Error: `nothrow` deallocator `fail7848.C.delete` may throw\n---\n*/\n\nvoid func() {}\n\nclass C\n{\n    @safe pure nothrow @nogc unittest\n    {\n        func();\n    }\n\n    @safe pure nothrow @nogc invariant\n    {\n        func();\n    }\n\n    @safe pure nothrow @nogc new (size_t sz)\n    {\n        func();\n        return null;\n    }\n\n    @safe pure nothrow @nogc delete (void* p)\n    {\n        func();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7851.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=7851\n\n\ntemplate TypeTuple(TList...)\n{\n    alias TList TypeTuple;\n}\n\nstruct Tuple(Specs...)\n{\n    TypeTuple!(int, long, float) mem;\n\n    alias Identity!(mem[0]) _0;\n    alias Identity!(mem[1]) _1;\n    alias Identity!(mem[2]) _2;\n\n    alias mem this;\n\n    enum length = mem.length;\n}\n\nprivate template Identity(alias T)\n{\n    alias T Identity;\n}\n\n\nvoid main() {\n  alias Tuple!(int, long, float) TL;\n  foreach (i; TL)\n  { }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7859.d",
    "content": "template A(alias B) {}\n\nmixin template C(alias B = cast(NonExistent)null) {\n  alias A!B D;\n}\n\nmixin C!();\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7861.d",
    "content": "module test;\n\nmixin template A() {\nimport test;\n}\n\nstruct B {\nmixin A!();\n}\n\nenum C = B.nonexistent;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7862.d",
    "content": "/*\nTEST_OUTPUT:\n---\nA: false\nA: false\nfail_compilation/fail7862.d(26): Error: template instance `nonExistent!()` template `nonExistent` is not defined\nfail_compilation/fail7862.d(25): Error: template instance `fail7862.B!(A)` error instantiating\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=7862\n\ntemplate B(T) {\n  mixin(\n    {\n      foreach (name; __traits(derivedMembers, T)) {}\n      return \"struct B {}\";\n    }()\n  );\n}\n\nstruct A {\n  pragma(msg, \"A: \" ~ (__traits(compiles, B!A) ? \"true\" : \"false\"));\n  pragma(msg, \"A: \" ~ (__traits(compiles, B!A) ? \"true\" : \"false\"));\n  B!A c;\n  static if (nonExistent!()) {}\n}\n\nauto d = A.init.c;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail79.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail79.d(13): Error: incompatible types for `(& a) + (& b)`: both operands are of type `int*`\n---\n*/\n\nvoid main()\n{\n    int a, b;\n    int* p;\n\n    p = &a + &b;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail7903.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail7903.d(21): Error: variable `fail7903.F1.x` Field members of a `synchronized` class cannot be `public`\nfail_compilation/fail7903.d(22): Error: variable `fail7903.F1.y` Field members of a `synchronized` class cannot be `export`\nfail_compilation/fail7903.d(27): Error: variable `fail7903.F2.x` Field members of a `synchronized` class cannot be `public`\n---\n*/\nsynchronized class K1\n{\n    public struct S { }\n}\n\nsynchronized class K2\n{\n    struct S { }\n}\n\nsynchronized class F1\n{\n    public int x;\n    export int y;\n}\n\nsynchronized class F2\n{\n    int x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail8009.d",
    "content": "void filter(R)(scope bool delegate(ref BAD!R) func) { }\nvoid main() { filter(r => r); }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail8032.d",
    "content": "mixin template T()\n{\n    void f() { }\n}\n\nclass A {\n    mixin T;\n    mixin T;\n}\n\nclass B : A\n{\n    override void f() { }\n    // raises \"cannot determine overridden function\" error.\n}\n\nvoid main(){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail80_m32.d",
    "content": "// REQUIRED_ARGS: -m32\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail80_m32.d(28): Error: cannot implicitly convert expression `\"progress_rem\"` of type `string` to `uint`\nfail_compilation/fail80_m32.d(29): Error: cannot implicitly convert expression `\"redo\"` of type `string` to `uint`\n---\n*/\n\nmodule paintshop;\n\nclass Image{}\n\nclass ResourceManager\n{\n    Image getImage(char[] name) { return null; }\n}\n\nclass Test\n{\n    import std.file;\n    import std.path;\n\n    static Image[] images;\n\n    static void initIcons() \n    {\n        images[\"progress_rem\"]  = ResourceManager.getImage(\"progress_rem.gif\"); // delete_obj_dis\n        images[\"redo\"]          = ResourceManager.getImage(\"redo.gif\");\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail80_m64.d",
    "content": "// REQUIRED_ARGS: -m64\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail80_m64.d(28): Error: cannot implicitly convert expression `\"progress_rem\"` of type `string` to `ulong`\nfail_compilation/fail80_m64.d(29): Error: cannot implicitly convert expression `\"redo\"` of type `string` to `ulong`\n---\n*/\n\nmodule paintshop;\n\nclass Image{}\n\nclass ResourceManager\n{\n    Image getImage(char[] name) { return null; }\n}\n\nclass Test\n{\n    import std.file;\n    import std.path;\n\n    static Image[] images;\n\n    static void initIcons() \n    {\n        images[\"progress_rem\"]  = ResourceManager.getImage(\"progress_rem.gif\"); // delete_obj_dis\n        images[\"redo\"]          = ResourceManager.getImage(\"redo.gif\");\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail8168.d",
    "content": "void main() {\n    asm {\n        unknown; // wrong opcode\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail8179b.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail8179b.d(10): Error: cannot cast expression `[1, 2]` of type `int[]` to `int[2][1]`\n---\n*/\nvoid foo(int[2][1]) {}\nvoid main() {\n    foo(cast(int[2][1])[1, 2]);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail8217.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail8217.d(22): Error: `this` for `foo` needs to be type `D` not type `fail8217.D.C`\n---\n*/\n\nclass D\n{\n    int x;\n    template bar()\n    {\n        int foo()\n        {\n            return x;\n        }\n    }\n    static class C\n    {\n        int foo()\n        {\n            return bar!().foo();\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail8262.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/fail8262.d(32): Error: cannot interpret `Tuple8262!1` at compile time\nfail_compilation/fail8262.d(27): Error: template instance `fail8262.T8262!(Tuple8262!1)` error instantiating\nfail_compilation/fail8262.d(19): Error: cannot implicitly convert expression `S(0)` of type `S` to `int`\n---\n * https://issues.dlang.org/show_bug.cgi?id=8262\n */\n\ntemplate Seq(T...) { alias T Seq; }\n\nstruct S\n{\n    int s;\n    alias Seq!s _;\n    alias _ this;\n}\n\nint si = S.init;\n\nstruct Tuple8262(T...)\n{\n    alias T expand;\n    alias expand this;\n}\n\nauto data = T8262!(Tuple8262!1);\n//pragma(msg, data);\n\ntemplate T8262(T)\n{\n    immutable(int) T8262 = T;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail8313.d",
    "content": "auto bar()(int x){return x;}\nauto bar()(int x = bar()){return x;}\nstatic assert(bar(1));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail8373.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail8373.d(21): Error: `fail8373.fun1` called with argument types `(int)` matches both:\nfail_compilation/fail8373.d(15):     `fail8373.fun1!().fun1!int.fun1(int)`\nand:\nfail_compilation/fail8373.d(16):     `fail8373.fun1!int.fun1(int)`\nfail_compilation/fail8373.d(22): Error: `fail8373.fun2` called with argument types `(int)` matches both:\nfail_compilation/fail8373.d(18):     `fail8373.fun2!int.fun2(int)`\nand:\nfail_compilation/fail8373.d(19):     `fail8373.fun2!().fun2!int.fun2(int)`\n---\n*/\n\ntemplate fun1(a...) { auto fun1(T...)(T args){ return 1; } }\n                      auto fun1(T...)(T args){ return 2; }\n\n                      auto fun2(T...)(T args){ return 2; }\ntemplate fun2(a...) { auto fun2(T...)(T args){ return 1; } }\n\nenum x1 = fun1(0);\nenum x2 = fun2(0);\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail86.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail86.d(12): Error: alias `Foo` recursive alias declaration\n---\n*/\n\ntemplate Foo(TYPE) {}\n\nvoid main()\n{\n    alias Foo!(int) Foo;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail8631.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail8631.d(14): Error: function `shared const int fail8631.D.foo()` does not override any function, did you mean to override `immutable int fail8631.B.foo()`?\n---\n*/\n\nclass B {\n    int foo() immutable { return 2; }\n    int foo() const { return 2; }\n}\nclass D : B {\n    override int foo() immutable { return 2; }\n    override int foo() const shared { return 2; }   // doesn't override any\n    override int foo() const { return 2; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail8691.d",
    "content": "struct Foo\n{\n    Foo[1] f;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail8724.d",
    "content": "// REQUIRED_ARGS: -w\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail8724.d(14): Error: `object.Exception` is thrown but not caught\nfail_compilation/fail8724.d(12): Error: `nothrow` constructor `fail8724.Foo.this` may throw\n---\n*/\n\nstruct Foo\n{\n    this(int) nothrow\n    {\n        throw new Exception(\"something\");\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9.d(23): Error: no property `Vector` for type `fail9.Vector!int`\n---\n*/\n\ntemplate Vector(T)\n{\n    int x;\n\n    class Vector\n    {\n    }\n}\n\nstruct Sorter\n{\n}\n\nvoid Vector_test_int()\n{\n    alias Vector!(int).Vector vector_t;\n    vector_t v;\n    Sorter sorter;\n    v.sort_with!(int)(sorter);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9063.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9063.d(9): Error: static assert:  \"msg\"\n---\n*/\n\n@property string bar() { return \"msg\"; }\nstatic assert(false, bar);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9081.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9081.d(12): Error: package `core` has no type\nfail_compilation/fail9081.d(13): Error: package `stdc` has no type\nfail_compilation/fail9081.d(14): Error: module `stdio` has no type\n---\n*/\n\nimport core.stdc.stdio;\n\ntypeof(core) a;\ntypeof(core.stdc) b;\ntypeof(core.stdc.stdio) c;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail91.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail91.d(12): Error: struct `fail91.S` unknown size\n---\n*/\n\nstruct S;\n\nvoid main()\n{\n    S* s = new S();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9199.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9199.d(13): Error: function `fail9199.fc` without `this` cannot be `const`\nfail_compilation/fail9199.d(14): Error: function `fail9199.fi` without `this` cannot be `immutable`\nfail_compilation/fail9199.d(15): Error: function `fail9199.fw` without `this` cannot be `inout`\nfail_compilation/fail9199.d(16): Error: function `fail9199.fs` without `this` cannot be `shared`\nfail_compilation/fail9199.d(17): Error: function `fail9199.fsc` without `this` cannot be `shared const`\nfail_compilation/fail9199.d(18): Error: function `fail9199.fsw` without `this` cannot be `shared inout`\n---\n*/\nvoid fc() const {}\nvoid fi() immutable {}\nvoid fw() inout {}\nvoid fs() shared {}\nvoid fsc() shared const {}\nvoid fsw() shared inout {}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9199.d(33): Error: function `fail9199.C.fc` without `this` cannot be `const`\nfail_compilation/fail9199.d(34): Error: function `fail9199.C.fi` without `this` cannot be `immutable`\nfail_compilation/fail9199.d(35): Error: function `fail9199.C.fw` without `this` cannot be `inout`\nfail_compilation/fail9199.d(36): Error: function `fail9199.C.fs` without `this` cannot be `shared`\nfail_compilation/fail9199.d(37): Error: function `fail9199.C.fsc` without `this` cannot be `shared const`\nfail_compilation/fail9199.d(38): Error: function `fail9199.C.fsw` without `this` cannot be `shared inout`\n---\n*/\nclass C\n{\n    static void fc() const {}\n    static void fi() immutable {}\n    static void fw() inout {}\n    static void fs() shared {}\n    static void fsc() shared const {}\n    static void fsw() shared inout {}\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail92.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail92.d(15): Error: invalid `foreach` aggregate `t`\nfail_compilation/fail92.d(23): Error: template instance `fail92.crash!(typeof(null))` error instantiating\n---\n*/\n\n// [25]\n\ntemplate crash(T)\n{\n    void crash(T t)\n    {\n        foreach (u; t)\n        {\n        }\n    }\n}\n\nvoid main()\n{\n    crash(null);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9279.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9279.d(10): Error: escaping reference to stack allocated value returned by `b()`\nfail_compilation/fail9279.d(13): Error: escaping reference to stack allocated value returned by `getArr()`\n---\n*/\n\nchar[2] b()() { char[2] ret; return ret; }\nstring a() { return b(); }\n\nchar[12] getArr() { return \"Hello World!\"; }\nstring getString() { return getArr(); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9290.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9290.d(15): Error: slice `s1[]` is not mutable, struct `S` has immutable members\nfail_compilation/fail9290.d(16): Error: array `s1` is not mutable, struct `S` has immutable members\n---\n*/\n\nstruct S { immutable int i; }\n\nvoid main()\n{\n    S[1] s1 = S(1);\n    S[1] s2 = S(2);\n    s1 = S(3);\n    s1 = s2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail93.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail93.d(13): Error: variable `i` is shadowing variable `fail93.main.i`\n---\n*/\n\n// accepts-valid with DMD0.120. volatile as well as synchronized\n\nvoid main()\n{\n    int i = 1;\n    synchronized int i = 2; // should fail to compile\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9301.d",
    "content": "/*\nREQUIRED_ARGS: -o-\nPERMUTE_ARGS:\n*/\n\nvoid main()\n{\n    __vector(void[16]) x = 0x0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9346.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9346.d(26): Error: struct `fail9346.S` is not copyable because it is annotated with `@disable`\nfail_compilation/fail9346.d(27): Error: struct `fail9346.S` is not copyable because it is annotated with `@disable`\n---\n*/\n\nstruct S\n{\n    @disable this(this);\n}\nstruct SS1\n{\n    S s;\n}\nstruct SS2\n{\n    S s;\n    this(this){}\n}\n\nvoid main()\n{\n    S s;\n    SS1 ss1 = SS1(s);\n    SS2 ss2 = SS2(s);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9368.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9368.d(20): Error: `enum` member `b` not represented in `final switch`\n---\n*/\n\nenum E\n{\n    a,\n    b\n}\n\nvoid main()\n{\n    alias E F;\n    F f;\n    final switch (f)\n    {\n        case F.a:\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9368.d(41): Error: `enum` member `B` not represented in `final switch`\n---\n*/\n\nenum G\n{\n    A,B,C\n}\n\nvoid test286()\n{\n    G e;\n    final switch (e)\n    {\n        case G.A:\n//      case G.B:\n        case G.C:\n            {}\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail94.d",
    "content": "interface I\n{\n    int foo();\n}\n\nclass IA : I\n{\n    int foo() { return 1; }\n}\n\nclass A\n{\n    I i;\n\n    I clone() { return i; }\n}\n\nclass B : A\n{\n    IA ia;\n\n    IA clone()\n    out (result)\n    {\n\tprintf(\"B.clone()\\n\");\n    }\n    body { return ia; }\n}\n\nvoid main()\n{\n    IA ia = new IA;\n    assert(ia.foo() == 1);\n\n    I i = ia;\n    assert(i.foo() == 1);\n\n    A a = new A;\n    a.i = i;\n    assert(a.clone().foo() == 1);\n\n    B b = new B;\n    b.ia = ia;\n    assert(b.clone().foo() == 1);\n\n    a = b;\n    assert(a.clone().foo() == 1);\n\n    bar(&b.clone);\n}\n\n\nvoid bar(IA delegate() dg)\n{\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9413.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9413.d(45): Error: variable `fail9413.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9413.d(32): Error: variable `fail9413.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9413.d(33): Error: variable `fail9413.foo.bar.y` cannot modify parameter `y` in contract\nfail_compilation/fail9413.d(38): Error: variable `fail9413.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9413.d(39): Error: variable `fail9413.foo.bar.y` cannot modify parameter `y` in contract\nfail_compilation/fail9413.d(40): Error: variable `fail9413.foo.bar.s` cannot modify result `s` in contract\nfail_compilation/fail9413.d(50): Error: variable `fail9413.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9413.d(73): Error: variable `fail9413.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9413.d(74): Error: variable `fail9413.foo.r` cannot modify result `r` in contract\nfail_compilation/fail9413.d(58): Error: variable `fail9413.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9413.d(59): Error: variable `fail9413.foo.r` cannot modify result `r` in contract\nfail_compilation/fail9413.d(60): Error: variable `fail9413.foo.baz.y` cannot modify parameter `y` in contract\nfail_compilation/fail9413.d(65): Error: variable `fail9413.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9413.d(66): Error: variable `fail9413.foo.r` cannot modify result `r` in contract\nfail_compilation/fail9413.d(67): Error: variable `fail9413.foo.baz.y` cannot modify parameter `y` in contract\nfail_compilation/fail9413.d(68): Error: variable `fail9413.foo.baz.s` cannot modify result `s` in contract\nfail_compilation/fail9413.d(79): Error: variable `fail9413.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9413.d(80): Error: variable `fail9413.foo.r` cannot modify result `r` in contract\n---\n*/\n\nint foo(int x)\nin\n{\n    int a;\n    int bar(int y)\n    in\n    {\n        x = 10; // err\n        y = 10; // err\n        a = 1;  // OK\n    }\n    out(s)\n    {\n        x = 10; // err\n        y = 10; // err\n        s = 10; // err\n        a = 1;  // OK\n    }\n    body\n    {\n        x = 10; // err\n        y = 1;  // OK\n        a = 1;  // OK\n        return 2;\n    }\n    x = 10; // err\n}\nout(r)\n{\n    int a;\n    int baz(int y)\n    in\n    {\n        x = 10; // err\n        r = 10; // err\n        y = 10; // err\n        a = 1;  // OK\n    }\n    out(s)\n    {\n        x = 10; // err\n        r = 10; // err\n        y = 10; // err\n        s = 10; // err\n        a = 1;  // OK\n    }\n    body\n    {\n        x = 10; // err\n        r = 10; // err\n        y = 1;  // OK\n        a = 1;  // OK\n        return 2;\n    }\n    x = 10; // err\n    r = 10; // err\n}\nbody\n{\n    return 1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9414a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9414a.d(47): Error: variable `fail9414a.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414a.d(34): Error: variable `fail9414a.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414a.d(35): Error: variable `fail9414a.C.foo.__require.bar.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414a.d(40): Error: variable `fail9414a.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414a.d(41): Error: variable `fail9414a.C.foo.__require.bar.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414a.d(42): Error: variable `fail9414a.C.foo.__require.bar.s` cannot modify result `s` in contract\nfail_compilation/fail9414a.d(52): Error: variable `fail9414a.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414a.d(75): Error: variable `fail9414a.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414a.d(76): Error: variable `fail9414a.C.foo.__ensure.r` cannot modify result `r` in contract\nfail_compilation/fail9414a.d(60): Error: variable `fail9414a.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414a.d(61): Error: variable `fail9414a.C.foo.__ensure.r` cannot modify result `r` in contract\nfail_compilation/fail9414a.d(62): Error: variable `fail9414a.C.foo.__ensure.baz.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414a.d(67): Error: variable `fail9414a.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414a.d(68): Error: variable `fail9414a.C.foo.__ensure.r` cannot modify result `r` in contract\nfail_compilation/fail9414a.d(69): Error: variable `fail9414a.C.foo.__ensure.baz.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414a.d(70): Error: variable `fail9414a.C.foo.__ensure.baz.s` cannot modify result `s` in contract\nfail_compilation/fail9414a.d(81): Error: variable `fail9414a.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414a.d(82): Error: variable `fail9414a.C.foo.__ensure.r` cannot modify result `r` in contract\n---\n*/\n\nclass C\n{\n    int foo(int x)\n    in\n    {\n        int a;\n        int bar(int y)\n        in\n        {\n            x = 10; // err\n            y = 10; // err\n            a = 1;  // OK\n        }\n        out(s)\n        {\n            x = 10; // err\n            y = 10; // err\n            s = 10; // err\n            a = 1;  // OK\n        }\n        body\n        {\n            x = 10; // err\n            y = 1;  // OK\n            a = 1;  // OK\n            return 2;\n        }\n        x = 10; // err\n    }\n    out(r)\n    {\n        int a;\n        int baz(int y)\n        in\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 10; // err\n            a = 1;  // OK\n        }\n        out(s)\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 10; // err\n            s = 10; // err\n            a = 1;  // OK\n        }\n        body\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 1;  // OK\n            a = 1;  // OK\n            return 2;\n        }\n        x = 10; // err\n        r = 10; // err\n    }\n    body\n    {\n        return 1;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9414b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9414b.d(47): Error: variable `fail9414b.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414b.d(34): Error: variable `fail9414b.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414b.d(35): Error: variable `fail9414b.C.foo.__require.bar.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414b.d(40): Error: variable `fail9414b.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414b.d(41): Error: variable `fail9414b.C.foo.__require.bar.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414b.d(42): Error: variable `fail9414b.C.foo.__require.bar.s` cannot modify result `s` in contract\nfail_compilation/fail9414b.d(52): Error: variable `fail9414b.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414b.d(75): Error: variable `fail9414b.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414b.d(76): Error: variable `fail9414b.C.foo.__ensure.r` cannot modify result `r` in contract\nfail_compilation/fail9414b.d(60): Error: variable `fail9414b.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414b.d(61): Error: variable `fail9414b.C.foo.__ensure.r` cannot modify result `r` in contract\nfail_compilation/fail9414b.d(62): Error: variable `fail9414b.C.foo.__ensure.baz.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414b.d(67): Error: variable `fail9414b.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414b.d(68): Error: variable `fail9414b.C.foo.__ensure.r` cannot modify result `r` in contract\nfail_compilation/fail9414b.d(69): Error: variable `fail9414b.C.foo.__ensure.baz.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414b.d(70): Error: variable `fail9414b.C.foo.__ensure.baz.s` cannot modify result `s` in contract\nfail_compilation/fail9414b.d(81): Error: variable `fail9414b.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414b.d(82): Error: variable `fail9414b.C.foo.__ensure.r` cannot modify result `r` in contract\n---\n*/\n\nclass C\n{\n    final int foo(int x)\n    in\n    {\n        int a;\n        int bar(int y)\n        in\n        {\n            x = 10; // err\n            y = 10; // err\n            a = 1;  // OK\n        }\n        out(s)\n        {\n            x = 10; // err\n            y = 10; // err\n            s = 10; // err\n            a = 1;  // OK\n        }\n        body\n        {\n            x = 10; // err\n            y = 1;  // OK\n            a = 1;  // OK\n            return 2;\n        }\n        x = 10; // err\n    }\n    out(r)\n    {\n        int a;\n        int baz(int y)\n        in\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 10; // err\n            a = 1;  // OK\n        }\n        out(s)\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 10; // err\n            s = 10; // err\n            a = 1;  // OK\n        }\n        body\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 1;  // OK\n            a = 1;  // OK\n            return 2;\n        }\n        x = 10; // err\n        r = 10; // err\n    }\n    body\n    {\n        return 1;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9414c.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9414c.d(47): Error: variable `fail9414c.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414c.d(34): Error: variable `fail9414c.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414c.d(35): Error: variable `fail9414c.C.foo.bar.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414c.d(40): Error: variable `fail9414c.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414c.d(41): Error: variable `fail9414c.C.foo.bar.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414c.d(42): Error: variable `fail9414c.C.foo.bar.s` cannot modify result `s` in contract\nfail_compilation/fail9414c.d(52): Error: variable `fail9414c.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414c.d(75): Error: variable `fail9414c.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414c.d(76): Error: variable `fail9414c.C.foo.r` cannot modify result `r` in contract\nfail_compilation/fail9414c.d(60): Error: variable `fail9414c.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414c.d(61): Error: variable `fail9414c.C.foo.r` cannot modify result `r` in contract\nfail_compilation/fail9414c.d(62): Error: variable `fail9414c.C.foo.baz.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414c.d(67): Error: variable `fail9414c.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414c.d(68): Error: variable `fail9414c.C.foo.r` cannot modify result `r` in contract\nfail_compilation/fail9414c.d(69): Error: variable `fail9414c.C.foo.baz.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414c.d(70): Error: variable `fail9414c.C.foo.baz.s` cannot modify result `s` in contract\nfail_compilation/fail9414c.d(81): Error: variable `fail9414c.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414c.d(82): Error: variable `fail9414c.C.foo.r` cannot modify result `r` in contract\n---\n*/\n\nclass C\n{\n    private int foo(int x)\n    in\n    {\n        int a;\n        int bar(int y)\n        in\n        {\n            x = 10; // err\n            y = 10; // err\n            a = 1;  // OK\n        }\n        out(s)\n        {\n            x = 10; // err\n            y = 10; // err\n            s = 10; // err\n            a = 1;  // OK\n        }\n        body\n        {\n            x = 10; // err\n            y = 1;  // OK\n            a = 1;  // OK\n            return 2;\n        }\n        x = 10; // err\n    }\n    out(r)\n    {\n        int a;\n        int baz(int y)\n        in\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 10; // err\n            a = 1;  // OK\n        }\n        out(s)\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 10; // err\n            s = 10; // err\n            a = 1;  // OK\n        }\n        body\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 1;  // OK\n            a = 1;  // OK\n            return 2;\n        }\n        x = 10; // err\n        r = 10; // err\n    }\n    body\n    {\n        return 1;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9414d.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9414d.d(47): Error: variable `fail9414d.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414d.d(34): Error: variable `fail9414d.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414d.d(35): Error: variable `fail9414d.C.foo.bar.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414d.d(40): Error: variable `fail9414d.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414d.d(41): Error: variable `fail9414d.C.foo.bar.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414d.d(42): Error: variable `fail9414d.C.foo.bar.s` cannot modify result `s` in contract\nfail_compilation/fail9414d.d(52): Error: variable `fail9414d.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414d.d(75): Error: variable `fail9414d.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414d.d(76): Error: variable `fail9414d.C.foo.r` cannot modify result `r` in contract\nfail_compilation/fail9414d.d(60): Error: variable `fail9414d.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414d.d(61): Error: variable `fail9414d.C.foo.r` cannot modify result `r` in contract\nfail_compilation/fail9414d.d(62): Error: variable `fail9414d.C.foo.baz.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414d.d(67): Error: variable `fail9414d.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414d.d(68): Error: variable `fail9414d.C.foo.r` cannot modify result `r` in contract\nfail_compilation/fail9414d.d(69): Error: variable `fail9414d.C.foo.baz.y` cannot modify parameter `y` in contract\nfail_compilation/fail9414d.d(70): Error: variable `fail9414d.C.foo.baz.s` cannot modify result `s` in contract\nfail_compilation/fail9414d.d(81): Error: variable `fail9414d.C.foo.x` cannot modify parameter `x` in contract\nfail_compilation/fail9414d.d(82): Error: variable `fail9414d.C.foo.r` cannot modify result `r` in contract\n---\n*/\n\nclass C\n{\n    static int foo(int x)\n    in\n    {\n        int a;\n        int bar(int y)\n        in\n        {\n            x = 10; // err\n            y = 10; // err\n            a = 1;  // OK\n        }\n        out(s)\n        {\n            x = 10; // err\n            y = 10; // err\n            s = 10; // err\n            a = 1;  // OK\n        }\n        body\n        {\n            x = 10; // err\n            y = 1;  // OK\n            a = 1;  // OK\n            return 2;\n        }\n        x = 10; // err\n    }\n    out(r)\n    {\n        int a;\n        int baz(int y)\n        in\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 10; // err\n            a = 1;  // OK\n        }\n        out(s)\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 10; // err\n            s = 10; // err\n            a = 1;  // OK\n        }\n        body\n        {\n            x = 10; // err\n            r = 10; // err\n            y = 1;  // OK\n            a = 1;  // OK\n            return 2;\n        }\n        x = 10; // err\n        r = 10; // err\n    }\n    body\n    {\n        return 1;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail95.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail95.d(19): Error: template `fail95.A` cannot deduce function from argument types `!()(int)`, candidates are:\nfail_compilation/fail95.d(11):        `fail95.A(alias T)(T)`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=142\n// Assertion failure: '0' on line 610 in file 'template.c'\ntemplate A(alias T)\n{\n    void A(T) { T = 2; }\n}\n\nvoid main()\n{\n    int i;\n    A(i);\n    assert(i == 2);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9537.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9537.d(26): Error: `foo(tuple(1, 2))` is not an lvalue and cannot be modified\n---\n*/\n\nstruct Tuple(T...)\n{\n    T field;\n    alias field this;\n}\n\nTuple!T tuple(T...)(T args)\n{\n    return Tuple!T(args);\n}\n\nauto ref foo(T)(auto ref T t)\n{\n    return t[0];    // t[0] is deduced to non-ref\n}\n\nvoid main()\n{\n    int* p = &foo(tuple(1, 2));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9562.d",
    "content": "/*\nREQUIRED_ARGS: -o-\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/fail9562.d(17): Error: `int[]` is not an expression\nfail_compilation/fail9562.d(18): Error: no property `reverse` for type `int[]`\nfail_compilation/fail9562.d(19): Error: no property `sort` for type `int[]`\nfail_compilation/fail9562.d(20): Error: no property `dup` for type `int[]`\nfail_compilation/fail9562.d(21): Error: no property `idup` for type `int[]`\n---\n*/\n\nvoid main()\n{\n    alias A = int[];\n    auto len  = A.length;\n    auto rev  = A.reverse;\n    auto sort = A.sort;\n    auto dup  = A.dup;\n    auto idup = A.idup;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9572.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9572.d(10): Error: index type `ubyte` cannot cover index range 0..300\n---\n*/\n\nvoid main() {\n    int[300] data;\n    foreach (ubyte i, x; data) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail96.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail96.d(21): Error: template instance `foo!long` `foo` is not a template declaration, it is a function alias\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=153\n\ntemplate bar(T)\n{\n    void foo() {}\n}\n\nalias bar!(long).foo foo;\nalias bar!(char).foo foo;\n\n\nvoid main()\n{\n    foo!(long);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9613.d",
    "content": "// PREMUTE_ARGS:\n\nvoid main()\n{\n    auto x = const byte.init;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9665a.d",
    "content": "// REQUIRED_ARGS:\n// PERMUTE_ARGS:\n/+\nTEST_OUTPUT:\n---\nfail_compilation/fail9665a.d(45): Error: immutable field `v` initialized multiple times\nfail_compilation/fail9665a.d(44):        Previous initialization is here.\nfail_compilation/fail9665a.d(55): Error: immutable field `v` initialized multiple times\nfail_compilation/fail9665a.d(54):        Previous initialization is here.\nfail_compilation/fail9665a.d(60): Error: immutable field `v` initialized multiple times\nfail_compilation/fail9665a.d(59):        Previous initialization is here.\nfail_compilation/fail9665a.d(65): Error: immutable field `v` initialized multiple times\nfail_compilation/fail9665a.d(64):        Previous initialization is here.\nfail_compilation/fail9665a.d(75): Error: immutable field `v` initialized multiple times\nfail_compilation/fail9665a.d(74):        Previous initialization is here.\nfail_compilation/fail9665a.d(80): Error: immutable field `v` initialized multiple times\nfail_compilation/fail9665a.d(79):        Previous initialization is here.\nfail_compilation/fail9665a.d(85): Error: immutable field `v` initialized multiple times\nfail_compilation/fail9665a.d(84):        Previous initialization is here.\nfail_compilation/fail9665a.d(98): Error: immutable field `v` initialization is not allowed in loops or after labels\nfail_compilation/fail9665a.d(103): Error: immutable field `v` initialization is not allowed in loops or after labels\nfail_compilation/fail9665a.d(108): Error: immutable field `v` initialized multiple times\nfail_compilation/fail9665a.d(107):        Previous initialization is here.\nfail_compilation/fail9665a.d(113): Error: immutable field `v` initialized multiple times\nfail_compilation/fail9665a.d(112):        Previous initialization is here.\nfail_compilation/fail9665a.d(118): Error: immutable field `v` initialized multiple times\nfail_compilation/fail9665a.d(117):        Previous initialization is here.\nfail_compilation/fail9665a.d(132): Error: immutable field `v` initialized multiple times\nfail_compilation/fail9665a.d(131):        Previous initialization is here.\nfail_compilation/fail9665a.d(136): Error: immutable field `w` initialized multiple times\nfail_compilation/fail9665a.d(135):        Previous initialization is here.\nfail_compilation/fail9665a.d(150): Error: static assert:  `__traits(compiles, this.v = 1)` is false\n---\n+/\n\n/***************************************************/\n// immutable field\n\nstruct S1A\n{\n    immutable int v;\n    this(int)\n    {\n        v = 1;\n        v = 2;  // multiple initialization\n    }\n}\n\nstruct S1B\n{\n    immutable int v;\n    this(int)\n    {\n        if (true) v = 1; else v = 2;\n        v = 3;  // multiple initialization\n    }\n    this(long)\n    {\n        if (true) v = 1;\n        v = 3;  // multiple initialization\n    }\n    this(string)\n    {\n        if (true) {} else v = 2;\n        v = 3;  // multiple initialization\n    }\n}\n\nstruct S1C\n{\n    immutable int v;\n    this(int)\n    {\n        true ? (v = 1) : (v = 2);\n        v = 3;  // multiple initialization\n    }\n    this(long)\n    {\n        auto x = true ? (v = 1) : 2;\n        v = 3;  // multiple initialization\n    }\n    this(string)\n    {\n        auto x = true ? 1 : (v = 2);\n        v = 3;  // multiple initialization\n    }\n}\n\n/***************************************************/\n// with control flow\n\nstruct S2\n{\n    immutable int v;\n    this(int)\n    {\n    L:\n        v = 1;  // after labels\n    }\n    this(long)\n    {\n        foreach (i; 0..1)\n            v = 1;  // in loops\n    }\n    this(string)\n    {\n        v = 1;  // initialization\n    L:  v = 2;  // assignment after labels\n    }\n    this(wstring)\n    {\n        v = 1;  // initialization\n        foreach (i; 0..1) v = 2;  // assignment in loops\n    }\n    this(dstring)\n    {\n        v = 1; return;\n        v = 2;  // multiple initialization\n    }\n}\n\n/***************************************************/\n// with immutable constructor\n\nstruct S3\n{\n    int v;\n    int w;\n    this(int) immutable\n    {\n        v = 1;\n        v = 2;  // multiple initialization\n\n        if (true)\n            w = 1;\n        w = 2;  // multiple initialization\n    }\n}\n\n/***************************************************/\n// in __traits(compiles)\n\nstruct S4\n{\n    immutable int v;\n    this(int)\n    {\n        static assert(__traits(compiles, v = 1));\n        v = 1;\n        static assert(__traits(compiles, v = 1)); // multiple initialization\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9665b.d",
    "content": "/***************************************************/\n// with disable this() struct\n\nstruct X\n{\n    @disable this();\n\n    this(int) {}\n}\n\n/+\nTEST_OUTPUT:\n---\nfail_compilation/fail9665b.d(32): Error: one path skips field `x2`\nfail_compilation/fail9665b.d(33): Error: one path skips field `x3`\nfail_compilation/fail9665b.d(35): Error: one path skips field `x5`\nfail_compilation/fail9665b.d(36): Error: one path skips field `x6`\nfail_compilation/fail9665b.d(30): Error: field `x1` must be initialized in constructor\nfail_compilation/fail9665b.d(30): Error: field `x4` must be initialized in constructor\n---\n+/\nstruct S1\n{\n    X x1;\n    X x2;\n    X x3;\n    X[2] x4;\n    X[2] x5;\n    X[2] x6;\n    this(int)\n    {\n        if (true) x2 = X(1);\n        auto n = true ? (x3 = X(1)) : X.init;\n\n        if (true) x5 = X(1);\n        auto m = true ? (x6 = X(1)) : typeof(x6).init;\n    }\n}\n\n/***************************************************/\n// with nested struct\n\n/+\nTEST_OUTPUT:\n---\nfail_compilation/fail9665b.d(65): Error: one path skips field `x2`\nfail_compilation/fail9665b.d(66): Error: one path skips field `x3`\nfail_compilation/fail9665b.d(68): Error: one path skips field `x5`\nfail_compilation/fail9665b.d(69): Error: one path skips field `x6`\nfail_compilation/fail9665b.d(63): Error: field `x1` must be initialized in constructor, because it is nested struct\nfail_compilation/fail9665b.d(63): Error: field `x4` must be initialized in constructor, because it is nested struct\nfail_compilation/fail9665b.d(76): Error: template instance `fail9665b.S2!(X)` error instantiating\n---\n+/\nstruct S2(X)\n{\n    X x1;\n    X x2;\n    X x3;\n    X[2] x4;\n    X[2] x5;\n    X[2] x6;\n    this(X x)\n    {\n        if (true) x2 = x;\n        auto a = true ? (x3 = x) : X.init;\n\n        if (true) x5 = x;\n        auto b = true ? (x6 = x) : typeof(x6).init;\n    }\n}\nvoid test2()\n{\n    struct X { this(int) {} }\n    static assert(X.tupleof.length == 1);\n    S2!(X) s = X(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail97.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail97.d(11): Error: pragma `lib` is missing a terminating `;`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=151\n\nimport std.stdio;\npragma(lib,\"ws2_32.lib\")//;\nclass bla{}\nvoid main(){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9710.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9710.d(9): Error: static variable `e` cannot be read at compile time\n---\n*/\n\nint* e;\nenum v = e[1];\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9735.d",
    "content": "/*\nREQUIRED_ARGS: -de\nTEST_OUTPUT:\n---\nfail_compilation/fail9735.d(10): Deprecation: casting from void delegate() to void* is deprecated\n---\n*/\n\nvoid* dg2ptr(void delegate() dg) {\n    return cast(void*) dg;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9766.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9766.d(14): Error: cannot interpret `Foo!int` at compile time\nfail_compilation/fail9766.d(17): Error: alignment must be an integer positive power of 2, not -1\nfail_compilation/fail9766.d(20): Error: alignment must be an integer positive power of 2, not 0\nfail_compilation/fail9766.d(23): Error: alignment must be an integer positive power of 2, not 3\nfail_compilation/fail9766.d(26): Error: alignment must be an integer positive power of 2, not 2147483649u\n---\n*/\n\ntemplate Foo(T) {}\n\nalign(Foo!int)\nstruct S9766a {}\n\nalign(-1)\nstruct S9766b {}\n\nalign(0)\nstruct S9766c {}\n\nalign(3)\nstruct S9766d {}\n\nalign((1u << 31) + 1)\nstruct S9766e {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9773.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9773.d(7): Error: `\"\"` is not an lvalue and cannot be modified\n---\n*/\nvoid f(ref string a = \"\")\n{\n    a = \"crash and burn\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9790.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9790.d(13): Error: undefined identifier `_Unused_`\nfail_compilation/fail9790.d(20): Error: template instance `fail9790.foo!()` error instantiating\nfail_compilation/fail9790.d(18): Error: undefined identifier `_Unused_`\nfail_compilation/fail9790.d(21): Error: template instance `fail9790.bar!()` error instantiating\n---\n*/\n\ntemplate foo()\n{\n    enum bool _foo = _Unused_._unused_;\n    enum bool foo = _foo;\n}\ntemplate bar()\n{\n    enum bool bar = _Unused_._unused_;\n}\nalias Foo = foo!();\nalias Bar = bar!();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail98.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail98.d(17): Error: cannot implicitly convert expression `256` of type `int` to `E`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=139\n\nE foo(int index)\n{\n    return index + 256;\n}\n\nenum : E\n{\n    D3DTS_WORLD = 256,\n    D3DTS_WORLD1,\n    D3DTS_WORLD2,\n    D3DTS_WORLD3\n}\n\nenum E\n{\n    D3DTS_VIEW         =  2,\n    D3DTS_PROJECTION,\n    D3DTS_TEXTURE0     = 16,\n    D3DTS_TEXTURE1,\n    D3DTS_TEXTURE2,\n    D3DTS_TEXTURE3,\n    D3DTS_TEXTURE4,\n    D3DTS_TEXTURE5,\n    D3DTS_TEXTURE6,\n    D3DTS_TEXTURE7, // = 23\n    D3DTS_FORCE_DWORD  = 0xffffffff\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9891.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9891.d(13): Error: `cast(int)i` is not an lvalue and cannot be modified\nfail_compilation/fail9891.d(18): Error: `cast(int)i` is not an lvalue and cannot be modified\nfail_compilation/fail9891.d(23): Error: `prop()` is not an lvalue and cannot be modified\n---\n*/\n\nimmutable int i;\nint prop() { return 0; }\n\nvoid f1(ref int n = i)\n{\n    ++n;\n}\n\nvoid f2(out int n = i)\n{\n    ++n;\n}\n\nvoid f3(ref int n = prop)\n{\n    ++n;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9892.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=9892\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9892.d(11): Error: enum member `fail9892.a` circular reference to `enum` member\n---\n*/\n\nenum\n{\n    a = b, //Segfault!\n    b\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail99.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail99.d(12): Error: delegate `dg(int)` is not callable using argument types `()`\n---\n*/\n\n//import std.stdio;\n\nvoid foo(void delegate(int) dg)\n{\n    dg();\n    //writefln(\"%s\", dg(3));\n}\n\nvoid main()\n{\n    foo(delegate(int i)\n        {\n            //writefln(\"i = %d\\n\", i);\n        }\n       );\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail9936.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail9936.d(25): Error: `S().opBinary` isn't a template\nfail_compilation/fail9936.d(26): Error: `S().opBinaryRight` isn't a template\nfail_compilation/fail9936.d(27): Error: `S().opOpAssign` isn't a template\nfail_compilation/fail9936.d(29): Error: `S().opIndexUnary` isn't a template\nfail_compilation/fail9936.d(30): Error: `S().opUnary` isn't a template\n---\n*/\nstruct S\n{\n    auto opBinary(S s) { return 1; }\n    auto opBinaryRight(int n) { return 1; }\n    auto opOpAssign(S s) { return 1; }\n\n    auto opIndexUnary(S s) { return 1; }\n    auto opUnary(S s) { return 1; }\n}\nvoid main()\n{\n    static assert(!is(typeof( S() + S() )));\n    static assert(!is(typeof( 100 + S() )));\n    static assert(!is(typeof( S() += S() )));\n    S() + S();\n    100 + S();\n    S() += S();\n\n    +S()[0];\n    +S();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_arrayop1.d",
    "content": "// REQUIRED_ARGS: -o-\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop1.d(11): Error: invalid array operation `a + a` (possible missing [])\n---\n*/\nvoid test2199(int[] a)  // https://issues.dlang.org/show_bug.cgi?id=2199 - Segfault using array operation in function call (from fail266.d)\n{\n    test2199(a + a);\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop1.d(29): Error: invalid array operation `-a` (possible missing [])\n---\n*/\nvoid fail323()      // from fail323.d, maybe was a part of https://issues.dlang.org/show_bug.cgi?id=3471 fix?\n{\n    void foo(double[]) {}\n\n    auto a = new double[10],\n         b = a.dup,\n         c = a.dup,\n         d = a.dup;\n\n    foo(-a);\n    // a[] = -(b[] * (c[] + 4)) + 5 * d[]; // / 3;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop1.d(54): Error: invalid array operation `-a` (possible missing [])\nfail_compilation/fail_arrayop1.d(55): Error: invalid array operation `~a` (possible missing [])\nfail_compilation/fail_arrayop1.d(56): Error: invalid array operation `a + a` (possible missing [])\nfail_compilation/fail_arrayop1.d(57): Error: invalid array operation `a - a` (possible missing [])\nfail_compilation/fail_arrayop1.d(58): Error: invalid array operation `a * a` (possible missing [])\nfail_compilation/fail_arrayop1.d(59): Error: invalid array operation `a / a` (possible missing [])\nfail_compilation/fail_arrayop1.d(60): Error: invalid array operation `a % a` (possible missing [])\nfail_compilation/fail_arrayop1.d(61): Error: invalid array operation `a ^^ a` (possible missing [])\nfail_compilation/fail_arrayop1.d(62): Error: invalid array operation `a & a` (possible missing [])\nfail_compilation/fail_arrayop1.d(63): Error: invalid array operation `a | a` (possible missing [])\nfail_compilation/fail_arrayop1.d(64): Error: invalid array operation `a ^ a` (possible missing [])\n---\n*/\nvoid test3903()\n{\n    int[] a = [1, 2];\n    int[] r;\n\n    r = -a;\n    r = ~a;\n    r = a + a;\n    r = a - a;\n    r = a * a;\n    r = a / a;\n    r = a % a;\n    r = a ^^ a;\n    r = a & a;\n    r = a | a;\n    r = a ^ a;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop1.d(85): Error: invalid array operation `a += a[]` (possible missing [])\nfail_compilation/fail_arrayop1.d(86): Error: invalid array operation `a -= a[]` (possible missing [])\nfail_compilation/fail_arrayop1.d(87): Error: invalid array operation `a *= a[]` (possible missing [])\nfail_compilation/fail_arrayop1.d(88): Error: invalid array operation `a /= a[]` (possible missing [])\nfail_compilation/fail_arrayop1.d(89): Error: invalid array operation `a %= a[]` (possible missing [])\nfail_compilation/fail_arrayop1.d(90): Error: invalid array operation `a ^= a[]` (possible missing [])\nfail_compilation/fail_arrayop1.d(91): Error: invalid array operation `a &= a[]` (possible missing [])\nfail_compilation/fail_arrayop1.d(92): Error: invalid array operation `a |= a[]` (possible missing [])\nfail_compilation/fail_arrayop1.d(93): Error: invalid array operation `a ^^= a[]` (possible missing [])\n---\n*/\nvoid test9459()\n{\n    int[] a = [1, 2, 3];\n\n    a += a[];\n    a -= a[];\n    a *= a[];\n    a /= a[];\n    a %= a[];\n    a ^= a[];\n    a &= a[];\n    a |= a[];\n    a ^^= a[];\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop1.d(105): Error: invalid array operation `a[] <<= 1` (possible missing [])\n---\n*/\nvoid test11566()\n{\n    int[] a;\n    a[] <<= 1;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop1.d(121): Error: invalid array operation `a + b` (possible missing [])\nfail_compilation/fail_arrayop1.d(122): Error: invalid array operation `x + y` (possible missing [])\nfail_compilation/fail_arrayop1.d(123): Error: invalid array operation `\"hel\" + \"lo.\"` (possible missing [])\n---\n*/\nvoid test14649()\n{\n    char[] a, b, r;\n    string x, y;\n\n    r[] = a + b;\n    r[] = x + y;\n    r[] = \"hel\" + \"lo.\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d",
    "content": "// REQUIRED_ARGS: -o-\n\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop2.d(13): Error: array operation `[1, 2, 3] - [1, 2, 3]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(16): Error: invalid array operation `\"a\" - \"b\"` (possible missing [])\n---\n*/\nvoid test2603() // https://issues.dlang.org/show_bug.cgi?id=2603 - ICE(cgcs.c) on subtracting string literals\n{\n    auto c1 = [1,2,3] - [1,2,3];\n\n    // this variation is wrong code on D2, ICE ..\\ztc\\cgcs.c 358 on D1.\n    string c2 = \"a\" - \"b\";\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop2.d(38): Error: array operation `-a[]` without destination memory not allowed (possible missing [])\nfail_compilation/fail_arrayop2.d(39): Error: array operation `~a[]` without destination memory not allowed (possible missing [])\nfail_compilation/fail_arrayop2.d(41): Error: array operation `a[] + a[]` without destination memory not allowed (possible missing [])\nfail_compilation/fail_arrayop2.d(42): Error: array operation `a[] - a[]` without destination memory not allowed (possible missing [])\nfail_compilation/fail_arrayop2.d(43): Error: array operation `a[] * a[]` without destination memory not allowed (possible missing [])\nfail_compilation/fail_arrayop2.d(44): Error: array operation `a[] / a[]` without destination memory not allowed (possible missing [])\nfail_compilation/fail_arrayop2.d(45): Error: array operation `a[] % a[]` without destination memory not allowed (possible missing [])\nfail_compilation/fail_arrayop2.d(46): Error: array operation `a[] ^ a[]` without destination memory not allowed (possible missing [])\nfail_compilation/fail_arrayop2.d(47): Error: array operation `a[] & a[]` without destination memory not allowed (possible missing [])\nfail_compilation/fail_arrayop2.d(48): Error: array operation `a[] | a[]` without destination memory not allowed (possible missing [])\nfail_compilation/fail_arrayop2.d(49): Error: array operation `a[] ^^ a[]` without destination memory not allowed (possible missing [])\n---\n*/\nvoid test9459()\n{\n    int[] a = [1, 2, 3];\n    a = -a[];\n    a = ~a[];\n\n    a = a[] + a[];\n    a = a[] - a[];\n    a = a[] * a[];\n    a = a[] / a[];\n    a = a[] % a[];\n    a = a[] ^ a[];\n    a = a[] & a[];\n    a = a[] | a[];\n    a = a[] ^^ a[];\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop2.d(75): Error: array operation `a[] + a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(76): Error: array operation `a[] - a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(77): Error: array operation `a[] * a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(78): Error: array operation `a[] / a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(79): Error: array operation `a[] % a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(80): Error: array operation `a[] ^ a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(81): Error: array operation `a[] & a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(82): Error: array operation `a[] | a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(83): Error: array operation `a[] ^^ 10` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(84): Error: array operation `-a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(85): Error: array operation `~a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(90): Error: array operation `[1] + a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(91): Error: array operation `[1] + a[]` without destination memory not allowed\n---\n*/\nvoid test12179()\n{\n    void foo(int[]) {}\n    int[1] a;\n\n    foo(a[] + a[]);\n    foo(a[] - a[]);\n    foo(a[] * a[]);\n    foo(a[] / a[]);\n    foo(a[] % a[]);\n    foo(a[] ^ a[]);\n    foo(a[] & a[]);\n    foo(a[] | a[]);\n    foo(a[] ^^ 10);\n    foo(-a[]);\n    foo(~a[]);\n\n    // from https://issues.dlang.org/show_bug.cgi?id=11992\n    int[]   arr1;\n    int[][] arr2;\n    arr1 ~= [1] + a[];         // NG\n    arr2 ~= [1] + a[];         // NG\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop2.d(105): Error: array operation `h * y[]` without destination memory not allowed\n---\n*/\nvoid test12381()\n{\n    double[2] y;\n    double h;\n\n    double[2] temp1 = cast(double[2])(h * y[]);\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop2.d(118): Error: array operation `-a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(120): Error: array operation `(-a[])[0..4]` without destination memory not allowed\n---\n*/\nfloat[] test12769(float[] a)\n{\n    if (a.length < 4)\n        return -a[];\n    else\n        return (-a[])[0..4];\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop2.d(137): Error: array operation `a[] - a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(139): Error: array operation `a[] - a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(140): Error: array operation `a[] - a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(143): Error: array operation `a[] - a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(145): Error: array operation `a[] - a[]` without destination memory not allowed\n---\n*/\nvoid test13208()\n{\n    int[] a;\n\n    auto arr = [a[] - a[]][0];\n\n    auto aa1 = [1 : a[] - a[]];\n    auto aa2 = [a[] - a[] : 1];\n\n    struct S { int[] a; }\n    auto s = S(a[] - a[]);\n\n    auto n = int(a[] - a[]);\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop2.d(160): Error: array operation `a[] * a[]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(161): Error: array operation `(a[] * a[])[0..1]` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(164): Error: array operation `a[] * a[]` without destination memory not allowed (possible missing [])\nfail_compilation/fail_arrayop2.d(165): Error: array operation `(a[] * a[])[0..1]` without destination memory not allowed (possible missing [])\n---\n*/\nvoid test13497()\n{\n    int[1] a;\n    auto b1 = (a[] * a[])[];\n    auto b2 = (a[] * a[])[0..1];\n\n    int[] c;\n    c = (a[] * a[])[];\n    c = (a[] * a[])[0..1];\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop2.d(181): Error: array operation `data[segmentId][28..29] & cast(ubyte)(1 << 0)` without destination memory not allowed\n---\n*/\nvoid test13910()\n{\n    ubyte[][] data;\n    size_t segmentId;\n\n    bool isGroup()\n    {\n        return !!((data[segmentId][28..29]) & (1 << 0));\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop2.d(195): Error: array operation `a[] + 1` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(195): Error: array operation `a[] * 2` without destination memory not allowed\n---\n*/\nvoid test14895()\n{\n    int[] a;\n    int[] b = (a[] + 1) ~ a[] * 2;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop2.d(247): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(248): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(249): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(253): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(256): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(265): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(268): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(269): Error: array operation `\"abc\"[] + '\\x01'` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(272): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(275): Error: `([1] * 6)[0..2]` is not an lvalue and cannot be modified\nfail_compilation/fail_arrayop2.d(278): Error: can only `*` a pointer, not a `int[]`\nfail_compilation/fail_arrayop2.d(281): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/fail_arrayop2.d(281): Error: `[1] * 6` is not an lvalue and cannot be modified\nfail_compilation/fail_arrayop2.d(284): Error: array operation `da[] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(287): Error: array operation `da[] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(290): Error: `[1] * 6` is not an lvalue and cannot be modified\nfail_compilation/fail_arrayop2.d(291): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(294): Error: `[1] * 6` is not an lvalue and cannot be modified\nfail_compilation/fail_arrayop2.d(295): Error: `([1] * 6)[]` is not an lvalue and cannot be modified\nfail_compilation/fail_arrayop2.d(298): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(299): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(300): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(303): Error: `[1] * 6` is not an lvalue and cannot be modified\nfail_compilation/fail_arrayop2.d(304): Error: `[1] * 6` is not an lvalue and cannot be modified\nfail_compilation/fail_arrayop2.d(307): Error: `[1] * 6` is not of integral type, it is a `int[]`\nfail_compilation/fail_arrayop2.d(308): Error: `[1] * 6` is not of integral type, it is a `int[]`\nfail_compilation/fail_arrayop2.d(309): Error: `[1] * 6` is not of integral type, it is a `int[]`\nfail_compilation/fail_arrayop2.d(312): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(313): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(316): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(317): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(318): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(321): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(321): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(321): Error: array operation `[1] * 6` without destination memory not allowed\n---\n*/\n// Test all expressions, which can take arrays as their operands but cannot be a part of array operation.\nvoid test15407exp()\n{\n    struct S { int[] a; }\n    void f(int[] a) {}\n\n    int[] da;\n    int[6] sa;\n\n    { auto r = [[1] * 6]; }     // ArrayLiteralExp\n    { auto r = [[1] * 6 :\n                [1] * 6]; }     // AssocArrayLiteralExp\n\n    //TupleExp\n    // StructLiteralExp.elements <- preFunctionParameters in CallExp\n    { auto r = S([1] * 6); }\n\n    // NewExp.newargs/arguments <- preFunctionParameters\n    { auto r = new S([1] * 6); }\n\n    // TODO: TypeidExp\n    //auto ti = typeid([1] * 6);\n    //auto foo(T)(T t) {}\n    //foo(typeid([1] * 6));\n    //auto a = [typeid([1] * 6)];\n\n    // CommaExp.e1\n    { auto r = ([1] * 6, 1); }\n\n    // AssertExp\n    assert([1] * 6,\n           cast(char)1 + \"abc\"[]);\n\n    // CallExp.arguments <- preFunctionParameters\n    f([1] * 6);\n\n    // AddrExp, if a CT-known length slice can become an TypeSarray lvalue in the future.\n    { auto r = &(([1] * 6)[0..2]); }\n\n    // PtrExp, *([1] * 6).ptr is also invalid -> show better diagnostic\n    { auto r = *([1] * 6); }\n\n    // DeleteExp - e1\n    delete ([1] * 6);\n\n    // TypeDArray.dotExp, cannot check in ArrayLengthExp.semantic()\n    { auto r = (6 * da[]).length; }\n\n    // IndexExp - e1\n    { auto x1 = (da[] * 6)[1]; }\n\n    // Pre, PostExp - e1\n    ([1] * 6)++;\n    --([1] * 6);\n\n    // AssignExp e1\n    ([1] * 6) = 10;\n    ([1] * 6)[] = 10;\n\n    // BinAssignExp e1\n    ([1] * 6) += 1;\n    ([1] * 6)[] *= 2;\n    ([1] * 6)[] ^^= 3;\n\n    // CatExp e1\n    ([1] * 6) ~= 1;\n    ([1] * 6)[] ~= 2;\n\n    // Shl, Shr, UshrExp - e1, e2 --> checkIntegralBin\n    { auto r = ([1] * 6) << 1; }\n    { auto r = ([1] * 6) >> 1; }\n    { auto r = ([1] * 6) >>> 1; }\n\n    // AndAnd, OrOrExp - e1, e2\n    { auto r = sa[0..5] && [1] * 6; }\n    { auto r = sa[0..5] || [1] * 6; }\n\n    // Cmp, Equal, IdentityExp - e1, e2\n    { auto r = sa[0..5] <= [1] * 6; }\n    { auto r = sa[0..5] == [1] * 6; }\n    { auto r = sa[0..5] is [1] * 6; }\n\n    // CondExp - econd, e1, e2\n    { auto r = [1] * 6 ? [1] * 6 : [1] * 6; }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_arrayop2.d(342): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(345): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(348): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(349): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(350): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(353): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(356): Error: array operation `[1] * 6` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(359): Error: array operation `\"str\"[] + cast(immutable(char))1` without destination memory not allowed\nfail_compilation/fail_arrayop2.d(367): Error: CTFE internal error: non-constant value `\"uvt\"[]`\n---\n*/\n// Test all statements, which can take arrays as their operands.\nvoid test15407stmt()\n{\n    // ExpStatement - exp\n    [1] * 6;\n\n    // DoStatement - condition\n    do {} while ([1] * 6);\n\n    // ForStatement - condition, increment\n    for ([1] * 6;       // init == ExpStatement\n         [1] * 6;\n         [1] * 6) {}\n\n    // ForeachStatement - aggr -> lowered to ForStatement\n    foreach (e; [1] * 6) {}\n\n    // IfStatement condition\n    if ([1] * 6) {}\n\n    // SwitchStatement - condition\n    switch (\"str\"[] + 1)\n    {\n        case \"tus\":         break;\n        default:            break;\n    }\n    // CaseStatement - exp\n    switch (\"tus\")\n    {\n        case \"uvt\"[] - 1:   break;\n        default:            break;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_arrayop3a.d",
    "content": "// REQUIRED_ARGS: -o-\n\n/*\nexample output from druntime\n----\n../../druntime/import/core/internal/arrayop.d(160): Error: static assert  \"Binary op `*` not supported for element type X.\"\n../../druntime/import/core/internal/arrayop.d(145):        instantiated from here: `opsSupported!(true, X, \"*\")`\n../../druntime/import/core/internal/arrayop.d(20):        instantiated from here: `opsSupported!(true, X, \"*\", \"=\")`\n../../druntime/import/object.d(3640):        instantiated from here: `arrayOp!(X[], X[], X[], \"*\", \"=\")`\nfail_compilation/fail_arrayop3a.d(28):        instantiated from here: `_arrayOp!(X[], X[], X[], \"*\", \"=\")`\n../../druntime/import/core/internal/arrayop.d(160): Error: static assert  \"Binary op `+=` not supported for element type string.\"\n../../druntime/import/core/internal/arrayop.d(20):        instantiated from here: `opsSupported!(true, string, \"+=\")`\n../../druntime/import/object.d(3640):        instantiated from here: `arrayOp!(string[], string[], \"+=\")`\nfail_compilation/fail_arrayop3a.d(32):        instantiated from here: `_arrayOp!(string[], string[], \"+=\")`\n../../druntime/import/core/internal/arrayop.d(160): Error: static assert  \"Binary op `*=` not supported for element type int*.\"\n../../druntime/import/core/internal/arrayop.d(20):        instantiated from here: `opsSupported!(true, int*, \"*=\")`\n../../druntime/import/object.d(3640):        instantiated from here: `arrayOp!(int*[], int*[], \"*=\")`\nfail_compilation/fail_arrayop3a.d(36):        instantiated from here: `_arrayOp!(int*[], int*[], \"*=\")`\n----\n*/\nvoid test11376()\n{\n    struct X { }\n\n    auto x1 = [X()];\n    auto x2 = [X()];\n    auto x3 = [X()];\n    x1[] = x2[] * x3[];\n\n    string[] s1;\n    string[] s2;\n    s2[] += s1[];\n\n    int*[] pa1;\n    int*[] pa2;\n    pa1[] *= pa2[];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_arrayop3b.d",
    "content": "// REQUIRED_ARGS: -o-\n\n/*\nexample output from druntime\n----\n../../druntime/import/core/internal/arrayop.d(160): Error: static assert  \"Binary op `+=` not supported for element type string.\"\n../../druntime/import/core/internal/arrayop.d(20):        instantiated from here: `opsSupported!(true, string, \"+=\")`\n../../druntime/import/object.d(3640):        instantiated from here: `arrayOp!(string[], string[], \"+=\")`\nfail_compilation/fail_arrayop3b.d(16):        instantiated from here: `_arrayOp!(string[], string[], \"+=\")`\n---\n*/\nvoid test11376()\n{\n    string[] s1;\n    string[] s2;\n    s2[] += s1[];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_arrayop3c.d",
    "content": "// REQUIRED_ARGS: -o-\n\n/*\nexample output from druntime\n----\n../../druntime/import/core/internal/arrayop.d(160): Error: static assert  \"Binary op `*=` not supported for element type int*.\"\n../../druntime/import/core/internal/arrayop.d(20):        instantiated from here: `opsSupported!(true, int*, \"*=\")``\n../../druntime/import/object.d(3640):        instantiated from here: `arrayOp!(int*[], int*[], \"*=\")`\nfail_compilation/fail_arrayop3c.d(16):        instantiated from here: `_arrayOp!(int*[], int*[], \"*=\")`\n----\n*/\nvoid test11376()\n{\n    int*[] pa1;\n    int*[] pa2;\n    pa1[] *= pa2[];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_casting.d",
    "content": "// REQUIRED_ARGS: -o-\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting.d(12): Error: cannot cast expression `x` of type `short[2]` to `int[2]` because of different sizes\n---\n*/\nvoid test3133()\n{\n    short[2] x = [1, 2];\n    auto y = cast(int[2])x;     // error\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting.d(28): Error: cannot cast expression `null` of type `typeof(null)` to `S1`\nfail_compilation/fail_casting.d(29): Error: cannot cast expression `null` of type `typeof(null)` to `S2`\nfail_compilation/fail_casting.d(30): Error: cannot cast expression `s1` of type `S1` to `typeof(null)`\nfail_compilation/fail_casting.d(31): Error: cannot cast expression `s2` of type `S2` to `typeof(null)`\n---\n*/\nvoid test9904()\n{\n    static struct S1 { size_t m; }\n    static struct S2 { size_t m; byte b; }\n    { auto x = cast(S1)null; }\n    { auto x = cast(S2)null; }\n    { S1 s1; auto x = cast(typeof(null))s1; }\n    { S2 s2; auto x = cast(typeof(null))s2; }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting.d(46): Error: cannot cast expression `x` of type `Object[]` to `object.Object`\nfail_compilation/fail_casting.d(47): Error: cannot cast expression `x` of type `Object[2]` to `object.Object`\nfail_compilation/fail_casting.d(49): Error: cannot cast expression `x` of type `object.Object` to `Object[]`\nfail_compilation/fail_casting.d(50): Error: cannot cast expression `x` of type `object.Object` to `Object[2]`\n---\n*/\nvoid test10646()\n{\n    // T[] or T[n] --> Tclass\n    { Object[]  x; auto y = cast(Object)x; }\n    { Object[2] x; auto y = cast(Object)x; }\n    // T[] or T[n] <-- Tclass\n    { Object x; auto y = cast(Object[] )x; }\n    { Object x; auto y = cast(Object[2])x; }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting.d(69): Error: cannot cast expression `x` of type `int[1]` to `int`\nfail_compilation/fail_casting.d(70): Error: cannot cast expression `x` of type `int` to `int[1]`\nfail_compilation/fail_casting.d(71): Error: cannot cast expression `x` of type `float[1]` to `int`\nfail_compilation/fail_casting.d(72): Error: cannot cast expression `x` of type `int` to `float[1]`\nfail_compilation/fail_casting.d(75): Error: cannot cast expression `x` of type `int[]` to `int`\nfail_compilation/fail_casting.d(76): Error: cannot cast expression `x` of type `int` to `int[]`\nfail_compilation/fail_casting.d(77): Error: cannot cast expression `x` of type `float[]` to `int`\nfail_compilation/fail_casting.d(78): Error: cannot cast expression `x` of type `int` to `float[]`\n---\n*/\nvoid test11484()\n{\n    // Tsarray <--> integer\n    { int[1]   x; auto y = cast(int     ) x; }\n    { int      x; auto y = cast(int[1]  ) x; }\n    { float[1] x; auto y = cast(int     ) x; }\n    { int      x; auto y = cast(float[1]) x; }\n\n    // Tarray <--> integer\n    { int[]   x; auto y = cast(int    ) x; }\n    { int     x; auto y = cast(int[]  ) x; }\n    { float[] x; auto y = cast(int    ) x; }\n    { int     x; auto y = cast(float[]) x; }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting.d(97): Error: cannot cast expression `x` of type `int` to `fail_casting.test11485.C`\nfail_compilation/fail_casting.d(98): Error: cannot cast expression `x` of type `int` to `fail_casting.test11485.I`\nfail_compilation/fail_casting.d(101): Error: cannot cast expression `x` of type `fail_casting.test11485.C` to `int`\nfail_compilation/fail_casting.d(102): Error: cannot cast expression `x` of type `fail_casting.test11485.I` to `int`\n---\n*/\n\nvoid test11485()\n{\n    class C {}\n    interface I {}\n\n    // https://issues.dlang.org/show_bug.cgi?id=11485 TypeBasic --> Tclass\n    { int x; auto y = cast(C)x; }\n    { int x; auto y = cast(I)x; }\n\n    // https://issues.dlang.org/show_bug.cgi?id=7472 TypeBasic <-- Tclass\n    { C x; auto y = cast(int)x; }\n    { I x; auto y = cast(int)x; }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting.d(114): Error: cannot cast expression `x` of type `typeof(null)` to `int[2]`\nfail_compilation/fail_casting.d(115): Error: cannot cast expression `x` of type `int[2]` to `typeof(null)`\n---\n*/\nvoid test8179()\n{\n    { typeof(null) x; auto y = cast(int[2])x; }\n    { int[2] x;       auto y = cast(typeof(null))x; }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting.d(128): Error: cannot cast expression `x` of type `S` to `int*`\nfail_compilation/fail_casting.d(130): Error: cannot cast expression `x` of type `void*` to `S`\n---\n*/\nvoid test13959()\n{\n    struct S { int* p; }\n    { S     x; auto y = cast(int*)x; }\n    { int*  x; auto y = cast(S)x; }     // no error so it's rewritten as: S(x)\n    { void* x; auto y = cast(S)x; }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting.d(144): Error: cannot cast expression `mi.x` of type `int` to `MyUbyte14154`\n---\n*/\nstruct MyUbyte14154 { ubyte x; alias x this; }\nstruct MyInt14154   {   int x; alias x this; }\nvoid test14154()\n{\n    MyInt14154 mi;\n    ubyte t = cast(MyUbyte14154)mi;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting.d(179): Error: cannot cast expression `__tup$n$.__expand_field_0` of type `int` to `object.Object`\nfail_compilation/fail_casting.d(179): Error: cannot cast expression `__tup$n$.__expand_field_1` of type `int` to `object.Object`\n---\n*/\nalias TypeTuple14093(T...) = T;\nstruct Tuple14093(T...)\n{\n    static if (T.length == 4)\n    {\n        alias Types = TypeTuple14093!(T[0], T[2]);\n\n        Types expand;\n\n        @property ref inout(Tuple14093!Types) _Tuple_super() inout @trusted\n        {\n            return *cast(typeof(return)*) &(expand[0]);\n        }\n        alias _Tuple_super this;\n    }\n    else\n    {\n        alias Types = T;\n        Types expand;\n        alias expand this;\n    }\n}\nvoid test14093()\n{\n    Tuple14093!(int, \"x\", int, \"y\") point;\n    auto newPoint = cast(Object)(point);\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting.d(192): Error: cannot cast expression `p` of type `void*` to `char[]`\nfail_compilation/fail_casting.d(193): Error: cannot cast expression `p` of type `void*` to `char[2]`\n---\n*/\nvoid test14596()\n{\n    void* p = null;\n    auto arr = cast(char[])p;\n    char[2] sarr = cast(char[2])p;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting.d(217): Error: cannot cast expression `c` of type `fail_casting.test14629.C` to `typeof(null)`\nfail_compilation/fail_casting.d(218): Error: cannot cast expression `p` of type `int*` to `typeof(null)`\nfail_compilation/fail_casting.d(219): Error: cannot cast expression `da` of type `int[]` to `typeof(null)`\nfail_compilation/fail_casting.d(220): Error: cannot cast expression `aa` of type `int[int]` to `typeof(null)`\nfail_compilation/fail_casting.d(221): Error: cannot cast expression `fp` of type `int function()` to `typeof(null)`\nfail_compilation/fail_casting.d(222): Error: cannot cast expression `dg` of type `int delegate()` to `typeof(null)`\n---\n*/\nvoid test14629()\n{\n    alias P = int*;             P p;\n    alias DA = int[];           DA da;\n    alias AA = int[int];        AA aa;\n    alias FP = int function();  FP fp;\n    alias DG = int delegate();  DG dg;\n    class C {}                  C c;\n    alias N = typeof(null);\n\n    { auto x = cast(N)c;  }\n    { auto x = cast(N)p;  }\n    { auto x = cast(N)da; }\n    { auto x = cast(N)aa; }\n    { auto x = cast(N)fp; }\n    { auto x = cast(N)dg; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_casting1.d",
    "content": "// REQUIRED_SRGS: -o-\n\n\n// references\nalias P = int*;             P p;\nalias FP = int function();  FP fp;\nalias DG = int delegate();  DG dg;\nalias DA = int[];           DA da;\nalias AA = int[int];        AA aa;\nclass C {}                  C c;\nalias N = typeof(null);     N n;\n\n// values\nalias SA = int[1];          SA sa;\nstruct S {}                 S s;\n                            int i;\n                            double f;\n\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting1.d(39): Error: cannot cast expression `p` of type `int*` to `int[1]`\nfail_compilation/fail_casting1.d(40): Error: cannot cast expression `fp` of type `int function()` to `int[1]`\nfail_compilation/fail_casting1.d(41): Error: cannot cast expression `dg` of type `int delegate()` to `int[1]`\nfail_compilation/fail_casting1.d(42): Error: cannot cast expression `da` of type `int[]` to `int[1]`\nfail_compilation/fail_casting1.d(43): Error: cannot cast expression `aa` of type `int[int]` to `int[1]`\nfail_compilation/fail_casting1.d(44): Error: cannot cast expression `c` of type `fail_casting1.C` to `int[1]`\nfail_compilation/fail_casting1.d(45): Error: cannot cast expression `n` of type `typeof(null)` to `int[1]`\nfail_compilation/fail_casting1.d(49): Error: cannot cast expression `sa` of type `int[1]` to `int delegate()`\nfail_compilation/fail_casting1.d(51): Error: cannot cast expression `sa` of type `int[1]` to `double[]` since sizes don't line up\nfail_compilation/fail_casting1.d(52): Error: cannot cast expression `sa` of type `int[1]` to `int[int]`\nfail_compilation/fail_casting1.d(53): Error: cannot cast expression `sa` of type `int[1]` to `fail_casting1.C`\nfail_compilation/fail_casting1.d(54): Error: cannot cast expression `sa` of type `int[1]` to `typeof(null)`\n---\n*/\nvoid test1()\n{\n    { auto x = cast(SA) p; }        // Reject (Bugzilla 14596)\n    { auto x = cast(SA)fp; }        // Reject (Bugzilla 14596) (FP is Tpointer)\n    { auto x = cast(SA)dg; }        // Reject (from e2ir)\n    { auto x = cast(SA)da; }        // Reject (from e2ir)\n    { auto x = cast(SA)aa; }        // Reject (from e2ir)\n    { auto x = cast(SA) c; }        // Reject (Bugzilla 10646)\n    { auto x = cast(SA) n; }        // Reject (Bugzilla 8179)\n    { auto x = cast( P)sa; }        // Accept (equivalent with: cast(int*)sa.ptr;)\n    { auto x = cast(double*)sa; }   // Accept (equivalent with: cast(double*)sa.ptr;)\n    { auto x = cast(FP)sa; }        // Accept (equivalent with: cast(FP)sa.ptr;)\n    { auto x = cast(DG)sa; }        // Reject (from e2ir)\n    { auto x = cast(DA)sa; }        // Accept (equivalent with: cast(int[])sa[];)\n    { auto x = cast(double[])sa; }  // Reject (from e2ir)\n    { auto x = cast(AA)sa; }        // Reject (from e2ir)\n    { auto x = cast( C)sa; }        // Reject (Bugzilla 10646)\n    { auto x = cast( N)sa; }        // Reject (Bugzilla 8179)\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting1.d(78): Error: cannot cast expression `p` of type `int*` to `S`\nfail_compilation/fail_casting1.d(79): Error: cannot cast expression `fp` of type `int function()` to `S`\nfail_compilation/fail_casting1.d(80): Error: cannot cast expression `dg` of type `int delegate()` to `S`\nfail_compilation/fail_casting1.d(81): Error: cannot cast expression `da` of type `int[]` to `S`\nfail_compilation/fail_casting1.d(82): Error: cannot cast expression `aa` of type `int[int]` to `S`\nfail_compilation/fail_casting1.d(83): Error: cannot cast expression `c` of type `fail_casting1.C` to `S`\nfail_compilation/fail_casting1.d(84): Error: cannot cast expression `n` of type `typeof(null)` to `S`\nfail_compilation/fail_casting1.d(85): Error: cannot cast expression `s` of type `S` to `int*`\nfail_compilation/fail_casting1.d(86): Error: cannot cast expression `s` of type `S` to `int function()`\nfail_compilation/fail_casting1.d(87): Error: cannot cast expression `s` of type `S` to `int delegate()`\nfail_compilation/fail_casting1.d(88): Error: cannot cast expression `s` of type `S` to `int[]`\nfail_compilation/fail_casting1.d(89): Error: cannot cast expression `s` of type `S` to `int[int]`\nfail_compilation/fail_casting1.d(90): Error: cannot cast expression `s` of type `S` to `fail_casting1.C`\nfail_compilation/fail_casting1.d(91): Error: cannot cast expression `s` of type `S` to `typeof(null)`\n---\n*/\nvoid test2()\n{\n    { auto x = cast( S) p; }        // Reject (Bugzilla 13959)\n    { auto x = cast( S)fp; }        // Reject (Bugzilla 13959) (FP is Tpointer)\n    { auto x = cast( S)dg; }        // Reject (from e2ir)\n    { auto x = cast( S)da; }        // Reject (from e2ir)\n    { auto x = cast( S)aa; }        // Reject (from e2ir)\n    { auto x = cast( S) c; }        // Reject (from e2ir)\n    { auto x = cast( S) n; }        // Reject (Bugzilla 9904)\n    { auto x = cast( P) s; }        // Reject (Bugzilla 13959)\n    { auto x = cast(FP) s; }        // Reject (Bugzilla 13959) (FP is Tpointer)\n    { auto x = cast(DG) s; }        // Reject (from e2ir)\n    { auto x = cast(DA) s; }        // Reject (from e2ir)\n    { auto x = cast(AA) s; }        // Reject (from e2ir)\n    { auto x = cast( C) s; }        // Reject (from e2ir)\n    { auto x = cast( N) s; }        // Reject (Bugzilla 9904)\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting1.d(125): Error: cannot cast expression `p` of type `int*` to `int delegate()`\nfail_compilation/fail_casting1.d(126): Error: cannot cast expression `p` of type `int*` to `int[]`\nfail_compilation/fail_casting1.d(129): Error: cannot cast expression `p` of type `int*` to `typeof(null)`\nfail_compilation/fail_casting1.d(133): Error: cannot cast expression `fp` of type `int function()` to `int delegate()`\nfail_compilation/fail_casting1.d(134): Error: cannot cast expression `fp` of type `int function()` to `int[]`\nfail_compilation/fail_casting1.d(137): Error: cannot cast expression `fp` of type `int function()` to `typeof(null)`\nfail_compilation/fail_casting1.d(139): Deprecation: casting from int delegate() to int* is deprecated\nfail_compilation/fail_casting1.d(140): Deprecation: casting from int delegate() to int function() is deprecated\nfail_compilation/fail_casting1.d(142): Error: cannot cast expression `dg` of type `int delegate()` to `int[]`\nfail_compilation/fail_casting1.d(143): Error: cannot cast expression `dg` of type `int delegate()` to `int[int]`\nfail_compilation/fail_casting1.d(144): Error: cannot cast expression `dg` of type `int delegate()` to `fail_casting1.C`\nfail_compilation/fail_casting1.d(145): Error: cannot cast expression `dg` of type `int delegate()` to `typeof(null)`\nfail_compilation/fail_casting1.d(157): Error: cannot cast expression `da` of type `int[]` to `int delegate()`\nfail_compilation/fail_casting1.d(159): Error: cannot cast expression `da` of type `int[]` to `int[int]`\nfail_compilation/fail_casting1.d(160): Error: cannot cast expression `da` of type `int[]` to `fail_casting1.C`\nfail_compilation/fail_casting1.d(161): Error: cannot cast expression `da` of type `int[]` to `typeof(null)`\nfail_compilation/fail_casting1.d(165): Error: cannot cast expression `aa` of type `int[int]` to `int delegate()`\nfail_compilation/fail_casting1.d(166): Error: cannot cast expression `aa` of type `int[int]` to `int[]`\nfail_compilation/fail_casting1.d(169): Error: cannot cast expression `aa` of type `int[int]` to `typeof(null)`\nfail_compilation/fail_casting1.d(173): Error: cannot cast expression `c` of type `fail_casting1.C` to `int delegate()`\nfail_compilation/fail_casting1.d(174): Error: cannot cast expression `c` of type `fail_casting1.C` to `int[]`\nfail_compilation/fail_casting1.d(177): Error: cannot cast expression `c` of type `fail_casting1.C` to `typeof(null)`\n---\n*/\nvoid test3()    // between reference types\n{\n    { auto x = cast( P) p; }    // Accept\n    { auto x = cast(FP) p; }    // Accept (FP is Tpointer)\n    { auto x = cast(DG) p; }    // Reject (from e2ir)\n    { auto x = cast(DA) p; }    // Reject (Bugzilla 14596)\n    { auto x = cast(AA) p; }    // Accept (because of size match)\n    { auto x = cast( C) p; }    // Accept (because of size match)\n    { auto x = cast( N) p; }    // Reject (Bugzilla 14629)\n\n    { auto x = cast( P)fp; }    // Accept (FP is Tpointer)\n    { auto x = cast(FP)fp; }    // Accept\n    { auto x = cast(DG)fp; }    // Reject (from e2ir)\n    { auto x = cast(DA)fp; }    // Reject (Bugzilla 14596)\n    { auto x = cast(AA)fp; }    // Accept (because of size match)\n    { auto x = cast( C)fp; }    // Accept (because of size match)\n    { auto x = cast( N)fp; }    // Reject (Bugzilla 14629)\n\n    { auto x = cast( P)dg; }    // Deprecated (equivalent with: cast( P)dg.ptr;)\n    { auto x = cast(FP)dg; }    // Deprecated (equivalent with: cast(FP)dg.ptr;)\n    { auto x = cast(DG)dg; }    // Accept\n    { auto x = cast(DA)dg; }    // Reject (from e2ir)\n    { auto x = cast(AA)dg; }    // Reject (from e2ir)\n    { auto x = cast( C)dg; }    // Reject (from e2ir)\n    { auto x = cast( N)dg; }    // Reject (Bugzilla 14629)\n\n    { auto x = cast( P) n; }    // Accept\n    { auto x = cast(FP) n; }    // Accept\n    { auto x = cast(DG) n; }    // Accept\n    { auto x = cast(DA) n; }    // Accept\n    { auto x = cast(AA) n; }    // Accept\n    { auto x = cast( C) n; }    // Accept\n    { auto x = cast( N) n; }    // Accept\n\n    { auto x = cast( P)da; }    // Accept (equivalent with: cast(P)da.ptr;)\n    { auto x = cast(FP)da; }    // Accept (FP is Tpointer)\n    { auto x = cast(DG)da; }    // Reject (from e2ir)\n    { auto x = cast(DA)da; }    // Accept\n    { auto x = cast(AA)da; }    // Reject (from e2ir)\n    { auto x = cast( C)da; }    // Reject (Bugzilla 10646)\n    { auto x = cast( N)da; }    // Reject (Bugzilla 14629)\n\n    { auto x = cast( P)aa; }    // Accept (because of size match)\n    { auto x = cast(FP)aa; }    // Accept (FP is Tpointer)\n    { auto x = cast(DG)aa; }    // Reject (from e2ir)\n    { auto x = cast(DA)aa; }    // Reject (from e2ir)\n    { auto x = cast(AA)aa; }    // Accept\n    { auto x = cast( C)aa; }    // Accept (because of size match)\n    { auto x = cast( N)aa; }    // Reject (Bugzilla 14629)\n\n    { auto x = cast( P) c; }    // Accept\n    { auto x = cast(FP) c; }    // Accept (FP is Tpointer)\n    { auto x = cast(DG) c; }    // Reject (from e2ir)\n    { auto x = cast(DA) c; }    // Reject (Bugzilla 10646)\n    { auto x = cast(AA) c; }    // Accept (because of size match)\n    { auto x = cast( C) c; }    // Accept\n    { auto x = cast( N) c; }    // Reject (Bugzilla 14629)\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting1.d(206): Error: cannot cast expression `0` of type `int` to `int delegate()`\nfail_compilation/fail_casting1.d(207): Error: cannot cast expression `0` of type `int` to `int[]`\nfail_compilation/fail_casting1.d(208): Error: cannot cast expression `0` of type `int` to `int[1]`\nfail_compilation/fail_casting1.d(209): Error: cannot cast expression `0` of type `int` to `int[int]`\nfail_compilation/fail_casting1.d(210): Error: cannot cast expression `0` of type `int` to `fail_casting1.C`\nfail_compilation/fail_casting1.d(211): Error: cannot cast expression `0` of type `int` to `typeof(null)`\nfail_compilation/fail_casting1.d(215): Error: cannot cast expression `i` of type `int` to `int delegate()`\nfail_compilation/fail_casting1.d(216): Error: cannot cast expression `i` of type `int` to `int[]`\nfail_compilation/fail_casting1.d(217): Error: cannot cast expression `i` of type `int` to `int[1]`\nfail_compilation/fail_casting1.d(218): Error: cannot cast expression `i` of type `int` to `int[int]`\nfail_compilation/fail_casting1.d(219): Error: cannot cast expression `i` of type `int` to `fail_casting1.C`\nfail_compilation/fail_casting1.d(220): Error: cannot cast expression `i` of type `int` to `typeof(null)`\nfail_compilation/fail_casting1.d(224): Error: cannot cast expression `dg` of type `int delegate()` to `int`\nfail_compilation/fail_casting1.d(225): Error: cannot cast expression `da` of type `int[]` to `int`\nfail_compilation/fail_casting1.d(226): Error: cannot cast expression `sa` of type `int[1]` to `int`\nfail_compilation/fail_casting1.d(227): Error: cannot cast expression `aa` of type `int[int]` to `int`\nfail_compilation/fail_casting1.d(228): Error: cannot cast expression `c` of type `fail_casting1.C` to `int`\n---\n*/\nvoid test4()\n{\n    { auto x = cast( P) 0; }    // Accept\n    { auto x = cast(FP) 0; }    // Accept\n    { auto x = cast(DG) 0; }    // Reject (from constfold)\n    { auto x = cast(DA) 0; }    // Reject (Bugzilla 11484)\n    { auto x = cast(SA) 0; }    // Reject (Bugzilla 11484)\n    { auto x = cast(AA) 0; }    // Reject (from constfold)\n    { auto x = cast( C) 0; }    // Reject (Bugzilla 11485)\n    { auto x = cast( N) 0; }    // Reject (from constfold)\n\n    { auto x = cast( P) i; }    // Accept\n    { auto x = cast(FP) i; }    // Accept\n    { auto x = cast(DG) i; }    // Reject (from e2ir)\n    { auto x = cast(DA) i; }    // Reject (Bugzilla 11484)\n    { auto x = cast(SA) i; }    // Reject (Bugzilla 11484)\n    { auto x = cast(AA) i; }    // Reject (from e2ir)\n    { auto x = cast( C) i; }    // Reject (Bugzilla 11485)\n    { auto x = cast( N) i; }    // Reject (from e2ir)\n\n    { auto x = cast(int) p; }   // Accept\n    { auto x = cast(int)fp; }   // Accept\n    { auto x = cast(int)dg; }   // Reject (from e2ir)\n    { auto x = cast(int)da; }   // Reject (Bugzilla 11484)\n    { auto x = cast(int)sa; }   // Reject (Bugzilla 11484)\n    { auto x = cast(int)aa; }   // Reject (from e2ir)\n    { auto x = cast(int) c; }   // Reject (Bugzilla 7472)\n    { auto x = cast(int) n; }   // Accept\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting1.d(249): Error: cannot cast expression `0` of type `int` to `int[1]`\nfail_compilation/fail_casting1.d(250): Error: cannot cast expression `0` of type `int` to `S`\nfail_compilation/fail_casting1.d(251): Error: cannot cast expression `i` of type `int` to `int[1]`\nfail_compilation/fail_casting1.d(252): Error: cannot cast expression `i` of type `int` to `S`\nfail_compilation/fail_casting1.d(253): Error: cannot cast expression `f` of type `double` to `int[1]`\nfail_compilation/fail_casting1.d(254): Error: cannot cast expression `f` of type `double` to `S`\nfail_compilation/fail_casting1.d(255): Error: cannot cast expression `sa` of type `int[1]` to `int`\nfail_compilation/fail_casting1.d(256): Error: cannot cast expression `s` of type `S` to `int`\nfail_compilation/fail_casting1.d(257): Error: cannot cast expression `sa` of type `int[1]` to `double`\nfail_compilation/fail_casting1.d(258): Error: cannot cast expression `s` of type `S` to `double`\n---\n*/\nvoid test5()\n{\n    { auto x = cast(SA) 0; }        // Reject (Bugzilla 14154)\n    { auto x = cast( S) 0; }        // Reject (Bugzilla 14154)\n    { auto x = cast(SA) i; }        // Reject (Bugzilla 14154)\n    { auto x = cast( S) i; }        // Reject (Bugzilla 14154)\n    { auto x = cast(SA) f; }        // Reject (Bugzilla 14154)\n    { auto x = cast( S) f; }        // Reject (Bugzilla 14154)\n    { auto x = cast(int)sa; }       // Reject (Bugzilla 14154)\n    { auto x = cast(int) s; }       // Reject (Bugzilla 14154)\n    { auto x = cast(double)sa; }    // Reject (Bugzilla 14154)\n    { auto x = cast(double) s; }    // Reject (Bugzilla 14154)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_casting2.d",
    "content": "// REQUIRED_ARGS: -o-\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_casting2.d(15): Error: type `int` is not an expression\nfail_compilation/fail_casting2.d(17): Error: template lambda has no type\nfail_compilation/fail_casting2.d(20): Error: template `Templ()` has no type\n---\n*/\n\nvoid test15214()\n{\n    alias Type = int;\n    cast(void)(Type);\n\n    cast(void)(x => mixin(x)(\"mixin(x);\"));\n\n    template Templ() {}\n    cast(void)(Templ);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_circular.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_circular.d(16): Error: circular reference to variable `fail_circular.a1`\nfail_compilation/fail_circular.d(17): Error: circular reference to variable `fail_circular.a2`\nfail_compilation/fail_circular.d(19): Error: circular reference to variable `fail_circular.b1`\nfail_compilation/fail_circular.d(20): Error: circular reference to variable `fail_circular.b2`\nfail_compilation/fail_circular.d(22): Error: circular reference to variable `fail_circular.c1`\nfail_compilation/fail_circular.d(23): Error: circular reference to variable `fail_circular.c2`\nfail_compilation/fail_circular.d(25): Error: circular initialization of variable `fail_circular.d1`\nfail_compilation/fail_circular.d(26): Error: circular initialization of variable `fail_circular.d2`\nfail_compilation/fail_circular.d(28): Error: circular initialization of variable `fail_circular.e1`\nfail_compilation/fail_circular.d(29): Error: circular initialization of variable `fail_circular.e2`\n---\n*/\nauto a1 =  a1;          // semantic error (cannot determine expression type)\nauto a2 = .a2;          // semantic error\n\nconst b1 =  b1;         // semantic error\nconst b2 = .b2;         // semantic error\n\nenum c1 =  c1;          // semantic error\nenum c2 = .c2;          // semantic error\n\nconst int d1 =  d1;     // CTFE error (expression type is determined to int)\nconst int d2 = .d2;     // CTFE error\n\nenum int e1 =  e1;      // CTFE error\nenum int e2 = .e2;      // CTFE error\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_circular.d(47): Error: circular reference to variable `fail_circular.a1a`\nfail_compilation/fail_circular.d(49): Error: circular reference to variable `fail_circular.a2a`\nfail_compilation/fail_circular.d(52): Error: circular reference to variable `fail_circular.b1a`\nfail_compilation/fail_circular.d(54): Error: circular reference to variable `fail_circular.b2a`\nfail_compilation/fail_circular.d(57): Error: circular reference to variable `fail_circular.c1a`\nfail_compilation/fail_circular.d(59): Error: circular reference to variable `fail_circular.c2a`\nfail_compilation/fail_circular.d(62): Error: circular initialization of variable `fail_circular.d1a`\nfail_compilation/fail_circular.d(64): Error: circular initialization of variable `fail_circular.d2a`\nfail_compilation/fail_circular.d(67): Error: circular initialization of variable `fail_circular.e1a`\nfail_compilation/fail_circular.d(69): Error: circular initialization of variable `fail_circular.e2a`\n---\n*/\nauto a1a =  a1b;\nauto a1b =  a1a;        // semantic error\nauto a2a =  a2b;\nauto a2b = .a2a;        // semantic error\n\nconst b1a =  b1b;\nconst b1b =  b1a;       // semantic error\nconst b2a =  b2b;\nconst b2b = .b2a;       // semantic error\n\nenum c1a =  c1b;\nenum c1b =  c1a;        // semantic error\nenum c2a =  c2b;\nenum c2b = .c2a;        // semantic error\n\nconst int d1a =  d1b;\nconst int d1b =  d1a;   // CTFE error\nconst int d2a =  d2b;\nconst int d2b = .d2a;   // CTFE error\n\nenum int e1a =  e1b;\nenum int e1b =  e1a;    // CTFE error\nenum int e2a =  e2b;\nenum int e2b = .e2a;    // CTFE error\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_circular.d(84): Error: circular reference to variable `fail_circular.S1.a1`\nfail_compilation/fail_circular.d(88): Error: circular reference to variable `fail_circular.S2.b1`\nfail_compilation/fail_circular.d(92): Error: circular reference to variable `fail_circular.S3.c1`\nfail_compilation/fail_circular.d(97): Error: circular reference to variable `fail_circular.S4.a1a`\nfail_compilation/fail_circular.d(102): Error: circular reference to variable `fail_circular.S5.b1a`\nfail_compilation/fail_circular.d(107): Error: circular reference to variable `fail_circular.S6.c1a`\n---\n*/\nstruct S1\n{\n    static a1 = S1.a1;          // semantic error\n}\nstruct S2\n{\n    static const b1 = S2.b1;     // semantic error\n}\nstruct S3\n{\n    enum c1 = S3.c1;             // semantic error\n}\nstruct S4\n{\n    static a1a = S4.a1b;\n    static a1b = S4.a1a;         // semantic error\n}\nstruct S5\n{\n    static const b1a = S5.b1b;\n    static const b1b = S5.b1a;   // semantic error\n}\nstruct S6\n{\n    enum c1a = S6.c1b;\n    enum c1b = S6.c1a;           // semantic error\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_circular.d(123): Error: circular reference to variable `fail_circular.C.a1`\nfail_compilation/fail_circular.d(125): Error: circular reference to variable `fail_circular.C.b1`\nfail_compilation/fail_circular.d(127): Error: circular reference to variable `fail_circular.C.c1`\nfail_compilation/fail_circular.d(130): Error: circular reference to variable `fail_circular.C.a1a`\nfail_compilation/fail_circular.d(133): Error: circular reference to variable `fail_circular.C.b1a`\nfail_compilation/fail_circular.d(136): Error: circular reference to variable `fail_circular.C.c1a`\n---\n*/\nclass C\n{\n    static a1 = C.a1;           // semantic error\n\n    static const b1 = C.b1;     // semantic error\n\n    enum c1 = C.c1;             // semantic error\n\n    static a1a = C.a1b;\n    static a1b = C.a1a;         // semantic error\n\n    static const b1a = C.b1b;\n    static const b1b = C.b1a;   // semantic error\n\n    enum c1a = C.c1b;\n    enum c1b = C.c1a;           // semantic error\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_circular2.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_circular2.d(10): Error: circular initialization of variable `fail_circular2.S.d1`\nfail_compilation/fail_circular2.d(12): Error: circular initialization of variable `fail_circular2.S.e1`\n---\n*/\nstruct S\n{\n    static const int d1 = S.d1;     // CTFE error (expression type is determined to int)\n\n    enum int e1 = S.e1;             // CTFE error\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_circular2.d(24): Error: circular initialization of variable `fail_circular2.C.d1`\nfail_compilation/fail_circular2.d(26): Error: circular initialization of variable `fail_circular2.C.e1`\n---\n*/\nclass C\n{\n    static const int d1 = C.d1;     // CTFE error\n\n    enum int e1 = C.e1;             // CTFE error\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_contracts1.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_contracts1.d(8): Error: `(identifier) { ... }` or `(identifier; expression)` following `out` expected, not `)`\n---\n*/\n\nvoid foo() out()){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_contracts2.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_contracts2.d(8): Error: missing `do { ... }` after `in` or `out`\n---\n*/\n\nvoid foo()in{}{}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_contracts3.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_contracts3.d(13): Error: function `fail_contracts3.D.foo` cannot have an in contract when overridden function `fail_contracts3.C.foo` does not have an in contract\n---\n*/\n\nclass C {\n\tvoid foo(){}\n}\n\nclass D : C {\n\toverride void foo()in{}do{}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_contracts4.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_contracts4.d(8): Error: missing `do { ... }` for function literal\n---\n*/\n\nenum x = delegate int()in(true) out(;true) out(r; true) in{} out(r){};\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_isZeroInit.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_isZeroInit.d(11): Error: type expected as second argument of __traits `isZeroInit` instead of `a`\n---\n*/\nvoid test()\n{\n    int a = 3;\n    // Providing a specific variable rather than a type isn't allowed.\n    enum bool az = __traits(isZeroInit, a);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_opover.d",
    "content": "// REQUIRED_ARGS: -o-\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_opover.d(13): Error: no `[]` operator overload for type `object.Object`\nfail_compilation/fail_opover.d(17): Error: no `[]` operator overload for type `TestS`\n---\n*/\nvoid test1()\n{\n    Object m;\n    m[] = error;\n\n    struct TestS {}\n    TestS s;\n    s[] = error;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/fail_opover.d(46): Error: no `[]` operator overload for type `S`\nfail_compilation/fail_opover.d(47): Error: no `[]` operator overload for type `S`\nfail_compilation/fail_opover.d(48): Error: no `[]` operator overload for type `S`\nfail_compilation/fail_opover.d(49): Error: no `[]` operator overload for type `S`\nfail_compilation/fail_opover.d(50): Error: no `[]` operator overload for type `S`\nfail_compilation/fail_opover.d(51): Error: no `[]` operator overload for type `S`\nfail_compilation/fail_opover.d(52): Error: no `[]` operator overload for type `S`\nfail_compilation/fail_opover.d(53): Error: no `[]` operator overload for type `S`\nfail_compilation/fail_opover.d(54): Error: no `[]` operator overload for type `S`\nfail_compilation/fail_opover.d(55): Error: no `[]` operator overload for type `S`\nfail_compilation/fail_opover.d(56): Error: no `[]` operator overload for type `S`\nfail_compilation/fail_opover.d(57): Error: no `[]` operator overload for type `S`\n---\n*/\nvoid test2()\n{\n    struct S\n    {\n        void func(int) {}\n        alias func this;\n    }\n    S s;\n    // The errors failing aliasthis access need to be gagged for better error messages.\n    s[];            // in ArrayExp::op_overload()\n    s[1];           // ditto\n    s[1..2];        // ditto\n    +s[];           // in UnaExp::op_overload()\n    +s[1];          // ditto\n    +s[1..2];       // ditto\n    s[] = 3;        // in AssignExp::semantic()\n    s[1] = 3;       // ditto\n    s[1..2] = 3;    // ditto\n    s[] += 3;       // in BinAssignExp::op_overload()\n    s[1] += 3;      // ditto\n    s[1..2] += 3;   // ditto\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fail_scope.d",
    "content": "/*\nPERMUTE_ARGS:\nREQUIRED_ARGS: -dip25\nTEST_OUTPUT:\n---\nfail_compilation/fail_scope.d(45): Error: returning `cast(char[])string` escapes a reference to local variable `string`\nfail_compilation/fail_scope.d(63): Error: returning `s.bar()` escapes a reference to local variable `s`\nfail_compilation/fail_scope.d(82): Error: returning `& string` escapes a reference to local variable `string`\nfail_compilation/fail_scope.d(92): Error: returning `cast(int[])a` escapes a reference to local variable `a`\nfail_compilation/fail_scope.d(100): Error: returning `cast(int[])a` escapes a reference to local variable `a`\nfail_compilation/fail_scope.d(108): Error: escaping reference to outer local variable `x`\nfail_compilation/fail_scope.d(127): Error: returning `s.bar()` escapes a reference to local variable `s`\nfail_compilation/fail_scope.d(137): Error: returning `foo16226(i)` escapes a reference to local variable `i`\n---\n//fail_compilation/fail_scope.d(30): Error: scope variable `da` may not be returned\n//fail_compilation/fail_scope.d(32): Error: scope variable `o` may not be returned\n//fail_compilation/fail_scope.d(33): Error: scope variable `dg` may not be returned\n//fail_compilation/fail_scope.d(35): Error: scope variable `da` may not be returned\n//fail_compilation/fail_scope.d(37): Error: scope variable `o` may not be returned\n//fail_compilation/fail_scope.d(38): Error: scope variable `dg` may not be returned\n//fail_compilation/fail_scope.d(40): Error: scope variable `p` may not be returned\n*/\n\n\n\n\n\nalias int delegate() dg_t;\n\nint[]  checkEscapeScope1(scope int[]  da) { return da; }\nint[3] checkEscapeScope2(scope int[3] sa) { return sa; }\nObject checkEscapeScope3(scope Object o)  { return o;  }\ndg_t   checkEscapeScope4(scope dg_t   dg) { return dg; }\n\nint[]  checkEscapeScope1() { scope int[]  da = [];           return da; }\nint[3] checkEscapeScope2() { scope int[3] sa = [1,2,3];      return sa; }\nObject checkEscapeScope3() { scope Object  o = new Object;   return o;  }   // same with fail7294.d\ndg_t   checkEscapeScope4() { scope dg_t   dg = () => 1;      return dg; }\n\nint* test(scope int* p) @safe { return p; }\n\nchar[] foo140()\n{\n    char[4] string = \"abcd\";\n    return string;\n}\n\n/************/\n\nstruct S\n{\n    int x;\n\n    ref int bar() return\n    {\n        return x;\n    }\n}\n\nref int test()\n{\n    S s;\n    return s.bar();\n}\n\n/************/\n\nref int foo8(ref int x);\nref int foo8(return ref int x);\n\nvoid testover()\n{\n    int x;\n    foo8(x);\n}\n\n/************/\n\nchar* fail141()\n{\n    char[4] string = \"abcd\";\n    return string.ptr;\n}\n\n/************/\n\nint[] test1313b()\nout{}\nbody\n{\n    int[2] a;\n    return a;\n}\n\nint[] test1313a()\n//out{}\nbody\n{\n    int[2] a;\n    return a;\n}\n\n/******************/\n// https://issues.dlang.org/show_bug.cgi?id=15192\n\nref int fun15192(ref int x) @safe\n{\n    ref int bar(){ return x; }\n    return bar();\n}\n\nref int fun15192_2(return ref int x) @safe\n{\n    ref int bar(){ return x; }\n    return bar();\n}\n\n/**************************/\n// https://issues.dlang.org/show_bug.cgi?id=15193\n\nref int foo15193()@safe{\n    struct S{\n        int x;\n        ref int bar() { return x; }\n    }\n    S s;\n    return s.bar();\n}\n\n\n/*****************************/\n// https://issues.dlang.org/show_bug.cgi?id=16226\n\nref int test16226() @safe\n{\n    int i;\n    return foo16226(i);\n}\n\n\nref foo16226(ref int bar) @safe\n{\n    return bar;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failattr.d",
    "content": "// REQUIRED_ARGS: -o-\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/failattr.d(16): Error: variable `failattr.C2901.v1` cannot be `synchronized`\nfail_compilation/failattr.d(17): Error: variable `failattr.C2901.v2` cannot be `override`\nfail_compilation/failattr.d(18): Error: variable `failattr.C2901.v3` cannot be `abstract`\nfail_compilation/failattr.d(19): Error: variable `failattr.C2901.v4` cannot be `final`, perhaps you meant `const`?\nfail_compilation/failattr.d(31): Error: variable `failattr.C2901.v13` cannot be `final abstract synchronized override`\nfail_compilation/failattr.d(33): Error: variable `failattr.C2901.v14` cannot be `final`, perhaps you meant `const`?\n---\n*/\nclass C2901\n{\n    synchronized    int v1;         // error\n    override        int v2;         // error\n    abstract        int v3;         // error\n    final           int v4;         // error\n\n    synchronized    { int v5; }     // no error\n    override        { int v6; }     // no error\n    abstract        { int v7; }     // no error\n    final           { int v8; }     // no error\n\n    synchronized:   int v9;         // no error\n    override:       int v10;        // no error\n    abstract:       int v11;        // no error\n    final:          int v12;        // no error\n\n    synchronized override abstract final int v13;   // one line error\n\n    static final int v14;           // error, even if static is applied at the same time\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failcontracts.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/failcontracts.d(18): Error: missing `{ ... }` for function literal\nfail_compilation/failcontracts.d(18): Error: semicolon expected following auto declaration, not `bode`\nfail_compilation/failcontracts.d(19): Error: function declaration without return type. (Note that constructors are always named `this`)\nfail_compilation/failcontracts.d(19): Error: no identifier for declarator `test1()`\nfail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration\nfail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration\nfail_compilation/failcontracts.d(22): Error: unexpected `(` in declarator\nfail_compilation/failcontracts.d(22): Error: found `T` when expecting `)`\nfail_compilation/failcontracts.d(22): Error: enum declaration is invalid\nfail_compilation/failcontracts.d(22): Error: found `)` instead of statement\n---\n*/\n\nvoid test()\n{\n    auto f1 = function() bode;\n    auto test1() bode;\n    auto test2()() bode;\n\n    enum : int (int function() bode T);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/faildeleteaa.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/faildeleteaa.d(12): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/faildeleteaa.d(12): Error: cannot delete type `int`\n---\n*/\n\nvoid main()\n{\n    int[int] aa = [1 : 2];\n    delete aa[1];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/faildottypeinfo.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/faildottypeinfo.d(11): Error: no property `typeinfo` for type `int`\nfail_compilation/faildottypeinfo.d(12): Error: no property `typeinfo` for type `object.Object`\n---\n*/\n\nvoid main()\n{\n    auto x = 0.typeinfo;\n    auto y = Object.typeinfo;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failescape.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/failescape.d(8): Error: character '\\' is not a valid token\n---\n*/\n\nstring x = \\n;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failinout1.d",
    "content": "inout(int) foo(inout(int) x)\n{\n    x = 5;  // cannot modify inout\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failinout2.d",
    "content": "inout int x;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failinout3748a.d",
    "content": "struct S3748\n{\n    inout(int) err8;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failinout3748b.d",
    "content": "void main()\n{\n    inout(int)* err11;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failmemalloc.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/failmemalloc.d(11): Deprecation: class allocators have been deprecated, consider moving the allocation strategy outside of the class\nfail_compilation/failmemalloc.d(14): Error: member allocators not supported by CTFE\n---\n*/\n\nstruct S\n{\n    new(size_t sz) { return null; }\n}\n\nS* s = new S();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failoffset.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/failoffset.d(12): Error: no property `offset` for type `int`\nfail_compilation/failoffset.d(12):        while evaluating: `static assert(b.offset == 4)`\n---\n*/\n\nvoid main()\n{\n    struct S { int a, b; }\n    static assert(S.b.offset == 4);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failsafea.d",
    "content": "\nvoid systemfunc() @system {}\n\n@safe\nvoid callingsystem()\n{\n    systemfunc();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failsafeb.d",
    "content": "\nvoid function() @system sysfuncptr;\n\n@safe\nvoid callingsystem()\n{\n    sysfuncptr();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/failsafec.d",
    "content": "\nvoid delegate() @system sysdelegate;\n\n@safe\nvoid callingsystem()\n{\n    sysdelegate();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fix17635.d",
    "content": "/* REQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/fix17635.d(22): Error: cannot implicitly convert expression `f(& p)` of type `immutable(int)**` to `immutable(int**)`\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=17635\n// https://issues.dlang.org/show_bug.cgi?id=15660\n\nalias T = immutable int;\n\nT** f(const T** input) pure\n{\n    T** output;\n    return output;\n}\n\nvoid main()\n{\n    T i;\n    T* p = &i;\n    immutable T** r = f(&p);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fix17751.d",
    "content": "/* REQUIRED_ARGS: -m64\n * TEST_OUTPUT:\n---\nfail_compilation/fix17751.d(15): Error: last parameter to `__simd()` must be a constant\n---\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=17751\n\nimport core.simd;\n\npure @safe V1 simd(XMM opcode, V1, V2)(V1 op1, V2 op2, ubyte imm8)\n    if (is(V1 == __vector) && is(V2 == __vector))\n{\n    return cast(V1)__simd(opcode, op1, op2, imm8);\n}\n\nvoid main()\n{\n    float4 a, b;\n    a = simd!(XMM.CMPPD)(a, b, 0x7A);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fix18575.d",
    "content": "/* REQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/fix18575.d(27): Error: returning `s.foo()` escapes a reference to parameter `s`, perhaps annotate with `return`\nfail_compilation/fix18575.d(31): Error: returning `s.foo()` escapes a reference to parameter `s`, perhaps annotate with `return`\nfail_compilation/fix18575.d(35): Error: returning `s.abc()` escapes a reference to parameter `s`, perhaps annotate with `return`\nfail_compilation/fix18575.d(39): Error: returning `s.ghi(t)` escapes a reference to parameter `t`, perhaps annotate with `return`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18575\n\n@safe:\n\nstruct S {\n@safe:\n    int x;\n\n    void bar() { }\n    auto foo() { return &this.bar; }\n    auto def() { return &bar; }\n    auto abc() { return &x; }\n    auto ghi(ref S s) { return &s.bar; }\n}\n\nauto f(S s) {\n    return s.foo();\n}\n\nauto g(S s) {\n    return s.foo();\n}\n\nauto h(S s) {\n    return s.abc();\n}\n\nauto j(S s, S t) {\n    return s.ghi(t);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fix19018.d",
    "content": "/* REQUIRED_ARGS: -de\n * PERMUTE_ARGS:\n * TEST_OUTPUT:\n---\nfail_compilation/fix19018.d(17): Deprecation: `0b` isn't a valid integer literal, use `0b0` instead\nfail_compilation/fix19018.d(18): Deprecation: `0B` isn't a valid integer literal, use `0B0` instead\nfail_compilation/fix19018.d(19): Deprecation: `0x` isn't a valid integer literal, use `0x0` instead\nfail_compilation/fix19018.d(20): Deprecation: `0X` isn't a valid integer literal, use `0X0` instead\nfail_compilation/fix19018.d(21): Deprecation: `0x_` isn't a valid integer literal, use `0x0` instead\n---\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=19018\n\nvoid foo()\n{\n    auto a = 0b;\n    auto b = 0B;\n    auto c = 0x;\n    auto d = 0X;\n    auto e = 0x_;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fix19059.d",
    "content": "/* REQUIRED_ARGS:\n * PERMUTE_ARGS:\n * TEST_OUTPUT:\n---\nfail_compilation/fix19059.d(17): Error: octal digit expected, not `8`\nfail_compilation/fix19059.d(17): Error: octal literals larger than 7 are no longer supported\nfail_compilation/fix19059.d(18): Error: octal digit expected, not `9`\nfail_compilation/fix19059.d(18): Error: octal literals larger than 7 are no longer supported\nfail_compilation/fix19059.d(19): Error: octal literals `010` are no longer supported, use `std.conv.octal!10` instead\n---\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=19059\n\nvoid foo()\n{\n    auto a = 08;\n    auto b = 09;\n    auto c = 010;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fix350a.d",
    "content": "struct S1\n{\n    int a, b, c;\n\n    static immutable S1 C1 = { 1 2 3 }; // no commas here, compiles\n    static immutable S1 C2 = { 1, 2, 3 }; // compiles as well\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fix350b.d",
    "content": "int foo() { return 3; }\n\nstruct S2\n{\n    int a, b, c;\n\n    static immutable S2 C1 = { foo() 2 3 }; // compiles (and works)\n    static immutable S2 C2 = { foo() 2, 3 }; // compiles (and works)\n    //static immutable S2 C3 = { 2 foo() 3 }; // does not compile: comma expected separating field initializers\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/fix5212.d",
    "content": "/* REQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/fix5212.d(14): Error: scope variable `args_` assigned to non-scope `this.args`\n---\n*/\n\n\n// https://issues.dlang.org/show_bug.cgi?id=5212\n\nclass Foo {\n    int[] args;\n    @safe this(int[] args_...) {\n        args = args_;\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/gag4269a.d",
    "content": "﻿// REQUIRED_ARGS: -c -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/gag4269a.d(12): Error: undefined identifier `B`\n---\n*/\n\nstatic if(is(typeof(A4269.sizeof))) {}\nclass A4269\n{\n    void foo(B b);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/gag4269b.d",
    "content": "﻿// REQUIRED_ARGS: -c -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/gag4269b.d(10): Error: undefined identifier `Y`\n---\n*/\n\nstatic if(is(typeof(X2.init))) {}\nstruct X2 { Y y; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/gag4269c.d",
    "content": "﻿// REQUIRED_ARGS: -c -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/gag4269c.d(10): Error: undefined identifier `T3`, did you mean function `X3`?\n---\n*/\n\nstatic if(is(typeof(X3.init))) {}\nvoid X3(T3) { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/gag4269d.d",
    "content": "﻿// REQUIRED_ARGS: -c -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/gag4269d.d(10): Error: undefined identifier `Y4`, did you mean function `X4`?\n---\n*/\n\nstatic if(is(typeof(X4.init))) {}\nY4 X4() { return typeof(return).init; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/gag4269e.d",
    "content": "﻿// REQUIRED_ARGS: -c -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/gag4269e.d(10): Error: undefined identifier `Y8`, did you mean class `X8`?\n---\n*/\n\nstatic if(is(typeof(X8.init))) {}\nclass X8 : Y8 {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/gag4269f.d",
    "content": "﻿// REQUIRED_ARGS: -c -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/gag4269f.d(11): Error: undefined identifier `Y9`, did you mean interface `X9`?\nfail_compilation/gag4269f.d(11): Error: variable `gag4269f.X9.y` field not allowed in interface\n---\n*/\n\nstatic if(is(typeof(X9.init))) {}\ninterface X9 { Y9 y; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/gag4269g.d",
    "content": "﻿// REQUIRED_ARGS: -c -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/gag4269g.d(10): Error: undefined identifier `Y13`, did you mean template `X13(Y13 y)`?\n---\n*/\n\nstatic if(is(typeof(X13!(0).init))) {}\ntemplate X13(Y13 y) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10016.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10016.d(33): Error: undefined identifier `unknownIdentifier`\nfail_compilation/ice10016.d(47): Error: template instance `ice10016.RefCounted!(S)` error instantiating\n---\n*/\n\nstruct RefCounted(T)\n{\n    struct RefCountedStore\n    {\n        struct Impl\n        {\n            T _payload;\n        }\n        Impl* _store;\n    }\n    RefCountedStore _refCounted;\n\n    void opAssign(typeof(this)) { }\n    void opAssign(T) { }\n\n    @property refCountedPayload()\n    {\n        return _refCounted._store._payload;\n    }\n    alias refCountedPayload this;\n}\n\nstruct S\n{\n    int i = unknownIdentifier;\n}\n\nclass C {}\n\nclass N\n{\n    this(C) {}\n    C c() { return null; }\n}\n\nclass D : N\n{\n    this() { super(c); }\n    RefCounted!S _s;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10076.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10076.d(18): Error: template instance `getMembersAndAttributesWhere!()` template `getMembersAndAttributesWhere` is not defined\nfail_compilation/ice10076.d(23): Error: template instance `ice10076.getValidaterAttrs!string` error instantiating\nfail_compilation/ice10076.d(13):        instantiated from here: `validate!string`\n---\n*/\n\nvoid main()\n{\n    string s;\n    validate(s);\n}\n\ntemplate getValidaterAttrs(T)\n{\n    alias getMembersAndAttributesWhere!().Elements getValidaterAttrs;\n}\n\nvoid validate(T)(T)\n{\n    alias getValidaterAttrs!T memberAttrs;\n    auto x = memberAttrs.length;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10212.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10212.d(12): Error: mismatched function return type inference of `int function() pure nothrow @nogc @safe` and `int`\n---\n*/\n\nint delegate() foo()\n{\n    // returns \"int function() pure nothrow @safe function() pure nothrow @safe\"\n    // and it mismatches to \"int delegate()\"\n    return () => {\n        return 1;\n    };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10259.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10259.d(11): Error: circular reference to `ice10259.D.d`\nfail_compilation/ice10259.d(11):        called from here: `(*function () => x)()`\n---\n*/\nclass D\n{\n    int x;\n    D d = { auto x = new D(); return x; }();\n}\nenum x = new D;\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10259.d(25): Error: circular reference to `ice10259.D2.d`\nfail_compilation/ice10259.d(25):        called from here: `(*function () => x)()`\n---\n*/\nclass D2\n{\n    int x;\n    D2 d = function { auto x = new D2(); return x; }();\n}\nenum x2 = new D2;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10273.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=10273\n// ICE in CTFE\n\nstruct Bug10273 {\n    int val = 3.45;\n}\nint bug10273()\n{\n    Bug10273 p;\n    return 1;\n}\n\nstatic assert(bug10273());\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10283.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=10283\n\nS10283 blah(S10283 xxx) { return xxx; }\nS10283 repy = blah(S10283());\n\nstruct S10283\n{\n    string source = 7;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10341.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10341.d(10): Error: case range not in `switch` statement\n---\n*/\n\nvoid main()\n{\n    case 1: .. case 2:\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10382.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10382.d(14): Error: can only catch class objects, not `int`\n---\n*/\n\nvoid main ()\n{\n    try\n    {\n        int b = 3;\n    }\n    catch (int a) { }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10419.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10419.d(12): Error: `arr().length` is not an lvalue and cannot be modified\n---\n*/\n\nint[] arr() { return []; }\n\nvoid main()\n{\n    arr().length = 1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10599.d",
    "content": "﻿// https://issues.dlang.org/show_bug.cgi?id=10599\n// ICE(interpret.c)\n\nstruct Bug {\n    int val = 3.45;\n}\nint bug10599()\n{\n    Bug p = Bug();\n    return 1;\n}\n\nstatic assert(bug10599());\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10600.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10600.d(30): Error: template instance `to!(int, double)` does not match template declaration `to(T)`\n---\n*/\n\nimport imports.ice10600a;\nimport imports.ice10600b;\n\ntemplate Tuple(Specs...)\n{\n    struct Tuple\n    {\n        string toString()\n        {\n            Appender!string w;  // issue!\n            return \"\";\n        }\n    }\n}\nTuple!T tuple(T...)(T args)\n{\n    return typeof(return)();\n}\n\nvoid main()\n{\n    auto a = to!int(\"\");\n    auto b = to!(int, double)(\"\");\n    tuple(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10616.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10616.d(8): Error: class `ice10616.A` is forward referenced when looking for `B`\n---\n*/\n\nclass A : A.B\n{\n    interface B {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10624.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10624.d(38): Error: need member function `opCmp()` for struct `Tuple!(Msg)` to compare\nfail_compilation/ice10624.d(48): Error: template instance `ice10624.Variant.handler!(Tuple!(Msg))` error instantiating\nfail_compilation/ice10624.d(21):        instantiated from here: `opAssign!(Tuple!(Msg))`\n---\n*/\n\nstruct Msg {}\n\nstruct Tuple(Specs...)\n{\n    Specs expand;\n    alias expand this;\n}\n\nvoid main()\n{\n    Variant data;\n    data = Tuple!Msg();\n\n}\n\nstruct Variant\n{\n    ptrdiff_t function() fptr = &handler!(void);\n\n    static ptrdiff_t handler(A : void)()\n    {\n        return 0;\n    }\n    static ptrdiff_t handler(A)()\n    {\n        A* zis;\n        A* rhsPA;\n        {\n            return *zis < *rhsPA ? -1 : 1;\n            // Tuple!(Msg) < Tuple!(Msg)\n            // Tuple!(Msg).expand < Tuple!(Msg).expand\n            // -> should be error\n        }\n        return 0;\n    }\n\n    Variant opAssign(T)(T rhs)\n    {\n        fptr = &handler!(T);\n        return this;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10651.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10651.d(11): Error: can only throw class objects derived from `Throwable`, not type `int*`\n---\n*/\n\nvoid main()\n{\n    alias T = int;\n    throw new T();  // ICE\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10713.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10713.d(10): Error: no property `nonExistingField` for type `S`\n---\n*/\n\nstruct S\n{\n    void f(typeof(this.nonExistingField) a) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10727a.d",
    "content": "// REQUIRED_ARGS: -c\n/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/foo10727a.d(34): Error: undefined identifier `Frop`\n---\n*/\n\nimport imports.foo10727a;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10727b.d",
    "content": "// REQUIRED_ARGS: -c\n/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/foo10727b.d(25): Error: undefined identifier `Frop`\n---\n*/\n\nimport imports.foo10727b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10770.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10770.d(13): Error: enum `ice10770.E2` is forward referenced looking for base type\nfail_compilation/ice10770.d(13):        while evaluating: `static assert(is(E2 e == enum))`\n---\n*/\n\nenum E1 : int;\nstatic assert(is(E1 e == enum) && is(e == int));\n\nenum E2;\nstatic assert(is(E2 e == enum));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10922.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10922.d(9): Error: function `ice10922.__lambda4(const(uint) n)` is not callable using argument types `()`\n---\n*/\n\nauto fib = (in uint n) pure nothrow {\n    enum self = __traits(parent, {});\n    return (n < 2) ? n : self(n - 1) + self(n - 2);\n};\n\nvoid main()\n{\n    auto n = fib(39);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10938.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10938.d(12): Error: no property `opts` for type `ice10938.C`\n---\n*/\n\nclass C\n{\n    this()\n    {\n        this.opts[\"opts\"] = 1;\n    }\n\n    auto opDispatch(string field : \"opts\")()\n    {\n        return this.opts;  // ICE -> compile time error\n    }\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice10949.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice10949.d(12): Error: Using the result of a comma expression is not allowed\nfail_compilation/ice10949.d(12): Error: array index 3 is out of bounds `[5, 5][0 .. 2]`\nfail_compilation/ice10949.d(12): Error: array index 17 is out of bounds `[2, 3][0 .. 2]`\nfail_compilation/ice10949.d(12):        while evaluating: `static assert((((([5, 5][3] + global - global) * global / global % global >> global & global | global) ^ global) == 9 , [2, 3][17]) || [3, 3, 3][9] is 4 && [[1, 2, 3]][4].length)`\n---\n*/\n\nint global;\nstatic assert((((((([5,5][3] + global - global)*global/global%global)>>global) &global|global)^global) == 9, [2,3][17]) || ([3,3,3][9] is 4) && ([[1,2,3]][4]).length);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11086.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11086.d(10): Error: template instance `foo!A` template `foo` is not defined\n---\n*/\n\nstruct A\n{\n    foo!(A) l1,l2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11136.d",
    "content": "// EXTRA_SOURCES: imports/bar11136.d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/bar11136.d(1): Error: package name 'ice11136' conflicts with usage as a module name in file fail_compilation/ice11136.d\n---\n*/\n\nmodule ice11136;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11153.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11153.d(11): Error: function declaration without return type. (Note that constructors are always named `this`)\nfail_compilation/ice11153.d(11): Error: no identifier for declarator `foo()`\n---\n*/\n\nstruct S\n{\n    foo(T)() {}\n    // Parser creates a TemplateDeclaration object with ident == NULL\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11404.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11404.d(10): Error: cannot have associative array of `(int, int)`\n---\n*/\ntemplate TypeTuple(TL...) { alias TL TypeTuple; }\nvoid main()\n{\n    TypeTuple!(int, int)[string] my_map;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice1144.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice1144.d(14): Error: undefined identifier `a`\nfail_compilation/ice1144.d(23): Error: template instance `ice1144.testHelper!(\"hello\", \"world\")` error instantiating\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=1144\n// ICE(template.c) template mixin causes DMD crash\nchar[] testHelper(A ...)()\n{\n    char[] result;\n    foreach (t; a)\n    {\n        result ~= \"int \" ~ t ~ \";\\n\";\n    }\n    return result;\n}\n\nvoid main()\n{\n    mixin(testHelper!(\"hello\", \"world\")());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11472.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11472.d(13): Error: template instance `fun2!fun` `fun2` is not a template declaration, it is a function\nfail_compilation/ice11472.d(18): Error: template instance `ice11472.fun1!(fun3)` error instantiating\n---\n*/\n\nvoid fun3() {}\nvoid fun2(string a) {}\nvoid fun1(alias fun=fun3)()\n{\n    \"a\".fun2!fun;\n}\n\nvoid main()\n{\n    fun1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11513a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/ice11513x.d(1): Error: package name 'ice11513a' conflicts with usage as a module name in file fail_compilation/ice11513a.d\n---\n*/\n\nmodule ice11513a;\n\nimport imports.ice11513x;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11513b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/ice11513y.d(1): Error: package name 'ice11513b' conflicts with usage as a module name in file fail_compilation/ice11513b.d\n---\n*/\n\nmodule ice11513b;\n\nimport imports.ice11513y;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11518.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11518.d(17): Error: class `ice11518.B` matches more than one template declaration:\nfail_compilation/ice11518.d(12):     `B(T : A!T)`\nand\nfail_compilation/ice11518.d(13):     `B(T : A!T)`\n---\n*/\n\nclass A(T) {}\nclass B(T : A!T) {}\nclass B(T : A!T) {}\n\nvoid main()\n{\n    new B!(A!void);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11552.d",
    "content": "/*\nREQUIRED_ARGS: -o-\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/ice11552.d(14): Error: label `label` is undefined\nfail_compilation/ice11552.d(17):        called from here: `test11552()`\nfail_compilation/ice11552.d(17):        while evaluating: `static assert(test11552())`\n---\n*/\n\nint test11552()\n{\n    goto label;\n    return 1;\n}\nstatic assert(test11552());\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11553.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11553.d(22): Error: recursive template expansion while looking for `A!().A()`\n---\n*/\n\n\ntemplate A(alias T)\n{\n    template A()\n    {\n        alias A = T!();\n    }\n}\n\ntemplate B()\n{\n    alias B = A!(.B);\n}\n\nstatic if (A!B) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11626.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11626.d(8): Error: undefined identifier `Bar`\n---\n*/\n\nvoid foo(in ref Bar) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11726.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11726.d(16): Error: undefined identifier `x`\n---\n*/\n\nstruct S\n{\n    auto opDispatch(string fn, Args...)(Args args)\n    {\n    }\n}\n\nvoid main() {\n    S().reserve(x.foo());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11790.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11790.d(8): Error: cannot pass type `string` as a function argument\n---\n*/\n\nstring[string] crash = new string[string];\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11793.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11793.d(11): Error: circular reference to `ice11793.Outer.outer`\n---\n*/\n\nclass Outer\n{\n    int foo;\n    Outer outer = new Outer();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11822.d",
    "content": "\n\n// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11822.d(32): Deprecation: function `ice11822.d` is deprecated\nfail_compilation/ice11822.d(21):        instantiated from here: `S!(__lambda1)`\nfail_compilation/ice11822.d(32):        instantiated from here: `g!((n) => d(i))`\n---\n*/\n\nstruct S(alias pred)\n{\n    this(int) { pred(1); }\n    void f()  { pred(2); }\n}\n\nauto g(alias pred)()\n{\n    return S!pred(3);\n}\n\ndeprecated bool d(int)\n{\n    return true;\n}\n\nauto h()\n{\n    int i;\n    return g!(n => d(i))();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11849b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11849b.d(11): Error: circular reference to enum base type `DWORD1`\nfail_compilation/ice11849b.d(11): Error: `DWORD1` is used as a type\nfail_compilation/ice11849b.d(16): Error: circular reference to enum base type `typeof(DWORD2)`\n---\n*/\nenum REG_DWORD = 1;\n\nenum : DWORD1\n{\n    DWORD1 = REG_DWORD\n}\n\nenum : typeof(DWORD2)\n{\n    DWORD2 = REG_DWORD\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11850.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11850.d(14): Error: incompatible types for `(a) < ([0])`: `uint[]` and `int[]`\nfail_compilation/imports/a11850.d(9):        instantiated from here: `FilterResult!(__lambda1, uint[][])`\nfail_compilation/ice11850.d(14):        instantiated from here: `filter!(uint[][])`\n---\n*/\n\nimport imports.a11850 : filter;\n\nvoid main()\n{\n    filter!(a => a < [0])([[0u]]);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11919.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11919.d(17): Error: cannot interpret `foo` at compile time\nfail_compilation/imports/a11919.d(4): Error: template instance `a11919.doBar!(Foo).doBar.zoo!(t)` error instantiating\nfail_compilation/imports/a11919.d(11):        instantiated from here: `doBar!(Foo)`\nfail_compilation/ice11919.d(25):        instantiated from here: `doBar!(Bar)`\n---\n*/\n\nimport imports.a11919;\n\nenum foo;\n\nclass Foo\n{\n    @foo bool _foo;\n}\n\nclass Bar : Foo {}\n\nvoid main()\n{\n    auto bar = new Bar();\n    bar.doBar;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11922.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11922.d(11): Error: undefined identifier `a`\nfail_compilation/ice11922.d(17): Error: template instance `ice11922.S.f!int` error instantiating\n---\n*/\n\nstruct S\n{\n    auto f(B)(B) { return a; }\n}\n\nvoid main()\n{\n    S s;\n    s.f(5);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11926.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11926.d(11): Error: no identifier for declarator `const(a)`\nfail_compilation/ice11926.d(12): Error: no identifier for declarator `const(b)`\n---\n*/\n\nenum\n{\n    const a = 1,\n    const b = 2\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11944.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11944.d(12): Error: template instance `doCommand!(func)` does not match template declaration `doCommand(f, T)(f, T arg)`\n---\n*/\n\nvoid func(int var) {}\n\nvoid doCommand(f, T)(f, T arg) {}\n\nauto var = &doCommand!func;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11963.d",
    "content": "A(\"\")=\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11965.d",
    "content": "u[{b*A,\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11967.d",
    "content": "[F(%g{@\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11968.d",
    "content": "void main() {  delete __FILE__  ; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11969.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice11969.d(9): Error: undefined identifier `index`\nfail_compilation/ice11969.d(10): Error: undefined identifier `cond`\nfail_compilation/ice11969.d(11): Error: undefined identifier `msg`\n---\n*/\nvoid test1() { mixin ([index]); }\nvoid test2() { mixin (assert(cond)); }\nvoid test3() { mixin (assert(0, msg)); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11974.d",
    "content": "void main() {  0 = __LINE__ ^^ [ 0 ] ; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice11982.d",
    "content": "void main() { new scope ( funk ) function }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12040.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12040.d(8): Error: circular reference to `ice12040.lol`\n---\n*/\n\nbool[lol.length] lol;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12158.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12158.d(7): Error: module `object` import `nonexisting` not found\n---\n*/\nimport object : nonexisting;\nauto x = nonexisting.init;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12174.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12174.d(12): Error: no property `sum` for type `int[]`\nfail_compilation/ice12174.d(20): Error: CTFE failed because of previous errors in `this`\nfail_compilation/ice12174.d(13):        called from here: `filter([1, 2, 3])`\n---\n*/\n\nvoid main()\n{\n    enum foo3 = (int n) => [1,2,3].sum;\n    enum bar3 = [1,2,3].filter!(n => n % foo3(n) == 0);\n}\n\ntemplate filter(alias pred)\n{\n    auto filter(Range)(Range rs)\n    {\n        return FilterResult!(pred, Range)(rs);\n    }\n}\n\nprivate struct FilterResult(alias pred, R)\n{\n    R _input;\n\n    this(R r)\n    {\n        _input = r;\n        while (_input.length && !pred(_input[0]))\n        {\n            _input = _input[1..$];\n        }\n    }\n\n    @property bool empty() { return _input.length == 0; }\n\n    @property auto ref front()\n    {\n        return _input[0];\n    }\n\n    void popFront()\n    {\n        do\n        {\n            _input = _input[1..$];\n        } while (_input.length && !pred(_input[0]));\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12235.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12235.d(14): Error: forward reference to inferred return type of function `__lambda1`\nfail_compilation/ice12235.d(15): Error: forward reference to inferred return type of function `__lambda1`\nfail_compilation/ice12235.d(15):        while evaluating `pragma(msg, __lambda1.mangleof)`\n---\n*/\n\nvoid main()\n{\n    (){\n        int x;\n        enum s = __traits(parent, x).mangleof;\n        pragma(msg, __traits(parent, x).mangleof);\n    }();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12350.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12350.d(15): Error: type `MyUDC` has no value\nfail_compilation/ice12350.d(30): Error: template instance `ice12350.testAttrs!(MyStruct)` error instantiating\n---\n*/\n\n\nenum MyUDC;\n\nstruct MyStruct\n{\n    int a;\n    @MyUDC int b;\n}\n\nvoid testAttrs(T)(const ref T t)\nif (is(T == struct))\n{\n    foreach (name; __traits(allMembers, T))\n    {\n        auto tr = __traits(getAttributes, __traits(getMember, t, name));\n    }\n}\n\nvoid main()\n{\n    MyStruct s;\n    testAttrs(s);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12362.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12362.d(12): Error: cannot interpret `foo` at compile time\n---\n*/\n\nenum foo;\n\nvoid main()\n{\n    enum bar = foo;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12397.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12397.d(12): Error: undefined identifier `tokenLookup`\n---\n*/\n\nstruct DSplitter\n{\n    enum Token : int\n    {\n        max = tokenLookup.length\n    }\n\n    immutable string[Token.max] tokenText;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12501.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12501.d(29): Error: function `ice12501.foo(int value)` is not callable using argument types `(int, int)`\nfail_compilation/ice12501.d(29): Error: function `ice12501.foo(int value)` is not callable using argument types `(int, int)`\nfail_compilation/ice12501.d(43): Error: template instance `ice12501.reduce!(foo, foo).reduce!(Tuple!(int, int), int[])` error instantiating\n---\n*/\n\nstruct Tuple(T...)\n{\n    alias Types = T;\n    T field;\n    alias field this;\n}\nTuple!A tuple(A...)(A args) { return typeof(return)(args); }\n\ntemplate reduce(fun...)\n{\n    auto reduce(Args...)(Args args)\n    {\n        alias seed = args[0];\n        alias r    = args[1];\n        Args[0] result = seed;\n        for (; r.length != 0; r = r[1..$])\n        {\n            foreach (i, Unused; Args[0].Types)\n            {\n                result[i] = fun[i](result[i], r[0]);\n            }\n        }\n        return result;\n    }\n}\n\nint foo(int value)\n{\n    return value;\n}\n\nvoid main()\n{\n    reduce!(foo, foo)(tuple(0, 0), [ 1 ]);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12534.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12534.d(14): Error: static assert:  `is(exprs[0 .. 0])` is false\n---\n*/\n\nalias TypeTuple(T...) = T;\n\nvoid main()\n{\n    int x, y;\n    alias exprs = TypeTuple!(x, y);\n    static assert(is(exprs[0..0]));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12539.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12539.d(15): Error: array index `[0]` is outside array bounds `[0 .. 0]`\n---\n*/\n\nalias TypeTuple(E...) = E;\n\nvoid main ()\n{\n    int[string] map;\n\n    alias Foo = TypeTuple!();\n    auto a = map[Foo[0]];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12574.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12574.d(40): Error: tuple index `2` exceeds length 2\nfail_compilation/ice12574.d(53): Error: template instance `ice12574.reduce!(\"a\", \"a\").reduce!(Tuple!(int, int, int))` error instantiating\n---\n*/\n\nstruct Tuple(T...)\n{\n    alias Types = T;\n    T field;\n    alias field this;\n}\nTuple!A tuple(A...)(A args) { return typeof(return)(args); }\n\ntemplate binaryFun(alias fun)\n{\n    static if (is(typeof(fun) : string))\n    {\n        auto binaryFun(ElementType1, ElementType2)(auto ref ElementType1 __a, auto ref ElementType2 __b)\n        {\n            mixin(\"alias \"~\"a\"~\" = __a ;\");\n            mixin(\"alias \"~\"b\"~\" = __b ;\");\n            return mixin(fun);\n        }\n    }\n    else\n    {\n        alias binaryFun = fun;\n    }\n}\n\ntemplate reduce(fun...)\n{\n    auto reduce(Seed)(Seed result)\n    {\n        foreach (i, Unused; Seed.Types)\n        {\n           result[i] = binaryFun!(fun[i])(1, 1); // here\n        }\n        return result;\n    }\n}\n\nint foo(int value)\n{\n    return value;\n}\n\nvoid main()\n{\n    reduce!(\"a\", \"a\")(tuple(1, 1, 1));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12581.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12581.d(21): Error: undefined identifier `undef`\n---\n*/\n\nstruct S\n{\n    int[3] a;\n    alias a this;\n}\nstruct T\n{\n    S s;\n    alias s this;\n}\nvoid main()\n{\n    T x;\n    x[] = (undef = 1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12673.d",
    "content": "void main()\n{\n    static assert(__traits(compiles, { abcd(); }));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12727.d",
    "content": "/*\nTEST_OUTPUT:\n----\nfail_compilation/ice12727.d(16): Error: alias `ice12727.IndexTuple!(1, 0).IndexTuple` recursive alias declaration\nfail_compilation/ice12727.d(23): Error: template instance `ice12727.IndexTuple!(1, 0)` error instantiating\nfail_compilation/ice12727.d(27):        instantiated from here: `Matrix!(float, 3)`\nfail_compilation/ice12727.d(28):        instantiated from here: `Vector!(float, 3)`\n----\n*/\n\ntemplate IndexTuple(int e, int s = 0, T...)\n{\n    static if (s == e)\n        alias IndexTuple = T;\n    else\n        alias IndexTuple = IndexTuple!(e);\n}\n\nstruct Matrix(T, int N = M)\n{\n    pure decomposeLUP()\n    {\n        foreach (j; IndexTuple!(1)) {}\n    }\n}\n\nalias Vector(T, int M) = Matrix!(T, M);\nalias Vector3 = Vector!(float, 3);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12827.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12827.d(10): Error: circular initialization of variable `ice12827.Test.i`\n---\n*/\n\nstruct Test\n{\n\timmutable int i = i;\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12836.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12836.d(9): Error: undefined identifier `C`\nfail_compilation/ice12836.d(9): Error: undefined identifier `K`\n---\n*/\n\nimmutable C L = 1 << K;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12838.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12838.d(27): Error: cannot implicitly convert expression `1` of type `int` to `string`\n---\n*/\n\nstruct Tuple(T...)\n{\n    T field;\n    alias field this;\n}\n\nstruct Data\n{\n    string a;\n}\n\ntemplate toTuple(T)\n{\n    mixin(`alias toTuple = Tuple!(string);`);\n}\n\nvoid main()\n{\n    toTuple!Data a;\n    a[0] = 1;   // ICE!\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12841.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12841.d(23): Error: `taskPool().amap(Args...)(Args args)` is not an lvalue and cannot be modified\nfail_compilation/ice12841.d(24): Error: `amap(Args...)(Args args)` is not an lvalue and cannot be modified\n---\n*/\n\n@property TaskPool taskPool() @trusted { return new TaskPool; }\n\nfinal class TaskPool\n{\n    template amap(functions...)\n    {\n        auto amap(Args...)(Args args)\n        {\n        }\n    }\n}\n\nvoid main()\n{\n    auto dg = &(taskPool.amap!\"a.result()\");\n    auto fp = &(TaskPool.amap!\"a.result()\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12850.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12850.d(12): Error: cannot implicitly convert expression `0` of type `int` to `string`\n---\n*/\nalias TypeTuple(TL...) = TL;\n\nvoid main()\n{\n    int[string] arr;\n    alias staticZip = TypeTuple!(arr[0]);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12902.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12902.d(20): Error: variable `ice12902.main.__dollar` type `void` is inferred from initializer `s.opDollar()`, and variables cannot be of type `void`\nfail_compilation/ice12902.d(20): Error: expression `s.opDollar()` is `void` and has no value\n---\n*/\n\nstruct S\n{\n    void opDollar() { }\n    void opIndex() { }\n    void opIndexAssign() { }\n    void opSliceAssign() { }\n}\n\nvoid main()\n{\n    S s;\n    s[] = s[$];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice12907.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice12907.d(10): Error: template lambda has no type\n---\n*/\n\nauto f(void function() g)\n{\n    return x => (*g)();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13024.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13024.d(15): Error: cannot implicitly convert expression `t.x` of type `A` to `B`\n---\n*/\n\nenum A { a }\nenum B { b }\nstruct T { A x; B y; }\nvoid main()\n{\n    T t;\n    auto r1 = [cast(int)(t.x), cast(int)(t.y)]; // OK\n    auto r3 = [t.x, t.y]; // crash\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13027.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13027.d(9): Error: template instance `b!\"c\"` template `b` is not defined\n---\n*/\nvoid main()\n{\n    scope a = b!\"c\";\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13081.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13081.d(17): Error: undefined identifier `node`\nfail_compilation/ice13081.d(17): Error: undefined identifier `data`\nfail_compilation/ice13081.d(17): Error: undefined identifier `node`\nfail_compilation/ice13081.d(28): Error: template instance `ice13081.Cube!(SparseDataStore)` error instantiating\n---\n*/\n\nstruct Cube(StorageT)\n{\n    StorageT datastore;\n    alias datastore this;\n    auto seed()\n    {\n        this[] = node.data ? data : node.data;\n    }\n}\n\nclass SparseDataStore\n{\n    auto opSlice() {}\n}\n\nvoid main()\n{\n    Cube!SparseDataStore c;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13131.d",
    "content": "// EXTRA_SOURCES: imports/a13131parameters.d imports/a13131elec.d\n/*\nTEST_OUTPUT:\n---\n+A\n+B\nfail_compilation/imports/a13131elec.d(10): Error: template instance `elecConnOf!gconn` template `elecConnOf` is not defined\n-B\n-A\n---\n*/\n\nvoid main()\n{\n    struct Connectivity {}\n    auto L = Connectivity();\n\n    import imports.a13131elec;          // [1] import\n    L.initElec;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13220.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13220.d(22): Error: template instance `test!0` does not match template declaration `test(T)()`\n---\n*/\n\nstruct Tuple(T...)\n{\n    T field;\n    alias field this;\n}\n\ntemplate test(T)\n{\n    bool test() { return false; };\n}\n\nvoid main()\n{\n    Tuple!bool t;\n    t[0] = test!0();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13221.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13221.d(20): Error: variable `r` cannot be read at compile time\n---\n*/\n\nstruct Tuple(T...)\n{\n    T field;\n    alias field this;\n}\n\ntemplate test(T) {}\n\nvoid main()\n{\n    foreach (r; 0 .. 0)\n    {\n        enum i = r;\n        test!(Tuple!bool[i]);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13225.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13225.d(12): Error: mixin `ice13225.S.M!(function (S _param_0) => 0)` does not match template declaration `M(T)`\nfail_compilation/ice13225.d(16): Error: undefined identifier `undefined`\n---\n*/\nmixin template M(T) {}\n\nstruct S\n{\n    mixin M!((typeof(this)) => 0);\n}\nstruct T\n{\n    mixin M!(() => undefined);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13311.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/a13311.d(8): Error: undefined identifier `PieceTree`\n---\n*/\nmodule ice13311;\n\nstruct TextPiece\n{\n    import imports.a13311;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13356.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13356.d(32): Error: template instance `Algebraic!(Tuple!(List))` recursive template expansion\nfail_compilation/ice13356.d(15): Error: template instance `ice13356.isPrintable!(List)` error instantiating\nfail_compilation/ice13356.d(33):        instantiated from here: `Tuple!(List)`\n---\n*/\n\nstruct Tuple(Types...)\n{\n    Types expand;\n    alias expand this;\n\n    static if (isPrintable!(Types[0]))\n    {\n    }\n}\n\n// T == Tuple!List, and accessing its .init will cause unresolved forward reference\nenum bool isPrintable(T) = is(typeof({ T t; }));\n\nstruct Algebraic(AllowedTypesX...)\n{\n    alias AllowedTypes = AllowedTypesX;\n\n    double x;   // dummy for the syntax Payload(d)\n}\n\nstruct List\n{\n    alias Payload = Algebraic!(\n        Tuple!(List)\n    );\n\n    Payload payload;\n\n    this(double d) { payload = Payload(d); }\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13382.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13382.d(18): Error: incompatible types for `(a) == (0)`: `int[]` and `int`\nfail_compilation/ice13382.d(19): Error: incompatible types for `(a) >= (0)`: `int[]` and `int`\nfail_compilation/ice13382.d(20): Error: incompatible types for `(0) == (a)`: `int` and `int[]`\nfail_compilation/ice13382.d(21): Error: incompatible types for `(0) >= (a)`: `int` and `int[]`\nfail_compilation/ice13382.d(22): Error: incompatible types for `(a) is (0)`: `int[]` and `int`\nfail_compilation/ice13382.d(23): Error: incompatible types for `(a) !is (0)`: `int[]` and `int`\nfail_compilation/ice13382.d(24): Error: incompatible types for `(0) is (a)`: `int` and `int[]`\nfail_compilation/ice13382.d(25): Error: incompatible types for `(0) !is (a)`: `int` and `int[]`\n---\n*/\n\nvoid main ()\n{\n    int[] a;\n    if (a == 0) {}\n    if (a >= 0) {}\n    if (0 == a) {}\n    if (0 >= a) {}\n    if (a  is 0) {}\n    if (a !is 0) {}\n    if (0  is a) {}\n    if (0 !is a) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13385.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13385.d(9): Error: protection attribute `package(a)` does not bind to one of ancestor packages of module `ice13385`\n---\n*/\nmodule ice13385;\n\npackage(a) void foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13459.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13459.d(12): Error: undefined identifier `B`\nfail_compilation/ice13459.d(18): Error: none of the overloads of `opSlice` are callable using argument types `(int, int)`, candidates are:\nfail_compilation/ice13459.d(11):        `ice13459.A.opSlice()`\n---\n*/\nstruct A\n{\n    auto opSlice() const {}\n    auto opSlice() { return B; }\n}\n\nvoid main()\n{\n    auto df = A();\n    foreach (fi; df[0..0]) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13465a.d",
    "content": "// REQUIRED_ARGS: -o-\n// EXTRA_SOURCES: imports/a13465.d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/a13465.d(10): Error: cannot infer type from template instance `isMaskField!()`\nfail_compilation/ice13465a.d(17): Error: template instance `imports.a13465.isMatchingMaskField!()` error instantiating\n---\n*/\n\nmodule ice13465a;\n\nimport imports.a13465;\n\nauto createCheckpointMixins()\n{\n    enum b = isMatchingMaskField!();\n}\n\nimmutable checkpointMixins = createCheckpointMixins;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13465b.d",
    "content": "// REQUIRED_ARGS: -o-\n// EXTRA_SOURCES: imports/b13465.d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/b13465.d(10): Error: cannot infer type from template instance `isMaskField!()`\nfail_compilation/ice13465b.d(17): Error: template instance `imports.b13465.isMatchingMaskField!()` error instantiating\n---\n*/\n\nmodule ice13465b;\n\nimport imports.b13465;\n\nauto createCheckpointMixins()\n{\n    enum b = isMatchingMaskField!();\n}\n\nimmutable checkpointMixins = createCheckpointMixins;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13563.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13563.d(23): Error: undefined identifier `z` in module `ice13563`\n---\n*/\n\nstruct Payload\n{\n    void opIndex(K)(K i) {}\n    void opIndexAssign(T, N)(T value, N i) {}\n}\n\nstruct Value\n{\n    Payload payload;\n    alias payload this;\n}\n\nvoid main()\n{\n    Value v;\n    v[\"name\"] = .z();           // ICE\n  //v[\"name\"] = z();            // OK\n  //v.opIndex(\"name\") = .z();   // OK\n  //v.payload[\"name\"] = .z();   // OK\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice1358.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice1358.d(29): Error: invalid UTF character \\U80000000\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=1358\n// ICE(root.c) on Unicode codepoints greater than 0x7FFFFFFF\n/* 1358. Assertion failure: '0' on line 1548 in file '..\\root\\root.c'\nThis one is trivial.\nPATCH(lexer.c, Lexer::escapeSequence()).\n--- lexer.c (revision 24)\n+++ lexer.c (working copy)\n@@ -1281,8 +1281,10 @@\n                            break;\n                        }\n                     }\n-                    if (ndigits != 2 && !utf_isValidDchar(v))\n+                        if (ndigits != 2 && !utf_isValidDchar(v)) {\n                         error(\"invalid UTF character \\\\U%08x\", v);\n+                        v = 0; // prevent ICE\n+                        }\n                     c = v;\n                 }\n                 else\n\n*/\nauto bla = \"\\U80000000\";\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13644.d",
    "content": "\nstruct Tuple(T...)\n{\n    T field;\n    alias field this;\n}\n\nTuple!(string, string)[] foo()\n{\n    Tuple!(string, string)[] res;\n    return res;\n}\n\nvoid main()\n{\n    foreach (string k2, string v2; foo())\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13788.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13788.d(11): Error: pragma `mangle` string expected for mangled name\nfail_compilation/ice13788.d(12): Error: `string` expected for mangled name, not `(1)` of type `int`\nfail_compilation/ice13788.d(13): Error: pragma `mangle` zero-length string not allowed for mangled name\nfail_compilation/ice13788.d(14): Error: pragma `mangle` mangled name characters can only be of type `char`\n---\n*/\n\npragma(mangle) void f1();\npragma(mangle, 1) void f2();\npragma(mangle, \"\") void f3();\npragma(mangle, \"a\"w) void f4();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13816.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13816.d(15): Error: alias `ice13816.ItemProperty!().ItemProperty` recursive alias declaration\nfail_compilation/ice13816.d(20): Error: template instance `ice13816.ItemProperty!()` error instantiating\n---\n*/\n\nalias TypeTuple(T...) = T;\n\ntemplate ItemProperty()\n{\n    static if (true)\n    {\n        alias ItemProperty = TypeTuple!(ItemProperty!());\n    }\n}\nvoid main()\n{\n    alias items = ItemProperty!();\n\n    enum num = items.length;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13835.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13835.d(15): Error: value of `this` is not known at compile time\nfail_compilation/ice13835.d(21): Error: template instance `ice13835.Foo!int` error instantiating\n---\n*/\n\nclass Foo(T)\n{\n    private T* _data;\n\n    final private void siftUp(int position) nothrow\n    {\n        static T crash = *(this._data + position);\n    }\n}\n\nvoid main()\n{\n    auto heap = new Foo!(int);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13921.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13921.d(13): Error: undefined identifier `undefined_identifier`\nfail_compilation/ice13921.d(25): Error: template instance `ice13921.S!string` error instantiating\n---\n*/\n\nstruct S(N)\n{\n    void fun()\n    {\n        undefined_identifier;\n        // or anything that makes the instantiation fail\n    }\n\n}\n\nvoid test(T)(S!T)\n{\n}\n\nvoid main()\n{\n    S!string g;\n    test(g);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice13987.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice13987.d(9): Error: cannot use array to initialize `S`\n---\n*/\n\nstruct S {}\nS s = [{}];\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14055.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14055.d(16): Error: uninitialized variable `foo` cannot be returned from CTFE\n---\n*/\n\nstruct S\n{\n    static returnsFoo()\n    {\n        uint[1] foo = void;\n        return foo;\n    }\n\n    static enum fooEnum = returnsFoo();\n    static uint[1] fooArray = fooEnum[];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14096.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14096.d(29): Error: cannot access frame pointer of `ice14096.main.Baz!((i) => i).Baz`\nfail_compilation/ice14096.d(23): Error: template instance `ice14096.foo!(Tuple!(Baz!((i) => i))).foo.bar!(t)` error instantiating\nfail_compilation/ice14096.d(40):        instantiated from here: `foo!(Tuple!(Baz!((i) => i)))`\n---\n*/\n\nstruct Tuple(Types...)\n{\n    Types expand;\n    alias expand this;\n    alias field = expand;\n}\nTuple!T tuple(T...)(T args)\n{\n    return typeof(return)(args);\n}\n\nauto foo(T)(T t)\n{\n    bar!t();\n}\n\nauto bar(alias s)()\n{\n    // default construction is not possible for: Tuple!(Baz!(i => i))\n    typeof(s) p;\n}\n\nstruct Baz(alias f)\n{\n    void g() {}\n}\n\nvoid main()\n{\n    auto t = tuple(Baz!(i => i)());\n    foo(t);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14116.d",
    "content": "// EXTRA_SOURCES: imports/a14116.d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/a14116.d(3): Error: module `ice14116.ice14116` from file fail_compilation/ice14116.d must be imported with 'import ice14116.ice14116;'\n---\n*/\n\nmodule ice14116.ice14116;\n\nvoid foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14130.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14130.d(10): Error: undefined identifier `Undef`\nfail_compilation/ice14130.d(14): Error: template `ice14130.foo` cannot deduce function from argument types `!()(int)`, candidates are:\nfail_compilation/ice14130.d(10):        `ice14130.foo(R, F = Undef)(R r, F s = 0)`\n---\n*/\n\nF foo(R, F = Undef)(R r, F s = 0) {}\n\nvoid main()\n{\n    0.foo;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14146.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14146.d(15): Error: constructor `ice14146.Array.this` default constructor for structs only allowed with `@disable`, no body, and no parameters\n---\n*/\n\nstruct RangeT(A)\n{\n    A[1] XXXouter;\n}\n\nstruct Array\n{\n    this()\n    {\n    }\n\n    alias Range = RangeT!Array;\n\n    bool opEquals(Array)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14177.d",
    "content": "/*\nTEST_OUTPUT:\n----\nfail_compilation/ice14177.d(8): Error: alias `ice14177.Primitive` recursive alias declaration\n----\n*/\n\nalias Primitive = Atom*;\nalias Atom = Primitive;\n\nvoid main()\n{\n    Atom atom;\n    atom;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14185.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14185.d(12): Error: cannot implicitly convert expression `this` of type `Mutexed` to `Mutexed*`\n---\n*/\n\nstruct Mutexed\n{\n\tauto acquire ()\n\t{\n\t\treturn Lock (this);\n\t}\n\talias acquire this;\n\n\tstruct Lock\n\t{\n\t\tMutexed* source;\n\t}\n}\nvoid main ()\n{\n\tMutexed x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14272.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14272.d(11): Error: circular initialization of variable `ice14272.A14272!1.A14272.tag`\nfail_compilation/ice14272.d(14): Error: template instance `ice14272.A14272!1` error instantiating\n---\n*/\n\nstruct A14272(int tag)\n{\n    enum int tag = tag;\n}\n\nalias a14272 = A14272!1;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14424.d",
    "content": "// REQUIRED_ARGS: -o- -unittest\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14424.d(12): Error: `tuple(__unittest_L3_C1)` has no effect\n---\n*/\n\nvoid main()\n{\n    import imports.a14424;\n    __traits(getUnitTests, imports.a14424);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14446.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n// EXTRA_SOURCES: extra-files/a14446.d\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/extra-files/a14446.d(5): Error: module `x14446` from file fail_compilation/ice14446.d must be imported with 'import x14446;'\n---\n*/\n\nmodule x14446;\n\nstruct CDB {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14621.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14621.d(22): Error: static assert:  `false` is false\nfail_compilation/ice14621.d(28):        instantiated from here: `erroneousTemplateInstantiation!()`\n---\n*/\n\nvoid main()\n{\n    S s;\n    s.foo();\n}\n\nstruct S\n{\n    float[] array;\n    alias array this;\n\n    template erroneousTemplateInstantiation()\n    {\n        static assert(false);\n    }\n\n    void foo()\n    {\n        S ret;\n        ret[] = erroneousTemplateInstantiation!();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14642.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14642.d(47): Error: undefined identifier `errorValue`\nfail_compilation/ice14642.d(23): Error: template instance `ice14642.X.NA!()` error instantiating\n---\n*/\n\nalias TypeTuple(T...) = T;\n\nstruct X\n{\n    static struct NA()\n    {\n        X x;\n\n        void check()\n        {\n            x.func();\n        }\n    }\n\n    alias na = NA!();\n\n    auto func()\n    {\n        Y* p;\n        p.func();\n    }\n}\n\nstruct Y\n{\n    mixin Mix;\n}\n\ntemplate Mix()\n{\n    void func()\n    {\n        auto z = Z(null);\n    }\n}\n\nstruct Type(size_t v) {}\n\nenum errVal = errorValue;\n\nstruct Z\n{\n    Type!errVal v;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14844.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14844.d(20): Error: template `opDispatch(string name)` has no members\n---\n*/\n\nstruct Typedef\n{\n    template opDispatch(string name)\n    {\n        static if (true)\n        {\n        }\n    }\n}\n\nvoid runUnitTestsImpl()\n{\n    foreach (x; __traits(allMembers, Typedef.opDispatch))\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14907.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14907.d(14): Error: struct `ice14907.S(int v = S)` recursive template expansion\nfail_compilation/ice14907.d(19):        while looking for match for `S!()`\nfail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion\nfail_compilation/ice14907.d(20):        while looking for match for `f!()`\nfail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion\nfail_compilation/ice14907.d(21): Error: template `ice14907.f` cannot deduce function from argument types `!()()`, candidates are:\nfail_compilation/ice14907.d(15):        `ice14907.f(int v = f)()`\n---\n*/\n\nstruct S(int v = S) {}\nvoid f(int v = f)() {}\n\nvoid main()\n{\n    S!() s;     // OK <- ICE\n    f!()();     // OK <- ICE\n    f();        // OK <- ICE\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14923.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14923.d(22): Error: function `ice14923.parse(C a)` is not callable using argument types `(A)`\nfail_compilation/ice14923.d(22):        cannot pass argument `b` of type `ice14923.A` to parameter `C a`\nfail_compilation/ice14923.d(22):        instantiated from here: `bar!((b) => parse(b))`\n---\n*/\n\nauto bar(alias fun)()\n{\n    size_t counter;\n    scope(exit) counter++;\n\n    Object a2;\n    if (auto ai = cast(A)a2) return fun(ai);\n    if (auto ai = cast(B)a2) return fun(ai);\n}\n\nvoid parse(C a)\n{\n    bar!(b => parse(b))();\n}\n\nclass A {}\n\nclass C {}\n\nclass B : C {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice14929.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice14929.d(45): Error: `cast(Node)(*this.current).items[this.index]` is not an lvalue and cannot be modified\nfail_compilation/ice14929.d(88): Error: template instance `ice14929.HashMap!(ulong, int).HashMap.opBinaryRight!\"in\"` error instantiating\nfail_compilation/ice14929.d(92):        instantiated from here: `HashmapComponentStorage!int`\nfail_compilation/ice14929.d(92): Error: template instance `ice14929.isComponentStorage!(HashmapComponentStorage!int, int)` error instantiating\nfail_compilation/ice14929.d(92):        while evaluating: `static assert(isComponentStorage!(HashmapComponentStorage!int, int))`\n---\n*/\n\nstruct HashMap(K, V)\n{\n    V* opBinaryRight(string op)(K key) const if (op == \"in\")\n    {\n        size_t index;\n        foreach (ref node; buckets[index].range)\n        {\n            return &(node.value);\n        }\n        return null;\n    }\n\n    struct Node\n    {\n        K key;\n        V value;\n    }\n\n    alias Bucket = UnrolledList!(Node);\n    Bucket[] buckets;\n}\n\nstruct UnrolledList(T)\n{\n    Range range() const pure\n    {\n        return Range(_front);\n    }\n\n    static struct Range\n    {\n        ref T front() const @property\n        {\n            return cast(T) current.items[index];\n        }\n        void popFront() pure\n        {\n        }\n        bool empty() const pure @property\n        {\n            return true;\n        }\n        const(Node)* current;\n        size_t index;\n    }\n\n    Node* _front;\n\n    static struct Node\n    {\n        ContainerStorageType!T[10] items;\n    }\n}\n\ntemplate ContainerStorageType(T)\n{\n    alias ContainerStorageType = T;\n}\n\ntemplate isComponentStorage(CS, C)\n{\n    enum bool isComponentStorage = is(typeof(\n    (inout int = 0)\n    {\n        CS cs = CS.init;\n        ulong eid;\n        cs.add(eid, C.init);\n    }));\n}\n\nstruct HashmapComponentStorage(ComponentType)\n{\n    private HashMap!(ulong, ComponentType) components;\n\n    void add(ulong eid, ComponentType component)\n    {\n        assert(eid !in components);\n    }\n}\n\nstatic assert(isComponentStorage!(HashmapComponentStorage!int, int));\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15002.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice15002.d(10): Error: array index 5 is out of bounds `x[0 .. 3]`\nfail_compilation/ice15002.d(10): Error: array index 5 is out of bounds `x[0 .. 3]`\n---\n*/\n\nint[][3] x = [];\nint* p = &x[5][0];\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15092.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice15092.d(13): Error: struct `ice15092.A.S` conflicts with struct `ice15092.A.S` at fail_compilation/ice15092.d(12)\nfail_compilation/ice15092.d(16): Error: class `ice15092.A.C` conflicts with class `ice15092.A.C` at fail_compilation/ice15092.d(15)\nfail_compilation/ice15092.d(19): Error: interface `ice15092.A.I` conflicts with interface `ice15092.A.I` at fail_compilation/ice15092.d(18)\n---\n*/\n\nclass A\n{\n    struct S {}\n    struct S {}\n\n    class C {}\n    class C {}\n\n    interface I {}\n    interface I {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15127.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice15127.d(17): Error: basic type expected, not `struct`\nfail_compilation/ice15127.d(17): Error: identifier expected for template value parameter\nfail_compilation/ice15127.d(17): Error: found `struct` when expecting `)`\nfail_compilation/ice15127.d(17): Error: found `ExampleStruct` when expecting `=`\nfail_compilation/ice15127.d(17): Error: semicolon expected following auto declaration, not `)`\nfail_compilation/ice15127.d(17): Error: declaration expected, not `)`\n---\n*/\n\nstruct ExampleStruct(S) { }\n\ntemplate ExampleTemplate(K)\n{\n    enum ExampleTemplate(struct ExampleStruct(K)) = K;\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15172.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice15172.d(14): Error: constructor `ice15172.ThreadError.this` no match for implicit `super()` call in constructor\n---\n*/\n\n// 1. ClassDeclaration.semantic\nclass ThreadError : Error\n{\n    // 2. FuncDeclaration.semantic\n    // 4. FuncDeclaration.semantic3\n    //    --> error happens\n    this(string)\n    {\n    }\n}\n\n// 3. FuncDeclaration.semantic\n// 5. FuncDeclaration.semantic3\nvoid onThreadError()\n{\n    // 6. NewExp.semantic\n    //    --> cd.members.errors == false, cd.members.semantic3Errors == true\n    //    BUT, The ThreadError class constructor is not a template function, so\n    //    the errors inside its function body won't be associated with the validness of this NewExp.\n    //    Therefore, converting the semantic3Error to ErrorExp is not correct.\n    // 7. ctfeInterpret\n    //    Finally, FuncDeclaration::interpret may encounter a function which is semantic3Errors == true. So\n    //    7a. functionSemantic3() should return false if semantic3Errors is true.\n    //    7b. the function body errors may not happen during ctfeInterpret call and global.errors could be unincremented.\n    __gshared auto ThreadError = new ThreadError(null);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15239.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice15239.d(21): Error: cannot interpret `opDispatch!\"foo\"` at compile time\nfail_compilation/ice15239.d(21): Error: bad type/size of operands `__error`\n---\n*/\n\nstruct T\n{\n    template opDispatch(string Name, P...)\n    {\n        static void opDispatch(P) {}\n    }\n}\n\nvoid main()\n{\n    version(GNU)\n    {\n        asm\n        {\n            \"\" : : \"r\" T.foo;\n        }\n    }\n    else\n    {\n        asm\n        {\n            call T.foo;\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15317.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ice15317.d(11): Error: undefined identifier `fun`\n---\n*/\n\nvoid main()\n{\n    alias f = fun;\n    auto x1 = &f;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15332.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice15332.d(16): Error: need `this` for `fun` of type `int()`\nfail_compilation/ice15332.d(17): Error: need `this` for `var` of type `int`\n---\n*/\n\nclass C\n{\n    int fun() { return 5; }\n    int var;\n\n    void test()\n    {\n        int a1 = function() { return fun; }();\n        int a2 = function() { return var; }();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15441.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice15441.d(24): Error: variable `ice15441.main.__front3` type `void` is inferred from initializer `__r2.front()`, and variables cannot be of type `void`\nfail_compilation/ice15441.d(24): Error: expression `__r2.front()` is `void` and has no value\nfail_compilation/ice15441.d(24): Error: `s1.front` is `void` and has no value\nfail_compilation/ice15441.d(27): Error: cannot infer argument types, expected 1 argument, not 2\n---\n*/\n\nstruct S1\n{\n    auto front()() {}\n}\n\nstruct S2\n{\n    auto front()() { return 1; }\n}\n\nvoid main()\n{\n    S1 s1;\n    foreach (p, e; s1) {}\n\n    S2 s2;\n    foreach (p, e; s2) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15688.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ice15688.d(12): Error: undefined identifier `mappings`\nfail_compilation/ice15688.d(12): Error: function expected before `()`, not `0` of type `int`\n---\n*/\n\nvoid main()\n{\n    (mappings, 0)();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15788.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice15788.d(17): Error: none of the overloads of `iota` are callable using argument types `!()(S, S)`\n---\n*/\n\nimport imports.range15788 : iota;\n\nvoid iota() {}\n\nstruct S {}\n\nvoid main()\n{\n    S s;\n    iota(s, s);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15816.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/a15816.d(3): Error: anonymous classes not allowed\n---\n*/\n\nclass A\n{\n    import imports.a15816;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15855.d",
    "content": "// REQUIRED_ARGS: -o-\n\na[{for\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice15922.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice15922.d(23): Error: function `ice15922.ValidSparseDataStore!int.ValidSparseDataStore.correctedInsert!false.correctedInsert` has no `return` statement, but is expected to return a value of type `int`\nfail_compilation/ice15922.d(21): Error: template instance `ice15922.ValidSparseDataStore!int.ValidSparseDataStore.correctedInsert!false` error instantiating\nfail_compilation/ice15922.d(26):        instantiated from here: `ValidSparseDataStore!int`\nfail_compilation/ice15922.d(14): Error: need `this` for `insert` of type `pure nothrow @nogc @safe int()`\nfail_compilation/ice15922.d(26): Error: template instance `ice15922.StorageAttributes!(ValidSparseDataStore!int)` error instantiating\n---\n*/\n\ntemplate StorageAttributes(Store)\n{\n    enum hasInsertMethod = Store.insert;\n    enum hasFullSlice = Store.init[];\n}\nstruct ValidSparseDataStore(DataT)\n{\n    DataT insert()\n    {\n        correctedInsert!(false);\n    }\n    DataT correctedInsert(bool CorrectParents)() {}\n    auto opSlice() inout {}\n}\nalias BasicCubeT = StorageAttributes!(ValidSparseDataStore!int);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice16035.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice16035.d(18): Error: forward reference to inferred return type of function call `this.a[0].toString()`\nfail_compilation/ice16035.d(13): Error: template instance `ice16035.Value.get!string` error instantiating\n---\n*/\n\nstruct Value\n{\n    auto toString() inout\n    {\n        get!string;\n    }\n\n    T get(T)()\n    {\n        a[0].toString();\n    }\n\n    const(Value)* a;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice17074.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice17074.d(9): Error: identifier expected for C++ namespace\nfail_compilation/ice17074.d(9): Error: found `cast` when expecting `)`\nfail_compilation/ice17074.d(9): Error: declaration expected, not `)`\n---\n*/\nextern(C++, cast) void ice_keyword();\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ice17074.d(19): Error: identifier expected for C++ namespace\nfail_compilation/ice17074.d(19): Error: found `__overloadset` when expecting `)`\nfail_compilation/ice17074.d(19): Error: declaration expected, not `)`\n---\n*/\nextern(C++, std.__overloadset) void ice_std_keyword();\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ice17074.d(29): Error: identifier expected for C++ namespace\nfail_compilation/ice17074.d(29): Error: found `...` when expecting `)`\nfail_compilation/ice17074.d(29): Error: declaration expected, not `)`\n---\n*/\nextern(C++, ...) void ice_token();\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ice17074.d(39): Error: identifier expected for C++ namespace\nfail_compilation/ice17074.d(39): Error: found `*` when expecting `)`\nfail_compilation/ice17074.d(39): Error: declaration expected, not `)`\n---\n*/\nextern(C++, std.*) void ice_std_token();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice17690.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice17690.d(9): Error: undefined identifier `x`\n---\n*/\nvoid main(){\n    scope(exit) int x=3;\n    assert(x==3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice17831.d",
    "content": "// REQUIRED_ARGS: -d\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ice17831.d(19): Error: `case` variable `i` declared at fail_compilation/ice17831.d(17) cannot be declared in `switch` body\nfail_compilation/ice17831.d(33): Error: `case` variable `i` declared at fail_compilation/ice17831.d(31) cannot be declared in `switch` body\nfail_compilation/ice17831.d(48): Error: `case` variable `i` declared at fail_compilation/ice17831.d(45) cannot be declared in `switch` body\nfail_compilation/ice17831.d(61): Error: `case` variable `i` declared at fail_compilation/ice17831.d(60) cannot be declared in `switch` body\nfail_compilation/ice17831.d(73): Error: `case` variable `i` declared at fail_compilation/ice17831.d(72) cannot be declared in `switch` body\n---\n */\n\nvoid test17831a()\n{\n    switch (0)\n    {\n        foreach (i; 0 .. 5)\n        {\n            case i:\n                break;\n        }\n        default:\n            break;\n    }\n}\n\nvoid test17831b()\n{\n    switch (0)\n    {\n        for (int i = 0; i < 5; i++)\n        {\n            case i:\n                break;\n        }\n        default:\n            break;\n    }\n}\n\nvoid test17831c()\n{\n    switch (0)\n    {\n        int i = 0;\n        while (i++ < 5)\n        {\n            case i:\n                break;\n        }\n        default:\n            break;\n    }\n}\n\nvoid test17831d()\n{\n    switch (0)\n    {\n        int i = 0;\n        case i:\n            break;\n        default:\n            break;\n    }\n}\n\nvoid test17831e()\n{\n    switch (0)\n    {\n        static int i = 0;\n        case i:\n            break;\n        default:\n            break;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice18469.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice18469.d(10): Error: no property `opCall` for type `void`\n---\n*/\nclass Bar\n{\n    ~this(){}\n    this(){alias T = typeof(Bar.__dtor.opCall);}\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice18753.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice18753.d(21): Error: variable `ice18753.isInputRange!(Group).isInputRange` type `void` is inferred from initializer `ReturnType(func...)`, and variables cannot be of type `void`\nfail_compilation/ice18753.d(23): Error: template instance `ice18753.isInputRange!(Group)` error instantiating\nfail_compilation/ice18753.d(18):        instantiated from here: `isForwardRange!(Group)`\nfail_compilation/ice18753.d(18):        while evaluating: `static assert(isForwardRange!(Group))`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18753\n\nstruct ChunkByImpl\n{\n    struct Group\n    { }\n    \n    static assert(isForwardRange!Group);\n}\n\nenum isInputRange(R) = ReturnType;\n\nenum isForwardRange(R) = isInputRange!R is ReturnType!(() => r);\n\ntemplate ReturnType(func...)\n{\n    static if (is(FunctionTypeOf!func R == return))\n        ReturnType R;\n}\n\ntemplate FunctionTypeOf(func...)\n{\n    static if (is(typeof(func[0]) T))\n        static if (is(T Fptr ) )\n            alias FunctionTypeOf = Fptr;\n}\n\ntemplate Select()\n{ }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice18803a.d",
    "content": "void main() { import ice18803b; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice18803b.d",
    "content": "static if\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice2843.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice2843.d(22): Error: incompatible types for `(1) is (typeid(int))`: `int` and `object.TypeInfo`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=2843\n// ICE(constfold.c) with is-expression with invalid dot-expression in is-expression involving typeid expression\n/* 2843 Assertion failure: '0' on line 863 in file 'constfold.c'\nPATCH: constfold.c, line 861:\nOLD:\n        }else\n        assert(0);\nNEW:\n        }else if (e1->isConst() && e2->isConst()) {\n        // Comparing a SymExp with a literal, eg typeid(int) is 7.1;\n           cmp=0; // An error has already occurred. Prevent an ICE.\n        }else\n        assert(0);\n*/\nbool b = 1 is typeid(int);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice4094.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice4094.d(11): Error: circular reference to variable `ice4094.Zug!0.Zug.bahn`\nfail_compilation/ice4094.d(19): Error: template instance `ice4094.Zug!0` error instantiating\n---\n*/\n// REQUIRED_ARGS: -d\nstruct Zug(int Z)\n{\n    const bahn = Bug4094!(0).hof.bahn;\n}\n\nstruct Bug4094(int Q)\n{\n    Zug!(0) hof;\n}\n\nconst a = Zug!(0).bahn;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice4983.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice4983.d(14): Error: circular reference to `ice4983.Foo.dg`\n---\n*/\n\nstruct Foo\n{\n    void bar()\n    {\n    }\n\n    void delegate() dg = &Foo.init.bar;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice5996.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice5996.d(8): Error: undefined identifier `anyOldGarbage`\n---\n*/\nauto bug5996() {\n    if (anyOldGarbage) {}\n    return 2;\n}\nenum uint h5996 = bug5996();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice6538.d",
    "content": "\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9361\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ice6538.d(23): Error: expression `super` is not a valid template value argument\nfail_compilation/ice6538.d(28): Error: template `ice6538.D.foo` cannot deduce function from argument types `!()()`, candidates are:\nfail_compilation/ice6538.d(23):        `ice6538.D.foo()() if (Sym!(super))`\n---\n*/\n\ntemplate Sym(alias A)\n{\n    enum Sym = true;\n}\n\nclass C {}\nclass D : C\n{\n    void foo()() if (Sym!(super)) {}\n}\nvoid test9361b()\n{\n    auto d = new D();\n    d.foo();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice7645.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice7645.d(28): Error: need `this` for `t` of type `char`\nfail_compilation/ice7645.d(31): Error: need `this` for `fn` of type `pure nothrow @nogc @safe void()`\n---\n*/\n\nclass C\n{\n    class C2()\n    {\n        char t;\n    }\n}\n\nstruct S\n{\n    struct S2(T)\n    {\n        void fn() {}\n    }\n}\n\nvoid main()\n{\n    C c;\n    auto v = c.C2!().t;\n\n    S s;\n    s.S2!int.fn();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice7782.d",
    "content": "import imports.ice7782algorithm;\nimport imports.ice7782range. imports.ice7782math;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice8100.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice8100.d(10): Error: no property `Q` for type `ice8100.Bar!bool`\nfail_compilation/ice8100.d(11): Error: template instance `ice8100.Foo!(Bar!bool)` error instantiating\nfail_compilation/ice8100.d(12):        instantiated from here: `Bar!bool`\n---\n*/\n\nclass Foo(T1) { T1.Q r; }\nclass Bar(T2) : Foo!(Bar!T2) {}\nBar!bool b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice8255.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice8255.d(11): Error: function `ice8255.F!(G).F.f(ref G _param_0)` is not callable using argument types `(G)`\nfail_compilation/ice8255.d(11):        cannot pass rvalue argument `G()` of type `G` to parameter `ref G _param_0`\nfail_compilation/ice8255.d(11):        while evaluating `pragma(msg, F().f(G()))`\n---\n*/\nstruct G {}\nstruct F(T) { void f(ref T) {} }\npragma(msg, F!G().f(G.init));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice8309.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice8309.d(10): Error: incompatible types for `(__lambda1) : (__lambda2)`: `double function() pure nothrow @nogc @safe` and `int function() pure nothrow @nogc @safe`\n---\n*/\n\nvoid main()\n{\n    auto x = [()=>1.0, ()=>1];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice8499.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice8499.d(18): Error: undefined identifier `i`\n---\n*/\n\nstruct Variant\n{\n    @property T get(T)()\n    {\n        struct X {}   // necessary\n    }\n}\n\nvoid main()\n{\n    (Variant()).get!(typeof(() => i));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice8511.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice8511.d(11): Error: enum `ice8511.hypot.SQRTMAX` is forward referenced looking for base type\nfail_compilation/ice8511.d(12): Error: incompatible types for `(SQRTMAX) / (2)`: cannot use `/` with types\n---\n*/\n\nreal hypot()\n{\n    enum SQRTMAX;\n    SQRTMAX/2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice8604.d",
    "content": "struct StructFoo\n{\n    static if(i) { }\n    else enum z = \"\";\n}\n\nvoid main() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice8630.d",
    "content": "auto map(alias func, R)(R r) { return r; }\ntypeof(v) foo(R)(R v) { return map!(p=>p)(v); }\nvoid main() { foo([1]); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice8711.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice8711.d(8): Error: cannot use array to initialize `int function(int)`\n---\n*/\n\nint function(int) foos = [x => 0];\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice8742.d",
    "content": "// PERMUTE_ARGS:\nclass C\n{\n    class D { }\n}\n\nvoid main ( )\n{\n    auto c = new C;\n    auto d = c.new class C.D { };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice8795.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice8795.d-mixin-14(14): Error: found `End of File` when expecting `(`\nfail_compilation/ice8795.d-mixin-14(14): Error: expression expected, not `End of File`\nfail_compilation/ice8795.d-mixin-14(14): Error: found `End of File` when expecting `)`\nfail_compilation/ice8795.d-mixin-14(14): Error: found `End of File` instead of statement\nfail_compilation/ice8795.d-mixin-15(15): Error: { } expected following `interface` declaration\nfail_compilation/ice8795.d-mixin-15(15): Error: anonymous interfaces not allowed\n---\n*/\nvoid main()\n{\n    mixin(\"switch\");\n    mixin(\"interface;\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice8795b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice8795b.d-mixin-8(8): Error: { } expected following `interface` declaration\nfail_compilation/ice8795b.d-mixin-8(8): Error: anonymous interfaces not allowed\n---\n*/\nmixin(\"interface;\");\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9013.d",
    "content": "void main()\n{\n    foreach (i; 0 .. missing)\n        int[] foo = cast(int[])[i];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9254a.d",
    "content": "\nvoid main()\n{\n    foreach (divisor; !(2, 3, 4, 8, 7, 9))\n    {\n        // ice in ForeachRangeStatement::blockExit()\n        foreach (v; 0..uint.max) {}\n\n        // ice in WhileStatement::blockExit()\n        while (1) {}\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9254b.d",
    "content": "\nclass C\n{\n    synchronized void foo()\n    {\n        foreach(divisor; !(2, 3, 4, 8, 7, 9))\n        {\n            // ice in ForeachRangeStatement::usesEH()\n            foreach (v; 0..uint.max) {}\n\n            // ice in WhileStatement::usesEH()\n            while (1) {}\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9254c.d",
    "content": "\nvoid main()\n{\n    foreach(divisor; !(2, 3, 4, 8, 7, 9))\n    {\n        assert(0);\n\n        // ice in ForeachRangeStatement::comeFrom()\n        foreach (v; 0..uint.max) {}\n\n        // ice in WhileStatement::comeFrom()\n        while (1) {}\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9273a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9273a.d(19): Error: constructor `ice9273a.C.__ctor!().this` no match for implicit `super()` call in constructor\nfail_compilation/ice9273a.d(23): Error: template instance `ice9273a.C.__ctor!()` error instantiating\n---\n*/\n\ntemplate CtorMixin()\n{\n    this(T)() {}\n}\nclass B\n{\n    mixin CtorMixin!();\n}\nclass C : B\n{\n    this()() {}\n}\nvoid main()\n{\n    auto c = new C();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9273b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9273b.d(14): Error: constructor `ice9273b.B.this` no match for implicit `super()` call in constructor\n---\n*/\n\nclass A\n{\n    this(T)() {}\n}\nclass B : A\n{\n    this() {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9284.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9284.d(14): Error: template `ice9284.C.__ctor` cannot deduce function from argument types `!()(int)`, candidates are:\nfail_compilation/ice9284.d(12):        `ice9284.C.__ctor()(string)`\nfail_compilation/ice9284.d(20): Error: template instance `ice9284.C.__ctor!()` error instantiating\n---\n*/\n\nclass C\n{\n    this()(string)\n    {\n        this(10);\n        // delegating to a constructor which not exists.\n    }\n}\nvoid main()\n{\n    new C(\"hello\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9291.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9291.d(10): Error: undefined identifier `F`\n---\n*/\n\nvoid main() nothrow\n{\n    throw new F();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9338.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9338.d(13): Error: value of `this` is not known at compile time\nfail_compilation/ice9338.d(14): Error: value of `this` is not known at compile time\n---\n*/\n\nclass Foo\n{\n    void test()\n    {\n        enum members1 = makeArray();\n        enum members2 = this.makeArray();\n    }\n\n    string[] makeArray()\n    {\n        return [\"a\"];\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9406.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9406.d(21): Error: expression has no value\n---\n*/\n\nmixin template Mixin() { }\n\nstruct S\n{\n    template t1()\n    {\n        mixin Mixin t1;\n    }\n}\n\nvoid main()\n{\n    S s1;\n    s1.t1!();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9439.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9439.d(12): Error: `this` for `foo` needs to be type `Derived` not type `ice9439.Base`\nfail_compilation/ice9439.d(12):        while evaluating: `static assert((__error).foo())`\nfail_compilation/ice9439.d(19): Error: template instance `ice9439.Base.boo!(foo)` error instantiating\n---\n*/\n\nclass Base {\n    void boo(alias F)() {\n        static assert(F());\n    }\n}\n\nclass Derived : Base {\n    int foo() { return 1; }\n    void bug() {\n        boo!(foo)();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9494.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9494.d(10): Error: circular reference to variable `ice9494.test`\nfail_compilation/ice9494.d(14): Error: circular reference to variable `ice9494.Foo.test`\nfail_compilation/ice9494.d(19): Error: circular reference to variable `ice9494.Bar.test`\n---\n*/\n\nint[test] test;  // stack overflow\n\nclass Foo\n{\n    int[this.test] test;  // stack overflow\n}\n\nstruct Bar\n{\n    int[this.test] test;  // stack overflow\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9540.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9540.d(34): Error: function `ice9540.A.test.AddFront!(this, f).AddFront.dg(int _param_0)` is not callable using argument types `()`\nfail_compilation/ice9540.d(25): Error: template instance `ice9540.A.test.AddFront!(this, f)` error instantiating\n---\n*/\n\ntemplate Tuple(E...) { alias E Tuple; }\nalias Tuple!(int) Args;\n\nvoid main() {\n    (new A).test ();\n}\n\nvoid test1 (int delegate (int) f) { f (-2); }\n\nclass A\n{\n    int f (int a) {\n        return a;\n    }\n\n    void test () {\n        test1 (&AddFront!(this, f));\n    }\n}\n\ntemplate AddFront (alias ctx, alias fun)  {\n    auto AddFront(Args args) {\n        auto dg (Args dgArgs) {\n            return fun (dgArgs);\n        }\n        dg.ptr = ctx;\n        return dg(args);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9545.d",
    "content": "// REQUIRED_ARGS: -o-\n/*\nTEST_OUTPUT:\n----\nfail_compilation/ice9545.d(13): Error: type `int` has no value\n----\n*/\n\nstruct S { template T(X) { alias T = X; } }\n\nvoid main()\n{\n    auto x1 = S.init.T!int; // ICE\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9759.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9759.d(25): Error: mutable method `ice9759.Json.opAssign` is not callable using a `const` object\nfail_compilation/ice9759.d(25):        Consider adding `const` or `inout` to ice9759.Json.opAssign\n---\n*/\n\nstruct Json\n{\n    union\n    {\n        Json[] m_array;\n        Json[string] m_object;\n    }\n\n    void opAssign(Json v)\n    {\n    }\n}\n\nvoid bug()\n{\n    const(Json) r;\n    r = r.init;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9806.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9806.d(12): Error: undefined identifier `undefined_expr`\nfail_compilation/ice9806.d(17): Error: template instance `ice9806.S1!()` error instantiating\nfail_compilation/ice9806.d(13): Error: undefined identifier `undefined_expr`\nfail_compilation/ice9806.d(19): Error: template instance `ice9806.C1!()` error instantiating\nfail_compilation/ice9806.d(14): Error: undefined identifier `undefined_expr`\nfail_compilation/ice9806.d(21): Error: template instance `ice9806.I1!()` error instantiating\n---\n*/\nstruct S1() { enum x = undefined_expr; }\nclass  C1() { enum x = undefined_expr; }\nclass  I1() { enum x = undefined_expr; }\nvoid test1() {\n    static assert(!is(typeof(S1!().x)));\n    auto sx = S1!().x;\n    static assert(!is(typeof(C1!().x)));\n    auto cx = C1!().x;\n    static assert(!is(typeof(I1!().x)));\n    auto ix = I1!().x;\n}\n\n// --------\n/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9806.d(36): Error: undefined identifier `undefined_expr`\nfail_compilation/ice9806.d(44): Error: template instance `ice9806.S2!()` error instantiating\nfail_compilation/ice9806.d(37): Error: undefined identifier `undefined_expr`\nfail_compilation/ice9806.d(46): Error: template instance `ice9806.C2!()` error instantiating\nfail_compilation/ice9806.d(38): Error: undefined identifier `undefined_expr`\nfail_compilation/ice9806.d(48): Error: template instance `ice9806.I2!()` error instantiating\n---\n*/\nint foo2()() { return undefined_expr; }\nint bar2()() { return undefined_expr; }\nint baz2()() { return undefined_expr; }\nstruct S2() { enum x = foo2(); }\nclass  C2() { enum x = bar2(); }\nclass  I2() { enum x = baz2(); }\nvoid test2() {\n    static assert(!is(typeof(S2!().x)));\n    auto sx = S2!().x;\n    static assert(!is(typeof(C2!().x)));\n    auto cx = C2!().x;\n    static assert(!is(typeof(I2!().x)));\n    auto ix = I2!().x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/ice9865.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/ice9865.d(8): Error: alias `ice9865.Baz` recursive alias declaration\n---\n*/\n\npublic import imports.ice9865b : Baz;\nstruct Foo { Baz f; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/impconv.d",
    "content": "/*\nFIXME: DMD host compilers < 2.073 with faulty optimization\nlead to unfortunate test failures, see\nhttps://github.com/dlang/dmd/pull/6831#issuecomment-304495842.\n\nDISABLED: win32 win64 linux osx freebsd\n*/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/impconv.d(30): Error: function `impconv.foo_float(float)` is not callable using argument types `(int)`\nfail_compilation/impconv.d(30):        cannot pass argument `-2147483647` of type `int` to parameter `float`\nfail_compilation/impconv.d(31): Error: function `impconv.foo_float(float)` is not callable using argument types `(uint)`\nfail_compilation/impconv.d(31):        cannot pass argument `4294967295u` of type `uint` to parameter `float`\nfail_compilation/impconv.d(34): Error: function `impconv.foo_double(double)` is not callable using argument types `(long)`\nfail_compilation/impconv.d(34):        cannot pass argument `-9223372036854775807L` of type `long` to parameter `double`\nfail_compilation/impconv.d(35): Error: function `impconv.foo_double(double)` is not callable using argument types `(ulong)`\nfail_compilation/impconv.d(35):        cannot pass argument `18446744073709551615LU` of type `ulong` to parameter `double`\n---\n*/\n\nvoid foo_float(float);\nvoid foo_double(double);\nvoid foo_real(real);\n\nvoid main()\n{\n    foo_float(1);        // implicitly convertible to float\n    foo_float(-int.max); // -(2^31 - 1)\n    foo_float(uint.max); // 2^32 - 1\n\n    foo_double(int.max);   // implicitly convertible to double\n    foo_double(-long.max); // -(2^63 - 1)\n    foo_double(ulong.max); // 2^64 - 1\n\n    foo_real(0xffff_ffff_ffffL); // 2^48 - 1, implicitly convertible to real\n    static assert(__traits(compiles, foo_real(-long.max)) == (real.mant_dig >= 63));\n    static assert(__traits(compiles, foo_real(ulong.max)) == (real.mant_dig >= 64));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imphint.d",
    "content": "/* PERMUTE_ARGS:\n---\nfail_compilation/imphint.d(14): Error: 'printf' is not defined, perhaps you need to import core.stdc.stdio; ?\nfail_compilation/imphint.d(15): Error: 'writeln' is not defined, perhaps you need to import std.stdio; ?\nfail_compilation/imphint.d(16): Error: 'sin' is not defined, perhaps you need to import std.math; ?\nfail_compilation/imphint.d(17): Error: 'cos' is not defined, perhaps you need to import std.math; ?\nfail_compilation/imphint.d(18): Error: 'sqrt' is not defined, perhaps you need to import std.math; ?\nfail_compilation/imphint.d(19): Error: 'fabs' is not defined, perhaps you need to import std.math; ?\n---\n*/\n\nvoid foo()\n{\n    printf(\"hello world\\n\");\n    writeln(\"hello world\\n\");\n    sin(3.6);\n    cos(1.2);\n    sqrt(2.0);\n    fabs(-3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a10169.d",
    "content": "module imports.a10169;\n\nstruct B\n{\n    private int x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a10528.d",
    "content": "private enum string a = \"asdfgh\";\nprivate enum { b = \"asdfgh\" }\n\nstruct S { private enum string c = \"qwerty\"; }\nclass  C { private enum string d = \"qwerty\"; }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a11850.d",
    "content": "//import std.array, std.range;\nmodule imports.a11850;\n\n\ntemplate filter(alias pred)\n{\n    auto filter(Range)(Range rs)\n    {\n        return FilterResult!(pred, Range)(rs);\n    }\n}\n\n\nprivate struct FilterResult(alias pred, Range)\n{\n    alias Range R;\n    R _input;\n\n\n    this(R r)\n    {\n        _input = r;\n        while (_input.length != 0 && !pred(_input[0]))\n        {\n            _input = _input[1..$];\n        }\n    }\n\n\n    auto opSlice() { return this; }\n\n\n    @property bool empty() { return _input.length == 0; }\n\n\n    void popFront()\n    {\n        do\n        {\n            _input = _input[1..$];\n        } while (_input.length != 0 && !pred(_input[0]));\n    }\n\n\n    @property auto ref front()\n    {\n        return _input[0];\n    }\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a11919.d",
    "content": "void doBar(T)(T t)\n{\n    static if (t.tupleof.length)\n        if (zoo!t.length == 0) {}\n    static if (is(T B == super)\n            && is(B[0] == class)\n            && is(B[])\n            )\n    {\n        B[0] b = t;\n        doBar(b);\n    }\n}\ntemplate zoo(alias t)\n{\n    enum zoo = __traits(getAttributes, t.tupleof);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a13131checkpoint.d",
    "content": "module imports.a13131checkpoint;\n\nmixin(createGlobalsMixins);             // [3] mixin\n\nauto createGlobalsMixins()              // [4] semantic3\n{\n    pragma(msg, \"+A\");\n    enum fullModuleName = \"imports.a13131parameters\";  // necessary\n    mixin(\"import \"~fullModuleName~\";\");\n    foreach (e ; __traits(derivedMembers, mixin(fullModuleName)))\n    {\n        // [5] see imports.parameters (it's listed in command line)\n        static if ( __traits(compiles, mixin(`__traits(getAttributes, `~fullModuleName~`.`~e~`)`))) {}\n    }\n    pragma(msg, \"-A\");\n\n    return \"\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a13131elec.d",
    "content": "module imports.a13131elec;\n\nimport imports.a13131checkpoint;        // [2] import\n\nvoid initElec(T)(T L)\n{\n    immutable cv = econn.velocities;    // econn is invalid so generates ErrorExp\n}\n\nalias econn = elecConnOf!gconn; // invalid declaration\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a13131parameters.d",
    "content": "module imports.a13131parameters;\n\nauto createParameterMixins()    // auto is necessary to invoke semantic3 to calculate full signature\n{\n    pragma(msg, \"+B\");\n    enum fullModuleName = \"imports.a13131elec\";  // necessary\n    mixin(\"import \"~fullModuleName~\";\");\n    foreach (e ; __traits(derivedMembers, mixin(fullModuleName)))\n    {\n        // will access yet-not semantic analyzed invalid symbol 'econn' in imports.elec\n        static if ( __traits(compiles, mixin(`__traits(getAttributes, `~fullModuleName~`.`~e~`)`))) {}\n    }\n    pragma(msg, \"-B\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a13311.d",
    "content": "module imports.a13311;\n\nimport ice13311;\n\nclass Z\n{\n    TextPiece piece;\n    this(PieceTree owner) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a13465.d",
    "content": "module imports.a13465;\n\ntemplate isMaskField()\n{\n    import imports.a13465;\n}\n\ntemplate isMatchingMaskField()\n{\n    enum isMatchingMaskField = isMaskField!();\n\n    /* Semantic analysis journey came from isMatchingMaskField!()\n     *\n     * TemplateInstance('isMaskField!T')->semantic()\n     *  TemplateInstance('isMaskField!T')->semantic2() <---\n     *          TemplateInstance::semantic() will run its semantic2() always.\n     *   Import('import imports.ice1365a;')->semantic2()\n     *    Module('imports.ice1365a')->semantic2()\n     *     VarDeclaration('imports.ice1365a.isMatchingMaskField!().isMatchingMaskField')->semantic2() <---\n     *          The type field is yet NULL during type inference, then ICE happens.\n     */\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a14116.d",
    "content": "module ice14116.a14116;\n\nimport ice14116;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a14235.d",
    "content": "module imports.a14235;\n\nstruct SomeThing(T...)\n{\n}\n\nclass SomeClass {}"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a14407.d",
    "content": "module imports.a14407;\n\ndeprecated class C\n{\n    private deprecated new (size_t, string)\n    {\n        return null;\n    }\n    private this(int) {}\n}\n\ndeprecated struct S\n{\n    private deprecated new (size_t, string)\n    {\n        return null;\n    }\n    private this(int) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a14424.d",
    "content": "module imports.a14424;\n\nunittest { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a15667.d",
    "content": "module imports.a15667;\n\ntemplate staticIndexOf(T)\n{\n    enum staticIndexOf = genericIndexOf!T;\n}\n\ntemplate genericIndexOf(args...)\n{\n    alias e     = args;\n    alias tuple = args;\n    alias tail = tuple;\n    enum next  = genericIndexOf!(e, tail);\n}\n\nalias X = ;\n\nstatic if (staticIndexOf!X)\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a15816.d",
    "content": "module imports.a15816;\n\nclass\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a17625.d",
    "content": "module a17625;\n\nprivate int boo() { return 69; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a17630.d",
    "content": "module a17630;\n\nimport b17630;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a18219.d",
    "content": "module a18219;\n\nstruct AST\n{\n    import b18219;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a18243.d",
    "content": "module a18243;\n\nimport std.math : isNaN;\n\npublic bool isNaN() { return false; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a313.d",
    "content": "module imports.a313;\n\nprivate import imports.b313;\nprivate static import imports.b313;\nprivate static import b313 = imports.b313;\n\nprivate import imports.pkg313;\n\nprivate import core.stdc.stdio;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/a314.d",
    "content": "module imports.a314;\n\nstatic import imports.c314;\nimport renamed = imports.c314;\nimport imports.c314 : bug;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/b13465.d",
    "content": "module imports.b13465;\n\ntemplate isMaskField()\n{\n    import imports.b13465;\n}\n\ntemplate isMatchingMaskField()\n{\n    enum isMatchingMaskField = { enum n = isMaskField!(); return n; }();\n\n    /* Semantic analysis journey came from isMatchingMaskField!()\n     *\n     * TemplateInstance('isMaskField!T')->semantic()\n     *  TemplateInstance('isMaskField!T')->semantic2() <---\n     *          TemplateInstance::semantic() should run its semantic2() in function body.\n     *   Import('import imports.ice1365a;')->semantic2()\n     *    Module('imports.ice1365a')->semantic2()\n     *     VarDeclaration('imports.ice1365a.isMatchingMaskField!().isMatchingMaskField')->semantic2() <---\n     *          Cannot avoid this visiting, so we need to add a fix in VarDeclaration::semantic2().\n     */\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/b17625.d",
    "content": "module b17625;\n\nprivate int boo() { return 45; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/b17630.d",
    "content": "module b17630;\n\nint Erase;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/b17918a.d",
    "content": "module imports.b17918a;\n\nclass Base\n{\n    auto byNode()\n    {\n        return _listMap;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/b18219.d",
    "content": "module b18219;\n\nclass Foobar\n{\n    int a;\n    this(int a)\n    {\n        this.a = a;\n    }\n    static int smeth()\n    {\n        return 1;\n    }\n}\nvoid fun() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/b313.d",
    "content": "module imports.b313;\n\nvoid bug()\n{}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/b314.d",
    "content": "module imports.b314;\n\npackage import renamedpkg = imports.c314;\npackage import imports.c314 : bugpkg=bug;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/bar11136.d",
    "content": "module ice11136.bar11136;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/c314.d",
    "content": "module imports.c314;\n\nvoid bug(string s)\n{}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/diag10089a.d",
    "content": "module imports.diag10089a;\n\nstruct chunks\n{\n    this(size_t size)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/diag10089b.d",
    "content": "module imports.diag10089b;\n\nvoid chunks(Source)(Source source, size_t chunkSize)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/diag10141a.d",
    "content": "module imports.diag10141a;\n\nimport imports.diag10141b;\n\nstring format()\n{\n    auto w = Appender!string();\n    char[] digits = ['0'];\n    put(w, digits);\n    return null;\n}\n\ntemplate Tuple(Specs...)\n{\n    struct Tuple\n    {\n        Specs expand;\n\n        enum x = format();  // in injectNameFields()\n    }\n}\n\nprivate template Identity(alias T)\n{\n    alias T Identity;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/diag10141b.d",
    "content": "module imports.diag10141b;\n\ntemplate isSomeChar(T) {\n    enum isSomeChar =\n        is(immutable T == immutable  char) ||\n        is(immutable T == immutable wchar) ||\n        is(immutable T == immutable dchar);\n}\n\nstruct Appender(A : T[], T)\n{\n    private template canPutItem(U)\n    {\n        enum bool canPutItem =\n            //isImplicitlyConvertible!(U, T) ||\n            isSomeChar!T && isSomeChar!U;\n    }\n    private template canPutRange(Range)\n    {\n        enum bool canPutRange =\n            //isInputRange!Range &&\n            is(typeof(Appender.init.put(\"a\"d[0])));\n    }\n\n    /**\n     * Appends one item to the managed array.\n     */\n    void put(U)(U item) if (canPutItem!U)\n    {\n        char[T.sizeof == 1 ? 4 : 2] encoded;\n        auto len = 1;\n        put(encoded[0 .. len]); // !\n    }\n\n    /**\n     * Appends an entire range to the managed array.\n     */\n    void put(Range)(Range items) if (canPutRange!Range)\n    {\n    }\n}\n\nvoid put(R, E)(ref R r, E e)\n{\n    static if (is(typeof(r.put(e))))\n    {\n        r.put(e);\n    }\n    else\n    {\n        static assert(false,\n                \"Cannot put a \"~E.stringof~\" into a \"~R.stringof);\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/diag12598a.d",
    "content": "module imports.diag12598a;\n\nstruct lines { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/diag9210b.d",
    "content": "module imports.diag9210b;\n\nimport imports.diag9210c;\nimport imports.diag9210stdcomplex;\n\ninterface B : A {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/diag9210c.d",
    "content": "module imports.diag9210c;\n\nimport diag9210a;\ninterface C : A {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/diag9210stdcomplex.d",
    "content": "module imports.diag9210stdcomplex;\n\nimport imports.diag9210stdtraits;\n\nstruct Complex(T) if (isFloatingPoint!T)\n{\n    T re;\n    T im;\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=9210: Complex!real instantiation is incomplete in here,\n// because its completion is deferred by an \"undefined identifier\" error in imports.diag9210b.\nComplex!real expi(real y)\n{\n    return Complex!real(0, 0);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/diag9210stdtraits.d",
    "content": "module imports.diag9210stdtraits;\n\ntemplate FloatingPointTypeOf(T)// if (!is(T == enum))\n{\n           inout( float) idx(        inout( float) );\n           inout(double) idx(        inout(double) );\n           inout(  real) idx(        inout(  real) );\n    shared(inout  float) idx( shared(inout  float) );\n    shared(inout double) idx( shared(inout double) );\n    shared(inout   real) idx( shared(inout   real) );\n\n       immutable( float) idy(   immutable( float) );\n       immutable(double) idy(   immutable(double) );\n       immutable(  real) idy(   immutable(  real) );\n\n    static if (is(typeof(idx(T.init)) X))\n    {\n        alias X FloatingPointTypeOf;\n    }\n    else static if (is(typeof(idy(T.init)) X))\n    {\n        alias X FloatingPointTypeOf;\n    }\n    else\n    {\n        static assert(0, T.stringof~\" is not a floating point type\");\n    }\n}\n\ntemplate isFloatingPoint(T)\n{\n    enum bool isFloatingPoint = is(FloatingPointTypeOf!T);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/dip22a.d",
    "content": "module imports.dip22a;\n\nclass Klass\n{\n    private void bar() {}\n}\n\nstruct Struct\n{\n    private void bar() {}\n}\n\nprivate void bar() {}\n\ntemplate Template(T)\n{\n    private void bar() {}\n}\n\nprivate void bar(int) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/dip22b.d",
    "content": "module imports.dip22b;\n// this public import only exports symbols that are visible within this module\npublic import imports.dip22c;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/dip22c.d",
    "content": "module pkg.dip22c;\n\npackage(pkg) struct Foo {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/dip22d.d",
    "content": "module imports.dip22d;\n\nprivate struct Foo {}\nprivate void foo() {}\nprivate void bar() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/dip22e.d",
    "content": "module imports.dip22e;\n\npublic struct Foo {}\npublic void bar(int) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail10277.d",
    "content": "module imports.fail10277;\n\nclass TypeInfo { }\nclass TypeInfo_Class { }\nclass TypeInfo_Interface { }\nclass TypeInfo_Struct { }\nclass TypeInfo_Typedef { }\nclass TypeInfo_Pointer { }\nclass TypeInfo_Array { }\nclass TypeInfo_AssociativeArray { }\nclass TypeInfo_Enum { }\nclass TypeInfo_Function { }\nclass TypeInfo_Delegate { }\nclass TypeInfo_Tuple { }\nclass TypeInfo_Const { }\nclass TypeInfo_Invariant { }\nclass TypeInfo_Shared { }\nclass TypeInfo_Inout { }\nclass TypeInfo_Vector { }\nclass Object { }\nclass Throwable { }\nclass Exception { }\nclass Error { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail17646.d",
    "content": "module imports.fail17646;\n\nstruct TestData\n{\n}\n\nconst(TestData)[] allTestData(MOD_STRINGS...)()\n{\n    foreach (i; MOD_STRINGS)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail1900a.d",
    "content": "module imports.fail1900a;\ntemplate Bar(int n) { enum Bar = n; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail1900b.d",
    "content": "module imports.fail1900b;\ntemplate Bar(short n) { enum Bar = n; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail2962a.d",
    "content": "import fail2962;\n\n// comment 4\nint foo4()\n{\n    return bar4(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail320a.d",
    "content": "void foo(int) { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail320b.d",
    "content": "void foo(T)(){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail347a.d",
    "content": "module imports.fail347a;\n\npure size_t strlen(in char* s);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail355.d",
    "content": "module imports.fail355;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail356.d",
    "content": "module imports.fail356;\nint bar;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail4479.d",
    "content": "module imports.fail4479mod;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/fail5385.d",
    "content": "module imports.fail5385;\n\nclass C\n{\n    static private int privX;\n    static package int packX;\n    __gshared private int privX2;\n    __gshared package int packX2;\n}\n\nstruct S\n{\n    static private int privX;\n    static package int packX;\n    __gshared private int privX2;\n    __gshared package int packX2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/foo10727a.d",
    "content": "struct CirBuff(T)\n{\n    import imports.stdtraits10727 : isArray;\n    CirBuff!T opAssign(R)(R) if (isArray!R)\n    {}\n\n    struct Range(U, S)\n    {\n        Range!(U, S) save() { return U; }\n    }\n\n    T[] toArray()\n    {\n        T[] ret = new T[this.length];\n        return ret;\n    }\n\n    alias toArray this;\n\n    Range!(T, T) range() {}\n\n}\n\nclass Bar(T = int)\n{\n    CirBuff!T _bar;\n}\n\nclass Once\n{\n    Bar!Foo _foobar;\n}\n\nclass Foo : Frop {} // Frop is not defined\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/foo10727b.d",
    "content": "struct CirBuff(T)\n{\n    import imports.stdtraits10727 : isArray;\n    CirBuff!T opAssign(R)(R) if (isArray!R)\n    {}\n\n    T[] toArray()\n    {\n        T[] ret = new T[this.length];\n        return ret;\n    }\n    alias toArray this;\n}\n\nclass Bar(T = int)\n{\n    CirBuff!T _bar;\n}\n\nclass Once\n{\n    Bar!Foo _foobar;\n}\n\nclass Foo : Frop {} // Frop is not defined\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/ice10600a.d",
    "content": "module imports.ice10600a;\n\nstruct Appender(A : T[], T)\n{\n    this(T[]) {}\n}\n\nAppender!(E[]) appender(A : E[], E)()\n{\n    return Appender!(E[])(null);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/ice10600b.d",
    "content": "module imports.ice10600b;\n\nimport imports.ice10600a;\n\ntemplate to(T)\n{\n    T to(A...)(A args)\n    {\n        return toImpl!T(args);\n    }\n}\n\n\nT toImpl(T, S)(S value)\nif (is(S : T))\n{\n    return value;\n}\n\n\nT toImpl(T, S)(S value)\nif (!is(S : T) &&\n     is(T == string))\n{\n    auto w = appender!T();\n    //Appender!T w;\n    return null;\n}\n\nT toImpl(T, S)(S value)\nif ( is(S == string) &&\n    !is(T == string) && is(typeof(to!string(value[0])))\n   )\n{\n    return T.init;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/ice11513x.d",
    "content": "module ice11513a.imports;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/ice11513y.d",
    "content": "module ice11513b.imports.ice11513y;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/ice7782algorithm.d",
    "content": "module imports.ice7782algorithm;\n\nimport imports.ice7782range;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/ice7782range.d",
    "content": "module imports.ice7782range;\n\nimport imports.ice7782algorithm;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/ice9865b.d",
    "content": "public import ice9865;\nclass Bar { Foo foo; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/imp1.d",
    "content": "module imports.imp1;\n\nenum X = 1;\nenum Y = 1;\nenum Z = 1;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/imp15896.d",
    "content": "module imports.imp15896;\n\nprivate int thebar=4;\npackage int packagebar=3;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/imp17602.d",
    "content": "module imports.imp17602;\n\nenum Status { on }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/imp18554.d",
    "content": "struct S\n{\n    private int i;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/imp2.d",
    "content": "module imports.imp2;\n\nenum X = 2;\nenum Y = 2;\nenum Z = 2;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/pkg313/package.d",
    "content": "module imports.pkg313;\n\nvoid bug()\n{}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/range15788.d",
    "content": "module imports.range15788;\n\nauto iota(B, E, S)(B, E, S)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/spell9644a.d",
    "content": "module imports.spell9644a;\n\npublic import imports.spell9644b;\n\nint cora;\nint pub;\nprivate int priv;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/spell9644b.d",
    "content": "module imports.spell9644b;\n\nprivate int prib;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/stdtraits10727.d",
    "content": "template StaticArrayTypeOf(T)\n{\n    inout(U[n]) idx(U, size_t n)( inout(U[n]) );\n\n    /+static if (is(T == enum))\n        alias .StaticArrayTypeOf!(OriginalType!T) StaticArrayTypeOf;\n    else +/static if (is(typeof(idx(T.init/+defaultInit!T+/)) X))\n        alias X StaticArrayTypeOf;\n    else\n        static assert(0, T.stringof~\" is not a static array type\");\n}\n\ntemplate DynamicArrayTypeOf(T)\n{\n    inout(U[]) idx(U)( inout(U[]) );\n\n    /+static if (is(T == enum))\n        alias .DynamicArrayTypeOf!(OriginalType!T) DynamicArrayTypeOf;\n    else +/static if (!is(StaticArrayTypeOf!T) &&\n                     is(typeof(idx(T.init/+defaultInit!T+/)) X))\n    {\n        alias typeof(T.init[0]/+defaultInit!T[0]+/) E;\n\n                     E[]  idy(              E[]  );\n               const(E[]) idy(        const(E[]) );\n               inout(E[]) idy(        inout(E[]) );\n        shared(      E[]) idy( shared(      E[]) );\n        shared(const E[]) idy( shared(const E[]) );\n        shared(inout E[]) idy( shared(inout E[]) );\n           immutable(E[]) idy(    immutable(E[]) );\n\n        alias typeof(idy(T.init/+defaultInit!T+/)) DynamicArrayTypeOf;\n    }\n    else\n        static assert(0, T.stringof~\" is not a dynamic array\");\n}\n\ntemplate isDynamicArray(T)\n{\n    enum isDynamicArray = is(DynamicArrayTypeOf!T)/+ && !isAggregateType!T+/;\n}\n\ntemplate isArray(T)\n{\n    enum bool isArray = /+isStaticArray!T || +/isDynamicArray!T;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test10327/empty.d",
    "content": "module empty;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152a.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152b.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152c.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152d.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152e.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152f.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152g.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152h.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152i.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152j.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152k.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152l.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152m.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152n.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152o.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152p.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152q.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152r.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152s.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152t.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152u.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152v.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152w.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152x.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152y.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test13152z.d",
    "content": "public import imports.test13152a;\npublic import imports.test13152b;\npublic import imports.test13152c;\npublic import imports.test13152d;\npublic import imports.test13152e;\npublic import imports.test13152f;\npublic import imports.test13152g;\npublic import imports.test13152h;\npublic import imports.test13152i;\npublic import imports.test13152j;\npublic import imports.test13152k;\npublic import imports.test13152l;\npublic import imports.test13152m;\npublic import imports.test13152n;\npublic import imports.test13152o;\npublic import imports.test13152p;\npublic import imports.test13152q;\npublic import imports.test13152r;\npublic import imports.test13152s;\npublic import imports.test13152t;\npublic import imports.test13152u;\npublic import imports.test13152v;\npublic import imports.test13152w;\npublic import imports.test13152x;\npublic import imports.test13152y;\npublic import imports.test13152z;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test143.d",
    "content": "module imports.test143;\n\npackage int x = 5;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test15785.d",
    "content": "module imports.test15785;\n\nclass Base\n{\n    private void foo() {}\n    private void bar() {}\n    private alias T = int;\n}\n\ninterface IBase2\n{\n    private alias T = int;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test15897.d",
    "content": "module imports.test15897;\nimport test15897;\n\nclass Cat : Animal\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test18480b.d",
    "content": "template TestTemplate() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test5412a.d",
    "content": "module imports.test5412a;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test5412b.d",
    "content": "module imports.test5412b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/imports/test64a.d",
    "content": "module imports;\n\nconst char[] file1 = \"File1\";\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/isreturnonstack.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/isreturnonstack.d(11): Error: argument to `__traits(isReturnOnStack, int)` is not a function\nfail_compilation/isreturnonstack.d(12): Error: expected 1 arguments for `isReturnOnStack` but had 2\n---\n*/\n\nint test() { return 0; }\n\nenum b = __traits(isReturnOnStack, int);\nenum c = __traits(isReturnOnStack, test, int);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/issue3827.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/issue3827.d(12): Error: Implicit string concatenation is deprecated, use \"Hello\" ~ \"World\" instead\nfail_compilation/issue3827.d(13): Error: Implicit string concatenation is deprecated, use \"A\" ~ \"B\" instead\n---\n*/\n\nvoid main ()\n{\n    string[] arr = [ \"Hello\" \"World\" ];\n    auto foo = \"A\" \"B\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/lexer1.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/lexer1.d(30): Deprecation: Built-in hex string literals are deprecated, use `std.conv.hexString` instead.\nfail_compilation/lexer1.d(30): Error: declaration expected, not `x\"01 02 03\"w`\nfail_compilation/lexer1.d(31): Error: declaration expected, not `2147483649U`\nfail_compilation/lexer1.d(32): Error: declaration expected, not `0.1`\nfail_compilation/lexer1.d(33): Error: declaration expected, not `0.1f`\nfail_compilation/lexer1.d(34): Error: declaration expected, not `0.1L`\nfail_compilation/lexer1.d(35): Error: declaration expected, not `0.1i`\nfail_compilation/lexer1.d(36): Error: declaration expected, not `0.1fi`\nfail_compilation/lexer1.d(37): Error: declaration expected, not `0.1Li`\nfail_compilation/lexer1.d(38): Error: declaration expected, not `32U`\nfail_compilation/lexer1.d(39): Error: declaration expected, not `55295U`\nfail_compilation/lexer1.d(40): Error: declaration expected, not `65536U`\nfail_compilation/lexer1.d(41): Error: declaration expected, not `\"ab\\\\c\\\"\\u1234a\\U00011100a\"d`\nfail_compilation/lexer1.d(43): Error: declaration expected, not `module`\nfail_compilation/lexer1.d(45): Error: escape hex sequence has 1 hex digits instead of 2\nfail_compilation/lexer1.d(46): Error: undefined escape hex sequence \\xG\nfail_compilation/lexer1.d(47): Error: unnamed character entity &unnamedentity;\nfail_compilation/lexer1.d(48): Error: unterminated named entity &1;\nfail_compilation/lexer1.d(49): Error: unterminated named entity &*;\nfail_compilation/lexer1.d(50): Error: unterminated named entity &s1\";\nfail_compilation/lexer1.d(51): Error: unterminated named entity &2;\nfail_compilation/lexer1.d(52): Error: escape octal sequence \\400 is larger than \\377\n---\n*/\n\n// https://dlang.dawg.eu/coverage/src/lexer.c.gcov.html\nx\"01 02 03\"w;\n0x80000001;\n0.1;\n0.1f;\n0.1L;\n0.1i;\n0.1fi;\n0.1Li;\n' ';\n'\\uD7FF';\n'\\U00010000';\n\"ab\\\\c\\\"\\u1234a\\U00011100a\\000ab\"d;\n\nmodule x;\n\nstatic s1 = \"\\x1G\";\nstatic s2 = \"\\xGG\";\nstatic s3 = \"\\&unnamedentity;\";\nstatic s4 = \"\\&1\";\nstatic s5 = \"\\&*\";\nstatic s6 = \"\\&s1\";\nstatic s7 = \"\\&2;\";\nstatic s7 = \"\\400;\";\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/lexer2.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/lexer2.d(16): Error: odd number (3) of hex characters in hex string\nfail_compilation/lexer2.d(16): Deprecation: Built-in hex string literals are deprecated, use `std.conv.hexString` instead.\nfail_compilation/lexer2.d(17): Error: non-hex character 'G' in hex string\nfail_compilation/lexer2.d(17): Deprecation: Built-in hex string literals are deprecated, use `std.conv.hexString` instead.\nfail_compilation/lexer2.d(18): Error: heredoc rest of line should be blank\nfail_compilation/lexer2.d(20): Error: unterminated delimited string constant starting at fail_compilation/lexer2.d(20)\nfail_compilation/lexer2.d(22): Error: semicolon expected following auto declaration, not `End of File`\n---\n*/\n\n// https://dlang.dawg.eu/coverage/src/lexer.c.gcov.html\n\nstatic s1 = x\"123\";\nstatic s2 = x\"123G\";\nstatic s4 = q\"here notblank\nhere\";\nstatic s5 = q\"here\n\";\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/lexer3.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/lexer3.d(9): Error: unterminated token string constant starting at fail_compilation/lexer3.d(9)\nfail_compilation/lexer3.d(10): Error: semicolon expected following auto declaration, not `End of File`\n---\n*/\n\nstatic s1 = q{ asef;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/lexer4.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/lexer4.d(22): Error: unterminated character constant\nfail_compilation/lexer4.d(24): Error: unterminated character constant\nfail_compilation/lexer4.d(25): Error: unterminated character constant\nfail_compilation/lexer4.d(26): Error: binary digit expected, not `2`\nfail_compilation/lexer4.d(27): Error: octal digit expected, not `8`\nfail_compilation/lexer4.d(27): Error: octal literals larger than 7 are no longer supported\nfail_compilation/lexer4.d(28): Error: decimal digit expected, not `a`\nfail_compilation/lexer4.d(29): Error: unrecognized token\nfail_compilation/lexer4.d(30): Error: exponent required for hex float\nfail_compilation/lexer4.d(31): Error: lower case integer suffix 'l' is not allowed. Please use 'L' instead\nfail_compilation/lexer4.d(32): Error: use 'i' suffix instead of 'I'\nfail_compilation/lexer4.d(34): Error: line number `1234567891234567879` out of range\nfail_compilation/lexer4.d(36): Error: #line integer [\"filespec\"]\\n expected\nfail_compilation/lexer4.d(19): Error: #line integer [\"filespec\"]\\n expected\nfail_compilation/lexer4.d(19): Error: declaration expected, not `\"file\"`\n---\n*/\n\nstatic c1 = '\n;\nstatic c2 = '';\nstatic c3 = 'a;\nint i = 0b12;\nint j = 0128;\nint k = 12a;\nint l = 12UU;\nint f = 0x1234.0;\nint m = 12l;\nstatic n = 12.1I;\n\n#line 1234567891234567879\n\n#line whatever\n\n#line 18 __FILE__\n\n#line 20 \"file\" \"file\"\n\n/** asdf *//** asdf2 */\nint o;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/lookup.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/lookup.d(23): Error: no property `X` for type `lookup.B`\nfail_compilation/lookup.d(23):        while evaluating: `static assert((B).X == 0)`\nfail_compilation/lookup.d(24): Error: no property `Y` for type `lookup.B`\nfail_compilation/lookup.d(24):        while evaluating: `static assert((B).Y == 2)`\n---\n*/\n\nimport imports.imp1;\n\nenum X = 0;\n\nclass B\n{\n    import imports.imp2;\n    static assert(X == 0);\n    static assert(Y == 2);\n}\nclass C : B\n{\n    static assert(B.X == 0);\n    static assert(B.Y == 2);\n\n    static assert(X == 0);\n    static assert(Y == 1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/mangle1.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/mangle1.d(8): Error: pragma `mangle` can only apply to a single declaration\n---\n*/\n\npragma(mangle, \"_stuff_\") __gshared { int x, y; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/mangle2.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/mangle2.d(20): Error: pragma `mangle` char 0x20 not allowed in mangled name\nfail_compilation/mangle2.d(21): Error: pragma `mangle` char 0x20 not allowed in mangled name\nfail_compilation/mangle2.d(24): Error: pragma `mangle` char 0x0a not allowed in mangled name\nfail_compilation/mangle2.d(25): Error: pragma `mangle` char 0x0a not allowed in mangled name\nfail_compilation/mangle2.d(28): Error: pragma `mangle` char 0x07 not allowed in mangled name\nfail_compilation/mangle2.d(29): Error: pragma `mangle` char 0x07 not allowed in mangled name\nfail_compilation/mangle2.d(32): Error: pragma `mangle` char 0x01 not allowed in mangled name\nfail_compilation/mangle2.d(33): Error: pragma `mangle` char 0x01 not allowed in mangled name\nfail_compilation/mangle2.d(36): Error: pragma `mangle` char 0x00 not allowed in mangled name\nfail_compilation/mangle2.d(37): Error: pragma `mangle` char 0x00 not allowed in mangled name\nfail_compilation/mangle2.d(40): Error: pragma `mangle` Outside Unicode code space\nfail_compilation/mangle2.d(41): Error: pragma `mangle` Outside Unicode code space\n---\n*/\n\n//spaces\n__gshared pragma(mangle, \"test 9\") ubyte test9_1;\n__gshared extern pragma(mangle, \"test 9\") ubyte test9_1_e;\n\n//\\n chars\n__gshared pragma(mangle, \"test\\n9\") ubyte test9_2;\n__gshared extern pragma(mangle, \"test\\n9\") ubyte test9_2_e;\n\n//\\a chars\n__gshared pragma(mangle, \"test\\a9\") ubyte test9_3;\n__gshared extern pragma(mangle, \"test\\a9\") ubyte test9_3_e;\n\n//\\x01 chars\n__gshared pragma(mangle, \"test\\x019\") ubyte test9_4;\n__gshared extern pragma(mangle, \"test\\x019\") ubyte test9_4_e;\n\n//\\0 chars\n__gshared pragma(mangle, \"test\\09\") ubyte test9_5;\n__gshared extern pragma(mangle, \"test\\09\") ubyte test9_5_e;\n\n//\\xff chars\n__gshared pragma(mangle, \"test\\xff9\") ubyte test9_6;\n__gshared extern pragma(mangle, \"test\\xff9\") ubyte test9_6_e;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/moduleundefuda.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/moduleundefuda.d(7): Error: undefined identifier `undef`\n---\n*/\n@undef module moduleundefuda;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/no_Throwable.d",
    "content": "/* \nDFLAGS:\nREQUIRED_ARGS: -c\nEXTRA_SOURCES: extra-files/no_Throwable/object.d\nTEST_OUTPUT:\n---\nfail_compilation/no_Throwable.d(13): Error: Cannot use `throw` statements because `object.Throwable` was not declared\nfail_compilation/no_Throwable.d(18): Error: Cannot use try-catch statements because `object.Throwable` was not declared\n---\n*/\n\nvoid test()\n{\n    throw new Exception(\"msg\");\n}\n\nvoid test2()\n{\n    try\n    {\n        test();\n    }\n    catch (Exception e)\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/no_TypeInfo.d",
    "content": "/* \nDFLAGS:\nREQUIRED_ARGS: -c\nEXTRA_SOURCES: extra-files/no_TypeInfo/object.d\nTEST_OUTPUT:\n---\nfail_compilation/no_TypeInfo.d(13): Error: `object.TypeInfo` could not be found, but is implicitly used\n---\n*/\n\nvoid test()\n{\n    int i;\n    auto ti = typeid(i);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/nogc1.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\n/***************** NewExp *******************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc1.d(17): Deprecation: class allocators have been deprecated, consider moving the allocation strategy outside of the class\nfail_compilation/nogc1.d(18): Deprecation: class allocators have been deprecated, consider moving the allocation strategy outside of the class\n---\n*/\n\nstruct S1 { }\nstruct S2 { this(int); }\nstruct S3 { this(int) @nogc; }\nstruct S4 { new(size_t); }\nstruct S5 { @nogc new(size_t); }\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc1.d(35): Error: cannot use `new` in `@nogc` function `nogc1.testNew`\nfail_compilation/nogc1.d(37): Error: cannot use `new` in `@nogc` function `nogc1.testNew`\nfail_compilation/nogc1.d(38): Error: cannot use `new` in `@nogc` function `nogc1.testNew`\nfail_compilation/nogc1.d(40): Error: cannot use `new` in `@nogc` function `nogc1.testNew`\nfail_compilation/nogc1.d(41): Error: `@nogc` function `nogc1.testNew` cannot call non-@nogc constructor `nogc1.S2.this`\nfail_compilation/nogc1.d(42): Error: cannot use `new` in `@nogc` function `nogc1.testNew`\nfail_compilation/nogc1.d(43): Error: `@nogc` function `nogc1.testNew` cannot call non-@nogc allocator `nogc1.S4.new`\nfail_compilation/nogc1.d(46): Error: cannot use `new` in `@nogc` function `nogc1.testNew`\n---\n*/\n@nogc void testNew()\n{\n    int* p1 = new int;\n\n    int[] a1 = new int[3];\n    int[][] a2 = new int[][](2, 3);\n\n    S1* ps1 = new S1();\n    S2* ps2 = new S2(1);\n    S3* ps3 = new S3(1);\n    S4* ps4 = new S4;\n    S5* ps5 = new S5;   // no error\n\n    Object o1 = new Object();\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc1.d(63): Error: cannot use `new` in `@nogc` function `nogc1.testNewScope`\nfail_compilation/nogc1.d(65): Error: cannot use `new` in `@nogc` function `nogc1.testNewScope`\nfail_compilation/nogc1.d(66): Error: cannot use `new` in `@nogc` function `nogc1.testNewScope`\nfail_compilation/nogc1.d(68): Error: cannot use `new` in `@nogc` function `nogc1.testNewScope`\nfail_compilation/nogc1.d(69): Error: `@nogc` function `nogc1.testNewScope` cannot call non-@nogc constructor `nogc1.S2.this`\nfail_compilation/nogc1.d(70): Error: cannot use `new` in `@nogc` function `nogc1.testNewScope`\nfail_compilation/nogc1.d(71): Error: `@nogc` function `nogc1.testNewScope` cannot call non-@nogc allocator `nogc1.S4.new`\n---\n*/\n@nogc void testNewScope()\n{\n    scope int* p1 = new int;\n\n    scope int[] a1 = new int[3];\n    scope int[][] a2 = new int[][](2, 3);\n\n    scope S1* ps1 = new S1();\n    scope S2* ps2 = new S2(1);\n    scope S3* ps3 = new S3(1);\n    scope S4* ps4 = new S4;\n    scope S5* ps5 = new S5;             // no error\n\n    scope Object o1 = new Object();     // no error\n    scope o2 = new Object();            // no error\n}\n\n/***************** DeleteExp *******************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc1.d(93): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/nogc1.d(93): Error: cannot use `delete` in `@nogc` function `nogc1.testDelete`\nfail_compilation/nogc1.d(94): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/nogc1.d(94): Error: cannot use `delete` in `@nogc` function `nogc1.testDelete`\nfail_compilation/nogc1.d(95): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/nogc1.d(95): Error: cannot use `delete` in `@nogc` function `nogc1.testDelete`\n---\n*/\n@nogc void testDelete(int* p, Object o, S1* s)\n{\n    delete p;\n    delete o;\n    delete s;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/nogc2.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\n/***************** CatExp *******************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc2.d(21): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`\nfail_compilation/nogc2.d(22): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`\nfail_compilation/nogc2.d(23): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`\nfail_compilation/nogc2.d(25): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`\nfail_compilation/nogc2.d(26): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`\nfail_compilation/nogc2.d(27): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`\nfail_compilation/nogc2.d(28): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`\nfail_compilation/nogc2.d(29): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`\n---\n*/\n@nogc void testCat(int[] a, string s)\n{\n    int[] a1 = a ~ a;\n    int[] a2 = a ~ 1;\n    int[] a3 = 1 ~ a;\n\n    string s1 = s ~ s;\n    string s2 = s ~ \"a\";\n    string s3 = \"a\" ~ s;\n    string s4 = s ~ 'c';\n    string s5 = 'c' ~ s;\n\n    string s6 = \"a\" ~ \"b\";      // no error\n    string s7 = \"a\" ~ 'c';      // no error\n    string s8 = 'c' ~ \"b\";      // no error\n}\n\n/***************** CatAssignExp *******************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc2.d(48): Error: cannot use operator `~=` in `@nogc` function `nogc2.testCatAssign`\nfail_compilation/nogc2.d(50): Error: cannot use operator `~=` in `@nogc` function `nogc2.testCatAssign`\nfail_compilation/nogc2.d(51): Error: cannot use operator `~=` in `@nogc` function `nogc2.testCatAssign`\n---\n*/\n@nogc void testCatAssign(int[] a, string s)\n{\n    a ~= 1;\n\n    s ~= \"a\";\n    s ~= 'c';\n}\n\n/***************** ArrayLiteralExp *******************/\n\n@nogc int* barA();\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc2.d(70): Error: array literal in `@nogc` function `nogc2.testArray` may cause a GC allocation\nfail_compilation/nogc2.d(71): Error: array literal in `@nogc` function `nogc2.testArray` may cause a GC allocation\n---\n*/\n@nogc void testArray()\n{\n    enum arrLiteral = [null, null];\n\n    int* p;\n    auto a = [p, p, barA()];\n    a = arrLiteral;\n}\n\n/***************** AssocArrayLiteralExp *******************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc2.d(87): Error: associative array literal in `@nogc` function `nogc2.testAssocArray` may cause a GC allocation\nfail_compilation/nogc2.d(88): Error: associative array literal in `@nogc` function `nogc2.testAssocArray` may cause a GC allocation\n---\n*/\n@nogc void testAssocArray()\n{\n    enum aaLiteral = [10: 100];\n\n    auto aa = [1:1, 2:3, 4:5];\n    aa = aaLiteral;\n}\n\n/***************** IndexExp *******************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc2.d(102): Error: indexing an associative array in `@nogc` function `nogc2.testIndex` may cause a GC allocation\nfail_compilation/nogc2.d(103): Error: indexing an associative array in `@nogc` function `nogc2.testIndex` may cause a GC allocation\n---\n*/\n@nogc void testIndex(int[int] aa)\n{\n    aa[1] = 0;\n    int n = aa[1];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/nogc3.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\n/***************** AssignExp *******************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc3.d(16): Error: setting `length` in `@nogc` function `nogc3.testArrayLength` may cause a GC allocation\nfail_compilation/nogc3.d(17): Error: setting `length` in `@nogc` function `nogc3.testArrayLength` may cause a GC allocation\nfail_compilation/nogc3.d(18): Error: setting `length` in `@nogc` function `nogc3.testArrayLength` may cause a GC allocation\n---\n*/\n@nogc void testArrayLength(int[] a)\n{\n    a.length = 3;\n    a.length += 1;\n    a.length -= 1;\n}\n\n/***************** CallExp *******************/\n\nvoid barCall();\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc3.d(35): Error: `@nogc` function `nogc3.testCall` cannot call non-@nogc function pointer `fp`\nfail_compilation/nogc3.d(36): Error: `@nogc` function `nogc3.testCall` cannot call non-@nogc function `nogc3.barCall`\n---\n*/\n@nogc void testCall()\n{\n    auto fp = &barCall;\n    (*fp)();\n    barCall();\n}\n\n/****************** Closure ***********************/\n\n@nogc void takeDelegate2(scope int delegate() dg) {}\n@nogc void takeDelegate3(      int delegate() dg) {}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc3.d(53): Error: function `nogc3.testClosure1` is `@nogc` yet allocates closures with the GC\nfail_compilation/nogc3.d(56):        nogc3.testClosure1.bar closes over variable x at fail_compilation/nogc3.d(55)\nfail_compilation/nogc3.d(65): Error: function `nogc3.testClosure3` is `@nogc` yet allocates closures with the GC\nfail_compilation/nogc3.d(68):        nogc3.testClosure3.bar closes over variable x at fail_compilation/nogc3.d(67)\n---\n*/\n@nogc auto testClosure1()\n{\n    int x;\n    int bar() { return x; }\n    return &bar;\n}\n@nogc void testClosure2()\n{\n    int x;\n    int bar() { return x; }\n    takeDelegate2(&bar);     // no error\n}\n@nogc void testClosure3()\n{\n    int x;\n    int bar() { return x; }\n    takeDelegate3(&bar);\n}\n\n/****************** ErrorExp ***********************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/nogc3.d(86): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation\nfail_compilation/nogc3.d(87): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation\nfail_compilation/nogc3.d(93): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation\nfail_compilation/nogc3.d(92): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation\n---\n*/\nint[] foo13702(bool b) @nogc\n{\n    if (b)\n        return [1];     // error\n    return 1 ~ [2];     // error\n}\nint[] bar13702(bool b) @nogc\n{\n    if (b)\n        return [1];     // error <- no error report\n    auto aux = 1 ~ [2]; // error\n    return aux;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/notype.d",
    "content": "struct S(int var = 3) {\n    int a;\n}\nS s;\n\nalias A() = int;\nA a;\n\nenum e() = 5;\ne val;\n\ninterface I()\n{\n}\nI i;\n\ntemplate t()\n{\n}\nt tv;\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/notype.d(4): Error: template struct `notype.S(int var = 3)` is used as a type without instantiation; to instantiate it use `S!(arguments)`\nfail_compilation/notype.d(7): Error: template `notype.A()` is used as a type\nfail_compilation/notype.d(10): Error: template `notype.e()` is used as a type\nfail_compilation/notype.d(15): Error: template interface `notype.I()` is used as a type without instantiation; to instantiate it use `I!(arguments)`\nfail_compilation/notype.d(20): Error: template `notype.t()` is used as a type\n---\n*/\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/objc_non_objc_base.d",
    "content": "// EXTRA_OBJC_SOURCES\n/*\nTEST_OUTPUT:\n---\nfail_compilation/objc_non_objc_base.d(12): Error: interface `objc_non_objc_base.A` base interface for an Objective-C interface must be `extern (Objective-C)`\n---\n*/\n\ninterface Base {}\n\nextern (Objective-C)\ninterface A : Base {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/parse12924.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/parse12924.d(14): Error: declaration expected following attribute, not `;`\nfail_compilation/parse12924.d(15): Error: declaration expected following attribute, not `;`\nfail_compilation/parse12924.d(16): Error: declaration expected following attribute, not `;`\nfail_compilation/parse12924.d(17): Error: declaration expected following attribute, not `;`\nfail_compilation/parse12924.d(18): Error: declaration expected following attribute, not `;`\nfail_compilation/parse12924.d(19): Error: declaration expected following attribute, not `;`\nfail_compilation/parse12924.d(20): Error: declaration expected following attribute, not `;`\n---\n*/\n\nstatic;         void f1() {}\ndeprecated;     void f2() {}\ndeprecated(\"\"); void f3() {}\nextern(C);      void f4() {}\npublic;         void f5() {}\nalign(1);       void f6() {}\n@(1);           void f7() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/parse12967a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/parse12967a.d(14): Error: function `parse12967a.pre_i1` without `this` cannot be `immutable`\nfail_compilation/parse12967a.d(15): Error: function `parse12967a.pre_i2` without `this` cannot be `immutable`\nfail_compilation/parse12967a.d(16): Error: function `parse12967a.pre_c1` without `this` cannot be `const`\nfail_compilation/parse12967a.d(17): Error: function `parse12967a.pre_c2` without `this` cannot be `const`\nfail_compilation/parse12967a.d(18): Error: function `parse12967a.pre_w1` without `this` cannot be `inout`\nfail_compilation/parse12967a.d(19): Error: function `parse12967a.pre_w2` without `this` cannot be `inout`\nfail_compilation/parse12967a.d(20): Error: function `parse12967a.pre_s1` without `this` cannot be `shared`\nfail_compilation/parse12967a.d(21): Error: function `parse12967a.pre_s2` without `this` cannot be `shared`\n---\n*/\nimmutable      pre_i1() {}\nimmutable void pre_i2() {}\nconst          pre_c1() {}\nconst     void pre_c2() {}\ninout          pre_w1() {}\ninout     void pre_w2() {}\nshared         pre_s1() {}\nshared    void pre_s2() {}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parse12967a.d(36): Error: function `parse12967a.post_i1` without `this` cannot be `immutable`\nfail_compilation/parse12967a.d(37): Error: function `parse12967a.post_i2` without `this` cannot be `immutable`\nfail_compilation/parse12967a.d(38): Error: function `parse12967a.post_c1` without `this` cannot be `const`\nfail_compilation/parse12967a.d(39): Error: function `parse12967a.post_c2` without `this` cannot be `const`\nfail_compilation/parse12967a.d(40): Error: function `parse12967a.post_w1` without `this` cannot be `inout`\nfail_compilation/parse12967a.d(41): Error: function `parse12967a.post_w2` without `this` cannot be `inout`\nfail_compilation/parse12967a.d(42): Error: function `parse12967a.post_s1` without `this` cannot be `shared`\nfail_compilation/parse12967a.d(43): Error: function `parse12967a.post_s2` without `this` cannot be `shared`\n---\n*/\nauto post_i1() immutable {}\nvoid post_i2() immutable {}\nauto post_c1() const     {}\nvoid post_c2() const     {}\nauto post_w1() inout     {}\nvoid post_w2() inout     {}\nauto post_s1() shared    {}\nvoid post_s2() shared    {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/parse12967b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/parse12967b.d(24): Error: function `parse12967b.C.pre_c` without `this` cannot be `const`\nfail_compilation/parse12967b.d(25): Error: function `parse12967b.C.pre_i` without `this` cannot be `immutable`\nfail_compilation/parse12967b.d(26): Error: function `parse12967b.C.pre_w` without `this` cannot be `inout`\nfail_compilation/parse12967b.d(27): Error: function `parse12967b.C.pre_s` without `this` cannot be `shared`\nfail_compilation/parse12967b.d(29): Error: function `parse12967b.C.post_c` without `this` cannot be `const`\nfail_compilation/parse12967b.d(30): Error: function `parse12967b.C.post_i` without `this` cannot be `immutable`\nfail_compilation/parse12967b.d(31): Error: function `parse12967b.C.post_w` without `this` cannot be `inout`\nfail_compilation/parse12967b.d(32): Error: function `parse12967b.C.post_s` without `this` cannot be `shared`\nfail_compilation/parse12967b.d(37): Error: function `parse12967b.D.pre_c` without `this` cannot be `const`\nfail_compilation/parse12967b.d(38): Error: function `parse12967b.D.pre_i` without `this` cannot be `immutable`\nfail_compilation/parse12967b.d(39): Error: function `parse12967b.D.pre_w` without `this` cannot be `inout`\nfail_compilation/parse12967b.d(40): Error: function `parse12967b.D.pre_s` without `this` cannot be `shared`\nfail_compilation/parse12967b.d(41): Error: function `parse12967b.D.post_c` without `this` cannot be `const`\nfail_compilation/parse12967b.d(42): Error: function `parse12967b.D.post_i` without `this` cannot be `immutable`\nfail_compilation/parse12967b.d(43): Error: function `parse12967b.D.post_w` without `this` cannot be `inout`\nfail_compilation/parse12967b.d(44): Error: function `parse12967b.D.post_s` without `this` cannot be `shared`\n---\n*/\nclass C\n{\n    const     static      pre_c() {}\n    immutable static      pre_i() {}\n    inout     static      pre_w() {}\n    shared    static      pre_s() {}\n\n    static      post_c() const     {}\n    static      post_i() immutable {}\n    static      post_w() inout     {}\n    static      post_s() shared    {}\n}\n\nclass D\n{\n    const     static void pre_c() {}\n    immutable static void pre_i() {}\n    inout     static void pre_w() {}\n    shared    static void pre_s() {}\n    static void post_c() const     {}\n    static void post_i() immutable {}\n    static void post_w() inout     {}\n    static void post_s() shared    {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/parse13361.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/parse13361.d(11): Error: empty attribute list is not allowed\nfail_compilation/parse13361.d(14): Error: empty attribute list is not allowed\nfail_compilation/parse13361.d(14): Error: use `@(attributes)` instead of `[attributes]`\n---\n*/\nstruct A\n{\n  @()\n    int b;\n\n  []    // deprecated style\n    int c;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/parse14285.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/parse14285.d(10): Error: no identifier for declarator `this`\n---\n*/\n\nstruct S\n{\n    alias this;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/parse14745.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/parse14745.d(11): Error: function literal cannot be `immutable`\nfail_compilation/parse14745.d(12): Error: function literal cannot be `const`\n---\n*/\n\nvoid test14745()\n{\n    auto fp1 = function () pure immutable { return 0; };\n    auto fp2 = function () pure const { return 0; };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/parseStc.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc.d(11): Error: found `;` when expecting `)`\nfail_compilation/parseStc.d(11): Error: found `)` when expecting `;` following statement\nfail_compilation/parseStc.d(12): Error: redundant attribute `const`\n---\n*/\nvoid test1()\n{\n    if (x; 1) {}\n    if (const const auto x = 1) {}\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc.d(25): Error: redundant attribute `const`\nfail_compilation/parseStc.d(26): Error: redundant attribute `const`\nfail_compilation/parseStc.d(27): Error: conflicting attribute `immutable`\n---\n*/\nvoid test2()\n{\n    const const x = 1;\n    foreach (const const x; [1,2,3]) {}\n    foreach (const immutable x; [1,2,3]) {}\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc.d(37): Error: redundant attribute `const`\nfail_compilation/parseStc.d(38): Error: redundant attribute `const`\n---\n*/\nstruct S3 { const const test3() {} }\nvoid test4(const const int x) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/parseStc2.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc2.d(11): Error: conflicting attribute `const`\nfail_compilation/parseStc2.d(12): Error: conflicting attribute `@system`\nfail_compilation/parseStc2.d(13): Error: conflicting attribute `@safe`\nfail_compilation/parseStc2.d(14): Error: conflicting attribute `@trusted`\nfail_compilation/parseStc2.d(15): Error: conflicting attribute `__gshared`\n---\n*/\nimmutable const void f4() {}\n@safe @system void f4() {}\n@trusted @safe void f4() {}\n@system @trusted void f4() {}\nshared __gshared f4() {}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc2.d(26): Error: redundant attribute `static`\nfail_compilation/parseStc2.d(27): Error: redundant attribute `pure`\nfail_compilation/parseStc2.d(28): Error: redundant attribute `@property`\nfail_compilation/parseStc2.d(29): Error: redundant attribute `@safe`\n---\n*/\nstatic static void f1() {}\npure nothrow pure void f2() {}\n@property extern(C) @property void f3() {}\ndeprecated(\"\") @safe @safe void f4() {}\n@(1) @(1) void f5() {}  // OK\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc2.d(39): Error: redundant linkage `extern (C)`\nfail_compilation/parseStc2.d(40): Error: conflicting linkage `extern (C)` and `extern (C++)`\n---\n*/\nextern(C) extern(C) void f6() {}\nextern(C) extern(C++) void f7() {}\nextern(C++, foo) extern(C++, bar) void f8() {}  // OK\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc2.d(50): Error: redundant protection attribute `public`\nfail_compilation/parseStc2.d(51): Error: conflicting protection attribute `public` and `private`\n---\n*/\npublic public void f9() {}\npublic private void f10() {}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc2.d(63): Error: redundant alignment attribute `align`\nfail_compilation/parseStc2.d(64): Error: redundant alignment attribute `align(1)`\nfail_compilation/parseStc2.d(65): Error: redundant alignment attribute `align(1)`\nfail_compilation/parseStc2.d(66): Error: redundant alignment attribute `align`\nfail_compilation/parseStc2.d(67): Error: redundant alignment attribute `align(2)`\n---\n*/\nalign    align    void f11() {}\nalign(1) align(1) void f12() {}\nalign    align(1) void f13() {}\nalign(1) align    void f14() {}\nalign(1) align(2) void f15() {}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc2.d(76): Error: redundant linkage `extern (System)`\nfail_compilation/parseStc2.d(77): Error: conflicting linkage `extern (System)` and `extern (C++)`\n---\n*/\nextern(System) extern(System) void f16() {}\nextern(System) extern(C++) void f17() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/parseStc3.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc3.d(10): Error: redundant attribute `pure`\nfail_compilation/parseStc3.d(11): Error: redundant attribute `nothrow`\nfail_compilation/parseStc3.d(12): Error: redundant attribute `@nogc`\nfail_compilation/parseStc3.d(13): Error: redundant attribute `@property`\n---\n*/\npure      void f1() pure      {}\nnothrow   void f2() nothrow   {}\n@nogc     void f3() @nogc     {}\n@property void f4() @property {}\n//ref     int  f5() ref       { static int g; return g; }\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc3.d(24): Error: redundant attribute `@safe`\nfail_compilation/parseStc3.d(25): Error: redundant attribute `@system`\nfail_compilation/parseStc3.d(26): Error: redundant attribute `@trusted`\n---\n*/\n@safe     void f6() @safe    {}\n@system   void f7() @system  {}\n@trusted  void f8() @trusted {}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc3.d(39): Error: conflicting attribute `@system`\nfail_compilation/parseStc3.d(40): Error: conflicting attribute `@trusted`\nfail_compilation/parseStc3.d(41): Error: conflicting attribute `@safe`\nfail_compilation/parseStc3.d(42): Error: conflicting attribute `@trusted`\nfail_compilation/parseStc3.d(43): Error: conflicting attribute `@safe`\nfail_compilation/parseStc3.d(44): Error: conflicting attribute `@system`\n---\n*/\n@safe     void f9()  @system  {}\n@safe     void f10() @trusted {}\n@system   void f11() @safe    {}\n@system   void f12() @trusted {}\n@trusted  void f13() @safe    {}\n@trusted  void f14() @system  {}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc3.d(59): Error: conflicting attribute `@system`\nfail_compilation/parseStc3.d(59): Error: conflicting attribute `@trusted`\nfail_compilation/parseStc3.d(60): Error: conflicting attribute `@system`\nfail_compilation/parseStc3.d(60): Error: redundant attribute `@system`\nfail_compilation/parseStc3.d(61): Error: conflicting attribute `@safe`\nfail_compilation/parseStc3.d(61): Error: redundant attribute `@system`\nfail_compilation/parseStc3.d(62): Error: conflicting attribute `@safe`\nfail_compilation/parseStc3.d(62): Error: redundant attribute `@trusted`\n---\n*/\n@safe @system  void f15() @trusted {}\n@safe @system  void f16() @system  {}\n@system @safe  void f17() @system  {}\n@trusted @safe void f18() @trusted {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/parseStc4.d",
    "content": "\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc4.d(14): Error: redundant attribute `pure`\nfail_compilation/parseStc4.d(14): Error: redundant attribute `nothrow`\nfail_compilation/parseStc4.d(14): Error: conflicting attribute `@system`\nfail_compilation/parseStc4.d(14): Error: redundant attribute `@nogc`\nfail_compilation/parseStc4.d(14): Error: redundant attribute `@property`\n---\n*/\npure nothrow @safe   @nogc @property\nint foo()\npure nothrow @system @nogc @property\n{\n    return 0;\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc4.d(35): Error: redundant attribute `const`\nfail_compilation/parseStc4.d(36): Error: redundant attribute `const`\nfail_compilation/parseStc4.d(36): Deprecation: `const` postblit is deprecated. Please use an unqualified postblit.\nfail_compilation/parseStc4.d(37): Error: redundant attribute `const`\nfail_compilation/parseStc4.d(39): Error: redundant attribute `pure`\nfail_compilation/parseStc4.d(40): Error: redundant attribute `@safe`\nfail_compilation/parseStc4.d(41): Error: redundant attribute `nothrow`\nfail_compilation/parseStc4.d(42): Error: conflicting attribute `@trusted`\n---\n*/\n\nstruct S\n{\n    const this(int) const {}\n    const this(this) const {}\n    const ~this() const {}\n\n    pure static this() pure {}\n    @safe static ~this() @safe {}\n    nothrow shared static this() nothrow {}\n    @system shared static ~this() @trusted {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/parseStc5.d",
    "content": "// REQUIRED_ARGS:\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc5.d(11): Error: constructor cannot be static\nfail_compilation/parseStc5.d(12): Error: postblit cannot be `static`\n---\n*/\nclass C1\n{\n    static pure this(int) {}        // `static pure` + `this(int)`\n    static pure this(this) {}       // `static pure` + `this(this)`\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc5.d(28): Error: use `shared static this()` to declare a shared static constructor\nfail_compilation/parseStc5.d(29): Error: use `shared static this()` to declare a shared static constructor\nfail_compilation/parseStc5.d(31): Error: use `shared static this()` to declare a shared static constructor\nfail_compilation/parseStc5.d(33): Error: use `shared static ~this()` to declare a shared static destructor\nfail_compilation/parseStc5.d(34): Error: use `shared static ~this()` to declare a shared static destructor\nfail_compilation/parseStc5.d(36): Error: use `shared static ~this()` to declare a shared static destructor\n---\n*/\nclass C2    // wrong combinations of `shared`, `static`, and `~?this()`\n{\n    shared pure static this() {}    // `shared pure` + `static this()`\n    shared static pure this() {}    // `shared static pure` + `this()`\n\n    static this() shared {}         // `shared pure` + `static this()`\n\n    shared pure static ~this() {}   // `shared pure` + `static ~this()`\n    shared static pure ~this() {}   // `shared static pure` + `~this()`\n\n    static ~this() shared {}        // `shared` + `static ~this()`\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc5.d(48): Error: use `static this()` to declare a static constructor\nfail_compilation/parseStc5.d(49): Error: use `static ~this()` to declare a static destructor\n---\n*/\nclass C3    // wrong combinations of `static` and `~?this()`\n{\n    static pure this() {}           // `static pure` + `this()`\n    static pure ~this() {}          // `static pure` + `~this()`\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc5.d(64): Error: redundant attribute `shared`\nfail_compilation/parseStc5.d(65): Error: redundant attribute `shared`\nfail_compilation/parseStc5.d(67): Error: redundant attribute `static`\nfail_compilation/parseStc5.d(69): Error: redundant attribute `static shared`\nfail_compilation/parseStc5.d(70): Error: redundant attribute `static shared`\n---\n*/\nclass C4    // redundancy of `shared` and/or `static`\n{\n    shared shared static this() {}                  // `shared` + `shared static this()`\n    shared static this() shared {}                  // `shared` + `shared static this()`\n\n    static static this() {}                         // `static` + `shared static this()`\n\n    shared static shared static this() {}           // shared static + `shared static this()`\n    shared static shared static this() shared {}    // shared shared static + `shared static this()`\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/parseStc5.d(84): Error: static constructor cannot be `const`\nfail_compilation/parseStc5.d(85): Error: static destructor cannot be `const`\nfail_compilation/parseStc5.d(86): Error: shared static constructor cannot be `const`\nfail_compilation/parseStc5.d(87): Error: shared static destructor cannot be `const`\n---\n*/\nclass C5    // wrong MemberFunctionAttributes on `shared? static (con|de)structor`\n{\n    static this() const {}\n    static ~this() const {}\n    shared static this() const {}\n    shared static ~this() const {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/pragmainline.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/pragmainline.d(9): Error: pragma `inline` one boolean expression expected for `pragma(inline)`, not 3\nfail_compilation/pragmainline.d(10): Error: pragma `inline` pragma(`inline`, `true` or `false`) expected, not `\"string\"`\n---\n*/\n\npragma(inline, 1,2,3) void bar();\npragma(inline, \"string\") void baz();\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/pragmas.d",
    "content": "/*\nREQUIRED_ARGS:\nPERMUTE_ARGS:\n*/\n\n/************************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/pragmas.d(103): Error: boolean expression expected for `pragma(inline)`\nfail_compilation/pragmas.d(108): Error: boolean expression expected for `pragma(inline)`\nfail_compilation/pragmas.d(113): Error: pragma(inline, true or false) expected, not `\"string\"`\nfail_compilation/pragmas.d(118): Error: unrecognized `pragma(unrecognized)`\n---\n*/\n\n#line 100\nvoid test1()\n{\n    pragma(inline);\n    pragma(inline, true, false);\n}\n\nvoid test2()\n{\n    pragma(inline, true, false);\n}\n\nvoid test3()\n{\n    pragma(inline, \"string\");\n}\n\nvoid test4()\n{\n    pragma(unrecognized, \"string\");\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/protattr1.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/protection/subpkg/test1.d(3): Error: protection attribute `package(undefined)` does not bind to one of ancestor packages of module `protection.subpkg.test1`\n---\n*/\nimport protection.subpkg.test1;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/protattr2.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/protection/subpkg/test2.d(3): Error: protection attribute `package(protection.subpkg2)` does not bind to one of ancestor packages of module `protection.subpkg.test2`\n---\n*/\nimport protection.subpkg.test2;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/protattr3.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/protection/subpkg/test3.d(3): Error: `protection package` expected as dot-separated identifiers, got `123`\n---\n*/\nimport protection.subpkg.test3;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/protection/subpkg/test1.d",
    "content": "module protection.subpkg.test1;\n\npackage(undefined) void foo1();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/protection/subpkg/test2.d",
    "content": "module protection.subpkg.test2;\n\npackage(protection.subpkg2) void foo2();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/protection/subpkg/test3.d",
    "content": "module protection.subpkg.test3;\n\npackage(123) void foo3();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/reserved_version.d",
    "content": "// REQUIRED_ARGS: -verrors=0\n/*\nTEST_OUTPUT:\n---\nfail_compilation/reserved_version.d(105): Error: version identifier `MSP430` is reserved and cannot be set\nfail_compilation/reserved_version.d(106): Error: version identifier `D_P16` is reserved and cannot be set\nfail_compilation/reserved_version.d(107): Error: version identifier `DigitalMars` is reserved and cannot be set\nfail_compilation/reserved_version.d(108): Error: version identifier `GNU` is reserved and cannot be set\nfail_compilation/reserved_version.d(109): Error: version identifier `LDC` is reserved and cannot be set\nfail_compilation/reserved_version.d(110): Error: version identifier `SDC` is reserved and cannot be set\nfail_compilation/reserved_version.d(111): Error: version identifier `Windows` is reserved and cannot be set\nfail_compilation/reserved_version.d(112): Error: version identifier `Win32` is reserved and cannot be set\nfail_compilation/reserved_version.d(113): Error: version identifier `Win64` is reserved and cannot be set\nfail_compilation/reserved_version.d(114): Error: version identifier `linux` is reserved and cannot be set\nfail_compilation/reserved_version.d(115): Error: version identifier `OSX` is reserved and cannot be set\nfail_compilation/reserved_version.d(116): Error: version identifier `FreeBSD` is reserved and cannot be set\nfail_compilation/reserved_version.d(117): Error: version identifier `OpenBSD` is reserved and cannot be set\nfail_compilation/reserved_version.d(118): Error: version identifier `NetBSD` is reserved and cannot be set\nfail_compilation/reserved_version.d(119): Error: version identifier `DragonFlyBSD` is reserved and cannot be set\nfail_compilation/reserved_version.d(120): Error: version identifier `BSD` is reserved and cannot be set\nfail_compilation/reserved_version.d(121): Error: version identifier `Solaris` is reserved and cannot be set\nfail_compilation/reserved_version.d(122): Error: version identifier `Posix` is reserved and cannot be set\nfail_compilation/reserved_version.d(123): Error: version identifier `AIX` is reserved and cannot be set\nfail_compilation/reserved_version.d(124): Error: version identifier `Haiku` is reserved and cannot be set\nfail_compilation/reserved_version.d(125): Error: version identifier `SkyOS` is reserved and cannot be set\nfail_compilation/reserved_version.d(126): Error: version identifier `SysV3` is reserved and cannot be set\nfail_compilation/reserved_version.d(127): Error: version identifier `SysV4` is reserved and cannot be set\nfail_compilation/reserved_version.d(128): Error: version identifier `Hurd` is reserved and cannot be set\nfail_compilation/reserved_version.d(129): Error: version identifier `Android` is reserved and cannot be set\nfail_compilation/reserved_version.d(130): Error: version identifier `PlayStation` is reserved and cannot be set\nfail_compilation/reserved_version.d(131): Error: version identifier `PlayStation4` is reserved and cannot be set\nfail_compilation/reserved_version.d(132): Error: version identifier `Cygwin` is reserved and cannot be set\nfail_compilation/reserved_version.d(133): Error: version identifier `MinGW` is reserved and cannot be set\nfail_compilation/reserved_version.d(134): Error: version identifier `FreeStanding` is reserved and cannot be set\nfail_compilation/reserved_version.d(135): Error: version identifier `X86` is reserved and cannot be set\nfail_compilation/reserved_version.d(136): Error: version identifier `X86_64` is reserved and cannot be set\nfail_compilation/reserved_version.d(137): Error: version identifier `ARM` is reserved and cannot be set\nfail_compilation/reserved_version.d(138): Error: version identifier `ARM_Thumb` is reserved and cannot be set\nfail_compilation/reserved_version.d(139): Error: version identifier `ARM_SoftFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(140): Error: version identifier `ARM_SoftFP` is reserved and cannot be set\nfail_compilation/reserved_version.d(141): Error: version identifier `ARM_HardFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(142): Error: version identifier `AArch64` is reserved and cannot be set\nfail_compilation/reserved_version.d(143): Error: version identifier `Epiphany` is reserved and cannot be set\nfail_compilation/reserved_version.d(144): Error: version identifier `PPC` is reserved and cannot be set\nfail_compilation/reserved_version.d(145): Error: version identifier `PPC_SoftFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(146): Error: version identifier `PPC_HardFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(147): Error: version identifier `PPC64` is reserved and cannot be set\nfail_compilation/reserved_version.d(148): Error: version identifier `IA64` is reserved and cannot be set\nfail_compilation/reserved_version.d(149): Error: version identifier `MIPS32` is reserved and cannot be set\nfail_compilation/reserved_version.d(150): Error: version identifier `MIPS64` is reserved and cannot be set\nfail_compilation/reserved_version.d(151): Error: version identifier `MIPS_O32` is reserved and cannot be set\nfail_compilation/reserved_version.d(152): Error: version identifier `MIPS_N32` is reserved and cannot be set\nfail_compilation/reserved_version.d(153): Error: version identifier `MIPS_O64` is reserved and cannot be set\nfail_compilation/reserved_version.d(154): Error: version identifier `MIPS_N64` is reserved and cannot be set\nfail_compilation/reserved_version.d(155): Error: version identifier `MIPS_EABI` is reserved and cannot be set\nfail_compilation/reserved_version.d(156): Error: version identifier `MIPS_SoftFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(157): Error: version identifier `MIPS_HardFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(158): Error: version identifier `NVPTX` is reserved and cannot be set\nfail_compilation/reserved_version.d(159): Error: version identifier `NVPTX64` is reserved and cannot be set\nfail_compilation/reserved_version.d(160): Error: version identifier `RISCV32` is reserved and cannot be set\nfail_compilation/reserved_version.d(161): Error: version identifier `RISCV64` is reserved and cannot be set\nfail_compilation/reserved_version.d(162): Error: version identifier `SPARC` is reserved and cannot be set\nfail_compilation/reserved_version.d(163): Error: version identifier `SPARC_V8Plus` is reserved and cannot be set\nfail_compilation/reserved_version.d(164): Error: version identifier `SPARC_SoftFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(165): Error: version identifier `SPARC_HardFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(166): Error: version identifier `SPARC64` is reserved and cannot be set\nfail_compilation/reserved_version.d(167): Error: version identifier `S390` is reserved and cannot be set\nfail_compilation/reserved_version.d(168): Error: version identifier `S390X` is reserved and cannot be set\nfail_compilation/reserved_version.d(169): Error: version identifier `SystemZ` is reserved and cannot be set\nfail_compilation/reserved_version.d(170): Error: version identifier `HPPA` is reserved and cannot be set\nfail_compilation/reserved_version.d(171): Error: version identifier `HPPA64` is reserved and cannot be set\nfail_compilation/reserved_version.d(172): Error: version identifier `SH` is reserved and cannot be set\nfail_compilation/reserved_version.d(173): Error: version identifier `Alpha` is reserved and cannot be set\nfail_compilation/reserved_version.d(174): Error: version identifier `Alpha_SoftFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(175): Error: version identifier `Alpha_HardFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(176): Error: version identifier `LittleEndian` is reserved and cannot be set\nfail_compilation/reserved_version.d(177): Error: version identifier `BigEndian` is reserved and cannot be set\nfail_compilation/reserved_version.d(178): Error: version identifier `ELFv1` is reserved and cannot be set\nfail_compilation/reserved_version.d(179): Error: version identifier `ELFv2` is reserved and cannot be set\nfail_compilation/reserved_version.d(180): Error: version identifier `CRuntime_Bionic` is reserved and cannot be set\nfail_compilation/reserved_version.d(181): Error: version identifier `CRuntime_DigitalMars` is reserved and cannot be set\nfail_compilation/reserved_version.d(182): Error: version identifier `CRuntime_Glibc` is reserved and cannot be set\nfail_compilation/reserved_version.d(183): Error: version identifier `CRuntime_Microsoft` is reserved and cannot be set\nfail_compilation/reserved_version.d(184): Error: version identifier `CRuntime_Musl` is reserved and cannot be set\nfail_compilation/reserved_version.d(185): Error: version identifier `CRuntime_UClibc` is reserved and cannot be set\nfail_compilation/reserved_version.d(186): Error: version identifier `D_Coverage` is reserved and cannot be set\nfail_compilation/reserved_version.d(187): Error: version identifier `D_Ddoc` is reserved and cannot be set\nfail_compilation/reserved_version.d(188): Error: version identifier `D_InlineAsm_X86` is reserved and cannot be set\nfail_compilation/reserved_version.d(189): Error: version identifier `D_InlineAsm_X86_64` is reserved and cannot be set\nfail_compilation/reserved_version.d(190): Error: version identifier `D_LP64` is reserved and cannot be set\nfail_compilation/reserved_version.d(191): Error: version identifier `D_X32` is reserved and cannot be set\nfail_compilation/reserved_version.d(192): Error: version identifier `D_HardFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(193): Error: version identifier `D_SoftFloat` is reserved and cannot be set\nfail_compilation/reserved_version.d(194): Error: version identifier `D_PIC` is reserved and cannot be set\nfail_compilation/reserved_version.d(195): Error: version identifier `D_SIMD` is reserved and cannot be set\nfail_compilation/reserved_version.d(196): Error: version identifier `D_Version2` is reserved and cannot be set\nfail_compilation/reserved_version.d(197): Error: version identifier `D_NoBoundsChecks` is reserved and cannot be set\nfail_compilation/reserved_version.d(200): Error: version identifier `all` is reserved and cannot be set\nfail_compilation/reserved_version.d(201): Error: version identifier `none` is reserved and cannot be set\nfail_compilation/reserved_version.d(202): Error: version identifier `AsmJS` is reserved and cannot be set\nfail_compilation/reserved_version.d(203): Error: version identifier `Emscripten` is reserved and cannot be set\nfail_compilation/reserved_version.d(204): Error: version identifier `WebAssembly` is reserved and cannot be set\nfail_compilation/reserved_version.d(205): Error: version identifier `CppRuntime_Clang` is reserved and cannot be set\nfail_compilation/reserved_version.d(206): Error: version identifier `CppRuntime_DigitalMars` is reserved and cannot be set\nfail_compilation/reserved_version.d(207): Error: version identifier `CppRuntime_Gcc` is reserved and cannot be set\nfail_compilation/reserved_version.d(208): Error: version identifier `CppRuntime_Microsoft` is reserved and cannot be set\nfail_compilation/reserved_version.d(209): Error: version identifier `CppRuntime_Sun` is reserved and cannot be set\n---\n*/\n\n// Some extra empty lines to help fixup the manual line numbering after adding new version identifiers\n\n#line 105\nversion = MSP430;\nversion = D_P16;\nversion = DigitalMars;\nversion = GNU;\nversion = LDC;\nversion = SDC;\nversion = Windows;\nversion = Win32;\nversion = Win64;\nversion = linux;\nversion = OSX;\nversion = FreeBSD;\nversion = OpenBSD;\nversion = NetBSD;\nversion = DragonFlyBSD;\nversion = BSD;\nversion = Solaris;\nversion = Posix;\nversion = AIX;\nversion = Haiku;\nversion = SkyOS;\nversion = SysV3;\nversion = SysV4;\nversion = Hurd;\nversion = Android;\nversion = PlayStation;\nversion = PlayStation4;\nversion = Cygwin;\nversion = MinGW;\nversion = FreeStanding;\nversion = X86;\nversion = X86_64;\nversion = ARM;\nversion = ARM_Thumb;\nversion = ARM_SoftFloat;\nversion = ARM_SoftFP;\nversion = ARM_HardFloat;\nversion = AArch64;\nversion = Epiphany;\nversion = PPC;\nversion = PPC_SoftFloat;\nversion = PPC_HardFloat;\nversion = PPC64;\nversion = IA64;\nversion = MIPS32;\nversion = MIPS64;\nversion = MIPS_O32;\nversion = MIPS_N32;\nversion = MIPS_O64;\nversion = MIPS_N64;\nversion = MIPS_EABI;\nversion = MIPS_SoftFloat;\nversion = MIPS_HardFloat;\nversion = NVPTX;\nversion = NVPTX64;\nversion = RISCV32;\nversion = RISCV64;\nversion = SPARC;\nversion = SPARC_V8Plus;\nversion = SPARC_SoftFloat;\nversion = SPARC_HardFloat;\nversion = SPARC64;\nversion = S390;\nversion = S390X;\nversion = SystemZ;\nversion = HPPA;\nversion = HPPA64;\nversion = SH;\nversion = Alpha;\nversion = Alpha_SoftFloat;\nversion = Alpha_HardFloat;\nversion = LittleEndian;\nversion = BigEndian;\nversion = ELFv1;\nversion = ELFv2;\nversion = CRuntime_Bionic;\nversion = CRuntime_DigitalMars;\nversion = CRuntime_Glibc;\nversion = CRuntime_Microsoft;\nversion = CRuntime_Musl;\nversion = CRuntime_UClibc;\nversion = D_Coverage;\nversion = D_Ddoc;\nversion = D_InlineAsm_X86;\nversion = D_InlineAsm_X86_64;\nversion = D_LP64;\nversion = D_X32;\nversion = D_HardFloat;\nversion = D_SoftFloat;\nversion = D_PIC;\nversion = D_SIMD;\nversion = D_Version2;\nversion = D_NoBoundsChecks;\n//version = unittest;\n//version = assert;\nversion = all;\nversion = none;\nversion = AsmJS;\nversion = Emscripten;\nversion = WebAssembly;\nversion = CppRuntime_Clang;\nversion = CppRuntime_DigitalMars;\nversion = CppRuntime_Gcc;\nversion = CppRuntime_Microsoft;\nversion = CppRuntime_Sun;\n\n// This should work though\ndebug = DigitalMars;\ndebug = GNU;\ndebug = LDC;\ndebug = SDC;\ndebug = Windows;\ndebug = Win32;\ndebug = Win64;\ndebug = linux;\ndebug = OSX;\ndebug = FreeBSD;\ndebug = OpenBSD;\ndebug = NetBSD;\ndebug = DragonFlyBSD;\ndebug = BSD;\ndebug = Solaris;\ndebug = Posix;\ndebug = AIX;\ndebug = Haiku;\ndebug = SkyOS;\ndebug = SysV3;\ndebug = SysV4;\ndebug = Hurd;\ndebug = Android;\ndebug = Cygwin;\ndebug = MinGW;\ndebug = FreeStanding;\ndebug = X86;\ndebug = X86_64;\ndebug = ARM;\ndebug = ARM_Thumb;\ndebug = ARM_SoftFloat;\ndebug = ARM_SoftFP;\ndebug = ARM_HardFloat;\ndebug = AArch64;\ndebug = Epiphany;\ndebug = PPC;\ndebug = PPC_SoftFloat;\ndebug = PPC_HardFloat;\ndebug = PPC64;\ndebug = IA64;\ndebug = MIPS32;\ndebug = MIPS64;\ndebug = MIPS_O32;\ndebug = MIPS_N32;\ndebug = MIPS_O64;\ndebug = MIPS_N64;\ndebug = MIPS_EABI;\ndebug = MIPS_SoftFloat;\ndebug = MIPS_HardFloat;\ndebug = NVPTX;\ndebug = NVPTX64;\ndebug = RISCV32;\ndebug = RISCV64;\ndebug = SPARC;\ndebug = SPARC_V8Plus;\ndebug = SPARC_SoftFloat;\ndebug = SPARC_HardFloat;\ndebug = SPARC64;\ndebug = S390;\ndebug = S390X;\ndebug = SystemZ;\ndebug = HPPA;\ndebug = HPPA64;\ndebug = SH;\ndebug = Alpha;\ndebug = Alpha_SoftFloat;\ndebug = Alpha_HardFloat;\ndebug = LittleEndian;\ndebug = BigEndian;\ndebug = ELFv1;\ndebug = ELFv2;\ndebug = CRuntime_Bionic;\ndebug = CRuntime_DigitalMars;\ndebug = CRuntime_Glibc;\ndebug = CRuntime_Microsoft;\ndebug = CRuntime_Musl;\ndebug = CRuntime_UClibc;\ndebug = CppRuntime_Clang;\ndebug = CppRuntime_DigitalMars;\ndebug = CppRuntime_Gcc;\ndebug = CppRuntime_Microsoft;\ndebug = CppRuntime_Sun;\ndebug = D_Coverage;\ndebug = D_Ddoc;\ndebug = D_InlineAsm_X86;\ndebug = D_InlineAsm_X86_64;\ndebug = D_LP64;\ndebug = D_X32;\ndebug = D_HardFloat;\ndebug = D_SoftFloat;\ndebug = D_PIC;\ndebug = D_SIMD;\ndebug = D_Version2;\ndebug = D_NoBoundsChecks;\n//debug = unittest;\n//debug = assert;\ndebug = all;\ndebug = none;\ndebug = D_P16;\ndebug = MSP430;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d",
    "content": "// REQUIRED_ARGS: -verrors=0\n\n// REQUIRED_ARGS: -version=DigitalMars\n// REQUIRED_ARGS: -version=GNU\n// REQUIRED_ARGS: -version=LDC\n// REQUIRED_ARGS: -version=SDC\n// REQUIRED_ARGS: -version=Windows\n// REQUIRED_ARGS: -version=Win32\n// REQUIRED_ARGS: -version=Win64\n// REQUIRED_ARGS: -version=linux\n// REQUIRED_ARGS: -version=OSX\n// REQUIRED_ARGS: -version=FreeBSD\n// REQUIRED_ARGS: -version=OpenBSD\n// REQUIRED_ARGS: -version=NetBSD\n// REQUIRED_ARGS: -version=DragonFlyBSD\n// REQUIRED_ARGS: -version=BSD\n// REQUIRED_ARGS: -version=Solaris\n// REQUIRED_ARGS: -version=Posix\n// REQUIRED_ARGS: -version=AIX\n// REQUIRED_ARGS: -version=Haiku\n// REQUIRED_ARGS: -version=SkyOS\n// REQUIRED_ARGS: -version=SysV3\n// REQUIRED_ARGS: -version=SysV4\n// REQUIRED_ARGS: -version=Hurd\n// REQUIRED_ARGS: -version=Android\n// REQUIRED_ARGS: -version=Cygwin\n// REQUIRED_ARGS: -version=MinGW\n// REQUIRED_ARGS: -version=FreeStanding\n// REQUIRED_ARGS: -version=X86\n// REQUIRED_ARGS: -version=X86_64\n// REQUIRED_ARGS: -version=ARM\n// REQUIRED_ARGS: -version=ARM_Thumb\n// REQUIRED_ARGS: -version=ARM_SoftFloat\n// REQUIRED_ARGS: -version=ARM_SoftFP\n// REQUIRED_ARGS: -version=ARM_HardFloat\n// REQUIRED_ARGS: -version=AArch64\n// REQUIRED_ARGS: -version=Epiphany\n// REQUIRED_ARGS: -version=PPC\n// REQUIRED_ARGS: -version=PPC_SoftFloat\n// REQUIRED_ARGS: -version=PPC_HardFloat\n// REQUIRED_ARGS: -version=PPC64\n// REQUIRED_ARGS: -version=IA64\n// REQUIRED_ARGS: -version=MIPS32\n// REQUIRED_ARGS: -version=MIPS64\n// REQUIRED_ARGS: -version=MIPS_O32\n// REQUIRED_ARGS: -version=MIPS_N32\n// REQUIRED_ARGS: -version=MIPS_O64\n// REQUIRED_ARGS: -version=MIPS_N64\n// REQUIRED_ARGS: -version=MIPS_EABI\n// REQUIRED_ARGS: -version=MIPS_SoftFloat\n// REQUIRED_ARGS: -version=MIPS_HardFloat\n// REQUIRED_ARGS: -version=NVPTX\n// REQUIRED_ARGS: -version=NVPTX64\n// REQUIRED_ARGS: -version=RISCV32\n// REQUIRED_ARGS: -version=RISCV64\n// REQUIRED_ARGS: -version=SPARC\n// REQUIRED_ARGS: -version=SPARC_V8Plus\n// REQUIRED_ARGS: -version=SPARC_SoftFloat\n// REQUIRED_ARGS: -version=SPARC_HardFloat\n// REQUIRED_ARGS: -version=SPARC64\n// REQUIRED_ARGS: -version=S390\n// REQUIRED_ARGS: -version=S390X\n// REQUIRED_ARGS: -version=SystemZ\n// REQUIRED_ARGS: -version=HPPA\n// REQUIRED_ARGS: -version=HPPA64\n// REQUIRED_ARGS: -version=SH\n// REQUIRED_ARGS: -version=Alpha\n// REQUIRED_ARGS: -version=Alpha_SoftFloat\n// REQUIRED_ARGS: -version=Alpha_HardFloat\n// REQUIRED_ARGS: -version=LittleEndian\n// REQUIRED_ARGS: -version=BigEndian\n// REQUIRED_ARGS: -version=ELFv1\n// REQUIRED_ARGS: -version=ELFv2\n// REQUIRED_ARGS: -version=CRuntime_Bionic\n// REQUIRED_ARGS: -version=CRuntime_DigitalMars\n// REQUIRED_ARGS: -version=CRuntime_Glibc\n// REQUIRED_ARGS: -version=CRuntime_Microsoft\n// REQUIRED_ARGS: -version=CRuntime_Musl\n// REQUIRED_ARGS: -version=CRuntime_UClibc\n// REQUIRED_ARGS: -version=CppRuntime_Clang\n// REQUIRED_ARGS: -version=CppRuntime_DigitalMars\n// REQUIRED_ARGS: -version=CppRuntime_Gcc\n// REQUIRED_ARGS: -version=CppRuntime_Microsoft\n// REQUIRED_ARGS: -version=CppRuntime_Sun\n// REQUIRED_ARGS: -version=D_Coverage\n// REQUIRED_ARGS: -version=D_Ddoc\n// REQUIRED_ARGS: -version=D_InlineAsm_X86\n// REQUIRED_ARGS: -version=D_InlineAsm_X86_64\n// REQUIRED_ARGS: -version=D_LP64\n// REQUIRED_ARGS: -version=D_X32\n// REQUIRED_ARGS: -version=D_HardFloat\n// REQUIRED_ARGS: -version=D_SoftFloat\n// REQUIRED_ARGS: -version=D_PIC\n// REQUIRED_ARGS: -version=D_SIMD\n// REQUIRED_ARGS: -version=D_Version2\n// REQUIRED_ARGS: -version=D_NoBoundsChecks\n// REQUIRED_ARGS: -version=unittest\n// REQUIRED_ARGS: -version=assert\n// REQUIRED_ARGS: -version=all\n// REQUIRED_ARGS: -version=none\n// REQUIRED_ARGS: -debug=DigitalMars\n// REQUIRED_ARGS: -debug=GNU\n// REQUIRED_ARGS: -debug=LDC\n// REQUIRED_ARGS: -debug=SDC\n// REQUIRED_ARGS: -debug=Windows\n// REQUIRED_ARGS: -debug=Win32\n// REQUIRED_ARGS: -debug=Win64\n// REQUIRED_ARGS: -debug=linux\n// REQUIRED_ARGS: -debug=OSX\n// REQUIRED_ARGS: -debug=FreeBSD\n// REQUIRED_ARGS: -debug=OpenBSD\n// REQUIRED_ARGS: -debug=NetBSD\n// REQUIRED_ARGS: -debug=DragonFlyBSD\n// REQUIRED_ARGS: -debug=BSD\n// REQUIRED_ARGS: -debug=Solaris\n// REQUIRED_ARGS: -debug=Posix\n// REQUIRED_ARGS: -debug=AIX\n// REQUIRED_ARGS: -debug=Haiku\n// REQUIRED_ARGS: -debug=SkyOS\n// REQUIRED_ARGS: -debug=SysV3\n// REQUIRED_ARGS: -debug=SysV4\n// REQUIRED_ARGS: -debug=Hurd\n// REQUIRED_ARGS: -debug=Android\n// REQUIRED_ARGS: -debug=Cygwin\n// REQUIRED_ARGS: -debug=MinGW\n// REQUIRED_ARGS: -debug=FreeStanding\n// REQUIRED_ARGS: -debug=X86\n// REQUIRED_ARGS: -debug=X86_64\n// REQUIRED_ARGS: -debug=ARM\n// REQUIRED_ARGS: -debug=ARM_Thumb\n// REQUIRED_ARGS: -debug=ARM_SoftFloat\n// REQUIRED_ARGS: -debug=ARM_SoftFP\n// REQUIRED_ARGS: -debug=ARM_HardFloat\n// REQUIRED_ARGS: -debug=AArch64\n// REQUIRED_ARGS: -debug=Epiphany\n// REQUIRED_ARGS: -debug=PPC\n// REQUIRED_ARGS: -debug=PPC_SoftFloat\n// REQUIRED_ARGS: -debug=PPC_HardFloat\n// REQUIRED_ARGS: -debug=PPC64\n// REQUIRED_ARGS: -debug=IA64\n// REQUIRED_ARGS: -debug=MIPS32\n// REQUIRED_ARGS: -debug=MIPS64\n// REQUIRED_ARGS: -debug=MIPS_O32\n// REQUIRED_ARGS: -debug=MIPS_N32\n// REQUIRED_ARGS: -debug=MIPS_O64\n// REQUIRED_ARGS: -debug=MIPS_N64\n// REQUIRED_ARGS: -debug=MIPS_EABI\n// REQUIRED_ARGS: -debug=MIPS_SoftFloat\n// REQUIRED_ARGS: -debug=MIPS_HardFloat\n// REQUIRED_ARGS: -debug=NVPTX\n// REQUIRED_ARGS: -debug=NVPTX64\n// REQUIRED_ARGS: -debug=SPARC\n// REQUIRED_ARGS: -debug=SPARC_V8Plus\n// REQUIRED_ARGS: -debug=SPARC_SoftFloat\n// REQUIRED_ARGS: -debug=SPARC_HardFloat\n// REQUIRED_ARGS: -debug=SPARC64\n// REQUIRED_ARGS: -debug=S390\n// REQUIRED_ARGS: -debug=S390X\n// REQUIRED_ARGS: -debug=SystemZ\n// REQUIRED_ARGS: -debug=HPPA\n// REQUIRED_ARGS: -debug=HPPA64\n// REQUIRED_ARGS: -debug=SH\n// REQUIRED_ARGS: -debug=Alpha\n// REQUIRED_ARGS: -debug=Alpha_SoftFloat\n// REQUIRED_ARGS: -debug=Alpha_HardFloat\n// REQUIRED_ARGS: -debug=LittleEndian\n// REQUIRED_ARGS: -debug=BigEndian\n// REQUIRED_ARGS: -debug=ELFv1\n// REQUIRED_ARGS: -debug=ELFv2\n// REQUIRED_ARGS: -debug=CRuntime_Bionic\n// REQUIRED_ARGS: -debug=CRuntime_DigitalMars\n// REQUIRED_ARGS: -debug=CRuntime_Glibc\n// REQUIRED_ARGS: -debug=CRuntime_Microsoft\n// REQUIRED_ARGS: -debug=CRuntime_Musl\n// REQUIRED_ARGS: -debug=CRuntime_UClibc\n// REQUIRED_ARGS: -debug=CppRuntime_Clang\n// REQUIRED_ARGS: -debug=CppRuntime_DigitalMars\n// REQUIRED_ARGS: -debug=CppRuntime_Gcc\n// REQUIRED_ARGS: -debug=CppRuntime_Microsoft\n// REQUIRED_ARGS: -debug=CppRuntime_Sun\n// REQUIRED_ARGS: -debug=D_Coverage\n// REQUIRED_ARGS: -debug=D_Ddoc\n// REQUIRED_ARGS: -debug=D_InlineAsm_X86\n// REQUIRED_ARGS: -debug=D_InlineAsm_X86_64\n// REQUIRED_ARGS: -debug=D_LP64\n// REQUIRED_ARGS: -debug=D_X32\n// REQUIRED_ARGS: -debug=D_HardFloat\n// REQUIRED_ARGS: -debug=D_SoftFloat\n// REQUIRED_ARGS: -debug=D_PIC\n// REQUIRED_ARGS: -debug=D_SIMD\n// REQUIRED_ARGS: -debug=D_Version2\n// REQUIRED_ARGS: -debug=D_NoBoundsChecks\n// REQUIRED_ARGS: -debug=unittest\n// REQUIRED_ARGS: -debug=assert\n// REQUIRED_ARGS: -debug=all\n// REQUIRED_ARGS: -debug=none\n/*\nTEST_OUTPUT:\n---\nError: version identifier `DigitalMars` is reserved and cannot be set\nError: version identifier `GNU` is reserved and cannot be set\nError: version identifier `LDC` is reserved and cannot be set\nError: version identifier `SDC` is reserved and cannot be set\nError: version identifier `Windows` is reserved and cannot be set\nError: version identifier `Win32` is reserved and cannot be set\nError: version identifier `Win64` is reserved and cannot be set\nError: version identifier `linux` is reserved and cannot be set\nError: version identifier `OSX` is reserved and cannot be set\nError: version identifier `FreeBSD` is reserved and cannot be set\nError: version identifier `OpenBSD` is reserved and cannot be set\nError: version identifier `NetBSD` is reserved and cannot be set\nError: version identifier `DragonFlyBSD` is reserved and cannot be set\nError: version identifier `BSD` is reserved and cannot be set\nError: version identifier `Solaris` is reserved and cannot be set\nError: version identifier `Posix` is reserved and cannot be set\nError: version identifier `AIX` is reserved and cannot be set\nError: version identifier `Haiku` is reserved and cannot be set\nError: version identifier `SkyOS` is reserved and cannot be set\nError: version identifier `SysV3` is reserved and cannot be set\nError: version identifier `SysV4` is reserved and cannot be set\nError: version identifier `Hurd` is reserved and cannot be set\nError: version identifier `Android` is reserved and cannot be set\nError: version identifier `Cygwin` is reserved and cannot be set\nError: version identifier `MinGW` is reserved and cannot be set\nError: version identifier `FreeStanding` is reserved and cannot be set\nError: version identifier `X86` is reserved and cannot be set\nError: version identifier `X86_64` is reserved and cannot be set\nError: version identifier `ARM` is reserved and cannot be set\nError: version identifier `ARM_Thumb` is reserved and cannot be set\nError: version identifier `ARM_SoftFloat` is reserved and cannot be set\nError: version identifier `ARM_SoftFP` is reserved and cannot be set\nError: version identifier `ARM_HardFloat` is reserved and cannot be set\nError: version identifier `AArch64` is reserved and cannot be set\nError: version identifier `Epiphany` is reserved and cannot be set\nError: version identifier `PPC` is reserved and cannot be set\nError: version identifier `PPC_SoftFloat` is reserved and cannot be set\nError: version identifier `PPC_HardFloat` is reserved and cannot be set\nError: version identifier `PPC64` is reserved and cannot be set\nError: version identifier `IA64` is reserved and cannot be set\nError: version identifier `MIPS32` is reserved and cannot be set\nError: version identifier `MIPS64` is reserved and cannot be set\nError: version identifier `MIPS_O32` is reserved and cannot be set\nError: version identifier `MIPS_N32` is reserved and cannot be set\nError: version identifier `MIPS_O64` is reserved and cannot be set\nError: version identifier `MIPS_N64` is reserved and cannot be set\nError: version identifier `MIPS_EABI` is reserved and cannot be set\nError: version identifier `MIPS_SoftFloat` is reserved and cannot be set\nError: version identifier `MIPS_HardFloat` is reserved and cannot be set\nError: version identifier `NVPTX` is reserved and cannot be set\nError: version identifier `NVPTX64` is reserved and cannot be set\nError: version identifier `RISCV32` is reserved and cannot be set\nError: version identifier `RISCV64` is reserved and cannot be set\nError: version identifier `SPARC` is reserved and cannot be set\nError: version identifier `SPARC_V8Plus` is reserved and cannot be set\nError: version identifier `SPARC_SoftFloat` is reserved and cannot be set\nError: version identifier `SPARC_HardFloat` is reserved and cannot be set\nError: version identifier `SPARC64` is reserved and cannot be set\nError: version identifier `S390` is reserved and cannot be set\nError: version identifier `S390X` is reserved and cannot be set\nError: version identifier `SystemZ` is reserved and cannot be set\nError: version identifier `HPPA` is reserved and cannot be set\nError: version identifier `HPPA64` is reserved and cannot be set\nError: version identifier `SH` is reserved and cannot be set\nError: version identifier `Alpha` is reserved and cannot be set\nError: version identifier `Alpha_SoftFloat` is reserved and cannot be set\nError: version identifier `Alpha_HardFloat` is reserved and cannot be set\nError: version identifier `LittleEndian` is reserved and cannot be set\nError: version identifier `BigEndian` is reserved and cannot be set\nError: version identifier `ELFv1` is reserved and cannot be set\nError: version identifier `ELFv2` is reserved and cannot be set\nError: version identifier `CRuntime_Bionic` is reserved and cannot be set\nError: version identifier `CRuntime_DigitalMars` is reserved and cannot be set\nError: version identifier `CRuntime_Glibc` is reserved and cannot be set\nError: version identifier `CRuntime_Microsoft` is reserved and cannot be set\nError: version identifier `CRuntime_Musl` is reserved and cannot be set\nError: version identifier `CRuntime_UClibc` is reserved and cannot be set\nError: version identifier `CppRuntime_Clang` is reserved and cannot be set\nError: version identifier `CppRuntime_DigitalMars` is reserved and cannot be set\nError: version identifier `CppRuntime_Gcc` is reserved and cannot be set\nError: version identifier `CppRuntime_Microsoft` is reserved and cannot be set\nError: version identifier `CppRuntime_Sun` is reserved and cannot be set\nError: version identifier `D_Coverage` is reserved and cannot be set\nError: version identifier `D_Ddoc` is reserved and cannot be set\nError: version identifier `D_InlineAsm_X86` is reserved and cannot be set\nError: version identifier `D_InlineAsm_X86_64` is reserved and cannot be set\nError: version identifier `D_LP64` is reserved and cannot be set\nError: version identifier `D_X32` is reserved and cannot be set\nError: version identifier `D_HardFloat` is reserved and cannot be set\nError: version identifier `D_SoftFloat` is reserved and cannot be set\nError: version identifier `D_PIC` is reserved and cannot be set\nError: version identifier `D_SIMD` is reserved and cannot be set\nError: version identifier `D_Version2` is reserved and cannot be set\nError: version identifier `D_NoBoundsChecks` is reserved and cannot be set\nError: version identifier `unittest` is reserved and cannot be set\nError: version identifier `assert` is reserved and cannot be set\nError: version identifier `all` is reserved and cannot be set\nError: version identifier `none` is reserved and cannot be set\n---\n*/\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/retref2.d",
    "content": "\n// REQUIRED_ARGS: -dip25\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retref2.d(21): Error: function `ref int retref2.D.foo(return ref int)` does not override any function, did you mean to override `ref int retref2.C.foo(ref int)`?\nfail_compilation/retref2.d(22): Error: function `ref scope int retref2.D.bar() return` does not override any function, did you mean to override `ref int retref2.C.bar()`?\n---\n*/\n\n\nclass C\n{\n    ref int foo(ref int);\n    ref int bar();\n}\n\nclass D : C\n{\n    override ref int foo(return ref int);\n    override ref int bar() return;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/retscope.d",
    "content": "/*\nREQUIRED_ARGS: -dip1000\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(23): Error: scope variable `p` may not be returned\nfail_compilation/retscope.d(33): Error: returning `b ? nested1(& i) : nested2(& j)` escapes a reference to local variable `j`\nfail_compilation/retscope.d(46): Error: scope variable `p` assigned to non-scope `q`\nfail_compilation/retscope.d(48): Error: address of variable `i` assigned to `q` with longer lifetime\nfail_compilation/retscope.d(49): Error: scope variable `a` assigned to non-scope `b`\nfail_compilation/retscope.d(50): Error: reference to stack allocated value returned by `(*fp2)()` assigned to non-scope `q`\n---\n*/\n\n\n\n\nint* foo1(return scope int* p) { return p; } // ok\n\nint* foo2()(scope int* p) { return p; }  // ok, 'return' is inferred\nalias foo2a = foo2!();\n\nint* foo3(scope int* p) { return p; }   // error\n\nint* foo4(bool b)\n{\n    int i;\n    int j;\n\n    int* nested1(scope int* p) { return null; }\n    int* nested2(return scope int* p) { return p; }\n\n    return b ? nested1(&i) : nested2(&j);\n}\n\n/************************************************/\n\nstruct S2 { int a,b,c,d; }\n\n@safe S2 function() fp2;\n\nvoid test2(scope int* p, int[] a ...) @safe\n{\n    static int* q;\n    static int[] b;\n    q = p;\n    int i;\n    q = &i;\n    b = a;\n    q = &fp2().d;\n}\n\n/**************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(76): Error: function `retscope.HTTP.Impl.onReceive` is `@nogc` yet allocates closures with the GC\nfail_compilation/retscope.d(78):        retscope.HTTP.Impl.onReceive.__lambda1 closes over variable this at fail_compilation/retscope.d(76)\n---\n*/\n\n\nstruct Curl\n{\n    int delegate() dg;\n}\n\nstruct HTTP\n{\n    struct Impl\n    {\n        Curl curl;\n        int x;\n\n        @nogc void onReceive()\n        {\n            auto dg = ( ) { return x; };\n            curl.dg = dg;\n        }\n    }\n}\n\n/***********************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(97): Error: reference to local variable `sa` assigned to non-scope parameter `a` calling retscope.bar8\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=8838\n\nint[] foo8() @safe\n{\n    int[5] sa;\n    return bar8(sa);\n}\n\nint[] bar8(int[] a) @safe\n{\n    return a;\n}\n\n\n/*************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(124): Error: returning `foo9(cast(char[])tmp)` escapes a reference to local variable `tmp`\n---\n*/\n\nchar[] foo9(return char[] a) @safe pure nothrow @nogc\n{\n    return a;\n}\n\nchar[] bar9() @safe\n{\n    char[20] tmp;\n    foo9(tmp);          // ok\n    return foo9(tmp);   // error\n}\n\n/*************************************************/\n\n/*\n//\n//\n//fail_compilation/retscope.d(143): To enforce `@safe`, the compiler allocates a closure unless `opApply()` uses `scope`\n//\n*/\n\nstruct S10\n{\n    static int opApply(int delegate(S10*) dg);\n}\n\nS10* test10()\n{\n    foreach (S10* m; S10)\n        return m;\n    return null;\n}\n\n/************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(159): Error: scope variable `this` may not be returned\n---\n*/\n\nclass C11\n{\n    @safe C11 foo() scope { return this; }\n}\n\n\n/****************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(178): Error: address of variable `i` assigned to `p` with longer lifetime\n---\n*/\n\n\n\nvoid foo11() @safe\n{\n    int[] p;\n    int[3] i;\n    p = i[];\n}\n\n/************************************************/\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(198): Error: scope variable `e` may not be returned\n---\n*/\n\nstruct Escaper\n{\n    void* DG;\n}\n\nvoid* escapeDg1(scope void* d) @safe\n{\n    Escaper e;\n    e.DG = d;\n    return e.DG;\n}\n\n/*************************************************/\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(213): Error: scope variable `p` assigned to non-scope `e.e`\n---\n*/\nstruct Escaper3 { void* e; }\n\nvoid* escape3 (scope void* p) @safe {\n    Escaper3 e;\n    scope dg = () { return e.e; };\n    e.e = p;\n    return dg();\n}\n\n/**************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(230): Error: scope variable `ptr` may not be returned\n---\n*/\n\nalias dg_t = void* delegate () return scope @safe;\n\nvoid* funretscope(scope dg_t ptr) @safe\n{\n    return ptr();\n}\n\n/*****************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(249): Error: cannot implicitly convert expression `__lambda1` of type `void* delegate() pure nothrow @nogc return @safe` to `void* delegate() @safe`\nfail_compilation/retscope.d(249): Error: cannot implicitly convert expression `__lambda1` of type `void* delegate() pure nothrow @nogc return @safe` to `void* delegate() @safe`\nfail_compilation/retscope.d(250): Error: cannot implicitly convert expression `__lambda2` of type `void* delegate() pure nothrow @nogc return @safe` to `void* delegate() @safe`\nfail_compilation/retscope.d(250): Error: cannot implicitly convert expression `__lambda2` of type `void* delegate() pure nothrow @nogc return @safe` to `void* delegate() @safe`\n---\n*/\n\nvoid escape4() @safe\n{\n    alias FunDG = void* delegate () @safe;\n    int x = 42;\n    scope FunDG f = () return { return &x; };\n    scope FunDG g = ()        { return &x; };\n}\n\n/**************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(267): Error: cannot take address of `scope` local `p` in `@safe` function `escape5`\n---\n*/\n\nvoid escape5() @safe\n{\n    int* q;\n    scope int* p;\n    scope int** pp = &q; // ok\n    pp = &p; // error\n}\n\n/***********************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(287): Error: returning `foo6(& b)` escapes a reference to local variable `b`\n---\n*/\n\n@safe int* foo6()(int* arg)\n{\n    return arg;\n}\n\nint* escape6() @safe\n{\n    int b;\n    return foo6(&b);\n}\n\n/***************************************************/\n\nstruct S7\n{\n    int[10] a;\n    int[3] abc(int i) @safe\n    {\n        return a[0 .. 3]; // should not error\n    }\n}\n\n/***************************************************/\n\nint[3] escape8(scope int[] p) @safe { return p[0 .. 3]; } // should not error\nchar*[3] escape9(scope char*[] p) @safe { return p[0 .. 3]; }\n\n/***************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(320): Error: reference to local variable `i` assigned to non-scope `f`\n---\n*/\n\nint* escape10() @safe\n{\n    int i;\n    int* f;\n    scope int** x = &f;\n    f = &i;\n\n    return bar10(x);\n}\n\nint* bar10( scope int** ptr ) @safe\n{\n    return *ptr;\n}\n\n/******************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(343): Error: cannot take address of `scope` local `aa` in `@safe` function `escape11`\n---\n*/\n\nint* escape11() @safe\n{\n    int i;\n    int*[3] aa = [ &i, null, null ];\n    return bar11(&aa[0]);\n}\n\nint* bar11(scope int** x) @safe\n{\n    return foo11(*x);\n}\n\nint* foo11(int* x) @safe { return x; }\n\n/******************************************/\n\nvoid escape15() @safe\n{\n    int arg;\n    const(void)*[1] argsAddresses;\n    argsAddresses[0] = // MUST be an array assignment\n        (ref arg)@trusted{ return cast(const void*) &arg; }(arg);\n}\n\n/******************************************/\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(1003): Error: returning `f.foo()` escapes a reference to local variable `f`\n---\n*/\n\n#line 1000\nint* escape12() @safe\n{\n    Foo12 f;\n    return f.foo;\n}\n\nstruct Foo12\n{\n    int* foo() return @safe;\n}\n\n/******************************************/\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(1103): Error: scope variable `f` may not be returned\n---\n*/\n\n#line 1100\nint* escape13() @safe\n{\n    scope Foo13 f;\n    return f.foo;\n}\n\nclass Foo13\n{\n    int* foo() return @safe;\n}\n\n/******************************************/\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(1205): Error: scope variable `f14` assigned to non-scope parameter `this` calling retscope.Foo14.foo\n---\n*/\n\n#line 1200\nint* escape14() @safe\n{\n    int i;\n    Foo14 f14;\n    f14.v = &i;\n    return f14.foo;\n}\n\nstruct Foo14\n{\n    int* v;\n    int* foo () @safe { return this.v; }\n}\n\n/******************************************/\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(1311): Error: scope variable `u2` assigned to `ek` with longer lifetime\n---\n*/\n\n#line 1300\n@safe struct U13 {\n  int* k;\n  int* get() return scope { return k; }\n  static int* sget(return scope ref U13 u) { return u.k; }\n}\n\n@safe void foo13() {\n  int* ek;\n\n  int i;\n  auto u2 = U13(&i);\n  ek = U13.sget(u2); // Error: scope variable u2 assigned to ek with longer lifetime\n\n  auto u1 = U13(new int);\n  ek = u1.get();   // ok\n  ek = U13.sget(u1); // ok\n}\n\n/************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(1405): Error: reference to local variable `buf` assigned to non-scope parameter `unnamed` calling retscope.myprintf\n---\n*/\n\n#line 1400\n@trusted extern(C) int myprintf(const(char)*, ...);\n\n@safe void foo14()\n{\n    char[4] buf = [ 'h', 'i', '\\n', 0 ];\n    myprintf(&buf[0]);\n}\n\n/************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(1509): Error: reference to stack allocated value returned by `(*fp15)()` assigned to non-scope parameter `unnamed`\n---\n*/\n\n#line 1500\n\n@safe void bar15(int*);\n\nstruct S15 { int a,b,c,d; }\n\n@safe S15 function() fp15;\n\nvoid test15() @safe\n{\n    bar15(&fp15().d);\n}\n\n\n/*************************************************/\n\nvoid foo16() @nogc nothrow\n{\n    alias dg_t = string delegate(string) @nogc nothrow;\n\n    dg_t dg = (string s) => s;\n}\n\n/*************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(1701): Error: cannot implicitly convert expression `& func` of type `int* function(int* p)` to `int* function(scope int* p)`\nfail_compilation/retscope.d(1702): Error: cannot implicitly convert expression `& func` of type `int* function(int* p)` to `int* function(return scope int* p)`\nfail_compilation/retscope.d(1703): Error: cannot implicitly convert expression `& func` of type `int* function(int* p)` to `int* function(return scope int* p)`\nfail_compilation/retscope.d(1711): Error: cannot implicitly convert expression `& funcr` of type `int* function(return scope int* p)` to `int* function(scope int* p)`\nfail_compilation/retscope.d(1716): Error: cannot implicitly convert expression `& funcrs` of type `int* function(return scope int* p)` to `int* function(scope int* p)`\n---\n*/\n\nint* func(int* p);\nint* funcs(scope int* p);\nint* funcr(return int* p);\nint* funcrs(return scope int* p);\n\nvoid foo17()\n{\n#line 1700\n    typeof(func)   *fp1 = &func;\n    typeof(funcs)  *fp2 = &func; // error\n    typeof(funcr)  *fp3 = &func; // error\n    typeof(funcrs) *fp4 = &func; // error\n\n    typeof(func)   *fq1 = &funcs;\n    typeof(funcs)  *fq2 = &funcs;\n    typeof(funcr)  *fq3 = &funcs;\n    typeof(funcrs) *fq4 = &funcs;\n\n    typeof(func)   *fr1 = &funcr;\n    typeof(funcs)  *fr2 = &funcr; // error\n    typeof(funcr)  *fr3 = &funcr;\n    typeof(funcrs) *fr4 = &funcr;\n\n    typeof(func)   *fs1 = &funcrs;\n    typeof(funcs)  *fs2 = &funcrs; // error\n    typeof(funcr)  *fs3 = &funcrs;\n    typeof(funcrs) *fs4 = &funcrs;\n}\n\n/*************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope.d(1801): Error: cannot implicitly convert expression `&c.func` of type `int* delegate()` to `int* delegate() scope`\nfail_compilation/retscope.d(1802): Error: cannot implicitly convert expression `&c.func` of type `int* delegate()` to `int* delegate() return scope`\nfail_compilation/retscope.d(1803): Error: cannot implicitly convert expression `&c.func` of type `int* delegate()` to `int* delegate() return scope`\nfail_compilation/retscope.d(1811): Error: cannot implicitly convert expression `&c.funcr` of type `int* delegate() return scope` to `int* delegate() scope`\nfail_compilation/retscope.d(1816): Error: cannot implicitly convert expression `&c.funcrs` of type `int* delegate() return scope` to `int* delegate() scope`\n---\n*/\n\nclass C18\n{\n    int* func();\n    int* funcs() scope;\n    int* funcr() return;\n    int* funcrs() return scope;\n}\n\nvoid foo18()\n{\n    C18 c;\n\n#line 1800\n    typeof(&c.func)   fp1 = &c.func;\n    typeof(&c.funcs)  fp2 = &c.func; // error\n    typeof(&c.funcr)  fp3 = &c.func; // error\n    typeof(&c.funcrs) fp4 = &c.func; // error\n\n    typeof(&c.func)   fq1 = &c.funcs;\n    typeof(&c.funcs)  fq2 = &c.funcs;\n    typeof(&c.funcr)  fq3 = &c.funcs;\n    typeof(&c.funcrs) fq4 = &c.funcs;\n\n    typeof(&c.func)   fr1 = &c.funcr;\n    typeof(&c.funcs)  fr2 = &c.funcr; // error\n    typeof(&c.funcr)  fr3 = &c.funcr;\n    typeof(&c.funcrs) fr4 = &c.funcr;\n\n    typeof(&c.func)   fs1 = &c.funcrs;\n    typeof(&c.funcs)  fs2 = &c.funcrs; // error\n    typeof(&c.funcr)  fs3 = &c.funcrs;\n    typeof(&c.funcrs) fs4 = &c.funcrs;\n}\n\n/*********************************************/\n\n@safe void foo19(C)(ref C[] str)  // infer 'scope' for 'str'\n{\n    str = str;\n    str = str[1 .. str.length];\n}\n\n@safe void test19()\n{\n    char[10] s;\n    char[] t = s[];\n    foo19(t);\n}\n\n/********************************************/\n\n\nbool foo20(const string a) @safe pure nothrow @nogc\n{\n    return !a.length;\n}\n\nstruct Result(R)\n{\n    R source;\n\n    bool empty() // infer 'scope' for 'this'\n    { return foo20(source); }\n}\n\n@safe void test20()\n{\n    scope n = Result!string(\"abc\");\n    n.empty();\n}\n\n/************************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=17117\n\nref int foo21(return ref int s)\n{\n        return s;\n}\n\nint fail21()\n{\n        int s;\n        return foo21(s); // Error: escaping reference to local variable s\n}\n\nint test21()\n{\n        int s;\n        s = foo21(s);\n        return s;\n}\n\n/**********************************************/\n\n@safe void foo22()(ref char[] s)\n{\n    char[] a = s;\n}\n\n@safe void test22(scope char[] s)\n{\n    foo22(s);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/retscope2.d",
    "content": "/*\nREQUIRED_ARGS: -dip1000\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(102): Error: scope variable `s` assigned to `p` with longer lifetime\nfail_compilation/retscope2.d(107): Error: address of variable `s` assigned to `p` with longer lifetime\n---\n*/\n\n#line 100\n@safe foo1(ref char[] p, scope char[] s)\n{\n    p = s;\n}\n\n@safe bar1(ref char* p, char s)\n{\n    p = &s;\n}\n\n/**********************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=17123\n\nvoid test200()\n{\n    char[256] buffer;\n\n    char[] delegate() read = () {\n        return buffer[];\n    };\n}\n\n/**********************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(302): Error: scope variable `a` assigned to return scope `b`\n---\n*/\n\n#line 300\n@safe int* test300(scope int* a, return scope int* b)\n{\n    b = a;\n    return b;\n}\n\n/**********************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(403): Error: scope variable `a` assigned to return scope `c`\n---\n*/\n\n#line 400\n@safe int* test400(scope int* a, return scope int* b)\n{\n    auto c = b; // infers 'return scope' for 'c'\n    c = a;\n    return c;\n}\n\n/**********************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(504): Error: scope variable `c` may not be returned\n---\n*/\n\n#line 500\n@safe int* test500(scope int* a, return scope int* b)\n{\n    scope c = b; // does not infer 'return' for 'c'\n    c = a;\n    return c;\n}\n\n/**********************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(604): Error: scope variable `_param_0` assigned to non-scope parameter `unnamed` calling retscope2.foo600\nfail_compilation/retscope2.d(604): Error: scope variable `_param_1` assigned to non-scope parameter `unnamed` calling retscope2.foo600\nfail_compilation/retscope2.d(614): Error: template instance `retscope2.test600!(int*, int*)` error instantiating\n---\n*/\n\n#line 600\n@safe test600(A...)(scope A args)\n{\n    foreach (i, Arg; A)\n    {\n        foo600(args[i]);\n    }\n}\n\n@safe void foo600(int*);\n\n@safe bar600()\n{\n    scope int* p;\n    scope int* q;\n    test600(p, q);\n}\n\n/*************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(719): Error: returning `get2(s)` escapes a reference to local variable `s`\nfail_compilation/retscope2.d(721): Error: returning `s.get1()` escapes a reference to local variable `s`\n---\n*/\n\n#line 700\n// https://issues.dlang.org/show_bug.cgi?id=17049\n\n@safe S700* get2(return ref scope S700 _this)\n{\n    return &_this;\n}\n\nstruct S700\n{\n    @safe S700* get1() return scope\n    {\n        return &this;\n    }\n}\n\nS700* escape700(int i) @safe\n{\n    S700 s;\n    if (i)\n        return s.get2(); // 719\n    else\n        return s.get1(); // 721\n}\n\n/*************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(804): Error: scope variable `e` may not be thrown\n---\n*/\n\n#line 800\n\nvoid foo800()\n{\n    scope Exception e;\n    throw e;\n}\n\n/*************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(907): Error: address of variable `this` assigned to `p17568` with longer lifetime\n---\n*/\n\n#line 900\n\nint* p17568;\nstruct T17568\n{\n    int a;\n    void escape() @safe scope\n    {\n        p17568 = &a;\n    }\n}\n\n/*************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(1005): Error: scope variable `p` assigned to non-scope `this._p`\nfail_compilation/retscope2.d(1021): Error: scope variable `p` assigned to non-scope `c._p`\nfail_compilation/retscope2.d(1024): Error: scope variable `p` assigned to non-scope `d._p`\n---\n*/\n\n#line 1000\n\nclass C17428\n{\n    void set(scope int* p) @safe\n    {\n        _p = p;\n    }\n\n    int* _p;\n}\n\nclass C17428b\n{\n    int* _p;\n}\n\nvoid test17428() @safe\n{\n        int x;\n        int* p = &x;\n        scope C17428b c;\n        c._p = p;   // bad\n\n        C17428b d;\n        d._p = p;   // bad\n}\n\n\n\n/*************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(1107): Error: scope variable `dg` may not be returned\n---\n*/\n\n#line 1100\n\nstruct S17430 { void foo() {} }\n\nvoid delegate() test17430() @safe\n{\n    S17430 s;\n    auto dg = &s.foo; // infer dg as scope\n    return dg;\n}\n\n/****************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(1216): Error: returning `s.foo()` escapes a reference to local variable `s`\nfail_compilation/retscope2.d(1233): Error: returning `t.foo()` escapes a reference to local variable `t`\n---\n*/\n\n#line 1200\n// https://issues.dlang.org/show_bug.cgi?id=17388\n\nstruct S17388\n{\n    //int*\n    auto\n        foo() return @safe\n    {\n        return &x;\n    }\n    int x;\n}\n\n@safe int* f17388()\n{\n    S17388 s;\n    return s.foo();\n}\n\nstruct T17388\n{\n    //int[]\n    auto\n        foo() return @safe\n    {\n        return x[];\n    }\n    int[4] x;\n}\n\n@safe int[] g17388()\n{\n    T17388 t;\n    return t.foo();\n}\n\n/****************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope2.d(1306): Error: copying `& i` into allocated memory escapes a reference to local variable `i`\n---\n*/\n\n#line 1300\n\n// https://issues.dlang.org/show_bug.cgi?id=17370\n\nvoid test1300() @safe\n{\n    int i;\n    auto p = new S1300(&i).oops;\n}\n\nstruct S1300\n{\n    int* oops;\n//    this(int* p) @safe { oops = p; }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/retscope3.d",
    "content": "/*\nREQUIRED_ARGS: -dip1000\nPERMUTE_ARGS:\n*/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope3.d(2008): Error: copying `& i` into allocated memory escapes a reference to local variable `i`\nfail_compilation/retscope3.d(2017): Error: copying `S2000(& i)` into allocated memory escapes a reference to local variable `i`\n---\n*/\n\n#line 2000\n\n// https://issues.dlang.org/show_bug.cgi?id=17790\n\n@safe:\n\nint* bar1()\n{\n    int i;\n    int*[] arr = [ &i ];\n    return arr[0];\n}\n\nstruct S2000 { int* p; }\n\nS2000 bar2()\n{\n    int i;\n    S2000[] arr = [ S2000(&i) ];\n    return arr[0];\n}\n\nvoid bar3(string[] u...) @safe pure nothrow @nogc\n{\n    foreach (str; u)\n    {\n    }\n}\n\nvoid bar4()\n{\n    static struct S { int* p; }\n    S[2][10] pairs;\n    foreach (ref pair; pairs)\n    {\n    }\n}\n\n/**********************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope3.d(3027): Error: scope variable `l` assigned to `elem` with longer lifetime\n---\n*/\n\n#line 3000\n\nstruct List\n{\n    Elem front() @safe return scope;\n\n    ~this() @trusted scope;\n\n    @disable this(this);\n\n    void* data;\n}\n\nstruct Elem\n{\n    void* data;\n}\n\nList list() @trusted\n{\n    return List();\n}\n\nvoid test3000() @safe\n{\n    Elem elem;\n    {\n        auto l = list(); // inferred as scope\n        elem = l.front; // escapes, b/c l isn't scoped\n    }\n}\n\n/**********************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope3.d(4003): Error: copying `u[]` into allocated memory escapes a reference to variadic parameter `u`\nfail_compilation/retscope3.d(4016): Error: storing reference to outer local variable `i` into allocated memory causes it to escape\nfail_compilation/retscope3.d(4025): Error: storing reference to stack allocated value returned by `makeSA()` into allocated memory causes it to escape\n---\n*/\n\n#line 4000\n\nvoid bar4000(int[1] u...) @safe\n{\n    int[][] n = [u[]];\n}\n\nvoid bar4001() @safe\n{\n    static int i;\n    int*[] n = [&i];\n}\n\nref int bar4002(return ref int i) @safe\n{\n    void nested()\n    {\n        int*[] n = [&i];\n    }\n    return i;\n}\n\nint[3] makeSA() @safe;\n\nvoid bar4003() @safe\n{\n    int[][] a = [makeSA()[]];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/retscope4.d",
    "content": "/*\nREQUIRED_ARGS: -de\nPERMUTE_ARGS:\n*/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope4.d(3007): Deprecation: slice of static array temporary returned by `func()` assigned to longer lived variable `a`\n---\n*/\n\n#line 3000\n\n// https://issues.dlang.org/show_bug.cgi?id=12625\n\nint[16] func();\n\nvoid foo()\n{\n    int[] a = func();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/retscope5.d",
    "content": "/*\nREQUIRED_ARGS: -dip1000\nPERMUTE_ARGS:\n*/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope5.d(5010): Error: reference `t` assigned to `p` with longer lifetime\n---\n*/\n\n#line 5000\n\n// https://issues.dlang.org/show_bug.cgi?id=17725\n\nvoid test() @safe\n{\n    int* p;\n    struct T {\n            int a;\n    }\n    void escape(ref T t) @safe {\n            p = &t.a; // should not compile\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/retscope6.d",
    "content": "/*\nREQUIRED_ARGS: -dip1000\nPERMUTE_ARGS:\n*/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/retscope6.d(6007): Error: copying `& i` into allocated memory escapes a reference to local variable `i`\n---\n*/\n\n#line 6000\n\n// https://issues.dlang.org/show_bug.cgi?id=17795\n\nint* test() @safe\n{\n    int i;\n    int*[][] arr = new int*[][](1);\n    arr[0] ~= &i;\n    return arr[0][0];\n}\n\n/* TEST_OUTPUT:\n---\nfail_compilation/retscope6.d(7034): Error: reference to local variable `i` assigned to non-scope parameter `_param_1` calling retscope6.S.emplace!(int*).emplace\nfail_compilation/retscope6.d(7035): Error: reference to local variable `i` assigned to non-scope parameter `_param_0` calling retscope6.S.emplace2!(int*).emplace2\nfail_compilation/retscope6.d(7024): Error: scope variable `_param_2` assigned to `s` with longer lifetime\nfail_compilation/retscope6.d(7025): Error: scope variable `_param_2` assigned to `t` with longer lifetime\nfail_compilation/retscope6.d(7037): Error: template instance `retscope6.S.emplace4!(int*)` error instantiating\n---\n*/\n\n#line 7000\n\nalias T = int*;\n\nstruct S\n{\n    T payload;\n\n    static void emplace(Args...)(ref S s, Args args) @safe\n    {\n        s.payload = args[0];\n    }\n\n    void emplace2(Args...)(Args args) @safe\n    {\n        payload = args[0];\n    }\n\n    static void emplace3(Args...)(S s, Args args) @safe\n    {\n        s.payload = args[0];\n    }\n\n    static void emplace4(Args...)(scope ref S s, scope out S t, scope Args args) @safe\n    {\n        s.payload = args[0];\n        t.payload = args[0];\n    }\n\n}\n\nvoid foo() @safe\n{\n    S s;\n    int i;\n    s.emplace(s, &i);\n    s.emplace2(&i);\n    s.emplace3(s, &i);\n    s.emplace4(s, s, &i);\n}\n\n\n/* TEST_OUTPUT:\n---\nfail_compilation/retscope6.d(8016): Error: reference to local variable `i` assigned to non-scope parameter `s` calling retscope6.frank!().frank\nfail_compilation/retscope6.d(8031): Error: reference to local variable `i` assigned to non-scope parameter `p` calling retscope6.betty!().betty\nfail_compilation/retscope6.d(8031): Error: reference to local variable `j` assigned to non-scope parameter `q` calling retscope6.betty!().betty\nfail_compilation/retscope6.d(8048): Error: reference to local variable `j` assigned to non-scope parameter `q` calling retscope6.archie!().archie\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=19035\n\n#line 8000\n@safe\n{\n\nvoid escape(int*);\n\n/**********************/\n\nvoid frank()(ref scope int* p, int* s)\n{\n    p = s;  // should error here\n}\n\nvoid testfrankly()\n{\n    int* p;\n    int i;\n    frank(p, &i);\n}\n\n/**********************/\n\nvoid betty()(int* p, int* q)\n{\n     p = q;\n     escape(p);\n}\n\nvoid testbetty()\n{\n    int i;\n    int j;\n    betty(&i, &j); // should error on i and j\n}\n\n/**********************/\n\nvoid archie()(int* p, int* q, int* r)\n{\n     p = q;\n     r = p;\n     escape(q);\n}\n\nvoid testarchie()\n{\n    int i;\n    int j;\n    int k;\n    archie(&i, &j, &k); // should error on j\n}\n\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/scope_class.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/scope_class.d(10): Error: functions cannot return `scope scope_class.C`\n---\n*/\n\nscope class C { int i; }    // Notice the use of `scope` here\n\nC increment(C c)\n{\n    c.i++;\n    return c;\n}\n\nvoid main()\n{\n    scope C c = new C();\n    c.increment();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/skip.d",
    "content": "/*\n * REQUIRED_ARGS: -de\n * TEST_OUTPUT:\n---\nfail_compilation/skip.d(21): Error: `switch` skips declaration of `with` temporary at fail_compilation/skip.d(26)\nfail_compilation/skip.d(43): Error: `switch` skips declaration of variable `skip.test14532.n` at fail_compilation/skip.d(45)\n---\n */\n// https://issues.dlang.org/show_bug.cgi?id=10524\n\nstruct S\n{\n    int field;\n}\n\nvoid test10524()\n{\n    int a = 1;\n    S struct_with_long_name;\n\n    switch( a )\n    {\n        case 0:\n            struct_with_long_name.field = 444; // ok\n            break;\n        with( struct_with_long_name )\n        {\n            case 1:\n                field = 555; // segfault\n                break;\n        }\n\n        default:\n            break;\n    }\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=14532\n\nvoid test14532()\n{\n    char ch = '!';\n    switch (ch)\n    {\n            int n = 42;\n        case '!':\n            assert(n == 42);\n            break;\n\n      default:\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/spell9644.d",
    "content": "// REQUIRED_ARGS: -o-\n// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/spell9644.d(27): Error: undefined identifier `b`\nfail_compilation/spell9644.d(28): Error: undefined identifier `xx`\nfail_compilation/spell9644.d(29): Error: undefined identifier `cb`, did you mean variable `ab`?\nfail_compilation/spell9644.d(30): Error: undefined identifier `bc`, did you mean variable `abc`?\nfail_compilation/spell9644.d(31): Error: undefined identifier `ccc`\nfail_compilation/spell9644.d(33): Error: undefined identifier `cor2`, did you mean variable `cor1`?\nfail_compilation/spell9644.d(34): Error: undefined identifier `pua`, did you mean variable `pub`?\nfail_compilation/spell9644.d(35): Error: undefined identifier `priw`\n---\n*/\n\nimport imports.spell9644a;\n\nint a;\nint ab;\nint abc;\nint cor1;\n\nint main()\n{\n    cast(void)b; // max distance 0, no match\n    cast(void)xx; // max distance 1, no match\n    cast(void)cb; // max distance 1, match\n    cast(void)bc; // max distance 1, match\n    cast(void)ccc; // max distance 2, match\n\n    cast(void)cor2; // max distance 1, match \"cor1\", but not cora from import (bug 13736)\n    cast(void)pua;  // max distance 1, match \"pub\" from import\n    cast(void)priw; // max distance 1, match \"priv\" from import, but do not report (bug 5839)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/staticarrayoverflow.d",
    "content": "/*\nREQUIRED_ARGS: -m64\nPERMUTE_ARGS:\n---\nfail_compilation/staticarrayoverflow.d(21): Error: static array S[1879048192] size overflowed to 7516192768000\nfail_compilation/staticarrayoverflow.d(21): Error: variable staticarrayoverflow.y size overflow\nfail_compilation/staticarrayoverflow.d(22): Error: variable staticarrayoverflow.z size of x1000ae0 exceeds max allowed size 0x100_0000\nfail_compilation/staticarrayoverflow.d(23): Error: static array S[8070450532247928832] size overflowed to 0\nfail_compilation/staticarrayoverflow.d(23): Error: variable staticarrayoverflow.a size overflow\n---\n*/\n\n\n\nstruct S\n{\n    int[1000] x;\n}\n\nS[0x7000_0000] y;\nS[0x100_0000/(4*1000 - 1)] z;\nS[0x7000_0000_0000_0000] a;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/staticforeach1.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/staticforeach1.d(10): Error: must use labeled `break` within `static foreach`\n---\n*/\nvoid main(){\n\tfor(;;){\n\t\tstatic foreach(i;0..1){\n\t\t\tbreak;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/staticforeach2.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/staticforeach2.d(10): Error: must use labeled `continue` within `static foreach`\n---\n*/\nvoid main(){\n\tfor(;;){\n\t\tstatic foreach(i;0..1){\n\t\t\tcontinue;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/staticforeach3.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/staticforeach3.d(7): Error: variable `staticforeach3.__anonymous.i` conflicts with variable `staticforeach3.__anonymous.i` at fail_compilation/staticforeach3.d(7)\n---\n*/\nstatic foreach(i,i;[0]){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/switches.d",
    "content": "/*\nREQUIRED_ARGS:\nPERMUTE_ARGS:\n*/\n\n/************************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/switches.d(105): Error: `case 2` not found\n---\n*/\n\n#line 100\nvoid test1(int i)\n{\n    switch (i)\n    {\n        case 1:\n            goto case 2;\n        defaut:\n            break;\n    }\n}\n\n/************************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/switches.d(205): Error: no `case` statement following `goto case;`\n---\n*/\n\n#line 200\nvoid test2(int i)\n{\n    switch (i)\n    {\n        case 1:\n            goto case;\n        defaut:\n            break;\n    }\n}\n\n/************************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/switches.d(302): Error: `switch` skips declaration of variable `switches.test3.j` at fail_compilation/switches.d(306)\n---\n*/\n\n#line 300\nvoid test3(int i)\n{\n    switch (i)\n    {\n        case 1:\n        {\n            int j;\n        case 2:\n            ++j;\n            break;\n        }\n        default:\n            break;\n    }\n}\n\n\n/************************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/switches.d(404): Error: `switch` skips declaration of variable `switches.test.z` at fail_compilation/switches.d(406)\n---\n*/\n\n#line 400\n// https://issues.dlang.org/show_bug.cgi?id=18858\n\nint test(int n)\n{\n    final switch(n)\n    {\n        int z = 5;\n        enum e = 6;\n\n        case 1:\n            int y = 2;\n            return y;\n    }\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test1.d",
    "content": "fail\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test10.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test10.d(10): Error: found `else` without a corresponding `if`, `version` or `debug` statement\n---\n*/\n\nvoid test(int i)\n{\n    ++i;\n    else\n        ++i;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test11006.d",
    "content": "/* REQUIRED_ARGS: -main -de\n * TEST_OUTPUT:\n---\nfail_compilation/test11006.d(10): Deprecation: cannot subtract pointers to different types: `void*` and `int*`.\nfail_compilation/test11006.d(10):        while evaluating: `static assert(2L == 2L)`\nfail_compilation/test11006.d(11): Deprecation: cannot subtract pointers to different types: `int*` and `void*`.\nfail_compilation/test11006.d(11):        while evaluating: `static assert(8L == 8L)`\n---\n */\nstatic assert(cast(void*)8 - cast(int*) 0 == 2L);\nstatic assert(cast(int*) 8 - cast(void*)0 == 8L);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test11047.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test11047.d(11): Error: value of `x` is not known at compile time\nfail_compilation/test11047.d(11): Error: value of `x` is not known at compile time\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=11047\n\nint x;\n@(++x, ++x) void foo(){}\n\n@safe pure void test()\n{\n    __traits(getAttributes, foo);\n    __traits(getAttributes, foo)[0];\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test11176.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test11176.d(12): Error: `b.ptr` cannot be used in `@safe` code, use `&b[0]` instead\nfail_compilation/test11176.d(16): Error: `b.ptr` cannot be used in `@safe` code, use `&b[0]` instead\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=11176\n\n@safe ubyte oops(ubyte[] b) {\n    return *b.ptr;\n}\n\n@safe ubyte oops(ubyte[3] b) {\n    return *b.ptr;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test12228.d",
    "content": "/*\nREQUIRED_ARGS: -de\nTEST_OUTPUT:\n---\nfail_compilation/test12228.d(14): Deprecation: Using `this` as a type is deprecated. Use `typeof(this)` instead\nfail_compilation/test12228.d(19): Error: no property `x` for type `object.Object`\nfail_compilation/test12228.d(20): Deprecation: Using `super` as a type is deprecated. Use `typeof(super)` instead\nfail_compilation/test12228.d(21): Deprecation: Using `super` as a type is deprecated. Use `typeof(super)` instead\n---\n*/\n\nclass C\n{\n    shared(this) x;\n}\n\nclass D : C\n{\n    alias x = typeof(super).x;\n    shared(super) a;\n    super b;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test12385.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test12385.d(29): Error: cannot modify `immutable` expression `BundledState(\"bla\", 3).x`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=12385\n\nclass BundledState\n{\n    string m_State;\n\n    int x = 3;\n\n    this(string state) immutable\n    {\n        m_State = state;\n    }\n}\n\nenum States : immutable(BundledState)\n{\n    unbundled = new immutable BundledState(\"bla\"),\n}\n\nvoid main()\n{\n    States.unbundled.x = 6; // Modifies x.\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test12558.d",
    "content": "// REQUIRED_ARGS:\n/*\nTEST_OUTPUT:\n---\nfail_compilation/test12558.d(18): Error: `catch` statement without an exception specification is deprecated\nfail_compilation/test12558.d(18):        use `catch(Throwable)` for old behavior\nfail_compilation/test12558.d(23): Error: `catch` statement without an exception specification is deprecated\nfail_compilation/test12558.d(23):        use `catch(Throwable)` for old behavior\n---\n*/\n\nvoid main()\n{\n    auto handler = () { };\n\n    try {\n        assert(0);\n    } catch\n        handler();\n\n    try {\n        assert(0);\n    } catch {\n        handler();\n    }\n\n    // ensure diagnostics are not emitted for verioned-out blocks\n    version (none)\n    {\n        try {\n            assert(0);\n        } catch  // should not emit diagnostics\n            handler();\n\n        try {\n            assert(0);\n        } catch {  // ditto\n            handler();\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test12822.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test12822.d(13): Error: cannot modify delegate pointer in `@safe` code `dg.ptr`\nfail_compilation/test12822.d(14): Error: `dg.funcptr` cannot be used in `@safe` code\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=12822\nvoid test2(int delegate() dg) @safe\n{\n    static int i;\n    dg.ptr = &i;\n    dg.funcptr = &func;\n}\n\nint func();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test12979.d",
    "content": "// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/test12979.d(13): Error: `const`/`immutable`/`shared`/`inout` attributes are not allowed on `asm` blocks\n---\n*/\n\nvoid foo()\n{\n    version(GNU)\n    {\n        asm const shared\n        {\n            \"\";\n        }\n    }\n    else\n    {\n        asm const shared\n        {\n            ret;\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test13152.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test13152.d(11): Error: undefined identifier `x`\n---\n*/\nimport imports.test13152a;\n\nvoid main()\n{\n    auto y = x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test13536.d",
    "content": "/*\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/test13536.d(24): Error: field `U.sysDg` cannot access pointers in `@safe` code that overlap other fields\nfail_compilation/test13536.d(24): Error: address of variable `s` assigned to `u` with longer lifetime\nfail_compilation/test13536.d(25): Error: field `U.safeDg` cannot access pointers in `@safe` code that overlap other fields\n---\n*/\n\n\n// https://issues.dlang.org/show_bug.cgi?id=13536\n\nstruct S {\n    void sysMethod() @system {}\n}\nvoid fun() @safe {\n    union U {\n        void delegate() @system sysDg;\n        void delegate() @safe safeDg;\n    }\n    U u;\n    S s;\n    u.sysDg = &s.sysMethod;\n    u.safeDg();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test13537.d",
    "content": "/*\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/test13537.d(32): Error: field `U.y` cannot modify fields in `@safe` code that overlap fields with other storage classes\nfail_compilation/test13537.d(33): Error: field `U.y` cannot modify fields in `@safe` code that overlap fields with other storage classes\nfail_compilation/test13537.d(34): Error: field `U.z` cannot access pointers in `@safe` code that overlap other fields\nfail_compilation/test13537.d(35): Error: field `U.y` cannot modify fields in `@safe` code that overlap fields with other storage classes\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=13537\n\nunion U\n{\n    immutable int x;\n    int y;\n    int* z;\n}\n\nunion V\n{\n    immutable int x;\n    const int y;\n}\n\nvoid fun() @safe\n{\n    U u;\n\n    // errors\n    u.y = 1;\n    int* p = &u.y;\n    int** q = &u.z;\n    abc(u.y);\n\n    // read access is allowed\n    int a = u.x;\n    a = u.y;\n    def(u.y);\n\n    // Overlapping const/immutable is allowed\n    auto v = V(1);\n    assert(v.y == 1);\n}\n\nvoid gun() @system\n{\n    U u;\n\n    // allowed because system code\n    u.y = 1;\n    int* p = &u.y;\n    int** q = &u.z;\n    abc(u.y);\n}\n\n@safe:\nvoid abc(ref int x) { }\nvoid def(const ref int x) { }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test13786.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test13786.d(14): Error: debug `123` level declaration must be at module level\nfail_compilation/test13786.d(15): Error: debug `abc` declaration must be at module level\nfail_compilation/test13786.d(16): Error: version `123` level declaration must be at module level\nfail_compilation/test13786.d(17): Error: version `abc` declaration must be at module level\nfail_compilation/test13786.d(20): Error: template instance `test13786.T!()` error instantiating\n---\n*/\n\ntemplate T()\n{\n    debug = 123;\n    debug = abc;\n    version = 123;\n    version = abc;\n}\n\nalias X = T!();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test13867.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test13867.d(12): Error: function `void test13867.X.blah()` does not override any function, did you mean to override `extern (C++) void test13867.Base.blah()`?\nfail_compilation/test13867.d(19): Error: function `void test13867.Z.blah()` does not override any function, did you mean to override `extern (C++) void test13867.Base.blah()`?\n---\n*/\nextern (C++) class Base {\n    void blah() {}\n}\nclass X : Base {\n    override void blah();//Error\n}\nextern (C++) class Y : Base {\n    override void blah(){}\n}\nclass Z : Base {\n    alias blah = typeof(super).blah;\n    override void blah(){}//Error\n}\nclass O : Base {\n    extern (C++) override void blah(){}\n}\nextern (C++) class OK : Base {\n    alias blah = typeof(super).blah;\n    override void blah(){}\n}\n\nvoid main() {\n    scope b = new Base();\n    b.blah();\n    scope x = new X();\n    x.blah();\n    scope y = new Y();\n    y.blah();\n    scope o = new O();\n    o.blah();\n    scope z = new Z();\n    z.blah();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test14238.d",
    "content": "/* REQUIRED_ARGS: -dip1000\n   PERMUTE_ARGS:\n   TEST_OUTPUT:\n---\nfail_compilation/test14238.d(21): Error: scope variable `fn` may not be returned\nfail_compilation/test14238.d(29): Error: escaping reference to stack allocated value returned by `&baz`\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=14238\n\n@safe:\n\nalias Fn = ref int delegate() return;\n\nref int foo(return scope Fn fn)\n{\n    return fn(); // Ok\n}\n\nref int foo2(scope Fn fn) {\n    return fn(); // Error\n}\n\nref int bar() {\n    int x;\n    ref int baz() {\n            return x;\n    }\n    return foo(&baz);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test143.d",
    "content": "// REQUIRED_ARGS: -de\nmodule test143; // https://issues.dlang.org/show_bug.cgi?id=143\n\nimport imports.test143;\n\nvoid bar(int)\n{\n}\n\nvoid foo()\n{\n    bar(x);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test14496.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test14496.d(21): Error: variable `test14496.foo.f` `void` initializers for pointers not allowed in safe functions\nfail_compilation/test14496.d(24): Error: variable `test14496.foo.Bar.foo` `void` initializers for pointers not allowed in safe functions\nfail_compilation/test14496.d(28): Error: variable `test14496.foo.Baz.x` `void` initializers for pointers not allowed in safe functions\nfail_compilation/test14496.d(48): Error: variable `test14496.sinister.bar` `void` initializers for pointers not allowed in safe functions\nfail_compilation/test14496.d(49): Error: variable `test14496.sinister.baz` `void` initializers for pointers not allowed in safe functions\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=14496\n\n@safe void foo()\n{\n    struct Foo {\n        int* indirection1;\n        Object indirection2;\n        string[] indirection3;\n    }\n\n    Foo f = void;\n\n    struct Bar {\n        Foo foo = void;\n    }\n\n    struct Baz {\n        int* x = void;\n    }\n}\n\n\nstruct Foo {\n    int* indirection1;\n    Object indirection2;\n    string[] indirection3;\n}\n\nstruct Bar {\n    Foo foo = void;\n}\n\nstruct Baz {\n    int* x = void;\n}\n\n@safe void sinister() {\n    Bar bar;\n    Baz baz;\n}\n\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test14538.d",
    "content": "// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/test14538.d(19): Error: cannot implicitly convert expression `x ? cast(uint)this.fCells[x].code : 32u` of type `uint` to `Cell`\n---\n*/\n\nstruct Cell\n{\n    dchar code;\n    alias code this;\n}\n\nstruct Row\n{\n    Cell[] fCells;\n    Cell opIndex(size_t x) { return x ? fCells[x] : ' '; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15191.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test15191.d(17): Error: cannot take address of `ref return` of `foo()` in `@safe` function `bar`\n---\n*/\n\n\n// https://issues.dlang.org/show_bug.cgi?id=15191\n\nref int foo(return ref int s)@safe\n{\n    return s;\n}\n\nint* bar(return ref int s) @safe\n{\n    return &foo(s);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15306.d",
    "content": "/*\nREQUIRED_ARGS:\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/test15306.d(17): Error: `immutable` delegate `test15306.main.__dgliteral1` cannot access mutable data `i`\nfail_compilation/test15306.d(21): Error: `shared` delegate `test15306.main.__dgliteral2` cannot access non-shared data `p`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=15306\n\nvoid main()\n{\n    // immutable cannot access mutable\n    int i = 42;\n    auto dg1 = delegate void() immutable { auto inner = i; };\n\n    // shared cannot access unshared\n    int* p = &i;\n    auto dg2 = delegate int() shared { return *p; };\n    assert(dg2() == i);\n\n    // unshared can access shared\n    shared j = 43;\n    shared int* q = &j;\n    auto dg3 = delegate int() { return *q; };\n    assert(dg2() == j);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15373.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test15373.d(21): Error: Runtime type information is not supported for `extern(C++)` classes\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=15373\n\n// Using `typeid` on an `extern(C++) class` type is ok  as it is evaluated at compile-time\n// See test/runnable/test15373.d\n\n// Using `typeid` on an `extern(C++) class` instance is not ok because `extern(C++) class`\n// instances are not rooted in `Object`\n\nextern(C++) class C { }\n\nvoid foo()\n{\n    C c = new C();\n    auto ti = typeid(c);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15399.d",
    "content": "/* https://issues.dlang.org/show_bug.cgi?id=15399\n---\nfail_compilation/test15399.d(31): Error: writing to misaligned pointer in field S1.ptr is not @safe\nfail_compilation/test15399.d(32): Error: writing to misaligned pointer in field S2.ptr is not @safe\nfail_compilation/test15399.d(33): Error: taking address of misaligned pointer in field S1.ptr is not @safe\nfail_compilation/test15399.d(34): Error: taking address of misaligned pointer in field S2.ptr is not @safe\nfail_compilation/test15399.d(35): Error: 'ref' of misaligned pointer in field S1.ptr is not @safe\nfail_compilation/test15399.d(36): Error: 'ref' of misaligned pointer in field S2.ptr is not @safe\nfail_compilation/test15399.d(37): Error: 'out' of misaligned pointer in field S1.ptr is not @safe\nfail_compilation/test15399.d(38): Error: 'out' of misaligned pointer in field S2.ptr is not @safe\n---\n*/\n\nstruct S1\n{\n        char c;\n    align (1)\n        int* ptr;\n}\n\nalign (1)\nstruct S2\n{\n    int* ptr;\n}\n\n@safe void test(S1* s1, S2* s2)\n{\n    int* p = s1.ptr;\n    p = s2.ptr;\n    s1.ptr = null;\n    s2.ptr = null;\n    int** pp = &s1.ptr;\n    pp = &s2.ptr;\n    bar(s1.ptr);\n    bar(s2.ptr);\n    sinister(s1.ptr);\n    sinister(s2.ptr);\n    cbar(s1.ptr);\n    cbar(s2.ptr);\n}\n\n@safe void bar(ref int*);\n@safe void cbar(ref const int*);\n@safe void sinister(out int*);\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15544.d",
    "content": "/*\nREQUIRED_ARGS: -dip1000\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/test15544.d(21): Error: reference to local `this` assigned to non-scope `_del` in @safe code\nfail_compilation/test15544.d(23): Error: reference to local `this` assigned to non-scope `_del` in @safe code\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=15544\n\nvoid delegate() @safe _del;\n\nstruct S {\n    int x = 42;\n\n    @safe void test()\n    {\n        void foo() { assert(x == 42); }\n        _del = &foo;\n\n        _del = { assert(x == 42); };\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/test15544.d(47): Error: reference to local `y` assigned to non-scope `dg` in @safe code\n---\n*/\n\nint delegate() dg;\n\nvoid testClosure1()\n{\n    int* x;\n    int bar() { return *x; }\n    dg = &bar;\n}\n\n@safe void testClosure2()\n{\n    scope int* y;\n    int bar() { return *y; }\n    dg = &bar;               // Error\n    auto dg2 = &bar;\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15660.d",
    "content": "/* REQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/test15660.d(20): Error: cannot implicitly convert expression `f(v)` of type `int[]` to `immutable(int[])`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=15660\n\nint[] f(ref void[] m) pure\n{\n    auto result = new int[5];\n    m = result;\n    return result;\n}\n\nvoid main()\n{\n    void[] v;\n    immutable x = f(v);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15672.d",
    "content": "/*\n * TEST_OUTPUT:\n---\nfail_compilation/test15672.d(15): Error: cast from `void[]` to `byte[]` not allowed in safe code\nfail_compilation/test15672.d(25): Error: cast from `void*` to `byte*` not allowed in safe code\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=15672\n\nalias byte T;\nalias const(byte) CT;\n\n@safe T[] test1(void[] a)\n{\n    return cast(T[])a;\n}\n\n@safe CT[] test2(void[] a)\n{\n    return cast(CT[])a;\n}\n\n@safe T* test3(void* a)\n{\n    return cast(T*)a;\n}\n\n@safe CT* test4(void* a)\n{\n    return cast(CT*)a;\n}\n\n@safe T[] test5()\n{\n    return cast(T[])[];\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15703.d",
    "content": "/*\nREQUIRED_ARGS: -m32\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/test15703.d(17): Error: cast from `Object[]` to `uint[]` not allowed in safe code\nfail_compilation/test15703.d(19): Error: cast from `object.Object` to `const(uint)*` not allowed in safe code\nfail_compilation/test15703.d(22): Error: cast from `uint[]` to `Object[]` not allowed in safe code\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=15703\n\nvoid test() @safe\n{\n     auto objs = [ new Object() ];\n     auto longs = cast(size_t[]) objs;          // error\n     auto longc = cast(const(size_t)[]) objs;   // ok\n     auto longp = cast(const(size_t)*) objs[0]; // error\n\n     size_t[] al;\n     objs = cast(Object[]) al;                  // error\n\n     auto am = cast(int[])[];\n}\n\nvoid test2() @safe\n{\n    const(ubyte)[] a;\n    auto b = cast(const(uint[])) a;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15704.d",
    "content": "/*\n * TEST_OUTPUT:\n---\nfail_compilation/test15704.d(15): Error: cannot copy `void[]` to `void[]` in `@safe` code\n---\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=15704\n\nvoid main() @safe {\n    Object[] objs = [ new Object() ];\n    void[] arr1 = objs;\n    void[] arr2 = [ 123, 345, 567 ];\n\n    arr1[] = arr2[];  // overwrites pointers with arbitrary ints\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15785.d",
    "content": "// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\nfail_compilation/test15785.d(17): Deprecation: `imports.test15785.Base.foo` is not visible from module `test15785`\nfail_compilation/test15785.d(17): Error: class `test15785.Derived` member `foo` is not accessible\nfail_compilation/test15785.d(18): Deprecation: `imports.test15785.Base.bar` is not visible from module `test15785`\nfail_compilation/test15785.d(18): Error: class `test15785.Derived` member `bar` is not accessible\n---\n*/\nimport imports.test15785;\n\nclass Derived : Base\n{\n    void test()\n    {\n        super.foo();\n        bar();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15785b.d",
    "content": "// REQUIRED_ARGS: -de\n// PERMUTE_ARGS:\n/*\nTEST_OUTPUT:\n---\nfail_compilation/test15785b.d(15): Deprecation: `imports.test15785.Base.T` is not visible from module `test15785b`\nfail_compilation/test15785b.d(16): Deprecation: `imports.test15785.Base.T` is not visible from module `test15785b`\nfail_compilation/test15785b.d(17): Deprecation: `imports.test15785.IBase2.T` is not visible from module `test15785b`\n---\n*/\nimport imports.test15785;\n\nclass Derived : Base, IBase2\n{\n    typeof(super).T t;\n    Base.T t2;\n    IBase2.T t3;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15897.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/test15897.d(18): Deprecation: `test15897.Animal.create` is not visible from class `Cat`\n---\n*/\nmodule test15897;\nimport imports.test15897;\n\nclass Animal\n{\n    private void create() {}\n}\n\nvoid foo(Cat cat)\n{\n    cat.create();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test15989.d",
    "content": "/*\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/test15989.d(40): Error: variable `test15989.main.ctRegex` : Unable to initialize enum with class or pointer to struct. Use static const variable instead.\nfail_compilation/test15989.d(49): Error: variable `test15989.test.c` : Unable to initialize enum with class or pointer to struct. Use static const variable instead.\nfail_compilation/test15989.d(50): Error: cannot use non-constant CTFE pointer in an initializer `&[3][0]`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=15989\n\nimport core.stdc.stdio;\n\ninterface Kickstart{\n    bool foo( int );\n}\n\nclass ShiftOr : Kickstart\n{\n    bool foo( int i )\n    {\n        printf(\"i = %d\\n\", i);\n        return false;\n    }\n}\n\nstruct Regex\n{\n    Kickstart kickstart;\n}\n\nRegex regex()\n{\n    return Regex(new ShiftOr());\n}\n\nvoid main()\n{\n    enum ctRegex = regex();\n    Regex r = ctRegex;\n    r.kickstart.foo(7);\n}\n\nclass C { }\n\nvoid test()\n{\n    enum c = new C();\n    enum pi = new int(3);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test16095.d",
    "content": "/*\nREQUIRED_ARGS:\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/test16095.d(20): Error: `shared` method `test16095.C.ping` is not callable using a non-shared `a`\nfail_compilation/test16095.d(30): Error: `shared` method `test16095.S.ping` is not callable using a non-shared `*a`\nfail_compilation/test16095.d(43): Error: mutable method `test16095.Foo.flip` is not callable using a `immutable` `foo`\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=16095\n\nclass C\n{\n    void ping() shared;\n}\n\nvoid test1(C a)\n{\n    (&a.ping)(); // error\n}\n\nstruct S\n{\n    void ping() shared;\n}\n\nvoid test2(S* a)\n{\n    (&a.ping)(); // error\n}\n\nstruct Foo {\n   bool flag;\n   void flip() {\n        flag = true;\n   }\n}\n\nvoid test3()\n{\n    immutable Foo foo;\n    (&foo.flip)();      // error\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test16116.d",
    "content": "/*\nREQUIRED_ARGS: -m64\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/test16116.d(15): Error: incompatible types for `(v) * (i)`: `__vector(short[8])` and `int`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=16116\n\nvoid foo() {\n    __vector(short[8]) v;\n    int i;\n    v = v * i;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test16188.d",
    "content": "/* PERMUTE_ARGS:\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=16188\n\n/* This produces the message:\n *   Error: no property 'name' for type 'Where'\n * when the actual error is 'getMember is undefined'.\n * This happens because errors are gagged when opDispatch() is compiled,\n * I don't understand why.\n */\n\nvoid where() { Where().name; }\n\nstruct Where\n{\n    void opDispatch(string name)()\n    {\n        alias FieldType = typeof(getMember);\n        WhereField!FieldType;\n    }\n}\n\nstruct WhereField(FieldType) {}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test16193.d",
    "content": "/*\nREQUIRED_ARGS: -dip1000\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/test16193.d(39): Error: function `test16193.abc` is `@nogc` yet allocates closures with the GC\nfail_compilation/test16193.d(41):        test16193.abc.__foreachbody1 closes over variable x at fail_compilation/test16193.d(40)\n---\n*/\n//fail_compilation/test16193.d(22): To enforce `@safe`, the compiler allocates a closure unless `opApply()` uses `scope`\n//fail_compilation/test16193.d(34): To enforce `@safe`, the compiler allocates a closure unless `opApply()` uses `scope`\n//fail_compilation/test16193.d(41): To enforce `@safe`, the compiler allocates a closure unless `opApply()` uses `scope`\n\n// https://issues.dlang.org/show_bug.cgi?id=16193\n\nstruct S {\n    int opApply(int delegate(int) dg) @nogc;\n}\n\nvoid foo() {\n    int x = 0;\n    foreach(i; S.init) {\n        x++;\n    }\n}\n\nstruct T {\n    int opApply(scope int delegate(int) dg) @nogc;\n}\n\n\nvoid bar() @nogc {\n    int x = 0;\n    foreach(i; T.init) {\n        x++;\n    }\n}\n\nvoid abc() @nogc {\n    int x = 0;\n    foreach(i; S.init) {\n        x++;\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test16195.d",
    "content": "/*\n * TEST_OUTPUT:\n---\nfail_compilation/test16195.d(14): Deprecation: The `delete` keyword has been deprecated.  Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead.\nfail_compilation/test16195.d(14): Error: `delete p` is not `@safe` but is used in `@safe` function `test`\n---\n */\n\n\n// https://issues.dlang.org/show_bug.cgi?id=16195\n\n@safe pure nothrow @nogc void test(int* p)\n{\n    delete p;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test16228.d",
    "content": "/* REQUIRED_ARGS: -dip25\n   TEST_OUTPUT:\n---\nfail_compilation/test16228.d(23): Error: function `test16228.S.bar` `static` member has no `this` to which `return` can apply\n---\n*/\n\n\n\n\n// https://issues.dlang.org/show_bug.cgi?id=16228\n\nint* wrap ( return ref int input )\n{\n    return &input;\n}\n\nstruct S\n{\n    int x;\n\n    int foo() return { return 3; }\n    static ref int bar() return { return x; }\n}\n\n\n// https://issues.dlang.org/show_bug.cgi?id=18963\n\nT Identity(T)(return T t) { return t; }\n\nvoid bar(int i, void* p)\n{\n    Identity(p);\n    Identity(i);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test16365.d",
    "content": "/* REQUIRED_ARGS:\n   PERMUTE_ARGS:\n   TEST_OUTPUT:\n---\nfail_compilation/test16365.d(22): Error: `this` reference necessary to take address of member `f1` in `@safe` function `main`\nfail_compilation/test16365.d(24): Error: cannot implicitly convert expression `&f2` of type `void delegate() pure nothrow @nogc @safe` to `void function() @safe`\nfail_compilation/test16365.d(28): Error: address of variable `s` assigned to `dg` with longer lifetime\nfail_compilation/test16365.d(29): Error: `dg.funcptr` cannot be used in `@safe` code\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=16365\n\nstruct S\n{\n    void f1() @safe { }\n}\n\nvoid main() @safe\n{\n    void function() @safe f;\n    f = &S.f1;\n    void f2() @safe { }\n    f = &f2;\n\n    void delegate() @safe dg;\n    S s;\n    dg = &s.f1;\n    f = dg.funcptr;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test16381.d",
    "content": "/*\nREQUIRED_ARGS: -m64\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/test16381.d(16): Error: `foo()` is not an lvalue and cannot be modified\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=16381\n\n__vector(float[4]) foo();\n\nvoid bar()\n{\n    float g = foo().ptr[0];\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test16523.d",
    "content": "// REQUIRED_ARGS: -de\n/*\nTEST_OUTPUT:\n---\nfail_compilation/test16523.d(13): Deprecation: `case` variables have to be `const` or `immutable`\n---\n*/\n\nvoid test(int a, int b)\n{\n    switch (a)\n    {\n    case b: return;\n    default: assert(0);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test16589.d",
    "content": "/* PERMUTE_ARGS:\nREQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/test16589.d(26): Error: returning `&this.data` escapes a reference to parameter `this`, perhaps annotate with `return`\nfail_compilation/test16589.d(31): Error: returning `&this` escapes a reference to parameter `this`, perhaps annotate with `return`\nfail_compilation/test16589.d(37): Error: returning `&s.data` escapes a reference to parameter `s`, perhaps annotate with `return`\nfail_compilation/test16589.d(42): Error: returning `&s` escapes a reference to parameter `s`, perhaps annotate with `return`\nfail_compilation/test16589.d(47): Error: returning `&s.data` escapes a reference to parameter `s`, perhaps annotate with `return`\nfail_compilation/test16589.d(52): Error: returning `& s` escapes a reference to parameter `s`, perhaps annotate with `return`\n---\n*/\n\n\n\n\n\n// https://issues.dlang.org/show_bug.cgi?id=16589\n\nstruct S\n{\n    int data;\n\n    @safe int* access1()\n    {\n        return &data;\n    }\n\n    @safe S* access2()\n    {\n        return &this;\n    }\n}\n\n@safe int* access3(ref S s)\n{\n    return &s.data;\n}\n\n@safe S* access4(ref S s)\n{\n    return &s;\n}\n\n@safe int* access5(S s)\n{\n    return &s.data;\n}\n\n@safe S* access6(S s)\n{\n    return &s;\n}\n\nclass C\n{\n    int data;\n\n    @safe int* access7()\n    {\n        return &data;\n    }\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test16694.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test16694.d(8): Error: cannot take address of imported symbol `bar` at compile time\n---\n*/\nexport void bar();\nauto barptr = &bar;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17096.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test17096.d(28): Error: expected 1 arguments for `isPOD` but had 2\nfail_compilation/test17096.d(29): Error: expected 1 arguments for `isNested` but had 2\nfail_compilation/test17096.d(30): Error: expected 1 arguments for `isVirtualFunction` but had 2\nfail_compilation/test17096.d(31): Error: expected 1 arguments for `isVirtualMethod` but had 2\nfail_compilation/test17096.d(32): Error: expected 1 arguments for `isAbstractFunction` but had 2\nfail_compilation/test17096.d(33): Error: expected 1 arguments for `isFinalFunction` but had 2\nfail_compilation/test17096.d(34): Error: expected 1 arguments for `isOverrideFunction` but had 2\nfail_compilation/test17096.d(35): Error: expected 1 arguments for `isStaticFunction` but had 2\nfail_compilation/test17096.d(36): Error: expected 1 arguments for `isRef` but had 2\nfail_compilation/test17096.d(37): Error: expected 1 arguments for `isOut` but had 2\nfail_compilation/test17096.d(38): Error: expected 1 arguments for `isLazy` but had 2\nfail_compilation/test17096.d(39): Error: expected 1 arguments for `identifier` but had 2\nfail_compilation/test17096.d(40): Error: expected 1 arguments for `getProtection` but had 2\nfail_compilation/test17096.d(41): Error: expected 1 arguments for `parent` but had 2\nfail_compilation/test17096.d(42): Error: expected 1 arguments for `classInstanceSize` but had 2\nfail_compilation/test17096.d(43): Error: expected 1 arguments for `allMembers` but had 2\nfail_compilation/test17096.d(44): Error: expected 1 arguments for `derivedMembers` but had 2\nfail_compilation/test17096.d(45): Error: expected 1 arguments for `getAliasThis` but had 2\nfail_compilation/test17096.d(46): Error: expected 1 arguments for `getAttributes` but had 2\nfail_compilation/test17096.d(47): Error: expected 1 arguments for `getFunctionAttributes` but had 2\nfail_compilation/test17096.d(48): Error: expected 1 arguments for `getUnitTests` but had 2\nfail_compilation/test17096.d(49): Error: expected 1 arguments for `getVirtualIndex` but had 2\nfail_compilation/test17096.d(50): Error: a single type expected for trait pointerBitmap\n---\n*/\nenum b03 = __traits(isPOD, 1, 2);\nenum b04 = __traits(isNested, 1, 2);\nenum b05 = __traits(isVirtualFunction, 1, 2);\nenum b06 = __traits(isVirtualMethod, 1, 2);\nenum b07 = __traits(isAbstractFunction, 1, 2);\nenum b08 = __traits(isFinalFunction, 1, 2);\nenum b09 = __traits(isOverrideFunction, 1, 2);\nenum b10 = __traits(isStaticFunction, 1, 2);\nenum b11 = __traits(isRef, 1, 2);\nenum b12 = __traits(isOut, 1, 2);\nenum b13 = __traits(isLazy, 1, 2);\nenum b14 = __traits(identifier, 1, 2);\nenum b15 = __traits(getProtection, 1, 2);\nenum b16 = __traits(parent, 1, 2);\nenum b17 = __traits(classInstanceSize, 1, 2);\nenum b18 = __traits(allMembers, 1, 2);\nenum b19 = __traits(derivedMembers, 1, 2);\nenum b20 = __traits(getAliasThis, 1, 2);\nenum b21 = __traits(getAttributes, 1, 2);\nenum b22 = __traits(getFunctionAttributes, 1, 2);\nenum b23 = __traits(getUnitTests, 1, 2);\nenum b24 = __traits(getVirtualIndex, 1, 2);\nenum b25 = __traits(getPointerBitmap, 1, 2);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17284.d",
    "content": "/* REQUIRED_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/test17284.d(16): Error: field `U.c` cannot access pointers in `@safe` code that overlap other fields\npure nothrow @safe void(U t)\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17284\n\nclass C { }\nunion U { C c; int i; }\n\n@safe void func(T)(T t)\n{\n        t.c = new C;\n}\n\npragma(msg, typeof(func!U));\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17307.d",
    "content": "/* \nTEST_OUTPUT:\n---\nfail_compilation/test17307.d(9): Error: anonymous struct can only be a part of an aggregate, not module `test17307`\n---\n * https://issues.dlang.org/show_bug.cgi?id=17307\n */\n\nstruct { enum bitsPerWord = size_t; }\n\nvoid main()\n{ }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17380.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test17380.d(12): Error: undefined identifier `ThisTypeDoesNotExistsAndCrahesTheCompiler`\n---\n * https://issues.dlang.org/show_bug.cgi?id=17380\n */\n\nstruct Int128\n{\n    Uint128 opCast()\n    {\n        return ThisTypeDoesNotExistsAndCrahesTheCompiler;\n    }\n    alias opCast this;\n}\n\nstruct Uint128\n{\n    Int128 opCast() { return Int128.init; }\n    alias opCast this;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17380spec.d",
    "content": "/* REQUIRED_ARGS: -verrors=spec\nTEST_OUTPUT:\n---\n(spec:1) fail_compilation/test17380spec.d(14): Error: cannot resolve identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`\n(spec:1) fail_compilation/test17380spec.d(14): Error: no property `ThisTypeDoesNotExistAndCrashesTheCompiler` for type `Uint128`\nfail_compilation/test17380spec.d(14): Error: undefined identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`\n---\n */\n\nstruct Int128\n{\n    Uint128 opCast()\n    {\n        return ThisTypeDoesNotExistAndCrashesTheCompiler;\n    }\n    alias opCast this;\n}\n\nstruct Uint128\n{\n    Int128 opCast() { return Int128.init; }\n    alias opCast this;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17422.d",
    "content": "/*\nREQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/test17422.d(23): Error: scope variable `p` may not be returned\n---\n*/\nstruct RC\n{\n    Object get() return scope @trusted\n    {\n        return cast(Object) &store[0];\n    }\n\nprivate:\n    ubyte[__traits(classInstanceSize, Object)] store;\n}\n\nObject test() @safe\n{\n    RC rc;\n    auto p = rc.get; // p must be inferred as scope variable, works for int*\n    return p;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17423.d",
    "content": "/* REQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/test17423.d(26): Error: reference to local `this` assigned to non-scope parameter `dlg` calling test17423.Bar.opApply\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17423\n\nstruct Bar\n{\n    int delegate(int) @safe myDlg;\n\n    auto opApply(int delegate(int) @safe dlg) @safe {\n        myDlg = dlg;\n        return 0;\n    }\n}\n\nstruct Foo\n{\n    Bar o;\n    int i = 3;\n\n    this(int x) @safe {\n        foreach(_; o) { i = 0; }\n        i = x;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17425.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test17425.d(24): Error: parameter index must be in range 0..4 not 4\nfail_compilation/test17425.d(27): Error: first argument to `__traits(getParameterStorageClasses, i, 4)` is not a function\nfail_compilation/test17425.d(29): Error: expression expected as second argument of `__traits(getParameterStorageClasses, foo, int)`\nfail_compilation/test17425.d(31): Error: expected 2 arguments for `getParameterStorageClasses` but had 3\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17425\n\nref int foo(return ref const int* p, scope int* a, out int b, lazy int c);\n\n//pragma(msg, __traits(getParameterStorageClasses, foo, 0));\n\nstatic assert(__traits(getParameterStorageClasses, foo, 0)[0] == \"return\");\nstatic assert(__traits(getParameterStorageClasses, foo, 0)[1] == \"ref\");\n\n//pragma(msg, __traits(getParameterStorageClasses, foo, 1));\nstatic assert(__traits(getParameterStorageClasses, foo, 1)[0] == \"scope\");\nstatic assert(__traits(getParameterStorageClasses, foo, 2)[0] == \"out\");\nstatic assert(__traits(getParameterStorageClasses, typeof(&foo), 3)[0] == \"lazy\");\n\nenum a1 = __traits(getParameterStorageClasses, foo, 4);\n\nint i;\nenum a2 = __traits(getParameterStorageClasses, i, 4);\n\nenum a3 = __traits(getParameterStorageClasses, foo, int);\n\nenum a4 = __traits(getParameterStorageClasses, foo, 0, 1);\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17450.d",
    "content": "/*\nREQUIRED_ARGS: -dip1000 -dip25\nTEST_OUTPUT:\n---\nfail_compilation/test17450.d(15): Error: returning `&s.bar` escapes a reference to parameter `s`, perhaps annotate with `return`\nfail_compilation/test17450.d(18): Error: returning `&this.bar` escapes a reference to parameter `this`, perhaps annotate with `return`\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=17450\n\nalias dg_t = void delegate();\n\nstruct S {\n    @safe dg_t foo1(ref S s) {\n        return &s.bar;\n    }\n    @safe dg_t foo2() {\n        return &bar;\n    }\n\n    @safe dg_t foo3(return ref S s) {\n        return &s.bar;\n    }\n    @safe dg_t foo4() return {\n        return &bar;\n    }\n\n    @safe void bar();\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/test17450.d(103): Error: scope variable `c` may not be returned\nfail_compilation/test17450.d(106): Error: scope variable `this` may not be returned\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=17450\n\n#line 100\n\nclass C {\n    @safe dg_t foo1(scope C c) {\n        return &c.bar;\n    }\n    @safe dg_t foo2() scope {\n        return &bar;\n    }\n\n    @safe dg_t foo3(return scope C c) {\n        return &c.bar;\n    }\n    @safe dg_t foo4() return scope {\n        return &bar;\n    }\n\n    @safe void bar();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17451.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test17451.d(22): Error: undefined identifier `allocator`\nfail_compilation/test17451.d(23): Error: `false` has no effect\nfail_compilation/test17451.d(30): Error: variable `test17451.HashMap!(ThreadSlot).HashMap.__lambda2.v` size of type `ThreadSlot` is invalid\nfail_compilation/test17451.d(44): Error: template instance `test17451.HashMap!(ThreadSlot)` error instantiating\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17451\n\ninterface ManualEvent {}\n\ninterface EventDriver {\n        ManualEvent createManualEvent() ;\n}\n\nstruct ArraySet(Key)\n{\n        ~this()\n    {\n                try allocator;\n                catch false; // should never happen\n        }\n}\n\nstruct HashMap(TValue)\n{\n        alias Value = TValue;\n        static if ({ Value v; }) {}\n}\n\nstruct Task {}\n\nclass Libevent2Driver : EventDriver {\n        Libevent2ManualEvent createManualEvent() {}\n}\n\nstruct ThreadSlot {\n        ArraySet!Task tasks;\n}\n\nclass Libevent2ManualEvent {\n        HashMap!ThreadSlot m_waiters;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17586.d",
    "content": "/* REQUIRED_ARGS: -o- -de\nTEST_OUTPUT:\n---\nfail_compilation/test17586.d(13): Deprecation: `test17586.D.foo` is overriding the deprecated method `test17586.C.foo`\n---\n*/\n\nclass C{\n    deprecated void foo(){}\n}\n\nclass D : C{\n    override void foo(){}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17868.d",
    "content": "/*\nTEST_OUTPUT:\n----\nfail_compilation/test17868.d(10): Error: pragma `crt_constructor` takes no argument\nfail_compilation/test17868.d(11): Error: pragma `crt_constructor` takes no argument\nfail_compilation/test17868.d(12): Error: pragma `crt_constructor` takes no argument\nfail_compilation/test17868.d(13): Error: pragma `crt_constructor` takes no argument\n----\n */\npragma(crt_constructor, ctfe())\npragma(crt_constructor, 1.5f)\npragma(crt_constructor, \"foobar\")\npragma(crt_constructor, S())\nvoid foo()\n{\n}\n\nint ctfe()\n{\n    __gshared int val;\n    return val;\n}\n\nstruct S {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17868b.d",
    "content": "/*\nTEST_OUTPUT:\n----\nfail_compilation/test17868b.d(10): Error: function `test17868b.foo` must be `extern(C)` for `pragma(crt_constructor)`\nfail_compilation/test17868b.d(14): Error: function `test17868b.bar` must be `extern(C)` for `pragma(crt_constructor)`\nfail_compilation/test17868b.d(9): Error: pragma `crt_constructor` can only apply to a single declaration\n----\n */\npragma(crt_constructor):\nvoid foo()\n{\n}\n\nvoid bar()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17892.d",
    "content": "/* REQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/test17892.d(27): Error: returning `s.pointer1()` escapes a reference to local variable `s`\nfail_compilation/test17892.d(29): Error: returning `s.pointer2()` escapes a reference to local variable `s`\nfail_compilation/test17892.d(31): Error: returning `s.pointer3()` escapes a reference to local variable `s`\n---\n*/\n\n\n// https://issues.dlang.org/show_bug.cgi?id=17892\n\nstruct S\n{\n  @safe:\n    int x;\n    int[1] y;\n    auto pointer1() return { return &x; }\n    auto pointer2() return { return &y[0]; }\n    auto pointer3() return { return &y[0..1][0]; }\n}\n\n@safe int* testPointer(int b)\n{\n    S s;\n    if (b == 1)\n        return s.pointer1();\n    else if (b == 2)\n        return s.pointer2();\n    else\n        return s.pointer3();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17908a.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test17908a.d(10): Error: function `test17908a.foo` cannot be used because it is annotated with `@disable`\n---\n*/\n\n@disable void foo();\n@disable void foo(int) {}\nalias g = foo;\n\nvoid main()\n{\n    g(10);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17908b.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test17908b.d(13): Error: function `test17908b.foobar` cannot be used because it is annotated with `@disable`\n---\n*/\nvoid foobar() {}\n@disable void foobar(int) {}\nalias i = foobar;\n\nvoid main()\n{\n    i(10);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test17959.d",
    "content": "/* REQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/test17959.d(18): Error: scope variable `this` assigned to non-scope `this.escape`\nfail_compilation/test17959.d(19): Error: scope variable `this` assigned to non-scope `this.f`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17959\n\nclass Foo\n{\n    void delegate () @safe escape;\n    Foo f;\n\n    void escfoo() @safe scope\n    {\n        this.escape = &this.escfoo;\n        f = this;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test18130.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test18130.d(8): Error: variable `test18130.foo.v` Zero-length `out` parameters are not allowed.\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=18130\nvoid foo(out byte[0] v)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test18282.d",
    "content": "/* REQUIRED_ARGS: -dip1000\n   TEST_OUTPUT:\n---\nfail_compilation/test18282.d(25): Error: scope variable `aa` may not be returned\nfail_compilation/test18282.d(34): Error: copying `& i` into allocated memory escapes a reference to local variable `i`\nfail_compilation/test18282.d(35): Error: copying `& i` into allocated memory escapes a reference to local variable `i`\nfail_compilation/test18282.d(36): Error: scope variable `staa` may not be returned\nfail_compilation/test18282.d(44): Error: copying `S2000(& i)` into allocated memory escapes a reference to local variable `i`\nfail_compilation/test18282.d(53): Error: copying `& i` into allocated memory escapes a reference to local variable `i`\nfail_compilation/test18282.d(53): Error: copying `& c` into allocated memory escapes a reference to local variable `c`\n---\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=18282\n\nstring* f() @safe\n{\n    scope string*[] ls;\n    return ls[0];\n}\n\nint* g() @safe\n{\n    scope int*[3] aa;\n    return aa[0];\n}\n\n@safe:\n\nauto bar1()\n{\n    int i = void;\n    int*[1] staa = [ &i ];\n    auto    dyna = [ &i ];\n    int*[ ] dynb = [ &i ];\n    return staa[0];\n}\n\nstruct S2000 { int* p; }\n\nS2000 bar2()\n{\n    int i;\n    S2000[] arr = [ S2000(&i) ];\n    return arr[0];\n}\n\n\nvoid bar2()\n{\n    int i;\n    char c;\n    char*[int*] aa = [ &i : &c ];\n}\n\n\n/******************************\nTEST_OUTPUT:\n---\nfail_compilation/test18282.d(1007): Error: copying `& foo` into allocated memory escapes a reference to local variable `foo`\nfail_compilation/test18282.d(1008): Error: copying `& foo` into allocated memory escapes a reference to local variable `foo`\nfail_compilation/test18282.d(1009): Error: copying `& foo` into allocated memory escapes a reference to local variable `foo`\nfail_compilation/test18282.d(1016): Error: copying `&this` into allocated memory escapes a reference to parameter variable `this`\n---\n*/\n\n#line 1000\n\n// https://issues.dlang.org/show_bug.cgi?id=18282\n\nvoid test18282() @safe\n{\n    string foo = \"foo\";\n    scope string*[] ls;\n    ls = ls ~ &foo;\n    ls = &foo ~ ls;\n    ls ~= &foo;\n}\n\nstruct S\n{\n    auto fun()\n    {\n        arr ~= &this;\n    }\n\n    S*[] arr;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test18312.d",
    "content": "/*\nREQUIRED_ARGS: -betterC\nTEST_OUTPUT:\n---\nfail_compilation/test18312.d(14): Error: array concatenation of expression `\"[\" ~ s ~ \"]\"` requires the GC which is not available with -betterC\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18312\n\nextern (C) void main()\n{\n    scope string s;\n    s = \"[\" ~ s ~ \"]\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test18484.d",
    "content": "/* REQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/test18484.d(19): Error: returning `x.bar()` escapes a reference to local variable `x`\nfail_compilation/test18484.d(24): Error: escaping reference to stack allocated value returned by `S(0)`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18484\n\nstruct S\n{\n    int* bar() return;\n    int i;\n}\n\nint* test1()\n{\n    auto x = S(); return x.bar();  // error\n}\n\nint* test2()\n{\n    return S().bar();  // error\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test18554.d",
    "content": "/* REQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/test18554.d(15): Error: struct `imp18554.S` member `i` is not accessible from `@safe` code\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18554\n\nimport imports.imp18554;\n\nvoid test1() @safe\n{\n    S s;\n    s.tupleof[0] = 1;\n}\n\nvoid test2()\n{\n    S s;\n    s.tupleof[0] = 1;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test18597.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test18597.d(24): Error: field `Unaligned.p` cannot modify misaligned pointers in `@safe` code\nfail_compilation/test18597.d(25): Error: field `Unaligned.p` cannot assign to misaligned pointers in `@safe` code\nfail_compilation/test18597.d(26): Error: field `Unaligned.p` cannot assign to misaligned pointers in `@safe` code\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18597\n\n@safe:\n\nalign(1)\nstruct Unaligned\n{\nalign(1):\n    ubyte filler;\n    int* p;\n}\n\nvoid test()\n{\n    Unaligned u;\n    u.p = new int;\n    Unaligned v = Unaligned(0, new int);\n    Unaligned w = { p : new int };\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test18607.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test18607.d(10): Error: function `test18607.test!int.test` no `return exp;` or `assert(0);` at end of function\n& test\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18607\n\nint* test(T...)() pure @safe {\n        L:foreach(_; T) {\n                continue L;\n                return null;\n        }\n}\n\n\npragma(msg, &test!(int));\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test18644.d",
    "content": "/* REQUIRED_ARGS: -dip1000\nTEST_OUTPUT:\n---\nfail_compilation/test18644.d(15): Error: storing reference to stack allocated value returned by `foo()` into allocated memory causes it to escape\nfail_compilation/test18644.d(16): Error: escaping reference to stack allocated value returned by `foo()`\nfail_compilation/test18644.d(22): Error: escaping reference to stack allocated value returned by `foo()`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18644\n\n@safe int* test1() {\n    int i;\n    int* foo() { return &i; }\n    int*[] b = [foo()];\n    return foo();\n}\n\n@safe ref int test2() {\n    int i;\n    ref int foo() { return i; }\n    return foo();\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test18708.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test18708.d(24): Error: one path skips field `s`\nfail_compilation/test18708.d(29): Error: one path skips field `s`\nfail_compilation/test18708.d(34): Error: one path skips field `s`\nfail_compilation/test18708.d(39): Error: one path skips field `s`\n---\n*/\n// https://issues.dlang.org/show_bug.cgi?id=18708\n\nstruct S { int y; @disable this(); }\n\nclass C\n{\n    S s;\n\n    this(S t)\n    {\n        if (bar(s = t)) foo(); // OK\n    }\n\n    this(S t, int i)\n    {\n        i || bar(s = t);\n    }\n\n    this(S t, int i, int j)\n    {\n        i && bar(s = t);\n    }\n\n    this(S t, int i, long j)\n    {\n        i ? bar(s = t) : i;\n    }\n\n    this(S t, int i, byte j)\n    {\n        i ? i : bar(s = t);\n    }\n}\n\nint bar(S s);\nint foo();\n\n/***********************************/\n\nclass E : Exception\n{\n    this(string msg, int line = 0, int pos = 0) pure nothrow @safe\n    {\n        if (line)\n            super(\"hello\");\n        else\n            super(msg);\n    }\n\n    this(string msg, string file, size_t line) pure nothrow @safe\n    {\n        super(msg, file, line);\n    }\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test18736.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test18736.d(21): Error: constructor calls not allowed in loops or after labels\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=18736\n\nclass A\n{\n    this(char c) { }\n\n    this(int i)\n    {\n        switch (i)\n        {\n            case 1:  break;\n            case 2: .. case 4: break;\n            default: break;\n        }\n        this('c');\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test19112.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test19112.d(13): Error: cannot implicitly convert expression `[123, 456]` of type `int[]` to `int[1]`\nfail_compilation/test19112.d(15): Error: cannot implicitly convert expression `a` of type `int[]` to `int[1]`\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=19112\n\nvoid main()\n{\n    int[int[1]] aa;\n    int* p = [123, 456] in aa;\n    int[] a;\n    p = a in aa;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test19176.d",
    "content": "/*\nREQUIRED_ARGS: -unittest\nTEST_OUTPUT:\n---\nfail_compilation/test19176.d(19): Error: `static if` conditional cannot be at global scope\nfail_compilation/test19176.d(14): Error: `tuple()` has no effect\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=19176\n\nvoid main()\n{\n    __traits(getUnitTests, foo);\n}\n\ntemplate foo()\n{\n    static if(true)\n    {\n        enum bar;\n    }\n    else\n    {\n        enum bar;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test19193.d",
    "content": "/*\nREQUIRED_ARGS: -de\nTEST_OUTPUT\n---\nfail_compilation/test19193.d(13): Deprecation: enum member `test19193.T19193!int.A.b` is deprecated\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=19193\n\nvoid main ()\n{\n    cast(void)T19193!int.A.b;\n}\n\ntemplate T19193(T)\n{\n    enum A\n    {\n        deprecated b\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test314.d",
    "content": "/*\nREQUIRED_ARGS: -de\nTEST_OUTPUT:\n---\nfail_compilation/test314.d(19): Deprecation: `imports.a314.renamed` is not visible from module `test314`\nfail_compilation/test314.d(20): Deprecation: `imports.a314.bug` is not visible from module `test314`\nfail_compilation/test314.d(22): Deprecation: `imports.b314.renamedpkg` is not visible from module `test314`\nfail_compilation/test314.d(23): Deprecation: `imports.b314.bugpkg` is not visible from module `test314`\n---\n*/\n\nmodule test314;\n\nimport imports.a314;\nimport imports.b314;\n\nvoid main()\n{\n    renamed.bug(\"This should not work.\\n\");\n    bug(\"This should not work.\\n\");\n\n    renamedpkg.bug(\"This should not work.\\n\");\n    bugpkg(\"This should not work.\\n\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test4682.d",
    "content": "/*\nTEST_OUTPUT:\n----\nfail_compilation/test4682.d(10): Error: integer overflow: `int.min / -1`\nfail_compilation/test4682.d(11): Error: integer overflow: `long.min / -1L`\nfail_compilation/test4682.d(12): Error: integer overflow: `int.min % -1`\nfail_compilation/test4682.d(13): Error: integer overflow: `long.min % -1L`\n----\n*/\nauto a = int.min / -1;\nauto b = long.min / -1;\nauto c = int.min % -1;\nauto d = long.min % -1;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test4682a.d",
    "content": "/*\nTEST_OUTPUT:\n----\nfail_compilation/test4682a.d(10): Error: divide by 0\nfail_compilation/test4682a.d(11): Error: divide by 0\nfail_compilation/test4682a.d(12): Error: divide by 0\nfail_compilation/test4682a.d(13): Error: divide by 0\n----\n*/\nauto a = int.min / 0;\nauto b = long.min / 0;\nauto c = int.min % 0;\nauto d = long.min % 0;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test4838.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test4838.d(13): Error: `const`/`immutable`/`shared`/`inout`/`return` attributes are only valid for non-static member functions\nfail_compilation/test4838.d(14): Error: `const`/`immutable`/`shared`/`inout`/`return` attributes are only valid for non-static member functions\nfail_compilation/test4838.d(15): Error: `const`/`immutable`/`shared`/`inout`/`return` attributes are only valid for non-static member functions\nfail_compilation/test4838.d(16): Error: `const`/`immutable`/`shared`/`inout`/`return` attributes are only valid for non-static member functions\nfail_compilation/test4838.d(17): Error: `const`/`immutable`/`shared`/`inout`/`return` attributes are only valid for non-static member functions\nfail_compilation/test4838.d(18): Error: `const`/`immutable`/`shared`/`inout`/`return` attributes are only valid for non-static member functions\n---\n*/\n\nvoid function() const fpc;\nvoid function() immutable fpi;\nvoid function() shared fps;\nvoid function() shared const fpsc;\nvoid function() inout fpw;\nvoid function() shared inout fpsw;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test4946.d",
    "content": "/* TEST_OUTPUT:\n---\nfail_compilation/test4946.d(13): Error: 'pure' cannot be placed after a template constraint\nfail_compilation/test4946.d(14): Error: 'const' cannot be placed after a template constraint\nfail_compilation/test4946.d(15): Error: 'immutable' cannot be placed after a template constraint\nfail_compilation/test4946.d(16): Error: 'inout' cannot be placed after a template constraint\nfail_compilation/test4946.d(17): Error: 'shared' cannot be placed after a template constraint\nfail_compilation/test4946.d(18): Error: 'nothrow' cannot be placed after a template constraint\nfail_compilation/test4946.d(19): Error: attributes cannot be placed after a template constraint\n---\n*/\n\nvoid bar1(int x)() if (x > 0) pure { int a;}\nvoid bar2(int x)() if (x > 0) const { int a;}\nvoid bar3(int x)() if (x > 0) immutable { int a;}\nvoid bar4(int x)() if (x > 0) inout { int a;}\nvoid bar5(int x)() if (x > 0) shared { int a;}\nvoid bar6(int x)() if (x > 0) nothrow { int a;}\nvoid bar7(int x)() if (x > 0) @safe { int a;}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test5412a.d",
    "content": "module test5412a;\n\nimport A = imports.test5412a;\nimport A = imports.test5412b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test5412b.d",
    "content": "module test5412b;\n\nimport A = imports.test5412a;\nstatic import A = imports.test5412b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test5412c.d",
    "content": "module test5412c;\n\nimport test5412c2 = imports.test5412a;\nimport test5412c2;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test64.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/imports/test64a.d(1): Error: module `imports` from file fail_compilation/imports/test64a.d conflicts with package name imports\n---\n*/\n\n// PERMUTE_ARGS:\n\n//import std.stdio;\n\nimport imports.test64a;\n\nint main(string[] args)\n{\n    //writefln(file1);\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test6883.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test6883.d(15): Error: array index 5 is out of bounds `x[0 .. 5]`\nfail_compilation/test6883.d(17): Error: array index 7 is out of bounds `x[0 .. 5]`\nfail_compilation/test6883.d(21): Error: array index 5 is out of bounds `x[0 .. 5]`\nfail_compilation/test6883.d(23): Error: array index 7 is out of bounds `x[0 .. 5]`\n---\n*/\n\nvoid main()\n{\n    {\n        int[5] x;\n        x[x.length] = 1;\n        enum size_t n = 2;\n        x[x.length + n] = 2;\n    }\n    {\n        int[5] x;\n        x[$] = 1;\n        enum size_t n = 2;\n        x[$ + n] = 2;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test8509.d",
    "content": "module test8509;\nenum E : string { a = \"hello\", b = \"world\" }\n\nvoid main()\n{\n    E e1 = E.a ~ \" world\";\n    E e2 = \"hello \" ~ E.b;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test8556.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test8556.d(21): Error: template instance `test8556.Grab!(Circle!(uint[]))` does not match template declaration `Grab(Range) if (!isSliceable!Range)`\nfail_compilation/test8556.d(52): Error: template instance `test8556.grab!(Circle!(uint[]))` error instantiating\n---\n*/\n\nextern(C) int printf(const char*, ...);\n\ntemplate isSliceable(R)\n{\n    enum bool isSliceable = is(typeof( R.init[1 .. 2] ));\n}\n\nstruct Grab(Range) if (!isSliceable!Range)\n{\n    public Range source;\n}\n\nGrab!R grab(R)(R input)\n{\n    return Grab!R(input);\n}\n\n// 3. evaluate isSliceable in template constraint\nauto grabExactly(R)(R range) if (!isSliceable!R) { return 0; }\nauto grabExactly(R)(R range) if ( isSliceable!R) { return 0; }\n\nstruct Circle(Range)\n{\n    // 2. auto return opSlice\n    auto opSlice(size_t i, size_t j)\n    {\n        //pragma(msg, typeof(opSlice)); // prints \"fwdref err\" with B, but doesn't with A\n\n        printf(\"%d %d\\n\", i, j);\n        assert(j >= i);\n\n        // 1. grabExactly curcular refers this opSlice.\n        return grabExactly(typeof(this)());     // broken execution with A\n    }\n}\n\nCircle!R circle(R)()\n{\n    return Circle!R();\n}\n\nvoid main()\n{\n    auto t = grab(circle!(uint[])());\n\n    auto cx = circle!(uint[])();\n    auto slice = cx[23 .. 33];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test8751.d",
    "content": "Bar foo3(ref const int x) pure {\n    return y => x > y; // error\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test9150.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=9150\n// Mismatching static array length should be detected in foreach\n/*\nTEST_OUTPUT:\n---\nfail_compilation/test9150.d(14): Error: mismatched array lengths, 5 and 3\n---\n*/\n\nvoid main()\n{\n    int[3][2] matrix = [ [1,11,111], [2,22,222] ];\n\n    foreach (int[5] row; matrix) //if int[3], there is no error.\n    {\n        foreach (x; row)\n        {}//write(x, \"  \");\n\n        //writeln();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test9176.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/test9176.d(14): Error: forward reference to inferred return type of function call `get()`\nfail_compilation/test9176.d(10):        while evaluating: `static assert(!false)`\n---\n*/\n\nvoid foo(int x) {}\nstatic assert(!is(typeof(foo(S()))));\n\nstruct S\n{\n    auto get() { return get(); }\n    alias get this;\n}\n\nvoid main(){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test9701.d",
    "content": "/*\nTEST_OUTPUT\n---\nfail_compilation/test9701.d(38): Error: `@safe` is not a valid attribute for enum members\nfail_compilation/test9701.d(39): Error: `@system` is not a valid attribute for enum members\nfail_compilation/test9701.d(40): Error: `@trusted` is not a valid attribute for enum members\nfail_compilation/test9701.d(41): Error: `@nogc` is not a valid attribute for enum members\nfail_compilation/test9701.d(42): Error: `pure` is not a valid attribute for enum members\nfail_compilation/test9701.d(43): Error: `shared` is not a valid attribute for enum members\nfail_compilation/test9701.d(44): Error: `inout` is not a valid attribute for enum members\nfail_compilation/test9701.d(45): Error: `immutable` is not a valid attribute for enum members\nfail_compilation/test9701.d(46): Error: `const` is not a valid attribute for enum members\nfail_compilation/test9701.d(47): Error: `synchronized` is not a valid attribute for enum members\nfail_compilation/test9701.d(48): Error: `scope` is not a valid attribute for enum members\nfail_compilation/test9701.d(49): Error: `auto` is not a valid attribute for enum members\nfail_compilation/test9701.d(50): Error: `ref` is not a valid attribute for enum members\nfail_compilation/test9701.d(51): Error: `__gshared` is not a valid attribute for enum members\nfail_compilation/test9701.d(52): Error: `final` is not a valid attribute for enum members\nfail_compilation/test9701.d(53): Error: `extern` is not a valid attribute for enum members\nfail_compilation/test9701.d(54): Error: `export` is not a valid attribute for enum members\nfail_compilation/test9701.d(55): Error: `nothrow` is not a valid attribute for enum members\nfail_compilation/test9701.d(56): Error: `public` is not a valid attribute for enum members\nfail_compilation/test9701.d(57): Error: `private` is not a valid attribute for enum members\nfail_compilation/test9701.d(58): Error: `package` is not a valid attribute for enum members\nfail_compilation/test9701.d(59): Error: `static` is not a valid attribute for enum members\nfail_compilation/test9701.d(60): Error: `static` is not a valid attribute for enum members\nfail_compilation/test9701.d(61): Error: `static` is not a valid attribute for enum members\nfail_compilation/test9701.d(62): Error: `static` is not a valid attribute for enum members\n---\n*/\n\n// This test exists to verify that parsing of enum member attributes rejects invalid attributes\n\n// https://issues.dlang.org/show_bug.cgi?id=9701\n\nenum Enum\n{\n    @safe safe,\n    @system system,\n    @trusted trusted,\n    @nogc nogc,\n    pure pure_,\n    shared shared_,\n    inout inout_,\n    immutable immutable_,\n    const const_,\n    synchronized synchronized_,\n    scope scope_,\n    auto auto_,\n    ref ref_,\n    __gshared __gshared_,\n    final final_,\n    extern extern_,\n    export export_,\n    nothrow nothrow_,\n    public public_,\n    private private_,\n    package package_,\n    static static1,\n    @(\"a\") static static2,\n    static @(\"a\") static3,\n    @(\"a\") static @(\"b\") static3,\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/test9701b.d",
    "content": "/*\nREQUIRED_ARGS: -de\nTEST_OUTPUT\n---\nfail_compilation/test9701b.d(20): Deprecation: enum member `test9701b.Enum.e0` is deprecated\nfail_compilation/test9701b.d(21): Deprecation: enum member `test9701b.Enum.e1` is deprecated - message\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=9701\n\nenum Enum\n{\n    deprecated e0,\n    deprecated(\"message\") e1,\n}\n\nvoid main()\n{\n    auto value = Enum.e0;\n    auto value2 = Enum.e1;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/testCols.d",
    "content": "// REQUIRED_ARGS: -vcolumns\n// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/testCols.d(13,5): Error: undefined identifier `nonexistent`\n---\n*/\n\nvoid test()\n{\n    nonexistent();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/testInference.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/testInference.d(24): Error: cannot implicitly convert expression `this.a` of type `inout(A8998)` to `immutable(A8998)`\n---\n*/\n\nclass A8998\n{\n    int i;\n}\nclass C8998\n{\n    A8998 a;\n\n    this()\n    {\n        a = new A8998();\n    }\n\n    // WRONG: Returns immutable(A8998)\n    immutable(A8998) get() inout pure\n    {\n        return a;   // should be error\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/testInference.d(39): Error: cannot implicitly convert expression `s` of type `const(char[])` to `string`\nfail_compilation/testInference.d(44): Error: cannot implicitly convert expression `a` of type `int[]` to `immutable(int[])`\nfail_compilation/testInference.d(49): Error: cannot implicitly convert expression `a` of type `int[]` to `immutable(int[])`\nfail_compilation/testInference.d(54): Error: cannot implicitly convert expression `a` of type `int[]` to `immutable(int[])`\n---\n*/\nstring foo(in char[] s) pure\n{\n    return s;   //\n}\nimmutable(int[]) x1() /*pure*/\n{\n    int[] a = new int[](10);\n    return a;   //\n}\nimmutable(int[]) x2(int len) /*pure*/\n{\n    int[] a = new int[](len);\n    return a;\n}\nimmutable(int[]) x3(immutable(int[]) org) /*pure*/\n{\n    int[] a = new int[](org.length);\n    return a;   //\n}\n\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/testInference.d(94): Error: cannot implicitly convert expression `c` of type `testInference.C1` to `immutable(C1)`\nfail_compilation/testInference.d(95): Error: cannot implicitly convert expression `c` of type `testInference.C1` to `immutable(C1)`\nfail_compilation/testInference.d(96): Error: cannot implicitly convert expression `c` of type `testInference.C3` to `immutable(C3)`\nfail_compilation/testInference.d(97): Error: cannot implicitly convert expression `c` of type `testInference.C3` to `immutable(C3)`\nfail_compilation/testInference.d(100): Error: undefined identifier `X1`, did you mean function `x1`?\nfail_compilation/testInference.d(106): Error: cannot implicitly convert expression `s` of type `S1` to `immutable(S1)`\nfail_compilation/testInference.d(109): Error: cannot implicitly convert expression `a` of type `int*[]` to `immutable(int*[])`\nfail_compilation/testInference.d(110): Error: cannot implicitly convert expression `a` of type `const(int)*[]` to `immutable(int*[])`\nfail_compilation/testInference.d(114): Error: cannot implicitly convert expression `s` of type `S2` to `immutable(S2)`\nfail_compilation/testInference.d(115): Error: cannot implicitly convert expression `s` of type `S2` to `immutable(S2)`\nfail_compilation/testInference.d(116): Error: cannot implicitly convert expression `s` of type `S2` to `immutable(S2)`\nfail_compilation/testInference.d(118): Error: cannot implicitly convert expression `a` of type `const(int)*[]` to `immutable(int*[])`\n---\n*/\nimmutable(Object) get(inout int*) pure\n{\n    auto o = new Object;\n    return o;   // should be ok\n}\nimmutable(Object) get(immutable Object) pure\n{\n    auto o = new Object;\n    return o;   // should be ok\n}\ninout(Object) get(inout Object) pure\n{\n    auto o = new Object;\n    return o;   // should be ok (, but cannot in current conservative rule)\n}\n\nclass C1 { C2 c2; }\nclass C2 { C3 c3; }\nclass C3 { C1 c1; }\nimmutable(C1) recursive1(C3 pc) pure { auto c = new C1(); return c; }   // should be error, because pc.c1 == C1\nimmutable(C1) recursive2(C2 pc) pure { auto c = new C1(); return c; }   // should be error, because pc.c3.c1 == C1\nimmutable(C3) recursive3(C1 pc) pure { auto c = new C3(); return c; }   // should be error, c.c1 may be pc\nimmutable(C3) recursive4(C2 pc) pure { auto c = new C3(); return c; }   // should be error, c.c1.c2 may be pc\nimmutable(C1) recursive5(shared C2 pc) pure { auto c = new C1(); return c; }\nimmutable(C1) recursive6(immutable C2 pc) pure { auto c = new C1(); return c; }\nimmutable(C1) recursiveE(immutable C2 pc) pure { auto c = new X1(); return c; }\n\nclass C4 { C4[] arr; }\nimmutable(C4)[] recursive7(int[] arr) pure { auto a = new C4[](1); return a; }\n\nstruct S1 { int* ptr; }\nimmutable(S1)     foo1a(          int*[] prm) pure {                S1 s; return s; }   // NG\nimmutable(S1)     foo1b(    const int*[] prm) pure {                S1 s; return s; }   // OK\nimmutable(S1)     foo1c(immutable int*[] prm) pure {                S1 s; return s; }   // OK\nimmutable(int*[]) bar1a(              S1 prm) pure {           int *[] a; return a; }   // NG\nimmutable(int*[]) bar1b(              S1 prm) pure {     const(int)*[] a; return a; }   // NG\nimmutable(int*[]) bar1c(              S1 prm) pure { immutable(int)*[] a; return a; }   // OK\n\nstruct S2 { const(int)* ptr; }\nimmutable(S2)     foo2a(          int*[] prm) pure {                S2 s; return s; }   // OK\nimmutable(S2)     foo2b(    const int*[] prm) pure {                S2 s; return s; }   // NG\nimmutable(S2)     foo2c(immutable int*[] prm) pure {                S2 s; return s; }   // NG\nimmutable(int*[]) bar2a(              S2 prm) pure {           int *[] a; return a; }   // OK\nimmutable(int*[]) bar2b(              S2 prm) pure {     const(int)*[] a; return a; }   // NG\nimmutable(int*[]) bar2c(              S2 prm) pure { immutable(int)*[] a; return a; }   // OK\n\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/testInference.d(134): Error: cannot implicitly convert expression `f10063(cast(inout(void*))p)` of type `inout(void)*` to `immutable(void)*`\n---\n*/\ninout(void)* f10063(inout void* p) pure\n{\n    return p;\n}\nimmutable(void)* g10063(inout int* p) pure\n{\n    return f10063(p);\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/testInference.d(154): Error: `pure` function `testInference.bar14049` cannot call impure function `testInference.foo14049!int.foo14049`\n---\n*/\nauto impure14049() { static int i = 1; return i; }\n\nvoid foo14049(T)(T val)\n{\n    auto n = () @trusted {\n        return impure14049();\n    }();\n}\n\nvoid bar14049() pure\n{\n    foo14049(1);\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/testInference.d(166): Error: `pure` function `testInference.f14160` cannot access mutable static data `g14160`\n---\n*/\nint g14160;\nint* f14160() pure\n{\n    return &g14160; // should be rejected\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/testInference.d(180): Error: `pure` function `testInference.test12422` cannot call impure function `testInference.test12422.bar12422!().bar12422`\n---\n*/\nint g12422;\nvoid foo12422() { ++g12422; }\nvoid test12422() pure\n{\n    void bar12422()() { foo12422(); }\n    bar12422();\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/testInference.d(196): Error: `pure` function `testInference.test13729a` cannot access mutable static data `g13729`\nfail_compilation/testInference.d(206): Error: `pure` function `testInference.test13729b` cannot call impure function `testInference.test13729b.foo!().foo`\n---\n*/\nint g13729;\n\nvoid test13729a() pure\n{\n    static void foo()   // typed as impure\n    {\n        g13729++;       // disallowed\n    }\n    foo();\n}\nvoid test13729b() pure\n{\n    static void foo()() // inferred to impure\n    {\n        g13729++;\n    }\n    foo();              // cannot call impure function\n}\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/testInference.d(225): Error: `testInference.test17086` called with argument types `(bool)` matches both:\nfail_compilation/testInference.d(219):     `testInference.test17086!(bool, false).test17086(bool x)`\nand:\nfail_compilation/testInference.d(220):     `testInference.test17086!(bool, false).test17086(bool y)`\n---\n*/\n\nvoid test17086 (T, T V = T.init) (T x) { assert(x.foo); }\nvoid test17086 (T, T V = T.init) (T y) { assert(y.bar); }\n\nvoid test17086_call ()\n{\n    bool f;\n    test17086(f);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/testpull1810.d",
    "content": "// REQUIRED_ARGS: -c -w\n/*\nTEST_OUTPUT:\n---\nfail_compilation/testpull1810.d(19): Warning: statement is not reachable\n---\n*/\n\nuint foo(uint i)\n{\n    try\n    {\n        ++i;\n        return 3;\n    }\n    catch (Exception e)\n    {\n    }\n    return 4;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/testscopestatic.d",
    "content": "\n/* TEST_OUTPUT:\n---\nfail_compilation/testscopestatic.d(15): Error: variable `testscopestatic.foo.p` cannot be `scope` and `static`\nfail_compilation/testscopestatic.d(16): Error: variable `testscopestatic.foo.b` cannot be `scope` and `extern`\nfail_compilation/testscopestatic.d(17): Error: variable `testscopestatic.foo.c` cannot be `scope` and `__gshared`\nfail_compilation/testscopestatic.d(21): Error: variable `testscopestatic.foo.S.x` field cannot be `scope`\n---\n*/\n\n\nvoid foo()\n{\n    scope int a;\n    static scope int* p;\n    extern scope int b;\n    scope __gshared int c;\n\n    struct S\n    {\n        scope int x;\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/traits.d",
    "content": "/*\nREQUIRED_ARGS:\nPERMUTE_ARGS:\n*/\n\n/************************************************************/\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/traits.d(100): Error: `getTargetInfo` key `\"not_a_target_info\"` not supported by this implementation\nfail_compilation/traits.d(101): Error: string expected as argument of __traits `getTargetInfo` instead of `100`\nfail_compilation/traits.d(102): Error: expected 1 arguments for `getTargetInfo` but had 2\nfail_compilation/traits.d(103): Error: expected 1 arguments for `getTargetInfo` but had 0\n---\n*/\n\n#line 100\nenum A = __traits(getTargetInfo, \"not_a_target_info\");\nenum B = __traits(getTargetInfo, 100);\nenum C = __traits(getTargetInfo, \"cppRuntimeLibrary\", \"bits\");\nenum D = __traits(getTargetInfo);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/typeerrors.d",
    "content": "/*\nPERMUTE_ARGS:\nTEST_OUTPUT:\n---\nfail_compilation/typeerrors.d(36): Error: tuple index 4 exceeds 4\nfail_compilation/typeerrors.d(38): Error: variable `x` cannot be read at compile time\nfail_compilation/typeerrors.d(39): Error: cannot have array of `void()`\nfail_compilation/typeerrors.d(40): Error: cannot have array of scope `typeerrors.C`\nfail_compilation/typeerrors.d(41): Error: cannot have array of scope `typeerrors.C`\nfail_compilation/typeerrors.d(44): Error: `int[5]` is not an expression\nfail_compilation/typeerrors.d(46): Error: `x` is used as a type\nfail_compilation/typeerrors.d(47): Error: cannot have associative array key of `void()`\nfail_compilation/typeerrors.d(48): Error: cannot have associative array key of `void`\nfail_compilation/typeerrors.d(49): Error: cannot have array of scope `typeerrors.C`\nfail_compilation/typeerrors.d(50): Error: cannot have associative array of `void`\nfail_compilation/typeerrors.d(51): Error: cannot have associative array of `void()`\nfail_compilation/typeerrors.d(53): Error: cannot have parameter of type `void`\nfail_compilation/typeerrors.d(55): Error: slice `[1..5]` is out of range of [0..4]\nfail_compilation/typeerrors.d(56): Error: slice `[2..1]` is out of range of [0..4]\n---\n*/\n\n\n\n\n\ntemplate tuple(T...) { alias T tuple; }\n\nvoid bar();\n\nscope class C { }\n\nvoid foo()\n{\n    alias T = tuple!(1,2,int,7);\n    T[4] a;\n    int x;\n    T[x] b;\n    typeof(bar)[5] c;\n    C[6] d;\n    C[] e;\n\n    alias int[5] AI;\n    auto f = AI.ptr;\n\n    int[x*] g;\n    int[typeof(bar)] h;\n    int[void] i;\n    C[int] j;\n    void[int] k;\n    typeof(bar)[int] l;\n\n    void abc(void) { }\n\n    alias T2 = T[1 .. 5];\n    alias T3 = T[2 .. 1];\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/udaparams.d",
    "content": "/*\nTEST_OUTPUT:\n---\nfail_compilation/udaparams.d(31): Error: variadic parameter cannot have user-defined attributes\nfail_compilation/udaparams.d(32): Error: variadic parameter cannot have user-defined attributes\nfail_compilation/udaparams.d(34): Error: user-defined attributes cannot appear as postfixes\nfail_compilation/udaparams.d(35): Error: user-defined attributes cannot appear as postfixes\nfail_compilation/udaparams.d(36): Error: user-defined attributes cannot appear as postfixes\nfail_compilation/udaparams.d(38): Error: `@safe` attribute for function parameter is not supported\nfail_compilation/udaparams.d(39): Error: `@safe` attribute for function parameter is not supported\nfail_compilation/udaparams.d(40): Error: `@safe` attribute for function parameter is not supported\nfail_compilation/udaparams.d(43): Error: `@system` attribute for function parameter is not supported\nfail_compilation/udaparams.d(44): Error: `@trusted` attribute for function parameter is not supported\nfail_compilation/udaparams.d(45): Error: `@nogc` attribute for function parameter is not supported\nfail_compilation/udaparams.d(51): Error: Cannot put a storage-class in an alias declaration.\nfail_compilation/udaparams.d(52): Error: Cannot put a storage-class in an alias declaration.\nfail_compilation/udaparams.d(53): Error: semicolon expected to close `alias` declaration\nfail_compilation/udaparams.d(53): Error: declaration expected, not `=>`\nfail_compilation/udaparams.d(54): Error: semicolon expected to close `alias` declaration\nfail_compilation/udaparams.d(54): Error: declaration expected, not `=>`\nfail_compilation/udaparams.d(57): Error: basic type expected, not `@`\nfail_compilation/udaparams.d(57): Error: identifier expected for template value parameter\nfail_compilation/udaparams.d(57): Error: found `@` when expecting `)`\nfail_compilation/udaparams.d(57): Error: basic type expected, not `3`\nfail_compilation/udaparams.d(57): Error: found `3` when expecting `)`\nfail_compilation/udaparams.d(57): Error: semicolon expected following function declaration\nfail_compilation/udaparams.d(57): Error: declaration expected, not `)`\n---\n*/\n\nvoid vararg1(int a, @(10) ...);\nextern(C) void vararg2(int a, @(10) ...);\n\nvoid rhsuda(int a @(10));\nvoid rhsuda2(int @(10));\nvoid rhsuda3(int[] arr @(10) ...);\n\nvoid wrongAttr1(@safe int);\nvoid wrongAttr2(@safe void function());\nvoid wrongAttr3(@safe void delegate());\n\n\nvoid test16(A)(A a @system);\nvoid test16(A)(A a @trusted);\nvoid test16(A)(A a @nogc);\n\n// lambdas without parentheses\nalias test19a = @safe b => 1 + 2;\nalias test19b = @system b => 1 + 2;\nalias test19c = @nogc b => 1 + 2;\nalias test19d = @(2) @system b => 1 + 2;\nalias test19e = @safe @(2) b => 1 + 2;\nalias test19f = extern(C++) b => 1 + 2;\nalias test19g = align(2) b => 1 + 2;\n\n// UDAs on Template parameter aren't supported\nvoid test21(@(3) T)(T t) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/verrors0.d",
    "content": "// REQUIRED_ARGS: -verrors=0\n\nvoid main()\n{\n    { T a; }    // 1\n    { T a; }    // 2\n    { T a; }    // 3\n    { T a; }    // 4\n    { T a; }    // 5\n    { T a; }    // 6\n    { T a; }    // 7\n    { T a; }    // 8\n    { T a; }    // 9\n    { T a; }    // 10\n    { T a; }    // 11\n    { T a; }    // 12\n    { T a; }    // 13\n    { T a; }    // 14\n    { T a; }    // 15\n    { T a; }    // 16\n    { T a; }    // 17\n    { T a; }    // 18\n    { T a; }    // 19\n    { T a; }    // 20 (default limit)\n    { T a; }    // 21\n    { T a; }    // 22\n    { T a; }    // 23\n    { T a; }    // 24\n    { T a; }    // 25\n}\n/*\nTEST_OUTPUT:\n---\nfail_compilation/verrors0.d(5): Error: undefined identifier `T`\nfail_compilation/verrors0.d(6): Error: undefined identifier `T`\nfail_compilation/verrors0.d(7): Error: undefined identifier `T`\nfail_compilation/verrors0.d(8): Error: undefined identifier `T`\nfail_compilation/verrors0.d(9): Error: undefined identifier `T`\nfail_compilation/verrors0.d(10): Error: undefined identifier `T`\nfail_compilation/verrors0.d(11): Error: undefined identifier `T`\nfail_compilation/verrors0.d(12): Error: undefined identifier `T`\nfail_compilation/verrors0.d(13): Error: undefined identifier `T`\nfail_compilation/verrors0.d(14): Error: undefined identifier `T`\nfail_compilation/verrors0.d(15): Error: undefined identifier `T`\nfail_compilation/verrors0.d(16): Error: undefined identifier `T`\nfail_compilation/verrors0.d(17): Error: undefined identifier `T`\nfail_compilation/verrors0.d(18): Error: undefined identifier `T`\nfail_compilation/verrors0.d(19): Error: undefined identifier `T`\nfail_compilation/verrors0.d(20): Error: undefined identifier `T`\nfail_compilation/verrors0.d(21): Error: undefined identifier `T`\nfail_compilation/verrors0.d(22): Error: undefined identifier `T`\nfail_compilation/verrors0.d(23): Error: undefined identifier `T`\nfail_compilation/verrors0.d(24): Error: undefined identifier `T`\nfail_compilation/verrors0.d(25): Error: undefined identifier `T`\nfail_compilation/verrors0.d(26): Error: undefined identifier `T`\nfail_compilation/verrors0.d(27): Error: undefined identifier `T`\nfail_compilation/verrors0.d(28): Error: undefined identifier `T`\nfail_compilation/verrors0.d(29): Error: undefined identifier `T`\n---\n*/\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/verrors5.d",
    "content": "// REQUIRED_ARGS: -verrors=5\n\nvoid main()\n{\n    { T a; }    // 1\n    { T a; }    // 2\n    { T a; }    // 3\n    { T a; }    // 4\n    { T a; }    // 5\n    { T a; }    // 6\n    { T a; }    // 7\n    { T a; }    // 8\n    { T a; }    // 9\n    { T a; }    // 10\n    { T a; }    // 11\n    { T a; }    // 12\n    { T a; }    // 13\n    { T a; }    // 14\n    { T a; }    // 15\n    { T a; }    // 16\n    { T a; }    // 17\n    { T a; }    // 18\n    { T a; }    // 19\n    { T a; }    // 20 (default limit)\n    { T a; }    // 21\n    { T a; }    // 22\n    { T a; }    // 23\n    { T a; }    // 24\n    { T a; }    // 25\n}\n/*\nTEST_OUTPUT:\n---\nfail_compilation/verrors5.d(5): Error: undefined identifier `T`\nfail_compilation/verrors5.d(6): Error: undefined identifier `T`\nfail_compilation/verrors5.d(7): Error: undefined identifier `T`\nfail_compilation/verrors5.d(8): Error: undefined identifier `T`\nfail_compilation/verrors5.d(9): Error: undefined identifier `T`\n---\n*/\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/warn12809.d",
    "content": "// REQUIRED_ARGS: -o- -w\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/warn12809.d(25): Warning: statement is not reachable\nfail_compilation/warn12809.d(33): Warning: statement is not reachable\n---\n*/\n\n//void test_unrachable1()\n//{\n//    try assert(0);\n//    finally\n//    {\n//        int x = 1;  // unreachable\n//    }\n//}\n\nvoid test_unrachable2()\n{\n    try assert(0);\n    finally {}\n\n    int x = 1;      // unreachable\n}\n\nvoid test_unrachable3()\n{\n    try {}\n    finally assert(0);\n\n    int x = 1;      // unreachable\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/warn13679.d",
    "content": "// REQUIRED_ARGS: -w\n// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/warn13679.d(14): Warning: cannot use `foreach_reverse` with an associative array\n---\n*/\n\nvoid main()\n{\n    int[int] aa;\n    foreach_reverse(k, v; aa) {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/warn7444.d",
    "content": "// REQUIRED_ARGS: -w\n// PERMUTE_ARGS:\n\n/*\nTEST_OUTPUT:\n---\nfail_compilation/warn7444.d(23): Error: cannot implicitly convert expression `e` of type `int` to `int[]`\n---\n*/\n\nvoid test7444()\n{\n    int[2] sa;\n    int[]  da;\n    int    e;\n\n    {\n        // X: Changed accepts-invalid to rejects-invalid by this issue\n        // a: slice assignment\n        // b: element-wise assignment\n        sa   = e;      // X\n        sa[] = e;      // b\n        da   = e;\n        da[] = e;      // b\n\n        // lhs is static array\n        sa   = sa;     // b == identity assign\n        sa   = sa[];   // X\n        sa[] = sa;     // X\n        sa[] = sa[];   // b\n\n        sa   = da;     // X\n        sa   = da[];   // X\n        sa[] = da;     // X\n        sa[] = da[];   // b\n\n        // lhs is dynamic array\n        da   = sa;     // X\n        da   = sa[];   // a\n        da[] = sa;     // X\n        da[] = sa[];   // b\n\n        da   = da;     // a == identity assign\n        da   = da[];   // a\n        da[] = da;     // X\n        da[] = da[];   // b\n    }\n}\n\n/*\nTEST_OUTPUT:\n---\nNo warning\n---\n*/\n\nvoid test10214()\n{\n    bool[1] arr;\n    arr = 0;\n    pragma(msg, \"No warning\");\n}\n\n/*\nTEST_OUTPUT:\n---\nNo warning\n---\n*/\n\nstruct S11228\n{\n    int[2] ii;\n    alias ii this;\n}\nvoid test11228()\n{\n    S11228 s;\n    int[2] ii;\n    ii = s.ii; // OK\n    ii = s;    // OK <- Warning\n    pragma(msg, \"No warning\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/fail_compilation/widechars.d",
    "content": "\n/*\nDISABLED: win32 win64\nTEST_OUTPUT:\n---\nfail_compilation/widechars.d(10): Error: undefined identifier `wchar_t`, did you mean `dchar`?\n---\n*/\n\nwchar_t x;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/A16.d",
    "content": "// EXTRA_SOURCES: imports/A16a.d\n\nimport std.stdio;\n\nclass AA16\n{\n  protected:\n    this()\n    {\n        printf(\"class AA16\\n\");\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/Same.d",
    "content": "// EXTRA_SOURCES: imports/Other.d\n// PERMUTE_ARGS:\n\nmodule Same; // makes no difference if removed\nimport core.stdc.stdio;\nclass Same\n{\nthis()\n{\nprintf(\"Same\\n\");\n}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/a17.d",
    "content": "// EXTRA_SOURCES: imports/a17a.d\n\nmodule a17;\n\nimport std.stdio;\n\nprivate import imports.a17a;\n\nclass barx {\n    this() { printf(\"barx\\n\"); }\n}\n\n\nint main()\n{\n    foo2x f = new foo2x();\n//    f = new foo2x();\n//    f.x++;\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/a18.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/a18a.d\n// PERMUTE_ARGS:\n\nimport imports.a18a;\n\nextern(C) int printf(const char*, ...);\n\nalias   IContainer!(int) icontainer_t;\n\nint main()\n{\n        printf(\"Test enumerator\\n\");\n\n        return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/a19.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/a19a.d\n// PERMUTE_ARGS:\n\nimport imports.a19a;\n\nint main(char[][] args)\n{\n        TemplatedStruct!(Dummy) e;\n\n        return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/a21.d",
    "content": "// EXTRA_SOURCES: imports/a21a.d\n// PERMUTE_ARGS:\n\nimport std.stdio;\nimport imports.a21a;\n\n\ntemplate BadMixin()\n{\n    int badFunc()\n    {\n        printf(\"badFunc\\n\");\n        return 2;\n    }\n}\n\n\nint main()\n{\n    int i;\n    auto x = new SomeClass;\n    i = x.goodFunc();\n    assert(i == 1);\n    i = x.badFunc();\n    assert(i == 2);\n\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/aliasthis.d",
    "content": "\nextern (C) int printf(const(char*) fmt, ...);\nimport core.vararg;\n\nstruct Tup(T...)\n{\n    T field;\n    alias field this;\n\n    bool opEquals(const Tup rhs) const\n    {\n        foreach (i, _; T)\n            if (field[i] != rhs.field[i])\n                return false;\n        return true;\n    }\n}\n\nTup!T tup(T...)(T fields)\n{\n    return typeof(return)(fields);\n}\n\ntemplate Seq(T...)\n{\n    alias T Seq;\n}\n\n/**********************************************/\n\nstruct S\n{\n    int x;\n    alias x this;\n}\n\nint foo(int i)\n{\n    return i * 2;\n}\n\nvoid test1()\n{\n    S s;\n    s.x = 7;\n    int i = -s;\n    assert(i == -7);\n\n    i = s + 8;\n    assert(i == 15);\n\n    i = s + s;\n    assert(i == 14);\n\n    i = 9 + s;\n    assert(i == 16);\n\n    i = foo(s);\n    assert(i == 14);\n}\n\n/**********************************************/\n\nclass C\n{\n    int x;\n    alias x this;\n}\n\nvoid test2()\n{\n    C s = new C();\n    s.x = 7;\n    int i = -s;\n    assert(i == -7);\n\n    i = s + 8;\n    assert(i == 15);\n\n    i = s + s;\n    assert(i == 14);\n\n    i = 9 + s;\n    assert(i == 16);\n\n    i = foo(s);\n    assert(i == 14);\n}\n\n/**********************************************/\n\nvoid test3()\n{\n    Tup!(int, double) t;\n    t[0] = 1;\n    t[1] = 1.1;\n    assert(t[0] == 1);\n    assert(t[1] == 1.1);\n    printf(\"%d %g\\n\", t[0], t[1]);\n}\n\n/**********************************************/\n\nstruct Iter\n{\n    bool empty() { return true; }\n    void popFront() { }\n    ref Tup!(int, int) front() { return *new Tup!(int, int); }\n    ref Iter opSlice() { return this; }\n}\n\nvoid test4()\n{\n    foreach (a; Iter()) { }\n}\n\n/**********************************************/\n\nvoid test5()\n{\n    static struct Double1 {\n        double val = 1;\n        alias val this;\n    }\n    static Double1 x() { return Double1(); }\n    x()++;\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4617\n\nstruct S4617\n{\n    struct F\n    {\n        int  square(int  n) { return n*n; }\n        real square(real n) { return n*n; }\n    }\n    F forward;\n\n    alias forward this;\n\n    alias forward.square sqr;    // okay\n\n    int field;\n    void mfunc();\n    template Templ(){}\n    void tfunc()(){}\n}\n\ntemplate Id4617(alias k) { alias k Id4617; }\n\nvoid test4617a()\n{\n    alias Id4617!(S4617.square) test1;            //NG\n    alias Id4617!(S4617.forward.square) test2;    //OK\n\n    alias Id4617!(S4617.sqr) test3;               //okay\n\n    static assert(__traits(isSame, S4617.square, S4617.forward.square));\n}\n\nvoid test4617b()\n{\n    static struct Sub(T)\n    {\n        T value;\n        @property ref inout(T) payload() inout { return value; }\n        alias payload this;\n    }\n\n    alias Id4617!(S4617.field) S_field;\n    alias Id4617!(S4617.mfunc) S_mfunc;\n    alias Id4617!(S4617.Templ) S_Templ;\n    alias Id4617!(S4617.tfunc) S_tfunc;\n\n    alias Sub!S4617 T4617;\n    alias Id4617!(T4617.field) R_field;\n    alias Id4617!(T4617.mfunc) R_mfunc;\n    alias Id4617!(T4617.Templ) R_Templ;\n    alias Id4617!(T4617.tfunc) R_tfunc;\n    static assert(__traits(isSame, R_field, S_field));\n    static assert(__traits(isSame, R_mfunc, S_mfunc));\n    static assert(__traits(isSame, R_Templ, S_Templ));\n    static assert(__traits(isSame, R_tfunc, S_tfunc));\n\n    alias Id4617!(T4617.square) R_sqr;\n    static assert(__traits(isSame, R_sqr, S4617.forward.square));\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4773\n\nvoid test4773()\n{\n    struct Rebindable\n    {\n        Object obj;\n        @property const(Object) get(){ return obj; }\n        alias get this;\n    }\n\n    Rebindable r;\n    if (r) assert(0);\n    r.obj = new Object;\n    if (!r) assert(0);\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5188\n\nvoid test5188()\n{\n    struct S\n    {\n        int v = 10;\n        alias v this;\n    }\n\n    S s;\n    assert(s <= 20);\n    assert(s != 14);\n}\n\n/***********************************************/\n\nstruct Foo {\n  void opIndexAssign(int x, size_t i) {\n    val = x;\n  }\n  void opSliceAssign(int x, size_t a, size_t b) {\n    val = x;\n  }\n  int val;\n}\n\nstruct Bar {\n   Foo foo;\n   alias foo this;\n}\n\nvoid test6() {\n   Bar b;\n   b[0] = 1;\n   assert(b.val == 1);\n   b[0 .. 1] = 2;\n   assert(b.val == 2);\n}\n\n/**********************************************/\n// recursive alias this detection\n\nclass C0 {}\n\nclass C1 { C2 c; alias c this; }\nclass C2 { C1 c; alias c this; }\n\nclass C3 { C2 c; alias c this; }\n\nstruct S0 {}\n\nstruct S1 { S2* ps; @property ref get(){return *ps;} alias get this; }\nstruct S2 { S1* ps; @property ref get(){return *ps;} alias get this; }\n\nstruct S3 { S2* ps; @property ref get(){return *ps;} alias get this; }\n\nstruct S4 { S5* ps; @property ref get(){return *ps;} alias get this; }\nstruct S5 { S4* ps; @property ref get(){return *ps;} alias get this; }\n\nstruct S6 { S5* ps; @property ref get(){return *ps;} alias get this; }\n\nvoid test7()\n{\n    // Able to check a type is implicitly convertible within a finite time.\n    static assert(!is(C1 : C0));\n    static assert( is(C2 : C1));\n    static assert( is(C1 : C2));\n    static assert(!is(C3 : C0));\n    static assert( is(C3 : C1));\n    static assert( is(C3 : C2));\n\n    static assert(!is(S1 : S0));\n    static assert( is(S2 : S1));\n    static assert( is(S1 : S2));\n    static assert(!is(S3 : S0));\n    static assert( is(S3 : S1));\n    static assert( is(S3 : S2));\n\n    C0 c0;  C1 c1;  C3 c3;\n    S0 s0;  S1 s1;  S3 s3;  S4 s4;  S6 s6;\n\n    // Allow merging types that contains alias this recursion.\n    static assert( __traits(compiles, c0 is c1));   // typeMerge(c || c) e2->implicitConvTo(t1);\n    static assert( __traits(compiles, c0 is c3));   // typeMerge(c || c) e2->implicitConvTo(t1);\n    static assert( __traits(compiles, c1 is c0));   // typeMerge(c || c) e1->implicitConvTo(t2);\n    static assert( __traits(compiles, c3 is c0));   // typeMerge(c || c) e1->implicitConvTo(t2);\n    static assert(!__traits(compiles, s1 is c0));   // typeMerge(c || c) e1\n    static assert(!__traits(compiles, s3 is c0));   // typeMerge(c || c) e1\n    static assert(!__traits(compiles, c0 is s1));   // typeMerge(c || c) e2\n    static assert(!__traits(compiles, c0 is s3));   // typeMerge(c || c) e2\n\n    static assert(!__traits(compiles, s1 is s0));   // typeMerge(s && s) e1\n    static assert(!__traits(compiles, s3 is s0));   // typeMerge(s && s) e1\n    static assert(!__traits(compiles, s0 is s1));   // typeMerge(s && s) e2\n    static assert(!__traits(compiles, s0 is s3));   // typeMerge(s && s) e2\n    static assert(!__traits(compiles, s1 is s4));   // typeMerge(s && s) e1 + e2\n    static assert(!__traits(compiles, s3 is s6));   // typeMerge(s && s) e1 + e2\n\n    static assert(!__traits(compiles, s1 is 10));   // typeMerge(s || s) e1\n    static assert(!__traits(compiles, s3 is 10));   // typeMerge(s || s) e1\n    static assert(!__traits(compiles, 10 is s1));   // typeMerge(s || s) e2\n    static assert(!__traits(compiles, 10 is s3));   // typeMerge(s || s) e2\n\n    // SliceExp::semantic\n    static assert(!__traits(compiles, c1[]));\n    static assert(!__traits(compiles, c3[]));\n    static assert(!__traits(compiles, s1[]));\n    static assert(!__traits(compiles, s3[]));\n\n    // CallExp::semantic\n//  static assert(!__traits(compiles, c1()));\n//  static assert(!__traits(compiles, c3()));\n    static assert(!__traits(compiles, s1()));\n    static assert(!__traits(compiles, s3()));\n\n    // AssignExp::semantic\n    static assert(!__traits(compiles, { c1[1] = 0; }));\n    static assert(!__traits(compiles, { c3[1] = 0; }));\n    static assert(!__traits(compiles, { s1[1] = 0; }));\n    static assert(!__traits(compiles, { s3[1] = 0; }));\n    static assert(!__traits(compiles, { c1[ ] = 0; }));\n    static assert(!__traits(compiles, { c3[ ] = 0; }));\n    static assert(!__traits(compiles, { s1[ ] = 0; }));\n    static assert(!__traits(compiles, { s3[ ] = 0; }));\n\n    // UnaExp::op_overload\n    static assert(!__traits(compiles, +c1[1]));\n    static assert(!__traits(compiles, +c3[1]));\n    static assert(!__traits(compiles, +s1[1]));\n    static assert(!__traits(compiles, +s3[1]));\n    static assert(!__traits(compiles, +c1[ ]));\n    static assert(!__traits(compiles, +c3[ ]));\n    static assert(!__traits(compiles, +s1[ ]));\n    static assert(!__traits(compiles, +s3[ ]));\n    static assert(!__traits(compiles, +c1));\n    static assert(!__traits(compiles, +c3));\n    static assert(!__traits(compiles, +s1));\n    static assert(!__traits(compiles, +s3));\n\n    // ArrayExp::op_overload\n    static assert(!__traits(compiles, c1[1]));\n    static assert(!__traits(compiles, c3[1]));\n    static assert(!__traits(compiles, s1[1]));\n    static assert(!__traits(compiles, s3[1]));\n\n    // BinExp::op_overload\n    static assert(!__traits(compiles, c1 + 10));    // e1\n    static assert(!__traits(compiles, c3 + 10));    // e1\n    static assert(!__traits(compiles, 10 + c1));    // e2\n    static assert(!__traits(compiles, 10 + c3));    // e2\n    static assert(!__traits(compiles, s1 + 10));    // e1\n    static assert(!__traits(compiles, s3 + 10));    // e1\n    static assert(!__traits(compiles, 10 + s1));    // e2\n    static assert(!__traits(compiles, 10 + s3));    // e2\n\n    // BinExp::compare_overload\n    static assert(!__traits(compiles, c1 < 10));    // (Object.opCmp(int) is invalid)\n    static assert(!__traits(compiles, c3 < 10));    // (Object.opCmp(int) is invalid)\n    static assert(!__traits(compiles, 10 < c1));    // (Object.opCmp(int) is invalid)\n    static assert(!__traits(compiles, 10 < c3));    // (Object.opCmp(int) is invalid)\n    static assert(!__traits(compiles, s1 < 10));    // e1\n    static assert(!__traits(compiles, s3 < 10));    // e1\n    static assert(!__traits(compiles, 10 < s1));    // e2\n    static assert(!__traits(compiles, 10 < s3));    // e2\n\n    // BinAssignExp::op_overload\n    static assert(!__traits(compiles, c1[1] += 1));\n    static assert(!__traits(compiles, c3[1] += 1));\n    static assert(!__traits(compiles, s1[1] += 1));\n    static assert(!__traits(compiles, s3[1] += 1));\n    static assert(!__traits(compiles, c1[ ] += 1));\n    static assert(!__traits(compiles, c3[ ] += 1));\n    static assert(!__traits(compiles, s1[ ] += 1));\n    static assert(!__traits(compiles, s3[ ] += 1));\n    static assert(!__traits(compiles, c1 += c0));   // e1\n    static assert(!__traits(compiles, c3 += c0));   // e1\n    static assert(!__traits(compiles, s1 += s0));   // e1\n    static assert(!__traits(compiles, s3 += s0));   // e1\n    static assert(!__traits(compiles, c0 += c1));   // e2\n    static assert(!__traits(compiles, c0 += c3));   // e2\n    static assert(!__traits(compiles, s0 += s1));   // e2\n    static assert(!__traits(compiles, s0 += s3));   // e2\n    static assert(!__traits(compiles, c1 += s1));   // e1 + e2\n    static assert(!__traits(compiles, c3 += s3));   // e1 + e2\n\n    // ForeachStatement::inferAggregate\n    static assert(!__traits(compiles, { foreach (e; s1){} }));\n    static assert(!__traits(compiles, { foreach (e; s3){} }));\n    static assert(!__traits(compiles, { foreach (e; c1){} }));\n    static assert(!__traits(compiles, { foreach (e; c3){} }));\n\n    // Expression::checkToBoolean\n    static assert(!__traits(compiles, { if (s1){} }));\n    static assert(!__traits(compiles, { if (s3){} }));\n\n    // SwitchStatement::semantic\n    static assert(!__traits(compiles, { switch (c0) { default: } }));\n    static assert(!__traits(compiles, { switch (c1) { default: } }));\n    static assert(!__traits(compiles, { switch (c3) { default: } }));\n\n    // https://issues.dlang.org/show_bug.cgi?id=12537: function arguments with IFTI\n    void eq12537()(Object lhs) {}\n    const C0 cc0;\n    const C1 cc1;\n    const C3 cc3;\n    static assert(!__traits(compiles, eq12537(cc0)));\n    static assert(!__traits(compiles, eq12537(cc1)));\n    static assert(!__traits(compiles, eq12537(cc3)));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11875\n// endless recursion in Type::deduceType\n\nstruct T11875x(C)\n{\n    C c;\n}\nclass D11875a { D11875b c; alias c this; }\nclass D11875b { D11875a c; alias c this; }\nstatic assert(!is(D11875a == D11875b));\nstatic assert( is(T11875x!D11875a == T11875x!D, D) && is(D == D11875a));\nstatic assert(!is(D11875a == T11875x!D, D));    // this used to freeze dmd\n\n// test that types in recursion are still detected\nstruct T11875y(C)\n{\n    C c;\n    alias c this;\n}\nclass D11875c { T11875y!D11875b c; alias c this; }\nstatic assert(is(D11875c : T11875y!D, D) && is(D == D11875b));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11930\n\nclass BarObj11930 {}\n\nstruct Bar11930\n{\n    BarObj11930 _obj;\n    alias _obj this;\n}\n\nBarObj11930 getBarObj11930(T)(T t)\n{\n    static if (is(T unused : BarObj11930))\n        return t;\n    else\n        static assert(false, \"Can not get BarObj from \" ~ T.stringof);\n}\n\nvoid test11930()\n{\n    Bar11930 b;\n    getBarObj11930(b);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2781\n\nstruct Tuple2781a(T...) {\n    T data;\n    alias data this;\n}\n\nstruct Tuple2781b(T) {\n    T data;\n    alias data this;\n}\n\nvoid test2781()\n{\n    Tuple2781a!(uint, float) foo;\n    foreach(elem; foo) {}\n\n    {\n        Tuple2781b!(int[]) bar1;\n        foreach(elem; bar1) {}\n\n        Tuple2781b!(int[int]) bar2;\n        foreach(key, elem; bar2) {}\n\n        Tuple2781b!(string) bar3;\n        foreach(dchar elem; bar3) {}\n    }\n\n    {\n        Tuple2781b!(int[]) bar1;\n        foreach(elem; bar1) goto L1;\n    L1:\n        ;\n\n        Tuple2781b!(int[int]) bar2;\n        foreach(key, elem; bar2) goto L2;\n    L2:\n        ;\n\n        Tuple2781b!(string) bar3;\n        foreach(dchar elem; bar3) goto L3;\n    L3:\n        ;\n    }\n\n\n    int eval;\n\n    auto t1 = tup(10, \"str\");\n    auto i1 = 0;\n    foreach (e; t1)\n    {\n        pragma(msg, \"[] = \", typeof(e));\n        static if (is(typeof(e) == int   )) assert(i1 == 0 && e == 10);\n        static if (is(typeof(e) == string)) assert(i1 == 1 && e == \"str\");\n        ++i1;\n    }\n\n    auto t2 = tup(10, \"str\");\n    foreach (i2, e; t2)\n    {\n        pragma(msg, \"[\", cast(int)i2, \"] = \", typeof(e));\n        static if (is(typeof(e) == int   )) { static assert(i2 == 0); assert(e == 10); }\n        static if (is(typeof(e) == string)) { static assert(i2 == 1); assert(e == \"str\"); }\n    }\n\n    auto t3 = tup(10, \"str\");\n    auto i3 = 2;\n    foreach_reverse (e; t3)\n    {\n        --i3;\n        pragma(msg, \"[] = \", typeof(e));\n        static if (is(typeof(e) == int   )) assert(i3 == 0 && e == 10);\n        static if (is(typeof(e) == string)) assert(i3 == 1 && e == \"str\");\n    }\n\n    auto t4 = tup(10, \"str\");\n    foreach_reverse (i4, e; t4)\n    {\n        pragma(msg, \"[\", cast(int)i4, \"] = \", typeof(e));\n        static if (is(typeof(e) == int   )) { static assert(i4 == 0); assert(e == 10); }\n        static if (is(typeof(e) == string)) { static assert(i4 == 1); assert(e == \"str\"); }\n    }\n\n    eval = 0;\n    foreach (i, e; tup(tup((){eval++; return 10;}(), 3.14), tup(\"str\", [1,2])))\n    {\n        static if (i == 0) assert(e == tup(10, 3.14));\n        static if (i == 1) assert(e == tup(\"str\", [1,2]));\n    }\n    assert(eval == 1);\n\n    eval = 0;\n    foreach (i, e; tup((){eval++; return 10;}(), tup(3.14, tup(\"str\", tup([1,2])))))\n    {\n        static if (i == 0) assert(e == 10);\n        static if (i == 1) assert(e == tup(3.14, tup(\"str\", tup([1,2]))));\n    }\n    assert(eval == 1);\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6546\n\nvoid test6546()\n{\n    class C {}\n    class D : C {}\n\n    struct S { C c; alias c this; } // S : C\n    struct T { S s; alias s this; } // T : S\n    struct U { T t; alias t this; } // U : T\n\n    C c;\n    D d;\n    S s;\n    T t;\n    U u;\n\n    assert(c is c);  // OK\n    assert(c is d);  // OK\n    assert(c is s);  // OK\n    assert(c is t);  // OK\n    assert(c is u);  // OK\n\n    assert(d is c);  // OK\n    assert(d is d);  // OK\n    assert(d is s);  // doesn't work\n    assert(d is t);  // doesn't work\n    assert(d is u);  // doesn't work\n\n    assert(s is c);  // OK\n    assert(s is d);  // doesn't work\n    assert(s is s);  // OK\n    assert(s is t);  // doesn't work\n    assert(s is u);  // doesn't work\n\n    assert(t is c);  // OK\n    assert(t is d);  // doesn't work\n    assert(t is s);  // doesn't work\n    assert(t is t);  // OK\n    assert(t is u);  // doesn't work\n\n    assert(u is c);  // OK\n    assert(u is d);  // doesn't work\n    assert(u is s);  // doesn't work\n    assert(u is t);  // doesn't work\n    assert(u is u);  // OK\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6736\n\nvoid test6736()\n{\n    static struct S1\n    {\n        struct S2 // must be 8 bytes in size\n        {\n            uint a, b;\n        }\n        S2 s2;\n        alias s2 this;\n    }\n    S1 c;\n    static assert(!is(typeof(c + c)));\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2777\n\nstruct ArrayWrapper(T) {\n    T[] array;\n    alias array this;\n}\n\n// alias array this\nvoid test2777a()\n{\n    ArrayWrapper!(uint) foo;\n    foo.length = 5;  // Works\n    foo[0] = 1;      // Works\n    auto e0 = foo[0];  // Works\n    auto e4 = foo[$ - 1];  // Error:  undefined identifier __dollar\n    auto s01 = foo[0..2];  // Error:  ArrayWrapper!(uint) cannot be sliced with[]\n}\n\n// alias tuple this\nvoid test2777b()\n{\n    auto t = tup(10, 3.14, \"str\", [1,2]);\n\n    assert(t[$ - 1] == [1,2]);\n\n    auto f1 = t[];\n    assert(f1[0] == 10);\n    assert(f1[1] == 3.14);\n    assert(f1[2] == \"str\");\n    assert(f1[3] == [1,2]);\n\n    auto f2 = t[1..3];\n    assert(f2[0] == 3.14);\n    assert(f2[1] == \"str\");\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2787\n\nstruct Base2787\n{\n    int x;\n    void foo() { auto _ = x; }\n}\n\nstruct Derived2787\n{\n    Base2787 _base;\n    alias _base this;\n    int y;\n    void bar() { auto _ = x; }\n}\n\n/***********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5679\n\nvoid test5679()\n{\n    class Foo {}\n\n    class Base\n    {\n        @property Foo getFoo() { return null; }\n    }\n    class Derived : Base\n    {\n        alias getFoo this;\n    }\n\n    Derived[] dl;\n    Derived d = new Derived();\n    dl ~= d; // Error: cannot append type alias_test.Base to type Derived[]\n}\n\n/***********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6508\n\nvoid test6508()\n{\n    int x, y;\n    Seq!(x, y) = tup(10, 20);\n    assert(x == 10);\n    assert(y == 20);\n}\n\nvoid test6508x()\n{\n    static int ctor, cpctor, dtor;\n\n    static struct Tuple(T...)\n    {\n        T field;\n        alias field this;\n\n        this(int)  { ++ctor;   printf(\"ctor\\n\");   }\n        this(this) { ++cpctor; printf(\"cpctor\\n\"); }\n        ~this()    { ++dtor;   printf(\"dtor\\n\");   }\n    }\n\n    {\n        alias Tup = Tuple!(int, string);\n        auto tup = Tup(1);\n        assert(ctor==1 && cpctor==0 && dtor==0);\n\n        auto getVal() { return tup; }\n        ref getRef(ref Tup s = tup) { return s; }\n\n        {\n            auto n1 = tup[0];\n            assert(ctor==1 && cpctor==0 && dtor==0);\n\n            auto n2 = getRef()[0];\n            assert(ctor==1 && cpctor==0 && dtor==0);\n\n            auto n3 = getVal()[0];\n            assert(ctor==1 && cpctor==1 && dtor==1);\n        }\n\n        // bug in DotVarExp::semantic\n        {\n            typeof(tup.field) vars;\n            vars = getVal();\n            assert(ctor==1 && cpctor==2 && dtor==2);\n        }\n    }\n    assert(ctor==1 && cpctor==2 && dtor==3);\n    assert(ctor + cpctor == dtor);\n}\n\n/***********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6369\n\nvoid test6369a()\n{\n    alias Seq!(int, string) Field;\n\n    auto t1 = Tup!(int, string)(10, \"str\");\n    Field field1 = t1;           // NG -> OK\n    assert(field1[0] == 10);\n    assert(field1[1] == \"str\");\n\n    auto t2 = Tup!(int, string)(10, \"str\");\n    Field field2 = t2.field;     // NG -> OK\n    assert(field2[0] == 10);\n    assert(field2[1] == \"str\");\n\n    auto t3 = Tup!(int, string)(10, \"str\");\n    Field field3;\n    field3 = t3.field;\n    assert(field3[0] == 10);\n    assert(field3[1] == \"str\");\n}\n\nvoid test6369b()\n{\n    auto t = Tup!(Tup!(int, double), string)(tup(10, 3.14), \"str\");\n\n    Seq!(int, double, string) fs1 = t;\n    assert(fs1[0] == 10);\n    assert(fs1[1] == 3.14);\n    assert(fs1[2] == \"str\");\n\n    Seq!(Tup!(int, double), string) fs2 = t;\n    assert(fs2[0][0] == 10);\n    assert(fs2[0][1] == 3.14);\n    assert(fs2[0] == tup(10, 3.14));\n    assert(fs2[1] == \"str\");\n\n    Tup!(Tup!(int, double), string) fs3 = t;\n    assert(fs3[0][0] == 10);\n    assert(fs3[0][1] == 3.14);\n    assert(fs3[0] == tup(10, 3.14));\n    assert(fs3[1] == \"str\");\n}\n\nvoid test6369c()\n{\n    auto t = Tup!(Tup!(int, double), Tup!(string, int[]))(tup(10, 3.14), tup(\"str\", [1,2]));\n\n    Seq!(int, double, string, int[]) fs1 = t;\n    assert(fs1[0] == 10);\n    assert(fs1[1] == 3.14);\n    assert(fs1[2] == \"str\");\n    assert(fs1[3] == [1,2]);\n\n    Seq!(int, double, Tup!(string, int[])) fs2 = t;\n    assert(fs2[0] == 10);\n    assert(fs2[1] == 3.14);\n    assert(fs2[2] == tup(\"str\", [1,2]));\n\n    Seq!(Tup!(int, double), string, int[]) fs3 = t;\n    assert(fs3[0] == tup(10, 3.14));\n    assert(fs3[0][0] == 10);\n    assert(fs3[0][1] == 3.14);\n    assert(fs3[1] == \"str\");\n    assert(fs3[2] == [1,2]);\n}\n\nvoid test6369d()\n{\n    int eval = 0;\n    Seq!(int, string) t = tup((){++eval; return 10;}(), \"str\");\n    assert(eval == 1);\n    assert(t[0] == 10);\n    assert(t[1] == \"str\");\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6434\n\nstruct Variant6434{}\n\nstruct A6434\n{\n   Variant6434 i;\n   alias i this;\n\n   void opDispatch(string name)()\n   {\n   }\n}\n\nvoid test6434()\n{\n   A6434 a;\n   a.weird; // no property 'weird' for type 'VariantN!(maxSize)'\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6366\n\nvoid test6366()\n{\n    struct Zip\n    {\n        string str;\n        size_t i;\n        this(string s)\n        {\n            str = s;\n        }\n        @property const bool empty()\n        {\n            return i == str.length;\n        }\n        @property Tup!(size_t, char) front()\n        {\n            return typeof(return)(i, str[i]);\n        }\n        void popFront()\n        {\n            ++i;\n        }\n    }\n\n    foreach (i, c; Zip(\"hello\"))\n    {\n        switch (i)\n        {\n            case 0: assert(c == 'h');   break;\n            case 1: assert(c == 'e');   break;\n            case 2: assert(c == 'l');   break;\n            case 3: assert(c == 'l');   break;\n            case 4: assert(c == 'o');   break;\n            default:assert(0);\n        }\n    }\n\n    auto range(F...)(F field)\n    {\n        static struct Range {\n            F field;\n            bool empty = false;\n            Tup!F front() { return typeof(return)(field); }\n            void popFront(){ empty = true; }\n        }\n        return Range(field);\n    }\n\n    foreach (i, t; range(10, tup(\"str\", [1,2]))){\n        static assert(is(typeof(i) == int));\n        static assert(is(typeof(t) == Tup!(string, int[])));\n        assert(i == 10);\n        assert(t == tup(\"str\", [1,2]));\n    }\n    auto r1 = range(10, \"str\", [1,2]);\n    auto r2 = range(tup(10, \"str\"), [1,2]);\n    auto r3 = range(10, tup(\"str\", [1,2]));\n    auto r4 = range(tup(10, \"str\", [1,2]));\n    alias Seq!(r1, r2, r3, r4) ranges;\n    foreach (n, _; ranges)\n    {\n        foreach (i, s, a; ranges[n]){\n            static assert(is(typeof(i) == int));\n            static assert(is(typeof(s) == string));\n            static assert(is(typeof(a) == int[]));\n            assert(i == 10);\n            assert(s == \"str\");\n            assert(a == [1,2]);\n        }\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6711\n\nvoid test6711()\n{\n    struct A { int i; }\n    struct B { A a; alias a this; }\n    struct C { B b; alias b this; }\n\n    B b;\n    with (b)\n    {\n        i = 42;\n    }\n    assert(b.i == 42);\n\n    C c;\n    with (c)\n    {\n        i = 42;\n    }\n    assert(c.i == 42);\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12161\n\nclass A12161\n{\n    void m() {}\n}\n\nclass B12161\n{\n    A12161 a;\n    alias a this;\n}\n\nvoid test12161()\n{\n    B12161 b = new B12161();\n    b.a = new A12161();\n    with (b)\n        m();\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6759\n\nstruct Range\n{\n    size_t front() { return 0; }\n    void popFront() { empty = true; }\n    bool empty;\n}\n\nstruct ARange\n{\n    Range range;\n    alias range this;\n}\n\nvoid test6759()\n{\n    ARange arange;\n    assert(arange.front == 0);\n    foreach(e; arange)\n    {\n        assert(e == 0);\n    }\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6479\n\nstruct Memory6479\n{\n    mixin Wrapper6479!();\n}\nstruct Image6479\n{\n    Memory6479 sup;\n    alias sup this;\n}\nmixin template Wrapper6479()\n{\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6832\n\nvoid test6832()\n{\n    static class Foo { }\n    static struct Bar { Foo foo; alias foo this; }\n    Bar bar;\n    bar = new Foo;          // ok\n    assert(bar !is null);   // ng\n\n    struct Int { int n; alias n this; }\n    Int a;\n    int b;\n    auto c = (true ? a : b);    // TODO\n    assert(c == a);\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6928\n\nvoid test6928()\n{\n    struct T { int* p; } // p is necessary.\n    T tx;\n\n    struct S {\n        T get() const { return tx; }\n        alias get this;\n    }\n\n    immutable(S) s;\n    immutable(T) t;\n    static assert(is(typeof(1? s:t))); // ok.\n    static assert(is(typeof(1? t:s))); // ok.\n    static assert(is(typeof(1? s:t)==typeof(1? t:s))); // fail.\n\n    auto x = 1? t:s; // ok.\n    auto y = 1? s:t; // compile error.\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6929\n\nstruct S6929\n{\n    T6929 get() const { return T6929.init; }\n    alias get this;\n}\nstruct T6929\n{\n    S6929 get() const { return S6929.init; }\n    alias get this;\n}\nvoid test6929()\n{\n    T6929 t;\n    S6929 s;\n    static assert(!is(typeof(1? t:s)));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7136\n\nvoid test7136()\n{\n    struct X\n    {\n        Object get() immutable { return null; }\n        alias get this;\n    }\n    immutable(X) x;\n    Object y;\n    static assert( is(typeof(1?x:y) == Object));        // fails\n    static assert(!is(typeof(1?x:y) == const(Object))); // fails\n\n    struct A\n    {\n        int[] get() immutable { return null; }\n        alias get this;\n    }\n    immutable(A) a;\n    int[] b;\n    static assert( is(typeof(1?a:b) == int[]));         // fails\n    static assert(!is(typeof(1?a:b) == const(int[])));  // fails\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7731\n\nstruct A7731\n{\n    int a;\n}\ntemplate Inherit7731(alias X)\n{\n    X __super;\n    alias __super this;\n}\nstruct B7731\n{\n    mixin Inherit7731!A7731;\n    int b;\n}\n\nstruct PolyPtr7731(X)\n{\n    X* _payload;\n    static if (is(typeof(X.init.__super)))\n    {\n        alias typeof(X.init.__super) Super;\n        @property auto getSuper(){ return PolyPtr7731!Super(&_payload.__super); }\n        alias getSuper this;\n    }\n}\ntemplate create7731(X)\n{\n    PolyPtr7731!X create7731(T...)(T args){\n        return PolyPtr7731!X(args);\n    }\n}\n\nvoid f7731a(PolyPtr7731!A7731 a) {/*...*/}\nvoid f7731b(PolyPtr7731!B7731 b) {f7731a(b);/*...*/}\n\nvoid test7731()\n{\n    auto b = create7731!B7731();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7808\n\nstruct Nullable7808(T)\n{\n    private T _value;\n\n    this()(T value)\n    {\n        _value = value;\n    }\n\n    @property ref inout(T) get() inout pure @safe\n    {\n        return _value;\n    }\n    alias get this;\n}\n\nclass C7808 {}\nstruct S7808 { C7808 c; }\n\nvoid func7808(S7808 s) {}\n\nvoid test7808()\n{\n    auto s = Nullable7808!S7808(S7808(new C7808));\n    func7808(s);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7945\n\nstruct S7945\n{\n    int v;\n    alias v this;\n}\nvoid foo7945(ref int n){}\n\nvoid test7945()\n{\n    auto s = S7945(1);\n    foo7945(s);         // 1.NG -> OK\n    s.foo7945();        // 2.OK, ufcs\n    foo7945(s.v);       // 3.OK\n    s.v.foo7945();      // 4.OK, ufcs\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15674\n// alias this on out parameter, consistent with 7945 case\n\nstruct S15674\n{\n    int v;\n    alias v this;\n}\nvoid foo15674(out int i){ i = 42; }\n\nvoid test15674()\n{\n    S15674 s;\n    s.v = 1;    foo15674(s);    assert(s.v == 42);\n    s.v = 1;    foo15674(s.v);  assert(s.v == 42);\n    s.v = 1;    s.foo15674();   assert(s.v == 42);\n    s.v = 1;    s.v.foo15674(); assert(s.v == 42);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7979\n\nvoid test7979()\n{\n    static struct N\n    {\n        int val;\n        alias val this;\n    }\n    N n = N(1);\n\n    switch (n)\n    {\n        case 0:\n            assert(0);\n        case 1:\n            break;\n        default:\n            assert(0);\n    }\n\n    static struct S\n    {\n        string val;\n        alias val this;\n    }\n    S s = S(\"b\");\n\n    switch (s)\n    {\n        case \"a\":\n            assert(0);\n        case \"b\":\n            break;\n        default:\n            assert(0);\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7992\n\nstruct S7992\n{\n    int[] arr;\n    alias arr this;\n}\nS7992 func7992(...)\n{\n    S7992 ret;\n    ret.arr.length = _arguments.length;\n    return ret;\n}\nvoid test7992()\n{\n    int[] arr;\n    assert(arr.length == 0);\n    arr ~= func7992(1, 2);  //NG\n    //arr = func7992(1, 2); //OK\n    assert(arr.length == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8169\n\nvoid test8169()\n{\n    static struct ValueImpl\n    {\n       static immutable(int) getValue()\n       {\n           return 42;\n       }\n    }\n\n    static struct ValueUser\n    {\n       ValueImpl m_valueImpl;\n       alias m_valueImpl this;\n    }\n\n    static assert(ValueImpl.getValue() == 42); // #0, OK\n    static assert(ValueUser.getValue() == 42); // #1, NG -> OK\n    static assert(       ValueUser.m_valueImpl .getValue() == 42); // #2, NG -> OK\n    static assert(typeof(ValueUser.m_valueImpl).getValue() == 42); // #3, OK\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8735\n\nstruct S8735(alias Arg)\n{\n    alias Arg Val;\n    alias Val this;\n}\n\nstruct Tuple9709(T...)\n{\n    alias T expand;\n    alias expand this;\n}\n\nvoid test8735()\n{\n    alias S8735!1 S;\n    S s;\n    int n = s;\n    assert(n == 1);\n\n    // https://issues.dlang.org/show_bug.cgi?id=11502\n    static void f(int i);\n    S8735!f sf;\n\n    // https://issues.dlang.org/show_bug.cgi?id=9709\n    alias A = Tuple9709!(1,int,\"foo\");\n    A a;\n    //static assert(A[0] == 1);\n    static assert(a[0] == 1);\n    //static assert(is(A[1] == int));\n    //static assert(is(a[1] == int));\n    //static assert(A[2] == \"foo\");\n    static assert(a[2] == \"foo\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9174\n\nvoid test9174()\n{\n    static struct Foo\n    {\n        char x;\n        alias x this;\n    }\n    static assert(is(typeof(true ? 'A' : Foo()) == char));\n    static assert(is(typeof(true ? Foo() : 100) == int));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9177\n\nstruct S9177\n{\n    int foo(int){ return 0; }\n    alias foo this;\n}\npragma(msg, is(S9177 : int));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9858\n\nstruct S9858()\n{\n    @property int get() const\n    {\n        return 42;\n    }\n    alias get this;\n    void opAssign(int) {}\n}\nvoid test9858()\n{\n    const S9858!() s;\n    int i = s;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9873\n\nvoid test9873()\n{\n    struct Tup(T...) { T field; alias field this; }\n\n    auto seq1 = Seq!(1, \"hi\");\n    assert(Seq!(1, \"hi\") == Seq!(1, \"hi\"));\n    assert(seq1          == Seq!(1, \"hi\"));\n    assert(Seq!(1, \"hi\") == seq1);\n    assert(seq1          == seq1);\n\n    auto seq2 = Seq!(2, \"hi\");\n    assert(Seq!(1, \"hi\") != Seq!(2, \"hi\"));\n    assert(seq2          != Seq!(1, \"hi\"));\n    assert(Seq!(1, \"hi\") != seq2);\n    assert(seq2          != seq1);\n\n    auto tup1 = Tup!(int, string)(1, \"hi\");\n    assert(Seq!(1, \"hi\") == tup1);\n    assert(seq1          == tup1);\n    assert(tup1          == Seq!(1, \"hi\"));\n    assert(tup1          == seq1);\n\n    auto tup2 = Tup!(int, string)(2, \"hi\");\n    assert(Seq!(1, \"hi\") != tup2);\n    assert(seq1          != tup2);\n    assert(tup2          != Seq!(1, \"hi\"));\n    assert(tup2          != seq1);\n\n    static assert(!__traits(compiles, seq1 == Seq!(1, \"hi\", [1,2])));\n    static assert(!__traits(compiles, tup1 == Seq!(1, \"hi\", [1,2])));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10178\n\nvoid test10178()\n{\n    struct S { static int count; }\n    S s;\n    assert((s.tupleof == s.tupleof) == true);\n    assert((s.tupleof != s.tupleof) == false);\n\n    S getS()\n    {\n        S s;\n        ++S.count;\n        return s;\n    }\n    assert(getS().tupleof == getS().tupleof);\n    assert(S.count == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10179\n\nvoid test10179()\n{\n    struct S { static int count; }\n    S s;\n    static assert(s.tupleof.length == 0);\n    s.tupleof = s.tupleof;   // error -> OK\n\n    S getS()\n    {\n        S s;\n        ++S.count;\n        return s;\n    }\n    getS().tupleof = getS().tupleof;\n    assert(S.count == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9890\n\nvoid test9890()\n{\n    struct RefCounted(T)\n    {\n        T _payload;\n\n        ref T refCountedPayload()\n        {\n            return _payload;\n        }\n\n        alias refCountedPayload this;\n    }\n\n    struct S(int x_)\n    {\n        alias x_ x;\n    }\n\n    alias RefCounted!(S!1) Rs;\n    static assert(Rs.x == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10004\n\nvoid test10004()\n{\n    static int count = 0;\n\n    static S make(S)()\n    {\n        ++count;    // necessary to make this function impure\n        S s;\n        return s;\n    }\n\n    struct SX(T...) {\n        T field; alias field this;\n    }\n    alias S = SX!(int, long);\n    assert(make!S.field == make!S.field);\n    assert(count == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10180\n\ntemplate TypeTuple10180(TL...) { alias TypeTuple10180 = TL; }\n\ntemplate Identity10180(alias T) { alias Identity10180 = T; }\n\nstruct Tuple10180(Specs...)\n{\n    static if (is(Specs))\n    {\n        alias Types = Specs;\n        Types expand;\n        alias expand this;\n    }\n    else\n    {\n        alias Types = TypeTuple10180!(Specs[0]);\n        Types expand;\n        mixin(\"alias Identity10180!(expand[0]) \"~Specs[1]~\";\");\n\n        @property\n        ref Tuple10180!(Specs[0]) _Tuple_super()\n        {\n            return *cast(typeof(return)*) (&expand[0]);\n        }\n        alias _Tuple_super this;\n    }\n}\n\nvoid test10180()\n{\n    Tuple10180!(int, \"a\") x;\n    auto o1 = x.a.offsetof;     // OK\n    auto o2 = x[0].offsetof;    // NG: no property 'offsetof' for type 'int'\n    auto o3 = x._Tuple_super[0].offsetof;   // same as above\n    assert(o2 == o3);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10456\n\nvoid test10456()\n{\n    S10456 s1, s2;\n    auto x = s1 == s2;\n}\n\nstruct S10456\n{\n    enum E { e };\n    alias E this;\n    int[] x;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11261\n\ntemplate Tuple11261(Specs...)\n{\n    struct Tuple11261\n    {\n        static if (Specs.length != 4)   // anonymous field version\n        {\n            alias Specs Types;\n            Types expand;\n            alias expand this;\n        }\n        else\n        {\n            alias Seq!(Specs[0], Specs[2]) Types;\n            Types expand;\n            ref inout(Tuple11261!Types) _Tuple_super() inout @trusted\n            {\n                return *cast(typeof(return)*) &(expand[0]);\n            }\n            // This is mostly to make t[n] work.\n            alias _Tuple_super this;\n        }\n\n        this()(Types values)\n        {\n            expand[] = values[];\n        }\n    }\n}\n\ninterface InputRange11261(E)\n{\n    @property bool empty();\n    @property E front();\n    void popFront();\n\n    int opApply(int delegate(E));\n    int opApply(int delegate(size_t, E));\n\n}\ntemplate InputRangeObject11261(R)\n{\n    alias typeof(R.init.front()) E;\n\n    class InputRangeObject11261 : InputRange11261!E\n    {\n        private R _range;\n\n        this(R range) { this._range = range; }\n\n        @property bool empty() { return _range.empty; }\n        @property E front() { return _range.front; }\n        void popFront() { _range.popFront(); }\n\n        int opApply(int delegate(E) dg) { return 0; }\n        int opApply(int delegate(size_t, E) dg) { return 0; }\n    }\n}\n\n// ------\n\nclass Container11261\n{\n    alias Tuple11261!(string, \"key\", string, \"value\") Key;\n\n    InputRange11261!Key opSlice()\n    {\n        Range r;\n        return new InputRangeObject11261!Range(r);\n    }\n    private struct Range\n    {\n        enum empty = false;\n        auto popFront() {}\n        auto front() { return Key(\"myKey\", \"myValue\"); }\n    }\n}\n\nvoid test11261()\n{\n    auto container = new Container11261();\n    foreach (k, v; container)   // map the tuple of container[].front to (k, v)\n    {\n        static assert(is(typeof(k) == string) && is(typeof(v) == string));\n        break;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11333\n\nalias id11333(a...) = a;\n\nstruct Unit11333\n{\n    enum value = Unit11333.init.tupleof;\n    alias value this;\n}\n\nvoid test11333()\n{\n    void foo() {}\n\n    id11333!() unit;\n    unit = unit; // ok\n    foo(unit);   // ok\n\n    unit = Unit11333.value; // ok\n    foo(Unit11333.value);   // ok\n\n    Unit11333 unit2;\n    unit = unit2; // ok <- segfault\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11538\n\nstruct NullableRef11538(T)\n{\n    T* _value;\n    inout(T) get() inout { return *_value; }\n    alias get this;\n}\n\nstruct S11538\n{\n    NullableRef11538!S11538 parent;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11800\n\nstruct A11800\n{\n    B11800 b;\n    alias b this;\n}\n\nstruct B11800\n{\n    static struct Value {}\n    Value value;\n    alias value this;\n\n    void foo(ref const B11800 rhs)\n    {\n    }\n}\n\nvoid test11800()\n{\n    A11800 a;\n    B11800 b;\n    b.foo(a);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12008\n\nstruct RefCounted12008(T)\n{\n    struct RefCountedStore\n    {\n        private struct Impl\n        {\n            T _payload;\n        }\n\n        private void initialize(A...)(auto ref A args)\n        {\n            import core.memory;\n        }\n\n        void ensureInitialized()\n        {\n            initialize();\n        }\n\n    }\n    RefCountedStore _refCounted;\n\n    void opAssign(T rhs)\n    {\n    }\n\n    int refCountedPayload()\n    {\n        _refCounted.ensureInitialized();\n        return 0;\n    }\n\n    int refCountedPayload() inout\n    {\n        return 0;\n    }\n\n    alias refCountedPayload this;\n}\n\nstruct SharedInput12008\n{\n    Group12008 unused;\n}\n\nstruct Group12008\n{\n    RefCounted12008!SharedInput12008 _allGroups;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12038\n\nbool f12038(void* p) { return true; }\n\nstruct S12038\n{\n    @property p() { f12038(&this); }\n    alias p this;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13490\n\nstruct S13490\n{\n    int i;\n    alias i this;\n}\n\nstruct T13490\n{\n    S13490[] a1, a2;\n}\n\nvoid test13490()\n{\n    T13490 t;\n\n    (true ? t.a1 : t.a2) ~= S13490(1);\n    assert(t.a1 == [S13490(1)]);\n    assert(t.a2 == []);\n\n    (false ? t.a1 : t.a2) ~= S13490(2);\n    assert(t.a1 == [S13490(1)]);\n    assert(t.a2 == [S13490(2)]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11355\n\nstruct A11355\n{\n    static int postblit;\n    this(this) { ++postblit; }\n}\n\nstruct B11355\n{\n    A11355 a;\n    alias a this;\n}\n\nB11355 make11355()\n{\n    return B11355();\n}\nvoid test11355()\n{\n    A11355 a1 = make11355();\n    assert(A11355.postblit == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13009\n\nstruct T13009\n{\n    void put(char c) {}\n}\n\nstruct S13009(bool rev)\n{\n    T13009 t;\n\n    static if (!rev)\n    {\n        @property       T13009  getT()       { return t; }\n        @property inout(T13009) getT() inout { return t; }\n    }\n    else\n    {\n        @property inout(T13009) getT() inout { return t; }\n        @property       T13009  getT()       { return t; }\n    }\n\n    alias getT this;\n}\n\nvoid test13009()\n{\n    foreach (bool rev; Seq!(false, true))\n    {\n        alias S = S13009!rev;\n\n        alias MS   =                    S;\n        alias CS   =              const(S);\n        alias WS   =        inout(      S);\n        alias WCS  =        inout(const S);\n        alias SMS  = shared(            S);\n        alias SCS  = shared(      const S);\n        alias SWS  = shared(inout       S);\n        alias SWCS = shared(inout const S);\n        alias IS   =          immutable(S);\n\n        alias MSput  = MS .put;\n        alias CSput  = CS .put;\n        alias WSput  = WS .put;\n        alias WCSput = WCS.put;\n        static assert(!__traits(compiles, { alias SMSput  = SMS .put; }));\n        static assert(!__traits(compiles, { alias SCSput  = SCS .put; }));\n        static assert(!__traits(compiles, { alias SWSput  = SWS .put; }));\n        static assert(!__traits(compiles, { alias SWCSput = SWCS.put; }));\n        alias ISput  = IS .put;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14806\n\nstruct Nullable14806\n{\n    float get() { return float.nan; }\n    alias get this;\n}\n\nstruct Foo14806(T)\n{\n    T bar;\n    Nullable14806 baz;\n}\n\nvoid test14806()\n{\n    Foo14806!int a, b;\n    assert(a != b);\n    // ==> a.tupleof != b.tupleof\n    // ==> a.bar != b.bar || a.baz.get() != b.baz.get()\n\n    Foo14806!string c, d;\n    assert(c != d);\n    // ==> c.tupleof != d.tupleof\n    // ==> c.bar != d.bar || c.baz.get() != d.baz.get()\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14948\n\nstruct RefCounted14948(T)\n{\n    struct Impl\n    {\n        T data;\n    }\n    Impl* impl;\n\n    @property ref T payload() { return impl.data; }\n\n    alias payload this;\n}\n\nstruct HTTP14948\n{\n    struct Impl\n    {\n    }\n\n    RefCounted14948!Impl p;\n}\n\nvoid test14948()\n{\n    int[HTTP14948] aa;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15292\n\nstruct NullableRef15292(T)\n{\n    inout(T) get() inout\n    {\n        assert(false);\n    }\n\n    alias get this;\n}\n\nstruct S15292\n{\n    NullableRef15292!S15292 n;  // -> no segfault\n\n    /* The field 'n' contains alias this, so to use it for the equality,\n     * following helper function is automatically generated in buildXopEquals().\n     *\n     *  static bool __xopEquals(ref const S15292 p, ref const S15292 q)\n     *  {\n     *      return p == q;\n     *  }\n     *\n     * In its definition, const(S15292) equality is analyzed. It fails, then\n     * the error is gagged.\n     */\n}\n\n/***************************************************/\n\nstruct S19284a { int x; }\nstruct S19284b\n{\n    S19284a s;\n    alias s this;\n    int t;\n    void f()\n    {\n        void wrapped()\n        {\n            x = 1;\n            t = 1;\n        }\n        wrapped(); // <-- 'x' not found, whereas 's.x' works fine\n    }\n\n    void f1()\n    {\n        x = 2;\n    }\n\n    void f2()\n    {\n        int x;\n        void wrapped()\n        {\n            x = 7;\n        }\n        wrapped();\n        assert(x == 7);\n    }\n\n    void f3()\n    {\n        void wrapped()\n        {\n            void wrapped2()\n            {\n                x = 5;\n            }\n            wrapped2();\n        }\n        wrapped();\n    }\n}\n\nvoid test19284()\n{\n    S19284b t;\n\n    // nested function modifies alias this\n    t.f();\n    assert(t.x == 1);\n    assert(t.t == 1);\n\n    // member function modifies alias this\n    t.f1();\n    assert(t.x == 2);\n\n    // nested function does not modify alias this when it is shadowd by a local variable\n    t.f2();\n    assert(t.x == 2);\n\n    // multiple levels of nesting\n    t.f3();\n    assert(t.x == 5);\n}\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test4617a();\n    test4617b();\n    test4773();\n    test5188();\n    test6();\n    test7();\n    test2781();\n    test6546();\n    test6736();\n    test2777a();\n    test2777b();\n    test5679();\n    test6508();\n    test6508x();\n    test6369a();\n    test6369b();\n    test6369c();\n    test6369d();\n    test6434();\n    test6366();\n    test6711();\n    test12161();\n    test6759();\n    test6832();\n    test6928();\n    test6929();\n    test7136();\n    test7731();\n    test7808();\n    test7945();\n    test15674();\n    test7979();\n    test7992();\n    test8169();\n    test8735();\n    test9174();\n    test9858();\n    test9873();\n    test10178();\n    test10179();\n    test9890();\n    test10004();\n    test10180();\n    test10456();\n    test11333();\n    test11800();\n    test13490();\n    test11355();\n    test14806();\n    test19284();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/argufilem.d",
    "content": "// EXTRA_SOURCES: imports/argufile.d\n\n// NOTE: The bug only works when main.d and argufile.d are put in\n//                      separate files and compiled like 'dmd main.d argufile.d'\n//                      Also, I'm sure writefln is causing the crash cause when I\n//                      use printf(), it doesn't crash.\n\n// main.d -------------------------------------------------------\n\nimport argufile;\n\nint main(string[] args)\n{\n        string message = arguments(\"bob is \", 7, \" years old\");\n\n        writefln(message);\n\n        argufile.useargs(); // will crash here\n\n        return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/arrayop.d",
    "content": "import std.math;\n\nextern(C) int printf(const char*, ...);\n\nstring abc;\n\ntemplate Floating(T)\n{\n    T[3] a;\n    T[3] b;\n    T[3] c;\n\n    T[] A()\n    {\n        printf(\"A\\n\");\n        abc ~= \"A\";\n        return a;\n    }\n\n    T[] B()\n    {\n        printf(\"B\\n\");\n        abc ~= \"B\";\n        return b;\n    }\n\n    T[] C()\n    {\n        printf(\"C\\n\");\n        abc ~= \"C\";\n        return c;\n    }\n\n    T D()\n    {\n        printf(\"D\\n\");\n        abc ~= \"D\";\n        return 4;\n    }\n\n\n    void testx()\n    {\n        a = [11, 22, 33];\n        b = [1, 2, 3];\n        c = [4, 5, 6];\n\n        abc = null;\n        A()[] = B()[] + C()[];\n        assert(abc == \"ABC\");\n        assert(a[0] == 5);\n        assert(a[1] == 7);\n        assert(a[2] == 9);\n\n        abc = null;\n        A()[] = B()[] + 4;\n        assert(abc == \"AB\");\n        assert(a[0] == 5);\n        assert(a[1] == 6);\n        assert(a[2] == 7);\n\n        abc = null;\n        A()[] = 4 + B()[];\n        assert(abc == \"AB\");\n        assert(a[0] == 5);\n        assert(a[1] == 6);\n        assert(a[2] == 7);\n\n        abc = null;\n        A()[] = D() + B()[];\n        assert(abc == \"ADB\");\n        assert(a[0] == 5);\n        assert(a[1] == 6);\n        assert(a[2] == 7);\n\n        a = [11, 22, 33];\n        abc = null;\n        A()[] += B()[];\n        assert(abc == \"AB\");\n        assert(a[0] == 12);\n        assert(a[1] == 24);\n        assert(a[2] == 36);\n\n        a = [11, 22, 33];\n        A()[] += 4;\n        assert(a[0] == 15);\n        assert(a[1] == 26);\n        assert(a[2] == 37);\n\n        a = [11, 22, 33];\n        A()[] -= 4;\n        assert(a[0] == 7);\n        assert(a[1] == 18);\n        assert(a[2] == 29);\n\n        a = [11, 22, 33];\n        A()[] *= 4;\n        assert(a[0] == 44);\n        assert(a[1] == 88);\n        assert(a[2] == 132);\n\n        a = [4, 8, 32];\n        A()[] /= 4;\n        assert(a[0] == 1);\n        assert(a[1] == 2);\n        assert(a[2] == 8);\n\n        a = [4, 8, 33];\n        A()[] %= 4;\n        assert(a[0] == 0);\n        assert(a[1] == 0);\n        assert(a[2] == 1);\n\n        a = [11, 22, 33];\n        abc = null;\n        A()[] += 4 + B()[];\n        assert(abc == \"AB\");\n        assert(a[0] == 16);\n        assert(a[1] == 28);\n        assert(a[2] == 40);\n\n        abc = null;\n        A()[] = B()[] - C()[];\n        assert(abc == \"ABC\");\n        printf(\"%Lg, %Lg, %Lg\\n\", cast(real)a[0], cast(real)a[1], cast(real)a[2]);\n        assert(a[0] == -3);\n        assert(a[1] == -3);\n        assert(a[2] == -3);\n\n        abc = null;\n        A()[] = -B()[] - C()[];\n        assert(abc == \"ABC\");\n        printf(\"%Lg, %Lg, %Lg\\n\", cast(real)a[0], cast(real)a[1], cast(real)a[2]);\n        assert(a[0] == -5);\n        assert(a[1] == -7);\n        assert(a[2] == -9);\n\n        abc = null;\n        A()[] = B()[] + C()[] * 4;\n        assert(abc == \"ABC\");\n        printf(\"%Lg, %Lg, %Lg\\n\", cast(real)a[0], cast(real)a[1], cast(real)a[2]);\n        assert(a[0] == 17);\n        assert(a[1] == 22);\n        assert(a[2] == 27);\n\n        abc = null;\n        A()[] = B()[] + C()[] * B()[];\n        assert(abc == \"ABCB\");\n        printf(\"%Lg, %Lg, %Lg\\n\", cast(real)a[0], cast(real)a[1], cast(real)a[2]);\n        assert(a[0] == 5);\n        assert(a[1] == 12);\n        assert(a[2] == 21);\n\n        abc = null;\n        A()[] = B()[] + C()[] / 2;\n        assert(abc == \"ABC\");\n        printf(\"%Lg, %Lg, %Lg\\n\", cast(real)a[0], cast(real)a[1], cast(real)a[2]);\n        assert(a[0] == 3);\n        assert(a[1] == 4.5);\n        assert(a[2] == 6);\n\n        abc = null;\n        A()[] = B()[] + C()[] % 2;\n        assert(abc == \"ABC\");\n        printf(\"%Lg, %Lg, %Lg\\n\", cast(real)a[0], cast(real)a[1], cast(real)a[2]);\n        assert(a[0] == 1);\n        assert(a[1] == 3);\n        assert(a[2] == 3);\n    }\n}\n\nmixin Floating!(float) Ffloat;\nmixin Floating!(double) Fdouble;\nmixin Floating!(real) Freal;\n\nvoid test1()\n{\n    Ffloat.testx();\n    Fdouble.testx();\n    Freal.testx();\n}\n\n/************************************************************************/\n\ntemplate Integral(T)\n{\n    T[3] a;\n    T[3] b;\n    T[3] c;\n\n    T[] A()\n    {\n        printf(\"A\\n\");\n        abc ~= \"A\";\n        return a;\n    }\n\n    T[] B()\n    {\n        printf(\"B\\n\");\n        abc ~= \"B\";\n        return b;\n    }\n\n    T[] C()\n    {\n        printf(\"C\\n\");\n        abc ~= \"C\";\n        return c;\n    }\n\n    T D()\n    {\n        printf(\"D\\n\");\n        abc ~= \"D\";\n        return 4;\n    }\n\n\n    void testx()\n    {\n        a = [11, 22, 33];\n        b = [1, 2, 3];\n        c = [4, 5, 6];\n\n        abc = null;\n        A()[] = B()[] + C()[];\n        assert(abc == \"ABC\");\n        assert(a[0] == 5);\n        assert(a[1] == 7);\n        assert(a[2] == 9);\n\n        abc = null;\n        A()[] = B()[] + 4;\n        assert(abc == \"AB\");\n        assert(a[0] == 5);\n        assert(a[1] == 6);\n        assert(a[2] == 7);\n\n        abc = null;\n        A()[] = 4 + B()[];\n        assert(abc == \"AB\");\n        assert(a[0] == 5);\n        assert(a[1] == 6);\n        assert(a[2] == 7);\n\n        abc = null;\n        A()[] = D() + B()[];\n        assert(abc == \"ADB\");\n        assert(a[0] == 5);\n        assert(a[1] == 6);\n        assert(a[2] == 7);\n\n        a = [11, 22, 33];\n        abc = null;\n        A()[] += B()[];\n        assert(abc == \"AB\");\n        assert(a[0] == 12);\n        assert(a[1] == 24);\n        assert(a[2] == 36);\n\n        a = [11, 22, 33];\n        A()[] += 4;\n        assert(a[0] == 15);\n        assert(a[1] == 26);\n        assert(a[2] == 37);\n\n        a = [11, 22, 33];\n        A()[] -= 4;\n        assert(a[0] == 7);\n        assert(a[1] == 18);\n        assert(a[2] == 29);\n\n        a = [11, 22, 27];\n        A()[] *= 4;\n        assert(a[0] == 44);\n        assert(a[1] == 88);\n        assert(a[2] == 108);\n\n        a = [11, 22, 33];\n        A()[] /= 4;\n        assert(a[0] == 2);\n        assert(a[1] == 5);\n        assert(a[2] == 8);\n\n        a = [11, 22, 33];\n        A()[] %= 4;\n        assert(a[0] == 3);\n        assert(a[1] == 2);\n        assert(a[2] == 1);\n\n        a = [1, 2, 7];\n        A()[] &= 4;\n        assert(a[0] == 0);\n        assert(a[1] == 0);\n        assert(a[2] == 4);\n\n        a = [1, 2, 7];\n        A()[] |= 4;\n        assert(a[0] == 5);\n        assert(a[1] == 6);\n        assert(a[2] == 7);\n\n        a = [1, 2, 7];\n        A()[] ^= 4;\n        assert(a[0] == 5);\n        assert(a[1] == 6);\n        assert(a[2] == 3);\n\n        a = [11, 22, 33];\n        abc = null;\n        A()[] += 4 + B()[];\n        assert(abc == \"AB\");\n        assert(a[0] == 16);\n        assert(a[1] == 28);\n        assert(a[2] == 40);\n\n        abc = null;\n        A()[] = B()[] - C()[];\n        assert(abc == \"ABC\");\n        printf(\"%lld, %lld, %lld\\n\", cast(long)a[0], cast(long)a[1], cast(long)a[2]);\n        assert(a[0] == -3);\n        assert(a[1] == -3);\n        assert(a[2] == -3);\n\n        abc = null;\n        A()[] = -B()[] - C()[];\n        assert(abc == \"ABC\");\n        printf(\"%lld, %lld, %lld\\n\", cast(long)a[0], cast(long)a[1], cast(long)a[2]);\n        assert(a[0] == -5);\n        assert(a[1] == -7);\n        assert(a[2] == -9);\n\n        abc = null;\n        A()[] = B()[] + C()[] * 4;\n        assert(abc == \"ABC\");\n        printf(\"%lld, %lld, %lld\\n\", cast(long)a[0], cast(long)a[1], cast(long)a[2]);\n        assert(a[0] == 17);\n        assert(a[1] == 22);\n        assert(a[2] == 27);\n\n        abc = null;\n        A()[] = B()[] + C()[] * B()[];\n        assert(abc == \"ABCB\");\n        printf(\"%lld, %lld, %lld\\n\", cast(long)a[0], cast(long)a[1], cast(long)a[2]);\n        assert(a[0] == 5);\n        assert(a[1] == 12);\n        assert(a[2] == 21);\n\n        abc = null;\n        A()[] = B()[] + C()[] / 2;\n        assert(abc == \"ABC\");\n        printf(\"%lld, %lld, %lld\\n\", cast(long)a[0], cast(long)a[1], cast(long)a[2]);\n        assert(a[0] == 3);\n        assert(a[1] == 4);\n        assert(a[2] == 6);\n\n        abc = null;\n        A()[] = B()[] + C()[] % 2;\n        assert(abc == \"ABC\");\n        printf(\"%lld, %lld, %lld\\n\", cast(long)a[0], cast(long)a[1], cast(long)a[2]);\n        assert(a[0] == 1);\n        assert(a[1] == 3);\n        assert(a[2] == 3);\n\n        abc = null;\n        A()[] = ~B()[];\n        assert(abc == \"AB\");\n        assert(a[0] == ~cast(T)1);\n        assert(a[1] == ~cast(T)2);\n        assert(a[2] == ~cast(T)3);\n\n        abc = null;\n        A()[] = B()[] & 2;\n        assert(abc == \"AB\");\n        assert(a[0] == 0);\n        assert(a[1] == 2);\n        assert(a[2] == 2);\n\n        abc = null;\n        A()[] = B()[] | 2;\n        assert(abc == \"AB\");\n        assert(a[0] == 3);\n        assert(a[1] == 2);\n        assert(a[2] == 3);\n\n        abc = null;\n        A()[] = B()[] ^ 2;\n        assert(abc == \"AB\");\n        assert(a[0] == 3);\n        assert(a[1] == 0);\n        assert(a[2] == 1);\n    }\n}\n\n/************************************************************************/\n\nmixin Integral!(byte) Fbyte;\nmixin Integral!(short) Fshort;\nmixin Integral!(int) Fint;\nmixin Integral!(long) Flong;\n\nvoid test2()\n{\n    Fbyte.testx();\n    Fshort.testx();\n    Fint.testx();\n    Flong.testx();\n}\n\n/************************************************************************/\n\nvoid test3()\n{\n    auto a = new double[10], b = a.dup, c = a.dup, d = a.dup;\n    a[] = -(b[] * (c[] + 4)) + 5 * d[] / 3.0;\n}\n\n/************************************************************************/\n\nvoid test4()\n{\n    int[] a, b;\n    if (a && b) {}\n}\n\n/***************************************************/\n\nvoid test4662()\n{\n    immutable double[] nums = [1.0, 2.0];\n\n    static assert(!is(typeof({ nums[] += nums[]; })));\n    static assert(!is(typeof({ nums[] -= nums[]; })));\n    static assert(!is(typeof({ nums[] /= nums[]; })));\n    static assert(!is(typeof({ nums[] += 4; })));\n    static assert(!is(typeof({ nums[] /= 7; })));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5284\n\nvoid bug5284_1()\n{\n    class C { int v; }\n\n              C [] mda;\n    immutable(C)[] ida;\n    static assert(!__traits(compiles, (mda[] = ida[])));\n\n              C [1] msa;\n    immutable(C)[1] isa;\n    static assert(!__traits(compiles, (msa[] = isa[])));\n\n              C  m;\n    immutable(C) i;\n    static assert(!__traits(compiles, m = i));\n}\nvoid bug5284_2a()\n{\n    struct S { int v; }\n\n              S [] mda;\n    immutable(S)[] ida;\n    mda[] = ida[];\n\n              S [1] msa;\n    immutable(S)[1] isa;\n    msa[] = isa[];\n\n              S  m = S();\n    immutable(S) i = immutable(S)();\n    m = i;\n}\nvoid bug5284_2b()\n{\n    struct S { int v; int[] arr; }\n\n              S [] mda;\n    immutable(S)[] ida;\n    static assert(!__traits(compiles, (mda[] = ida[])));\n\n              S [1] msa;\n    immutable(S)[1] isa;\n    static assert(!__traits(compiles, (msa[] = isa[])));\n\n              S  m;\n    immutable(S) i;\n    static assert(!__traits(compiles, m = i));\n}\nvoid bug5284_3()\n{\n              int [] ma;\n    immutable(int)[] ia;\n    ma[] = ia[];\n\n    int m;\n    immutable(int) i;\n    m = i;\n}\n\nvoid test5()\n{\n    bug5284_1();\n    bug5284_2a();\n    bug5284_2b();\n    bug5284_3();\n}\n\n/************************************************************************/\n\nvoid test6()\n{\n    int[10] a = [1,2,3,4,5,6,7,8,9,10];\n    int[10] b;\n\n    b = a[] ^^ 2;\n    assert(b[0] == 1);\n    assert(b[1] == 4);\n    assert(b[2] == 9);\n    assert(b[3] == 16);\n    assert(b[4] == 25);\n    assert(b[5] == 36);\n    assert(b[6] == 49);\n    assert(b[7] == 64);\n    assert(b[8] == 81);\n    assert(b[9] == 100);\n\n    int[10] c = 3;\n    b = a[] ^^ c[];\n    assert(b[0] == 1);\n    assert(b[1] == 8);\n    assert(b[2] == 27);\n    assert(b[3] == 64);\n    assert(b[4] == 125);\n    assert(b[5] == 216);\n    assert(b[6] == 343);\n    assert(b[7] == 512);\n    assert(b[8] == 729);\n    assert(b[9] == 1000);\n}\n\n/************************************************************************/\n\nvoid test8390() {\n    const int[] a = new int[5];\n    int[] b = new int[5];\n    b[] += a[];\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8651\n\nvoid test8651()\n{\n    void test(T)() @safe pure nothrow\n    {\n        T[3] a = [11, 22, 33];\n        T[3] b = [1, 2, 3];\n        T[3] c = [4, 5, 6];\n        T    d = 4;\n\n        // Arithmetic array ops\n        {\n            a[] = b[] + c[];\n            a[] = b[] + 4;\n            a[] = 4 + b[];\n            a[] = d + b[];\n            a[] += b[];\n            a[] += 4;\n            a[] -= 4;\n            a[] *= 4;\n            a[] /= 4;\n            a[] %= 4;\n            a[] += 4 + b[];\n            a[] = b[] - c[];\n            a[] = -b[] - c[];\n            a[] = b[] + c[] * 4;\n            a[] = b[] + c[] * b[];\n            a[] = b[] + c[] / 2;\n            a[] = b[] + c[] % 2;\n        }\n        // Bitwise array ops\n        static if (is(typeof(T.init & T.init)))\n        {\n            a[] &= 4;\n            a[] |= 4;\n            a[] ^= 4;\n            a[] = ~b[];\n            a[] = b[] & 2;\n            a[] = b[] | 2;\n            a[] = b[] ^ 2;\n        }\n    }\n\n    test!float();\n    test!double();\n    test!real();\n\n    test!byte();\n    test!short();\n    test!int();\n    test!long();\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9656\n\nvoid test9656()\n{\n    static class C {}\n    static struct S\n    {\n        immutable int[] narr1;\n        immutable int[] narr2;\n        immutable C[] carr1;\n        immutable C[] carr2;\n        this(int n) {\n            narr1 = new int[](3); // OK, expected\n            narr2 = [1,2,3].dup;  // NG -> OK\n            carr1 = [new C].dup;  // NG -> OK\n\n            C c = new C;\n            static assert(!__traits(compiles, carr2 = [c]));\n        }\n    }\n\n    {\n        int[] ma = [1,2,3];\n        immutable ia = ma.idup;\n    }\n\n\n    {\n        static struct V { int val; }\n        V[] ma = [V(1), V(2)];\n        immutable ia = ma.idup;\n    }\n\n    {\n        static struct R { int* ptr; }\n        R[] ma = [R(new int), R(null)];\n        static assert(!__traits(compiles, { immutable ia = rarr.dup; }));\n    }\n\n    {\n        C[] ma = [new C(), new C()];\n        static assert(!__traits(compiles, { immutable ia = carr.dup; }));\n    }\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10282\n\nvoid test10282()\n{\n    int[3]           a1 = [1, 3, 6];\n    int[3]           a2 = [1, 3, 6] * 3;    // OK\n    const     int[3] a3 = a1[] * 3;         // OK <- Error\n    const     int[3] a4 = [1, 3, 6] * 3;    // OK <- Error\n    immutable int[3] a5 = [1, 3, 6] * 3;    // OK <- Error\n\n    assert(a1[0] == 1 && a1[1] == 3 && a1[2] == 6);\n    assert(a2[0] == 3 && a2[1] == 9 && a2[2] == 18);\n    assert(a3[0] == 3 && a3[1] == 9 && a3[2] == 18);\n    assert(a4[0] == 3 && a4[1] == 9 && a4[2] == 18);\n    assert(a5[0] == 3 && a5[1] == 9 && a5[2] == 18);\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10433\n\nvoid test10433()\n{\n    void foo(T)(in int[] v1, in T v2)\n    {\n        int[2] r;\n        r[] = v1[] + v2[];\n    }\n\n    immutable int[] v = [10, 20];\n    foo(v, v);\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10684\n\nvoid test10684a()\n{\n    int[] a = [0, 0];\n    a[] += [10, 20][];\n}\n\nvoid test10684b()\n{\n    int[] a = [1, 2, 3];\n    int[] b = [4, 5, 6];\n\n    // Allow array literal as the operand of array oeration\n    a[] += [1, 2, 3];\n    assert(a == [2, 4, 6]);\n\n    a[] *= b[] + [1, 1, 1];\n    assert(a == [2*(4+1), 4*(5+1), 6*(6+1)]);\n\n    a[] = [9, 8, 7] - [1, 2, 3];\n    assert(a == [8, 6, 4]);\n\n    a[] = [2, 4, 6] / 2;\n    assert(a == [1,2,3]);\n\n    // Disallow: [1,2,3] is not an lvalue\n    static assert(!__traits(compiles, { [1,2,3] = a[] * 2; }));\n    static assert(!__traits(compiles, { [1,2,3] += a[] * b[]; }));\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11376\n\ntemplate TL11376(T...)\n{\n    alias TL11376 = T;\n}\n\nauto sumArrs11376(T0, T1)(T0[] a, T1[] b)\n{\n    a[] += b[]; //no ICE without this line\n    return a;\n}\n\nstatic assert(!__traits(compiles, sumArrs11376(TL11376!(string[], string).init)));\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11525\n\nvoid test11525()\n{\n    static struct Complex(T)\n    {\n        T re, im;\n\n        ref opOpAssign(string op : \"*\")(Complex z)\n        {\n            auto temp = re*z.re - im*z.im;\n            im = im*z.re + re*z.im;\n            re = temp;\n            return this;\n        }\n    }\n\n    auto a = [Complex!double(2, 2)];\n    assert(a.length == 1 && a[0].re == 2 && a[0].im == 2);\n    a[] *= a[];\n    assert(a.length == 1 && a[0].re == 0 && a[0].im == 8);\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12250\n\nvoid f12250(inout int[] p, inout int[] q, int[] r)\n{\n    r[] = p[] + q[];\n    assert(r == [5,7,9]);\n    r[] -= p[] - q[];\n    assert(r == [8,10,12]);\n}\n\nvoid test12250()\n{\n    immutable int[3] x = [1,2,3], y = [4,5,6];\n    int[3] z;\n    f12250(x[], y[], z[]);\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12179\n\nvoid test12179()\n{\n    void foo(int[]) {}\n    int[1] a;\n\n    foo(a[] = a[]);\n    foo(a[] += a[]);\n    foo(a[] -= a[]);\n    foo(a[] *= a[]);\n    foo(a[] /= a[]);\n    foo(a[] %= a[]);\n    foo(a[] ^= a[]);\n    foo(a[] &= a[]);\n    foo(a[] |= a[]);\n    foo(a[] ^^= a[]);\n\n    // from https://issues.dlang.org/show_bug.cgi?id=11992\n    int[]   arr1;\n    int[][] arr2;\n    arr1 ~= (a[] = [1] + a[]); // OK\n    arr2 ~= (a[] = [1] + a[]); // OK\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12780\n\nvoid test12780()\n{\n    int ival = 2;\n    int[] iarr = [1, 2, 3];\n    double dval = 2.0;\n    double[] darr = [4, 5, 6];\n\n    double[] oarr = [0, 0, 0];\n\n    // multiply array operations\n    oarr[] = dval * iarr[];\n    assert(oarr == [dval * iarr[0],\n                    dval * iarr[1],\n                    dval * iarr[2]]);\n\n    oarr[] = iarr[] / dval;\n    assert(oarr == [iarr[0] / dval,\n                    iarr[1] / dval,\n                    iarr[2] / dval]);\n\n    oarr[] = dval * (ival + iarr[]);\n    assert(oarr == [dval * (ival + iarr[0]),\n                    dval * (ival + iarr[1]),\n                    dval * (ival + iarr[2])]);\n\n    oarr[] = (iarr[] & ival) / dval;\n    assert(oarr == [(iarr[0] & ival) / dval,\n                    (iarr[1] & ival) / dval,\n                    (iarr[2] & ival) / dval]);\n\n    oarr[] = darr[] + iarr[];\n    assert(oarr == [darr[0] + iarr[0],\n                    darr[1] + iarr[1],\n                    darr[2] + iarr[2]]);\n\n    oarr[] = iarr[] - darr[];\n    assert(oarr == [iarr[0] - darr[0],\n                    iarr[1] - darr[1],\n                    iarr[2] - darr[2]]);\n\n    oarr[] = darr[] * (ival & iarr[]);\n    assert(oarr == [darr[0] * (ival & iarr[0]),\n                    darr[1] * (ival & iarr[1]),\n                    darr[2] * (ival & iarr[2])]);\n\n    oarr[] = (iarr[] ^ ival) / darr[];\n    assert(oarr == [(iarr[0] ^ ival) / darr[0],\n                    (iarr[1] ^ ival) / darr[1],\n                    (iarr[2] ^ ival) / darr[2]]);\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13497\n\nvoid test13497()\n{\n    int[1] a = [2], b = [3];\n    int[1] c1 =  a[] * b[];\n    int[1] c2 = (a[] * b[])[];\n    assert(c1 == [6]);\n    assert(c2 == [6]);\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14649\n\nvoid test14649()\n{\n    char[] a = \"abc\".dup;\n    char[] b = [char(1), char(2), char(3)];\n    string x = \"abc\";\n    string y = [char(1), char(2), char(3)];\n    char[] r = new char[](3);\n\n    r[] = a[] + b[];\n    assert(r == \"bdf\");\n\n    r[] = x[] + y[];\n    assert(r == \"bdf\");\n\n    r[] = \"hel\"[] + \"lo.\"[];\n    assert(r == [('h'+'l'), ('e'+'o'), ('l'+'.')]);\n\n    enum s = \"abc\";\n    r[] = s[0..3] + \"def\"[0..3];\n    assert(r == [('a'+'d'), ('b'+'e'), ('c'+'f')]);\n}\n\n/************************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14851\n\nvoid test14851()\n{\n    int[8] a, b, c;\n\n    c   = a[] | b[];    // OK <- NG from 2.068.0-b2\n    c   = a[] ^ b[];    // OK <- NG from 2.068.0-b2\n\n    c[] = a[] | b[];    // OK\n    c[] = a[] ^ b[];    // OK\n}\n\n/************************************************************************/\n\nint main()\n{\n    version(X86)\n    {\n        test1();\n        test2();\n    }\n    else version(X86_64)\n    {\n        test1();\n        test2();\n    }\n    else\n    {\n        pragma(msg, \"arrayop.d:test1 Test skipped because arrayop evaluation\" ~\n                    \" order is ill-defined. See GDC issue #8\");\n    }\n    test3();\n    test4();\n    test5();\n    test6();\n    test8390();\n    test8651();\n    test9656();\n    test10282();\n    test10433();\n    test10684a();\n    test10684b();\n    test11525();\n    test12250();\n    test12780();\n    test13497();\n    test14649();\n    test14851();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n\nversion (none)\n{\nextern (C) T[] _arraySliceSliceAddSliceAssignd(T[] a, T[] c, T[] b)\n{\n    foreach (i; 0 .. a.length)\n        a[i] = b[i] + c[i];\n    return a;\n}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/auto1.d",
    "content": "\nimport core.stdc.stdio;\n\n/******************************************/\n\nscope class Foo\n{\n    static int x;\n\n    ~this()\n    {\n        printf(\"Foo.~this()\\n\");\n        x++;\n    }\n}\n\nint test1x()\n{\n    scope Foo f = new Foo();\n    return 6;\n}\n\n\nvoid test1()\n{\n    {\n        scope Foo f = new Foo();\n    }\n    int c;\n\n    assert(Foo.x == 1);\n    c = test1x();\n    assert(c == 6);\n    assert(Foo.x == 2);\n\n    if (c != 6)\n        scope Foo h = new Foo();\n    assert(Foo.x == 2);\n\n    if (c == 6)\n        scope Foo j = new Foo();\n    assert(Foo.x == 3);\n\n    {\n        scope Foo g = null, k = new Foo();\n        assert(Foo.x == 3);\n    }\n    assert(Foo.x == 4);\n}\n\n/******************************************/\n\nint ax;\n\nscope class A2\n{\n  this()\n  {\n    printf(\"A2.this()\\n\");\n    ax += 1;\n  }\n\n  ~this()\n  {\n    printf(\"A2.~this()\\n\");\n    ax += 1000;\n  }\n};\n\n\nvoid test2()\n{\n  {\n    scope A2 a = new A2();\n    printf(\"Hello world.\\n\");\n  }\n  assert(ax == 1001);\n}\n\n\n\n/******************************************/\n\nint status3;\n\nscope class Parent3\n{\n}\n\nscope class Child3 : Parent3\n{\n        this(){\n                assert(status3==0);\n                status3=1;\n        }\n\n        ~this(){\n                assert(status3==1);\n                status3=2;\n        }\n}\n\nvoid foo3()\n{\n        scope Parent3 o = new Child3();\n        assert(status3==1);\n}\n\nvoid test3()\n{\n        foo3();\n        assert(status3==2);\n}\n\n/******************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/b16278.d",
    "content": "// REQUIRED_ARGS: -main\nclass A()\n{\n    static struct S { A a; }\n}\nenum e = is(A!());\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/b17073.d",
    "content": "struct S0\n{\n    int x = void;\n}\nstruct S1\n{\n    S0  x = S0(42);\n}\nvoid main()\n{\n    S1  x;\n    assert(x.x.x == 42);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/b18034.d",
    "content": "// REQUIRED_ARGS: -O\nversion (D_SIMD)\n{\n    import core.simd;\n\n    void check(void16 a) \n    {\n        foreach (x; (cast(ushort8)a).array) \n        {\n\t        assert(x == 1);\n        }\n    }\n\n    void make(ushort x) \n    {\n        ushort8 v = ushort8(x);\n        check(v);\n    }\n\n    void main() \n    {\t\n        make(1);\n    }\n}\nelse\n{\n    void main() { }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/b26.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/b26a.d\n// PERMUTE_ARGS:\n\n// https://issues.dlang.org/show_bug.cgi?id=382\n\nstruct List(T) {\n        interface A {}\n}\n\nint main(char[][] args) {\n        List!(char) list;\n        return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/b6400.d",
    "content": "/* TEST_OUTPUT:\n---\nFoo\nBar\nFoo\nBar\nBar\nFoo\nBar\n---\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=6400\n\nenum int base(string name) = 10 * (name[$-1] - '0');\nstruct Foo { int opDispatch(string name)() { pragma(msg, \"Foo\"); return base!name + 1; } }\nstruct Bar { int opDispatch(string name)() { pragma(msg, \"Bar\"); return base!name + 2; } }\nstruct Baz {  }\n\nvoid main()\n{\n    assert(test());\n    static assert(test());\n}\n\nbool test()\n{\n    auto foo = new Foo;\n    auto bar = new Bar;\n    auto baz = new Baz;\n\n    with (foo)\n    {\n        assert(f1() == 11);\n        with (baz) assert(f1() == 11);\n        with (bar)\n        {\n            assert(f2() == 22);\n            with (baz) assert(f2() == 22);\n            with (foo)\n            {\n                assert(f3() == 31);\n                with (baz) assert(f3() == 31);\n                with (bar)\n                {\n                    assert(f4() == 42);\n                    with (baz) assert(f4() == 42);\n                    with (baz)\n                    {\n                        assert(f5() == 52);\n                        with (baz) assert(f5() == 52);\n                    }\n                    with (foo)\n                    {\n                        assert(f6() == 61);\n                        with (baz) assert(f6() == 61);\n                    }\n                    with (bar)\n                    {\n                        assert(f7() == 72);\n                        with (baz) assert(f7() == 72);\n                    }\n                }\n            }\n        }\n    }\n\n    return true;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/bcraii.d",
    "content": "/* REQUIRED_ARGS: -betterC\n * PERMUTE_ARGS:\n */\n\nimport core.stdc.stdio;\n\nextern (C) int main()\n{\n    auto j = test(1);\n    assert(j == 3);\n    return 0;\n}\n\nint test(int i) nothrow\n{\n  {\n    int j = i ? S(3).i : 3;\n    printf(\"inside\\n\");\n    assert(Sctor == 1);\n    assert(Sdtor == 1);\n    return j;\n  }\n  printf(\"done\\n\");\n  return -1;\n}\n\n__gshared int Sctor;\n__gshared int Sdtor;\n\nstruct S\n{\n    int i;\n    this(int i) nothrow\n    {\n        this.i += i;\n        printf(\"S.this()\\n\");\n        ++Sctor;\n    }\n\n    ~this() nothrow\n    {\n        assert(i == 3);\n        i = 0;\n        printf(\"S.~this()\\n\");\n        ++Sdtor;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/bcraii2.d",
    "content": "/* REQUIRED_ARGS: -betterC\n * PERMUTE_ARGS:\n */\n\nimport core.stdc.stdio;\n\nextern (C) int main()\n{\n    auto j = test(1);\n    assert(j == 3);\n    assert(Sdtor == 1);\n\n    test2();\n    return 0;\n}\n\nint test(int i) nothrow\n{\n  {\n    S s = S(3);\n    printf(\"inside\\n\");\n    assert(Sctor == 1);\n    assert(Sdtor == 0);\n    return s.i;\n  }\n  printf(\"done\\n\");\n  return -1;\n}\n\n__gshared int Sctor;\n__gshared int Sdtor;\n\nstruct S\n{\n    int i;\n    this(int i) nothrow\n    {\n        this.i += i;\n        printf(\"S.this()\\n\");\n        ++Sctor;\n    }\n\n    ~this() nothrow\n    {\n        assert(i == 3);\n        i = 0;\n        printf(\"S.~this()\\n\");\n        ++Sdtor;\n    }\n}\n\n/*************************************/\n\nvoid test2()\n{\n    int i = 3;\n    try\n    {\n        try\n        {\n            ++i;\n            goto L10;\n        }\n        finally\n        {\n            i *= 2;\n            printf(\"f1\\n\");\n        }\n    }\n    finally\n    {\n        i += 5;\n        printf(\"f2\\n\");\n    }\n\nL10:\n    printf(\"3\\n\");\n    assert(i == (3 + 1) * 2 + 5);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/bench1.d",
    "content": "// REQUIRED_ARGS:\n// EXECUTE_ARGS: 10000\n\nextern(C) int printf(const char *, ...);\nextern(C) int atoi(const char *);\n\n    int main (string[] argv)\n    {\n        string s = \"\";\n        int count, loop;\n\n        count = atoi((argv[1] ~ '\\0').ptr);\n        if (count == 0)\n            count = 1;\n        printf(\"count = %u\\n\", count);\n\n        for (loop = 0; loop < count; loop ++)\n            s ~= \"hello\\n\";\n        for (loop = 0; loop < count; loop ++)\n            s ~= \"h\";\n        printf (\"%d\\n\", s.length);\n        //printf(\"%.*s\\n\", s[0..100]);\n        assert(s.length == count * (6 + 1));\n        s.length = 3;\n        s.length = 10;\n        s.length = 0;\n        s.length = 1000;\n        return 0;\n    }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/betterc.d",
    "content": "/* REQUIRED_ARGS: -betterC\n   PERMUTE_ARGS:\n */\n\n\nvoid test(int ij)\n{\n    assert(ij);\n#line 100 \"anotherfile\"\n    assert(ij,\"it is not zero\");\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17843\n\nstruct S\n{\n    double d = 0.0;\n    int[] x;\n}\n\n/*******************************************/\n\nextern (C) void main()\n{\n    test(1);\n    test18472();\n    testRuntimeLowerings();\n    test18457();\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17605\n\nextern (C) void test17605()\n{\n    int a;\n    enum bool works = __traits(compiles, { a = 1; });\n    a = 1;\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18472\n\nvoid test18472()\n{\n    version(D_LP64)\n    {\n        enum b = typeid(size_t) is typeid(ulong);\n    }\n    else\n    {\n        enum b = typeid(size_t) is typeid(uint);\n    }\n\n    assert(b);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18493\n\nstruct S18493\n{\n    this(this) nothrow { }  // Since this is attributed with `nothrow` there should be no error about using\n                            // try-catch with -betterC\n    ~this() { }\n}\n\nstruct S18493_2\n{\n    S18493 s1;\n    S18493 s2;\n}\n\n/******************************************************\n * tests to ensure there is sufficient runtime support\n * in imported object.d\n */\nmixin template initArray()\n{\n    static if (is(T == bool))\n    {\n        T[6] a1 = [true, false, true, true, false, true];\n    }\n    else static if (is(T == Sint))\n    {\n        T[6] a1 = [Sint(1), Sint(2), Sint(3), Sint(1), Sint(2), Sint(3)];\n    }\n    else\n    {\n        T[6] a1 = [1,2,3,1,2,3];\n    }\n}\n\nstruct Sint\n{\n    int x;\n    this(int v) { x = v;}\n}\n\nvoid testRuntimeLowerings()\n{\n    // test call to `object.__equals`\n    void test__equals(T)()\n    {\n        mixin initArray;\n\n        assert(a1[0..3] == a1[3..$]);\n    }\n\n    test__equals!int;\n    test__equals!uint;\n    test__equals!long;\n    test__equals!ulong;\n    test__equals!short;\n    test__equals!ushort;\n    test__equals!byte;\n    test__equals!dchar;\n    test__equals!wchar;\n    test__equals!ubyte;\n    test__equals!char;\n    test__equals!(const char);\n    test__equals!bool;\n    test__equals!Sint;\n\n    // test call to `object.__cmp`\n    void test__cmp(T)()\n    {\n        mixin initArray;\n\n        assert(a1[0..3] >= a1[3..$]);\n        assert(a1[0..3] <= a1[3..$]);\n    }\n\n    test__cmp!int;\n    test__cmp!uint;\n    test__cmp!long;\n    test__cmp!ulong;\n    test__cmp!short;\n    test__cmp!ushort;\n    test__cmp!byte;\n    test__cmp!dchar;\n    test__cmp!wchar;\n    test__cmp!ubyte;\n    test__cmp!char;\n    test__cmp!(const char);\n    test__cmp!bool;\n    test__cmp!Sint;\n\n    // test call to `object.__switch``\n    auto s = \"abc\";\n    switch(s)\n    {\n        case \"abc\":\n            break;\n        default:\n            break;\n    }\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18457\n\n__gshared int dtor;\n\nstruct S18457\n{\n    int a = 3;\n    ~this() { a = 0; ++dtor; }\n}\n\nS18457 myFunction()\n{\n    S18457 s = S18457();\n    return s;\n}\n\nvoid test18457()\n{\n    {\n        S18457 s = myFunction();\n        assert(s.a == 3);\n        assert(dtor == 0);\n    }\n    assert(dtor == 1);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/bitops.d",
    "content": "// PERMUTE_ARGS:\n\nimport core.stdc.stdio;\nimport core.bitop;\n\n/*****************************************************/\n\nvoid test1()\n{\n    size_t[2] array;\n    uint x;\nversion (D_LP64)\n    size_t bitToUse = 67;\nelse\n    size_t bitToUse = 35;\n\n    array[0] = 2;\n    array[1] = 0x100;\n    printf(\"array = [0]:x%x, [1]:x%x\\n\", array[0], array[1]);\n\n    x = btc(array.ptr, bitToUse);\n    printf(\"btc(array, %d) = %d\\n\", bitToUse, x);\n    printf(\"array = [0]:x%x, [1]:x%x\\n\", array[0], array[1]);\n    assert(x == 0);\n    assert(array[0] == 0x2 && array[1] == 0x108);\n\n    x = btc(array.ptr, bitToUse);\n    printf(\"btc(array, %d) = %d\\n\", bitToUse, x);\n    printf(\"array = [0]:x%x, [1]:x%x\\n\", array[0], array[1]);\n    assert(x != 0);\n    assert(array[0] == 2 && array[1] == 0x100);\n\n    x = bts(array.ptr, bitToUse);\n    printf(\"bts(array, %d) = %d\\n\", bitToUse, x);\n    printf(\"array = [0]:x%x, [1]:x%x\\n\", array[0], array[1]);\n    assert(x == 0);\n    assert(array[0] == 2 && array[1] == 0x108);\n\n    x = btr(array.ptr, bitToUse);\n    printf(\"btr(array, %d) = %d\\n\", bitToUse, x);\n    printf(\"array = [0]:x%x, [1]:x%x\\n\", array[0], array[1]);\n    assert(x != 0);\n    assert(array[0] == 2 && array[1] == 0x100);\n\n    x = bt(array.ptr, 1);\n    printf(\"bt(array, 1) = %d\\n\", x);\n    printf(\"array = [0]:x%x, [1]:x%x\\n\", array[0], array[1]);\n    assert(x != 0);\n    assert(array[0] == 2 && array[1] == 0x100);\n}\n\n/*****************************************************/\n\nvoid test2()\n{\n    uint v;\n    int x;\n\n    v = 0x21;\n    x = bsf(v);\n    printf(\"bsf(x%x) = %d\\n\", v, x);\n    assert(x == 0);\n\n    x = bsr(v);\n    printf(\"bsr(x%x) = %d\\n\", v, x);\n    assert(x == 5);\n}\n\n/*****************************************************/\n\nversion (DigitalMars)\nvoid test3()\n{   uint v;\n    int b;\n\n    b = inp(b);\n    b = inpw(b);\n    b = inpl(b);\n\n    b = outp(v, cast(ubyte)b);\n    b = outpw(v, cast(ushort)b);\n    b = outpl(v, b);\n}\n\n/*****************************************************/\n\nvoid test4()\n{\n    uint i = 0x12_34_56_78;\n    i = bswap(i);\n    assert(i == 0x78_56_34_12);\n}\n\n/*****************************************************/\n\nvoid test5()\n{\n    size_t[2] array;\n\n    array[0] = 2;\n    array[1] = 0x100;\n\n    printf(\"btc(array, 35) = %d\\n\", btc(array.ptr, 35));\n    printf(\"array = [0]:x%x, [1]:x%x\\n\", array[0], array[1]);\n\n    printf(\"btc(array, 35) = %d\\n\", btc(array.ptr, 35));\n    printf(\"array = [0]:x%x, [1]:x%x\\n\", array[0], array[1]);\n\n    printf(\"bts(array, 35) = %d\\n\", bts(array.ptr, 35));\n    printf(\"array = [0]:x%x, [1]:x%x\\n\", array[0], array[1]);\n\n    printf(\"btr(array, 35) = %d\\n\", btr(array.ptr, 35));\n    printf(\"array = [0]:x%x, [1]:x%x\\n\", array[0], array[1]);\n\n    printf(\"bt(array, 1) = %d\\n\", bt(array.ptr, 1));\n    printf(\"array = [0]:x%x, [1]:x%x\\n\", array[0], array[1]);\n}\n\n\n/*****************************************************/\n\nclass Node {\n  uint leaf = 0;\n\n  int m() {\n        return leaf ? 0 : bsf(leaf);\n  }\n}\n\nvoid test6()\n{\n    Node n = new Node();\n}\n\n/*****************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    //test3();\n    test4();\n    test5();\n    test6();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/bug11155.d",
    "content": "// PERMUTE_ARGS:\n\nversion(D_SIMD)\n{\n    alias float4 = __vector(float[4]);\n\n    void foo(float4* ptr, float4 val)\n    {\n        assert((cast(ulong) &val & 0xf) == 0);\n    }\n\n    void main()\n    {\n        float4 v;\n        foo(&v, v);\n    }\n}\nelse\n    void main(){}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/bug12928.d",
    "content": "// PERMUTE_ARGS: -inline -g -O\nimport core.exception : RangeError;\nvoid main(string[] args)\n{\n  int[2] a;\n  try\n  {\n    foreach(const i; 0..3)\n      a[i] = i;\n    assert(0);\n  }\n  catch(RangeError){}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/bug16146.d",
    "content": "struct X {\n  int* rc;\n  this (int n) { auto x = new int[](1); rc = x.ptr; *rc = n; }\n  this (this)  { ++*rc; }\n  ~this ()     { --*rc; }\n  @disable void opAssign (X src);\n}\n\nstruct Y {\n  X x;\n}\n\nvoid frob(X x)\n{\n    Y y = { x: x };\n    // The 'rc' counter starts from 1 and gets bumped when:\n    // - 'f0' is passed to 'frob'\n    // - 'y' is initialized with 'x'\n    assert(*y.x.rc == 3);\n}\n\nvoid main ()\n{\n    auto f0 = X(1);\n    frob(f0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/bug5.d",
    "content": "// REQUIRED_ARGS: -w\n\nclass F { }\n\nint test1() {\n    scope F f = new F(); // comment out and warning goes away\n    return 0;\n}\n\nint test2() { // no return at end of function\n    try {\n        return 0;\n    } finally { }\n}\n\nvoid main()\n{\n    test1();\n    test2();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/bug7068.d",
    "content": "// PERMUTE_ARGS: -inline -g -O -d\nvoid main()\n{\n    auto darray1 = new int*[](10);\n    foreach(ref v; darray1)\n        v = new int;\n    auto darray2 = new int*[](10);\n    darray2[] = darray1[]; // calls memset instead of memcpy\n    foreach(i; 0 .. 10)\n        assert(darray1[i] == darray2[i]);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/bug846.d",
    "content": "// see also: bug 8\n// EXTRA_SOURCES: imports/bug846.d\n\nimport imports.bug846;\n\nvoid main()\n{\n    auto num = removeIf( \"abcdef\".dup, ( char c ) { return c == 'c'; } );\n    assert(num == 5);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/builtin.d",
    "content": "\nimport std.stdio;\nimport std.math;\nimport core.bitop;\n\nversion (DigitalMars)\n{\n    version (X86_64)\n        version = AnyX86;\n    else version (X86)\n        version = AnyX86;\n}\n\n/*******************************************/\n\nvoid test1()\n{\n    writefln(\"%a\", sin(6.8L));\n    auto f = 6.8L;\n    writefln(\"%a\", sin(f));\n    assert(sin(f) == sin(6.8L));\n    static assert(approxEqual(sin(6.8L), 0x1.f9f8d9aea10fdf1cp-2));\n\n    writefln(\"%a\", cos(6.8L));\n    f = 6.8L;\n    writefln(\"%a\", cos(f));\n    assert(cos(f) == cos(6.8L));\n    static assert(approxEqual(cos(6.8L), 0x1.bd21aaf88dcfa13ap-1));\n\n    writefln(\"%a\", tan(6.8L));\n    f = 6.8L;\n    writefln(\"%a\", tan(f));\n    version (Win64)\n    { }\n    else\n        assert(tan(f) == tan(6.8L));\n    static assert(approxEqual(tan(6.8L), 0x1.22fd752af75cd08cp-1));\n}\n\n/*******************************************/\n\nvoid test2()\n{\n    float i = 3;\n    i = i ^^ 2;\n    assert(i == 9);\n\n    int j = 2;\n    j = j ^^ 1;\n    assert(j == 2);\n\n    i = 4;\n    i = i ^^ .5;\n    assert(i == 2);\n}\n\n/**** https://issues.dlang.org/show_bug.cgi?id=5703 ****/\n\nstatic assert({\n    int a = 0x80;\n    int f = bsf(a);\n    int r = bsr(a);\n    a = 0x22;\n    assert(bsf(a)==1);\n    assert(bsr(a)==5);\n    a = 0x8000000;\n    assert(bsf(a)==27);\n    assert(bsr(a)==27);\n    a = 0x13f562c0;\n    assert(bsf(a) == 6);\n    assert(bsr(a) == 28);\n    assert(bswap(0xAABBCCDD) == 0xDDCCBBAA);\n    return true;\n}());\n\n/*******************************************/\n\nvoid test3()\n{\n    version (AnyX86)\n    {\n        static assert( _popcnt( cast(ushort)0 ) == 0 );\n        static assert( _popcnt( cast(ushort)7 ) == 3 );\n        static assert( _popcnt( cast(ushort)0xAA )== 4);\n        static assert( _popcnt( cast(ushort)0xFFFF ) == 16 );\n        static assert( _popcnt( cast(ushort)0xCCCC ) == 8 );\n        static assert( _popcnt( cast(ushort)0x7777 ) == 12 );\n        static assert( _popcnt( cast(uint)0 ) == 0 );\n        static assert( _popcnt( cast(uint)7 ) == 3 );\n        static assert( _popcnt( cast(uint)0xAA )== 4);\n        static assert( _popcnt( cast(uint)0x8421_1248 ) == 8 );\n        static assert( _popcnt( cast(uint)0xFFFF_FFFF ) == 32 );\n        static assert( _popcnt( cast(uint)0xCCCC_CCCC ) == 16 );\n        static assert( _popcnt( cast(uint)0x7777_7777 ) == 24 );\n        version (X86_64)\n        {\n            static assert( _popcnt( cast(ulong)0 ) == 0 );\n            static assert( _popcnt( cast(ulong)7 ) == 3 );\n            static assert( _popcnt( cast(ulong)0xAA )== 4);\n            static assert( _popcnt( cast(ulong)0x8421_1248 ) == 8 );\n            static assert( _popcnt( cast(ulong)0xFFFF_FFFF_FFFF_FFFF ) == 64 );\n            static assert( _popcnt( cast(ulong)0xCCCC_CCCC_CCCC_CCCC ) == 32 );\n            static assert( _popcnt( cast(ulong)0x7777_7777_7777_7777 ) == 48 );\n        }\n    }\n}\n\n/*******************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/c22.d",
    "content": "// EXTRA_SOURCES: imports/c22a.d imports/c22b.d\n// PERMUTE_ARGS:\n\nmodule main;\n\nimport imports.c22a;\nimport imports.c22b;\n\nint main()\n{\n    afn1();\n    afn2();\n    bfn1();\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/cabi1.d",
    "content": "\n// EXTRA_CPP_SOURCES: extra-files/cabi2.cpp\n\nimport core.stdc.stdio;\nimport core.stdc.config;\n\nstruct Foo1 { char c; }\nstruct Foo2 { short s; }\nstruct Foo3 { char c; short s; }\nstruct Foo4 { int i; }\nstruct Foo5 { int i, j; }\nstruct Foo6 { int i, j, k; }\nstruct S7 { float a, b; }\n\nextern (C) Foo1 ctest1();\nextern (C) Foo2 ctest2();\nextern (C) Foo3 ctest3();\nextern (C) Foo4 ctest4();\nextern (C) Foo5 ctest5();\nextern (C) Foo6 ctest6();\nextern (C) S7 ctest10();\n\nversion(Windows)\n    version = Windows_or_32bit;\nelse version(X86)\n    version = Windows_or_32bit;\n\n\nvoid test1()\n{\n    Foo1 f1 = ctest1();\n    assert(f1.c == 3);\n\n    Foo2 f2 = ctest2();\n    assert(f2.s == 0x1234);\n\n    Foo3 f3 = ctest3();\n    assert(f3.s == 0x5678);\n\n    Foo4 f4 = ctest4();\n    assert(f4.i == 0x12345678);\n\n    Foo5 f5 = ctest5();\n    assert(f5.i == 0x12345678);\n    assert(f5.j == 0x21436587);\n\nversion(Windows_or_32bit)\n{\n    Foo6 f6 = ctest6();\n    assert(f6.i == 0x12345678);\n    assert(f6.j == 0x21463587);\n    assert(f6.k == 0x24163857);\n}\n\n    S7 s7 = ctest10();\n    assert(s7.a == 2.5);\n    assert(s7.b == 1.5);\n}\n\n/*******************************************/\n\nextern (C)\n{\n    char ctest7(char);\n    ubyte ctest8(ubyte);\n    byte ctest9(byte);\n}\n\nvoid test2()\n{\n    assert(ctest7('a') == 'b');\n    assert(ctest8(7) == 8);\n    assert(ctest9(3) == 4);\n}\n\n/******************************************/\n\nextern (C)\n{\n    void ctestrir(int x1, int x2, int x3, int x4, int x5, int x6, c_long_double a, int b, c_long_double c);\n}\n\nvoid test3()\n{\n    ctestrir(1,2,3,4,5,6, c_long_double(100.0), 67, c_long_double(200.0));\n}\n\n/******************************************/\n\nextern (C) void dtestrir(int x1, int x2, int x3, int x4, int x5, int x6, c_long_double a, int b, c_long_double c)\n{\n    assert(a == 300.0);\n    assert(b == 68);\n    assert(c == 401.0);\n}\n\nextern (C) void test4();\n\n/******************************************/\n\nstruct S11 { ubyte a, b, c; }\n\nextern (C) S11 ctest11(ubyte x, S11, ubyte y);\n\nvoid test11()\n{\n  version (X86)\n  {\n  S11 t;\n  assert(S11.sizeof == 3);\n  t.a = 2;\n  t.b = 3;\n  t.c = 4;\n  auto s = ctest11(1, t, 5);\n  assert(s.a == 2);\n  assert(s.b == 3);\n  assert(s.c == 4);\n  }\n}\n\n/******************************************/\n\nstruct S12 { char a,d; char b,e; ubyte c; }\n\nextern (C) S12 ctest12(ubyte x, S12, ubyte y);\n\nvoid test12()\n{\n  version (X86)\n  {\n  S12 t;\n  printf(\"D sz = %d\\n\", cast(int)S12.sizeof);\n//  assert(S12.sizeof == 5);\n  t.a = 2;\n  t.b = 3;\n  t.c = 4;\n  auto s = ctest12(1, t, 5);\n  assert(s.a == 2);\n  assert(s.b == 3);\n  assert(s.c == 4);\n  }\n}\n\n/******************************************/\n\nstruct S13 { ushort a, b, c; }\n\nextern (C) S13 ctest13(ubyte x, S13, ubyte y);\n\nvoid test13()\n{\n  version (X86)\n  {\n  S13 t;\n  assert(S13.sizeof == 6);\n  t.a = 2;\n  t.b = 3;\n  t.c = 4;\n  auto s = ctest13(1, t, 5);\n  assert(s.a == 2);\n  assert(s.b == 3);\n  assert(s.c == 4);\n  }\n}\n\n/******************************************/\n\nstruct S14 { char a,d,e,f; char b,g; ubyte c; }\n\nextern (C) S14 ctest14(ubyte x, S14, ubyte y);\n\nvoid test14()\n{\n  version (X86)\n  {\n  S14 t;\n  assert(S14.sizeof == 7);\n  t.a = 2;\n  t.b = 3;\n  t.c = 4;\n  auto s = ctest14(1, t, 5);\n  assert(s.a == 2);\n  assert(s.b == 3);\n  assert(s.c == 4);\n  }\n}\n\n/******************************************/\n\nstruct S15 { char a,d,e,f; char b,g,h,i; ubyte c; }\n\nextern (C) S15 ctest15(ubyte x, S15, ubyte y);\n\nvoid test15()\n{\n  version (X86)\n  {\n  S15 t;\n  assert(S15.sizeof == 9);\n  t.a = 2;\n  t.b = 3;\n  t.c = 4;\n  auto s = ctest15(1, t, 5);\n  assert(s.a == 2);\n  assert(s.b == 3);\n  assert(s.c == 4);\n  }\n}\n\n/******************************************/\n\n// see https://issues.dlang.org/show_bug.cgi?id=17277\nstruct S16 {\n  char[5] a;\n  struct {\n    char b;\n    align(1) int c;\n  }\n}\n\nextern (C) S16 ctest16(ubyte x, S16, ubyte y);\n\nvoid test16()\n{\n  version (X86) // misaligned field\n  {\n  S16 t;\n  assert(S16.sizeof == 10);\n  assert(S16.alignof == 1);\n  t.a = \"hello\";\n  t.b = 3;\n  t.c = 0x11223344;\n  auto s = ctest16(1, t, 5);\n  assert(s.a == \"hello\");\n  assert(s.b == 3);\n  assert(s.c == 0x11223344);\n  }\n}\n\n/******************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\nversion (Win64)\n{\n}\nelse\n{\n    test4();\n}\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/casting.d",
    "content": "extern(C) int printf(const char*, ...);\n\ntemplate Seq(T...) { alias T Seq; }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3133\n\nvoid test3133()\n{\n    short[2] x = [1, 2];\n    auto y = cast(int[1])x;     // no error\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7504\n\nvoid test7504() pure nothrow @safe\n{\n    auto n = null;\n    char[] k = n;\n    assert(k.ptr == null);\n    assert(k.length == 0);\n\n    double[] l;\n    l = n;\n    assert(l.ptr == null);\n    assert(l.length == 0);\n\n    immutable(int[]) m = n;\n    assert(m.ptr == null);\n    assert(m.length == 0);\n\n    const(float)[] o;\n    o = n;\n    assert(o.ptr == null);\n    assert(o.length == 0);\n\n    auto c = create7504(null, null);\n    assert(c.k.ptr == null);\n    assert(c.k.length == 0);\n    assert(c.l.ptr == null);\n    assert(c.l.length == 0);\n}\n\nclass C7504\n{\n    int[] k;\n    string l;\n}\n\nC7504 create7504(T...)(T input)\n{\n    auto obj = new C7504;\n    obj.tupleof = input;\n    return obj;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8119\n\nstruct S8119;\n\nvoid test8119()\n{\n    void* v;\n    auto sp1 = cast(S8119*)v;\n\n    int* i;\n    auto sp2 = cast(S8119*)i;\n\n    S8119* s;\n    auto ip = cast(int*)s;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8645\n\ntemplate TypeTuple8645(TL...)\n{\n    alias TL TypeTuple8645;\n}\n\nvoid test8645()\n{\n    alias TypeTuple8645!(int) Foo;\n    int bar;\n    static assert(!is(typeof( cast(Foo)bar )));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10497\n\nstruct S10497;\n\nvoid test10497(S10497** s)\n{\n    void* ptr;\n    *s = cast(S10497*)ptr;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10793\n\nstruct RealFoo10793\n{\n    int i;\n}\n\nstruct Foo10793;\n\nvoid test10793()\n{\n    auto rf = RealFoo10793(10);\n    void* prf = cast(void*)&rf;\n    Foo10793* f = cast(Foo10793*)prf;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10834\n\nvoid test10834()\n{\n    struct S { int i; }\n    S s;\n    cast(void)s;\n\n    class C { int i; }\n    C c;\n    cast(void)c;\n\n    enum E { a, b }\n    E e;\n    cast(void)e;\n\n    int[] ia;\n    cast(void)ia;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10842\n\ntemplate Test10842(F, T)\n{\n    bool res;\n    F from()\n    {\n        res = true;\n        return F.init;\n    }\n    T to()\n    {\n        // The cast operand had incorrectly been eliminated\n        return cast(T)from();\n    }\n    bool test()\n    {\n        res = false;\n        to();\n        return res;\n    }\n}\n\nvoid test10842()\n{\n    foreach (From; Seq!(bool, byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real))\n    {\n        foreach (To; Seq!(ifloat, idouble, ireal))\n        {\n            if (!Test10842!(From, To).test())\n                assert(0);\n        }\n    }\n\n    foreach (From; Seq!(ifloat, idouble, ireal))\n    {\n        foreach (To; Seq!(/*bool*, */byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real))\n        {\n            if (!Test10842!(From, To).test())\n                assert(0);\n        }\n    }\n\n    if (!Test10842!(typeof(null), string).test())   // 10842\n        assert(0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11722\n\nclass C11722\n{\n    T opCast(T)() { assert(0); }\n}\n\nvoid test11722()\n{\n    C11722 c = new C11722();\n    shared C11722 sc = cast(shared)c;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14218\n\nvoid test14218()\n{\n    foreach (To; Seq!( byte,  short,  int,  long,\n                      ubyte, ushort, uint, ulong,\n                       char,  wchar, dchar, bool))\n    {\n        auto x = cast(To)null;\n        assert(x == 0);     // false, '0x00'\n    }\n\n    version (DigitalMars)\n    {\n        // Questionable but currently accepted by DMD (but not GDC).\n        foreach (To; Seq!( float,  double,  real,\n                           ifloat, idouble, ireal))\n        {\n            auto x = cast(To)null;\n            assert(x == 0);     // 0i\n        }\n\n        // Internal error: backend/el.c in el_long()\n        //foreach (To; Seq!(cfloat, cdouble, creal))\n        //{\n        //    static assert(!__traits(compiles, { auto x = cast(To)null; }));\n        //}\n    }\n}\n\n/***************************************************/\n\nint main()\n{\n    test3133();\n    test7504();\n    test8119();\n    test8645();\n    test10793();\n    test10834();\n    test10842();\n    test11722();\n    test14218();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/circular.d",
    "content": "// REQUIRED_ARGS: -d\n// PERMUTE_ARGS: -dw\n// EXTRA_SOURCES: imports/circularA.d\n// This bug is typedef-specific.\n\n// https://issues.dlang.org/show_bug.cgi?id=4543\n\nimport core.stdc.stdio;\nimport imports.circularA;\n\nclass bclass {};\nalias bclass Tclass;\n\nstruct bstruct {}\nalias bstruct Tstruct;\n\n\n/************************************/\n\nint main()\n{\n    printf(\"Success\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/closure.d",
    "content": "\nimport core.stdc.stdio;\n\nstruct S { int a,b,c,d; }\n\nalias int delegate() dg_t;\nalias int delegate(int) dg1_t;\n\nvoid fill()\n{\n    int[100] x;\n}\n\n/************************************/\n\ndg_t foo()\n{\n    int x = 7;\n\n    int bar()\n    {\n        return x + 3;\n    }\n\n    return &bar;\n}\n\nvoid test1()\n{\n    dg_t dg = foo();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 10);\n}\n\n/************************************/\n\ndg_t foo2()\n{\n    dg_t abc()\n    {\n        int x = 7;\n\n        int bar()\n        {\n            return x + 3;\n        }\n\n        return &bar;\n    }\n\n    return abc();\n}\n\nvoid test2()\n{\n    dg_t dg = foo2();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 10);\n}\n\n/************************************/\n\ndg_t foo3()\n{\n    dg_t abc(int x)\n    {\n        int bar()\n        {\n            return x + 3;\n        }\n\n        return &bar;\n    }\n\n    return abc(7);\n}\n\nvoid test3()\n{\n    dg_t dg = foo3();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 10);\n}\n\n/************************************/\n\ndg_t foo4()\n{\n    S s;\n\n    s = S(4,5,6,7);\n\n    dg_t abc(S t)\n    {\n        int bar()\n        {\n            return t.d + 3;\n        }\n\n        return &bar;\n    }\n\n    return abc(s);\n}\n\nvoid test4()\n{\n    dg_t dg = foo4();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 10);\n}\n\n/************************************/\n\nvoid test5()\n{\n    int x = 7;\n\n    dg_t abc(ref int y)\n    {\n        int bar()\n        {\n            y += 4;\n            return y + 3;\n        }\n\n        return &bar;\n    }\n\n    dg_t dg = abc(x);\n    fill();\n    assert(x == 7);\n    auto i = dg();\n    assert(x == 11);\n    assert(i == 14);\n\n    x = 8;\n    i = dg();\n    assert(x == 12);\n    assert(i == 15);\n}\n\n/************************************/\n\nvoid test6()\n{\n    int x = 7;\n\n    dg_t abc(out int y)\n    {\n        int bar()\n        {\n            y += 4;\n            return y + 3;\n        }\n\n        return &bar;\n    }\n\n    dg_t dg = abc(x);\n    fill();\n\n    assert(x == 0);\n    auto i = dg();\n    assert(x == 4);\n    assert(i == 7);\n\n    x = 8;\n    i = dg();\n    assert(x == 12);\n    assert(i == 15);\n}\n\n/************************************/\n\nvoid test7()\n{\n    int[3] a = [10,11,12];\n\n    dg_t abc(int[3] y)\n    {\n        int bar()\n        {\n            y[2] += 4;\n            return y[2] + 3;\n        }\n\n        return &bar;\n    }\n\n    dg_t dg = abc(a);\n    fill();\n\n    assert(a[2] == 12);\n    auto i = dg();\n    assert(a[2] == 12);\n    assert(i == 19);\n}\n\n/************************************/\n\nvoid test8()\n{\n    S s = S(7,8,9,10);\n\n    dg_t abc(ref S t)\n    {\n        int bar()\n        {\n            t.d += 4;\n            return t.c + 3;\n        }\n\n        return &bar;\n    }\n\n    dg_t dg = abc(s);\n    fill();\n\n    assert(s.d == 10);\n    auto i = dg();\n    assert(s.d == 14);\n    assert(i == 12);\n}\n\n/************************************/\n\nS foo9(out dg_t dg)\n{\n    S s1 = S(7,8,9,10);\n\n    dg_t abc()\n    {\n        int bar()\n        {\n            s1.d += 4;\n            return s1.c + 3;\n        }\n\n        return &bar;\n    }\n\n    dg = abc();\n    return s1;\n}\n\nvoid test9()\n{\n    dg_t dg;\n\n    S s = foo9(dg);\n    fill();\n    assert(s.a == 7);\n    assert(s.b == 8);\n    assert(s.c == 9);\n    assert(s.d == 10);\n\n    auto i = dg();\n    assert(s.d == 10);\n    assert(i == 12);\n}\n\n/************************************/\n\ndg_t foo10()\n{\n    dg_t abc()\n    {\n        int x = 7;\n\n        int bar()\n        {\n            int def()\n            {\n                return x + 3;\n            }\n            return def();\n        }\n\n        return &bar;\n    }\n\n    return abc();\n}\n\nvoid test10()\n{\n    dg_t dg = foo10();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 10);\n}\n\n\n/************************************/\n\ndg_t foo11()\n{\n    int x = 7;\n\n    class T\n    {\n        int bar()\n        {\n            return x + 3;\n        }\n    }\n\n    T t = new T;\n\n    return &t.bar;\n}\n\nvoid test11()\n{\n    dg_t dg = foo11();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 10);\n}\n\n/************************************/\n\ndg_t foo12()\n{\n    int x = 7;\n\n    class T\n    {\n        int bar()\n        {\n            return x + 3;\n        }\n\n        int xyz()\n        {\n            return bar();\n        }\n    }\n\n    T t = new T;\n\n    return &t.xyz;\n}\n\nvoid test12()\n{\n    dg_t dg = foo12();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 10);\n}\n\n/************************************/\n\ndg_t foo13()\n{\n    int x = 7;\n\n    class T\n    {\n        int xyz()\n        {\n            int bar()\n            {\n                return x + 3;\n            }\n\n            return bar();\n        }\n    }\n\n    T t = new T;\n\n    return &t.xyz;\n}\n\nvoid test13()\n{\n    dg_t dg = foo13();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 10);\n}\n\n\n/************************************/\n\ndg_t foo14()\n{\n    class T\n    {\n        int xyz()\n        {\n            int x = 7;\n\n            int bar()\n            {\n                return x + 3;\n            }\n\n            return bar();\n        }\n    }\n\n    T t = new T;\n\n    return &t.xyz;\n}\n\nvoid test14()\n{\n    dg_t dg = foo14();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 10);\n}\n\n/************************************/\n\ndg_t foo15()\n{\n    class T\n    {\n        int x = 7;\n\n        int xyz()\n        {\n            int bar()\n            {\n                return x + 3;\n            }\n\n            return bar();\n        }\n    }\n\n    T t = new T;\n\n    return &t.xyz;\n}\n\nvoid test15()\n{\n    dg_t dg = foo15();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 10);\n}\n\n/************************************/\n\ndg_t foo16()\n{\n    int a = 5;\n\n    class T\n    {\n        int x = 7;\n\n        int xyz()\n        {\n            int y = 8;\n            int bar()\n            {\n                return a + x + y + 3;\n            }\n\n            return bar();\n        }\n    }\n\n    T t = new T;\n\n    return &t.xyz;\n}\n\nvoid test16()\n{\n    dg_t dg = foo16();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 23);\n}\n\n/************************************/\n\ndg_t foo17()\n{\n    int a = 5;\n\n    class T\n    {\n        int x = 7;\n\n        dg_t xyz()\n        {\n            int y = 8;\n\n            int bar()\n            {\n                return a + x + y + 3;\n            }\n\n            return &bar;\n        }\n    }\n\n    T t = new T;\n\n    return t.xyz();\n}\n\nvoid test17()\n{\n    dg_t dg = foo17();\n    fill();\n    printf(\"bar = %d\\n\", dg());\n    assert(dg() == 23);\n}\n\n/************************************/\n\ndg_t dg18;\n\nvoid bar18()\n{\n    int a = 7;\n    int foo() { return a + 3; }\n\n    dg18 = &foo;\n    int i = dg18();\n    assert(i == 10);\n}\n\nvoid test18()\n{\n    bar18();\n    fill();\n    int i = dg18();\n    assert(i == 10);\n}\n\n/************************************/\n\nvoid abc19(void delegate() dg)\n{\n    dg();\n    dg();\n    dg();\n}\n\nstruct S19\n{\n    static S19 call(int v)\n    {\n        S19 result;\n\n        result.v = v;\n        void nest()\n        {\n            result.v += 1;\n        }\n        abc19(&nest);\n        return result;\n    }\n    int a;\n    int v;\n    int x,y,z;\n}\n\nint foo19()\n{\n    auto s = S19.call(5);\n    return s.v;\n}\n\nvoid test19()\n{\n    int i = foo19();\n    printf(\"%d\\n\", i);\n    assert(i == 8);\n}\n\n/************************************/\n\nvoid enforce20(lazy int msg)\n{\n}\n\n\nvoid test20()\n{\n    int x;\n    foreach (j; 0 .. 10)\n    {\n        printf(\"%d\\n\", j);\n        assert(j == x);\n        x++;\n        enforce20(j);\n    }\n}\n\n/************************************/\n\nvoid thrash21() { char[128] x = '\\xfe'; }\n\nvoid delegate() dg21;\nint g_input = 11, g_output;\n\nvoid f21()\n{\n    int i = g_input + 2;\n\n    class X\n    {\n        // both 'private' and 'final' to make non-virtual\n        private final void actual()\n        {\n            g_output = i;\n        }\n\n        void go()\n        {\n            actual();\n        }\n    }\n\n    dg21 = & (new X).go;\n}\n\nvoid test21()\n{\n    f21();\n    thrash21();\n    dg21();\n    assert(g_output == 13);\n}\n\n/************************************/\n\nvoid thrash22() { char[128] x = '\\xfe'; }\nint gi22;\nvoid delegate() dg22;\n\nclass A22\n{\n    int x = 42;\n\n    void am()\n    {\n        int j; /* Making f access this variable causes f's chain to be am's\n                  frame.  Otherwise, f's chain would be the A instance. */\n        void f()\n        {\n            int k = j;\n\n            void g()\n            {\n                class B\n                {\n                    void bm()\n                    {\n                        gi22 = x; /* No checkedNestedReference for A.am.this,\n                                   so it is never placed in a closure. */\n                    }\n                }\n\n                (new B).bm();\n            }\n\n            dg22 = &g;\n        }\n\n        f();\n    }\n}\n\nvoid test22()\n{\n    (new A22).am();\n    thrash22();\n    dg22();\n    assert(gi22 == 42);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1759\n\nvoid test1759()\n{\n    struct S { int a, b, c; }\n    struct SS { S obj; }\n\n    static int delegate() makeSum1(S s)\n    {\n        with (s) return { return a + b + c; };\n    }\n    static int delegate() makeSum2(S[1] sa)\n    {\n        with (sa[0]) return { return a + b + c; };\n    }\n    static int delegate() makeSum3(SS ss)\n    {\n        with (ss.obj) return { return a + b + c; };\n    }\n    static int delegate() makeSum4(SS[1] ssa)\n    {\n        with (ssa[0].obj) return { return a + b + c; };\n    }\n\n    S s = {15, 30, 45};\n    SS ss = {s};\n    int delegate() sum;\n\n    sum = makeSum1(s);      assert(sum() == 90);\n    sum = makeSum2([s]);    assert(sum() == 90);\n    sum = makeSum3(ss);     assert(sum() == 90);\n    sum = makeSum4([ss]);   assert(sum() == 90);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1841\n\nint delegate() foo1841()\n{\n    int stack;\n    int heap = 3;\n\n    int nested_func()\n    {\n        ++heap;\n        return heap;\n    }\n    return delegate int() { return nested_func(); };\n}\n\nint delegate() foo1841b()\n{\n    int stack;\n    int heap = 7;\n\n    int nested_func()\n    {\n        ++heap;\n        return heap;\n    }\n    int more_nested() { return nested_func(); }\n    return delegate int() { return more_nested(); };\n}\n\nvoid test1841()\n{\n    auto z = foo1841();\n    auto p = foo1841();\n    assert(z() == 4);\n    p();\n    assert(z() == 5);\n    z = foo1841b();\n    p = foo1841b();\n    assert(z() == 8);\n    p();\n    assert(z() == 9);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5911\n\nvoid writeln5911(const(char)[] str) {}\n\nvoid logout5911(lazy const(char)[] msg) { writeln5911(msg); }\n\nvoid test5911()\n{\n    string str = \"hello world\";\n    logout5911((){ return str; }());    // closure 1\n\n    try\n    {\n        throw new Exception(\"exception!!\");\n    }\n    catch (Exception e)\n    {\n        assert(e !is null);\n        logout5911(e.toString());       // closure2 SEGV : e is null.\n    }\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9685\n\nauto get9685a(alias fun)()\n{\n    int x = 10;\n    struct Foo\n    {\n        size_t data;\n\n        @property clone()\n        {\n            return Foo(15);\n        }\n    }\n    return Foo(5);\n}\nvoid test9685a()\n{\n    uint a = 42;\n    auto bar = get9685a!(() => a)();\n    auto qux = bar.clone;\n    //printf(\"bar context pointer : %p\\n\", bar.tupleof[$-1]);\n    //printf(\"qux context pointer : %p\\n\", qux.tupleof[$-1]);\n    assert(bar.tupleof[$-1] == qux.tupleof[$-1]);\n    assert(qux.data == 15);\n}\n\nauto get9685b(alias fun)()\n{\n    int x = 10;\n    struct Foo\n    {\n        size_t data;\n\n        @property clone()\n        {\n            return Foo(data + x);\n        }\n    }\n    return Foo(5);\n}\nvoid test9685b()\n{\n    uint a = 42;\n    auto bar = get9685b!(() => a)();\n    auto qux = bar.clone;\n    //printf(\"bar context pointer : %p\\n\", bar.tupleof[$-1]);\n    //printf(\"qux context pointer : %p\\n\", qux.tupleof[$-1]);\n    assert(bar.tupleof[$-1] == qux.tupleof[$-1]);\n    assert(qux.data == 15);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12406\n\nauto createDg12406()\n{\n    static struct Dg\n    {\n        Dg delegate() action;\n    }\n\n    static void fn(void delegate()) { }\n\n    int x; fn({ x++; }); // required\n\n    Dg dg;\n\n    Dg createDg2()\n    {\n        int x; void unusedFun() { x++; } // required\n\n        return Dg(() => dg); // lambda returns garbage instead of dg\n    }\n\n    return dg = Dg(&createDg2);\n}\n\nvoid test12406()\n{\n    auto dgs = [createDg12406()];\n    //printf(\"dgs[%2d].action = %p:%p\\n\", 0, dgs[$-1].action.ptr, dgs[$-1].action.funcptr);\n    foreach (i; 1 .. 10+1)\n    {\n        dgs ~= dgs[i-1].action();\n        //printf(\"dgs[%2d].action = %p:%p\\n\", i, dgs[$-1].action.ptr, dgs[$-1].action.funcptr);\n    }\n\n    foreach (i, dgx; dgs)\n    {\n        if (i % 2 == 0)\n        {\n            // All closures are equal with dgs[0].\n            assert(dgx.action.ptr     is dgs[0].action.ptr);\n            assert(dgx.action.funcptr is dgs[0].action.funcptr);    // is: createDg2\n        }\n        else\n        {\n            // Each closures has unique context.\n            for (size_t j = i + 2; j < dgs.length; j += 2)\n                assert(dgx.action.ptr !is dgs[j].action.ptr);\n            assert(dgx.action.funcptr is dgs[1].action.funcptr);    // is: lambda () => dg\n        }\n    }\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14730\n\nvoid test14730()\n{\n    static auto makeS(int x)\n    {\n        struct S\n        {\n            int n;\n            int get() { return x; }     // x will be a closure variable\n        }\n        return S(x);\n    }\n    auto s = makeS(1);\n    assert(s.get() == 1);\n    // By inlining get() function call, it's rewritten to:\n    // assert(*(s.tupleof[$-1] + x.offset) == 1);\n    // --> In DotVarExp::toElem(), x->offset should be already nonzero.\n}\n\n// ----\n\n// This is questionable case. Currently it works without any errors,\n// but not sure it's really intentional\n\nstruct S14730x(alias f)\n{\n    auto foo()() { return f(0); }\n\n    void dummy() {}\n}\n\nauto makeS14730x() //@nogc\n{\n    int x = 10;\n    S14730x!(a => x) s;\n    //assert(s.foo() == 10);\n    return s;\n}\n\nvoid test14730x()\n{\n    auto s = makeS14730x();\n    assert(s.tupleof[$-1] !is null);\n\n    // instantiationg foo outside of makeS will place the variable x in closure\n    // *after* the semantic3 completion of makeS() function.\n    assert(s.foo() == 10);\n}\n\n/************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test1759();\n    test1841();\n    test5911();\n    test9685a();\n    test9685b();\n    test12406();\n    test14730();\n    test14730x();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/complex.d",
    "content": "// PERMUTE_ARGS:\n\nimport std.stdio;\nimport std.math;\nimport core.stdc.stdio;\n\n/***************************************/\n\nvoid test1()\n{\n    creal c = 3.0 + 4.0i;\n    c = sqrt(c);\n    printf(\"re = %Lg, im = %Lg\\n\", c.re, c.im);\n    assert(c.re == 2.0);\n    assert(c.im == 1.0);\n\n    float f = sqrt(25.0f);\n    assert(f == 5.0);\n    double d = sqrt(4.0);\n    assert(d == 2.0);\n    real r = sqrt(9.0L);\n    assert(r == 3.0);\n}\n\n/***************************************/\n\nireal f2() { return 1i; }\n\nvoid test2()\n{\n    creal v = 0+0i;\n\n    v += f2();\n    assert(v == 0 + 1i);\n\n    v = v + f2();\n    assert(v == 0 + 2i);\n}\n\n/***************************************/\n\ncdouble[1] a3;\ncdouble[1] b3;\n\ncdouble[] concat3() {\n        return a3~b3;\n}\n\nvoid test3()\n{\n        a3[]=0.5+1.0i;\n        b3[]=0.5+3.0i;\n\n        cdouble[] arr=concat3();\n\n        assert(arr.length==2);\n        assert(arr[0]==0.5+1.0i);\n        assert(arr[1]==0.5+3.0i);\n}\n\n/***************************************/\n\ncreal[1] a4;\ncreal[1] b4;\n\ncreal[] concat4() {\n        return a4~b4;\n}\n\nvoid test4()\n{\n        a4[]=0.5+1.0i;\n        b4[]=0.5+3.0i;\n\n        creal[] arr=concat4();\n\n        assert(arr.length==2);\n        assert(arr[0]==0.5+1.0i);\n        assert(arr[1]==0.5+3.0i);\n}\n\n/***************************************/\n\nvoid test5()\n{\n        ifloat i=1.0fi;\n//      i += 2.2;\n//      assert(i == 1i);\n}\n\n/***************************************/\n\nvoid test6()\n{\n        float i=1.0f;\n//      i /= 2.2fi;\n//      assert(i == 0);\n}\n\n/***************************************/\n\nvoid test7()\n{\n        creal x=1.0i+2.0;\n        creal[] arr;\n\n        arr = arr ~ x;\n        assert(arr.length==1);\n        assert(arr[0]==1.0i+2.0);\n\n        x=0.0i+5.0;\n        assert(arr[0]==1.0i+2.0);\n}\n\n/****************************************/\n\ncreal[1] a8;\ncreal[1] b8;\n\ncreal[] concat8() {\n    return a8 ~ b8;\n}\n\nvoid test8()\n{\n    a8[]=0.5L+1.0Li;\n    b8[]=0.5L+3.0Li;\n\n    creal[] arr=concat8();\n\n    assert(arr.length==2);\n    assert(arr[0]==0.5L+1.0Li);\n    assert(arr[1]==0.5L+3.0Li);\n}\n\n/***************************************/\n\ncreal[1] a9;\ncreal[1] b9;\n\ncreal[] concat9() {\n    return a9~b9;\n}\n\nvoid test9()\n{\n    a9[]=0.5L+1.0Li;\n    b9[]=0.5L+3.0Li;\n\n    creal[] arr=concat9();\n\n    assert(arr.length==2);\n    assert(arr[0]==0.5L+1.0Li);\n    assert(arr[1]==0.5L+3.0Li);\n}\n\n\n/***************************************/\n\nvoid test10()\n{\n    ifloat a = 1.0i;\n    assert(a.im == 1.0);\n\n    const ifloat b = 2.0i;\n    static assert(b.im == 2.0); // FAIL\n\n}\n\n/***************************************/\n\nvoid test11()\n{\n    real r = real.nan;\n    assert( r!=0 );\n    if (r==0) assert(0);\n\n    ireal ir = ireal.nan;\n    assert( ir!=0 );\n    assert( ir!=0i );\n    if (ir==0) assert(0);\n    if (ir==0i) assert(0);\n\n    creal cr = creal.nan;\n    assert( cr!=0 );\n    assert( cr!=0i );\n    if (cr==0) assert(0);\n    if (cr==0i) assert(0);\n\n    double d = double.nan;\n    assert( d!=0 );\n    if (d==0) assert(0);\n\n    idouble id = idouble.nan;\n    assert( id!=0 );\n    assert( id!=0i );\n    if (id==0) assert(0);\n    if (id==0i) assert(0);\n\n    cdouble cd = cdouble.nan;\n    assert( cd!=0 );\n    assert( cd!=0i );\n    if (cd==0) assert(0);\n    if (cd==0i) assert(0);\n\n    float f = float.nan;\n    assert( f!=0 );\n    if (f==0) assert(0);\n\n    ifloat ifx = ifloat.nan;\n    assert( ifx!=0 );\n    assert( ifx!=0i );\n    if (ifx==0) assert(0);\n    if (ifx==0i) assert(0);\n\n    cfloat cf = cfloat.nan;\n    assert( cf!=0 );\n    assert( cf!=0i );\n    if (cf==0) assert(0);\n    if (cf==0i) assert(0);\n}\n\n/***************************************/\n\nvoid test12()\n{\n    real x = 3;\n    creal a = (2 + 4i) % 3;\n    writeln(a);\n    assert(a == 2 + 1i);\n\n    creal b = (2 + 4i) % x;\n    writeln(b);\n    assert(b == a);\n}\n\n/***************************************/\n\nvoid test13()\n{\n        ireal a = 5i;\n        ireal b = a % 2;\n        writeln(b);\n        assert(b == 1i);\n}\n\n/***************************************/\n\ncdouble inv( cdouble expr )\n{\n    return (1.0 + 0.0i) / expr;\n}\n\n/***************************************/\n\nvoid test14()\n{\n    cfloat c;\n    cfloat d;\n    assert(c != d);\n\n    cdouble e;\n    cdouble f;\n    assert(e != f);\n\n    creal g;\n    creal h;\n    assert(g != h);\n}\n\n/***************************************/\n\nvoid test7581()\n{\n    cfloat a() { return cfloat.nan; }\n    assert(a() != 0);\n}\n\n/***************************************/\n\nfloat f() { return 1.0f; }\nifloat i() { return 1.0fi; }\n\nvoid test7594()\n{\n    assert(f() + i() == 1.0f + 1.0fi);\n}\n\n/***************************************/\n\ncdouble conv(cfloat a)\n{\n    return a;\n}\n\nvoid test7593()\n{\n    assert(conv(1.0f+1.0fi) == 1.0+1.0i);\n}\n\n/***************************************/\n\ncfloat get() { return cfloat.nan; }\n\nvoid test7591()\n{\n    assert(!(get() == 0));\n}\n\n/***************************************/\n\nvoid foo8966(cfloat x)\n{\n    assert(x.re == 3.0f);\n}\n\n__gshared cfloat[] a8966;\n\nvoid test8966()\n{\n    a8966 = new cfloat[2];\n    a8966[0] = 3.0f + 1.0fi;\n    foo8966(a8966[0]);\n}\n\n/***************************************/\n\nvoid formatTest2(cfloat s, double re, double im)\n{\n    assert(s.re == re);\n    assert(s.im == im);\n}\n\ncfloat getcf()\n{\n    return 2 + 1i;\n}\n\nvoid test10677()\n{\n    formatTest2( getcf(), 2, 1 );\n}\n\n/***************************************/\n\nvoid test7806()\n{\n    for (idouble i = -2i; i <= 2i; i += .125i)\n        for (double r = -2; r <= 2; r += .0625)\n        {\n            cdouble c = r + i;\n            printf(\"%g %gi\\n\", c.re, c.im);\n        }\n}\n\n/***************************************/\n\nvoid test7976() {\n    creal[] a = new creal[2];\n    auto b = a[0] = a[1];\n}\n\n/***************************************/\n\ncfloat foo15f(ifloat re, float im)\n{\n    return re + im;\n}\n\ncfloat bar15f(float re, ifloat im)\n{\n    return re + im;\n}\n\ncdouble foo15(idouble re, double im)\n{\n    return re + im;\n}\n\ncdouble bar15(double re, idouble im)\n{\n    return re + im;\n}\n\ncreal foo15r(ireal re, real im)\n{\n    return re + im;\n}\n\ncreal bar15r(real re, ireal im)\n{\n    return re + im;\n}\n\nvoid test15()\n{\n    assert(foo15f(1.0fi, 2.0f) == 2.0f + 1.0fi);\n    assert(bar15f(1.0f, 2.0fi) == 1.0f + 2.0fi);\n\n    assert(foo15(1.0i, 2.0) == 2.0 + 1.0i);\n    assert(bar15(1.0, 2.0i) == 1.0 + 2.0i);\n\n    assert(foo15r(1.0Li, 2.0L) == 2.0L + 1.0Li);\n    assert(bar15r(1.0L, 2.0Li) == 1.0L + 2.0Li);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17087\n\ncfloat toComplex(int x) { return cast(cfloat)x; }\n\nvoid test17087()\n{\n    assert (toComplex(1) == 1.0);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17677\n\nvoid test17677()\n{\n    cfloat v2 = 0.0f + 0.0fi;\n    ulong v1 = 1;\n    auto z = v2 + v1;\n    assert(z == 1.0f);\n}\n\n/***************************************/\n\nint main(char[][] args)\n{\n\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test7581();\n    test7594();\n    test7593();\n    test7591();\n    test8966();\n    test10677();\n    test7806();\n    test7976();\n    test15();\n    test17087();\n    test17677();\n\n    printf(\"Success!\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/constfold.d",
    "content": "#! blah\n\nstatic assert(__LINE__ == 3); // fails as __LINE__ is 2\n\nimport std.stdio;\nimport std.math : signbit, sqrt;\n\n\n/************************************/\n\nstatic assert(-(1) == -1);\nstatic assert(-(6i) == -6i);\nstatic assert(-(1 + 6i) == -1 - 6i);\n\nstatic assert(!27 == 0);\nstatic assert(!0 == 1);\nstatic assert(!6.2 == 0);\nstatic assert(!0.0 == 1);\nstatic assert(!3.7i == 0);\nstatic assert(!0.0i == 1);\nstatic assert(!(2+3.7i) == 0);\nstatic assert(!(0+3.7i) == 0);\nstatic assert(!(2+0.0i) == 0);\nstatic assert(!(0+0.0i) == 1);\n\nstatic assert(-6i + 2i == -4i);\nstatic assert(6i - 1i == 5i);\n\nstatic assert((3.6 + 7.2i) / (1 + 0i) == 3.6 + 7.2i);\nstatic assert((3.6 + 7.2i) / (0.0 + 1i) == 7.2 - 3.6i);\n\nstatic assert((6 % 4) == 2);\nstatic assert((6u % 4u) == 2u);\n\nstatic assert((cast(byte)0x109 >> 1) == 4);\nstatic assert((cast(byte)-1 >> 1) == -1);\nstatic assert((cast(ubyte)0x109 >> 1) == 4);\n\nstatic assert((cast(short)0x10009 >> 1) == 4);\nstatic assert((cast(short)-1 >> 1) == -1);\nstatic assert((cast(ushort)0x10009 >> 1) == 4);\n\nstatic assert((cast(long)0x1_0000_0000_0009 >> 1) == 0x8000_0000_0004);\nstatic assert((cast(long)-1L >> 1) == -1);\nstatic assert((cast(ulong)0x10009 >> 1) == 0x8004);\n\nstatic assert((cast(byte)0x109 >>> 1) == 4);\nstatic assert((cast(byte)-1 >>> 1) == int.max);\nstatic assert((cast(ubyte)0x109 >>> 1) == 4);\n\nstatic assert((cast(short)0x10009 >>> 1) == 4);\nstatic assert((cast(short)-1 >>> 1) == int.max);\nstatic assert((cast(ushort)0x10009 >>> 1) == 4);\n\nstatic assert((cast(long)0x1_0000_0000_0009 >>> 1) == 0x8000_0000_0004);\nstatic assert((cast(long)-1L >>> 1) == long.max);\nstatic assert((cast(ulong)0x10009 >>> 1) == 0x8004);\n\nstatic assert((3 ^ 5) == 6);\n\nstatic assert((0 && 0) == 0);\nstatic assert((0 && 5) == 0);\nstatic assert((10 && 0) == 0);\nstatic assert((58 && 10000) == 1);\n\nstatic assert((0.0 && 0.0) == 0);\nstatic assert((0.0 && 5.1) == 0);\nstatic assert((10.0 && 0.0) == 0);\nstatic assert((58.6 && 10000.7) == 1);\n\nstatic assert((0 || 0) == 0);\nstatic assert((0 || 5) == 1);\nstatic assert((10 || 0) == 1);\nstatic assert((58 || 10000) == 1);\n\nstatic assert((0.0 || 0.0) == 0);\nstatic assert((0.0 || 5.1) == 1);\nstatic assert((10.0 || 0.0) == 1);\nstatic assert((58.6 || 10000.7) == 1);\n\nstatic assert((5 < 3) == 0);\nstatic assert((5 < 5) == 0);\nstatic assert((5 < 6) == 1);\nstatic assert((5 <= 3) == 0);\nstatic assert((5 <= 5) == 1);\nstatic assert((5 <= 6) == 1);\nstatic assert((5 > 3) == 1);\nstatic assert((5 > 5) == 0);\nstatic assert((5 > 6) == 0);\nstatic assert((5 >= 3) == 1);\nstatic assert((5 >= 5) == 1);\nstatic assert((5 >= 6) == 0);\n\nstatic assert((-5 < -3) == 1);\nstatic assert((-5 < -5) == 0);\nstatic assert((-5 < -6) == 0);\nstatic assert((-5 <= -3) == 1);\nstatic assert((-5 <= -5) == 1);\nstatic assert((-5 <= -6) == 0);\nstatic assert((-5 > -3) == 0);\nstatic assert((-5 > -5) == 0);\nstatic assert((-5 > -6) == 1);\nstatic assert((-5 >= -3) == 0);\nstatic assert((-5 >= -5) == 1);\nstatic assert((-5 >= -6) == 1);\n\nstatic assert((5u < 3u) == 0);\nstatic assert((5u < 5u) == 0);\nstatic assert((5u < 6u) == 1);\nstatic assert((5u <= 3u) == 0);\nstatic assert((5u <= 5u) == 1);\nstatic assert((5u <= 6u) == 1);\nstatic assert((5u > 3u) == 1);\nstatic assert((5u > 5u) == 0);\nstatic assert((5u > 6u) == 0);\nstatic assert((5u >= 3u) == 1);\nstatic assert((5u >= 5u) == 1);\nstatic assert((5u >= 6u) == 0);\n\nstatic assert((-5u < 3) == 0);\nstatic assert((-5u <= 3) == 0);\nstatic assert((-5u > 3) == 1);\nstatic assert((-5u >= 3) == 1);\n\nstatic assert((-5 < 3u) == 0);\nstatic assert((-5 <= 3u) == 0);\nstatic assert((-5 > 3u) == 1);\nstatic assert((-5 >= 3u) == 1);\n\nstatic assert((5.2 <    double.nan) == 0);\nstatic assert((5.2 <=   double.nan) == 0);\nstatic assert((5.2 >    double.nan) == 0);\nstatic assert((5.2 >=   double.nan) == 0);\n\nstatic assert((double.nan <    6.2) == 0);\nstatic assert((double.nan <=   6.2) == 0);\nstatic assert((double.nan >    6.2) == 0);\nstatic assert((double.nan >=   6.2) == 0);\n\nstatic assert((double.nan <    double.nan) == 0);\nstatic assert((double.nan <=   double.nan) == 0);\nstatic assert((double.nan >    double.nan) == 0);\nstatic assert((double.nan >=   double.nan) == 0);\n\nstatic assert((5.2 <    6.2) == 1);\nstatic assert((5.2 <=   6.2) == 1);\nstatic assert((5.2 >    6.2) == 0);\nstatic assert((5.2 >=   6.2) == 0);\n\nstatic assert((5.2 <    5.2) == 0);\nstatic assert((5.2 <=   5.2) == 1);\nstatic assert((5.2 >    5.2) == 0);\nstatic assert((5.2 >=   5.2) == 1);\n\nstatic assert((7.2 <    6.2) == 0);\nstatic assert((7.2 <=   6.2) == 0);\nstatic assert((7.2 >    6.2) == 1);\nstatic assert((7.2 >=   6.2) == 1);\n\nstatic assert((7.2i < 6.2i) == 0);\n\n\nstatic assert((7.2i == 6.2i) == 0);\nstatic assert((7.2i != 6.2i) == 1);\nstatic assert((7.2 == 6.2) == 0);\nstatic assert((7.2 != 6.2) == 1);\n\nstatic assert((7.2i == 7.2i) == 1);\nstatic assert((7.2i != 7.2i) == 0);\nstatic assert((7.2 == 7.2) == 1);\nstatic assert((7.2 != 7.2) == 0);\n\nstatic assert((7.2 == double.nan) == 0);\nstatic assert((7.2 != double.nan) == 1);\nstatic assert((double.nan == double.nan) == 0);\nstatic assert((double.nan != double.nan) == 1);\nstatic assert((double.nan == 7.2) == 0);\nstatic assert((double.nan != 7.2) == 1);\n\nstatic assert((5 is 5) == 1);\nstatic assert((5 is 4) == 0);\nstatic assert((5 !is 5) == 0);\nstatic assert((5 !is 4) == 1);\n\nstatic assert((5.1 is 5.1) == 1);\nstatic assert((5.1 is 4.1) == 0);\nstatic assert((5.1 !is 5.1) == 0);\nstatic assert((5.1 !is 4.1) == 1);\n\nstatic assert((5.1 is 5.1i) == 0);\nstatic assert((5.1 !is 5.1i) == 1);\n\nstatic assert((5 ? 2 : 3) == 2);\nstatic assert((0 ? 2 : 3) == 3);\nstatic assert((5.0 ? 2 : 3) == 2);\nstatic assert((0.0 ? 2 : 3) == 3);\n\nstatic assert(\"abc\" == \"abc\");\n\n//static assert(\"abc\"w.sizeof == 6);\n//static assert(\"\\U00010000bc\"w.sizeof == 8);\n\nstatic assert([1,2,3][1] == 2);\nstatic assert([1,2,3] ~ [4] == [1,2,3,4]);\nstatic assert([1,2,3][1..3] == [2,3]);\n\nstatic assert(['a','b','c','d'] == \"abcd\");\nstatic assert(\"efgh\" == ['e','f','g','h']);\nstatic assert(\"efgi\" != ['e','f','g','h']);\n\nstatic assert((2 ^^ 8) == 256);\nstatic assert((3 ^^ 8.0) == 6561);\nstatic assert((4.0 ^^ 8) == 65536);\nstatic assert((5.0 ^^ 8.0) == 390625);\n\nstatic assert((0.5 ^^ 3) == 0.125);\nstatic assert((1.5 ^^ 3.0) == 3.375);\nstatic assert((2.5 ^^ 3) == 15.625);\nstatic assert((3.5 ^^ 3.0) == 42.875);\n\nstatic assert(((-2) ^^ -5.0) == -0.031250);\nstatic assert(((-2.0) ^^ -6) == 0.015625);\nstatic assert(((-2.0) ^^ -7.0) == -0.0078125);\n\nstatic assert((144 ^^ 0.5) == 12);\nstatic assert((1089 ^^ 0.5) == 33);\nstatic assert((1764 ^^ 0.5) == 42);\nstatic assert((650.25 ^^ 0.5) == 25.5);\n\n\nvoid test1()\n{\n    int x;\n    int y;\n    int* p;\n\n    p = &x + cast(size_t)&y;\n    p = &x + 2;\n    p = 4 + &y;\n    p = &x - 1;\n\n    assert((&x is &x) == 1);\n    assert((&x is &y) == 0);\n    assert((&x !is &x) == 0);\n    assert((&x !is &y) == 1);\n}\n\n/************************************/\n\nvoid test2()\n{\n    // This test only tests undefined, architecture-dependant behavior.\n    // E.g. the result of converting a float whose value doesn't fit into the integer\n    // leads to an undefined result.\n    version(GNU)\n       return;\n\n    float f = float.infinity;\n    int i = cast(int) f;\n    writeln(i);\n    writeln(cast(int)float.max);\n    assert(i == cast(int)float.max);\n    assert(i == 0x80000000);\n}\n\n/************************************/\n\nvoid test3()\n{\n     real n = -0.0;\n     const real m = -0.0;\n\n     creal c = -0.0 + 3i;\n     creal d = n + 3i;\n     creal e = m + 3i;\n\n     // should print \"11111\"\n     writeln(signbit(n), signbit(m),\n        signbit(c.re), signbit(d.re), signbit(e.re));\n\n     assert(signbit(n) == 1);\n     assert(signbit(m) == 1);\n     assert(signbit(c.re) == 1);\n     assert(signbit(d.re) == 1);\n     assert(signbit(e.re) == 1);\n}\n\n/************************************/\n\nstruct A4 { char [] a; }\nstruct B4 { long x; }\nstruct C4 { int a;\n    static C4 opCall(int b) { C4 q; q.a=b; return q; }\n}\nstatic assert(!is(typeof( (){ A4 s; B4 q = s; })));\nstatic assert(!is(typeof( (){ B4 x =1L; })));\nstatic assert(is(typeof( (){ C4 g = 7; })));\nstatic assert(is(typeof( (){ C4 g = 7; C4 h = g;})));\n\n/************************************/\n\nalias uint DWORD;\nMY_API_FUNCTION lpStartAddress;\nextern (Windows) alias DWORD function(void*) MY_API_FUNCTION;\npragma(msg, MY_API_FUNCTION.stringof);\nstatic assert(MY_API_FUNCTION.stringof == \"extern (Windows) uint function(void*)\");\n\n/************************************/\n\nenum bug6 = cast(void*)0xFEFEFEFE;\nstatic assert(bug6 is bug6);\n\n/************************************/\n\nstruct S7{\n   double z;\n}\n\nint bug7(int x) {  return x; }\n\nS7 s7;\ndouble e7 = 4;\nconst double d7 = 4;\n\nstatic assert(!is(typeof(bug7(cast(long)e7))));\nstatic assert(!is(typeof(bug7(cast(long)s7))));\nversion (LDC) {} else // cast in LDC undefined result w/ x > long.max\nstatic assert(!is(typeof(bug7(cast(long)3.256679e30))));\n\nstatic assert(is(typeof(bug7(cast(long)d7))));\nstatic assert(is(typeof(bug7(cast(long)3.256679e4))));\n\n/************************************/\n\nclass C8 {\n    int x;\n}\nalias C8.x F8;\nstatic assert(is(typeof(F8) == int));\nstatic assert(is(typeof(C8.x) == int));\n\n/************************************/\n\nint foo9() {\n   int u = cast(int)(0x1_0000_0000L);\n   while (u) {\n      if (u) {\n         assert(u!=0);\n        }\n      assert(u!=0);\n   }\n   return 2;\n}\n\nstatic assert(foo9()==2);\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6077\n\nvoid test6077() {\n    static string scat(string s1, string s2)\n    {\n        return s1 ~ s2;\n    }\n\n    static string scatass(string s1, string s2)\n    {\n        s1 ~= s2;\n        return s1;\n    }\n\n    static string[] arycats(string[] ary, string s)\n    {\n        return ary ~ s;\n    }\n\n    static string[] scatary(string s, string[] ary)\n    {\n        return s ~ ary;\n    }\n\n    static string[] arycatasss(string[] ary, string s)\n    {\n        ary ~= s;\n        return ary;\n    }\n\n    static assert(scat(null, null) is null);\n    static assert(scatass(null, null) is null);\n    static assert(arycats(null, null) == cast(string[])[null]);\n    static assert(scatary(null, null) == cast(string[])[null]);\n    static assert(arycatasss(null, null) == cast(string[])[null]);\n}\n\n/************************************/\n\nint test4()\n{\n    int i;\n\n    dchar  d;\n    d  >>= 1;\n    d >>>= 1;\n    d  <<= 1;\n    d = d  >> 1;\n    d = d >>> 1;\n    d = d  << 1;\n    wchar  w;\n    w  >>= 1;\n    w >>>= 1;\n    w  <<= 1;\n    w = w  >> 1;\n    w = w >>> 1;\n    i = w  << 1; // promoted to int\n    char   c;\n    c  >>= 1;\n    c >>>= 1;\n    c  <<= 1;\n    c = c  >> 1;\n    c = c >>> 1;\n    i = c  << 1; // promoted to int\n    return d + w + c + i;\n}\n\nstatic assert(test4() == 24666);\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8400\n\nvoid test8400()\n{\n    immutable a = [1,2];\n    int[a.length+0] b; // ok\n    int[a.length  ] c; // error\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8939\n\nvoid foo8939(T)(ref T) { } // same for `auto ref`\nvoid bar8939(ref const int) { }\nvoid bar8939(ref const S8939) { }\n\nstatic struct S8939 { int n; }\n\nconst gn8939 = 1; // or `immutable`\nconst gs8939 = S8939(3);\nstatic assert(__traits(compiles, foo8939(gn8939), bar8939(gn8939)));\nstatic assert(__traits(compiles, foo8939(gs8939), bar8939(gs8939)));\n\nvoid test8939()\n{\n    foo8939(gn8939), bar8939(gn8939);\n    foo8939(gs8939), bar8939(gs8939);\n\n    const ln8939 = 1;\n    const ls8939 = S8939(3);\n    foo8939(ln8939), bar8939(ln8939);\n    foo8939(ls8939), bar8939(ls8939);\n}\n\nclass C8939regression\n{\n    const int n1 = 0;\n    const int n2 = 0;\n    const int n3 = 0;\n    const int n4 = 1;\n\n    int refValue(V)(ref V var)\n    {\n        return 0;\n    }\n\n    void foo()\n    {\n        string[2] str;\n        refValue(str[n1]);\n\n        int[] da;\n        refValue(da[n2]);\n\n        int n; int* p = &n;\n        refValue(*cast(int*)(p + n3));\n\n        refValue([1,2,n4].ptr[0]);\n    }\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9058\n\ntemplate TypeTuple9058(TL...) { alias TypeTuple9058 = TL; }\ntemplate EnumMembers9058(T)\n{\n    alias EnumMembers9058 = TypeTuple9058!(Foo9058.A, Foo9058.B);\n}\nenum Foo9058 { A, B }\nsize_t bar9058(size_t n)\n{\n    return 0;\n}\nvoid test9058()\n{\n    Foo9058 x = [EnumMembers9058!Foo9058][bar9058($)];\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11159\n\nvoid test11159()\n{\n    import std.math : pow;\n    enum ulong\n        e_2_pow_64 = 2uL^^64,\n        e_10_pow_19 = 10uL^^19,\n        e_10_pow_20 = 10uL^^20;\n    assert(e_2_pow_64 == pow(2uL, 64));\n    assert(e_10_pow_19 == pow(10uL, 19));\n    assert(e_10_pow_20 == pow(10uL, 20));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12306\n\nvoid test12306()\n{\n    struct Point3D { ubyte x, y, z; }\n\n    enum      Point3D pt1 = {x:1, y:1, z:1};\n    const     Point3D pt2 = {x:1, y:1, z:1};\n    immutable Point3D pt3 = {x:1, y:1, z:1};\n\n    int[pt1.z][pt1.y][pt1.x] a1;\n    int[pt2.z][pt2.y][pt2.x] a2;\n    int[pt3.z][pt3.y][pt3.x] a3;\n\n    ubyte a = 1;\n    const     Point3D ptx = {x:a, y:1, z:1};\n\n    static assert(!__traits(compiles, { int[ptx.z][ptx.y][ptx.x] ax; }));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13977\n\nvoid test13977()\n{\n    bool cond(bool b) { return b; }\n    int x = 0;\n    void check(int n = 1) { x = n; }\n\n    cond(true) && check();\n    assert(x == 1); x = 0;\n\n    cond(false) && check();\n    assert(x == 0); x = 0;\n\n    true && check();\n    assert(x == 1); x = 0;\n\n    false && check();\n    assert(x == 0); x = 0;\n    (int[]).init && check();\n    assert(x == 0); x = 0;\n    Object.init && check();\n    assert(x == 0);\n\n    check(2);\n    false && check();\n    assert(x == 2); x = 0;\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13978\n\nvoid test13978()\n{\n    bool cond(bool b) { return b; }\n    int x = 0;\n    void check(int n = 1) { x = n; }\n\n    cond(true) || check();\n    assert(x == 0); x = 0;\n\n    cond(false) || check();\n    assert(x == 1); x = 0;\n\n    true || check();\n    assert(x == 0); x = 0;\n\n    false || check();\n    assert(x == 1); x = 0;\n    (int[]).init || check();\n    assert(x == 1); x = 0;\n    Object.init || check();\n    assert(x == 1); x = 0;\n\n    check(2);\n    true || check();\n    assert(x == 2); x = 0;\n}\n\n/************************************/\n// Pull Request 3697\n\nvoid test3697and()\n{\n    enum x = 0;\n    auto y = x && 1 / x;\n}\n\nvoid test3697or()\n{\n    enum x = 0;\n    enum y = 1;\n    auto z = y || 1 / x;\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14459\n\nvoid test14459()\n{\n    const char* s0 = \"hi0\";\n    const(char)* p0 = s0;\n    assert(p0 == s0);\n\n    const char* s1 = \"hi1\";\n    const char* s2 = \"hi2\";\n    const char* s3 = \"hi3\";\n    const char* s4 = \"hi4\";\n    const char* s5 = \"hi5\";\n    const char* s6 = \"hi6\";\n    const char* s7 = \"hi7\";\n    const char* s8 = \"hi8\";\n    const char* s9 = \"hi9\";\n    const char* s10 = \"hi10\";\n    const char* s11 = \"hi11\";\n    const char* s12 = \"hi12\";\n    const char* s13 = \"hi13\";\n    const char* s14 = \"hi14\";\n    const char* s15 = \"hi15\";\n    assert(p0 == s0);           // ok\n    const char* s16 = \"hi16\";\n    assert(p0 == s0);           // ok <- fails\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15607\n\nstatic immutable char[2][4] code_base = [ \"??\", 12 ];\nstatic assert(code_base[0] == \"??\");\nstatic assert(code_base[1] == [12, 12]);\nstatic assert(code_base[2] == typeof(code_base[2]).init);\n\n/************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test3697and();\n    test3697or();\n    test6077();\n    test8400();\n    test8939();\n    test9058();\n    test11159();\n    test13977();\n    test13978();\n    test14459();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/cpp_abi_tests.d",
    "content": "// EXTRA_CPP_SOURCES: extra-files/cpp_abi_tests.cpp\n\nextern(C++) {\n\nstruct S\n{\n    float a = 1;\n}\n\nextern(C++, std)\n{\n    struct test19248 {int a = 34;}\n}\n\nbool   passthrough(bool   value);\nbyte   passthrough(byte   value);\nubyte  passthrough(ubyte  value);\nchar   passthrough(char   value);\ndchar  passthrough(dchar  value);\nshort  passthrough(short  value);\nushort passthrough(ushort value);\nint    passthrough(int    value);\nuint   passthrough(uint   value);\nlong   passthrough(long   value);\nulong  passthrough(ulong  value);\nfloat  passthrough(float  value);\ndouble passthrough(double value);\nS      passthrough(S      value);\nstd.test19248 passthrough(const(std.test19248) value);\n\nbool   passthrough_ptr(bool   *value);\nbyte   passthrough_ptr(byte   *value);\nubyte  passthrough_ptr(ubyte  *value);\nchar   passthrough_ptr(char   *value);\ndchar  passthrough_ptr(dchar  *value);\nshort  passthrough_ptr(short  *value);\nushort passthrough_ptr(ushort *value);\nint    passthrough_ptr(int    *value);\nuint   passthrough_ptr(uint   *value);\nlong   passthrough_ptr(long   *value);\nulong  passthrough_ptr(ulong  *value);\nfloat  passthrough_ptr(float  *value);\ndouble passthrough_ptr(double *value);\nS      passthrough_ptr(S      *value);\nstd.test19248 passthrough_ptr(const(std.test19248)* value);\n\nbool   passthrough_ref(ref bool   value);\nbyte   passthrough_ref(ref byte   value);\nubyte  passthrough_ref(ref ubyte  value);\nchar   passthrough_ref(ref char   value);\ndchar  passthrough_ref(ref dchar  value);\nshort  passthrough_ref(ref short  value);\nushort passthrough_ref(ref ushort value);\nint    passthrough_ref(ref int    value);\nuint   passthrough_ref(ref uint   value);\nlong   passthrough_ref(ref long   value);\nulong  passthrough_ref(ref ulong  value);\nfloat  passthrough_ref(ref float  value);\ndouble passthrough_ref(ref double value);\nS      passthrough_ref(ref S      value);\nstd.test19248 passthrough_ref(ref const(std.test19248) value);\n}\n\ntemplate IsSigned(T)\n{\n    enum IsSigned = is(T==byte)  ||\n                    is(T==short) ||\n                    is(T==int)   ||\n                    is(T==long);\n}\n\ntemplate IsUnsigned(T)\n{\n    enum IsUnsigned = is(T==ubyte)  ||\n                      is(T==ushort) ||\n                      is(T==uint)   ||\n                      is(T==ulong);\n}\n\ntemplate IsIntegral(T)\n{\n    enum IsIntegral = IsSigned!T || IsUnsigned!T;\n}\n\ntemplate IsFloatingPoint(T)\n{\n    enum IsFloatingPoint = is(T==float) || is(T==double) || is(T==real);\n}\n\ntemplate IsBoolean(T)\n{\n    enum IsBoolean = is(T==bool);\n}\n\ntemplate IsSomeChar(T)\n{\n    enum IsSomeChar = is(T==char) || is(T==dchar);\n}\n\nvoid check(T)(T actual, T expected)\n{\n    assert(actual is expected);\n}\n\nvoid check(T)(T value)\n{\n    check(passthrough(value), value);\n    check(passthrough_ptr(&value), value);\n    check(passthrough_ref(value), value);\n}\n\nT[] values(T)()\n{\n    T[] values;\n    static if(IsBoolean!T)\n    {\n        values ~= true;\n        values ~= false;\n    }\n    else static if(IsSomeChar!T)\n    {\n        values ~= T.init;\n        values ~= T('a');\n        values ~= T('z');\n    }\n    else\n    {\n        values ~= T(0);\n        values ~= T(1);\n        static if(IsIntegral!T)\n        {\n            static if(IsSigned!T) values ~= T.min;\n            values ~= T.max;\n        }\n        else static if(IsFloatingPoint!T)\n        {\n            values ~= T.nan;\n            values ~= T.min_normal;\n            values ~= T.max;\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n    return values;\n}\n\nvoid main()\n{\n    foreach(bool val; values!bool())     check(val);\n    foreach(byte val; values!byte())     check(val);\n    foreach(ubyte val; values!ubyte())   check(val);\n    foreach(char val; values!char())     check(val);\n    foreach(dchar val; values!dchar())   check(val);\n    foreach(short val; values!short())   check(val);\n    foreach(ushort val; values!ushort()) check(val);\n    foreach(int val; values!int())       check(val);\n    foreach(uint val; values!uint())     check(val);\n    foreach(long val; values!long())     check(val);\n    foreach(ulong val; values!ulong())   check(val);\n    foreach(float val; values!float())   check(val);\n    foreach(double val; values!double()) check(val);\n    check(S());\n    check(std.test19248());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/cpp_stdlib.d",
    "content": "// DISABLED: win32 win64 osx32\n// EXTRA_CPP_SOURCES: cpp_stdlib.cpp\n// CXXFLAGS: -std=c++11\nimport core.stdc.stdio;\n\n// Disabled on windows because it needs bindings\n// Disabled on osx32 because size_t is not properly mangled\n\nversion (CppRuntime_Clang)\n{\n    extern(C++, `std`, `__1`)\n    {\n        struct allocator(T);\n        struct vector (T, A = allocator!T);\n        struct array (T, size_t N);\n    }\n}\nelse\n{\n    extern(C++, `std`)\n    {\n        struct allocator(T);\n        struct vector (T, A = allocator!T);\n        struct array (T, size_t N);\n    }\n}\n\nextern(C++):\n\nref T identity (T) (ref T v);\nT** identityPP (T) (T** v);\nvector!T* getVector (T) (size_t length, const T* ptr);\narray!(T, N)* getArray(T, size_t N) (const T* ptr);\n\nvoid main ()\n{\n    int i = 42;\n    float f = 21.0f;\n\n    int* pi = &i;\n    float* pf = &f;\n\n    assert(42 == identity(i));\n    assert(21.0f == identity(f));\n    assert(&pi == identityPP(&pi));\n    assert(&pf == identityPP(&pf));\n\n    auto vi = getVector(1, &i);\n    auto vf = getVector(3, [f, f, f].ptr);\n    assert(vi !is null);\n    assert(vf !is null);\n\n    auto ai = getArray!(int, 4)([2012, 10, 11, 42].ptr);\n    auto af = getArray!(float, 4)([42.0f, 21.0f, 14.0f, 1957.0f].ptr);\n    assert(ai !is null);\n    assert(af !is null);\n\n    printf(\"Success\\n\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/cppa.d",
    "content": "// PERMUTE_ARGS: -g -version=PULL8152\n// EXTRA_CPP_SOURCES: extra-files/cppb.cpp\n// EXTRA_FILES: extra-files/cppb.h\n\nimport core.stdc.stdio;\nimport core.stdc.stdarg;\nimport core.stdc.config;\nimport core.stdc.stdint;\n\nextern (C++)\n        int foob(int i, int j, int k);\n\nclass C\n{\n    extern (C++) int bar(int i, int j, int k)\n    {\n        printf(\"this = %p\\n\", this);\n        printf(\"i = %d\\n\", i);\n        printf(\"j = %d\\n\", j);\n        printf(\"k = %d\\n\", k);\n        return 1;\n    }\n}\n\n\nextern (C++)\n        int foo(int i, int j, int k)\n{\n    printf(\"i = %d\\n\", i);\n    printf(\"j = %d\\n\", j);\n    printf(\"k = %d\\n\", k);\n    assert(i == 1);\n    assert(j == 2);\n    assert(k == 3);\n    return 1;\n}\n\nvoid test1()\n{\n    foo(1, 2, 3);\n\n    auto i = foob(1, 2, 3);\n    assert(i == 7);\n\n    C c = new C();\n    c.bar(4, 5, 6);\n}\n\n/****************************************/\n\nextern (C++) interface D\n{\n    int bar(int i, int j, int k);\n}\n\nextern (C++) D getD();\n\nvoid test2()\n{\n    D d = getD();\n    int i = d.bar(9,10,11);\n    assert(i == 8);\n}\n\n/****************************************/\n\nextern (C++) int callE(E);\n\nextern (C++) interface E\n{\n    int bar(int i, int j, int k);\n}\n\nclass F : E\n{\n    extern (C++) int bar(int i, int j, int k)\n    {\n        printf(\"F.bar: i = %d\\n\", i);\n        printf(\"F.bar: j = %d\\n\", j);\n        printf(\"F.bar: k = %d\\n\", k);\n        assert(i == 11);\n        assert(j == 12);\n        assert(k == 13);\n        return 8;\n    }\n}\n\nvoid test3()\n{\n    F f = new F();\n    int i = callE(f);\n    assert(i == 8);\n}\n\n/****************************************/\n\nextern (C++) void foo4(char* p);\n\nvoid test4()\n{\n    foo4(null);\n}\n\n/****************************************/\n\nextern(C++)\n{\n  struct foo5 { int i; int j; void* p; }\n\n  interface bar5{\n    foo5 getFoo(int i);\n  }\n\n  bar5 newBar();\n}\n\nvoid test5()\n{\n  bar5 b = newBar();\n  foo5 f = b.getFoo(4);\n  printf(\"f.p = %p, b = %p\\n\", f.p, cast(void*)b);\n  assert(f.p == cast(void*)b);\n}\n\n\n/****************************************/\n\nextern(C++)\n{\n    struct S6\n    {\n        int i;\n        double d;\n    }\n\n    union S6_2\n    {\n        int i;\n        double d;\n    }\n\n    enum S6_3\n    {\n        A, B\n    }\n\n    S6 foo6();\n    S6_2 foo6_2();\n    S6_3 foo6_3();\n}\n\nextern (C) int foosize6();\n\nvoid test6()\n{\n    S6 f = foo6();\n    printf(\"%d %d\\n\", foosize6(), S6.sizeof);\n    assert(foosize6() == S6.sizeof);\nversion (X86)\n{\n    assert(f.i == 42);\n    printf(\"f.d = %g\\n\", f.d);\n    assert(f.d == 2.5);\n    assert(foo6_2().i == 42);\n    assert(foo6_3() == S6_3.A);\n}\n}\n\n/****************************************/\n\nextern (C) int foo7();\n\nstruct S\n{\n    int i;\n    long l;\n}\n\nvoid test7()\n{\n    printf(\"%d %d\\n\", foo7(), S.sizeof);\n    assert(foo7() == S.sizeof);\n}\n\n/****************************************/\n\nextern (C++) void foo8(const(char)*);\n\nvoid test8()\n{\n    char c;\n    foo8(&c);\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4059\n\nstruct elem9 { }\n\nextern(C++) void foobar9(elem9*, elem9*);\n\nvoid test9()\n{\n    elem9 *a;\n    foobar9(a, a);\n}\n\n/****************************************/\n\n\nstruct A11802;\nstruct B11802;\n\nextern(C++) class C11802\n{\n    int x;\n    void fun(A11802*) { x += 2; }\n    void fun(B11802*) { x *= 2; }\n}\n\nextern(C++) class D11802 : C11802\n{\n    override void fun(A11802*) { x += 3; }\n    override void fun(B11802*) { x *= 3; }\n}\n\nextern(C++) void test11802x(D11802);\n\nvoid test11802()\n{\n    auto x = new D11802();\n    x.x = 0;\n    test11802x(x);\n    assert(x.x == 9);\n}\n\n\n/****************************************/\n\nstruct S13956\n{\n}\n\nextern(C++) void func13956(S13956 arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);\n\nextern(C++) void check13956(S13956 arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)\n{\n    assert(arg0 == S13956());\n    assert(arg1 == 1);\n    assert(arg2 == 2);\n    assert(arg3 == 3);\n    assert(arg4 == 4);\n    assert(arg5 == 5);\n    assert(arg6 == 6);\n}\n\nvoid test13956()\n{\n    func13956(S13956(), 1, 2, 3, 4, 5, 6);\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5148\n\nextern (C++)\n{\n    void foo10(const(char)*, const(char)*);\n    void foo10(const int, const int);\n    void foo10(const char, const char);\n    void foo10(bool, bool);\n\n    struct MyStructType { }\n    void foo10(const MyStructType s, const MyStructType t);\n\n    enum MyEnumType { onemember }\n    void foo10(const MyEnumType s, const MyEnumType t);\n}\n\nvoid test10()\n{\n    char* p;\n    foo10(p, p);\n    foo10(1,2);\n    foo10('c','d');\n    MyStructType s;\n    foo10(s,s);\n    MyEnumType e;\n    foo10(e,e);\n}\n\n/****************************************/\n\nextern (C++, N11.M) { void bar11(); }\n\nextern (C++, A11.B) { extern (C++, C) { void bar(); }}\n\nvoid test11()\n{\n    bar11();\n    A11.B.C.bar();\n}\n/****************************************/\n\nstruct Struct10071\n{\n    void *p;\n    c_long_double r;\n}\n\nextern(C++) size_t offset10071();\nvoid test10071()\n{\n    assert(offset10071() == Struct10071.r.offsetof);\n}\n\n/****************************************/\n\nchar[100] valistbuffer;\n\nextern(C++) void myvprintfx(const(char)* format, va_list va)\n{\n    vsprintf(valistbuffer.ptr, format, va);\n}\nextern(C++) void myvprintf(const(char)*, va_list);\nextern(C++) void myprintf(const(char)* format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    myvprintf(format, ap);\n    va_end(ap);\n}\n\nvoid testvalist()\n{\n    myprintf(\"hello %d\", 999);\n    assert(valistbuffer[0..9] == \"hello 999\");\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12825\n\nextern(C++) class C12825\n{\n    uint a = 0x12345678;\n}\n\nvoid test12825()\n{\n    auto c = new C12825();\n}\n\n/****************************************/\n\nstruct S13955a\n{\n    float a;\n    double b;\n}\n\nstruct S13955b\n{\n    double a;\n    float b;\n}\n\nstruct S13955c\n{\n    float a;\n    float b;\n}\n\nstruct S13955d\n{\n    double a;\n    double b;\n}\n\nextern(C++) void check13955(S13955a a, S13955b b, S13955c c, S13955d d)\n{\n    assert(a.a == 2);\n    assert(a.b == 4);\n    assert(b.a == 8);\n    assert(b.b == 16);\n    assert(c.a == 32);\n    assert(c.b == 64);\n    assert(d.a == 128);\n    assert(d.b == 256);\n}\n\nextern(C++) void func13955(S13955a a, S13955b b, S13955c c, S13955d d);\n\nvoid test13955()\n{\n    func13955(S13955a(2, 4), S13955b(8, 16), S13955c(32, 64), S13955d(128, 256));\n}\n\n/****************************************/\n\nextern(C++) class C13161\n{\n    void dummyfunc();\n    long val_5;\n    uint val_9;\n}\n\nextern(C++) class Test : C13161\n{\n    uint val_0;\n    long val_1;\n}\n\nextern(C++) size_t getoffset13161();\n\nextern(C++) class C13161a\n{\n    void dummyfunc();\n    c_long_double val_5;\n    uint val_9;\n}\n\nextern(C++) class Testa : C13161a\n{\n    bool val_0;\n}\n\nextern(C++) size_t getoffset13161a();\n\nvoid test13161()\n{\n    assert(getoffset13161() == Test.val_0.offsetof);\n    assert(getoffset13161a() == Testa.val_0.offsetof);\n}\n\n/****************************************/\n\nversion (linux)\n{\n    extern(C++, __gnu_cxx)\n    {\n        struct new_allocator(T)\n        {\n            alias size_type = size_t;\n            static if (is(T : char))\n                void deallocate(T*, size_type) { }\n            else\n                void deallocate(T*, size_type);\n        }\n    }\n}\n\nextern (C++, std)\n{\n    extern (C++, class) struct allocator(T)\n    {\n        version (linux)\n        {\n            alias size_type = size_t;\n            void deallocate(T* p, size_type sz)\n            {   (cast(__gnu_cxx.new_allocator!T*)&this).deallocate(p, sz); }\n        }\n    }\n\n    class vector(T, A = allocator!T)\n    {\n        final void push_back(ref const T);\n    }\n\n    struct char_traits(T)\n    {\n    }\n\n    // https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html\n    version (none)\n    {\n        extern (C++, __cxx11)\n        {\n            struct basic_string(T, C = char_traits!T, A = allocator!T)\n            {\n            }\n        }\n    }\n    else\n    {\n        extern (C++, class) struct basic_string(T, C = char_traits!T, A = allocator!T)\n        {\n        }\n    }\n\n    struct basic_istream(T, C = char_traits!T)\n    {\n    }\n\n    struct basic_ostream(T, C = char_traits!T)\n    {\n    }\n\n    struct basic_iostream(T, C = char_traits!T)\n    {\n    }\n\n    class exception { }\n\n    // https://issues.dlang.org/show_bug.cgi?id=14956\n    extern(C++, N14956)\n    {\n        struct S14956 { }\n    }\n}\n\nextern (C++)\n{\n    version (linux)\n    {\n        void foo14(std.vector!(int) p);\n        void foo14a(std.basic_string!(char) *p);\n        void foo14b(std.basic_string!(int) *p);\n        void foo14c(std.basic_istream!(char) *p);\n        void foo14d(std.basic_ostream!(char) *p);\n        void foo14e(std.basic_iostream!(char) *p);\n\n        void foo14f(std.char_traits!char* x, std.basic_string!char* p, std.basic_string!char* q);\n    }\n}\n\nvoid test14()\n{\n    version (linux)\n    {\n        std.vector!int p;\n        foo14(p);\n\n        foo14a(null);\n        foo14b(null);\n        foo14c(null);\n        foo14d(null);\n        foo14e(null);\n        foo14f(null, null, null);\n    }\n}\n\nversion (linux)\n{\n    void test14a(std.allocator!int * pa)\n    {\n    pa.deallocate(null, 0);\n    }\n\n    void gun(std.vector!int pa)\n    {\n    int x = 42;\n    pa.push_back(x);\n    }\n}\n\nvoid test13289()\n{\n    assert(f13289_cpp_wchar_t('a') == 'A');\n    assert(f13289_cpp_wchar_t('B') == 'B');\n    assert(f13289_d_wchar('c') == 'C');\n    assert(f13289_d_wchar('D') == 'D');\n    assert(f13289_d_dchar('e') == 'E');\n    assert(f13289_d_dchar('F') == 'F');\n    assert(f13289_cpp_test());\n}\n\nextern(C++)\n{\n    bool f13289_cpp_test();\n\n    version(Posix)\n    {\n        dchar f13289_cpp_wchar_t(dchar);\n    }\n    else version(Windows)\n    {\n        wchar f13289_cpp_wchar_t(wchar);\n    }\n\n    wchar f13289_d_wchar(wchar ch)\n    {\n        if (ch <= 'z' && ch >= 'a')\n        {\n            return cast(wchar)(ch - ('a' - 'A'));\n        }\n        else\n        {\n            return ch;\n        }\n    }\n    dchar f13289_d_dchar(dchar ch)\n    {\n        if (ch <= 'z' && ch >= 'a')\n        {\n            return ch - ('a' - 'A');\n        }\n        else\n        {\n            return ch;\n        }\n    }\n}\n\n/****************************************/\n\nversion (CRuntime_Microsoft)\n{\n    version (PULL8152)\n    {\n        enum __c_long_double : double;\n    }\n    else\n    {\n        struct __c_long_double\n        {\n            this(double d) { ld = d; }\n            double ld;\n            alias ld this;\n        }\n    }\n    alias __c_long_double myld;\n}\nelse\n    alias c_long_double myld;\n\nextern (C++) myld testld(myld);\n\n\nvoid test15()\n{\n    myld ld = 5.0;\n    ld = testld(ld);\n    assert(ld == 6.0);\n}\n\n/****************************************/\n\nversion( Windows )\n{\n    alias int   x_long;\n    alias uint  x_ulong;\n}\nelse\n{\n  static if( (void*).sizeof > int.sizeof )\n  {\n    alias long  x_long;\n    alias ulong x_ulong;\n  }\n  else\n  {\n    alias int   x_long;\n    alias uint  x_ulong;\n  }\n}\n\nversion (PULL8152)\n{\n    enum __c_long : x_long;\n    enum __c_ulong : x_ulong;\n}\nelse\n{\n    struct __c_long\n    {\n        this(x_long d) { ld = d; }\n        x_long ld;\n        alias ld this;\n    }\n\n    struct __c_ulong\n    {\n        this(x_ulong d) { ld = d; }\n        x_ulong ld;\n        alias ld this;\n    }\n}\n\nalias __c_long mylong;\nalias __c_ulong myulong;\n\nextern (C++) mylong testl(mylong);\nextern (C++) myulong testul(myulong);\n\n\nvoid test16()\n{\n  {\n    mylong ld = 5;\n    ld = testl(ld);\n    printf(\"ld = %lld, mylong.sizeof = %lld\\n\", cast(long)ld, cast(long)mylong.sizeof);\n    assert(ld == 5 + mylong.sizeof);\n  }\n  {\n    myulong ld = 5;\n    ld = testul(ld);\n    assert(ld == 5 + myulong.sizeof);\n  }\n\n    version (PULL8152)\n    {\n        static if (__c_long.sizeof == long.sizeof)\n        {\n            static assert(__c_long.max == long.max);\n            static assert(__c_long.min == long.min);\n            static assert(__c_long.init == long.init);\n\n            static assert(__c_ulong.max == ulong.max);\n            static assert(__c_ulong.min == ulong.min);\n            static assert(__c_ulong.init == ulong.init);\n\n            __c_long cl = 0;\n            cl = cl + 1;\n            long l = cl;\n            cl = l;\n\n            __c_ulong cul = 0;\n            cul = cul + 1;\n            ulong ul = cul;\n            cul = ul;\n        }\n        else static if (__c_long.sizeof == int.sizeof)\n        {\n            static assert(__c_long.max == int.max);\n            static assert(__c_long.min == int.min);\n            static assert(__c_long.init == int.init);\n\n            static assert(__c_ulong.max == uint.max);\n            static assert(__c_ulong.min == uint.min);\n            static assert(__c_ulong.init == uint.init);\n\n            __c_long cl = 0;\n            cl = cl + 1;\n            int i = cl;\n            cl = i;\n\n            __c_ulong cul = 0;\n            cul = cul + 1;\n            uint u = cul;\n            cul = u;\n        }\n        else\n            static assert(0);\n    }\n}\n\n\n/****************************************/\n\nstruct S13707\n{\n    void* a;\n    void* b;\n    this(void* a, void* b)\n    {\n        this.a = a;\n        this.b = b;\n    }\n}\n\nextern(C++) S13707 func13707();\n\nvoid test13707()\n{\n    auto p = func13707();\n    assert(p.a == null);\n    assert(p.b == null);\n}\n\n/****************************************/\n\nstruct S13932(int x)\n{\n        int member;\n}\n\nextern(C++) void func13932(S13932!(-1) s);\n\n/****************************************/\n\nextern(C++, N13337.M13337)\n{\n  struct S13337{}\n  void foo13337(S13337 s);\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14195\n\nstruct Delegate1(T) {}\nstruct Delegate2(T1, T2) {}\n\ntemplate Signature(T)\n{\n    alias Signature = typeof(*(T.init));\n}\n\nextern(C++)\n{\n    alias del1_t = Delegate1!(Signature!(void function()));\n    alias del2_t = Delegate2!(Signature!(int function(float, double)), Signature!(int function(float, double)));\n    void test14195a(del1_t);\n    void test14195b(del2_t);\n}\n\nvoid test14195()\n{\n    test14195a(del1_t());\n    test14195b(del2_t());\n}\n\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14200\n\ntemplate Tuple14200(T...)\n{\n  alias Tuple14200 = T;\n}\n\nextern(C++) void test14200a(Tuple14200!(int));\nextern(C++) void test14200b(float, Tuple14200!(int, double));\n\nvoid test14200()\n{\n  test14200a(1);\n  test14200b(1.0f, 1, 1.0);\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14956\n\nextern(C++) void test14956(S14956 s);\n\n/****************************************/\n// check order of overloads in vtable\n\nextern (C++) class Statement {}\nextern (C++) class ErrorStatement {}\nextern (C++) class PeelStatement {}\nextern (C++) class ExpStatement {}\nextern (C++) class DtorExpStatement {}\n\nextern (C++) class Visitor\n{\npublic:\n    int visit(Statement) { return 1; }\n    int visit(ErrorStatement) { return 2; }\n    int visit(PeelStatement) { return 3; }\n}\n\nextern (C++) class Visitor2 : Visitor\n{\n    int visit2(ExpStatement) { return 4; }\n    int visit2(DtorExpStatement) { return 5; }\n}\n\nextern(C++) bool testVtableCpp(Visitor2 sv);\nextern(C++) Visitor2 getVisitor2();\n\nbool testVtableD(Visitor2 sv)\n{\n    Statement s1;\n    ErrorStatement s2;\n    PeelStatement s3;\n    ExpStatement s4;\n    DtorExpStatement s5;\n\n    if (sv.visit(s1) != 1) return false;\n    if (sv.visit(s2) != 2) return false;\n    if (sv.visit(s3) != 3) return false;\n    if (sv.visit2(s4) != 4) return false;\n    if (sv.visit2(s5) != 5) return false;\n    return true;\n}\n\nvoid testVtable()\n{\n    Visitor2 dinst = new Visitor2;\n    if (!testVtableCpp(dinst))\n        assert(0);\n\n    Visitor2 cppinst = getVisitor2();\n    if (!testVtableD(cppinst))\n        assert(0);\n}\n\n/****************************************/\n/* problems detected by fuzzer */\nextern(C++) void fuzz1_cppvararg(int64_t arg10, int64_t arg11, bool arg12);\nextern(C++) void fuzz1_dvararg(int64_t arg10, int64_t arg11, bool arg12)\n{\n    fuzz1_checkValues(arg10, arg11, arg12);\n}\n\nextern(C++) void fuzz1_checkValues(int64_t arg10, int64_t arg11, bool arg12)\n{\n    assert(arg10 == 103);\n    assert(arg11 == 104);\n    assert(arg12 == false);\n}\n\nvoid fuzz1()\n{\n    long arg10 = 103;\n    long arg11 = 104;\n    bool arg12 = false;\n    fuzz1_dvararg(arg10, arg11, arg12);\n    fuzz1_cppvararg(arg10, arg11, arg12);\n}\n\n////////\nextern(C++) void fuzz2_cppvararg(uint64_t arg10, uint64_t arg11, bool arg12);\nextern(C++) void fuzz2_dvararg(uint64_t arg10, uint64_t arg11, bool arg12)\n{\n    fuzz2_checkValues(arg10, arg11, arg12);\n}\n\nextern(C++) void fuzz2_checkValues(uint64_t arg10, uint64_t arg11, bool arg12)\n{\n    assert(arg10 == 103);\n    assert(arg11 == 104);\n    assert(arg12 == false);\n}\n\nvoid fuzz2()\n{\n    ulong arg10 = 103;\n    ulong arg11 = 104;\n    bool arg12 = false;\n    fuzz2_dvararg(arg10, arg11, arg12);\n    fuzz2_cppvararg(arg10, arg11, arg12);\n}\n\n////////\nextern(C++) void fuzz3_cppvararg(wchar arg10, wchar arg11, bool arg12);\nextern(C++) void fuzz3_dvararg(wchar arg10, wchar arg11, bool arg12)\n{\n    fuzz2_checkValues(arg10, arg11, arg12);\n}\n\nextern(C++) void fuzz3_checkValues(wchar arg10, wchar arg11, bool arg12)\n{\n    assert(arg10 == 103);\n    assert(arg11 == 104);\n    assert(arg12 == false);\n}\n\nvoid fuzz3()\n{\n    wchar arg10 = 103;\n    wchar arg11 = 104;\n    bool arg12 = false;\n    fuzz3_dvararg(arg10, arg11, arg12);\n    fuzz3_cppvararg(arg10, arg11, arg12);\n}\n\nvoid fuzz()\n{\n    fuzz1();\n    fuzz2();\n    fuzz3();\n}\n\n/****************************************/\n\nextern (C++)\n{\n    void throwit();\n}\n\nvoid testeh()\n{\n    printf(\"testeh()\\n\");\n    version (linux)\n    {\n        version (X86_64)\n        {\n            bool caught;\n            try\n            {\n                throwit();\n            }\n            catch (std.exception e)\n            {\n                caught = true;\n            }\n            assert(caught);\n        }\n    }\n}\n\n/****************************************/\n\nversion (linux)\n{\n    version (X86_64)\n    {\n        bool raii_works = false;\n        struct RAIITest\n        {\n           ~this()\n           {\n               raii_works = true;\n           }\n        }\n\n        void dFunction()\n        {\n            RAIITest rt;\n            throwit();\n        }\n\n        void testeh2()\n        {\n            printf(\"testeh2()\\n\");\n            try\n            {\n                dFunction();\n            }\n            catch(std.exception e)\n            {\n                assert(raii_works);\n            }\n        }\n    }\n    else\n        void testeh2() { }\n}\nelse\n    void testeh2() { }\n\n/****************************************/\n\nextern (C++) { void throwle(); void throwpe(); }\n\nvoid testeh3()\n{\n    printf(\"testeh3()\\n\");\n    version (linux)\n    {\n        version (X86_64)\n        {\n            bool caught = false;\n            try\n            {\n               throwle();\n            }\n            catch (std.exception e)  //polymorphism test.\n            {\n                caught = true;\n            }\n            assert(caught);\n        }\n    }\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15576\n\nextern (C++, ns15576)\n{\n    extern __gshared int global15576;\n\n    extern (C++, ns)\n    {\n        extern __gshared int n_global15576;\n    }\n}\n\nvoid test15576()\n{\n    global15576 = n_global15576 = 123;\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15579\n\nextern (C++)\n{\n    class Base\n    {\n        //~this() {}\n        void based() { }\n        ubyte x = 4;\n    }\n\n    interface Interface\n    {\n        int MethodCPP();\n        int MethodD();\n    }\n\n    class Derived : Base, Interface\n    {\n        short y = 5;\n        int MethodCPP();\n        int MethodD() {\n            printf(\"Derived.MethodD(): this = %p, x = %d, y = %d\\n\", this, x, y);\n            Derived p = this;\n            //p = cast(Derived)(cast(void*)p - 16);\n            assert(p.x == 4 || p.x == 7);\n            assert(p.y == 5 || p.y == 8);\n            return 3;\n        }\n        int Method() { return 6; }\n    }\n\n    Derived cppfoo(Derived);\n    Interface cppfooi(Interface);\n}\n\nvoid test15579()\n{\n    Derived d = new Derived();\n    printf(\"d = %p\\n\", d);\n    assert(d.x == 4);\n    assert(d.y == 5);\n    assert((cast(Interface)d).MethodCPP() == 30);\n    assert((cast(Interface)d).MethodD() == 3);\n    assert(d.MethodCPP() == 30);\n    assert(d.MethodD() == 3);\n    assert(d.Method() == 6);\n\n    d = cppfoo(d);\n    assert(d.x == 7);\n    assert(d.y == 8);\n\n    printf(\"d2 = %p\\n\", d);\n\n    /* Casting to an interface involves thunks in the vtbl[].\n     * g++ puts the thunks for MethodD in the same COMDAT as MethodD.\n     * But D doesn't, so when the linker \"picks one\" of the D generated MethodD\n     * or the g++ generated MethodD, it may wind up with a messed up thunk,\n     * resulting in a seg fault. The solution is to not expect objects of the same\n     * type to be constructed on both sides of the D/C++ divide if the same member\n     * function (in this case, MethodD) is also defined on both sides.\n     */\n    version (Windows)\n    {\n        assert((cast(Interface)d).MethodD() == 3);\n    }\n    assert((cast(Interface)d).MethodCPP() == 30);\n\n    assert(d.Method() == 6);\n\n    printf(\"d = %p, i = %p\\n\", d, cast(Interface)d);\n    version (Windows)\n    {\n        Interface i = cppfooi(d);\n        printf(\"i2: %p\\n\", i);\n        assert(i.MethodD() == 3);\n        assert(i.MethodCPP() == 30);\n    }\n    printf(\"test15579() done\\n\");\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15610\n\nextern(C++) class Base2\n{\n    int i;\n    void baser() { }\n}\n\nextern(C++) interface Interface2 { abstract void f(); }\n\nextern(C++) class Derived2 : Base2, Interface2\n{\n    final\n        override void f();\n}\n\n\nvoid test15610()\n{\n    auto c = new Derived2();\n    printf(\"test15610(): c = %p\\n\", c);\n    c.i = 3;\n    c.f();\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15455\n\nstruct X6\n{\n    ushort a;\n    ushort b;\n    ubyte c;\n    ubyte d;\n}\n\nstatic assert(X6.sizeof == 6);\n\nstruct X8\n{\n    ushort a;\n    X6 b;\n}\n\nstatic assert(X8.sizeof == 8);\n\nvoid test15455a(X8 s)\n{\n    assert(s.a == 1);\n    assert(s.b.a == 2);\n    assert(s.b.b == 3);\n    assert(s.b.c == 4);\n    assert(s.b.d == 5);\n}\n\nextern (C++) void test15455b(X8 s);\n\nvoid test15455()\n{\n    X8 s;\n\n    s.a = 1;\n    s.b.a = 2;\n    s.b.b = 3;\n    s.b.c = 4;\n    s.b.d = 5;\n    test15455a(s);\n    test15455b(s);\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15372\n\nextern(C++) int foo15372(T)(int v);\n\nvoid test15372()\n{\n    version(Windows){}\n    else\n        assert(foo15372!int(1) == 1);\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15802\n\nextern(C++) {\n    template Foo15802(T) {\n        static int boo(T v);\n    }\n}\n\nvoid test15802()\n{\n    version(Windows){}\n    else\n        assert(Foo15802!(int).boo(1) == 1);\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16536\n// mangling mismatch on OSX\n\nversion(OSX) extern(C++) uint64_t pass16536(uint64_t);\n\nvoid test16536()\n{\n    version(OSX) assert(pass16536(123) == 123);\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15589\n// extern(C++) virtual destructors are not put in vtbl[]\n\nextern(C++)\n{\n    class A15589\n    {\n        extern(D) static int[] dtorSeq;\n        struct S\n        {\n            this(int x) { this.x = x; }\n            ~this() { dtorSeq ~= x; }\n            int x;\n        }\n        int foo() { return 100; } // shift dtor to slot 1\n        ~this() { dtorSeq ~= 10; }\n        S s1 = S(1);\n        S s2 = S(2);\n    }\n    class B15589 : A15589\n    {\n        int bar() { return 200;} // add an additional function AFTER the dtor at slot 2\n        ~this() { dtorSeq ~= 20; }\n        S s3 = S(3);\n    }\n\n    void test15589b(A15589 p);\n}\n\nvoid test15589()\n{\n    A15589 c = new B15589;\n    assert(A15589.dtorSeq == null);\n    assert(c.foo() == 100);\n    assert((cast(B15589)c).bar() == 200);\n    c.__xdtor(); // virtual dtor call\n    assert(A15589.dtorSeq[] == [ 20, 3, 10, 2, 1 ]); // destroyed full hierarchy!\n\n    A15589.dtorSeq = null;\n    test15589b(c);\n    assert(A15589.dtorSeq[] == [ 20, 3, 10, 2, 1 ]); // destroyed full hierarchy!\n}\n\nextern(C++)\n{\n    class Cpp15589Base\n    {\n    public:\n        final ~this();\n\n        void nonVirtual();\n        int a;\n    }\n\n    class Cpp15589Derived : Cpp15589Base\n    {\n    public:\n        this();\n        final ~this();\n        int b;\n    }\n\n    class Cpp15589BaseVirtual\n    {\n    public:\n        void beforeDtor();\n\n        this();\n        ~this();\n\n        void afterDtor();\n        int c = 1;\n    }\n\n    class Cpp15589DerivedVirtual : Cpp15589BaseVirtual\n    {\n    public:\n        this();\n        ~this();\n\n        override void afterDtor();\n\n        int d;\n    }\n\n    class Cpp15589IntroducingVirtual : Cpp15589Base\n    {\n    public:\n        this();\n        void beforeIntroducedVirtual();\n        ~this();\n        void afterIntroducedVirtual(int);\n\n        int e;\n    }\n\n    struct Cpp15589Struct\n    {\n        ~this();\n        int s;\n    }\n\n    void trace15589(int ch)\n    {\n        traceBuf[traceBufPos++] = cast(char) ch;\n    }\n}\n\n__gshared char[32] traceBuf;\n__gshared size_t traceBufPos;\n\nmixin template scopeAllocCpp(C)\n{\n    // workaround for https://issues.dlang.org/show_bug.cgi?id=18986\n    version(OSX)\n        enum cppCtorReturnsThis = false;\n    else version(FreeBSD)\n        enum cppCtorReturnsThis = false;\n    else\n        enum cppCtorReturnsThis = true;\n\n    static if (cppCtorReturnsThis)\n        scope C ptr = new C;\n    else\n    {\n        ubyte[__traits(classInstanceSize, C)] data;\n        C ptr = (){ auto p = cast(C) data.ptr; p.__ctor(); return p; }();\n    }\n}\n\nvoid test15589b()\n{\n    traceBufPos = 0;\n    {\n        Cpp15589Struct struc = Cpp15589Struct();\n        mixin scopeAllocCpp!Cpp15589Derived derived;\n        mixin scopeAllocCpp!Cpp15589DerivedVirtual derivedVirtual;\n        mixin scopeAllocCpp!Cpp15589IntroducingVirtual introducingVirtual;\n\n        introducingVirtual.ptr.destroy();\n        derivedVirtual.ptr.destroy();\n        derived.ptr.destroy();\n    }\n    printf(\"traceBuf15589 %.*s\\n\", cast(int)traceBufPos, traceBuf.ptr);\n    assert(traceBuf[0..traceBufPos] == \"IbVvBbs\");\n}\n\n/****************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=18928\n// Win64: extern(C++) bad codegen, wrong calling convention\n\nextern(C++) struct Small18928\n{\n    int x;\n}\n\nextern(C++) class CC18928\n{\n    Small18928 getVirtual(); // { return S(3); }\n    final Small18928 getFinal(); // { return S(4); }\n    static Small18928 getStatic(); // { return S(5); }\n}\n\nextern(C++) CC18928 newCC18928();\n\nvoid test18928()\n{\n    auto cc = newCC18928();\n    Small18928 v = cc.getVirtual();\n    assert(v.x == 3);\n    Small18928 f = cc.getFinal();\n    assert(f.x == 4);\n    Small18928 s = cc.getStatic();\n    assert(s.x == 5);\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18953\n// Win32: extern(C++) struct destructor not called correctly through runtime\n\nextern(C++)\nstruct S18953\n{\n    char x;\n    ~this() nothrow @nogc { traceBuf[traceBufPos++] = x; }\n}\n\nvoid test18953()\n{\n    traceBufPos = 0;\n    S18953[] arr = new S18953[3];\n    arr[1].x = '1';\n    arr[2].x = '2';\n    arr.length = 1;\n    assumeSafeAppend(arr); // destroys arr[1] and arr[2]\n    printf(\"traceBuf18953 %.*s\\n\", cast(int)traceBufPos, traceBuf.ptr);\n    assert(traceBuf[0..traceBufPos] == \"21\");\n}\n\n/****************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=18966\n\nextern(C++):\nclass Base18966\n{\n    this() @safe nothrow;\n    ~this();\n    void vf();\n    int x;\n}\n\nclass Derived18966 : Base18966\n{\n    override void vf() { x = 200; }\n}\n\nclass Explicit18966 : Base18966\n{\n    this() @safe { super(); }\n    override void vf() { x = 250; }\n}\n\nclass Implicit18966 : Base18966\n{\n    this() nothrow {}\n    override void vf() { x = 300; }\n}\n\n// test vptr in full ctor chain of mixed D/C++ class hierarchies\n\n// TODO: Make this a D class and let C++ derive from it. This works on Windows,\n//       but results in linker errors on Posix due to extra base ctor (`C2`\n//       mangling) being called by the B ctor.\nclass A18966 // in C++\n{\n    char[8] calledOverloads = 0;\n    int i;\n    this();\n    void foo();\n}\n\nclass B18966 : A18966 // in C++\n{\n    this();\n    override void foo();\n}\n\nclass C18966 : B18966\n{\n    this() { foo(); }\n    override void foo() { calledOverloads[i++] = 'C'; }\n}\n\nclass D18966 : C18966\n{\n    this() { foo(); }\n    override void foo() { calledOverloads[i++] = 'D'; }\n}\n\nvoid test18966()\n{\n    Derived18966 d = new Derived18966;\n    assert(d.x == 10);\n    d.vf();\n    assert(d.x == 200);\n\n    Explicit18966 e = new Explicit18966;\n    assert(e.x == 10);\n    e.vf();\n    assert(e.x == 250);\n\n    Implicit18966 i = new Implicit18966;\n    assert(i.x == 10);\n    i.vf();\n    assert(i.x == 300);\n\n    // TODO: Allocating + constructing a C++ class with the D GC is not\n    //       supported on Posix. The returned pointer (probably from C++ ctor)\n    //       seems to be an offset and not the actual object address.\n    version (Windows)\n    {\n        auto a = new A18966;\n        assert(a.calledOverloads[0..2] == \"A\\0\");\n\n        auto b = new B18966;\n        assert(b.calledOverloads[0..3] == \"AB\\0\");\n    }\n\n    auto c = new C18966;\n    assert(c.calledOverloads[0..4] == \"ABC\\0\");\n\n    auto d2 = new D18966;\n    // note: the vptr semantics in ctors of extern(C++) classes may be revised (to \"ABCD\")\n    assert(d2.calledOverloads[0..5] == \"ABDD\\0\");\n}\n\n/****************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=19134\n\nclass Base19134\n{\n    int a = 123;\n    this() { a += 42; }\n    int foo() const { return a; }\n}\n\nclass Derived19134 : Base19134\n{\n    int b = 666;\n    this()\n    {\n        a *= 2;\n        b -= 6;\n    }\n    override int foo() const { return b; }\n}\n\nvoid test19134()\n{\n    static const d = new Derived19134;\n    assert(d.a == (123 + 42) * 2);\n    assert(d.b == 666 - 6);\n    assert(d.foo() == 660);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=18955\nalias std_string = std.basic_string!(char);\n\nextern(C++) void callback18955(ref const(std_string) str)\n{\n}\nextern(C++) void test18955();\n\n/****************************************/\n\nvoid main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test13956();\n    test5();\n    test6();\n    test10071();\n    test7();\n    test8();\n    test11802();\n    test9();\n    test10();\n    test13955();\n    test11();\n    testvalist();\n    test12825();\n    test13161();\n    test14();\n    test13289();\n    test15();\n    test16();\n    func13707();\n    func13932(S13932!(-1)(0));\n    foo13337(S13337());\n    test14195();\n    test14200();\n    test14956(S14956());\n    testVtable();\n    fuzz();\n    testeh();\n    testeh2();\n    testeh3();\n    test15576();\n    test15579();\n    test15610();\n    test15455();\n    test15372();\n    test15802();\n    test16536();\n    test15589();\n    test15589b();\n    test18928();\n    test18953();\n    test18966();\n    test19134();\n    test18955();\n    \n    printf(\"Success\\n\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ctorpowtests.d",
    "content": "// PERMUTE_ARGS:\n\nint magicVariable()\n{\n  if (__ctfe)\n   return 3;\n\n  version(GNU)\n  {\n    version(X86)\n      asm { \"nop\"; }\n    else version(X86_64)\n      asm { \"nop\"; }\n    else\n      static assert(\"\");\n  }\n  else\n      asm { nop; }\n  return 2;\n}\n\nstatic assert(magicVariable()==3);\n\nvoid main()\n{\n  assert(!__ctfe);\n  assert(magicVariable()==2);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=991 -- invalid.\n// https://issues.dlang.org/show_bug.cgi?id=3500 -- is this related to 2127?\n\n// Tests for ^^\n// TODO: These tests should not require import std.math.\n\nimport std.math;\n// Test float ^^ int\nstatic assert( 27.0 ^^ 5 == 27.0 * 27.0 * 27.0 * 27.0 * 27.0);\nstatic assert( 2.0 ^^ 3 == 8.0);\n\nstatic assert( 2.0 ^^ 4 == 16.0);\nstatic assert( 2 ^^ 4 == 16);\n\n// Check the typing rules.\nstatic assert( is (typeof(2.0^^7) == double));\nstatic assert( is (typeof(7^^3) == int));\n\nstatic assert( is (typeof(7L^^3) == long));\nstatic assert( is (typeof(7^^3L) == long));\nenum short POW_SHORT_1 = 3;\nenum short POW_SHORT_3 = 7;\nstatic assert( is (typeof(POW_SHORT_1 * POW_SHORT_1) ==\ntypeof(POW_SHORT_1*POW_SHORT_1)));\n\nstatic assert( is (typeof(7.0^^3) == double));\nstatic assert( is (typeof(7.0L^^3) == real));\nstatic assert( is (typeof(7.0f^^3) == float));\nstatic assert( is (typeof(POW_SHORT_1^^3.1) == double));\nstatic assert( is (typeof(POW_SHORT_1^^3.1f) == float));\nstatic assert( is (typeof(2.1f ^^ POW_SHORT_1) == float));\nstatic assert( is (typeof(7.0f^^3.1) == double));\nstatic assert( is (typeof(7.0^^3.1f) == double));\nstatic assert( is (typeof(7.0f^^3.1f) == float));\nstatic assert( is (typeof(7.0f^^3.1L) == real));\nstatic assert( is (typeof(7.0L^^3.1f) == real));\n// Check typing for special cases\nstatic assert( is (typeof(7.0f^^2) == float));\nstatic assert( is (typeof(7.0f^^2.0) == double));\nstatic assert( is (typeof(7.0f^^8.0) == double));\nstatic assert( is (typeof(1^^0.5f) == float));\nstatic assert( is (typeof(7^^0.5f) == float));\nstatic assert( is (typeof(3L^^0.5) == double));\nstatic assert( is (typeof(123^^17.0f) == float));\n\nstatic assert(POW_SHORT_1 ^^ 2 == 9);\nstatic assert(4.0 ^^ POW_SHORT_1 == 4.0*4.0*4.0);\nstatic assert(4.0 ^^ 7.0 == 4.0*4.0*4.0*4.0*4.0*4.0*4.0);\n\n// ^^ has higher precedence than multiply\nstatic assert( 2 * 2 ^^ 3 + 1 == 17);\nstatic assert( 2 ^^ 3 * 2 + 1 == 17);\n// ^^ has higher precedence than negate\nstatic assert( -2 ^^ 3 * 2 - 1 == -17);\n\n// ^^ is right associative\nstatic assert( 2 ^^ 3 ^^ 2 == 2 ^^ 9);\nstatic assert( 2.0 ^^ -3 ^^ 2 == 2.0 ^^ -9);\n\n// 1 ^^ n is always 1, even if n is negative\nstatic assert( 1 ^^ -5 == 1);\n\n// -1 ^^ n gets transformed into  n & 1 ? -1 : 1\n// even if n is negative\nstatic assert( (-1) ^^ -5 == -1);\nstatic assert( (-1) ^^ -4 == 1);\nstatic assert( (-1) ^^ 0 == 1);\n\n// n ^^ 0 is always 1\nstatic assert( (-5) ^^ 0 == 1);\n\n// n ^^ 1 is always n\nstatic assert( 6.0 ^^ 1 == 6.0);\n\n// n ^^ -1.0 gets transformed into 1.0 / n, even if n is negative\nstatic assert( (-4) ^^ -1.0 == 1.0 / -4);\nstatic assert( 9 ^^ -1.0 == 1.0 / 9);\n\n// Other integers raised to negative powers create an error\nstatic assert( !is(typeof(2 ^^ -5)));\nstatic assert( !is(typeof((-2) ^^ -4)));\n\n// https://issues.dlang.org/show_bug.cgi?id=3535\nstruct StructWithCtor\n{\n    this(int _n) {\n        n = _n; x = 5;\n    }\n    this(int _n, float _x) {\n        n = _n; x = _x;\n    }\n    int n;\n    float x;\n}\n\nint containsAsm() {\n       version(GNU)\n       {\n         version(X86)\n           asm { \"nop\"; }\n         else version(X86_64)\n           asm { \"nop\"; }\n         else\n           static assert(\"\");\n       }\n       else\n          asm { nop; }\n       return 0;\n    }\n\nenum A = StructWithCtor(1);\nenum B = StructWithCtor(7, 2.3);\n\nstatic assert(A.n == 1);\nstatic assert(A.x == 5.0);\nstatic assert(B.n == 7);\nstatic assert(B.x == 2.3);\n\nint bazra(int x)\n{\n   StructWithCtor p = StructWithCtor(4);\n   return p.n ^^ 3;\n\n}\n\nstatic assert(bazra(14)==64);\n\nvoid moreCommaTests()\n{\n   (containsAsm(), containsAsm());\n   auto k = containsAsm();\n   for (int i=0; i< k^^2; i+=StructWithCtor(1).n) {}\n}\n\n// Test copy constructors\nstruct CopyTest {\n   double x;\n   this(double a) { x = a * 10.0;}\n   this(this) {  x+=2.0;}\n}\n\nstruct CopyTest2\n{\n   int x; int x1; int x2; int x3;\n   this(int a) { x = a * 2; x1 = 3;}\n   this(this) {  x1+=17;}\n}\n\n\nconst CopyTest z = CopyTest(5.3);\n/+\n// TODO: This is not yet supported. But it\n// generates an error message instead of wrong-code.\nconst CopyTest w = z;\nstatic assert(z.x==55.0);\n+/\n\nint copytest1()\n{\n   CopyTest z = CopyTest(3.4);\n   CopyTest w = z;\n   assert(w.x == 36.0);\n   CopyTest2 q = CopyTest2(7);\n   CopyTest2 q2 = q;\n   CopyTest2 q3 = q2;\n   assert(q3.x1 == 37);\n\n  return 123;\n}\nstatic assert(copytest1()==123);\n\n// This must not cause a segfault\nalias int FILTH;\nstruct Filth\n{\n     struct Impl\n    {\n        FILTH * handle = null;\n        this(FILTH* h, uint r, string n)\n        {\n            handle = h;\n        }\n    }\n    Impl * p;\n\n    this(string name, in char[] stdioOpenmode = \"rb\")\n    {\n    }\n\n    ~this()\n    {\n        if (!p) return;\n    }\n\n    this(this)\n    {\n        if (!p) return;\n    }\n    }\n    struct InputByChar\n    {\n        private Filth _f;\n\n        this(Filth f)\n        {\n            _f = f;\n        }\n}\n\n\nstatic int nastyForCtfe=4;\n\n// Can't use a global variable\nstatic assert(!is(typeof( (){ static assert(0!=nastyForCtfe^^2); })));\n\nint anotherPowTest()\n{\n   double x = 5.0;\n   return x^^4 > 2.0 ? 3: 2;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/debug_info.d",
    "content": "// REQUIRED_ARGS: -g\n\nvoid main()\n{\n    version(OSX) testDebugLineMacOS();\n}\n\nversion (OSX):\n\nstruct mach_header;\nstruct mach_header_64;\nstruct section;\nstruct section_64;\n\nversion (D_LP64)\n{\n    alias MachHeader = mach_header_64;\n    alias Section = section_64;\n}\n\nelse\n{\n    alias MachHeader = mach_header;\n    alias Section = section;\n}\n\nextern (C)\n{\n    MachHeader* _dyld_get_image_header(uint image_index);\n    const(section)* getsectbynamefromheader(in mach_header* mhp, in char* segname, in char* sectname);\n    const(section_64)* getsectbynamefromheader_64(in mach_header_64* mhp, in char* segname, in char* sectname);\n}\n\nconst(Section)* getSectByNameFromHeader(MachHeader* mhp, in char* segname, in char* sectname)\n{\n    version (D_LP64)\n        return getsectbynamefromheader_64(mhp, segname, sectname);\n    else\n        return getsectbynamefromheader(mhp, segname, sectname);\n}\n\nvoid testDebugLineMacOS()\n{\n    auto header = _dyld_get_image_header(0);\n    assert(header);\n\n    auto section = getSectByNameFromHeader(header, \"__DWARF\", \"__debug_line\");\n    // verify that the __debug_line section is present in the final executable\n    assert(section);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/declaration.d",
    "content": "\nextern(C) int printf(const char*, ...);\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6475\n\nclass Foo6475(Value)\n{\n    template T1(size_t n){ alias int T1; }\n}\n\nvoid test6475()\n{\n    alias Foo6475!(int) C1;\n    alias C1.T1!0 X1;\n    static assert(is(X1 == int));\n\n    alias const(Foo6475!(int)) C2;\n    alias C2.T1!0 X2;\n    static assert(is(X2 == int));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6905\n\nvoid test6905()\n{\n    auto foo1() { static int n; return n; }\n    auto foo2() {        int n; return n; }\n    auto foo3() {               return 1; }\n    static assert(typeof(&foo1).stringof == \"int delegate() nothrow @nogc @safe\");\n    static assert(typeof(&foo2).stringof == \"int delegate() pure nothrow @nogc @safe\");\n    static assert(typeof(&foo3).stringof == \"int delegate() pure nothrow @nogc @safe\");\n\n    ref bar1() { static int n; return n; }\n  static assert(!__traits(compiles, {\n    ref bar2() {        int n; return n; }\n  }));\n  static assert(!__traits(compiles, {\n    ref bar3() {               return 1; }\n  }));\n\n    auto ref baz1() { static int n; return n; }\n    auto ref baz2() {        int n; return n; }\n    auto ref baz3() {               return 1; }\n    static assert(typeof(&baz1).stringof == \"int delegate() nothrow @nogc ref @safe\");\n    static assert(typeof(&baz2).stringof == \"int delegate() pure nothrow @nogc @safe\");\n    static assert(typeof(&baz3).stringof == \"int delegate() pure nothrow @nogc @safe\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7019\n\nstruct S7019\n{\n    int store;\n    this(int n)\n    {\n        store = n << 3;\n    }\n}\n\nS7019 rt_gs = 2;\nenum S7019 ct_gs = 2;\npragma(msg, ct_gs, \", \", ct_gs.store);\n\nvoid test7019()\n{\n    S7019 rt_ls = 3; // this compiles fine\n    enum S7019 ct_ls = 3;\n    pragma(msg, ct_ls, \", \", ct_ls.store);\n\n    static class C\n    {\n        S7019 rt_fs = 4;\n        enum S7019 ct_fs = 4;\n        pragma(msg, ct_fs, \", \", ct_fs.store);\n    }\n\n    auto c = new C;\n    assert(rt_gs == S7019(2) && rt_gs.store == 16);\n    assert(rt_ls == S7019(3) && rt_ls.store == 24);\n    assert(c.rt_fs == S7019(4) && c.rt_fs.store == 32);\n    static assert(ct_gs == S7019(2) && ct_gs.store == 16);\n    static assert(ct_ls == S7019(3) && ct_ls.store == 24);\n    static assert(C.ct_fs == S7019(4) && C.ct_fs.store == 32);\n\n    void foo(S7019 s = 5)   // fixing bug 7152\n    {\n        assert(s.store == 5 << 3);\n    }\n    foo();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7239\n\nstruct vec7239\n{\n    float x, y, z, w;\n    alias x r;  //! for color access\n    alias y g;  //! ditto\n    alias z b;  //! ditto\n    alias w a;  //! ditto\n}\n\nvoid test7239()\n{\n    vec7239 a = {x: 0, g: 0, b: 0, a: 1};\n    assert(a.r == 0);\n    assert(a.g == 0);\n    assert(a.b == 0);\n    assert(a.a == 1);\n}\n\n/***************************************************/\nstruct S10635\n{\n    string str;\n\n    this(string[] v) { str = v[0]; }\n    this(string[string] v) { str = v.keys[0]; }\n}\n\nS10635 s10635a = [\"getnonce\"];\nS10635 s10635b = [\"getnonce\" : \"str\"];\n\nvoid test10635()\n{\n    S10635 sa = [\"getnonce\"];\n    S10635 sb = [\"getnonce\" : \"str\"];\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8123\n\nvoid test8123()\n{\n    struct S { }\n\n    struct AS\n    {\n        alias S Alias;\n    }\n\n    struct Wrapper\n    {\n        AS as;\n    }\n\n    Wrapper w;\n    static assert(is(typeof(w.as).Alias == S));         // fail\n    static assert(is(AS.Alias == S));                   // ok\n    static assert(is(typeof(w.as) == AS));              // ok\n    static assert(is(typeof(w.as).Alias == AS.Alias));  // fail\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8147\n\nenum A8147 { a, b, c }\n\n@property ref T front8147(T)(T[] a)\nif (!is(T[] == void[]))\n{\n    return a[0];\n}\n\ntemplate ElementType8147(R)\n{\n    static if (is(typeof({ R r = void; return r.front8147; }()) T))\n        alias T ElementType8147;\n    else\n        alias void ElementType8147;\n}\n\nvoid test8147()\n{\n    auto arr = [A8147.a];\n    alias typeof(arr) R;\n    auto e = ElementType8147!R.init;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8410\n\nvoid test8410()\n{\n    struct Foo { int[15] x; string s; }\n\n    Foo[5] a1 = Foo([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], \"hello\"); // OK\n    Foo f = { s: \"hello\" }; // OK (not static)\n    Foo[5] a2 = { s: \"hello\" }; // error\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8942\n\nalias const int A8942_0;\nstatic assert(is(A8942_0 == const int)); // passes\n\nvoid test8942()\n{\n    alias const int A8942_1;\n    static assert(is(A8942_1 == const int)); // passes\n\n    static struct S { int i; }\n    foreach (Unused; typeof(S.tupleof))\n    {\n        alias const(int) A8942_2;\n        static assert(is(A8942_2 == const int)); // also passes\n\n        alias const int A8942_3;\n        static assert(is(A8942_3 == const int)); // fails\n        // Error: static assert  (is(int == const(int))) is false\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10144\n\nfinal class TNFA10144(char_t)\n{\n    enum Act { don }\n    const Act[] action_lookup1 = [ Act.don, ];\n}\nalias X10144 = TNFA10144!char;\n\nclass C10144\n{\n    enum Act { don }\n    synchronized { enum x1 = [Act.don]; }\n    override     { enum x2 = [Act.don]; }\n    abstract     { enum x3 = [Act.don]; }\n    final        { enum x4 = [Act.don]; }\n    synchronized { static s1 = [Act.don]; }\n    override     { static s2 = [Act.don]; }\n    abstract     { static s3 = [Act.don]; }\n    final        { static s4 = [Act.don]; }\n    synchronized { __gshared gs1 = [Act.don]; }\n    override     { __gshared gs2 = [Act.don]; }\n    abstract     { __gshared gs3 = [Act.don]; }\n    final        { __gshared gs4 = [Act.don]; }\n}\n\n/***************************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=10142\n\nclass File10142\n{\n    enum Access : ubyte { Read = 0x01 }\n    enum Open : ubyte { Exists = 0 }\n    enum Share : ubyte { None = 0 }\n    enum Cache : ubyte { None = 0x00 }\n\n    struct Style\n    {\n        Access  access;\n        Open    open;\n        Share   share;\n        Cache   cache;\n    }\n    enum Style ReadExisting = { Access.Read, Open.Exists };\n\n    this (const(char[]) path, Style style = ReadExisting)\n    {\n        assert(style.access == Access.Read);\n        assert(style.open   == Open  .Exists);\n        assert(style.share  == Share .None);\n        assert(style.cache  == Cache .None);\n    }\n}\n\nvoid test10142()\n{\n    auto f = new File10142(\"dummy\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11421\n\nvoid test11421()\n{\n    // AAs in array\n    const            a1 = [[1:2], [3:4]];   // ok <- error\n    const int[int][] a2 = [[1:2], [3:4]];   // ok\n    static assert(is(typeof(a1) == typeof(a2)));\n\n    // AAs in AA\n    auto aa = [1:[\"a\":1.0], 2:[\"b\":2.0]];\n    static assert(is(typeof(aa) == double[string][int]));\n    assert(aa[1][\"a\"] == 1.0);\n    assert(aa[2][\"b\"] == 2.0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13776\n\nenum a13776(T) = __traits(compiles, { T; });\n\nenum b13776(A...) = 1;\n\ntemplate x13776s()\n{\n    struct S;\n    alias x13776s = b13776!(a13776!S);\n}\ntemplate y13776s()\n{\n    struct S;\n    alias x2 = b13776!(a13776!S);\n    alias y13776s = x2;\n}\ntemplate z13776s()\n{\n    struct S;\n    alias x1 = a13776!S;\n    alias x2 = b13776!(x1);\n    alias z13776s = x2;\n}\n\ntemplate x13776c()\n{\n    class C;\n    alias x13776c = b13776!(a13776!C);\n}\ntemplate y13776c()\n{\n    class C;\n    alias x2 = b13776!(a13776!C);\n    alias y13776c = x2;\n}\ntemplate z13776c()\n{\n    class C;\n    alias x1 = a13776!C;\n    alias x2 = b13776!(x1);\n    alias z13776c = x2;\n}\n\nvoid test13776()\n{\n    alias xs = x13776s!();  // ok <- ng\n    alias ys = y13776s!();  // ok <- ng\n    alias zs = z13776s!();  // ok\n\n    alias xc = x13776c!();  // ok <- ng\n    alias yc = y13776c!();  // ok <- ng\n    alias zc = z13776c!();  // ok\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14090\n\ntemplate Packed14090(Args...)\n{\n    enum x = __traits(compiles, { Args[0] v; });\n    // Args[0] is an opaque struct Empty, so the variable declaration fails to compile.\n    // The error message creation calls TypeStruct('_Empty')->toChars(), and\n    // it wrongly calls TemplateInstance('RoundRobin!()')->toAlias().\n    // Finally it will cause incorrect \"recursive template instantiation\" error.\n}\n\ntemplate Map14090(A...)\n{\n    alias Map14090 = A[0];\n}\n\ntemplate RoundRobin14090()\n{\n    struct Empty;\n    alias RoundRobin14090 = Map14090!(Packed14090!(Empty));\n}\n\nalias roundRobin14090 = RoundRobin14090!();\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13950\n\ntemplate Tuple13950(T...) { alias T Tuple13950; }\n\nvoid f13950(int x = 0, Tuple13950!() xs = Tuple13950!())\n{\n    assert(x == 0);\n    assert(xs.length == 0);\n}\n\nvoid test13950()\n{\n    f13950();\n}\n\n/***************************************************/\n\nint main()\n{\n    test6475();\n    test6905();\n    test7019();\n    test7239();\n    test8123();\n    test8147();\n    test8410();\n    test8942();\n    test10142();\n    test11421();\n    test13950();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/delegate.d",
    "content": "// REQUIRED_ARGS:\n\nimport core.stdc.stdio;\n\n/********************************************************/\n\n//int delegate(int, char[]) *p;\n\nclass Foo\n{\n   int bar(int i, char[] s) { return 4; }\n}\n\nclass Bar : Foo\n{\n   override int bar(int i, char[] s) { return 5; }\n}\n\nvoid test1()\n{\n    int delegate(int, char[]) dg;\n    Foo f = new Foo();\n    Bar b = new Bar();\n    int x;\n\n    dg = &f.bar;\n    x = dg(3, null);\n    assert(x == 4);\n\n    f = b;\n    dg = &f.bar;\n    x = dg(3, null);\n    assert(x == 5);\n}\n\n/********************************************************/\n\nint foo2()\n{\n    return 3;\n}\n\nvoid test2()\n{\n    int function () fp;\n\n    fp = &foo2;\n    assert(fp() == 3);\n}\n\n/********************************************************/\n\nclass Foo3\n{\n    int bar(int i, char[] s) { return 47; }\n\n    void test()\n    {\n        int delegate(int, char[]) dg;\n\n        dg = &bar;\n        printf(\"%d %d\\n\", dg(3, null), result());\n        assert(dg(3, null) == result());\n\n        dg = &this.bar;\n        printf(\"%d %d\\n\", dg(3, null), result());\n        assert(dg(3, null) == result());\n    }\n\n    int result() { return 47; }\n}\n\nclass Bar3 : Foo3\n{\n    override int bar(int i, char[] s) { return 48; }\n\n    override int result() { return 48; }\n\n    void test2()\n    {\n        int delegate(int, char[]) dg;\n\n        dg = &super.bar;\n        assert(dg(3, null) == 47);\n    }\n\n}\n\nvoid test3()\n{\n    Foo3 f = new Foo3();\n    f.test();\n\n    Bar3 b = new Bar3();\n    b.test();\n    b.test2();\n}\n\n/********************************************************/\n\n\nint foo4(int x) { return 1; }\nint foo4(char x) { return 2; }\nint foo4(int x, int y) { return 3; }\n\nvoid test4()\n{\n    int function (char) fp;\n\n    fp = &foo4;\n    assert(fp(0) == 2);\n}\n\n/********************************************************/\n\nclass Abc\n{\n    int foo1(int x) { return 1; }\n    int foo1(char x) { return 2; }\n    int foo1(int x, int y) { return 3; }\n}\n\nvoid test5()\n{\n    int delegate(char) dg;\n    Abc a = new Abc();\n\n    dg = &a.foo1;\n    assert(dg(0) == 2);\n}\n\n/********************************************************/\n\nint delegate(int) bar6;\n\nint[int delegate(int)] aa6;\n\nvoid test6()\n{\n    aa6[bar6] = 0;\n}\n\n/********************************************************/\n\nvoid foo7(void delegate(int) dg)\n{\n    dg(1);\n    //writefln(\"%s\", dg(3));\n}\n\nvoid test7()\n{\n    foo7(delegate(int i)\n        {\n            printf(\"i = %d\\n\", i);\n        }\n        );\n}\n\n/********************************************************/\n\nvoid foo8(int delegate(int) dg)\n{\n    printf(\"%d\\n\", dg(3));\n    assert(dg(3) == 6);\n}\n\nvoid test8()\n{\n    foo8(delegate(int i)\n        {\n            return i * 2;\n        }\n        );\n}\n\n/********************************************************/\n\nvoid foo9(int delegate(int) dg)\n{\n    assert(dg(3) == 6);\n}\n\nvoid test9()\n{\n    foo9( (int i) { return i * 2; } );\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8257\n\nstruct S8257 {\n    static int g() {\n        return 6;\n    }\n}\n\nvoid test8257()\n{\n     S8257 s;\n     int w = 2;\n     S8257 func() { ++w; return s; }\n     auto k = &(func()).g;\n     // check that the call to func() still happened\n     assert(w == 3);\n     assert( k() == 6);\n}\n\nauto f8257(string m)() { return &__traits(getMember, S8257.init, m); }\nstatic assert (__traits(compiles, f8257!\"g\"()));\n\n/********************************************************/\n\nvoid foo10(int delegate() dg)\n{\n    assert(dg() == 6);\n}\n\nvoid test10()\n{   int i = 3;\n\n    foo10( { return i * 2; } );\n}\n\n/********************************************************/\n\nclass A12\n{\npublic:\n  int delegate(int, int)[4] dgs;\n  int function(int, int)[4] fps;\n  int delegate(int, int) dg;\n  int function(int, int) fp;\n  int f(int x, int y) {\n    printf(\"here \");\n    int res = x + y;\n    printf(\"%d\\n\", res);\n    return res;\n  }\n\n  void bug_1() {\n//    fp = &f;\n//    fp(1,2);\n    dg = &f;\n    dg(1,2);\n//    fps[] = [&f, &f, &f, &(f)];  // bug 1: this line shouldn't compile\n//    this.fps[0](1, 2);  // seg-faults here!\n\n    dgs[] = [&(f), &(f), &(f), &(f)];  // bug 1: why this line can't compile?\n    this.dgs[0](1, 2);\n\n    dgs[] = [&(this.f), &(this.f), &(this.f), &(this.f)];\n    this.dgs[0](1, 2);\n  }\n\n}\n\nvoid test12()\n{\n  A12 a = new A12();\n\n  a.bug_1();\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1570\n\nclass A13\n{\n    int f()\n    {\n        return 1;\n    }\n}\n\nclass B13 : A13\n{\n    override int f()\n    {\n        return 2;\n    }\n}\n\nvoid test13()\n{\n    B13 b = new B13;\n    assert(b.f() == 2);\n    assert(b.A13.f() == 1);\n    assert((&b.f)() == 2);\n    assert((&b.A13.f)() == 1);\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2472\n\nclass A2472\n{\n    void foo() {}\n}\n\nvoid test2472()\n{\n    auto a = new A2472;\n    auto fp1 = (&a.foo).funcptr;\n    auto dg = &a.foo;\n    auto fp2 = dg.funcptr;\n    assert(fp1 == fp2);\n}\n\n/********************************************************/\n\nvoid testAssign()\n{\n    static class C\n    {\n        int a;\n        this(int a) { this.a = a; }\n        int funca() { return a; }\n        int funcb() { return a + 1; }\n    }\n\n    auto x = new C(5);\n    auto y = new C(7);\n\n    auto dg = &x.funca;\n    assert(dg() == 5);\n    dg.funcptr = &C.funcb;\n    assert(dg() == 6);\n    dg.ptr = cast(void*)y;\n    assert(dg() == 8);\n    dg.funcptr = &C.funca;\n    assert(dg() == 7);\n}\n\n/********************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test12();\n    test13();\n    test2472();\n    test8257();\n    testAssign();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/dhry.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -release -O -g -inline\n// DISABLED: freebsd dragonflybsd\n\n/*\n *************************************************************************\n *\n *                   \"DHRYSTONE\" Benchmark Program\n *                   -----------------------------\n *\n *  Version:    C, Version 2.1\n *\n *  File:       dhry.h (part 1 of 3)\n *\n *  Date:       May 25, 1988\n *\n *  Author:     Reinhold P. Weicker\n *              Siemens Nixdorf Inf. Syst.\n *              STM OS 32\n *              Otto-Hahn-Ring 6\n *              W-8000 Muenchen 83\n *              Germany\n *                      Phone:    [+49]-89-636-42436\n *                                (8-17 Central European Time)\n *                      UUCP:     weicker@ztivax.uucp@unido.uucp\n *                      Internet: weicker@ztivax.siemens.com\n *\n *              Original Version (in Ada) published in\n *              \"Communications of the ACM\" vol. 27., no. 10 (Oct. 1984),\n *              pp. 1013 - 1030, together with the statistics\n *              on which the distribution of statements etc. is based.\n *\n *              In this C version, the following C library functions are\n *              used:\n *              - strcpy, strcmp (inside the measurement loop)\n *              - printf, scanf (outside the measurement loop)\n *\n *  Collection of Results:\n *              Reinhold Weicker (address see above) and\n *\n *              Rick Richardson\n *              PC Research. Inc.\n *              94 Apple Orchard Drive\n *              Tinton Falls, NJ 07724\n *                      Phone:  (201) 834-1378 (9-17 EST)\n *                      UUCP:   ...!uunet!pcrat!rick\n *\n *      Please send results to Rick Richardson and/or Reinhold Weicker.\n *      Complete information should be given on hardware and software\n *      used. Hardware information includes: Machine type, CPU, type and\n *      size of caches; for microprocessors: clock frequency, memory speed\n *      (number of wait states). Software information includes: Compiler\n *      (and runtime library) manufacturer and version, compilation\n *      switches, OS version. The Operating System version may give an\n *      indication about the compiler; Dhrystone itself performs no OS\n *      calls in the measurement loop.\n *\n *      The complete output generated by the program should be mailed\n *      such that at least some checks for correctness can be made.\n *\n *************************************************************************\n *\n *  History:    This version C/2.1 has been made for two reasons:\n *\n *              1) There is an obvious need for a common C version of\n *              Dhrystone, since C is at present the most popular system\n *              programming language for the class of processors\n *              (microcomputers, minicomputers) where Dhrystone is used\n *              most. There should be, as far as possible, only one C\n *              version of Dhrystone such that results can be compared\n *              without restrictions. In the past, the C versions\n *              distributed by Rick Richardson (Version 1.1) and by\n *              Reinhold Weicker had small (though not significant)\n *              differences.\n *\n *              2) As far as it is possible without changes to the\n *              Dhrystone statistics, optimizing compilers should be\n *              prevented from removing significant statements.\n *\n *              This C version has been developed in cooperation with\n *              Rick Richardson (Tinton Falls, NJ), it incorporates many\n *              ideas from the \"Version 1.1\" distributed previously by\n *              him over the UNIX network Usenet.\n *              I also thank Chaim Benedelac (National Semiconductor),\n *              David Ditzel (SUN), Earl Killian and John Mashey (MIPS),\n *              Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)\n *              for their help with comments on earlier versions of the\n *              benchmark.\n *\n *  Changes:    In the initialization part, this version follows mostly\n *              Rick Richardson's version distributed via Usenet, not the\n *              version distributed earlier via floppy disk by Reinhold\n *              Weicker. As a concession to older compilers, names have\n *              been made unique within the first 8 characters. Inside the\n *              measurement loop, this version follows the version\n *              previously distributed by Reinhold Weicker.\n *\n *              At several places in the benchmark, code has been added,\n *              but within the measurement loop only in branches that\n *              are not executed. The intention is that optimizing\n *              compilers should be prevented from moving code out of the\n *              measurement loop, or from removing code altogether. Since\n *              the statements that are executed within the measurement\n *              loop have NOT been changed, the numbers defining the\n *              \"Dhrystone distribution\" (distribution of statements,\n *              operand types and locality) still hold. Except for\n *              sophisticated optimizing compilers, execution times for\n *              this version should be the same as for previous versions.\n *\n *              Since it has proven difficult to subtract the time for the\n *              measurement loop overhead in a correct way, the loop check\n *              has been made a part of the benchmark. This does have\n *              an impact - though a very minor one - on the distribution\n *              statistics which have been updated for this version.\n *\n *              All changes within the measurement loop are described\n *              and discussed in the companion paper \"Rationale for\n *              Dhrystone version 2\".\n *\n *              Because of the self-imposed limitation that the order and\n *              distribution of the executed statements should not be\n *              changed, there are still cases where optimizing compilers\n *              may not generate code for some statements. To a certain\n *              degree, this is unavoidable for small synthetic\n *              benchmarks. Users of the benchmark are advised to check\n *              code listings whether code is generated for all statements\n *              of Dhrystone.\n *\n *              Version 2.1 is identical to version 2.0 distributed via\n *              the UNIX network Usenet in March 1988 except that it\n *              corrects some minor deficiencies that were found by users\n *              of version 2.0. The only change within the measurement\n *              loop is that a non-executed \"else\" part was added to the\n *              \"if\" statement in Func_3, and a non-executed \"else\" part\n *              removed from Proc_3.\n *\n *************************************************************************\n *\n * Defines:     The following \"Defines\" are possible:\n *              -DROPT         (default: Not defined)\n *                      As an approximation to what an average C\n *                      programmer might do, the \"register\" storage class\n *                      is applied (if enabled by -DROPT)\n *                      - for local variables, if they are used\n *                        (dynamically) five or more times\n *                      - for parameters if they are used (dynamically)\n *                        six or more times\n *                      Note that an optimal \"register\" strategy is\n *                      compiler-dependent, and that \"register\"\n *                      declarations do not necessarily lead to faster\n *                      execution.\n *              -DNOSTRUCTASSIGN        (default: Not defined)\n *                      Define if the C compiler does not support\n *                      assignment of structures.\n *              -DNOENUMS               (default: Not defined)\n *                      Define if the C compiler does not support\n *                      enumeration types.\n *\n *************************************************************************\n *\n *  Compilation model and measurement (IMPORTANT):\n *\n *  This C version of Dhrystone consists of three files:\n *  - dhry.h (this file, containing global definitions and comments)\n *  - dhry_1.c (containing the code corresponding to Ada package Pack_1)\n *  - dhry_2.c (containing the code corresponding to Ada package Pack_2)\n *\n *  The following \"ground rules\" apply for measurements:\n *  - Separate compilation\n *  - No procedure merging\n *  - Otherwise, compiler optimizations are allowed but should be\n *    indicated\n *  - Default results are those without register declarations\n *  See the companion paper \"Rationale for Dhrystone Version 2\" for a more\n *  detailed discussion of these ground rules.\n *\n *  For 16-Bit processors (e.g. 80186, 80286), times for all compilation\n *  models (\"small\", \"medium\", \"large\" etc.) should be given if possible,\n *  together with a definition of these models for the compiler system\n *  used.\n *\n *************************************************************************\n *\n *  Dhrystone (C version) statistics:\n *\n *  [Comment from the first distribution, updated for version 2.\n *   Note that because of language differences, the numbers are slightly\n *   different from the Ada version.]\n *\n *  The following program contains statements of a high level programming\n *  language (here: C) in a distribution considered representative:\n *\n *    assignments                  52 (51.0 %)\n *    control statements           33 (32.4 %)\n *    procedure, function calls    17 (16.7 %)\n *\n *  103 statements are dynamically executed. The program is balanced with\n *  respect to the three aspects:\n *\n *    - statement type\n *    - operand type\n *    - operand locality\n *         operand global, local, parameter, or constant.\n *\n *  The combination of these three aspects is balanced only approximately.\n *\n *  1. Statement Type:\n *  -----------------             number\n *\n *     V1 = V2                     9\n *       (incl. V1 = F(..)\n *     V = Constant               12\n *     Assignment,                 7\n *       with array element\n *     Assignment,                 6\n *       with record component\n *                                --\n *                                34       34\n *\n *     X = Y +|-|\"&&\"|\"|\" Z        5\n *     X = Y +|-|\"==\" Constant     6\n *     X = X +|- 1                 3\n *     X = Y *|/ Z                 2\n *     X = Expression,             1\n *           two operators\n *     X = Expression,             1\n *           three operators\n *                                --\n *                                18       18\n *\n *     if ....                    14\n *       with \"else\"      7\n *       without \"else\"   7\n *           executed        3\n *           not executed    4\n *     for ...                     7  |  counted every time\n *     while ...                   4  |  the loop condition\n *     do ... while                1  |  is evaluated\n *     switch ...                  1\n *     break                       1\n *     declaration with            1\n *       initialization\n *                                --\n *                                34       34\n *\n *     P (...)  procedure call    11\n *       user procedure      10\n *       library procedure    1\n *     X = F (...)\n *             function  call      6\n *       user function        5\n *       library function     1\n *                                --\n *                                17       17\n *                                        ---\n *                                        103\n *\n *    The average number of parameters in procedure or function calls\n *    is 1.82 (not counting the function values as implicit parameters).\n *\n *\n *  2. Operators\n *  ------------\n *                          number    approximate\n *                                    percentage\n *\n *    Arithmetic             32          50.8\n *\n *       +                     21          33.3\n *       -                      7          11.1\n *       *                      3           4.8\n *       / (int div)            1           1.6\n *\n *    Comparison             27           42.8\n *\n *       ==                     9           14.3\n *       /=                     4            6.3\n *       >                      1            1.6\n *       <                      3            4.8\n *       >=                     1            1.6\n *       <=                     9           14.3\n *\n *    Logic                   4            6.3\n *\n *       && (AND-THEN)          1            1.6\n *       |  (OR)                1            1.6\n *       !  (NOT)               2            3.2\n *\n *                           --          -----\n *                           63          100.1\n *\n *\n *  3. Operand Type (counted once per operand reference):\n *  ---------------\n *                          number    approximate\n *                                    percentage\n *\n *     Integer               175        72.3 %\n *     Character              45        18.6 %\n *     Pointer                12         5.0 %\n *     String30                6         2.5 %\n *     Array                   2         0.8 %\n *     Record                  2         0.8 %\n *                           ---       -------\n *                           242       100.0 %\n *\n *  When there is an access path leading to the final operand (e.g. a\n *  record component), only the final data type on the access path is\n *  counted.\n *\n *\n *  4. Operand Locality:\n *  -------------------\n *                                number    approximate\n *                                          percentage\n *\n *     local variable              114        47.1 %\n *     global variable              22         9.1 %\n *     parameter                    45        18.6 %\n *        value                        23         9.5 %\n *        reference                    22         9.1 %\n *     function result               6         2.5 %\n *     constant                     55        22.7 %\n *                                 ---       -------\n *                                 242       100.0 %\n *\n *\n *  The program does not compute anything meaningful, but it is\n *  syntactically and semantically correct. All variables have a value\n *  assigned to them before they are used as a source operand.\n *\n *  There has been no explicit effort to account for the effects of a\n *  cache, or to balance the use of long or short displacements for code\n *  or data.\n *\n *************************************************************************\n */\n\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport core.stdc.stdlib;\nimport std.string;\n\n\n/* Compiler and system dependent definitions: */\n\nconst double Mic_secs_Per_Second = 1000000.0;\n                /* Berkeley UNIX C returns process times in seconds/HZ */\n\nenum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}\nalias int Enumeration;\n        /* for boolean and enumeration types in Ada, Pascal */\n\n/* General definitions: */\n\nconst int StrLen = 30;\n\nalias int           One_Thirty;\nalias int           One_Fifty;\nalias char          Capital_Letter;\nalias bool          Boolean;\nalias char[StrLen]  Str_30;\nalias int[50]       Arr_1_Dim;\nalias int[50][50]   Arr_2_Dim;\n\nstruct record\n{\n    record *Ptr_Comp;\n    Enumeration    Discr;\n    union V {\n          struct V1 {\n                  Enumeration   Enum_Comp;\n                  int           Int_Comp;\n                  char[StrLen]  Str_Comp;\n                  }\n          V1 var_1;\n          struct V2 {\n                  Enumeration   E_Comp_2;\n                  char [StrLen] Str_2_Comp;\n                  }\n          V2 var_2;\n          struct V3 {\n                  char          Ch_1_Comp;\n                  char          Ch_2_Comp;\n                  }\n          V3 var_3;\n          }\n    V variant;\n}\n\nalias record Rec_Type;\nalias record *Rec_Pointer;\n\n\n/* Global Variables: */\n\nRec_Pointer     Ptr_Glob,\n                Next_Ptr_Glob;\nint             Int_Glob;\nBoolean         Bool_Glob;\nchar            Ch_1_Glob,\n                Ch_2_Glob;\nint[50]         Arr_1_Glob;\nint[50][50]     Arr_2_Glob;\n\nchar[StrLen] Reg_Define = \"Register option selected.\";\n\n/* variables for time measurement: */\n\nconst int Too_Small_Time = 2;\n                /* Measurements should last at least 2 seconds */\n\ndouble          Begin_Time,\n                End_Time,\n                User_Time;\n\ndouble          Microseconds,\n                Dhrystones_Per_Second,\n                Vax_Mips;\n\n/* end of variables for time measurement */\n\n\nvoid main ()\n/*****/\n\n  /* main program, corresponds to procedures        */\n  /* Main and Proc_0 in the Ada version             */\n{\n        One_Fifty       Int_1_Loc;\n        One_Fifty       Int_2_Loc;\n        One_Fifty       Int_3_Loc;\n        char            Ch_Index;\n        Enumeration     Enum_Loc;\n        Str_30          Str_1_Loc;\n        Str_30          Str_2_Loc;\n        int             Run_Index;\n        int             Number_Of_Runs;\n\n/+\n        FILE            *Ap;\n\n  /* Initializations */\n\n  if ((Ap = fopen(\"dhry.res\",\"a+\")) == null)\n    {\n       printf(\"Can not open dhry.res\\n\\n\");\n       exit(1);\n    }\n+/\n\n  Next_Ptr_Glob = cast(Rec_Pointer) malloc (Rec_Type.sizeof);\n  Ptr_Glob = cast(Rec_Pointer) malloc (Rec_Type.sizeof);\n\n  Ptr_Glob.Ptr_Comp                    = Next_Ptr_Glob;\n  Ptr_Glob.Discr                       = Ident_1;\n  Ptr_Glob.variant.var_1.Enum_Comp     = Ident_3;\n  Ptr_Glob.variant.var_1.Int_Comp      = 40;\n//  strcpy (Ptr_Glob.variant.var_1.Str_Comp,\n//          \"DHRYSTONE PROGRAM, SOME STRING\");\n//  strcpy (Str_1_Loc, \"DHRYSTONE PROGRAM, 1'ST STRING\");\n  Ptr_Glob.variant.var_1.Str_Comp[] = \"DHRYSTONE PROGRAM, SOME STRING\";\n  Str_1_Loc[] = \"DHRYSTONE PROGRAM, 1'ST STRING\";\n\n  Arr_2_Glob [8][7] = 10;\n        /* Was missing in published program. Without this statement,    */\n        /* Arr_2_Glob [8][7] would have an undefined value.             */\n        /* Warning: With 16-Bit processors and Number_Of_Runs > 32000,  */\n        /* overflow may occur for this array element.                   */\n\n  printf (\"\\n\");\n  printf (\"Dhrystone Benchmark, Version 2.1 (Language: D)\\n\");\n  printf (\"\\n\");\n  printf (\"Please give the number of runs through the benchmark: \");\n  {\n    int n;\n    //scanf (\"%d\", &n);\n    n = 10000000;\n    Number_Of_Runs = n;\n  }\n  printf (\"\\n\");\n\n  printf (\"Execution starts, %d runs through Dhrystone\\n\",Number_Of_Runs);\n\n  /***************/\n  /* Start timer */\n  /***************/\n\n  Begin_Time = dtime();\n\n  for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)\n  {\n\n    Proc_5();\n    Proc_4();\n      /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */\n    Int_1_Loc = 2;\n    Int_2_Loc = 3;\n    //strcpy (Str_2_Loc, \"DHRYSTONE PROGRAM, 2'ND STRING\");\n    Str_2_Loc[] = \"DHRYSTONE PROGRAM, 2'ND STRING\";\n    Enum_Loc = Ident_2;\n    Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);\n      /* Bool_Glob == 1 */\n    while (Int_1_Loc < Int_2_Loc)  /* loop body executed once */\n    {\n      Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;\n        /* Int_3_Loc == 7 */\n      Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);\n        /* Int_3_Loc == 7 */\n      Int_1_Loc += 1;\n    } /* while */\n      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */\n    Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);\n      /* Int_Glob == 5 */\n    Proc_1 (Ptr_Glob);\n    for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)\n                             /* loop body executed twice */\n    {\n      if (Enum_Loc == Func_1 (Ch_Index, 'C'))\n          /* then, not executed */\n        {\n        Proc_6 (Ident_1, &Enum_Loc);\n        //strcpy (Str_2_Loc, \"DHRYSTONE PROGRAM, 3'RD STRING\");\n        Str_2_Loc[] = \"DHRYSTONE PROGRAM, 3'RD STRING\";\n        Int_2_Loc = Run_Index;\n        Int_Glob = Run_Index;\n        }\n    }\n      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */\n    Int_2_Loc = Int_2_Loc * Int_1_Loc;\n    Int_1_Loc = Int_2_Loc / Int_3_Loc;\n    Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;\n      /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */\n    Proc_2 (&Int_1_Loc);\n      /* Int_1_Loc == 5 */\n\n  } /* loop \"for Run_Index\" */\n\n  /**************/\n  /* Stop timer */\n  /**************/\n\n  End_Time = dtime();\n\n  printf (\"Execution ends\\n\");\n  printf (\"\\n\");\n  printf (\"Final values of the variables used in the benchmark:\\n\");\n  printf (\"\\n\");\n  printf (\"Int_Glob:            %d\\n\", Int_Glob);\n  printf (\"        should be:   %d\\n\", 5);\n  printf (\"Bool_Glob:           %d\\n\", Bool_Glob);\n  printf (\"        should be:   %d\\n\", 1);\n  printf (\"Ch_1_Glob:           %c\\n\", Ch_1_Glob);\n  printf (\"        should be:   %c\\n\", cast(int)'A');\n  printf (\"Ch_2_Glob:           %c\\n\", Ch_2_Glob);\n  printf (\"        should be:   %c\\n\", cast(int)'B');\n  printf (\"Arr_1_Glob[8]:       %d\\n\", Arr_1_Glob[8]);\n  printf (\"        should be:   %d\\n\", 7);\n  printf (\"Arr_2_Glob[8][7]:    %d\\n\", Arr_2_Glob[8][7]);\n  printf (\"        should be:   Number_Of_Runs + 10\\n\");\n  printf (\"Ptr_Glob.\\n\");\n  printf (\"  Ptr_Comp:          %d\\n\", cast(int) Ptr_Glob.Ptr_Comp);\n  printf (\"        should be:   (implementation-dependent)\\n\");\n  printf (\"  Discr:             %d\\n\", Ptr_Glob.Discr);\n  printf (\"        should be:   %d\\n\", 0);\n  printf (\"  Enum_Comp:         %d\\n\", Ptr_Glob.variant.var_1.Enum_Comp);\n  printf (\"        should be:   %d\\n\", 2);\n  printf (\"  Int_Comp:          %d\\n\", Ptr_Glob.variant.var_1.Int_Comp);\n  printf (\"        should be:   %d\\n\", 17);\n  printf (\"  Str_Comp:          %.*s\\n\", Ptr_Glob.variant.var_1.Str_Comp.length, Ptr_Glob.variant.var_1.Str_Comp.ptr);\n  printf (\"        should be:   DHRYSTONE PROGRAM, SOME STRING\\n\");\n  printf (\"Next_Ptr_Glob.\\n\");\n  printf (\"  Ptr_Comp:          %d\\n\", cast(int) Next_Ptr_Glob.Ptr_Comp);\n  printf (\"        should be:   (implementation-dependent), same as above\\n\");\n  printf (\"  Discr:             %d\\n\", Next_Ptr_Glob.Discr);\n  printf (\"        should be:   %d\\n\", 0);\n  printf (\"  Enum_Comp:         %d\\n\", Next_Ptr_Glob.variant.var_1.Enum_Comp);\n  printf (\"        should be:   %d\\n\", 1);\n  printf (\"  Int_Comp:          %d\\n\", Next_Ptr_Glob.variant.var_1.Int_Comp);\n  printf (\"        should be:   %d\\n\", 18);\n  printf (\"  Str_Comp:          %.*s\\n\", Next_Ptr_Glob.variant.var_1.Str_Comp.length, Next_Ptr_Glob.variant.var_1.Str_Comp.ptr);\n  printf (\"        should be:   DHRYSTONE PROGRAM, SOME STRING\\n\");\n  printf (\"Int_1_Loc:           %d\\n\", Int_1_Loc);\n  printf (\"        should be:   %d\\n\", 5);\n  printf (\"Int_2_Loc:           %d\\n\", Int_2_Loc);\n  printf (\"        should be:   %d\\n\", 13);\n  printf (\"Int_3_Loc:           %d\\n\", Int_3_Loc);\n  printf (\"        should be:   %d\\n\", 7);\n  printf (\"Enum_Loc:            %d\\n\", Enum_Loc);\n  printf (\"        should be:   %d\\n\", 1);\n  printf (\"Str_1_Loc:           %.*s\\n\", Str_1_Loc.length, Str_1_Loc.ptr);\n  printf (\"        should be:   DHRYSTONE PROGRAM, 1'ST STRING\\n\");\n  printf (\"Str_2_Loc:           %.*s\\n\", Str_2_Loc.length, Str_2_Loc.ptr);\n  printf (\"        should be:   DHRYSTONE PROGRAM, 2'ND STRING\\n\");\n  printf (\"\\n\");\n\n  User_Time = End_Time - Begin_Time;\n\n  if (User_Time < Too_Small_Time)\n  {\n    printf (\"Measured time too small to obtain meaningful results\\n\");\n    printf (\"Please increase number of runs\\n\");\n    printf (\"\\n\");\n  }\n  else\n  {\n    Microseconds = User_Time * Mic_secs_Per_Second\n                        / cast(double) Number_Of_Runs;\n    Dhrystones_Per_Second = cast(double) Number_Of_Runs / User_Time;\n    Vax_Mips = Dhrystones_Per_Second / 1757.0;\n\n    printf (\"Register option selected?  NO\\n\");\n    strcpy(Reg_Define.ptr, \"Register option not selected.\");\n    printf (\"Microseconds for one run through Dhrystone: \");\n    printf (\"%7.1lf \\n\", Microseconds);\n    printf (\"Dhrystones per Second:                      \");\n    printf (\"%10.1lf \\n\", Dhrystones_Per_Second);\n    printf (\"VAX MIPS rating = %10.3lf \\n\",Vax_Mips);\n    printf (\"\\n\");\n\n   /+\n  fprintf(Ap,\"\\n\");\n  fprintf(Ap,\"Dhrystone Benchmark, Version 2.1 (Language: D)\\n\");\n  fprintf(Ap,\"%.*s\\n\",Reg_Define.length, Reg_Define.ptr);\n  fprintf(Ap,\"Microseconds for one loop: %7.1lf\\n\",Microseconds);\n  fprintf(Ap,\"Dhrystones per second: %10.1lf\\n\",Dhrystones_Per_Second);\n  fprintf(Ap,\"VAX MIPS rating: %10.3lf\\n\",Vax_Mips);\n  fclose(Ap);\n  +/\n\n  }\n\n}\n\nvoid Proc_1 (Rec_Pointer Ptr_Val_Par)\n/******************/\n\n    /* executed once */\n{\n      Rec_Pointer Next_Record = Ptr_Val_Par.Ptr_Comp;\n                                        /* == Ptr_Glob_Next */\n  /* Local variable, initialized with Ptr_Val_Par.Ptr_Comp,    */\n  /* corresponds to \"rename\" in Ada, \"with\" in Pascal           */\n\n  *Ptr_Val_Par.Ptr_Comp = *Ptr_Glob;\n  Ptr_Val_Par.variant.var_1.Int_Comp = 5;\n  Next_Record.variant.var_1.Int_Comp\n        = Ptr_Val_Par.variant.var_1.Int_Comp;\n  Next_Record.Ptr_Comp = Ptr_Val_Par.Ptr_Comp;\n  Proc_3 (&Next_Record.Ptr_Comp);\n    /* Ptr_Val_Par.Ptr_Comp.Ptr_Comp\n                        == Ptr_Glob.Ptr_Comp */\n  if (Next_Record.Discr == Ident_1)\n    /* then, executed */\n  {\n    Next_Record.variant.var_1.Int_Comp = 6;\n    Proc_6 (Ptr_Val_Par.variant.var_1.Enum_Comp,\n           &Next_Record.variant.var_1.Enum_Comp);\n    Next_Record.Ptr_Comp = Ptr_Glob.Ptr_Comp;\n    Proc_7 (Next_Record.variant.var_1.Int_Comp, 10,\n           &Next_Record.variant.var_1.Int_Comp);\n  }\n  else /* not executed */\n    *Ptr_Val_Par = *Ptr_Val_Par.Ptr_Comp;\n} /* Proc_1 */\n\nvoid Proc_2 (One_Fifty *Int_Par_Ref)\n/******************/\n    /* executed once */\n    /* *Int_Par_Ref == 1, becomes 4 */\n{\n  One_Fifty  Int_Loc;\n  Enumeration   Enum_Loc;\n\n  Int_Loc = *Int_Par_Ref + 10;\n  do /* executed once */\n    if (Ch_1_Glob == 'A')\n      /* then, executed */\n    {\n      Int_Loc -= 1;\n      *Int_Par_Ref = Int_Loc - Int_Glob;\n      Enum_Loc = Ident_1;\n    } /* if */\n  while (Enum_Loc != Ident_1); /* true */\n} /* Proc_2 */\n\n\nvoid Proc_3 (Rec_Pointer *Ptr_Ref_Par)\n/******************/\n    /* executed once */\n    /* Ptr_Ref_Par becomes Ptr_Glob */\n\n{\n  if (Ptr_Glob !=    null)\n    /* then, executed */\n    *Ptr_Ref_Par = Ptr_Glob.Ptr_Comp;\n  Proc_7 (10, Int_Glob, &Ptr_Glob.variant.var_1.Int_Comp);\n} /* Proc_3 */\n\nvoid Proc_4 () /* without parameters */\n/*******/\n    /* executed once */\n{\n  Boolean Bool_Loc;\n\n  Bool_Loc = Ch_1_Glob == 'A';\n  Bool_Glob = Bool_Loc | Bool_Glob;\n  Ch_2_Glob = 'B';\n} /* Proc_4 */\n\n\nvoid Proc_5 () /* without parameters */\n/*******/\n    /* executed once */\n{\n  Ch_1_Glob = 'A';\n  Bool_Glob = false;\n} /* Proc_5 */\n\n\nvoid Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)\n/*********************************/\n    /* executed once */\n    /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */\n{\n  *Enum_Ref_Par = Enum_Val_Par;\n  if (! Func_3 (Enum_Val_Par))\n    /* then, not executed */\n    *Enum_Ref_Par = Ident_4;\n  final switch (Enum_Val_Par)\n  {\n    case Ident_1:\n      *Enum_Ref_Par = Ident_1;\n      break;\n    case Ident_2:\n      if (Int_Glob > 100)\n        /* then */\n      *Enum_Ref_Par = Ident_1;\n      else *Enum_Ref_Par = Ident_4;\n      break;\n    case Ident_3: /* executed */\n      *Enum_Ref_Par = Ident_2;\n      break;\n    case Ident_4: break;\n    case Ident_5:\n      *Enum_Ref_Par = Ident_3;\n      break;\n  } /* switch */\n} /* Proc_6 */\n\n\nvoid Proc_7 (One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val, One_Fifty *Int_Par_Ref)\n/**********************************************/\n    /* executed three times                                      */\n    /* first call:      Int_1_Par_Val == 2, Int_2_Par_Val == 3,  */\n    /*                  Int_Par_Ref becomes 7                    */\n    /* second call:     Int_1_Par_Val == 10, Int_2_Par_Val == 5, */\n    /*                  Int_Par_Ref becomes 17                   */\n    /* third call:      Int_1_Par_Val == 6, Int_2_Par_Val == 10, */\n    /*                  Int_Par_Ref becomes 18                   */\n{\n  One_Fifty Int_Loc;\n\n  Int_Loc = Int_1_Par_Val + 2;\n  *Int_Par_Ref = Int_2_Par_Val + Int_Loc;\n} /* Proc_7 */\n\n\nvoid Proc_8 (ref Arr_1_Dim Arr_1_Par_Ref, ref Arr_2_Dim Arr_2_Par_Ref, int Int_1_Par_Val, int Int_2_Par_Val)\n/*********************************************************************/\n    /* executed once      */\n    /* Int_Par_Val_1 == 3 */\n    /* Int_Par_Val_2 == 7 */\n{\n      One_Fifty Int_Index;\n      One_Fifty Int_Loc;\n\n  Int_Loc = Int_1_Par_Val + 5;\n  Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;\n  Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];\n  Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;\n  for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)\n    Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;\n  Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;\n  Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];\n  Int_Glob = 5;\n} /* Proc_8 */\n\n\nEnumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)\n/*************************************************/\n    /* executed three times                                         */\n    /* first call:      Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R'    */\n    /* second call:     Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C'    */\n    /* third call:      Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C'    */\n{\n  Capital_Letter        Ch_1_Loc;\n  Capital_Letter        Ch_2_Loc;\n\n  Ch_1_Loc = Ch_1_Par_Val;\n  Ch_2_Loc = Ch_1_Loc;\n  if (Ch_2_Loc != Ch_2_Par_Val)\n    /* then, executed */\n    return (Ident_1);\n  else  /* not executed */\n  {\n    Ch_1_Glob = Ch_1_Loc;\n    return (Ident_2);\n   }\n} /* Func_1 */\n\n\nBoolean Func_2 (Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref)\n/*************************************************/\n    /* executed once */\n    /* Str_1_Par_Ref == \"DHRYSTONE PROGRAM, 1'ST STRING\" */\n    /* Str_2_Par_Ref == \"DHRYSTONE PROGRAM, 2'ND STRING\" */\n{\n      One_Thirty        Int_Loc;\n      Capital_Letter    Ch_Loc;\n\n  Int_Loc = 2;\n  while (Int_Loc <= 2) /* loop body executed once */\n    if (Func_1 (Str_1_Par_Ref[Int_Loc],\n                Str_2_Par_Ref[Int_Loc+1]) == Ident_1)\n      /* then, executed */\n    {\n      Ch_Loc = 'A';\n      Int_Loc += 1;\n    } /* if, while */\n  if (Ch_Loc >= 'W' && Ch_Loc < 'Z')\n    /* then, not executed */\n    Int_Loc = 7;\n  if (Ch_Loc == 'R')\n    /* then, not executed */\n    return (true);\n  else /* executed */\n  {\n    //if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)\n    //if (memcmp (Str_1_Par_Ref, Str_2_Par_Ref, 30) > 0)\n    if (Str_1_Par_Ref > Str_2_Par_Ref)\n      /* then, not executed */\n    {\n      Int_Loc += 7;\n      Int_Glob = Int_Loc;\n      return (true);\n    }\n    else /* executed */\n      return (false);\n  } /* if Ch_Loc */\n} /* Func_2 */\n\n\nBoolean Func_3 (Enumeration Enum_Par_Val)\n/***************************/\n    /* executed once        */\n    /* Enum_Par_Val == Ident_3 */\n{\n  Enumeration Enum_Loc;\n\n  Enum_Loc = Enum_Par_Val;\n  if (Enum_Loc == Ident_3)\n    /* then, executed */\n    return (true);\n  else /* not executed */\n    return (false);\n} /* Func_3 */\n\nversion (Windows)\n{\n    import core.sys.windows.windows;\n\n    double dtime()\n    {\n     double q;\n\n     q = cast(double)GetTickCount() * 1.0e-03;\n\n     return q;\n    }\n}\n\nversion (linux)\n{\n    import core.stdc.time;\n\n    double dtime()\n    {\n     double q;\n\n     q = cast(double)time(null);\n\n     return q;\n    }\n}\n\nversion (OSX)   // supplied by Anders F Bjorklund\n{\n    import core.sys.posix.sys.time;\n\n    double dtime()\n    {\n     double q;\n     timeval tv;\n\n     gettimeofday(&tv,null);\n     q = cast(double)tv.tv_sec + cast(double)tv.tv_usec * 1.0e-6;\n\n     return q;\n    }\n}\n\nversion (NetBSD)\n{\n    import core.sys.posix.sys.time;\n\n    double dtime()\n    {\n     double q;\n     timeval tv;\n\n     gettimeofday(&tv,null);\n     q = cast(double)tv.tv_sec + cast(double)tv.tv_usec * 1.0e-6;\n\n     return q;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/eh.d",
    "content": "// PERMUTE_ARGS: -O -fPIC\n\nextern(C) int printf(const char*, ...);\n\n/****************************************************/\n\nclass Abc : Exception\n{\n    this()\n    {\n        super(\"\");\n    }\n    int i;\n}\n\nint y;\n\nalias int boo;\n\nvoid foo(int x)\n{\n    y = cast(boo)1;\nL6:\n    try\n    {\n        printf(\"try 1\\n\");\n        y += 4;\n        if (y == 5)\n            goto L6;\n        y += 3;\n    }\n    finally\n    {\n        y += 5;\n        printf(\"finally 1\\n\");\n    }\n    try\n    {\n        printf(\"try 2\\n\");\n        y = 1;\n        if (y == 4)\n            goto L6;\n        y++;\n    }\n    catch (Abc c)\n    {\n        printf(\"catch 2\\n\");\n        y = 2 + c.i;\n    }\n    y++;\n    printf(\"done\\n\");\n}\n\n/****************************************************/\n\n\nclass IntException : Exception\n{\n    this(int i)\n    {\n        m_i = i;\n    super(\"\");\n    }\n\n    int getValue()\n    {\n        return m_i;\n    }\n\n    int m_i;\n}\n\n\nvoid test2()\n{\n    int     cIterations =   10;\n\n    int     i;\n    long    total_x     =   0;\n    long    total_nox   =   0;\n\n    for(int WARMUPS = 2; WARMUPS-- > 0; )\n    {\n        for(total_x = 0, i = 0; i < cIterations; ++i)\n        {\n            total_nox += fn2_nox();\n        }\nprintf(\"foo\\n\");\n\n        for(total_nox = 0, i = 0; i < cIterations; ++i)\n        {\nprintf(\"i = %d\\n\", i);\n            try\n            {\n                int z = 1;\n\n                throw new IntException(z);\n            }\n            catch(IntException x)\n            {\nprintf(\"catch, i = %d\\n\", i);\n                total_x += x.getValue();\n            }\n        }\n    }\n\n    printf(\"iterations %d totals: %ld, %ld\\n\", cIterations, total_x, total_nox);\n}\n\nint fn2_nox()\n{\n    return 47;\n}\n\n\n/****************************************************/\n\nvoid test3()\n{\n    static int x;\n    try\n    {\n    }\n    finally\n    {\n        printf(\"a\\n\");\n        assert(x == 0);\n        x++;\n    }\n    printf(\"--\\n\");\n    assert(x == 1);\n    try\n    {\n        printf(\"tb\\n\");\n        assert(x == 1);\n    }\n    finally\n    {\n        printf(\"b\\n\");\n        assert(x == 1);\n        x++;\n    }\n    assert(x == 2);\n}\n\n/****************************************************/\n\nclass Tester\n{\n    this(void delegate() dg_) { dg = dg_; }\n    void delegate() dg;\n    void stuff() { dg(); }\n}\n\nvoid test4()\n{\n    printf(\"Starting test\\n\");\n\n    int a = 0;\n    int b = 0;\n    int c = 0;\n    int d = 0;\n\n    try\n    {\n        a++;\n        throw new Exception(\"test1\");\n        a++;\n    }\n    catch(Exception e)\n    {\n        auto es = e.toString();\n                printf(\"%.*s\\n\", es.length, es.ptr);\n        b++;\n    }\n    finally\n    {\n        c++;\n    }\n\n    printf(\"initial test.\\n\");\n\n    assert(a == 1);\n    assert(b == 1);\n    assert(c == 1);\n\n    printf(\"pass\\n\");\n\n    Tester t = new Tester(\n    delegate void()\n    {\n        try\n        {\n            a++;\n            throw new Exception(\"test2\");\n            a++;\n        }\n        catch(Exception e)\n        {\n            b++;\n            throw e;\n            b++;\n        }\n    });\n\n    try\n    {\n        c++;\n        t.stuff();\n        c++;\n    }\n    catch(Exception e)\n    {\n        d++;\n        string es = e.toString;\n        printf(\"%.*s\\n\", es.length, es.ptr);\n    }\n\n    assert(a == 2);\n    assert(b == 2);\n    assert(c == 2);\n    assert(d == 1);\n\n\n    int q0 = 0;\n    int q1 = 0;\n    int q2 = 0;\n    int q3 = 0;\n\n    Tester t2 = new Tester(\n    delegate void()\n    {\n        try\n        {\n            q0++;\n            throw new Exception(\"test3\");\n            q0++;\n        }\n        catch(Exception e)\n        {\n            printf(\"Never called.\\n\");\n            q1++;\n            throw e;\n            q1++;\n        }\n    });\n\n    try\n    {\n        q2++;\n        t2.stuff();\n        q2++;\n    }\n    catch(Exception e)\n    {\n        q3++;\n                string es = e.toString;\n        printf(\"%.*s\\n\", es.length, es.ptr);\n    }\n\n    assert(q0 == 1);\n    assert(q1 == 1);\n    assert(q2 == 1);\n    assert(q3 == 1);\n\n    printf(\"Passed!\\n\");\n}\n\n/****************************************************/\n\nvoid test5()\n{\n    char[] result;\n    int i = 3;\n    while(i--)\n    {\n        try\n        {\n            printf(\"i: %d\\n\", i);\n            result ~= 't';\n            if (i == 1)\n                continue;\n        }\n        finally\n        {\n            printf(\"finally\\n\");\n            result ~= cast(char)('a' + i);\n        }\n    }\n    printf(\"--- %.*s\", result.length, result.ptr);\n    if (result != \"tctbta\")\n        assert(0);\n}\n\n/****************************************************/\n\nvoid test6()\n{\n    char[] result;\n\n    while (true)\n    {\n        try\n        {\n            printf(\"one\\n\");\n            result ~= 'a';\n            break;\n        }\n        finally\n        {\n            printf(\"two\\n\");\n            result ~= 'b';\n        }\n    }\n    printf(\"three\\n\");\n    result ~= 'c';\n    if (result != \"abc\")\n        assert(0);\n}\n\n/****************************************************/\n\nstring a7;\n\nvoid doScan(int i)\n{\n    a7 ~= \"a\";\n    try\n    {\n        try\n        {\n            a7 ~= \"b\";\n            return;\n        }\n        finally\n        {\n            a7 ~= \"c\";\n        }\n    }\n    finally\n    {\n        a7 ~= \"d\";\n    }\n}\n\nvoid test7()\n{\n    doScan(0);\n    assert(a7 == \"abcd\");\n}\n\n\n/****************************************************\n * Exception chaining tests. See also test4.d\n * Don writes about the complexity:\n\nI can explain this, since I did the original implementation.\nWhen I originally implemented this, I discovered that the idea of\n\"chained exceptions\" was hopeless naive. The idea was that while\nprocessing one exception, if you encounter a second one, and you\nchain them together. Then you get a third, fourth, etc.\n\nThe problem is that it's much more complicated than that. Each of\nthe exceptions can be a chain of exceptions themselves. This means\nthat you don't end up with a chain of exceptions, but rather a tree\nof exceptions. That's why there are those really nasty test cases\nin the test suite.\n\nThe examples in the test suite are very difficult to understand if\nyou expect it to be a simple chain!\n\nOn the one hand, I was very proud that I was able to work out the\nbarely-documented behaviour of Windows SEH, and it was really\nthorough. In the initial implementation, all the complexity\nwas covered. It wasn't the bugfix-driven-development which dmd\nusually operates under <g>.\n\nBut on the other hand, once you can see all of the complexity,\nexception chaining becomes much less convincing as a concept. Sure,\nthe full exception tree is available in the final exception which\nyou catch. But, is it of any use? I doubt it very much.\nIt's pretty clearly a nett loss to the language, it increases\ncomplexity with negligible benefit. Fortunately in this case, the\ncost isn't really high.\n\nhttps://digitalmars.com/d/archives/digitalmars/D/Dicebot_on_leaving_D_It_is_anarchy_driven_development_in_all_its_317950.html#N318305\n ****************************************************/\nint result1513;\n\nvoid bug1513a()\n{\n     throw new Exception(\"d\");\n}\n\nvoid bug1513b()\n{\n    try\n    {\n        try\n        {\n            bug1513a();\n        }\n        finally\n        {\n            result1513 |=4;\n           throw new Exception(\"f\");\n        }\n    }\n    catch(Exception e)\n    {\n        assert(e.msg == \"d\");\n        assert(e.next.msg == \"f\");\n        assert(!e.next.next);\n        int i;\n        foreach (u; e)\n        {\n            if (i)\n                assert(u.msg == \"f\");\n            else\n                assert(u.msg == \"d\");\n            ++i;\n        }\n    }\n}\n\nvoid bug1513c()\n{\n    try\n    {\n        try\n        {\n            throw new Exception(\"a\");\n        }\n        finally\n        {\n            result1513 |= 1;\n            throw new Exception(\"b\");\n        }\n    }\n    finally\n    {\n        bug1513b();\n        result1513 |= 2;\n        throw new Exception(\"c\");\n    }\n}\n\nvoid bug1513()\n{\n    result1513 = 0;\n    try\n    {\n        bug1513c();\n    }\n    catch(Exception e)\n    {\n        assert(result1513 == 7);\n        assert(e.msg == \"a\");\n        assert(e.next.msg == \"b\");\n        assert(e.next.next.msg == \"c\");\n    }\n}\n\nvoid collideone()\n{\n    try\n    {\n        throw new Exception(\"x\");\n    }\n    finally\n    {\n        throw new Exception(\"y\");\n    }\n}\n\nvoid doublecollide()\n{\n    try\n    {\n        try\n        {\n            try\n            {\n                throw new Exception(\"p\");\n            }\n            finally\n            {\n                throw new Exception(\"q\");\n            }\n        }\n        finally\n        {\n            collideone();\n        }\n    }\n    catch(Exception e)\n    {\n            assert(e.msg == \"p\");\n            assert(e.next.msg == \"q\");\n            assert(e.next.next.msg == \"x\");\n            assert(e.next.next.next.msg == \"y\");\n            assert(!e.next.next.next.next);\n    }\n}\n\nvoid collidetwo()\n{\n       try\n        {\n            try\n            {\n                throw new Exception(\"p2\");\n            }\n            finally\n            {\n                throw new Exception(\"q2\");\n            }\n        }\n        finally\n        {\n            collideone();\n        }\n}\n\nvoid collideMixed()\n{\n    int works = 6;\n    try\n    {\n        try\n        {\n            try\n            {\n                throw new Exception(\"e\");\n            }\n            finally\n            {\n                throw new Error(\"t\");\n            }\n        }\n        catch(Exception f)\n        {    // Doesn't catch, because Error is chained to it.\n            works += 2;\n        }\n    }\n    catch(Error z)\n    {\n        works += 4;\n        assert(z.msg==\"t\"); // Error comes first\n        assert(z.next is null);\n        assert(z.bypassedException.msg == \"e\");\n    }\n    assert(works == 10);\n}\n\nclass AnotherException : Exception\n{\n    this(string s)\n    {\n        super(s);\n    }\n}\n\nvoid multicollide()\n{\n    try\n    {\n       try\n        {\n            try\n            {\n                try\n                {\n                    throw new Exception(\"m2\");\n                }\n                finally\n                {\n                    throw new AnotherException(\"n2\");\n                }\n            }\n            catch(AnotherException s)\n            {   // Not caught -- we needed to catch the root cause \"m2\", not\n                // just the collateral \"n2\" (which would leave m2 uncaught).\n                assert(0);\n            }\n        }\n        finally\n        {\n            collidetwo();\n        }\n    }\n    catch(Exception f)\n    {\n        assert(f.msg == \"m2\");\n        assert(f.next.msg == \"n2\");\n        Throwable e = f.next.next;\n        assert(e.msg == \"p2\");\n        assert(e.next.msg == \"q2\");\n        assert(e.next.next.msg == \"x\");\n        assert(e.next.next.next.msg == \"y\");\n        assert(!e.next.next.next.next);\n    }\n}\n\n/****************************************************/\n\nvoid use9568(char [] x, char [] y) {}\n\nint bug9568()\n{\n    try\n        return 7;\n     finally\n        use9568(null,null);\n}\n\nvoid test9568()\n{\n    assert( bug9568() == 7 );\n}\n\n/****************************************************/\n\nversion (DigitalMars)\n{\nvoid test8a()\n{\n  int a;\n  goto L2;    // L2 is not addressable.\n\n  try {\n      a += 2;\n  }\n  catch (Exception) {\n      a += 3;\nL2: ;\n      a += 100;\n  }\n  assert(a == 100);\n}\n\nvoid test8b()\n{\n  int a;\n  goto L2;    // L2 is not addressable.\n\n  try {\n  }\n  catch (Exception) {\n      a += 3;\nL2: ;\n      a += 100;\n  }\n  assert(a == 100);\n}\n\nvoid test8c()\n{\n  int a;\n  goto L2;    // L2 is not addressable.\n\n  try\n    static assert(true);\n  catch (Exception) {\n      a += 3;\nL2: ;\n      a += 100;\n  }\n  assert(a == 100);\n}\n\nvoid test8()\n{\n  test8a();\n  test8b();\n  test8c();\n}\n}\n\n/****************************************************/\n\nuint foo9(uint i)\n{\n    try\n    {\n        ++i;\n        return 3;\n    }\n    catch (Exception e)\n    {\n        debug printf(\"Exception happened\\n\");\n    }\n    return 4;\n}\n\nvoid test9()\n{\n    assert(foo9(7) == 3);\n}\n\n/****************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10964\n\nvoid test10964()\n{\n    static struct S\n    {\n        this(this)\n        {\n            throw new Exception(\"BOOM!\");\n        }\n    }\n\n    S    ss;\n    S[1] sa;\n    int result;\n\n    result = 0;\n    try\n    {\n        ss = ss;\n    }\n    catch (Exception e) result = 1;\n    catch (Error     e) result = 2;\n    catch (Throwable e) result = 3;\n    assert(result == 1);\n\n    try\n    {\n        sa = ss;\n    }\n    catch (Exception e) result = 1;\n    catch (Error     e) result = 2;\n    catch (Throwable e) result = 3;\n    assert(result == 1);\n\n    try\n    {\n        sa = sa;\n    }\n    catch (Exception e) result = 1;\n    catch (Error     e) result = 2;\n    catch (Throwable e) result = 3;\n    assert(result == 1);\n}\n\n/****************************************************/\n\nalias Action = void delegate();\n\nclass A10\n{\n    invariant()\n    {\n    }\n\n    public Action foo(Action a)\n    {\n        synchronized\n        {\n            B10 elements = new B10;\n            Action[] actions = [a];\n\n            elements.bar(actions);\n\n            if (actions.length > 1)\n                elements.bar(actions);\n            return actions[0];\n        }\n        return null;\n    }\n}\n\nclass B10\n{\n    public bool bar(ref Action[])\n    {\n        return false;\n    }\n}\n\nclass D10\n{\n    void baz()\n    {\n    }\n}\n\nvoid test12989()\n{\n    auto a = new A10;\n    auto d = new D10;\n\n    assert(a.foo(&d.baz) == &d.baz);\n}\n\n/****************************************************/\n\nint bar10(int c)\n{\n    if (c <= 0xFFFF)\n    {\n    L3:\n        return 3;\n    }\n    throw new Exception(\"msg\");\n    goto L3;\n}\n\nvoid test10()\n{\n    int x;\n    try\n    {\n        bar10(0x110000);\n    }\n    catch (Exception e)\n    {\n        printf(\"caught\\n\");\n        x = 1;\n    }\n    assert(x == 1);\n    printf(\"test10 success\\n\");\n}\n\n/****************************************************/\n\nclass ParseException : Exception\n{\n    @safe pure nothrow this( string msg )\n    {\n        super( msg );\n    }\n}\n\nclass OverflowException : Exception\n{\n    @safe pure nothrow this( string msg )\n    {\n        super( msg );\n    }\n}\n\nvoid test11()\n{\n    int x;\n    try\n    {\n        printf(\"test11()\\n\");\n        throw new ParseException(\"msg\");\n    }\n    catch( OverflowException e )\n    {\n        printf( \"catch OverflowException\\n\" );\n    }\n    catch( ParseException e )\n    {\n        printf( \"catch ParseException: %.*s\\n\", cast(int) e.msg.length, e.msg.ptr );\n        x = 1;\n    }\n    assert(x == 1);\n}\n\n/****************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17481\n\nclass C17481\n{\n    synchronized void trigger(){ new ubyte[1]; }\n}\n\nvoid test17481()\n{\n    auto k = new shared C17481;\n    k.trigger;\n}\n\n/****************************************************/\n\n// a nothrow function, even though it is not marked as nothrow\nvoid test12()\n{\n    int i = 3;\n    try\n    {\n        try\n        {\n            ++i;\n            goto L10;\n        }\n        finally\n        {\n            i *= 2;\n            printf(\"f1\\n\");\n        }\n    }\n    finally\n    {\n        i += 5;\n        printf(\"f2\\n\");\n    }\n\nL10:\n    printf(\"3\\n\");\n    assert(i == (3 + 1) * 2 + 5);\n}\n\n/****************************************************/\n\nvoid foo13() { }\n\nvoid test13()\n{\n    int i = 3;\n    try\n    {\n        try\n        {\n            foo13(); // compiler assumes it throws\n            ++i;\n            goto L10;\n        }\n        finally\n        {\n            i *= 2;\n            printf(\"f1\\n\");\n        }\n    }\n    finally\n    {\n        i += 5;\n        printf(\"f2\\n\");\n    }\n\nL10:\n    printf(\"3\\n\");\n    assert(i == (3 + 1) * 2 + 5);\n}\n\n/****************************************************/\n\nint main()\n{\n    printf(\"start\\n\");\n    foo(3);\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n\n    bug1513();\n    doublecollide();\n    collideMixed();\n    multicollide();\n    test9568();\n\n    version(DigitalMars) test8();\n    test9();\n    test10964();\n    test12989();\n    test10();\n    test11();\n    test17481();\n    test12();\n    test13();\n\n    printf(\"finish\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/eh2.d",
    "content": "// PERMUTE_ARGS: -fPIC\n\nextern(C) int printf(const char*, ...);\n\nclass Abc : Throwable\n{\n    this() pure\n    {\n        super(\"\");\n    }\n    static int x;\n    int a,b,c;\n\n    synchronized void test()\n    {\n        printf(\"test 1\\n\");\n        x |= 1;\n        foo();\n        printf(\"test 2\\n\");\n        x |= 2;\n    }\n\n    shared void foo()\n    {\n        printf(\"foo 1\\n\");\n        x |= 4;\n        throw this;\n        printf(\"foo 2\\n\");\n        x |= 8;\n    }\n}\n\nstruct RefCounted\n{\n    void *p;\n    ~this()\n    {\n        p = null;\n    }\n}\n\nstruct S\n{\n    RefCounted _data;\n\n    int get() @property\n    {\n        throw new Exception(\"\");\n    }\n}\n\nvoid b9438()\n{\n    try\n    {\n        S s;\n        S().get;\n    }\n    catch (Exception e){ }\n}\n\nint main()\n{\n    printf(\"hello world\\n\");\n    auto a = new shared(Abc)();\n    printf(\"hello 2\\n\");\n    Abc.x |= 0x10;\n\n    try\n    {\n        Abc.x |= 0x20;\n        a.test();\n        Abc.x |= 0x40;\n    }\n    catch (shared(Abc) b)\n    {\n        Abc.x |= 0x80;\n        printf(\"Caught %p, x = x%x\\n\", b, Abc.x);\n        assert(a is b);\n        assert(Abc.x == 0xB5);\n    }\n    printf(\"Success!\\n\");\n    b9438();\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/entity1.d",
    "content": "// $HeadURL$\n// $Date$\n// $Author$\n\nmodule dstress.run.named_entity_02;\n\n// \"-//W3C//ENTITIES Symbolic//EN//HTML\"\n\nint main(){\n        assert('\\&fnof;'==402);\n        assert('\\&Alpha;'==913);\n        assert('\\&Beta;'==914);\n        assert('\\&Gamma;'==915);\n        assert('\\&Delta;'==916);\n        assert('\\&Epsilon;'==917);\n        assert('\\&Zeta;'==918);\n        assert('\\&Eta;'==919);\n        assert('\\&Theta;'==920);\n        assert('\\&Iota;'==921);\n        assert('\\&Kappa;'==922);\n        assert('\\&Lambda;'==923);\n        assert('\\&Mu;'==924);\n        assert('\\&Nu;'==925);\n        assert('\\&Xi;'==926);\n        assert('\\&Omicron;'==927);\n        assert('\\&Pi;'==928);\n        assert('\\&Rho;'==929);\n        assert('\\&Sigma;'==931);\n        assert('\\&Tau;'==932);\n        assert('\\&Upsilon;'==933);\n        assert('\\&Phi;'==934);\n        assert('\\&Chi;'==935);\n        assert('\\&Psi;'==936);\n        assert('\\&Omega;'==937);\n        assert('\\&alpha;'==945);\n        assert('\\&beta;'==946);\n        assert('\\&gamma;'==947);\n        assert('\\&delta;'==948);\n        assert('\\&epsilon;'==949);\n        assert('\\&zeta;'==950);\n        assert('\\&eta;'==951);\n        assert('\\&theta;'==952);\n        assert('\\&iota;'==953);\n        assert('\\&kappa;'==954);\n        assert('\\&lambda;'==955);\n        assert('\\&mu;'==956);\n        assert('\\&nu;'==957);\n        assert('\\&xi;'==958);\n        assert('\\&omicron;'==959);\n        assert('\\&pi;'==960);\n        assert('\\&rho;'==961);\n        assert('\\&sigmaf;'==962);\n        assert('\\&sigma;'==963);\n        assert('\\&tau;'==964);\n        assert('\\&upsilon;'==965);\n        assert('\\&phi;'==966);\n        assert('\\&chi;'==967);\n        assert('\\&psi;'==968);\n        assert('\\&omega;'==969);\n        assert('\\&thetasym;'==977);\n        assert('\\&upsih;'==978);\n        assert('\\&piv;'==982);\n        assert('\\&bull;'==8226);\n        assert('\\&hellip;'==8230);\n        assert('\\&prime;'==8242);\n        assert('\\&Prime;'==8243);\n        assert('\\&oline;'==8254);\n        assert('\\&frasl;'==8260);\n        assert('\\&weierp;'==8472);\n        assert('\\&image;'==8465);\n        assert('\\&real;'==8476);\n        assert('\\&trade;'==8482);\n        assert('\\&alefsym;'==8501);\n        assert('\\&larr;'==8592);\n        assert('\\&uarr;'==8593);\n        assert('\\&rarr;'==8594);\n        assert('\\&darr;'==8595);\n        assert('\\&harr;'==8596);\n        assert('\\&crarr;'==8629);\n        assert('\\&lArr;'==8656);\n        assert('\\&uArr;'==8657);\n        assert('\\&rArr;'==8658);\n        assert('\\&dArr;'==8659);\n        assert('\\&hArr;'==8660);\n        assert('\\&forall;'==8704);\n        assert('\\&part;'==8706);\n        assert('\\&exist;'==8707);\n        assert('\\&empty;'==8709);\n        assert('\\&nabla;'==8711);\n        assert('\\&isin;'==8712);\n        assert('\\&notin;'==8713);\n        assert('\\&ni;'==8715);\n        assert('\\&prod;'==8719);\n        assert('\\&sum;'==8721);\n        assert('\\&minus;'==8722);\n        assert('\\&lowast;'==8727);\n        assert('\\&radic;'==8730);\n        assert('\\&prop;'==8733);\n        assert('\\&infin;'==8734);\n        assert('\\&ang;'==8736);\n        assert('\\&and;'==8743);\n        assert('\\&or;'==8744);\n        assert('\\&cap;'==8745);\n        assert('\\&cup;'==8746);\n        assert('\\&int;'==8747);\n        assert('\\&there4;'==8756);\n        assert('\\&sim;'==8764);\n        assert('\\&cong;'==8773);\n        assert('\\&asymp;'==8776);\n        assert('\\&ne;'==8800);\n        assert('\\&equiv;'==8801);\n        assert('\\&le;'==8804);\n        assert('\\&ge;'==8805);\n        assert('\\&sub;'==8834);\n        assert('\\&sup;'==8835);\n        assert('\\&nsub;'==8836);\n        assert('\\&sube;'==8838);\n        assert('\\&supe;'==8839);\n        assert('\\&oplus;'==8853);\n        assert('\\&otimes;'==8855);\n        assert('\\&perp;'==8869);\n        assert('\\&sdot;'==8901);\n        assert('\\&lceil;'==8968);\n        assert('\\&rceil;'==8969);\n        assert('\\&lfloor;'==8970);\n        assert('\\&rfloor;'==8971);\n        //assert('\\&lang;'==9001); // U+2329 valid for HTML 4.01; changed in HTML5\n        //assert('\\&rang;'==9002); // U+232A valid for HTML 4.01; changed in HTML5\n    assert('\\&lang;'==0x27E8); // valid for HTML 5 and later. The character was introduced in HTML 3.2\n    assert('\\&rang;'==0x27E9); // valid for HTML 5 and later. The character was introduced in HTML 3.2\n        assert('\\&loz;'==9674);\n        assert('\\&spades;'==9824);\n        assert('\\&clubs;'==9827);\n        assert('\\&hearts;'==9829);\n        assert('\\&diams;'==9830);\n        return 0;\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=5221\nstatic assert('\\&check;'==10003);\nstatic assert('\\&lsim;'==8818);\nstatic assert('\\&numero;'==8470);\nstatic assert('\\&urcorn;'==8989);\nstatic assert('\\&Zdot;'==379);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/evalorder.d",
    "content": "extern(C) int printf(const char*, ...);\n\nvoid test14040()\n{\n    uint[] values = [0, 1, 2, 3, 4, 5, 6, 7];\n    uint offset = 0;\n\n    auto a1 = values[offset .. offset += 2];\n    if (a1 != [0, 1] || offset != 2)\n        assert(0);\n\n    uint[] fun()\n    {\n        offset += 2;\n        return values;\n    }\n    auto a2 = fun()[offset .. offset += 2];\n    if (a2 != [4, 5] || offset != 6)\n        assert(0);\n\n    // Also test an offset of type size_t such that it is used\n    // directly without any implicit conversion in the slice expression.\n    size_t offset_szt = 0;\n    auto a3 = values[offset_szt .. offset_szt += 2];\n    if (a3 != [0, 1] || offset_szt != 2)\n        assert(0);\n}\n\n/******************************************/\n\nint add8ret3(T)(ref T s)\n{\n    s += 8;\n    return 3;\n}\n\nint mul11ret3(T)(ref T s)\n{\n    s *= 11;\n    return 3;\n}\n\nvoid add()\n{\n    static int test1(int val) { val += add8ret3(val); return val; }\n    assert(test1(1) == (1 + 8 + 3));\n    static assert(test1(1) == (1 + 8 + 3));\n\n    static int test2(int val) { val = val + add8ret3(val); return val; }\n    // FIXME: assert(test2(1) == (1 + 3));\n    static assert(test2(1) == (1 + 3));\n\n    static int test3(int val) { (val += 7) += mul11ret3(val); return val; }\n    assert(test3(2) == (((2+7)*11) + 3));\n    static assert(test3(2) == (((2+7)*11) + 3));\n}\n\nvoid min()\n{\n    static int test1(int val) { val -= add8ret3(val); return val; }\n    assert(test1(1) == (1 + 8 - 3));\n    static assert(test1(1) == (1 + 8 - 3));\n\n    static int test2(int val) { val = val - add8ret3(val); return val; }\n    // FIXME: assert(test2(1) == (1 - 3));\n    static assert(test2(1) == (1 - 3));\n\n    static int test3(int val) { (val -= 7) -= mul11ret3(val); return val; }\n    assert(test3(2) == (((2-7)*11) - 3));\n    static assert(test3(2) == (((2-7)*11) - 3));\n}\n\nvoid mul()\n{\n    static int test1(int val) { val *= add8ret3(val); return val; }\n    assert(test1(7) == ((7 + 8) * 3));\n    static assert(test1(7) == ((7 + 8) * 3));\n\n    static int test2(int val) { val = val * add8ret3(val); return val; }\n    // FIXME: assert(test2(7) == (7 * 3));\n    static assert(test2(7) == (7 * 3));\n\n    static int test3(int val) { (val *= 7) *= add8ret3(val); return val; }\n    assert(test3(2) == (((2*7)+8) * 3));\n    static assert(test3(2) == (((2*7)+8) * 3));\n}\n\nvoid xor()\n{\n    static int test1(int val) { val ^= add8ret3(val); return val; }\n    assert(test1(1) == ((1 + 8) ^ 3));\n    static assert(test1(1) == ((1 + 8) ^ 3));\n\n    static int test2(int val) { val = val ^ add8ret3(val); return val; }\n    // FIXME: assert(test2(1) == (1 ^ 3));\n    static assert(test2(1) == (1 ^ 3));\n\n    static int test3(int val) { (val ^= 7) ^= add8ret3(val); return val; }\n    assert(test3(2) == (((2^7)+8) ^ 3));\n    static assert(test3(2) == (((2^7)+8) ^ 3));\n}\n\nvoid addptr()\n{\n    static int* test1(int* val) { val += add8ret3(val); return val; }\n    assert(test1(cast(int*)4) == ((cast(int*)4) + 8 + 3));\n\n    static int* test2(int* val) { val = val + add8ret3(val); return val; }\n    // FIXME: assert(test2(cast(int*)4) == ((cast(int*)4) + 3));\n\n    static int* test3(int* val) { (val += 7) += add8ret3(val); return val; }\n    assert(test3(cast(int*)16) == ((cast(int*)16) + 7 + 8 + 3));\n}\n\nvoid lhsCast()\n{\n    static byte test(byte val)\n    {\n        // lhs type `byte`, rhs type `int` =>\n        // rewritten to `cast(int)(cast(int)val += 10) -= mul11ret3(val)`\n        (val += 10) -= mul11ret3(val);\n        return val;\n    }\n\n    assert(test(1) == ((1 + 10) * 11 - 3));\n    static assert(test(1) == ((1 + 10) * 11 - 3));\n}\n\nvoid shr()\n{\n    static ubyte test(ubyte val)\n    {\n        // lhs type `ubyte`, rhs type `int` =>\n        // rewritten to `cast(int)val >>= 1`\n        // we still want a logical (unsigned) right-shift though\n        val >>= 1;\n        return val;\n    }\n\n    assert(test(0x80) == 0x40);\n    static assert(test(0x80) == 0x40);\n}\n\nvoid ldc_github_1617()\n{\n    add();\n    min();\n    mul();\n    xor();\n    addptr();\n    lhsCast();\n    shr();\n}\n\n/******************************************/\n\nint main()\n{\n    test14040();\n    ldc_github_1617();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extern1.d",
    "content": "// note: not actually imported, just built and linked against\n// EXTRA_SOURCES: imports/extern1a.d\n// PERMUTE_ARGS:\n\nextern (C)\n{\n    extern int x;\n}\n\nint main()\n{\n    assert(x == 3);\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/externmangle.d",
    "content": "// EXTRA_CPP_SOURCES: extra-files/externmangle.cpp\n\nimport core.stdc.config;\nimport core.stdc.stdint;\n\nextern(C++):\n\nstruct Foo(X)\n{\n    X* v;\n}\n\n\nstruct Boo(X)\n{\n    X* v;\n}\n\n\nvoid test1(Foo!int arg1);\nvoid test2(int* arg2, Boo!(int*) arg1);\n\n\nstruct Test3(int X, int Y)\n{\n}\n\nvoid test3(Test3!(3,3) arg1);\n\nvoid test4(Foo!(int*) arg1, Boo!(int*) arg2, Boo!(int*) arg3, int*, Foo!(double));\n\nvoid test5(Foo!(int*) arg1, Boo!(int*) arg2, Boo!(int*) arg3);\n\n\nstruct Goo\n{\n    struct Foo(X)\n    {\n        X* v;\n    }\n\n    struct Boo(X)\n    {\n        struct Xoo(Y)\n        {\n            Y* v;\n        };\n        X* v;\n    }\n\n\n    void test6(Foo!(Boo!(Foo!(void))) arg1);\n    void test7(Boo!(void).Xoo!(int) arg1);\n}\n\nstruct P1\n{\n    struct Mem(T)\n    {\n    }\n}\n\nstruct P2\n{\n    struct Mem(T)\n    {\n    }\n}\n\nvoid test8(P1.Mem!int, P2.Mem!int);\nvoid test9(Foo!(int**), Foo!(int*), int**, int*);\n\n\ninterface Test10\n{\n    private final void test10();\n    public final void test11();\n    protected final void test12();\n    public final void test13() const;\n\n    private void test14();\n    public void test15();\n    protected void test16();\n\n    private static void test17();\n    public static void test18();\n    protected static void test19();\n};\n\nTest10 Test10Ctor();\nvoid Test10Dtor(ref Test10 ptr);\n\nstruct Test20\n{\n    __gshared:\n    private extern int test20;\n    protected extern int test21;\n    public extern int test22;\n};\n\n\nint test23(Test10*, Test10, Test10**, const(Test10));\nint test23b(const Test10*, const Test10, Test10);\n\nvoid test24(int function(int,int));\n\nvoid test25(int[291][6][5]* arr);\nint test26(int[291][6]* arr);\n\nvoid test27(int, ...);\nvoid test28(int);\n\nvoid test29(float);\nvoid test30(const float);\n\nstruct Array(T)\n{\n    int dim;\n}\n\n\ninterface Module\n{\n    public static void imports(Module);\n    public static int dim(Array!Module*);\n};\n\nuint64_t testlongmangle(int a, uint b, int64_t c, uint64_t d);\ncpp_ulong testCppLongMangle(cpp_long a, cpp_ulong b);\ncpp_ulonglong testCppLongLongMangle(cpp_longlong a, cpp_ulonglong b);\n\n// direct size_t/ptrdiff_t interop is fine except on 32-bit OS X\nversion (OSX) { version (D_LP64) {} else version = OSX_32; }\nversion (OSX_32)\n    cpp_size_t testCppSizeTMangle(cpp_ptrdiff_t a, cpp_size_t b);\nelse\n    size_t testCppSizeTMangle(ptrdiff_t a, size_t b);\n\n__gshared extern int[2][2][2] test31;\n__gshared extern int* test32;\n\n\nalias int function(Expression , void* ) apply_fp_t;\n\ninterface Expression\n{\n    public final int apply(apply_fp_t fp, apply_fp_t fp2, void* param);\n    public final int getType();\n    public static Expression create(int);\n    public static void dispose(ref Expression);\n}\n\n//int test34(int[0][0]*);\nversion(CRuntime_Microsoft){}\nelse\n{\n    int test35(real arg);\n}\n\nconst(char)* test36(const(char)*);\n\nfinal class Test37\n{\n    static Test37 create()\n    {\n        return new Test37;\n    }\n\n    bool test()\n    {\n        return true;\n    }\n}\n\nbool test37();\n\ninterface Test38\n{\n     final int test(int, ...);\n     public static Test38 create();\n     public static void dispose(ref Test38);\n}\n\nextern(C++) int test39cpp(C2!char, S2!(int)*);\n\nextern(C++, class)\nstruct S1\n{\n    private int val;\n    static S1* init(int);\n    int value();\n}\n\nextern(C++, class)\nstruct S2(T)\n{\n    private T val;\n    static S2!T* init(int);\n    T value();\n}\n\nextern(C++, struct)\nclass C1\n{\n    const(char)* data;\n\n    static C1 init(const(char)* p);\n    const(char)* getDataCPP();\n    extern(C++) const(char)* getDataD()\n    {\n        return data;\n    }\n}\n\nextern(C++, struct)\nclass C2(T)\n{\n    const(T)* data;\n\n    static C2!T init(const(T)* p);\n    const(T)* getData();\n}\n\nvoid test39()\n{\n    S1* s1 = S1.init(42);\n    assert(s1.value == 42);\n    assert(S2!int.init(43).value == 43);\n    const(char)* ptr = \"test\".ptr;\n    C1 c1 = C1.init(ptr);\n    assert(c1.getDataCPP() == ptr);\n    assert(c1.getDataD() == ptr);\n    C2!char c2 = C2!char.init(ptr);\n    assert(c2.getData() == ptr);\n    auto result = test39cpp(c2, S2!int.init(43));\n    assert(result == 0);\n}\n\n\nvoid main()\n{\n    test1(Foo!int());\n    test2(null, Boo!(int*)());\n    test3(Test3!(3,3)());\n    test4(Foo!(int*)(), Boo!(int*)(), Boo!(int*)(), null, Foo!(double)());\n    test5(Foo!(int*)(), Boo!(int*)(), Boo!(int*)());\n    Goo goo;\n    goo.test6(Goo.Foo!(Goo.Boo!(Goo.Foo!(void)))());\n    goo.test7(Goo.Boo!(void).Xoo!(int)());\n\n    test8(P1.Mem!int(), P2.Mem!int());\n    test9(Foo!(int**)(), Foo!(int*)(), null, null);\n\n    auto t10 = Test10Ctor();\n    scope(exit) Test10Dtor(t10);\n\n    t10.test10();\n    t10.test11();\n    t10.test12();\n    t10.test13();\n    t10.test14();\n    t10.test15();\n    t10.test16();\n    t10.test17();\n    t10.test18();\n    t10.test19();\n\n    assert(Test20.test20 == 20);\n    assert(Test20.test21 == 21);\n    assert(Test20.test22 == 22);\n\n    assert(test23(null, null, null, null) == 1);\n    assert(test23b(null, null, null) == 1);\n\n    extern(C++) static int cb(int a, int b){return a+b;}\n\n    test24(&cb);\n    int[291][6][5] arr;\n    arr[1][1][1] = 42;\n    test25(&arr);\n    assert(test26(&arr[0]) == 42);\n\n    test27(3,4,5);\n    test28(3);\n\n    test29(3.14f);\n    test30(3.14f);\n\n    auto t32 = &Module.imports;\n    Array!Module arr2;\n    arr2.dim = 20;\n    assert(Module.dim(&arr2) == 20);\n\n    assert(testlongmangle(1, 2, 3, 4) == 10);\n    assert(testCppLongMangle(1, 2) == 3);\n    assert(testCppLongLongMangle(3, 4) == 7);\n    assert(testCppSizeTMangle(3, 4) == 7);\n    assert(test31 == [[[1, 1], [1, 1]], [[1, 1], [1, 1]]]);\n    assert(test32 == null);\n\n    auto ee = Expression.create(42);\n    extern(C++) static int efun(Expression e, void* p)\n    {\n        return cast(int)(cast(size_t)p ^ e.getType());\n    }\n\n    extern(C++) static int efun2(Expression e, void* p)\n    {\n        return cast(int)(cast(size_t)p * e.getType());\n    }\n\n    auto test33 = ee.apply(&efun, &efun2, cast(void*)&Expression.create);\n    assert(test33 == cast(int)(cast(size_t)cast(void*)&Expression.create ^ 42) * cast(int)(cast(size_t)cast(void*)&Expression.create * 42));\n    Expression.dispose(ee);\n    assert(ee is null);\n    //assert(test34(null) == 0);\n    version(CRuntime_Microsoft){}\n    else\n    {\n        assert(test35(3.14L) == 3);\n    }\n    const char* hello = \"hello\";\n    assert(test36(hello) == hello);\n    assert(test37());\n    auto t38 = Test38.create();\n    assert(t38.test(1, 2, 3) == 1);\n    Test38.dispose(t38);\n    test39();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/externmangle2.d",
    "content": "// EXTRA_CPP_SOURCES: extra-files/externmangle2.cpp\n\nversion(Windows)\n{\n    void main()\n    {\n    }\n}\nelse\n{\n    extern(C++):\n\n    struct Test32NS1\n    {\n        struct Foo(X)\n        {\n            X *v;\n        }\n\n\n        struct Bar(X)\n        {\n            X *v;\n        }\n\n    };\n\n    struct Test32NS2\n    {\n        struct Foo(X)\n        {\n            X *v;\n        }\n    };\n\n    struct Test32(alias Y, alias Z)\n    {\n        Y!(int)* field;\n    };\n\n\n    void test32a(Test32!(Test32NS1.Foo, Test32NS1.Foo) arg);\n    void test32b(Test32!(Test32NS1.Foo, Test32NS1.Bar) arg);\n    void test32c(Test32!(Test32NS1.Foo, Test32NS2.Foo) arg);\n    void test32d(Test32!(Test32NS1.Foo, Test32NS2.Foo) arg1, Test32!(Test32NS2.Foo, Test32NS1.Foo) arg2);\n\n    interface XXX\n    {\n    }\n\n    void test33a(XXX, XXX*);\n\n\n    struct Test33(alias A, alias B)\n    {\n    }\n\n    /*\n    void test33(XXX, Test33!(test33a, test33a) arg, XXX);\n\n\n    struct Test34(alias A)\n    {\n    };\n\n    struct Test34A\n    {\n        static void foo(int);\n    };\n\n\n    void test34(Test34!(Test34A.foo) arg);\n    */\n\n    __gshared extern int test36;\n\n    /*\n    struct Test37(alias A)\n    {\n    };\n\n    struct Test37A\n    {\n        __gshared extern int t38;\n    };\n\n    void test37(Test37!(test36) arg);\n    void test38(Test37!(Test37A.t38) arg);\n    */\n\n    struct Test39\n    {\n        struct T39A(X)\n        {\n        }\n    }\n\n    struct T39A\n    {\n    }\n\n    void test39(Test39.T39A!(.T39A));\n\n    version(none)\n    {\n        version(Posix) //Only for g++ with -std=c++0x and Visual Studio 2013+\n        {\n\n            struct Test40(T, V...)\n            {\n\n            }\n\n            void test40(Test40!(int, double, void))\n            {\n            }\n        }\n        else version(Win64) //Only for g++ with -std=c++0x and Visual Studio 2013+\n        {\n\n            struct Test40(T, V...)\n            {\n\n            }\n\n            void test40(Test40!(int, double, void))\n            {\n            }\n        }\n    }\n\n\n    __gshared extern const XXX test41;\n    struct Test42\n    {\n        __gshared extern const XXX test42;\n    }\n    __gshared extern int[4] test43;\n    const(XXX) test44();\n\n    void main()\n    {\n        test32a(Test32!(Test32NS1.Foo, Test32NS1.Foo)());\n        test32b(Test32!(Test32NS1.Foo, Test32NS1.Bar)());\n        test32c(Test32!(Test32NS1.Foo, Test32NS2.Foo)());\n        test32d(Test32!(Test32NS1.Foo, Test32NS2.Foo)(), Test32!(Test32NS2.Foo, Test32NS1.Foo)());\n\n        //test33a(null, null);\n        //test33(null, Test33!(test33a, test33a)(), null);\n\n        //test34(Test34!(Test34A.foo)());\n\n        assert(test36 == 36);\n\n        //test37(Test37!(test36)());\n        //test38(Test37!(Test37A.t38)());\n        test39(Test39.T39A!(.T39A)());\n\n        assert(test41 is null);\n        assert(Test42.test42 is null);\n        assert(test43 == [1, 2, 3, 4]);\n        auto ptr = &test44;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/alice30.txt",
    "content": "\n\n\n\n                ALICE'S ADVENTURES IN WONDERLAND\n\n                          Lewis Carroll\n\n               THE MILLENNIUM FULCRUM EDITION 3.0\n\n\n\n\n                            CHAPTER I\n\n                      Down the Rabbit-Hole\n\n\n  Alice was beginning to get very tired of sitting by her sister\non the bank, and of having nothing to do:  once or twice she had\npeeped into the book her sister was reading, but it had no\npictures or conversations in it, `and what is the use of a book,'\nthought Alice `without pictures or conversation?'\n\n  So she was considering in her own mind (as well as she could,\nfor the hot day made her feel very sleepy and stupid), whether\nthe pleasure of making a daisy-chain would be worth the trouble\nof getting up and picking the daisies, when suddenly a White\nRabbit with pink eyes ran close by her.\n\n  There was nothing so VERY remarkable in that; nor did Alice\nthink it so VERY much out of the way to hear the Rabbit say to\nitself, `Oh dear!  Oh dear!  I shall be late!'  (when she thought\nit over afterwards, it occurred to her that she ought to have\nwondered at this, but at the time it all seemed quite natural);\nbut when the Rabbit actually TOOK A WATCH OUT OF ITS WAISTCOAT-\nPOCKET, and looked at it, and then hurried on, Alice started to\nher feet, for it flashed across her mind that she had never\nbefore seen a rabbit with either a waistcoat-pocket, or a watch to\ntake out of it, and burning with curiosity, she ran across the\nfield after it, and fortunately was just in time to see it pop\ndown a large rabbit-hole under the hedge.\n\n  In another moment down went Alice after it, never once\nconsidering how in the world she was to get out again.\n\n  The rabbit-hole went straight on like a tunnel for some way,\nand then dipped suddenly down, so suddenly that Alice had not a\nmoment to think about stopping herself before she found herself\nfalling down a very deep well.\n\n  Either the well was very deep, or she fell very slowly, for she\nhad plenty of time as she went down to look about her and to\nwonder what was going to happen next.  First, she tried to look\ndown and make out what she was coming to, but it was too dark to\nsee anything; then she looked at the sides of the well, and\nnoticed that they were filled with cupboards and book-shelves;\nhere and there she saw maps and pictures hung upon pegs.  She\ntook down a jar from one of the shelves as she passed; it was\nlabelled `ORANGE MARMALADE', but to her great disappointment it\nwas empty:  she did not like to drop the jar for fear of killing\nsomebody, so managed to put it into one of the cupboards as she\nfell past it.\n\n  `Well!' thought Alice to herself, `after such a fall as this, I\nshall think nothing of tumbling down stairs!  How brave they'll\nall think me at home!  Why, I wouldn't say anything about it,\neven if I fell off the top of the house!' (Which was very likely\ntrue.)\n\n  Down, down, down.  Would the fall NEVER come to an end!  `I\nwonder how many miles I've fallen by this time?' she said aloud.\n`I must be getting somewhere near the centre of the earth.  Let\nme see:  that would be four thousand miles down, I think--' (for,\nyou see, Alice had learnt several things of this sort in her\nlessons in the schoolroom, and though this was not a VERY good\nopportunity for showing off her knowledge, as there was no one to\nlisten to her, still it was good practice to say it over) `--yes,\nthat's about the right distance--but then I wonder what Latitude\nor Longitude I've got to?'  (Alice had no idea what Latitude was,\nor Longitude either, but thought they were nice grand words to\nsay.)\n\n  Presently she began again.  `I wonder if I shall fall right\nTHROUGH the earth!  How funny it'll seem to come out among the\npeople that walk with their heads downward!  The Antipathies, I\nthink--' (she was rather glad there WAS no one listening, this\ntime, as it didn't sound at all the right word) `--but I shall\nhave to ask them what the name of the country is, you know.\nPlease, Ma'am, is this New Zealand or Australia?' (and she tried\nto curtsey as she spoke--fancy CURTSEYING as you're falling\nthrough the air!  Do you think you could manage it?)  `And what\nan ignorant little girl she'll think me for asking!  No, it'll\nnever do to ask:  perhaps I shall see it written up somewhere.'\n\n  Down, down, down.  There was nothing else to do, so Alice soon\nbegan talking again.  `Dinah'll miss me very much to-night, I\nshould think!'  (Dinah was the cat.)  `I hope they'll remember\nher saucer of milk at tea-time.  Dinah my dear!  I wish you were\ndown here with me!  There are no mice in the air, I'm afraid, but\nyou might catch a bat, and that's very like a mouse, you know.\nBut do cats eat bats, I wonder?'  And here Alice began to get\nrather sleepy, and went on saying to herself, in a dreamy sort of\nway, `Do cats eat bats?  Do cats eat bats?' and sometimes, `Do\nbats eat cats?' for, you see, as she couldn't answer either\nquestion, it didn't much matter which way she put it.  She felt\nthat she was dozing off, and had just begun to dream that she\nwas walking hand in hand with Dinah, and saying to her very\nearnestly, `Now, Dinah, tell me the truth:  did you ever eat a\nbat?' when suddenly, thump! thump! down she came upon a heap of\nsticks and dry leaves, and the fall was over.\n\n  Alice was not a bit hurt, and she jumped up on to her feet in a\nmoment:  she looked up, but it was all dark overhead; before her\nwas another long passage, and the White Rabbit was still in\nsight, hurrying down it.  There was not a moment to be lost:\naway went Alice like the wind, and was just in time to hear it\nsay, as it turned a corner, `Oh my ears and whiskers, how late\nit's getting!'  She was close behind it when she turned the\ncorner, but the Rabbit was no longer to be seen:  she found\nherself in a long, low hall, which was lit up by a row of lamps\nhanging from the roof.\n\n  There were doors all round the hall, but they were all locked;\nand when Alice had been all the way down one side and up the\nother, trying every door, she walked sadly down the middle,\nwondering how she was ever to get out again.\n\n  Suddenly she came upon a little three-legged table, all made of\nsolid glass; there was nothing on it except a tiny golden key,\nand Alice's first thought was that it might belong to one of the\ndoors of the hall; but, alas! either the locks were too large, or\nthe key was too small, but at any rate it would not open any of\nthem.  However, on the second time round, she came upon a low\ncurtain she had not noticed before, and behind it was a little\ndoor about fifteen inches high:  she tried the little golden key\nin the lock, and to her great delight it fitted!\n\n  Alice opened the door and found that it led into a small\npassage, not much larger than a rat-hole:  she knelt down and\nlooked along the passage into the loveliest garden you ever saw.\nHow she longed to get out of that dark hall, and wander about\namong those beds of bright flowers and those cool fountains, but\nshe could not even get her head though the doorway; `and even if\nmy head would go through,' thought poor Alice, `it would be of\nvery little use without my shoulders.  Oh, how I wish\nI could shut up like a telescope!  I think I could, if I only\nknow how to begin.'  For, you see, so many out-of-the-way things\nhad happened lately, that Alice had begun to think that very few\nthings indeed were really impossible.\n\n  There seemed to be no use in waiting by the little door, so she\nwent back to the table, half hoping she might find another key on\nit, or at any rate a book of rules for shutting people up like\ntelescopes:  this time she found a little bottle on it, (`which\ncertainly was not here before,' said Alice,) and round the neck\nof the bottle was a paper label, with the words `DRINK ME'\nbeautifully printed on it in large letters.\n\n  It was all very well to say `Drink me,' but the wise little\nAlice was not going to do THAT in a hurry.  `No, I'll look\nfirst,' she said, `and see whether it's marked \"poison\" or not';\nfor she had read several nice little histories about children who\nhad got burnt, and eaten up by wild beasts and other unpleasant\nthings, all because they WOULD not remember the simple rules\ntheir friends had taught them:  such as, that a red-hot poker\nwill burn you if you hold it too long; and that if you cut your\nfinger VERY deeply with a knife, it usually bleeds; and she had\nnever forgotten that, if you drink much from a bottle marked\n`poison,' it is almost certain to disagree with you, sooner or\nlater.\n\n  However, this bottle was NOT marked `poison,' so Alice ventured\nto taste it, and finding it very nice, (it had, in fact, a sort\nof mixed flavour of cherry-tart, custard, pine-apple, roast\nturkey, toffee, and hot buttered toast,) she very soon finished\nit off.\n\n     *       *       *       *       *       *       *\n\n         *       *       *       *       *       *\n\n     *       *       *       *       *       *       *\n\n  `What a curious feeling!' said Alice; `I must be shutting up\nlike a telescope.'\n\n  And so it was indeed:  she was now only ten inches high, and\nher face brightened up at the thought that she was now the right\nsize for going through the little door into that lovely garden.\nFirst, however, she waited for a few minutes to see if she was\ngoing to shrink any further:  she felt a little nervous about\nthis; `for it might end, you know,' said Alice to herself, `in my\ngoing out altogether, like a candle.  I wonder what I should be\nlike then?'  And she tried to fancy what the flame of a candle is\nlike after the candle is blown out, for she could not remember\never having seen such a thing.\n\n  After a while, finding that nothing more happened, she decided\non going into the garden at once; but, alas for poor Alice!\nwhen she got to the door, she found she had forgotten the\nlittle golden key, and when she went back to the table for it,\nshe found she could not possibly reach it:  she could see it\nquite plainly through the glass, and she tried her best to climb\nup one of the legs of the table, but it was too slippery;\nand when she had tired herself out with trying,\nthe poor little thing sat down and cried.\n\n  `Come, there's no use in crying like that!' said Alice to\nherself, rather sharply; `I advise you to leave off this minute!'\nShe generally gave herself very good advice, (though she very\nseldom followed it), and sometimes she scolded herself so\nseverely as to bring tears into her eyes; and once she remembered\ntrying to box her own ears for having cheated herself in a game\nof croquet she was playing against herself, for this curious\nchild was very fond of pretending to be two people.  `But it's no\nuse now,' thought poor Alice, `to pretend to be two people!  Why,\nthere's hardly enough of me left to make ONE respectable\nperson!'\n\n  Soon her eye fell on a little glass box that was lying under\nthe table:  she opened it, and found in it a very small cake, on\nwhich the words `EAT ME' were beautifully marked in currants.\n`Well, I'll eat it,' said Alice, `and if it makes me grow larger,\nI can reach the key; and if it makes me grow smaller, I can creep\nunder the door; so either way I'll get into the garden, and I\ndon't care which happens!'\n\n  She ate a little bit, and said anxiously to herself, `Which\nway?  Which way?', holding her hand on the top of her head to\nfeel which way it was growing, and she was quite surprised to\nfind that she remained the same size:  to be sure, this generally\nhappens when one eats cake, but Alice had got so much into the\nway of expecting nothing but out-of-the-way things to happen,\nthat it seemed quite dull and stupid for life to go on in the\ncommon way.\n\n  So she set to work, and very soon finished off the cake.\n\n     *       *       *       *       *       *       *\n\n         *       *       *       *       *       *\n\n     *       *       *       *       *       *       *\n\n\n\n\n                           CHAPTER II\n\n                        The Pool of Tears\n\n\n  `Curiouser and curiouser!' cried Alice (she was so much\nsurprised, that for the moment she quite forgot how to speak good\nEnglish); `now I'm opening out like the largest telescope that\never was!  Good-bye, feet!' (for when she looked down at her\nfeet, they seemed to be almost out of sight, they were getting so\nfar off).  `Oh, my poor little feet, I wonder who will put on\nyour shoes and stockings for you now, dears?  I'm sure _I_ shan't\nbe able!  I shall be a great deal too far off to trouble myself\nabout you:  you must manage the best way you can; --but I must be\nkind to them,' thought Alice, `or perhaps they won't walk the\nway I want to go!  Let me see:  I'll give them a new pair of\nboots every Christmas.'\n\n  And she went on planning to herself how she would manage it.\n`They must go by the carrier,' she thought; `and how funny it'll\nseem, sending presents to one's own feet!  And how odd the\ndirections will look!\n\n            ALICE'S RIGHT FOOT, ESQ.\n                HEARTHRUG,\n                    NEAR THE FENDER,\n                        (WITH ALICE'S LOVE).\n\nOh dear, what nonsense I'm talking!'\n\n  Just then her head struck against the roof of the hall:  in\nfact she was now more than nine feet high, and she at once took\nup the little golden key and hurried off to the garden door.\n\n  Poor Alice!  It was as much as she could do, lying down on one\nside, to look through into the garden with one eye; but to get\nthrough was more hopeless than ever:  she sat down and began to\ncry again.\n\n  `You ought to be ashamed of yourself,' said Alice, `a great\ngirl like you,' (she might well say this), `to go on crying in\nthis way!  Stop this moment, I tell you!'  But she went on all\nthe same, shedding gallons of tears, until there was a large pool\nall round her, about four inches deep and reaching half down the\nhall.\n\n  After a time she heard a little pattering of feet in the\ndistance, and she hastily dried her eyes to see what was coming.\nIt was the White Rabbit returning, splendidly dressed, with a\npair of white kid gloves in one hand and a large fan in the\nother:  he came trotting along in a great hurry, muttering to\nhimself as he came, `Oh! the Duchess, the Duchess! Oh! won't she\nbe savage if I've kept her waiting!'  Alice felt so desperate\nthat she was ready to ask help of any one; so, when the Rabbit\ncame near her, she began, in a low, timid voice, `If you please,\nsir--'  The Rabbit started violently, dropped the white kid\ngloves and the fan, and skurried away into the darkness as hard\nas he could go.\n\n  Alice took up the fan and gloves, and, as the hall was very\nhot, she kept fanning herself all the time she went on talking:\n`Dear, dear!  How queer everything is to-day!  And yesterday\nthings went on just as usual.  I wonder if I've been changed in\nthe night?  Let me think:  was I the same when I got up this\nmorning?  I almost think I can remember feeling a little\ndifferent.  But if I'm not the same, the next question is, Who in\nthe world am I?  Ah, THAT'S the great puzzle!'  And she began\nthinking over all the children she knew that were of the same age\nas herself, to see if she could have been changed for any of\nthem.\n\n  `I'm sure I'm not Ada,' she said, `for her hair goes in such\nlong ringlets, and mine doesn't go in ringlets at all; and I'm\nsure I can't be Mabel, for I know all sorts of things, and she,\noh! she knows such a very little!  Besides, SHE'S she, and I'm I,\nand--oh dear, how puzzling it all is!  I'll try if I know all the\nthings I used to know.  Let me see:  four times five is twelve,\nand four times six is thirteen, and four times seven is--oh dear!\nI shall never get to twenty at that rate!  However, the\nMultiplication Table doesn't signify:  let's try Geography.\nLondon is the capital of Paris, and Paris is the capital of Rome,\nand Rome--no, THAT'S all wrong, I'm certain!  I must have been\nchanged for Mabel!  I'll try and say \"How doth the little--\"'\nand she crossed her hands on her lap as if she were saying lessons,\nand began to repeat it, but her voice sounded hoarse and\nstrange, and the words did not come the same as they used to do:--\n\n            `How doth the little crocodile\n              Improve his shining tail,\n            And pour the waters of the Nile\n              On every golden scale!\n\n            `How cheerfully he seems to grin,\n              How neatly spread his claws,\n            And welcome little fishes in\n              With gently smiling jaws!'\n\n  `I'm sure those are not the right words,' said poor Alice, and\nher eyes filled with tears again as she went on, `I must be Mabel\nafter all, and I shall have to go and live in that poky little\nhouse, and have next to no toys to play with, and oh! ever so\nmany lessons to learn!  No, I've made up my mind about it; if I'm\nMabel, I'll stay down here!  It'll be no use their putting their\nheads down and saying \"Come up again, dear!\"  I shall only look\nup and say \"Who am I then?  Tell me that first, and then, if I\nlike being that person, I'll come up:  if not, I'll stay down\nhere till I'm somebody else\"--but, oh dear!' cried Alice, with a\nsudden burst of tears, `I do wish they WOULD put their heads\ndown!  I am so VERY tired of being all alone here!'\n\n  As she said this she looked down at her hands, and was\nsurprised to see that she had put on one of the Rabbit's little\nwhite kid gloves while she was talking.  `How CAN I have done\nthat?' she thought.  `I must be growing small again.'  She got up\nand went to the table to measure herself by it, and found that,\nas nearly as she could guess, she was now about two feet high,\nand was going on shrinking rapidly:  she soon found out that the\ncause of this was the fan she was holding, and she dropped it\nhastily, just in time to avoid shrinking away altogether.\n\n`That WAS a narrow escape!' said Alice, a good deal frightened at\nthe sudden change, but very glad to find herself still in\nexistence; `and now for the garden!' and she ran with all speed\nback to the little door:  but, alas! the little door was shut\nagain, and the little golden key was lying on the glass table as\nbefore, `and things are worse than ever,' thought the poor child,\n`for I never was so small as this before, never!  And I declare\nit's too bad, that it is!'\n\n  As she said these words her foot slipped, and in another\nmoment, splash! she was up to her chin in salt water.  Her first\nidea was that she had somehow fallen into the sea, `and in that\ncase I can go back by railway,' she said to herself.  (Alice had\nbeen to the seaside once in her life, and had come to the general\nconclusion, that wherever you go to on the English coast you find\na number of bathing machines in the sea, some children digging in\nthe sand with wooden spades, then a row of lodging houses, and\nbehind them a railway station.)  However, she soon made out that\nshe was in the pool of tears which she had wept when she was nine\nfeet high.\n\n  `I wish I hadn't cried so much!' said Alice, as she swam about,\ntrying to find her way out.  `I shall be punished for it now, I\nsuppose, by being drowned in my own tears!  That WILL be a queer\nthing, to be sure!  However, everything is queer to-day.'\n\n  Just then she heard something splashing about in the pool a\nlittle way off, and she swam nearer to make out what it was:  at\nfirst she thought it must be a walrus or hippopotamus, but then\nshe remembered how small she was now, and she soon made out that\nit was only a mouse that had slipped in like herself.\n\n  `Would it be of any use, now,' thought Alice, `to speak to this\nmouse?  Everything is so out-of-the-way down here, that I should\nthink very likely it can talk:  at any rate, there's no harm in\ntrying.'  So she began:  `O Mouse, do you know the way out of\nthis pool?  I am very tired of swimming about here, O Mouse!'\n(Alice thought this must be the right way of speaking to a mouse:\nshe had never done such a thing before, but she remembered having\nseen in her brother's Latin Grammar, `A mouse--of a mouse--to a\nmouse--a mouse--O mouse!'  The Mouse looked at her rather\ninquisitively, and seemed to her to wink with one of its little\neyes, but it said nothing.\n\n  `Perhaps it doesn't understand English,' thought Alice; `I\ndaresay it's a French mouse, come over with William the\nConqueror.'  (For, with all her knowledge of history, Alice had\nno very clear notion how long ago anything had happened.)  So she\nbegan again:  `Ou est ma chatte?' which was the first sentence in\nher French lesson-book.  The Mouse gave a sudden leap out of the\nwater, and seemed to quiver all over with fright.  `Oh, I beg\nyour pardon!' cried Alice hastily, afraid that she had hurt the\npoor animal's feelings.  `I quite forgot you didn't like cats.'\n\n  `Not like cats!' cried the Mouse, in a shrill, passionate\nvoice.  `Would YOU like cats if you were me?'\n\n  `Well, perhaps not,' said Alice in a soothing tone:  `don't be\nangry about it.  And yet I wish I could show you our cat Dinah:\nI think you'd take a fancy to cats if you could only see her.\nShe is such a dear quiet thing,' Alice went on, half to herself,\nas she swam lazily about in the pool, `and she sits purring so\nnicely by the fire, licking her paws and washing her face--and\nshe is such a nice soft thing to nurse--and she's such a capital\none for catching mice--oh, I beg your pardon!' cried Alice again,\nfor this time the Mouse was bristling all over, and she felt\ncertain it must be really offended.  `We won't talk about her any\nmore if you'd rather not.'\n\n  `We indeed!' cried the Mouse, who was trembling down to the end\nof his tail.  `As if I would talk on such a subject!  Our family\nalways HATED cats:  nasty, low, vulgar things!  Don't let me hear\nthe name again!'\n\n  `I won't indeed!' said Alice, in a great hurry to change the\nsubject of conversation.  `Are you--are you fond--of--of dogs?'\nThe Mouse did not answer, so Alice went on eagerly:  `There is\nsuch a nice little dog near our house I should like to show you!\nA little bright-eyed terrier, you know, with oh, such long curly\nbrown hair!  And it'll fetch things when you throw them, and\nit'll sit up and beg for its dinner, and all sorts of things--I\ncan't remember half of them--and it belongs to a farmer, you\nknow, and he says it's so useful, it's worth a hundred pounds!\nHe says it kills all the rats and--oh dear!' cried Alice in a\nsorrowful tone, `I'm afraid I've offended it again!'  For the\nMouse was swimming away from her as hard as it could go, and\nmaking quite a commotion in the pool as it went.\n\n  So she called softly after it, `Mouse dear!  Do come back\nagain, and we won't talk about cats or dogs either, if you don't\nlike them!'  When the Mouse heard this, it turned round and swam\nslowly back to her:  its face was quite pale (with passion, Alice\nthought), and it said in a low trembling voice, `Let us get to\nthe shore, and then I'll tell you my history, and you'll\nunderstand why it is I hate cats and dogs.'\n\n  It was high time to go, for the pool was getting quite crowded\nwith the birds and animals that had fallen into it:  there were a\nDuck and a Dodo, a Lory and an Eaglet, and several other curious\ncreatures.  Alice led the way, and the whole party swam to the\nshore.\n\n\n\n                           CHAPTER III\n\n                  A Caucus-Race and a Long Tale\n\n\n  They were indeed a queer-looking party that assembled on the\nbank--the birds with draggled feathers, the animals with their\nfur clinging close to them, and all dripping wet, cross, and\nuncomfortable.\n\n  The first question of course was, how to get dry again:  they\nhad a consultation about this, and after a few minutes it seemed\nquite natural to Alice to find herself talking familiarly with\nthem, as if she had known them all her life.  Indeed, she had\nquite a long argument with the Lory, who at last turned sulky,\nand would only say, `I am older than you, and must know better';\nand this Alice would not allow without knowing how old it was,\nand, as the Lory positively refused to tell its age, there was no\nmore to be said.\n\n  At last the Mouse, who seemed to be a person of authority among\nthem, called out, `Sit down, all of you, and listen to me!  I'LL\nsoon make you dry enough!'  They all sat down at once, in a large\nring, with the Mouse in the middle.  Alice kept her eyes\nanxiously fixed on it, for she felt sure she would catch a bad\ncold if she did not get dry very soon.\n\n  `Ahem!' said the Mouse with an important air, `are you all ready?\nThis is the driest thing I know.  Silence all round, if you please!\n\"William the Conqueror, whose cause was favoured by the pope, was\nsoon submitted to by the English, who wanted leaders, and had been\nof late much accustomed to usurpation and conquest.  Edwin and\nMorcar, the earls of Mercia and Northumbria--\"'\n\n  `Ugh!' said the Lory, with a shiver.\n\n  `I beg your pardon!' said the Mouse, frowning, but very\npolitely:  `Did you speak?'\n\n  `Not I!' said the Lory hastily.\n\n  `I thought you did,' said the Mouse.  `--I proceed.  \"Edwin and\nMorcar, the earls of Mercia and Northumbria, declared for him:\nand even Stigand, the patriotic archbishop of Canterbury, found\nit advisable--\"'\n\n  `Found WHAT?' said the Duck.\n\n  `Found IT,' the Mouse replied rather crossly:  `of course you\nknow what \"it\" means.'\n\n  `I know what \"it\" means well enough, when I find a thing,' said\nthe Duck:  `it's generally a frog or a worm.  The question is,\nwhat did the archbishop find?'\n\n  The Mouse did not notice this question, but hurriedly went on,\n`\"--found it advisable to go with Edgar Atheling to meet William\nand offer him the crown.  William's conduct at first was\nmoderate.  But the insolence of his Normans--\"  How are you\ngetting on now, my dear?' it continued, turning to Alice as it\nspoke.\n\n  `As wet as ever,' said Alice in a melancholy tone:  `it doesn't\nseem to dry me at all.'\n\n  `In that case,' said the Dodo solemnly, rising to its feet, `I\nmove that the meeting adjourn, for the immediate adoption of more\nenergetic remedies--'\n\n  `Speak English!' said the Eaglet.  `I don't know the meaning of\nhalf those long words, and, what's more, I don't believe you do\neither!'  And the Eaglet bent down its head to hide a smile:\nsome of the other birds tittered audibly.\n\n  `What I was going to say,' said the Dodo in an offended tone,\n`was, that the best thing to get us dry would be a Caucus-race.'\n\n  `What IS a Caucus-race?' said Alice; not that she wanted much\nto know, but the Dodo had paused as if it thought that SOMEBODY\nought to speak, and no one else seemed inclined to say anything.\n\n  `Why,' said the Dodo, `the best way to explain it is to do it.'\n(And, as you might like to try the thing yourself, some winter\nday, I will tell you how the Dodo managed it.)\n\n  First it marked out a race-course, in a sort of circle, (`the\nexact shape doesn't matter,' it said,) and then all the party\nwere placed along the course, here and there.  There was no `One,\ntwo, three, and away,' but they began running when they liked,\nand left off when they liked, so that it was not easy to know\nwhen the race was over.  However, when they had been running half\nan hour or so, and were quite dry again, the Dodo suddenly called\nout `The race is over!' and they all crowded round it, panting,\nand asking, `But who has won?'\n\n  This question the Dodo could not answer without a great deal of\nthought, and it sat for a long time with one finger pressed upon\nits forehead (the position in which you usually see Shakespeare,\nin the pictures of him), while the rest waited in silence.  At\nlast the Dodo said, `EVERYBODY has won, and all must have\nprizes.'\n\n  `But who is to give the prizes?' quite a chorus of voices\nasked.\n\n  `Why, SHE, of course,' said the Dodo, pointing to Alice with\none finger; and the whole party at once crowded round her,\ncalling out in a confused way, `Prizes! Prizes!'\n\n  Alice had no idea what to do, and in despair she put her hand\nin her pocket, and pulled out a box of comfits, (luckily the salt\nwater had not got into it), and handed them round as prizes.\nThere was exactly one a-piece all round.\n\n  `But she must have a prize herself, you know,' said the Mouse.\n\n  `Of course,' the Dodo replied very gravely.  `What else have\nyou got in your pocket?' he went on, turning to Alice.\n\n  `Only a thimble,' said Alice sadly.\n\n  `Hand it over here,' said the Dodo.\n\n  Then they all crowded round her once more, while the Dodo\nsolemnly presented the thimble, saying `We beg your acceptance of\nthis elegant thimble'; and, when it had finished this short\nspeech, they all cheered.\n\n  Alice thought the whole thing very absurd, but they all looked\nso grave that she did not dare to laugh; and, as she could not\nthink of anything to say, she simply bowed, and took the thimble,\nlooking as solemn as she could.\n\n  The next thing was to eat the comfits:  this caused some noise\nand confusion, as the large birds complained that they could not\ntaste theirs, and the small ones choked and had to be patted on\nthe back.  However, it was over at last, and they sat down again\nin a ring, and begged the Mouse to tell them something more.\n\n  `You promised to tell me your history, you know,' said Alice,\n`and why it is you hate--C and D,' she added in a whisper, half\nafraid that it would be offended again.\n\n  `Mine is a long and a sad tale!' said the Mouse, turning to\nAlice, and sighing.\n\n  `It IS a long tail, certainly,' said Alice, looking down with\nwonder at the Mouse's tail; `but why do you call it sad?'  And\nshe kept on puzzling about it while the Mouse was speaking, so\nthat her idea of the tale was something like this:--\n\n                    `Fury said to a\n                   mouse, That he\n                 met in the\n               house,\n            \"Let us\n              both go to\n                law:  I will\n                  prosecute\n                    YOU.  --Come,\n                       I'll take no\n                        denial; We\n                     must have a\n                 trial:  For\n              really this\n           morning I've\n          nothing\n         to do.\"\n           Said the\n             mouse to the\n               cur, \"Such\n                 a trial,\n                   dear Sir,\n                         With\n                     no jury\n                  or judge,\n                would be\n              wasting\n             our\n              breath.\"\n               \"I'll be\n                 judge, I'll\n                   be jury,\"\n                         Said\n                    cunning\n                      old Fury:\n                     \"I'll\n                      try the\n                         whole\n                          cause,\n                             and\n                        condemn\n                       you\n                      to\n                       death.\"'\n\n\n  `You are not attending!' said the Mouse to Alice severely.\n`What are you thinking of?'\n\n  `I beg your pardon,' said Alice very humbly:  `you had got to\nthe fifth bend, I think?'\n\n  `I had NOT!' cried the Mouse, sharply and very angrily.\n\n  `A knot!' said Alice, always ready to make herself useful, and\nlooking anxiously about her.  `Oh, do let me help to undo it!'\n\n  `I shall do nothing of the sort,' said the Mouse, getting up\nand walking away.  `You insult me by talking such nonsense!'\n\n  `I didn't mean it!' pleaded poor Alice.  `But you're so easily\noffended, you know!'\n\n  The Mouse only growled in reply.\n\n  `Please come back and finish your story!' Alice called after\nit; and the others all joined in chorus, `Yes, please do!' but\nthe Mouse only shook its head impatiently, and walked a little\nquicker.\n\n  `What a pity it wouldn't stay!' sighed the Lory, as soon as it\nwas quite out of sight; and an old Crab took the opportunity of\nsaying to her daughter `Ah, my dear!  Let this be a lesson to you\nnever to lose YOUR temper!'  `Hold your tongue, Ma!' said the\nyoung Crab, a little snappishly.  `You're enough to try the\npatience of an oyster!'\n\n  `I wish I had our Dinah here, I know I do!' said Alice aloud,\naddressing nobody in particular.  `She'd soon fetch it back!'\n\n  `And who is Dinah, if I might venture to ask the question?'\nsaid the Lory.\n\n  Alice replied eagerly, for she was always ready to talk about\nher pet:  `Dinah's our cat.  And she's such a capital one for\ncatching mice you can't think!  And oh, I wish you could see her\nafter the birds!  Why, she'll eat a little bird as soon as look\nat it!'\n\n  This speech caused a remarkable sensation among the party.\nSome of the birds hurried off at once:  one old Magpie began\nwrapping itself up very carefully, remarking, `I really must be\ngetting home; the night-air doesn't suit my throat!' and a Canary\ncalled out in a trembling voice to its children, `Come away, my\ndears!  It's high time you were all in bed!'  On various pretexts\nthey all moved off, and Alice was soon left alone.\n\n  `I wish I hadn't mentioned Dinah!' she said to herself in a\nmelancholy tone.  `Nobody seems to like her, down here, and I'm\nsure she's the best cat in the world!  Oh, my dear Dinah!  I\nwonder if I shall ever see you any more!'  And here poor Alice\nbegan to cry again, for she felt very lonely and low-spirited.\nIn a little while, however, she again heard a little pattering of\nfootsteps in the distance, and she looked up eagerly, half hoping\nthat the Mouse had changed his mind, and was coming back to\nfinish his story.\n\n\n\n                           CHAPTER IV\n\n                The Rabbit Sends in a Little Bill\n\n\n  It was the White Rabbit, trotting slowly back again, and\nlooking anxiously about as it went, as if it had lost something;\nand she heard it muttering to itself `The Duchess!  The Duchess!\nOh my dear paws!  Oh my fur and whiskers!  She'll get me\nexecuted, as sure as ferrets are ferrets!  Where CAN I have\ndropped them, I wonder?'  Alice guessed in a moment that it was\nlooking for the fan and the pair of white kid gloves, and she\nvery good-naturedly began hunting about for them, but they were\nnowhere to be seen--everything seemed to have changed since her\nswim in the pool, and the great hall, with the glass table and\nthe little door, had vanished completely.\n\n  Very soon the Rabbit noticed Alice, as she went hunting about,\nand called out to her in an angry tone, `Why, Mary Ann, what ARE\nyou doing out here?  Run home this moment, and fetch me a pair of\ngloves and a fan!  Quick, now!'  And Alice was so much frightened\nthat she ran off at once in the direction it pointed to, without\ntrying to explain the mistake it had made.\n\n  `He took me for his housemaid,' she said to herself as she ran.\n`How surprised he'll be when he finds out who I am!  But I'd\nbetter take him his fan and gloves--that is, if I can find them.'\nAs she said this, she came upon a neat little house, on the door\nof which was a bright brass plate with the name `W. RABBIT'\nengraved upon it.  She went in without knocking, and hurried\nupstairs, in great fear lest she should meet the real Mary Ann,\nand be turned out of the house before she had found the fan and\ngloves.\n\n  `How queer it seems,' Alice said to herself, `to be going\nmessages for a rabbit!  I suppose Dinah'll be sending me on\nmessages next!'  And she began fancying the sort of thing that\nwould happen:  `\"Miss Alice!  Come here directly, and get ready\nfor your walk!\" \"Coming in a minute, nurse!  But I've got to see\nthat the mouse doesn't get out.\"  Only I don't think,' Alice went\non, `that they'd let Dinah stop in the house if it began ordering\npeople about like that!'\n\n  By this time she had found her way into a tidy little room with\na table in the window, and on it (as she had hoped) a fan and two\nor three pairs of tiny white kid gloves:  she took up the fan and\na pair of the gloves, and was just going to leave the room, when\nher eye fell upon a little bottle that stood near the looking-\nglass.  There was no label this time with the words `DRINK ME,'\nbut nevertheless she uncorked it and put it to her lips.  `I know\nSOMETHING interesting is sure to happen,' she said to herself,\n`whenever I eat or drink anything; so I'll just see what this\nbottle does.  I do hope it'll make me grow large again, for\nreally I'm quite tired of being such a tiny little thing!'\n\n  It did so indeed, and much sooner than she had expected:\nbefore she had drunk half the bottle, she found her head pressing\nagainst the ceiling, and had to stoop to save her neck from being\nbroken.  She hastily put down the bottle, saying to herself\n`That's quite enough--I hope I shan't grow any more--As it is, I\ncan't get out at the door--I do wish I hadn't drunk quite so\nmuch!'\n\n  Alas! it was too late to wish that!  She went on growing, and\ngrowing, and very soon had to kneel down on the floor:  in\nanother minute there was not even room for this, and she tried\nthe effect of lying down with one elbow against the door, and the\nother arm curled round her head.  Still she went on growing, and,\nas a last resource, she put one arm out of the window, and one\nfoot up the chimney, and said to herself `Now I can do no more,\nwhatever happens.  What WILL become of me?'\n\n  Luckily for Alice, the little magic bottle had now had its full\neffect, and she grew no larger:  still it was very uncomfortable,\nand, as there seemed to be no sort of chance of her ever getting\nout of the room again, no wonder she felt unhappy.\n\n  `It was much pleasanter at home,' thought poor Alice, `when one\nwasn't always growing larger and smaller, and being ordered about\nby mice and rabbits.  I almost wish I hadn't gone down that\nrabbit-hole--and yet--and yet--it's rather curious, you know,\nthis sort of life!  I do wonder what CAN have happened to me!\nWhen I used to read fairy-tales, I fancied that kind of thing\nnever happened, and now here I am in the middle of one!  There\nought to be a book written about me, that there ought!  And when\nI grow up, I'll write one--but I'm grown up now,' she added in a\nsorrowful tone; `at least there's no room to grow up any more\nHERE.'\n\n  `But then,' thought Alice, `shall I NEVER get any older than I\nam now?  That'll be a comfort, one way--never to be an old woman--\nbut then--always to have lessons to learn!  Oh, I shouldn't like THAT!'\n\n  `Oh, you foolish Alice!' she answered herself.  `How can you\nlearn lessons in here?  Why, there's hardly room for YOU, and no\nroom at all for any lesson-books!'\n\n  And so she went on, taking first one side and then the other,\nand making quite a conversation of it altogether; but after a few\nminutes she heard a voice outside, and stopped to listen.\n\n  `Mary Ann!  Mary Ann!' said the voice.  `Fetch me my gloves\nthis moment!'  Then came a little pattering of feet on the\nstairs.  Alice knew it was the Rabbit coming to look for her, and\nshe trembled till she shook the house, quite forgetting that she\nwas now about a thousand times as large as the Rabbit, and had no\nreason to be afraid of it.\n\n  Presently the Rabbit came up to the door, and tried to open it;\nbut, as the door opened inwards, and Alice's elbow was pressed\nhard against it, that attempt proved a failure.  Alice heard it\nsay to itself `Then I'll go round and get in at the window.'\n\n  `THAT you won't' thought Alice, and, after waiting till she\nfancied she heard the Rabbit just under the window, she suddenly\nspread out her hand, and made a snatch in the air.  She did not\nget hold of anything, but she heard a little shriek and a fall,\nand a crash of broken glass, from which she concluded that it was\njust possible it had fallen into a cucumber-frame, or something\nof the sort.\n\n  Next came an angry voice--the Rabbit's--`Pat! Pat!  Where are\nyou?'  And then a voice she had never heard before, `Sure then\nI'm here!  Digging for apples, yer honour!'\n\n  `Digging for apples, indeed!' said the Rabbit angrily.  `Here!\nCome and help me out of THIS!'  (Sounds of more broken glass.)\n\n  `Now tell me, Pat, what's that in the window?'\n\n  `Sure, it's an arm, yer honour!'  (He pronounced it `arrum.')\n\n  `An arm, you goose!   Who ever saw one that size?  Why, it\nfills the whole window!'\n\n  `Sure, it does, yer honour:  but it's an arm for all that.'\n\n  `Well, it's got no business there, at any rate:  go and take it\naway!'\n\n  There was a long silence after this, and Alice could only hear\nwhispers now and then; such as, `Sure, I don't like it, yer\nhonour, at all, at all!'  `Do as I tell you, you coward!' and at\nlast she spread out her hand again, and made another snatch in\nthe air.  This time there were TWO little shrieks, and more\nsounds of broken glass.  `What a number of cucumber-frames there\nmust be!' thought Alice.  `I wonder what they'll do next!  As for\npulling me out of the window, I only wish they COULD!  I'm sure I\ndon't want to stay in here any longer!'\n\n  She waited for some time without hearing anything more:  at\nlast came a rumbling of little cartwheels, and the sound of a\ngood many voices all talking together:  she made out the words:\n`Where's the other ladder?--Why, I hadn't to bring but one;\nBill's got the other--Bill! fetch it here, lad!--Here, put 'em up\nat this corner--No, tie 'em together first--they don't reach half\nhigh enough yet--Oh! they'll do well enough; don't be particular--\nHere, Bill! catch hold of this rope--Will the roof bear?--Mind\nthat loose slate--Oh, it's coming down!  Heads below!' (a loud\ncrash)--`Now, who did that?--It was Bill, I fancy--Who's to go\ndown the chimney?--Nay, I shan't! YOU do it!--That I won't,\nthen!--Bill's to go down--Here, Bill! the master says you're to\ngo down the chimney!'\n\n  `Oh! So Bill's got to come down the chimney, has he?' said\nAlice to herself.  `Shy, they seem to put everything upon Bill!\nI wouldn't be in Bill's place for a good deal:  this fireplace is\nnarrow, to be sure; but I THINK I can kick a little!'\n\n  She drew her foot as far down the chimney as she could, and\nwaited till she heard a little animal (she couldn't guess of what\nsort it was) scratching and scrambling about in the chimney close\nabove her:  then, saying to herself `This is Bill,' she gave one\nsharp kick, and waited to see what would happen next.\n\n  The first thing she heard was a general chorus of `There goes\nBill!' then the Rabbit's voice along--`Catch him, you by the\nhedge!' then silence, and then another confusion of voices--`Hold\nup his head--Brandy now--Don't choke him--How was it, old fellow?\nWhat happened to you?  Tell us all about it!'\n\n  Last came a little feeble, squeaking voice, (`That's Bill,'\nthought Alice,) `Well, I hardly know--No more, thank ye; I'm\nbetter now--but I'm a deal too flustered to tell you--all I know\nis, something comes at me like a Jack-in-the-box, and up I goes\nlike a sky-rocket!'\n\n  `So you did, old fellow!' said the others.\n\n  `We must burn the house down!' said the Rabbit's voice; and\nAlice called out as loud as she could, `If you do.  I'll set\nDinah at you!'\n\n  There was a dead silence instantly, and Alice thought to\nherself, `I wonder what they WILL do next!  If they had any\nsense, they'd take the roof off.'  After a minute or two, they\nbegan moving about again, and Alice heard the Rabbit say, `A\nbarrowful will do, to begin with.'\n\n  `A barrowful of WHAT?' thought Alice; but she had not long to\ndoubt, for the next moment a shower of little pebbles came\nrattling in at the window, and some of them hit her in the face.\n`I'll put a stop to this,' she said to herself, and shouted out,\n`You'd better not do that again!' which produced another dead\nsilence.\n\n  Alice noticed with some surprise that the pebbles were all\nturning into little cakes as they lay on the floor, and a bright\nidea came into her head.  `If I eat one of these cakes,' she\nthought, `it's sure to make SOME change in my size; and as it\ncan't possibly make me larger, it must make me smaller, I\nsuppose.'\n\n  So she swallowed one of the cakes, and was delighted to find\nthat she began shrinking directly.  As soon as she was small\nenough to get through the door, she ran out of the house, and\nfound quite a crowd of little animals and birds waiting outside.\nThe poor little Lizard, Bill, was in the middle, being held up by\ntwo guinea-pigs, who were giving it something out of a bottle.\nThey all made a rush at Alice the moment she appeared; but she\nran off as hard as she could, and soon found herself safe in a\nthick wood.\n\n  `The first thing I've got to do,' said Alice to herself, as she\nwandered about in the wood, `is to grow to my right size again;\nand the second thing is to find my way into that lovely garden.\nI think that will be the best plan.'\n\n  It sounded an excellent plan, no doubt, and very neatly and\nsimply arranged; the only difficulty was, that she had not the\nsmallest idea how to set about it; and while she was peering\nabout anxiously among the trees, a little sharp bark just over\nher head made her look up in a great hurry.\n\n  An enormous puppy was looking down at her with large round\neyes, and feebly stretching out one paw, trying to touch her.\n`Poor little thing!' said Alice, in a coaxing tone, and she tried\nhard to whistle to it; but she was terribly frightened all the\ntime at the thought that it might be hungry, in which case it\nwould be very likely to eat her up in spite of all her coaxing.\n\n  Hardly knowing what she did, she picked up a little bit of\nstick, and held it out to the puppy; whereupon the puppy jumped\ninto the air off all its feet at once, with a yelp of delight,\nand rushed at the stick, and made believe to worry it; then Alice\ndodged behind a great thistle, to keep herself from being run\nover; and the moment she appeared on the other side, the puppy\nmade another rush at the stick, and tumbled head over heels in\nits hurry to get hold of it; then Alice, thinking it was very\nlike having a game of play with a cart-horse, and expecting every\nmoment to be trampled under its feet, ran round the thistle\nagain; then the puppy began a series of short charges at the\nstick, running a very little way forwards each time and a long\nway back, and barking hoarsely all the while, till at last it sat\ndown a good way off, panting, with its tongue hanging out of its\nmouth, and its great eyes half shut.\n\n  This seemed to Alice a good opportunity for making her escape;\nso she set off at once, and ran till she was quite tired and out\nof breath, and till the puppy's bark sounded quite faint in the\ndistance.\n\n  `And yet what a dear little puppy it was!' said Alice, as she\nleant against a buttercup to rest herself, and fanned herself\nwith one of the leaves:  `I should have liked teaching it tricks\nvery much, if--if I'd only been the right size to do it!  Oh\ndear!  I'd nearly forgotten that I've got to grow up again!  Let\nme see--how IS it to be managed?  I suppose I ought to eat or\ndrink something or other; but the great question is, what?'\n\n  The great question certainly was, what?  Alice looked all round\nher at the flowers and the blades of grass, but she did not see\nanything that looked like the right thing to eat or drink under\nthe circumstances.  There was a large mushroom growing near her,\nabout the same height as herself; and when she had looked under\nit, and on both sides of it, and behind it, it occurred to her\nthat she might as well look and see what was on the top of it.\n\n  She stretched herself up on tiptoe, and peeped over the edge of\nthe mushroom, and her eyes immediately met those of a large\ncaterpillar, that was sitting on the top with its arms folded,\nquietly smoking a long hookah, and taking not the smallest notice\nof her or of anything else.\n\n\n\n                            CHAPTER V\n\n                    Advice from a Caterpillar\n\n\n  The Caterpillar and Alice looked at each other for some time in\nsilence:  at last the Caterpillar took the hookah out of its\nmouth, and addressed her in a languid, sleepy voice.\n\n  `Who are YOU?' said the Caterpillar.\n\n  This was not an encouraging opening for a conversation.  Alice\nreplied, rather shyly, `I--I hardly know, sir, just at present--\nat least I know who I WAS when I got up this morning, but I think\nI must have been changed several times since then.'\n\n  `What do you mean by that?' said the Caterpillar sternly.\n`Explain yourself!'\n\n  `I can't explain MYSELF, I'm afraid, sir' said Alice, `because\nI'm not myself, you see.'\n\n  `I don't see,' said the Caterpillar.\n\n  `I'm afraid I can't put it more clearly,' Alice replied very\npolitely, `for I can't understand it myself to begin with; and\nbeing so many different sizes in a day is very confusing.'\n\n  `It isn't,' said the Caterpillar.\n\n  `Well, perhaps you haven't found it so yet,' said Alice; `but\nwhen you have to turn into a chrysalis--you will some day, you\nknow--and then after that into a butterfly, I should think you'll\nfeel it a little queer, won't you?'\n\n  `Not a bit,' said the Caterpillar.\n\n  `Well, perhaps your feelings may be different,' said Alice;\n`all I know is, it would feel very queer to ME.'\n\n  `You!' said the Caterpillar contemptuously.  `Who are YOU?'\n\n  Which brought them back again to the beginning of the\nconversation.  Alice felt a little irritated at the Caterpillar's\nmaking such VERY short remarks, and she drew herself up and said,\nvery gravely, `I think, you ought to tell me who YOU are, first.'\n\n  `Why?' said the Caterpillar.\n\n  Here was another puzzling question; and as Alice could not\nthink of any good reason, and as the Caterpillar seemed to be in\na VERY unpleasant state of mind, she turned away.\n\n  `Come back!' the Caterpillar called after her.  `I've something\nimportant to say!'\n\n  This sounded promising, certainly:  Alice turned and came back\nagain.\n\n  `Keep your temper,' said the Caterpillar.\n\n  `Is that all?' said Alice, swallowing down her anger as well as\nshe could.\n\n  `No,' said the Caterpillar.\n\n  Alice thought she might as well wait, as she had nothing else\nto do, and perhaps after all it might tell her something worth\nhearing.  For some minutes it puffed away without speaking, but\nat last it unfolded its arms, took the hookah out of its mouth\nagain, and said, `So you think you're changed, do you?'\n\n  `I'm afraid I am, sir,' said Alice; `I can't remember things as\nI used--and I don't keep the same size for ten minutes together!'\n\n  `Can't remember WHAT things?' said the Caterpillar.\n\n  `Well, I've tried to say \"HOW DOTH THE LITTLE BUSY BEE,\" but it\nall came different!' Alice replied in a very melancholy voice.\n\n  `Repeat, \"YOU ARE OLD, FATHER WILLIAM,\"' said the Caterpillar.\n\n  Alice folded her hands, and began:--\n\n    `You are old, Father William,' the young man said,\n      `And your hair has become very white;\n    And yet you incessantly stand on your head--\n      Do you think, at your age, it is right?'\n\n    `In my youth,' Father William replied to his son,\n      `I feared it might injure the brain;\n    But, now that I'm perfectly sure I have none,\n      Why, I do it again and again.'\n\n    `You are old,' said the youth, `as I mentioned before,\n      And have grown most uncommonly fat;\n    Yet you turned a back-somersault in at the door--\n      Pray, what is the reason of that?'\n\n    `In my youth,' said the sage, as he shook his grey locks,\n      `I kept all my limbs very supple\n    By the use of this ointment--one shilling the box--\n      Allow me to sell you a couple?'\n\n    `You are old,' said the youth, `and your jaws are too weak\n      For anything tougher than suet;\n    Yet you finished the goose, with the bones and the beak--\n      Pray how did you manage to do it?'\n\n    `In my youth,' said his father, `I took to the law,\n      And argued each case with my wife;\n    And the muscular strength, which it gave to my jaw,\n      Has lasted the rest of my life.'\n\n    `You are old,' said the youth, `one would hardly suppose\n      That your eye was as steady as ever;\n    Yet you balanced an eel on the end of your nose--\n      What made you so awfully clever?'\n\n    `I have answered three questions, and that is enough,'\n      Said his father; `don't give yourself airs!\n    Do you think I can listen all day to such stuff?\n      Be off, or I'll kick you down stairs!'\n\n\n  `That is not said right,' said the Caterpillar.\n\n  `Not QUITE right, I'm afraid,' said Alice, timidly; `some of the\nwords have got altered.'\n\n  `It is wrong from beginning to end,' said the Caterpillar\ndecidedly, and there was silence for some minutes.\n\n  The Caterpillar was the first to speak.\n\n  `What size do you want to be?' it asked.\n\n  `Oh, I'm not particular as to size,' Alice hastily replied;\n`only one doesn't like changing so often, you know.'\n\n  `I DON'T know,' said the Caterpillar.\n\n  Alice said nothing:  she had never been so much contradicted in\nher life before, and she felt that she was losing her temper.\n\n  `Are you content now?' said the Caterpillar.\n\n  `Well, I should like to be a LITTLE larger, sir, if you\nwouldn't mind,' said Alice:  `three inches is such a wretched\nheight to be.'\n\n  `It is a very good height indeed!' said the Caterpillar\nangrily, rearing itself upright as it spoke (it was exactly three\ninches high).\n\n  `But I'm not used to it!' pleaded poor Alice in a piteous tone.\nAnd she thought of herself, `I wish the creatures wouldn't be so\neasily offended!'\n\n  `You'll get used to it in time,' said the Caterpillar; and it\nput the hookah into its mouth and began smoking again.\n\n  This time Alice waited patiently until it chose to speak again.\nIn a minute or two the Caterpillar took the hookah out of its\nmouth and yawned once or twice, and shook itself.  Then it got\ndown off the mushroom, and crawled away in the grass, merely\nremarking as it went, `One side will make you grow taller, and\nthe other side will make you grow shorter.'\n\n  `One side of WHAT?  The other side of WHAT?' thought Alice to\nherself.\n\n  `Of the mushroom,' said the Caterpillar, just as if she had\nasked it aloud; and in another moment it was out of sight.\n\n  Alice remained looking thoughtfully at the mushroom for a\nminute, trying to make out which were the two sides of it; and as\nit was perfectly round, she found this a very difficult question.\nHowever, at last she stretched her arms round it as far as they\nwould go, and broke off a bit of the edge with each hand.\n\n  `And now which is which?' she said to herself, and nibbled a\nlittle of the right-hand bit to try the effect:  the next moment\nshe felt a violent blow underneath her chin:  it had struck her\nfoot!\n\n  She was a good deal frightened by this very sudden change, but\nshe felt that there was no time to be lost, as she was shrinking\nrapidly; so she set to work at once to eat some of the other bit.\nHer chin was pressed so closely against her foot, that there was\nhardly room to open her mouth; but she did it at last, and\nmanaged to swallow a morsel of the lefthand bit.\n\n\n     *       *       *       *       *       *       *\n\n         *       *       *       *       *       *\n\n     *       *       *       *       *       *       *\n\n  `Come, my head's free at last!' said Alice in a tone of\ndelight, which changed into alarm in another moment, when she\nfound that her shoulders were nowhere to be found:  all she could\nsee, when she looked down, was an immense length of neck, which\nseemed to rise like a stalk out of a sea of green leaves that lay\nfar below her.\n\n  `What CAN all that green stuff be?' said Alice.  `And where\nHAVE my shoulders got to?  And oh, my poor hands, how is it I\ncan't see you?'  She was moving them about as she spoke, but no\nresult seemed to follow, except a little shaking among the\ndistant green leaves.\n\n  As there seemed to be no chance of getting her hands up to her\nhead, she tried to get her head down to them, and was delighted\nto find that her neck would bend about easily in any direction,\nlike a serpent.  She had just succeeded in curving it down into a\ngraceful zigzag, and was going to dive in among the leaves, which\nshe found to be nothing but the tops of the trees under which she\nhad been wandering, when a sharp hiss made her draw back in a\nhurry:  a large pigeon had flown into her face, and was beating\nher violently with its wings.\n\n  `Serpent!' screamed the Pigeon.\n\n  `I'm NOT a serpent!' said Alice indignantly.  `Let me alone!'\n\n  `Serpent, I say again!' repeated the Pigeon, but in a more\nsubdued tone, and added with a kind of sob, `I've tried every\nway, and nothing seems to suit them!'\n\n  `I haven't the least idea what you're talking about,' said\nAlice.\n\n  `I've tried the roots of trees, and I've tried banks, and I've\ntried hedges,' the Pigeon went on, without attending to her; `but\nthose serpents!  There's no pleasing them!'\n\n  Alice was more and more puzzled, but she thought there was no\nuse in saying anything more till the Pigeon had finished.\n\n  `As if it wasn't trouble enough hatching the eggs,' said the\nPigeon; `but I must be on the look-out for serpents night and\nday!  Why, I haven't had a wink of sleep these three weeks!'\n\n  `I'm very sorry you've been annoyed,' said Alice, who was\nbeginning to see its meaning.\n\n  `And just as I'd taken the highest tree in the wood,' continued\nthe Pigeon, raising its voice to a shriek, `and just as I was\nthinking I should be free of them at last, they must needs come\nwriggling down from the sky!  Ugh, Serpent!'\n\n  `But I'm NOT a serpent, I tell you!' said Alice.  `I'm a--I'm\na--'\n\n  `Well!  WHAT are you?' said the Pigeon.  `I can see you're\ntrying to invent something!'\n\n  `I--I'm a little girl,' said Alice, rather doubtfully, as she\nremembered the number of changes she had gone through that day.\n\n  `A likely story indeed!' said the Pigeon in a tone of the\ndeepest contempt.  `I've seen a good many little girls in my\ntime, but never ONE with such a neck as that!  No, no!  You're a\nserpent; and there's no use denying it.  I suppose you'll be\ntelling me next that you never tasted an egg!'\n\n  `I HAVE tasted eggs, certainly,' said Alice, who was a very\ntruthful child; `but little girls eat eggs quite as much as\nserpents do, you know.'\n\n  `I don't believe it,' said the Pigeon; `but if they do, why\nthen they're a kind of serpent, that's all I can say.'\n\n  This was such a new idea to Alice, that she was quite silent\nfor a minute or two, which gave the Pigeon the opportunity of\nadding, `You're looking for eggs, I know THAT well enough; and\nwhat does it matter to me whether you're a little girl or a\nserpent?'\n\n  `It matters a good deal to ME,' said Alice hastily; `but I'm\nnot looking for eggs, as it happens; and if I was, I shouldn't\nwant YOURS:  I don't like them raw.'\n\n  `Well, be off, then!' said the Pigeon in a sulky tone, as it\nsettled down again into its nest.  Alice crouched down among the\ntrees as well as she could, for her neck kept getting entangled\namong the branches, and every now and then she had to stop and\nuntwist it.  After a while she remembered that she still held the\npieces of mushroom in her hands, and she set to work very\ncarefully, nibbling first at one and then at the other, and\ngrowing sometimes taller and sometimes shorter, until she had\nsucceeded in bringing herself down to her usual height.\n\n  It was so long since she had been anything near the right size,\nthat it felt quite strange at first; but she got used to it in a\nfew minutes, and began talking to herself, as usual.  `Come,\nthere's half my plan done now!  How puzzling all these changes\nare!  I'm never sure what I'm going to be, from one minute to\nanother!  However, I've got back to my right size:  the next\nthing is, to get into that beautiful garden--how IS that to be\ndone, I wonder?'  As she said this, she came suddenly upon an\nopen place, with a little house in it about four feet high.\n`Whoever lives there,' thought Alice, `it'll never do to come\nupon them THIS size:  why, I should frighten them out of their\nwits!'  So she began nibbling at the righthand bit again, and did\nnot venture to go near the house till she had brought herself\ndown to nine inches high.\n\n\n\n                           CHAPTER VI\n\n                         Pig and Pepper\n\n\n  For a minute or two she stood looking at the house, and\nwondering what to do next, when suddenly a footman in livery came\nrunning out of the wood--(she considered him to be a footman\nbecause he was in livery:  otherwise, judging by his face only,\nshe would have called him a fish)--and rapped loudly at the door\nwith his knuckles.  It was opened by another footman in livery,\nwith a round face, and large eyes like a frog; and both footmen,\nAlice noticed, had powdered hair that curled all over their\nheads.  She felt very curious to know what it was all about, and\ncrept a little way out of the wood to listen.\n\n  The Fish-Footman began by producing from under his arm a great\nletter, nearly as large as himself, and this he handed over to\nthe other, saying, in a solemn tone, `For the Duchess.  An\ninvitation from the Queen to play croquet.'  The Frog-Footman\nrepeated, in the same solemn tone, only changing the order of the\nwords a little, `From the Queen.  An invitation for the Duchess\nto play croquet.'\n\n  Then they both bowed low, and their curls got entangled\ntogether.\n\n  Alice laughed so much at this, that she had to run back into\nthe wood for fear of their hearing her; and when she next peeped\nout the Fish-Footman was gone, and the other was sitting on the\nground near the door, staring stupidly up into the sky.\n\n  Alice went timidly up to the door, and knocked.\n\n  `There's no sort of use in knocking,' said the Footman, `and\nthat for two reasons.  First, because I'm on the same side of the\ndoor as you are; secondly, because they're making such a noise\ninside, no one could possibly hear you.'  And certainly there was\na most extraordinary noise going on within--a constant howling\nand sneezing, and every now and then a great crash, as if a dish\nor kettle had been broken to pieces.\n\n  `Please, then,' said Alice, `how am I to get in?'\n\n  `There might be some sense in your knocking,' the Footman went\non without attending to her, `if we had the door between us.  For\ninstance, if you were INSIDE, you might knock, and I could let\nyou out, you know.'  He was looking up into the sky all the time\nhe was speaking, and this Alice thought decidedly uncivil.  `But\nperhaps he can't help it,' she said to herself; `his eyes are so\nVERY nearly at the top of his head.  But at any rate he might\nanswer questions.--How am I to get in?' she repeated, aloud.\n\n  `I shall sit here,' the Footman remarked, `till tomorrow--'\n\n  At this moment the door of the house opened, and a large plate\ncame skimming out, straight at the Footman's head:  it just\ngrazed his nose, and broke to pieces against one of the trees\nbehind him.\n\n  `--or next day, maybe,' the Footman continued in the same tone,\nexactly as if nothing had happened.\n\n  `How am I to get in?' asked Alice again, in a louder tone.\n\n  `ARE you to get in at all?' said the Footman.  `That's the\nfirst question, you know.'\n\n  It was, no doubt:  only Alice did not like to be told so.\n`It's really dreadful,' she muttered to herself, `the way all the\ncreatures argue.  It's enough to drive one crazy!'\n\n  The Footman seemed to think this a good opportunity for\nrepeating his remark, with variations.  `I shall sit here,' he\nsaid, `on and off, for days and days.'\n\n  `But what am I to do?' said Alice.\n\n  `Anything you like,' said the Footman, and began whistling.\n\n  `Oh, there's no use in talking to him,' said Alice desperately:\n`he's perfectly idiotic!'  And she opened the door and went in.\n\n  The door led right into a large kitchen, which was full of\nsmoke from one end to the other:  the Duchess was sitting on a\nthree-legged stool in the middle, nursing a baby; the cook was\nleaning over the fire, stirring a large cauldron which seemed to\nbe full of soup.\n\n  `There's certainly too much pepper in that soup!' Alice said to\nherself, as well as she could for sneezing.\n\n  There was certainly too much of it in the air.  Even the\nDuchess sneezed occasionally; and as for the baby, it was\nsneezing and howling alternately without a moment's pause.  The\nonly things in the kitchen that did not sneeze, were the cook,\nand a large cat which was sitting on the hearth and grinning from\near to ear.\n\n  `Please would you tell me,' said Alice, a little timidly, for\nshe was not quite sure whether it was good manners for her to\nspeak first, `why your cat grins like that?'\n\n  `It's a Cheshire cat,' said the Duchess, `and that's why.  Pig!'\n\n  She said the last word with such sudden violence that Alice\nquite jumped; but she saw in another moment that it was addressed\nto the baby, and not to her, so she took courage, and went on\nagain:--\n\n  `I didn't know that Cheshire cats always grinned; in fact, I\ndidn't know that cats COULD grin.'\n\n  `They all can,' said the Duchess; `and most of 'em do.'\n\n  `I don't know of any that do,' Alice said very politely,\nfeeling quite pleased to have got into a conversation.\n\n  `You don't know much,' said the Duchess; `and that's a fact.'\n\n  Alice did not at all like the tone of this remark, and thought\nit would be as well to introduce some other subject of\nconversation.  While she was trying to fix on one, the cook took\nthe cauldron of soup off the fire, and at once set to work\nthrowing everything within her reach at the Duchess and the baby\n--the fire-irons came first; then followed a shower of saucepans,\nplates, and dishes.  The Duchess took no notice of them even when\nthey hit her; and the baby was howling so much already, that it\nwas quite impossible to say whether the blows hurt it or not.\n\n  `Oh, PLEASE mind what you're doing!' cried Alice, jumping up\nand down in an agony of terror.  `Oh, there goes his PRECIOUS\nnose'; as an unusually large saucepan flew close by it, and very\nnearly carried it off.\n\n  `If everybody minded their own business,' the Duchess said in a\nhoarse growl, `the world would go round a deal faster than it\ndoes.'\n\n  `Which would NOT be an advantage,' said Alice, who felt very\nglad to get an opportunity of showing off a little of her\nknowledge.  `Just think of what work it would make with the day\nand night!  You see the earth takes twenty-four hours to turn\nround on its axis--'\n\n  `Talking of axes,' said the Duchess, `chop off her head!'\n\n  Alice glanced rather anxiously at the cook, to see if she meant\nto take the hint; but the cook was busily stirring the soup, and\nseemed not to be listening, so she went on again:  `Twenty-four\nhours, I THINK; or is it twelve?  I--'\n\n  `Oh, don't bother ME,' said the Duchess; `I never could abide\nfigures!'  And with that she began nursing her child again,\nsinging a sort of lullaby to it as she did so, and giving it a\nviolent shake at the end of every line:\n\n        `Speak roughly to your little boy,\n          And beat him when he sneezes:\n        He only does it to annoy,\n          Because he knows it teases.'\n\n                    CHORUS.\n\n    (In which the cook and the baby joined):--\n\n                `Wow! wow! wow!'\n\n  While the Duchess sang the second verse of the song, she kept\ntossing the baby violently up and down, and the poor little thing\nhowled so, that Alice could hardly hear the words:--\n\n        `I speak severely to my boy,\n          I beat him when he sneezes;\n        For he can thoroughly enjoy\n          The pepper when he pleases!'\n\n                    CHORUS.\n\n                `Wow! wow! wow!'\n\n  `Here! you may nurse it a bit, if you like!' the Duchess said\nto Alice, flinging the baby at her as she spoke.  `I must go and\nget ready to play croquet with the Queen,' and she hurried out of\nthe room.  The cook threw a frying-pan after her as she went out,\nbut it just missed her.\n\n  Alice caught the baby with some difficulty, as it was a queer-\nshaped little creature, and held out its arms and legs in all\ndirections, `just like a star-fish,' thought Alice.  The poor\nlittle thing was snorting like a steam-engine when she caught it,\nand kept doubling itself up and straightening itself out again,\nso that altogether, for the first minute or two, it was as much\nas she could do to hold it.\n\n  As soon as she had made out the proper way of nursing it,\n(which was to twist it up into a sort of knot, and then keep\ntight hold of its right ear and left foot, so as to prevent its\nundoing itself,) she carried it out into the open air.  `IF I\ndon't take this child away with me,' thought Alice, `they're sure\nto kill it in a day or two:  wouldn't it be murder to leave it\nbehind?'  She said the last words out loud, and the little thing\ngrunted in reply (it had left off sneezing by this time).  `Don't\ngrunt,' said Alice; `that's not at all a proper way of expressing\nyourself.'\n\n  The baby grunted again, and Alice looked very anxiously into\nits face to see what was the matter with it.  There could be no\ndoubt that it had a VERY turn-up nose, much more like a snout\nthan a real nose; also its eyes were getting extremely small for\na baby:  altogether Alice did not like the look of the thing at\nall.  `But perhaps it was only sobbing,' she thought, and looked\ninto its eyes again, to see if there were any tears.\n\n  No, there were no tears.  `If you're going to turn into a pig,\nmy dear,' said Alice, seriously, `I'll have nothing more to do\nwith you.  Mind now!'  The poor little thing sobbed again (or\ngrunted, it was impossible to say which), and they went on for\nsome while in silence.\n\n  Alice was just beginning to think to herself, `Now, what am I\nto do with this creature when I get it home?' when it grunted\nagain, so violently, that she looked down into its face in some\nalarm.  This time there could be NO mistake about it:  it was\nneither more nor less than a pig, and she felt that it would be\nquite absurd for her to carry it further.\n\n  So she set the little creature down, and felt quite relieved to\nsee it trot away quietly into the wood.  `If it had grown up,'\nshe said to herself, `it would have made a dreadfully ugly child:\nbut it makes rather a handsome pig, I think.'  And she began\nthinking over other children she knew, who might do very well as\npigs, and was just saying to herself, `if one only knew the right\nway to change them--' when she was a little startled by seeing\nthe Cheshire Cat sitting on a bough of a tree a few yards off.\n\n  The Cat only grinned when it saw Alice.  It looked good-\nnatured, she thought:  still it had VERY long claws and a great\nmany teeth, so she felt that it ought to be treated with respect.\n\n  `Cheshire Puss,' she began, rather timidly, as she did not at\nall know whether it would like the name:  however, it only\ngrinned a little wider.  `Come, it's pleased so far,' thought\nAlice, and she went on.  `Would you tell me, please, which way I\nought to go from here?'\n\n  `That depends a good deal on where you want to get to,' said\nthe Cat.\n\n  `I don't much care where--' said Alice.\n\n  `Then it doesn't matter which way you go,' said the Cat.\n\n  `--so long as I get SOMEWHERE,' Alice added as an explanation.\n\n  `Oh, you're sure to do that,' said the Cat, `if you only walk\nlong enough.'\n\n  Alice felt that this could not be denied, so she tried another\nquestion.  `What sort of people live about here?'\n\n  `In THAT direction,' the Cat said, waving its right paw round,\n`lives a Hatter:  and in THAT direction,' waving the other paw,\n`lives a March Hare.  Visit either you like:  they're both mad.'\n\n  `But I don't want to go among mad people,' Alice remarked.\n\n  `Oh, you can't help that,' said the Cat:  `we're all mad here.\nI'm mad.  You're mad.'\n\n  `How do you know I'm mad?' said Alice.\n\n  `You must be,' said the Cat, `or you wouldn't have come here.'\n\n  Alice didn't think that proved it at all; however, she went on\n`And how do you know that you're mad?'\n\n  `To begin with,' said the Cat, `a dog's not mad.  You grant\nthat?'\n\n  `I suppose so,' said Alice.\n\n  `Well, then,' the Cat went on, `you see, a dog growls when it's\nangry, and wags its tail when it's pleased.  Now I growl when I'm\npleased, and wag my tail when I'm angry.  Therefore I'm mad.'\n\n  `I call it purring, not growling,' said Alice.\n\n  `Call it what you like,' said the Cat.  `Do you play croquet\nwith the Queen to-day?'\n\n  `I should like it very much,' said Alice, `but I haven't been\ninvited yet.'\n\n  `You'll see me there,' said the Cat, and vanished.\n\n  Alice was not much surprised at this, she was getting so used\nto queer things happening.  While she was looking at the place\nwhere it had been, it suddenly appeared again.\n\n  `By-the-bye, what became of the baby?' said the Cat.  `I'd\nnearly forgotten to ask.'\n\n  `It turned into a pig,' Alice quietly said, just as if it had\ncome back in a natural way.\n\n  `I thought it would,' said the Cat, and vanished again.\n\n  Alice waited a little, half expecting to see it again, but it\ndid not appear, and after a minute or two she walked on in the\ndirection in which the March Hare was said to live.  `I've seen\nhatters before,' she said to herself; `the March Hare will be\nmuch the most interesting, and perhaps as this is May it won't be\nraving mad--at least not so mad as it was in March.'  As she said\nthis, she looked up, and there was the Cat again, sitting on a\nbranch of a tree.\n\n  `Did you say pig, or fig?' said the Cat.\n\n  `I said pig,' replied Alice; `and I wish you wouldn't keep\nappearing and vanishing so suddenly:  you make one quite giddy.'\n\n  `All right,' said the Cat; and this time it vanished quite slowly,\nbeginning with the end of the tail, and ending with the grin,\nwhich remained some time after the rest of it had gone.\n\n  `Well!  I've often seen a cat without a grin,' thought Alice;\n`but a grin without a cat!  It's the most curious thing I ever\nsaw in my life!'\n\n  She had not gone much farther before she came in sight of the\nhouse of the March Hare:  she thought it must be the right house,\nbecause the chimneys were shaped like ears and the roof was\nthatched with fur.  It was so large a house, that she did not\nlike to go nearer till she had nibbled some more of the lefthand\nbit of mushroom, and raised herself to about two feet high:  even\nthen she walked up towards it rather timidly, saying to herself\n`Suppose it should be raving mad after all!  I almost wish I'd\ngone to see the Hatter instead!'\n\n\n\n                           CHAPTER VII\n\n                         A Mad Tea-Party\n\n\n  There was a table set out under a tree in front of the house,\nand the March Hare and the Hatter were having tea at it:  a\nDormouse was sitting between them, fast asleep, and the other two\nwere using it as a cushion, resting their elbows on it, and talking\nover its head.  `Very uncomfortable for the Dormouse,' thought Alice;\n`only, as it's asleep, I suppose it doesn't mind.'\n\n  The table was a large one, but the three were all crowded\ntogether at one corner of it:  `No room!  No room!' they cried\nout when they saw Alice coming.  `There's PLENTY of room!' said\nAlice indignantly, and she sat down in a large arm-chair at one\nend of the table.\n\n  `Have some wine,' the March Hare said in an encouraging tone.\n\n  Alice looked all round the table, but there was nothing on it\nbut tea.  `I don't see any wine,' she remarked.\n\n  `There isn't any,' said the March Hare.\n\n  `Then it wasn't very civil of you to offer it,' said Alice\nangrily.\n\n  `It wasn't very civil of you to sit down without being\ninvited,' said the March Hare.\n\n  `I didn't know it was YOUR table,' said Alice; `it's laid for a\ngreat many more than three.'\n\n  `Your hair wants cutting,' said the Hatter.  He had been\nlooking at Alice for some time with great curiosity, and this was\nhis first speech.\n\n  `You should learn not to make personal remarks,' Alice said\nwith some severity; `it's very rude.'\n\n  The Hatter opened his eyes very wide on hearing this; but all\nhe SAID was, `Why is a raven like a writing-desk?'\n\n  `Come, we shall have some fun now!' thought Alice.  `I'm glad\nthey've begun asking riddles.--I believe I can guess that,' she\nadded aloud.\n\n  `Do you mean that you think you can find out the answer to it?'\nsaid the March Hare.\n\n  `Exactly so,' said Alice.\n\n  `Then you should say what you mean,' the March Hare went on.\n\n  `I do,' Alice hastily replied; `at least--at least I mean what\nI say--that's the same thing, you know.'\n\n  `Not the same thing a bit!' said the Hatter.  `You might just\nas well say that \"I see what I eat\" is the same thing as \"I eat\nwhat I see\"!'\n\n  `You might just as well say,' added the March Hare, `that \"I\nlike what I get\" is the same thing as \"I get what I like\"!'\n\n  `You might just as well say,' added the Dormouse, who seemed to\nbe talking in his sleep, `that \"I breathe when I sleep\" is the\nsame thing as \"I sleep when I breathe\"!'\n\n  `It IS the same thing with you,' said the Hatter, and here the\nconversation dropped, and the party sat silent for a minute,\nwhile Alice thought over all she could remember about ravens and\nwriting-desks, which wasn't much.\n\n  The Hatter was the first to break the silence.  `What day of\nthe month is it?' he said, turning to Alice:  he had taken his\nwatch out of his pocket, and was looking at it uneasily, shaking\nit every now and then, and holding it to his ear.\n\n  Alice considered a little, and then said `The fourth.'\n\n  `Two days wrong!' sighed the Hatter.  `I told you butter\nwouldn't suit the works!' he added looking angrily at the March\nHare.\n\n  `It was the BEST butter,' the March Hare meekly replied.\n\n  `Yes, but some crumbs must have got in as well,' the Hatter\ngrumbled:  `you shouldn't have put it in with the bread-knife.'\n\n  The March Hare took the watch and looked at it gloomily:  then\nhe dipped it into his cup of tea, and looked at it again:  but he\ncould think of nothing better to say than his first remark, `It\nwas the BEST butter, you know.'\n\n  Alice had been looking over his shoulder with some curiosity.\n`What a funny watch!' she remarked.  `It tells the day of the\nmonth, and doesn't tell what o'clock it is!'\n\n  `Why should it?' muttered the Hatter.  `Does YOUR watch tell\nyou what year it is?'\n\n  `Of course not,' Alice replied very readily:  `but that's\nbecause it stays the same year for such a long time together.'\n\n  `Which is just the case with MINE,' said the Hatter.\n\n  Alice felt dreadfully puzzled.  The Hatter's remark seemed to\nhave no sort of meaning in it, and yet it was certainly English.\n`I don't quite understand you,' she said, as politely as she\ncould.\n\n  `The Dormouse is asleep again,' said the Hatter, and he poured\na little hot tea upon its nose.\n\n  The Dormouse shook its head impatiently, and said, without\nopening its eyes, `Of course, of course; just what I was going to\nremark myself.'\n\n  `Have you guessed the riddle yet?' the Hatter said, turning to\nAlice again.\n\n  `No, I give it up,' Alice replied:  `what's the answer?'\n\n  `I haven't the slightest idea,' said the Hatter.\n\n  `Nor I,' said the March Hare.\n\n  Alice sighed wearily.  `I think you might do something better\nwith the time,' she said, `than waste it in asking riddles that\nhave no answers.'\n\n  `If you knew Time as well as I do,' said the Hatter, `you\nwouldn't talk about wasting IT.  It's HIM.'\n\n  `I don't know what you mean,' said Alice.\n\n  `Of course you don't!' the Hatter said, tossing his head\ncontemptuously.  `I dare say you never even spoke to Time!'\n\n  `Perhaps not,' Alice cautiously replied:  `but I know I have to\nbeat time when I learn music.'\n\n  `Ah! that accounts for it,' said the Hatter.  `He won't stand\nbeating.  Now, if you only kept on good terms with him, he'd do\nalmost anything you liked with the clock.  For instance, suppose\nit were nine o'clock in the morning, just time to begin lessons:\nyou'd only have to whisper a hint to Time, and round goes the\nclock in a twinkling!  Half-past one, time for dinner!'\n\n  (`I only wish it was,' the March Hare said to itself in a\nwhisper.)\n\n  `That would be grand, certainly,' said Alice thoughtfully:\n`but then--I shouldn't be hungry for it, you know.'\n\n  `Not at first, perhaps,' said the Hatter:  `but you could keep\nit to half-past one as long as you liked.'\n\n  `Is that the way YOU manage?' Alice asked.\n\n  The Hatter shook his head mournfully.  `Not I!' he replied.\n`We quarrelled last March--just before HE went mad, you know--'\n(pointing with his tea spoon at the March Hare,) `--it was at the\ngreat concert given by the Queen of Hearts, and I had to sing\n\n            \"Twinkle, twinkle, little bat!\n            How I wonder what you're at!\"\n\nYou know the song, perhaps?'\n\n  `I've heard something like it,' said Alice.\n\n  `It goes on, you know,' the Hatter continued, `in this way:--\n\n            \"Up above the world you fly,\n            Like a tea-tray in the sky.\n                    Twinkle, twinkle--\"'\n\nHere the Dormouse shook itself, and began singing in its sleep\n`Twinkle, twinkle, twinkle, twinkle--' and went on so long that\nthey had to pinch it to make it stop.\n\n  `Well, I'd hardly finished the first verse,' said the Hatter,\n`when the Queen jumped up and bawled out, \"He's murdering the\ntime!  Off with his head!\"'\n\n  `How dreadfully savage!' exclaimed Alice.\n\n  `And ever since that,' the Hatter went on in a mournful tone,\n`he won't do a thing I ask!  It's always six o'clock now.'\n\n  A bright idea came into Alice's head.  `Is that the reason so\nmany tea-things are put out here?' she asked.\n\n  `Yes, that's it,' said the Hatter with a sigh:  `it's always\ntea-time, and we've no time to wash the things between whiles.'\n\n  `Then you keep moving round, I suppose?' said Alice.\n\n  `Exactly so,' said the Hatter:  `as the things get used up.'\n\n  `But what happens when you come to the beginning again?' Alice\nventured to ask.\n\n  `Suppose we change the subject,' the March Hare interrupted,\nyawning.  `I'm getting tired of this.  I vote the young lady\ntells us a story.'\n\n  `I'm afraid I don't know one,' said Alice, rather alarmed at\nthe proposal.\n\n  `Then the Dormouse shall!' they both cried.  `Wake up,\nDormouse!'  And they pinched it on both sides at once.\n\n  The Dormouse slowly opened his eyes.  `I wasn't asleep,' he\nsaid in a hoarse, feeble voice:  `I heard every word you fellows\nwere saying.'\n\n  `Tell us a story!' said the March Hare.\n\n  `Yes, please do!' pleaded Alice.\n\n  `And be quick about it,' added the Hatter, `or you'll be asleep\nagain before it's done.'\n\n  `Once upon a time there were three little sisters,' the\nDormouse began in a great hurry; `and their names were Elsie,\nLacie, and Tillie; and they lived at the bottom of a well--'\n\n  `What did they live on?' said Alice, who always took a great\ninterest in questions of eating and drinking.\n\n  `They lived on treacle,' said the Dormouse, after thinking a\nminute or two.\n\n  `They couldn't have done that, you know,' Alice gently\nremarked; `they'd have been ill.'\n\n  `So they were,' said the Dormouse; `VERY ill.'\n\n  Alice tried to fancy to herself what such an extraordinary ways\nof living would be like, but it puzzled her too much, so she went\non:  `But why did they live at the bottom of a well?'\n\n  `Take some more tea,' the March Hare said to Alice, very\nearnestly.\n\n  `I've had nothing yet,' Alice replied in an offended tone, `so\nI can't take more.'\n\n  `You mean you can't take LESS,' said the Hatter:  `it's very\neasy to take MORE than nothing.'\n\n  `Nobody asked YOUR opinion,' said Alice.\n\n  `Who's making personal remarks now?' the Hatter asked\ntriumphantly.\n\n  Alice did not quite know what to say to this:  so she helped\nherself to some tea and bread-and-butter, and then turned to the\nDormouse, and repeated her question.  `Why did they live at the\nbottom of a well?'\n\n  The Dormouse again took a minute or two to think about it, and\nthen said, `It was a treacle-well.'\n\n  `There's no such thing!'  Alice was beginning very angrily, but\nthe Hatter and the March Hare went `Sh! sh!' and the Dormouse\nsulkily remarked, `If you can't be civil, you'd better finish the\nstory for yourself.'\n\n  `No, please go on!' Alice said very humbly; `I won't interrupt\nagain.  I dare say there may be ONE.'\n\n  `One, indeed!' said the Dormouse indignantly.  However, he\nconsented to go on.  `And so these three little sisters--they\nwere learning to draw, you know--'\n\n  `What did they draw?' said Alice, quite forgetting her promise.\n\n  `Treacle,' said the Dormouse, without considering at all this\ntime.\n\n  `I want a clean cup,' interrupted the Hatter:  `let's all move\none place on.'\n\n  He moved on as he spoke, and the Dormouse followed him:  the\nMarch Hare moved into the Dormouse's place, and Alice rather\nunwillingly took the place of the March Hare.  The Hatter was the\nonly one who got any advantage from the change:  and Alice was a\ngood deal worse off than before, as the March Hare had just upset\nthe milk-jug into his plate.\n\n  Alice did not wish to offend the Dormouse again, so she began\nvery cautiously:  `But I don't understand.  Where did they draw\nthe treacle from?'\n\n  `You can draw water out of a water-well,' said the Hatter; `so\nI should think you could draw treacle out of a treacle-well--eh,\nstupid?'\n\n  `But they were IN the well,' Alice said to the Dormouse, not\nchoosing to notice this last remark.\n\n  `Of course they were', said the Dormouse; `--well in.'\n\n  This answer so confused poor Alice, that she let the Dormouse\ngo on for some time without interrupting it.\n\n  `They were learning to draw,' the Dormouse went on, yawning and\nrubbing its eyes, for it was getting very sleepy; `and they drew\nall manner of things--everything that begins with an M--'\n\n  `Why with an M?' said Alice.\n\n  `Why not?' said the March Hare.\n\n  Alice was silent.\n\n  The Dormouse had closed its eyes by this time, and was going\noff into a doze; but, on being pinched by the Hatter, it woke up\nagain with a little shriek, and went on:  `--that begins with an\nM, such as mouse-traps, and the moon, and memory, and muchness--\nyou know you say things are \"much of a muchness\"--did you ever\nsee such a thing as a drawing of a muchness?'\n\n  `Really, now you ask me,' said Alice, very much confused, `I\ndon't think--'\n\n  `Then you shouldn't talk,' said the Hatter.\n\n  This piece of rudeness was more than Alice could bear:  she got\nup in great disgust, and walked off; the Dormouse fell asleep\ninstantly, and neither of the others took the least notice of her\ngoing, though she looked back once or twice, half hoping that\nthey would call after her:  the last time she saw them, they were\ntrying to put the Dormouse into the teapot.\n\n  `At any rate I'll never go THERE again!' said Alice as she\npicked her way through the wood.  `It's the stupidest tea-party I\never was at in all my life!'\n\n  Just as she said this, she noticed that one of the trees had a\ndoor leading right into it.  `That's very curious!' she thought.\n`But everything's curious today.  I think I may as well go in at once.'\nAnd in she went.\n\n  Once more she found herself in the long hall, and close to the\nlittle glass table.  `Now, I'll manage better this time,'\nshe said to herself, and began by taking the little golden key,\nand unlocking the door that led into the garden.  Then she went\nto work nibbling at the mushroom (she had kept a piece of it\nin her pocket) till she was about a foot high:  then she walked down\nthe little passage:  and THEN--she found herself at last in the\nbeautiful garden, among the bright flower-beds and the cool fountains.\n\n\n\n                          CHAPTER VIII\n\n                   The Queen's Croquet-Ground\n\n\n  A large rose-tree stood near the entrance of the garden:  the\nroses growing on it were white, but there were three gardeners at\nit, busily painting them red.  Alice thought this a very curious\nthing, and she went nearer to watch them, and just as she came up\nto them she heard one of them say, `Look out now, Five!  Don't go\nsplashing paint over me like that!'\n\n  `I couldn't help it,' said Five, in a sulky tone; `Seven jogged\nmy elbow.'\n\n  On which Seven looked up and said, `That's right, Five!  Always\nlay the blame on others!'\n\n  `YOU'D better not talk!' said Five.  `I heard the Queen say only\nyesterday you deserved to be beheaded!'\n\n  `What for?' said the one who had spoken first.\n\n  `That's none of YOUR business, Two!' said Seven.\n\n  `Yes, it IS his business!' said Five, `and I'll tell him--it\nwas for bringing the cook tulip-roots instead of onions.'\n\n  Seven flung down his brush, and had just begun `Well, of all\nthe unjust things--' when his eye chanced to fall upon Alice, as\nshe stood watching them, and he checked himself suddenly:  the\nothers looked round also, and all of them bowed low.\n\n  `Would you tell me,' said Alice, a little timidly, `why you are\npainting those roses?'\n\n  Five and Seven said nothing, but looked at Two.  Two began in a\nlow voice, `Why the fact is, you see, Miss, this here ought to\nhave been a RED rose-tree, and we put a white one in by mistake;\nand if the Queen was to find it out, we should all have our heads\ncut off, you know.  So you see, Miss, we're doing our best, afore\nshe comes, to--'  At this moment Five, who had been anxiously\nlooking across the garden, called out `The Queen!  The Queen!'\nand the three gardeners instantly threw themselves flat upon\ntheir faces.  There was a sound of many footsteps, and Alice\nlooked round, eager to see the Queen.\n\n  First came ten soldiers carrying clubs; these were all shaped\nlike the three gardeners, oblong and flat, with their hands and\nfeet at the corners:  next the ten courtiers; these were\nornamented all over with diamonds, and walked two and two, as the\nsoldiers did.  After these came the royal children; there were\nten of them, and the little dears came jumping merrily along hand\nin hand, in couples:  they were all ornamented with hearts.  Next\ncame the guests, mostly Kings and Queens, and among them Alice\nrecognised the White Rabbit:  it was talking in a hurried nervous\nmanner, smiling at everything that was said, and went by without\nnoticing her.  Then followed the Knave of Hearts, carrying the\nKing's crown on a crimson velvet cushion; and, last of all this\ngrand procession, came THE KING AND QUEEN OF HEARTS.\n\n  Alice was rather doubtful whether she ought not to lie down on\nher face like the three gardeners, but she could not remember\never having heard of such a rule at processions; `and besides,\nwhat would be the use of a procession,' thought she, `if people\nhad all to lie down upon their faces, so that they couldn't see it?'\nSo she stood still where she was, and waited.\n\n  When the procession came opposite to Alice, they all stopped\nand looked at her, and the Queen said severely `Who is this?'\nShe said it to the Knave of Hearts, who only bowed and smiled in reply.\n\n  `Idiot!' said the Queen, tossing her head impatiently; and,\nturning to Alice, she went on, `What's your name, child?'\n\n  `My name is Alice, so please your Majesty,' said Alice very\npolitely; but she added, to herself, `Why, they're only a pack of\ncards, after all.  I needn't be afraid of them!'\n\n  `And who are THESE?' said the Queen, pointing to the three\ngardeners who were lying round the rosetree; for, you see, as\nthey were lying on their faces, and the pattern on their backs\nwas the same as the rest of the pack, she could not tell whether\nthey were gardeners, or soldiers, or courtiers, or three of her\nown children.\n\n  `How should I know?' said Alice, surprised at her own courage.\n`It's no business of MINE.'\n\n  The Queen turned crimson with fury, and, after glaring at her\nfor a moment like a wild beast, screamed `Off with her head!\nOff--'\n\n  `Nonsense!' said Alice, very loudly and decidedly, and the\nQueen was silent.\n\n  The King laid his hand upon her arm, and timidly said\n`Consider, my dear:  she is only a child!'\n\n  The Queen turned angrily away from him, and said to the Knave\n`Turn them over!'\n\n  The Knave did so, very carefully, with one foot.\n\n  `Get up!' said the Queen, in a shrill, loud voice, and the\nthree gardeners instantly jumped up, and began bowing to the\nKing, the Queen, the royal children, and everybody else.\n\n  `Leave off that!' screamed the Queen.  `You make me giddy.'\nAnd then, turning to the rose-tree, she went on, `What HAVE you\nbeen doing here?'\n\n  `May it please your Majesty,' said Two, in a very humble tone,\ngoing down on one knee as he spoke, `we were trying--'\n\n  `I see!' said the Queen, who had meanwhile been examining the\nroses.  `Off with their heads!' and the procession moved on,\nthree of the soldiers remaining behind to execute the unfortunate\ngardeners, who ran to Alice for protection.\n\n  `You shan't be beheaded!' said Alice, and she put them into a\nlarge flower-pot that stood near.  The three soldiers wandered\nabout for a minute or two, looking for them, and then quietly\nmarched off after the others.\n\n  `Are their heads off?' shouted the Queen.\n\n  `Their heads are gone, if it please your Majesty!' the soldiers\nshouted in reply.\n\n  `That's right!' shouted the Queen.  `Can you play croquet?'\n\n  The soldiers were silent, and looked at Alice, as the question\nwas evidently meant for her.\n\n  `Yes!' shouted Alice.\n\n  `Come on, then!' roared the Queen, and Alice joined the\nprocession, wondering very much what would happen next.\n\n  `It's--it's a very fine day!' said a timid voice at her side.\nShe was walking by the White Rabbit, who was peeping anxiously\ninto her face.\n\n  `Very,' said Alice:  `--where's the Duchess?'\n\n  `Hush!  Hush!' said the Rabbit in a low, hurried tone.  He\nlooked anxiously over his shoulder as he spoke, and then raised\nhimself upon tiptoe, put his mouth close to her ear, and\nwhispered `She's under sentence of execution.'\n\n  `What for?' said Alice.\n\n  `Did you say \"What a pity!\"?' the Rabbit asked.\n\n  `No, I didn't,' said Alice:  `I don't think it's at all a pity.\nI said \"What for?\"'\n\n  `She boxed the Queen's ears--' the Rabbit began.  Alice gave a\nlittle scream of laughter.  `Oh, hush!' the Rabbit whispered in a\nfrightened tone.  `The Queen will hear you!  You see, she came\nrather late, and the Queen said--'\n\n  `Get to your places!' shouted the Queen in a voice of thunder,\nand people began running about in all directions, tumbling up\nagainst each other; however, they got settled down in a minute or\ntwo, and the game began.  Alice thought she had never seen such a\ncurious croquet-ground in her life; it was all ridges and\nfurrows; the balls were live hedgehogs, the mallets live\nflamingoes, and the soldiers had to double themselves up and to\nstand on their hands and feet, to make the arches.\n\n  The chief difficulty Alice found at first was in managing her\nflamingo:  she succeeded in getting its body tucked away,\ncomfortably enough, under her arm, with its legs hanging down,\nbut generally, just as she had got its neck nicely straightened\nout, and was going to give the hedgehog a blow with its head, it\nWOULD twist itself round and look up in her face, with such a\npuzzled expression that she could not help bursting out laughing:\nand when she had got its head down, and was going to begin again,\nit was very provoking to find that the hedgehog had unrolled\nitself, and was in the act of crawling away:  besides all this,\nthere was generally a ridge or furrow in the way wherever she\nwanted to send the hedgehog to, and, as the doubled-up soldiers\nwere always getting up and walking off to other parts of the\nground, Alice soon came to the conclusion that it was a very\ndifficult game indeed.\n\n  The players all played at once without waiting for turns,\nquarrelling all the while, and fighting for the hedgehogs; and in\na very short time the Queen was in a furious passion, and went\nstamping about, and shouting `Off with his head!' or `Off with\nher head!' about once in a minute.\n\n  Alice began to feel very uneasy:  to be sure, she had not as\nyet had any dispute with the Queen, but she knew that it might\nhappen any minute, `and then,' thought she, `what would become of\nme?  They're dreadfully fond of beheading people here; the great\nwonder is, that there's any one left alive!'\n\n  She was looking about for some way of escape, and wondering\nwhether she could get away without being seen, when she noticed a\ncurious appearance in the air:  it puzzled her very much at\nfirst, but, after watching it a minute or two, she made it out to\nbe a grin, and she said to herself `It's the Cheshire Cat:  now I\nshall have somebody to talk to.'\n\n  `How are you getting on?' said the Cat, as soon as there was\nmouth enough for it to speak with.\n\n  Alice waited till the eyes appeared, and then nodded.  `It's no\nuse speaking to it,' she thought, `till its ears have come, or at\nleast one of them.'  In another minute the whole head appeared,\nand then Alice put down her flamingo, and began an account of the\ngame, feeling very glad she had someone to listen to her.  The\nCat seemed to think that there was enough of it now in sight, and\nno more of it appeared.\n\n  `I don't think they play at all fairly,' Alice began, in rather\na complaining tone, `and they all quarrel so dreadfully one can't\nhear oneself speak--and they don't seem to have any rules in\nparticular; at least, if there are, nobody attends to them--and\nyou've no idea how confusing it is all the things being alive;\nfor instance, there's the arch I've got to go through next\nwalking about at the other end of the ground--and I should have\ncroqueted the Queen's hedgehog just now, only it ran away when it\nsaw mine coming!'\n\n  `How do you like the Queen?' said the Cat in a low voice.\n\n  `Not at all,' said Alice:  `she's so extremely--'  Just then\nshe noticed that the Queen was close behind her, listening:  so\nshe went on, `--likely to win, that it's hardly worth while\nfinishing the game.'\n\n  The Queen smiled and passed on.\n\n  `Who ARE you talking to?' said the King, going up to Alice, and\nlooking at the Cat's head with great curiosity.\n\n  `It's a friend of mine--a Cheshire Cat,' said Alice:  `allow me\nto introduce it.'\n\n  `I don't like the look of it at all,' said the King:\n`however, it may kiss my hand if it likes.'\n\n  `I'd rather not,' the Cat remarked.\n\n  `Don't be impertinent,' said the King, `and don't look at me\nlike that!'  He got behind Alice as he spoke.\n\n  `A cat may look at a king,' said Alice.  `I've read that in\nsome book, but I don't remember where.'\n\n  `Well, it must be removed,' said the King very decidedly, and\nhe called the Queen, who was passing at the moment, `My dear!  I\nwish you would have this cat removed!'\n\n  The Queen had only one way of settling all difficulties, great\nor small.  `Off with his head!' she said, without even looking\nround.\n\n  `I'll fetch the executioner myself,' said the King eagerly, and\nhe hurried off.\n\n  Alice thought she might as well go back, and see how the game\nwas going on, as she heard the Queen's voice in the distance,\nscreaming with passion.  She had already heard her sentence three\nof the players to be executed for having missed their turns, and\nshe did not like the look of things at all, as the game was in\nsuch confusion that she never knew whether it was her turn or\nnot.  So she went in search of her hedgehog.\n\n  The hedgehog was engaged in a fight with another hedgehog,\nwhich seemed to Alice an excellent opportunity for croqueting one\nof them with the other:  the only difficulty was, that her\nflamingo was gone across to the other side of the garden, where\nAlice could see it trying in a helpless sort of way to fly up\ninto a tree.\n\n  By the time she had caught the flamingo and brought it back,\nthe fight was over, and both the hedgehogs were out of sight:\n`but it doesn't matter much,' thought Alice, `as all the arches\nare gone from this side of the ground.'  So she tucked it away\nunder her arm, that it might not escape again, and went back for\na little more conversation with her friend.\n\n  When she got back to the Cheshire Cat, she was surprised to\nfind quite a large crowd collected round it:  there was a dispute\ngoing on between the executioner, the King, and the Queen, who\nwere all talking at once, while all the rest were quite silent,\nand looked very uncomfortable.\n\n  The moment Alice appeared, she was appealed to by all three to\nsettle the question, and they repeated their arguments to her,\nthough, as they all spoke at once, she found it very hard indeed\nto make out exactly what they said.\n\n  The executioner's argument was, that you couldn't cut off a\nhead unless there was a body to cut it off from:  that he had\nnever had to do such a thing before, and he wasn't going to begin\nat HIS time of life.\n\n  The King's argument was, that anything that had a head could be\nbeheaded, and that you weren't to talk nonsense.\n\n  The Queen's argument was, that if something wasn't done about\nit in less than no time she'd have everybody executed, all round.\n(It was this last remark that had made the whole party look so\ngrave and anxious.)\n\n  Alice could think of nothing else to say but `It belongs to the\nDuchess:  you'd better ask HER about it.'\n\n  `She's in prison,' the Queen said to the executioner:  `fetch\nher here.'  And the executioner went off like an arrow.\n\n   The Cat's head began fading away the moment he was gone, and,\nby the time he had come back with the Dutchess, it had entirely\ndisappeared; so the King and the executioner ran wildly up and down\nlooking for it, while the rest of the party went back to the game.\n\n\n\n                           CHAPTER IX\n\n                     The Mock Turtle's Story\n\n\n  `You can't think how glad I am to see you again, you dear old\nthing!' said the Duchess, as she tucked her arm affectionately\ninto Alice's, and they walked off together.\n\n  Alice was very glad to find her in such a pleasant temper, and\nthought to herself that perhaps it was only the pepper that had\nmade her so savage when they met in the kitchen.\n\n  `When I'M a Duchess,' she said to herself, (not in a very\nhopeful tone though), `I won't have any pepper in my kitchen AT\nALL.  Soup does very well without--Maybe it's always pepper that\nmakes people hot-tempered,' she went on, very much pleased at\nhaving found out a new kind of rule, `and vinegar that makes them\nsour--and camomile that makes them bitter--and--and barley-sugar\nand such things that make children sweet-tempered.  I only wish\npeople knew that:  then they wouldn't be so stingy about it, you\nknow--'\n\n  She had quite forgotten the Duchess by this time, and was a\nlittle startled when she heard her voice close to her ear.\n`You're thinking about something, my dear, and that makes you\nforget to talk.  I can't tell you just now what the moral of that\nis, but I shall remember it in a bit.'\n\n  `Perhaps it hasn't one,' Alice ventured to remark.\n\n  `Tut, tut, child!' said the Duchess.  `Everything's got a\nmoral, if only you can find it.'  And she squeezed herself up\ncloser to Alice's side as she spoke.\n\n  Alice did not much like keeping so close to her:  first,\nbecause the Duchess was VERY ugly; and secondly, because she was\nexactly the right height to rest her chin upon Alice's shoulder,\nand it was an uncomfortably sharp chin.  However, she did not\nlike to be rude, so she bore it as well as she could.\n\n  `The game's going on rather better now,' she said, by way of\nkeeping up the conversation a little.\n\n  `'Tis so,' said the Duchess:  `and the moral of that is--\"Oh,\n'tis love, 'tis love, that makes the world go round!\"'\n\n  `Somebody said,' Alice whispered, `that it's done by everybody\nminding their own business!'\n\n  `Ah, well!  It means much the same thing,' said the Duchess,\ndigging her sharp little chin into Alice's shoulder as she added,\n`and the moral of THAT is--\"Take care of the sense, and the\nsounds will take care of themselves.\"'\n\n  `How fond she is of finding morals in things!' Alice thought to\nherself.\n\n  `I dare say you're wondering why I don't put my arm round your\nwaist,' the Duchess said after a pause:  `the reason is, that I'm\ndoubtful about the temper of your flamingo.  Shall I try the\nexperiment?'\n\n  `HE might bite,' Alice cautiously replied, not feeling at all\nanxious to have the experiment tried.\n\n  `Very true,' said the Duchess:  `flamingoes and mustard both\nbite.  And the moral of that is--\"Birds of a feather flock\ntogether.\"'\n\n  `Only mustard isn't a bird,' Alice remarked.\n\n  `Right, as usual,' said the Duchess:  `what a clear way you\nhave of putting things!'\n\n  `It's a mineral, I THINK,' said Alice.\n\n  `Of course it is,' said the Duchess, who seemed ready to agree\nto everything that Alice said; `there's a large mustard-mine near\nhere.  And the moral of that is--\"The more there is of mine, the\nless there is of yours.\"'\n\n  `Oh, I know!' exclaimed Alice, who had not attended to this\nlast remark, `it's a vegetable.  It doesn't look like one, but it\nis.'\n\n  `I quite agree with you,' said the Duchess; `and the moral of\nthat is--\"Be what you would seem to be\"--or if you'd like it put\nmore simply--\"Never imagine yourself not to be otherwise than\nwhat it might appear to others that what you were or might have\nbeen was not otherwise than what you had been would have appeared\nto them to be otherwise.\"'\n\n  `I think I should understand that better,' Alice said very\npolitely, `if I had it written down:  but I can't quite follow it\nas you say it.'\n\n  `That's nothing to what I could say if I chose,' the Duchess\nreplied, in a pleased tone.\n\n  `Pray don't trouble yourself to say it any longer than that,'\nsaid Alice.\n\n  `Oh, don't talk about trouble!' said the Duchess.  `I make you\na present of everything I've said as yet.'\n\n  `A cheap sort of present!' thought Alice.  `I'm glad they don't\ngive birthday presents like that!'  But she did not venture to\nsay it out loud.\n\n  `Thinking again?' the Duchess asked, with another dig of her\nsharp little chin.\n\n  `I've a right to think,' said Alice sharply, for she was\nbeginning to feel a little worried.\n\n  `Just about as much right,' said the Duchess, `as pigs have to fly;\nand the m--'\n\n  But here, to Alice's great surprise, the Duchess's voice died\naway, even in the middle of her favourite word `moral,' and the\narm that was linked into hers began to tremble.  Alice looked up,\nand there stood the Queen in front of them, with her arms folded,\nfrowning like a thunderstorm.\n\n  `A fine day, your Majesty!' the Duchess began in a low, weak\nvoice.\n\n  `Now, I give you fair warning,' shouted the Queen, stamping on\nthe ground as she spoke; `either you or your head must be off,\nand that in about half no time!  Take your choice!'\n\n  The Duchess took her choice, and was gone in a moment.\n\n  `Let's go on with the game,' the Queen said to Alice; and Alice\nwas too much frightened to say a word, but slowly followed her\nback to the croquet-ground.\n\n  The other guests had taken advantage of the Queen's absence,\nand were resting in the shade:  however, the moment they saw her,\nthey hurried back to the game, the Queen merely remarking that a\nmoment's delay would cost them their lives.\n\n  All the time they were playing the Queen never left off\nquarrelling with the other players, and shouting `Off with his\nhead!' or `Off with her head!'  Those whom she sentenced were\ntaken into custody by the soldiers, who of course had to leave\noff being arches to do this, so that by the end of half an hour\nor so there were no arches left, and all the players, except the\nKing, the Queen, and Alice, were in custody and under sentence of\nexecution.\n\n  Then the Queen left off, quite out of breath, and said to\nAlice, `Have you seen the Mock Turtle yet?'\n\n  `No,' said Alice.  `I don't even know what a Mock Turtle is.'\n\n  `It's the thing Mock Turtle Soup is made from,' said the Queen.\n\n  `I never saw one, or heard of one,' said Alice.\n\n  `Come on, then,' said the Queen, `and he shall tell you his\nhistory,'\n\n  As they walked off together, Alice heard the King say in a low\nvoice, to the company generally, `You are all pardoned.'  `Come,\nTHAT'S a good thing!' she said to herself, for she had felt quite\nunhappy at the number of executions the Queen had ordered.\n\n  They very soon came upon a Gryphon, lying fast asleep in the\nsun.  (IF you don't know what a Gryphon is, look at the picture.)\n`Up, lazy thing!' said the Queen, `and take this young lady to\nsee the Mock Turtle, and to hear his history.  I must go back and\nsee after some executions I have ordered'; and she walked off,\nleaving Alice alone with the Gryphon.  Alice did not quite like\nthe look of the creature, but on the whole she thought it would\nbe quite as safe to stay with it as to go after that savage\nQueen:  so she waited.\n\n  The Gryphon sat up and rubbed its eyes:  then it watched the\nQueen till she was out of sight:  then it chuckled.  `What fun!'\nsaid the Gryphon, half to itself, half to Alice.\n\n  `What IS the fun?' said Alice.\n\n  `Why, SHE,' said the Gryphon.  `It's all her fancy, that:  they\nnever executes nobody, you know.  Come on!'\n\n  `Everybody says \"come on!\" here,' thought Alice, as she went\nslowly after it:  `I never was so ordered about in all my life,\nnever!'\n\n  They had not gone far before they saw the Mock Turtle in the\ndistance, sitting sad and lonely on a little ledge of rock, and,\nas they came nearer, Alice could hear him sighing as if his heart\nwould break.  She pitied him deeply.  `What is his sorrow?' she\nasked the Gryphon, and the Gryphon answered, very nearly in the\nsame words as before, `It's all his fancy, that:  he hasn't got\nno sorrow, you know.  Come on!'\n\n  So they went up to the Mock Turtle, who looked at them with\nlarge eyes full of tears, but said nothing.\n\n  `This here young lady,' said the Gryphon, `she wants for to\nknow your history, she do.'\n\n  `I'll tell it her,' said the Mock Turtle in a deep, hollow\ntone:  `sit down, both of you, and don't speak a word till I've\nfinished.'\n\n  So they sat down, and nobody spoke for some minutes.  Alice\nthought to herself, `I don't see how he can EVEN finish, if he\ndoesn't begin.'  But she waited patiently.\n\n  `Once,' said the Mock Turtle at last, with a deep sigh, `I was\na real Turtle.'\n\n  These words were followed by a very long silence, broken only\nby an occasional exclamation of `Hjckrrh!' from the Gryphon, and\nthe constant heavy sobbing of the Mock Turtle.  Alice was very\nnearly getting up and saying, `Thank you, sir, for your\ninteresting story,' but she could not help thinking there MUST be\nmore to come, so she sat still and said nothing.\n\n  `When we were little,' the Mock Turtle went on at last, more\ncalmly, though still sobbing a little now and then, `we went to\nschool in the sea.  The master was an old Turtle--we used to call\nhim Tortoise--'\n\n  `Why did you call him Tortoise, if he wasn't one?' Alice asked.\n\n  `We called him Tortoise because he taught us,' said the Mock\nTurtle angrily:  `really you are very dull!'\n\n  `You ought to be ashamed of yourself for asking such a simple\nquestion,' added the Gryphon; and then they both sat silent and\nlooked at poor Alice, who felt ready to sink into the earth.  At\nlast the Gryphon said to the Mock Turtle, `Drive on, old fellow!\nDon't be all day about it!' and he went on in these words:\n\n  `Yes, we went to school in the sea, though you mayn't believe\nit--'\n\n  `I never said I didn't!' interrupted Alice.\n\n  `You did,' said the Mock Turtle.\n\n  `Hold your tongue!' added the Gryphon, before Alice could speak\nagain.  The Mock Turtle went on.\n\n  `We had the best of educations--in fact, we went to school\nevery day--'\n\n  `I'VE been to a day-school, too,' said Alice; `you needn't be\nso proud as all that.'\n\n  `With extras?' asked the Mock Turtle a little anxiously.\n\n  `Yes,' said Alice, `we learned French and music.'\n\n  `And washing?' said the Mock Turtle.\n\n  `Certainly not!' said Alice indignantly.\n\n  `Ah! then yours wasn't a really good school,' said the Mock\nTurtle in a tone of great relief.  `Now at OURS they had at the\nend of the bill, \"French, music, AND WASHING--extra.\"'\n\n  `You couldn't have wanted it much,' said Alice; `living at the\nbottom of the sea.'\n\n  `I couldn't afford to learn it.' said the Mock Turtle with a\nsigh.  `I only took the regular course.'\n\n  `What was that?' inquired Alice.\n\n  `Reeling and Writhing, of course, to begin with,' the Mock\nTurtle replied; `and then the different branches of Arithmetic--\nAmbition, Distraction, Uglification, and Derision.'\n\n  `I never heard of \"Uglification,\"' Alice ventured to say.  `What is it?'\n\n  The Gryphon lifted up both its paws in surprise.  `What!  Never\nheard of uglifying!' it exclaimed.  `You know what to beautify is,\nI suppose?'\n\n  `Yes,' said Alice doubtfully:  `it means--to--make--anything--prettier.'\n\n  `Well, then,' the Gryphon went on, `if you don't know what to\nuglify is, you ARE a simpleton.'\n\n  Alice did not feel encouraged to ask any more questions about\nit, so she turned to the Mock Turtle, and said `What else had you\nto learn?'\n\n  `Well, there was Mystery,' the Mock Turtle replied, counting\noff the subjects on his flappers, `--Mystery, ancient and modern,\nwith Seaography:  then Drawling--the Drawling-master was an old\nconger-eel, that used to come once a week:  HE taught us\nDrawling, Stretching, and Fainting in Coils.'\n\n  `What was THAT like?' said Alice.\n\n  `Well, I can't show it you myself,' the Mock Turtle said:  `I'm\ntoo stiff.  And the Gryphon never learnt it.'\n\n  `Hadn't time,' said the Gryphon:  `I went to the Classics\nmaster, though.  He was an old crab, HE was.'\n\n  `I never went to him,' the Mock Turtle said with a sigh:  `he\ntaught Laughing and Grief, they used to say.'\n\n  `So he did, so he did,' said the Gryphon, sighing in his turn;\nand both creatures hid their faces in their paws.\n\n  `And how many hours a day did you do lessons?' said Alice, in a\nhurry to change the subject.\n\n  `Ten hours the first day,' said the Mock Turtle: `nine the\nnext, and so on.'\n\n  `What a curious plan!' exclaimed Alice.\n\n  `That's the reason they're called lessons,' the Gryphon\nremarked:  `because they lessen from day to day.'\n\n  This was quite a new idea to Alice, and she thought it over a\nlittle before she made her next remark.  `Then the eleventh day\nmust have been a holiday?'\n\n  `Of course it was,' said the Mock Turtle.\n\n  `And how did you manage on the twelfth?' Alice went on eagerly.\n\n  `That's enough about lessons,' the Gryphon interrupted in a\nvery decided tone:  `tell her something about the games now.'\n\n\n\n                            CHAPTER X\n\n                      The Lobster Quadrille\n\n\n  The Mock Turtle sighed deeply, and drew the back of one flapper\nacross his eyes.  He looked at Alice, and tried to speak, but for\na minute or two sobs choked his voice.  `Same as if he had a bone\nin his throat,' said the Gryphon:  and it set to work shaking him\nand punching him in the back.  At last the Mock Turtle recovered\nhis voice, and, with tears running down his cheeks, he went on\nagain:--\n\n  `You may not have lived much under the sea--' (`I haven't,' said Alice)--\n`and perhaps you were never even introduced to a lobster--'\n(Alice began to say `I once tasted--' but checked herself hastily,\nand said `No, never') `--so you can have no idea what a delightful\nthing a Lobster Quadrille is!'\n\n  `No, indeed,' said Alice.  `What sort of a dance is it?'\n\n  `Why,' said the Gryphon, `you first form into a line along the sea-shore--'\n\n  `Two lines!' cried the Mock Turtle.  `Seals, turtles, salmon, and so on;\nthen, when you've cleared all the jelly-fish out of the way--'\n\n  `THAT generally takes some time,' interrupted the Gryphon.\n\n  `--you advance twice--'\n\n  `Each with a lobster as a partner!' cried the Gryphon.\n\n  `Of course,' the Mock Turtle said:  `advance twice, set to\npartners--'\n\n  `--change lobsters, and retire in same order,' continued the\nGryphon.\n\n  `Then, you know,' the Mock Turtle went on, `you throw the--'\n\n  `The lobsters!' shouted the Gryphon, with a bound into the air.\n\n  `--as far out to sea as you can--'\n\n  `Swim after them!' screamed the Gryphon.\n\n  `Turn a somersault in the sea!' cried the Mock Turtle,\ncapering wildly about.\n\n  `Change lobsters again!' yelled the Gryphon at the top of its voice.\n\n  `Back to land again, and that's all the first figure,' said the\nMock Turtle, suddenly dropping his voice; and the two creatures,\nwho had been jumping about like mad things all this time, sat\ndown again very sadly and quietly, and looked at Alice.\n\n  `It must be a very pretty dance,' said Alice timidly.\n\n  `Would you like to see a little of it?' said the Mock Turtle.\n\n  `Very much indeed,' said Alice.\n\n  `Come, let's try the first figure!' said the Mock Turtle to the\nGryphon.  `We can do without lobsters, you know.  Which shall\nsing?'\n\n  `Oh, YOU sing,' said the Gryphon.  `I've forgotten the words.'\n\n  So they began solemnly dancing round and round Alice, every now\nand then treading on her toes when they passed too close, and\nwaving their forepaws to mark the time, while the Mock Turtle\nsang this, very slowly and sadly:--\n\n\n`\"Will you walk a little faster?\" said a whiting to a snail.\n\"There's a porpoise close behind us, and he's treading on my\n tail.\nSee how eagerly the lobsters and the turtles all advance!\nThey are waiting on the shingle--will you come and join the\ndance?\n\nWill you, won't you, will you, won't you, will you join the\ndance?\nWill you, won't you, will you, won't you, won't you join the\ndance?\n\n\n\"You can really have no notion how delightful it will be\nWhen they take us up and throw us, with the lobsters, out to\n                                                      sea!\"\nBut the snail replied \"Too far, too far!\" and gave a look\n                                                       askance--\nSaid he thanked the whiting kindly, but he would not join the\n   dance.\n    Would not, could not, would not, could not, would not join\n        the dance.\n    Would not, could not, would not, could not, could not join\n        the dance.\n\n`\"What matters it how far we go?\" his scaly friend replied.\n\"There is another shore, you know, upon the other side.\nThe further off from England the nearer is to France--\nThen turn not pale, beloved snail, but come and join the dance.\n\n    Will you, won't you, will you, won't you, will you join the\n         dance?\n    Will you, won't you, will you, won't you, won't you join the\n         dance?\"'\n\n\n\n  `Thank you, it's a very interesting dance to watch,' said\nAlice, feeling very glad that it was over at last:  `and I do so\nlike that curious song about the whiting!'\n\n  `Oh, as to the whiting,' said the Mock Turtle, `they--you've\nseen them, of course?'\n\n  `Yes,' said Alice, `I've often seen them at dinn--' she\nchecked herself hastily.\n\n  `I don't know where Dinn may be,' said the Mock Turtle, `but\nif you've seen them so often, of course you know what they're\nlike.'\n\n  `I believe so,' Alice replied thoughtfully.  `They have their\ntails in their mouths--and they're all over crumbs.'\n\n  `You're wrong about the crumbs,' said the Mock Turtle:\n`crumbs would all wash off in the sea.  But they HAVE their tails\nin their mouths; and the reason is--' here the Mock Turtle\nyawned and shut his eyes.--`Tell her about the reason and all\nthat,' he said to the Gryphon.\n\n  `The reason is,' said the Gryphon, `that they WOULD go with\nthe lobsters to the dance.  So they got thrown out to sea.  So\nthey had to fall a long way.  So they got their tails fast in\ntheir mouths.  So they couldn't get them out again.  That's all.'\n\n  `Thank you,' said Alice, `it's very interesting.  I never knew\nso much about a whiting before.'\n\n  `I can tell you more than that, if you like,' said the\nGryphon.  `Do you know why it's called a whiting?'\n\n  `I never thought about it,' said Alice.  `Why?'\n\n  `IT DOES THE BOOTS AND SHOES.' the Gryphon replied very\nsolemnly.\n\n  Alice was thoroughly puzzled.  `Does the boots and shoes!' she\nrepeated in a wondering tone.\n\n  `Why, what are YOUR shoes done with?' said the Gryphon.  `I\nmean, what makes them so shiny?'\n\n  Alice looked down at them, and considered a little before she\ngave her answer.  `They're done with blacking, I believe.'\n\n  `Boots and shoes under the sea,' the Gryphon went on in a deep\nvoice, `are done with a whiting.  Now you know.'\n\n  `And what are they made of?' Alice asked in a tone of great\ncuriosity.\n\n  `Soles and eels, of course,' the Gryphon replied rather\nimpatiently:  `any shrimp could have told you that.'\n\n  `If I'd been the whiting,' said Alice, whose thoughts were\nstill running on the song, `I'd have said to the porpoise, \"Keep\nback, please:  we don't want YOU with us!\"'\n\n  `They were obliged to have him with them,' the Mock Turtle\nsaid:  `no wise fish would go anywhere without a porpoise.'\n\n  `Wouldn't it really?' said Alice in a tone of great surprise.\n\n  `Of course not,' said the Mock Turtle:  `why, if a fish came\nto ME, and told me he was going a journey, I should say \"With\nwhat porpoise?\"'\n\n  `Don't you mean \"purpose\"?' said Alice.\n\n  `I mean what I say,' the Mock Turtle replied in an offended\ntone.  And the Gryphon added `Come, let's hear some of YOUR\nadventures.'\n\n  `I could tell you my adventures--beginning from this morning,'\nsaid Alice a little timidly:  `but it's no use going back to\nyesterday, because I was a different person then.'\n\n  `Explain all that,' said the Mock Turtle.\n\n  `No, no!  The adventures first,' said the Gryphon in an\nimpatient tone:  `explanations take such a dreadful time.'\n\n  So Alice began telling them her adventures from the time when\nshe first saw the White Rabbit.  She was a little nervous about\nit just at first, the two creatures got so close to her, one on\neach side, and opened their eyes and mouths so VERY wide, but she\ngained courage as she went on.  Her listeners were perfectly\nquiet till she got to the part about her repeating `YOU ARE OLD,\nFATHER WILLIAM,' to the Caterpillar, and the words all coming\ndifferent, and then the Mock Turtle drew a long breath, and said\n`That's very curious.'\n\n  `It's all about as curious as it can be,' said the Gryphon.\n\n  `It all came different!' the Mock Turtle repeated\nthoughtfully.  `I should like to hear her try and repeat\nsomething now.  Tell her to begin.'  He looked at the Gryphon as\nif he thought it had some kind of authority over Alice.\n\n  `Stand up and repeat \"'TIS THE VOICE OF THE SLUGGARD,\"' said\nthe Gryphon.\n\n  `How the creatures order one about, and make one repeat\nlessons!' thought Alice; `I might as well be at school at once.'\nHowever, she got up, and began to repeat it, but her head was so\nfull of the Lobster Quadrille, that she hardly knew what she was\nsaying, and the words came very queer indeed:--\n\n    `'Tis the voice of the Lobster; I heard him declare,\n    \"You have baked me too brown, I must sugar my hair.\"\n    As a duck with its eyelids, so he with his nose\n    Trims his belt and his buttons, and turns out his toes.'\n\n              [later editions continued as follows\n    When the sands are all dry, he is gay as a lark,\n    And will talk in contemptuous tones of the Shark,\n    But, when the tide rises and sharks are around,\n    His voice has a timid and tremulous sound.]\n\n  `That's different from what I used to say when I was a child,'\nsaid the Gryphon.\n\n  `Well, I never heard it before,' said the Mock Turtle; `but it\nsounds uncommon nonsense.'\n\n  Alice said nothing; she had sat down with her face in her\nhands, wondering if anything would EVER happen in a natural way\nagain.\n\n  `I should like to have it explained,' said the Mock Turtle.\n\n  `She can't explain it,' said the Gryphon hastily.  `Go on with\nthe next verse.'\n\n  `But about his toes?' the Mock Turtle persisted.  `How COULD\nhe turn them out with his nose, you know?'\n\n  `It's the first position in dancing.' Alice said; but was\ndreadfully puzzled by the whole thing, and longed to change the\nsubject.\n\n  `Go on with the next verse,' the Gryphon repeated impatiently:\n`it begins \"I passed by his garden.\"'\n\n  Alice did not dare to disobey, though she felt sure it would\nall come wrong, and she went on in a trembling voice:--\n\n    `I passed by his garden, and marked, with one eye,\n    How the Owl and the Panther were sharing a pie--'\n\n        [later editions continued as follows\n    The Panther took pie-crust, and gravy, and meat,\n    While the Owl had the dish as its share of the treat.\n    When the pie was all finished, the Owl, as a boon,\n    Was kindly permitted to pocket the spoon:\n    While the Panther received knife and fork with a growl,\n    And concluded the banquet--]\n\n  `What IS the use of repeating all that stuff,' the Mock Turtle\ninterrupted, `if you don't explain it as you go on?  It's by far\nthe most confusing thing I ever heard!'\n\n  `Yes, I think you'd better leave off,' said the Gryphon:  and\nAlice was only too glad to do so.\n\n  `Shall we try another figure of the Lobster Quadrille?' the\nGryphon went on.  `Or would you like the Mock Turtle to sing you\na song?'\n\n  `Oh, a song, please, if the Mock Turtle would be so kind,'\nAlice replied, so eagerly that the Gryphon said, in a rather\noffended tone, `Hm!  No accounting for tastes!  Sing her\n\"Turtle Soup,\" will you, old fellow?'\n\n  The Mock Turtle sighed deeply, and began, in a voice sometimes\nchoked with sobs, to sing this:--\n\n\n    `Beautiful Soup, so rich and green,\n    Waiting in a hot tureen!\n    Who for such dainties would not stoop?\n    Soup of the evening, beautiful Soup!\n    Soup of the evening, beautiful Soup!\n        Beau--ootiful Soo--oop!\n        Beau--ootiful Soo--oop!\n    Soo--oop of the e--e--evening,\n        Beautiful, beautiful Soup!\n\n    `Beautiful Soup!  Who cares for fish,\n    Game, or any other dish?\n    Who would not give all else for two\n    Pennyworth only of beautiful Soup?\n    Pennyworth only of beautiful Soup?\n        Beau--ootiful Soo--oop!\n        Beau--ootiful Soo--oop!\n    Soo--oop of the e--e--evening,\n        Beautiful, beauti--FUL SOUP!'\n\n  `Chorus again!' cried the Gryphon, and the Mock Turtle had\njust begun to repeat it, when a cry of `The trial's beginning!'\nwas heard in the distance.\n\n  `Come on!' cried the Gryphon, and, taking Alice by the hand,\nit hurried off, without waiting for the end of the song.\n\n  `What trial is it?' Alice panted as she ran; but the Gryphon\nonly answered `Come on!' and ran the faster, while more and more\nfaintly came, carried on the breeze that followed them, the\nmelancholy words:--\n\n    `Soo--oop of the e--e--evening,\n        Beautiful, beautiful Soup!'\n\n\n\n                           CHAPTER XI\n\n                      Who Stole the Tarts?\n\n\n  The King and Queen of Hearts were seated on their throne when\nthey arrived, with a great crowd assembled about them--all sorts\nof little birds and beasts, as well as the whole pack of cards:\nthe Knave was standing before them, in chains, with a soldier on\neach side to guard him; and near the King was the White Rabbit,\nwith a trumpet in one hand, and a scroll of parchment in the\nother.  In the very middle of the court was a table, with a large\ndish of tarts upon it:  they looked so good, that it made Alice\nquite hungry to look at them--`I wish they'd get the trial done,'\nshe thought, `and hand round the refreshments!'  But there seemed\nto be no chance of this, so she began looking at everything about\nher, to pass away the time.\n\n  Alice had never been in a court of justice before, but she had\nread about them in books, and she was quite pleased to find that\nshe knew the name of nearly everything there.  `That's the\njudge,' she said to herself, `because of his great wig.'\n\n  The judge, by the way, was the King; and as he wore his crown\nover the wig, (look at the frontispiece if you want to see how he\ndid it,) he did not look at all comfortable, and it was certainly\nnot becoming.\n\n  `And that's the jury-box,' thought Alice, `and those twelve\ncreatures,' (she was obliged to say `creatures,' you see, because\nsome of them were animals, and some were birds,) `I suppose they\nare the jurors.'  She said this last word two or three times over\nto herself, being rather proud of it:  for she thought, and\nrightly too, that very few little girls of her age knew the\nmeaning of it at all.  However, `jury-men' would have done just\nas well.\n\n  The twelve jurors were all writing very busily on slates.\n`What are they doing?'  Alice whispered to the Gryphon.  `They\ncan't have anything to put down yet, before the trial's begun.'\n\n  `They're putting down their names,' the Gryphon whispered in\nreply, `for fear they should forget them before the end of the\ntrial.'\n\n  `Stupid things!' Alice began in a loud, indignant voice, but\nshe stopped hastily, for the White Rabbit cried out, `Silence in\nthe court!' and the King put on his spectacles and looked\nanxiously round, to make out who was talking.\n\n  Alice could see, as well as if she were looking over their\nshoulders, that all the jurors were writing down `stupid things!'\non their slates, and she could even make out that one of them\ndidn't know how to spell `stupid,' and that he had to ask his\nneighbour to tell him.  `A nice muddle their slates'll be in\nbefore the trial's over!' thought Alice.\n\n  One of the jurors had a pencil that squeaked.  This of course,\nAlice could not stand, and she went round the court and got\nbehind him, and very soon found an opportunity of taking it\naway.  She did it so quickly that the poor little juror (it was\nBill, the Lizard) could not make out at all what had become of\nit; so, after hunting all about for it, he was obliged to write\nwith one finger for the rest of the day; and this was of very\nlittle use, as it left no mark on the slate.\n\n  `Herald, read the accusation!' said the King.\n\n  On this the White Rabbit blew three blasts on the trumpet, and\nthen unrolled the parchment scroll, and read as follows:--\n\n    `The Queen of Hearts, she made some tarts,\n          All on a summer day:\n      The Knave of Hearts, he stole those tarts,\n          And took them quite away!'\n\n  `Consider your verdict,' the King said to the jury.\n\n  `Not yet, not yet!' the Rabbit hastily interrupted.  `There's\na great deal to come before that!'\n\n  `Call the first witness,' said the King; and the White Rabbit\nblew three blasts on the trumpet, and called out, `First\nwitness!'\n\n  The first witness was the Hatter.  He came in with a teacup in\none hand and a piece of bread-and-butter in the other.  `I beg\npardon, your Majesty,' he began, `for bringing these in:  but I\nhadn't quite finished my tea when I was sent for.'\n\n  `You ought to have finished,' said the King.  `When did you\nbegin?'\n\n  The Hatter looked at the March Hare, who had followed him into\nthe court, arm-in-arm with the Dormouse.  `Fourteenth of March, I\nthink it was,' he said.\n\n  `Fifteenth,' said the March Hare.\n\n  `Sixteenth,' added the Dormouse.\n\n  `Write that down,' the King said to the jury, and the jury\neagerly wrote down all three dates on their slates, and then\nadded them up, and reduced the answer to shillings and pence.\n\n  `Take off your hat,' the King said to the Hatter.\n\n  `It isn't mine,' said the Hatter.\n\n  `Stolen!' the King exclaimed, turning to the jury, who\ninstantly made a memorandum of the fact.\n\n  `I keep them to sell,' the Hatter added as an explanation;\n`I've none of my own.  I'm a hatter.'\n\n  Here the Queen put on her spectacles, and began staring at the\nHatter, who turned pale and fidgeted.\n\n  `Give your evidence,' said the King; `and don't be nervous, or\nI'll have you executed on the spot.'\n\n  This did not seem to encourage the witness at all:  he kept\nshifting from one foot to the other, looking uneasily at the\nQueen, and in his confusion he bit a large piece out of his\nteacup instead of the bread-and-butter.\n\n  Just at this moment Alice felt a very curious sensation, which\npuzzled her a good deal until she made out what it was:  she was\nbeginning to grow larger again, and she thought at first she\nwould get up and leave the court; but on second thoughts she\ndecided to remain where she was as long as there was room for\nher.\n\n  `I wish you wouldn't squeeze so.' said the Dormouse, who was\nsitting next to her.  `I can hardly breathe.'\n\n  `I can't help it,' said Alice very meekly:  `I'm growing.'\n\n  `You've no right to grow here,' said the Dormouse.\n\n  `Don't talk nonsense,' said Alice more boldly:  `you know\nyou're growing too.'\n\n  `Yes, but I grow at a reasonable pace,' said the Dormouse:\n`not in that ridiculous fashion.'  And he got up very sulkily\nand crossed over to the other side of the court.\n\n  All this time the Queen had never left off staring at the\nHatter, and, just as the Dormouse crossed the court, she said to\none of the officers of the court, `Bring me the list of the\nsingers in the last concert!' on which the wretched Hatter\ntrembled so, that he shook both his shoes off.\n\n  `Give your evidence,' the King repeated angrily, `or I'll have\nyou executed, whether you're nervous or not.'\n\n  `I'm a poor man, your Majesty,' the Hatter began, in a\ntrembling voice, `--and I hadn't begun my tea--not above a week\nor so--and what with the bread-and-butter getting so thin--and\nthe twinkling of the tea--'\n\n  `The twinkling of the what?' said the King.\n\n  `It began with the tea,' the Hatter replied.\n\n  `Of course twinkling begins with a T!' said the King sharply.\n`Do you take me for a dunce?  Go on!'\n\n  `I'm a poor man,' the Hatter went on, `and most things\ntwinkled after that--only the March Hare said--'\n\n  `I didn't!' the March Hare interrupted in a great hurry.\n\n  `You did!' said the Hatter.\n\n  `I deny it!' said the March Hare.\n\n  `He denies it,' said the King:  `leave out that part.'\n\n  `Well, at any rate, the Dormouse said--' the Hatter went on,\nlooking anxiously round to see if he would deny it too:  but the\nDormouse denied nothing, being fast asleep.\n\n  `After that,' continued the Hatter, `I cut some more bread-\nand-butter--'\n\n  `But what did the Dormouse say?' one of the jury asked.\n\n  `That I can't remember,' said the Hatter.\n\n  `You MUST remember,' remarked the King, `or I'll have you\nexecuted.'\n\n  The miserable Hatter dropped his teacup and bread-and-butter,\nand went down on one knee.  `I'm a poor man, your Majesty,' he\nbegan.\n\n  `You're a very poor speaker,' said the King.\n\n  Here one of the guinea-pigs cheered, and was immediately\nsuppressed by the officers of the court.  (As that is rather a\nhard word, I will just explain to you how it was done.  They had\na large canvas bag, which tied up at the mouth with strings:\ninto this they slipped the guinea-pig, head first, and then sat\nupon it.)\n\n  `I'm glad I've seen that done,' thought Alice.  `I've so often\nread in the newspapers, at the end of trials, \"There was some\nattempts at applause, which was immediately suppressed by the\nofficers of the court,\" and I never understood what it meant\ntill now.'\n\n  `If that's all you know about it, you may stand down,'\ncontinued the King.\n\n  `I can't go no lower,' said the Hatter:  `I'm on the floor, as\nit is.'\n\n  `Then you may SIT down,' the King replied.\n\n  Here the other guinea-pig cheered, and was suppressed.\n\n  `Come, that finished the guinea-pigs!' thought Alice.  `Now we\nshall get on better.'\n\n  `I'd rather finish my tea,' said the Hatter, with an anxious\nlook at the Queen, who was reading the list of singers.\n\n  `You may go,' said the King, and the Hatter hurriedly left the\ncourt, without even waiting to put his shoes on.\n\n  `--and just take his head off outside,' the Queen added to one\nof the officers:  but the Hatter was out of sight before the\nofficer could get to the door.\n\n  `Call the next witness!' said the King.\n\n  The next witness was the Duchess's cook.  She carried the\npepper-box in her hand, and Alice guessed who it was, even before\nshe got into the court, by the way the people near the door began\nsneezing all at once.\n\n  `Give your evidence,' said the King.\n\n  `Shan't,' said the cook.\n\n  The King looked anxiously at the White Rabbit, who said in a\nlow voice, `Your Majesty must cross-examine THIS witness.'\n\n  `Well, if I must, I must,' the King said, with a melancholy\nair, and, after folding his arms and frowning at the cook till\nhis eyes were nearly out of sight, he said in a deep voice, `What\nare tarts made of?'\n\n  `Pepper, mostly,' said the cook.\n\n  `Treacle,' said a sleepy voice behind her.\n\n  `Collar that Dormouse,' the Queen shrieked out.  `Behead that\nDormouse!  Turn that Dormouse out of court!  Suppress him!  Pinch\nhim!  Off with his whiskers!'\n\n  For some minutes the whole court was in confusion, getting the\nDormouse turned out, and, by the time they had settled down\nagain, the cook had disappeared.\n\n  `Never mind!' said the King, with an air of great relief.\n`Call the next witness.'  And he added in an undertone to the\nQueen, `Really, my dear, YOU must cross-examine the next witness.\nIt quite makes my forehead ache!'\n\n  Alice watched the White Rabbit as he fumbled over the list,\nfeeling very curious to see what the next witness would be like,\n`--for they haven't got much evidence YET,' she said to herself.\nImagine her surprise, when the White Rabbit read out, at the top\nof his shrill little voice, the name `Alice!'\n\n\n\n                           CHAPTER XII\n\n                        Alice's Evidence\n\n\n  `Here!' cried Alice, quite forgetting in the flurry of the\nmoment how large she had grown in the last few minutes, and she\njumped up in such a hurry that she tipped over the jury-box with\nthe edge of her skirt, upsetting all the jurymen on to the heads\nof the crowd below, and there they lay sprawling about, reminding\nher very much of a globe of goldfish she had accidentally upset\nthe week before.\n\n  `Oh, I BEG your pardon!' she exclaimed in a tone of great\ndismay, and began picking them up again as quickly as she could,\nfor the accident of the goldfish kept running in her head, and\nshe had a vague sort of idea that they must be collected at once\nand put back into the jury-box, or they would die.\n\n  `The trial cannot proceed,' said the King in a very grave\nvoice, `until all the jurymen are back in their proper places--\nALL,' he repeated with great emphasis, looking hard at Alice as\nhe said do.\n\n  Alice looked at the jury-box, and saw that, in her haste, she\nhad put the Lizard in head downwards, and the poor little thing\nwas waving its tail about in a melancholy way, being quite unable\nto move.  She soon got it out again, and put it right; `not that\nit signifies much,' she said to herself; `I should think it\nwould be QUITE as much use in the trial one way up as the other.'\n\n  As soon as the jury had a little recovered from the shock of\nbeing upset, and their slates and pencils had been found and\nhanded back to them, they set to work very diligently to write\nout a history of the accident, all except the Lizard, who seemed\ntoo much overcome to do anything but sit with its mouth open,\ngazing up into the roof of the court.\n\n  `What do you know about this business?' the King said to\nAlice.\n\n  `Nothing,' said Alice.\n\n  `Nothing WHATEVER?' persisted the King.\n\n  `Nothing whatever,' said Alice.\n\n  `That's very important,' the King said, turning to the jury.\nThey were just beginning to write this down on their slates, when\nthe White Rabbit interrupted:  `UNimportant, your Majesty means,\nof course,' he said in a very respectful tone, but frowning and\nmaking faces at him as he spoke.\n\n  `UNimportant, of course, I meant,' the King hastily said, and\nwent on to himself in an undertone, `important--unimportant--\nunimportant--important--' as if he were trying which word\nsounded best.\n\n  Some of the jury wrote it down `important,' and some\n`unimportant.'  Alice could see this, as she was near enough to\nlook over their slates; `but it doesn't matter a bit,' she\nthought to herself.\n\n  At this moment the King, who had been for some time busily\nwriting in his note-book, cackled out `Silence!' and read out\nfrom his book, `Rule Forty-two.  ALL PERSONS MORE THAN A MILE\nHIGH TO LEAVE THE COURT.'\n\n  Everybody looked at Alice.\n\n  `I'M not a mile high,' said Alice.\n\n  `You are,' said the King.\n\n  `Nearly two miles high,' added the Queen.\n\n  `Well, I shan't go, at any rate,' said Alice:  `besides,\nthat's not a regular rule:  you invented it just now.'\n\n  `It's the oldest rule in the book,' said the King.\n\n  `Then it ought to be Number One,' said Alice.\n\n  The King turned pale, and shut his note-book hastily.\n`Consider your verdict,' he said to the jury, in a low, trembling\nvoice.\n\n  `There's more evidence to come yet, please your Majesty,' said\nthe White Rabbit, jumping up in a great hurry; `this paper has\njust been picked up.'\n\n  `What's in it?' said the Queen.\n\n  `I haven't opened it yet,' said the White Rabbit, `but it seems\nto be a letter, written by the prisoner to--to somebody.'\n\n  `It must have been that,' said the King, `unless it was\nwritten to nobody, which isn't usual, you know.'\n\n  `Who is it directed to?' said one of the jurymen.\n\n  `It isn't directed at all,' said the White Rabbit; `in fact,\nthere's nothing written on the OUTSIDE.'  He unfolded the paper\nas he spoke, and added `It isn't a letter, after all:  it's a set\nof verses.'\n\n  `Are they in the prisoner's handwriting?' asked another of\nthe jurymen.\n\n  `No, they're not,' said the White Rabbit, `and that's the\nqueerest thing about it.'  (The jury all looked puzzled.)\n\n  `He must have imitated somebody else's hand,' said the King.\n(The jury all brightened up again.)\n\n  `Please your Majesty,' said the Knave, `I didn't write it, and\nthey can't prove I did:  there's no name signed at the end.'\n\n  `If you didn't sign it,' said the King, `that only makes the\nmatter worse.  You MUST have meant some mischief, or else you'd\nhave signed your name like an honest man.'\n\n  There was a general clapping of hands at this:  it was the\nfirst really clever thing the King had said that day.\n\n  `That PROVES his guilt,' said the Queen.\n\n  `It proves nothing of the sort!' said Alice.  `Why, you don't\neven know what they're about!'\n\n  `Read them,' said the King.\n\n  The White Rabbit put on his spectacles.  `Where shall I begin,\nplease your Majesty?' he asked.\n\n  `Begin at the beginning,' the King said gravely, `and go on\ntill you come to the end:  then stop.'\n\n  These were the verses the White Rabbit read:--\n\n        `They told me you had been to her,\n          And mentioned me to him:\n        She gave me a good character,\n          But said I could not swim.\n\n        He sent them word I had not gone\n          (We know it to be true):\n        If she should push the matter on,\n          What would become of you?\n\n        I gave her one, they gave him two,\n          You gave us three or more;\n        They all returned from him to you,\n          Though they were mine before.\n\n        If I or she should chance to be\n          Involved in this affair,\n        He trusts to you to set them free,\n          Exactly as we were.\n\n        My notion was that you had been\n          (Before she had this fit)\n        An obstacle that came between\n          Him, and ourselves, and it.\n\n        Don't let him know she liked them best,\n          For this must ever be\n        A secret, kept from all the rest,\n          Between yourself and me.'\n\n  `That's the most important piece of evidence we've heard yet,'\nsaid the King, rubbing his hands; `so now let the jury--'\n\n  `If any one of them can explain it,' said Alice, (she had\ngrown so large in the last few minutes that she wasn't a bit\nafraid of interrupting him,) `I'll give him sixpence.  _I_ don't\nbelieve there's an atom of meaning in it.'\n\n  The jury all wrote down on their slates, `SHE doesn't believe\nthere's an atom of meaning in it,' but none of them attempted to\nexplain the paper.\n\n  `If there's no meaning in it,' said the King, `that saves a\nworld of trouble, you know, as we needn't try to find any.  And\nyet I don't know,' he went on, spreading out the verses on his\nknee, and looking at them with one eye; `I seem to see some\nmeaning in them, after all.  \"--SAID I COULD NOT SWIM--\" you\ncan't swim, can you?' he added, turning to the Knave.\n\n  The Knave shook his head sadly.  `Do I look like it?' he said.\n(Which he certainly did NOT, being made entirely of cardboard.)\n\n  `All right, so far,' said the King, and he went on muttering\nover the verses to himself:  `\"WE KNOW IT TO BE TRUE--\" that's\nthe jury, of course-- \"I GAVE HER ONE, THEY GAVE HIM TWO--\" why,\nthat must be what he did with the tarts, you know--'\n\n  `But, it goes on \"THEY ALL RETURNED FROM HIM TO YOU,\"' said\nAlice.\n\n  `Why, there they are!' said the King triumphantly, pointing to\nthe tarts on the table.  `Nothing can be clearer than THAT.\nThen again--\"BEFORE SHE HAD THIS FIT--\"  you never had fits, my\ndear, I think?' he said to the Queen.\n\n  `Never!' said the Queen furiously, throwing an inkstand at the\nLizard as she spoke.  (The unfortunate little Bill had left off\nwriting on his slate with one finger, as he found it made no\nmark; but he now hastily began again, using the ink, that was\ntrickling down his face, as long as it lasted.)\n\n  `Then the words don't FIT you,' said the King, looking round\nthe court with a smile.  There was a dead silence.\n\n  `It's a pun!' the King added in an offended tone, and\neverybody laughed, `Let the jury consider their verdict,' the\nKing said, for about the twentieth time that day.\n\n  `No, no!' said the Queen.  `Sentence first--verdict afterwards.'\n\n  `Stuff and nonsense!' said Alice loudly.  `The idea of having\nthe sentence first!'\n\n  `Hold your tongue!' said the Queen, turning purple.\n\n  `I won't!' said Alice.\n\n  `Off with her head!' the Queen shouted at the top of her voice.\nNobody moved.\n\n  `Who cares for you?' said Alice, (she had grown to her full\nsize by this time.)  `You're nothing but a pack of cards!'\n\n  At this the whole pack rose up into the air, and came flying\ndown upon her:  she gave a little scream, half of fright and half\nof anger, and tried to beat them off, and found herself lying on\nthe bank, with her head in the lap of her sister, who was gently\nbrushing away some dead leaves that had fluttered down from the\ntrees upon her face.\n\n  `Wake up, Alice dear!' said her sister; `Why, what a long\nsleep you've had!'\n\n  `Oh, I've had such a curious dream!' said Alice, and she told\nher sister, as well as she could remember them, all these strange\nAdventures of hers that you have just been reading about; and\nwhen she had finished, her sister kissed her, and said, `It WAS a\ncurious dream, dear, certainly:  but now run in to your tea; it's\ngetting late.'  So Alice got up and ran off, thinking while she\nran, as well she might, what a wonderful dream it had been.\n\n  But her sister sat still just as she left her, leaning her\nhead on her hand, watching the setting sun, and thinking of\nlittle Alice and all her wonderful Adventures, till she too began\ndreaming after a fashion, and this was her dream:--\n\n  First, she dreamed of little Alice herself, and once again the\ntiny hands were clasped upon her knee, and the bright eager eyes\nwere looking up into hers--she could hear the very tones of her\nvoice, and see that queer little toss of her head to keep back\nthe wandering hair that WOULD always get into her eyes--and\nstill as she listened, or seemed to listen, the whole place\naround her became alive the strange creatures of her little\nsister's dream.\n\n  The long grass rustled at her feet as the White Rabbit hurried\nby--the frightened Mouse splashed his way through the\nneighbouring pool--she could hear the rattle of the teacups as\nthe March Hare and his friends shared their never-ending meal,\nand the shrill voice of the Queen ordering off her unfortunate\nguests to execution--once more the pig-baby was sneezing on the\nDuchess's knee, while plates and dishes crashed around it--once\nmore the shriek of the Gryphon, the squeaking of the Lizard's\nslate-pencil, and the choking of the suppressed guinea-pigs,\nfilled the air, mixed up with the distant sobs of the miserable\nMock Turtle.\n\n  So she sat on, with closed eyes, and half believed herself in\nWonderland, though she knew she had but to open them again, and\nall would change to dull reality--the grass would be only\nrustling in the wind, and the pool rippling to the waving of the\nreeds--the rattling teacups would change to tinkling sheep-\nbells, and the Queen's shrill cries to the voice of the shepherd\nboy--and the sneeze of the baby, the shriek of the Gryphon, and\nall thy other queer noises, would change (she knew) to the\nconfused clamour of the busy farm-yard--while the lowing of the\ncattle in the distance would take the place of the Mock Turtle's\nheavy sobs.\n\n  Lastly, she pictured to herself how this same little sister of\nhers would, in the after-time, be herself a grown woman; and how\nshe would keep, through all her riper years, the simple and\nloving heart of her childhood:  and how she would gather about\nher other little children, and make THEIR eyes bright and eager\nwith many a strange tale, perhaps even with the dream of\nWonderland of long ago:  and how she would feel with all their\nsimple sorrows, and find a pleasure in all their simple joys,\nremembering her own child-life, and the happy summer days.\n\n                             THE END\n\u001a\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/cabi2.cpp",
    "content": "\n#include <assert.h>\n#include <stdio.h>\n#include <stdint.h>\n\n#if __cplusplus\nextern \"C\" {\n#endif\n\nstruct Foo1 { char c; };\n\nstruct Foo1 ctest1()\n{\n    struct Foo1 f;\n\n    f.c = 3;\n    return f;\n}\n\nstruct Foo2 { short s; };\n\nstruct Foo2 ctest2()\n{\n    struct Foo2 f;\n\n    f.s = 0x1234;\n    return f;\n}\n\nstruct Foo3 { char c; short s; };\n\nstruct Foo3 ctest3()\n{\n    struct Foo3 f;\n\n    f.s = 0x5678;\n    return f;\n}\n\n\nstruct Foo4 { int i; };\n\nstruct Foo4 ctest4()\n{\n    struct Foo4 f;\n\n    f.i = 0x12345678;\n    return f;\n}\n\nstruct Foo5 { int i, j; };\n\nstruct Foo5 ctest5()\n{\n    struct Foo5 f;\n\n    f.i = 0x12345678;\n    f.j = 0x21436587;\n    return f;\n}\n\n\nstruct Foo6 { int i, j, k; };\n\nstruct Foo6 ctest6()\n{\n    struct Foo6 f;\n\n    f.i = 0x12345678;\n    f.j = 0x21463587;\n    f.k = 0x24163857;\n    return f;\n}\n\nstruct S7 { float a,b; };\n\nstruct S7 ctest10()\n{\n    struct S7 f;\n\n    f.a = 2.5;\n    f.b = 1.5;\n    return f;\n}\n\n// =================================\n\nchar ctest7(char c)\n{\n    return c + 1;\n}\n\nunsigned char ctest8(unsigned char c)\n{\n    return c + 1;\n}\n\nsigned char ctest9(signed char c)\n{\n    return c + 1;\n}\n\n/***********************************************/\n\nvoid ctestrir(int x1, int x2, int x3, int x4, int x5, int x6, long double a, int b, long double c)\n{\n    assert(a == 100.0);\n    assert(b == 67);\n    assert(c == 200.0);\n}\n\n/***********************************************/\n\nextern void dtestrir(int x1, int x2, int x3, int x4, int x5, int x6, long double a, int b, long double c);\n\nvoid test4()\n{\n    dtestrir(1,2,3,4,5,6, 300.0, 68, 401.0);\n}\n\n/**********************************************/\n\ntypedef struct S11 {\n  char a;\n  char b;\n  char c;\n} S11;\n\nS11 ctest11(char x, S11 s, char y) {\n  printf(\"C sz = %d\\n\", (int)sizeof(S11));\n  assert(sizeof(S11) == 3);\n  printf(\"x   = %d\\n\", (int)x);\n  printf(\"s.a = %d\\n\", (int)s.a);\n  printf(\"s.b = %d\\n\", (int)s.b);\n  printf(\"s.c = %d\\n\", (int)s.c);\n  printf(\"y   = %d\\n\", (int)y);\n  return s;\n}\n\n/**********************************************/\n\ntypedef struct S12 {\n  char a,d;\n  char b,e;\n  char c;\n} S12;\n\nS12 ctest12(char x, S12 s, char y) {\n  printf(\"C sz = %d\\n\", (int)sizeof(S12));\n  assert(sizeof(S12) == 5);\n  printf(\"x   = %d\\n\", (int)x);\n  printf(\"s.a = %d\\n\", (int)s.a);\n  printf(\"s.b = %d\\n\", (int)s.b);\n  printf(\"s.c = %d\\n\", (int)s.c);\n  printf(\"y   = %d\\n\", (int)y);\n  return s;\n}\n\n\n/**********************************************/\n\ntypedef struct S13 {\n  short a;\n  short b;\n  short c;\n} S13;\n\nS13 ctest13(char x, S13 s, char y) {\n  printf(\"C sz = %d\\n\", (int)sizeof(S13));\n  assert(sizeof(S13) == 6);\n  printf(\"x   = %d\\n\", (int)x);\n  printf(\"s.a = %d\\n\", (int)s.a);\n  printf(\"s.b = %d\\n\", (int)s.b);\n  printf(\"s.c = %d\\n\", (int)s.c);\n  printf(\"y   = %d\\n\", (int)y);\n  return s;\n}\n\n\n/**********************************************/\n\ntypedef struct S14 {\n  char a,d,e,f;\n  char b,g;\n  char c;\n} S14;\n\nS14 ctest14(char x, S14 s, char y) {\n  printf(\"C sz = %d\\n\", (int)sizeof(S14));\n  assert(sizeof(S14) == 7);\n  printf(\"x   = %d\\n\", (int)x);\n  printf(\"s.a = %d\\n\", (int)s.a);\n  printf(\"s.b = %d\\n\", (int)s.b);\n  printf(\"s.c = %d\\n\", (int)s.c);\n  printf(\"y   = %d\\n\", (int)y);\n  return s;\n}\n\n\n/**********************************************/\n\ntypedef struct S15 {\n  char a,d,e,f;\n  char b,g,h,i;\n  char c;\n} S15;\n\nS15 ctest15(char x, S15 s, char y) {\n  printf(\"C sz = %d\\n\", (int)sizeof(S15));\n  assert(sizeof(S15) == 9);\n  printf(\"x   = %d\\n\", (int)x);\n  printf(\"s.a = %d\\n\", (int)s.a);\n  printf(\"s.b = %d\\n\", (int)s.b);\n  printf(\"s.c = %d\\n\", (int)s.c);\n  printf(\"y   = %d\\n\", (int)y);\n  return s;\n}\n\n\n/**********************************************/\n\ntypedef struct S16 {\n  char a[5];\n#ifdef __GNUC__\n  struct __attribute__((packed))\n#else\n  #pragma pack(push, 1)\n  struct\n#endif\n  {\n    char b;\n    int c;\n  };\n#ifndef __GNUC__\n  #pragma pack(pop)\n#endif\n} S16;\n\nS16 ctest16(char x, S16 s, char y) {\n  printf(\"C sz = %d\\n\", (int)sizeof(S16));\n  assert(sizeof(S16) == 10);\n  printf(\"x   = %d\\n\", (int)x);\n  printf(\"s.a = %.*s\\n\", 5, s.a);\n  printf(\"s.b = %d\\n\", (int)s.b);\n  printf(\"s.c = %d\\n\", s.c);\n  printf(\"y   = %d\\n\", (int)y);\n  return s;\n}\n\n\n\n#if __cplusplus\n}\n#endif\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/cpp_abi_tests.cpp",
    "content": "struct S{\n    float a;\n};\n\nnamespace std\n{\n    struct test19248 {int a;};\n};\n\nbool               passthrough(bool                value)     { return value; }\nsigned char        passthrough(signed char         value)     { return value; }\nunsigned char      passthrough(unsigned char       value)     { return value; }\nchar               passthrough(char                value)     { return value; }\nwchar_t            passthrough(wchar_t             value)     { return value; }\nshort              passthrough(short               value)     { return value; }\nunsigned short     passthrough(unsigned short      value)     { return value; }\nint                passthrough(int                 value)     { return value; }\nunsigned int       passthrough(unsigned int        value)     { return value; }\nlong               passthrough(long                value)     { return value; }\nunsigned long      passthrough(unsigned long       value)     { return value; }\nlong long          passthrough(long long           value)     { return value; }\nunsigned long long passthrough(unsigned long long  value)     { return value; }\nfloat              passthrough(float               value)     { return value; }\ndouble             passthrough(double              value)     { return value; }\nS                  passthrough(S                   value)     { return value; }\nstd::test19248     passthrough(const std::test19248 value)     { return value; }\n\nbool               passthrough_ptr(bool               *value) { return *value; }\nsigned char        passthrough_ptr(signed char        *value) { return *value; }\nunsigned char      passthrough_ptr(unsigned char      *value) { return *value; }\nchar               passthrough_ptr(char               *value) { return *value; }\nwchar_t            passthrough_ptr(wchar_t            *value) { return *value; }\nshort              passthrough_ptr(short              *value) { return *value; }\nunsigned short     passthrough_ptr(unsigned short     *value) { return *value; }\nint                passthrough_ptr(int                *value) { return *value; }\nunsigned int       passthrough_ptr(unsigned int       *value) { return *value; }\nlong               passthrough_ptr(long               *value) { return *value; }\nunsigned long      passthrough_ptr(unsigned long      *value) { return *value; }\nlong long          passthrough_ptr(long long          *value) { return *value; }\nunsigned long long passthrough_ptr(unsigned long long *value) { return *value; }\nfloat              passthrough_ptr(float              *value) { return *value; }\ndouble             passthrough_ptr(double             *value) { return *value; }\nS                  passthrough_ptr(S                  *value) { return *value; }\nstd::test19248     passthrough_ptr(const std::test19248 *value) { return *value; }\n\nbool               passthrough_ref(bool               &value) { return value; }\nsigned char        passthrough_ref(signed char        &value) { return value; }\nunsigned char      passthrough_ref(unsigned char      &value) { return value; }\nchar               passthrough_ref(char               &value) { return value; }\nwchar_t            passthrough_ref(wchar_t            &value) { return value; }\nshort              passthrough_ref(short              &value) { return value; }\nunsigned short     passthrough_ref(unsigned short     &value) { return value; }\nint                passthrough_ref(int                &value) { return value; }\nunsigned int       passthrough_ref(unsigned int       &value) { return value; }\nlong               passthrough_ref(long               &value) { return value; }\nunsigned long      passthrough_ref(unsigned long      &value) { return value; }\nlong long          passthrough_ref(long long          &value) { return value; }\nunsigned long long passthrough_ref(unsigned long long &value) { return value; }\nfloat              passthrough_ref(float              &value) { return value; }\ndouble             passthrough_ref(double             &value) { return value; }\nS                  passthrough_ref(S                  &value) { return value; }\nstd::test19248     passthrough_ref(const std::test19248 &value) { return value; }\n\n// Uncomment when mangling is fixed\n// typedef void(*fn0)();\n// fn0            passthrough_fn0   (fn0 value) { return value; }\n// typedef int (*fn1)(int);\n// fn1            passthrough_fn1   (fn1 value) { return value; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/cpp_stdlib.cpp",
    "content": "#include <array>\n#include <string>\n#include <vector>\n\ntemplate<typename T>\nT& identity (T& v) { return v; }\ntemplate<typename T>\nT** identityPP (T** v) { return v; }\n\ntemplate<typename T>\nstd::vector<T>* getVector(size_t len, const T* ptr)\n{\n    std::vector<T>* ret = new std::vector<T>(len);\n    for (size_t i = 0; i < len; ++i)\n        (*ret)[i] = ptr[i];\n    return ret;\n}\n\nstd::string* getString(int len, const char* ptr)\n{\n    return new std::string(ptr, len);\n}\n\ntemplate<typename T, size_t N>\nstd::array<T, N>* getArray(const T* ptr)\n{\n    std::array<T, N>* ret = new std::array<T, N>();\n    for (size_t x = 0; x < N; ++x)\n        (*ret)[x] = ptr[x];\n    return ret;\n}\n\n// This function should never be called\nvoid instantiate ()\n{\n    int i;\n    float f;\n    int* pi;\n    float* pf;\n\n    identityPP(&pi);\n    identityPP(&pf);\n    identity(i);\n    identity(f);\n\n    getVector<int>(0, 0);\n    getVector<float>(0, 0);\n    getVector<std::vector<float> >(0, 0);\n\n    getArray<int, 4>(0);\n    getArray<float, 4>(0);\n    //getArray<Foo<int, 42>, 4>(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/cppb.cpp",
    "content": "/*\nGCC 5.1 introduced new implementations of std::string and std::list:\n\nhttps://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html\n\nThis causes e.g. std::string to be actually defined as\nstd::__cxx11::string.\n\nOn machines with GCC 5.1, this manifests as a linker error when\nrunning the cppa.d / cppb.cpp test:\n\ncppa.o: In function `_D4cppa6test14FZv':\ncppa.d:(.text._D4cppa6test14FZv+0x11): undefined reference to `foo14a(std::string*)'\ncppa.d:(.text._D4cppa6test14FZv+0x18): undefined reference to `foo14b(std::basic_string<int, std::char_traits<int>, std::allocator<int> >*)'\ncppa.d:(.text._D4cppa6test14FZv+0x3a): undefined reference to `foo14f(std::char_traits<char>*, std::string*, std::string*)'\ncppa.o: In function `_D4cppa7testeh3FZv':\ncppa.d:(.text._D4cppa7testeh3FZv+0x19): undefined reference to `throwle()'\ncollect2: error: ld returned 1 exit status\n--- errorlevel 1\n\nWhen the .cpp file is compiled with g++ 5.3.0, the actual function\nsignatures in the cppb.o object file are:\n\nfoo14a(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)\nfoo14b(std::__cxx11::basic_string<int, std::char_traits<int>, std::allocator<int> >*)\nfoo14f(std::char_traits<char>*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)\n\nFortunately, it is easily possible to disable the new feature\nby defining _GLIBCXX_USE_CXX11_ABI as 0 before including any standard\nheaders.\n*/\n#define _GLIBCXX_USE_CXX11_ABI 0\n\n#include <stdio.h>\n#include <stdint.h>\n#include <assert.h>\n#include <exception>\n#include <cstdarg>\n\n#include \"cppb.h\"\n\n/**************************************/\n\nint foo(int i, int j, int k);\n\nint foob(int i, int j, int k)\n{\n    printf(\"i = %d\\n\", i);\n    printf(\"j = %d\\n\", j);\n    printf(\"k = %d\\n\", k);\n    assert(i == 1);\n    assert(j == 2);\n    assert(k == 3);\n\n    foo(i, j, k);\n\n    return 7;\n}\n\n/**************************************/\n\nclass D *dthis;\n\nclass D\n{\n  public:\n    virtual int bar(int i, int j, int k)\n    {\n    printf(\"this = %p\\n\", this);\n    assert(this == dthis);\n    printf(\"D.bar: i = %d\\n\", i);\n    printf(\"D.bar: j = %d\\n\", j);\n    printf(\"D.bar: k = %d\\n\", k);\n    assert(i == 9);\n    assert(j == 10);\n    assert(k == 11);\n    return 8;\n    }\n};\n\n\nD* getD()\n{\n    D *d = new D();\n    dthis = d;\n    return d;\n}\n\n/**************************************/\n\nclass E\n{\n  public:\n    virtual int bar(int i, int j, int k);\n};\n\n\nint callE(E *e)\n{\n    return e->bar(11,12,13);\n}\n\n/**************************************/\n\nvoid foo4(char *p)\n{\n}\n\n/**************************************/\n\nstruct foo5 { int i; int j; void *p; };\n\nclass bar5\n{\npublic:\n  virtual foo5 getFoo(int i){\n    printf(\"This = %p\\n\", this);\n    foo5 f;\n    f.i = 1;\n    f.j = 2 + i;\n    f.p = (void*)this;\n    return f;\n  }\n};\n\nbar5* newBar()\n{\n  bar5* b = new bar5();\n  printf(\"bar = %p\\n\", b);\n  return b;\n}\n\n\n/**************************************/\n\nstruct A11802;\nstruct B11802;\n\nclass C11802\n{\npublic:\n    virtual void fun(A11802 *);\n    virtual void fun(B11802 *);\n};\n\nclass D11802 : public C11802\n{\npublic:\n    void fun(A11802 *);\n    void fun(B11802 *);\n};\n\nvoid test11802x(D11802 *c)\n{\n    c->fun((A11802 *)0);\n    c->fun((B11802 *)0);\n}\n\n/**************************************/\n\ntypedef struct\n{\n    int i;\n    double d;\n} S6;\n\nunion S6_2\n{\n    int i;\n    double d;\n};\n\nenum S6_3\n{\n    A, B\n};\n\n\nS6 foo6(void)\n{\n    S6 s;\n    s.i = 42;\n    s.d = 2.5;\n    return s;\n}\n\nS6_2 foo6_2(void)\n{\n    S6_2 s;\n    s.i = 42;\n    return s;\n}\n\nS6_3 foo6_3(void)\n{\n    S6_3 s = A;\n    return s;\n}\n\nextern \"C\" { int foosize6()\n{\n    return sizeof(S6);\n}\n}\n\n/**************************************/\n\ntypedef struct\n{\n    int i;\n    long long d;\n} S7;\n\nextern \"C\" { int foo7()\n{\n    return sizeof(S7);\n}\n}\n\n/**************************************/\n\nstruct S13955a\n{\n    float a;\n    double b;\n};\n\nstruct S13955b\n{\n    double a;\n    float b;\n};\n\nstruct S13955c\n{\n    float a;\n    float b;\n};\n\nstruct S13955d\n{\n    double a;\n    double b;\n};\n\nvoid check13955(S13955a a, S13955b b, S13955c c, S13955d d);\n\nvoid func13955(S13955a a, S13955b b, S13955c c, S13955d d)\n{\n    check13955(a, b, c, d);\n}\n\n/**************************************/\n\nstruct Struct10071\n{\n    void *p;\n    long double r;\n};\n\nsize_t offset10071()\n{\n    Struct10071 s;\n    return (char *)&s.r - (char *)&s;\n}\n\n/**************************************/\n\nvoid foo8(const char *p)\n{\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4059\n\nstruct elem9 { };\nvoid foobar9(elem9*, elem9*) { }\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5148\n\nvoid foo10(const char*, const char*) { }\nvoid foo10(const int, const int) { }\nvoid foo10(const char, const char) { }\nvoid foo10(bool, bool) { }\n\nstruct MyStructType { };\nvoid foo10(const MyStructType s, const MyStructType t) { }\n\nenum MyEnumType { onemember };\nvoid foo10(const MyEnumType s, const MyEnumType t) { }\n\n/**************************************/\n\nnamespace N11 { namespace M { void bar11() { } } }\n\nnamespace A11 { namespace B { namespace C { void bar() { } } } }\n\n/**************************************/\n\nvoid myvprintfx(const char* format, va_list);\n\nvoid myvprintf(const char* format, va_list va)\n{\n    myvprintfx(format, va);\n}\n\n/**************************************/\n\nclass C13161\n{\npublic:\n        virtual void dummyfunc() {}\n        long long val_5;\n        unsigned val_9;\n};\n\nclass Test : public C13161\n{\npublic:\n        unsigned val_0;\n        long long val_1;\n};\n\nsize_t getoffset13161()\n{\n    Test s;\n    return (char *)&s.val_0 - (char *)&s;\n}\n\nclass C13161a\n{\npublic:\n        virtual void dummyfunc() {}\n        long double val_5;\n        unsigned val_9;\n};\n\nclass Testa : public C13161a\n{\npublic:\n        bool val_0;\n};\n\nsize_t getoffset13161a()\n{\n    Testa s;\n    return (char *)&s.val_0 - (char *)&s;\n}\n\n/****************************************************/\n\n#if __linux__ || __APPLE__ || __FreeBSD__ || __DragonFly__\n#include <memory>\n#include <vector>\n#include <string>\n\n#if __linux__\ntemplate struct std::allocator<int>;\ntemplate struct std::vector<int>;\n\nvoid foo15()\n{\n    std::allocator<int>* p;\n    p->deallocate(0, 0);\n}\n\n#endif\n\n// _Z5foo14PSt6vectorIiSaIiEE\nvoid foo14(std::vector<int, std::allocator<int> > *p) { }\n\nvoid foo14a(std::basic_string<char> *p) { }\nvoid foo14b(std::basic_string<int> *p) { }\nvoid foo14c(std::basic_istream<char> *p) { }\nvoid foo14d(std::basic_ostream<char> *p) { }\nvoid foo14e(std::basic_iostream<char> *p) { }\n\nvoid foo14f(std::char_traits<char>* x, std::basic_string<char> *p, std::basic_string<char> *q) { }\n\n#endif\n\n/**************************************/\n\nstruct S13956\n{\n};\n\nvoid check13956(S13956 arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);\n\nvoid func13956(S13956 arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)\n{\n    check13956(arg0, arg1, arg2, arg3, arg4, arg5, arg6);\n}\n\n/**************************************/\n\nwchar_t f13289_cpp_wchar_t(wchar_t ch)\n{\n    if (ch <= L'z' && ch >= L'a')\n    {\n        return ch - (L'a' - L'A');\n    }\n    else\n    {\n        return ch;\n    }\n}\n\n#if __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun || __NetBSD__ || __DragonFly__\nunsigned short f13289_d_wchar(unsigned short ch);\nwchar_t f13289_d_dchar(wchar_t ch);\n#elif _WIN32\nwchar_t f13289_d_wchar(wchar_t ch);\nunsigned int f13289_d_dchar(unsigned int ch);\n#endif\n\nbool f13289_cpp_test()\n{\n#if __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun || __NetBSD__ || __DragonFly__\n    if (!(f13289_d_wchar((unsigned short)'c') == (unsigned short)'C')) return false;\n    if (!(f13289_d_wchar((unsigned short)'D') == (unsigned short)'D')) return false;\n    if (!(f13289_d_dchar(L'e') == L'E')) return false;\n    if (!(f13289_d_dchar(L'F') == L'F')) return false;\n    return true;\n#elif _WIN32\n    if (!(f13289_d_wchar(L'c') == L'C')) return false;\n    if (!(f13289_d_wchar(L'D') == L'D')) return false;\n    if (!(f13289_d_dchar((unsigned int)'e') == (unsigned int)'E')) return false;\n    if (!(f13289_d_dchar((unsigned int)'F') == (unsigned int)'F')) return false;\n    return true;\n#else\n    return false;\n#endif\n}\n\n/******************************************/\n\nlong double testld(long double ld)\n{\n    assert(ld == 5);\n    return ld + 1;\n}\n\nlong testl(long lng)\n{\n    assert(lng == 5);\n    return lng + sizeof(long);\n}\n\nunsigned long testul(unsigned long ul)\n{\n    assert(ul == 5);\n    return ul + sizeof(unsigned long);\n}\n\n/******************************************/\n\nstruct S13707\n{\n    void* a;\n    void* b;\n    S13707(void *a, void* b)\n    {\n        this->a = a;\n        this->b = b;\n    }\n};\n\nS13707 func13707()\n{\n    S13707 pt(NULL, NULL);\n    return pt;\n}\n\n/******************************************/\n\ntemplate <int x> struct S13932\n{\n    int member;\n};\n\nvoid func13932(S13932<-1> s) {}\n\n/******************************************/\n\nnamespace N13337 {\n  namespace M13337 {\n    struct S13337 { };\n    void foo13337(S13337 s) { }\n  }\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14195\n\ntemplate <typename T>\nstruct Delegate1 {};\n\ntemplate <typename R1>\nstruct Delegate1 < R1() > {};\n\ntemplate <typename T1, typename T2>\nstruct Delegate2 {};\n\ntemplate < typename R1, typename T1, typename T2, typename R2, typename T3, typename T4 >\nstruct Delegate2<R1(T1, T2), R2(T3, T4)> {};\n\nvoid test14195a(Delegate1<void()> func) {}\n\nvoid test14195b(Delegate2<int(float, double), int(float, double)> func) {}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14200\n\nvoid test14200a(int a) {};\nvoid test14200b(float a, int b, double c) {};\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14956\n\nnamespace std {\n    namespace N14956 {\n    struct S14956 { };\n    }\n}\n\nvoid test14956(std::N14956::S14956 s) { }\n\n/******************************************/\n// check order of overloads in vtable\n\nclass Statement;\nclass ErrorStatement;\nclass PeelStatement;\nclass ExpStatement;\nclass DtorExpStatement;\n\nclass Visitor\n{\npublic:\n    virtual int visit(Statement*) { return 1; }\n    virtual int visit(ErrorStatement*) { return 2; }\n    virtual int visit(PeelStatement*) { return 3; }\n};\n\nclass Visitor2 : public Visitor\n{\npublic:\n    virtual int visit2(ExpStatement*) { return 4; }\n    virtual int visit2(DtorExpStatement*) { return 5; }\n};\n\nbool testVtableCpp(Visitor2* sv)\n{\n    if (sv->visit((Statement*)0) != 1) return false;\n    if (sv->visit((ErrorStatement*)0) != 2) return false;\n    if (sv->visit((PeelStatement*)0) != 3) return false;\n    if (sv->visit2((ExpStatement*)0) != 4) return false;\n    if (sv->visit2((DtorExpStatement*)0) != 5) return false;\n    return true;\n}\n\nVisitor2 inst;\n\nVisitor2* getVisitor2()\n{\n    return &inst;\n}\n\n/******************************************/\n// issues detected by fuzzer\n\nvoid fuzz1_checkValues(int64_t arg10, int64_t arg11, bool arg12);\nvoid fuzz1_cppvararg(int64_t arg10, int64_t arg11, bool arg12)\n{\n    fuzz1_checkValues(arg10, arg11, arg12);\n}\n\nvoid fuzz2_checkValues(uint64_t arg10, uint64_t arg11, bool arg12);\nvoid fuzz2_cppvararg(uint64_t arg10, uint64_t arg11, bool arg12)\n{\n    fuzz2_checkValues(arg10, arg11, arg12);\n}\n\n#if __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun || __NetBSD__ || __DragonFly__\n#define wchar unsigned short\n#elif _WIN32\n#define wchar wchar_t\n#endif\n\nvoid fuzz3_checkValues(wchar arg10, wchar arg11, bool arg12);\nvoid fuzz3_cppvararg(wchar arg10, wchar arg11, bool arg12)\n{\n    fuzz3_checkValues(arg10, arg11, arg12);\n}\n\n/******************************************/\n\nvoid throwit()\n{\n#if _WIN32\n#else\n    std::exception se;\n    throw se;\n#endif\n}\n\n/******************************************/\n\n#if linux\n#include <stdexcept>\n\nvoid throwle()\n{\n     std::logic_error le(\"test\");\n     throw le;\n}\n\n#endif\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15579\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15579\n\nclass Base\n{\npublic:\n    //virtual ~Base() {}\n    virtual void base();\n    unsigned char x;\n};\n\nclass Interface\n{\npublic:\n    virtual int MethodCPP() = 0;\n    virtual int MethodD() = 0;\n};\n\nclass Derived : public Base, public Interface\n{\npublic:\n    Derived();\n    short y;\n    int MethodCPP();\n#if _WIN32 || _WIN64\n    int MethodD();\n    virtual int Method();\n#else\n    int MethodD() { return 3; }  // need def or vtbl[] is not generated\n    virtual int Method()  { return 6; }  // need def or vtbl[] is not generated\n#endif\n};\n\nvoid Base::base() { }\nint Derived::MethodCPP() {\n    printf(\"Derived::MethodCPP() this = %p, x = %d, y = %d\\n\", this, x, y);\n    assert(x == 4 || x == 7);\n    assert(y == 5 || y == 8);\n    return 30;\n}\nDerived::Derived() { }\n\n\nDerived *cppfoo(Derived *d)\n{\n    printf(\"cppfoo(): d = %p\\n\", d);\n    assert(d->x == 4);\n    assert(d->y == 5);\n    assert(d->MethodD() == 3);\n    assert(d->MethodCPP() == 30);\n    assert(d->Method() == 6);\n\n    d = new Derived();\n    d->x = 7;\n    d->y = 8;\n    assert(d->MethodD() == 3);\n    assert(d->MethodCPP() == 30);\n    assert(d->Method() == 6);\n    printf(\"d1 = %p\\n\", d);\n    return d;\n}\n\nInterface *cppfooi(Interface *i)\n{\n    printf(\"cppfooi(): i = %p\\n\", i);\n    assert(i->MethodD() == 3);\n    assert(i->MethodCPP() == 30);\n\n    Derived *d = new Derived();\n    d->x = 7;\n    d->y = 8;\n    printf(\"d = %p, i = %p\\n\", d, (Interface *)d);\n    return d;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15610\n\nclass Base2\n{\n  public:\n    int i;\n    virtual void baser() { }\n};\n\nclass Interface2\n{\n  public:\n    virtual void f() = 0;\n};\n\nclass Derived2 : public Base2, public Interface2\n{\n  public:\n    void f();\n};\n\nvoid Derived2::f()\n{\n    printf(\"Derived2::f() this = %p i = %d\\n\", this, i);\n    assert(i == 3);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15455\n\nstruct X6\n{\n    unsigned short a;\n    unsigned short b;\n    unsigned char c;\n    unsigned char d;\n};\n\nstruct X8\n{\n    unsigned short a;\n    X6 b;\n};\n\nvoid test15455b(X8 s)\n{\n    assert(sizeof(X6) == 6);\n    assert(sizeof(X8) == 8);\n    assert(s.a == 1);\n    assert(s.b.a == 2);\n    assert(s.b.b == 3);\n    assert(s.b.c == 4);\n    assert(s.b.d == 5);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15372\n\ntemplate <typename T>\nint foo15372(int value)\n{\n    return value;\n}\n\nvoid test15372b()\n{\n    int t = foo15372<int>(1);\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15576\n\nnamespace ns15576\n{\n    int global15576;\n\n    namespace ns\n    {\n        int n_global15576;\n    }\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15802\n\ntemplate <typename T>\nclass Foo15802\n{\npublic:\n    static int boo(int value)\n    {\n        return value;\n    }\n};\n\nvoid test15802b()\n{\n    int t = Foo15802<int>::boo(1);\n}\n\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16536\n// mangling mismatch on OSX\n\n#if defined(__APPLE__)\nuint64_t pass16536(uint64_t a)\n{\n    return a;\n}\n#endif\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15589\n// extern(C++) virtual destructors are not put in vtbl[]\n\nclass A15589\n{\npublic:\n    struct S\n    {\n    public:\n        int x;\n    };\n    virtual int foo();\n    virtual ~A15589();\n    S s1;\n    S s2;\n};\nclass B15589 : public A15589\n{\npublic:\n    virtual int bar();\n    virtual ~B15589();\n    S s3;\n};\n\nvoid test15589b(A15589 *p)\n{\n    assert(p->foo() == 100);\n    assert(((B15589*)p)->bar() == 200);\n    p->~A15589();\n}\n\n\n/////////////////\nvoid trace15589(int ch);\n\nCpp15589Base::~Cpp15589Base()\n{\n    trace15589('b');\n}\n\nCpp15589Derived::Cpp15589Derived()\n{\n    b = 1;\n}\n\nCpp15589Derived::~Cpp15589Derived()\n{\n    trace15589('B');\n}\n\nCpp15589BaseVirtual::Cpp15589BaseVirtual()\n{\n    c = 2;\n}\n\nCpp15589BaseVirtual::~Cpp15589BaseVirtual()\n{\n    trace15589('v');\n}\n\nCpp15589DerivedVirtual::Cpp15589DerivedVirtual()\n{\n    d = 3;\n}\n\nCpp15589DerivedVirtual::~Cpp15589DerivedVirtual()\n{\n    trace15589('V');\n}\n\nCpp15589IntroducingVirtual::Cpp15589IntroducingVirtual()\n{\n    e = 4;\n}\n\nCpp15589IntroducingVirtual::~Cpp15589IntroducingVirtual()\n{\n    trace15589('I');\n}\n\nCpp15589Struct::~Cpp15589Struct()\n{\n    trace15589('s');\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18928\n\nstruct Small18928\n{\n    int x;\n};\n\nclass CC18928\n{\npublic:\n    virtual Small18928 getVirtual();\n    Small18928 getFinal();\n    static Small18928 getStatic();\n};\n\nSmall18928 CC18928::getVirtual() { Small18928 s = {3}; return s; }\nSmall18928 CC18928::getFinal()   { Small18928 s = {4}; return s; }\nSmall18928 CC18928::getStatic()  { Small18928 s = {5}; return s; }\n\nCC18928* newCC18928()\n{\n    return new CC18928();\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18966\nBase18966::Base18966() { x = 10; }\nBase18966::~Base18966() {}\nvoid Base18966::vf()\n{\n    x = 100;\n}\n\nA18966::A18966() : calledOverloads(/*zero-init*/), i(0) { foo(); }\nvoid A18966::foo() { calledOverloads[i++] = 'A'; }\n\nB18966::B18966() { foo(); }\nvoid B18966::foo() { calledOverloads[i++] = 'B'; }\n\n#if _WIN32 // otherwise defined in C header files!\n// https://issues.dlang.org/show_bug.cgi?id=18955\nnamespace std\n{\n    template<typename Char>\n    struct char_traits\n    {\n    };\n    template<typename Char>\n    class allocator\n    {\n    };\n    template<typename Char, typename Traits, typename Alloc>\n    class basic_string\n    {\n    };\n    typedef basic_string<char, char_traits<char>, allocator<char> > string;\n}\n#endif // _WIN32\n\nvoid callback18955(const std::string& s);\n\nvoid test18955()\n{\n    std::string s;\n// TODO: on OSX and FreeBSD, std is mangled as std::__1\n#if !__APPLE__ && !__FreeBSD__\n    callback18955(s);\n#endif\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/cppb.h",
    "content": "// avoid declaration in cpp file so the C/C++ compiler does no assume\n// these are inaccessible from elsewhere\nclass Cpp15589Base\n{\npublic:\n    ~Cpp15589Base();\n\n    virtual void nonVirtual() {}\n    int a;\n};\n\nclass Cpp15589Derived : public Cpp15589Base\n{\npublic:\n    Cpp15589Derived();\n    ~Cpp15589Derived();\n    int b;\n};\n\nclass Cpp15589BaseVirtual\n{\npublic:\n    virtual void beforeDtor() {}\n\n    Cpp15589BaseVirtual();\n    virtual ~Cpp15589BaseVirtual();\n\n    virtual void afterDtor() {}\n    int c;\n};\n\nclass Cpp15589DerivedVirtual : public Cpp15589BaseVirtual\n{\npublic:\n    Cpp15589DerivedVirtual(); // explicit C++ ctor needed, see https://issues.dlang.org/show_bug.cgi?id=18966\n    virtual ~Cpp15589DerivedVirtual();\n\n    virtual void afterDtor() {}\n\n    int d;\n};\n\nclass Cpp15589IntroducingVirtual : public Cpp15589Base\n{\npublic:\n    Cpp15589IntroducingVirtual();\n    virtual void beforeIntroducedVirtual() {}\n    virtual ~Cpp15589IntroducingVirtual();\n    virtual void afterIntroducedVirtual(int) {}\n\n    int e;\n};\n\nstruct Cpp15589Struct\n{\n    ~Cpp15589Struct();\n    int s;\n};\n\nclass Base18966\n{\npublic:\n    Base18966();\n    virtual ~Base18966();\n    virtual void vf();\n    int x;\n};\n\nclass A18966\n{\npublic:\n    char calledOverloads[8];\n    int i;\n    A18966();\n    virtual void foo();\n};\n\nclass B18966 : public A18966\n{\npublic:\n    B18966();\n    void foo() /*override*/;\n};\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/depsprot.d",
    "content": "import depsprot_default;\nprivate import depsprot_private;\npublic import depsprot_public;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/externmangle.cpp",
    "content": "#include <stddef.h>\n#include <stdint.h>\n\ntemplate<class X>\nstruct Foo\n{\n    X *v;\n};\n\ntemplate<class X>\nstruct Boo\n{\n    X *v;\n};\n\nvoid test1(Foo<int> arg1)\n{\n}\n\n\nvoid test2(int* arg2, Boo<int*> arg1)\n{\n}\n\ntemplate<int X, int Y>\nstruct Test3\n{\n\n};\n\nvoid test3(Test3<3,3> arg1)\n{\n}\n\nvoid test4(Foo<int*> arg1, Boo<int*> arg2, Boo<int*> arg3, int*, Foo<double>)\n{\n}\n\nvoid test5(Foo<int*> arg1, Boo<int*> arg2, Boo<int*> arg3)\n{\n}\n\nstruct Goo\n{\n\n    template<class X>\n    struct Foo\n    {\n        X* v;\n    };\n\n    template<class X>\n    struct Boo\n    {\n        template<class Y>\n        struct Xoo\n        {\n            Y* v;\n        };\n        X* v;\n    };\n\n\n    void test6(Foo<Boo<Foo<void> > > arg1);\n    void test7(Boo<void>::Xoo<int> arg1);\n};\n\nvoid Goo::test6(Goo::Foo<Goo::Boo<Goo::Foo<void> > > arg1)\n{\n}\n\nvoid Goo::test7(Goo::Boo<void>::Xoo<int> arg1)\n{\n}\n\nstruct P1\n{\n    template<class T>\n    struct Mem\n    {\n    };\n};\n\nstruct P2\n{\n    template<class T>\n    struct Mem\n    {\n    };\n};\n\nvoid test8(P1::Mem<int>, P2::Mem<int>){}\nvoid test9(Foo<int**>, Foo<int*>, int**, int*){}\n\n\n\nclass Test10\n{\n    private: void test10();\n    public: void test11();\n    protected: void test12();\n    public: void test13() const;\n\n    private: void test14(); // Private methods in D are always non-virtual\n    public: virtual void test15();\n    protected: virtual void test16();\n\n    private: static void test17();\n    public: static void test18();\n    protected: static void test19();\n};\n\nTest10* Test10Ctor()\n{\n    return new Test10();\n}\n\nvoid Test10Dtor(Test10*& ptr)\n{\n    delete ptr;\n    ptr = 0;\n}\n\nvoid Test10::test10(){}\nvoid Test10::test11(){}\nvoid Test10::test12(){}\nvoid Test10::test13() const{}\nvoid Test10::test14(){}\nvoid Test10::test15(){}\nvoid Test10::test16(){}\nvoid Test10::test17(){}\nvoid Test10::test18(){}\nvoid Test10::test19(){}\n\nstruct Test20\n{\n    private: static int test20;\n    protected: static int test21;\n    public: static int test22;\n};\n\nint Test20::test20 = 20;\nint Test20::test21 = 21;\nint Test20::test22 = 22;\n\nint test23(Test10**, Test10*, Test10***, Test10 const *const)\n{\n    return 1;\n}\n\nint test23b(Test10 const *const *const,  Test10 const* const, Test10*)\n{\n    return 1;\n}\n\nvoid test24(int(*)(int,int))\n{\n}\n\nvoid test25(int arr[2][5][6][291])\n{\n}\n\nint test26(int arr[5][6][291])\n{\n    return arr[1][1][1];\n}\n\nvoid test27(int, ...){}\nvoid test28(int){}\n\nvoid test29(float){}\nvoid test30(const float){}\n\ntemplate<class T>\nstruct Array\n{\n    int dim;\n};\n\nclass Module\n{\npublic:\n    static void imports(Module*);\n    static int dim(Array<Module*>*);\n};\n\n\nvoid Module::imports(Module*)\n{\n}\n\nint Module::dim(Array<Module*>* arr)\n{\n    return arr->dim;\n}\n\nuint64_t testlongmangle(int a, unsigned int b, int64_t c, uint64_t d)\n{\n    return a + b + c + d;\n}\n\nunsigned long testCppLongMangle(long a, unsigned long b)\n{\n    return a + b;\n}\n\nunsigned long long testCppLongLongMangle(long long a, unsigned long long b)\n{\n    return a + b;\n}\n\nsize_t testCppSizeTMangle(ptrdiff_t a, size_t b)\n{\n    return a + b;\n}\n\nint test31[2][2][2] = {1, 1, 1, 1, 1, 1, 1, 1};\nint *test32 = 0;\n\n\n\nclass Expression;\n\ntypedef int (*apply_fp_t)(Expression*, void*);\n\nclass Expression\n{\n    int type;\npublic:\n    int apply(apply_fp_t fp, apply_fp_t fp2, void *param);\n    int getType();\n    static Expression* create(int v);\n    static void dispose(Expression*&);\n};\n\nint Expression::apply(apply_fp_t fp, apply_fp_t fp2, void *param)\n{\n    return fp(this, param) * fp2(this, param);\n}\n\nint Expression::getType()\n{\n    return type;\n}\n\nExpression* Expression::create(int v)\n{\n    Expression *e = new Expression();\n    e->type = v;\n    return e;\n}\n\nvoid Expression::dispose(Expression *&e)\n{\n    if (e)\n        delete e;\n    e = 0;\n}\n\n/*int test34(int v[0][0][0])\n{\n    return 0;\n}*/\n\n#ifndef _MSC_VER\n    int test35(long double arg)\n    {\n        return (int)arg;\n    }\n#endif\n\nconst char *test36(const char *arg)\n{\n    return arg;\n}\n\nclass Test37\n{\npublic:\n    static Test37 *create();\n    bool test();\n};\n\nbool test37()\n{\n    Test37 *o = Test37::create();\n    return o->test();\n}\n\nclass Test38\n{\npublic:\n     int test(int, ...);\n     static Test38* create();\n     static void dispose(Test38*&);\n};\n\nint Test38::test(int a, ...)\n{\n    return a;\n}\n\nTest38* Test38::create()\n{\n    Test38 *t = new Test38();\n    return t;\n}\n\nvoid Test38::dispose(Test38 *&t)\n{\n    if (t)\n        delete t;\n    t = 0;\n}\n\nclass S1\n{\n    int val;\npublic:\n    static S1* init(int);\n    S1(int v) : val(v) {}\n    int value();\n};\n\nS1* S1::init(int x)\n{\n    return new S1(x);\n}\n\nint S1::value()\n{\n    return val;\n}\n\ntemplate<class T>\nclass S2\n{\n    T val;\npublic:\n    static S2<T>* init(T);\n    S2(T v) : val(v) {}\n    T value();\n};\n\ntemplate<>\nS2<int>* S2<int>::init(int x)\n{\n    return new S2<int>(x);\n}\n\ntemplate<>\nint S2<int>::value()\n{\n    return val;\n}\n\nstruct C1\n{\n    const char *data;\n\n    static C1* init(const char *p);\n\n    C1(const char* p) : data(p) { }\n\n    virtual const char* getDataCPP();\n    virtual const char* getDataD();\n};\n\nC1* C1::init(const char *p)\n{\n    return new C1(p);\n}\n\nconst char* C1::getDataCPP()\n{\n    return data;\n}\n\ntemplate<class T>\nstruct C2\n{\n    const T *data;\n\n    static C2* init(const T *p);\n\n    C2(const T* p) : data(p) { }\n\n    virtual const T* getData();\n};\n\ntemplate<>\nC2<char>* C2<char>::init(const char *p)\n{\n    return new C2<char>(p);\n}\n\ntemplate<>\nconst char* C2<char>::getData()\n{\n    return data;\n}\n\nint test39cpp(C2<char>* c2, S2<int>* s2)\n{\n    C2<char>* otherC2 = C2<char>::init(c2->getData());\n    if (c2->getData() != otherC2->getData())\n        return 1;\n    S2<int>* otherS2 = S2<int>::init(s2->value());\n    if (s2->value() != otherS2->value())\n        return 2;\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/externmangle2.cpp",
    "content": "\nstruct Test32NS1\n{\n    template<class X>\n    struct Foo\n    {\n        X *v;\n    };\n\n    template<class X>\n    struct Bar\n    {\n        X *v;\n    };\n\n};\n\nstruct Test32NS2\n{\n    template<class X>\n    struct Foo\n    {\n        X *v;\n    };\n};\n\ntemplate <template <class X> class Y, template <class X> class Z>\nstruct Test32\n{\n    Y<int>* field;\n};\n\n\nvoid test32a(Test32<Test32NS1::Foo, Test32NS1::Foo> arg)\n{\n}\n\nvoid test32b(Test32<Test32NS1::Foo, Test32NS1::Bar> arg)\n{\n}\n\nvoid test32c(Test32<Test32NS1::Foo, Test32NS2::Foo> arg)\n{\n}\n\nvoid test32d(Test32<Test32NS1::Foo, Test32NS2::Foo> arg1, Test32<Test32NS2::Foo, Test32NS1::Foo> arg2)\n{\n}\n\n\nclass XXX\n{\n};\ntemplate <void (&Goo)(XXX*, XXX**), void (&Xoo)(XXX*, XXX**)>\nstruct Test33\n{\n};\n\nvoid test33a(XXX*, XXX**){}\n\nvoid test33(XXX*, Test33<test33a, test33a> arg, XXX*)\n{\n}\n\ntemplate <void (&Goo)(int)>\nstruct Test34\n{\n};\n\nstruct Test34A\n{\n    static void foo(int);\n};\n\nvoid Test34A::foo(int) {}\nvoid test34(Test34<Test34A::foo> arg)\n{\n}\n\nint test36= 36;\n\ntemplate <int& XREF>\nstruct Test37\n{\n};\n\nstruct Test37A\n{\n    static int t38;\n};\n\nint Test37A::t38 = 42;\n\nvoid test37(Test37<test36> arg)\n{\n}\n\nvoid test38(Test37<Test37A::t38> arg)\n{\n}\n\nstruct Test39\n{\n    template <class X>\n    struct T39A\n    {\n    };\n};\n\nstruct T39A\n{\n};\n\nvoid test39(Test39::T39A< ::T39A >)\n{\n}\n\n#if 0 //only for g++ with -std=c++0x and Visual C++ >= 2013\n    #if defined(__GNUG__) || (defined(_MSC_VER) && _MSC_VER >= 1200)\n    template<class... VarArg> struct Test40\n    {\n    };\n\n    void test40(Test40<int, double, void> arg)\n    {\n    }\n    #endif\n\n\n#endif\n\n\nextern XXX const * const  test41 = 0;\n\nnamespace Test42\n{\n    extern XXX const * const  test42 = 0;\n}\n\nint test43[4] = {1, 2, 3, 4};\n\nXXX const* const test44()\n{\n    return new XXX;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/foo37.txt",
    "content": "hello\nbetty\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/lib10386/foo/bar.d",
    "content": "module lib10386.foo.bar;\n\nvoid foo(int x)\n{\n    assert(x == 1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/lib10386/foo/package.d",
    "content": "module lib10386.foo;\n\npublic import lib10386.foo.bar;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/lib13666.d",
    "content": "module lib13666;\n\ntemplate drt_envvars()\n{\n    extern(C) __gshared bool enabled = false;\n}\n\nbool foo()\n{\n\treturn drt_envvars!().enabled;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/lib13742a.d",
    "content": "module lib13742a;\n\nvoid performLocked(alias PROC)()\n{\n    PROC();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/lib13742b.d",
    "content": "module lib13742b;\nimport lib13742a;\n\nvoid clear()\n{\n    void foo() {} // nested function\n    performLocked!foo; // template from other module (preceding on command line)\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/lib13774a.d",
    "content": "module lib13774a;\n\nvoid comdef()()\n{\n    __gshared int a;\n}\n\nvoid use1()\n{\n    comdef();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/lib13774b.d",
    "content": "module lib13774b;\nimport lib13774a;\n\nvoid use2()\n{\n    comdef();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/lib846.d",
    "content": "module link846a;\n\ntemplate ElemTypeOf(T)\n{\n    alias typeof(T.init[0]) ElemTypeOf;\n}\n\ntemplate removeIf_(Elem, Pred)\n{\n    size_t fn(Elem[] buf, Pred pred)\n    {\n        void exch(size_t p1, size_t p2)\n        {\n            Elem t  = buf[p1];\n            buf[p1] = buf[p2];\n            buf[p2] = t;\n        }\n\n        size_t cnt = 0;\n\n        for (size_t pos = 0, len = buf.length; pos < len; ++pos)\n        {\n            if (pred(buf[pos]))\n                ++cnt;\n            else\n                exch(pos, pos - cnt);\n        }\n        return buf.length - cnt;\n    }\n}\n\ntemplate removeIf(Buf, Pred)\n{\n    size_t removeIf(Buf buf, Pred pred)\n    {\n        return removeIf_!(ElemTypeOf!Buf, Pred).fn(buf, pred);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/link14834a.d",
    "content": "module link14834a;\n\nstruct DirIterator\n{\n    int i = 1;\n\n    @property bool empty() { return i == 0; }\n    @property int front() { return 10; }\n    void popFront() { --i; }\n}\n\nauto dirEntries(string path)\n{\n    bool f(int x)\n    {\n        assert(path == \".\");    // should pass\n        return true;\n    }\n    return filter!f(DirIterator());\n}\n\ntemplate filter(alias pred)\n{\n    auto filter(R)(R range)\n    {\n        return FilterResult!(pred, R)(range);\n    }\n}\n\nstruct FilterResult(alias pred, R)\n{\n    R input;\n\n    this(R r)\n    {\n        input = r;\n        while (!input.empty && !pred(input.front))\n        {\n            input.popFront();\n        }\n    }\n\n    @property bool empty() { return input.empty; }\n\n    @property auto ref front()\n    {\n        return input.front;\n    }\n\n    void popFront()\n    {\n        do\n        {\n            input.popFront();\n        } while (!input.empty && !pred(input.front));\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/link14834b.d",
    "content": "import link14834a;\n\nvoid main()\n{\n    foreach (n; dirEntries(\".\"))\n    {\n        assert(n == 10);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/linkdebug.d",
    "content": "module linkdebug;\n\nvoid main()\n{\n    import linkdebug_uni;\n    import linkdebug_range;\n\n    // OK\n    //SortedRangeX!(uint[], \"a <= b\") SR;\n\n    CodepointSet set;\n    set.addInterval(1, 2);\n\n    // NG, order dependent.\n    SortedRange!(uint[], \"a <= b\") SR;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/linkdebug_primitives.d",
    "content": "module linkdebug_primitives;\n\nsize_t popBackN(R)(ref R r, size_t n)\n{\n    n = cast(size_t) (n < r.length ? n : r.length);\n    r = r[0 .. $ - n];\n    return n;\n}\n\nauto moveAt(R, I)(R r, I i)\n{\n    return r[i];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/linkdebug_range.d",
    "content": "module linkdebug_range;\n\nimport linkdebug_primitives : popBackN, moveAt;\n\nauto stride(R)(R r)\n{\n    static struct Result\n    {\n        R source;\n\n        void popBack()\n        {\n            popBackN(source, 0);\n        }\n\n        uint moveAt(size_t n)\n        {\n            return .moveAt(source, n);\n        }\n    }\n    return Result(r);\n}\n\nstruct SortedRange(Range, alias pred = \"a < b\")\n{\n    this(Range input)\n    out\n    {\n        dbgVerifySorted();\n    }\n    body\n    {\n    }\n\n    void dbgVerifySorted()\n    {\n        debug\n        {\n            uint[] _input;\n            auto st = stride(_input);\n        }\n    }\n}\n\nauto assumeSorted(alias pred = \"a < b\", R)(R r)\n{\n    return SortedRange!(R, pred)(r);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/linkdebug_uni.d",
    "content": "module linkdebug_uni;\n\nimport linkdebug_range;\n\nstruct GcPolicy {}\n\nalias CodepointSet = InversionList!();\n\nstruct InversionList(SP = GcPolicy)\n{\n@trusted:\n    size_t addInterval(int a, int b, size_t hint = 0)\n    {\n        auto data = new uint[](0);        // affects to the number of missimg symbol\n        auto range = assumeSorted(data[]);  // NG\n        //SortedRange!(uint[], \"a < b\") SR; // OK\n        return 1;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/main846.d",
    "content": "import lib846;\n\nvoid main()\n{\n    auto num = removeIf(\"abcdef\".dup, (char c){ return c == 'c'; });\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/minimal/object.d",
    "content": "module object;\n\nprivate alias extern(C) int function(char[][] args) MainFunc;\nprivate extern (C) int _d_run_main(int argc, char** argv, MainFunc mainFunc)\n{\n    return mainFunc(null);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/mul9377a.d",
    "content": "import core.stdc.stdio;\n\nimport mul9377b;\n\nvoid abc()\n{\n    printf(\"mul9377b.abc()\\n\");\n    foo();\n    bar();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/mul9377b.d",
    "content": "module mul9377b;\n\nimport core.stdc.stdio;\n\nint j;\n\nint foo()()\n{\n    printf(\"foo()\\n\");\n    static int z = 7;\n    assert(z != 10);\n    return ++z;\n}\n\nvoid bar()\n{\n    assert(j == 7);\n    foo();\n    printf(\"bar\\n\");\n}\n\ntemplate def()\n{\n    alias int defint;\n\n    static this()\n    {\n        printf(\"def.static this()\\n\");\n        j = 7;\n    }\n\n    //void mem(int){}\n    void mem()\n    {\n        printf(\"def().mem()\\n\");\n    }\n}\n\ndef!().defint x;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/multi9377.d",
    "content": "import core.stdc.stdio;\n\nimport mul9377a, mul9377b;\n\nint main()\n{\n    printf(\"main\\n\");\n    abc();\n    def!().mem();\n    pragma(msg, def!().mem.mangleof);\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/objc_self_test.m",
    "content": "#import <Foundation/Foundation.h>\n\n@interface objc_self_test : NSObject\n-(int) getValue;\n@end\n\n@implementation objc_self_test\n-(int) getValue\n{\n    return 3;\n}\n@end\n\nint getValue ()\n{\n    return [[[objc_self_test alloc] init] getValue];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/std14198/array.d",
    "content": "module std14198.array;\n\nversion(bug14198)\n{\n}\nelse\n    import std14198.uni;\n\nstruct Appender(A)\n{\n    alias T = immutable char;\n\n    void put(U)(U item)\n    if (\n            is(U : T) ||\n            is(immutable U == immutable char)\n       )\n    {\n        import std14198.uni; // necessary\n        assert(0);\n    }\n}\n\nAppender!A appender(A)()\n{\n    return Appender!A();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/std14198/conv.d",
    "content": "module std14198.conv;\n\ntemplate to(T)\n{\n    T to(A...)(A args)\n    {\n        return toImpl!T(args);\n    }\n}\n\nT toImpl(T, S)(S value)\n    if (is(S : T))\n{\n    return value;\n}\n\nT toImpl(T, S)(S value)\n    if (!is(S : T) &&\n        is(T == string))\n{\n    alias src = value;\n\n    import std14198.format : FormatSpec;\n    import std14198.array : appender;\n\n    auto w = appender!T();\n    FormatSpec!char f; // necessary\n\n    string str = src ? \"true\" : \"false\";\n    for (; !str.length; str = str[1..$])\n        w.put(str[0]);\n\n    return \"\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/std14198/format.d",
    "content": "module std14198.format;\n\nstruct FormatSpec(Char) if (is(Char == char))\n{\n    import std14198.conv;\n\n    string toString()\n    {\n        return to!string(true); // necessary\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/std14198/uni.d",
    "content": "module std14198.uni;\n\nalias CodepointSet = InversionList!();\n\nstruct InversionList()\n{\n    import std14198.format;\n\n    void toString(FormatSpec!char fs) // necessary\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/stdint.cpp",
    "content": "#include <stdint.h>\n\nint testCppI8Mangle (int8_t,  uint8_t,  int_least8_t,  uint_least8_t,  int_fast8_t,  uint_fast8_t)  { return 1; }\nint testCppI16Mangle(int16_t, uint16_t, int_least16_t, uint_least16_t, int_fast16_t, uint_fast16_t) { return 2; }\nint testCppI32Mangle(int32_t, uint32_t, int_least32_t, uint_least32_t, int_fast32_t, uint_fast32_t) { return 3; }\nint testCppI64Mangle(int64_t, uint64_t, int_least64_t, uint_least64_t, int_fast64_t, uint_fast64_t) { return 4; }\nint testCppIntPtrMangle(intptr_t, uintptr_t) { return 5; }\nint testCppIntMaxMangle(intmax_t, uintmax_t) { return 6; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test10386.d",
    "content": "module test10386;\n\n// import lib.foo.bar;  // ok\nimport lib10386.foo;  // linker failure\n\nimport imports.testmangle;\n\nvoid main()\n{\n    static assert(equalDemangle(foo.mangleof, \"_D8lib103863foo3bar3fooFiZv\"));\n    foo(1);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test10567.d",
    "content": "import test10567a;\n\ntemplate TypeTuple(TL...) { alias TL TypeTuple; }\n\nvoid main()\n{\n    foreach (BigInt; TypeTuple!(BigInt1, BigInt2, BigInt3))\n    {\n        auto i = BigInt([100]);\n        auto j = BigInt([100]);\n\n        assert(typeid(BigInt).equals(&i, &j) == true);\n        assert(typeid(BigInt).compare(&i, &j) == 0);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test10567a.d",
    "content": "struct BigInt1\n{\n    int[] dara;\n\n    bool opEquals(const ref BigInt1 rhs) const  // -> stored in TypeInfo_Struct.xopEquals\n    {\n        return true;\n    }\n    bool opEquals(T)(T rhs) const\n    {\n        return false;\n    }\n\n    int opCmp(const ref BigInt1 rhs) const      // stored in TypeInfo_Struct.xopCmp\n    {\n        return 0;\n    }\n    int opCmp(T)(T rhs) const\n    {\n        return 1;\n    }\n}\n\nstruct BigInt2\n{\n    int[] dara;\n\n    bool opEquals(const ref BigInt2 rhs) const  // stored in TypeInfo_Struct.xopEquals\n    {\n        return true;\n    }\n\n    int opCmp(const ref BigInt2 rhs) const      // stored in TypeInfo_Struct.xopCmp\n    {\n        return 0;\n    }\n}\n\nstruct BigInt3\n{\n    int[] dara;\n\n    bool opEquals(T)(T rhs) const   // stored in TypeInfo_Struct.xopEquals\n    {\n        return true;\n    }\n\n    int opCmp(T)(T rhs) const       // stored in TypeInfo_Struct.xopCmp\n    {\n        return 0;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test13666.d",
    "content": "import lib13666;\n\nint main()\n{\n\treturn foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test13742.d",
    "content": "import lib13742b;\n\nvoid main()\n{\n    clear();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test14198.d",
    "content": "module test14198;\n\nimport std14198.conv;\n\nstruct S\n{\n    ptrdiff_t function() fptr = &handler;\n\n    static ptrdiff_t handler() pure @safe\n    {\n        static if (is(typeof(to!string(false))))\n        {\n            to!string(false);\n            // [1] to!string(bool src) should be deduced to pure @safe, and the function will be mangled to:\n            //     --> _D8std141984conv11__T2toTAyaZ9__T2toTbZ2toFNaNbNiNfbZAya\n            // [2] its object code would be stored in the library file, because it's instantiated in std14188.uni:\n            //     --> FormatSpec!char --> to!string(bool src) in FormatSpec!char.toString()\n            //     But semanti3 of FormatSpec!char.toString() won't get called from this module compilation,\n            //     so the instantiaion is invisible.\n            //     Then, the object code is also stored in test14198.obj, and the link will succeed.\n        }\n        else\n            static assert(0);\n        return 0;\n    }\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test15.txt",
    "content": "ad0.doubleclick.be\nad0.erasercash.com\nad0.ezcybersearch.com\nad0.gamesweb.com\nad0.haynet.com\nad0.hpg.com.br\nad0.hpg.ig.com.br\nad0.paycount.com\nad0.popupad.net\nad00.erasercash.com\nad00.ezcybersearch.com\nad00.hpg.com.br\nad00.hpg.ig.com.br\nad00.paycount.com\nad00.popupad.net\nad01.erasercash.com\nad01.ezcybersearch.com\nad01.focalink.com\nad01.hpg.com.br\nad01.hpg.ig.com.br\nad01.mediacorpsingapore.com\nad01.nakednews.com\nad01.paycount.com\nad01.popupad.net\nad02.focalink.com\nad03.erasercash.com\nad03.ezcybersearch.com\nad03.focalink.com\nad03.freenet.de\nad03.hpg.com.br\nad03.hpg.ig.com.br\nad03.paycount.com\nad03.popupad.net\nad04.erasercash.com\nad04.ezcybersearch.com\nad04.focalink.com\nad04.hpg.com.br\nad04.hpg.ig.com.br\nad04.paycount.com\nad04.popupad.net\nad05.erasercash.com\nad05.ezcybersearch.com\nad05.focalink.com\nad05.hpg.com.br\nad05.hpg.ig.com.br\nad05.paycount.com\nad05.popupad.net\nad06.erasercash.com\nad06.ezcybersearch.com\nad06.focalink.com\nad06.hpg.com.br\nad06.hpg.ig.com.br\nad06.paycount.com\nad06.popupad.net\nad07.erasercash.com\nad07.ezcybersearch.com\nad07.focalink.com\nad07.hpg.com.br\nad07.hpg.ig.com.br\nad07.paycount.com\nad07.popupad.net\nad08.erasercash.com\nad08.ezcybersearch.com\nad08.focalink.com\nad08.hpg.com.br\nad08.hpg.ig.com.br\nad08.paycount.com\nad08.popupad.net\nad09.erasercash.com\nad09.ezcybersearch.com\nad09.focalink.com\nad09.hpg.com.br\nad09.hpg.ig.com.br\nad09.paycount.com\nad09.popupad.net\nad1.aaddzz.com\nad1.adnetwork.com.br\nad1.adsolution.de\nad1.adverticum.net\nad1.bb.ru\nad1.dada.it\nad1.denverpost.com\nad1.dialpad.com\nad1.doubleclick.be\nad1.doubleclick.com\nad1.doubleclick.net\nad1.emediate.dk\nad1.erasercash.com\nad1.ezcybersearch.com\nad1.gamezone.com\nad1.gamezone.de\nad1.hpg.com.br\nad1.hpg.ig.com.br\nad1.icorp.net\nad1.ixo.com\nad1.kde.cz\nad1.lbe.ru\nad1.lbn.ru\nad1.outpost.com\nad1.pamedia.com.au\nad1.paycount.com\nad1.peel.com\nad1.popupad.net\nad1.primorye.ru\nad1.radioreti.it\nad1.targetgraph.com\nad1.trafficx.com\nad1.yourmedia.com\nad1.zendmedia.com\nad10.doubleclick.be\nad10.erasercash.com\nad10.ezcybersearch.com\nad10.focalink.com\nad10.hpg.com.br\nad10.hpg.ig.com.br\nad10.lbn.ru\nad10.paycount.com\nad10.popupad.net\nad100.erasercash.com\nad100.ezcybersearch.com\nad100.hpg.com.br\nad100.hpg.ig.com.br\nad100.paycount.com\nad100.popupad.net\nad101.erasercash.com\nad101.ezcybersearch.com\nad101.hpg.com.br\nad101.hpg.ig.com.br\nad101.paycount.com\nad101.popupad.net\nad102.erasercash.com\nad102.ezcybersearch.com\nad102.hpg.com.br\nad102.hpg.ig.com.br\nad102.paycount.com\nad102.popupad.net\nad103.erasercash.com\nad103.ezcybersearch.com\nad103.hpg.com.br\nad103.hpg.ig.com.br\nad103.paycount.com\nad103.popupad.net\nad104.erasercash.com\nad104.ezcybersearch.com\nad104.hpg.com.br\nad104.hpg.ig.com.br\nad104.paycount.com\nad104.popupad.net\nad105.erasercash.com\nad105.ezcybersearch.com\nad105.hpg.com.br\nad105.hpg.ig.com.br\nad105.paycount.com\nad105.popupad.net\nad106.erasercash.com\nad106.ezcybersearch.com\nad106.hpg.com.br\nad106.hpg.ig.com.br\nad106.paycount.com\nad106.popupad.net\nad107.erasercash.com\nad107.ezcybersearch.com\nad107.hpg.com.br\nad107.hpg.ig.com.br\nad107.paycount.com\nad107.popupad.net\nad108.erasercash.com\nad108.ezcybersearch.com\nad108.hpg.com.br\nad108.hpg.ig.com.br\nad108.paycount.com\nad108.popupad.net\nad109.erasercash.com\nad109.ezcybersearch.com\nad109.hpg.com.br\nad109.hpg.ig.com.br\nad109.paycount.com\nad109.popupad.net\nad11.doubleclick.be\nad11.erasercash.com\nad11.ezcybersearch.com\nad11.focalink.com\nad11.hpg.com.br\nad11.hpg.ig.com.br\nad11.lbn.ru\nad11.paycount.com\nad11.popupad.net\nad110.erasercash.com\nad110.ezcybersearch.com\nad110.hpg.com.br\nad110.hpg.ig.com.br\nad110.paycount.com\nad110.popupad.net\nad111.erasercash.com\nad111.ezcybersearch.com\nad111.hpg.com.br\nad111.hpg.ig.com.br\nad111.paycount.com\nad111.popupad.net\nad112.erasercash.com\nad112.ezcybersearch.com\nad112.hpg.com.br\nad112.hpg.ig.com.br\nad112.paycount.com\nad112.popupad.net\nad113.erasercash.com\nad113.ezcybersearch.com\nad113.hpg.com.br\nad113.hpg.ig.com.br\nad113.paycount.com\nad113.popupad.net\nad114.erasercash.com\nad114.ezcybersearch.com\nad114.hpg.com.br\nad114.hpg.ig.com.br\nad114.paycount.com\nad114.popupad.net\nad115.erasercash.com\nad115.ezcybersearch.com\nad115.hpg.com.br\nad115.hpg.ig.com.br\nad115.paycount.com\nad115.popupad.net\nad116.erasercash.com\nad116.ezcybersearch.com\nad116.hpg.com.br\nad116.hpg.ig.com.br\nad116.paycount.com\nad116.popupad.net\nad117.erasercash.com\nad117.ezcybersearch.com\nad117.hpg.com.br\nad117.hpg.ig.com.br\nad117.paycount.com\nad117.popupad.net\nad118.erasercash.com\nad118.ezcybersearch.com\nad118.hpg.com.br\nad118.hpg.ig.com.br\nad118.paycount.com\nad118.popupad.net\nad119.erasercash.com\nad119.ezcybersearch.com\nad119.hpg.com.br\nad119.hpg.ig.com.br\nad119.paycount.com\nad119.popupad.net\nad12.doubleclick.be\nad12.erasercash.com\nad12.ezcybersearch.com\nad12.focalink.com\nad12.hpg.com.br\nad12.hpg.ig.com.br\nad12.lbn.ru\nad12.paycount.com\nad12.popupad.net\nad120.erasercash.com\nad120.ezcybersearch.com\nad120.hpg.com.br\nad120.hpg.ig.com.br\nad120.paycount.com\nad120.popupad.net\nad121.erasercash.com\nad121.ezcybersearch.com\nad121.hpg.com.br\nad121.hpg.ig.com.br\nad121.paycount.com\nad121.popupad.net\nad122.erasercash.com\nad122.ezcybersearch.com\nad122.hpg.com.br\nad122.hpg.ig.com.br\nad122.paycount.com\nad122.popupad.net\nad123.erasercash.com\nad123.ezcybersearch.com\nad123.hpg.com.br\nad123.hpg.ig.com.br\nad123.paycount.com\nad123.popupad.net\nad124.erasercash.com\nad124.ezcybersearch.com\nad124.hpg.com.br\nad124.hpg.ig.com.br\nad124.paycount.com\nad124.popupad.net\nad125.erasercash.com\nad125.ezcybersearch.com\nad125.hpg.com.br\nad125.hpg.ig.com.br\nad125.paycount.com\nad125.popupad.net\nad126.erasercash.com\nad126.ezcybersearch.com\nad126.hpg.com.br\nad126.hpg.ig.com.br\nad126.paycount.com\nad126.popupad.net\nad127.erasercash.com\nad127.ezcybersearch.com\nad127.hpg.com.br\nad127.hpg.ig.com.br\nad127.paycount.com\nad127.popupad.net\nad128.erasercash.com\nad128.ezcybersearch.com\nad128.hpg.com.br\nad128.hpg.ig.com.br\nad128.paycount.com\nad128.popupad.net\nad129.erasercash.com\nad129.ezcybersearch.com\nad129.hpg.com.br\nad129.hpg.ig.com.br\nad129.paycount.com\nad129.popupad.net\nad13.doubleclick.be\nad13.erasercash.com\nad13.ezcybersearch.com\nad13.focalink.com\nad13.hpg.com.br\nad13.hpg.ig.com.br\nad13.lbn.ru\nad13.paycount.com\nad13.popupad.net\nad130.erasercash.com\nad130.ezcybersearch.com\nad130.hpg.com.br\nad130.hpg.ig.com.br\nad130.paycount.com\nad130.popupad.net\nad131.erasercash.com\nad131.ezcybersearch.com\nad131.hpg.com.br\nad131.hpg.ig.com.br\nad131.paycount.com\nad131.popupad.net\nad132.erasercash.com\nad132.ezcybersearch.com\nad132.hpg.com.br\nad132.hpg.ig.com.br\nad132.paycount.com\nad132.popupad.net\nad133.erasercash.com\nad133.ezcybersearch.com\nad133.hpg.com.br\nad133.hpg.ig.com.br\nad133.paycount.com\nad133.popupad.net\nad134.erasercash.com\nad134.ezcybersearch.com\nad134.hpg.com.br\nad134.hpg.ig.com.br\nad134.paycount.com\nad134.popupad.net\nad135.erasercash.com\nad135.ezcybersearch.com\nad135.hpg.com.br\nad135.hpg.ig.com.br\nad135.paycount.com\nad135.popupad.net\nad136.erasercash.com\nad136.ezcybersearch.com\nad136.hpg.com.br\nad136.hpg.ig.com.br\nad136.paycount.com\nad136.popupad.net\nad137.erasercash.com\nad137.ezcybersearch.com\nad137.hpg.com.br\nad137.hpg.ig.com.br\nad137.paycount.com\nad137.popupad.net\nad138.erasercash.com\nad138.ezcybersearch.com\nad138.hpg.com.br\nad138.hpg.ig.com.br\nad138.paycount.com\nad138.popupad.net\nad139.erasercash.com\nad139.ezcybersearch.com\nad139.hpg.com.br\nad139.hpg.ig.com.br\nad139.paycount.com\nad139.popupad.net\nad14.doubleclick.be\nad14.erasercash.com\nad14.ezcybersearch.com\nad14.focalink.com\nad14.hpg.com.br\nad14.hpg.ig.com.br\nad14.paycount.com\nad14.popupad.net\nad140.erasercash.com\nad140.ezcybersearch.com\nad140.hpg.com.br\nad140.hpg.ig.com.br\nad140.paycount.com\nad140.popupad.net\nad141.erasercash.com\nad141.ezcybersearch.com\nad141.hpg.com.br\nad141.hpg.ig.com.br\nad141.paycount.com\nad141.popupad.net\nad142.erasercash.com\nad142.ezcybersearch.com\nad142.hpg.com.br\nad142.hpg.ig.com.br\nad142.paycount.com\nad142.popupad.net\nad143.erasercash.com\nad143.ezcybersearch.com\nad143.hpg.com.br\nad143.hpg.ig.com.br\nad143.paycount.com\nad143.popupad.net\nad144.erasercash.com\nad144.ezcybersearch.com\nad144.hpg.com.br\nad144.hpg.ig.com.br\nad144.paycount.com\nad144.popupad.net\nad145.erasercash.com\nad145.ezcybersearch.com\nad145.hpg.com.br\nad145.hpg.ig.com.br\nad145.paycount.com\nad145.popupad.net\nad146.erasercash.com\nad146.ezcybersearch.com\nad146.hpg.com.br\nad146.hpg.ig.com.br\nad146.paycount.com\nad146.popupad.net\nad147.erasercash.com\nad147.ezcybersearch.com\nad147.hpg.com.br\nad147.hpg.ig.com.br\nad147.paycount.com\nad147.popupad.net\nad148.erasercash.com\nad148.ezcybersearch.com\nad148.hpg.com.br\nad148.hpg.ig.com.br\nad148.paycount.com\nad148.popupad.net\nad149.erasercash.com\nad149.ezcybersearch.com\nad149.hpg.com.br\nad149.hpg.ig.com.br\nad149.paycount.com\nad149.popupad.net\nad15.doubleclick.be\nad15.erasercash.com\nad15.ezcybersearch.com\nad15.focalink.com\nad15.hpg.com.br\nad15.hpg.ig.com.br\nad15.paycount.com\nad15.popupad.net\nad150.erasercash.com\nad150.ezcybersearch.com\nad150.hpg.com.br\nad150.hpg.ig.com.br\nad150.paycount.com\nad150.popupad.net\nad151.erasercash.com\nad151.ezcybersearch.com\nad151.hpg.com.br\nad151.hpg.ig.com.br\nad151.paycount.com\nad151.popupad.net\nad152.erasercash.com\nad152.ezcybersearch.com\nad152.hpg.com.br\nad152.hpg.ig.com.br\nad152.paycount.com\nad152.popupad.net\nad153.erasercash.com\nad153.ezcybersearch.com\nad153.hpg.com.br\nad153.hpg.ig.com.br\nad153.paycount.com\nad153.popupad.net\nad154.erasercash.com\nad154.ezcybersearch.com\nad154.hpg.com.br\nad154.hpg.ig.com.br\nad154.paycount.com\nad154.popupad.net\nad155.erasercash.com\nad155.ezcybersearch.com\nad155.hpg.com.br\nad155.hpg.ig.com.br\nad155.paycount.com\nad155.popupad.net\nad156.erasercash.com\nad156.ezcybersearch.com\nad156.hpg.com.br\nad156.hpg.ig.com.br\nad156.paycount.com\nad156.popupad.net\nad157.erasercash.com\nad157.ezcybersearch.com\nad157.hpg.com.br\nad157.hpg.ig.com.br\nad157.paycount.com\nad157.popupad.net\nad158.erasercash.com\nad158.ezcybersearch.com\nad158.hpg.com.br\nad158.hpg.ig.com.br\nad158.paycount.com\nad158.popupad.net\nad159.erasercash.com\nad159.ezcybersearch.com\nad159.hpg.com.br\nad159.hpg.ig.com.br\nad159.paycount.com\nad159.popupad.net\nad16.doubleclick.be\nad16.erasercash.com\nad16.ezcybersearch.com\nad16.focalink.com\nad16.hpg.com.br\nad16.hpg.ig.com.br\nad16.paycount.com\nad16.popupad.net\nad160.erasercash.com\nad160.ezcybersearch.com\nad160.hpg.com.br\nad160.hpg.ig.com.br\nad160.paycount.com\nad160.popupad.net\nad161.erasercash.com\nad161.ezcybersearch.com\nad161.hpg.com.br\nad161.hpg.ig.com.br\nad161.paycount.com\nad161.popupad.net\nad162.erasercash.com\nad162.ezcybersearch.com\nad162.hpg.com.br\nad162.hpg.ig.com.br\nad162.paycount.com\nad162.popupad.net\nad163.erasercash.com\nad163.ezcybersearch.com\nad163.hpg.com.br\nad163.hpg.ig.com.br\nad163.paycount.com\nad163.popupad.net\nad164.erasercash.com\nad164.ezcybersearch.com\nad164.hpg.com.br\nad164.hpg.ig.com.br\nad164.paycount.com\nad164.popupad.net\nad165.erasercash.com\nad165.ezcybersearch.com\nad165.hpg.com.br\nad165.hpg.ig.com.br\nad165.paycount.com\nad165.popupad.net\nad166.erasercash.com\nad166.ezcybersearch.com\nad166.hpg.com.br\nad166.hpg.ig.com.br\nad166.paycount.com\nad166.popupad.net\nad167.erasercash.com\nad167.ezcybersearch.com\nad167.hpg.com.br\nad167.hpg.ig.com.br\nad167.paycount.com\nad167.popupad.net\nad168.erasercash.com\nad168.ezcybersearch.com\nad168.hpg.com.br\nad168.hpg.ig.com.br\nad168.paycount.com\nad168.popupad.net\nad169.erasercash.com\nad169.ezcybersearch.com\nad169.hpg.com.br\nad169.hpg.ig.com.br\nad169.paycount.com\nad169.popupad.net\nad17.doubleclick.be\nad17.erasercash.com\nad17.ezcybersearch.com\nad17.focalink.com\nad17.hpg.com.br\nad17.hpg.ig.com.br\nad17.paycount.com\nad17.popupad.net\nad170.erasercash.com\nad170.ezcybersearch.com\nad170.hpg.com.br\nad170.hpg.ig.com.br\nad170.paycount.com\nad170.popupad.net\nad171.erasercash.com\nad171.ezcybersearch.com\nad171.hpg.com.br\nad171.hpg.ig.com.br\nad171.paycount.com\nad171.popupad.net\nad172.erasercash.com\nad172.ezcybersearch.com\nad172.hpg.com.br\nad172.hpg.ig.com.br\nad172.paycount.com\nad172.popupad.net\nad173.erasercash.com\nad173.ezcybersearch.com\nad173.hpg.com.br\nad173.hpg.ig.com.br\nad173.paycount.com\nad173.popupad.net\nad174.erasercash.com\nad174.ezcybersearch.com\nad174.hpg.com.br\nad174.hpg.ig.com.br\nad174.paycount.com\nad174.popupad.net\nad175.erasercash.com\nad175.ezcybersearch.com\nad175.hpg.com.br\nad175.hpg.ig.com.br\nad175.paycount.com\nad175.popupad.net\nad176.erasercash.com\nad176.ezcybersearch.com\nad176.hpg.com.br\nad176.hpg.ig.com.br\nad176.paycount.com\nad176.popupad.net\nad177.erasercash.com\nad177.ezcybersearch.com\nad177.hpg.com.br\nad177.hpg.ig.com.br\nad177.paycount.com\nad177.popupad.net\nad178.erasercash.com\nad178.ezcybersearch.com\nad178.hpg.com.br\nad178.hpg.ig.com.br\nad178.paycount.com\nad178.popupad.net\nad179.erasercash.com\nad179.ezcybersearch.com\nad179.hpg.com.br\nad179.hpg.ig.com.br\nad179.paycount.com\nad179.popupad.net\nad18.doubleclick.be\nad18.erasercash.com\nad18.ezcybersearch.com\nad18.focalink.com\nad18.hpg.com.br\nad18.hpg.ig.com.br\nad18.paycount.com\nad18.popupad.net\nad180.erasercash.com\nad180.ezcybersearch.com\nad180.hpg.com.br\nad180.hpg.ig.com.br\nad180.paycount.com\nad180.popupad.net\nad181.erasercash.com\nad181.ezcybersearch.com\nad181.hpg.com.br\nad181.hpg.ig.com.br\nad181.paycount.com\nad181.popupad.net\nad182.erasercash.com\nad182.ezcybersearch.com\nad182.hpg.com.br\nad182.hpg.ig.com.br\nad182.paycount.com\nad182.popupad.net\nad183.erasercash.com\nad183.ezcybersearch.com\nad183.hpg.com.br\nad183.hpg.ig.com.br\nad183.paycount.com\nad183.popupad.net\nad184.erasercash.com\nad184.ezcybersearch.com\nad184.hpg.com.br\nad184.hpg.ig.com.br\nad184.paycount.com\nad184.popupad.net\nad185.erasercash.com\nad185.ezcybersearch.com\nad185.hpg.com.br\nad185.hpg.ig.com.br\nad185.paycount.com\nad185.popupad.net\nad186.erasercash.com\nad186.ezcybersearch.com\nad186.hpg.com.br\nad186.hpg.ig.com.br\nad186.paycount.com\nad186.popupad.net\nad187.erasercash.com\nad187.ezcybersearch.com\nad187.hpg.com.br\nad187.hpg.ig.com.br\nad187.paycount.com\nad187.popupad.net\nad188.erasercash.com\nad188.ezcybersearch.com\nad188.hpg.com.br\nad188.hpg.ig.com.br\nad188.paycount.com\nad188.popupad.net\nad189.erasercash.com\nad189.ezcybersearch.com\nad189.hpg.com.br\nad189.hpg.ig.com.br\nad189.paycount.com\nad189.popupad.net\nad19.doubleclick.be\nad19.erasercash.com\nad19.ezcybersearch.com\nad19.focalink.com\nad19.hpg.com.br\nad19.hpg.ig.com.br\nad19.paycount.com\nad19.popupad.net\nad190.erasercash.com\nad190.ezcybersearch.com\nad190.hpg.com.br\nad190.hpg.ig.com.br\nad190.paycount.com\nad190.popupad.net\nad191.erasercash.com\nad191.ezcybersearch.com\nad191.hpg.com.br\nad191.hpg.ig.com.br\nad191.paycount.com\nad191.popupad.net\nad192.erasercash.com\nad192.ezcybersearch.com\nad192.hpg.com.br\nad192.hpg.ig.com.br\nad192.paycount.com\nad192.popupad.net\nad193.erasercash.com\nad193.ezcybersearch.com\nad193.hpg.com.br\nad193.hpg.ig.com.br\nad193.paycount.com\nad193.popupad.net\nad194.erasercash.com\nad194.ezcybersearch.com\nad194.hpg.com.br\nad194.hpg.ig.com.br\nad194.paycount.com\nad194.popupad.net\nad195.erasercash.com\nad195.ezcybersearch.com\nad195.hpg.com.br\nad195.hpg.ig.com.br\nad195.paycount.com\nad195.popupad.net\nad196.erasercash.com\nad196.ezcybersearch.com\nad196.hpg.com.br\nad196.hpg.ig.com.br\nad196.paycount.com\nad196.popupad.net\nad197.erasercash.com\nad197.ezcybersearch.com\nad197.hpg.com.br\nad197.hpg.ig.com.br\nad197.paycount.com\nad197.popupad.net\nad198.erasercash.com\nad198.ezcybersearch.com\nad198.hpg.com.br\nad198.hpg.ig.com.br\nad198.paycount.com\nad198.popupad.net\nad199.erasercash.com\nad199.ezcybersearch.com\nad199.hpg.com.br\nad199.hpg.ig.com.br\nad199.paycount.com\nad199.popupad.net\nad2.163.com\nad2.adcept.net\nad2.adnetwork.com.br\nad2.adverticum.net\nad2.allbanners.ru\nad2.asit.de\nad2.asv.de\nad2.atlas.cz\nad2.bannerbank.ru\nad2.bb.ru\nad2.billboard.cz\nad2.billboard.sk\nad2.dialpad.com\nad2.doubleclick.be\nad2.doubleclick.com\nad2.doubleclick.net\nad2.erasercash.com\nad2.ezcybersearch.com\nad2.gamezone.com\nad2.hpg.com.br\nad2.hpg.ig.com.br\nad2.lbe.ru\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test17968.d",
    "content": "import test17968a;\n\nvoid main()\n{\n    auto r = fun2.fun1;\n    // just check that getHash works (doesn't throw).\n    typeid(r).getHash(&r);\n\n    // try gethash when member is null.\n    r.t = null;\n    typeid(r).getHash(&r);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test17968a.d",
    "content": "struct S(T)\n{\n    T t;\n}\n\nclass C(T) { }\n\nauto fun1(T)(T t)\n{\n    return S!T(t);\n}\n\nauto fun2()\n{\n    return new C!int;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test18868_a.d",
    "content": "shared static this() { }\nimport imports.test18868_fls;\nalias floop = FLS!(int);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test18868_b.d",
    "content": "import imports.test18868_fls;\nalias floop = FLS!(int);\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test2.d",
    "content": "\nimport object;\nimport core.stdc.stdio;\nimport std.algorithm;\n\n/* ================================ */\n\nclass Foo\n{\n\tint foo(int x) { return x + 3; }\n}\n\nclass Bar : Foo\n{\n\toverride int foo(int y) { return y + 4; }\n}\n\nvoid test1()\n{\n    Bar e;\n\n    assert(e is null);\n    e = new Bar();\n    assert(e.foo(5) == 9);\n}\n\n/* ================================ */\n\nclass Foo2\n{\n    int foo(int x)\n    {\n\treturn x + 3;\n    }\n}\n\nclass Bar2 : Foo2\n{\n    override int foo(int y)\n    {\n\tassert(Foo2.foo(2) == 5);\n\treturn y + 4;\n    }\n}\n\nvoid test2()\n{\n    Bar2 e;\n\n    assert(e is null);\n    e = new Bar2();\n    assert(e.foo(5) == 9);\n    assert(e.Foo2.foo(10) == 13);\n}\n\n/* ================================ */\n\nvoid test3()\n{\n    debug printf(\"debug\\n\");\n    debug(1) printf(\"debug(1)\\n\");\n    debug(2) printf(\"debug(2)\\n\");\n    debug(3) printf(\"debug(3)\\n\");\n    debug(bar) printf(\"debug(bar)\\n\");\n    debug(10) assert(0);\n\n    debug(1)\n    {\tint d1 = 3;\n\n\tprintf(\"debug(1) { }\\n\");\n    }\n    debug(2)\n    {\n\tprintf(\"debug(2): d1 = %d\\n\", d1);\n    }\n}\n\n/* ================================ */\n\nint x1;\nint x2;\n\nclass Foo4\n{\n    static  this() { x1 = 3; printf(\"Foo4 ctor()\\n\"); }\n    static ~this() { x1 = 4; printf(\"Foo4 dtor()\\n\"); }\n}\n\nstatic  this() { x2 = 5; printf(\"ctor()\\n\"); }\nstatic ~this() { x2 = 6; printf(\"dtor()\\n\"); }\n\nvoid test4()\n{\n    printf(\"x1 = %d, x2 = %d\\n\", x1, x2);\n    assert(x1 == 3);\n    assert(x2 == 5);\n}\n\n/* ================================ */\n\nvoid test5()\n{\n    printf(\"test5()\\n\");\n    static uint foo;\n    static uint x = 3;\n    static uint len = 32;\n\n    version (D_Bits)\n    {\n\tbit[] bits;\n\n\tbits = (cast(bit *)&foo)[0..len];\n\tbits[6] = true;\n\tassert(foo == (1 << 6));\n    }\n}\n\n/* ================================ */\n\nint[] test6_1(int[] a)\n{\n\ta.length = 6;\n\treturn a;\n}\n\nvoid test6()\n{\n    printf(\"test6()\\n\");\n    int[3] b;\n    int[] a;\n\n    b[0] = 0;\n    b[1] = 1;\n    b[2] = 2;\n    assert(b.length == 3);\n    a = test6_1(b);\n    a[2] = 2;\n    assert(a.length == 6);\n}\n\n/* ================================ */\n\nclass OutBuffer7\n{\n    char[] data;\n    uint offset;\n\n    void write(const(char) *p, uint nbytes)\n    {\n\tdata[offset .. offset + nbytes] = (cast(char *)p)[0 .. nbytes];\n    }\n}\n\n\nvoid test7()\n{\n    printf(\"test7()\\n\");\n    int i;\n    OutBuffer7 ob = new OutBuffer7;\n\n    ob.data = new char[10];\n    printf(\"ob.data.length = %d\\n\", ob.data.length);\n    assert(ob.data.length == 10);\n    for (i = 0; i < 10; i++)\n\tassert(ob.data[i] == char.init);\n\nprintf(\"test7.1()\\n\");\n    ob.data[] = '-';\nprintf(\"test7.2()\\n\");\n    printf(\"ob.data[] = '%.*s'\\n\", cast(int)ob.data.length, ob.data.ptr);\n    for (i = 0; i < 10; i++)\n\tassert(ob.data[i] == '-');\n\n    ob.offset = 3;\n    ob.write(\"foo\", 3);\n    printf(\"ob.data.length = %d\\n\", ob.data.length);\n    printf(\"ob.data[] = '%.*s'\\n\", cast(int)ob.data.length, ob.data.ptr);\n    for (i = 0; i < 10; i++)\n    {\tif (i < 3 || i >= 6)\n\t    assert(ob.data[i] == '-');\n    }\n    assert(ob.data[3] == 'f');\n    assert(ob.data[4] == 'o');\n    assert(ob.data[5] == 'o');\n}\n\n/* ================================ */\n\nclass A8\n{\n    enum { bar = 8, baz }\n    int foo;\n}\n\nvoid test8()\n{\n    printf(\"test8()\\n\");\n    A8 a;\n    a = new A8();\n    a.foo = A8.bar;\n    assert(a.foo == 8);\n}\n\n/* ================================ */\n\n\nint z9;\n\nunittest\n{\n    printf(\"module unittest 9\\n\");\n    z9 = 3;\n}\n\n\nvoid test9()\n{\n    assert(z9 == 3);\n}\n\n/* ================================ */\n\nvoid test10()\n{\n    printf(\"test10()\\n\");\n    const int i = 8000;\n    assert(i == 8000);\n    static int j = 78;\n    assert(j == 78);\n}\n\n/* ================================ */\n\nObject test11_a()\n{\n    return null;\n}\n\nvoid test11()\n{\n    assert(test11_a() is null);\n}\n\n/* ================================ */\n\nclass A12 { }\nclass B12 { }\n\nint testx(A12 a) { return 1; }\n\nint testx(B12 b) { return 2; }\n\nvoid test12()\n{\n    A12 a = new A12();\n    B12 b = new B12();\n\n    assert(testx(a) == 1);\n    assert(testx(b) == 2);\n}\n\n/* ================================ */\n\nchar[] tolower13(ref char[] s)\n{\n    int i;\n\n    for (i = 0; i < s.length; i++)\n    {\n\tchar c = s[i];\n\tif ('A' <= c && c <= 'Z')\n\t    s[i] = cast(char)(c + (cast(char)'a' - 'A'));\n    }\n    return s;\n}\n\nvoid test13()\n{\n    auto s1 = \"FoL\".dup;\n    char[] s2;\n\n    s2 = tolower13(s1);\n    assert(std.algorithm.cmp(s2, \"fol\") == 0);\n    assert(s2 == s1);\n}\n\n/* ================================ */\n\nalias ABC14* LPABC14;\nclass ABC14 { }\n\nalias DEF14* LPDEF14;\nDEF14[3] foo;\nstruct DEF14 { int x; }\n\nvoid test14()\n{\n    assert(foo.sizeof == int.sizeof * 3);\n}\n\n/* ================================ */\n\nclass bits15\n{\n    bool a = true, b = true, c = true;\n    void dump()\n    {\n\tprintf(\"%d %d %d\\n\", a, b, c);\n    }\n}\n\nvoid test15()\n{\n     bits15 k = new bits15;\n     k.a = true; k.dump();\n     k.b = true; k.dump();\n     k.c = true; k.dump();\n     assert(k.a == true);\n     assert(k.b == true);\n     assert(k.c == true);\n}\n\n\n/* ================================ */\n\nalign(4) struct foo16\n{\n    short s;\n    int i;\n}\n\nvoid test16()\n{\n    assert(foo16.sizeof == 8);\n}\n\n/* ================================ */\n\nenum Color { red, blue, green };\nint[Color.max+1] colors1 = [ Color.blue:6, Color.green:2, Color.red:5 ];\n\n\nenum { red, blue, green };\nint[3] colors2 = [ blue:6, green:2, red:5 ];\n\nvoid test17()\n{\n    assert(colors1.length == 3);\n    assert(colors1[0] == 5);\n    assert(colors1[1] == 6);\n    assert(colors1[2] == 2);\n    assert(colors2[0] == 5);\n    assert(colors2[1] == 6);\n    assert(colors2[2] == 2);\n}\n\n/* ================================ */\n\nclass Test19 { struct { int a, b, c; } }\n\nvoid test19()\n{\n    Test19 t = new Test19();\n\n    t.a = 3;\n    assert(t.a == 3);\n}\n\n/* ================================ */\n\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test19();\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test35.d",
    "content": "import imports.test35a;\n\nvoid main()\n{\n    auto num = removeIf( \"abcdef\".dup, ( char c ) { return c == 'c'; } );\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test39.d",
    "content": "\n//pragma (lib, \"a39.lib\");\n\nimport imports.test39a;\n\nvoid main()\n{\n        auto t = new Test!(char);\n        t.show (\"hello\");\n} \n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test44.d",
    "content": "\nimport imports.test44a;\n\nconst char[][7] DAY_NAME = [\n        DAY.SUN: \"sunday\", \"monday\", \"tuesday\", \"wednesday\",\n          \"thursday\", \"friday\", \"saturday\"\n];\n\n\nvoid main()\n{\n    assert(DAY_NAME[DAY.SUN] == \"sunday\");\n    assert(DAY_NAME[DAY.MON] == \"monday\");\n    assert(DAY_NAME[DAY.TUE] == \"tuesday\");\n    assert(DAY_NAME[DAY.WED] == \"wednesday\");\n    assert(DAY_NAME[DAY.THU] == \"thursday\");\n    assert(DAY_NAME[DAY.FRI] == \"friday\");\n    assert(DAY_NAME[DAY.SAT] == \"saturday\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/test_shared.d",
    "content": "void main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/teststdio.txt",
    "content": "asdfasdf\na\nsdf\nasdf\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/extra-files/untag.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" dir=\"ltr\">\n  <head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n\t<!-- headlinks removed -->\n\t<link rel=\"shortcut icon\" href=\"../../../../misc/favicon.ico\"/>\n    <title>Abbott and Costello Meet Frankenstein - Wikipedia, the free encyclopedia</title>\n    <style type=\"text/css\">/*<![CDATA[*/ @import \"../../../../skins/offline/main.css\"; /*]]>*/</style>\n    <link rel=\"stylesheet\" type=\"text/css\" media=\"print\" href=\"../../../../skins/common/commonPrint.css\" />\n    <!--[if lt IE 5.5000]><style type=\"text/css\">@import \"../../../../skins/monobook/IE50Fixes.css\";</style><![endif]-->\n    <!--[if IE 5.5000]><style type=\"text/css\">@import \"../../../../skins/monobook/IE55Fixes.css\";</style><![endif]-->\n    <!--[if IE 6]><style type=\"text/css\">@import \"../../../../skins/monobook/IE60Fixes.css\";</style><![endif]-->\n    <!--[if IE]><script type=\"text/javascript\" src=\"../../../../skins/common/IEFixes.js\"></script>\n    <meta http-equiv=\"imagetoolbar\" content=\"no\" /><![endif]-->\n    <script type=\"text/javascript\" src=\"../../../../skins/common/wikibits.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../../skins/offline/md5.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../../skins/offline/utf8.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../../skins/offline/lookup.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../../raw/gen.js\"></script>        <style type=\"text/css\">/*<![CDATA[*/\n@import \"../../../../raw/MediaWiki%7ECommon.css\";\n@import \"../../../../raw/MediaWiki%7EMonobook.css\";\n@import \"../../../../raw/gen.css\";\n/*]]>*/</style>          </head>\n  <body\n    class=\"ns-0\">\n    <div id=\"globalWrapper\">\n      <div id=\"column-content\">\n\t<div id=\"content\">\n\t  <a name=\"top\" id=\"contentTop\"></a>\n\t        <h1 class=\"firstHeading\">Abbott and Costello Meet Frankenstein</h1>\n\t  <div id=\"bodyContent\">\n\t    <h3 id=\"siteSub\">From Wikipedia, the free encyclopedia</h3>\n\t    <div id=\"contentSub\"></div>\n\t    \t    \t    <!-- start content -->\n\t    <table class=\"infobox vevent\" style=\"width:20em; text-align:left; font-size:90%;\" cellspacing=\"2\">\n<tr>\n<th class=\"summary\" style=\"font-size: 110%; text-align: center;\" colspan=\"2\"><i>Abbott and Costello Meet Frankenstein</i></th>\n</tr>\n<tr>\n<td style=\"font-size: 95%; line-height:1.5em; text-align: center;\" colspan=\"2\"><a href=\"../../../../articles/a/%26/c/Image%7EA%26cfrank.jpg_1a86.html\" class=\"image\" title=\"A&amp;cfrank.jpg\"><img alt=\"\" src=\"../../../../images/local/thumb/2/23/A&amp;cfrank.jpg/200px-A&amp;cfrank.jpg\" width=\"200\" height=\"303\" border=\"0\" /></a><br />\n<i>Abbott and Costello Meet Frankenstein</i> Theatrical Poster</td>\n</tr>\n<tr class=\"description\">\n<th>Directed by</th>\n<td><a href=\"../../../../articles/c/h/a/Charles_Barton_f649.html\" title=\"Charles Barton\">Charles Barton</a></td>\n</tr>\n<tr>\n<th>Produced&#160;by</th>\n<td>Robert Arthur</td>\n</tr>\n<tr>\n<th>Written&#160;by</th>\n<td><a href=\"../../../../articles/r/o/b/Robert_Lees_4940.html\" title=\"Robert Lees\">Robert Lees</a><br />\nFrederic I. Rinaldo<br />\nJohn Grant</td>\n</tr>\n<tr>\n<th>Starring</th>\n<td><a href=\"../../../../articles/b/u/d/Bud_Abbott_cd1f.html\" title=\"Bud Abbott\">Bud Abbott</a><br />\n<a href=\"../../../../articles/l/o/u/Lou_Costello_553d.html\" title=\"Lou Costello\">Lou Costello</a><br />\n<a href=\"../../../../articles/l/o/n/Lon_Chaney%2C_Jr._3ef0.html\" title=\"Lon Chaney, Jr.\">Lon Chaney, Jr.</a><br />\n<a href=\"../../../../articles/b/e/l/Bela_Lugosi_59d1.html\" class=\"mw-redirect\" title=\"Bela Lugosi\">Bela Lugosi</a><br />\n<a href=\"../../../../articles/g/l/e/Glenn_Strange_7693.html\" title=\"Glenn Strange\">Glenn Strange</a></td>\n</tr>\n<tr>\n<th>Music&#160;by</th>\n<td><a href=\"../../../../articles/f/r/a/Frank_Skinner_%28composer%29_103e.html\" title=\"Frank Skinner (composer)\">Frank Skinner</a></td>\n</tr>\n<tr>\n<th>Editing&#160;by</th>\n<td>Frank Gross</td>\n</tr>\n<tr>\n<th>Distributed&#160;by</th>\n<td><a href=\"../../../../articles/u/n/i/Universal_International_4c70.html\" class=\"mw-redirect\" title=\"Universal International\">Universal International</a></td>\n</tr>\n<tr>\n<th>Release&#160;date(s)</th>\n<td><a href=\"../../../../articles/j/u/n/June_15.html\" title=\"June 15\">June 15</a>, <a href=\"../../../../articles/1/9/4/1948.html\" title=\"1948\">1948</a> (U.S. release)</td>\n</tr>\n<tr>\n<th>Running time</th>\n<td>83 min.</td>\n</tr>\n<tr>\n<th>Language</th>\n<td><a href=\"../../../../articles/e/n/g/English_language.html\" title=\"English language\">English</a></td>\n</tr>\n<tr>\n<th>Budget</th>\n<td>$760,000</td>\n</tr>\n<tr>\n<th>Preceded&#160;by</th>\n<td><i><a href=\"../../../../articles/h/o/u/House_of_Dracula_f4bb.html\" title=\"House of Dracula\">House of Dracula</a></i> (<a href=\"../../../../articles/1/9/4/1945_in_film.html\" title=\"1945 in film\">1945</a>)<br />\n<i><a href=\"../../../../articles/t/h/e/The_Invisible_Man%27s_Revenge_98c7.html\" title=\"The Invisible Man's Revenge\">The Invisible Man's Revenge</a></i> (<a href=\"../../../../articles/1/9/4/1944_in_film.html\" title=\"1944 in film\">1944</a>)<br />\n<i><a href=\"../../../../articles/t/h/e/The_Noose_Hangs_High_a16d.html\" title=\"The Noose Hangs High\">The Noose Hangs High</a></i> (<a href=\"../../../../articles/1/9/4/1948_in_film.html\" title=\"1948 in film\">1948</a>)</td>\n</tr>\n<tr>\n<th>Followed&#160;by</th>\n<td><i><a href=\"../../../../articles/m/e/x/Mexican_Hayride_c692.html\" title=\"Mexican Hayride\">Mexican Hayride</a></i> (<a href=\"../../../../articles/1/9/4/1948_in_film.html\" title=\"1948 in film\">1948</a>)<br />\n<i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Invisible_Man_c511.html\" title=\"Abbott and Costello Meet the Invisible Man\">Abbott and Costello Meet the Invisible Man</a></i> (<a href=\"../../../../articles/1/9/5/1951_in_film.html\" title=\"1951 in film\">1951</a>)</td>\n</tr>\n</table>\n<p><b>Abbott and Costello Meet Frankenstein</b> (onscreen title: <i>Bud Abbott Lou Costello Meet Frankenstein</i>) is a <a href=\"../../../../articles/1/9/4/1948_in_film.html\" title=\"1948 in film\">1948</a> <a href=\"../../../../articles/c/o/m/Comedy_film.html\" title=\"Comedy film\">comedy</a>/<a href=\"../../../../articles/h/o/r/Horror_film.html\" title=\"Horror film\">horror film</a> <a href=\"../../../../articles/f/i/l/Film_director.html\" title=\"Film director\">directed</a> by <a href=\"../../../../articles/c/h/a/Charles_Barton_f649.html\" title=\"Charles Barton\">Charles Barton</a> and starring the comedy team of <a href=\"../../../../articles/a/b/b/Abbott_and_Costello_fa65.html\" title=\"Abbott and Costello\">Abbott and Costello</a>.</p>\n<p>This is the first of several films where the comedy duo meets classic characters from <a href=\"../../../../articles/u/n/i/Universal_Studios_23de.html\" title=\"Universal Studios\">Universal</a>'s film stable. In the film, they encounter <a href=\"../../../../articles/d/r/a/Dracula.html\" title=\"Dracula\">Dracula</a>, <a href=\"../../../../articles/f/r/a/Frankenstein%27s_monster.html\" title=\"Frankenstein's monster\">Frankenstein's monster</a>, and the <a href=\"../../../../articles/t/h/e/The_Wolf_Man_%281941_film%29_e5e9.html\" title=\"The Wolf Man (1941 film)\">Wolf Man</a>. Subsequent films pair the duo with <a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Mummy_0243.html\" title=\"Abbott and Costello Meet the Mummy\">the Mummy</a>, the <a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Keystone_Kops_a436.html\" title=\"Abbott and Costello Meet the Keystone Kops\">Keystone Kops</a>, and the <a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Invisible_Man_c511.html\" title=\"Abbott and Costello Meet the Invisible Man\">Invisible Man</a>. On a TV special in the early 1950s, the comedy duo did a sketch where they interacted with the latest original Universal Studios monster being promoted at the time, the Creature from the Black Lagoon.</p>\n<p>The film is considered the swan song for the \"Big Three\" Universal horror monsters – Dracula, the Wolf Man and Frankenstein's monster – although it does not appear to fit within the loose continuity of the earlier films.</p>\n<p>The film was re-released in <a href=\"../../../../articles/1/9/5/1956.html\" title=\"1956\">1956</a> along with <i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Killer%2C_Boris_Karloff_0b24.html\" title=\"Abbott and Costello Meet the Killer, Boris Karloff\">Abbott and Costello Meet the Killer, Boris Karloff</a></i>.</p>\n<p>In 2001, the United States <a href=\"../../../../articles/l/i/b/Library_of_Congress_f2f1.html\" title=\"Library of Congress\">Library of Congress</a> deemed this film \"culturally, historically, or aesthetically significant\" and selected it for preservation in the <a href=\"../../../../articles/n/a/t/National_Film_Registry_0c8c.html\" title=\"National Film Registry\">National Film Registry</a>.</p>\n<p>In September 2007, Reader’s Digest selected the movie as one of the top 100 funniest films of all time.</p>\n<table id=\"toc\" class=\"toc\" summary=\"Contents\">\n<tr>\n<td>\n<div id=\"toctitle\">\n<h2>Contents</h2>\n</div>\n<ul>\n<li class=\"toclevel-1\"><a href=\"#Plot\"><span class=\"tocnumber\">1</span> <span class=\"toctext\">Plot</span></a></li>\n<li class=\"toclevel-1\"><a href=\"#Cast\"><span class=\"tocnumber\">2</span> <span class=\"toctext\">Cast</span></a></li>\n<li class=\"toclevel-1\"><a href=\"#Production\"><span class=\"tocnumber\">3</span> <span class=\"toctext\">Production</span></a></li>\n<li class=\"toclevel-1\"><a href=\"#Film_mistakes\"><span class=\"tocnumber\">4</span> <span class=\"toctext\">Film mistakes</span></a></li>\n<li class=\"toclevel-1\"><a href=\"#Cultural_references\"><span class=\"tocnumber\">5</span> <span class=\"toctext\">Cultural references</span></a></li>\n<li class=\"toclevel-1\"><a href=\"#Routines\"><span class=\"tocnumber\">6</span> <span class=\"toctext\">Routines</span></a></li>\n<li class=\"toclevel-1\"><a href=\"#DVD_releases\"><span class=\"tocnumber\">7</span> <span class=\"toctext\">DVD releases</span></a></li>\n<li class=\"toclevel-1\"><a href=\"#Notes\"><span class=\"tocnumber\">8</span> <span class=\"toctext\">Notes</span></a></li>\n<li class=\"toclevel-1\"><a href=\"#External_links\"><span class=\"tocnumber\">9</span> <span class=\"toctext\">External links</span></a></li>\n</ul>\n</td>\n</tr>\n</table>\n<script type=\"text/javascript\">\n//<![CDATA[\n if (window.showTocToggle) { var tocShowText = \"show\"; var tocHideText = \"hide\"; showTocToggle(); } \n//]]>\n</script>\n<p><a name=\"Plot\" id=\"Plot\"></a></p>\n<h2><span class=\"editsection\">[<a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Frankenstein_59d9.html\" title=\"Edit section: Plot\">edit</a>]</span> <span class=\"mw-headline\">Plot</span></h2>\n<p>Chick Young (<a href=\"../../../../articles/b/u/d/Bud_Abbott_cd1f.html\" title=\"Bud Abbott\">Bud Abbott</a>) and Wilbur Grey (<a href=\"../../../../articles/l/o/u/Lou_Costello_553d.html\" title=\"Lou Costello\">Lou Costello</a>) work as baggage clerks in LaMirada, Florida. When Wilbur mishandles two crates belonging to 'MacDougal's House of Horrors' museum, Mr. MacDougal (<a href=\"../../../../articles/f/r/a/Frank_Ferguson_a96e.html\" title=\"Frank Ferguson\">Frank Ferguson</a>) demands that they deliver them in person so that they can be inspected by an insurance agent. MacDougal boasts to Wilbur's girlfriend, Dr. Sandra Mornay (Lénore Aubert), that the crates contain \"the remains of the original Count Dracula\" (<a href=\"../../../../articles/b/e/l/Bela_Lugosi_59d1.html\" class=\"mw-redirect\" title=\"Bela Lugosi\">Bela Lugosi</a>) and \"the body of the Frankenstein Monster\" (<a href=\"../../../../articles/g/l/e/Glenn_Strange_7693.html\" title=\"Glenn Strange\">Glenn Strange</a>).</p>\n<p>Dracula awakens, hypnotizes Wilbur, and spirits away his own coffin (and the revived Monster) before anyone else sees them. MacDougal then arrives with the insurance agent. Finding the storage crates empty, he accuses the boys of theft and has them arrested.</p>\n<p>Mornay receives Dracula and the Monster at her island castle. Sandra is a gifted surgeon who has studied Dr. Frankenstein's notebooks, and has been posing as Wilbur's girlfriend as part of Dracula's scheme to replace the Monster's brutish brain with one more pliable — Wilbur's.</p>\n<p>Wilbur and Chick are bailed out of jail and mistakenly believe Sandra to be their benefactor. Actually Joan Raymond (<a href=\"../../../../articles/j/a/n/Jane_Randolph_7069.html\" title=\"Jane Randolph\">Jane Randolph</a>), who also seems to like Wilbur, is responsible for the good deed. Joan is secretly working for the company that is processing MacDougal's insurance claim, and hopes Wilbur will lead her to the missing 'exhibits'.</p>\n<p>Meanwhile, Larry Talbot (<a href=\"../../../../articles/l/o/n/Lon_Chaney%2C_Jr._3ef0.html\" title=\"Lon Chaney, Jr.\">Lon Chaney, Jr.</a>) has taken the apartment across the hall from Wilbur and Chick. He has tracked Dracula and the Monster from Europe, and knows them to be alive. Talbot asks the boys to help him find and destroy the villains. Wilbur is amenable to the plan, but Chick thinks both of them are crazy. Talbot's desperate insistence that he be locked in his room before moonrise impresses Chick even less.</p>\n<p>The following night, Wilbur, Chick and Joan go to Sandra's castle to pick her up for a costume ball. Sandra has told Wilbur to come alone, and receives the extra guests rather icily.</p>\n<p>While the ladies powder their noses, Wilbur answers a telephone call from someone wanting to speak to a 'Dr Lejos'. It is Talbot, who informs them that they are in the \"house of Dracula\". Wilbur reluctantly agrees to search the castle with Chick, and soon stumbles upon an underground passageway, complete with boat and dock. Behind a secret revolving wall, Wilbur again encounters Dracula and the Monster, but escapes. Wilbur's every attempt to get Chick to witness the villains fails - thanks to the revolving wall. Meanwhile, Joan has discovered Dr Frankenstein's notebook in Sandra's bureau, while Sandra has discovered Joan's employee I.D. in her bag.</p>\n<p>Suavely reattired, Dracula (a.k.a. Dr. Lejos) is introduced by Sandra to Joan and the boys. He commends Sandra on her 'choice', expertly massaging the ego of Wilbur, who does not realize the true context of the remark. Also working at the castle is the naive Dr. Stevens (Charles Bradstreet), who questions some of the specialized equipment that has arrived. Dracula manages to deflect Dr. Stevens' questions by pairing him with Joan and shooing off the 'young people' to their ball. Sandra claims to have a sudden splitting headache and will not be able to attend the event. When Dracula consults Sandra in private, she admits that Dr. Stevens' questions, Joan's insurance credentials and Wilbur's inquiries have made her nervous, and wants to postpone the experiments. Impatient, Dracula asserts his will by hypnotizing her, and biting her in the throat.</p>\n<p>At the ball, the boys encounter Talbot and MacDougal. Dracula arrives unexpectedly with Sandra, now under his spell. Dracula easily deflects Talbot's accusations, making the man appear disturbed. Dracula takes Joan for a dance while Sandra lures Wilbur to a quiet spot. Just before she can bite Wilbur's neck, Chick and Larry approach looking for Joan, and Sandra flees. As they search the grounds, Talbot transforms into the Wolf Man. Wilbur escapes, but the Wolf Man finds and injures MacDougal. Later noting that Chick is costumed as a werewolf, MacDougal concludes that Chick attacked him for revenge. (The fact that Chick is dressed like Talbot certainly does not help the situation). Chick manages to slip away, only to witness Dracula hypnotizing Wilbur. Chick becomes somewhat hypnotized himself, while Wilbur and an entranced Joan are brought back to the castle by Dracula and Sandra. The next morning, Chick is still on the lam when he finds Larry, who confesses that he was MacDougal's attacker. Now finally convinced, Chick agrees to help Larry rescue Wilbur and Joan.</p>\n<p>While Wilbur is being held in a pillory, Sandra finally explains to him the plan to transplant his brain into the Monster. She and Dracula leave him to prepare the Monster for the operation. Chick and Talbot arrive, free Wilbur, and head off to save Joan. Wilbur, meanwhile, is lured back to the castle by Dracula, who easily overpowers his mind.</p>\n<p>While the Monster receives an electrical boost in the lab, Sandra is about to open Wilbur's skull when Talbot storms in and casts her aside. Chick fends off Dracula with a chair, lifting it over his head to swing it at the vampire and inadvertently knocking out Sandra in the process. But just as Talbot is about to untie Wilbur, he once again transforms into the Wolf Man.</p>\n<p>Dracula returns to the scene, only to have a tug-of-war with the Wolf Man over Wilbur's gurney. Dracula flees, with the Wolf Man giving chase. Chick arrives to untie Wilbur just as the Monster, now fully recovered, breaks his own restraints and rises from his stretcher. Sandra attempts to order him back as Dracula does, but the Monster defiantly tosses her out a window.</p>\n<p>Dr. Stevens, meanwhile, has managed to find Joan and gets her to the boat. Dracula, in an attempt to escape, transforms into a bat, but the Wolf Man snares him and both fall over a balcony and into the rocky seas below. Joan abruptly wakes from her trance, while the boys escape the castle and head to the pier, with the Monster in pursuit. Once again Chick and Wilbur encounter Mr. MacDougal, who still insists that he wants his exhibits. They loudly reply, \"..here comes one of them now!\" When the Monster appears, MacDougal and his partner jump off the pier. Chick and Wilbur attempt to escape in a rowboat that is securely tied to the pier. The Monster throws barrels at them, in a series of near misses. Wilbur finally unties the boat, while Stevens and Joan arrive and set the pier ablaze. The Monster turns around and marches into the flames, slowing and succumbing as the pier collapses into the water.</p>\n<p>Just as Chick and Wilbur relax, they hear a disembodied voice (<a href=\"../../../../articles/v/i/n/Vincent_Price_ab84.html\" title=\"Vincent Price\">Vincent Price</a>) and see a cigarette floating in the air: \"Allow me to introduce myself, I'm the <a href=\"../../../../articles/i/n/v/Invisible_Man_894b.html\" title=\"Invisible Man\">Invisible Man</a>!\" The boys jump off the boat and swim away as the Invisible Man lights his cigarette and laughs. (This scene presaged 1951's <i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Invisible_Man_c511.html\" title=\"Abbott and Costello Meet the Invisible Man\">Abbott and Costello Meet the Invisible Man</a></i>, though Price did not star, and all characters were different.</p>\n<p><a name=\"Cast\" id=\"Cast\"></a></p>\n<h2><span class=\"editsection\">[<a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Frankenstein_59d9.html\" title=\"Edit section: Cast\">edit</a>]</span> <span class=\"mw-headline\">Cast</span></h2>\n<ul>\n<li><a href=\"../../../../articles/b/u/d/Bud_Abbott_cd1f.html\" title=\"Bud Abbott\">Bud Abbott</a> as Chick Young</li>\n<li><a href=\"../../../../articles/l/o/u/Lou_Costello_553d.html\" title=\"Lou Costello\">Lou Costello</a> as Wilbur Grey</li>\n<li><a href=\"../../../../articles/l/o/n/Lon_Chaney%2C_Jr._3ef0.html\" title=\"Lon Chaney, Jr.\">Lon Chaney, Jr.</a> as Larry Talbot, the <a href=\"../../../../articles/t/h/e/The_Wolf_Man_%281941_film%29_e5e9.html\" title=\"The Wolf Man (1941 film)\">Wolfman</a></li>\n<li><a href=\"../../../../articles/b/e/l/Bela_Lugosi_59d1.html\" class=\"mw-redirect\" title=\"Bela Lugosi\">Bela Lugosi</a> as <a href=\"../../../../articles/c/o/u/Count_Dracula_0c41.html\" title=\"Count Dracula\">Count Dracula</a></li>\n<li><a href=\"../../../../articles/g/l/e/Glenn_Strange_7693.html\" title=\"Glenn Strange\">Glenn Strange</a> as the <a href=\"../../../../articles/f/r/a/Frankenstein.html\" title=\"Frankenstein\">Frankenstein</a> Monster<sup id=\"cite_ref-0\" class=\"reference\"><a href=\"#cite_note-0\" title=\"\">[1]</a></sup></li>\n<li>Lenore Aubert as Dr. Sandra Mornay</li>\n<li><a href=\"../../../../articles/j/a/n/Jane_Randolph_7069.html\" title=\"Jane Randolph\">Jane Randolph</a> as Joan Raymond</li>\n<li>Charles Bradstreet as Dr. Stevens</li>\n</ul>\n<p><a name=\"Production\" id=\"Production\"></a></p>\n<h2><span class=\"editsection\">[<a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Frankenstein_59d9.html\" title=\"Edit section: Production\">edit</a>]</span> <span class=\"mw-headline\">Production</span></h2>\n<p>The film was originally intended to be titled <i>The Brain of Frankenstein</i>, but its name was changed prior to the filming schedule, which ran from <a href=\"../../../../articles/f/e/b/February_5.html\" title=\"February 5\">February 5</a> through <a href=\"../../../../articles/m/a/r/March_20.html\" title=\"March 20\">March 20</a>, 1948.</p>\n<p><a href=\"../../../../articles/w/a/l/Walter_Lantz_d857.html\" title=\"Walter Lantz\">Walter Lantz</a>, noted for the creation of <a href=\"../../../../articles/w/o/o/Woody_Woodpecker_3063.html\" title=\"Woody Woodpecker\">Woody Woodpecker</a>, provided the animation for Dracula's transformations.</p>\n<p>In a <a href=\"../../../../articles/1/9/9/1996.html\" title=\"1996\">1996</a> documentary, <i>100 Years of Horror</i>, hosted by <a href=\"../../../../articles/c/h/r/Christopher_Lee_b095.html\" title=\"Christopher Lee\">Christopher Lee</a>, it was revealed that the studio hired two additional comedians to add laughs between takes on the set.</p>\n<p>Costello hated the script for <i>Abbott and Costello Meet Frankenstein</i>.<sup id=\"cite_ref-1\" class=\"reference\"><a href=\"#cite_note-1\" title=\"\">[2]</a></sup> He said that his five-year-old daughter could have written something better, but later warmed to the film during production.</p>\n<p>During the filming of <i>Abbott and Costello Meet Frankenstein</i>, Glenn Strange found Costello so funny he would often break up laughing, necessitating many retakes. There were several pie fights between takes as well, but Abbott and Costello respected the three monsters (Chaney as the Wolfman, Lugosi as Dracula and Strange as the Monster) and made sure no pies were flung at the heavily made-up actors.</p>\n<p><a href=\"../../../../articles/b/o/r/Boris_Karloff_4d96.html\" title=\"Boris Karloff\">Boris Karloff</a> was originally approached to play the monster once again, but declined. He did, however, help promote the movie and can be seen in several publicity photos, including one where he is buying a ticket, even though he refused to actually see the film (considering it an insult).</p>\n<p>The Australian film board required that almost every scene involving a monster should be removed before release.<sup id=\"cite_ref-2\" class=\"reference\"><a href=\"#cite_note-2\" title=\"\">[3]</a></sup></p>\n<p><a name=\"Film_mistakes\" id=\"Film_mistakes\"></a></p>\n<h2><span class=\"editsection\">[<a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Frankenstein_59d9.html\" title=\"Edit section: Film mistakes\">edit</a>]</span> <span class=\"mw-headline\">Film mistakes</span></h2>\n<p>At one point in the film, where Abbott and Costello's characters are going through the revolving panel, Costello calls Abbott by his real name instead of his character's name. In addition, although the film is titled <i>Abbott and Costello Meet Frankenstein</i>, there is no character named Frankenstein in this movie. He is referenced for his work in bringing his creature to life, but the character himself does not appear. In addition, <a href=\"../../../../articles/d/r/a/Dracula.html\" title=\"Dracula\">Dracula</a>'s <a href=\"../../../../articles/r/e/f/Reflection.html\" title=\"Reflection\">reflection</a> can be seen in the mirror when he makes the <a href=\"../../../../articles/n/u/r/Nurse.html\" title=\"Nurse\">nurse</a> his next victim. The studio intended to remove the reflection, but failed to do before the theatrical release, and to this day can still be seen in the movie.</p>\n<p><a name=\"Cultural_references\" id=\"Cultural_references\"></a></p>\n<h2><span class=\"editsection\">[<a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Frankenstein_59d9.html\" title=\"Edit section: Cultural references\">edit</a>]</span> <span class=\"mw-headline\">Cultural references</span></h2>\n<table class=\"metadata plainlinks ambox ambox-style\" style=\"margin: auto;\">\n<tr>\n<td class=\"ambox-image\">\n<div style=\"width: 52px;\"><a href=\"../../../../articles/a/m/b/Image%7EAmbox_style.png_780a.html\" class=\"image\" title=\"Ambox style.png\"><img alt=\"\" src=\"../../../../images/local/d/d6/Ambox_style.png\" width=\"40\" height=\"40\" border=\"0\" /></a></div>\n</td>\n<td class=\"ambox-text\" style=\"width:auto;\"><b><a href=\"../../../../articles/t/r/i/Wikipedia%7ETrivia_sections_49e9.html\" title=\"Wikipedia:Trivia sections\">Trivia sections are discouraged</a></b> under <a href=\"../../../../articles/p/o/l/Wikipedia%7EPolicies_and_guidelines_cdad.html\" title=\"Wikipedia:Policies and guidelines\">Wikipedia guidelines</a>.<br />\n<small>The article could be improved by <a href=\"../../../../articles/h/a/n/Wikipedia%7EHandling_trivia_c9aa.html#Recommendations_for_handling_trivia\" title=\"Wikipedia:Handling trivia\">integrating</a> relevant items and removing <a href=\"../../../../articles/w/h/a/Wikipedia%7EWhat_Wikipedia_is_not_86da.html\" title=\"Wikipedia:What Wikipedia is not\">inappropriate</a> ones.</small></td>\n</tr>\n</table>\n<ul>\n<li>In a <a href=\"../../../../articles/2/0/0/2006.html\" title=\"2006\">2006</a> episode of Iconoclasts on the <a href=\"../../../../articles/s/u/n/Sundance_Channel_764e.html\" title=\"Sundance Channel\">Sundance Channel</a>, <a href=\"../../../../articles/q/u/e/Quentin_Tarantino_858b.html\" title=\"Quentin Tarantino\">Quentin Tarantino</a> cited the film as his favorite childhood movie because \"when it was supposed to be funny, it was really funny, and when it was supposed to be scary, it was really scary.\"</li>\n<li>The film was unofficially remade in Mexico as <i>Frankenstein, el Vampiro y Compañía</i> (1962) and in Egypt as <i>Haram Alek</i> (1953).<sup id=\"cite_ref-3\" class=\"reference\"><a href=\"#cite_note-3\" title=\"\">[4]</a></sup></li>\n<li>In the <i><a href=\"../../../../articles/e/n/t/Star_Trek%7E_Enterprise_849e.html\" title=\"Star Trek: Enterprise\">Star Trek: Enterprise</a></i> episode \"<a href=\"../../../../articles/h/o/r/Horizon_%28Enterprise_episode%29_6d7c.html\" class=\"mw-redirect\" title=\"Horizon (Enterprise episode)\">Horizon</a>\", <a href=\"../../../../articles/t/r/i/Trip_Tucker_96a0.html\" class=\"mw-redirect\" title=\"Trip Tucker\">Trip Tucker</a> wanted to show the film.</li>\n<li>In an episode of <i><a href=\"../../../../articles/h/o/m/Home_Improvement_0a18.html\" class=\"mw-redirect\" title=\"Home Improvement\">Home Improvement</a></i> in which Mark is putting together a project for <a href=\"../../../../articles/f/i/l/Film.html\" title=\"Film\">film</a> class, after Tim tells his other sons that film was something he himself appreciated in school, Randy sarcastically quips back that his favorite movie was <i>Abbott and Costello Meet Frankenstein</i>.<sup class=\"noprint Template-Fact\"><span title=\"This claim needs references to reliable sources&#160;since February 2008\" style=\"white-space: nowrap;\">[<i><a href=\"../../../../articles/c/i/t/Wikipedia%7ECitation_needed_0174.html\" title=\"Wikipedia:Citation needed\">citation needed</a></i>]</span></sup></li>\n<li>In 1954, an Egyptian film studio created Ismil and Abdel Meet Frankenstein, a scene-for-scene <a href=\"../../../../articles/r/e/m/Remake.html\" title=\"Remake\">remake</a> of the 1948 classic. This version is not commercially available on <a href=\"../../../../articles/d/v/d/DVD_1991.html\" title=\"DVD\">DVD</a>, but is scheduled for a public film showing at the <a href=\"../../../../articles/m/i/d/Mid-Atlantic_Nostalgia_Convention_a12f.html\" title=\"Mid-Atlantic Nostalgia Convention\">Mid-Atlantic Nostalgia Convention</a> in <a href=\"../../../../articles/s/e/p/September.html\" title=\"September\">September</a> <a href=\"../../../../articles/2/0/0/2008.html\" title=\"2008\">2008</a>.</li>\n</ul>\n<p><a name=\"Routines\" id=\"Routines\"></a></p>\n<h2><span class=\"editsection\">[<a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Frankenstein_59d9.html\" title=\"Edit section: Routines\">edit</a>]</span> <span class=\"mw-headline\">Routines</span></h2>\n<p>The <i>Moving Candle</i> routine previously used in <i><a href=\"../../../../articles/h/o/l/Hold_That_Ghost_5d90.html\" title=\"Hold That Ghost\">Hold That Ghost</a></i> was utilized again in this film.</p>\n<p><a name=\"DVD_releases\" id=\"DVD_releases\"></a></p>\n<h2><span class=\"editsection\">[<a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Frankenstein_59d9.html\" title=\"Edit section: DVD releases\">edit</a>]</span> <span class=\"mw-headline\">DVD releases</span></h2>\n<table class=\"gallery\" cellspacing=\"0\" cellpadding=\"0\">\n<tr>\n<td>\n<div class=\"gallerybox\" style=\"width: 155px;\">\n<div class=\"thumb\" style=\"padding: 13px 0; width: 150px;\">\n<div style=\"margin-left: auto; margin-right: auto; width: 120px;\"><a href=\"../../../../articles/m/o/v/Image%7EMovie_DVD_cover_abbott_%26_costello_meet_frankenstein.jpg_4342.html\" class=\"image\" title=\"Movie DVD cover abbott &amp; costello meet frankenstein.jpg\"><img alt=\"\" src=\"../../../../images/local/thumb/4/46/Movie_DVD_cover_abbott_&amp;_costello_meet_frankenstein.jpg/85px-Movie_DVD_cover_abbott_&amp;_costello_meet_frankenstein.jpg\" width=\"85\" height=\"120\" border=\"0\" /></a></div>\n</div>\n<div class=\"gallerytext\">\n<center>August 29, 2000</center>\n</div>\n</div>\n</td>\n<td>\n<div class=\"gallerybox\" style=\"width: 155px;\">\n<div class=\"thumb\" style=\"padding: 13px 0; width: 150px;\">\n<div style=\"margin-left: auto; margin-right: auto; width: 120px;\"><a href=\"../../../../articles/a/%26/c/Image%7EA%26cdvd3.jpg_6f62.html\" class=\"image\" title=\"A&amp;cdvd3.jpg\"><img alt=\"\" src=\"../../../../images/local/thumb/5/55/A&amp;cdvd3.jpg/84px-A&amp;cdvd3.jpg\" width=\"84\" height=\"120\" border=\"0\" /></a></div>\n</div>\n<div class=\"gallerytext\">\n<center>August 3, 2004</center>\n</div>\n</div>\n</td>\n</tr>\n</table>\n<p><a name=\"Notes\" id=\"Notes\"></a></p>\n<h2><span class=\"editsection\">[<a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Frankenstein_59d9.html\" title=\"Edit section: Notes\">edit</a>]</span> <span class=\"mw-headline\">Notes</span></h2>\n<div class=\"references-small\">\n<ol class=\"references\">\n<li id=\"cite_note-0\"><b><a href=\"#cite_ref-0\" title=\"\">^</a></b> The monster is actually played by two actors. Glenn Strange plays him for most of the film, but when he broke his foot during production, Lon Chaney, Jr. (who previously played the monster in <i><a href=\"../../../../articles/t/h/e/The_Ghost_of_Frankenstein_9d19.html\" title=\"The Ghost of Frankenstein\">The Ghost of Frankenstein</a></i>), took over the role for a portion of the laboratory battle sequence.</li>\n<li id=\"cite_note-1\"><b><a href=\"#cite_ref-1\" title=\"\">^</a></b> Furmanek, Bob and Ron Palumbo (1991). <i>Abbott and Costello in Hollywood</i>. New York: Perigee Books. <a href=\"../../../../articles/b/o/o/Special%7EBookSources_0399516050_5a3e.html\" class=\"internal\">ISBN 0-399-51605-0</a></li>\n<li id=\"cite_note-2\"><b><a href=\"#cite_ref-2\" title=\"\">^</a></b> Furmanek, Bob and Ron Palumbo (1991). <i>Abbott and Costello in Hollywood</i>. New York: Perigee Books. <a href=\"../../../../articles/b/o/o/Special%7EBookSources_0399516050_5a3e.html\" class=\"internal\">ISBN 0-399-51605-0</a></li>\n<li id=\"cite_note-3\"><b><a href=\"#cite_ref-3\" title=\"\">^</a></b> <a href=\"http://frankensteinia.blogspot.com/2007/09/frankenstein-gets-knocked-off.html\" class=\"external text\" title=\"http://frankensteinia.blogspot.com/2007/09/frankenstein-gets-knocked-off.html\" rel=\"nofollow\">Frankensteinia: The Frankenstein Blog: Frankenstein Gets Knocked-Off</a></li>\n</ol>\n</div>\n<p><a name=\"External_links\" id=\"External_links\"></a></p>\n<h2><span class=\"editsection\">[<a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Frankenstein_59d9.html\" title=\"Edit section: External links\">edit</a>]</span> <span class=\"mw-headline\">External links</span></h2>\n<ul>\n<li><a href=\"http://www.imdb.com/title/tt0040068/\" class=\"external text\" title=\"http://www.imdb.com/title/tt0040068/\" rel=\"nofollow\"><i>Abbott and Costello Meet Frankenstein</i></a> at the <a href=\"../../../../articles/i/n/t/Internet_Movie_Database_7ea7.html\" title=\"Internet Movie Database\">Internet Movie Database</a></li>\n<li><a href=\"http://www.allmovie.com/cg/avg.dll?p=avg&amp;sql=1:574\" class=\"external text\" title=\"http://www.allmovie.com/cg/avg.dll?p=avg&amp;sql=1:574\" rel=\"nofollow\"><i>Abbott and Costello Meet Frankenstein</i></a> at <a href=\"../../../../articles/a/l/l/Allmovie.html\" title=\"Allmovie\">Allmovie</a></li>\n</ul>\n<table class=\"navbox\" cellspacing=\"0\" style=\";\">\n<tr>\n<td style=\"padding:2px;\">\n<table cellspacing=\"0\" class=\"nowraplinks collapsible autocollapse\" style=\"width:100%;background:transparent;color:inherit;;\">\n<tr>\n<th style=\";\" colspan=\"2\" class=\"navbox-title\">\n<div style=\"float:left; width:6em;text-align:left;\">\n<div class=\"noprint plainlinksneverexpand\" style=\"background-color:transparent; padding:0; white-space:nowrap; font-weight:normal; font-size:xx-small;&#160;;;border:none;;\"><a href=\"../../../../articles/a/b/b/Template%7EAbbott_and_Costello_8f59.html\" title=\"Template:Abbott and Costello\"><span title=\"View this template\" style=\";;border:none;;\">v</span></a>&#160;<span style=\"font-size:80%;\">•</span>&#160;<a href=\"../../../../articles/a/b/b/Template_talk%7EAbbott_and_Costello_ba36.html\" title=\"Template talk:Abbott and Costello\"><span style=\"color:#002bb8;;;border:none;;\" title=\"Discussion about this template\">d</span></a>&#160;<span style=\"font-size:80%;\">•</span>&#160;<a href=\"http://en.wikipedia.org../../../../articles/a/b/b/Template%7EAbbott_and_Costello_8f59.html\" class=\"external text\" title=\"http://en.wikipedia.org../../../../articles/a/b/b/Template%7EAbbott_and_Costello_8f59.html\" rel=\"nofollow\"><span style=\"color:#002bb8;;;border:none;;\" title=\"You can edit this template. Please use the preview button before saving.\">e</span></a></div>\n</div>\n<span style=\"font-size:110%;\"><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_fa65.html\" title=\"Abbott and Costello\">Abbott and Costello</a></span></th>\n</tr>\n<tr style=\"height:2px;\">\n<td></td>\n</tr>\n<tr>\n<td colspan=\"2\" style=\"width:100%;padding:0px;;;\" class=\"navbox-list navbox-odd\">\n<div style=\"padding:0em 0.25em\"><span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/o/n/e/One_Night_in_the_Tropics_9a69.html\" title=\"One Night in the Tropics\">One Night in the Tropics</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/b/u/c/Buck_Privates_bda4.html\" title=\"Buck Privates\">Buck Privates</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/i/n/_/In_the_Navy_%28film%29_e5f7.html\" title=\"In the Navy (film)\">In the Navy</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/h/o/l/Hold_That_Ghost_5d90.html\" title=\"Hold That Ghost\">Hold That Ghost</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/k/e/e/Keep_%27Em_Flying_fb10.html\" title=\"Keep 'Em Flying\">Keep 'Em Flying</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/r/i/d/Ride_%27Em_Cowboy_370e.html\" title=\"Ride 'Em Cowboy\">Ride 'Em Cowboy</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/r/i/o/Rio_Rita_%281942_film%29_f599.html\" title=\"Rio Rita (1942 film)\">Rio Rita</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/p/a/r/Pardon_My_Sarong_51a7.html\" title=\"Pardon My Sarong\">Pardon My Sarong</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/w/h/o/Who_Done_It__%281942_film%29_d608.html\" title=\"Who Done It? (1942 film)\">Who Done It?</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/i/t/_/It_Ain%27t_Hay_d1bc.html\" title=\"It Ain't Hay\">It Ain't Hay</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/h/i/t/Hit_the_Ice_%28film%29_79b7.html\" title=\"Hit the Ice (film)\">Hit the Ice</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/i/n/_/In_Society_789c.html\" title=\"In Society\">In Society</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/l/o/s/Lost_in_a_Harem_66be.html\" title=\"Lost in a Harem\">Lost in a Harem</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/h/e/r/Here_Come_the_Co-Eds_9097.html\" title=\"Here Come the Co-Eds\">Here Come the Co-Eds</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/t/h/e/The_Naughty_Nineties_aad8.html\" title=\"The Naughty Nineties\">The Naughty Nineties</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_in_Hollywood_62d2.html\" title=\"Abbott and Costello in Hollywood\">Abbott and Costello in Hollywood</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/l/i/t/Little_Giant_66a6.html\" title=\"Little Giant\">Little Giant</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/t/h/e/The_Time_of_Their_Lives_831c.html\" title=\"The Time of Their Lives\">The Time of Their Lives</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/b/u/c/Buck_Privates_Come_Home_c7e4.html\" title=\"Buck Privates Come Home\">Buck Privates Come Home</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/t/h/e/The_Wistful_Widow_of_Wagon_Gap_0dfb.html\" title=\"The Wistful Widow of Wagon Gap\">The Wistful Widow of Wagon Gap</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/t/h/e/The_Noose_Hangs_High_a16d.html\" title=\"The Noose Hangs High\">The Noose Hangs High</a></i> •</span> <span style=\"white-space:nowrap;\"><i><strong class=\"selflink\">Abbott and Costello Meet Frankenstein</strong></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/m/e/x/Mexican_Hayride_c692.html\" title=\"Mexican Hayride\">Mexican Hayride</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/a/f/r/Africa_Screams_4927.html\" title=\"Africa Screams\">Africa Screams</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Killer%2C_Boris_Karloff_0b24.html\" title=\"Abbott and Costello Meet the Killer, Boris Karloff\">Abbott and Costello Meet the Killer, Boris Karloff</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_in_the_Foreign_Legion_3ad4.html\" title=\"Abbott and Costello in the Foreign Legion\">Abbott and Costello in the Foreign Legion</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Invisible_Man_c511.html\" title=\"Abbott and Costello Meet the Invisible Man\">Abbott and Costello Meet the Invisible Man</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/c/o/m/Comin%27_Round_the_Mountain_9601.html\" title=\"Comin' Round the Mountain\">Comin' Round the Mountain</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/j/a/c/Jack_and_the_Beanstalk_%281952_film%29_018a.html\" title=\"Jack and the Beanstalk (1952 film)\">Jack and the Beanstalk</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/l/o/s/Lost_in_Alaska_461e.html\" title=\"Lost in Alaska\">Lost in Alaska</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Captain_Kidd_7dab.html\" title=\"Abbott and Costello Meet Captain Kidd\">Abbott and Costello Meet Captain Kidd</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Go_to_Mars_0a6a.html\" title=\"Abbott and Costello Go to Mars\">Abbott and Costello Go to Mars</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Dr._Jekyll_and_Mr._Hyde_5399.html\" title=\"Abbott and Costello Meet Dr. Jekyll and Mr. Hyde\">Abbott and Costello Meet Dr. Jekyll and Mr. Hyde</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Keystone_Kops_a436.html\" title=\"Abbott and Costello Meet the Keystone Kops\">Abbott and Costello Meet the Keystone Kops</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Mummy_0243.html\" title=\"Abbott and Costello Meet the Mummy\">Abbott and Costello Meet the Mummy</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/d/a/n/Dance_with_Me_Henry_dbd4.html\" title=\"Dance with Me Henry\">Dance with Me Henry</a></i> •</span> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/t/h/e/The_World_of_Abbott_and_Costello_fb17.html\" title=\"The World of Abbott and Costello\">The World of Abbott and Costello</a></i></span><br />\n<b>Lou Costello solo film:</b> <span style=\"white-space:nowrap;\"><i><a href=\"../../../../articles/t/h/e/The_30_Foot_Bride_of_Candy_Rock_7ce2.html\" title=\"The 30 Foot Bride of Candy Rock\">The 30 Foot Bride of Candy Rock</a></i></span></div>\n</td>\n</tr>\n</table>\n</td>\n</tr>\n</table>\n<table class=\"navbox\" cellspacing=\"0\" style=\";\">\n<tr>\n<td style=\"padding:2px;\">\n<table cellspacing=\"0\" class=\"nowraplinks collapsible autocollapse\" style=\"width:100%;background:transparent;color:inherit;;\">\n<tr>\n<th style=\";\" colspan=\"2\" class=\"navbox-title\">\n<div style=\"float:left; width:6em;text-align:left;\">\n<div class=\"noprint plainlinksneverexpand\" style=\"background-color:transparent; padding:0; white-space:nowrap; font-weight:normal; font-size:xx-small;&#160;;;border:none;;\"><a href=\"../../../../articles/u/n/i/Template%7EUniversal_Horror_5eb2.html\" title=\"Template:Universal Horror\"><span title=\"View this template\" style=\";;border:none;;\">v</span></a>&#160;<span style=\"font-size:80%;\">•</span>&#160;<a href=\"../../../../articles/u/n/i/Template_talk%7EUniversal_Horror_d0ee.html\" title=\"Template talk:Universal Horror\"><span style=\"color:#002bb8;;;border:none;;\" title=\"Discussion about this template\">d</span></a>&#160;<span style=\"font-size:80%;\">•</span>&#160;<a href=\"http://en.wikipedia.org../../../../articles/u/n/i/Template%7EUniversal_Horror_5eb2.html\" class=\"external text\" title=\"http://en.wikipedia.org../../../../articles/u/n/i/Template%7EUniversal_Horror_5eb2.html\" rel=\"nofollow\"><span style=\"color:#002bb8;;;border:none;;\" title=\"You can edit this template. Please use the preview button before saving.\">e</span></a></div>\n</div>\n<span style=\"font-size:110%;\"><a href=\"../../../../articles/u/n/i/Universal_Horror_db04.html\" title=\"Universal Horror\">Universal Horror</a> film series</span></th>\n</tr>\n<tr style=\"height:2px;\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">Dracula</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-odd\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/d/r/a/Dracula_%281931_film%29.html\" title=\"Dracula (1931 film)\">Dracula</a></i> (1931)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%28Spanish-language_version%29_27a3.html\" title=\"Dracula (Spanish-language version)\">Dracula (Spanish-language version)</a></i> (1931)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula%27s_Daughter_d3d9.html\" title=\"Dracula's Daughter\">Dracula's Daughter</a></i> (1936)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/s/o/n/Son_of_Dracula_%281943_film%29_48c1.html\" title=\"Son of Dracula (1943 film)\">Son of Dracula</a></i> (1943)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">Frankenstein's Monster</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-even\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/f/r/a/Frankenstein_%281931_film%29.html\" title=\"Frankenstein (1931 film)\">Frankenstein</a></i> (1931)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/b/r/i/Bride_of_Frankenstein_ebc1.html\" title=\"Bride of Frankenstein\">Bride of Frankenstein</a></i> (1935)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/s/o/n/Son_of_Frankenstein_a9ca.html\" title=\"Son of Frankenstein\">Son of Frankenstein</a></i> (1939)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Ghost_of_Frankenstein_9d19.html\" title=\"The Ghost of Frankenstein\">The Ghost of Frankenstein</a></i> (1942)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/h/o/u/House_of_Frankenstein_1997_aa1e.html\" title=\"House of Frankenstein 1997\">House of Frankenstein 1997</a></i></div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">The Wolf Man<br />\nalone and with other monsters</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-odd\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/t/h/e/The_Wolf_Man_%281941_film%29_e5e9.html\" title=\"The Wolf Man (1941 film)\">The Wolf Man</a></i> (1941)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/f/r/a/Frankenstein_Meets_the_Wolf_Man_eab7.html\" title=\"Frankenstein Meets the Wolf Man\">Frankenstein Meets the Wolf Man</a></i> (1943)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/h/o/u/House_of_Frankenstein_%281944_film%29_991c.html\" title=\"House of Frankenstein (1944 film)\">House of Frankenstein</a></i> (1944)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/h/o/u/House_of_Dracula_f4bb.html\" title=\"House of Dracula\">House of Dracula</a></i> (1945)<span style=\"font-weight:bold;\">&#160;·</span> <i><strong class=\"selflink\">Abbott and Costello Meet Frankenstein</strong></i> (1948)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">London werewolves</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-even\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/w/e/r/Werewolf_of_London_a436.html\" title=\"Werewolf of London\">Werewolf of London</a></i> (1935)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/s/h/e/She-Wolf_of_London_%28film%29_1758.html\" title=\"She-Wolf of London (film)\">She-Wolf of London</a></i> (1946)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">Mummies</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-odd\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/t/h/e/The_Mummy_%281932_film%29_49a8.html\" title=\"The Mummy (1932 film)\">The Mummy</a></i> (1932)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Mummy%27s_Hand_64ab.html\" title=\"The Mummy's Hand\">The Mummy's Hand</a></i> (1940)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Mummy%27s_Tomb_e782.html\" title=\"The Mummy's Tomb\">The Mummy's Tomb</a></i> (1942)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Mummy%27s_Ghost_75ba.html\" title=\"The Mummy's Ghost\">The Mummy's Ghost</a></i> (1944)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Mummy%27s_Curse_8ed3.html\" title=\"The Mummy's Curse\">The Mummy's Curse</a></i> (1944)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Mummy_0243.html\" title=\"Abbott and Costello Meet the Mummy\">Abbott and Costello Meet the Mummy</a></i> (1955)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">The Invisible Man</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-even\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/t/h/e/The_Invisible_Man_%281933_film%29_8511.html\" class=\"mw-redirect\" title=\"The Invisible Man (1933 film)\">The Invisible Man</a></i> (1933)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Invisible_Man_Returns_625c.html\" title=\"The Invisible Man Returns\">The Invisible Man Returns</a></i> (1940)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Invisible_Woman_143f.html\" title=\"The Invisible Woman\">The Invisible Woman</a></i> (1940)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/i/n/v/Invisible_Agent_77a5.html\" title=\"Invisible Agent\">Invisible Agent</a></i> (1942)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Invisible_Man%27s_Revenge_98c7.html\" title=\"The Invisible Man's Revenge\">The Invisible Man's Revenge</a></i> (1944)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_the_Invisible_Man_c511.html\" title=\"Abbott and Costello Meet the Invisible Man\">Abbott and Costello Meet the Invisible Man</a></i> (1951)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">The Phantom of the Opera</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-odd\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/t/h/e/The_Phantom_of_the_Opera_%281925_film%29_7f13.html\" title=\"The Phantom of the Opera (1925 film)\">The Phantom of the Opera</a></i> § (1925)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/p/h/a/Phantom_of_the_Opera_%281943_film%29_f074.html\" title=\"Phantom of the Opera (1943 film)\">Phantom of the Opera</a></i> (1943)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Climax_0fd4.html\" title=\"The Climax\">The Climax</a></i> (1944)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">Edgar Allan Poe</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-even\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/m/u/r/Murders_in_the_Rue_Morgue_%28film%29_e788.html\" title=\"Murders in the Rue Morgue (film)\">Murders in the Rue Morgue</a></i> (1932)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Black_Cat_%281934_film%29_6487.html\" title=\"The Black Cat (1934 film)\">The Black Cat</a></i> (1934)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Raven_%281935_film%29_e18f.html\" title=\"The Raven (1935 film)\">The Raven</a></i> (1935)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\"><a href=\"../../../../articles/i/n/n/Inner_Sanctum_5ea1.html\" class=\"mw-redirect\" title=\"Inner Sanctum\">Inner Sanctum</a> Mysteries</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-odd\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/c/a/l/Calling_Dr._Death_767f.html\" title=\"Calling Dr. Death\">Calling Dr. Death</a></i> (1943)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/w/e/i/Weird_Woman_c931.html\" title=\"Weird Woman\">Weird Woman</a></i> (1944)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/e/a/Dead_Man%27s_Eyes_ba92.html\" title=\"Dead Man's Eyes\">Dead Man's Eyes</a></i> (1944)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/s/t/r/Strange_Confession_a642.html\" title=\"Strange Confession\">Strange Confession</a></i> (1945)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Frozen_Ghost_e61f.html\" title=\"The Frozen Ghost\">The Frozen Ghost</a></i> (1945)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/p/i/l/Pillow_of_Death_61aa.html\" title=\"Pillow of Death\">Pillow of Death</a></i> (1945)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">The Ape Woman</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-even\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/c/a/p/Captive_Wild_Woman_6055.html\" title=\"Captive Wild Woman\">Captive Wild Woman</a></i> (1943)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/j/u/n/Jungle_Woman_9306.html\" title=\"Jungle Woman\">Jungle Woman</a></i> (1944)<span style=\"font-weight:bold;\">&#160;·</span> <i>The Jungle Captive</i> (1945)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">The Creature from the Black Lagoon</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-odd\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/c/r/e/Creature_from_the_Black_Lagoon_d27b.html\" title=\"Creature from the Black Lagoon\">Creature from the Black Lagoon</a></i> (1954)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/r/e/v/Revenge_of_the_Creature_4fe3.html\" title=\"Revenge of the Creature\">Revenge of the Creature</a></i> (1955)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Creature_Walks_Among_Us_510d.html\" title=\"The Creature Walks Among Us\">The Creature Walks Among Us</a></i> (1956)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">Others</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-even\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/t/h/e/The_Hunchback_of_Notre_Dame_%281923_film%29_14ab.html\" title=\"The Hunchback of Notre Dame (1923 film)\">The Hunchback of Notre Dame</a></i> § (1923)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Cat_and_the_Canary_%281927_film%29_5aac.html\" title=\"The Cat and the Canary (1927 film)\">The Cat and the Canary</a></i> § (1927)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Man_Who_Laughs_%281928_film%29_2840.html\" title=\"The Man Who Laughs (1928 film)\">The Man Who Laughs</a></i> § (1928)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Last_Warning_81b0.html\" title=\"The Last Warning\">The Last Warning</a></i> § (1929)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Last_Performance_6098.html\" title=\"The Last Performance\">The Last Performance</a></i> § (1929)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Cat_Creeps_e2e0.html\" title=\"The Cat Creeps\">The Cat Creeps</a></i> (1930)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/l/a/_/La_Voluntad_del_muerto_c442.html\" title=\"La Voluntad del muerto\">La Voluntad del muerto</a></i> (1930)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Mystery_of_Edwin_Drood_%281935_film%29_ba28.html\" title=\"The Mystery of Edwin Drood (1935 film)\">The Mystery of Edwin Drood</a></i> (1935)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/o/w/Tower_of_London_%281939_film%29_f50b.html\" title=\"Tower of London (1939 film)\">Tower of London</a></i> (1939)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/m/a/n/Man_Made_Monster_67f4.html\" title=\"Man Made Monster\">Man Made Monster</a></i> (1941)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/n/i/g/Night_Monster_0dd1.html\" title=\"Night Monster\">Night Monster</a></i> (1942)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Mad_Ghoul_65e0.html\" title=\"The Mad Ghoul\">The Mad Ghoul</a></i> (1943)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/h/o/u/House_of_Horrors_5ece.html\" title=\"House of Horrors\">House of Horrors</a></i> (1946)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Strange_Door_59ee.html\" title=\"The Strange Door\">The Strange Door</a></i> (1951)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Black_Castle_e1f0.html\" title=\"The Black Castle\">The Black Castle</a></i> (1952)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Dr._Jekyll_and_Mr._Hyde_5399.html\" title=\"Abbott and Costello Meet Dr. Jekyll and Mr. Hyde\">Abbott and Costello Meet Dr. Jekyll and Mr Hyde</a></i> (1953)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/c/u/l/Cult_of_the_Cobra_807c.html\" title=\"Cult of the Cobra\">Cult of the Cobra</a></i> (1955)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/a/r/Tarantula_%28film%29.html\" title=\"Tarantula (film)\">Tarantula</a></i> (1955)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Mole_People_16c7.html\" title=\"The Mole People\">The Mole People</a></i> (1956)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Deadly_Mantis_d769.html\" title=\"The Deadly Mantis\">The Deadly Mantis</a></i> (1957)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Monolith_Monsters_2ba2.html\" title=\"The Monolith Monsters\">The Monolith Monsters</a></i> (1957)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/m/o/n/Monster_on_the_Campus_a4ea.html\" title=\"Monster on the Campus\">Monster on the Campus</a></i> (1958)</div>\n</td>\n</tr>\n<tr style=\"height:2px;\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-abovebelow\" style=\";\" colspan=\"2\"><b>Note:</b> § denotes a <a href=\"../../../../articles/s/i/l/Silent_film.html\" title=\"Silent film\">silent film</a>.</td>\n</tr>\n</table>\n</td>\n</tr>\n</table>\n<table class=\"navbox\" cellspacing=\"0\" style=\";\">\n<tr>\n<td style=\"padding:2px;\">\n<table cellspacing=\"0\" class=\"nowraplinks collapsible show\" style=\"width:100%;background:transparent;color:inherit;;\">\n<tr>\n<th style=\";\" colspan=\"2\" class=\"navbox-title\">\n<div style=\"float:left; width:6em;text-align:left;\">\n<div class=\"noprint plainlinksneverexpand\" style=\"background-color:transparent; padding:0; white-space:nowrap; font-weight:normal; font-size:xx-small;&#160;;;border:none;;\"><a href=\"../../../../articles/d/r/a/Template%7EDracula_31d6.html\" title=\"Template:Dracula\"><span title=\"View this template\" style=\";;border:none;;\">v</span></a>&#160;<span style=\"font-size:80%;\">•</span>&#160;<a href=\"../../../../articles/d/r/a/Template_talk%7EDracula_0ffd.html\" title=\"Template talk:Dracula\"><span style=\"color:#002bb8;;;border:none;;\" title=\"Discussion about this template\">d</span></a>&#160;<span style=\"font-size:80%;\">•</span>&#160;<a href=\"http://en.wikipedia.org../../../../articles/d/r/a/Template%7EDracula_31d6.html\" class=\"external text\" title=\"http://en.wikipedia.org../../../../articles/d/r/a/Template%7EDracula_31d6.html\" rel=\"nofollow\"><span style=\"color:#002bb8;;;border:none;;\" title=\"You can edit this template. Please use the preview button before saving.\">e</span></a></div>\n</div>\n<span style=\"font-size:110%;\"><a href=\"../../../../articles/d/r/a/Dracula.html\" title=\"Dracula\">Dracula</a></span></th>\n</tr>\n<tr style=\"height:2px;\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">Characters of Dracula</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-odd\">\n<div style=\"padding:0em 0.25em\"><a href=\"../../../../articles/c/o/u/Count_Dracula_0c41.html\" title=\"Count Dracula\">Count Dracula</a> <span style=\"font-weight:bold;\">&#160;·</span> <a href=\"../../../../articles/j/o/n/Jonathan_Harker_f513.html\" title=\"Jonathan Harker\">Jonathan Harker</a> <span style=\"font-weight:bold;\">&#160;·</span> <a href=\"../../../../articles/m/i/n/Mina_Harker_1b1a.html\" title=\"Mina Harker\">Mina Harker</a> <span style=\"font-weight:bold;\">&#160;·</span> <a href=\"../../../../articles/a/b/r/Abraham_Van_Helsing_ecd9.html\" title=\"Abraham Van Helsing\">Abraham Van Helsing</a> <span style=\"font-weight:bold;\">&#160;·</span> <a href=\"../../../../articles/l/u/c/Lucy_Westenra_645b.html\" title=\"Lucy Westenra\">Lucy Westenra</a> <span style=\"font-weight:bold;\">&#160;·</span> <a href=\"../../../../articles/a/r/t/Arthur_Holmwood_07e5.html\" title=\"Arthur Holmwood\">Arthur Holmwood</a> <span style=\"font-weight:bold;\">&#160;·</span> <a href=\"../../../../articles/j/o/h/John_Seward_d538.html\" title=\"John Seward\">Dr. John Seward</a> <span style=\"font-weight:bold;\">&#160;·</span> <a href=\"../../../../articles/q/u/i/Quincey_Morris_117e.html\" title=\"Quincey Morris\">Quincey Morris</a> <span style=\"font-weight:bold;\">&#160;·</span> <a href=\"../../../../articles/r/e/n/Renfield.html\" title=\"Renfield\">Renfield</a> <span style=\"font-weight:bold;\">&#160;·</span> <a href=\"../../../../articles/b/r/i/Brides_of_Dracula_9ecc.html\" title=\"Brides of Dracula\">Brides</a></div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">Film Adaptations of Dracula</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-even\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/n/o/s/Nosferatu.html\" title=\"Nosferatu\">Nosferatu</a></i> (1922)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%281931_film%29.html\" title=\"Dracula (1931 film)\">Dracula</a></i> (1931)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%28Spanish-language_version%29_27a3.html\" title=\"Dracula (Spanish-language version)\">Dracula</a></i> (1931 Spanish Version)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%281958_film%29.html\" title=\"Dracula (1958 film)\">Dracula</a></i> (1958)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_Has_Risen_from_the_Grave_ffea.html\" title=\"Dracula Has Risen from the Grave\">Dracula Has Risen from the Grave</a></i> (1968)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/c/o/u/Count_Dracula_%281970_film%29_bebb.html\" title=\"Count Dracula (1970 film)\">Count Dracula</a></i> (1970)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%281973%29.html\" title=\"Dracula (1973)\">Dracula</a></i> (1973)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/c/o/u/Count_Dracula_%281977%29_c3fa.html\" title=\"Count Dracula (1977)\">Count Dracula (1977)</a></i> (1977)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%281979_film%29.html\" title=\"Dracula (1979 film)\">Dracula</a></i> (1979)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/n/o/s/Nosferatu_the_Vampyre_d854.html\" title=\"Nosferatu the Vampyre\">Nosferatu the Vampyre</a></i> (1979)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/b/r/a/Bram_Stoker%27s_Dracula_d465.html\" title=\"Bram Stoker's Dracula\">Bram Stoker's Dracula</a></i> (1992)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%282002%29.html\" title=\"Dracula (2002)\">Dracula</a></i> (2002)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/p/a/g/Dracula%7E_Pages_from_a_Virgin%27s_Diary_0e8d.html\" title=\"Dracula: Pages from a Virgin's Diary\">Dracula: Pages from a Virgin's Diary</a></i> (2002)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%282006%29.html\" title=\"Dracula (2006)\">Dracula</a></i> (2006)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">Other films featuring Dracula</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-odd\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/d/r/a/Dracula%27s_Daughter_d3d9.html\" title=\"Dracula's Daughter\">Dracula's Daughter</a></i> (1936)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/s/o/n/Son_of_Dracula_%281943_film%29_48c1.html\" title=\"Son of Dracula (1943 film)\">Son of Dracula</a></i> (1943)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/h/o/u/House_of_Frankenstein_%281944_film%29_991c.html\" title=\"House of Frankenstein (1944 film)\">House of Frankenstein</a></i> (1944)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/h/o/u/House_of_Dracula_f4bb.html\" title=\"House of Dracula\">House of Dracula</a></i> (1945)<span style=\"font-weight:bold;\">&#160;·</span> <i><strong class=\"selflink\">Abbott and Costello Meet Frankenstein</strong></i> (1948)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Brides_of_Dracula_6e76.html\" class=\"mw-redirect\" title=\"The Brides of Dracula\">The Brides of Dracula</a></i> (1960)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/p/r/i/Dracula%7E_Prince_of_Darkness_5421.html\" title=\"Dracula: Prince of Darkness\">Dracula: Prince of Darkness</a></i> (1966)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_Has_Risen_from_the_Grave_ffea.html\" title=\"Dracula Has Risen from the Grave\">Dracula Has Risen from the Grave</a></i> (1968)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/a/s/Taste_the_Blood_of_Dracula_a80c.html\" title=\"Taste the Blood of Dracula\">Taste the Blood of Dracula</a></i> (1970)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/s/c/a/Scars_of_Dracula_92fb.html\" title=\"Scars of Dracula\">Scars of Dracula</a></i> (1970)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_AD_1972_8f87.html\" title=\"Dracula AD 1972\">Dracula AD 1972</a></i> (1972)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Satanic_Rites_of_Dracula_7764.html\" title=\"The Satanic Rites of Dracula\">The Satanic Rites of Dracula</a></i> (1973)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/The_Legend_of_the_7_Golden_Vampires_1a81.html\" title=\"The Legend of the 7 Golden Vampires\">The Legend of the 7 Golden Vampires</a></i> (1974)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/h/e/Dark_Prince%7E_The_True_Story_of_Dracula_c032.html\" title=\"Dark Prince: The True Story of Dracula\">Dark Prince: The True Story of Dracula</a></i> (2000)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_2000.html\" title=\"Dracula 2000\">Dracula 2000</a></i> (2000)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/a/s/c/Dracula_II%7E_Ascension_cd81.html\" title=\"Dracula II: Ascension\">Dracula II: Ascension</a></i> (2003)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_3000.html\" title=\"Dracula 3000\">Dracula 3000</a></i> (2004)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/t/r/i/Blade%7E_Trinity_5851.html\" title=\"Blade: Trinity\">Blade: Trinity</a></i> (2004)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/v/a/n/Van_Helsing_%28film%29_95a7.html\" title=\"Van Helsing (film)\">Van Helsing</a></i> (2004)<span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/l/e/g/Dracula_III%7E_Legacy_c42f.html\" title=\"Dracula III: Legacy\">Dracula III: Legacy</a></i> (2005)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">Stage Adaptations of Dracula</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-even\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/d/r/a/Dracula_%28play%29.html\" title=\"Dracula (play)\">Dracula</a></i> (1924) <span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/c/o/u/Count_Dracula_%281972%29_455a.html\" title=\"Count Dracula (1972)\">Count Dracula</a></i> (1972) <span style=\"font-weight:bold;\">&#160;·</span> Dracula, a Musical Nightmare (1974) <span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%281980%29.html\" title=\"Dracula (1980)\">Dracula</a></i> (1980) <span style=\"font-weight:bold;\">&#160;·</span> Dracula: the Musical? (1982) <span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%281995%29.html\" title=\"Dracula (1995)\">Dracula</a></i> (1995) <span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%281996%29.html\" title=\"Dracula (1996)\">Dracula</a></i> (1996) <span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula_%282000%29.html\" title=\"Dracula (2000)\">Dracula</a></i> (2000) <span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/r/a/Dracula%2C_the_Musical_6c20.html\" title=\"Dracula, the Musical\">Dracula, the Musical</a></i> (2004)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">Parodies of Dracula</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-odd\">\n<div style=\"padding:0em 0.25em\"><i><a href=\"../../../../articles/b/l/a/Blacula.html\" title=\"Blacula\">Blacula</a></i> (1972) <span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/l/o/v/Love_at_First_Bite_8d9c.html\" class=\"mw-redirect\" title=\"Love at First Bite\">Love at First Bite</a></i> (1979) <span style=\"font-weight:bold;\">&#160;·</span> <i><a href=\"../../../../articles/d/e/a/Dracula%7E_Dead_and_Loving_It_d1fb.html\" title=\"Dracula: Dead and Loving It\">Dracula: Dead and Loving It</a></i> (1995)</div>\n</td>\n</tr>\n<tr style=\"height:2px\">\n<td></td>\n</tr>\n<tr>\n<td class=\"navbox-group\" style=\";;\">Dracula in video games</td>\n<td style=\"text-align:left;border-left:2px solid #fdfdfd;width:100%;padding:0px;;;\" class=\"navbox-list navbox-even\">\n<div style=\"padding:0em 0.25em\"><a href=\"../../../../articles/d/r/a/Dracula_%28Castlevania%29_db73.html\" title=\"Dracula (Castlevania)\">Dracula (Castlevania)</a> <span style=\"font-weight:bold;\">&#160;·</span> <a href=\"../../../../articles/c/a/s/Castlevania.html\" title=\"Castlevania\">Castlevania</a> <span style=\"font-weight:bold;\">&#160;·</span> <a href=\"../../../../articles/a/l/u/Alucard_%28Castlevania%29_ead1.html\" title=\"Alucard (Castlevania)\">Alucard</a></div>\n</td>\n</tr>\n</table>\n</td>\n</tr>\n</table>\n\n\n<!-- \nNewPP limit report\nPreprocessor node count: 2425/1000000\nPost-expand include size: 80992/2048000 bytes\nTemplate argument size: 48214/2048000 bytes\nExpensive parser function count: 3/500\n-->\n<div class=\"printfooter\">\n</div>\n\t    <div id=\"catlinks\"><div id='catlinks' class='catlinks'><div id=\"mw-normal-catlinks\"><a href=\"../../../../articles/c/a/t/Special%7ECategories_101d.html\" title=\"Special:Categories\">Categories</a>:&#32;<span dir='ltr'><a href=\"../../../../articles/e/n/g/Category%7EEnglish-language_films_bc72.html\" title=\"Category:English-language films\">English-language films</a></span> | <span dir='ltr'><a href=\"../../../../articles/1/9/4/Category%7E1948_films.html\" title=\"Category:1948 films\">1948 films</a></span> | <span dir='ltr'><a href=\"../../../../articles/a/m/e/Category%7EAmerican_films_c371.html\" title=\"Category:American films\">American films</a></span> | <span dir='ltr'><a href=\"../../../../articles/c/o/m/Category%7EComedy_horror_films_fe9e.html\" title=\"Category:Comedy horror films\">Comedy horror films</a></span> | <span dir='ltr'><a href=\"../../../../articles/f/r/a/Category%7EFrankenstein_films_a72c.html\" title=\"Category:Frankenstein films\">Frankenstein films</a></span> | <span dir='ltr'><a href=\"../../../../articles/b/l/a/Category%7EBlack_and_white_films_27c4.html\" title=\"Category:Black and white films\">Black and white films</a></span> | <span dir='ltr'><a href=\"../../../../articles/b/_/m/Category%7EB_movies_16f7.html\" title=\"Category:B movies\">B movies</a></span> | <span dir='ltr'><a href=\"../../../../articles/u/n/i/Category%7EUnited_States_National_Film_Registry_films_7405.html\" title=\"Category:United States National Film Registry films\">United States National Film Registry films</a></span> | <span dir='ltr'><a href=\"../../../../articles/w/e/r/Category%7EWerewolves_in_film_and_television_e856.html\" title=\"Category:Werewolves in film and television\">Werewolves in film and television</a></span> | <span dir='ltr'><a href=\"../../../../articles/d/r/a/Category%7EDracula_films_b631.html\" title=\"Category:Dracula films\">Dracula films</a></span> | <span dir='ltr'><a href=\"../../../../articles/a/b/b/Category%7EAbbott_and_Costello_%28film_series%29_47a1.html\" title=\"Category:Abbott and Costello (film series)\">Abbott and Costello (film series)</a></span> | <span dir='ltr'><a href=\"../../../../articles/c/r/o/Category%7ECrossover_fiction_0d54.html\" title=\"Category:Crossover fiction\">Crossover fiction</a></span> | <span dir='ltr'><a href=\"../../../../articles/f/i/l/Category%7EFilms_directed_by_Charles_Barton_39a6.html\" title=\"Category:Films directed by Charles Barton\">Films directed by Charles Barton</a></span></div><div id=\"mw-hidden-catlinks\" class=\"mw-hidden-cats-hidden\">Hidden categories:&#32;<span dir='ltr'><a href=\"../../../../articles/a/r/t/Category%7EArticles_with_trivia_sections_from_June_2007_b36d.html\" title=\"Category:Articles with trivia sections from June 2007\">Articles with trivia sections from June 2007</a></span> | <span dir='ltr'><a href=\"../../../../articles/a/l/l/Category%7EAll_articles_with_unsourced_statements_2f67.html\" title=\"Category:All articles with unsourced statements\">All articles with unsourced statements</a></span> | <span dir='ltr'><a href=\"../../../../articles/a/r/t/Category%7EArticles_with_unsourced_statements_since_February_2008_7f92.html\" title=\"Category:Articles with unsourced statements since February 2008\">Articles with unsourced statements since February 2008</a></span></div></div></div>\t    <!-- end content -->\n\t    <div class=\"visualClear\"></div>\n\t  </div>\n\t</div>\n      </div>\n      <div id=\"column-one\">\n\t<div id=\"p-cactions\" class=\"portlet\">\n\t  <h5>Views</h5>\n\t  <ul>\n\t    <li id=\"ca-nstab-main\"\n\t       class=\"selected\"\t       ><a href=\"../../../../articles/a/b/b/Abbott_and_Costello_Meet_Frankenstein_59d9.html\">Article</a></li><li id=\"ca-talk\"\n\t       \t       ><a href=\"../../../../articles/a/b/b/Talk%7EAbbott_and_Costello_Meet_Frankenstein_d4fc.html\">Discussion</a></li><li id=\"ca-current\"\n\t       \t       ><a href=\"http://en.wikipedia.org/wiki/Abbott_and_Costello_Meet_Frankenstein\">Current revision</a></li>\t  </ul>\n\t</div>\n\t<div class=\"portlet\" id=\"p-logo\">\n\t  <a style=\"background-image: url(../../../../misc/Wiki.png);\"\n\t    href=\"../../../../index.html\"\n\t    title=\"Main Page\"></a>\n\t</div>\n\t<script type=\"text/javascript\"> if (window.isMSIE55) fixalpha(); </script>\n\t\t<div class='portlet' id='p-navigation'>\n\t  <h5>Navigation</h5>\n\t  <div class='pBody'>\n\t    <ul>\n\t    \t      <li id=\"n-mainpage\"><a href=\"../../../../index.html\">Main Page</a></li>\n\t     \t      <li id=\"n-Contents\"><a href=\"../../../../articles/c/o/n/Portal%7EContents_b878.html\">Contents</a></li>\n\t     \t      <li id=\"n-featuredcontent\"><a href=\"../../../../articles/f/e/a/Portal%7EFeatured_content_5442.html\">Featured content</a></li>\n\t     \t      <li id=\"n-currentevents\"><a href=\"../../../../articles/c/u/r/Portal%7ECurrent_events_bb60.html\">Current events</a></li>\n\t     \t    </ul>\n\t  </div>\n\t</div>\n\t\t<div class='portlet' id='p-interaction'>\n\t  <h5>Interaction</h5>\n\t  <div class='pBody'>\n\t    <ul>\n\t    \t      <li id=\"n-aboutsite\"><a href=\"../../../../articles/a/b/o/Wikipedia%7EAbout_8d82.html\">About Wikipedia</a></li>\n\t     \t      <li id=\"n-portal\"><a href=\"../../../../articles/c/o/m/Wikipedia%7ECommunity_Portal_6a3c.html\">Community portal</a></li>\n\t     \t      <li id=\"n-recentchanges\"><a href=\"../../../../articles/r/e/c/Special%7ERecentChanges_e0d0.html\">Recent changes</a></li>\n\t     \t      <li id=\"n-contact\"><a href=\"../../../../articles/c/o/n/Wikipedia%7EContact_us_afd6.html\">Contact Wikipedia</a></li>\n\t     \t      <li id=\"n-sitesupport\"><a href=\"http://wikimediafoundation.org/wiki/Donate\">Donate to Wikipedia</a></li>\n\t     \t      <li id=\"n-help\"><a href=\"../../../../articles/c/o/n/Help%7EContents_22de.html\">Help</a></li>\n\t     \t    </ul>\n\t  </div>\n\t</div>\n\t\t<div id=\"p-search\" class=\"portlet\">\n\t  <h5><label for=\"searchInput\">Search</label></h5>\n\t  <div id=\"searchBody\" class=\"pBody\">\n\t    <form action=\"javascript:goToStatic(3)\" id=\"searchform\"><div>\n\t      <input id=\"searchInput\" name=\"search\" type=\"text\"\n\t        accesskey=\"f\" value=\"\" />\n\t      <input type='submit' name=\"go\" class=\"searchButton\" id=\"searchGoButton\"\n\t        value=\"Go\" />\n\t    </div></form>\n\t  </div>\n\t</div>\n\t<div id=\"p-lang\" class=\"portlet\">\n\t  <h5>Languages</h5>\n\t  <div class=\"pBody\">\n\t    <ul>\n\t      \t      <li>\n\t      <a href=\"../../../../../de/articles/a/b/b/Abbott_und_Costello_treffen_Frankenstein_3ec4.html\">Deutsch</a>\n\t      </li>\n\t      \t      <li>\n\t      <a href=\"../../../../../et/articles/a/b/b/Abbott_and_Costello_Meet_Frankenstein_59d9.html\">Eesti</a>\n\t      </li>\n\t      \t      <li>\n\t      <a href=\"../../../../../it/articles/i/l/_/Il_cervello_di_Frankenstein_d283.html\">Italiano</a>\n\t      </li>\n\t      \t      <li>\n\t      <a href=\"../../../../../no/articles/a/b/b/Abbott_og_Costello_i_redselskabinettet_95ad.html\">‪Norsk (bokmål)‬</a>\n\t      </li>\n\t      \t    </ul>\n\t  </div>\n\t</div>\n\t      </div><!-- end of the left (by default at least) column -->\n      <div class=\"visualClear\"></div>\n      <div id=\"footer\">\n    <div id=\"f-poweredbyico\"><a href=\"http://www.mediawiki.org/\"><img src=\"../../../../skins/common/images/poweredby_mediawiki_88x31.png\" alt=\"Powered by MediaWiki\" /></a></div>\t<div id=\"f-copyrightico\"><a href=\"http://wikimediafoundation.org/\"><img src=\"../../../../misc/wikimedia-button.png\" border=\"0\" alt=\"Wikimedia Foundation\"/></a></div>\t<ul id=\"f-list\">\n\t  \t  \t  <li id=\"f-credits\">This page was last modified 23:38, 23 May 2008 by Wikipedia user <a href=\"../../../../articles/b/a/r/User%7EBarticus88_0fa5.html\" title=\"User:Barticus88\">Barticus88</a>. Based on work by Wikipedia user(s) <a href=\"../../../../articles/k/b/d/User%7EKbdankbot_f267.html\" title=\"User:Kbdankbot\">Kbdankbot</a>, Otrauthor, <a href=\"../../../../articles/d/o/n/User%7EDonaldd23_880f.html\" title=\"User:Donaldd23\">Donaldd23</a>, <a href=\"../../../../articles/l/u/g/User%7ELugnuts_a0c2.html\" title=\"User:Lugnuts\">Lugnuts</a>, <a href=\"../../../../articles/b/a/d/User%7EBadgernet_5043.html\" title=\"User:Badgernet\">Badgernet</a>, <a href=\"../../../../articles/d/y/s/User%7EDysepsion_8adb.html\" title=\"User:Dysepsion\">Dysepsion</a>, <a href=\"../../../../articles/d/u/m/User%7EDumZiBoT_2099.html\" title=\"User:DumZiBoT\">DumZiBoT</a>, <a href=\"../../../../articles/t/i/n/User%7ETinyMark_4a01.html\" title=\"User:TinyMark\">TinyMark</a>, <a href=\"../../../../articles/s/t/r/User%7EStr1977_cbd8.html\" title=\"User:Str1977\">Str1977</a>, <a href=\"../../../../articles/d/o/c/User%7EDoczilla_1c36.html\" title=\"User:Doczilla\">Doczilla</a>, <a href=\"../../../../articles/t/f/c/User%7ETFCforever_8e6c.html\" title=\"User:TFCforever\">TFCforever</a>, <a href=\"../../../../articles/v/o/l/User%7EVolkovBot_5c6d.html\" title=\"User:VolkovBot\">VolkovBot</a>, JamesGothMog13, <a href=\"../../../../articles/s/l/i/User%7ESlingbat_bd02.html\" title=\"User:Slingbat\">Slingbat</a>, <a href=\"../../../../articles/s/i/l/User%7ESilkTork_60ce.html\" title=\"User:SilkTork\">SilkTork</a>, <a href=\"../../../../articles/p/o/p/User%7EPopplewick_9d47.html\" title=\"User:Popplewick\">Popplewick</a>, <a href=\"../../../../articles/t/o/m/User%7ETom_Tresser_5804.html\" title=\"User:Tom Tresser\">Tom Tresser</a>, <a href=\"../../../../articles/a/n/i/User%7EAnimalz_Records_4f65.html\" title=\"User:Animalz Records\">Animalz Records</a>, Grantleigh, <a href=\"../../../../articles/t/j/m/User%7ETjmayerinsf_3183.html\" title=\"User:Tjmayerinsf\">Tjmayerinsf</a>, Marbpl, <a href=\"../../../../articles/j/o/n/User%7EJon138_bba3.html\" title=\"User:Jon138\">Jon138</a>, <a href=\"../../../../articles/m/l/o/User%7EMlouns_fbae.html\" title=\"User:Mlouns\">Mlouns</a>, <a href=\"../../../../articles/b/a/l/User%7EBalance2214_25ad.html\" title=\"User:Balance2214\">Balance2214</a>, John O'C, Tronta, <a href=\"../../../../articles/d/m/a/User%7EDmacw6_8359.html\" title=\"User:Dmacw6\">Dmacw6</a>, <a href=\"../../../../articles/n/a/t/User%7ENatureBoyMD_96c3.html\" title=\"User:NatureBoyMD\">NatureBoyMD</a>, <a href=\"../../../../articles/h/e/n/User%7EHenryCow_e1da.html\" title=\"User:HenryCow\">HenryCow</a>, <a href=\"../../../../articles/k/b/d/User%7EKbdank71_f952.html\" title=\"User:Kbdank71\">Kbdank71</a>, Jzummak, <a href=\"../../../../articles/z/v/a/User%7EZvar_a270.html\" title=\"User:Zvar\">Zvar</a>, <a href=\"../../../../articles/i/r/i/User%7EIrishguy_9732.html\" title=\"User:Irishguy\">Irishguy</a>, <a href=\"../../../../articles/s/m/a/User%7ESmackBot_cc7a.html\" title=\"User:SmackBot\">SmackBot</a>, <a href=\"../../../../articles/t/h/e/User%7ETheRingess_7faf.html\" title=\"User:TheRingess\">TheRingess</a>, <a href=\"../../../../articles/d/a/v/User%7EDavid_Gerard_df91.html\" title=\"User:David Gerard\">David Gerard</a>, <a href=\"../../../../articles/s/c/o/User%7EScottandrewhutchins_fac3.html\" title=\"User:Scottandrewhutchins\">Scottandrewhutchins</a>, <a href=\"../../../../articles/c/y/d/User%7ECydebot_38a6.html\" title=\"User:Cydebot\">Cydebot</a>, MOVIEMAN1963, Kepittman, <a href=\"../../../../articles/a/n/d/User%7EAndrzejbanas_e861.html\" title=\"User:Andrzejbanas\">Andrzejbanas</a>, <a href=\"../../../../articles/s/k/i/User%7ESkierRMH_4ae2.html\" title=\"User:SkierRMH\">SkierRMH</a>, <a href=\"../../../../articles/a/m/x/User%7EAmxitsa_0a7b.html\" title=\"User:Amxitsa\">Amxitsa</a>, <a href=\"../../../../articles/z/o/n/User%7EZondor_d557.html\" title=\"User:Zondor\">Zondor</a>, <a href=\"../../../../articles/j/o/g/User%7EJogersbot_c8cf.html\" title=\"User:Jogersbot\">Jogersbot</a>, <a href=\"../../../../articles/p/a/u/User%7EPaul_A_a8ca.html\" title=\"User:Paul A\">Paul A</a>, <a href=\"../../../../articles/m/a/l/User%7EMallanox_1ced.html\" title=\"User:Mallanox\">Mallanox</a>, <a href=\"../../../../articles/a/n/d/User%7EAndman8_44a5.html\" title=\"User:Andman8\">Andman8</a>, <a href=\"../../../../articles/r/e/e/User%7EReedy_bc31.html\" title=\"User:Reedy\">Reedy</a>, <a href=\"../../../../articles/w/a/v/User%7EWavy_G_9d03.html\" title=\"User:Wavy G\">Wavy G</a>, <a href=\"../../../../articles/t/h/e/User%7EThe_Iconoclast_bf11.html\" title=\"User:The Iconoclast\">The Iconoclast</a>, <a href=\"../../../../articles/p/r/o/User%7EProteus71_15e9.html\" title=\"User:Proteus71\">Proteus71</a>, <a href=\"../../../../articles/b/e/t/User%7EBetacommandBot_3654.html\" title=\"User:BetacommandBot\">BetacommandBot</a>, Andreal, Andrew777, <a href=\"../../../../articles/h/e/a/User%7EHEAD_ON_APPLY_DIRECTLY_TO_THE_FOREHEAD_1e75.html\" title=\"User:HEAD ON APPLY DIRECTLY TO THE FOREHEAD\">HEAD ON APPLY DIRECTLY TO THE FOREHEAD</a>, <a href=\"../../../../articles/n/e/h/User%7ENehrams2020_121d.html\" title=\"User:Nehrams2020\">Nehrams2020</a>, <a href=\"../../../../articles/2/3/s/User%7E23skidoo.html\" title=\"User:23skidoo\">23skidoo</a>, <a href=\"../../../../articles/i/b/a/User%7EIbaranoff24_bfad.html\" title=\"User:Ibaranoff24\">Ibaranoff24</a>, <a href=\"../../../../articles/m/o/t/User%7EMotor_c62e.html\" title=\"User:Motor\">Motor</a>, <a href=\"../../../../articles/d/a/v/User%7EDavid_L_Rattigan_f48b.html\" title=\"User:David L Rattigan\">David L Rattigan</a>, <a href=\"../../../../articles/j/a/m/User%7EJamesMLane_34be.html\" title=\"User:JamesMLane\">JamesMLane</a>, Sledgeh101, <a href=\"../../../../articles/a/r/t/User%7EArtemisboy_24da.html\" title=\"User:Artemisboy\">Artemisboy</a>, Estrose, <a href=\"../../../../articles/n/e/t/User%7ENetBot_052d.html\" title=\"User:NetBot\">NetBot</a>, <a href=\"../../../../articles/b/o/b/User%7EBobblewik_fbc0.html\" title=\"User:Bobblewik\">Bobblewik</a>, <a href=\"../../../../articles/n/o/i/User%7ENoirish_ce0d.html\" title=\"User:Noirish\">Noirish</a>, <a href=\"../../../../articles/h/e/l/User%7EHelga76_03d6.html\" title=\"User:Helga76\">Helga76</a>, <a href=\"../../../../articles/i/c/e/User%7EIceDrake523_e684.html\" title=\"User:IceDrake523\">IceDrake523</a>, <a href=\"../../../../articles/i/a/n/User%7EIanblair23_6de0.html\" title=\"User:Ianblair23\">Ianblair23</a>, <a href=\"../../../../articles/w/h/o/User%7EWho_d957.html\" title=\"User:Who\">Who</a>, <a href=\"../../../../articles/j/e/f/User%7EJeff_Watts_14b9.html\" title=\"User:Jeff Watts\">Jeff Watts</a>, <a href=\"../../../../articles/s/i/m/User%7ESimonP_1010.html\" title=\"User:SimonP\">SimonP</a>, <a href=\"../../../../articles/p/e/a/User%7EPearle_6f07.html\" title=\"User:Pearle\">Pearle</a>, <a href=\"../../../../articles/c/r/y/User%7ECryptoDerk_6aa9.html\" title=\"User:CryptoDerk\">CryptoDerk</a>, <a href=\"../../../../articles/j/e/f/User%7EJeffq_074c.html\" title=\"User:Jeffq\">Jeffq</a>, <a href=\"../../../../articles/o/w/e/User%7EOwenBlacker_920f.html\" title=\"User:OwenBlacker\">OwenBlacker</a>, <a href=\"../../../../articles/g/a/m/User%7EGamaliel_c9b8.html\" title=\"User:Gamaliel\">Gamaliel</a>, <a href=\"../../../../articles/t/i/m/User%7ETimc_6767.html\" title=\"User:Timc\">Timc</a>, <a href=\"../../../../articles/z/a/n/User%7EZanimum_8561.html\" title=\"User:Zanimum\">Zanimum</a>, <a href=\"../../../../articles/r/f/c/User%7ERfc1394_3d02.html\" title=\"User:Rfc1394\">Rfc1394</a>, <a href=\"../../../../articles/k/o/y/User%7EKoyaanis_Qatsi_7ab5.html\" title=\"User:Koyaanis Qatsi\">Koyaanis Qatsi</a> and <a href=\"../../../../articles/z/o/e/User%7EZoe_6ab7.html\" title=\"User:Zoe\">Zoe</a> and Anonymous user(s) of Wikipedia.</li>\t  <li id=\"f-copyright\">All text is available under the terms of the <a class='internal' href=\"http://en.wikipedia.org/wiki/Wikipedia:Text_of_the_GNU_Free_Documentation_License\" title=\"Wikipedia:Text of the GNU Free Documentation License\">GNU Free Documentation License</a>. (See <b><a class='internal' href=\"http://en.wikipedia.org/wiki/Wikipedia:Copyrights\" title=\"Wikipedia:Copyrights\">Copyrights</a></b> for details.) <br /> Wikipedia&reg; is a registered trademark of the <a href=\"http://www.wikimediafoundation.org\">Wikimedia Foundation, Inc</a>., a U.S. registered <a class='internal' href=\"http://en.wikipedia.org/wiki/501%28c%29#501.28c.29.283.29\" title=\"501(c)(3)\">501(c)(3)</a> <a href=\"http://wikimediafoundation.org/wiki/Deductibility_of_donations\">tax-deductible</a> <a class='internal' href=\"http://en.wikipedia.org/wiki/Non-profit_organization\" title=\"Non-profit organization\">nonprofit</a> <a href=\"http://en.wikipedia.org/wiki/Charitable_organization\" title=\"Charitable organization\">charity</a>.<br /></li>\t  <li id=\"f-about\"><a href=\"../../../../articles/a/b/o/Wikipedia%7EAbout_8d82.html\" title=\"Wikipedia:About\">About Wikipedia</a></li>\t  <li id=\"f-disclaimer\"><a href=\"../../../../articles/g/e/n/Wikipedia%7EGeneral_disclaimer_3e44.html\" title=\"Wikipedia:General disclaimer\">Disclaimers</a></li>\t  \t</ul>\n      </div>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/fix17429.d",
    "content": "class Klazz\n{\n    __gshared size_t count;\n    ~this()\n    {\n        ++count;\n    }\n}\n\nvoid main()\n{\n    auto s = new Klazz;\n    {\n        scope s2 = s; // calls delete even though it does not own s\n    }\n    assert(Klazz.count == 0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/foreach.d",
    "content": "\nimport core.stdc.stdio;\n\n/**************************************************/\n\nvoid test1()\n{\n    int i;\n\n    foreach (char c; \"abcd\")\n    {\n        switch (i++)\n        {   case 0:     assert(c == 'a');   break;\n            case 1:     assert(c == 'b');   break;\n            case 2:     assert(c == 'c');   break;\n            case 3:     assert(c == 'd');   break;\n            default:    assert(0);\n        }\n    }\n\n    i = 0;\n    foreach (wchar c; \"asdf\")\n    {\n        switch (i++)\n        {   case 0:     assert(c == 'a');   break;\n            case 1:     assert(c == 's');   break;\n            case 2:     assert(c == 'd');   break;\n            case 3:     assert(c == 'f');   break;\n            default:    assert(0);\n        }\n    }\n\n    i = 0;\n    foreach (dchar c; \"bncd\")\n    {\n        switch (i++)\n        {   case 0:     assert(c == 'b');   break;\n            case 1:     assert(c == 'n');   break;\n            case 2:     assert(c == 'c');   break;\n            case 3:     assert(c == 'd');   break;\n            default:    assert(0);\n        }\n    }\n}\n\n/**************************************************/\n\nvoid test2()\n{\n    int i;\n\n    uint[5] a;\n    a[0] = 16;\n    a[1] = 1;\n    a[2] = 5;\n    a[3] = 8;\n    a[4] = 3;\n\n    foreach (uint u; a)\n    {\n        switch (i++)\n        {   case 0:     assert(u == 16);    break;\n            case 1:     assert(u == 1);     break;\n            case 2:     assert(u == 5);     break;\n            case 3:     assert(u == 8);     break;\n            case 4:     assert(u == 3);     break;\n            default:    assert(0);\n        }\n    }\n\n    uint[] b = a;\n\n    i = 0;\n    foreach (uint u; b)\n    {\n        switch (i++)\n        {   case 0:     assert(u == 16);    break;\n            case 1:     assert(u == 1);     break;\n            case 2:     assert(u == 5);     break;\n            case 3:     assert(u == 8);     break;\n            case 4:     assert(u == 3);     break;\n            default:    assert(0);\n        }\n    }\n\n    test2_x(a);\n}\n\nvoid test2_x(uint[5] a)\n{\n    int i;\n\n    foreach (uint u; a)\n    {\n        switch (i++)\n        {   case 0:     assert(u == 16);    break;\n            case 1:     assert(u == 1);     break;\n            case 2:     assert(u == 5);     break;\n            case 3:     assert(u == 8);     break;\n            case 4:     assert(u == 3);     break;\n            default:    assert(0);\n        }\n    }\n}\n\n/**************************************************/\n\nvoid test3()\n{\n    int i;\n\n    uint[5] a;\n    a[0] = 16;\n\n    foreach (ref uint u; a)\n    {\n        i += u;\n        u++;\n    }\n    assert(i == 16);\n    assert(a[0] == 17);\n    assert(a[4] == 1);\n\n    foreach (uint u; a)\n    {\n        printf(\"u = %d\\n\", u);\n        //u++;\n    }\n    assert(a[0] == 17);\n    assert(a[4] == 1);\n}\n\n/**************************************************/\n\nenum E4 { m }\n\nstruct X4 {\n    char [] b;\n    E4 a;\n}\n\nvoid test4()\n{\n    X4 [] x;\n    foreach (X4 w; x) {}\n}\n\n\n/**************************************************/\n\nclass Thing5\n{}\n\nclass Things5\n{\npublic:\n  int opApply(int delegate(ref Thing5 thing) dg)\n  {\n    Thing5 thing = new Thing5();\n\n    return dg(thing);\n  }\n}\n\nvoid foo5(Things5 things)\n{\n    foreach(Thing5 t; things)\n    {\n    }\n}\n\nvoid test5()\n{\n}\n\n\n/**************************************************/\n\nvoid test6()\n{\n    static long[3] a = [21,22,23];\n    long[3] b;\n    int sum;\n\n    foreach (int i, ref long v; a)\n    {\n        printf(\"a[%d] = %lld\\n\", i, v);\n        b[i] = v;\n    }\n\n    for (uint i = 0; i < 3; i++)\n    {\n        assert(b[i] == 21 + i);\n    }\n\n    foreach (ref long v; a)\n    {\n        printf(\"a[] = %lld\\n\", v);\n        sum += v;\n    }\n    assert(sum == 21 + 22 + 23);\n}\n\n/**************************************************/\n\nvoid test7()\n{\n    uint[string] a;\n\n    a[\"foo\"] = 3;\n    a[\"bar\"] = 4;\n    foreach (string s, uint v; a)\n    {\n        printf(\"a[%.*s] = %d\\n\", s.length, s.ptr, v);\n        if (s == \"bar\")\n            assert(v == 4);\n        else if (s == \"foo\")\n            assert(v == 3);\n        else\n            assert(0);\n    }\n}\n\n\n/**************************************************/\n\nclass Foo8\n{\n    int x, y, z;\n\n    int opApply(int delegate(ref int a, ref int b, ref int c) dg)\n    {\n        int result = dg(x, y, z);\n        return 0;\n    }\n}\n\nvoid test8()\n{\n    Foo8 f = new Foo8();\n    f.x = 63;\n    f.y = 47;\n    f.z = 83;\n    foreach (int a, ref int b, int c; f)\n    {\n        printf(\"a = %d, b = %d, c = %d\\n\", a, b, c);\n        assert(a == 63);\n        assert(b == 47);\n        assert(c == 83);\n        a++;\n        b++;\n        c++;\n    }\n    foreach (int a, ref int b, int c; f)\n    {\n        printf(\"a = %d, b = %d, c = %d\\n\", a, b, c);\n        assert(a == 63);\n        assert(b == 48);\n        assert(c == 83);\n        a++;\n        b++;\n        c++;\n    }\n}\n\n/**************************************************/\n\nstruct S\n{\n    int opApply(int delegate(ref int a)) { return 0; }\n    int opApplyReverse(int delegate(ref int a)) { return 0; }\n    int dg(int delegate(ref int a)) { return 0; }\n}\n\nvoid test9()\n{\n    S s;\n    foreach(a; s) {}\n    foreach_reverse(a; s) {}\n    foreach(a; &s.dg) {}\n}\n\n/**************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/foreach2.d",
    "content": "\nimport core.stdc.stdio;\n\n/**************************************************/\n\nvoid test1()\n{\n    uint[char[]] a;\n    int i;\n\n    a[\"hello\"] = 73;\n    a[\"world\"] = 82;\n\n    foreach (uint u; a)\n    {\n        i++;\n        u++;\n    }\n    assert(i == 2);\n    assert(a[\"hello\"] == 73);\n    assert(a[\"world\"] == 82);\n}\n\n/**************************************************/\n\nvoid test2()\n{\n    uint[char[]] a;\n    int i;\n\n    a[\"hello\"] = 73;\n    a[\"world\"] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        u++;\n    }\n    assert(i == 2);\n    assert(a[\"hello\"] == 74);\n    assert(a[\"world\"] == 83);\n}\n\n/**************************************************/\n\nvoid test3()\n{\n    uint[char[]] a;\n    int i;\n\n    a[\"hello\"] = 73;\n    a[\"world\"] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            break;\n        u++;\n    }\n    assert(i == 1);\n    assert(a[\"hello\"] == 73);\n    assert(a[\"world\"] == 82);\n}\n\n/**************************************************/\n\nvoid test4()\n{\n    uint[char[]] a;\n    int i;\n\n    a[\"hello\"] = 73;\n    a[\"world\"] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i == 1)\n            continue;\n        u++;\n    }\n    assert(i == 2);\n    assert((a[\"hello\"] == 73 && a[\"world\"] == 83) ||\n           (a[\"hello\"] == 74 && a[\"world\"] == 82));\n}\n\n/**************************************************/\n\nvoid test5()\n{\n    uint[char[]] a;\n    int i;\n\n    a[\"hello\"] = 73;\n    a[\"world\"] = 82;\n\nLoop:\n    while (1)\n    {\n        foreach (ref uint u; a)\n        {\n            i++;\n            if (i)\n                break Loop;\n            u++;\n        }\n    }\n    assert(i == 1);\n    assert(a[\"hello\"] == 73);\n    assert(a[\"world\"] == 82);\n}\n\n/**************************************************/\n\nvoid test6()\n{\n    uint[char[]] a;\n    int i;\n\n    a[\"hello\"] = 73;\n    a[\"world\"] = 82;\n\nLoop:\n    while (1)\n    {\n        foreach (ref uint u; a)\n        {\n            i++;\n            if (i == 1)\n                continue Loop;\n            u++;\n        }\n        break;\n    }\n    assert(i == 3);\n    assert(a[\"hello\"] == 74);\n    assert(a[\"world\"] == 83);\n}\n\n/**************************************************/\n\nvoid test7()\n{\n    uint[char[]] a;\n    int i;\n\n    a[\"hello\"] = 73;\n    a[\"world\"] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            goto Label;\n        u++;\n    }\n    assert(0);\nLabel:\n    assert(i == 1);\n    assert(a[\"hello\"] == 73);\n    assert(a[\"world\"] == 82);\n}\n\n/**************************************************/\n\nvoid test8_x(uint[char[]] a)\n{\n    int i;\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            return;\n        u++;\n    }\n}\n\nvoid test8()\n{\n    uint[char[]] a;\n    int i;\n\n    a[\"hello\"] = 73;\n    a[\"world\"] = 82;\n\n    test8_x(a);\n    assert(i == 0);\n    assert(a[\"hello\"] == 73);\n    assert(a[\"world\"] == 82);\n}\n\n/**************************************************/\n\nint test9_x(uint[char[]] a)\n{\n    int i;\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            return 67;\n        u++;\n    }\n    return 23;\n}\n\nvoid test9()\n{\n    uint[char[]] a;\n    int i;\n\n    a[\"hello\"] = 73;\n    a[\"world\"] = 82;\n\n    i = test9_x(a);\n    assert(i == 67);\n    assert(a[\"hello\"] == 73);\n    assert(a[\"world\"] == 82);\n}\n\n/**************************************************/\n\nint test10_x(uint[char[]] a)\n{\n    int i;\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            return i;\n        u++;\n    }\n    return 23;\n}\n\nvoid test10()\n{\n    uint[char[]] a;\n    int i;\n\n    a[\"hello\"] = 73;\n    a[\"world\"] = 82;\n\n    i = test10_x(a);\n    assert(i == 1);\n    assert(a[\"hello\"] == 73);\n    assert(a[\"world\"] == 82);\n}\n\n/**************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/foreach3.d",
    "content": "\nimport core.stdc.stdio;\n\nstruct Foo\n{\n    uint[2] array;\n\n    int opApply(int delegate(ref uint) dg)\n    {\n        int result;\n        for (int i = 0; i < array.length; i++)\n        {\n            result = dg(array[i]);\n            if (result)\n                break;\n        }\n        return result;\n    }\n}\n\n\n/**************************************************/\n\nvoid test1()\n{\n    Foo a;\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (uint u; a)\n    {\n        i++;\n        u++;\n    }\n    assert(i == 2);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nvoid test2()\n{\n    Foo a;\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        u++;\n    }\n    assert(i == 2);\n    assert(a.array[0] == 74);\n    assert(a.array[1] == 83);\n}\n\n/**************************************************/\n\nvoid test3()\n{\n    Foo a;\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            break;\n        u++;\n    }\n    assert(i == 1);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nvoid test4()\n{\n    Foo a;\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i == 1)\n            continue;\n        u++;\n    }\n    assert(i == 2);\n    assert(a.array[0] == 73 && a.array[1] == 83);\n}\n\n/**************************************************/\n\nvoid test5()\n{\n    Foo a;\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\nLoop:\n    while (1)\n    {\n        foreach (ref uint u; a)\n        {\n            i++;\n            if (i)\n                break Loop;\n            u++;\n        }\n    }\n    assert(i == 1);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nvoid test6()\n{\n    Foo a;\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\nLoop:\n    while (1)\n    {\n        foreach (ref uint u; a)\n        {\n            i++;\n            if (i == 1)\n                continue Loop;\n            u++;\n        }\n        break;\n    }\n    assert(i == 3);\n    assert(a.array[0] == 74);\n    assert(a.array[1] == 83);\n}\n\n/**************************************************/\n\nvoid test7()\n{\n    Foo a;\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            goto Label;\n        u++;\n    }\n    assert(0);\nLabel:\n    assert(i == 1);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nvoid test8_x(Foo a)\n{\n    int i;\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            return;\n        u++;\n    }\n}\n\nvoid test8()\n{\n    Foo a;\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    test8_x(a);\n    assert(i == 0);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nint test9_x(Foo a)\n{\n    int i;\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            return 67;\n        u++;\n    }\n    return 23;\n}\n\nvoid test9()\n{\n    Foo a;\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    i = test9_x(a);\n    assert(i == 67);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nint test10_x(Foo a)\n{\n    int i;\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            return i;\n        u++;\n    }\n    return 23;\n}\n\nvoid test10()\n{\n    Foo a;\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    i = test10_x(a);\n    assert(i == 1);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/foreach4.d",
    "content": "\nimport core.stdc.stdio;\nimport std.stdio;\n\nalias bool bit;\n\n/************************************************/\n\nclass Foo\n{\n    uint[2] array;\n\n    int opApply(int delegate(ref uint) dg)\n    {\n        int result;\n        for (int i = 0; i < array.length; i++)\n        {\n            result = dg(array[i]);\n            if (result)\n                break;\n        }\n        return result;\n    }\n}\n\n\n/**************************************************/\n\nvoid test1()\n{\n    Foo a = new Foo();\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (uint u; a)\n    {\n        i++;\n        u++;\n    }\n    assert(i == 2);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nvoid test2()\n{\n    Foo a = new Foo();\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        u++;\n    }\n    assert(i == 2);\n    assert(a.array[0] == 74);\n    assert(a.array[1] == 83);\n}\n\n/**************************************************/\n\nvoid test3()\n{\n    Foo a = new Foo();\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            break;\n        u++;\n    }\n    assert(i == 1);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nvoid test4()\n{\n    Foo a = new Foo();\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i == 1)\n            continue;\n        u++;\n    }\n    assert(i == 2);\n    assert(a.array[0] == 73 && a.array[1] == 83);\n}\n\n/**************************************************/\n\nvoid test5()\n{\n    Foo a = new Foo();\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\nLoop:\n    while (1)\n    {\n        foreach (ref uint u; a)\n        {\n            i++;\n            if (i)\n                break Loop;\n            u++;\n        }\n    }\n    assert(i == 1);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nvoid test6()\n{\n    Foo a = new Foo();\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\nLoop:\n    while (1)\n    {\n        foreach (ref uint u; a)\n        {\n            i++;\n            if (i == 1)\n                continue Loop;\n            u++;\n        }\n        break;\n    }\n    assert(i == 3);\n    assert(a.array[0] == 74);\n    assert(a.array[1] == 83);\n}\n\n/**************************************************/\n\nvoid test7()\n{\n    Foo a = new Foo();\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            goto Label;\n        u++;\n    }\n    assert(0);\nLabel:\n    assert(i == 1);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nvoid test8_x(Foo a)\n{\n    int i;\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            return;\n        u++;\n    }\n}\n\nvoid test8()\n{\n    Foo a = new Foo();\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    test8_x(a);\n    assert(i == 0);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nint test9_x(Foo a)\n{\n    int i;\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            return 67;\n        u++;\n    }\n    return 23;\n}\n\nvoid test9()\n{\n    Foo a = new Foo();\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    i = test9_x(a);\n    assert(i == 67);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nint test10_x(Foo a)\n{\n    int i;\n    foreach (ref uint u; a)\n    {\n        i++;\n        if (i)\n            return i;\n        u++;\n    }\n    return 23;\n}\n\nvoid test10()\n{\n    Foo a = new Foo();\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    i = test10_x(a);\n    assert(i == 1);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n/+\nthe expected output:\n\n1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0\n1\n1 1 0 1 0 1 1 0 1 0 1 1 0 1 0 1 1 0 1 0 1 1 1 1 0\n1 1 0 1 0 1 1 0 1 0 1 1 0 1 0 1 1 0 1 0 1 1 1 1 0\n1 1 0 1 0 1 1 0 1 0 1 1 0 1 0 1 1 0 1 0 1 1 1 1 0\n+/\n\nvoid test11()\n{\n    bit[25] data;\n    int j;\n\n    for (int i = 0; i < 25; i += 5) {\n        data[i+0] = data[i+1] = true;\n    }\n\n    for (int i = 0; i < 25; i++) {\n        printf(\"%d \", data[i]);\n        if ((i % 5) < 2)\n            assert(data[i] == true);\n        else\n            assert(data[i] == false);\n    }\n\n    printf(\"\\n%d\\n\", data[22] = true);\n    j = data[22] = true;\n    assert(j == true);\n\n    for (int i = 0; i < 25; i += 5) {\n        data[i+1] = data[i+3] = true;\n        j = i % 5;\n        if (j == 0 || j == 1 || j == 3)\n            assert(data[i] == true);\n        else\n            assert(data[i] == false);\n    }\n\n    for (int i = 0; i < 25; i++) {\n        printf(\"%d \", data[i]);\n    }\n\n    printf(\"\\n\");\n\n    int k;\n    foreach (bit b; data) {\n        printf(\"%d \", b);\n        j = k % 5;\n        if (j == 0 || j == 1 || j == 3 || k == 22)\n            assert(data[k] == true);\n        else\n            assert(data[k] == false);\n        k++;\n    }\n    printf(\"\\n\");\n\n    foreach (int l, bit b; data) {\n        printf(\"%d \", b);\n        j = l % 5;\n        if (j == 0 || j == 1 || j == 3 || l == 22)\n            assert(data[l] == true);\n        else\n            assert(data[l] == false);\n    }\n    printf(\"\\n\");\n}\n\n\n/**************************************************/\n\nvoid test12()\n{\n    int j;\n\n    j = 0;\n    foreach (dchar d; \"hello\")\n    {\n        printf(\"d = x%x\\n\", d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        j++;\n    }\n    assert(j == 5);\n\n    j = 0;\n    foreach (size_t i, dchar d; \"hello\")\n    {\n        printf(\"i = %d, d = x%x\\n\", i, d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        assert(i == j);\n        j++;\n    }\n    assert(j == 5);\n}\n\n/**************************************************/\n\nvoid test13()\n{\n    int j;\n\n    j = 0;\n    foreach (wchar d; \"hello\")\n    {\n        printf(\"d = x%x\\n\", d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        j++;\n    }\n    assert(j == 5);\n\n    j = 0;\n    foreach (size_t i, wchar d; \"hello\")\n    {\n        printf(\"i = %d, d = x%x\\n\", i, d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        assert(i == j);\n        j++;\n    }\n    assert(j == 5);\n}\n\n/**************************************************/\n\nvoid test14()\n{\n    int j;\n\n    j = 0;\n    foreach (char d; cast(wstring)\"hello\")\n    {\n        printf(\"d = x%x\\n\", d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        j++;\n    }\n    assert(j == 5);\n\n    j = 0;\n    foreach (size_t i, char d; cast(wstring)\"hello\")\n    {\n        printf(\"i = %d, d = x%x\\n\", i, d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        assert(i == j);\n        j++;\n    }\n    assert(j == 5);\n}\n\n/**************************************************/\n\nvoid test15()\n{\n    int j;\n\n    j = 0;\n    foreach (dchar d; cast(wstring)\"hello\")\n    {\n        printf(\"d = x%x\\n\", d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        j++;\n    }\n    assert(j == 5);\n\n    j = 0;\n    foreach (size_t i, dchar d; cast(wstring)\"hello\")\n    {\n        printf(\"i = %d, d = x%x\\n\", i, d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        assert(i == j);\n        j++;\n    }\n    assert(j == 5);\n}\n\n/**************************************************/\n\nvoid test16()\n{\n    int j;\n\n    j = 0;\n    foreach (char d; cast(dstring)\"hello\")\n    {\n        printf(\"d = x%x\\n\", d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        j++;\n    }\n    assert(j == 5);\n\n    j = 0;\n    foreach (size_t i, char d; cast(dstring)\"hello\")\n    {\n        printf(\"i = %d, d = x%x\\n\", i, d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        assert(i == j);\n        j++;\n    }\n    assert(j == 5);\n}\n\n/**************************************************/\n\nvoid test17()\n{\n    int j;\n\n    j = 0;\n    foreach (wchar d; cast(dstring)\"hello\")\n    {\n        printf(\"d = x%x\\n\", d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        j++;\n    }\n    assert(j == 5);\n\n    j = 0;\n    foreach (size_t i, wchar d; cast(dstring)\"hello\")\n    {\n        printf(\"i = %d, d = x%x\\n\", i, d);\n        if (j == 0) assert(d == 'h');\n        if (j == 1) assert(d == 'e');\n        if (j == 2) assert(d == 'l');\n        if (j == 3) assert(d == 'l');\n        if (j == 4) assert(d == 'o');\n        assert(i == j);\n        j++;\n    }\n    assert(j == 5);\n}\n\n/**************************************************/\n\nvoid test18()\n{\n    string a = \"\\xE2\\x89\\xA0\";      // \\u2260 encoded as 3 UTF-8 bytes\n\n    foreach (dchar c; a)\n    {\n        printf(\"a[] = %x\\n\", c);    // prints 'a[] = 2260'\n        assert(c == 0x2260);\n    }\n\n    dstring b = \"\\u2260\";\n\n    int i;\n    foreach (char c; b)\n    {\n        printf(\"%x, \", c);      // prints e2, 89, a0\n        if (i == 0) assert(c == 0xE2);\n        else if (i == 1) assert(c == 0x89);\n        else if (i == 2) assert(c == 0xA0);\n        else\n            assert(0);\n        i++;\n    }\n    printf(\"\\n\");\n}\n\n/**************************************************/\n\nvoid test19()\n{\n    string string = x\"F0 9D 83 93\";\n\n    int count=0;\n    dchar tmp;\n    foreach(dchar value ; string){\n        tmp=value;\n        count++;\n    }\n    assert(count==1);\n    assert(tmp==0x01D0D3);\n}\n\n/**************************************************/\n\nstruct S20\n{\n    int opApply(int delegate(ref int i) dg)\n    {\n       return 0;\n    }\n}\n\nS20 foo20;\n\nvoid test20()\n{\n    label:\n    foreach(int i; foo20)\n    {\n       continue label;\n    }\n}\n\n\n/**************************************************/\n\nvoid foo21(string[] args)\n{\n    printf(\"args.length = %d\\n\", args.length);\n    assert(args.length == 3);\n    foreach (i, arg; args)\n    {\n        assert(typeid(typeof(i)) == typeid(size_t));\n        assert(typeid(typeof(arg)) == typeid(string));\n        writefln(\"args[%d] = '%s'\", i, arg);\n    }\n    foreach (arg; args)\n    {\n        assert(typeid(typeof(arg)) == typeid(string));\n        writefln(\"args[] = '%s'\", arg);\n    }\n}\n\nvoid test21()\n{\n    string[] args;\n\n    args.length = 3;\n    args[0] = \"a\";\n    args[1] = \"bc\";\n    args[2] = \"d\";\n    foo21(args);\n}\n\n/**************************************************/\n\nvoid test22()\n{\n    int[string] map;\n\n    map[\"hello\"] = 3;\n    map[\"world\"] = 4;\n\n    foreach (key, value; map)\n    {\n        assert(typeid(typeof(key)) == typeid(string));\n        assert(typeid(typeof(value)) == typeid(int));\n        writefln(\"map[%s] = %s\", key, value);\n    }\n    foreach (key, int value; map)\n    {\n        assert(typeid(typeof(key)) == typeid(string));\n        assert(typeid(typeof(value)) == typeid(int));\n        writefln(\"map[%s] = %s\", key, value);\n    }\n    foreach (string key, value; map)\n    {\n        assert(typeid(typeof(key)) == typeid(string));\n        assert(typeid(typeof(value)) == typeid(int));\n        writefln(\"map[%s] = %s\", key, value);\n    }\n    foreach (value; map)\n    {\n        assert(typeid(typeof(value)) == typeid(int));\n        writefln(\"map[] = %s\", value);\n    }\n}\n\n/**************************************************/\n\nclass Foo23\n{\n    int[2] array;\n\n    int opApply(int delegate(ref int) dg)\n    {\n        int result;\n        for (int i = 0; i < array.length; i++)\n        {\n            result = dg(array[i]);\n            if (result)\n                break;\n        }\n        return result;\n    }\n\n    int opApply(int delegate(ref size_t, ref int) dg)\n    {\n        int result;\n        for (size_t i = 0; i < array.length; i++)\n        {\n            result = dg(i, array[i]);\n            if (result)\n                break;\n        }\n        return result;\n    }\n}\n\nvoid test23()\n{\n    Foo23 a = new Foo23();\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (u; a)\n    {\n        assert(typeid(typeof(u)) == typeid(int));\n        i++;\n        u++;\n        //writefln(\"u = %d\", u);\n        assert((i == 1) ? u == 74 : u == 83);\n    }\n    assert(i == 2);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n\n    foreach (j, u; a)\n    {\n        assert(typeid(typeof(j)) == typeid(size_t));\n        assert(typeid(typeof(u)) == typeid(int));\n        i++;\n        u++;\n        writefln(\"u = %d\", u);\n        assert((i == 3) ? u == 74 : u == 83);\n        assert(j == i - 3);\n    }\n    assert(i == 4);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n}\n\n/**************************************************/\n\nstruct Collection24\n{\n    int opApply(int delegate(ref int) dg){\n        return 0;\n    }\n}\n\nbool foo24()\n{\n    Collection24 a,b;\n\n    foreach(int x; a){\n        foreach(int y; b){\n            return false;\n        }\n    }\n\n    return true;\n}\n\nvoid test24()\n{\n    assert(foo24() == true);\n}\n\n/**************************************************/\n\nvoid test25()\n{\n    alias void function(string[string]) FN;\n    FN fn = function (string[string] aarray)\n    {\n        foreach (string s; aarray)\n        {\n            writeln(s);\n            assert(s == \"b\");\n        }\n    };\n    string[string] aarray;\n    aarray[\"a\"] = \"b\";\n    fn(aarray);\n}\n\n/**************************************************/\n\nstruct Foo26\n{\n    uint[2] array;\n\n    int forward(int delegate(ref uint) dg)\n    {\n        int result;\n        for (int i = 0; i < array.length; i++)\n        {\n            result = dg(array[i]);\n            if (result)\n                break;\n        }\n        return result;\n    }\n\n    int forward(int delegate(ref uint) dg, int x) { return 1; }\n\n    int reverse(int delegate(ref uint) dg, int x) { return 1; }\n\n    int reverse(int delegate(ref uint) dg)\n    {\n        int result;\n        foreach_reverse (v; array)\n        {\n            auto u = v;\n            result = dg(u);\n            if (result)\n                break;\n        }\n        return result;\n    }\n}\n\n\nvoid test26()\n{\n    Foo26 a;\n    int i;\n\n    a.array[0] = 73;\n    a.array[1] = 82;\n\n    foreach (u; &a.forward)\n    {\n        writeln(u);\n        i++;\n        u++;\n    }\n    assert(i == 2);\n    assert(a.array[0] == 73);\n    assert(a.array[1] == 82);\n\n    foreach (uint u; &a.reverse)\n    {\n        writeln(u);\n    }\n}\n\n/**************************************************/\n\nstruct S27\n{\n    int[] a;\n\n    bool empty() { return a.length == 0; }\n\n    void popFront() { a = a[1 .. $]; }\n    int front() { return a[0]; }\n\n    void popBack() { a = a[0 .. $ - 1]; }\n    ref int back() { return a[$ - 1]; }\n}\n\nvoid test27()\n{\n    S27 s;\n    s.a = [5,6,7];\n    string r;\n\n    foreach (e; s)\n    {\n        printf(\"%d\\n\", e);\n        r ~= cast(char)(e + '0');\n    }\n    assert(r == \"567\");\n\n    r = null;\n    foreach_reverse (ref e; s)\n    {\n        e++;\n        printf(\"%d\\n\", e);\n        r ~= cast(char)(e + '0');\n    }\n    assert(r == \"876\");\n\n    r = null;\n    foreach (e; s)\n    {\n        printf(\"%d\\n\", e);\n        r ~= cast(char)(e + '0');\n    }\n    assert(r == \"678\");\n}\n\n/**************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/foreach5.d",
    "content": "\nextern(C) int printf(const char* fmt, ...);\n\nalias AliasSeq(X...) = X;\n\n/***************************************/\n\nvoid test1()\n{\n    char[] a;\n\n    int foo()\n    {\n        printf(\"foo\\n\");\n        a ~= \"foo\";\n        return 10;\n    }\n\n    foreach (i; 0 .. foo())\n    {\n        printf(\"%d\\n\", i);\n        a ~= cast(char)('0' + i);\n    }\n    assert(a == \"foo0123456789\");\n\n    foreach_reverse (i; 0 .. foo())\n    {\n        printf(\"%d\\n\", i);\n        a ~= cast(char)('0' + i);\n    }\n    assert(a == \"foo0123456789foo9876543210\");\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2411\n\nstruct S2411\n{\n    int n;\n    string s;\n}\n\nvoid test2411()\n{\n    S2411 s;\n    assert(s.n == 0);\n    assert(s.s == \"\");\n    foreach (i, ref e; s.tupleof)\n    {\n        static if (i == 0)\n            e = 10;\n        static if (i == 1)\n            e = \"str\";\n    }\n    assert(s.n == 10);\n    assert(s.s == \"str\");\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2442\n\ntemplate canForeach(T, E)\n{\n    enum canForeach = __traits(compiles,\n    {\n        foreach(a; new T)\n        {\n            static assert(is(typeof(a) == E));\n        }\n    });\n}\n\nvoid test2442()\n{\n    struct S1\n    {\n        int opApply(int delegate(ref const(int) v) dg) const { return 0; }\n        int opApply(int delegate(ref int v) dg)              { return 0; }\n    }\n          S1 ms1;\n    const S1 cs1;\n    foreach (x; ms1) { static assert(is(typeof(x) ==       int)); }\n    foreach (x; cs1) { static assert(is(typeof(x) == const int)); }\n\n    struct S2\n    {\n        int opApply(int delegate(ref  int v) dg) { return 0; }\n        int opApply(int delegate(ref long v) dg) { return 0; }\n    }\n    S2 ms2;\n    static assert(!__traits(compiles, { foreach (    x; ms2) {} }));    // ambiguous\n    static assert( __traits(compiles, { foreach (int x; ms2) {} }));\n\n    struct S3\n    {\n        int opApply(int delegate(ref int v) dg) const        { return 0; }\n        int opApply(int delegate(ref int v) dg) shared const { return 0; }\n    }\n    immutable S3 ms3;\n    static assert(!__traits(compiles, { foreach (int x; ms3) {} }));    // ambiguous\n\n    // from https://github.com/dlang/dmd/pull/120\n    static class C\n    {\n        int opApply(int delegate(ref              int v) dg)              { return 0; }\n        int opApply(int delegate(ref        const int v) dg) const        { return 0; }\n        int opApply(int delegate(ref    immutable int v) dg) immutable    { return 0; }\n        int opApply(int delegate(ref       shared int v) dg) shared       { return 0; }\n        int opApply(int delegate(ref shared const int v) dg) shared const { return 0; }\n    }\n    static class D\n    {\n        int opApply(int delegate(ref int v) dg) const        { return 0; }\n    }\n    static class E\n    {\n        int opApply(int delegate(ref int v) dg) shared const { return 0; }\n    }\n\n    static assert( canForeach!(             C  ,              int  ));\n    static assert( canForeach!(       const(C) ,        const(int) ));\n    static assert( canForeach!(   immutable(C) ,    immutable(int) ));\n    static assert( canForeach!(      shared(C) ,       shared(int) ));\n    static assert( canForeach!(shared(const(C)), shared(const(int))));\n\n    static assert( canForeach!(             D  , int));\n    static assert( canForeach!(       const(D) , int));\n    static assert( canForeach!(   immutable(D) , int));\n    static assert(!canForeach!(      shared(D) , int));\n    static assert(!canForeach!(shared(const(D)), int));\n\n    static assert(!canForeach!(             E  , int));\n    static assert(!canForeach!(       const(E) , int));\n    static assert( canForeach!(   immutable(E) , int));\n    static assert( canForeach!(      shared(E) , int));\n    static assert( canForeach!(shared(const(E)), int));\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2443\n\nstruct S2443\n{\n    int[] arr;\n    int opApply(int delegate(size_t i, ref int v) dg)\n    {\n        int result = 0;\n        foreach (i, ref x; arr)\n        {\n            if ((result = dg(i, x)) != 0)\n                break;\n        }\n        return result;\n    }\n}\n\nvoid test2443()\n{\n    S2443 s;\n    foreach (i, ref v; s) {}\n    foreach (i,     v; s) {}\n    static assert(!__traits(compiles, { foreach (ref i, ref v; s) {} }));\n    static assert(!__traits(compiles, { foreach (ref i,     v; s) {} }));\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3187\n\nclass Collection\n{\n    int opApply(int delegate(ref Object) a)\n    {\n        return 0;\n    }\n}\n\nObject testForeach(Collection level1, Collection level2)\n{\n    foreach (first; level1) {\n        foreach (second; level2)\n            return second;\n    }\n    return null;\n}\n\nvoid test3187()\n{\n    testForeach(new Collection, new Collection);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4090\n\nvoid test4090a()\n{\n    double[10] arr = 1;\n    double tot = 0;\n\n  static assert(!__traits(compiles, {\n    foreach (immutable ref x; arr) {}\n  }));\n    foreach (const ref x; arr)\n    {\n        static assert(is(typeof(x) == const double));\n        tot += x;\n    }\n    foreach (immutable x; arr)\n    {\n        static assert(is(typeof(x) == immutable double));\n        tot += x;\n    }\n    assert(tot == 1*10 + 1*10);\n}\n\nvoid test4090b()\n{\n    int tot = 0;\n\n  static assert(!__traits(compiles, {\n    foreach (immutable ref x; 1..11) {}\n  }));\n    foreach (const ref x; 1..11)\n    {\n        static assert(is(typeof(x) == const int));\n        tot += x;\n    }\n    foreach (immutable x; 1..11)\n    {\n        static assert(is(typeof(x) == immutable int));\n        tot += x;\n    }\n    assert(tot == 55 + 55);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5605\n\nstruct MyRange\n{\n    int theOnlyOne;\n\n    @property bool empty() const\n    {\n        return true;\n    }\n\n    @property ref int front()\n    {\n        return theOnlyOne;\n    }\n\n    void popFront()\n    {}\n}\n\nstruct MyCollection\n{\n    MyRange opSlice() const\n    {\n        return MyRange();\n    }\n}\n\nvoid test5605()\n{\n    auto coll = MyCollection();\n\n    foreach (i; coll) {            // <-- compilation error\n        // ...\n    }\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7004\n\nvoid func7004(A...)(A args)\n{\n    foreach (i, e; args){}        // OK\n    foreach (uint i, e; args){}   // OK\n    foreach (size_t i, e; args){} // NG\n}\nvoid test7004()\n{\n    func7004(1, 3.14);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7406\n\ntemplate TypeTuple7406(T...)\n{\n    alias T TypeTuple7406;\n}\n\ntemplate foobar7406(T)\n{\n    enum foobar = 2;\n}\n\nvoid test7406()\n{\n    foreach (sym; TypeTuple7406!(int, double))     // OK\n        pragma(msg, sym.stringof);\n\n    foreach (sym; TypeTuple7406!(foobar7406))      // OK\n        pragma(msg, sym.stringof);\n\n    foreach (sym; TypeTuple7406!(test7406))        // OK\n        pragma(msg, sym.stringof);\n\n    foreach (sym; TypeTuple7406!(int, foobar7406)) // Error: type int has no value\n        pragma(msg, sym.stringof);\n\n    foreach (sym; TypeTuple7406!(int, test7406))   // Error: type int has no value\n        pragma(msg, sym.stringof);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6659\n\nvoid test6659()\n{\n    static struct Iter\n    {\n        ~this()\n        {\n            ++_dtor;\n        }\n\n        bool opCmp(ref const Iter rhs) { return _pos == rhs._pos; }\n        void opUnary(string op:\"++\")() { ++_pos; }\n        size_t _pos;\n\n        static size_t _dtor;\n    }\n\n    foreach (ref iter; Iter(0) .. Iter(10))\n    {\n        assert(Iter._dtor == 0);\n    }\n    assert(Iter._dtor == 2);\n\n    Iter._dtor = 0; // reset\n\n    for (auto iter = Iter(0), limit = Iter(10); iter != limit; ++iter)\n    {\n        assert(Iter._dtor == 0);\n    }\n    assert(Iter._dtor == 2);\n}\n\nvoid test6659a()\n{\n    auto value = 0;\n    try\n    {\n        for ({scope(success) { assert(value == 1); value = 2;} }  true; )\n        {\n            value = 1;\n            break;\n        }\n        assert(value == 2);\n    }\n    catch (Exception e)\n    {\n        assert(0);\n    }\n    assert(value == 2);\n}\n\nvoid test6659b()\n{\n    auto value = 0;\n    try\n    {\n        for ({scope(failure) value = 1;}  true; )\n        {\n            throw new Exception(\"\");\n        }\n        assert(0);\n    }\n    catch (Exception e)\n    {\n        assert(e);\n    }\n    assert(value == 1);\n}\n\nvoid test6659c()\n{\n    auto value = 0;\n    try\n    {\n        for ({scope(exit) value = 1;}  true; )\n        {\n            throw new Exception(\"\");\n        }\n        assert(0);\n    }\n    catch (Exception e)\n    {\n        assert(e);\n    }\n    assert(value == 1);\n}\n\n/***************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=10221\n\nvoid test10221()\n{\n    // All of these should work, but most are too slow.  Just check they compile.\n    foreach(char i; char.min..char.max+1) {}\n    if (0) foreach(wchar i; wchar.min..wchar.max+1) {}\n    if (0) foreach(dchar i; dchar.min..dchar.max+1) {}\n    foreach(byte i; byte.min..byte.max+1) {}\n    foreach(ubyte i; ubyte.min..ubyte.max+1) {}\n    if (0) foreach(short i; short.min..short.max+1) {}\n    if (0) foreach(ushort i; ushort.min..ushort.max+1) {}\n    if (0) foreach(int i; int.min..int.max+1U) {}\n    if (0) foreach(uint i; uint.min..uint.max+1L) {}\n    if (0) foreach(long i; long.min..long.max+1UL) {}\n\n    foreach_reverse(char i; char.min..char.max+1) { assert(i == typeof(i).max); break; }\n    foreach_reverse(wchar i; wchar.min..wchar.max+1) { assert(i == typeof(i).max); break; }\n    foreach_reverse(dchar i; dchar.min..dchar.max+1) { assert(i == typeof(i).max); break; }\n    foreach_reverse(byte i; byte.min..byte.max+1) { assert(i == typeof(i).max); break; }\n    foreach_reverse(ubyte i; ubyte.min..ubyte.max+1) { assert(i == typeof(i).max); break; }\n    foreach_reverse(short i; short.min..short.max+1) { assert(i == typeof(i).max); break; }\n    foreach_reverse(ushort i; ushort.min..ushort.max+1) { assert(i == typeof(i).max); break; }\n    foreach_reverse(int i; int.min..int.max+1U) { assert(i == typeof(i).max); break; }\n    foreach_reverse(uint i; uint.min..uint.max+1L) { assert(i == typeof(i).max); break; }\n    foreach_reverse(long i; long.min..long.max+1UL) { assert(i == typeof(i).max); break; }\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7814\n\nstruct File7814\n{\n    ~this(){}\n}\n\nstruct ByLine7814\n{\n    File7814 file;\n\n    // foreach interface\n    @property bool empty() const    { return true; }\n    @property char[] front()        { return null; }\n    void popFront(){}\n}\n\nvoid test7814()\n{\n    int dummy;\n    ByLine7814 f;\n    foreach (l; f) {\n        scope(failure) // 'failure' or 'success' fails, but 'exit' works\n            dummy = -1;\n        dummy = 0;\n    }\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10049\n\nstruct ByLine10049\n{\n    bool empty() { return true; }\n    string front() { return null; }\n    void popFront() {}\n\n    ~this() {}  // necessary\n}\n\nvoid test10049()\n{\n    ByLine10049 r;\n    foreach (line; r)\n    {\n        doNext:\n            {}\n    }\n}\n\n/******************************************/\n\nstruct T11955(T...) { T field; alias field this; }\n\nalias X11955 = uint;\n\nstruct S11955\n{\n    enum empty = false;\n    T11955!(uint, uint) front;\n    void popFront() {}\n}\n\nvoid test11955()\n{\n    foreach(X11955 i, v; S11955()) {}\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6652\n\nvoid test6652()\n{\n    size_t sum;\n    foreach (i; 0 .. 10)\n        sum += i++; // 0123456789\n    assert(sum == 45);\n\n    sum = 0;\n    foreach (ref i; 0 .. 10)\n        sum += i++; // 02468\n    assert(sum == 20);\n\n    sum = 0;\n    foreach_reverse (i; 0 .. 10)\n        sum += i--; // 9876543210\n    assert(sum == 45);\n\n    sum = 0;\n    foreach_reverse (ref i; 0 .. 10)\n        sum += i--; // 97531\n    assert(sum == 25);\n\n    enum ary = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n    sum = 0;\n    foreach (i, v; ary)\n    {\n        assert(i == v);\n        sum += i++; // 0123456789\n    }\n    assert(sum == 45);\n\n    sum = 0;\n    foreach (ref i, v; ary)\n    {\n        assert(i == v);\n        sum += i++; // 02468\n    }\n    assert(sum == 20);\n\n    sum = 0;\n    foreach_reverse (i, v; ary)\n    {\n        assert(i == v);\n        sum += i--; // 9876543210\n    }\n    assert(sum == 45);\n\n    sum = 0;\n    foreach_reverse (ref i, v; ary)\n    {\n        assert(i == v);\n        sum += i--; // 97531\n    }\n    assert(sum == 25);\n\n    static struct Iter\n    {\n        ~this()\n        {\n            ++_dtorCount;\n        }\n\n        bool opCmp(ref const Iter rhs)\n        {\n            return _pos == rhs._pos;\n        }\n\n        void opUnary(string op)() if(op == \"++\" || op == \"--\")\n        {\n            mixin(op ~ q{_pos;});\n        }\n\n        size_t _pos;\n        static size_t _dtorCount;\n    }\n\n    Iter._dtorCount = sum = 0;\n    foreach (v; Iter(0) .. Iter(10))\n        sum += v._pos++; // 0123456789\n    assert(sum == 45 && Iter._dtorCount == 12);\n\n    Iter._dtorCount = sum = 0;\n    foreach (ref v; Iter(0) .. Iter(10))\n        sum += v._pos++; // 02468\n    assert(sum == 20 && Iter._dtorCount == 2);\n\n    // additional dtor calls due to unnecessary postdecrements\n    Iter._dtorCount = sum = 0;\n    foreach_reverse (v; Iter(0) .. Iter(10))\n        sum += v._pos--; // 9876543210\n    assert(sum == 45 && Iter._dtorCount >= 12);\n\n    Iter._dtorCount = sum = 0;\n    foreach_reverse (ref v; Iter(0) .. Iter(10))\n        sum += v._pos--; // 97531\n    assert(sum == 25 && Iter._dtorCount >= 2);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8595\n\nstruct OpApply8595\n{\n    int opApply(int delegate(ref int) dg)\n    {\n        assert(0);\n    }\n}\n\nstring test8595()\n{\n    foreach (elem; OpApply8595.init)\n    {\n        static assert(is(typeof(return) == string));\n    }\n    assert(0);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9068\n\nstruct Foo9068\n{\n    static int[] destroyed;\n    int x;\n    ~this() { destroyed ~= x; }\n}\n\nstruct SimpleCounter9068\n{\n    static int destroyedCount;\n    enum int limit = 5;\n    int counter;\n    ~this() { destroyedCount++; }\n\n    // Range primitives.\n    @property bool empty() const { return counter >= limit; }\n    @property int front() { return counter; }\n    void popFront() { counter++; }\n}\n\nvoid test9068()\n{\n    //----------------------------------------\n    // There was never a bug in this case (no range).\n    int sum;\nloop_simple:\n    foreach (i; [10, 20])\n    {\n        sum += i;\n        break loop_simple;\n    }\n    assert(sum == 10);\n\n    //----------------------------------------\n    // There was a bug with loops over ranges.\n    int last = -1;\nX:  foreach (i; SimpleCounter9068())\n    {\n        switch(i)\n        {\n            case 3:\n                break X;\n            default:\n                last = i;\n       }\n    }\n    assert(last == 2);\n    assert(SimpleCounter9068.destroyedCount == 1);\n\n    //----------------------------------------\n    // Simpler case: the compiler error had nothing to do with the switch.\n    last = -1;\nloop_with_range:\n    foreach (i; SimpleCounter9068())\n    {\n        last = i;\n        break loop_with_range;\n    }\n    assert(last == 0);\n    assert(SimpleCounter9068.destroyedCount == 2);\n\n    //----------------------------------------\n    // Test with destructors: the loop is implicitly wrapped into two\n    // try/finally clauses.\nloop_with_dtors:\n    for (auto x = Foo9068(4), y = Foo9068(5); x.x != 10; ++x.x)\n    {\n        if (x.x == 8)\n            break loop_with_dtors;\n    }\n    assert(Foo9068.destroyed == [5, 8]);\n    Foo9068.destroyed = null;\n\n    //----------------------------------------\n    // Same with an unlabelled break.\n    for (auto x = Foo9068(4), y = Foo9068(5); x.x != 10; ++x.x)\n    {\n        if (x.x == 7)\n            break;\n    }\n    assert(Foo9068.destroyed == [5, 7]);\n    Foo9068.destroyed = null;\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11885\n\nstruct Foo11885\n{\n    static int[] destroyed;\n    int x;\n    ~this() { destroyed ~= x; }\n}\n\nstruct SimpleCounter11885\n{\n    static int destroyedCount;\n    enum int limit = 5;\n    int counter;\n    ~this() { destroyedCount++; }\n\n    // Range primitives.\n    @property bool empty() const { return counter >= limit; }\n    @property int front() { return counter; }\n    void popFront() { counter++; }\n}\n\nvoid test11885()\n{\n    //----------------------------------------\n    // There was never a bug in this case (no range).\n    int sum;\nloop_simple:\n    foreach (i; [10, 20])\n    {\n        sum += i;\n        continue loop_simple;\n    }\n    assert(sum == 30);\n\n    //----------------------------------------\n    // There was a bug with loops over ranges.\n    int last = -1;\nX:  foreach (i; SimpleCounter11885())\n    {\n        switch(i)\n        {\n            case 3:\n                continue X;\n            default:\n                last = i;\n       }\n    }\n    assert(last == 4);\n    assert(SimpleCounter11885.destroyedCount == 1);\n\n    //----------------------------------------\n    // Simpler case: the compiler error had nothing to do with the switch.\n    last = -1;\nloop_with_range:\n    foreach (i; SimpleCounter11885())\n    {\n        last = i;\n        continue loop_with_range;\n    }\n    assert(last == 4);\n    assert(SimpleCounter11885.destroyedCount == 2);\n\n    //----------------------------------------\n    // Test with destructors: the loop is implicitly wrapped into two\n    // try/finally clauses.\nloop_with_dtors:\n    for (auto x = Foo11885(4), y = Foo11885(5); x.x != 10; ++x.x)\n    {\n        if (x.x == 8)\n            continue loop_with_dtors;\n    }\n    assert(Foo11885.destroyed == [5, 10]);\n    Foo11885.destroyed = null;\n\n    //----------------------------------------\n    // Same with an unlabelled continue.\n    for (auto x = Foo11885(4), y = Foo11885(5); x.x != 10; ++x.x)\n    {\n        if (x.x == 7)\n            continue;\n    }\n    assert(Foo11885.destroyed == [5, 10]);\n    Foo11885.destroyed = null;\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10475\n\nvoid test10475a()\n{\n    struct DirIterator\n    {\n        int _store = 42;\n        ~this() { assert(0); }\n    }\n\n    DirIterator dirEntries()\n    {\n        throw new Exception(\"\");\n    }\n\n    try\n    {\n        for (DirIterator c = dirEntries(); true; ) {}\n        assert(0);\n    }\n    catch (Exception e)\n    {\n        assert(e.next is null);\n    }\n}\n\nvoid test10475b()\n{\n    uint g;\n    struct S\n    {\n        uint flag;\n        ~this() { g |= flag; }\n    }\n\n    S thrown()\n    {\n        throw new Exception(\"\");\n    }\n\n    g = 0x0;\n    try\n    {\n        for (auto x = S(0x1), y = S(0x2), z = thrown(); true; ) {}\n        assert(0);\n    }\n    catch (Exception e)\n    {\n        assert(e.next is null);\n    }\n    assert(g == 0x3);\n\n    g = 0x0;\n    try\n    {\n        for (auto x = S(0x1), y = thrown(), z = S(0x2); true; ) {}\n        assert(0);\n    }\n    catch (Exception e)\n    {\n        assert(e.next is null);\n    }\n    assert(g == 0x1);\n\n    g = 0x0;\n    try\n    {\n        for (auto x = thrown(), y = S(0x1), z = S(0x2); true; ) {}\n        assert(0);\n    }\n    catch (Exception e)\n    {\n        assert(e.next is null);\n    }\n    assert(g == 0x0);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11291\n\nvoid test11291()\n{\n    struct Tuple(T...)\n    {\n        T field;\n        alias field this;\n    }\n    struct zip\n    {\n        string[] s1, s2;\n\n        bool empty() { return true; }\n        auto front() { return Tuple!(string, string)(s1[0], s2[0]); }\n        void popFront() {}\n    }\n\n    foreach (const a, const b; zip([\"foo\"], [\"bar\"]))\n    {\n        static assert(is(typeof(a) == const string));\n        static assert(is(typeof(b) == const string));\n\n        static assert(!__traits(compiles, a = \"something\"));\n        static assert(!__traits(compiles, b = \"something\"));\n    }\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12103\n\nalias TypeTuple12103(TL...) = TL;\n\nalias Id12103(alias a) = a;\n\nvoid test12103()\n{\n    alias fs1 = TypeTuple12103!(() => 0, () => 1);\n    foreach (i, f; fs1)\n    {\n        static assert(f() == i);\n        static assert(Id12103!f() == i);\n        assert(f() == i);\n        assert(Id12103!f() == i);\n    }\n\n    alias fs2 = TypeTuple12103!(x=>x+0, y=>y+1);\n    foreach (i, f; fs2)\n    {\n        static assert(f(0) == i);\n        static assert(Id12103!f(0) == i);\n        assert(f(0) == i);\n        assert(Id12103!f(0) == i);\n    }\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12739\n\nstruct S12739\n{\nnothrow:\n    int opApply(int delegate(ref int) nothrow dg)\n    {\n        return 0;\n    }\n}\n\nvoid test12739() nothrow\n{\n    S12739 s;\n    foreach (e; s) {}\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12932\n\nvoid test12932() @nogc\n{\n    int sum;\n    foreach (e; [1,2,3])\n    {\n        sum += e;\n    }\n    assert(sum == 6);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13756\n\nvoid test13756()\n{\n    printf(\"test13756()\\n\");\n    int[int] org = [1:2], aa;\n\n    aa = org.dup;\n    foreach (v; aa)\n    {\n        static assert(is(typeof(v) == int));\n        v = 20;\n    }\n    assert(aa == [1:2]);\n\n    aa = org.dup;\n    foreach (ref v; aa)\n    {\n        static assert(is(typeof(v) == int));\n        v = 20;\n    }\n    assert(aa == [1:20]);\n\n    aa = org.dup;\n    foreach (k, v; aa)\n    {\n        static assert(is(typeof(k) == int));\n        static assert(is(typeof(v) == int));\n        k = 10;\n        v = 20;\n    }\n    assert(aa == [1:2]);\n\n    aa = org.dup;\n    foreach (k, ref v; aa)\n    {\n        static assert(is(typeof(k) == int));\n        static assert(is(typeof(v) == int));\n        k = 10;\n        v = 20;\n    }\n    assert(aa == [1:20]);\n\n    aa = org.dup;\n    foreach (ref k, v; aa)      // NG -> OK\n    {\n        static assert(is(typeof(k) == const int));\n        static assert(is(typeof(v) == int));\n        static assert(!__traits(compiles, k = 10));\n        v = 20;\n    }\n    assert(aa == [1:2]);\n\n    aa = org.dup;\n    foreach (ref k, ref v; aa)  // NG -> OK\n    {\n        static assert(is(typeof(k) == const int));\n        static assert(is(typeof(v) == int));\n        static assert(!__traits(compiles, k = 10));\n        v = 20;\n    }\n    assert(aa == [1:20]);\n\n    foreach (ref const k, v; aa)  // NG -> OK, same with 'ref k'\n    {\n        static assert(is(typeof(k) == const int));\n    }\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14653\n\nstatic string result14653;\n\nclass RangeClass14653\n{\n    int a;\n\n    this(T)(T...) { result14653 ~= \"c\"; }\n    ~this()       { result14653 ~= \"d\"; a = -1; }\n\n    @property bool empty() { result14653 ~= \"e\"; return a >= 2; }\n    @property int front()  { result14653 ~= \"f\"; assert(a >= 0); return a; }\n    void popFront()        { result14653 ~= \"p\"; ++a; }\n}\n\nauto scoped14653(T, A...)(A args)\n{\n    static struct Scoped(T)\n    {\n        void[__traits(classInstanceSize, T)] store;\n        T payload() { return cast(T)cast(void*)store.ptr; }\n        alias payload this;\n\n        ~this()\n        {\n            //.destroy(payload);\n            payload.__dtor();\n            (cast(byte[])store)[] = 0;\n        }\n    }\n\n    Scoped!T result = void;\n\n    //emplace!T(result.store[], args);\n    result.store[] = typeid(T).initializer[];\n    result.payload.__ctor(args);\n\n    return result;\n}\n\nvoid test14653()\n{\n    printf(\"test14653()\\n\");\n    foreach (e; scoped14653!RangeClass14653(1))\n    {\n        result14653 ~= \"b\";\n    }\n    assert(result14653 == \"cefbpefbped\", result14653);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15777\n\ntemplate funA15777()\n{\n    import imports.test15777a;\n    alias funA15777 = fun;\n}\n\ntemplate funB15777()\n{\n    import imports.test15777b;\n    alias funB15777 = fun;\n}\n\ntemplate funAB15777()\n{\n    import imports.test15777a;\n    import imports.test15777b;\n    alias funAB15777 = fun;\n}\n\nvoid foo15777(alias tpl)()\n{\n    alias seq = AliasSeq!(tpl!());\n    // Make alias of 'overload set' in tuple elements\n    static assert(seq.length == 1);\n    foreach (i, n; seq)\n    {\n        static assert(__traits(identifier, seq[i]) == \"fun\");\n    }\n}\n\nvoid test15777()\n{\n    foo15777!funA15777;\n    foo15777!funB15777;\n    foo15777!funAB15777;\n}\n\n/***************************************/\n\nint main()\n{\n    test1();\n    test2411();\n    test2442();\n    test2443();\n    test3187();\n    test4090a();\n    test4090b();\n    test5605();\n    test7004();\n    test10221();\n    test7406();\n    test6659();\n    test6659a();\n    test6659b();\n    test6659c();\n    test7814();\n    test6652();\n    test9068();\n    test11885();\n    test10475a();\n    test10475b();\n    test11291();\n    test12103();\n    test12739();\n    printf(\"test12932()\\n\");\n    test12932();\n    test13756();\n    test14653();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/funclit.d",
    "content": "import core.vararg;\n\nextern (C) int printf(const char*, ...);\n\n/***************************************************/\n// lambda syntax check\n\nauto una(alias dg)(int n)\n{\n    return dg(n);\n}\nauto bin(alias dg)(int n, int m)\n{\n    return dg(n, m);\n}\nvoid test1()\n{\n    assert(una!(      a  => a*2 )(2) == 4);\n    assert(una!( (    a) => a*2 )(2) == 4);\n    assert(una!( (int a) => a*2 )(2) == 4);\n    assert(una!(             (    a){ return a*2; } )(2) == 4);\n    assert(una!( function    (    a){ return a*2; } )(2) == 4);\n    assert(una!( function int(    a){ return a*2; } )(2) == 4);\n    assert(una!( function    (int a){ return a*2; } )(2) == 4);\n    assert(una!( function int(int a){ return a*2; } )(2) == 4);\n    assert(una!( delegate    (    a){ return a*2; } )(2) == 4);\n    assert(una!( delegate int(    a){ return a*2; } )(2) == 4);\n    assert(una!( delegate    (int a){ return a*2; } )(2) == 4);\n    assert(una!( delegate int(int a){ return a*2; } )(2) == 4);\n\n    // partial parameter specialization syntax\n    assert(bin!( (    a,     b) => a*2+b )(2,1) == 5);\n    assert(bin!( (int a,     b) => a*2+b )(2,1) == 5);\n    assert(bin!( (    a, int b) => a*2+b )(2,1) == 5);\n    assert(bin!( (int a, int b) => a*2+b )(2,1) == 5);\n    assert(bin!(             (    a,     b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!(             (int a,     b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!(             (    a, int b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!(             (int a, int b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( function    (    a,     b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( function    (int a,     b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( function    (    a, int b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( function    (int a, int b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( function int(    a,     b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( function int(int a,     b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( function int(    a, int b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( function int(int a, int b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( delegate    (    a,     b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( delegate    (int a,     b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( delegate    (    a, int b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( delegate    (int a, int b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( delegate int(    a,     b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( delegate int(int a,     b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( delegate int(    a, int b){ return a*2+b; } )(2,1) == 5);\n    assert(bin!( delegate int(int a, int b){ return a*2+b; } )(2,1) == 5);\n}\n\n/***************************************************/\n// on initializer\n\nvoid test2()\n{\n    // explicit typed binding ignite parameter types inference\n    int function(int) fn1 = a => a*2;                               assert(fn1(2) == 4);\n    int function(int) fn2 =             (    a){ return a*2; };     assert(fn2(2) == 4);\n    int function(int) fn3 = function    (    a){ return a*2; };     assert(fn3(2) == 4);\n    int function(int) fn4 = function int(    a){ return a*2; };     assert(fn4(2) == 4);\n    int function(int) fn5 = function    (int a){ return a*2; };     assert(fn5(2) == 4);\n    int function(int) fn6 = function int(int a){ return a*2; };     assert(fn6(2) == 4);\n    int delegate(int) dg1 = a => a*2;                               assert(dg1(2) == 4);\n    int delegate(int) dg2 =             (    a){ return a*2; };     assert(dg2(2) == 4);\n    int delegate(int) dg3 = delegate    (    a){ return a*2; };     assert(dg3(2) == 4);\n    int delegate(int) dg4 = delegate int(    a){ return a*2; };     assert(dg4(2) == 4);\n    int delegate(int) dg5 = delegate    (int a){ return a*2; };     assert(dg5(2) == 4);\n    int delegate(int) dg6 = delegate int(int a){ return a*2; };     assert(dg6(2) == 4);\n\n    // function/delegate mismatching always raises an error\n    static assert(!__traits(compiles, { int function(int) xfg3 = delegate    (    a){ return a*2; }; }));\n    static assert(!__traits(compiles, { int function(int) xfg4 = delegate int(    a){ return a*2; }; }));\n    static assert(!__traits(compiles, { int function(int) xfg5 = delegate    (int a){ return a*2; }; }));\n    static assert(!__traits(compiles, { int function(int) xfg6 = delegate int(int a){ return a*2; }; }));\n    static assert(!__traits(compiles, { int delegate(int) xdn3 = function    (    a){ return a*2; }; }));\n    static assert(!__traits(compiles, { int delegate(int) xdn4 = function int(    a){ return a*2; }; }));\n    static assert(!__traits(compiles, { int delegate(int) xdn5 = function    (int a){ return a*2; }; }));\n    static assert(!__traits(compiles, { int delegate(int) xdn6 = function int(int a){ return a*2; }; }));\n\n    // auto binding requires explicit parameter types at least\n    static assert(!__traits(compiles, { auto afn1 = a => a*2;                           }));\n    static assert(!__traits(compiles, { auto afn2 =             (    a){ return a*2; }; }));\n    static assert(!__traits(compiles, { auto afn3 = function    (    a){ return a*2; }; }));\n    static assert(!__traits(compiles, { auto afn4 = function int(    a){ return a*2; }; }));\n    static assert(!__traits(compiles, { auto adg3 = delegate    (    a){ return a*2; }; }));\n    static assert(!__traits(compiles, { auto adg4 = delegate int(    a){ return a*2; }; }));\n    auto afn5 = function    (int a){ return a*2; };     assert(afn5(2) == 4);\n    auto afn6 = function int(int a){ return a*2; };     assert(afn6(2) == 4);\n    auto adg5 = delegate    (int a){ return a*2; };     assert(adg5(2) == 4);\n    auto adg6 = delegate int(int a){ return a*2; };     assert(adg6(2) == 4);\n\n    // partial specialized lambda\n    string delegate(int, string) dg =\n        (n, string s){\n            string r = \"\";\n            foreach (_; 0..n) r~=s;\n            return r;\n        };\n    assert(dg(2, \"str\") == \"strstr\");\n}\n\n/***************************************************/\n// on return statement\n\nvoid test3()\n{\n    // inference matching system is same as on initializer\n    int delegate(int) mul(int x)\n    {\n        return a => a * x;\n    }\n    assert(mul(5)(2) == 10);\n}\n\n/***************************************************/\n// on function arguments\n\nauto foo4(int delegate(int) dg) { return dg(10); }\nauto foo4(int delegate(int, int) dg) { return dg(10, 20); }\n\nvoid nbar4fp(void function(int) fp) { }\nvoid nbar4dg(void delegate(int) dg) { }\nvoid tbar4fp(T,R)(R function(T) dg) { static assert(is(typeof(dg) == void function(int))); }\nvoid tbar4dg(T,R)(R delegate(T) dg) { static assert(is(typeof(dg) == void delegate(int))); }\n\nauto nbaz4(void function() fp) { return 1; }\nauto nbaz4(void delegate() dg) { return 2; }\nauto tbaz4(R)(R function() dg) { static assert(is(R == void)); return 1; }\nauto tbaz4(R)(R delegate() dg) { static assert(is(R == void)); return 2; }\n\nauto thoo4(T)(T lambda){ return lambda; }\n\nvoid tfun4a()(int function(int) a){}\nvoid tfun4b(T)(T function(T) a){}\nvoid tfun4c(T)(T f){}\n\nvoid test4()\n{\n    int v;\n    static void sfoo() {}\n           void nfoo() {}\n\n    // parameter type inference + overload resolution\n    assert(foo4((a)   => a * 2) == 20);\n    assert(foo4((a,b) => a * 2 + b) == 40);\n\n    // function/delegate inference\n    nbar4fp((int x){ });\n    nbar4dg((int x){ });\n    tbar4fp((int x){ });\n    tbar4dg((int x){ });\n\n    // function/delegate inference + overload resolution\n    assert(nbaz4({ }) == 1);\n    assert(nbaz4({ v = 1; }) == 2);\n    assert(nbaz4({ sfoo(); }) == 1);    // https://issues.dlang.org/show_bug.cgi?id=8836\n    assert(nbaz4({ nfoo(); }) == 2);\n\n    assert(tbaz4({ }) == 1);\n    assert(tbaz4({ v = 1; }) == 2);\n    assert(tbaz4({ sfoo(); }) == 1);\n    assert(tbaz4({ nfoo(); }) == 2);\n\n    // template function deduction\n    static assert(is(typeof(thoo4({ })) : void function()));\n    static assert(is(typeof(thoo4({ v = 1;  })) : void delegate()));\n\n    tfun4a(a => a);\n    static assert(!__traits(compiles, { tfun4b(a => a); }));\n    static assert(!__traits(compiles, { tfun4c(a => a); }));\n}\n\nvoid fsvarg4(int function(int)[] a...){}\nvoid fcvarg4(int dummy, ...){}\n\nvoid tsvarg4a()(int function(int)[] a...){}\nvoid tsvarg4b(T)(T function(T)[] a...){}\nvoid tsvarg4c(T)(T [] a...){}\nvoid tcvarg4()(int dummy, ...){}\n\nvoid test4v()\n{\n    fsvarg4(function(int a){ return a; });      // OK\n    fsvarg4(a => a);                            // OK\n\n    fcvarg4(0, function(int a){ return a; });   // OK\n    static assert(!__traits(compiles, { fcvarg4(0, a => a); }));\n\n    tsvarg4a(function(int a){ return a; });     // OK\n    tsvarg4b(function(int a){ return a; });     // OK\n    tsvarg4c(function(int a){ return a; });     // OK\n    tsvarg4a(a => a);\n    static assert(!__traits(compiles, { tsvarg4b(a => a); }));\n    static assert(!__traits(compiles, { tsvarg4c(a => a); }));\n\n    tcvarg4(0, function(int a){ return a; });   // OK\n    static assert(!__traits(compiles, { tcvarg4(0, a => a); }));\n}\n\n// A lambda in function default argument should be deduced to delegate, by the\n// preparation inferType call in TypeFunction.semantic.\nvoid test4_findRoot(scope bool delegate(real lo, real hi) tolerance = (real a, real b) => false)\n{}\n\n/***************************************************/\n// on CallExp::e1\n\nvoid test5()\n{\n    assert((a => a*2)(10) == 20);\n    assert((    a,        s){ return s~s; }(10, \"str\") == \"strstr\");\n    assert((int a,        s){ return s~s; }(10, \"str\") == \"strstr\");\n    assert((    a, string s){ return s~s; }(10, \"str\") == \"strstr\");\n    assert((int a, string s){ return s~s; }(10, \"str\") == \"strstr\");\n}\n\n/***************************************************/\n// escape check to nested function symbols\n\nvoid checkNestedRef(alias dg)(bool isnested)\n{\n    static if (is(typeof(dg) == delegate))\n        enum isNested = true;\n    else static if ((is(typeof(dg) PF == F*, F) && is(F == function)))\n        enum isNested = false;\n    else\n        static assert(0);\n\n    assert(isnested == isNested);\n    dg();\n}\n\nvoid freeFunc(){}\n\nvoid test6()\n{\n    static void localFunc(){}\n    void nestedLocalFunc(){}\n\n    checkNestedRef!({  })(false);\n\n    checkNestedRef!({ freeFunc(); })(false);\n    checkNestedRef!({ localFunc(); })(false);\n    checkNestedRef!({ nestedLocalFunc(); })(true);\n    checkNestedRef!({ void inner(){} inner(); })(false);\n\n    checkNestedRef!({ auto f = &freeFunc; })(false);\n    checkNestedRef!({ auto f = &localFunc; })(false);\n    checkNestedRef!({ auto f = &nestedLocalFunc; })(true);\n    checkNestedRef!({ void inner(){} auto f = &inner; })(false);\n}\n\n/***************************************************/\n// on AssignExp::e2\n\nvoid test7()\n{\n    int function(int) fp;\n    fp = a => a;\n    fp = (int a) => a;\n    fp = function(int a) => a;\n    fp = function int(int a) => a;\n    static assert(!__traits(compiles, { fp = delegate(int a) => a; }));\n    static assert(!__traits(compiles, { fp = delegate int(int a) => a; }));\n\n    int delegate(int) dg;\n    dg = a => a;\n    dg = (int a) => a;\n    dg = delegate(int a) => a;\n    dg = delegate int(int a) => a;\n    static assert(!__traits(compiles, { dg = function(int a) => a; }));\n    static assert(!__traits(compiles, { dg = function int(int a) => a; }));\n}\n\n/***************************************************/\n// on StructLiteralExp::elements\n\nvoid test8()\n{\n    struct S\n    {\n        int function(int) fp;\n    }\n    auto s1 = S(a => a);\n    static assert(!__traits(compiles, { auto s2 = S((a, b) => a); }));\n}\n\n/***************************************************/\n// on concat operation\n\nvoid test9()\n{\n    int function(int)[] a2;\n    a2 ~= x => x;\n}\n\n/***************************************************/\n// on associative array key\n\nvoid test10()\n{\n    int[int function()] aa;\n    assert(!aa.remove(() => 1));\n\n    int[int function(int)] aa2;\n    assert(!aa2.remove(x => 1));\n}\n\n/***************************************************/\n// on common type deduction\n\nvoid test11()\n{\n    auto a1 = [x => x, (int x) => x * 2];\n    static assert(is(typeof(a1[0]) == int function(int) pure @safe nothrow @nogc));\n    assert(a1[0](10) == 10);\n    assert(a1[1](10) == 20);\n\n    //int n = 10;\n    //auto a2 = [x => n, (int x) => x * 2];\n    //static assert(is(typeof(a2[0]) == int delegate(int) @safe nothrow));\n    //assert(a2[0](99) == 10);\n    //assert(a2[1](10) == 20);\n\n    int function(int) fp = true ? (x => x) : (x => x*2);\n    assert(fp(10) == 10);\n\n    int m = 10;\n    int delegate(int) dg = true ? (x => x) : (x => m*2);\n    assert(dg(10) == 10);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3235\n\nvoid test3235()\n{\n    // from TDPL\n    auto f = (int i) {};\n    static if (is(typeof(f) _ == F*, F) && is(F == function))\n    {} else static assert(0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6714\n\nvoid foo6714x(int function (int, int) a){}\nvoid bar6714x(int delegate (int, int) a){}\n\nint bar6714y(double delegate(int, int) a){ return 1; }\nint bar6714y(   int delegate(int, int) a){ return 2; }\n\nvoid test6714()\n{\n    foo6714x((a, b) { return a + b; });\n    bar6714x((a, b) { return a + b; });\n\n    assert(bar6714y((a, b){ return 1.0;  }) == 1);\n    assert(bar6714y((a, b){ return 1.0f; }) == 1);\n    assert(bar6714y((a, b){ return a;    }) == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7193\n\nvoid test7193()\n{\n    static assert(!__traits(compiles, {\n        delete a => a;\n    }));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7207\n// on CastExp\n\nvoid test7202()\n{\n    auto dg = cast(int function(int))(a => a);\n    assert(dg(10) == 10);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7288\n\nvoid test7288()\n{\n    // 7288 -> OK\n    auto foo()\n    {\n        int x;\n        return () => { return x; };\n    }\n    pragma(msg, typeof(&foo));\n    alias int delegate() pure nothrow @nogc @safe delegate() pure nothrow @nogc @safe delegate() pure nothrow @safe Dg;\n    pragma(msg, Dg);\n    static assert(is(typeof(&foo) == Dg));  // should pass\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7499\n\nvoid test7499()\n{\n    int function(int)[]   a1 = [ x => x ];  // 7499\n    int function(int)[][] a2 = [[x => x]];  // +a\n    assert(a1[0]   (10) == 10);\n    assert(a2[0][0](10) == 10);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7500\n\nvoid test7500()\n{\n    alias immutable bool function(int[]) Foo;\n    Foo f = a => true;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7525\n\nvoid test7525()\n{\n    {\n        char[] delegate() a = { return null; };\n           int delegate() b = { return 1U; };\n          uint delegate() c = { return 1; };\n         float delegate() d = { return 1.0; };\n        double delegate() e = { return 1.0f; };\n    }\n\n    {\n        char[] delegate(int) a = (x){ return null; };\n           int delegate(int) b = (x){ return 1U; };\n          uint delegate(int) c = (x){ return 1; };\n         float delegate(int) d = (x){ return 1.0; };\n        double delegate(int) e = (x){ return 1.0f; };\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7582\n\nvoid test7582()\n{\n    void delegate(int) foo;\n    void delegate(int) foo2;\n    foo = (a) {\n        foo2 = (b) { };\n    };\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7649\n\nvoid test7649()\n{\n    void foo(int function(int) fp = x => 1)\n    {\n        assert(fp(1) == 1);\n    }\n    foo();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7650\n\nvoid test7650()\n{\n    int[int function(int)] aa1 = [x=>x:1, x=>x*2:2];\n    foreach (k, v; aa1) {\n        if (v == 1) assert(k(10) == 10);\n        if (v == 2) assert(k(10) == 20);\n    }\n\n    int function(int)[int] aa2 = [1:x=>x, 2:x=>x*2];\n    assert(aa2[1](10) == 10);\n    assert(aa2[2](10) == 20);\n\n    int n = 10;\n    int[int delegate(int)] aa3 = [x=>n+x:1, x=>n+x*2:2];\n    foreach (k, v; aa3) {\n        if (v == 1) assert(k(10) == 20);\n        if (v == 2) assert(k(10) == 30);\n    }\n\n    int delegate(int)[int] aa4 = [1:x=>n+x, 2:x=>n+x*2];\n    assert(aa4[1](10) == 20);\n    assert(aa4[2](10) == 30);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7705\n\nvoid test7705()\n{\n    void foo1(void delegate(ref int ) dg){ int x=10; dg(x); }\n    foo1((ref x){ pragma(msg, typeof(x)); assert(x == 10); });\n    static assert(!__traits(compiles, foo1((x){}) ));\n\n    void foo2(void delegate(int, ...) dg){ dg(20, 3.14); }\n    foo2((x,...){ pragma(msg, typeof(x)); assert(x == 20); });\n\n    void foo3(void delegate(int[]...) dg){ dg(1, 2, 3); }\n    foo3((x ...){ pragma(msg, typeof(x)); assert(x == [1,2,3]); });\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7713\n\nvoid foo7713(T)(T delegate(in Object) dlg)\n{}\nvoid test7713()\n{\n   foo7713( (in obj) { return 15; } );   // line 6\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7743\n\nauto foo7743a()\n{\n    int x = 10;\n    return () nothrow {\n        return x;\n    };\n}\nauto foo7743b()\n{\n    int x = 10;\n    return () nothrow => x;\n}\nvoid test7743()\n{\n    pragma(msg, typeof(&foo7743a));\n    static assert(is(typeof(&foo7743a) == int delegate() pure nothrow @nogc @safe function() pure nothrow @safe));\n    assert(foo7743a()() == 10);\n\n    static assert(is(typeof(&foo7743b) == int delegate() pure nothrow @nogc @safe function() pure nothrow @safe));\n    assert(foo7743b()() == 10);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7761\n\nenum dg7761 = (int a) pure => 2 * a;\n\nvoid test7761()\n{\n    static assert(is(typeof(dg7761) == int function(int) pure @safe nothrow @nogc));\n    assert(dg7761(10) == 20);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7941\n\nvoid test7941()\n{\n    static assert(!__traits(compiles, { enum int c = function(){}; }));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8005\n\nvoid test8005()\n{\n    auto n = (a, int n = 2){ return n; }(1);\n    assert(n == 2);\n}\n\n/***************************************************/\n// test8198\n\nvoid test8198()\n{\n    T delegate(T) zero(T)(T delegate(T) f)\n    {\n        return x => x;\n    }\n\n    T delegate(T) delegate(T delegate(T)) succ(T)(T delegate(T) delegate(T delegate(T)) n)\n    {\n        return f => x => f(n(f)(x));\n    }\n\n    uint delegate(uint) delegate(uint delegate(uint)) n = &zero!uint;\n    foreach (i; 0..10)\n    {\n        assert(n(x => x + 1)(0) == i);\n        n = succ(n);\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8226\n\nimmutable f8226 = (int x) => x * 2;\n\nvoid test8226()\n{\n    assert(f8226(10) == 20);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8241\n\nauto exec8241a(alias a = function(x) => x, T...)(T as)\n{\n    return a(as);\n}\n\nauto exec8241b(alias a = (x) => x, T...)(T as)\n{\n    return a(as);\n}\n\nvoid test8241()\n{\n    exec8241a(2);\n    exec8241b(2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8242\n\ntemplate exec8242(alias a, T...)\n{\n    auto func8242(T as)\n    {\n        return a(as);\n    }\n}\n\nmixin exec8242!(x => x, int);\nmixin exec8242!((string x) => x, string);\n\nvoid test8242()\n{\n    func8242(1);\n    func8242(\"\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8315\n\nvoid test8315()\n{\n    bool b;\n    foo8315!(a => b)();\n}\n\nvoid foo8315(alias pred)()\nif (is(typeof(pred(1)) == bool))\n{}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8397\n\nvoid test8397()\n{\n    void function(int) f;\n  static assert(!is(typeof({\n    f = function(string x) {};\n  })));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8496\n\nvoid test8496()\n{\n    alias extern (C) void function() Func;\n\n    Func fp = (){};\n\n    fp = (){};\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8575\n\ntemplate tfunc8575(func...)\n{\n    auto tfunc8575(U)(U u) { return func[0](u); }\n}\nauto bar8575(T)(T t)\n{\n    return tfunc8575!(a => a)(t);\n}\nvoid foo8575a() { assert(bar8575(uint.init + 1) == +1); }\nvoid foo8575b() { assert(bar8575( int.init - 1) == -1); }\n\nvoid test8575()\n{\n    foo8575a();\n    foo8575b();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9153\n\nvoid writeln9153(string s){}\n\nvoid test9153()\n{\n    auto tbl1 = [\n        (string x) { writeln9153(x); },\n        (string x) { x ~= 'a'; },\n    ];\n    auto tbl2 = [\n        (string x) { x ~= 'a'; },\n        (string x) { writeln9153(x); },\n    ];\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9393\n\ntemplate ifThrown9393a(E)\n{\n    void ifThrown9393a(T)(scope T delegate(E) errHandler)\n    {\n    }\n}\nvoid ifThrown9393b(E, T)(scope T delegate(E) errHandler)\n{\n}\n\nvoid foo9393(T)(void delegate(T) dg){ dg(T.init); }\nvoid foo9393()(void delegate(int) dg){ foo9393!int(dg); }\n\nvoid test9393()\n{\n    ifThrown9393a!Exception(e => 10);\n    ifThrown9393b!Exception(e => 10);\n\n    foo9393((x){ assert(x == int.init); });\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9415\n\nvoid test9415()\n{\n    int z;\n    typeof((int a){return z;}) dg;\n    dg = (int a){return z;};\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9628\n\ntemplate TypeTuple9628(TL...) { alias TypeTuple9628 = TL; }\nvoid map9628(alias func)() { func(0); }\n\nvoid test9628()\n{\n    auto items = [[10, 20], [30]];\n    size_t[] res;\n\n    res = null;\n    foreach (_; 0 .. 2)\n    {\n        foreach (sub; items)\n        {\n            map9628!((       i){ res ~= sub.length; });\n            map9628!((size_t i){ res ~= sub.length; });\n        }\n    }\n    assert(res == [2,2,1,1, 2,2,1,1]);\n\n    res = null;\n    foreach (_; TypeTuple9628!(0, 1))\n    {\n        foreach (sub; items)\n        {\n            map9628!((       i){ res ~= sub.length; });\n            map9628!((size_t i){ res ~= sub.length; });\n        }\n    }\n    assert(res == [2,2,1,1, 2,2,1,1]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9928\n\nvoid test9928()\n{\n    void* smth = (int x) { return x; };\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10133\n\nptrdiff_t countUntil10133(alias pred, R)(R haystack)\n{\n    typeof(return) i;\n\n    alias T = dchar;\n\n    foreach (T elem; haystack)\n    {\n        if (pred(elem)) return i;\n        ++i;\n    }\n\n    return -1;\n}\n\nbool func10133(string s)() if (countUntil10133!(x => x == 'x')(s) == 1)\n{\n    return true;\n}\n\nbool func10133a(string s)() if (countUntil10133!(x => s == \"x\")(s) != -1)\n{\n    return true;\n}\nbool func10133b(string s)() if (countUntil10133!(x => s == \"x\")(s) != -1)\n{\n    return true;\n}\n\nvoid test10133()\n{\n    func10133!(\"ax\")();\n\n    func10133a!(\"x\")();\n    static assert(!is(typeof(func10133a!(\"ax\")())));\n    static assert(!is(typeof(func10133b!(\"ax\")())));\n    func10133b!(\"x\")();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10219\n\nvoid test10219()\n{\n    interface I { }\n    class C : I { }\n\n    void test_dg(I delegate(C) dg)\n    {\n        C c = new C;\n        void* cptr = cast(void*) c;\n        void* iptr = cast(void*) cast(I) c;\n        void* xptr = cast(void*) dg(c);\n        assert(cptr != iptr);\n        assert(cptr != xptr); // should pass\n        assert(iptr == xptr); // should pass\n    }\n\n    C delegate(C c) dg = delegate C(C c) { return c; };\n    static assert(!__traits(compiles, { test_dg(dg); }));\n    static assert(!__traits(compiles, { test_dg(delegate C(C c) { return c; }); }));\n    static assert(!__traits(compiles, { I delegate(C) dg2 = dg; }));\n\n    // creates I delegate(C)\n    test_dg(c => c);\n    test_dg(delegate(C c) => c);\n\n    void test_fp(I function(C) fp)\n    {\n        C c = new C;\n        void* cptr = cast(void*) c;\n        void* iptr = cast(void*) cast(I) c;\n        void* xptr = cast(void*) fp(c);\n        assert(cptr != iptr);\n        assert(cptr != xptr); // should pass\n        assert(iptr == xptr); // should pass\n    }\n\n    C function(C c) fp = function C(C c) { return c; };\n    static assert(!__traits(compiles, { test_fp(fp); }));\n    static assert(!__traits(compiles, { test_fp(function C(C c) { return c; }); }));\n    static assert(!__traits(compiles, { I function(C) fp2 = fp; }));\n\n    // creates I function(C)\n    test_fp(c => c);\n    test_fp(function(C c) => c);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10288\n\nT foo10288(T)(T x)\n{\n    void lambda() @trusted nothrow { x += 10; }\n    lambda();\n    return x;\n}\n\nT bar10288(T)(T x)\n{\n    () @trusted { x += 10; } ();\n    return x;\n}\n\nT baz10288(T)(T arg)\n{\n    static int g = 10;\n    () @trusted { x += g; } ();\n    return x;\n}\n\nvoid test10288() @safe pure nothrow\n{\n    assert(foo10288(10) == 20); // OK\n    assert(bar10288(10) == 20); // OK <- NG\n    static assert(!__traits(compiles, baz10288(10)));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10666\n\nstruct S10666\n{\n    int val;\n    ~this() {}\n}\n\nvoid foo10666(S10666 s1)\n{\n    S10666 s2;\n\n    /* Even if closureVars(s1 and s2) are accessed by directly called lambdas,\n     * they won't escape the scope of this function.\n     */\n    auto x1 = (){ return s1.val; }();   // OK\n    auto x2 = (){ return s2.val; }();   // OK\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11081\n\nT ifThrown11081(E : Throwable, T)(T delegate(E) errorHandler)\n{\n    return errorHandler();\n}\n\nvoid test11081()\n{\n    static if (__traits(compiles, ifThrown11081!Exception(e => 0)))\n    {\n    }\n    static if (__traits(compiles, ifThrown11081!Exception(e => 0)))\n    {\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11220\n\nint parsePrimaryExp11220(int x)\n{\n    parseAmbig11220!( (parsed){ x += 1; } )();\n    return 1;\n}\n\ntypeof(handler(1)) parseAmbig11220(alias handler)()\n{\n    return handler(parsePrimaryExp11220(1));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11230\n\ntemplate map11230(fun...)\n{\n    auto map11230(Range)(Range r)\n    {\n        return MapResult11230!(fun, Range)(r);\n    }\n}\n\nstruct MapResult11230(alias fun, R)\n{\n    R _input;\n    this(R input) { _input = input; }\n}\n\nclass A11230 { A11230[] as; }\nclass B11230 { A11230[] as; }\nclass C11230 : A11230 {}\n\nC11230 visit11230(A11230 a)\n{\n    a.as.map11230!(a => visit11230);\n    return null;\n}\nC11230 visit11230(B11230 b)\n{\n    b.as.map11230!(a => visit11230);\n    return null;\n}\nC11230 visit11230()\n{\n    return null;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10336\n\nstruct S10336\n{\n    template opDispatch(string name)\n    {\n        enum opDispatch = function(int x) {\n            return x;\n        };\n    }\n}\n\nvoid test10336()\n{\n    S10336 s;\n    assert(s.hello(12) == 12);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10928\n\nstruct D10928\n{\n    int x;\n    ~this() @nogc {}\n}\n\nvoid f10928a(D10928 bar)\n{\n    (){ bar.x++; }();\n}\nvoid f10928b(D10928 bar) @nogc\n{\n    (){ bar.x++; }();\n}\n\nvoid test10928()\n{\n    f10928a(D10928.init);\n    f10928b(D10928.init);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11661\n\nvoid test11661()\n{\n    void delegate() dg = {};  // OK\n    void function() fp = {};  // OK <- NG\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11774\n\nvoid f11774(T, R)(R delegate(T[]) dg)\n{\n    T[] src;\n    dg(src);\n}\n\nvoid test11774()\n{\n    int[] delegate(int[]) dg = (int[] a) => a;\n    f11774!int(dg);\n    f11774!Object(a => a);\n    f11774!int(dg);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12421\n\nvoid test12421()\n{\n    void test(string decl, bool polymorphic = true)()\n    {\n        // parse AliasDeclaration in Statement\n        mixin(\"alias f = \" ~ decl ~ \";\");\n        assert(f(1) == 1);\n      static if (polymorphic)\n        assert(f(\"s\") == \"s\");\n\n        // parse AliasDeclaration in DeclDefs\n        mixin(\"template X() { alias g = \" ~ decl ~ \"; }\");\n        alias g = X!().g;\n        assert(g(1) == 1);\n      static if (polymorphic)\n        assert(g(\"s\") == \"s\");\n    }\n\n    test!(q{      x  => x });\n    test!(q{ (    x) => x });\n    test!(q{ (int x) => x }, false);\n\n    test!(q{ (    x){ return x; } });\n    test!(q{ (int x){ return x; } }, false);\n\n    test!(q{ function     (    x) => x });\n    test!(q{ function     (int x) => x }, false);\n    test!(q{ function int (    x) => x }, false);\n    test!(q{ function int (int x) => x }, false);\n\n    test!(q{ delegate     (    x) => x });\n    test!(q{ delegate     (int x) => x }, false);\n    test!(q{ delegate int (    x) => x }, false);\n    test!(q{ delegate int (int x) => x }, false);\n\n    test!(q{ function     (    x){ return x; } });\n    test!(q{ function     (int x){ return x; } }, false);\n    test!(q{ function int (    x){ return x; } }, false);\n    test!(q{ function int (int x){ return x; } }, false);\n\n    test!(q{ delegate     (    x){ return x; } });\n    test!(q{ delegate     (int x){ return x; } }, false);\n    test!(q{ delegate int (    x){ return x; } }, false);\n    test!(q{ delegate int (int x){ return x; } }, false);\n\n    // This is problematic case, and should be disallowed in the future.\n    alias f = x => y;\n    int y = 10;\n    assert(f(1) == 10);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12508\n\ninterface A12508(T)\n{\n    T getT();\n}\n\nclass C12508 : A12508!double\n{\n    double getT() { return 1; }\n}\n\nvoid f12508(A12508!double delegate() dg)\n{\n    auto a = dg();\n    assert(a !is null);\n    assert(a.getT() == 1.0);    // fails!\n}\n\nvoid t12508(T)(A12508!T delegate() dg)\n{\n    auto a = dg();\n    assert(a !is null);\n    assert(a.getT() == 1.0);    // fails!\n}\n\nref alias Dg12508 = A12508!double delegate();\nvoid t12508(T)(Dg12508 dg) {}\n\nvoid test12508()\n{\n    f12508({ return new C12508(); });\n    t12508({ return new C12508(); });\n    static assert(!__traits(compiles, x12508({ return new C12508(); })));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13879\n\nvoid test13879()\n{\n    bool function(int)[2] funcs1 = (int x) => true; // OK\n    assert(funcs1[0] is funcs1[1]);\n    funcs1[0] = x => true;                          // OK\n    bool function(int)[2] funcs2 = x => true;       // OK <- Error\n    assert(funcs2[0] is funcs2[1]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14745\n\nvoid test14745()\n{\n    // qualified nested functions\n    auto foo1() pure immutable { return 0; }\n    auto foo2() pure const { return 0; }\n\n    // qualified lambdas (== implicitly marked as delegate literals)\n    auto lambda1 = () pure immutable { return 0; };\n    auto lambda2 = () pure const { return 0; };\n    static assert(is(typeof(lambda1) : typeof(&foo1)));\n    static assert(is(typeof(lambda2) : typeof(&foo2)));\n\n    // qualified delegate literals\n    auto dg1 = delegate () pure immutable { return 0; };\n    auto dg2 = delegate () pure const { return 0; };\n    static assert(is(typeof(dg1) : typeof(&foo1)));\n    static assert(is(typeof(dg2) : typeof(&foo2)));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15794\n\nstruct Foo15794\n{\n    static void fun(Holder)()\n    {\n        int i = Holder.fn();\n    }\n}\n\nstruct Holder15794(alias Fn)\n{\n    alias fn = Fn;\n}\n\nvoid gun15794(alias fn, U...)()\n{\n    Foo15794.fun!(Holder15794!fn)();\n}\n\nvoid test15794()\n{\n    gun15794!(() => 0)(); // Line 26\n}\n\n/***************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test4v();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test3235();\n    test6714();\n    test7193();\n    test7202();\n    test7288();\n    test7499();\n    test7500();\n    test7525();\n    test7582();\n    test7649();\n    test7650();\n    test7705();\n    test7713();\n    test7743();\n    test7761();\n    test7941();\n    test8005();\n    test8198();\n    test8226();\n    test8241();\n    test8242();\n    test8315();\n    test8397();\n    test8496();\n    test8575();\n    test9153();\n    test9393();\n    test9415();\n    test9628();\n    test9928();\n    test10133();\n    test10219();\n    test10288();\n    test10336();\n    test10928();\n    test11661();\n    test11774();\n    test12421();\n    test12508();\n    test13879();\n    test14745();\n    test15794();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/functype.d",
    "content": "extern(C) int printf(const char*, ...);\n\n/***************************************************/\n\nvoid testfp()\n{\n    static int func1(int n = 1) { return n; }\n    static int func2(int n    ) { return n; }\n    static assert(typeof(func1).stringof == \"pure nothrow @nogc @safe int(int n = 1)\");\n    static assert(typeof(func2).stringof == \"pure nothrow @nogc @safe int(int n)\");\n    static assert( is(typeof(func1())));     // OK\n    static assert(!is(typeof(func2())));     // NG\n\n    alias typeof(func1) Func1;\n    alias typeof(func2) Func2;\n    static assert(is(Func1 == Func2));\n    static assert(Func1.stringof == \"pure nothrow @nogc @safe int(int n = 1)\");\n    static assert(Func2.stringof == \"pure nothrow @nogc @safe int(int n)\");\n\n    auto fp1 = &func1;\n    auto fp2 = &func2;\n    static assert(typeof(fp1).stringof == \"int function(int n = 1) pure nothrow @nogc @safe\");\n    static assert(typeof(fp2).stringof == \"int function(int n) pure nothrow @nogc @safe\");\n    static assert( is(typeof(fp1())));     // OK\n    static assert(!is(typeof(fp2())));     // NG\n\n    alias typeof(fp1) Fp1;\n    alias typeof(fp2) Fp2;\n    static assert(is(Fp1 == Fp2));\n    static assert(Fp1.stringof == \"int function(int n = 1) pure nothrow @nogc @safe\");\n    static assert(Fp2.stringof == \"int function(int n) pure nothrow @nogc @safe\");\n\n    typeof(fp1) fp3 = fp1;\n    typeof(fp2) fp4 = fp2;\n    static assert(is(typeof(fp3) == typeof(fp4)));\n    static assert(typeof(fp3).stringof == \"int function(int n = 1) pure nothrow @nogc @safe\");\n    static assert(typeof(fp4).stringof == \"int function(int n) pure nothrow @nogc @safe\");\n    static assert( is(typeof(fp3())));     // OK\n    static assert(!is(typeof(fp4())));     // NG\n\n    alias typeof(fp3) Fp3;\n    alias typeof(fp4) Fp4;\n    static assert(is(Fp3 == Fp4));\n    static assert(Fp3.stringof == \"int function(int n = 1) pure nothrow @nogc @safe\");\n    static assert(Fp4.stringof == \"int function(int n) pure nothrow @nogc @safe\");\n\n    auto fplit1 = function(int n = 1) { return n; };\n    auto fplit2 = function(int n    ) { return n; };\n    static assert( is(typeof(fplit1())));   // OK\n    static assert(!is(typeof(fplit2())));   // NG\n}\n\nvoid testdg()\n{\n    int nest1(int n = 1) { return n; }\n    int nest2(int n    ) { return n; }\n    static assert(typeof(nest1).stringof == \"pure nothrow @nogc @safe int(int n = 1)\");\n    static assert(typeof(nest2).stringof == \"pure nothrow @nogc @safe int(int n)\");\n    static assert( is(typeof(nest1())));     // OK\n    static assert(!is(typeof(nest2())));     // NG\n\n    alias typeof(nest1) Nest1;\n    alias typeof(nest2) Nest2;\n    static assert(is(Nest1 == Nest2));\n    static assert(Nest1.stringof == \"pure nothrow @nogc @safe int(int n = 1)\");\n    static assert(Nest2.stringof == \"pure nothrow @nogc @safe int(int n)\");\n\n    auto dg1 = &nest1;\n    auto dg2 = &nest2;\n    static assert(typeof(dg1).stringof == \"int delegate(int n = 1) pure nothrow @nogc @safe\");\n    static assert(typeof(dg2).stringof == \"int delegate(int n) pure nothrow @nogc @safe\");\n    static assert( is(typeof(dg1())));     // OK\n    static assert(!is(typeof(dg2())));     // NG\n\n    alias typeof(dg1) Dg1;\n    alias typeof(dg2) Dg2;\n    static assert(is(Dg1 == Dg2));\n    static assert(Dg1.stringof == \"int delegate(int n = 1) pure nothrow @nogc @safe\");\n    static assert(Dg2.stringof == \"int delegate(int n) pure nothrow @nogc @safe\");\n\n    typeof(dg1) dg3 = dg1;\n    typeof(dg2) dg4 = dg2;\n    static assert(typeof(dg3).stringof == \"int delegate(int n = 1) pure nothrow @nogc @safe\");\n    static assert(typeof(dg4).stringof == \"int delegate(int n) pure nothrow @nogc @safe\");\n    static assert( is(typeof(dg3())));     // OK\n    static assert(!is(typeof(dg4())));     // NG\n\n    alias typeof(dg3) Dg3;\n    alias typeof(dg4) Dg4;\n    static assert(is(Dg3 == Dg4));\n    static assert(Dg3.stringof == \"int delegate(int n = 1) pure nothrow @nogc @safe\");\n    static assert(Dg4.stringof == \"int delegate(int n) pure nothrow @nogc @safe\");\n\n    auto dglit1 = delegate(int n = 1) { return n; };\n    auto dglit2 = delegate(int n    ) { return n; };\n    static assert( is(typeof(dglit1())));   // OK\n    static assert(!is(typeof(dglit2())));   // NG\n}\n\nvoid testda()\n{\n    // Unsupported cases with current implementation.\n\n    int function(int n = 1)[] fpda = [n => n + 1, n => n+2];\n    assert(fpda[0](1) == 2);\n    assert(fpda[1](1) == 3);\n    static assert(!is(typeof(fpda[0]() == 1)));     // cannot call with using defArgs\n    static assert(!is(typeof(fpda[1]() == 2)));     // cannot call with using defArgs\n    static assert(typeof(fpda).stringof == \"int function(int)[]\");\n    static assert(typeof(fpda).stringof != \"int function(int n = 1)[]\");\n\n    int delegate(int n = 1)[] dgda = [n => n + 1, n => n+2];\n    assert(dgda[0](1) == 2);\n    assert(dgda[1](1) == 3);\n    static assert(!is(typeof(dgda[0]() == 1)));     // cannot call with using defArgs\n    static assert(!is(typeof(dgda[1]() == 2)));     // cannot call with using defArgs\n    static assert(typeof(dgda).stringof == \"int delegate(int)[]\");\n    static assert(typeof(fpda).stringof != \"int delegate(int n = 1)[]\");\n}\n\ntemplate StringOf(T)\n{\n    // template type parameter cannot have redundant information\n    enum StringOf = T.stringof;\n}\n\nvoid testti()\n{\n    int[] test(int[] a = []) { return a; }\n    static assert(typeof(test).stringof == \"pure nothrow @nogc @safe int[](int[] a = [])\");\n    static assert(StringOf!(typeof(test)) == \"pure nothrow @nogc @safe int[](int[])\");\n\n    float function(float x = 0F) fp = x => x;\n    static assert(typeof(fp).stringof == \"float function(float x = \" ~ (0F).stringof ~ \")\");\n    static assert(StringOf!(typeof(fp)) == \"float function(float)\");\n\n    double delegate(double x = 0.0) dg = x => x;\n    static assert(typeof(dg).stringof == \"double delegate(double x = \" ~ (0.0).stringof ~ \")\");\n    static assert(StringOf!(typeof(dg)) == \"double delegate(double)\");\n\n    template F(T) {}\n    auto fp1 = (int a = 1) {};\n    auto fp2 = (int b = 2) {};\n    static assert(typeof(fp1).stringof != typeof(fp2).stringof);\n    alias F1 = F!(typeof(fp1));\n    alias F2 = F!(typeof(fp2));\n    static assert(__traits(isSame, F1, F2));\n    static assert(F1.mangleof == F2.mangleof);\n}\n\nvoid testxx()\n{\n    // The corner cases which I had introduced in forum discussion\n\n    // f will inherit default args from its initializer, if it's declared with 'auto'\n    auto f1 = (int n = 10){ return 10; };\n    assert(f1() == 10);\n\n    // what is the actual default arg of f?\n    int function(int n = 10) f2 = (int n = 20){ return n; };\n    int function(int n     ) f3 = (int n = 30){ return n; };\n    int function(int n = 40) f4 = (int n     ){ return n; };\n    assert(f2() == 10);\n    static assert(!is(typeof(f3())));\n    assert(f4() == 40);\n\n    // conditional expression and the type of its result\n    auto f5 = true ? (int n = 10){ return n; }\n                   : (int n = 20){ return n; } ;\n    auto f6 = true ? (int n = 10, string s = \"hello\"){ return n; }\n                   : (int n = 10, string s = \"world\"){ return n; } ;\n    static assert(!is(typeof(f5())));   // cannot call\n    static assert(!is(typeof(f6())));   // cannot call\n\n    int function(int n = 10) f7;    // default arg of the first parameter is 10\n    f7 = (int n = 20){ return n; }; // function literal's default arg will be ignored\n    assert(f7() == 10);\n\n    // returning function pointer/delegate type can have default args\n    int delegate(int n = 10) foo(int x) { return n => n + x; }\n    auto f = foo(1);\n    assert(f() == 11);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3646\n\nint bar3646(int x = 10) { printf(\"bar %d\\n\", x); return x; }\nint bam3646(int y)      { printf(\"bam %d\\n\", y); return y; }\n\nint qux3646()      { printf(\"quux\\n\");       return 20; }\nint qux3646(int i) { printf(\"quux %d\\n\", i); return 30; }\n\nvoid foo3646a(Fn)(Fn fn)\n{\n    fn();\n}\n\nvoid foo3646b(alias fn)(int res1, int res2)\n{\n    assert(fn() == res1);\n    assert(fn(42) == res2);\n}\n\nvoid test3646()\n{\n    static assert(!is(typeof(foo3646(&bar3646))));\n    static assert(!is(typeof(foo3646(&bam3646))));\n    static assert(typeof(&bar3646).stringof == \"int function(int x = 10)\");\n    static assert(typeof(&bam3646).stringof == \"int function(int y)\");\n\n    foo3646b!bar3646(10, 42);\n    static assert(!is(typeof(foo3646b!bam3646(0, 0))));\n    foo3646b!qux3646(20, 30);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3866\n\nvoid test3866()\n{\n\n    auto foo = (int a = 1) { return a; };\n    auto bar = (int a) { return a; };\n\n    assert(foo() == 1);\n    static assert(!is(typeof(bar())));\n    assert(foo(2) == 2);\n    assert(bar(3) == 3);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8579\n\nvoid test8579()\n{\n    static void func1(int i, double j = 1.0) {}\n    static void func2(int x, double y) {}\n    auto fn1 = &func1;\n    auto fn2 = &func2;\n    static assert(is(typeof(fn1) == typeof(fn2)));\n           assert(   typeid(fn1) is typeid(fn2) );\n    static assert(typeof(fn1).stringof == \"void function(int i, double j = \" ~ (1.0).stringof ~ \") pure nothrow @nogc @safe\");\n    static assert(typeof(fn2).stringof == \"void function(int x, double y) pure nothrow @nogc @safe\");\n\n    static int func3(int x, double y) { return 0; }\n    static int func4(int i, double j = 1.0) { return 0; }\n    auto fn3 = &func3;\n    auto fn4 = &func4;\n    static assert(is(typeof(fn3) == typeof(fn4)));\n           assert(   typeid(fn3) is typeid(fn4) );\n    static assert(typeof(fn3).stringof == \"int function(int x, double y) pure nothrow @nogc @safe\");\n    static assert(typeof(fn4).stringof == \"int function(int i, double j = \" ~ (1.0).stringof ~ \") pure nothrow @nogc @safe\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14210\n\nstring foo14210a(DT)(string name, DT dg)\n{\n    return name ~ \" :: \" ~ typeof(dg).stringof;\n}\nstring foo14210b(DT)(string name, DT dg)\n{\n    return name ~ \" :: \" ~ typeof(dg).stringof;\n}\nvoid test14210()\n{\n    assert(foo14210a(\"1\", (int a)    => a+0) == \"1 :: int function(int) pure nothrow @nogc @safe\");\n    assert(foo14210a(\"2\", (int a=40) => a+2) == \"2 :: int function(int) pure nothrow @nogc @safe\");\n\n    assert(foo14210b(\"2\", (int a=40) => a+2) == \"2 :: int function(int) pure nothrow @nogc @safe\");\n    assert(foo14210b(\"1\", (int a)    => a+0) == \"1 :: int function(int) pure nothrow @nogc @safe\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10734\n\n// There's no platform independent export symbol, so\n// test just only in Win32.\nversion(Win32)\n{\n\nextern(Windows)\n{\n    // use a symbol from kernel32.lib, not user32.lib. The latter might not\n    //  be passed automatically on the command line\n    export void* GetModuleHandleA(const(char)*moduleName);\n    alias void* function(const(char)*moduleName) PROC;\n}\n\nvoid test10734()\n{\n    PROC lpfnProc = &GetModuleHandleA;\n}\n\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14656\n\nvoid test14656()\n{\n    //void unaryFun()(auto int a) pure nothrow @safe @nogc {}   // changed to invalid by fixing issue 14669\n    alias Identity(F) = F;\n    //unaryFun!()(41);\n    static void fun(int n) pure nothrow @safe @nogc {}\n    alias F = typeof(fun);\n    assert(Identity!F.stringof == \"pure nothrow @nogc @safe void(int)\");\n}\n\nvoid test14656_ref()\n{\n    void unaryFun()(auto ref int a) pure nothrow @safe @nogc {}\n    alias Identity(F) = F;\n    unaryFun!()(41);\n    static void fun(int n) pure nothrow @safe @nogc {}\n    alias F = typeof(fun);\n    assert(Identity!F.stringof == \"pure nothrow @nogc @safe void(int)\");\n}\n\n/***************************************************/\n\nint main()\n{\n    testfp();\n    testdg();\n    testda();\n    testti();\n    testxx();\n    test3646();\n    test3866();\n    test8579();\n    test14210();\n    test14656();\n    test14656_ref();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/future.d",
    "content": "/* PERMUTE_ARGS:\n */\n\nclass A\n{\n    @__future char msg() { return 'a'; }\n}\n\nclass B : A\n{\n    char msg() { return 'b'; }\n}\n\nclass C : B\n{\n    override char msg() { return 'c'; }\n}\n\nclass D : A\n{\n    override char msg() { return 'd'; }\n}\n\nint main()\n{\n    auto a = new A();\n    assert(a.msg() == 'a');\n    auto b = new B();\n    assert(b.msg() == 'b');\n    auto c = new C();\n    assert(c.msg() == 'c');\n    auto d = new D();\n    assert(d.msg() == 'd');\n\n    assert(b.A.msg() == 'a');\n\n    auto ba = cast(A)b;\n    assert(ba.msg() == 'a');\n\n    auto da = cast(A)d;\n    assert(da.msg() == 'd');\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/hello.d",
    "content": "// PERMUTE_ARGS:\n\nextern(C) int printf(const char*, ...);\n\nint main(char[][] args)\n{\n    printf(\"hello world\\n\");\n    printf(\"args.length = %d\\n\", args.length);\n    for (int i = 0; i < args.length; i++)\n        printf(\"args[%d] = '%.*s'\\n\", i, args[i].length, args[i].ptr);\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/helloUTF8.d",
    "content": "﻿// PERMUTE_ARGS:\n\nextern(C) int printf(const char *, ...);\n\nint main(char[][] args)\n{\n    printf(\"hello world\\n\");\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/hospital.d",
    "content": "// REQUIRED_ARGS:\n\n// NOTE: the shootout appears to be BSD licensed content.\n// Including this in the test suite based on that license.\n\n/* The Great Computer Language Shootout\n   http://shootout.alioth.debian.org/\n\n   Unoptimised reference implementation\n\n   contributed by Isaac Gouy\n*/\n\nimport std.stdio, std.string, std.conv;\nimport core.memory;\n\nint main(string[] args)\n{\n    //std.gc.setV1_0();\n    int n = args.length > 1 ? to!int(args[1]) : 1000;\n\n    HealthcareRegion healthcareSystem = HealthcareRegion.Create();\n\n    for(int i = 0; i < n; i++)\n        healthcareSystem.TransferPatients();\n\n    Totals t = healthcareSystem.AccumulateTotals();\n\n    writeln(\"Patients: \", t.patients );\n    writeln(\"Time:     \", t.hospitalTime );\n    writeln(\"Visits:   \", t.hospitalVisits );\n\n    if (n == 1000)\n    {\n        assert(t.patients == 102515);\n        assert(t.hospitalTime == 33730654);\n        assert(t.hospitalVisits == 106371);\n    }\n    return 0;\n}\n\nclass HealthcareRegion\n{\npublic:\n    static HealthcareRegion Create()\n    {\n        return HealthcareRegion.Create(LEVELS, 0, 42);\n    }\n\n    static HealthcareRegion Create(int level, int seed1, int seed2)\n    {\n        HealthcareRegion r = null;\n\n        if(level > 0)\n        {\n            r = new HealthcareRegion(level, seed1*seed2);\n            for(ptrdiff_t i = r.districts.length-1; i >= 0; i--)\n                r.districts[i] = Create(level-1, cast(int)((seed1*4)+i+1), seed2);\n        }\n        return r;\n    }\n\n    this(int level, int s)\n    {\n        districts = new HealthcareRegion[DISTRICTS];\n        localHospital = new Hospital(level == LEVELS, level, s);\n    }\n\nprivate:\n    enum int LEVELS = 5, DISTRICTS = 4;\n    HealthcareRegion[] districts;\n    Hospital localHospital;\n\npackage:\n    Patient[] TransferPatients()\n    {\n        for(ptrdiff_t i = districts.length-1; i >= 0; i--)\n            if(districts[i])\n                foreach(Patient p; districts[i].TransferPatients().dup)\n                    localHospital.NewArrival(p);\n\n        localHospital.TriageExaminationTreatment();\n\n        return localHospital.RegionalTransferPatients();\n    }\n\n    Totals AccumulateTotals()\n    {\n        Totals t = new Totals();\n        for(ptrdiff_t i = districts.length-1; i >= 0; i--)\n            if(districts[i])\n                t += districts[i].AccumulateTotals();\n\n        localHospital.AccumulateTotals(t);\n\n        return t;\n    }\n}\n\nclass Hospital\n{\n    public this(bool hasNoRegionalHospital, int level, int seed)\n    {\n        this.hasNoRegionalHospital = hasNoRegionalHospital;\n        availableStaff = 1 << (level - 1);\n        discharged = new Totals();\n        this.seed = seed;\n    }\n\npackage:\n    void TriageExaminationTreatment()\n    {\n        DischargePatients();\n        TreatOrTransferPatients();\n        TriagePatients();\n\n        if(genRandom(1.0) > 0.7)\n        {   Patient p = new Patient();\n            NewArrival(p);\n        }\n    }\n\n    Patient[] RegionalTransferPatients()\n    {\n        return transfers;\n    }\n\n    void AccumulateTotals(Totals t)\n    {\n        foreach(Patient p; triage) t.Plus(p);\n        foreach(Patient p; examination) t.Plus(p);\n        foreach(Patient p; treatment) t.Plus(p);\n        t += discharged;\n    }\n\n    void NewArrival(Patient p)\n    {\n        p.hospitalVisits++;\n        if(availableStaff > 0)\n        {\n            availableStaff--;\n            examination ~= p;\n            p.remainingTime = 3;\n            p.hospitalTime += 3;\n        } else {\n            triage ~= p;\n        }\n    }\n\nprivate:\n    Patient[] triage, examination, treatment, transfers;\n    Totals discharged;\n    int availableStaff;\n    bool hasNoRegionalHospital;\n\n    void DischargePatients()\n    {\n        for(ptrdiff_t i = treatment.length-1; i >= 0; i--)\n        {\n            Patient p = treatment[i];\n            p.remainingTime -= 1;\n            if(!p.remainingTime)\n            {\n                availableStaff++;\n                treatment = treatment[0..i] ~ treatment[i+1..$];\n                discharged.Plus(p);\n            }\n        }\n    }\n\n    void TreatOrTransferPatients()\n    {\n        delete transfers;\n\n        for(ptrdiff_t i = examination.length-1; i >= 0; i--)\n        {\n            Patient p = examination[i];\n            p.remainingTime -= 1;\n\n            if(!p.remainingTime)\n            {\n                // no transfer\n                if(genRandom(1.0) > 0.1 || hasNoRegionalHospital)\n                {\n                    examination = examination[0..i] ~ examination[i+1..$];\n                    treatment ~= p;\n                    p.remainingTime = 10;\n                    p.hospitalTime += 10;\n                } else {\n                // transfer\n                    availableStaff++;\n                    examination = examination[0..i] ~ examination[i+1..$];\n                    transfers ~= p;\n                }\n            }\n        }\n    }\n\n    void TriagePatients()\n    {\n        for(ptrdiff_t i = triage.length-1; i >= 0; i--)\n        {\n            Patient p = triage[i];\n            if(availableStaff > 0)\n            {\n                availableStaff--;\n                p.remainingTime = 3;\n                p.hospitalTime += 3;\n                triage = triage[0..i] ~ triage[i+1..$];\n                examination ~= p;\n            } else {\n                p.hospitalTime++;\n            }\n        }\n    }\n\n    int seed = 42;\n    const int IM = 139968;\n    const int IA = 3877;\n    const int IC = 29573;\n    double genRandom(double max)\n    {\n        return(max * (seed = (seed * IA + IC) % IM) / IM);\n    }\n}\n\nclass Patient\n{\n    package int remainingTime, hospitalTime, hospitalVisits;\n}\n\nclass Totals\n{\n    public Totals opAddAssign(Totals b)\n    {\n        patients += b.patients;\n        hospitalTime += b.hospitalTime;\n        hospitalVisits += b.hospitalVisits;\n        return this;\n    }\n\npackage:\n    long patients, hospitalTime, hospitalVisits;\n\n    void Plus(Patient p)\n    {\n        patients++;\n        hospitalTime += p.hospitalTime;\n        hospitalVisits += p.hospitalVisits;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ice10086a.d",
    "content": "// EXTRA_SOURCES: imports/ice10086x.d imports/ice10086y.d\n\nimport imports.ice10086x;\nimport imports.ice10086y;\n\nvoid main() { test(); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ice10086b.d",
    "content": "// EXTRA_SOURCES: imports/ice10086y.d imports/ice10086x.d\n\nimport imports.ice10086y;\nimport imports.ice10086x;\n\nvoid main() { test(); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ice10857.d",
    "content": "// EXTRA_SOURCES: imports/ice10857a.d imports/ice10857b.d\n\nimport imports.ice10857a;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ice15030.d",
    "content": "// REQUIRED_ARGS: -unittest -boundscheck=off\n// PERMUTE_ARGS:\n// EXTRA_SOURCES: imports/a15030.d imports/b15030.d\n\nvoid main() {}\n\n/+\nCompiler output with -v switch.\n\nWith 2.068.0:\n--------\ncode      a\ncode      b\nfunction  b.__unittestL5_2\nfunction  b.__unittestL5_2.__lambda1\nfunction  b.__unittestL5_2.__lambda1.__lambda2\nfunction  b.__unittestL5_2.__lambda1.__lambda2.filter!((a) => a).filter!(int[]).filter\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.this\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.empty\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.front\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.popFront\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.__xopEquals\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.__xtoHash\nfunction  b.__unittestL5_2.__lambda1.__lambda2.__lambda2\n\nThe nested functions '__lambda1', '__lambda2', and 'filter' are\n(fortunately) generated from outer to inner.\n\n\nWith 2.068.1:\n--------\ncode      a\nfunction  b.__unittestL5_2.__lambda1.__lambda2.filter!((a) => a).filter!(int[]).filter\nfunction  b.__unittestL5_2.__lambda1.__lambda2\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.this\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.empty\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.front\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.popFront\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.__xopEquals\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.__xtoHash\ncode      b\nfunction  b.__unittestL5_2\nfunction  b.__unittestL5_2.__lambda1\nAssertion failure: '!v->csym' on line 1060 in file 'glue.c'\n\nabnormal program termination\n\n'filer' is generated before its ancestor functions '__lambda1' and '__lambda2' - it's a bug.\n\n\nFixed (contains debug prints):\n--------\ncode      a\nb.__unittestL5_2.__lambda1.__lambda2.filter!((a) => a).filter!(int[]).filter @[algorithm.d(5)]\n    --> pushed to unittest @[b.d(5)]\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.this\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.empty\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.front\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.popFront\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.__xopEquals\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.__xtoHash\ncode      b\nfunction  b.__unittestL5_2\nfunction  b.__unittestL5_2.__lambda1\nfunction  b.__unittestL5_2.__lambda1.__lambda2\nfunction  b.__unittestL5_2.__lambda1.__lambda2.filter!((a) => a).filter!(int[]).filter\nfunction  b.__unittestL5_2.__lambda1.__lambda2.__lambda2\n\nBy using `deferredNested` correctly, those nested function generations are ordered again.\n\n\nFixed more:\n--------\nfunction  D main\ncode      a\ncode      b\nfunction  b.__unittestL5_2\nfunction  b.__unittestL5_2.__lambda1\nfunction  b.__unittestL5_2.__lambda1.__lambda2\nfunction  b.__unittestL5_2.__lambda1.__lambda2.filter!(int[]).filter\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.this\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.empty\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.front\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.popFront\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.__xopEquals\nfunction  b.__unittestL5_2.__lambda1.__lambda2.FilterResult!(__lambda2, int[]).FilterResult.__xtoHash\nfunction  b.__unittestL5_2.__lambda1.__lambda2.__lambda2\n\nBy the tweak in TemplateInstance::appendToModuleMember(), all the code of\n(implicitly) nested instances are stored into corresponding module object file.\n\n+/\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ice15138.d",
    "content": "// EXTRA_SOURCES: imports/ice15138a.d\n// PERMUTE_ARGS: -unittest -inline\n// COMPILE_SEPARATELY\n\nimport imports.ice15138a;\n\nvoid main()\n{\n    JSONValue v;\n    v.get!JSONValue;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ice15176.d",
    "content": "// EXTRA_SOURCES: imports/ice15176a.d imports/ice15176b.d\n// COMPILE_SEPARATELY\n\nimport imports.ice15176a;\n\nvoid main()\n{\n    func();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ice15200.d",
    "content": "// EXTRA_SOURCES: imports/ice15200a.d imports/ice15200b.d\n// COMPILE_SEPARATELY\n\nmodule ice15200;\n\nimport imports.ice15200a;\n\nvoid main()\n{\n    f();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ice4481.d",
    "content": "// EXTRA_SOURCES: imports/ice4481a.d imports/ice4481b.d\n\nimport imports.ice4481a;\nimport imports.ice4481b;\n\nvoid main()\n{\n    auto f = new Font();\n    assert(f.textHeight(\"str\"));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ifti.d",
    "content": "import std.stdio;\n\nstruct S {\n    int x = 3;\n    void fun(T)(T x) { writefln(\"S.fun(%s)(%s)\",typeid(T),x); this.x += x; }\n}\n\nclass Tst(TST, int v = 2) {\n    int x = 3;\n    int z = 4;\n\n    final private void proc(int x) { writefln(\"proc(%s) -> %s\",x,this.x); }\n    void fun(T)(T x) { writefln(\"fun(%s)(%s) -> %s\",typeid(T),x,this.x);}\n    void fun()() { writefln(\"fun()() -> %s\",this.x); }\n    void fun2()() { writefln(\"fun2\"); }\n\n    class Inner {\n        int y = 99;\n        Tst outer;\n        void f3() { z = 55; }\n        // Make sure the correct this-ptr is used\n        void f1() { writefln(\"Inner.f1\"); proc(-11); outer.proc(-11); }\n        void f2() { writefln(\"Inner.f2\"); fun(-17); outer.fun(-17); }\n    }\n    Inner inner;\n\n    this() {\n        inner = new Inner;\n        inner.outer = this;\n    }\n\n    void callInnerf1() { writefln(\"callInnerf1\"); inner.f1(); }\n    void callInnerf2() { writefln(\"callInnerf2\"); inner.f2(); }\n\n\n//\n    void opAdd(T)(T x) { this.x += x; writefln(\"opAdd(%s)\",x); }\n    void opPos()() { writefln(\"opPos()\"); }\n    //void opPos() { writefln(\"xxx\"); }\n    void opIndex(T)(T x) { writefln(\"opIndex[%s]\",x); }\n\n    void opIndex(A,B,C)(A a, B b, C c) {\n        writefln(\"opIndex[(%s)%s,(%s)%s,(%s)%s]\",typeid(A),a,\n                 typeid(B),b,typeid(C),c);\n    }\n\n\n    static if (v > 1) {\n        void opCall(A = int, B = float)(A a = 1, B b = 8.2) { writefln(\"opCall(%s,%s)\",a,b); this.x++; }\n\n    }\n    void opSlice(A,B)(A a, B b) { writefln(\"opSlice(%s,%s)\",a,b); }\n    void opSlice()() { writefln(\"opSlice()\"); }\n\n    void opIndexAssign(A,B)(A a, B b) {\n        writefln(\"opIndexAssign((%s)%s,(%s)%s)\",typeid(A),a,typeid(B),b);\n    }\n\n    void opSliceAssign(A,B,C)(A a, B b, C c) {\n        writefln(\"opSliceAssign(%s,%s,%s)\",a,b,c);\n    }\n\n    bool opEquals(A)(A x) { writefln(\"opEquals((%s))\",typeid(A));return true; }\n\n    int opApply(T)(int delegate(ref T)dg) {\n        for (int i = 0; i < 5; i++) {\n            T d = cast(T)(i+0.1);\n            if (auto result = dg(d))\n                return result;\n        }\n        return 0;\n    }\n}\n\nclass Y : Tst!(float) {}\n\nvoid main() {\n    Tst!(int) t = new Tst!(int);\n    Y u = new Y;\n    S s;\n    t.x = 7;\n    t.proc(5);\n    t.fun(5);\n    t.fun();\n    t.callInnerf1();\n    t.callInnerf2();\n    u.fun(5);\n    u.fun();\n    u.callInnerf1();\n    u.callInnerf2();\n    s.fun(5);\n    t.fun2();\n\n    +t;\n    t+5;\n    t[55];\n    t[1,2,3.0];\n    u[1,2,3.0];\n    t(1,2.5);\n    t(2);\n    t();\n    t[];\n    t[1..2];\n    u[1..2.5];\n    t[1i] = 5;\n    t[-4.5..7i] = \"hello\";\n    t == t;\n    auto b = t != t; // without assignment -> \"! has no effect in expression\"\n    t == u;\n    u == t;\n    u == u;\n    b = u != u;\n    foreach(int i;t) {\n        writefln(\"%s\",i);\n    }\n    foreach(double i;t) {\n        writefln(\"%s\",i);\n    }\n\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/implicit.d",
    "content": "\nimport std.stdio;\n\n/***********************************/\n\ntemplate cat1(T)\n{\n    T cat1(T i) { return i + 1; }\n}\n\nvoid test1()\n{\n    auto a = cat1(1);\n    assert(a == 2);\n}\n\n/***********************************/\n\ntemplate cat2(T)\n{\n    T cat2(T* p) { return *p + 1; }\n}\n\nvoid test2()\n{\n    int i = 1;\n    auto a = cat2(&i);\n    assert(a == 2);\n    assert(typeid(typeof(a)) == typeid(int));\n}\n\n/***********************************/\n\nstruct S3 { }\n\ntemplate cat3(T)\n{\n    T cat3(T* p, S3 s) { return *p + 1; }\n}\n\nvoid test3()\n{\n    S3 s;\n    int i = 1;\n    auto a = cat3(&i, s);\n    assert(a == 2);\n    assert(typeid(typeof(a)) == typeid(int));\n}\n\n/***********************************/\n\ntemplate cat4(T, int N)\n{\n    T cat4(T[N] p, T[N] q) { return p[0] + N; }\n}\n\nvoid test4()\n{\n    int[3] i;\n    i[0] = 7;\n    i[1] = 8;\n    i[2] = 9;\n    auto a = cat4(i, i);\n    assert(a == 10);\n    assert(typeid(typeof(a)) == typeid(int));\n}\n\n/***********************************/\n\ntemplate cat5(T, U=T*, int V=7)\n{\n    T cat5(T x)\n    {\n        U u = &x;\n\n        return x + 3 + *u + V;\n    }\n}\n\nvoid test5()\n{\n    int x = 2;\n\n    auto a = cat5(x);\n    assert(a == 14);\n    assert(typeid(typeof(a)) == typeid(int));\n\n    auto b = cat5!(int,int*,8)(x);\n    assert(b == 15);\n    assert(typeid(typeof(b)) == typeid(int));\n}\n\n/***********************************/\n\nint* pureMaker() pure\n{\n    return [1,2,3,4].ptr + 1;\n}\n\nvoid testDIP29_1()\n{\n    int* p;\n    static assert(!__traits(compiles, { immutable x = p + 3; }));\n    immutable x = pureMaker() + 1;\n    immutable y = pureMaker() - 1;\n    immutable z = 1 + pureMaker();\n}\n\n/***********************************/\n\nint** pureMaker2() pure\n{\n    int*[] da = [[11,12,13].ptr, [21,22,23].ptr, [31,32,33].ptr, [41,42,43].ptr];\n    return da.ptr + 1;\n}\n\nvoid testDIP29_2()\n{\n    immutable x2 = pureMaker2() + 1;\n    immutable y2 = pureMaker2() - 1;\n    immutable z2 = 1 + pureMaker2();\n}\n\n/***********************************/\n\nint[] pureMaker3a() pure\n{\n    return new int[4];\n}\n\nint* pureMaker3b() pure\n{\n    return new int[4].ptr;\n}\n\nint[4] pureMaker3c() pure\n{\n    int[4] buf;\n    return buf;\n}\n\nvoid testDIP29_3()\n{\n    immutable x1 = pureMaker3a()[];\n    immutable x2 = pureMaker3a()[0..2];\n\n    immutable y2 = pureMaker3b()[0..2];\n\n    // Conversion from *rvalue* of mutable static array to immutable slice\n    immutable z1 = pureMaker3c()[];\n    immutable z2 = pureMaker3c()[0..2];\n\n    // https://issues.dlang.org/show_bug.cgi?id=12467\n    // conversion from lvalue of mutable static array to immutable slice\n    char[3] arr = \"foo\";\n    static assert(!__traits(compiles, { string str = arr[]; }));\n}\n\n/***********************************/\n\nimport core.vararg;\n\nint* maker() pure { return null; }\nint* maker1(int *) pure { return null; }\nint* function(int *) pure makerfp1;\nint* maker2(int *, ...) pure { return null; }\nint* maker3(int) pure { return null; }\nint* maker4(ref int) pure { return null; }\nint* maker5(ref immutable int) pure { return null; }\n\nvoid testDIP29_4()\n{\n    { immutable x = maker1(maker()); }\n    { immutable x = maker1(null); }\n    static assert(__traits(compiles, { immutable x = (*makerfp1)(maker()); }));\n    { shared x = maker1(null); }\n    { immutable x = maker2(null, 3); }\n    { immutable int g; immutable x = maker2(null, 3, &g); }\n    static assert(!__traits(compiles, { int g; immutable x = maker2(null, 3, &g); }));\n    { immutable x = maker3(1); }\n    static assert(!__traits(compiles, { int g; immutable x = maker4(g); }));\n    { immutable int g; immutable x = maker5(g); }\n}\n\n/***********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14155\n\nimmutable int g14155;\n\nstatic this() { g14155 = 1; }\n\n             int*  make14155m (             int*  p) pure { return null; }\n       const(int*) make14155c (       const(int*) p) pure { return &g14155; }\n   immutable(int*) make14155i (   immutable(int*) p) pure { return &g14155; }\n      shared(int*) make14155sm(      shared(int*) p) pure { return null; }\nshared(const int*) make14155sc(shared(const int*) p) pure { return &g14155; }\n\nvoid test14155_for_testDIP29_4()\n{\n    static assert( __traits(compiles, {              int*  p = make14155m (null); }));  //  m <- m (normal)\n    static assert( __traits(compiles, {        const(int*) p = make14155m (null); }));  //  c <- m (normal)\n    static assert( __traits(compiles, {       shared(int*) p = make14155m (null); }));  // sm <- m (unique)\n    static assert( __traits(compiles, { shared(const int*) p = make14155m (null); }));  // sc <- m (unique)\n    static assert( __traits(compiles, {    immutable(int*) p = make14155m (null); }));  //  i <- m (unique)\n\n    static assert(!__traits(compiles, {              int*  p = make14155c (null); }));  //  m <- c (NG) <bugzilla case>\n    static assert( __traits(compiles, {        const(int*) p = make14155c (null); }));  //  c <- c (normal)\n    static assert(!__traits(compiles, {       shared(int*) p = make14155c (null); }));  // sm <- c (NG)\n    static assert( __traits(compiles, { shared(const int*) p = make14155c (null); }));  // sc <- c (unique or immutable global)\n    static assert( __traits(compiles, {    immutable(int*) p = make14155c (null); }));  //  i <- c (unique or immutable global)\n\n    static assert(!__traits(compiles, {              int*  p = make14155i (null); }));  //  m <- i (NG)\n    static assert( __traits(compiles, {        const(int*) p = make14155i (null); }));  //  c <- i (normal)\n    static assert(!__traits(compiles, {       shared(int*) p = make14155i (null); }));  // sm <- i (NG)\n    static assert( __traits(compiles, { shared(const int*) p = make14155i (null); }));  // sc <- i (normal)\n    static assert( __traits(compiles, {    immutable(int*) p = make14155i (null); }));  //  i <- i (normal)\n\n    static assert( __traits(compiles, {              int*  p = make14155sm(null); }));  //  m <- sm (unique)\n    static assert( __traits(compiles, {        const(int*) p = make14155sm(null); }));  //  c <- sm (unique)\n    static assert( __traits(compiles, {       shared(int*) p = make14155sm(null); }));  // sm <- sm (normal)\n    static assert( __traits(compiles, { shared(const int*) p = make14155sm(null); }));  // sc <- sm (normal)\n    static assert( __traits(compiles, {    immutable(int*) p = make14155sm(null); }));  //  i <- sm (unique)\n\n    static assert(!__traits(compiles, {              int*  p = make14155sc(null); }));  //  m <- sc (NG)\n    static assert( __traits(compiles, {        const(int*) p = make14155sc(null); }));  //  c <- sc (unique or immutable global)\n    static assert(!__traits(compiles, {       shared(int*) p = make14155sc(null); }));  // sm <- sc (NG)\n    static assert( __traits(compiles, { shared(const int*) p = make14155sc(null); }));  // sc <- sc (normal)\n    static assert( __traits(compiles, {    immutable(int*) p = make14155sc(null); }));  //  i <- sc\n\n    int x;\n    int* nestf() pure { return &x; }\n    static assert(!__traits(compiles, { immutable(int*) ip = nestf(); }));\n}\n\n/***********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14141\n\nstruct S14141\n{\n    Object obj;\n\n    const(Object) getObj() const pure\n    {\n        return obj;\n    }\n}\n\nvoid test14141()\n{\n    const S14141 s;\n    static assert(is(typeof(s.getObj()) == const Object));           // ok\n    static assert(!__traits(compiles, { Object o = s.getObj(); }));  // ok <- fails\n}\n\n/***********************************/\n\nint[] test6(int[] a) pure @safe nothrow\n{\n    return a.dup;\n}\n\n/***********************************/\n\nint*[] pureFoo() pure { return null; }\n\n\nvoid testDIP29_5() pure\n{\n    { char[] s; immutable x = s.idup; }\n    { immutable x = (cast(int*[])null).dup; }\n    { immutable x = pureFoo(); }\n    { immutable x = pureFoo().dup; }\n}\n\n/***********************************/\n\nvoid testDIP29_6()\n{\n    /******* structs ************/\n\n    static assert(__traits(compiles,\n    {\n        static struct S { int *p; }\n        immutable s = new S;        // since p is null\n    }));\n\n    static assert(!__traits(compiles,\n    {\n        __gshared int x;\n        static struct S { int *p = &x; }\n        immutable s = new S;        // x is mutable\n    }));\n\n    static assert(!__traits(compiles,\n    {\n        int y;\n        struct S { int x; void bar() { y = 3; } }\n        immutable s = new S;        // nested struct\n    }));\n\n    static assert(!__traits(compiles,\n    {\n        static struct S { int x; this(int); }\n        immutable s = new S(1);\n    }));\n\n    static assert(__traits(compiles,\n    {\n        static struct S { int x; this(int) pure; }\n        immutable s = new S(1);\n    }));\n\n    static assert(__traits(compiles,\n    {\n        static struct S { int* p = void; this(int) pure; }\n        immutable s = new S(1);\n    }));\n\n    static assert(!__traits(compiles,\n    {\n        static struct S { int* p = void; this(int*) pure; }\n        int x;\n        immutable s = new S(&x);\n    }));\n\n    static assert(__traits(compiles,\n    {\n        static struct S { int* p = void; this(immutable(int)*) pure; }\n        immutable int x;\n        immutable s = new S(&x);\n    }));\n\n    static assert(__traits(compiles,\n    {\n        static struct S { int* p = void; this(int*) pure; }\n        immutable s = new S(null);\n    }));\n\n    /******* classes ************/\n\n    static assert(__traits(compiles,\n    {\n        static class S { int *p; }\n        immutable s = new S;        // since p is null\n    }));\n\n    static assert(!__traits(compiles,\n    {\n        __gshared int x;\n        static class S { int *p = &x; }\n        immutable s = new S;        // x is mutable\n    }));\n\n    static assert(!__traits(compiles,\n    {\n        int y;\n        class S { int x; void bar() { y = 3; } }\n        immutable s = new S;        // nested class\n    }));\n\n    static assert(!__traits(compiles,\n    {\n        static class S { int x; this(int); }\n        immutable s = new S(1);\n    }));\n\n    static assert(__traits(compiles,\n    {\n        static class S { int x; this(int) pure; }\n        immutable s = new S(1);\n    }));\n\n    static assert(__traits(compiles,\n    {\n        static class S { int* p = void; this(int) pure; }\n        immutable s = new S(1);\n    }));\n\n    static assert(!__traits(compiles,\n    {\n        static class S { int* p = void; this(int*) pure; }\n        int x;\n        immutable s = new S(&x);\n    }));\n\n    static assert(__traits(compiles,\n    {\n        static class S { int* p = void; this(immutable(int)*) pure; }\n        immutable int x;\n        immutable s = new S(&x);\n    }));\n\n    static assert(__traits(compiles,\n    {\n        static class S { int* p = void; this(int*) pure; }\n        immutable s = new S(null);\n    }));\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=14155\n\nvoid test14155_for_testDIP29_6()\n{\n    static class CI\n    {\n        int* p;\n        this(int) immutable pure { p = &g14155; }\n    }\n\n    static assert(!__traits(compiles, {           CI c = new immutable CI(1); }));\n    static assert( __traits(compiles, {     const CI c = new immutable CI(1); }));\n    static assert( __traits(compiles, { immutable CI c = new immutable CI(1); }));\n    static assert(!__traits(compiles, {    shared CI c = new immutable CI(1); }));\n    static assert(!__traits(compiles, {           CI c = new     const CI(1); }));\n    static assert( __traits(compiles, {     const CI c = new     const CI(1); }));\n    static assert( __traits(compiles, { immutable CI c = new     const CI(1); }));\n    static assert(!__traits(compiles, {    shared CI c = new     const CI(1); }));\n}\n\n/***********************************/\n// https://issues.dlang.org/show_bug.cgi?id=13640\n\nstruct S13640\n{\n    static struct R\n    {\n        int* p;\n        this(inout ref int* p) inout pure { this.p = p; }\n    }\n\n    int* p;\n\n    void foo() inout pure\n    {\n        // Implicit conversion from inout(R) to R should be disallowed.\n        static assert(!__traits(compiles, { R r = inout(R)(p); }));\n    }\n}\n\n/***********************************/\n// https://issues.dlang.org/show_bug.cgi?id=15778\n\nvoid test15778()\n{\n     char[] cs = new  char[](3);\n    wchar[] ws = new wchar[](3);\n    dchar[] ds = new dchar[](3);\n\n    cs[] = \"abc\";   assert(cs == \"abc\");\n    cs[] = \"def\"c;  assert(cs == \"def\");\n    ws[] = \"abc\";   assert(ws == \"abc\");\n    ws[] = \"def\"w;  assert(ws == \"def\");\n    ds[] = \"abc\";   assert(ds == \"abc\");\n    ds[] = \"def\"d;  assert(ds == \"def\");\n\n    static assert(!__traits(compiles, (cs[] = \"a\"w)));\n    static assert(!__traits(compiles, (cs[] = \"a\"d)));\n    static assert(!__traits(compiles, (ws[] = \"a\"c)));\n    static assert(!__traits(compiles, (ws[] = \"a\"d)));\n    static assert(!__traits(compiles, (ds[] = \"a\"c)));\n    static assert(!__traits(compiles, (ds[] = \"a\"w)));\n}\n\n/***********************************/\n\nvoid main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    testDIP29_1();\n    testDIP29_2();\n    testDIP29_3();\n    testDIP29_4();\n    testDIP29_5();\n    testDIP29_6();\n    test15778();\n\n    writefln(\"Success\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/A16a.d",
    "content": "import A16;\n\nimport std.stdio;\n\nclass B16 : AA16\n{\n  public\n    this()\n    {\n\tsuper();\n\tprintf(\"class B16\\n\");\n    }\n}\n\nint main()\n{\n    new B16;\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/Other.d",
    "content": "module imports.Other; // makes no difference if removed\nimport Same;\nimport core.stdc.stdio;\n\nclass Other : Same // segfault\n// class Other : Same.Same //***UGLY ALERT*** but doesn't segfault\n{\nthis()\n{\nprintf(\"other\\n\");\n}\n}\n\nint main()\n{\n    new Other;\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a11447.d",
    "content": "module imports.a11447;\nstruct A { }\n\nvoid map(alias dg)(A r) { }\n\nstruct TTT\n{\n    static auto yyy(A a)\n    {\n        map!(b => 0)(a);\n    }\n}\n\nvoid bar() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a12010.d",
    "content": "module imports.a12010;\nimport imports.std12010container : Array, BinaryHeap;\nBinaryHeap!(Array!int) test;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a12037.d",
    "content": "module imports.aXXXXX;\n\nauto min(A, B)(A a, B b) { return a < b ? a : b; }\nalias TypeTuple(T...) = T;\n\nprivate template CustomFloatParams(uint bits)\n{\n    static if (bits ==  8) alias CustomFloatParams!( 4,  3) CustomFloatParams;\n    static if (bits == 16) alias CustomFloatParams!(10,  5) CustomFloatParams;\n    static if (bits == 32) alias CustomFloatParams!(23,  8) CustomFloatParams;\n    static if (bits == 64) alias CustomFloatParams!(52, 11) CustomFloatParams;\n    static if (bits == 80) alias CustomFloatParams!(64, 15) CustomFloatParams;\n}\nprivate template CustomFloatParams(uint precision, uint exponentWidth)\n{\n    alias TypeTuple!(\n        precision,\n        exponentWidth,\n    ) CustomFloatParams;\n}\n\nstruct CustomFloat(uint precision, uint exponentWidth)\nif ((1 + precision + exponentWidth) % 8 == 0 && precision + exponentWidth > 0)\n{\nprivate:\n    union ToBinary(F)\n    if (is(typeof(CustomFloatParams!(F.sizeof*8))) || is(F == real))\n    {\n        F set;\n\n        // If on Linux or Mac, where 80-bit reals are padded, ignore the\n        // padding.\n        CustomFloat!(CustomFloatParams!(min(F.sizeof*8, 80))) get;\n\n        // Convert F to the correct binary type.\n        static typeof(get) opCall(F value)\n        {\n            ToBinary r;\n            r.set = value;\n            return r.get;\n        }\n        alias get this;\n    }\n\npublic:\n    @property bool sign() { return 1; }\n    @property void sign(bool) {}\n\n    this(F)(F input)\n    if (__traits(compiles, cast(real)input))\n    {\n        this = input;\n    }\n\n    void opAssign(F)(F input)\n    if (__traits(compiles, cast(real)input))\n    {\n        static if (is(F == float) || is(F == double) || is(F == real))\n                auto value = ToBinary!(F)(input);\n        else    auto value = ToBinary!(real)(input);\n\n        sign = value.sign;\n    }\n\n    @property F get(F)()\n    if (is(F == float) || is(F == double) || is(F == real))\n    {\n        ToBinary!F result;\n        return F.init;\n    }\n\n    T opCast(T)()\n    if (__traits(compiles, get!T))\n    {\n        return get!T;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a12874.d",
    "content": "module imports.a12874;\n\ntemplate foo(alias x)\n{\n    void check(int[] arr)\n    {\n        auto n = arr[0];\n    }\n    void foo()\n    {\n        check([]);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a14267.d",
    "content": "module imports.a14267;\n\nstruct SysTime14267\n{\n    // semantic() is called twice, and its scope is wrongly set to NULL\n    // at the second call.\n    this(long stdTime) {}\n    this(this) {}\n    ~this() {}\n\n    static SysTime14267 min()\n    {\n        // inlining this function will call the semantic3() of SysTime14267 constructor.\n        // but its 'scope' field is NULL so unintentionally semantic3() call fails.\n        auto st = SysTime14267(long.min);\n        auto st2 = st;\n        return st2;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a14992.d",
    "content": "module imports.a14992;\n\nstruct S1 { }\n\nstruct S2 { int v; int[] a; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a15030.d",
    "content": "module a;\n\nimport imports.std15030algo;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a15079.d",
    "content": "module imports.a15079;\n\nVector!string parseAlgorithmName()\n{\n    assert(0);\n}\n\nstruct Vector(ALLOC)\n{\n    @disable this(this);\n\n    RefCounted!(Vector, ALLOC) dupr()\n    {\n        assert(0);\n    }\n}\n\nstruct RefCounted(T, ALLOC)\n{\n    ~this()\n    {\n        T* objc;\n        .destroy(*objc);\n    }\n}\n\n// ----\n\nvoid _destructRecurse(S)(ref S s)\n    if (is(S == struct))\n{\n    static if (__traits(hasMember, S, \"__xdtor\") &&\n               __traits(isSame, S, __traits(parent, s.__xdtor)))\n    {\n        s.__xdtor();\n    }\n}\n\nvoid destroy(T)(ref T obj) if (is(T == struct))\n{\n    _destructRecurse(obj);\n    () @trusted {\n        auto buf = (cast(ubyte*) &obj)[0 .. T.sizeof];\n        auto init = cast(ubyte[])typeid(T).init();\n        if (init.ptr is null) // null ptr means initialize to 0s\n            buf[] = 0;\n        else\n            buf[] = init[];\n    } ();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a17a.d",
    "content": "module imports.a17a;\n\nprivate import a17;\n\nclass foo2x : barx {\n    int x;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a18a.d",
    "content": "module imports.a18a;\n\ninterface IEnumerator\n{\n}\n\nclass Enumerator(T) : IEnumerator\n{\n\tthis()\n\t{\n\t}\n}\n\ninterface IContainer(T)\n{\n\talias   Container!(int)\t\tselected_type;\n\n\tIEnumerator\tenumerate();\n}\n\nclass Container(T) : IContainer!(int)\n{\n\tIEnumerator\tenumerate()\n\t{\n\t    return new Enumerator!(int)();\n\t}\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a19a.d",
    "content": "module imports.a19a;\n\nstruct Dummy\n{\n}\n\nstruct TemplatedStruct(Param)\n{\n        static real fgh = 0;\n}\n\nvoid foo()\n{\n        alias TemplatedStruct!(Dummy) X;        \n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a20a.d",
    "content": "import a20;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a21a.d",
    "content": "module imports.a21a;\n\nimport std.stdio;\nimport a21;\n\ntemplate GoodMixin()\n{\n    int goodFunc()\n    {\n\tprintf(\"goodFunc\\n\");\n\treturn 1;\n    }\n}\n\n\nclass SomeClass\n{\n    mixin GoodMixin;\n    mixin BadMixin;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a7595.d",
    "content": "@trusted:\n\nimport test7595;\n\nstruct Matrix\n{\n    int[4] _data;\n}\n\nvoid inverse(const ref Matrix m)\n{\n    for (size_t i = 0; i < 4; i++)\n        assert(m._data[i] == i + 1);\n}\n\nvoid main()\n{\n    Matrix m9;\n    m9._data[0] = 1;\n    m9._data[1] = 2;\n    m9._data[2] = 3;\n    m9._data[3] = 4;\n    for (size_t i = 0; i < 4; i++)\n        assert(m9._data[i] == i + 1);\n\n    benchmark!({ inverse(m9); })(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a9546.d",
    "content": "module imports.a9546;\n\nstruct S\n{\n    private   int privA;\n    protected int protA;\n    package   int packA;\n\n    private   void privF() {}\n    protected void protF() {}\n    package   void packF() {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/a9741.d",
    "content": "module imports.a9741b;\n\ntemplate ShowAttributes(alias X)\n{\n    pragma(msg, X.stringof);\n    pragma(msg, __traits(getAttributes, X));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/another_module_with_tests.d",
    "content": "module imports.another_module_with_tests;\nunittest {}\nunittest {}\nunittest { assert(false); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/argufile.d",
    "content": "// argufile.d ----------------------------------------------------\n\npublic:\n\nimport core.vararg;\nimport std.stdio;\nimport std.utf;\n\ndstring formatstring(TypeInfo[] arguments, va_list argptr)\n{\n\n\tdstring message = null;\n\n\tvoid putc(dchar c)\n\t{\n\t\tmessage ~= c;\n\t}\n\n\n\tdoFormat(&putc, arguments, argptr);\n\n\n\treturn message;\n}\n\nstring arguments(...) // turns a bunch of arguments into a formatted char[] string\n{\n\treturn std.utf.toUTF8(formatstring(_arguments, _argptr));\n}\n\nvoid useargs(...)\n{\n\tstring crashage = arguments(\"why is 8 scared of 7? because\", 7,8,9);\n\n\t//printf(\"%.*s\\n\", crashage);\n\twritefln(crashage);\n}\n\n\n// dustmited version of the deprecated doFormat.\n// See the full file at:\n// https://github.com/dlang/undeaD/blob/master/src/undead/doformat.d\nvoid doFormat(void delegate(dchar) putc, TypeInfo[] arguments, va_list ap)\n{\n    import core.stdc.stdlib : alloca, malloc;\n    import std.format ;\n\n    size_t bufLength = 1024;\n    void* argBuffer = malloc(bufLength);\n    size_t bufUsed ;\n    foreach (ti; arguments)\n    {\n        auto pos = bufUsed;\n        // Align to next word boundary\n        bufUsed += ti.tsize + size_t.sizeof - 1;\n        bufUsed -= bufUsed& size_t.sizeof - 1;\n        // Copy argument into buffer\n        va_arg(ap, ti, argBuffer + pos);\n    }\n\n    auto argptr = argBuffer;\n    void* skipArg(TypeInfo ti)\n    {\n        auto p = argptr;\n        // Align to next word boundary\n        argptr += ti.tsize + size_t.sizeof - 1;\n        argptr -= cast(size_t)argptr & size_t.sizeof - 1;\n        return p;\n    }\n    auto getArg(T)()\n    {\n        return *cast(T*)skipArg(typeid(T));\n    }\n\n    TypeInfo ti;\n    Mangle m;\n    void formatArg()\n    {\n        ulong vnumber;\n        char vchar;\n        Mangle m2;\n        int signed ;\n        string s;\n\n        void putstr(const char[] s)\n        {\n            foreach (c; s)\n                putc(c);\n\n        }\n\n        //printf(\"formatArg(fc = '%c', m = '%c')\\n\", fc, m);\n        int mi;\n        switch (m)\n        {\n            L2:\n                putstr((&vchar)[0 .. 1]);\n                return;\n\n            case Mangle.Tint:\n                signed = 1;\n                vnumber = getArg!int;\n                goto Lnumber;\n\n            case Mangle.Tarray:\n                mi = 10;\nwhile (1)\n                {\n                    m2 = cast(Mangle)typeid(ti).name[mi];\n                    switch (m2)\n                    {\n                        case Mangle.Tchar:\n                            s = getArg!string;\n                            putstr(s);\n                            break;\n\n                        case Mangle.Timmutable:\n                            mi++;\n                            continue;\n\n                        default:\n                            {}\n                    }\n                    return;\n                }\n            default:\n                {}\n        }\n\n    Lnumber:\n;\nvchar = cast(char)('0' + vnumber);\n                goto L2;\n    }\n\n    for (int j ; j < arguments.length; )\n    {\n        ti = arguments[j++];\n        int mi = 9;\n        do\n            m = cast(Mangle)typeid(ti).name[mi++];\nwhile (m == Mangle.Tconst );\n\n            formatArg;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/b11447.d",
    "content": "module imports.b11447;\nclass A {}\n\nvoid map(alias dg)(int b) { }\n\nauto aaa(A a)\n{\n    int bs;\n\n    static A ggg;\n\n    bs.map!(\n        b => (a is ggg ? \"a\" : \"b\")\n    );\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/b15030.d",
    "content": "module b;\n\nimport imports.std15030algo;\n\nunittest\n{\n    auto dg =\n        // __lambda1\n        (int[] delegate(int[]) self) =>\n            // __lambda2\n            (int[] arr) => arr\n                           ? self([arr.filter!(\n                                // __lambda2.__lambda2\n                                a => a\n                             ).front])\n                           : null;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/b26a.d",
    "content": "module imports.b26a;\n\nimport b26;\n\nvoid foo(List!(char) list) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/bar10378.d",
    "content": "\nmodule bar;\n\nvoid writeln() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/bug10425.d",
    "content": "module imports.bug10425;\n\nstruct A()\n{\n    int opCmp(const ref A p) const\n    {\n        return 0;\n    }\n\n    string toString()\n    {\n        return \"\";\n    }\n}\n\nstruct B()\n{\n    void foo()\n    {\n        auto a = new A!();\n    }\n}\n\nstruct C\n{\n    alias A!() a_t;\n\n    this(B!() b)\n    {\n\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/bug846.d",
    "content": "module imports.bug846;\n\ntemplate ElemTypeOf( T )\n{\n    alias typeof(T.init[0]) ElemTypeOf;\n}\n\ntemplate removeIf_( Elem, Pred )\n{\n    size_t fn( Elem[] buf, Pred pred )\n    {\n        void exch( size_t p1, size_t p2 )\n        {\n            Elem t  = buf[p1];\n            buf[p1] = buf[p2];\n            buf[p2] = t;\n        }\n\n        size_t cnt = 0;\n\n        for( size_t pos = 0, len = buf.length; pos < len; ++pos )\n        {\n            if( pred( buf[pos] ) )\n                ++cnt;\n            else\n                exch( pos, pos - cnt );\n        }\n        return buf.length - cnt;\n    }\n}\n\ntemplate removeIf( Buf, Pred )\n{\n    size_t removeIf( Buf buf, Pred pred )\n    {\n        return removeIf_!(ElemTypeOf!(Buf), Pred).fn( buf, pred );\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/c11447.d",
    "content": "module imports.c11447;\ntemplate map(fun...)\n{\n    auto map(Range)(Range r)\n    {\n        return MapResult!(fun, Range)(r);\n    }\n}\nprivate struct MapResult(alias fun, R)\n{\n    R _input;\n    this(R input) { _input = input; }\n    @property bool empty() { return _input.length == 0; }\n    @property auto ref front() { return fun(_input[0]); }\n    void popFront() { _input = _input[1..$]; }\n}\n\nclass A {}\n\nstruct TemplateInstancier\n{\n    auto instanciateFromResolvedArgs(A a)\n    {\n        auto bs = [B(a)];\n\n        static A gladeulfeurah;\n        gladeulfeurah = a;\n\n        auto r = bs.map!(\n            b => b.apply!(\n                function string() { assert(0); },\n                delegate string(i) {\n                    assert(a is gladeulfeurah, \"tagazok\");\n                    return \"\";\n                }\n            )\n        );\n\n        foreach (e; r) {}\n    }\n}\n\nenum Tag { Undefined, A, }\n\nstruct B\n{\n    A a;\n    Tag tag;\n\n    this(A a)\n    {\n        tag = Tag.A;\n        this.a = a;\n    }\n}\n\nauto apply(alias undefinedHandler, alias handler)(B b)\n{\n    final switch(b.tag) with(Tag)\n    {\n        case Undefined :\n            return undefinedHandler();\n\n        case A :\n            return handler(b.a);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/c22a.d",
    "content": "module imports.c22a;\n\nvoid afn1() {}\nvoid afn2() {}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/c22b.d",
    "content": "module imports.c22b;\n\npublic import imports.c22a : afn1;\n\nvoid bfn1() {}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/circularA.d",
    "content": "module imports.circularA;\nimport circular;\n\nclass A\n{\n    struct\n    {\n        Tclass a;\n        Tstruct b;\n    }\n    union\n    {\n        Tclass c;\n        Tstruct d;\n    }\n}\n\nstruct B\n{\n    struct\n    {\n        Tclass a;\n        Tstruct b;\n    }\n    union\n    {\n        Tclass c;\n        Tstruct d;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/depsprot_default.d",
    "content": "void pack() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/depsprot_private.d",
    "content": "void priv() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/depsprot_public.d",
    "content": "void pub() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/extern1a.d",
    "content": "extern (C)\n{\n    int x = 3;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ice10086x.d",
    "content": "module imports.ice10086x;\n\nimport imports.ice10086y;\n\nstruct S1\n{\n    int a1 = 123;\n}\n\n@safe auto f1(S1 r)\n{\n    return r;\n}\n\n@safe auto f2a()(S1 r)\n{\n    return bind!(f1, r);\n}\n\n@safe auto f2b(S1 r)\n{\n    return bind!(f1, r);\n}\n\nvoid test()\n{\n    S1 s1;\n\n    auto za = bind!(f2a, s1)();\n    assert(za.a1 == 123);\n\n    auto zb = bind!(f2b, s1)();\n    assert(zb.a1 == 123);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ice10086y.d",
    "content": "module imports.ice10086y;\n\nauto bind(alias f, bindValues...)()\n{\n    auto bind(Types...)(Types values)\n    {\n        return f(bindValues, values);\n    }\n    return bind();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ice10857a.d",
    "content": "module imports.ice10857a;\n\ntemplate filter(alias pred)\n{\n    auto filter(Range)(Range rs)\n    {\n        return FilterResult!(pred, Range)(rs);\n    }\n}\n\nprivate struct FilterResult(alias pred, R)\n{\n    R _input;\n\n    void popFront()\n    {\n        assert(pred(_input[0]) == 123);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ice10857b.d",
    "content": "module imports.ice10857b;\n\nimport imports.ice10857a;\nimport imports.ice10857b;\n\nvoid foo(int outer)\n{\n    int[] infos = [1];\n    auto f1 = filter!(s => outer)(infos);     // NG: error is triggered here\n    f1.popFront();\n    auto f2 = filter!((int s)=>outer)(infos); // OK\n    f2.popFront();\n}\nvoid main() { foo(123); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ice15138a.d",
    "content": "module imports.ice15138a;\n\nalias AliasSeq(TL...) = TL;\n\nalias FieldNameTuple(T...) = AliasSeq!();\n\nstruct TaggedAlgebraic(U)\n{\n    alias X = FieldNameTuple!(U.tupleof);\n}\n\nvoid get(T, U)(TaggedAlgebraic!U ta) {}\n\nunion PayloadUnion\n{\n    int dummy;\n}\n\nstruct JSONValue\n{\n    alias Payload = TaggedAlgebraic!PayloadUnion;\n\n    void get(T)()\n    {\n        Payload payload;\n        .get!T(payload);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ice15176a.d",
    "content": "module imports.ice15176a;\n\nimport imports.ice15176b;\n\nstruct Stack(T)\n{\n    T[] data;\n}\n\nvoid func()\n{\n    alias ValStack = Stack!CodepointSet;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ice15176b.d",
    "content": "module imports.ice15176b;\n\nalias CodepointSet = InversionList!();\n\nstruct InversionList()\n{\n    uint[] data;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ice15200a.d",
    "content": "module imports.ice15200a;\nimport imports.ice15200b;\n\nauto f() // not void\n{\n    sub([0], false);\n}\nvoid sub(R)(R list, bool b)\n{\n    foreach (i; list.filter!(delegate(e) => b))\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ice15200b.d",
    "content": "module imports.ice15200b;\n\ntemplate filter(alias pred)\n{\n    auto filter(R)(R range)\n    {\n        return FilterResult!(pred, R)(range);\n    }\n}\n\nstruct FilterResult(alias pred, R)\n{\n    R _input;\n\n    this(R r)\n    {\n        _input = r;\n        while (_input.length && !pred(_input[0]))\n        {\n            _input = _input[1..$];\n        }\n    }\n\n    @property bool empty()\n    {\n        return _input.length == 0;\n    }\n\n    @property auto ref front()\n    {\n        return _input[0];\n    }\n\n    void popFront()\n    {\n        do\n        {\n            _input = _input[1..$];\n        } while (_input.length && !pred(_input[0]));\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ice4481a.d",
    "content": "module imports.ice4481a;\n\ntemplate reduce(alias pred)\n{\n    auto reduce(R)(R range)\n    {\n        return pred(range[0]);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ice4481b.d",
    "content": "module imports.ice4481b;\n\nimport imports.ice4481a;\n\nclass Font\n{\npublic:\n    int charHeight(dchar c) { return c == 's'; }\n    int textHeight(in string text)\n    {\n        auto maxHeight = (dchar ch) { return charHeight(ch); };\n        return reduce!(maxHeight)(text);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/inc11239.d",
    "content": "// REQUIRED_ARGS:\nmodule imports.inc11239;\n\nint foo(T)(T x)\n{\n    return 3;\n}\n\ndebug\n{\n    int x = foo(2);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/inline2a.d",
    "content": "/*******************************************************************************\n\n        @file Primes.d\n\n        Copyright (C) 2004 Kris Bell\n\n        This software is provided 'as-is', without any express or implied\n        warranty. In no event will the authors be held liable for damages\n        of any kind arising from the use of this software.\n\n        Permission is hereby granted to anyone to use this software for any\n        purpose, including commercial applications, and to alter it and/or\n        redistribute it freely, subject to the following restrictions:\n\n        1. The origin of this software must not be misrepresented; you must\n           not claim that you wrote the original software. If you use this\n           software in a product, an acknowledgment within documentation of\n           said product would be appreciated but is not required.\n\n        2. Altered source versions must be plainly marked as such, and must\n           not be misrepresented as being the original software.\n\n        3. This notice may not be removed or altered from any distribution\n           of the source.\n\n\n                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\n        @version        Initial version, April 2004\n        @author         Kris\n\n\n*******************************************************************************/\n\n// originally: module primes;\nmodule imports.inline2a;\n\nclass Primes\n{\n        private\n         static const short[] primes =\n        [\n           2,    3,    5,    7,   11,   13,   17,   19,   23,   29,\n          31,   37,   41,   43,   47,   53,   59,   61,   67,   71,\n          73,   79,   83,   89,   97,  101,  103,  107,  109,  113,\n         127,  131,  137,  139,  149,  151,  157,  163,  167,  173,\n         179,  181,  191,  193,  197,  199,  211,  223,  227,  229,\n         233,  239,  241,  251,  257,  263,  269,  271,  277,  281,\n         283,  293,  307,  311,  313,  317,  331,  337,  347,  349,\n         353,  359,  367,  373,  379,  383,  389,  397,  401,  409,\n         419,  421,  431,  433,  439,  443,  449,  457,  461,  463,\n         467,  479,  487,  491,  499,  503,  509,  521,  523,  541,\n         547,  557,  563,  569,  571,  577,  587,  593,  599,  601,\n         607,  613,  617,  619,  631,  641,  643,  647,  653,  659,\n         661,  673,  677,  683,  691,  701,  709,  719,  727,  733,\n         739,  743,  751,  757,  761,  769,  773,  787,  797,  809,\n         811,  821,  823,  827,  829,  839,  853,  857,  859,  863,\n         877,  881,  883,  887,  907,  911,  919,  929,  937,  941,\n         947,  953,  967,  971,  977,  983,  991,  997, 1009, 1013,\n        1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,\n        1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,\n        1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,\n        1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,\n        1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,\n        1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,\n        1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,\n        1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,\n        1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657,\n        1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,\n        1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,\n        1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889,\n        1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987,\n        1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,\n        2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129,\n        2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213,\n        2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287,\n        2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,\n        2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,\n        2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531,\n        2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617,\n        2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,\n        2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,\n        2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819,\n        2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903,\n        2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,\n        3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,\n        3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181,\n        3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257,\n        3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,\n        3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,\n        3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511,\n        3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571,\n        3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,\n        3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727,\n        3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821,\n        3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907,\n        3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,\n        4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057,\n        4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139,\n        4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231,\n        4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,\n        4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409,\n        4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493,\n        4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583,\n        4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,\n        4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751,\n        4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831,\n        4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937,\n        4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003,\n        5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087,\n        5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179,\n        5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279,\n        5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387,\n        5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,\n        5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521,\n        5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639,\n        5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693,\n        5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,\n        5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857,\n        5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939,\n        5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053,\n        6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133,\n        6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221,\n        6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301,\n        6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367,\n        6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,\n        6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571,\n        6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673,\n        6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761,\n        6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,\n        6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917,\n        6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997,\n        7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103,\n        7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,\n        7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297,\n        7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411,\n        7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499,\n        7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561,\n        7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643,\n        7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723,\n        7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829,\n        7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919\n        ];\n\n        /*********************************************************************\n\n                Binary-chop search on sorted data.\n\n        *********************************************************************/\n\n        private static ptrdiff_t bsearch (in short[] array, short match)\n        {\n                ptrdiff_t l, u, m;\n\n                l = -1;\n                u = array.length;\n\n                while (l+1 != u)\n                      {\n                      m = (l + u) / 2;\n                      if (array[m] < match)\n                          l = m;\n                      else\n                         u = m;\n                      }\n\n               if (u >= array.length || array[u] != match)\n                   return -u;\n               return u;\n        }\n\n        /**********************************************************************\n\n                return a prime number between 2 and 7919 (inclusive) that\n                is equal to or larger than the given 'target' number.\n\n        **********************************************************************/\n\n        static int lookup (short target)\n        {\n                auto index = bsearch (primes, target);\n                if (index < 0)\n                    index = -index;\n\n                if (index >= primes.length)\n                    index = primes.length - 1;\n\n                return primes[index];\n        }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link10920a.d",
    "content": "module imports.link10920a;\n\nstruct FormatSpec(C)\n{\n    void func() {}\n}\n\nstruct BitArray\n{\n    auto toString()\n    {\n        // An auto function may runs semantic3 to calculate return type,\n        // even if it's non-root symbol.\n        // But inside the function body, all instantiations should be treated\n        // as speculative.\n        FormatSpec!char fs;\n        fs.func();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link11069x.d",
    "content": "module imports.link11069x;\nimport imports.link11069z;\n\nimport std.algorithm;\n\nvoid bar()\n{\n    Vector2[] tc;\n    sort(tc);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link11069y.d",
    "content": "module imports.link11069y;\nimport std.traits;\n\nvoid readWriteVariable(T)(ref T data)\n{\n    foreach (it; __traits(allMembers, T))\n    {\n        enum vValid = mixin(`is(FunctionTypeOf!(T.` ~ it ~ `) == function)`);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link11069z.d",
    "content": "module imports.link11069z;\nstruct Matrix(T, uint _M)\n{\n    int opCmp()(auto ref in Matrix b) const\n    {\n        return 0;\n    }\n\n    pure auto opDispatch(string s)()\n    {\n        enum L = s.length;\n        Matrix!(T, L) ret;\n        return ret;\n    }\n\n    pure Matrix normalized()\n    {\n        return Matrix();\n    }\n}\n\nalias Matrix!(float, 2) Vector2;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link11127a.d",
    "content": "module imports.link11127a;\n\nstruct Cycle(Range)\n{\n    alias Range R;\n\n    R _original;\n    size_t _index;\n\n    this(R input, size_t index = 0) {}\n}\n\nCycle!R cycle(R)(R input)\n{\n    return Cycle!R(input);\n}\n\nCycle!R cycle(R)(R input, size_t index = 0)\n{\n    return Cycle!R(input, index);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link11395a.d",
    "content": "module imports.link11395a;\n\nstruct SA\n{\n    bool flag;\n    int[] nums;\n\n    bool opEquals(bool b) { return flag == b; }\n}\n\nstruct SB\n{\n    int num;\n    SA sa;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link12144a.d",
    "content": "module imports.link12144a;\nstruct S1 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S2 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S3 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S4 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S5 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S6 { bool opEquals(T : typeof(this))(T) { return false; } ~this(){} }\nstruct S7 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S8 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S9 { bool opEquals(T : typeof(this))(T) { return false; } }\n\nstruct S10 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S11 { bool opEquals(T : typeof(this))(T) const { return false; }\n             int opCmp(T : typeof(this))(T) const { return 0; }\n             size_t toHash() const nothrow @safe { return 0; } }\nstruct S12 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S13 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S14 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S15 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S16 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S17 { bool opEquals(T : typeof(this))(T) { return false; } }\nstruct S18 { bool opEquals(T : typeof(this))(T) { return false; } }\n\nvoid fun()()\n{\n    { auto a = new S1[1]; }\n    { auto p = new S2(); }\n    { alias P = S3*; auto p = new P; }\n    { S4[int] aa; auto b = (aa == aa); }\n    { S5[] a; a.length = 10; }\n    { S6[] a; delete a; }\n    { S7[] a = []; }\n    { S8[] a = [S8.init]; }\n    { S9[int] aa = [1:S9.init]; }\n\n    { auto ti = typeid(S10[int]); }\n    { auto ti = typeid(int[S11]); }\n    { auto ti = typeid(S12[]); }\n    { auto ti = typeid(S13*); }\n    { auto ti = typeid(S14[3]); }\n    { auto ti = typeid(S15 function()); }\n    { auto ti = typeid(S16 delegate()); }\n    { auto ti = typeid(void function(S17)); }   // TypeInfo_Function doesn't have parameter types\n    { auto ti = typeid(void delegate(S18)); }   // ditto\n}\n\nstruct B12146\n{\n    bool opCmp(ubyte val) { return false; }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link13043a.d",
    "content": "module imports.lin13043a;\n\nstruct QualifiedNameTests\n{\n    struct Inner\n    {\n        const int opCmp(ref const Inner) { return 0; }\n    }\n\n    shared(const(Inner[string])[]) data;\n\n  version(bug)\n    size_t toHash() const\n    {\n        return typeid(typeof(data)).getHash(cast(const void*)&data);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link13394a.d",
    "content": "module imports.link13394a;\n\nclass A\n{\n    this() { }\n}\n\nclass Btpl(T) : T\n{\n    this()() { }\n\n    invariant() {}\n}\n\nalias B = Btpl!A;\n\nstruct Stpl()\n{\n    void func()() {}\n\n    invariant() {}\n}\n\nalias S = Stpl!();\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link13400a.d",
    "content": "module imports.link13400a;\n\nstruct BigInt\n{\n    this(string s) {}\n\n    // This template opEquals is determined to 'identity opEquals' by\n    // hasIdentityOpEquals() in clone.c with the speculative instantiation\n    // with dummy rvalue argument.\n    // Then BigInt.opEquals!().opEquals(const BigInt y) const pure is stored\n    // in template instance cache.\n    bool opEquals()(auto ref const BigInt y) const pure\n    {\n       return true;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link13415a.d",
    "content": "module imports.link13415a;\nstruct S(alias func)\n{\n    void call()\n    {\n        func();\n    }\n}\n\nextern(C) int printf(in char*, ...);\n\nvoid f(int i = 77)\n{\n    void g()\n    {\n        printf(\"i = %d;\\n\", i);\n        assert(i == 77);\n    }\n    S!g().call();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link14074x.d",
    "content": "module imports.link14074x;\n\nvoid put(R)(R)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link14074y.d",
    "content": "module imports.link14074y;\n\nvoid encode(R, E)(R sink, E value)\n{\n    encodeInt(sink);\n    encodeArray(sink, value);\n\n    static assert(false);\n}\n\nvoid encodeInt(R)(R sink)\n{\n    encodeLongType(sink);\n}\n\nvoid encodeLongType(R)(R sink)\n{\n    import imports.link14074x;\n    put(sink);\n}\n\nvoid encodeArray(R, A)(R sink, A)\n{\n    encodeArrayHead(sink,\n        __traits(compiles, { encode(cast(ubyte[])null, A.tupleof[0].init); }));\n}\n\nvoid encodeArrayHead(R)(R sink, ulong arrayLength)\n{\n    encodeLongType(sink);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link14074z.d",
    "content": "import imports.link14074z;\n\nvoid replaceAllWith(RE)(RE re)\nif (is(RE == S!()) || true)\n{\n    auto m = RegexMatch!()(re);\n}\n\nstruct RegexMatch()\n{\n    this(RE)(RE prog)\n    {\n        enum x = is(RE == S!());\n    }\n}\n\nstruct S()  // StaticRegex\n{\n    alias Matcher = BTM!();\n    alias M = Matcher!();\n}\n\nstruct Input()\n{\n    struct L\n    {\n        auto loopBack()\n        {\n            return Input();\n        }\n    }\n    auto loopBack()\n    {\n        return L();\n    }\n}\n\ntemplate BTM()  // BacktrackingMatcher\n{\n    struct BTM(Stream = Input!())\n    {\n        Stream s;\n        dchar front;\n\n        this(Stream stream)\n        {\n        }\n\n        auto bwdMatcher(ref BTM matcher)\n        {\n            alias BMTempl = .BTM!();\n            alias BM = BMTempl!(typeof(s.loopBack()));\n            auto m = BM(s.loopBack());\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link14541traits.d",
    "content": "module imports.link14541traits;\n\ntemplate hasElaborateAssign(S)\n{\n    static if (is(S == struct))\n    {\n        extern __gshared S lvalue;\n\n        enum hasElaborateAssign = is(typeof(S.init.opAssign(S.init))) ||\n                                  is(typeof(S.init.opAssign(lvalue)));\n    }\n    else\n    {\n        enum bool hasElaborateAssign = false;\n    }\n}\n\nvoid swap(T)(ref T lhs, ref T rhs) @trusted pure nothrow @nogc\n{\n    static if (hasElaborateAssign!T)\n    {\n    }\n    else\n    {\n    }\n}\n\ntemplate Tuple(Types...)\n{\n    struct Tuple\n    {\n        Types field;\n        alias field this;\n\n        this(Types values)\n        {\n            field[] = values[];\n        }\n\n        void opAssign(R)(auto ref R rhs)\n        {\n            static if (is(R : Tuple!Types) && !__traits(isRef, rhs))\n            {\n                // Use swap-and-destroy to optimize rvalue assignment\n                swap!(Tuple!Types)(this, rhs);\n            }\n            else\n            {\n                // Do not swap; opAssign should be called on the fields.\n                field[] = rhs.field[];\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link14588a.d",
    "content": "module imports.link14588a;\n\nvoid func(alias a)()\n{\n}\n\nclass A\n{\n    int i;\n\n    void all()()\n    {\n        func!(i)();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link14814a.d",
    "content": "module imports.link14814a;\n\nvoid fun0()\n{\n}\n\nvoid fun4()\n{\n    void function()[TypeInfo] funs;\n    funs[typeid(int)] = &fun0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link15194b.d",
    "content": "module imports.link15194b;\n\nauto fun()\n{\n    import imports.link15194std;\n    return new RedBlackTree!int;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link15194std.d",
    "content": "module imports.link15194std;\n\n// std.algorithm.setopts\n\n/* setUnion template function is instantiated in module link15194 as root,\n * and linked into executable.\n *\n * - In \"original case\", due to link to typeid(const RBRange!(RBNode!int*)),\n *   unSpeculative should be called for the type of typeid operand.\n *\n * - In \"additional case\", typeid(const RBRange!(RBNode!int*)*) returns\n *   TypeInfo_Pointer instance. But later its 'next' field access will reference\n *   RBRange instance. Therefore typeid should also unSpeculative the bottom struct\n *   of operand type.\n */\nversion (A)\n{\n    // additional case\n\n    TypeInfo setUnion(Rs...)(Rs )\n    {\n        return typeid(const Rs[0]*).next;\n\n        // semanticTypeInfo should also unSpaculate TypePointer.next.\n    }\n}\nelse\n{\n    // original case\n\n    struct SetUnion(Rs...)\n    {\n        pragma(msg, Rs);\n        Rs r;\n\n        // Rs[0] == RBRange!(RBNode!int*)\n        // Rs[1] == int[]\n\n        // size_t toHash() is implicitly generated by buildXtoHash.\n        // And from that,\n        //  typeid(const RBRange!(RBNode!int*))\n        // and\n        //  typeid(const int[])\n        // are referenced to invoke TypeInfo.getHash().\n    }\n\n    SetUnion!(Rs) setUnion(Rs...)(Rs )\n    {\n        return typeof(return)();\n    }\n}\n\n// std.container.rbtree\n\nstruct RBNode(V) {}\n\nstruct RBRange(N) {}\n\nclass RedBlackTree(Elem)\n{\n    alias Range = RBRange!(RBNode!Elem*);\n\n    Range opSlice()\n    {\n        return Range();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link2500a.d",
    "content": "module imports.link2500a;\n\nimport link2500;\nimport imports.link2500b;\n\nclass B\n{\n    S!A t;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link2500b.d",
    "content": "module imports.link2500b;\n\nstruct S(T)\n{\n    void foo() {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link2644a.d",
    "content": "module imports.link2644a;\n\nimport imports.link2644c;\nimport imports.link2644b;\n\nversion(X)\n    struct X { alias C!(bool) CA; }\nelse\n    alias C!(bool) CA;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link2644b.d",
    "content": "module imports.link2644b;\n\nimport imports.link2644c;\nimport imports.link2644a;\n\nversion(X)\n    struct X { alias C!(bool) CB; }\nelse\n    alias C!(bool) CB;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link2644c.d",
    "content": "module imports.link2644c;\n\nclass C(T)\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link7745b.d",
    "content": "module imports.link7745b;\nstruct C { auto asdfg() {} }\n\n// extreme test of bug 4820\nvoid nextis(W)(void delegate() dg = {}) {}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link8023b.d",
    "content": "module imports.link8023b;\nimport link8023;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/link9571a.d",
    "content": "module imports.link9571a;\nstruct MapResult(alias fun)\n{\n    void bar() { fun(0); }\n}\nauto foo()\n{\n    alias MapResult!(function(int c) => 0) M;\n    M m;\n    m.bar();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/linktypeinfo_file.d",
    "content": "module imports.linktypeinfo_file;\n\nauto filter(alias pred, R)(R r)\n{\n    return FilterResult!(pred, R)(r);\n}\n\nstruct FilterResult(alias pred, R)\n{\n    R r;\n    bool empty() { return r.empty; }\n    auto front() { return r.front; }\n    void popFront()\n    {\n        while (!r.empty && pred(r.front))\n            r.popFront();\n    }\n}\n\nstruct DirIterator\n{\n    int[] r;\n    @property bool empty() { return r.length == 0; }\n    @property auto front() { return r[0]; }\n    void popFront() { r = r[1..$]; }\n\n}\n\nauto dirEntries(string path)\n{\n    bool f(int de) { return 1; }\n    return filter!f(DirIterator());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/m1a.d",
    "content": "module imports.m1a;\n\nimport m1;\n\nA aFunc( aliasM1 f )\n{\n  return f(); // line 7\n}\n\n//A aFunc( A function() f );\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/m8668a.d",
    "content": "module imports.m8668a;\n\nvoid split8668(T)(T k)\n    if(is(T : string))\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/m8668b.d",
    "content": "module imports.m8668b;\n\nvoid split8668(T)(T k)\n    if(is(T : int))\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/m8668c.d",
    "content": "//drop in another one to pull split from m2\nmodule imports.m8668c;\n\npublic import imports.m8668b: split8668;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/mangle10077.d",
    "content": "module imports.mangle10077;\n\n//UTF-8 chars\n__gshared pragma(mangle, \"test_эльфийские_письмена_9\") ubyte test10077i_v;\n\nvoid setTest10077i()\n{\n    test10077i_v = 42;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/mod2.d",
    "content": "// mod2.d\n\nmodule imports.mod2;\n\nimport mod1;\n\nextern(C) int printf(const char*, ...);\n\nvoid greet()\n{\n printf(name().ptr);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/module_with_tests.d",
    "content": "module imports.module_with_tests;\nunittest {} unittest { assert(false); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ovs1528a.d",
    "content": "module imports.ovs1528a;\n\nauto func1528() { return 1; }\nauto func1528(T)(T) if (is(T : real)) { return 2; }\n\nauto bunc1528(T)(T) if (is(T : real)) { return 2; }\nauto bunc1528() { return 1; }\n\nauto vunc1528(int) { return 1; }\nauto wunc1528(T)(T[]) { return 2; }\n\nauto opUnary1528(string op : \"+\")(int) { return 1; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ovs1528b.d",
    "content": "module imports.ovs1528b;\n\nauto func1528(string) { return 3; }\nauto func1528(T)(T[]) { return 4; }\n\nauto bunc1528(T)(T[]) { return 4; }\nauto bunc1528(string) { return 3; }\n\nauto vunc1528(T)(T[]) { return 2; }\nauto wunc1528(int) { return 1; }\n\nauto opUnary1528(string op : \"-\")(int) { return 2; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std11069array.d",
    "content": "module imports.std11069array;\n\n@property bool empty(T)(in T[] a) @safe pure nothrow\n{\n    return !a.length;\n}\n\nvoid popFront(T)(ref T[] a) @safe pure nothrow\n{\n    a = a[1 .. $];\n}\n\n@property ref T front(T)(T[] a) @safe pure nothrow\n{\n    return a[0];\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std11069container.d",
    "content": "module imports.std11069container;\n\nimport imports.std11069range, imports.std11069typecons;\n\nstruct BinaryHeap(Store)\nif (isInputRange!Store)\n//if (isRandomAccessRange!Store)\n{\n    // The payload includes the support store and the effective length\n    private RefCounted!(Tuple!(Store)) _payload;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std11069range.d",
    "content": "module imports.std11069range;\n\npublic import imports.std11069array;\n\ntemplate isInputRange(R)\n{\n    enum bool isInputRange = is(typeof(\n    (inout int = 0)\n    {\n        R r = void;       // can define a range object\n        if (r.empty) {}   // can test for empty\n        r.popFront();     // can invoke popFront()\n        auto h = r.front; // can get the front of the range\n    }));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std11069typecons.d",
    "content": "module imports.std11069typecons;\n\nimport imports.std11069array;\n\ntemplate Tuple(Specs...)\n{\n    struct Tuple\n    {\n        Specs expand;\n\n        string toString()\n        {\n            expand[0].empty;\n            expand[0].front;\n            expand[0].popFront();\n\n            return null;\n        }\n    }\n}\n\n\nstruct RefCounted(T)\n{\n    T payload;\n\n    ~this()\n    {\n        //.destroy(_refCounted._store._payload);\n        //auto init = typeid(payload).init();\n        payload.toString(); // refer Tuple.toString symbol?\n    }\n\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std11863bitmanip.d",
    "content": "module imports.std11863bitmanip;\n\nimport imports.std11863format : FormatSpec;\n\nstruct BitArray\n{\n    void toString(scope void delegate(const(char)[]) sink,\n                  FormatSpec!char fmt) const\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std11863conv.d",
    "content": "module imports.std11863conv;\n\nimport imports.std11863format;\n\ntemplate to(T)\n{\n    T to(A...)(A args)\n    {\n        return toImpl!T(args);\n    }\n}\n\nT toImpl(T, S)(S value)\n{\n    static if (is(S == int) && is(T == string))\n    {\n        // other integral-to-string conversions with default radix\n        return toImpl!(T, S)(value, 10);\n    }\n    else\n        static assert(0);\n}\n\n@trusted pure T toImpl(T, S)(S value, uint radix/*, LetterCase letterCase = LetterCase.upper*/)\n{\n    static assert(is(S == int) && is(T == string));\n\n    alias EEType = char/*Unqual!(typeof(T.init[0]))*/;\n\n    T toStringRadixConvert(size_t bufLen, uint radix = 0, bool neg = false)(uint runtimeRadix = 0)\n    {\n        static if (neg)\n            ulong div = void, mValue = cast(uint)(-value);\n        else\n            uint/*Unsigned!(Unqual!S)*/ div = void, mValue = cast(uint)(value);\n\n        size_t index = bufLen;\n        EEType[bufLen] buffer = void;\n        char baseChar = /*letterCase == LetterCase.lower ? 'a' : */'A';\n        char mod = void;\n\n        do\n        {\n            static if (radix == 0)\n            {\n                div = cast(S)(mValue / runtimeRadix );\n                mod = cast(ubyte)(mValue % runtimeRadix);\n                mod += mod < 10 ? '0' : baseChar - 10;\n            }\n            else static if (radix > 10)\n            {\n                div = cast(S)(mValue / radix );\n                mod = cast(ubyte)(mValue % radix);\n                mod += mod < 10 ? '0' : baseChar - 10;\n            }\n            else\n            {\n                div = cast(S)(mValue / radix);\n                mod = mValue % radix + '0';\n            }\n            buffer[--index] = cast(char)mod;\n            mValue = div;\n        } while (mValue);\n\n        static if (neg)\n        {\n            buffer[--index] = '-';\n        }\n        return cast(T)buffer[index .. $].dup;\n    }\n\n    //enforce(radix >= 2 && radix <= 36, new ConvException(\"Radix error\"));\n\n    switch(radix)\n    {\n        case 10:\n            if (value < 0)\n                return toStringRadixConvert!(S.sizeof * 3 + 1, 10, true)();\n            else\n                return toStringRadixConvert!(S.sizeof * 3, 10)();\n        //case 16:\n        //    return toStringRadixConvert!(S.sizeof * 2, 16)();\n        //case 2:\n        //    return toStringRadixConvert!(S.sizeof * 8, 2)();\n        //case 8:\n        //    return toStringRadixConvert!(S.sizeof * 3, 8)();\n        default:\n            assert(0);//return toStringRadixConvert!(S.sizeof * 6)(radix);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std11863format.d",
    "content": "module imports.std11863format;\n\nimport imports.std11863bitmanip;\nimport imports.std11863conv;\n\nstruct FormatSpec(Char)\n{\n    string toString()\n    {\n        // text(width)\n        return to!string(1);    // instantiate toImpl!(string, int)\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std12010container.d",
    "content": "module imports.std12010container;\nstruct Array(T)\n{\n    private struct Payload\n    {\n        size_t _capacity;\n        T[] _payload;\n\n        ~this()\n        {\n        }\n\n        this(this)\n        {\n        }\n    }\n    private alias RefCounted!(Payload) Data;\n    private Data _data;\n\n    bool opEquals(ref const Array rhs) const\n    {\n        return true;\n    }\n}\n\n\nstruct BinaryHeap(Store)\n{\n    private static struct Data\n    {\n        Store _store;\n        size_t _length;\n    }\n    private RefCounted!(Data) _payload;\n}\n\n\nstruct RefCounted(T)\n{\n    struct RefCountedStore\n    {\n        private struct Impl\n        {\n            T _payload;\n            size_t _count;\n        }\n\n        private Impl* _store;\n\n    }\n    RefCountedStore _refCounted;\n\n    this(this)\n    {\n    }\n\n    ~this()\n    {\n        .destroy(_refCounted._store._payload);\n    }\n\n    void opAssign(typeof(this) rhs)\n    {\n    }\n\n    void opAssign(T rhs)\n    {\n        typeid(T).destroy(&rhs);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std15017variant.d",
    "content": "module imports.std15017variant;\n\nstruct VariantN(size_t maxDataSize)\n{\n    VariantN opAssign() { return this; }\n\n    bool opEquals(T)(T) { return true; }\n\n    bool opEquals(T)(ref const T) const { return true; }\n\n    size_t toHash() const nothrow @trusted { return 0;  }\n\n    ~this() {}\n}\n\nalias Variant1 = VariantN!(1);\nalias Variant2 = VariantN!(2);\nalias Variant3 = VariantN!(3);\nalias Variant4 = VariantN!(4);\nalias Variant5 = VariantN!(5);\nalias Variant6 = VariantN!(6);\nalias Variant7 = VariantN!(7);\nalias Variant8 = VariantN!(8);\nalias Variant9 = VariantN!(9);\nalias Variant10 = VariantN!(10);\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std15021conv.d",
    "content": "module imports.std15021conv;\n\nT to(T, A...)(A args)\n{\n    return toImpl!T(args);\n}\n\nT toImpl(T, S)(S value)\n{\n    import imports.std15021format;\n    enforceValidFormatSpec!(S, char)('c');\n    return \"\";\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std15021format.d",
    "content": "module imports.std15021format;\n\nT enforceEx(T)(T value, lazy string msg = \"\")\n{\n    if (!value) throw new Exception(msg);\n    return value;\n}\n\nvoid enforceValidFormatSpec(T, Char)(int spec)\n{\n    enforceEx(spec == 's');\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/std15030algo.d",
    "content": "module imports.std15030algo;\n\ntemplate filter(alias pred)\n{\n    auto filter(R)(R r)\n    {\n        return FilterResult!(pred, R)(r);\n    }\n}\n\nprivate struct FilterResult(alias pred, R)\n{\n    R _input;\n\n    this(R r)\n    {\n        _input = r;\n        while (_input.length != 0 && !pred(_input[0]))\n        {\n            _input = _input[1..$];\n        }\n    }\n\n    @property bool empty() { return _input.length == 0; }\n\n    @property auto ref front() { return _input[0]; }\n\n    void popFront()\n    {\n        do\n        {\n            _input = _input[1..$];\n        } while (_input.length != 0 && !pred(_input[0]));\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/template13478a.d",
    "content": "module imports.template13478a;\n\nimport gcc.attribute;\n\n@attribute(\"noinline\") bool foo(T)() {\n    // Make sure this is not inlined so template13478.o actually\n    // needs to reference it.\n    return false;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/template13478b.d",
    "content": "import imports.template13478b;\n\nimport imports.template13478a;\n\n// Note that foo is only used in the template constraint here.\nT barImpl(T)(T t) if (is(typeof({ foo!T(); }))) { return t; }\nint bar(int a) { return barImpl(a); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/template2962a.d",
    "content": "module imports.template2962a;\nimport template2962;\n\nalias bug2962comment36!() bug2962_comment36_alias;\n\nvoid main() {\n    funcC!(bool)(1.0);\n    foo!int(0);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/template_ovs1.d",
    "content": "module imports.template_ovs1;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1900\n// template overload set\n\nauto foo1900a(int num) { return 1; }\nauto foo1900b(T)(T arg) if (is(T : const(char)[])) { return 2; }\n\nauto bar1900a(T)(T arg) if (is(T : double)) { return 1; }\nauto bar1900b(T)(T arg) if (is(T : const(char)[])) { return 2; }\n\nauto baz1900(T)(T arg) if (is(T : double)) { return 1; }\nauto baz1900(T)(T arg) if (is(T : int[int])) { return 2; }\n\nauto bad1900(string op)() if (op == \"++\") { return 1; }\n\nmixin template Mix1900_A()\n{\n    auto mixfooa() { return 1; }\n    auto mixfoob(T)(T) { return 2; }\n\n    mixin Mix1900_SubA;\n}\n\nmixin template Mix1900_SubA()\n{\n    auto mixsubfooa() { return 1; }\n    auto mixsubfoob(T)(T) { return 2; }\n}\n\nauto merge1900(T)(int)\n{\n    return 1;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1900\n\nclass AClass1900 {}\ntemplate Traits1900(T : AClass1900) { enum name = \"AClass\"; }\n\n\nvoid Value1900a() {}\ntemplate Value1900a(T) if (is(T == double)) { enum Value1900a = 1; }\n\ntemplate Value1900b(T) if (is(T == double)) { enum Value1900b = 1; }\nvoid Value1900b() {}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8352\n\nRange remove8352a(alias pred, Range)(Range range) { return range; }\nvoid remove8352b(in char[] name) {}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10658\n\ntemplate Val10658(int n) { enum Val10658 = 1; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/template_ovs2.d",
    "content": "module imports.template_ovs2;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1900\n// template overload set\n\nauto foo1900a(T)(T arg) if (is(T : const(char)[])) { return 2; }\nauto foo1900b(int num) { return 1; }\n\nauto bar1900a(T)(T arg) if (is(T : const(char)[])) { return 2; }\nauto bar1900b(T)(T arg) if (is(T : double)) { return 1; }\n\nauto baz1900(T)(T arg) if (is(T : Object)) { return 3; }\nauto baz1900(T)(T arg) if (is(T : const(char)[])) { return 4; }\n\nauto bad1900(string op)() if (op == \"++\") { return 2; }\n\nmixin template Mix1900_B()\n{\n    auto mixfooa(T)(T) { return 2; }\n    auto mixfoob() { return 1; }\n\n    mixin Mix1900_SubB;\n}\n\nmixin template Mix1900_SubB()\n{\n    auto mixsubfooa(T)(T) { return 2; }\n    auto mixsubfoob() { return 1; }\n}\n\nauto merge1900(T)(string)\n{\n    return 2;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1900\n\nclass BClass1900 {}\ntemplate Traits1900(T : BClass1900) { enum name = \"BClass\"; }\nstring func1900(BClass1900 b) { return \"BClass\"; }\n\nvoid Value1900a() {}\ntemplate Value1900a(T) if (is(T == string)) { enum Value1900a = 2; }\n\ntemplate Value1900b(T) if (is(T == string)) { enum Value1900b = 2; }\nvoid Value1900b() {}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8352\n\nvoid remove8352a(in char[] name) {}\nRange remove8352b(alias pred, Range)(Range range) { return range; }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10658\n\ntemplate Val10658(long n) { enum Val10658 = 2; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/template_ovs3.d",
    "content": "module imports.template_ovs3;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1900\n// template overload set\n\nimport imports.template_ovs1;\nimport imports.template_ovs2;\n\nstruct S1900\n{\n    alias .foo1900a foo1900a;\n    alias .foo1900b foo1900b;\n\n    alias .bar1900a bar1900a;\n    alias .bar1900b bar1900b;\n\n    alias .baz1900 baz1900;\n\n    alias .bad1900 bad1900;\n\n    // This is a kind of Issue 1528, cannot make overload contains both templates and functions\n    //void funcF() {}\n    //void funcT(T)(T) {}\n    //alias funcF funca;   // make overload with alias declaration\n    //alias funcT funca;\n    //alias funcT funcb;   // make overload with alias declaration\n    //alias funcF funcb;\n\n    mixin Mix1900_A a;\n    mixin Mix1900_B b;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1900\n\nstruct Traits1900(T) if (!is(T == class)) { enum name = \"any\"; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test10441b.d",
    "content": "\npublic import test10441c;\n\nauto foo()()\n    if (boo(1))\n{\n    return 1;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test10441c.d",
    "content": "\nauto boo(T)(T t)\n{\n    return 1;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test10573a.d",
    "content": "module imports.test10573a;\n\nabstract class base {}\nclass mysql : base {}\n\nclass handler\n{\n    private mysql[int] mysql_servers;\n    public void foo()\n    {\n        base[int] hServers = cast(base[int])mysql_servers;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test10736a.d",
    "content": "module imports.test10736a;\n\nversion(A) import std.range;\nelse       import imports.test10736c;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test10736b.d",
    "content": "module imports.test10736b;\n\nversion(A) import std.range;\nelse       import imports.test10736c;\n\nvoid main()\n{\n    int[] arr = [0, 1, 2, 3];\n    auto x = chunks(arr, 4);  // error\n\n    import core.stdc.stdio;\n    printf(\"success\\n\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test10736c.d",
    "content": "module imports.test10736c;\n\nstruct Chunks(Source)\n{\n    this(Source source, size_t chunkSize)\n    {\n        _source = source;\n        _chunkSize = chunkSize;\n    }\n\n    typeof(this) opSlice(size_t, size_t)\n    {\n        return chunks(_source, _chunkSize);\n    }\n\nprivate:\n    Source _source;\n    size_t _chunkSize;\n}\n\nChunks!Source chunks(Source)(Source source, size_t chunkSize)\n{\n    return typeof(return)(source, chunkSize);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test10a.d",
    "content": "module imports.test10a;\n\nvoid init()\n{\n    it[0] = 32;\n}\n\nint[1] it;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test11039b.d",
    "content": "\nmodule imports.test11039b;\n\nimport test11039;\n\nstatic anotherGlobalField = SomeStruct!string(\"Hello Again!\");\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test11745b.d",
    "content": "module imports.test11745b;\n\nunittest \n{\n\t\t\n}\n\nprivate unittest \n{\n\t\n}\n\nprivate:\nunittest \n{\n\t\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test11931a.d",
    "content": "module imports.test11931a;\n\nimport std.stdio;\n\nimport imports.test11931d;\nimport imports.test11931b;\n\nfinal class Engine\n{\npackage:\n    mixin GUIManager;\npublic:\n    Signal!void onLeftUp;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test11931b.d",
    "content": "module imports.test11931b;\n\nimport imports.test11931c;\nimport imports.test11931d;\n\nclass GUIElement\n{\npublic:\n    Signal!void onSubmit;\n}\n\nmixin template GUIManager()\n{\npublic:\n    void foo()\n    {\n        onLeftUp.add(&guiUp);\n    }\n\n    void guiUp() {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test11931c.d",
    "content": "module imports.test11931c;\n\nimport imports.test11931a;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test11931d.d",
    "content": "module imports.test11931d;\n\nimport std.array;\nimport std.algorithm;\n\nstruct ConnectionPoint\n{\n    void disconnect()\n    {\n        if(_f)\n        {\n            _f();\n            _f = null;\n        }\n    }\n    private void delegate() _f;\n}\n\nstruct Signal(T, A...)\n{\n    ConnectionPoint add(D f)\n    {\n        auto rf = { _arr = _arr.filter!(a => a != f).array; };\n        return ConnectionPoint();\n    }\n\nprivate:\n    alias D = T delegate(A);\n    D[] _arr;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test13a.d",
    "content": "module imports.test13a;\n\nextern(C) int printf(const char*, ...);\n\npublic alias bool boolean;\npublic alias int Order;\npublic const Order LESS_THAN    = -1;\npublic const Order EQUALS_TO    = 0;\npublic const Order GREATER_THAN = +1;\ntemplate Ordinal(T) {\n    public T min(T left, T right) {\n        return left < right ? left: right;\n    }\n    public T max(T left, T right) {\n        return left > right ? left: right;\n    }\n    public T clamp(T item, T lower, T upper)\n    in {\n        assert(lower <= upper);\n    } body {\n        return max(min(item, upper), lower);\n    }\n}\ntemplate TPair(T, U) {\n    public class Pair {\n        private T _left;\n        private U _right;\n        public this(T left, U right) {\n            this._left = left;\n            this._right = right;\n        }\n        public T left() {\n            return this._left;\n        }\n        public U right() {\n            return this._right;\n        }\n        override public boolean opEquals(Object obj) {\n            Pair other = cast(Pair) obj;\n            if (other !is null) {\n                return (left() == other.left()) && (right() == other.right());\n            } else {\n                return false;\n            }\n        }\n    }\n}\nunittest {\n    alias TPair!(char, char) charPair;\n    charPair.Pair pairA = new charPair.Pair('a', 'b');\n    charPair.Pair pairB = new charPair.Pair('a', 'b');\n    assert(pairA == pairB);\n    printf(\"Pair tests passed!\\r\\n\");\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test14901a.d",
    "content": "module imports.test14901a;\n\n//extern(C) int printf(const char*, ...);\n\nextern extern(C) __gshared static int initCount;\n\nint make(string s)()\n{\n    __gshared static int value;\n\n    struct WithCtor\n    {\n        shared static this()\n        {\n            //printf(\"%s\\n\", s.ptr);\n            initCount++;\n        }\n    }\n\n    return value;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test14901b.d",
    "content": "module imports.test14901b;\n\nimport imports.test14901a;\n\nalias bar = make!\"bar\";\n\nstruct User(int id)\n{\n    int foo()\n    {\n        return bar;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test14901c.d",
    "content": "module imports.test14901c;\n\nimport imports.test14901b;\n\nshared static this() {}\n\nvoid caller1()\n{\n    User!1 u;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test14901d.d",
    "content": "module imports.test14901d;\n\nimport imports.test14901b;\n\nvoid caller2()\n{\n    User!2 u;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test15777a.d",
    "content": "void fun() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test15777b.d",
    "content": "void fun() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test18322import.d",
    "content": "module test18322import;\nvoid fun(string templateFileFullPath = __FILE_FULL_PATH__,\n    string templateFile = __FILE__)(string expectedFilename, string fileFullPath = __FILE_FULL_PATH__)\n{\n    // make sure it is an absolute path\n    version(Windows)\n        assert(fileFullPath[1..3] == \":\\\\\");\n    else\n        assert(fileFullPath[0] == '/');\n\n    assert(templateFileFullPath == fileFullPath);\n    assert(fileFullPath[$ - expectedFilename.length .. $] == expectedFilename);\n    assert(fileFullPath[$ - templateFile.length .. $] == templateFile);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test18868_fls.d",
    "content": "module imports.test18868_fls;\n\ntemplate FLS(T)\n{\n    int ctorcount = 0;\n    int dtorcount = 0;\n    int sharedctorcount = 0;\n    int shareddtorcount = 0;\n\n    static this()\n    {\n        assert(ctorcount == 0);\n        ctorcount += 1;\n    }\n\n    static ~this()\n    {\n        assert(dtorcount == 0);\n        dtorcount += 1;\n    }\n\n    shared static this()\n    {\n        assert(sharedctorcount == 0);\n        sharedctorcount += 1;\n    }\n\n    shared static ~this()\n    {\n        assert(shareddtorcount == 0);\n        shareddtorcount += 1;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test21a.d",
    "content": "module imports.test21a;\n\nstruct TC(T)\n{\n void method()\n {\n     void inline_function()\n     {\n     }\n }\n}\n\ntemplate TB(T)\n{\n alias TC!(T) tc_instance;\n}\n\nstruct TA(T)\n{\n mixin TB!(T);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test24a.d",
    "content": "module imports.test24a;\n\npublic import std.string;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test24b.d",
    "content": "module imports.test24b;\n\npublic import std.string;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test27a.d",
    "content": "module imports.test27a;\n\nimport std.variant;\n\nclass myClass(T) {\npublic:\n    void func(T v) {\n        Variant b = Variant(v);\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test29a.d",
    "content": "module imports.test29a;\n\nprivate import imports.test29b;\n\ndeprecated alias imports.test29b.qwert qwert;\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test29b.d",
    "content": "module imports.test29b;\n\nconst int qwert = 42;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test31a.d",
    "content": "module imports.test31a;\n\ntemplate Baz() {\n    private void privfunc(){ }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test32a.d",
    "content": "module imports.test32a;\n\nstruct S{\n  int i;\n}\n\nint f(){\n  return S.sizeof; // OK\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test35a.d",
    "content": "module imports.test35a;\n\ntemplate ElemTypeOf( T )\n{\n    alias typeof(T.init[0]) ElemTypeOf;\n}\n\ntemplate removeIf_( Elem, Pred )\n{\n    size_t fn( Elem[] buf, Pred pred )\n    {\n\tvoid exch( size_t p1, size_t p2 )\n\t{\n\t    Elem t  = buf[p1];\n\t    buf[p1] = buf[p2];\n\t    buf[p2] = t;\n\t}\n\n\tsize_t cnt = 0;\n\n\tfor( size_t pos = 0, len = buf.length; pos < len; ++pos )\n\t{\n\t    if( pred( buf[pos] ) )\n\t\t++cnt;\n\t    else\n\t\texch( pos, pos - cnt );\n\t}\n\treturn buf.length - cnt;\n    }\n}\n\ntemplate removeIf( Buf, Pred )\n{\n    size_t removeIf( Buf buf, Pred pred )\n    {\n\treturn removeIf_!(ElemTypeOf!(Buf), Pred).fn( buf, pred );\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test38a.d",
    "content": "module imports.test38a;\n\nint bar(int i)\n{\n    return i * i;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test39a.d",
    "content": "module imports.test39a;\n\nextern (C) int printf (const char*, ...);\n\nclass Test (T)\n{\n        final void show (in T[] msg)\n        {\n                printf (\"%.*s\\n\", msg.length, msg.ptr);\n        }\n}\n\nTest!(char) Global;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test3a.d",
    "content": "module imports.test3a;\n\nimport imports.test3b;\n\nextern(C) int printf(const char*, ...);\n\nclass Afoo\n{\n    static this()\n    {\n\tprintf(\"Afoo()\\n\");\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test3b.d",
    "content": "module imports.test3b;\n\nimport imports.test3a;\n\nclass Bfoo\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test40a.d",
    "content": "module imports.test40a;\n\nimport std.stdio;\n\ntemplate Mix()\n{\n    static void foobar()\n    {\n\tauto context = new Context;\n        auto ts = context.toString;\n\tprintf(\"context: %.*s %p\\n\", ts.length, ts.ptr, context);\n\tcontext.func!(typeof(this))();\n\tprintf(\"returning from opCall\\n\");\n    }\n}\n\n\nclass Bar\n{\n    mixin Mix;\n}\n\n\nvoid someFunc(string z)\n{\n    printf(\"str length: %d\\n\", z.length);\n    printf(\"str: '%.*s'\\n\", z.length, z.ptr);\n}\n\n\nclass Context\n{\n    void func(T)()\n    {\n\tprintf(\"<context.func\\n\");\n\tprintf(\"thisptr: %p\\n\", this);\n\tsomeFunc(`a`);\n\tprintf(\"context.func>\\n\");\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test41a.d",
    "content": "module imports.test41a;\n\nvoid foo()\n{\n        assert(false, \"GO\");\n}\n\npublic void func(T)()\n{\n        assert(false, \"Blah\");\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test44a.d",
    "content": "module imports.test44a;\n\nimport test44;\n\nenum DAY { SUN, MON, TUE, WED, THU, FRI, SAT }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test45a.d",
    "content": "module imports.test45a;\n\nimport std.stdio;\n\nint foo()\n{\n    printf(\"foo()\\n\");\n    return 1;\n}\n\n\nint bar(T)(T t)\n{\n    printf(\"bar(t)\\n\");\n    return 3;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test45b.d",
    "content": "module imports.test45b;\n\nimport std.stdio;\n\nint foo(int i)\n{\n    printf(\"foo(int)\\n\");\n    return 2;\n}\n\nint bar(T)(T t, int i)\n{\n    printf(\"bar(t,i)\\n\");\n    return 4;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test46a.d",
    "content": "module imports.test46a;\n\nprivate import imports.test46c;\n\ninterface I\n{\n    void anything();\n}\n\nclass A : I\n{\n    private C!(char) c;\n    this() { c = new C!(char) (); }\n    void anything() {}\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test46b.d",
    "content": "module imports.test46b;\n\nprivate import imports.test46c;\n\nclass B\n{\n    private C!(char) c;\n    this() { c = new C!(char); }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test46c.d",
    "content": "module imports.test46c;\n\nclass C(T)\n{\n    void foo() { }\n} \n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test48a.d",
    "content": "module imports.test48a;\n\nstruct S\n{\n    int a = 1;\n    int b = 2;\n  private:\n    int c = 3;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test49a.d",
    "content": "module imports.test49a;\n\nimport std.stdio;\n\nint x;\n\ntemplate Foo(T)\n{\n   static this()\n   {\n\tprintf(\"static this()\\n\");\n\tassert(x == 0);\n\tx++;\n   }\n\n   static ~this()\n   {\n\tprintf(\"static ~this()\\n\");\n\tassert(x == 1);\n\tx--;\n   }\n}\n\nvoid baz()\n{\n    alias Foo!(int) bar;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test57a.d",
    "content": "module imports.test57a;\nimport imports.test57b;\n\n// works - even fixes the error from below!\n// C!(int) x;\n\n// doesn't work\nvoid foo() { C!(int) x; }\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test57b.d",
    "content": "module imports.test57b;\nclass C(T) { struct X {} }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test58a.d",
    "content": "module imports.test58a;\n\nvoid foo(T)() {\n   long[] a;\n   a[] = -a[];\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test61a.d",
    "content": "module imports.test61a;\n\nint bar()\n{\n    return 12;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test7494a.d",
    "content": "module imports.test7494a;\n\ntemplate map(alias fun)\n{\n    auto map(R)(R range) { return [4,5,6]; }\n}\n\nauto writeln(A...)(A args)\n{\n    return [7,8,9];\n}\n\nauto foo() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test8997a.d",
    "content": "module imports.test8997a;\n\nclass A\n{\n    A[string] foobar;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/test9271a.d",
    "content": "module imports.test9271a;\n\nbool any(alias pred, Range)(Range range)\n{\n    return true;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/testkwd_file.d",
    "content": "module imports.testkwd;\n\n/****************************************/\n\nversion(Windows) enum sep = \"\\\\\";  else enum sep = \"/\";\n\nenum thatFile = \"runnable\"~sep~\"imports\"~sep~\"testkwd_file.d\";\nenum thatMod  = \"imports.testkwd\";\n//enum thatLine;\nenum thatFunc  = \"imports.testkwd.getCalleeFunc\";\nenum thatFunc2 = `string imports.testkwd.getCalleeFunc2(int x = 1, string s = \"hello\")`;\n\nstring getCalleeFile() { return __FILE__; }\nulong  getCalleeLine() { return __LINE__; }         enum thatLine = 14;\nstring getCalleeMod()  { return __MODULE__; }\nstring getCalleeFunc() { return __FUNCTION__; }\nstring getCalleeFunc2(int x = 1, string s = \"hello\") { return __PRETTY_FUNCTION__; }\n\n/****************************************/\n\nstring getFuncArgFile (string name = __FILE__           ) { return name; }\nulong  getFuncArgLine (ulong  lnum = __LINE__           ) { return lnum; }\nstring getFuncArgMod  (string name = __MODULE__         ) { return name; }\nstring getFuncArgFunc (string name = __FUNCTION__       ) { return name; }\nstring getFuncArgFunc2(string name = __PRETTY_FUNCTION__) { return name; }\n\nstring getFuncTiargFile (string name = __FILE__           )() { return name; }\nulong  getFuncTiargLine (ulong  lnum = __LINE__           )() { return lnum; }\nstring getFuncTiargMod  (string name = __MODULE__         )() { return name; }\nstring getFuncTiargFunc (string name = __FUNCTION__       )() { return name; }\nstring getFuncTiargFunc2(string name = __PRETTY_FUNCTION__)() { return name; }\n\ntemplate getInstTiargFile (string name = __FILE__           ) { enum getInstTiargFile  = name; }\ntemplate getInstTiargLine (ulong  lnum = __LINE__           ) { enum getInstTiargLine  = lnum; }\ntemplate getInstTiargMod  (string name = __MODULE__         ) { enum getInstTiargMod   = name; }\ntemplate getInstTiargFunc (string name = __FUNCTION__       ) { enum getInstTiargFunc  = name; }\ntemplate getInstTiargFunc2(string name = __PRETTY_FUNCTION__) { enum getInstTiargFunc2 = name; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/testmangle.d",
    "content": "// helper for mangling tests with back references\n\nmodule imports.testmangle;\n\npublic import core.demangle : demangle, demangleType;\n\n// detect mangle version\nprivate\n{\n    struct Detect;\n    Detect* detectMangle(Detect*);\n    void DetectTmpl(T)() {}\n}\n\npragma(msg,detectMangle.mangleof);\nstatic if(detectMangle.mangleof == \"_D7imports10testmangle12detectMangleFPSQL3H6DetectZQ1e\")\n    enum { BackRefs = true, BackRefSymbols = true }\nelse static if(detectMangle.mangleof == \"_D7imports10testmangle12detectMangleFPSQBlQBg6DetectZQq\")\n    enum { BackRefs = true, BackRefSymbols = false }\nelse static if(detectMangle.mangleof == \"_D7imports10testmangle12detectMangleFPS7imports10testmangle6DetectZPS7imports10testmangle6Detect\")\n    enum { BackRefs = false, BackRefSymbols = false }\nelse\n    static assert(false, \"unknown mangling\");\n\nprivate enum tmplMangle = (DetectTmpl!int).mangleof;\npragma(msg,tmplMangle);\nstatic if(tmplMangle[0..40] == \"_D7imports10testmangle__T10DetectTmplTiZ\")\n    enum HasTemplateLength = false;\nelse static if(tmplMangle[0..42] == \"_D7imports10testmangle18__T10DetectTmplTiZ\")\n    enum HasTemplateLength = true;\nelse\n    static assert(false, \"unknown mangling\");\n\npragma(msg,BackRefs);\npragma(msg,BackRefSymbols);\n\nstatic if (BackRefs)\n{\n    string tl(string s)() { return null; }\n    string id(string s, string r, string r2 = null)() { return BackRefSymbols && r2 !is null ? r2 : r; }\n}\nelse\n{\n    string tl(string s)() { return HasTemplateLength ? s : null; }\n    string id(string s, string r, string r2 = null)() { return s; }\n}\n\nbool equalDemangle(string m1, string m2)\n{\n    auto dm1 = demangle(m1);\n    auto dm2 = demangle(m2);\n    return dm1 == dm2;\n}\n\nstring unsignedToString(ulong x)\n{\n    string s;\n    s ~= cast(char)('0' + (x % 10));\n    x /= 10;\n    while (x > 0)\n    {\n        s = cast(char)('0' + (x % 10)) ~ s;\n        x /= 10;\n    }\n    return s;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/testminitAA.d",
    "content": "module imports.testminitAA;\n\nimport core.stdc.stdio;\nint aa;\n\nstatic this()\n{\n    printf(\"AA\\n\");\n    aa = 1;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/testminitBB.d",
    "content": "module imports.testminitBB;\n\nimport core.stdc.stdio;\nint bb;\n\nstatic this()\n{\n    printf(\"BB\\n\");\n    bb = 1;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/testmod1a.d",
    "content": "module imports.testmod1a;\n\nimport testmod1;\n\nvoid bar2() {\n  Foo!(int) w;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/testmod1b.d",
    "content": "module imports.testmod1b;\n\nimport testmod1;\n\nvoid bar3() {\n  Foo!(int) w;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/testmod2a.d",
    "content": "module imports.testmod2a;\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=1904\n\n// testmod.d\nprivate void bar(alias a)() {}\n\nvoid foo(alias a)() {\n    .bar!(a)();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/tlsa.d",
    "content": "module imports.tlsa;\n\nimport core.stdc.stdio;\n\nint foo()()\n{\n    static int z = 7;\n    return ++z;\n}\n\n/*************************************/\n\n\nint abc4(T)(T t)\n{\n    static T qqq;\t\t// TLS comdef\n    static       T rrr;\t// comdef\n    static T sss = 8;\t// TLS comdat\n    static       T ttt = 9;\t// comdat\n    printf(\"qqq = %d, rrr = %d, sss = %d, ttt = %d\\n\", qqq, rrr, sss, ttt);\n    qqq += 2;\n    rrr += 3;\n    sss += 4;\n    ttt += 5;\n    return t + qqq + rrr + sss + ttt;\n}\n\nint bar4()\n{\n    return abc4(4);\n}\n\n/*************************************/\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/traits_getUnitTests_import.d",
    "content": "module imports.traits_getUnitTests_import;\n\nunittest\n{\n    assert(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ufcs5a.d",
    "content": "module imports.ufcs5a;\n\nauto f5a1(int)    { return 1; }\nauto f5a2(string) { return 2; }\nauto f5a3(double) { return 3; }\nalias f5a4 = f5a1, f5a4 = f5a2;\nalias f5a5 = f5a3, f5a5 = f5a4;\n\n@property p5a1(int)    { return 1; }    @property p5a1(int,    int) { return 1; }\n@property p5a2(string) { return 2; }    @property p5a2(string, int) { return 2; }\n@property p5a3(double) { return 3; }    @property p5a3(double, int) { return 3; }\nalias p5a4 = p5a1, p5a4 = p5a2;         alias p5a4 = p5a1, p5a4 = p5a2;\nalias p5a5 = p5a3, p5a5 = p5a4;         alias p5a5 = p5a3, p5a5 = p5a4;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ufcs5b.d",
    "content": "module imports.ufcs5b;\n\nauto f5b1(int)    { return 1; }\nauto f5b2(string) { return 2; }\nauto f5b3(double) { return 3; }\nalias f5b4 = f5b1, f5b4 = f5b2;\nalias f5b5 = f5b3, f5b5 = f5b4;\n\n@property p5b1(int)    { return 1; }    @property p5b1(int,    int) { return 1; }\n@property p5b2(string) { return 2; }    @property p5b2(string, int) { return 2; }\n@property p5b3(double) { return 3; }    @property p5b3(double, int) { return 3; }\nalias p5b4 = p5b1, p5b4 = p5b2;         alias p5b4 = p5b1, p5b4 = p5b2;\nalias p5b5 = p5b3, p5b5 = p5b4;         alias p5b5 = p5b3, p5b5 = p5b4;\n\n/***************************************/\n\nauto      f5ov(int)      { return 1; }\n@property p5ov(int)      { return 1; }\n@property p5ov(int, int) { return 1; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ufcs5c.d",
    "content": "module imports.ufcs5c;\n\nauto f5c1(int)    { return 1; }\nauto f5c2(string) { return 2; }\nauto f5c3(double) { return 3; }\nalias f5c4 = f5c1, f5c4 = f5c2;\nalias f5c5 = f5c3, f5c5 = f5c4;\n\n@property p5c1(int)    { return 1; }    @property p5c1(int,    int) { return 1; }\n@property p5c2(string) { return 2; }    @property p5c2(string, int) { return 2; }\n@property p5c3(double) { return 3; }    @property p5c3(double, int) { return 3; }\nalias p5c4 = p5c1, p5c4 = p5c2;         alias p5c4 = p5c1, p5c4 = p5c2;\nalias p5c5 = p5c3, p5c5 = p5c4;         alias p5c5 = p5c3, p5c5 = p5c4;\n\n/***************************************/\n\nauto      f5ov(string)      { return 2; }\n@property p5ov(string)      { return 2; }\n@property p5ov(string, int) { return 2; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ufcs5d.d",
    "content": "module imports.ufcs5d;\n\nauto f5d1(int)    { return 1; }\nauto f5d2(string) { return 2; }\nauto f5d3(double) { return 3; }\nalias f5d4 = f5d1, f5d4 = f5d2;\nalias f5d5 = f5d3, f5d5 = f5d4;\n\n@property p5d1(int)    { return 1; }    @property p5d1(int,    int) { return 1; }\n@property p5d2(string) { return 2; }    @property p5d2(string, int) { return 2; }\n@property p5d3(double) { return 3; }    @property p5d3(double, int) { return 3; }\nalias p5d4 = p5d1, p5d4 = p5d2;         alias p5d4 = p5d1, p5d4 = p5d2;\nalias p5d5 = p5d3, p5d5 = p5d4;         alias p5d5 = p5d3, p5d5 = p5d4;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/imports/ufcs5e.d",
    "content": "module imports.ufcs5e;\n\nauto f5e1(int)    { return 1; }\nauto f5e2(string) { return 2; }\nauto f5e3(double) { return 3; }\nalias f5e4 = f5e1, f5e4 = f5e2;\nalias f5e5 = f5e3, f5e5 = f5e4;\n\n@property p5e1(int)    { return 1; }    @property p5e1(int,    int) { return 1; }\n@property p5e2(string) { return 2; }    @property p5e2(string, int) { return 2; }\n@property p5e3(double) { return 3; }    @property p5e3(double, int) { return 3; }\nalias p5e4 = p5e1, p5e4 = p5e2;         alias p5e4 = p5e1, p5e4 = p5e2;\nalias p5e5 = p5e3, p5e5 = p5e4;         alias p5e5 = p5e3, p5e5 = p5e4;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/inline.d",
    "content": "\nimport core.stdc.stdio;\n\n// Test function inlining\n\ndebug = NRVO;\n\n/************************************/\n\nint foo(int i)\n{\n    return i;\n}\n\nint bar()\n{\n    return foo(3) + 4;\n}\n\nvoid test1()\n{\n    printf(\"%d\\n\", bar());\n    assert(bar() == 7);\n}\n\n\n/************************************/\n\nstruct Foo2\n{\n    int a,b,c,e,f,g;\n}\n\n\nint foo2(Foo2 f)\n{\n    f.b += 73;\n    return f.b;\n}\n\nint bar2()\n{\n    Foo2 gg;\n\n    gg.b = 6;\n    return foo2(gg) + 4;\n}\n\nvoid test2()\n{\n    printf(\"%d\\n\", bar2());\n    assert(bar2() == 83);\n}\n\n\n/************************************/\n\nstruct Foo3\n{\n    int bar() { return y + 3; }\n    int y = 4;\n}\n\nvoid test3()\n{\n    Foo3 f;\n\n    assert(f.bar() == 7);\n}\n\n\n/************************************/\n\nvoid func(void function () v)\n{\n}\n\nvoid test4()\n{\n   static void f1() { }\n\n   func(&f1);\n   //func(f1);\n}\n\n\n/************************************/\n\nvoid foo5(ubyte[16] array)\n{\n    bar5(array.ptr);\n}\n\nvoid bar5(ubyte *array)\n{\n}\n\nvoid abc5(ubyte[16] array)\n{\n    foo5(array);\n}\n\nvoid test5()\n{\n}\n\n/************************************/\n\nstruct Struct\n{\n    real foo()\n    {\n        return 0;\n    }\n\n    void bar(out Struct Q)\n    {\n        if (foo() < 0)\n            Q = this;\n    }\n}\n\nvoid test6()\n{\n}\n\n/************************************/\n\nstruct S7(T)\n{\n    immutable(T)[] s;\n}\n\nT foo7(T)(T t)\n{\n    enum S7!(T)[] i = [{\"hello\"},{\"world\"}];\n    auto x = i[0].s;\n    return t;\n}\n\nvoid test7()\n{\n    auto x = foo7('c');\n}\n\n/************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=10833\nstring fun10833(T...)()\n{\n    foreach (v ; T)\n        return v;\n    assert(0);\n}\n\nvoid test10833()\n{\n    auto a = fun10833!(\"bar\")();\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4825\n\nint a8() {\n    int r;\n    return r;\n}\n\nint b8() {\n    return a8();\n}\n\nvoid test8() {\n    void d() {\n        auto e = b8();\n    }\n    static const int f = b8();\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4841\n\nauto fun4841a()\n{\n    int i = 42;\n    struct Result\n    {\n        this(int u) {}\n        auto bar()\n        {\n            // refer context of fun4841a\n            return i;\n        }\n    }\n    return Result();\n}\nvoid test4841a()\n{\n    auto t = fun4841a();\n    auto x = t.bar();\n    assert(x == 42);\n}\n\nauto fun4841b()\n{\n    int i = 40;\n    auto foo()  // hasNestedFrameRefs() == false\n    {\n        //\n        struct Result\n        {\n            this(int u) {}\n            auto bar()\n            {\n                // refer context of fun4841b\n                return i + 2;\n            }\n        }\n        return Result();\n    }\n    return foo();\n}\nvoid test4841b()\n{\n    auto t = fun4841b();\n    assert(cast(void*)t.tupleof[$-1] !is null);     // Result to fun4841b\n    auto x = t.bar();\n    assert(x == 42);\n}\n\nauto fun4841c()\n{\n    int i = 40;\n    auto foo()  // hasNestedFrameRefs() == true\n    {\n        int g = 2;\n        struct Result\n        {\n            this(int u) {}\n            auto bar()\n            {\n                // refer context of fun4841c and foo\n                return i + g;\n            }\n        }\n        return Result();\n    }\n    return foo();\n}\nvoid test4841c()\n{\n    auto t = fun4841c();\n    assert(  cast(void*)t.tupleof[$-1] !is null);   // Result to foo\n    assert(*cast(void**)t.tupleof[$-1] !is null);   // foo to fun4841c\n    auto x = t.bar();\n    assert(x == 42);\n}\n\nvoid test4841()\n{\n    test4841a();\n    test4841b();\n    test4841c();\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7261\n\nstruct AbstractTask\n{\n    ubyte taskStatus;\n}\n\nstruct Task\n{\n    AbstractTask base;\n    alias base this;\n\n    void opAssign(Task rhs)\n    {\n    }\n\n    ~this()\n    {\n        if (taskStatus != 3) { }\n    }\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9356\n\nvoid test9356()\n{\n    static inout(char)[] bar (inout(char)[] a)\n    {\n        return a;\n    }\n\n    string result;\n    result ~= bar(\"abc\");\n    assert(result == \"abc\");\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12079\n\nvoid test12079()\n{\n    string[string][string] foo;\n\n    foo.get(\"bar\", null).get(\"baz\", null);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12243\n\nchar f12243() { return 'a'; }\n\nvoid test12243()\n{\n    string s;\n    s ~= f12243();\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11201\n\nstruct Foo11201\n{\n    int a;\n    float b;\n\n    Foo11201 func()() const { return this; }\n}\n\nauto f11201()(Foo11201 a) { return a; }\n\nvoid test11201()\n{\n    auto a = Foo11201(0, 1);\n\n    assert(f11201(a.func!()()) == a);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11223\n\nstruct Tuple11223(T...)\n{\n    T values;\n\n    void opAssign(Tuple11223 rhs)\n    {\n        if (0)\n            values = rhs.values;\n        else\n            assert(1);\n    }\n}\n\nvoid test11223()\n{\n    Tuple11223!string tmp;\n    tmp = Tuple11223!string();\n}\n\n/************************************/\n\n\nvoid foo3918()\n{\n    import core.stdc.stdlib : alloca;\n    void[] mem = alloca(1024)[0..1024];\n}\n\nvoid test3918()\n{\n    foreach(i; 0 .. 10_000_000)\n    {\n        foo3918();\n    }\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11314\n\nstruct Tuple11314(T...)\n{\n    T values;\n\n    void opAssign(typeof(this) rhs)\n    {\n        if (0)\n            values[] = rhs.values[];\n        else\n            assert(1);\n    }\n}\n\nstruct S11314 {}\n\nvoid test11314()\n{\n    Tuple11314!S11314 t;\n    t = Tuple11314!S11314(S11314.init);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11224\n\nS11224* ptr11224;\n\nstruct S11224\n{\n    this(int)\n    {\n        ptr11224 = &this;\n        /*printf(\"ctor &this = %p\\n\", &this);*/\n    }\n    this(this)\n    {\n        /*printf(\"cpctor &this = %p\\n\", &this);*/\n    }\n    int num;\n}\nS11224 foo11224()\n{\n    S11224 s = S11224(1);\n    //printf(\"foo  &this = %p\\n\", &s);\n    assert(ptr11224 is &s);\n    return s;\n}\nvoid test11224()\n{\n    auto s = foo11224();\n    //printf(\"main &this = %p\\n\", &s);\n    assert(ptr11224 is &s);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11322\n\nbool b11322;\nuint n11322;\n\nref uint fun11322()\n{\n    if (b11322)\n        return n11322;\n    else\n        return n11322;\n}\n\nvoid test11322()\n{\n    fun11322()++;\n    assert(n11322 == 1);\n    fun11322() *= 5;\n    assert(n11322 == 5);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11394\n\ndebug(NRVO) static void* p11394a, p11394b, p11394c;\n\nstatic int[5] make11394(in int x) pure\n{\n    typeof(return) a;\n    a[0] = x;\n    a[1] = x + 1;\n    a[2] = x + 2;\n    a[3] = x + 3;\n    a[4] = x + 4;\n    debug(NRVO) p11394a = cast(void*)a.ptr;\n    return a;\n}\n\nstruct Bar11394\n{\n    immutable int[5] arr;\n\n    this(int x)\n    {\n        this.arr = make11394(x);    // NRVO should work\n        debug(NRVO) p11394b = cast(void*)this.arr.ptr;\n    }\n}\n\nvoid test11394()\n{\n    auto b = Bar11394(5);\n    debug(NRVO) p11394c = cast(void*)b.arr.ptr;\n  //debug(NRVO) printf(\"p1 = %p\\np2 = %p\\np3 = %p\\n\", p11394a, p11394b, p11394c);\n    debug(NRVO) assert(p11394a == p11394b);\n    debug(NRVO) assert(p11394b == p11394c);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=12080\n\nclass TZ12080 {}\n\nstruct ST12080\n{\n    ST12080 opBinary()() const pure nothrow\n    {\n        auto retval = ST12080();\n        return retval;  // NRVO\n    }\n\n    long  _stdTime;\n    immutable TZ12080 _timezone;\n}\n\nclass Foo12080\n{\n\n    ST12080 bar;\n    bool quux;\n\n    public ST12080 sysTime()\n    out {}\n    body\n    {\n        if (quux)\n            return ST12080();\n\n        return bar.opBinary();\n        // returned value is set to __result\n        // --> Inliner wrongly created the second DeclarationExp for __result.\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=13503\n\nvoid f13503a(string[] s...)\n{\n    assert(s[0] == \"Cheese\");\n}\n\nauto f13503b(string arg)\n{\n    string result = arg;\n    return result;\n}\n\nstring f13503c(string arg)\n{\n    string result = arg;\n    return result;\n}\n\nvoid test13503()\n{\n    f13503a(f13503b(\"Cheese\"));\n    f13503a(f13503c(\"Cheese\"));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14267\n\n// EXTRA_SOURCES: imports/a14267.d\nimport imports.a14267;\n\nvoid test14267()\n{\n    foreach (m; __traits(allMembers, SysTime14267))\n    {\n        static if (is(typeof(__traits(getMember, SysTime14267, m))))\n        {\n            foreach (func; __traits(getOverloads, SysTime14267, m))\n            {\n                auto prot = __traits(getProtection, func);\n                static if (__traits(isStaticFunction, func))\n                {\n                    static assert(func.stringof == \"min()\");\n                    auto result = func;\n                }\n            }\n        }\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=13244\n\nstruct MapResult13244(alias fun)\n{\n    int[] input;\n    @property front() { return fun(input[0]); }\n}\n\nint[] array13244(R)(R r)\n{\n    int[] a;\n    a ~= r.front;\n    return a;\n}\n\nvoid test13244()\n{\n    auto arr = [[cast(ubyte)1]];\n    foreach (ref x; arr)\n    {\n        auto m = MapResult13244!(c => x[c])([0]);\n        array13244(m);\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14306\n\nstruct MapResult(alias fun)\n{\n    void front()\n    {\n//  while (1) { break; }\n        fun(1);\n    }\n}\n\nvoid bar(R)(R r)\n{\n    foreach (i; 0..100)\n    {\n        r.front();\n    }\n}\n\nstruct S\n{\n    int x;\n    int bump()\n    {\n        while (1) { break; }\n        ++x;\n        return x;\n    }\n}\n\nvoid fun(ref S s)\n{\n    MapResult!(y => s.bump())().bar;\n//  MapResult!((int x) => s.bump())().bar;\n\n    if (s.x != 100)\n        assert(0);\n}\n\nvoid test14306()\n{\n    S t;\n    fun(t);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14754\n\nauto aafunc14754(string k)\n{\n    enum aa = [ \"K\": \"V\" ];\n    auto p = k in aa;\n    return null;\n}\n\nstruct MapResult14754(alias fun, R)\n{\n    R _input;\n\n    @property auto ref front()\n    {\n        return fun(_input[0]);\n    }\n}\n\nauto array14754(R)(R r)\n{\n    alias E = typeof(r.front);\n    E[] result;\n    result ~= r.front;\n    return result;\n}\n\nauto mapfun14754(R)(R words, string k)\n{\n    return array14754(MapResult14754!(s => aafunc14754(k), R)(words));\n}\n\nvoid test14754()\n{\n    auto r = mapfun14754([\"\"], \"\");\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14606\n\nstruct S14606\n{\n    this(long stdTime)\n    {\n        _stdTime = stdTime;\n    }\n\n    long _stdTime;\n}\n\nS14606 getS14606()\n{\n    S14606 sysTime = S14606(0);\n    return sysTime;\n}\n\nstruct T14606\n{\n    this(string)\n    {\n        uint[3] arr;\n        s = getS14606();\n    }\n\n    S14606 s;\n}\n\nvoid test14606()\n{\n    auto t = T14606(null);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14753\n\npragma(inline)\nvoid test14753(string) { }\n\n/**********************************/\n\nstruct S14975\n{\n    int bar;\n\n    pragma(inline, true) this(int bar)\n    {\n        this.bar = bar;\n    }\n}\n\nvoid test14975()\n{\n    S14975 baz = 1;\n    if (baz.bar != 1)\n        assert(0);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=15210\n\nstruct BigInt15210 {}\n\nstruct Tuple15210(Types...)\n{\n    Types field;\n\n    void opAssign(R)(R rhs)\n    {\n        field = rhs.field;\n    }\n}\n\nvoid test15210()\n{\n    alias X = Tuple15210!BigInt15210;\n\n    X[BigInt15210] cache;\n\n    auto x = X();\n\n    cache[BigInt15210()] = x;\n}\n\n/**********************************/\n\nint foo7625(int v)\n{\n    return bar7625(2 * v);\n}\n\nint bar7625(int a)\n{\n    ++a;\n    if (a > 0)\n        return 1;\n    return baz(a);\n}\n\nint baz(int a)\n{\n    if (a > 0)\n        throw new Exception(\"a > 0\");\n    return a - 1;\n}\n\nvoid test7625()\n{\n    int x = foo7625(1);\n    if (x != 1)\n        assert(0);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9785 partial fix\n\nvoid test9785()\n{\n        int j = 3;\n\n        void loop(scope const void function(int x) dg) {\n            pragma(inline, true);\n            dg(++j);\n        }\n\n        loop((x) {\n                pragma(inline, true);\n                printf(\"%d\\n\", x);\n                assert(x == 4);\n        });\n}\n\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9785 partial fix\n\nvoid test9785_2() {\n        int j = 3;\n\n        void loop(scope const void function(int x) dg) {\n            pragma(inline, true);\n            dg(++j);\n        }\n\n        static void func(int x) {\n                pragma(inline, true);\n                printf(\"%d\\n\", x);\n                assert(x == 4);\n        }\n\n        loop(&func);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9785 partial fix\n\nvoid test9785_3() @nogc\n{\n    int j = 3;\n\n    void loop(scope const void delegate(int x) @nogc dg) @nogc {\n        pragma(inline, true);\n        dg(++j);\n    }\n\n    loop((x) @nogc {\n            pragma(inline, true);\n            //printf(\"%d\\n\", x + j * 2);\n            assert(x == 4);\n            assert(j == 4);\n    });\n\n    j = 3;\n    void func(int x) @nogc {\n            pragma(inline, true);\n            //printf(\"%d\\n\", x + j * 2);\n            assert(x == 4);\n            assert(j == 4);\n    }\n\n    loop(&func);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=15207\n\nstruct Vec15207\n{\n    float x, y, z;\n\n    this(float x_, float y_, float z_)\n    {\n        x = x_;\n        y = y_;\n        z = z_;\n    }\n\n    Vec15207 clone()\n    {\n        // When the variable 'res' is replaced with a STCref temporary,\n        // this line was accidentally changed to reference initialization.\n        Vec15207 res = this;\n\n        return res;\n    }\n}\n\nclass C15207\n{\n    Vec15207 a;\n\n    this()\n    {\n        a = Vec15207(1, 2, 3).clone();\n\n        assert(a.x == 1);\n        assert(a.y == 2);\n        assert(a.z == 3);\n        printf(\"%f %f %f\\n\", a.x, a.y, a.z);\n    }\n}\n\nvoid test15207()\n{\n    auto c = new C15207();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=15253\n\nstruct MessageType15253\n{\n    MessageType15253[] messageTypes;\n\n    const void toString1(scope void delegate(const(char)[]) sink)\n    {\n        messageTypes[0].toString1(sink);\n    }\n}\n\nstruct ProtoPackage15253\n{\n    MessageType15253[] messageTypes;\n\n    const void toString1(scope void delegate(const(char)[]) sink)\n    {\n        messageTypes[0].toString1(sink);\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=15296\n\nstatic int x15296;\n\nstruct S15296\n{\n    // Can be expanded only as statements.\n    pragma(inline, true)\n    void bar(size_t , size_t )\n    {\n        for (size_t w = 0; w < 2; w++) { ++x15296; }\n    }\n\n    pragma(inline, true)\n    void foo(size_t a, size_t b)\n    {\n        bar(a, b);\n    }\n}\n\npragma(inline, true)\nstatic void voidCall15296()\n{\n    for (size_t w = 0; w < 3; w++) { ++x15296; }\n}\n\nvoid test15296()\n{\n    bool cond = true;\n\n    S15296 s;\n\n    // CallExp at the top of ExpStatement\n    x15296 = 0;\n    s.foo(0, 0);\n    assert(x15296 == 2);\n\n    // CondExp at the top of ExpStatement\n    x15296 = 0;\n    (cond ? s.foo(0, 0) : voidCall15296());\n    assert(x15296 == 2);\n    (cond ? voidCall15296() : s.foo(0, 0));\n    assert(x15296 == 2 + 3);\n\n    // CommaExp at the top of ExpStatement\n    x15296 = 0;\n    (s.foo(0, 0), voidCall15296());\n    assert(x15296 == 3 + 2);\n}\n\n// ----\n\nstruct File15296\n{\n    struct Impl {}\n    Impl* _p;\n\n    pragma(inline, true)\n    ~this() { _p = null; }\n\n    struct LockingTextWriter\n    {\n        pragma(inline, true)\n        this(ref File15296 f)\n        {\n            assert(f._p, \"Attempting to write to closed File\");\n        }\n    }\n\n    pragma(inline, true)\n    auto lockingTextWriter() { return LockingTextWriter(this); }\n\n    pragma(inline, true)\n    void write() { auto w = lockingTextWriter(); }\n\n    //pragma(inline, true)\n    static uint formattedWrite(Writer)(Writer w) { return 0; }\n\n    pragma(inline, true)\n    void writef() { formattedWrite(lockingTextWriter()); }\n}\n\n__gshared File15296 stdout15296 = {new File15296.Impl()};\n\npragma(inline, true)\n@property File15296 trustedStdout15296() { return stdout15296; }\n\n// ----\n// reduced case from runnable/test34.d test34()\n\nvoid test15296b()\n{\n    // trustedStdout() returns a temporary File object. Its dtor call\n    // should be deferred till the end of expanded writef body statements.\n    trustedStdout15296().writef();\n}\n\n// ----\n// reduced case from runnable/xtest46.d test136()\n\nstruct Perm15296c\n{\n    this(byte[] input)\n    {\n        foreach (elem; input)\n        {\n            // if vthis.isDataseg() is true in expandInline,\n            // its edtor should not be called.\n            stdout15296.write();\n        }\n    }\n}\n\nvoid test15296c()\n{\n    auto perm2 = Perm15296c([0, 1, 2]);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=17676\n__gshared bool bgEnable = 1;\n\nvoid test17676() nothrow\n{\n    fullcollect();\n}\n\nsize_t fullcollect() nothrow\n{\n    if(bgEnable)\n       return fullcollectTrigger();\n\n    return fullcollectNow();\n}\n\nsize_t fullcollectNow() nothrow\n{\n    if (bgEnable)\n        assert(0);\n    pragma(inline, false);\n    return 1;\n}\n\nsize_t fullcollectTrigger() nothrow\n{\n    pragma(inline, false);\n    return 0;\n}\n\n/**********************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test3918();\n    test4();\n    test5();\n    test9356();\n    test6();\n    test7();\n    test8();\n    test4841();\n    test11201();\n    test11223();\n    test11314();\n    test11224();\n    test11322();\n    test11394();\n    test13503();\n    test13244();\n    test14306();\n    test14754();\n    test14606();\n    test14975();\n    test15210();\n    test7625();\n    test9785();\n    test9785_2();\n    test9785_3();\n    test15207();\n    test15296();\n    test15296b();\n    test15296c();\n    test17676();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/inline14560.d",
    "content": "// PERMUTE_ARGS: -inline -release -g -O\n\nauto serialize(T)(T value)\n{\n    foreach (i; value) { }\n\n    return;     // important\n    // By this ReturnStatement with NULL exp wrongly appears in the\n    // expanded result of serialize([\"test\"]) call in main(), it will\n    // return from main() without setting exit code.\n}\n\nint main()\n{\n    serialize([\"test\"]);\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/inline2.d",
    "content": "// EXTRA_SOURCES: imports/inline2a.d\n// PERMUTE_ARGS:\n// REQUIRED_ARGS: -O -release -inline\n\nimport imports.inline2a;\n\nclass Foo\n{\n        this ()\n        {\n                Primes.lookup(2);\n        }\n}\n\n\nint main()\n{\n        Primes.lookup(2);\n        return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/inner.d",
    "content": "\nimport std.stdio;\n\n/*******************************************************/\n\nclass Outer\n{\n    int o;\n    static int os = 3;\n\n    static class StaticInner\n    {\n        int si;\n\n        int foo()\n        {\n            return si + os;\n        }\n    }\n\n    class Inner\n    {\n        int i;\n\n        int foo(int m)\n        {\n            return i * o + m;\n        }\n\n        this(int k)\n        {\n            i = k + 7;\n            os = 6;\n        }\n    }\n\n    Inner bar()\n    {\n        return new Inner(17);\n    }\n}\n\nvoid test1()\n{\n    Outer p = new Outer();\n\n    assert(p.o == 0);\n    assert(p.os == 3);\n    p.o = 9;\n\n    Outer.StaticInner s = new Outer.StaticInner;\n    s.si = 10;\n    assert(s.foo() == 13);\n\n    Outer.Inner q = p.bar();\n    assert(q.i == 24);\n    assert(q.foo(8) == 24*9+8);\n}\n\n/*******************************************************/\n\nclass C1\n{\n    int c1;\n\n    this()\n    {\n        c1 = 2;\n    }\n\n    class C2\n    {\n        class C3\n        {\n            int c3;\n\n            this(int n)\n            {\n                c3 = n + c1 + c2;\n            }\n        }\n\n        int c2;\n\n        C3 foo()\n        {\n            return new C3(8);\n        }\n\n        this(int k)\n        {\n            c2 = k + 7;\n        }\n    }\n\n    C2 bar()\n    {\n        return new C2(17);\n    }\n}\n\nvoid test2()\n{\n   C1 p = new C1();\n   assert(p.c1 == 2);\n\n   C1.C2 q = p.bar();\n   assert(q.c2 == 24);\n\n   C1.C2.C3 r = q.foo();\n   assert(r.c3 == 2+24+8);\n}\n\n/*******************************************************/\n\nclass C3\n{\n    int c1;\n\n    this()\n    {\n        c1 = 2;\n    }\n\n    class B { }\n\n    class C2 : B\n    {\n        int c2;\n\n        this(int k)\n        {\n            c2 = c1 + k + 7;\n        }\n    }\n\n    C2 bar()\n    {\n        return new C2(17);\n    }\n}\n\nvoid test3()\n{\n   C3 q = new C3();\n   assert(q.c1 == 2);\n   C3.C2 p = q.bar();\n   assert(p.c2 == 26);\n}\n\n\n/*******************************************************/\n\nvoid test4()\n{\n    int m = 3;\n\n    class C\n    {\n        void foo()\n        {\n            assert(m == 3);\n        }\n    }\n\n    void bar()\n    {\n        assert(m == 3);\n    }\n\n    bar();\n    C c = new C;\n    c.foo();\n}\n\n/*******************************************************/\n\nvoid test5()\n{\n    int m = 3;\n\n    void bar()\n    {\n        assert(m == 3);\n    }\n\n    class C\n    {\n        void foo()\n        {\n            assert(m == 3);\n            bar();\n        }\n    }\n\n    bar();\n    C c = new C;\n    c.foo();\n}\n\n\n/*******************************************************/\n\nvoid test6()\n{\n    int m = 3;\n\n    void bar()\n    {\n        assert(m == 3);\n    }\n\n    void abc()\n    {\n        class C\n        {\n            void foo()\n            {\n                assert(m == 3);\n                bar();\n            }\n        }\n\n        bar();\n        C c = new C;\n        c.foo();\n    }\n\n    abc();\n}\n\n/*******************************************************/\n\nvoid test7()\n{\n    int m = 3;\n\n    void bar()\n    {\n        assert(m == 3);\n    }\n\n    void ghi()\n    {\n        void abc()\n        {\n            class C\n            {\n                void foo()\n                {\n                    assert(m == 3);\n                    bar();\n                }\n            }\n\n            bar();\n            C c = new C;\n            c.foo();\n        }\n\n        abc();\n    }\n\n    ghi();\n}\n\n/*******************************************************/\n\nvoid test8()\n{\n    int m = 3;\n\n    void bar()\n    {\n        assert(m == 3);\n    }\n\n    void ghi()\n    {\n        void abc()\n        {\n            class C\n            {\n                void foo()\n                {\n                    void fooey()\n                    {\n                        assert(m == 3);\n                        bar();\n                    }\n\n                    fooey();\n                }\n            }\n\n            bar();\n            C c = new C;\n            c.foo();\n        }\n\n        abc();\n    }\n\n    ghi();\n}\n\n/*******************************************************/\n\nclass C9\n{\n    int m;\n\n    void ccc()\n    {\n        assert(m == 3);\n    }\n\n    this()\n    {\n        m = 3;\n    }\n\n    class D\n    {\n        int n;\n\n        this() { n = 4; }\n\n        void abc()\n        {\n            assert(m == 3);\n            ccc();\n        }\n    }\n\n    D def()\n    {\n        return new D;\n    }\n}\n\n\nvoid test9()\n{\n    C9 c = new C9;\n    assert(c.m == 3);\n    c.ccc();\n\n    C9.D d = c.def();\n    assert(d.n == 4);\n    d.abc();\n}\n\n/*******************************************************/\n\nvoid test10()\n{\n    int m = 3;\n\n    class C\n    {\n        void foo()\n        {\n            assert(m == 3);\n        }\n    }\n\n    void abc()\n    {\n        C c = new C;\n        c.foo();\n    }\n\n    abc();\n}\n\n/*******************************************************/\n\nvoid test11()\n{\n    int m = 3;\n\n    class C\n    {\n        void foo()\n        {\n            assert(m == 3);\n        }\n    }\n\n    void abc()\n    {\n        void def()\n        {\n            C c = new C;\n            c.foo();\n        }\n\n        def();\n    }\n\n    abc();\n}\n\n/*******************************************************/\n\nvoid test12()\n{\n    int m = 3;\n\n    class C\n    {\n        void foo()\n        {\n            assert(m == 3);\n        }\n\n        void abc()\n        {\n            assert(m == 3);\n            C c = new C;\n            c.foo();\n        }\n    }\n\n    C d = new C;\n    d.abc();\n}\n\n/*******************************************************/\n\nvoid test13()\n{\n    int m = 3;\n\n    class C\n    {\n        void foo()\n        {\n            assert(m == 3);\n        }\n\n        void abc()\n        {\n            void def()\n            {\n                assert(m == 3);\n                C c = new C;\n                c.foo();\n            }\n\n            def();\n        }\n    }\n\n    C d = new C;\n    d.abc();\n}\n\n/*******************************************************/\n\nclass C14\n{\n    void foo()\n    {\n        assert(0);\n    }\n}\n\nvoid test14()\n{\n    int m = 3;\n\n    C14 c = new class C14\n        {\n            override void foo()\n            {\n                printf(\"in inner class\\n\");\n                assert(m == 3);\n            }\n        };\n\n    c.foo();\n}\n\n/*******************************************************/\n\nclass C15\n{\n    void foo()\n    {\n        assert(0);\n    }\n}\n\nvoid test15()\n{\n    int m = 3;\n\n    C15 c = new class(1,2) C15\n        {\n            this(int i, int j)\n            {\n                printf(\"in inner class ctor\\n\");\n                assert(i == 1);\n                assert(j == 2);\n            }\n\n            override void foo()\n            {\n                printf(\"in inner class\\n\");\n                assert(m == 3);\n            }\n        };\n\n    c.foo();\n}\n\n/*******************************************************/\n\nclass C16\n{\n    int w = 3;\n\n    void iterator()\n    {\n        class Foo\n        {\n            void current()\n            {\n                assert(w == 3);\n            }\n        }\n\n        Foo f = new Foo();\n        f.current();\n    }\n}\n\nvoid test16()\n{\n    C16 s = new C16();\n\n    s.iterator();\n}\n\n/*******************************************************/\n\nclass Owner\n{\n\n    this()\n    {\n        n = new Nested(this);\n    }\n\n    class Nested\n    {\n        this(Owner owner)\n        {\n            m = owner;\n        }\n\n        Owner foo()\n        {\n            return m;\n        }\n\n        Owner m;\n    }\n\n    Nested n;\n}\n\nclass OwnerDerived : Owner\n{\n}\n\nvoid test17()\n{\n    OwnerDerived o = new OwnerDerived();\n\n    assert(o.n.foo() is o);\n}\n\n/*******************************************************/\n\nclass Foo18\n{\n    class Bar\n    {\n        void doSayHello()\n        {\n            writefln(\"Betty\");\n            sayHello();\n        }\n    }\n    Bar bar;\n\n    void sayHello()\n    {\n        writefln(\"Hello\");\n    }\n}\n\nclass Foo182 : Foo18\n{\n    this()\n    {\n        bar = new Bar();\n    }\n}\n\nvoid test18()\n{\n    Foo182 foo = new Foo182();\n    writefln(\"This should print Hello:\");\n\n    foo.bar.doSayHello();\n}\n\n/*******************************************************/\n\nclass Foo19\n{\n    class Bar\n    {\n        void doSayHello()\n        {\n            writefln(\"Betty\");\n            sayHello();\n        }\n    }\n    Bar bar;\n\n    void sayHello()\n    {\n        writefln(\"Hello\");\n    }\n\n    this()\n    {\n        bar = new Bar();\n    }\n}\n\nclass Foo192 : Foo19\n{\n}\n\nvoid test19()\n{\n    Foo192 foo = new Foo192();\n    writefln(\"This should print Hello:\");\n\n    foo.bar.doSayHello();\n}\n\n/*******************************************************/\n\nclass Outer20\n{\n    int a;\n\n    class Inner\n    {\n        int foo()\n        {\n            return a;\n        }\n    }\n}\n\nvoid test20()\n{\n    Outer20 o = new Outer20;\n    o.a = 3;\n    Outer20.Inner oi = o.new Inner;\n    assert(oi.foo() == 3);\n}\n\n/*******************************************************/\n\nclass Foo21{}\n\nstatic if (is(typeof(new class Foo21{}))) {}\n\nvoid test21()\n{\n}\n\n/*******************************************************/\n\nclass Outer22\n{\n    class Inner\n    {\n        Outer22 foo()\n        {\n            return this.outer;\n        }\n    }\n\n    void bar()\n    {\n        Inner i = new Inner;\n        assert(this == i.foo());\n    }\n}\n\nvoid test22()\n{\n    Outer22 o = new Outer22;\n    o.bar();\n}\n\n/*******************************************************/\n\nclass Adapter23\n{\n    void func() { }\n}\n\nclass Foo23\n{\n    class AnonAdapter : Adapter23\n    {\n    }\n\n    void bar()\n    {\n        Adapter23 a = cast( Adapter23 )( new AnonAdapter() );\n    }\n}\n\nvoid test23()\n{\n    Foo23 f = new Foo23();\n    f.bar();\n    Adapter23 a = cast( Adapter23 )( f.new AnonAdapter() );\n    auto aa = f.new AnonAdapter();\n    Adapter23 ab = cast( Adapter23 )(aa);\n\n}\n\n/*******************************************************/\n\nclass I24\n{\n    public abstract void callI();\n}\n\nC24 c24;\n\nclass C24\n{\n    private int index;\n    void foo()\n    {\n        printf( \"ok, this = %p\\n\", this);\n        assert(this == c24);\n    }\n    I24 bar()\n    {\n        auto i = new class() I24\n        {\n            override public void callI()\n            {\n                foo();\n            }\n        };\n        printf(\"bar.this = %p\\n\", this);\n        printf(\"  i.this = %p\\n\", (cast(void**)i)[2]);\n        assert(*cast(void**)&c24 == (cast(void**)i)[2]);\n        return i;\n    }\n}\n\nvoid test24()\n{\n    c24 = new C24;\n    printf(\"c = %p\\n\", c24);\n    auto i = c24.bar();\n    i.callI();\n}\n\n/*******************************************************/\n\nstruct S7426\n{\n    static struct Inner\n    {\n        int x;\n        alias typeof(Inner.tupleof) T;\n    }\n}\n\n/*******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14046\n\nclass A14046\n{\n    class NestedA { }\n}\n\nclass B14046 : A14046\n{\n    int field;\n\n    class NestedB : NestedA\n    {\n        void foo()\n        {\n            this.outer.field = 1;  // ok <- disallowed\n\n            //(cast(B14046)this.outer).field = 1;  // workaround\n        }\n    }\n}\n\nvoid test14046()\n{\n    auto b = new B14046();\n    auto nb = b.new NestedB();\n    assert(b.field == 0);\n    nb.foo();\n    assert(b.field == 1);\n}\n\n/*******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15839\n\nclass AnimatedProgress15839(bool makeClosure)\n{\n    static AnimatedProgress15839 saveThis;\n\n    interface Runnable {}\n\n    static class GC\n    {\n        this(AnimatedProgress15839 ap)\n        {\n            assert(ap is saveThis);\n        }\n    }\n\n    void start()\n    {\n        assert(this is saveThis);\n\n        static if (makeClosure) int a;\n\n        auto r = new class Runnable\n        {\n            void run()\n            {\n                static assert(is(typeof(this.outer) == AnimatedProgress15839));\n                assert(this.outer is saveThis);\n\n                GC gc = new GC(this.outer);\n\n                static if (makeClosure) int b = a;\n            }\n        };\n        r.run();\n    }\n}\n\nvoid test15839()\n{\n    auto ap1 = new AnimatedProgress15839!false();\n    ap1.saveThis = ap1;\n    ap1.start();\n\n    auto ap2 = new AnimatedProgress15839!true();\n    ap2.saveThis = ap2;\n    ap2.start();\n}\n\n/*******************************************************/\n\nint main()\n{\n\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n\n    test11();\n    test12();\n    test13();\n\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n\n    test21();\n    test22();\n    test23();\n    test24();\n\n    test14046();\n    test15839();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/integrate.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS:\n\n// NOTE: the shootout is under a BSD license\n// The Great Computer Language Shootout\n// http://shootout.alioth.debian.org/\n//\n// contributed by Sebastien Loisel\n\nimport std.math, std.stdio, std.string, std.conv;\n\nalias fl F;\nstruct fl\n{\n    double a;\n\n    static fl opCall() { fl f; f.a = 0; return f; }\n    static fl opCall(fl v) { fl f; f.a = v.a; return f; }\n    void set(double x)\n    {\n        if(x==0) { a=0; return; }\n        int k=cast(int)log(fabs(x));\n        a=round(x*exp(-k+6.0))*exp(k-6.0);\n    }\n    static fl opCall(int x) { fl f; f.set(x); return f; }\n    static fl opCall(double x) { fl f; f.set(x); return f; }\n    fl opAdd(fl y) { return fl(a+y.a); }\n    fl opAddAssign(fl y) { this=(this)+y; return this; }\n    fl opSub(fl y) { return fl(a-y.a); }\n    fl opSubAssign(fl y) { this=(this)-y; return this; }\n    fl opMul(fl y) { return fl(a*y.a); }\n    fl opDiv(fl y) { return fl(a/y.a); }\n\n    fl opAdd(int y) { return fl(a+y); }\n    fl opSub(int y) { return fl(a-y); }\n    fl opMul(int y) { return fl(a*y); }\n    fl opDiv(int y) { return fl(a/y); }\n\n    fl opAdd(double y) { return fl(a+y); }\n    fl opSub(double y) { return fl(a-y); }\n    fl opMul(double y) { return fl(a*y); }\n    fl opDiv(double y) { return fl(a/y); }\n}\n\nstruct ad\n{\n    F x, dx;\n    static ad opCall() { ad t; t.x = F(0); t.dx = F(0); return t; }\n    static ad opCall(int y) { ad t; t.x = F(y); t.dx = F(0); return t; }\n    static ad opCall(F y) { ad t; t.x = y; t.dx = F(0); return t; }\n    static ad opCall(F X, F DX) { ad t; t.x = X; t.dx = DX; return t; }\n    ad opAdd(ad y) { return ad(x+y.x,dx+y.dx); }\n    ad opSub(ad y) { return ad(x-y.x,dx-y.dx); }\n    ad opMul(ad y) { return ad(x*y.x,dx*y.x+x*y.dx); }\n    ad opDiv(ad y) { return ad(x/y.x,(dx*y.x-x*y.dx)/(y.x*y.x)); }\n    ad opMul(F v) { return ad(x*v,dx*v); }\n    ad opAdd(F v) { return ad(x+v,dx); }\n}\n\nF sqr(F x) { return x * x; }\nad sqr(ad x) { return x * x; }\n\nF pow(F x, int i)\n{\n    if(i < 1) return F(1);\n    if(i & 1) if(i == 1) return x; else return x * pow(x,i-1);\n    return sqr(pow(x,i/2));\n}\nad pow(ad x, int i)\n{\n    if(i < 1) return ad(1);\n    if(i & 1) if(i == 1) return x; else return x * pow(x,i-1);\n    return sqr(pow(x,i/2));\n}\n\nF rat(F x)\n{\n    F t = (x * F(2) + pow(x,2) * F(3) + pow(x,6) * F(7) + pow(x,11) * F(5) + F(1))\n        / (x * F(5) - pow(x,3) * F(6) - pow(x,7) * F(3) + F(2));\n    return t;\n}\nad rat(ad x)\n{\n    ad t = (x * ad(2) + pow(x,2) * ad(3) + pow(x,6) * ad(7) + pow(x,11) * ad(5) + ad(1))\n        / (x * ad(5) - pow(x,3) * ad(6) - pow(x,7) * ad(3) + ad(2));\n    return t;\n}\n\nF newton(F x0, int n, trapezoid_method_rooter g)\n{\n\n    for(int i=0 ; i<n; i++)\n    {\n        ad val = g( ad(x0,F(1)) );    // ad = trapezoid_method_rooter(ad);\n//**\n        x0 = x0 - val.x / val.dx;\n/+\n        F t0 = val.x;\n        F t1 = val.dx;\n        x0 = x0 - t0 / t1;\n+/\n    }\n\n    return x0;\n}\n\nstruct trapezoid_method_rooter\n{\n    sqrintegrand g;\n    ad g0;\n    F y0, t0, t1;\n    trapezoid_method_rooter opCall(sqrintegrand G, F Y0, F T0, F T1)\n    {\n        g = G;\n        y0 = Y0;\n        t0 = T0;\n        t1 = T1;\n        g0 = G(T0,Y0);              // ad = sqr/ratintegrand(float,float);\n        return this;\n    }\n    ad opCall(ad y1)\n    {\n        return (g(ad(t1),y1) + g0) * ((t1-t0)/F(2)) + y0 - y1;        // ad = sqr/ratintegrand(ad,ad);\n    }\n}\n\nF trapezoid_method(F t0, F dt, F y0, sqrintegrand g, int numsteps)\n{\n  for(int i = 0; i < numsteps; i++)\n  {\n      trapezoid_method_rooter solver;\n      y0 = newton(y0,10,solver(g,y0,t0,t0+dt));\n      t0 = t0 + dt;\n  }\n  return y0;\n}\n\nstruct sqrintegrand\n{\n      ad opCall(F t, F y) { return ad(sqr(y)); }\n      ad opCall(ad t, ad y) { return sqr(y); }\n}\n\nstruct ratintegrand\n{\n    ad opCall(F t, F y) { return ad(rat(y) - t); }\n    ad opCall(ad t, ad y) { return rat(y) - t; }\n}\n\nvoid integrate_functions(F x0, int n)\n{\n    sqrintegrand   i1;\n    writeln(\"i1 \",pr(trapezoid_method(F(1), F(1)/F(n), x0, i1 ,n)));\n}\n\nchar[] pr(fl x) { char[] s = new char[100]; int len = sprintf(s.ptr,\"%.2e\",x.a); return s[0..len]; }\n\nint main(string[] args)\n{\n  int N = args.length > 1 ? to!int(args[1]) : 50;\n\n  integrate_functions(F(0.02),N);\n  return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/interface.d",
    "content": "\nimport core.stdc.stdio;\n\n/*******************************************/\n\ninterface IStream\n{\n    int read();\n}\n\ninterface OStream\n{\n    int write();\n}\n\nclass IO : IStream, OStream\n{\n    int read() { return 7; }\n    int write() { return 267; }\n}\n\nvoid foo(IStream i, OStream o)\n{\n    printf(\"foo(i = %p, o = %p)\\n\", i, o);\n    assert(i.read() == 7);\n    assert(o.write() == 267);\n}\n\nvoid test1()\n{\n    IO io = new IO();\n    printf(\"io = %p\\n\", io);\n    foo(io, io);\n    delete io;\n}\n\n/*******************************************/\n\ninterface I { }\nclass C : I\n{\n    ~this() { printf(\"~C()\\n\"); }\n}\n\nvoid test2()\n{\n    I i = new C();\n    delete i;\n\n  {\n    scope I j = new C();\n  }\n}\n\n/*******************************************/\n\ninterface I3 {\n    void h();\n}\ninterface K3 {\n    void f();\n}\n\ninterface J3 : I3, K3 {}\n\nclass A3 : J3 {\n    short x = 3;\n\n    void f(){ assert(x == 3); }\n    void h(){ assert(x == 3); }\n}\n\nvoid test3()\n{\n    auto a = new A3();\n    a.f();\n    a.h();\n    J3 j = a;\n    j.f();\n    K3 k = a;\n    k.f();\n    assert(&j.f == &k.f); // https://issues.dlang.org/show_bug.cgi?id=3706\n}\n\n/*******************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/interface1.d",
    "content": "\nextern(C) int printf(const char*, ...);\n\n/*******************************************/\n\ninterface D {\n        int foo();\n}\n\nclass A : D {\n        int foo() { return 1; }\n}\n\nclass B : A, D\n{\n        override int foo() { return 2; }\n}\n\nclass C : B, D {\n        override int foo() { return 3; }\n}\n\nvoid test1()\n{\n        C c = new C;\n        A a = cast(A) c;\n        int j = a.foo();\n        printf(\"%d\\n\", j);\n        assert(j == 3);\n\n        B b = cast(B) c;\n        int k = b.foo();\n        printf(\"%d\\n\", k);\n        assert(k == 3);\n\n        D d1 = cast(D) c;\n        int l = d1.foo();\n        printf(\"%d\\n\", l);\n        assert(l == 3);\n\n        D d2 = cast(D) b;\n        int m = d2.foo();\n        printf(\"%d\\n\", m);\n        assert(m == 3);\n}\n\n\n/*******************************************/\n\ninterface D2 {\n        int foo();\n}\n\nclass A2 : D2 {\n        int foo() { printf(\"A2\\n\"); return 1; }\n}\n\nclass B2 : A2 {\n        override int foo() { printf(\"B2\\n\"); return 2; }\n}\n\nclass C2 : B2, D2 {\n        override int foo() { printf(\"C2\\n\"); return 3; }\n}\n\nvoid test2()\n{\n    int i;\n\n    C2 c = new C2;\n    D2 d = cast(D2)c;\n    i = c.foo();\n    assert(i == 3);\n\n    i = d.foo();\n    assert(i == 3);\n\n    B2 b = new B2;\n    if (cast(D2) b)\n    {\n        D2 e = cast(D2) b;\n        i = e.foo();\n        assert(i == 2);\n    }\n    else\n        assert(0);\n\n    A2 a;\n    if (cast(D2) a)\n        assert(0);\n}\n\n\n/*******************************************/\n\ninterface C3\n{\n    int doLayout();\n}\n\nclass A3\n{\n    void print() { printf(\"A3::print\\n\"); }\n}\n\nclass B3 : A3, C3\n{\n    int doLayout() { printf( \"B3::doLayout\\n\" ); return 17; }\n}\n\nvoid callLayout(A3 b)\n{\n    printf(\"b = %p\\n\", b);\n    C3 cl = cast(C3)b;\n    printf(\"cl = %p\\n\", cl);\n    if (cl)\n    {   int i;\n\n        i = cl.doLayout();\n        assert(i == 17);\n    }\n    else\n    {   printf(\"the 'A3' you passed did not implement 'C3'\\n\" );\n        assert(0);\n    }\n}\n\nvoid test3()\n{\n    callLayout(new B3());\n}\n\n\n/*******************************************/\n\n\ntemplate IContainer(T)\n{\n        interface IContainer\n        {\n                alias   Container!(int) selected_type;\n                bool    isEmpty();\n                int     enumerate();\n        }\n}\n\ntemplate Container(T)\n{\n        class Container : IContainer!(int)\n        {\n            bool isEmpty() { return false; }\n            int enumerate() { return 3; }\n        }\n}\n\nvoid Vector_test_IContainer_int()\n{\n    alias IContainer!(int) icontainer_t;\n}\n\nvoid test4()\n{\n}\n\n/*******************************************/\n\n\ninterface Italy(T)\n{\n        alias   Foo5!(int) selected_type;\n        bool    isempty();\n        int     enumerate();\n}\n\nclass Foo5(T) : Italy!(int)\n{\n        bool    isempty() { return false; }\n        int     enumerate() { return 3; }\n}\n\nvoid test5()\n{\n    alias Italy!(int) Ic;\n    Foo5!(int) f = new Foo5!(int);\n    Ic i = cast(Ic)f;\n    assert(i.isempty() == false);\n    assert(i.enumerate() == 3);\n}\n\n\n/*******************************************/\n\nint main (char[][] args)\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/interface2.d",
    "content": "// PERMUTE_ARGS:\n\nextern(C) int printf(const char*, ...);\n\n/*******************************************************/\n\ninterface Foo { int bar(); }\n\nvoid* p1;\n\nclass Bar : Foo\n{\n    int bar()\n    {\n        printf(\"Bar.bar(this = %p)\\n\", this);\n        p1 = cast(void*)this;\n        return 0;\n    }\n}\n\nvoid test1()\n{\n    Bar b = new Bar();\n    Foo f = b;\n\n    printf(\"b = %p\\n\", b);\n    printf(\"f = %p\\n\", f);\n    assert(cast(void*)b !is cast(void*)f);\n\n    printf(\"f.class = '%.*s'\\n\", f.classinfo.name.length, f.classinfo.name.ptr);\n    assert(f.classinfo.name == \"interface2.Foo\");\n\n    f.bar();\n    assert(p1 is cast(void*)b);\n\n    Bar b2 = cast(Bar)f;\n    printf(\"cast(Bar)f = %p\\n\", b2);\n    assert(b is b2);\n\n    delete f;\n}\n\n/*******************************************************/\n\ninterface A {}\ninterface B:A {}\ninterface C {}\nclass D:B,C {}\n\nvoid test2()\n{\n    D x = new D();\n    printf(\"D: %p\\n\",x);\n    Object o = x;\n    printf(\"o: %p\\n\",o);\n    B b = cast(B)o;\n    printf(\"B: %p\\n\",b);\n    C c = cast(C)o;    // boom\n    printf(\"C: %p\\n\",c);\n}\n\n/*******************************************************/\n\ninterface B3\n{\n    void close();\n}\n\ninterface C3 : B3\n{\n}\n\nclass A3 : B3\n{\n    void close()\n    {\n    }\n}\n\nclass D3 : A3\n{\n}\n\nclass E3 : D3, C3\n{\n}\n\nvoid test3()\n{\n    C3 c = new E3();\n    delete c;\n}\n\n\n/*******************************************************/\n\ninterface K\n{\n}\n\ninterface X\n{\n}\n\ninterface Y : X\n{\n}\n\nclass Z : Y\n{\n}\n\nvoid test4()\n{\n    Z z = new Z();\n    if (cast(K) z)\n    {\n        printf(\"not ok\\n\");\n        assert(0);\n    }\n}\n\n/*******************************************************/\n\ninterface I5\n{\n    char M ();\n}\n\ninterface J5 : I5\n{\n    char N ();\n}\n\nclass A5 : I5\n{\n    char M () { printf(\"M()\\n\"); return 'M'; }\n}\n\nclass B5 : A5, J5\n{\n    char N () { printf(\"N()\\n\"); return 'N'; }\n}\n\nvoid test5()\n{\n    I5 f = new B5 ();\n\n    char c = f.M();\n    assert(c == 'M');\n}\n\n/*******************************************************/\n\ninterface A6\n{\n    void ma ();\n}\n\ninterface B6\n{\n    void mb ();\n}\n\nclass C6 : A6, B6\n{\n    void ma () { }\n    void mb () { }\n}\n\nvoid test6()\n{\n    A6 x = new C6 ();\n\n    assert (cast (B6) x);\n}\n\n/*******************************************************/\n\ninterface D7 { int foo(); }\n\nclass A7 : D7 { int foo() { return 1; } }\n\nclass B7 : A7\n{\n    override int foo() { return 2; }\n    D7 me() { return this; }\n}\n\nvoid test7()\n{\n    A7 a = new A7;\n    B7 b = new B7;\n    assert(b.me().foo() != a.foo());\n}\n\n/*******************************************************/\n\ninterface D8 { void foo(); }\n\nclass A8 : D8 { void foo() { printf(\"A8.foo()\\n\"); } }\n\nclass B8 : A8 {}\n\nvoid test8()\n{\n    B8 b = new B8();\n    D8 d = cast(D8) b;\n    d.foo();\n}\n\n/*******************************************************/\n\ninterface IA9\n{\n    int i1();\n}\n\ninterface IB9\n{\n    int i2();\n}\n\ninterface IC9 : IA9, IB9\n{\n}\n\nclass C9 : IC9\n{\n    int i1() { printf(\"i1\\n\"); return 1; }\n    int i2() { printf(\"i2\\n\"); return 2; }\n}\n\nvoid f9(IA9 i1, IB9 i2)\n{\n    int i;\n\n    printf(\"f9\\n\");\n    i = i1.i1();\n    assert(i == 1);\n    i = i2.i2();\n    assert(i == 2);\n}\n\nvoid test9()\n{\n    IC9 i3 = new C9();\n    C9 c = new C9();\n    f9(c, c);\n    //printf(\"c = %p, IC9 = %p, IA9 = %p, IB9 = %p\\n\", c, i3, cast(IA9)i3, cast(IB9)i3);\n    f9(i3, i3);\n}\n\n\n/*******************************************************/\n\ninterface IOne\n{\n    int one ();\n}\n\ninterface ITwo\n{\n    int two ();\n}\n\ninterface IThree : IOne, ITwo\n{\n    int three ();\n}\n\nclass Three : IThree\n{\n    int one ()   { printf (\"one\\n\"); return 1; }\n    int two ()   { printf (\"two\\n\"); return 2; }\n    int three () { printf (\"three\\n\"); return 3; }\n}\n\n\nvoid test10()\n{\n    int i;\n    IThree three = new Three;\n\n    i = three.one();\n    assert(i == 1);\n    i = three.two();\n    assert(i == 2);\n    i = three.three();\n    assert(i == 3);\n\n    ITwo two = cast(ITwo) three;\n    i = two.two();\n    assert(i == 2);\n}\n\n\n/*******************************************************/\n\ninterface A11{\n}\n\ninterface B11 : A11{\n}\n\nclass MyClass : B11{\n}\n\nvoid test11()\n{\n    B11 b = new MyClass();\n    Object o = cast(Object)b;\n    printf(\"o = %p\\n\", o);\n}\n\n/*******************************************************/\n\ninterface I12\n{\n    int foo();\n}\n\nclass IA12 : I12\n{\n    int foo() { return 1; }\n}\n\nclass A12\n{\n    I12 i;\n\n    I12 clone() { return i; }\n}\n\nclass B12 : A12\n{\n    IA12 ia;\n\n    override IA12 clone()   // covariant return value\n    out (result)\n    {\n        printf(\"B12.clone()\\n\");\n    }\n    body\n    {\n        return ia;\n    }\n}\n\nvoid test12()\n{\n    IA12 ia = new IA12;\n    assert(ia.foo() == 1);\n\n    I12 i = ia;\n    assert(i.foo() == 1);\n\n    A12 a = new A12;\n    a.i = i;\n    assert(a.clone().foo() == 1);\n\n    B12 b = new B12;\n    b.ia = ia;\n    assert(b.clone().foo() == 1);\n\n    a = b;\n    assert(a.clone().foo() == 1);\n}\n\n/*******************************************************/\n\nclass I13\n{\n    int foo() { return 0; }\n}\n\nclass IA13 : I13\n{\n    override int foo() { return 1; }\n}\n\nclass A13\n{\n    I13 i;\n\n    I13 clone() { return i; }\n}\n\nclass B13 : A13\n{\n    IA13 ia;\n\n    override IA13 clone()\n    out (result)\n    {\n        printf(\"B13.clone()\\n\");\n    }\n    body { return ia; }\n}\n\nvoid test13()\n{\n    IA13 ia = new IA13;\n    assert(ia.foo() == 1);\n\n    I13 i = ia;\n    assert(i.foo() == 1);\n\n    A13 a = new A13;\n    a.i = i;\n    assert(a.clone().foo() == 1);\n\n    B13 b = new B13;\n    b.ia = ia;\n    assert(b.clone().foo() == 1);\n\n    a = b;\n    assert(a.clone().foo() == 1);\n\n    bar(&b.clone);\n}\n\nvoid bar(IA13 delegate() dg)\n{\n}\n\n/*******************************************************/\n\ninterface I14\n{\n        I14 clone();\n}\n\ninterface BabyI14: I14\n{\n}\n\nclass A14: BabyI14\n{\n    int x;\n    BabyI14 clone()\n    {\n        A14 a = new A14;\n        a.x = x;\n        return a;\n    }\n}\n\nI14 foo14(I14 i)\n{\n    return i.clone();\n}\n\nvoid test14()\n{\n    A14 a = new A14;\n    a.x = 3;\n    a = cast(A14)a.clone();\n    assert(a.x == 3);\n\n    A14 b = cast(A14)foo14(a);\n    a.x = 4;\n    assert(b.x == 3);\n}\n\n/*******************************************************/\n\ninterface I15\n{\n        Object clone();\n}\n\nclass A15 : I15\n{\n    int x;\n    A15 clone() { return this; }\n}\n\nvoid test15()\n{\n    A15 a = new A15;\n    a.x = 3;\n\n    A15 a1 = a.clone();\n    assert(a1.x == 3);\n\n    I15 i = a1;\n    Object o = i.clone();\n    A15 a2 = cast(A15) o;\n    assert(a2.x == 3);\n}\n\n/*******************************************************/\n\ninterface I16 {}\n\nclass A16\n{\n    I16 foo()\n    {\n        printf(\"Called A.foo\\n\");\n        return new B16(42);\n    }\n}\n\nclass B16 : A16, I16\n{\n    int data;\n\n    this(int d) { data = d; }\n\n    override B16 foo()\n    {\n        printf(\"Called B.foo\\n\");\n        return new B16(69);\n    }\n}\n\nvoid test16()\n{\n    B16 b = new B16(105);\n    b.foo();\n    A16 a = b;\n    a.foo();\n    printf(\"foo\\n\");\n    B16 b2 = cast(B16) a.foo();\n}\n\n\n/*******************************************************/\n\ninterface Father\n{\n    int showData();\n}\n\nclass Mother\n{\n    Father test() {\n        printf(\"Called Mother.test\\n\");\n        return new Child(42);\n    }\n}\n\nclass Child : Mother, Father {\n    int data;\n\n    this(int d) { data = d; }\n\n    override Child test()\n    {\n        printf(\"Called Child.test\\n\");\n        return new Child(69);\n    }\n\n    int showData() {\n        printf(\"%d\\n\", data);\n        return data;\n    }\n}\n\nvoid test17()\n{\n    Child aChild = new Child(105);\n    Mother childsMum = aChild;\n\n    aChild.test();\n    Father mumTest = childsMum.test();\n    int i;\n    i = aChild.showData();\n    assert(i == 105);\n    i = mumTest.showData();\n    assert(i == 69);\n}\n\n\n/*******************************************************/\n\nint status18;\n\ninterface I18 {\n    int showData();\n}\n\nclass Parent18 {\n    I18 test() {\n        status18 += 7;\n        return new Child18(42);\n    }\n}\n\nclass Child18 : Parent18, I18 {\n    int data;\n\n    this(int d) {\n        data = d;\n    }\n\n    override Child18 test() {\n        status18 += 1;\n        return new Child18(69);\n    }\n\n    override\n     int showData(){\n        return data;\n    }\n}\n\nvoid test18()\n{\n    Child18 a = new Child18(105);\n    assert(a);\n    assert(status18 == 0);\n    assert(a.data == 105);\n\n    Parent18 p = a;\n    assert(a);\n    assert(status18 == 0);\n\n    a.test();\n    assert(status18 == 1);\n\n    I18 i = p.test();\n    assert(i);\n    assert(status18 == 2);\n\n    assert(a.data == 105);\n    assert(a.showData() == 105);\n    assert(i.showData() == 69);\n}\n\n/*******************************************************/\n\n\ninterface IFoo19 {\n}\n\ninterface ICov19 {\n    IFoo19 covfunc();\n}\n\nclass Child19 : ICov19, IFoo19 {\n    Child19 covfunc() {\n        printf(\"in Child19.covfunc()\\n\");\n        return this;\n    }\n}\n\nvoid test19()\n{\n    Child19 c = new Child19();\n    ICov19 icov = c;\n\n    IFoo19 ifoo = icov.covfunc();\n\n    printf(\"c = %p\\n\", c);\n    printf(\"icov = %p\\n\", icov);\n    printf(\"ifoo = %p\\n\", ifoo);\n\n    assert(cast(void*)c + (2*(void*).sizeof) == cast(void*)icov);\n    assert(cast(void*)c + (3*(void*).sizeof) == cast(void*)ifoo);\n\n    string s = ifoo.classinfo.name;\n    printf(\"%.*s\\n\", s.length, s.ptr);\n    assert(s == \"interface2.IFoo19\");\n\n    s = (cast(Object)ifoo).toString;\n    printf(\"%.*s\\n\", s.length, s.ptr);\n    assert(s == \"interface2.Child19\");\n}\n\n/*******************************************************/\n\ninterface Iface1\n{\n    Iface2 func1();\n}\n\ninterface Iface2\n{\n    Iface1 func2();\n}\n\nclass C1_20 : Iface1\n{\n    C2_20 func1(){ return null; }\n}\n\nclass C2_20 : Iface2\n{\n    C1_20 func2(){ return null; }\n}\n\nvoid test20()\n{\n    C1_20 c1 = new C1_20();\n    printf(\"c1.func1() == %p\\n\", c1.func1());\n    assert(c1.func1() is null);\n    printf(\"test1\\n\");\n\n    C2_20 c2 = new C2_20();\n    printf(\"c2.func2() == %p\\n\", c2.func2());\n    assert(c2.func2() is null);\n}\n\n/*******************************************************/\n\ninterface I21\n{\n    int test(int);\n}\n\nclass C21 : I21\n{\n    int test(int i){\n        return i+1;\n    }\n}\n\nvoid test21()\n{\n    C21[I21] aa;\n\n    C21 o = new C21();\n\n    aa[o] = o;\n\n    I21 i = aa[o];\n    assert(i.test(3) == 4);\n}\n\n\n/*******************************************************/\n\ninterface IFoo22\n{\n   int foo();\n}\n\nclass Foo22: IFoo22\n{\n   final int foo() { return 7; }\n}\n\nvoid test22()\n{\n    Foo22 f = new Foo22;\n    assert(f.foo() == 7);\n\n    IFoo22 i = f;\n    assert(i.foo() == 7);\n}\n\n/*******************************************************/\n\ninterface IFoo23\n{\n   int foo();\n}\n\nclass Foo23: IFoo23\n{\n   final int foo() { return 7; }\n}\n\nclass Baz23 : Foo23\n{\n}\n\nvoid test23()\n{\n    Baz23 f = new Baz23;\n    assert(f.foo() == 7);\n\n    IFoo23 i = f;\n    assert(i.foo() == 7);\n}\n\n/*******************************************************/\n\ninterface I24B() : I24A\n{\n}\n\ninterface I24A\n{\n    I24B!() func ();\n}\n\nclass Foo24 : I24B!()\n{\n    I24B!() func()\n    {\n        return null;\n    }\n}\n\nvoid test24()\n{\n    auto foo = new Foo24();\n\n    foo.func();\n    printf(\"foo.func() call passed\\n\");\n\n    I24A ifA = foo;\n    assert(ifA !is null);\n    ifA.func();\n}\n\n/*******************************************************/\n\ninterface IA25\n{\n    char a();\n}\n\ninterface IB25\n{\n    char b();\n}\n\ninterface IC25 : IA25, IB25\n{\n    char c();\n}\n\ninterface ID25\n{\n    char d();\n}\n\ninterface IE25 : IC25, ID25\n{\n    char e();\n}\n\nclass Foo25 : IE25\n{\n    char a() { return('a'); }\n    char b() { return('b'); }\n    char c() { return('c'); }\n    char d() { return('d'); }\n    char e() { return('e'); }\n}\n\nvoid test25()\n{\n    auto foo = new Foo25;\n    printf(\"Foo: %c %c %c %c %c\\n\", foo.a, foo.b, foo.c, foo.d, foo.e);\n    IA25 a = foo;\n    printf(\"A: %c\\n\", a.a);\n    assert(a.a == 'a');\n    IB25 b = foo;\n    printf(\"B: %c\\n\", b.b);\n    assert(b.b == 'b');\n    IC25 c = foo;\n    printf(\"C: %c %c %c\\n\", c.a, c.b, c.c);\n    assert(c.a == 'a');\n    assert(c.b == 'b');\n    assert(c.c == 'c');\n    ID25 d = foo;\n    printf(\"D: %c\\n\", d.d);\n    assert(d.d == 'd');\n    IE25 e = foo;\n    printf(\"E: %c %c %c %c %c\\n\", e.a, e.b, e.c, e.d, e.e);\n    assert(e.a == 'a');\n    assert(e.b == 'b');\n    assert(e.c == 'c');\n    assert(e.d == 'd');\n    assert(e.e == 'e');\n\n    b = e;\n    printf(\"IB25: %c\\n\", b.b);\n    assert(b.b == 'b');\n}\n\n/*******************************************************/\n\ninterface VisualElement {\n   void draw();\n}\n\ninterface Actor {\n}\n\ninterface VisualActor : Actor, VisualElement {\n}\n\nclass Sprite3 : Actor, VisualActor {\n    override void draw() { }\n}\n\nvoid test26()\n{\n}\n\n/*******************************************************/\n\ninterface I27\n{\n    static int foo() { return 3; }\n\n    final int bar() { return 7 + abc(); }\n\n    int abc();\n}\n\nclass C27 : I27\n{\n    int x;\n    int abc() { return x * 10; }\n}\n\nvoid test27()\n{\n    C27 c = new C27();\n    c.x = 8;\n    I27 i = c;\n    assert(i.foo() == 3);\n    assert(I27.foo() == 3);\n    assert(i.bar() == 87);\n}\n\n/*******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1747\n// https://issues.dlang.org/show_bug.cgi?id=2013\n\nvoid test1747()\n{\n    interface IA          { int mA(); }\n    interface IB : IA     { int mB(); }\n    interface IC : IB     { }\n    interface ID : IA, IC { int mD(); }\n\n    // offset:   0   +n  +n + ptrsize\n    //                  (IA)\n    //                   IB\n    //               IA, IC\n    static class C : ID\n    {\n        int mA() { return 1; }\n        int mB() { return 2; }\n        int mD() { return 3; }\n    }\n\n    C c = new C;    void* pc  = *cast(void**)&c;\n    ID id = c;      void* pid = *cast(void**)&id;\n    IC ic = c;      void* pic = *cast(void**)&ic;\n    IB ib = c;      void* pib = *cast(void**)&ib;\n    IA ia = c;      void* pia = *cast(void**)&ia;\n\n    //printf(\" c = %p\\n\", pc);\n    //printf(\"id = %p\\n\", pid);\n    //printf(\"ic = %p\\n\", pic);\n    //printf(\"ib = %p\\n\", pib);\n    //printf(\"ia = %p\\n\", pia);\n\n    size_t n = pid - pc;\n    assert(pic == pc + n + (void*).sizeof);\n    assert(pib == pc + n + (void*).sizeof);     // OK <- NG\n    assert(pia == pc + n);\n\n    assert(id.mA() == 1);\n    assert(id.mB() == 2);   // OK <- NG (bugzilla 2013 case)\n    assert(id.mD() == 3);\n\n    assert(ic.mA() == 1);\n    assert(ic.mB() == 2);   // OK <- NG (bugzilla 2013 case)\n\n    assert(ib.mA() == 1);\n    assert(ib.mB() == 2);   // OK <- NG\n\n    assert(ia.mA() == 1);\n}\n\n/*******************************************************/\n\nprivate interface IFoo\n{\n   void foo();\n}\n\nvoid test2553()\n{\n    IFoo foo;\n    if (0)\n        foo.foo;\n}\n\n/*******************************************************/\n\ninterface I2524\n{\n    void foo();\n}\n\nclass C2524 : I2524\n{\n    final override void foo() { }\n}\n\n/*******************************************************/\n\ninterface Test4088 {}\n\nbool foo4088(Test4088 x, Test4088 y)\n{\n    return x == y;\n}\n\n/*******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7950\n\ntemplate TypeTuple7950(T...){alias T TypeTuple7950;}\ninterface I7950a {} // ok\ninterface I7950b : I7950a, TypeTuple7950!() {} // fail\n\n/*******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10007\n\nstruct A10007 {}\n\ninterface IFoo10007\n{\n    void bar(ref const A10007);\n}\n\nclass Foo10007 : IFoo10007\n{\n    void bar(ref const A10007 a) {}\n    void bar(    const A10007 a) { return this.bar(a); }\n}\n\n/*******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10744\n\ninterface A10744\n{\n    int x();\n    Foo10744 foo();\n}\n\nclass B10744 : A10744\n{\n    int x() { return 0; }\n    Bar10744 foo() { return null; }\n}\n\nclass Foo10744 { }\nclass Bar10744 : Foo10744 { }\n\ninterface C10744\n{\n    int x();\n    Baz10744 foo();\n}\n\nclass D10744 : C10744\n{\n    int x() { return 0; }\n    Qux10744 foo() { return null; }\n}\n\ninterface Baz10744 { }\ninterface Qux10744 : Baz10744 { }\n\n/*******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11034\n\nclass A11034(T)\n{\n    A11034!int view() { return null; }\n}\nclass B11034(T) : A11034!int\n{\noverride:\n    C11034!int view() { return null; }\n}\nclass C11034(T) : B11034!int {}\n\nvoid test11034()\n{\n    auto b = new B11034!int;\n\n    // Check that B!int.view() overrides A!int.view()\n    auto tiobj = typeid(Object);\n    assert(typeid(A11034!int).vtbl.length == tiobj.vtbl.length + 1);\n    assert(typeid(B11034!int).vtbl.length == tiobj.vtbl.length + 1);\n}\n\n/*******************************************************/\n\nvoid testTypeid()\n{\n    interface I\n    {\n    }\n\n    interface J : I\n    {\n    }\n\n    class C : J\n    {\n    }\n\n    class D : C\n    {\n    }\n\n    D d = new D();\n    Object o = d;\n    I i = d;\n\n    assert(typeid(typeof(o)) is typeid(Object));\n    assert(typeid(o) is typeid(D));\n    assert(o.classinfo is typeid(D));\n    assert(typeid(typeof(i)) is typeid(I));\n    assert(typeid(i) !is typeid(J));\n    assert(i.classinfo !is typeid(J));\n}\n\n/*******************************************************/\n\nextern (C++)\n{\n    interface IA47\n    {\n        char a();\n    }\n\n    interface IB47\n    {\n        char b();\n    }\n\n    interface IC47 : IA47, IB47\n    {\n        char c();\n    }\n\n    interface ID47\n    {\n        char d();\n    }\n\n    interface IE47 : IC47, ID47\n    {\n        char e();\n    }\n\n    class Foo47 : IE47\n    {\n        int x = 9;\n        char a() { printf(\"a.this = %p\\n\", this); return('a'); }\n        char b() { printf(\"b.this = %p\\n\", this); return('b'); }\n        char c() { printf(\"c.this = %p\\n\", this); return('c'); }\n        char d() { printf(\"d.this = %p\\n\", this); return('d'); }\n        char e() { printf(\"e.this = %p\\n\", this); return('e'); }\n    }\n}\n\nvoid test15647()\n{\n    auto foo = new Foo47;\n    printf(\"Foo: %p %c %c %c %c %c\\n\", foo, foo.a, foo.b, foo.c, foo.d, foo.e);\n    IA47 a = foo;\n    printf(\"A: %c\\n\", a.a);\n    assert(a.a == 'a');\n    IB47 b = foo;\n    printf(\"B: %c\\n\", b.b);\n    assert(b.b == 'b');\n    IC47 c = foo;\n    printf(\"C: %p %c %c %c\\n\", c, c.a, c.b, c.c);\n    assert(c.a == 'a');\n    assert(c.b == 'b');\n    assert(c.c == 'c');\n    ID47 d = foo;\n    printf(\"D: %c\\n\", d.d);\n    assert(d.d == 'd');\n    IE47 e = foo;\n    printf(\"E: %c %c %c %c %c\\n\", e.a, e.b, e.c, e.d, e.e);\n    assert(e.a == 'a');\n    assert(e.b == 'b');\n    assert(e.c == 'c');\n    assert(e.d == 'd');\n    assert(e.e == 'e');\n\n    b = e;\n    printf(\"IB47: %c\\n\", b.b);\n    assert(b.b == 'b');\n}\n\n/*******************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test1747();\n    test2553();\n    test11034();\n    testTypeid();\n    test15647();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/interface3.d",
    "content": "// PERMUTE_ARGS:\n\nextern(C) int printf(const char*, ...);\n\ninterface IWriter\n{\n        IWriter put (I1 x);\n}\n\ninterface I1\n{\n        void write (IWriter writer);\n}\n\ninterface I2 : I1 {}\n\ninterface I3 : I2 {}\n\nclass Newline : I3\n{\n        static int OKset;\n\n        void write (IWriter writer)\n        {\n                printf (\"OK\\n\");\n                OKset += 1;\n        }\n}\n\n\n\nclass Writer : IWriter\n{\n        IWriter put (I1 x)\n        {\n                x.write (this);\n                return this;\n        }\n}\n\nclass FlushWriter : Writer\n{\n        override IWriter put (I1 x)\n        {\n               // have superclass handle the I1\n                super.put (x);\n\n                // flush output when we see a newline\n                if (cast(Newline) x)\n                   {\n                   }\n\n                return this;\n        }\n}\n\n\n\nvoid test (IWriter w)\n{\n        //w.put (new Newline);\n\n        I3 NL = new Newline;\n        w.put (NL);\n}\n\n\nint main()\n{\n        test (new FlushWriter);\n        assert(Newline.OKset == 1);\n        return 0;\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/interpret.d",
    "content": "\nimport std.stdio;\n\ntemplate Tuple(A...)\n{\n    alias A Tuple;\n}\n\ntemplate eval(A...)\n{\n    const typeof(A[0]) eval = A[0];\n}\n\n/************************************************/\n\nint Foo1(int i)\n{\n    if (i == 0)\n        return 1;\n    else\n        return i * Foo1(i - 1);\n}\n\nvoid test1()\n{\n    static int f = Foo1(5);\n    printf(\"%d %d\\n\", f, 5*4*3*2);\n    assert(f == 120);\n}\n\n/************************************************/\n\nint find2(string s, char c)\n{\n    if (s.length == 0)\n        return -1;\n    else if (c == s[0])\n        return 0;\n    else\n        return 1 + find2(s[1..$], c);\n}\n\nvoid test2()\n{\n    static int f = find2(\"hello\", 'l');\n    printf(\"%d\\n\", f);\n    assert(f == 2);\n}\n\n/************************************************/\n\nint bar3(int i)\n{\n    int j;\n    while (i)\n    {\n        j += i;\n        i--;\n    }\n    return j;\n}\n\nvoid test3()\n{\n    static b = bar3(7);\n    printf(\"b = %d, %d\\n\", b, bar3(7));\n    assert(b == 28);\n}\n\n/************************************************/\n\nint bar4(int i)\n{\n    for (int j = 0; j < 10; j++)\n        i += j;\n    return i;\n}\n\nvoid test4()\n{\n    static b = bar4(7);\n    printf(\"b = %d, %d\\n\", b, bar4(7));\n    assert(b == 52);\n}\n\n/************************************************/\n\nint bar5(int i)\n{\n    int j;\n    do\n    {\n        i += j;\n        j++;\n    } while (j < 10);\n    return i;\n}\n\nvoid test5()\n{\n    static b = bar5(7);\n    printf(\"b = %d, %d\\n\", b, bar5(7));\n    assert(b == 52);\n}\n\n/************************************************/\n\nint bar6(int i)\n{\n    int j;\n    do\n    {\n        i += j;\n        j++;\n        if (j == 4)\n            break;\n    } while (j < 10);\n    return i;\n}\n\nvoid test6()\n{\n    static b = bar6(7);\n    printf(\"b = %d, %d\\n\", b, bar6(7));\n    assert(b == 13);\n}\n\n/************************************************/\n\nint bar7(int i)\n{\n    int j;\n    do\n    {\n        i += j;\n        j++;\n        if (j == 4)\n            return 80;\n    } while (j < 10);\n    return i;\n}\n\nvoid test7()\n{\n    static b = bar7(7);\n    printf(\"b = %d, %d\\n\", b, bar7(7));\n    assert(b == 80);\n}\n\n/************************************************/\n\nint bar8(int i)\n{\n    int j;\n    do\n    {\n        j++;\n        if (j == 4)\n            continue;\n        i += j;\n    } while (j < 10);\n    return i;\n}\n\nvoid test8()\n{\n    static b = bar8(7);\n    printf(\"b = %d, %d\\n\", b, bar8(7));\n    assert(b == 58);\n}\n\n/************************************************/\n\nint bar9(int i)\n{\n    int j;\n    while (j < 10)\n    {\n        j++;\n        if (j == 4)\n            continue;\n        i += j;\n    }\n    return i;\n}\n\nvoid test9()\n{\n    static b = bar9(7);\n    printf(\"b = %d, %d\\n\", b, bar9(7));\n    assert(b == 58);\n}\n\n/************************************************/\n\nint bar10(int i)\n{\n    int j;\n    while (j < 10)\n    {\n        j++;\n        if (j == 4)\n            break;\n        i += j;\n    }\n    return i;\n}\n\nvoid test10()\n{\n    static b = bar10(7);\n    printf(\"b = %d, %d\\n\", b, bar10(7));\n    assert(b == 13);\n}\n\n/************************************************/\n\nint bar11(int i)\n{\n    int j;\n    while (j < 10)\n    {\n        j++;\n        if (j == 4)\n            return i << 3;\n        i += j;\n    }\n    return i;\n}\n\nvoid test11()\n{\n    static b = bar11(7);\n    printf(\"b = %d, %d\\n\", b, bar11(7));\n    assert(b == 104);\n}\n\n/************************************************/\n\nint bar12(int i)\n{\n    for (int j; j < 10; j++)\n    {\n        if (j == 4)\n            return i << 3;\n        i += j;\n    }\n    return i;\n}\n\nvoid test12()\n{\n    static b = bar12(7);\n    printf(\"b = %d, %d\\n\", b, bar12(7));\n    assert(b == 104);\n}\n\n/************************************************/\n\nint bar13(int i)\n{\n    for (int j; j < 10; j++)\n    {\n        if (j == 4)\n            break;\n        i += j;\n    }\n    return i;\n}\n\nvoid test13()\n{\n    static b = bar13(7);\n    printf(\"b = %d, %d\\n\", b, bar13(7));\n    assert(b == 13);\n}\n\n/************************************************/\n\nint bar14(int i)\n{\n    for (int j; j < 10; j++)\n    {\n        if (j == 4)\n            continue;\n        i += j;\n    }\n    return i;\n}\n\nvoid test14()\n{\n    static b = bar14(7);\n    printf(\"b = %d, %d\\n\", b, bar14(7));\n    assert(b == 48);\n}\n\n/************************************************/\n\nint bar15(int i)\n{\n    foreach (k, v; \"hello\")\n    {\n        i <<= 1;\n        if (k == 4)\n            continue;\n        i += v;\n    }\n    return i;\n}\n\nvoid test15()\n{\n    static b = bar15(7);\n    printf(\"b = %d, %d\\n\", b, bar15(7));\n    assert(b == 3344);\n}\n\n/************************************************/\n\nint bar16(int i)\n{\n    foreach_reverse (k, v; \"hello\")\n    {\n        i <<= 1;\n        if (k == 4)\n            continue;\n        i += v;\n    }\n    return i;\n}\n\nvoid test16()\n{\n    static b = bar16(7);\n    printf(\"b = %d, %d\\n\", b, bar16(7));\n    assert(b == 1826);\n}\n\n/************************************************/\n\nint bar17(int i)\n{\n    foreach (k, v; \"hello\")\n    {\n        i <<= 1;\n        if (k == 2)\n            break;\n        i += v;\n    }\n    return i;\n}\n\nvoid test17()\n{\n    static b = bar17(7);\n    printf(\"b = %d, %d\\n\", b, bar17(7));\n    assert(b == 674);\n}\n\n/************************************************/\n\nint bar18(int i)\n{\n    foreach_reverse (k, v; \"hello\")\n    {\n        i <<= 1;\n        if (k == 2)\n            break;\n        i += v;\n    }\n    return i;\n}\n\nvoid test18()\n{\n    static b = bar18(7);\n    printf(\"b = %d, %d\\n\", b, bar18(7));\n    assert(b == 716);\n}\n\n/************************************************/\n\nint bar19(int i)\n{\n    assert(i > 0);\n    foreach_reverse (k, v; \"hello\")\n    {\n        i <<= 1;\n        if (k == 2)\n            return 8;\n        i += v;\n    }\n    return i;\n}\n\nvoid test19()\n{\n    static b = bar19(7);\n    printf(\"b = %d, %d\\n\", b, bar19(7));\n    assert(b == 8);\n}\n\n/************************************************/\n\nint bar20(int i)\n{\n    assert(i > 0);\n    foreach (k, v; \"hello\")\n    {\n        i <<= 1;\n        if (k == 2)\n            return 8;\n        i += v;\n    }\n    return i;\n}\n\nvoid test20()\n{\n    static b = bar20(7);\n    printf(\"b = %d, %d\\n\", b, bar20(7));\n    assert(b == 8);\n}\n\n/************************************************/\n\nint bar21(int i)\n{\n    assert(i > 0);\n    foreach (v; Tuple!(57, 23, 8))\n    {\n        i <<= 1;\n        i += v;\n    }\n    return i;\n}\n\nvoid test21()\n{\n    static b = bar21(7);\n    printf(\"b = %d, %d\\n\", b, bar21(7));\n    assert(b == 338);\n}\n\n/************************************************/\n\nint bar22(int i)\n{\n    assert(i > 0);\n    foreach_reverse (v; Tuple!(57, 23, 8))\n    {\n        i <<= 1;\n        i += v;\n    }\n    return i;\n}\n\nvoid test22()\n{\n    static b = bar22(7);\n    printf(\"b = %d, %d\\n\", b, bar22(7));\n    assert(b == 191);\n}\n\n/************************************************/\n\nint bar23(int i)\n{\n    assert(i > 0);\n    foreach_reverse (v; Tuple!(57, 23, 8))\n    {\n        i <<= 1;\n        if (v == 23)\n            return i + 1;\n        i += v;\n    }\n    return i;\n}\n\nvoid test23()\n{\n    static b = bar23(7);\n    printf(\"b = %d, %d\\n\", b, bar23(7));\n    assert(b == 45);\n}\n\n/************************************************/\n\nint bar24(int i)\n{\n    assert(i > 0);\n    foreach (v; Tuple!(57, 23, 8))\n    {\n        i <<= 1;\n        if (v == 23)\n            return i + 1;\n        i += v;\n    }\n    return i;\n}\n\nvoid test24()\n{\n    static b = bar24(7);\n    printf(\"b = %d, %d\\n\", b, bar24(7));\n    assert(b == 143);\n}\n\n/************************************************/\n\nint bar25(int i)\n{\n    assert(i > 0);\n    foreach_reverse (v; Tuple!(57, 23, 8))\n    {\n        i <<= 1;\n        if (v == 23)\n            break;\n        i += v;\n    }\n    return i;\n}\n\nvoid test25()\n{\n    static b = bar25(7);\n    printf(\"b = %d, %d\\n\", b, bar25(7));\n    assert(b == 44);\n}\n\n/************************************************/\n\nint bar26(int i)\n{\n    assert(i > 0);\n    foreach (v; Tuple!(57, 23, 8))\n    {\n        i <<= 1;\n        if (v == 23)\n            break;\n        i += v;\n    }\n    return i;\n}\n\nvoid test26()\n{\n    static b = bar26(7);\n    printf(\"b = %d, %d\\n\", b, bar26(7));\n    assert(b == 142);\n}\n\n/************************************************/\n\nint bar27(int i)\n{\n    foreach_reverse (v; Tuple!(57, 23, 8))\n    {\n        i <<= 1;\n        if (v == 23)\n            continue;\n        i += v;\n    }\n    return i;\n}\n\nvoid test27()\n{\n    static b = bar27(7);\n    printf(\"b = %d, %d\\n\", b, bar27(7));\n    assert(b == 145);\n}\n\n/************************************************/\n\nint bar28(int i)\n{\n    foreach (v; Tuple!(57, 23, 8))\n    {\n        i <<= 1;\n        if (v == 23)\n            continue;\n        i += v;\n    }\n    return i;\n}\n\nvoid test28()\n{\n    static b = bar28(7);\n    printf(\"b = %d, %d\\n\", b, bar28(7));\n    assert(b == 292);\n}\n\n/************************************************/\n\nint bar29(int i)\n{\n    switch (i)\n    {\n        case 1:\n            i = 4;\n            break;\n        case 7:\n            i = 3;\n            break;\n        default: assert(0);\n    }\n    return i;\n}\n\nvoid test29()\n{\n    static b = bar29(7);\n    printf(\"b = %d, %d\\n\", b, bar29(7));\n    assert(b == 3);\n}\n\n/************************************************/\n\nint bar30(int i)\n{\n    switch (i)\n    {\n        case 1:\n            i = 4;\n            break;\n        case 8:\n            i = 2;\n            break;\n        default:\n            i = 3;\n            break;\n    }\n    return i;\n}\n\nvoid test30()\n{\n    static b = bar30(7);\n    printf(\"b = %d, %d\\n\", b, bar30(7));\n    assert(b == 3);\n}\n\n/************************************************/\n\nint bar31(string s)\n{   int i;\n\n    switch (s)\n    {\n        case \"hello\":\n            i = 4;\n            break;\n        case \"betty\":\n            i = 2;\n            break;\n        default:\n            i = 3;\n            break;\n    }\n    return i;\n}\n\nvoid test31()\n{\n    static b = bar31(\"betty\");\n    printf(\"b = %d, %d\\n\", b, bar31(\"betty\"));\n    assert(b == 2);\n}\n\n/************************************************/\n\nint bar32(int i)\n{\n    switch (i)\n    {\n        case 7:\n            i = 4;\n            goto case;\n        case 5:\n            i = 2;\n            break;\n        default:\n            i = 3;\n            break;\n    }\n    return i;\n}\n\nvoid test32()\n{\n    static b = bar32(7);\n    printf(\"b = %d, %d\\n\", b, bar32(7));\n    assert(b == 2);\n}\n\n/************************************************/\n\nint bar33(int i)\n{\n    switch (i)\n    {\n        case 5:\n            i = 2;\n            break;\n        case 7:\n            i = 4;\n            goto case 5;\n        default:\n            i = 3;\n            break;\n    }\n    return i;\n}\n\nvoid test33()\n{\n    static b = bar33(7);\n    printf(\"b = %d, %d\\n\", b, bar33(7));\n    assert(b == 2);\n}\n\n/************************************************/\n\nint bar34(int i)\n{\n    switch (i)\n    {\n        default:\n            i = 3;\n            break;\n        case 5:\n            i = 2;\n            break;\n        case 7:\n            i = 4;\n            goto default;\n    }\n    return i;\n}\n\nvoid test34()\n{\n    static b = bar34(7);\n    printf(\"b = %d, %d\\n\", b, bar34(7));\n    assert(b == 3);\n}\n\n/************************************************/\n\nint bar35(int i)\n{\n  L1:\n    switch (i)\n    {\n        default:\n            i = 3;\n            break;\n        case 5:\n            i = 2;\n            break;\n        case 3:\n            return 8;\n        case 7:\n            i = 4;\n            goto default;\n    }\n    goto L1;\n}\n\nvoid test35()\n{\n    static b = bar35(7);\n    printf(\"b = %d, %d\\n\", b, bar35(7));\n    assert(b == 8);\n}\n\n/************************************************/\n\nint square36(int x)\n{\n    return x * x;\n}\n\nconst int foo36 = square36(5);\n\nvoid test36()\n{\n    assert(foo36 == 25);\n}\n\n/************************************************/\n\nstring someCompileTimeFunction()\n{\n    return \"writefln(\\\"Wowza!\\\");\";\n}\n\nvoid test37()\n{\n    mixin(someCompileTimeFunction());\n}\n\n/************************************************/\n\nstring NReps(string x, int n)\n{\n    string ret = \"\";\n    for (int i = 0; i < n; i++)\n    {\n        ret ~= x;\n    }\n    return ret;\n}\n\nvoid test38()\n{\n    static x = NReps(\"3\", 6);\n    assert(x == \"333333\");\n}\n\n/************************************************/\n\nbool func39() { return true; }\n\nstatic if (func39())\n{\n    pragma(msg, \"true\");\n}\nelse\n{\n    pragma(msg, \"false\");\n}\n\nvoid test39()\n{\n}\n\n/************************************************/\n\nstring UpToSpace(string x)\n{\n    int i = 0;\n    while (i < x.length && x[i] != ' ')\n    {\n        i++;\n    }\n    return x[0..i];\n}\n\nvoid test40()\n{\n    const y = UpToSpace(\"first space was after first\");\n    writeln(y);\n    assert(y == \"first\");\n}\n\n/************************************************/\n\nint bar41(ref int j)\n{\n    return 5;\n}\n\nint foo41(int i)\n{\n    int x;\n    x = 3;\n    bar41(x);\n    return i + x;\n}\n\nvoid test41()\n{\n    const y = foo41(3);\n    writeln(y);\n    assert(y == 6);\n}\n\n/************************************************/\n\nint bar42(ref int j)\n{\n    return 5;\n}\n\nint foo42(int i)\n{\n    int x;\n    x = 3;\n    bar42(x);\n    return i + x;\n}\n\nvoid test42()\n{\n    const y = foo42(3);\n    writeln(y);\n    assert(y == 6);\n}\n\n/************************************************/\n\nint bar(string a)\n{\n    int v;\n    for (int i = 0; i < a.length; i++)\n    {\n        if (a[i] != ' ')\n        {\n            v += a.length;\n        }\n    }\n    return v;\n}\n\nvoid test43()\n{\n    const int foo = bar(\"a b c d\");\n    writeln(foo);\n    assert(foo == 28);\n}\n\n/************************************************/\n\nstring foo44() { return (\"bar\"); }\n\nvoid test44()\n{\n    const string bar = foo44();\n    assert(bar == \"bar\");\n}\n\n/************************************************/\n\nint square45(int n) { return (n * n); }\n\nvoid test45()\n{\n    int bar = eval!(square45(5));\n    assert(bar == 25);\n}\n\n/************************************************/\n\nconst int[5] foo46 = [0,1,2,3,4];\n\nvoid test46()\n{\n    writeln(eval!(foo46[3]));\n}\n\n/************************************************/\n\nstring foo47()\n{\n    string s;\n    s = s ~ 't';\n    return s ~ \"foo\";\n}\n\nvoid test47()\n{\n    static const x = foo47();\n    pragma(msg, x);\n    assert(x == \"tfoo\");\n}\n\n/************************************************/\n\nstring foo48()\n{\n    string s;\n    s = s ~ 't';\n    s = s.idup;\n    return s ~ \"foo\";\n}\n\nvoid test48()\n{\n    static const x = foo48();\n    pragma(msg, x);\n    assert(x == \"tfoo\");\n}\n\n/************************************************/\n\ndstring testd49(dstring input)\n{\n    if (input[3..5] != \"rt\")\n    {\n        return input[1..3];\n    }\n    return \"my\";\n}\n\nvoid test49()\n{\n    static x = testd49(\"hello\");\n    writeln(x);\n    assert(x == \"el\");\n}\n\n/************************************************/\n\nstring makePostfix50(int x)\n{\n    string first;\n    first = \"bad\";\n    if (x)\n    {\n        first = \"ok\";\n        makePostfix50(0);\n    }\n    return first;\n}\n\nvoid test50()\n{\n    static const char [] q2 = makePostfix50(1);\n    static assert(q2 == \"ok\", q2);\n}\n\n/************************************************/\n\nint exprLength(string s)\n{\n    int numParens=0;\n    for (int i = 0; i < s.length; ++i)\n    {\n        if (s[i] == '(') { numParens++; }\n        if (s[i] == ')') { numParens--; }\n        if (numParens == 0) { return i; }\n    }\n    assert(0);\n}\n\nstring makePostfix51(string operations)\n{\n    if (operations.length < 2)\n        return \"x\";\n    int x = exprLength(operations);\n    string first=\"bad\";\n    if (x > 0)\n    {\n        first = \"ok\";\n        string ignore = makePostfix51(operations[1..x]);\n    }\n    return first;\n}\n\n\nvoid test51()\n{\n    string q = makePostfix51(\"(a+b)*c\");\n    assert(q == \"ok\");\n    static const string q2 = makePostfix51(\"(a+b)*c\");\n    static assert(q2 == \"ok\");\n    static assert(makePostfix51(\"(a+b)*c\") == \"ok\");\n}\n\n/************************************************/\n\nint foo52(ref int x)\n{\n    x = 7;\n    return 3;\n}\n\nint bar52(int y)\n{\n    y = 4;\n    foo52(y);\n    return y;\n}\n\nvoid test52()\n{\n    printf(\"%d\\n\", bar52(2));\n    static assert(bar52(2) == 7);\n}\n\n/************************************************/\n\nvoid bar53(out int x) { x = 2; }\n\nint foo53() { int y; bar53(y); return y; }\n\nvoid test53()\n{\n    const int z = foo53();\n    assert(z == 2);\n}\n\n/************************************************/\n\nvoid test54()\n{\n    static assert(equals54(\"alphabet\", \"alphabet\"));\n}\n\nbool equals54(string a, string b)\n{\n    return (a == b);\n}\n\n/************************************************/\n\nconst string[2] foo55 = [\"a\", \"b\"];\nstring retsth55(int i) { return foo55[i]; }\n\nvoid test55()\n{\n    writeln(eval!(foo55[0]));\n    writeln(eval!(retsth55(0)));\n}\n\n/************************************************/\n\nstring retsth56(int i)\n{\n    static const string[2] foo = [\"a\", \"b\"];\n    return foo[i];\n}\n\nvoid test56()\n{\n    writeln(eval!(retsth56(0)));\n}\n\n/************************************************/\n\nint g57()\n{\n    pragma(msg, \"g\");\n    return 2;\n}\n\nconst int a57 = g57();\n\nvoid test57()\n{\n    assert(a57 == 2);\n}\n\n/************************************************/\n\nint[] Fun58(int x)\n{\n    int[] result;\n    result ~= x + 1;\n    return result;\n}\n\nvoid test58()\n{\n    static b = Fun58(1) ~ Fun58(2);\n    assert(b.length == 2);\n    assert(b[0] == 2);\n    assert(b[1] == 3);\n    writeln(b);\n}\n\n/************************************************/\n\nint Index59()\n{\n    int[] data = [1];\n    return data[0];\n}\n\nvoid test59()\n{\n    static assert(Index59() == 1);\n}\n\n/************************************************/\n\nstring[int] foo60()\n{\n    return [3:\"hello\", 4:\"betty\"];\n}\n\nvoid test60()\n{\n    static assert(foo60()[3] == \"hello\");\n    static assert(foo60()[4] == \"betty\");\n}\n\n/************************************************/\n\nstring[int] foo61()\n{\n    return [3:\"hello\", 4:\"betty\", 3:\"world\"];\n}\n\nvoid test61()\n{\n    static assert(foo61()[3] == \"world\");\n    static assert(foo61()[4] == \"betty\");\n}\n\n/************************************************/\n\nstring foo62(int k)\n{\n    string[int] aa;\n    aa = [3:\"hello\", 4:\"betty\"];\n    return aa[k];\n}\n\nvoid test62()\n{\n    static assert(foo62(3) == \"hello\");\n    static assert(foo62(4) == \"betty\");\n}\n\n/************************************************/\n\nvoid test63()\n{\n    static auto x = foo63();\n}\n\nint foo63()\n{\n    pragma(msg, \"Crash!\");\n    return 2;\n}\n\n/************************************************/\n\ndstring testd64(dstring input)\n{\n    debug int x = 10;\n    return \"my\";\n}\n\nvoid test64()\n{\n    static x = testd64(\"hello\");\n}\n\n/************************************************/\n\nstruct S65\n{\n    int i;\n    int j = 3;\n}\n\nint foo(S65 s1, S65 s2)\n{\n    return s1 == s2;\n}\n\nvoid test65()\n{\n    static assert(foo(S65(1, 5), S65(1, 5)) == 1);\n    static assert(foo(S65(1, 5), S65(1, 4)) == 0);\n}\n\n/************************************************/\n\nstruct S66\n{\n    int i;\n    int j = 3;\n}\n\nint foo66(S66 s1)\n{\n    return s1.j;\n}\n\nvoid test66()\n{\n    static assert(foo66(S66(1, 5)) == 5);\n}\n\n/************************************************/\n\nstruct S67\n{\n    int i;\n    int j = 3;\n}\n\nint foo67(S67 s1)\n{\n    s1.j = 3;\n    int i = (s1.j += 2);\n    assert(i == 5);\n    return s1.j + 4;\n}\n\nvoid test67()\n{\n    static assert(foo67(S67(1, 5)) == 9);\n}\n\n/************************************************/\n\nint foo68(int[] a)\n{\n    a[1] = 3;\n    int x = (a[0] += 7);\n    assert(x == 8);\n    return a[0] + a[1];\n}\n\nvoid test68()\n{\n    static assert(foo68( [1,5] ) == 11);\n}\n\n/************************************************/\n\nint foo69(char[] a)\n{\n    a[1] = 'c';\n    char x = (a[0] += 7);\n    assert(x == 'h');\n    assert(x == a[0]);\n    return a[0] + a[1] - 'a';\n}\n\nvoid test69()\n{\n    static assert(foo69(['a', 'b']) == 'j');\n}\n\n/************************************************/\n\nint foo70(int[string] a)\n{\n    a[\"world\"] = 5;\n    auto x = (a[\"hello\"] += 7);\n    assert(x == 10);\n    assert(x == a[\"hello\"]);\n    return a[\"hello\"] + a[\"betty\"] + a[\"world\"];\n}\n\nvoid test70()\n{\n    static assert(foo70([\"hello\":3, \"betty\":4]) == 19);\n}\n\n/************************************************/\n\nsize_t foo71(int[string] a)\n{\n    return a.length;\n}\n\nvoid test71()\n{\n    static assert(foo71([\"hello\":3, \"betty\":4]) == 2);\n}\n\n/************************************************/\n\nstring[] foo72(int[string] a)\n{\n    return a.keys;\n}\n\nvoid test72()\n{\n    static assert(foo72([\"hello\":3, \"betty\":4]) == [\"hello\", \"betty\"]);\n}\n\n/************************************************/\n\nint[] foo73(int[string] a)\n{\n    return a.values;\n}\n\nvoid test73()\n{\n    static assert(foo73([\"hello\":3, \"betty\":4]) == [3, 4]);\n}\n\n/************************************************/\n\nbool b74()\n{\n    string a = \"abc\";\n    return (a[$-1] == 'c');\n}\n\nconst c74 = b74();\n\nvoid test74()\n{\n    assert(c74 == true);\n}\n\n/************************************************/\n\nstruct FormatSpec\n{\n    uint leading;\n    bool skip;\n    uint width;\n    char modifier;\n    char format;\n    uint formatStart;\n    uint formatLength;\n    uint length;\n}\n\nFormatSpec GetFormat(string s)\n{\n    FormatSpec result;\n    return result;\n}\n\nFormatSpec GetFormat2(string s)\n{\n    FormatSpec result = FormatSpec();\n    result.length = 0;\n    assert(result.length < s.length);\n    while (result.length < s.length)\n    {\n        ++result.length;\n    }\n    return result;\n}\n\nvoid test75()\n{\n    static FormatSpec spec = GetFormat(\"asd\");\n\n    assert(spec.leading == 0);\n    assert(spec.modifier == char.init);\n\n    static FormatSpec spec2 = GetFormat2(\"asd\");\n    assert(spec2.length == 3);\n}\n\n/************************************************/\n\nint f76()\n{\n    int[3] a = void;\n    a[0] = 1;\n    assert(a[0] == 1);\n    return 1;\n}\n\nconst i76 = f76();\n\nvoid test76()\n{\n}\n\n/************************************************/\n\nstruct V77\n{\n    int a;\n    int b;\n}\n\nV77 f77()\n{\n    int q = 0;\n    int unused;\n    int unused2;\n    return V77(q, 0);\n}\n\nvoid test77()\n{\n    const w = f77();\n    const v = f77().b;\n}\n\n/************************************************/\n\nstruct Bar78\n{\n    int x;\n}\n\nint foo78()\n{\n    Bar78 b = Bar78.init;\n    Bar78 c;\n    b.x = 1;\n    b = bar(b);\n    return b.x;\n}\n\nBar78 bar(Bar78 b)\n{\n    return b;\n}\n\nvoid test78()\n{\n    static x = foo78();\n}\n\n/************************************************/\n\nstruct Bar79\n{\n    int y,x;\n}\n\nint foo79()\n{\n    Bar79 b = Bar79.init;\n\n    b.x = 100;\n\n    for (size_t i = 0; i < b.x; i++) { }\n\n    b.x++;\n    b.x = b.x + 1;\n\n    return b.x;\n}\n\nvoid test79()\n{\n    static x = foo79();\n    printf(\"x = %d\\n\", x);\n    assert(x == 102);\n}\n\n/************************************************/\n\nvoid test80()\n{\n}\n\n/************************************************/\n\nstring foo81()\n{\n    return \"\";\n}\n\nstring rod81(string[] a)\n{\n    return a[0];\n}\n\nvoid test81()\n{\n    static x = rod81([foo81(), \"\"]);\n    assert(x == \"\");\n}\n\n\n/************************************************/\n\nstruct S82\n{\n    string name;\n}\n\nconst S82 item82 = {\"item\"};\n\nstring mixItemList82()\n{\n    return item82.name;\n}\n\nconst string s82 = mixItemList82();\n\nvoid test82()\n{\n    assert(s82 == \"item\");\n}\n\n/************************************************/\n\nstruct S83\n{\n    string name;\n}\n\nconst S83[] items83 =\n[\n    {\"item\"},\n];\n\nstring mixItemList83()\n{\n    string s;\n    foreach (item; items83)\n        s ~= item.name;\n    return s;\n}\n\nconst string s83 = mixItemList83();\n\nvoid test83()\n{\n    writeln(s83);\n    assert(s83 == \"item\");\n}\n\n/************************************************/\n\nstruct S84 { int a; }\n\nint func84()\n{\n    S84 [] s = [S84(7)];\n    return s[0].a; // Error: cannot evaluate func() at compile time\n}\n\nvoid test84()\n{\n    const int x = func84();\n    assert(x == 7);\n}\n\n/************************************************/\n\nstruct S85\n{\n    int a;\n}\n\nsize_t func85()\n{\n    S85 [] s;\n    s ~= S85(7);\n    return s.length;\n}\n\nvoid test85()\n{\n    const size_t x = func85();\n    assert(x == 1);\n}\n\n/************************************************/\n\nstruct Bar86\n{\n    int x;\n    char[] s;\n}\n\nchar[] foo86()\n{\n    Bar86 bar;\n    return bar.s;\n}\n\nvoid test86()\n{\n    static x = foo86();\n    assert(x == null);\n}\n\n/************************************************/\n\nstruct Bar87\n{\n    int x;\n}\n\nint foo87()\n{\n    Bar87 bar;\n    bar.x += 1;\n    bar.x++;\n    return bar.x;\n}\n\nvoid test87()\n{\n    static x = foo87();\n    assert(x == 2);\n}\n\n/************************************************/\n\nint foo88()\n{\n    char[] s;\n    int i;\n\n    if (s)\n    {\n        i |= 1;\n    }\n\n    if (s == null)\n    {\n        i |= 2;\n    }\n\n    if (s is null)\n    {\n        i |= 4;\n    }\n\n    if (s == \"\")\n    {\n        i |= 8;\n    }\n\n    if (s.length)\n    {\n        i |= 16;\n    }\n\n    if (s == ['c'][0..0])\n    {\n        i |= 32;\n    }\n\n\n    if (null == s)\n    {\n        i |= 64;\n    }\n\n    if (null is s)\n    {\n        i |= 128;\n    }\n\n    if (\"\" == s)\n    {\n        i |= 256;\n    }\n\n    if (['c'][0..0] == s)\n    {\n        i |= 512;\n    }\n\n    return i;\n}\n\nvoid test88()\n{\n    static x = foo88();\n    printf(\"x = %x\\n\", x);\n    assert(x == (2|4|8|32|64|128|256|512));\n}\n\n/************************************************/\n\ntemplate Tuple89(T...)\n{\n    alias T val;\n}\n\nalias Tuple89!(int) Tup89;\n\nstring gen89()\n{\n    foreach (i, type; Tup89.val)\n    {\n        assert(i == 0);\n        assert(is(type == int));\n    }\n    return null;\n}\n\nvoid test89()\n{\n    static const string text = gen89();\n    assert(text is null);\n}\n\n/************************************************/\n\nstring bar90(string z)\n{\n    return z;\n}\n\nstring foo90(string a, string b)\n{\n    string f = a.length == 1 ? a: foo90(\"B\", \"C\");\n    string g = b.length == 1 ? b: bar90(foo90(\"YYY\", \"A\"));\n    return  f;\n}\n\nvoid test90()\n{\n    static const string xxx = foo90(\"A\", \"xxx\");\n    printf(\"%.*s\\n\", xxx.length, xxx.ptr);\n    assert(xxx == \"A\");\n}\n\n/************************************************/\n\nstruct PR91\n{\n}\n\nint foo91()\n{\n    PR91 pr;\n    pr = PR91();\n    return 0;\n}\n\nvoid test91()\n{\n    static const i = foo91();\n}\n\n/************************************************/\n\nchar find92(immutable(char)[7] buf)\n{\n    return buf[3];\n}\n\n\nvoid test92()\n{\n    static const pos = find92(\"abcdefg\");\n    assert(pos == 'd');\n}\n\n/************************************************/\n\nstatic string hello93()\n{\n    string result = \"\";\n    int i = 0;\n    for (;;)\n    {\n        result ~= `abc`;\n        i += 1;\n        if (i == 3)\n            break;\n    }\n    return result;\n}\n\nvoid test93()\n{\n    static string s = hello93();\n    assert(s == \"abcabcabc\");\n}\n\n/************************************************/\n\nint foo94 (string[] list, string s)\n{\n    if (list.length == 0)\n        return 1;\n    else\n    {\n        return 2 + foo94(list[1..$], list[0]);\n    }\n}\n\nvoid test94()\n{\n    printf(\"test94\\n\");\n    static const int x = foo94([\"a\", \"b\"], \"\");\n    assert(x == 5);\n}\n\n/************************************************/\n\nchar[] func95(immutable char[] s)\n{\n    char[] u = \"\".dup;\n    u ~= s;\n    u = u ~ s;\n    return u;\n}\n\nvoid test95()\n{\n    mixin(func95(\"{}\"));\n}\n\n/************************************************/\n\nchar[] func96(string s)\n{\n    char[] u = \"\".dup;\n    u ~= s;\n    u = u ~ s;\n    return u;\n}\n\nvoid test96()\n{\n    mixin(func96(\"{}\"));\n}\n\n/************************************************/\n\nstring foo97()\n{\n    string a;\n    a ~= \"abc\"; // ok\n    string[] b;\n    b ~= \"abc\"; // ok\n    string[][] c;\n    c ~= [\"abc\", \"def\"];\n    string[][] d = [];\n    d ~= [\"abc\", \"def\"]; // ok\n    return \"abc\";\n}\n\nvoid test97()\n{\n    static const xx97 = foo97();\n}\n\n/************************************************/\n\nimmutable(int)[] foo98(immutable(int)[][] ss)\n{\n    immutable(int)[] r;\n    r ~= ss[0]; // problem here\n    return r;\n}\n\nvoid test98()\n{\n    const r = foo98([[1], [2]]);\n}\n\n/************************************************/\n\nstruct Number\n{\n    public int value;\n    static Number opCall(int value)\n    {\n        Number n = void;\n        n.value = value;\n        return n;\n    }\n}\n\nclass Crash\n{\n    Number number = Number(0);\n}\n\nvoid test99()\n{\n}\n\n/************************************************/\n\nint[] map100 = ([4:true, 5:true]).keys;\nbool[] foo100 = ([4:true, 5:true]).values;\n\nvoid test100()\n{\n}\n\n/************************************************/\n\nint foo101()\n{\n    immutable bool [int] map = [4:true, 5:true];\n    foreach (x; map.keys) {}\n    return 3;\n}\n\nstatic int x101 = foo101();\n\nvoid test101()\n{\n}\n\n/************************************************/\n\nint foo102()\n{\n    foreach (i; 0 .. 1)\n        return 1;\n    return 0;\n}\nstatic assert(foo102() == 1);\n\nint bar102()\n{\n    foreach_reverse (i; 0 .. 1)\n        return 1;\n    return 0;\n}\nstatic assert(bar102() == 1);\n\nvoid test102()\n{\n}\n\n/************************************************/\n\nint foo103()\n{\n    foreach (c; '0' .. '9') {  }\n    foreach_reverse (c; '9' .. '0') {  }\n    return 0;\n}\n\nenum x103 = foo103();\n\nvoid test103()\n{\n}\n\n/************************************************/\n\nstruct S\n{\n    int x;\n    char y;\n}\n\n// Functions which should fail CTFE\n\nint badfoo()\n{\n    S[2] c;\n    int w = 4;\n    c[w].x = 6;  // array bounds error\n    return 7;\n}\n\nint badglobal = 1;\n\nint badfoo3()\n{\n    S[2] c;\n    c[badglobal].x = 6;  // global index error\n    return 7;\n}\n\nint badfoo4()\n{\n    static S[2] c;\n    c[0].x = 6;  // Cannot access static\n    return 7;\n}\n\n/+ // This doesn't compile at runtime\nint badfoo5()\n{\n    S[] c = void;\n    c[0].x = 6;  // c is uninitialized, and not a static array.\n    return 1;\n}\n+/\n\nint badfoo6()\n{\n    S[] b = [S(7), S(15), S(56), S(12)];\n    b[-2..4] = S(17); // exceeding (negative) array bounds\n    return 1;\n}\n\nint badfoo7()\n{\n    S[] b = [S(7), S(15), S(56), S(12), S(67)];\n    S[] c = [S(17), S(4)];\n    b[1..4] = c[]; // slice mismatch in dynamic array\n    return 1;\n}\n\nint badfoo8()\n{\n    S[] b;\n    b[1..3] = [S(17), S(4)]; // slice assign to uninitialized dynamic array\n    return 1;\n}\n\ntemplate Compileable(int z) { bool OK = true;}\nstatic assert(!is(typeof(Compileable!(badfoo()).OK)));\nstatic assert(!is(typeof(Compileable!(\n(){\n    S[] c;\n    return c[7].x;  // uninitialized error\n}()).OK\n)));\nstatic assert( is(typeof(Compileable!(0).OK)));\nstatic assert(!is(typeof(Compileable!(badfoo3()).OK)));\nstatic assert(!is(typeof(Compileable!(badfoo4()).OK)));\n//static assert(!is(typeof(Compileable!(badfoo5()).OK)));\nstatic assert(!is(typeof(Compileable!(badfoo6()).OK)));\nstatic assert(!is(typeof(Compileable!(badfoo7()).OK)));\nstatic assert(!is(typeof(Compileable!(badfoo8()).OK)));\n\n// Functions which should pass CTFE\n\nint goodfoo1()\n{\n    int[8] w;           // use static array in CTFE\n    w[] = 7;            // full slice assign\n    w[$ - 1] = 538;     // use of $ in index assignment\n    assert(w[6] == 7);\n    return w[7];\n}\nstatic assert(goodfoo1() == 538);\n\nint goodfoo2()\n{\n    S[4] w = S(101);    // Block-initialize array of structs\n    w[$ - 2].x = 917;   // use $ in index member assignment\n    w[$ - 2].y = 58;    // this must not clobber the prev assignment\n    return w[2].x;      // check we got the correct one\n}\nstatic assert(goodfoo2() == 917);\n\nstatic assert(is(typeof(Compileable!(\n(){\n    S[4] w = void;      // uninitialized array of structs\n    w[$ - 2].x = 217;   // initialize one member\n    return w[2].x;\n}()).OK\n)));\n\nint goodfoo4()\n{\n    S[4] b = [S(7), S(15), S(56), S(12)];   // assign from array literal\n    assert(b[3] == S(12));\n    return b[2].x - 55;\n}\nstatic assert(goodfoo4()==1);\n\nint goodfoo5()\n{\n    S[4] b = [S(7), S(15), S(56), S(12)];\n    b[0..2] = [S(2), S(6)];         // slice assignment from array literal\n    assert(b[3] == S(12));\n    assert(b[1] == S(6));\n    return b[0].x;\n}\nstatic assert(goodfoo5() == 2);\nstatic assert(goodfoo5() == 2);     // check for memory corruption\n\nint goodfoo6()\n{\n    S[6] b = void;\n    b[2..5] = [S(2), S(6), S(17)];  // slice assign to uninitialized var\n    assert(b[4] == S(17));\n    return b[3].x;\n}\nstatic assert(goodfoo6() == 6);\n\nint goodfoo7()\n{\n    S[8] b = void;\n    b[2..5] = S(217);   // slice assign to uninitialized var\n    assert(b[4] == S(217));\n    return b[3].x;\n}\nstatic assert(goodfoo7() == 217);\n\nint goodfoo8()\n{\n    S[] b = [S(7), S(15), S(56), S(12), S(67)];\n    b[2..4] = S(17);    // dynamic array block slice assign\n    assert(b[3] == S(17));\n    assert(b[4] == S(67));\n    return b[0].x;\n}\nstatic assert(goodfoo8() == 7);\n\n// --------- CTFE MEMBER FUNCTION TESTS --------\nstruct Q\n{\n    int x;\n    char y;\n    int opAddAssign(int w)\n    {\n        x += w;\n        return x + w;\n    }\n    Q opSubAssign(int w)\n    {\n        x -= w;\n        version(D_Version2) { mixin(\"return this;\"); } else { mixin(\"return *this;\"); }\n    }\n    int boo()  { return 4; }\n    int coo()  { return x; }\n    int foo()  { return coo(); }\n    int doo(int a)\n    {\n        Q z = Q(a, 'x');\n        z.x += 5;\n        return z.coo() + 3 * x;\n    }\n    void goo(int z) { x = z; }\n    int hoo(int y, int z) { return y + z; }\n    void joo(int z)\n    {\n        x += z;\n    }\n}\n\nint memtest1()\n{\n    Q b = Q(15, 'a');\n    return b.hoo(3, 16);    // simple const function\n}\n\nstatic assert(memtest1() == 19);\n\nint memtest2()\n{\n    Q b = Q(15, 'x');\n    b.x -= 10;\n    return b.coo();\n}\n\nstatic assert(memtest2() == 5);\n\nint memtest3()\n{\n    Q b = Q(15, 'x');\n    b.x -= 10;\n    return b.foo();\n}\n\nstatic assert(memtest3() == 5);\n\nint memtest4()\n{\n    Q b = Q(12, 'x');\n    return b.doo(514);\n}\nstatic assert(memtest4() == 519 + 3 * 12);\n\n\nint memtest5()\n{\n    Q b = Q(132, 'x');\n    b.goo(4178);    // Call modifying member\n    return b.x;\n}\nstatic assert(memtest5() == 4178);\n\nint memtest6()\n{\n    Q q = Q(1);\n    q += 3;         // operator overloading\n    return q.x;\n}\nstatic assert(memtest6() == 4);\n\nstatic assert(!is(typeof(Compileable!(Q += 2).OK)));    // Mustn't cause segfault\n\nint memtest7()\n{\n    Q q = Q(57);\n    q -= 35;\n    return q.x;\n}\n\nstatic assert(memtest7() == 57 - 35);\n\nint memtest8()\n{\n    Q[3] w;\n    w[2].x = 17;\n    w[2].joo(6);    // Modify member of array\n    w[1].x += 18;\n    return w[2].coo();\n}\n\nstatic assert(memtest8() == 6 + 17);\n\n// --------- CTFE REF PASSING TESTS --------\n\n// https://issues.dlang.org/show_bug.cgi?id=1950 - CTFE doesn't work correctly for structs passed by ref\nstruct S1950\n{\n    int x;\n}\n\nint foo1950()\n{\n    S1950 s = S1950(5);     // explicitly initialized\n    bar1950(s);\n    return s.x;\n}\n\nvoid bar1950(ref S1950 w)\n{\n    w.x = 10;\n}\n\nstatic assert(foo1950() == 10); // OK <- Fails, x is 0\n\nint foo1950b()\n{\n    S1950 s;  // uninitialized\n    bar1950(s);\n    return s.x;\n}\n\nstatic assert(foo1950b() == 10); // OK <- Fails, x is 0\n\n\n// More extreme case, related to 1950\n\nvoid bar1950c(ref int w)\n{\n    w = 87;\n}\n\nint foo1950c()\n{\n    int[5] x;\n    x[] = 56;\n    bar1950c(x[1]);     // Non-trivial ref parameters\n    return x[1];\n}\n\nstatic assert(foo1950c() == 87);\n\nvoid bar1950d(ref int[] w)\n{\n    w[1..$] = 87;\n    w[0] += 15;\n}\n\nint foo1950d()\n{\n    int[] x = [1, 2, 3, 4, 5];\n    x[1..$] = 56;\n    bar1950d(x);    // Non-trivial ref parameters\n    assert(x[0] == 16);\n    return x[1];\n}\n\nstatic assert(foo1950d() == 87);\n\n// Nested functions\nint nested(int x)\n{\n    int y = 3;\n    int inner(int w)\n    {\n        int z = 2;\n        ++z;\n        y += w;\n        return x + 3;\n    }\n\n    int z = inner(14);\n    assert(y == 17);\n    inner(8);\n    assert(y == 17 + 8);\n    return z + y;\n}\n\nstatic assert(nested(7) == 17 + 8 + 10);\nstatic assert(nested(7) == 17 + 8 + 10);\n\n// Recursive nested functions\n\nint nested2(int x)\n{\n   int y = 3;\n   int inner(int w)\n    {\n        int z = 2;\n        ++z;\n        ++y;\n        if (w <= 1)\n            return x + 3;\n        else\n            return inner(w - 1);\n    }\n\n   int z = inner(14);\n   assert(y == 17);\n\n   inner(8);\n   assert(y == 17 + 8);\n   return z + y;\n}\n\nstatic assert(nested2(7) == 17 + 8 + 10);\n\n// https://issues.dlang.org/show_bug.cgi?id=1605\n// D1 & D2. break in switch with goto breaks in ctfe\nint bug1605()\n{\n    int i = 0;\n    while (true)\n    {\n        goto LABEL;\n    LABEL:\n        if (i != 0)\n            return i;\n        i = 27;\n    }\n    assert(i == 27);\n    return 88; // unreachable\n}\n\nstatic assert(bug1605() == 27);\n\n// https://issues.dlang.org/show_bug.cgi?id=2564\n// D2 only. CTFE: the index in a tuple foreach is uninitialized (bogus error)\n// NOTE: Beware of optimizer bug 3264.\n\nint bug2564()\n{\n    version(D_Version2) { mixin(\"enum int Q = 0;\"); }else {mixin(\"int Q = 0;\"); }\n    string [2] s = [\"a\", \"b\"];\n    assert(s[Q].dup == \"a\");\n    return 0;\n}\n\nstatic int bug2564b = bug2564();\n\n\n// https://issues.dlang.org/show_bug.cgi?id=1461\n// D1 + D2. Local variable as template alias parameter breaks CTFE\nvoid bug1461()\n{\n    int x;\n    static assert(Gen1461!(x).generate() == null);\n}\n\ntemplate Gen1461(alias A)\n{\n    string generate()\n    {\n        return null;\n    }\n}\n\n/************************************************/\n\nstring foo104(string[] a...)\n{\n    string result = \"\";\n    foreach (s; a)\n        result ~= s;\n    return result;\n}\n\nmixin (foo104(\"int \", \"x;\"));\n\n/************************************************/\n\nstruct SwineFlu\n{\n    int a;\n    int b;\n}\n\nstruct Infection\n{\n    SwineFlu y;\n}\n\nstruct IveGotSwineFlu\n{\n    Infection x;\n    int z;\n    int oink() { return x.y.a + 10; }\n}\n\nint quarantine()\n{\n    IveGotSwineFlu d;\n    return d.oink();\n}\n\nstruct Mexico\n{\n    Infection x;\n    int z = 2;\n    int oink() { return z + x.y.b; }\n}\n\nint mediafrenzy()\n{\n    Mexico m;\n    return m.oink;\n}\n\nstatic assert(quarantine() == 10);\nstatic assert(mediafrenzy() == 2);\n\n/************************************************/\n\nint ctfeArrayTest(int z)\n{\n    int[] a = new int[z];\n    a[$ - 3] = 6;\n    assert(a.length == z);\n    return a[$ - 3];\n}\nstatic assert(ctfeArrayTest(15) == 6);\n\n/************************************************/\n\nchar bugzilla1298()\n{\n    char [4] q = \"abcd\".dup;\n    char [4] r = ['a', 'b', 'c', 'd'];\n    assert(q == r);\n    q[0..2] = \"xy\";\n    q[2] += 3;\n    return q[2];\n}\n\nstatic assert(bugzilla1298() == 'f');\n\nint bugzilla1790(Types...)()\n{\n    foreach (T; Types)\n    {\n    }\n    return 0;\n}\n\nconst int bugs1790 = bugzilla1790!(\"\")();\n\nchar ctfeStrTest1()\n{\n    char [8] s = void;\n    s[2..4] = 'x';\n\n   assert(s.length == 8);\n   return s[3];\n}\n\nstatic assert(ctfeStrTest1() == 'x');\n\n//--------- DELEGATE TESTS ------\n\n// Function + delegate literals inside CTFE\nint delegtest1()\n{\n    assert(function int(int a){ return 7 + a; }(16) == 23);\n    return delegate int(int a){ return 7 + a; }(6);\n}\n\nint delegtest2()\n{\n    int innerfunc1()\n    {\n        return delegate int(int a){ return 7 + a; }(6);\n    }\n    int delegate() f = &innerfunc1;\n    return 3 * f();\n}\n\nint delegtest3()\n{\n    int function() f = &delegtest1;\n    return 3 * f();\n}\n\nstruct DelegStruct\n{\n    int a;\n    int bar(int x) { return a + x; }\n}\n\nint delegtest4()\n{\n    DelegStruct s;\n    s.a = 5;\n    auto f = &s.bar;\n    return f(3);\n}\n\nalias int delegate(int) DelegType;\n\n// Test arrays of delegates\nint delegtest5()\n{\n    DelegStruct s;\n    s.a = 5;\n    DelegType[4] w;\n    w[] = &s.bar;\n    return w[2](3);\n}\n\n// Test arrays of structs of delegates\nstruct FoolishStruct\n{\n    DelegType z;\n}\n\nint delegtest6()\n{\n    DelegStruct s;\n    s.a = 5;\n    FoolishStruct[3] k;\n    DelegType u = &s.bar;\n    k[1].z = u;\n    return k[1].z(3);\n}\n\nstatic assert(delegtest1() == 13);\nstatic assert(delegtest2() == 39);\nstatic assert(delegtest3() == 39);\nstatic assert(delegtest4() == 8);\nstatic assert(delegtest5() == 8);\nstatic assert(delegtest6() == 8);\n\n// Function + delegate literals, module scope\nstatic assert(function int(int a){ return 17 + a; }(16) == 33);\nstatic assert(            (int a){ return  7 + a; }(16) == 23);\n\n// --- Test lazy ---\nint lazyTest1(lazy int y)\n{\n    return y + 1;\n}\n\nint lazyTest2(int x)\n{\n    return lazyTest1(x);\n}\n\nstatic assert(lazyTest1(7) == 8);\nstatic assert(lazyTest2(17) == 18);\n\n/************************************************/\n\nversion(D_Version2)\n{\n// https://issues.dlang.org/show_bug.cgi?id=4020\n// https://issues.dlang.org/show_bug.cgi?id=4027\n// D2 only\nstruct PostblitCrash\n{\n    int x;\n    mixin(\"this(this) { ++x; }\");\n}\n\nint bug4020()\n{\n    PostblitCrash f;\n    f.x = 3;\n    f = f;\n    f = f;\n    return f.x;\n}\nstatic assert(bug4020() == 5);\n\nstring delegate() bug4027(string s)\n{\n    return { return s; };\n}\n\n// If it compiles, it must not generate wrong code on D2.\nstatic if (is(typeof((){ static const s = bug4027(\"aaa\")(); }()))) {\n    static assert(bug4027(\"aaa\")() == \"aaa\");\n    static assert(bug4027(\"bbb\")() == \"bbb\");\n}\n}\n\n// ---\n\nvoid bug4004a(ref int a)\n{\n    assert(a == 7);\n    a += 3;\n}\n\nvoid bug4004b(ref int b)\n{\n    b = 7;\n    bug4004a(b);\n}\n\nint bug4004c()\n{\n    int offset = 5;\n    bug4004b(offset);\n    return offset;\n}\n\nstatic assert(bug4004c() == 10);\n\n// ---\n\nint bug4019()\n{\n    int[int] aa;\n    aa[1] = 2;\n    aa[4] = 6;\n    return aa[1] + aa[4];\n}\nstatic assert(bug4019() == 8);\n\n// ---\n\nstring delegate() bug4029a()\n{\n    return { return \"abc\"[]; };\n}\n\nstring bug4029()\n{\n   return bug4029a()();\n}\n\nstatic assert(bug4029() == \"abc\");\n\n/************************************************/\n\nint bug4078()\n{\n    int[] arr = new int[1];\n    return arr[0];\n}\nstatic assert(bug4078() == 0);\n\nint bug4052()\n{\n    int[] arr = new int[1];\n    int s;\n    foreach (x; arr)\n        s += x;\n    foreach (x; arr)\n        s += x * x;\n    return 4052;\n}\nstatic assert(bug4052() == 4052);\n\nint bug4252()\n{\n    char [] s = \"abc\".dup;\n    s[15] = 'd';    // Array bounds error\n    return 3;\n}\n\nstatic assert(!is(typeof(Compileable!(bug4252()))));\n\nsize_t setlen1()\n{\n    int[] w = new int[4];\n    w[] = 7;\n    w.length = 6;\n    return 21 + w.length;\n}\n\nstatic assert(setlen1() == 27);\n\nsize_t setlen2()\n{\n    int[] w;\n    w.length = 15;\n    assert(w[3] == 0);\n    w[2] = 8;\n    w[14] = 7;\n    w.length = 12;  // check shrinking\n    assert(w[2] == 8);\n    return 2 + w.length;\n}\n\nstatic assert(setlen2() == 14);\n\n/************************************************/\n\nint bug4257(ref int x)\n{\n    return 3;\n}\n\nint bug4257c(int x)\n{\n    return 3;\n}\n\nstruct Struct4257\n{\n    int foo() { return 2; }\n}\n\nvoid bug4257b()\n{\n    int y;\n    static assert(!is(typeof(Compileable!(bug4257(y)))));\n    static assert(!is(typeof(Compileable!(bug4257c(y)))));\n    Struct4257 s;\n    static assert(!is(typeof(Compileable!(s.foo()))));\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5117\n\nstatic int dummy5117 = test5117();\n\nint test5117()\n{\n    S5117 s;\n    s.change();\n    assert(s.value == 1);       // (7) succeeds\n\n    R5117 r;\n    r.s.change();\n    assert(r.s.value == 1);     // (11) fails, value == 0\n\n    return 0;\n}\n\nstruct S5117\n{\n    int value;\n    void change() { value = 1; }\n}\n\nstruct R5117\n{\n    S5117 s;\n}\n\n/************************************************/\n\nenum dummy5117b = test5117b();\n\nint test5117b()\n{\n    S5117b s;\n    getRef5117b(s).change();\n    assert(s.value == 1);     // fails, value == 0\n    return 0;\n}\nref S5117b getRef5117b(ref S5117b s) { return s; }\n\nstruct S5117b\n{\n    int value;\n    void change() { value = 1; }\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6439\n\nstruct A6439\n{\n    this(uint a, uint b)\n    {\n        begin = a;\n        end = b;\n    }\n    union\n    {\n        struct\n        {\n            uint begin, end;\n        }\n        uint[2] arr;\n    }\n}\n\nvoid test6439()\n{\n    enum y = A6439(10, 20);\n    A6439 y2 = A6439(10, 20);\n    assert(y2.begin == y.begin && y2.end == y.end);  //passes\n    assert(y.arr != [0,0]);\n    assert(y.arr == [10,20]);\n    assert(y.arr == y2.arr);\n}\n\n/************************************************/\n// from tests/fail_compilation/fail147\n\nstatic assert(!is(typeof(Compileable!(\n    (int i){\n        int x = void;\n        ++x; // used before initialization\n        return i + x;\n    }(3)\n))));\n\n// https://issues.dlang.org/show_bug.cgi?id=6504 regression\nvoid test6504()\n{\n    for (int i = 0; i < 3; ++i)\n    {\n        char[] x2 = \"xxx\" ~ ['c'];\n        assert(x2[1] == 'x');\n        x2[1] = 'q';\n    }\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=8818 regression\nvoid test8818()\n{\n    static bool test()\n    {\n        string op1 = \"aa\";\n        string op2 = \"b\";\n        assert(\"b\" >= \"aa\");\n        assert(op2 >= op1);\n        return true;\n    }\n    static assert(test());\n    assert(test());\n}\n\n/************************************************/\n\nstruct Test104Node\n{\n    int val;\n    Test104Node* next;\n}\n\nTest104Node* CreateList(int[] arr)\n{\n    if (!arr.length)\n        return null;\n    Test104Node* ret = new Test104Node;\n    ret.val = arr[0];\n    ret.next = CreateList(arr[1..$]);\n    return ret;\n}\n\nconst(Test104Node)* root = CreateList([1, 2, 3, 4, 5]);\n\nvoid test104()\n{\n    assert(root.val == 1);\n    assert(root.next.val == 2);\n    assert(root.next.next.val == 3);\n    assert(root.next.next.next.val == 4);\n    assert(root.next.next.next.next.val == 5);\n}\n\n/************************************************/\n\ninterface ITest105a\n{\n    string test105a() const;\n}\n\nclass Test105a : ITest105a\n{\n    char a;\n    int b;\n    char c = 'C';\n    int d = 42;\n    string test105a() const { return \"test105a\"; }\n}\n\ninterface ITest105b\n{\n    string test105b() const;\n}\n\nclass Test105b : Test105a, ITest105b\n{\n    char e;\n    int f;\n    this(char _e, int _f, char _a, int _b) pure\n    {\n        e = _e;\n        f = _f;\n        a = _a;\n        b = _b;\n    }\n    string test105b() const { return \"test105b\"; }\n}\n\n    const Test105b  t105b  = new Test105b('E', 88, 'A', 99);\n    const Test105a  t105a  = new Test105b('E', 88, 'A', 99);\n    const ITest105b t105ib = new Test105b('E', 88, 'A', 99);\n    const ITest105a t105ia = new Test105b('E', 88, 'A', 99);\n__gshared Test105b  t105gs = new Test105b('E', 88, 'A', 99);\n   shared Test105b  t105bs = new    shared(Test105b)('E', 88, 'A', 99);\nimmutable Test105b  t105bi = new immutable(Test105b)('E', 88, 'A', 99);\n\nvoid test105()\n{\n    assert(t105b.a == 'A');\n    assert(t105b.b == 99);\n    assert(t105b.c == 'C');\n    assert(t105b.d == 42);\n    assert(t105b.e == 'E');\n    assert(t105b.f == 88);\n    assert(t105b.test105a() == \"test105a\");\n    assert(t105b.test105b() == \"test105b\");\n\n    assert(t105a.a == 'A');\n    assert(t105a.b == 99);\n    assert(t105a.c == 'C');\n    assert(t105a.d == 42);\n    assert(t105a.test105a() == \"test105a\");\n\n    assert(t105ia.test105a() == \"test105a\");\n    assert(t105ib.test105b() == \"test105b\");\n\n    assert(t105a.classinfo is Test105b.classinfo);\n    //t105b.d = -1;\n    //assert(t105b.d == -1);\n    //assert(t105a.d == 42);\n\n    assert(t105gs.a == 'A');\n    assert(t105gs.b == 99);\n    assert(t105gs.c == 'C');\n    assert(t105gs.d == 42);\n    assert(t105gs.e == 'E');\n    assert(t105gs.f == 88);\n    assert(t105gs.test105a() == \"test105a\");\n    assert(t105gs.test105b() == \"test105b\");\n\n    assert(t105bs.a == 'A');\n    assert(t105bs.b == 99);\n    assert(t105bs.c == 'C');\n    assert(t105bs.d == 42);\n    assert(t105bs.e == 'E');\n    assert(t105bs.f == 88);\n\n    assert(t105bi.a == 'A');\n    assert(t105bi.b == 99);\n    assert(t105bi.c == 'C');\n    assert(t105bi.d == 42);\n    assert(t105bi.e == 'E');\n    assert(t105bi.f == 88);\n    assert(t105bi.test105a() == \"test105a\");\n    assert(t105bi.test105b() == \"test105b\");\n}\n\nint bug9938()\n{\n    assert(t105ia.test105a() == \"test105a\");\n    return 1;\n}\n\nstatic assert(t105ia.test105a() == \"test105a\");\nstatic assert(bug9938());\n\n/************************************************/\n\nstruct Test106\n{\n    Test106* f;\n    Test106* s;\n}\n\nTest106* ctfe106()\n{\n    auto s = new Test106;\n    auto s2 = new Test106;\n    s.f = s2;\n    s.s = s2;\n    assert(s.f is s.s);\n    return s;\n}\n\nconst(Test106)* t106 = ctfe106();\n\nvoid test106()\n{\n    assert(t106.f is t106.s);\n}\n\n/************************************************/\n\nclass Test107\n{\n    Test107 a;\n    Test107 b;\n\n    this()\n    {\n    }\n\n    this(int)\n    {\n        a = new Test107();\n        b = a;\n        assert(a is b);\n    }\n}\n\nconst Test107 t107 = new Test107(1);\n\nvoid test107()\n{\n    assert(t107.a is t107.b);\n}\n\n/************************************************/\n\n/*\ninterface Getter\n{\n    int getNum() const;\n}\n\nclass Test108 : Getter\n{\n    int f;\n    this(int v) inout\n    {\n        f = v;\n    }\n\n    int getNum() const\n    {\n        return f;\n    }\n}\n\nenum const(Test108) t108 = new Test108(38);\n\nvoid test108()\n{\n    const Test108 obj = t108;\n    assert(obj.classinfo is Test108.classinfo);\n    assert(obj.f == 38);\n\n    const Getter iobj = t108;\n    assert(iobj.getNum() == 38);\n    assert((cast(Object)iobj).classinfo is Test108.classinfo);\n    assert(t108 is t108);\n}\n*/\n\n/***** https://issues.dlang.org/show_bug.cgi?id=5678 *****/\n\n/*\nstruct Bug5678\n{\n    this(int) {}\n}\n\nenum const(Bug5678)* b5678 = new const(Bug5678)(0);\n\nvoid test5678()\n{\n    assert(b5678 is b5678);\n}*/\n\n/************************************************/\n\nclass Test109C { this(){ this.c = this; } Test109C c; }\nconst t109c = new Test109C();\n\nstruct Test109S { this(int){ this.s = &this; } Test109S* s; }\nconst t109s = new Test109S(0);\npragma(msg, t109s); // Make sure there is no infinite recursion.\n\nvoid test109()\n{\n    assert(t109c.c is t109c);\n    assert(t109s.s is t109s);\n}\n\n/************************************************/\n\nstruct Test110f { int f1; Test110s f2; }\nstruct Test110s { this(int, int, int){} }\nauto test110 = [Test110f(1, Test110s(1, 2, 3))];\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6907\n\nint test6907()\n{\n    int dtor1;\n    class C { ~this() { ++dtor1; } }\n\n    // delete on Object\n    { Object o; delete o; }\n    { scope o = new Object(); }\n    { Object o = new Object(); delete o; }\n\n    // delete on C\n    { C c; delete c; }\n    { { scope c = new C(); } assert(dtor1 == 1); }\n    { { scope Object o = new C(); } assert(dtor1 == 2); }\n    { C c = new C(); delete c; assert(dtor1 == 3); }\n    { Object o = new C(); delete o; assert(dtor1 == 4); }\n\n    int dtor2;\n    struct S1 { ~this() { ++dtor2; } }\n\n    // delete on S1\n    { S1* p; delete p; }\n    { S1* p = new S1(); delete p; assert(dtor2 == 1); }\n\n    // delete on S1[]\n    { S1[] a = [S1(), S1()]; delete a; assert(dtor2 == 3); }\n\n    return 1;\n}\nstatic assert(test6907());\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9023\n\nbool test9023()\n{\n    string[][string] aas;\n    assert(aas.length == 0);\n    aas[\"a\"] ~= \"anything\";\n    assert(aas.length == 1);\n    assert(aas[\"a\"] == [\"anything\"]);\n    aas[\"a\"] ~= \"more\";\n    assert(aas.length == 1);\n    assert(aas[\"a\"] == [\"anything\", \"more\"]);\n\n    int[int] aan;\n    assert(aan.length == 0);\n    auto x = aan[0]++;\n    assert(x == 0);\n    assert(aan.length == 1);\n    assert(aan[0] == 1);\n\n    return true;\n}\nstatic assert(test9023());\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15817\n\nS[] split15817(S)(S s)\n{\n    size_t istart;\n    S[] result;\n\n    foreach (i, c ; s)\n        result ~= s[istart .. i];\n    return result;\n}\n\nint test15817()\n{\n    auto targets = `a1`.split15817;\n    uint[string] counts;\n    foreach (a; targets)\n        counts[a]++;\n    assert(counts == [\"\":1u, \"a\":1]);\n    return 1;\n}\nstatic assert(test15817());\n\n/************************************************/\n\ninterface IBug9954\n{\n    string foo() const;\n}\n\nclass Bug9954 : IBug9954\n{\n    string foo() const { return \"hello\"; }\n}\n\nIBug9954 makeIBug9954()\n{\n    return new Bug9954;\n}\n\nconst IBug9954 b9954 = makeIBug9954();\n\nvoid test9954()\n{\n    assert(b9954.foo() == \"hello\");\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10483\n\nstruct Bug10483\n{\n    int[3][4] val;\n}\n\nstruct Outer10483\n{\n    Bug10483 p = Bug10483(67);\n}\n\nint k10483a = Outer10483.init.p.val[2][2];   // ICE(expression.c)\n\nvoid test10483()\n{\n    int k10483b = Outer10483.init.p.val[2][2]; // Segfault (backend/type.c)\n}\n\n/************************************************/\n\nstruct S10669 { uint x; }\n\nstatic const S10669 iid0_10669 = S10669(0);\n\nclass C10669\n{\n    static const S10669 iid1_10669 = S10669(1);\n};\n\nconst S10669 IID0_10669 = iid0_10669;\nconst S10669 IID1_10669 = C10669.iid1_10669;\n\n/************************************************/\n\nTypeInfo getTi()\n{\n    return typeid(int);\n}\n\nauto t112 = getTi();\n\nvoid test112()\n{\n    assert(t112.toString() == \"int\");\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10687\n\nenum Foo10687 : uint { A, B, C, D, E }\nimmutable uint[5][] m10687 = [[0, 1, 2, 3, 4]];\n\nvoid test10687()\n{\n    static immutable uint[5] a1 = [0, 1, 2, 3, 4];\n    auto   a2 = cast(immutable(Foo10687[5]))a1;\n    static a3 = cast(immutable(Foo10687[5]))a1;\n\n    auto   foos1 = cast(immutable(Foo10687[5][]))m10687;\n    static foos2 = cast(immutable(Foo10687[5][]))m10687;\n}\n\n/************************************************/\n\nvoid test113()\n{\n    import core.math;\n\n    static void compare(real a, real b)\n    {\n        writefln(\"compare(%30.30f, %30.30f);\", a, b);\n        assert(fabs(a - b) < 128 * real.epsilon);\n    }\n\n    static if (__traits(compiles, (){ enum real ctval1 = yl2x(3.14, 1); }))\n    {\n        enum real ctval1 = yl2x(3.14, 1);\n        enum real ctval2 = yl2x(2e1500L, 3);\n        enum real ctval3 = yl2x(1, 5);\n\n        real rtval1 = yl2x(3.14, 1);\n        real rtval2 = yl2x(2e1500L, 3);\n        real rtval3 = yl2x(1, 5);\n\n        compare(ctval1, rtval1);\n        compare(ctval2, rtval2);\n        compare(ctval3, rtval3);\n    }\n\n    static if (__traits(compiles, (){ enum real ctval4 = yl2xp1(3.14, 1); }))\n    {\n        enum real ctval4 = yl2xp1(3.14, 1);\n        enum real ctval5 = yl2xp1(2e1500L, 3);\n        enum real ctval6 = yl2xp1(1, 5);\n\n        real rtval4 = yl2xp1(3.14, 1);\n        real rtval5 = yl2xp1(2e1500L, 3);\n        real rtval6 = yl2xp1(1, 5);\n\n        compare(ctval4, rtval4);\n        compare(ctval5, rtval5);\n        compare(ctval6, rtval6);\n    }\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14140\n\nstruct S14140\n{\n    union\n    {\n        float[3][1] A;\n        float[3] flat;\n    }\n\n    this(in float[] args...)\n    {\n        flat[] = args[];\n    }\n}\n\nclass C14140\n{\n    union\n    {\n        float[3][1] A;\n        float[3] flat;\n    }\n\n    this(in float[] args...)\n    {\n        flat[] = args[];\n    }\n}\n\nimmutable s14140 = S14140(0, 1, 0);\nconst c14140 = new C14140(0, 1, 0);\n\nvoid test14140()\n{\n    auto s = s14140;\n    assert(s.flat == [0, 1, 0]);\n\n    auto c = c14140;\n    assert(c.flat == [0, 1, 0]);\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14862\n\nstruct S14862\n{\n    union\n    {\n        struct { uint hi, lo; }\n        ulong data;\n    }\n\n    this(ulong data)\n    {\n        this.data = data;\n    }\n}\n\nvoid test14862()\n{\n           S14862 s14862 = S14862(123UL);\n      enum S14862 e14862 = S14862(123UL);\n    static S14862 g14862 = S14862(123UL);\n\n    assert(s14862.data == 123UL);   // OK\n    assert(e14862.data == 123UL);   // OK\n    assert(g14862.data == 123UL);   // OK <- fail\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15681\n\nvoid test15681()\n{\n    static struct A { float value; }\n\n    static struct S\n    {\n        A[2] values;\n\n        this(float)\n        {\n            values[0].value = 0;\n            values[1].value = 1;\n        }\n    }\n\n    auto s1 = S(1.0f);\n    assert(s1.values[0].value == 0);        // OK\n    assert(s1.values[1].value == 1);        // OK\n\n    enum s2 = S(1.0f);\n    static assert(s2.values[0].value == 0); // OK <- NG\n    static assert(s2.values[1].value == 1); // OK\n    assert(s2.values[0].value == 0);        // OK <- NG\n    assert(s2.values[1].value == 1);        // OK\n}\n\n/************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test56();\n    test57();\n    test58();\n    test59();\n    test60();\n    test61();\n    test62();\n    test63();\n    test64();\n    test65();\n    test66();\n    test67();\n    test68();\n    test69();\n    test70();\n    test71();\n    test72();\n    test73();\n    test74();\n    test75();\n    test76();\n    test77();\n    test78();\n    test79();\n    test80();\n    test81();\n    test82();\n    test83();\n    test84();\n    test85();\n    test86();\n    test87();\n    test88();\n    test89();\n    test90();\n    test91();\n    test92();\n    test93();\n    test94();\n    test95();\n    test96();\n    test97();\n    test98();\n    test99();\n    test100();\n    test101();\n    test102();\n    test103();\n    test104();\n    test105();\n    test106();\n    test107();\n    //test108();\n    test109();\n    test112();\n    test113();\n    test6439();\n    test6504();\n    test8818();\n    test6907();\n    test9023();\n    test15817();\n    test9954();\n    test14140();\n    test14862();\n    test15681();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/interpret2.d",
    "content": "\n//import std.stdio;\nextern(C) int printf(const char*, ...);\n\ntemplate Tuple(A...)\n{\n    alias A Tuple;\n}\n\ntemplate eval(A...)\n{\n    const typeof(A[0]) eval = A[0];\n}\n\n/************************************************/\n\nint foo1()\n{\n    int x;\n    foreach (i; 0 .. 10)\n        x += i;\n    return x;\n}\n\nint bar1()\n{\n    int x;\n    foreach_reverse (i; 0 .. 10)\n    {\n        x <<= 1;\n        x += i;\n    }\n    return x;\n}\n\nvoid test1()\n{\n    const y = foo1();\n    //writeln(y);\n    assert(y == 45);\n\n    auto y1 = foo1();\n    //writeln(y1);\n    assert(y1 == 45);\n\n    const z = bar1();\n    //writeln(z);\n    assert(z == 8194);\n\n    auto z1 = bar1();\n    //writeln(z1);\n    assert(z1 == 8194);\n}\n\n/***** https://issues.dlang.org/show_bug.cgi?id=2850 *****/\n\n/* These tests are not passing, and shouldn't pass. A non-first field in a union\nbeing initialized cannot be converted to an expression, at least not until there are\nimprovements to StructLiterals.\n */\n\nversion (none)\n{\nstruct Bug2850\n{\n    union\n    {\n        int c;\n        double d;\n    }\n    int b;\n    int a;\n}\n\nstatic assert(is(typeof(\n () { enum Bug2850 w = {b:47, 714, d:4}; return w; }\n)));\nstatic assert(is(typeof(\n () { enum Bug2850 w = {b:47, d:4}; return w; }\n)));\n// union not initialized\nstatic assert(!is(typeof(\n () { enum Bug2850 w = {b:47, 4}; return w; }\n)));\n// initializers for two fields in same union\nstatic assert(!is(typeof(\n () { enum Bug2850 w = {b:47, 4, c:5, 9}; return w; }\n)));\n\nenum Bug2850 test2850 = {b:47, 714, d:23.1e-17};\n\nstruct Horrid2850\n{\n    union\n    {\n        int a;\n        int b;\n        struct\n        {\n            int c;\n            int d;\n        }\n    }\n    int f;\n    double q;\n}\n\nenum Horrid2850 horrid2850 = {c:5,6};\nHorrid2850 m2850 = {47, f:6};\nHorrid2850 z2850 = {q:5, c:4, d:5};\n\nstatic assert(!is(typeof(\n () { enum Horrid2850 w = {c:47, d:5, a:7}; return w; }\n)));\n\nvoid test2()\n{\n    assert(test2850.a == 714);\n    assert(test2850.b == 47);\n    assert(test2850.d == 23.1e-17);\n    assert(test2850.c != 0);\n}\n}\n\n/***** https://issues.dlang.org/show_bug.cgi?id=3779 *****/\n\nstatic const bug3779 = [\"123\"][0][$-1];\n\n/***** https://issues.dlang.org/show_bug.cgi?id=1880 *****/\n\n\nenum Property1880 {First=1,Second=2}\n\nstruct CompileTimeCheck1880(Property1880 Prop)\n{\n    alias Prop prop;\n}\nProperty1880 junkprop1880;\nstatic assert(!is(CompileTimeCheck1880!(junkprop1880)));\n\nint main()\n{\n    test1();\n//    test2();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/issue16995.d",
    "content": "// REQUIRED_ARGS: -unittest\n// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/module_with_tests.d imports/another_module_with_tests.d\n\nimport imports.module_with_tests;\nimport imports.another_module_with_tests;\nimport core.exception: AssertError;\n\nshared static this()\n{\n    import core.runtime: Runtime, UnitTestResult;\n    Runtime.extendedModuleUnitTester = () => UnitTestResult.pass;\n}\n\nvoid main()\n{\n    foreach(i, ut; __traits(getUnitTests, imports.module_with_tests))\n    {\n        try\n        {\n            ut();\n            assert(i == 0, \"2nd unittest should fail\");\n        }\n        catch(AssertError e)\n        {\n            assert(i == 1, \"Only 2nd unittest should fail\");\n        }\n    }\n\n    foreach(i, ut; __traits(getUnitTests, imports.another_module_with_tests))\n    {\n        try\n        {\n            ut();\n            assert(i == 0 || i == 1, \"3rd unittest should fail\");\n        }\n        catch(AssertError e)\n        {\n            assert(i == 2, \"Only 3rd unittest should fail\");\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/issue8671.d",
    "content": "import std.random;\nvoid main()\n{\n    double t = 1.0 - uniform(0.0, 1.0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/lazy.d",
    "content": "import core.vararg;\nimport std.stdio;\n\n/*********************************************************/\n\nvoid ifthen(bool cond, lazy void dg)\n{\n    if (cond)\n        dg();\n}\n\nvoid ifthen(bool cond, lazy void dgthen, lazy void dgelse)\n{\n    if (cond)\n        dgthen();\n    else\n        dgelse();\n}\n\nvoid dotimes(int i, lazy int dg)\n{\n    for (int j = 0; j < i; j++)\n        dg();\n}\n\nvoid switcher(bool delegate()[] cases...)\n{\n    foreach (c; cases)\n    {\n        if (c())\n            break;\n    }\n}\n\nbool scase(bool b, lazy void dg)\n{\n    if (b)\n    {\n        dg();\n        return true;\n    }\n    return false;\n}\n\nbool sdefault(lazy void dg)\n{\n    dg();\n    return true;\n}\n\nvoid whiler(lazy bool cond, lazy void bdy)\n{\n    while (cond())\n        bdy();\n}\n\nvoid test1()\n{\n    int x = 3;\n    dotimes(5, printf(\"%d\\n\", ++x));\n\n    ifthen(true, printf(\"yes\\n\"));\n    ifthen(false, printf(\"no\\n\"));\n\n    ifthen(true, printf(\"yes\\n\"), printf(\"no\\n\"));\n    ifthen(false, printf(\"yes\\n\"), printf(\"no\\n\"));\n\n    int v = 2;\n    switcher(\n        scase(v == 1, printf(\"it is 1\\n\")),\n        scase(v == 2, printf(\"it is 2\\n\")),\n        scase(v == 3, printf(\"it is 3\\n\")),\n        sdefault( printf(\"it is default\\n\"))\n    );\n\n    whiler( x < 100,\n        (){ printf(\"%d\\n\", x); x *= 2; }()\n    );\n}\n\n/*********************************************************/\n\nvoid fooa(lazy void dg)\n{\n    dg();\n}\n\nvoid test2()\n{\n    fooa(cast(void)null);\n}\n\n/*********************************************************/\n\nvoid dotimes3(int count, lazy void exp)\n{\n    for (int i = 0; i < count; i++)\n       exp;\n}\n\nvoid bar3(...)\n{\n    assert(_arguments.length == 1);\n    assert(va_arg!int(_argptr) == 14);\n}\n\nvoid abc3(int* p)\n{\n    writeln(*p);\n    assert(*p == 3);\n}\n\nvoid test3()\n{\n    int x = 3;\n    dotimes3(10, abc3(&x));\n    dotimes3(10, write(++x));\n    writeln();\n    dotimes3(1, bar3(++x));\n\n    int[10] a = new int[10];\n    a[0] = 1;\n    a[$ - 1] = 9;\n    dotimes3(3, write(a[0..$]));\n    writeln();\n}\n\n/*********************************************************/\n\nint p4;\n\nvoid foo4(void* delegate()[] dgs...)\n{\n    assert(dgs.length == 4);\n    writefln(\"%s %s\", dgs[0](), cast(void*)&p4);\n    assert(dgs[0]() == cast(void*)&p4);\n    assert(dgs[1]() == cast(void*)&p4);\n    assert(dgs[2]() == null);\n    assert(dgs[3] == null);\n}\n\nvoid test4()\n{\n    void *abc()\n    {\n        writeln(cast(void*)&p4);\n        return cast(void*)&p4;\n    }\n\n    foo4(&abc, cast(void* delegate())&abc, null, cast(void* delegate())null);\n}\n\n/*********************************************************/\n\nbool nextis(void delegate() dgpositive = {})\n{\n    return true;\n}\n\nbool looping(lazy bool condition)\n{\n    return true;\n}\n\nvoid test5()\n{\n    looping(nextis({}));\n    looping(nextis({}));\n}\n\n/*********************************************************/\n\nvoid foo6(lazy int expr, ...)\n{\n    char[] tmp_msg = va_arg!(char[])(_argptr);\n    if (cast(int)(tmp_msg.ptr)==\"food_for_thought\".length)\n         assert(0, \"length is in the pointer!\");\n    assert(tmp_msg==\"food_for_thought\");\n}\n\nint bar6() { return 3; }\n\nvoid test6()\n{\n    foo6(bar6(),\"food_for_thought\");\n}\n\n/*********************************************************/\n\nvoid foo7(long delegate()[] dg...)\n{\n    assert(dg[0]() == 1024);\n    assert(dg[1]() == 1024);\n}\n\nvoid bar7(lazy long n)\n{\n    assert(n == 1024);\n}\n\nvoid test7()\n{\n    int n = 1024;\n    foo7(n, n);\n    bar7(n);\n}\n\n/*********************************************************/\n\nstruct Bug5750 { int a, b; }\npure Bug5750 bug5750(lazy int y) {\n    Bug5750 retval;\n    retval.a = y;\n    retval.b = y;\n    return retval;\n}\n\npure void test5750a() {\n    auto z1 = bug5750(3);\n    assert(z1 == Bug5750(3, 3));\n    auto z2 = bug5750(z1.a);\n    assert(z2 == Bug5750(3, 3));\n    auto z3 = bug5750(z1.a+z2.a+3);\n    assert(z3 == Bug5750(9, 9));\n    auto z4 = bug5750(++z1.a);    // expected???\n    assert(z4 == Bug5750(4, 5));\n    assert(z1 == Bug5750(5, 3));\n}\n\nint bug5750Global = 7;\nvoid test5750b() {\n    auto z4 = bug5750(bug5750Global);\n    assert(z4 == Bug5750(7, 7));\n    auto z5 = bug5750(++bug5750Global);\n    assert(z5 == Bug5750(8, 9));  // expected???\n    assert(bug5750Global == 9);\n}\n// Note: also need to make up some fail-compilation tests.\n\n/*********************************************************/\n\nT calcLazy6682(T)(lazy T n)\n{\n    return n;\n}\nint purefunc6682() pure\n{\n    return calcLazy6682(1);\n}\nvoid test6682()\n{\n    assert(purefunc6682() == 1);\n}\n\n/*********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9109\n\nvoid test9109()\n{\n    void foo(int delegate()[] dgs ...)\n    {\n        assert(dgs[0]() + dgs[1]() == 1 + 13);\n    }\n\n    int x = 10;\n    int delegate() dg;\n    foo({ return 1; }, { return 3+x; }, dg, null);\n}\n\n/*********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15835\n\nclass C15835 {}\n\nstring fun15835(lazy string s)\n{\n    return s;\n}\n\nvoid test15835()\n{\n    auto c = new C15835;\n    auto s = typeid(c).name;\n    assert(fun15835(typeid(c).name) == s);\n\n    auto a = [c];\n    assert(fun15835(typeid(a[0]).name) == s);\n}\n\n/*********************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n\n    test5750a();\n    test5750b();\n    test6682();\n    test9109();\n    test15835();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ldc_github_1677.d",
    "content": "interface IBar(T)\n{\n    IFoo!T ownerDocument();\n}\n\ninterface IFoo(T): IBar!T\n{\n    // un-commenting the following line solves the issue\n    //IList!T getList();\n}\n\ninterface IList(T) {}\n\nclass DOMImplementation(T)\n{\n    class BarImpl: IBar!T\n    {\n        FooImpl ownerDocument() { return null; }\n    }\n    class FooImpl: BarImpl, IFoo!T\n    {\n        IList!T getList() { return null; }\n    }\n}\n\nvoid main()\n{\n    auto impl = new DOMImplementation!string();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/lexer.d",
    "content": "// REQUIRED_ARGS:\n\n\n/*********************************************************/\n\nvoid test6()\n{\n    string s = q\"(foo(xxx))\";\n    assert(s == \"foo(xxx)\");\n\n    s = q\"[foo[xxx]]\";\n    assert(s == \"foo[xxx]\");\n\n    s = q\"{foo{xxx}}\";\n    assert(s == \"foo{xxx}\");\n\n    s = q\"<foo<xxx>>\";\n    assert(s == \"foo<xxx>\");\n\n    s = q\"[foo(]\";\n    assert(s == \"foo(\");\n\n    s = q\"/foo]/\";\n    assert(s == \"foo]\");\n\n\n    s = q\"HERE\nfoo\nHERE\";\n    //writefln(\"'%s'\", s);\n    assert(s == \"foo\\n\");\n\n\n    s = q{ foo(xxx) };\n    assert(s ==\" foo(xxx) \");\n\n    s = q{foo(};\n    assert(s == \"foo(\");\n\n    s = q{{foo}/*}*/};\n    assert(s == \"{foo}/*}*/\");\n\n    s = q{{foo}\"}\"};\n    assert(s == \"{foo}\\\"}\\\"\");\n}\n\n/*********************************************************/\n\nvoid test7()\n{\n//    auto str = \\xDB;\n//    assert(str.length == 1);\n}\n\n/*********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4633\n\ntemplate Types(alias v)\n{\n    alias typeof(v) Types;\n}\n\ntypeof({return 1;}()) a; // ok\nTypes!({return 1;}()) x; // ok\n\nvoid test8()\n{\n    typeof({return 1;}()) b;\n    Types!({return 1;}()) y;\n}\n\n/*********************************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=6584\nversion(9223372036854775807){}\ndebug(9223372036854775807){}\n\n/*********************************************************/\n\nenum e13102=184467440737095516153.6L;\n\n/*********************************************************/\n\nint main()\n{\n    test6();\n    test7();\n    test8();\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link10425.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/bug10425.d\n\nimport imports.bug10425;\n\nvoid main()\n{\n    auto ti = typeid(A!());\n    /* Today, taking TypeInfo object address by using `typeid` always generates\n     * the TypeInfo object on comdat section (done by TypeInfoDeclaration::toObjFile),\n     * even if the associated struct belongs *non-root modules*.\n     *\n     * And, from 2.062, issue 7511 is implemented.\n     * The attribute inference for member functions in instantiated struct may modify\n     * their actual mangled names. Then TypeInfo object compiled in this module would\n     * use wrong symbol names, to link non-template opEquals/opCmp/toHash/toString\n     * member functions.\n     *\n     * To fix the issue, we should run semantic3 to calculate the correct symbol names\n     * of the specific member functions.\n     */\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link10920.d",
    "content": "// PERMUTE_ARGS: -version=A\n\n// It's imported but won't be linked.\nimport imports.link10920a;\n\nvoid main()\n{\n    BitArray ba;\n    version(A)\n    {\n        // Run semantic3 of BitArray.toString()\n        // before the FormatSpec instantiation in main().\n        pragma(msg, typeof(ba.toString()));\n    }\n\n    // The instance codegen should be run always, unrelated with -version=A.\n    FormatSpec!char fs;\n    fs.func();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link11069a.d",
    "content": "// REQUIRED_ARGS: -noboundscheck\n// <-- To remove necessity of _D7imports13std11069array7__arrayZ\n\nclass Bar\n{\n    import imports.std11069container;\n\n    BinaryHeap!(Foo[]) Heap;\n\n    struct Foo {}\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link11069b.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/link11069x.d imports/link11069y.d imports/link11069z.d\n\nimport imports.link11069y;\nimport imports.link11069z;\n\nvoid foo()\n{\n    Vector2 rsm;\n    readWriteVariable(rsm);\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link11127.d",
    "content": "import imports.link11127a;\n\nvoid main()\n{\n    cycle([1, 2]);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link11395.d",
    "content": "// EXTRA_SOURCES: imports/link11395a.d\n// PERMUTE_ARGS:\n// COMPILE_SEPARATELY\nmodule link11395;\nimport imports.link11395a;\n\nvoid main()\n{\n    SB s;\n    SB[] a;\n\n    a ~= s;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link11931.d",
    "content": "// REQUIRED_ARGS: -g\n// PERMUTE_ARGS:\n// EXTRA_SOURCES: imports/test11931a.d\n// EXTRA_SOURCES: imports/test11931b.d\n// EXTRA_SOURCES: imports/test11931c.d\n// EXTRA_SOURCES: imports/test11931d.d\n// COMPILE_SEPARATELY: -g\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link12010.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/a12010.d imports/std12010container.d\n// REQUIRED_ARGS: -release\n// -release is necessary to avoid __assert.\n\nimport imports.a12010;\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link12037.d",
    "content": "import imports.a12037;\n\nalias CustomFloat!(10, 5) Float16;\n\nvoid main()\n{\n    Float16 f = 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link12144.d",
    "content": "// COMPILE_SEPARATELY: -g\n// EXTRA_SOURCES: imports/link12144a.d\n\nimport imports.link12144a;\n\nvoid main()\n{\n    fun();\n}\n\nstruct A12146\n{\n    B12146[] tokens;\n    // implicitly generated\n    //   bool opEquals(const ref Appender rhs) const\n    // will make\n    //   tokens == rhs.tokens\n    // references TypeInfo of B12146\n    // and it references __xopCmp\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link13043.d",
    "content": "// PERMUTE_ARGS: -g -inline -version=bug -release -O\n\nimport imports.link13043a;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link13350.d",
    "content": "extern (C) int printf(const(char*) fmt, ...);\n\nstatic int foo();\n\n/**********************************/\n\nauto red()()\n{\n    return foo();\n}\n\nvoid test13350()\n{\n    int[] data;\n    assert(is(typeof(red())));\n}\n\n/**********************************/\n\nstruct A1(T) { void f1() {} }\nstruct B1(T) { void f2() {} }\n\nA1!(B1!int) func1()() { return typeof(return).init; }\n\nvoid test1()\n{\n    static if (is(typeof(func1()) R : X!(Y), alias X, Y))\n    {\n        R.init.f1();\n        Y.init.f2();\n    }\n    else\n        static assert(0);\n}\n\n/**********************************/\n\nstruct A2(T) { void f1() { foo(); } }\nstruct B2(T) { void f2() { foo(); } }\n\nA2!(B2!int) func2()() { return typeof(return).init; }\n\nvoid test2()\n{\n    static if (is(typeof(func2())))\n    {\n    }\n    else\n        static assert(0);\n}\n\n/**********************************/\n\ntemplate A3() { void foo() { B3!().bar(); } }\ntemplate B3() { void bar() {} }\n\nvoid test3()\n{\n    // A3!() and B3!() are marked as 'speculative'\n    static assert(is(typeof(A3!().foo())));\n\n    // A3!() is unspeculative, but B3!() isn't.\n    A3!().foo();\n\n    // in codegen phase, B3!() will generate its members, because\n    // the tinst chain contains unspeculative instance A3!().\n}\n\n/**********************************/\n\nstruct S4(T)\n{\n    string toString() const { return \"instantiated\"; }\n}\n\nvoid test4()\n{\n    // inside typeof is not speculative context\n    alias X = typeof(S4!int());\n    assert(typeid(X).xtoString !is null);\n}\n\n/**********************************/\n\nstruct S5(T)\n{\n    string toString() const { return \"instantiated\"; }\n}\n\nvoid test5()\n{\n    enum x = S5!int();\n    assert(x.toString() == \"instantiated\");\n}\n\n/**********************************/\n\nint foo6()() { return 0; }\n\ntemplate A6() { alias f = foo6!(); }\nvoid testa6()() if (is(typeof(A6!().f))) {}\n\ntemplate B6() { alias f = foo6!(); }\nvoid testb6()() if (is(typeof(B6!().f))) {}\n\ntemplate C6() { void f() { B6!().f(); } }\n\nvoid test6()\n{\n    testa6();\n    // foo6!() is speculatively instantiated from A6!() [TemplateInstance a]\n    // -> foo6!() is instantiated in A6!(), so it should be inserted to the members of this module.\n\n    testb6();\n    // foo6!() is speculatively instantiated from B6!() [TemplateInstance b],\n    // but the tinst of cached [TemplateInstance a] is not changed.\n    // -> insert [b] to the tnext chain of [a]\n\n    C6!().f();\n    // foo6!() is used through C6!(), so it should be linked to the final executable.\n    // but its first instance does not link to any non-speculative instances.\n    // -> look for tnext chain and determine its codegen is really necessary.\n}\n\n/**********************************/\n\nint main()\n{\n    test13350();\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link13394.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/link13394a.d\n\nmodule link13394;\nimport imports.link13394a;\n\nvoid main()\n{\n    auto b = new B();\n\n    auto s = S();\n    s.func();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link13400.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/link13400a.d\n\nimport imports.link13400a;\n\nvoid main()\n{\n    BigInt r;\n\n    // This comparison will instantiate BigInt.opEquals!().opEquals(const BigInt y) const pure again.\n    // But here is non-speculative context, so this module compilation should generate its objcode.\n    bool b = r == BigInt(\"2\");  // comparison with rvalue\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link13415.d",
    "content": "// EXTRA_SOURCES: imports/link13415a.d\n// REQUIRED_ARGS: -inline\n// PERMUTE_ARGS: -allinst -unittest -debug\n// COMPILE_SEPARATELY\n\nimport imports.link13415a;\n\nvoid main()\n{\n    f();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link13843.d",
    "content": "template binaryFun(alias fun)\n{\n    static if (is(typeof(fun) : string))\n    {\n        auto binaryFun(E1, E2)(E1 a, E2 b)\n        {\n            return mixin(fun);\n        }\n    }\n    else\n    {\n        alias binaryFun = fun;\n    }\n}\n\nclass Foo(int n, alias greater = \"a > b\")\n{\n    private alias binaryFun!(greater) compare;\n\n    public this()\n    {\n        //assert(compare(2, 1));\n        // 'compare' -> FuncExp\n\n        assert(this.compare(2, 1));\n        // old: 'this.compare' -> DotVarExp (e1: ThisExp, var: FuncLiteralDeclaration)\n        // new: 'this.compare' -> CommaExp (e1: ThisExp, e2: FuncExp)\n\n        // Then, in both cases lambda->toObjFile() will run via FuncExp::toElem().\n    }\n}\n\nvoid main()\n{\n    // OK\n    auto foo1 = new Foo!(1, \"a > b\");\n    auto foo2 = new Foo!(2, (a, b) => a > b);\n    auto foo3 = new Foo!(3, delegate(a, b){ return a > b; });\n\n    // OK <- NG\n    auto foo4 = new Foo!(4, (int a, int b) => a > b);\n    auto foo5 = new Foo!(5, function(int a, int b){ return a > b; });\n    auto foo6 = new Foo!(6, delegate(int a, int b){ return a > b; });\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link14074a.d",
    "content": "// EXTRA_SOURCES: imports/link14074y.d\nimport imports.link14074x;\nimport imports.link14074y;\n\nstruct Inner\n{\n}\n\nstruct Test\n{\n    Inner inner;\n}\n\n\nvoid main()\n{\n    ubyte[] buffer;\n    Test test;\n\n    encodeArray(buffer, test);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link14074b.d",
    "content": "import imports.link14074z;\n\nvoid main()\n{\n    replaceAllWith!()(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link14425.d",
    "content": "struct SFoo(I) { I i; }\nstruct SBar(I) { I i; }\nstatic assert(is(SFoo!(SBar!string)));\n\nclass CFoo(I) { I i; }\nclass CBar(I) { I i; }\nstatic assert(is(CFoo!(CBar!string)));\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link14541.d",
    "content": "import imports.link14541traits;\n\nvoid main()\n{\n    Tuple!(int, int) result;\n\n    alias T = typeof(result);\n    static assert(hasElaborateAssign!T);\n    // hasElaborateAssign!(Tuple(int, int)):\n    // 1. instantiates Tuple!(int, int).opAssign!(Tuple!(int, int)) [auto ref = Rvalue]\n    //    2. instantiates swap!(Tuple!(int, int))\n    //       3. instantiates hasElaborateAssign!(Tuple!(int, int))\n    //          --> forward reference error\n    //       --> swap!(Tuple!(int, int)) fails to instantiate\n    //    --> Tuple!(int, int).opAssign!(Tuple!(int, int)) [auto ref = rvalue] fails to instantiate\n    // 4. instantiates Tuple!(int, int).opAssign!(Tuple!(int, int)) [auto ref = Lvalue]\n    //    --> succeeds\n    // hasElaborateAssign!(Tuple(int, int)) succeeds to instantiate (result is 'true')\n\n    // Instantiates Tuple!(int, int).opAssign!(Tuple!(int, int)) [auto ref = Rvalue], but\n    // it's already done in gagged context, so this is made an error reproduction instantiation.\n    // But, the forward reference of hasElaborateAssign!(Tuple(int, int)) is already resolved, so\n    // the instantiation will succeeds.\n    result = Tuple!(int, int)(0, 0);    // --> 1st error reproduction instantiation\n    result = Tuple!(int, int)(0, 0);    // --> 2nd error reproduction instantiation\n\n    // The two error reproduction instantiations generate the function:\n    //   Tuple!(int, int).opAssign!(Tuple!(int, int)) [auto ref = Rvalue]\n    // twice, then it will cause duplicate COMDAT error in Win64 platform.\n}\n\n/+\nThe point is, if instantiated contexts are different, two instantiations may cause different result.\n\n- The 1st Tuple.opAssign instantiation is invoked from hasElaborateAssign template with gagging.\n  So it has failed, because of the circular reference of hasElaborateAssign template..\n\n- The 2nd Tuple.opAssign instantiation is invoked from main() without gagging.\n  It does not have circular reference, so the instantiation should succeed.\n\nTherefore, the gagged failure should be overridden by the ungagged success.\n+/\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link14588.d",
    "content": "// EXTRA_SOURCES: imports/link14588a.d\n// PERMUTE_ARGS: -allinst -unittest -debug -inline\n// COMPILE_SEPARATELY\n\nimport imports.link14588a;\n\nvoid main()\n{\n    new A().all();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link14814.d",
    "content": "// EXTRA_SOURCES: imports/link14814a.d\n// PERMUTE_ARGS: -inline -release -g -O -fPIC\n// COMPILE_SEPARATELY\n\nimport imports.link14814a;\n\nvoid main()\n{\n    fun4;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link14992.d",
    "content": "import imports.a14992;  // do not link\n\nint test()\n{\n    S1 v1;      // OK\n    S1* p1;     // OK\n    S1[] da1;   // OK\n    S1[2] a1;   // OK <- NG\n\n    S2 v2;      // OK\n    S2* p2;     // OK\n    S2[] da2;   // OK\n    S2[2] a2;   // OK <- NG\n\n    return 1;\n}\nstatic assert(test());\n\nvoid main()\n{\n    test();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link15017.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/std15017variant.d\n\nimport imports.std15017variant;\n\nvoid test()\n{\n    // OK <- in IndexExp::semantic\n    Variant1[string] aa1;\n    aa1[\"abc\"] = Variant1();\n\n    // already ok in CatExp::semantic with checkPostblit\n    Variant2[] a2;\n    a2 = a2 ~ Variant2();\n\n    // already ok in CatAssignExp::semantic with checkPostblit\n    Variant3[] a3;\n    a3 ~= Variant3();\n\n    // OK <- in CmpExp::semantic\n    Variant4[] a4;\n    assert(a4 < a4);\n\n    // already OK in needDirectEq from EqualExp::semantic\n    Variant5[] a5;\n    assert(a5 == a5);\n\n    // already OK in EqualExp::semantic\n    Variant6[Variant7] aa67;\n    assert(aa67 == aa67);\n\n    // OK <- in InExp::semantic\n    string[Variant8] aa8;\n    assert(Variant8() in aa8);\n\n    // OK <- in resolveUFCS with RemoveExp\n    string[Variant9] aa9;\n    aa9.remove(Variant9());\n\n    // OK <- in DeleteExp::semantic\n    Variant10* p10;\n    delete p10;\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link15021.d",
    "content": "// PERMUTE_ARGS: -inline -g -debug -unittest\n\nimport imports.std15021conv;\n\nclass AliasDecl {}\n\nvoid aliasDecl(AliasDecl ad)\n{\n    AliasDecl* zis;\n\n    static if (is(typeof(to!string(*zis))))\n    {\n        pragma(msg, \"hit!\");\n        to!string(*zis);\n    }\n}\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link15149.d",
    "content": "// REQUIRED_ARGS: -g\n// PERMUTE_ARGS: -inline -version=A\n// EXTRA_SOURCES: imports/link15194b.d imports/link15194std.d\n// COMPILE_SEPARATELY: -g\n\nimport imports.link15194std;\nimport imports.link15194b;\n\nvoid main()\n{\n    int[] foo;\n\n    // fun() returns new RedBlackTree!int. But it's instantiated in\n    // non-template non-root function, so it's left as speculative.\n    setUnion(fun()[], foo);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link2500.d",
    "content": "// EXTRA_SOURCES: imports/link2500a.d\n// EXTRA_SOURCES: imports/link2500b.d\n// COMPILE_SEPARATELY:\n\nmodule link2500;\n\nimport imports.link2500a;\nimport imports.link2500b;\n\npublic class A\n{\n    S!A c;\n}\n\nvoid main()\n{\n    A a = new A();\n    a.c.foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link2644.d",
    "content": "// PERMUTE_ARGS: -version=X -inline -release -g -O\n// EXTRA_SOURCES: imports/link2644a.d imports/link2644b.d imports/link2644c.d\n// COMPILE_SEPARATELY:\n\nmodule link2644;\nimport imports.link2644a;\n\nvoid main()\n{\n  version(X)\n    auto c = new X.CA();\n  else\n    auto c = new CA();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link6574.d",
    "content": "// PERMUTE_ARGS:\nmodule link6574;\n\nimport imports.testmangle;\n\nenum Method { A, B, }\n\nint foo(Method method = Method.A)()\n{\n    static assert(foo.mangleof == \"_D8link6574\"~tl!\"28\"~\"__T3fooVE\"~id!(\"8link6574\",\"Qs\")~\"6Methodi0Z\"~id!(\"3foo\",\"Qs\")~\"FZi\");\n    return 10 * foo!method();\n}\nint foo(Method method : Method.A)()\n{\n    static assert(foo.mangleof == \"_D8link6574\"~tl!\"29\"~\"__T3fooHVE\"~id!(\"8link6574\",\"Qt\")~\"6Methodi0Z\"~id!(\"3foo\",\"Qt\")~\"FZi\");\n    return 2;\n}\nint foo(Method method : Method.B)()\n{\n    static assert(0);\n    return 3;\n}\n\nint bar(Method method = Method.B)()\n{\n    static assert(bar.mangleof == \"_D8link6574\"~tl!\"28\"~\"__T3barVE\"~id!(\"8link6574\",\"Qs\")~\"6Methodi1Z\"~id!(\"3bar\",\"Qs\")~\"FZi\");\n    return 10 * bar!method();\n}\nint bar(Method method : Method.A)()\n{\n    static assert(0);\n    return 2;\n}\nint bar(Method method : Method.B)()\n{\n    static assert(bar.mangleof == \"_D8link6574\"~tl!\"29\"~\"__T3barHVE\"~id!(\"8link6574\",\"Qt\")~\"6Methodi1Z\"~id!(\"3bar\",\"Qt\")~\"FZi\");\n    return 3;\n}\n\nvoid main()\n{\n    assert(foo!() == 10 * 2);\n    assert(foo() == 10 * 2);\n\n    assert(bar!() == 10 * 3);\n    assert(bar() == 10 * 3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link7745.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/link7745b.d\n// PERMUTE_ARGS:\n\nimport imports.link7745b;\n\nbool forceSemantic7745()\n{\n   C c;\n   c.asdfg();\n  return true;\n}\nstatic assert(forceSemantic7745());\n\nvoid f(C c) { auto x = &c.asdfg; }\n\nvoid main() {\n    // https://issues.dlang.org/show_bug.cgi?id=4820\n    nextis!(int)();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link7966.d",
    "content": "enum E { i }\n\nstruct S1 { bool opCast(T)() { return true; } }\nstruct S2 { bool opCast(T)() { return true; } }\n\nimport a = core.stdc.stdio;\n\nvoid main()\n{\n    with (E)            // exp == TOKtype\n        assert(S1());   // Doesn't enclose in ScopeStatement\n    assert(S1());\n\n    with (a)            // exp == TOKimport\n        assert(S2());   // Doesn't enclose in ScopeStatement\n    assert(S2());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link8023.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/link8023b.d\n// PERMUTE_ARGS: -inline -release\n\nimport imports.link8023b;\n\nprivate void t(alias Code)()\n{\n  return Code();\n}\n\nvoid f()\n{\n  t!( () { } )();\n}\n\nvoid main() {\n  f();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/link9571.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/link9571a.d\n\nimport imports.link9571a;\n\nvoid main()\n{\n    foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/linktypeinfo.d",
    "content": "// EXTRA_SOURCES: imports/linktypeinfo_file.d\n// PERMUTE_ARGS: -g -inline -unittest -debug\n// COMPILE_SEPARATELY\n\nimport imports.linktypeinfo_file;\n\nstruct Only(T)\n{\n    private T _val;\n}\n\nauto only(V)(V v)\n{\n    return Only!V(v);\n}\n\nstatic struct Chain(R...)\n{\n    R source;\n}\n\nauto chain(R...)(R rs)\n{\n    return Chain!R(rs);\n}\n\nvoid main()\n{\n    string docRoot;\n\n    const r = dirEntries(docRoot);\n    typeof(r)[] a;\n    a.length = 0;   // require TypeInfo for const(FilterResult!(DirIterator))\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/literal.d",
    "content": "\nextern(C) int printf(const char*, ...);\n\nenum\n{\n    T_char,\n    T_wchar,\n    T_dchar,\n    T_bit,\n    T_byte,\n    T_ubyte,\n    T_short,\n    T_ushort,\n    T_int,\n    T_uint,\n    T_long,\n    T_ulong,\n}\n\nint dotype(char x) { return T_char; }\nint dotype(bool x) { return T_bit; }\nint dotype(byte x) { return T_byte; }\nint dotype(ubyte x) { return T_ubyte; }\nint dotype(wchar x) { return T_wchar; }\nint dotype(short x) { return T_short; }\nint dotype(ushort x) { return T_ushort; }\nint dotype(int x) { return T_int; }\nint dotype(uint x) { return T_uint; }\nint dotype(long x) { return T_long; }\nint dotype(ulong x) { return T_ulong; }\n\nvoid test1()\n{\n    /*\n     * 0x7FFF             077777                  32767\n     * 0x8000             0100000                 32768\n     * 0xFFFF             0177777                 65535\n     * 0x10000            0200000                 65536\n     * 0x7FFFFFFF         017777777777            2147483647\n     * 0x80000000         020000000000            2147483648\n     * 0xFFFFFFFF         037777777777            4294967295\n     * 0x100000000        040000000000            4294967296\n     * 0x7FFFFFFFFFFFFFFF 0777777777777777777777  9223372036854775807\n     * 0x8000000000000000 01000000000000000000000 9223372036854775808\n     * 0xFFFFFFFFFFFFFFFF 01777777777777777777777 18446744073709551615\n     */\n\n    assert(dotype(1) == T_int);\n\n    /***************** Hexadecimal ***********************/\n\n    assert(dotype(0) == T_int);\n    assert(dotype(0x7FFF) == T_int);\n    assert(dotype(0x8000) == T_int);\n    assert(dotype(0xFFFF) == T_int);\n    assert(dotype(0x10000) == T_int);\n    assert(dotype(0x7FFFFFFF) == T_int);\n    assert(dotype(0x80000000) == T_uint);\n    assert(dotype(0xFFFFFFFF) == T_uint);\n    assert(dotype(0x100000000) == T_long);\n    assert(dotype(0x7FFFFFFFFFFFFFFF) == T_long);\n    assert(dotype(0x8000000000000000) == T_ulong);\n    assert(dotype(0xFFFFFFFFFFFFFFFF) == T_ulong);\n\n    assert(dotype(0u) == T_uint);\n    assert(dotype(0x7FFFu) == T_uint);\n    assert(dotype(0x8000u) == T_uint);\n    assert(dotype(0xFFFFu) == T_uint);\n    assert(dotype(0x10000u) == T_uint);\n    assert(dotype(0x7FFFFFFFu) == T_uint);\n    assert(dotype(0x80000000u) == T_uint);\n    assert(dotype(0xFFFFFFFFu) == T_uint);\n    assert(dotype(0x100000000u) == T_ulong);\n    assert(dotype(0x7FFFFFFFFFFFFFFFu) == T_ulong);\n    assert(dotype(0x8000000000000000u) == T_ulong);\n    assert(dotype(0xFFFFFFFFFFFFFFFFu) == T_ulong);\n\n    assert(dotype(0L) == T_long);\n    assert(dotype(0x7FFFL) == T_long);\n    assert(dotype(0x8000L) == T_long);\n    assert(dotype(0xFFFFL) == T_long);\n    assert(dotype(0x10000L) == T_long);\n    assert(dotype(0x7FFFFFFFL) == T_long);\n    assert(dotype(0x80000000L) == T_long);\n    assert(dotype(0xFFFFFFFFL) == T_long);\n    assert(dotype(0x100000000L) == T_long);\n    assert(dotype(0x7FFFFFFFFFFFFFFFL) == T_long);\n    assert(dotype(0x8000000000000000L) == T_ulong);\n    assert(dotype(0xFFFFFFFFFFFFFFFFL) == T_ulong);\n\n    assert(dotype(0uL) == T_ulong);\n    assert(dotype(0x7FFFuL) == T_ulong);\n    assert(dotype(0x8000uL) == T_ulong);\n    assert(dotype(0xFFFFuL) == T_ulong);\n    assert(dotype(0x10000uL) == T_ulong);\n    assert(dotype(0x7FFFFFFFuL) == T_ulong);\n    assert(dotype(0x80000000uL) == T_ulong);\n    assert(dotype(0xFFFFFFFFuL) == T_ulong);\n    assert(dotype(0x100000000uL) == T_ulong);\n    assert(dotype(0x7FFFFFFFFFFFFFFFuL) == T_ulong);\n    assert(dotype(0x8000000000000000uL) == T_ulong);\n    assert(dotype(0xFFFFFFFFFFFFFFFFuL) == T_ulong);\n\n    /***************** Decimal ***********************/\n\n    assert(dotype(0) == T_int);\n    assert(dotype(32767) == T_int);\n    assert(dotype(32768) == T_int);\n    assert(dotype(65535) == T_int);\n    assert(dotype(65536) == T_int);\n    assert(dotype(2147483647) == T_int);\n    assert(dotype(2147483648) == T_long);\n    assert(dotype(4294967295) == T_long);\n    assert(dotype(4294967296) == T_long);\n    assert(dotype(9223372036854775807) == T_long);\n    //assert(dotype(9223372036854775808) == T_long);\n    //assert(dotype(18446744073709551615) == T_ulong);\n\n    assert(dotype(0u) == T_uint);\n    assert(dotype(32767u) == T_uint);\n    assert(dotype(32768u) == T_uint);\n    assert(dotype(65535u) == T_uint);\n    assert(dotype(65536u) == T_uint);\n    assert(dotype(2147483647u) == T_uint);\n    assert(dotype(2147483648u) == T_uint);\n    assert(dotype(4294967295u) == T_uint);\n    assert(dotype(4294967296u) == T_ulong);\n    assert(dotype(9223372036854775807u) == T_ulong);\n    assert(dotype(9223372036854775808u) == T_ulong);\n    assert(dotype(18446744073709551615u) == T_ulong);\n\n    assert(dotype(0L) == T_long);\n    assert(dotype(32767L) == T_long);\n    assert(dotype(32768L) == T_long);\n    assert(dotype(65535L) == T_long);\n    assert(dotype(65536L) == T_long);\n    assert(dotype(2147483647L) == T_long);\n    assert(dotype(2147483648L) == T_long);\n    assert(dotype(4294967295L) == T_long);\n    assert(dotype(4294967296L) == T_long);\n    assert(dotype(9223372036854775807L) == T_long);\n    //assert(dotype(9223372036854775808L) == T_ulong);\n    //assert(dotype(18446744073709551615L) == T_ulong);\n\n    assert(dotype(0uL) == T_ulong);\n    assert(dotype(32767uL) == T_ulong);\n    assert(dotype(32768uL) == T_ulong);\n    assert(dotype(65535uL) == T_ulong);\n    assert(dotype(65536uL) == T_ulong);\n    assert(dotype(2147483647uL) == T_ulong);\n    assert(dotype(2147483648uL) == T_ulong);\n    assert(dotype(4294967295uL) == T_ulong);\n    assert(dotype(4294967296uL) == T_ulong);\n    assert(dotype(9223372036854775807uL) == T_ulong);\n    assert(dotype(9223372036854775808uL) == T_ulong);\n    assert(dotype(18446744073709551615uL) == T_ulong);\n}\n\nvoid test2()\n{\n    ulong[] a = [ 2_463_534_242UL ];\n\n    foreach(e; a)\n        assert(e == 2_463_534_242UL);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13907\n\nvoid f13907_1(wchar[1] a) {}\nvoid f13907_2(wchar[2] a) {}\nvoid f13907_3(wchar[3] a) {}\n\nauto f13907_12(char[1]) { return 1; }\nauto f13907_12(char[2]) { return 2; }\n\nauto f13907_123(char[1]) { return 1; }\nauto f13907_123(char[2]) { return 2; }\nauto f13907_123(char[3]) { return 3; }\nauto f13907_123(const(char)[]) { return 0; }\n\nvoid test13907()\n{\n    static assert(!__traits(compiles, { f13907_1(\"\\U00010000\"w); }));\n    static assert(!__traits(compiles, { f13907_1(\"\\U00010000\" ); }));\n    f13907_2(\"\\U00010000\"w);\n    f13907_2(\"\\U00010000\");\n    f13907_3(\"\\U00010000\"w);    // Re-enable implicit length extension, from https://issues.dlang.org/show_bug.cgi?id=13999\n    f13907_3(\"\\U00010000\" );    // Re-enable implicit length extension, from https://issues.dlang.org/show_bug.cgi?id=13999\n\n    assert(f13907_12(\"a\") == 1);\n    assert(f13907_12(\"ab\") == 2);\n    static assert(!__traits(compiles, { f13907_12(\"abc\"); }));\n\n    assert(f13907_123(\"a\") == 1);\n    assert(f13907_123(\"ab\") == 2);\n    assert(f13907_123(\"abc\") == 3);\n    assert(f13907_123(\"abcd\") == 0);\n\n    // regression tests for the lengthen behavior in initializer\n    enum const(char*) p = \"hello world\";\n    static assert(!__traits(compiles, { static   char[5] a = \"hello world\"; }));  // truncation is not allowed\n    static assert(!__traits(compiles, { static  void[20] a = \"hello world\"; }));\n    static assert(!__traits(compiles, { static   int[20] a = \"hello world\"; }));\n    static assert(!__traits(compiles, { static  char[20] a = \"hello world\"w; }));\n    static assert(!__traits(compiles, { static wchar[20] a = \"hello world\"d; }));\n    static assert(!__traits(compiles, { static dchar[20] a = \"hello world\"c; }));\n    static assert(!__traits(compiles, { static  char[20] a = p; }));\n    static  char[20] csa = \"hello world\";  // extending is allowed\n    static wchar[20] wsa = \"hello world\";  // ok\n    static dchar[20] dsa = \"hello world\";  // ok\n\n    // https://issues.dlang.org/show_bug.cgi?id=13966\n    string[1][] arr;\n    arr ~= [\"class\"];\n    enum immutable(char[5]) sarrstr = \"class\";\n    arr ~= [sarrstr];\n\n    // https://issues.dlang.org/show_bug.cgi?id=13999\n    string[dchar[2]] aa13999 = [\"あ\": \"bar\"];\n    assert(aa13999[\"あ\"] == \"bar\");\n    dchar[2] key13999 = \"あ\";\n    assert(key13999[0] == 'あ');\n    assert(key13999[1] == '\\0');\n    assert(aa13999[key13999] == \"bar\");\n}\n\n/***************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test13907();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/loopunroll.d",
    "content": "\n/* PERMUTE_ARGS: -O\n */\n\nimport core.stdc.stdio;\n\nversion (all)\n{\n\n/************************************/\n\nint func1(int[] data)\n{\n        int j;\n        for (int i = 0; i < 10; i++) {\n                data[i*10] = i;\n                j = data[0] * 10;\n        }\n        return j;\n}\n\nvoid test1()\n{\n    int[100] data = [1,7,6,3,8,9,7,2,2,4,\n                     1,7,6,3,8,9,7,2,2,4,\n                     1,7,6,3,8,9,7,2,2,4,\n                     1,7,6,3,8,9,7,2,2,4,\n                     1,7,6,3,8,9,7,2,2,4,\n                     1,7,6,3,8,9,7,2,2,4,\n                     1,7,6,3,8,9,7,2,2,4,\n                     1,7,6,3,8,9,7,2,2,4,\n                     1,7,6,3,8,9,7,2,2,4,\n                     1,7,6,3,8,9,7,2,2,4,\n                    ];\n    int i = func1(data[]);\n    if (i != 0)\n        assert(0);\n    printf(\"%d\\n\", i);\n}\n\n/************************************/\n\nvoid test2()\n{\n    int result = 0;\n    for (int i = 0; i < 10; ++i)\n        result += i;\n    printf(\"%d\\n\", result);\n    if (result != 45)\n        assert(0);\n}\n\n/************************************/\n\nvoid test3()\n{\n    int result = 0;\n    for (int i = 0; i < 10; i++)\n        result += i;\n    printf(\"%d\\n\", result);\n    if (result != 45)\n        assert(0);\n}\n\n/************************************/\n\nvoid test4()\n{\n    int result = 0;\n    for (int i = 0; i < 10; i += 1)\n        result += i;\n    printf(\"%d\\n\", result);\n    if (result != 45)\n        assert(0);\n}\n\n/************************************/\n\nvoid test5()\n{\n    int result = 0;\n    for (int i = 0; i < 10; i -= -1)\n        result += i;\n    printf(\"%d\\n\", result);\n    if (result != 45)\n        assert(0);\n}\n\n/************************************/\n\nvoid test6()\n{\n    int result = 0;\n    for (uint i = 0; i < 10; i++)\n        result += i;\n    printf(\"%d\\n\", result);\n    if (result != 45)\n        assert(0);\n}\n\n/************************************/\n\nvoid test7()\n{\n    int result = 0;\n    for (long i = 0; i < 10; i++)\n        result += i;\n    printf(\"%d\\n\", result);\n    if (result != 45)\n        assert(0);\n}\n\n/************************************/\n\nvoid test8()\n{\n    int result = 0;\n    for (ulong i = 0; i < 10; i++)\n        result += i;\n    printf(\"%d\\n\", result);\n    if (result != 45)\n        assert(0);\n}\n\n/************************************/\n\nvoid test9()\n{\n    int result = 0;\n    for (ulong i = 0; i < 5; i++)\n        result += i;\n    printf(\"%d\\n\", result);\n    if (result != 10)\n        assert(0);\n}\n\n/************************************/\n\nvoid test10()\n{\n    __gshared int i;\n    int result = 0;\n    for (i = 0; i < 10; i++)\n        result += i;\n    printf(\"%d\\n\", result);\n    if (result != 45)\n        assert(0);\n}\n\n/************************************/\n\nvoid test11()\n{\n    int result = 0;\n    for (int i = 0; i < 10; i += 10)\n        result += i;\n    printf(\"%d\\n\", result);\n    if (result != 0)\n        assert(0);\n}\n\n/************************************/\n\nvoid test12()\n{\n    int result = 0;\n    for (int i = 0; i < 10; i += 5)\n        result += i;\n    printf(\"%d\\n\", result);\n    if (result != 5)\n        assert(0);\n}\n\n/************************************/\n\nvoid test13()\n{\n    int result = 0;\n    int i;\n    int* p = &i;\n\n    int foo() { return *p; }\n\n    for (i = 0; i < 10; ++i)\n    {\n        if (foo() != i)\n            assert(0);\n        result += i;\n    }\n    printf(\"%d\\n\", result);\n    if (result != 45)\n        assert(0);\n}\n\n/************************************/\n\nvoid test14()\n{\n    int result = 0;\n    int i;\n\n    int foo() { return i; }\n\n    for (i = 0; i < 10; ++i)\n    {\n        if (foo() != i)\n            assert(0);\n        result += i;\n    }\n    printf(\"%d\\n\", result);\n    if (result != 45)\n        assert(0);\n}\n\n/************************************/\n\nvoid test15()\n{\n    int result = 0;\n    int i;\n\n    try\n    {\n        for (i = 0; i < 10; ++i)\n        {\n            if (i == 1)\n                throw new Exception(\"hello\");\n            result += i;\n        }\n        assert(0);\n    }\n    catch (Exception e)\n    {\n        assert(i == 1);\n    }\n}\n\n/************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    return 0;\n}\n\n}\nelse\n{\n\nvoid main()\n{\n    int result = 0;\n    int i;\n\n    try\n    {\n        for (i = 0; i < 10; ++i)\n        {\n            if (i == 1)\n                throw new Exception(\"hello\");\n            result += i;\n        }\n        assert(0);\n    }\n    catch (Exception e)\n    {\n        assert(i == 1);\n    }\n}\n\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/m1.d",
    "content": "// EXTRA_SOURCES: imports/m1a.d\n// PERMUTE_ARGS:\n\nmodule m1;\n\nimport std.stdio;\n\nimport imports.m1a;\n\nclass A\n{\n}\n\nA createA() { return new A; }\n\nalias A function() aliasM1;\n\nvoid main()\n{\n  aFunc( &createA );\n  printf(\"Success\\n\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/manboy.d",
    "content": "// PERMUTE_ARGS:\n\nimport std.stdio;\n\nint a(int k, lazy int x1, lazy int x2, lazy int x3, lazy int x4, lazy int x5)\n{\n    int delegate() b;\n    b = { k -= 1; return a(k, b(), x1, x2, x3, x4); };\n    if (k <= 0)\n        return x4 + x5;\n    else\n        return b();\n}\n\nint main()\n{\n    assert(a(10, 1, -1, -1, 1, 0) == -67);\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/mangle.d",
    "content": "// PERMUTE_ARGS:\n// EXTRA_SOURCES: imports/mangle10077.d\n\nimport imports.testmangle;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10077\n// pragma(mangle)\n\npragma(mangle, \"_test10077a_\") int test10077a;\nstatic assert(test10077a.mangleof == \"_test10077a_\");\n\n__gshared pragma(mangle, \"_test10077b_\") ubyte test10077b;\nstatic assert(test10077b.mangleof == \"_test10077b_\");\n\npragma(mangle, \"_test10077c_\") void test10077c() {}\nstatic assert(test10077c.mangleof == \"_test10077c_\");\n\npragma(mangle, \"_test10077f_\") __gshared char test10077f;\nstatic assert(test10077f.mangleof == \"_test10077f_\");\n\npragma(mangle, \"_test10077g_\") @system { void test10077g() {} }\nstatic assert(test10077g.mangleof == \"_test10077g_\");\n\ntemplate getModuleInfo(alias mod)\n{\n    pragma(mangle, \"_D\"~mod.mangleof~\"12__ModuleInfoZ\") static __gshared extern ModuleInfo mi;\n    enum getModuleInfo = &mi;\n}\n\nvoid test10077h()\n{\n    assert(getModuleInfo!(object).name == \"object\");\n}\n\n//UTF-8 chars\n__gshared extern pragma(mangle, \"test_эльфийские_письмена_9\") ubyte test10077i_evar;\n\nvoid test10077i()\n{\n    import imports.mangle10077;\n\n    setTest10077i();\n    assert(test10077i_evar == 42);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13050\n\nvoid func13050(int);\ntemplate decl13050(Arg)\n{\n    void decl13050(Arg);\n}\ntemplate problem13050(Arg)\n{\n    pragma(mangle, \"foobar\")\n        void problem13050(Arg);\n}\ntemplate workaround13050(Arg)\n{\n    pragma(mangle, \"foobar\")\n        void func(Arg);\n    alias workaround13050 = func;\n}\n\nstatic assert(is(typeof(&func13050) == void function(int)));\nstatic assert(is(typeof(&decl13050!int) == void function(int)));\nstatic assert(is(typeof(&problem13050!int) == void function(int)));\nstatic assert(is(typeof(&workaround13050!int) == void function(int)));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2774\n\nint foo2774(int n) { return 0; }\nstatic assert(foo2774.mangleof == \"_D6mangle7foo2774FiZi\");\n\nclass C2774\n{\n    int foo2774() { return 0; }\n}\nstatic assert(C2774.foo2774.mangleof == \"_D6mangle5C27747foo2774MFZi\");\n\ntemplate TFoo2774(T) {}\nstatic assert(TFoo2774!int.mangleof == \"6mangle\"~tl!\"15\"~\"__T8TFoo2774TiZ\");\n\nvoid test2774()\n{\n    int foo2774(int n) { return 0; }\n    static assert(foo2774.mangleof == \"_D6mangle8test2774FZ7foo2774MFNaNbNiNfiZi\");\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8847\n\nauto S8847()\n{\n    static struct Result\n    {\n        inout(Result) get() inout { return this; }\n    }\n    return Result();\n}\n\nvoid test8847a()\n{\n    auto a = S8847();\n    auto b = a.get();\n    alias typeof(a) A;\n    alias typeof(b) B;\n    assert(is(A == B), A.stringof~ \" is different from \"~B.stringof);\n}\n\n// --------\n\nenum result8847a = \"S6mangle9iota8847aFZ6Result\";\nenum result8847b = \"S6mangle9iota8847bFZ4iotaMFZ6Result\";\nenum result8847c = \"C6mangle9iota8847cFZ6Result\";\nenum result8847d = \"C6mangle9iota8847dFZ4iotaMFZ6Result\";\n\nauto iota8847a()\n{\n    static struct Result\n    {\n        this(int) {}\n        inout(Result) test() inout { return cast(inout)Result(0); }\n    }\n    static assert(Result.mangleof == result8847a);\n    return Result.init;\n}\nauto iota8847b()\n{\n    auto iota()\n    {\n        static struct Result\n        {\n            this(int) {}\n            inout(Result) test() inout { return cast(inout)Result(0); }\n        }\n        static assert(Result.mangleof == result8847b);\n        return Result.init;\n    }\n    return iota();\n}\nauto iota8847c()\n{\n    static class Result\n    {\n        this(int) {}\n        inout(Result) test() inout { return cast(inout)new Result(0); }\n    }\n    static assert(Result.mangleof == result8847c);\n    return Result.init;\n}\nauto iota8847d()\n{\n    auto iota()\n    {\n        static class Result\n        {\n            this(int) {}\n            inout(Result) test() inout { return cast(inout)new Result(0); }\n        }\n        static assert(Result.mangleof == result8847d);\n        return Result.init;\n    }\n    return iota();\n}\nvoid test8847b()\n{\n    static assert(typeof(iota8847a().test()).mangleof == result8847a);\n    static assert(typeof(iota8847b().test()).mangleof == result8847b);\n    static assert(typeof(iota8847c().test()).mangleof == result8847c);\n    static assert(typeof(iota8847d().test()).mangleof == result8847d);\n}\n\n// --------\n\nstruct Test8847\n{\n    enum result1 = \"S6mangle8Test8847\"~tl!(\"8\")~\"__T3fooZ\"~id!(\"3foo\",\"Qf\")~\"MFZ6Result\";\n    enum result2 = \"S6mangle8Test8847\"~tl!(\"8\")~\"__T3fooZ\"~id!(\"3foo\",\"Qf\")~\"MxFiZ6Result\";\n\n    auto foo()()\n    {\n        static struct Result\n        {\n            inout(Result) get() inout { return this; }\n        }\n        static assert(Result.mangleof == Test8847.result1);\n        return Result();\n    }\n    auto foo()(int n) const\n    {\n        static struct Result\n        {\n            inout(Result) get() inout { return this; }\n        }\n        static assert(Result.mangleof == Test8847.result2);\n        return Result();\n    }\n}\nvoid test8847c()\n{\n    static assert(typeof(Test8847().foo( ).get()).mangleof == Test8847.result1);\n    static assert(typeof(Test8847().foo(1).get()).mangleof == Test8847.result2);\n}\n\n// --------\n\nvoid test8847d()\n{\n    enum resultS = \"S6mangle9test8847dFZ3fooMFZ3barMFZ3bazMFZ1S\";\n    enum resultX = \"S6mangle9test8847dFZ3fooMFZ1X\";\n    // Return types for test8847d and bar are mangled correctly,\n    // and return types for foo and baz are not mangled correctly.\n\n    auto foo()\n    {\n        struct X { inout(X) get() inout { return inout(X)(); } }\n        string bar()\n        {\n            auto baz()\n            {\n                struct S { inout(S) get() inout { return inout(S)(); } }\n                return S();\n            }\n            static assert(typeof(baz()      ).mangleof == resultS);\n            static assert(typeof(baz().get()).mangleof == resultS);\n            return \"\";\n        }\n        return X();\n    }\n    static assert(typeof(foo()      ).mangleof == resultX);\n    static assert(typeof(foo().get()).mangleof == resultX);\n}\n\n// --------\n\nvoid test8847e()\n{\n    enum resultHere = \"6mangle\"~\"9test8847eFZ\"~tl!\"8\"~\"__T3fooZ\"~id!(\"3foo\",\"Qf\");\n    enum resultBar =  \"S\"~resultHere~\"MFNaNfNgiZ3Bar\";\n    static if(BackRefs) {} else\n      enum resultFoo = \"_D\"~resultHere~\"MFNaNbNiNfNgiZNg\"~resultBar;   // added 'Nb'\n\n    // Make template function to infer 'nothrow' attributes\n    auto foo()(inout int) pure @safe\n    {\n        struct Bar {}\n        static assert(Bar.mangleof == resultBar);\n        return inout(Bar)();\n    }\n\n    import core.demangle : demangle, demangleType;\n    auto bar = foo(0);\n    static assert(typeof(bar).stringof == \"Bar\");\n    static assert(typeof(bar).mangleof == resultBar);\n    enum fooDemangled = \"pure nothrow @nogc @safe inout(mangle.test8847e().foo!().foo(inout(int)).Bar) mangle.test8847e().foo!().foo(inout(int))\";\n\n    static if (BackRefs)\n      static assert(demangle(foo!().mangleof) == fooDemangled);\n    else\n      static assert(foo!().mangleof == resultFoo);\n}\n\n// --------\n\npure f8847a()\n{\n    struct S {}\n    return S();\n}\n\npure\n{\n    auto f8847b()\n    {\n        struct S {}\n        return S();\n    }\n}\n\nstatic assert(typeof(f8847a()).mangleof == \"S6mangle6f8847aFNaZ1S\");\nstatic assert(typeof(f8847b()).mangleof == \"S6mangle6f8847bFNaZ1S\");\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12352\n\nauto bar12352()\n{\n    struct S { int var; void func() {} }\n\n    static assert(!__traits(compiles, bar12352.mangleof));   // forward reference to bar\n    static assert(S     .mangleof ==  \"S6mangle8bar12352FZ1S\");\n    static assert(S.func.mangleof == \"_D6mangle8bar12352FZ1S4funcMFZv\");\n\n    return S();\n}\nstatic assert(       bar12352        .mangleof == \"_D6mangle8bar12352FNaNbNiNfZS\"~id!(\"6mangle8bar12352FZ\",\"QBbQxFZ\",\"QL2H\")~\"1S\");\nstatic assert(typeof(bar12352())     .mangleof ==  \"S6mangle8bar12352FZ1S\");\nstatic assert(typeof(bar12352()).func.mangleof == \"_D6mangle8bar12352FZ1S4funcMFZv\");\n\nauto baz12352()\n{\n    class C { int var; void func() {} }\n\n    static assert(!__traits(compiles, baz12352.mangleof));   // forward reference to baz\n    static assert(C     .mangleof ==  \"C6mangle8baz12352FZ1C\");\n    static assert(C.func.mangleof == \"_D6mangle8baz12352FZ1C4funcMFZv\");\n\n    return new C();\n}\nstatic assert(       baz12352      .mangleof == \"_D6mangle8baz12352FNaNbNfZC\"~id!(\"6mangle8baz12352FZ\",\"QzQuFZ\",\"QL2F\")~\"1C\");\nstatic assert(typeof(baz12352())     .mangleof ==  \"C6mangle8baz12352FZ1C\");\nstatic assert(typeof(baz12352()).func.mangleof == \"_D6mangle8baz12352FZ1C4funcMFZv\");\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9525\n\nvoid f9525(T)(in T*) { }\n\nvoid test9525()\n{\n    enum result1 = \"S6mangle8test9525FZ\"~tl!\"26\"~\"__T5test1S\"~tl!\"13\"~id!(\"6mangle\",\"QBc\")~\"5f9525Z\"~id!(\"5test1\",\"Qr\")~\"MFZ1S\";\n    enum result2 = \"S6mangle8test9525FZ\"~tl!\"26\"~\"__T5test2S\"~tl!\"13\"~id!(\"6mangle\",\"QBc\")~\"5f9525Z\"~id!(\"5test2\",\"Qr\")~\"MFNaNbZ1S\";\n\n    bool test1(alias a)()\n    {\n        static struct S {}\n        static assert(S.mangleof == result1);\n        S s;\n        a(&s);  // Error: Cannot convert &S to const(S*) at compile time\n        return true;\n    }\n    enum evalTest1 = test1!f9525();\n\n    bool test2(alias a)() pure nothrow\n    {\n        static struct S {}\n        static assert(S.mangleof == result2);\n        S s;\n        a(&s);  // Error: Cannot convert &S to const(S*) at compile time\n        return true;\n    }\n    enum evalTest2 = test2!f9525();\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10249\n\ntemplate Seq10249(T...) { alias Seq10249 = T; }\n\nmixin template Func10249(T)\n{\n    void func10249(T) {}\n}\nmixin Func10249!long;\nmixin Func10249!string;\n\nvoid f10249(long) {}\n\nclass C10249\n{\n    mixin Func10249!long;\n    mixin Func10249!string;\n    static assert(Seq10249!(.func10249)[0].mangleof == \"6mangle9func10249\");           // <- 9func10249\n    static assert(Seq10249!( func10249)[0].mangleof == \"6mangle6C102499func10249\");    // <- 9func10249\n\nstatic: // necessary to make overloaded symbols accessible via __traits(getOverloads, C10249)\n    void foo(long) {}\n    void foo(string) {}\n    static assert(Seq10249!(foo)[0].mangleof                                   ==   \"6mangle6C102493foo\");         // <- _D6mangle6C102493fooFlZv\n    static assert(Seq10249!(__traits(getOverloads, C10249, \"foo\"))[0].mangleof == \"_D6mangle6C102493fooFlZv\");     // <-\n    static assert(Seq10249!(__traits(getOverloads, C10249, \"foo\"))[1].mangleof == \"_D6mangle6C102493fooFAyaZv\");   // <-\n\n    void g(string) {}\n    alias bar = .f10249;\n    alias bar =  g;\n    static assert(Seq10249!(bar)[0].mangleof                                   ==   \"6mangle6C102493bar\");         // <- _D6mangle1fFlZv\n    static assert(Seq10249!(__traits(getOverloads, C10249, \"bar\"))[0].mangleof == \"_D6mangle6f10249FlZv\");         // <-\n    static assert(Seq10249!(__traits(getOverloads, C10249, \"bar\"))[1].mangleof == \"_D6mangle6C102491gFAyaZv\");     // <-\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11718\n\nstruct Ty11718(alias sym) {}\n\nauto fn11718(T)(T a)   { return Ty11718!(a).mangleof; }\nauto fn11718(T)() { T a; return Ty11718!(a).mangleof; }\n\nvoid test11718()\n{\n    string TyName(string tail)()\n    {\n        enum s = \"__T7Ty11718\" ~ tail;\n        enum len = unsignedToString(s.length);\n        return \"S6mangle\" ~ tl!(len) ~ s;\n    }\n    string fnName(string paramPart)()\n    {\n        enum s = \"_D6mangle\"~tl!(\"35\")~\"__T7fn11718T\"~\n                 \"S6mangle9test11718FZ1AZ7fn11718\"~paramPart~\"1a\"~\n                 \"S6mangle9test11718FZ1A\";\n        enum len = unsignedToString(s.length);\n        return tl!len ~ s;\n    }\n    enum result1 = TyName!(\"S\" ~ fnName!(\"F\"~\"S6mangle9test11718FZ1A\"~\"Z\") ~ \"Z\") ~ \"7Ty11718\";\n    enum result2 = TyName!(\"S\" ~ fnName!(\"F\"~\"\"                      ~\"Z\") ~ \"Z\") ~ \"7Ty11718\";\n\n    struct A {}\n    static if (BackRefs)\n    {\n        static assert(fn11718(A.init) == \"S6mangle__T7Ty11718S_DQv__T7fn11718TSQBk9test11718FZ1AZQBcFQxZ1aQBcZQCf\");\n        static assert(fn11718!A()     == \"S6mangle__T7Ty11718S_DQv__T7fn11718TSQBk9test11718FZ1AZQBcFZ1aQBaZQCd\");\n    }\n    else\n    {\n        pragma(msg, fn11718(A.init));\n        static assert(fn11718(A.init) == result1);\n        static assert(fn11718!A()     == result2);\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11776\n\nstruct S11776(alias fun) { }\n\nvoid test11776()\n{\n    auto g = ()\n    {\n        if (1)\n            return; // fill tf->next\n        if (1)\n        {\n            auto s = S11776!(a => 1)();\n            static assert(typeof(s).mangleof ==\n                \"S\"~\"6mangle\"~tl!(\"56\")~\n                (\"__T\"~\"6S11776\"~\"S\"~tl!(\"42\")~\n                 (id!(\"6mangle\",\"Qs\")~\"9test11776\"~\"FZ\"~\"9__lambda1MFZ\"~id!(\"9__lambda1\",\"Qn\"))~\"Z\"\n                 )~id!(\"6S11776\", \"QBm\"));\n        }\n    };\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12044\n\nstruct S12044(T)\n{\n    void f()()\n    {\n        new T[1];\n    }\n\n    bool opEquals(O)(O)\n    {\n        f();\n    }\n}\n\nvoid test12044()\n{\n    ()\n    {\n        enum E { e }\n        auto arr = [E.e];\n        S12044!E s;\n    }\n    ();\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12217\n\nvoid test12217(int)\n{\n    static struct S {}\n    void bar() {}\n    int var;\n    template X(T) {}\n\n    static assert(    S.mangleof ==  \"S6mangle9test12217FiZ1S\");\n    static assert(  bar.mangleof == \"_D6mangle9test12217FiZ3barMFNaNbNiNfZv\");\n    static assert(  var.mangleof == \"_D6mangle9test12217FiZ3vari\");\n    static assert(X!int.mangleof ==   \"6mangle9test12217FiZ\"~tl!(\"8\")~\"__T1XTiZ\");\n}\n\nvoid test12217() {}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12231\n\nvoid func12231a()()\nif (is(typeof({\n        class C {}\n        static assert(C.mangleof ==\n            \"C6mangle\"~tl!(\"16\")~\"__U10func12231aZ\"~id!(\"10func12231a\",\"Qn\")~\"FZ9__lambda1MFZ1C\");\n            //         ###            L                       #\n    })))\n{}\n\nvoid func12231b()()\nif (is(typeof({\n        class C {}        static assert(C.mangleof ==\n            \"C6mangle\"~tl!(\"16\")~\"__U10func12231bZ\"~id!(\"10func12231b\",\"Qn\")~\"FZ9__lambda1MFZ1C\");\n            //         L__L           L                       LL\n      })) &&\n    is(typeof({\n        class C {}\n        static assert(C.mangleof ==\n            \"C6mangle\"~tl!(\"16\")~\"__U10func12231bZ\"~id!(\"10func12231b\",\"Qn\")~\"FZ9__lambda2MFZ1C\");\n            //         L__L           L                       LL\n    })))\n{}\n\nvoid func12231c()()\nif (is(typeof({\n        class C {}\n        static assert(C.mangleof ==\n            \"C6mangle\"~tl!(\"16\")~\"__U10func12231cZ\"~id!(\"10func12231c\",\"Qn\")~\"FZ9__lambda1MFZ1C\");\n            //         L__L           L                       LL\n    })))\n{\n    (){\n        class C {}\n        static assert(C.mangleof ==\n            \"C6mangle\"~tl!(\"16\")~\"__T10func12231cZ\"~id!(\"10func12231c\",\"Qn\")~\"FZ9__lambda1MFZ1C\");\n            //         L__L           L                       LL\n    }();\n}\n\nvoid func12231c(X)()\nif (is(typeof({\n        class C {}\n    static assert(C.mangleof ==\n            \"C6mangle\"~tl!(\"20\")~\"__U10func12231cTAyaZ\"~id!(\"10func12231c\",\"Qr\")~\"FZ9__lambda1MFZ1C\");\n            //         L__L           L___L                       LL\n    })))\n{\n    (){\n        class C {}\n        static assert(C.mangleof ==\n            \"C6mangle\"~tl!(\"20\")~\"__T10func12231cTAyaZ\"~id!(\"10func12231c\",\"Qr\")~\"FZ9__lambda1MFZ1C\");\n            //         L__L           L___L                       LL\n    }();\n}\n\nvoid test12231()\n{\n    func12231a();\n\n    func12231b();\n\n    func12231c();\n    func12231c!string();\n}\n\n/***************************************************/\n\nint test2a(scope int a) { return a; }\n\nstatic assert(test2a.mangleof == \"_D6mangle6test2aFiZi\");\n\n/***************************************************/\n\nclass CC\n{\n    int* p;\n\n    int* member() scope\n    {\n        return p;\n    }\n}\n\nstatic assert(CC.member.mangleof == \"_D6mangle2CC6memberMFNlZPi\");\n\n/***************************************************/\n\nvoid fooA(void delegate (scope void delegate()) dg)\n{\n}\nvoid fooB(void delegate (void delegate()) scope dg)\n{\n}\n\n//pragma(msg, fooA.mangleof);\n//pragma(msg, fooB.mangleof);\nstatic assert(typeof(fooA).mangleof != typeof(fooB).mangleof);\n\n\n/***************************************************/\n\nvoid main()\n{\n    test10077h();\n    test10077i();\n    test12044();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/mars1.d",
    "content": "/*\nREQUIRED_ARGS: -mcpu=native -transition=intpromote\nPERMUTE_ARGS: -O -inline -release\n*/\n\nimport core.stdc.stdio;\n\nvoid testgoto()\n{\n    int i;\n\n    i = 3;\n    goto L4;\nL3: i++;\n    goto L5;\nL4: goto L3;\nL5: assert(i == 4);\n}\n\nint testswitch()\n{\n    int i;\n\n    i = 3;\n    switch (i)\n    {\n        case 0:\n        case 1:\n        default:\n            assert(0);\n        case 3:\n            break;\n    }\n    return 0;\n}\n\nvoid testdo()\n{\n    int x = 0;\n\n    do\n    {\n        x++;\n    } while (x < 10);\n    printf(\"x == %d\\n\", x);\n    assert(x == 10);\n}\n\n\nvoid testbreak()\n{   int i, j;\n\n  Louter:\n    for (i = 0; i < 10; i++)\n    {\n        for (j = 0; j < 10; j++)\n        {\n            if (j == 3)\n                break Louter;\n        }\n    }\n\n    printf(\"i = %d, j = %d\\n\", i, j);\n    assert(i == 0);\n    assert(j == 3);\n}\n\n///////////////////////\n\nint foo(string s)\n{\n    int i;\n\n    i = 0;\n    switch (s)\n    {\n        case \"hello\":\n            i = 1;\n            break;\n        case \"goodbye\":\n            i = 2;\n            break;\n        case \"goodb\":\n            i = 3;\n            break;\n        default:\n            i = 10;\n            break;\n    }\n    return i;\n}\n\n\nvoid teststringswitch()\n{   int i;\n\n    i = foo(\"hello\");\n    printf(\"i = %d\\n\", i);\n    assert(i == 1);\n\n    i = foo(\"goodbye\");\n    printf(\"i = %d\\n\", i);\n    assert(i == 2);\n\n    i = foo(\"goodb\");\n    printf(\"i = %d\\n\", i);\n    assert(i == 3);\n\n    i = foo(\"huzzah\");\n    printf(\"i = %d\\n\", i);\n    assert(i == 10);\n}\n\n\n///////////////////////\n\nstruct Foo\n{\n    int a;\n    char b;\n    long c;\n}\n\nFoo test(Foo f)\n{\n    f.a += 1;\n    f.b += 3;\n    f.c += 4;\n    return f;\n}\n\n\nvoid teststrarg()\n{\n    Foo g;\n    g.a = 1;\n    g.b = 2;\n    g.c = 3;\n\n    Foo q;\n    q = test(g);\n    assert(q.a == 2);\n    assert(q.b == 5);\n    assert(q.c == 7);\n}\n\n///////////////////////\n\nalign (1) struct Foo1\n{\n  align (1):\n    int a;\n    char b;\n    long c;\n}\n\nstruct Foo2\n{\n    int a;\n    char b;\n    long c;\n}\n\nstruct Foo3\n{\n    int a;\n    align (1) char b;\n    long c;\n}\n\nstruct Foo4\n{\n    int a;\n    struct { char b; }\n    long c;\n}\n\nvoid testsizes()\n{\n    printf(\"%d\\n\", Foo1.sizeof);\n    assert(Foo1.a.offsetof == 0);\n    assert(Foo1.b.offsetof == 4);\n    assert(Foo1.c.offsetof == 5);\n    assert(Foo1.sizeof == 13);\n\n    assert(Foo2.a.offsetof == 0);\n    assert(Foo2.b.offsetof == 4);\n    assert(Foo2.c.offsetof == 8);\n    assert(Foo2.sizeof == 16);\n\n    assert(Foo3.a.offsetof == 0);\n    assert(Foo3.b.offsetof == 4);\n    assert(Foo3.c.offsetof == 8);\n    assert(Foo3.b.sizeof == 1);\n    assert(Foo3.sizeof == 16);\n\n    assert(Foo4.sizeof == 16);\n}\n\n///////////////////////\n\nsize_t cond11565(size_t val)\n{\n    return val ? size_t.max : 0;\n}\n\nvoid test11565()\n{\n    assert(cond11565(true) == size_t.max);\n}\n\n///////////////////////\n\nint[3] array1 = [1:1,2,0:3];\n\nvoid testarrayinit()\n{\n    assert(array1[0] == 3);\n    assert(array1[1] == 1);\n    assert(array1[2] == 2);\n}\n\n///////////////////////\n\nvoid test13023(ulong n)\n{\n    static void func(bool b) {}\n\n    ulong k = 0;\n\n    func(k >= n / 2);\n\n    if (k >= n / 2)\n        assert(0);\n}\n\n///////////////////////\n\nstruct U { int a; union { char c; int d; } long b; }\n\nU f = { b:3, d:2, a:1 };\n\nvoid testU()\n{\n    assert(f.b == 3);\n    assert(f.d == 2);\n    assert(f.c == 2);\n    assert(f.a == 1);\n    assert(f.sizeof == 16);\n    assert(U.sizeof == 16);\n}\n\n\n///////////////////////\n\nvoid testulldiv()\n{\n    __gshared ulong[4][] vectors =\n    [\n        [10,3,3,1],\n        [10,1,10,0],\n        [3,10,0,3],\n        [10,10,1,0],\n        [10_000_000_000L, 11_000_000_000L, 0, 10_000_000_000L],\n        [11_000_000_000L, 10_000_000_000L, 1, 1_000_000_000L],\n        [11_000_000_000L, 11_000_000_000L, 1, 0],\n        [10_000_000_000L, 10, 1_000_000_000L, 0],\n        [0x8000_0000_0000_0000, 0x8000_0000_0000_0000, 1, 0],\n        [0x8000_0000_0000_0001, 0x8000_0000_0000_0001, 1, 0],\n        [0x8000_0001_0000_0000, 0x8000_0001_0000_0000, 1, 0],\n        [0x8000_0001_0000_0000, 0x8000_0000_0000_0000, 1, 0x1_0000_0000],\n        [0x8000_0001_0000_0000, 0x8000_0000_8000_0000, 1, 0x8000_0000],\n        [0x8000_0000_0000_0000, 0x7FFF_FFFF_FFFF_FFFF, 1, 1],\n        [0x8000_0000_0000_0000, 0x8000_0000_0000_0001, 0, 0x8000_0000_0000_0000],\n        [0x8000_0000_0000_0000, 0x8000_0001_0000_0000, 0, 0x8000_0000_0000_0000],\n    ];\n\n    for (size_t i = 0; i < vectors.length; i++)\n    {\n        ulong q = vectors[i][0] / vectors[i][1];\n        if (q != vectors[i][2])\n            printf(\"[%d] %lld / %lld = %lld, should be %lld\\n\",\n                vectors[i][0], vectors[i][1], q, vectors[i][2]);\n\n        ulong r = vectors[i][0] % vectors[i][1];\n        if (r != vectors[i][3])\n            printf(\"[%d] %lld %% %lld = %lld, should be %lld\\n\",\n                i, vectors[i][0], vectors[i][1], r, vectors[i][3]);\n    }\n}\n\n////////////////////////////////////////////////////////////////////////\n\n\nuint udiv10(uint x)\n{\n    return x / 10;\n}\n\nuint udiv14(uint x)\n{\n    return x / 14;\n}\n\nuint udiv14007(uint x)\n{\n    return x / 14007;\n}\n\nuint umod10(uint x)\n{\n    return x % 10;\n}\n\nuint umod14(uint x)\n{\n    return x % 14;\n}\n\nuint umod14007(uint x)\n{\n    return x % 14007;\n}\n\nuint uremquo10(uint x)\n{\n    return (x / 10) | (x % 10);\n}\n\nuint uremquo14(uint x)\n{\n    return (x / 14) | (x % 14);\n}\n\nuint uremquo14007(uint x)\n{\n    return (x / 14007) | (x % 14007);\n}\n\n\n\nulong uldiv10(ulong x)\n{\n    return x / 10;\n}\n\nulong uldiv14(ulong x)\n{\n    return x / 14;\n}\n\nulong uldiv14007(ulong x)\n{\n    return x / 14007;\n}\n\nulong ulmod10(ulong x)\n{\n    return x % 10;\n}\n\nulong ulmod14(ulong x)\n{\n    return x % 14;\n}\n\nulong ulmod14007(ulong x)\n{\n    return x % 14007;\n}\n\nulong ulremquo10(ulong x)\n{\n    return (x / 10) | (x % 10);\n}\n\nulong ulremquo14(ulong x)\n{\n    return (x / 14) | (x % 14);\n}\n\nulong ulremquo14007(ulong x)\n{\n    return (x / 14007) | (x % 14007);\n}\n\n\nvoid testfastudiv()\n{\n  {\n    static uint x10 = 10;\n    static uint x14 = 14;\n    static uint x14007 = 14007;\n\n    uint u = 10000;\n    uint r;\n    r = udiv10(u);  assert(r == u/x10);\n    r = udiv14(u);  assert(r == u/x14);\n    r = udiv14007(u);  assert(r == u/x14007);\n    r = umod10(u);  assert(r == u%x10);\n    r = umod14(u);  assert(r == u%x14);\n    r = umod14007(u);  assert(r == u%x14007);\n    r = uremquo10(u);  assert(r == ((u/10)|(u%x10)));\n    r = uremquo14(u);  assert(r == ((u/14)|(u%x14)));\n    r = uremquo14007(u);  assert(r == ((u/14007)|(u%x14007)));\n  }\n  {\n    static ulong y10 = 10;\n    static ulong y14 = 14;\n    static ulong y14007 = 14007;\n\n    ulong u = 10000;\n    ulong r;\n    r = uldiv10(u);  assert(r == u/y10);\n    r = uldiv14(u);  assert(r == u/y14);\n    r = uldiv14007(u);  assert(r == u/y14007);\n    r = ulmod10(u);  assert(r == u%y10);\n    r = ulmod14(u);  assert(r == u%y14);\n    r = ulmod14007(u);  assert(r == u%y14007);\n    r = ulremquo10(u);  assert(r == ((u/10)|(u%y10)));\n    r = ulremquo14(u);  assert(r == ((u/14)|(u%y14)));\n    r = ulremquo14007(u);  assert(r == ((u/14007)|(u%y14007)));\n  }\n}\n\n\n////////////////////////////////////////////////////////////////////////\n\nvoid vfunc() {}\n\nvoid test12095(int k)\n{\n    int e = 0;\n    e ? k || assert(0) : !e || vfunc();\n    e ? k || assert(0) : e && vfunc();\n    !e ? !e || vfunc() : k || assert(0);\n}\n\n\n////////////////////////////////////////////////////////////////////////\n\n\nbool test3918a( float t, real u )\n{\n        printf(\"%f\\n\", u );\n        return t && u;\n}\n\nbool test3918b( real t, float u )\n{\n        printf(\"%f\\n\", t );\n        return t && u;\n}\n\nvoid test3918()\n{\n        assert(test3918a(float.nan, real.nan));\n        assert(test3918b(real.nan, float.nan));\n}\n\n////////////////////////////////////////////////////////////////////////\n\n\nint div10(int x)\n{\n    return x / 10;\n}\n\nint div14(int x)\n{\n    return x / 14;\n}\n\nint div14007(int x)\n{\n    return x / 14007;\n}\n\nint mod10(int x)\n{\n    return x % 10;\n}\n\nint mod14(int x)\n{\n    return x % 14;\n}\n\nint mod14007(int x)\n{\n    return x % 14007;\n}\n\nint remquo10(int x)\n{\n    return (x / 10) | (x % 10);\n}\n\nint remquo14(int x)\n{\n    return (x / 14) | (x % 14);\n}\n\nint remquo14007(int x)\n{\n    return (x / 14007) | (x % 14007);\n}\n\n////////////////////\n\nint mdiv10(int x)\n{\n    return x / -10;\n}\n\nint mdiv14(int x)\n{\n    return x / -14;\n}\n\nint mdiv14007(int x)\n{\n    return x / -14007;\n}\n\nint mmod10(int x)\n{\n    return x % -10;\n}\n\nint mmod14(int x)\n{\n    return x % -14;\n}\n\nint mmod14007(int x)\n{\n    return x % -14007;\n}\n\nint mremquo10(int x)\n{\n    return (x / -10) | (x % -10);\n}\n\nint mremquo14(int x)\n{\n    return (x / -14) | (x % -14);\n}\n\nint mremquo14007(int x)\n{\n    return (x / -14007) | (x % -14007);\n}\n\n////////////////////\n\n\nlong ldiv10(long x)\n{\n    return x / 10;\n}\n\nlong ldiv14(long x)\n{\n    return x / 14;\n}\n\nlong ldiv14007(long x)\n{\n    return x / 14007;\n}\n\nlong lmod10(long x)\n{\n    return x % 10;\n}\n\nlong lmod14(long x)\n{\n    return x % 14;\n}\n\nlong lmod14007(long x)\n{\n    return x % 14007;\n}\n\nlong lremquo10(long x)\n{\n    return (x / 10) | (x % 10);\n}\n\nlong lremquo14(long x)\n{\n    return (x / 14) | (x % 14);\n}\n\nlong lremquo14007(long x)\n{\n    return (x / 14007) | (x % 14007);\n}\n\n\n////////////////////\n\n\nlong mldiv10(long x)\n{\n    return x / -10;\n}\n\nlong mldiv14(long x)\n{\n    return x / -14;\n}\n\nlong mldiv14007(long x)\n{\n    return x / -14007;\n}\n\nlong mlmod10(long x)\n{\n    return x % -10;\n}\n\nlong mlmod14(long x)\n{\n    return x % -14;\n}\n\nlong mlmod14007(long x)\n{\n    return x % -14007;\n}\n\nlong mlremquo10(long x)\n{\n    return (x / -10) | (x % -10);\n}\n\nlong mlremquo14(long x)\n{\n    return (x / -14) | (x % -14);\n}\n\nlong mlremquo14007(long x)\n{\n    return (x / -14007) | (x % -14007);\n}\n\n\n\nvoid testfastdiv()\n{\n  {\n    static int x10 = 10;\n    static int x14 = 14;\n    static int x14007 = 14007;\n\n    int u = 10000;\n    int r;\n    r = div10(u);  assert(r == u/x10);\n    r = div14(u);  assert(r == u/x14);\n    r = div14007(u);  assert(r == u/x14007);\n    r = mod10(u);  assert(r == u%x10);\n    r = mod14(u);  assert(r == u%x14);\n    r = mod14007(u);  assert(r == u%x14007);\n    r = remquo10(u);  assert(r == ((u/x10)|(u%x10)));\n    r = remquo14(u);  assert(r == ((u/x14)|(u%x14)));\n    r = remquo14007(u);  assert(r == ((u/x14007)|(u%x14007)));\n  }\n  {\n    static int t10 = -10;\n    static int t14 = -14;\n    static int t14007 = -14007;\n\n    int u = 10000;\n    int r;\n    r = mdiv10(u);  assert(r == u/t10);\n    r = mdiv14(u);  assert(r == u/t14);\n    r = mdiv14007(u);  assert(r == u/t14007);\n    r = mmod10(u);  assert(r == u%t10);\n    r = mmod14(u);  assert(r == u%t14);\n    r = mmod14007(u);  assert(r == u%t14007);\n    r = mremquo10(u);  assert(r == ((u/t10)|(u%t10)));\n    r = mremquo14(u);  assert(r == ((u/t14)|(u%t14)));\n    r = mremquo14007(u);  assert(r == ((u/t14007)|(u%t14007)));\n  }\n  {\n    static long y10 = 10;\n    static long y14 = 14;\n    static long y14007 = 14007;\n\n    long u = 10000;\n    long r;\n    r = ldiv10(u);  assert(r == u/y10);\n    r = ldiv14(u);  assert(r == u/y14);\n    r = ldiv14007(u);  assert(r == u/y14007);\n    r = lmod10(u);  assert(r == u%y10);\n    r = lmod14(u);  assert(r == u%y14);\n    r = lmod14007(u);  assert(r == u%y14007);\n    r = lremquo10(u);  assert(r == ((u/y10)|(u%y10)));\n    r = lremquo14(u);  assert(r == ((u/y14)|(u%y14)));\n    r = lremquo14007(u);  assert(r == ((u/y14007)|(u%y14007)));\n  }\n  {\n    static long z10 = -10;\n    static long z14 = -14;\n    static long z14007 = -14007;\n\n    long u = 10000;\n    long r;\n    r = mldiv10(u);  assert(r == u/z10);\n    r = mldiv14(u);  assert(r == u/z14);\n    r = mldiv14007(u);  assert(r == u/z14007);\n    r = mlmod10(u);  assert(r == u%z10);\n    r = mlmod14(u);  assert(r == u%z14);\n    r = mlmod14007(u);  assert(r == u%z14007);\n    r = mlremquo10(u);  assert(r == ((u/z10)|(u%z10)));\n    r = mlremquo14(u);  assert(r == ((u/z14)|(u%z14)));\n    r = mlremquo14007(u);  assert(r == ((u/z14007)|(u%z14007)));\n  }\n}\n\n////////////////////////////////////////////////////////////////////////\n\n\nT docond1(T)(T l, ubyte thresh, ubyte val) {\n    l += (thresh < val);\n    return l;\n}\n\nT docond2(T)(T l, ubyte thresh, ubyte val) {\n    l -= (thresh >= val);\n    return l;\n}\n\nT docond3(T)(T l, ubyte thresh, ubyte val) {\n    l += (thresh >= val);\n    return l;\n}\n\nT docond4(T)(T l, ubyte thresh, ubyte val) {\n    l -= (thresh < val);\n    return l;\n}\n\nvoid testdocond()\n{\n    assert(docond1!ubyte(10,3,5)  == 11);\n    assert(docond1!ushort(10,3,5) == 11);\n    assert(docond1!uint(10,3,5)   == 11);\n    assert(docond1!ulong(10,3,5)  == 11);\n\n    assert(docond2!ubyte(10,3,5)  == 10);\n    assert(docond2!ushort(10,3,5) == 10);\n    assert(docond2!uint(10,3,5)   == 10);\n    assert(docond2!ulong(10,3,5)  == 10);\n\n    assert(docond3!ubyte(10,3,5)  == 10);\n    assert(docond3!ushort(10,3,5) == 10);\n    assert(docond3!uint(10,3,5)   == 10);\n    assert(docond3!ulong(10,3,5)  == 10);\n\n    assert(docond4!ubyte(10,3,5)  == 9);\n    assert(docond4!ushort(10,3,5) == 9);\n    assert(docond4!uint(10,3,5)   == 9);\n    assert(docond4!ulong(10,3,5)  == 9);\n\n\n    assert(docond1!ubyte(10,5,3)  == 10);\n    assert(docond1!ushort(10,5,3) == 10);\n    assert(docond1!uint(10,5,3)   == 10);\n    assert(docond1!ulong(10,5,3)  == 10);\n\n    assert(docond2!ubyte(10,5,3)  == 9);\n    assert(docond2!ushort(10,5,3) == 9);\n    assert(docond2!uint(10,5,3)   == 9);\n    assert(docond2!ulong(10,5,3)  == 9);\n\n    assert(docond3!ubyte(10,5,3)  == 11);\n    assert(docond3!ushort(10,5,3) == 11);\n    assert(docond3!uint(10,5,3)   == 11);\n    assert(docond3!ulong(10,5,3)  == 11);\n\n    assert(docond4!ubyte(10,5,3)  == 10);\n    assert(docond4!ushort(10,5,3) == 10);\n    assert(docond4!uint(10,5,3)   == 10);\n    assert(docond4!ulong(10,5,3)  == 10);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nstruct S8658\n{\n    int[16385] a;\n}\n\nvoid foo8658(S8658 s)\n{\n    int x;\n}\n\nvoid test8658()\n{\n    S8658 s;\n    for(int i = 0; i < 1000; i++)\n        foo8658(s);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nuint neg(uint i)\n{\n    return ~i + 1;\n}\n\nuint com(uint i)\n{\n    return -i - 1;\n}\n\nfloat com(float i)\n{\n    return -i - 1;\n}\n\nuint com2(uint i)\n{\n    return -(i + 1);\n}\n\nvoid testnegcom()\n{\n    assert(neg(3) == -3);\n    assert(com(3) == -4);\n    assert(com(3.0f) == -4.0f);\n    assert(com2(3) == -4);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nint oror1(char c)\n{\n    return ((((((((((cast(int) c <= 32 || cast(int) c == 46) || cast(int) c == 44)\n                 || cast(int) c == 58) || cast(int) c == 59) || cast(int) c == 60)\n              || cast(int) c == 62) || cast(int) c == 34) || cast(int) c == 92)\n           || cast(int) c == 39) != 0);\n}\n\nint oror2(char c)\n{\n    return ((((((((((c <= 32 || c == 46) || c == 44)\n                 || c == 58) || c == 59) || c == 60)\n                 || c == 62) || c == 34) || c == 92)\n                 || c == 39) != 0);\n}\n\nvoid testoror()\n{\n    assert(oror1(0) == 1);\n    assert(oror1(32) == 1);\n    assert(oror1(46) == 1);\n    assert(oror1(44) == 1);\n    assert(oror1(58) == 1);\n    assert(oror1(59) == 1);\n    assert(oror1(60) == 1);\n    assert(oror1(62) == 1);\n    assert(oror1(34) == 1);\n    assert(oror1(92) == 1);\n    assert(oror1(39) == 1);\n    assert(oror1(33) == 0);\n    assert(oror1(61) == 0);\n    assert(oror1(93) == 0);\n    assert(oror1(255) == 0);\n\n    assert(oror2(0) == 1);\n    assert(oror2(32) == 1);\n    assert(oror2(46) == 1);\n    assert(oror2(44) == 1);\n    assert(oror2(58) == 1);\n    assert(oror2(59) == 1);\n    assert(oror2(60) == 1);\n    assert(oror2(62) == 1);\n    assert(oror2(34) == 1);\n    assert(oror2(92) == 1);\n    assert(oror2(39) == 1);\n    assert(oror2(33) == 0);\n    assert(oror2(61) == 0);\n    assert(oror2(93) == 0);\n    assert(oror2(255) == 0);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nbool bt1(int p, int a, int b)\n{\n    return p && ((1 << b) & a);\n}\n\nbool bt2(int p, long a, long b)\n{\n    return p && ((1L << b) & a);\n}\n\nvoid testbt()\n{\n    assert(bt1(1,7,2) == 1);\n    assert(bt1(1,7,3) == 0);\n\n    assert(bt2(1,0x7_0000_0000,2+32) == 1);\n    assert(bt2(1,0x7_0000_0000,3+32) == 0);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid test13383()\n{\n    foreach (k; 32..33)\n    {\n        if (1L & (1L << k))\n        {\n            assert(0);\n        }\n    }\n}\n\n////////////////////////////////////////////////////////////////////////\n\nint andand1(int c)\n{\n    return (c > 32 && c != 46 && c != 44\n                   && c != 58 && c != 59\n                   && c != 60 && c != 62\n                   && c != 34 && c != 92\n                   && c != 39) != 0;\n}\n\nbool andand2(long c)\n{\n    return (c > 32 && c != 46 && c != 44\n                   && c != 58 && c != 59\n                   && c != 60 && c != 62\n                   && c != 34 && c != 92\n                   && c != 39) != 0;\n}\n\nint foox3() { return 1; }\n\nint andand3(uint op)\n{\n    if (foox3() &&\n        op != 7 &&\n        op != 3 &&\n        op != 18 &&\n        op != 30 &&\n        foox3())\n        return 3;\n    return 4;\n}\n\n\nvoid testandand()\n{\n    assert(andand1(0) == 0);\n    assert(andand1(32) == 0);\n    assert(andand1(46) == 0);\n    assert(andand1(44) == 0);\n    assert(andand1(58) == 0);\n    assert(andand1(59) == 0);\n    assert(andand1(60) == 0);\n    assert(andand1(62) == 0);\n    assert(andand1(34) == 0);\n    assert(andand1(92) == 0);\n    assert(andand1(39) == 0);\n    assert(andand1(33) == 1);\n    assert(andand1(61) == 1);\n    assert(andand1(93) == 1);\n    assert(andand1(255) == 1);\n\n    assert(andand2(0) == false);\n    assert(andand2(32) == false);\n    assert(andand2(46) == false);\n    assert(andand2(44) == false);\n    assert(andand2(58) == false);\n    assert(andand2(59) == false);\n    assert(andand2(60) == false);\n    assert(andand2(62) == false);\n    assert(andand2(34) == false);\n    assert(andand2(92) == false);\n    assert(andand2(39) == false);\n    assert(andand2(33) == true);\n    assert(andand2(61) == true);\n    assert(andand2(93) == true);\n    assert(andand2(255) == true);\n\n    assert(andand3(6) == 3);\n    assert(andand3(30) == 4);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nbool bittest11508(char c)\n{\n    return c=='_' || c=='-' || c=='+' || c=='.';\n}\n\nvoid testbittest()\n{\n    assert(bittest11508('_'));\n}\n\n////////////////////////////////////////////////////////////////////////\n\nuint or1(ubyte x)\n{\n    return x | (x<<8) | (x<<16) | (x<<24) | (x * 3);\n}\n\nvoid testor_combine()\n{\n    printf(\"%x\\n\", or1(1));\n    assert(or1(5) == 5 * (0x1010101 | 3));\n}\n\n////////////////////////////////////////////////////////////////////////\n\n\nint shrshl(int i) {\n  return ((i+1)>>1)<<1;\n}\n\nvoid testshrshl()\n{\n    assert(shrshl(6) == 6);\n    assert(shrshl(7) == 8);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nstruct S1\n{\n    cdouble val;\n}\n\nvoid formatTest(S1 s, double re, double im)\n{\n    assert(s.val.re == re);\n    assert(s.val.im == im);\n}\n\nvoid test10639()\n{\n    S1 s = S1(3+2.25i);\n    formatTest(s, 3, 2.25);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nbool bt10715(in uint[] ary, size_t bitnum)\n{\n    return !!(ary[bitnum >> 5] & 1 << (bitnum & 31)); // uses bt\n}\n\nbool neg_bt10715(in uint[] ary, size_t bitnum)\n{\n    return !(ary[bitnum >> 5] & 1 << (bitnum & 31)); // does not use bt\n}\n\nvoid test10715()\n{\n    static uint[2]  a1 = [0x1001_1100, 0x0220_0012];\n\n    if ( bt10715(a1,30)) assert(0);\n    if (!bt10715(a1,8))  assert(0);\n    if ( bt10715(a1,30+32)) assert(0);\n    if (!bt10715(a1,1+32))  assert(0);\n\n    if (!neg_bt10715(a1,30)) assert(0);\n    if ( neg_bt10715(a1,8))  assert(0);\n    if (!neg_bt10715(a1,30+32)) assert(0);\n    if ( neg_bt10715(a1,1+32))  assert(0);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nptrdiff_t compare12164(A12164* rhsPA, A12164* zis)\n{\n    if (*rhsPA == *zis)\n        return 0;\n    return ptrdiff_t.min;\n}\n\nstruct A12164\n{\n    int a;\n}\n\nvoid test12164()\n{\n    auto a = A12164(3);\n    auto b = A12164(2);\n    assert(compare12164(&a, &b));\n}\n\n////////////////////////////////////////////////////////////////////////\n\nint foo10678(char[5] txt)\n{\n    return txt[0] + txt[1] + txt[4];\n}\n\nvoid test10678()\n{\n    char[5] hello = void;\n    hello[0] = 8;\n    hello[1] = 9;\n    hello[4] = 10;\n    int i = foo10678(hello);\n    assert(i == 27);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nstruct S12051\n{\n    this(char c)\n    {\n        assert(c == 'P' || c == 'M');\n    }\n}\n\nvoid test12051()\n{\n    auto ip = [\"abc\"];\n    foreach (i, s; ip)\n    {\n        S12051(i < ip.length ? 'P' : 'M');\n    }\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid bug7565( double x) { assert(x == 3); }\n\nvoid test7565()\n{\n   double y = 3;\n   bug7565( y++ );\n   assert(y == 4);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nint bug8525(int[] devt)\n{\n    return devt[$ - 1];\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid func13190(int) {}\n\nstruct Struct13190\n{\n    ulong a;\n    uint b;\n};\n\n__gshared Struct13190* table13190 =\n[\n    Struct13190(1, 1),\n    Struct13190(0, 2)\n];\n\nvoid test13190()\n{\n    for (int i = 0; table13190[i].a; i++)\n    {\n        ulong tbl = table13190[i].a;\n        func13190(i);\n        if (1 + tbl)\n        {\n            if (tbl == 0x80000)\n                return;\n        }\n    }\n}\n\n////////////////////////////////////////////////////////////////////////\n\ndouble foo13485(double c, double d)\n{\n    // This must not be optimized to c += (d + d)\n    c += d;\n    c += d;\n    return c;\n}\n\nvoid test13485()\n{\n    enum double d = 0X1P+1023;\n    assert(foo13485(-d, d) == d);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid test12833a(int a)\n{\n    long x = cast(long)a;\n\n    switch (cast(int)(cast(ushort)(x >> 16 & 65535L)))\n    {\n        case 1:\n        {\n            break;\n        }\n        default:\n        {\n            assert(0);\n        }\n    }\n}\n\nvoid test12833()\n{\n    test12833a(0x1_0000);\n}\n\n/***********************************************/\n\nstruct Point9449\n{\n    double f = 3.0;\n    double g = 4.0;\n}\n\nvoid test9449()\n{\n    Point9449[1] arr;\n    if (arr[0].f != 3.0) assert(0);\n    if (arr[0].g != 4.0) assert(0);\n}\n\nstruct Point9449x\n{\n    float  f = 0.0;\n    double g = 0.0;\n}\n\nvoid test9449x()\n{\n    Point9449x[1] arr;\n    if (arr[0].f != 0.0) assert(0);\n    if (arr[0].g != 0.0) assert(0);\n}\n\n////////////////////////////////////////////////////////////////////////\n// https://issues.dlang.org/show_bug.cgi?id=12057\n\nbool prop12057(real x) { return false; }\ndouble f12057(real) { return double.init; }\nvoid test12057()\n{\n    real fc = f12057(real.init);\n    if (fc == 0 || fc.prop12057) {}\n}\n\n\n////////////////////////////////////////////////////////////////////////\n\nlong modulo24 (long ticks)\n{\n    ticks %= 864000000000;\n    if (ticks < 0)\n        ticks += 864000000000;\n    return ticks;\n}\n\nvoid test13784()\n{\n    assert (modulo24(-141600000000) == 722400000000);\n}\n\n\n////////////////////////////////////////////////////////////////////////\n\nstruct S13969 {\n    int x, y;\n}\n\nint test13969(const S13969* f) {\n    return 0 % ((f.y > 0) ? f.x / f.y : f.x / -f.y);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nint[] arr14436;\nvoid test14436()\n{\n    assert(arr14436 == null);\n    arr14436 = [1, 2, 3];\n    assert(arr14436 != null);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid test14220()\n{\n    auto a = toString(14);\n\n    printf(\"a.ptr = %p, a.length = %d\\n\", a.ptr, cast(int)a.length);\n    return;\n}\n\nauto toString(int value)\n{\n    uint mValue = value;\n\n    char[int.sizeof * 3] buffer = void;\n    size_t index = buffer.length;\n\n    do\n    {\n        uint div = cast(int)(mValue / 10);\n        char mod = mValue % 10 + '0';\n        buffer[--index] = mod;        // Line 22\n        mValue = div;\n    } while (mValue);\n\n    //printf(\"buffer.ptr = %p, index = %d\\n\", buffer.ptr, cast(int)index);\n    return dup(buffer[index .. $]);\n}\n\nchar[] dup(char[] a)\n{\n    //printf(\"a.ptr = %p, a.length = %d\\n\", a.ptr, cast(int)a.length);\n    a[0] = 1;       // segfault\n    return a;\n}\n\n////////////////////////////////////////////////////////////////////////\n\nint stripLeft(int str, int dc)\n{\n    while (true)\n    {\n        int a = str;\n        int s = a;\n        str += 1;\n        if (dc) return s;\n    }\n}\n\nvoid test14829()\n{\n    if (stripLeft(3, 1) != 3) // fails with -O\n        assert(0);\n}\n\n\n////////////////////////////////////////////////////////////////////////\n\nvoid test2()\n{\n    void test(cdouble v)\n    {\n            auto x2 = cdouble(v);\n            assert(x2 == v);\n    }\n    test(1.2+3.4i);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid test3()\n{\n    int[6] a;\n    int[] b;\n    b = a;\n    b = (b.ptr + b.length - 5)[0 .. b.ptr + b.length - 1 - a.ptr];\n    assert(b.ptr == a.ptr + 1);\n    assert(b.length == 5);\n}\n\n////////////////////////////////////////////////////////////////////////\n// https://issues.dlang.org/show_bug.cgi?id=14782\n\n\nvoid test14782()\n{\n    static struct Foo\n    {\n        long a = 8;\n        int b = 7;\n    }\n\n    static Foo[1] fun() { Foo[1] a; return a; }\n\n    auto result = fun();\n    assert(result[0].a == 8);\n    assert(result[0].b == 7);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid test14987()\n{\n    static struct Foo\n    {\n        int b = 7;\n    }\n    static assert((Foo[4]).sizeof == 16);\n\n    static Foo[4] fun() { Foo[4] a; return a; }\n\n    auto result = fun();\n    assert(result[0].b == 7);\n    assert(result[1].b == 7);\n    assert(result[2].b == 7);\n    assert(result[3].b == 7);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid[] calloc15272(size_t bc) nothrow pure\n{\n    assert(bc == 1);\n    return new void[1];\n}\n\nvoid test15272()\n{\n    void[] scache = cast(void[])\"abc\";\n    size_t count = 1;\n    void[]* buckets = &scache;\n    *buckets = calloc15272(count)[0 .. count];\n}\n\n/*****************************************\n * https://issues.dlang.org/show_bug.cgi?id=15861\n */\n\nvoid test15861()\n{\n    double val = 4286853117.;\n\n    (){\n        assert(val == 4286853117.);\n    }();\n}\n\n////////////////////////////////////////////////////////////////////////\n\n// https://issues.dlang.org/show_bug.cgi?id=15629 comment 3\n// -O\n\nvoid test15629()\n{\n    int[] a = [3];\n    int value = a[0] >= 0 ? a[0] : -a[0];\n    assert(a[0] == 3);\n    writeln(value, a);\n}\n\nvoid writeln(int v, int[] a)\n{\n}\n\n////////////////////////////////////////////////////////////////////////\n\nreal binPosPow2() { return 1.0L; }\n\nreal binPow2()\n{\n    return 1.0L/binPosPow2();\n}\n\nvoid test4()\n{\n    assert(binPow2() == 1.0L);\n}\n\n////////////////////////////////////////////////////////////////////////\n// https://issues.dlang.org/show_bug.cgi?id=13474\n\n\ndouble sumKBN(double s = 0.0)\n{\n    import std.math : fabs;\n    double c = 0.0;\n        foreach(double x; [1, 1e100, 1, -1e100])\n        {\n            x = multiply(x);\n            double t = s + x;\n            if(s.fabs >= x.fabs)\n            {\n                double y = s-t;\n                c += y+x;\n            }\n            else\n            {\n                double y = x-t;\n                c += y+s;\n            }\n            s = t;\n        }\n    return s + c;\n}\n\ndouble multiply(double a) { return a * 10000; }\n\nvoid test13474()\n{\n    double r = 20000;\n    assert(r == sumKBN());\n}\n\n////////////////////////////////////////////////////////////////////////\n// https://issues.dlang.org/show_bug.cgi?id=16699\n\nulong[1] parseDateRange()\n{\n    try\n    {\n        ulong[1] result;\n        result[0] = 6;\n        return result;\n    }\n    finally\n    {\n    }\n}\n\nvoid test16699()\n{\n    ulong[1] range = parseDateRange();\n    assert(range[0] == 6);\n}\n\n////////////////////////////////////////////////////////////////////////\n\n// https://issues.dlang.org/show_bug.cgi?id=16102\n\nstruct S16102 { ~this() { } }\n\nlong[1] f16102()\n{\n    S16102 a;\n    return [1];\n}\n\nvoid test16102()\n{\n    assert( f16102() == [1] );\n}\n\n////////////////////////////////////////////////////////////////////////\n\n\n/* Test the pattern:\n *   replace ((i / C1) / C2) with (i / (C1 * C2))\n * when e1 is 0 or 1 and (i2-i1) is a power of 2.\n */\n\nvoid divdiv(T, T C1, T C2)(T i)\n{\n    auto a = (i / C1) / C2;\n    auto b = i / (C1 * C2);\n    if (a != b) assert(0);\n}\n\nvoid testdivdiv()\n{\n    divdiv!(int,10,20)(30);\n    divdiv!(uint,10,20)(30);\n    divdiv!(long,10,20)(30);\n    divdiv!(ulong,10,20)(30);\n\n    divdiv!(int,-10,20)(30);\n    divdiv!(long,-10,20)(30);\n\n    divdiv!(int,-10,-20)(-30);\n    divdiv!(long,-10,-20)(-30);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid test5a(ulong x, ulong y)\n{\n    int a;\n    if (x >> 32)\n        a = 1;\n    else\n        a = 2;\n    assert(a == 1);\n\n    if (y >> 32)\n        a = 1;\n    else\n        a = 2;\n    assert(a == 2);\n}\n\nvoid test5()\n{\n    test5a(uint.max + 1L, uint.max);\n}\n\n////////////////////////////////////////////////////////////////////////\n\n/* Test the pattern:\n *   replace (e ? i1 : i2) with (i1 + e * (i2 - i1))\n * when e1 is 0 or 1 and (i2-i1) is a power of 2.\n */\n\nint foo61(int i)\n{\n    return (i % 2 != 0) ? 4 : 2;\n}\n\nint foo62(int i)\n{\n    return (i % 2 != 0) ? 2 : 4;\n}\n\nbool bar6(bool b) { return b; }\n\nint foo63(bool b)\n{\n    return bar6(b) ? 16 : 8;\n}\n\nint foo64(bool b)\n{\n    return bar6(b) ? 8 : 16;\n}\n\nvoid test6()\n{\n    if (foo61(0) != 2) assert(0);\n    if (foo61(1) != 4) assert(0);\n    if (foo62(0) != 4) assert(0);\n    if (foo62(1) != 2) assert(0);\n    if (foo63(0) != 8) assert(0);\n    if (foo63(1) != 16) assert(0);\n    if (foo64(0) != 16) assert(0);\n    if (foo64(1) != 8) assert(0);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nint dataflow(int b) {\n  int ret;\n\n  if (b==4)\n    ret = 3;\n  else\n    ret = 5;\n\n  if (ret == 4)\n    return 0;\n  else\n    return 1;\n}\n\nvoid testeqeqranges()\n{\n    int i = dataflow(4);\n    if (i != 1)\n        assert(0);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid testdivcmp()\n{\n    // https://github.com/dlang/dmd/pull/7128\n    static bool foo(uint a, uint b)\n    {\n        return cast(bool)(a / b); // convert / to >=\n    }\n\n    assert(!foo(3, 4));\n    assert(foo(4, 4));\n    assert(foo(5, 4));\n}\n\n////////////////////////////////////////////////////////////////////////\n\n// https://issues.dlang.org/show_bug.cgi?id=16189\n\nvoid test16189()\n{\n    ubyte[9][1] data;\n    uint a = 0;\n  loop:\n    data[0] = data[a];\n    a--;\n    bool b = false;\n    if (b) goto loop;\n    assert(a == -1); // was failing with -O\n}\n\n\n////////////////////////////////////////////////////////////////////////\n\n// https://issues.dlang.org/show_bug.cgi?id=16997\n\nvoid test16997()\n{\n    /* Exhaustively test all signed and unsigned byte promotions for\n     * - + and ~\n     */\n    for (int i = 0; i < 256; ++i)\n    {\n        ubyte c = cast(ubyte)i;\n\n        int i1 = cast(int)(~c);\n        int i2 = cast(int)(~cast(int)c);\n\n        //printf(\"%d, %d\\n\", i1, i2);\n        assert(i1 == i2);\n\n        i1 = cast(int)(+c);\n        i2 = cast(int)(+cast(int)c);\n        assert(i1 == i2);\n\n        i1 = cast(int)(-c);\n        i2 = cast(int)(-cast(int)c);\n        assert(i1 == i2);\n    }\n\n    for (int i = 0; i < 256; ++i)\n    {\n        byte c = cast(byte)i;\n\n        int i1 = cast(int)(~c);\n        int i2 = cast(int)(~cast(int)c);\n\n        //printf(\"%d, %d\\n\", i1, i2);\n        assert(i1 == i2);\n\n        i1 = cast(int)(+c);\n        i2 = cast(int)(+cast(int)c);\n        assert(i1 == i2);\n\n        i1 = cast(int)(-c);\n        i2 = cast(int)(-cast(int)c);\n        assert(i1 == i2);\n    }\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid test18315() // https://issues.dlang.org/show_bug.cgi?id=18315\n{\n    int i = int.min;\n    bool b = i > 0;\n    assert(!b);\n    b = 0 < i;\n    assert(!b);\n}\n\n////////////////////////////////////////////////////////////////////////\n\n// https://issues.dlang.org/show_bug.cgi?id=18461\n\nvoid test18461()\n{\n    import core.bitop;\n\n    size_t test_val = 0b0001_0000;\n\n    if (bt(&test_val, 4) == 0)\n        assert(false);\n}\n\n////////////////////////////////////////////////////////////////////////\n\nvoid test18730() // https://issues.dlang.org/show_bug.cgi?id=18730\n{\n    static if (size_t.sizeof == 8)\n    {\n        static int bt18730_64_64(in ulong* p, ulong bitnum) pure @system\n        {\n            return ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0;\n        }\n        static int bt18730_64_32(in ulong* p, uint bitnum) pure @system\n        {\n            return ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0;\n        }\n        static int bt18730_32_64(in uint* p, ulong bitnum) pure @system\n        {\n            return ((p[bitnum >> 5] & (1 << (bitnum & 31)))) != 0;\n        }\n\n        // Check that bt_64_64 uses a 64-bit register for the offset.\n        {\n            enum bitIndex = int.max + 1L;\n            auto a = new ulong[](bitIndex / 64 + 1);\n            a[bitIndex / 64] = 1;\n            assert(bt18730_64_64(a.ptr, bitIndex));\n            assert(!bt18730_64_64(a.ptr, bitIndex + 1));\n            assert(!bt18730_64_64(a.ptr, bitIndex - 1));\n        }\n        // Check that bt_64_32 uses a 32-bit register for the offset.\n        {\n            static int f(ulong* p, ulong bitnum)\n            {\n                return bt18730_64_32(p, cast(uint) bitnum);\n            }\n            enum bitIndex = uint.max + 1L;\n            assert(cast(uint) bitIndex == 0);\n            ulong s = 1;\n            assert(f(&s, bitIndex));\n        }\n        /* Check that bt_32_64 does not become a 64-bit bt instruction. Would lead\n        to a segfault when trying to load 8 bytes while only 4 are accessible. */\n        version (Posix)\n        {{\n            import core.sys.posix.sys.mman;\n            import core.sys.posix.unistd;\n            // Allocate two pages.\n            immutable sz = 2 * sysconf(_SC_PAGESIZE);\n            auto m = mmap(null, sz, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0);\n            // Discard the higher page. It becomes unreadable.\n            munmap(m + sz / 2, sz / 2);\n            // Try looking at the last 4 bytes of the readable page.\n            uint* p = cast(uint*) (m + sz / 2 - uint.sizeof);\n            bt18730_32_64(p, 0);\n            munmap(m, sz / 2); // Free the readable page.\n        }}\n    }\n}\n\n////////////////////////////////////////////////////////////////////////\n\nint main()\n{\n    testgoto();\n    testswitch();\n    testdo();\n    testbreak();\n    teststringswitch();\n    teststrarg();\n    test12164();\n    testsizes();\n    testarrayinit();\n    testU();\n    testulldiv();\n    testbittest();\n    test8658();\n    testfastudiv();\n    testfastdiv();\n    test3918();\n    test12051();\n    testdocond();\n    testnegcom();\n    test11565();\n    testoror();\n    testbt();\n    test12095(0);\n    testandand();\n    testor_combine();\n    testshrshl();\n    test13383();\n    test13190();\n    test13485();\n    test14436();\n    test10639();\n    test10715();\n    test10678();\n    test7565();\n    test13023(0x10_0000_0000);\n    test12833();\n    test9449();\n    test9449x();\n    test12057();\n    test13784();\n    test14220();\n    test14829();\n    test2();\n    test3();\n    test14782();\n    test14987();\n    test15272();\n    test15861();\n    test15629();\n    test4();\n    test13474();\n    test16699();\n    test16102();\n    testdivdiv();\n    test5();\n    test6();\n    testeqeqranges();\n    testdivcmp();\n    test16189();\n    test16997();\n    test18315();\n    test18461();\n    test18730();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/minimal.d",
    "content": "// DFLAGS:\n// PERMUTE_ARGS:\n// REQUIRED_ARGS: -defaultlib=\n// EXTRA_SOURCES: extra-files/minimal/object.d\n\n// This test ensures an empty main can be built and executed with a minimal runtime\n\nvoid main() { }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/minimal2.d",
    "content": "// DFLAGS:\n// REQUIRED_ARGS: -defaultlib=\n// EXTRA_SOURCES: extra-files/minimal/object.d\n\n// This test ensures that interfaces and classes can be used in a minimal\n// runtime as long as they only contain shared static members.  Non-shared\n// static members would require a thread-local storage (TLS) implementation.\n\ninterface I\n{\n    shared static int i;\n}\n\nclass A : I\n{\n    shared static int a;\n}\n\nclass B : A\n{\n    shared static int b;\n\n    static int sumAll()\n    {\n        return b + a + i;\n    }\n}\n\nvoid poorMansAssert(bool condition)\n{\n    if (!condition)\n    {\n        version (GNU)\n        {\n            import gcc.builtins;\n            __builtin_trap();\n        }\n        else\n        {\n            asm {hlt;}\n        }\n    }\n}\n\nvoid main()\n{\n    B.i = 32;\n    B.a = 42;\n    B.b = 52;\n\n    poorMansAssert(B.i == 32 || B.a == 42 || B.b == 52);\n    poorMansAssert(B.sumAll() == (32 + 42 + 52));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/mixin1.d",
    "content": "\nmodule mixin1;\n\nimport std.stdio;\n\nalias TypeTuple(T...) = T;\n\n/*******************************************/\n\nmixin template Foo(T)\n{\n    T x;\n}\n\nmixin Foo!(uint);\n\nstruct Bar\n{\n    template Abc(T)\n    {\n        T y;\n    }\n\n    template Def(T)\n    {\n        T z;\n    }\n}\n\nmixin Bar.Abc!(int);\n\nBar b;\nmixin typeof(b).Def!(int);\n\nvoid test1()\n{\n    x = 3;\n    assert(x == 3);\n    y = 4;\n    assert(y == 4);\n    z = 5;\n    assert(z == 5);\n}\n\n/*******************************************/\n\ntemplate Foo2(T)\n{\n    T x2 = T.sizeof;\n}\n\nmixin Foo2!(uint) B2;\nmixin Foo2!(long) C2;\nmixin Foo2!(int);\n\nvoid test2()\n{\n    B2.x2 = 3;\n    assert(B2.x2 == 3);\n    assert(C2.x2 == long.sizeof);\n//    assert(x2 == int.sizeof);\n}\n\n/*******************************************/\n\ntemplate Foo3(T)\n{\n    int func() { printf(\"Foo3.func()\\n\"); return 1; }\n}\n\nclass Bar3\n{\n    mixin Foo3!(int);\n}\n\nclass Code3 : Bar3\n{\n    override int func() { printf(\"Code3.func()\\n\"); return 2; }\n}\n\nvoid test3()\n{\n    int i;\n\n    Bar3 b = new Bar3();\n    i = b.func();\n    assert(i == 1);\n\n    b = new Code3();\n    i = b.func();\n    assert(i == 2);\n}\n\n/*******************************************/\n\ntemplate Foo4(T)\n{\n    int func() { printf(\"Foo4.func()\\n\"); return 1; }\n}\n\nstruct Bar4\n{\n    mixin Foo4!(int);\n}\n\nvoid test4()\n{\n    int i;\n\n    Bar4 b;\n    i = b.func();\n    assert(i == 1);\n}\n\n/*******************************************/\n\ntemplate Foo5()\n{\n    int func() { printf(\"Foo5.func()\\n\"); return 1; }\n}\n\nstruct Bar5\n{\n    mixin Foo5;\n}\n\nvoid test5()\n{\n    int i;\n\n    Bar5 b;\n    i = b.func();\n    assert(i == 1);\n}\n\n/*******************************************/\n\ntemplate Foo6()\n{\n    int x = 5;\n}\n\nstruct Bar6\n{\n    mixin Foo6;\n}\n\nvoid test6()\n{\n    int i;\n\n    Bar6 b;\n    i = b.x;\n    assert(i == 5);\n    assert(b.sizeof == int.sizeof);\n}\n\n/*******************************************/\n\ntemplate Foo7()\n{\n    int x = 5;\n}\n\nclass Bar7\n{\n    int y = 6;\n    mixin Foo7;\n}\n\nvoid test7()\n{\n    int i;\n\n    Bar7 b = new Bar7();\n    i = b.x;\n    printf(\"b.x = %d\\n\", b.x);\n    assert(i == 5);\n}\n\n/*******************************************/\n\ntemplate Foo8()\n{\n    int x = 5;\n    int bar() { return 7; }\n}\n\nvoid test8()\n{\n    mixin Foo8;\n    printf(\"x = %d\\n\", x);\n    assert(x == 5);\n    assert(bar() == 7);\n}\n\n/*******************************************/\n\ntemplate Foo9()\n{\n    int abc() { return y; }\n}\n\nvoid test9()\n{\n    int y = 8;\n    mixin Foo9;\n    assert(abc() == 8);\n}\n\n/*******************************************/\n\ntemplate Foo10(alias b)\n{\n    typeof(b) abc() { return b; }\n}\n\nvoid test10()\n{\n    int y = 8;\n    mixin Foo10!(y);\n    assert(abc() == 8);\n}\n\n\n/*******************************************/\n\ntemplate Foo11(alias b)\n{\n    int abc() { return b; }\n}\n\nvoid test11()\n{\n    int y = 8;\n    mixin Foo11!(y) B;\n    assert(B.abc() == 8);\n}\n\n/*******************************************/\n\ntemplate duff_for(alias id1, alias id2, alias s)\n{\n\n    void duff_for()\n    {\n        printf(\"duff_for(%d, %d)\\n\", id1, id2);\n        typeof(id1) id = id1;\n        printf(\"fid = %d, %d\\n\", id, (id2 - id) % 8);\n        switch ((id2 - id) % 8)\n        {\n        case 0:\n         while (id != id2)\n         {\n             printf(\"wid = %d\\n\", id);\n             s(); ++id;\n             goto case;\n        case 7: s(); ++id; goto case;\n        case 6: s(); ++id; goto case;\n        case 5: s(); ++id; goto case;\n        case 4: s(); ++id; goto case;\n        case 3: s(); ++id; goto case;\n        case 2: s(); ++id; goto case;\n        case 1: s(); ++id;\n             break;\n        default: assert(0);\n         }\n        }\n    }\n}\n\nvoid foo12() { printf(\"foo12\\n\"); }\n\nvoid test12()\n{\n    int i = 1;\n    int j = 11;\n\n    mixin duff_for!(i, j, delegate void() { foo12(); });\n    duff_for();\n}\n\n/*******************************************/\n\ntemplate duff(alias id1, alias id2, alias s)\n{\n\n    void duff()\n    {\n        s();\n        s();\n    }\n}\n\nvoid foo13(int j)\n{\n    printf(\"foo13 j = %d\\n\", j);\n    assert(j == 1);\n}\n\nvoid test13()\n{\n    int i = 1;\n    int j = 11;\n\n    mixin duff!(i, j, delegate { foo13(i); });\n    duff();\n}\n\n/*******************************************/\n\ntemplate Foo14()\n{\n    int x14 = 5;\n}\n\nvoid test14()\n{\n    int x14 = 6;\n    mixin Foo14;\n    printf(\"x14 = %d\\n\", x14);\n    assert(x14 == 6);\n}\n\n/*******************************************/\n\ntemplate Foo15()\n{\n    int x15 = 5;\n\n    int bar15() { return x15; }\n}\n\nint x15 = 6;\nmixin Foo15;\n\nvoid test15()\n{\n\n    printf(\"x15 = %d\\n\", x15);\n    printf(\"bar15() = %d\\n\", bar15());\n    assert(x15 == 6);\n    assert(bar15() == 5);\n}\n\n/*******************************************/\n\ntemplate Foo16()\n{\n    int x16 = 5;\n\n    int bar() { return x16; }\n}\n\nmixin Foo16 A16;\nint x16 = 6;\nmixin Foo16 B16;\n\nvoid test16()\n{\n\n    printf(\"x16 = %d\\n\", x16);\n    printf(\"bar() = %d\\n\", A16.bar());\n    assert(x16 == 6);\n    assert(A16.x16 == 5);\n    assert(B16.x16 == 5);\n    assert(A16.bar() == 5);\n    assert(B16.bar() == 5);\n}\n\n/*******************************************/\n\ntemplate Foo17()\n{\n    int x17 = 5;\n}\n\nmixin Foo17;\n\nstruct Bar17\n{\n    mixin Foo17;\n}\n\nvoid test17()\n{\n    printf(\"x17 = %d\\n\", x17);          // prints 5\n    assert(x17 == 5);\n    {   Bar17 b;\n        int x17 = 3;\n\n        printf(\"b.x17 = %d\\n\", b.x17);  // prints 5\n        assert(b.x17 == 5);\n        printf(\"x17 = %d\\n\", x17);      // prints 3\n        assert(x17 == 3);\n        {\n            mixin Foo17;\n            printf(\"x17 = %d\\n\", x17);  // prints 5\n            assert(x17 == 5);\n            x17 = 4;\n            printf(\"x17 = %d\\n\", x17);  // prints 4\n            assert(x17 == 4);\n        }\n        printf(\"x17 = %d\\n\", x17);      // prints 3\n        assert(x17 == 3);\n    }\n    printf(\"x17 = %d\\n\", x17);          // prints 5\n    assert(x17 == 5);\n}\n\n/*******************************************/\n\ntemplate Foo18() { int z = 3; }\n\nstruct Bar18(alias Tmpl)\n{\n    mixin Tmpl;\n}\n\nBar18!(Foo18) b18;\n\nvoid test18()\n{\n    assert(b18.z == 3);\n}\n\n/*******************************************/\n\ntemplate Mix1(T)\n{\n    int foo19(T a) { return 2*a; }\n}\n\ntemplate Mix2(T)\n{\n    mixin Mix1!(T);\n\n    int bar19(T a) { return foo19(a); }\n}\n\nmixin Mix2!(int);\n\nvoid test19()\n{\n    int i;\n\n    i = bar19(7);\n    assert(i == 14);\n}\n\n/*******************************************/\n\ninterface A20 { int f(); }\n\ntemplate Foo20()\n{\n    int f()\n    {\n        printf(\"in C20.f()\\n\");\n        return 6;\n    }\n}\n\nclass C20 : A20\n{\n    mixin Foo20;\n//    void f() { printf(\"in C20.f()\\n\"); }\n}\n\nvoid test20()\n{\n    C20 c = new C20();\n    int i = c.f();\n    assert(i == 6);\n}\n\n/*******************************************/\n\ntemplate Mix21() { this(int x) { printf(\"mix1\\n\"); }}\n\nclass Bar21\n{\n     int myx;\n     mixin Mix21; // wouldn't compile\n\n     this() { myx = 15; }\n\n//     mixin Mix21; // placing it here compiles\n}\n\nvoid test21()\n{\n     Bar21 bar = new Bar21();\n}\n\n/*******************************************/\n\ntemplate A22(T)\n{\n    this()\n    {   int i;\n        i = super.foo();\n        assert(i == 67);\n    }\n}\n\n\nclass B22\n{\n    int foo() { printf(\"B22.foo()\\n\"); return 67; }\n}\n\nclass C22 : B22\n{\n    mixin A22!(C22);\n}\n\nvoid test22()\n{\n    C22 c = new C22;\n}\n\n\n/*******************************************/\n\ntemplate Foo23()\n{\n     const int x = 5;\n}\n\nclass C23\n{\n     mixin Foo23 F;\n}\n\nstruct D23\n{\n     mixin Foo23 F;\n}\n\nvoid test23()\n{\n     C23 c = new C23;\n\n     printf(\"%d\\n\",c.F.x);\n     assert(c.F.x == 5);\n\n     D23 d;\n\n     printf(\"%d\\n\",d.F.x);\n     assert(d.F.x == 5);\n}\n\n/*******************************************/\n\ntemplate T24()\n{\n   void foo24() { return cast(void)0; }\n//   alias foo24 foo24;\n}\n\nmixin T24;\n\nvoid test24()\n{\n   foo24();\n}\n\n\n/*******************************************/\n\ntemplate ctor25()\n{\n this() { this(null); }\n this( Object o ) {}\n}\n\nclass Foo25\n{\n mixin ctor25;\n}\n\nvoid test25()\n{\n Foo25 foo = new Foo25();\n}\n\n\n/*******************************************/\n\ntemplate Get26(T)\n{\n    Reader get (ref T x)\n    {\n        return this;\n    }\n}\n\nclass Reader\n{\n    mixin Get26!(byte) bar;\n    alias bar.get get;\n    mixin Get26!(int) beq;\n    alias beq.get get;\n}\n\nvoid test26()\n{\n    Reader r = new Reader;\n    Reader s;\n    byte q;\n    s = r.get (q);\n    assert(s == r);\n}\n\n/*******************************************/\n\ntemplate Template(int L)\n{\n    int i = L;\n    int foo(int b = Template!(9).i) {\n        return b;\n    }\n}\n\nvoid test27()\n{\n    int i = 10;\n    int foo(int b = Template!(9).i) {\n        return b;\n    }\n    assert(foo()==9);\n}\n\n/*******************************************/\n\ntemplate Blah28(int a, alias B)\n{\n   mixin Blah28!(a-1, B);\n   //mixin Blah28!(0, B);\n}\n\ntemplate Blah28(int a:0, alias B)\n{\n}\n\nvoid test28()\n{\n   int a;\n   mixin Blah28!(5,a);\n   printf(\"a = %d\\n\", a);\n}\n\n/*******************************************/\n\ntemplate T29()\n{\n    int x;\n}\n\nstruct S29\n{\n    mixin T29;\n    int y;\n}\n\nconst S29 s29 = { x:2, y:3 };\n\nvoid test29()\n{\n    assert(s29.x == 2);\n    assert(s29.y == 3);\n}\n\n/*******************************************/\n\nclass A30\n{\n    template ctor(Type)\n    {\n        this(Type[] arr)\n        {\n            foreach(Type v; arr) writeln(typeid(typeof(v)));\n        }\n    }\n\n    mixin ctor!(int);\n}\n\nvoid test30()\n{\n    static int[] ints = [0,1,2,3];\n    A30 a = new A30(ints);\n}\n\n/*******************************************/\n\ntemplate Share(T) {\n  const bool opEquals(ref const T x) { return true; }\n}\n\nstruct List31(T) {\n\n    //int opEquals(List31 x) { return 0; }\n    mixin Share!(List31);\n}\n\nvoid test31()\n{\n  List31!(int) x;\n  List31!(int) y;\n  int i = x == y;\n  assert(i == 1);\n}\n\n/*******************************************/\n\ntemplate Blah(int a, alias B)\n{\n   mixin Blah!(a-1, B);\n}\n\ntemplate Blah(int a:0, alias B)\n{\n    int foo()\n    {   return B + 1;\n    }\n}\n\nvoid test32()\n{\n   int a = 3;\n   mixin Blah!(5,a);\n\n   assert(foo() == 4);\n}\n\n/*******************************************/\n\ntemplate T33( int i )\n{\n    int foo()\n    {\n        printf(\"foo %d\\n\", i );\n        return i;\n    }\n    int opCall()\n    {\n        printf(\"opCall %d\\n\", i );\n        return i;\n    }\n}\n\n\nclass C33\n{\n    mixin T33!( 1 ) t1;\n    mixin T33!( 2 ) t2;\n}\n\nvoid test33()\n{\n    int i;\n    C33 c1 = new C33;\n    i = c1.t1.foo();\n    assert(i == 1);\n    i = c1.t2.foo();\n    assert(i == 2);\n    i = c1.t1();\n    assert(i == 1);\n    i = c1.t2();\n    assert(i == 2);\n}\n\n\n/*******************************************/\n\ntemplate mix34()\n{\n    int i;\n    void print()\n    {\n        printf( \"%d %d\\n\", i, j );\n        assert(i == 0);\n        assert(j == 0);\n    }\n}\n\nvoid test34()\n{\n    int j;\n    mixin mix34!();\n\n    print();\n    //printf( \"%i\\n\", i );\n}\n\n/*******************************************/\n\nmixin T35!(int) m35;\n\ntemplate T35(t)\n{\n    t a;\n}\n\nvoid test35()\n{\n   m35.a = 3;\n}\n\n/*******************************************/\n\nstruct Foo36\n{\n    int a;\n    mixin T!(int) m;\n    template T(t)\n    {\n        t b;\n    }\n    int c;\n}\n\nvoid test36()\n{\n   Foo36 f;\n   printf(\"f.sizeof = %d\\n\", f.sizeof);\n   assert(f.sizeof == 12);\n\n   f.a = 1;\n   f.m.b = 2;\n   f.c = 3;\n\n   assert(f.a == 1);\n   assert(f.m.b == 2);\n   assert(f.c == 3);\n}\n\n/*******************************************/\n\ntemplate Foo37()\n{\n    template func() {\n        int func() {\n            return 6;\n        }\n    }\n}\n\nclass Baz37\n{\n    mixin Foo37 bar;\n}\n\nvoid test37()\n{\n    Baz37 b = new Baz37;\n    auto i = b.bar.func!()();\n    assert(i == 6);\n    i = (new Baz37).bar.func!()();\n    assert(i == 6);\n}\n\n/*******************************************/\n\ntemplate Foo38()\n{\n    int a = 4;\n\n    ~this()\n    {\n        printf(\"one\\n\");\n        assert(a == 4);\n        assert(b == 5);\n        c++;\n    }\n}\n\nclass Outer38\n{   int b = 5;\n\n    static int c;\n\n    mixin Foo38!() bar;\n    mixin Foo38!() abc;\n\n    ~this()\n    {\n        printf(\"two\\n\");\n        assert(b == 5);\n        assert(c == 0);\n        c++;\n    }\n}\n\nvoid test38()\n{\n    Outer38 o = new Outer38();\n    delete o;\n    assert(Outer38.c == 3);\n}\n\n/*******************************************/\n\ntemplate TDtor()\n{\n    ~this()\n    {\n        printf(\"Mixed-in dtor\\n\");\n    }\n}\n\nclass Base39\n{\n    ~this()\n    {\n        printf(\"Base39 dtor\\n\");\n    }\n}\n\nclass Class39 : Base39\n{\n    mixin TDtor A;\n    mixin TDtor B;\n\n    ~this()\n    {\n        printf(\"Class39 dtor\\n\");\n    }\n}\n\nvoid test39()\n{\n    auto test = new Class39;\n}\n\n\n/*******************************************/\n\ntemplate Mix40()\n{\n  int  i;\n}\n\nstruct Z40\n{\n  union { mixin Mix40; }\n}\n\nvoid test40()\n{\n    Z40 z;\n    z.i = 3;\n}\n\n/*******************************************/\n\n\nclass X41(P...)\n{\n    alias P[0] Q;\n    mixin Q!();\n}\n\ntemplate MYP()\n{\n    void foo() { }\n}\n\nvoid test41()\n{\n    X41!(MYP) x;\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2245\n\ntemplate TCALL2245a(ARGS...)\n{\n    int makecall(ARGS args)\n    {\n        return args.length;\n    }\n}\n\ntemplate TCALL2245b(int n)\n{\n    int makecall2(ARGS...)(ARGS args) if (ARGS.length == n)\n    {\n        return args.length;\n    }\n}\n\nclass C2245\n{\n    mixin TCALL2245a!();\n    mixin TCALL2245a!(int);\n    mixin TCALL2245a!(int,int);\n\n    mixin TCALL2245b!(0);\n    mixin TCALL2245b!(1);\n    mixin TCALL2245b!(2);\n}\n\nstruct S2245\n{\n    mixin TCALL2245a!();\n    mixin TCALL2245a!(int);\n    mixin TCALL2245a!(int,int);\n\n    mixin TCALL2245b!(0);\n    mixin TCALL2245b!(1);\n    mixin TCALL2245b!(2);\n}\n\nvoid test2245()\n{\n    auto c = new C2245;\n    assert(c.makecall() == 0);\n    assert(c.makecall(0) == 1);\n    assert(c.makecall(0,1) == 2);\n\n    assert(c.makecall2() == 0);\n    assert(c.makecall2(0) == 1);\n    assert(c.makecall2(0,1) == 2);\n\n    assert(c.makecall2!()() == 0);\n    assert(c.makecall2!(int)(0) == 1);\n    assert(c.makecall2!(int, int)(0,1) == 2);\n\n    auto s = S2245();\n    assert(s.makecall() == 0);\n    assert(s.makecall(0) == 1);\n    assert(s.makecall(0,1) == 2);\n\n    assert(s.makecall2() == 0);\n    assert(s.makecall2(0) == 1);\n    assert(s.makecall2(0,1) == 2);\n\n    assert(s.makecall2!()() == 0);\n    assert(s.makecall2!(int)(0) == 1);\n    assert(s.makecall2!(int, int)(0,1) == 2);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2481\n\ntemplate M2481() { int i; }\nclass Z2481a { struct { mixin M2481!(); } }\nclass Z2481b { struct { int i; } }\n\nvoid test2481()\n{\n    Z2481a z1;\n    Z2481b z2;\n    static assert(z1.i.offsetof == z2.i.offsetof);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2740\n\ninterface IFooable2740\n{\n    bool foo();\n}\nabstract class CFooable2740\n{\n    bool foo();\n}\n\nmixin template MFoo2740()\n{\n    override bool foo() { return true; }\n}\n\nclass Foo2740i1 : IFooable2740\n{\n    override bool foo() { return false; }\n    mixin MFoo2740;\n}\nclass Foo2740i2 : IFooable2740\n{\n    mixin MFoo2740;\n    override bool foo() { return false; }\n}\n\nclass Foo2740c1 : CFooable2740\n{\n    override bool foo() { return false; }\n    mixin MFoo2740;\n}\nclass Foo2740c2 : CFooable2740\n{\n    mixin MFoo2740;\n    override bool foo() { return false; }\n}\n\nvoid test2740()\n{\n    {\n        auto p = new Foo2740i1();\n        IFooable2740 i = p;\n        assert(p.foo() == false);\n        assert(i.foo() == false);\n    }\n    {\n        auto p = new Foo2740i2();\n        IFooable2740 i = p;\n        assert(p.foo() == false);\n        assert(i.foo() == false);\n    }\n\n    {\n        auto p = new Foo2740c1();\n        CFooable2740 i = p;\n        assert(p.foo() == false);\n        assert(i.foo() == false);\n    }\n    {\n        auto p = new Foo2740c2();\n        CFooable2740 i = p;\n        assert(p.foo() == false);\n        assert(i.foo() == false);\n    }\n}\n\n/*******************************************/\n\nmixin template MTestFoo()\n{\n    int foo(){ return 2; }\n}\nclass TestFoo\n{\n    mixin MTestFoo!() test;\n    int foo(){ return 1; }\n}\nvoid test42()\n{\n    auto p = new TestFoo();\n    assert(p.foo() == 1);\n    assert(p.test.foo() == 2);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7744\n\nclass ZeroOrMore7744(Expr)\n{\n    enum name = \"ZeroOrMore7744!(\"~Expr.name~\")\";\n}\nclass Range7744(char begin, char end)\n{\n    enum name = \"Range7744!(\"~begin~\",\"~end~\")\";\n}\n\nmixin(q{\n    class RubySource7744 : ZeroOrMore7744!(DecLiteral7744)\n    {\n    }\n    class DecLiteral7744 : Range7744!('0','9')\n    {\n    }\n});\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8032\n\nmixin template T8032()\n{\n    void f() { }\n}\n\nclass A8032a\n{\n    mixin T8032; // Named mixin causes the error too\n    void f() { }\n}\nclass B8032a : A8032a\n{\n    override void f() { }\n}\n\nclass A8032b\n{\n    void f() { }\n    mixin T8032; // Named mixin causes the error too\n}\nclass B8032b : A8032b\n{\n    override void f() { }\n}\n\n/*********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9417\n\nmixin template Foo9417()\n{\n    void foo() {}\n}\n\nvoid test9417()\n{\n    struct B\n    {\n        mixin Foo9417;\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11487\n\ntemplate X11487()\n{\n    struct R()\n    {\n        C11487 c;\n\n        ~this()\n        {\n            static assert(is(typeof(c.front) == void));\n        }\n    }\n    template Mix(alias R)\n    {\n        R!() range;\n        @property front() inout {}\n    }\n}\n\nclass C11487\n{\n    alias X11487!() M;\n    mixin M.Mix!(M.R);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11767\n\nmixin template M11767()\n{\n    struct S11767 {}\n}\nmixin M11767!();\nmixin M11767!();    // OK\nstatic assert(!__traits(compiles, S11767));\n\nvoid test11767()\n{\n    mixin M11767!();\n    alias S1 = S11767;\n    {\n        mixin M11767!();\n        alias S2 = S11767;\n        static assert(!is(S1 == S2));\n        static assert(S1.mangleof == \"S6mixin19test11767FZ8__mixin16S11767\");\n        static assert(S2.mangleof == \"S6mixin19test11767FZ8__mixin26S11767\");\n    }\n    mixin M11767!();\n    static assert(!__traits(compiles, S11767));\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12023\n\nvoid Delete12023(Object obj) {}\n\ntemplate MessageCode12023()\n{\n    alias typeof(this) C;\n\n    struct MessageDeinitHelper\n    {\n        C m_outer;\n\n        ~this()\n        {\n            m_outer.DoDeinitMessaging();\n        }\n    }\n\n    CToClient toClient = null;\n    TypeTuple!(CToClient) toClients;\n\n    class CToClient {}\n\n    void DoDeinitMessaging()\n    {\n        Delete12023(toClient);\n        Delete12023(toClients);\n    }\n}\n\nclass TurretCannon12023(ProjectileClass)\n{\n    mixin MessageCode12023;\n}\n\nvoid test12023()\n{\n    auto tc = new TurretCannon12023!Object();\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14243\n\nmixin template Mix14243a(int n)\n{\n    static assert(n > 0);\n    import core.stdc.stdio;\n    enum { enumMember = 1 }\n\n    auto a = A14243(n);\n}\n\nmixin template Mix14243b(int n)\n{\n    static if (n > 0)\n    {\n        auto b = A14243(n);\n    }\n}\n\ntemplate foo14243(alias v) { auto bar() { return &v; } }\nmixin template Mix14243c(alias v)\n{\n    // instantiate template in TemplateMixin\n    auto c = foo14243!v.bar();\n}\n\nmixin template Mix14243d(int n)\n{\n    // Type declaration in TemplateMixin\n    struct NS { int x = n; }\n    mixin(\"auto d\" ~ ('0' + n) ~ \" = NS();\");\n}\n\nmixin template Mix14243e(int n)\n{\n@safe:\nnothrow:\n    int foo() { return var; }\n\nstatic:\n    struct S { int x; void f() {} }\n    int bar() { return n; }\n}\n\nint test14243()\n{\n    int[] ctor;\n    int[] dtor;\n    struct A14243\n    {\n        int x;\n        this(int x) { ctor ~= x; this.x = x; }\n        ~this()     { dtor ~= x; }\n    }\n\n    {\n        /**/\n        assert(ctor == [] && dtor == []);         mixin Mix14243a!(1);\n        assert(ctor == [1] && dtor == []);        mixin Mix14243b!(12) b1;\n        assert(ctor == [1,12] && dtor == []);     mixin Mix14243b!(24) b2;\n        assert(ctor == [1,12,24] && dtor == []);\n        assert(a.x == 1);\n        static assert(!__traits(compiles, b > 0));  // ambiguous symbol access\n        assert(b1.b.x == 12);\n        assert(b2.b.x == 24);\n\n        int x;\n        mixin Mix14243c!(x);\n        assert(c == &x);\n\n        mixin Mix14243d!(1);\n        mixin Mix14243d!(2);\n        static assert(!is(typeof(d1) == typeof(d2)));\n        assert(d1.x == 1);\n        assert(d2.x == 2);\n\n        assert(ctor == [1,12,24] && dtor == []);\n    }\n    assert(ctor == [1,12,24] && dtor == [24,12,1]);\n\n    {\n        int var = 1;\n        mixin Mix14243e!12;\n        static assert(is(typeof(&foo) == int delegate() @safe nothrow pure @nogc));\n        static assert(is(typeof(&bar) == int function() @safe nothrow pure @nogc));\n        static assert(S.sizeof == int.sizeof);  // s is static struct\n        assert(foo() == 1);\n        assert(bar() == 12);\n    }\n    return 1;\n}\nstatic assert(test14243()); // changed to be workable\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10492\n\nclass TestClass10492 {}\n\nmixin template mix10492(string name)\n{\n    mixin(\"scope \" ~ name ~ \" = new TestClass10492;\" );\n}\n\nvoid test10492()\n{\n    mixin mix10492!(\"var\");\n}\n\n/*******************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test2245();\n    test2740();\n    test42();\n    test9417();\n    test11767();\n    test12023();\n    test14243();\n    test10492();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/mixin2.d",
    "content": "import std.stdio;\n\n/*********************************************/\n\nint foo(int x)\n{\n    return mixin(\"x + 1\"w);\n}\n\nvoid test1()\n{\n    assert(foo(3) == 4);\n}\n\n/*********************************************/\n\nvoid test2()\n{\n    int j;\n    mixin(\"\n        int x = 3;\n        for (int i = 0; i < 10; i++)\n            writeln(x + i, ++j);\n        \");\n    assert(j == 10);\n}\n\n/*********************************************/\n\nmixin(\"int abc3 = 5;\");\n\nvoid test3()\n{\n    writeln(abc3);\n    assert(abc3 == 5);\n}\n\n/*********************************************/\n\nmixin(\"\nvoid test4()\n{\n    writeln(\\\"test4\\\");\n\" ~ \"}\");\n\n/*********************************************/\n\nint x5;\n\nscope class Foo5\n{\n        this ()\n        {\n                writeln (\"Constructor\");\n                assert(x5 == 0);\n                x5++;\n        }\n        ~this ()\n        {\n                writeln (\"Destructor\");\n                assert(x5 == 2);\n                x5++;\n        }\n}\n\nvoid test5()\n{\n    {\n        mixin (\"scope Foo5 f = new Foo5;\\n\");\n        writeln (\"  Inside Scope\");\n        assert(x5 == 1);\n        x5++;\n    }\n    assert(x5 == 3);\n}\n\n/*********************************************/\n\nvoid test6()\n{\n    static const b = \"printf(`hey\\n`);\";\n\n    if (true)\n        mixin(b);\n}\n\n/*********************************************/\n\ntemplate Foo7(alias f)\n{\n}\n\nclass Bar7\n{\n        mixin Foo7!( function {} );\n}\n\nvoid test7()\n{\n}\n\n/*********************************************/\n\ntemplate TupleDecls(T, R ...) {\n    T value;\n    static if (R.length)\n        mixin TupleDecls!(R) Inner;\n}\n\nstruct TupleStruct(T ...) { mixin TupleDecls!(T); }\n\nvoid test8() {\n    alias TupleStruct!(char[], char[]) twoStrings;\n}\n\n/*********************************************/\n\ntemplate Magic()\n{\n    void* magic = null;\n}\n\nstruct Item\n{\n    mixin Magic A;\n}\n\nstruct Foo9(alias S)\n{\n}\n\nvoid test9()\n{\n    Foo9!(Item.A) bar;\n}\n\n/*********************************************/\n\npragma(msg, \"hello\");\npragma(msg, ['h', 'e', 'l', 'l', 'o']);\npragma(msg, \"\");\npragma(msg, []);\npragma(msg, null);\nmixin(\"string hello;\");\nmixin(['i', 'n', 't', ' ', 't', 'e', 's', 't', '1', '0', 'x', ';']);\nmixin(\"\");\nmixin([]);\nmixin(null);\nvoid test10()\n{\n    pragma(msg, \"hello\");\n    pragma(msg, ['h', 'e', 'l', 'l', 'o']);\n    pragma(msg, \"\");\n    pragma(msg, []);\n    pragma(msg, null);\n    mixin(\"string hello;\");\n    mixin(['i', 'n', 't', ' ', 'a', ';']);\n    mixin(\"\");\n    mixin([]);\n    mixin(null);\n}\n\n/*********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7560\n\nclass Base7560\n{\n    template getter(T)\n    {\n        void get(ref T[] i, uint n) {}\n    }\n    mixin getter!uint;\n    mixin getter!char;\n}\n\nclass Derived7560 : Base7560\n{\n    alias Base7560.get get;\n    void get(ref char[] x) {}\n}\n\n/*********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10577\n\nenum sync10577;\n\npublic template get_sync10577(size_t I, A...)\n{\n    static if (I == A.length)               enum bool get_sync10577 = false;\n    else static if (is(A[I] == sync10577))  enum bool get_sync10577 = true;\n    else                                    enum bool get_sync10577 = get_sync!10577(I+1, A);\n}\n\ntemplate add_sync10577(T, size_t ITER=0)\n{\n    static if (ITER == (__traits(derivedMembers, T).length))\n    {\n        enum string add_sync10577 = \"\";\n    }\n    else\n    {\n        enum string mem = __traits(derivedMembers, T)[ITER];\n        enum string add_sync10577 =\n            \"static if (! __traits(isVirtualMethod, \" ~ mem ~ \")) {\" ~\n            \"mixin(add_sync10577!(get_sync10577!(0, __traits(getAttributes, \"\n            ~ mem ~ \")), \\\"\" ~ mem ~ \"\\\"));} \" ~ add_sync10577!(T, ITER+1);\n    }\n}\n\ntemplate add_sync10577(bool A, string M)\n{\n    static if (A)\n    {\n        enum string add_sync10577 = \" auto \" ~ M[1..$] ~\n            \"() { synchronized(this) return \" ~ M ~ \"; }\";\n    }\n    else\n    {\n        enum string add_sync10577 = \"\";\n    }\n}\n\nclass base10577\n{\n    public void foo() {}\n}\n\nclass derived10577 : base10577\n{\n    mixin(add_sync10577!(derived10577));\n    @sync10577 private bool _bar;\n\n    public override void foo() {}\n}\n\n/*********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10583\n\nenum sync10583;\n\npublic template get_sync10583(size_t I, A...)\n{\n    static if (I == A.length)\n        enum bool get_sync10583 = false;\n    else static if (is(A[I] == sync10583))\n        enum bool get_sync10583 = true;\n    else\n        enum bool get_sync10583 = get_sync10583!(I+1, A);\n}\n\ntemplate add_sync10583(T, size_t ITER = 0)\n{\n    static if (ITER == (__traits(derivedMembers, T).length))\n    {\n        enum string add_sync10583 = \"\";\n    }\n    else\n    {\n        enum string mem = __traits(derivedMembers, T)[ITER];\n        enum string add_sync10583 =\n            \"mixin(add_sync10583!(get_sync10583!(0, __traits(getAttributes, \"\n            ~ mem ~ \")), __traits(getProtection, \"\n            ~ mem ~ \"), \\\"\" ~ mem ~ \"\\\"));\\n\" ~ add_sync10583!(T, ITER+1);\n    }\n}\n\ntemplate add_sync10583(bool A, string P, string M)\n{\n    static if (A)\n    {\n        enum string add_sync10583 = \" auto \" ~ M[1..$] ~\n            \"() { synchronized(this) return \" ~ M ~ \"; }\";\n    }\n    else\n        enum string add_sync10583 = \"\";\n}\n\nclass derived10583\n{\n    mixin(add_sync10583!(derived10583));\n    @sync10583 private bool _bar;\n    void frop() {}\n}\n\n/*********************************************/\n\nstring rep(string s, int n)\n{\n    return n > 1 ? s ~ rep(s, n-1) : s;\n}\n\nvoid test7156()\n{\n    int i;\n    mixin(rep(\"++i;\", 200));\n}\n\n/*********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7553\n\ntemplate Foo7553()\n{\n    struct Range7553 {}\n}\ntemplate Biz7553()\n{\n    struct Range7553 {}\n}\n\nclass Bar7553\n{\n    mixin Foo7553!() index0;\n    mixin Biz7553!() index1;\n\n    auto to_range(Range)(Range r)\n    {\n        return r;\n    }\n\n}\n\nvoid test7553()\n{\n    auto r2 = new Bar7553().to_range(1);\n}\n\n/*********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13479\n\nmixin template F13479()\n{\n    void t()()\n    {\n    }\n\n    alias t!() a;\n}\n\nvoid test13479()\n{\n    mixin F13479!();\n    a();\n}\n\n/*********************************************/\n\nvoid main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test7156();\n    test13479();\n\n    writeln(\"Success\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/mod1.d",
    "content": "// PERMUTE_ARGS:\n// EXTRA_SOURCES: imports/mod2.d\n\n// mod1.d\n\nimport imports.mod2;\n\nstring name()\n{\n  return \"EvilOne\";\n}\n\nint main(string[] args)\n{\n  greet();\n  return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/nan.d",
    "content": "import core.stdc.stdio;\n\nenum real er1 = real.nan;\nenum real er2 = 1;\nstatic assert(er1 != er2);\nstatic assert(!(er1 == er2));\nstatic assert(!(er1 < er2));\nstatic assert(!(er1 > er2));\nstatic assert(!(er1 >= er2));\nstatic assert(!(er1 <= er2));\n\nenum double ed1 = real.nan;\nenum double ed2 = 1;\nstatic assert(ed1 != ed2);\nstatic assert(!(ed1 == ed2));\nstatic assert(!(ed1 < ed2));\nstatic assert(!(ed1 > ed2));\nstatic assert(!(ed1 >= ed2));\nstatic assert(!(ed1 <= ed2));\n\nbool b;\n\nbool test()\n{\n        real r1 = real.nan;\n        real r2 = 1;\n        b = (r1 != r2); assert(b);\n        b = (r1 == r2); assert(!b);\n        b = (r1 <  r2); assert(!b);\n        b = (r1 >  r2); assert(!b);\n        b = (r1 <= r2); assert(!b);\n        b = (r1 >= r2); assert(!b);\n\n        double d1 = double.nan;\n        double d2 = 1;\n        b = (d1 != d2); assert(b);\n        b = (d1 == d2); assert(!b);\n        b = (d1 <  d2); assert(!b);\n        b = (d1 >  d2); assert(!b);\n        b = (d1 <= d2); assert(!b);\n        b = (d1 >= d2); assert(!b);\n\n        float f1 = float.nan;\n        float f2 = 1;\n        b = (f1 != f2); assert(b);\n        b = (f1 == f2); assert(!b);\n        b = (f1 <  f2); assert(!b);\n        b = (f1 >  f2); assert(!b);\n        b = (f1 <= f2); assert(!b);\n        b = (f1 >= f2); assert(!b);\n        return true;\n}\n\nvoid main()\n{\n        assert(test());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/nested.d",
    "content": "// REQUIRED_ARGS:\n\nimport core.stdc.stdio;\n\n/*******************************************/\n\nint bar(int a)\n{\n    int foo(int b) { return b + 1; }\n\n    return foo(a);\n}\n\nvoid test1()\n{\n    assert(bar(3) == 4);\n}\n\n/*******************************************/\n\nint bar2(int a)\n{\n    static int c = 4;\n\n    int foo(int b) { return b + c + 1; }\n\n    return foo(a);\n}\n\nvoid test2()\n{\n    assert(bar2(3) == 8);\n}\n\n\n/*******************************************/\n\nint bar3(int a)\n{\n    static int foo(int b) { return b + 1; }\n\n    return foo(a);\n}\n\nvoid test3()\n{\n    assert(bar3(3) == 4);\n}\n\n/*******************************************/\n\nint bar4(int a)\n{\n    static int c = 4;\n\n    static int foo(int b) { return b + c + 1; }\n\n    return foo(a);\n}\n\nvoid test4()\n{\n    assert(bar4(3) == 8);\n}\n\n\n/*******************************************/\n\nint bar5(int a)\n{\n    int c = 4;\n\n    int foo(int b) { return b + c + 1; }\n\n    return c + foo(a);\n}\n\nvoid test5()\n{\n    assert(bar5(3) == 12);\n}\n\n\n/*******************************************/\n\nint bar6(int a)\n{\n    int c = 4;\n\n    int foob(int b) { return b + c + 1; }\n    int fooa(int b) { return foob(c + b) * 7; }\n\n    return fooa(a);\n}\n\nvoid test6()\n{\n    assert(bar6(3) == 84);\n}\n\n\n/*******************************************/\n\nint bar7(int a)\n{\n    static int c = 4;\n\n    static int foob(int b) { return b + c + 1; }\n\n    int function(int) fp = &foob;\n\n    return fp(a);\n}\n\nvoid test7()\n{\n    assert(bar7(3) == 8);\n}\n\n/*******************************************/\n\nint bar8(int a)\n{\n    int c = 4;\n\n    int foob(int b) { return b + c + 1; }\n\n    int delegate(int) fp = &foob;\n\n    return fp(a);\n}\n\nvoid test8()\n{\n    assert(bar8(3) == 8);\n}\n\n\n/*******************************************/\n\nstruct Abc9\n{\n    int a;\n    int b;\n    int c = 7;\n\n    int bar(int x)\n    {\n        Abc9 *foo() { return &this; }\n\n        Abc9 *p = foo();\n        assert(p == &this);\n        return p.c + x;\n    }\n}\n\nvoid test9()\n{\n    Abc9 x;\n\n    assert(x.bar(3) == 10);\n}\n\n/*******************************************/\n\nclass Abc10\n{\n    int a;\n    int b;\n    int c = 7;\n\n    int bar(int x)\n    {\n        Abc10 foo() { return this; }\n\n        Abc10 p = foo();\n        assert(p == this);\n        return p.c + x;\n    }\n\n}\n\nvoid test10()\n{\n    Abc10 x = new Abc10();\n\n    assert(x.bar(3) == 10);\n}\n\n\n/*******************************************/\n\nclass Collection\n{\n    int[3] array;\n\n    void opApply(void delegate(int) fp)\n    {\n        for (int i = 0; i < array.length; i++)\n            fp(array[i]);\n    }\n}\n\nint func11(Collection c)\n{\n    int max = int.min;\n\n    void comp_max(int i)\n    {\n        if (i > max)\n            max = i;\n    }\n\n    c.opApply(&comp_max);\n    return max;\n}\n\nvoid test11()\n{\n    Collection c = new Collection();\n\n    c.array[0] = 7;\n    c.array[1] = 26;\n    c.array[2] = 25;\n\n    int m = func11(c);\n    assert(m == 26);\n}\n\n\n/*******************************************/\n\nvoid SimpleNestedFunction ()\n{\n    int nest () { return 432; }\n\n    assert (nest () == 432);\n    int delegate () func = &nest;\n    assert (func () == 432);\n}\n\nvoid AccessParentScope ()\n{\n    int value = 9;\n\n    int nest () { assert (value == 9); return 9; }\n\n    assert (nest () == 9);\n}\n\nvoid CrossNestedScope ()\n{\n    int x = 45;\n\n    void foo () { assert (x == 45); }\n    void bar () { int z = 16; foo (); }\n    bar ();\n}\n\nvoid BadMultipleNested ()\n{\n    int x;\n\n    void foo ()\n    {\n       void bar ()\n       {\n           //erroneous x = 4; // Should fail.\n       }\n    }\n}\n\n/* This one kind of depends upon memory layout.  GlobalScopeSpoof should\nbe called with no \"this\" pointer; this is trying to ensure that\neverything is working properly.  Of course, in the DMD calling\nconvention it'll fail if the caller passes too much/little data. */\n\nvoid GlobalScopeSpoof (int x, int y)\n{\n    assert (x == y && y == 487);\n}\n\nvoid GlobalScope ()\n{\n    void bar () { GlobalScopeSpoof (487, 487); }\n    bar ();\n}\n\nclass TestClass\n{\n    int x = 6400;\n\n    void foo ()\n    {\n       void bar () { assert (x == 6400); }\n       bar ();\n    }\n}\n\nvoid test12()\n{\n    SimpleNestedFunction ();\n    AccessParentScope ();\n    CrossNestedScope ();\n    GlobalScope ();\n    (new TestClass).foo ();\n}\n\n\n/*******************************************/\n\nvoid test13()\n{\n    struct Abc\n    {\n        int x = 3;\n        int y = 4;\n    }\n\n    Abc a;\n\n    assert(a.x == 3 && a.y == 4);\n}\n\n\n/*******************************************/\n\nvoid test14()\n{\n    struct Abc\n    {\n        int x = 3;\n        int y = 4;\n\n        int foo() { return y; }\n    }\n\n    Abc a;\n\n    assert(a.foo() == 4);\n}\n\n\n/*******************************************/\n\nvoid test15()\n{\n    static int z = 5;\n\n    struct Abc\n    {\n        int x = 3;\n        int y = 4;\n\n        int foo() { return y + z; }\n    }\n\n    Abc a;\n\n    assert(a.foo() == 9);\n}\n\n\n/*******************************************/\n\nvoid test16()\n{\n    static int z = 5;\n\n    static class Abc\n    {\n        int x = 3;\n        int y = 4;\n\n        int foo() { return y + z; }\n    }\n\n    Abc a = new Abc();\n\n    assert(a.foo() == 9);\n}\n\n\n/*******************************************/\n\nvoid test17()\n{\n    int function(int x) fp;\n\n    fp = function int(int y) { return y + 3; };\n    assert(fp(7) == 10);\n}\n\n/*******************************************/\n\nvoid test18()\n{\n    static int a = 3;\n    int function(int x) fp;\n\n    fp = function int(int y) { return y + a; };\n    assert(fp(7) == 10);\n}\n\n/*******************************************/\n\nvoid test19()\n{\n    int a = 3;\n\n    int delegate(int x) fp;\n\n    fp = delegate int(int y) { return y + a; };\n    assert(fp(7) == 10);\n}\n\n\n/*******************************************/\n\nclass Collection20\n{\n    int[3] array;\n\n    void opApply(void delegate(int) fp)\n    {\n        for (int i = 0; i < array.length; i++)\n            fp(array[i]);\n    }\n}\n\nint func20(Collection20 c)\n{\n    int max = int.min;\n\n    c.opApply(delegate(int i) { if (i > max) max = i; });\n    return max;\n}\n\nvoid test20()\n{\n    Collection20 c = new Collection20();\n\n    c.array[0] = 7;\n    c.array[1] = 26;\n    c.array[2] = 25;\n\n    int m = func20(c);\n    assert(m == 26);\n}\n\n\n/*******************************************/\n\nint bar21(int a)\n{\n    int c = 3;\n\n    int foo(int b)\n    {\n        b += c;         // 4 is added to b\n        c++;            // bar.c is now 5\n        return b + c;   // 12 is returned\n    }\n    c = 4;\n    int i = foo(a);     // i is set to 12\n    return i + c;       // returns 17\n}\n\nvoid test21()\n{\n    int i = bar21(3);   // i is assigned 17\n    assert(i == 17);\n}\n\n/*******************************************/\n\nvoid foo22(void delegate() baz)\n{\n  baz();\n}\n\nvoid bar22(int i)\n{\n  int j = 14;\n  printf(\"%d,%d\\n\",i,j);\n\n  void fred()\n  {\n    printf(\"%d,%d\\n\",i,j);\n    assert(i == 12 && j == 14);\n  }\n\n  fred();\n  foo22(&fred);\n}\n\nvoid test22()\n{\n  bar22(12);\n}\n\n\n/*******************************************/\n\nvoid frelled(void delegate() baz)\n{\n  baz();\n}\n\nclass Foo23\n{\n  void bar(int i)\n  {\n    int j = 14;\n    printf(\"%d,%d\\n\",i,j);\n\n    void fred()\n    {\n        printf(\"%d,%d\\n\",i,j);\n        assert(i == 12);\n        assert(j == 14);\n    }\n\n    frelled(&fred);\n  }\n}\n\nvoid test23()\n{\n    Foo23 f = new Foo23();\n\n    f.bar(12);\n}\n\n\n/*******************************************/\n\nvoid delegate () function (int x) store24;\n\nvoid delegate () zoom24(int x)\n{\n   return delegate void () { };\n}\n\nvoid test24()\n{\n   store24 = &zoom24;\n   store24 (1) ();\n}\n\n\n/*******************************************/\n\nvoid test25()\n{\n    delegate() { printf(\"stop the insanity!\\n\"); }();\n    delegate() { printf(\"stop the insanity! 2\\n\"); }();\n}\n\n/*******************************************/\n\nalias bool delegate(int) callback26;\n\n\nbool foo26(callback26 a)\n{\n    return a(12);\n}\n\nclass Bar26\n{\n    int func(int v)\n    {\n        printf(\"func(v=%d)\\n\", v);\n        foo26(delegate bool(int a)\n        {\n            printf(\"%d %d\\n\",a,v); return true;\n            assert(a == 12);\n            assert(v == 15);\n            assert(0);\n        } );\n        return v;\n    }\n}\n\n\nvoid test26()\n{\n    Bar26 b = new Bar26();\n\n    b.func(15);\n}\n\n\n/*******************************************/\n\nclass A27\n{\n    uint myFunc()\n    {\n        uint myInt = 13;\n        uint mySubFunc()\n        {\n            return myInt;\n        }\n        return mySubFunc();\n    }\n}\n\nvoid test27()\n{\n    A27 myInstance = new A27;\n    int i = myInstance.myFunc();\n    printf(\"%d\\n\", i);\n    assert(i == 13);\n}\n\n\n/*******************************************/\n\nvoid Foo28(void delegate() call)\n{\n    call();\n}\n\nclass Bar28\n{\n    int func()\n    {\n        int count = 0;\n\n        Foo28(delegate void() { ++count; } );\n        return count;\n    }\n}\n\nvoid test28()\n{\n    Bar28 b = new Bar28();\n    int i = b.func();\n    assert(i == 1);\n}\n\n\n/*******************************************/\n\nclass Foo29\n{\n  void Func(void delegate() call)\n  {\n    for(int i = 0; i < 10; ++i)\n      call();\n  }\n}\n\nclass Bar29\n{\n    int Func()\n    {\n        int count = 0;\n        Foo29 ic = new Foo29();\n\n        ic.Func(delegate void() { ++count; } );\n        return count;\n    }\n}\n\nvoid test29()\n{\n    Bar29 b = new Bar29();\n    int i = b.Func();\n    assert(i == 10);\n}\n\n/*******************************************/\n\nstruct Foo30\n{\n  int[] arr;\n}\n\nvoid Func30(Foo30 bar)\n{\n    void InnerFunc(int x, int y)\n    {\n        int a = bar.arr[y]; // Ok\n\n        if(bar.arr[y]) // Access violation\n        {\n        }\n    }\n\n    InnerFunc(5,5);\n}\n\n\nvoid test30()\n{\n  Foo30 abc;\n\n  abc.arr.length = 10;\n  Func30(abc);\n}\n\n\n/*******************************************/\n\nvoid call31(int d, void delegate(int d) f)\n{\n    assert(d == 100 || d == 200);\n    printf(\"d = %d\\n\", d);\n    f(d);\n}\n\nvoid test31()\n{\n    call31(100, delegate void(int d1)\n    {\n        printf(\"d1 = %d\\n\", d1);\n        assert(d1 == 100);\n        call31(200, delegate void(int d2)\n        {\n            printf(\"d1 = %d\\n\", d1);\n            printf(\"d2 = %d\\n\", d2);\n            assert(d1 == 100);\n            assert(d2 == 200);\n        });\n    });\n}\n\n\n/*******************************************/\n\nvoid call32(int d, void delegate(int d) f)\n{\n    assert(d == 100 || d == 200);\n    printf(\"d = %d\\n\", d);\n    f(d);\n}\n\nvoid test32()\n{\n    call32(100, delegate void(int d1)\n    {\n        int a = 3;\n        int b = 4;\n        printf(\"d1 = %d, a = %d, b = %d\\n\", d1, a, b);\n        assert(a == 3);\n        assert(b == 4);\n        assert(d1 == 100);\n\n        call32(200, delegate void(int d2)\n        {\n            printf(\"d1 = %d, a = %d\\n\", d1, a);\n            printf(\"d2 = %d, b = %d\\n\", d2, b);\n            assert(a == 3);\n            assert(b == 4);\n            assert(d1 == 100);\n            assert(d2 == 200);\n        });\n    });\n}\n\n\n/*******************************************/\n\nvoid test33()\n{\n    extern (C) int Foo1(int a, int b, int c)\n    {\n        assert(a == 1);\n        assert(b == 2);\n        assert(c == 3);\n        return 1;\n    }\n\n    extern (D) int Foo2(int a, int b, int c)\n    {\n        assert(a == 1);\n        assert(b == 2);\n        assert(c == 3);\n        return 2;\n    }\n\n    extern (Windows) int Foo3(int a, int b, int c)\n    {\n        assert(a == 1);\n        assert(b == 2);\n        assert(c == 3);\n        return 3;\n    }\n\n    extern (Pascal) int Foo4(int a, int b, int c)\n    {\n        assert(a == 1);\n        assert(b == 2);\n        assert(c == 3);\n        return 4;\n    }\n\n    assert(Foo1(1, 2, 3) == 1);\n    assert(Foo2(1, 2, 3) == 2);\n    assert(Foo3(1, 2, 3) == 3);\n    assert(Foo4(1, 2, 3) == 4);\n\n    printf(\"test33 success\\n\");\n}\n\n/*******************************************/\n\nclass Foo34\n{\n    int x;\n\n    class Bar\n    {\n        int y;\n\n        int delegate() getDelegate()\n        {\n            assert(y == 8);\n            auto i = sayHello();\n            assert(i == 23);\n            return &sayHello;\n        }\n    }\n    Bar bar;\n\n    int sayHello()\n    {\n        printf(\"Hello\\n\");\n        assert(x == 47);\n        return 23;\n    }\n\n    this()\n    {\n        x = 47;\n        bar = new Bar();\n        bar.y = 8;\n    }\n}\n\nvoid test34()\n{\n    Foo34 foo = new Foo34();\n    int delegate() saydg = foo.bar.getDelegate();\n    printf(\"This should print Hello:\\n\");\n    auto i = saydg();\n    assert(i == 23);\n}\n\n/*******************************************/\n\nclass Foo35\n{\n    int x = 42;\n    void bar()\n    {\n        int y = 43;\n        new class Object\n        {\n            this()\n            {\n                //writefln(\"x = %s\", x);\n                //writefln(\"y = %s\", y);\n                assert(x == 42);\n                assert(y == 43);\n              //static assert(is(typeof(this.outer) == void*)); // https://issues.dlang.org/show_bug.cgi?id=14442\n                static assert(is(typeof(this.outer) == Foo35)); // https://issues.dlang.org/show_bug.cgi?id=15839\n            }\n        };\n    }\n}\n\nvoid test35()\n{\n    Foo35 f = new Foo35();\n    f.bar();\n}\n\n/*******************************************/\n\nclass Foo36\n{\n    int x = 42;\n    this()\n    {\n        int y = 43;\n        new class Object\n        {\n            this()\n            {\n                //writefln(\"x = %s\", x);\n                //writefln(\"y = %s\", y);\n                assert(x == 42);\n                assert(y == 43);\n            }\n        };\n    }\n}\n\nvoid test36()\n{\n    Foo36 f = new Foo36();\n}\n\n/*******************************************/\n\nclass Foo37\n{\n    int x = 42;\n    void bar()\n    {\n        int y = 43;\n        void abc()\n        {\n            new class Object\n            {\n                this()\n                {\n                    //writefln(\"x = %s\", x);\n                    //writefln(\"y = %s\", y);\n                    assert(x == 42);\n                    assert(y == 43);\n                }\n            };\n        }\n\n        abc();\n    }\n}\n\nvoid test37()\n{\n    Foo37 f = new Foo37();\n    f.bar();\n}\n\n/*******************************************/\n\nvoid test38()\n{\n    int status = 3;\n\n    int delegate() foo()\n    {\n        class C\n        {\n            int dg()\n            {\n                return ++status;\n            }\n        }\n\n        C c = new C();\n\n        return &c.dg;\n    }\n\n    int delegate() bar = foo();\n\n    if(status != 3)\n    {\n        assert(0);\n    }\n\n    if(bar() != 4)\n    {\n        assert(0);\n    }\n\n    if(status != 4)\n    {\n        assert(0);\n    }\n}\n\n/*******************************************/\n\nvoid test39()\n{\n    int status;\n\n    int delegate() foo()\n    {\n        return &(new class\n            {\n                int dg()\n                {\n                    return ++status;\n                }\n            }\n        ).dg;\n    }\n\n    int delegate() bar = foo();\n\n    if(status != 0)\n    {\n        assert(0);\n    }\n\n    if(bar() != 1)\n    {\n        assert(0);\n    }\n\n    if(status != 1)\n    {\n        assert(0);\n    }\n}\n\n/*******************************************/\n\ninterface I40\n{\n    void get( string s );\n}\n\nclass C40\n{\n    int a = 4;\n\n    void init()\n    {\n        I40 i = new class() I40\n        {\n            void get( string s )\n            {\n                func();\n            }\n        };\n        i.get(\"hello\");\n    }\n    void func( ){ assert(a == 4); }\n}\n\nvoid test40()\n{\n    C40 c = new C40();\n    c.init();\n}\n\n/*******************************************/\n\nclass C41\n{   int a = 3;\n\n    void init()\n    {\n        class N\n        {\n            void get()\n            {\n                func();\n            }\n        }\n        N n = new N();\n        n.get();\n    }\n    void func()\n    {\n        assert(a == 3);\n    }\n}\n\n\nvoid test41()\n{\n   C41 c = new C41();\n   c.init();\n}\n\n/*******************************************/\n\nclass C42\n{   int a = 3;\n\n    void init()\n    {\n        class N\n        {\n            void init()\n            {\n                class M\n                {\n                    void get()\n                    {\n                        func();\n                    }\n                }\n                M m = new M();\n                m.get();\n            }\n        }\n        N n = new N();\n        n.init();\n    }\n    void func()\n    {\n        assert(a == 3);\n    }\n}\n\nvoid test42()\n{\n   C42 c = new C42();\n   c.init();\n}\n\n\n/*******************************************/\n\nint foo43(alias X)() { return X; }\n\nvoid test43()\n{\n    int x = 3;\n\n    void bar()\n    {\n        int y = 4;\n        assert(foo43!(x)() == 3);\n        assert(foo43!(y)() == 4);\n    }\n\n    bar();\n\n    assert(foo43!(x)() == 3);\n}\n\n\n/*******************************************/\n\nclass Comb\n{\n}\n\nComb Foo44(Comb delegate()[] c...)\n{\n    Comb ec = c[0]();\n    printf(\"1ec = %p\\n\", ec);\n    ec.toString();\n    printf(\"2ec = %p\\n\", ec);\n    return ec;\n}\n\nComb c44;\n\nstatic this()\n{\n    c44 = new Comb;\n}\n\nvoid test44()\n{\n    c44 = Foo44(Foo44(c44));\n}\n\n/*******************************************/\n\nclass Bar45\n{\n    void test()\n    {\n        a = 4;\n        Inner i = new Inner;\n        i.foo();\n    }\n\n    class Inner\n    {\n        void foo()\n        {\n            assert(a == 4);\n            Inner i = new Inner;\n            i.bar();\n        }\n\n        void bar()\n        {\n            assert(a == 4);\n        }\n    }\n    int a;\n}\n\nvoid test45()\n{\n    Bar45 b = new Bar45;\n    assert(b.a == 0);\n    b.test();\n}\n\n/*******************************************/\n\nclass Adapter\n{\n    int a = 2;\n\n    int func()\n    {\n        return 73;\n    }\n}\n\nclass Foo46\n{\n    int b = 7;\n\n    class AnonAdapter : Adapter\n    {\n        int aa = 8;\n\n        this()\n        {\n            assert(b == 7);\n            assert(aa == 8);\n        }\n    }\n\n    void func()\n    {\n        Adapter a = cast( Adapter )( new AnonAdapter() );\n        assert(a.func() == 73);\n        assert(a.a == 2);\n    }\n}\n\nvoid test46()\n{\n    Foo46 f = new Foo46();\n    f.func();\n}\n\n\n/*******************************************/\n\nvoid test47()\n{\n    void delegate() test =\n    {\n        struct Foo {int x=3;}\n        Foo f;\n        assert(f.x == 3);\n    };\n    test();\n}\n\n/*******************************************/\n\nstruct Outer48\n{\n    class Inner\n    {\n        this(int i) { b = i; }\n        int b;\n    }\n\n    int a = 6;\n\n    void f()\n    {\n        int nested()\n        {\n            auto x = new Inner(a);\n            return x.b + 1;\n        }\n        int i = nested();\n        assert(i == 7);\n    }\n}\n\n\nvoid test48()\n{\n    Outer48 s;\n    s.f();\n}\n\n/*******************************************/\n\nvoid test49()\n{\n    int j = 10;\n    void mainlocal(int x)\n    {\n        printf(\"mainlocal: j = %d, x = %d\\n\", j, x);\n        assert(j == 10);\n        assert(x == 1);\n    }\n\n    void fun2()\n    {\n        int k = 20;\n        void fun2local(int x)\n        {\n            printf(\"fun2local: k = %d, x = %d\\n\", k, x);\n            assert(j == 10);\n            assert(k == 20);\n            assert(x == 2);\n        }\n\n        void fun1()\n        {\n            mainlocal(1);\n            fun2local(2);\n        }\n\n        fun1();\n    }\n\n    fun2();\n}\n\n/*******************************************/\n\nvoid funa50(alias pred1, alias pred2)()\n{\n    pred1(1);\n    pred2(2);\n}\n\nvoid funb50(alias pred1)()\n{   int k = 20;\n    void funb50local(int x)\n    {\n        printf(\"funb50local: k = %d, x = %d\\n\", k, x);\n        assert(k == 20);\n        assert(x == 2);\n    }\n    funa50!(pred1, funb50local)();\n}\n\nvoid test50()\n{\n    int j = 10;\n    void mainlocal(int x)\n    {\n        printf(\"mainlocal: j = %d, x = %d\\n\", j, x);\n        assert(j == 10);\n        assert(x == 1);\n    }\n    funb50!(mainlocal)();\n}\n\n/*******************************************/\n\nvoid funa51(alias pred1, alias pred2)()\n{\n    pred1(2);\n    pred2(1);\n}\n\nvoid funb51(alias pred1)()\n{   int k = 20;\n    void funb51local(int x)\n    {\n        printf(\"funb51local: k = %d, x = %d\\n\", k, x);\n        assert(k == 20);\n        assert(x == 2);\n    }\n    funa51!(funb51local, pred1)();\n}\n\nvoid test51()\n{\n    int j = 10;\n    void mainlocal(int x)\n    {\n        printf(\"mainlocal: j = %d, x = %d\\n\", j, x);\n        assert(j == 10);\n        assert(x == 1);\n    }\n    funb51!(mainlocal)();\n}\n\n/*******************************************/\n\nC52 c52;\n\nclass C52\n{\n    int index = 7;\n    void test1(){\n        printf( \"this = %p, index = %d\\n\", this, index );\n        assert(index == 7);\n        assert(this == c52);\n    }\n    void test()\n    {\n        class N\n        {\n            void callI()\n            {\n                printf(\"test1\\n\");\n                test1();\n                printf(\"test2\\n\");\n                if (index is -1)\n                {   // Access to the outer-super-field triggers the bug\n                    printf(\"test3\\n\");\n                }\n            }\n        }\n        auto i = new N();\n        i.callI();\n    }\n}\n\nvoid test52()\n{\n    auto c = new C52;\n    printf(\"c = %p\\n\", c);\n    c52 = c;\n    c.test();\n}\n\n/*******************************************/\n\nvoid foo53(int i)\n{\n    struct SS\n    {\n        int x,y;\n        int bar() { return x + i + 1; }\n    }\n    SS s;\n    s.x = 3;\n    assert(s.bar() == 11);\n}\n\nvoid test53()\n{\n    foo53(7);\n}\n\n/*******************************************/\n\nvoid test54()\n{\n    int x = 40;\n    int fun(int i) { return x + i; }\n\n    struct A\n    {\n        int bar(int i) { return fun(i); }\n    }\n\n    A makeA()\n    {\n        // A a; return a;\n        return A();\n    }\n\n    A makeA2()\n    {\n         A a;   return a;\n        //return A();\n    }\n\n    A a = makeA();\n    assert(a.bar(2) == 42);\n\n    A b = makeA2();\n    assert(b.bar(3) == 43);\n\n    auto c = new A;\n    assert(c.bar(4) == 44);\n}\n/*******************************************/\n\nvoid test55()\n{\n    int localvar = 7;\n\n    int inner(int delegate(ref int) dg) {\n        int k = localvar;\n        return 0;\n    }\n\n    int a = localvar * localvar; // This modifies the EAX register\n\n    foreach (entry; &inner)\n    {\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4401\n\nvoid test4401()\n{\n    auto foo() {\n        return 3;\n    }\n\n    auto bar() nothrow pure {\n        return 3;\n    }\n\n    auto baz() @property pure @safe {\n        return 3;\n    }\n\n    auto zoo()() @property pure @safe nothrow {\n        return 3;\n    }\n}\n\n/*******************************************/\n\nalias void delegate() dg_t;\n\nvoid Y(dg_t delegate (dg_t) y)\n{\n    struct F { void delegate(F) f; }\n\n  version (all)\n  { // generates error\n    (dg_t delegate(F) a){return a(F((F b){return y(a(b))();})); }\n    ((F b){return (){return b.f(b);};});\n  }\n  else\n  {\n    auto abc(dg_t delegate(F) a)\n    {\n        return a(F((F b){return y(a(b))();}));\n    }\n\n    abc((F b){return (){return b.f(b);};});\n  }\n}\n\n\nvoid test7428(){\n    dg_t foo(dg_t self)\n    {\n        void bar() { self(); }\n        return &bar;\n    }\n\n    Y(&foo);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4612\n\nstruct S4612a(alias x)\n{\n    void* func() { void* p = &x; return p; }\n}\n\nstruct S4612b(alias x)\n{\n    int i;\n    void* func() { void* p = &x; return p; }\n}\n\nvoid test4612()\n{\n    int a;\n\n    auto sa = S4612a!a();\n    assert(sa.func() == &a);\n\n    auto sb = S4612b!(a)();\n    assert(sb.func() == &a);\n}\n\n/*******************************************/\n\nstruct S4841(alias pred)\n{\n    void unused_func();\n}\n\nvoid abc4841() {\n   int w;\n   S4841!(w) m;\n}\n\nvoid test4841() {\n   abc4841();\n}\n\n/*******************************************/\n\n\nvoid index7199()\n{\n    void find()\n    {\n        bool hay()\n        {\n            return true;\n        }\n    }\n\n    find();\n}\n\nvoid test7199()\n{\n    index7199();\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7965\n\nvoid test7965()\n{\n    int x;\n    static int* px;\n    px = &x;\n\n    printf(\"&x = %p in main()\\n\", &x);\n    struct S1\n    {\n        char y;\n        void boom() {\n            printf(\"&x = %p in S1.boom()\\n\", &x);\n            assert(&x == px);\n            //x = 42; // makes the struct nested\n        }\n    }\n    S1 s1;\n    s1.boom();\n\n    struct S2\n    {\n        this(int n) {\n            printf(\"&x = %p in S2.this()\\n\", &x);\n            assert(&x == px);\n        }\n        char y;\n    }\n    S2 s2 = S2(10);\n}\n\nstruct S7965\n{\n    string str;\n    uint unused1, unused2 = 0;\n}\n\nauto f7965(alias fun)()\n{\n    struct Result\n    {\n        S7965 s;\n        this(S7965 _s) { s = _s; }  // required for the problem\n        void g() { assert(fun(s.str) == \"xa\"); }\n    }\n\n    return Result(S7965(\"a\"));\n}\n\nvoid test7965a()\n{\n    string s = \"x\";\n    f7965!(a => s ~= a)().g();\n    assert(s == \"xa\");\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8188\n\nmixin template Print8188(b...)\n{\n    int doprint()\n    {\n        return b[0] * b[1];\n    }\n}\n\nclass A8188\n{\n    int x, y;\n    mixin Print8188!(x, y);\n}\n\nvoid test8188()\n{\n    auto a = new A8188;\n    a.x = 2;\n    a.y = 5;\n    assert(a.doprint() == 10);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5082\n\nstruct S5082 { float x; }\n\nstruct Map5082a(alias fun)\n{\n    typeof({ return fun(int.init); }()) cache;\n}\n\nstruct Map5082b(alias fun)\n{\n    typeof({ return fun(int.init); }()) cache;\n\n    S5082 front(int i) { return fun(i); }\n}\n\nvoid test5082()\n{\n    auto temp = S5082(1);\n    auto func = (int v){ return temp; };\n    auto map1 = Map5082a!func();\n    auto map2 = Map5082b!func();\n    assert(map2.front(1) == temp);\n}\n\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8194\n\nvoid test8194()\n{\n    int foo;\n    static void bar()\n    {\n        typeof(foo) baz;\n        static assert(is(typeof(baz) == int));\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8339\n\ntemplate map8339a(fun...)\n{\n    auto map8339a(Range)(Range r) {\n        struct Result {\n            this(double[] input) {}\n        }\n        return Result(r);\n    }\n}\ntemplate map8339b(fun...)\n{\n    auto map8339b(Range)(Range r) {\n        struct Result {\n            this(double[] input) { fun[0](input.length); }\n        }\n        return Result(r);\n    }\n}\ntemplate map8339c(fun...)\n{\n    auto map8339c(Range)(Range r) {\n        static struct Result {\n            this(double[] input) {}\n        }\n        return Result(r);\n    }\n}\ntemplate map8339d(fun...)\n{\n    auto map8339d(Range)(Range r) {\n        static struct Result {\n            this(double[] input) { fun[0](input.length); }\n        }\n        return Result(r);\n    }\n}\nvoid copy8339(T)(T x)\n{\n    T xSaved;\n}\nvoid test8339a()\n{\n    double[] x;\n    int n;\n\n    // Result has context pointer, so cannot copy\n    static assert (!is(typeof({ copy8339(map8339a!(a=>a)(x)); })));\n    static assert (!is(typeof({ copy8339(map8339a!(a=>n)(x)); })));\n\n    // same as\n    static assert (!is(typeof({ copy8339(map8339b!(a=>a)(x)); })));\n    static assert (!is(typeof({ copy8339(map8339b!(a=>n)(x)); })));\n\n    // fun is never instantiated\n    copy8339(map8339c!(a=>a)(x));\n    copy8339(map8339c!(a=>n)(x));\n\n    // static nested struct doesn't have contest pointer\n    copy8339(map8339d!(a=>a)(x));\n  //copy8339(map8339d!(a=>n)(x));   // too strict case\n\n}\n\ntemplate filter8339(alias pred)\n{\n    auto filter8339(R)(R r) {\n        struct Result {\n            R range;\n            this(R r) { range = r; }\n            auto front() { return pred(0); }\n        }\n        return Result(r);\n    }\n}\nvoid test8339b()\n{\n    static makefilter() { int n; return filter8339!(a=>n)([]); }\n\n    auto r1 = makefilter();\n    filter8339!(a=>a)(r1);\n}\n\nvoid test8339c()\n{\n    class C(X) { X x; }\n    class C1 { C!C1 x; }\n    alias C!C1 C2;\n\n    struct Pair { C1 t; C2 u; void func(){} }\n    Pair pair;\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8704\n\nvoid check8704(T, int num)()\n{\n    static if (num == 1) T t0;\n    static if (num == 2) T t1 = T();\n    static if (num == 3) T t2 = T(1);\n}\n\nvoid test8704()\n{\n    struct S\n    {\n        int n;\n        void foo(){}\n    }\n\n    static assert(!is(typeof(check8704!(S, 1)())));\n    static assert(!is(typeof(check8704!(S, 2)())));\n    static assert(!is(typeof(check8704!(S, 3)())));\n\n    static assert(!__traits(compiles, check8704!(S, 1)()));\n    static assert(!__traits(compiles, check8704!(S, 2)()));\n    static assert(!__traits(compiles, check8704!(S, 3)()));\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8923\n\nvoid test8923a()\n{\n    int val;\n\n    struct S  // is nested struct\n    {\n        void foo() { val = 1; }  // access to val through the hidden frame pointer\n    }\n    S    s1a;           s1a.foo();\n    S    s1b = S();     s1b.foo();\n    S[1] s2a;           s2a[0].foo();\n    S[1] s2b = S();     s2b[0].foo();\n\n    static struct U { S s; }\n    U    u1a;           u1a.s.foo();\n    U    u1b = U();     u1b.s.foo();\n    U    u1c = U(s1a);  u1c.s.foo();\n    U[1] u2a;           u2a[0].s.foo();\n    U[1] u2b = U();     u2b[0].s.foo();\n    U[1] u2c = U(s1a);  u2c[0].s.foo();\n    static struct V { S[1] s; }\n    V    v1a;           v1a.s[0].foo();\n    V    v1b = V();     v1b.s[0].foo();\n    V    v1c = V(s1a);  v1c.s[0].foo();\n    V[1] v2a;           v2a[0].s[0].foo();\n    V[1] v2b = V();     v2b[0].s[0].foo();\n    V[1] v2c = V(s1a);  v2c[0].s[0].foo();\n\n    static struct W { S s; this(S s){ this.s = s; } }\n    W    w1a;           w1a.s.foo();\n    W    w1b = W();     w1b.s.foo();\n    W    w1c = W(s1a);  w1c.s.foo();\n    W[1] w2a;           w2a[0].s.foo();\n    W[1] w2b = W();     w2b[0].s.foo();\n    W[1] w2c = W(s1a);  w2c[0].s.foo();\n    static struct X { S[1] s; this(S s){ this.s[] = s; } }\n    X    x1a;           x1a.s[0].foo();\n    X    x1b = X();     x1b.s[0].foo();\n    X    x1c = X(s1a);  x1c.s[0].foo();\n    X[1] x2a;           x2a[0].s[0].foo();\n    X[1] x2b = X();     x2b[0].s[0].foo();\n    X[1] x2c = X(s1a);  x2c[0].s[0].foo();\n\n    // Both declarations, Y and Z should raise errors,\n    // because their ctors don't initialize their field 's'.\n  static assert(!__traits(compiles, {\n    static struct Y { S s; this(S){} }\n  }));\n/+  Y    y1a;         //y1a.s.foo();\n    Y    y1b = Y();     y1b.s.foo();\n    Y    y1c = Y(s1a);//y1c.s.foo();\n    Y[1] y2a;         //y2a[0].s.foo();\n    Y[1] y2b = Y();     y2b[0].s.foo();\n    Y[1] y2c = Y(s1a);//y2c[0].s.foo();  +/\n  static assert(!__traits(compiles, {\n    static struct Z { S[1] s; this(S){} }\n  }));\n/+  Z    z1a;         //z1a.s[0].foo();\n    Z    z1b = Z();     z1b.s[0].foo();\n    Z    z1c = Z(s1a);//z1c.s[0].foo();\n    Z[1] z2a;         //z1a.s[0].foo();\n    Z[1] z2b = Z();     z1b.s[0].foo();\n    Z[1] z2c = Z(s1a);//z1c.s[0].foo();  // +/\n}\n\nstruct Tuple8923(int v, T...)\n{\n    T field;\n    static if (v == 1) this(T args) { }    // should be an error\n    static if (v == 2) this(T args) { field = args; }\n    static if (v == 3) this(U...)(U args) { }    // should be an error\n    static if (v == 4) this(U...)(U args) { field = args; }\n    //alias field this;\n}\nvoid test8923b()\n{\n    int val;\n    struct S { void foo() { val = 1; } }\n\n  static assert(!__traits(compiles, Tuple8923!(1, S)(S()) ));\n  static assert(!__traits(compiles, Tuple8923!(3, S)(S()) ));\n\n    auto tup2 = Tuple8923!(2, S)(S());\n    tup2.field[0].foo();    // correctly initialized\n\n    auto tup4 = Tuple8923!(4, S)(S());\n    tup4.field[0].foo();    // correctly initialized\n}\n\nvoid test8923c()\n{\n    int val;\n\n    struct S  // is nested struct\n    {\n        void foo() { val = 1; }  // access to val through the hidden frame pointer\n    }\n    S    s1a;           s1a.foo();\n    S    s1b = S();     s1b.foo();\n    S[1] s2a;           s2a[0].foo();\n    S[1] s2b = S();     s2b[0].foo();\n\n    // U,V,W,X are nested struct, but should work same as non-nested.\n    // 1: bare struct object.  2: static array of structs.\n    // a: default construction.\n    // b: construction by literal syntax which has no argument.\n    // c: construction by literal syntax which has one or more arguments.\n\n    struct U\n    {\n        S s;\n        void foo() { val = 2; }\n    }\n    U    u1a;           u1a.foo();      u1a.s.foo();\n    U    u1b = U();     u1b.foo();      u1b.s.foo();\n    U    u1c = U(s1a);  u1c.foo();      u1c.s.foo();\n    U[1] u2a;           u2a[0].foo();   u2a[0].s.foo();\n    U[1] u2b = U();     u2b[0].foo();   u2b[0].s.foo();\n    U[1] u2c = U(s1a);  u2c[0].foo();   u2c[0].s.foo();\n\n    struct V\n    {\n        S[1] s;\n        void foo() { val = 2; }\n    }\n    V    v1a;           v1a.foo();      v1a.s[0].foo();\n    V    v1b = V();     v1b.foo();      v1b.s[0].foo();\n    V    v1c = V(s1a);  v1c.foo();      v1c.s[0].foo();\n    V[1] v2a;           v2a[0].foo();   v2a[0].s[0].foo();\n    V[1] v2b = V();     v2b[0].foo();   v2b[0].s[0].foo();\n    V[1] v2c = V(s1a);  v2c[0].foo();   v2c[0].s[0].foo();\n\n    struct W\n    {\n        S s;\n        this(S s) { this.s = s; }\n        void foo() { val = 2; }\n    }\n    W    w1a;           w1a.foo();      w1a.s.foo();\n    W    w1b = W();     w1b.foo();      w1b.s.foo();\n    W    w1c = W(s1a);  w1c.foo();      w1c.s.foo();\n    W[1] w2a;           w2a[0].foo();   w2a[0].s.foo();\n    W[1] w2b = W();     w2b[0].foo();   w2b[0].s.foo();\n    W[1] w2c = W(s1a);  w2c[0].foo();   w2c[0].s.foo();\n\n    struct X\n    {\n        S[1] s;\n        this(S s) { this.s[] = s; }\n        void foo() { val = 2; }\n    }\n    X    x1a;           x1a.foo();      x1a.s[0].foo();\n    X    x1b = X();     x1b.foo();      x1b.s[0].foo();\n    X    x1c = X(s1a);  x1c.foo();      x1c.s[0].foo();\n    X[1] x2a;           x2a[0].foo();   x2a[0].s[0].foo();\n    X[1] x2b = X();     x2b[0].foo();   x2b[0].s[0].foo();\n    X[1] x2c = X(s1a);  x2c[0].foo();   x2c[0].s[0].foo();\n\n    // Both declarations, Y and Z should raise errors,\n    // because their ctors don't initialize their field 's'.\n  static assert(!__traits(compiles, {\n    struct Y1 { S s; this(S){} void foo() { val = 2; } }\n  }));\n  static assert(!__traits(compiles, {\n    struct Y2 { S s; this(T)(S){} void foo() { val = 2; } }\n    auto y2 = Y2!S(S());    // instantiate ctor\n  }));\n\n  static assert(!__traits(compiles, {\n    struct Z1 { S[1] s; this(S){} void foo() { val = 2; } }\n  }));\n  static assert(!__traits(compiles, {\n    struct Z2 { S[1] s; this(T)(S){} void foo() { val = 2; } }\n    auto z2 = Z2!S(S());    // instantiate ctor\n  }));\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9003\n\nvoid test9003()\n{\n    int i;\n    struct NS {\n        int n1;    // Comment to pass all asserts\n        int n2;    // Uncomment to fail assert on line 19\n        int f() { return i; }\n    }\n\n    static struct SS1 {\n        NS ns;\n    }\n    SS1 ss1;\n    assert(ss1.ns != NS.init);\n\n    static struct SS2 {\n        NS ns1, ns2;\n    }\n    SS2 ss2;\n    assert(ss2.ns1 != NS.init); // line 19\n    assert(ss2.ns2 != NS.init);\n\n    static struct SS3 {\n        int i;\n        NS ns;\n    }\n\n    SS3 ss3;\n    assert(ss3.ns != NS.init);\n\n    static struct SS4 {\n        int i;\n        NS ns1, ns2;\n    }\n\n    SS4 ss4;\n    assert(ss4.ns1 != NS.init); // fails\n    assert(ss4.ns2 != NS.init); // fails\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9006\n\nvoid test9006()\n{\n    int i;\n    struct NS\n    {\n        int n;\n        int[3] a; // Uncomment to fail assert on line 20 and pass on line 23\n        int f() { return i; }\n    }\n    NS ns;\n    assert(ns != NS.init);\n    ns = NS.init;\n    assert(ns == NS.init);\n\n    static struct SS { NS ns; }\n    assert(SS.init.ns == NS.init); // fails\n    assert(SS.init.ns != NS());    // fails\n\n    SS s;\n    assert(s.ns != NS.init); // line 20\n    assert(s != SS.init);    // fails\n    s = SS.init;\n    assert(s.ns == NS.init); // line 23, fails\n    assert(s == SS.init);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9035\n\nvoid test9035()\n{\n    static struct S {}\n\n    void f(T)(auto ref T t)\n    {\n        static assert(!__traits(isRef, t));\n    }\n\n    f(S.init); // ok, rvalue\n    f(S());    // ok, rvalue\n\n    int i;\n    struct Nested\n    {\n        int j = 0; void f() { ++i; }\n    }\n\n    f(Nested());    // ok, rvalue\n    f(Nested.init); // fails, lvalue\n\n    assert(Nested.init.j == 0);\n    //(ref n) { n.j = 5; }(Nested.init);\n    assert(Nested.init.j == 0); // fails, j is 5\n}\n\nvoid test9035a()\n{\n    int x;\n    struct S {\n        // no field\n        void foo() { x = 1; }\n    }\n    S s1;\n    S s2 = S();\n    assert(s1  != S.init);  // OK\n    assert(s2  != S.init);  // OK\n    assert(S() != S.init);  // NG -> OK\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9036\n\nvoid test9036()\n{\n    static int i;\n    static struct S\n    {\n        this(this) { ++i; }\n    }\n\n    S s = S.init;\n    assert(i == 0); // postblit not called\n    s = S.init;\n    assert(i == 0); // postblit not called\n\n    int k;\n    static int j = 0;\n    struct N\n    {\n        this(this)\n        {\n            ++j;\n            assert(this.tupleof[$-1] != null); // fails\n        }\n        void f() { ++k; }\n    }\n\n    N n = N.init;\n    assert(j == 0); // fails, j = 1, postblit called\n    n = N.init;\n    assert(j == 0); // fails, j = 2, postblit called\n}\n\n/*******************************************/\n\n/+\nauto fun8863(T)(T* ret) { *ret = T(); }\n\nvoid test8863()\n{\n    int x = 1;\n    struct A\n    {\n        auto f()\n        {\n            assert(x == 1);\n        }\n    }\n\n    A a;\n    a.f();\n    fun8863!A(&a);\n    a.f();\n}\n+/\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8774\n\nvoid popFront8774()\n{\n    int[20] abc;    // smash stack\n}\n\nstruct MapResult8774(alias fun)\n{\n    void delegate() front()\n    {\n        return fun(1);\n    }\n}\n\nvoid test8774() {\n\n    int sliceSize = 100;\n\n    void delegate() foo( int i )\n    {\n        void delegate() closedPartialSum()\n        {\n            int ii = i ;\n            void bar()\n            {\n                printf(\"%d\\n\", sliceSize);\n                assert(sliceSize == 100);\n            }\n            return &bar;\n        }\n        return closedPartialSum();\n    }\n\n    auto threads = MapResult8774!foo();\n\n    auto dg = threads.front();\n    popFront8774();\n\n    printf(\"calling dg()\\n\");\n    dg();\n}\n\n/*******************************************/\n\nint Bug8832(alias X)()\n{\n    return X();\n}\n\nint delegate() foo8832()\n{\n  int stack;\n  int heap = 3;\n\n  int nested_func()\n  {\n    ++heap;\n    return heap;\n  }\n  return delegate int() { return Bug8832!(nested_func); };\n}\n\nvoid test8832()\n{\n  auto z = foo8832();\n  auto p = foo8832();\n  assert(z() == 4);\n  p();\n  assert(z() == 5);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9315\n\nauto test9315()\n{\n    struct S\n    {\n        int i;\n        void bar() {}\n    }\n    pragma(msg, S.init.tupleof[$-1]);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9244\n\nvoid test9244()\n{\n    union U {\n        int i;\n        @safe int x() { return i; }\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10495\n\nstruct X10495\n{\n    @disable this();\n}\n\nstruct Y10495(alias f)\n{\n    void g() {}\n}\n\nclass C10495\n{\n    X10495 s = X10495.init;\n\n    void h()\n    {\n        Y10495!(a => a) st;\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11385\n\nauto map11385(alias fun, R)(R range)\n{\n    return MapResult11385!(fun, R)(range);\n}\nstruct MapResult11385(alias fun, R)\n{\n    R range;\n    auto front() { return fun(range[0]); }\n}\nvoid test11385()\n{\n    //import std.algorithm;\n    static auto fun1(T)(T a) { return a * 2; }\n           auto fun2(T)(T a) { return a * 2; }\n    [1].map11385!(a=>fun1(a));   // OK\n    [1].map11385!(a=>fun2(a));   // NG:XXX is a nested function and cannot be accessed from XXX\n}\n\n/*******************************************/\n\nvoid xmap(alias g)(int t)\n{\n    g(t);\n}\n\nenum foo11297 = function (int x)\n   {\n        //int bar(int y) { return x; } xmap!bar(7);\n        xmap!(y => x)(7);\n   };\n\nvoid xreduce(alias f)()\n{\n    f(4);\n}\n\nvoid test11297()\n{\n    xreduce!foo11297();\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11886\n\nstruct Lambda11886(alias fun)\n{\n    auto opCall(A...)(A args) { return fun(args); }\n}\nvoid test11886()\n{\n    int n = 10;\n    Lambda11886!(x => x + n) f;\n    assert(f(1) == 11); // Line 9\n\n    struct NS\n    {\n        auto foo(T)(T t) { return t * n; }\n    }\n    static assert(NS.tupleof.length == 1);\n    static assert(NS.sizeof == (void*).sizeof);\n    NS ns;\n    assert(ns.foo(2) == 20);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12234\n\nvoid test12234()\n{\n    class B\n    {\n        int a;\n        this(int aa) { a = aa; }\n    }\n    auto foo = {\n        return new B(1);\n    };\n    static assert(is(typeof(foo) == delegate));\n\n    auto b = foo();\n    assert(b.a == 1);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12981\n\ntemplate Mix12981(T)\n{\n    class A\n    {\n        alias typeof(this.outer) x;\n    }\n}\n\nclass B12981\n{\n    mixin Mix12981!(int);\n\n    static assert(is(A.x == B12981));\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13861\n\nstruct Foo13861(alias f)\n{\n    struct Bar\n    {\n        Bar func()\n        {\n            return Bar();   // OK <- Segfault\n        }\n    }\n}\n\nvoid test13861()\n{\n    Foo13861!(n => n) a;\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14398\n\nvoid test14398()\n{\n    int outer;\n\n    struct Inner\n    {\n        this(this)\n        {\n            outer += 42;\n        }\n    }\n\n    struct Outer\n    {\n        Inner inner;\n\n        this(int dummy)\n        {\n            inner = Inner();\n\n            // hidden fields correctly set\n            assert(this.tupleof[$-1] !is null);\n            assert(inner.tupleof[$-1] !is null);\n        }\n    }\n\n    Outer[1] arr1 = [Outer(0)];\n    assert(outer == 0);     // no postblit called on arr1 construction\n    auto arr2 = arr1;\n    assert(outer == 42);    // inner is copied successfully\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14846\n\nvoid foo14846(Dg)(scope Dg code)\n{\n    static assert(is(Dg == delegate));\n    code();\n}\n\nvoid test14846()\n{\n    int x;\n\n    struct S\n    {\n        this(int n) { x = n; }\n        ~this() { x = 99; }\n    }\n\n    foo14846({ S s; });\n    foo14846({ S s = S(); });\n    foo14846({ S s = S(1); });\n    foo14846({ S[3] s; });\n\n    foo14846({ S* p = new S(); });\n    foo14846({ S* p = new S(1); });\n    foo14846({ S[] a = [S()]; });\n    foo14846({ S[] a = [S(1)]; });\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15422\n\nclass App15422(T)\n{\n    this() {}\n\n    auto test1(T val)\n    in {} body      // necessary to reproduce the crash\n    {\n        struct Foo\n        {\n            this(int k) {}\n            T a;\n        }\n\n        Foo foo;\n        foo.a = val;\n\n        // Frame of test2 function, allocated on heap.\n        assert(foo.tupleof[$-1] !is null);\n\n        //printf(\"&foo = %p\\n\", &foo);                  // stack\n        //printf(\"&this = %p\\n\", &this);                // stack?\n        //printf(\"foo.vthis = %p\\n\", foo.tupleof[$-1]); // stack...!?\n        //assert(cast(void*)&this !is *cast(void**)&foo.tupleof[$-1], \"bad\");\n        // BUG: currently foo.vthis set to the address of 'this' variable on the stack.\n        // It's should be stomped to null, because Foo.vthis is never be used.\n\n        int[Foo] map;\n        map[foo] = 1;   // OK <- crash\n\n        return foo;\n    }\n\n    auto test2(T val)\n    //in {} body\n    {\n        int closVar;\n        struct Foo\n        {\n            this(int k) { closVar = k; }\n            // Make val a closure variable.\n\n            T a;\n        }\n\n        Foo foo;\n        foo.a = val;\n\n        // Frame of test2 function, allocated on heap.\n        assert(foo.tupleof[$-1] !is null);\n\n        return foo;\n    }\n}\n\nvoid test15422a()\n{\n    alias App = App15422!int;\n    App app1 = new App;\n    {\n        auto x = app1.test1(1);\n        auto y = app1.test1(1);\n        static assert(is(typeof(x) == typeof(y)));\n\n        // int (bitwise comparison)\n        assert(x.a == y.a);\n\n        assert(*cast(void**)&x.tupleof[$-1] is *cast(void**)&y.tupleof[$-1]);\n\n        // bitwise equality (needOpEquals() and needToHash() returns false)\n        assert(x == y);\n\n        // BUG\n        //assert(*cast(void**)&x.tupleof[$-1] is null);\n        //assert(*cast(void**)&y.tupleof[$-1] is null);\n        auto getZ() { auto z = app1.test1(1); return z; }\n        auto z = getZ();\n        assert(x.a == z.a);\n        //assert(x.tupleof[$-1] is z.tupleof[$-1]);   // should pass\n        //assert(x == z);                             // should pass\n\n        x = y;  // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.\n    }\n    App app2 = new App;\n    {\n        auto x = app1.test2(1);\n        auto y = app2.test2(1);\n        static assert(is(typeof(x) == typeof(y)));\n\n        // int (bitwise comparison)\n        assert(x.a == y.a);\n\n        // closure envirionments\n        assert(*cast(void**)&x.tupleof[$-1] !is *cast(void**)&y.tupleof[$-1]);\n\n        // Changed to bitwise equality (needOpEquals() and needToHash() returns false)\n        assert(x != y);         // OK <- crash\n\n        x = y;  // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.\n    }\n}\n\nvoid test15422b()\n{\n    alias App = App15422!string;\n    App app1 = new App;\n    {\n        auto x = app1.test1(\"a\".idup);\n        auto y = app1.test1(\"a\".idup);\n        static assert(is(typeof(x) == typeof(y)));\n\n        // string (element-wise comparison)\n        assert(x.a == y.a);\n\n        assert(*cast(void**)&x.tupleof[$-1] is *cast(void**)&y.tupleof[$-1]);\n\n        // memberwise equality (needToHash() returns true)\n        assert(x == y);\n        // Lowered to: x.a == y.a && x.tupleof[$-1] is y.tupleof[$-1]\n\n        // BUG\n        //assert(*cast(void**)&x.tupleof[$-1] is null);\n        //assert(*cast(void**)&y.tupleof[$-1] is null);\n        auto getZ() { auto z = app1.test1(\"a\".idup); return z; }\n        auto z = getZ();\n        assert(x.a == z.a);\n        //assert(x.tupleof[$-1] is z.tupleof[$-1]);   // should pass\n        //assert(x == z);                             // should pass\n\n        x = y;  // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.\n    }\n    App app2 = new App;\n    {\n        auto x = app1.test2(\"a\".idup);\n        auto y = app2.test2(\"a\".idup);\n        static assert(is(typeof(x) == typeof(y)));\n\n        // string (element-wise comparison)\n        assert(x.a == y.a);\n\n        // closure envirionments\n        assert(*cast(void**)&x.tupleof[$-1] !is *cast(void**)&y.tupleof[$-1]);\n\n        // Changed to memberwise equality (needToHash() returns true)\n        // Lowered to: x.a == y.a && x.tupleof[$-1] is y.tupleof[$-1]\n        assert(x != y);         // OK <- crash\n\n        x = y;  // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15757\n\ntemplate map15757(fun...)\n{\n    auto map15757(R)(R r)\n    {\n        return MapResult15757!(fun, R)(r);\n    }\n}\n\nstruct MapResult15757(alias fun, R)\n{\n    R _input;\n\n    this(R input)\n    {\n        _input = input;\n    }\n}\n\nvoid wrap15757(R)(R r)\n{\n    struct M(R)\n    {\n        this(R r)\n        {\n            payload = r;\n        }\n        R payload;\n    }\n\n    M!R m = M!R(r);\n}\n\nvoid test15757() @safe\n{\n    [1,2,3].map15757!(x => x*x).wrap15757;\n}\n\n/***************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test4401();\n    test7428();\n    test4612();\n    test4841();\n    test7199();\n    test7965();\n    test7965a();\n    test8188();\n\n    test5082();\n    test8194();\n    test8339a();\n    test8339b();\n    test8339c();\n    test8923a();\n    test8923b();\n    test8923c();\n    test9003();\n    test9006();\n    test9035();\n    test9035a();\n    test9036();\n//    test8863();\n    test8774();\n    test8832();\n    test9315();\n    test9244();\n    test11385();\n    test11297();\n    test11886();\n    test12234();\n    test13861();\n    test14398();\n    test14846();\n    test15422a();\n    test15422b();\n    test15757();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/newdel.d",
    "content": "// PERMUTE_ARGS:\n\nimport core.stdc.stdio;\nimport core.stdc.stdlib;\n\n/*********************************************/\n\nclass Foo\n{\n    static uint flags;\n\n    new(size_t sz, int x)\n    {   void* p;\n\n        printf(\"Foo.new(sz = %d, x = %d)\\n\", sz, x);\n        assert(sz == Foo.classinfo.initializer.length);\n        assert(x == 5);\n\n        p = core.stdc.stdlib.malloc(sz);\n        flags |= 4;\n        return p;\n    }\n\n    this()\n    {\n        printf(\"this() %p\\n\", this);\n        a = 36;\n    }\n\n    ~this()\n    {\n        printf(\"~this() %p\\n\", this);\n        a = -5;\n        flags |= 1;\n    }\n\n    delete(void* p)\n    {\n        printf(\"delete %p\\n\", p);\n        free(p);\n        flags |= 2;\n    }\n\n    int a = 3;\n    int b = 4;\n    int d = 56;\n}\n\nvoid test1()\n{\n    Foo f;\n\n    f = new(5) Foo;\n    assert(f.a == 36);\n    assert(f.b == 4);\n    assert(f.d == 56);\n    assert(Foo.flags == 4);\n\n    delete f;\n    assert(Foo.flags == 7);\n}\n\n\n/*********************************************/\n\nstruct Foo2\n{\n    static uint flags;\n\n    new(size_t sz, int x)\n    {   void* p;\n\n        printf(\"Foo2.new(sz = %d, x = %d)\\n\", sz, x);\n        assert(sz == Foo2.sizeof);\n        assert(x == 5);\n\n        p = core.stdc.stdlib.malloc(sz);\n        flags |= 4;\n        return p;\n    }\n\n    delete(void *p)\n    {\n        printf(\"p = %p\\n\", p);\n        flags |= 2;\n        core.stdc.stdlib.free(p);\n    }\n}\n\nvoid test2()\n{\n    Foo2 *f = new(5) Foo2();\n\n    printf(\"f = %p\\n\", f);\n    delete f;\n    assert(Foo2.flags == 6);\n}\n\n\n/*********************************************/\n\nint main()\n{\n    test1();\n    test2();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/nogc.d",
    "content": "\nextern(C) int printf(const char*, ...);\n\n/***********************/\n\n@nogc int test1()\n{\n    return 3;\n}\n\n/***********************/\n// https://issues.dlang.org/show_bug.cgi?id=3032\n\nvoid test3032() @nogc\n{\n    scope o1 = new Object();        // on stack\n    scope o2 = new class Object {}; // on stack\n\n    int n = 1;\n    scope fp = (){ n = 10; };       // no closure\n    fp();\n    assert(n == 10);\n}\n\n/***********************/\n// https://issues.dlang.org/show_bug.cgi?id=12642\n\n__gshared int[1] data12642;\n\nint[1] foo12642() @nogc\n{\n    int x;\n    return [x];\n}\n\nvoid test12642() @nogc\n{\n    int x;\n    data12642 = [x];\n    int[1] data2;\n    data2 = [x];\n\n    data2 = foo12642();\n}\n\n/***********************/\n// https://issues.dlang.org/show_bug.cgi?id=12936\n\nvoid test12936() @nogc\n{\n    foreach (int[1] a; [[1]])\n    {\n        assert(a == [1]);\n    }\n    foreach (i, int[1] a; [[1], [2]])\n    {\n             if (i == 0) assert(a == [1]);\n        else if (i == 1) assert(a == [2]);\n        else             assert(0);\n    }\n}\n\n/***********************/\n\nint main()\n{\n    test1();\n    test3032();\n    test12642();\n    test12936();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/nulltype.d",
    "content": "extern (C) int printf(const(char*) fmt, ...);\n\nalias typeof(null) null_t;\n\n/**********************************************/\n\nvoid test1()\n{\n    null_t null1;\n    typeof(null) null2;\n\n    static assert(is(typeof(null1) == typeof(null)));\n    static assert(is(typeof(null2) == typeof(null)));\n\n    static assert(is(typeof(null1) == null_t));\n    static assert(is(typeof(null2) == null_t));\n}\n\n/**********************************************/\n\ninterface I{}\nclass C{}\n\nint f(null_t)   { return 1; }\nint f(int[])    { return 2; }\nint f(C)        { return 3; }\n\nvoid test2()\n{\n    static assert(is(null_t : C));\n    static assert(is(null_t : I));\n    static assert(is(null_t : int[]));\n    static assert(is(null_t : void*));\n    static assert(is(null_t : int**));\n\n    static assert(!is(null_t == C));\n    static assert(!is(null_t == I));\n    static assert(!is(null_t == int[]));\n    static assert(!is(null_t == void*));\n    static assert(!is(null_t == int**));\n\n    static assert(is(null_t == null_t));\n\n    assert(f(null) == 1);\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5899\n\nauto f5899(bool b)\n{\n    if (b)\n        return new Object;\n    else\n        return null;\n}\nstatic assert(is(typeof(f5899) R == return) && is(R == Object));\npragma(msg, typeof(f5899));\n\nauto g5899(bool b)\n{\n    if (b)\n        return new int;\n    else\n        return null;\n}\nstatic assert(is(typeof(g5899) R == return) && is(R == int*));\npragma(msg, typeof(g5899));\n\nauto h5899(bool b)\n{\n    if (b)\n        return [1];\n    else\n        return null;\n}\nstatic assert(is(typeof(h5899) R == return) && is(R == int[]));\npragma(msg, typeof(h5899));\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7278\n\nstruct Foo7278(string s)\n{\n    string var;\n    void func()\n    {\n        string local = var;\n    }\n}\n\nvoid test7278()\n{\n    Foo7278!null a;\n    Foo7278!null b;\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8221\n\nclass A8221\n{\n    A8221 foo() { return this; }\n}\nclass B8221: A8221\n{\n    override typeof(null) foo() { return null; } // error\n}\nvoid test8221()\n{\n    auto a = new A8221();\n    assert(a.foo() is a);\n    auto b = new B8221();\n    assert(b.foo() is null);\n    a = b;\n    assert(a.foo() is null);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8589\n\nvoid test8589()\n{\n    static typeof(null) retnull() { return null; }\n\n    void test(bool result, T)()\n    {\n        void f(T function() dg) { assert(!dg()); }\n\n        static assert((T.sizeof == typeof(null).sizeof) == result);\n        static assert(is(typeof( f(&retnull) )) == result);\n        static assert(is(typeof( f(()=>null) )) == result);\n        static if (result)\n        {\n            f(&retnull);\n            f(()=>null);\n        }\n    }\n    test!(true,  int*)();\n    test!(true,  Object)();\n    test!(true,  int[int])();\n    test!(false, int[])();\n    test!(false, void delegate())();\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9385\n\nvoid test9385()\n{\n    assert((null ? true : false) == false);\n    if (null) assert(0);\n    assert(!null);\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12203\n\nvoid test12203()\n{\n    typeof(null) v;\n    void foo(float) {}\n    void delegate(float) dg = &foo;\n    assert(dg !is null);\n\n    dg = v; // Error: e2ir: cannot cast v of type typeof(null) to type void delegate(float)\n\n    assert(dg  is null);\n}\n\n/**********************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test7278();\n    test8221();\n    test8589();\n    test9385();\n    test12203();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/opdisp.d",
    "content": "extern (C) int printf(const char* fmt, ...);\n\nint pass(int n){ return n; }\n\nstruct X\n{\n    int m;\n\n    int opIndex(int m, int n)\n    {\n        return n;\n    }\n}\n\n/**********************************************/\n\nstruct S1f\n{\n    int opDispatch(string name, A...)(A args)\n    {\n      static if (args.length)\n        return args[0];\n      else\n        return 0;\n    }\n}\nstruct S1p\n{\n    @property int opDispatch(string name, A...)(A args)\n    {\n      static if (args.length)\n        return args[0];\n      else\n        return 0;\n    }\n}\nvoid test1()\n{\n    S1f s1f;\n    assert(s1f.func() == 0);            // ok -> ok\n    assert(s1f.func(1) == 1);           // ok -> ok\n    assert(pass(s1f.func()) == 0);      // ok -> ok\n    assert(pass(s1f.func(1)) == 1);     // ok -> ok\n    assert(X(s1f.func()).m == 0);\n    assert(X()[0, s1f.func()] == 0);\n\n    S1p s1p;\n    assert(s1p.prop == 0);              // ok   -> ok\n    assert((s1p.prop = 1) == 1);        // CTng -> CTng\n    assert(pass(s1p.prop) == 0);        // ok   -> ok\n    assert(pass(s1p.prop = 2) == 2);    // CTng -> CTng\n    assert(X(s1p.prop).m == 0);\n    assert(X()[0, s1p.prop] == 0);\n}\n\n/**********************************************/\n\nstruct S2f\n{\n    template opDispatch(string name)\n    {\n        int opDispatch(A...)(A args)\n        {\n          static if (args.length)\n            return args[0];\n          else\n            return 0;\n        }\n    }\n}\nstruct S2p\n{\n    template opDispatch(string name)\n    {\n        @property int opDispatch(A...)(A args)\n        {\n          static if (args.length)\n            return args[0];\n          else\n            return 0;\n        }\n    }\n}\nvoid test2()\n{\n    S2f s2f;\n    assert(s2f.func() == 0);            // ok -> ok\n    assert(s2f.func(1) == 1);           // ok -> ok\n    assert(pass(s2f.func()) == 0);      // ok -> ok\n    assert(pass(s2f.func(1)) == 1);     // ok -> ok\n    assert(X(s2f.func()).m == 0);\n    assert(X()[0, s2f.func()] == 0);\n\n    S2p s2p;\n    assert(s2p.prop == 0);              // CTng -> ok\n    assert((s2p.prop = 1) == 1);        // ok   -> ok\n    assert(pass(s2p.prop) == 0);        // CTng -> ok\n    assert(pass(s2p.prop = 2) == 2);    // ok   -> ok\n    assert(X(s2p.prop).m == 0);\n    assert(X()[0, s2p.prop] == 0);\n}\n\n/**********************************************/\n\nstruct S3f\n{\n    template opDispatch(string name)\n    {\n        template opDispatch(T)\n        {\n            int opDispatch(A...)(A args)\n            {\n              static if (args.length)\n                return args[0];\n              else\n                return 0;\n            }\n        }\n    }\n}\nstruct S3p\n{\n    template opDispatch(string name)\n    {\n        template opDispatch(T)\n        {\n            @property int opDispatch(A...)(A args)\n            {\n              static if (args.length)\n                return args[0];\n              else\n                return 0;\n            }\n        }\n    }\n}\nvoid test3()\n{\n    S3f s3f;\n    assert(s3f.func!int() == 0);            // ok -> ok\n    assert(s3f.func!int(1) == 1);           // ok -> ok\n    assert(pass(s3f.func!int()) == 0);      // ok -> ok\n    assert(pass(s3f.func!int(1)) == 1);     // ok -> ok\n    assert(X(s3f.func!int()).m == 0);\n    assert(X()[0, s3f.func!int()] == 0);\n\n    S3p s3p;\n    assert(s3p.prop!int == 0);              // CTng -> ok\n    assert((s3p.prop!int = 1) == 1);        // ok   -> ok\n    assert(pass(s3p.prop!int) == 0);        // CTng -> ok\n    assert(pass(s3p.prop!int = 2) == 2);    // ok   -> ok\n    assert(X(s3p.prop!int).m == 0);\n    assert(X()[0, s3p.prop!int] == 0);\n}\n\n/**********************************************/\n\nstruct S4f\n{\n    ref int opDispatch(string name, A...)(A args)\n    {\n        static int n;\n        n = args.length;\n        return n;\n    }\n}\nstruct S4p\n{\n    @property ref int opDispatch(string name, A...)(A args)\n    {\n        static int n;\n        n = args.length;\n        return n;\n    }\n}\nvoid test4()\n{\n    S4f s4f;\n    assert(s4f.func == 0);          // getter\n    assert((s4f.func = 1) == 1);    // setter\n\n    S4p s4p;\n    assert(s4p.prop == 0);          // getter\n    assert((s4p.prop = 1) == 1);    // setter\n}\n\n/**********************************************/\n\nstruct S5f\n{\n    template opDispatch(string name)\n    {\n        ref int opDispatch(A...)(A args)\n        {\n            static int n;\n            n = args.length;\n            return n;\n        }\n    }\n}\nstruct S5p\n{\n    template opDispatch(string name)\n    {\n        @property ref int opDispatch(A...)(A args)\n        {\n            static int n;\n            n = args.length;\n            return n;\n        }\n    }\n}\nvoid test5()\n{\n    S5f s5f;\n    assert(s5f.prop == 0);          // getter   ng -> ok\n    assert((s5f.prop = 1) == 1);    // setter\n\n    S5p s5p;\n    assert(s5p.prop == 0);          // getter   ng -> ok\n    assert((s5p.prop = 1) == 1);    // setter\n}\n\n/**********************************************/\n\nstruct S6f\n{\n    template opDispatch(string name)\n    {\n        template opDispatch(T)\n        {\n            ref int opDispatch(A...)(A args)\n            {\n                static int n;\n                n = args.length;\n                return n;\n            }\n        }\n    }\n}\nstruct S6p\n{\n    template opDispatch(string name)\n    {\n        template opDispatch(T)\n        {\n            @property ref int opDispatch(A...)(A args)\n            {\n                static int n;\n                n = args.length;\n                return n;\n            }\n        }\n    }\n}\nvoid test6()\n{\n    S6f s6f;\n    assert(s6f.prop!int == 0);          // getter   ng -> ok\n    assert((s6f.prop!int = 1) == 1);    // setter\n\n    S6p s6p;\n    assert(s6p.prop!int == 0);          // getter   ng -> ok\n    assert((s6p.prop!int = 1) == 1);    // setter\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7578\n\nstruct Foo7578\n{\n    static int[] opDispatch(string op, Args...)(Args)\n    {\n        return [0];\n    }\n}\n\nvoid test7578()\n{\n    Foo7578.attrs[0] = 1;\n}\n\n/**********************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7578();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/opover.d",
    "content": "\n// Test operator overloading\n\nimport core.stdc.stdio;\n\n/**************************************/\n\nclass A1\n{\n    int opAdd(int i) { return 7 + i; }\n}\n\nvoid test1()\n{\n    A1 a = new A1();\n    int i;\n\n    i = a + 3;\n    assert(i == 10);\n\n    i = 4 + a;\n    assert(i == 11);\n}\n\n/**************************************/\n\nclass A2\n{\n    int opDiv(int i)   { return 9 + i; }\n    int opDiv_r(int i) { return 17 + i; }\n}\n\nvoid test2()\n{\n    A2 a = new A2();\n    int i;\n\n    i = a / 3;\n    assert(i == 12);\n\n    i = 4 / a;\n    assert(i == 21);\n}\n\n/**************************************/\n\nclass C1\n{\n}\n\nclass C2\n{\n    int opAdd(D1 d)   { return 1; }\n    int opAdd(D2 d)   { return 2; }\n    int opAdd(D3 d)   { return 3; }\n    int opAdd(D4 d)   { return 4; }\n}\n\nclass C3\n{\n    int opAdd_r(D1 d) { return 5; }\n    int opAdd_r(D2 d) { return 6; }\n    int opAdd_r(D3 d) { return 7; }\n    int opAdd_r(D4 d) { return 8; }\n}\n\nclass C4\n{\n    int opAdd(D1 d)   { return 9; }\n    int opAdd(D2 d)   { return 10; }\n    int opAdd(D3 d)   { return 11; }\n    int opAdd(D4 d)   { return 12; }\n\n    int opAdd_r(D1 d) { return 13; }\n    int opAdd_r(D2 d) { return 14; }\n    int opAdd_r(D3 d) { return 15; }\n    int opAdd_r(D4 d) { return 16; }\n}\n\nclass D1\n{\n}\n\nclass D2\n{\n    int opAdd(C1 c)   { return 17; }\n    int opAdd(C2 d)   { return 18; }\n    int opAdd(C3 d)   { return 19; }\n    int opAdd(C4 d)   { return 20; }\n}\n\nclass D3\n{\n    int opAdd_r(C1 d) { return 21; }\n    int opAdd_r(C2 d) { return 22; }\n    int opAdd_r(C3 d) { return 23; }\n    int opAdd_r(C4 d) { return 24; }\n}\n\nclass D4\n{\n    int opAdd(C1 d)   { return 25; }\n    int opAdd(C2 d)   { return 26; }\n    int opAdd(C3 d)   { return 27; }\n    int opAdd(C4 d)   { return 28; }\n\n    int opAdd_r(C1 d) { return 29; }\n    int opAdd_r(C2 d) { return 30; }\n    int opAdd_r(C3 d) { return 31; }\n    int opAdd_r(C4 d) { return 32; }\n}\n\n\n\nvoid test3()\n{\n    C1 c1 = new C1();\n    C2 c2 = new C2();\n    C3 c3 = new C3();\n    C4 c4 = new C4();\n    D1 d1 = new D1();\n    D2 d2 = new D2();\n    D3 d3 = new D3();\n    D4 d4 = new D4();\n\n    int i;\n\n  version (ADD_R)\n  {\n    //i = c1 + d1;    assert(i == );\n    i = c1 + d2;    assert(i == 17);\n    i = c1 + d3;    assert(i == 21);\n    i = c1 + d4;    assert(i == 29);\n\n    i = c2 + d1;    assert(i == 1);\n    i = c2 + d2;    assert(i == 2);\n    i = c2 + d3;    assert(i == 3);\n    i = c2 + d4;    assert(i == 4);\n\n    //i = c3 + d1;    assert(i == );\n    i = c3 + d2;    assert(i == 19);\n    i = c3 + d3;    assert(i == 23);\n    i = c3 + d4;    assert(i == 31);\n\n    i = c4 + d1;    assert(i == 9);\n    i = c4 + d2;    assert(i == 10);\n    i = c4 + d3;    assert(i == 11);\n    i = c4 + d4;    assert(i == 12);\n\n    //i = d1 + c1;    assert(i == );\n    i = d1 + c2;    assert(i == 1);\n    i = d1 + c3;    assert(i == 5);\n    i = d1 + c4;    assert(i == 13);\n\n    i = d2 + c1;    assert(i == 17);\n    i = d2 + c2;    assert(i == 18);\n    i = d2 + c3;    assert(i == 19);\n    i = d2 + c4;    assert(i == 20);\n\n    //i = d3 + c1;    assert(i == );\n    i = d3 + c2;    assert(i == 3);\n    i = d3 + c3;    assert(i == 7);\n    i = d3 + c4;    assert(i == 15);\n\n    i = d4 + c1;    assert(i == 25);\n    i = d4 + c2;    assert(i == 26);\n    i = d4 + c3;    assert(i == 27);\n    i = d4 + c4;    assert(i == 28);\n  }\n  else\n  {\n    //i = c1 + d1;    assert(i == );\n    i = c1 + d2;    assert(i == 17);\n//    i = c1 + d3;    assert(i == 21);\n    i = c1 + d4;    assert(i == 29);\n\n    i = c2 + d1;    assert(i == 1);\n    i = c2 + d2;    assert(i == 2);\n//    i = c2 + d3;    assert(i == 3);\n//    i = c2 + d4;    assert(i == 4);\n\n    //i = c3 + d1;    assert(i == );\n//    i = c3 + d2;    printf(\"i = %d\\n\", i); assert(i == 19);\n//    i = c3 + d3;    assert(i == 23);\n    i = c3 + d4;    assert(i == 31);\n\n    i = c4 + d1;    assert(i == 9);\n    i = c4 + d2;    assert(i == 10);\n//    i = c4 + d3;    assert(i == 11);\n//    i = c4 + d4;    assert(i == 12);\n\n    //i = d1 + c1;    assert(i == );\n    i = d1 + c2;    assert(i == 1);\n//    i = d1 + c3;    assert(i == 5);\n    i = d1 + c4;    assert(i == 13);\n\n    i = d2 + c1;    assert(i == 17);\n    i = d2 + c2;    assert(i == 18);\n//    i = d2 + c3;    assert(i == 19);\n//    i = d2 + c4;    assert(i == 20);\n\n    //i = d3 + c1;    assert(i == );\n//    i = d3 + c2;    assert(i == 3);\n//    i = d3 + c3;    assert(i == 7);\n    i = d3 + c4;    assert(i == 15);\n\n    i = d4 + c1;    assert(i == 25);\n    i = d4 + c2;    assert(i == 26);\n//    i = d4 + c3;    assert(i == 27);\n//    i = d4 + c4;    assert(i == 28);\n  }\n}\n\n/**************************************/\n\nstruct Foo4\n{\n    int a;\n    int opCmp(Foo4 b)\n    {\n        return a < b.a;\n    }\n}\n\nvoid test4()\n{\n   Foo4 a;\n   Foo4 b;\n\n   assert(a <= b);\n}\n\n/**************************************/\n\nclass A5\n{\n    int opNeg()     { return 10; }\n    int opCom()     { return 11; }\n    int opPostInc() { return 12; }\n    int opPostDec() { return 13; }\n\n    int opAdd(int j)     { return 14; }\n    int opSub(int j)     { return 15; }\n    int opSub_r(int j)   { return 16; }\n    int opMul(int j)     { return 17; }\n    int opDiv(int j)     { return 18; }\n    int opDiv_r(int j)   { return 19; }\n    int opMod(int j)     { return 20; }\n    int opMod_r(int j)   { return 21; }\n    int opAnd(int j)     { return 22; }\n    int opOr(int j)      { return 23; }\n    int opXor(int j)     { return 24; }\n    int opShl(int j)     { return 25; }\n    int opShl_r(int j)   { return 26; }\n    int opShr(int j)     { return 27; }\n    int opShr_r(int j)   { return 28; }\n    int opUShr(int j)    { return 29; }\n    int opUShr_r(int j)  { return 30; }\n    int opCat(int j)     { return 31; }\n    int opCat_r(int j)   { return 32; }\n    int opEquals(int j)  { return 33; }\n    int opCmp(int j)     { return 34; }\n    int opAddAssign(int j)  { return 35; }\n    int opSubAssign(int j)  { return 36; }\n    int opMulAssign(int j)  { return 37; }\n    int opDivAssign(int j)  { return 38; }\n    int opModAssign(int j)  { return 39; }\n    int opAndAssign(int j)  { return 40; }\n    int opOrAssign(int j)   { return 41; }\n    int opXorAssign(int j)  { return 42; }\n    int opShlAssign(int j)  { return 43; }\n    int opShrAssign(int j)  { return 44; }\n    int opUShrAssign(int j) { return 45; }\n    int opCatAssign(int j)  { return 46; }\n}\n\nvoid test5()\n{\n    A5 a = new A5();\n    int i;\n\n    i = -a;\n    assert(i == 10);\n\n    i = ~a;\n    assert(i == 11);\n\n    i = a++;\n    assert(i == 12);\n\n    i = a--;\n    assert(i == 13);\n\n    i = a + 1;\n    assert(i == 14);\n\n    i = a - 1;\n    assert(i == 15);\n\n    i = 1 - a;\n    assert(i == 16);\n\n    i = a * 1;\n    assert(i == 17);\n\n    i = a / 1;\n    assert(i == 18);\n\n    i = 1 / a;\n    assert(i == 19);\n\n    i = a % 1;\n    assert(i == 20);\n\n    i = 1 % a;\n    assert(i == 21);\n\n    i = a & 1;\n    assert(i == 22);\n\n    i = a | 1;\n    assert(i == 23);\n\n    i = a ^ 1;\n    assert(i == 24);\n\n    i = a << 1;\n    assert(i == 25);\n\n    i = 1 << a;\n    assert(i == 26);\n\n    i = a >> 1;\n    assert(i == 27);\n\n    i = 1 >> a;\n    assert(i == 28);\n\n    i = a >>> 1;\n    assert(i == 29);\n\n    i = 1 >>> a;\n    assert(i == 30);\n\n    i = a ~ 1;\n    assert(i == 31);\n\n    i = 1 ~ a;\n    assert(i == 32);\n\n    i = a == 1;\n    assert(i == 33);\n    i = 1 == a;\n    assert(i == 33);\n    i = a != 1;\n    assert(i == 0);\n    i = 1 != a;\n    assert(i == 0);\n\n    i = a < 1;\n    assert(i == 0);\n    i = a <= 1;\n    assert(i == 0);\n    i = a > 1;\n    assert(i == 1);\n    i = a >= 1;\n    assert(i == 1);\n\n    i = 1 < a;\nprintf(\"i = %d\\n\", i);\n    assert(i == 1);\n    i = 1 <= a;\n    assert(i == 1);\n    i = 1 > a;\n    assert(i == 0);\n    i = 1 >= a;\n    assert(i == 0);\n\n    i = (a += 1);\n    assert(i == 35);\n    i = ++a;\n    assert(i == 35);\n\n    i = (a -= 1);\n    assert(i == 36);\n    i = --a;\n    assert(i == 36);\n\n    i = (a *= 1);\n    assert(i == 37);\n\n    i = (a /= 1);\n    assert(i == 38);\n\n    i = (a %= 1);\n    assert(i == 39);\n\n    i = (a &= 1);\n    assert(i == 40);\n\n    i = (a |= 1);\n    assert(i == 41);\n\n    i = (a ^= 1);\n    assert(i == 42);\n\n    i = (a <<= 1);\n    assert(i == 43);\n\n    i = (a >>= 1);\n    assert(i == 44);\n\n    i = (a >>>= 1);\n    assert(i == 45);\n\n    i = (a ~= 1);\n    assert(i == 46);\n}\n\n/*********************************/\n\nstruct A6\n{\n    int opNeg()     { return 10; }\n    int opCom()     { return 11; }\n    int opPostInc() { return 12; }\n    int opPostDec() { return 13; }\n\n    int opAdd(int j)     { return 14; }\n    int opSub(int j)     { return 15; }\n    int opSub_r(int j)   { return 16; }\n    int opMul(int j)     { return 17; }\n    int opDiv(int j)     { return 18; }\n    int opDiv_r(int j)   { return 19; }\n    int opMod(int j)     { return 20; }\n    int opMod_r(int j)   { return 21; }\n    int opAnd(int j)     { return 22; }\n    int opOr(int j)      { return 23; }\n    int opXor(int j)     { return 24; }\n    int opShl(int j)     { return 25; }\n    int opShl_r(int j)   { return 26; }\n    int opShr(int j)     { return 27; }\n    int opShr_r(int j)   { return 28; }\n    int opUShr(int j)    { return 29; }\n    int opUShr_r(int j)  { return 30; }\n    int opCat(int j)     { return 31; }\n    int opCat_r(int j)   { return 32; }\n    int opEquals(int j)      { return 33; }\n    const bool opEquals(const ref A6)      { return false; }\n    int opCmp(int j)     { return 34; }\n    int opAddAssign(int j)  { return 35; }\n    int opSubAssign(int j)  { return 36; }\n    int opMulAssign(int j)  { return 37; }\n    int opDivAssign(int j)  { return 38; }\n    int opModAssign(int j)  { return 39; }\n    int opAndAssign(int j)  { return 40; }\n    int opOrAssign(int j)   { return 41; }\n    int opXorAssign(int j)  { return 42; }\n    int opShlAssign(int j)  { return 43; }\n    int opShrAssign(int j)  { return 44; }\n    int opUShrAssign(int j) { return 45; }\n    int opCatAssign(int j)  { return 46; }\n}\n\nvoid test6()\n{\n    A6 a;\n    int i;\n\n    i = -a;\n    assert(i == 10);\n\n    i = ~a;\n    assert(i == 11);\n\n    i = a++;\n    assert(i == 12);\n\n    i = a--;\n    assert(i == 13);\n\n    i = a + 1;\n    assert(i == 14);\n\n    i = a - 1;\n    assert(i == 15);\n\n    i = 1 - a;\n    assert(i == 16);\n\n    i = a * 1;\n    assert(i == 17);\n\n    i = a / 1;\n    assert(i == 18);\n\n    i = 1 / a;\n    assert(i == 19);\n\n    i = a % 1;\n    assert(i == 20);\n\n    i = 1 % a;\n    assert(i == 21);\n\n    i = a & 1;\n    assert(i == 22);\n\n    i = a | 1;\n    assert(i == 23);\n\n    i = a ^ 1;\n    assert(i == 24);\n\n    i = a << 1;\n    assert(i == 25);\n\n    i = 1 << a;\n    assert(i == 26);\n\n    i = a >> 1;\n    assert(i == 27);\n\n    i = 1 >> a;\n    assert(i == 28);\n\n    i = a >>> 1;\n    assert(i == 29);\n\n    i = 1 >>> a;\n    assert(i == 30);\n\n    i = a ~ 1;\n    assert(i == 31);\n\n    i = 1 ~ a;\n    assert(i == 32);\n\n    i = a == 1;\n    assert(i == 33);\n    i = 1 == a;\n    assert(i == 33);\n    i = a != 1;\n    assert(i == 0);\n    i = 1 != a;\n    assert(i == 0);\n\n    i = a < 1;\n    assert(i == 0);\n    i = a <= 1;\n    assert(i == 0);\n    i = a > 1;\n    assert(i == 1);\n    i = a >= 1;\n    assert(i == 1);\n\n    i = 1 < a;\n    assert(i == 1);\n    i = 1 <= a;\n    assert(i == 1);\n    i = 1 > a;\n    assert(i == 0);\n    i = 1 >= a;\n    assert(i == 0);\n\n    i = (a += 1);\n    assert(i == 35);\n    i = ++a;\n    assert(i == 35);\n\n    i = (a -= 1);\n    assert(i == 36);\n    i = --a;\n    assert(i == 36);\n\n    i = (a *= 1);\n    assert(i == 37);\n\n    i = (a /= 1);\n    assert(i == 38);\n\n    i = (a %= 1);\n    assert(i == 39);\n\n    i = (a &= 1);\n    assert(i == 40);\n\n    i = (a |= 1);\n    assert(i == 41);\n\n    i = (a ^= 1);\n    assert(i == 42);\n\n    i = (a <<= 1);\n    assert(i == 43);\n\n    i = (a >>= 1);\n    assert(i == 44);\n\n    i = (a >>>= 1);\n    assert(i == 45);\n\n    i = (a ~= 1);\n    assert(i == 46);\n}\n\n\n/**************************************/\n\nstruct Foo7\n{\n    int opSlice() { return 7; }\n    int opSlice(int i, int j) { return i * (j + 1); }\n}\n\nvoid test7()\n{\n    Foo7 f;\n    int i;\n\n    i = f[];\n    assert(i == 7);\n    i = f[3..4];\n    assert(i == 15);\n}\n\n/**************************************/\n\ninterface IWriter\n{\n        int opShl (string i);\n        int opShl (int i);\n}\n\nclass Writer : IWriter\n{\n    int opShl (string i)\n    {\n        printf(\"Writer.opShl(char[])\\n\");\n        return 1;\n    }\n\n    int opShl (int i)\n    {\n        printf(\"Writer.opShl(int)\\n\");\n        return 2;\n    }\n}\n\nclass BinaryWriter : Writer\n{\n    alias Writer.opShl opShl;\n\n    override int opShl (int i)\n    {\n        printf(\"BinaryWriter.opShl(int)\\n\");\n        return 3;\n    }\n}\n\nvoid test8()\n{\n    BinaryWriter bw = new BinaryWriter();\n    int i;\n\n    i = bw << \"test\";\n    assert(i == 1);\n    i = bw << 1;\n    assert(i == 3);\n}\n\n/**************************************/\n\nstruct A9\n{\n    int opCast() { return 28; }\n}\n\nvoid test9()\n{\n    A9 a;\n\n    long i = cast(long)a;\n    assert(i == 28);\n}\n\n/**************************************/\n\nclass A10\n{\n    int opAdd(int i) { return i + 1; }\n}\n\nclass B10\n{\n    int opAdd_r(A10 a) { return 3; }\n}\n\nvoid test10()\n{\n    int i;\n    A10 a = new A10();\n\n    i = a + 1;\n    printf(\"a + 1 = %d\\n\", i);\n    assert(i == 2);\n\n    i = 1 + a;\n    printf(\"1 + a = %d\\n\", i);\n    assert(i == 2);\n\n    B10 b = new B10();\n    i = a + b;\n    printf(\"a + b = %d\\n\", i);\n    assert(i == 3);\n\n    i = b + a;\n    printf(\"b + a = %d\\n\", i);\n    assert(i == 3);\n\n//    i = b + 3;\n}\n\n/**************************************/\n\nclass A11\n{\n    int opIndex(int i) { return i; }\n    int opIndexAssign(int value, int i) { return value * 10 + i; }\n}\n\nvoid test11()\n{\n    int i;\n    A11 a = new A11();\n\n    i = a[5];\n    assert(i == 5);\n    i = (a[4] = 6);\n    printf(\"i = %d\\n\", i);\n    assert(i == 64);\n}\n\n/**************************************/\n\nclass A12\n{\n    int opIndex(int i1, int i2) { return i1 * 10 + i2; }\n    int opIndexAssign(int value, int i1, int i2) { return value * 100 + i1 * 10 + i2; }\n}\n\n\nvoid test12()\n{\n   A12 a = new A12();\n   int i;\n\n   printf(\"%d\\n\", a[1, 2]);\n   assert(a[1, 2] == 12);\n\n   i = (a[3, 4] = 5);\n   printf(\"%d\\n\", i);\n   assert(i == 534);\n}\n\n/**************************************/\n\nclass A13\n{\n A13 opShl(int x)\n {\n    printf(\"A::opShl(int %d)\\n\", x);\n    printf(\"%d\",x);\n    return this;\n }\n A13 opShl(string x)\n {\n    printf(\"A::opShl(char[])\\n\");\n    printf(\"%.*s\", x.length, x.ptr);\n    return this;\n }\n}\n\nclass B13\n{\n A13 opShl_r(A13 a)\n {\n    printf(\"B::opShl_r(A)\\n\");\n    return a;\n }\n}\n\nvoid test13()\n{\n    A13 a = new A13();\n    a << 4 << \" \" << 12 << \"\\n\";\n\n    B13 b = new B13();\n    a << b;\n}\n\n\n/**************************************/\n\nclass Foo14\n{   int a;\n\n    int opIn(int x)\n    {\n        return a + x;\n    }\n}\n\nvoid test14()\n{\n    auto f = new Foo14;\n    f.a = 3;\n    auto i = f in 7;\n    assert(i == 10);\n}\n\n/**************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=3983\n\nstruct Fug\n{\n    bool opEquals(ref const Fug y) const {\n        return false;\n    }\n}\n\nstruct Fig\n{\n   Fug f;\n   bool opEquals(Tdummy=void)(ref const Fig y) const {\n      return false;\n   }\n\n   bool opEquals(T: int)(T y) const {\n      return false;\n   }\n}\n\nvoid test15()\n{\n  Fig fx, fy;\n  if (fx==2) {}\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4953\n\nstruct S4953a\n{\n    short _x;\n    bool opBinaryRight(string op)(short x) if (op == \"in\")\n    {\n        return x == _x;\n    }\n}\nvoid test4953a()\n{\n    S4953a s;\n    5 in s;\n}\n\nstruct S4953b\n{\n    void opBinary(string op)(short x)\n    {}\n}\nvoid test4953b()\n{\n    S4953b s;\n    s + 5;\n}\n\n\nstruct S4953c\n{\n    void funOpAssign(float[1u] data) { }\n    void opOpAssign(string op)(float[1u] data) if(op==\"<<\") { }\n}\nvoid test4953c()\n{\n    // dmd v2.054, v2.055\n    S4953c s;\n    float[1u] a = [1.0f]; // OK: Implicit cast from float[] compiles\n    s.funOpAssign([1.0f]); // OK: Implicit cast from float[] compiles\n    s <<= [1.0f]; // Issue: Implicit cast from float[] does not compile\n    s <<= cast(float[1u])[1.0f]; // OK: Explicit cast from float[] compiles\n}\n\nvoid f4953d1  (dstring d) { dstring e = d; }\nvoid f4953d2()(dstring d) { dstring e = d; }\nvoid f4953d3  ( byte[] b) { byte[] c = b; }\nvoid f4953d4()( byte[] b) { byte[] c = b; }\nvoid test4953d()\n{\n    f4953d1(\"abc\");  // OK\n    f4953d2(\"abc\");  // OK\n    f4953d3([1,2,3]); // OK\n    f4953d4([1,2,3]);\n    // Error: template test2.f() does not match any function template declaration\n    // Error: template test2.f() cannot deduce template function from argument types !()(int[])\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4993\n\n// reduced from the bug report\nstruct Bar4993\n{\n    void opIndexAssign(int value, size_t index) {}\n}\n@property auto bar4993()\n{\n    return Bar4993();\n}\nvoid test4993()\n{\n    bar4993[3] = 42;\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8133\n\nvoid test8133()\n{\n    struct S\n    {\n        int opCall() { return 1; }\n    }\n    struct A\n    {\n        S s;\n        alias s this;\n    }\n    A f = A();\n    assert(f() == 1);\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8522\n\nstruct Point8522\n{\n    bool opEquals(R)(R rhs) { return true; }\n    bool opEquals(R)(R rhs) const { return true; }\n}\n\nvoid test8522()\n{\n    Point8522 mp;\n    const Point8522 cp;\n    assert(mp == mp);\n    assert(mp == cp);\n    assert(cp == mp);   // doesn't work\n    assert(cp == cp);   // doesn't work\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12778\n\nstruct Vec12778X\n{\n    Vec12778X opBinary(string op)(Vec12778X b) const\n    if (op == \"+\")\n    {\n        mixin(\"return Vec12778X(this.x \" ~ op ~ \" b.x, this.y \" ~ op ~ \" b.y);\");\n    }\n    alias opBinaryRight = opBinary;\n\n    float x = 0, y = 0;\n}\n\nstruct Vec12778Y\n{\n    Vec12778Y opAdd()(Vec12778Y b) const\n    {\n        enum op = \"+\";\n        mixin(\"return Vec12778Y(this.x \" ~ op ~ \" b.x, this.y \" ~ op ~ \" b.y);\");\n    }\n    alias opAdd_r = opAdd;\n\n    float x = 0, y = 0;\n}\n\nvoid test12778()\n{\n    struct S\n    {\n        void test1()\n        {\n            Vec12778X vx = vx1 + vx2;   // ok\n            Vec12778Y vy = vy1 + vy2;   // ok\n        }\n\n        void test2() const\n        {\n            Vec12778X vx = vx1 + vx2;   // ok <- error\n            Vec12778Y vy = vy1 + vy2;   // ok <- error\n        }\n\n        Vec12778X vx1, vx2;\n        Vec12778Y vy1, vy2;\n    }\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14343\n\nstruct S14343a\n{\n    int i;\n    immutable(Object) o;\n\n    S14343a opUnary(string op)() { return this; }\n    void opAssign(S14343a other) {}\n}\n\nstruct S14343b\n{\n    int i;\n    immutable(Object) o;\n\n    void opAddAssign(int j) { i += j; }\n    S14343b opPostInc() { ++i; return this; }\n    void opAssign(S14343b other) {}\n}\n\nvoid test14343()\n{\n    {\n        S14343a s, t;\n\n        t = s;  // OK\n        ++s;    // OK\n        s++;    // OK <- Error: cannot modify struct s S with immutable members\n    }\n    {\n        S14343b s;\n        ++s;\n        assert(s.i == 1);\n        s++;\n        assert(s.i == 2);\n    }\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14344\n\nstruct S14344\n{\n    S14344 opBinary(string op)(S14344 v)\n    {\n        static assert(0);\n    }\n    S14344 opAssign()(S14344 v)\n    {\n        static assert(0);\n    }\n}\n\nstruct S14344Mix\n{\n    S14344 s;\n    alias s this;\n}\n\nclass C14344\n{\n    S14344Mix height() { return S14344Mix(); }\n\n    void update()\n    {\n        S14344 height = this.height;\n    }\n}\n\n/**************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test4953a();\n    test4953b();\n    test4953c();\n    test4953d();\n    test4993();\n    test8133();\n    test8522();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/opover2.d",
    "content": "// PERMUTE_ARGS: -inline -O\n// REQUIRED_ARGS: -dip25\n\n// Test operator overloading\n\nextern (C) int printf(const(char*) fmt, ...);\n\ntemplate Seq(T...){ alias T Seq; }\n\nbool thrown(E, T)(lazy T val)\n{\n    try { val(); return false; }\n    catch (E e) { return true; }\n}\n\nvoid stompStack() { int[256] sa = 0xdeadbeef; }\n\n/**************************************/\n\nclass A\n{\n    string opUnary(string s)()\n    {\n        printf(\"A.opUnary!(%.*s)\\n\", s.length, s.ptr);\n        return s;\n    }\n}\n\nvoid test1()\n{\n    auto a = new A();\n\n    +a;\n    -a;\n    ~a;\n    *a;\n    ++a;\n    --a;\n\n    auto x = a++;\n    assert(x == a);\n    auto y = a--;\n    assert(y == a);\n}\n\n/**************************************/\n\nclass A2\n{\n    T opCast(T)()\n    {\n        auto s = T.stringof;\n        printf(\"A.opCast!(%.*s)\\n\", s.length, s.ptr);\n        return T.init;\n    }\n}\n\n\nvoid test2()\n{\n    auto a = new A2();\n\n    auto x = cast(int)a;\n    assert(x == 0);\n\n    auto y = cast(char)a;\n    assert(y == char.init);\n}\n\n/**************************************/\n\nstruct A3\n{\n    int opBinary(string s)(int i)\n    {\n        printf(\"A.opBinary!(%.*s)\\n\", s.length, s.ptr);\n        return 0;\n    }\n\n    int opBinaryRight(string s)(int i) if (s == \"/\" || s == \"*\")\n    {\n        printf(\"A.opBinaryRight!(%.*s)\\n\", s.length, s.ptr);\n        return 0;\n    }\n\n    T opCast(T)()\n    {\n        auto s = T.stringof;\n        printf(\"A.opCast!(%.*s)\\n\", s.length, s.ptr);\n        return T.init;\n    }\n}\n\n\nvoid test3()\n{\n    A3 a;\n\n    a + 3;\n    4 * a;\n    4 / a;\n    a & 5;\n}\n\n/**************************************/\n\nstruct A4\n{\n    int opUnary(string s)()\n    {\n        printf(\"A.opUnary!(%.*s)\\n\", s.length, s.ptr);\n        return 0;\n    }\n\n    T opCast(T)()\n    {\n        auto s = T.stringof;\n        printf(\"A.opCast!(%.*s)\\n\", s.length, s.ptr);\n        return T.init;\n    }\n}\n\n\nvoid test4()\n{\n    A4 a;\n\n    if (a)\n        int x = 3;\n    if (!a)\n        int x = 3;\n    if (!!a)\n        int x = 3;\n}\n\n/**************************************/\n\nclass A5\n{\n    override bool opEquals(Object o)\n    {\n        printf(\"A.opEquals!(%p)\\n\", o);\n        return 1;\n    }\n\n    int opUnary(string s)()\n    {\n        printf(\"A.opUnary!(%.*s)\\n\", s.length, s.ptr);\n        return 0;\n    }\n\n    T opCast(T)()\n    {\n        auto s = T.stringof;\n        printf(\"A.opCast!(%.*s)\\n\", s.length, s.ptr);\n        return T.init;\n    }\n}\n\nclass B5 : A5\n{\n    override bool opEquals(Object o)\n    {\n        printf(\"B.opEquals!(%p)\\n\", o);\n        return 1;\n    }\n}\n\n\nvoid test5()\n{\n    A5 a = new A5();\n    A5 a2 = new A5();\n    B5 b = new B5();\n    A n = null;\n\n    if (a == a)\n        int x = 3;\n    if (a == a2)\n        int x = 3;\n    if (a == b)\n        int x = 3;\n    if (a == n)\n        int x = 3;\n    if (n == a)\n        int x = 3;\n    if (n == n)\n        int x = 3;\n}\n\n/**************************************/\n\nstruct S6\n{\n    const bool opEquals(ref const S6 b)\n    {\n        printf(\"S.opEquals(S %p)\\n\", &b);\n        return true;\n    }\n\n    const bool opEquals(ref const T6 b)\n    {\n        printf(\"S.opEquals(T %p)\\n\", &b);\n        return true;\n    }\n}\n\nstruct T6\n{\n    const bool opEquals(ref const T6 b)\n    {\n        printf(\"T.opEquals(T %p)\\n\", &b);\n        return true;\n    }\n/+\n    const bool opEquals(ref const S6 b)\n    {\n        printf(\"T.opEquals(S %p)\\n\", &b);\n        return true;\n    }\n+/\n}\n\n\nvoid test6()\n{\n    S6 s1;\n    S6 s2;\n\n    if (s1 == s2)\n        int x = 3;\n\n    T6 t;\n\n    if (s1 == t)\n        int x = 3;\n\n    if (t == s2)\n        int x = 3;\n}\n\n/**************************************/\n\nstruct S7\n{\n    const int opCmp(ref const S7 b)\n    {\n        printf(\"S.opCmp(S %p)\\n\", &b);\n        return -1;\n    }\n\n    const int opCmp(ref const T7 b)\n    {\n        printf(\"S.opCmp(T %p)\\n\", &b);\n        return -1;\n    }\n}\n\nstruct T7\n{\n    const int opCmp(ref const T7 b)\n    {\n        printf(\"T.opCmp(T %p)\\n\", &b);\n        return -1;\n    }\n/+\n    const int opCmp(ref const S7 b)\n    {\n        printf(\"T.opCmp(S %p)\\n\", &b);\n        return -1;\n    }\n+/\n}\n\n\nvoid test7()\n{\n    S7 s1;\n    S7 s2;\n\n    if (s1 < s2)\n        int x = 3;\n\n    T7 t;\n\n    if (s1 < t)\n        int x = 3;\n\n    if (t < s2)\n        int x = 3;\n}\n\n/**************************************/\n\nstruct A8\n{\n    int opUnary(string s)()\n    {\n        printf(\"A.opUnary!(%.*s)\\n\", s.length, s.ptr);\n        return 0;\n    }\n\n    int opIndexUnary(string s, T)(T i)\n    {\n        printf(\"A.opIndexUnary!(%.*s)(%d)\\n\", s.length, s.ptr, i);\n        return 0;\n    }\n\n    int opIndexUnary(string s, T)(T i, T j)\n    {\n        printf(\"A.opIndexUnary!(%.*s)(%d, %d)\\n\", s.length, s.ptr, i, j);\n        return 0;\n    }\n\n    int opSliceUnary(string s)()\n    {\n        printf(\"A.opSliceUnary!(%.*s)()\\n\", s.length, s.ptr);\n        return 0;\n    }\n\n    int opSliceUnary(string s, T)(T i, T j)\n    {\n        printf(\"A.opSliceUnary!(%.*s)(%d, %d)\\n\", s.length, s.ptr, i, j);\n        return 0;\n    }\n}\n\n\nvoid test8()\n{\n    A8 a;\n\n    -a;\n    -a[3];\n    -a[3, 4];\n    -a[];\n    -a[5 .. 6];\n    --a[3];\n}\n\n/**************************************/\n\nstruct A9\n{\n    int opOpAssign(string s)(int i)\n    {\n        printf(\"A.opOpAssign!(%.*s)\\n\", s.length, s.ptr);\n        return 0;\n    }\n\n    int opIndexOpAssign(string s, T)(int v, T i)\n    {\n        printf(\"A.opIndexOpAssign!(%.*s)(%d, %d)\\n\", s.length, s.ptr, v, i);\n        return 0;\n    }\n\n    int opIndexOpAssign(string s, T)(int v, T i, T j)\n    {\n        printf(\"A.opIndexOpAssign!(%.*s)(%d, %d, %d)\\n\", s.length, s.ptr, v, i, j);\n        return 0;\n    }\n\n    int opSliceOpAssign(string s)(int v)\n    {\n        printf(\"A.opSliceOpAssign!(%.*s)(%d)\\n\", s.length, s.ptr, v);\n        return 0;\n    }\n\n    int opSliceOpAssign(string s, T)(int v, T i, T j)\n    {\n        printf(\"A.opSliceOpAssign!(%.*s)(%d, %d, %d)\\n\", s.length, s.ptr, v, i, j);\n        return 0;\n    }\n}\n\n\nvoid test9()\n{\n    A9 a;\n\n    a += 8;\n    a -= 8;\n    a *= 8;\n    a /= 8;\n    a %= 8;\n    a &= 8;\n    a |= 8;\n    a ^= 8;\n    a <<= 8;\n    a >>= 8;\n    a >>>= 8;\n    a ~= 8;\n    a ^^= 8;\n\n    a[3] += 8;\n    a[3] -= 8;\n    a[3] *= 8;\n    a[3] /= 8;\n    a[3] %= 8;\n    a[3] &= 8;\n    a[3] |= 8;\n    a[3] ^= 8;\n    a[3] <<= 8;\n    a[3] >>= 8;\n    a[3] >>>= 8;\n    a[3] ~= 8;\n    a[3] ^^= 8;\n\n    a[3, 4] += 8;\n    a[] += 8;\n    a[5 .. 6] += 8;\n}\n\n/**************************************/\n\nstruct BigInt\n{\n    int opEquals(T)(T n) const\n    {\n        return 1;\n    }\n\n    int opEquals(T:int)(T n) const\n    {\n        return 1;\n    }\n\n    int opEquals(T:const(BigInt))(T n) const\n    {\n        return 1;\n    }\n\n}\n\nint decimal(BigInt b, const BigInt c)\n{\n    while (b != c) {\n    }\n    return 1;\n}\n\n/**************************************/\n\nstruct Foo10\n{\n    int opUnary(string op)() { return 1; }\n}\n\nvoid test10()\n{\n    Foo10 foo;\n    foo++;\n}\n\n/**************************************/\n\nstruct S4913\n{\n    bool opCast(T : bool)() { return true; }\n}\n\nint bug4913()\n{\n    if (S4913 s = S4913()) { return 83; }\n    return 9;\n}\n\nstatic assert(bug4913() == 83);\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5551\n\nstruct Foo11 {\n    Foo11 opUnary(string op:\"++\")() {\n        return this;\n    }\n    Foo11 opBinary(string op)(int y) {\n        return this;\n    }\n}\n\nvoid test11()\n{\n    auto f = Foo11();\n    f++;\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4099\n\nstruct X4099\n{\n    int x;\n    alias x this;\n\n    typeof(this) opUnary (string operator) ()\n    {\n        printf(\"operator called\\n\");\n        return this;\n    }\n}\n\nvoid test4099()\n{\n    X4099 x;\n    X4099 r1 = ++x; //operator called\n    X4099 r2 = x++; //BUG! (alias this used. returns int)\n}\n\n/**************************************/\n\nvoid test12()\n{\n    static int opeq;\n\n    // xopEquals OK\n    static struct S1a { const bool opEquals(    const typeof(this) rhs) { ++opeq; return false; } }\n    static struct S1b { const bool opEquals(ref const typeof(this) rhs) { ++opeq; return false; } }\n    static struct S1c { const bool opEquals(          typeof(this) rhs) { ++opeq; return false; } }\n\n    // xopEquals NG\n    static struct S2a {       bool opEquals(          typeof(this) rhs) { ++opeq; return false; } }\n\n    foreach (S; Seq!(S1a, S1b, S1c))\n    {\n        S s;\n        opeq = 0;\n        assert(s != s);                     // call opEquals directly\n        assert(!typeid(S).equals(&s, &s));  // -> xopEquals (-> __xopEquals) -> opEquals\n        assert(opeq == 2);\n    }\n\n    foreach (S; Seq!(S2a))\n    {\n        S s;\n        opeq = 0;\n        assert(s != s);\n        assert(thrown!Error(!typeid(S).equals(&s, &s)));\n            // Error(\"notImplemented\") thrown\n        assert(opeq == 1);\n    }\n}\n\n/**************************************/\n\nvoid test13()\n{\n    static int opeq;\n\n    struct X\n    {\n        const bool opEquals(const X){ ++opeq; return false; }\n    }\n    struct S\n    {\n        X x;\n    }\n\n    S makeS(){ return S(); }\n\n    S s;\n    opeq = 0;\n    assert(s != s);\n    assert(makeS() != s);\n    assert(s != makeS());\n    assert(makeS() != makeS());\n    assert(opeq == 4);\n\n    // built-in opEquals == const bool opEquals(const S rhs);\n    assert(s != s);\n    assert(opeq == 5);\n\n    // xopEquals\n    assert(!typeid(S).equals(&s, &s));\n    assert(opeq == 6);\n}\n\n/**************************************/\n\nvoid test14()\n{\n    static int opeq;\n\n    struct S\n    {\n        const bool opEquals(T)(const T rhs) { ++opeq; return false; }\n    }\n\n    S makeS(){ return S(); }\n\n    S s;\n    opeq = 0;\n    assert(s != s);\n    assert(makeS() != s);\n    assert(s != makeS());\n    assert(makeS() != makeS());\n    assert(opeq == 4);\n\n    // xopEquals (-> __xxopEquals) -> template opEquals\n    assert(!typeid(S).equals(&s, &s));\n    assert(opeq == 5);\n}\n\n/**************************************/\n\nvoid test15()\n{\n    struct S\n    {\n        const bool opEquals(T)(const(T) rhs)\n        if (!is(T == S))\n        { return false; }\n\n        @disable const bool opEquals(T)(const(T) rhs)\n        if (is(T == S))\n        { return false; }\n    }\n\n    S makeS(){ return S(); }\n\n    S s;\n    static assert(!__traits(compiles, s != s));\n    static assert(!__traits(compiles, makeS() != s));\n    static assert(!__traits(compiles, s != makeS()));\n    static assert(!__traits(compiles, makeS() != makeS()));\n\n    // xopEquals (-> __xxopEquals) -> Error thrown\n    assert(thrown!Error(!typeid(S).equals(&s, &s)));\n}\n\n/**************************************/\n\nvoid test16()\n{\n    struct X\n    {\n        int n;\n        const bool opEquals(T)(T t)\n        {\n            return false;\n        }\n    }\n    struct S\n    {\n        X x;\n    }\n\n    S s1, s2;\n    assert(s1 != s2);\n        // field template opEquals should call\n}\n\n/**************************************/\n\nvoid test17()\n{\n    static int opeq = 0;\n\n    struct S\n    {\n        bool opEquals(ref S rhs) { ++opeq; return false; }\n    }\n    S[] sa1 = new S[3];\n    S[] sa2 = new S[3];\n    assert(sa1 != sa2);     // isn't used TypeInfo.equals\n    assert(opeq == 1);\n\n    const(S)[] csa = new const(S)[3];\n    static assert(!__traits(compiles, csa == sa1));\n    static assert(!__traits(compiles, sa1 == csa));\n    static assert(!__traits(compiles, csa == csa));\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3789\n\nbool test3789()\n{\n    static struct Float\n    {\n        double x;\n    }\n    Float f;\n    assert(f.x != f.x); // NaN != NaN\n    assert(f != f);\n\n    static struct Array\n    {\n        int[] x;\n    }\n    Array a1 = Array([1,2,3].dup);\n    Array a2 = Array([1,2,3].dup);\n    if (!__ctfe)\n    {   // Currently doesn't work this in CTFE - may or may not a bug.\n        assert(a1.x !is a2.x);\n    }\n    assert(a1.x == a2.x);\n    assert(a1 == a2);\n\n    static struct AA\n    {\n        int[int] x;\n    }\n    AA aa1 = AA([1:1,2:2,3:3]);\n    AA aa2 = AA([1:1,2:2,3:3]);\n    if (!__ctfe)\n    {   // Currently doesn't work this in CTFE - may or may not a bug.\n        assert(aa1.x !is aa2.x);\n    }\n    if (!__ctfe)\n    {   // This is definitely a bug. Should work in CTFE.\n        assert(aa1.x == aa2.x);\n        assert(aa1 == aa2);\n    }\n\n    if (!__ctfe)\n    {   // Currently union operation is not supported in CTFE.\n        union U1\n        {\n            double x;\n        }\n        static struct UnionA\n        {\n            int[] a;\n            U1 u;\n        }\n        auto ua1 = UnionA([1,2,3]);\n        auto ua2 = UnionA([1,2,3]);\n        assert(ua1.u.x is ua2.u.x);\n        assert(ua1.u.x != ua2.u.x);\n        assert(ua1 == ua2);\n        ua1.u.x = 1.0;\n        ua2.u.x = 1.0;\n        assert(ua1.u.x is ua2.u.x);\n        assert(ua1.u.x == ua2.u.x);\n        assert(ua1 == ua2);\n        ua1.u.x = double.nan;\n        assert(ua1.u.x !is ua2.u.x);\n        assert(ua1.u.x !=  ua2.u.x);\n        assert(ua1 != ua2);\n\n        union U2\n        {\n            int[] a;\n        }\n        static struct UnionB\n        {\n            double x;\n            U2 u;\n        }\n        auto ub1 = UnionB(1.0);\n        auto ub2 = UnionB(1.0);\n        assert(ub1 == ub2);\n        ub1.u.a = [1,2,3].dup;\n        ub2.u.a = [1,2,3].dup;\n        assert(ub1.u.a !is ub2.u.a);\n        assert(ub1.u.a  == ub2.u.a);\n        assert(ub1 != ub2);\n        ub2.u.a = ub1.u.a;\n        assert(ub1.u.a is ub2.u.a);\n        assert(ub1.u.a == ub2.u.a);\n        assert(ub1 == ub2);\n    }\n\n    if (!__ctfe)\n    {   // This is definitely a bug. Should work in CTFE.\n        static struct Class\n        {\n            Object x;\n        }\n        static class X\n        {\n            override bool opEquals(Object o){ return true; }\n        }\n\n        Class c1a = Class(new Object());\n        Class c2a = Class(new Object());\n        assert(c1a.x !is c2a.x);\n        assert(c1a.x != c2a.x);\n        assert(c1a != c2a); // Pass, Object.opEquals works like bitwise compare\n\n        Class c1b = Class(new X());\n        Class c2b = Class(new X());\n        assert(c1b.x !is c2b.x);\n        assert(c1b.x == c2b.x);\n        assert(c1b == c2b); // Fails, should pass\n    }\n    return true;\n}\nstatic assert(test3789());\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10037\n\nstruct S10037\n{\n    bool opEquals(ref const S10037) { assert(0); }\n}\n\nstruct T10037\n{\n    S10037 s;\n    // Compiler should not generate 'opEquals' here implicitly:\n}\n\nstruct Sub10037(TL...)\n{\n    TL data;\n    int value;\n    alias value this;\n}\n\nvoid test10037()\n{\n    S10037 s;\n    T10037 t;\n    static assert( __traits(hasMember, S10037, \"opEquals\"));\n    static assert(!__traits(hasMember, T10037, \"opEquals\"));\n    assert(thrown!Error(s == s));\n    assert(thrown!Error(t == t));\n\n    Sub10037!(S10037) lhs;\n    Sub10037!(S10037) rhs;\n    static assert(!__traits(hasMember, Sub10037!(S10037), \"opEquals\"));\n    assert(lhs == rhs);     // lowered to: lhs.value == rhs.value\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5810\n\nstruct Bug5810\n{\n    void opUnary(string op)() {}\n}\n\nstruct Foo5810\n{\n    Bug5810 x;\n    void bar() { x++; }\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6798\n\nstruct Tuple6798(T...)\n{\n    T field;\n    alias field this;\n\n    bool opEquals(Tuple6798 rhs)\n    {\n        foreach (i, _; T)\n        {\n            if (this[i] != rhs[i])\n                return false;\n        }\n        return true;\n    }\n}\nauto tuple6798(T...)(T args)\n{\n    return Tuple6798!T(args);\n}\n\nint test6798a()\n{\n    //import std.typecons;\n    alias tuple6798 tuple;\n\n    static struct S1\n    {\n        auto opDollar(size_t dim)()\n        {\n            return 99;\n        }\n        auto opSlice(int dim)(int lwr, int upr)\n        {\n            return [dim, lwr, upr];\n        }\n\n        auto opIndex(A...)(A indices)\n        {\n            return tuple(\" []\", indices);\n        }\n        auto opIndexUnary(string op, A...)(A indices)\n        {\n            return tuple(op~\"[]\", indices);\n        }\n        auto opIndexAssign(A...)(string s, A indices)\n        {\n            return tuple(\"[] =\", s, indices);\n        }\n        auto opIndexOpAssign(string op, A...)(string s, A indices)\n        {\n            return tuple(\"[]\"~op~\"=\", s, indices);\n        }\n    }\n    S1 s1;\n    assert( s1[]       == tuple(\" []\"));\n    assert( s1[10]     == tuple(\" []\", 10));\n    assert( s1[10, 20] == tuple(\" []\", 10, 20));\n    assert( s1[10..20] == tuple(\" []\", [0, 10, 20]));\n    assert(+s1[]       == tuple(\"+[]\"));\n    assert(-s1[10]     == tuple(\"-[]\", 10));\n    assert(*s1[10, 20] == tuple(\"*[]\", 10, 20));\n    assert(~s1[10..20] == tuple(\"~[]\", [0, 10, 20]));\n    assert((s1[]       =\"x\") == tuple(\"[] =\", \"x\"));\n    assert((s1[10]     =\"x\") == tuple(\"[] =\", \"x\", 10));\n    assert((s1[10, 20] =\"x\") == tuple(\"[] =\", \"x\", 10, 20));\n    assert((s1[10..20] =\"x\") == tuple(\"[] =\", \"x\", [0, 10, 20]));\n    assert((s1[]      +=\"x\") == tuple(\"[]+=\", \"x\"));\n    assert((s1[10]    -=\"x\") == tuple(\"[]-=\", \"x\", 10));\n    assert((s1[10, 20]*=\"x\") == tuple(\"[]*=\", \"x\", 10, 20));\n    assert((s1[10..20]~=\"x\") == tuple(\"[]~=\", \"x\", [0, 10, 20]));\n    assert( s1[20..30, 10]           == tuple(\" []\", [0, 20, 30], 10));\n    assert( s1[10, 10..$, $-4, $..2] == tuple(\" []\", 10, [1,10,99], 99-4, [3,99,2]));\n    assert(+s1[20..30, 10]           == tuple(\"+[]\", [0, 20, 30], 10));\n    assert(-s1[10, 10..$, $-4, $..2] == tuple(\"-[]\", 10, [1,10,99], 99-4, [3,99,2]));\n    assert((s1[20..30, 10]           =\"x\") == tuple(\"[] =\", \"x\", [0, 20, 30], 10));\n    assert((s1[10, 10..$, $-4, $..2] =\"x\") == tuple(\"[] =\", \"x\", 10, [1,10,99], 99-4, [3,99,2]));\n    assert((s1[20..30, 10]          +=\"x\") == tuple(\"[]+=\", \"x\", [0, 20, 30], 10));\n    assert((s1[10, 10..$, $-4, $..2]-=\"x\") == tuple(\"[]-=\", \"x\", 10, [1,10,99], 99-4, [3,99,2]));\n\n    // opIndex exist, but opSlice for multi-dimensional doesn't.\n    static struct S2\n    {\n        auto opSlice(size_t dim)() { return [dim]; }\n        auto opSlice()(size_t lwr, size_t upr) { return [lwr, upr]; }\n\n        auto opIndex(A...)(A indices){ return [[indices]]; }\n    }\n    S2 s2;\n    assert(s2[] == [[]]);\n    assert(s2[1] == [[1]]);\n    assert(s2[1, 2] == [[1, 2]]);\n    assert(s2[1..2] == [1, 2]);\n    static assert(!__traits(compiles, s2[1, 2..3] ));\n    static assert(!__traits(compiles, s2[1..2, 2..3] ));\n\n    // opSlice for multi-dimensional exists, but opIndex for that doesn't.\n    static struct S3\n    {\n        auto opSlice(size_t dim)(size_t lwr, size_t upr) { return [lwr, upr]; }\n\n        auto opIndex(size_t n){ return [[n]]; }\n        auto opIndex(size_t n, size_t m){ return [[n, m]]; }\n    }\n    S3 s3;\n    static assert(!__traits(compiles, s3[] ));\n    assert(s3[1]    == [[1]]);\n    assert(s3[1, 2] == [[1, 2]]);\n    static assert(!__traits(compiles, s3[1..2] ));\n    static assert(!__traits(compiles, s3[1, 2..3] ));\n    static assert(!__traits(compiles, s3[1..2, 2..3] ));\n\n    return 0;\n}\n\nint test6798b()\n{\n    static struct Typedef(T)\n    {\n        private T Typedef_payload = T.init;\n\n        alias a = Typedef_payload;\n\n        auto ref opIndex(this X, D...)(auto ref D i)    { return a[i]; }\n        auto ref opSlice(this X      )()                { return a[]; }\n        auto ref opSlice(this X, B, E)(auto ref B b, auto ref E e)\n        {\n            assert(b == 0 && e == 3);\n            return a[b..e];\n        }\n\n        template opDispatch(string name)\n        {\n            // field or property function\n            @property auto ref opDispatch(this X)()                { return mixin(\"a.\"~name);        }\n            @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin(\"a.\"~name~\" = v\"); }\n        }\n\n        static if (is(typeof(a) : E[], E))\n        {\n            auto opDollar() const { return a.length; }\n        }\n    }\n\n    Typedef!(int[]) dollar2;\n    dollar2.length = 3;\n    assert(dollar2.Typedef_payload.length == 3);\n    assert(dollar2[0 .. $] is dollar2[0 .. 3]);\n\n    return 0;\n}\n\nint test6798c()\n{\n    alias T = Tuple6798!(int, int);\n    auto n = T[].init;\n    static assert(is(typeof(n[0]) == Tuple6798!(int, int)));\n\n    return 0;\n}\n\nvoid test6798()\n{\n    static assert(test6798a() == 0);    // CTFE check\n    test6798a();\n    static assert(test6798b() == 0);\n    test6798b();\n    static assert(test6798c() == 0);\n    test6798c();\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12382\n\nstruct S12382\n{\n    size_t opDollar() { return 0; }\n    size_t opIndex(size_t) { return 0; }\n}\n\nS12382 func12382() { return S12382(); }\n\nstatic assert(S12382.init[$] == 0);\nstatic assert(func12382()[$] == 0);\nenum e12382a = S12382.init[$];\nenum e12382b = func12382()[$];\nstatic v12382a = S12382.init[$];\nstatic v12382b = func12382()[$];\n\nvoid test12382()\n{\n    static assert(S12382.init[$] == 0);\n    static assert(func12382()[$] == 0);\n    enum e12382a = S12382.init[$];\n    enum e12382b = func12382()[$];\n    static v12382a = S12382.init[$];\n    static v12382b = func12382()[$];\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12904\n\nstruct S12904\n{\n    void opIndexAssign(U, A...)(U value, A args)\n    {\n        static assert(0);\n    }\n    void opSliceAssign(int n)\n    {\n        assert(n == 10);\n    }\n\n    size_t opDollar(size_t dim)()\n    {\n        return 7;\n    }\n\n    int opSlice(size_t dim)(size_t, size_t to)\n    {\n        assert(to == 7);\n        return 1;\n    }\n\n    int opIndex(int i1, int i2)\n    {\n        assert(i1 == 1 && i2 == 1);\n        return 10;\n    }\n}\n\nvoid test12904()\n{\n    S12904 s;\n    s[] = s[0..$, 1];\n    s[] = s[0..$, 0..$];\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7641\n\nmixin template Proxy7641(alias a)\n{\n    auto ref opBinaryRight(string op, B)(auto ref B b)\n    {\n        return mixin(\"b \"~op~\" a\");\n    }\n}\nstruct Typedef7641(T)\n{\n    private T Typedef_payload;\n\n    this(T init)\n    {\n        Typedef_payload = init;\n    }\n\n    mixin Proxy7641!Typedef_payload;\n}\n\nvoid test7641()\n{\n    class C {}\n    C c1 = new C();\n    auto a = Typedef7641!C(c1);\n    static assert(!__traits(compiles, { C c2 = a; }));\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8434\n\nvoid test8434()\n{\n    static class Vector2D(T)\n    {\n        T x, y;\n\n        this(T x, T y) {\n            this.x = x;\n            this.y = y;\n        }\n\n        U opCast(U)() const { assert(0); }\n    }\n\n    alias Vector2D!(short) Vector2s;\n    alias Vector2D!(float) Vector2f;\n\n    Vector2s vs1 = new Vector2s(42, 23);\n    Vector2s vs2 = new Vector2s(42, 23);\n\n    assert(vs1 != vs2);\n}\n\n/**************************************/\n\nvoid test18()\n{\n    // one dimensional indexing\n    static struct IndexExp\n    {\n        int[] opIndex(int a)\n        {\n            return [a];\n        }\n\n        int[] opIndexUnary(string op)(int a)\n        {\n            return [a];\n        }\n\n        int[] opIndexAssign(int val, int a)\n        {\n            return [val, a];\n        }\n\n        int[] opIndexOpAssign(string op)(int val, int a)\n        {\n            return [val, a];\n        }\n\n        int opDollar()\n        {\n            return 8;\n        }\n    }\n\n    IndexExp index;\n    // opIndex\n    assert(index[8]     == [8]);\n    assert(index[$]     == [8]);\n    assert(index[$-1]   == [7]);\n    assert(index[$-$/2] == [4]);\n    // opIndexUnary\n    assert(-index[8]     == [8]);\n    assert(-index[$]     == [8]);\n    assert(-index[$-1]   == [7]);\n    assert(-index[$-$/2] == [4]);\n    // opIndexAssign\n    assert((index[8]     = 2) == [2, 8]);\n    assert((index[$]     = 2) == [2, 8]);\n    assert((index[$-1]   = 2) == [2, 7]);\n    assert((index[$-$/2] = 2) == [2, 4]);\n    // opIndexOpAssign\n    assert((index[8]     += 2) == [2, 8]);\n    assert((index[$]     += 2) == [2, 8]);\n    assert((index[$-1]   += 2) == [2, 7]);\n    assert((index[$-$/2] += 2) == [2, 4]);\n\n    // opDollar is only one-dimensional\n    static assert(!is(typeof(index[$, $])));\n    static assert(!is(typeof(-index[$, $])));\n    static assert(!is(typeof(index[$, $] = 2)));\n    static assert(!is(typeof(index[$, $] += 2)));\n\n    // multi dimensional indexing\n    static struct ArrayExp\n    {\n        int[] opIndex(int a, int b)\n        {\n            return [a, b];\n        }\n\n        int[] opIndexUnary(string op)(int a, int b)\n        {\n            return [a, b];\n        }\n\n        int[] opIndexAssign(int val, int a, int b)\n        {\n            return [val, a, b];\n        }\n\n        int[] opIndexOpAssign(string op)(int val, int a, int b)\n        {\n            return [val, a, b];\n        }\n\n        int opDollar(int dim)()\n        {\n            return dim;\n        }\n    }\n\n    ArrayExp array;\n    // opIndex\n    assert(array[8, 8]     == [8, 8]);\n    assert(array[$, $]     == [0, 1]);\n    assert(array[$, $-1]   == [0, 0]);\n    assert(array[2, $-$/2] == [2, 1]);\n    // opIndexUnary\n    assert(-array[8, 8]     == [8, 8]);\n    assert(-array[$, $]     == [0, 1]);\n    assert(-array[$, $-1]   == [0, 0]);\n    assert(-array[2, $-$/2] == [2, 1]);\n    // opIndexAssign\n    assert((array[8, 8]      = 2) == [2, 8, 8]);\n    assert((array[$, $]      = 2) == [2, 0, 1]);\n    assert((array[$, $-1]    = 2) == [2, 0, 0]);\n    assert((array[2, $-$/2]  = 2) == [2, 2, 1]);\n    // opIndexOpAssign\n    assert((array[8, 8]      += 2) == [2, 8, 8]);\n    assert((array[$, $]      += 2) == [2, 0, 1]);\n    assert((array[$, $-1]    += 2) == [2, 0, 0]);\n    assert((array[2, $-$/2]  += 2) == [2, 2, 1]);\n\n    // one dimensional slicing\n    static struct SliceExp\n    {\n        int[] opSlice(int a, int b)\n        {\n            return [a, b];\n        }\n\n        int[] opSliceUnary(string op)(int a, int b)\n        {\n            return [a, b];\n        }\n\n        int[] opSliceAssign(int val, int a, int b)\n        {\n            return [val, a, b];\n        }\n\n        int[] opSliceOpAssign(string op)(int val, int a, int b)\n        {\n            return [val, a, b];\n        }\n\n        int opDollar()\n        {\n            return 8;\n        }\n    }\n\n    SliceExp slice;\n    // opSlice\n    assert(slice[0 .. 8]     == [0, 8]);\n    assert(slice[0 .. $]     == [0, 8]);\n    assert(slice[0 .. $-1]   == [0, 7]);\n    assert(slice[$-3 .. $-1] == [5, 7]);\n    // opSliceUnary\n    assert(-slice[0 .. 8]     == [0, 8]);\n    assert(-slice[0 .. $]     == [0, 8]);\n    assert(-slice[0 .. $-1]   == [0, 7]);\n    assert(-slice[$-3 .. $-1] == [5, 7]);\n    // opSliceAssign\n    assert((slice[0 .. 8]     = 2) == [2, 0, 8]);\n    assert((slice[0 .. $]     = 2) == [2, 0, 8]);\n    assert((slice[0 .. $-1]   = 2) == [2, 0, 7]);\n    assert((slice[$-3 .. $-1] = 2) == [2, 5, 7]);\n    // opSliceOpAssign\n    assert((slice[0 .. 8]     += 2) == [2, 0, 8]);\n    assert((slice[0 .. $]     += 2) == [2, 0, 8]);\n    assert((slice[0 .. $-1]   += 2) == [2, 0, 7]);\n    assert((slice[$-3 .. $-1] += 2) == [2, 5, 7]);\n\n    // test different kinds of opDollar\n    auto dollar(string opDollar)()\n    {\n        static struct Dollar\n        {\n            size_t opIndex(size_t a) { return a; }\n            mixin(opDollar);\n        }\n        Dollar d;\n        return d[$];\n    }\n    assert(dollar!q{@property size_t opDollar() { return 8; }}() == 8);\n    assert(dollar!q{template opDollar(size_t dim) { enum opDollar = dim; }}() == 0);\n    assert(dollar!q{static const size_t opDollar = 8;}() == 8);\n    assert(dollar!q{enum opDollar = 8;}() == 8);\n    assert(dollar!q{size_t length() { return 8; } alias length opDollar;}() == 8);\n}\n\n/**************************************/\n\nvoid test19()\n{\n    static struct Foo\n    {\n        int[] opSlice(int a, int b)\n        {\n            return [a, b];\n        }\n\n        int opDollar(int dim)()\n        {\n            return dim;\n        }\n    }\n\n    Foo foo;\n    assert(foo[0 .. $] == [0, 0]);\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9453\n\nstruct Foo9453\n{\n    static int ctor = 0;\n\n    this(string bar) { ++ctor; }\n\n    void opIndex(size_t i) const {}\n    void opSlice(size_t s, size_t e) const {}\n\n    size_t opDollar(int dim)() const if (dim == 0) { return 1; }\n}\n\nvoid test9453()\n{\n    assert(Foo9453.ctor == 0);  Foo9453(\"bar\")[$-1];\n    assert(Foo9453.ctor == 1);  Foo9453(\"bar\")[0..$];\n    assert(Foo9453.ctor == 2);\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9496\n\nstruct S9496\n{\n    static S9496* ptr;\n\n    size_t opDollar()\n    {\n        assert(ptr is &this);\n        return 10;\n    }\n    void opSlice(size_t , size_t)\n    {\n        assert(ptr is &this);\n    }\n    void getSlice()\n    {\n        assert(ptr is &this);\n        this[1 .. opDollar()];\n        this[1 .. $];\n    }\n}\n\nvoid test9496()\n{\n    S9496 s;\n    S9496.ptr = &s;\n    s.getSlice();\n    s[1 .. $];\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9689\n\nstruct B9689(T)\n{\n    T val;\n    @disable this(this);\n\n    bool opEquals(this X, B)(auto ref B b)\n    {\n        //pragma(msg, \"+\", X, \", B = \", B, \", ref = \", __traits(isRef, b));\n        return this.val == b.val;\n        //pragma(msg, \"-\", X, \", B = \", B, \", ref = \", __traits(isRef, b));\n    }\n}\n\nstruct S9689\n{\n    B9689!int num;\n}\n\nvoid test9689()\n{\n    B9689!S9689 b;\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9694\n\nstruct S9694\n{\n    bool opEquals(ref S9694 rhs)\n    {\n        assert(0);\n    }\n}\nstruct T9694\n{\n    S9694 s;\n}\nvoid test9694()\n{\n    T9694 t;\n    assert(thrown!Error(typeid(T9694).equals(&t, &t)));\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10064\n\nvoid test10064()\n{\n    static struct S\n    {\n        int x = 3;\n\n        @disable this();\n\n        this(int)\n        { x = 7; }\n\n        int opSlice(size_t, size_t)\n        { return 0; }\n\n        @property size_t opDollar()\n        {\n            assert(x == 7 || x == 3); // fails\n            assert(x == 7);\n            return 0;\n        }\n    }\n    auto x = S(0)[0 .. $];\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12585\n\nvoid test12585()\n{\n    struct Bar\n    {\n        int opIndex(size_t index)\n        {\n            return 0;\n        }\n    }\n\n    struct Foo\n    {\n        Bar opIndex(size_t index)\n        {\n            throw new Exception(\"Fail\");\n        }\n    }\n\n    Foo foo()\n    {\n        return Foo();\n    }\n\n    void catchStuff(E)(lazy E expression)\n    {\n        try\n            expression();\n        catch (Exception e) {}\n    }\n\n    catchStuff(foo()[0][0]);          // OK <- NG\n    catchStuff(foo().opIndex(0)[0]);  // OK\n    catchStuff(foo()[0].opIndex(0));  // OK\n    Foo f; catchStuff(f[0][0]);       // OK\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10394\n\nvoid test10394()\n{\n    alias Seq!(int, int) Pair;\n    Pair pair;\n\n    struct S1\n    {\n        int opBinary(string op)(Pair) { return 1;  }\n        bool opEquals(Pair) { return true; }\n        int opOpAssign(string op)(Pair) { return 1; }\n    }\n    S1 s1;\n    assert((s1 + pair) == 1);\n    assert((s1 == pair) == true);\n    assert((s1 *= pair) == 1);\n\n    struct S2\n    {\n        int opBinaryRight(string op)(Pair lhs) { return 1;  }\n        int opCmp(Pair) { return -1; }\n    }\n    S2 s2;\n    assert((pair in s2) == 1);\n    assert(s2 < pair);\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10597\n\nstruct R10597\n{\n    void opIndex(int) {}\n    void opSlice(int, int) {}\n    int opDollar();\n}\nR10597 r;\n\nstruct S10597\n{\n    static assert(is(typeof(r[0]))); //ok\n    static assert(is(typeof(r[$]))); //fails\n\n    static assert(is(typeof(r[0..0]))); //ok\n    static assert(is(typeof(r[$..$]))); //fails\n\n    void foo()\n    {\n        static assert(is(typeof(r[0]))); //ok\n        static assert(is(typeof(r[$]))); //ok\n\n        static assert(is(typeof(r[0..0]))); //ok\n        static assert(is(typeof(r[$..$]))); //ok\n    }\n}\n\nstatic assert(is(typeof(r[0]))); //ok\nstatic assert(is(typeof(r[$]))); //fails\n\nstatic assert(is(typeof(r[0..0]))); //ok\nstatic assert(is(typeof(r[$..$]))); //fails\n\nvoid test10597()\n{\n    static assert(is(typeof(r[0]))); //ok\n    static assert(is(typeof(r[$]))); //ok\n\n    static assert(is(typeof(r[0..0]))); //ok\n    static assert(is(typeof(r[$..$]))); //ok\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10567\n\n// doesn't require thunk\nstruct S10567x1n { int value; int opCmp(ref const S10567x1n rhs) const { return 0; } }\n\n// requires thunk\nstruct S10567y1n { int value; int opCmp(const S10567y1n rhs) const { return 0; } }\nstruct S10567y1t { int value; int opCmp(S)(const S rhs) const { return 0; } }\n\n// doesn't support const comparison\nstruct S10567z1n { int value; int opCmp(const S10567z1n rhs) { return 0; } }\nstruct S10567z1t { int value; int opCmp(S)(const S rhs) { return 0; } }\n\n/+\nstruct S10567x2n { S10567x1n s; this(int n) { s = typeof(s)(n); } alias s this; }\n\nstruct S10567y2n { S10567y1n s; this(int n) { s = typeof(s)(n); } alias s this; }\nstruct S10567y2t { S10567y1t s; this(int n) { s = typeof(s)(n); } alias s this; }\n\nstruct S10567z2n { S10567z1n s; this(int n) { s = typeof(s)(n); } alias s this; }\nstruct S10567z2t { S10567z1t s; this(int n) { s = typeof(s)(n); } alias s this; }\n\nstruct S10567d1\n{\n    int value;\n    int opDispatch(string name, S)(const S rhs) const if (name == \"opCmp\")\n    { assert(0); }\n}\nstruct S10567d2\n{\n    int value;\n    template opDispatch(string name) if (name == \"opCmp\")\n    {\n        int opDispatch(const S rhs) const\n        { assert(0); }\n    }\n}\n\n// recursive alias this + opCmp searching\nstruct S10567r1\n{\n    static S10567r2 t;\n    ref S10567r2 payload() { return t; }\n    alias payload this;\n\n    int opCmp(const S10567r1 s) const { return 0; }\n}\nstruct S10567r2\n{\n    static S10567r1 s;\n    ref S10567r1 payload() { return s; }\n    alias payload this;\n}\n+/\n\nvoid test10567()\n{\n    foreach (S; Seq!(S10567x1n/+, S10567x2n+/))\n    {\n        S sx = S(1);\n        S sy = S(2);\n        assert(!(sx < sy) && !(sx > sy));\n        assert(sx.opCmp(sy) == 0);\n\n        assert(typeid(S).compare(&sx, &sy) == 0);\n        static if (is(S == S10567x1n))\n            assert(cast(void*)typeid(S).xopCmp == cast(void*)&S.opCmp, S.stringof);\n    }\n\n    foreach (S; Seq!(S10567y1n, S10567y1t/+, S10567y2n, S10567y2t+/))\n    {\n        S sx = S(1);\n        S sy = S(2);\n        assert(!(sx < sy) && !(sx > sy));\n        assert(sx.opCmp(sy) == 0);\n\n        assert(typeid(S).compare(&sx, &sy) == 0);\n    }\n\n    foreach (S; Seq!(S10567z1n, S10567z1t/+, S10567z2n, S10567z2t+/))\n    {\n        S sx = S(1);\n        S sy = S(2);\n        assert(!(sx < sy) && !(sx > sy));\n        assert(sx.opCmp(sy) == 0);\n\n        try\n        {\n            auto x = typeid(S).compare(&sx, &sy);\n            assert(0);\n        }\n        catch (Error e) { assert(e.msg[$-15 .. $] == \"not implemented\"); }\n    }\n/+\n    foreach (S; Seq!(S10567d1, S10567d2))\n    {\n        int[S] aa;\n        aa[S(1)] = 10;  aa[S(1)] = 1;\n        aa[S(2)] = 20;  aa[S(2)] = 2;\n        assert(aa.length == 2);\n        foreach (k, v; aa)\n            assert(k.value == v);\n\n        S sx = S(1);\n        S sy = S(2);\n\n        // Don't invoke opDispatch!\"opCmp\"\n        assert(typeid(S).compare(&sx, &sy) != 0);\n    }\n+/\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11062\n\nstruct S11062ia\n{\n    struct S1\n    {\n        void opIndexAssign(int val, int key) {}\n    }\n    struct S2\n    {\n        S1 headers;\n    }\n\n    private S2 m_obj;\n    @property S2 get() { return m_obj; }\n    alias get this;\n}\n\nstruct S11062sa\n{\n    struct S1\n    {\n        void opSliceAssign(int val, int lwr, int upr) {}\n    }\n    struct S2\n    {\n        S1 headers;\n    }\n\n    private S2 m_obj;\n    @property S2 get() { return m_obj; }\n    alias get this;\n}\n\nvoid test11062()\n{\n    auto sia = S11062ia();\n    sia.headers[1] = 1;     // bug\n\n    auto ssa = S11062sa();\n    ssa.headers[1..2] = 1;  // bug\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11311\n\nvoid test11311()\n{\n    static int ctor, cpctor, dtor;\n\n    static struct S\n    {\n        this(int)  { ++ctor; }\n        this(this) { ++cpctor; }\n        ~this()    { ++dtor; }\n    }\n    static struct Arr\n    {\n        S data;\n        ref S opIndex(int) return { return data; }\n        ref S opSlice(int, int) return { return data; }\n    }\n\n    {\n        Arr a = Arr(S(1));\n        assert(ctor == 1);\n        assert(cpctor == 0);\n        assert(dtor == 0);\n\n        auto getA1() { return a; }\n      //getA1().opIndex(1);  // OK\n        getA1()[1];          // NG\n\n        assert(ctor == 1);\n        assert(cpctor == 1);  // getA() returns a copy of a\n        assert(dtor == 1);    // temporary returned by getA() should be destroyed\n    }\n    assert(dtor == 2);\n    assert(ctor + cpctor == dtor);\n\n    ctor = cpctor = dtor = 0;\n\n    {\n        Arr a = Arr(S(1));\n        assert(ctor == 1);\n        assert(cpctor == 0);\n        assert(dtor == 0);\n\n        auto getA2() { return a; }\n      //getA2().opSlice(1, 2);  // OK\n        getA2()[1..2];          // NG\n\n        assert(ctor == 1);\n        assert(cpctor == 1);  // getA() returns a copy of a\n        assert(dtor == 1);    // temporary returned by getA() should be destroyed\n    }\n    assert(dtor == 2);\n    assert(ctor + cpctor == dtor);\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12193\n\nvoid test12193()\n{\n    struct Foo\n    {\n        bool bar;\n        alias bar this;\n        void opOpAssign(string op)(size_t x)\n        {\n            bar = false;\n        }\n    }\n\n    Foo foo;\n    foo <<= 1;\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14057\n\nstruct W14057\n{\n    int[] subType;\n    alias subType this;\n\n    W14057 opSlice(size_t, size_t)\n    {\n        return this;\n    }\n}\n\nvoid test14057()\n{\n    auto w = W14057();\n    W14057 w2 = w[0 .. 1337];\n}\n\n/**************************************/\n\nstruct Tuple20(T...) { T field; alias field this; }\n\nvoid test20a()\n{\n    // ae1save in in AssignExp::semantic\n    int a, b;\n\n    struct A1\n    {\n        void opIndexAssign(int v, Tuple20!(int, int) ) { a = v; }\n        Tuple20!(int, int) opSlice(size_t dim)(int, int) { return typeof(return).init; }\n    }\n    struct A2\n    {\n        A1 a1;\n        alias a1 this;\n        int opIndexAssign(int) { return b; }\n    }\n\n    stompStack();\n    A2 foo() { return A2(); }\n    foo()[1..2] = 1;\n    // ref A1 __tmp = foo().a1; __tmp.opIndexAssign(1, __tmp.opSlice!0(1, 2));\n    assert(a == 1);     // should work\n    assert(b == 0);\n}\n\nvoid test20b()\n{\n    // ae1save in UnaExp::op_overload()\n    int a, b;\n\n    struct A1\n    {\n        void opIndexUnary(string op)(Tuple20!(int, int) ) { a = 1; }\n        Tuple20!(int, int) opSlice(size_t dim)(int, int) { return typeof(return).init; }\n        void dummy() {} // nessary to make A1 nested struct\n    }\n    struct A2\n    {\n        A1 a1;\n        alias a1 this;\n        int opIndexUnary(string op)(int) { return 0; }\n    }\n\n    stompStack();\n    A2 foo() { return A2(); }\n    +foo()[1..2];\n    // ref A1 __tmp = foo().a1; __tmp.opIndexUnary!\"+\"(__tmp.opSlice!0(1, 2));\n    assert(a == 1);     // should pass\n    assert(b == 0);\n}\n\nvoid test20c()\n{\n    // ae1save in ArrayExp::op_overload()\n    int a, b;\n\n    struct A1\n    {\n        void opIndex(Tuple20!(int, int) ) { a = 1; }\n        Tuple20!(int, int) opSlice(size_t dim)(int, int) { return typeof(return).init; }\n    }\n    struct A2\n    {\n        A1 a1;\n        alias a1 this;\n        int opIndex(int) { return 0; }\n    }\n\n    stompStack();\n    A2 foo() { return A2(); }\n    foo()[1..2];\n    // ref A1 __tmp = foo().a1; __tmp.opIndex(__tmp.opSlice!0(1, 2));\n    assert(a == 1);     // should pass\n    assert(b == 0);\n}\n\nvoid test20d()\n{\n    // ae1save in BinAssignExp::op_overload()\n    int a, b;\n\n    struct A1\n    {\n        void opIndexOpAssign(string op)(int v, Tuple20!(int, int) ) { a = v; }\n        Tuple20!(int, int) opSlice(size_t dim)(int, int) { return typeof(return).init; }\n        void dummy() {} // nessary to make A1 nested struct\n    }\n    struct A2\n    {\n        A1 a1;\n        alias a1 this;\n        ref int opIndexOpAssign(alias op)(int) { return b; }\n    }\n\n    stompStack();\n    A2 foo() { return A2(); }\n    foo()[1..2] += 1;\n    // ref A1 __tmp = foo().a1; __tmp.opIndexOpAssign!\"+\"(1, __tmp.opSlice!0(1, 2));\n    assert(a == 1);     // should pass\n    assert(b == 0);\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14624\n\nvoid test14624()\n{\n    struct A1\n    {\n        int x;\n        ref int opIndex() return { return x; }\n        ref int opSlice() { assert(0); }\n    }\n    {\n        A1 a = A1(1);\n        auto x = a[];       // a.opIndex()\n        assert(x == a.x);\n        auto y = -a[];      // -a.opIndex()        <-- not found: a.opIndexUnary!\"-\"\n        assert(y == -a.x);\n        a[] = 1;            // a.opIndex() = 1;    <-- not found: a.opIndexAssign(int)\n        assert(a.x == 1);\n        a[] += 1;           // a.opIndex() += 1;   <-- not found: a.opIndexOpAssign!\"+\"(int)\n        assert(a.x == 2);\n    }\n\n    struct A2\n    {\n        int x;\n        ref int opIndex() return               { x = 10; return x; }\n        ref int opSlice() { assert(0); }\n        ref int opSliceUnary(alias op)()       { x = 11; return x; }\n        ref int opSliceAssign(int) return      { x = 12; return x; }\n        ref int opSliceOpAssign(alias op)(int) { x = 13; return x; }\n    }\n    {\n        A2 a = A2(1);\n        auto x = a[];       // a.opIndex()\n        assert(a.x == 10);\n        auto y = -a[];      // a.opSliceUnary!\"-\"()     is preferred than: -a.opIndex()\n        assert(a.x == 11);\n        a[] = 1;            // a.opSliceAssign(1)       is preferred than: a.opIndex() = 1;\n        assert(a.x == 12);\n        a[] += 1;           // a.opSliceOpAssign!\"+\"(1) is preferred than: a.opIndex() += 1;\n        assert(a.x == 13);\n    }\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14625\n\nvoid test14625()\n{\n    struct R\n    {\n        @property bool empty() { return true; }\n        @property int front() { return 0; }\n        void popFront() {}\n    }\n\n    struct C1\n    {\n        R opIndex() { return R(); }\n        R opSlice() { assert(0); }\n    }\n    C1 c1;\n    foreach (e; c1) {}      // OK <- asserts in opSlice()\n    foreach (e; c1[]) {}    // OK, opIndex()\n\n    struct C2\n    {\n        R opIndex() { return R(); }\n    }\n    C2 c2;\n    foreach (e; c2) {}      // OK <- rejected\n    foreach (e; c2[]) {}    // OK, opIndex()\n}\n\n/**************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test4099();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test3789();\n    test10037();\n    test6798();\n    test12904();\n    test7641();\n    test8434();\n    test18();\n    test19();\n    test9453();\n    test9496();\n    test9689();\n    test9694();\n    test10064();\n    test12585();\n    test10394();\n    test10567();\n    test11062();\n    test11311();\n    test14057();\n    test20a();\n    test20b();\n    test20c();\n    test20d();\n    test14624();\n    test14625();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/opover3.d",
    "content": "\nvoid test1()\n{\n    static struct Foo1\n    {\n    }\n\n    Foo1 foo1;\n    Foo1 foo1_2 = Foo1();       // literal syntax\n\n    static assert(!__traits(compiles, foo1()));\n}\n\n/**************************************/\n\nvoid test2()\n{\n    static struct Foo2\n    {\n        this(int n){}\n    }\n\n    Foo2 foo2;\n    Foo2 foo2_2 = Foo2(1);      // user ctor call\n    Foo2 foo2_3 = Foo2();       // literal syntax\n\n    static assert(!__traits(compiles, foo2(1)));\n    static assert(!__traits(compiles, foo2()));\n}\n\n/**************************************/\n\nvoid test2a()\n{\n    static struct Foo2a // alternation of Foo2\n    {\n        static Foo2a opCall(int n){ Foo2a foo2a; return foo2a; }\n    }\n\n    Foo2a foo2a;\n    Foo2a foo2a_3 = Foo2a(1);                       // static opCall\n    static assert(!__traits(compiles, Foo2a()));    // static opCall hides literal syntax.\n\n    foo2a(1);                                       // static opCall from instance\n    static assert(!__traits(compiles, foo2a()));\n}\n\n/**************************************/\n\nvoid test2c()\n{\n    static struct Foo2c // conflict version\n    {\n        this(int n){}\n        static Foo2c opCall(int n, int m){ Foo2c foo2c; return foo2c; }\n    }\n\n    Foo2c foo2c;\n    Foo2c foo2c_2 = Foo2c(1);                       // user ctor call\n    static assert(!__traits(compiles, Foo2c(1,2))); // user ctor hides static opCall.\n    Foo2c foo2c_3 = Foo2c();                        // literal syntax\n\n    static assert(!__traits(compiles, foo2c(1)));\n    foo2c(1,2);                                     // static opCall from instance\n    static assert(!__traits(compiles, foo2c()));\n}\n\n/**************************************/\n\nvoid test3()\n{\n    static struct Foo3\n    {\n        this(int n){}\n        int opCall(int n){ return 0; }\n    }\n\n    Foo3 foo3;\n    Foo3 foo3_2 = Foo3();                           // literal syntax (default construction)\n    Foo3 foo3_3 = Foo3(1);                          // user ctor call\n\n    assert(foo3(1) == 0);                           // instance opCall\n    static assert(!__traits(compiles, foo3()));\n}\n\n/**************************************/\n\nvoid test3c()\n{\n    static struct Foo3c\n    {\n        this(int n){}\n        static Foo3c opCall(int n, int m){ Foo3c foo3c; return foo3c; }\n        int opCall(int n){ return 0; }\n    }\n\n    Foo3c foo3c;\n    Foo3c foo3c_2 = Foo3c();                        // literal syntax (default construction)\n    Foo3c foo3c_3 = Foo3c(1);                       // user ctor call\n    static assert(!__traits(compiles, Foo3c(1,2))); // user ctor hides static opCall\n\n    assert(foo3c(1,2) == Foo3c.init);               // static opCall from instance\n    assert(foo3c(1) == 0);                          // instance opCall\n    static assert(!__traits(compiles, foo3c()));\n}\n\n/**************************************/\n\nvoid test4()\n{\n    static struct Foo4\n    {\n        static Foo4 opCall(int n, int m){ Foo4 foo4; return foo4; }\n        int opCall(int n){ return 0; }\n    }\n\n    Foo4 foo4;\n    Foo4 foo4_4 = Foo4(1,2);                        // static opCall\n    static assert(!__traits(compiles, Foo4(1)));\n    static assert(!__traits(compiles, Foo4()));     // static opCall without constructor hides literal syntax\n\n    assert(foo4(1,2) == Foo4.init);                 // static opCall from instance\n    assert(foo4(1) == 0);                           // instance opCall\n    static assert(!__traits(compiles, foo4()));\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12070\n\nvoid test12070()\n{\n    static string result;\n\n    struct S\n    {\n        this(T...)(T)\n        {\n            result ~= \"c\" ~ cast(char)('0' + T.length);\n        }\n\n        void opCall(A...)(A)\n        {\n            result ~= \"x\" ~ cast(char)('0' + A.length);\n        }\n    }\n\n    auto s0 = S();\n    s0();\n    s0(1);\n    s0(1, 2);\n    assert(result == \"x0x1x2\");\n\n    result = null;\n\n    auto s1 = S(1);\n    s1();\n    s1('a');\n    s1('a', 'b');\n    assert(result == \"c1x0x1x2\");\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12124\n\nstruct S12124\n{\n    this(int) {}\n    S12124 opCall()() { static assert(0); }\n    // speculative opCall instantiation for diagnostic message should not cause false errors\n}\n\n/**************************************/\n\nvoid main()\n{\n    test1();\n    test2();\n    test2a();\n    test2c();\n    test3();\n    test3c();\n    test4();\n    test12070();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/overload.d",
    "content": "// EXTRA_SOURCES: imports/ovs1528a.d imports/ovs1528b.d imports/template_ovs1.d imports/template_ovs2.d imports/template_ovs3.d\n\nimport imports.template_ovs1;\nimport imports.template_ovs2;\nimport imports.template_ovs3;\n\nextern(C) int printf(const char* fmt, ...);\n\ntemplate TypeTuple(T...){ alias T TypeTuple; }\ntemplate Id(      T){ alias T Id; }\ntemplate Id(alias A){ alias A Id; }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1528\n\nint foo1528(long){ return 1; }\nint foo1528(int[]){ return 2; }\nint foo1528(T)(T) if ( is(T:real)) { return 3; }\nint foo1528(T)(T) if (!is(T:real)) { return 4; }\nint bar1528(T)(T) if (!is(T:real)) { return 4; }\nint bar1528(T)(T) if ( is(T:real)) { return 3; }\nint bar1528(int[]){ return 2; }\nint bar1528(long){ return 1; }\n\n@property auto getfoo1528   () { return 1; }\n@property auto getfoo1528(T)() { return 2; }\n@property auto getbar1528(T)() { return 2; }\n@property auto getbar1528   () { return 1; }\n\n@property auto setfoo1528   (int) { return 1; }\n@property auto setfoo1528(T)(int) { return 2; }\n@property auto setbar1528(T)(int) { return 2; }\n@property auto setbar1528   (int) { return 1; }\n\nstruct S1528\n{\n    int foo(long){ return 1; }\n    int foo(int[]){ return 2; }\n    int foo(T)(T) if ( is(T:real)) { return 3; }\n    int foo(T)(T) if (!is(T:real)) { return 4; }\n    int bar(T)(T) if (!is(T:real)) { return 4; }\n    int bar(T)(T) if ( is(T:real)) { return 3; }\n    int bar(int[]){ return 2; }\n    int bar(long){ return 1; }\n\n    @property auto getfoo   () { return 1; }\n    @property auto getfoo(T)() { return 2; }\n    @property auto getbar(T)() { return 2; }\n    @property auto getbar   () { return 1; }\n\n    @property auto setfoo   (int) { return 1; }\n    @property auto setfoo(T)(int) { return 2; }\n    @property auto setbar(T)(int) { return 2; }\n    @property auto setbar   (int) { return 1; }\n\n    @property auto propboo   ()    { return 1; }\n    @property auto propboo(T)(T)   { return 2; }\n    @property auto propbaz(T)(T)   { return 2; }\n    @property auto propbaz   ()    { return 1; }\n}\n\nauto ufoo1528   (S1528) { return 1; }\nauto ufoo1528(T)(S1528) { return 2; }\nauto ubar1528(T)(S1528) { return 2; }\nauto ubar1528   (S1528) { return 1; }\n\n@property auto ugetfoo1528   (S1528) { return 1; }\n@property auto ugetfoo1528(T)(S1528) { return 2; }\n@property auto ugetbar1528(T)(S1528) { return 2; }\n@property auto ugetbar1528   (S1528) { return 1; }\n\n@property auto usetfoo1528   (S1528, int) { return 1; }\n@property auto usetfoo1528(T)(S1528, int) { return 2; }\n@property auto usetbar1528(T)(S1528, int) { return 2; }\n@property auto usetbar1528   (S1528, int) { return 1; }\n\n@property auto upropboo1528   (S1528)      { return 1; }\n@property auto upropboo1528(T)(S1528, T)   { return 2; }\n@property auto upropbaz1528(T)(S1528, T)   { return 2; }\n@property auto upropbaz1528   (S1528)      { return 1; }\n\nvoid test1528a()\n{\n    // global\n    assert(foo1528(100) == 1);\n    assert(foo1528(10L) == 1);\n    assert(foo1528([1]) == 2);\n    assert(foo1528(1.0) == 3);\n    assert(foo1528(\"a\") == 4);\n    assert(bar1528(100) == 1);\n    assert(bar1528(10L) == 1);\n    assert(bar1528([1]) == 2);\n    assert(bar1528(1.0) == 3);\n    assert(bar1528(\"a\") == 4);\n\n    assert(getfoo1528        == 1);\n    assert(getfoo1528!string == 2);\n    assert(getbar1528        == 1);\n    assert(getbar1528!string == 2);\n\n    assert((setfoo1528        = 1) == 1);\n    assert((setfoo1528!string = 1) == 2);\n    assert((setbar1528        = 1) == 1);\n    assert((setbar1528!string = 1) == 2);\n\n    S1528 s;\n\n    // member\n    assert(s.foo(100) == 1);\n    assert(s.foo(10L) == 1);\n    assert(s.foo([1]) == 2);\n    assert(s.foo(1.0) == 3);\n    assert(s.foo(\"a\") == 4);\n    assert(s.bar(100) == 1);\n    assert(s.bar(10L) == 1);\n    assert(s.bar([1]) == 2);\n    assert(s.bar(1.0) == 3);\n    assert(s.bar(\"a\") == 4);\n\n    assert(s.getfoo        == 1);\n    assert(s.getfoo!string == 2);\n    assert(s.getbar        == 1);\n    assert(s.getbar!string == 2);\n\n    assert((s.setfoo        = 1) == 1);\n    assert((s.setfoo!string = 1) == 2);\n    assert((s.setbar        = 1) == 1);\n    assert((s.setbar!string = 1) == 2);\n\n    assert((s.propboo = 1) == 2);\n    assert( s.propboo      == 1);\n    assert((s.propbaz = 1) == 2);\n    assert( s.propbaz      == 1);\n\n    // UFCS\n    assert(s.ufoo1528       () == 1);\n    assert(s.ufoo1528!string() == 2);\n    assert(s.ubar1528       () == 1);\n    assert(s.ubar1528!string() == 2);\n\n    assert(s.ugetfoo1528        == 1);\n    assert(s.ugetfoo1528!string == 2);\n    assert(s.ugetbar1528        == 1);\n    assert(s.ugetbar1528!string == 2);\n\n    assert((s.usetfoo1528        = 1) == 1);\n    assert((s.usetfoo1528!string = 1) == 2);\n    assert((s.usetbar1528        = 1) == 1);\n    assert((s.usetbar1528!string = 1) == 2);\n\n    assert((s.upropboo1528 = 1) == 2);\n    assert( s.upropboo1528      == 1);\n    assert((s.upropbaz1528 = 1) == 2);\n    assert( s.upropbaz1528      == 1);\n\n    // overload set\n    import imports.ovs1528a, imports.ovs1528b;\n    assert(func1528()    == 1);\n    assert(func1528(1.0) == 2);\n    assert(func1528(\"a\") == 3);\n    assert(func1528([1.0]) == 4);\n    assert(bunc1528()    == 1);\n    assert(bunc1528(1.0) == 2);\n    assert(bunc1528(\"a\") == 3);\n    assert(bunc1528([1.0]) == 4);\n\n    assert(vunc1528(100) == 1);\n    assert(vunc1528(\"a\") == 2);\n    assert(wunc1528(100) == 1);\n    assert(wunc1528(\"a\") == 2);\n\n    //assert(opUnary1528!\"+\"(10) == 1);\n    //assert(opUnary1528!\"-\"(10) == 2);\n}\n\n// ----\n\nint doo1528a(int a, double=10) { return 1; }\nint doo1528a(int a, string=\"\") { return 2; }\n\nint doo1528b(int a) { return 1; }\nint doo1528b(T:int)(T b) { return 2; }\n\nint doo1528c(T:int)(T b, double=10) { return 2; }\nint doo1528c(T:int)(T b, string=\"\") { return 2; }\n\nint doo1528d(int a) { return 1; }\nint doo1528d(T)(T b) { return 2; }\n\nvoid test1528b()\n{\n    // MatchLevel by tiargs     / by fargs\n    static assert(!__traits(compiles, doo1528a(1)));\n            // 1: MATCHexact    / MATCHexact\n            // 2: MATCHexact    / MATCHexact\n    static assert(!__traits(compiles, doo1528a(1L)));\n            // 1: MATCHexact    / MATCHconvert\n            // 2: MATCHexact    / MATCHconvert\n\n    static assert(!__traits(compiles, doo1528b(1)));\n            // 1: MATCHexact    / MATCHexact\n            // 2: MATCHexact    / MATCHexact\n    assert(doo1528b(1L) == 1);\n            // 1: MATCHexact    / MATCHconvert\n            // 2: MATCHnomatch  / -\n\n    static assert(!__traits(compiles, doo1528c(1)));\n            // 1: MATCHexact    / MATCHexact\n            // 2: MATCHexact    / MATCHexact\n    static assert(!__traits(compiles, doo1528c(1L)));\n            // 1: MATCHnomatch  / -\n            // 2: MATCHnomatch  / -\n\n    assert(doo1528d(1) == 1);\n            // 1: MATCHexact    / MATCHexact\n            // 2: MATCHconvert  / MATCHexact\n    assert(doo1528d(1L) == 1);\n            // 1: MATCHexact    / MATCHconvert\n            // 2: MATCHconvert  / MATCHexact\n            // -> not sure, may be ambiguous...?\n}\n\n// ----\n\nchar[num*2] toHexString1528(int order, size_t num)(in ubyte[num] digest) { return typeof(return).init; }\n     string toHexString1528(int order)(in ubyte[] digest) { assert(0); }\n\nchar[8] test1528c()\n{\n    ubyte[4] foo() { return typeof(return).init; }\n    return toHexString1528!10(foo);\n}\n\n// ----\n\nint f1528d1(int a, double=10) { return 1; }\nint f1528d1(int a, string=\"\") { return 2; }\n\nint f1528d2(T:int)(T b, double=10) { return 1; }\nint f1528d2(T:int)(T b, string=\"\") { return 2; }\n\n// vs deduced parameter\nint f1528d3(int a) { return 1; }\nint f1528d3(T)(T b) { return 2; }\n\n// vs specialized parameter\nint f1528d4(int a) { return 1; }\nint f1528d4(T:int)(T b) { return 2; }\n\n// vs deduced parameter + template constraint (1)\nint f1528d5(int a) { return 1; }\nint f1528d5(T)(T b) if (is(T == int)) { return 2; }\n\n// vs deduced parameter + template constraint (2)\nint f1528d6(int a) { return 1; }\nint f1528d6(T)(T b) if (is(T : int)) { return 2; }\n\n// vs nallowing conversion\nint f1528d7(ubyte a) { return 1; }\nint f1528d7(T)(T b) if (is(T : int)) { return 2; }\n\nint f1528d10(int, int) { return 1; }\nint f1528d10(T)(T, int) { return 2; }\n\nvoid test1528d()\n{\n    static assert(!__traits(compiles, f1528d1(1)));  // ambiguous\n    static assert(!__traits(compiles, f1528d1(1L))); // ambiguous\n\n    static assert(!__traits(compiles, f1528d2(1)));  // ambiguous\n    static assert(!__traits(compiles, f1528d2(1L))); // no match\n\n    assert(f1528d3(1) == 1);\n    assert(f1528d3(1L) == 1);    // '1L' matches int\n    short short_val = 42;\n    assert(f1528d3(cast(short) 42) == 1);\n    assert(f1528d3(short_val) == 1);\n\n    static assert(!__traits(compiles, f1528d4(1)));\n    assert(f1528d4(1L) == 1);\n\n    assert(f1528d5(1) == 1);\n    assert(f1528d5(1L) == 1);\n\n    assert(f1528d6(1) == 1);\n    assert(f1528d6(1L) == 1);\n    static assert(!__traits(compiles, f1528d6(ulong.max))); // no match\n                                          // needs to fix bug 9617\n    ulong ulval = 1;\n    static assert(!__traits(compiles, f1528d6(ulval)));     // no match\n\n    assert(f1528d7(200u) == 1);  // '200u' matches ubyte\n    assert(f1528d7(400u) == 2);\n    uint uival = 400;       // TDPL-like range knowledge lost here.\n    assert(f1528d7(uival) == 2);\n    uival = 200;            // Ditto.\n    assert(f1528d7(uival) == 2);\n\n\n    assert(f1528d10(        1, 9) == 1);\n    assert(f1528d10(       1U, 9) == 1);\n    assert(f1528d10(       1L, 9) == 1);\n    assert(f1528d10(      1LU, 9) == 1);\n    assert(f1528d10( long.max, 9) == 2);\n    assert(f1528d10(ulong.max, 9) == 2);\n    assert(f1528d10(        1, 9L) == 1);\n    assert(f1528d10(       1U, 9L) == 1);\n    assert(f1528d10(       1L, 9L) == 1);\n    assert(f1528d10(      1LU, 9L) == 1);\n    assert(f1528d10( long.max, 9L) == 2);\n    assert(f1528d10(ulong.max, 9L) == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1680\n\nstruct S1680\n{\n    ulong _y;\n\n           ulong blah1()        { return _y; }\n    static S1680 blah1(ulong n) { return S1680(n); }\n\n    static S1680 blah2(ulong n)  { return S1680(n); }\n    static S1680 blah2(char[] n) { return S1680(n.length); }\n}\n\nclass C1680\n{\n    ulong _y;\n    this(ulong n){}\n\n           ulong blah1()        { return _y; }\n    static C1680 blah1(ulong n) { return new C1680(n); }\n\n    static C1680 blah2(ulong n)  { return new C1680(n); }\n    static C1680 blah2(char[] n) { return new C1680(n.length); }\n}\n\nvoid test1680()\n{\n    // OK\n    S1680 s = S1680.blah1(5);\n    void fs()\n    {\n        S1680 s1 = S1680.blah2(5);              // OK\n        S1680 s2 = S1680.blah2(\"hello\".dup);    // OK\n        S1680 s3 = S1680.blah1(5);\n        // Error: 'this' is only allowed in non-static member functions, not f\n    }\n\n    C1680 c = C1680.blah1(5);\n    void fc()\n    {\n        C1680 c1 = C1680.blah2(5);\n        C1680 c2 = C1680.blah2(\"hello\".dup);\n        C1680 c3 = C1680.blah1(5);\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7418\n\nint foo7418(uint a)   { return 1; }\nint foo7418(char[] a) { return 2; }\n\nalias foo7418 foo7418a;\ntemplate foo7418b(T = void) { alias foo7418 foo7418b; }\n\nvoid test7418()\n{\n    assert(foo7418a(1U) == 1);\n    assert(foo7418a(\"a\".dup) == 2);\n\n    assert(foo7418b!()(1U) == 1);\n    assert(foo7418b!()(\"a\".dup) == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7552\n\nstruct S7552\n{\n    static void foo(){}\n    static void foo(int){}\n}\n\nstruct T7552\n{\n    alias TypeTuple!(__traits(getOverloads, S7552, \"foo\")) FooInS;\n    alias FooInS[0] foo;    // should be S7552.foo()\n    static void foo(string){}\n}\n\nstruct U7552\n{\n    alias TypeTuple!(__traits(getOverloads, S7552, \"foo\")) FooInS;\n    alias FooInS[1] foo;    // should be S7552.foo(int)\n    static void foo(string){}\n}\n\nvoid test7552()\n{\n    alias TypeTuple!(__traits(getOverloads, S7552, \"foo\")) FooInS;\n    static assert(FooInS.length == 2);\n                                      FooInS[0]();\n    static assert(!__traits(compiles, FooInS[0](0)));\n    static assert(!__traits(compiles, FooInS[1]()));\n                                      FooInS[1](0);\n\n                                      Id!(FooInS[0])();\n    static assert(!__traits(compiles, Id!(FooInS[0])(0)));\n    static assert(!__traits(compiles, Id!(FooInS[1])()));\n                                      Id!(FooInS[1])(0);\n\n    alias TypeTuple!(__traits(getOverloads, T7552, \"foo\")) FooInT;\n    static assert(FooInT.length == 2);                  // fail\n                                      FooInT[0]();\n    static assert(!__traits(compiles, FooInT[0](0)));\n    static assert(!__traits(compiles, FooInT[0](\"\")));\n    static assert(!__traits(compiles, FooInT[1]()));\n    static assert(!__traits(compiles, FooInT[1](0)));   // fail\n                                      FooInT[1](\"\");    // fail\n\n    alias TypeTuple!(__traits(getOverloads, U7552, \"foo\")) FooInU;\n    static assert(FooInU.length == 2);\n    static assert(!__traits(compiles, FooInU[0]()));\n                                      FooInU[0](0);\n    static assert(!__traits(compiles, FooInU[0](\"\")));\n    static assert(!__traits(compiles, FooInU[1]()));\n    static assert(!__traits(compiles, FooInU[1](0)));\n                                      FooInU[1](\"\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8668\n\nimport imports.m8668a;\nimport imports.m8668c; //replace with m8668b to make it work\n\nvoid test8668()\n{\n    split8668(\"abc\");\n    split8668(123);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8943\n\nvoid test8943()\n{\n    struct S\n    {\n        void foo();\n    }\n\n    alias TypeTuple!(__traits(getOverloads, S, \"foo\")) Overloads;\n    alias TypeTuple!(__traits(parent, Overloads[0])) P; // fail\n    static assert(is(P[0] == S));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9410\n\nstruct S {}\nint foo(float f, ref S s) { return 1; }\nint foo(float f,     S s) { return 2; }\nvoid test9410()\n{\n    S s;\n    assert(foo(1, s  ) == 1); // works fine. Print: ref\n    assert(foo(1, S()) == 2); // Fails with: Error: S() is not an lvalue\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10171\n\nstruct B10171(T) { static int x; }\n\nvoid test10171()\n{\n    auto mp = &B10171!(B10171!int).x;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1900\n// template overload set\n\nvoid test1900a()\n{\n    // function vs function template with IFTI call\n    assert(foo1900a(100) == 1);\n    assert(foo1900a(\"s\") == 2);\n    assert(foo1900b(100) == 1);\n    assert(foo1900b(\"s\") == 2);\n    // function template call with explicit template arguments\n    assert(foo1900a!string(\"s\") == 2);\n    assert(foo1900b!string(\"s\") == 2);\n\n    // function template overloaded set call with IFTI\n    assert(bar1900a(100) == 1);\n    assert(bar1900a(\"s\") == 2);\n    assert(bar1900b(100) == 1);\n    assert(bar1900b(\"s\") == 2);\n    // function template overloaded set call with explicit template arguments\n    assert(bar1900a!double(100) == 1);\n    assert(bar1900a!string(\"s\") == 2);\n    assert(bar1900b!double(100) == 1);\n    assert(bar1900b!string(\"s\") == 2);\n\n    // function template overloaded set call with IFTI\n    assert(baz1900(1234567890) == 1);\n    assert(baz1900([1:1, 2:2]) == 2);\n    assert(baz1900(new Object) == 3);\n    assert(baz1900(\"deadbeaf\") == 4);\n    // function template overloaded set call with explicit template arguments\n    assert(baz1900!(double)(14142135) == 1);\n    assert(baz1900!(int[int])([12:34]) == 2);\n    assert(baz1900!(Object)(new Object) == 3);\n    assert(baz1900!(string)(\"cafe babe\") == 4);\n\n    static assert(!__traits(compiles, bad1900!\"++\"()));\n}\n\nvoid test1900b()\n{\n    S1900 s;\n\n    // function vs function template with IFTI call\n    assert(s.foo1900a(100) == 1);\n    assert(s.foo1900a(\"s\") == 2);\n    assert(s.foo1900b(100) == 1);\n    assert(s.foo1900b(\"s\") == 2);\n    // function template call with explicit template arguments\n    assert(s.foo1900a!string(\"s\") == 2);\n    assert(s.foo1900b!string(\"s\") == 2);\n\n    // function template overloaded set call with IFTI\n    assert(s.bar1900a(100) == 1);\n    assert(s.bar1900a(\"s\") == 2);\n    assert(s.bar1900b(100) == 1);\n    assert(s.bar1900b(\"s\") == 2);\n    // function template overloaded set call with explicit template arguments\n    assert(s.bar1900a!double(100) == 1);\n    assert(s.bar1900a!string(\"s\") == 2);\n    assert(s.bar1900b!double(100) == 1);\n    assert(s.bar1900b!string(\"s\") == 2);\n\n    // function template overloaded set call with IFTI\n    assert(s.baz1900(1234567890) == 1);\n    assert(s.baz1900([1:1, 2:2]) == 2);\n    assert(s.baz1900(new Object) == 3);\n    assert(s.baz1900(\"deadbeaf\") == 4);\n    // function template overloaded set call with explicit template arguments\n    assert(s.baz1900!(double)(14142135) == 1);\n    assert(s.baz1900!(int[int])([12:34]) == 2);\n    assert(s.baz1900!(Object)(new Object) == 3);\n    assert(s.baz1900!(string)(\"cafe babe\") == 4);\n\n    static assert(!__traits(compiles, s.bad1900!\"++\"()));\n}\n\nvoid test1900c()\n{\n    S1900 s;\n\n    // This is a kind of Issue 1528 - [tdpl] overloading template and non-template functions\n    //s.funca();\n    //s.funca(10);\n    //s.funcb();\n    //s.funcb(10);\n\n    // Call function template overload set through mixin member lookup\n    assert(s.mixfooa() == 1);\n    assert(s.mixfooa(10) == 2);\n    assert(s.mixfoob() == 1);\n    assert(s.mixfoob(10) == 2);\n\n    // Call function template overload set through mixin^2 member lookup\n    assert(s.mixsubfooa() == 1);\n    assert(s.mixsubfooa(10) == 2);\n    assert(s.mixsubfoob() == 1);\n    assert(s.mixsubfoob(10) == 2);\n\n    // Using mixin identifier can limit overload set\n    assert(s.a.mixfooa() == 1);     static assert(!__traits(compiles, s.a.mixfooa(10)));\n    assert(s.b.mixfooa(10) == 2);   static assert(!__traits(compiles, s.b.mixfooa()));\n    assert(s.b.mixfoob() == 1);     static assert(!__traits(compiles, s.b.mixfoob(10)));\n    assert(s.a.mixfoob(10) == 2);   static assert(!__traits(compiles, s.a.mixfoob()));\n}\n\nalias merge1900 = imports.template_ovs1.merge1900;\nalias merge1900 = imports.template_ovs2.merge1900;\n\nvoid test1900d()\n{\n    assert( merge1900!double(100) == 1);\n    assert(.merge1900!double(100) == 1);\n}\n\nmixin template Foo1900e(T)\n{\n    void foo(U : T)() { v++;}\n}\nvoid test1900e()\n{\n    struct S\n    {\n        int v;\n        mixin Foo1900e!double;\n        mixin Foo1900e!string;\n        void test()\n        {\n            foo!(int);          // ScopeExp(ti->tempovers != NULL)\n            foo!(typeof(null)); // ScopeExp(ti->tempovers != NULL)\n        }\n    }\n\n    S s;\n    assert(s.v == 0);\n    s.test();\n    assert(s.v == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1900\n\nvoid test1900()\n{\n    AClass1900 a;\n    BClass1900 b;\n\n    static assert(Traits1900!(AClass1900).name == \"AClass\");\n    static assert(Traits1900!(BClass1900).name == \"BClass\");\n    static assert(Traits1900!(int).name == \"any\");\n\n    Traits1900!(long) obj;\n\n    static assert(Value1900a!double == 1);\n    static assert(Value1900b!double == 1);\n    static assert(Value1900a!string == 2);\n    static assert(Value1900b!string == 2);\n}\n\nalias imports.template_ovs1.Traits1900 Traits1900X;\nalias imports.template_ovs2.Traits1900 Traits1900X;\nalias imports.template_ovs3.Traits1900 Traits1900X;\nstatic assert(Traits1900X!(AClass1900).name == \"AClass\");\nstatic assert(Traits1900X!(BClass1900).name == \"BClass\");\nstatic assert(Traits1900X!(int).name == \"any\");\n\n// Traits1900Y is exact same as imports.template_ovs1.Traits1900.\nalias imports.template_ovs1.Traits1900 Traits1900Y1;\nalias imports.template_ovs1.Traits1900 Traits1900Y2;\nalias Traits1900Y1 Traits1900Y;\nalias Traits1900Y2 Traits1900Y;\nstatic assert(Traits1900Y!(AClass1900).name == \"AClass\");\nstatic assert(!__traits(compiles, Traits1900Y!(BClass1900)));\nstatic assert(!__traits(compiles, Traits1900Y!(int)));\n\ntemplate Foo1900(T)\n{\n    template Bar1900(U : T)\n    {\n    }\n}\nmixin Foo1900!(int) A1900;\nmixin Foo1900!(char) B1900;\nalias Bar1900!(int) bar1900;    // error\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7780\n\nmixin template A7780()\n{\n    template C(int n : 0) { int C = 0; }\n}\nmixin template B7780()\n{\n    template C(int n : 1) { int C = 1; }\n}\n\nclass Foo7780\n{\n    mixin A7780!();\n    mixin B7780!();\n}\n\nvoid test7780()\n{\n    assert(Foo7780.C!0 == 0);\n}\n\n/***************************************************/\n\nauto foo7849(string) { return 1; }\nauto foo7849(dstring) { return 2; }\n\nenum str7849a = \"string\";\nimmutable str7849ai = \"string\";\nimmutable str7849bi = str7849ai;\nenum str7849b = str7849ai;\nenum str7849c = str7849bi;\n\nvoid test7849()\n{\n    assert(foo7849(str7849a) == 1);\n    assert(foo7849(str7849b) == 1);\n    assert(foo7849(str7849c) == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8352\n\nvoid test8352()\n{\n    [1, 2].remove8352a!(x => x == 2)();\n    [1, 2].remove8352b!(x => x == 2)();\n    remove8352a(\"deleteme\");\n    remove8352b(\"deleteme\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8441\n\nmixin template T8441a(string i)\n{\n    auto j(string s = \"a\", U)(U u1, U u2)\n    {\n        return 0;\n    }\n    auto j(int i,string s = \"a\", W)(W u1, W u2)\n    {\n        return i;\n    }\n\n    mixin(\"\n        class F\" ~ i ~ \"\n        {\n            auto j(string s = \\\"a\\\", U)(U u1, U u2)\n            {\n                return this.outer.t\" ~ i ~ \".j!(s, U)(u1, u2);\n            }\n            auto j(int i, string s = \\\"a\\\", W)(W u1, W u2)\n            {\n                return this.outer.t\" ~ i ~ \".j!(i, s, W)(u1, u2);   // <- dmd is giving error for j!(...).j's type\n            }\n        }\n        auto f\" ~ i ~ \"()\n        {\n            return new F\" ~ i ~ \"();\n        }\n    \");\n}\nclass X8441a\n{\n    mixin T8441a!(\"1\") t0;\n    alias t0 t1;\n}\nvoid test8441a()\n{\n    auto x = new X8441a();\n    x.f1().j!(3,\"a\")(2.2, 3.3);\n}\n\n// ----\n\nmixin template T8441b()\n{\n    void k()() {}\n\n    void j()() {}\n    void j(int i)() {}\n}\nclass X8441b\n{\n    mixin T8441b t0;\n}\nvoid test8441b()\n{\n    auto x = new X8441b();\n    x.k!()();    // Fine\n    x.j!()();    // Fine\n    x.t0.k!()(); // Fine\n    x.t0.j!()(); // Derp\n}\n\n// ----\n\nmixin template Signal8441c(Args...)\n{\n    bool call = false;\n    final void connect(string method, ClassType)(ClassType obj)\n    if (is(ClassType == class) && __traits(compiles, { void delegate(Args) dg = mixin(\"&obj.\"~method); }))\n    {\n        call = true;\n    }\n}\nvoid test8441c()\n{\n    class Observer\n    {\n        void watchInt(string str, int i) {}\n    }\n    class Bar\n    {\n        mixin Signal8441c!(string, int)  s1;\n        mixin Signal8441c!(string, int)  s2;\n        mixin Signal8441c!(string, long) s3;\n    }\n    auto a = new Bar;\n    auto o1 = new Observer;\n\n    a.s1.connect!\"watchInt\"(o1);\n\n    assert( a.s1.call);\n    assert(!a.s2.call);\n    assert(!a.s3.call);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9235\n\ntemplate FlowEvaluator9235()\n{\n    // if control flow\n    bool execute(Command cmd)()\n        if (cmd == Command.Jump ||\n            cmd == Command.Fork)\n    {\n        return false;\n    }\n}\ntemplate MatchEvaluator9235()\n{\n    // if operation\n    bool execute(Command cmd)()\n        if (cmd == Command.Char ||\n            cmd == Command.Any ||\n            cmd == Command.End)\n    {\n        return true;\n    }\n}\nvoid test9235a()\n{\n    enum Command\n    {\n        Char, Any, Fork, Jump, End\n    }\n    struct Machine\n    {\n        mixin FlowEvaluator9235;\n        mixin MatchEvaluator9235;\n\n        bool exec_flow()\n        {\n            return execute!(Command.Jump)();\n        }\n        bool exec_match()\n        {\n            return execute!(Command.Any)();\n        }\n    }\n\n    Machine m;\n    assert(!m.exec_flow());\n    assert( m.exec_match());\n}\n\n// ----\n\nmixin template mixA9235()\n{\n    int foo(string s)() if (s == \"a\") { return 1; }\n}\nmixin template mixB9235()\n{\n    int foo(string s)() if (s == \"b\") { return 2; }\n}\nstruct Foo9235\n{\n    mixin mixA9235 A;\n    mixin mixB9235 B;\n    alias A.foo foo;\n    alias B.foo foo;\n}\nvoid test9235b()\n{\n    Foo9235 f;\n    assert(f.foo!\"a\"() == 1);\n    assert(f.foo!\"b\"() == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10658\n\nalias Val10658 = imports.template_ovs1.Val10658;\nalias Val10658 = imports.template_ovs2.Val10658;\nstatic assert(Val10658!1 == 1);\nstatic assert(Val10658!1L == 2);\n\n// ----\n\ntemplate Foo10658(T) if (is(T == double)) { enum Foo10658 = 1; }\ntemplate Bar10658(T) if (is(T == string)) { enum Bar10658 = 2; }\nalias Baz10658 = Foo10658;\nalias Baz10658 = Bar10658;\n\ntemplate Voo10658(T) if (is(T == cfloat)) { enum Voo10658 = 5; }\ntemplate Voo10658(T) if (is(T == Object)) { enum Voo10658 = 6; }\n\nalias Vaz10658 = Baz10658;  // OvarDeclaration\nalias Vaz10658 = Voo10658;  // TemplateDeclaration (overnext != NULL)\n\ntemplate Merge10658a(alias A)\n{\n    enum Merge10658a = A!double + A!string;\n}\ntemplate Merge10658b(alias A)\n{\n    enum Merge10658b = A!double + A!string + A!cfloat + A!Object;\n}\n\nvoid test10658a()\n{\n    static assert(Baz10658!double == 1);\n    static assert(Baz10658!string == 2);\n    static assert(Voo10658!cfloat == 5);\n    static assert(Voo10658!Object == 6);\n\n    // pass OverDeclaration through TemplateAliasParameter\n    static assert(Merge10658a!Baz10658 == 1 + 2);\n    static assert(Merge10658b!Vaz10658 == 1 + 2 + 5 + 6);\n}\n\n// ----\n\nmixin template mix10658A()\n{\n    int f10658(string s)() if (s == \"a\") { return 1; }\n}\nmixin template mix10658B()\n{\n    int f10658(string s)() if (s == \"b\") { return 2; }\n}\nmixin mix10658A A10658;\nmixin mix10658B B10658;\nalias A10658.f10658 foo10658;\nalias B10658.f10658 foo10658;\n\nmixin template mix10658C()\n{\n    int f10658(string s, T)(T arg) if (s == \"c\") { return 3; }\n}\nmixin template mix10658D()\n{\n    int f10658(string s, T)(T arg) if (s == \"d\") { return 4; }\n}\nstruct S10658\n{\n    mixin mix10658C C10658;\n    mixin mix10658D D10658;\n    alias C10658.f10658 foo10658;\n    alias D10658.f10658 foo10658;\n}\n\nvoid test10658b()\n{\n    assert( foo10658!\"a\"() == 1);\n    assert(.foo10658!\"b\"() == 2);\n\n    S10658 s;\n    assert(s.foo10658!\"c\"(0) == 3);\n    assert(s.foo10658!\"d\"(0) == 4);\n}\n\n/***************************************************/\n\nclass InputStream11785\n{\n    long read(ubyte* bytes, long len)\n    {\n        return 0;\n    }\n    void read(T)(ref T val)\n    {\n        read(cast(ubyte*)&val, cast(long)val.sizeof);\n    }\n}\n\nlong read11785(ubyte* bytes, long len)\n{\n    return 0;\n}\nvoid read11785(T)(ref T val)\n{\n    read11785(cast(ubyte*)&val, cast(long)val.sizeof);\n}\n\nvoid test11785()\n{\n    int v;\n\n    read11785(v);\n\n    auto input = new InputStream11785();\n    input.read(v);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11915\n\nint f11915(    int) { return 1; }\nint f11915(ref int) { return 2; }\n\nint g11915(    int) { return 1; }\nint g11915(out int) { return 2; }\n\nvoid test11915()\n{\n    const int n = 1;\n    assert(f11915(n) == 1);\n    assert(g11915(n) == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11916\n\nauto f11916(T)(    T)            { return 1; }\nauto f11916(T)(out T) if (false) { return 2; }\n\nauto g11916(T)(    T) { return 1; }\nauto g11916(T)(out T) { return 2; }\n\nvoid test11916()\n{\n    const int c = 1;\n    int m = 2;\n\n    // 'out const int' is invalid function parameter, so (out T) version will be dropped\n    // from overload candidates before template constraint evaluated.\n    assert(f11916(c) == 1);\n\n    // Both (T) and (out T) have valid signatures with T == int, but the 2nd overload will be\n    // dropped from overload candidates because of the template constraint.\n    assert(f11916(m) == 1);\n\n    // 'out const int' parameter is invalid, so non-out version is selected.\n    assert(g11916(c) == 1);\n\n    // MATCHconst for (T) version, and MATCHexact for (out T) version.\n    assert(g11916(m) == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13783\n\nenum E13783 { a = 5 }\n\n    inout(int) f(    inout(int) t) { return t * 2; }\nref inout(int) f(ref inout(int) t) { return t; }\n\nvoid test13783()\n{\n    const E13783 e = E13783.a;\n    assert(f(e) == 10);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14858\n\nint foo14858()() { return 1; }\nint bar14858(int) { return 2; }\n\nalias foobar14858 = foo14858;\nalias foobar14858 = bar14858;\n\nvoid test14858()\n{\n    assert(foobar14858() == 1);\n    assert(foobar14858(1) == 2); // OK <- NG\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14989\n\ntemplate Foo14989(T) if (is(T == int))    { enum Foo14989 = 1; }\ntemplate Bar14989(T) if (is(T == double)) { enum Bar14989 = 2; }\ntemplate Baz14989(T) if (is(T == string)) { enum Baz14989 = 3; }\n\nalias X14989 = Foo14989;\nalias X14989 = Bar14989;\n// X is an alias to is OverDeclaration\nalias A14989 = X14989;\n// first, A->aliassym == X\nstatic if (true)\n{\n    alias A14989 = Baz14989;\n    // A->aliassym = new OverDeclaration('A')\n    // then, A->aliassym->overloadInsert(Baz)\n}\n\ntemplate Mix14989a() { alias M14989 = Foo14989; }\ntemplate Mix14989b() { alias M14989 = Bar14989; }\nmixin Mix14989a;\nmixin Mix14989b;\nalias Y14989 = M14989;\n// Y is an alias to OverloadSet\nalias B14989 = Y14989;\n// first, B->aliassym == Y\nstatic if (true)\n{\n    alias B14989 = Baz14989;\n    // (B->aliassym = new OverloadSet('B')\n    // then, B->aliassym->overloadInsert(Baz)\n}\n\nvoid test14989()\n{\n    static assert(X14989!int    == 1);\n    static assert(X14989!double == 2);\n    static assert(!__traits(compiles, X14989!string));  // Baz is not in X\n\n    static assert(A14989!int    == 1);\n    static assert(A14989!double == 2);\n    static assert(A14989!string == 3);  // OK <- error\n\n    static assert(Y14989!int    == 1);\n    static assert(Y14989!double == 2);\n    static assert(!__traits(compiles, Y14989!string));  // Baz is not in Y\n\n    static assert(B14989!int    == 1);\n    static assert(B14989!double == 2);\n    static assert(B14989!string == 3);  // OK <- error\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14965\n\nauto f14965a1() { return f14965a1(123); }\nint f14965a1(int x) { return x; }\n\nint f14965a2(int x) { return x; }\nauto f14965a2() { return f14965a2(123); }\n\nauto f14965b1() { int function(int) fp = &f14965b1; return fp(123); }\nint f14965b1(int x) { return x; }\n\nint f14965b2(int x) { return x; }\nauto f14965b2() { int function(int) fp = &f14965b2; return fp(123); }\n\nauto f14965c1() { auto fp = cast(int function(int))&f14965c1; return fp(123); }\nint f14965c1(int x) { return x; }\n\nint f14965c2(int x) { return x; }\nauto f14965c2() { auto fp = cast(int function(int))&f14965c2; return fp(123); }\n\nint function(int) f14965d1() { return &f14965d1; }\nint f14965d1(int n) { return 10 + n; }\n\nint f14965d2(int n) { return 10 + n; }\nint function(int) f14965d2() { return &f14965d2; }\n\nclass C\n{\n    auto fa1() { return this.fa1(123); }\n    int fa1(int x) { return x; }\n\n    int fa2(int x) { return x; }\n    auto fa2() { return this.fa2(123); }\n\n    auto fb1() { int delegate(int) dg = &this.fb1; return dg(123); }\n    int fb1(int x) { return x; }\n\n    int fb2(int x) { return x; }\n    auto fb2() { int delegate(int) dg = &this.fb2; return dg(123); }\n\n    auto fc1() { auto dg = cast(int delegate(int))&this.fc1; return dg(123); }\n    int fc1(int x) { return x; }\n\n    int fc2(int x) { return x; }\n    auto fc2() { auto dg = cast(int delegate(int))&this.fc2; return dg(123); }\n\n    int delegate(int) fd1() { return &fd1; }\n    int fd1(int n) { return 10 + n; }\n\n    int fd2(int n) { return 10 + n; }\n    int delegate(int) fd2() { return &fd2; }\n}\n\nvoid test14965()\n{\n    assert(f14965a1() == 123);\n    assert(f14965b1() == 123);\n    assert(f14965c1() == 123);\n    assert(f14965d1()(113) == 123);\n    assert(f14965a2() == 123);\n    assert(f14965b2() == 123);\n    assert(f14965c2() == 123);\n    assert(f14965d2()(113) == 123);\n\n    auto c = new C();\n    assert(c.fa1() == 123);\n    assert(c.fb1() == 123);\n    assert(c.fc1() == 123);\n    assert(c.fd1()(113) == 123);\n    assert(c.fa2() == 123);\n    assert(c.fb2() == 123);\n    assert(c.fc2() == 123);\n    assert(c.fd2()(113) == 123);\n}\n\n/***************************************************/\n\nint main()\n{\n    test1528a();\n    test1528b();\n    test1528c();\n    test1528d();\n    test1680();\n    test7418();\n    test7552();\n    test8668();\n    test8943();\n    test9410();\n    test10171();\n    test1900a();\n    test1900b();\n    test1900c();\n    test1900d();\n    test1900e();\n    test7780();\n    test7849();\n    test8352();\n    test8441a();\n    test8441b();\n    test8441c();\n    test9235a();\n    test9235b();\n    test10658a();\n    test10658b();\n    test11785();\n    test11915();\n    test11916();\n    test13783();\n    test14858();\n    test14965();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/pi.d",
    "content": "// PERMUTE_ARGS:\n// EXECUTE_ARGS: 1000\n\nimport core.stdc.stdio;\nimport core.stdc.time;\n\nconst int LONG_TIME=4000;\n\nbyte[] p;\nbyte[] t;\nint q;\n\nint main(char[][] args)\n{\n        time_t startime, endtime;\n        int i;\n\n        if (args.length == 2) {\n                sscanf(&args[1][0],\"%d\",&q);\n        } else {\n                printf(\"Usage: pi [precision]\\n\");\n                return 1;\n        }\n\n        if (q < 0)\n        {\n                printf(\"Precision was too low, running with precision of 0.\\n\");\n                q = 0;\n        }\n\n        if (q > LONG_TIME)\n        {\n            printf(\"Be prepared to wait a while...\\n\");\n        }\n\n        // Compute one more digit than we display to compensate for rounding\n        q++;\n\n        p.length = q + 1;\n        t.length = q + 1;\n\n        /* compute pi */\n\n        time(&startime);\n        arctan(2);\n        arctan(3);\n        mul4();\n        time(&endtime);\n\n        // Return to the number of digits we want to display\n        q--;\n\n        /* print pi */\n\n        printf(\"pi = %d.\",cast(int)(p[0]));\n        for (i = 1; i <= q; i++)\n        printf(\"%d\",cast(int)(p[i]));\n        printf(\"\\n\");\n        printf(\"%lld seconds to compute pi with a precision of %d digits.\\n\", cast(long)(endtime-startime),q);\n\n        return 0;\n}\n\nvoid arctan(int s)\n{\n        int n;\n\n        t[0] = 1;\n        div(s); /* t[] = 1/s */\n        add();\n        n = 1;\n        do {\n                mul(n);\n                div(s * s);\n                div(n += 2);\n                if (((n-1) / 2) % 2 == 0)\n                        add();\n                else\n                        sub();\n        } while (!tiszero());\n}\n\nvoid add()\n{\n        int j;\n\n        for (j = q; j >= 0; j--)\n        {\n                if (t[j] + p[j] > 9) {\n                        p[j] += t[j] - 10;\n                        p[j-1] += 1;\n                } else\n                        p[j] += t[j];\n        }\n}\n\nvoid sub()\n{\n        int j;\n\n        for (j = q; j >= 0; j--)\n                if (p[j] < t[j]) {\n                        p[j] -= t[j] - 10;\n                        p[j-1] -= 1;\n                } else\n                        p[j] -= t[j];\n}\n\nvoid mul(int multiplier)\n{\n        int b;\n        int i;\n        int carry = 0, digit = 0;\n\n        for (i = q; i >= 0; i--) {\n                b = (t[i] * multiplier + carry);\n                digit = b % 10;\n                carry = b / 10;\n                t[i] = cast(byte)digit;\n        }\n}\n\n/* t[] /= l */\n\nvoid div(int divisor)\n{\n        int i, b;\n        int quotient, remainder = 0;\n\n        foreach (ref x; t)\n        {\n                b = (10 * remainder + x);\n                quotient = b / divisor;\n                remainder = b % divisor;\n                x = cast(byte)quotient;\n        }\n}\n\nvoid div4()\n{\n        int i, c, d = 0;\n\n        for (i = 0; i <= q; i++) {\n                c = (10 * d + p[i]) / 4;\n                d = (10 * d + p[i]) % 4;\n                p[i] = cast(byte)c;\n        }\n}\n\nvoid mul4()\n{\n        int i, c, d;\n\n        d = c = 0;\n\n        for (i = q; i >= 0; i--) {\n                d = (p[i] * 4 + c) % 10;\n                c = (p[i] * 4 + c) / 10;\n                p[i] = cast(byte)d;\n        }\n}\n\nint tiszero()\n{\n        int k;\n\n        for (k = 0; k <= q; k++)\n                if (t[k] != 0)\n                        return false;\n        return true;\n}\n\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/polysemous.d",
    "content": "// PERMUTE_ARGS:\n\n// Prefer immutable(char)[] to all others\nint foo(           char[] a) { return 11; }\nint foo(    const  char[] a) { return 12; }\nint foo(immutable  char[] a) { return 13; }\nint foo(          wchar[] a) { return 21; }\nint foo(    const wchar[] a) { return 22; }\nint foo(immutable wchar[] a) { return 23; }\nint foo(          dchar[] a) { return 31; }\nint foo(    const dchar[] a) { return 32; }\nint foo(immutable dchar[] a) { return 33; }\n\n// Prefer const conversion over polysemous conversion\nint bar(           char[] a) { return 11; }\nint bar(    const  char[] a) { return 12; }\n//  bar(immutable  char[] a);\nint bar(          wchar[] a) { return 21; }\nint bar(    const wchar[] a) { return 22; }\n//  bar(immutable wchar[] a);\nint bar(          dchar[] a) { return 31; }\nint bar(    const dchar[] a) { return 32; }\n//  bar(immutable dchar[] a);\n\n// No conversion to mutable\nint baz(           char[] a) { return 11; }\n//  baz(    const  char[] a);\n//  baz(immutable  char[] a);\nint baz(          wchar[] a) { return 21; }\n//  baz(    const wchar[] a);\n//  baz(immutable wchar[] a);\nint baz(          dchar[] a) { return 31; }\n//  baz(    const dchar[] a);\n//  baz(immutable dchar[] a);\n\nint main()\n{\n    auto strn = \"a\";\n    auto strc = \"a\"c;\n    auto strw = \"a\"w;\n    auto strd = \"a\"d;\n\n    assert(foo(\"a\" ) == 13);\n    assert(foo(strn) == 13);\n    assert(foo(\"a\"c) == 13);\n    assert(foo(strc) == 13);\n    assert(foo(\"a\"w) == 23);\n    assert(foo(strw) == 23);\n    assert(foo(\"a\"d) == 33);\n    assert(foo(strd) == 33);\n\n    assert(bar(\"a\" ) == 12);\n    assert(bar(strn) == 12);\n    assert(bar(\"a\"c) == 12);\n    assert(bar(strc) == 12);\n    assert(bar(\"a\"w) == 22);\n    assert(bar(strw) == 22);\n    assert(bar(\"a\"d) == 32);\n    assert(bar(strd) == 32);\n\n    static assert(!__traits(compiles, baz(\"a\" ) ));\n    static assert(!__traits(compiles, baz(strn) ));\n    static assert(!__traits(compiles, baz(\"a\"c) ));\n    static assert(!__traits(compiles, baz(strc) ));\n    static assert(!__traits(compiles, baz(\"a\"w) ));\n    static assert(!__traits(compiles, baz(strw) ));\n    static assert(!__traits(compiles, baz(\"a\"d) ));\n    static assert(!__traits(compiles, baz(strd) ));\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/printargs.d",
    "content": "// PERMUTE_ARGS:\n// EXECUTE_ARGS: A B C\n\nextern(C) int printf(const char*, ...);\n\nint main(char[][] args)\n{\n    int i;\n\n    for (i = 0; i < args.length; i++)\n        printf(\"args[%d] = '%.*s'\\n\", i, args[i].length, args[i].ptr);\n\n    assert(args[1] == \"A\");\n    assert(args[2] == \"B\");\n    assert(args[3] == \"C\");\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/property.d",
    "content": "\n\n/******************************************/\n\nstruct Foo\n{\n    int v;\n\n    int bar(int value) { return v = value + 2; }\n    int bar() { return 73; }\n}\n\nint test1()\n{\n    Foo f;\n    int i;\n\n    i = (f.bar = 6);\n    assert(i == 8);\n    assert(f.v == 8);\n\n    i = f.bar;\n    assert(i == 73);\n\n    return 0;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6259\n\nstruct S6259\n{\n    private int m_prop;\n    ref const(int) prop() { return m_prop; }\n    void prop(int v) { m_prop = v; }\n}\n\nvoid test6259()\n{\n    S6259 s;\n    s.prop = 1;\n}\n\n/******************************************/\n\nvoid main()\n{\n    test1();\n    test6259();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/property2.d",
    "content": "extern (C) int printf(const char* fmt, ...);\n\n/*******************************************/\n\ntemplate select(alias v1, alias v2)\n{\n    enum select = v2;\n}\n\nstruct Test(int N)\n{\n    int value;\n    int getset;\n\n    static if (N == 0)\n    {\n        ref foo(){ getset = 1; return value; }\n\n        enum result = select!(0, 1);\n        // prints \"getter\"\n    }\n    static if (N == 1)\n    {\n        ref foo(int x){ getset = 2; value = x; return value; }\n\n        enum result = select!(0, 2);\n        // prints \"setter\"\n    }\n    static if (N == 2)\n    {\n        @property ref foo(){ getset = 1; return value; }\n\n        enum result = select!(1, 1);\n        // prints \"getter\"\n    }\n    static if (N == 3)\n    {\n        @property ref foo(int x){ getset = 2; value = x; return value; }\n\n        enum result = select!(2, 2);\n        // prints \"setter\"\n    }\n\n\n    static if (N == 4)\n    {\n        ref foo()     { getset = 1; return value; }\n        ref foo(int x){ getset = 2; value = x; return value; }\n\n        enum result = select!(0, 2);\n        // prints \"setter\"\n    }\n    static if (N == 5)\n    {\n        @property ref foo()     { getset = 1; return value; }\n                  ref foo(int x){ getset = 2; value = x; return value; }\n\n        enum result = select!(0, 0);\n        // test.d(xx): Error: cannot overload both property and non-property functions\n    }\n    static if (N == 6)\n    {\n                  ref foo()     { getset = 1; return value; }\n        @property ref foo(int x){ getset = 2; value = x; return value; }\n\n        enum result = select!(0, 0);\n        // test.d(xx): Error: cannot overload both property and non-property functions\n    }\n    static if (N == 7)\n    {\n        @property ref foo()     { getset = 1; return value; }\n        @property ref foo(int x){ getset = 2; value = x; return value; }\n\n        enum result = select!(2, 2);\n        // prints \"setter\"\n    }\n}\n\ntemplate seq(T...)\n{\n    alias T seq;\n}\ntemplate iota(int begin, int end)\n    if (begin <= end)\n{\n    static if (begin == end)\n        alias seq!() iota;\n    else\n        alias seq!(begin, iota!(begin+1, end)) iota;\n}\n\nvoid test1()\n{\n    foreach (N; iota!(0, 8))\n    {\n        printf(\"%d: \", N);\n\n        Test!N s;\n        static if (Test!N.result == 0)\n        {\n            static assert(!is(typeof({ s.foo = 1; })));\n            printf(\"compile error\\n\");\n        }\n        else\n        {\n            s.foo = 1;\n            if (s.getset == 1)\n                printf(\"getter\\n\");\n            else\n                printf(\"setter\\n\");\n            assert(s.getset == Test!N.result);\n        }\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7722\n\nclass Foo7722 {}\nvoid spam7722(Foo7722 f) {}\n\nvoid test7722()\n{\n    auto f = new Foo7722;\n    f.spam7722;\n}\n\n/*******************************************/\n\n@property void check(alias v1, alias v2, alias dg)()\n{\n    void checkImpl(alias v)()\n    {\n        static if (v == 0)\n            static assert(!__traits(compiles, dg(0)));\n        else\n            assert(dg(0) == v);\n    }\n\n    checkImpl!(v2)();\n}\n\nstruct S {}\n\nint foo(int n)          { return 1; }\nint foo(int n, int m)   { return 2; }\nint goo(int[] a)        { return 1; }\nint goo(int[] a, int m) { return 2; }\nint bar(S s)            { return 1; }\nint bar(S s, int n)     { return 2; }\n\nint baz(X)(X x)         { return 1; }\nint baz(X)(X x, int n)  { return 2; }\n\nint temp;\nref int boo(int n)      { return temp; }\nref int coo(int[] a)    { return temp; }\nref int mar(S s)        { return temp; }\n\nref int maz(X)(X x)     { return temp; }\n\nvoid test7722a()\n{\n    int n;\n    int[] a;\n    S s;\n\n    check!(1, 1, x =>    foo(4)     );      check!(1, 1, x =>    baz(4)     );\n    check!(1, 1, x =>  4.foo()      );      check!(1, 1, x =>  4.baz()      );\n    check!(0, 1, x =>  4.foo        );      check!(0, 1, x =>  4.baz        );\n    check!(2, 2, x =>    foo(4, 2)  );      check!(2, 2, x =>    baz(4, 2)  );\n    check!(2, 2, x =>  4.foo(2)     );      check!(2, 2, x =>  4.baz(2)     );\n    check!(0, 2, x => (4.foo = 2)   );      check!(0, 2, x => (4.baz = 2)   );\n\n    check!(1, 1, x =>    goo(a)     );      check!(1, 1, x =>    baz(a)     );\n    check!(1, 1, x =>  a.goo()      );      check!(1, 1, x =>  a.baz()      );\n    check!(0, 1, x =>  a.goo        );      check!(0, 1, x =>  a.baz        );\n    check!(2, 2, x =>    goo(a, 2)  );      check!(2, 2, x =>    baz(a, 2)  );\n    check!(2, 2, x =>  a.goo(2)     );      check!(2, 2, x =>  a.baz(2)     );\n    check!(0, 2, x => (a.goo = 2)   );      check!(0, 2, x => (a.baz = 2)   );\n\n    check!(1, 1, x =>    bar(s)     );      check!(1, 1, x =>    baz(s)     );\n    check!(1, 1, x =>  s.bar()      );      check!(1, 1, x =>  s.baz()      );\n    check!(0, 1, x =>  s.bar        );      check!(0, 1, x =>  s.baz        );\n    check!(2, 2, x =>    bar(s, 2)  );      check!(2, 2, x =>    baz(s, 2)  );\n    check!(2, 2, x =>  s.bar(2)     );      check!(2, 2, x =>  s.baz(2)     );\n    check!(0, 2, x => (s.bar = 2)   );      check!(0, 2, x => (s.baz = 2)   );\n\n    check!(2, 2, x => (  boo(4) = 2));      check!(2, 2, x => (  maz(4) = 2));\n    check!(0, 2, x => (4.boo    = 2));      check!(0, 2, x => (4.maz    = 2));\n    check!(2, 2, x => (  coo(a) = 2));      check!(2, 2, x => (  maz(a) = 2));\n    check!(0, 2, x => (a.coo    = 2));      check!(0, 2, x => (a.maz    = 2));\n    check!(2, 2, x => (  mar(s) = 2));      check!(2, 2, x => (  maz(s) = 2));\n    check!(0, 2, x => (s.mar    = 2));      check!(0, 2, x => (s.maz    = 2));\n}\n\nint hoo(T)(int n)          { return 1; }\nint hoo(T)(int n, int m)   { return 2; }\nint koo(T)(int[] a)        { return 1; }\nint koo(T)(int[] a, int m) { return 2; }\nint var(T)(S s)            { return 1; }\nint var(T)(S s, int n)     { return 2; }\n\nint vaz(T, X)(X x)         { return 1; }\nint vaz(T, X)(X x, int n)  { return 2; }\n\n//int temp;\nref int voo(T)(int n)      { return temp; }\nref int woo(T)(int[] a)    { return temp; }\nref int nar(T)(S s)        { return temp; }\n\nref int naz(T, X)(X x)     { return temp; }\n\nvoid test7722b()\n{\n    int n;\n    int[] a;\n    S s;\n\n    check!(1, 1, x =>    hoo!int(4)     );  check!(1, 1, x =>    vaz!int(4)     );\n    check!(1, 1, x =>  4.hoo!int()      );  check!(1, 1, x =>  4.vaz!int()      );\n    check!(0, 1, x =>  4.hoo!int        );  check!(0, 1, x =>  4.vaz!int        );\n    check!(2, 2, x =>    hoo!int(4, 2)  );  check!(2, 2, x =>    vaz!int(4, 2)  );\n    check!(2, 2, x =>  4.hoo!int(2)     );  check!(2, 2, x =>  4.vaz!int(2)     );\n    check!(0, 2, x => (4.hoo!int = 2)   );  check!(0, 2, x => (4.vaz!int = 2)   );\n\n    check!(1, 1, x =>    koo!int(a)     );  check!(1, 1, x =>    vaz!int(a)     );\n    check!(1, 1, x =>  a.koo!int()      );  check!(1, 1, x =>  a.vaz!int()      );\n    check!(0, 1, x =>  a.koo!int        );  check!(0, 1, x =>  a.vaz!int        );\n    check!(2, 2, x =>    koo!int(a, 2)  );  check!(2, 2, x =>    vaz!int(a, 2)  );\n    check!(2, 2, x =>  a.koo!int(2)     );  check!(2, 2, x =>  a.vaz!int(2)     );\n    check!(0, 2, x => (a.koo!int = 2)   );  check!(0, 2, x => (a.vaz!int = 2)   );\n\n    check!(1, 1, x =>    var!int(s)     );  check!(1, 1, x =>    vaz!int(s)     );\n    check!(1, 1, x =>  s.var!int()      );  check!(1, 1, x =>  s.vaz!int()      );\n    check!(0, 1, x =>  s.var!int        );  check!(0, 1, x =>  s.vaz!int        );\n    check!(2, 2, x =>    var!int(s, 2)  );  check!(2, 2, x =>    vaz!int(s, 2)  );\n    check!(2, 2, x =>  s.var!int(2)     );  check!(2, 2, x =>  s.vaz!int(2)     );\n    check!(0, 2, x => (s.var!int = 2)   );  check!(0, 2, x => (s.vaz!int = 2)   );\n\n    check!(2, 2, x => (  voo!int(4) = 2));  check!(2, 2, x => (  naz!int(4) = 2));\n    check!(0, 2, x => (4.voo!int    = 2));  check!(0, 2, x => (4.naz!int    = 2));\n    check!(2, 2, x => (  woo!int(a) = 2));  check!(2, 2, x => (  naz!int(a) = 2));\n    check!(0, 2, x => (a.woo!int    = 2));  check!(0, 2, x => (a.naz!int    = 2));\n    check!(2, 2, x => (  nar!int(s) = 2));  check!(2, 2, x => (  naz!int(s) = 2));\n    check!(0, 2, x => (s.nar!int    = 2));  check!(0, 2, x => (s.naz!int    = 2));\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7174\n\nvoid test7174()\n{\n    @property bool foo7174() { return true; }\n    static if (foo7174) {}\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7274\n\n@property foo7274(){ return \"test\"; }\n@property bar7274(){ return \"kernel32.lib\"; }\n\npragma(msg, \"decl: \", foo7274);   // print \"decl: foo\", not \"decl: test\"\nversion(Windows) pragma(lib, bar7274); // Error: pragma lib string expected for library name, not 'bar'\n\nvoid test7274()\n{\n    pragma(msg, \"stmt: \", foo7274);  // print \"stmt: foo\", not \"stmt: test\"\n    //pragma(lib, bar);   // Error: pragma(lib) not allowed as statement\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7275\n\nvoid test7275()\n{\n    @property int bar1() { return 0; }\n    @property int bar2() { return 1; }\n    @property int bar3() { return 2; }\n\n    switch (0){\n        case bar1:  break;\n        case bar2: ..\n        case bar3:  break;\n        default:    break;\n    }\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7538\n\nvoid test7538()\n{\n    struct P\n    {\n        @property long pr() { return 1; }\n        @property void pr(int) {}\n\n        @property long a1()() { return 1; }\n        @property void a1()(int) {}\n        template a2() { @property long a2() { return 1; } }\n        template a2() { @property void a2(int) {} }\n        template a3() { long a3() @property { return 1; } }\n        template a3() { void a3(int) @property {} }\n\n      static\n      {\n        @property long b1()() { return 1; }\n        @property void b1()(int) {}\n        template b2() { @property long b2() { return 1; } }\n        template b2() { @property void b2(int) {} }\n        template b3() { long b3() @property { return 1; } }\n        template b3() { void b3(int) @property {} }\n      }\n\n        @property long c1(T)()    { return 1; }\n        @property long c1(T)(int) { return 1; }\n        template c2(T) { @property long c2() { return 1; } }\n        template c2(T) { @property void c2(int) {} }\n        template c3(T) { long c3() @property { return 1; } }\n        template c3(T) { void c3(int) @property {} }\n\n      static\n      {\n        @property long d1(T)() { return 1; }\n        @property void d1(T)(int) {}\n        template d2(T) { @property long d2() { return 1; } }\n        template d2(T) { @property void d2(int) {} }\n        template d3(T) { long d3() @property { return 1; } }\n        template d3(T) { void d3(int) @property {} }\n      }\n\n        void test()\n        {\n            // TOKvar\n            static assert(is(typeof(pr) == long));\n\n            // TOKtemplate\n            static assert(is(typeof(b1) == long));\n            static assert(is(typeof(b2) == long));\n            static assert(is(typeof(b3) == long));\n\n            // TOKimport\n            static assert(is(typeof(d1!int) == long));\n            static assert(is(typeof(d2!int) == long));\n            static assert(is(typeof(d3!int) == long));\n        }\n    }\n    P p;\n    {\n        // TOKdotvar\n        static assert(is(typeof(p.pr) == long));\n\n        // TOKdottd\n        static assert(is(typeof(p.a1) == long));\n        static assert(is(typeof(p.a2) == long));\n        static assert(is(typeof(p.a3) == long));\n\n        // TOKimport\n        static assert(is(typeof(P.b1) == long));\n        static assert(is(typeof(P.b2) == long));\n        static assert(is(typeof(P.b3) == long));\n\n        // TOKdotti;\n        static assert(is(typeof(p.c1!int) == long));\n        static assert(is(typeof(p.c2!int) == long));\n        static assert(is(typeof(p.c3!int) == long));\n    }\n\n    struct F\n    {\n        long fn() { return 1; }\n        void fn(int) {}\n\n        long a1()() { return 1; }\n        void a1()(int) {}\n        template a2() { long a2() { return 1; } }\n        template a2() { void a2(int) {} }\n\n      static\n      {\n        long b1()() { return 1; }\n        void b1()(int) {}\n        template b2() { long b2() { return 1; } }\n        template b2() { void b2(int) {} }\n      }\n\n        long c1(T)()    { return 1; }\n        long c1(T)(int) { return 1; }\n        template c2(T) { long c2() { return 1; } }\n        template c2(T) { void c2(int) {} }\n\n      static\n      {\n        long d1(T)() { return 1; }\n        void d1(T)(int) {}\n        template d2(T) { long d2() { return 1; } }\n        template d2(T) { void d2(int) {} }\n      }\n\n        void test()\n        {\n            // TOKvar\n            static assert( is(typeof(fn) == function));\n\n            // TOKtemplate\n            static assert(!is(typeof(b1) == long));\n            static assert(!is(typeof(b2) == long));\n\n            // TOKimport\n            static assert(!is(typeof(d1!int) == long));\n            static assert(!is(typeof(d2!int) == long));\n        }\n    }\n    F f;\n    {\n        // TOKdotvar\n        static assert(is( typeof(f.fn) == function));\n\n        // TOKdottd\n        static assert(!is(typeof(f.a1) == long));\n        static assert(!is(typeof(f.a2) == long));\n\n        // TOKimport\n        static assert(!is(typeof(F.b1) == long));\n        static assert(!is(typeof(F.b2) == long));\n\n        // TOKdotti;\n        static assert(!is(typeof(f.c1!int) == long));\n        static assert(!is(typeof(f.c2!int) == long));\n    }\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8251\n\nstruct S8251\n{\n    static @property int min() { return 123; }\n}\n@property int T8251_Min() { return 456; }\n\ntemplate T8251a (int v)             { int T8251a  = v; }\n\ntemplate T8251b1(int v = S8251.min) { int T8251b1 = v; }\ntemplate T8251b2(int v = T8251_Min) { int T8251b2 = v; }\n\ntemplate T8251c1(int v : S8251.min) { int T8251c1 = v; }\ntemplate T8251c2(int v : T8251_Min) { int T8251c2 = v; }\n\nvoid test8251()\n{\n    static assert(S8251.min == 123);    // OK\n    static assert(T8251_Min == 456);    // OK\n    int a0 = T8251a!(S8251.min());      // OK\n    int b0 = T8251a!(T8251_Min());      // OK\n\n    // TemplateValueParameter\n    int a1 = T8251a!(S8251.min);        // NG\n    int b1 = T8251a!(T8251_Min);        // NG\n\n    // TemplateValueParameterDefault\n    int a2 = T8251b1!();                // NG\n    int b2 = T8251b2!();                // NG\n\n    // TemplateValueParameterSpecialization\n    int a3 = T8251c1!(123);             // NG\n    int b3 = T8251c2!(456);             // NG\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9063\n\n@property bool foo9063(){ return true; }\nstatic assert(foo9063);\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9234\n\nclass Fizz9234\n{\n    void bar() {}\n    Foo9234!bar foobar;\n}\n\nstruct Foo9234(alias F) {}\nstruct Foo9234(string thunk) {}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10103\n\nmixin template Getter10103()\n{\n    @property auto foo() { return v; }\n    @property auto bar()() { return v; }\n    @property auto baz(T)() { return v; }\n\n    static @property auto goo() { return 1; }\n}\n\nmixin template Setter10103()\n{\n    @property void foo(int x) { v = x; }\n    @property void bar()(int x) { v = x; }\n    @property void baz(T)(int x) { v = x; }\n\n    static @property void goo(int x) {}\n}\n\nstruct Foo10103\n{\n    int v;\n    mixin Getter10103!();\n    mixin Setter10103!();\n}\n\nvoid test10103()\n{\n    auto f = Foo10103(4);\n\n    f.foo;\n    f.foo = 3;\n\n    f.bar;\n    f.bar = 3;\n\n    f.baz!int;\n    f.baz!int = 3;\n\n    Foo10103.goo = 3;\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10197\n\ntemplate OriginalType10197(T)\n{\n    static if (is(T U == enum))\n        alias OriginalType10197 = U;\n    else\n        static assert(0);\n}\n\nvoid test10197()\n{\n    enum E : int { F = -20 }\n    struct S\n    {\n        int val;\n        @trusted @property T as(T)()\n        if (is(T == int) && !is(T == enum))\n        {\n            return cast(T)(val);\n        }\n        @trusted @property T as(T)()\n        if (is(T == enum))\n        {\n            return cast(T)as!(OriginalType10197!T);\n        }\n    }\n\n    S val = S(-20);\n    assert(val.as!int == -20);\n    assert(val.as!E == E.F);\n}\n\n/*****************************************/\n\nint main()\n{\n    test1();\n    test7722();\n    test7722a();\n    test7722b();\n    test7174();\n    test7274();\n    test7275();\n    test7538();\n    test8251();\n    test10103();\n    test10197();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/s2ir.d",
    "content": "\nimport std.stdio;\n\n/***********************************/\n\nvoid test1()\n{\n    int i;\n    __gshared int j;\n\n    version (D_InlineAsm_X86)\n    {\n        asm\n        {\n            naked       ;\n            mov EAX, i  ;\n        }\n      version(D_PIC)\n      {}\n      else\n      {\n        asm\n        {\n            mov EAX, j  ;\n        }\n      }\n    }\n}\n\n/***********************************/\n\nint main()\n{\n    for (int i = 0; ; i++)\n    {\n        if (i == 10)\n            break;\n    }\n\n    string[] a = new string[3];\n    a[0] = \"hello\";\n    a[1] = \"world\";\n    a[2] = \"foo\";\n\n    foreach (string s; a)\n        writefln(s);\n\n    switch (1)\n    {\n        default:\n            break;\n    }\n\n    switch (\"foo\"w)\n    {\n        case \"foo\":\n            break;\n        default: assert(0);\n    }\n\n    switch (1)\n    {\n        case 1:\n            try\n            {\n                goto default;\n            }\n            catch (Throwable o)\n            {\n            }\n            break;\n\n        default:\n            break;\n    }\n\n    switch (1)\n    {\n        case 1:\n            try\n            {\n                goto case 2;\n            }\n            catch (Throwable o)\n            {\n            }\n            break;\n\n        case 2:\n            break;\n\n        default: assert(0);\n    }\n\n    writefln(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/sctor.d",
    "content": "// REQUIRED_ARGS:\n// PERMUTE_ARGS: -w -d -de -dw\n\nextern(C) int printf(const char*, ...);\n\n/***************************************************/\n// mutable field\n\nstruct S1A\n{\n    int v;\n    this(int)\n    {\n        v = 1;\n        v = 2;  // multiple initialization\n    }\n}\n\nstruct S1B\n{\n    int v;\n    this(int)\n    {\n        if (true) v = 1; else v = 2;\n        v = 3;  // multiple initialization\n    }\n    this(long)\n    {\n        if (true) v = 1;\n        v = 3;  // multiple initialization\n    }\n    this(string)\n    {\n        if (true) {} else v = 2;\n        v = 3;  // multiple initialization\n    }\n}\n\nstruct S1C\n{\n    int v;\n    this(int)\n    {\n        true ? (v = 1) : (v = 2);\n        v = 3;  // multiple initialization\n    }\n    this(long)\n    {\n        auto x = true ? (v = 1) : 2;\n        v = 3;  // multiple initialization\n    }\n    this(string)\n    {\n        auto x = true ? 1 : (v = 2);\n        v = 3;  // multiple initialization\n    }\n}\n\n/***************************************************/\n// with control flow\n\nstruct S2\n{\n    immutable int v;\n    immutable int w;\n    int x;\n    this(int)\n    {\n        if (true) v = 1;\n        else      v = 2;\n\n        true ? (w = 1) : (w = 2);\n\n        x = 1;  // initialization\n    L:  x = 2;  // assignment after labels\n    }\n    this(long n)\n    {\n        if (n > 0)\n            return;\n        v = 1;  // skipped initialization\n\n        // w skipped initialization\n\n        x = 1;  // initialization\n        foreach (i; 0..1) x = 2;  // assignment in loops\n    }\n}\n\n/***************************************************/\n// with immutable constructor\n\nstruct S3\n{\n    int v;\n    int w;\n    this(int) immutable\n    {\n        if (true) v = 1;\n        else      v = 2;\n\n        true ? (w = 1) : (w = 2);\n    }\n}\n\n/***************************************************/\n// in typeof\n\nstruct S4\n{\n    immutable int v;\n    this(int)\n    {\n        static assert(is(typeof(v = 1)));\n        v = 1;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8117\n\nstruct S8117\n{\n    @disable this();\n    this(int) {}\n}\n\nclass C8117\n{\n    S8117 s = S8117(1);\n}\n\nvoid test8117()\n{\n    auto t = new C8117();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9665\n\nstruct X9665\n{\n    static uint count;\n    ulong payload;\n    this(int n) { payload = n; count += 1; }\n    this(string s) immutable { payload = s.length; count += 10; }\n    void opAssign(X9665 x) { payload = 100; count += 100; }\n}\n\nstruct S9665\n{\n              X9665 mval;\n    immutable X9665 ival;\n    this(int n)\n    {\n        X9665.count = 0;\n        mval = X9665(n);                // 1st, initializing\n        ival = immutable X9665(\"hi\");   // 1st, initializing\n        mval = X9665(1);                // 2nd, assignment\n        static assert(!__traits(compiles, ival = immutable X9665(1)));  // 2nd, assignment\n        //printf(\"X9665.count = %d\\n\", X9665.count);\n        assert(X9665.count == 112);\n    }\n    this(int[])\n    {\n        X9665.count = 0;\n        mval = 1;       // 1st, initializing (implicit constructor call)\n        ival = \"hoo\";   // ditto\n        assert(X9665.count == 11);\n    }\n}\n\nvoid test9665()\n{\n    S9665 s1 = S9665(1);\n    assert(s1.mval.payload == 100);\n    assert(s1.ival.payload == 2);\n\n    S9665 s2 = S9665([]);\n    assert(s2.mval.payload == 1);\n    assert(s2.ival.payload == 3);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11246\n\nstruct Foo11246\n{\n    static int ctor = 0;\n    static int dtor = 0;\n    this(int i)\n    {\n        ++ctor;\n    }\n\n    ~this()\n    {\n        ++dtor;\n    }\n}\n\nstruct Bar11246\n{\n    Foo11246 foo;\n\n    this(int)\n    {\n        foo = Foo11246(5);\n        assert(Foo11246.ctor == 1);\n        assert(Foo11246.dtor == 0);\n    }\n}\n\nvoid test11246()\n{\n    {\n        auto bar = Bar11246(1);\n        assert(Foo11246.ctor == 1);\n        assert(Foo11246.dtor == 0);\n    }\n    assert(Foo11246.ctor == 1);\n    assert(Foo11246.dtor == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13515\n\nObject[string][100] aa13515;\n\nstatic this()\n{\n    aa13515[5][\"foo\"] = null;\n}\n\nstruct S13515\n{\n    Object[string][100] aa;\n\n    this(int n)\n    {\n        aa[5][\"foo\"] = null;\n    }\n}\n\nvoid test13515()\n{\n    assert(aa13515[5].length == 1);\n    assert(aa13515[5][\"foo\"] is null);\n\n    auto s = S13515(1);\n    assert(s.aa[5].length == 1);\n    assert(s.aa[5][\"foo\"] is null);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14409\n\nclass B14409 { this(int) {} }\nclass C14409 : B14409\n{\n    this(int n)\n    {\n        if (true)\n            super(n);\n        else\n            assert(0);\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14376\n\nauto map14376()\n{\n    return MapResult14376!(e => 0)();\n}\n\nstruct MapResult14376(alias pred)\n{\n    @property int front() { return pred(0); }\n}\n\nstruct S14376\n{\n    typeof(map14376()) x;\n\n    this(int dummy)\n    {\n        if (true)\n            this.x = map14376();\n        else\n            assert(0);\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14351\n\nclass B14351\n{\n    this(inout int[]) inout { }\n}\n\nclass D14351a : B14351\n{\n    this(int[] arr) { super(arr); }\n}\n\nclass D14351b : B14351\n{\n    this(const int[] arr) const { super(arr); }\n}\n\nclass D14351c : B14351\n{\n    this(inout int[] arr) inout { super(arr); }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14450\n\nstruct S14450a      // non-template struct + non template ctors - OK\n{\n    int x;\n    this(int) { x = 1; }\n    this(int) immutable { x = 2; }\n}\nstruct S14450b      // non-template struct + template ctors - OK\n{\n    int x;\n    this()(int) { x = 1; }\n    this()(int) immutable { x = 2; }\n}\nstruct S14450c()    // template struct + non-template ctors - Error -> OK\n{\n    int x;\n    this(int) { x = 1; }\n    this(int) immutable { x = 2; }\n}\nstruct S14450d()    // template struct + template ctors - OK\n{\n    int x;\n    this()(int) { x = 1; }\n    this()(int) immutable { x = 2; }\n}\nstruct S14450e() // template struct + pure template ctors - Error -> OK\n{\n    int x;\n    this()(int) pure { x = 1; }\n    this()(int) pure immutable { x = 2; }\n}\n\nvoid test14450()\n{\n    { auto m = S14450a(1);    assert(m.x == 1); }\n    { auto m = S14450b(1);    assert(m.x == 1); }\n    { auto m = S14450c!()(1); assert(m.x == 1); }\n    { auto m = S14450d!()(1); assert(m.x == 1); }\n    { auto m = S14450e!()(1); assert(m.x == 1); }\n\n    { auto i = immutable S14450a(1);    assert(i.x == 2); }\n    { auto i = immutable S14450b(1);    assert(i.x == 2); }\n    { auto i = immutable S14450c!()(1); assert(i.x == 2); }\n    { auto i = immutable S14450d!()(1); assert(i.x == 2); }\n    { auto i = immutable S14450e!()(1); assert(i.x == 2); }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14944\n\nstatic int[2] tbl14944;\n\nstatic this()\n{\n    foreach (ref v; tbl14944)\n    {\n        // This is an initialization of referenced memory\n        // rather than the initialization of the reference.\n        v = 1;\n    }\n}\n\nvoid test14944()\n{\n    assert(tbl14944[0] == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15258\n// a field initialization affects other overlapped fields\n\nclass C15258\n{\n    this(const char* result)\n    {\n        this.result = result;\n    }\n\n    union\n    {\n        const char** results;\n        const char* result;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15665\n\nscope class C15665 (V)\n{\n    this () {}\n}\n\nvoid test15665()\n{\n    scope foo = new C15665!int;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15869\n\nstruct Set {\n    @disable this(this);\n    int value = 0;\n}\n\nSet clobber(ref Set a) {\n    Set ret; // <- This overwrites *a, i.e. &ret is the same as a\n    ret.value = a.value; // <- Now a.value is 0\n    return ret;\n}\n\nstruct XX {\n    Set a = Set(1);\n    this(int n) {\n        a = clobber(a); // fix is to make this an assignment, not a construction\n    }\n}\nvoid test15869()\n{\n    Set a = Set(1);\n    a = clobber(a);\n    assert(a.value == 1);\n\n    XX xx = XX(0);\n    assert(xx.a.value == 1);\n}\n\n/***************************************************/\n\nint main()\n{\n    test8117();\n    test9665();\n    test11246();\n    test13515();\n    test14450();\n    test14944();\n    test15665();\n    test15869();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/sdtor.d",
    "content": "// PERMUTE_ARGS: -unittest -O -release -inline -g\n// REQUIRED_ARGS: -transition=dtorfields\n\nimport core.vararg;\n\nextern (C) int printf(const(char*) fmt, ...) nothrow;\n\ntemplate TypeTuple(T...) { alias TypeTuple = T; }\n\n/**********************************/\n\nint sdtor;\n\nstruct S1\n{\n    ~this() { printf(\"~S()\\n\"); sdtor++; }\n}\n\nvoid test1()\n{\n    S1* s = new S1();\n    delete s;\n    assert(sdtor == 1);\n}\n\n/**********************************/\n\nint sdtor2;\n\nstruct S2\n{\n    ~this() { printf(\"~S2()\\n\"); sdtor2++; }\n    delete(void* p) { assert(sdtor2 == 1); printf(\"S2.delete()\\n\"); sdtor2++; }\n}\n\nvoid test2()\n{\n    S2* s = new S2();\n    delete s;\n    assert(sdtor2 == 2);\n}\n\n/**********************************/\n\nint sdtor3;\n\nstruct S3\n{   int a;\n    ~this() { printf(\"~S3()\\n\"); sdtor3++; assert(a == 3); }\n}\n\nstruct T3\n{\n    int i;\n    S3 s;\n}\n\nvoid test3()\n{\n    T3* s = new T3();\n    s.s.a = 3;\n    delete s;\n    assert(sdtor3 == 1);\n}\n\n/**********************************/\n\nint sdtor4;\n\nstruct S4\n{   int a = 3;\n    ~this()\n    {   printf(\"~S4()\\n\");\n        if (a == 4)\n            assert(sdtor4 == 2);\n        else\n        {   assert(a == 3);\n            assert(sdtor4 == 1);\n        }\n        sdtor4++;\n    }\n}\n\nstruct T4\n{\n    int i;\n    S4 s;\n    ~this() { printf(\"~T4()\\n\"); assert(sdtor4 == 0); sdtor4++; }\n    S4 t;\n}\n\nvoid test4()\n{\n    T4* s = new T4();\n    s.s.a = 4;\n    delete s;\n    assert(sdtor4 == 3);\n}\n\n/**********************************/\n\nint sdtor5;\n\ntemplate M5()\n{  ~this()\n   {\n        printf(\"~M5()\\n\"); assert(sdtor5 == 1); sdtor5++;\n   }\n}\n\nstruct T5\n{\n    mixin M5 m;\n    ~this() { printf(\"~T5()\\n\"); assert(sdtor5 == 0); sdtor5++; }\n}\n\nvoid test5()\n{\n    T5* s = new T5();\n    delete s;\n    assert(sdtor5 == 2);\n}\n\n/**********************************/\n\nint sdtor6;\n\nstruct S6\n{   int b = 7;\n    ~this()\n    {\n        printf(\"~S6()\\n\"); assert(b == 7); assert(sdtor6 == 1); sdtor6++;\n    }\n}\n\nclass T6\n{\n    int a = 3;\n    S6 s;\n    ~this() { printf(\"~T6()\\n\"); assert(a == 3); assert(sdtor6 == 0); sdtor6++; }\n}\n\nvoid test6()\n{\n    T6 s = new T6();\n    delete s;\n    assert(sdtor6 == 2);\n}\n\n/**********************************/\n\nint sdtor7;\n\nstruct S7\n{   int b = 7;\n    ~this()\n    {\n        printf(\"~S7()\\n\");\n        assert(b == 7);\n        assert(sdtor7 >= 1 && sdtor7 <= 3);\n        sdtor7++;\n    }\n}\n\nstruct T7\n{\n    int a = 3;\n    S7[3] s;\n    ~this()\n    {   printf(\"~T7() %d\\n\", sdtor7);\n        assert(a == 3);\n        assert(sdtor7 == 0);\n        sdtor7++;\n    }\n}\n\nvoid test7()\n{\n    T7* s = new T7();\n    delete s;\n    assert(sdtor7 == 4);\n}\n\n/**********************************/\n\nint sdtor8;\n\nstruct S8\n{   int b = 7;\n    int c;\n    ~this()\n    {\n        printf(\"~S8() %d\\n\", sdtor8);\n        assert(b == 7);\n        assert(sdtor8 == c);\n        sdtor8++;\n    }\n}\n\nvoid test8()\n{\n    S8[] s = new S8[3];\n    s[0].c = 2;\n    s[1].c = 1;\n    s[2].c = 0;\n    delete s;\n    assert(sdtor8 == 3);\n}\n\n/**********************************/\n\nint sdtor9;\n\nstruct S9\n{   int b = 7;\n    ~this()\n    {\n        printf(\"~S9() %d\\n\", sdtor9);\n        assert(b == 7);\n        sdtor9++;\n    }\n}\n\nvoid test9()\n{\n    {\n    S9 s;\n    }\n    assert(sdtor9 == 1);\n}\n\n/**********************************/\n\nint sdtor10;\n\nstruct S10\n{   int b = 7;\n    int c;\n    ~this()\n    {\n        printf(\"~S10() %d\\n\", sdtor10);\n        assert(b == 7);\n        assert(sdtor10 == c);\n        sdtor10++;\n    }\n}\n\nvoid test10()\n{\n    {\n    S10[3] s;\n    s[0].c = 2;\n    s[1].c = 1;\n    s[2].c = 0;\n    }\n    assert(sdtor10 == 3);\n}\n\n/**********************************/\n\nint sdtor11;\n\ntemplate M11()\n{   ~this()\n    {\n        printf(\"~M11()\\n\"); assert(sdtor11 == 1); sdtor11++;\n    }\n}\n\nclass T11\n{\n    mixin M11 m;\n    ~this() { printf(\"~T11()\\n\"); assert(sdtor11 == 0); sdtor11++; }\n}\n\nvoid test11()\n{\n    T11 s = new T11();\n    delete s;\n    assert(sdtor11 == 2);\n}\n\n/**********************************/\n\nint sdtor12;\n\nstruct S12\n{   int a = 3;\n    ~this() { printf(\"~S12() %d\\n\", sdtor12); sdtor12++; }\n}\n\nvoid foo12(S12 s)\n{\n}\n\nvoid test12()\n{\n    {\n    S12 s;\n    foo12(s);\n    s.a = 4;\n    }\n    assert(sdtor12 == 2);\n}\n\n/**********************************/\n\nstruct S13\n{   int a = 3;\n    int opAssign(S13 s)\n    {\n        printf(\"S13.opAssign(%p)\\n\", &this);\n        a = 4;\n        return s.a + 2;\n    }\n}\n\nvoid test13()\n{\n    S13 s;\n    S13 t;\n    assert((s = t) == 5);\n    assert(s.a == 4);\n}\n\n/**********************************/\n\nstruct S14\n{   int a = 3;\n    int opAssign(ref S14 s)\n    {\n        printf(\"S14.opAssign(%p)\\n\", &this);\n        a = 4;\n        return s.a + 2;\n    }\n}\n\nvoid test14()\n{\n    S14 s;\n    S14 t;\n    assert((s = t) == 5);\n    assert(s.a == 4);\n}\n\n/**********************************/\n\nstruct S15\n{   int a = 3;\n    int opAssign(ref const S15 s)\n    {\n        printf(\"S15.opAssign(%p)\\n\", &this);\n        a = 4;\n        return s.a + 2;\n    }\n}\n\nvoid test15()\n{\n    S15 s;\n    S15 t;\n    assert((s = t) == 5);\n    assert(s.a == 4);\n}\n\n/**********************************/\n\nstruct S16\n{   int a = 3;\n    int opAssign(S16 s, ...)\n    {\n        printf(\"S16.opAssign(%p)\\n\", &this);\n        a = 4;\n        return s.a + 2;\n    }\n}\n\nvoid test16()\n{\n    S16 s;\n    S16 t;\n    assert((s = t) == 5);\n    assert(s.a == 4);\n}\n\n/**********************************/\n\nstruct S17\n{   int a = 3;\n    int opAssign(...)\n    {\n        printf(\"S17.opAssign(%p)\\n\", &this);\n        a = 4;\n        return 5;\n    }\n}\n\nvoid test17()\n{\n    S17 s;\n    S17 t;\n    assert((s = t) == 5);\n    assert(s.a == 4);\n}\n\n/**********************************/\n\nstruct S18\n{   int a = 3;\n    int opAssign(S18 s, int x = 7)\n    {\n        printf(\"S18.opAssign(%p)\\n\", &this);\n        a = 4;\n        assert(x == 7);\n        return s.a + 2;\n    }\n}\n\nvoid test18()\n{\n    S18 s;\n    S18 t;\n    assert((s = t) == 5);\n    assert(s.a == 4);\n}\n\n/**********************************/\n\nstruct S19\n{\n    int a,b,c,d;\n    this(this) { printf(\"this(this) %p\\n\", &this); }\n    ~this() { printf(\"~this() %p\\n\", &this); }\n}\n\nS19 foo19()\n{\n    S19 s;\n    void bar() { s.a++; }\n    bar();\n    return s;\n}\n\nvoid test19()\n{\n    S19 t = foo19();\n    printf(\"-main()\\n\");\n}\n\n/**********************************/\n\nstruct S20\n{\n    static char[] r;\n    int a,b,c=2,d;\n    this(this) { printf(\"this(this) %p\\n\", &this); r ~= '='; }\n    ~this() { printf(\"~this() %p\\n\", &this); r ~= '~'; }\n}\n\nvoid foo20()\n{\n    S20 s;\n    S20[3] a;\n    assert(S20.r == \"\");\n    a = s;\n    assert(S20.r == \"=~=~=~\");\n}\n\nvoid test20()\n{\n    foo20();\n    assert(S20.r == \"=~=~=~~~~~\");\n    printf(\"-main()\\n\");\n}\n\n/**********************************/\n\nstruct S21\n{\n    static char[] r;\n    int a,b,c=2,d;\n    this(this) { printf(\"this(this) %p\\n\", &this); r ~= '='; }\n    ~this() { printf(\"~this() %p\\n\", &this); r ~= '~'; }\n}\n\nvoid foo21()\n{\n    S21 s;\n    S21[3] a = s;\n    assert(S21.r == \"===\");\n    S21.r = null;\n    S21[3][2] b = s;\n    assert(S21.r == \"======\");\n    S21.r = null;\n}\n\nvoid test21()\n{\n    foo21();\n    assert(S21.r == \"~~~~~~~~~~\");\n    printf(\"-main()\\n\");\n}\n\n/**********************************/\n\nstruct S22\n{\n    static char[] r;\n    int a,b,c=2,d;\n    this(this) { printf(\"this(this) %p\\n\", &this); r ~= '='; }\n    ~this() { printf(\"~this() %p\\n\", &this); r ~= '~'; }\n}\n\nvoid foo22()\n{\n    S22[3] s;\n    S22[3][2] a;\n    assert(S22.r == \"\");\n    a = s;\n    assert(S22.r == \"===~~~===~~~\");\n    S22.r = null;\n}\n\nvoid test22()\n{\n    foo22();\n    assert(S22.r == \"~~~~~~~~~\");\n    printf(\"-main()\\n\");\n}\n\n\n/************************************************/\n\nstruct S23\n{\n    int m = 4, n, o, p, q;\n\n    this(int x)\n    {\n        printf(\"S23(%d)\\n\", x);\n        assert(x == 3);\n        assert(m == 4 && n == 0 && o == 0 && p == 0 && q == 0);\n        q = 7;\n    }\n}\n\nvoid test23()\n{\n  {\n    auto s = S23(3);\n    printf(\"s.m = %d, s.n = %d, s.q = %d\\n\", s.m, s.n, s.q);\n    assert(s.m == 4 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);\n  }\n  {\n    auto s = new S23(3);\n    printf(\"s.m = %d, s.n = %d, s.q = %d\\n\", s.m, s.n, s.q);\n    assert(s.m == 4 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);\n  }\n  {\n    S23 s;\n    s = S23(3);\n    printf(\"s.m = %d, s.n = %d, s.q = %d\\n\", s.m, s.n, s.q);\n    assert(s.m == 4 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);\n  }\n}\n\n/************************************************/\n\nstruct S24\n{\n    int m, n, o, p, q;\n\n    this(int x)\n    {\n        printf(\"S24(%d)\\n\", x);\n        assert(x == 3);\n        assert(m == 0 && n == 0 && o == 0 && p == 0 && q == 0);\n        q = 7;\n    }\n}\n\nvoid test24()\n{\n  {\n    auto s = S24(3);\n    printf(\"s.m = %d, s.n = %d, s.q = %d\\n\", s.m, s.n, s.q);\n    assert(s.m == 0 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);\n  }\n  {\n    auto s = new S24(3);\n    printf(\"s.m = %d, s.n = %d, s.q = %d\\n\", s.m, s.n, s.q);\n    assert(s.m == 0 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);\n  }\n  {\n    S24 s;\n    s = S24(3);\n    printf(\"s.m = %d, s.n = %d, s.q = %d\\n\", s.m, s.n, s.q);\n    assert(s.m == 0 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);\n  }\n}\n\n/**********************************/\n\nstruct S25\n{\n    this(int s) {}\n}\n\nvoid test25()\n{\n    auto a = S25();\n}\n\n/**********************************/\n\nint z26;\n\nstruct A26\n{\n    int id;\n    this(int x) { id = x; printf(\"Created A from scratch: %d\\n\", x); z26++; }\n    this(this) { printf(\"Copying A: %d\\n\", id); z26 += 10; }\n    ~this() { printf(\"Destroying A: %d\\n\", id); z26 += 100; }\n}\n\nstruct B26\n{\n    A26 member;\n    this(this) { printf(\"Copying B: %d\\n\", member.id); assert(0); }\n}\n\nB26 foo26()\n{\n    A26 a = A26(45);\n    printf(\"1\\n\");\n    assert(z26 == 1);\n    return B26(a);\n}\n\nvoid test26()\n{\n    {\n    auto b = foo26();\n    assert(z26 == 111);\n    printf(\"2\\n\");\n    }\n    assert(z26 == 211);\n}\n\n/**********************************/\n\nint z27;\n\nstruct A27\n{\n    int id;\n    this(int x) { id = x; printf(\"Ctor A27: %d\\n\", x); z27++; }\n    this(this) { printf(\"Copying A27: %d\\n\", id); z27 += 10; }\n    ~this() { printf(\"Destroying A27: %d\\n\", id); z27 += 100; }\n}\n\nstruct B27\n{\n    A27[2][3] member;\n}\n\nvoid test27()\n{\n  {\n    A27[2][3] a;\n    assert(z27 == 0);\n    B27 b = B27(a);\n    assert(z27 == 60);\n  }\n  assert(z27 == 1260);\n}\n\n\n/**********************************/\n\nstring s28;\n\nstruct A28\n{\n    this(this)\n    {\n        printf(\"A's copy\\n\");\n        s28 ~= \"A\";\n    }\n}\n\nstruct B28\n{\n    A28 member;\n    this(this)\n    {\n        printf(\"B's copy\\n\");\n        s28 ~= \"B\";\n    }\n}\n\nvoid test28()\n{\n    B28 b1;\n    B28 b2 = b1;\n    assert(s28 == \"AB\");\n}\n\n\n/**********************************/\n\nstring s29;\n\ntemplate Templ29 ()\n{\n    this(int i) { this(0.0); s29 ~= \"i\"; }\n    this(double d) { s29 ~= \"d\"; }\n}\n\nclass C29 { mixin Templ29; }\nstruct S29 { mixin Templ29; }\n\nvoid test29()\n{\n    auto r = S29(1);\n    assert(s29 == \"di\");\n\n    r = S29(2.0);\n    assert(s29 == \"did\");\n\n    auto c = new C29(2);\n    assert(s29 == \"diddi\");\n\n    auto c2 = new C29(2.0);\n    assert(s29 == \"diddid\");\n}\n\n/**********************************/\n\nstruct S30\n{\n    int x;\n    this(T)(T args) { x = args + 1; }\n}\n\nvoid test30()\n{\n    auto s = S30(3);\n    assert(s.x == 4);\n}\n\n/**********************************/\n\nstruct S31\n{\n    int x;\n    this(T...)(T args) { x = args[0] + 1; }\n}\n\nvoid test31()\n{\n    auto s = S31(3);\n    assert(s.x == 4);\n}\n\n/**********************************/\n\nstruct S32\n{\n    static int x;\n\n    this(int i)\n    {\n        printf(\"ctor %p(%d)\\n\", &this, i);\n        x += 1;\n    }\n\n    this(this)\n    {\n        printf(\"postblit %p\\n\", &this);\n        x += 0x10;\n    }\n\n    ~this()\n    {\n        printf(\"dtor %p\\n\", &this);\n        x += 0x100;\n    }\n}\n\nS32 foo32()\n{\n    printf(\"test1\\n\");\n    return S32(1);\n}\n\nS32 bar32()\n{\n    printf(\"test1\\n\");\n    S32 f = S32(1);\n    printf(\"test2\\n\");\n    return f;\n}\n\nvoid test32()\n{\n  {\n    S32 s = foo32();\n  }\n  assert(S32.x == 0x101);\n\n  S32.x = 0;\n  {\n    S32 s = bar32();\n  }\n  assert(S32.x == 0x101);\n}\n\n/**********************************/\n\nstruct S33\n{\n    static int x;\n\n    this(int i)\n    {\n        printf(\"ctor %p(%d)\\n\", &this, i);\n        x += 1;\n    }\n\n    this(this)\n    {\n        printf(\"postblit %p\\n\", &this);\n        x += 0x10;\n    }\n\n    ~this()\n    {\n        printf(\"dtor %p\\n\", &this);\n        x += 0x100;\n    }\n}\n\nstruct T33\n{\n    S33 foo()\n    {\n        return t;\n    }\n\n    S33 t;\n}\n\nvoid test33()\n{\n    {\n        T33 t;\n        S33 s = t.foo();\n    }\n    printf(\"S.x = %x\\n\", S33.x);\n    assert(S33.x == 0x210);\n}\n\n/**********************************/\n\nstruct X34 {\n    int i;\n    this(this) {\n        printf(\"postblit %p\\n\", &this);\n        ++i;\n    }\n\n    ~this() {\n        printf(\"dtor %p\\n\", &this);\n    }\n}\n\nvoid test34()\n{\n    X34[2] xs;\n//  xs[0][0] = X34();\n    printf(\"foreach\\n\");\n    for (int j = 0; j < xs.length; j++) {\n        j++,j--;\n        auto x = xs[j];\n        //foreach(x; xs) {\n        //printf(\"foreach x.i = %d\\n\", x[0].i);\n        //assert(x[0].i == 1);\n        printf(\"foreach x.i = %d\\n\", x.i);\n        assert(x.i == 1);\n    }\n    printf(\"loop done\\n\");\n}\n\n/**********************************/\n\nstruct X35 {\n    __gshared int k;\n    int i;\n    this(this) {\n        printf(\"postblit %p\\n\", &this);\n        ++i;\n    }\n\n    ~this() {\n        printf(\"dtor %p\\n\", &this);\n        k++;\n    }\n}\n\nvoid test35()\n{\n    {\n        X35[2] xs;\n        printf(\"foreach\\n\");\n        foreach(ref x; xs) {\n            printf(\"foreach x.i = %d\\n\", x.i);\n            assert(x.i == 0);\n        }\n        printf(\"loop done\\n\");\n    }\n    assert(X35.k == 2);\n}\n\n/**********************************/\n\nstruct X36 {\n    __gshared int k;\n    int i;\n    this(this) {\n        printf(\"postblit %p\\n\", &this);\n        ++i;\n    }\n\n    ~this() {\n        printf(\"dtor %p\\n\", &this);\n        k++;\n    }\n}\n\nvoid test36()\n{\n    {\n        X36[2] xs;\n        printf(\"foreach\\n\");\n        foreach(x; xs) {\n            printf(\"foreach x.i = %d\\n\", x.i);\n            assert(x.i == 1);\n        }\n        printf(\"loop done\\n\");\n    }\n    assert(X36.k == 4);\n}\n\n/**********************************/\n\nstruct X37 {\n    __gshared int k;\n    int i;\n    this(this) {\n        printf(\"postblit %p\\n\", &this);\n        ++i;\n    }\n\n    ~this() {\n        printf(\"dtor %p\\n\", &this);\n        k++;\n    }\n}\n\nvoid test37() {\n    {\n        X37[2][3] xs;\n        printf(\"foreach\\n\");\n        foreach(ref x; xs) {\n            printf(\"foreach x.i = %d\\n\", x[0].i);\n            assert(x[0].i == 0);\n        }\n        printf(\"loop done\\n\");\n    }\n  assert(X37.k == 6);\n}\n\n/**********************************/\n\nstruct S38 {\n    __gshared int count;\n    __gshared int postblit;\n\n    this(int x) {\n        printf(\"this(%d)\\n\", x);\n        assert(this.x == 0);\n        this.x = x;\n        count++;\n    }\n    this(this) {\n        printf(\"this(this) with %d\\n\", x);\n        assert(x == 1 || x == 2);\n        count++;\n        postblit++;\n    }\n    ~this() {\n        printf(\"~this(%d)\\n\", x);\n        assert(x == 1 || x == 2);\n        x = 0;\n        count--;\n    }\n    int x;\n}\n\nS38 foo38() {\n    auto s = S38(1);\n    return s;\n}\n\nS38 bar38() {\n    return S38(2);\n}\n\nvoid test38()\n{\n  {\n    auto s1 = foo38();\n    assert(S38.count == 1);\n    assert(S38.postblit == 0);\n  }\n  assert(S38.count == 0);\n  S38.postblit = 0;\n\n  {\n    auto s2 = bar38();\n    assert(S38.count == 1);\n    assert(S38.postblit == 0);\n  }\n  assert(S38.count == 0);\n}\n\n\n/**********************************/\n\nstruct Foo39\n{\n    int x;\n    this(int v){ x = v + 1; }\n    void opAssign(int v){\n        x = v + 3;\n    }\n}\n\nvoid test39()\n{\n    int y = 5;\n    Foo39 f = y;\n    assert(f.x == 6);\n    f = y;\n    assert(f.x == 8);\n//  f = Foo39(y);\n\n}\n\n/**********************************/\n\nbool approxEqual(float a, float b)\n{\n    return a < b ? b-a < .001 : a-b < .001;\n}\n\nstruct Point {\n    float x = 0, y = 0;\n    const bool opEquals(const ref Point rhs)\n    {\n        return approxEqual(x, rhs.x) && approxEqual(y, rhs.y);\n    }\n}\n\nstruct Rectangle {\n   Point leftBottom, rightTop;\n}\n\nvoid test40()\n{\n   Rectangle a, b;\n   assert(a == b);\n   a.leftBottom.x = 1e-8;\n   assert(a == b);\n   a.rightTop.y = 5;\n   assert(a != b);\n}\n\n/**********************************/\n\nstruct S41 {\n   this(int) immutable {   }\n}\n\nvoid test41()\n{\n    auto s = new immutable S41(3);\n    //writeln(typeid(typeof(s)));\n    static assert(is(typeof(s) == immutable(S41)*));\n\n    auto t = immutable S41(3);\n    //writeln(typeid(typeof(t)));\n    static assert(is(typeof(t) == immutable(S41)));\n}\n\n/**********************************/\n\nclass C42 {\n   this(int) immutable {\n   }\n}\n\nvoid test42()\n{\n    static assert(!__traits(compiles, new C42(3)));\n    //writeln(typeid(typeof(c)));\n    //static assert(is(typeof(c) == immutable(C42)));\n\n    auto d = new immutable(C42)(3);\n    //writeln(typeid(typeof(d)));\n    static assert(is(typeof(d) == immutable(C42)));\n}\n\n/**********************************/\n\nstruct S43 {\n    int i;\n    int* p;\n//  this(int i, int* t) immutable { this.i = i; p = t;  }\n}\n\nvoid test43()\n{\n    int i;\n    assert(!__traits(compiles, immutable(S43)(3, &i)));\n    immutable int j = 4;\n    auto s = immutable(S43)(3, &j);\n    //writeln(typeid(typeof(s)));\n    static assert(is(typeof(s) == immutable(S43)));\n}\n\n/**********************************/\n\nstruct S44 {\n    int i;\n    immutable(int)* p;\n    this(int i, immutable(int)* t) immutable { this.i = i; this.p = t;  }\n}\n\nvoid test44()\n{\n    int i;\n    assert(!__traits(compiles, immutable(S44)(3, &i)));\n    immutable int j = 4;\n    auto s = immutable(S44)(3, &j);\n    //writeln(typeid(typeof(s)));\n    static assert(is(typeof(s) == immutable(S44)));\n}\n\n/**********************************/\n\nclass C45 {\n    C45 next;\n    this(int[] data) immutable {\n        next = new immutable(C45)(data[1 .. $]);\n    }\n}\n\nvoid test45()\n{\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=3986\n\nstruct SiberianHamster\n{\n   int rat = 813;\n   this(string z) { }\n}\n\nvoid test46()\n{\n   SiberianHamster basil = \"cybil\";\n   assert(basil.rat == 813);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8741\n\nstruct Vec8741\n{\n    this(float x)\n    {\n        m[0] = x;\n        m[1] = 58;\n    }\n    float[2] m;\n    static Vec8741 zzz = Vec8741(7);\n}\n\nvoid test8741()\n{\n    assert(Vec8741.zzz.m[0] == 7);\n    assert(Vec8741.zzz.m[1] == 58);\n}\n\n/**********************************/\n\nstruct Segfault3984\n{\n    int a;\n    this(int x){\n        a = x;\n    }\n}\n\nvoid test47()\n{\n    //static\n    assert(Segfault3984(3).a == 3);\n}\n\n/**********************************/\n\nvoid test48()\n{\n    struct B {\n        void foo()  {   }\n    }\n    B x = B.init;\n}\n\n/**********************************/\n\nstruct Foo49 {\n   int z;\n   this(int a){z=a;}\n}\n\nvoid bar49(Foo49 a = Foo49(1))\n{\n    assert(a.z == 1);\n}\n\nvoid test49()\n{\n    bar49();\n    bar49();\n}\n\n/**********************************/\n\nstruct aStruct{\n    int    m_Int;\n\n    this(int a){\n        m_Int = a;\n    }\n}\n\nclass aClass{\n    void aFunc(aStruct a = aStruct(44))\n    {\n        assert(a.m_Int == 44);\n    }\n}\n\nvoid test50()\n{\n    aClass a = new aClass();\n    a.aFunc();\n    a.aFunc();\n}\n\n/**********************************/\n\nint A51_a;\n\nstruct A51\n{\n    ~this() { ++A51_a; }\n}\n\nvoid test51()\n{\n  A51_a = 0; { while(0) A51 a;                      } assert(A51_a == 0);\n  A51_a = 0; { if(0) A51 a;                         } assert(A51_a == 0);\n  A51_a = 0; { if(1){} else A51 a;                  } assert(A51_a == 0);\n  A51_a = 0; { for(;0;) A51 a;                      } assert(A51_a == 0);\n  A51_a = 0; { if (1) { A51 a; }                    } assert(A51_a == 1);\n  A51_a = 0; { if (1) A51 a;                        } assert(A51_a == 1);\n  A51_a = 0; { if(0) {} else A51 a;                 } assert(A51_a == 1);\n  A51_a = 0; { if (0) for(A51 a;;) {}               } assert(A51_a == 0);\n  A51_a = 0; { if (0) for(;;) A51 a;                } assert(A51_a == 0);\n  A51_a = 0; { do A51 a; while(0);                  } assert(A51_a == 1);\n  A51_a = 0; { if (0) while(1) A51 a;               } assert(A51_a == 0);\n  A51_a = 0; { try A51 a; catch(Error e) {}         } assert(A51_a == 1);\n  A51_a = 0; { if (0) final switch(1) A51 a;        } assert(A51_a == 0); // should fail to build\n//  A51_a = 0; { if (0) switch(1) { A51 a; default: } } assert(A51_a == 0);\n  A51_a = 0; { if (0) switch(1) { default: A51 a; } } assert(A51_a == 0);\n//  A51_a = 0; { if (1) switch(1) { A51 a; default: } } assert(A51_a == 1); // should be 0, right?\n  A51_a = 0; { if (1) switch(1) { default: A51 a; } } assert(A51_a == 1);\n//  A51_a = 0; { final switch(0) A51 a;               } assert(A51_a == 0);\n  A51_a = 0; { A51 a; with(a) A51 b;                } assert(A51_a == 2);\n}\n\n/**********************************/\n\nstring s52;\n\nstruct A52\n{\n    int m;\n    this(this)\n    {\n        printf(\"this(this) %p\\n\", &this);\n        s52 ~= 'a';\n    }\n    ~this()\n    {\n        printf(\"~this() %p\\n\", &this);\n        s52 ~= 'b';\n    }\n    A52 copy()\n    {\n        s52 ~= 'c';\n        A52 another = this;\n        return another;\n    }\n}\n\nvoid test52()\n{\n  {\n    A52 a;\n    A52 b = a.copy();\n    printf(\"a: %p, b: %p\\n\", &a, &b);\n  }\n    printf(\"s = '%.*s'\\n\", s52.length, s52.ptr);\n    assert(s52 == \"cabb\");\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=4339\n\nstruct A53 {\n    invariant() {   }\n    ~this() { }\n    void opAssign(A53 a) {}\n    int blah(A53 a) { return 0; }\n}\n\n/**********************************/\n\nstruct S54\n{\n    int x = 1;\n\n    int bar() { return x; }\n\n    this(int i)\n    {\n        printf(\"ctor %p(%d)\\n\", &this, i);\n        t ~= \"a\";\n    }\n\n    this(this)\n    {\n        printf(\"postblit %p\\n\", &this);\n        t ~= \"b\";\n    }\n\n    ~this()\n    {\n        printf(\"dtor %p\\n\", &this);\n        t ~= \"c\";\n    }\n\n    static string t;\n}\n\nvoid bar54(S54 s) { }\n\nS54 abc54() { return S54(1); }\n\nvoid test54()\n{\n    {   S54.t = null;\n        S54 s = S54(1);\n    }\n    assert(S54.t == \"ac\");\n\n    {   S54.t = null;\n        S54 s = S54();\n    }\n    assert(S54.t == \"c\");\n\n    {   S54.t = null;\n        int b = 1 && (){ bar54(S54(1)); return 1;}();\n    }\n    assert(S54.t == \"ac\");\n\n    {   S54.t = null;\n        int b = 0 && (){ bar54(S54(1)); return 1;}();\n    }\n    assert(S54.t == \"\");\n\n    {   S54.t = null;\n        int b = 0 || (){ bar54(S54(1)); return 1;}();\n    }\n    assert(S54.t == \"ac\");\n\n    {   S54.t = null;\n        int b = 1 || (){ bar54(S54(1)); return 1;}();\n    }\n    assert(S54.t == \"\");\n\n    {\n    S54.t = null;\n    { const S54 s = S54(1); }\n        assert(S54.t == \"ac\");\n    }\n    {\n        S54.t = null;\n        abc54();\n        assert(S54.t == \"ac\");\n    }\n    {\n        S54.t = null;\n        abc54().x += 1;\n        assert(S54.t == \"ac\");\n    }\n}\n\n/**********************************/\n\nvoid test55()\n{\n    S55 s;\n    auto t = s.copy();\n    assert(t.count == 1);   // (5)\n}\n\nstruct S55\n{\n    int count;\n    this(this) { ++count; }\n    S55 copy() { return this; }\n}\n\n/**********************************/\n\nstruct S56\n{\n    int x = 1;\n\n    int bar() { return x; }\n\n    this(int i)\n    {\n        printf(\"ctor %p(%d)\\n\", &this, i);\n        t ~= \"a\";\n    }\n\n    this(this)\n    {\n        printf(\"postblit %p\\n\", &this);\n        t ~= \"b\";\n    }\n\n    ~this()\n    {\n        printf(\"dtor %p\\n\", &this);\n        t ~= \"c\";\n    }\n\n    static string t;\n}\n\nint foo56()\n{\n    throw new Throwable(\"hello\");\n    return 5;\n}\n\n\nvoid test56()\n{\n    int i;\n    int j;\n    try\n    {\n        j |= 1;\n        i = S56(1).x + foo56() + 1;\n        j |= 2;\n    }\n    catch (Throwable o)\n    {\n        printf(\"caught\\n\");\n        j |= 4;\n    }\n    printf(\"i = %d, j = %d\\n\", i, j);\n    assert(i == 0);\n    assert(j == 5);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5859\n\nint dtor_cnt = 0;\nstruct S57\n{\n    int v;\n    this(int n){ v = n; printf(\"S.ctor v=%d\\n\", v); }\n    ~this(){ ++dtor_cnt; printf(\"S.dtor v=%d\\n\", v); }\n    bool opCast(T:bool)(){ printf(\"S.cast v=%d\\n\", v); return true; }\n}\nS57 f(int n){ return S57(n); }\n\nvoid test57()\n{\n    printf(\"----\\n\");\n    dtor_cnt = 0;\n    if (auto s = S57(10))\n    {\n        printf(\"ifbody\\n\");\n    }\n    else assert(0);\n    assert(dtor_cnt == 1);\n\n    printf(\"----\\n\");    //+\n    dtor_cnt = 0;\n    S57(1), S57(2);\n    if (auto s = S57(10))\n    {\n        assert(dtor_cnt == 2);\n        printf(\"ifbody\\n\");\n    }\n    else assert(0);\n    assert(dtor_cnt == 3);  // +/\n\n    printf(\"----\\n\");\n    dtor_cnt = 0;\n    try{\n        if (auto s = S57(10))\n        {\n            printf(\"ifbody\\n\");\n            throw new Exception(\"test\");\n        }\n        else assert(0);\n    }catch (Exception e){}\n    assert(dtor_cnt == 1);\n\n\n\n    printf(\"----\\n\");\n    dtor_cnt = 0;\n    if (auto s = f(10))\n    {\n        printf(\"ifbody\\n\");\n    }\n    else assert(0);\n    assert(dtor_cnt == 1);\n\n    printf(\"----\\n\");    //+\n    dtor_cnt = 0;\n    f(1), f(2);\n    if (auto s = f(10))\n    {\n        assert(dtor_cnt == 2);\n        printf(\"ifbody\\n\");\n    }\n    else assert(0);\n    assert(dtor_cnt == 3);  // +/\n\n    printf(\"----\\n\");\n    dtor_cnt = 0;\n    try{\n        if (auto s = f(10))\n        {\n            printf(\"ifbody\\n\");\n            throw new Exception(\"test\");\n        }\n        else assert(0);\n    }catch (Exception e){}\n    assert(dtor_cnt == 1);\n\n\n\n\n    printf(\"----\\n\");\n    dtor_cnt = 0;\n    if (S57(10))\n    {\n        assert(dtor_cnt == 1);\n        printf(\"ifbody\\n\");\n    }\n    else assert(0);\n\n    printf(\"----\\n\");\n    dtor_cnt = 0;\n    S57(1), S57(2);\n    if (S57(10))\n    {\n        assert(dtor_cnt == 3);\n        printf(\"ifbody\\n\");\n    }\n    else assert(0);\n\n    printf(\"----\\n\");\n    dtor_cnt = 0;\n    try{\n        if (auto s = S57(10))\n        {\n            printf(\"ifbody\\n\");\n            throw new Exception(\"test\");\n        }\n        else assert(0);\n    }catch (Exception e){}\n    assert(dtor_cnt == 1);\n\n\n\n    printf(\"----\\n\");\n    dtor_cnt = 0;\n    if (f(10))\n    {\n        assert(dtor_cnt == 1);\n        printf(\"ifbody\\n\");\n    }\n    else assert(0);\n\n    printf(\"----\\n\");\n    dtor_cnt = 0;\n    f(1), f(2);\n    if (f(10))\n    {\n        assert(dtor_cnt == 3);\n        printf(\"ifbody\\n\");\n    }\n    else assert(0);\n\n    printf(\"----\\n\");\n    dtor_cnt = 0;\n    try{\n        if (auto s = f(10))\n        {\n            printf(\"ifbody\\n\");\n            throw new Exception(\"test\");\n        }\n        else assert(0);\n    }catch (Exception e){}\n    assert(dtor_cnt == 1);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5574\n\nstruct foo5574a\n{\n    ~this() {}\n}\nclass bar5574a\n{\n    foo5574a[1] frop;\n}\n\nstruct foo5574b\n{\n    this(this){}\n}\nstruct bar5574b\n{\n    foo5574b[1] frop;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5777\n\nint sdtor58 = 0;\nS58* ps58;\n\nstruct S58\n{\n    @disable this(this);\n    ~this(){ ++sdtor58; }\n}\n\nS58 makeS58()\n{\n    S58 s;\n    ps58 = &s;\n    return s;\n}\n\nvoid test58()\n{\n    auto s1 = makeS58();\n    assert(ps58 == &s1);\n    assert(sdtor58 == 0);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6308\n\nstruct C59\n{\n    void oops()\n    {\n        throw new Throwable(\"Oops!\");\n    }\n\n    ~this()\n    {\n    }\n}\n\nvoid foo59()\n{\n    C59().oops();\n//  auto c = C(); c.oops();\n}\n\n\nvoid test59()\n{\n    int i = 0;\n    try\n        foo59();\n    catch (Throwable)\n    {   i = 1;\n    }\n    assert(i == 1);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5737\n\nvoid test5737()\n{\n    static struct S\n    {\n        static int destroyed;\n        static int copied;\n\n        this(this)\n        {\n            copied++;\n        }\n\n        ~this()\n        {\n            destroyed++;\n        }\n    }\n\n    static S s;\n\n    ref S foo()\n    {\n        return s;\n    }\n\n    {\n        auto s2 = foo();\n    }\n\n    assert(S.copied == 1); // fail, s2 was not copied;\n    assert(S.destroyed == 1); // ok, s2 was destroyed\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6119\n\nvoid test6119()\n{\n    int postblit = 0;\n    int dtor = 0;\n\n    struct Test\n    {\n        this(this) { ++postblit; }\n        ~this()    { ++dtor; }\n    }\n\n    void takesVal(Test x) {}\n    ref Test returnsRef(ref Test x) { return x; }\n\n    void f(ref Test x) { takesVal( x ); }\n\n    Test x;\n\n    postblit = dtor = 0;\n    takesVal(returnsRef(x));\n    assert(postblit == 1);\n    assert(dtor == 1);\n\n    postblit = dtor = 0;\n    f(x);\n    assert(postblit == 1);\n    assert(dtor == 1);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6364\n\nstruct Foo6364\n{\n    int state = 1;\n\n    ~this()\n    {\n        state = 0;\n    }\n}\n\nvoid testfoo6364()\n{\n    static Foo6364 foo;\n    printf(\"%d\\n\", foo.state);\n    assert(foo.state == 1);\n}\n\nvoid test6364()\n{\n    testfoo6364();\n    testfoo6364();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6499\n\nstruct S6499\n{\n    string m = \"<not set>\";\n\n    this(string s)\n    {\n        m = s;\n        printf(\"Constructor - %.*s\\n\", m.length, m.ptr);\n        if (m == \"foo\") { ++sdtor; assert(sdtor == 1); }\n        if (m == \"bar\") { ++sdtor; assert(sdtor == 2); }\n    }\n    this(this)\n    {\n        printf(\"Postblit    - %.*s\\n\", m.length, m.ptr);\n        assert(0);\n    }\n    ~this()\n    {\n        printf(\"Destructor  - %.*s\\n\", m.length, m.ptr);\n        if (m == \"bar\") { assert(sdtor == 2); --sdtor; }\n        if (m == \"foo\") { assert(sdtor == 1); --sdtor; }\n    }\n    S6499 bar()     { return S6499(\"bar\"); }\n    S6499 baz()()   { return S6499(\"baz\"); }\n}\n\nvoid test6499()\n{\n    S6499 foo() { return S6499(\"foo\"); }\n\n    {\n        sdtor = 0;\n        scope(exit) assert(sdtor == 0);\n        foo().bar();\n    }\n    {\n        sdtor = 0;\n        scope(exit) assert(sdtor == 0);\n        foo().baz();\n    }\n}\n\n/**********************************/\n\ntemplate isImplicitlyConvertible(From, To)\n{\n    enum bool isImplicitlyConvertible = is(typeof({\n                        void fun(ref From v) {\n                            void gun(To) {}\n                            gun(v);\n                        }\n                    }()));\n}\n\nvoid test60()\n{\n    static struct X1\n    {\n        void* ptr;\n        this(this){}\n    }\n    static struct S1\n    {\n        X1 x;\n    }\n\n    static struct X2\n    {\n        int ptr;\n        this(this){}\n    }\n    static struct S2\n    {\n        X2 x;\n    }\n\n    {\n              S1  ms;\n              S1  ms2 = ms; // mutable to mutable\n        const(S1) cs2 = ms; // mutable to const                         // NG -> OK\n    }\n    {\n        const(S1) cs;\n        static assert(!__traits(compiles,{                              // NG -> OK\n              S1 ms2 = cs;  // field has reference, then const to mutable is invalid\n        }));\n        const(S1) cs2 = cs; // const to const                           // NG -> OK\n    }\n    static assert( isImplicitlyConvertible!(      S1 ,       S1 ) );\n    static assert( isImplicitlyConvertible!(      S1 , const(S1)) );    // NG -> OK\n    static assert(!isImplicitlyConvertible!(const(S1),       S1 ) );\n    static assert( isImplicitlyConvertible!(const(S1), const(S1)) );    // NG -> OK\n\n\n    {\n              S2  ms;\n              S2  ms2 = ms; // mutable to mutable\n        const(S2) cs2 = ms; // mutable to const                         // NG -> OK\n    }\n    {\n        const(S2) cs;\n              S2  ms2 = cs; // all fields are value, then const to mutable is OK\n        const(S2) cs2 = cs; // const to const                           // NG -> OK\n    }\n\n    static assert( isImplicitlyConvertible!(      S2 ,       S2 ) );\n    static assert( isImplicitlyConvertible!(      S2 , const(S2)) );    // NG -> OK\n    static assert( isImplicitlyConvertible!(const(S2),       S2 ) );\n    static assert( isImplicitlyConvertible!(const(S2), const(S2)) );    // NG -> OK\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=4316\n\nstruct A4316\n{\n    this(this) @safe { }\n}\n\n@safe void test4316()\n{\n    A4316 a;\n    auto b = a; // Error: safe function 'main' cannot call system function'__cpctor'\n}\n\n/**********************************/\n\nstruct F6177\n{\n    ~this()    {}\n}\n\nstruct G6177\n{\n    this(F6177[] p...) {}\n}\n\nvoid test6177()\n{\n    F6177 c;\n    auto g = G6177(c);\n}\n\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6470\n\nstruct S6470\n{\n    static int spblit;\n\n    this(this){ ++spblit; }\n}\n\nvoid test6470()\n{\n    S6470[] a1;\n    S6470[] a2;\n    a1.length = 3;\n    a2.length = 3;\n    a1[] = a2[];\n    assert(S6470.spblit == 3);\n\n    S6470 s;\n\n    S6470[] a3;\n    a3.length = 3;\n    a3 = [s, s, s];\n    assert(S6470.spblit == 6);\n\n    void func(S6470[] a){}\n    func([s, s, s]);\n    assert(S6470.spblit == 9);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6636\n\nstruct S6636\n{\n    ~this()\n    {\n        ++sdtor;\n    }\n}\n\nvoid func6636(S6636[3] sa) {}\n\nvoid test6636()\n{\n    sdtor = 0;\n\n    S6636[3] sa;\n    func6636(sa);\n    assert(sdtor == 3);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6637\n\nstruct S6637\n{\n    static int spblit;\n\n    this(this){ ++spblit; }\n}\n\nvoid test6637()\n{\n    void func(S6637[3] sa){}\n\n    S6637[3] sa;\n    func(sa);\n    assert(S6637.spblit == 3);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7353\n\nstruct S7353\n{\n    static uint ci = 0;\n    uint i;\n\n    this(int x) { i = ci++; /*writeln(\"new: \", i);*/ }\n    this(this)  { i = ci++; /*writeln(\"copy \", i);*/ }\n    ~this()     {           /*writeln(\"del \", i);*/ }\n\n    S7353 save1() // produces 2 copies in total\n    {\n        S7353 s = this;\n        return s;\n    }\n    auto save2() // produces 3 copies in total\n    {\n        S7353 s = this;\n        return s;\n        pragma(msg, typeof(return));\n    }\n}\nvoid test7353()\n{\n    {\n        auto s = S7353(1), t = S7353(1);\n        t = s.save1();\n        assert(S7353.ci == 3);\n    }\n    S7353.ci = 0; //writeln(\"-\");\n    {\n        auto s = S7353(1), t = S7353(1);\n        t = s.save2();\n        assert(S7353.ci == 3);\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8036\n\nstruct S8036a\n{\n    ~this() {}\n}\nstruct S8036b // or class\n{\n    S8036a[0] s;\n}\n\n/**********************************/\n\nstruct S61\n{\n    this(long length)\n    {\n        this.length = length;\n    }\n\n    long length;\n}\n\n\nconst(S61) copy(const S61 s)\n{\n    return s;\n}\n\n\nvoid test61()\n{\n    S61 t = S61(42);\n    const S61 u = t;\n\n    assert(t == u);\n    assert(copy(t) == u);\n    assert(t == copy(u));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7506\n\nvoid test7506()\n{\n    static struct S\n    {\n        static uint ci = 0;\n        static uint di = 0;\n        uint i;\n\n        this(int x) { i = ci++; /*writeln(\"new: \", i);*/ }\n        this(this)  { i = ci++; /*writeln(\"copy \", i);*/ }\n        ~this()     { ++di;     /*writeln(\"del: \", i);*/ }\n\n        S save3()\n        {\n            return this;\n        }\n    }\n\n    {\n        auto s = S(1), t = S(1);\n        assert(S.ci == 2);\n        t = s.save3();\n        assert(S.ci == 3);  // line 23\n    }\n    assert(S.di == 3);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7516\n\nstruct S7516\n{\n    int val;\n\n    this(int n) { val = n; }\n    this(this) { val *= 3; }\n}\n\n// CondExp on return statement\nvoid test7516a()\n{\n    alias S = S7516;\n    S s1 = S(1);\n    S s2 = S(2);\n\n    S foo(bool f) { return f ?  s1  :  s2;  }\n    S hoo(bool f) { return f ? S(1) : S(2); }\n    S bar(bool f) { return f ?  s1  : S(2); }\n    S baz(bool f) { return f ? S(1) :  s2;  }\n\n    auto r1 = foo(true);    assert(r1.val == 3);\n    auto r2 = foo(false);   assert(r2.val == 6);\n    auto r3 = hoo(true);    assert(r3.val == 1);\n    auto r4 = hoo(false);   assert(r4.val == 2);\n    auto r5 = bar(true);    assert(r5.val == 3);\n    auto r6 = bar(false);   assert(r6.val == 2);\n    auto r7 = baz(true);    assert(r7.val == 1);\n    auto r8 = baz(false);   assert(r8.val == 6);\n}\n\n// CondExp on function argument\nvoid test7516b()\n{\n    alias S = S7516;\n    S s1 = S(1);\n    S s2 = S(2);\n    S func(S s) { return s; }\n\n    S foo(bool f) { return func(f ?  s1  :  s2 ); }\n    S hoo(bool f) { return func(f ? S(1) : S(2)); }\n    S bar(bool f) { return func(f ?  s1  : S(2)); }\n    S baz(bool f) { return func(f ? S(1) :  s2 ); }\n\n    auto r1 = foo(true);    assert(r1.val == 3 * 3);\n    auto r2 = foo(false);   assert(r2.val == 6 * 3);\n    auto r3 = hoo(true);    assert(r3.val == 1 * 3);\n    auto r4 = hoo(false);   assert(r4.val == 2 * 3);\n    auto r5 = bar(true);    assert(r5.val == 3 * 3);\n    auto r6 = bar(false);   assert(r6.val == 2 * 3);\n    auto r7 = baz(true);    assert(r7.val == 1 * 3);\n    auto r8 = baz(false);   assert(r8.val == 6 * 3);\n}\n\n// CondExp on array literal\nvoid test7516c()\n{\n    alias S = S7516;\n    S s1 = S(1);\n    S s2 = S(2);\n\n    S[] foo(bool f) { return [f ?  s1  :  s2 ]; }\n    S[] hoo(bool f) { return [f ? S(1) : S(2)]; }\n    S[] bar(bool f) { return [f ?  s1  : S(2)]; }\n    S[] baz(bool f) { return [f ? S(1) :  s2 ]; }\n\n    auto r1 = foo(true);    assert(r1[0].val == 3);\n    auto r2 = foo(false);   assert(r2[0].val == 6);\n    auto r3 = hoo(true);    assert(r3[0].val == 1);\n    auto r4 = hoo(false);   assert(r4[0].val == 2);\n    auto r5 = bar(true);    assert(r5[0].val == 3);\n    auto r6 = bar(false);   assert(r6[0].val == 2);\n    auto r7 = baz(true);    assert(r7[0].val == 1);\n    auto r8 = baz(false);   assert(r8[0].val == 6);\n}\n\n// CondExp on rhs of cat assign\nvoid test7516d()\n{\n    alias S = S7516;\n    S s1 = S(1);\n    S s2 = S(2);\n\n    S[] foo(bool f) { S[] a; a ~= f ?  s1  :  s2 ; return a; }\n    S[] hoo(bool f) { S[] a; a ~= f ? S(1) : S(2); return a; }\n    S[] bar(bool f) { S[] a; a ~= f ?  s1  : S(2); return a; }\n    S[] baz(bool f) { S[] a; a ~= f ? S(1) :  s2 ; return a; }\n\n    auto r1 = foo(true);    assert(r1[0].val == 3);\n    auto r2 = foo(false);   assert(r2[0].val == 6);\n    auto r3 = hoo(true);    assert(r3[0].val == 1);\n    auto r4 = hoo(false);   assert(r4[0].val == 2);\n    auto r5 = bar(true);    assert(r5[0].val == 3);\n    auto r6 = bar(false);   assert(r6[0].val == 2);\n    auto r7 = baz(true);    assert(r7[0].val == 1);\n    auto r8 = baz(false);   assert(r8[0].val == 6);\n}\n\n// CondExp on struct literal element\nvoid test7516e()\n{\n    alias S = S7516;\n    S s1 = S(1);\n    S s2 = S(2);\n    struct X { S s; }\n\n    X foo(bool f) { return X(f ?  s1  :  s2 ); }\n    X hoo(bool f) { return X(f ? S(1) : S(2)); }\n    X bar(bool f) { return X(f ?  s1  : S(2)); }\n    X baz(bool f) { return X(f ? S(1) :  s2 ); }\n\n    auto r1 = foo(true);    assert(r1.s.val == 3);\n    auto r2 = foo(false);   assert(r2.s.val == 6);\n    auto r3 = hoo(true);    assert(r3.s.val == 1);\n    auto r4 = hoo(false);   assert(r4.s.val == 2);\n    auto r5 = bar(true);    assert(r5.s.val == 3);\n    auto r6 = bar(false);   assert(r6.s.val == 2);\n    auto r7 = baz(true);    assert(r7.s.val == 1);\n    auto r8 = baz(false);   assert(r8.s.val == 6);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7530\n\nvoid test7530()\n{\n    static struct S\n    {\n        int val;\n\n        this(int n) { val = n; }\n        this(this) { val *= 3; }\n    }\n\n    S[] sa = new S[](1);\n    sa[0].val = 1;\n    S foo()\n    {\n        return sa[0];\n    }\n    auto s = foo();\n    assert(s.val == 3);\n}\n\n/**********************************/\n\nstruct S62\n{\n    this(int length)\n    {\n        _length = length;\n    }\n\n    int opBinary(string op)(in S62 rhs) const\n        if(op == \"-\")\n    {\n        return this.length - rhs.length;\n    }\n\n    @property int length() const\n    {\n        return _length;\n    }\n\n    invariant()\n    {\n        assert(_length == 1);\n    }\n\n    int _length  = 1;\n}\n\n\nvoid test62()\n{\n    immutable result = S62.init - S62.init;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7579\n\nvoid test7579a()\n{\n    static struct S\n    {\n        // postblit can also have no body because isn't called\n        @disable this(this) { assert(0); }\n    }\n\n    @property S fs() { return S(); }\n    @property S[3] fsa() { return [S(), S(), S()]; }\n\n    S s0;\n    S s1 = S();\n    static assert(!__traits(compiles, { S s2 = s1; }));         // OK\n    S s2 = fs;\n    static assert(!__traits(compiles, { s2 = s1; }));           // OK\n\n    // static array\n    S[3] sa0;\n    S[3] sa1 = [S(), S(), S()];\n    static assert(!__traits(compiles, { S[3] sa2 = sa1; }));    // fixed\n    S[3] sa2 = fsa;\n    static assert(!__traits(compiles, { sa2 = sa1; }));         // fixed\n    sa2 = [S(), S(), S()];\n    sa2 = fsa;\n\n    S[] da1 = new S[3];\n    S[] da2 = new S[3];\n    static assert(!__traits(compiles, { da2[] = da1[]; }));     // fixed\n\n    // concatenation and appending\n    static assert(!__traits(compiles, { da1 ~= s1; }));         // fixed\n    static assert(!__traits(compiles, { da1 ~= S(); }));\n    static assert(!__traits(compiles, { da1 ~= fsa; }));\n    static assert(!__traits(compiles, { da1 ~= fsa[]; }));\n    static assert(!__traits(compiles, { da1 = da1 ~ s1; }));    // fixed\n    static assert(!__traits(compiles, { da1 = s1 ~ da1; }));    // fixed\n    static assert(!__traits(compiles, { da1 = da1 ~ S(); }));\n    static assert(!__traits(compiles, { da1 = da1 ~ fsa; }));\n    static assert(!__traits(compiles, { da1 = da1 ~ da; }));\n}\n\nvoid test7579b()\n{\n    static struct S\n    {\n        // postblit asserts in runtime\n        this(this) { assert(0); }\n    }\n\n    @property S fs() { return S(); }\n    @property S[3] fsa() { return [S(), S(), S()]; }\n\n    S s0;\n    S s1 = S();\n    S s2 = fs;\n\n    // static array\n    S[3] sa0;\n    S[3] sa1 = [S(), S(), S()];\n    S[3] sa2 = fsa;\n    sa2 = [S(), S(), S()];\n    sa2 = fsa;\n\n    S[] da1 = new S[3];\n    S[] da2 = new S[3];\n\n    // concatenation and appending always run postblits\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8335\n\nstruct S8335\n{\n    static int postblit;\n\n    int i;\n    this(this) { ++postblit; }\n}\n\nvoid f8335(ref S8335[3] arr)\n{\n    arr[0].i = 7;\n}\n\nvoid g8335(lazy S8335[3] arr)\n{\n    assert(S8335.postblit == 0);\n    auto x = arr;\n    assert(S8335.postblit == 3);\n}\n\nvoid h8335(lazy S8335 s)\n{\n    assert(S8335.postblit == 0);\n    auto x = s;\n    assert(S8335.postblit == 1);\n}\n\nvoid test8335()\n{\n    S8335[3] arr;\n    f8335(arr);\n    assert(S8335.postblit == 0);\n    assert(arr[0].i == 7);\n\n    g8335(arr);\n    assert(S8335.postblit == 3);\n\n    S8335.postblit = 0;\n    S8335 s;\n    h8335(s);\n    assert(S8335.postblit == 1);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8356\n\nvoid test8356()\n{\n    static struct S\n    {\n        @disable this(this) { assert(0); }\n    }\n\n    S s;\n    S[3] sa;\n\n  static assert(!__traits(compiles, {\n    S fs() { return s; }\n  }));\n\n  static assert(!__traits(compiles, {\n    S[3] fsa() { return sa; }\n  }));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8475\n\nT func8475(T)(T x) @safe pure\n{\n    return T();\n}\n\ntemplate X8475(bool something)\n{\n    struct XY\n    {\n        this(this) @safe pure {}\n        void func(XY x) @safe pure\n        {\n            XY y = x; //Error: see below\n            func8475(x);\n            func8475(y);\n        }\n    }\n}\n\nalias X8475!(true).XY Xtrue;\n\n/**********************************/\n\nstruct Foo9320 {\n    real x;\n\n    this(real x) {\n        this.x = x;\n    }\n\n    Foo9320 opBinary(string op)(Foo9320 other) {\n        return Foo9320(mixin(\"x\" ~ op ~ \"other.x\"));\n    }\n}\n\nFoo9320 test9320(Foo9320 a, Foo9320 b, Foo9320 c) {\n    return (a + b) / (a * b) - c;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9386\n\nstruct Test9386\n{\n    string name;\n    static char[25] op;\n    static size_t i;\n\n    static @property string sop() { return cast(string)op[0..i]; }\n\n    this(string name)\n    {\n        this.name = name;\n        printf(\"Created %.*s...\\n\", name.length, name.ptr);\n        assert(i + 1 < op.length);\n        op[i++] = 'a';\n    }\n\n    this(this)\n    {\n        printf(\"Copied %.*s...\\n\", name.length, name.ptr);\n        assert(i + 1 < op.length);\n        op[i++] = 'b';\n    }\n\n    ~this()\n    {\n        printf(\"Deleted %.*s\\n\", name.length, name.ptr);\n        assert(i + 1 < op.length);\n        op[i++] = 'c';\n    }\n\n    const int opCmp(ref const Test9386 t)\n    {\n        return op[0] - t.op[0];\n    }\n}\n\nvoid test9386()\n{\n    {\n        Test9386.op[] = 0;\n        Test9386.i = 0;\n\n        Test9386[] tests =\n            [ Test9386(\"one\"),\n              Test9386(\"two\"),\n              Test9386(\"three\"),\n              Test9386(\"four\") ];\n\n        assert(Test9386.sop == \"aaaa\");\n        Test9386.op[] = 0;\n        Test9386.i = 0;\n\n        printf(\"----\\n\");\n        foreach (Test9386 test; tests)\n        {\n            printf(\"\\tForeach %.*s\\n\", test.name.length, test.name.ptr);\n            Test9386.op[Test9386.i++] = 'x';\n        }\n\n        assert(Test9386.sop == \"bxcbxcbxcbxc\");\n        Test9386.op[] = 0;\n        Test9386.i = 0;\n\n        printf(\"----\\n\");\n        foreach (ref Test9386 test; tests)\n        {\n            printf(\"\\tForeach %.*s\\n\", test.name.length, test.name.ptr);\n            Test9386.op[Test9386.i++] = 'x';\n        }\n        assert(Test9386.sop == \"xxxx\");\n    }\n    printf(\"====\\n\");\n    {\n        Test9386.op[] = 0;\n        Test9386.i = 0;\n\n        Test9386[Test9386] tests =\n            [ Test9386(\"1\") : Test9386(\"one\"),\n              Test9386(\"2\") : Test9386(\"two\"),\n              Test9386(\"3\") : Test9386(\"three\"),\n              Test9386(\"4\") : Test9386(\"four\") ];\n\n        Test9386.op[] = 0;\n        Test9386.i = 0;\n\n        printf(\"----\\n\");\n        foreach (Test9386 k, Test9386 v; tests)\n        {\n            printf(\"\\tForeach %.*s : %.*s\\n\", k.name.length, k.name.ptr,\n                                              v.name.length, v.name.ptr);\n            Test9386.op[Test9386.i++] = 'x';\n        }\n\n        assert(Test9386.sop == \"bbxccbbxccbbxccbbxcc\");\n        Test9386.op[] = 0;\n        Test9386.i = 0;\n\n        printf(\"----\\n\");\n        foreach (Test9386 k, ref Test9386 v; tests)\n        {\n            printf(\"\\tForeach %.*s : %.*s\\n\", k.name.length, k.name.ptr,\n                                              v.name.length, v.name.ptr);\n            Test9386.op[Test9386.i++] = 'x';\n        }\n        assert(Test9386.sop == \"bxcbxcbxcbxc\");\n        Test9386.op[] = 0;\n        Test9386.i = 0;\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9441\n\nauto x9441 = X9441(0.123);\n\nstruct X9441\n{\n    int a;\n    this(double x) { a = cast(int)(x * 100); }\n}\n\nvoid test9441()\n{\n    assert(x9441.a == 12);\n}\n\n/**********************************/\n\nstruct Payload\n{\n    size_t _capacity; //Comment me\n    int[] _pay;       //Comment me\n\n    size_t insertBack(Data d)\n    {\n        immutable newLen   = _pay.length + 3;\n        _pay.length = newLen;\n        _pay = _pay[0 .. newLen]; //Comment me\n        return 3;\n    }\n}\n\nstruct Impl\n{\n    Payload _payload;\n    size_t _count;\n}\n\nstruct Data\n{\n    Impl* _store;\n\n    this(int i)\n    {\n        _store = new Impl;\n        _store._payload = Payload.init;\n    }\n\n    ~this()\n    {\n        printf(\"%d\\n\", _store._count);\n        --_store._count;\n    }\n}\n\n\nvoid test9720()\n{\n    auto a = Data(1);\n    auto b = Data(1);\n    a._store._payload.insertBack(b); //Fails\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9899\n\nstruct S9899\n{\n    @safe pure nothrow ~this() {}\n}\n\nstruct MemberS9899\n{\n    S9899 s;\n}\n\nvoid test9899() @safe pure nothrow\n{\n    MemberS9899 s; // 11\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9907\n\nvoid test9907()\n{\n    static struct SX(bool hasCtor, bool hasDtor)\n    {\n        int i;\n        static size_t assign;\n        static size_t dtor;\n\n        static if (hasCtor)\n        {\n            this(int i) { this.i = i; }\n        }\n\n        void opAssign(SX rhs)\n        {\n            printf(\"%08X(%d) from Rvalue %08X(%d)\\n\", &this.i, this.i, &rhs.i, rhs.i);\n            ++assign;\n        }\n\n        void opAssign(ref SX rhs)\n        {\n            printf(\"%08X(%d) from Lvalue %08X(%d)\\n\", &this.i, this.i, &rhs.i, rhs.i);\n            assert(0);\n        }\n\n        static if (hasDtor)\n        {\n            ~this()\n            {\n                printf(\"destroying %08X(%d)\\n\", &this.i, this.i);\n                ++dtor;\n            }\n        }\n    }\n\n    S test(S)(int i)\n    {\n        return S(i);\n    }\n\n    foreach (hasCtor; TypeTuple!(false, true))\n    foreach (hasDtor; TypeTuple!(false, true))\n    {\n        alias S = SX!(hasCtor, hasDtor);\n        alias test!S foo;\n\n        printf(\"----\\n\");\n        auto s = S(1);\n\n        // Assignment from two kinds of rvalues\n        assert(S.assign == 0);\n        s = foo(2);\n        static if (hasDtor) assert(S.dtor == 1);\n        assert(S.assign == 1);\n        s = S(3);\n        assert(S.assign == 2);\n        static if (hasDtor) assert(S.dtor == 2);\n    }\n    printf(\"----\\n\");\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9985\n\nstruct S9985\n{\n    ubyte* b;\n    ubyte[128] buf;\n    this(this) { assert(0); }\n\n    static void* ptr;\n}\nauto ref makeS9985() @system\n{\n    S9985 s;\n    s.b = s.buf.ptr;\n    S9985.ptr = &s;\n    return s;\n}\nvoid test9985()\n{\n    S9985 s = makeS9985();\n    assert(S9985.ptr == &s);    // NRVO\n\n    static const int n = 1;\n    static auto ref retN()\n    {\n        return n;\n    }\n    auto p = &(retN());        // OK\n    assert(p == &n);\n    alias pure nothrow @nogc @safe ref const(int) F1();\n    static assert(is(typeof(retN) == F1));\n\n    enum const(int) x = 1;\n    static auto ref retX()\n    {\n        return x;\n    }\n    static assert(!__traits(compiles, { auto q = &(retX()); }));\n    alias pure nothrow @nogc @safe const(int) F2();\n    static assert(is(typeof(retX) == F2));\n}\n\n/**********************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=17457\n\nvoid delegate() dg17457;\n\nstruct S17457 {\n    ulong[10] data;\n\n    this(int seconds) {\n        dg17457 = &mfunc;\n    }\n    void mfunc() {}\n}\n\nauto foo17457() {\n    pragma(inline, false);\n    return S17457(18);\n}\n\nvoid test17457()\n{\n    auto x = foo17457();\n    //printf(\"%p vs %p\\n\", &x, dg17457.ptr);\n    assert(&x == dg17457.ptr);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9994\n\nvoid test9994()\n{\n    static struct S\n    {\n        static int dtor;\n        ~this() { ++dtor; }\n    }\n\n    S s;\n    static assert( __traits(compiles, s.opAssign(s)));\n    static assert(!__traits(compiles, s.__postblit()));\n\n    assert(S.dtor == 0);\n    s = s;\n    assert(S.dtor == 1);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10053\n\nstruct S10053A\n{\n    pure ~this() {}\n}\n\nstruct S10053B\n{\n    S10053A sa;\n    ~this() {}\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10055\n\nvoid test10055a()\n{\n    static struct SX { pure nothrow @safe ~this() {} }\n    static struct SY { pure nothrow @safe ~this() {} }\n    static struct SZ {           @disable ~this() {} }\n\n    // function to check merge result of the dtor attributes\n    static void check(S)() { S s; }\n\n    static struct S1 {                                             }\n    static struct S2 {                                  ~this() {} }\n    static struct SA { SX sx; SY sy;                               }\n    static struct SB { SX sx; SY sy; pure nothrow @safe ~this() {} }\n    static struct SC { SX sx; SY sy;      nothrow @safe ~this() {} }\n    static struct SD { SX sx; SY sy; pure         @safe ~this() {} }\n    static struct SE { SX sx; SY sy; pure nothrow       ~this() {} }\n    static struct SF { SX sx; SY sy;              @safe ~this() {} }\n    static struct SG { SX sx; SY sy;      nothrow       ~this() {} }\n    static struct SH { SX sx; SY sy; pure               ~this() {} }\n    static struct SI { SX sx; SY sy;                    ~this() {} }\n    static assert(is( typeof(&check!S1) == void function() pure nothrow @nogc @safe ));\n    static assert(is( typeof(&check!S2) == void function()                    ));\n    static assert(is( typeof(&check!SA) == void function() pure nothrow @safe ));\n    static assert(is( typeof(&check!SB) == void function() pure nothrow @safe ));\n    static assert(is( typeof(&check!SC) == void function()      nothrow @safe ));\n    static assert(is( typeof(&check!SD) == void function() pure         @safe ));\n    static assert(is( typeof(&check!SE) == void function() pure nothrow       ));\n    static assert(is( typeof(&check!SF) == void function()              @safe ));\n    static assert(is( typeof(&check!SG) == void function()      nothrow       ));\n    static assert(is( typeof(&check!SH) == void function() pure               ));\n    static assert(is( typeof(&check!SI) == void function()                    ));\n\n    static struct S1x {                                             SZ sz; }\n    static struct S2x {                                  ~this() {} SZ sz; }\n    static struct SAx { SX sx; SY sy;                               SZ sz; }\n    static struct SBx { SX sx; SY sy; pure nothrow @safe ~this() {} SZ sz; }\n    static struct SCx { SX sx; SY sy;      nothrow @safe ~this() {} SZ sz; }\n    static struct SDx { SX sx; SY sy; pure         @safe ~this() {} SZ sz; }\n    static struct SEx { SX sx; SY sy; pure nothrow       ~this() {} SZ sz; }\n    static struct SFx { SX sx; SY sy;              @safe ~this() {} SZ sz; }\n    static struct SGx { SX sx; SY sy;      nothrow       ~this() {} SZ sz; }\n    static struct SHx { SX sx; SY sy; pure               ~this() {} SZ sz; }\n    static struct SIx { SX sx; SY sy;                    ~this() {} SZ sz; }\n    foreach (Sx; TypeTuple!(S1x, S2x, SAx, SBx, SCx, SDx, SEx, SFx, SGx, SHx, SIx))\n    {\n        static assert(!__traits(compiles, &check!Sx));\n    }\n}\n\nvoid test10055b()\n{\n    static struct SX { pure nothrow @safe this(this) {} }\n    static struct SY { pure nothrow @safe this(this) {} }\n    static struct SZ {           @disable this(this) {} }\n\n    // function to check merge result of the postblit attributes\n    static void check(S)() { S s; S s2 = s; }\n\n    static struct S1 {                                               }\n    static struct S2 {                                  this(this) {} }\n    static struct SA { SX sx; SY sy;                                  }\n    static struct SB { SX sx; SY sy; pure nothrow @safe this(this) {} }\n    static struct SC { SX sx; SY sy;      nothrow @safe this(this) {} }\n    static struct SD { SX sx; SY sy; pure         @safe this(this) {} }\n    static struct SE { SX sx; SY sy; pure nothrow       this(this) {} }\n    static struct SF { SX sx; SY sy;              @safe this(this) {} }\n    static struct SG { SX sx; SY sy;      nothrow       this(this) {} }\n    static struct SH { SX sx; SY sy; pure               this(this) {} }\n    static struct SI { SX sx; SY sy;                    this(this) {} }\n    static assert(is( typeof(&check!S1) == void function() pure nothrow @nogc @safe ));\n    static assert(is( typeof(&check!S2) == void function()                    ));\n    static assert(is( typeof(&check!SA) == void function() pure nothrow @safe ));\n    static assert(is( typeof(&check!SB) == void function() pure nothrow @safe ));\n    static assert(is( typeof(&check!SC) == void function()      nothrow @safe ));\n    static assert(is( typeof(&check!SD) == void function() pure         @safe ));\n    static assert(is( typeof(&check!SE) == void function() pure nothrow       ));\n    static assert(is( typeof(&check!SF) == void function()              @safe ));\n    static assert(is( typeof(&check!SG) == void function()      nothrow       ));\n    static assert(is( typeof(&check!SH) == void function() pure               ));\n    static assert(is( typeof(&check!SI) == void function()                    ));\n\n    static struct S1x {                                                SZ sz; }\n    static struct S2x {                                  this(this) {} SZ sz; }\n    static struct SAx { SX sx; SY sy;                                  SZ sz; }\n    static struct SBx { SX sx; SY sy; pure nothrow @safe this(this) {} SZ sz; }\n    static struct SCx { SX sx; SY sy;      nothrow @safe this(this) {} SZ sz; }\n    static struct SDx { SX sx; SY sy; pure         @safe this(this) {} SZ sz; }\n    static struct SEx { SX sx; SY sy; pure nothrow       this(this) {} SZ sz; }\n    static struct SFx { SX sx; SY sy;              @safe this(this) {} SZ sz; }\n    static struct SGx { SX sx; SY sy;      nothrow       this(this) {} SZ sz; }\n    static struct SHx { SX sx; SY sy; pure               this(this) {} SZ sz; }\n    static struct SIx { SX sx; SY sy;                    this(this) {} SZ sz; }\n    foreach (Sx; TypeTuple!(S1x, S2x, SAx, SBx, SCx, SDx, SEx, SFx, SGx, SHx, SIx))\n    {\n        static assert(!__traits(compiles, &check!Sx));\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10160\n\nstruct S10160 { this(this) {} }\n\nstruct X10160a { S10160 s; const int x;     }\nstruct X10160b { S10160 s; enum int x = 1; }\n\nvoid test10160()\n{\n    X10160a xa;\n    X10160b xb;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10094\n\nvoid test10094()\n{\n    static void* p;\n    const string[4] i2s = ()\n    {\n        string[4] tmp;\n        p = &tmp[0];\n        for (int i = 0; i < 4; ++i)\n        {\n            char[1] buf = [cast(char)('0' + i)];\n            string str = buf.idup;\n            tmp[i] = str;\n        }\n        return tmp; // NRVO should work\n    }();\n    assert(p == cast(void*)&i2s[0]);\n    assert(i2s == [\"0\", \"1\", \"2\", \"3\"]);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10079\n\n// dtor || postblit\nstruct S10079a\n{\n    this(this) pure nothrow @safe {}\n}\nstruct S10079b\n{\n    ~this() pure nothrow @safe {}\n}\nstruct S10079c\n{\n    this(this) pure nothrow @safe {}\n    ~this() pure nothrow @safe {}\n}\nstruct S10079d\n{\n    this(this) {}\n}\nstruct S10079e\n{\n    this(this) {}\n    ~this() pure nothrow @safe {}\n}\n\n// memberwise\nstruct S10079f\n{\n    S10079a a;\n    S10079b b;\n    S10079c c;\n    S10079d d;\n    S10079e e;\n}\n\nvoid check10079(S)(ref S s) pure nothrow @safe { s = S(); }\n\n// Assignment is pure, nothrow, and @safe in all cases.\nstatic assert(__traits(compiles, &check10079!S10079a));\nstatic assert(__traits(compiles, &check10079!S10079b));\nstatic assert(__traits(compiles, &check10079!S10079c));\nstatic assert(__traits(compiles, &check10079!S10079d));\nstatic assert(__traits(compiles, &check10079!S10079e));\nstatic assert(__traits(compiles, &check10079!S10079f));\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10244\n\nvoid test10244()\n{\n    static struct Foo\n    {\n        string _str;\n        long _num;\n\n        template DeclareConstructor(string fieldName)\n        {\n            enum code =\n                `this(typeof(_` ~ fieldName ~ `) value)` ~\n                `{ this._` ~ fieldName ~ ` = value; }`;\n            mixin(code);\n        }\n\n        mixin DeclareConstructor!\"str\";\n        mixin DeclareConstructor!\"num\";\n    }\n\n    Foo value1 = Foo(\"D\");\n    Foo value2 = Foo(128);\n    assert(value1._str == \"D\");\n    assert(value2._num == 128);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10694\n\nstruct Foo10694 { ~this() { } }\n\nvoid test10694() pure\n{\n    static Foo10694 i1;\n    __gshared Foo10694 i2;\n    void foo() pure\n    {\n        static Foo10694 j1;\n        __gshared Foo10694 j2;\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10787\n\nint global10787;\n\nstatic ~this() nothrow pure @safe\n{\n    int* p;\n    static assert(!__traits(compiles, ++p));\n    static assert(!__traits(compiles, ++global10787));\n}\n\nshared static ~this() nothrow pure @safe\n{\n    int* p;\n    static assert(!__traits(compiles, ++p));\n    static assert(!__traits(compiles, ++global10787));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10789\n\nstruct S10789\n{\n    static int count;\n    int value;\n\n    this(int)  { value = ++count; }\n    ~this()    { --count; }\n    this(this) { value = ++count; assert(value == 3); }\n}\n\nS10789 fun10789a(bool isCondExp)(bool cond)\n{\n    S10789 s1 = S10789(42), s2 = S10789(24);\n    assert(S10789.count == 2);\n    static if (isCondExp)\n    {\n        return cond ? s1 : s2;\n    }\n    else\n    {\n        if (cond)\n            return s1;\n        else\n            return s2;\n    }\n}\n\nauto fun10789b(bool isCondExp)(bool cond)\n{\n    S10789 s1 = S10789(42), s2 = S10789(24);\n    assert(S10789.count == 2);\n    static if (isCondExp)\n    {\n        return cond ? s1 : s2;\n    }\n    else\n    {\n        if (cond)\n            return s1;\n        else\n            return s2;\n    }\n}\n\nvoid test10789()\n{\n    foreach (fun; TypeTuple!(fun10789a, fun10789b))\n    foreach (isCondExp; TypeTuple!(false, true))\n    {\n        {\n            S10789 s = fun!isCondExp(true);\n            assert(S10789.count == 1);\n            assert(s.value == 3);\n        }\n        assert(S10789.count == 0);\n        {\n            S10789 s = fun!isCondExp(false);\n            assert(S10789.count == 1);\n            assert(s.value == 3);\n        }\n        assert(S10789.count == 0);\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10972\n\nint test10972()\n{\n    string result;\n\n    struct A\n    {\n        this(this)  { result ~= \"pA\"; version(none) printf(\"copied A\\n\"); }\n        ~this()     { result ~= \"dA\"; version(none) printf(\"destroy A\\n\"); }\n    }\n    struct B\n    {\n        this(this)\n        {\n            result ~= \"(pB)\"; version(none) printf(\"B says what?\\n\");\n            throw new Exception(\"BOOM!\");\n        }\n        ~this() { result ~= \"dB\"; version(none) printf(\"destroy B\\n\"); }\n    }\n    struct S\n    {\n        A a;\n        B b;\n    }\n\n    result = \"{\";\n    {\n        S s1;\n        result ~= \"[\";\n        try\n        {\n            S s3 = s1;\n            assert(0);\n        }\n        catch (Exception e)\n        {}\n        result ~= \"]\";\n    }\n    result ~= \"}\";\n    assert(result == \"{[pA(pB)dA]dBdA}\", result);\n\n    result = \"{\";\n    {\n        S s1;\n        S s2;\n        result ~= \"[\";\n        try\n        {\n            s2 = s1;\n            assert(0);\n        }\n        catch (Exception e)\n        {}\n        result ~= \"]\";\n    }\n    result ~= \"}\";\n    assert(result == \"{[pA(pB)dA]dBdAdBdA}\", result);\n\n    return 1;\n}\nstatic assert(test10972()); // CTFE\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=11134\n\nvoid test11134()\n{\n    void test(S)()\n    {\n        S s;\n        S[2] sa;\n        S[2][] dsa = [[S(), S()]];\n        dsa.reserve(dsa.length + 2);    // avoid postblit calls by GC\n\n        S.count = 0;\n        dsa ~= sa;\n        assert(S.count == 2);\n\n        S.count = 0;\n        dsa ~= [s, s];\n        assert(S.count == 2);\n    }\n\n    static struct SS\n    {\n        static int count;\n        this(this) { ++count; }\n    }\n    test!SS();\n\n    struct NS\n    {\n        static int count;\n        this(this) { ++count; }\n    }\n    test!NS();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=11197\n\nstruct S11197a\n{\n    this(bool) {}\n    this(this) {}\n}\n\nstruct S11197b\n{\n    //this(bool) {}\n    this(this) {}\n}\n\nvoid test11197()\n{\n    S11197a[][string] aa1;\n    aa1[\"test\"] ~= S11197a.init;\n\n    S11197b[][string] aa2;\n    aa2[\"test\"] ~= S11197b.init;\n}\n\n/**********************************/\n\nstruct S7474 {\n  float x;\n  ~this() {}\n}\n\nvoid fun7474(T...)() { T x; }\nvoid test7474() { fun7474!S7474(); }\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=11286\n\nstruct A11286\n{\n    ~this() {}\n}\n\nA11286 getA11286() pure nothrow\n{\n    return A11286();\n}\n\nvoid test11286()\n{\n    A11286 a = getA11286();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=11505\n\nstruct Foo11505\n{\n    Bar11505 b;\n}\n\nstruct Bar11505\n{\n    ~this() @safe { }\n    void* p;\n}\n\nvoid test11505()\n{\n    Foo11505 f;\n    f = Foo11505();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=12045\n\nbool test12045()\n{\n    string dtor;\n    void* ptr;\n\n    struct S12045\n    {\n        string val;\n\n        this(this) { assert(0); }\n        ~this() { dtor ~= val; }\n    }\n\n    auto makeS12045(bool thrown)\n    {\n        auto s1 = S12045(\"1\");\n        auto s2 = S12045(\"2\");\n        ptr = &s1;\n\n        if (thrown)\n            throw new Exception(\"\");\n\n        return s1;  // NRVO\n    }\n\n    dtor = null, ptr = null;\n    try\n    {\n        S12045 s = makeS12045(true);\n        assert(0);\n    }\n    catch (Exception e)\n    {\n        assert(dtor == \"21\", dtor);\n    }\n\n    dtor = null, ptr = null;\n    {\n        S12045 s = makeS12045(false);\n        assert(dtor == \"2\");\n        if (!__ctfe) assert(ptr is &s);   // NRVO\n    }\n    assert(dtor == \"21\");\n\n    return true;\n}\nstatic assert(test12045());\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=12591\n\nstruct S12591(T)\n{\n    this(this)\n    {}\n}\n\nstruct Tuple12591(Types...)\n{\n    Types expand;\n    this(Types values)\n    {\n        expand[] = values[];\n    }\n}\n\nvoid test12591()\n{\n    alias T1 = Tuple12591!(S12591!int);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=12660\n\nstruct X12660\n{\n    this(this) @nogc {}\n    ~this() @nogc {}\n    void opAssign(X12660) @nogc {}\n    @nogc invariant() {}\n}\nstruct Y12660\n{\n    X12660 x;\n\n    this(this) @nogc {}\n    ~this() @nogc {}\n    @nogc invariant() {}\n}\nstruct Z12660\n{\n    Y12660 y;\n}\n\nclass C12660\n{\n    this() @nogc {}\n    @nogc invariant() {}\n}\n\nvoid test12660() @nogc\n{\n    X12660 x;\n    x = x;\n\n    Y12660 y = { x };\n    y = y;\n\n    Z12660 z = { y };\n    z = z;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=12686\n\nstruct Foo12686\n{\n    static int count;\n\n    invariant() { ++count; }\n\n    @disable this(this);\n\n    Foo12686 bar()\n    {\n        Foo12686 f;\n        return f;\n    }\n}\n\nvoid test12686()\n{\n    Foo12686 f;\n    Foo12686 f2 = f.bar();\n    version (unittest)\n    { }\n    else\n        assert(Foo12686.count == 2);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=13089\n\nstruct S13089\n{\n    @disable this(this);    // non nothrow\n    int val;\n}\n\nvoid* p13089;\n\nS13089[1000] foo13089() nothrow\n{\n    typeof(return) data;\n    p13089 = &data;\n    return data;\n}\n\nvoid test13089() nothrow\n{\n    immutable data = foo13089();\n    assert(p13089 == &data);\n}\n\n/**********************************/\n\nstruct NoDtortest11763 {}\n\nstruct HasDtortest11763\n{\n    NoDtortest11763 func()\n    {\n        return NoDtortest11763();\n    }\n    ~this() {}\n}\n\nvoid test11763()\n{\n    HasDtortest11763().func();\n}\n\n/**********************************/\n\nstruct Buf { }\n\nstruct Variant\n{\n    ~this() { }\n\n    Buf get() { Buf b; return b; }\n}\n\nVariant value() { Variant v; return v; }\n\nvoid test13303()\n{\n    value.get();\n}\n\n/**********************************/\n\nstruct S13673\n{\n    string _name;\n    ~this() {}\n}\n\nstring name13673;\n\nvoid test13673()\n{\n    S13673(name13673);\n    S13673(name13673);\n}\n\n/**********************************/\n\nvoid test13586()\n{\n    static struct S {\n        __gshared int count;\n        ~this() { ++count; printf(\"~S\\n\"); }\n    }\n\n    static struct T {\n        __gshared int count;\n        ~this() { ++count; printf(\"~T\\n\"); }\n    }\n\n    static int foo(bool flag)\n    {\n        if (flag)\n            throw new Exception(\"hello\");\n        return 1;\n    }\n\n    static void func(S s, int f, T t)\n    {\n        printf(\"func()\\n\");\n    }\n\n    static class C\n    {\n        this(S s, int f, T t)\n        {\n            printf(\"C()\\n\");\n        }\n    }\n\n  {\n    bool threw = false;\n    try\n    {\n        func(S(), foo(true), T());\n        printf(\"not reach\\n\");\n    }\n    catch (Exception e)\n    {\n        threw = true;\n    }\n    printf(\"threw %d S %d T %d\\n\", threw, S.count, T.count);\n    assert(threw && S.count == 1 && T.count == 0);\n    S.count = 0;\n    T.count = 0;\n  }\n  {\n    bool threw = false;\n    try\n    {\n        func(S(), foo(false), T());\n        printf(\"reached\\n\");\n    }\n    catch (Exception e)\n    {\n        threw = true;\n    }\n    printf(\"threw %d S %d T %d\\n\", threw, S.count, T.count);\n    assert(!threw && S.count == 1 && T.count == 1);\n    S.count = 0;\n    T.count = 0;\n  }\n  {\n    bool threw = false;\n    try\n    {\n        new C(S(), foo(true), T());\n        printf(\"not reach\\n\");\n    }\n    catch (Exception e)\n    {\n        threw = true;\n    }\n    printf(\"threw %d S %d T %d\\n\", threw, S.count, T.count);\n    assert(threw && S.count == 1 && T.count == 0);\n    S.count = 0;\n    T.count = 0;\n  }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14443\n\nT enforce14443(E : Throwable = Exception, T)(T value)\n{\n    if (!value)\n        throw new E(\"Enforcement failed\");\n    return value;\n}\n\nstruct RefCounted14443(T)\nif (!is(T == class) && !(is(T == interface)))\n{\n    struct RefCountedStore\n    {\n        private struct Impl\n        {\n            T _payload;\n            size_t _count;\n        }\n\n        private Impl* _store;\n\n        private void initialize(A...)(auto ref A args)\n        {\n            import core.stdc.stdlib : malloc;\n\n            // enforce is necessary\n            _store = cast(Impl*) enforce14443(malloc(Impl.sizeof));\n\n            // emulate 'emplace'\n            static if (args.length > 0)\n                _store._payload.tupleof = args;\n            else\n                _store._payload = T.init;\n\n            _store._count = 1;\n        }\n\n        @property bool isInitialized() const nothrow @safe\n        {\n            return _store !is null;\n        }\n\n        void ensureInitialized()\n        {\n            if (!isInitialized) initialize();\n        }\n\n    }\n    RefCountedStore _refCounted;\n\n    this(A...)(auto ref A args) if (A.length > 0)\n    {\n        _refCounted.initialize(args);\n    }\n\n    this(this)\n    {\n        if (!_refCounted.isInitialized)\n            return;\n        ++_refCounted._store._count;\n        //printf(\"RefCounted count = %d (inc)\\n\", _refCounted._store._count);\n    }\n\n    ~this()\n    {\n        if (!_refCounted.isInitialized)\n            return;\n        assert(_refCounted._store._count > 0);\n        if (--_refCounted._store._count)\n        {\n            //printf(\"RefCounted count = %u\\n\", _refCounted._store._count);\n            return;\n        }\n\n        import core.stdc.stdlib : free;\n        free(_refCounted._store);\n        _refCounted._store = null;\n    }\n\n    void opAssign(typeof(this) rhs) { assert(0); }\n    void opAssign(T rhs) { assert(0); }\n\n    @property ref T refCountedPayload()\n    {\n        _refCounted.ensureInitialized();\n        return _refCounted._store._payload;\n    }\n\n    alias refCountedPayload this;\n}\n\nstruct Path14443\n{\n    struct Payload\n    {\n        int p;\n    }\n    RefCounted14443!Payload data;\n}\n\nstruct PathRange14443\n{\n    Path14443 path;\n    size_t i;\n\n    @property PathElement14443 front()\n    {\n        return PathElement14443(this, path.data.p);\n    }\n}\n\nstruct PathElement14443\n{\n    PathRange14443 range;\n\n    this(PathRange14443 range, int)\n    {\n        this.range = range;\n    }\n}\n\nvoid test14443()\n{\n    auto path = Path14443(RefCounted14443!(Path14443.Payload)(12));\n    assert(path.data.p == 12);\n\n    @property refCount() { return path.data._refCounted._store._count; }\n    assert(refCount == 1);\n\n    {\n        auto _r = PathRange14443(path);\n        assert(refCount == 2);\n        // foreach\n        {\n            auto element = _r.front;\n            assert(refCount == 3);  // fail with 2.067\n        }\n        assert(refCount == 2);\n    }\n    assert(refCount == 1);\n}\n\n/**********************************/\n// postblit/dtor call on static array assignment\n// https://issues.dlang.org/show_bug.cgi?id=13661\n// https://issues.dlang.org/show_bug.cgi?id=14022\n// https://issues.dlang.org/show_bug.cgi?id=14023\n\nbool test13661()\n{\n    string op;\n\n    struct S\n    {\n        char x = 'x';\n        this(this) { op ~= x-0x20; }    // upper case\n        ~this()    { op ~= x; }         // lower case\n\n        ref auto opAssign(T)(T arg)\n        {\n            assert(0);\n            return this;\n        }\n    }\n\n    {\n        S[2] a;\n\n        a[0].x = 'a';\n        a[1].x = 'b';\n        a = a.init;\n        assert(op == \"ab\");\n        assert(a[0].x == 'x' && a[1].x == 'x');\n\n        a[0].x = 'c';\n        a[1].x = 'd';\n        a = [S(), S()];   // equivalent a = a.init\n        assert(op == \"abcd\");\n        assert(a[0].x == 'x' && a[1].x == 'x');\n    }\n    assert(op == \"abcdxx\");\n\n    return true;\n}\nbool test13661a()\n{\n    string op;\n\n    struct S\n    {\n        char x = 'x';\n        this(this) { op ~= x-0x20; }    // upper case\n        ~this()    { op ~= x; }         // lower case\n    }\n\n    {\n        S[3] sa = [S('a'), S('b'), S('c')];\n        S[2] sb = sa[1..3];\n        assert(sa == [S('a'), S('b'), S('c')]);\n        assert(sb == [S('b'), S('c')]);\n        sb[0].x = 'x';\n        sb[1].x = 'y';\n        assert(sa != [S('a'), S('x'), S('y')]); // OK <- incorrectly fails\n        assert(sa == [S('a'), S('b'), S('c')]); // OK <- incorrectly fails\n        assert(sb == [S('x'), S('y')]);\n    }\n    return true;\n}\nstatic assert(test13661());     // CTFE\nstatic assert(test13661a());\n\nbool test14022()\n{\n    string op;\n\n    struct S\n    {\n        char x = 'x';\n        this(this) { op ~= x-0x20; }    // upper case\n        ~this()    { op ~= x; }         // lower case\n    }\n\n    S[2] makeSA() { return [S('p'), S('q')]; }\n\n    struct T\n    {\n        S[2] sb;\n\n        this(ref S[2] sa)\n        {\n            assert(op == \"\");\n            this.sb = sa;   // TOKconstruct\n            assert(op == \"BC\", op);\n            assert(sb == [S('b'), S('c')]);\n        }\n        void test(ref S[2] sa)\n        {\n            this.sb = sa;    // dotvar: resolveSlice(newva)\n            assert(op == \"BxCy\");\n        }\n    }\n\n    op = null;\n    {\n        S[2] sa = [S('a'), S('b')];\n        T t;    t.sb[0].x = 'x';\n                t.sb[1].x = 'y';\n        assert(op == \"\");\n        t.sb = sa;\n        assert(op == \"AxBy\");\n        t.sb = makeSA();\n        assert(op == \"AxByab\");\n    }\n    assert(op == \"AxByabqpba\");\n\n    op = null;\n    {\n        S[3] sa = [S('a'), S('b'), S('c')];\n        T t = T(sa[1..3]);\n        t.sb[0].x = 'x';\n        t.sb[1].x = 'y';\n        assert(sa == [S('a'), S('b'), S('c')]);\n        assert(t.sb == [S('x'), S('y')]);\n        assert(op == \"BC\");\n    }\n    assert(op == \"BCyxcba\");\n\n    op = null;\n    {\n        S[3] sx = [S('a'), S('b'), S('c')];\n        T t;    t.sb[0].x = 'x';\n                t.sb[1].x = 'y';\n        t.test(sx[1..3]);\n        assert(op == \"BxCy\");\n        assert(t.sb == [S('b'), S('c')]);\n    }\n    assert(op == \"BxCycbcba\");\n\n    return true;\n}\nstatic assert(test14022());\n\nbool test14023()\n{\n    string op;\n\n    struct S\n    {\n        char x = 'x';\n        this(this) { op ~= x-0x20; }    // upper case\n        ~this()    { op ~= x; }         // lower case\n    }\n\n    S[2] makeSA() { return [S('p'), S('q')]; }\n\n    struct T\n    {\n        S[2][1] sb;\n        this(ref S[2] sa)\n        {\n            assert(op == \"\");\n            this.sb[0] = sa;   // TOKconstruct\n            assert(sa    == [S('b'), S('c')]);\n            assert(sb[0] == [S('b'), S('c')]);\n        }\n    }\n\n    void test(ref S[2] sa)\n    {\n        S[2][] a;\n        //a.length = 1; // will cause runtine AccessViolation\n        a ~= (S[2]).init;\n        assert(op == \"\");\n        a[0] = sa;      // index <-- resolveSlice(newva)\n        assert(op == \"BxCx\");\n        assert(a[0] == [S('b'), S('c')]);\n    }\n\n    op = null;\n    {\n        S[3] sa = [S('a'), S('b'), S('c')];\n        T t = T(sa[1..3]);\n        t.sb[0][0].x = 'x';\n        t.sb[0][1].x = 'y';\n        assert(sa      != [S('a'), S('x'), S('y')]);    // OK <- incorrectly fails\n        assert(sa      == [S('a'), S('b'), S('c')]);    // OK <- incorrectly fails\n        assert(t.sb[0] == [S('x'), S('y')]);\n    }\n\n    op = null;\n    {\n        S[2] sa = [S('a'), S('b')];\n        S[2][] a = [[S('x'), S('y')]];\n        assert(op == \"\");\n        a[0] = sa;\n        assert(op == \"AxBy\");\n        a[0] = makeSA();\n        assert(op == \"AxByab\");\n    }\n    assert(op == \"AxByabba\");\n\n    op = null;\n    {\n        S[3] sa = [S('a'), S('b'), S('c')];\n        test(sa[1..3]);\n        assert(op == \"BxCx\");\n    }\n    assert(op == \"BxCxcba\");\n\n    return true;\n}\nstatic assert(test14023());\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13669 - dtor call on static array variable\n\nbool test13669()\n{\n    string dtor;\n\n    struct S\n    {\n        char x = 'x';\n        ~this() { dtor ~= x; }\n    }\n\n    { S[2] a; }\n    assert(dtor == \"xx\");\n    dtor = \"\";\n\n    { S[2] a = [S('a'), S('b')]; }\n    assert(dtor == \"ba\");   // reverse order. See also: TypeInfo_StaticArray.destroy()\n\n    return true;\n}\nstatic assert(test13669());\n\n/**********************************/\n\n__gshared bool b13095 = false;\n\nvoid bar13095() { throw new Exception(\"\"); }\n\nstruct S13095\n{\n    this(int) { printf(\"ctor %p\\n\", &this); bar13095(); }\n\n    ~this() { b13095 = true; printf(\"dtor %p\\n\", &this); }\n}\n\nvoid test13095()\n{\n    try {\n        S13095(0);\n    } catch(Exception) { printf(\"catch\\n\"); }\n    assert(!b13095);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14264\n\nvoid test14264()\n{\n    static int dtor;\n    static struct Foo\n    {\n        ~this() { ++dtor; }\n        T opCast(T:bool)() { return true; }\n    }\n\n    Foo makeFoo()\n    {\n        return Foo();\n    }\n\n    assert(dtor == 0);\n\n    makeFoo();\n    assert(dtor == 1);\n\n    makeFoo;\n    assert(dtor == 2);\n\n    if (makeFoo()) {}\n    assert(dtor == 3);\n\n    if (makeFoo) {}\n    assert(dtor == 4);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14686\n\nint test14686()\n{\n    string r;\n\n    struct S\n    {\n        int n;\n        this(this) { r ~= cast(char)('0' + n); }\n    }\n\n    S s1 = S(1);\n    S s2 = S(2);\n    S[] a1 = [S(1)];\n\n    S[2] sa1 = [s1, s2];\n    assert(r == \"12\", r);       // OK\n\n    r = \"\";\n    S[] a2 = a1 ~ s2;           // runtime concatenation\n    assert(r == \"12\", r);       // OK <- NG only in CTFE\n\n    r = \"\";\n    S[2] sa2a = [s1] ~ s2;\n    assert(r == \"12\", r);       // OK <- NG, s2 is not copied\n\n    r = \"\";\n    S[2] sa2b = s2 ~ [s1];\n    assert(r == \"21\", r);       // OK <- NG, s2 is not copied\n\n    r = \"\";\n    S[3] sa3a = ([s1] ~ [s1]) ~ s2;\n    assert(r == \"112\", r);      // OK <- NG, s2 is not copied\n\n    r = \"\";\n    S[3] sa3b = s2 ~ ([s1] ~ [s1]);\n    assert(r == \"211\", r);      // OK <- NG, s2 is not copied\n\n    return 1;\n}\nstatic assert(test14686());\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14815\n\nint test14815()\n{\n    uint dtorCount;\n\n    struct S\n    {\n        uint x;\n        ~this() { ++dtorCount; }\n    }\n\n    S[2] sa1;\n    sa1[0].x = 42;\n    sa1 = (S[2]).init;      // S[2] <- rvalue\n    assert(sa1[0].x == 0);\n    assert(dtorCount == 2);\n\n    S[2] sa2;\n    sa2[0].x = 42;\n    S[] da2 = sa2[];\n    da2[] = (S[2]).init[];  // S[] <- rvalue slice\n    assert(sa2[0].x == 0);\n    assert(dtorCount == 4);\n\n    S[2] sa3;\n    S[2] sa4;\n    sa3[0].x = 42;\n    sa3 = sa4;              // S[2] <- lvalue\n    assert(sa3[0].x == 0);\n    assert(dtorCount == 6);\n\n    S[2] sa5;\n    S[] da4 = sa4[];\n    da4[] = sa5[];          // S[] <- lvalue slice\n    assert(sa4[0].x == 0);\n    assert(dtorCount == 8);\n\n    return 1;\n}\nstatic assert(test14815());\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=16197\n\nstruct Elem {\n    static string r;\n    int x = -1;\n    this(this) { r ~= 'p'; printf(\"POSTBLIT %d\\n\", x++); }\n    ~this()    { r ~= 'd'; printf(\"DTOR %d\\n\"    , x++); }\n}\n\nstruct Ctr {\n    Elem[3] arr;\n}\n\nvoid test16197() {\n    { auto p = Ctr(); }\n    assert(Elem.r == \"ddd\");\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14860\n\nint test14860()\n{\n    uint dtorCount;\n\n    struct S\n    {\n        uint x;\n        ~this() { ++dtorCount; }\n    }\n\n    S[] a = [S(42)];\n    a[] = S();\n\n    assert(a[0].x == 0);\n    assert(dtorCount == 1);\n\n    return 1;\n}\nstatic assert(test14860());\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14246\n\nstruct A14246 {\n     int a = 3;\n     static string s;\n     this( int var ) { printf(\"A()\\n\"); a += var; s ~= \"a\"; }\n\n     ~this() { printf(\"~A()\\n\"); s ~= \"b\"; }\n}\n\nstruct B14246 {\n     int i;\n     A14246 a;\n\n     this( int var ) {\n         A14246.s ~= \"c\";\n         a = A14246(var+1);\n         throw new Exception(\"An exception\");\n     }\n}\n\nvoid test14246() {\n    try {\n         auto b = B14246(2);\n    } catch( Exception ex ) {\n        printf(\"Caught ex\\n\");\n        A14246.s ~= \"d\";\n    }\n    assert(A14246.s == \"cabd\");\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14696\n\nvoid test14696(int len = 2)\n{\n    string result;\n\n    struct S\n    {\n        int n;\n\n        void* get(void* p = null)\n        {\n            result ~= \"get(\" ~ cast(char)(n+'0') ~ \").\";\n            return null;\n        }\n\n        ~this()\n        {\n            result ~= \"dtor(\" ~ cast(char)(n+'0') ~ \").\";\n        }\n    }\n\n    S makeS(int n)\n    {\n        result ~= \"makeS(\" ~ cast(char)(n+'0') ~ \").\";\n        return S(n);\n    }\n    void foo(void* x, void* y = null)\n    {\n        result ~= \"foo.\";\n    }\n    void fooThrow(void* x, void* y = null)\n    {\n        result ~= \"fooThrow.\";\n        throw new Exception(\"fail!\");\n    }\n\n    void check(void delegate() dg, string r, string file = __FILE__, size_t line = __LINE__)\n    {\n        import core.exception;\n\n        result = null;\n        try { dg(); } catch (Exception e) {}\n        if (result != r)\n            throw new AssertError(result, file, line);\n    }\n\n    // temporary in condition\n    check({ foo(len == 2 ?        makeS(1).get() : null); }, \"makeS(1).get(1).foo.dtor(1).\");\n    check({ foo(len == 2 ? null : makeS(1).get()       ); }, \"foo.\");\n    check({ foo(len != 2 ?        makeS(1).get() : null); }, \"foo.\");\n    check({ foo(len != 2 ? null : makeS(1).get()       ); }, \"makeS(1).get(1).foo.dtor(1).\");\n\n    // temporary in nesting conditions\n    check({ foo(len >= 2 ?        (len == 2 ?        makeS(1).get() : null) : null); }, \"makeS(1).get(1).foo.dtor(1).\");\n    check({ foo(len >= 2 ?        (len == 2 ? null : makeS(1).get()       ) : null); }, \"foo.\");\n    check({ foo(len >= 2 ?        (len != 2 ?        makeS(1).get() : null) : null); }, \"foo.\");\n    check({ foo(len >= 2 ?        (len != 2 ? null : makeS(1).get()       ) : null); }, \"makeS(1).get(1).foo.dtor(1).\");\n    check({ foo(len >= 2 ? null : (len == 2 ?        makeS(1).get() : null)       ); }, \"foo.\");\n    check({ foo(len >= 2 ? null : (len == 2 ? null : makeS(1).get()       )       ); }, \"foo.\");\n    check({ foo(len >= 2 ? null : (len != 2 ?        makeS(1).get() : null)       ); }, \"foo.\");\n    check({ foo(len >= 2 ? null : (len != 2 ? null : makeS(1).get()       )       ); }, \"foo.\");\n    check({ foo(len >  2 ?        (len == 2 ?        makeS(1).get() : null) : null); }, \"foo.\");\n    check({ foo(len >  2 ?        (len == 2 ? null : makeS(1).get()       ) : null); }, \"foo.\");\n    check({ foo(len >  2 ?        (len != 2 ?        makeS(1).get() : null) : null); }, \"foo.\");\n    check({ foo(len >  2 ?        (len != 2 ? null : makeS(1).get()       ) : null); }, \"foo.\");\n    check({ foo(len >  2 ? null : (len == 2 ?        makeS(1).get() : null)       ); }, \"makeS(1).get(1).foo.dtor(1).\");\n    check({ foo(len >  2 ? null : (len == 2 ? null : makeS(1).get()       )       ); }, \"foo.\");\n    check({ foo(len >  2 ? null : (len != 2 ?        makeS(1).get() : null)       ); }, \"foo.\");\n    check({ foo(len >  2 ? null : (len != 2 ? null : makeS(1).get()       )       ); }, \"makeS(1).get(1).foo.dtor(1).\");\n\n    // temporary in condition and throwing callee\n    // check({ fooThrow(len == 2 ?        makeS(1).get() : null); }, \"makeS(1).get(1).fooThrow.dtor(1).\");\n    // check({ fooThrow(len == 2 ? null : makeS(1).get()       ); }, \"fooThrow.\");\n    // check({ fooThrow(len != 2 ?        makeS(1).get() : null); }, \"fooThrow.\");\n    // check({ fooThrow(len != 2 ? null : makeS(1).get()       ); }, \"makeS(1).get(1).fooThrow.dtor(1).\");\n\n    // temporary in nesting condititions and throwing callee\n    // check({ fooThrow(len >= 2 ?        (len == 2 ?        makeS(1).get() : null) : null); }, \"makeS(1).get(1).fooThrow.dtor(1).\");\n    // check({ fooThrow(len >= 2 ?        (len == 2 ? null : makeS(1).get()       ) : null); }, \"fooThrow.\");\n    // check({ fooThrow(len >= 2 ?        (len != 2 ?        makeS(1).get() : null) : null); }, \"fooThrow.\");\n    // check({ fooThrow(len >= 2 ?        (len != 2 ? null : makeS(1).get()       ) : null); }, \"makeS(1).get(1).fooThrow.dtor(1).\");\n    // check({ fooThrow(len >= 2 ? null : (len == 2 ?        makeS(1).get() : null)       ); }, \"fooThrow.\");\n    // check({ fooThrow(len >= 2 ? null : (len == 2 ? null : makeS(1).get()       )       ); }, \"fooThrow.\");\n    // check({ fooThrow(len >= 2 ? null : (len != 2 ?        makeS(1).get() : null)       ); }, \"fooThrow.\");\n    // check({ fooThrow(len >= 2 ? null : (len != 2 ? null : makeS(1).get()       )       ); }, \"fooThrow.\");\n    // check({ fooThrow(len >  2 ?        (len == 2 ?        makeS(1).get() : null) : null); }, \"fooThrow.\");\n    // check({ fooThrow(len >  2 ?        (len == 2 ? null : makeS(1).get()       ) : null); }, \"fooThrow.\");\n    // check({ fooThrow(len >  2 ?        (len != 2 ?        makeS(1).get() : null) : null); }, \"fooThrow.\");\n    // check({ fooThrow(len >  2 ?        (len != 2 ? null : makeS(1).get()       ) : null); }, \"fooThrow.\");\n    // check({ fooThrow(len >  2 ? null : (len == 2 ?        makeS(1).get() : null)       ); }, \"makeS(1).get(1).fooThrow.dtor(1).\");\n    // check({ fooThrow(len >  2 ? null : (len == 2 ? null : makeS(1).get()       )       ); }, \"fooThrow.\");\n    // check({ fooThrow(len >  2 ? null : (len != 2 ?        makeS(1).get() : null)       ); }, \"fooThrow.\");\n    // check({ fooThrow(len >  2 ? null : (len != 2 ? null : makeS(1).get()       )       ); }, \"makeS(1).get(1).fooThrow.dtor(1).\");\n\n    // temporaries in each conditions\n    check({ foo(len == 2 ? makeS(1).get() : null, len == 2 ? makeS(2).get() : null); }, \"makeS(1).get(1).makeS(2).get(2).foo.dtor(2).dtor(1).\");\n    check({ foo(len == 2 ? makeS(1).get() : null, len != 2 ? makeS(2).get() : null); }, \"makeS(1).get(1).foo.dtor(1).\");\n    check({ foo(len != 2 ? makeS(1).get() : null, len == 2 ? makeS(2).get() : null); }, \"makeS(2).get(2).foo.dtor(2).\");\n    check({ foo(len != 2 ? makeS(1).get() : null, len != 2 ? makeS(2).get() : null); }, \"foo.\");\n\n    // nesting temporaries in conditions\n    check({ foo(len == 2 ? makeS(1).get(len == 2 ? makeS(2).get() : null) : null); }, \"makeS(1).makeS(2).get(2).get(1).foo.dtor(2).dtor(1).\");\n    check({ foo(len == 2 ? makeS(1).get(len != 2 ? makeS(2).get() : null) : null); }, \"makeS(1).get(1).foo.dtor(1).\");\n    check({ foo(len != 2 ? makeS(1).get(len == 2 ? makeS(2).get() : null) : null); }, \"foo.\");\n    check({ foo(len != 2 ? makeS(1).get(len != 2 ? makeS(2).get() : null) : null); }, \"foo.\");\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14838\n\nint test14838() pure nothrow @safe\n{\n    int dtor;\n\n    struct S14838(T)\n    {\n        ~this() { ++dtor; }\n    }\n    struct X14838\n    {\n              S14838!int ms;\n        const S14838!int cs;\n\n              S14838!int[2] ma;\n        const S14838!int[2] ca;\n\n              S14838!int[2][2] ma2x2;\n        const S14838!int[2][2] ca2x2;\n\n        // number of S14838 = 1*2 + 2*2 + 4*2 = 14\n    }\n\n    void test(Dg)(scope Dg code)\n    {\n        dtor = 0;\n        code();\n    }\n\n    test(delegate{       S14838!int a; }); assert(dtor == 1);\n    test(delegate{ const S14838!int a; }); assert(dtor == 1);\n\n    test(delegate{       S14838!int[2] a; }); assert(dtor == 2);\n    test(delegate{ const S14838!int[2] a; }); assert(dtor == 2);\n\n    test(delegate{       S14838!int[2][2] a; }); assert(dtor == 4);\n    test(delegate{ const S14838!int[2][2] a; }); assert(dtor == 4);\n\n    test(delegate{       X14838 a; }); assert(dtor == 1 * 14);\n    test(delegate{ const X14838 a; }); assert(dtor == 1 * 14);\n\n    test(delegate{       X14838[2] a; }); assert(dtor == 2 * 14);\n    test(delegate{ const X14838[2] a; }); assert(dtor == 2 * 14);\n\n    test(delegate{       X14838[2][2] a; }); assert(dtor == 4 * 14);\n    test(delegate{ const X14838[2][2] a; }); assert(dtor == 4 * 14);\n\n    return 1;\n}\nstatic assert(test14838());\n\n/**********************************/\n\nstruct S63\n{\n    private long p = 87;\n\n    this(int x)\n    {\n        assert(p == 87);\n        p += x;\n    }\n\n    ~this() { }\n\n    this(this) { }\n\n    void funky() { assert(p == 90); }\n\n    static void tester()\n    {\n        S63(3).funky();\n    }\n}\n\nvoid test63()\n{\n    S63.tester();\n}\n\n/**********************************/\n\nstruct X64\n{\n    static int dtor;\n\n    ~this() { ++dtor; }\n}\n\nstruct S64\n{\n    int n;\n    long[10] dummy;     // S64 needs to be passed by stack\n}\n\nS64 foo64()\n{\n    X64();\n    return S64(1);\n}\n\nvoid test64()\n{\n    auto s = foo64();\n    assert(X64.dtor == 1);\n}\n\n/**********************************/\n\nstruct S65\n{\n    static string t;\n\n    void bar(int a, int b)\n    {\n        t ~= \"d\";\n    }\n}\n\nS65 foo65a()\n{\n    S65.t ~= \"a\";\n    return S65();\n}\n\nint foo65b()\n{\n    S65.t ~= \"b\";\n    return 1;\n}\n\nint foo65c()\n{\n    S65.t ~= \"c\";\n    return 2;\n}\n\nvoid test65()\n{\n    import core.stdc.stdio;\n    foo65a().bar(foo65b(), foo65c());\n    printf(\"'%.*s'\\n\", cast(int)S65.t.length, S65.t.ptr);\n    assert(S65.t == \"abcd\");\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=15661\n\nstruct X15661\n{\n    ~this() {}\n}\n\nX15661 createX15661() { return X15661(); }\n\nstruct Y15661\n{\n    static int dtor;\n\n    @disable this();\n    @disable this(this);\n    this(X15661 a1, X15661 a2) {}\n    ~this() { ++dtor; }\n}\n\nstruct Z15661\n{\n    this(int)\n    {\n        b = Y15661(createX15661(), createX15661());\n        assert(Y15661.dtor == 0);\n    }\n\n    private Y15661 b;\n}\n\nvoid test15661()\n{\n    {\n        auto v = Z15661(5);\n        assert(Y15661.dtor == 0);\n    }\n    assert(Y15661.dtor == 1);\n}\n\n/**********************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=18045\n\nstruct A18045\n{\n  nothrow:\n    __gshared int r;\n    int state;\n    this(this) { printf(\"postblit: A(%d)\\n\", state); r += 1; }\n    ~this() { printf(\"dtor: A(%d)\\n\", state); r *= 3; }\n}\n\nA18045 fun18045() nothrow\n{\n    __gshared a = A18045(42);\n    return a;\n}\n\nvoid test18045() nothrow\n{\n    alias A = A18045;\n\n    __gshared a = A(-42);\n    if (fun18045() == a)\n        assert(0);\n    else\n        assert(A.r == 3);\n\n    A.r = 0;\n    if (a == fun18045())\n        assert(0);\n    else\n        assert(A.r == 3);\n}\n\n/**********************************/\n\nstruct S66\n{\n    ~this() { }\n}\n\nnothrow void notthrow() { }\n\nclass C66\n{\n    S66 s;\n\n    this() nothrow { notthrow(); }\n}\n\n/**********************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n\n    test54();\n    test55();\n    test56();\n    test57();\n    test58();\n    test59();\n    test5737();\n    test6119();\n    test8741();\n    test6364();\n    test6499();\n    test60();\n    test4316();\n    test6177();\n    test6470();\n    test6636();\n    test6637();\n    test7353();\n    test61();\n    test7506();\n    test7516a();\n    test7516b();\n    test7516c();\n    test7516d();\n    test7516e();\n    test7530();\n    test62();\n    test7579a();\n    test7579b();\n    test8335();\n    test8356();\n    test9386();\n    test9441();\n    test9720();\n    test9899();\n    test9907();\n    test9985();\n    //test17457();    // XBUG: NRVO implementation differs\n    test9994();\n    test10094();\n    test10244();\n    test10694();\n    test10789();\n    test10972();\n    test11134();\n    test11197();\n    test7474();\n    test11505();\n    test12045();\n    test12591();\n    test12660();\n    test12686();\n    test13089();\n    test11763();\n    test13303();\n    test13673();\n    test13586();\n    test14443();\n    test13661();\n    test13661a();\n    test14022();\n    test14023();\n    test13669();\n    test13095();\n    test14264();\n    test14686();\n    test14815();\n    test16197();\n    test14860();\n    test14246();\n    test14696();\n    test14838();\n    test63();\n    test64();\n    test65();\n    test15661();\n    test18045();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/statictor.d",
    "content": "// PERMUTE_ARGS:\n// POST_SCRIPT: runnable/extra-files/statictor-postscript.sh\n\nprivate import std.stdio;\n\nclass Foo\n{\n        static this() {printf(\"Foo static ctor\\n\");}\n        static ~this() {printf(\"Foo static dtor\\n\");}\n}\n\nstatic this() {printf(\"static ctor\\n\");}\nstatic ~this() {printf(\"static dtor\\n\");}\n\nshared static this()\n{\n    printf(\"shared static this()\\n\");\n}\n\nshared static ~this()\n{\n    printf(\"shared static this()\\n\");\n}\n\nclass Bar\n{\n        static this() {printf(\"Bar static ctor\\n\");}\n        static ~this() {printf(\"Bar static dtor\\n\");}\n}\n\n/***********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6677\n\nint global6677;\n\nstatic this() nothrow pure @safe\n{\n    int* p;\n    static assert(!__traits(compiles, ++p));\n    static assert(!__traits(compiles, ++global6677));\n    auto throwit = { throw new Exception(\"sup\"); };\n    static assert(!__traits(compiles, throwit() ));\n}\n\nshared static this() nothrow pure @safe\n{\n    int* p;\n    static assert(!__traits(compiles, ++p));\n    static assert(!__traits(compiles, ++global6677));\n}\n\n/***********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7533\nstruct Foo7533(int n)\n{\n    pure static this() { }\n}\n\nalias Foo7533!5 Bar7533;\n\n/***********************************************/\n\nint main()\n{\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/stdint.d",
    "content": "// EXTRA_CPP_SOURCES: extra-files/stdint.cpp\n\nmodule stdint_test;\n\nimport core.stdc.stdint;\n\nextern(C++):\n\nint testCppI8Mangle (int8_t,  uint8_t,  int_least8_t,  uint_least8_t,  int_fast8_t,  uint_fast8_t);\nint testCppI16Mangle(int16_t, uint16_t, int_least16_t, uint_least16_t, int_fast16_t, uint_fast16_t);\nint testCppI32Mangle(int32_t, uint32_t, int_least32_t, uint_least32_t, int_fast32_t, uint_fast32_t);\nint testCppI64Mangle(int64_t, uint64_t, int_least64_t, uint_least64_t, int_fast64_t, uint_fast64_t);\nint testCppIntPtrMangle(intptr_t, uintptr_t);\nint testCppIntMaxMangle(intmax_t, uintmax_t);\n\nvoid main()\n{\n    assert(testCppI8Mangle (1, 2, 3, 4, 5, 6) == 1);\n    assert(testCppI16Mangle(1, 2, 3, 4, 5, 6) == 2);\n    assert(testCppI32Mangle(1, 2, 3, 4, 5, 6) == 3);\n    assert(testCppI64Mangle(1, 2, 3, 4, 5, 6) == 4);\n    assert(testCppIntPtrMangle(1, 2) == 5);\n    assert(testCppIntMaxMangle(1, 2) == 6);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/stress.d",
    "content": "// PERMUTE_ARGS:\n\nimport core.stdc.stdio : printf;\nimport std.string : splitLines;\nimport std.utf : toUTF16, toUTF32;\n\n/***********************************************/\n\nvoid test3()\n{\n    char[] str;\n    str ~= \"test\"; // segfault\n}\n\n/***********************************************/\n\nclass A {\nprivate:\n    int _i;\npublic:\n    this(int i) { _i = i; }\n    int i() { return _i; };\n}\n\nclass B : A {\nprivate:\n    char[] s;\npublic:\n    this(int i) { super(i); }\n}\n\nint main()\n{\n    printf(\"Testing array of Chars\\n\");\n    CHAR();\n    printf(\"Testing array of WChars\\n\");\n    WCHAR();\n    printf(\"Testing array of DChars\\n\");\n    DCHAR();\n\n    printf(\"Testing array of Bytes\\n\");\n    BYTE();\n    printf(\"Testing array of UBytes\\n\");\n    UBYTE();\n    printf(\"Testing array of Shorts\\n\");\n    SHORT();\n    printf(\"Testing array of UShorts\\n\");\n    USHORT();\n    printf(\"Testing array of Ints\\n\");\n    INT();\n    printf(\"Testing array of UInts\\n\");\n    UINT();\n    printf(\"Testing array of Longs\\n\");\n    LONG();\n    printf(\"Testing array of ULongs\\n\");\n    ULONG();\n    printf(\"Testing array of Floats\\n\");\n    FLOAT();\n    printf(\"Testing array of Doubles\\n\");\n    DOUBLE();\n    printf(\"Testing array of Reals\\n\");\n    REAL();\n\n    printf(\"Testing multi-dim array of Chars\\n\");\n    MDCHAR();\n\n    printf(\"Testing array of Objects\\n\");\n    CLASS();\n\n    test3();\n    return 0;\n}\n\nvoid MDCHAR()\n{\n    const int ITERS = 100;\n    alias char typ;\n    typ[][] str;\n\n    str.length = ITERS;\n    for(int idx = 0; idx < ITERS; idx++) {\n        str[idx] = str[idx] ~ \"TEST LINE\\n\";\n    }\n\n    if(str.length != ITERS) printf(\"Length Error: %d\\n\",str.length);\n    if(str[0].length != 10) printf(\"Length Error: %d\\n\",str[0].length);\n    if(str[ITERS-1].sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",str[ITERS-1].sizeof);\n    if(str[ITERS-1][0].sizeof != (typ).sizeof) printf(\"Size Error: %d\\n\",str[ITERS-1][0].sizeof);\n\n    foreach(s; str) {\n        int lstart;\n        foreach(int idx, char c; s) {\n            if(c == '\\n') {\n                typ[] t = s[lstart..idx];\n                if(t != \"TEST LINE\") {\n                    printf(\"Error testing character array\\n\");\n                    break;\n                }\n                lstart = idx + 1;\n            }\n        }\n    }\n\n    typ[] tmp;\n    foreach(char[] s; str) {\n        tmp = tmp ~ s;\n    }\n\n    foreach(s; splitLines(cast(string)tmp)) {\n        int lstart;\n        foreach(int idx, char c; s) {\n            if(c == '\\n') {\n                if(s[lstart..idx] != \"TEST LINE\") {\n                    printf(\"Error testing character array\\n\");\n                    break;\n                }\n                lstart = idx + 1;\n            }\n        }\n    }\n}\n\nvoid CHAR()\n{\n    const int ITERS = 1000;\n    alias char typ;\n    typ[] str;\n\n    for(int idx = 0; idx < ITERS; idx++) {\n        str = str ~ \"TEST LINE\\n\";\n    }\n\n    if(str.length != (ITERS * 10)) printf(\"Length Error: %d\\n\",str.length);\n    if(str.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",str.sizeof);\n\n    int lstart;\n    foreach(int idx, char c; str) {\n        if(c == '\\n') {\n            if(str[lstart..idx] != \"TEST LINE\") {\n                printf(\"Error testing character array\\n\");\n                break;\n            }\n            lstart = idx + 1;\n        }\n    }\n}\n\nvoid WCHAR()\n{\n    const int ITERS = 1000;\n    alias wchar typ;\n    typ[] str;\n\n    for(int idx = 0; idx < ITERS; idx++) {\n        str = str ~ toUTF16(cast(char[])\"TEST LINE\\n\");\n    }\n\n    if(str.length != (ITERS * 10)) printf(\"Length Error: %d\\n\",str.length);\n    if(str.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",str.sizeof);\n\n    int lstart;\n    foreach(int idx, char c; str) {\n        if(c == '\\n') {\n            if(str[lstart..idx] != toUTF16(cast(char[])\"TEST LINE\")) {\n                printf(\"Error testing character array\\n\");\n                break;\n            }\n            lstart = idx + 1;\n        }\n    }\n}\n\nvoid DCHAR()\n{\n    const int ITERS = 1000;\n    alias dchar typ;\n    typ[] str;\n\n    for(int idx = 0; idx < ITERS; idx++) {\n        str = str ~ toUTF32(cast(char[])\"TEST LINE\\n\");\n    }\n\n    if(str.length != (ITERS * 10)) printf(\"Length Error: %d\\n\",str.length);\n    if(str.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",str.sizeof);\n\n    int lstart;\n    foreach(int idx, char c; str) {\n        if(c == '\\n') {\n            if(str[lstart..idx] != toUTF32(cast(char[])\"TEST LINE\")) {\n                printf(\"Error testing character array\\n\");\n                break;\n            }\n            lstart = idx + 1;\n        }\n    }\n}\n\nvoid BYTE()\n{\n    const int ITERS = 100;\n    alias byte typ;\n    typ[] a;\n\n    for(typ idx = 0; idx < ITERS; idx++) {\n        a ~= idx;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx] != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx]);\n            break;\n        }\n    }\n\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx] != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx]);\n            break;\n        }\n    }\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx] != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx]);\n            break;\n        }\n    }\n}\n\nvoid UBYTE()\n{\n    const int ITERS = 100;\n    alias ubyte typ;\n    typ[] a;\n\n    for(typ idx = 0; idx < ITERS; idx++) {\n        a ~= idx;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx] != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx]);\n            break;\n        }\n    }\n\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx] != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx]);\n            break;\n        }\n    }\n\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx] != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx]);\n            break;\n        }\n    }\n}\n\nvoid SHORT()\n{\n    const int ITERS = 10000;\n    alias short typ;\n    typ[] a;\n\n    for(typ idx = 0; idx < ITERS; idx++) {\n        a ~= idx;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx] != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx]);\n            break;\n        }\n    }\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx] != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx]);\n            break;\n        }\n    }\n\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx] != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx]);\n            break;\n        }\n    }\n}\n\nvoid USHORT()\n{\n    const int ITERS = 10000;\n    alias ushort typ;\n    typ[] a;\n\n    for(typ idx = 0; idx < ITERS; idx++) {\n        a ~= idx;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx] != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx]);\n            break;\n        }\n    }\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx] != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx]);\n            break;\n        }\n    }\n\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx] != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx]);\n            break;\n        }\n    }\n}\n\nvoid INT()\n{\n    const int ITERS = 1000000;\n    alias int typ;\n    typ[] a;\n\n    for(int idx = 0; idx < ITERS; idx++) {\n        a ~= idx;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx] != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx]);\n            break;\n        }\n    }\n\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx] != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx]);\n            break;\n        }\n    }\n\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx] != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx]);\n            break;\n        }\n    }\n}\n\nvoid UINT()\n{\n    const int ITERS = 1000000;\n    alias uint typ;\n    typ[] a;\n\n    for(int idx = 0; idx < ITERS; idx++) {\n        a ~= idx;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx] != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx]);\n            break;\n        }\n    }\n\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx] != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx]);\n            break;\n        }\n    }\n\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx] != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx]);\n            break;\n        }\n    }\n}\n\nvoid LONG()\n{\n    const int ITERS = 1000000;\n    alias long typ;\n    typ[] a;\n\n    for(int idx = 0; idx < ITERS; idx++) {\n        a ~= idx;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx] != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx]);\n            break;\n        }\n    }\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx] != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx]);\n            break;\n        }\n    }\n\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx] != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx]);\n            break;\n        }\n    }\n}\n\nvoid ULONG()\n{\n    const int ITERS = 1000000;\n    alias ulong typ;\n    typ[] a;\n\n    for(int idx = 0; idx < ITERS; idx++) {\n        a ~= idx;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx] != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx]);\n            break;\n        }\n    }\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx] != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx]);\n            break;\n        }\n    }\n\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx] != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx]);\n            break;\n        }\n    }\n}\n\nvoid FLOAT()\n{\n    const int ITERS = 1000000;\n    alias float typ;\n    typ[] a;\n\n    for(int idx = 0; idx < ITERS; idx++) {\n        a ~= idx;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx] != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx]);\n            break;\n        }\n    }\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx] != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx]);\n            break;\n        }\n    }\n\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx] != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx]);\n            break;\n        }\n    }\n}\n\nvoid DOUBLE()\n{\n    const int ITERS = 1000000;\n    alias double typ;\n    typ[] a;\n\n    for(int idx = 0; idx < ITERS; idx++) {\n        a ~= idx;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx] != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx]);\n            break;\n        }\n    }\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx] != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx]);\n            break;\n        }\n    }\n\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx] != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx]);\n            break;\n        }\n    }\n}\n\nvoid REAL()\n{\n    const int ITERS = 1000000;\n    alias real typ;\n    typ[] a;\n\n    for(int idx = 0; idx < ITERS; idx++) {\n        a ~= idx;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx] != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx]);\n            break;\n        }\n    }\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx] != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx]);\n            break;\n        }\n    }\n\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx] != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx]);\n            break;\n        }\n    }\n}\n\nvoid CLASS()\n{\n    const int ITERS = 1000000;\n    alias B typ;\n    typ[] a;\n\n    for(int idx = 0; idx < ITERS; idx++) {\n        typ tc = new typ(idx);\n        a ~= tc;\n    }\n\n    if(a.length != ITERS) printf(\"Length Error: %d\\n\",a.length);\n    if(a.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",a.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(a[idx].i != idx) {\n            printf(\"a Data Error: %d\\n\",a[idx].i);\n            break;\n        }\n    }\n\n    typ[] b = a[];\n\n    if(b.length != ITERS) printf(\"Length Error: %d\\n\",b.length);\n    if(b.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",b.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(b[idx].i != idx) {\n            printf(\"b Data Error: %d\\n\",b[idx].i);\n            break;\n        }\n    }\n\n    typ[] c;\n    c = a[0..ITERS/2] ~ b[ITERS/2..$];\n\n    if(c.length != ITERS) printf(\"Length Error: %d\\n\",c.length);\n    if(c.sizeof != (typ[]).sizeof) printf(\"Size Error: %d\\n\",c.sizeof);\n    for(int idx = 0; idx < ITERS; idx++) {\n        if(c[idx].i != idx) {\n            printf(\"c Data Error: %d\\n\",c[idx].i);\n            break;\n        }\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/structlit.d",
    "content": "import std.stdio;\n\nstruct S\n{\n    int x;\n    int y;\n}\n\n/********************************************/\n\nvoid test1()\n{\n    S s = S(1,2);\n    assert(s.x == 1);\n    assert(s.y == 2);\n}\n\n/********************************************/\n\nvoid foo2(S s)\n{\n    assert(s.x == 1);\n    assert(s.y == 2);\n}\n\nvoid test2()\n{\n    foo2( S(1,2) );\n}\n\n/********************************************/\n\nS foo3()\n{\n    return S(1, 2);\n}\n\nvoid test3()\n{\n    S s = foo3();\n    assert(s.x == 1);\n    assert(s.y == 2);\n}\n\n/********************************************/\n\nstruct S4\n{\n    long x;\n    long y;\n    long z;\n}\n\nS4 foo4()\n{\n    return S4(1, 2, 3);\n}\n\nvoid test4()\n{\n    S4 s = foo4();\n    assert(s.x == 1);\n    assert(s.y == 2);\n    assert(s.z == 3);\n}\n\n/********************************************/\n\nstruct S5\n{\n    long x;\n    char y;\n    long z;\n}\n\nS5 foo5()\n{\n    return S5(1, 2, 3);\n}\n\nvoid test5()\n{\n    S5 s = foo5();\n    assert(s.x == 1);\n    assert(s.y == 2);\n    assert(s.z == 3);\n}\n\n/********************************************/\n\nstruct S6\n{\n    long x;\n    char y;\n    long z;\n}\n\nvoid test6()\n{\n    S6 s1 = S6(1,2,3);\n    S6 s2 = S6(1,2,3);\n    assert(s1 == s2);\n\n    s1 = S6(4,5,6);\n    s2 = S6(4,5,6);\n    assert(s1 == s2);\n\n    S6* p1 = &s1;\n    S6* p2 = &s2;\n    *p1 = S6(7,8,9);\n    *p2 = S6(7,8,9);\n    assert(*p1 == *p2);\n}\n\n/********************************************/\n\nstruct S7\n{\n    long x;\n    char y;\n    long z;\n}\n\nvoid test7()\n{\n    static S7 s1 = S7(1,2,3);\n    static S7 s2 = S7(1,2,3);\n    assert(s1 == s2);\n}\n\n/********************************************/\n\nstruct S8\n{\n    int i;\n    string s;\n}\n\nvoid test8()\n{\n    S8 s = S8(3, \"hello\");\n    assert(s.i == 3);\n    assert(s.s == \"hello\");\n\n    static S8 t = S8(4, \"betty\");\n    assert(t.i == 4);\n    assert(t.s == \"betty\");\n\n    S8 u = S8(3, ['h','e','l','l','o']);\n    assert(u.i == 3);\n    assert(u.s == \"hello\");\n\n    static S8 v = S8(4, ['b','e','t','t','y']);\n    assert(v.i == 4);\n    assert(v.s == \"betty\");\n}\n\n/********************************************/\n\nstruct S9\n{\n    int i;\n    char[5] s;\n}\n\nvoid test9()\n{\n    S9 s = S9(3, \"hello\");\n    assert(s.i == 3);\n    assert(s.s == \"hello\");\n\n    static S9 t = S9(4, \"betty\");\n    assert(t.i == 4);\n    assert(t.s == \"betty\");\n\n    S9 u = S9(3, ['h','e','l','l','o']);\n    assert(u.i == 3);\n    assert(u.s == \"hello\");\n\n    static S9 v = S9(4, ['b','e','t','t','y']);\n    assert(v.i == 4);\n    assert(v.s == \"betty\");\n}\n\n/********************************************/\n\nalias int myint10;\n\nstruct S10\n{\n    int i;\n    union\n    {\n        int x = 2;\n        int y;\n    }\n    int j = 3;\n    myint10 k = 4;\n}\n\nvoid test10()\n{\n    S10 s = S10( 1 );\n    assert(s.i == 1);\n    assert(s.x == 2);\n    assert(s.y == 2);\n    assert(s.j == 3);\n    assert(s.k == 4);\n\n    static S10 t = S10( 1 );\n    assert(t.i == 1);\n    assert(t.x == 2);\n    assert(t.y == 2);\n    assert(t.j == 3);\n    assert(t.k == 4);\n\n    S10 u = S10( 1, 5 );\n    assert(u.i == 1);\n    assert(u.x == 5);\n    assert(u.y == 5);\n    assert(u.j == 3);\n    assert(u.k == 4);\n\n    static S10 v = S10( 1, 6 );\n    assert(v.i == 1);\n    assert(v.x == 6);\n    assert(v.y == 6);\n    assert(v.j == 3);\n    assert(v.k == 4);\n}\n\n/********************************************/\n\nstruct S11\n{\n    int i;\n    int j = 3;\n}\n\n\nvoid test11()\n{\n    static const s = S11( 1, 5 );\n    static const i = s.i;\n    assert(i == 1);\n    static assert(s.j == 5);\n}\n\n/********************************************/\n\nstruct S12\n{\n    int[5] x;\n    int[5] y = 3;\n}\n\nvoid test12()\n{\n    S12 s = S12();\n    foreach (v; s.x)\n        assert(v == 0);\n    foreach (v; s.y)\n        assert(v == 3);\n}\n\n/********************************************/\n\nstruct S13\n{\n    int[5] x;\n    int[5] y;\n    int[6][3] z;\n}\n\nvoid test13()\n{\n    S13 s = S13(0,3,4);\n    foreach (v; s.x)\n        assert(v == 0);\n    foreach (v; s.y)\n        assert(v == 3);\n    for (int i = 0; i < 6; i++)\n    {\n        for (int j = 0; j < 3; j++)\n        {\n            assert(s.z[j][i] == 4);\n        }\n    }\n}\n\n/********************************************/\n\nstruct S14a { int n; }\nstruct S14b { this(int n){} }\n\nvoid foo14(ref S14a s) {}\nvoid foo14(ref S14b s) {}\nvoid hoo14()(ref S14a s) {}\nvoid hoo14()(ref S14b s) {}\nvoid poo14(S)(ref S s) {}\n\nvoid bar14(S14a s) {}\nvoid bar14(S14b s) {}\nvoid var14()(S14a s) {}\nvoid var14()(S14b s) {}\nvoid war14(S)(S s) {}\n\nint baz14(    S14a s) { return 1; }\nint baz14(ref S14a s) { return 2; }\nint baz14(    S14b s) { return 1; }\nint baz14(ref S14b s) { return 2; }\nint vaz14()(    S14a s) { return 1; }\nint vaz14()(ref S14a s) { return 2; }\nint vaz14()(    S14b s) { return 1; }\nint vaz14()(ref S14b s) { return 2; }\nint waz14(S)(    S s) { return 1; }\nint waz14(S)(ref S s) { return 2; }\n\nvoid test14()\n{\n    // can not bind rvalue-sl with ref\n    static assert(!__traits(compiles, foo14(S14a(0))));\n    static assert(!__traits(compiles, foo14(S14b(0))));\n    static assert(!__traits(compiles, hoo14(S14a(0))));\n    static assert(!__traits(compiles, hoo14(S14b(0))));\n    static assert(!__traits(compiles, poo14(S14a(0))));\n    static assert(!__traits(compiles, poo14(S14b(0))));\n\n    // still can bind rvalue-sl with non-ref\n    bar14(S14a(0));\n    bar14(S14b(0));\n    var14(S14a(0));\n    var14(S14b(0));\n    war14(S14a(0));\n    war14(S14b(0));\n\n    // preferred binding of rvalue-sl in overload resolution\n    assert(baz14(S14a(0)) == 1);\n    assert(baz14(S14b(0)) == 1);\n    assert(vaz14(S14a(0)) == 1);\n    assert(vaz14(S14b(0)) == 1);\n    assert(waz14(S14a(0)) == 1);\n    assert(waz14(S14b(0)) == 1);\n}\n\n/********************************************/\n\nvoid check15(T, ubyte results, A...)(A args)\n{\n                         // m c i s sc\n    enum m  = (results & 0b_1_0_0_0_0) != 0;\n    enum c  = (results & 0b_0_1_0_0_0) != 0;\n    enum i  = (results & 0b_0_0_1_0_0) != 0;\n    enum s  = (results & 0b_0_0_0_1_0) != 0;\n    enum sc = (results & 0b_0_0_0_0_1) != 0;\n\n    // allocation on stack\n    static assert((is(typeof(                  T(args) ) U) && is(U ==              T  )) == m);\n    static assert((is(typeof(            const T(args) ) U) && is(U ==        const(T) )) == c);\n    static assert((is(typeof(        immutable T(args) ) U) && is(U ==    immutable(T) )) == i);\n    static assert((is(typeof(           shared T(args) ) U) && is(U ==       shared(T) )) == s);\n    static assert((is(typeof(     shared const T(args) ) U) && is(U == shared(const T) )) == sc);\n\n    // allocation on heap\n    static assert((is(typeof( new              T(args) ) U) && is(U ==              T *)) == m);\n    static assert((is(typeof( new        const T(args) ) U) && is(U ==        const(T)*)) == c);\n    static assert((is(typeof( new    immutable T(args) ) U) && is(U ==    immutable(T)*)) == i);\n    static assert((is(typeof( new       shared T(args) ) U) && is(U ==       shared(T)*)) == s);\n    static assert((is(typeof( new shared const T(args) ) U) && is(U == shared(const T)*)) == sc);\n}\nvoid test15a()\n{\n    static struct Foo1 { this(int v) {}                int value; }\n    static struct Boo1 { this(int v) const {}          int[] value; }\n    static struct Bar1 { this(int[] v) {}              int[] value; }\n    static struct Baz1 { this(const int[] v) pure {}   int[] value; }  // unique ctor\n    static struct Coo1 { this(int[] v) immutable {}    int[] value; }\n    static struct Car1 { this(int[] v) immutable {}    immutable(int)[] value; }\n    check15!(Foo1, 0b_1_1_0_0_0)(1);\n    check15!(Boo1, 0b_0_1_0_0_0)(1);\n    check15!(Bar1, 0b_1_1_0_0_0)(null);\n    check15!(Baz1, 0b_1_1_1_1_1)(null);\n    check15!(Coo1, 0b_0_1_1_0_1)(null);\n    check15!(Car1, 0b_0_1_1_0_1)(null);\n                   // m c i s sc\n\n    // Template constructor should work as same as non-template ones\n    static struct Foo2 { this()(int v) {}              int value; }\n    static struct Boo2 { this()(int v) const {}        int[] value; }\n    static struct Bar2 { this()(int[] v) {}            int[] value; }  // has mutable indieection\n    static struct Baz2 { this()(const int[] v) pure {} int[] value; }  // unique ctor\n    static struct Coo2 { this()(int[] v) immutable {}  int[] value; }\n    static struct Car2 { this()(int[] v) immutable {}  immutable(int)[] value; }\n    check15!(Foo2, 0b_1_1_0_0_0)(1);\n    check15!(Boo2, 0b_0_1_0_0_0)(1);\n    check15!(Bar2, 0b_1_1_0_0_0)(null);\n    check15!(Baz2, 0b_1_1_1_1_1)(null);\n    check15!(Coo2, 0b_0_1_1_0_1)(null);\n    check15!(Car2, 0b_0_1_1_0_1)(null);\n                   // m c i s sc\n\n    // Except Bar!().__ctor, their constructors are inferred to pure, then they become unique ctors.\n    static struct Foo3() { this(int v) {}              int value; }\n    static struct Boo3() { this(int v) const {}        int[] value; }\n    static struct Bar3() { this(int[] v) {}            int[] value; }  // has mutable indieection\n    static struct Baz3() { this(const int[] v) pure {} int[] value; }  // unique ctor\n    static struct Coo3() { this(int[] v) immutable {}  int[] value; }\n    static struct Car3() { this(int[] v) immutable {}  immutable(int)[] value; }\n    check15!(Foo3!(), 0b_1_1_1_1_1)(1);\n    check15!(Boo3!(), 0b_1_1_1_1_1)(1);\n    check15!(Bar3!(), 0b_1_1_0_0_0)(null);\n    check15!(Baz3!(), 0b_1_1_1_1_1)(null);\n    check15!(Coo3!(), 0b_1_1_1_1_1)(null);\n    check15!(Car3!(), 0b_1_1_1_1_1)(null);\n                      // m c i s sc\n}\n\n// inout constructor works as like unique constructor in many cases\nvoid test15b()\n{\n    static struct Nullable1\n    {\n        private int[] _value;\n        private bool _isNull = true;\n        this(inout int[] v) inout //pure\n        {\n            _value = v;\n            //static int g; auto x = g; // impure access\n            _isNull = false;\n        }\n    }\n    static assert( __traits(compiles,           Nullable1([1,2,3])));\n    static assert(!__traits(compiles,           Nullable1([1,2,3].idup)));\n    static assert(!__traits(compiles, immutable Nullable1([1,2,3])));\n    static assert( __traits(compiles, immutable Nullable1([1,2,3].idup)));\n    static assert(!__traits(compiles,    shared Nullable1([1,2,3])));\n    static assert(!__traits(compiles,    shared Nullable1([1,2,3].idup)));\n\n    static struct Nullable2(T)\n    {\n        private T _value;\n        private bool _isNull = true;\n        this(inout T v) inout //pure\n        {\n            _value = v;\n            //static int g; auto x = g; // impure access\n            _isNull = false;\n        }\n    }\n    static assert( __traits(compiles,           Nullable2!(int[])([1,2,3])));\n    static assert(!__traits(compiles,           Nullable2!(int[])([1,2,3].idup)));\n    static assert(!__traits(compiles, immutable Nullable2!(int[])([1,2,3])));\n    static assert( __traits(compiles, immutable Nullable2!(int[])([1,2,3].idup)));\n    static assert(!__traits(compiles,    shared Nullable2!(int[])([1,2,3])));\n    static assert(!__traits(compiles,    shared Nullable2!(int[])([1,2,3].idup)));\n\n    // ctor is inout pure, but cannot create unique object.\n    struct S\n    {\n        int[] marr;\n        const int[] carr;\n        immutable int[] iarr;\n        this(int[] m, const int[] c, immutable int[] i) inout pure\n        {\n            static assert(!__traits(compiles, marr = m));\n            static assert(!__traits(compiles, carr = c));  // cannot implicitly convertible const(int[]) to inout(const(int[]))\n            iarr = i;\n        }\n    }\n    static assert(!__traits(compiles, { int[] ma; immutable int[] ia; auto m =           S(ma, ma, ia); }));\n    static assert( __traits(compiles, { int[] ma; immutable int[] ia; auto c =     const S(ma, ma, ia); }));\n    static assert(!__traits(compiles, { int[] ma; immutable int[] ia; auto i = immutable S(ma, ma, ia); }));\n}\n\n// TemplateThisParameter with constructor should work\nvoid test15c()\n{\n    static class C\n    {\n        this(this This)()\n        {\n            static assert(is(This == immutable C));\n        }\n\n        this(T = void, this This)(int)\n        {\n            static assert(is(This == immutable C));\n        }\n    }\n    auto c1 = new immutable C;\n    auto c2 = new immutable C(1);\n}\n\nvoid test15d()  // https://issues.dlang.org/show_bug.cgi?id=9974\n{\n    class CM { this() {} }\n    auto cm = new CM();\n\n    const class CC { this() {} }\n    const cc = new const CC();\n\n    immutable class CI { this() {} }\n    immutable ci = new immutable CI();\n\n    shared class CS { this() {} }\n    shared cs = new shared CS();\n\n    shared const class CSC { this() {} }\n    shared const csc = new shared const CSC();\n\n\n    struct SM { this(int) {} }\n    auto sm = new SM(1);\n\n    const struct SC { this(int) {} }\n    const sc = new const SC(1);\n\n    immutable struct SI { this(int) {} }\n    immutable si = new immutable SI(1);\n\n    shared struct SS { this(int) {} }\n    shared ss = new shared SS(1);\n\n    shared const struct SSC { this(int) {} }\n    shared const ssc = new shared const SSC(1);\n}\n\nvoid test15e()  // https://issues.dlang.org/show_bug.cgi?id=10005\n{\n    // struct literal\n    static struct S\n    {\n        int[] a;\n    }\n    int[] marr = [1,2,3];\n    static assert( __traits(compiles, {           S m =           S(marr); }));\n    static assert( __traits(compiles, {     const S c =           S(marr); }));\n    static assert(!__traits(compiles, { immutable S i =           S(marr); }));\n    immutable int[] iarr = [1,2,3];\n    static assert(!__traits(compiles, {           S m = immutable S(iarr); }));\n    static assert( __traits(compiles, {     const S c = immutable S(iarr); }));\n    static assert( __traits(compiles, { immutable S i = immutable S(iarr); }));\n\n    // mutable constructor\n    static struct MS\n    {\n        int[] a;\n        this(int n) { a = new int[](n); }\n    }\n    static assert( __traits(compiles, {           MS m =           MS(3); }));\n    static assert( __traits(compiles, {     const MS c =           MS(3); }));\n    static assert(!__traits(compiles, { immutable MS i =           MS(3); }));\n    static assert(!__traits(compiles, {           MS m = immutable MS(3); }));\n    static assert(!__traits(compiles, {     const MS c = immutable MS(3); }));\n    static assert(!__traits(compiles, { immutable MS i = immutable MS(3); }));\n\n    // immutable constructor\n    static struct IS\n    {\n        int[] a;\n        this(int n) immutable { a = new int[](n); }\n    }\n    static assert(!__traits(compiles, {           IS m =           IS(3); }));\n    static assert(!__traits(compiles, {     const IS c =           IS(3); }));\n    static assert(!__traits(compiles, { immutable IS i =           IS(3); }));\n    static assert(!__traits(compiles, {           IS m = immutable IS(3); }));\n    static assert( __traits(compiles, {     const IS c = immutable IS(3); }));\n    static assert( __traits(compiles, { immutable IS i = immutable IS(3); }));\n}\n\nstruct Foo9984\n{\n    int[] p;\n    // Prefix storage class and tempalte constructor\n    inout this()(inout int[] a) { p = a; }\n    auto foo() inout { return inout(Foo9984)(p); }\n}\n\nvoid test9993a()\n{\n    static class A\n    {\n        int x;\n        this()           { x = 13; }\n        this() immutable { x = 42; }\n    }\n              A ma = new           A;   assert(ma.x == 13);\n    immutable A ia = new immutable A;   assert(ia.x == 42);\n    static assert(!__traits(compiles, { immutable A ia = new A; }));\n\n    static class B\n    {\n        int x;\n        this()       { x = 13; }\n        this() const { x = 42; }\n    }\n    const B mb = new       B;           assert(mb.x == 13);\n    const B cb = new const B;           assert(cb.x == 42);\n    static assert(!__traits(compiles, { immutable B ib = new B; }));\n\n    static class C\n    {\n        int x;\n        this() const     { x = 13; }\n        this() immutable { x = 42; }\n    }\n        const C cc = new     const C;   assert(cc.x == 13);\n    immutable C ic = new immutable C;   assert(ic.x == 42);\n    static assert(!__traits(compiles, { C mc = new C; }));\n}\nvoid test9993b()\n{\n    static class A\n    {\n        int x;\n        this()()           { x = 13; }\n        this()() immutable { x = 42; }\n    }\n              A ma = new           A;   assert(ma.x == 13);\n    immutable A ia = new immutable A;   assert(ia.x == 42);\n    static assert(__traits(compiles, { immutable A ia = new A; }));\n\n    static class B\n    {\n        int x;\n        this()()       { x = 13; }\n        this()() const { x = 42; }\n    }\n    const B mb = new       B;           assert(mb.x == 13);\n    const B cb = new const B;           assert(cb.x == 42);\n    static assert(__traits(compiles, { immutable B ib = new B; }));\n\n    static class C\n    {\n        int x;\n        this()() const     { x = 13; }\n        this()() immutable { x = 42; }\n    }\n        const C cc = new     const C;   assert(cc.x == 13);\n    immutable C ic = new immutable C;   assert(ic.x == 42);\n    static assert(!__traits(compiles, { C mc = new C; }));\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1914\n\nstruct Bug1914a\n{\n    const char[10] i = [1,0,0,0,0,0,0,0,0,0];\n    char[10] x = i;\n    int y = 5;\n}\n\nstruct Bug1914b\n{\n    const char[10] i = [0,0,0,0,0,0,0,0,0,0];\n    char[10] x = i;\n    int y = 5;\n}\n\nstruct Bug1914c\n{\n    const char[2] i = ['a', 'b'];\n    const char[2][3] j = [['x', 'y'], ['p', 'q'], ['r', 's']];\n    const char[2][3] k = [\"cd\", \"ef\", \"gh\"];\n    const char[2][3] l = [['x', 'y'], ['p'], ['h', 'k']];\n    char[2][3] x = i;\n    int y = 5;\n    char[2][3] z = j;\n    char[2][3] w = k;\n    int v = 27;\n    char[2][3] u = l;\n    int t = 718;\n}\n\nstruct T3198\n{\n    int g = 1;\n}\n\nclass Foo3198\n{\n    int[5] x = 6;\n    T3198[5] y = T3198(4);\n}\n\nvoid test3198and1914()\n{\n    Bug1914a a;\n    assert(a.y == 5, \"bug 1914, non-zero init\");\n    Bug1914b b;\n    assert(b.y == 5, \"bug 1914, zero init\");\n    Bug1914c c;\n    assert(c.y == 5, \"bug 1914, multilevel init\");\n    assert(c.v == 27, \"bug 1914, multilevel init2\");\n    assert(c.x[2][1] == 'b');\n    assert(c.t == 718, \"bug 1914, multi3\");\n    assert(c.u[1][0] == 'p');\n    assert(c.u[1][1] == char.init);\n    auto f = new Foo3198();\n    assert(f.x[0] == 6);\n    assert(f.y[0].g == 4, \"bug 3198\");\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14996\n\nenum E14996a : string { confirm = \"confirm\" }\nenum E14996b : long[] { confirm = [1,2,3,4] }\n\nstruct S14996\n{\n    E14996a[1] data1;\n    E14996b[1] data2;\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2427\n\nvoid test2427()\n{\n    struct S\n    {\n        int x;\n    }\n\n    int foo(int i)\n    {\n        return i;\n    }\n\n    int i;\n    S s = { foo(i) };\n}\n\n/********************************************/\n\nstruct T5885 {\n    uint a, b;\n}\n\ndouble mulUintToDouble(T5885 t, double m) {\n    return t.a * m;\n}\n\nvoid test5885()\n{\n    enum ae = mulUintToDouble(T5885(10, 0), 10.0);\n    enum be = mulUintToDouble(T5885(10, 20), 10.0);\n    static assert(ae == be);\n\n    auto a = mulUintToDouble(T5885(10, 0), 10.0);\n    auto b = mulUintToDouble(T5885(10, 20), 10.0);\n    assert(a == b);\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5889\n\nstruct S5889a { int n; }\nstruct S5889b { this(int n){} }\n\nbool isLvalue(S)(auto ref S s){ return __traits(isRef, s); }\n\nint foo(ref S5889a s) { return 1; }\nint foo(    S5889a s) { return 2; }\nint foo(ref S5889b s) { return 1; }\nint foo(    S5889b s) { return 2; }\n\nint goo(ref const(S5889a) s) { return 1; }\nint goo(    const(S5889a) s) { return 2; }\nint goo(ref const(S5889b) s) { return 1; }\nint goo(    const(S5889b) s) { return 2; }\n\nint too(S)(ref S s) { return 1; }\nint too(S)(    S s) { return 2; }\n\nS makeRvalue(S)(){ S s; return s; }\n\nvoid test5889()\n{\n    S5889a sa;\n    S5889b sb;\n\n    assert( isLvalue(sa));\n    assert( isLvalue(sb));\n    assert(!isLvalue(S5889a(0)));\n    assert(!isLvalue(S5889b(0)));\n    assert(!isLvalue(makeRvalue!S5889a()));\n    assert(!isLvalue(makeRvalue!S5889b()));\n\n    assert(foo(sa) == 1);\n    assert(foo(sb) == 1);\n    assert(foo(S5889a(0)) == 2);\n    assert(foo(S5889b(0)) == 2);\n    assert(foo(makeRvalue!S5889a()) == 2);\n    assert(foo(makeRvalue!S5889b()) == 2);\n\n    assert(goo(sa) == 1);\n    assert(goo(sb) == 1);\n    assert(goo(S5889a(0)) == 2);\n    assert(goo(S5889b(0)) == 2);\n    assert(goo(makeRvalue!S5889a()) == 2);\n    assert(goo(makeRvalue!S5889b()) == 2);\n\n    assert(too(sa) == 1);\n    assert(too(sb) == 1);\n    assert(too(S5889a(0)) == 2);\n    assert(too(S5889b(0)) == 2);\n    assert(too(makeRvalue!S5889a()) == 2);\n    assert(too(makeRvalue!S5889b()) == 2);\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4147\n\nstruct S4247\n{\n    int n = 1024;\n    this(int x) { n = x; }\n}\nvoid test4247()\n{\n    auto p1 = S4247();\n    assert(p1.n == 1024);\n\n    auto p2 = S4247(1);\n    assert(p2.n == 1);\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6937\n\nvoid test6937()\n{\n    static struct S\n    {\n        int x, y;\n    }\n\n    auto s1 = S(1, 2);\n    auto ps1 = new S(1, 2);\n    assert(ps1.x == 1);\n    assert(ps1.y == 2);\n    assert(*ps1 == s1);\n\n    auto ps2 = new S(1);\n    assert(ps2.x == 1);\n    assert(ps2.y == 0);\n    assert(*ps2 == S(1, 0));\n\n    static assert(!__traits(compiles, new S(1,2,3)));\n\n    int v = 0;\n    struct NS\n    {\n        int x;\n        void foo() { v = x; }\n    }\n    auto ns = NS(1);\n    ns.foo();\n    assert(ns.x == 1);\n    assert(v == 1);\n    auto pns = new NS(2);\n    assert(pns.x == 2);\n    pns.foo();\n    assert(v == 2);\n    pns.x = 1;\n    assert(*pns == ns);\n\n    static struct X {\n        int v;\n        this(this) { ++v; }\n    }\n    static struct Y {\n        X x;\n    }\n    Y y = Y(X(1));\n    assert(y.x.v == 1);\n    auto py1 = new Y(X(1));\n    assert(py1.x.v == 1);\n    assert(*py1 == y);\n    auto py2 = new Y(y.x);\n    assert(py2.x.v == 2);\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12681\n\nstruct HasUnion12774\n{\n    union\n    {\n        int a, b;\n    }\n}\n\nbool test12681()\n{\n    immutable int x = 42;\n\n    static struct S1\n    {\n        immutable int *p;\n    }\n    immutable s1 = new S1(&x);\n    assert(s1.p == &x);\n\n    struct S2\n    {\n        immutable int *p;\n        void foo() {}\n    }\n    auto s2 = new S2(&x);\n    assert(s2.p == &x);\n\n    struct S3\n    {\n        immutable int *p;\n        int foo() { return x; }\n    }\n    auto s3 = new S3(&x);\n    assert(s3.p == &x);\n    assert(s3.foo() == 42);\n\n    auto x12774 = new HasUnion12774();\n\n    return true;\n}\nstatic assert(test12681());\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3991\n\nunion X3991\n{\n    int   a = void;\n    dchar b = void;\n}\n\nunion Y3991\n{\n    int   a = void;\n    dchar b = 'a';\n}\n\nunion Z3991\n{\n    int   a = 123;\n    dchar b = void;\n}\n\nvoid test3991()\n{\n    X3991 x;\n\n    Y3991 y;\n    assert(y.b == 'a');\n\n    Z3991 z;\n    assert(z.a == 123);\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7727\n\nunion U7727A1 { int i;       double d;       }\nunion U7727A2 { int i = 123; double d;       }\n//union U7727A3 { int i;       double d = 2.5; }\n\nunion U7727B1 { double d;       int i;       }\nunion U7727B2 { double d = 2.5; int i;       }\n//union U7727B3 { double d;       int i = 123; }\n\nvoid test7727()\n{\n    import core.stdc.math : isnan;\n\n    { U7727A1 u;                assert(u.i == 0); }\n    { U7727A1 u = { i: 1024 };  assert(u.i == 1024); }\n    { U7727A1 u = { d: 1.225 }; assert(u.d == 1.225); }\n  static assert(!__traits(compiles,\n    { U7727A1 u = { i: 1024, d: 1.225 }; }\n  ));\n\n    { U7727A2 u;                assert(u.i == 123); }\n    { U7727A2 u = { i: 1024 };  assert(u.i == 1024); }\n    { U7727A2 u = { d: 1.225 }; assert(u.d == 1.225); }\n  static assert(!__traits(compiles,\n    { U7727A2 u = { i: 1024, d: 1.225 }; }\n  ));\n\n// Blocked by https://issues.dlang.org/show_bug.cgi?id=1432\n//    { U7727A3 u;                assert(u.d == 2.5); }\n//    { U7727A3 u = { i: 1024 };  assert(u.i == 1024); }\n//    { U7727A3 u = { d: 1.225 }; assert(u.d == 1.225); }\n//  static assert(!__traits(compiles,\n//    { U7727A3 u = { i: 1024, d: 1.225 }; }\n//  ));\n\n    { U7727B1 u;                assert(isnan(u.d)); }\n    { U7727B1 u = { i: 1024 };  assert(u.i == 1024); }\n    { U7727B1 u = { d: 1.225 }; assert(u.d == 1.225); }\n  static assert(!__traits(compiles,\n    { U7727B1 u = { i: 1024, d: 1.225 }; }\n  ));\n\n    { U7727B2 u;                assert(u.d == 2.5); }\n    { U7727B2 u = { i: 1024 };  assert(u.i == 1024); }\n    { U7727B2 u = { d: 1.225 }; assert(u.d == 1.225); }\n  static assert(!__traits(compiles,\n    { U7727B2 u = { i: 1024, d: 1.225 }; }\n  ));\n\n// Blocked by https://issues.dlang.org/show_bug.cgi?id=1432\n//    { U7727B3 u;                assert(u.i == 123); }\n//    { U7727B3 u = { i: 1024 };  assert(u.i == 1024); }\n//    { U7727B3 u = { d: 1.225 }; assert(u.d == 1.225); }\n//  static assert(!__traits(compiles,\n//    { U7727B3 u = { i: 1024, d: 1.225 }; }\n//  ));\n\n\n    test7727a();\n    test7727b();\n}\n\n// --------\n\nstruct Foo7727a\n{\n    ushort bar2;\n}\nstruct Foo7727b\n{\n    union\n    {\n        ubyte[2] bar1;\n        ushort bar2;\n    }\n}\n\nvoid test7727a()\n{\n    immutable Foo7727a foo1 = { bar2: 100 }; // OK\n    immutable Foo7727b foo2 = { bar2: 100 }; // OK <-- error\n}\n\n// --------\n\nstruct S7727 { int i; double d; }\nunion U7727 { int i; double d; }\n\nvoid test7727b()\n{\n    S7727 s = { d: 5 }; // OK\n    U7727 u = { d: 5 }; // OK <-- Error: is not a static and cannot have static initializer\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7929\n\nvoid test7929()\n{\n    static struct S\n    {\n        int [] numbers;\n    }\n\n    const int [] numbers = new int[2];\n    const S si = {numbers};\n    // Error: cannot implicitly convert expression (numbers) of type const(int[]) to int[]\n\n    const S se = const(S)(numbers);\n    // OK\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7021\n\nstruct S7021\n{\n    @disable this();\n}\n\nvoid test7021()\n{\n  static assert(!is(typeof({\n    auto s = S7021();\n  })));\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8738\n\nvoid test8738()\n{\n    int[3] a = [1, 2, 3];\n\n    struct S { int a, b, c; }\n    S s = S(1, 2, 3);\n\n    a = [4, a[0], 6];\n    s = S(4, s.a, 6);\n\n    assert(a == [4, 1, 6]);\n    assert(s == S(4, 1, 6));\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8763\n\nvoid test8763()\n{\n    struct S\n    {\n        this(int) {}\n    }\n\n    void foo(T, Args...)(Args args)\n    {\n        T t = T(args);\n        // Error: constructor main.S.this (int) is not callable using argument types ()\n    }\n\n    S t = S(); // OK, initialize to S.init\n    foo!S();\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8902\n\nunion U8902 { int a, b; }\n\nenum U8902 u8902a = U8902.init; // No errors\nU8902 u8902b;                   // No errors\nU8902 u8902c = U8902.init;      // Error: duplicate union initialization for b\n\nvoid test8902()\n{\n    U8902 u8902d = U8902.init;                  // No errors\n    immutable U8902 u8902e = U8902.init;        // No errors\n    immutable static U8902 u8902f = U8902.init; // Error: duplicate union...\n    static U8902 u8902g = u8902e;               // Error: duplicate union...\n    static U8902 u8902h = U8902.init;           // Error: duplicate union...\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9116\n\nvoid test9116()\n{\n    static struct X\n    {\n        int v;\n        this(this) { ++v; }\n    }\n    static struct Y\n    {\n        X x;\n    }\n    X x = X(1);\n    assert(x.v == 1);\n    Y y = Y(X(1));\n    //printf(\"y.x.v = %d\\n\", y.x.v);  // print 2, but should 1\n    assert(y.x.v == 1); // fails\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9293\n\nvoid test9293()\n{\n    static struct A\n    {\n    //  enum A zero = A(); // This works as expected\n        enum A zero = {};  // Note the difference here\n\n        int opCmp(const ref A a) const\n        {\n            assert(0);\n        }\n\n        int opCmp(const A a) const\n        {\n            return 0;\n        }\n    }\n\n    A a;\n    auto b = a >= A.zero;  // Error: A() is not an lvalue\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9566\n\nvoid test9566()\n{\n    static struct ExpandData\n    {\n        ubyte[4096] window = 0;\n    }\n    ExpandData a;\n    auto b = ExpandData.init;   // bug\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9775\n\nenum Month9775 : ubyte { jan = 1, }\nstruct Date9775\n{\n    this(int year, int month, int day) pure\n    {\n        _year  = cast(short)year;\n        _month = cast(Month9775)month;\n        _day   = cast(ubyte)day;\n    }\n    short     _year  = 1;\n    Month9775 _month = Month9775.jan;\n    ubyte     _day   = 1;\n}\n\nconst Date9775 date9775c1 = Date9775(2012, 12, 21);\nconst          date9775c2 = Date9775(2012, 12, 21);\nenum  Date9775 date9775e1 = Date9775(2012, 12, 21);\nenum           date9775e2 = Date9775(2012, 12, 21);\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11105\n\nstruct S11105\n{\n    int[2][1] a21;\n}\n\nvoid test11105()\n{\n    S11105 s = S11105([1, 2]);\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11147\n\nstruct V11147\n{\n    union\n    {\n        struct\n        {\n            float x = 0;\n            float y = 0;\n            float z = 0;\n        }\n        struct\n        {\n            float r;\n            float g;\n            float b;\n        }\n    }\n}\n\nvoid test11147()\n{\n    auto v = V11147.init;\n    assert(v.x == 0f);\n    assert(v.y == 0f);\n    assert(v.z == 0f);\n    assert(v.r == 0f);\n    assert(v.g == 0f);\n    assert(v.b == 0f);\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11256\n\nstruct S11256 { @disable this(); }\n\nstruct Z11256a(Ranges...)\n{\n    Ranges ranges;\n    this(Ranges rs) { ranges = rs; }\n}\nstruct Z11256b(Ranges...)\n{\n    Ranges ranges = Ranges.init;    // Internal error: e2ir.c 5321\n    this(Ranges rs) { ranges = rs; }\n}\nstruct Z11256c(Ranges...)\n{\n    Ranges ranges = void;           // todt.c(475) v->type->ty == Tsarray && vsz == 0\n    this(Ranges rs) { ranges = rs; }\n}\n\nstruct F11256(alias pred)\n{\n    this(int[] = null) { }\n}\n\nZ!Ranges z11256(alias Z, Ranges...)(Ranges ranges)\n{\n    return Z!Ranges(ranges);\n}\n\nvoid test11256()\n{\n    z11256!Z11256a(S11256.init, F11256!(gv => true)());\n    z11256!Z11256b(S11256.init, F11256!(gv => true)());\n    z11256!Z11256c(S11256.init, F11256!(gv => true)());\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11269\n\nstruct Atom\n{\n    union\n    {\n        int i;\n        struct\n        {\n            ulong first, rest;\n        }\n        struct\n        {\n            uint a, b;\n        }\n    }\n}\n\nvoid test11269()\n{\n    Atom a1;\n    Atom a2 = {i:1, rest:10, b:2};\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11427\n\nstruct S11427\n{\n    union\n    {\n        ubyte a;\n        int x;\n    }\n    void[] arr;\n}\n\nint foo11427() @safe\n{\n    S11427 s1 = S11427();\n    S11427 s2;\n    return 0;\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12011\n\nstruct S12011a\n{\n    int f() { return i; }\n    enum e = this.init.f();\n    int i = 1, j = 2;\n}\n\nstruct S12011b\n{\n    int f() { return i; }\n    enum e = S12011b().f();\n    int i = 1, j = 2;\n}\n\nvoid test12011()\n{\n    static assert(S12011a.e == 1);\n    static assert(S12011b.e == 1);\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13021\n\nvoid test13021()\n{\n    static union U1\n    {\n        float a;\n        int b;\n    }\n\n    static union U2\n    {\n        double a;\n        long b;\n    }\n\n    static union U3\n    {\n        real a;\n        struct B { long b1, b2; } // ICE happens only if B.sizeof == real.sizeof\n        B b;\n    }\n\n    static union U4\n    {\n        real a;\n        long[2] b; // ditto\n    }\n\n    auto f = U1(1.0);  auto ok = f.b;\n\n    auto fail1 = U1(1.0).b; // OK <- Internal error: e2ir.c 1162\n    auto fail2 = U2(1.0).b; // OK <- Internal error: e2ir.c 1162\n    auto fail3 = U3(1.0).b; // OK <- Internal error: e2ir.c 1162\n    auto fail4 = U4(1.0).b; // OK <- Internal error: backend/el.c 2904\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14556\n\nenum E14556 { a = 1 }\n\nstruct S14556a\n{\n    this(int) {}\n    E14556[1] data;\n}\n\nstruct S14556b\n{\n    this(int) {}\n    void[1] data;\n}\n\nvoid test14556()\n{\n    auto sa = S14556a(0);\n    assert(sa.data == [E14556.a]);\n\n    auto sb = S14556b(0);\n    assert(sb.data[] == cast(ubyte[1])[0]);\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17622\n\nstruct S17622\n{\n    int i;\n\n    this(ubyte)\n    {\n        return;\n    }\n\n    void fun()\n    {\n        assert(i == 0);\n    }\n}\n\nS17622 make()\n{\n    return S17622(0);\n}\n\nvoid test17622()\n{\n    S17622 s = make();\n\n    auto rdg = (){ s.fun(); };\n\n    s.fun();\n}\n\n/********************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15a();\n    test15b();\n    test15c();\n    test15d();\n    test15e();\n    test9993a();\n    test9993b();\n    test3198and1914();\n    test2427();\n    test5885();\n    test5889();\n    test4247();\n    test6937();\n    test12681();\n    test3991();\n    test7727();\n    test7929();\n    test7021();\n    test8738();\n    test8763();\n    test8902();\n    test9116();\n    test9293();\n    test9566();\n    test11105();\n    test11147();\n    test11256();\n    test13021();\n    test14556();\n    test17622();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/template1.d",
    "content": "// REQUIRED_ARGS:\n\nmodule template1;\n\nimport core.stdc.stdio : printf;\nimport core.vararg;\n\n/******************************************/\n\ntemplate TFoo1(T,U)\n{\n    int foo(T t, U u)\n    {\n        return 3;\n    }\n}\n\n\nalias TFoo1!(int, char) Foo1;\n\n\nvoid test1()\n{\n    int i = Foo1.foo(1, 2);\n    assert(i == 3);\n}\n\n/******************************************/\n\ntemplate TFoo2(T,U)\n{\n    T x = 4;\n    U y;\n}\n\n\nalias TFoo2!(int, char) Foo2;\n\n\nvoid test2()\n{\n    assert(Foo2.x + Foo2.y == 0x103);\n    Foo2.x = 3;\n    Foo2.y = 7;\n    assert(Foo2.x + Foo2.y == 10);\n}\n\n/******************************************/\n\ntemplate TFoo3(T,U)\n{\n    class Bar\n    {\n        T x = 4;\n        U y;\n    }\n}\n\n\nalias TFoo3!(int, char) Foo3;\n\n\nvoid test3()\n{\n    Foo3.Bar b = new Foo3.Bar();\n\n    assert(b.x == 4);\n    assert(b.y == 0xFF);\n}\n\n/******************************************/\n\ntemplate TFoo4(T,U)\n{\n    T x;\n    U y;\n}\n\ntemplate TFoo4(T:T,U:T)\n{\n    T a;\n    U b;\n}\n\ntemplate TFoo4(T:uint, U:uint)\n{\n    T c;\n    U d;\n}\n\nalias TFoo4!(int, char) Foo4x;\n\nvoid test4()\n{\n    alias TFoo4!(int, char) Foo4;\n    int* x = &Foo4.c;\n    char* y = &Foo4.d;\n\n    alias TFoo4!(uint, char**) Foo4_2;\n    uint* x2 = &Foo4_2.x;\n    char*** y2 = &Foo4_2.y;\n\n    alias TFoo4!(int, int) Foo4_3;\n    int* x3 = &Foo4_3.a;\n    int* y3 = &Foo4_3.b;\n\n    alias TFoo4!(uint, uint) Foo4_4;\n    uint* x4 = &Foo4_4.c;\n    uint* y4 = &Foo4_4.d;\n}\n\n\n/******************************************/\n\ntemplate TtoUx(T, U)\n{\n    T toUx(U[] s)\n    {\n        uint v = 0;\n\n        if (v != cast(T)v)\n            return 3;\n\n        return cast(T)v;\n    }\n\n}\n\nalias TtoUx!(ubyte, char).toUx toUbyte;\nalias TtoUx!(ushort, char).toUx toUshort;\n\nvoid test5()\n{\n}\n\n\n/******************************************/\n\ntemplate TtoUx6(T, U)\n{\n    T toUx(U[] s)\n    {\n        uint v = 0;\n\n        if (v != cast(T)v)\n            return 3;\n\n        return cast(T)v;\n    }\n\n}\n\nalias TtoUx6!(ubyte, char) t6;\n\nvoid test6()\n{\n}\n\n/******************************************/\n\ntemplate A7(T) {\n    T id(T t) {\n        return t;\n    }\n}\n\nalias A7!(int) a;\n\nvoid test7()\n{\n    printf(\"%d\\r\\n\", a.id(3));\n    assert(a.id(3) == 3);\n}\n\n/******************************************/\n\ntemplate Swapper(T)\n{\n    void Swap(ref T a, ref T b)\n    {\n        T temp = a; a = b; b = temp;\n    }\n}\n\nvoid test8()\n{\n    alias Swapper!(int) IntSwap;\n    int a=1,b=2;\n    IntSwap.Swap(a,b);\n    printf(\"a=%d,b=%d\\n\",a,b); // prints 2,1\n    assert(a == 2);\n    assert(b == 1);\n}\n\n\n/******************************************/\n\ntemplate Foo9(T)\n{\n    class B\n    {\n        T data;\n    }\n}\n\nvoid test9()\n{\n    (new Foo9!(int).B).data += 4;\n}\n\n\n/******************************************/\n\ntemplate A10(T) {\n}\n\ntemplate B10(T) {\n    alias A10!(int) a;\n}\n\nvoid test10()\n{\n    alias B10!(int) b;\n}\n\n/******************************************/\n\ntemplate A11(T) {\n    T idf(T t) {\n        return t;\n    }\n}\n\ntemplate B11(T) {\n    private alias A11!(T) a;\n    T same(T t) {\n        return a.idf(t);\n    }\n}\n\nvoid test11()\n{\n    alias B11!(int) b;\n    //printf(\"%d\\r\\n\", b.same(10));\n    assert(b.same(10) == 10);\n}\n\n\n/******************************************/\n\ntemplate A12(T) {\n    class B {\n        invariant() {\n            assert(1);\n        }\n    T ide(T t) {\n        return t;\n    }\n    }\n}\n\nvoid test12()\n{\n    alias A12!(int) a;\n    a.B b = new a.B();\n    printf(\"%d\\r\\n\", b.ide(10));\n    assert(b.ide(10) == 10);\n}\n\n\n/******************************************/\n\ntemplate A13(T) {\n    public interface I {\n        public T i();\n    }\n}\n\nclass B13 : A13!(int).I {\n    public int i() {\n        return 42;\n    }\n}\n\nvoid test13()\n{\n    B13 b = new B13();\n    A13!(int).I i = b;\n    assert(b.i() == 42);\n    assert(i.i() == 42);\n}\n\n\n/******************************************/\n\nclass B14\n{\n}\n\ntemplate A14(T, U) {\n\n    private U u;\n\n    static this()\n    {\n        u = new U();\n    }\n}\n\nalias A14!(int, B14) t14;\n\nvoid test14()\n{\n}\n\n\n/******************************************/\n\ntemplate A15(T) {\n    public interface Init {\n        public T init();\n    }\n}\ntemplate A15(T : int) {\n    public class Init {\n        public T init() {\n            return 42;\n        };\n    }\n}\ntemplate A15(T : float) {\n    public class Init {\n        public T init() {\n            return 3.25;\n        };\n    }\n}\n\ntemplate TB15(T, U) {\n    private U initializer;\n    private void setInitializer(U init) {\n        initializer = init;\n    }\n    public class B {\n        private T _value;\n        public this() {\n            this._value = initializer.init();\n        }\n        public T value() {\n            return this._value;\n        }\n    }\n}\ntemplate TB15(T) {\n    private alias TB15!(T, A15!(T).Init) tb;\n    private void setInitializer(A15!(T).Init init) {\n        tb.setInitializer(init);\n    }\n    public class B : tb.B {\n    }\n}\n\nvoid test15()\n{\n    alias TB15!(int, A15!(int).Init) tb;\n    tb.setInitializer(new A15!(int).Init());\n    tb.B b = new tb.B();\n    int i;\n    i = b.value();\n    assert(i == 42);\n\n    alias TB15!(float) tb2;\n    tb2.setInitializer(new A15!(float).Init());\n    tb2.B b2 = new tb2.B();\n    assert(b2.value() == 3.25);\n}\n\n/******************************************/\n\ntemplate foo16(U : int, int T : 9+1)\n{\n    U x = T;\n}\n\nalias foo16!(int, 10) bar16;\n\nvoid test16()\n{\n    int i;\n\n    i = bar16.x;\n    assert(i == 10);\n    assert(foo16!(int, 10).x == 10);\n}\n\n/******************************************/\n\ntemplate VecTemplate(tfloat)\n{\n    struct Vector\n    {\n        tfloat d;\n    }\n}\n\nvoid test17()\n{\n    with (VecTemplate!(int)) // crash DMD\n    {\n    }\n}\n\n/******************************************/\n\ntemplate Bomb (T)\n{\n   void foo (T *parm)\n   {\n   }\n}\n\ntemplate Name (T)\n{\n   T y;\n\n   void test ()\n   {\n      Bomb!(T).foo (&y);\n   }\n}\n\nalias Name!(int) a18;\nalias Name!(ubyte) b18;\n\nvoid test18()\n{\n}\n\n/******************************************/\n\ntemplate one20( T )\n{\n  alias T function () safeptr;\n}\n\ntemplate one20( T1, T2 )\n{\n  alias int function(int) safeptr;\n}\n\nalias one20!( int ) A;\nA.safeptr foo20;\n\nalias one20!( int, int ) B;\nB.safeptr bar20;\n\n\nint func_bar(int i) { return 2; }\n\nvoid test20()\n{\n    bar20 = &func_bar;\n}\n\n/******************************************/\n\nclass A21 { int x; }\nclass B21 : A21 { int y; }\n\nvoid abc21(B21* b) { }\n\ntemplate TFoo21(T : A21, U : T*)\n{\n    void test()\n    {\n        assert(T.sizeof == B21.sizeof);\n        U u;\n        abc21(u);\n    }\n}\n\nalias TFoo21!(B21, B21*) bar21;\n\nvoid test21()\n{\n    bar21.test();\n}\n\n/******************************************/\n\ntemplate Bug22(T : Object) {\n    int print() {\n        printf(\"Bug22(T : Object).print()\\r\\n\");\n        return 1;\n    }\n}\ntemplate Bug22(T) {\n    int print() {\n        printf(\"Bug22(T).print()\\r\\n\");\n        return 2;\n    }\n}\ntemplate TTest22(T) {\n    private alias Bug22!(T) bug;\n    class Test {\n        int test() {\n            return bug.print();\n        }\n    }\n}\n\nvoid test22()\n{\n    alias TTest22!(int).Test Test1;\n    alias TTest22!(Test1).Test Test2;\n    alias TTest22!(Object).Test Test3;\n    Test1 test1 = new Test1();\n    Test2 test2 = new Test2();\n    Test3 test3 = new Test3();\n    int i;\n\n    i = test1.test();\n    assert(i == 2);\n    i = test2.test();\n    assert(i == 1);\n    i = test3.test();\n    assert(i == 1);\n}\n\n\n/******************************************/\n\ntemplate T23()\n{\n     struct Rank\n     {\n     }\n}\n\ntemplate A23()\n{\n    struct Array\n    {\n        alias T23!().Rank Rank1;\n\n        Rank1 data;\n    }\n}\n\nalias A23!().Array Array_int23;\n\nvoid test23()\n{\n}\n\n\n/******************************************/\n\ntemplate TList24(T)\n{\n    class Node\n    {\n    }\n    class List\n    {\n        Node m_first = null;\n    }\n}\n\nvoid test24()\n{\n  alias TList24!(uint).List UIntList;\n}\n\n\n/******************************************/\n\ntemplate TList25(T)\n{\n    class Node\n    {\n        Node prev;\n        Node next;\n        T Value;\n    }\n    class List\n    {\n        Node m_first = null;\n        Node m_last = null;\n        void AddFront(T _Value)\n        {\n            Node cur = new Node;\n            with (cur)\n            {\n                next = m_first;\n                prev = null;\n                Value = _Value;\n                if (next !is null)\n                    next.prev = cur;\n            }\n            m_first = null;\n            if (m_last is null)\n                m_last = cur;\n        }\n    }\n}\n\nvoid test25()\n{\n  alias TList25!(uint).List UIntList;\n  alias TList25!(uint).Node UIntNode;\n  UIntList list;\n  UIntNode node;\n  for (int i = 1; i <= 10; i++)\n        {} //list.AddFront(i);\n}\n\n\n/******************************************/\n\ntemplate Foo26(T)\n{\n    void doIt() {\n        printf(\"Foo26(T)\\r\\n\");\n    }\n}\n\ntemplate Foo26(T : T[])\n{\n    private alias Foo26!(T) bug;\n    void doIt() {\n        printf(\"Foo26(T[])\\r\\n\");\n        bug.doIt();\n    }\n}\n\nvoid test26()\n{\n    alias Foo26!(int[]) foo;\n    foo.doIt();\n}\n\n\n/******************************************/\n\ntemplate Foo27(T)\n{\n    public const T[] empty = [];\n}\n\nvoid test27()\n{\n    alias Foo27!(int) bug;\n}\n\n\n/******************************************/\n\ntemplate A28(T) {\n    public bool all(in T[] array, bool function (T) predicate) {\n        for (int i = 0; i < array.length; i++) {\n            if (!predicate(array[i])) {\n                return false;\n            }\n        }\n        return true;\n    }\n}\n\nvoid test28()\n{\n    static bool isVowel(char c) {\n        return (c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u');\n    }\n\n    alias A28!(char) arrays;\n    assert(arrays.all(\"aeiouoeieuiei\", &isVowel));\n    assert(arrays.all(\"aeoiuaioeuioaeuiouoiaeu\", &isVowel));\n    assert(!arrays.all(\"aaeiouioeujiurioue\", &isVowel));\n    assert(!arrays.all(\"bjkqwkjbwqjbkwb\", &isVowel));\n    assert(arrays.all(\"\", &isVowel));\n    printf(\"A28(char).all tests passed!\\r\\n\");\n}\n\n\n/******************************************/\n\npublic template TRange29(T) {\n    debug private bool recursing = false;\n    public class Range {\n        private T _lower;\n        private T _upper;\n        public this(T lower, T upper) {\n            this._lower = lower;\n            this._upper = upper;\n        }\n        public T lower() {\n            return this._lower;\n        }\n        public T upper() {\n            return this._upper;\n        }\n        public bool contains(T item) {\n            return (lower() <= item) && (item <= upper());\n        }\n        public bool intersects(Range other)\n        in {\n            assert(other !is null);\n        } out (result) {\n            debug {\n                if (!recursing) {\n                    recursing = true;\n                    assert(result == other.intersects(this));\n                } else {\n                    recursing = false;\n                }\n            }\n        } body {\n            return contains(other.lower()) || contains(other.upper()) || other.includes(this);\n        }\n        public bool includes(Range other)\n        in {\n            assert(other !is null);\n        } out (result) {\n            assert(result == (contains(other.lower()) && contains(other.upper())));\n        } body {\n            return contains(other.lower()) && contains(other.upper());\n        }\n    }\n}\n\nvoid test29()\n{\n    alias TRange29!(int).Range Range;\n    Range r1 = new Range(1, 10);\n    Range r2 = new Range(5, 15);\n    assert(r1.intersects(r2) == 1);\n}\n\n\n/******************************************/\n\ntemplate TCopy30(T)\n{\n    void copy(out T to, T from)\n    {\n        to = from;\n    }\n}\n\ntemplate TCopy30(T : string)\n{\n    void copy(out string to, in string from)\n    {\n        printf(\"Specialization\\n\");\n        to = from;\n    }\n}\n\nvoid test30()\n{\n    int i = 0;\n    float f = 0;\n    string s;\n\n    alias TCopy30!(int) copyint;\n    alias TCopy30!(string) copystr;\n\n    copyint.copy(i, 3);\n    printf(\"%d\\n\", i);\n    assert(i == 3);\n\n    copystr.copy(s, \"Here it comes\");\n    printf(\"%.*s\\n\", s.length, s.ptr);\n    assert(s == \"Here it comes\");\n}\n\n/******************************************/\n\nimport std.string;\n\ntemplate Foo31(alias X)\n{\n        alias X.toStringz y;\n}\n\nvoid test31()\n{\n    alias Foo31!(std.string) bar;\n}\n\n\n/******************************************/\n\nshared int x32;\n\ntemplate Foo32(alias X)\n{\n    static shared int* p = &X;\n}\n\nalias Foo32!(x32) abc32;\n\nvoid test32()\n{\n    alias Foo32!(x32) bar;\n\n    *bar.p = 3;\n    assert(x32 == 3);\n\n    *abc32.p = 4;\n    assert(x32 == 4);\n}\n\n/******************************************/\n\nshared int x33;\n\ntemplate Foo33(alias X)\n{\n    static shared int* p = &X;\n}\n\ntemplate Bar33(alias T)\n{\n    alias T!(x33) abc;\n}\n\nvoid test33()\n{\n    alias Bar33!(Foo33) bar;\n\n    *bar.abc.p = 3;\n    assert(x33 == 3);\n}\n\n/******************************************/\n\nshared int x34;\n\ntemplate Foo34(alias X)\n{\n    static shared int* p = &X;\n}\n\ntemplate Bar34(alias T)\n{\n    alias T.p q;\n}\n\nvoid test34()\n{\n    alias Foo34!(x34) foo;\n    alias Bar34!(foo) bar;\n\n    *bar.q = 3;\n    assert(x34 == 3);\n}\n\n/******************************************/\n\nclass Foo35\n{\n    static int p;\n}\n\ntemplate Bar35(alias T)\n{\n    alias T.p q;\n}\n\nvoid test35()\n{\n    alias Bar35!(Foo35) bar;\n\n    bar.q = 3;\n    assert(Foo35.p == 3);\n}\n\n/******************************************/\n\ntemplate Bar36(T)\n{\n    class Bar36\n    {\n        static T x;\n    };\n}\n\nvoid test36()\n{\n    Bar36!(int).x = 3;\n}\n\n/******************************************/\n\nclass Bar37(T)\n{\n    static T x;\n}\n\n\nvoid test37()\n{\n    Bar37!(int).x = 3;\n}\n\n/******************************************/\n\nclass Bar38(T)\n{\n    static T x = 3;\n}\n\n\nvoid test38()\n{\n    int i = template1.Bar38!(int).x;\n    assert(i == 3);\n\n    int j = Bar38!(int).x;\n    assert(j == 3);\n}\n\n/******************************************/\n\nclass Bar39(T)\n{\n    alias T x;\n}\n\n\nvoid test39()\n{\n    Bar39!(int).x y = 3;\n    assert(y == 3);\n}\n\n\n/******************************************/\n\ntemplate Bar40(T)\n{\n    alias T Bar40;\n}\n\n\nvoid test40()\n{\n    Bar40!(int) y = 3;\n    assert(y == 3);\n}\n\n/******************************************/\n\ntemplate Bar41(T)\n{\n    alias T Bar41;\n}\n\n\nvoid test41()\n{\n    template1.Bar41!(int) y = 3;\n    assert(y == 3);\n\n    assert(template1.Bar41!(int).sizeof == int.sizeof);\n}\n\n/******************************************/\n\ntemplate Bar42(T) { T t; }\n\ntypeof(Bar42!(int).t) bar42;\n\nvoid test42()\n{\n    bar42 = 5;\n}\n\n/******************************************/\n\ntemplate factor43(int n : 1)\n{\n  enum { value = 1 }\n}\n\ntemplate factor43(int n)\n{\n  enum { value = n*factor43!(n-1).value }\n}\n\nvoid test43()\n{\n\n  int i = factor43!(3).value;\n\n  printf(\"%d\\n\",i);\n  assert(i == 6);\n}\n\n\n/******************************************/\n\ntemplate factorial1(int n : 1)\n{\n    const int x = 1;\n}\n\ntemplate factorial1(int n)\n{\n    const int x = n*.factorial1!(n-1).x;\n}\n\ntemplate factorial2(int n : 1)\n{\n    const int factorial2 = 1;\n}\n\ntemplate factorial2(int n)\n{\n    const int factorial2 = n*.factorial2!(n-1);\n}\n\ntemplate factorial3(int n : 1)\n{\n    enum { x = 1 }\n}\n\ntemplate factorial3(int n)\n{\n    enum { x = n*.factorial3!(n-1).x }\n}\n\ntemplate factorial4(int n : 1)\n{\n    enum { factorial4 = 1 }\n}\n\ntemplate factorial4(int n)\n{\n    enum { factorial4 = n*.factorial4!(n-1) }\n}\n\nvoid test44()\n{\n\n  int i = factorial1!(4).x;\n  printf(\"%d\\n\",i);\n  assert(i == 24);\n\n  i = factorial2!(4);\n  printf(\"%d\\n\",i);\n  assert(i == 24);\n\n  i = factorial3!(4).x;\n  printf(\"%d\\n\",i);\n  assert(i == 24);\n\n  i = factorial4!(4);\n  printf(\"%d\\n\",i);\n  assert(i == 24);\n}\n\n\n/******************************************/\n\ntemplate factor45(int n)\n{\n    int value()\n    {\n        if (n==0 || n==1)\n            return 1;\n        return n * factor45!(n-1).value();\n    }\n}\n\ntemplate factor45(int n : 0)\n{\n    int value()\n    {\n        return 1;\n    }\n}\n\ntemplate factor45(int n : 1)\n{\n    int value()\n    {\n        return 1;\n    }\n}\n\nvoid test45()\n{\n    int i;\n\n    i = factor45!(4).value();\n    printf( \"%d\\n\", i);\n    assert(i == 24);\n}\n\n\n/******************************************/\n\ntemplate sqrt46(int n, int lo, int hi : lo)\n{\n    enum { result = lo }\n}\n\nvoid test46()\n{\n    int i;\n\n    i = sqrt46!(1, 24, 24).result;\n    printf(\"i = %d\\n\", i);\n    assert(i == 24);\n}\n\n/******************************************/\n\ntemplate sqrt47(int n, int lo, int hi)\n{\n    enum { mid = (lo + hi + 1) / 2 }\n\n    enum { result = (n < mid * mid) ? sqrt47!(n, lo, mid - 1).result\n                                    : sqrt47!(n, mid, hi).result }\n}\n\ntemplate sqrt47(int n, int lo, int hi : lo)\n{\n    enum { result = lo }\n}\n\ntemplate sqrt47(int n)\n{\n    enum { sqrt47 = .sqrt47!(n, 1, n).result }\n}\n\nvoid test47()\n{\n    int i;\n\n    i = sqrt47!(24);\n    printf(\"i = %d\\n\", i);\n}\n\n/******************************************/\n\nclass Foo48 (T)\n{\n    alias T Type;\n\n    class Inner (U)\n    {\n        alias U Type;\n    };\n};\n\nstruct Bar48 (alias TT)\n{\n    alias TT!(int).Type A;\n    alias TT!(int).Inner!(A).Type B;\n};\n\nvoid test48()\n{\n    Bar48!(Foo48).A x;\n    Bar48!(Foo48).B y;\n\n    int *p;\n\n    p = &x;\n    p = &y;\n}\n\n\n/******************************************/\n\nstruct Foo49(T)\n{\n    static Foo49 bar(T c1)\n    {\n        Foo49 rtn; // Error here\n        return rtn;\n    }\n}\n\nvoid test49()\n{\n    alias Foo49!(double) vector;\n\n    vector.bar(1);\n}\n\n/******************************************/\n\nstruct Foo50(T)\n{\n  T x = 0;\n\n  static Foo50 bar(T c1)\n  {\n    .Foo50!(typeof(c1)) rtn;\n    rtn.x = c1;\n    return rtn;\n  }\n\n  static .Foo50!(T) barx(T c1)\n  {\n    Foo50 rtn;\n    rtn.x = c1;\n    return rtn;\n  }\n}\n\nvoid test50()\n{\n  alias Foo50!(double) vector;\n\n  vector xAxis = vector.bar(1);\n}\n\n/******************************************/\n\nstruct Foo51(T)\n{\n  T x = 0;\n  .Foo51!(long)* p;\n\n  static Foo51 bar(T c1)\n  {\n    .Foo51!(typeof(c1)) rtn;\n    rtn.x = c1;\n    return rtn;\n  }\n\n  static .Foo51!(T) barx(T c1)\n  {\n    Foo51 rtn;\n    .Foo51!(int)* c;\n    rtn.x = c1;\n    return rtn;\n  }\n}\n\nvoid test51()\n{\n  alias Foo51!(double) vector;\n\n  vector xAxis = vector.bar(1);\n}\n\n\n/******************************************/\n\ninterface Interface(T)\n{\n    void foo52();\n}\n\nvoid bar52(Interface!(Object) i)\n{\n    i.foo52();\n}\n\nclass Abstract(T) : Interface!(T)\n{\n    abstract void foo52();\n}\n\nclass Concrete(T) : Abstract!(T)\n{\n    override void foo52() { printf(\"Concrete.foo52(this = %p)\\n\", this); }\n}\n\nclass Sub(T) : Concrete!(T)\n{\n}\n\nvoid test52()\n{\n    Sub!(Object) s = new Sub!(Object)();\n    s.foo52();\n    bar52(s);\n}\n\n\n/******************************************/\n\nclass Foo53\n{\n    template tmethod (T)\n    {\n        public static void tmethod (T param)\n        {\n            printf(\"param = %d\\n\", param);\n            assert(param == 42);\n        }\n    }\n}\n\n\nvoid test53()\n{\n    Foo53 foo = new Foo53;\n\n    Foo53.tmethod!(int)(42);\n}\n\n\n/******************************************/\n\nclass Foo54\n{\n   template func(W) {\n     static void foo(W w) { printf(\"W_I %d\\n\", w); assert(w == 3); }\n     static int xx;\n   }\n}\n\nvoid test54() {\n\n   Foo54 c = new Foo54();\n   c.func!(int).foo(3);\n   c.func!(int).xx = 4;\n\n}\n\n/******************************************/\n\ntemplate T55(S)\n{\n    struct Foo55\n    {\n        static Foo55 test(Foo55 f)\n        {\n            Foo55 a = f;\n            return f;\n        }\n    }\n}\n\nalias T55!(char).Foo55 Foo55;\nalias T55!(char).Foo55 Bar55;\n\n\nvoid test55()\n{\n    Bar55 a;\n    Foo55 b;\n    b.test(a);\n    Bar55.test(a);\n}\n\n/******************************************/\n\ntemplate CT56(T)\n{\n  class C\n  {\n    const char[][1] arrArr=[\"foo\" ];\n  }\n}\n\nvoid test56()\n{\n  alias CT56!(int) Ct;\n  Ct.C c= new Ct.C();\n  printf(\"%.*s\\n\", c.arrArr[0].length, c.arrArr[0].ptr);\n  assert(c.arrArr[0] == \"foo\");\n}\n\n\n/******************************************/\n\ntemplate foo57(T : int = int)\n{\n    T x = 3;\n}\n\nvoid test57()\n{\n    printf(\"%d\\n\", foo57!().x);\n    assert(foo57!().x == 3);\n}\n\n/******************************************/\n\ntemplate Foo58(T, U = T)\n{\n    U x = 3;\n}\n\nvoid test58()\n{\n    alias Foo58!(int) f;\n    assert(f.x == 3);\n    assert(f.x.sizeof == 4);\n}\n\n/******************************************/\n\ntemplate Foo59(T, U = T*)\n{\n    shared T x = 3;\n    shared U px = &x;\n}\n\nvoid test59()\n{\n    alias Foo59!(uint) f;\n    assert(f.x == 3);\n    assert(f.x.sizeof == 4);\n    assert(*f.px == 3);\n\n    alias Foo59!(long) g;\n    assert(g.x == 3);\n    assert(g.x.sizeof == 8);\n    assert(*g.px == 3);\n}\n\n/******************************************/\n\nclass A60\n{}\n\ntemplate B60(T, U = short)\n{\n        struct Thing\n        {\n                T       t;\n                U       u;\n        };\n}\n\ntemplate C60(T, U = A60)\n{\n        class C60\n                : U\n        {}\n\n        class C2\n        {};\n}\n\nvoid test60()\n{\n        B60!(int, long).Thing   thing1;\n        B60!(int).Thing         thing2;\n\n        printf(\"thing1.sizeof: %u\\n\", thing1.sizeof);\n        printf(\"thing2.sizeof: %u\\n\", thing2.sizeof);\n\n        assert(thing1.sizeof == long.alignof + long.sizeof);\n        assert(thing2.sizeof == 8);\n\n        C60!(int /*,A60*/ )     container1;\n\n        printf(\"container1.sizeof: %u\\n\", container1.sizeof);\n        assert(container1.sizeof == (void*).sizeof);\n}\n\n/******************************************/\n\nstruct Foo61\n{\n    int a;\n\n    template Bar(T)\n    {\n        T abc() { return a; }\n    }\n\n    int def() { return 4; }\n}\n\nvoid test61()\n{\n    Foo61 *f = new Foo61();\n    int i;\n\n    f.a = 3;\n    i = f.def();\n    assert(i == 4);\n    i = f.Bar!(int).abc();\n    assert(i == 3);\n\n    Foo61 g;\n    g.a = 3;\n    i = g.def();\n    assert(i == 4);\n    i = g.Bar!(int).abc();\n    assert(i == 3);\n}\n\n/******************************************/\n\nclass Foo62(T)\n{\n    template Bar(T)\n    {\n        int func() { return 3; }\n    }\n}\n\nvoid test62()\n{\n    Foo62!(int) x = new Foo62!(int);\n\n    assert(x.Bar!(int).func() == 3);\n}\n\n/******************************************/\n\nclass Foo63(T)\n{\n    template Bar(T)\n    {\n        int func() { this.def(); return 3; }\n        int func2() { return 4; }\n    }\n\n    void def()\n    {\n        assert(Bar!(T).func2() == 4);\n    }\n}\n\nvoid test63()\n{\n    Foo63!(int) x = new Foo63!(int);\n\n    assert(x.Bar!(int).func() == 3);\n    x.def();\n}\n\n/******************************************/\n\nstruct XVector(qfloat)\n{\n    qfloat x;qfloat y;qfloat z;\n\n    static int opCall (qfloat x, qfloat y, qfloat z) { return 8; }\n}\n\nvoid test64()\n{\n    int i;\n    i = XVector!(int)(1,2,3);\n    assert(i == 8);\n    i = XVector!(real).opCall(1,2,3);\n    assert(i == 8);\n}\n\n/******************************************/\n// http://www.digitalmars.com/d/archives/28052.html\n\nalias int value_type;\n\nstruct Foo65\n{\n    uint length() { return 47; }\n\n    size_t test()\n    {\n        value_type[] e = new value_type[length];\n        return e.length;\n    }\n}\n\nvoid test65()\n{\n    Foo65 f;\n\n    assert(f.test() == 47);\n}\n\n/******************************************/\n\nclass Thing66\n{\n        template print(T2)\n        {\n                void print(T2 t)\n                {\n                    printf(\"t = %d\\n\", t);\n                    assert(t == 10);\n                }\n        }\n}\n\n\nvoid test66()\n{\n        Thing66 thing = new Thing66;\n\n        thing.print!(int)(10);\n}\n\n/******************************************/\n\ntemplate Foo67(alias T)\n{\n    void Foo67()\n    {\n        printf(\"T = '%.*s'\\n\", T.length, T.ptr);\n        assert(T == \"hello\");\n    }\n}\n\nvoid test67()\n{\n    static string x = \"hello\";\n\n    Foo67!(x)();\n}\n\n\n/******************************************/\n\ntemplate T68(int a) {\n    int[a] vec;\n}\n\nvoid test68()\n{\n        int i;\n\n        i = T68!(4>1?4:1).vec[0];\n        assert(i == 0);\n        i = T68!(4==1?1:(1==1?4:(4>1?1:4))).vec[0];\n        assert(i == 0);\n}\n\n/******************************************/\n\nsize_t printx(string s)\n{\n    printf(\"s = '%.*s'\\n\", s.length, s.ptr);\n    return s.length;\n}\n\nsize_t printx(int i)\n{\n    printf(\"i = %d\\n\", i);\n    return 28;\n}\n\ntemplate Foo69(alias T)\n{\n size_t Foo69()\n {\n  return printx(T);\n }\n}\n\nvoid test69()\n{\n static string x = \"hello\";\n static string z = \"abc\";\n static int y=100;\n size_t i;\n\n alias Foo69!(x) foox;\n alias Foo69!(y) fooy;\n\n    i = Foo69!(x)();\n    assert(i == 5);\n    i = Foo69!(y)();\n    assert(i == 28);\n    i = Foo69!(z)();\n    assert(i == 3);\n    i = foox();\n    assert(i == 5);\n    i = fooy();\n    assert(i == 28);\n}\n\n/******************************************/\n\ntemplate temptt70(alias func)\n{\n   void temp()\n   {\n        func();\n   }\n}\n\nint x70;\n\nvoid myfunc70()\n{\n    printf(\"myfunc70()\\n\");\n    x70 = 6;\n}\n\nalias temptt70!(myfunc70).temp foo70;\n\nvoid test70()\n{\n   foo70();\n   assert(x70 == 6);\n}\n\n/******************************************/\n\nstruct A71(T)\n{\n    alias .A71!(T) AT;\n    int x;\n}\n\nalias A71!(int) Aint71;\n\nvoid test71()\n{\n    Aint71.AT a;\n    a.x = 3;\n}\n\n/******************************************/\n\ntemplate foo72(T)\n{\n    char[] foo72(T d)\n    {\n        uint sz = typeof(d[0]).sizeof * 2;\n        return null;\n    }\n}\n\nvoid test72()\n{\n    static ulong[5] a = [0,1,2,3,4];\n    static uint[5] b = [0,1,2,3,4];\n    char[] r;\n    r = foo72!(ulong[5])(a); printf(\"%.*s\\n\", r.length, r.ptr);\n    r = foo72!(uint[5])(b);  printf(\"%.*s\\n\", r.length, r.ptr);\n}\n\n\n/******************************************/\n\nalias int Int73;\nclass Test73(T = Int73);\nalias Test73!() Foo73;\n\nvoid test73()\n{\n}\n\n/******************************************/\n\nclass A74\n{\n    alias A74 atype;\n    int x;\n}\n\n\nclass B74(R, int V = R.sizeof)\n{\n    int v = V;\n}\n\nvoid test74()\n{\n    B74!(A74,3) b = new B74!(A74,3)();\n    assert(b.v == 3);\n\n    B74!(A74) c = new B74!(A74)();\n    assert(c.v == A74.sizeof);\n}\n\n\n/******************************************/\n\ninterface NotionalRange75(V)\n{\n}\n\nclass MatchedNotionalRange75(R)\n    : NotionalRange75!(R.value_type)\n{\n}\n\nclass Range75\n{\n    alias   int   value_type;\n}\n\nclass List75\n{\n\n    MatchedNotionalRange75!(Range75) x;\n}\n\nvoid test75()\n{\n}\n\n\n/******************************************/\n\ninterface Indian(T)\n{\n}\n\ninterface Iterable(T)\n{\n  Indian!(T) foo();\n}\n\nclass Lope(T) : Iterable!(T)\n{\n  Indian!(T) foo()\n  {\n        return new Corn!(T);\n  }\n}\n\nclass Corn(T) : Indian!(T)\n{\n}\n\nvoid test76()\n{\n  Lope!(int) x = new Lope!(int);\n}\n\n\n/******************************************/\n\nclass RawFile\n{\n}\n\nclass Stream : RawFile\n{\n        template readLineT(T) { bool readLineT()\n        {\n                if (super)\n                        return false;\n                return true;\n        }}\n\n        bool readLine()\n        {\n                return readLineT!(int)();\n        }\n}\n\nvoid test77()\n{\n}\n\n\n/******************************************/\n\nclass Four(U, V, X, Y)\n{\n  U i;  V j;  X k;  Y l;\n}\n\ntemplate WhatFour(U,V,X,Y)\n{\n    int func(Four!(U,V,X,Y) four)\n    {\n        printf(\"general template\\n\");\n        return 1;\n    }\n}\n\ntemplate WhatFour(U:int,V,X,Y)\n{\n    int func(Four!(int,V,X,Y) four)\n    {\n        printf(\"specialization:: first int\\n\");\n        return 2;\n    }\n}\n\ntemplate WhatFour(U,V:U,X,Y:X)\n{\n    int func(Four!(U,U,X,X) four)\n    {\n        printf(\"specialization:: first two equal, second two equal\\n\");\n        return 3;\n    }\n}\n\nalias WhatFour!(int,float,char,bool).func whatfour;\nalias WhatFour!(float,float,char,bool).func whatfour;\nalias WhatFour!(float,float,char,char).func whatfour;\nalias WhatFour!(int,int,float,char).func whatfour;  // ambiguous match\n\nvoid test78()\n{ int j;\n\n  Four!(int,float,char,bool) f;\n  Four!(float,float,char,bool) g;\n  Four!(float,float,char,char) h;\n  Four!(int,int,float,char) i;\n\n  j = whatfour(f);\n  assert(j == 2);\n  j = whatfour(g);\n  assert(j == 1);\n  j = whatfour(h);\n  assert(j == 3);\n  j = whatfour(i);\n  assert(j == 2);\n\n  /*\n  will print:\nspecialization:: first int\ngeneral template\nspecialization:: first two equal, second two equal\nspecialization:: first int\n  */\n}\n\n\n/******************************************/\n// http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D.bugs&artnum=2117\n\nclass Conversion(T,U){\n        alias char Small;\n        class Big{\n                char[2] dummy;\n        }\n        static Small Test(U u);\n        static Big Test(...);\n        static T MakeT();\n        enum {\n                exists = (Test(MakeT())).sizeof == (Small).sizeof\n        }\n}\n\nvoid variadicDummy(...){\n}\n\nvoid test79()\n{\n        variadicDummy(Conversion!(double,int).exists);\n}\n\n/******************************************/\n\nclass A80(T)\n{\n   T s;\n\n   int foo(int delegate (T) d) { return 3 + d(s); }\n\n   int bar()\n   {\n     return foo(delegate int (T t) { return 6 + t.x; });\n   }\n}\n\nclass B80: A80!(B80)\n{\n    int x = 20;\n}\n\nclass C80: A80!(C80)\n{\n    int y = 3;\n    int x = 10;\n}\n\nvoid test80()\n{\n    B80 b = new B80();\n    C80 c = new C80();\n\n    b.s = b;\n    c.s = c;\n\n    assert(b.bar() == 9+20);\n    assert(c.bar() == 9+10);\n}\n\n/******************************************/\n\nstruct T81(FOO)\n{\n        S81 s;\n}\n\nstruct S81\n{\n        T81!(int)* pt;\n}\n\nvoid test81()\n{\n}\n\n/******************************************/\n\nT foo82(T : const(U)*, U=char)(T t)\n{\n    return null;\n}\n\nvoid test82()\n{   int i;\n    const int ci;\n\n    //writeln(typeid(typeof(foo82(&ci))));\n    //writeln(typeid(typeof(foo82(&i))));\n    assert(typeof(foo82(&ci)).stringof == \"const(int)*\");\n    assert(typeof(foo82(&i)).stringof == \"int*\");\n}\n\n/******************************************/\n\nstruct A83\n{\n    void foo(int) {}\n    void bar(T)(T) {}\n}\n\nvoid test83()\n{\n    A83 a;\n    a.foo = 5;\n    a.bar = 6;\n}\n\n/******************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n//    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test56();\n    test57();\n    test58();\n    test59();\n    test60();\n    test61();\n    test62();\n    test63();\n    test64();\n    test65();\n    test66();\n    test67();\n    test68();\n    test69();\n    test70();\n    test71();\n    test72();\n    test73();\n    test74();\n    test75();\n    test76();\n    test77();\n    test78();\n    test79();\n    test80();\n    test81();\n    test82();\n    test83();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/template13478.d",
    "content": "/// Tests emission of templates also referenced in speculative contexts.\n/// Failure triggered with -inline.\nmodule template13478;\n\nimport imports.template13478a;\nimport imports.template13478b;\n\nint main() {\n   return foo!int();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/template2.d",
    "content": "// original post to the D newsgroup:\n//    http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=D&artnum=10554&header\n// Test to manipulate 3D vectors, in D!\n// by Sean L Palmer (seanpalmer@directvinternet.com)\n// This code is released without any warranty.  Use at your own risk.\nimport core.stdc.stdio;\nimport std.math : sqrt;\n\ntemplate VecTemplate(tfloat, int dim:3)\n{\n struct Vector\n {\n  tfloat[dim] d;\n\n  version(none)\n  {\n   // sets the vector to the value of the given array\n   void set(tfloat[dim] r) { d[] = r[]; }\n   // comparison (a == b, a != b)\n   bool opEquals(Vector b) { for (int i=0; i<dim; ++i) if (d[i] != b.d[i]) return\nfalse; return true; }\n   // negate (-a)\n   Vector opNeg() { Vector r; for (int i=0; i<dim; ++i) r.d[i] = -d[i]; return\nr;  }\n   // complement (~a)\n   Vector opCom() { Vector r; for (int i=0; i<dim; ++i) r.d[i] = d[(i+1)%dim];\nd[0] = -d[0]; return r;  }\n   // add (a + b)\n   Vector opAdd(Vector b) { Vector r; r.d[] = d[] + b.d[]; return r;  }\n   // addto (a += b)\n   Vector opAddAssign(Vector b) { d[] += b.d[]; return r;  }\n   // subtract (a - b)\n   Vector opSub(Vector b) { Vector r; r.d[] = d[] - b.d[]; return r;  }\n   // multiply by scalar (a * 2.0)\n   Vector opMul(tfloat b) { Vector r; for (int i=0; i<dim; ++i) r.d[i] = d[i]\n* b; return r;  }\n   // divide by scalar (a / b)\n   Vector opDiv(tfloat b) { return *this * (1/b);  }\n   // dot product (a * b)\n   tfloat opMul(Vector b) { tfloat r=0; for (int i=0; i<dim; ++i) r += d[i];\nreturn r;  }\n   // outer product (a ^ b)\n   //Vector opXor(Vector b) { Vector r; for (int i=0; i<dim; ++i) r += d[i]; return r;  }\n  }\n\n  void set(tfloat[dim] r) { for (int i=0; i<dim; ++i) d[i] = r[i]; }\n  // comparison (a == b, a != b)\n  const bool opEquals(ref const Vector b) { for (int i=0; i<dim; ++i) if (d[i] != b.d[i]) return\nfalse; return true; }\n  // negate (-a)\n  Vector opNeg() { Vector r; for (int i=0; i<dim; ++i) r.d[i] = -d[i]; return\nr;  }\n  // complement (~a)\n  Vector opCom() { Vector r; for (int i=0; i<dim; ++i) r.d[i] = d[(i+1)%dim];\nd[0] = -d[0]; return r;  }\n  // add (a + b)\n  Vector opAdd(Vector b) { Vector r; for (int i=0; i<dim; ++i) r.d[i] = d[i] +\nb.d[i]; return r;  }\n  // addto (a += b)\n  Vector opAddAssign(Vector b) { for (int i=0; i<dim; ++i) d[i] += b.d[i]; return\nthis; }\n  // subtract (a - b)\n  Vector opSub(Vector b) { Vector r; for (int i=0; i<dim; ++i) r.d[i] = d[i] -\nb.d[i]; return r;  }\n  // multiply by scalar (a * 2.0)\n  Vector opMul(tfloat b) { Vector r; for (int i=0; i<dim; ++i) r.d[i] = d[i] *\nb; return r;  }\n  // divide by scalar (a / b)\n  Vector opDiv(tfloat b) { return this * (1/b);  }\n  // dot product (a * b)\n  tfloat opMul(Vector b) { tfloat r=0; for (int i=0; i<dim; ++i) r += d[i];\nreturn r;  }\n  // outer product (a ^ b)\n  //Vector opXor(Vector b) { Vector r; for (int i=0; i<dim; ++i) r += d[i]; return r;  }\n\n  void print() { for (int i=0; i<dim; ++i) printf(\"%f \", d[i]);\nprintf(\"\\n\"); }\n }\n\n tfloat abs(Vector v)\n {\n  return sqrt(sqr(v));\n }\n\n tfloat sqr(Vector v)\n {\n  return v * v;\n }\n}\n\nalias VecTemplate!(float, 3) VcT;\n\nfloat[3] up = [ 0, 1, 0 ];\n\nint main(char[][] args)\n{\n printf(\"running\\n\");\n with (VcT)         // try this, I dare ya!!  crashes DMD 0.51\n {\n  VcT.Vector a,b,c;\n  c.set(up);\n  b.set(up);\n  a = b + c;\n  a.print();\n  printf(\"b * c = %f\\n\",b * c);\n  printf(\"abs(a) = %f\\n\",VcT.abs(a));\n  printf(\"sqr(a) = %f\\n\",VcT.sqr(a));\n }\n printf(\"closing\\n\");\n return 0;\n}\n\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/template2962.d",
    "content": "// EXTRA_SOURCES: imports/template2962a.d\n\n// comment 29\nvoid foo(T)(T p)\n{\n    void inner(U)() {\n        auto p2 = p;\n    }\n    inner!int();\n}\n\n// comment 20\nvoid funcD(alias x)() {\n   assert(x==1.0);\n}\n\nvoid funcC(T)(double a){\n    // Case 1: ICE(glue.c)\n    funcD!(a)();\n\n    // Case 2: wrong code\n    double b = 1.0; funcD!(b)();\n}\n\nvoid bug2962comment36()(int p)\n{\n    int inner()() { return p; }\n    alias inner!() finner;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/template3.d",
    "content": "\nimport core.stdc.stdio;\n\n/*********************************************************/\n\ntemplate Foo(T)\n{\n    static if (is(T : int))\n        alias T t1;\n\n    static if (T.sizeof == 4)\n        alias T t2;\n\n    static if (is(T U : int))\n        alias U t3;\n\n    static if (is(T* V : V*))\n        alias V t4;\n\n    static if (is(T W))\n        alias W t5;\n    else\n        alias char t5;\n\n    static if (is(T* X : X*))\n    {\n    }\n}\n\nvoid test1()\n{\n    Foo!(int).t1 x1;\n    assert(typeid(typeof(x1)) == typeid(int));\n\n    Foo!(int).t2 x2;\n    assert(typeid(typeof(x2)) == typeid(int));\n\n    Foo!(int).t3 x3;\n    assert(typeid(typeof(x3)) == typeid(int));\n\n    Foo!(int*).t4 x4;\n    assert(typeid(typeof(x4)) == typeid(int*));\n\n    Foo!(int).t5 x5;\n    assert(typeid(typeof(x5)) == typeid(int));\n\n    Foo!(int).X x6;\n    assert(typeid(typeof(x6)) == typeid(int));\n}\n\n/*********************************************************/\n\n\nvoid test2()\n{\n    alias int T;\n\n    static if (is(T : int))\n        alias T t1;\n\n    static if (T.sizeof == 4)\n        alias T t2;\n\n    static if (is(T U : int))\n        alias U t3;\n\n    static if (is(T* V : V*))\n        alias V t4;\n\n    static if (is(T W))\n        alias W t5;\n    else\n        alias char t5;\n\n    static if (is(T* X : X*))\n    {\n    }\n\n    t1 x1;\n    assert(typeid(typeof(x1)) == typeid(int));\n\n    t2 x2;\n    assert(typeid(typeof(x2)) == typeid(int));\n\n    t3 x3;\n    assert(typeid(typeof(x3)) == typeid(int));\n\n    t4 x4;\n    assert(typeid(typeof(x4)) == typeid(int));\n\n    t5 x5;\n    assert(typeid(typeof(x5)) == typeid(int));\n\n    X x6;\n    assert(typeid(typeof(x6)) == typeid(int));\n}\n\n/*********************************************************/\n\nvoid test3()\n{\n    static if (is(short : int))\n    {   printf(\"1\\n\");\n    }\n    else\n        assert(0);\n    static if (is(short == int))\n        assert(0);\n    static if (is(int == int))\n    {   printf(\"3\\n\");\n    }\n    else\n        assert(0);\n}\n\n/*********************************************************/\n\ntemplate TValue(int i:1)\n{\n        pragma(msg,\"last instantiation!!!\");\n        const int TValue = 1;\n}\n\ntemplate TValue(int i)\n{\n        pragma(msg,\"instantiating...\");\n        const int TValue = i * TValue!(i-1);\n}\n\nvoid test4()\n{\n        assert(TValue!(3) == 6);\n}\n\n/*********************************************************/\n\ntemplate Reverse(string s: \"\") {\n    const char[] Reverse = \"\";\n}\n\ntemplate Reverse(string s) {\n    const char[] Reverse = Reverse!(s[1..$]) ~ s[0];\n}\n\nvoid test5()\n{\n    assert(Reverse!(\"Recursive string template\") == \"etalpmet gnirts evisruceR\");\n}\n\n/*********************************************************/\n\ntemplate foo6(alias V)\n{\n    int foo6()\n    {\n        return V;\n    }\n}\n\nclass bar6(alias V)\n{\n    int abc()\n    {\n        return V;\n    }\n}\n\nvoid test6()\n{\n    int j = 3;\n    int k = 4;\n\n    int i = foo6!(j)();\n    i += foo6!(j)();\n\n    i += foo6!(k)();\n\n    bar6!(j) b = new bar6!(j);\n    i -= b.abc();\n\n    assert(i == 7);\n}\n\n/*********************************************************/\n\ntemplate Bind7(alias dg)\n{\n    int Bind7()\n    {\n        dg('c');\n        return 0;\n    }\n}\n\nvoid test7()\n{\n    char[] v;\n\n    void foo(char c) { v ~= c; }\n\n    alias Bind7!(foo) intv;\n    intv();\n    assert(v[0] == 'c');\n}\n\n/*********************************************************/\n\ntemplate sum8(real x)\n{\n    static if (x <= 1.0L){\n            const real sum8 = x;\n    }else{\n            const real sum8 = x + sum8!(x - 1.0L);\n    }\n}\n\nvoid test8()\n{\n    real x = sum8!(3.0L);\n\n    if(x != 6.0L){\n            assert(0);\n    }\n}\n\n/*********************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/template4.d",
    "content": "import std.stdio;\nimport core.stdc.stdio;\n\n/*********************************************************/\n\ntemplate Foo(T)\n{\n    static if ( is(T : int) )\n        alias T t1;\n\n    static if (T.sizeof == 4)\n        alias T t2;\n\n    static if ( is(T AB : int) )\n        alias AB t3;\n\n    static if ( is(T* V : V*) )\n        alias V t4;\n\n    static if ( is(T W) )\n        alias W t5;\n    else\n        alias char t5;\n\n    static if ( is(T* X : X*) )\n    {\n    }\n}\n\nvoid test1()\n{\n    Foo!(int).t1 x1;\n    assert(typeid(typeof(x1)) == typeid(int));\n\n    Foo!(int).t2 x2;\n    assert(typeid(typeof(x2)) == typeid(int));\n\n    Foo!(int).t3 x3;\n    assert(typeid(typeof(x3)) == typeid(int));\n\n    Foo!(int).t4 x4;\n    assert(typeid(typeof(x4)) == typeid(int));\n\n    Foo!(int).t5 x5;\n    assert(typeid(typeof(x5)) == typeid(int));\n\n    Foo!(int).X x6;\n    assert(typeid(typeof(x6)) == typeid(int));\n}\n\n/*********************************************************/\n\n\nvoid test2()\n{\n    alias int T;\n\n    static if ( is(T : int) )\n        alias T t1;\n\n    static if (T.sizeof == 4)\n        alias T t2;\n\n    static if ( is(T U : int) )\n        alias U t3;\n\n    static if ( is(T* V : V*) )\n        alias V t4;\n\n    static if ( is(T W) )\n        alias W t5;\n    else\n        alias char t5;\n\n    static if ( is(T* X : X*) )\n    {\n    }\n\n    t1 x1;\n    assert(typeid(typeof(x1)) == typeid(int));\n\n    t2 x2;\n    assert(typeid(typeof(x2)) == typeid(int));\n\n    t3 x3;\n    assert(typeid(typeof(x3)) == typeid(int));\n\n    t4 x4;\n    assert(typeid(typeof(x4)) == typeid(int));\n\n    t5 x5;\n    assert(typeid(typeof(x5)) == typeid(int));\n\n    X x6;\n    assert(typeid(typeof(x6)) == typeid(int));\n}\n\n/*********************************************************/\n\nvoid test3()\n{\n    static if ( is(short : int) )\n    {\n        printf(\"1\\n\");\n    }\n    else\n        assert(0);\n    static if ( is(short == int) )\n        assert(0);\n    static if ( is(int == int) )\n    {\n        printf(\"3\\n\");\n    }\n    else\n        assert(0);\n}\n\n/*********************************************************/\n\nvoid test4()\n{\n    alias void Function(int);\n\n    static if (is(Function Void == function))\n        printf(\"if\\n\");\n    else\n        assert(0);\n\n//    static if (is(Void == void))\n//        printf(\"if\\n\");\n//    else\n//        assert(0);\n\n\n    alias byte delegate(int) Delegate;\n\n    static if (is(Delegate Foo == delegate))\n        printf(\"if\\n\");\n    else\n        assert(0);\n\n    static if (is(Foo Byte == function))\n        printf(\"if\\n\");\n    else\n        assert(0);\n\n//    static if (is(Byte == byte))\n//        printf(\"if\\n\");\n//    else\n//        assert(0);\n\n\n    union Union { }\n\n    static if (is(Union == union))\n        printf(\"if\\n\");\n    else\n        assert(0);\n\n\n    struct Struct { }\n\n    static if (is(Struct == struct))\n        printf(\"if\\n\");\n    else\n        assert(0);\n\n\n    enum Enum : short { EnumMember }\n\n    static if (is(Enum Short == enum))\n        printf(\"if\\n\");\n    else\n        assert(0);\n\n    static if (is(Short == short))\n        printf(\"if\\n\");\n    else\n        assert(0);\n\n    class Class { }\n\n    static if (is(Class == class))\n        printf(\"if\\n\");\n    else\n        assert(0);\n\n\n    interface Interface { }\n\n    static if (is(Interface == interface))\n        printf(\"if\\n\");\n    else\n        assert(0);\n\n}\n\n/*********************************************************/\n\nclass Foo5(T)\n{\n    Node sentinel;\n\n    struct Node\n    {\n        int value;\n    }\n}\n\nvoid test5()\n{\n    Foo5!(int) bar=new Foo5!(int);\n    bar.sentinel.value = 7;\n}\n\n\n/*********************************************************/\n\ntemplate factorial6(int n)\n{\n    static if (n == 1)\n        const int factorial6 = 1;\n    else\n        const int factorial6 = n * .factorial6!(n-1);\n}\n\nvoid test6()\n{\n    int i = factorial6!(4);\n    printf(\"%d\\n\", i);\n    assert(i == 24);\n}\n\n\n/*********************************************************/\n\ntemplate factorial7(float n, cdouble c, string sss, string ttt)\n{\n    static if (n == 1)\n        const float factorial7 = 1;\n    else\n        const float factorial7 = n * 2;\n}\n\ntemplate bar7(wstring abc, dstring def)\n{\n    const int x = 3;\n}\n\nvoid test7()\n{\n    float f = factorial7!(4.25, 6.8+3i, \"hello\", null);\n    printf(\"%g\\n\", f);\n    assert(f == 8.5);\n    int i = bar7!(\"abc\"w, \"def\"d).x;\n    printf(\"%d\\n\", i);\n    assert(i == 3);\n}\n\n/*********************************************************/\n\ntemplate whale(string walrus)\n{\n    const char [] whale = walrus;\n}\n\ntemplate dolphin(string fish)\n{\n   const char [] dolphin = whale!(fish[0..3]);\n}\n\nconst char [] urchin1 = dolphin!(\"anenome\");\nconst char [] urchin2 = whale!(\"anenome\"[0..3]);\n\ntemplate dolphin3(string fish)\n{\n   const char [] dolphin3 = fish[0..3];\n}\n\nconst char [] urchin3 = dolphin3!(\"anenome\");\n\ntemplate dolphin4(string fish)\n{\n  const char [] dolphin4 = whale!(fish[0..(3)]);\n}\n\nconst char [] urchin4 = dolphin4!(\"anenome\");\n\ntemplate dolphin5(string fish)\n{\n  const char [] dolphin5 = whale!(fish[(0)..3]);\n}\n\nconst char [] urchin5 = dolphin5!(\"anenome\");\n\nvoid test8()\n{\n    assert(urchin1 == \"ane\");\n    assert(urchin2 == \"ane\");\n    assert(urchin3 == \"ane\");\n    assert(urchin4 == \"ane\");\n    assert(urchin5 == \"ane\");\n}\n\n/*********************************************************/\n\nint testEmpty(string s) { return 0; }\n\ntemplate Recurse(string pattern){\n}\n\n\ntemplate slice(string str, int from, int to)\n{\n    const string slice = str[from..to];\n}\n\n\ntemplate Compile(string pattern)\n{\n    const string left = slice!(pattern,4,pattern.length);\n\n    const string remaining = slice!(left,1,left.length);\n\n    alias Recurse!(remaining) fn;\n}\n\n\n\ntemplate Match(string pattern)\n{\n    alias Compile!(pattern) Match;\n}\n\nvoid test9()\n{\n    alias Match!(\"abcdefghijk\") f;\n}\n\n/*********************************************************/\n\ntemplate Foo10(string s)\n{\n    const string Foo10 = s;\n}\n\nvoid test10()\n{\n    string s;\n\n    s = Foo10!(\"abc\" ~ \"e\");\n    assert(s == \"abce\");\n\n    s = Foo10!(\"abc\" ~ 'f');\n    assert(s == \"abcf\");\n\n    s = Foo10!('g' ~ \"abc\");\n    assert(s == \"gabc\");\n\n    s = Foo10!('g' ~ \"abc\" ~ 'h');\n    assert(s == \"gabch\");\n}\n\n/*********************************************************/\n\ntemplate Foo11(string s)\n{\n    const string Foo11 = s;\n}\n\nvoid test11()\n{\n    string s;\n\n    s = Foo11!(\"abcdef\"[1..$ - 1]);\n    assert(s == \"bcde\");\n}\n\n/*********************************************************/\n\ntemplate Foo12(int i)\n{\n    const int Foo12 = i;\n}\n\nvoid test12()\n{\n    int i;\n\n    i = Foo12!(\"abcdef\" == \"abcdef\");\n    assert(i == 1);\n    i = Foo12!(\"abcdef\" == \"abcqef\");\n    assert(i == 0);\n    i = Foo12!(\"abcdef\" == \"abc\");\n    assert(i == 0);\n    i = Foo12!(\"abc\" == \"abcdef\");\n    assert(i == 0);\n}\n\n/*********************************************************/\n\nconst a13 = 3;\nstatic if (a13 == 3)\n    int b13 = 7;\n\ntemplate Foo13(int i)\n{\n    const int j = i + 1;\n    static if (j == 3)\n        const int k = 2;\n}\n\nvoid test13()\n{\n    assert(b13 == 7);\n    assert(Foo13!(2).k == 2);\n}\n\n/*********************************************************/\n\ntemplate zebra(string w)\n{\n    static if (w.length > 2 && w[1] == 'q')\n        const bool zebra = true;\n    else\n        const bool zebra = false;\n}\n\ntemplate horse(string w)\n{\n    static if (w.length == 1 || w[1] == 'q')\n        const bool horse = true;\n    else\n        const bool horse = false;\n}\n\nvoid test14()\n{\n    bool lion = zebra!(\"a\");\n    writeln(lion);\n    assert(!lion);\n    lion = zebra!(\"aqb\");\n    writeln(lion);\n    assert(lion);\n\n    lion = horse!(\"a\");\n    writeln(lion);\n    assert(lion);\n    lion = horse!(\"aqb\");\n    writeln(lion);\n    assert(lion);\n    lion = horse!(\"ab\");\n    writeln(lion);\n    assert(!lion);\n}\n\n/*********************************************************/\n\ntemplate factorial15(int n)\n{\n   static if (n<2) const int factorial15 = 1;\n   else const int factorial15 = n * factorial15!(n-1);\n}\n\ntemplate rhino15(alias hippo)\n{\n   const int rhino15 = hippo!(3);\n}\n\nvoid test15()\n{\n    const int lion = rhino15!(factorial15);\n    assert(lion == 6);\n}\n\n/*********************************************************/\n\n// Create a constant array of int or uint sized items\n// as a dstring string. n is the index of the last item.\ntemplate makeLookup(alias entry, int n)\n{\n   static if (n == -1) // start with an empty array...\n     const dchar [] makeLookup = \"\";\n   else        // ... and fill it up\n     const dchar [] makeLookup = makeLookup!(entry, n-1)\n           ~ cast(dchar)entry!(n);\n}\n\ntemplate factorial16(uint n)\n{\n     static if (n<2) const uint factorial16 = 1;\n     else const factorial16 = n * factorial16!(n-1);\n}\n\n// Make an array of factorials from 0 to 13 (14!> uint.max)\nconst smallfactorials = makeLookup!(factorial16, 13);\n\nconst uint[14] testtable =\n[\n  1,\n  1,\n  2,\n  6,\n  24,\n  120,\n  720,\n  5040,\n  40320,\n  362880,\n  3628800,\n  39916800,\n  479001600,\n  1932053504,\n];\n\nvoid test16()\n{\n    for (int i=0; i<smallfactorials.length; ++i)\n    {\n        writefln(\"%d  %d\", i, smallfactorials[i]);\n        assert(smallfactorials[i] == testtable[i]);\n    }\n}\n\n/*********************************************************/\n\ntemplate dingo(int a)\n{\n    pragma(msg, \"This actually gets evaluated!\");\n    static if (a==2) {\n        const int dingo = 28;\n    }\n    else\n        const int dingo = a;\n}\n\nconst int bilby = dingo!(2);\n\nvoid test17()\n{\n    assert(bilby == 28);\n}\n\n/*********************************************************/\n\ntemplate frog(char F)\n{\n     const int frog = 1;\n}\n\ntemplate frog(int F)\n{\n     const int frog = 2;\n}\n\ntemplate frog(char F: 'A')\n{\n     const int frog = 3;\n}\n\ntemplate frog(int F: 65)\n{\n     const int frog = 4;\n}\n\nstatic assert( frog!('B')==1);\nstatic assert( frog!(64)==2);\nstatic assert( frog!('A')==3);\nstatic assert( frog!(65)==4);\n\nvoid test18()\n{\n}\n\n/*********************************************************/\n\nvoid test19()\n{\n    MakeTuple19!(int,int) t;\n    assert(t.sizeof == int.sizeof);\n}\n\ntemplate MakeTuple19( T1, T2 )\n{\n     alias int MakeTuple19;\n}\n\ntemplate MakeTuple19(T1, T2, T3=float)\n{\n     alias long MakeTuple19;\n}\n\n\n/*********************************************************/\n\ntemplate sqrt(real x, real root = x/2, int ntries = 0)\n{\n  static if (ntries == 5)\n    // precision doubles with each iteration,\n    // 5 should be enough\n    const sqrt = root;\n  else static if (root * root - x == 0)\n    const sqrt = root;  // exact match\n  else\n    // iterate again\n    const sqrt = sqrt!(x, (root+x/root)/2, ntries+1);\n}\n\nvoid test20()\n{\n    real x = sqrt!(2);\n    writefln(\"%.20g\", x); // 1.4142135623730950487\n}\n\n/*********************************************************/\n\ntemplate hash(string s, uint sofar=0)\n{\n   static if (s.length == 0)\n      const hash = sofar;\n   else\n      const hash = hash!(s[1 .. $], sofar * 11 + s[0]);\n}\n\nuint foo21()\n{\n    return hash!(\"hello world\");\n}\n\nvoid test21()\n{\n    auto i = foo21();\n    writeln(i);\n    assert(i == 1871483972);\n}\n\n\n/*********************************************************/\n\nT Foo22(T)(int i)\n{\n    printf(\"i = %d\\n\", i);\n    return cast(T)0;\n}\n\nvoid test22()\n{\n    Foo22!(int)(3);\n}\n\n/*********************************************************/\n\ntemplate fish( char s)\n{\n  const bool fish = true;\n}\n\ntemplate dog(string bird)\n{\n        static if (bird.length>99 && fish!( (bird[95])) )\n           const int dog = 2;\n        else const int dog = 3;\n}\n\nconst int pig = dog!(\"a\");\n\nvoid test23()\n{\n}\n\n/*********************************************************/\n\nT delegate (T) acc24 (T) (T n)\n{\n    return (T i) { return n += i; };\n}\n\nvoid test24()\n{\n    auto acc1 = acc24 (4);\n}\n\n/*********************************************************/\n\nT func25(T, T c = 1)(T x)\n{\n    return x * c;\n}\n\nvoid test25()\n{\n    double d;\n\n    d = func25(1.0);\n    assert(d == 1.0);\n\n    d = func25(2.0);\n    assert(d == 2.0);\n\n    d = func25!(double)(2.0);\n    assert(d == 2.0);\n\n    d = func25!(double, 3)(2.0);\n    assert(d == 6.0);\n}\n\n/*********************************************************/\n\nclass Foo26 {}\nclass Bar26 {}\n\nstring name26;\n\ntemplate aliastest(alias A) {\n    pragma(msg,\"Alias Test instantiated\");\n    void aliastest() {\n        name26 = (new A!().al).classinfo.name;\n        //writefln(\"Alias Test: \", name26);\n    }\n}\n\ntemplate boxtpl(alias A) {\n    template box() {\n        alias A al;\n    }\n}\n\nvoid test26()\n{\n    aliastest!(boxtpl!(Foo26).box) ();\n    assert(name26 == \"template4.Foo26\");\n    aliastest!(boxtpl!(Bar26).box) ();\n    assert(name26 == \"template4.Bar26\");\n}\n\n/*********************************************************/\n\nstruct TFoo27(int x) { }\nalias TFoo27!(3) a;\nalias TFoo27!(2+1) b;\nalias TFoo27!(3u) c;\n\nstatic assert(is(TFoo27!(3) == TFoo27!(2 + 1)));\nstatic assert(is(TFoo27!(3) == TFoo27!(3u)));\n\nvoid test27()\n{\n}\n\n/*********************************************************/\n\nstruct SiQuantity\n{\n    real value = 0;\n    static assert(SiQuantity.sizeof == real.sizeof);\n\n    template AddDimensions(int mul, U) { }\n}\n\nvoid test28()\n{\n}\n\n/*********************************************************/\n\ntemplate Count29() { const Count29 = 5; }\n\nvoid test29()\n{\n    int[Count29!()] x;\n\n    assert(x.length == 5);\n}\n\n/*********************************************************/\n\nclass FooClass(T) {  T data; }\n\nstruct FooStruct(T) {  T data;  }\n\nvoid bar_struct(T)(FooStruct!(T) a) {}\n\nvoid bar_class(T)(FooClass!(T) a) {}\n\nvoid test30()\n{\n    auto C = new FooClass!(double);\n    FooStruct!(double) S;\n\n    bar_struct(S);\n    bar_class!(double)(C);\n    bar_class(C);\n}\n\n/*********************************************************/\n\nV get31(V,K)(V[K] dict, K key, V def = V.init)\n{\n    V* ptr = key in dict;\n    return ptr? *ptr: def;\n}\n\n\nstring get31x(string[int] dict, int key, string def = null)\n{\n    string* ptr = key in dict;\n    return ptr? *ptr: def;\n}\n\n\nvoid test31()\n{\n    string[int] i2s;\n    i2s[1] = \"Hello\";\n    i2s[5] = \"There\";\n\n    writeln( i2s.get31(1, \"yeh\") );\n    writeln( i2s.get31(2, \"default\") );\n    writeln( i2s.get31(1) );\n    writeln( i2s.get31(2) );\n}\n\n/*********************************************************/\n\nvoid delegate(T, S) Concat(S, T...)(void delegate(T) one, void delegate(S) two)\n{\n  return( delegate void(T t, S s){} );\n}\n\nvoid test32()\n{\n  void delegate(char, char, int) wtf = Concat(\n    delegate void(char a, char b) {},\n    delegate void(int lol) {}\n  );\n}\n\n/*********************************************************/\n\nstruct Composer(T) {\n    alias T delegate(T) Fun;\n    Fun[] funs;\n    public T opCall()(T x) {\n        T result = x;\n        foreach_reverse (f; funs)\n        {\n            result = f(result);\n        }\n        return result;\n    }\n    public void opAddAssign(Fun f) {\n        funs ~= f;\n    }\n}\n\nstruct square(T) {\n    T opCall(T t) {\n        return t*t;\n    }\n}\n\nstruct plus1(T) {\n    T opCall(T t) {\n        return t+1;\n    }\n}\n\nstruct div3(T) {\n    T opCall(T t) {\n        return t/3.0;\n    }\n}\n\nT delegate(T) tofp(T : S!(T), alias S)()\n{\n    class Foo\n    {\n        div3!(T) arg;\n\n        T bar(T t)\n        {\n            return arg(t);\n        }\n    }\n\n    Foo f = new Foo;\n    return &f.bar;\n}\n\nvoid test33() {\n    Composer!(double) comp;\n    comp += delegate double (double x) { return x/3.0;};\n    comp += delegate double (double x) { return x*x;};\n    comp += (double x) => x + 1.0;\n    writefln(\"%f\", comp(2.0));\n\n    // Try function objects\n    Composer!(double) comp2;\n    comp2 += tofp!(div3!(double))();\n    comp2 += tofp!(square!(double))();\n    comp2 += tofp!(plus1!(double))();\n    writefln(\"%f\", comp2( 2.0));\n}\n\n/*********************************************************/\n\ntemplate Print34(Ts ...) { pragma (msg, Ts.stringof); }\n\ntemplate Tuple34(Ts ...) { alias Ts Tuple34; }\n\ntemplate Decode34( T )                                       { alias Tuple34!() Types; }\ntemplate Decode34( T : TT!(U1),       alias TT, U1 )         { alias Tuple34!(U1) Types; }\ntemplate Decode34( T : TT!(U1,U2),    alias TT, U1, U2 )     { alias Tuple34!(U1,U2) Types; }\ntemplate Decode34( T : TT!(U1,U2,U3), alias TT, U1, U2, U3 ) { alias Tuple34!(U1,U2,U3) Types; }\n\n\nstruct S34_1(T1) {}\nstruct S34_2(T1, T2) {}\nstruct S34_3(T1, T2, T3) {}\n\nalias Decode34!( bool ).Types SQ0;\nalias Decode34!( S34_1!(bool) ).Types SQ1;\nalias Decode34!( S34_2!(bool,short) ).Types SQ2;\nalias Decode34!( S34_3!(bool,short,int) ).Types SQ3;\n\nmixin Print34!(SQ0);\nmixin Print34!(SQ1);\nmixin Print34!(SQ2);\nmixin Print34!(SQ3);\n\nvoid test34()\n{\n}\n\n/*********************************************************/\n\ntemplate strof(T)\n{\n    static string strof = T.stringof;\n}\n\nvoid test35()\n{\n    alias typeof(delegate () { return (char[]).init;} ) del;\n    auto a = strof!(del);\n    auto aa = strof!(int);\n    auto ab = strof!(typeof(5));\n    auto meth = delegate () { return (char[]).init;};\n    auto b = strof!(typeof(meth));\n    auto c = strof!(typeof(delegate () { return 5; } ));\n    auto d = strof!(typeof(delegate () { return (char[]).init;} ));\n}\n\n/*********************************************************/\n\nstruct Number36(int N)\n{\n    const int value = N;\n}\n\nstruct Foo36(T)\n{\n    int talk() { printf(\"Not so special:\\n\"); return 1; }\n}\n\nstruct Foo36(T : Number36!(N), int N)\n{\n    int talk() { printf(\"Ooh special - NUMBER N\\n\"); return 2; }\n}\n\nvoid test36()\n{\n    Foo36!(Number36!(5)) x;\n    auto i = x.talk();\n    assert(i == 2);\n}\n\n/*********************************************************/\n\nstruct Base37(T) {}\n\nalias Base37 Alias37;\n\nvoid foo37(T)(Alias37!(T) x) {}\n\nvoid test37()\n{\n   Base37!(float) b;\n   foo37(b); // fails!\n}\n\n/*********************************************************/\n\nvoid sort(alias dg, T)(T[] arr)\n{\n    bool a = dg(1,2);\n    printf(\"a = %d\\n\", a);\n    assert(a == true);\n}\n\nvoid test38()\n{   int[] arr;\n    int i = 3;\n\n    sort!( (x,y){ return x + i > y; } )(arr);\n    sort!( (int x,int y){ return x + i > y; } )(arr);\n}\n\n/*********************************************************/\n\nvoid bug4652(U, T...)(long y, T x, U num) {}\nvoid bug4652default(T) (T value, int x=2) {}\nvoid bug4652default(T) (T value, int y) {}\nvoid bug4676(T...)(T args, string str) {}\nvoid bug4676(T...)(T args) {}\n\nvoid instantiate4652()\n{\n    bug4652(2, 'c', 27, 'e', 'f',1); // rejects-valid\n    bug4652(2, 1);  // infinite loop on valid code\n    bug4652default(true);\n    bug4676(1, 2, 3);\n}\n\n/*********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7589\n\nstruct T7589(T)\n{\n    void n;\n}\nstatic assert(!__traits(compiles, T7589!(int)));\n\nint bug7589b(T)() @safe { int *p; *(p + 8) = 6; }\nstatic assert(!__traits(compiles, bug7589b!(int)()+7 ));\n\n\n/*********************************************************/\n\nint bar39(alias dg)(int i)\n{\n    return dg(i);\n}\n\nvoid test39()\n{\n    auto i = bar39!(a => a + 1)(3);\n    if (i != 4)\n        assert(0);\n}\n\n/*********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6701\n\nuint foo_6701(uint v:0)() { return 1; }\nuint foo_6701(uint v)() { return 0; }\nuint foo2_6701(uint v:0, string op)() { return 1; }\nuint foo2_6701(uint v, string op)() { return 0; }\n\nvoid test6701()\n{\n    assert(foo_6701!(0u)() == 1);\n    assert(foo2_6701!(0u, \"+\")() == 1);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7469\n\nstruct Foo7469a(int x) { }\nstruct Foo7469b(int x) { }\nstruct Foo7469c(alias v) { }\nstruct Foo7469d(T...) { }\nstruct Foo7469e(int a, T...) { }\nstruct Foo7469f(T, int k=1) { }\nstruct Foo7469g(T, int k=1) { }\nstruct Foo7469h(uint x) { }\n\nimport core.demangle : demangleType;\n\nvoid test7469()\n{\n    static assert(demangleType(Foo7469a!(3 )    .mangleof) == \"template4.Foo7469a!(3).Foo7469a\");\n    static assert(demangleType(Foo7469a!(3u)    .mangleof) == \"template4.Foo7469a!(3).Foo7469a\");\n    static assert(demangleType(Foo7469b!(3u)    .mangleof) == \"template4.Foo7469b!(3).Foo7469b\");\n    static assert(demangleType(Foo7469b!(3 )    .mangleof) == \"template4.Foo7469b!(3).Foo7469b\");\n    static assert(demangleType(Foo7469c!(3 )    .mangleof) == \"template4.Foo7469c!(3).Foo7469c\");\n    static assert(demangleType(Foo7469c!(3u)    .mangleof) == \"template4.Foo7469c!(3u).Foo7469c\");\n    static assert(demangleType(Foo7469d!(3 )    .mangleof) == \"template4.Foo7469d!(3).Foo7469d\");\n    static assert(demangleType(Foo7469d!(3u)    .mangleof) == \"template4.Foo7469d!(3u).Foo7469d\");\n    static assert(demangleType(Foo7469e!(3u, 5u).mangleof) == \"template4.Foo7469e!(3, 5u).Foo7469e\");\n    static assert(demangleType(Foo7469f!(int, 1).mangleof) == \"template4.Foo7469f!(int, 1).Foo7469f\");\n    static assert(demangleType(Foo7469f!(int)   .mangleof) == \"template4.Foo7469f!(int, 1).Foo7469f\");\n    static assert(demangleType(Foo7469g!(int)   .mangleof) == \"template4.Foo7469g!(int, 1).Foo7469g\");\n    static assert(demangleType(Foo7469g!(int, 1).mangleof) == \"template4.Foo7469g!(int, 1).Foo7469g\");\n    static assert(demangleType(Foo7469h!(3 )    .mangleof) == \"template4.Foo7469h!(3u).Foo7469h\");\n    static assert(demangleType(Foo7469h!(3u)    .mangleof) == \"template4.Foo7469h!(3u).Foo7469h\");\n}\n\n/******************************************/\n\ntemplate foo7698a(T, T val : 0)\n{\n    enum foo7698a = val;\n}\n\nT foo7698b(T, T val : 0)()\n{\n    return val;\n}\n\nT foo7698c(T, T val : T.init)()\n{\n    return val;\n}\n\nvoid test7698()\n{\n    static assert(foo7698a!(int, 0) == 0);\n    assert(foo7698b!(int, 0)() == 0);\n    assert(foo7698c!(int, 0)() == 0);\n}\n\n/*********************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test6701();\n    test7698();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/template6.d",
    "content": "// This is a copy of the engine here:\n//   http://www.digitalmars.com/d/2.0/templates-revisited.html\n// which is a cut down version of the file here:\n//   http://www.dsource.org/projects/ddl/browser/trunk/meta/regex.d\n// which has this copyright notice:\n/+\n    Copyright (c) 2005 Eric Anderton\n\n    Permission is hereby granted, free of charge, to any person\n    obtaining a copy of this software and associated documentation\n    files (the \"Software\"), to deal in the Software without\n    restriction, including without limitation the rights to use,\n    copy, modify, merge, publish, distribute, sublicense, and/or\n    sell copies of the Software, and to permit persons to whom the\n    Software is furnished to do so, subject to the following\n    conditions:\n\n    The above copyright notice and this permission notice shall be\n    included in all copies or substantial portions of the Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n    OTHER DEALINGS IN THE SOFTWARE.\n+/\n\n\nimport std.stdio;\n\n\nconst int testFail = -1;\n\n/**\n * Compile pattern[] and expand to a custom generated function\n * that will take a string str[] and apply the regular expression\n * to it, returning an array of matches.\n */\n\ntemplate regexMatch(string pattern)\n{\n    string[] regexMatch(string str)\n    {\n        string[] results;\n        int result = regexCompile!(pattern).fn(str);\n        if(result != testFail && result > 0){\n            results ~= str[0..result];\n        }\n        return results;\n    }\n}\n\n/******************************\n * The testXxxx() functions are custom generated by templates\n * to match each predicate of the regular expression.\n *\n * Params:\n *      string str      the input string to match against\n *\n * Returns:\n *      testFail        failed to have a match\n *      n >= 0          matched n characters\n */\n\n/// Always match\ntemplate testEmpty()\n{\n    int testEmpty(string str) { return 0; }\n}\n\n/// Match if testFirst(str) and testSecond(str) match\ntemplate testUnion(alias testFirst,alias testSecond,string key)\n{\n    int testUnion(string str)\n    {\n        int result = testFirst(str);\n        if(result != testFail){\n            int nextResult = testSecond(str[result..$]);\n            if(result != testFail)\n                return result + nextResult;\n        }\n        return testFail;\n    }\n}\n\n/// Match if first part of str[] matches text[]\ntemplate testText(string text)\n{\n    int testText(string str)\n    {\n        if (str.length &&\n            text.length <= str.length &&\n            str[0..text.length] == text\n           )\n            return text.length;\n        return testFail;\n    }\n}\n\n/// Match if testPredicate(str) matches 0 or more times\ntemplate testZeroOrMore(alias testPredicate,string key)\n{\n    int testZeroOrMore(string str)\n    {\n        if(str.length == 0) return 0;\n        int result = testPredicate(str);\n        if(result != testFail){\n            int nextResult = .testZeroOrMore!(testPredicate,key)(str[result..$]);\n            if(nextResult != testFail)\n                return result + nextResult;\n            return result;\n        }\n        return 0;\n    }\n}\n\n/// Match if term1[0] <= str[0] <= term2[0]\ntemplate testRange(string term1,string term2)\n{\n    int testRange(string str)\n    {\n        if(str.length && str[0] >= term1[0] && str[0] <= term2[0])\n            return 1;\n        return testFail;\n    }\n}\n\n/// Match if ch[0]==str[0]\ntemplate testChar(string ch)\n{\n    int testChar(string str)\n    {\n        if(str.length && str[0] == ch[0])\n            return 1;\n        return testFail;\n    }\n}\n\n/// Match if str[0] is a word character\ntemplate testWordChar()\n{\n    int testWordChar(string str)\n    {\n        if(str.length &&\n           (\n            (str[0] >= 'a' && str[0] <= 'z') ||\n            (str[0] >= 'A' && str[0] <= 'Z') ||\n            (str[0] >= '0' && str[0] <= '9') ||\n            str[0] == '_'\n           )\n          )\n        {\n            return 1;\n        }\n        return testFail;\n    }\n}\n\n/*****************************************************/\n\n/**\n * Returns the front of pattern[] up until the end or a special character.\n */\n\ntemplate parseTextToken(string pattern){\n    static if(pattern.length > 0){\n        static if(isSpecial!(pattern)){\n            const string parseTextToken=\"\";\n        }\n        else{\n            const string parseTextToken = pattern[0] ~ parseTextToken!(pattern[1..$]);\n        }\n    }\n    else{\n        const string parseTextToken=\"\";\n    }\n}\n\n/**\n * Parses pattern[] up to and including terminator.\n * Returns:\n *      token[]         everything up to terminator.\n *      consumed        number of characters in pattern[] parsed\n */\ntemplate parseUntil(string pattern,char terminator,bool fuzzy=false){\n    static if(pattern.length > 0){\n        static if(pattern[0] == '\\\\'){\n            static if(pattern.length > 1){\n                const string nextSlice = pattern[2 .. $];\n                alias parseUntil!(nextSlice,terminator,fuzzy) next;\n                const string token = pattern[0 .. 2] ~ next.token;\n                const uint consumed = next.consumed+2;\n            }\n            else{\n                pragma(msg,\"Error: expected character to follow \\\\\");\n                static assert(false);\n            }\n        }\n        else static if(pattern[0] == terminator){\n            const string token=\"\";\n            const uint consumed = 1;\n        }\n        else{\n            const string nextSlice = pattern[1 .. $];\n            alias parseUntil!(nextSlice,terminator,fuzzy) next;\n            const string token = pattern[0] ~ next.token;\n            const uint consumed = next.consumed+1;\n        }\n    }\n    else static if(fuzzy){\n        const string token = \"\";\n        const uint consumed = 0;\n    }\n    else{\n        pragma(msg,\"Error: exptected \" ~ terminator ~ \" to terminate group expression\");\n        static assert(false);\n    }\n}\n\n/**\n * Parse contents of character class.\n * Params:\n *      pattern[]  rest of pattern to compile\n * Output:\n *      fn         generated function\n *      consumed   number of characters in pattern[] parsed\n */\n\ntemplate regexCompileCharClass2(string pattern){\n    static if(pattern.length > 0){\n        static if(pattern.length > 1){\n            static if(pattern[1] == '-'){\n                static if(pattern.length > 2){\n                    alias testRange!(pattern[0..1], pattern[2..3]) termFn;\n                    const uint thisConsumed = 3;\n                    const string remaining = pattern[3 .. $];\n                }\n                else{ // length is 2\n                    pragma(msg,\"Error: expected character following '-' in character class\");\n                    static assert(false);\n                }\n            }\n            else{ // not '-'\n                alias testChar!(pattern[0..1]) termFn;\n                const uint thisConsumed = 1;\n                const string remaining = pattern[1 .. $];\n            }\n        }\n        else{\n            alias testChar!(pattern[0..1]) termFn;\n            const uint thisConsumed = 1;\n            const string remaining = pattern[1 .. $];\n        }\n\n        static if(remaining.length > 0){\n            static if(remaining[0] != ']'){\n                alias regexCompileCharClass2!(remaining) next;\n                alias testOr!(termFn,next.fn,remaining) fn;\n                const uint consumed = next.consumed + thisConsumed;\n            }\n            else{\n                alias termFn fn;\n                const uint consumed = thisConsumed;\n            }\n        }\n        else{\n            alias termFn fn;\n            const uint consumed = thisConsumed;\n        }\n    }\n    else{\n        alias testEmpty!() fn;\n        const uint consumed = 0;\n    }\n}\n\n/**\n * At start of character class. Compile it.\n * Params:\n *      pattern[]  rest of pattern to compile\n * Output:\n *      fn         generated function\n *      consumed   number of characters in pattern[] parsed\n */\n\ntemplate regexCompileCharClass(string pattern){\n    static if(pattern.length > 0){\n        static if(pattern[0] == ']'){\n            alias testEmpty!() fn;\n            const uint consumed = 0;\n        }\n        else{\n            alias regexCompileCharClass2!(pattern) charClass;\n            alias charClass.fn fn;\n            const uint consumed = charClass.consumed;\n        }\n    }\n    else{\n        pragma(msg,\"Error: expected closing ']' for character class\");\n        static assert(false);\n    }\n}\n\n/**\n * Look for and parse '*' postfix.\n * Params:\n *      test       function compiling regex up to this point\n *      token[]    the part of original pattern that the '*' is a postfix of\n *      pattern[]  rest of pattern to compile\n * Output:\n *      fn         generated function\n *      consumed   number of characters in pattern[] parsed\n */\n\ntemplate regexCompilePredicate(alias test,string token,string pattern){\n    static if(pattern.length > 0){\n        static if(pattern[0] == '*'){\n            alias testZeroOrMore!(test,token) fn;\n            const uint consumed = 1;\n        }\n        else{\n            alias test fn;\n            const uint consumed = 0;\n        }\n    }\n    else{\n        alias test fn;\n        const uint consumed = 0;\n    }\n}\n\n/**\n * Parse escape sequence.\n * Params:\n *      pattern[]  rest of pattern to compile\n * Output:\n *      fn         generated function\n *      consumed   number of characters in pattern[] parsed\n */\n\ntemplate regexCompileEscape(string pattern){\n    static if(pattern.length > 0){\n        static if(pattern[0] == 's'){\n            // whitespace char\n            alias testRange!(\"\\x00\",\"\\x20\") fn;\n        }\n        else static if(pattern[0] == 'w'){\n            //word char\n            alias testWordChar!() fn;\n        }\n        else{\n            alias testChar!(pattern[0 .. 1]) fn;\n        }\n        const uint consumed = 1;\n    }\n    else{\n        pragma(msg,\"Error: expected char following '\\\\'\");\n        static assert(false);\n    }\n}\n\n/**\n * Parse and compile regex represented by pattern[].\n * Params:\n *      pattern[]  rest of pattern to compile\n * Output:\n *      fn         generated function\n */\n\ntemplate regexCompile(string pattern)\n{\n    static if(pattern.length > 0){\n        static if(pattern[0] == '['){\n            const string charClassToken = parseUntil!(pattern[1 .. $],']').token;\n            alias regexCompileCharClass!(charClassToken) charClass;\n            const string token = pattern[0 .. charClass.consumed+2];\n            const string next = pattern[charClass.consumed+2 .. $];\n            alias charClass.fn test;\n        }\n        else static if(pattern[0] == '\\\\'){\n            alias regexCompileEscape!(pattern[1..$]) escapeSequence;\n            const string token = pattern[0 .. escapeSequence.consumed+1];\n            const string next = pattern[escapeSequence.consumed+1 .. $];\n            alias escapeSequence.fn test;\n        }\n        else{\n            const string token = parseTextToken!(pattern);\n            static assert(token.length > 0);\n            const string next = pattern[token.length .. $];\n            alias testText!(token) test;\n        }\n\n        alias regexCompilePredicate!(test,token,next) term;\n        const string remaining = next[term.consumed .. next.length];\n\n        static if(remaining.length > 0){\n            alias testUnion!(term.fn,regexCompile!(remaining).fn,remaining) fn;\n        }\n        else{\n            alias term.fn fn;\n        }\n    }\n    else{\n        alias testEmpty!() fn;\n    }\n}\n\n/// Utility function for parsing\ntemplate isSpecial(string pattern)\n{\n    static if(\n        pattern[0] == '*' ||\n        pattern[0] == '+' ||\n        pattern[0] == '?' ||\n        pattern[0] == '.' ||\n        pattern[0] == '[' ||\n        pattern[0] == '{' ||\n        pattern[0] == '(' ||\n        pattern[0] == '$' ||\n        pattern[0] == '^' ||\n        pattern[0] == '\\\\'\n    ){\n        const bool isSpecial = true;\n    }\n    else{\n        const bool isSpecial = false;\n    }\n}\n\n\n\n\nint main()\n{\n    auto exp = &regexMatch!(r\"[a-z]*\\s*\\w*\");\n    string[] m = exp(\"hello    world\");\n    writefln(\"matches: %s\", m);\n    assert(m.length == 1);\n    assert(m[0] == \"hello    world\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/template8.d",
    "content": "// NOTE: comes from std.bitmanip\n\n// PERMUTE_ARGS:\n\nprivate string myToString(ulong n)\n{\n    return n < 10\n        ? \"\" ~ cast(char) (n + '0')\n        : myToString(n / 10) ~ myToString(n % 10);\n}\n\nprivate string toStringSfx(ulong n)\n{\n    return myToString(n) ~ (n > uint.max ? \"UL\" : \"U\");\n}\n\nprivate string CreateAccessors(\n    string store, T, string name, size_t len, size_t offset)()\n{\n    static if (!name.length)\n    {\n        // No need to create any accessor\n        return \"\";\n    }\n    else\n    {\n        static const\n            maskAllElse = ((1uL << len) - 1u) << offset,\n            maskMyself = ~maskAllElse,\n            signBitCheck = 1uL << (len - 1),\n            extendSign = ~((1uL << len) - 1);\n\n        string result;\n        static if (is(T == bool))\n        {\n            static assert(len == 1);\n            // getter\n            result ~= \"bool \" ~ name ~ \"(){ return \"\n                ~ \"(\"~store~\" & \"~toStringSfx(maskAllElse)~\") != 0;}\";\n            // setter\n            result ~= \"void \" ~ name ~ \"(bool v){\"\n                ~ \"if (v) \"~store~\" |= \"~toStringSfx(maskAllElse)~\";\"\n                ~ \"else \"~store~\" &= \"~toStringSfx(maskMyself)~\";}\";\n        }\n        else\n        {\n            // getter\n            result ~= T.stringof ~ \" \" ~ name ~ \"(){ auto result = \"\n                ~ \"(\"~store~\" & \"\n                ~ toStringSfx(maskAllElse) ~ \") >>\"\n                ~ toStringSfx(offset) ~ \";\";\n            static if (T.min < 0)\n            {\n                result ~= \"if (result >= \" ~ toStringSfx(signBitCheck)\n                    ~ \") result |= \" ~ toStringSfx(extendSign) ~ \";\";\n            }\n            result ~= \" return cast(\" ~ T.stringof ~ \") result;}\";\n            // setter\n            result ~= \"void \" ~ name ~ \"(\" ~ T.stringof\n                ~ \" v){ \"~store~\" = (\"~store~\" & \"\n                ~ toStringSfx(maskMyself) ~ \") | \"\n                ~ \"((cast(typeof(\"~store~\")) v << \" ~ toStringSfx(offset)\n                ~ \") & \" ~ toStringSfx(maskAllElse)\n                ~ \");}\";\n        }\n        return result;\n    }\n}\n\nprivate string createStoreName(Ts...)()\n{\n    static if (Ts.length == 0)\n        return \"\";\n    else\n        return Ts[1] ~ createStoreName!(Ts[3 .. $])();\n}\n\nprivate string CreateFields(string store, size_t offset, Ts...)()\n{\n    static if (!Ts.length)\n    {\n        static if (offset == ubyte.sizeof * 8)\n            return \"private ubyte \" ~ store ~ \";\";\n        else static if (offset == ushort.sizeof * 8)\n            return \"private ushort \" ~ store ~ \";\";\n        else static if (offset == uint.sizeof * 8)\n            return \"private uint \" ~ store ~ \";\";\n        else static if (offset == ulong.sizeof * 8)\n            return \"private ulong \" ~ store ~ \";\";\n        else\n            static assert(false, ToString!(offset));\n    }\n    else\n    {\n        return CreateAccessors!(store, Ts[0], Ts[1], Ts[2], offset)()\n            ~ CreateFields!(store, offset + Ts[2], Ts[3 .. $])();\n    }\n}\n\ntemplate BitFields(T...)\n{\n    //pragma(msg, CreateFields!(createStoreName!(T)(), 0, T)());\n    mixin(CreateFields!(createStoreName!(T)(), 0, T)());\n}\n\nstruct FloatRep\n{\n    mixin BitFields!(\n        uint, \"fraction\", 23,\n        uint, \"exponent\", 8,\n        bool, \"sign\", 1);\n}\n\nstruct DoubleRep\n{\n    mixin BitFields!(\n        ulong, \"fraction\", 52,\n        uint, \"exponent\", 11,\n        bool, \"sign\", 1);\n}\n\nstruct Bug2355(string x) {}\nstatic assert(is(Bug2355!\"a\" U : Bug2355!V, string V));\n\nint main()\n{\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/template9.d",
    "content": "// PERMUTE_ARGS:\n\nmodule breaker;\n\nimport core.stdc.stdio, core.vararg;\n\n/**********************************/\n\nU foo(T, U)(U i)\n{\n    return i + 1;\n}\n\nint foo(T)(int i)\n{\n    return i + 2;\n}\n\nvoid test1()\n{\n    auto i = foo!(int)(2L);\n//    assert(i == 4);    // now returns 3\n}\n\n/**********************************/\n\nU foo2(T, U)(U i)\n{\n    return i + 1;\n}\n\nvoid test2()\n{\n    auto i = foo2!(int)(2L);\n    assert(i == 3);\n}\n\n/**********************************/\n\nclass Foo3\n{\n    T bar(T,U)(U u)\n    {\n        return cast(T)u;\n    }\n}\n\nvoid test3()\n{\n  Foo3 foo = new Foo3;\n  int i = foo.bar!(int)(1.0);\n  assert(i == 1);\n}\n\n\n/**********************************/\n\nT* begin4(T)(T[] a) { return a.ptr; }\n\nvoid copy4(string pred = \"\", Ranges...)(Ranges rs)\n{\n    alias rs[$ - 1] target;\n    pragma(msg, typeof(target).stringof);\n    auto tb = begin4(target);//, te = end(target);\n}\n\nvoid test4()\n{\n    int[] a, b, c;\n    copy4(a, b, c);\n    // comment the following line to prevent compiler from crashing\n    copy4!(\"a > 1\")(a, b, c);\n}\n\n/**********************************/\n\nimport std.stdio:writefln;\n\ntemplate foo5(T,S)\n{\n    void foo5(T t, S s) {\n        writefln(\"typeof(T)=\",typeid(T),\" typeof(S)=\",typeid(S));\n    }\n}\n\ntemplate bar5(T,S)\n{\n    void bar5(S s) {\n        writefln(\"typeof(T)=\",typeid(T),\"typeof(S)=\",typeid(S));\n    }\n}\n\n\nvoid test5()\n{\n    foo5(1.0,33);\n    bar5!(double,int)(33);\n    bar5!(float)(33);\n}\n\n/**********************************/\n\nint foo6(T...)(auto ref T x)\n{   int result;\n\n    foreach (i, v; x)\n    {\n        if (v == 10)\n            assert(__traits(isRef, x[i]));\n        else\n            assert(!__traits(isRef, x[i]));\n        result += v;\n    }\n    return result;\n}\n\nvoid test6()\n{   int y = 10;\n    int r;\n    r = foo6(8);\n    assert(r == 8);\n    r = foo6(y);\n    assert(r == 10);\n    r = foo6(3, 4, y);\n    assert(r == 17);\n    r = foo6(4, 5, y);\n    assert(r == 19);\n    r = foo6(y, 6, y);\n    assert(r == 26);\n}\n\n/**********************************/\n\nauto ref min(T, U)(auto ref T lhs, auto ref U rhs)\n{\n    return lhs > rhs ? rhs : lhs;\n}\n\nvoid test7()\n{   int x = 7, y = 8;\n    int i;\n\n    i = min(4, 3);\n    assert(i == 3);\n    i = min(x, y);\n    assert(i == 7);\n    min(x, y) = 10;\n    assert(x == 10);\n    static assert(!__traits(compiles, min(3, y) = 10));\n    static assert(!__traits(compiles, min(y, 3) = 10));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5946\n\ntemplate TTest8()\n{\n    int call(){ return this.g(); }\n}\nclass CTest8\n{\n    int f() { mixin TTest8!(); return call(); }\n    int g() { return 10; }\n}\nvoid test8()\n{\n    assert((new CTest8()).f() == 10);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=693\n\ntemplate TTest9(alias sym)\n{\n    int call(){ return sym.g(); }\n}\nclass CTest9\n{\n    int f1() { mixin TTest9!(this); return call(); }\n    int f2() { mixin TTest9!this; return call(); }\n    int g() { return 10; }\n}\nvoid test9()\n{\n    assert((new CTest9()).f1() == 10);\n    assert((new CTest9()).f2() == 10);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=1780\n\ntemplate Tuple1780(Ts ...) { alias Ts Tuple1780; }\n\ntemplate Decode1780( T )                            { alias Tuple1780!() Types; }\ntemplate Decode1780( T : TT!(Us), alias TT, Us... ) { alias Us Types; }\n\nvoid test1780()\n{\n    struct S1780(T1, T2) {}\n\n    // should extract tuple (bool,short) but matches the first specialisation\n    alias Decode1780!( S1780!(bool,short) ).Types SQ1780;  // --> SQ2 is empty tuple!\n    static assert(is(SQ1780 == Tuple1780!(bool, short)));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=1659\n\nclass Foo1659 { }\nclass Bar1659 : Foo1659 { }\n\nvoid f1659(T : Foo1659)() { }\nvoid f1659(alias T)() { static assert(false); }\n\nvoid test1659()\n{\n    f1659!Bar1659();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=2025\n\nstruct S2025 {}\nvoid f2025() {}\n\ntemplate Foo2025(int i) { enum Foo2025 = 1; }\ntemplate Foo2025(TL...) { enum Foo2025 = 2; }\nstatic assert(Foo2025!1 == 1);\nstatic assert(Foo2025!int == 2);\nstatic assert(Foo2025!S2025 == 2);\nstatic assert(Foo2025!f2025 == 2);\n\ntemplate Bar2025(T)    { enum Bar2025 = 1; }\ntemplate Bar2025(A...) { enum Bar2025 = 2; }\nstatic assert(Bar2025!1 == 2);\nstatic assert(Bar2025!int == 1);    // 2 -> 1\nstatic assert(Bar2025!S2025 == 1);  // 2 -> 1\nstatic assert(Bar2025!f2025 == 2);\n\ntemplate Baz2025(T)       { enum Baz2025 = 1; }\ntemplate Baz2025(alias A) { enum Baz2025 = 2; }\nstatic assert(Baz2025!1 == 2);\nstatic assert(Baz2025!int == 1);\nstatic assert(Baz2025!S2025 == 1);  // 2 -> 1\nstatic assert(Baz2025!f2025 == 2);\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=3608\n\ntemplate foo3608(T, U){}\n\ntemplate BaseTemplate3608(alias TTT : U!V, alias U, V...)\n{\n    alias U BaseTemplate3608;\n}\ntemplate TemplateParams3608(alias T : U!V, alias U, V...)\n{\n    alias V TemplateParams3608;\n}\n\ntemplate TyueTuple3608(T...) { alias T TyueTuple3608; }\n\nvoid test3608()\n{\n    alias foo3608!(int, long) Foo3608;\n\n    static assert(__traits(isSame, BaseTemplate3608!Foo3608, foo3608));\n    static assert(is(TemplateParams3608!Foo3608 == TyueTuple3608!(int, long)));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5015\n\nimport breaker;\n\nstatic if (is(ElemType!(int))){}\n\ntemplate ElemType(T) {\n  alias _ElemType!(T).type ElemType;\n}\n\ntemplate _ElemType(T) {\n    alias r type;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5185\n\nclass C5185(V)\n{\n    void f()\n    {\n        C5185!(C5185!(int)) c;\n    }\n}\n\nvoid test5185()\n{\n    C5185!(C5185!(int)) c;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5893\n\nclass C5893\n{\n    int concatAssign(C5893 other) { return 1; }\n    int concatAssign(int other) { return 2; } // to demonstrate overloading\n\n    template opOpAssign(string op) if (op == \"~\")\n    { alias concatAssign opOpAssign; }\n\n    int opOpAssign(string op)(int other) if (op == \"+\") { return 3; }\n}\n\nvoid test5893()\n{\n    auto c = new C5893;\n    assert(c.opOpAssign!\"~\"(c) == 1); // works\n    assert(c.opOpAssign!\"~\"(1) == 2); // works\n    assert((c ~= 1) == 2);\n    assert((c += 1) == 3);  // overload\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5988\n\ntemplate Templ5988(alias T)\n{\n    alias T!int Templ5988;\n}\n\nclass C5988a(T) { Templ5988!C5988a foo; }\n//Templ5988!C5988a foo5988a;    // Commented version\nvoid test5988a() { C5988a!int a; }  // Was error, now works\n\nclass C5988b(T) { Templ5988!C5988b foo; }\nTempl5988!C5988b foo5988b;      // Uncomment version\nvoid test5988b() { C5988b!int a; }  // Works\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6404\n\n// receive only rvalue\nvoid rvalue(T)(auto ref T x) if (!__traits(isRef, x)) {}\nvoid rvalueVargs(T...)(auto ref T x) if (!__traits(isRef, x[0])) {}\n\n// receive only lvalue\nvoid lvalue(T)(auto ref T x) if ( __traits(isRef, x)) {}\nvoid lvalueVargs(T...)(auto ref T x) if ( __traits(isRef, x[0])) {}\n\nvoid test6404()\n{\n    int n;\n\n    static assert(!__traits(compiles, rvalue(n)));\n    static assert( __traits(compiles, rvalue(0)));\n\n    static assert( __traits(compiles, lvalue(n)));\n    static assert(!__traits(compiles, lvalue(0)));\n\n    static assert(!__traits(compiles, rvalueVargs(n)));\n    static assert( __traits(compiles, rvalueVargs(0)));\n\n    static assert( __traits(compiles, lvalueVargs(n)));\n    static assert(!__traits(compiles, lvalueVargs(0)));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=2246\n\nclass A2246(T,d){\n    T p;\n}\n\nclass B2246(int rk){\n    int[rk] p;\n}\n\nclass C2246(T,int rk){\n    T[rk] p;\n}\n\ntemplate f2246(T:A2246!(U,d),U,d){\n    void f2246(){ }\n}\n\ntemplate f2246(T:B2246!(rank),int rank){\n    void f2246(){ }\n}\n\ntemplate f2246(T:C2246!(U,rank),U,int rank){\n    void f2246(){ }\n}\n\nvoid test2246(){\n    A2246!(int,long) a;\n    B2246!(2) b;\n    C2246!(int,2) c;\n    f2246!(A2246!(int,long))();\n    f2246!(B2246!(2))();\n    f2246!(C2246!(int,2))();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=2296\n\nvoid foo2296(size_t D)(int[D] i...){}\nvoid test2296()\n{\n    foo2296(1, 2, 3);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=1684\n\ntemplate Test1684( uint memberOffset ){}\n\nclass MyClass1684 {\n    int flags2;\n    mixin Test1684!(cast(uint)flags2.offsetof) t1; // compiles ok\n    mixin Test1684!(cast(int)flags2.offsetof)  t2; // compiles ok\n    mixin Test1684!(flags2.offsetof)           t3; // Error: no property 'offsetof' for type 'int'\n}\n\n/**********************************/\n\nvoid bug4984a(int n)() if (n > 0 && is(typeof(bug4984a!(n-1) ()))) {\n}\n\nvoid bug4984a(int n : 0)() {\n}\n\nvoid bug4984b(U...)(U args) if ( is(typeof( bug4984b(args[1..$]) )) ) {\n}\n\nvoid bug4984b(U)(U u) {\n}\n\nvoid bug4984() {\n  // Note: compiling this overflows the stack if dmd is build with DEBUG\n  //bug4984a!400();\n    bug4984a!200();\n    bug4984b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2579\n\nvoid foo2579(T)(T delegate(in Object) dlg)\n{\n}\n\nvoid test2579()\n{\n    foo2579( (in Object o) { return 15; } );\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=2803\n\nauto foo2803(T)(T t = 0) { return t; }\n\nstruct S2803 {}\nS2803 s2803;\nref S2803 getS2803() { return s2803; }\nauto fun2803(T, U)(T t, ref U u = getS2803)\n{\n    static assert(is(U == S2803));\n    return &u;\n}\n\n// from the past version of std.conv\ntemplate to2803(T) { T to2803(S)(S src) { return T.init; } }\nauto toImpl2803a(T, S)(S s, in T left, in T sep = \", \", in T right = \"]\") {}\nauto toImpl2803b(T, S)(S s, in T left = to2803!T(S.stringof~\"(\"), in T right = \")\") {}\nauto toImpl2803c(T, S)(S s, in T left =          S.stringof~\"(\" , in T right = \")\") {}  // combination with enh 13944\n\n// from std.range.package in 2.067a.\nauto enumerate2803(En = size_t, R)(R r, En start = 0)\n{\n    // The type of 'start' should be size_t, it's the defaultArg of En,\n    // rather than the deduced type from its defualtArg '0'.\n    static assert(is(typeof(start) == size_t));\n    return start;\n}\n\n// from std.numeric.\nalias ElementType2803(R) = typeof(R.init[0].init);\nvoid normalize2803(R)(R range, ElementType2803!R sum = 1)\n{\n    // The type of 'sum' should be determined to ElementType!(double[]) == double\n    // before the type deduction from its defaultArg '1'.\n    static assert(is(typeof(sum) == double));\n}\n\nauto foo14468(T)(T[]...) { return 1; }\nauto foo14468(bool flag, T)(T[]...) { return 2; }\n\nvoid test2803()\n{\n    assert(foo2803() == 0);\n    assert(foo2803(1) == 1);\n\n    S2803 s;\n    assert(fun2803(1)    is &s2803);\n    assert(fun2803(1, s) is &s);\n\n    // regression cases\n\n    toImpl2803a!string(1, \"[\");\n\n    toImpl2803b! string(1);\n    toImpl2803b!wstring(1);\n    toImpl2803b!dstring(1);\n\n    toImpl2803c! string(1);\n    toImpl2803c!wstring(1); // requires enhancement 13944\n    toImpl2803c!dstring(1); // requires enhancement 13944\n\n    enumerate2803([1]);\n\n    double[] a = [];\n    normalize2803(a);\n\n    assert(foo14468!int() == 1);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6613\n\nalias Tuple6613(T...) = T;\n\nvoid f6613(T...)(int x = 0, T xs = Tuple6613!())\n{\n    assert(x == 0);\n    static assert(T.length == 0);\n}\n\nvoid test6613()\n{\n    f6613();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=4953\n\nvoid bug4953(T = void)(short x) {}\nstatic assert(is(typeof(bug4953(3))));\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5886\n// https://issues.dlang.org/show_bug.cgi?id=5393\n\nmixin template Foo5886(T)\n{\n    void foo(U : T, this X)() const { static assert(is(X == const K5886)); }\n}\n\nstruct K5886\n{\n    void get1(this T)() const\n    {\n        pragma(msg, T);\n    }\n    void get2(int N=4, this T)() const\n    {\n        pragma(msg, N, \" ; \", T);\n    }\n\n    mixin Foo5886!double;\n    mixin Foo5886!string;\n\n    void test() const\n    {\n        get1;       // OK\n        get2;       // OK\n        get2!8;     // NG\n\n        foo!(int);\n        foo!(typeof(null));\n    }\n}\n\nvoid test5886()\n{\n    K5886 km;\n    const(K5886) kc;\n    immutable(K5886) ki;\n\n    km.get1;        // OK\n    kc.get1;        // OK\n    ki.get1;        // OK\n    km.get2;        // OK\n    kc.get2;        // OK\n    ki.get2;        // OK\n    km.get2!(1, K5886);             // Ugly\n    kc.get2!(2, const(K5886));      // Ugly\n    ki.get2!(3, immutable(K5886));  // Ugly\n    km.get2!8;      // Error\n    kc.get2!9;      // Error\n    ki.get2!10;     // Error\n}\n\n// --------\n\nvoid test5393()\n{\n    class A\n    {\n        void opDispatch (string name, this T) () { }\n    }\n\n    class B : A {}\n\n    auto b = new B;\n    b.foobar();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5896\n\nstruct X5896\n{\n                 T opCast(T)(){ return 1; }\n           const T opCast(T)(){ return 2; }\n       immutable T opCast(T)(){ return 3; }\n          shared T opCast(T)(){ return 4; }\n    const shared T opCast(T)(){ return 5; }\n}\nvoid test5896()\n{\n    auto xm =              X5896  ();\n    auto xc =        const(X5896) ();\n    auto xi =    immutable(X5896) ();\n    auto xs =       shared(X5896) ();\n    auto xcs= const(shared(X5896))();\n    assert(cast(int)xm == 1);\n    assert(cast(int)xc == 2);\n    assert(cast(int)xi == 3);\n    assert(cast(int)xs == 4);\n    assert(cast(int)xcs== 5);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6312\n\nvoid h6312() {}\n\nclass Bla6312\n{\n    mixin wrap6312!h6312;\n}\n\nmixin template wrap6312(alias f)\n{\n    void blub(alias g = f)()\n    {\n        g();\n    }\n}\n\nvoid test6312()\n{\n    Bla6312 b = new Bla6312();\n    b.blub();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6825\n\nvoid test6825()\n{\n    struct File\n    {\n        void write(S...)(S args) {}\n    }\n\n    void dump(void delegate(string) d) {}\n\n    auto o = File();\n    dump(&o.write!string);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6789\n\ntemplate isStaticArray6789(T)\n{\n    static if (is(T U : U[N], size_t N))    // doesn't match\n    {\n        pragma(msg, \"> U = \", U, \", N:\", typeof(N), \" = \", N);\n        enum isStaticArray6789 = true;\n    }\n    else\n        enum isStaticArray6789 = false;\n}\n\nvoid test6789()\n{\n    alias int[3] T;\n    static assert(isStaticArray6789!T);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=2778\n\nstruct ArrayWrapper2778(T)\n{\n    T[] data;\n    alias data this;\n}\n\nvoid doStuffFunc2778(int[] data) {}\n\nvoid doStuffTempl2778(T)(T[] data) {}\n\nint doStuffTemplOver2778(T)(void* data) { return 1; }\nint doStuffTemplOver2778(T)(ArrayWrapper2778!T w) { return 2; }\n\nvoid test2778()\n{\n    ArrayWrapper2778!(int) foo;\n\n    doStuffFunc2778(foo);  // Works.\n\n    doStuffTempl2778!(int)(foo);  // Works.\n\n    doStuffTempl2778(foo);  // Error\n\n    assert(doStuffTemplOver2778(foo) == 2);\n}\n\n// ----\n\nvoid test2778aa()\n{\n    void foo(K, V)(V[K] aa){ pragma(msg, \"K=\", K, \", V=\", V); }\n\n    int[string] aa1;\n    foo(aa1);   // OK\n\n    struct SubTypeOf(T)\n    {\n        T val;\n        alias val this;\n    }\n    SubTypeOf!(string[char]) aa2;\n    foo(aa2);   // NG\n}\n\n// ----\n\nvoid test2778get()\n{\n    void foo(ubyte[]){}\n\n    static struct S\n    {\n        ubyte[] val = [1,2,3];\n        @property ref ubyte[] get(){ return val; }\n        alias get this;\n    }\n    S s;\n    foo(s);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6208\n\nint getRefNonref(T)(ref T s){ return 1; }\nint getRefNonref(T)(    T s){ return 2; }\n\nint getAutoRef(T)(auto ref T s){ return __traits(isRef, s) ? 1 : 2; }\n\nvoid getOut(T)(out T s){ {} }\n\nvoid getLazy1(T=int)(lazy void s){ s(), s(); }\nvoid getLazy2(T)(lazy T s){  s(), s(); }\n\nvoid test6208a()\n{\n    int lvalue;\n    int rvalue(){ int t; return t; }\n\n    assert(getRefNonref(lvalue  ) == 1);\n    assert(getRefNonref(rvalue()) == 2);\n\n    assert(getAutoRef(lvalue  ) == 1);\n    assert(getAutoRef(rvalue()) == 2);\n\n    static assert( __traits(compiles, getOut(lvalue  )));\n    static assert(!__traits(compiles, getOut(rvalue())));\n\n    int n1; getLazy1(++n1); assert(n1 == 2);\n    int n2; getLazy2(++n2); assert(n2 == 2);\n\n    struct X\n    {\n        int f(T)(auto ref T t){ return 1; }\n        int f(T)(auto ref T t, ...){ return -1; }\n    }\n    auto xm =       X ();\n    auto xc = const(X)();\n    int n;\n    assert(xm.f!int(n) == 1);   // resolved 'auto ref'\n    assert(xm.f!int(0) == 1);   // ditto\n}\n\nvoid test6208b()\n{\n    void foo(T)(const T value) if (!is(T == int)) {}\n\n    int mn;\n    const int cn;\n    static assert(!__traits(compiles, foo(mn)));    // OK -> OK\n    static assert(!__traits(compiles, foo(cn)));    // NG -> OK\n}\n\nvoid test6208c()\n{\n    struct S\n    {\n        // Original test case.\n        int foo(V)(in V v)                         { return 1; }\n        int foo(Args...)(auto ref const Args args) { return 2; }\n\n        // Reduced test cases\n\n        int hoo(V)(const V v)             { return 1; }  // typeof(10) : const V       -> MATCHconst\n        int hoo(Args...)(const Args args) { return 2; }  // typeof(10) : const Args[0] -> MATCHconst\n        // If deduction matching level is same, tuple parameter is less specialized than others.\n\n        int bar(V)(V v)                   { return 1; }  // typeof(10) : V             -> MATCHexact\n        int bar(Args...)(const Args args) { return 2; }  // typeof(10) : const Args[0] -> MATCHconst\n\n        int baz(V)(const V v)             { return 1; }  // typeof(10) : const V -> MATCHconst\n        int baz(Args...)(Args args)       { return 2; }  // typeof(10) : Args[0] -> MATCHexact\n\n        inout(int) war(V)(inout V v)            { return 1; }\n        inout(int) war(Args...)(inout Args args){ return 2; }\n\n        inout(int) waz(Args...)(inout Args args){ return 0; }   // wild deduction test\n    }\n\n    S s;\n\n    int nm = 10;\n    assert(s.foo(nm) == 1);\n    assert(s.hoo(nm) == 1);\n    assert(s.bar(nm) == 1);\n    assert(s.baz(nm) == 2);\n    assert(s.war(nm) == 1);\n    static assert(is(typeof(s.waz(nm)) == int));\n\n    const int nc = 10;\n    assert(s.foo(nc) == 1);\n    assert(s.hoo(nc) == 1);\n    assert(s.bar(nc) == 1);\n    assert(s.baz(nc) == 1);\n    assert(s.war(nc) == 1);\n    static assert(is(typeof(s.waz(nc)) == const(int)));\n\n    immutable int ni = 10;\n    assert(s.foo(ni) == 1);\n    assert(s.hoo(ni) == 1);\n    assert(s.bar(ni) == 1);\n    assert(s.baz(ni) == 2);\n    assert(s.war(ni) == 1);\n    static assert(is(typeof(s.waz(ni)) == immutable(int)));\n\n    static assert(is(typeof(s.waz(nm, nm)) == int));\n    static assert(is(typeof(s.waz(nm, nc)) == const(int)));\n    static assert(is(typeof(s.waz(nm, ni)) == const(int)));\n    static assert(is(typeof(s.waz(nc, nm)) == const(int)));\n    static assert(is(typeof(s.waz(nc, nc)) == const(int)));\n    static assert(is(typeof(s.waz(nc, ni)) == const(int)));\n    static assert(is(typeof(s.waz(ni, nm)) == const(int)));\n    static assert(is(typeof(s.waz(ni, nc)) == const(int)));\n    static assert(is(typeof(s.waz(ni, ni)) == immutable(int)));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6805\n\nstruct T6805\n{\n    template opDispatch(string name)\n    {\n        alias int Type;\n    }\n}\nstatic assert(is(T6805.xxx.Type == int));\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6738\n\nstruct Foo6738\n{\n    int _val = 10;\n\n    @property int val()() { return _val; }\n    int get() { return val; }  // fail\n}\n\nvoid test6738()\n{\n    Foo6738 foo;\n    auto x = foo.val;  // ok\n    assert(x == 10);\n    assert(foo.get() == 10);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7498\n\ntemplate IndexMixin(){\n    void insert(T)(T value){  }\n}\n\nclass MultiIndexContainer{\n    mixin IndexMixin!() index0;\n    class Index0{\n        void baburk(){\n            this.outer.index0.insert(1);\n        }\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6780\n\n@property int foo6780()(){ return 10; }\n\nint g6780;\n@property void bar6780()(int n){ g6780 = n; }\n\nvoid test6780()\n{\n    auto n = foo6780;\n    assert(n == 10);\n\n    bar6780 = 10;\n    assert(g6780 == 10);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6810\n\nint f6810(int n)(int) { return 1;}\nint f6810(U...)(U)    { assert(0); }\nint f6810(U...)(U a)  { assert(0); }\nint f6810(U...)(U)   if (true) { assert(0); }\nint f6810(U...)(U a) if (true) { assert(0); }\n\nvoid test6810()\n{\n    assert(f6810!0(0) == 1);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6891\n\nstruct S6891(int N, T)\n{\n    void f(U)(S6891!(N, U) u) { }\n}\n\nvoid test6891()\n{\n    alias S6891!(1, void) A;\n    A().f(A());\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6994\n\nstruct Foo6994\n{\n    T get(T)(){ return T.init; }\n\n    T func1(T)()\n    if (__traits(compiles, get!T()))\n    { return get!T; }\n\n    T func2(T)()\n    if (__traits(compiles, this.get!T()))   // add explicit 'this'\n    { return get!T; }\n}\nvoid test6994()\n{\n    Foo6994 foo;\n    foo.get!int();      // OK\n    foo.func1!int();    // OK\n    foo.func2!int();    // NG\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6764\n\nenum N6764 = 1; //use const for D1\n\nalias size_t[N6764] T6764; //workaround\nvoid f6764()(T6764 arr...) { }\n\nvoid g6764()(size_t[1] arr...) { }\n\nvoid h6764()(size_t[N6764] arr...) { }\n\nvoid test6764()\n{\n    f6764(0);    //good\n    g6764(0);    //good\n    h6764!()(0); //good\n    h6764(0);    //Error: template main.f() does not match any function template declaration\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=3467\n// https://issues.dlang.org/show_bug.cgi?id=6806\n\nstruct Foo3467( uint n )\n{\n    Foo3467!( n ) bar( ) {\n        typeof( return ) result;\n        return result;\n    }\n}\nstruct Vec3467(size_t N)\n{\n    void opBinary(string op:\"~\", size_t M)(Vec3467!M) {}\n}\nvoid test3467()\n{\n    Foo3467!( 4 ) baz;\n    baz = baz.bar;// FAIL\n\n    Vec3467!2 a1;\n    Vec3467!3 a2;\n    a1 ~ a2; // line 7, Error\n}\n\nstruct TS6806(size_t n) { pragma(msg, typeof(n)); }\nstatic assert(is(TS6806!(1u) == TS6806!(1)));\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=4413\n\nstruct Foo4413\n{\n    alias typeof(this) typeof_this;\n    void bar1(typeof_this other) {}\n    void bar2()(typeof_this other) {}\n    void bar3(typeof(this) other) {}\n    void bar4()(typeof(this) other) {}\n}\n\nvoid test4413()\n{\n    Foo4413 f;\n    f.bar1(f); // OK\n    f.bar2(f); // OK\n    f.bar3(f); // OK\n    f.bar4(f); // ERR\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=4675\n\ntemplate isNumeric(T)\n{\n    enum bool test1 = is(T : long);     // should be hidden\n    enum bool test2 = is(T : real);     // should be hidden\n    enum bool isNumeric = test1 || test2;\n}\nvoid test4675()\n{\n    static assert( isNumeric!int);\n    static assert(!isNumeric!string);\n    static assert(!__traits(compiles, isNumeric!int.test1));   // should be an error\n    static assert(!__traits(compiles, isNumeric!int.test2));   // should be an error\n    static assert(!__traits(compiles, isNumeric!int.isNumeric));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5525\n\ntemplate foo5525(T)\n{\n    T foo5525(T t)      { return t; }\n    T foo5525(T t, T u) { return t + u; }\n}\n\nvoid test5525()\n{\n    alias foo5525!int f;\n    assert(f(1) == 1);\n    assert(f(1, 2) == 3);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5801\n\nint a5801;\nvoid bar5801(T = double)(typeof(a5801) i) {}\nvoid baz5801(T)(typeof(a5801) i, T t) {}\nvoid test5801()\n{\n    bar5801(2);  // Does not compile.\n    baz5801(3, \"baz\"); // Does not compile.\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=5832\n\nstruct Bar5832(alias v) {}\n\ntemplate isBar5832a(T)\n{\n    static if (is(T _ : Bar5832!(v), alias v))\n        enum isBar5832a = true;\n    else\n        enum isBar5832a = false;\n}\ntemplate isBar5832b(T)\n{\n    static if (is(T _ : Bar5832!(v), alias int v))\n        enum isBar5832b = true;\n    else\n        enum isBar5832b = false;\n}\ntemplate isBar5832c(T)\n{\n    static if (is(T _ : Bar5832!(v), alias string v))\n        enum isBar5832c = true;\n    else\n        enum isBar5832c = false;\n}\nstatic assert( isBar5832a!(Bar5832!1234));\nstatic assert( isBar5832b!(Bar5832!1234));\nstatic assert(!isBar5832c!(Bar5832!1234));\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=2550\n\ntemplate pow10_2550(long n)\n{\n    const long pow10_2550 = 0;\n    static if (n < 0)\n        const long pow10_2550 = 0;\n    else\n        const long pow10_2550 = 10 * pow10_2550!(n - 1);\n}\ntemplate pow10_2550(long n:0)\n{\n    const long pow10_2550 = 1;\n}\nstatic assert(pow10_2550!(0) == 1);\n\n/**********************************/\n// [2.057] Remove top const in IFTI, 9198\n\nvoid foo10a(T   )(T)            { static assert(is(T    == const(int)[])); }\nvoid foo10b(T...)(T)            { static assert(is(T[0] == const(int)[])); }\n\n// ref parameter doesn't remove top const\nvoid boo10a(T   )(ref T)        { static assert(is(T    == const(int[]))); }\nvoid boo10b(T...)(ref T)        { static assert(is(T[0] == const(int[]))); }\n\n// auto ref with lvalue doesn't\nvoid goo10a(T   )(auto ref T)   { static assert(is(T    == const(int[]))); }\nvoid goo10b(T...)(auto ref T)   { static assert(is(T[0] == const(int[]))); }\n\n// auto ref with rvalue does\nvoid hoo10a(T   )(auto ref T)   { static assert(is(T    == const(int)[])); }\nvoid hoo10b(T...)(auto ref T)   { static assert(is(T[0] == const(int)[])); }\n\nvoid bar10a(T   )(T)            { static assert(is(T    == const(int)*)); }\nvoid bar10b(T...)(T)            { static assert(is(T[0] == const(int)*)); }\n\nvoid test10()\n{\n    const a = [1,2,3];\n    static assert(is(typeof(a) == const(int[])));\n    foo10a(a);\n    foo10b(a);\n    boo10a(a);\n    boo10b(a);\n    goo10a(a);\n    goo10b(a);\n    hoo10a(cast(const)[1,2,3]);\n    hoo10b(cast(const)[1,2,3]);\n\n    int n;\n    const p = &n;\n    static assert(is(typeof(p) == const(int*)));\n    bar10a(p);\n    bar10b(p);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=3092\n\ntemplate Foo3092(A...)\n{\n    alias A[0] Foo3092;\n}\nstatic assert(is(Foo3092!(int, \"foo\") == int));\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7037\n\nstruct Foo7037 {}\nstruct Bar7037 { Foo7037 f; alias f this; }\nvoid works7037( T )( T value ) if ( is( T : Foo7037 ) ) {}\nvoid doesnotwork7037( T : Foo7037 )( T value ) {}\n\nvoid test7037()\n{\n   Bar7037 b;\n   works7037( b );\n   doesnotwork7037( b );\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7110\n\nstruct S7110\n{\n    int opSlice(int, int) const { return 0; }\n    int opSlice()         const { return 0; }\n    int opIndex(int, int) const { return 0; }\n    int opIndex(int)      const { return 0; }\n}\n\nenum e7110 = S7110();\n\ntemplate T7110(alias a) { } // or T7110(a...)\n\nalias T7110!( S7110 ) T71100; // passes\nalias T7110!((S7110)) T71101; // passes\n\nalias T7110!( S7110()[0..0]  )  A0; // passes\nalias T7110!(  (e7110[0..0]) )  A1; // passes\nalias T7110!(   e7110[0..0]  )  A2; // passes\n\nalias T7110!( S7110()[0, 0]  ) B0; // passes\nalias T7110!(  (e7110[0, 0]) ) B1; // passes\nalias T7110!(   e7110[0, 0]  ) B2; // passes\n\nalias T7110!( S7110()[]  ) C0; // passes\nalias T7110!(  (e7110[]) ) C1; // passes\nalias T7110!(   e7110[]  ) C2; // fails: e7110 is used as a type\n\nalias T7110!( S7110()[0]  ) D0; // passes\nalias T7110!(  (e7110[0]) ) D1; // passes\nalias T7110!(   e7110[0]  ) D2; // fails: e7110 must be an array or pointer type, not S7110\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7124\n\ntemplate StaticArrayOf(T : E[dim], E, size_t dim)\n{\n    pragma(msg, \"T = \", T, \", E = \", E, \", dim = \", dim);\n    alias E[dim] StaticArrayOf;\n}\n\ntemplate DynamicArrayOf(T : E[], E)\n{\n    pragma(msg, \"T = \", T, \", E = \", E);\n    alias E[] DynamicArrayOf;\n}\n\ntemplate AssocArrayOf(T : V[K], K, V)\n{\n    pragma(msg, \"T = \", T, \", K = \", K, \", V = \", V);\n    alias V[K] AssocArrayOf;\n}\nvoid test7124()\n{\n    struct SA { int[5] sa; alias sa this; }\n    static assert(is(StaticArrayOf!SA == int[5]));\n\n    struct DA { int[] da; alias da this; }\n    static assert(is(DynamicArrayOf!DA == int[]));\n\n    struct AA { int[string] aa; alias aa this; }\n    static assert(is(AssocArrayOf!AA == int[string]));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7359\n\nbool foo7359(T)(T[] a ...)\n{\n    return true;\n}\n\nvoid test7359()\n{\n    assert(foo7359(1,1,1,1,1,1));               // OK\n    assert(foo7359(\"abc\",\"abc\",\"abc\",\"abc\"));   // NG\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7363\n\ntemplate t7363()\n{\n   enum e = 0;\n   static if (true)\n       enum t7363 = 0;\n}\nstatic assert(!__traits(compiles, t7363!().t7363 == 0)); // Assertion fails\nstatic assert(t7363!() == 0); // Error: void has no value\n\ntemplate u7363()\n{\n   static if (true)\n   {\n       enum e = 0;\n       enum u73631 = 0;\n   }\n   alias u73631 u7363;\n}\nstatic assert(!__traits(compiles, u7363!().u7363 == 0)); // Assertion fails\nstatic assert(u7363!() == 0); // Error: void has no value\n\n/**********************************/\n\nstruct S4371(T ...) { }\n\nalias S4371!(\"hi!\") t;\n\nstatic if (is(t U == S4371!(U))) { }\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7416\n\nvoid t7416(alias a)() if(is(typeof(a())))\n{}\n\nvoid test7416() {\n    void f() {}\n    alias t7416!f x;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7563\n\nclass Test7563\n{\n    void test(T, bool a = true)(T t)\n    {\n\n    }\n}\n\nvoid test7563()\n{\n    auto test = new Test7563;\n    pragma(msg, typeof(test.test!(int, true)).stringof);\n    pragma(msg, typeof(test.test!(int)).stringof); // Error: expression (test.test!(int)) has no type\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7572\n\nclass F7572\n{\n    Tr fn7572(Tr, T...)(T t) { return 1; }\n}\nTr Fn7572(Tr, T...)(T t) { return 2; }\n\nvoid test7572()\n{\n    F7572 f = new F7572();\n    int delegate() dg = &f.fn7572!int;\n    assert(dg() == 1);\n\n    int function() fn = &Fn7572!int;\n    assert(fn() == 2);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7580\n\nstruct S7580(T)\n{\n    void opAssign()(T value) {}\n}\nstruct X7580(T)\n{\n    private T val;\n    @property ref inout(T) get()() inout { return val; }    // template\n    alias get this;\n}\nstruct Y7580(T)\n{\n    private T val;\n    @property ref auto get()() inout { return val; }        // template + auto return\n    alias get this;\n}\n\nvoid test7580()\n{\n    S7580!(int) s;\n    X7580!int x;\n    Y7580!int y;\n    s = x;\n    s = y;\n\n    shared(X7580!int) sx;\n    static assert(!__traits(compiles, s = sx));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7585\n\nextern(C) alias void function() Callback;\n\ntemplate W7585a(alias dg)\n{\n    //pragma(msg, typeof(dg));\n    extern(C) void W7585a() { dg(); }\n}\n\nvoid test7585()\n{\n    static void f7585a(){}\n    Callback cb1 = &W7585a!(f7585a);      // OK\n    static assert(!__traits(compiles,\n    {\n        void f7585b(){}\n        Callback cb2 = &W7585a!(f7585b);  // NG\n    }));\n\n    Callback cb3 = &W7585a!((){});              // NG -> OK\n    Callback cb4 = &W7585a!(function(){});      // OK\n    static assert(!__traits(compiles,\n    {\n        Callback cb5 = &W7585a!(delegate(){});  // NG\n    }));\n\n    static int global;  // global data\n    Callback cb6 = &W7585a!((){return global;});    // NG -> OK\n    static assert(!__traits(compiles,\n    {\n        int n;\n        Callback cb7 = &W7585a!((){return n;});     // NG\n    }));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7643\n\ntemplate T7643(A...){ alias A T7643; }\n\nalias T7643!(long, \"x\", string, \"y\") Specs7643;\n\nalias T7643!( Specs7643[] ) U7643;  // Error: tuple A is used as a type\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7671\n\n       inout(int)[3]  id7671n1             ( inout(int)[3] );\n       inout( U )[n]  id7671x1(U, size_t n)( inout( U )[n] );\n\nshared(inout int)[3]  id7671n2             ( shared(inout int)[3] );\nshared(inout  U )[n]  id7671x2(U, size_t n)( shared(inout  U )[n] );\n\nvoid test7671()\n{\n    static assert(is( typeof( id7671n1( (immutable(int)[3]).init ) ) == immutable(int[3]) ));\n    static assert(is( typeof( id7671x1( (immutable(int)[3]).init ) ) == immutable(int[3]) ));\n\n    static assert(is( typeof( id7671n2( (immutable(int)[3]).init ) ) == immutable(int[3]) ));\n    static assert(is( typeof( id7671x2( (immutable(int)[3]).init ) ) == immutable(int[3]) ));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7672\n\nT foo7672(T)(T a){ return a; }\n\nvoid test7672(inout(int[]) a = null, inout(int*) p = null)\n{\n    static assert(is( typeof(        a ) == inout(int[]) ));\n    static assert(is( typeof(foo7672(a)) == inout(int)[] ));\n\n    static assert(is( typeof(        p ) == inout(int*) ));\n    static assert(is( typeof(foo7672(p)) == inout(int)* ));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7684\n\n       U[]  id7684(U)(        U[]  );\nshared(U[]) id7684(U)( shared(U[]) );\n\nvoid test7684()\n{\n    shared(int)[] x;\n    static assert(is( typeof(id7684(x)) == shared(int)[] ));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7694\n\nvoid match7694(alias m)()\n{\n    m.foo();    //removing this line suppresses ice in both cases\n}\n\nstruct T7694\n{\n    void foo(){}\n    void bootstrap()\n    {\n    //next line causes ice\n        match7694!(this)();\n    //while this works:\n        alias this p;\n        match7694!(p)();\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7755\n\ntemplate to7755(T)\n{\n    T to7755(A...)(A args)\n    {\n        return toImpl7755!T(args);\n    }\n}\n\nT toImpl7755(T, S)(S value)\n{\n    return T.init;\n}\n\ntemplate Foo7755(T){}\n\nstruct Bar7755\n{\n    void qux()\n    {\n        if (is(typeof(to7755!string(Foo7755!int)))){}\n    }\n}\n\n/**********************************/\n\n             U[]   id11a(U)(              U[]   );\n       inout(U)[]  id11a(U)(        inout(U)[]  );\n       inout(U[])  id11a(U)(        inout(U[])  );\ninout(shared(U[])) id11a(U)( inout(shared(U[])) );\n\nvoid test11a(inout int _ = 0)\n{\n    shared(const(int))[] x;\n    static assert(is( typeof(id11a(x)) == shared(const(int))[] ));\n\n    shared(int)[] y;\n    static assert(is( typeof(id11a(y)) == shared(int)[] ));\n\n    inout(U)[n] idz(U, size_t n)( inout(U)[n] );\n\n    inout(shared(bool[1])) z;\n    static assert(is( typeof(idz(z)) == inout(shared(bool[1])) ));\n}\n\ninout(U[]) id11b(U)( inout(U[]) );\n\nvoid test11b()\n{\n    alias const(shared(int)[]) T;\n    static assert(is(typeof(id11b(T.init)) == const(shared(int)[])));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7769\n\nvoid f7769(K)(inout(K) value){}\nvoid test7769()\n{\n    f7769(\"abc\");\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7812\n\ntemplate A7812(T...) {}\n\ntemplate B7812(alias C) if (C) {}\n\ntemplate D7812()\n{\n    alias B7812!(A7812!(NonExistent!())) D7812;\n}\n\nstatic assert(!__traits(compiles, D7812!()));\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7873\n\ninout(T)* foo(T)(inout(T)* t)\n{\n    static assert(is(T == int*));\n    return t;\n}\n\ninout(T)* bar(T)(inout(T)* t)\n{\n    return foo(t);\n}\n\nvoid test7873()\n{\n    int *i;\n    bar(&i);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7933\n\nstruct Boo7933(size_t dim){int a;}\nstruct Baa7933(size_t dim)\n{\n    Boo7933!dim a;\n    //Boo7933!1 a; //(1) This version causes no errors\n}\n\nauto foo7933()(Boo7933!1 b){return b;}\n//auto fuu7933(Boo7933!1 b){return b;} //(2) This line neutralizes the error\n\nvoid test7933()\n{\n    Baa7933!1 a; //(3) This line causes the error message\n    auto b = foo7933(Boo7933!1(1));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8094\n\nstruct Tuple8094(T...) {}\n\ntemplate getParameters8094(T, alias P)\n{\n    static if (is(T t == P!U, U...))\n        alias U getParameters8094;\n    else\n        static assert(false);\n}\n\nvoid test8094()\n{\n    alias getParameters8094!(Tuple8094!(int, string), Tuple8094) args;\n}\n\n/**********************************/\n\nstruct Tuple12(T...)\n{\n    void foo(alias P)()\n    {\n        alias Tuple12 X;\n        static if (is(typeof(this) t == X!U, U...))\n            alias U getParameters;\n        else\n            static assert(false);\n    }\n}\n\nvoid test12()\n{\n    Tuple12!(int, string) t;\n    t.foo!Tuple12();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=14290\n\nstruct Foo14290(int i) {}\nalias Foo14290a = Foo14290!1;\nstatic assert(!is(Foo14290!2 == Foo14290a!T, T...));\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8125\n\nvoid foo8125(){}\n\nstruct X8125(alias a) {}\n\ntemplate Y8125a(T : A!f, alias A, alias f) {}  //OK\ntemplate Y8125b(T : A!foo8125, alias A) {}     //NG\n\nvoid test8125()\n{\n    alias Y8125a!(X8125!foo8125) y1;\n    alias Y8125b!(X8125!foo8125) y2;\n}\n\n/**********************************/\n\nstruct A13() {}\nstruct B13(TT...) {}\nstruct C13(T1) {}\nstruct D13(T1, TT...) {}\nstruct E13(T1, T2) {}\nstruct F13(T1, T2, TT...) {}\n\ntemplate Test13(alias X)\n{\n    static if (is(X x : P!U, alias P, U...))\n        enum Test13 = true;\n    else\n        enum Test13 = false;\n}\n\nvoid test13()\n{\n    static assert(Test13!( A13!() ));\n    static assert(Test13!( B13!(int) ));\n    static assert(Test13!( B13!(int, double) ));\n    static assert(Test13!( B13!(int, double, string) ));\n    static assert(Test13!( C13!(int) ));\n    static assert(Test13!( D13!(int) ));\n    static assert(Test13!( D13!(int, double) ));\n    static assert(Test13!( D13!(int, double, string) ));\n    static assert(Test13!( E13!(int, double) ));\n    static assert(Test13!( F13!(int, double) ));\n    static assert(Test13!( F13!(int, double, string) ));\n    static assert(Test13!( F13!(int, double, string, bool) ));\n}\n\n/**********************************/\n\nstruct A14(T, U, int n = 1)\n{\n}\n\ntemplate Test14(alias X)\n{\n    static if (is(X x : P!U, alias P, U...))\n        alias U Test14;\n    else\n        static assert(0);\n}\n\nvoid test14()\n{\n    alias A14!(int, double) Type;\n    alias Test14!Type Params;\n    static assert(Params.length == 3);\n    static assert(is(Params[0] == int));\n    static assert(is(Params[1] == double));\n    static assert(   Params[2] == 1);\n}\n\n/**********************************/\n// test for evaluateConstraint assertion\n\nbool canSearchInCodeUnits15(C)(dchar c)\nif (is(C == char))\n{\n    return true;\n}\n\nvoid test15()\n{\n    int needle = 0;\n    auto b = canSearchInCodeUnits15!char(needle);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8129\n\nclass X8129 {}\nclass A8129 {}\nclass B8129 : A8129 {}\n\nint foo8129(T : A8129)(X8129 x) { return 1; }\nint foo8129(T : A8129)(X8129 x, void function (T) block) { return 2; }\n\nint bar8129(T, R)(R range, T value) { return 1; }\n\nint baz8129(T, R)(R range, T value) { return 1; }\nint baz8129(T, R)(R range, Undefined value) { return 2; }\n\nvoid test8129()\n{\n    auto x = new X8129;\n    assert(x.foo8129!B8129()      == 1);\n    assert(x.foo8129!B8129((a){}) == 2);\n    assert(foo8129!B8129(x)        == 1);\n    assert(foo8129!B8129(x, (a){}) == 2);\n    assert(foo8129!B8129(x)              == 1);\n    assert(foo8129!B8129(x, (B8129 b){}) == 2);\n\n    ubyte[] buffer = [0, 1, 2];\n    assert(bar8129!ushort(buffer, 915) == 1);\n\n    // While deduction, parameter type 'Undefined' shows semantic error.\n    static assert(!__traits(compiles, {\n        baz8129!ushort(buffer, 915);\n    }));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8238\n\nvoid test8238()\n{\n    static struct S { template t(){ int t; } }\n\n    S s1, s2;\n    assert(cast(void*)&s1      != cast(void*)&s2     );\n    assert(cast(void*)&s1      != cast(void*)&s1.t!());\n    assert(cast(void*)&s2      != cast(void*)&s2.t!());\n    assert(cast(void*)&s1.t!() == cast(void*)&s2.t!());\n    s1.t!() = 256;\n    assert(s2.t!() == 256);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8669\n\nstruct X8669\n{\n    void mfoo(this T)()\n    {\n        static assert(is(typeof(this) == T));\n    }\n    void cfoo(this T)() const\n    {\n        static assert(is(typeof(this) == const(T)));\n    }\n    void sfoo(this T)() shared\n    {\n        static assert(is(typeof(this) == shared(T)));\n    }\n    void scfoo(this T)() shared const\n    {\n        static assert(is(typeof(this) == shared(const(T))));\n    }\n    void ifoo(this T)() immutable\n    {\n        static assert(is(typeof(this) == immutable(T)));\n    }\n}\n\nvoid test8669()\n{\n                 X8669 mx;\n           const X8669 cx;\n      immutable  X8669 ix;\n          shared X8669 sx;\n    shared const X8669 scx;\n\n     mx.mfoo();\n     cx.mfoo();\n     ix.mfoo();\n     sx.mfoo();\n    scx.mfoo();\n\n     mx.cfoo();\n     cx.cfoo();\n     ix.cfoo();\n     sx.cfoo();\n    scx.cfoo();\n\n    static assert(!is(typeof(  mx.sfoo() )));\n    static assert(!is(typeof(  cx.sfoo() )));\n     ix.sfoo();\n     sx.sfoo();\n    scx.sfoo();\n\n    static assert(!is(typeof(  mx.scfoo() )));\n    static assert(!is(typeof(  cx.scfoo() )));\n     ix.scfoo();\n     sx.scfoo();\n    scx.scfoo();\n\n    static assert(!is(typeof(  mx.ifoo() )));\n    static assert(!is(typeof(  cx.ifoo() )));\n     ix.ifoo();\n    static assert(!is(typeof(  sx.ifoo() )));\n    static assert(!is(typeof( scx.ifoo() )));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8833\n\ntemplate TypeTuple8833(T...) { alias TypeTuple = T; }\n\nvoid func8833(alias arg)() { }\n\nvoid test8833()\n{\n    int x, y;\n\n    alias TypeTuple8833!(\n        func8833!(x),\n        func8833!(y),\n    ) Map;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=8976\n\nvoid f8976(ref int) { }\n\nvoid g8976()()\n{\n    f8976(0); // line 5\n}\n\n\nvoid h8976()()\n{\n    g8976!()();\n}\n\nstatic assert(! __traits(compiles, h8976!()() ) ); // causes error\nstatic assert(!is(typeof(          h8976!()() )));\n\nvoid test8976()\n{\n    static assert(! __traits(compiles, h8976!()() ) );\n    static assert(!is(typeof(          h8976!()() )));\n}\n\n/****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8940\n\nconst int n8940; // or `immutable`\nstatic this() { n8940 = 3; }\n\nvoid f8940(T)(ref int val)\n{\n    assert(val == 3);\n    ++val;\n}\n\nstatic assert(!__traits(compiles,  f8940!void(n8940))); // fails\nvoid test8940()\n{\n    assert(n8940 == 3);\n    static assert(!__traits(compiles, f8940!void(n8940)));\n    //assert(n8940 == 3); // may pass as compiler caches comparison result\n    //assert(n8940 != 4); // may pass but likely will fail\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=6969\n// https://issues.dlang.org/show_bug.cgi?id=8990\n\nclass A6969() { alias C6969!() C1; }\nclass B6969   { alias A6969!() A1; }\nclass C6969() : B6969 {}\n\nstruct A8990(T) { T t; }\nstruct B8990(T) { A8990!T* a; }\nstruct C8990    { B8990!C8990* b; }\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9018\n\ntemplate Inst9018(alias Template, T)\n{\n    alias Template!T Inst;\n}\n\ntemplate Template9018(T)\n{\n    enum Template9018 = T;\n}\n\nstatic assert(!__traits(compiles, Inst9018!(Template9018, int))); // Assert passes\nstatic assert(!__traits(compiles, Inst9018!(Template9018, int))); // Assert fails\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9022\n\nclass C9022\n{\n    struct X {}\n\n    alias B = X;\n}\nclass D9022\n{\n    struct X {}\n}\n\nvoid test9022()\n{\n    auto c = new C9022();\n    auto d = new D9022();\n    auto cx = C9022.X();\n    auto dx = D9022.X();\n\n    void foo1(T)(T, T.X) { static assert(is(T == C9022)); }\n    void foo2(T)(T.X, T) { static assert(is(T == C9022)); }\n    foo1(c, cx);\n    foo2(cx, c);\n\n    void hoo1(T)(T, T.B) { static assert(is(T == C9022)); }\n    void hoo2(T)(T.B, T) { static assert(is(T == C9022)); }\n    hoo1(c, cx);\n    hoo1(c, cx);\n\n    void bar1(alias A)(A.C9022, A.D9022) { static assert(A.stringof == \"module breaker\"); }\n    void bar2(alias A)(A.D9022, A.C9022) { static assert(A.stringof == \"module breaker\"); }\n    bar1(c, d);\n    bar2(d, c);\n\n    void var1(alias A)(A.C9022, A.D9022.X) { static assert(A.stringof == \"module breaker\"); }\n    void var2(alias A)(A.D9022.X, A.C9022) { static assert(A.stringof == \"module breaker\"); }\n    var1(c, dx);\n    var2(dx, c);\n\n    void baz(T)(T.X t, T.X u) { }\n    static assert(!__traits(compiles, baz(cx, dx)));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9026\n\nmixin template node9026()\n{\n    static if (is(this == struct))\n        alias typeof(this)* E;\n    else\n        alias typeof(this) E;\n    E prev, next;\n}\n\nstruct list9026(alias N)\n{\n    N.E head;\n    N.E tail;\n}\n\nclass A9026\n{\n    mixin node9026 L1;\n    mixin node9026 L2;\n}\n\nlist9026!(A9026.L1) g9026_l1;\nlist9026!(A9026.L2) g9026_l2;\n\nvoid test9026()\n{\n    list9026!(A9026.L1) l9026_l1;\n    list9026!(A9026.L2) l9026_l2;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9038\n\nmixin template Foo9038()\n{\n    string data = \"default\";\n}\n\nclass Bar9038\n{\n    string data;\n    mixin Foo9038 f;\n}\n\nvoid check_data9038(alias M, T)(T obj)\n{\n    //writeln(M.stringof);\n    assert(obj.data == \"Bar\");\n    assert(obj.f.data == \"F\");\n}\n\nvoid test9038()\n{\n    auto bar = new Bar9038;\n    bar.data = \"Bar\";\n    bar.f.data = \"F\";\n\n    assert(bar.data == \"Bar\");\n    assert(bar.f.data == \"F\");\n\n    check_data9038!(Bar9038)(bar);\n    check_data9038!(Bar9038.f)(bar);\n    check_data9038!(bar.f)(bar);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9050\n\nstruct A9050(T) {}\n\nstruct B9050(T)\n{\n    void f() { foo9050(A9050!int()); }\n}\n\nauto foo9050()(A9050!int base) pure\n{\n    return B9050!int();\n}\n\nauto s9050 = foo9050(A9050!int());\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10936 (dup of 9050)\n\nstruct Vec10936(string s)\n{\n    auto foo(string v)()\n    {\n        return Vec10936!(v)();\n    }\n\n    static void bar()\n    {\n        Vec10936!\"\" v;\n        auto p = v.foo!\"sup\";\n    }\n}\n\nVec10936!\"\" v;\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9076\n\ntemplate forward9076(args...)\n{\n    @property forward9076()(){ return args[0]; }\n}\n\nvoid test9076()\n{\n    int a = 1;\n    int b = 1;\n    assert(a == forward9076!b);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9083\n\ntemplate isFunction9083(X...) if (X.length == 1)\n{\n    enum isFunction9083 = true;\n}\n\nstruct S9083\n{\n    static string func(alias Class)()\n    {\n        foreach (m; __traits(allMembers, Class))\n        {\n            pragma(msg, m);  // prints \"func\"\n            enum x1 = isFunction9083!(mixin(m));  //NG\n            enum x2 = isFunction9083!(func);      //OK\n        }\n        return \"\";\n    }\n}\nenum nothing9083 = S9083.func!S9083();\n\nclass C9083\n{\n    int x;  // some class members\n\n    void func()\n    {\n        void templateFunc(T)(const T obj)\n        {\n            enum x1 = isFunction9083!(mixin(\"x\"));  // NG\n            enum x2 = isFunction9083!(x);           // NG\n        }\n        templateFunc(this);\n    }\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9100\n\ntemplate Id(alias A) { alias Id = A; }\ntemplate ErrId(alias A) { static assert(0); }\ntemplate TypeTuple9100(TL...) { alias TypeTuple9100 = TL; }\n\nclass C9100\n{\n    int value;\n\n    int fun() { return value; }\n    int tfun(T)() { return value; }\n    TypeTuple9100!(int, long) field;\n\n    void test()\n    {\n        this.value = 1;\n        auto c = new C9100();\n        c.value = 2;\n\n        alias t1a = Id!(c.fun);             // OK\n        alias t1b = Id!(this.fun);          // Prints weird error, bad\n        // -> internally given TOKdotvar\n        assert(t1a() == this.value);\n        assert(t1b() == this.value);\n\n        alias t2a = Id!(c.tfun);            // OK\n        static assert(!__traits(compiles, ErrId!(this.tfun)));\n        alias t2b = Id!(this.tfun);         // No error occurs, why?\n        // -> internally given TOKdottd\n        assert(t2a!int() == this.value);\n        assert(t2b!int() == this.value);\n\n        alias t3a = Id!(foo9100);           // OK\n        alias t3b = Id!(mixin(\"foo9100\"));  // Prints weird error, bad\n        // -> internally given TOKtemplate\n        assert(t3a() == 10);\n        assert(t3b() == 10);\n\n        assert(field[0] == 0);\n        alias t4a = TypeTuple9100!(field);              // NG\n        alias t4b = TypeTuple9100!(GetField9100!());    // NG\n        t4a[0] = 1; assert(field[0] == 1);\n        t4b[0] = 2; assert(field[0] == 2);\n    }\n}\n\nint foo9100()() { return 10; }\ntemplate GetField9100() { alias GetField9100 = C9100.field[0]; }\n\nvoid test9100()\n{\n    (new C9100()).test();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9101\n\nclass Node9101\n{\n    template ForwardCtorNoId()\n    {\n        this() {} // default constructor\n        void foo() { 0 = 1; }    // wrong code\n    }\n}\nenum x9101 = __traits(compiles, Node9101.ForwardCtorNoId!());\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9124\n\nstruct Foo9124a(N...)\n{\n    enum SIZE = N[0];\n    private int _val;\n\n    public void opAssign (T) (T other)\n    if (is(T unused == Foo9124a!(_N), _N...))\n    {\n        _val = other._val;          // compile error\n        this._val = other._val;     // explicit this make it work\n    }\n\n    public auto opUnary (string op) () if (op == \"~\") {\n        Foo9124a!(SIZE) result = this;\n        return result;\n    }\n}\nvoid test9124a()\n{\n    Foo9124a!(28) a;\n    Foo9124a!(28) b = ~a;\n}\n\n// --------\n\ntemplate Foo9124b(T, U, string OP)\n{\n    enum N = T.SIZE;\n    alias Foo9124b = Foo9124b!(false, true, N);\n}\nstruct Foo9124b(bool S, bool L, N...)\n{\n    enum SIZE = 5;\n    long[1] _a = 0;\n    void someFunction() const {\n        auto data1 = _a;        // Does not compile\n        auto data2 = this._a;   // <--- Compiles\n    }\n    auto opBinary(string op, T)(T) {\n        Foo9124b!(typeof(this), T, op) test;\n    }\n}\nvoid test9124b()\n{\n    auto p = Foo9124b!(false, false, 5)();\n    auto q = Foo9124b!(false, false, 5)();\n    p|q;\n    p&q;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9143\n\nstruct Foo9143a(bool S, bool L)\n{\n    auto noCall() {\n        Foo9143a!(S, false) x1;         // compiles if this line commented\n        static if(S) Foo9143a!(true,  false) x2;\n        else         Foo9143a!(false, false) x2;\n    }\n    this(T)(T other)        // constructor\n    if (is(T unused == Foo9143a!(P, Q), bool P, bool Q)) { }\n}\n\nstruct Foo9143b(bool L, size_t N)\n{\n    void baaz0() {\n        bar!(Foo9143b!(false, N))();    // line 7\n        // -> move to before the baaz semantic\n    }\n    void baaz() {\n        bar!(Foo9143b!(false, 2LU))();  // line 3\n        bar!(Foo9143b!(true, 2LU))();   // line 4\n        bar!(Foo9143b!(L, N))();        // line 5\n        bar!(Foo9143b!(true, N))();     // line 6\n        bar!(Foo9143b!(false, N))();    // line 7\n    }\n    void bar(T)()\n    if (is(T unused == Foo9143b!(_L, _N), bool _L, size_t _N))\n    {}\n}\n\nvoid test9143()\n{\n    Foo9143a!(false, true) k = Foo9143a!(false, false)();\n\n    auto p = Foo9143b!(true, 2LU)();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9266\n\ntemplate Foo9266(T...)\n{\n    T Foo9266;\n}\nstruct Bar9266()\n{\n    alias Foo9266!int f;\n}\nvoid test9266()\n{\n    Bar9266!() a, b;\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9361\n\nstruct Unit9361(A)\n{\n    void butPleaseDontUseMe()()\n    if (is(unitType9361!((this))))  // !\n    {}\n\n}\ntemplate isUnit9361(alias T) if ( is(T)) {}\ntemplate isUnit9361(alias T) if (!is(T)) {}\n\ntemplate unitType9361(alias T) if (isUnit9361!T) {}\n\nvoid test9361()\n{\n    Unit9361!int u;\n    static assert(!__traits(compiles, u.butPleaseDontUseMe())); // crashes\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9536\n\nstruct S9536\n{\n    static A foo(A)(A a)\n    {\n        return a * 2;\n    }\n    int bar() const\n    {\n        return foo(42);\n    }\n}\n\nvoid test9536()\n{\n    S9536 s;\n    assert(s.bar() == 84);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9578\n\ntemplate t9578(alias f) { void tf()() { f(); } }\n\nvoid g9578a(alias f)()  { f(); }        // Error -> OK\nvoid g9578b(alias ti)() { ti.tf(); }    // Error -> OK\n\nvoid test9578()\n{\n    int i = 0;\n    int m() { return i; }\n\n    g9578a!(t9578!m.tf)();\n    g9578b!(t9578!m)();\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9596\n\nint foo9596a(K, V)(inout(       V  [K])) { return 1; }\nint foo9596a(K, V)(inout(shared(V) [K])) { return 2; }\n\nint foo9596b(K, V)(inout(       V  [K])) { return 1; }\nint foo9596b(K, V)(inout( const(V) [K])) { return 3; }\n\nint foo9596c(K, V)(inout(shared(V) [K])) { return 2; }\nint foo9596c(K, V)(inout( const(V) [K])) { return 3; }\n\nint foo9596d(K, V)(inout(       V  [K])) { return 1; }\nint foo9596d(K, V)(inout(shared(V) [K])) { return 2; }\nint foo9596d(K, V)(inout( const(V) [K])) { return 3; }\n\nint foo9596e(K, V)(inout(shared(V) [K])) { return 2; }\nint foo9596e(K, V)(inout(       V  [K])) { return 1; }\nint foo9596e(K, V)(inout( const(V) [K])) { return 3; }\n\nvoid test9596()\n{\n    shared(int)[int] aa;\n    static assert(!__traits(compiles, foo9596a(aa)));\n\n    assert(foo9596b(aa) == 1);\n    assert(foo9596c(aa) == 2);\n\n    static assert(!__traits(compiles, foo9596d(aa)));\n    static assert(!__traits(compiles, foo9596e(aa)));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9806\n\nstruct S9806a(alias x)\n{\n    alias S9806a!0 N;\n}\nenum expr9806a = 0 * 0;\nalias S9806a!expr9806a T9806a;\n\n// --------\n\nstruct S9806b(alias x)\n{\n    template Next()\n    {\n        enum expr = x + 1;\n        alias S9806b!expr Next;\n    }\n}\nalias S9806b!1 One9806b;\nalias S9806b!0.Next!() OneAgain9806b;\n\n// --------\n\nstruct S9806c(x...)\n{\n    template Next()\n    {\n        enum expr = x[0] + 1;\n        alias S9806c!expr Next;\n    }\n}\nalias S9806c!1 One9806c;\nalias S9806c!0.Next!() OneAgain9806c;\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9837\n\nvoid test9837()\n{\n    enum DA : int[] { a = [1,2,3] }\n    DA da;\n    int[] bda = da;\n    static assert(is(DA : int[]));\n    void fda1(int[] a) {}\n    void fda2(T)(T[] a) {}\n    fda1(da);\n    fda2(da);\n\n    enum SA : int[3] { a = [1,2,3] }\n    SA sa;\n    int[3] bsa = sa;\n    static assert(is(SA : int[3]));\n    void fsa1(int[3] a) {}\n    void fsa2(T)(T[3] a) {}\n    void fsa3(size_t d)(int[d] a) {}\n    void fsa4(T, size_t d)(T[d] a) {}\n    fsa1(sa);\n    fsa2(sa);\n    fsa3(sa);\n    fsa4(sa);\n\n    enum AA : int[int] { a = null }\n    AA aa;\n    int[int] baa = aa;\n    static assert(is(AA : int[int]));\n    void faa1(int[int] a) {}\n    void faa2(V)(V[int] a) {}\n    void faa3(K)(int[K] a) {}\n    void faa4(K, V)(V[K] a) {}\n    faa1(aa);\n    faa2(aa);\n    faa3(aa);\n    faa4(aa);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9874\n\nbool foo9874() { return true; }\nvoid bar9874(T)(T) if (foo9874()) {} // OK\nvoid baz9874(T)(T) if (foo9874)   {} // error\n\nvoid test9874()\n{\n    foo9874;                      // OK\n    bar9874(0);\n    baz9874(0);\n}\n\n/******************************************/\n\nvoid test9885()\n{\n    void foo(int[1][]) {}\n    void boo()(int[1][]){}\n    struct X(T...) { static void xoo(T){} }\n    struct Y(T...) { static void yoo()(T){} }\n    struct Z(T...) { static void zoo(U...)(T, U){} }\n\n    struct V(T...) { static void voo()(T, ...){} }\n    struct W(T...) { static void woo()(T...){} }\n\n    struct R(T...) { static void roo(U...)(int, U, T){} }\n\n    // OK\n    foo([[10]]);\n    boo([[10]]);\n\n    // OK\n    X!(int[1][]).xoo([[10]]);\n\n    // NG!\n    Y!().yoo();\n    Y!(int).yoo(1);\n    Y!(int, int[]).yoo(1, [10]);\n    static assert(!__traits(compiles, Y!().yoo(1)));\n    static assert(!__traits(compiles, Y!(int).yoo(\"a\")));\n    static assert(!__traits(compiles, Y!().yoo!(int)()));\n\n    // NG!\n    Z!().zoo();\n    Z!().zoo([1], [1:1]);\n    Z!(int, string).zoo(1, \"a\");\n    Z!(int, string).zoo(1, \"a\", [1], [1:1]);\n    Z!().zoo!()();\n    static assert(!__traits(compiles, Z!().zoo!()(1)));     // (none) <- 1\n    static assert(!__traits(compiles, Z!(int).zoo!()()));   // int <- (none)\n    static assert(!__traits(compiles, Z!(int).zoo!()(\"\"))); // int <- \"\"\n    static assert(!__traits(compiles, Z!().zoo!(int)()));   // int <- (none)\n    static assert(!__traits(compiles, Z!().zoo!(int)(\"\"))); // int <- \"\"\n\n    V!().voo(1,2,3);\n    V!(int).voo(1,2,3);\n    V!(int, long).voo(1,2,3);\n    static assert(!__traits(compiles, V!(int).voo()));          // int <- (none)\n    static assert(!__traits(compiles, V!(int, long).voo(1)));       // long <- (none)\n    static assert(!__traits(compiles, V!(int, string).voo(1,2,3)));     // string <- 2\n\n    W!().woo();\n    //W!().woo(1, 2, 3);    // Access Violation\n    {   // this behavior is consistent with:\n        //alias TL = TypeTuple!();\n        //void foo(TL...) {}\n        //foo(1, 2, 3);     // Access Violation\n        //pragma(msg, typeof(foo));   // void(...)  -> D-style variadic function?\n    }\n    W!(int,int[]).woo(1,2,3);\n    W!(int,int[2]).woo(1,2,3);\n    static assert(!__traits(compiles, W!(int,int,int).woo(1,2,3)));     // int... <- 2\n    static assert(!__traits(compiles, W!(int,int).woo(1,2)));           // int... <- 2\n    static assert(!__traits(compiles, W!(int,int[2]).woo(1,2)));    // int[2]... <- 2\n\n    R!().roo(1, \"\", []);\n    R!(int).roo(1, \"\", [], 1);\n    R!(int, string).roo(1, \"\", [], 1, \"\");\n    R!(int, string).roo(1, 2, \"\");\n    static assert(!__traits(compiles, R!(int).roo(1, \"\", []))); // int <- []\n    static assert(!__traits(compiles, R!(int, int).roo(1, \"\", [])));    // int <- []\n    static assert(!__traits(compiles, R!(int, string).roo(1, 2, 3)));   // string <- 3\n\n    // test case\n    struct Tuple(T...) { this()(T values) {} }\n    alias T = Tuple!(int[1][]);\n    auto t = T([[10]]);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9971\n\nvoid goo9971()()\n{\n    auto g = &goo9971;\n}\n\nstruct S9971\n{\n    void goo()()\n    {\n        auto g = &goo;\n        static assert(is(typeof(g) == delegate));\n    }\n}\n\nvoid test9971()\n{\n    goo9971!()();\n\n    S9971.init.goo!()();\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9977\n\nvoid test9977()\n{\n    struct S1(T) { T value; }\n    auto func1(T)(T value) { return value; }\n    static assert(is(S1!int == struct));\n    assert(func1(10) == 10);\n\n    template S2(T) { struct S2 { T value; } }\n    template func2(T) { auto func2(T value) { return value; } }\n    static assert(is(S2!int == struct));\n    assert(func2(10) == 10);\n\n    template X(T) { alias X = T[3]; }\n    static assert(is(X!int == int[3]));\n\n    int a;\n    template Y(T) { alias Y = T[typeof(a)]; }\n    static assert(is(Y!double == double[int]));\n\n    int v = 10;\n    template Z() { alias Z = v; }\n    assert(v == 10);\n    Z!() = 20;\n    assert(v == 20);\n}\n\n/******************************************/\n\nenum T8848a(int[] a) = a;\nenum T8848b(int[int] b) = b;\nenum T8848c(void* c) = c;\n\nstatic assert(T8848a!([1,2,3]) == [1,2,3]);\nstatic assert(T8848b!([1:2,3:4]) == [1:2,3:4]);\nstatic assert(T8848c!(null) == null);\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9990\n\nauto initS9990() { return \"hi\"; }\n\nclass C9990(alias init) {}\n\nalias SC9990 = C9990!(initS9990);\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10067\n\nstruct assumeSize10067(alias F) {}\n\ntemplate useItemAt10067(size_t idx, T)\n{\n    void impl(){ }\n\n    alias useItemAt10067 = assumeSize10067!(impl);\n}\n\nuseItemAt10067!(0, char) mapS10067;\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4072\n\nvoid bug4072(T)(T x)\n    if (is(typeof(bug4072(x))))\n{}\n\nstatic assert(!is(typeof(bug4072(7))));\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10074\n\ntemplate foo10074(F)\n{\n    enum foo10074 = false;\n}\nbool foo10074(F)(F f)\n    if (foo10074!F)\n{\n    return false;\n}\n\nstatic assert(!is(typeof(foo10074(1))));\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10083\n\n// [a-c] IFTI can find syntactic eponymous member\ntemplate foo10083a(T)\n{\n    int foo10083a(double) { return 1; }\n    int foo10083a(T) { return 2; }\n}\ntemplate foo10083b(T)\n{\n    int foo10083b(T) { return 1; }\n    int foo10083b(T, T) { return 2; }\n}\ntemplate foo10083c1(T)\n{\n    int foo10083c1(T) { return 1; }\n    static if (true) { int x; }\n}\ntemplate foo10083c2(T)\n{\n    int foo10083c2(T) { return 1; }\n    static if (true) { int x; } else { int y; }\n}\n\n// [d-f] IFTI cannot find syntactic eponymous member\ntemplate foo10083d1(T)\n{\n    static if (true)\n    {\n        int foo10083d1(T) { return 1; }\n    }\n    else\n    {\n    }\n}\ntemplate foo10083d2(T)\n{\n    static if (true)\n    {\n    }\n    else\n    {\n        int foo10083d2(T) { return 1; }\n    }\n}\ntemplate foo10083e(T)\n{\n    static if (true)\n    {\n        int foo10083e(double arg) { return 1; }\n    }\n    int foo10083e(T arg) { return 2; }\n}\ntemplate foo10083f(T)\n{\n    static if (true)\n    {\n        int foo10083f(T) { return 1; }\n    }\n    else\n    {\n        int foo10083f(T) { return 2; }\n    }\n}\n\nvoid test10083()\n{\n    assert(foo10083a(1) == 2);\n    assert(foo10083a!int(1) == 2);\n    assert(foo10083a!int(1.0) == 1);\n    static assert(!__traits(compiles, foo10083a!double(1)));\n    static assert(!__traits(compiles, foo10083a!double(1.0)));\n    static assert(!__traits(compiles, foo10083a!real(1)));\n    assert(foo10083a!real(1.0) == 1);\n    assert(foo10083a!real(1.0L) == 2);\n\n    assert(foo10083b(2) == 1);\n    assert(foo10083b(3, 4) == 2);\n    static assert(!__traits(compiles, foo10083b(2, \"\")));\n\n    assert(foo10083c1(1) == 1);\n    assert(foo10083c2(1) == 1);\n\n    static assert(!__traits(compiles, foo10083d1(2)));\n    static assert(!__traits(compiles, foo10083d2(2)));\n    static assert(!__traits(compiles, foo10083e(3)));\n    static assert(!__traits(compiles, foo10083f(3)));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10134\n\ntemplate ReturnType10134(alias func)\n{\n    static if (is(typeof(func) R == return))\n        alias R ReturnType10134;\n    else\n        static assert(0);\n}\n\nstruct Result10134(T) {}\n\ntemplate getResultType10134(alias func)\n{\n    static if(is(ReturnType10134!(func.exec) _ == Result10134!(T), T))\n    {\n        alias getResultType10134 = T;\n    }\n}\n\ntemplate f10134(alias func)\n{\n    Result10134!(getResultType10134!(func)) exec(int i)\n    {\n        return typeof(return)();\n    }\n}\n\ntemplate a10134()\n{\n    Result10134!(double) exec(int i)\n    {\n        return b10134!().exec(i);\n    }\n}\n\ntemplate b10134()\n{\n    Result10134!(double) exec(int i)\n    {\n        return f10134!(a10134!()).exec(i);\n    }\n}\n\npragma(msg, getResultType10134!(a10134!()));\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10313\n\nvoid test10313()\n{\n    struct Nullable(T)\n    {\n        this()(inout T value) inout {}\n    }\n\n    struct S { S[] array; }\n    S s;\n    auto ns = Nullable!S(s);\n\n    class C { C[] array; }\n    C c;\n    auto nc = Nullable!C(c);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10498\n\ntemplate triggerIssue10498a()\n{\n    enum triggerIssue10498a = __traits(compiles, { T10498a; });\n}\n\ntemplate PackedGenericTuple10498a(Args...)\n{\n    alias Args Tuple;\n    enum e = triggerIssue10498a!();\n}\n\nstruct S10498a { }\n\ntemplate T10498a()\n{\n    alias PackedGenericTuple10498a!S10498a T10498a;\n}\n\nvoid test10498a()\n{\n    alias T10498a!() t;\n    static assert(is(t.Tuple[0])); // Fails -> OK\n}\n\n// --------\n\ntemplate triggerIssue10498b(A...)\n{\n    enum triggerIssue10498b = __traits(compiles, { auto a = A[0]; });\n}\n\ntemplate PackedGenericTuple10498b(Args...)\n{\n    alias Args Tuple;\n    enum e = triggerIssue10498b!Args;\n}\n\ntemplate T10498b()\n{\n    struct S {} // The fact `S` is in `T` causes the problem\n    alias PackedGenericTuple10498b!S T10498b;\n}\n\nvoid test10498b()\n{\n    alias T10498b!() t;\n    static assert(is(t.Tuple[0]));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10537\n\nstruct Iota10537\n{\n    int s,e,i;\n    mixin Yield10537!q{ ; };\n}\n\nauto skipStrings10537(T)(T source)\n{\n    return \"\";\n}\n\nmixin template Yield10537(dstring code)\n{\n    alias X = typeof({ enum x = rewriteCode10537(code); }());\n}\n\ndstring rewriteCode10537(dstring code)\n{\n    skipStrings10537(code);  // IFTI causes forward reference\n    return \"\";\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10558\n\ntemplate Template10558() {}\n\nstruct Struct10558(alias T){}\n\nalias bar10558 = foo10558!(Template10558!());\n\ntemplate foo10558(alias T)\n{\n    alias foobar = Struct10558!T;\n\n    void fun()\n    {\n        alias a = foo10558!T;\n    }\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10592\n\nvoid test10592()\n{\n    struct A(E)\n    {\n        int put()(const(E)[] data)\n        {\n            return 1;\n        }\n\n        int put()(const(dchar)[] data) if (!is(E == dchar))\n        {\n            return 2;\n        }\n\n        int put(C)(const(C)[] data) if (!is(C == dchar) && !is(E == C))\n        {\n            return 3;\n        }\n    }\n\n    A!char x;\n    assert(x.put(\"abcde\"c) == 1);   // OK: hit 1\n    assert(x.put(\"abcde\"w) == 3);   // NG: this should hit 3\n    assert(x.put(\"abcde\"d) == 2);   // OK: hit 2\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11242\n\ninout(T[]) fromString11242(T)(inout(char[]) s, T[] dst)\n{\n    return s;\n}\n\nvoid test11242()\n{\n    char[] a;\n    fromString11242(a, a);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10811\n\nvoid foo10811a(R1, R2)(R1, R2) {}\ntemplate foo10811a(alias pred) { void foo10811a(R1, R2)(R1, R2) {} }\n\ntemplate foo10811b(alias pred) { void foo10811b(R1, R2)(R1, R2) {} }\nvoid foo10811b(R1, R2)(R1, R2) {}\n\nvoid test10811()\n{\n    foo10811a(1, 2);\n    foo10811a!(a => a)(1, 2);\n\n    foo10811b(1, 2);\n    foo10811b!(a => a)(1, 2);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10969\n\ntemplate A10969(T, U...) { alias A10969 = T; }\nvoid foo10969(T, U...)(A10969!(T, U) a) {}\n\ntemplate B10969(T, U) { alias B10969 = T; }\nvoid bar10969(T, U...)(B10969!(T, U[0]) a) {}\n\nvoid test10969()\n{\n    foo10969!(int, float)(3);\n    bar10969!(int, float)(3);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11271\n\nstruct SmartPtr11271(T)\n{\n    ~this() {}\n    void opAssign(U)(auto ref U rh) {}\n}\n\nvoid test11271()\n{\n    SmartPtr11271!Object a;\n    a = SmartPtr11271!Object();\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11533\n\nversion (none)\n{\nstruct S11533\n{\n    void put(alias fun)() { fun!int(); }\n}\nvoid test11533a()\n{\n    static void foo(T)() {}\n    S11533 s;\n    s.put!foo();\n}\n\nvoid test11533b()\n{\n    static void bar(alias fun)() { fun(); }\n    void nested() {}\n    bar!nested();\n}\n\nvoid test11533c()\n{\n    static struct Foo(alias fun)\n    {\n        auto call() { return fun(); }\n    }\n    int var = 1;\n    auto getVar() { return var; }\n    Foo!getVar foo;\n    assert(foo.call() == var);\n    var += 1;\n    assert(foo.call() == var);\n}\n\nvoid test11533()\n{\n    test11533a();\n    test11533b();\n    test11533c();\n}\n}\nelse\n{\nvoid test11533()\n{\n}\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11553\n\nstruct Pack11553(T ...)\n{\n    alias Unpack = T;\n    enum length = T.length;\n}\n\ntemplate isPack11553(TList ...)\n{\n    static if (TList.length == 1 && is(Pack11553!(TList[0].Unpack) == TList[0]))\n    {\n        enum isPack11553 = true;\n    }\n    else\n    {\n        enum isPack11553 = false;\n    }\n}\n\ntemplate PartialApply11553(alias T, uint argLoc, Arg ...)\n    if (Arg.length == 1)\n{\n    template PartialApply11553(L ...)\n    {\n        alias PartialApply11553 = T!(L[0 .. argLoc], Arg, L[argLoc .. $]);\n    }\n}\n\ntemplate _hasLength11553(size_t len, T)\n{\n    static if (T.length == len)\n    {\n        enum _hasLength11553 = true;\n    }\n    else\n    {\n        enum _hasLength11553 = false;\n    }\n}\n\nalias _hasLength11553(size_t len) = PartialApply11553!(._hasLength11553, 0, len);\n\n\nalias hl11553 = _hasLength11553!1;\n\n// this segfaults\nstatic if (!isPack11553!hl11553) { pragma(msg, \"All good 1\"); }\n\n// these are fine\nstatic if ( hl11553!(Pack11553!(5))) { pragma(msg, \"All good 2\"); }\n\nstatic if (!hl11553!(Pack11553!( ))) { pragma(msg, \"All good 3\"); }\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11818\n\nenum E11818 { e0, e1 }\n\nstruct SortedRange11818\n{\n    void fun(E11818 e = true ? E11818.e0 : E11818.e1)()\n    {\n    }\n}\n\nvoid test11818()\n{\n    SortedRange11818 s;\n    s.fun();\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11843\n\nvoid test11843()\n{\n    struct Foo\n    {\n        int[string] x;\n    }\n\n    struct Bar(alias foo) {}\n\n    enum bar1 = Bar!(Foo([\"a\": 1]))();\n    enum bar2 = Bar!(Foo([\"a\": 1]))();\n    static assert(is(typeof(bar1) == typeof(bar2)));\n\n    enum foo1 = Foo([\"a\": 1]);\n    enum foo2 = Foo([\"b\": -1]);\n    static assert(!__traits(isSame, foo1, foo2));\n    enum bar3 = Bar!foo1();\n    enum bar4 = Bar!foo2();\n    static assert(!is(typeof(bar3) == typeof(bar4)));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11872\n\nclass Foo11872\n{\n    auto test(int v)() {}\n    auto test(int v)(string) {}\n\n    template Bar(T)\n    {\n        void test(T) {}\n    }\n}\n\nvoid test11872()\n{\n    auto foo = new Foo11872();\n\n    with (foo)\n    {\n        // ScopeExp(ti) -> DotTemplateInstanceExp(wthis, ti)\n        foo.test!2();   // works\n        test!2();       // works <- fails\n        test!2;         // works <- fails\n\n        // ScopeExp(ti) -> DotTemplateInstanceExp(wthis, ti) -> DotExp(wthis, ScopeExp)\n        foo.Bar!int.test(1);    // works\n        Bar!int.test(1);        // works <- fails\n    }\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12042\n\nstruct S12042\n{\n    int[] t;\n\n    void m()()\n    {\n        t = null;   // CTFE error -> OK\n    }\n}\n\nint test12042()\n{\n    S12042 s;\n\n    with (s)\n        m!()();\n\n    return 1;\n}\n\nstatic assert(test12042());\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12077\n\nstruct S12077(A) {}\n\nalias T12077(alias T : Base!Args, alias Base, Args...) = Base;\nstatic assert(__traits(isSame, T12077!(S12077!int), S12077));\n\nalias U12077(alias T : Base!Args, alias Base, Args...) = Base;\nalias U12077(      T : Base!Args, alias Base, Args...) = Base;\nstatic assert(__traits(isSame, U12077!(S12077!int), S12077));\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12262\n\ntemplate Inst12262(T) { int x; }\n\nenum fqnSym12262(alias a)                      = 1;\nenum fqnSym12262(alias a : B!A, alias B, A...) = 2;\n\nstatic assert(fqnSym12262!(Inst12262!(Object)) == 2);\nstatic assert(fqnSym12262!(Inst12262!(Object).x) == 1);\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12264\n\nstruct S12264(A) {}\n\ntemplate AX12264(alias A1)                      { enum AX12264 = 1; }\ntemplate AX12264(alias A2 : B!A, alias B, A...) { enum AX12264 = 2; }\ntemplate AY12264(alias A1)                  { enum AY12264 = 1; }\ntemplate AY12264(alias A2 : B!int, alias B) { enum AY12264 = 2; }\ntemplate AZ12264(alias A1)               { enum AZ12264 = 1; }\ntemplate AZ12264(alias A2 : S12264!T, T) { enum AZ12264 = 2; }\nstatic assert(AX12264!(S12264!int) == 2);\nstatic assert(AY12264!(S12264!int) == 2);\nstatic assert(AZ12264!(S12264!int) == 2);\n\ntemplate TX12264(T1)                      { enum TX12264 = 1; }\ntemplate TX12264(T2 : B!A, alias B, A...) { enum TX12264 = 2; }\ntemplate TY12264(T1)                  { enum TY12264 = 1; }\ntemplate TY12264(T2 : B!int, alias B) { enum TY12264 = 2; }\ntemplate TZ12264(T1)               { enum TZ12264 = 1; }\ntemplate TZ12264(T2 : S12264!T, T) { enum TZ12264 = 2; }\nstatic assert(TX12264!(S12264!int) == 2);\nstatic assert(TY12264!(S12264!int) == 2);\nstatic assert(TZ12264!(S12264!int) == 2);\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12122\n\nenum N12122 = 1;\n\nvoid foo12122(T)(T[N12122]) if(is(T == int)) {}\n\nvoid test12122()\n{\n    int[N12122] data;\n    foo12122(data);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12186\n\ntemplate map_front12186(fun...)\n{\n    auto map_front12186(Range)(Range r)\n    {\n        return fun[0](r[0]);\n    }\n}\n\nvoid test12186()\n{\n    immutable int[][] mat;\n\n    mat.map_front12186!((in r) => 0);              // OK\n    mat.map_front12186!((const r) => 0);           // OK\n    mat.map_front12186!((immutable int[] r) => 0); // OK\n    mat.map_front12186!((immutable r) => 0);       // OK <- Error\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12207\n\nvoid test12207()\n{\n    static struct S\n    {\n        static void f(T)(T) {}\n    }\n\n    immutable S s;\n\n    s.f(1);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12263\n\ntemplate A12263(alias a) { int x; }\ntemplate B12263(alias a) { int x; }\n\ntemplate fqnSym12263(alias T : B12263!A, alias B12263, A...)\n{\n    enum fqnSym12263 = true;\n}\n\nstatic assert(fqnSym12263!(A12263!(Object)));\nstatic assert(fqnSym12263!(B12263!(Object)));\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12290\n\nvoid test12290()\n{\n    short[] arrS;\n    float[] arrF;\n    double[] arrD;\n    real[] arrR;\n    string cstr;\n    wstring wstr;\n    dstring dstr;\n    short[short] aa;\n\n    auto func1a(E)(E[], E) { return E.init; }\n    auto func1b(E)(E, E[]) { return E.init; }\n\n    static assert(is(typeof(func1a(arrS, 1)) == short));\n    static assert(is(typeof(func1b(1, arrS)) == short));\n    static assert(is(typeof(func1a(arrF, 1.0)) == float));\n    static assert(is(typeof(func1b(1.0, arrF)) == float));\n    static assert(is(typeof(func1a(arrD, 1.0L)) == double));\n    static assert(is(typeof(func1b(1.0L, arrD)) == double));\n    static assert(is(typeof(func1a(arrR, 1)) == real));\n    static assert(is(typeof(func1b(1, arrR)) == real));\n    static assert(is(typeof(func1a(\"str\" , 'a')) == immutable  char));\n    static assert(is(typeof(func1b('a', \"str\" )) == immutable  char));\n    static assert(is(typeof(func1a(\"str\"c, 'a')) == immutable  char));\n    static assert(is(typeof(func1b('a', \"str\"c)) == immutable  char));\n    static assert(is(typeof(func1a(\"str\"w, 'a')) == immutable wchar));\n    static assert(is(typeof(func1b('a', \"str\"w)) == immutable wchar));\n    static assert(is(typeof(func1a(\"str\"d, 'a')) == immutable dchar));\n    static assert(is(typeof(func1b('a', \"str\"d)) == immutable dchar));\n    static assert(is(typeof(func1a([1,2,3], 1L)) == long));\n    static assert(is(typeof(func1b(1L, [1,2,3])) == long));\n    static assert(is(typeof(func1a([1,2,3], 1.5)) == double));\n    static assert(is(typeof(func1b(1.5, [1,2,3])) == double));\n    static assert(is(typeof(func1a([\"a\",\"b\"], \"s\"c)) ==  string));\n    static assert(is(typeof(func1b(\"s\"c, [\"a\",\"b\"])) ==  string));\n    static assert(is(typeof(func1a([\"a\",\"b\"], \"s\"w)) == wstring));\n    static assert(is(typeof(func1b(\"s\"w, [\"a\",\"b\"])) == wstring));\n    static assert(is(typeof(func1a([\"a\",\"b\"], \"s\"d)) == dstring));\n    static assert(is(typeof(func1b(\"s\"d, [\"a\",\"b\"])) == dstring));\n\n    auto func2a(K, V)(V[K], K, V) { return V[K].init; }\n    auto func2b(K, V)(V, K, V[K]) { return V[K].init; }\n\n    static assert(is(typeof(func2a(aa, 1, 1)) == short[short]));\n    static assert(is(typeof(func2b(1, 1, aa)) == short[short]));\n    static assert(is(typeof(func2a([1:10,2:20,3:30], 1L, 10L)) == long[long]));\n    static assert(is(typeof(func2b(1L, 10L, [1:20,2:20,3:30])) == long[long]));\n\n    auto func3a(T)(T, T) { return T.init; }\n    auto func3b(T)(T, T) { return T.init; }\n\n    static assert(is(typeof(func3a(arrS, null)) == short[]));\n    static assert(is(typeof(func3b(null, arrS)) == short[]));\n    static assert(is(typeof(func3a(arrR, null)) == real[]));\n    static assert(is(typeof(func3b(null, arrR)) == real[]));\n    static assert(is(typeof(func3a(cstr, \"str\")) ==  string));\n    static assert(is(typeof(func3b(\"str\", cstr)) ==  string));\n    static assert(is(typeof(func3a(wstr, \"str\")) == wstring));\n    static assert(is(typeof(func3b(\"str\", wstr)) == wstring));\n    static assert(is(typeof(func3a(dstr, \"str\")) == dstring));\n    static assert(is(typeof(func3b(\"str\", dstr)) == dstring));\n    static assert(is(typeof(func3a(\"str1\" , \"str2\"c)) ==  string));\n    static assert(is(typeof(func3b(\"str1\"c, \"str2\" )) ==  string));\n    static assert(is(typeof(func3a(\"str1\" , \"str2\"w)) == wstring));\n    static assert(is(typeof(func3b(\"str1\"w, \"str2\" )) == wstring));\n    static assert(is(typeof(func3a(\"str1\" , \"str2\"d)) == dstring));\n    static assert(is(typeof(func3b(\"str1\"d, \"str2\" )) == dstring));\n\n    inout(V) get(K, V)(inout(V[K]) aa, K key, lazy V defaultValue) { return V.init; }\n\n    short[short] hash12220;\n    short res12220 = get(hash12220, 1, 1);\n\n    short[short] hash12221;\n    enum Key12221 : short { a }\n    get(hash12221, Key12221.a, Key12221.a);\n\n    int[][string] mapping13026;\n    int[] v = get(mapping13026, \"test\", []);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12292\n\nvoid test12292()\n{\n    void fun(T : string)(T data) {}\n\n    ubyte[3] sa;\n    static assert(!__traits(compiles, fun(sa)));\n    static assert(!__traits(compiles, { alias f = fun!(ubyte[3]); }));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12376\n\nstatic auto encode12376(size_t sz)(dchar ch) if (sz > 1)\n{\n    undefined;\n}\n\nvoid test12376()\n{\n    enum x = __traits(compiles, encode12376!2(x));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12447\n\nenum   test12447(string str) = str; // [1]\nstring test12447(T...)(T args) if (T.length) { return args[0]; }    // [2]\n\n// With [1]: The template parameter str cannot be be deduced -> no match\n// With [2]: T is deduced to a type tuple (string), then match to the function call.\nstatic assert(test12447(\"foo\") == \"foo\");\n\n// With [1]: template parameter str is deduced to \"bar\", then match.\n// With [2]: T is deduced to an expression tuple (\"bar\"), but it will make invalid the function signature (T args).\n//           The failure should be masked silently and prefer the 1st version.\nstatic assert(test12447!(\"bar\") == \"bar\");\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12651\n\nalias TemplateArgsOf12651(alias T : Base!Args, alias Base, Args...) = Args;\n\nstruct S12651(T) { }\n\nstatic assert(!__traits(compiles, TemplateArgsOf12651!(S12651!int, S, float)));\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12719\n\nstruct A12719\n{\n    B12719!int b();\n}\n\nstruct B12719(T)\n{\n    A12719 a;\n    void m()\n    {\n        auto v = B12719!T.init;\n    }\n}\n\n// --------\n\nenum canDoIt12719(R) = is(typeof(W12719!R));\n\nstruct W12719(R)\n{\n    R r;\n    static if (canDoIt12719!R) {}\n}\n\nW12719!int a12719;\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12746\n\ntemplate foo12746()\n{\n    void bar()\n    {\n        static assert(!__traits(compiles, bar(1)));\n    }\n    alias foo12746 = bar;\n}\n\nvoid foo12746(int)\n{\n    assert(0);\n}\n\nvoid test12746()\n{\n    foo12746(); // instantiate\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12748\n\nvoid foo12748(S, C : typeof(S.init[0]))(S s, C c)\n{\n}\n\nvoid test12748()\n{\n    foo12748(\"abc\", 'd');\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9708\n\nstruct S9708\n{\n    void f()(inout(Object)) inout {}\n}\n\nvoid test9708()\n{\n    S9708 s;\n    s.f(new Object);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12880\n\nvoid f12880(T)(in T value) { static assert(is(T == string)); }\nvoid test12880() { f12880(string.init); }\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13087\n\nstruct Vec13087\n{\n    int x;\n    void m()                      { auto n = component13087!(this, 'x'); }\n    void c() const                { auto n = component13087!(this, 'x'); }\n    void w() inout                { auto n = component13087!(this, 'x'); }\n    void wc() inout const         { auto n = component13087!(this, 'x'); }\n    void s() shared               { auto n = component13087!(this, 'x'); }\n    void sc() shared const        { auto n = component13087!(this, 'x'); }\n    void sw() shared inout        { auto n = component13087!(this, 'x'); }\n    void swc() shared inout const { auto n = component13087!(this, 'x'); }\n    void i() immutable            { auto n = component13087!(this, 'x'); }\n}\n\ntemplate component13087(alias vec, char c)\n{\n    alias component13087 = vec.x;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13127\n\n/+void test13127(inout int = 0)\n{\n                       int []   ma1;\n                 const(int)[]   ca1;\n                 const(int[])   ca2;\n           inout(      int)[]  wma1;\n           inout(      int[])  wma2;\n           inout(const int)[]  wca1;\n           inout(const int[])  wca2;\n             immutable(int)[]   ia1;\n             immutable(int[])   ia2;\n    shared(            int)[]  sma1;\n    shared(            int[])  sma2;\n    shared(      const int)[]  sca1;\n    shared(      const int[])  sca2;\n    shared(inout       int)[] swma1;\n    shared(inout       int[]) swma2;\n    shared(inout const int)[] swca1;\n    shared(inout const int[]) swca2;\n\n    /* In all cases, U should be deduced to top-unqualified type.\n     */\n\n    /* Parameter is (shared) mutable\n     */\n    U f_m(U)(       U) { return null; }\n    U fsm(U)(shared U) { return null; }\n    // 9 * 2 - 1\n    static assert(is(typeof(f_m(  ma1))  ==                    int []));\n    static assert(is(typeof(f_m(  ca1))  ==              const(int)[]));\n    static assert(is(typeof(f_m(  ca2))  ==              const(int)[]));\n    static assert(is(typeof(f_m( wma1))  ==        inout(      int)[]));\n    static assert(is(typeof(f_m( wma2))  ==        inout(      int)[]));\n    static assert(is(typeof(f_m( wca1))  ==        inout(const int)[]));\n    static assert(is(typeof(f_m( wca2))  ==        inout(const int)[]));\n    static assert(is(typeof(f_m(  ia1))  ==          immutable(int)[]));\n    static assert(is(typeof(f_m(  ia2))  ==          immutable(int)[]));\n    static assert(is(typeof(f_m( sma1))  == shared(            int)[]));\n    static assert(is(typeof(f_m( sma2))  == shared(            int)[]));  // <- shared(int[])\n    static assert(is(typeof(f_m( sca1))  == shared(      const int)[]));\n    static assert(is(typeof(f_m( sca2))  == shared(      const int)[]));  // <- shared(const(int)[])\n    static assert(is(typeof(f_m(swma1))  == shared(inout       int)[]));\n    static assert(is(typeof(f_m(swma2))  == shared(inout       int)[]));  // <- shared(inout(int[]))\n    static assert(is(typeof(f_m(swca1))  == shared(inout const int)[]));\n    static assert(is(typeof(f_m(swca2))  == shared(inout const int)[]));  // <- shared(inout(const(int))[])\n    // 9 * 2 - 1\n    static assert(is(typeof(fsm(  ma1))) == false);\n    static assert(is(typeof(fsm(  ca1))) == false);\n    static assert(is(typeof(fsm(  ca2))) == false);\n    static assert(is(typeof(fsm( wma1))) == false);\n    static assert(is(typeof(fsm( wma2))) == false);\n    static assert(is(typeof(fsm( wca1))) == false);\n    static assert(is(typeof(fsm( wca2))) == false);\n    static assert(is(typeof(fsm(  ia1))) == false);\n    static assert(is(typeof(fsm(  ia2))) == false);\n    static assert(is(typeof(fsm( sma1))  == shared(            int)[]));  // <- NG\n    static assert(is(typeof(fsm( sma2))  == shared(            int)[]));\n    static assert(is(typeof(fsm( sca1))  == shared(      const int)[]));  // <- NG\n    static assert(is(typeof(fsm( sca2))  == shared(      const int)[]));\n    static assert(is(typeof(fsm(swma1))  == shared(inout       int)[]));  // <- NG\n    static assert(is(typeof(fsm(swma2))  == shared(inout       int)[]));\n    static assert(is(typeof(fsm(swca1))  == shared(inout const int)[]));  // <- NG\n    static assert(is(typeof(fsm(swca2))  == shared(inout const int)[]));\n\n    /* Parameter is (shared) const\n     */\n    U f_c(U)(       const U) { return null; }\n    U fsc(U)(shared const U) { return null; }\n    // 9 * 2 - 1\n    static assert(is(typeof(f_c(  ma1))  ==                    int []));\n    static assert(is(typeof(f_c(  ca1))  ==              const(int)[]));\n    static assert(is(typeof(f_c(  ca2))  ==              const(int)[]));\n    static assert(is(typeof(f_c( wma1))  ==        inout(      int)[]));\n    static assert(is(typeof(f_c( wma2))  ==        inout(      int)[]));\n    static assert(is(typeof(f_c( wca1))  ==        inout(const int)[]));\n    static assert(is(typeof(f_c( wca2))  ==        inout(const int)[]));\n    static assert(is(typeof(f_c(  ia1))  ==          immutable(int)[]));\n    static assert(is(typeof(f_c(  ia2))  ==          immutable(int)[]));\n    static assert(is(typeof(f_c( sma1))  == shared(            int)[]));\n    static assert(is(typeof(f_c( sma2))  == shared(            int)[]));  // <- shared(int[])\n    static assert(is(typeof(f_c( sca1))  == shared(      const int)[]));\n    static assert(is(typeof(f_c( sca2))  == shared(      const int)[]));  // <- shared(const(int)[])\n    static assert(is(typeof(f_c(swma1))  == shared(inout       int)[]));\n    static assert(is(typeof(f_c(swma2))  == shared(inout       int)[]));  // shared(inout(int)[])\n    static assert(is(typeof(f_c(swca1))  == shared(inout const int)[]));\n    static assert(is(typeof(f_c(swca2))  == shared(inout const int)[]));  // shared(inout(const(int))[])\n    // 9 * 2 - 1\n    static assert(is(typeof(fsc(  ma1))) == false);\n    static assert(is(typeof(fsc(  ca1))) == false);\n    static assert(is(typeof(fsc(  ca2))) == false);\n    static assert(is(typeof(fsc( wma1))) == false);\n    static assert(is(typeof(fsc( wma2))) == false);\n    static assert(is(typeof(fsc( wca1))) == false);\n    static assert(is(typeof(fsc( wca2))) == false);\n    static assert(is(typeof(fsc(  ia1))  ==          immutable(int)[]));  // <- NG\n    static assert(is(typeof(fsc(  ia2))  ==          immutable(int)[]));  // <- NG\n    static assert(is(typeof(fsc( sma1))  == shared(            int)[]));  // <- NG\n    static assert(is(typeof(fsc( sma2))  == shared(            int)[]));\n    static assert(is(typeof(fsc( sca1))  == shared(      const int)[]));  // <- NG\n    static assert(is(typeof(fsc( sca2))  == shared(      const int)[]));\n    static assert(is(typeof(fsc(swma1))  == shared(inout       int)[]));  // <- NG\n    static assert(is(typeof(fsc(swma2))  == shared(inout       int)[]));\n    static assert(is(typeof(fsc(swca1))  == shared(inout const int)[]));  // <- NG\n    static assert(is(typeof(fsc(swca2))  == shared(inout const int)[]));\n\n    /* Parameter is immutable\n     */\n    U fi(U)(immutable U) { return null; }\n    // 9 * 2 - 1\n    static assert(is(typeof(fi(  ma1))) == false);\n    static assert(is(typeof(fi(  ca1))) == false);\n    static assert(is(typeof(fi(  ca2))) == false);\n    static assert(is(typeof(fi( wma1))) == false);\n    static assert(is(typeof(fi( wma2))) == false);\n    static assert(is(typeof(fi( wca1))) == false);\n    static assert(is(typeof(fi( wca2))) == false);\n    static assert(is(typeof(fi(  ia1))  == immutable(int)[]));  // <- NG\n    static assert(is(typeof(fi(  ia2))  == immutable(int)[]));  // <- NG\n    static assert(is(typeof(fi( sma1))) == false);\n    static assert(is(typeof(fi( sma2))) == false);\n    static assert(is(typeof(fi( sca1))) == false);\n    static assert(is(typeof(fi( sca2))) == false);\n    static assert(is(typeof(fi(swma1))) == false);\n    static assert(is(typeof(fi(swma2))) == false);\n    static assert(is(typeof(fi(swca1))) == false);\n    static assert(is(typeof(fi(swca2))) == false);\n\n    /* Parameter is (shared) inout\n     */\n    U f_w(U)(       inout U) { return null; }\n    U fsw(U)(shared inout U) { return null; }\n    // 9 * 2 - 1\n    static assert(is(typeof(f_w(  ma1))  ==              int []));\n    static assert(is(typeof(f_w(  ca1))  ==              int []));  // <- const(int)[]\n    static assert(is(typeof(f_w(  ca2))  ==              int []));  // <- const(int)[]\n    static assert(is(typeof(f_w( wma1))  ==              int []));  // <- inout(int)[]\n    static assert(is(typeof(f_w( wma2))  ==              int []));  // <- inout(int)[]\n    static assert(is(typeof(f_w( wca1))  ==        const(int)[]));  // <- inout(const(int))[]\n    static assert(is(typeof(f_w( wca2))  ==        const(int)[]));  // <- inout(const(int))[]\n    static assert(is(typeof(f_w(  ia1))  ==              int []));  // <- immutable(int)[]\n    static assert(is(typeof(f_w(  ia2))  ==              int []));  // <- immutable(int)[]\n    static assert(is(typeof(f_w( sma1))  == shared(      int)[]));\n    static assert(is(typeof(f_w( sma2))  == shared(      int)[]));  // <- shared(int[])\n    static assert(is(typeof(f_w( sca1))  == shared(      int)[]));  // <- shared(const(int))[]\n    static assert(is(typeof(f_w( sca2))  == shared(      int)[]));  // <- shared(const(int)[])\n    static assert(is(typeof(f_w(swma1))  == shared(      int)[]));  // <- shared(inout(int))[]\n    static assert(is(typeof(f_w(swma2))  == shared(      int)[]));  // <- shared(inout(int)[])\n    static assert(is(typeof(f_w(swca1))  == shared(const int)[]));  // <- shared(inout(const(int)))[]\n    static assert(is(typeof(f_w(swca2))  == shared(const int)[]));  // <- shared(inout(const(int))[])\n    // 9 * 2 - 1\n    static assert(is(typeof(fsw(  ma1))) == false);\n    static assert(is(typeof(fsw(  ca1))) == false);\n    static assert(is(typeof(fsw(  ca2))) == false);\n    static assert(is(typeof(fsw( wma1))) == false);\n    static assert(is(typeof(fsw( wma2))) == false);\n    static assert(is(typeof(fsw( wca1))) == false);\n    static assert(is(typeof(fsw( wca2))) == false);\n    static assert(is(typeof(fsw(  ia1))  ==              int []));  // <- NG\n    static assert(is(typeof(fsw(  ia2))  ==              int []));  // <- NG\n    static assert(is(typeof(fsw( sma1))  ==              int []));  // <- NG\n    static assert(is(typeof(fsw( sma2))  ==              int []));\n    static assert(is(typeof(fsw( sca1))  ==              int []));  // <- NG\n    static assert(is(typeof(fsw( sca2))  ==              int []));  // const(int)[]\n    static assert(is(typeof(fsw(swma1))  ==              int []));  // <- NG\n    static assert(is(typeof(fsw(swma2))  ==              int []));  // inout(int)[]\n    static assert(is(typeof(fsw(swca1))  ==        const(int)[]));  // <- NG\n    static assert(is(typeof(fsw(swca2))  ==        const(int)[]));  // <- inout(const(int))[]\n\n    /* Parameter is (shared) inout const\n     */\n    U f_wc(U)(       inout const U) { return null; }\n    U fswc(U)(shared inout const U) { return null; }\n    // 9 * 2 - 1\n    static assert(is(typeof(f_wc(  ma1))  ==        int []));\n    static assert(is(typeof(f_wc(  ca1))  ==        int []));  // <- const(int)[]\n    static assert(is(typeof(f_wc(  ca2))  ==        int []));  // <- const(int)[]\n    static assert(is(typeof(f_wc( wma1))  ==        int []));  // <- inout(int)[]\n    static assert(is(typeof(f_wc( wma2))  ==        int []));  // <- inout(int)[]\n    static assert(is(typeof(f_wc( wca1))  ==        int []));  // <- inout(const(int))[]\n    static assert(is(typeof(f_wc( wca2))  ==        int []));  // <- inout(const(int))[]\n    static assert(is(typeof(f_wc(  ia1))  ==        int []));  // <- immutable(int)[]\n    static assert(is(typeof(f_wc(  ia2))  ==        int []));  // <- immutable(int)[]\n    static assert(is(typeof(f_wc( sma1))  == shared(int)[]));\n    static assert(is(typeof(f_wc( sma2))  == shared(int)[]));  // <- shared(int[])\n    static assert(is(typeof(f_wc( sca1))  == shared(int)[]));  // <- shared(const(int))[]\n    static assert(is(typeof(f_wc( sca2))  == shared(int)[]));  // <- shared(const(int)[])\n    static assert(is(typeof(f_wc(swma1))  == shared(int)[]));  // <- shared(inout(int))[]\n    static assert(is(typeof(f_wc(swma2))  == shared(int)[]));  // <- shared(inout(int)[])\n    static assert(is(typeof(f_wc(swca1))  == shared(int)[]));  // <- shared(inout(const(int)))[]\n    static assert(is(typeof(f_wc(swca2))  == shared(int)[]));  // <- shared(inout(const(int))[])\n    // 9 * 2 - 1\n    static assert(is(typeof(fswc(  ma1))) == false);\n    static assert(is(typeof(fswc(  ca1))) == false);\n    static assert(is(typeof(fswc(  ca2))) == false);\n    static assert(is(typeof(fswc( wma1))) == false);\n    static assert(is(typeof(fswc( wma2))) == false);\n    static assert(is(typeof(fswc( wca1))) == false);\n    static assert(is(typeof(fswc( wca2))) == false);\n    static assert(is(typeof(fswc(  ia1))  ==        int []));  // <- NG\n    static assert(is(typeof(fswc(  ia2))  ==        int []));  // <- NG\n    static assert(is(typeof(fswc( sma1))  ==        int []));  // <- NG\n    static assert(is(typeof(fswc( sma2))  ==        int []));\n    static assert(is(typeof(fswc( sca1))  ==        int []));  // <- NG\n    static assert(is(typeof(fswc( sca2))  ==        int []));  // <- const(int)[]\n    static assert(is(typeof(fswc(swma1))  ==        int []));  // <- NG\n    static assert(is(typeof(fswc(swma2))  ==        int []));  // <- inout(int)[]\n    static assert(is(typeof(fswc(swca1))  ==        int []));  // <- NG\n    static assert(is(typeof(fswc(swca2))  ==        int []));  // <- inout(const(int))[]\n}+/\n\nvoid test13127a()\n{\n    void foo(T)(in T[] src, T[] dst) { static assert(is(T == int[])); }\n\n    int[][] a;\n    foo(a, a);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13159\n\ntemplate maxSize13159(T...)\n{\n    static if (T.length == 1)\n    {\n        enum size_t maxSize13159 = T[0].sizeof;\n    }\n    else\n    {\n        enum size_t maxSize13159 =\n            T[0].sizeof >= maxSize13159!(T[1 .. $])\n                ? T[0].sizeof\n                : maxSize13159!(T[1 .. $]);\n    }\n}\n\nstruct Node13159\n{\n    struct Pair\n    {\n        Node13159 value;\n    }\n\n    //alias Algebraic!(Node[], int) Value;\n    enum n = maxSize13159!(Node13159[], int);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13180\n\nvoid test13180()\n{\n    inout(V) get1a(K, V)(inout(V[K]) aa, lazy inout(V) defaultValue)\n    {\n        static assert(is(V == string));\n        static assert(is(K == string));\n        return defaultValue;\n    }\n    inout(V) get1b(K, V)(lazy inout(V) defaultValue, inout(V[K]) aa)\n    {\n        static assert(is(V == string));\n        static assert(is(K == string));\n        return defaultValue;\n    }\n\n    inout(V) get2a(K, V)(inout(V)[K] aa, lazy inout(V) defaultValue)\n    {\n        static assert(is(V == string));\n        static assert(is(K == string));\n        return defaultValue;\n    }\n    inout(V) get2b(K, V)(lazy inout(V) defaultValue, inout(V)[K] aa)\n    {\n        static assert(is(V == string));\n        static assert(is(K == string));\n        return defaultValue;\n    }\n    string def;\n    string[string] aa;\n    string s1a = get1a(aa, def);\n    string s1b = get1b(def, aa);\n    string s2a = get2a(aa, def);\n    string s2b = get2b(def, aa);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13204\n\nstruct A13204(uint v)\n{\n    alias whatever = A13204y;\n    static assert(is(whatever == A13204));\n}\nalias A13204x = A13204!1;\nalias A13204y = A13204x;\n\nstruct B13204(uint v)\n{\n    alias whatever = B13204z;\n    static assert(is(whatever == B13204));\n}\nalias B13204x = B13204!1;\nalias B13204y = B13204x;\nalias B13204z = B13204y;\n\nvoid test13204()\n{\n    static assert(is(A13204x == A13204!1));\n    static assert(is(A13204x == A13204!1.whatever));\n    static assert(is(A13204x == A13204y));\n\n    static assert(is(B13204x == B13204!1));\n    static assert(is(B13204x == B13204!1.whatever));\n    static assert(is(B13204x == B13204y));\n    static assert(is(B13204x == B13204z));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8462 (dup of 13204)\n\nalias FP8462 = void function(C8462.Type arg);\n\nclass C8462\n{\n    enum Type { Foo }\n    alias funcPtrPtr = FP8462*;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13218\n\ntemplate isCallable13218(T...)\n    if (T.length == 1)\n{\n    static assert(0);\n}\n\ntemplate ParameterTypeTuple13218(func...)\n    if (func.length == 1 && isCallable13218!func)\n{\n    static assert(0);\n}\n\nstruct R13218\n{\n    private static string mangleFuncPtr(ArgTypes...)()\n    {\n        string result = \"fnp_\";\n        foreach (T; ArgTypes)\n            result ~= T.mangleof;\n        return result;\n    }\n    void function(int) fnp_i;\n    double delegate(double) fnp_d;\n\n    void opAssign(FnT)(FnT func)\n    {\n        mixin(mangleFuncPtr!( ParameterTypeTuple13218!FnT) ~ \" = func;\");   // parsed as TypeInstance\n      //mixin(mangleFuncPtr!(.ParameterTypeTuple13218!FnT) ~ \" = func;\");   // parsed as DotTemplateInstanceExp -> works\n    }\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13219\n\nstruct Map13219(V) {}\n\nvoid test13219a(alias F, VA, VB)(Map13219!VA a, Map13219!VB b)\nif (is(VA : typeof(F(VA.init, VB.init))))\n{}\n\nvoid test13219b(alias F)()\n{\n    test13219a!((a, b) => b)(Map13219!int.init, Map13219!int.init);\n}\n\nvoid test13219()\n{\n    int x;\n    test13219b!x();\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13223\n\nvoid test13223()\n{\n    T[] f1(T)(T[] a1, T[] a2)\n    {\n        static assert(is(T == int));\n        return a1 ~ a2;\n    }\n    T[] f2(T)(T[] a1, T[] a2)\n    {\n        static assert(is(T == int));\n        return a1 ~ a2;\n    }\n    int[] a = [1, 2];\n    static assert(is(typeof(f1(a, [])) == int[]));\n    static assert(is(typeof(f2([], a)) == int[]));\n    static assert(is(typeof(f1(a, null)) == int[]));\n    static assert(is(typeof(f2(null, a)) == int[]));\n\n    T[] f3(T)(T[] a) { return a; }\n    static assert(is(typeof(f3([])) == void[]));\n    static assert(is(typeof(f3(null)) == void[]));\n\n    T f4(T)(T a) { return a; }\n    static assert(is(typeof(f4([])) == void[]));\n    static assert(is(typeof(f4(null)) == typeof(null)));\n\n    T[][] f5(T)(T[][] a) { return a; }\n    static assert(is(typeof(f5([])) == void[][]));\n    static assert(is(typeof(f5(null)) == void[][]));\n\n    void translate(C = immutable char)(const(C)[] toRemove)\n    {\n        static assert(is(C == char));\n    }\n    translate(null);\n}\n\nvoid test13223a()\n{\n    T f(T)(T, T) { return T.init; }\n\n    immutable i = 0;\n    const c = 0;\n    auto m = 0;\n    shared s = 0;\n\n    static assert(is(typeof(f(i, i)) == immutable int));\n    static assert(is(typeof(f(i, c)) ==     const int));\n    static assert(is(typeof(f(c, i)) ==     const int));\n    static assert(is(typeof(f(i, m)) ==           int));\n    static assert(is(typeof(f(m, i)) ==           int));\n    static assert(is(typeof(f(c, m)) ==           int));\n    static assert(is(typeof(f(m, c)) ==           int));\n    static assert(is(typeof(f(m, m)) ==           int));\n    static assert(is(typeof(f(i, s)) ==    shared int));\n    static assert(is(typeof(f(s, i)) ==    shared int));\n    static assert(is(typeof(f(c, s)) ==    shared int));\n    static assert(is(typeof(f(s, c)) ==    shared int));\n    static assert(is(typeof(f(s, s)) ==    shared int));\n    static assert(is(typeof(f(s, m)) ==           int));\n    static assert(is(typeof(f(m, s)) ==           int));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13235\n\nstruct Tuple13235(T...)\n{\n    T expand;\n    alias expand field;\n\n    this(T values)\n    {\n        field = values;\n    }\n}\nstruct Foo13235\n{\n    Tuple13235!(int, Foo13235)* foo;\n}\n\ntemplate Inst13235(T...)\n{\n    struct Tuple\n    {\n        T expand;\n        alias expand field;\n\n        this(T values)\n        {\n            field = values;\n        }\n    }\n    alias Inst13235 = Tuple*;\n}\nstruct Bar13235\n{\n    Inst13235!(int, Bar13235) bar;\n}\n\nvoid test13235()\n{\n    alias Tup1 = Tuple13235!(int, Foo13235);\n    assert(Tup1(1, Foo13235()).expand[0] == 1);\n\n    alias Tup2 = typeof(*Inst13235!(int, Bar13235).init);\n    assert(Tup2(1, Bar13235()).expand[0] == 1);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13252\n\nalias TypeTuple13252(T...) = T;\n\nstatic assert(is(typeof(TypeTuple13252!(cast(int )1)[0]) == int ));\nstatic assert(is(typeof(TypeTuple13252!(cast(long)1)[0]) == long));\n\nstatic assert(is(typeof(TypeTuple13252!(cast(float )3.14)[0]) == float ));\nstatic assert(is(typeof(TypeTuple13252!(cast(double)3.14)[0]) == double));\n\nstatic assert(is(typeof(TypeTuple13252!(cast(cfloat )(1 + 2i))[0]) == cfloat ));\nstatic assert(is(typeof(TypeTuple13252!(cast(cdouble)(1 + 2i))[0]) == cdouble));\n\nstatic assert(is(typeof(TypeTuple13252!(cast(string  )null)[0]) == string  ));\nstatic assert(is(typeof(TypeTuple13252!(cast(string[])null)[0]) == string[]));  // OK <- NG\n\nstatic assert(is(typeof(TypeTuple13252!(cast(wstring)\"abc\")[0]) == wstring));\nstatic assert(is(typeof(TypeTuple13252!(cast(dstring)\"abc\")[0]) == dstring));\n\nstatic assert(is(typeof(TypeTuple13252!(cast(int[] )[])[0]) == int[] ));\nstatic assert(is(typeof(TypeTuple13252!(cast(long[])[])[0]) == long[]));        // OK <- NG\n\nstruct S13252 { }\nstatic assert(is(typeof(TypeTuple13252!(const     S13252())[0]) ==     const(S13252)));\nstatic assert(is(typeof(TypeTuple13252!(immutable S13252())[0]) == immutable(S13252)));     // OK <- NG\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13294\n\nvoid test13294()\n{\n    void f(T)(const ref T src, ref T dst)\n    {\n        pragma(msg, \"T = \", T);\n        static assert(!is(T == const));\n    }\n    {\n        const byte src;\n              byte dst;\n        f(src, dst);\n    }\n    {\n        const char src;\n              char dst;\n        f(src, dst);\n    }\n\n    // https://issues.dlang.org/show_bug.cgi?id=13351\n    T add(T)(in T x, in T y)\n    {\n        T z;\n        z = x + y;\n        return z;\n    }\n    const double a = 1.0;\n    const double b = 2.0;\n    double c;\n    c = add(a,b);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13299\n\nstruct Foo13299\n{\n    Foo13299 opDispatch(string name)(int a, int[] b...)\n    if (name == \"bar\")\n    {\n        return Foo13299();\n    }\n\n    Foo13299 opDispatch(string name)()\n    if (name != \"bar\")\n    {\n        return Foo13299();\n    }\n}\n\nvoid test13299()\n{\n    Foo13299()\n        .bar(0)\n        .bar(1)\n        .bar(2);\n\n    Foo13299()\n        .opDispatch!\"bar\"(0)\n        .opDispatch!\"bar\"(1)\n        .opDispatch!\"bar\"(2);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13333\n\ntemplate AliasThisTypeOf13333(T)\n{\n    static assert(0, T.stringof);  // T.stringof is important\n}\n\ntemplate StaticArrayTypeOf13333(T)\n{\n    static if (is(AliasThisTypeOf13333!T AT))\n        alias X = StaticArrayTypeOf13333!AT;\n    else\n        alias X = T;\n\n    static if (is(X : E[n], E, size_t n))\n        alias StaticArrayTypeOf13333 = X;\n    else\n        static assert(0, T.stringof~\" is not a static array type\");\n}\n\nenum bool isStaticArray13333(T) = is(StaticArrayTypeOf13333!T);\n\nstruct VaraiantN13333(T)\n{\n    static if (isStaticArray13333!T)\n        ~this() { static assert(0); }\n}\n\nstruct DummyScope13333\n{\n    alias A = VaraiantN13333!C;\n\n    static class C\n    {\n        A entity;\n    }\n}\n\nvoid test13333()\n{\n    struct DummyScope\n    {\n        alias A = VaraiantN13333!C;\n\n        static class C\n        {\n            A entity;\n        }\n    }\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13374\n\nint f13374(alias a)()  { return 1; }\nint f13374(string s)() { return 2; }\n\nvoid x13374(int i) {}\n\nvoid test13374()\n{\n    assert(f13374!x13374() == 1);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14109\n\nstring f14109() { return \"a\"; }\nstring g14109()() { return \"a\"; }\n\nstruct S14109(string s) { static assert(s == \"a\"); }\n\nalias X14109 = S14109!(f14109);\nalias Y14109 = S14109!(g14109!());\nstatic assert(is(X14109 == Y14109));\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13378\n\nstruct Vec13378(size_t n, T, string as)\n{\n    T[n] data;\n}\n\nvoid doSome13378(size_t n, T, string as)(Vec13378!(n,T,as) v) {}\n\nvoid test13378()\n{\n    auto v = Vec13378!(3, float, \"xyz\")([1,2,3]);\n    doSome13378(v);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13379\n\nvoid test13379()\n{\n    match13379(\"\");\n}\n\nauto match13379(RegEx )(RegEx  re)\nif (is(RegEx == Regex13379!char))       // #1 Regex!char (speculative && tinst == NULL)\n{}\nauto match13379(String)(String re)\n{}\n\nstruct Regex13379(Char)\n{\n    ShiftOr13379!Char kickstart;        // #2 ShiftOr!char (speculative && tinst == Regex!char)\n}\nstruct ShiftOr13379(Char)\n{\n    this(ref Regex13379!Char re)        // #3 Regex!Char (speculative && tinst == ShiftOr!char)\n    {\n        uint n_length;\n        uint idx;\n        n_length = min13379(idx, n_length);\n    }\n}\n\ntemplate MinType13379(T...)\n{\n    alias MinType13379 = T[0];\n}\nMinType13379!T min13379(T...)(T args)   // #4 MinType!uint (speculative && thist == ShiftOr!char)\n{\n    alias a = args[0];\n    alias b = args[$-1];\n    return cast(typeof(return)) (a < b ? a : b);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13417\n\nstruct V13417(size_t N, E, alias string AS)\n{\n}\n\nauto f13417(E)(in V13417!(4, E, \"ijka\"))\n{\n    return V13417!(3, E, \"xyz\")();\n}\n\nvoid test13417()\n{\n    f13417(V13417!(4, float, \"ijka\")());\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13484\n\nint foo13484()(void delegate() hi) { return 1; }\nint foo13484(T)(void delegate(T) hi) { return 2; }\n\nvoid test13484()\n{\n    assert(foo13484({}) == 1);          // works\n    assert(foo13484((float v){}) == 2); // works <- throws error\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13675\n\nenum E13675;\n\nbool foo13675(T : E13675)()\n{\n    return false;\n}\n\nvoid test13675()\n{\n    if (foo13675!E13675)\n    {}\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13694\n\nauto foo13694(T)(string A,         T[] G ...) { return 1; }\nauto foo13694(T)(string A, long E, T[] G ...) { return 2; }\n\nvoid test13694()\n{\n    struct S {}\n\n    S v;\n    assert(foo13694(\"A\", v) == 1);      // <- OK\n    assert(foo13694(\"A\", 0, v) == 2);   // <- used to be OK but now fails\n    assert(foo13694!S(\"A\", 0, v) == 2); // <- workaround solution\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13760\n\nvoid test13760()\n{\n    void func(K, V)(inout(V[K]) aa, inout(V) val) {}\n\n    class C {}\n    C[int] aa;\n    func(aa, new C);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13714\n\nstruct JSONValue13714\n{\n    this(T)(T arg)\n    {\n    }\n    this(T : JSONValue13714)(inout T arg) inout\n    {\n        //store = arg.store;\n    }\n\n    void opAssign(T)(T arg)\n    {\n    }\n}\n\nvoid test13714()\n{\n    enum DummyStringEnum\n    {\n        foo = \"bar\"\n    }\n\n    JSONValue13714[string] aa;\n    aa[\"A\"] = DummyStringEnum.foo;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13807\n\nT f13807(T)(inout(T)[] arr)\n{\n    return T.init;\n}\n\nvoid test13807()\n{\n    static assert(is(typeof(f13807([1, 2, 3])) == int));    // OK\n    static assert(is(typeof(f13807([\"a\", \"b\"])) == string));    // OK <- Error\n    static assert(is(typeof(f13807!string([\"a\", \"b\"])) == string)); // OK\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14174\nimport imports.testmangle;\n\nstruct Config14174(a, b) {}\n\nstruct N14174 {}\n\nalias defConfig14174 = Config14174!(N14174, N14174);\n\nvoid accepter14174a(Config : Config14174!(T) = defConfig14174, T...)()\n{\n    static assert(equalDemangle(accepter14174a.mangleof,\n           \"_D7breaker131__T14\"~\n           \"accepter14174a\"~\n           \"HTS7breaker51__T11Config14174TS7breaker6N14174TS7breaker6N14174Z11Config14174TS7breaker6N14174TS7breaker6N14174Z14\"~\n           \"accepter14174a\"~\n           \"FZv\"));\n}\n\nvoid accepter14174b(Config : Config14174!(T) = defConfig14174, T...)()\n{\n    static assert(equalDemangle(accepter14174b.mangleof,\n           \"_D7breaker131__T14\"~\n           \"accepter14174b\"~\n           \"HTS7breaker51__T11Config14174TS7breaker6N14174TS7breaker6N14174Z11Config14174TS7breaker6N14174TS7breaker6N14174Z14\"~\n           \"accepter14174b\"~\n           \"FZv\"));\n}\n\nvoid test14174()\n{\n    accepter14174a!()(); // ok\n    accepter14174b();    // error\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14836\n\ntemplate a14836x(alias B, C...)\n{\n    int a14836x(D...)()    if (D.length == 0) { return 1; }\n    int a14836x(D...)(D d) if (D.length >  0) { return 2; }\n}\ntemplate a14836y(alias B, C...)\n{\n    int a14836y(T, D...)(T t)      if (D.length == 0) { return 1; }\n    int a14836y(T, D...)(T t, D d) if (D.length >  0) { return 2; }\n}\n\nvoid test14836()\n{\n    int v;\n    assert(a14836x!(v)() == 1);\n    assert(a14836x!(v)(1) == 2);\n    assert(a14836y!(v)(1) == 1);\n    assert(a14836y!(v)(1, 2) == 2);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14357\n\ntemplate Qux14357(T : U*, U : V*, V)\n{\n    pragma(msg, T);     // no match <- float**\n    pragma(msg, U);     // no match <- float*\n    pragma(msg, V);     // no match <- int\n    enum Qux14357 = T.sizeof + V.sizeof;\n}\nstatic assert(!__traits(compiles, Qux14357!(float**, int*)));\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14481\n\ntemplate someT14481(alias e)\n{\n    alias someT14481 = e;\n}\n\nmixin template Mix14481(alias e)\n{\n    alias SomeAlias = someT14481!e;\n}\n\nstruct Hoge14481\n{\n    mixin Mix14481!e;\n    enum e = 10;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14520\n\ntemplate M14520(alias  a) { enum M14520 = 1; }\ntemplate M14520(string s) { enum M14520 = 2; }\n\nint f14520a();\nstring f14520b() { assert(0); }\nstring f14520c() { return \"a\"; }\n\nstatic assert(M14520!f14520a == 1);\nstatic assert(M14520!f14520b == 1);\nstatic assert(M14520!f14520c == 1);\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14568\n\nstruct Interval14568()\n{\n    auto left = INVALID;\n\n    auto opAssign()(Interval14568) { left; }\n}\n\nauto interval14568(T)(T point)\n{\n    Interval14568!();\n}\n\nalias Instantiate14568(alias symbol, Args...) = symbol!Args;\n\ntemplate Match14568(patterns...)\n{\n    static if (__traits(compiles, Instantiate14568!(patterns[0])))\n    {\n        alias Match14568 = patterns[0];\n    }\n    else static if (patterns.length == 1)\n    {}\n}\n\ntemplate SubOps14568(Args...)\n{\n    auto opIndex()\n    {\n        template IntervalType(T...)\n        {\n            alias Point() = typeof(T.interval14568);\n\n            alias IntervalType = Match14568!(Point);\n        }\n        alias Subspace = IntervalType!(Args);\n    }\n}\n\nstruct Nat14568 { mixin SubOps14568!(null); }\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14603\n// https://issues.dlang.org/show_bug.cgi?id=14604\n\nstruct S14603\n{\n    template opDispatch(string name)\n    {\n        void opDispatch()() {}\n    }\n}\nalias a14603 = S14603.opDispatch!\"go\";  // OK\nalias b14603 = S14603.go;               // OK <- NG\n\nstruct S14604\n{\n    template opDispatch(string name)\n    {\n        void opDispatch()() {}\n    }\n}\nalias Id14604(alias thing) = thing;\nalias c14604 = Id14604!(S14604.opDispatch!\"go\");     // ok\nalias d14604 = Id14604!(S14604.go);                  // issue 14604, 'Error: template instance opDispatch!\"go\" cannot resolve forward reference'\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14735\n\nenum CS14735 { yes, no }\n\nint indexOf14735a(Range      )(Range    s, in dchar c) { return 1; }\nint indexOf14735a(T, size_t n)(ref T[n] s, in dchar c) { return 2; }\n\nint indexOf14735b(Range      )(Range    s, in dchar c, in CS14735 cs = CS14735.yes) { return 1; }\nint indexOf14735b(T, size_t n)(ref T[n] s, in dchar c, in CS14735 cs = CS14735.yes) { return 2; }\n\nvoid test14735()\n{\n    char[64] buf;\n\n    // Supported from 2.063: (http://dlang.org/changelog#implicitarraycast)\n    assert(indexOf14735a(buf[0..32], '\\0') == 2);\n    assert(indexOf14735b(buf[0..32], '\\0') == 2);\n\n    // Have to work as same as above.\n    assert(indexOf14735a(buf[], '\\0') == 2);\n    assert(indexOf14735b(buf[], '\\0') == 2);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14743\n\nclass A14743\n{\n    auto func1 = (A14743 a) { a.func2!int(); };\n    auto func2(T)() {}\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14802\n\nvoid test14802()\n{\n    auto func(T)(T x, T y) { return x; }\n\n    struct S1 { double x; alias x this; }\n    struct S2 { double x; alias x this; }\n    S1 s1;\n    S2 s2;\n\n    enum E1 : double { a = 1.0 }\n    enum E2 : double { a = 1.0 }\n\n    static assert(is(typeof( func(1 , 1 ) ) == int));\n    static assert(is(typeof( func(1u, 1u) ) == uint));\n    static assert(is(typeof( func(1u, 1 ) ) == uint));\n    static assert(is(typeof( func(1 , 1u) ) == uint));\n\n    static assert(is(typeof( func(1.0f, 1.0f) ) == float));\n    static assert(is(typeof( func(1.0 , 1.0 ) ) == double));\n    static assert(is(typeof( func(1.0 , 1.0f) ) == double));\n    static assert(is(typeof( func(1.0f, 1.0 ) ) == double));\n\n    static assert(is(typeof( func(s1, s1) ) == S1));\n    static assert(is(typeof( func(s2, s2) ) == S2));\n    static assert(is(typeof( func(s1, s2) ) == double));\n    static assert(is(typeof( func(s2, s1) ) == double));\n\n    static assert(is(typeof( func(E1.a, E1.a) ) == E1));\n    static assert(is(typeof( func(E2.a, E2.a) ) == E2));\n    static assert(is(typeof( func(E1.a, 1.0)  ) == double));\n    static assert(is(typeof( func(E2.a, 1.0)  ) == double));\n    static assert(is(typeof( func(1.0,  E1.a) ) == double));\n    static assert(is(typeof( func(1.0,  E2.a) ) == double));\n    static assert(is(typeof( func(E1.a, E2.a) ) == double));\n    static assert(is(typeof( func(E2.a, E1.a) ) == double));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14886\n\nvoid test14886()\n{\n    alias R = int[100_000];\n\n    auto front(T)(T[] a) {}\n    front(R.init);\n\n    auto bar1(T)(T, T[] a) { return T.init; }\n    auto bar2(T)(T[] a, T) { return T.init; }\n\n    static assert(is(typeof(bar1(1L, R.init)) == long));\n    static assert(is(typeof(bar2(R.init, 1L)) == long));\n    // <-- T should be deduced to int because R.init is rvalue...?\n\n    ubyte x;\n    static assert(is(typeof(bar1(x, R.init)) == int));\n    static assert(is(typeof(bar2(R.init, x)) == int));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15156\n\n// https://issues.dlang.org/show_bug.cgi?id=15156\nauto f15116a(T)(string s, string arg2) { return 1; }\nauto f15116b(T)(int    i, string arg2) { return 2; }\n\ntemplate bish15116(T)\n{\n    alias bish15116 = f15116a!T;\n    alias bish15116 = f15116b!T;\n}\n\nvoid test15116()\n{\n    alias func = bish15116!string;\n    assert(func(\"\", \"\") == 1);\n    assert(func(12, \"\") == 2);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15152\n\nvoid test15152()\n{\n    void func(string M)() { }\n\n    struct S\n    {\n        enum name = \"a\";\n    }\n\n    enum s = S.init;\n    func!(s.name);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15352\n\nstruct S15352(T, T delegate(uint idx) supplier)\n{\n}\n\nauto make15352a(T, T delegate(uint idx) supplier)()\n{\n    enum local = supplier;      // OK\n    S15352!(T, local) ret;\n    return ret;\n}\n\nauto make15352b(T, T delegate(uint idx) supplier)()\n{\n    S15352!(T, supplier) ret;   // OK <- Error\n    return ret;\n}\n\nvoid test15352()\n{\n    enum dg = delegate(uint idx) => idx;\n    auto s1 = S15352!(uint, dg)();\n    auto s2 = make15352a!(uint, dg)();\n    auto s3 = make15352b!(uint, dg)();\n    assert(is(typeof(s1) == typeof(s2)));\n    assert(is(typeof(s1) == typeof(s3)));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15623\n\nstruct WithFoo15623a { void foo() {} }\nstruct WithFoo15623b { void foo() {} }\nstruct WithFoo15623c { void foo() {} }\nstruct WithFoo15623d { void foo() {} }\n\nstruct WithoutFoo15623a {}\nstruct WithoutFoo15623b {}\nstruct WithoutFoo15623c {}\nstruct WithoutFoo15623d {}\n\nstruct CallsFoo15623(T)\n{\n    T t;\n    void bar() { t.foo(); }     // error occurs during TemplateInstance.semantic3\n}\n\n// Instantiations outside of function bodies\nstatic assert( is(CallsFoo15623!WithFoo15623a));\nstatic assert(!is(CallsFoo15623!WithoutFoo15623a));                     // OK <- NG\nstatic assert( __traits(compiles, CallsFoo15623!WithFoo15623b));\nstatic assert(!__traits(compiles, CallsFoo15623!WithoutFoo15623b));     // OK <- NG\n\n// Instantiations inside function bodies (OK)\nstatic assert( is(typeof({ alias Baz = CallsFoo15623!WithFoo15623c; return Baz.init; }())));\nstatic assert(!is(typeof({ alias Baz = CallsFoo15623!WithoutFoo15623c; return Baz.init; }())));\nstatic assert( __traits(compiles, { alias Baz = CallsFoo15623!WithFoo15623d; return Baz.init; }()));\nstatic assert(!__traits(compiles, { alias Baz = CallsFoo15623!WithoutFoo15623d; return Baz.init; }()));\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15781\n\nvoid test15781()\n{\n    static struct S\n    {\n        int value;\n    }\n\n    T foo(T)(T a, T b)\n    {\n        return T();\n    }\n\n    const S cs;\n          S ms;\n    static assert(is(typeof(foo(ms, ms)) ==       S));\n    static assert(is(typeof(foo(ms, cs)) == const S));\n    static assert(is(typeof(foo(cs, ms)) == const S));\n    static assert(is(typeof(foo(cs, cs)) == const S));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16042\n\nstruct Foo16042 {}\n\nauto map16042(alias func, T)(T t)\n{\n    return func(t);\n}\n\nauto toChars16042(R)(R r) if (is(R == int[]))\n{\n    Foo16042 f;\n    assert(toChars16042(f) == 1);               // OK\n    assert(map16042!(toChars16042)(f) == 1);    // OK <- NG\n    assert(map16042!((toChars16042))(f) == 1);  // OK\n}\n\nauto toChars16042(Foo16042 f)\n{\n    return 1;\n}\n\nvoid test16042()\n{\n    [1].toChars16042();\n}\n\n// ---\n\nauto fn16042(R)(R r) if (is(R == int[])) {}\nauto fn16042(Foo16042 f) { return 1; }\n\nstruct Namespace16042\n{\n    alias fn = fn16042!(int[]);\n}\n\nvoid test16042b()\n{\n    Foo16042 f;\n\n    with (Namespace16042)\n    {\n        static assert(!__traits(compiles, fn(f)));              // NG\n        static assert(!__traits(compiles, map16042!(fn)(f)));   // should be NG -> actually NG\n        static assert(!__traits(compiles, map16042!((fn))(f))); // NG\n    }\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15243\n\nstruct S15243(Types...)\n{\n    void apply1(U)(U delegate(Types[0]) f0) {}\n\n    void apply2(U)(U delegate(Types) f0) {}\n\n    void apply3(U)(U delegate(Types[1..$]) f0) {}\n}\n\nvoid test15243()\n{\n    int f1(int) { return 0; }\n    int f2(int, long) { return 0; }\n    int f3(long, string) { return 0; }\n\n    S15243!(int) s1;\n    s1.apply1(&f1);\n    s1.apply2(&f1);\n\n    S15243!(int, long) s2;\n    s2.apply2(&f2);\n\n    S15243!(int, long, string) s3;\n    s3.apply3(&f3);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15653\n\nalias TypeTuple15653(T...) = T;\n\nvoid test15653()\n{\n    void foo(U, T)(const T x)     { static assert(is(T == U)); }\n    void bar(U, T)(immutable T x) { static assert(is(T == U)); }\n\n    struct X { int a; long[2] b; }\n    struct Y { int* a; long[] b; }\n\n    foreach (U; TypeTuple15653!( byte,    short,   int,  long,\n                                ubyte,   ushort,  uint, ulong,\n                                 float,  double,  real,\n                                ifloat, idouble, ireal,\n                                cfloat, cdouble, creal,\n                                void delegate(),\n                                int[2], X, X[2]))\n    {\n        foo!U(U.init);      // OK\n        bar!U(U.init);      // Was error, now OK\n\n        U u;\n        foo!U(u);           // OK\n        bar!U(u);           // Was error, now OK\n    }\n\n    foreach (U; TypeTuple15653!(void*, int**, long[], double*[2]))\n    {\n        foo!U(U.init);      // OK\n        bar!U(U.init);      // Was error, now OK\n\n        U u;\n        foo!U(u);\n        static assert(!__traits(compiles, bar!U(u)), U.stringof);\n    }\n\n    foreach (U; TypeTuple15653!(Object, Y, Y[2], int[int]))\n    {\n        foo!U(U.init);      // OK\n        static assert(!__traits(compiles, bar!U(U.init)), U.stringof);\n\n        U u;\n        foo!U(u);           // OK\n        static assert(!__traits(compiles, bar!U(u)), U.stringof);\n    }\n}\n\n/******************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test1780();\n    test3608();\n    test5893();\n    test6404();\n    test2246();\n    test2296();\n    bug4984();\n    test2579();\n    test2803();\n    test6613();\n    test5886();\n    test5393();\n    test5896();\n    test6825();\n    test6789();\n    test2778();\n    test2778aa();\n    test2778get();\n    test6208a();\n    test6208b();\n    test6208c();\n    test6738();\n    test6780();\n    test6810();\n    test6891();\n    test6994();\n    test6764();\n    test3467();\n    test4413();\n    test5525();\n    test5801();\n    test10();\n    test7037();\n    test7124();\n    test7359();\n    test7416();\n    test7563();\n    test7572();\n    test7580();\n    test7585();\n    test7671();\n    test7672();\n    test7684();\n    test11a();\n    test11b();\n    test7769();\n    test7873();\n    test7933();\n    test8094();\n    test12();\n    test8125();\n    test13();\n    test14();\n    test8129();\n    test8238();\n    test8669();\n    test8833();\n    test8976();\n    test8940();\n    test9022();\n    test9026();\n    test9038();\n    test9076();\n    test9100();\n    test9124a();\n    test9124b();\n    test9143();\n    test9266();\n    test9536();\n    test9578();\n    test9596();\n    test9837();\n    test9874();\n    test9885();\n    test9971();\n    test9977();\n    test10083();\n    test10592();\n    test11242();\n    test10811();\n    test10969();\n    test11271();\n    test11533();\n    test11818();\n    test11843();\n    test11872();\n    test12122();\n    test12207();\n    test12376();\n    test13235();\n    test13294();\n    test13299();\n    test13374();\n    test13378();\n    test13379();\n    test13484();\n    test13694();\n    test14836();\n    test14735();\n    test14802();\n    test15116();\n    test16042();\n    test16042b();\n    test15243();\n    test15653();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test10.d",
    "content": "// EXTRA_SOURCES: imports/test10a.d\n\nimport imports.test10a;\n\nextern(C) int printf(const char*, ...);\n\nint main()\n{\n    imports.test10a.init();\n    printf(\"it is %d\\n\", it[0]);\n    assert(it[0] == 32);\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test10378.d",
    "content": "\nint writeln() { return 3; }\n\nstruct S {\n    import imports.bar10378;\n    void abc() { assert(writeln() == 3); }\n}\n\n\nvoid main() {\n    S s;\n    s.abc();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test10441.d",
    "content": "// EXTRA_SOURCES: imports/test10441b.d imports/test10441c.d\n\nimport test10441b;\n\nvoid main()\n{\n    boo(1);\n    foo();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test10573.d",
    "content": "// EXTRA_SOURCES: imports/test10573a.d\n\nimport imports.test10573a;\nvoid main(string[] args) {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test10736.d",
    "content": "// EXTRA_SOURCES: imports/test10736a.d imports/test10736b.d\n\nimport imports.test10736a;\nimport imports.test10736b;\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test10942.d",
    "content": "// REQUIRED_ARGS: -g\n\nimport std.string;\n\nstring getEnum(size_t count)\n{\n    string en;\n    en ~= \"enum KeyCode\\n {    \\n\";\n\n    foreach (i; 0 .. count)\n    {\n        en ~= format(\"    memb_%s = %s,\\n\", i+1, i+1);\n    }\n\n    en ~= \"} \";\n    return en;\n}\n\n// Linker warning: Warning 161: Unknown CV version, ignored\n// mixin(getEnum(1024));\n\n// ICE\nmixin(getEnum(1087));\n\nvoid main() { }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test11.d",
    "content": "// REQUIRED_ARGS:\n\nextern(C) int printf(const char*, ...);\nextern(C) size_t strlen(const char*);\n\n/**************************************/\n\nalias strlen foo1;\n\nvoid test1()\n{\n    const(char) *p = \"bar\";\n    size_t i = foo1(p);\n    assert(i == 3);\n}\n\n/**************************************/\n\ntemplate Foo2(T)\n{\n    alias T t;\n}\n\nalias Foo2!(int) t1;\nalias Foo2!(int).t t2;\nalias t1.t t3;\nalias t2 t4;\nalias Foo2!(int) t5;\n\nvoid test2()\n{\n    t1.t v1;\n    t2 v2;\n    t3 v3;\n    t4 v4;\n    t5.t v5;\n    int *p;\n\n    p = &v1;\n    p = &v2;\n    p = &v3;\n    p = &v4;\n    p = &v5;\n}\n\n\n/**************************************/\n\ndebug = stdchar;\n\ndebug(mychar)\n{\n    alias byte mychar;\n}\n\nvoid test3()\n{\n    debug(mychar)\n    {\n    mychar[] line=cast(mychar[])cast(char[])\"It is a long line.\";\n    mychar[] delimiter=cast(mychar[])cast(string)\"is\";\n    }\n\n    debug(stdchar)\n    {\n    string line=\"It is a long line.\";\n    string delimiter=\"is\";\n    }\n\n    debug(stdbyte)\n    {\n    byte[] line=cast(byte[])cast(string)\"It is a long line.\";\n    byte[] delimiter=cast(byte[])cast(string)\"is\";\n    }\n\n    debug(stdwchar)\n    {\n    wstring line=\"It is a long line.\";\n    wstring delimiter=\"is\";\n    }\n    int ptr=3;\n\n    size_t dl=delimiter.length;\n    size_t pl=ptr+dl;\n\n    assert(line[ptr..pl]==delimiter[]);\n}\n\n\n/**************************************/\n\nvoid test4()\n{\n    byte* p;\n\n    version(D_LP64)\n        assert(p.sizeof == 8);\n    else\n        assert(p.sizeof == 4);\n}\n\n\n/**************************************/\n\n\nclass Foo6\n{\n}\n\nvoid test6()\n{\n    Foo6 foo = new Foo6();\n\n     with (foo)\n     {\n         int x;\n\n         x = 4;\n     }\n}\n\n/**************************************/\n\nint i7 = 3;\n\nvoid test7()\n{\n    switch (i7)\n    {\n    default: assert(0);\n    case 3:\n        int x;\n\n        x = 4;\n    }\n}\n\n/**************************************/\n\nvoid test8()\n{\n    string a = \"a\nb\nc\";\n    assert(a.length == 5);\n    assert(a[1] == '\\n');\n}\n\n/**************************************/\n\n\nstruct Foo9 { char c; char bar() { return c; } }\n\nFoo9 makeFoo() { Foo9 f; return f; }\n\nvoid callFoo (Foo9 a)\n{\n    a.bar();\n}\n\nvoid test9()\n{\n    callFoo(makeFoo ());\n}\n\n/**************************************/\n\n\nstruct Foo10 { }\n\nFoo10 makeFoo10() { Foo10 f; return f; }\n\nvoid callFoo (Foo10 a)\n{\n}\n\nvoid test10()\n{\n    callFoo(makeFoo10());\n}\n\n/**************************************/\n\nstruct Color\n{ int x; }\n\nColor[3] colors;\n\nColor eval(float x, float y)\n{\n    colors[1].x = 7;\n    return colors[1];\n}\n\nvoid test11()\n{\n    Color c;\n\n    c = eval(1.0, 2.0);\n    assert(c.x == 7);\n}\n\n/**************************************/\n\nstruct Size12\n{\n  int width;\n  int height;\n}\n\nint x12;\n\nvoid foo12(out Size12 sz)\n{\n  sz.width = 2;\n\n  if(sz.width == 2)\n    x12 = 1;\n}\n\n\nvoid test12()\n{\n  Size12 sz;\n\n  foo12(sz);\n  assert(x12 == 1);\n  assert(sz.width == 2);\n}\n\n/**************************************/\n\n\ninterface D13\n{\n    void setHostFrame();\n}\n\nclass A13 : D13\n{\n    void setHostFrame()\n    {\n    }\n\n    char         group;\n}\n\n\nvoid setLayout(D13 lo)\n{\n    printf(\"lo = %p\\n\", lo);\n    lo.setHostFrame();\n    printf(\"ok\\n\");\n}\n\n\nvoid test13()\n{\n    A13 a = new A13();\n    printf(\"a  = %p\\n\", a);\n    setLayout(a);\n}\n\n/**************************************/\n\nvoid test14()\n{\n    while(false)\n    {\n        static int a;\n    }\n}\n\n\n/**************************************/\n\nalias void delegate(int) t_func;\n\nclass Foo15\n{\n   t_func func1;\n   int x;\n\n   void dothis()\n   {\n     if (func1)\n        func1(4);\n     else\n        x = 3;\n   }\n\n   void func(int num) { x = num; }\n}\n\nvoid test15()\n{\n   Foo15 a = new Foo15;\n   a.dothis();\n   assert(a.x == 3);\n   a.func1 = &a.func;\n   a.dothis();\n   assert(a.x == 4);\n}\n\n\n/**************************************/\n\nint[] foo16(byte[] a)\n{\n    return cast(int[])a;\n}\n\nvoid test16()\n{\n    byte[12] b;\n    int[] i;\n\n    i = foo16(b);\n    assert(i.length == 3);\n}\n\n/**************************************/\n\nvoid test17()\n{\n  {\n    float x = 10;\n    x %= 4;\n    printf(\"x = %g\\n\", x);\n    assert(x == 2);\n    x = 10;\n    x = x % 4;\n    printf(\"x = %g\\n\", x);\n    assert(x == 2);\n    x = 4;\n    x = 10 % x;\n    printf(\"x = %g\\n\", x);\n    assert(x == 2);\n  }\n  {\n    double y = 10;\n    y %= 4;\n    printf(\"y = %g\\n\", y);\n    assert(y == 2);\n    y = 10;\n    y = y % 4;\n    printf(\"y = %g\\n\", y);\n    assert(y == 2);\n    y = 4;\n    y = 10 % y;\n    printf(\"y = %g\\n\", y);\n    assert(y == 2);\n  }\n  {\n    real z = 10;\n    z %= 4;\n    printf(\"z = %Lg\\n\", z);\n    assert(z == 2);\n    z = 10;\n    z = z % 4;\n    printf(\"z = %Lg\\n\", z);\n    assert(z == 2);\n    z = 4;\n    z = 10 % z;\n    printf(\"z = %Lg\\n\", z);\n    assert(z == 2);\n  }\n}\n\n\n/**************************************/\n\nstruct Bar18 { }\n\nstruct Foo18\n{\n     static Bar18 x = { };\n}\n\nvoid test18()\n{\n     const Bar18 b = Foo18.x;\n}\n\n\n/**************************************/\n\nint x19 = 10;\n\nvoid test19()\n{   bool b;\n\n    b = cast(bool)x19;\n    assert(b == true);\n}\n\n/**************************************/\n\nclass A20\n{\n  int abc() { return 3; }\n\n  alias abc def;\n}\n\nvoid test20()\n{\n    int i;\n    A20 a = new A20();\n\n    i = a.def();\n    assert(i == 3);\n}\n\n\n/**************************************/\n\nvoid test21()\n{\n    string s;\n    s = 1 ? \"a\" : \"b\";\n    assert(s == \"a\");\n}\n\n/**************************************/\n\nclass Foo22\n{\n}\n\nclass Bar22 : Foo22\n{\n}\n\nclass Abc22\n{\n    Foo22 test() { return null; }\n}\n\nclass Def22 : Abc22\n{\n    override Bar22 test() { return new Bar22; }\n}\n\nvoid testx22(Abc22 a)\n{\n    assert(a.test() !is null);\n}\n\nvoid test22()\n{\n    Def22 d = new Def22();\n\n    testx22(d);\n}\n\n/**************************************/\n\nstruct foo23\n{\n   static struct bar\n   {\n      int x;\n   }\n}\n\nvoid test23()\n{\n   //printf (\"%d\\n\", foo23.bar.sizeof);\n   assert(foo23.bar.sizeof == int.sizeof);\n}\n\n\n/**************************************/\n\nvoid test24()\n{\n  struct Test\n  {\n    int i;\n\n    bool bar(int a)\n    {\n      i = a;\n      return true;\n    }\n  }\n\n  Test t;\n  assert(t.bar(3));\n}\n\n\n/**************************************/\n\nvoid test25()\n{\n    {   const int [] list = [ 1, 2 ];\n      assert(list[0] == 1);\n      assert(list[1] == 2);\n    }\n\n    {   const int [] list = [ 3, 4 ];\n      assert(list[0] == 3);\n      assert(list[1] == 4);\n    }\n}\n\n\n/**************************************/\n\nvoid test26()\n{\n   while (0)\n   {\n      int x;\n   }\n\n   while (0)\n   {\n      int x;\n   }\n}\n\n\n/**************************************/\n\nstruct NODE27 {\n    int data;\n    shared(NODE27) *next;\n}\n\nstatic shared NODE27[3] nodetbl =\n[\n    {   0,cast(shared(NODE27)*)nodetbl + 1},\n    {   0,cast(shared(NODE27)*)nodetbl + 2},\n    {   0,null}\n];\n\nstatic shared NODE27[3] nodetbl2 = [\n    {   0,&nodetbl2[1]},\n    {   0,&nodetbl2[2]},\n    {   0,null}\n];\n\nvoid test27()\n{\n}\n\n\n/**************************************/\n\nclass Foo28\n{\n    protected int x;\n\n    static class Bar\n    {\n       Foo28 f;\n\n       int method () { return f.x; }\n    }\n}\n\nvoid test28()\n{\n}\n\n\n/**************************************/\n\nvoid test29()\n{\n  int[immutable(byte)[]] foo;\n\n  static immutable(byte)[] bar = [ 65, 66, 67 ];\n\n  foo[bar] = 1;\n  assert(foo[bar] == 1);\n}\n\n/**************************************/\n\nclass A30\n{\n   static class Child\n   {\n   }\n}\n\n\nclass B30\n{\n   static class Child\n   {\n      static int value = 6;\n   }\n}\n\nvoid test30()\n{\n   printf (\"%d\\n\", B30.Child.value);\n   assert(B30.Child.value == 6);\n}\n\n\n/**************************************/\n\nvoid test31()\n{\n    float b;\n    b -= 1.0;\n    b += 1.0;\n}\n\n/**************************************/\n\nclass Foo32\n{\n    struct Bar\n    {\n        int x;\n    }\n}\n\nvoid test32()\n{\n    with (new Foo32)\n    {\n        Bar z;\n        z.x = 5;\n    }\n}\n\n\n/**************************************/\n\nstring[2][] foo33;\n\nvoid test33()\n{\n    string[2] bar;\n\n    bar[1] = \"hello\";\n    foo33 ~= bar;\n    assert(foo33[0][1] == \"hello\");\n}\n\n\n/**************************************/\n\n\nvoid test34()\n{\n try {\n  int i = 0;\n  printf( \"i:%d\\n\", i );\n } finally {\n  printf( \"Done\\n\" );\n }\n try {\n  int i = 1;\n  printf( \"i:%d\\n\", i );\n } finally {\n  printf( \"Done\\n\" );\n }\n}\n\n\n/**************************************/\n\nclass Bar35 {}\n\ntemplate Foo35( T )\n{\n    void func() { };\n}\n\nvoid test35()\n{\n try {\n  alias Foo35!( Bar35 ) filter;\n } catch (Exception e) {\n  printf( \"Exception %.*s\", e.msg.length, e.msg.ptr );\n } finally {\n  printf( \"Done0.\" );\n }\n}\n\n\n/**************************************/\n\nvoid test36()\n{\n    enum {A=1}\n    enum {B=A?0:1}\n    assert(A == 1);\n    assert(B == 0);\n}\n\n/**************************************/\n\nstruct A37\n{\n    int a;\n}\n\nstruct B37\n{\n    int a;\n    int b;\n}\n\nstruct C37\n{\n    int a;\n    int b;\n    int c;\n}\n\nstruct D37\n{\n    byte a,b,c;\n}\n\nvoid test37()\n{\n    A37 a;\n    B37 b;\n    C37 c;\n    D37 d;\n\n    assert(a.a == 0);\n    assert(b.a == 0 && b.b == 0);\n    assert(c.a == 0 && c.b == 0 && c.c == 0);\n    assert(d.a == 0 && d.b == 0 && d.c == 0);\n}\n\n\n/**************************************/\n\nint function() fp18;\n\nextern(Windows) int func18()\n{\n    static int otherfunc()\n    {   return 18; }\n\n    fp18 = &otherfunc;\n    return fp18();\n}\n\nvoid test38()\n{\n    assert(func18() == 18);\n}\n\n\n/**************************************/\n\nclass bar39\n{\n  struct _sub\n  {\n    bool a;\n    string d;\n  };\n  _sub mySub;\n};\n\nclass foo39\n{\n  bar39._sub[] subArray;\n\n  this(bar39[] arr)\n  {\n    for(int i=0; i<arr.length; i++)\n      subArray ~= arr[i].mySub;\n  };\n};\n\n\nvoid test39()\n{\n}\n\n\n/**************************************/\n\nvoid test40()\n{\n    void* h;\n\n    h = h.init;\n    assert(h == cast(void*)0);\n}\n\n/**************************************/\n\nint test41()\n{\n label:\n int foo;\n foo = 0;\n return foo;\n}\n\n\n/**************************************/\n\nstruct A42\n{\n    invariant()\n    {\n    }\n\n    B42 *findPool()\n    {\n        return null;\n    }\n\n}\n\nstruct B42\n{\n    int cmp(B42 *p2)\n    {\n        return 0;\n    }\n}\n\nvoid test42()\n{\n}\n\n\n/**************************************/\n\nvoid test43()\n{\n    real a = 0.9;\n    ulong b = cast(ulong) a;\n    printf(\"%u\", cast(uint) b);\n    assert(cast(uint) b == 0);\n\n    int c = cast(int) a;\n    printf(\"%i\", c);\n    assert(c == 0);\n}\n\n\n/**************************************/\n\nvoid test44()\n{\n   switch(\"asdf\")\n   {\n   case \"asdf\":\n     printf(\"asdf\\n\");\n     break;\n\n\n   case \"jkl\":\n     printf(\"jkl\\n\");\n     assert(0);\n     break;\n\n\n   default:\n     printf(\"default\\n\");\n     assert(0);\n   }\n}\n\n\n/**************************************/\n\nvoid func45(string a)\n{\n    assert(a.length == 5);\n}\n\nvoid test45()\n{\n    char[5] foo;\n\n    foo[] = \"hello\";\n    printf(\"'%.*s'\\n\", foo.length, foo.ptr);\n    func45(cast(string)foo);\n}\n\n/**************************************/\n\nstruct Foo46\n{\n    int x;\n}\n\nvoid test46()\n{\n    Foo46 f;\n\n    with (f)\n    {\n        x = 3;\n    }\n    assert(f.x == 3);\n}\n\n/**************************************/\n\nstruct Bar48\n{\n    uint k;\n    ubyte m;\n}\n\nBar48 makebar48() { Bar48 b; return b; }\n\nvoid test48()\n{\n    Bar48 b = makebar48();\n}\n\n/**************************************/\n\nvoid testx49() { printf(\"testx49()\\n\"); }\n\nvoid test49() { return testx49(); }\n\n/**************************************/\n\nint testx50() { printf(\"testx50()\\n\"); return 3; }\n\nvoid test50() { return cast(void)testx50(); }\n\n/**************************************/\n\nclass A51\n{\n    static typeof(this) foo()\n    {\n        return new A51();\n    }\n\n    this()\n    {\n        bar = 3;\n    }\n\n    int bar;\n}\n\nclass B51 : A51\n{\n    static typeof(super) b;\n}\n\nstruct C51\n{\n    typeof(&this) x;\n}\n\nvoid test51()\n{\n    A51 a = A51.foo();\n    assert(a.bar == 3);\n\n    B51.b = a;\n    assert(B51.b.bar == 3);\n    assert(B51.b.classinfo == A51.classinfo);\n\n    C51 c;\n    c.x = &c;\n}\n\n\n/**************************************/\n\nclass A52\n{\n    char get() { return 'A'; }\n\n    char foo() { return typeof(this).get(); }\n    char bar() { return A52.get(); }\n}\n\nclass B52 : A52\n{\n    override char get() { return 'B'; }\n}\n\nvoid test52()\n{\n    B52 b = new B52();\n\n    assert(b.foo() == 'A');\n    assert(b.bar() == 'A');\n    assert(b.get() == 'B');\n}\n\n/**************************************/\n\nstruct A53\n{\n    int b() { return 1; }\n}\n\nint x53()\n{\n    A53 a;\n    return a.b;\n}\n\nvoid test53()\n{\n    assert(x53() == 1);\n}\n\n/**************************************/\n\nclass A54\n{\n    void a()\n    {\n        printf(\"A54.a\\n\");\n    }\n\n    void b()\n    {\n        typeof(this).a();\n    }\n}\n\nclass B54 : A54\n{\n    override void a()\n    {\n        printf(\"B54.a\\n\");\n        assert(0);\n    }\n}\n\nvoid test54()\n{\n    B54 b = new B54();\n\n    b.b();\n}\n\n\n/**************************************/\n\nint foo55(int x = 5)\n{\n    printf(\"x = %d\\n\", x);\n    return x;\n}\n\nvoid test55()\n{   int i;\n\n    i = foo55(6);\n    assert(i == 6);\n    i = foo55();\n    assert(i == 5);\n}\n\n/**************************************/\n\nclass A56\n{\n    int foo(int x = 5)\n    {\n        printf(\"A56.x = %d\\n\", x);\n        return x;\n    }\n}\n\nclass B56 : A56\n{\n    override int foo(int x = 7)\n    {\n        printf(\"B56.x = %d\\n\", x);\n        return x;\n    }\n}\n\n\nvoid test56()\n{   int i;\n    B56 b = new B56();\n\n    i = b.foo(6);\n    assert(i == 6);\n    i = b.foo();\n    assert(i == 7);\n}\n\n\n/**************************************/\n\nvoid test57()\n{\n    char c;\n    wchar w;\n    dchar d;\n\n    printf(\"c = %x, w = %x, d = %x\\n\", c, w, d);\n    assert(c == 0xFF);\n    assert(w == 0xFFFF);\n    assert(d == 0xFFFF);\n}\n\n/**************************************/\n\nvoid test58()\n{\n    static int x;\n\n    static class S\n    {\n        static this()\n        {\n            printf (\"static constructor\\n\");\n            x = 10;\n        }\n\n        this()\n        {\n            printf (\"class constructor\\n\");\n        }\n    }\n\n    assert(x == 10);\n    new S;\n}\n\n/**************************************/\n\nstruct S61 {\n    int a, b, c, d;\n}\n\nvoid rec(int n, S61 t)\n{\n if (n > 0) {\n  t.b++;\n  rec(n-1,t);\n }\n}\n\nvoid test61()\n{\n    S61 F;\n\n    rec(100, F);\n}\n\n/**************************************/\n\nclass A62\n{\n    static A62 test(int q=0) {\n        return null;\n    }\n}\n\nA62 foo62()\n{\n    return A62.test;\n}\n\nvoid test62()\n{\n    foo62();\n}\n\n\n/**************************************/\n\nclass A63\n{\n     private import std.file;\n     alias std.file.getcwd getcwd;\n}\n\nvoid test63()\n{\n     A63 f = new A63();\n     auto s = f.getcwd();\n     printf(\"%.*s\\n\", s.length, s.ptr);\n}\n\n\n/**************************************/\n\ndebug = 3;\n\nvoid test64()\n{\n    debug(5)\n    {\n        assert(0);\n    }\n    debug(3)\n    {\n        int x = 3;\n    }\n    assert(x == 3);\n}\n\n/**************************************/\n\nversion = 3;\n\nvoid test65()\n{\n    version(5)\n    {\n        assert(0);\n    }\n    version(3)\n    {\n        int x = 3;\n    }\n    assert(x == 3);\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8809\n\nvoid test8809()\n{\n    static class B\n    {\n        char foo() { return 'B'; }\n    }\n    static class C : B\n    {\n        char test1Bx() { return B.foo(); }\n        char test1Cx() { return C.foo(); }\n        char test1Dx() { return   foo(); }\n        char test1By() { return this.B.foo(); }\n        char test1Cy() { return this.C.foo(); }   // cannot compile -> OK\n        char test1Dy() { return this.  foo(); }\n        char test1Bz() { return typeof(super).foo(); }\n        char test1Cz() { return typeof(this). foo(); }\n      //char test1Dz();\n\n        char test2Bx() { return { return B.foo(); }(); }\n        char test2Cx() { return { return C.foo(); }(); }\n        char test2Dx() { return { return   foo(); }(); }\n        char test2By() { return { return this.B.foo(); }(); }\n        char test2Cy() { return { return this.C.foo(); }(); }   // cannot compile -> OK\n        char test2Dy() { return { return this.  foo(); }(); }\n        char test2Bz() { return { return typeof(super).foo(); }(); }\n        char test2Cz() { return { return typeof(this). foo(); }(); }\n      //char test2Dz();\n\n        char test3Bx() { return (new class Object { char bar() { return B.foo(); } }).bar(); }\n        char test3Cx() { return (new class Object { char bar() { return C.foo(); } }).bar(); }\n        char test3Dx() { return (new class Object { char bar() { return   foo(); } }).bar(); }\n\n        override char foo() { return 'C'; }\n    }\n    static class D : C\n    {\n        override char foo() { return 'D'; }\n    }\n\n    C c = new D();\n\n    assert(c.test1Bx() == 'B');\n    assert(c.test1Cx() == 'C');\n    assert(c.test1Dx() == 'D');\n    assert(c.test1By() == 'B');\n    assert(c.test1Cy() == 'C');\n    assert(c.test1Dy() == 'D');\n    assert(c.test1Bz() == 'B'); // NG('D') -> OK\n    assert(c.test1Cz() == 'C');\n  //assert(c.test1Dz() == 'D');\n\n    assert(c.test2Bx() == 'B'); // NG('D') -> OK\n    assert(c.test2Cx() == 'C'); // NG('D') -> OK\n    assert(c.test2Dx() == 'D');\n    assert(c.test2By() == 'B');\n    assert(c.test2Cy() == 'C');\n    assert(c.test2Dy() == 'D');\n    assert(c.test2Bz() == 'B'); // NG('D') -> OK\n    assert(c.test2Cz() == 'C'); // NG('D') -> OK\n  //assert(c.test2Dz() == 'D');\n\n    assert(c.test3Bx() == 'B'); // NG('D') -> OK\n    assert(c.test3Cx() == 'C'); // NG('D') -> OK\n    assert(c.test3Dx() == 'D');\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9734\n\nvoid test9734()\n{\n    class C {}\n    class D : C\n    {\n        static bool test(C) { return true; }\n\n        void foo()() if (is(typeof(test(super)))) {}\n        void bar()() if (is(typeof(super) == C)) {}\n    }\n    void baz()() if (is(typeof(super))) {}\n\n    auto d = new D();\n    d.foo();\n    d.bar();\n    static assert(!__traits(compiles, baz()));\n}\n\n/**************************************/\n\nint main(string[] argv)\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test56();\n    test57();\n    test58();\n    test61();\n    test62();\n    test63();\n    test64();\n    test65();\n    test8809();\n    test9734();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test11039.d",
    "content": "\n// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/test11039b.d\n\nimport imports.test11039b;\n\nstruct SomeStruct(T)\n{\n    T field;\n    T getInnerField()\n    {\n        return field;\n    }\n}\n\nstatic globalField = SomeStruct!string(\"Hello!\");\n\nvoid main()\n{\n    globalField.getInnerField();\n    anotherGlobalField.getInnerField();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test11239.d",
    "content": "// EXTRA_SOURCES: imports/inc11239.d\n// REQUIRED_ARGS: -debug\n// COMPILE_SEPARATELY\n// PERMUTE_ARGS:\n\nimport imports.inc11239;\n\nvoid main()\n{\n    foo(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test11447a.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/a11447.d\n// PERMUTE_ARGS: -allinst\n\nimport imports.a11447;\n\nvoid main()\n{\n    A a;\n    TTT.yyy(a);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test11447b.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/b11447.d\n// PERMUTE_ARGS: -allinst\n\nimport imports.b11447;\n\nvoid main()\n{\n    A a;\n    aaa(a);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test11447c.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/c11447.d\n// PERMUTE_ARGS: -allinst -w -debug -g\n\nimport imports.c11447;\n\nvoid main()\n{\n    auto a = new A();\n    TemplateInstancier().instanciateFromResolvedArgs(a);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test11745.d",
    "content": "// EXTRA_SOURCES: imports/test11745b.d\n// REQUIRED_ARGS: -unittest\n// PERMUTE_ARGS:\nimport imports.test11745b;\n\nvoid main()\n{\n        // Test that we can invoke all unittests, including private ones.\n        assert(__traits(getUnitTests, imports.test11745b).length == 3);\n        foreach(test; __traits(getUnitTests, imports.test11745b))\n        {\n                test();\n        }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test11863.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/std11863conv.d imports/std11863format.d\n\nimport imports.std11863conv;\n\nvoid main()\n{\n    auto s = to!string(15, 10);\n    assert(s == \"15\");  // failure\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test12.d",
    "content": "// PERMUTE_ARGS: -unittest -O -release -inline -fPIC -g\n\nextern(C) int printf(const char*, ...);\nextern(C) int sprintf(char*, const char*, ...);\n\n/**************************************/\n\nvoid test1()\n{\n     bool x;\n     int i;\n\n     i = !(\"bar\" == \"bar\");\n     assert(i == 0);\n\n     i = \"bar\" != \"bar\";\n     assert(i == 0);\n\n     i = \"bar\" == \"bar\";\n     assert(i == 1);\n\n     x = \"bar\" != \"bar\";\n     assert(x == false);\n\n     assert(\"bar\" == \"bar\");\n\n     x = \"bar\" == \"bar\";\n     assert(x == true);\n\n     /+ ---- +/\n\n     i = !(\"foo\" == \"bar\");\n     assert(i == 1);\n\n     i = \"foo\" != \"bar\";\n     assert(i == 1);\n\n     i = \"foo\" == \"bar\";\n     assert(i == 0);\n\n     x = \"foo\" != \"bar\";\n     assert(x == true);\n\n     assert(\"foo\" != \"bar\");\n\n     x = \"foo\" == \"bar\";\n     assert(x == false);\n\n}\n\n\n/**************************************/\n\nvoid test2()\n{\n     bool x;\n     int i;\n\n     i = !(\"bar\" <= \"bar\");\n     assert(i <= 0);\n\n     i = \"bar\" > \"bar\";\n     assert(i == 0);\n\n     i = \"bar\" >= \"bar\";\n     assert(i == 1);\n\n     x = \"bar\" < \"bar\";\n     assert(x == false);\n\n     assert(\"bar\" <= \"bar\");\n\n     x = \"bar\" <= \"bar\";\n     assert(x == true);\n\n     /+ ---- +/\n\n     i = !(\"foo\" < \"bar\");\n     assert(i == 1);\n\n     i = \"foo\" > \"bar\";\n     assert(i == 1);\n\n     i = \"foo\" < \"bar\";\n     assert(i == 0);\n\n     x = \"foo\" >= \"bar\";\n     assert(x == true);\n\n     assert(\"foo\" >= \"bar\");\n\n     x = \"foo\" <= \"bar\";\n     assert(x == false);\n\n}\n\n\n/**************************************/\n\nbool all(string array, bool function(char) predicate) {\n    for (int i = 0; i < array.length; i++) {\n        if (!predicate(array[i])) {\n            return false;\n        }\n    }\n    return true;\n}\n\nbool all(string array, bool delegate(char) predicate) {\n    for (int i = 0; i < array.length; i++) {\n        if (!predicate(array[i])) {\n            return false;\n        }\n    }\n    return true;\n}\n\nbool isVowel(char c) {\n    return (c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u');\n}\n\nclass Character {\n    private char letter;\n    this(char c) {\n        this.letter = c;\n    }\n    public bool isLetter(char c) {\n        return this.letter == c;\n    }\n}\n\nvoid test3()\n{\n    Character a = new Character('a');\n    bool delegate(char) isLetter;\n    isLetter = &a.isLetter;\n    bool i;\n\n    i = all(\"aeiouoeieuiei\", &isVowel);\n    assert(i == true);\n\n    i = all(\"aeiouoeieuiei\", isLetter);\n    assert(i == false);\n}\n\n\n/**************************************/\n\nint[] fun(int i)\n    in\n    {\n        assert(i > 0);\n    }\n    out (result)\n    {\n        assert(result[0] == 2);\n    }\n    body\n    {\n        char result;\n        int[] res = new int[10];\n        res[] = i;\n        int isZero = (result == 0xFF);\n        assert(isZero);\n        return res;\n    }\n\nvoid test4()\n{\n    int[] values = fun(2);\n}\n\n\n/**************************************/\n\n\nconst uint D3DSP_DSTMOD_SHIFT = 20;\n\nconst uint D3DSP_DSTMOD_MASK = 0x00F00000;\n\n\nenum D3DSHADER_PARAM_DSTMOD_TYPE\n\n{\n    NONE = 0<<D3DSP_DSTMOD_SHIFT,\n    SATURATE= 1<<D3DSP_DSTMOD_SHIFT,\n    FORCE_DWORD = 0x7fffffff,\n}\n\nvoid test5()\n{\n}\n\n/**************************************/\n\nclass foo6\n{\n     union\n     {\n         int i;\n         char j;\n     }\n}\n\nvoid test6()\n{\n}\n\n/**************************************/\n\nvoid test7()\n{\n}\n\n\n/**************************************/\n\nreal x8 = 4;\nlong y8;\n\nvoid test8()\n{\n    y8 = cast(long)x8;\n    assert(y8 == 4);\n    y8 = cast(long)cast(double)x8;\n    assert(y8 == 4);\n    printf (\"%lld\\n\", y8);\n}\n\n\n/**************************************/\n\nvoid test9()\n{\n    struct B { }\n    B bar (ref int p)\n    {\n        B b;\n        return b;\n    }\n}\n\n\n/**************************************/\n\nstruct B10\n{\n   uint member;\n}\n\nB10 func10()\n{\n   B10 b;\n   b.member=7;\n   return b;\n}\n\nvoid test10()\n{\n   uint i=func10().member; // Internal error: ..\\ztc\\cgcs.c 350\n   assert(i == 7);\n\n   B10 b=func10();  //works\n   i=b.member;\n   assert(i == 7);\n}\n\n\n/**************************************/\n\nvoid test11()\n{\n   const int notInitialized;\n   const int i=notInitialized; // DMD crashes\n   assert(notInitialized == 0);\n   assert(i == 0);\n}\n\n\n/**************************************/\n\nstruct Array12\n{\n    char len;\n    void* p;\n}\n//Array12 f12(string a)\n//{\n//    return *cast(Array12*) &a[0..23]; //Internal error: ..\\ztc\\cgcs.c 350\n//}\n\nArray12 g12(string a)\n{\n    return *cast(Array12*) &a; //works\n}\n\nvoid test12()\n{\n    string a = \"12345678901234567890123\";\n    Array12 b;\n\n    //b = f12(a);\n    //printf(\"b.len = %x\\n\", b.len);\n    b = g12(a);\n    printf(\"b.len = %x\\n\", b.len);\n}\n\n\n/**************************************/\n\n\nclass A13\n{\n    int opShl(char* v) { return 1; }\n    int opShl(string v) { return 2; }\n}\n\nvoid test13()\n{\n        A13 a = new A13();\n        int i;\n        i = a.opShl(cast(string)\"\");\n        assert(i == 2);\n        i = a << cast(string)\"\";\n        assert(i == 2);\n}\n\n/**************************************/\n\nunion U1\n{\n   struct { int a; }\n   struct { int b; }\n}\n\nunion U2\n{\n   struct { int a; }\n   struct { long b; }\n}\n\nunion U3\n{\n   struct { long a; }\n   struct { int b; }\n}\n\nunion U4\n{\n   int a;\n   int b;\n}\n\nunion U5\n{\n   int a;\n   long b;\n}\n\nunion U6\n{\n   long a;\n   int b;\n}\n\nvoid test14()\n{\n   printf(\"%d %d %d\\n\", U1.a.offsetof, U1.b.offsetof, U1.sizeof);\n   assert(U1.a.offsetof == 0);\n   assert(U1.b.offsetof == 0);\n   assert(U1.sizeof == 4);\n\n   printf(\"%d %d %d\\n\", U2.a.offsetof, U2.b.offsetof, U2.sizeof);\n   assert(U2.a.offsetof == 0);\n   assert(U2.b.offsetof == 0);\n   assert(U2.sizeof == 8);\n\n   printf(\"%d %d %d\\n\", U3.a.offsetof, U3.b.offsetof, U3.sizeof);\n   assert(U3.a.offsetof == 0);\n   assert(U3.b.offsetof == 0);\n   assert(U3.sizeof == 8);\n\n   printf(\"%d %d %d\\n\", U4.a.offsetof, U4.b.offsetof, U4.sizeof);\n   assert(U4.a.offsetof == 0);\n   assert(U4.b.offsetof == 0);\n   assert(U4.sizeof == 4);\n\n   printf(\"%d %d %d\\n\", U5.a.offsetof, U5.b.offsetof, U5.sizeof);\n   assert(U5.a.offsetof == 0);\n   assert(U5.b.offsetof == 0);\n   assert(U5.sizeof == 8);\n\n   printf(\"%d %d %d\\n\", U6.a.offsetof, U6.b.offsetof, U6.sizeof);\n   assert(U6.a.offsetof == 0);\n   assert(U6.b.offsetof == 0);\n   assert(U6.sizeof == 8);\n}\n\n\n/**************************************/\n\nvoid test15()\n{\n    const int[] array = [1,2,3];\n\n    assert(array.length == 3);\n    assert(array[1] == 2);\n}\n\n\n/**************************************/\n\nclass Conversion(T)\n{\n  class Big {char[2] dummy;}\n  static Big Test(...);\n\n  enum { exists = Test().sizeof }\n}\n\nvoid test16()\n{\n    assert(Conversion!(double).exists == (void*).sizeof);\n}\n\n\n/**************************************/\n\nclass Cout17\n{\n Cout17 set(int x)\n {\n  printf(\"%d\",x);\n  return this;\n }\n alias set opShl;\n}\n\nvoid test17()\n{\n Cout17 cout = new Cout17;\n cout << 5 << 4;\n}\n\n\n\n/**************************************/\n\nvoid test18()\n{\n  bool[] x = new bool[100];\n  x[] = 1;\n  bool[] y = x.dup;\n  assert(y[99]);\n}\n\n\n/**************************************/\n\nbool[32] x19 = 1;\n\nvoid test19()\n{\n    assert(x19[31]);\n}\n\n\n/**************************************/\n\nbool[2] y20 = [ cast(bool) 3, cast(bool) 2 ];\n\nvoid test20()\n{\n    assert(y20[0]); // ok\n    assert(y20[1]); // fails\n}\n\n/**************************************/\n\nbool isnan(float x) { return !( (x >= 0)  || (x < 0)); }\n\nstruct X21 { float f, g, h; }\nX21 x21_1;\nX21 x21_2 = { f: 1.0, h: 2.0 };\n\nchar[3] y21_1;\nchar[3] y21_2 = [ 0: 'a', 2: 'b' ];\n\nvoid test21()\n{\n    assert(isnan(x21_1.g));\n    assert(isnan(x21_2.g));\n    assert(y21_1[1] == '\\xff');\n    assert(y21_2[1] == '\\xff');\n}\n\n\n/**************************************/\n\nvoid test22()\n{\n    wstring a = cast(wstring)\"一〇\";\n}\n\n\n/**************************************/\n\ninterface A23 { void x(); }\nclass B23 : A23 { void x() { } }\nclass C23 : B23 { uint y = 12345678; }\n\nvoid stest23(A23 a)\n{\n    synchronized (a)\n    {\n    }\n}\n\nvoid test23()\n{\n    C23 c = new C23;\n    assert(c.y == 12345678 /*c.y.init*/);\n    stest23(c);\n    assert(c.y == 12345678 /*c.y.init*/);\n}\n\n\n/**************************************/\n\nclass A24\n{\n    unittest\n    {\n    }\n}\n\nvoid test24()\n{\n}\n\n/**************************************/\n\nchar rot13(char ret)\n{\n    if (ret > 'A'-1 && ret < 'N')\n    {   ret += 13;}\n    else if(ret > 'M' && ret < 'Z'+1)\n    {   ret -= 13;}\n    else if(ret > 'a'-1 && ret < 'n')\n    {   ret += 13;}\n    else if(ret > 'm' && ret < 'z'+1)\n    {   ret -= 13;}\n\n    return ret;\n}\n\n\nvoid test25()\n{\n    foreach (char c; \"hello World\\n\")\n        printf(\"%c %c\\n\", c, rot13(c));\n    assert(rot13('h') == 'u');\n    assert(rot13('o') == 'b');\n    assert(rot13('W') == 'J');\n    assert(rot13('H') == 'U');\n}\n\n\n/**************************************/\n\nbool b26a = cast(bool)( cast(bool) 2 & cast(bool) 1 );\nbool b26b = cast(bool) 2;\n\nvoid test26()\n{\n    assert( (* cast(byte *) & b26a) == 1 );\n    assert( (* cast(byte *) & b26b) == 1 );\n}\n\n\n/**************************************/\n\nint c27;\n\nstruct X27\n{\n  int x;\n  struct\n  {\n      int a;\n      int b;\n      static this() { c27 = 3; }\n  }\n}\n\nvoid test27()\n{\n    assert(c27 == 3);\n}\n\n/**************************************/\n\nvoid test28()\n{\n  void bar()\n  {\n    throw new Foo28();\n  }\n}\n\nclass Foo28 : Throwable\n{\n  private:\n        this() { super(\"\"); }\n}\n\n/**************************************/\n\nstruct S29 {\n    ubyte a, b, c, d;\n}\n\nint hoge(S29 s) {\n    char[10] b;\n    printf(\"%x\\n\", s);\n    sprintf(b.ptr, \"%x\", s);\n    assert(b[0 .. 7] == \"4030201\");\n    return 0;\n}\n\nvoid test29()\n{\n    for (int i = 0; i < 1; i++) {\n        S29 s;\n        s.a = 1;\n        s.b = 2;\n        s.c = 3;\n        s.d = 4;\n        hoge(s);\n    }\n}\n\n\n/**************************************/\n\nclass Qwert {\n     static {\n         deprecated int yuiop() {\n             return 42;\n         }\n     }\n\n     static deprecated int asdfg() {\n         return yuiop() + 105;\n     }\n}\n\nvoid test30()\n{\n}\n\n/**************************************/\n\nvoid test31()\n{\n    string foo = \"hello\";\n\n    printf(\"%s\\n\", foo.ptr);\n    auto s = typeid(typeof(foo.ptr)).toString();\n    printf(\"%.*s\\n\", s.length, s.ptr);\n    s = typeid(char*).toString();\n    printf(\"%.*s\\n\", s.length, s.ptr);\n    assert(typeid(typeof(foo.ptr)) == typeid(immutable(char)*));\n}\n\n/**************************************/\n\nclass Qwert32\n{\n    struct\n    {\n        int yuiop = 13;\n    }\n    int asdfg = 42;\n\n    void foo()\n    {\n        printf(\"yuiop = %d, asdfg = %d\\n\", Qwert32.yuiop.offsetof, Qwert32.asdfg.offsetof);\n        version(D_LP64)\n        {\n            assert(Qwert32.yuiop.offsetof == 16);\n            assert(Qwert32.asdfg.offsetof == 20);\n        }\n        else\n        {\n            assert(Qwert32.yuiop.offsetof == 8);\n            assert(Qwert32.asdfg.offsetof == 12);\n        }\n    }\n}\n\nvoid test32()\n{\n    Qwert32 q = new Qwert32;\n\n    q.foo();\n}\n\n\n/**************************************/\n\nint x33;\nint y33;\n\nsize_t os_query()\n{\n    return cast(uint)(cast(char *)&x33 - cast(char *)&y33);\n}\n\nvoid test33()\n{\n    os_query();\n}\n\n/**************************************/\n\nuint x34 = ~(16u-1u);\nuint y34 = ~(16u-1);\n\nvoid test34()\n{\n     assert(x34 == 0xFFFFFFF0);\n     assert(y34 == 0xFFFFFFF0);\n}\n\n/**************************************/\n\nprivate static extern (C)\n{\n        shared char* function () uloc_getDefault;\n}\n\n\nstatic shared void**[] targets =\n    [\n        cast(shared(void*)*) &uloc_getDefault,\n    ];\n\nvoid test35()\n{\n}\n\n/**************************************/\n\nclass S36\n{\n    int s = 1;\n\n    this()\n    {\n    }\n}\n\n\nclass A36 : S36\n{\n    int a = 2;\n    int b = 3;\n    int c = 4;\n    int d = 5;\n}\n\nvoid test36()\n{\n    A36 a = new A36;\n\n    printf(\"A36.sizeof = %d\\n\", a.classinfo.initializer.length);\n    printf(\"%d\\n\", a.s);\n    printf(\"%d\\n\", a.a);\n    printf(\"%d\\n\", a.b);\n    printf(\"%d\\n\", a.c);\n    printf(\"%d\\n\", a.d);\n\n    version(D_LP64)\n        assert(a.classinfo.initializer.length == 36);\n    else\n        assert(a.classinfo.initializer.length == 28);\n    assert(a.s == 1);\n    assert(a.a == 2);\n    assert(a.b == 3);\n    assert(a.c == 4);\n    assert(a.d == 5);\n}\n\n\n/**************************************/\n\nstruct MyStruct\n{\n    StructAlias* MyStruct()\n    {\n        return null;\n    }\n}\n\nalias MyStruct StructAlias;\n\nvoid test37()\n{\n}\n\n/**************************************/\n\nclass Foo38\n{\n    static void display_name()\n    {\n        printf(\"%.*s\\n\", Object.classinfo.name.length, Object.classinfo.name.ptr);\n        assert(Object.classinfo.name == \"object.Object\");\n        assert(super.classinfo.name == \"object.Object\");\n        assert(this.classinfo.name == \"test12.Foo38\");\n    }\n}\n\nvoid test38()\n{\n    Foo38.display_name();\n}\n\n\n/**************************************/\n// http://www.digitalmars.com/d/archives/digitalmars/D/bugs/2409.html\n\nclass C39\n{\n    C39 c;\n    this() { c = this; }\n    C39 lock() { return c; }\n}\n\nvoid test39()\n{\n    C39 c = new C39();\n    synchronized( c.lock() ) {}\n    synchronized( c.lock ) {}\n}\n\n\n/**************************************/\n\nclass C40\n{\n    static int x = 4;\n\n    static int foo()\n    {\n        return this.x;\n    }\n}\n\nvoid test40()\n{\n    C40 c = new C40();\n    assert(C40.foo() == 4);\n}\n\n\n/**************************************/\n\nstruct Foo42\n{\n    Bar42 b;\n}\n\nstruct Bar42\n{\n    long a;\n}\n\nvoid test42()\n{\n    assert(Bar42.sizeof == long.sizeof);\n    assert(Foo42.sizeof == long.sizeof);\n}\n\n\n/**************************************/\n\nclass Foo43\n{\n    Bar43 b;\n}\n\nstruct Bar43\n{\n    long a;\n}\n\nvoid test43()\n{\n    assert(Bar43.sizeof == long.sizeof);\n    assert(Foo43.sizeof == (void*).sizeof);\n}\n\n\n/**************************************/\n\nstruct Property\n{\n    uint attributes;\n\n    Value value;\n}\n\nstruct Value\n{\n    int a,b,c,d;\n}\n\nstruct PropTable\n{\n    Property[Value] table;\n    PropTable* previous;\n\n    Value* get(Value* key)\n    {\n        Property *p;\n\n        p = *key in table;\n        p = &table[*key];\n        table.remove(*key);\n        return null;\n    }\n\n}\n\nvoid test44()\n{\n}\n\n\n/**************************************/\n\nstruct Shell\n{\n    string str;\n\n    const int opCmp(ref const Shell s)\n    {\n        import std.algorithm;\n        return std.algorithm.cmp(this.str, s.str);\n    }\n}\n\nvoid test45()\n{\n    import std.algorithm;\n\n    Shell[3] a;\n\n    a[0].str = \"hello\";\n    a[1].str = \"betty\";\n    a[2].str = \"fred\";\n\n    a[].sort;\n\n    foreach (Shell s; a)\n    {\n        printf(\"%.*s\\n\", s.str.length, s.str.ptr);\n    }\n\n    assert(a[0].str == \"betty\");\n    assert(a[1].str == \"fred\");\n    assert(a[2].str == \"hello\");\n}\n\n/**************************************/\n\nclass A46\n{\n    char foo() { return 'a'; }\n}\n\nclass B46 : A46\n{\n}\n\nclass C46 : B46\n{\n    override char foo() { return 'c'; }\n    char bar()\n    {\n        return B46.foo();\n    }\n}\n\nvoid test46()\n{\n    C46 c = new C46();\n\n    assert(c.bar() == 'a');\n    printf(\"%c\\n\", c.bar());\n}\n\n\n/**************************************/\n\nclass Foo47\n{\n   static bool prop() { return false; }\n   static string charprop() { return null; }\n}\n\nvoid test47()\n{\n   if (0 || Foo47.prop) { }\n   if (1 && Foo47.prop) { }\n   switch (Foo47.prop) { default: break; }\n   foreach (char ch; Foo47.charprop) { }\n}\n\n\n/**************************************/\n\nstruct foo48\n{\n    int x, y, z;\n}\n\nvoid bar48() {}\n\nvoid test48()\n{\n    foo48[] arr;\n    foreach(foo48 a; arr)\n    {\n        bar48();\n    }\n}\n\n\n/**************************************/\n\nenum E49;\n\nvoid test49()\n{\n}\n\n/**************************************/\n\nvoid test50()\n{\n        S50!() s;\n        assert(s.i == int.sizeof);\n}\n\nstruct S50()\n{\n        int i=f50(0).sizeof;\n}\n\nint f50(...);\n\n/**************************************/\n\nenum Enum51\n{\n        A,\n        B,\n        C\n}\n\nstruct Struct51\n{\n        Enum51 e;\n}\n\nvoid test51()\n{\n        Struct51 s;\n        assert(s.e == Enum51.A);\n        assert(s.e == 0);\n}\n\n/**************************************/\n\nbool foo52()\n{\n  int x;\n  for (;;) {\n    if (x == 0)\n      return true;\n    x = 1;\n  }\n  return false;\n}\n\nvoid test52()\n{\n  foo52();\n}\n\n/**************************************/\n\nvoid foo53()\n{\n   ret:{}\n   goto ret;\n}\n\nvoid test53()\n{\n}\n\n/**************************************/\n\nstruct V54\n{\n    int x = 3;\n}\n\nclass Foo54\n{\n    static int y;\n    static V54 prop() { V54 val; return val; }\n    static void prop(V54 val) { y = val.x * 2; }\n}\n\nvoid test54()\n{\n    (new Foo54).prop = true ? Foo54.prop : Foo54.prop;\n    assert(Foo54.y == 6);\n}\n\n/**************************************/\n\nvoid test55()\n{\n    dchar c;\n\n    c = 'x';\n    //writefln(\"c = '%s', c.init = '%s'\", c, c.init);\n    assert(c == 'x');\n    assert(c.init == dchar.init);\n}\n\n/**************************************/\n\nvoid writefln(string s)\n{\n    printf(\"%.*s\\n\", s.length, s.ptr);\n}\n\nvoid test58()\n{\n        int label=1;\n        if (0)\n        {\nlabel:\n            int label2=2;\n            assert(label2==2);\n        }\n        else\n        {\n            assert(label==1);\n            goto label;\n        }\n        assert(label==1);\n}\n\n/**************************************/\n\nvoid test59()\n{\n        if(0){\nlabel:\n                return;\n        }else{\n                goto label;\n        }\n        assert(0);\n}\n\n/**************************************/\n\nint main(string[] argv)\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test58();\n    test59();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test12197.d",
    "content": "// import std.math;\n\nvoid foo(T)(T[] b)\n{\n    b[] = b[] ^^ 4;\n}\nvoid main()\n{\n    double[] a = [10];\n    foo(a);\n    assert(a[0] == 10000);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test12486.d",
    "content": "module test12486;\n\nstruct S { enum a = 1; } // or `const` but not for all types\n\nS f(ref int i)\n{\n    ++i;\n    return S();\n}\n\nvoid main()\n{\n    int i = 2;\n    assert(f(i).a == 1);\n    // ensure that f(i) was actually called, even though\n    // a is a statically known property of the returned type\n    assert(i == 3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test12874.d",
    "content": "// EXTRA_SOURCES: imports/a12874.d\n// PERMUTE_ARGS: -inline -g -O\n\nimport imports.a12874;\n\nvoid main()\n{\n    try\n    {\n        int x;\n        foo!(x)();\n    }\n    catch (Error e)\n    {\n        assert(e.file[$-8..$] == \"a12874.d\");\n        assert(e.line == 7);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test13.d",
    "content": "// EXTRA_SOURCES: imports/test13a.d\n// PERMUTE_ARGS:\n// REQUIRED_ARGS: -unittest\n\nmodule test13;\n\nimport imports.test13a;\n\nalias Ordinal!(char) ord;\n\nint main() {\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test13504.d",
    "content": "// REQUIRED_ARGS: -O -cov\n\nbool func(T)()\n{\n    return true;\n}\n\nvoid main()\n{\n    assert(func!int() || int.sizeof);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test13613.d",
    "content": "// PERMUTE_ARGS:\n\n// MT!\"y\" is analyzed from the pragma inside MT!\"x\"\n/*\nTEST_OUTPUT:\n---\nCT x.offsetof = <\nCT y.offsetof = <\n0 > y\n0 > x\n---\n*/\n\nmixin template MT(string id)\n{\n    union\n    {\n        mixin(\"void* \" ~ id ~ \";\");\n    }\n\n    // Evaluating `typeof(this).init` completes data layout.\n    pragma(msg,\n        \"CT \" ~ id ~ \".offsetof = <\\n\",\n        cast(int)typeof(this).init.i.offsetof, \" > \" ~ id);\n}\n\nstruct S1\n{\n    int i;\n    mixin MT!\"x\";\n    mixin MT!\"y\";\n}\nstruct S2\n{\n    int i;\n    union { void* x; }\n    union { void* y; }\n}\nstruct S3\n{\n    int i;\n    void* x;\n    void* y;\n}\n\nvoid main()\n{\n    // S1, S2, and S3 should have exactly same data layout.\n    static assert(S1.i.offsetof == S3.i.offsetof);\n    static assert(S1.i.offsetof == S3.i.offsetof);\n    static assert(S1.x.offsetof == S3.x.offsetof);\n    static assert(S1.y.offsetof == S3.y.offsetof);\n    static assert(S2.x.offsetof == S3.x.offsetof);\n    static assert(S2.y.offsetof == S3.y.offsetof);\n    static assert(S1.sizeof == S3.sizeof);\n    static assert(S2.sizeof == S3.sizeof);\n\n    S1 s = void;\n\n    s.i = 1;\n    assert(s.i == 1);\n    s.x = null;\n    assert(s.i == 1);\n    s.y = null;\n    assert(s.i == 1);\n\n    char a, b;\n    s.x = cast(void*)&a;\n    assert(s.x is &a);\n    assert(s.y is null);\n    s.y = cast(void*)&b;\n    assert(s.x is &a);\n    assert(s.y is &b);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test13944.d",
    "content": "// PERMUTE_ARGS:\nmodule m;\n\nstruct S {}\nenum E { a }\nvoid f() {}\n\nvoid main()\n{\n     string ssc = S.stringof;   assert(ssc == \"S\"c);\n    wstring ssw = S.stringof;   assert(ssw == \"S\"w);\n    dstring ssd = S.stringof;   assert(ssd == \"S\"d);\n\n     string esc = E.stringof;   assert(esc == \"E\"c);\n    wstring esw = E.stringof;   assert(esw == \"E\"w);\n    dstring esd = E.stringof;   assert(esd == \"E\"d);\n\n     string msc = m.stringof;   assert(msc == \"module m\"c);\n    wstring msw = m.stringof;   assert(msw == \"module m\"w);\n    dstring msd = m.stringof;   assert(msd == \"module m\"d);\n\n     string smc = S.mangleof;   assert(smc == \"S1m1S\"c);\n    wstring smw = S.mangleof;   assert(smw == \"S1m1S\"w);\n    dstring smd = S.mangleof;   assert(smd == \"S1m1S\"d);\n\n     string fmc = f.mangleof;   assert(fmc == \"_D1m1fFZv\"c);\n    wstring fmw = f.mangleof;   assert(fmw == \"_D1m1fFZv\"w);\n    dstring fmd = f.mangleof;   assert(fmd == \"_D1m1fFZv\"d);\n\n    // The default type is still string\n    static assert(is(typeof(S.stringof) == string));\n    static assert(is(typeof(E.stringof) == string));\n    static assert(is(typeof(m.stringof) == string));\n    static assert(is(typeof(S.mangleof) == string));\n    static assert(is(typeof(f.mangleof) == string));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test14613.d",
    "content": "\n// https://issues.dlang.org/show_bug.cgi?id=14613\n\nT foo(T)(T b)\n{\n    return (b / (b == 0)) == 0;\n}\n\nvoid main()\n{\n    assert(foo(0.0f) == 1.0f);\n    assert(foo(1.0f) == 0.0f);\n\n    assert(foo(0.0) == 1.0);\n    assert(foo(1.0) == 0.0);\n\n    assert(foo(0.0L) == 1.0L);\n    assert(foo(1.0L) == 0.0L);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test14874.d",
    "content": "// REQUIRED_ARGS: -dip25\r\n\r\ntemplate indexOfReturn(T...)\r\n{\r\n    static if (T.length == 0)\r\n    {\r\n        enum indexOfReturn = -1;\r\n    }\r\n    else static if (T[$ - 1] == \"return\")\r\n    {\r\n        enum indexOfReturn = T.length - 1;\r\n    }\r\n    else\r\n    {\r\n        enum indexOfReturn = indexOfReturn!(T[0..$-1]);\r\n    }\r\n}\r\n\r\nstruct Test\r\n{\r\n    int n;\r\n\r\n    ref int getN() return\r\n    {\r\n        return n;\r\n    }\r\n\r\n    int getNNonReturn()\r\n    {\r\n        return n;\r\n    }\r\n}\r\n\r\nvoid main()\r\n{\r\n    assert(indexOfReturn!(__traits(getFunctionAttributes, Test.getN)) != -1);\r\n    assert(indexOfReturn!(__traits(getFunctionAttributes, Test.getNNonReturn)) == -1);\r\n}\r\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test14901.d",
    "content": "// REQUIRED_ARGS:\n// PERMUTE_ARGS: -unittest\n// EXTRA_SOURCES: imports/test14901a.d imports/test14901b.d imports/test14901c.d imports/test14901d.d\n// COMPILE_SEPARATELY\n\nmodule test14901;\n\nimport imports.test14901c;\nimport imports.test14901d;\n\nextern(C) __gshared static int initCount;\n\nextern(C) int printf(const char*, ...);\n\nvoid main()\n{\n    caller1();\n    caller2();\n    assert(initCount == 1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test14903.d",
    "content": "import core.stdc.stdio : printf;\n\n__gshared int counter;\n\nint getID(int expectedID) nothrow {\n    printf(\"getID: counter = %d, expecting %d\\n\", counter, expectedID);\n    assert(counter == expectedID);\n    ++counter;\n    return expectedID;\n}\n\nref int getCounterRef(int expectedID) nothrow {\n    getID(expectedID);\n    return counter;\n}\n\nstruct StructWithDtor {\n    __gshared int numDtor;\n    int id;\n\n    this(int expectedID) nothrow {\n        printf(\"constructing %d\\n\", expectedID);\n        this.id = getID(expectedID);\n    }\n\n    ~this() nothrow {\n        printf(\"destructing %d\\n\", id);\n        ++numDtor;\n    }\n}\n\nStructWithDtor make(int expectedID, bool doThrow) {\n    if (doThrow)\n        throw new Exception(\"make()\");\n    return StructWithDtor(expectedID);\n}\n\nvoid evaluationOrder(int a, int b, StructWithDtor c, int d, int e, ref int f, StructWithDtor g, int h, int i) {\n    assert(f is counter);\n}\nvoid evaluationOrderTest() {\n    counter = StructWithDtor.numDtor = 0;\n    evaluationOrder(getID(0), getID(1), StructWithDtor(2), getID(3), getID(4), getCounterRef(5), make(6, false), getID(7), getID(8));\n    assert(counter == 9);\n\n    // TODO: add right-to-left test (array ops)\n}\n\nvoid dtors(StructWithDtor a, StructWithDtor b, StructWithDtor c, StructWithDtor d) {\n    throw new Exception(\"dtors()\");\n}\nvoid dtorsTest() {\n    // no throw in args, but in callee\n    counter = StructWithDtor.numDtor = 0;\n    try {\n        dtors(StructWithDtor(0), make(1, false), StructWithDtor(2), make(3, false));\n        assert(0);\n    } catch (Exception) {}\n    assert(counter == 4);\n    assert(StructWithDtor.numDtor == 4);\n\n    // throw in last arg\n    counter = StructWithDtor.numDtor = 0;\n    try {\n        dtors(StructWithDtor(0), make(1, false), StructWithDtor(2), make(3, true));\n        assert(0);\n    } catch (Exception) {}\n    assert(counter == 3);\n    assert(StructWithDtor.numDtor == 3);\n\n    // throw in 2nd arg\n    counter = StructWithDtor.numDtor = 0;\n    try {\n        dtors(StructWithDtor(0), make(1, true), StructWithDtor(2), make(3, true));\n        assert(0);\n    } catch (Exception) {}\n    assert(counter == 1);\n    assert(StructWithDtor.numDtor == 1);\n\n    // TODO: test exception chaining with throwing dtors\n}\n\nvoid main() {\n    evaluationOrderTest();\n    dtorsTest();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test15.d",
    "content": "// REQUIRED_ARGS:\n// EXTRA_FILES: extra-files/test15.txt\n\nimport std.array;\nimport core.stdc.math : cos, fabs, sin, sqrt;\nimport core.vararg;\nimport std.math: rndtol, rint;\nimport std.string;\nimport std.stdio : File;\n\nextern (C)\n{\n    int printf(const char*, ...);\n}\n\nstruct A { int x; }\nstruct B { int x = 22; }\n\nvoid test5()\n{\n    A* a = new A;\n    assert(a.x == 0);\n    B* b = new B;\n    assert(b.x == 22);\n}\n\n/************************************/\n\nvoid test6()\n{\n    assert('\\x12'.sizeof == 1);\n    assert('\\u1234'.sizeof == 2);\n    assert('\\U00105678'.sizeof == 4);\n\n    assert('\\x12' == 0x12);\n    assert('\\u1234' == 0x1234);\n    assert('\\U00105678' == 0x105678);\n\n    assert(\"abc\\\\def\" == r\"abc\\def\");\n}\n\n\n/************************************/\n\nvoid test7()\n{\n    string s = `hello\"there'you`;\n    printf(\"s = '%.*s'\\n\", s.length, s.ptr);\n    assert(s == \"hello\\\"there'you\");\n    ubyte[] b = cast(ubyte[])x\"8B 7D f4 0d\";\n    for (int i = 0; i < b.length; i++)\n        printf(\"b[%d] = x%02x\\n\", i, b[i]);\n    assert(b.length == 4);\n    assert(b[0] == 0x8B);\n    assert(b[1] == 0x7D);\n    assert(b[2] == 0xF4);\n    assert(b[3] == 0x0D);\n}\n\n\n/************************************/\n\n\nvoid foo8(out bool b)\n{\n    b = true;\n}\n\n\nvoid test8()\n{\n   bool b;\n   bool *pb = &b;\n\n   assert(b == false);\n   *pb = true;\n   assert(b == true);\n   *pb = false;\n   assert(b == false);\n   foo8(b);\n   assert(b == true);\n}\n\n\n/************************************/\n\nstruct Pair\n{\n   int a;\n   int b;\n\n   Pair abs ()\n   {\n       return this;\n   }\n\n   Pair opDiv(Pair other)\n   {\n       Pair result;\n\n        result.a = a + other.a;\n        result.b = b + other.b;\n       return result;\n   }\n}\n\nvoid test9()\n{\n   Pair t;\n\n   t.a = 5;\n   t.b = 23;\n   t = t.abs () / t;\n   printf(\"a = %d, b = %d\\n\", t.a, t.b);\n   assert(t.a == 10);\n   assert(t.b == 46);\n}\n\n\n/************************************/\n\nvoid test10()\n{\n    int b = 0b_1_1__1_0_0_0_1_0_1_0_1_0_;\n\n    printf(\"b = %d\\n\", b);\n    assert(b == 3626);\n\n    b = 1_2_3_4_;\n    printf(\"b = %d\\n\", b);\n    assert(b == 1234);\n\n    b = 0x_1_2_3_4_;\n    printf(\"b = %d\\n\", b);\n    assert(b == 4660);\n\n    b = 0_;\n    printf(\"b = %d\\n\", b);\n    assert(b == 0);\n\n    double d = 0_._2_3_4_;\n    printf(\"d = %g\\n\", d);\n    assert(d == 0.234);\n\n    d = 0_._2_3_4_e+3_5_;\n    printf(\"d = %g\\n\", d);\n    assert(d == 0.234e+35);\n\n    d = 0_._2_3_4_e3_5_;\n    printf(\"d = %g\\n\", d);\n    assert(d == 0.234e+35);\n}\n\n/************************************/\n\nclass CA14 { }\nclass CB14 : CA14 { }\n\nclass A14 {\n    int show( CA14 a ) { printf(\"A14::show( CA14 )\\n\"); return 1; }\n    int boat( CA14 a ) { printf(\"A14::boat( CA14 )\\n\"); return 1; }\n}\n\nclass B14 : A14 {\n    int show( CA14 a, CB14 b ) { printf(\"B14::show(CA14, CB14)\\n\"); return 2; }\n    int boat( CA14 a, CB14 b ) { printf(\"B14::boat(CA14, CB14)\\n\"); return 2; }\n}\n\nclass C14 : B14 {\n    override int show( CA14 a ) { printf(\"C::show( CA14 )\\n\"); return 3; }\n    alias B14.show show;\n\n    alias B14.boat boat;\n    override int boat( CA14 a ) { printf(\"C::boat( CA14 )\\n\"); return 3; }\n}\n\nclass D14 : C14  {\n}\n\n\nvoid test14()\n{\n    D14 b = new D14();\n    int i;\n\n    i = b.show( new CA14(), new CB14() );\n    assert(i == 2);\n    i = b.show( new CA14() );\n    assert(i == 3);\n\n    i = b.boat( new CA14(), new CB14() );\n    assert(i == 2);\n    i = b.boat( new CA14() );\n    assert(i == 3);\n}\n\n\n/************************************/\n\nclass A15\n{\n    void foo()\n    {\n        List1.rehash;\n        List2.rehash;\n    }\n  private:\n    int delegate(in int arg1)[char[]] List1;\n    int[char []]  List2;\n}\n\nvoid test15()\n{\n}\n\n\n/************************************/\n\nvoid test16()\n{\n    char[] a=new char[0];\n    uint c = 200000;\n    while (c--)\n        a ~= 'x';\n    //printf(\"a = '%.*s'\\n\", a.length, a.ptr);\n}\n\n\n/************************************/\n\nclass A17 { }\nclass B17 : A17 { }\n\nvoid foo17(const(A17)[] a) { }\n\nvoid test17()\n{\n    B17[] b;\n    foo17(b);\n}\n\n\n/************************************/\n\nvoid test18()\n{\n    uint a;\n    real b=4;\n    a=cast(uint)b;\n}\n\n/************************************/\n\nabstract class Foo19\n{\n    int bar() { return 1; }\n}\n\nvoid test19()\n{\n    Foo19 f;\n}\n\n/************************************/\n\nint foo20(string s,char d) {  return 1; }\nint foo20(string s,double d) {  return 2; }\nint foo20(string s,cdouble d) {  return 3; }\n\nvoid test20()\n{\n    int i;\n    double x;\n    i = foo20(\"test=\",x);\n    assert(i == 2);\n}\n\n/************************************/\n\nvoid test21()\n{\n    int[string] esdom;\n    auto f = File(\"runnable/extra-files/test15.txt\", \"r\");\n\n    foreach(it; f.byLine())\n        esdom[it.idup] = 0;\n\n    esdom.rehash;\n}\n\n/************************************/\n\nint foo22(char* p) { return 1; }\nint foo22(char[] s) { return 2; }\n\nvoid test22()\n{\n    int i;\n\n    i = foo22(cast(char*)\"abc\");\n    assert(i == 1);\n    i = foo22(cast(char[])\"abc\");\n    assert(i == 2);\n}\n\n\n/************************************/\n\nvoid test23()\n{\n    uint v;\n    int b;\n    long l;\n    real e;\n\n    e = cos(e);\n    e = fabs(e);\n    e = rint(e);\n    l = rndtol(e);\n    e = sin(e);\n    e = sqrt(e);\n}\n\n\n/************************************/\n\nabstract class dtortest24\n{\n  this() {}\n  ~this() {}\n}\n\nvoid test24()\n{\n}\n\n\n/************************************/\n\nabstract class bar25 {\n\n  this() {}\n\n  void foo() {}\n\n}\n\nclass subbar25 : bar25 {\n\n  this() {}\n\n}\n\nvoid test25()\n{\n   new subbar25();\n}\n\n\n/************************************/\n\nvoid test26()\n{\n    string[] instructions = std.array.split(\"a;b;c\", \";\");\n\n    foreach(ref string instr; instructions)\n    {\n        std.string.strip(instr);\n    }\n\n    foreach(string instr; instructions)\n    {\n        printf(\"%.*s\\n\", instr.length, instr.ptr);\n    }\n}\n\n\n/************************************/\n\nvoid foo27(ClassInfo ci) { }\n\nclass A27\n{\n}\n\nclass B27 : A27\n{\n    static this()\n    {\n        foo27(B27.classinfo);\n        foo27(A27.classinfo);\n    }\n}\n\nvoid test27()\n{\n}\n\n\n/************************************/\n\nvoid foo28(ClassInfo ci)\n{\n    printf(\"%.*s\\n\", ci.name.length, ci.name.ptr);\n\n    static int i;\n    switch (i++)\n    {\n        case 0:\n        case 2: assert(ci.name == \"test15.A28\");\n                break;\n        case 1: assert(ci.name == \"test15.B28\");\n                break;\n        default: assert(0);\n    }\n}\n\nclass A28\n{\n    static this() {\n    foo28(A28.classinfo );\n    }\n}\n\nclass B28 : A28\n{\n    static this() {\n        foo28(B28.classinfo );\n        (new B28()).bodge_it();\n    }\n    void bodge_it() {\n        foo28(A28.classinfo );\n    }\n}\n\nvoid test28()\n{\n    A28 a,b;\n    a = new A28();\n    b = new B28();\n}\n\n\n/************************************/\n\nvoid test29()\n{\n    static void delegate() dg;\n\n    dg = null;\n}\n\n\n/************************************/\n\nstring foo30(int i)\n{\n    return i ? \"three\" : \"two\";\n}\n\nstring bar30(int i)\n{\n    return i ? \"one\" : \"five\";\n}\n\nvoid test30()\n{\n    string s;\n\n    s = foo30(0);\n    assert(s == \"two\");\n    s = foo30(1);\n    assert(s == \"three\");\n\n    s = bar30(0);\n    assert(s == \"five\");\n    s = bar30(1);\n    assert(s == \"one\");\n}\n\n\n/************************************/\n// http://www.digitalmars.com/d/archives/18204.html\n// DMD0.050 also failed with alias.\n\nalias int recls_bool_t;\n\nclass Entry31\n{\n\n    recls_bool_t IsReadOnly()\n    {\n        return cast(recls_bool_t)0;\n    }\n}\n\n\nvoid test31()\n{\n    Entry31 entry = new Entry31();\n\n    if (entry.IsReadOnly)\n    {\n    }\n}\n\n\n/************************************/\n\nclass A32\n{\n    alias int delegate() mfunc;\n\n    this( mfunc initv )\n    {\n    }\n}\n\nclass foo32\n{\n    static void getMemberBar()\n    {\n        //foo32 f = new foo32(); new A32( &(f.bar) );\n        new A32( &((new foo32()).bar) );\n    }\n\n    int bar()\n    {\n        return 0;\n    }\n}\n\n\nvoid test32()\n{\n    foo32.getMemberBar();\n}\n\n\n/************************************/\n\nvoid[] foo33(int[] b)\n{\n    return b;\n}\n\nvoid test33()\n{\n    int[6] c;\n    void[] v;\n\n    v = foo33(c);\n    assert(v.length == 6 * int.sizeof);\n}\n\n/************************************/\n\nvoid test34()\n{\n    version (D_Bits)\n    {\n        bool[8] a8;\n        assert(a8.sizeof == 4);\n        bool[16] a16;\n        assert(a16.sizeof == 4);\n        bool[32] a32;\n        assert(a32.sizeof == 4);\n        bool[256] a256;\n        assert(a256.sizeof == 32);\n    }\n}\n\n/************************************/\n\nvoid test35()\n{\n    typeof(1 + 2) i;\n\n    assert(i.sizeof == int.sizeof);\n    assert(typeof('c').sizeof == char.sizeof);\n    assert(typeof(1).sizeof == int.sizeof);\n    assert(typeof(1.0F).sizeof == float.sizeof);\n    assert(typeof(1.0).sizeof == double.sizeof);\n    assert(typeof(1.0L).sizeof == real.sizeof);\n\n    //assert(((typeof(1.0L))i).sizeof == real.sizeof);\n    assert((cast(typeof(1.0L))i).sizeof == real.sizeof);\n}\n\n/************************************/\n\nvoid test36x()\n{\n    version (Win32)\n    {\n//      stdin.getch();\n    }\n}\n\nvoid test36()\n{\n}\n\n\n/************************************/\n\nstruct T37\n{\n    char x;\n\n    T37 create()\n    {   T37 t;\n        t.x = 3;\n        return t;\n    }\n\n    bool test1()\n    {\n        return create() == this;\n    }\n\n    bool test2()\n    {\n        return this == create();\n    }\n}\n\n\nvoid test37()\n{\n    T37 t;\n\n    assert(!t.test1());\n    t.x = 3;\n    assert(t.test1());\n\n    t.x = 0;\n    assert(!t.test2());\n    t.x = 3;\n    assert(t.test2());\n}\n\n/************************************/\n\nvoid test38()\n{\n    uint f(uint n) { return n % 10; }\n\n    printf(\"%u\\n\", uint.max);\n    printf(\"%u\\n\", f(uint.max));\n    assert(f(uint.max) == 5);\n}\n\n/************************************/\n\nvoid test39()\n{\n    short s=HIWORD (0x0FFFDDDD);\n    short t=LOWORD (0xFFFFCCCC);\n    short v=HIWORD_(0x0FFFEEEE);\n    short x=HIWORD_(0xFFFFAAAA);\n\n    printf(\"%x %x %x %x\\n\",s,t,v,x);\n    assert(s == 0xFFF);\n    assert(t == 0xFFFFCCCC);\n    assert(v == 0xFFF);\n    assert(x == 0xFFFFFFFF);\n}\n\nshort HIWORD(uint i)\n{\n    return cast(short)(( i >> 16) & 0xFFFF);\n}\n\nshort LOWORD(uint i)\n{\n\n    return cast(short)i;\n}\nextern (C) short HIWORD_(uint i)\n{\n    return cast(short)(( i >> 16) & 0xFFFF);\n}\n\n\n/************************************/\n\nclass caller40 {\n   caller40 opCall (out int i) {\n      i = 10;\n      return this;\n   }\n}\n\nvoid test40()\n{\n   caller40 c = new caller40;\n   int x,y;\n   c(x)(y);\n   assert(x == 10);\n   assert(y == 10);\n}\n\n/************************************/\n\nclass Foo41 { void print() {printf(\"Foo41\\n\");} }\n\nclass Bar41 : Foo41\n{\n    void test()\n    {\n        void printFoo41()\n        {\n            super.print();      // DMD crashes here\n        }\n        printFoo41();\n    }\n}\n\nvoid test41()\n{\n    Bar41 b = new Bar41();\n    b.test();\n}\n\n/************************************/\n\ninterface Interface\n{\n    void foo42();\n}\n\nvoid bar42(Interface i)\n{\n    i.foo42();\n}\n\nclass Abstract : Interface\n{\n    abstract void foo42();\n}\n\nclass Concrete : Abstract\n{\n    override void foo42() { printf(\"Concrete.foo42(this = %p)\\n\", this); }\n}\n\nclass Sub : Concrete\n{\n}\n\nvoid test42()\n{\n    Sub s = new Sub();\n    s.foo42();\n    bar42(s);\n}\n\n/************************************/\n\nclass A43\n{\n    int foo() { return 6; }\n}\n\nint bar43(A43 a)\n{\n    return a.foo;\n}\n\nvoid test43()\n{\n    A43 a = new A43();\n    assert(bar43(a) == 6);\n}\n\n\n/************************************/\n\nclass C44\n{\n    const char[][] arrArr=[\"foo\"];\n}\n\nvoid test44()\n{\n  C44 c= new C44();\n  printf(\"%.*s\\n\", c.arrArr[0].length, c.arrArr[0].ptr);\n  assert(c.arrArr[0] == \"foo\");\n}\n\n\n/************************************/\n\nvoid test45()\n{\n    void* p;\n    void[] data;\n\n    data = p[0 .. 5];\n}\n\n/************************************/\n\nunion A46\n{\n    char c;\n    struct { short s; }\n    struct { long  l; }\n    int a;\n    struct { float f; }\n}\n\nvoid test46()\n{\n    A46 a;\n    printf(\"%d\\n\", cast(byte*)&a.c - cast(byte*)&a);\n    printf(\"%d\\n\", cast(byte*)&a.s - cast(byte*)&a);\n    printf(\"%d\\n\", cast(byte*)&a.l - cast(byte*)&a);\n    printf(\"%d\\n\", cast(byte*)&a.a - cast(byte*)&a);\n    printf(\"%d\\n\", cast(byte*)&a.f - cast(byte*)&a);\n\n    assert(cast(byte*)&a.c == cast(byte*)&a);\n    assert(cast(byte*)&a.s == cast(byte*)&a);\n    assert(cast(byte*)&a.l == cast(byte*)&a);\n    assert(cast(byte*)&a.a == cast(byte*)&a);\n    assert(cast(byte*)&a.f == cast(byte*)&a);\n}\n\n\n/************************************/\n\nclass Bug47\n{\n\n    void foo()\n    {\n    }\n\n    static void foo(int i)\n    {\n    }\n\n    static void bar()\n    {\n        foo(1);\n    }\n}\n\nvoid test47()\n{\n}\n\n\n/************************************/\n\nint[2] x48 = 3;\nfloat y48 = 0.0f;\n\nvoid test48()\n{\n    printf(\"%d, %d\\n\", x48[0], x48[1]);\n    assert(x48[0] == 3 && x48[1] == 3);\n\n    y48 = -100;\n\n    printf(\"%d, %d\\n\", x48[0], x48[1]);\n    assert(x48[0] == 3 && x48[1] == 3);\n}\n\n/************************************/\n\nstruct Baz49 { int x,y,z,t; }\n\nvoid foo49(out Baz49 x, out int y)\n{\n}\n\nvoid test49()\n{\n    int y = 3;\n    Baz49 b;\n    assert(b.x == 0);\n    assert(b.y == 0);\n    assert(b.z == 0);\n    assert(b.t == 0);\n    b.x = 1;\n    b.y = 6;\n    b.z = 10;\n    b.t = 11;\n    foo49(b, y);\n    assert(b.x == 0);\n    assert(b.y == 0);\n    assert(b.z == 0);\n    assert(b.t == 0);\n    assert(y == 0);\n}\n\n/************************************/\n\nvoid foo50(int[] f, ...)\n{\n    foreach(int i, TypeInfo ti; _arguments) { }\n}\n\nvoid bar50(out int[] f, ...)\n{\n    foreach(int i, TypeInfo ti; _arguments) { }\n}\n\nvoid test50()\n{\n    int[] a;\n\n    foo50(a, 1, 2, 3);\n    bar50(a, 1, 2, 3);\n}\n\n\n/************************************/\n\ndeprecated int tri(int x)\n{\n    return x*(x+1)/2;\n}\n\ndeprecated int pent(int x)\n{\n    return x*x + tri(x) - x;\n}\n\ndeprecated class Qwert\n{\n    int yuiop;\n\n    this(int y) { yuiop = y; }\n\n    int twiceYuiop()\n    {\n        return 2 * yuiop;\n    }\n\n    invariant()\n    {\n        assert (yuiop < 100);\n    }\n}\n\nvoid test51()\n{\n}\n\n/************************************/\n\nvoid foo52(double d) {}\ndeprecated void foo52(int i) {}\n\ndeprecated void bar52(int i) {}\nvoid bar52(double d) {}\n\nvoid test52()\n{\n//    foo52(1);\n    foo52(1.0);\n    bar52(1.0);\n}\n\n/************************************/\n\nclass X53\n{\n    void foo(double d) {}\n    deprecated void foo(int i) {}\n\n    deprecated void bar(int i) {}\n    void bar(double d) {}\n}\n\nvoid test53()\n{\n    X53 x = new X53();\n    //x.foo(1);\n    //x.bar(1);\n    x.foo(1.0);\n    x.bar(1.0);\n}\n\n/************************************/\n\ninterface B54 : A54\n{\n  A54 getParent();\n}\n\ninterface A54\n{\n  void parse(char[] systemId);\n}\n\nvoid test54()\n{\n}\n\n\n/************************************/\n\nclass Writer\n{\n    int put (bool x){ return 1; }\n    int put (int x){ return 2; }\n}\n\nclass MyWriter : Writer\n{\n    alias Writer.put put;\n\n    override int put (bool x){ return 3; }\n}\n\nvoid test55()\n{\n    MyWriter m = new MyWriter();\n\n    assert(m.put(false) == 3);\n    assert(m.put(1) == 2);\n}\n\n\n/************************************/\n\nclass Foo56\n{\n    alias int baseType;\n}\n\nvoid test56()\n{\n    Foo56 f = new Foo56;\n\n    f.baseType s = 10;\n}\n\n\n/************************************/\n\nvoid det(float[][] mat)\n{\n    float[][] newmat;\n\n    size_t i = newmat[0 .. (mat.length - 1)].length;\n}\n\nvoid test57()\n{\n}\n\n\n/************************************/\n\nint foo58 (int a, int t) { return 2; }\n\nclass A58\n{\n    int foo58 ( ) { return 3; }\n    alias .foo58 foo58;\n}\n\nvoid test58()\n{   int y, x;\n\n    with ( new A58 )\n    {   y = foo58(0,1);\n        x = foo58();\n    }\n    assert(y == 2);\n    assert(x == 3);\n}\n\n\n/************************************/\n\nvoid test59()\n{\n    struct data\n    {\n        int b1=-1;\n        int b2=2;\n    }\n\n    data d;\n    assert(d.b1 == -1);\n    assert(d.b2 == 2);\n}\n\n\n/************************************/\n\nclass Foo60\n{\n   int x;\n   this() { x = 3; }\n   ~this() { }\n}\n\n\nvoid test60()\n{\n    Foo60 f = new Foo60();\n\n    assert(f.x == 3);\n}\n\n\n/************************************/\n\nclass StdString\n{\n     alias std.string.format toString;\n}\n\nvoid test61()\n{\n    int i = 123;\n    StdString g = new StdString();\n    string s = g.toString(\"%s\", i);\n    printf(\"%.*s\\n\", s.length, s.ptr);\n    assert(s == \"123\");\n}\n\n\n/************************************/\n\nvoid test62()\n{   char[4] a;\n\n    assert(a[0] == 0xFF);\n    assert(a[1] == 0xFF);\n    assert(a[2] == 0xFF);\n    assert(a[3] == 0xFF);\n}\n\n\n/************************************/\n\nvoid test63()\n{\n    bool b;\n    real r;\n    int i;\n\n    i=cast(double) b ? 1 : 4;\n    r=cast(real) b ? 1.0 : 2.0;\n}\n\n\n/************************************/\n\nstruct MyStruct64\n{\n    int test(short s){printf(\"dynamic short\\n\"); return 1; }\n    int test(int i){printf(\"dynamic int\\n\"); return 2; }\n    static int staticTest(short s){printf(\"static short\\n\"); return 3; }\n    static int staticTest(int i){printf(\"static int\\n\"); return 4; }\n}\n\nvoid test64()\n{\n    MyStruct64 S;\n    int j;\n\n    short s = 1;\n    int i = 1;\n\n    j = S.test(s);\n    assert(j == 1);\n    j = S.test(i);\n    assert(j == 2);\n\n    j = S.staticTest(s);\n    assert(j == 3);\n    j = S.staticTest(i);\n    assert(j == 4);\n\n}\n\n/************************************/\n\nvoid test65()\n{\n    int[8] qwert;\n    int[] yuiop = qwert[2..5] = 4;\n\n    assert(yuiop.length == 3);\n    assert(yuiop[0] == 4);\n    assert(yuiop[1] == 4);\n    assert(yuiop[2] == 4);\n    yuiop[1] = 2;\n    assert(qwert[0] == 0);\n    assert(qwert[1] == 0);\n    assert(qwert[2] == 4);\n    assert(qwert[3] == 2);\n    assert(qwert[4] == 4);\n    assert(qwert[5] == 0);\n    assert(qwert[6] == 0);\n    assert(qwert[7] == 0);\n}\n\n\n/************************************/\n\nvoid foo66(ref bool b)\n{\n    b = true;\n}\n\nvoid test66()\n{\n    bool[3] a;\n\n    foo66(a[0]);\n    assert(a[0] == true);\n    assert(a[1] == false);\n    assert(a[2] == false);\n}\n\n\n/************************************/\n\nclass FuBar\n{\n        void foo ()\n        {\n                printf (\"should never get here\\n\");\n                assert(0);\n        }\n\n        const(void)[] get ()\n        {\n                return \"weqweqweqweqwee\";\n        }\n\n        void test (void* dst)\n        {\n                uint count = 7;\n                while (count)\n                      {\n                      // get as much as there is available in the buffer\n                      uint available = 10;\n\n                      // cap bytes read\n                      if (available > count)\n                          available = count;\n\n                      // copy them over\n                      dst[0..available] = get ()[0..available];\n\n                      // bump counters\n                      dst += available;\n                      if ((count -= available) > 0)\n                           foo ();\n                      }\n        }\n}\n\n\nvoid test67()\n{\n    FuBar b = new FuBar();\n    char[10] dst;\n    b.test(&dst[0]);\n}\n\n\n/************************************/\n\nstruct Foo68 { int a,b,c,d; }\n\nvoid bar68(out Foo68 f)\n{\n    f.a = 28;\n}\n\nvoid test68()\n{\n    Foo68 f;\n    bar68(f);\n    assert(f.a == 28);\n}\n\n/************************************/\n\nclass ConduitStyle\n{\n\n//      static ConduitStyle     Read;\n//      static ConduitStyle     ReadWrite;\n\n        static ConduitStyle     Read, ReadWrite;\n}\n\nvoid test69()\n{\n}\n\n\n/************************************/\n\nvoid test70()\n{\n    printf(\"-5/3 prints: %d\\n\", -5/3);\n    printf(\"-5/2 prints: %d\\n\", -5/2);\n    printf(\"-7/3 prints: %d\\n\", -7/3);\n    printf(\"-7/4 prints: %d\\n\", -7/4);\n    printf(\"-7/7 prints: %d\\n\", -7/7);\n    printf(\"-8/7 prints: %d\\n\", -8/7);\n    printf(\"-12/6 prints: %d\\n\", -12/6);\n    printf(\"12/6 prints: %d\\n\", 12/6);\n    printf(\"-9/7 prints: %d\\n\", -9/7);\n    printf(\"-11/8 prints: %d\\n\", -11/8);\n    printf(\"-7/9 prints: %d\\n\", -7/9);\n\n    assert(-5/3 == -1);\n    assert(-5/2 == -2);\n    assert(-7/3 == -2);\n    assert(-7/4 == -1);\n    assert(-7/7 == -1);\n    assert(-8/7 == -1);\n    assert(-12/6 == -2);\n    assert(12/6 == 2);\n    assert(-9/7 == -1);\n    assert(-11/8 == -1);\n    assert(-7/9 == 0);\n}\n\n/************************************/\n\nvoid insertText(string str)\n{\n    assert(str == \"a \");\n}\n\nchar getCharAt()\n{\n    return 'a';\n}\n\nvoid test71()\n{\n    insertText(getCharAt() ~ \" \");\n}\n\n/************************************/\n\npublic class Foo72\n{\n    public this() { }\n}\n\nvoid test72()\n{\n    Foo72[] foos;\n\n    foos = new Foo72() ~ foos[];\n    assert(foos.length == 1);\n}\n\n\n/************************************/\n\nint main()\n{\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test56();\n    test57();\n    test58();\n    test59();\n    test60();\n    test61();\n    test62();\n    test63();\n    test64();\n    test65();\n    test66();\n    test67();\n    test68();\n    test69();\n    test70();\n    test71();\n    test72();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test15079.d",
    "content": "module test15079;\n\nimport imports.a15079;\n\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test15373.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=15373\n\n// Using `typeid` on an `extern(C++) class` type is fine as it is evaluated at compile-time\n\n// Using `typeid` on an `extern(C++) class` instance is not ok because `extern(C++) class`\n// instances are not rooted in `Object`.  See test/fail_compilation/test15373.d\n\nextern(C++) class C\n{ }\n\nvoid main()\n{\n    auto Cti = typeid(C);\n    assert(Cti.name == \"test15373.C\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test15568.d",
    "content": "// REQUIRED_ARGS: -unittest -main -O\n// https://issues.dlang.org/show_bug.cgi?id=15568\n\nimport std.algorithm;\nimport std.array;\n\nclass A\n{\n    B foo(C c, D[] ds, bool f)\n    in\n    {\n        assert(c !is null);\n    }\n    body\n    {\n        D[] ds2 = ds.filter!(a => c).array;\n\n        return new B(ds2, f);\n    }\n}\n\nclass B\n{\n    this(D[], bool)\n    {\n    }\n}\n\nclass C\n{\n}\n\nstruct D\n{\n}\n\nunittest\n{\n    auto a = new A;\n    C c = new C;\n\n    a.foo(c, null, false);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test15624.d",
    "content": "/* PERMUTE_ARGS:\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=15624\n\nstruct Foo {\n        int x;\n        int opApply(int delegate(int, string, string) @safe dg) @safe {\n                x = 1;\n                return 0;\n        }\n        int opApply(int delegate(int, string, string) @system dg) @system {\n                x = 2;\n                return 0;\n        }\n}\n\nvoid testSafe() @safe {\n        Foo foo;\n        foreach (i, k, v; foo) {\n        }\n        assert(foo.x == 1);\n}\n\nvoid testSystem() @system {\n        Foo foo;\n        foreach (i, k, v; foo) {\n        }\n        assert(foo.x == 2);\n}\n\nvoid test() @system\n{\n    Foo f;\n\n    int dgsafe  (int x, string s, string t) @safe   { return 1; }\n    int dgsystem(int x, string s, string t) @system { return 1; }\n\n    f.opApply(&dgsafe);\n    assert(f.x == 1);\n    f.opApply(&dgsystem);\n    assert(f.x == 2);\n}\n\nint main()\n{\n    testSafe();\n    testSystem();\n    test();\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test15913.d",
    "content": "void main()//test10282()\n{\n  //const     int[3] a4 = [1, 3, 6] * 3;\n    immutable int[3] a5 = [1, 3, 6] * 3;\n\n    assert(a5[0] == 3 && a5[1] == 9 && a5[2] == 18);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test16.d",
    "content": "// REQUIRED_ARGS:\n\nextern(C) int printf(const char*, ...);\n\n/************************************************/\n// These seem to be the original tests for $ (originally 'length').\n\nint x;\n\nint[] bar(int[] a)\n{\n    x++;\n    return a[0 .. $ - 1];\n}\n\nvoid test1()\n{\n  {\n    int[4] foo;\n\n    foo[$ - 2] = 4;\n    assert(foo[0] == 0);\n    assert(foo[1] == 0);\n    assert(foo[2] == 4);\n    assert(foo[3] == 0);\n\n    foo[3] = 5;\n    assert(foo[$ - 1] == 5);\n\n    x = 0;\n    bar(foo)[$ - 3] = 6;\n    assert(x == 1);\n    assert(foo[0] == 6);\n\n    assert(bar(foo)[$ * 2 - 1 - $] == 4);\n    assert(x == 2);\n\n    foo[0 .. $] = 1;\n    assert(foo[0] == 1);\n    assert(foo[1] == 1);\n    assert(foo[2] == 1);\n    assert(foo[3] == 1);\n\n    x = 0;\n    bar(foo)[1 .. $ * 3 - $ - $] = 2;\n    assert(x == 1);\n    assert(foo[0] == 1);\n    assert(foo[1] == 2);\n    assert(foo[2] == 2);\n    assert(foo[3] == 1);\n\n    int[] a = new int[3];\n    a[0..$] = foo[0..$-1];\n    assert(a[0] == 1);\n    assert(a[1] == 2);\n    assert(a[2] == 2);\n    a[] = 4;\n    a[0..$] = bar(foo)[0..$];\n    assert(x == 2);\n    assert(a[0] == 1);\n    assert(a[1] == 2);\n    assert(a[2] == 2);\n  }\n\n  {\n    int[4] f; int[] foo = f;\n\n    foo[$ - 2] = 4;\n    assert(foo[0] == 0);\n    assert(foo[1] == 0);\n    assert(foo[2] == 4);\n    assert(foo[3] == 0);\n\n    foo[3] = 5;\n    assert(foo[$ - 1] == 5);\n\n    x = 0;\n    bar(foo)[$ - 3] = 6;\n    assert(x == 1);\n    assert(foo[0] == 6);\n\n    assert(bar(foo)[$ * 2 - 1 - $] == 4);\n    assert(x == 2);\n\n    foo[0 .. $] = 1;\n    assert(foo[0] == 1);\n    assert(foo[1] == 1);\n    assert(foo[2] == 1);\n    assert(foo[3] == 1);\n\n    x = 0;\n    bar(foo)[1 .. $ * 3 - $ - $] = 2;\n    assert(x == 1);\n    assert(foo[0] == 1);\n    assert(foo[1] == 2);\n    assert(foo[2] == 2);\n    assert(foo[3] == 1);\n\n    int[] a = new int[3];\n    a[0..$] = foo[0..$-1];\n    assert(a[0] == 1);\n    assert(a[1] == 2);\n    assert(a[2] == 2);\n    a[] = 4;\n    a[0..$] = bar(foo)[0..$];\n    assert(x == 2);\n    assert(a[0] == 1);\n    assert(a[1] == 2);\n    assert(a[2] == 2);\n  }\n}\n\n/************************************************/\n\nstruct ICONINFO\n{\n    bool fIcon;\n}\n\nvoid test2()\n{\n     ICONINFO info;\n     info.fIcon = true;\n     assert(info.fIcon == true);\n}\n\n\n/************************************************/\n\nclass A3\n{\n    void foo()\n    {\n        printf(\"A.foo \\n\" );\n    }\n}\n\nclass B3 : A3\n{\n}\n\nclass C3 : B3\n{\n    override void foo()\n    {\n        printf(\"C.foo \\n\" );\n        super.foo();\n    }\n}\n\nvoid test3()\n{\n    C3 c = new C3();\n    c.foo();\n}\n\n\n/************************************************/\n\nvoid test4()\n{\n    int function (int i) x = function int (int i) { return i * 2; };\n    int function (int i) y = function int (int i) { return i / 2; };\n\n    int k;\n    k = x(2);\n    assert(k == 4);\n    k = y(3);\n    assert(k == 1);\n}\n\n\n/************************************************/\n\nclass Parser\n{\n    void next(ref int test)\n    {\n        void work (int input)\n        {\n            printf(\"work(%d, %d)\\n\", input, test);\n            test = 2;\n        }\n\n        test = 3;\n        work(4);\n    }\n}\n\n\nvoid test5()\n{\n    Parser parser = new Parser();\n    int test;\n\n    parser.next (test);\n    printf(\"test %d\\n\", test);\n    assert(test == 2);\n}\n\n\n/************************************************/\n\nvoid foo6(out int bar)\n{\n}\n\nvoid test6()\n{\n    int bar = 3;\n    foo6(bar);\n    printf(\"%d\", bar );\n    assert(bar == 0);\n//    return 0;\n}\n\n/************************************************/\n\nvoid test7()\n{\n   char ch = ' ';\n   char[] u;\n   u.length = 3;\n\n   int i = 2;\n\n   printf(\"a\\n\");\n   u[0..2] = ch;\n   printf(\"b\\n\");\n   u[0..i] = ch;\n   printf(\"c\\n\");\n   assert(u[0] == 0x20);\n   assert(u[1] == 0x20);\n}\n\n\n/************************************************/\n\nstruct X8\n{\n    bool flag;\n}\n\nvoid test8()\n{\n    X8 x;\n    x.flag = 0 != 0;\n}\n\n\n/************************************************/\n\nvoid foo9(float x)\n{\n    assert(x == 0.0f);\n}\n\nvoid len9(float x, float y, float z, float t)\n{\n    foo9(x*x+y*y+z*z);\n}\n\nvoid test9()\n{\n    float[4] a;\n    a[0] = a[1] = a[2] = a[3] = 0.0f;\n\n    for (int y = 0; y < 7; ++y)\n    {\n        len9(a[0], a[1], a[2], a[3]);\n\n        float justOne() { return 1.0f; }\n\n        float dot = justOne();\n        if (dot < 0.0f)\n            dot = 0.0f;\n    }\n}\n\n/************************************************/\n\nubyte[4] arr10;\n\nvoid foo10()\n{\n  *cast(float*)(&arr10[0]) = 3.25;\n}\n\nuint bar10()\n{\n  uint result = *cast(uint*)&arr10[0];\n  return result;\n}\n\nfloat baz10()\n{\n  uint result = bar10();\n  return *cast(float*)&result;\n}\n\nvoid test10()\n{\n  foo10();\n  float x = baz10();\n\n  assert(x == 3.25);\n}\n\n\n/************************************************/\n\ninterface I11\n{\n  void M ();\n}\n\ninterface J11 : I11\n{\n  void N ();\n}\n\nclass A11 : I11\n{\n  void M () { printf(\"A.M()\\n\"); }\n}\n\nclass B11 : A11, J11\n{\n  void N () { printf(\"B.N()\\n\"); }\n}\n\nvoid test11()\n{\n  I11 f = new B11 ();\n\n  f.M();\n}\n\n\n/************************************************/\n\nint x12;\n\nvoid test12()\n{\n    static class S\n    {\n        static this()\n        {\n            printf (\"static constructor\\n\");\n            x12 += 1;\n        }\n\n        this()\n        {\n            printf (\"class constructor\\n\");\n            x12 += 10;\n        }\n    }\n\n    assert(x12 == 1);\n    new S;\n    assert(x12 == 11);\n}\n\n\n/************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test16115.d",
    "content": "/*\nREQUIRED_ARGS: -d\nPERMUTE_ARGS:\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=16115\n// https://github.com/dlang/dmd/pull/3979\n\nint n;\n\nstruct Test\n{\n    enum tag = 42;\n}\n\nenum tagx = 42;\n\nauto call()\n{\n    version (none) // works\n    {\n        n = Test.tag;\n        return null;\n    }\n    else // assert error\n    {\n        //return n = tagx, null;\n        return n = Test.tag;\n        //return n = Test.tag;\n    }\n}\n\nvoid main()\n{\n    call();\n\n    assert(n == 42);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test16555.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16555\n\nvoid outer(\n    double x,\n    double a, double b, double c, double d,\n    double e, double f, double g, double h)\n{\n    assert(x == 999.0 && a == 1 && b == 2 && c == 3 && d == 4\n        && e == 5 && f == 6 && g == 7 && h == 8);\n}\n\nvoid main()\n{\n    void inner(double x)\n    {\n        outer(x, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);\n    }\n\n    inner(999.0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test16640.d",
    "content": "// PERMUTE_ARGS:\n\nvoid testFileFullPathAsDefaultArgument(string preBakedFileFullPath, string fileFullPath = __FILE_FULL_PATH__)\n{\n    assert(preBakedFileFullPath == fileFullPath);\n}\n\nvoid main()\n{\n    testFileFullPathAsDefaultArgument(__FILE_FULL_PATH__);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test16980.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=16980\ninterface A { void foo(); }\ninterface B { void bar(); }\ninterface AB : A, B {}\nclass C : AB {\n    void foo() { assert(false, \"Must never be called!\"); }\n    void bar() {}\n}\n\nstruct T() {\n    AB ab;\n    ~this() {\n        ab.bar(); // uses wrong vtable\n    }\n}\n\nT!() tinst; // triggers semantic3 of dtor from Module::semantic(1)\n\nvoid main()\n{\n    auto dst = T!()(new C);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17.d",
    "content": "\nimport core.stdc.stdio: fflush, stdout;\n\nextern(C) int printf(const char*, ...);\n\nvoid ulog(string s)\n{\n    printf(\"%.*s\\n\",s.length, s.ptr);\n    fflush(stdout);\n}\n\nint open()\n{\n    char *s;\n    char[2000] abs;\n    char[100] qu;\n    int a;\n    ulog(\"reaches this only 9 times of 10!\\n\");\n    return 0;\n}\n\n\nint yhenda()\n{\n    char[2200] MEM;\n    int a;\n    ulog(\"point(2.1) \\n\");\n    open();\n    ulog(\"point(2.2) \\n\");\n    return 0;\n}\n\n\nint main()\n{\n    printf(\"Content-type: text/html\\n\\n\");\n    fflush(stdout);\n    ulog(\"point(1.1)\\n\");\n    yhenda();\n    ulog(\"point(1.2)\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17072.d",
    "content": "/*\nREQUIRED_ARGS: -inline\nPERMUTE_ARGS: -release -O -dip25\n*/\n\n// https://issues.dlang.org/show_bug.cgi?id=17072\n\nimport core.thread;\n\nvoid main()\n{\n        Thread.sleep(dur!\"msecs\"(0));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17246.d",
    "content": "/* REQUIRED_ARGS:\n * OPTIONAL_ARGS:\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=17246\n\nstruct Foo\n{\n    int* rc;\n    this(int val)\n    {\n        rc = new int;\n        (*rc) = 1;\n    }\n    this(this)\n    {\n        (*rc)++;\n    }\n    ~this()\n    {\n        if (rc)\n        {\n            assert(*rc > 0);\n            (*rc)--;\n        }\n    }\n}\n\nstruct Bar\n{\n    Foo foo;\n    this(Foo foo, bool)\n    {\n        this.foo = foo;\n    }\n}\n\nbool fun(bool val) { return !val; }\n\nauto genBar(bool flag)\n{\n    return flag ? Bar() : Bar(Foo(10), fun(!flag));\n}\n\nint main(string[] args)\n{\n    auto bar = genBar(args.length == 0);\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17338.d",
    "content": "// PERMUTE_ARGS:\n// Generate \\sum_{i=0}^{14} 2^i = 32767 template instantiations\n// (each with 3 sections) to use more than 64Ki sections in total.\nversion (Win32)\n{\n    // Apparently omf or optlink does not support more than 32767 symbols.\n    void main()\n    {\n    }\n}\nelse\n{\n    size_t foo(size_t i, size_t mask)()\n    {\n        static if (i == 14)\n            return mask;\n        else\n            return foo!(i + 1, mask) + foo!(i + 1, mask | (1UL << i));\n    }\n\n    void main()\n    {\n        assert(foo!(0, 0) != 0);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17559.d",
    "content": "// REQUIRED_ARGS: -g\n// REQUIRED_ARGS(linux freebsd dragonflybsd): -L-export-dynamic\n// PERMUTE_ARGS:\n// DISABLED: osx\n\nimport core.stdc.stdio;\n\nvoid main()\n{\n    fun(1);\n    fun(2);\n    fun(3);\n#line 30\n    fun(4);\n\n    foo(1, 10);\n    foo(2, 10);\n    foo(3, 10);\n#line 40\n    foo(4, 10);\n}\n\nvoid fun(int n, int defParam = 10)\n{\n    try\n    {\n        if (n == 4)\n            throw new Exception(\"fun\");\n    }\n    catch(Exception e)\n    {\n        string s = e.toString();\n        printf(\"%.*s\\n\", cast(int)s.length, s.ptr);\n        int line = lineInMain(e.toString());\n        assert(line >= 30 && line <= 32); // return address might be next statement\n    }\n}\n\nvoid foo(int n, int m)\n{\n    try\n    {\n        if (n == 4)\n            throw new Exception(\"foo\");\n    }\n    catch(Exception e)\n    {\n        string s = e.toString();\n        printf(\"%.*s\\n\", cast(int)s.length, s.ptr);\n        int line = lineInMain(e.toString());\n        assert(line >= 40 && line <= 41); // return address might be next statement\n    }\n}\n\nint lineInMain(string msg)\n{\n    // find line number of _Dmain in stack trace\n    // on linux:   file.d:line _Dmain [addr]\n    // on windows: addr in _Dmain at file.d(line)\n    int line = 0;\n    bool mainFound = false;\n    for (size_t pos = 0; pos + 6 < msg.length; pos++)\n    {\n        if (msg[pos] == '\\n')\n        {\n            line = 0;\n            mainFound = false;\n        }\n        else if ((msg[pos] == ':' || msg[pos] == '(') && line == 0)\n        {\n            for (pos++; pos < msg.length && msg[pos] >= '0' && msg[pos] <= '9'; pos++)\n                line = line * 10 + msg[pos] - '0';\n            if (line > 0 && mainFound)\n                return line;\n        }\n        else if (msg[pos .. pos + 6] == \"_Dmain\" || msg[pos .. pos + 6] == \"D main\")\n        {\n            mainFound = true;\n            if (line > 0 && mainFound)\n                return line;\n        }\n    }\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17684.d",
    "content": "struct StructField(T)\n{\n    static T Field;\n    static alias Field this;\n}\n\nstruct StructProperty(T)\n{\n    static T Field;\n\t\n\tstatic @property T property()\n\t{\n\t\treturn Field;\t\n\t}\n\t\n\tstatic @property void property(T value)\n\t{\n\t\tField = value;\t\n\t}\n\t\n    static alias property this;\n}\n\nclass ClassField(T)\n{\n    static T Field;\n    static alias Field this;\n}\n\nclass ClassProperty(T)\n{\n    static T Field;\n\t\n\tstatic @property T property()\n\t{\n\t\treturn Field;\t\n\t}\n\t\n\tstatic @property void property(T value)\n\t{\n\t\tField = value;\t\n\t}\n\t\n    static alias property this;\n}\n\nbool boolTest(T)()\n{\n    alias t = T;\n\n    t = false;                    // tests AssignExp\n    assert(t == false);\n\n    bool boolValue = t;           // tests AssignExp\n    assert(boolValue == false);\n\n    t = !t;                       // tests NotExp\n    assert(t == true);\n\n    boolValue = t;\n    assert(boolValue == true);\n\n    assert(boolValue && t);       // tests AndAndExp\n    assert(t && boolValue);\n\n    boolValue = false;\n    assert(boolValue || t);       // tests OrOrExp\n    assert(t || boolValue);\n\n    assert(t != boolValue);       // tests CmpExp\n    assert(boolValue != t);\n\n    boolValue = true;\n    assert(t == boolValue);\n    assert(boolValue == t);\n\n    t = true;                     // tests inferType\n    auto inferredValue = t;\n    assert(inferredValue == true);\n\n    t = true;\n    return t;                     // tests ReturnStatement\n}\n\nint intTest(T)()\n{\n    alias t = T;\n\n    t = 42;                       // tests AssignExp\n    assert(t == 42);\n\n    int intValue = t;\n    assert(intValue == 42);\n\n    assert(t == 42);              // tests CmpExp\n    assert(42 == t);\n    assert(t != 43);\n    assert(43 != t);\n    assert(t < 43);\n    assert(43 > t);\n    assert(t <= 42);\n    assert(42 >= t);\n\n    // These currently don't work for properties due to https://issues.dlang.org/show_bug.cgi?id=8006\n    static if (!(typeid(T) is typeid(StructProperty!int)) && !(typeid(T) is typeid(ClassProperty!int)))\n    {\n        t++;              // test a few unary and binary operators\n        assert(t == 43);\n\n        t += 1;\n        assert(t == 44);\n\n        t--;\n        assert(t == 43);\n\n        t -= 1;\n        assert(t == 42);\n    }\n\n    assert(~t == ~42);            // tests ComExp\n\n    return t;                     // tests ReturnStatement\n}\n\nvoid main()\n{\n    assert(boolTest!(StructField!(bool))());\n    assert(boolTest!(StructProperty!(bool))());\n    assert(boolTest!(ClassField!(bool))());\n    assert(boolTest!(ClassProperty!(bool))());\n\n    assert(intTest!(StructField!(int))() == 42);\n    assert(intTest!(StructProperty!(int))() == 42);\n    assert(intTest!(ClassField!(int))() == 42);\n    assert(intTest!(ClassProperty!(int))() == 42);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17868.d",
    "content": "// REQUIRED_ARGS: -betterC\n// POST_SCRIPT: runnable/extra-files/test17868-postscript.sh\nimport core.stdc.stdio;\n\nextern(C):\n\npragma(crt_constructor)\nvoid init()\n{\n    puts(\"init\");\n}\n\npragma(crt_destructor)\nvoid fini2()\n{\n    puts(\"fini\");\n}\n\npragma(crt_constructor)\nvoid foo()\n{\n    puts(\"init\");\n}\n\npragma(crt_destructor)\nvoid bar()\n{\n    puts(\"fini\");\n}\n\nint main()\n{\n    puts(\"main\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17868b.d",
    "content": "// REQUIRED_ARGS: -betterC\n// POST_SCRIPT: runnable/extra-files/test17868-postscript.sh\nimport core.stdc.stdio;\n\nextern(C):\n\npragma(crt_constructor)\npragma(crt_destructor)\nvoid ctor_dtor_1()\n{\n    __gshared bool initialized;\n    puts(initialized ? \"fini\" : \"init\");\n    initialized = true;\n}\n\npragma(crt_constructor)\n__gshared int var; // ignored for anything but functions\n\npragma(crt_constructor)\n{\n    version (all) void init()\n    {\n        puts(\"init\");\n    }\n}\n\ntemplate fini()\n{\n    pragma(crt_destructor)\n    void fini()\n    {\n        puts(\"fini\");\n    }\n}\n\nalias instantiate = fini!();\n\nint main()\n{\n    puts(\"main\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17878.d",
    "content": "@__future int foo()\n{\n    return 0;\n}\n\nint bar()\n{\n    return 1;\n}\n\n@__future int c;\n\n\nvoid main()\n{\n    static assert(__traits(isFuture, foo));\n    static assert(!__traits(isFuture, bar));\n    static assert(__traits(isFuture, c));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17899.d",
    "content": "module test17899;\n\n// Test that the ICE in 13259 does not ICE but produces correct code\nauto dg = delegate {}; \n\nint setme = 0;\nvoid delegate() bar1 = (){ setme = 1;};\n\n__gshared void delegate() bar2 = (){ setme = 2;};\n\nvoid main()\n{\n    dg();\n    assert(setme == 0);\n    bar1();\n    assert(setme == 1);\n    bar2();\n    assert(setme == 2);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17940.d",
    "content": "// PERMUTE_ARGS: -O\n\n// https://issues.dlang.org/show_bug.cgi?id=17940\n\nstruct Array\n{\n    long length;\n    long ptr;\n}\n\nstruct Struct\n{\n    bool b = true;\n}\n\nvoid fun1(int)\n{\n}\n\nvoid fun2(Array arr, int, int)\n{\n    assert(!arr.length);\n}\n\nvoid fn(Struct* str)\n{\n    Array arr;\n    if (!str)\n    {\n        return;\n    }\n    if (str)\n    {\n        fun1(str.b);\n    }\n    if (str.b)\n    {\n        fun2(arr, str.b, 0);\n    }\n}\n\nvoid main()\n{\n    Struct s;\n    fn(&s);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test17943.d",
    "content": "// REQUIRED_ARGS: -O\n\nvoid main()\n{\n    int[32] data;\n    auto p1 = data.ptr + 0;\n    auto p2 = data.ptr + 3;\n    assert(p2 - p1 == 3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test18296.d",
    "content": "// REQUIRED_ARGS: -cov\n// PERMUTE_ARGS: -fPIC\nalias AliasSeq(Args...) = Args;\n\nstruct Duration\n{\n    this(long hnsecs)\n    {\n        _hnsecs = hnsecs;\n    }\n\n\n    long _hnsecs;\n}\n\nvoid main()\n{\n    foreach(U; AliasSeq!(Duration, const Duration))\n    {\n        const Duration t = 42;\n        U u = t;\n        assert(t._hnsecs == u._hnsecs);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test18322.d",
    "content": "/*\nREQUIRED_ARGS: -Irunnable/imports\nCOMPILED_IMPORTS: imports/test18322import.d\nPERMUTE_ARGS:\n*/\nimport test18322import;\nvoid main(){\n    version(Windows)\n        auto sep = \"\\\\\";\n    else\n        auto sep = \"/\";\n\n    auto filename = \"runnable\" ~ sep ~ \"test18322.d\";\n\n    fun(filename);\n    mixin(`fun(filename ~ \"-mixin-16\");`);\n\n    #line 100 \"poundlinefile.d\"\n    fun(\"poundlinefile.d\");\n    mixin(`fun(\"poundlinefile.d-mixin-101\");`);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test18534.d",
    "content": "/* REQUIRED_ARGS: -O\n * PERMUTE_ARGS:\n */\n\n// https://issues.dlang.org/show_bug.cgi?id=18534\n\nauto blah(char ch) { return ch; }\n\nauto foo(int i)\n{\n    return blah(i ? 'A' : 'A');\n}\n\nvoid main()\n{\n    auto c = foo(0);\n    assert(c == 'A');\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test18746.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=18746\n\nstruct S {}\n\nS f(ref int i)\n{\n    ++i;\n    return S();\n}\n\nvoid main()\n{\n    int i = 2;\n    assert(f(i) == S());\n    assert(i == 3); /* failed before patch, i = 2; should pass */\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test18868_2.d",
    "content": "mixin(genCtor(\"666\")); mixin(genCtor(\"777\"));\n\nint i;\n\nstring genCtor(string a)\n{\n    return \"static this() { i += \" ~ a ~ \"; }\";\n}\n\nvoid main()\n{\n    assert(i == 0 + 666 + 777);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test18868_3.d",
    "content": "static foreach(s; [\"666\", \"777\", \"888\"])\n{\n    mixin(genCtor(s));\n}\n\nint i;\n\nstring genCtor(string a)\n{\n    return \"static this() { i += \" ~ a ~ \"; }\";\n}\n\nvoid main()\n{\n    assert(i == 0 + 666 + 777 + 888);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test18880.d",
    "content": "/* REQUIRED_ARGS: -unittest\n   PERMUTE_ARGS:\n */\n\nstatic foreach(s; [\"666\", \"777\", \"888\"])\n{\n    mixin(genTest(s));\n}\n\nint i;\n\nstring genTest(string a)\n{\n    return \"unittest { i += \" ~ a ~ \"; }\";\n}\n\nvoid main()\n{\n    assert(i == 0 + 666 + 777 + 888);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test18916.d",
    "content": "struct Line\n{\n    int line;\n    alias line this;\n\n    this(int line)\n    {\n        this.line = line;\n    }\n}\n\nvoid foo(Line line1 = __LINE__, int line2 = __LINE__, int line3 = int(__LINE__))\n{\n    assert(line1 == 12);\n    assert(line2 == 21);\n    assert(line3 == 12);\n}\n\nvoid main()\n{\n    foo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test19.d",
    "content": "// REQUIRED_ARGS: -unittest\n\nimport std.algorithm: cmp;\n\nextern(C) int printf(const char*, ...);\n\n/* ================================ */\n\nclass Foo\n{\n    int foo(int x) { return x + 3; }\n}\n\nclass Bar : Foo\n{\n    override int foo(int y) { return y + 4; }\n}\n\nvoid test1()\n{\n    Bar e;\n\n    assert(e is null);\n    e = new Bar();\n    assert(e.foo(5) == 9);\n}\n\n/* ================================ */\n\nclass Foo2\n{\n    int foo(int x)\n    {\n        return x + 3;\n    }\n}\n\nclass Bar2 : Foo2\n{\n    override int foo(int y)\n    {\n        assert(Foo2.foo(2) == 5);\n        return y + 4;\n    }\n}\n\nvoid test2()\n{\n    Bar2 e;\n\n    assert(e is null);\n    e = new Bar2();\n    assert(e.foo(5) == 9);\n    assert(e.Foo2.foo(10) == 13);\n}\n\n/* ================================ */\n\nvoid test3()\n{\n    debug printf(\"debug\\n\");\n    debug(1) printf(\"debug(1)\\n\");\n    debug(2) printf(\"debug(2)\\n\");\n    debug(3) printf(\"debug(3)\\n\");\n    debug(bar) printf(\"debug(bar)\\n\");\n    debug(10) assert(0);\n\n    debug(1)\n    {\n        int d1 = 3;\n\n        printf(\"debug(1) { }\\n\");\n    }\n    debug(2)\n    {\n        printf(\"debug(2): d1 = %d\\n\", d1);\n    }\n}\n\n/* ================================ */\n\nint x1;\nint x2;\n\nclass Foo4\n{\n    static  this() { x1 = 3; printf(\"Foo4 ctor()\\n\"); }\n    static ~this() { x1 = 4; printf(\"Foo4 dtor()\\n\"); }\n}\n\nstatic  this() { x2 = 5; printf(\"ctor()\\n\"); }\nstatic ~this() { x2 = 6; printf(\"dtor()\\n\"); }\n\nvoid test4()\n{\n    printf(\"x1 = %d, x2 = %d\\n\", x1, x2);\n    assert(x1 == 3);\n    assert(x2 == 5);\n}\n\n/* ================================ */\n\nvoid test5()\n{\n    version (D_Bits)\n    {\n    printf(\"test5()\\n\");\n    static uint foo;\n    static uint x = 3;\n    static uint len = 32;\n\n    bool[] bools;\n\n    bools = (cast(bool *)&foo)[0..len];\n    bools[6] = true;\n    assert(foo == (1 << 6));\n    }\n}\n\n/* ================================ */\n\nint[] test6_1(int[] a)\n{\n    a.length = 6;\n    return a;\n}\n\nvoid test6()\n{\n    printf(\"test6()\\n\");\n    int[3] b;\n    int[] a;\n\n    b[0] = 0;\n    b[1] = 1;\n    b[2] = 2;\n    assert(b.length == 3);\n    a = test6_1(b);\n    a[2] = 2;\n    assert(a.length == 6);\n}\n\n/* ================================ */\n\nclass OutBuffer7\n{\n    char[] data;\n    uint offset;\n\n    void write(const(char) *p, uint nbytes)\n    {\n        data[offset .. offset + nbytes] = (cast(char *)p)[0 .. nbytes];\n    }\n}\n\n\nvoid test7()\n{\n    printf(\"test7()\\n\");\n    int i;\n    OutBuffer7 ob = new OutBuffer7;\n\n    ob.data = new char[10];\n    printf(\"ob.data.length = %d\\n\", ob.data.length);\n    assert(ob.data.length == 10);\n    for (i = 0; i < 10; i++)\n        assert(ob.data[i] == char.init);\n\nprintf(\"test7.1()\\n\");\n    ob.data[] = '-';\nprintf(\"test7.2()\\n\");\n    printf(\"ob.data[] = '%.*s'\\n\", ob.data.length, ob.data.ptr);\n    for (i = 0; i < 10; i++)\n        assert(ob.data[i] == '-');\n\n    ob.offset = 3;\n    ob.write(\"foo\", 3);\n    printf(\"ob.data.length = %d\\n\", ob.data.length);\n    printf(\"ob.data[] = '%.*s'\\n\", ob.data.length, ob.data.ptr);\n    for (i = 0; i < 10; i++)\n    {\n        if (i < 3 || i >= 6)\n            assert(ob.data[i] == '-');\n    }\n    assert(ob.data[3] == 'f');\n    assert(ob.data[4] == 'o');\n    assert(ob.data[5] == 'o');\n}\n\n/* ================================ */\n\nclass A8\n{\n    enum { bar = 8, baz }\n    int foo;\n}\n\nvoid test8()\n{\n    printf(\"test8()\\n\");\n    A8 a;\n    a = new A8();\n    a.foo = A8.bar;\n    assert(a.foo == 8);\n}\n\n/* ================================ */\n\n\nint z9;\n\nunittest\n{\n    printf(\"module unittest 9\\n\");\n    z9 = 3;\n}\n\n\nvoid test9()\n{\n    assert(z9 == 3);\n}\n\n/* ================================ */\n\nvoid test10()\n{\n    printf(\"test10()\\n\");\n    const int i = 8000;\n    assert(i == 8000);\n    static int j = 78;\n    assert(j == 78);\n}\n\n/* ================================ */\n\nObject test11_a()\n{\n    return null;\n}\n\nvoid test11()\n{\n    assert(test11_a() is null);\n}\n\n/* ================================ */\n\nclass A12 { }\nclass B12 { }\n\nint testx(A12 a) { return 1; }\n\nint testx(B12 b) { return 2; }\n\nvoid test12()\n{\n    A12 a = new A12();\n    B12 b = new B12();\n\n    assert(testx(a) == 1);\n    assert(testx(b) == 2);\n}\n\n/* ================================ */\n\nchar[] tolower13(ref char[] s)\n{\n    int i;\n\n    for (i = 0; i < s.length; i++)\n    {\n        char c = s[i];\n        if ('A' <= c && c <= 'Z')\n            s[i] = cast(char)(c + (cast(char)'a' - 'A'));\n    }\n    return s;\n}\n\nvoid test13()\n{\n    char[] s1 = \"FoL\".dup;\n    char[] s2;\n\n    s1 = s1.dup;\n    s2 = tolower13(s1);\n    assert(cmp(s2, \"fol\") == 0);\n    assert(s2 == s1);\n}\n\n/* ================================ */\n\nalias ABC14* LPABC14;\nclass ABC14 { }\n\nalias DEF14* LPDEF14;\nDEF14[3] foo;\nstruct DEF14 { int x; }\n\nvoid test14()\n{\n    assert(foo.sizeof == int.sizeof * 3);\n}\n\n/* ================================ */\n\nclass bools15\n{\n    bool a = true, b = true, c = true;\n    void dump()\n    {\n        printf(\"%d %d %d\\n\", a, b, c);\n    }\n}\n\nvoid test15()\n{\n     bools15 k = new bools15;\n     k.a = true; k.dump();\n     k.b = true; k.dump();\n     k.c = true; k.dump();\n     assert(k.a == true);\n     assert(k.b == true);\n     assert(k.c == true);\n}\n\n\n/* ================================ */\n\nalign(4) struct foo16\n{\n    short s;\n    int i;\n}\n\nvoid test16()\n{\n    assert(foo16.sizeof == 8);\n}\n\n/* ================================ */\n\nenum Color { red, blue, green };\nint[Color.max+1] colors1 = [ Color.blue:6, Color.green:2, Color.red:5 ];\n\n\nenum { red, blue, green };\nint[3] colors2 = [ blue:6, green:2, red:5 ];\n\nvoid test17()\n{\n    assert(colors1.length == 3);\n    assert(colors1[0] == 5);\n    assert(colors1[1] == 6);\n    assert(colors1[2] == 2);\n    assert(colors2[0] == 5);\n    assert(colors2[1] == 6);\n    assert(colors2[2] == 2);\n}\n\n/* ================================ */\n\n\nalias void* HANDLE18;\n\nHANDLE18 testx18()\n{\n    return null;\n}\n\nvoid test18()\n{\n    assert(testx18() is null);\n}\n\n/* ================================ */\n\nclass Test19 { struct { int a, b, c; } }\n\nvoid test19()\n{\n    Test19 t = new Test19();\n\n    t.a = 3;\n    assert(t.a == 3);\n}\n\n/* ================================ */\n\nbool tested20;\n\nstruct S20\n{\n    unittest\n    {\n        assert(!tested20);\n        tested20 = true;\n    }\n}\n\nvoid test20()\n{\n    assert(tested20);\n}\n\n/* ================================ */\n// https://issues.dlang.org/show_bug.cgi?id=7848\n\n@safe pure nothrow void func7848() {}\n\n@safe pure nothrow unittest\n{\n    func7848();\n}\n\n/* ================================ */\n// https://issues.dlang.org/show_bug.cgi?id=8128\n\nint flag8128 = 0;\n\ninterface I8128\n{\n    unittest\n    {\n        printf(\"utest, flag8128 = %d\\n\", flag8128);\n        flag8128 = 1;\n    }\n}\n\nvoid test8128()\n{\n    printf(\"main, flag8128 = %d\\n\", flag8128);\n    assert(flag8128 == 1);\n}\n\n/* ================================ */\n\nclass C8635{\n        int x;\n        this(int x)\n        {\n                this.x = x;\n        }\n}\nvoid test8635()\n{\n        assert(new C8635(2).x==2);\n        assert(new C8635(3).x==3);\n}\n\n/* ================================ */\n\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test8128();\n    test8635();\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test19185.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=19185\n\nint fun()\n{\n    int x = 2;\n    struct A\n    {\n        int a;\n        this(int a)\n        {\n            this.a = a + x;      // segault here\n        }\n    }\n\n    A a = 5;\n    return a.a;\n}\n\nvoid main()\n{\n    assert(fun() == 7);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test19251.d",
    "content": "string result;\n\nstruct A\n{\n    int[] a;\n    immutable(A) fun()\n    {\n        result ~= \"Yo\";\n        return immutable A([7]);\n    }\n\n    alias fun this;\n}\n\nvoid main()\n{\n    A a;\n    immutable A b = a;   // error: cannot implicitly convert expression a of type A to immutable(A)\n    assert(result == \"Yo\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test20.d",
    "content": "import core.vararg;\n\nextern(C) int printf(const char*, ...);\n\n/*****************************************/\n\nclass A1\n{\n    union\n    {\n        struct\n        {\n            int x;\n            public int y;\n        }\n        protected int z;\n    }\n}\n\nclass A2\n{\n    struct\n    {\n        int x;\n        public int y;\n    }\n}\n\nclass A3\n{\n    union\n    {\n        int x;\n        public int y;\n    }\n}\n\nvoid test1()\n{\n    A1 a1 = new A1();\n    A2 a2 = new A2();\n    A3 a3 = new A3();\n\n    a1.x = 1;\n    a1.y = 2;\n    a1.z = 3;\n    assert(a1.x == 3);\n    assert(a1.y == 2);\n\n    a2.x = 1;\n    a2.y = 2;\n    assert(a2.x == 1);\n\n    a3.x = 1;\n    a3.y = 2;\n    assert(a3.x == 2);\n}\n\n/*****************************************/\n\nstruct A4\n{\n    union\n    {\n        struct\n        {\n            int x = 13;\n        }\n        int y;\n    }\n}\n\nvoid test4()\n{\n    printf(\"A4.sizeof = %d\\n\", A4.sizeof);\n    assert(A4.sizeof == 1 * int.sizeof);\n\n    A4 q;\n    assert(q.y == 13);\n}\n\n/*****************************************/\n\nclass A5\n{\n     union {\n         struct {\n             int x;\n         }\n         public int y;\n     }\n}\n\nvoid test5()\n{\n     A5 a = new A5;\n\n     a.x = 3;\n     a.y = 4;\n     assert(a.x == 4);\n}\n\n/*****************************************/\n\nint i6 = 5;\n\nfloat m6 = 5.0;\n\nvoid test6()\n{\n  void f()\n  {\n    void i6(float j)\n    {\n        m6 = j;\n    }\n\n    void g()\n    {\n        i6 = 1;\n    }\n    g();\n  }\n\n  f();\n\n  printf( \"%d %f\\n\", i6, m6);\n  assert(i6 == 5);\n  assert(m6 == 1);\n}\n\n/*****************************************/\n\nconst int a1 = 50;\nconst int a2 = 50;\nconst int a3 = a1 * a2;\n\nconst int b1 = a1 - 1;\nconst int b2 = a2 - 1;\n\nconst int c1 = 50*50;\nconst int c2 = (a1-1)*(a2-1);\nconst int c3 = b1*b2;\n\nint[4*c1]  array1;  // illegal!\nint[4*c2]  array2;  // illegal!\nint[4*c3]  array3;  // illegal!\n\nint[a3]    array4;  // valid! no error!\n\nvoid test7()\n{\n    assert(a1 == 50);\n    assert(a2 == 50);\n    assert(a3 == 2500);\n\n    assert(b1 == 49);\n    assert(b2 == 49);\n\n    assert(c1 == 2500);\n    assert(c2 == 2401);\n    assert(c3 == 2401);\n\n    assert(array1.length == 10000);\n    assert(array2.length == 9604);\n    assert(array3.length == 9604);\n}\n\n/*****************************************/\n\nstruct Foo8\n{\n    static Foo8 bar()\n    {\n        Foo8 res;\n        return res;\n    }\n}\n\nvoid test8()\n{\n    Foo8[8] x;\n    x[] = Foo8.bar;\n}\n\n\n/*****************************************/\n\nvoid test9()\n{\n     try {\n     } catch (Exception e) {\n         debug printf(\"Exception happened\\n\");\n     }\n}\n\n/*****************************************/\n\nstruct Foo10 {\n  const bool opEquals(const ref Foo10 x) {\n    return this.normalize is x.normalize;\n  }\n  const Foo10 normalize() {\n    Foo10 res;\n    return res;\n  }\n}\n\nvoid test10()\n{\n}\n\n\n/*****************************************/\n\nscope class T11\n{\n    this(){}\n    ~this(){}\n}\n\nvoid test11()\n{\n    scope T11 t=new T11();\n    int i=1;\n    switch(i)\n    {\n        case 1:\n            break;\n\n        default:\n            break;\n    }\n}\n\n/*****************************************/\n\nvoid test12()\n{\n        char[] s;\n        char[] t;\n\n        if (true)\n            s = null;\n        s = (true) ? null : t;\n        t = (true) ? s : null;\n}\n\n/*****************************************/\n\nclass Foo13\n{\n       int init (int x) { return 1; }\n\n       static int init (long y) { return 2; }\n}\n\nvoid test13()\n{\n    Foo13 f = new Foo13();\n    int i;\n\n    i = f.init(1);\n    assert(i == 1);\n    i = f.init(1L);\n    assert(i == 2);\n}\n\n/*****************************************/\n\nvoid write14(bool[] c)\n{\n    printf(\"[%2d]: \", c.length);\n    foreach (bool x; c)\n        printf(\"%d,\", x);\n    printf(\"\\n\");\n}\n\nvoid test14()\n{\n     static bool[] a = [ 1, 1, 0, 1, 0 ];\n     static bool[] b = [ 1, 0, 0, 1 ];\n     bool[] c = a ~ b;\n\n     static bool[] r1 = [1,1,0,1,0,1,0,0,1];\n     static bool[] r2 = [1,1,0,1,0,1,0,0,1,1,1,0,1,0];\n     static bool[] r3 = [1,1,0,1,0,1,0,0,1,1,1,0,1,0,0];\n     static bool[] r4 = [1,1,0,1,0,1,0,0,1,1,1,0,1,0,0,1];\n\n\n     write14(c);\n     assert(c == r1);\n\n     c ~= a;\n     write14(c);\n     assert(c == r2);\n\n     c ~= 0;\n     write14(c);\n     assert(c == r3);\n\n     c ~= 1;\n     write14(c);\n     assert(c == r4);\n}\n\n/*****************************************/\n\nvoid test15()\n{\n        bool[] b;\n        bool[] c;\n\n        b.length = 10;\n        c = b[0..4];\n        c[] = true;\n\n        assert(b[0] == true);\n        assert(b[1] == true);\n        assert(b[2] == true);\n        assert(b[3] == true);\n\n        assert(b[4] == false);\n        assert(b[5] == false);\n        assert(b[6] == false);\n        assert(b[7] == false);\n        assert(b[8] == false);\n        assert(b[9] == false);\n}\n\n/*****************************************/\n\nint y16;\n\nclass C16\n{\n        new(size_t size, byte blah){\n                void* v = (new byte[C16.classinfo.initializer.length]).ptr;\n                y16 = 1;\n                assert(blah == 3);\n                return v;\n        }\n        int x;\n        this()\n        {\n            x = 4;\n        }\n}\n\nvoid test16()\n{\n    C16 c = new(3) C16;\n    assert(y16 == 1);\n    assert(c.x == 4);\n}\n\n/*****************************************/\n\nubyte* ptr17;\n\nvoid test17()\n{\n    ubyte[16] foo;\n\n    printf(\"foo = %p\\n\", foo.ptr);\n    ptr17 = foo.ptr;\n    abc17(foo);\n}\n\nvoid abc17(ref ubyte[16] bar)\n{\n    printf(\"bar = %p\\n\", bar.ptr);\n    assert(bar.ptr == ptr17);\n}\n\n/*****************************************/\n\nstruct Iterator18(T)\n{\n   T* m_ptr;\n\n   const bool opEquals(const ref Iterator18 iter)\n   {\n     return (m_ptr == iter.m_ptr);\n   }\n\n   const int opCmp(const ref Iterator18 iter)\n   {\n     return cast(int)(m_ptr - iter.m_ptr);\n   }\n}\n\nvoid test18()\n{\n    Iterator18!(int) iter;\n}\n\n/*****************************************/\n\nstruct S29(T)\n{\n   const bool opEquals(const ref S29!(T) len2)\n   {\n     return 0;\n   }\n\n   const int opCmp(const ref S29!(T) len2)\n   {\n     return 0;\n   }\n}\n\n\nvoid test19()\n{\n   TypeInfo info = typeid(S29!(int));\n}\n\n\n/*****************************************/\n\nclass Mapped : Buffer\n{\n        this()\n        {\n        }\n\n        ~this()\n        {\n        }\n}\n\nclass Buffer\n{\n        private uint limit;\n        private uint capacity;\n        private uint position;\n\n        invariant()\n        {\n               assert (position <= limit);\n               assert (limit <= capacity);\n        }\n}\n\nvoid test20()\n{\n    Buffer b = new Buffer();\n    delete b;\n}\n\n/*****************************************/\n\nclass T21\n{\n char[1] p1;\n char[1] p2;\npublic:\n char[] P() {return p1~p2;}\n}\n\nvoid test21()\n{\n    T21 t = new T21;\n    t.p1[0] = 'a';\n    t.p2[0] = 'b';\n    assert(t.P() == \"ab\");\n}\n\n/*****************************************/\n\nvoid test22()\n{\n    struct foo1 { int a; int b; int c; }\n\n    class foo2\n    {\n        foo1[] x;\n\n        foo1 fooret(foo1 foo2)\n        {\n            x.length = 9;\n            return x[0] = foo2; // Here\n\n            // x[0] = foo2; --- This version does not\n            // return x[0]; --- cause the error.\n        }\n    }\n}\n\n\n/*****************************************/\n\nvoid test23()\n{\n    float f;\n    double d;\n    real r;\n\n    if (f > ifloat.max)\n        goto Loverflow;\n    if (d > ifloat.max)\n        goto Loverflow;\n    if (r > ifloat.max)\n        goto Loverflow;\n\n    if (ifloat.max < f)\n        goto Loverflow;\n    if (ifloat.max < d)\n        goto Loverflow;\n    if (ifloat.max < r)\n        goto Loverflow;\n\n    return;\n\n  Loverflow:\n    return;\n}\n\n/*****************************************/\n\ninterface I24 { }\n\nvoid test24()\n{\n}\n\n/*****************************************/\n\ninterface D25{}\ninterface C25:D25{}\ninterface B25:C25{}\ninterface A25:B25{}\n\nvoid test25()\n{\n}\n\nclass     A26:B26{}\ninterface B26:C26{}\ninterface C26:D26{}\ninterface D26{}\n\nvoid test26()\n{\n}\n\ninterface A27:B27{}\ninterface B27:C27{}\ninterface C27:D27{}\ninterface D27{}\n\nvoid test27()\n{\n}\n\n/*****************************************/\n\nvoid test28()\n{\n    const double d = -1.0;\n    int i = cast(int)d;\n    printf(\"i = %d\\n\", i);\n    assert(-1 == i);\n}\n\n/*****************************************/\n\nstatic int[1][5] array = [[1],[2],[3],[4],[5] ];\n\nvoid Lookup( int which )\n{\n   switch( which )\n   {\n     case 0 : return cast(void)array[which];\n     default: assert(0);\n   }\n}\n\nvoid test29()\n{\n}\n\n/*****************************************/\n\nvoid test30()\n{\n  double d = 1;\n  cdouble cd = 1+0i;\n  assert(cd == 1.0 + 0i);\n}\n\n/*****************************************/\n\nvoid foo31(...)\n{\n    byte b = va_arg!byte(_argptr);\n    assert(b == 8);\n}\n\nvoid test31()\n{\n    byte x = 9;\n    foo31(--x);\n    --x;\n    foo31(++x);\n}\n\n/*****************************************/\n\ntemplate Foo33(T, int L)\n{\n        T[L] arr;\n        class Bar {\n                int before = 6;\n                T[L] arr;\n                int after = 7;\n        }\n}\n\nvoid test33()\n{\n        alias Foo33!(int, 100) foo;\n        foreach (int x; foo.arr)\n                assert(x == int.init);\n\n        foo.Bar bar = new foo.Bar();\n        foreach (int x; bar.arr)\n        {       //printf(\"%d\\n\", x);\n                assert(x == int.init);\n        }\n}\n\n\n/*****************************************/\n\nvoid test34()\n{\n        bool[1] a;\n        bool[1] b;\n\n        bool[] concat() {\n                return a~b;\n        }\n\n        a[]=0;\n        b[]=1;\n\n        bool[] arr=concat();\n\n        assert(arr.length==2);\n        assert(arr[0]==0);\n        assert(arr[1]==1);\n}\n\n/*****************************************/\n\nvoid dummy35(...) {}\n\nvoid test35()\n{\n    byte x = 9;\n    dummy35(x);\n    int y = --x;\n    assert (y == 8);\n    assert (x == 8);\n}\n\n/*****************************************/\n\nvoid test36()\n{\n        int[] a;\n        a.length = 2;\n        a[0]=1;\n        a[1]=2;\n\n        int[] b;\n        b.length = 1;\n        b[0]=3;\n\n        a~=b;\n\n        assert(a.length==3);\n        assert(a[0]==1);\n        assert(a[1]==2);\n        assert(a[2]==3);\n\n        assert(b.length==1);\n        assert(b[0]==3);\n}\n\n/*****************************************/\n\nstruct Range{\n        int width(){\n                return 1;\n        }\n}\n\nclass Container {\n        Range opIndex(int i){\n                return data[i];\n        }\n\n        Range[2] data;\n}\n\nvoid test37()\n{\n        Container ranges=new Container;\n\n// fails with -inline\n//      assert(ranges[0].width() == 1);\n}\n\n/*****************************************/\n\nvoid test38()\n{\n        uint mask = (uint.max >> 1);\n        assert(mask == (uint.max >> 1));\n}\n\n\n\n/*****************************************/\n\nvoid test41()\n{\n    assert(new void[40] == new void[40]);\n}\n\n/*****************************************/\n\nvoid test42()\n{\n        static ubyte[] master = [\n                0xE3u, 0x83u, 0xAFu, 0xE3u, 0x83u, 0xADu, 0xE3u, 0x82u,\n                0xB9u, 0xEFu, 0xBDu, 0x97u\n        ];\n\n        string string1 =  \"ワロスｗ\";\n        string string2 = r\"ワロスｗ\";\n        string string3 =  `ワロスｗ`;\n        string string4 = x\"E3 83 AF E3 83 AD E3 82 B9 EF BD 97\";\n\n        assert(string1.length==master.length);\n\n        for(int i=0; i<master.length; i++){\n                assert(string1[i]==master[i]);\n        }\n\n        assert(string2.length==master.length);\n\n        for(int i=0; i<master.length; i++){\n                assert(string2[i]==master[i]);\n        }\n\n        assert(string3.length==master.length);\n\n        for(int i=0; i<master.length; i++){\n                assert(string3[i]==master[i]);\n        }\n\n        assert(string4.length==master.length);\n\n        for(int i=0; i<master.length; i++){\n                assert(string4[i]==master[i]);\n        }\n}\n\n/*****************************************/\n\nstruct S43\n{\n        int i=1;\n}\n\nstatic S43[3] s= [ 1: { 2 } ];\n\nvoid test43()\n{\n        assert(s[0].i==1);\n        assert(s[1].i==2);\n        assert(s[2].i==1);\n}\n\n/*****************************************/\n\nstruct S44\n{\n  int i;\n}\n\nstatic S44[12] S44s = [];\n\nvoid test44()\n{\n}\n\n\n/*****************************************/\n\nstruct S45\n{\n    double x = 0, y = 0;\n    static S45 opCall(int i) { S45 r; r.x = i; return r; }\n    S45 opMul(S45 s)\n    {\n        S45 r;\n        r.x = x * s.x;\n        r.y = y * s.y;\n        return r;\n    }\n}\n\ntemplate sqr(F) { F sqr(F x) { return x * x; } }\n\ntemplate pow(F)\n{\n    F pow(F x, int i) {\n        if (i < 1)\n        {\n            static if (is(F : real))\n                return 1;\n            else\n                return F(1);\n        }\n        if (i & 1)\n        {\n            if (i == 1)\n                return x;\n            else\n                return x * pow(x,i-1);\n        }\n        return sqr!(F)(pow(x,i/2));\n    }\n}\n\nvoid test45()\n{\n    S45 s = S45(10);\n    S45 val = pow!(S45)(s,2);\n    printf(\"x = %2.2lf, y = %2.2lf\\n\", val.x, val.y);\n    assert(val.x == 100);\n    assert(val.y == 0);\n    double d = pow!(double)(10,3);\n    printf(\"%2.2lf\\n\", d);\n    assert(d == 1000);\n}\n\n/*****************************************/\n\nstruct Node46\n{\n  Node46* left,right,parent;\n  int color = 5;\n  char[] key;\n  char[] value;\n}\n\nvoid test46()\n{\n  Node46* x = new Node46;\n  assert( x.left is null );\n  assert( x.right is null );\n  assert( x.parent is null );\n  assert( x.color is 5 );\n  assert( x.key is null );\n  assert( x.value is null );\n}\n\n/*****************************************/\n\nvoid test47()\n{\n   cdouble[] a;\n   cdouble[] b;\n   foreach(ref cdouble d; b)\n     {\n       d = -a[0];\n       for(;;){}\n     }\n}\n\n/*****************************************/\n\nstring foo48(string s)\n{\n    return s;\n}\n\nvoid test48()\n{\n    char c = '?';\n    string s;\n\n    s = foo48(\"is this it\" ~ c ~ \" yep!\");\n    assert(s == \"is this it? yep!\");\n\n    s = foo48(\"is this it\" ~ c);\n    assert(s == \"is this it?\");\n\n    s = foo48(c ~ \"is this it\");\n    assert(s == \"?is this it\");\n}\n\n\n/*****************************************/\n\nchar[10] foo49 = void;\n\nvoid test49()\n{\n    int i = void;\n    //printf(\"i = %d\\n\", i);\n    int[10] a = void;\n    foreach (int x; a)\n    {\n        printf(\"\\tx = %d\\n\", x);\n    }\n}\n\n/*****************************************/\n\nvoid foo50(string s) { assert(s == \"is this it? yep!\"); }\n\nvoid test50()\n{\n    char c = '?';\n    foo50(\"is this it\"~c~\" yep!\");\n}\n\n/*****************************************/\n\nvoid test51()\n{\n    bool[9][3] qwert;\n\n    printf(\"qwert.sizeof = %d\\n\", qwert.sizeof);\n\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 9; j++)\n            assert(qwert[i][j] == false);\n\n    version (D_Bits)\n        assert(qwert.sizeof == 12);\n    else\n        assert(qwert.sizeof == 27);\n\n    qwert[0][3] = true;\n    qwert[0][5] = true;\n    qwert[0][7] = true;\n\n    qwert[1..3] = qwert[0];\n\n    for (int i = 0; i < 3; i++)\n    {\n        assert(qwert[i][0] == false);\n        assert(qwert[i][1] == false);\n        assert(qwert[i][2] == false);\n        assert(qwert[i][3] == true);\n        assert(qwert[i][4] == false);\n        assert(qwert[i][5] == true);\n        assert(qwert[i][6] == false);\n        assert(qwert[i][7] == true);\n        assert(qwert[i][8] == false);\n    }\n}\n\n\n/*****************************************/\n\nvoid test52()\n{\n    size_t vsize = void.sizeof;\n    assert(vsize == 1);\n}\n\n/*****************************************/\n\nconst char[3][13] month = [\n     1: \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\n     8: \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"\n];\n\nvoid test53()\n{\n    printf(\"%.*s\\n\", month[1].length, month[1].ptr);\n    printf(\"%.*s\\n\", month[2].length, month[2].ptr);\n    printf(\"%.*s\\n\", month[3].length, month[3].ptr);\n    printf(\"%.*s\\n\", month[4].length, month[4].ptr);\n    printf(\"%.*s\\n\", month[5].length, month[5].ptr);\n    printf(\"%.*s\\n\", month[6].length, month[6].ptr);\n    printf(\"%.*s\\n\", month[8].length, month[8].ptr);\n\n    assert(month[1] == \"Jan\");\n    assert(month[2] == \"Feb\");\n    assert(month[3] == \"Mar\");\n    assert(month[4] == \"Apr\");\n    assert(month[5] == \"May\");\n    assert(month[6] == \"Jun\");\n    assert(month[8] == \"Aug\");\n    assert(month[9] == \"Sep\");\n    assert(month[10] == \"Oct\");\n    assert(month[11] == \"Nov\");\n    assert(month[12] == \"Dec\");\n\n    assert(month[0][0] == 0xFF);\n    assert(month[0][1] == 0xFF);\n    assert(month[0][2] == 0xFF);\n\n    assert(month[7][0] == 0xFF);\n    assert(month[7][1] == 0xFF);\n    assert(month[7][2] == 0xFF);\n}\n\n/*****************************************/\n\nstruct S54\n{\n    static S54 foo()\n    {\n        S54 s;\n        with (s) {} // bug\n        return s;\n    }\n\n    static S54 bar()\n    {\n        return S54.foo() * S54.foo();\n    }\n\n    S54 opMul(S54 s)\n    {\n        return s;\n    }\n}\n\nvoid test54()\n{\n    S54.bar();\n}\n\n/*****************************************/\n\nvoid test55()\n{\n  char c = 'a';\n  char[] str, uvw;\n  str = str ~ c;\n  uvw = c ~ uvw;\n\n  printf(\"%.*s\\n\", str.length, str.ptr);\n  assert(str == \"a\");\n  assert(uvw == \"a\");\n\n  c = 'b';\n  printf(\"%.*s\\n\", str.length, str.ptr);\n  assert(str == \"a\");\n  assert(uvw == \"a\");\n}\n\n/*****************************************/\n\nvoid test56()\n{\n    char[4] a, b;\n    a[] = 'a'; b[] = 'a';\n\n    for (int i = 0; i < 4; i++)\n    {\n        assert(a[i] == 'a');\n        assert(b[i] == 'a');\n    }\n\n    a[] = b[] = 'b';\n\n    for (int i = 0; i < 4; i++)\n    {\n        assert(a[i] == 'b');\n        assert(b[i] == 'b');\n    }\n\n}\n\n\n/*****************************************/\n\nvoid test57()\n{\n        char[] a;\n        char[] b;\n\n        a = a ~ 'x';\n        assert(a == \"x\");\n        b = 'c' ~ a ~ 'b';\n        assert(b == \"cxb\");\n}\n\n\n/*****************************************/\n\nstruct Foo58\n{\n    ubyte a, b, c;\n}\n\nvoid test58()\n{\n    Foo58 d;\n    foobar58(d);\n    return cast(void)0;\n}\n\nvoid foobar58(Foo58 e) {}\n\n\n/*****************************************/\n\nvoid foo59(string s)\n{\n    assert(s == \"hello\");\n}\n\nvoid foo59(wstring s)\n{\n    assert(s == \"baby\");\n}\n\nvoid foo59(dstring s)\n{\n    assert(s == \"jane\");\n}\n\nvoid test59()\n{\n    string h = \"hello\"c;\n    wstring b = \"baby\"w;\n    dstring j = \"jane\"d;\n\n    //writefln(\"%s %s %s\", h, b, j);\n\n    foo59(h);\n    foo59(\"hello\"c);\n    foo59(b);\n    foo59(\"baby\"w);\n    foo59(j);\n    foo59(\"jane\"d);\n}\n\n/*****************************************/\n\nclass C60\n{\n    static const int x;\n    const int y;\n\n    void foo()\n    {\n    }\n\n    static this()\n    {\n        x = 5;\n    }\n\n    this()\n    {\n        y = 7;\n    }\n}\n\nconst int z60;\n\nstatic this()\n{\n    z60 = 3;\n}\n\nvoid test60()\n{\n    C60 c = new C60();\n\n    assert(c.x == 5);\n    assert(c.y == 7);\n    assert(z60 == 3);\n}\n\n/*****************************************/\n\nvoid foo61(real[] arr)\n{\n    // i = 0 doesn't trigger the bug, everything bigger seems to\n    // also, making this const fixes the bug\n    size_t i = 1;\n\n    for (size_t j = i; j >= i; j -= i)\n    {\n        // interesting results follow from this:\n        printf(\"%d \", i);\n        // it prints a _lot_ of ones\n\n        arr[j] = arr[j - i];\n    }\n}\n\nvoid test61()\n{\n    real[] array;\n    array.length = 2; // whatever, as long as it's more than 1\n\n    foreach (ref real i; array)\n        i = 1; // just something\n\n    foo61(array);\n}\n\n/*****************************************/\n\nvoid bug7493()\n{\n    string str = \"abcde\";\n    const(void) [][1] arr = [str];\n    assert(arr[0].length == str.length);\n    const(void) [][1] arr2;\n    arr2 = [str];\n    assert(arr[0].length == str.length);\n}\n\n/*****************************************/\n\nint main()\n{\n    test1();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test56();\n    test57();\n    test58();\n    test59();\n    test60();\n    test61();\n    bug7493();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test21.d",
    "content": "// EXTRA_SOURCES: imports/test21a.d\n\nimport imports.test21a;\n\nint main()\n{\n    TA!(int) variable;\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test22.d",
    "content": "// REQUIRED_ARGS:\n\nimport std.math: poly;\nimport core.stdc.stdarg;\n\nextern(C)\n{\n    int printf(const char*, ...);\n    version(Windows)\n    {\n        int _snprintf(char*, size_t, const char*, ...);\n        alias _snprintf snprintf;\n    }\n    else\n        int snprintf(char*, size_t, const char*, ...);\n}\n\n/*************************************/\n\n// http://www.digitalmars.com/d/archives/digitalmars/D/bugs/4766.html\n// Only with -O\n\nreal randx()\n{\n    return 1.2;\n}\n\nvoid test1()\n{\n    float x10=randx();\n    float x11=randx();\n    float x20=randx();\n    float x21=randx();\n    float y10=randx();\n    float y11=randx();\n    float y20=randx();\n    float y21=randx();\n\n    float tmp=(\n    x20*x21 + y10*y10 + y10*y11 + y11*y11 +\n    y11*y20 + y20*y20 + y10*y21 + y11*y21 +\n    y21*y21);\n    assert(tmp > 0);\n}\n\n/*************************************/\n\nvoid test2()\n{\n        double x10=randx();\n        double x11=randx();\n        double x20=randx();\n        double x21=randx();\n        double y10=randx();\n        double y11=randx();\n        double y20=randx();\n        double y21=randx();\n\n    double tmp=(\n    x20*x21 + y10*y10 + y10*y11 + y11*y11 +\n    y11*y20 + y20*y20 + y10*y21 + y11*y21 +\n    y21*y21);\n    assert(tmp > 0);\n}\n\n/*************************************/\n\nvoid test3()\n{\n    real x10=randx();\n    real x11=randx();\n    real x20=randx();\n    real x21=randx();\n    real y10=randx();\n    real y11=randx();\n    real y20=randx();\n    real y21=randx();\n\n    real tmp=(\n    x20*x21 + y10*y10 + y10*y11 + y11*y11 +\n    y11*y20 + y20*y20 + y10*y21 + y11*y21 +\n    y21*y21);\n    assert(tmp > 0);\n}\n\n/*************************************/\n\nvoid test4()\n{\n     printf(\"main() : (-128 >= 0)=%s, (-128 <= 0)=%s\\n\",\n              cast(char*)(-128 >= 0 ? \"true\" : \"false\"),\n              cast(char*)(-128 <= 0 ?  \"true\" : \"false\"));\n\n     printf(\"main() : (128 >= 0)=%s, (128 <= 0)=%s\\n\",\n              cast(char*)(128 >= 0 ? \"true\" : \"false\"),\n              cast(char*)(128 <= 0 ?  \"true\" : \"false\"));\n\n     assert((-128 >= 0 ? \"true\" : \"false\") == \"false\"),\n     assert((-128 <= 0 ? \"true\" : \"false\") == \"true\");\n     assert((+128 >= 0 ? \"true\" : \"false\") == \"true\"),\n     assert((+128 <= 0 ? \"true\" : \"false\") == \"false\");\n}\n\n\n/*************************************/\n\nint foo5() { assert(0); } // No return.\n\nint abc5()\n{\n    printf(\"foo = %d\\n\", foo5());\n    return 0;\n}\n\nvoid test5()\n{\n}\n\n/*************************************/\n\nvoid test6()\n{\n    ireal a = 6.5i % 3i;\n    printf(\"%Lfi %Lfi\\n\", a, a - .5i);\n    assert(a == .5i);\n\n    a = 6.5i % 3;\n    printf(\"%Lfi %Lfi\\n\", a, a - .5i);\n    assert(a == .5i);\n\n    real b = 6.5 % 3i;\n    printf(\"%Lf %Lf\\n\", b, b - .5);\n    assert(b == .5);\n\n    b = 6.5 % 3;\n    printf(\"%Lf %Lf\\n\", b, b - .5);\n    assert(b == .5);\n}\n\n/*************************************/\n\nvoid test7()\n{\n    cfloat f = 1+0i;\n    f %= 2fi;\n    printf(\"%f + %fi\\n\", f.re, f.im);\n    assert(f == 1 + 0i);\n\n    cdouble d = 1+0i;\n    d %= 2i;\n    printf(\"%f + %fi\\n\", d.re, d.im);\n    assert(d == 1 + 0i);\n\n    creal r = 1+0i;\n    r %= 2i;\n    printf(\"%Lf + %Lfi\\n\", r.re, r.im);\n    assert(r == 1 + 0i);\n}\n\n/*************************************/\n\nvoid test8()\n{\n    cfloat f = 1+0i;\n    f %= 2i;\n    printf(\"%f + %fi\\n\", f.re, f.im);\n    assert(f == 1);\n\n    cdouble d = 1+0i;\n    d = d % 2i;\n    printf(\"%f + %fi\\n\", d.re, d.im);\n    assert(d == 1);\n\n    creal r = 1+0i;\n    r = r % 2i;\n    printf(\"%Lf + %Lfi\\n\", r.re, r.im);\n    assert(r == 1);\n}\n\n/*************************************/\n\nclass A9\n{\n    this(int[] params ...)\n    {\n        for (int i = 0; i < params.length; i++)\n        {\n            assert(params[i] == i + 1);\n        }\n    }\n}\n\nclass B9\n{\n    this()\n    {\n        init();\n    }\n\n    private void init()\n    {\n        A9 test1 = new A9(1, 2, 3);\n        A9 test2 = new A9(1, 2, 3, 4);\n        int[3] arg;\n        arg[0]=1, arg[1]=2, arg[2]=3;\n        A9 test3 = new A9(arg);\n    }\n}\n\nvoid test9()\n{\n    B9 test2 = new B9();\n}\n\n/*************************************/\n\nvoid test10()\n{\n    auto i = 5u;\n    auto s = typeid(typeof(i)).toString;\n    printf(\"%.*s\\n\", s.length, s.ptr);\n    assert(typeid(typeof(i)) == typeid(uint));\n}\n\n/*************************************/\n\nvoid test11()\n{\n    printf(\"%d\\n\", 3);\n    printf(\"xhello world!\\n\");\n}\n\n/*************************************/\n\nvoid assertEqual(real* a, real* b, string file = __FILE__, size_t line = __LINE__)\n{\n    auto x = cast(ubyte*)a;\n    auto y = cast(ubyte*)b;\n\n    // Only compare the 10 value bytes, the padding bytes are of undefined\n    // value.\n    version (X86) enum count = 10;\n    else version (X86_64) enum count = 10;\n    else enum count = real.sizeof;\n    for (size_t i = 0; i < count; i++)\n    {\n        if (x[i] != y[i])\n        {\n            printf(\"%02d: %02x %02x\\n\", i, x[i], y[i]);\n            import core.exception;\n            throw new AssertError(file, line);\n        }\n    }\n}\n\nvoid assertEqual(creal* a, creal* b, string file = __FILE__, size_t line = __LINE__)\n{\n    assertEqual(cast(real*)a, cast(real*)b, file, line);\n    assertEqual(cast(real*)a + 1, cast(real*)b + 1, file, line);\n}\n\nvoid test12()\n{\n    creal a = creal.nan;\n    creal b = real.nan + ireal.nan;\n    assertEqual(&a, &b);\n\n    real c= real.nan;\n    real d=a.re;\n    assertEqual(&c, &d);\n\n    d=a.im;\n    assertEqual(&c, &d);\n}\n\n/*************************************/\n\nvoid test13()\n{\n    creal a = creal.infinity;\n    creal b = real.infinity + ireal.infinity;\n    assertEqual(&a, &b);\n\n    real c = real.infinity;\n    real d=a.re;\n    assertEqual(&c, &d);\n\n    d=a.im;\n    assertEqual(&c, &d);\n}\n\n/*************************************/\n\nvoid test14()\n{\n    creal a = creal.nan;\n    creal b = creal.nan;\n    b = real.nan + ireal.nan;\n    assertEqual(&a, &b);\n\n    real c = real.nan;\n    real d=a.re;\n    assertEqual(&c, &d);\n\n    d=a.im;\n    assertEqual(&c, &d);\n}\n\n/*************************************/\n\nireal x15;\n\nvoid foo15()\n{\n    x15 = -x15;\n}\n\nvoid bar15()\n{\n    return foo15();\n}\n\nvoid test15()\n{\n    x15=2i;\n    bar15();\n    assert(x15==-2i);\n}\n\n/*************************************/\n\nreal x16;\n\nvoid foo16()\n{\n    x16 = -x16;\n}\n\nvoid bar16()\n{\n    return foo16();\n}\n\nvoid test16()\n{\n    x16=2;\n    bar16();\n    assert(x16==-2);\n}\n\n/*************************************/\n\nclass Bar17\n{\n        this(...) {}\n}\n\nclass Foo17\n{\n        void opAdd (Bar17 b) {}\n}\n\nvoid test17()\n{\n        auto f = new Foo17;\n        f + new Bar17;\n}\n\n\n/*************************************/\n\ntemplate u18(int n)\n{\n    static if (n==1) {\n       int a = 1;\n    } else\n       int b = 4;\n}\n\nvoid test18()\n{\n   mixin u18!(2);\n   assert(b == 4);\n}\n\n/*************************************/\n\nclass DP\n{\n  private:\n    void I(char[] p)\n    {\n        I(p[1..p.length]);\n    }\n}\n\nvoid test19()\n{\n}\n\n/*************************************/\n\nstruct Struct20\n{\n    int i;\n}\n\nvoid test20()\n{\n    auto s = new Struct20;\n    s.i = 7;\n}\n\n/*************************************/\n\nclass C21(float f)\n{\n    float ff = f;\n}\n\nvoid test21()\n{\n    auto a = new C21!(1.2);\n    C21!(1.2) b = new C21!(1.2);\n}\n\n/*************************************/\n\nvoid test22()\n{\n    static creal[] params = [1+0i, 3+0i, 5+0i];\n\n    printf(\"params[0] = %Lf + %Lfi\\n\", params[0].re, params[0].im);\n    printf(\"params[1] = %Lf + %Lfi\\n\", params[1].re, params[1].im);\n    printf(\"params[2] = %Lf + %Lfi\\n\", params[2].re, params[2].im);\n\n    creal[] sums = new creal[3];\n    sums[] = 0+0i;\n\n    foreach(creal d; params)\n    {\n        creal prod = d;\n\n        printf(\"prod = %Lf + %Lfi\\n\", prod.re, prod.im);\n        for(int i; i<2; i++)\n        {\n            sums[i] += prod;\n            prod *= d;\n        }\n        sums[2] += prod;\n    }\n\n    printf(\"sums[0] = %Lf + %Lfi\", sums[0].re, sums[0].im);\n    assert(sums[0].re==9);\n    assert(sums[0].im==0);\n    assert(sums[1].re==35);\n    assert(sums[1].im==0);\n    assert(sums[2].re==153);\n    assert(sums[2].im==0);\n}\n\n/*************************************/\n\nconst int c23 = b23 * b23;\nconst int a23 = 1;\nconst int b23 = a23 * 3;\n\ntemplate T23(int n)\n{\n    int[n] x23;\n}\n\nmixin T23!(c23);\n\nvoid test23()\n{\n    assert(x23.length==9);\n}\n\n/*************************************/\n\nifloat func_24_1(ifloat f, double d)\n{\n//    f /= cast(cdouble)d;\n    return f;\n}\n\nifloat func_24_2(ifloat f, double d)\n{\n    f = cast(ifloat)(f / cast(cdouble)d);\n    return f;\n}\n\nfloat func_24_3(float f, double d)\n{\n//    f /= cast(cdouble)d;\n    return f;\n}\n\nfloat func_24_4(float f, double d)\n{\n    f = cast(float)(f / cast(cdouble)d);\n    return f;\n}\n\nvoid test24()\n{\n    ifloat f = func_24_1(10i, 8);\n    printf(\"%fi\\n\", f);\n//    assert(f == 1.25i);\n\n    f = func_24_2(10i, 8);\n    printf(\"%fi\\n\", f);\n    assert(f == 1.25i);\n\n    float g = func_24_3(10, 8);\n    printf(\"%f\\n\", g);\n//    assert(g == 1.25);\n\n    g = func_24_4(10, 8);\n    printf(\"%f\\n\", g);\n    assert(g == 1.25);\n}\n\n/*************************************/\n\ntemplate cat(int n)\n{\n   const int dog = n;\n}\n\nconst char [] bird = \"canary\";\n\nconst int sheep = cat!(bird.length).dog;\n\nvoid test25()\n{\n    assert(sheep == 6);\n}\n\n/*************************************/\n\nstring toString26(cdouble z)\n{\n    char[ulong.sizeof*8] buf;\n\n    auto len = snprintf(buf.ptr, buf.sizeof, \"%f+%fi\", z.re, z.im);\n    return buf[0 .. len].idup;\n}\n\nvoid test26()\n{\n  static cdouble[] A = [1+0i, 0+1i, 1+1i];\n  string s;\n\n  foreach( cdouble z; A )\n  {\n    s = toString26(z);\n    printf(\"%.*s  \", s.length, s.ptr);\n  }\n  printf(\"\\n\");\n\n  for(int ii=0; ii<A.length; ii++ )\n    A[ii] += -1i*A[ii];\n\n  assert(A[0] == 1 - 1i);\n  assert(A[1] == 1 + 1i);\n  assert(A[2] == 2);\n\n  foreach( cdouble z; A )\n  {\n    s = toString26(z);\n    printf(\"%.*s  \", s.length, s.ptr);\n  }\n  printf(\"\\n\");\n}\n\n/*************************************/\n\nvoid test27()\n{   int x;\n\n    string s = (int*function(int ...)[]).mangleof;\n    printf(\"%.*s\\n\", s.length, s.ptr);\n    assert((int*function(int ...)[]).mangleof == \"APFiXPi\");\n    assert(typeof(x).mangleof == \"i\");\n    assert(x.mangleof == \"_D6test226test27FZ1xi\");\n}\n\n/*************************************/\n\nvoid test28()\n{\n    alias cdouble X;\n    X four = cast(X) (4.0i + 0.4);\n}\n\n/*************************************/\n\nvoid test29()\n{\n    ulong a = 10_000_000_000_000_000,\n          b =  1_000_000_000_000_000;\n\n    printf(\"test29\\n%lx\\n%lx\\n%lx\\n\", a, b, a / b);\n    assert((a / b) == 10);\n}\n\nstatic assert((10_000_000_000_000_000 / 1_000_000_000_000_000) == 10);\n\n/*************************************/\n\ntemplate chook(int n)\n{\n   const int chook = 3;\n}\n\ntemplate dog(alias f) {\n    const int dog =  chook!(f.mangleof.length);\n}\n\nclass pig {}\n\nconst int goose = dog!(pig);\n\nvoid test30()\n{\n    printf(\"%d\\n\", goose);\n    assert(goose == 3);\n}\n\n/*************************************/\n\ntemplate dog31(string sheep)\n{\n  immutable string dog31 = \"daschund\";\n}\n\nvoid test31()\n{\n    string duck = dog31!(\"bird\"[1..3]);\n\n    assert(duck == \"daschund\");\n}\n\n/*************************************/\n\nstruct particle\n{\n    int   active; /* Active (Yes/No) */\n    float life;   /* Particle Life   */\n    float fade;   /* Fade Speed      */\n\n    float r;      /* Red Value       */\n    float g;      /* Green Value     */\n    float b;      /* Blue Value      */\n\n    float x;      /* X Position      */\n    float y;      /* Y Position      */\n\n    float xi;     /* X Direction     */\n    float yi;     /* Y Direction     */\n\n    float xg;     /* X Gravity       */\n    float yg;     /* Y Gravity       */\n}\n\nparticle[10000] particles;\n\nvoid test32()\n{\n}\n\n/*************************************/\n\nclass Foo33\n{\n    template foo()\n    {\n        int foo() { return 6; }\n    }\n}\n\n\nvoid test33()\n{\n    Foo33 f = new Foo33;\n\n    assert(f.foo!()() == 6);\n    with (f)\n        assert(foo!()() == 6);\n}\n\n/*************************************/\n\ntemplate dog34(string duck)\n{\n    const int dog34 = 2;\n}\n\nvoid test34()\n{\n    int aardvark = dog34!(\"cat\" ~ \"pig\");\n\n    assert(aardvark == 2);\n}\n\n/*************************************/\n\nclass A35\n{\n    private bool quit;\n    void halt() {quit = true;}\n    bool isHalted() {return quit;}\n}\n\nvoid test35()\n{\n    auto a = new A35;\n\n    a.halt;         // error here\n    a.halt();\n\n    a.isHalted;     // error here\n    bool done = a.isHalted;\n    if (a.isHalted)\n    {\n    }\n}\n\n\n/*************************************/\n\nvoid test36()\n{\n    bool q = (0.9 + 3.5L == 0.9L + 3.5L);\n    assert(q);\n    static assert(0.9 + 3.5L == 0.9L + 3.5L);\n    assert(0.9 + 3.5L == 0.9L + 3.5L);\n}\n\n/*************************************/\n\nabstract class Foo37(T)\n{\n    void bar () { }\n}\n\nclass Bar37 : Foo37!(int)\n{\n}\n\nvoid test37()\n{\n    auto f = new Bar37;\n}\n\n/*************************************/\n\nvoid test38()\n{\n        auto s=`hello`;\n        assert(s.length==5);\n        assert(s[0]=='h');\n        assert(s[1]=='e');\n        assert(s[2]=='l');\n        assert(s[3]=='l');\n        assert(s[4]=='o');\n}\n\n/*************************************/\n\nvoid test39()\n{\n        int value=1;\n        string key = \"eins\";\n        int[char[]] array;\n\n        array[key]=value;\n        int* ptr = key in array;\n\n        assert(value == *ptr);\n}\n\n/*************************************/\n\nvoid test40()\n{\n        auto s=r\"hello\";\n        assert(s.length==5);\n        assert(s[0]=='h');\n        assert(s[1]=='e');\n        assert(s[2]=='l');\n        assert(s[3]=='l');\n        assert(s[4]=='o');\n}\n\n/*************************************/\n\nvoid test41()\n{\n    version (Windows)\n    {\n        version(D_InlineAsm){\n                double a = 1.2;\n                double b = 0.2;\n                double c = 1.4;\n\n                asm{\n                        movq XMM0, a;\n                        movq XMM1, b;\n                        addsd XMM1, XMM0;\n                        movq c, XMM1;\n                }\n\n                a += b;\n\n                b = a-c;\n                b = (b>0) ? b : (-1 * b);\n\n                assert(b < b.epsilon*4);\n        }\n    }\n}\n\n/*************************************/\n\nconst char[] tapir = \"some horned animal\";\n\nconst byte[] antelope = cast(byte []) tapir;\n\nvoid test42()\n{\n}\n\n/*************************************/\n\nvoid test43()\n{\n     string armadillo = \"abc\" ~ 'a';\n     assert(armadillo == \"abca\");\n     string armadillo2 = 'b' ~ \"abc\";\n     assert(armadillo2 == \"babc\");\n}\n\n/*************************************/\n\nconst uint baboon44 = 3;\n\nconst int monkey44 = 4;\n\nconst ape44 = monkey44 * baboon44;\n\nvoid test44()\n{\n    assert(ape44 == 12);\n}\n\n/*************************************/\n\nclass A45\n{\n this()\n {\n  b = new B();\n  b.x = 5; // illegal\n }\n\n class B\n {\n  protected int x;\n }\n\n B b;\n}\n\nvoid test45()\n{\n}\n\n\n/*************************************/\n\nclass C46(T)\n{\n    private T i; // or protected or package\n}\n\nvoid test46()\n{\n    C46!(int) c = new C46!(int); //  class t4.C46!(int).C46 member i is not accessible\n    c.i = 10;\n}\n\n/*************************************/\n\nvoid bug5809()\n{\n    ushort[2] x = void;\n    x[0] = 0;\n    x[1] = 0x1234;\n    ushort *px =  &x[0];\n\n    uint b = px[0];\n\n    assert(px[0] == 0);\n}\n\n/*************************************/\n\nvoid bug7546()\n{\n    double p = -0.0;\n    assert(p == 0);\n}\n\n\n/*************************************/\n\nreal poly_asm(real x, real[] A)\nin\n{\n    assert(A.length > 0);\n}\nbody\n{\n    version (D_InlineAsm_X86)\n    {\n        version (linux)\n        {\n        asm     // assembler by W. Bright\n        {\n            // EDX = (A.length - 1) * real.sizeof\n            mov     ECX,A[EBP]          ; // ECX = A.length\n            dec     ECX                 ;\n            lea     EDX,[ECX][ECX*8]    ;\n            add     EDX,ECX             ;\n            add     EDX,ECX             ;\n            add     EDX,ECX             ;\n            add     EDX,A+4[EBP]        ;\n            fld     real ptr [EDX]      ; // ST0 = coeff[ECX]\n            jecxz   return_ST           ;\n            fld     x[EBP]              ; // ST0 = x\n            fxch    ST(1)               ; // ST1 = x, ST0 = r\n            align   4                   ;\n    L2:     fmul    ST,ST(1)            ; // r *= x\n            fld     real ptr -12[EDX]   ;\n            sub     EDX,12              ; // deg--\n            faddp   ST(1),ST            ;\n            dec     ECX                 ;\n            jne     L2                  ;\n            fxch    ST(1)               ; // ST1 = r, ST0 = x\n            fstp    ST(0)               ; // dump x\n            align   4                   ;\n    return_ST:                          ;\n            ;\n        }\n        }\n        else version (OSX)\n        {\n            asm // assembler by W. Bright\n            {\n                // EDX = (A.length - 1) * real.sizeof\n                mov     ECX,A[EBP]              ; // ECX = A.length\n                dec     ECX                     ;\n                lea     EDX,[ECX*8]             ;\n                add     EDX,EDX                 ;\n                add     EDX,A+4[EBP]            ;\n                fld     real ptr [EDX]          ; // ST0 = coeff[ECX]\n                jecxz   return_ST               ;\n                fld     x[EBP]                  ; // ST0 = x\n                fxch    ST(1)                   ; // ST1 = x, ST0 = r\n                align   4                       ;\n        L2:     fmul    ST,ST(1)                ; // r *= x\n                fld     real ptr -16[EDX]       ;\n                sub     EDX,16                  ; // deg--\n                faddp   ST(1),ST                ;\n                dec     ECX                     ;\n                jne     L2                      ;\n                fxch    ST(1)                   ; // ST1 = r, ST0 = x\n                fstp    ST(0)                   ; // dump x\n                align   4                       ;\n        return_ST:                              ;\n                ;\n            }\n        }\n        else version (FreeBSD)\n        {\n        asm     // assembler by W. Bright\n        {\n            // EDX = (A.length - 1) * real.sizeof\n            mov     ECX,A[EBP]          ; // ECX = A.length\n            dec     ECX                 ;\n            lea     EDX,[ECX][ECX*8]    ;\n            add     EDX,ECX             ;\n            add     EDX,ECX             ;\n            add     EDX,ECX             ;\n            add     EDX,A+4[EBP]        ;\n            fld     real ptr [EDX]      ; // ST0 = coeff[ECX]\n            jecxz   return_ST           ;\n            fld     x[EBP]              ; // ST0 = x\n            fxch    ST(1)               ; // ST1 = x, ST0 = r\n            align   4                   ;\n    L2:     fmul    ST,ST(1)            ; // r *= x\n            fld     real ptr -12[EDX]   ;\n            sub     EDX,12              ; // deg--\n            faddp   ST(1),ST            ;\n            dec     ECX                 ;\n            jne     L2                  ;\n            fxch    ST(1)               ; // ST1 = r, ST0 = x\n            fstp    ST(0)               ; // dump x\n            align   4                   ;\n    return_ST:                          ;\n            ;\n        }\n        }\n        else version (Solaris)\n        {\n        asm     // assembler by W. Bright\n        {\n            // EDX = (A.length - 1) * real.sizeof\n            mov     ECX,A[EBP]          ; // ECX = A.length\n            dec     ECX                 ;\n            lea     EDX,[ECX][ECX*8]    ;\n            add     EDX,ECX             ;\n            add     EDX,ECX             ;\n            add     EDX,ECX             ;\n            add     EDX,A+4[EBP]        ;\n            fld     real ptr [EDX]      ; // ST0 = coeff[ECX]\n            jecxz   return_ST           ;\n            fld     x[EBP]              ; // ST0 = x\n            fxch    ST(1)               ; // ST1 = x, ST0 = r\n            align   4                   ;\n    L2:     fmul    ST,ST(1)            ; // r *= x\n            fld     real ptr -12[EDX]   ;\n            sub     EDX,12              ; // deg--\n            faddp   ST(1),ST            ;\n            dec     ECX                 ;\n            jne     L2                  ;\n            fxch    ST(1)               ; // ST1 = r, ST0 = x\n            fstp    ST(0)               ; // dump x\n            align   4                   ;\n    return_ST:                          ;\n            ;\n        }\n        }\n        else\n        {\n        asm     // assembler by W. Bright\n        {\n            // EDX = (A.length - 1) * real.sizeof\n            mov     ECX,A[EBP]          ; // ECX = A.length\n            dec     ECX                 ;\n            lea     EDX,[ECX][ECX*8]    ;\n            add     EDX,ECX             ;\n            add     EDX,A+4[EBP]        ;\n            fld     real ptr [EDX]      ; // ST0 = coeff[ECX]\n            jecxz   return_ST           ;\n            fld     x[EBP]              ; // ST0 = x\n            fxch    ST(1)               ; // ST1 = x, ST0 = r\n            align   4                   ;\n    L2:     fmul    ST,ST(1)            ; // r *= x\n            fld     real ptr -10[EDX]   ;\n            sub     EDX,10              ; // deg--\n            faddp   ST(1),ST            ;\n            dec     ECX                 ;\n            jne     L2                  ;\n            fxch    ST(1)               ; // ST1 = r, ST0 = x\n            fstp    ST(0)               ; // dump x\n            align   4                   ;\n    return_ST:                          ;\n            ;\n        }\n        }\n    }\n    else\n    {\n        printf(\"Sorry, you don't seem to have InlineAsm_X86\\n\");\n        return 0;\n    }\n}\n\nreal poly_c(real x, real[] A)\nin\n{\n    assert(A.length > 0);\n}\nbody\n{\n    ptrdiff_t i = A.length - 1;\n    real r = A[i];\n    while (--i >= 0)\n    {\n        r *= x;\n        r += A[i];\n    }\n    return r;\n}\n\nvoid test47()\n{\n    real x = 3.1;\n    static real[] pp = [56.1, 32.7, 6];\n    real r;\n\n    printf(\"The result should be %Lf\\n\",(56.1L + (32.7L + 6L * x) * x));\n    printf(\"The C version outputs %Lf\\n\", poly_c(x, pp));\n    printf(\"The asm version outputs %Lf\\n\", poly_asm(x, pp));\n    printf(\"The std.math version outputs %Lf\\n\", poly(x, pp));\n\n    r = (56.1L + (32.7L + 6L * x) * x);\n    assert(r == poly_c(x, pp));\n    version (D_InlineAsm_X86)\n        assert(r == poly_asm(x, pp));\n    assert(r == poly(x, pp));\n}\n\n/*************************************/\n\nconst c48 = 1uL-1;\n\nvoid test48()\n{\n    assert(c48 == 0);\n}\n\n/*************************************/\n\ntemplate cat49()\n{\n     static assert(1);  // OK\n     static if (1)\n     {\n        static assert(1); // doesn't work\n        static if (1)\n        {\n             static assert(1);  // OK\n             const int cat49 = 3;\n        }\n     }\n}\n\nvoid test49()\n{\n    const int a = cat49!();\n    assert(a == 3);\n}\n\n/*************************************/\n\nvoid test50()\n{\n    if (auto x = 1)\n    {\n        assert(typeid(typeof(x)) == typeid(int));\n        assert(x == 1);\n    }\n    else\n        assert(0);\n\n    if (int x = 1)\n    {\n        assert(typeid(typeof(x)) == typeid(int));\n        assert(x == 1);\n    }\n    else\n        assert(0);\n\n    if (1)\n    {\n    }\n    else\n        assert(0);\n}\n\n/*************************************/\n\nvoid test51()\n{\n    bool b;\n    assert(b == false);\n    b &= 1;\n    assert(b == false);\n    b |= 1;\n    assert(b == true);\n    b ^= 1;\n    assert(b == false);\n    b = b | true;\n    assert(b == true);\n    b = b & false;\n    assert(b == false);\n    b = b ^ true;\n    assert(b == true);\n    b = !b;\n    assert(b == false);\n}\n\n/*************************************/\n\nalias int function (int) x52;\n\ntemplate T52(string str){\n        const int T52 = 1;\n}\n\nstatic assert(T52!(x52.mangleof));\n\nvoid test52()\n{\n}\n\n/*************************************/\nimport std.stdio;\nimport core.stdc.stdarg;\n\nvoid myfunc(int a1, ...) {\n        va_list argument_list;\n        TypeInfo argument_type;\n        string sa; int ia; double da;\n        writefln(\"%d variable arguments\", _arguments.length);\n        writefln(\"argument types %s\", _arguments);\n        va_start(argument_list, a1);\n        for (int i = 0; i < _arguments.length; ) {\n                if ((argument_type=_arguments[i++]) == typeid(string)) {\n                        va_arg(argument_list, sa);\n                        writefln(\"%d) string arg = '%s', length %d\", i+1, sa.length<=20? sa : \"?\", sa.length);\n                } else if (argument_type == typeid(int)) {\n                        va_arg(argument_list, ia);\n                        writefln(\"%d) int arg = %d\", i+1, ia);\n                } else if (argument_type == typeid(double)) {\n                        va_arg(argument_list, da);\n                        writefln(\"%d) double arg = %f\", i+1, da);\n                } else {\n                        throw new Exception(\"invalid argument type\");\n                }\n        }\n        va_end(argument_list);\n}\n\nvoid test6758() {\n        myfunc(1, 2, 3, 4, 5, 6, 7, 8, \"9\", \"10\");                              // Fails.\n        myfunc(1, 2.0, 3, 4, 5, 6, 7, 8, \"9\", \"10\");                    // Works OK.\n        myfunc(1, 2, 3, 4, 5, 6, 7, \"8\", \"9\", \"10\");                    // Works OK.\n        myfunc(1, \"2\", 3, 4, 5, 6, 7, 8, \"9\", \"10\");                    // Works OK.\n}\n\n\n/*************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    bug5809();\n    bug7546();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test6758();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test23.d",
    "content": "// REQUIRED_ARGS:\n\nmodule test;\n\nimport core.vararg;\nimport core.stdc.stdlib;\nimport std.stdio;\nimport std.string;\nimport core.stdc.stdlib;\n\n\n/*******************************************/\n\nstruct S\n{\n    int opSliceAssign(int v, size_t i, size_t j)\n    {\n        assert(v == 5);\n        assert(i == 9);\n        assert(j == 10);\n        return 3;\n    }\n\n    int opSliceAssign(int v)\n    {\n        assert(v == 6);\n        return 11;\n    }\n}\n\nvoid test1()\n{\n    S s;\n\n    assert((s[9 .. 10] = 5) == 3);\n    assert((s[] = 6) == 11);\n}\n\n/*******************************************/\n\nstatic int i2 = 1;\n\nvoid test2()\n{\n    synchronized { int i2 = 2; }\n    assert(i2 == 1);\n}\n\n/*******************************************/\n\nvoid test3()\n{\n    size_t border = 8;\n\n    for(ulong i = 0; i < border; i++)\n    {\n        ulong test = 1;\n        test <<= i;\n        double r = test;\n        ulong result = cast(ulong)r;\n\n        if (result != test)\n        {\n            assert(0);\n        }\n    }\n}\n\n/*******************************************/\n\nvoid test4()\n{\n    writeln(\"\",true);\n}\n\n/*******************************************/\n\nvoid test5()\n{\n    int[] qwert = new int[6];\n    int[] yuiop;\n    yuiop = qwert[2..5] = 3;\n    assert(yuiop.length == 3);\n    assert(yuiop[0] == 3);\n    assert(yuiop[1] == 3);\n    assert(yuiop[2] == 3);\n}\n\n/*******************************************/\n\nstruct Foo6\n{\n    static int x;\n\n    static int[] farray()\n    {\n        printf(\"farray\\n\");\n        assert(x == 0);\n        x++;\n        return new int[6];\n    }\n\n    static int flwr()\n    {\n        printf(\"flwr\\n\");\n        assert(x == 1);\n        x++;\n        return 2;\n    }\n\n    static int fupr()\n    {\n        printf(\"fupr\\n\");\n        assert(x == 2);\n        x++;\n        return 1;\n    }\n}\n\nvoid test6()\n{\n    int[] yuiop;\n    yuiop =\n        Foo6.farray()[Foo6.flwr() .. $ - Foo6.fupr()] = 3;\n    assert(Foo6.x == 3);\n    assert(yuiop.length == 3);\n    assert(yuiop[0] == 3);\n    assert(yuiop[1] == 3);\n    assert(yuiop[2] == 3);\n}\n\n/*******************************************/\n\nvoid test7()\n{\n    real a = 3.40483; // this is treated as 3.40483L\n    real b;\n    b = 3.40483;\n    assert(a==b);\n    assert(a==3.40483);\n    assert(a==3.40483L);\n    assert(a==3.40483F);\n}\n\n/*******************************************/\n\nvoid test8()\n{\n   real [5][5] m = 1;\n   m[1][1..3] = 2;\n\n   for (size_t i = 0; i < 5; i++)\n        for (size_t j = 0; j < 5; j++)\n        {\n            if (i == 1 && (j >= 1 && j < 3))\n                assert(m[i][j] == 2);\n            else\n                assert(m[i][j] == 1);\n        }\n}\n\n/*******************************************/\n\nclass ClassOf(Type)\n{\n    Type val;\n\n    template refx()\n    {\n        alias val refx;\n    }\n}\n\nstruct StructOf\n{\n    int val;\n\n    template refx()\n    {\n        alias val refx;\n    }\n}\n\nvoid test9()\n{\n    ClassOf!(int)  c = new ClassOf!(int)();\n    StructOf s;\n    int x = 10;\n\n    c.refx!() = x;\n    x = c.refx!();\n    assert(x == 10);\n\n    x = 11;\n    s.refx!() = x;\n    x = s.refx!();\n    assert(x == 11);\n}\n\n\n/*******************************************/\n\nvoid test10()\n{\n    static if( int.mangleof.length > 1 && int.mangleof[1] == 'x' )\n        printf(\"'x' as second char\\n\");\n}\n\n/*******************************************/\n\nclass Foo11 : Bar11 { }\n\nclass Foo11T(V)\n{\n    public void foo() {}\n}\n\nclass Bar11\n{\n    public this(){\n        f = new Foo11T!(int);\n    }\n    Foo11T!(int) f;\n}\n\nvoid test11()\n{\n    Foo11 fooIt = new Foo11();\n    if (fooIt !is null)\n        writefln(\"fooIt should be valid\");\n    fooIt.f.foo();\n    writefln(\"it worked\");\n}\n\n/*******************************************/\n\nstruct A12 {\n        int a;\n        union {\n                int c;\n                B12 b;\n        }\n}\n\nstruct B12 {\n        int b1;\n        int b2;\n}\n\nvoid test12()\n{\n        A12 a;\n        printf(\"%d\\n\", A12.sizeof);\n        assert(A12.sizeof == 12);\n}\n\n/*******************************************/\n\ntemplate declare13(X) { X declare13; }\n\ntypeof(declare13!(int[0]).ptr[0]) x13;\ntypeof(declare13!(typeof(\"\"))[0..$]) y13;\n\nvoid test13()\n{\n}\n\n/*******************************************/\n\ninterface Father {}\n\nclass Mother {\n     Father test() {\n         writefln(\"Called Mother.test!\");\n         return new Child(42);\n     }\n}\n\nclass Child : Mother, Father {\n     int data;\n\n     this(int d) { data = d; }\n\n     override Child test() {\n         writefln(\"Called Child.test!\");\n         return new Child(69);\n     }\n}\n\nvoid test14()\n{\n     Child aChild = new Child(105);\n     Mother childsMum = aChild;\n     Child childsChild = aChild.test();\n     Child mumsChild = cast(Child) childsMum.test();\n     writefln(\"Success2\");\n}\n\n\n/*******************************************/\n\nclass A15\n{\n        int a = 3;\n\n        class B\n        {\n            void bar()\n            {\n                assert(a == 3);\n            }\n        }\n\n        void fork()\n        {\n                assert(a == 3);\n                B b = new B();  // This is okay\n                b.bar();\n\n                void knife()\n                {\n                        assert(a == 3);\n                        B b = new B();  // No 'this' for nested class B\n                        b.bar();\n                }\n        }\n}\n\nvoid test15()\n{\n    A15 a = new A15();\n    a.fork();\n}\n\n/*******************************************/\n\ncreal x16;\n\nvoid foo16()\n{\n        x16 = -x16;\n}\n\nvoid bar16()\n{\n        return foo16();\n}\n\nvoid test16()\n{\n        x16 = 2.0L + 0.0Li;\n        bar16();\n        assert(x16 == -2.0L + 0.0Li);\n}\n\n/*******************************************/\n\nvoid test17()\n{\n    version (OSX)\n    {\n    }\n    else\n    {\n        /*const*/ float f = 1.2f;\n        float g = void;\n\n\n        version(D_SoftFloat)\n        {\n            g = f;\n        }\n        else version(GNU)\n        {\n            version(X86) asm\n            {\n                \"flds %1; fstps %0;\" : \"=m\" (g) : \"m\" (f) : ;\n            }\n            else version(X86_64) asm\n            {\n                \"flds %1; fstps %0;\" : \"=m\" (g) : \"m\" (f) : ;\n            }\n            else version(ARM) asm\n            {\n                \"vldr d0, %1; vstr d0, %0;\" : \"=m\" (g) : \"m\" (f), : \"d0\";\n            }\n            else static assert(false, \"ASM code not implemented for this architecture\");\n        }\n        else\n        {\n            asm\n            {\n                fld f;  // doesn't work with PIC\n                fstp g;\n            }\n        }\n        assert(g == 1.2f);\n    }\n}\n\n/*******************************************/\n\nclass Foo18 : Bar18 {}\nclass FooT18(V){}\nclass Bar18 : FooT18!(int) {}\n\nvoid test18()\n{\n}\n\n/*******************************************/\n\nstruct STRUCTA19\n{\n  union {\n    int a;\n    long b;\n  }\n  STRUCTB19 c;\n}\n\nstruct STRUCTB19\n{\n  int a;\n}\n\nvoid test19()\n{\n}\n\n/*******************************************/\n\nclass Foo20\n{\n        void bar (void * src)\n        {\n                void baz (void function (void *, size_t) xyz)\n                {\n                        size_t foo (void [] dst)\n                        {\n                                size_t len = dst.length;\n                                dst [0 .. len] = src [0 .. len];\n                                xyz (dst.ptr, len);\n                                return len;\n                        }\n                }\n        }\n}\n\nvoid test20()\n{\n}\n\n/*******************************************/\n\nclass Baz21\n{\n        int opApply (int delegate(ref int) dg)\n        {\n                int i;\n                return dg(i);\n        }\n}\n\nclass Foo21\n{\n        Baz21    baz;\n\n        int foo (int delegate() dg)\n        {\n                foreach (b; baz)\n                         if (bar ())\n                            if (dg ())\n                                break;\n                return 0;\n        }\n\n        bool bar ()\n        { return true; }\n}\n\nvoid test21()\n{\n}\n\n/*******************************************/\n\nstruct Bar22 {\n    union {\n        struct {\n            union {\n                Foo22 A;\n            }\n        }\n    }\n}\n\nstruct Foo22 {\n    double d = 3;\n}\n\nvoid test22()\n{\n    printf(\"Bar22.sizeof = %zd, double.sizeof = %zd\\n\", Bar22.sizeof, double.sizeof);\n    assert(Bar22.sizeof == double.sizeof);\n    Bar22 b;\n    assert(b.A.d == 3);\n}\n\n/*******************************************/\n\nstruct Ag\n{\n    static void func(){}\n\n    static void foo()\n    {\n        void function() fnp;\n        Ag a;\n\n        fnp = &func;\n        fnp = &Ag.func;\n        with(a)    fnp = &Ag.func;\n\n        with(a) fnp = &func;\n    }\n}\n\nclass Ah\n{\n    static void func(){}\n\n    static void foo()\n    {\n        void function() fnp;\n        Ah a;\n\n        fnp = &func;\n        fnp = &Ah.func;\n        with(a)    fnp = &Ah.func;\n\n        with(a) fnp = &func;\n    }\n}\n\nvoid test23()\n{\n}\n\n/*******************************************/\n\nvoid test24()\n{\n    uint[10] arr1;\n    ulong idx = 3;\n    uint[] arr3 = arr1[ cast(int)(idx) .. (cast(int) idx) + 3  ]; // OK\n    uint[] arr4 = arr1[ cast(int) idx  ..  cast(int) idx  + 3  ]; // OK\n    uint[] arr5 = arr1[ cast(int)(idx) ..  cast(int)(idx) + 3  ]; // C style cast illegal, use cast(idx)+3\n    uint[] arr6 = arr1[ cast(int)(idx) ..  cast(int)(idx  + 3) ]; // OK\n}\n\n/*******************************************/\n\nvoid test25()\n{\n  char[6] cstr = \"123456\"c;\n  auto str1 = cast(wchar[3])(cstr);\n\n  writefln(\"str1: \", (cast(char[])str1).length , \" : \", (cast(char[])str1));\n  assert(cast(char[])str1 == \"123456\"c);\n\n  auto str2 = cast(wchar[3])(\"789abc\"c);\n  writefln(\"str2: \", (cast(char[])str2).length , \" : \", (cast(char[])str2));\n  assert(cast(char[])str2 == \"789abc\"c);\n\n  auto str3 = cast(wchar[3])(\"defghi\");\n  writefln(\"str3: \", (cast(char[])str3).length , \" : \", (cast(char[])str3));\n  assert(cast(char[])str3 == \"d\\000e\\000f\\000\"c);\n}\n\n/*******************************************/\n\nvoid test26()\n{\n    assert(foo26(5) == 25);\n}\n\nint foo26(int i)\n{\n    if (auto j = i * i)\n      return j;\n    else\n      return 10;\n}\n\n/*******************************************/\n\nclass A27\n{\n    int am;\n\n    class B\n    {\n        this()\n        {\n            assert(am == 3);\n        }\n    }\n\n    void fork()\n    {\n        B b = new B();  // This is okay\n\n        void knife()\n        {\n                B b = new B();  // No 'this' for nested class B\n                assert(am == 3);\n        }\n    }\n}\n\n\nvoid test27()\n{\n    A27 a = new A27();\n    a.am = 3;\n\n    a.fork();\n}\n\n/*******************************************/\n\nuint intRes()\n{\n        return 4;\n}\n\nvoid test28()\n{\n        auto s = std.string.format(\"%s\", \"abc123\"[intRes() % $] );\n        writefln( \"%s\", s );\n        assert(s == \"2\");\n\n        static const char[] foo = \"abc123\";\n        s = std.string.format(\"%s\", foo[intRes() % $] );\n        assert(s == \"2\");\n\n\n        static string bar = \"abc123\";\n        s = std.string.format(\"%s\", bar[intRes() % $] );\n        assert(s == \"2\");\n\n        const char[] abc = \"abc123\";\n        s = std.string.format(\"%s\", abc[intRes() % $] );\n        assert(s == \"2\");\n\n        string def = \"abc123\";\n        s = std.string.format(\"%s\", def[intRes() % $] );\n        assert(s == \"2\");\n}\n\n/*******************************************/\n\nclass UA {\n    A29 f() { return null; }\n}\n\nclass UB : UA {\n    override B29 f() { return null; }\n}\n\nclass A29\n{\n}\n\nclass B29 : A29\n{\n}\n\nvoid test29()\n{\n}\n\n/*******************************************/\n\nclass Foo30 : Bar30 {}\n\nclass FooT30(V) {}\n\nclass Bar30 : FooT30!(int) {}\n\nvoid test30()\n{\n}\n\n\n/*******************************************/\n\nint y31;\n\nstruct X31 { static void opCall() { y31 = 3; } }\n\nvoid test31()\n{\n    X31 x;\n    typeof(x)();\n    assert(y31 == 3);\n}\n\n/*******************************************/\n\nclass Foo32\n{\n    static void* ps;\n\n    new (size_t sz)\n    {\n        void* p = core.stdc.stdlib.malloc(sz);\n        printf(\"new(sz = %d) = %p\\n\", sz, p);\n        ps = p;\n        return p;\n    }\n\n    delete(void* p)\n    {\n        printf(\"delete(p = %p)\\n\", p);\n        assert(p == ps);\n        if (p) core.stdc.stdlib.free(p);\n    }\n}\n\nvoid test32()\n{\n    Foo32 f = new Foo32;\n    delete f;\n}\n\n/*******************************************/\n\nclass Foo33\n{\n//    this() { printf(\"this()\\n\"); }\n//    ~this() { printf(\"~this()\\n\"); }\n\n    static void* ps;\n    static int del;\n\n    new (size_t sz, int i)\n    {\n        void* p = core.stdc.stdlib.malloc(sz);\n        printf(\"new(sz = %d) = %p\\n\", sz, p);\n        ps = p;\n        return p;\n    }\n\n    delete(void* p)\n    {\n        printf(\"delete(p = %p)\\n\", p);\n        assert(p == ps);\n        if (p) core.stdc.stdlib.free(p);\n        del += 1;\n    }\n}\n\nvoid foo33()\n{\n    scope Foo33 f = new(3) Foo33;\n}\n\nvoid test33()\n{\n    foo33();\n    assert(Foo33.del == 1);\n}\n\n/*******************************************/\n\nstruct o_O { int a; }\nunion  O_O { int a; }\nclass  O_o { int a; }\n\nstruct Foo34\n{\n    int ok;\n    o_O foo;\n    O_O bar;\n    O_o baz;\n}\n\nvoid test34()\n{\n    int o1 = Foo34.ok.offsetof;\n    assert(o1 == 0);\n    int o2 = Foo34.foo.offsetof;\n    assert(o2 == 4);\n    int o3 = Foo34.bar.offsetof;\n    assert(o3 == 8);\n    int o4 = Foo34.baz.offsetof;\n    assert((o4 % (void*).sizeof) == 0);\n    assert(o4 > o3);\n}\n\n/*******************************************/\n\nclass Foo37\n{\n    float[4] array = 1.0;\n    int count = 10;\n}\n\nvoid test37()\n{\n    Foo37 f = new Foo37();\n\n    writefln(\"Foo.array[0] = %s\", f.array[0] );\n    writefln(\"Foo.array[1] = %s\", f.array[1] );\n    writefln(\"Foo.array[2] = %s\", f.array[2] );\n    writefln(\"Foo.array[3] = %s\", f.array[3] );\n    writefln(\"Foo.count = %s\", f.count );\n\n    assert(f.array[0] == 1.0);\n    assert(f.array[1] == 1.0);\n    assert(f.array[2] == 1.0);\n    assert(f.array[3] == 1.0);\n    assert(f.count == 10);\n}\n\n/*******************************************/\n\nvoid test38()\nin\n{\n    static void checkParameters()\n    {\n        return;\n    }\n\n    checkParameters();\n}\nbody\n{\n}\n\n/*******************************************/\n\nvoid delegate() foo39()\n{\n        return &(new class\n        {\n\n                int a;\n\n                this() { a = 3; }\n\n                void dg()\n                {\n                        writefln(\"delegate!\");\n                        assert(a == 3);\n                }\n        }).dg;\n}\n\nvoid test39()\n{\n    void delegate() dg = foo39();\n\n    dg();\n}\n\n/*******************************************/\n\nvoid test40()\n{\n    assert( typeid(int) == typeid(int) );\n    assert( (typeid(int) != typeid(int)) == false );\n\n    int x;\n\n    bool b1 = (typeid(typeof(x)) != typeid(int));\n\n    TypeInfo t1 = typeid(typeof(x));\n    TypeInfo t2 = typeid(int);\n\n    bool b2 = (t1 != t2);\n\n    assert(b1 == b2);\n}\n\n/*******************************************/\n\nint foo41(string s)\n{\n        short shift = cast(short)(s.length * 3);\n        int answer;\n\n        for (size_t i = 0; i < s.length; i++){\n                answer = s[i] << shift;\n        }\n\n        return answer;\n}\n\nvoid test41()\n{\n        if(foo41(\"\\u0001\") != 8){\n                assert(0);\n        }\n}\n\n/*******************************************/\n\nstruct S42\n{\n        int i;\n\n        static S42 foo(int x){\n                S42 s;\n\n                s.i = x;\n\n                return s;\n        }\n}\n\nvoid test42()\n{\n        S42[] s;\n\n        s = s ~ S42.foo(6);\n        s = s ~ S42.foo(1);\n\n        if(s.length != 2){\n                assert(0);\n        }\n        if(s[0].i != 6){\n                assert(0);\n        }\n        if(s[1].i != 1){\n                assert(0);\n        }\n}\n\n/*******************************************/\n\nstruct S43\n{\n        int i,j;\n\n        static S43 foo(int x){\n                S43 s;\n\n                s.i = x;\n\n                return s;\n        }\n}\n\nvoid test43()\n{\n        S43[] s;\n\n        s = s ~ S43.foo(6);\n        s = s ~ S43.foo(1);\n\n        if(s.length != 2){\n                assert(0);\n        }\n        if(s[0].i != 6){\n                assert(0);\n        }\n        if(s[1].i != 1){\n                assert(0);\n        }\n}\n\n/*******************************************/\n\nstruct S44\n{\n        int i,j,k;\n\n        static S44 foo(int x){\n                S44 s;\n\n                s.i = x;\n\n                return s;\n        }\n}\n\nvoid test44()\n{\n        S44[] s;\n\n        s = s ~ S44.foo(6);\n        s = s ~ S44.foo(1);\n\n        if(s.length != 2){\n                assert(0);\n        }\n        if(s[0].i != 6){\n                assert(0);\n        }\n        if(s[1].i != 1){\n                assert(0);\n        }\n}\n\n/*******************************************/\n\nvoid test45()\n{\n   char[] buffer = \"abcdefghijklmnopqrstuvwxyz\".dup;\n   foreach(ref char c; buffer)\n   {\n       if('a' <= c && c <= 'z')\n       {\n           c -= cast(char)'a' - 'A'; // segfault here\n       }\n   }\n   for(int i = 0; i < buffer.length; i++)\n   {\n       if('a' <= buffer[i] && buffer[i] <= 'z')\n       {\n           buffer[i] -= cast(char)'a' - 'A'; // segfault here\n       }\n   }\n   writeln(buffer);\n}\n\n/*******************************************/\n\nstruct st46\n{\n    template t1()\n    {\n        template t2(int n2) { }\n    }\n}\n\nalias st46.t1!().t2 a46;\n\nvoid test46()\n{\n}\n\n/*******************************************/\n\nstruct A47\n{\n    static int y;\n    void opSliceAssign(int x)\n    {\n        printf(\"x = %d\\n\", x);\n        y = x;\n    }\n    A47 d() { return this; }\n}\n\nvoid test47()\n{\n    A47 a;\n    a[] = 3;\n    printf(\"y = %d\\n\", a.y);\n    a.d()[] = 5;\n    printf(\"y = %d\\n\", a.y);\n    assert(a.y == 5);\n    a.d[] = 6;\n    printf(\"y = %d\\n\", a.y);\n    assert(a.y == 6);\n}\n\n/*******************************************/\n\nstatic uint[] sarray48 = void;\n\nvoid test48()\n{\n    static uint[] array = void;\n\n    assert(sarray48 == null);\n    assert(array == null);\n}\n\n/*******************************************/\n\nint x = 2, y = 1;\n\nvoid foo50(int z)\n{\n    static int t;\n    t++;\n    assert(t == z);\n}\n\nvoid test50()\n{\n    printf(\"test50()\\n\");\n    int res = 0;\n    for(int i = 0; i < 10; i++)\n    {\n        res = res + x - y;\n        foo50(res);\n    }\n}\n\n/*******************************************/\n\nvoid test52()\n{\n    printf(\"test52()\\n\");\n    char[] s;\n    s = ['a', 'b', 'c'];\n    assert(s == \"abc\");\n\n    int[] x;\n    x = [17, 18u, 29, 33];\n    assert(x.length == 4);\n    assert(x[0] == 17);\n    assert(x[1] == 18);\n    assert(x[2] == 29);\n    assert(x[3] == 33);\n    assert(x == [17, 18, 29, 33]);\n}\n\n/*******************************************/\n\nvoid test54()\n{\n    printf(\"test54()\\n\");\n    uint[500][] data;\n\n    data.length = 1;\n    assert(data.length == 1);\n    foreach (ref foo; data)\n    {\n        assert(foo.length == 500);\n        foreach (ref u; foo)\n        {   //printf(\"u = %u\\n\", u);\n            assert(u == 0);\n            u = 23;\n        }\n    }\n    foreach (ref foo; data)\n    {\n        assert(foo.length == 500);\n        foreach (u; foo)\n        {   assert(u == 23);\n            auto v = u;\n            v = 23;\n        }\n    }\n}\n\n/*******************************************/\n\nclass Base56\n{\n        private string myfoo;\n        private string mybar;\n\n        // Get/set properties that will be overridden.\n        void foo(string s) { myfoo = s; }\n        string foo() { return myfoo; }\n\n        // Get/set properties that will not be overridden.\n        void bar(string s) { mybar = s; }\n        string bar() { return mybar; }\n}\n\nclass Derived56: Base56\n{\n        alias Base56.foo foo; // Bring in Base56's foo getter.\n        override void foo(string s) { super.foo = s; } // Override foo setter.\n}\n\nvoid test56()\n{\n        Derived56 d = new Derived56;\n        with (d)\n        {\n                foo = \"hi\";\n                d.foo = \"hi\";\n                bar = \"hi\";\n                assert(foo == \"hi\");\n                assert(d.foo == \"hi\");\n                assert(bar == \"hi\");\n        }\n}\n\n/*******************************************/\n\nbool[void[]] reg57;\n\nvoid addToReg57(const(void)[] a, int b, bool v)\n{\n    if (!v)\n        writefln(\"X\");\n    auto key = a~(cast(void*)&b)[0..4];\n    reg57[cast(immutable(void)[])key] = v;\n    writefln(\"OK\");\n}\n\nvoid test57()\n{\n        addToReg57(\"test\", 1024, true);\n}\n\n/*******************************************/\n\nint bar58( string msg ){\n    return 1;\n}\n\nint foo58( lazy string dg ){\n    return bar58( dg() );\n}\n\nvoid test58()\n{\n    printf(\"test58()\\n\");\n    try{\n    }\n    finally{\n        foo58(\"\");\n    }\n}\n\n/*******************************************/\n\nstruct S59\n{\n    string toString()\n    {\n        return \"foo\";\n    }\n}\n\nvoid test59()\n{   S59 s;\n    writefln(\"s = %s\", s);\n\n    string p;\n    p = std.string.format(\"s = %s\", s);\n    assert(p == \"s = foo\");\n}\n\n/*******************************************/\n\nvoid test60()\n{\n    int[2][] a;\n    a = [ [-1,2], [3,4] ];\n    assert(a[0][0] == -1);\n    assert(a[0][1] == 2);\n    assert(a[1][0] == 3);\n    assert(a[1][1] == 4);\n\n    int[][] b;\n    b = [ [-1,2], [3,4] ];\n    assert(b[0][0] == -1);\n    assert(b[0][1] == 2);\n    assert(b[1][0] == 3);\n    assert(b[1][1] == 4);\n}\n\n/*******************************************/\n\nvoid test61()\n{\n    int[][] f = [[1,2],[3,4]];\n    assert(f[0][0] == 1);\n    assert(f[0][1] == 2);\n    assert(f[1][0] == 3);\n    assert(f[1][1] == 4);\n    writeln(f);\n}\n\n/*******************************************/\n\nstruct List62 {\n        void get() {}\n}\nstruct Array62 {\n        interface Model {\n                List62 list();\n        }\n        List62 list() {\n                return model ? model.list() : List62.init;\n        }\n        void item() {\n                list.get();\n        }\n        private Model model;\n}\n\nvoid test62()\n{\n}\n\n/*******************************************/\n\nvoid foo63(...)\n{\n}\n\nvoid test63()\n{\n        int[] arr;\n        arr = [1] ~ 2;\n\n        // runtime crash, the length == 1\n        printf(\"%d\\n\", arr.length);\n        assert (arr.length == 2);\n        assert(arr[0] == 1);\n        assert(arr[1] == 2);\n\n        arr = 2 ~ [1];\n        assert(arr.length == 2);\n        assert(arr[0] == 2);\n        assert(arr[1] == 1);\n\n        arr = [2, 3] ~ [1];\n        assert(arr.length == 3);\n        assert(arr[0] == 2);\n        assert(arr[1] == 3);\n        assert(arr[2] == 1);\n\n        foo63([1] ~ 2, 2 ~ [1], [1,2] ~ [3,4,5]);\n}\n\n/*******************************************/\n\nvoid test64()\n{\n    printf(\"test64()\\n\");\n    int[] x = [1,2,3,4];\n    int j = 4;\n\n    foreach_reverse(v; x)\n    {\n        writeln(v);\n        assert(j == v);\n        j--;\n    }\n    assert(j == 0);\n\n    j = 4;\n    foreach_reverse(i, v; x)\n    {\n        writefln(\"[%s] = %s\", i, v);\n        assert(i + 1 == j);\n        assert(j == v);\n        j--;\n    }\n    assert(j == 0);\n    printf(\"-test64()\\n\");\n}\n\n/*******************************************/\n\nvoid test65()\n{\n    // Bugzilla Issue 407.\n    int i = *cast(int*)cast(char[4])['0', '0', '0', '0']; // compiler seg-fault\n    printf(\"i = %x\\n\", i);\n}\n\n/*******************************************/\n\nvoid test66()\n{\n    int[]  ia;\n    ia ~= 3;\n    byte[] data = new byte[ia[0]];\n    byte[] data2 = new byte[ cast(int)(ia[0])];\n}\n\n/*******************************************/\n\nclass C68\n{\n    static int value;\n}\n\nvoid test68()\n{\n    auto v1 = test.C68.value;\n    auto v2 = C68.classinfo;\n    auto v3 = test.C68.classinfo;\n    assert(v2 == v3);\n}\n\n/*******************************************/\n\nvoid test69()\n{\n    class Bug\n    {\n      char[12] str = \"\";\n      uint t = 1;\n    }\n\n    class NoBug\n    {\n      uint t = 2;\n      char[12] str = \"\";\n    }\n\n    class NoBug2\n    {\n      char[12] str;\n      uint t = 3;\n    }\n\n    auto b = new Bug;\n    auto n = new NoBug;\n    auto n2 = new NoBug2;\n\n    writefln(\"bug %d\", b.t);\n    assert(b.t == 1);\n    writefln(\"nobug %d\", n.t);\n    assert(n.t == 2);\n    writefln(\"nobug2 %d\", n2.t);\n    assert(n2.t == 3);\n}\n\n/*******************************************/\n\nvoid test70()\n{\n    void foo(char[0] p)\n    {\n    }\n\n    static const char[0] altsep;\n    string s = std.string.format(\"test%spath\", altsep);\n    assert(s == \"testpath\");\n    foo(altsep);\n}\n\n/*******************************************/\n\n\nclass C71\n{\n    static int cnt;\n    this() { printf(\"C()\\n\"); cnt++; }\n    ~this() { printf(\"~C()\\n\"); cnt--; }\n}\n\nclass D71\n{\n    static int cnt;\n    this() { printf(\"D()\\n\"); cnt++; }\n    ~this() { printf(\"~D()\\n\"); cnt--; }\n}\n\nclass E71\n{\n    static int cnt;\n    this() { printf(\"E()\\n\"); cnt++; }\n    ~this() { printf(\"~E()\\n\"); cnt--; }\n}\n\nvoid test71()\n{\n  {\n    int i = 0;\n    printf(\"start\\n\");\n    scope D71 d = new D71();\n    assert(D71.cnt == 1);\n    for (scope E71 e = new E71(); i < 5; i++)\n    {\n        assert(D71.cnt == 1);\n        assert(E71.cnt == 1);\n        scope c = new C71();\n        assert(C71.cnt == 1);\n    }\n    assert(C71.cnt == 0);\n    assert(E71.cnt == 0);\n    assert(D71.cnt == 1);\n    printf(\"finish\\n\");\n  }\n  assert(D71.cnt == 0);\n}\n\n/*******************************************/\n\nsize_t getLength(int[] arr) { return arr.length; }\n\nvoid test13237()\n{\n        int[] arr = [0];\n        immutable size_t len = getLength(arr);\n\n        arr.length--;\n\n        assert(len == 1); // ok\n        if (len) { auto l = len; }\n        assert(len == 1); // len cannot be changed, but produces Assertion failure with \"-O -inline\"\n}\n\n/*******************************************/\n\nvoid main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test50();\n    test52();\n    test54();\n    test56();\n    test57();\n    test58();\n    test59();\n    test60();\n    test61();\n    test62();\n    test63();\n    test64();\n    test65();\n    test66();\n    test68();\n    test69();\n    test70();\n    test71();\n    test13237();\n\n    printf(\"Success\\n\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test24.d",
    "content": "// EXTRA_SOURCES: imports/test24a.d imports/test24b.d\n// PERMUTE_ARGS:\n// REQUIRED_ARGS:\n\nimport imports.test24a, imports.test24b;\n\nvoid main()\n{\n    string hi = std.string.format(\"%s\", 3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test27.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/test27a.d\n// PERMUTE_ARGS:\n\nimport imports.test27a;\n\nint main()\n{\n    auto v = new myClass!(int)();\n    v.func(5);\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test28.d",
    "content": "module test;\n\nimport core.stdc.stdio;\nimport core.vararg;\nimport std.stdio;\nimport std.string;\n\n\n/*******************************************/\n\nstruct S1\n{\n    void* function(void*) fn;\n}\n\ntemplate M1()\n{\n    S1 s;\n}\n\nvoid test1()\n{\n    S1 s2;\n    mixin M1;\n    assert(s.fn == null);\n}\n\n/*******************************************/\n\nenum Qwert { yuiop }\n\nint asdfg(Qwert hjkl) { return 1; }\nint asdfg(uint zxcvb) { return 2; }\n\nvoid test2()\n{\n    int nm = 2;\n\n    assert(asdfg(nm) == 2);\n    assert(asdfg(cast(int) nm) == 2);\n    assert(asdfg(3) == 2);\n    assert(asdfg(cast(int) 3) == 2);\n    assert(asdfg(3L) == 2);\n    assert(asdfg(cast(int) 3L) == 2);\n    assert(asdfg(3 + 2) == 2);\n    assert(asdfg(cast(int) (3 + 2)) == 2);\n    assert(asdfg(nm + 2) == 2);\n    assert(asdfg(cast(int) (nm + 2)) == 2);\n    assert(asdfg(3 + nm) == 2);\n    assert(asdfg(cast(int) (3 + nm)) == 2);\n\n}\n\n/*******************************************/\n\ntemplate Qwert3(string yuiop) {\n    immutable string Qwert3 = cast(string)yuiop;\n}\n\ntemplate Asdfg3(string yuiop) {\n    immutable string Asdfg3 = cast(string)Qwert3!(cast(string)(cast(string)yuiop ~ cast(string)\"hjkl\"));\n}\n\nvoid test3()\n{\n    string zxcvb = Asdfg3!(null);\n    assert(zxcvb == \"hjkl\");\n    assert(zxcvb == \"hjkl\" ~ null);\n}\n\n/*******************************************/\n\ntemplate Qwert4(string yuiop)\n{\n    immutable string Qwert4 = cast(string)(yuiop ~ \"asdfg\" ~ yuiop);\n}\n\nvoid test4()\n{\n    string hjkl = Qwert4!(null);\n    assert(hjkl == \"asdfg\");\n}\n\n/*******************************************/\n\nvoid test6()\n{\n    struct Foo\n    {\n        void foo() { }\n    }\n\n    alias Foo Bar;\n\n    Bar a;\n    a.foo();\n}\n\n/*******************************************/\n\nvoid test7()\n{\n    struct Foo\n    {\n        alias typeof(this) ThisType;\n        alias typeof(this) ThatType;\n    }\n\n    assert(is(Foo.ThisType == Foo));\n    assert(is(Foo.ThatType == Foo));\n}\n\n/*******************************************/\n\nvoid test8()\n{\n   int[] test;\n   test.length = 10;\n   // Show address of array start and its length (10)\n   writefln(\"%s %s\", cast(uint)test.ptr, test.length);\n\n   test.length = 1;\n   // Show address of array start and its length (1)\n   writefln(\"%s %s\", cast(uint)test.ptr, test.length);\n\n   test.length = 8;\n   // Show address of array start and its length (8)\n   writefln(\"%s %s\", cast(uint)test.ptr, test.length);\n\n   test.length = 0;\n   // Shows 0 and 0!\n   writefln(\"%s %s\", cast(uint)test.ptr, test.length);\n   assert(test.length == 0);\n   assert(test.ptr != null);\n}\n\n/*******************************************/\n\ncdouble y9;\n\ncdouble f9(cdouble x)\n{\n    return (y9 = x);\n}\n\nvoid test9()\n{\n    f9(1.0+2.0i);\n    assert(y9 == 1.0+2.0i);\n}\n\n/*******************************************/\n\nclass CBase10\n{\n    this() { }\n}\n\nvoid foo10( CBase10 l )\n{\n}\n\nvoid test10()\n{\n    if (1)\n    {\n        foo10( new class() CBase10\n               {\n                    this() { super(); }\n               }\n             );\n    }\n    return;\n}\n\n/*******************************************/\n\nstruct Foo11\n{\n    static\n        int func(T)(T a) { assert(a == 1); return 0; }\n}\n\nvoid test11()\n{\n        auto a = Foo11.init.func(1);\n        a = Foo11.init.func!(int)(1);\n        a = Foo11.func(1);\n        a = Foo11.func!(int)(1);\n}\n\n/*******************************************/\n\nvoid test12()\n{\n    class ExceptioN { }\n\n    class ExceptioX { }\n\n    static assert(ExceptioN.mangleof[0 ..$-1] == ExceptioX.mangleof[0 .. $-1]);\n}\n\n/*******************************************/\n\ntemplate check( char ch1, char ch2)\n{\n    const bool check = ch1 == ch2;\n}\n\nvoid test13()\n{\n        const char[] s = \"123+456\" ;\n        assert(check!( '+', s[3] ) == true);\n}\n\n/*******************************************/\n\nvoid test14()\n{\n    static const char[] test=['a','b','c','d'];\n    static assert(test==['a','b','c','d']);\n    static assert(['a','b','c','d']== test);\n}\n\n/*******************************************/\n\nvoid func15(...)\nin {\n    writefln(\"Arguments len = %d\\n\", _arguments.length);\n    assert(_arguments.length == 2);\n}\nbody {\n\n}\n\nvoid test15()\n{\n    func15(1, 2);\n}\n\n/*******************************************/\n\nvoid test17()\n{\n    void delegate() y = { };\n    y();\n}\n\n/*******************************************/\n\nabstract class Pen { int foo(); }\n\nclass Penfold : Pen {\n    override int foo() { return 1; }\n}\n\nclass Pinky : Pen {\n    override int foo() { return 2; }\n}\n\nclass Printer {\n    void vprint(Pen obj) {\n        assert(obj.foo() == 1 || obj.foo() == 2);\n    }\n\n    C print(C)(C obj) {\n        assert(obj.foo() == 1 || obj.foo() == 2);\n        return obj;\n    }\n\n}\n\nvoid test18()\n{\n    Printer p = new Printer;\n    p.print(new Pinky);\n    p.print(new Penfold);\n    with (p)\n    {\n        vprint(new Pinky);\n        vprint(new Penfold);\n\n        print!(Pinky)(new Pinky);\n        print!(Penfold)(new Penfold);\n\n        p.print(new Pinky);\n        p.print(new Penfold);\n\n        print(new Pinky);\n        print(new Penfold);\n    }\n}\n\n/*******************************************/\n\n\nclass A19\n{\n    void s() {}\n}\n\nclass B19 : A19\n{\n    alias A19.s s;\n    static void s(int i) {}\n    override void s() {}\n}\n\nclass C19\n{\n    void f() {\n        B19.s(0);\n    }\n}\n\nvoid test19()\n{\n}\n\n\n/*******************************************/\n\nclass U {}\nclass T : U {}\n\nvoid test20()\n{\n        T*   ptr;\n        T[2] sar;\n        T[]  dar;\n\n        // all of the following should work according to the \"Implicit\n        // Conversions\" section of the spec\n\n        tPtr(ptr);\n        tPtr(sar.ptr);\n        tPtr(dar.ptr);\n        tDar(sar);\n\n//      uPtr(ptr);      // T* => U*\n//      uPtr(sar);      // T[2] => U*\n//      uPtr(dar);      // T[] => U*\n//      uSar(sar);      // T[2] => U[2]\n//      uDar(sar);      // T[2] => U[]\n\n        uDar(dar);      // T[] => const(U)[]\n        vPtr(ptr);      // T* => void*\n        vPtr(sar.ptr);\n        vPtr(dar.ptr);\n\n        vDar(sar);\n        vDar(dar);      // works, but T[] => void[] isn't mentioned in the spec\n}\n\nvoid tPtr(T*t){}\nvoid tDar(T[]t){}\nvoid uPtr(U*u){}\nvoid uSar(U[2]u){}\nvoid uDar(const(U)[]u){}\nvoid vPtr(void*v){}\nvoid vDar(void[]v){}\n\n\n/*******************************************/\n\nstruct Foo21\n{\n    int i;\n}\n\ntemplate some_struct_instance(T)\n{\n    static Foo21 some_struct_instance =\n    {\n        5,\n    };\n}\n\nvoid test21()\n{\n    alias some_struct_instance!(int) inst;\n    assert(inst.i == 5);\n}\n\n/*******************************************/\n\nstruct Foo22(T) {}\n\nvoid test22()\n{\n    int i;\n\n    if ((Foo22!(char)).init == (Foo22!(char)).init)\n        i = 1;\n    assert(i == 1);\n}\n\n\n/*******************************************/\n\nvoid test23()\n{\n    auto t=['a','b','c','d'];\n    writeln(typeid(typeof(t)));\n    assert(is(typeof(t) == char[]));\n\n    const t2=['a','b','c','d','e'];\n    writeln(typeid(typeof(t2)));\n    assert(is(typeof(t2) == const(const(char)[])));\n}\n\n/*******************************************/\n\nint foo24(int i ...)\n{\n    return i;\n}\n\nvoid test24()\n{\n    assert(foo24(3) == 3);\n}\n\n/*******************************************/\n\nvoid test25()\n{\n    ireal x = 4.0Li;\n    ireal y = 4.0Li;\n    ireal z = 4Li;\n    creal c = 4L + 0Li;\n}\n\n/*******************************************/\n\nstruct Foo26\n{\n    int a;\n\n    static Foo26 opCall(int i)\n    {   Foo26 f;\n        f.a += i;\n        return f;\n    }\n}\n\nvoid test26()\n{   Foo26 f;\n\n    f = cast(Foo26)3;\n    assert(f.a == 3);\n\n    Foo26 g = 3;\n    assert(g.a == 3);\n}\n\n/*******************************************/\n\nstruct S27\n{\n    int x;\n\n    void opAssign(int i)\n    {\n        x = i + 1;\n    }\n}\n\nvoid test27()\n{\n    S27 s;\n    s = 1;\n    assert(s.x == 2);\n}\n\n/*******************************************/\n\nclass C28\n{\n    int x;\n\n    void opAssign(int i)\n    {\n        x = i + 1;\n    }\n}\n\nvoid test28()\n{\n// No longer supported for 2.0\n//    C28 s = new C28;\n//    s = 1;\n//    assert(s.x == 2);\n}\n\n/*******************************************/\n\nstruct S29\n{\n    static S29 opCall(int v)\n    {\n        S29 result;\n        result.v = v;\n        return result;\n    }\n    int a;\n    int v;\n    int x,y,z;\n}\n\nint foo29()\n{\n   auto s = S29(5);\n   return s.v;\n}\n\nvoid test29()\n{\n    int i = foo29();\n    printf(\"%d\\n\", i);\n    assert(i == 5);\n}\n\n/*******************************************/\n\nstruct S30\n{\n    static S30 opCall(int v)\n    {\n        S30 result;\n\n        void bar()\n        {\n            result.v += 1;\n        }\n\n        result.v = v;\n        bar();\n        return result;\n    }\n    int a;\n    int v;\n    int x,y,z;\n}\n\nint foo30()\n{\n   auto s = S30(5);\n   return s.v;\n}\n\nvoid test30()\n{\n    int i = foo30();\n    printf(\"%d\\n\", i);\n    assert(i == 6);\n}\n\n/*******************************************/\n\nstruct S31\n{\n    static void abc(S31 *r)\n    {\n        r.v += 1;\n    }\n\n    static S31 opCall(int v)\n    {\n        S31 result;\n\n        void bar()\n        {\n            abc(&result);\n        }\n\n        result.v = v;\n        bar();\n        return result;\n    }\n    int a;\n    int v;\n    int x,y,z;\n}\n\nint foo31()\n{\n   auto s = S31(5);\n   return s.v;\n}\n\nvoid test31()\n{\n    int i = foo31();\n    printf(\"%d\\n\", i);\n    assert(i == 6);\n}\n\n/*******************************************/\n\n\nstruct T32\n{\n    int opApply(int delegate(ref int i) dg)\n    {\n        int i;\n        return dg(i);\n    }\n}\n\nstruct S32\n{\n    static void abc(S32 *r)\n    {\n        r.v += 1;\n    }\n\n    static S32 opCall(int v)\n    {\n        S32 result;\n        T32 t;\n\n        result.v = v;\n        foreach (i; t)\n        {\n            result.v += 1;\n            break;\n        }\n        return result;\n    }\n    int a;\n    int v;\n    int x,y,z;\n}\n\nint foo32()\n{\n   auto s = S32(5);\n   return s.v;\n}\n\nvoid test32()\n{\n    int i = foo32();\n    printf(\"%d\\n\", i);\n    assert(i == 6);\n}\n\n/*******************************************/\n\nclass Confectionary\n{\n    this(int sugar)\n    {\n        //if (sugar < 500)\n        //    tastiness = 200;\n\n        //for (int i = 0; i < 10; ++i)\n        //    tastiness = 300;\n\n        //int[] tastinesses_array;\n\n        //foreach (n; tastinesses_array)\n        //    tastiness = n;\n\n        //int[int] tastinesses_aa;\n\n        //foreach (n; tastinesses_aa)\n        //    tastiness = n;\n\n        tastiness = 1;\n    }\n\n   const int tastiness;\n}\n\nvoid test33()\n{\n}\n\n/*******************************************/\n\ntemplate a34(string name, T...)\n{\n    string a34(string name,T t)\n    {\n        string localchar;\n        foreach (a34; T)\n        {\n            writefln(`hello`);\n            localchar ~= a34.mangleof;\n        }\n        return localchar;\n    }\n}\n\nvoid test34()\n{\n    writeln(a34!(\"Adf\"[], typeof(\"adf\"),uint)(\"Adf\"[],\"adf\",1234));\n}\n\n/*******************************************/\n\ntemplate a35(string name, T...)\n{\n    int a35(M...)(M m)\n    {\n        return 3;\n    }\n}\n\nvoid test35()\n{\n    assert(a35!(\"adf\")() == 3);\n}\n\n/*******************************************/\n\ntemplate a36(AnotherT,string name,T...){\n    AnotherT a36(M...)(M){\n        AnotherT localchar;\n        foreach(a;T)\n        {\n            writefln(`hello`);\n            localchar~=a.mangleof;\n        }\n        return cast(AnotherT)localchar;\n    }\n}\n\nvoid test36()\n{\n    string b=\"adf\";\n    uint i=123;\n    char[3] c=\"Adf\";\n    writeln(a36!(typeof(b),\"Adf\")());\n}\n\n/*******************************************/\n\nstruct Q37 {\n    Y37 opCast() {\n        return Y37.init;\n    }\n}\n\nstruct Y37 {\n    Q37 asdfg() {\n        return Q37.init;\n    }\n\n    void hjkl() {\n        Q37 zxcvb = asdfg();  // line 13\n    }\n}\n\nvoid test37()\n{\n}\n\n/*******************************************/\n\n\n\nclass C38 { }\n\nconst(Object)[] foo38(C38[3] c) @system\n{   const(Object)[] x = c;\n    return x;\n}\n\nvoid test38()\n{\n}\n\n/*******************************************/\n\nvoid test39()\n{\n    void print(string[] strs)\n    {\n        writeln(strs);\n        assert(format(\"%s\", strs) == `[\"Matt\", \"Andrew\"]`);\n    }\n\n    print([\"Matt\", \"Andrew\"]);\n}\n\n/*******************************************/\n\nvoid test40()\n{\n    class C\n    {\n        Object propName()\n        {\n            return this;\n        }\n    }\n\n    auto c = new C;\n\n    with (c.propName)\n    {\n        writeln(toString());\n    }\n\n    auto foo = c.propName;\n}\n\n/*******************************************/\n\nvoid test41()\n{\n    auto test = new char [2];\n\n    int x1, x2, x3;\n    char[] foo1() { x1++; return test; }\n    int foo2() { x2++; return 0; }\n    int foo3() { x3++; return 1; }\n\n    test [] = 'a';\n    test = test [0 .. 1];\n\n    foo1() [foo2() .. foo3()] = 'b';\n    assert(x1 == 1);\n    assert(x2 == 1);\n    assert(x3 == 1);\n\n    //test [0 .. 2] = 'b'; // this line should assert\n    writef (\"%s\\n\", test.ptr [0 .. 2]);\n}\n\n/*******************************************/\n\nvoid test42()\n{\n    struct X { int x; }\n\n    X x;\n    assert(x.x == 0);\n    x = x.init;\n    assert(x.x == 0);\n}\n\n/*******************************************/\n\nstruct A43\n{\n    static const MY_CONST_STRING = \"hello\";\n\n    void foo()\n    {\n        // This will either print garbage or throw a UTF exception.\n        // But if never_called() is commented out, then it will work.\n        writefln(\"%s\", MY_CONST_STRING);\n    }\n}\n\nvoid never_called43()\n{\n    // This can be anything; there just needs to be a reference to\n    // A43.MY_CONST_STRING somewhere.\n    writefln(\"%s\", A43.MY_CONST_STRING);\n}\n\nvoid test43()\n{\n    A43 a;\n    a.foo();\n}\n\n/*******************************************/\n\nclass A44\n{\n    static const MY_CONST_STRING = \"hello\";\n\n    this()\n    {\n        // This will either print garbage or throw a UTF exception.\n        // But if never_called() is commented out, then it will work.\n        writefln(\"%s\", MY_CONST_STRING);\n    }\n}\n\nvoid never_called44()\n{\n    // This can be anything; there just needs to be a reference to\n    // A44.MY_CONST_STRING somewhere.\n    writefln(\"%s\", A44.MY_CONST_STRING);\n}\n\nvoid test44()\n{\n    A44 a = new A44();\n}\n\n/*******************************************/\n\nclass C45\n{\n    void func(lazy size_t x)\n    {\n        (new C45).func(super.toHash());\n    }\n}\n\nvoid test45()\n{\n}\n\n/*******************************************/\n\ntemplate T46(double v)\n{\n    double T46 = v;\n}\n\nvoid test46()\n{\n    double g = T46!(double.nan) + T46!(-double.nan);\n}\n\n/*******************************************/\n\nvoid test47()\n{\n    uint* where = (new uint[](5)).ptr;\n\n    where[0 .. 5] = 1;\n    assert(where[2] == 1);\n    where[0 .. 0] = 0;\n    assert(where[0] == 1);\n    assert(where[2] == 1);\n}\n\n/*******************************************/\n\nvoid test48()\n{\n    Object o = new Object();\n    printf(\"%.*s\\n\", typeof(o).classinfo.name.length, typeof(o).classinfo.name.ptr);\n    printf(\"%.*s\\n\", (typeof(o)).classinfo.name.length, (typeof(o)).classinfo.name.ptr);\n    printf(\"%.*s\\n\", (Object).classinfo.name.length, (Object).classinfo.name.ptr);\n}\n\n/*******************************************/\n\nvoid test49()\n{\n    foo49();\n}\n\nvoid foo49()\n{\n    char[] bar;\n    assert(true, bar ~ \"foo\");\n}\n\n/*******************************************/\n\nvoid test50()\n{\n    foo50(\"foo\");\n}\n\nvoid foo50(string bar)\n{\n    assert(true, bar ~ \"foo\");\n}\n\n/*******************************************/\n\nstruct Foo51\n{\n    static Foo51 opCall()\n    {\n      return Foo51.init;\n    }\n    private char[] _a;\n    private bool _b;\n}\n\nvoid test51()\n{\n}\n\n/*******************************************/\n\ntemplate A52(T ...) { }\nmixin A52!([\"abc2\", \"def\"]);\n\nvoid test52()\n{\n}\n\n/*******************************************/\n\nenum: int\n{\n        AF_INET53 =       2,\n        PF_INET53 =       AF_INET53,\n}\n\nenum: int\n{\n        SOCK_STREAM53 =     1,\n}\n\nstruct sockaddr_in53\n{\n        int sin_family = AF_INET53;\n}\n\nenum AddressFamily53: int\n{\n        INET =       AF_INET53,\n}\n\nenum SocketType53: int\n{\n        STREAM =     SOCK_STREAM53,\n}\n\n\nclass Socket53\n{\n        this(AddressFamily53 af, SocketType53 type)\n        {\n        }\n}\n\nvoid test53()\n{\n    new Socket53(AddressFamily53.INET, SocketType53.STREAM);\n}\n\n/*******************************************/\n\nvoid test54()\n{\n    int[2][] a;\n    a ~= [1,2];\n    assert(a.length == 1);\n    assert(a[0][0] == 1);\n    assert(a[0][1] == 2);\n}\n\n/*******************************************/\n\nvoid test55()\n{\n        float[][] a = new float [][](1, 1);\n\n        if((a.length != 1) || (a[0].length != 1)){\n                assert(0);\n        }\n        if (a[0][0] == a[0][0]){\n                assert(0);\n        }\n}\n\n/*******************************************/\n\nvoid test58()\n{\n    struct S\n    {\n        int i;\n        int[4] bar = 4;\n        float[4] abc;\n    }\n\n    static S a = {i: 1};\n    static S b;\n\n    writefln(\"a.bar: %s, %s\", a.bar, a.abc);\n    assert(a.i == 1);\n    assert(a.bar[0] == 4);\n    assert(a.bar[1] == 4);\n    assert(a.bar[2] == 4);\n    assert(a.bar[3] == 4);\n    writefln(\"b.bar: %s, %s\", b.bar, b.abc);\n    assert(b.i == 0);\n    assert(b.bar[0] == 4);\n    assert(b.bar[1] == 4);\n    assert(b.bar[2] == 4);\n    assert(b.bar[3] == 4);\n}\n\n\n/*******************************************/\n\nvoid bug59(string s)()\n{\n  writeln(s);\n  writeln(s.length);\n}\n\nvoid test59()\n{\n    bug59!(\"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\")();\n}\n\n/*******************************************/\n\nclass Foo60(T)\n{\n    this() { unknown_identifier; }\n}\n\nvoid test60()\n{\n    bool foobar = is( Foo60!(int) );\n    assert(!foobar);\n}\n\n\n/*******************************************/\n\nvoid repeat( int n, void delegate() dg )\n{\n    printf(\"n = %d\\n\", n);\n    if( n&1 ) dg();\n    if( n/2 ) repeat( n/2, {dg();dg();} );\n}\n\nvoid test61()\n{\n    repeat( 10, {printf(\"Hello\\n\");} );\n}\n\n/*******************************************/\n\nvoid test62()\n{\n    Vector62 a;\n    a.set(1,2,24);\n    a = a * 2;\n    writeln(a.x, a.y, a.z);\n    assert(a.x == 2);\n    assert(a.y == 4);\n    assert(a.z == 48);\n}\n\n\nstruct Vector62\n{\n    float x,y,z;\n\n    // constructor\n    void set(float _x, float _y, float _z)\n    {\n      x = _x;\n      y = _y;\n      z = _z;\n    }\n\n    Vector62 opMul(float s)\n    {\n      Vector62 ret;\n      ret.x = x*s;\n      ret.y = y*s;\n      ret.z = z*s;\n      return ret;\n    }\n}\n\n/*******************************************/\n\nstruct Data63\n{\n    int x, y;\n\n    /// To make size > 8 so NRVO is used.\n    /// Program runs correctly with this line commented out:\n    byte filler;\n}\n\nData63 frob(ref Data63 d)\n{\n    Data63 ret;\n    ret.y = d.x - d.y;\n    ret.x = d.x + d.y;\n    return ret;\n}\n\nvoid test63()\n{\n    Data63 d; d.x = 1; d.y = 2;\n    d = frob(d);\n    writeln(d.x);\n    writeln(d.y);\n    assert(d.x == 3 && d.y == -1);\n}\n\n/*******************************************/\n\nclass Foo64\n{\n    this() { writefln(\"Foo64 created\"); }\n    ~this() { writefln(\"Foo64 destroyed\"); }\n}\n\ntemplate Mix64()\n{\n    void init() {\n        ptr = new Foo64;\n    }\n    Foo64 ptr;\n}\n\nclass Container64\n{\n    this() { init(); }\n    mixin Mix64;\n}\n\n\nvoid test64()\n{\n    auto x = new Container64;\n\n    assert(!(x.classinfo.flags & 2));\n}\n\n/*******************************************/\n\nstruct Vector65(T, uint dim)\n{\n  T[dim]  data;\n}\n\nT dot65(T, uint dim)(Vector65!(T,dim) a, Vector65!(T,dim) b)\n{\n  T tmp;\n  for ( int i = 0; i < dim; ++i )\n    tmp += a.data[i] * b.data[i];\n  return tmp;\n}\n\nvoid test65()\n{\n  Vector65!(double,3u) a,b;\n  auto t = dot65(a,b);\n}\n\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=18576\n\nvoid delegate() callback;\n\nstruct S66 {\n    int x;\n    @disable this(this);\n\n    this(int x) {\n        this.x = x;\n        callback = &inc;\n    }\n    void inc() {\n        x++;\n    }\n}\n\nauto f66()\n{\n    return g66();   // RVO should be done\n}\n\nauto g66()\n{\n    return h66();   // RVO should be done\n}\n\nauto h66()\n{\n    return S66(100);\n}\n\nvoid test18576()\n{\n    auto s = f66();\n    printf(\"%p vs %p\\n\", &s, callback.ptr);\n    callback();\n    printf(\"s.x = %d\\n\", s.x);\n    assert(s.x == 101);\n    assert(&s == callback.ptr);\n}\n\n/*******************************************/\n\nvoid main()\n{\n    printf(\"Start\\n\");\n\n    test1();\n    test2();\n    test3();\n    test4();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test58();\n    test59();\n    test60();\n    test61();\n    test62();\n    test63();\n    test64();\n    test65();\n    //test18576();  // XBUG: NRVO implementation differs\n\n    printf(\"Success\\n\");\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test29.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/test29a.d imports/test29b.d\n// PERMUTE_ARGS:\n\nimport imports.test29a;\nimport imports.test29b;\n\nextern(C) int printf(const char*, ...);\n\nvoid main() {\n        printf(\"%d\\n\", qwert);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test3.d",
    "content": "// PERMUTE_ARGS: -unittest -O -release -inline -fPIC -g\n// EXTRA_SOURCES: imports/test3a.d imports/test3b.d\n\nimport imports.test3a;\n\nextern(C) int printf(const char*, ...);\n\nclass Foo\n{\n    string bar;\n\n    unittest\n    {\n        printf(\"in Foo.unittest()\\n\");\n    }\n}\n\n\nvoid test(int a)\n{\n}\n\nvoid test(uint b)\n{\n}\n\n\nint main(string[] args)\n{\n    Foo a = new Foo;\n    string baz = \"lolo\";\n\n    test(3);\n    a.bar = \"hello\";\n    a.bar = baz ~ \"betty\";\n\n    printf(\"a.bar = '%.*s'\\n\", a.bar.length, a.bar.ptr);\n    assert(a.bar == \"lolobetty\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test30.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=444\n\nint main()\n{\n  int nothing( int delegate(ref int) dg ) {return 0;}\n  foreach(int x; &nothing)\n    return 7;\n  return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test31.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/test31a.d\n// PERMUTE_ARGS:\n\nimport imports.test31a;\n\nclass Foo {\n    mixin Baz!();\n\n    void testfunc() {\n        privfunc(); // Error: .privfunc is private\n    }\n}\n\nint main()\n{\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test32.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/test32a.d\n// PERMUTE_ARGS:\n\nimport imports.test32a;\n\nvoid main()\n{\n    assert(S.sizeof == int.sizeof);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test34.d",
    "content": "\nmodule test34;\n\nimport std.stdio;\nimport std.string;\nimport std.format;\nimport core.exception;\n\n\n/************************************************/\n\nclass Foo {}\nclass Bar {}\n\nvoid test1()\n{\n    TypeInfo ti_foo = typeid(Foo);\n    TypeInfo ti_bar = typeid(Bar);\n\n    auto hfoo = ti_foo.toHash();\n    auto hbar = ti_bar.toHash();\n    writefln(\"typeid(Foo).toHash: \", hfoo);\n    writefln(\"typeid(Bar).toHash: \", hbar);\n    assert(hfoo != hbar);\n\n    auto e = (ti_foo == ti_bar);\n    writefln(\"opEquals: \", e ? \"equal\" : \"not equal\");\n    assert(!e);\n\n    auto c = (ti_foo.opCmp(ti_bar) == 0);\n    writefln(\"opCmp: \", c ? \"equal\" : \"not equal\");\n    assert(!c);\n}\n\n\n/************************************************/\n\nvoid test2()\n{\n  assert( [2,3]!=[2,4] );\n  assert( [3,2]!=[4,2] );\n  assert( !([2,3]==[2,4]) );\n  assert( ([2,3]==[2,3]) );\n}\n\n/************************************************/\n\nstruct Struct\n{\n    int langID;\n    long _force_nrvo;\n}\n\nStruct[1] table;\n\nStruct getfirst()\n{\n    foreach(v; table) {\n        writeln(v.langID);\n        assert(v.langID == 1);\n        return v;\n    }\n    assert(0);\n}\n\nStruct getsecond()\n{\n    foreach(ref v; table) {\n        writeln(v.langID);\n        assert(v.langID == 1);\n        return v;\n    }\n    assert(0);\n}\n\nvoid test3()\n{\n    table[0].langID = 1;\n\n    auto v = getfirst();\n    writeln(v.langID);\n    assert(v.langID == 1);\n\n    v = getsecond();\n    writeln(v.langID);\n    assert(v.langID == 1);\n}\n\n/************************************************/\n\nclass ExOuter\n{\n    class ExInner\n    {\n        this()\n        {\n            typeof(this.outer) X;\n            static assert(is(typeof(X) == ExOuter));\n        }\n    }\n}\n\nvoid test4()\n{\n}\n\n/************************************************/\n\nint status5;\n\nstruct MyStruct5\n{\n}\n\nvoid rec5(int i, MyStruct5 s)\n{\n    if( i > 0 )\n    {\n        status5++;\n        rec5(i-1, s);\n    }\n}\n\nvoid test5()\n{\n    assert(status5==0);\n    MyStruct5 st;\n    rec5(1030, st);\n    assert(status5==1030);\n}\n\n/************************************************/\n\nclass C6\n{\n    const int a;\n\n    this()\n    {\n        a = 3;\n    }\n\n    this(int x)\n    {\n        this();\n    }\n}\n\nvoid test6()\n{\n}\n\n/************************************************/\n\ntemplate parseUinteger(string s)\n{\n    static if (s.length == 0)\n    {   const char[] value = \"\";\n        const char[] rest = \"\";\n    }\n    else static if (s[0] >= '0' && s[0] <= '9')\n    {   const char[] value = s[0] ~ parseUinteger!(s[1..$]).value;\n        const char[] rest = parseUinteger!(s[1..$]).rest;\n    }\n    else\n    {   const char[] value = \"\";\n        const char[] rest = s;\n    }\n}\n\ntemplate parseInteger(string s)\n{\n    static if (s.length == 0)\n    {   const char[] value = \"\";\n        const char[] rest = \"\";\n    }\n    else static if (s[0] >= '0' && s[0] <= '9')\n    {   const char[] value = s[0] ~ parseUinteger!(s[1..$]).value;\n        const char[] rest = parseUinteger!(s[1..$]).rest;\n    }\n    else static if (s.length >= 2 &&\n                s[0] == '-' && s[1] >= '0' && s[1] <= '9')\n    {   const char[] value = s[0..2] ~ parseUinteger!(s[2..$]).value;\n        const char[] rest = parseUinteger!(s[2..$]).rest;\n    }\n    else\n    {   const char[] value = \"\";\n        const char[] rest = s;\n    }\n}\n\nvoid test7()\n{\n    writeln(parseUinteger!(\"1234abc\").value);\n    writeln(parseUinteger!(\"1234abc\").rest);\n    writeln(parseInteger!(\"-1234abc\").value);\n    writeln(parseInteger!(\"-1234abc\").rest);\n\n    assert(parseUinteger!(\"1234abc\").value == \"1234\");\n    assert(parseUinteger!(\"1234abc\").rest == \"abc\");\n    assert(parseInteger!(\"-1234abc\").value == \"-1234\");\n    assert(parseInteger!(\"-1234abc\").rest == \"abc\");\n}\n\n/************************************************/\n\nstruct Foo8 { }\n\nenum Enum { RED }\n\n//typedef int myint;\n\nalias int myalias;\n\nvoid test8()\n{\n/+\n    assert((1+2).stringof == \"1 + 2\");\n    assert(Foo8.stringof == \"Foo8\");\n    assert(test.Foo8.stringof == \"test.Foo8\");\n    assert(int.stringof == \"int\");\n    assert((int*[5][]).stringof == \"int*[5][]\");\n    assert(Enum.RED.stringof == \"Enum.RED\");\n    assert(test.myint.stringof == \"test.myint\");\n    assert(myalias.stringof == \"myalias\");\n    assert((5).stringof == \"5\");\n    assert(typeof(5).stringof == \"typeof(5)\");\n+/\n}\n\n/************************************************/\n\n/+\nclass Base9 {\n    public void fnc(){\n    }\n}\n\nclass Foo9 : Base9 {\n    alias Base9.fnc fnc;\n    public void fnc(){\n    }\n    static this(){\n        alias void function() T;\n        T ptr = & fnc;\n    }\n}\n+/\n\nvoid test9()\n{\n}\n\n/************************************************/\n\nbool isalnum(dchar c) { return c>='0' && c >= '9'; }\n\nchar[] toHtmlFilename(char[] fname)\n{\n    foreach (ref c; fname)\n    {\n        if (!isalnum(c) && c != '.' && c != '-')\n            c = '_';\n    }\n    return fname;\n}\n\nvoid test10()\n{\n}\n\n/************************************************/\n\nclass A34 { }\nclass B34 : A34 { }\n\nvoid test11()\n{\n  A34 test=new B34;\n  writefln(\"Test is \", test.toString);\n  assert(test.toString == \"test34.B34\");\n  A34 test_2=cast(A34)(new B34);\n  writefln(\"Test 2 is \", test_2.toString);\n  assert(test_2.toString == \"test34.B34\");\n}\n\n/************************************************/\n\ntemplate Foo12(T: T[U], U)\n{\n    alias int Foo12;\n}\n\nvoid test12()\n{\n    Foo12!(int[long]) x;\n    assert(is(typeof(x) == int));\n}\n\n/************************************************/\n\nclass C13\n{\n    int a = 4;\n    this()\n    {\n        printf(\"C13.this()\\n\");\n        assert(a == 4);\n        a = 5;\n    }\n}\n\nvoid test13()\n{\n    C13 c = cast(C13)Object.factory(\"test34.C13\");\n    assert(c.a == 5);\n    Object o = Object.factory(\"test35.C13\");\n    assert(o is null);\n}\n\n/************************************************/\n\nclass Base15 {\n        int func(int a) { return 1; }\n}\n\n\nclass Foo15 : Base15 {\n        alias Base15.func func;\n}\n\n\nclass Bar15 : Foo15 {\n        alias Foo15.func func;\n        int func(string a) { return 2; }\n}\n\nvoid test15()\n{\n    Bar15 b = new Bar15();\n    assert(b.func(\"hello\") == 2);\n    assert(b.func(5) == 1);\n}\n\n/************************************************/\n\nstruct Basic16(T, U) {}\n\nstruct Iterator16(T : Basic16!(T, U), U)\n{\n    static void Foo()\n    {\n        writeln(typeid(T), typeid(U));\n        assert(is(T == int));\n        assert(is(U == float));\n    }\n}\n\nvoid test16()\n{\n    Iterator16!(Basic16!(int, float)).Foo();\n}\n\n/************************************************/\n\nstruct S17(T)\n{\n    struct iterator {}\n}\n\nint insert17(T) (S17!(T) lst, S17!(T).iterator i)\n{\n    return 3;\n}\n\nvoid test17()\n{\n    S17!(int) a;\n    S17!(int).iterator i;\n    auto x = insert17(a, i);\n    assert(x == 3);\n}\n\n/************************************************/\n\nvoid test18()\n{\n    real t = 0.;\n    for(int i=0; i<10; i++)\n    {\n        t += 1.;\n        real r =  (2*t);\n        printf(\"%Lg  %Lg  %Lg\\n\", t, r, 2*t);\n        assert(2*t == (i+1)*2);\n    }\n}\n\n/************************************************/\n\nvoid test19()\n{\n    char c = '3';\n    void[] ca = cast(void[])[c];\n    char[] x = cast(char[])ca;\n    assert(x[0] == '3');\n}\n\n/************************************************/\n\nenum type20\n{\n    a,\n    b,\n}\n\nclass myclass20\n{\n    template XX(uint a, uint c)\n    {\n        static uint XX(){ return (a*256+c);}\n    }\n    void testcase()\n    {\n        switch (cast(uint)type20.a)\n        {\n            case XX!(cast(uint)type20.a,cast(uint)type20.b)():\n                break;\n            default: assert(0);\n        }\n    }\n}\n\nvoid test20()\n{\n}\n\n/************************************************/\n\nstruct S21\n{\n    alias int Foo;\n    int x;\n}\n\nvoid test21()\n{\n    S21 s;\n    typeof(s).Foo j;\n    assert(is(typeof(j) == int));\n}\n\n/************************************************/\n\nvoid test22()\n{\n    auto i = 3, j = 4;\n    assert(is(typeof(i) == int));\n    assert(is(typeof(j) == int));\n}\n\n/************************************************/\n\nstatic m23 = 5, n23 = 6;\n\nvoid test23()\n{\n    auto i = 3, j = 4;\n    assert(is(typeof(i) == int));\n    assert(is(typeof(j) == int));\n    assert(is(typeof(m23) == int));\n    assert(is(typeof(n23) == int));\n}\n\n/************************************************/\n\nconst int a24 = 0;\nconst int foo24 = 4;\nconst int[1] bar24 = [foo24 * 2];\nconst int zap24 = (1 << bar24[a24]);\n\nvoid test24()\n{\n    assert(zap24 == 256);\n}\n\n/************************************************/\n\nstruct List25(T) {  }\nstruct CircularQueue25(T) {  }\n\nvoid front25(T)(ref List25!(T) list) {  }\nvoid front25(T)(ref CircularQueue25!(T) queue) {  }\n\nvoid test25()\n{\n    List25!(int) x;\n    front25(x);\n}\n\n/************************************************/\n\nstruct Foo26\n{\n    const string x;\n}\n\nstatic Foo26 foo26 = {\"something\"};\n\nvoid test26()\n{\n    assert(foo26.x == \"something\");\n}\n\n/************************************************/\n\ntemplate Mang(alias F)\n{\n    class G { }\n    alias void function (G ) H;\n    const string mangledname = H.mangleof;\n}\n\ntemplate moo(alias A)\n{\n    pragma(msg,\"   \");\n    const string a = Mang!(A).mangledname;\n    pragma(msg,\"   \");\n    static assert(Mang!(A).mangledname == a); // FAILS !!!\n    pragma(msg,\"   \");\n}\n\nvoid test27()\n{\n    int q;\n    string b = moo!(q).a;\n}\n\n/************************************************/\n\nstruct Color\n{\n    static void fromRgb(uint rgb)\n    {\n    }\n\n    static void fromRgb(ubyte alpha, uint rgb)\n    {\n    }\n}\n\nvoid test28()\n{\n    Color.fromRgb(0);\n    Color.fromRgb(cast(uint)0);\n}\n\n/************************************************/\n\nvoid test29()\n{\n  const char[] t=\"abcd\";\n  const ubyte[] t2=cast(ubyte[])t;\n  const char[] t3=['a','b','c','d'];\n  const ubyte[] t4=cast(ubyte[])t3;\n  assert(t4[1] == 'b');\n}\n\n/************************************************/\n\nvoid test30()\n{\n  const char[] test = \"\" ~ 'a' ~ 'b' ~ 'c';\n  char[] test2 = (cast(char[])null)~'a'~'b'~'c';\n  const char[] test3 = (cast(char[])null)~'a'~'b'~'c';\n  char[] test4 = (cast(char[])[])~'a'~'b'~'c';\n  const char[] test5 = (cast(char[])[])~'a'~'b'~'c';\n  const char[] test6 = null;\n  const char[] test7 = test6~'a'~'b'~'c';\n}\n\n/************************************************/\n\nclass C31\n{\n    synchronized invariant() { int x; }\n}\n\nvoid test31()\n{\n}\n\n/************************************************/\n\nulong foo32()\n{\n        return cast(ulong) (cast(ulong) 1176576512 + cast(float) -2);\n}\n\nvoid test32()\n{\n        assert(foo32()==1176576510);\n}\n\n/************************************************/\n\nclass RangeCoder\n{\n    uint[258] cumCount; // 256 + end + total\n    uint lower;\n    uint upper;\n    ulong range;\n\n    this() {\n        for (int i=0; i<cumCount.length; i++)\n            cumCount[i] = i;\n        lower = 0;\n        upper = 0xffffffff;\n        range = 0x100000000;\n    }\n\n    void encode(uint symbol) {\n        uint total = cumCount[$ - 1];\n        // \"Error: Access Violation\" in following line\n        upper = lower + cast(uint)((cumCount[symbol+1] * range) / total) - 1;\n        lower = lower + cast(uint)((cumCount[symbol]   * range) / total);\n    }\n}\n\nvoid test33()\n{\n    RangeCoder rc = new RangeCoder();\n    rc.encode(77);\n}\n\n/************************************************/\n\nstruct Vector34\n{\n    float x, y, z;\n\n    public static Vector34 opCall(float x = 0, float y = 0, float z = 0)\n    {\n        Vector34 v;\n\n        v.x = x;\n        v.y = y;\n        v.z = z;\n\n        return v;\n    }\n\n    public string toString()\n    {\n        return std.string.format(\"<%f, %f, %f>\", x, y, z);\n    }\n}\n\nclass Foo34\n{\n    private Vector34 v;\n\n    public this()\n    {\n        v = Vector34(1, 0, 0);\n    }\n\n    public void foo()\n    {\n        bar();\n    }\n\n    private void bar()\n    {\n        auto s = foobar();\n        writef(\"Returned: %s\\n\", s);\n        assert(std.string.format(\"%s\", s) == \"<1.000000, 0.000000, 0.000000>\");\n    }\n\n    public Vector34 foobar()\n    {\n        writef(\"Returning %s\\n\", v);\n\n        return v;\n        Vector34 b = Vector34();\n        return b;\n    }\n}\n\nvoid test34()\n{\n    Foo34 f = new Foo34();\n    f.foo();\n}\n\n\n/************************************************/\n\nvoid foo35()\n{\n        uint a;\n        uint b;\n        uint c;\n        extern (Windows) int function(int i, int j, int k) xxx;\n\n        a = 1;\n        b = 2;\n        c = 3;\n\n        xxx = cast(typeof(xxx))(a + b);\n        version(GNU)\n        {\n            import gcc.builtins;\n            __builtin_trap();\n        }\n        else\n            asm { int 3; }\n        xxx( 4, 5, 6 );\n}\n\nvoid test35()\n{\n}\n\n/************************************************/\n\nvoid test36()\n{\n    int* p = void, c = void;\n}\n\n/************************************************/\n\nvoid test37()\n{\n    synchronized\n    {\n        synchronized\n        {\n            writefln(\"Hello world!\");\n        }\n    }\n}\n\n/************************************************/\n\nstruct Rect {\n    int left, top, right, bottom;\n}\n\nvoid test38()\n{\n    print38(sizeTest(false));\n    print38(sizeTest(true));\n    print38(defaultRect);\n}\n\nstatic Rect sizeTest(bool empty) {\n    if (empty) {\n        Rect result;\n        return result;\n        //return Rect.init;\n    } else {\n        return defaultRect;\n        /+Rect result = defaultRect;\n        return result;+/\n    }\n}\n\nvoid print38(Rect r) {\n    writefln(\"(%d, %d)-(%d, %d)\", r.left, r.top, r.right, r.bottom);\n    assert(r.left == 0);\n    assert(r.right == 0);\n    assert(r.top == 0);\n    assert(r.bottom == 0);\n}\n\nRect defaultRect() {\n    return Rect.init;\n}\n\n/************************************************/\n\nvoid test39()\n{\n   double[][] foo = [[1.0],[2.0]];\n\n   writeln(foo[0]); // --> [1] , ok\n   writeln(foo[1]); // --> [2] , ok\n\n   writeln(foo);       // --> [[1],4.63919e-306]  ack!\n   writefln(\"%s\", foo); // --> ditto\n   auto f = std.string.format(\"%s\", foo);\n   assert(f == \"[[1], [2]]\");\n\n   double[1][2] bar;\n   bar[0][0] = 1.0;\n   bar[1][0] = 2.0;\n\n   writeln(bar);       // Error: Access violation\n   auto r = std.string.format(\"%s\", bar);\n   assert(r == \"[[1], [2]]\");\n}\n\n/************************************************/\n\nvoid test40()\n{\n    int[char] x;\n    x['b'] = 123;\n    writeln(x);\n    auto r = std.string.format(\"%s\", x);\n    assert(r == \"['b':123]\");\n    writeln(x['b']);\n}\n\n/************************************************/\n\nvoid test41()\n{\n}\n\n/************************************************/\n\nenum Enum42 {\n        A = 1\n}\n\nvoid test42() {\n        Enum42[] enums = new Enum42[1];\n        assert(enums[0] == Enum42.A);\n}\n\n\n/************************************************/\n\nstruct A43 {}\n\nstruct B43(L) {\n  A43 l;\n}\n\nvoid test43()\n{\n  A43 a;\n  auto b = B43!(A43)(a);\n}\n\n/************************************************/\n\nvoid test44()\n{\n    int[ const char[] ] a = [\"abc\":3, \"def\":4];\n}\n\n/************************************************/\n\nvoid test45()\n{\n    //char[3][] a = [\"abc\", \"def\"];\n    //writefln(a);\n    //char[][2] b = [\"abc\", \"def\"];\n    //writefln(b);\n}\n\n/************************************************/\n\nstruct bignum\n{\n    bool smaller()\n    {\n        if (true) return false;\n        else      return false;\n        assert(0);\n    }\n\n    void equal()\n    {\n        if (!smaller)\n            return;\n    }\n}\n\nvoid test46()\n{\n}\n\n/************************************************/\n\nstatic size_t myfind(string haystack, char needle) {\n  foreach (i, c ; haystack) {\n    if (c == needle) return i;\n  }\n  return size_t.max;\n}\n\nstatic size_t skip_digits(string s) {\n  foreach (i, c ; s) {\n    if (c < '0' || c > '9') return i;\n  }\n  return s.length;\n}\n\nstatic uint matoi(string s) {\n  uint result = 0;\n  foreach (c ; s) {\n    if (c < '0' || c > '9') break;\n    result = result * 10 + (c - '0');\n  }\n  return result;\n}\n\nenum { leading, skip, width, modifier, format, fmt_length, extra };\n\nstatic string GetFormat(string s) {\n  uint pos = 0;\n  string result;\n  // find the percent sign\n  while (pos < s.length && s[pos] != '%') {\n    ++pos;\n  }\n  const leading_chars = pos;\n  result ~= cast(char) pos;\n  if (pos < s.length) ++pos; // go right after the '%'\n  // skip?\n  if (pos < s.length && s[pos] == '*') {\n    result ~= 1;\n    ++pos;\n  } else {\n    result ~= 0;\n  }\n  // width?\n  result ~= cast(char) matoi(s);\n  pos += skip_digits(s[pos .. $]);\n  // modifier?\n  if (pos < s.length && myfind(\"hjlLqtz\", s[pos]) != size_t.max) {\n    // @@@@@@@@@@@@@@@@@@@@@@@@@@@@\n    static if (true) {\n      result ~= s[pos++];\n    } else {\n      result ~= s[pos];\n      ++pos;\n    }\n    // @@@@@@@@@@@@@@@@@@@@@@@@@@@@\n  } else {\n    result ~= '\\0';\n  }\n  return result;\n}\n\nvoid test47()\n{\n  static string test = GetFormat(\" %*Lf\");\n  assert(test[modifier] == 'L', \"`\" ~ test[modifier] ~ \"'\");\n}\n\n/************************************************/\n\nclass B48() {}\nclass C48   {}\n\nint foo48()(B48!()) { return 1; }\nint foo48()(C48 c) { return 2; }\n\nvoid test48()\n{\n    auto i = foo48(new B48!());\n    assert(i == 1);\n\n    i = foo48(new C48);\n    assert(i == 2);\n}\n\n/************************************************/\n\nvoid test49()\n{\n    struct A { int v; }\n\n    A a = A(10);\n\n  version (all)\n  {\n    writefln(\"Before test 1: \", a.v);\n    if (a == a.init) { writeln(a.v,\"(a==a.init)\"); assert(0); }\n    else { writeln(a.v,\"(a!=a.init)\"); assert(a.v == 10); }\n  }\n  else\n  {\n    writefln(\"Before test 1: \", a.v);\n    if (a == a.init) { writeln(a.v,\"(a==a.init)\"); assert(a.v == 10); }\n    else { writeln(a.v,\"(a!=a.init)\"); assert(0); }\n  }\n\n    a.v = 100;\n    writefln(\"Before test 2: \", a.v);\n    if (a == a.init) { writeln(a.v,\"(a==a.init)\"); assert(0); }\n    else { writeln(a.v,\"(a!=a.init)\"); assert(a.v == 100); }\n\n    a = A(1000);\n    writefln(\"Before test 3: \", a.v);\n    if (a == a.init) { writeln(a.v,\"(a==a.init)\"); assert(0); }\n    else { writeln(a.v,\"(a!=a.init)\"); assert(a.v == 1000); }\n\n  version (all)\n    assert(a.init.v == 0);\n  else\n    assert(a.init.v == 10);\n}\n\n/************************************************/\n\nstruct S51\n{\n    int i = 3;\n    void div() { assert(i == 3); }\n}\n\nvoid test51()\n{\n    S51().div();\n}\n\n/************************************************/\n\nvoid test52()\n{\n    struct Foo {\n        alias int Y;\n    }\n    with (Foo) {\n         Y y;\n    }\n}\n\n/************************************************/\n\nstruct TestStruct\n{\n    int dummy0 = 0;\n    int dummy1 = 1;\n    int dummy2 = 2;\n}\n\nvoid func53(TestStruct[2] testarg)\n{\n    writeln(testarg[0].dummy0);\n    writeln(testarg[0].dummy1);\n    writeln(testarg[0].dummy2);\n\n    writeln(testarg[1].dummy0);\n    writeln(testarg[1].dummy1);\n    writeln(testarg[1].dummy2);\n\n    assert(testarg[0].dummy0 == 0);\n    assert(testarg[0].dummy1 == 1);\n    assert(testarg[0].dummy2 == 2);\n\n    assert(testarg[1].dummy0 == 0);\n    assert(testarg[1].dummy1 == 1);\n    assert(testarg[1].dummy2 == 2);\n}\n\nTestStruct[2] m53;\n\nvoid test53()\n{\n    writeln(&m53);\n    func53(m53);\n}\n\n/************************************************/\n\nvoid test54()\n{\n    double a = 0;\n    double b = 1;\n    // Internal error: ..\\ztc\\cg87.c 3233\n//    a += (1? b: 1+1i)*1i;\n    writeln(a);\n//    assert(a == 0);\n    // Internal error: ..\\ztc\\cod2.c 1680\n//    a += (b?1:b-1i)*1i;\n    writeln(a);\n//    assert(a == 0);\n}\n\n/************************************************/\n\nclass B55 {}\nclass D55 : B55 {}\n\ntemplate foo55(S, T : S) { }    // doesn't work\n\nalias foo55!(B55, D55) bar55;\n\nvoid test55()\n{\n}\n\n/************************************************/\n\ntemplate t56() { alias Object t56; }\npragma(msg, t56!().stringof);\n\nvoid test56()\n{\n}\n\n/************************************************/\n\nvoid test57()\n{\n    alias long[char[]] AA;\n\n    static if (is(AA T : T[U], U : const char[]))\n    {\n        writeln(typeid(T));\n        writeln(typeid(U));\n\n        assert(is(T == long));\n        assert(is(U == const(char)[]));\n    }\n\n    static if (is(AA A : A[B], B : int))\n    {\n        assert(0);\n    }\n\n    static if (is(int[10] W : W[V], int V))\n    {\n        writeln(typeid(W));\n        assert(is(W == int));\n        writeln(V);\n        assert(V == 10);\n    }\n\n    static if (is(int[10] X : X[Y], int Y : 5))\n    {\n        assert(0);\n    }\n}\n\n/************************************************/\n\nstatic this()\n{\n   printf(\"one\\n\");\n}\n\nstatic this()\n{\n   printf(\"two\\n\");\n}\n\nstatic ~this()\n{\n   printf(\"~two\\n\");\n}\n\nstatic ~this()\n{\n   printf(\"~one\\n\");\n}\n\n\nvoid test59()\n{\n}\n\n/************************************************/\n\nclass C60\n{\n    extern (C++) int bar60(int i, int j, int k)\n    {\n        printf(\"this = %p\\n\", this);\n        printf(\"i = %d\\n\", i);\n        printf(\"j = %d\\n\", j);\n        printf(\"k = %d\\n\", k);\n        assert(i == 4);\n        assert(j == 5);\n        assert(k == 6);\n        return 1;\n    }\n}\n\n\nextern (C++)\n        int foo60(int i, int j, int k)\n{\n    printf(\"i = %d\\n\", i);\n    printf(\"j = %d\\n\", j);\n    printf(\"k = %d\\n\", k);\n    assert(i == 1);\n    assert(j == 2);\n    assert(k == 3);\n    return 1;\n}\n\nvoid test60()\n{\n    foo60(1, 2, 3);\n\n    C60 c = new C60();\n    c.bar60(4, 5, 6);\n}\n\n/***************************************************/\n\ntemplate Foo61(alias a) {}\n\nstruct Bar61 {}\nconst Bar61 bar61 = {};\n\nalias Foo61!(bar61) baz61;\n\nvoid test61()\n{\n}\n\n/************************************************/\n\nT foo62(T)(lazy T value)\n{\n    return value;\n}\n\nvoid test62()\n{\n    foo62(new float[1]);\n}\n\n/************************************************/\n\nvoid main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test56();\n    test57();\n    test59();\n    test60();\n    test61();\n    test62();\n\n    writefln(\"Success\");\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test3449.d",
    "content": "\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3449\n\ntemplate TypeTuple(T...) { alias TypeTuple = T; }\n\n// If module variable has no explicit initializer,\n// constant folding is not allowed for that.\nint mg1;\nconst int cg1;\nimmutable int ig1;\nstatic this()\n{\n    mg1 = 10;\n    cg1 = 10;\n    ig1 = 10;\n}\nstatic assert(!__traits(compiles, { static assert(mg1 == 0); }));\nstatic assert(!__traits(compiles, { static assert(cg1 == 0); }));\nstatic assert(!__traits(compiles, { static assert(ig1 == 0); }));\n\n// But, if module variable has explicit initializer and\n// non-mutable type, constant folding is allowed for that..\nint mg2 = 1;\nconst int cg2 = 1;\nimmutable int ig2 = 1;\nstatic this()\n{\n    mg2 = 11;\n    static assert(!__traits(compiles, cg2 = 11));   // not allowed for constant folding\n    static assert(!__traits(compiles, ig2 = 11));   // not allowed for constant folding\n}\nstatic assert(!__traits(compiles, { static assert(mg2 == 1); }));\n                                    static assert(cg2 == 1);    // possible\n                                    static assert(ig2 == 1);    // possible\n\n// For aggregate fields, compiler behavior will be changed.\nvoid test3449()\n{\n    static struct S(T)\n    {\n        T field1;       // doesn't have explicit initializer\n        T field2 = 1;   // has explicit initializer\n\n        this(int n)\n        {\n            field1 = n; // allowed\n            field2 = n; // NEW! re-assigning during construction is allowed for any qualified fields.\n        }\n    }\n\n    foreach (T; TypeTuple!(int, const int, immutable int))\n    {\n        alias S!T ST;\n\n        auto s1 = ST();             // default construction\n        assert(s1.field1 == 0);     // == T.init\n        assert(s1.field2 == 1);     // == specified initializer\n\n        // Getting address for non-mutable field is allowed.\n        T* s1p1 = &s1.field1;\n        T* s1p2 = &s1.field2;\n        assert(*s1p1 == 0);\n        assert(*s1p2 == 1);\n        static if (is(T == int))\n        {   // If T is mutable,\n            // modification through indirection is allowed\n            *s1p1 = 100, *s1p2 = 101;\n            assert(*s1p1 == 100);\n            assert(*s1p2 == 101);\n        }\n        else\n        {   // If T is not mutable, modification is not allowed\n            static assert(!__traits(compiles, *s1p1 = 100));\n            static assert(!__traits(compiles, *s1p2 = 100));\n        }\n\n        // Access to non-static non-mutable field is\n        // now correctly rejected by \"need this\" error.\n        static assert(!__traits(compiles, ST.field1 == 1));\n        static assert(!__traits(compiles, ST.field2 == 0));\n\n        // So, re-assignment of non-mutable fields\n        // during construction is enough acceptable.\n        auto s2 = ST(10);\n        assert(s2.field1 == 10);\n        assert(s2.field2 == 10);\n    }\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10643\n\nstruct S10643\n{\n    const int[1000] x = void;\n\n    this(int n)\n    {\n        x[] = n;\n    }\n}\nstatic assert(S10643.sizeof == int.sizeof * 1000);\n\n/******************************************/\n\nint main()\n{\n    test3449();\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test3574a.d",
    "content": "int g = 0;\nstatic ~this() { assert(g == 100); }\n\nvoid main()\nout\n{\n    g = 100;\n}\nbody\n{\n    return;\n    // expected return code == 0\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test3574b.d",
    "content": "int g = 0;\nstatic ~this() { assert(g == 100); }\n\nvoid main()\nout\n{\n    g = 100;\n}\nbody\n{\n    //return;\n    // expected return code == 0\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test3574c.d",
    "content": "//int g = 0;\n//static ~this() { assert(g == 100); }\n\nvoid main()\n//out\n//{\n//    g = 100;\n//}\n//body\n{\n    return;\n    // expected return code == 0\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test3574d.d",
    "content": "//int g = 0;\n//static ~this() { assert(g == 100); }\n\nvoid main()\n//out\n//{\n//    g = 100;\n//}\n//body\n{\n    //return;\n    // expected return code == 0\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test36.d",
    "content": "// PERMUTE_ARGS:\n\nimport std.stdio;\ninterface IUnknown{\n        extern(Windows):\n        void func();\n}\nclass ComObject :IUnknown\n{\nextern (Windows):\n        void func()\n        {writefln(`comobject`);\n        }\n}\ninterface IDataObject: IUnknown\n{\n        extern(Windows):\n        void method();\n}\npackage class invarianttest:ComObject, IDataObject\n{\n        invariant()\n        {\n                writefln(`hello invariant`);\n        }\n\nextern (Windows):\n        override void func()\n        {\n        int esp;\n        version(GNU)\n        {\n            version(X86) asm\n            {\n                \"mov %%ESP,%0\" : \"=r\" esp : : ;\n            }\n            else version(X86_64) asm\n            {\n                \"mov %%ESP,%0\" : \"=r\" esp : : ;\n            }\n            else version(ARM) asm\n            {\n                \"str sp,%0\" : \"=m\" esp : : ;\n            }\n            else static assert(false, \"ASM code not implemented for this architecture\");\n        }\n        else asm\n        {\n                mov esp,ESP;\n        }\n        printf(\"\\n%d\",esp);\n        printf(`func`);\n        }\n        void method()\n        {\n                writefln(`method`);\n        }\n}\nint main()\n{\n        auto inst= new invarianttest;\n        int esp;\n        version(GNU)\n        {\n            version(X86) asm\n            {\n                \"mov %%ESP,%0\" : \"=r\" esp : : ;\n            }\n            else version(X86_64) asm\n            {\n                \"mov %%ESP,%0\" : \"=r\" esp : : ;\n            }\n            else version(ARM) asm\n            {\n                \"str sp,%0\" : \"=m\" esp : : ;\n            }\n            else static assert(false, \"ASM code not implemented for this architecture\");\n        }\n        else asm\n        {\n                mov esp,ESP;\n        }\n        inst.func();\n        inst.method();\n        writefln(\"\\n%d\",esp);\n        version(GNU)\n        {\n            version(X86) asm\n            {\n                \"mov %%ESP,%0\" : \"=r\" esp : : ;\n            }\n            else version(X86_64) asm\n            {\n                \"mov %%ESP,%0\" : \"=r\" esp : : ;\n            }\n            else version(ARM) asm\n            {\n                \"str sp,%0\" : \"=m\" esp : : ;\n            }\n            else static assert(false, \"ASM code not implemented for this architecture\");\n        }\n        else asm\n        {\n                mov esp,ESP;\n        }\n        writefln(\"\\n%d\",esp);\n        return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test37.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -Jrunnable/extra-files\n// EXTRA_FILES: extra-files/foo37.txt extra-files/std14198/uni.d\n\nimport std.stdio;\n\nvoid main()\n{\n    writefln(import(\"foo37.txt\"));\n    // also want to ensure that we can access\n    // imports in a subdirectory of the -J path\n    writefln(import(\"std14198/uni.d\"));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test38.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/test38a.d\n// PERMUTE_ARGS:\n\nimport std.stdio;\nimport imports.test38a;\n\nvoid main()\n{\n    static b = bar(7);\n    printf(\"b = %d, %d\\n\", b, bar(7));\n    assert(b == 49);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test4.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS:\n\nimport core.exception;\nimport core.stdc.math;\nimport core.vararg;\n\nextern(C)\n{\n    int atoi(const char*);\n    int memcmp(const void*, const void*, size_t);\n    int printf(const char*, ...);\n}\n\nint cmp(const(char)[] s1, const(char)[] s2)\n{\n    assert(s1.length == s2.length);\n\n    return memcmp(s1.ptr, s2.ptr, s1.length);\n}\n\n/* ================================ */\n\nvoid test1()\n{\n    int i;\n\n    int[6] foo = 1;\n    for (i = 0; i < foo.length; i++)\n        assert(foo[i] == 1);\n\n    int[10] bar;\n    for (i = 0; i < bar.length; i++)\n        assert(bar[i] == 0);\n\n    foo[3] = 4;\n    int[6] abc = foo;\n    for (i = 0; i < abc.length; i++)\n        assert(abc[i] == foo[i]);\n\n    abc[2] = 27;\n    foo[] = abc;\n    for (i = 0; i < abc.length; i++)\n        assert(abc[i] == foo[i]);\n}\n\n/* ================================ */\n\nvoid test2()\n{\n    byte[5] foo1;\n    ubyte[6] foo2;\n    short[7] foo3;\n    ushort[8] foo4;\n    int[9] foo5;\n    uint[10] foo6;\n    long[11] foo7;\n    ulong[12] foo8;\n    float[13] foo9;\n    double[14] foo10;\n    real[15] foo11;\n\n    int i;\n\n    printf(\"test2()\\n\");\n    for (i = 0; i < foo1.length; i++)\n        assert(foo1[i] == 0);\n    for (i = 0; i < foo2.length; i++)\n    {   printf(\"foo2[%d] = %d\\n\", i, foo2[i]);\n        assert(foo2[i] == 0);\n    }\n    for (i = 0; i < foo3.length; i++)\n        assert(foo3[i] == 0);\n    for (i = 0; i < foo4.length; i++)\n        assert(foo4[i] == 0);\n    for (i = 0; i < foo5.length; i++)\n    {\n        printf(\"foo5[%d] = %d\\n\", i, foo5[i]);\n        assert(foo5[i] == 0);\n    }\n    for (i = 0; i < foo6.length; i++)\n        assert(foo6[i] == 0);\n    for (i = 0; i < foo7.length; i++)\n        assert(foo7[i] == 0);\n    for (i = 0; i < foo8.length; i++)\n        assert(foo8[i] == 0);\n    for (i = 0; i < foo9.length; i++)\n        assert(isnan(foo9[i]));\n    for (i = 0; i < foo10.length; i++)\n        assert(isnan(foo10[i]));\n    for (i = 0; i < foo11.length; i++)\n        assert(isnan(foo11[i]));\n}\n\n/* ================================ */\n\nvoid test3()\n{\n    byte[5] foo1 = 20;\n    ubyte[6] foo2 = 21;\n    short[7] foo3 = 22;\n    ushort[8] foo4 = 23;\n    int[9] foo5 = 24;\n    uint[10] foo6 = 25;\n    long[11] foo7 = 26;\n    ulong[12] foo8 = 27;\n    float[13] foo9 = 28;\n    double[14] foo10 = 29;\n    real[15] foo11 = 30;\n\n    int i;\n\n    for (i = 0; i < foo1.length; i++)\n        assert(foo1[i] == 20);\n    for (i = 0; i < foo2.length; i++)\n        assert(foo2[i] == 21);\n    for (i = 0; i < foo3.length; i++)\n        assert(foo3[i] == 22);\n    for (i = 0; i < foo4.length; i++)\n        assert(foo4[i] == 23);\n    for (i = 0; i < foo5.length; i++)\n        assert(foo5[i] == 24);\n    for (i = 0; i < foo6.length; i++)\n        assert(foo6[i] == 25);\n    for (i = 0; i < foo7.length; i++)\n        assert(foo7[i] == 26);\n    for (i = 0; i < foo8.length; i++)\n        assert(foo8[i] == 27);\n    for (i = 0; i < foo9.length; i++)\n        assert(foo9[i] == 28);\n    for (i = 0; i < foo10.length; i++)\n        assert(foo10[i] == 29);\n    for (i = 0; i < foo11.length; i++)\n        assert(foo11[i] == 30);\n}\n\n/* ================================ */\n\nstruct a4\n{\n    string b = \"string\";\n    int c;\n}\n\nvoid test4()\n{\n    a4 a;\n    int i;\n\n    assert(a.b.length == 6);\n    i = cmp(a.b, \"string\");\n    assert(i == 0);\n\n    a4[3] c;\n    int j;\n    for (j = 0; j < 3; j++)\n    {\n        assert(c[j].b.length == 6);\n        i = cmp(c[j].b, \"string\");\n        assert(i == 0);\n    }\n}\n\n\n/* ================================ */\n\nfloat f5;\nconst char[4] x5 = \"abcd\";\n\nstruct a5\n{\n    string b = \"string\";\n    int c;\n}\n\na5[5] foo5;\n\nvoid test5()\n{\n    printf(\"test5()\\n\");\n    assert(isnan(f5));\n\n    assert(cmp(x5, \"abcd\") == 0);\n\n    int i;\n    for (i = 0; i < 5; i++)\n    {\n        assert(foo5[i].c == 0);\n        assert(cmp(foo5[i].b, \"string\") == 0);\n    }\n}\n\n/* ================================ */\n\nstruct TRECT6\n{\n    int foo1 = 2;\n\n    union {\n      struct\n      {\n        int Left = 3, Top = 4, Right = 5, Bottom = 6;\n      }\n      struct\n      {\n        long TopLeft, BottomRight;\n      }\n    }\n\n    int foo2 = 7;\n}\n\nvoid test6()\n{\n    TRECT6 t;\n\n    assert(t.foo1   == 2);\n    assert(t.Left   == 3);\n    assert(t.Top    == 4);\n    assert(t.Right  == 5);\n    assert(t.Bottom == 6);\n    assert(t.foo2   == 7);\n    assert(&t.foo1 < &t.Left);\n    assert(&t.Bottom < &t.foo2);\n\n    assert(TRECT6.foo1.offsetof == 0);\n    static if (long.alignof == 8)\n    {\n        assert(TRECT6.Left.offsetof == 8);\n        assert(TRECT6.Top.offsetof == 12);\n        assert(TRECT6.Right.offsetof == 16);\n        assert(TRECT6.Bottom.offsetof == 20);\n        assert(TRECT6.TopLeft.offsetof == 8);\n        assert(TRECT6.BottomRight.offsetof == 16);\n        assert(TRECT6.foo2.offsetof == 24);\n    }\n    else\n    {\n        assert(TRECT6.Left.offsetof == 4);\n        assert(TRECT6.Top.offsetof == 8);\n        assert(TRECT6.Right.offsetof == 12);\n        assert(TRECT6.Bottom.offsetof == 16);\n        assert(TRECT6.TopLeft.offsetof == 4);\n        assert(TRECT6.BottomRight.offsetof == 12);\n        assert(TRECT6.foo2.offsetof == 20);\n    }\n}\n\n/* ================================ */\n\nstruct TestVectors\n{\n    string pattern;\n    string input;\n    string result;\n    string format;\n    string replace;\n};\n\nTestVectors[] tva =\n[\n  {  pattern:\"(a)\\\\1\",  input:\"abaab\",  result:\"y\",     format:\"&\",     replace:\"aa\" },\n  {  pattern:\"abc\",     input:\"abc\",    result:\"y\",     format:\"&\",     replace:\"abc\" },\n];\n\nTestVectors[2] tvs =\n[\n  {  pattern:\"(a)\\\\1\",  input:\"abaab\",  result:\"y\",     format:\"&\",     replace:\"aa\" },\n  {  pattern:\"abc\",     input:\"abc\",    result:\"y\",     format:\"&\",     replace:\"abc\" },\n];\n\nTestVectors* tvp =\n[\n  {  pattern:\"(a)\\\\1\",  input:\"abaab\",  result:\"y\",     format:\"&\",     replace:\"aa\" },\n  {  pattern:\"abc\",     input:\"abc\",    result:\"y\",     format:\"&\",     replace:\"abc\" },\n];\n\nvoid test7()\n{\n    int i;\n\n    //printf(\"start\\n\");\n    //printf(\"%d\\n\", tva[0].pattern.length);\n    //printf(\"%.*s\\n\", tva[0].pattern.length, tva[0].pattern.ptr);\n\n    i = cmp(tva[0].pattern, \"(a)\\\\1\");\n    assert(i == 0);\n    i = cmp(tva[1].replace, \"abc\");\n    assert(i == 0);\n\n    i = cmp(tvs[0].pattern, \"(a)\\\\1\");\n    assert(i == 0);\n    i = cmp(tvs[1].replace, \"abc\");\n    assert(i == 0);\n\n    i = cmp(tvp[0].pattern, \"(a)\\\\1\");\n    assert(i == 0);\n    i = cmp(tvp[1].replace, \"abc\");\n    assert(i == 0);\n\n    //printf(\"finish\\n\");\n}\n\n/* ================================ */\n\nconst uint WSABASEERR            = 10000;\nconst uint WSAENOTCONN           = (WSABASEERR+57);\n\nvoid test8()\n{\n switch (10057)\n {\n  case WSAENOTCONN:\n   break;\n  default:\n   assert(0);\n }\n}\n\n/* ================================ */\n\n\nalias T9* PPixel;\nalign(1) struct TAG\n{\n    int foo;\n}\nalias TAG T9;\nalias TAG Pixel;\n\n\nvoid func9(PPixel x)\n{\n}\n\nvoid test9()\n{\n    Pixel p;\n    func9(&p);\n}\n\n/* ================================ */\n\n\nstring[] colors10 = [ \"red\", \"green\", \"blue\" ];\n\nvoid test10()\n{\n    printf(\"test10()\\n\");\n\n    int i;\n\n    i = cmp(colors10[0], \"red\");\n    assert(i == 0);\n}\n\n/* ================================ */\n\nconst uint MAX_PATH1 = 260;\nenum { MAX_PATH2 = 261 }\n\nstruct WIN32_FIND_DATA {\n    char[MAX_PATH1]   cFileName1;\n    char[MAX_PATH2]   cFileName2;\n}\n\nvoid test11()\n{\n}\n\n/* ================================ */\n\n\ninterface IPersistent\n{\n int store(Object);\n int retrieve(Object);\n}\n\nclass Persistent: IPersistent\n{\n int store(Object n) { return 1; }\n int retrieve(Object n) { return 2; }\n}\n\nvoid func12(IPersistent p)\n{\n    Object o = new Object();\n    assert(p.store(o) == 1);\n    assert(p.retrieve(o) == 2);\n}\n\nvoid test12()\n{\n    Persistent p = new Persistent();\n    Object o = new Object();\n    assert(p.store(o) == 1);\n    assert(p.retrieve(o) == 2);\n\n    func12(p);\n}\n\n/* ================================ */\n\nclass X13 { }\n\nclass A13\n{\n     X13 B(X13 x, out int i)\n     {\n        i = 666;\n        return new X13;\n     }\n\n     X13 B(X13 x)\n     {\n        int j;\n        return B(x, j);\n     }\n}\n\nvoid test13()\n{\n    A13 a;\n    X13 x;\n    int i;\n\n    a = new A13();\n    x = a.B(x, i);\n    assert(i == 666);\n}\n\n/* ================================ */\n\nvoid foo14() { }\n\nint testx14(int x)\n{\n    try\n    {\n        return 3;\n    }\n    finally\n    {\n        foo14();\n    }\n}\n\nclass bar\n{\n    int y;\n    synchronized int sync(int x)\n    {\n        printf(\"in sync(%d) = %d\\n\", x, y + 3);\n        return y + 3;\n    }\n}\n\nvoid test14()\n{\n    auto b = new shared(bar)();\n    int i;\n    i = b.sync(4);\n    printf(\"i = %d\\n\", i);\n    assert(i == 3);\n\n    assert(testx14(7) == 3);\n}\n\n/* ================================ */\n\n/+\nint foo15(int i)\n{\n    switch (i)\n    {\n        case 7:\n        case 8:\n            return i;\n    }\n    return 0;\n}\n\nvoid test15()\n{\n    int i = 0;\n    try\n    {\n        foo15(3);\n    }\n    catch (SwitchError sw)\n    {\n        //printf(\"caught switch error\\n\");\n        i = 1;\n    }\n    assert(i == 1);\n}\n+/\n\n/* ================================ */\n\n\nstruct GUID {          // size is 16\n    align(1):\n        uint     Data1;\n        ushort   Data2;\n        ushort   Data3;\n        ubyte[8] Data4;\n}\n\n\nGUID CLSID_Hello = { 0x30421140, 0, 0, [0xC0,0,0,0,0,0,0,0x46] };\nGUID IID_IHello  = { 0x00421140, 0, 0, [0xC0,0,0,0,0,0,0,0x46] };\n\nint testa()\n{\n    return CLSID_Hello == IID_IHello;\n}\n\nint testb()\n{\n    return CLSID_Hello != IID_IHello;\n}\n\nint testc()\n{\n    return CLSID_Hello == IID_IHello ? 5 : 3;\n}\n\nint testd()\n{\n    return CLSID_Hello != IID_IHello ? 7 : 9;\n}\n\nvoid test16()\n{\n    assert(testa() == 0);\n    assert(testb() == 1);\n    assert(testc() == 3);\n    assert(testd() == 7);\n}\n\n\n/* ================================ */\n\nvoid test17()\n{\n    creal z = 1. + 2.0i;\n\n    real r = z.re;\n    assert(r == 1.0);\n\n    real i = z.im;\n    assert(i == 2.0);\n\n    assert(r.im == 0.0);\n    assert(r.re == 1.0);\n\n    assert(i.re == 2.0);\n    assert(i.im == 0.0i);\n}\n\n/* ================================ */\n\nprivate const uint[256] crc_table = [\n    0x00000000u, 0x77073096u, 0xee0e612cu, 0x990951bau, 0x076dc419u,\n    0x2d02ef8du\n  ];\n\npublic const(uint)[] get_crc_table()\n{\n  return crc_table;\n}\n\nvoid test18()\n{\n    const(uint)[] c;\n\n    c = get_crc_table();\n    assert(c[3] == 0x990951bau);\n}\n\n/* ================================ */\n\nint[0xffff] foo19;\n\nvoid test19()\n{\n    int i;\n\n    for (i = 0; i < 0xffff; i++)\n        assert(foo19[i] == 0);\n}\n\n/* ================================ */\n\n\nextern (Windows) int cfw(int x, int y)\n{\n    return x * 10 + y;\n}\n\nextern (C) int cfc(int x, int y)\n{\n    return x * 10 + y;\n}\n\nextern (Pascal) int cfp(int x, int y)\n{\n    return x * 10 + y;\n}\n\nint cfd(int x, int y)\n{\n    return x * 10 + y;\n}\n\n\nextern (Windows) int function (int, int) fpw;\nextern (C) int function (int, int) fpc;\nextern (Pascal) int function (int, int) fpp;\nint function (int, int) fpd;\n\nvoid test20()\n{\n    printf(\"test20()\\n\");\n    int i;\n\n    fpw = &cfw;\n    fpc = &cfc;\n    fpp = &cfp;\n    fpd = &cfd;\n\n//printf(\"test w\\n\");\n    i = (*fpw)(1, 2);\n    assert(i == 12);\n\n//printf(\"test c\\n\");\n    i = (*fpc)(3, 4);\n    assert(i == 34);\n\n//printf(\"test p\\n\");\n    i = (*fpp)(5, 6);\n    assert(i == 56);\n\n//printf(\"test d\\n\");\n    i = (*fpd)(7, 8);\n    assert(i == 78);\n}\n\n\n/* ================================ */\n\nvoid test21()\n{\n    ireal imag = 2.5i;\n    printf (\"test of imag*imag = %Lf\\n\",imag*imag);\n    assert(imag * imag == -6.25);\n}\n\n/* ================================ */\n\nvoid test22()\n{\n    creal z1 = 1. - 2.0i;\n    ireal imag_part = z1.im/1i;\n}\n\n\n/* ================================ */\n\nint def23(int x, int y)\n{\n    return x * y;\n}\n\nstruct Foo23\n{\n    int a = 7;\n    int b = 8;\n    int c = 9;\n\n    int abc()\n    {\n        def23(3, 4);\n        a *= b;\n        bar();\n        return a;\n    }\n\n    int bar()\n    {\n        a *= 2;\n        return a;\n    }\n\n    invariant()\n    {\n        assert(c == 9);\n    }\n}\n\nvoid test23()\n{\n    Foo23 f;\n    int i;\n\n    assert(f.a == 7 && f.b == 8);\n    i = f.abc();\n    assert(i == 112);\n}\n\n/* ================================ */\n\nstruct Foo24\n{\n        int x, y;\n        int[] z;\n}\n\nvoid test24()\n{\n    assert(Foo24.z.offsetof == 8);\n}\n\n/* ================================ */\n\nvoid test27()\n{\n    static real[1] n = [ -1 ];\n    //printf(\"%Le\\n\", n[0]);\n    assert(n[0] == -1.0);\n}\n\n/* ================================ */\n\nint x29;\n\nclass Foo29\n{\n    ~this()\n    {\n        x29 = bar();\n    }\n\n    int bar()\n    {\n        return 3;\n    }\n}\n\n\nvoid test29()\n{\n    printf(\"test29()\\n\");\n\n    Foo29 f = new Foo29();\n\n    delete f;\n    assert(x29 == 3);\n}\n\n/* ================================ */\n\n\nstruct GC30\n{\n    static ClassInfo gcLock;\n\n    invariant()\n    {\n    }\n\n    void *malloc()\n    {   void *p;\n\n        synchronized (gcLock)\n        {\n            p = test();\n            if (!p)\n                return null;\n        }\n        return p;\n    }\n\n    void *test() { return null; }\n}\n\nvoid test30()\n{\n    printf(\"test30()\\n\");\n    GC30 gc;\n\n    GC30.gcLock = Object.classinfo;\n    assert(gc.malloc() == null);\n}\n\n\n/* ================================ */\n\nvoid test31()\n{\n    char[14] foo;\n    char[] bar;\n    int i = 3;\n\n    while (i--)\n        bar = foo;\n}\n\n/* ================================ */\n\n\n\nreal foo32()\n{\n    return 4 % 1.0;\n}\n\nvoid test32()\n{\n    assert(foo32() == 0);\n}\n\n/* ================================ */\n\nvoid test33()\n{\n    char[8] foo;\n\n    foo[] = \"12345678\";\n    assert(foo[7] == '8');\n}\n\n\n/* ================================ */\n\nvoid foo34(int[] a)\n{\n    //printf(\"a.length = %d\\n\", a.length);\n    assert(a.length == 5);\n    assert(a[0] == 11);\n    assert(a[1] == 22);\n    assert(a[2] == 33);\n    assert(a[3] == 44);\n    assert(a[4] == 55);\n}\n\nvoid test34()\n{\n    printf(\"test34()\\n\");\n\n    static int[5] x = [11,22,33,44,55];\n    int[] y;\n    int* z;\n\n    foo34(x);\n\n    y = x;\n    foo34(y);\n\n    z = x.ptr;\n    foo34(z[0..5]);\n}\n\n/* ================================ */\n\nclass X35\n{\n    final synchronized void foo()\n    {\n        for(;;)\n        {\n            break;\n        }\n    }\n}\n\nvoid test35()\n{\n    auto x = new shared(X35);\n\n    x.foo();\n}\n\n\n/* ================================ */\n\nvoid test36()\n{\n    synchronized\n    {\n    }\n}\n\nvoid test36b() @nogc nothrow\n{\n    synchronized\n    {\n    }\n}\n\n/* ================================ */\nint test37()\n{\n       string one = \"1\";\n       debug printf(\"pre\\n\");\n       int N = atoi(one.ptr);\n       assert(N == 1);\n       return 0;\n}\n\n\n/* ================================ */\n\nvoid test39()\n{\n        char[] array;\n        array.length=4;\n        char letter = 'a';\n        array[0..4]=letter;\n        assert(array[0]=='a');\n        assert(array[1]=='a');\n        assert(array[2]=='a');\n        assert(array[3]=='a');\n}\n\n/* ================================ */\n\nint dummyJob;\n\nint dummy()\n{\n        return ++dummyJob;\n}\n\nvoid bar40(){\n        return cast(void)dummy();\n}\n\nint foo40()\n{\n        bar40();\n        return dummyJob-1;\n}\n\nvoid test40()\n{\n    assert(foo40() == 0);\n}\n\n/* ================================ */\n\nint status;\n\nvoid check()\n{\n        assert(status==1);\n        void main(int dummy){\n                assert(status==3);\n                status+=5;\n        }\n        status+=2;\n        assert(status==3);\n        main(2);\n        assert(status==8);\n        status+=7;\n}\n\nvoid test41()\n{\n        status++;\n        assert(status==1);\n        check();\n        assert(status==15);\n}\n\n/* ================================ */\n\nvoid test42()\n{\n    real[10] array;\n    real[] copy = array.dup;\n}\n\n/* ================================ */\n\nvoid test43()\n{\n    string s;\n\n    s = __FILE__; printf(\"file = '%.*s'\\n\", s.length, s.ptr);\n    printf(\"line = %d\\n\", __LINE__);\n    s = __DATE__; printf(\"date = '%.*s'\\n\", s.length, s.ptr);\n    s = __TIME__; printf(\"time = '%.*s'\\n\", s.length, s.ptr);\n    s = __TIMESTAMP__; printf(\"timestamp = '%.*s'\\n\", s.length, s.ptr);\n}\n\n/* ================================ */\n\nvoid test44()\n{\n    int[] a;\n    int i;\n\n    a.length = 6;\n    a = a[0 .. $ - 1];\n    assert(a.length == 5);\n}\n\n/* ================================ */\n\nalias int MyInt;\n\nvoid test45()\n{\n        MyInt test(string c=\"x\"){\n                return 2;\n        }\n        assert(test(\"abc\")==2);\n}\n\n/* ================================ */\n\nint status46;\n\nclass Check46\n{\n        void sum(byte[] b){\n                status46++;\n        }\n\n        void add(byte b){\n                assert(0);\n        }\n\n        alias sum write;\n        alias add write;\n\n        void test(){\n                byte[] buffer;\n                write(buffer);\n        }\n}\n\n\nvoid test46()\n{\n        Check46 c = new Check46();\n        status46=0;\n        assert(status46==0);\n        c.test();\n        assert(status46==1);\n}\n\n/* ================================ */\n\nint status47;\n\nint foo47(int arg)\n{\nloop:\n    while(1)\n    {\n        try\n        {\n            try\n            {\n                if (arg == 1)\n                {\n                    break loop;\n                }\n            }\n            finally\n            {\n                assert(status47==0);\n                status47+=2;\n            }\n\n            try\n            {\n                assert(0);\n            }\n            finally\n            {\n                assert(0);\n            }\n        }\n        finally\n        {\n            assert(status47==2);\n            status47+=3;\n        }\n        assert(0);\n        return 0;\n    }\n    return -1;\n}\n\nvoid test47()\n{\n        assert(status47 == 0);\n        assert(foo47(1) == -1);\n        assert(status47 == 5);\n}\n\n/* ================================ */\n\nint status48;\n\nint foo48(int arg)\n{\n\nloop:\n    while(1){\n        try{\n            try{\n                if(arg == 1)\n                {\n                    break loop;\n                }\n            }finally{\n                assert(status48==0);\n                status48+=2;\n            }\n        }finally{\n            assert(status48==2);\n            status48+=3;\n        }\n        return 0;\n    }\n    return -1;\n}\n\nvoid test48()\n{\n    assert(status48 == 0);\n    assert(foo48(1) == -1);\n    assert(status48 == 5);\n}\n\n/* ================================ */\n\nint getch49()\n{\n        return 0;\n}\n\nvoid writefln49(...)\n{\n}\n\nclass Cout{\n        Cout set(int x){\n                return this;\n        }\n        alias set opShl;\n}\n\nvoid test49()\n{\n        Cout cout = new Cout;\n        cout << 5 << 4;\n        writefln49,getch49;\n}\n\n/* ================================ */\n\nstruct S50{\n        int i;\n}\n\nclass C50{\n        static S50 prop(){\n                S50 s;\n                return s;\n        }\n\n        static void prop(S50 s){\n        }\n}\n\nvoid test50()\n{\n        C50 c = new C50();\n        c.prop = true ? C50.prop : C50.prop;\n        assert(c.prop.i == 0);\n        c.prop.i = 7;\n        assert(c.prop.i != 7);\n}\n\n/* ================================ */\n\nvoid func1()\n{\n        static class foo {\n                public int a;\n        }\n}\n\nvoid test51()\n{\n        static class foo {\n                public int b;\n        }\n\n        foo bar = new foo();\n        bar.b = 255;\n}\n\n/* ================================ */\n\nstruct S52\n{\n        int i;\n}\n\nconst int a52 = 3;\nconst S52 b52 = { a52 };\nconst S52 c52 = b52;\n\nvoid test52()\n{\n    assert(c52.i == 3);\n}\n\n/* ================================ */\n\nconst int c53 = b53 + 1;\nconst int a53 = 1;\nconst int b53 = a53 + 1;\n\nvoid test53()\n{\n        assert(a53==1);\n        assert(b53==2);\n        assert(c53==3);\n}\n\n/* ================================ */\nvoid test54()\n{\n        int status=0;\n\n        try\n        {\n                try\n                {\n                        status++;\n                        assert(status==1);\n                        throw new Exception(\"first\");\n                }\n                finally\n                {\n                        printf(\"finally\\n\");\n                        status++;\n                        assert(status==2);\n                        status++;\n                        throw new Exception(\"second\");\n                }\n        }\n        catch(Exception e)\n        {\n                printf(\"catch %.*s\\n\", e.msg.length, e.msg.ptr);\n                assert(e.msg == \"first\");\n                assert(e.next.msg == \"second\");\n        }\n        printf(\"success54\\n\");\n}\n\n/* ================================ */\n\nvoid foo55()\n{\n    try\n    {\n        Exception x = new Exception(\"second\");\n        printf(\"inner throw %p\\n\", x);\n        throw x;\n    }\n    catch (Exception e)\n    {\n        printf(\"inner catch %p\\n\", e);\n        printf(\"e.msg == %.*s\\n\", e.msg.length, e.msg.ptr);\n        assert(e.msg == \"second\");\n        //assert(e.msg == \"first\");\n        //assert(e.next.msg == \"second\");\n    }\n}\n\nvoid test55()\n{\n        int status=0;\n        try{\n                try{\n                        status++;\n                        assert(status==1);\n                        Exception x = new Exception(\"first\");\n                        printf(\"outer throw %p\\n\", x);\n                        throw x;\n                }finally{\n                        printf(\"finally\\n\");\n                        status++;\n                        assert(status==2);\n                        status++;\n                        foo55();\n                        printf(\"finally2\\n\");\n                }\n        }catch(Exception e){\n                printf(\"outer catch %p\\n\", e);\n                assert(e.msg == \"first\");\n                assert(status==3);\n        }\n        printf(\"success55\\n\");\n}\n\n/* ================================ */\n\nvoid test56()\n{\n    assert('\\&sup2;'==178);\n    assert('\\&sup3;'==179);\n    assert('\\&sup1;'==185);\n    assert('\\&frac14;'==188);\n    assert('\\&frac12;'==189);\n    assert('\\&frac34;'==190);\n    assert('\\&there4;'==8756);\n}\n\n/* ================================ */\n\nvoid test57()\n{\n  version (D_Bits)\n  {\n    void displayb(char[] name, bit[] x)\n    {\n        writef(\"%-5s: \", name);\n        foreach(bit b; x)\n            writef(\"%d\",b);\n        writefln(\"\");\n    }\n\n    bit[] a;\n    bit[] b;\n\n    a.length = 7;\n    a[0] = 0;\n    a[1] = 1;\n    a[2] = 1;\n    a[3] = 0;\n    a[4] = 0;\n    a[5] = 1;\n    a[6] = 0;\n\n    displayb(\"a\", a);\n\n    b ~= a;\n    displayb(\"b1\", b);\n\n    b ~= a;\n    displayb(\"b2\", b);\n\n    for (int i = 0; i < a.length; i++)\n    {\n        assert(b[i] == a[i]);\n        assert(b[i+7] == a[i]);\n    }\n\n    b.length = 0;\n    b ~= a;\n    displayb(\"b3\", b);\n\n    b.length = b.length + 7;\n    for(int i = 0; i < a.length; i++)\n        b[i+7] = a[i];\n    displayb(\"b4\", b);\n\n    for (int i = 0; i < a.length; i++)\n    {\n        assert(b[i] == a[i]);\n        assert(b[i+7] == a[i]);\n    }\n  }\n}\n\n/* ================================ */\n\ninterface Foo58\n{\n}\n\ninterface Bar58 : Foo58\n{\n}\n\nclass Baz58 : Bar58\n{\n}\n\nObject test58()\n{\n    Bar58 b = new Baz58;\n    return cast(Object)b;\n}\n\n/* ================================ */\n\nfloat x59;\n\nvoid test59()\n{\n    return cast(void)(x59 = -x59);\n}\n\n\n/* ================================ */\n\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    //test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n//    test26();\n    test27();\n//    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test56();\n    test57();\n    test58();\n    test59();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test40.d",
    "content": "// EXTRA_SOURCES: imports/test40a.d\n// PERMUTE_ARGS:\n// REQUIRED_ARGS:\n\nimport std.stdio;\nimport imports.test40a;\n\nclass Foo {\n        mixin Mix;\n}\n\n\nvoid main() {\n        Bar.foobar();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test41.d",
    "content": "// EXTRA_SOURCES: imports/test41a.d\n// PERMUTE_ARGS: -inline -g -O\n\nimport imports.test41a;\nimport core.exception;\n\nint main()\n{\n    try\n    {\n        foo();\n        return 1;\n    }\n    catch (AssertError e)\n    {\n    }\n\n    try\n    {\n        func!(void)();\n        return 1;\n    }\n    catch (AssertError e)\n    {\n    }\n\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test42.d",
    "content": "// REQUIRED_ARGS:\n//\n\nmodule test42;\n\nimport std.stdio;\nimport core.stdc.stdio;\nimport std.string;\nimport core.memory;\n\n/***************************************************/\n\nclass Foo {\n    template myCast(T) {\n        T myCast(U)(U val) {\n            return cast(T) val;\n        }\n    }\n}\n\nvoid test1()\n{\n  Foo foo = new Foo;\n  int i = foo.myCast!(int)(1.0);\n}\n\n/***************************************************/\n\ntemplate A()\n{\n  static T foo(T)(T t) { return 7 + t; }\n}\n\nstruct Bar\n{\n  mixin A!() a;\n}\n\nvoid test2()\n{\n  auto i = A!().foo(1);\n  assert(i == 8);\n  i = Bar.a.foo!(int)(2);\n  assert(i == 9);\n  i = Bar.a.foo(3);\n  assert(i == 10);\n}\n\n/***************************************************/\n\nvoid test3()\n{\n    auto i = mixin(\"__LINE__\");\n    writefln(\"%d\", i);\n    assert(i == 53);\n}\n\n/***************************************************/\n\nclass C4\n{\n    void Stamp(){}\n\n    this() { }\n\n    S4 cursor;\n}\n\nstruct S4\n{\n}\n\nvoid test4()\n{\n}\n\n/***************************************************/\n\nchar a5 = (cast(char[])['a']) [$-1];\n\nvoid test5()\n{\n    assert(a5 == 'a');\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1200\n// One case moved to deprecate1.d\n\nvoid foo6a() {\n        do\n                debug {}\n        while (true);\n}\n\nvoid foo6b() {\n        while (true)\n                debug {}\n}\n\nvoid foo6c() {\n        with (Object.init)\n                debug {}\n}\n\nvoid foo6d() {\n        synchronized debug {}\n}\n\nvoid foo6e() {\n//        volatile debug {}\n}\n\nvoid test6()\n{\n}\n\n/***************************************************/\n\nclass C7 {\n    public this(){\n    }\n}\n\ninterface I7 {\n    void fnc();\n}\n\nvoid test7()\n{\n    char[][] t;\n    foreach( char[] c; t ){\n        new class( c ) C7, I7 {\n            public this( char[] c ){\n                super();\n            }\n            void fnc(){\n            }\n        };\n    }\n}\n\n/***************************************************/\n\nconst ulong[] A8 = ([1LU])[0..$];\n\nvoid test8()\n{\n    assert(A8[0] == 1);\n}\n\n/***************************************************/\n\nvoid test9()\n{\n    writeln(long.max.stringof);\n    writeln(ulong.max.stringof);\n    assert(long.max.stringof == \"9223372036854775807L\");\n    assert(ulong.max.stringof == \"18446744073709551615LU\");\n}\n\n/***************************************************/\n\nconst ulong[] A10 = [1UL];\nconst ulong[] B10 = A10 ~ [1UL];\n\nvoid test10()\n{\n}\n\n/***************************************************/\n\nclass Base11 {\n        private final void foo() {}\n}\n\nclass Derived11 : Base11 {\n        void foo() {}\n}\n\nvoid test11()\n{\n}\n\n/***************************************************/\n\nvoid test12()\n{\n    int[] bar;\n    assert((bar ~ 1).length == bar.length + 1);\n\n    int[][] baz;\n    assert((baz ~ cast(int[])[1]).length == baz.length + 1);\n\n    char[][] foo;\n    assert((foo ~ cast(char[])\"foo\").length == foo.length + 1);\n    assert((cast(char[])\"foo\" ~ foo).length == foo.length + 1);\n\n    printf(\"%d\\n\", (foo ~ cast(char[])\"foo\")[0].length);\n\n    assert((foo ~ [cast(char[])\"foo\"]).length == foo.length + 1);\n\n    char[] qux;\n    assert(([qux] ~ cast(char[])\"foo\").length == [qux].length + 1);\n\n    assert(([cast(dchar[])\"asdf\"] ~ cast(dchar[])\"foo\").length == [cast(dchar[])\"asdf\"].length + 1);\n\n    string[] quux;\n    auto quuux = quux.dup;\n    quuux ~= \"foo\";\n    assert (quuux.length == quux.length + 1);\n}\n\n/***************************************************/\n\nint prop() { return 3; }\n\nvoid test13()\n{\n  auto x = prop;\n  assert(x == 3);\n}\n\n/***************************************************/\n\nvoid recurse(ref int i)\n{\n    int j = i;\n    recurse(j);\n}\n\nvoid test14()\n{\n}\n\n/***************************************************/\n\nvoid bar15(void delegate(int) dg)\n{\n    dg(7);\n}\n\nclass C15\n{\n    int x;\n\n    private void callback(int i)\n    {\n        x = i + 3;\n    }\n\n    void foo()\n    {\n        bar15(&callback);\n        assert(x == 10);\n    }\n}\n\nvoid test15()\n{\n    C15 c = new C15();\n\n    c.foo();\n}\n\n/***************************************************/\n\nvoid bar16(int i, ...) { }\n\nvoid foo16() { }\nvoid foo16(int) { }\n\nvoid test16()\n{\n    bar16(1, cast(void function())&foo16);\n}\n\n/***************************************************/\n\nvoid foo17(char[4] buf, dchar c) { }\nvoid foo17(string s) { }\nvoid foo17(wstring s) { }\n\n\nvoid test17()\n{\n    wstring w;\n    .foo17(w);\n}\n\n/***************************************************/\n\nstruct S18\n{\n  version (Dversion2)\n  {\n    static void opCall(string msg) { assert(0); }\n  }\n    static void opCall() { }\n}\n\nvoid test18()\n{\n    S18();\n}\n\n/***************************************************/\n\nclass C19\n{\n  version (Dversion2)\n  {\n    static void opCall(string msg) { assert(0); }\n  }\n    static void opCall() { }\n}\n\nvoid test19()\n{\n    C19();\n}\n\n/***************************************************/\n\nextern (System) void test20()\n{\n}\n\n/***************************************************/\n\nvoid func21()\n{\n}\n\nint foo21()\n{\n   return *cast(int*)&func21;\n}\n\nvoid test21()\n{\n    foo21();\n}\n\n/***************************************************/\n\nvoid bar22(alias T)()\n{\n        assert(3 == T);\n}\n\nclass Test22\n{\n        int a;\n        mixin bar22!(a);\n}\n\nvoid test22()\n{\n        Test22 t = new Test22();\n        t.a = 3;\n        t.bar22();\n}\n\n/***************************************************/\n\nstatic this()\n{\n   printf(\"one\\n\");\n}\n\nstatic this()\n{\n   printf(\"two\\n\");\n}\n\nstatic ~this()\n{\n   printf(\"~two\\n\");\n}\n\nstatic ~this()\n{\n   printf(\"~one\\n\");\n}\n\nvoid test23()\n{\n}\n\n/***************************************************/\n\nclass Foo24\n{\n    static string gen()\n    {\n        return \"abc\";\n    }\n}\n\nauto s24 = Foo24.gen();\n\nvoid test24()\n{\n    assert(s24 == \"abc\");\n}\n\n/***************************************************/\n\nvoid test25()\n{\n    int[10] arrayA = [0,1,2,3,4,5,6,7,8,9];\n    foreach(int i; arrayA)\n    {\n        writeln(i);\n    }\n}\n\n/************************************/\n\nconst char[][7] DAY_NAME = [\n        DAY.SUN: \"sunday\", \"monday\", \"tuesday\", \"wednesday\",\n          \"thursday\", \"friday\", \"saturday\"\n];\n\nenum DAY { SUN, MON, TUE, WED, THU, FRI, SAT }\n\nvoid test27()\n{\n    assert(DAY_NAME[DAY.SUN] == \"sunday\");\n    assert(DAY_NAME[DAY.MON] == \"monday\");\n    assert(DAY_NAME[DAY.TUE] == \"tuesday\");\n    assert(DAY_NAME[DAY.WED] == \"wednesday\");\n    assert(DAY_NAME[DAY.THU] == \"thursday\");\n    assert(DAY_NAME[DAY.FRI] == \"friday\");\n    assert(DAY_NAME[DAY.SAT] == \"saturday\");\n}\n\n/***************************************************/\n\nvoid test28()\n{\n}\n\n/***************************************************/\n\nstruct C29 {\n\n    C29 copy() { return this; }\n}\n\nvoid foo29(C29 _c) {\n\n    foo29( _c.copy() );\n}\n\nvoid test29() {\n\n    C29 c;\n\n    //foo(c);\n}\n\n/***************************************************/\n\ntemplate Tuple31(T...) { alias T Tuple31; }\nalias Tuple31!(int,int) TType31;\n\nvoid bar31(TType31) {\n}\n\nvoid test31()\n{\n}\n\n/***************************************************/\n\ntemplate Foo32(T : S!(T), alias S)\n{\n    alias int Foo32;\n}\n\nstruct Struct32(T)\n{\n}\n\nvoid test32()\n{\n    Foo32!(Struct32!(int)) f;\n}\n\n/***************************************************/\n\nvoid test33()\n{\n    string a = \"a\";\n    string b = \"b\";\n    string c = a ~ b;\n    assert(c == \"ab\");\n}\n\n/***************************************************/\n\nvoid foo34(in string s)\n{\n    string t = s;\n}\n\nvoid test34()\n{\n}\n\n/***************************************************/\n\nstruct S35\n{\n   string toString()\n   {\n       return \"foo\";\n   }\n}\n\nvoid test35()\n{   S35 s;\n    auto t = typeid(S35);\n    writefln(\"s = %s\", s);\n    writefln(\"s = %s\", t);\n    auto tis = cast(TypeInfo_Struct)t;\n    writefln(\"s = %s\", tis);\n    writefln(\"s = %s\", tis.xtoString);\n    assert(tis.xtoString != null);\n}\n\n/***************************************************/\n\nvoid test36()\n{\n    void[0] x;\n    auto y = x;\n    alias x z;\n}\n\n/***************************************************/\n\ntemplate isStaticArray(T : U[], U)\n{\n    const bool isStaticArray = is(typeof(U) == typeof(T.init));\n}\n\ntemplate isStaticArray(T, U = void)\n{\n    const bool isStaticArray = false;\n}\n\ntemplate isStaticArray(T : T[N], size_t N)\n{\n    const bool isStaticArray = true;\n}\n\nstatic assert (isStaticArray!(int[51]));\nstatic assert (isStaticArray!(int[][2]));\nstatic assert (isStaticArray!(char[][int][11]));\nstatic assert (!isStaticArray!(int[]));\nstatic assert (!isStaticArray!(int[char]));\nstatic assert (!isStaticArray!(int[1][]));\n\nstatic assert(isStaticArray!(void[0]));\n\nvoid test37()\n{\n}\n\n/***************************************************/\n\ntemplate Foo38(T)\n{\n    const bool Foo38 = false;\n}\n\ntemplate Foo38(T : U[N], U, size_t N)\n{\n    const bool Foo38 = true;\n}\n\nvoid test38()\n{\n    static assert (Foo38!(int[51]));\n}\n\n/***************************************************/\n\nvoid test39()\n{\n}\n\n/***************************************************/\n\nvoid test40()\n{\n    static x = [[1.0, 2.0], [3.0, 4.0]]; // works\n    assert(x[0][0] == 1.0);\n    assert(x[0][1] == 2.0);\n    assert(x[1][0] == 3.0);\n    assert(x[1][1] == 4.0);\n\n    auto y = [[1.0, 2.0], [3.0, 4.0]]; // fails\n    assert(y[0][0] == 1.0);\n    assert(y[0][1] == 2.0);\n    assert(y[1][0] == 3.0);\n    assert(y[1][1] == 4.0);\n}\n\n/***************************************************/\n\nalign(16) struct S41\n{\n    int[4] a;\n}\n\nshared int x41;\nshared S41 s41;\n\nvoid test41()\n{\n    printf(\"&x = %p\\n\", &x41);\n    printf(\"&s = %p\\n\", &s41);\n    assert((cast(int)&s41 & 0xF) == 0);\n}\n\n/***************************************************/\n\nint test42(string[] args = null)\n{\n   foreach(p; args){\n      version(dummy) int i;\n   }\n   return 0;\n}\n\n\n/***************************************************/\n\nvoid foo43(float length, byte b)\n{\n//    b /= cast(cfloat) length;\n}\n\nvoid test43()\n{\n}\n\n/***************************************************/\n\nvoid test44()\n{\n    ifloat f = 1.0fi;\n//    f *= 2.0fi; // illegal but compiles\n    writefln(\"%s\", f);\n//    assert(f == 0i);\n}\n\n/***************************************************/\n\nint foo45(int i)\n{\n   if(i==0){\n      return 2;\n   }\n   assert(0);\n}\n\nvoid test45()\n{\n   version (Win32)  // this test fails in -release because asserts will be removed\n   {\n   assert(foo45(0)==2);\n   try{\n      foo45(1);\n   }catch(Throwable){\n      return cast(void)0;\n   }\n   assert(0);\n   }\n}\n\n/***************************************************/\n\n\nvoid va_copy46(out void* dest, void* src)\n{\n    dest = src;\n}\n\nvoid test46()\n{\n}\n\n/***************************************************/\n\nvoid test47()\n{\n    enum { _P_WAIT, _P_NOWAIT, _P_OVERLAY }\n\n    alias _P_WAIT P_WAIT;\n    alias _P_NOWAIT P_NOWAIT;\n}\n\n/***************************************************/\n\nvoid f48(int x)\n{\n    const(char)[] blah = (x == 1 ? \"hello\".dup : \"world\");\n}\n\nvoid test48()\n{\n    f48(1);\n}\n\n/***************************************************/\n\nvoid test49()\n{\n    version(GNU)\n    {\n        assert((25.5).stringof ~ (3.0625).stringof == \"2.55e+13.0625e+0\");\n        assert(25.5.stringof ~ 3.0625.stringof == \"2.55e+13.0625e+0\");\n    }\n    else\n    {\n        assert((25.5).stringof ~ (3.01).stringof == \"25.53.01\");\n        assert(25.5.stringof ~ 3.01.stringof == \"25.53.01\");\n    }\n}\n\n/***************************************************/\n\nclass Ap50\n{\n    ulong size;\n    static uint valuex;\n\n    void update(ubyte input, int i)\n    {\n        valuex =\n            (((size + i) & 1) == 0) ?\n                    0 :\n                    input;\n    }\n}\n\nvoid test50()\n{\n}\n\n/***************************************************/\n\nint* foo51()\n{\n    assert(is(typeof(return) == int*));\n    return null;\n}\n\nvoid test51()\n{\n    foo51();\n}\n\n/***************************************************/\n\ntemplate Foo52(ulong U)\n{\n    int Foo52 = 1;\n}\n\ntemplate Foo52(uint U)\n{\n    int Foo52 = 2;\n}\n\ntemplate Foo52(ubyte U)\n{\n    int Foo52 = 3;\n}\n\n\nvoid test52()\n{\n    const uint u = 3;\n    auto s = Foo52!(u);\n    assert(s == 2);\n}\n\n/***************************************************/\n\nvoid test53()\n{\n    extern int x;\n}\n\n/***************************************************/\n\nvoid func54(string delegate() dg)\n{\n        dg();\n}\n\nvoid test54()\n{\n    string[] k=[\"adf\",\"AsdfadSF\",\"dfdsfassdf\"];\n    foreach(d;k)\n    {\n        printf(\"%.*s\\n\", d.length, d.ptr);\n        string foo() {assert(d!=\"\");return d;}\n        func54(&foo);\n        func54(delegate string() {assert(d!=\"\");return d;});\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1767\n\nclass DebugInfo\n{\n    alias int CVHeaderType ;\n    enum anon:CVHeaderType{ CV_NONE, CV_DOS, CV_NT, CV_DBG }\n}\n\nvoid test55()\n{\n}\n\n/***************************************************/\n\ntemplate T56() { int i; }\n\nstruct S56 {\n    alias T56!() data;\n}\n\nclass C56 {\n    alias T56!() data;\n}\n\nvoid test56()\n{\n    S56.data.i = 3;\n    C56.data.i = 4;\n    assert(S56.data.i == 4);\n}\n\n/***************************************************/\n\nvoid writecrossing(bool goal)\n{\n  writeln(goal?\"escape\":\"return\");\n}\n\nvoid test57()\n{\n    writecrossing(true);\n    writecrossing(false);\n}\n\n/***************************************************/\n\nvoid f58(int n) {}\nvoid g58(char[] s) {}\n\nchar[][] a58;\n\nclass bar58\n{\n        int i;\n\n        void func() {\n                f58(i);\n\n                foreach (s; a58) {\n                        if (s == s){}\n                        if (s[0..0] == \"\" && s[0..0])\n                                g58(s);\n                }\n\n                f58(i);\n        }\n}\n\nvoid test58()\n{\n}\n\n/***************************************************/\n\nvoid test59()\n{\n    int[] array = new int[5];\n    uint check = 0;\n    foreach (it; array.ptr .. array.ptr + array.length) {\n        ++check;\n    }\n    assert(check == array.length);\n}\n\n/***************************************************/\n\nfinal class Foo60()\n{\n    void bar()\n    {\n        int baz;\n        baz = 1;\n    }\n}\n\nvoid test60()\n{\n    auto foo = new Foo60!();\n}\n\n/***************************************************/\n\nclass ZipEntry61\n{\n    ZipEntryInfo61 info;\n    this() {}\n}\nstruct ZipEntryInfo61 {}\n\nvoid test61()\n{\n}\n\n/***************************************************/\n\nvoid test62()\n{\n   int foo() { return 0; }\n   int bar() { return 0; }\n\n   auto t1 = typeid(typeof(foo));\n   auto t2 = typeid(typeof(bar));\n\n   t1.tsize();\n}\n\n/***************************************************/\n\nstruct S63\n{\n    int a;\n    static int foo()\n    {\n        return a.sizeof;\n    }\n}\n\nvoid test63()\n{\n    int x = S63.a.sizeof;\n    assert(x == 4);\n    assert(S63.foo() == 4);\n}\n\n/***************************************************/\n\nstring[] foo64()\n{\n    return [[]];\n}\n\nvoid test64()\n{\n    auto a = foo64();\n    assert(a.length == 1);\n    assert(a[0].length == 0);\n}\n\n/***************************************************/\n\nstring[][] foo65()\n{\n    string[][] result = [];\n    string[] s = [];\n    result ~= [s];\n    return result;\n}\n\nvoid test65()\n{\n    auto s = foo65();\n    assert(s.length == 1);\n    assert(s[0].length == 0);\n}\n\n/***************************************************/\n\nstring[][] foo66()\n{\n    string[] strings = [\"a\",\"bc\"];\n    string [][] result = [];\n    foreach (s; strings)\n    {\n        result ~= [s];\n    }\n    return result;\n}\n\nvoid test66()\n{\n    auto s = foo66();\n    assert(s.length == 2);\n    assert(s[0].length == 1);\n    assert(s[0][0].length == 1);\n    assert(s[1].length == 1);\n    assert(s[1][0].length == 2);\n}\n\n/***************************************************/\n\ntemplate Tuple67(A...)\n{\n    alias A Tuple67;\n}\n\ntemplate Bar67()\n{\n    const s = \"a bar\";\n}\n\nvoid test67()\n{\n    alias Tuple67!(Bar67!()) tuple;\n    static const i = 0;\n    alias tuple[0] bara;\n    alias tuple[i] barb;\n\n    static assert(bara.s == \"a bar\");\n    static assert(barb.s == \"a bar\");\n}\n\n/***************************************************/\n\ntemplate Tuple68(A...)\n{\n    alias A Tuple68;\n}\n\nsize_t foo68()\n{\n    return 1;\n}\n\nvoid test68()\n{\n    alias Tuple68!(\"one\", \"two\") tuple;\n    static assert(tuple[foo68()] == \"two\");\n}\n\n/***************************************************/\n\nclass Base69 {}\n\nclass Da69 : Base69 {}\nclass Db69 : Base69 {}\n\nvoid test69()\n{   int i;\n    auto b = i ? new Da69 : new Db69;\n    assert(is(typeof(b) == Base69));\n}\n\n/***************************************************/\n\nstruct Bar70\n{\n        Bar70[] bars;\n}\n\nvoid test70()\n{\n        Bar70 node;\n}\n\n/***************************************************/\n\ntemplate Foo71(string s)\n{\n    string b = s;\n}\n\nvoid test71()\n{\n    size_t s = Foo71!(\n\"helloabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n~ \"helloabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n~ \"helloabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n~ \"helloabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n~ \"helloabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n~ \"helloabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n~ \"helloabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n~ \"helloabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n~ \"helloabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n~ \"helloabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n~ \"helloabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n~ \"When dealing with complex template tuples, it's very easy to overflow the\nmaximum symbol length allowed by OPTLINK.  This is, simply put, a damn shame,\nbecause it prevents otherwise completely legal code from compiling and linking\nwith DMDWin, whereas it works perfectly fine when using DMDNix or GDC.\nI know that this is neither a simple nor a small issue to fix: either the\nancient, nearly-immutable OPTLINK would have to be modified, or DMDWin would\nhave to be changed to output a more reasonable format, in which case a new\nlinker would probably have to be written.  Until then, this issue should stand\nas a reminder that DMDWin is inherently limited.\nOplink isn't the issue. The OMF file format has a hard limit. This results in\nthe only solutions being: convert DMD to use some other .obj format or have DMD\ndo something else for name mangling.\nIn talking to Walter, the issue is that it's easy to get symbols that have more\ninfo in them than can be fit into the limit. (the limit has already stretched\nby gziping the symbols.)\nThe simple solution I have proposed is to just MD5 (or what not) the symbols.\nThe only issue (besides a vanishingly small chance of a hash collision) is that\nthis looses information so you can't look at a symbol and directly determine\nwhat it was. My answer to that is, who cares? The only place where hashing\nprovides less info than compressing is in a debugger and it can grab the full\nsymbol from a table in the static data segment.\nI suppose as a stopgap measure that'd work fine, and might even be controlled\nby a compiler switch, so that in the general case debugger info wouldn't be\naffected.  And what's more -- the only time these issues come up is with\ntemplates, which a lot of debuggers have serious problems with anyway, so..\nI would set it up as a method of last resort. It wouldn't be used unless the\nsymbol can't be used any other way.\n\"\n        ).b.length;\n}\n\n/***************************************************/\n\nclass B72 { this(bool b, string c){} }\n\nclass C72 : B72\n{\n        this()\n        {\n                alias typeof(super(false,\"hello\")) foo;\n                super(false,\"hello\");\n        }\n}\n\nvoid test72()\n{\n}\n\n/***************************************************/\n\ntemplate Foo73()\n{\n    mixin (\"const int x = 3;\");\n    //const int x = 3;\n\n    static if (x == 3)\n    {\n        pragma(msg, \"success\");\n    }\n}\n\nalias Foo73!() foo73;\n\nvoid test73()\n{\n}\n\n/***************************************************/\n\nalias uint foo74;\n\nvoid simple_func_t(T)(T s, foo74 i)\n{\n    assert(s == \"hello\");\n    assert(i == 3);\n}\n\nvoid test74()\n{\n    simple_func_t(\"hello\", 3);\n}\n\n/***************************************************/\n\nvoid foo75(T)(T[] x ...)\n{\n    assert(x.length == 3);\n    assert(x[0] == 2);\n    assert(x[1] == 3);\n    assert(x[2] == 4);\n    assert(is(T == int));\n}\n\nvoid test75()\n{\n    foo75(2,3,4);\n}\n\n/***************************************************/\n\nvoid delegate(U) Curry(A, U...)(void delegate(A,U) dg,A arg)\n{\n  struct ArgRecord {\n    A arg;\n    typeof(dg) callback;\n\n    void OpCall(U args) { callback(arg,args); }\n  }\n  auto temp = new ArgRecord;\n  temp.arg = arg;\n  temp.callback = dg;\n  return &temp.OpCall;\n}\n\nvoid delegate(A) Seq(A...)(void delegate(A)[] dgs...)\n{\n  return Curry(delegate void(void delegate(A)[] dgs1,A args)\n               {\n                 foreach(dg; dgs1)\n                   dg(args);\n               },\n               dgs);\n}\n\nstruct Foo76\n{\n  void fred(int i) {}\n}\n\nvoid test76()\n{\n  void delegate(int) tmp;\n  auto bob = new Foo76;\n  auto dan = new Foo76;\n\n  tmp = Seq!(int)(&bob.fred);             // this works\n  tmp = Seq!(int)(&bob.fred, &dan.fred);  // this works\n  tmp = Seq      (&bob.fred);             // this doesn't\n  tmp = Seq      (&bob.fred, &dan.fred);  // neither does this\n}\n\n/***************************************************/\n\nint x77;\n\nvoid foo77()\n{\n    x77 = 1;\n\n    static if(true)\n    {\n    }\n    else\n    {\n    }\n}\n\nvoid test77()\n{\n    foo77();\n    assert(x77 == 1);\n}\n\n/***************************************************/\n\nclass Foo78\n{\n  template TBar(T)\n  {\n    T x;                   // Compiles, but is implicitly static\n    void func(T t)   // Ok, non-static member template function\n    { assert(t == 2); assert(this.bar == 42); }\n  }\n  int bar = 42;\n}\n\nvoid test78()\n{\n  alias Foo78 Foo;\n  Foo.TBar!(int).x = 2;\n  //Foo.TBar!(int).func(2); // error, since funcx is not static\n\n  Foo f = new Foo;\n  Foo g = new Foo;\n\n  f.TBar!(int).func(2); // works\n\n  f.TBar!(int).x = 10;\n  g.TBar!(int).x = 20;\n  assert(f.TBar!(int).x == 20); // prints 20\n}\n\n/***************************************************/\n\nclass C79\n{\n}\n\nvoid test79()\n{\n    C79 c = new C79();\n    writeln(c.__vptr);\n    writeln(c.__vptr[0]);\n    writeln(cast(void*)c.classinfo);\n    assert(c.__vptr[0] == cast(void*)c.classinfo);\n    writeln(c.__monitor);\n    assert(c.__monitor == null);\n    synchronized (c)\n    {\n        writeln(c.__monitor);\n        assert(c.__monitor !is null);\n    }\n}\n\n/***************************************************/\n\nclass Test80{\n  template test(){\n    enum int test=1;\n  }\n}\n\nvoid test80()\n{\n  assert(Test80.test!()==1);\n  assert((new Test80).test!()==1);\n}\n\n/***************************************************/\n\nclass Test81\n{\n  static const test2=1;\n  template test(){\n    static const int test=1;\n  }\n}\n\nvoid test81()\n{\n  auto a=new Test81;\n  static assert(typeof(a).test2==1);//ok\n  alias typeof(a) t;\n  static assert(t.test!()==1);//ok\n  static assert(typeof(a).test!()==1);//syntax error\n}\n\n/***************************************************/\n\ndeprecated\n{\n    alias real A82;\n    void foo82(A82 x) {    }\n}\n\nvoid test82()\n{\n}\n\n/***************************************************/\n\nclass Bar83\n{\n    deprecated void foo(int param)\n    {\n    }\n\n    void foo(string param)\n    {\n    }\n}\n\nvoid test83()\n{\n    Bar83 b = new Bar83;\n    string str = \"bar\";\n    b.foo(str);\n}\n\n/***************************************************/\n\nvoid test84()\n{\n    int[0][10] arr;\n    printf(\"%u\\n\", &arr[9] - &arr[0]);\n    auto i = &arr[9] - &arr[0];\n    assert(i == 0);\n}\n\n/***************************************************/\n\nclass myid\n{\n    string buf;\n    this(string str )\n    {\n            buf = str;\n    }\n}\nstruct Lex\n{\n    static myid myidinst;\n    static void Init()\n    {\n            myidinst = new myid(\"abc\");\n    }\n}\n\nvoid test85()\n{\n    Lex.Init();\n    assert(cast(myid)(Lex.myidinst) !is null);\n}\n\n/***************************************************/\n\nstruct Time\n{\n  long ticks;\n}\n\nstruct Stamps\n{\n    Time    created,        /// time created\n            accessed,       /// last time accessed\n            modified;       /// last time modified\n}\n\nStamps getTimeStamps()\n{\n    foreach(i; 0..10) { }\n    Stamps                    time = void;\n\n    time.modified = Time(20);\n    time.accessed = Time(20);\n    time.created  = Time(20);\n    return time;\n}\n\nTime accessed ()\n{\n    foreach(i; 0..10) { }\n    return timeStamps(4).accessed;\n}\n\nStamps timeStamps (int name)\n{\n  return getTimeStamps();\n}\n\nvoid test86()\n{\n\n  assert(accessed().ticks == 20);\n}\n\n/***************************************************/\n\nconst bool foo87 = is(typeof(function void() { }));\nconst bar87      = is(typeof(function void() { }));\n\nvoid test87()\n{\n    assert(foo87 == true);\n    assert(bar87 == true);\n}\n\n/***************************************************/\n\nint function() wrap88(void function()) { return null; }\n\nvoid test88()\n{\n        printf(\"test88\\n\");\n        if (0)\n            wrap88(&test88)();\n}\n\n/***************************************************/\n\nstruct S89\n{\n        static const float[2] z = 3;\n}\n\nclass C89\n{\n        static const float[2] z = 3;\n}\n\nvoid bar89(float f) { assert(f == 3); }\n\nvoid test89()\n{\n        printf(\"test89\\n\");\n        bar89(S89.z[0]);\n        bar89(S89.z[1]);\n        bar89(C89.z[0]);\n        bar89(C89.z[1]);\n}\n\n/***************************************************/\n\nvoid trigger(char[] txt)\n{\n        txt[0] = 'x';\n\n        scope(exit)\n        {\n                txt[0] = 'x';\n        }\n\n        return;\n}\n\nvoid test90()\n{\n}\n\n/***************************************************/\n\nvoid test91()\n{\n    enum ABC { a, b, c }\n    assert(ABC.stringof == \"ABC\");\n}\n\n/***************************************************/\n\nint x92;\n\nint f92() {\n    x92++;\n    return 0;\n}\n\nvoid test92()\n{\n    int[1] a;\n    a[f92()] += 42L;\n    assert(x92 == 1);\n}\n\n/***************************************************/\n\nvoid test93()\n{\n    void foo() { }\n    static assert(is(typeof(1 || foo()) == void));\n    static assert(is(typeof(1 && foo()) == void));\n}\n\n/***************************************************/\n\nvoid foo94(T)()\n{\n}\n\nstruct f94(alias func=foo94!(int))\n{\n}\n\nvoid test94()\n{\n    f94!() myf;\n}\n\n/***************************************************/\n\nstruct X95\n{\n   import core.stdc.stdio;\n}\n\nvoid test95()\n{\n   X95.core.stdc.stdio.printf(\"hello\\n\");\n}\n\n/***************************************************/\n\ntemplate foo96(alias bar)\n{\n    pragma(msg, bar.stringof ~ \" \" ~ typeof(bar).stringof);\n    static assert((bar.stringof ~ \" \" ~ typeof(bar).stringof) == \"myInt int\" ||\n        (bar.stringof ~ \" \" ~ typeof(bar).stringof) == \"myBool bool\");\n    void foo96() {}\n}\n\nvoid test96()\n{\n    int myInt;\n    bool myBool;\n\n    foo96!(myInt)();\n    foo96!(myBool)();\n}\n\n/***************************************************/\n\nvoid test97()\n{\n    const short[] ct = cast(short[]) [cast(byte)1, 1];\n    writeln(ct);\n    assert(ct.length == 2 && ct[0] == 1 && ct[1] == 1);\n\n    short[] rt = cast(short[]) [cast(byte)1, cast(byte)1].dup;\n    writeln(rt);\n    assert(rt.length == 1 && rt[0] == 257);\n}\n\n/***************************************************/\n\nclass Foo98\n{\n    string foo = \"abc\";\n    size_t i = 0;\n\n    void bar()\n    {\n        printf(\"%c\\n\", foo[i]);\n        i++;\n        printf(\"%c\\n\", foo[i]);\n        assert(foo[i] == 'b');\n    }\n}\n\nvoid test98()\n{\n    auto f = new Foo98();\n    f.bar();\n}\n\n/***************************************************/\n\ntemplate implicitlyConverts99(S, T)\n{\n    enum bool implicitlyConverts99 = T.sizeof >= S.sizeof\n        && is(typeof({S s; T t = s;}()));\n}\n\nstatic assert(!implicitlyConverts99!(long, short));\n\nvoid test99()\n{\n}\n\n/***************************************************/\n\nvoid test100()\n{\n    static void check(ulong value)\n    {\n        real r = value;\n        ulong d = cast(ulong)r;\n        printf(\"ulong: %llu => real: %Lg => ulong: %llu\\n\", value, r, d);\n        assert(d == value);\n    }\n\n    // check biggest power of 2 representable in ulong: 2^63\n    check(1L << 63);\n\n    // check biggest representable uneven number\n    static if (real.mant_dig >= 64) // > 64: limited by ulong precision\n        check(ulong.max); // 2^64-1\n    else\n        check((1L << real.mant_dig) - 1);\n}\n\n/***************************************************/\n\nauto e101(int x) { return 5; }\n\nvoid test101()\n{\n    assert(is(typeof(e101(3)) == int));\n}\n\n/***************************************************/\n\nversion(GNU)\n{\nint x103;\n\nvoid external(int a, ...)\n{\n    va_list ap;\n    va_start(ap, a);\n    auto ext = va_arg!int(ap);\n    printf(\"external: %d\\n\", ext);\n    x103 = ext;\n    va_end(ap);\n}\n\nclass C103\n{\n    void method ()\n    {\n        void internal (int a, ...)\n        {\n            va_list ap;\n            va_start(ap, a);\n            auto internal = va_arg!int(ap);\n            printf(\"internal: %d\\n\", internal);\n            x103 = internal;\n            va_end(ap);\n        }\n\n        internal (0, 43);\n        assert(x103 == 43);\n    }\n}\n\nvoid test103()\n{\n    external(0, 42);\n    assert(x103 == 42);\n    (new C103).method ();\n}\n}\nelse version(X86)\n{\nint x103;\n\nvoid external(...)\n{\n    printf(\"external: %d\\n\", *cast (int *) _argptr);\n    x103 = *cast (int *) _argptr;\n}\n\nclass C103\n{\n    void method ()\n    {\n        void internal (...)\n        {\n            printf(\"internal: %d\\n\", *cast (int *)_argptr);\n            x103 = *cast (int *) _argptr;\n        }\n\n        internal (43);\n        assert(x103 == 43);\n    }\n}\n\nvoid test103()\n{\n    external(42);\n    assert(x103 == 42);\n    (new C103).method ();\n}\n}\nelse version(X86_64)\n{\n    pragma(msg, \"Not ported to x86-64 compatible varargs, yet.\");\n    void test103() {}\n}\nelse\n    static assert(false, \"Unknown platform\");\n\n/***************************************************/\n\nclass C104\n{\n    template Bar()\n    {\n    }\n}\n\nstatic assert(!is(typeof(C104.Bar.foo)));\n\nvoid test104()\n{\n}\n\n/***************************************************/\n\ntemplate Templ(T)\n{\n    const char [] XXX = Type.mangleof;\n    alias T Type;\n}\n\nvoid test105()\n{\n    Templ!(int).Type x;\n    auto s = Templ!(int).XXX;\n    writeln(s);\n    assert(s == \"i\");\n}\n\n/***************************************************/\n// rejects-valid 2.012.\n\nclass foo107 {}\nalias foo107 bar107;\nvoid x107()\n{\n   bar107 a = new bar107();\n   bar107 b = new bar107();\n   bool c = (a == b);\n}\n\nvoid test107()\n{\n}\n\n/***************************************************/\n\nstruct Foo108\n{\n    char[] byLine()()\n    {\n        return null;\n    }\n}\n\nvoid test108()\n{   Foo108 foo;\n\n    foreach (char c; foo.byLine)\n    {\n    }\n}\n\n/***************************************************/\n\nvoid test109()\n{\n    double[] x = new double[1];\n    assert(x[0] != 0);\n}\n\n/***************************************************/\n\nvoid test110()\n{\n    struct C {\n        int[0] b;\n    }\n    static C g_c2_ = {  };\n}\n\n/***************************************************/\n\ntemplate Foo111(T...) {\n    alias T Foo111;\n}\n\nvoid test111()\n{\n    auto y = (Foo111!(int) x){ return 0; };\n}\n\n/***************************************************/\n\nbool isNull(string str) {\n        return str is null;\n}\n\nconst bool foo112 = isNull(\"hello!\");\n\nvoid test112()\n{\n    assert(!foo112);\n}\n\n/***************************************************/\n\nvoid test113()\n{\n  for (int j=1; j<2; j++) {\n    int x = (j<0) ? -j : j;\n    int q=0;\n    for (int i=0; i<x; i++) ++q;\n    assert(q!=0);\n  }\n}\n\n/***************************************************/\n\nstruct VariantN\n{\n    static int opCall(int value)\n    {\n        return 0;\n    }\n\n    void foo()\n    {\n        VariantN v;\n        v.bar(42, 5);\n    }\n\n    void bar(int value, int i)\n    {\n        int[2] args = [ VariantN(value), VariantN(i) ];\n    }\n}\n\nvoid test114()\n{\n}\n\n/***************************************************/\n\nclass B115 : A115!(B115) { }\nclass A115(T) { }\n\nvoid test115()\n{\n}\n\n/***************************************************/\n\nstruct Foo116 {\n    this(U...)(U values)  { }\n}\n\nvoid test116()\n{\n  new Foo116;\n}\n\n/***************************************************/\n\nvoid test117()\n{\n    float f = 7;\n    f = f * 2;\n    assert(f == 14);\n\n    double d = 7;\n    d = d * 2;\n    assert(d == 14);\n\n    real r = 7;\n    r = r * 2;\n    assert(r == 14);\n}\n\n/***************************************************/\n\nvoid test118()\n{\n    int foo(real x)\n    {\n        real y = -x*-x;\n        return cast(int)y;\n    }\n\n    auto i = foo(4.0);\n    assert(i == 16);\n}\n\n/***************************************************/\n\nclass A119\n{\n    static class B119 : C119.D { }\n}\n\nabstract class C119\n{\n    static class D { }\n}\n\nvoid test119()\n{\n}\n\n/***************************************************/\n\nclass A120 {\n    class B120 : C120.D { }\n}\n\nclass C120 : E120 {\n    static class D { }\n}\n\ninterface E120 { }\n\nvoid test120()\n{\n}\n\n/***************************************************/\n\nvoid test121()\n{\n    static assert(null is null);\n}\n\n/***************************************************/\n\nT[] find123(alias pred, T)(T[] input) {\n   while (input.length > 0) {\n      if (pred(input[0])) break;\n      input = input[1 .. $];\n   }\n   return input;\n}\n\nvoid test123()\n{\n    int[] a = [ 1, 2, 3, 4, -5, 3, -4 ];\n    find123!(function bool(int i) { return i < 0; })(a);\n}\n\n\n/***************************************************/\n\nstatic assert(!is(typeof((){(){}\n         ;-()\n{};})));\n\n/***************************************************/\n\nstruct Foobar;\n\n/***************************************************/\n\nint test124()\n{   int result;\n    dchar[] aa;\n    alias uint foo_t;\n\n    foreach (foo_t i, dchar d; aa)\n    {\n    }\n    return result;\n}\n\n/***************************************************/\n\nint foo125(int x)\n{\n    while (1)\n    {\n        if (x)\n            return 3;\n        x++;\n    }\n}\n\nvoid test125()\n{\n    foo125(4);\n}\n\n/***************************************************/\n\nint foo126(int x)\n{\n    while (1)\n    {\n        if (x)\n            return 3;\n        x++;\n    }\n    assert(0);\n}\n\nvoid test126()\n{\n    foo126(4);\n}\n\n/***************************************************/\n\nstruct S127(T, int topology = 1)\n{\n    this(T value) { }\n}\n\nvoid cons127(int t)(S127!(int, t) tail)\n{\n}\n\nvoid test127()\n{\n    S127!(int)(1);\n    S127!(int, 1) lst;\n    cons127(lst);\n}\n\n/***************************************************/\n\nstruct S128(T, int topology = 1)\n{\n    this(T value) { }\n}\n\nvoid cons128(int t)(S128!(int, t) tail)\n{\n}\n\nvoid test128()\n{\n    S128!(int, 1)(1);\n    S128!(int) lst;\n    cons128(lst);\n}\n\n/***************************************************/\n\nstruct R129(R : E[], E)\n{\n    E[] forward;\n    static R129 opCall(E[] range)\n    {\n        R129 result = {};\n        result.forward =  range;\n        return result;\n    }\n}\n\nR129!(E[]) retro129(E)(E[] r)\n{\n    return R129!(E[])(r);\n}\n\nint begin129(F)(R129!(F) range)\n{\n    return 0;\n}\n\nvoid test129()\n{\n    int[] a = [ 1, 2, 3 ];\n    auto r = retro129(a);\n    auto i = begin129(r);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12725\n\nstruct R12725(R : E[], E)\n{\n}\n\nint begin12725(F)(R12725!(F) range)\n{\n    return 0;\n}\n\nvoid test12725()\n{\n    R12725!(int[], int) r;\n    auto i = begin12725(r);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12728\n\nstruct Matrix12728(T, uint m, uint n = m, ubyte f = 0)\n{\n    void foo(uint r)(auto ref in Matrix12728!(T, n, r) b)\n    {\n    }\n}\n\nvoid test12728()\n{\n    alias Matrix4 = Matrix12728!(float, 4);\n\n    Matrix4 m;\n    m.foo(m);\n}\n\n/***************************************************/\n\nstruct S130\n{\n  byte[3] x;\n}\n\n__gshared S130 e130;\n\nconst(S130) example130() { return e130; }\n\nvoid test130()\n{\n}\n\n/***************************************************/\n\nvoid foo131(real z) {}\n\nvoid test131()\n{\n    real F = 1;\n    foo131( 1 + (F*3*2.1) );\n}\n\n/***************************************************/\n\nfloat getFloat() {\n    return 11468.78f;\n}\n\nvoid test132()\n{\n    uint i = cast(uint) 11468.78f;\n    assert(i == 11468);\n\n    uint j = cast(uint) getFloat();\n    assert(j == 11468);\n}\n\n/***************************************************/\n\ntemplate T133(string s) {\n    const string T133 = s;\n}\n\nstring f133(string s) {\n    return s;\n}\n\nvoid test133()\n{\n    int foo;\n    //writeln(foo.stringof);\n    assert (\"foo\" == f133(foo.stringof));\n    assert (\"foo\" == T133!(foo.stringof));\n}\n\n/***************************************************/\n\npublic struct foo134\n{\n    public this(real aleft)\n    {\n    }\n}\n\nclass bar134\n{\n    final void fun(foo134 arg = foo134(0.)) { }\n}\n\n/***************************************************/\n\nvoid test135()\n{\n    char[char[3]] ac;\n    char[3] c = \"abc\";\n    ac[\"abc\"]='a';\n    assert(ac[c]=='a');\n\n    char[dchar[3]] ad;\n    dchar[3] d = \"abc\"d;\n    ad[\"abc\"d]='a';\n    assert(ad[d]=='a');\n}\n\n/***************************************************/\n\nvoid test136()\n{\n    struct S { int[3] i; }\n    enum S s = S(8);\n    const int i  = s.i[2];\n    assert(i == 8);\n}\n\n/***************************************************/\n\nstruct Particle {\n    char[16] name;\n}\n\nclass ReadSystem {\n    size_t[char[16]] pKindsIdx;\n\n    void t(Particle p)\n    {   auto idx=p.name in pKindsIdx;\n    }\n}\n\nvoid test137()\n{\n    char[16] n;\n    size_t[char[16]] aa;\n    auto r=n in aa; // works\n}\n\n/***************************************************/\n\nlong test138(int y)\n{\n    return *cast(long*)(&y);\n}\n\n/***************************************************/\n\nvoid test139()\n{\n   auto famousNamedConstants =\n    [ \"pi\" : 3.14, \"e\" : 2.71, \"moving sofa\" : 2.22 ];\n\n    assert(famousNamedConstants[\"e\"]==2.71);\n}\n\n/***************************************************/\n\nint* get140()  {  return (new int[4]).ptr; }\n\nvoid test140()\n{\n  int* p = get140();\n  p[0..3] = 0;\n  p[0] = 7;\n}\n\n/***************************************************/\n\nclass Foo141 {\n    Foo141 next;\n    void start()\n    in { assert (!next); } body\n    {\n        void* p = cast(void*)this;\n    }\n}\n\n/***************************************************/\n\nvoid a142(int b = 1+2)(){};\n\nvoid test142()\n{\n    a142!(1+2)();\n    a142();\n}\n\n/***************************************************/\n\nclass A143\n{\n    invariant() { }\n    void fill() { }\n}\n\n\nclass B143 : A143\n{\n    override void fill() { }\n}\n\nvoid test143()\n{\n    auto b = new B143();\n    b.fill();\n}\n\n/***************************************************/\n\nstruct Pair\n{\n    static Pair opCall(uint a, uint b) { return Pair.init; }\n}\n\nstruct Stack\n{\n    Pair pop() { return Pair.init; }\n}\n\nvoid test144()\n{\n    Stack stack;\n    Pair item = stack.pop;\n}\n\n/***************************************************/\n\nstruct Ashes {\n    int ashes = cast(int)0;\n}\nvoid funky (Ashes s = Ashes()) { }\n\nstruct S145 {\n    real a = 0, b = 0;\n}\n\nvoid func145(S145 s = S145()) { }\n\nvoid test145()\n{\n    funky();\n    func145();\n}\n\n/***************************************************/\n\nstring foo146(T...)(T args)\n{\n    string ret;\n\n    foreach(arg; args) {\n        ret = arg;\n    }\n\n    assert(ret==\"b\"); // passes\n    return ret;\n}\n\nvoid test146()\n{\n    string s = foo146(\"b\");\n    assert(s == \"b\"); // fails\n}\n\n/***************************************************/\n\nvoid test147()\n{\n    string s = \"foo\";\n    dchar c = 'x';\n    s ~= c;\n    assert(s == \"foox\");\n\n    wstring ws = \"foo\";\n    ws ~= c;\n    assert(ws == \"foox\");\n}\n\n/***************************************************/\n\nvoid test148()\n{\n    string a = \"\\U00091234\";\n    string b;\n\n    b ~= \"\\U00091234\";\n\n    if (a != b) {\n            assert(0);\n    }\n}\n\n/***************************************************/\n\nvoid test149()\n{\n  long[1] b = void;\n  b[0] = -1L;\n  b[0] >>>= 2;\n  assert( (b[0]) == 0x3FFFFFFFFFFFFFFFL);\n}\n\n/***************************************************/\n\nbool foo150()\n{\n    int x;\n    return cast(void*) (x & 1) == null;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3521\n\nvoid crash(int x)\n{\n    if (x==200) return;\n\n    version(GNU)\n    {\n        import gcc.builtins;\n        __builtin_trap();\n    }\n    else\n    {\n        asm { int 3; }\n    }\n}\n\nvoid test151()\n{\n   int x;\n   bug3521(&x);\n}\n\nvoid bug3521(int *a){\n    int c = 0;\n    *a = 0;\n    if ( *a || (*a != (c = 200)) )\n       crash(c);\n}\n\n/***************************************************/\n\nstring foo152(T...)() {\n    return \"\";\n}\n\nvoid test152() {\n    foo152!(int, char)();\n}\n\n/***************************************************/\n\nint get_value()\n{\n    return 1;\n}\n\nint[2] array1;\nint[2] array2;\n\nint foo153(ulong a1, ulong extra, ulong extra2, ulong extra3)\n{\n    if (!((a1 & 1) | (get_value() | array1[cast(uint)(a1^1)])))\n        return 0;\n\n    if (0 >= array2[cast(uint)(a1^1)])\n        return 0;\n\n    return 1;\n}\n\nvoid test153()\n{\n    foo153(0, 0, 0, 0);\n}\n\n/***************************************************/\n\nclass B154 : A154\n{\n}\n\nenum SomeEnum\n{\n    EnumMember = 10\n}\n\nclass A154\n{\n    SomeEnum someEnum()\n    {\n        return SomeEnum.EnumMember;\n    }\n}\n\nvoid test154()\n{\n    auto b = new B154();\n    assert(cast(int)b.someEnum == 10);\n}\n\n/***************************************************/\n\nstruct Qwert {\n    Yuiop.Asdfg hjkl;\n}\n\nstruct Yuiop {\n    struct Asdfg {\n        int zxcvb;\n    }\n}\n\n/***************************************************/\n\nvoid f156(Value156.Id t)\n{\n    assert(cast(int)t == 1);\n}\n\nstruct Value156 {\n  public static enum Id {\n    A,\n    B\n  }\n}\n\nvoid test156()\n{\n  Value156.Id t = Value156.Id.B;\n  f156(t);\n}\n\n/***************************************************/\n\nX157 x157;\nenum X157 { Y };\n\ninterface Foo157 {\n    Policy157 fn();\n}\n\nenum Policy157 {Default, Cached, Direct}\n\nvoid test157()\n{\n}\n\n/***************************************************/\n\nclass X158 {\n  Y158.NY t;\n  enum NX { BLA, BLA1 }\n}\n\nclass Y158 {\n  enum NY { FOO, BAR }\n  X158.NX nx;\n}\n\n/***************************************************/\n\nstruct Foo159 {\n    Bar.Baz x;\n\n    struct Bar {\n        struct Baz {}\n    }\n}\n\n/***************************************************/\n\nvoid test160()\n{\n  long[1] b = void;\n  b[0] = -1L;\n  b[0] >>>= 2;\n  assert( (b[0]) == 0x3FFFFFFFFFFFFFFFL);\n  int i = -1;\n  assert(i >>>2 == 0x3FFFFFFF);\n}\n\n/***************************************************/\n\nclass A161 {\n    struct B {\n        D161 x;\n\n        struct C {}\n    }\n}\n\n\nstruct D161 {}\n\nclass C161\n{\n    A a;\n\n    struct A\n    {\n        uint m;\n    }\n\n    enum\n    {\n        E = 0\n    }\n}\n\n/***************************************************/\n\ninterface A162\n{\n    C162 foo();\n    C162 foo() const;\n}\n\nclass B162 : A162\n{\n    C162 foo() { return null; }\n    C162 foo() const { return null; }\n}\n\nabstract class C162 : A162\n{\n    C162 foo() { return null; }\n    C162 foo() const { return null; }\n}\n\n/***************************************************/\n\nvoid func163( A... )( string name, string v )\n{\n}\n\nvoid test163()\n{\n    func163!( int, long, float )( \"val\", \"10\" );\n    func163!()( \"tmp\", \"77\" );\n    alias func163!() TMP; TMP( \"tmp\", \"77\" );\n}\n\n/***************************************************/\n\nclass A164\n{\n    B164 foo() { return null; }\n    B164 foo() const { return null; }\n}\n\nabstract class B164 : A164\n{\n    override final B164 foo() { return null; }\n    override final B164 foo() const { return null; }\n}\n\n/***************************************************/\n\nclass A165\n{\n    B165 foo() { return null; }\n    const(B165) foo() const { return null; }\n}\n\nabstract class B165 : A165\n{\n    override final B165 foo() { return null; }\n    override final const(B165) foo() const { return null; }\n}\n\n/***************************************************/\n\nstruct A166 {\n   B166  xxx;\n   static this () { }\n}\n\nstruct B166 {}\n\n/***************************************************/\n\nvoid x168(T)() {\n    static assert(false);\n}\n\ntemplate y168(T) {\n    const bool y168 = is(typeof( { x168!(T)(); } ));\n}\n\nstatic assert(!y168!(int));\n\n/***************************************************/\n\nvoid test169()\n{\n    int AssociativeArray;\n    int[int] foo;\n    foreach (x; foo)    {    }\n}\n\n/***************************************************/\n\nFwdEnum this_fails;\n\nenum : int\n{\n        E170 =  2\n}\n\nenum FwdEnum : int\n{\n        E2 =  E170\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3740\n\nabstract class Address {\n    abstract int nameLen();\n}\n\nclass Class171 : Address {\n    FwdStruct z;\n\n    struct FwdStruct  {  }\n\n    override int nameLen()    { return 0; }\n}\n\nvoid test171 ()\n{\n    Class171 xxx = new Class171;\n    assert(typeid(Class171).vtbl.length - typeid(Object).vtbl.length == 1);\n}\n\n/***************************************************/\n\nstruct Foo172\n{\n    enum bool BAR = is (typeof({}()));\n    static assert (BAR == is (typeof({}())));\n}\n\n/***************************************************/\n\nconst char[][ 89 ] ENUM_NAME = [ 1:\"N0\" ];\n\nvoid test173()\n{\n    switch(`Hi`.dup) {\n        case ENUM_NAME[1]:\n        default:\n                break;\n    }\n}\n\n/***************************************************/\n\nclass A174 {\n    void x() {  }\n}\n\nclass B174 : A174 {\n    override void x() {\n        assert(0);\n    }\n    final void do_x() {\n        super.x();\n    }\n}\n\nvoid test174()\n{\n    auto b = new B174();\n    b.do_x();\n}\n\n/***************************************************/\n\nvoid badvariadic(...) {}\n\nstatic assert(!is(typeof(mixin(badvariadic()))));\n\n/***************************************************/\n\nstruct Foo176\n{\n    int x;\n}\n\nFoo176 getFoo(Foo176 irrelevant)\n{\n    Foo176 p = Foo176(400);\n    if ( p.x > p.x )\n        return irrelevant;\n    else\n        return p;\n}\n\nvoid test176()\n{\n   assert(getFoo( Foo176(0) ).x == 400);\n}\n\n/***************************************************/\n\nint test177()\n{\n    long[1] c = [0]; // must be long\n\n    int [1] d = [1];\n    int k = 0;\n    if (!d[0])\n       k = 1;\n    k = d[0] + k + k;\n\n    if (c[0]) assert(c[0]);\n\n    return k;\n}\n\n/***************************************************/\n\nstruct S178 {\n    int x;\n\n    template T(int val) {\n        enum S178 T = { val };\n    }\n}\n\nconst x178 = S178.T!(0);\n\n/***************************************************/\n\ndouble[100_000] arr = 0.0;\n\n/***************************************************/\n\nalias ireal BUG3919;\nalias typeof(BUG3919.init*BUG3919.init) ICE3919;\nalias typeof(BUG3919.init/BUG3919.init) ICE3920;\n\n/***************************************************/\n\nstruct S179 {\n    char a, b, c, d;\n}\n\nvoid show(char[] args...) {\n    assert(args[0]=='A');\n    assert(args[1]=='L');\n    assert(args[2]=='D');\n    assert(args[3]=='O');\n}\n\nvoid A179( S179 ss ) {\n    show( ss.a, ss.b, ss.c, ss.d );\n}\n\nvoid test179()\n{\n    S179 ss3;\n    ss3.a = 'A';\n    ss3.b = 'L';\n    ss3.c = 'D';\n    ss3.d = 'O';\n    A179( ss3 );\n}\n\n/***************************************************/\n\nstruct XY { union { int x, y; } }\nstruct AHolder {\n    XY aa;\n    void a(XY x) { aa = x; }\n}\nstruct AB {\n    AHolder aHolder;\n    XY b;\n    void a(XY x) { aHolder.a(x); }\n}\nstruct Main {\n    AB ab;\n\n    void setB() { ab.b = XY(); }\n    void f() {\n        ab.a(XY.init);\n        setB();\n    }\n}\n\n/***************************************************/\n\nvoid fooa181(int x, int y, int[0] a, int z, int t)\n{\n    if (!(x == 2 && y == 4 && z == 6 && t == 8))\n        assert(0);\n}\n\nvoid foob181(int x, int y, int[0] a)\n{\n    if (!(x == 2 && y == 4))\n        assert(0);\n}\n\nvoid fooc181(int[0] a, int x, int y)\n{\n    if (!(x == 2 && y == 4))\n        assert(0);\n}\n\nvoid food181(int[0] a)\n{\n}\n\nvoid test181()\n{\n    int[0] arr = 0;\n    fooa181(2, 4, arr, 6, 8);\n    foob181(2, 4, arr);\n    fooc181(arr, 2, 4);\n    food181(arr);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4042\n\ntemplate isQObjectType(T)\n{\n    enum isQObjectType = is(T.__isQObjectType);\n}\n\ntemplate QTypeInfo(T)\n{\n    static if (!isQObjectType!T)\n    {\n        enum size = T.sizeof;\n    }\n}\n\nstruct QList(T)\n{\n    alias QTypeInfo!T TI;\n    int x;\n\n    void foo()\n    {\n        x++;\n    }\n}\n\nvoid exec(QList!(QAction) actions) {}\n\ninterface IQGraphicsItem\n{\n}\n\nabstract\n        class QGraphicsObject : IQGraphicsItem\n{\n}\n\nclass QGraphicsWidget : QGraphicsObject\n{\n}\n\nclass QAction\n{\n    void associatedGraphicsWidgets(QList!(QGraphicsWidget) a)\n    {\n        QList!(QGraphicsWidget) x;\n    }\n}\n\nvoid test182()\n{\n}\n\n/***************************************************/\n\nenum { a183 = b183() }\n\nint b183() { return 0; }\n\n/***************************************************/\n\nstruct Z184 {\n    int bar = 1;\n    union { Foo184 foo; }\n}\n\nstruct Foo184 { size_t offset = 0;}\n\n/***************************************************/\n\nstruct BB185\n{\n  Item185[1] aa;\n}\n\nstruct CC185\n{\n  Item185 aa;\n}\n\nstruct Item185\n{\n  byte data;\n}\n\n/***************************************************/\n\nconst PM_QS_INPUT = QS_INPUT;\nconst QS_INPUT = 2;\n\n/***************************************************/\n\nalias A187 B187;\nconst int A187 = 1;\n\n/***************************************************/\n\nint foo188(int[3] s)\n{\n    return s[0] + s[1] + s[2];\n}\n\nvoid test188()\n{\n    int[3] t = [1,3,4];\n    auto i = foo188(t);\n    if (i != 8)\n        assert(0);\n}\n\n/***************************************************/\n\ntemplate X189(alias fn) {\n    alias typeof(fn) X189;\n}\n\nvoid a189()(T1189 x) {\n    alias X189!(T1189.foo) P; //line 7\n\n    x.foo();\n}\n\nclass T1189 {\n    void foo() {\n        printf(\"T1.foo()\\n\");\n    }\n}\n\nclass T2189 : T1189 {\n    void bla() {\n        printf(\"T2.blah()\\n\");\n        assert(false); //line 19\n    }\n}\n\nvoid test189() {\n    a189!()(new T2189());\n}\n\n/***************************************************/\n\nvoid test190()\n{\n    string s;\n\n    if (true) scope(exit) s ~= \"a\";\n    if (false) { } else scope(exit) s ~= \"b\";\n    if (true) scope(exit) scope(exit) s ~= \"c\";\n    foreach(x; 1..2) scope(exit) s ~= \"d\";\n    if (true) L1: scope(exit) s ~= \"e\";\n    do scope(exit) s ~= \"f\"; while (false);\n    int i; while (++i == 1) scope(exit) s ~= \"g\";\n    try { } finally scope(exit) s ~= \"h\";\n    assert(s == \"abcdefgh\");\n}\n\n/***************************************************/\n\nstruct S191 {\n  int last = 0;\n  S191 opCall(int i) {\n    printf(\"%d %d\\n\", last, i);\n    assert(i == 1 && last == 0 || i == 2 && last == 1 || i == 3 && last == 1);\n    last = i;\n    return this;\n  }\n}\n\nvoid test191()\n{\n  S191 t;\n  t(1)(2);\n  t(3);\n}\n\n/***************************************************/\n\nenum foo192 {\n    item,\n}\n\n//pragma(msg, foo.mangleof);\nstatic assert(foo192.mangleof == \"E6test426foo192\");\n\n/***************************************************/\n\nvoid test193()\n{\n    enum Shapes\n    {\n        Circle, Square\n    }\n\n    int i;\n    Shapes s;\n\n    pragma(msg, i.stringof);\n    pragma(msg, s.stringof);\n\n    static assert(i.stringof == \"i\");\n    static assert(s.stringof == \"s\");\n}\n\n/***************************************************/\n\nvoid test194()\n{\n    uint[][] b = [[ 1, 2, ]];\n}\n\n/***************************************************/\n\nalias int T195;\n\nclass C195\n{\n    int yum = x195;\n}\n\nconst T195 x195 = 0;\n\n/***************************************************/\n\nunion A196 {\n    double[2] a;\n    double[2] b;\n}\n\nunion B196 {\npublic:\n     double[2] a;\n     double[2] b;\n}\n\nstatic assert(A196.sizeof == B196.sizeof);\n\n/***************************************************/\n\ntemplate Compileable(int z) { bool OK;}\n\nstruct Bug3569 {\n    int bar() { return 7; }\n}\n\nstruct Bug3569b {\n    Bug3569 foo;\n    void crash() {\n        static assert(!is(typeof(Compileable!(foo.bar()))));\n        static assert(!is(typeof(Compileable!((foo = Bug3569.init).bar()))));\n    }\n}\n\nvoid test197()\n{\n}\n\n/***************************************************/\n\nvoid test198()  // https://issues.dlang.org/show_bug.cgi?id=4506\n{\n    int c = 1;\n    for (int k = 0; k < 2; k++) {\n        assert((k == 0 && c == 1) || (k == 1 && c == -1));\n        c *= -1;\n    }\n}\n\n/***************************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=4514\nvoid g199(void delegate(void*, void*) d) { }\n\nstruct X199 {\n    void f(void*, void*) {}\n    void n()\n    {\n        g199(&f);\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4443\n\nstruct Struct4443\n{\n    int x;\n    char[5] unused;\n}\n\nvoid foo4443(Struct4443 *dest, Struct4443[] arr)\n{\n    int junk = arr[$-1].x;\n    if (dest || arr[$-1].x) {\n        *dest = arr[$-1];\n    }\n}\n\nvoid test200()\n{\n    Struct4443[1] a;\n    Struct4443 info;\n    foo4443(&info, a);\n}\n\n/***************************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=2931\n\nstruct Bug2931 {\n    int[4][3] val;\n}\n\nstruct Outer2931 {\n        Bug2931 p = Bug2931(67);  // Applies to struct static initializers too\n        int zoom = 2;\n        int move = 3;\n        int scale = 4;\n}\n\nint bug2931()\n{\n  Outer2931 v;\n  assert(v.move==3);\n  assert(v.scale == 4);\n  return v.zoom;\n}\n\nint bug2931_2()\n{\n  Outer2931 v;\n  Bug2931 w = Bug2931(68);\n  assert(v.move==3);\n  for (int i = 0; i < 4; i++)\n  {\n    for (int j = 0; j < 3; j++)\n    {\n        assert(w.val[j][i] == 68);\n        assert(v.p.val[j][i] == 67);\n    }\n  }\n  assert(v.scale == 4);\n  return v.zoom;\n}\n\nstatic assert(bug2931()==2);\n\nvoid test201() {\n    assert(bug2931()==2);\n    assert(bug2931_2()==2);\n}\n\n\n/***************************************************/\n// This was the original varargs example in std.vararg\n\nimport core.vararg;\n\nvoid foo202(int x, ...) {\n    printf(\"%d arguments\\n\", _arguments.length);\n    for (int i = 0; i < _arguments.length; i++) {\n        int j = va_arg!(int)(_argptr);\n        printf(\"\\t%d\\n\", j);\n        assert(j == i + 2);\n    }\n}\n\nvoid fooRef202(ref int x, ...) {\n    printf(\"%d arguments\\n\", _arguments.length);\n    for (int i = 0; i < _arguments.length; i++) {\n        int j = va_arg!(int)(_argptr);\n        printf(\"\\t%d\\n\", j);\n        assert(j == i + 2);\n    }\n}\n\nvoid test202()\n{\n    foo202(1, 2, 3, 4, 5);\n\n    printf(\"---\\n\");\n\n    int x = 1;\n    fooRef202(x, 2, 3, 4, 5);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1418\n\nclass A203\n{\n    char name = 'A';\n    class B203\n    {\n        char name = 'B';\n    }\n}\n\nvoid test203()\n{\n    class C203\n    {\n    char name = 'C';\n    }\n\n    auto a = new A203;\n    auto b = a.new B203;\n    auto c = new C203;\n\n    writeln(a.tupleof); // prints: A\n    writeln(b.tupleof); // prints: B main.A\n    writeln(c.tupleof); // prints: C 0000\n    assert(a.tupleof.length == 1 && a.tupleof[0] == 'A');\n    assert(b.tupleof.length == 1 && b.tupleof[0] == 'B');\n    assert(c.tupleof.length == 1 && c.tupleof[0] == 'C');\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4516\n\nstruct A204 { B204 b; }\nenum B204 { Z }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4503\n\nclass Collection205(T) { }\nICollection c;\n\nalias Collection205!int ICollection;\n\n/***************************************************/\n\nenum TaskStatus:int { Building=-1, }\n\nTaskStatus test206(char[] s){\n    char[] t=\"TaskStatus\".dup;\n    if (s.length>t.length && s[0..t.length]==t){\n        long res=0;\n        if (s[t.length]=='-') res= -res;        // <= OPnegass\n        return cast(TaskStatus)cast(int)res;\n    }\n    assert(0);\n}\n\n/***************************************************/\n\nstruct UN {   double dd;    long ll; }\nbool cmp( UN * pU ) {   return pU.dd >= pU.ll ? true : false; }\n\nstruct UN2 {  real dd; long ll; }\nbool cmp2( UN2 * pU ) {  return pU.dd >= pU.ll ? true : false; }\n\nstruct UN3 {  double dd; int ll; }\nbool cmp3( UN3 * pU ) {  return pU.dd >= pU.ll ? true : false; }\n\nvoid test207()\n{\n   static UN u = { 10.50, 10 };\n   auto i = cmp(&u);\n   printf( \"%d\\n\", cmp( &u ) );\n   assert(i);\n\n   static UN2 u2 = { 10.50, 10 };\n   i = cmp2(&u2);\n   assert(i);\n\n   static UN3 u3 = { 10.50, 10 };\n   i = cmp3(&u3);\n   assert(i);\n\n   static UN3 u3_1 = { 9.50, 10 };\n   i = cmp3(&u3_1);\n   assert(!i);\n}\n\n/***************************************************/\n\ntemplate fail4302() {\n    static assert(0);\n}\ntemplate bug4302() {\n   alias fail4302!() bad;\n}\nstatic if (is(bug4302!())) {}\n\n/***************************************************/\n\ntemplate tough4302()\n{\n  template bar()\n  {\n     template far()\n     {\n         static assert(0);\n     }\n     alias far!() par;\n  }\n  static if (is(bar!())) {}\n}\n\nalias tough4302!() tougher;\n\n/***************************************************/\n\ntemplate Bug6602A(T) {\n  Bug6602B!(T).Result result;\n}\n\ntemplate Bug6602B(U) {\n  static assert(is(U == int));\n  alias bool Result;\n}\n\nenum bug6602Compiles = __traits(compiles, Bug6602A!short);\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3493\n\nconst bar209 = foo209;\nconst int * foo209 = null;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3418\n\nvoid test210()\n{\n    ulong a = 1;\n    a = cast(ulong)(a * 2.0L);\n}\n\n/***************************************************/\n\nstatic assert(!is(typeof(Object.tupleof[2000]=0)));\n\n/***************************************************/\n\nstruct Ghost {}\n\nvoid bug4430(T)(int x)   {}\nvoid bug4430(T)(Ghost x) {}\n\nvoid test212()\n{\n    bug4430!(char)( 777 );\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4768\n\nstruct A213 { B213 b; }\nenum B213 { Z213 = 2 }\n\nvoid test213()\n{\n   A213 x;\n   assert(x.b == 2);\n}\n\n/***************************************************/\n\nvoid g214(int j) { }\n\nvoid test214()\n{\n    struct S\n    {\n        int i;\n        void f() { g214(i); }\n    }\n    auto s = S();\n}\n\n/***************************************************/\n\ntemplate Q(s...) { alias s q; }\n\nvoid test215()\n{\n    class C {}\n    enum assocarrayliteral = Q!( [1:2] ).q.stringof;\n    enum complex80 = Q!( 1+1.0i ).q.stringof;\n    //enum dottype = Q!( C.Object.toString ).q.stringof;\n    enum halt = 0.stringof;    // ICE w/ -release\n    //enum remove = Q!( [1:2].remove(1) ).q.stringof;\n    enum templat = Q!( Q ).q.stringof;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4941\n\ntemplate T216(_...) { alias _ T216; }\nsize_t mid216(size_t n) { return n/2; }\n\nalias T216!(int, int)[0 .. mid216($)] A216;\nalias T216!(1, 2, 3)[0 .. mid216($)] B216;\n\nvoid test216()\n{\n    T216!(int, int, int) values;\n    auto slice = values[0 .. mid216($)];   // C\n}\n\n/***************************************************/\n\nint bug4529a() { return 0; }\nint function() bug4529b;\nauto ivorBomb1 = typeid(typeof(bug4529a));\nauto ivorBomb2 = typeid(typeof(bug4529b));\n\n/***************************************************/\n\nvoid bug5218c(char [3] s) {}\nvoid bug5218w(wchar [3] s) {}\nvoid bug5218d(dchar [3] s) {}\n\nvoid test217()\n{\n    bug5218c(\"abc\");\n    bug5218w(\"abc\"w);\n    bug5218d(\"abc\"d);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2954\n\nvoid test218()\n{\n    char[char[3]] ac;\n    char[3] c = \"abc\";\n    ac[\"abc\"]='a';\n    assert(ac[c]=='a');\n\n    char[dchar[3]] ad;\n    dchar[3] d = \"abc\"d;\n    ad[\"abc\"d]='a';\n    assert(ad[d]=='a');\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2206\n\ntemplate T219(U) {\n  class C {}\n}\n\nvoid test219()\n{\n  mixin T219!(int); // using a named mixin here fixes it\n\n  pragma(msg, T219!(int).C.mangleof);\n  pragma(msg, C.mangleof); // incorrectly outputs the same as above\n\n  assert(T219!(int).C.classinfo !is C.classinfo); // fails\n  assert(T219!(int).C.mangleof != C.mangleof); // fails\n}\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2206\n\nclass D220 {}\n\ntemplate T220(U) {\n  class C { this() { } }\n}\n\nvoid test220()\n{\n  mixin T220!(int);\n\n  // all print 8\n  writeln(T220!(int).C.classinfo.initializer.length);\n  writeln(C.classinfo.initializer.length);\n  writeln(D220.classinfo.initializer.length);\n\n  auto c = new C; // segfault in _d_newclass\n}\n\n/***************************************************/\n\nconst struct S5110\n{\n    static int value;\n}\n\nstatic assert(is(typeof(S5110.value) == int));\n\n/***************************************************/\n\nclass C5110\n{\n override:\n    string toString() { return \"\"; }\n\n    class Nested\n    {\n        void gun() {}\n    }\n}\n\n/***************************************************/\n\nimmutable class Bug5504\n{\n    void foo(T)(T a) {}\n    template xx(X) {\n        void hoo(T)(T a) {}\n    }\n}\n\nshared class Bug5504b\n{\n    void foo(T)(T a) {}\n    template xx(X) {\n        void hoo(T)(T a) {}\n    }\n}\n\nvoid test5504()\n{\n    immutable Bug5504 c;\n    c.foo(10);\n    c.xx!(int).hoo(10);\n    shared Bug5504b d;\n    d.foo(10);\n    d.xx!(int).hoo(10);\n}\n\n/***************************************************/\n\nvoid bug5105() // compilation test -- don't need to run\n{\n    auto c = new shared(C5105);\n    c.foo(10);\n}\n\nsynchronized shared class C5105\n{\n    void foo(T)(T a) {}\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5145\n\ninterface I221{\n    void bla();\n}\n\ninterface J221\n{\n    I221 sync ();\n}\n\nclass A221 : B221\n{\n    final override I221 sync()\n    in { assert( valid ); }\n    body\n    {\n        return null;\n    }\n}\n\nclass B221 : J221\n{\n    override I221 sync()\n    in { assert( valid ); }\n    body\n    {\n        return null;\n    }\n\n    final bool valid()\n    {\n        return true;\n    }\n}\n\n/***************************************************/\n\ntemplate Bug3276(bool B) {\n   static if (B)\n      alias Bug3276!(false) Bug3276;\n   else\n       alias double Bug3276;\n}\n\ntemplate Bug3276_b(alias W) {\n    alias W!(true) Bug3276_b;\n}\n\nalias Bug3276_b!(Bug3276) Bug3276_c;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5294\n\nvoid foo222(int) {}\n\nvoid test222()\n{\n    int count;\n    for (int i = 0; i < 2; i++) {\n        count++;\n        foo222(i * 5 - 6); // comment this out and it makes 2 loops\n    }\n    printf(\"%d\\n\", count); // compile with -O and it prints 1\n    assert(count == 2);\n}\n\n/***************************************************/\n\nvoid foo223(long x,long a,long b,long c,long d,long e,long f)\n{\n    assert(x == 0x123456789ABCDEF0);\n}\n\nvoid test223()\n{\n    foo223(0x123456789ABCDEF0,2,3,4,5,6,7);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4379\n\ntemplate BigTuple(U...) {\n    alias U BigTuple;\n}\n\nalias\nBigTuple!(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n1,1,1,1,1,1) Tuple4379;\n\nvoid test224()\n{\n    foreach(x; Tuple4379) {    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3681\n\npublic final class A3681 {\n    private this() {\n        int i =0;\n        int j = i + 1;\n i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59;\n i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59;\n i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59;\n i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59;\n i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59;\n i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59;\n i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59;\n i = j * 15; j = i * 59; i = j * 15; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15;\n j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; j = i * 59; i = j * 15; j = i * 59;\n i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59;\n i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59; i = j * 15; j = i * 59;\n    }\n}\n\n/***************************************************/\n\nint bug4389()\n{\n    string s;\n    dchar c = '\\u2348';\n    s ~= c;\n    assert(s.length==3);\n    dchar d = 'D';\n    s ~= d;\n    assert(s.length==4);\n    s = \"\";\n    s ~= c;\n    assert(s.length==3);\n    s ~= d;\n    assert(s.length==4);\n    string z;\n    wchar w = '\\u0300';\n    z ~= w;\n    assert(z.length==2);\n    z = \"\";\n    z ~= w;\n    assert(z.length==2);\n    return 1;\n}\n\nstatic assert(bug4389());\n\n// ICE(constfold.c)\nint ice4389()\n{\n    string s;\n    dchar c = '\\u2348';\n    s ~= c;\n    s = s ~ \"xxx\";\n   return 1;\n}\n\nstatic assert(ice4389());\n\n// ICE(expression.c)\nstring ice4390()\n{\n    string s;\n    dchar c = '`';\n    s ~= c;\n    s ~= c;\n   return s;\n}\n\nstatic assert(mixin(ice4390()) == ``);\nstatic assert(mixin(ice4390()) == ``);\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=190\n\nalias int avocado;\nvoid eat(avocado x225 = .x225);\navocado x225;\n\nvoid test225()\n{\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5534\n\nvoid doStuff(byte start, byte end, uint increment = 1U) {\n   auto output = new byte[3];\n\n    size_t count = 0;\n    for(byte i = start; i < end; i += increment) {\n        output[count++] = i;\n    }\n}\n\nvoid test226()  {\n    doStuff(0, 3);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5536\n\nvoid test227()\n{\n  int[] as = [111, 666];\n  as ~= as[$ - 2];\n  assert(as.length == 3);\n  assert(as[2] == 111);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4017\n\nstruct _A\n{\n   uint data;\n}\n\nconst A_SIZE =   (A4017.sizeof);\n\nalias _A A4017;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5455\n\nvoid thrw(Data *s) {\n    throw new Exception(\"xxx\");\n}\n\nstruct Data {\n    Rapper *w;\n    uint n, m;\n}\n\nstruct Rapper {\n    ubyte * dat;\n    ubyte[] con() {\n        return dat[0..1];\n    }\n}\n\nuint jaz(ubyte[] data) {\n    return cast(uint)data.length;\n}\n\nstruct Resp {\n    void set(Data *data, string[] soup) {\n        switch(soup[0]) {\n            default:\n        }\n        uint[] f = [jaz(data.w ? data.w.con[data.n ..data.m] : null), data.m - data.n];\n        thrw(data);\n    }\n}\n\n/**************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5571\n\nvoid test228() {\n    auto b = new bool;\n    printf(\"%p\\n\", b);\n    *b = false;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5572\n\nvoid doSynchronized() {\n    printf(\"In doSynchronized() 1:  %p\\n\", cast(void*) global229);\n    synchronized {\n        printf(\"In doSynchronized() 2:  %p\\n\", cast(void*) global229);\n    }\n}\n\n__gshared Object global229;\n\nvoid test229() {\n    auto local = new Object;\n    global229 = local;\n\n    printf(\"In main() 1:  %p\\t%p\\n\",\n        cast(void*) global229, cast(void*) local);\n    doSynchronized();\n    printf(\"In main() 1:  %p\\t%p\\n\",\n        cast(void*) global229, cast(void*) local);\n\n    assert(cast(void*) global229 == cast(void*) local);\n}\n\n/***************************************************/\n\nstatic immutable real[14] negtab =\n    [ 1e-4096L,1e-2048L,1e-1024L,1e-512L,1e-256L,1e-128L,1e-64L,1e-32L,\n            1e-16L,1e-8L,1e-4L,1e-2L,1e-1L,1.0L ];\nstatic immutable real[13] postab =\n    [ 1e+4096L,1e+2048L,1e+1024L,1e+512L,1e+256L,1e+128L,1e+64L,1e+32L,\n            1e+16L,1e+8L,1e+4L,1e+2L,1e+1L ];\n\nfloat parse(ref string p)\n{\n    printf(\"test1\\n\");\n\n    real ldval = 0.0;\n    int exp = 0;\n    long msdec = 0;\n\n    msdec = 123;\n    exp = 2;\n\n    ldval = msdec;\n    printf(\"ldval = %Lg\\n\", ldval);\n    if (ldval)\n    {\n        uint u = 0;\n        int pow = 4096;\n\n        while (exp > 0)\n        {\n            while (exp >= pow)\n            {\n                ldval *= postab[u];\n                exp -= pow;\n            }\n            pow >>= 1;\n            u++;\n        }\n        while (exp < 0)\n        {\n            while (exp <= -pow)\n            {\n                ldval *= negtab[u];\n                exp += pow;\n            }\n            pow >>= 1;\n            u++;\n        }\n    }\n    return ldval;\n}\n\nvoid test230()\n{\n    float f;\n    string s = \"123e+2\";\n    f = parse( s );\n    //printf(\"f = %g\\n\", f);\n    assert( f == 123e+2f );\n}\n\n/***************************************************/\n\nclass Bug4033 {}\n\nclass Template4033(T) {\n    static assert(is(T : Bug4033));\n}\n\nalias Template4033!(Z4033) Bla;\n\nclass Z4033 : Bug4033 { }\n\n/***************************************************/\n\nstruct Bug4322 {\n    int[1] a = void;\n}\n\nvoid bug4322() {\n    Bug4322 f = Bug4322();\n    Bug4322 g = Bug4322.init;\n}\n\n/***************************************************/\n\nbool bug5672(long v)\n{\n    return  (v & 1) == 1;\n    return  (v & 1) == 1;\n}\n\n/***************************************************/\n\nvoid bug5717()\n{\n    string s, s2;\n    s = \"Привет\";\n    for (int i=0; i<s.length; i++)\n        s2 ~= s[i];\n    assert(s == s2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3086\n\nclass X231 {\n    void a() {}\n    void b(int z, short c) {}\n    void c(int z, short d) {}\n}\n\nvoid test231() {\n    auto z = new X231();\n    TypeInfo a = typeid(typeof(&z.a));\n    TypeInfo b = typeid(typeof(&z.b));\n    TypeInfo c = typeid(typeof(&z.c));\n\n    assert(a !is b, \"1\");\n    assert(a != b, \"2\");\n    assert(b == c, \"3\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4140\n\nconst A232 = [1,2,3];\nconst B232 = A232[1..A232.length];\nconst C232 = A232[1..$];\n\nvoid test232()\n{\n    assert(A232[0] == 1);\n    assert(A232[1] == 2);\n    assert(A232[2] == 3);\n    assert(B232[0] == 2);\n    assert(B232[1] == 3);\n    assert(C232[0] == 2);\n    assert(C232[1] == 3);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1389\n\nvoid test233()\n{\n    int a;\n    mixin(\"a\") = 666;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5735\n\nstruct A234 {}\n\nvoid foo234(bool cond){}\n\nvoid test234()\n{\n    A234 a;\n    int i;\n\n    static assert(!__traits(compiles, assert(a)));      // type A does not have a boolean value\n    static assert(!__traits(compiles, assert(i || a))); // type A does not have a boolean value\n    static assert(!__traits(compiles, assert(0 || a))); // OK\n\n//    if(a) {}        // type A does not have a boolean value\n//    if(i || a) {}   // type A does not have a boolean value\n//    if(0 || a) {}   // type A does not have a boolean value\n\n    static assert(!__traits(compiles, foo234(a)));         // cannot implicitly convert type A to bool\n    static assert(!__traits(compiles, foo234(i || a)));    // OK\n    static assert(!__traits(compiles, foo234(0 || a)));    // OK\n}\n\n\n/***************************************************/\n\nint space() { return 4001; }\n\nvoid oddity4001()\n{\n    const int bowie = space();\n    static assert(space() == 4001); // OK\n    static assert(bowie == 4001);   // doesn't compile\n}\n\n/***************************************************/\n\nint bug3809()\n{\n    version(GNU)\n    {\n        asm { \"\"; }\n    }\n    else\n    {\n        asm { nop; }\n    }\n    return 0;\n}\nstruct BUG3809 { int xx; }\nvoid bug3809b() {\n}\n\n/***************************************************/\n//\n\nvoid bug6184()\n{\n    bool cmp(ref int[3] a, ref int[3] b)\n    {\n        return a is b;\n    }\n\n    static struct Ary\n    {\n        int[3] ary;\n    }\n\n    auto a = new Ary;\n    auto b = new Ary;\n    assert(!cmp(a.ary, b.ary));\n    b = a;\n    assert(cmp(a.ary, b.ary));\n\n    // change high bit of ary address\n    *(cast(size_t*)&b) ^= (1UL << (size_t.sizeof * 4));\n    assert(!cmp(a.ary, b.ary));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6229\n\nint test6229()\n{\n  {\n    ubyte a = 2;\n    ubyte b = 4;\n    b += a;\n  }\n\n    char a = 2;\n    char b = 4;\n    b += a;\n\n    wchar c = 2;\n    wchar d = 4;\n    c /= d;\n\n    return b;\n}\n\n/***************************************************/\n// XMMBug\n\nclass XMMPainter\n{\n  float call()\n  {\n    return sumFloats(0.0f, 0.0f);\n  }\n\n  static float sumFloats(float a, float b)\n  {\n    return a + b;\n  }\n}\n\nvoid test6270()\n{\n  auto painter = new XMMPainter;\n  assert(XMMPainter.sumFloats(20, painter.call()) == 20.0f);\n  auto dg = () { return XMMPainter.sumFloats(0.0f, 0.0f); };\n  assert(XMMPainter.sumFloats(20, dg()) == 20.0f);\n}\n\n/***************************************************/\n\nvoid testrolror(int shift)\n{\n    uint a = 7;\n    uint r;\n    r = (a >> shift) | (a << (int.sizeof * 8 - shift));\n    assert(r == 0x8000_0003);\n    r = (r << shift) | (r >> (int.sizeof * 8 - shift));\n    assert(r == 7);\n}\n\nvoid test236()\n{\n    testrolror(1);\n}\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4460\n\nvoid test237()\n{\n    foreach (s, i; [ \"a\":1, \"b\":2 ])\n    {\n        writeln(s, i);\n    }\n}\n\n\n/***************************************************/\n\nvoid foo238(long a, long b)\n{\n  while (1)             // prevent inlining\n  {\n    long x = a / b;\n    long y = a % b;\n    assert(x == 3);\n    assert(y == 1);\n    break;\n  }\n}\n\nvoid test238()\n{\n    long a, b;\n    a = 10;\n    b = 3;\n    long x = a / b;\n    long y = a % b;     // evaluate at compile time\n    assert(x == 3);\n    assert(y == 1);\n\n    foo238(a, b);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5239\n\nstruct S239 { int x; }\n\nint test239()\n{\n   S239[4] w = void;\n   w[$-2].x = 217;\n   return w[2].x;\n}\n\n\n/***************************************************/\n\nvoid enforce6506b(bool condition, void delegate() m) {\n    assert(!condition);\n}\nvoid toImpl6506b(int value) {\n    void f(){}\n    enforce6506b(value >= 0, &f);\n}\nvoid test6506() {\n    toImpl6506b(-112345);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6505\n\ndouble foo240() {\n    return 1.0;\n}\n\nvoid test240() {\n    double a = foo240();\n    double b = foo240();\n    double x = a*a + a*a + a*a + a*a + a*a + a*a + a*a +\n               a*b + a*b;\n    assert(x > 0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6563\n\nint foo6563(float a, float b, float c, float d, float e, float f, float g, float h)\n{\n    assert(a == 1);\n    return 0; // return something to prevent folding\n}\n\nvoid test6563()\n{\n    auto res = foo6563(1, 1, 1, 1, 1, 1, 1, 1);\n}\n\n/***************************************************/\n\nubyte foo241(ubyte[] data)\n{\n    ubyte a, b, c, d;\n\n    a = data[0];\n    b = data[1];\n    c = data[2];\n    d = data[3];\n\n    c <<= 1;\n    if (c & 0x80)\n        c >>= 1;\n    d <<= 1;\n    if (d & 0x80)\n        d >>= 1;\n\n    return d;\n}\n\nvoid test241()\n{\n    ubyte[4] data;\n    data[3] = 0x40;\n    assert(foo241(data[]) == 0x40);\n    data[3] = 0x20;\n    assert(foo241(data[]) == 0x40);\n}\n\n/***************************************************/\n\nstruct Foo6665\n{\n    double[2][2] dat;\n\n    double foo(size_t i, size_t j)\n    {\n        return dat[i][j] = 0;\n    }\n}\n\nvoid test6665()\n{\n    Foo6665 a;\n}\n\n/***************************************************/\n\ndouble entropy(double[] probs) {\n    double result = 0;\n    foreach (p; probs) {\n        if (!p) continue;\n        result -= p;\n    }\n    return result;\n}\n\n/***************************************************/\n\nlong b5364(long bmax){\n    if(true){\n    }\n    if(bmax >= 0) bmax = -1;\n    return bmax;\n}\n\nvoid test5364()\n{\n    assert(b5364(0) == -1L);\n}\n\n\n/***************************************************/\n\nstruct FPoint {\n  float x, y;\n}\n\nvoid constructBezier(FPoint p0, FPoint p1, FPoint p2, ref FPoint[3] quad) {\n  quad[0] = p0;\n  quad[1] = FPoint(p1.x, p1.y);\n  quad[$-1] = p2;\n}\n\nvoid test6189() {\n  auto p0 = FPoint(0, 0);\n  auto p1 = FPoint(1, 1);\n  auto p2 = FPoint(2, 2);\n\n  // avoid inline of call\n  FPoint[3] quad;\n  auto f = &constructBezier;\n  f(p0, p1, p2, quad);\n\n  assert(quad == [p0, p1, p2]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6997\n\nlong fun6997(long a,long b,long c)\n{\n    return a < b ? a < c ? a : b < c ? b : c : b;\n}\n\nlong baz6997(long a, long b)\n{\n    bool s = (a<0) != (b<0);\n    a = a > 0 ? a : -a;\n    return s ? a : a;\n}\n\nstruct S6997\n{\n    ulong bar, qux;\n    bool c;\n\n    S6997 foo()\n    {\n        if(!c)\n        {\n            long a = baz6997(bar, 0),\n                b = baz6997(bar, 0),\n                c = baz6997(bar, 0);\n            return S6997(fun6997(a,b,c), fun6997(a,b,c));\n        }\n        return S6997();\n    }\n}\n\nvoid test6997()\n{\n    auto x = S6997().foo();\n}\n\n/***************************************************/\n\nubyte foo7026(uint n) {\n  ubyte[5] buf = void;\n  ubyte wsize;\n\n  while (true) {\n    if ((n & ~0x7F) == 0) {\n      buf[wsize++] = cast(ubyte)n;\n      break;\n    } else {\n      buf[wsize++] = cast(ubyte)((n & 0x7F) | 0x80);\n      n >>= 7;\n    }\n  }\n\n  printf(\"%hhu\\n\", wsize);\n  return buf[0];\n}\n\nvoid test7026() {\n    if (foo7026(3) != 3)\n        assert(0);\n}\n\n\n/***************************************************/\n\nvoid test6354()\n{\n    foreach(j; 0 .. 2)\n    {\n        scope(failure) int i = 0;\n\n        ushort left = 0xffU;\n        left <<= (ushort.sizeof - 1) * 8;\n\n        assert((((left & 0xff00U) >> 8) | ((left & 0x00ffU) << 8)) == 0xffu);\n    }\n}\n\n/***************************************************/\n\nstruct S7072\n{\n    this(A)(A args) { }\n}\n\nvoid test7072() {\n   auto s = S7072( null );\n}\n\n/***************************************************/\n\nstruct Point6881\n{\n    float _x, _y;\n\n    void rotateCCW()\n    {\n        float tmp = -_x;\n        _x = _y;\n        _y = tmp;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7212\nvoid foo7212(scope int delegate(int a) dg)\n{\n}\n\nvoid foo7212(bool a)\n{\n}\n\nvoid test7212()\n{\n    foo7212((int a) => a);\n}\n\n/***************************************************/\n\nvoid test242()\n{\n    foreach(v; long.max / 8 .. long.max / 8 + 1)\n    {\n        immutable long t1 = v;\n        long t2 = t1 + t1;\n        t2 *= 1L << 1;\n        assert(t2 > long.max / 4);\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7290\n\nvoid foo7290a(alias dg)()\n{\n    assert(dg(5) == 7);\n}\n\nvoid foo7290b(scope int delegate(int a) dg)\n{\n    assert(dg(5) == 7);\n}\n\nvoid foo7290c(int delegate(int a) dg)\n{\n    assert(dg(5) == 7);\n}\n\nvoid test7290()\n{\n    int add = 2;\n    scope dg = (int a) => a + add;\n\n    // This will break with -dip1000 because a closure will no longer be allocated\n    assert(GC.addrOf(dg.ptr) == null);\n\n    foo7290a!dg();\n    foo7290b(dg);\n    foo7290c(dg); // this will fail with -dip1000 and @safe because a scope delegate gets\n                  // assigned to @system delegate, but no closure was allocated\n}\n\n/***************************************************/\n\nvoid test7367()\n{\n    char a = '\\x00';\n    char b = '\\xFF';\n    assert(a < b);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7375\n\nclass A7375 {}\nclass B7375(int i) : A7375 {}\nclass C7375(int i) : B7375!i {}\n\ntemplate DerivedAlias(int i)\n{\n    alias B7375!i DerivedAlias;\n}\n\nalias DerivedAlias!22 X7375;\n\nvoid test7375()\n{\n    A7375 foo = new C7375!11();\n    assert(cast(B7375!22)foo is null);\n}\n\n/***************************************************/\n\nvoid test6504()\n{\n    for (int i=0; i<3; ++i)\n    {\n/+\n        char[] x2 = \"xxx\" ~ ['c'];\n        if (i == 0)\n            assert(x2[1] == 'x');\n        x2[1] = 'q';\n+/\n    }\n}\n\n/***************************************************/\n\nstruct S7424a\n{\n    @property inout(int) g()() inout { return 7424; }\n    void test1()\n    {\n        int f = g;\n        assert(f == 7424);\n        assert(g == 7424);\n    }\n    void test2() const\n    {\n        int f = g;\n        assert(f == 7424);\n        assert(g == 7424);\n    }\n    void test3() immutable\n    {\n        int f = g;\n        assert(f == 7424);\n        assert(g == 7424);\n    }\n}\nstruct S7425\n{\n    inout(T) g(T)(T x) inout\n    {\n        return x;\n    }\n    void test1()\n    {\n        int f = g(2);\n        assert(f == 2);\n    }\n    void test2() const\n    {\n        double y = g(4.5);\n        assert(y == 4.5);\n    }\n}\nvoid test7424()\n{\n    S7424a s1;\n    s1.test1();\n    s1.test2();\n\n    immutable(S7424a) s2;\n    s2.test2();\n    s2.test3();\n\n    const(S7424a) s3;\n    s3.test2();\n\n    S7425 s4;\n    s4.test1();\n    s4.test2();\n}\n\n/***************************************************/\n\nstruct Logger {\n    static bool info()() {\n        return false;\n    }\n}\n\nvoid test7422() {\n    if (Logger.info()) {\n    }\n}\n\n/***************************************************/\n\nstruct S7502\n{\n    int[0x1000] arr;\n}\n\nS7502 s7502;\n\nvoid test7502()\n{\n    s7502 = s7502.init;\n}\n\n/***************************************************/\n\nvoid nextis(void delegate() dg = {}) {}\n\nvoid test4820() {\n    nextis();\n}\n\n/***************************************************/\n\nvoid test4820_2() {\n\nvoid nextis(void delegate() dg = {}) {}\n    nextis();\n}\n\n/***************************************************/\n\ntemplate T3509(bool b) { static assert (b); }\n\ntemplate Mix3509() { void f() {} }\n\nclass C3509 {\n    alias T3509!(is(typeof(M.f))) U;\n    mixin Mix3509!() M;\n}\n\n/***************************************************/\n\nstruct S3510(int x) {}\n\ntemplate Mix3510() { Sa s; }\n\nclass C3510 {\n    mixin Mix3510!();\n    alias S3510!(0) Sa;\n}\n\n/***************************************************/\n\nstruct Array243(T) if (is(T == bool))\n{\n    struct Range\n    {\n        Array243!bool _outer;\n        ulong _a, _b, _c;\n        ulong _d;\n    }\n\n    Range opSlice()\n    {\n        return Range(this, 0, 3);\n    }\n\n}\n\n\nvoid test243() {\n    Array243!bool a;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7742\n\nstruct Foo7742 {\n    static immutable f = Foo7742(1, 2);\n    int x, y;\n}\n\nstruct Bar7742 {\n    int x, y;\n    static immutable f = Bar7742(1, 2);\n}\n\nvoid test7742()\n{\n    assert(Foo7742.f.x == 1);\n    assert(Foo7742.f.y == 2);\n\n    assert(Bar7742.f.x == 1);\n    assert(Bar7742.f.y == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7807\n\ninterface Interface7807\n{\n    Interface7807 getNext();\n    const(Interface7807) getNext() const;\n}\n\nclass Implementation7807 : Interface7807\n{\n    Implementation7807 getNext()\n    {\n        return this;\n    }\n\n    const(Implementation7807) getNext() const\n    {\n        return null;\n    }\n}\n\nvoid test7807()\n{\n    auto mc = new Implementation7807();\n    assert(mc.getNext() is mc);\n    Interface7807 mi = mc;\n    assert(mi.getNext() is mi);\n\n    auto cc = new const(Implementation7807)();\n    assert(cc.getNext() is null);\n    const(Interface7807) ci = cc;\n    assert(ci.getNext() is null);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7815\n\nenum Closure {\n    Matrix\n}\n\nstruct BasicMatrix {\n    mixin Operand!( Closure.Matrix );\n}\n\ntemplate Operand( Closure closure_ ) {\n    alias closure_ closure;\n}\n\nstruct Expression( string op_, Lhs, Rhs = void ) {\n    enum lhsClosure = closureOf!Lhs;\n}\n\ntemplate closureOf( T ) {\n    enum closureOf = T.closure;\n}\n\nalias Expression!(\"+\", BasicMatrix) Foo7815;\n\n/***************************************************/\n\nstruct Test244 {\n    static immutable c = Test244();\n    static if( true ){}\n}\n\n/***************************************************/\n\nint noswap245(ubyte *data)\n{\n    return\n        (data[0]<<  0) |\n        (data[1]<<  8) |\n        (data[2]<< 16) |\n        (data[3]<< 24);\n}\n\nint bswap245(ubyte *data)\n{\n    return\n        (data[0]<< 24) |\n        (data[1]<< 16) |\n        (data[2]<< 8 ) |\n        (data[3]<< 0 );\n}\n\nvoid test245()\n{\n    int x1 = 0x01234567;\n    x1 = noswap245(cast(ubyte *)&x1);\n    assert(x1 == 0x01234567);\n    x1 = bswap245(cast(ubyte *)&x1);\n    assert(x1 == 0x67452301);\n}\n\n/***************************************************/\n\nmixin template mix7974()\n{\n    uint _x;\n}\n\nstruct Foo7974\n{\n    static immutable Foo7974 fa = Foo7974(0);\n\n    this(uint x)\n    {\n        _x = x;\n    }\n\n    mixin mix7974!();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4155\n\n\nfloat getnanf() { return float.nan; }\ndouble getnand() { return double.nan; }\nreal getnanr() { return real.nan; }\n\nvoid test4155()\n{\n    assert(getnanf() != 0);\n    assert(getnand() != 0);\n    assert(getnanr() != 0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7911\n\nstruct Klass7911\n{\n    double value;\n\n    //static const Klass zero; // Does not trigger bug!\n    static const Klass7911 zero = {0}; // Bug trigger #1\n\n    static if (true) // Bug trigger #2\n        static if (true)\n            Klass7911 foo() { return Klass7911(); }\n}\n\nvoid test7911()\n{\n    auto a = Klass7911().foo();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8429\n\nstatic if(true)\n    version = Foo8429;\nstatic if(true)\n    version(Foo8429) {}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8069\n\ninterface I8069\n{\n    void f();\n}\nstruct A8069\n{\n    final class B8069 : I8069\n    {\n        A8069 a;\n        void f() {}\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8095\n\nvoid bug8095(int p0, int *p1, int z, int edx, int *p4, int p5)\n{\n    int x = z / 3;\n    if (z) {\n        int c = p5 + *p1 + p0; // *p1 segfaults -- it does *z !!\n        if ( z / 5 )\n            c = 1;\n        *p4 = c;\n        x = c;\n    }\n    void never_used() {\n        ++x;\n        int * unused = p1; // kills p4 somehow\n    }\n}\n\nvoid test8095() {\n    int x, y;\n    bug8095(0, &x, 1, 0, &y, 0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8091\n\nint solve1(int n) {\n    int a;\n    return ((a = n ? (n>=1u) : 1) != 0) ? a : 0;\n//    return ((a = !n ? 1 : (n>=1u)) != 0) ? a : 0;\n}\n\nint solve2(int n) {\n    int a;\n//    return ((a = n ? (n>=1u) : 1) != 0) ? a : 0;\n    return ((a = !n ? 1 : (n>=1u)) != 0) ? a : 0;\n}\n\nvoid test8091() {\n    assert(solve1(1) ==  1);\n    assert(solve2(1) ==  1);\n}\n\n/***************************************************/\n\nstruct IPoint {\n    int x, y;\n}\n\nvoid bug6189_2(uint half, IPoint pos, float[4] *pts, uint unused) {\n    pos.y += half;\n    float xo = pos.x;\n    float yo = pos.y;\n\n    (*pts)[0] = xo;\n    (*pts)[1] = yo;\n    (*pts)[2] = xo;\n}\n\nvoid test6189_2()\n{\n    auto pos = IPoint(2, 2);\n    float[4] pts;\n    pts[0] = pts[1] = pts[2] = pts[3] = 0;\n    bug6189_2(0, pos, &pts, 0);\n\n    assert(pts[0] == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8199\n\nversion (D_InlineAsm_X86_64)\n{\n    version = Check;\n    enum Align = 0x8;\n}\nelse version (D_InlineAsm_X86)\n{\n    version = Check;\n    version (OSX)\n        enum Align = 0xC;\n}\n\nvoid onFailure()\n{\n    assert(0, \"alignment failure\");\n}\n\nvoid checkAlign()\n{\n    version (Check)\n    {\n        static if (is(typeof(Align)))\n        asm\n        {\n            naked;\n            mov EAX, ESP;\n            and EAX, 0xF;\n            cmp EAX, Align;\n            je Lpass;\n            call onFailure;\n        Lpass:\n            ret;\n        }\n    }\n    else\n        return;\n}\n\nvoid foo8199()\n{\n}\n\nvoid test8199()\n{\n    try\n        foo8199();\n    finally\n        checkAlign();\n}\n\n/***************************************************/\n\nvoid test246()\n{\n    struct Struct\n    {\n        void method() {}\n    }\n    auto val = Struct();\n}\n\n/***************************************************/\n\ndouble sqrt8454(double d) { return d/2; }\nvoid foo8454(cdouble m) {}\nvoid test8454() {\n    foo8454(0 - sqrt8454(1.0) * 1i);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8423\n\nstruct S8423\n{\n    int opCmp(S8423 rhs)\n    {\n        return 1;\n    }\n}\n\nvoid enforce8423(bool value, string a, string b)\n{\n    if (!value) assert(false);\n}\n\nvoid test8423()\n{\n    auto a = S8423();\n    auto b = S8423();\n    enforce8423(a > b, null, null);\n}\n\n/***************************************************/\nclass Foo8496\n{\npublic:\n    void foo(uint value)\n    {\n        ubyte size = value < (0x7fU << 0 ) ? 1 :\n                     value < (0x7fU << 14) ? 2 :\n                                             3;\n        import std.stdio;\n        writeln(size);\n        assert(size == 2);\n    }\n}\n\nvoid test8496()\n{\n    Foo8496 f = new Foo8496();\n    f.foo(1000000);\n}\n\n/***************************************************/\n\nlong foo8840() { return 4; }\n\nint bar8840(long g) { assert(g == 4); return printf(\"%llx\\n\", g); }\n\nvoid test8840()\n{\n    long f1 = foo8840();\n    long f2 = foo8840();\n\n    long f = (f1 < f2 ? f1 : f2);\n    int len = (f == 0 ? 0 : bar8840(f));\n}\n\n/***************************************************/\n\nstruct S8889\n{\n    real f;\n    int i;\n}\n\nvoid test8889()\n{\n}\n\n/***************************************************/\n\nstruct S8870\n{\n    float x = 0;\n    float y = 0;\n    float z = 0;\n    float w = 0;\n}\n\nvoid test8870()\n{\n    S8870 r1 = S8870(1,2,3,4);\n    S8870 r2 = S8870(5,6,7,8);\n\n    foo8870(r1, r2, false, 1);\n    bar8870(r1, r2, false, 1);\n}\n\n//extern (C)\nvoid foo8870(S8870 t1, S8870 t2, bool someBool, float finalFloat)\n{\n    printf(\"t1: %g %g %g %g\\n\", t1.x, t1.y, t1.z, t1.w);\n    printf(\"t2: %g %g %g %g\\n\", t2.x, t2.y, t2.z, t2.w);\n    printf(\"someBool: %d\\n\", someBool);\n    printf(\"finalFloat: %g\\n\", finalFloat);\n\n    assert(t1.x == 1 && t1.y == 2 && t1.z == 3 && t1.w == 4);\n    assert(t2.x == 5 && t2.y == 6 && t2.z == 7 && t2.w == 8);\n    assert(someBool == false);\n    assert(finalFloat == 1);\n}\n\nextern (C)\nvoid bar8870(S8870 t1, S8870 t2, bool someBool, float finalFloat)\n{\n    printf(\"t1: %g %g %g %g\\n\", t1.x, t1.y, t1.z, t1.w);\n    printf(\"t2: %g %g %g %g\\n\", t2.x, t2.y, t2.z, t2.w);\n    printf(\"someBool: %d\\n\", someBool);\n    printf(\"finalFloat: %g\\n\", finalFloat);\n\n    assert(t1.x == 1 && t1.y == 2 && t1.z == 3 && t1.w == 4);\n    assert(t2.x == 5 && t2.y == 6 && t2.z == 7 && t2.w == 8);\n    assert(someBool == false);\n    assert(finalFloat == 1);\n}\n\n/***************************************************/\n\nint foo9781(int[1] x)\n{\n    return x[0] * x[0];\n}\n\nvoid test9781()\n{\n    foo9781([7]);\n}\n\n/***************************************************/\n\nstruct S247 { size_t length; size_t ptr; }\n\nS247 foo247()\n{\n    S247 f;\n    f.length = 7;\n    f.ptr = 8;\n    return f;\n}\n\nvoid test247()\n{\n    S247 f;\n    f = foo247();\n    assert(f.length == 7);\n    assert(f.ptr == 8);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8340\n\nvoid test8340(){\n    byte[] ba = [1,2,3,4,5];\n    short[] sa = [1,2,3,4,5];\n    int[] ia = [1,2,3,4,5];\n    long[] la = [1,2,3,4,5];\n\n    ba[2] *= -1;\n    sa[2] *= -1;\n    ia[2] *= -1;\n    la[2] *= -1;\n\n    assert(ba == [1,2,-3,4,5]);\n    assert(sa == [1,2,-3,4,5]);\n    assert(ia == [1,2,-3,4,5]);\n    assert(la == [1,2,-3,4,5]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8376\n\nvoid test8376() {\n    int i = 0;\n    int[2] a;\n    a[1]=1;\n    while(!a[0]){\n        if(a[i]) continue;\n        a[i] = 1;\n    }\n}\n\n/***************************************************/\n\n// Don't call, compile only\nvoid test8987(){\n    int last = 0;\n    int count = 0;\n    int d;\n\n    for (int x = 0; count < 100; x++){\n        d = 3;\n\n        while (x / d)\n            d += 2;\n\n        if (x & d) {\n            last = x;\n            count++;\n        }\n    }\n\n    printf(\"Last: %d\\n\", last);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8796\n\nint* wrong8796(int* p)\n{\n    *p++ = 1;\n    return p;\n}\n\nvoid test8796()\n{\n    int[3] arr;\n    int* q = arr.ptr;\n    q = wrong8796(q);\n    assert(q != arr.ptr);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9171\n\nulong bitcomb9171(ulong v)\n{\n    if(v)\n    {\n        ulong result;\n        if(v & 1)\n        {\n            auto r = bitcomb9171(v >> 1);\n            printf(\"r=%016llx\\n\", r);\n\n            auto z = ((r & (r-1) ^ r));\n            check9171(\"str\", z>>1);\n//          printf(\"z=%016llx\\n\", z>>1);\n            return r;\n        }\n        else\n        {\n            auto fb = v & (v-1) ^ v;\n            result = (fb >> 1) | (v ^ fb);\n        }\n        return result;\n    }\n    return 0;\n}\n\nvoid check9171(const char *s, ulong v)\n{\n    assert(v == 0x80000000);\n}\n\nvoid test9171()\n{\n    bitcomb9171(0b1110000000000000010000000000000000000000000000000001);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9248\n\nvoid test9248()\n{\n    void*[] a = [cast(void*)1];\n    void*[] b = [cast(void*)2];\n    auto c = a ~ b;\n    assert(c == [cast(void*)1, cast(void*)2]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14682\n\nvoid test14682a()\n{\n    // operands\n    int[]       a1;\n    int[][]     a2;\n    int[][][]   a3;\n    int[][][][] a4;\n\n    // results\n    int[]       r1w =    [];    assert(r1w.length == 0);\n    int[][]     r2w =    [];    assert(r2w.length == 0);\n    int[][][]   r3w =    [];    assert(r3w.length == 0);\n    int[][][][] r4w =    [];    assert(r4w.length == 0);\n    // ----\n    int[][]     r2x =   [[]];   assert(r2x.length == 1 && r2x[0].length == 0);\n    int[][][]   r3x =   [[]];   assert(r3x.length == 1 && r3x[0].length == 0);\n    int[][][][] r4x =   [[]];   assert(r4x.length == 1 && r4x[0].length == 0);\n    // ----\n    int[][][]   r3y =  [[[]]];  assert(r3y.length == 1 && r3y[0].length == 1 && r3y[0][0].length == 0);\n    int[][][][] r4y =  [[[]]];  assert(r4y.length == 1 && r4y[0].length == 1 && r4y[0][0].length == 0);\n    // ----\n    int[][][][] r4z = [[[[]]]]; assert(r4z.length == 1 && r4z[0].length == 1 && r4z[0][0].length == 1 && r4z[0][0][0].length == 0);\n\n    // ArrayLiteralExp conforms to the type of LHS.\n    { auto x = a1 ~    []   ;   static assert(is(typeof(x) == typeof(a1))); assert(x == r1w); } // no ambiguity\n    { auto x = a2 ~    []   ;   static assert(is(typeof(x) == typeof(a2))); assert(x == r2w); } // fix <- ambiguity\n    { auto x = a3 ~    []   ;   static assert(is(typeof(x) == typeof(a3))); assert(x == r3w); } // fix <- ambiguity\n    { auto x = a4 ~    []   ;   static assert(is(typeof(x) == typeof(a4))); assert(x == r4w); } // fix <- ambiguity\n    // ----\n  //{ auto x = a1 ~   [[]]  ; } // (see test14682b)\n    { auto x = a2 ~   [[]]  ;   static assert(is(typeof(x) == typeof(a2))); assert(x == r2x); } // no ambiguity\n    { auto x = a3 ~   [[]]  ;   static assert(is(typeof(x) == typeof(a3))); assert(x == r3x); } // fix <- ambiguity\n    { auto x = a4 ~   [[]]  ;   static assert(is(typeof(x) == typeof(a4))); assert(x == r4x); } // fix <- ambiguity\n    // ----\n    static assert(!__traits(compiles, { auto x = a1 ~   [[[]]] ; }));\n  //{ auto x = a2 ~  [[[]]] ; } // (see test14682b)\n    { auto x = a3 ~  [[[]]] ;   static assert(is(typeof(x) == typeof(a3))); assert(x == r3y); } // no ambiguity\n    { auto x = a4 ~  [[[]]] ;   static assert(is(typeof(x) == typeof(a4))); assert(x == r4y); } // fix <- ambiguity\n    // ----\n    static assert(!__traits(compiles, { auto x = a1 ~  [[[[]]]]; }));\n    static assert(!__traits(compiles, { auto x = a2 ~  [[[[]]]]; }));\n  //{ auto x = a3 ~ [[[[]]]]; } // (see test14682b)\n    { auto x = a4 ~ [[[[]]]];   static assert(is(typeof(x) == typeof(a4))); assert(x == r4z); } // no ambiguity\n\n    // ArrayLiteralExp conforms to the type of RHS.\n    { auto x =    []    ~ a1;   static assert(is(typeof(x) == typeof(a1))); assert(x == r1w); } // no ambiguity\n    { auto x =    []    ~ a2;   static assert(is(typeof(x) == typeof(a2))); assert(x == r2w); } // fix <- ambiguity\n    { auto x =    []    ~ a3;   static assert(is(typeof(x) == typeof(a3))); assert(x == r3w); } // fix <- ambiguity\n    { auto x =    []    ~ a4;   static assert(is(typeof(x) == typeof(a4))); assert(x == r4w); } // fix <- ambiguity\n    // ----\n  //{ auto x =   [[]]   ~ a1; } // (see test14682b)\n    { auto x =   [[]]   ~ a2;   static assert(is(typeof(x) == typeof(a2))); assert(x == r2x); } // no ambiguity\n    { auto x =   [[]]   ~ a3;   static assert(is(typeof(x) == typeof(a3))); assert(x == r3x); } // fix <- ambiguity\n    { auto x =   [[]]   ~ a4;   static assert(is(typeof(x) == typeof(a4))); assert(x == r4x); } // fix <- ambiguity\n    // ----\n    static assert(!__traits(compiles, { auto x =  [[[]]]  ~ a1; }));\n  //{ auto x =  [[[]]]  ~ a2; } // (see test14682b)\n    { auto x =  [[[]]]  ~ a3;   static assert(is(typeof(x) == typeof(a3))); assert(x == r3y); } // no ambiguity\n    { auto x =  [[[]]]  ~ a4;   static assert(is(typeof(x) == typeof(a4))); assert(x == r4y); } // fix <- ambiguity\n    // ----\n    static assert(!__traits(compiles, { auto x = [[[[]]]] ~ a1; }));\n    static assert(!__traits(compiles, { auto x = [[[[]]]] ~ a2; }));\n  //{ auto x = [[[[]]]] ~ a3; } // (see test14682b)\n    { auto x = [[[[]]]] ~ a4;   static assert(is(typeof(x) == typeof(a4))); assert(x == r4z); } // no ambiguity\n}\n\nvoid test14682b()\n{\n    // operands\n    int[]       a1;\n    int[][]     a2;\n    int[][][]   a3;\n    int[][][][] a4;\n\n    // results\n    int[][]     r2a = [[],   []  ]; assert(r2a.length == 2 && r2a[0].length == 0 && r2a[1].length == 0);\n  //int[][][]   r3a = [[],  [[]] ]; // should work, but doesn't\n  //int[][][][] r4a = [[], [[[]]]]; // should work, but doesn't\n    int[][][]   r3a;  { r3a.length = 2; r3a[0] = []; r3a[1] =  [[]] ; }\n                                    assert(r3a.length == 2 && r3a[0].length == 0 && r3a[1].length == 1 && r3a[1][0].length == 0);\n    int[][][][] r4a;  { r4a.length = 2; r4a[0] = []; r4a[1] = [[[]]]; }\n                                    assert(r4a.length == 2 && r4a[0].length == 0 && r4a[1].length == 1 && r4a[1][0].length == 1 && r4a[1][0][0].length == 0);\n    // ----\n    int[][]     r2b = [  []  , []]; assert(r2b.length == 2 && r2b[1].length == 0 && r2b[0].length == 0);\n  //int[][][]   r3b = [ [[]] , []]; // should work, but doesn't\n  //int[][][][] r4b = [[[[]]], []]; // should work, but doesn't\n    int[][][]   r3b;  { r3b.length = 2; r3b[0] =  [[]] ; r3b[1] = []; }\n                                    assert(r3b.length == 2 && r3b[1].length == 0 && r3b[0].length == 1 && r3b[0][0].length == 0);\n    int[][][][] r4b;  { r4b.length = 2; r4b[0] = [[[]]]; r4b[1] = []; }\n                                    assert(r4b.length == 2 && r4b[1].length == 0 && r4b[0].length == 1 && r4b[0][0].length == 1 && r4b[0][0][0].length == 0);\n\n    // ArrayLiteralExp conforms to the typeof(LHS)->arrayOf().\n    { auto x = a1 ~   [[]]  ;   static assert(is(typeof(x) == typeof(a1)[])); assert(x == r2a); } // fix\n    { auto x = a2 ~  [[[]]] ;   static assert(is(typeof(x) == typeof(a2)[])); assert(x == r3a); } // fix\n    { auto x = a3 ~ [[[[]]]];   static assert(is(typeof(x) == typeof(a3)[])); assert(x == r4a); } // fix\n\n    // ArrayLiteralExp conforms to the typeof(RHS)->arrayOf().\n    { auto x =   [[]]   ~ a1;   static assert(is(typeof(x) == typeof(a1)[])); assert(x == r2b); } // fix\n    { auto x =  [[[]]]  ~ a2;   static assert(is(typeof(x) == typeof(a2)[])); assert(x == r3b); } // fix\n    { auto x = [[[[]]]] ~ a3;   static assert(is(typeof(x) == typeof(a3)[])); assert(x == r4b); } // fix\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9739\n\nclass Foo9739\n{\n    int val = 1;\n    this(int arg = 2) { val = arg; }\n}\n\nclass Bar9739 : Foo9739 { }\n\nvoid test9739()\n{\n    Bar9739 bar = new Bar9739;\n    assert(bar.val == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6057\nvoid test6057()\n{\n    enum Foo { A=1, B=2 }\n    Foo[] bar = [cast(Foo)1];\n}\n\n/***************************************************/\n\nulong d2ulong(double u)\n{\n    return cast(ulong)u;\n}\n\nvoid testdbl_to_ulong()\n{\n    auto u = d2ulong(12345.6);\n    //writeln(u);\n    assert(u == 12345);\n\n    static if (real.mant_dig <= 64)\n    {\n        real adjust = 1.0L/real.epsilon;\n        u = d2ulong(adjust);\n        //writefln(\"%s %s\", adjust, u);\n        static if(real.mant_dig == 64)\n            assert(u == 9223372036854775808UL);\n        else static if(real.mant_dig == 53)\n            assert(u == 4503599627370496UL);\n        else\n            static assert(false, \"Test not implemented for this architecture\");\n\n        auto v = d2ulong(adjust * 1.1);\n        //writefln(\"%s %s %s\", adjust, v, u + u/10);\n\n        // The following can vary in the last bits with different optimization settings,\n        // i.e. the conversion from real to double may not happen.\n        //assert(v == 10145709240540254208UL);\n    }\n}\n\n/***************************************************/\n\n\n\nuint d2uint(double u)\n{\n    return cast(uint)u;\n}\n\nvoid testdbl_to_uint()\n{\n    auto u = d2uint(12345.6);\n    //writeln(u);\n    assert(u == 12345);\n}\n\n/***************************************************/\n\nulong r2ulong(real u)\n{\n    return cast(ulong)u;\n}\n\nvoid testreal_to_ulong()\n{\n    auto u = r2ulong(12345.6L);\n    //writeln(u);\n    assert(u == 12345);\n\n    real adjust = 1.0L/real.epsilon;\n    u = r2ulong(adjust);\n    //writefln(\"%s %s\", adjust, u);\n    static if(real.mant_dig == 113)\n        assert(u == 18446744073709551615UL);\n    else static if(real.mant_dig == 106)\n        assert(u == 18446744073709551615UL);\n    else static if(real.mant_dig == 64)\n        assert(u == 9223372036854775808UL);\n    else static if(real.mant_dig == 53)\n        assert(u == 4503599627370496UL);\n    else\n        static assert(false, \"Test not implemented for this architecture\");\n\n    auto v = r2ulong(adjust * 1.1);\n    writefln(\"%s %s %s\", adjust, v, u + u/10);\n\n    //assert(v == 10145709240540253389UL);\n}\n\n/***************************************************/\n\nlong testbt1(long a, long b, int c)\n{\n    return a + ((b >> c) & 1);\n//    return a + ((b & (1L << c)) != 0);\n}\n\n\nlong testbt2(long a, long b, int c)\n{\n//    return a + ((b >> c) & 1);\n    return a + ((b & (1L << c)) != 0);\n}\n\nint testbt3(int a, int b, int c)\n{\n    return a + ((b >> c) & 1);\n//    return a + ((b & (1 << c)) != 0);\n}\n\nint testbt4(int a, int b, int c)\n{\n//    return a + ((b >> c) & 1);\n    return a + ((b & (1 << c)) != 0);\n}\n\n\nvoid test248()\n{\n    auto a1 = testbt1(3, 4, 2);\n    assert(a1 == 4);\n    a1 = testbt2(3, 4, 2);\n    assert(a1 == 4);\n    a1 = testbt3(3, 4, 2);\n    assert(a1 == 4);\n    a1 = testbt4(3, 4, 2);\n    assert(a1 == 4);\n\n    a1 = testbt1(3, 8, 2);\n    assert(a1 == 3);\n    a1 = testbt2(3, 8, 2);\n    assert(a1 == 3);\n    a1 = testbt3(3, 8, 2);\n    assert(a1 == 3);\n    a1 = testbt4(3, 8, 2);\n    assert(a1 == 3);\n}\n\n/***************************************************/\n\nint foo249(int a, int b)\n{\n    return a + ((b & 0x80) != 0);\n}\n\nlong bar249(long a, int b)\n{\n    return a + ((b & 0x80) != 0);\n}\n\nvoid test249()\n{\n  {\n    auto i = foo249(3, 6);\n    assert(i == 3);\n    i = foo249(3, 0x88);\n    assert(i == 4);\n  }\n  {\n    auto i = bar249(3, 6);\n    assert(i == 3);\n    i = bar249(3, 0x88);\n    assert(i == 4);\n  }\n}\n\n/***************************************************/\n\n// These should all compile to a BT instruction when -O, for -m32 and -m64\n\nint bt32(uint *p, uint b) { return ((p[b >> 5] & (1 << (b & 0x1F)))) != 0; }\n\nint bt64a(ulong *p, uint b) { return ((p[b >> 6] & (1L << (b & 63)))) != 0; }\n\nint bt64b(ulong *p, size_t b) { return ((p[b >> 6] & (1L << (b & 63)))) != 0; }\n\nvoid test250()\n{\n    static uint[2]  a1 = [0x1001_1100, 0x0220_0012];\n\n    if ( bt32(a1.ptr,30)) assert(0);\n    if (!bt32(a1.ptr,8))  assert(0);\n    if ( bt32(a1.ptr,30+32)) assert(0);\n    if (!bt32(a1.ptr,1+32))  assert(0);\n\n    static ulong[2] a2 = [0x1001_1100_12345678, 0x0220_0012_12345678];\n\n    if ( bt64a(a2.ptr,30+32)) assert(0);\n    if (!bt64a(a2.ptr,8+32))  assert(0);\n    if ( bt64a(a2.ptr,30+32+64)) assert(0);\n    if (!bt64a(a2.ptr,1+32+64))  assert(0);\n\n    if ( bt64b(a2.ptr,30+32)) assert(0);\n    if (!bt64b(a2.ptr,8+32))  assert(0);\n    if ( bt64b(a2.ptr,30+32+64)) assert(0);\n    if (!bt64b(a2.ptr,1+32+64))  assert(0);\n}\n\n/***************************************************/\n\nstruct S251 { int a,b,c,d; }\n\nS251 foo251(S251 s)\n{\n    S251 a = s;\n    S251 b = a; // copy propagation\n    S251 c = b;\n    S251 d = c;\n    S251 e = d; // dead assignment\n    return d;\n}\n\nvoid test251()\n{\n    S251 a;\n    a.a = 1;\n    a.b = 2;\n    a.c = 3;\n    a.d = 4;\n    a = foo251(a);\n    assert(a.a == 1);\n    assert(a.b == 2);\n    assert(a.c == 3);\n    assert(a.d == 4);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9387\n\nvoid bug9387a(double x) { }\n\nvoid ice9387()\n{\n    double x = 0.3;\n    double r = x*0.1;\n    double q = x*0.1 + r;\n    double p = x*0.1 + r*0.2;\n    if ( q )\n        p = -p;\n    bug9387a(p);\n}\n\n/***************************************************/\n\nvoid bug6962(string value)\n{\n    string v = value;\n    try\n    {\n        v = v[0LU..0LU];\n        return;\n    }\n    finally\n    {\n        assert(!v.length);\n    }\n}\n\nvoid test6962()\n{\n    bug6962(\"42\");\n}\n\n/***************************************************/\n\nint[1] foo4414() {\n    return [7];\n}\n\nubyte[4] bytes4414()\n{\n    ubyte[4] x;\n    x[0] = 7;\n    x[1] = 8;\n    x[2] = 9;\n    x[3] = 10;\n    return x;\n}\n\nvoid test4414() {\n  {\n    int x = foo4414()[0];\n    assert(x == 7);\n  }\n  {\n    auto u = bytes4414();\n    auto x = u[0..4];\n    if (x[0] != 7 || x[1] != 8 || x[2] != 9 || x[3] != 10)\n        assert(0);\n  }\n  assert(bytes4414()[0] == 7);\n  assert(bytes4414()[1] == 8);\n  assert(bytes4414()[2] == 9);\n  assert(bytes4414()[3] == 10);\n}\n\n/***************************************************/\n\nvoid test9844() {\n    int a = -1;\n    long b = -1;\n    assert(a == -1);\n    assert(b == -1L);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10628\n\nabstract class B10628\n{\n    static if (! __traits(isVirtualMethod, foo))\n    {\n    }\n\n    private bool _bar;\n    public void foo();\n}\n\nclass D10628 : B10628\n{\n    public override void foo() {}\n}\n\nvoid test10628()\n{\n    assert(typeid(D10628).vtbl.length - typeid(Object).vtbl.length == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11265\n\nstruct S11265\n{\n    class InnerClass\n    {\n        S11265 s;\n\n        bool empty()\n        {\n            return true;\n        }\n    }\n}\n\nvoid test11265()\n{\n    S11265.InnerClass trav = new S11265.InnerClass();\n    trav.empty();\n}\n\n/***************************************************/\n\nstruct TimeOfDay\n{\n    void roll(int value)\n    {\n        value %= 60;\n        auto newVal = _seconds + value;\n\n        if(newVal < 0)\n            newVal += 60;\n        else if(newVal >= 60)\n            newVal -= 60;\n\n        _seconds = cast(ubyte)newVal;\n    }\n\n    ubyte _seconds;\n}\n\n\nvoid test10633()\n{\n    TimeOfDay tod = TimeOfDay(0);\n    tod.roll(-1);\n    assert(tod._seconds == 59);\n}\n\n/***************************************************/\n\nimport std.stdio;\n\nvoid _assertEq (ubyte lhs, short rhs, string msg, string file, size_t line)\n{\n    immutable result = lhs == rhs;\n\n    if(!result)\n    {\n        string op = \"==\";\n        if(msg.length > 0)\n            writefln(`_assertEq failed: [%s] is not [%s].`, lhs, rhs);\n        else\n            writefln(`_assertEq failed: [%s] is not [%s]: %s`, lhs, rhs, msg);\n    }\n\n    assert(result);\n}\n\nstruct Date\n{\n    short year;\n    ubyte month;\n    ubyte day;\n}\n\nstruct MonthDay\n{\n    ubyte month;\n    short day;\n}\n\nvoid test10642()\n{\n    static void test(Date date, int day, MonthDay expected, size_t line = __LINE__)\n    {\n        _assertEq(date.day, expected.day, \"\", __FILE__, line);\n    }\n\n    test(Date(1999, 1, 1), 1, MonthDay(1,1));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11581\n\nalias TT11581(T...) = T;\n\nvoid test11581()\n{\n    static class A {}\n\n    static class C { alias Types = TT11581!(4, int); }\n    static C makeC() { return null; }\n\n    alias T = TT11581!(A);\n\n    // edim == IntergerExp(0)\n    auto a1 = new T[0];\n    static assert(is(typeof(a1) == A));\n\n    enum d2 = 0;\n\n    // edim == TypeIdentifier('d2') --> IdentifierExp\n    auto a2 = new T[d2];\n    static assert(is(typeof(a2) == A));\n\n    alias U = int;\n    int d3 = 3;\n\n    // edim == TypeIdentifier('d3') --> IdentifierExp\n    auto a3 = new U[d3];\n    static assert(is(typeof(a3) == U[]));\n    assert(a3.length == d3);\n\n    // edim == IndexExp(DotIdExp(CallExp(makeC, []), 'Types'), 0)\n    auto a4 = new U[makeC().Types[0]];\n    static assert(is(typeof(a4) == U[]));\n    assert(a4.length == C.Types[0]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7436\n\nvoid test7436()\n{\n    ubyte a = 10;\n    float f = 6;\n    ubyte b = a += f;\n    assert(b == 16);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12138\n\nstruct S12138\n{\n    int num;\n    this(int n) { num = n; }\n    ~this() { num = 0; }\n}\n\nvoid test12138()\n{\nlabel:\n    auto s = S12138(10);\n    assert(s.num == 10);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14430\n\nvoid setCookie(long x = 1L << 32L, string y = null){\n    assert(y.ptr is null);\n}\n\nvoid test14430(){\n    setCookie();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14510\n\nalias Vector14510 = ulong[3];\n\nvoid fun14510(Vector14510 vec, bool recursive = false)\n{\n    assert(vec[2] == 0);\n    if (recursive)\n        return;\n    fun14510(vec, true);\n}\n\nvoid test14510()\n{\n    Vector14510 vec;\n    fun14510(vec);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16027\n\nvoid test16027()\n{\n    double value = 1.0;\n    value *= -1.0;\n    assert(value == -1.0);    // fails, value is +1.0\n\n    value = 1.0;\n    value = value * -1.0;\n    assert(value == -1.0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16530\n\ndouble entropy2(double[] probs)\n{\n    double result = 0;\n    foreach (p; probs)\n    {\n        __gshared int x;\n        ++x;\n        if (!p) continue;\n        import std.math : log2;\n        result -= p * log2(p);\n    }\n    return result;\n}\n\nvoid test16530()\n{\n    import std.stdio;\n    if (entropy2([1.0, 0, 0]) != 0.0)\n       assert(0);\n}\n\n/***************************************************/\n\nvoid test252()\n{\n    __gshared int x = 7;\n    __gshared long y = 217;\n    if ((-1 - x) != ~x)\n        assert(0);\n    if ((-1 - y) != ~y)\n        assert(0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7997\n\nvoid test7997()\n{\n    __gshared int[0] foos;\n    foreach (f; foos) {}\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5332\n\nint[0] arr5332;\n\nvoid test5332()\n{\n    auto a = arr5332;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11742\n\nconst int x11472 = void;\n\nstatic this() { x11472 = 10; }\n\nvoid test11472()\n{\n    assert(x11472 == 10);\n}\n\n/***************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test27();\n    test28();\n    test29();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test56();\n    test57();\n    test58();\n    test59();\n    test60();\n    test61();\n    test62();\n    test63();\n    test64();\n    test65();\n    test66();\n    test67();\n    test68();\n    test69();\n    test70();\n    test71();\n    test72();\n    test73();\n    test74();\n    test75();\n    test76();\n    test77();\n    test78();\n    test79();\n    test80();\n    test81();\n    test82();\n    test83();\n    test84();\n    test85();\n    test86();\n    test87();\n    test88();\n    test89();\n    test90();\n    test91();\n    test92();\n    test93();\n    test94();\n    test95();\n    test96();\n    test97();\n    test98();\n    test99();\n    test100();\n    test101();\n    test103();\n    test104();\n    test105();\n    test107();\n    test108();\n    test109();\n    test110();\n    test111();\n    test112();\n    test113();\n    test114();\n    test115();\n    test116();\n    test117();\n    test118();\n    test119();\n    test120();\n    test121();\n    //test122();\n    test123();\n    test124();\n    test125();\n    test126();\n    test127();\n    test128();\n    test129();\n    test130();\n    test131();\n    test132();\n    test133();\n\n//    test135();\n    test136();\n    test137();\n\n    test139();\n    test140();\n\n    test142();\n    test143();\n    test144();\n    test145();\n    test146();\n    test147();\n    test148();\n    test149();\n\n    test151();\n    test152();\n    test153();\n    test154();\n\n    test156();\n    test157();\n\n    test160();\n\n    test163();\n\n\n    test169();\n\n    test171();\n\n    test173();\n    test174();\n\n    test176();\n    test177();\n\n    test179();\n\n    test181();\n    test182();\n\n    test188();\n    test189();\n    test190();\n    test191();\n\n    test193();\n    test194();\n\n    test198();\n\n    test200();\n    test201();\n    test202();\n    test203();\n\n//    test208();\n\n    test210();\n\n    test212();\n    test213();\n    test214();\n    test215();\n    test216();\n    test217();\n    test218();\n    test219();\n    test220();\n\n    test222();\n    test223();\n    test224();\n    test225();\n    test226();\n    test227();\n    test228();\n    test229();\n    test230();\n    test230();\n    bug5717();\n    test231();\n    test232();\n    test233();\n    bug6184();\n    test236();\n    test237();\n    test238();\n    test239();\n    test6229();\n    test6270();\n    test6506();\n    test240();\n    test6563();\n    test241();\n    test6665();\n    test5364();\n    test6189();\n    test6997();\n    test7026();\n    test6354();\n    test7072();\n    test7212();\n    test242();\n    test7290();\n    test7367();\n    test7375();\n    test6504();\n    test7422();\n    test7424();\n    test7502();\n    test4820();\n    test4820_2();\n    test243();\n    test7742();\n    test245();\n    test7807();\n    test4155();\n    test7911();\n    test8095();\n    test8091();\n    test6189_2();\n    test8199();\n    test246();\n    test8454();\n    test8423();\n    test8496();\n    test8840();\n    test8889();\n    test8870();\n    test9781();\n    test247();\n    test8340();\n    test8376();\n    test8796();\n    test9171();\n    test9248();\n    test14682a();\n    test14682b();\n    test9739();\n    testdbl_to_ulong();\n    testdbl_to_uint();\n    testreal_to_ulong();\n    test248();\n    test249();\n    test250();\n    test6057();\n    test251();\n    test6962();\n    test4414();\n    test9844();\n    test10628();\n    test11265();\n    test10633();\n    test10642();\n    test11581();\n    test7436();\n    test12138();\n    test14430();\n    test14510();\n    test16027();\n    test16530();\n    test252();\n    test7997();\n    test5332();\n    test11472();\n\n    writefln(\"Success\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test42a.d",
    "content": "// PERMUTE_ARGS:\n\nmodule test42;\n\nimport core.stdc.stdio;\n\n/***************************************************/\n\nvoid test1()\n{\n    ubyte[] data2 = [\n    3,3,3,3,\n    3,3,3,3,\n    3,3,3,3,\n    3,3,3,\n    ];\n    foreach (i; data2)\n    {   //printf(\"i = %d\\n\", i);\n        assert(i == 3);\n    }\n\nubyte[] data = [\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n7,7,7,7,7,7,7,7,7,7,7,7];\n    foreach (i; data)\n    {   //printf(\"i = %d\\n\", i);\n        assert(i == 7);\n    }\n}\n\n/***************************************************/\n\nint main()\n{\n    test1();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test435.d",
    "content": "import core.stdc.stdio;\n\nclass A\n{\n    immutable size_t f;\n\n    this(T)(T z)\n    {\n        f = z.sizeof;\n    }\n}\n\nstruct AS\n{\n    immutable size_t f;\n\n    this(T)(T z)\n    {\n        f = z.sizeof;\n    }\n}\n\nvoid test0()\n{\n    assert((new A(2.2)).f == double.sizeof);\n    assert((new A('g')).f == char.sizeof);\n    assert((AS(17)).f == int.sizeof);\n    assert((AS(null)).f == typeof(null).sizeof);\n}\n\n//------------------------------------------------------------------------------\n\nclass C\n{\n    const int x;\n    const int y;\n\n    this(T...)(T z)\n    {\n        this.tupleof = z;\n    }\n}\n\nstruct CS\n{\n    const int x;\n    const int y;\n\n    this(T...)(T z)\n    {\n        this.tupleof = z;\n    }\n}\n\nvoid test1()\n{\n    auto c = new C(4, 6);\n    assert(c.x == 4);\n    assert(c.y == 6);\n\n    auto cs = CS(7, 8);\n    assert(cs.x == 7);\n    assert(cs.y == 8);\n}\n\n//------------------------------------------------------------------------------\n\n// https://issues.dlang.org/show_bug.cgi?id=435.\nclass B\n{\n    int i;\n    this(int k)\n    {\n        i = k;\n    }\n}\nclass D : B\n{\n    this(A...)(A args)\n    {\n        super(args);\n    }\n}\n\nvoid test2()\n{\n    auto a = new D(4);\n    assert(a.i == 4);\n}\n\n//------------------------------------------------------------------------------\n\n// https://issues.dlang.org/show_bug.cgi?id=4905\nclass C2\n{\n    string x;\n\n    this(T...)(in string msg, T args)\n    {\n        x = msg;\n        foreach (a; args)\n            x ~= a;\n    }\n}\n\nvoid test3()\n{\n    auto c2 = new C2(\"test\");\n    assert(c2.x == \"test\");\n\n    auto c3 = new C2(\"test\", \" variadic\", \" constructor\");\n    assert(c3.x == \"test variadic constructor\");\n}\n\n//------------------------------------------------------------------------------\n\n// https://issues.dlang.org/show_bug.cgi?id=4531 test case 2\nclass MyError : Exception\n{\n    this(T...)(T msg)\n    {\n        assert(msg[0] == \"Hello, \" && msg[1] == 42);\n        super(\"Hello, 42\");\n    }\n}\n\nvoid test4()\n{\n    auto err = new MyError(\"Hello, \", 42);\n    assert(err.msg == \"Hello, 42\");\n}\n\nvoid main()\n{\n    test0();\n    test1();\n    test2();\n    test3();\n    test4();\n    printf(\"Success\\n\");\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test45.d",
    "content": "// EXTRA_SOURCES: imports/test45a.d imports/test45b.d\n// PERMUTE_ARGS:\n\nimport imports.test45a;\nimport imports.test45b;\n\nalias int function() fp1;\nalias int function(int) fp2;\n\nvoid main()\n{\n    auto i = foo();\n    assert(i == 1);\n    i = foo(1);\n    assert(i == 2);\n    i = foo;\n    assert(i == 1);\n\n    fp1 fp = &foo;\n    i = (*fp)();\n    assert(i == 1);\n\n    fp2 fpi = &foo;\n    i = (*fpi)(1);\n    assert(i == 2);\n\n    i = bar(1);\n    assert(i == 3);\n    i = bar(1, 2);\n    assert(i == 4);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test46.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/test46b.d imports/test46a.d imports/test46c.d\n// PERMUTE_ARGS:\n\nmodule test46;\nvoid main() {}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test48.d",
    "content": "// EXTRA_SOURCES: imports/test48a.d\n// PERMUTE_ARGS:\n\nimport std.stdio;\nimport imports.test48a;\n\nvoid main()\n{\n    S s;\n    auto i = s.tupleof[0] + s.tupleof[1] + s.tupleof[2];\n    printf(\"i = %d\\n\", i);\n    assert(i == 6);\n\n    auto t = s.tupleof;\n    i = t[0] + t[1] + t[2];\n    printf(\"i = %d\\n\", i);\n    assert(i == 6);\n\n    printf(\"a = %d %d %d\\n\", S.tupleof.offsetof);\n    auto o = S.tupleof.offsetof;\n    assert(o[0] == 0);\n    assert(o[1] == 4);\n    assert(o[2] == 8);\n    printf(\"a = %d %d %d\\n\", S.tupleof[0].offsetof, S.tupleof[1].offsetof, S.tupleof[2].offsetof);\n    assert(S.tupleof[0].offsetof == 0);\n    assert(S.tupleof[1].offsetof == 4);\n    assert(S.tupleof[2].offsetof == 8);\n\n    auto offset0 = cast(void*)&s.tupleof[0] - cast(void*)&s;\n    printf(\"offset0 = %d\\n\", offset0);\n    assert(offset0 == 0);\n\n    auto offset1 = cast(void*)&s.tupleof[1] - cast(void*)&s;\n    printf(\"offset1 = %d\\n\", offset1);\n    assert(offset1 == 4);\n\n    auto offset2 = cast(void*)&s.tupleof[2] - cast(void*)&s;\n    printf(\"offset2 = %d\\n\", offset2);\n    assert(offset2 == 8);\n\n    int[S.tupleof.offsetof[1]] t1;\n    assert(t1.length == 4);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test49.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/test49a.d\n// PERMUTE_ARGS:\n\nimport imports.test49a;\n\nalias Foo!(int) foo;\n\nvoid main()\n{\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test5.d",
    "content": "// PERMUTE_ARGS:\n\nextern(C) int printf(const char*, ...);\n\ninterface foo\n{\n    extern (C) int testc(int i);\n    extern (Windows) int testw(int i);\n    extern (D) int testd(int i);\n}\n\nclass bar : foo\n{\n    int x = 47;\n\n  extern (C)\n    int testc(int i)\n    {\n        printf(\"foo.testc(%p)\\n\", this);\n        assert(x == 47);\n        return i + x;\n    }\n\n  extern (Windows)\n    int testw(int i)\n    {\n        printf(\"foo.testw(%p)\\n\", this);\n        assert(x == 47);\n        return i + x;\n    }\n\n  extern (D)\n    int testd(int i)\n    {\n        printf(\"foo.testd(%p)\\n\", this);\n        assert(x == 47);\n        return i + x;\n    }\n}\n\nint def(foo f)\n{\n    printf(\"def(%p), %p\\n\", f, (cast(int*)f)[0]);\n    assert(f.testc(3) == 50);\n    assert(f.testd(7) == 54);\n    assert(f.testd(10) == 57);\n    return 0;\n}\n\nvoid abc(bar b)\n{\n    printf(\"abc(%p), %p\\n\", b, (cast(int*)b)[3]);\n    def(b);\n}\n\nint main()\n{\n    bar b = new bar();\n\n    printf(\"b.size = x%x\\n\", b.classinfo.initializer.length);\n    printf(\"bar.size = x%x\\n\", bar.classinfo.initializer.length);\n    assert(b.classinfo.initializer.length == bar.classinfo.initializer.length);\n    abc(b);\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test52.d",
    "content": "// PERMUTE_ARGS:\n\n// https://issues.dlang.org/show_bug.cgi?id=2311\n\nextern(C)\n{\n    void exit(int);\n    int printf(const char*, ...);\n}\n\nstruct X()\n{\n  static this()\n  {\n     printf(\"this()\\n\");\n  }\n  static ~this()\n  {\n     printf(\"~this()\\n\");\n     exit(0);\n  }\n}\n\nstatic ~this()\n{\n     printf(\"g: ~this()\\n\");\n}\n\nint main() { alias X!() x; return 1; }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test5305.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=5305\n\nimport std.math;\nvoid map(real function(real) f) { }\nint main() { map(&sqrt); return 0; }\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test57.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/test57a.d imports/test57b.d\n// PERMUTE_ARGS:\n// REQUIRED_ARGS: -inline -release\n\nmodule test57;\nimport imports.test57a;\n\nvoid main() {}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test58.d",
    "content": "// EXTRA_SOURCES: imports/test58a.d\n// PERMUTE_ARGS:\n\nimport imports.test58a;\n\nvoid main()\n{\n    foo!(long)();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test5943.d",
    "content": "// test that the import of std.math is not needed\n\n__gshared uint x0 = 0;\n__gshared uint x1 = 1;\n__gshared uint x2 = 2;\n__gshared uint x3 = 3;\n__gshared uint x4 = 4;\n__gshared uint x5 = 5;\n__gshared uint x6 = 6;\n__gshared uint x7 = 7;\n__gshared uint x10 = 10;\n__gshared uint x15 = 15;\n__gshared uint x31 = 31;\n__gshared uint x32 = 32;\n\nvoid main()\n{\n    assert(2 ^^ x0 == 1);\n    assert(2 ^^ x1 == 2);\n    assert(2 ^^ x31 == 0x80000000);\n    assert(4 ^^ x0 == 1);\n    assert(4 ^^ x1 == 4);\n    assert(4 ^^ x15 == 0x40000000);\n    assert(8 ^^ x0 == 1);\n    assert(8 ^^ x1 == 8);\n    assert(8 ^^ x10 == 0x40000000);\n    assert(16 ^^ x0 == 1);\n    assert(16 ^^ x1 == 16);\n    assert(16 ^^ x7 == 0x10000000);\n    assert(32 ^^ x0 == 1);\n    assert(32 ^^ x1 == 32);\n    assert(32 ^^ x6 == 0x40000000);\n    assert(64 ^^ x0 == 1);\n    assert(64 ^^ x1 == 64);\n    assert(64 ^^ x5 == 0x40000000);\n    assert(128 ^^ x0 == 1);\n    assert(128 ^^ x1 == 128);\n    assert(128 ^^ x4 == 0x10000000);\n    assert(256 ^^ x0 == 1);\n    assert(256 ^^ x1 == 256);\n    assert(256 ^^ x3 == 0x1000000);\n    assert(512 ^^ x0 == 1);\n    assert(512 ^^ x1 == 512);\n    assert(512 ^^ x3 == 0x8000000);\n    assert(1024 ^^ x0 == 1);\n    assert(1024 ^^ x1 == 1024);\n    assert(1024 ^^ x3 == 0x40000000);\n    assert(2048 ^^ x0 == 1);\n    assert(2048 ^^ x1 == 2048);\n    assert(2048 ^^ x2 == 0x400000);\n    assert(4096 ^^ x0 == 1);\n    assert(4096 ^^ x1 == 4096);\n    assert(4096 ^^ x2 == 0x1000000);\n    assert(8192 ^^ x0 == 1);\n    assert(8192 ^^ x1 == 8192);\n    assert(8192 ^^ x2 == 0x4000000);\n    assert(16384 ^^ x0 == 1);\n    assert(16384 ^^ x1 == 16384);\n    assert(16384 ^^ x2 == 0x10000000);\n    assert(32768 ^^ x0 == 1);\n    assert(32768 ^^ x1 == 32768);\n    assert(32768 ^^ x2 == 0x40000000);\n    assert(65536 ^^ x0 == 1);\n    assert(65536 ^^ x1 == 65536);\n    assert(131072 ^^ x0 == 1);\n    assert(131072 ^^ x1 == 131072);\n    assert(262144 ^^ x0 == 1);\n    assert(262144 ^^ x1 == 262144);\n    assert(524288 ^^ x0 == 1);\n    assert(524288 ^^ x1 == 524288);\n    assert(1048576 ^^ x0 == 1);\n    assert(1048576 ^^ x1 == 1048576);\n    assert(2097152 ^^ x0 == 1);\n    assert(2097152 ^^ x1 == 2097152);\n    assert(4194304 ^^ x0 == 1);\n    assert(4194304 ^^ x1 == 4194304);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test60.d",
    "content": "import std.stdio;\nimport std.algorithm;\n\nvoid test1()\n{\n    int[] a = [1,2,3,4,5];\n    writeln( remove!(\"a < 3\")(a) );\n}\n\nvoid test2()\n{\n    auto arr = [1,2,3,4,5];\n    auto m = map!\"a + 1\"(filter!\"a < 4\"(arr));\n}\n\nvoid main()\n{\n    test1();\n    test2();\n\n    writeln(\"Success\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test61.d",
    "content": "// PERMUTE_ARGS:\n// EXTRA_SOURCES: imports/test61a.d\n\n// https://issues.dlang.org/show_bug.cgi?id=6556\n\ndebug=BUG;\n\nvoid main() {\n    debug(BUG) import imports.test61a;\n    assert(bar() == 12);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test6423.d",
    "content": "// DISABLED: osx64\n\nbool flag;\n\nvoid f()\n{\n}\n\nvoid main()\n{\n    if (!flag)\n    {\n        flag = true;\n        caller();\n    }\n    return f();\n}\n\nalias maintype = extern(C) int function();\n\nvoid caller()\n{\n    auto fp = cast(maintype)&main;\n    assert(fp() == 0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test7.d",
    "content": "// PERMUTE_ARGS:\n\n// Test memset style array assignments.\n\nextern(C) int printf(const char*, ...);\n\n/**************************************/\n\nchar[] b1;\n\nchar[] func1(int dim)\n{\n    char[] a = new char[dim];\n\n    b1 = a;\n    return a;\n}\n\nvoid test1()\n{\n    printf(\"test1()\\n\");\n    int i;\n    int j;\n\n    char[1] a1;\n    a1[] = 'x';\n    assert(a1[0] == 'x');\n\n    char[2] a2;\n    a2[] = 'x';\n    for (i = 0; i < a2.length; i++)\n        assert(a2[i] == 'x');\n\n    char[3] a3;\n    a3[] = 'x';\n    for (i = 0; i < a3.length; i++)\n        assert(a3[i] == 'x');\n\n    char[4] a4;\n    a4[] = 'x';\n    for (i = 0; i < a4.length; i++)\n        assert(a4[i] == 'x');\n\n    char[8] a8;\n    a8[] = 'x';\n    for (i = 0; i < a8.length; i++)\n        assert(a8[i] == 'x');\n\n    char[27] a27;\n    a27[] = 'x';\n    for (i = 0; i < a27.length; i++)\n        assert(a27[i] == 'x');\n\n    func1(33)[] = 'y';\n    for (i = 0; i < b1.length; i++)\n        assert(b1[i] == 'y');\n\n\n    char[23] a23 = 'x';\n    i = 16;\n    j = 18;\n    a23[i++..++j] = 'c';\n    printf(\"i = %d, j = %d\\n\", i, j);\n    assert(i == 17);\n    assert(j == 19);\n    assert(a23[15] == 'x');\n    assert(a23[16] == 'c');\n    assert(a23[17] == 'c');\n    assert(a23[18] == 'c');\n    assert(a23[19] == 'x');\n    assert(a23[20] == 'x');\n}\n\n/**************************************/\n\nshort[] b2;\n\nshort[] func2(int dim)\n{\n    short[] a = new short[dim];\n\n    b2 = a;\n    return a;\n}\n\nvoid test2()\n{\n    printf(\"test2()\\n\");\n    int i;\n    int j;\n\n    short[1] a1;\n    a1[] = 0x1234;\n    assert(a1[0] == 0x1234);\n\n    short[2] a2;\n    a2[] = 0x1234;\n    for (i = 0; i < a2.length; i++)\n        assert(a2[i] == 0x1234);\n\n    short[3] a3;\n    a3[] = 0x1234;\n    for (i = 0; i < a3.length; i++)\n        assert(a3[i] == 0x1234);\n\n    short[4] a4;\n    a4[] = 0x1234;\n    for (i = 0; i < a4.length; i++)\n        assert(a4[i] == 0x1234);\n\n    short[8] a8;\n    a8[] = 0x1234;\n    for (i = 0; i < a8.length; i++)\n        assert(a8[i] == 0x1234);\n\n    short[27] a27;\n    a27[] = 0x1234;\n    for (i = 0; i < a27.length; i++)\n        assert(a27[i] == 0x1234);\n\n    func2(33)[] = 0x5678;\n    for (i = 0; i < b2.length; i++)\n        assert(b2[i] == 0x5678);\n\n\n    short[23] a23 = 0x1234;\n    i = 16;\n    j = 18;\n    a23[i++..++j] = 0x4554;\n    printf(\"i = %d, j = %d\\n\", i, j);\n    assert(i == 17);\n    assert(j == 19);\n    assert(a23[15] == 0x1234);\n    assert(a23[16] == 0x4554);\n    assert(a23[17] == 0x4554);\n    assert(a23[18] == 0x4554);\n    assert(a23[19] == 0x1234);\n    assert(a23[20] == 0x1234);\n}\n\n/**************************************/\n\nint[] b3;\n\nint[] func3(int dim)\n{\n    int[] a = new int[dim];\n\n    b3 = a;\n    return a;\n}\n\nvoid test3()\n{\n    printf(\"test3()\\n\");\n    int i;\n    int j;\n\n    int[1] a1;\n    a1[] = 0x12345678;\n    assert(a1[0] == 0x12345678);\n\n    int[2] a2;\n    a2[] = 0x12345678;\n    for (i = 0; i < a2.length; i++)\n        assert(a2[i] == 0x12345678);\n\n    int[3] a3;\n    a3[] = 0x12345678;\n    for (i = 0; i < a3.length; i++)\n        assert(a3[i] == 0x12345678);\n\n    int[4] a4;\n    a4[] = 0x12345678;\n    for (i = 0; i < a4.length; i++)\n        assert(a4[i] == 0x12345678);\n\n    int[8] a8;\n    a8[] = 0x12345678;\n    for (i = 0; i < a8.length; i++)\n        assert(a8[i] == 0x12345678);\n\n    int[27] a27;\n    a27[] = 0x12345678;\n    for (i = 0; i < a27.length; i++)\n        assert(a27[i] == 0x12345678);\n\n    func3(33)[] = 0x56781234;\n    for (i = 0; i < b3.length; i++)\n        assert(b3[i] == 0x56781234);\n\n\n    int[23] a23 = 0x12345678;\n    i = 16;\n    j = 18;\n    a23[i++..++j] = 0x45546776;\n    printf(\"i = %d, j = %d\\n\", i, j);\n    assert(i == 17);\n    assert(j == 19);\n    assert(a23[15] == 0x12345678);\n    assert(a23[16] == 0x45546776);\n    assert(a23[17] == 0x45546776);\n    assert(a23[18] == 0x45546776);\n    assert(a23[19] == 0x12345678);\n    assert(a23[20] == 0x12345678);\n}\n\n/**************************************/\n\nlong[] b4;\n\nlong[] func4(int dim)\n{\n    long[] a = new long[dim];\n\n    b4 = a;\n    return a;\n}\n\nvoid test4()\n{\n    printf(\"test4()\\n\");\n    int i;\n    int j;\n\n    long[1] a1;\n    a1[] = 0x123456789ABCDEF0;\n    assert(a1[0] == 0x123456789ABCDEF0);\n\n    long[2] a2;\n    a2[] = 0x123456789ABCDEF0;\n    for (i = 0; i < a2.length; i++)\n        assert(a2[i] == 0x123456789ABCDEF0);\n\n    long[3] a3;\n    a3[] = 0x123456789ABCDEF0;\n    for (i = 0; i < a3.length; i++)\n        assert(a3[i] == 0x123456789ABCDEF0);\n\n    long[4] a4;\n    a4[] = 0x123456789ABCDEF0;\n    for (i = 0; i < a4.length; i++)\n        assert(a4[i] == 0x123456789ABCDEF0);\n\n    long[8] a8;\n    a8[] = 0x123456789ABCDEF0;\n    for (i = 0; i < a8.length; i++)\n        assert(a8[i] == 0x123456789ABCDEF0);\n\n    long[27] a27;\n    a27[] = 0x123456789ABCDEF0;\n    for (i = 0; i < a27.length; i++)\n        assert(a27[i] == 0x123456789ABCDEF0);\n\n    func4(33)[] = 0x5678889911223344;\n    for (i = 0; i < b4.length; i++)\n        assert(b4[i] == 0x5678889911223344);\n\n\n    long[23] a23 = 0x123456789ABCDEF0;\n    i = 16;\n    j = 18;\n    a23[i++..++j] = 0x567888991122334B;\n    printf(\"i = %d, j = %d\\n\", i, j);\n    assert(i == 17);\n    assert(j == 19);\n    assert(a23[15] == 0x123456789ABCDEF0);\n    assert(a23[16] == 0x567888991122334B);\n    assert(a23[17] == 0x567888991122334B);\n    assert(a23[18] == 0x567888991122334B);\n    assert(a23[19] == 0x123456789ABCDEF0);\n    assert(a23[20] == 0x123456789ABCDEF0);\n}\n\n/**************************************/\n\nreal[] b5;\n\nreal[] func5(int dim)\n{\n    real[] a = new real[dim];\n\n    b5 = a;\n    return a;\n}\n\nvoid test5()\n{\n    printf(\"test5()\\n\");\n    int i;\n    int j;\n\n    real[1] a1;\n    a1[] = 31234;\n    assert(a1[0] == 31234);\n\n    real[2] a2;\n    a2[] = 31234;\n    for (i = 0; i < a2.length; i++)\n        assert(a2[i] == 31234);\n\n    real[3] a3;\n    a3[] = 31234;\n    for (i = 0; i < a3.length; i++)\n        assert(a3[i] == 31234);\n\n    real[4] a4;\n    a4[] = 31234;\n    for (i = 0; i < a4.length; i++)\n        assert(a4[i] == 31234);\n\n    real[8] a8;\n    a8[] = 31234;\n    for (i = 0; i < a8.length; i++)\n        assert(a8[i] == 31234);\n\n    real[27] a27;\n    a27[] = 31234;\n    for (i = 0; i < a27.length; i++)\n        assert(a27[i] == 31234);\n\n    func5(33)[] = 35678;\n    for (i = 0; i < b5.length; i++)\n        assert(b5[i] == 35678);\n\n\n    real[23] a23 = 31234;\n    i = 16;\n    j = 18;\n    a23[i++..++j] = 34554e+4;\n    printf(\"i = %d, j = %d\\n\", i, j);\n    assert(i == 17);\n    assert(j == 19);\n    assert(a23[15] == 31234);\n    assert(a23[16] == 34554e+4);\n    assert(a23[17] == 34554e+4);\n    assert(a23[18] == 34554e+4);\n    assert(a23[19] == 31234);\n    assert(a23[20] == 31234);\n}\n\n/**************************************/\n\nstruct ABC\n{\n    int a,b,c,d;\n}\n\nABC abc1 = { a:1, b:2, c:3, d:4 };\nABC abc2 = { a:7, b:6, c:8, d:9 };\nABC abc3 = { a:5, b:10, c:11, d:12 };\n\nABC[] b6;\n\nABC[] func6(int dim)\n{\n    ABC[] a = new ABC[dim];\n\n    b6 = a;\n    return a;\n}\n\nvoid test6()\n{\n    printf(\"test6()\\n\");\n    int i;\n    int j;\n\n    ABC[1] a1;\n    a1[] = abc1;\n    assert(a1[0] == abc1);\n\n    ABC[2] a2;\n    a2[] = abc1;\n    for (i = 0; i < a2.length; i++)\n        assert(a2[i] == abc1);\n\n    ABC[3] a3;\n    a3[] = abc1;\n    for (i = 0; i < a3.length; i++)\n        assert(a3[i] == abc1);\n\n    ABC[4] a4;\n    a4[] = abc1;\n    for (i = 0; i < a4.length; i++)\n        assert(a4[i] == abc1);\n\n    ABC[8] a8;\n    a8[] = abc1;\n    for (i = 0; i < a8.length; i++)\n        assert(a8[i] == abc1);\n\n    ABC[27] a27;\n    a27[] = abc1;\n    for (i = 0; i < a27.length; i++)\n        assert(a27[i] == abc1);\n\n    func6(33)[] = abc2;\n    for (i = 0; i < b6.length; i++)\n        assert(b6[i] == abc2);\n\n\n    ABC[23] a23 = abc1;\n    i = 16;\n    j = 18;\n    a23[i++..++j] = abc3;\n    printf(\"i = %d, j = %d\\n\", i, j);\n    assert(i == 17);\n    assert(j == 19);\n    assert(a23[15] == abc1);\n    assert(a23[16] == abc3);\n    assert(a23[17] == abc3);\n    assert(a23[18] == abc3);\n    assert(a23[19] == abc1);\n    assert(a23[20] == abc1);\n}\n\n/**************************************/\n\nbool[] b7;\n\nbool[] func7(int dim)\n{\n    bool[] a = new bool[dim];\n\n    b7 = a;\n    return a;\n}\n\nvoid test7()\n{\n    printf(\"test7()\\n\");\n    int i;\n    int j;\n\n    bool[1] a1;\n    a1[] = 1;\n    assert(a1[0] == 1);\n\n    bool[2] a2;\n    a2[] = 1;\n    for (i = 0; i < a2.length; i++)\n        assert(a2[i] == 1);\n\n    bool[3] a3;\n    a3[] = 1;\n    for (i = 0; i < a3.length; i++)\n        assert(a3[i] == 1);\n\n    bool[4] a4;\n    a4[] = 1;\n    for (i = 0; i < a4.length; i++)\n        assert(a4[i] == 1);\n\n    bool[8] a8;\n    a8[] = 1;\n    for (i = 0; i < a8.length; i++)\n        assert(a8[i] == 1);\n\n    bool[27] a27;\n    a27[] = 1;\n    for (i = 0; i < a27.length; i++)\n        assert(a27[i] == 1);\n\n    func7(33)[] = 1;\n    assert(b7.length == 33);\n    for (i = 0; i < b7.length; i++)\n        assert(b7[i] == 1);\n\n    func7(33)[3..6] = 1;\n    //printf(\"b7.ptr = %p, b7.length = %d\\n\", b7.ptr, b7.length);\n    assert(b7.length == 33);\n    for (i = 0; i < b7.length; i++)\n    {\n        //printf(\"b7[%d] = %d\\n\", i, b7[i]);\n        if (i >= 3 && i < 6)\n            assert(b7[i] == 1);\n        else\n            assert(b7[i] == 0);\n    }\n\n    bool[23] a23 = 1;\n    i = 16;\n    j = 18;\n    a23[i++..++j] = 0;\n    printf(\"i = %d, j = %d\\n\", i, j);\n    assert(i == 17);\n    assert(j == 19);\n    assert(a23[15] == 1);\n    assert(a23[16] == 0);\n    assert(a23[17] == 0);\n    assert(a23[18] == 0);\n    assert(a23[19] == 1);\n    assert(a23[20] == 1);\n\n}\n\n/**************************************/\n\nbool[] slice8(bool[] b)\n{\n    return b[8..16];\n}\n\nvoid test8()\n{\n    bool[16] b;\n    bool[] b2;\n    b[9] = true;\n    b2 = slice8(b);\n    assert(b2.length == 8);\n    assert(b2[1] == true);\n    b[9] = false;\n    assert(b2[1] == false);\n}\n\n\n/**************************************/\n\nbool[] slice9(bool[] b, int i, int j)\n{\n    return b[i..j];\n}\n\nvoid test9()\n{\n    bool[17] b;\n    bool[] b2;\n    b[9] = true;\n    b[16] = true;\n    b2 = slice9(b,8,17);\n    assert(b2.length == 9);\n    assert(b2[1] == true);\n    assert(b2[8] == true);\n    b[9] = false;\n    b[16] = false;\n    assert(b2[1] == false);\n    assert(b2[8] == false);\n}\n\n\n/**************************************/\n\nbool* foo10(bool[] b, int i)\n{\n    return &b[i];\n}\n\nvoid test10()\n{\n    bool[17] b;\n    bool* pb;\n\n    b[8] = true;\n    b[9] = true;\n    pb = foo10(b, 8);\n    assert(*pb == true);\n    b[8] = false;\n    assert(*pb == false);\n}\n\n/**************************************/\n\nbool* foo11(bool[] b, int i)\n{\n    return &b[i];\n}\n\nvoid test11()\n{\n    bool[17] b;\n    bool* pb;\n\n    b[9] = true;\n    b[10] = true;\n    pb = foo11(b, 8);\n    assert(pb[1] == true);\n    b[9] = false;\n    assert(pb[1] == false);\n}\n\n\n/**************************************/\n\nbool* foo12(bool[] b, int i)\n{\n    return &b[i];\n}\n\nvoid test12()\n{\n    bool[17] b;\n    bool* pb;\n\n    b[9] = true;\n    b[10] = true;\n    pb = foo12(b, 0);\n    pb = pb + 8;\n    assert(pb[1] == true);\n    b[9] = false;\n    assert(pb[1] == false);\n}\n\n/**************************************/\n\nbool* foo13(bool* b, int i)\n{\n    return &b[i];\n}\n\nvoid test13()\n{\n    bool[17] b;\n    bool* pb;\n\n    b[9] = true;\n    b[10] = true;\n    pb = foo13(b.ptr, 8);\n    assert(pb[1] == true);\n    b[9] = false;\n    assert(pb[1] == false);\n}\n\n/**************************************/\n\nvoid test14()\n{\n    bool b = true;\n    assert(b);\n    b = !b;\n    assert(!b);\n}\n\n/**************************************/\n\nvoid test15()\n{\n   bool b = 1;\n   bool *pb = &b;\n   *pb = false;\n   assert(!b);\n}\n\n\n/**************************************/\n\nvoid foo16(bool[] b1, bool[] b2)\n{\n    b1[0..3] = b2[8..11];\n}\n\nvoid test16()\n{\n    static bool[16] b1 = [1,1,0,1,0,0,0,0];\n    static bool[16] b2 = [0,0,0,0,0,0,0,0, 0,0,1,0,1,1,1,1];\n\n    foo16(b1, b2);\n    assert(b1[0] == false);\n    assert(b1[1] == false);\n    assert(b1[2] == true);\n    assert(b1[3] == true);\n    assert(b1[4] == false);\n    assert(b1[5] == false);\n    assert(b1[6] == false);\n    assert(b1[7] == false);\n    assert(b1[8] == false);\n}\n\n/**************************************/\n\nvoid test17()\n{\n  bool bi = true;\n  byte by;\n\n  by=bi;\n  assert(by == 1);\n}\n\n\n/**************************************/\n\nvoid test18()\n{\n    bool b = 1;\n    bool c = 1;\n    b |= cast(bool)(3 + c);\n    assert(b == true);\n}\n\n\n/**************************************/\n\nvoid test19()\n{\n        int i;\n        for (i = 0; i < 10; i++){\n                version(dummy) i=22;\n        }\n        assert(i==10);\n\n        char[][] args;\n        foreach(char[] p; args){\n                version(dummy) int i;\n        }\n}\n\n/**************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test7452.d",
    "content": "import core.stdc.stdio : printf;\n\n//------------------------------------------------------------------------------\n\nT enforce7452(T, string file = __FILE__, size_t line = __LINE__)\n    (T value, lazy const(char)[] msg = null) @safe pure\n{\n    if (!value)\n        throw new Exception(msg ? msg.idup : \"Enforcement failed\", file, line);\n    return value;\n}\n\nint f7452()(int x)\n{\n   enforce7452(x > 0);\n   return x;\n}\nvoid g7452() @safe pure\n{\n   assert(4 == f7452(4));\n}\n\n//------------------------------------------------------------------------------\n\nvoid e7452b(int, lazy int) pure nothrow @safe {}\nint f7452b()(int x)\n{\n   e7452b(x, 0);\n   return x;\n}\nvoid g7452b() pure nothrow @safe\n{\n   assert(4 == f7452b(4));\n}\n\n//------------------------------------------------------------------------------\n\nint f7452c()(int x)\n{\n   auto y = function int() { return 0; };\n   return x;\n}\nvoid g7452c() pure nothrow @safe\n{\n   assert(4 == f7452c(4));\n}\n\n//------------------------------------------------------------------------------\n\nauto f6332a()() { return 1; }\nint f6332b()() { return 1; }\n\nalias f6332a!() F6332a;\n\nvoid g6332() pure nothrow @safe\n{\n    auto x = f6332b();\n    auto y = f6332a();\n    assert(x == y);\n}\n\n//------------------------------------------------------------------------------\n\nint main()\n{\n    g7452();\n    g7452b();\n    g7452c();\n    g6332();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test7453.d",
    "content": "struct S\n{\n    int opApply(int delegate(string) dg)\n    {\n        return 0;\n    }\n}\nvoid main()\n{\n    foreach (_; S())\n    {\n        return;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test7494.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/test7494a.d\n// PERMUTE_ARGS:\n// REQUIRED_ARGS:\n\nmodule test7494;\n\nvoid main()\n{\n    import imports.test7494a : map;             // selective\n    import imports.test7494a : put = writeln;   // selective + rename\n    auto r = map!(a=>a)([1,2,3]);\n    assert(r == [4,5,6]);\n    put(r);\n    static assert(!__traits(compiles, foo()));\n\n    import core.bitop : bsr;\n    // ^ or just any selective import statements\n    bsr(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test7511.d",
    "content": "extern(C) int printf(const char*, ...);\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=7511\n\nstruct S7511(T)\n{\n    // this is a pure function for T==int\n    T foo(T x)\n    {\n        return 2 * x;\n    }\n}\n\nvoid test7511a() pure\n{\n    S7511!int s;\n    s.foo(2); // error -> OK\n}\n\n/**********************************/\n// certain case - wrapper range\n\n//import std.range;\n@property bool empty(T)(in T[] a) { return !a.length; }\n@property ref T front(T)(T[] a) { return a[0]; }\nvoid popFront(T)(ref T[] a) { a = a[1 .. $]; }\n\nstruct S(T)\n{\n    int foo()\n    {\n        auto t = T();\n        return t.bar();\n    }\n}\n\nstruct Wrap(R)\n{\n    R original;\n    this(T : R)(T t) { original = t; }\n    this(A...)(A args) { original = R(args); }\n    @property auto empty() { return original.empty; }\n    @property auto front() { return original.front; }\n    void popFront() { original.popFront(); }\n}\n\nvoid test7511b() pure @safe\n{\n    static struct Iota\n    {\n        size_t curr;\n        size_t max;\n        @property bool empty() pure @safe { return curr == max; }\n        @property size_t front() pure @safe { return curr; }\n        void popFront() pure @safe { ++curr; }\n    }\n    {\n        auto a = Iota(0, 3);\n        size_t i = 0;\n        foreach (e; a) { assert(e == i++); } // OK\n    }\n    {\n        auto a = Wrap!(int[])([0,1,2]);\n        size_t i = 0;\n        foreach (e; a) { assert(e == i++); } // errors!\n    }\n    {\n        auto a = Wrap!Iota(0, 3);\n        size_t i = 0;\n        foreach (e; a) { assert(e == i++); } // errors!\n    }\n}\n\n/**********************************/\n// with attribute inheritance\n\nstruct X\n{\n    static int bar() pure nothrow @safe\n    {\n        return 1;\n    }\n}\n\nclass Class(T)\n{\n    int foo()\n    {   // inferred to pure nothrow @safe\n        return T.bar();\n    }\n}\n\nalias Class!X C;\n\nclass D : C\n{\n    override int foo()\n    {   // inherits attributes from Class!X.foo\n        return 2;\n    }\n}\n\nvoid test7511c() pure nothrow @safe\n{\n// Disabled for Bigzilla 9952\n/+\n    assert((new C()).foo() == 1);\n    assert((new D()).foo() == 2);\n    static assert(typeof(&C.init.foo).stringof == \"int delegate() pure nothrow @safe\");\n    static assert(typeof(&D.init.foo).stringof == \"int delegate() pure nothrow @safe\");\n+/\n}\n\n/**********************************/\n// curiously recurring template pattern (CRTP)\n\nclass BX(T, bool mutual)\n{\n    int foo()\n    {\n        static if (mutual)\n            return (cast(T)this).foo();\n        else\n            return 0;\n    }\n}\n\nclass D1 : BX!(D1, true)\n{\n    alias typeof(super) B;\n    int val;\n    this(int n) { val = n; }\n    override int foo() { return val; }\n}\nclass D2 : BX!(D2, false)\n{\n    alias typeof(super) B;\n    int val;\n    this(int n) { val = n; }\n    override int foo() { return val; }\n}\nclass D3 : BX!(D3, true)\n{\n    alias typeof(super) B;\n    int val;\n    this(int n) { val = n; }\n    override int foo() pure nothrow { return val; }\n}\nclass D4 : BX!(D4, false)\n{\n    alias typeof(super) B;\n    int val;\n    this(int n) { val = n; }\n    override int foo() pure nothrow { return val; }\n}\n\nvoid test7511d()\n{\n// Disabled for Bigzilla 9952\n/+\n    // mutual dependent and attribute inference impure, un-@safe, and may throw is default.\n    auto d1 = new D1(10);\n    static assert(is(typeof(&d1.B.foo) == int function()));\n    static assert(is(typeof(&d1.foo) == int delegate()));\n    assert(d1.foo() == 10);\n\n    // no mutual dependent.\n    auto d2 = new D2(10);\n    static assert(is(typeof(&d2.B.foo) == int function() pure nothrow @safe));\n    static assert(is(typeof(&d2  .foo) == int delegate() pure nothrow @safe));\n    assert(d2.foo() == 10);\n\n    // mutual dependent with explicit attribute specification.\n    auto d3 = new D3(10);\n    static assert(is(typeof(&d3.B.foo) == int function() pure nothrow));\n    static assert(is(typeof(&d3  .foo) == int delegate() pure nothrow));\n    assert(d3.foo() == 10);\n\n    // no mutual dependent with explicit attribute specification.\n    auto d4 = new D4(10);\n    static assert(is(typeof(&d4.B.foo) == int function() pure nothrow @safe));\n    static assert(is(typeof(&d4  .foo) == int delegate() pure nothrow @safe));\n    assert(d4.foo() == 10);\n+/\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9952\n\n@system void writeln9952(int) {}    // impure throwable\n\nclass C9952(T)\n{\n    T foo()\n    {\n        return 2;\n    }\n}\n\nclass D9952 : C9952!int\n{\n    override int foo()\n    {\n        writeln9952(super.foo());\n        return 3;\n    }\n}\n\nvoid test9952()\n{\n    static assert(typeof(&C9952!int.init.foo).stringof == \"int delegate()\");\n    static assert(typeof(&D9952    .init.foo).stringof == \"int delegate()\");\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10373\n\ntemplate isMutable10373(T)\n{\n    enum isMutable10373 = !is(T == const) && !is(T == immutable) && !is(T == inout);\n}\n\nstruct Test10373a(T, int N = 0)\n{\n    static if (N == 0) T[ ] mBuffer;\n    else               T[N] mBuffer;\n\n    static if (is(T == class))\n    {}\n    else\n    {\n        T* at_(size_t n) { return &mBuffer[n]; }\n\n        static if (is(typeof(*at_(0) = T.init)))\n        {\n            T opIndexAssign(T v, size_t i)\n            {\n                return (*at_(i) = v);\n            }\n        }\n    }\n}\nstruct Test10373b(T, int N = 0)\n{\n    static if (is(T == class))\n    {}\n    else\n    {\n        T* at_(size_t n) { return &mBuffer[n]; }\n\n        static if (is(typeof(*at_(0) = T.init)))\n        {\n            T opIndexAssign(T v, size_t i)\n            {\n                return (*at_(i) = v);\n            }\n        }\n    }\n\n    static if (N == 0) T[ ] mBuffer;\n    else               T[N] mBuffer;\n}\nstruct Test10373c(T, int N = 0)\n{\n    static if (is(T == class))\n    {}\n    else\n    {\n        T* at_(size_t n) { return &mBuffer[n]; }\n\n        static if (isMutable10373!T)\n        {\n            T opIndexAssign(T v, size_t i)\n            {\n                return (*at_(i) = v);\n            }\n        }\n    }\n\n    static if (N == 0) T[ ] mBuffer;\n    else               T[N] mBuffer;\n}\n\nvoid test10373()\n{\n    static assert(is(Test10373a!(int, 2)));\n    static assert(is(Test10373b!(int, 2)));\n    static assert(is(Test10373c!(int, 2)));\n\n    Test10373a!(int, 2) testa;  // dmd2.062:OK  dmd2.063:OK\n    Test10373b!(int, 2) testb;  // dmd2.062:OK  dmd2.063:NG\n    Test10373c!(int, 2) testc;  // dmd2.062:OK  dmd2.063:OK\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=10329\n\nauto foo10329(T)(T arg)\n{\n    auto bar()\n    {\n        return arg;\n    }\n    static assert(is(typeof(&bar) == T delegate() pure nothrow @nogc @safe));\n    return bar();\n}\n\nauto make10329(T)(T arg)\n{\n    struct S\n    {\n        auto front() { return T.init; }\n    }\n    S s;\n    static assert(is(typeof(&s.front) == T delegate() pure nothrow @nogc @safe));\n    return s;\n}\n\nvoid test10329() pure nothrow @safe\n{\n    assert(foo10329(1) == 1);\n\n    auto s = make10329(1);\n    assert(s.front() == 0);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=11896\n\nclass Foo11896a(T = int)\n{\n    static if (!__traits(isVirtualMethod, zoo)) {} else { Undefined x; }\n\n    static void bar() {}\n    static void bar(Foo11896a foo) {}\n\n    static void zoo()\n    {\n        bar(new Foo11896a);\n    }\n}\nFoo11896a!(int) baz11896a;\n\n// ----\n\nFrop11896b!(int) frop11896b;\n\nmixin template baz11896b()\n{\n    public void bar11896b() {}\n}\n\nmixin baz11896b;\n\nclass Foo11896b(T)\n{\n    static if (! __traits(isVirtualMethod, zoo)) {}\n\n    static void zoo()\n    {\n        bar11896b();\n    }\n}\n\nclass Frop11896b(T) : Foo11896b!T {}\n\n// ----\n\nstatic bool flag11896c = false;\n\nclass Bar11896c {}\n\nclass Foo11896c(T = Bar11896c)\n{\n    static if (! __traits(isVirtualMethod, foo)) {}\n    alias Foo11896c!(T) this_type;\n    this()\n    {\n        flag11896c = true;\n    }\n    static public this_type foo()\n    {\n        auto c = new this_type();\n        return flag11896c ? c : null;\n    }\n}\n\nvoid test11896c()\n{\n    alias Foo11896c!Bar11896c FooBar;\n    assert(FooBar.foo() !is null);\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=12392\n\nvoid f12392(T)() {}\nalias fa12392 = f12392;\n\nvoid test12392() pure nothrow @safe\n{\n    fa12392!int();\n}\n\n/**********************************/\n\nint main()\n{\n    test7511a();\n    test7511b();\n    test7511c();\n    test7511d();\n    test9952();\n    test10373();\n    test10329();\n    test11896c();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test7595.d",
    "content": "// EXTRA_SOURCES: imports/a7595.d\n\ntemplate isSafe(alias func)\n{\n    @safe void dummySafeFunc()\n    {\n        func();\n    }\n\n    enum isSafe = is(typeof(dummySafeFunc()));\n}\n\ntemplate areAllSafe(funcs...)\n{\n    enum areAllSafe = isSafe!(funcs[0]);\n}\n\n@safe benchmark(fun...)(uint n)\nif (areAllSafe!fun)\n{\n    foreach(i, unused; fun)\n    {\n        foreach (j; 0 .. n)\n            fun[i]();\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test7603.d",
    "content": "void test7603()\n{\n    int g;\n    void foo(int n, ref int r = g) { r = n; }\n\n    int x;\n    foo(1, x);\n    assert(x == 1);\n\n    foo(2);\n    assert(g == 2);\n\n    int h = 100;\n    void bar(int n, out int r = h) { if (n != 0) r = n;  }\n\n    bar(0);\n    assert(h == 0);\n\n    bar(10);\n    assert(h == 10);\n\n    bar(10, x);\n    assert(x == 10);\n\n    bar(0, x);\n    assert(x == 0);\n\n}\n\nvoid main() { test7603(); }\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test7618.d",
    "content": "interface ITest\n{\n    int foo();\n\n    final void bar(int k)() { assert(foo() == k); }\n}\n\nclass Test : ITest\n{\n    override int foo() { return 12; }\n}\n\nvoid main()\n{\n    auto test = new Test;\n    test.bar!12();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test7932.d",
    "content": "// https://issues.dlang.org/show_bug.cgi?id=7932\n\nimport std.stdio;\n\nsize_t N;\n\nclass C\n{\n    protected void f(size_t n)\n    out\n    {\n        printf(\"out: this=%p &n=%p n=%zu\\n\",\n                cast(void*) this, &n, n);\n        assert (N == n);\n    }\n    body\n    {\n        int dummy;\n        //printf(\"\\n\");\n        N = n;\n        printf(\"body: this=%p &dummy=%p &N=%p N=%zu\\n\",\n                cast(void*) this, &dummy, &N, N);\n    }\n}\n\nvoid main()\n{\n    auto x = new C;\n    x.f(1);\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test8.d",
    "content": "\nmodule testxxx8;\n\nimport core.vararg;\n\nextern(C)\n{\n    int atoi(const char*);\n    int printf(const char*, ...);\n    size_t strlen(const char*);\n    version(Windows)\n    {\n        int _snprintf(char*, size_t, const char*, ...);\n        alias _snprintf snprintf;\n    }\n    else\n        int snprintf(char*, size_t, const char*, ...);\n}\n\n/***********************************/\n\nstruct Foo1\n{\n        static int x = 3;\n        int y = 4;\n}\n\nvoid test1()\n{\n    Foo1 f;\n\n    assert(Foo1.x == 3);\n    assert(f.x == 3);\n    assert(f.y == 4);\n}\n\n/***********************************/\n\nclass Foo2\n{\n        static int x = 5;\n        int y = 6;\n}\n\nvoid test2()\n{\n    Foo2 f = new Foo2();\n\n    assert(Foo2.x == 5);\n    assert(f.x == 5);\n    assert(f.y == 6);\n}\n\n\n/***********************************/\n\nstruct Foo3\n{\n        static int bar() { return 3; }\n        int y = 4;\n}\n\nvoid test3()\n{\n    Foo3 f;\n\n    assert(Foo3.bar() == 3);\n    assert(f.bar() == 3);\n}\n\n/***********************************/\n\nclass Foo4\n{\n        static int bar() { return 3; }\n        int y = 4;\n}\n\nvoid test4()\n{\n    Foo4 f = new Foo4();\n\n    assert(Foo4.bar() == 3);\n    assert(f.bar() == 3);\n}\n\n\n/***********************************/\n\nstruct Foo5\n{\n        int bar() { return y + 3; }\n        int y = 4;\n}\n\nvoid test5()\n{\n    Foo5 f;\n\n    assert(f.bar() == 7);\n}\n\n/***********************************/\n\nclass Foo6\n{\n        int bar() { return y + 3; }\n        final int abc() { return y + 8; }\n        int y = 4;\n}\n\nclass FooX6 : Foo6\n{\n        override int bar() { return y + 5; }\n}\n\nvoid test6()\n{\n    Foo6 f = new FooX6();\n\n    assert(f.bar() == 9);\n    assert(f.abc() == 12);\n}\n\n\n/***********************************/\n\nvoid bar7(char[3] cad)\n{\n    assert(cad.length == 3);\n    printf(\"cad[0] = %d\\n\", cad[0]);\n    assert(cad[0] == 0xFF);\n    assert(cad[1] == 1);\n    assert(cad[2] == 0xFF);\n}\n\nvoid test7()\n{\n    char[3] foo;\n\n    foo[1] = 1;\n    bar7(foo);\n}\n\n\n/***********************************/\n\nclass gap8\n{\n    this(char[3] cad)\n    {\n        assert(cad[0] == 0xFF);\n        assert(cad[1] == 1);\n        assert(cad[2] == 0xFF);\n    }\n}\n\nvoid test8()\n{\n    char[3] foo;\n    gap8 g;\n\n    foo[1] = 1;\n    g = new gap8(foo);\n}\n\n\n/***********************************/\n\nvoid test9()\n{\n    ireal imag = 2.5i;\n    //printf (\"test of imag*imag = %Lf\\n\",imag*imag);\n    real f = imag * imag;\n    assert(f == -6.25);\n}\n\n/***********************************/\n\nvoid test10()\n{\n    creal z = 1 + 2.5i;\n    real e = z.im;\n\n    printf (\"e = %Lf\\n\", e);\n    assert(e == 2.5);\n}\n\n\n/***********************************/\n\nclass Foo11\n{\n  public:\n    int a = 47;\n\n  protected:\n    int b;\n\n  private:\n    int c;\n\n    int bar()\n    {\n        return a + b + c;\n    }\n}\n\nclass Bar11 : Foo11\n{\n    int abc()\n    {\n        return a + b;\n    }\n}\n\nvoid test11()\n{\n    Foo11 f = new Foo11();\n\n    int i = f.a;\n    assert(i == 47);\n}\n\n/***********************************/\n\nclass A12\n{\n    protected void foo() { }\n}\n\nclass B12: A12\n{\n    override void foo() { super.foo(); }\n}\n\nvoid test12()\n{\n}\n\n/***********************************/\n\nalias void *HWND;\n\nconst HWND hWnd = cast(HWND)(null);\n\nvoid test13()\n{\n}\n\n/***********************************/\n\nstring bar14()\n{\n    return \"f\";\n}\n\nchar foo14()\n{\n    return bar14()[0];\n}\n\nvoid test14()\n{\n    char f = foo14();\n    assert(f == 'f');\n}\n\n\n/***********************************/\n\nvoid test15()\n{\n        char[30] a;\n        char[30] b;\n\n        assert(a !is b);\n}\n\n/***********************************/\n\nvoid test16()\n{\n    static int function() fp = &func16;\n    int i = fp();\n    assert(i == 648);\n}\n\nint func16()\n{\n    return 648;\n}\n\n\n/***********************************/\n\nstring returnSameString(string inputstr)\n{\n    return inputstr;\n}\n\nstring passString()\n{\n    return returnSameString(\"First string\" ~ \"Concatenated with second\");\n}\n\nstring butThisWorks()\n{\n    string s = \"Third string\";\n    s = s ~ \"Concatenated with fourth\";\n    return returnSameString(s);\n}\n\nvoid test17()\n{\n    string s;\n\n    s = passString();\n    printf(\"passString() = %.*s\\n\", s.length, s.ptr);\n    assert(s == \"First stringConcatenated with second\");\n\n    s = butThisWorks();\n    printf(\"butThisWorks() = %.*s\\n\", s.length, s.ptr);\n    assert(s == \"Third stringConcatenated with fourth\");\n}\n\n/***********************************/\n\n\n\nclass A20\n{\n    private:\n        static int a;\n\n    public:\n        int foo(B20 j) { return j.b; }\n}\n\nclass B20\n{\n    private:\n        static int b;\n\n    public:\n        int bar(A20 j) { return j.a; }\n}\n\nvoid test20()\n{\n}\n\n/***********************************/\n\nalias int* IP;\n\nvoid test21()\n{\n    int i = 5;\n    IP ip = cast(IP) &i;\n    assert(*ip == 5);\n}\n\n/***********************************/\n\nstruct RECT\n{\n    int    left = 1;\n    int    top = 2;\n    int    right = 3;\n    int    bottom = 4;\n}\n\nstruct Rect\n{\n  RECT theRect;\n}\n\n\nvoid Test(Rect pos)\n{\n    //printf(\"left = %d\\n\", pos.theRect.left);\n    assert(pos.theRect.left == 1);\n    assert(pos.theRect.top == 2);\n    assert(pos.theRect.right == 3);\n    assert(pos.theRect.bottom == 4);\n}\n\nclass Window\n{\n  Rect position;\n\n  void createWindow()\n  {\n    Test(position);\n  }\n}\n\nvoid test22()\n{\n    Window w = new Window();\n    w.createWindow();\n}\n\n/***********************************/\n\nstruct Size\n{\n  int width;\n  int height;\n}\n\nSize computeSize()\n{\n  Size foo;\n\n  foo.width = 12;\n  foo.height = 34;\n\n  printf(\"Inside: %d,%d\\n\",foo.width,foo.height);\n\n  return foo;\n}\n\n\nvoid test24()\n{\n  Size bar;\n  bar = computeSize();\n\n  printf(\"Outside: %d,%d\\n\",bar.width,bar.height);\n  assert(bar.width == 12);\n  assert(bar.height == 34);\n}\n\n/***********************************/\n\nvoid test25()\n{   int i = 5;\n\n    while (i)\n    {\n        break;\n    }\n}\n\n/***********************************/\n\nint test26()\nin\n{\n}\nout (result)\n{\n}\nbody\n{   int i = 5;\n\n    while (i)\n    {\n        break;\n    }\n    return i;\n}\n\n/***********************************/\n\nclass A27\n{\n    int a;\n\n    this()\n    {\n        a = 1;\n    }\n}\n\nclass B27 : A27\n{\n}\n\nclass C27 : B27\n{\n    this()\n    {\n        super();\n    }\n\n    this(int i)\n    {\n    }\n}\n\nvoid test27()\n{\n    A27 a = new A27();\n    assert(a.a == 1);\n\n    B27 b = new B27();\n    assert(b.a == 1);\n\n    C27 c = new C27();\n    assert(c.a == 1);\n\n    C27 c2 = new C27(2);\n    assert(c2.a == 1);\n}\n\n\n/***********************************/\n\nconst char[1] sep = '/';\n\nstring testx28(string s, string t)\n{\n    return cast(string)(s ~ sep ~ t);\n}\n\nvoid test28()\n{\n    string r;\n\n    r = testx28(\"ab\", \"cd\");\n    assert(r == \"ab/cd\");\n}\n\n/***********************************/\n\nvoid test29()\n{\n}\n\n\n/***********************************/\n\nbool func30(int x, int y)\n{\n    bool b;\n    b|=(x==y);\n    return b;\n}\n\nvoid test30()\n{\n    bool b;\n\n    b = func30(1,1);\n    assert(b == true);\n    b = func30(1,2);\n    assert(b == false);\n}\n\n/***********************************/\n\nint a31;\n\nvoid test31()\n{\n    testxxx8.a31 = 3;\n    assert(a31 == 3);\n}\n\n/***********************************/\n\nvoid test32()\n{\n    string[] foo;\n    int i;\n\n    foo = new string[45];\n    for (i = 0; i < 45; i++)\n        foo[i] = \"hello\";\n    for (i = 0; i < 45; i++)\n        assert(foo[i] == \"hello\");\n}\n\n\n/***********************************/\n\nvoid test33()\n{\n    string[] foo;\n    int i = 45;\n\n    foo = new string[i];\n    for (i = 0; i < 45; i++)\n        foo[i] = \"hello\";\n    for (i = 0; i < 45; i++)\n        assert(foo[i] == \"hello\");\n}\n\n\n/***********************************/\n\nvoid test34()\n{\n    int[3][4] a;\n    int[5][6] b = 16;\n    int i, j;\n\n    for (i = 0; i < 4; i++)\n        for (j = 0; j < 3; j++)\n            assert(a[i][j] == 0);\n\n    for (i = 0; i < 6; i++)\n        for (j = 0; j < 5; j++)\n            assert(b[i][j] == 16);\n}\n\n\n/***********************************/\n\nvoid test35()\n{\n    ifloat b = cast(ifloat)1i;\n    assert(b == 1.0i);\n\n    ifloat c = 2fi;\n    assert(c == 2.0i);\n\n    c = 0fi;\n    assert(c == 0i);\n}\n\n/***********************************/\n\nstring itoa(int i)\n{\n    char[32] buffer;\n    snprintf(buffer.ptr, 32, \"%d\", i);\n    return buffer[0 .. strlen(buffer.ptr)].idup;\n}\n\nstring testa36(int i, int j, string a, string b, string c)\n{\n    string s =  \"string 0;\" ~ itoa(i) ~\n                \"string 1;\" ~ itoa(j) ~\n                \"string 2;\" ~ itoa(i) ~\n                \"string 3;\";\n\n//    string s = a ~ b ~ c;\n    return s;\n}\n\nvoid test36()\n{\n    string s = testa36(26, 47, \"a\", \"b\", \"c\");\n\n    printf(\"s = '%.*s'\\n\", s.length, s.ptr);\n    assert(s == \"string 0;26string 1;47string 2;26string 3;\");\n}\n\n/***********************************/\n\nvoid test37()\n{\n    string[ulong] x;\n    ulong v1 = 297321415603;\n    ulong v2 = 331681153971;\n    x[v1] = \"aa\";\n    printf( \"%llx %llx\\n\", v1, v2 );\n    assert(!(v2 in x));\n}\n\n\n/***********************************/\n\nvoid test38()\n{\n    int n = atoi(\"1\");\n    static char[8192 + 1] flags;\n    long i, k;\n    int count = 0;\n\n    try\n    {\n       while (n--)\n       {\n          count = 0;\n\n          for (i = 2; i <= 8192; i++)\n             flags[cast(size_t)i] = 1;\n\n          for (i = 2; i <= 8192; i++)\n          {\n             if (flags[cast(size_t)i])\n             {\n                for (k = i+i; k <= 8192; k += i)\n                   flags[cast(size_t)k] = 0;\n\n                count++;\n             }\n          }\n       }\n\n       printf(\"Count: %d\\n\", count);\n        assert(count == 1028);\n    }\n    catch(Throwable)\n    {\n       printf(\"Exception: %d\\n\", k);\n        assert(0);\n    }\n}\n\n\n/***********************************/\n\ninterface I39\n{\n}\n\nclass C39 : I39\n{\n    int x = 432;\n}\n\nvoid test39()\n{\n    C39 c = new C39;\n\n    printf(\"%p %d\\n\", c, c.x);\n    assert(c.x == 432);\n    printf(\"%p\\n\", cast(I39) c);\n    c = cast(C39) cast(I39) c;\n    printf(\"%p\\n\", c);\n    assert(c !is null);\n}\n\n\n/***********************************/\n\nvoid test40()\n{\n       Object x;\n\n       x = null;\n       x = 0 ? x : null;\n       x = 0 ? null : x;\n}\n\n/***********************************/\n\nint foo42(const(char) *x, ...)\n{\n    va_list ap;\n\n    va_start!(typeof(x))(ap, x);\n    //printf(\"&x = %p, ap = %p\\n\", &x, ap);     // XBUG: static array va_lists (eg: x86_64) cannot be passed as vararg.\n\n    int i;\n    i = va_arg!(typeof(i))(ap);\n    printf(\"i = %d\\n\", i);\n\n    long l;\n    l = va_arg!(typeof(l))(ap);\n    printf(\"l = %lld\\n\", l);\n\n    uint k;\n    k = va_arg!(typeof(k))(ap);\n    printf(\"k = %u\\n\", k);\n\n    va_end(ap);\n\n    return cast(int)(i + l + k);\n}\n\nvoid test42()\n{\n    int j;\n\n    j = foo42(\"hello\", 3, 23L, 4);\n    printf(\"j = %d\\n\", j);\n    assert(j == 30);\n}\n\n/***********************************/\n\nvoid test43()\n{\n    creal C,Cj;\n    real y1,x1;\n\n    C = x1 + y1*1i + Cj;\n    C = 1i*y1 + x1 + Cj;\n    C = Cj + 1i*y1 + x1;\n    C = y1*1i + Cj + x1;\n    C = 1i*y1 + Cj;\n    C = Cj + 1i*y1;\n}\n\n/***********************************/\n\nint x44;\n\nclass A44 {\n     this() { printf(\"A44 ctor\\n\"); x44 += 1; }\n     ~this() { printf(\"A44 dtor\\n\"); x44 += 0x100; }\n}\nclass B44 : A44 { }\n\nvoid foo44() { scope B44 b = new B44; }\n\nvoid test44()\n{\n     printf(\"foo44...\\n\");\n     foo44();\n     printf(\"...foo44\\n\");\n     assert(x44 == 0x101);\n}\n\n/***********************************/\n\n/*\nimport std.stdarg;\nimport std.utf;\n\nint unFormat( bool delegate( out dchar ) getc,\n        bool delegate( dchar ) ungetc,\n        TypeInfo[] arguments,\n        void* argptr )\n{\n    size_t  arg = 0;\n    dchar[] fmt;\n\n    if( arguments[arg] is typeid( string ) )\n        fmt = toUTF32( va_arg!(string)( argptr ) );\n    else if( arguments[arg] is typeid( wchar[] ) )\n        fmt = toUTF32( va_arg!(wchar[])( argptr ) );\n    else if( arguments[arg] is typeid( dchar[] ) )\n        fmt = va_arg!(dchar[])( argptr );\n    else\n        return 0;\n}\n*/\n\nvoid test45()\n{\n}\n\n/***********************************/\n\nint sreadf( ... )\n{\n    va_arg!(string)( _argptr );\n    return 0;\n}\n\n\nvoid test46()\n{\n    printf( \"hello world\\n\" );\n}\n\n/***********************************/\n\nvoid test48()\n{\n  try{\n  }finally{\n    debug(p48) { }\n  }\n}\n\n/***********************************/\n\nvoid test49()\n{\n  int k = 1;\n  if(k == 0)\n    debug{printf(\"test\");}\n}\n\n/***********************************/\n\nvoid test50()\n{       int x;\n\n        if (x)\n             version (none)\n                 foo;\n}\n\n/***********************************/\n\n/+\nvoid foo51(creal a)\n{\n  writeln(a);\n  assert(a == -8i);\n}\n\nvoid test51()\n{\n  cdouble a = (2-2i)*(2-2i);\n\n  // This fails\n  writeln(a);\n  assert(a == -8i);\n\n  // This works\n  writeln((2-2i)*(2-2i));\n\n  // This fails\n  foo51((2-2i)*(2-2i));\n}\n+/\n\nvoid foo51(creal a)\n{\n    assert(a == -8i);\n}\n\nvoid test51()\n{\n    assert((2-2i)*(2-2i) == -8i);\n\n    cdouble a = (2-2i)*(2-2i);\n    assert(a == -8i);\n\n    foo51((2-2i)*(2-2i));\n}\n\n/***********************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test20();\n    test21();\n    test22();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test48();\n    test49();\n    test50();\n    test51();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test8182.d",
    "content": "struct S\n{\n    ~this()\n    {\n        assert(false);\n    }\n}\n\nvoid lazily(lazy S)\n{\n}\n\nvoid main()\n{\n    lazily(S());\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test8544.d",
    "content": "// EXECUTE_ARGS: foo bar doo\n// PERMUTE_ARGS:\nimport std.stdio;\nimport std.conv;\nimport core.runtime;\n\nvoid main(string[] args)\n{\n    string[] dArgs = Runtime.args;\n    CArgs cArgs = Runtime.cArgs;\n\n    assert(dArgs.length && cArgs.argc);  // ensure we've passed some args\n    assert(dArgs.length == cArgs.argc);\n\n    assert(dArgs[1] == to!string(cArgs.argv[1]));\n    assert(args[1] == to!string(cArgs.argv[1]));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test8997.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/test8997a.d\n\nmodule test8997;\n\nimport imports.test8997a;\n\nvoid main()\n{\n    auto a = new A();\n\n    foreach(key; a.foobar.byKey())\n    {\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test9259.d",
    "content": "// PERMUTE_ARGS: -inline -release -g -O -d -dw -de\n\nvoid test(int*[] arr...)\n{\n    assert(arr.length == 1);\n    assert(*arr[0] == 5); // This assertion fails\n}\n\nvoid main()\n{\n    int a = 5;\n    test([&a]);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test9271.d",
    "content": "// PERMUTE_ARGS:\n\nimport algorithm = imports.test9271a;\n\nbool any(alias predicate, Range)(Range range)\n{\n    return algorithm.any!(predicate)(range);\n}\n\nvoid main()\n{\n    auto arr = [\"foo\"];\n    any!(e => e == \"asd\")(arr); // infinite recursive call -> OK\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test9309.d",
    "content": "immutable(T)[] assumeUnique(T)(ref T[] array) pure nothrow\n{\n    auto result = cast(immutable(T)[]) array;\n    array = null;\n    return result;\n}\n\npure nothrow\nprivate string escapeShellArguments()\n{\n    char[] buf;\n\n    @safe nothrow\n    char[] allocator(size_t size)\n    {\n        return buf = new char[size];\n    }\n\n    escapeShellArgument!allocator(\"foo\");\n    return assumeUnique(buf);\n}\n\n@safe nothrow\nauto escapeShellArgument(alias allocator)(in char[] arg)\n{\n    auto buf = allocator(4);\n    buf[0] = 'f';\n    buf[1] = 'o';\n    buf[2] = 'o';\n    buf[3] = '\\0';\n}\n\nvoid main()\n{\n    string res = escapeShellArguments();\n    if (res != \"foo\\0\") assert(0);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/test9495.d",
    "content": "// PERMUTE_ARGS:\n\nimport core.vararg;\n\nint func1(int a, ...)\n{\n  auto result = va_arg!int(_argptr);\n  return result;\n}\n\nvoid test9495a()\n{\n  assert(func1(5, 12345678) == 12345678);\n}\n\nint func2(const(char)[] a, ...)\n{\n  auto result = va_arg!int(_argptr);\n  return result;\n}\n\nvoid test9495b()\n{\n  assert(func2(\"5\", 12345678) == 12345678);\n}\n\nvoid main(string[] args)\n{\n  test9495a();\n  test9495b();\n}"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testaa.d",
    "content": "// PERMUTE_ARGS: -fPIC\n\n/* Test associative arrays */\n\nextern(C) int printf(const char*, ...);\nextern(C) int memcmp(const void *s1, const void *s2, size_t n);\n\nimport core.memory;  // for GC.collect\nimport std.random;   // for uniform random numbers\n\n/************************************************/\n\nint[char[]] nametable;\n\nvoid insert(string name, int value)\n{\n    nametable[name] = value;\n}\n\nint retrieve(string name)\n{\n    return nametable[name];\n}\n\nvoid test1()\n{   int v;\n\n    printf(\"test1.a\\n\");\n    insert(\"hello\", 1);\n    printf(\"test1.b\\n\");\n    insert(\"world\", 2);\n    printf(\"test1.c\\n\");\n    v = retrieve(\"hello\");\n    assert(v == 1);\n    v = retrieve(\"world\");\n    assert(v == 2);\n    v = retrieve(\"world\");\n    assert(v == 2);\n\n    nametable.rehash;\n    v = retrieve(\"world\");\n    assert(v == 2);\n}\n\n/************************************************/\n\n\nvoid test2()\n{\n    int[string] aa;\n    string[] keys;\n    int[] values;\n\n    printf(\"test2()\\n\");\n\n    /*************/\n\n    assert(aa == null);\n    assert(aa.length == 0);\n\n    keys = aa.keys;\n    assert(keys.length == 0);\n\n    values = aa.values;\n    assert(values.length == 0);\n\n    aa.rehash;\n    assert(aa.length == 0);\n\n    /*************/\n\n    aa[\"hello\"] = 3;\n    assert(aa[\"hello\"] == 3);\n    aa[\"hello\"]++;\n    assert(aa[\"hello\"] == 4);\n\n    assert(aa.length == 1);\n\n    keys = aa.keys;\n    assert(keys.length == 1);\n    assert(memcmp(keys[0].ptr, cast(char*)\"hello\", 5) == 0);\n\n    values = aa.values;\n    assert(values.length == 1);\n    assert(values[0] == 4);\n\n    aa.rehash;\n    assert(aa.length == 1);\n    assert(aa[\"hello\"] == 4);\n}\n\n/************************************************/\n\nvoid test4()\n{\n    int[const(ubyte)[]] b;\n    const(ubyte)[] x;\n    b[x] = 3;\n    assert(b[x] == 3);\n}\n\n/************************************************/\n\nvoid test5()\n{\n    int[immutable(short)[]] b;\n    immutable(short)[] x;\n    b[x] = 3;\n    assert(b[x] == 3);\n}\n\n/************************************************/\n\nvoid test6()\n{\n    int[const(int)[]] b;\n    const(int)[] x;\n    b[x] = 3;\n    assert(b[x] == 3);\n}\n\n/************************************************/\n\nvoid test7()\n{\n    int[immutable(uint)[]] b;\n    immutable(uint)[] x;\n    b[x] = 3;\n    assert(b[x] == 3);\n}\n\n/************************************************/\n\nvoid test8()\n{\n    int[immutable(long)[]] b;\n    immutable(long)[] x;\n    b[x] = 3;\n    assert(b[x] == 3);\n}\n\n/************************************************/\n\nvoid test9()\n{\n    int[immutable(ulong)[]] b;\n    immutable(ulong)[] x;\n    b[x] = 3;\n    assert(b[x] == 3);\n}\n\n/************************************************/\n\nclass A10 {}\n\nint[immutable(A10)[]] foo10;\n\nvoid test10()\n{\n    auto key = new immutable(A10)[2];\n\n    cast()(key[0]) = new A10();\n    foo10[key] = 0;\n    assert(key in foo10);\n    assert(!(key !in foo10));\n}\n\n\n/************************************************/\n\nstruct Value\n{\n    uint x,y,z,t;\n}\n\nstruct Key\n{\n    int a,b,c,d;\n\n    static int hash, cmp, equals;\n\n    size_t toHash() const\n    {\n        hash = 1;\n        return a + b + c + d;\n    }\n\n    int opCmp(ref const Key s) const\n    {\n        cmp = 1;\n        int x;\n\n        x = a - s.a;\n        if (x == 0)\n        {   x = b - s.b;\n            if (x == 0)\n            {   x = c - s.c;\n                if (x == 0)\n                    x = d - s.d;\n            }\n        }\n        return x;\n    }\n\n    bool opEquals(ref const Key s) const\n    {\n        printf(\"opEquals()\\n\");\n        equals = 1;\n        return (a == s.a && b == s.b && c == s.c && d == s.d);\n    }\n}\n\nvoid test11()\n{\n    Value[Key] table;\n\n    Value* p;\n    Value v;\n    Value r;\n    Key k;\n\n    v.x = 7;\n    v.y = 8;\n    v.z = 9;\n    v.t = 10;\n\n    k.a = 1;\n    k.b = 2;\n    k.c = 3;\n    k.d = 4;\n\n    p = k in table;\n    assert(!p);\n\n    table[k] = v;\n    p = k in table;\n    assert(p);\n\n    table.rehash;\n    p = k in table;\n    assert(p);\n\n    r = table[k];\n    assert(v == r);\n\n    table.remove(k);\n    assert(!(k in table));\n\n    printf(\"Key.hash = %d\\n\", Key.hash);\n    assert(Key.hash == 1);\n    printf(\"Key.cmp = %d\\n\", Key.cmp);\n    printf(\"Key.equals = %d\\n\", Key.equals);\n    assert(Key.cmp == 1 && !Key.equals || !Key.cmp && Key.equals == 1);\n}\n\n\n/************************************************/\n\nstruct S12\n{\n    byte number;\n    char[] description;\n    char[] font_face;\n    byte font_size;\n    ushort flags;\n    int colour_back;\n    int colour_fore;\n    byte charset;\n}\n\nvoid test12()\n{\n    S12[] x;\n    printf(\"size %d\\n\",S12.sizeof);\n    printf(\"align %d\\n\",S12.alignof);\n    printf(\"offset %d\\n\",S12.description.offsetof);\n\n    for (int i=0;i<3;i++) {\n        S12 s;\n        s.font_face=\"font face\".dup;\n        x ~= s;\n    }\n\n/* works fine\n    S12 s;\n    s.font_face=\"font face\".dup;\n    x ~= s;\n    s.font_face=\"font face\".dup;\n    x ~= s;\n    s.font_face=\"font face\".dup;\n    x ~= s;\n    s.font_face=\"font face\".dup;\n    x ~= s;\n*/\n    GC.collect();\n    printf(\"%.*s\\n\",x[0].font_face.length,x[0].font_face.ptr);\n    printf(\"%.*s\\n\",x[1].font_face.length,x[1].font_face.ptr);\n}\n\n\n/************************************************/\n\nvoid test13()\n{\n    int[string] array;\n    array[\"eins\"]=1;\n    array[\"zwei\"]=2;\n    array[\"drei\"]=3;\n\n    assert(array.length==3);\n\n    int[string] rehashed=array.rehash;\n    assert(rehashed is array);\n\n    string[] key = array.keys;\n    assert(key.length==3);\n\n    bool[3] have;\n\n    assert(!have[0]);\n    assert(!have[1]);\n    assert(!have[2]);\n\n    foreach(string value; key){\n        switch(value){\n            case \"eins\":{\n                have[0]=true;\n                break;\n            }case \"zwei\":{\n                have[1]=true;\n                break;\n            }case \"drei\":{\n                have[2]=true;\n                break;\n            }default:{\n                assert(0);\n            }\n        }\n    }\n\n    assert(have[0]);\n    assert(have[1]);\n    assert(have[2]);\n}\n\n/************************************************/\n\nvoid test14()\n{\n    int[char[]] aa;\n\n    aa[\"hello\"] = 3;\n    assert(aa[\"hello\"] == 3);\n    assert(\"hello\" in aa);\n    //delete aa[\"hello\"];\n    aa.remove(\"hello\");\n    assert(!(\"hello\" in aa));\n}\n\n/************************************************/\n\nclass SomeClass\n{\n    this(char value)\n    {\n        printf(\"class created\\n\");\n        _value = value;\n    }\n\n    ~this()\n    {\n        printf(\"class killed (%d)\\n\", _value);\n    }\n\n    char value()\n    {\n        return _value;\n    }\n\n    private\n    {\n        char _value;\n    }\n}\n\nchar[] allChars = [ 'a', 'b', 'c', 'e', 'z', 'q', 'x' ];\n\nSomeClass[char] _chars;\n\nvoid _realLoad()\n{\n    printf(\"Loading...\\n\");\n    foreach(char ch; allChars)\n    {\n        _chars[ch] = new SomeClass(ch);\n    }\n}\n\n\n\nvoid test15()\n{\n    _realLoad();\n    int j;\n\n    for (int i = 0; i < 10000; i++)\n    {\n        foreach(char ch; allChars)\n        {\n            SomeClass obj = _chars[ch];\n            j += obj.value;\n        }\n        GC.collect();\n    }\n    printf(\"j = %d\\n\", j);\n    assert(j == 7500000);\n}\n\n\n/************************************************/\n\nvoid test16()\n{\n    int[int] aa;\n\n    Random gen;\n    for (int i = 0; i < 50000; i++)\n    {\n        int key = uniform(0, int.max, gen);\n        int value = uniform(0, int.max, gen);\n\n        aa[key] = value;\n    }\n\n    int[] keys = aa.keys;\n    assert(keys.length == aa.length);\n\n    int j;\n    foreach (k; keys)\n    {\n        assert(k in aa);\n        j += aa[k];\n    }\n    printf(\"test16 = %d\\n\", j);\n\n    int m;\n    foreach (k, v; aa)\n    {\n        assert(k in aa);\n        assert(aa[k] == v);\n        m += v;\n    }\n    assert(j == m);\n\n    m = 0;\n    foreach (v; aa)\n    {\n        m += v;\n    }\n    assert(j == m);\n\n    int[] values = aa.values;\n    assert(values.length == aa.length);\n\n    foreach(k; keys)\n    {\n        aa.remove(k);\n    }\n    assert(aa.length == 0);\n\n    for (int i = 0; i < 1000; i++)\n    {\n        int key2 = uniform(0, int.max, gen);\n        int value2 = uniform(0, int.max, gen);\n\n        aa[key2] = value2;\n    }\n    foreach(k; aa)\n    {\n        if (k < 1000)\n            break;\n    }\n    foreach(k, v; aa)\n    {\n        if (k < 1000)\n            break;\n    }\n}\n\n/************************************************/\n\nvoid dummy17()\n{\n}\n\nint[string] bb17;\n\nint foo17()\n{\n    foreach(string s, int i; bb17)\n    {\n        dummy17();\n    }\n\n    bb17[\"a\"] = 1;\n\n    foreach(int b; bb17)\n    {\n        try{\n            throw new Error(\"foo\");\n        }catch(Error e){\n            assert(e);\n            return 0;\n        }catch(Throwable){\n            assert(0);\n        }\n        assert(0);\n    }\n\n    assert(0);\n}\n\nvoid test17()\n{\n    int i = foo17();\n    printf(\"foo17 = %d\\n\", i);\n    assert(i == 0);\n}\n\n/************************************************/\n\nvoid test18()\n{\n    int[uint] aa;\n\n    aa[1236448822] = 0;\n    aa[2716102924] = 1;\n    aa[ 315901071] = 2;\n\n    aa.remove(1236448822);\n    printf(\"%d\\n\", aa[2716102924]);\n    assert(aa[2716102924] == 1);\n}\n\n\n/************************************************/\n\nvoid test19()\n{\n    immutable(char[5])[int] aa = ([3:\"hello\", 4:\"betty\"]);\n\n    assert(aa[3] == \"hello\");\n    assert(aa[4] == \"betty\");\n\n    auto keys = aa.keys;\n    printf(\"%d\\n\", keys[0]);\n    printf(\"%d\\n\", keys[1]);\n\n    auto vs = aa.values;\n    printf(\"%.*s\\n\", vs[0].length, vs[0].ptr);\n    printf(\"%.*s\\n\", vs[1].length, vs[1].ptr);\n\n    string aavalue_typeid = typeid(typeof(aa.values)).toString();\n    printf(\"%.*s\\n\", aavalue_typeid.length, aavalue_typeid.ptr);\n\n    printf(\"%.*s\\n\", aa[3].length, aa[3].ptr);\n    printf(\"%.*s\\n\", aa[4].length, aa[4].ptr);\n}\n\n/************************************************/\n\nvoid test20()\n{\n    string[int] aa = ([3:\"hello\", 4:\"betty\"]);\n\n    assert(aa[3] == \"hello\");\n    assert(aa[4] == \"betty\");\n\n    auto keys = aa.keys;\n    printf(\"%d\\n\", keys[0]);\n    printf(\"%d\\n\", keys[1]);\n\n    auto values = aa.values;\n    printf(\"%.*s\\n\", values[0].length, values[0].ptr);\n    printf(\"%.*s\\n\", values[1].length, values[1].ptr);\n\n    string aavalue_typeid = typeid(typeof(aa.values)).toString();\n    printf(\"%.*s\\n\", aavalue_typeid.length, aavalue_typeid.ptr);\n\n    printf(\"%.*s\\n\", aa[3].length, aa[3].ptr);\n    printf(\"%.*s\\n\", aa[4].length, aa[4].ptr);\n}\n\n/************************************************/\n\nvoid test21()\n{\n    ushort[20] key = 23;\n    int[ushort[20]] aa;\n    aa[key] = 42;\n    auto x = aa[key];\n    assert(x == 42);\n    printf(\"foo\\n\");\n}\n\n/************************************************/\n\nvoid test22()\n{\n    int[string] stopWords = [ \"abc\"[]:1 ];\n    assert(\"abc\"[] in stopWords);\n}\n\n/************************************************/\n\nvoid test23()\n{\n    uint[char[]][] fractal;\n    fractal.length = 10;\n}\n\n/************************************************/\n\nvoid test24()\n{\n    int[string] x;\n    char[] y;\n    if (y in x)\n    {\n        int z = x[y];\n    }\n}\n\n/************************************************/\n\nvoid test25()\n{\n    string[string] aa;\n    foreach (k,v; aa)\n    {\n    }\n}\n\n/************************************************/\n\nclass Tag\n{\n    string[string] attr;\n}\n\nvoid foo26(const(Tag) tag_)\n{\n    foreach(k,v;tag_.attr) { }\n}\n\nvoid test26()\n{\n}\n\n/************************************************/\n\nvoid test27()\n{\n    int[int] s;\n    s = s.init;\n}\n\n/************************************************/\n\nvoid test28()\n{\n    auto a1 = [ 1:10.0, 2:20, 3:15 ];\n    auto a2 = [ 1:10.0, 2:20, 3:15 ];\n    assert(a1 !is a2);\n    assert(a1 == a2);\n    a2[7] = 23;\n    assert(a1 != a2);\n    a2.remove(7);\n    assert(a1 == a2);\n    a1.rehash;\n    assert(a1 == a2);\n    a2[2] = 18;\n    assert(a1 != a2);\n}\n\n/************************************************/\n\nvoid test29()\n{\n    auto gammaFunc = [-1.5:2.363, -0.5:-3.545, 0.5:1.772];\n\n    // write all keys\n    foreach (k; gammaFunc.byKey()) {\n       printf(\"%f\\n\", k);\n    }\n\n    // write all values\n    foreach (v; gammaFunc.byValue()) {\n       printf(\"%f\\n\", v);\n    }\n}\n\n/************************************************/\n\nstring toString(int value)\n{\n    char[] result = new char[12];\n\n    uint ndigits = 0;\n    do\n    {\n        const c = cast(char) ((value % 10) + '0');\n        value /= 10;\n        ndigits++;\n        result[$ - ndigits] = c;\n    }\n    while (value);\n    return cast(string) result[$ - ndigits .. $];\n}\n\nvoid test30()\n{\n    int[string] aa;\n    for(int i = 0; i < 100000; i++)\n    {\n        string s = toString(i);\n        aa[s] = i;\n    }\n}\n\n/************************************************/\n\nvoid test31()\n{\n    int[int] test;\n    test[0] = 0;\n    test[1] = 1;\n    test[2] = 2;\n\n    bool flag = false;\n    foreach( k, v; test){\n        //printf(\"loop: %d %d\\n\", k, v);\n        assert(!flag);\n        flag = true;\n        break;\n    }\n}\n\n/************************************************/\n\nvoid test32()\n{\n    uint[ushort] aa;\n    aa[1] = 1;\n    aa[2] = 2;\n    aa[3] = 3;\n    aa[4] = 4;\n    aa[5] = 5;\n    foreach(v; aa)\n    {\n        printf(\"%x\\n\", v);\n        assert(v >= 1 && v <= 5);\n    }\n}\n\n/************************************************/\n\ntemplate ICE3996(T : V[K], K, V) {}\n\nstruct Bug3996 {}\n\nstatic assert(!is( ICE3996!(Bug3996) ));\n\n/************************************************/\n\nvoid bug4826c(T)(int[int] value, T x) {}\n\nvoid test4826c()\n{\n    AssociativeArray!(int, int) z;\n    bug4826c(z,1);\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5131\n\nstruct ICE5131\n{\n    this(int n) {}\n    ICE5131 opAssign(int x) { return this; }\n}\n\nvoid test5131()\n{\n    ICE5131[string] a;\n    a[\"ICE?\"] = 1;  // call ctor\n    a[\"ICE?\"] = 1;  // call opAssign\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6178\n\nbool test6178a()\n{\n    // AA value setting through identity opAssign\n\n    int assign = 0;\n    struct S\n    {\n        int value = 10;\n\n        void opAssign(S rhs)\n        {\n            ++assign;\n            assert(value == 10);\n        }\n    }\n\n    int count = 0;\n    int makeKey() { return ++count; }\n\n    S[int] aa;\n    assert(aa.length == 0);\n\n    aa[makeKey()] = S();\n    assert(assign == 0);\n    assert(aa.length == 1 && 1 in aa);\n\n    aa[1] = S();\n    assert(assign == 1);\n    assert(aa.length == 1 && 1 in aa);\n\n    return true;\n}\n\nbool test6178b()\n{\n    // AA value setting through implicit ctor call + non-identity opAssign\n\n    int ctor = 0;\n    int assign = 0;\n    struct S\n    {\n        int value = 10;\n\n        @disable this();\n\n        this(int n)\n        {\n            ++ctor;\n            assert(value == 10);\n            value = 20;\n        }\n        void opAssign(int rhs)\n        {\n            ++assign;\n            assert(value == 20);\n            assert(rhs == 30);\n            value = rhs;\n        }\n    }\n\n    int count = 0;\n    int makeKey() { return ++count; }\n\n    S[int] aa;\n    assert(aa.length == 0);\n\n    aa[makeKey()] = 20;\n    assert(assign == 0 && ctor == 1 && count == 1);\n    assert(aa.length == 1 && (1 in aa));\n\n    aa[1] = 30;\n    assert(assign == 1 && ctor == 1);\n    assert(aa.length == 1 && 1 in aa);\n\n    return true;\n}\n\nbool test6178c()\n{\n    // AA value setting through non-identity opAssign\n\n    struct S\n    {\n        //this(int) {}\n        // not possible to perform implicit ctor call\n        void opAssign(int) {}\n    }\n\n    S[int] aa;\n    assert(aa.length == 0);\n\n    if (!__ctfe)\n    {\n        // currently CTFE does not support throwing RangeError\n        import core.exception : RangeError;\n        try { aa[1] = 1; assert(0); } catch (RangeError) {}\n\n        // The above line is exactly same as:\n        try { aa[1].opAssign(1); assert(0); } catch (RangeError) {}\n    }\n    assert(aa.length == 0);\n\n    aa[1] = S();\n    aa[1] = 1;\n    assert(aa.length == 1);\n\n    return true;\n}\n\nbool test6178d()\n{\n    // AA value setting through implicit ctor call + alias this\n\n    int ctor;\n    struct S\n    {\n        this(int n) { ++ctor; value = n; }\n\n        int value;\n        alias value this;\n    }\n\n    S[int] aa;\n    assert(ctor == 0);\n    assert(aa.length == 0);\n\n    aa[1] = 0;      // implicit ctor call + blit assign\n    assert(aa[1].value == 0 && ctor == 1);\n    assert(aa.length == 1);\n\n    aa[1] = 1;      // set through alias this\n    assert(aa[1].value == 1 && ctor == 1);\n    assert(aa.length == 1);\n\n    return true;\n}\n\nbool test6178e()\n{\n    // AA value setting through alias this\n\n    struct S\n    {\n        int value;\n        alias value this;\n    }\n\n    S[int] aa;\n    assert(aa.length == 0);\n\n    if (!__ctfe)\n    {\n        // currently CTFE does not support throwing RangeError\n        import core.exception : RangeError;\n        try { aa[1] = 1; assert(0); } catch (RangeError) {}\n\n        // The above line is exactly same as:\n        try { aa[1].value = 1; assert(0); } catch (RangeError) {}\n    }\n    assert(aa.length == 0);\n\n    aa[1] = S(0);   // construct + blit assign\n    assert(aa[1].value == 0 && aa.length == 1);\n\n    aa[1] = 1;      // set through alias this\n    assert(aa[1].value == 1 && aa.length == 1);\n\n    return true;\n}\n\nvoid test6178()\n{\n    static assert(test6178a()); // ctfe check\n    test6178a();                // runtime test\n\n    static assert(test6178b());\n    test6178b();\n\n    static assert(test6178c());\n    test6178c();\n\n    static assert(test6178d());\n    test6178d();\n\n    static assert(test6178e());\n    test6178e();\n}\n\nvoid test6178x()\n{\n    return; // depends on AA implementation\n    static int ctor, cpctor, dtor;\n\n    static struct S\n    {\n        this(int)  { ++ctor;   printf(\"ctor\\n\");   }\n        this(this) { ++cpctor; printf(\"cpctor\\n\"); }\n        ~this()    { ++dtor;   printf(\"dtor\\n\");   }\n    }\n    static struct X\n    {\n        this(int) {}\n        void opAssign(int) {}\n    }\n\n    X[S] aa1;\n    S[int] aa2;\n\n    {\n        auto value = S(1);\n        assert(ctor==1 && cpctor==0 && dtor==0);\n\n        ref getRef(ref S s = value) { return s; }\n        auto getVal() { return value; }\n\n        aa1[value] = 10;\n        assert(ctor==1 && cpctor==1 && dtor==0); //call copy ctor when we putting 'value' to aa1\n\n        aa1[getRef()] = 20;\n        assert(ctor==1 && cpctor==1 && dtor==0); //copy ctor wasn't called because we didn't create a new entry in aa, using an existing key\n\n        aa1[getVal()] = 20;\n        assert(ctor==1 && cpctor==2 && dtor==1); //call copy ctor and dtor, because we pass key by value\n\n        aa2[1] = value;\n        assert(ctor==1 && cpctor==3 && dtor==1); //call copy ctor when we putting `value` to aa2[1]\n\n        aa2[2] = getRef();\n        assert(ctor==1 && cpctor==4 && dtor==1); //call copy ctor when we putting `value` to aa2[2]\n    }\n    assert(ctor==1 && cpctor==4 && dtor==2);     //We've got 3 \"S\" instances that aren't destroyed yet: the key in aa1, aa2[1], aa2[2].\n    assert(ctor + cpctor - aa2.length - aa1.length == dtor);\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10595\n\nstruct S10595\n{\n    bool b = true;\n\n    bool test()\n    {\n        if (!b)  // note: must be a check, not 'return b;'\n            return false;\n\n        return true;\n    }\n}\n\nstruct Wrap10595\n{\n    int i;\n    alias i this;\n    S10595 s;\n}\n\nvoid test10595()\n{\n    {\n        Wrap10595[int] wrap;\n\n        wrap[0] = Wrap10595();\n        wrap[0].i = 0;\n\n        assert(wrap[0].s.test());  // ok\n    }\n\n    {\n        Wrap10595[int] wrap;\n\n        wrap[0] = Wrap10595();\n        wrap[0] = 0;  // note: using 'alias this' to assign\n\n        assert(wrap[0].s.test());  // failure\n    }\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10970\n\nstruct RefCounted10970(T) //if (!is(T == class))\n{\n    struct RefCountedStore\n    {\n    }\n    RefCountedStore _refCounted;\n\n    this(this) {}\n\n    ~this() {}\n}\n\nstruct Array10970(T) if (!is(T : const(bool)))\n{\n    struct Payload\n    {\n    }\n    RefCounted10970!Payload _data;\n}\n\nclass C10970\n{\n    this(string name)\n    {\n        m[name] = Arr();\n    }\n\n    alias Array10970!C10970 Arr;\n    Arr[string] m;\n}\n\nvoid test10970()\n{\n    C10970 c = new C10970(\"test\");\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6433\n\nvoid test6433()\n{\n    int[int] aa;\n    static assert(aa.sizeof != 0);\n    static assert(aa.alignof != 0);\n    static assert(is(typeof(aa.init) == int[int]));\n    static assert(typeof(aa).mangleof == \"Hii\");\n    static assert(typeof(aa).stringof == \"int[int]\");\n    static struct AA { int[int] aa; }\n    static assert(AA.aa.offsetof == 0);\n\n    aa = aa.init;\n    aa[0] = 1;\n    assert(aa.length == 1 && aa[0] == 1);\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6612\n\nvoid test6612()\n{\n    auto aa1 = [1: 2]; // OK\n    auto aa2 = [4: 5]; // OK\n    int[int[int]] aa3 = [aa1:3, aa2:6]; // OK\n    int[int[int]] aa4 = [[1:2]:3, [4:5]:6]; // error\n    int[int[string]] aa5 = [[\"a\":1]:2, [\"b\":3]:4];\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7365\n\nstruct TickDuration\n{\n    bool opEquals(ref const TickDuration rhs) const\n    {\n        return true;\n    }\n}\n\nvoid test7365()\n{\n    TickDuration[Object] aa;\n    aa.keys;\n}\n\n/************************************************/\n\nenum aa5520 = [5 : \"hello\"];\n\nvoid test5520()\n{\n    auto a = aa5520.values;\n}\n\n/************************************************/\n\nenum size_t N6655 = 1;\nint[bar6655.length] foo6655;\nint[N6655] bar6655;\n\n/************************************************/\n\nstruct ChunkLoc {}\n\nChunkLoc Get()\n{\n    return ChunkLoc();\n}\n\nvoid test6799()\n{\n    int[ChunkLoc] aa;\n    aa.remove(Get());\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11359\n\nvoid test11359()\n{\n    class Bar {}\n    static Bar[string] aa;\n    static ref fun() { return aa; }\n\n    string key = \"test\";\n\n    fun[key] = new Bar;\n    assert(aa.length == 1);\n    Bar bar = fun[key];\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11730\n\nstruct SysTime11730\n{\n    ref SysTime11730 opAssign(SysTime11730 rhs)\n    {\n        assert(0);\n    }\n}\n\nstruct Nullable11730(T)\n{\n    T _value;\n\n    void opAssign()(T value)\n    {\n        assert(0);\n    }\n\n    @property ref inout(T) get() inout\n    {\n        assert(0);\n    }\n    alias get this;\n}\n\nvoid test11730()\n{\n    Nullable11730!SysTime11730[string] map;\n    map[\"foo\"] = Nullable11730!SysTime11730();\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14089\n\nstruct S14089\n{\n    int num;\n    S14089 opAssign(S14089 val) { return this; }\n}\n\nvoid test14089()\n{\n    S14089[int] aa;\n    S14089 b = aa[1] = S14089(0);\n    assert(aa[1].num == 0);\n    assert(b.num == 0);\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14144\n\nstruct JSON14144\n{\n    union\n    {\n        double _floating;\n    }\n\n    this(typeof(null))\n    {\n    }\n\n    @trusted pure nothrow typeof(null) opAssign(typeof(null) nothing)\n    {\n        return null;\n    }\n}\n\nvoid test14144()\n{\n    JSON14144[string] x;\n    x[\"wat\"] = null;\n    assert(x.length == 1);\n    assert(\"wat\" in x);\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14321\n\nvoid test14321()\n{\n    struct Foo\n    {\n        static char[8] buf;\n        static char[] op;\n\n        this(int id) { buf[op.length] = 'c'; op = buf[0..op.length + 1]; }\n        this(this) { buf[op.length] = 'p'; op = buf[0..op.length + 1]; }\n        ~this() { buf[op.length] = 'd'; op = buf[0..op.length + 1]; }\n    }\n    Foo[string] foos;\n    assert(Foo.op == \"\");\n    foos[\"test\"] = Foo(42);     // initialization\n    assert(Foo.op == \"c\");\n    foos[\"test\"] = Foo(42);     // assignment\n    assert(Foo.op == \"ccd\");\n\n    struct Bar\n    {\n        static char[8] buf;\n        static char[] op;\n\n        int id;\n        //this(int id) { op ~= \"c\"; }\n        this(this) { buf[op.length] = 'p'; op = buf[0..op.length + 1]; }\n        ~this() { buf[op.length] = 'd'; op = buf[0..op.length + 1]; }\n    }\n    Bar[string] bars;\n    assert(Bar.op == \"\");\n    bars[\"test\"] = Bar(42);     // initialization\n    assert(Bar.op == \"\");\n    bars[\"test\"] = Bar(42);     // assignment\n    assert(Bar.op == \"d\");\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=19112\n\nvoid test19112()\n{\n    int[int[1]] aa;\n    aa[[2]] = 1;\n    assert([2] in aa);\n\n    int[int[]] aa2 = [[1, 2, 3]: 4];\n    int[3] k = [1, 2, 3];\n    assert(*(k in aa2) == 4);\n}\n\n/************************************************/\n\nint main()\n{\n    printf(\"before test 1\\n\");   test1();\n    printf(\"before test 2\\n\");   test2();\n    printf(\"before test 4\\n\");   test4();\n    printf(\"before test 5\\n\");   test5();\n    printf(\"before test 6\\n\");   test6();\n    printf(\"before test 7\\n\");   test7();\n    printf(\"before test 8\\n\");   test8();\n    printf(\"before test 9\\n\");   test9();\n    printf(\"before test 10\\n\");   test10();\n    printf(\"before test 11\\n\");   test11();\n    printf(\"before test 12\\n\");   test12();\n    printf(\"before test 13\\n\");   test13();\n    printf(\"before test 14\\n\");   test14();\n    printf(\"before test 15\\n\");   test15();\n    printf(\"before test 16\\n\");   test16();\n    printf(\"before test 17\\n\");   test17();\n    printf(\"before test 18\\n\");   test18();\n    printf(\"before test 19\\n\");   test19();\n    printf(\"before test 20\\n\");   test20();\n    printf(\"before test 21\\n\");   test21();\n    printf(\"before test 22\\n\");   test22();\n    printf(\"before test 23\\n\");   test23();\n    printf(\"before test 24\\n\");   test24();\n    printf(\"before test 25\\n\");   test25();\n    printf(\"before test 26\\n\");   test26();\n    printf(\"before test 27\\n\");   test27();\n    printf(\"before test 28\\n\");   test28();\n    printf(\"before test 29\\n\");   test29();\n    printf(\"before test 30\\n\");   test30();\n    printf(\"before test 31\\n\");   test31();\n    printf(\"before test 32\\n\");   test32();\n\n    test4826c();\n    test5131();\n    test6178();\n    test6178x();\n    test10595();\n    test10970();\n    test6433();\n    test6612();\n    test7365();\n    test5520();\n    test6799();\n    test11359();\n    test11730();\n    test14089();\n    test14321();\n    test19112();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testaa2.d",
    "content": "// PERMUTE_ARGS:\n\nextern(C) int printf(const char*, ...);\n\n/************************************************/\n\nint[string] a;\n\nsize_t foo(immutable char [3] s)\n{\n    printf(\"foo()\\n\");\n    int[string] b;\n    string[] key;\n    int[] value;\n    printf(\"foo() 2\\n\");\n    key = a.keys;\n    printf(\"foo() 3\\n\");\n    value = a.values;\n    printf(\"foo() 4\\n\");\n    return a.length + b.length;\n}\n\nvoid foo2()\n{\n    int[string] c;\n    string[] key;\n    int[] value;\n    int i;\n\n    assert(c.length == 0);\n    key = c.keys;\n    assert(key.length == 0);\n    value = c.values;\n    assert(value.length == 0);\n\n    c[\"foo\"] = 3;\n    assert(c[\"foo\"] == 3);\n    assert(c.length == 1);\n    key = c.keys;\n    assert(key.length == 1);\n    value = c.values;\n    assert(value.length == 1);\n    assert(value[0] == 3);\n\n    c[\"bar\"] = 4;\n    assert(c[\"bar\"] == 4);\n    assert(c.length == 2);\n    key = c.keys;\n    assert(key.length == 2);\n    value = c.values;\n    assert(value.length == 2);\n\n    for (i = 0; i < key.length; i++)\n    {\n        printf(\"c[\\\"%.*s\\\"] = %d\\n\", key[i].length, key[i].ptr, value[i]);\n    }\n\n    assert(\"foo\" in c);\n    c.remove(\"foo\");\n    assert(!(\"foo\" in c));\n    assert(c.length == 1);\n\n    assert(\"bar\" in c);\n    c.remove(\"bar\");\n    assert(!(\"bar\" in c));\n    assert(c.length == 0);\n}\n\nvoid testaa()\n{\n    size_t i = foo(\"abc\");\n    printf(\"i = %d\\n\", i);\n    assert(i == 0);\n\n    foo2();\n}\n\n/************************************************/\n\nvoid test1899()\n{\n    int[3][string] AA;\n    int[3] x = [5,4,3];\n    AA[\"abc\"] = x;\n    assert(AA[\"abc\"] == x);\n    AA[\"def\"] = [1,2,3];\n    assert(AA[\"def\"]==[1,2,3]);\n}\n\n/************************************************/\n\nvoid foo4523()\n{\n   int[string] aa = [\"test\":0, \"test2\":1];\n\n   bool found = aa.remove(\"test\");\n   assert(found);\n   bool notfound = aa.remove(\"nothing\");\n   assert(!notfound);\n}\n\nvoid test4523()\n{\n    foo4523();\n    static assert({ foo4523(); return true; }());\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3825\n\nimport std.math;    // necessary for ^^=\nvoid test3825()\n{\n    // Check for RangeError is thrown\n    bool thrown(T)(lazy T cond)\n    {\n        import core.exception;\n        bool f = false;\n        try {\n            cond();\n        } catch (RangeError e) { f = true; }\n        return f;\n    }\n\n    int[int] aax;\n    int[][int] aay;\n\n    aax = null, aay = null;\n    assert(thrown(aax[0]));\n    assert(thrown(aax[0]   = aax[0]));  // rhs throws\n    assert(thrown(aax[0]  += aax[0]));  // rhs throws\n    assert(thrown(aax[0] ^^= aax[0]));  // rhs throws\n    assert(thrown(aay[0]  ~= aay[0]));  // rhs throws\n    aax = null;   aax[0]   = 1;  assert(aax[0] ==  1);  // setting aax[0] is OK\n    aax = null;   aax[0]  += 1;  assert(aax[0] == +1);  // setting aax[0] to 0 and modify it is OK\n    aax = null;   aax[0] ^^= 1;  assert(aax[0] ==  0);  // setting aax[0] to 0 and modify it is OK\n    aay = null;   aay[0]  ~= []; assert(aay[0] == []);  // setting aay[0] to 0 and modify it is OK\n    aax = null; ++aax[0];        assert(aax[0] == +1);  // setting aax[0] to 0 and modify it is OK\n    aax = null; --aax[0];        assert(aax[0] == -1);  // setting aax[0] to 0 and modify it is OK\n\n    aax = [0:0], aay = [0:null];\n    assert(thrown(aax[aax[1]]   = 1));  // accessing aax[1] in key part throws\n    assert(thrown(aax[aax[1]]  += 1));  // accessing aax[1] in key part throws\n    assert(thrown(aax[aax[1]] ^^= 1));  // accessing aax[1] in key part throws\n    assert(thrown(aay[aax[1]]  ~= [])); // accessing aax[1] in key part throws\n\n    //assert(thrown(aax[(  aax[1], 0)] = 0));\n    /* accessing aax[1] in key part, why doesn't throw?\n     * Because, in aax[(aax[1], 0)], aax[1] is in lhs of comma expression, and is treated\n     * it has no side effect. Then optimizer eliminate it completely, and\n     * whole expression succeed to run in runtime. */\n    int n = 0;\n    assert(thrown(aax[((){ n=aax[1]; return 0;}())] = 0)); // accessing aax[1] in key part, throws OK\n\n    // This works as expected.\n    int[int][int] aaa;\n    aaa[0][0] = 0;              assert(aaa[0][0] == 0); // setting aaa[0][0] is OK\n\n    // real test cases\n    void bug3825()\n    {\n        string[] words = [\"how\", \"are\", \"you\", \"are\"];\n\n        int[string] aa1;\n        foreach (w; words)\n            aa1[w] = ((w in aa1) ? (aa1[w] + 1) : 2);\n        //writeln(aa1); // Prints: [how:1,you:1,are:2]\n\n        int[string] aa2;\n        foreach (w; words)\n            if (w in aa2)\n                aa2[w]++;\n            else\n                aa2[w] = 2;\n        //writeln(aa2); // Prints: [how:2,you:2,are:3]\n\n        assert(aa1 == aa2);\n        assert(aa1 == [\"how\":2, \"you\":2, \"are\":3]);\n        assert(aa2 == [\"how\":2, \"you\":2, \"are\":3]);\n    }\n    void bug5021()\n    {\n        int func()\n        {\n            throw new Exception(\"It's an exception.\");\n        }\n\n        int[string] arr;\n        try\n        {\n            arr[\"hello\"] = func();\n        }\n        catch(Exception e)\n        {\n        }\n        assert(arr.length == 0);\n    }\n    void bug7914()\n    {\n        size_t[ubyte] aa;\n        aa[0] = aa.length;\n        assert(aa[0] == 0);\n    }\n    void bug8070()\n    {\n        Object[string] arr;\n\n        class A\n        {\n            this()\n            {\n                // at this point:\n                assert(\"x\" !in arr);\n            }\n        }\n\n        arr[\"x\"] = new A();\n    }\n    bug3825();\n    bug5021();\n    bug7914();\n    bug8070();\n}\n\nvoid test3825x()\n{\n    return; // depends on AA implementation\n    static int ctor, cpctor, dtor;\n\n    static struct S\n    {\n        this(int)  { ++ctor; }\n        this(this) { ++cpctor; }\n        ~this()    { ++dtor; }\n    }\n\n    int[S] aa;\n    {\n        auto value = S(1);\n        assert(ctor==1 && cpctor==0 && dtor==0);\n\n        ref getRef(ref S s = value) { return s; }\n        auto getVal() { return value; }\n\n        aa[value] = 10;\n        assert(ctor==1 && cpctor==1 && dtor==0);\n\n        aa[getRef()] += 1;\n        assert(ctor==1 && cpctor==1 && dtor==0);\n\n        aa[getVal()] += 1;\n        assert(ctor==1 && cpctor==2 && dtor==1);\n    }\n    assert(ctor==1 && cpctor==2 && dtor==2);\n    assert(ctor + cpctor - aa.length == dtor);\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10106\n\nstruct GcPolicy10106 {}\n\nstruct Uint24Array10106(SP = GcPolicy10106)\n{\n    this(this) {}\n}\n\nstruct InversionList10106(SP = GcPolicy10106)\n{\n    Uint24Array10106!SP data;\n}\n\nalias InversionList10106!GcPolicy10106 CodepointSet10106;\n\nstruct PropertyTable10106\n{\n    CodepointSet10106[string] table;\n}\n\n/************************************************/\n\nint main()\n{\n    testaa();\n    test1899();\n    test4523();\n    test3825();\n    test3825x();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testaa3.d",
    "content": "\n/***************************************************/\n\n/* Test all aa properties (length, values, keys, opApply(Key, Value), opApply_r(Value),\n * dup, byKey, byValue, rehash, opIndex, opIndexAssign, opIn_r)\n *\n * With all aas: literal, variable, ref parameter, rvalue\n */\n\nint testLiteral()\n{\n    assert([5 : 4].length == 1);\n    assert([5 : 4].values == [4]);\n    assert([5 : 4].keys == [5]);\n    foreach (k, v; [5 : 4])\n        assert(k == 5 && v == 4);\n    foreach (v; [5 : 4])\n        assert(v == 4);\n    assert([5 : 4].dup == [5 : 4]);\n    assert([5 : 4].dup);\n    if (!__ctfe)\n    foreach (k; [5 : 4].byKey)\n        assert(k == 5);\n    if (!__ctfe)\n    foreach (v; [5 : 4].byValue)\n        assert(v == 4);\n    assert([5 : 4].rehash == [5 : 4]);\n    assert([5 : 4][5] == 4);\n    assert([5 : 4].get(5, 2) == 4);\n    assert([5 : 4].get(1, 2) == 2);\n    //assert(([5 : 4][3] = 7) == 7);\n    assert(*(5 in [5 : 4]) == 4);\n    return 1;\n}\n\nint testVar()\n{\n    auto aa = [5 : 4];\n    assert(aa.length == 1);\n    assert(aa.values == [4]);\n    assert(aa.keys == [5]);\n    foreach (k, v; aa)\n        assert(k == 5 && v == 4);\n    foreach (v; aa)\n        assert(v == 4);\n    assert(aa.dup == aa);\n    assert(aa.dup);\n    {\n        auto bb = aa.dup();\n        assert(bb == aa);\n        //assert(aa !is bb);  // issue in ctfeIdentity\n        assert(&aa[5] !is &bb[5]);\n        bb[5] = 10;\n        assert(aa[5] == 4);\n        assert(bb[5] == 10);\n    }\n    if (!__ctfe)\n    foreach (k; aa.byKey)\n        assert(k == 5);\n    if (!__ctfe)\n    foreach (v; aa.byValue)\n        assert(v == 4);\n    assert(aa.rehash == aa);\n    assert(aa[5] == 4);\n    assert(aa.get(5, 2) == 4);\n    assert(aa.get(1, 2) == 2);\n    assert(*(5 in aa) == 4);\n    assert((aa[3] = 7) == 7);\n    return 1;\n}\n\nint testVarConst()\n{\n    const aa = [5 : 4];\n    assert(aa.length == 1);\n    assert(aa.values == [4]);\n    assert(aa.keys == [5]);\n    foreach (k, v; aa)\n        assert(k == 5 && v == 4);\n    foreach (v; aa)\n        assert(v == 4);\n    //assert(aa.dup == aa);\n    assert(aa.dup);\n    {\n        auto bb = aa.dup();\n        //assert(bb == aa);\n        //assert(aa !is bb);  // issue in ctfeIdentity\n        assert(&aa[5] !is &bb[5]);\n    }\n    if (!__ctfe)\n    foreach (k; aa.byKey)\n        assert(k == 5);\n    if (!__ctfe)\n    foreach (v; aa.byValue)\n        assert(v == 4);\n    //assert(aa.rehash == aa);\n    assert(aa[5] == 4);\n    assert(aa.get(5, 2) == 4);\n    assert(aa.get(1, 2) == 2);\n    assert(*(5 in aa) == 4);\n    //assert((aa[3] = 7) == 7);\n    return 1;\n}\n\nint testVarImmutable()\n{\n    immutable aa = [5 : 4];\n    assert(aa.length == 1);\n    assert(aa.values == [4]);\n    assert(aa.keys == [5]);\n    foreach (k, v; aa)\n        assert(k == 5 && v == 4);\n    foreach (v; aa)\n        assert(v == 4);\n    //assert(aa.dup == aa);\n    assert(aa.dup);\n    {\n        auto bb = aa.dup();\n        //assert(bb == aa);\n        //assert(aa !is bb);  // issue in ctfeIdentity\n        assert(&aa[5] !is &bb[5]);\n    }\n    if (!__ctfe)\n    foreach (k; aa.byKey)\n        assert(k == 5);\n    if (!__ctfe)\n    foreach (v; aa.byValue)\n        assert(v == 4);\n    // assert(aa.rehash == aa);\n    assert(aa[5] == 4);\n    assert(aa.get(5, 2) == 4);\n    assert(aa.get(1, 2) == 2);\n    assert(*(5 in aa) == 4);\n    //assert((aa[3] = 7) == 7);\n    return 1;\n}\n\nint testPointer()\n{\n    auto x = [5 : 4];\n    auto aa = &x;\n    assert(aa.length == 1);\n    assert(aa.values == [4]);\n    assert(aa.keys == [5]);\n    // foreach (k, v; aa)\n    //     assert(k == 5 && v == 4);\n    // foreach (v; aa)\n    //     assert(v == 4);\n    assert(aa.dup == *aa);\n    assert(aa.dup);\n    {\n        auto bb = aa.dup();\n        assert(bb == *aa);\n        //assert(aa !is bb);  // issue in ctfeIdentity\n        assert(&(*aa)[5] !is &bb[5]);\n        bb[5] = 10;\n        assert((*aa)[5] == 4);\n        assert(bb[5] == 10);\n    }\n    if (!__ctfe)\n    foreach (k; aa.byKey)\n        assert(k == 5);\n    if (!__ctfe)\n    foreach (v; aa.byValue)\n        assert(v == 4);\n    if (!__ctfe)\n    assert(aa.rehash == *aa);\n    assert((*aa)[5] == 4);\n    assert(aa.get(5, 2) == 4);\n    assert(aa.get(1, 2) == 2);\n    // assert(*(5 in aa) == 4);\n    if (!__ctfe)\n    assert(((*aa)[3] = 7) == 7);\n    return 1;\n}\n\nint testPointerConst()\n{\n    const x = [5 : 4];\n    const aa = &x;\n    assert(aa.length == 1);\n    assert(aa.values == [4]);\n    assert(aa.keys == [5]);\n    // foreach (k, v; aa)\n    //     assert(k == 5 && v == 4);\n    // foreach (v; aa)\n    //     assert(v == 4);\n    // assert(aa.dup == *aa);\n    assert(aa.dup);\n    {\n        auto bb = aa.dup();\n        //assert(bb == aa);\n        //assert(aa !is bb);  // issue in ctfeIdentity\n        assert(&(*aa)[5] !is &bb[5]);\n    }\n    if (!__ctfe)\n    foreach (k; aa.byKey)\n        assert(k == 5);\n    if (!__ctfe)\n    foreach (v; aa.byValue)\n        assert(v == 4);\n    // assert(aa.rehash == aa);\n    assert((*aa)[5] == 4);\n    assert(aa.get(5, 2) == 4);\n    assert(aa.get(1, 2) == 2);\n    // assert(*(5 in aa) == 4);\n    // assert(((*aa)[3] = 7) == 7);\n    return 1;\n}\n\nint testPointerImmutable()\n{\n    immutable x = [5 : 4];\n    auto aa = &x;\n    assert(aa.length == 1);\n    assert(aa.values == [4]);\n    assert(aa.keys == [5]);\n    // foreach (k, v; aa)\n    //     assert(k == 5 && v == 4);\n    // foreach (v; aa)\n    //     assert(v == 4);\n    // assert(aa.dup == *aa);\n    assert(aa.dup);\n    {\n        auto bb = aa.dup();\n        //assert(bb == (*aa));\n        //assert(aa !is bb);  // issue in ctfeIdentity\n        assert(&(*aa)[5] !is &bb[5]);\n    }\n    if (!__ctfe)\n    foreach (k; aa.byKey)\n        assert(k == 5);\n    if (!__ctfe)\n    foreach (v; aa.byValue)\n        assert(v == 4);\n    // assert(aa.rehash == aa);\n    assert((*aa)[5] == 4);\n    assert(aa.get(5, 2) == 4);\n    assert(aa.get(1, 2) == 2);\n    // assert(*(5 in aa) == 4);\n    // assert(((*aa)[3] = 7) == 7);\n    return 1;\n}\n\nint testRef()\n{\n    auto aa = [5 : 4];\n    return testRefx(aa);\n}\nint testRefx(ref int[int] aa)\n{\n    assert(aa.length == 1);\n    assert(aa.values == [4]);\n    assert(aa.keys == [5]);\n    foreach (k, v; aa)\n        assert(k == 5 && v == 4);\n    foreach (v; aa)\n        assert(v == 4);\n    assert(aa.dup == aa);\n    assert(aa.dup);\n    {\n        auto bb = aa.dup();\n        assert(bb == aa);\n        //assert(aa !is bb);  // issue in ctfeIdentity\n        assert(&aa[5] !is &bb[5]);\n        bb[5] = 10;\n        assert(aa[5] == 4);\n        assert(bb[5] == 10);\n    }\n    if (!__ctfe)\n    foreach (k; aa.byKey)\n        assert(k == 5);\n    if (!__ctfe)\n    foreach (v; aa.byValue)\n        assert(v == 4);\n    assert(aa.rehash == aa);\n    assert(aa[5] == 4);\n    assert(aa.get(5, 2) == 4);\n    assert(aa.get(1, 2) == 2);\n    assert((aa[3] = 7) == 7);\n    assert(*(5 in aa) == 4);\n    return 1;\n}\n\nint testRet()\n{\n    assert(testRetx().length == 1);\n    assert(testRetx().values == [4]);\n    assert(testRetx().keys == [5]);\n    foreach (k, v; testRetx())\n        assert(k == 5 && v == 4);\n    foreach (v; testRetx())\n        assert(v == 4);\n    assert(testRetx().dup == testRetx());\n    assert(testRetx().dup);\n    if (!__ctfe)\n    foreach (k; testRetx().byKey)\n        assert(k == 5);\n    if (!__ctfe)\n    foreach (v; testRetx().byValue)\n        assert(v == 4);\n    assert(testRetx().rehash == testRetx());\n    assert(testRetx()[5] == 4);\n    assert(testRetx().get(5, 2) == 4);\n    assert(testRetx().get(1, 2) == 2);\n    //assert((testRetx()[3] = 7) == 7);\n    assert(*(5 in testRetx()) == 4);\n    return 1;\n}\nint[int] testRetx()\n{\n    return [5 : 4];\n}\n\nvoid aafunc(int[int] aa) {}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12214\n\nvoid test12214() pure nothrow\n{\n    int[int] aa;\n    auto n = aa.length;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12220\n// https://issues.dlang.org/show_bug.cgi?id=12221\n\nvoid test12220()\n{\n    short[short] hash;\n    short k = hash.get(1, 2);\n    assert(k == 2);\n\n    enum Key : short { a = 10 }\n    short a = hash.get(Key.a, Key.a);\n    assert(a == 10);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12403\n\nvoid test12403()\n{\n    const(int)[int] m;\n    assert(m.get(0, 1) == 1);\n}\n\n/***************************************************/\n\nvoid main()\n{\n    assert(testLiteral());\n    static assert(testLiteral());\n    assert(testVar());\n    static assert(testVar());\n    assert(testVarConst());\n    static assert(testVarConst());\n    assert(testVarImmutable());\n    static assert(testVarImmutable());\n    assert(testPointer());\n    static assert(testPointer());\n    assert(testPointerConst());\n    static assert(testPointerConst());\n    assert(testPointerImmutable());\n    static assert(testPointerImmutable());\n    assert(testRef());\n    static assert(testRef());\n    assert(testRet());\n    static assert(testRet());\n\n    test12220();\n    test12403();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testabi.d",
    "content": "// PERMUTE_ARGS: -release -g\n\nversion(Windows) {}\nelse version(X86_64)\n{\n        /* uncomment to enable tests! */\n        //version = Run_X86_64_Tests;\n}\n\nextern (C) int printf(const char*, ...);\n\ntemplate tuple(A...) { alias A tuple; }\n\nalias byte   B;\nalias short  S;\nalias int    I;\nalias long   L;\nalias float  F;\nalias double D;\nalias real   R;\n\n// Single Type\n\nstruct b        { B a;                  }\nstruct bb       { B a,b;                }\nstruct bbb      { B a,b,c;              }\nstruct bbbb     { B a,b,c,d;            }\nstruct bbbbb    { B a,b,c,d, e;         }\nstruct b6       { B a,b,c,d, e,f;       }\nstruct b7       { B a,b,c,d, e,f,g;     }\nstruct b8       { B a,b,c,d, e,f,g,h;   }\nstruct b9       { B a,b,c,d, e,f,g,h, i;                }\nstruct b10      { B a,b,c,d, e,f,g,h, i,j;              }\nstruct b11      { B a,b,c,d, e,f,g,h, i,j,k;            }\nstruct b12      { B a,b,c,d, e,f,g,h, i,j,k,l;          }\nstruct b13      { B a,b,c,d, e,f,g,h, i,j,k,l, m;       }\nstruct b14      { B a,b,c,d, e,f,g,h, i,j,k,l, m,n;     }\nstruct b15      { B a,b,c,d, e,f,g,h, i,j,k,l, m,n,o;   }\nstruct b16      { B a,b,c,d, e,f,g,h, i,j,k,l, m,n,o,p; }\nstruct b17      { B a,b,c,d, e,f,g,h, i,j,k,l, m,n,o,p, q;      }\nstruct b18      { B a,b,c,d, e,f,g,h, i,j,k,l, m,n,o,p, q,r;    }\nstruct b19      { B a,b,c,d, e,f,g,h, i,j,k,l, m,n,o,p, q,r,s;  }\nstruct b20      { B a,b,c,d, e,f,g,h, i,j,k,l, m,n,o,p, q,r,s,t;}\n\nstruct s        { S a;                  }\nstruct ss       { S a,b;                }\nstruct sss      { S a,b,c;              }\nstruct ssss     { S a,b,c,d;            }\nstruct sssss    { S a,b,c,d, e;         }\nstruct s6       { S a,b,c,d, e,f;       }\nstruct s7       { S a,b,c,d, e,f,g;     }\nstruct s8       { S a,b,c,d, e,f,g,h;   }\nstruct s9       { S a,b,c,d, e,f,g,h, i;  }\nstruct s10      { S a,b,c,d, e,f,g,h, i,j;}\n\nstruct i        { I a;          }       struct l        { L a;          }\nstruct ii       { I a,b;        }       struct ll       { L a,b;        }\nstruct iii      { I a,b,c;      }       struct lll      { L a,b,c;      }\nstruct iiii     { I a,b,c,d;    }       struct llll     { L a,b,c,d;    }\nstruct iiiii    { I a,b,c,d,e;  }       struct lllll    { L a,b,c,d,e;  }\n\nstruct f        { F a;          }       struct d        { D a;          }\nstruct ff       { F a,b;        }       struct dd       { D a,b;        }\nstruct fff      { F a,b,c;      }       struct ddd      { D a,b,c;      }\nstruct ffff     { F a,b,c,d;    }       struct dddd     { D a,b,c,d;    }\nstruct fffff    { F a,b,c,d,e;  }       struct ddddd    { D a,b,c,d,e;  }\n\n// Mixed Size\n\nstruct js       { I a;   S b;   }\nstruct iss      { I a;   S b,c; }\nstruct  si      { S a;   I b;   }\nstruct ssi      { S a,b; I c;   }\nstruct sis      { S a;   I b;  S c; }\n\nstruct ls       { L a;   S b;   }\nstruct lss      { L a;   S b,c; }\nstruct  sl      { S a;   L b;   }\nstruct ssl      { S a,b; L c;   }\nstruct sls      { S a;   L b;  S c; }\n\nstruct li       { L a;   I b;   }\nstruct lii      { L a;   I b,c; }\nstruct  il      { I a;   L b;   }\nstruct iil      { I a,b; L c;   }\nstruct ili      { I a;   L b;  I c; }\n\nstruct df       { D a;   F b;   }\nstruct dff      { D a;   F b,c; }\nstruct  fd      { F a;   D b;   }\nstruct ffd      { F a,b; D c;   }\nstruct fdf      { F a;   D b;  F c; }\n\n// Mixed Types\n\nstruct fi       { F a;   I b;   }\nstruct fii      { F a;   I b,c; }\nstruct  jf      { I a;   F b;   }\nstruct iif      { I a,b; F c;   }\nstruct ifi      { I a;   F b;  I c; }\n\nstruct ffi      { F a,b; I c;           }\nstruct ffii     { F a,b; I c,d;         }\nstruct  iff     { I a;   F b,c;         }\nstruct iiff     { I a,b; F c,d;         }\nstruct ifif     { I a;   F b;  I c; F d;}\n\nstruct di       { D a;   I b;   }\nstruct dii      { D a;   I b,c; }\nstruct  id      { I a;   D b;   }\nstruct iid      { I a,b; D c;   }\nstruct idi      { I a;   D b;  I c; }\n\n// Real ( long double )\n\nstruct r        { R a;          }\nstruct rr       { R a,b;        }\nstruct rb       { R a;   B b;   }\nstruct rf       { R a;   F b;   }\nstruct fr       { F a;   R b;   }\n\n                // Int Registers only\nalias tuple!(   b,bb,bbb,bbbb,bbbbb,\n                b6, b7, b8, b9, b10,\n                b11,b12,b13,b14,b15,\n                b16,b17,b18,b19,b20,\n                s,ss,sss,ssss,sssss,\n                s6, s7, s8, s9, s10,\n                i,ii,iii,iiii,iiiii,\n                l,ll,lll,llll,lllll,\n                //\n                js,iss,si,ssi, sis,\n                ls,lss,sl,ssl, sls,\n                li,lii,il,iil, ili,\n                fi,fii,jf,iif, ifi,\n                ffi,ffii,iff,iiff,ifif, // INT_END\n\n                // SSE registers only\n                f,ff,fff,ffff,fffff,\n                d,dd,ddd,dddd,ddddd,\n                //\n                df,dff,fd,ffd, fdf,     // SSE_END\n\n                // Int and SSE\n                di,  dii,id, iid, idi,  // MIX_END\n                // ---\n            ) ALL_T;\n\nenum INT_END = 65;\nenum SSE_END = 80;\nenum MIX_END = ALL_T.length;\n\n                // x87\nalias tuple!(   r,rr,rb,rf,fr,\n                // ---\n            ) R_T;\n//\"r\",\"rr\",\"rb\",\"rf\",\"fr\",\n\n\nstring[] ALL_S=[\n                \"b\",\"bb\",\"bbb\",\"bbbb\",\"bbbbb\",\n                \"b6\", \"b7\", \"b8\", \"b9\", \"b10\",\n                \"b11\",\"b12\",\"b13\",\"b14\",\"b15\",\n                \"b16\",\"b17\",\"b18\",\"b19\",\"b20\",\n                \"s\",\"ss\",\"sss\",\"ssss\",\"sssss\",\n                \"s6\",\"s7\",\"s8\",\"s9\" , \"s10\",\n                \"i\",\"ii\",\"iii\",\"iiii\",\"iiiii\",\n                \"l\",\"ll\",\"lll\",\"llll\",\"lllll\",\n                // ---\n                \"js\",\"iss\",\"si\",\"ssi\", \"sis\",\n                \"ls\",\"lss\",\"sl\",\"ssl\", \"sls\",\n                \"li\",\"lii\",\"il\",\"iil\", \"ili\",\n                \"fi\",\"fii\",\"jf\",\"iif\", \"ifi\",\n                \"ffi\",\"ffii\",\"iff\",\"iiff\",\"ifif\",\n                // ---\n                \"f\",\"ff\",\"fff\",\"ffff\",\"fffff\",\n                \"d\",\"dd\",\"ddd\",\"dddd\",\"ddddd\",\n                \"df\",\"dff\",\"fd\",\"ffd\", \"dfd\",\n                // ---\n                \"di\",\"dii\",\"id\",\"iid\",\"idi\",\n               ];\n\n/* ***********************************************************************\n                                   All\n ************************************************************************/\n// test1 Struct passing and return\n\nint[MIX_END] results_1;\n\nT test1_out(T)( )\n{\n        T t;\n        foreach( i, ref e; t.tupleof )  e = i+1;\n        return t;\n}\nT test1_inout(T)( T t)\n{\n        foreach( i, ref e; t.tupleof )  e += 10;\n        return t;\n}\n\nvoid test1_call_out(T)( int n )\n{\n        T t1;\n        foreach( i, ref e; t1.tupleof ) e = i+1;\n        T t2 = test1_out!(T)();\n\n        if( t1 == t2 ) results_1[n] |= 1;\n}\nvoid test1_call_inout(T)( int n )\n{\n        T t1;\n        foreach( i, ref e; t1.tupleof ) e = i+1;\n        T t2 = test1_inout!(T)( t1 );\n        foreach( i, ref e; t1.tupleof ) e += 10;\n\n        if( t1 == t2 ) results_1[n] |= 2;\n}\n\nvoid D_test1( )\n{\n        // Run Tests\n        foreach( n, T; ALL_T )\n        {\n                test1_call_out!(T)(n);\n                test1_call_inout!(T)(n);\n        }\n\n        bool pass = true;\n        foreach( i, r; results_1 )\n        {\n                if( ~r & 1 )\n                {\n                pass = false;\n                printf( \"Test1   out %s \\tFail\\n\", ALL_S[i].ptr );\n                }\n                if( ~r & 2 )\n                {\n                pass = false;\n                printf( \"Test1 inout %s \\tFail\\n\", ALL_S[i].ptr );\n                }\n        }\n        assert( pass );\n\n        results_1[0..5] = 0;\n        foreach( n, T; R_T )\n        {\n                test1_call_out!(T)(n);\n                test1_call_inout!(T)(n);\n        }\n}\n\n/************************************************************************/\n// based on runnable/test23.d : test44()\n// Return Struct into an Array\n\nstruct S1\n{       int i,j;\n\n        static S1 foo(int x)\n        {       S1 s;\n                s.i = x;\n                return s;\n}       }\nstruct S2\n{       int i,j,k;\n\n        static S2 foo(int x)\n        {       S2 s;\n                s.i = x;\n                return s;\n}       }\nstruct S3\n{       float i,j;\n\n        static S3 foo(int x)\n        {       S3 s;\n                s.i = x;\n                return s;\n}       }\nstruct S4\n{       float i,j,k;\n\n        static S4 foo(int x)\n        {       S4 s;\n                s.i = x;\n                return s;\n}       }\nstruct S5\n{       float i,j;\n        int   k;\n\n        static S5 foo(float x)\n        {       S5 s;\n                s.i = x;\n                return s;\n}       }\n\nvoid D_test2()\n{\n        S1[] s1;\n        S2[] s2;\n        S3[] s3;\n        S4[] s4;\n        S5[] s5;\n\n        s1 = s1 ~ S1.foo(6);    s1 = s1 ~ S1.foo(1);\n        s2 = s2 ~ S2.foo(6);    s2 = s2 ~ S2.foo(1);\n        s3 = s3 ~ S3.foo(6);    s3 = s3 ~ S3.foo(1);\n        s4 = s4 ~ S4.foo(6);    s4 = s4 ~ S4.foo(1);\n        s5 = s5 ~ S5.foo(6);    s5 = s5 ~ S5.foo(1);\n\n        assert( s1.length == 2 );\n        assert( s1[0].i == 6 );\n        assert( s1[1].i == 1 );\n\n        assert( s2.length == 2 );\n        assert( s2[0].i == 6 );\n        assert( s2[1].i == 1 );\n\n/+      // These Fail on Mainline DMD64 ( Should pass! )\n        assert( s3.length == 2 );\n        assert( s3[0].i == 6 );\n        assert( s3[1].i == 1 );\n\n        assert( s4.length == 2 );\n        assert( s4[0].i == 6 );\n        assert( s4[1].i == 1 );\n+/\n        assert( s5.length == 2 );\n        assert( s5[0].i == 6 );\n        assert( s5[1].i == 1 );\n\n}\n\n/* ***********************************************************************\n                                X86_64\n ************************************************************************/\n\nversion(Run_X86_64_Tests)\n{\n\n\nstruct TEST\n{\n        immutable int       num;\n        immutable string    desc;\n        bool[MIX_END] result;\n}\n\n/**\n * 0 = Should Fail\n * 1 = Should Pass\n */\nimmutable int[MIX_END] expected =\n        [\n        1,1,1,1,1, // b\n        1,1,1,1,1, // b6\n        1,1,1,1,1, // b11\n        1,0,0,0,0, // b16\n\n        1,1,1,1,1, // s\n        1,1,1,0,0, // s6\n        1,1,1,1,0, // i\n        1,1,0,0,0, // l\n        1,1,1,1,1, // si mix\n        1,1,1,1,0, // sl\n        1,1,1,1,0, // il\n        1,1,1,1,1, // int and float\n        1,1,1,1,1, // int and float\n\n        // SSE regs only\n        1,1,1,1,0, // f\n        1,1,0,0,0, // d\n        1,1,1,1,0, // float and double\n\n        // SSE + INT regs\n        1,1,1,1,0, // int and double\n        ];\n\n\n/**\n * Describes value expected in registers\n *\n * null means do not test\n * ( because value is passed on the stack ).\n */\n\nimmutable long[][] RegValue =\n        [\n/*   0  b       */ [ 0x0000000000000001,                    ],\n/*   1  bb      */ [ 0x0000000000000201,                    ],\n/*   2  bbb     */ [ 0x0000000000030201,                    ],\n/*   3  bbbb    */ [ 0x0000000004030201,                    ],\n/*   4  bbbbb   */ [ 0x0000000504030201,                    ],\n/*   5  b6      */ [ 0x0000060504030201,                    ],\n/*   6  b7      */ [ 0x0007060504030201,                    ],\n/*   7  b8      */ [ 0x0807060504030201,                    ],\n/*   8  b9      */ [ 0x0807060504030201, 0x0000000000000009 ],\n/*   9  b10     */ [ 0x0807060504030201, 0x0000000000000a09 ],\n/*  10  b11     */ [ 0x0807060504030201, 0x00000000000b0a09 ],\n/*  11  b12     */ [ 0x0807060504030201, 0x000000000c0b0a09 ],\n/*  12  b13     */ [ 0x0807060504030201, 0x0000000d0c0b0a09 ],\n/*  13  b14     */ [ 0x0807060504030201, 0x00000e0d0c0b0a09 ],\n/*  14  b15     */ [ 0x0807060504030201, 0x000f0e0d0c0b0a09 ],\n/*  15  b16     */ [ 0x0807060504030201, 0x100f0e0d0c0b0a09 ],\n/*  16  b17     */ null,\n/*  17  b18     */ null,\n/*  18  b19     */ null,\n/*  19  b20     */ null,\n/*  20  s       */ [ 0x0000000000000001,                    ],\n/*  21  ss      */ [ 0x0000000000020001,                    ],\n/*  22  sss     */ [ 0x0000000300020001,                    ],\n/*  23  ssss    */ [ 0x0004000300020001,                    ],\n/*  24  sssss   */ [ 0x0004000300020001, 0x0000000000000005 ],\n/*  25  s6      */ [ 0x0004000300020001, 0x0000000000060005 ],\n/*  26  s7      */ [ 0x0004000300020001, 0x0000000700060005 ],\n/*  27  s8      */ [ 0x0004000300020001, 0x0008000700060005 ],\n/*  28  s9      */ null,\n/*  29  s10     */ null,\n/*  30  i       */ [ 0x0000000000000001,                    ],\n/*  31  ii      */ [ 0x0000000200000001,                    ],\n/*  32  iii     */ [ 0x0000000200000001, 0x0000000000000003 ],\n/*  33  iiii    */ [ 0x0000000200000001, 0x0000000400000003 ],\n/*  34  iiiii   */ null,\n/*  35  l       */ [ 0x0000000000000001,                    ],\n/*  36  ll      */ [ 0x0000000000000001, 0x0000000000000002 ],\n/*  37  lll     */ null,\n/*  38  llll    */ null,\n/*  39  lllll   */ null,\n\n/*  40  js      */ [ 0x0000000200000001,                    ],\n/*  41  iss     */ [ 0x0003000200000001,                    ],\n/*  42  si      */ [ 0x0000000200000001,                    ],\n/*  43  ssi     */ [ 0x0000000300020001,                    ],\n/*  44  sis     */ [ 0x0000000200000001, 0x0000000000000003 ],\n/*  45  ls      */ [ 0x0000000000000001, 0x0000000000000002 ],\n/*  46  lss     */ [ 0x0000000000000001, 0x0000000000030002 ],\n/*  47  sl      */ [ 0x0000000000000001, 0x0000000000000002 ],\n/*  48  ssl     */ [ 0x0000000000020001, 0x0000000000000003 ],\n/*  49  sls     */ null,\n/*  50  li      */ [ 0x0000000000000001, 0x0000000000000002 ],\n/*  51  lii     */ [ 0x0000000000000001, 0x0000000300000002 ],\n/*  52  il      */ [ 0x0000000000000001, 0x0000000000000002 ],\n/*  53  iil     */ [ 0x0000000200000001, 0x0000000000000003 ],\n/*  54  ili     */ null,\n\n/*  55  fi      */ [ 0x000000023f800000,                    ],\n/*  56  fii     */ [ 0x000000023f800000, 0x0000000000000003 ],\n/*  57  jf      */ [ 0x4000000000000001,                    ],\n/*  58  iif     */ [ 0x0000000200000001, 0x0000000040400000 ],\n/*  59  ifi     */ [ 0x4000000000000001, 0x0000000000000003 ],\n\n/*  60  ffi     */ [ 0x0000000000000003, 0x400000003f800000 ],\n/*  61  ffii    */ [ 0x0000000400000003, 0x400000003f800000 ],\n/*  62  iff     */ [ 0x4000000000000001, 0x0000000040400000 ],\n/*  63  iiff    */ [ 0x0000000200000001, 0x4080000040400000 ],\n/*  64  ifif    */ [ 0x4000000000000001, 0x4080000000000003 ],\n\n/*  65  f       */ [ 0x000000003f800000,                    ],\n/*  66  ff      */ [ 0x400000003f800000,                    ],\n/*  67  fff     */ [ 0x400000003f800000, 0x0000000040400000 ],\n/*  68  ffff    */ [ 0x400000003f800000, 0x4080000040400000 ],\n/*  69  fffff   */ null,\n/*  70  d       */ [ 0x3ff0000000000000,                    ],\n/*  71  dd      */ [ 0x3ff0000000000000, 0x4000000000000000 ],\n/*  72  ddd     */ null,\n/*  73  dddd    */ null,\n/*  74  ddddd   */ null,\n\n/*  75  df      */ [ 0x3ff0000000000000, 0x0000000040000000 ],\n/*  76  dff     */ [ 0x3ff0000000000000, 0x4040000040000000 ],\n/*  77  fd      */ [ 0x000000003f800000, 0x4000000000000000 ],\n/*  78  ffd     */ [ 0x400000003f800000, 0x4008000000000000 ],\n/*  79  fdf     */ null,\n\n/*  80  di      */ [ 0x3ff0000000000000, 0x0000000000000002 ],\n/*  81  dii     */ [ 0x3ff0000000000000, 0x0000000300000002 ],\n/*  82  id      */ [ 0x4000000000000000, 0x0000000000000001 ],\n/*  83  iid     */ [ 0x4008000000000000, 0x0000000200000001 ],\n/*  84  idi     */ null,\n        ];\n\n/* Have to do it this way for OSX: Issue 7354 */\n__gshared long[2] dump;\n\n/**\n * Generate Register capture\n */\nstring gen_reg_capture( int n, string registers )( )\n{\n        if( RegValue[n] == null ) return \"return;\";\n\n        string[] REG = mixin(registers); // [\"RDI\",\"RSI\"];\n\n        // Which type of compare\n        static if(n < INT_END)\n                enum MODE = 1; // Int\n        else static if(n < SSE_END)\n                enum MODE = 2; // Float\n        else    enum MODE = 3; // Mix\n\n        /* Begin */\n\n        string code = \"asm {\\n\";\n\n        final switch( MODE )\n        {\n                case 1: code ~= \"mov [dump], \"~REG[0]~\";\\n\";\n                        REG = REG[1..$];\n                break;\n                case 2:\n                case 3: code ~= \"movq [dump], XMM0;\\n\";\n        }\n\n        if( RegValue[n].length == 2 )\n        final switch( MODE )\n        {\n                case 1:\n                case 3: code ~= \"mov [dump+8], \"~REG[0]~\";\\n\";\n                break;\n                case 2: code ~= \"movq [dump+8], XMM1;\\n\";\n        } else {\n                code ~= \"xor R8, R8;\\n\";\n                code ~= \"mov [dump+8], R8;\\n\";\n        }\n\n        return code ~ \"}\\n\";\n}\n\n/**\n * Check the results\n */\nbool check( TEST data )\n{\n        bool pass = true;\n        foreach( i, e; expected )\n        {\n                if( data.result[i] != (e & 1) )\n                {\n                        printf( \"Test%d %s \\tFail\\n\", data.num, ALL_S[i].ptr);\n                        pass = false;\n                }\n        }\n        return pass;\n}\n\n/************************************************************************/\n\n// test1 Return Struct in Registers\n// ( if RDI == 12 we have no hidden pointer )\n\nTEST data1 = { 1, \"RDI hidden pointer\" };\n\nT test1_asm( T, int n )( int i )\n{\n        asm {\n\n        cmp EDI, 12;\n        je L1;\n\n        leave; ret;\n        }\nL1:\n        data1.result[n] = true;\n}\n\nvoid test1()\n{\n        printf(\"\\nRunning iasm Test 1 ( %s )\\n\", data1.desc.ptr);\n\n        foreach( int n, T; ALL_T )\n                test1_asm!(T,n)(12);\n\n        check( data1 );\n}\n\n/************************************************************************/\n// test2 Pass Struct in Registers\n// ( if RDI == 0 we have no stack pointer )\n\nTEST data2 = { 2, \"RDI struct pointer\" };\n\nT test2_asm( T, int n )( T t )\n{\n        asm {\n\n        mov [dump], RDI;\n        mov [dump+8], RSP;\n        cmp EDI, 0; // TODO test RDI is a ptr to stack ? ?\n        je L1;\n\n        leave; ret;\n        }\nL1:\n        data2.result[n] = true;\n}\nT test2f_asm( T, int n )( T t, int x )\n{\n        asm {\n\n        cmp EDI, 12;\n        je L1;\n\n        leave; ret;\n        }\nL1:\n        data2.result[n] = true;\n}\n\nvoid test2()\n{\n        printf(\"\\nRunning iasm Test 2 ( %s )\\n\", data2.desc.ptr);\n\n        // Integer\n        foreach( int n, T; ALL_T ) {\n                T t = { 0 };\n                test2_asm!(T,n)( t );\n        }\n\n        // float alternative test\n        foreach( int n, T; ALL_T[INT_END..SSE_END] )\n        {\n                enum n2 = n + INT_END;\n                data2.result[n2] = false;\n                test2f_asm!(T,n2)( T.init, 12 );\n        }\n\n        check( data2 );\n}\n\n/************************************************************************/\n// test3\n\nTEST data3 = { 3, \"Check Return Register value\" };\n\nvoid test3_run( T, int n )( )\n{\n        test3_ret!T();\n        mixin( gen_reg_capture!(n,`[\"RAX\",\"RDX\"]`)() );\n\n        //dbg!(T,n)( );\n\n        enum len = RegValue[n].length;\n        if( dump[0..len] == RegValue[n] )\n                data3.result[n] = true;\n}\n\nT test3_ret( T )( )\n{\n        T t;\n        foreach( i, ref e; t.tupleof )  e = i+1;\n        return t;\n}\n\nvoid test3()\n{\n        printf(\"\\nRunning iasm Test 3 ( %s )\\n\", data3.desc.ptr);\n\n        foreach( int n, T; ALL_T )\n                test3_run!(T,n)( );\n\n        check( data3 );\n}\n\n/************************************************************************/\n// test4\n\nTEST data4 = { 4, \"Check Input Register value\" };\n\nvoid test4_run( T, int n )( T t )\n{\n        mixin( gen_reg_capture!(n,`[\"RDI\",\"RSI\"]`)() );\n\n        //dbg!(T,n)( );\n\n        enum len = RegValue[n].length;\n        if( dump[0..len] == RegValue[n] )\n                data4.result[n] = true;\n}\n\nvoid dbg( T, int n )( )\n{\n        import std.stdio;\n        writefln( \"D %s\\t[ %16x, %16x ]\", T.stringof, dump[0], dump[1], );\n        writef(   \"C %s\\t[ %16x\", T.stringof, RegValue[n][0] );\n        if( RegValue[n].length == 2 )\n        writef( \", %16x\", RegValue[n][1] );\n        writefln( \" ]\" );\n}\nvoid test4()\n{\n        printf(\"\\nRunning iasm Test 4 ( %s )\\n\", data4.desc.ptr);\n\n        foreach( int n, T; ALL_T )\n        {\n                T t;\n                foreach( i, ref e; t.tupleof )  e = i+1;\n                test4_run!(T,n)( t );\n        }\n        check( data4 );\n}\n\n\n} // end version(Run_X86_64_Tests)\n\n/************************************************************************/\n\n\nvoid main()\n{\n        D_test1();\n        D_test2();\n\n        version(Run_X86_64_Tests)\n        {\n                test1();\n                test2();\n                test3();\n                test4();\n        }\n}\n\n/+\n/**\n * C code to generate the table RegValue\n */\nstring c_generate_returns()\n{\n        string value =  \" 1, 2, 3, 4, 5, 6, 7, 8, 9,10,\"\n                        \"11,12,13,14,15,16,17,18,19,20,\";\n\n        string code = \"#include \\\"cgen.h\\\"\\n\";\n\n        // Generate return functions\n        foreach( int n, T; ALL_T )\n        {\n                auto Ts  = T.stringof;\n                auto len = T.tupleof.length;\n\n                code ~= \"struct \"~Ts~\" func_ret_\"~Ts~\"(void) { \\n\";\n                code ~= \"struct \"~Ts~\" x = { \";\n                code ~= value[0..len*3] ~ \" };\\n\";\n                code ~= \"return x;\\n}\\n\";\n        }\n        return code;\n}\nstring c_generate_pass()\n{\n        string value =  \" 1, 2, 3, 4, 5, 6, 7, 8, 9,10,\"\n                        \"11,12,13,14,15,16,17,18,19,20,\";\n\n        string code;\n\n        // Generate return functions\n        foreach( int n, T; ALL_T )\n        {\n                auto Ts  = T.stringof;\n                auto len = T.tupleof.length;\n\n                code ~= \"void func_pass_\"~Ts~\"( struct \"~Ts~\" x ) {\\n\";\n                ////////////////\n                // Which type of compare\n                static if(n < INT_END)\n                        enum MODE = 1; // Int\n                else static if(n < SSE_END)\n                        enum MODE = 2; // Float\n                else    enum MODE = 3; // Mix\n\n                auto nn  = n.stringof;\n\n                /* Begin */\n\n                code ~= \"asm(\\n\";\n                final switch( MODE )\n                {\n                case 1:\n                code ~= `\"movq  %rdi, reg\\n\" \"movq  %rsi, reg+8\\n\"`;\n                break;\n                case 2:\n                code ~= `\"movq %xmm0, reg\\n\" \"movq %xmm1, reg+8\\n\"`;\n                break;\n                case 3:\n                code ~= `\"movq %xmm0, reg\\n\" \"movq  %rdi, reg+8\\n\"`;\n                }\n                code ~= \"\\n);\\n\";\n                code ~= \"}\\n\";\n\n                ////////////////\n                code ~= \"void func_call_\"~Ts~\"( void ) {\\n\";\n                code ~= \"struct \"~Ts~\" x = { \";\n                code ~= value[0..len*3] ~ \" };\\n\";\n                code ~= \"func_pass_\"~Ts~\"( x );\\n}\\n\";\n        }\n        return code;\n}\nstring c_generate_main()\n{\n        string code = \"void main() {\\n\";\n\n        foreach( int n, T; ALL_T )\n        {\n                // Which type of compare\n                static if(n < INT_END)\n                        enum MODE = 1; // Int\n                else static if(n < SSE_END)\n                        enum MODE = 2; // Float\n                else    enum MODE = 3; // Mix\n\n                auto nn  = n.stringof;\n                auto Ts  = T.stringof;\n\n                /* Begin */\n\n                code ~= `printf(\"/* %3d  `~Ts~`\\t*/ \", `~nn~`);`\"\\n\";\n                if( !(expected[n] & 1) )\n                {\n                        code ~= `printf(\"null,\\n\");`\"\\n\";\n                        continue;\n                }\n                code ~= \"asm(\\n\";\n                code ~= `\"call func_ret_`~Ts~`\\n\"`\"\\n\";\n                final switch( MODE )\n                {\n                case 1:\n                code ~= `\"movq  %rax, reg\\n\" \"movq  %rdx, reg+8\\n\"`;\n                break;\n                case 2:\n                code ~= `\"movq %xmm0, reg\\n\" \"movq %xmm1, reg+8\\n\"`;\n                break;\n                case 3:\n                code ~= `\"movq %xmm0, reg\\n\" \"movq  %rax, reg+8\\n\"`;\n                }\n                code ~= \"\\n);\\n\";\n\n                code ~= `printf(\"[ 0x%016lx\", reg.r1 );`\"\\n\";\n\n                if( T.sizeof > 8  || MODE == 3 )\n                        code ~= `printf(\", 0x%016lx ],\\n\", reg.r2 );`\"\\n\";\n                else    code ~= `printf(\",   %015c  ],\\n\", ' '    );`\"\\n\";\n        }\n\n        foreach( int n, T; ALL_T )\n        {\n                // Which type of compare\n                static if(n < INT_END)\n                        enum MODE = 1; // Int\n                else static if(n < SSE_END)\n                        enum MODE = 2; // Float\n                else    enum MODE = 3; // Mix\n\n                auto nn  = n.stringof;\n                auto Ts  = T.stringof;\n\n                /* Begin */\n\n                code ~= `printf(\"/* %3d  `~Ts~`\\t*/ \", `~nn~`);`\"\\n\";\n                if( !(expected[n] & 1) )\n                {\n                        code ~= `printf(\"null,\\n\");`\"\\n\";\n                        continue;\n                }\n                code ~= \"func_call_\"~Ts~\"();\\n\";\n\n                code ~= `printf(\"[ 0x%016lx\", reg.r1 );`\"\\n\";\n\n                if( T.sizeof > 8  || MODE == 3 )\n                        code ~= `printf(\", 0x%016lx ],\\n\", reg.r2 );`\"\\n\";\n                else    code ~= `printf(\",   %015c  ],\\n\", ' '    );`\"\\n\";\n        }\n\n\n        return code ~ \"}\";\n}\npragma(msg, c_generate_returns() );\npragma(msg, c_generate_pass() );\npragma(msg, c_generate_main() );\n// +/\n\n/+\n/**\n * Generate Functions that pass/return each Struct type\n *\n * ( Easier to look at objdump this way )\n */\nstring d_generate_functions( )\n{\n        string code = \"extern(C) {\";\n\n        // pass\n        foreach( s; ALL_T )\n        {\n                string ss = s.stringof;\n\n                code ~= \"void func_in_\"~ss~\"( \"~ss~\" t ) { t.a = 12; }\\n\";\n        }\n        // return\n        foreach( s; ALL_T[0..10] )\n        {\n                string ss = s.stringof;\n\n                code ~= `\n                auto func_out_`~ss~`()\n                {\n                        `~ss~` t;\n                        foreach( i, ref e; t.tupleof )  e = i+1;\n                        return t;\n                }`;\n        }\n        // pass & return\n        foreach( s; ALL_T[0..10] )\n        {\n                string ss = s.stringof;\n\n                code ~= `\n                auto func_inout_`~ss~`( `~ss~` t )\n                {\n                        foreach( i, ref e; t.tupleof )  e += 10;\n                        return t;\n                }`;\n        }\n        return code ~ \"\\n} // extern(C)\\n\";\n}\n//pragma( msg, d_generate_functions() );\nmixin( d_generate_functions() );\n// +/\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testappend.d",
    "content": "// PERMUTE_ARGS:\n\nimport core.stdc.stdio;\nimport core.stdc.math : isnan;\n\nvoid test12826()\n{\n    string s, t;\n    t = t ~ \"1234567\";\n    s = s ~ \"1234567\";\n\n    s ~= s;\n    assert(s == \"12345671234567\", s);\n    assert(t == \"1234567\", t);\n}\n\n\nint main()\n{\n    int[] a;\n\n    for (int i = 0; i < 1000; i++)\n    {\n        a.length = a.length + 100;\n    }\n    foreach (v; a)\n    {\n        assert(v == 0);\n    }\n\n    float[] b;\n    for (int i = 0; i < 2000; i++)\n    {\n        b.length = b.length + 100;\n    }\n    foreach (v; b)\n    {\n        assert(isnan(v));\n    }\n    delete a;\n    delete b;\n\n    a = null;\n    for (int i = 0; i < 100000; i++)\n    {\n        a ~= i;\n    }\n    foreach (k, v; a)\n    {\n        assert(v == k);\n    }\n\n    b = null;\n    for (int i = 0; i < 200000; i++)\n    {\n        b ~= i;\n    }\n    foreach (k, v; b)\n    {\n        assert(v == k);\n    }\n    delete a;\n    delete b;\n\n    test12826();\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testargtypes.d",
    "content": "\nvoid chkArgTypes(S, V...)()\n{\n    pragma(msg, S);\n    static if (is(S U == __argTypes))\n    {\n        foreach (T; U) { pragma(msg, T); }\n        static assert(U.length == V.length);\n        foreach (i, T; U)\n            static assert(is(V[i] == T));\n    }\n    else\n        static assert(0);\n}\n\nvoid chkSingle(T,U)()\n{\n    struct S { T a; }\n    chkArgTypes!(S, U)();\n}\n\nvoid chkIdentity(T)()\n{\n    chkSingle!(T,T)();\n}\n\nvoid chkPair(T,U,V)()\n{\n    struct S { T a; U b; }\n    chkArgTypes!(S, V)();\n}\n\nversion (X86_64)\n{\n    int main()\n    {\n        chkIdentity!byte();\n        chkIdentity!ubyte();\n        chkIdentity!short();\n        chkIdentity!ushort();\n        chkIdentity!int();\n        chkIdentity!uint();\n        chkIdentity!long();\n        chkIdentity!ulong();\n        chkSingle!(char,ubyte)();\n        chkSingle!(wchar,ushort)();\n        chkSingle!(dchar,uint)();\n\n        chkIdentity!float();\n        chkIdentity!double();\n        chkIdentity!real();\n\n        chkIdentity!(void*)();\n\n        chkIdentity!(__vector(byte[16]))();\n        chkIdentity!(__vector(ubyte[16]))();\n        chkIdentity!(__vector(short[8]))();\n        chkIdentity!(__vector(ushort[8]))();\n        chkIdentity!(__vector(int[4]))();\n        chkIdentity!(__vector(uint[4]))();\n        chkIdentity!(__vector(long[2]))();\n        chkIdentity!(__vector(ulong[2]))();\n\n        chkIdentity!(__vector(float[4]))();\n        chkIdentity!(__vector(double[2]))();\n\n        chkPair!(byte,byte,short);\n        chkPair!(ubyte,ubyte,short);\n        chkPair!(short,short,int);\n        chkPair!(int,int,long);\n\n        chkPair!(byte,short,int);\n        chkPair!(short,byte,int);\n\n        chkPair!(int,float,long);\n        chkPair!(float,int,long);\n        chkPair!(byte,float,long);\n        chkPair!(float,short,long);\n\n        struct S1 { long a; long b; }\n        chkArgTypes!(S1, long, long)();\n\n        struct S2 { union { long a; double d; }}\n        chkArgTypes!(S2, long)();\n\n        struct S3 { union { double d; long a; }}\n        chkArgTypes!(S3, long)();\n\n        struct S4 { int a,b,c,d,e; }\n        chkArgTypes!(S4)();\n\n        struct S5 { align(1): char a; int b; }\n        chkArgTypes!(S5)();\n\n        struct S6 { align(1): int a; void* b; }\n        chkArgTypes!(S6)();\n\n        struct S7 { union { void* p; real r; }}\n        chkArgTypes!(S7)();\n\n        struct S8 { union { real r; void* p; }}\n        chkArgTypes!(S8)();\n\n        struct S9 { int a,b,c; }\n        chkArgTypes!(S9, long, int)();\n        chkArgTypes!(S9[1], long, int)();\n\n        struct S10 { int[3] a; }\n        chkArgTypes!(S10, long, int)();\n\n        chkArgTypes!(int[3], long, int)();\n\n        return 0;\n    }\n}\nelse\n{\n    int main()\n    {\n        return 0;\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testarray.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS:\n\nimport core.memory;\n\n// see http://forum.dlang.org/thread/4BB6296E.6050506@digitalmars.com for more info\n\n// failure case for bug fixed by druntime rev 282\n// how it works:\n// The erroneous code used the first element in the LRU cache to determine the\n// length of the block, instead of looking at the current blocks blockinfo.  So\n// we need a somewhat alignment of moons to get this to fail.  First, we create\n// the perfect storm: 1) a long blockinfo at the beginning (size = 32), 2) the\n// second blockinfo is smaller (16 bytes) and 3) a block of memory that is\n// exactly 16 bytes past the element in the 2nd block.  While this seems kind\n// of unlikely, in code that uses a lot of appending, it can easily happen.\n//\n// The bug causes the array appender to think that a pointer in the 16 bytes\n// past the second blockinfo is actually in the second blockinfo.  This is\n// because it uses the length from the first blockinfo for checking (which is\n// 32, so since the pointer is only 16 bytes into the block, it is considered\n// inside).\n// On top of all this, the third block must be marked as containing pointers,\n// and the second block not containing pointers.  The reason is because, it's\n// impossible for the runtime to append in place, since the outside pointer\n// can't possibly match the array length in the block.  But because the runtime\n// copies the blockinfo's attributes when reallocating, it copies the\n// attributes from the *wrong* block.  The only way to make this cause a\n// problem would be to then collect memory, which should incorrectly deallocate\n// data that the array containing pointers points to, and then use those\n// pointers.  However, for our purposes, we know this is possible, but we can\n// deterministically check the attributes of the array after appending and\n// verify that they are wrong.\n//\nvoid main()\n{\n    // fill up the cache to make it wrap, The block info cache has 8 elements,\n    // and the first element is not the first one filled, so we want to wrap to\n    // that first element we want to fill in\n    for(int i = 0; i < 7; i++)\n    {\n        auto n = new int[1];\n        n ~= 1;\n    }\n\n    // this will allocate a 32-byte block, and appending will insert it into\n    // the cache at the beginning.\n    auto y = new int[4];\n    y ~= 1;\n\n    // now, allocate a 16 byte block with pointers, this will be our block that\n    // gets corrupted.  The current GC allocates down, so we allocate this one\n    // first.\n    auto x = new char[][1];\n\n    // this block contains no pointers, and appending will insert it into the\n    // second element of the cache\n    y = new int[1];\n    y ~= 1;\n\n    // verify the noscan flag is 0 on the pointer-containing blocks\n    assert((GC.getAttr(x.ptr) & GC.BlkAttr.NO_SCAN) == 0);\n    x ~= \"hello\".dup; // this should leave the attributes alone\n    assert((GC.getAttr(x.ptr) & GC.BlkAttr.NO_SCAN) == 0); // fails on 2.042\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testassign.d",
    "content": "import core.stdc.stdio;\n\ntemplate TypeTuple(T...){ alias T TypeTuple; }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2625\n\nstruct Pair {\n    immutable uint g1;\n    uint g2;\n}\n\nvoid test1() {\n    Pair[1] stuff;\n    static assert(!__traits(compiles, (stuff[0] = Pair(1, 2))));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5327\n\nstruct ID\n{\n    immutable int value;\n}\n\nstruct Data\n{\n    ID id;\n}\nvoid test2()\n{\n    Data data = Data(ID(1));\n    immutable int* val = &data.id.value;\n    static assert(!__traits(compiles, data = Data(ID(2))));\n}\n\n/***************************************************/\n\nstruct S31A\n{\n    union\n    {\n        immutable int field1;\n        immutable int field2;\n    }\n\n    enum result = false;\n}\nstruct S31B\n{\n    union\n    {\n        immutable int field1;\n        int field2;\n    }\n\n    enum result = true;\n}\nstruct S31C\n{\n    union\n    {\n        int field1;\n        immutable int field2;\n    }\n\n    enum result = true;\n}\nstruct S31D\n{\n    union\n    {\n        int field1;\n        int field2;\n    }\n\n    enum result = true;\n}\n\nstruct S32A\n{\n    int dummy0;\n    union\n    {\n        immutable int field1;\n        int field2;\n    }\n\n    enum result = true;\n}\nstruct S32B\n{\n    immutable int dummy0;\n    union\n    {\n        immutable int field1;\n        int field2;\n    }\n\n    enum result = false;\n}\n\n\nstruct S32C\n{\n    union\n    {\n        immutable int field1;\n        int field2;\n    }\n    int dummy1;\n\n    enum result = true;\n}\nstruct S32D\n{\n    union\n    {\n        immutable int field1;\n        int field2;\n    }\n    immutable int dummy1;\n\n    enum result = false;\n}\n\nvoid test3()\n{\n    foreach (S; TypeTuple!(S31A,S31B,S31C,S31D, S32A,S32B,S32C,S32D))\n    {\n        S s;\n        static assert(__traits(compiles, s = s) == S.result);\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3511\n\nstruct S4\n{\n    private int _prop = 42;\n    ref int property() { return _prop; }\n}\n\nvoid test4()\n{\n    S4 s;\n    assert(s.property == 42);\n    s.property = 23;    // Rewrite to s.property() = 23\n    assert(s.property == 23);\n}\n\n/***************************************************/\n\nstruct S5\n{\n    int mX;\n    string mY;\n\n    ref int x()\n    {\n        return mX;\n    }\n    ref string y()\n    {\n        return mY;\n    }\n\n    ref int err(Object)\n    {\n        static int v;\n        return v;\n    }\n}\n\nvoid test5()\n{\n    S5 s;\n    s.x += 4;\n    assert(s.mX == 4);\n    s.x -= 2;\n    assert(s.mX == 2);\n    s.x *= 4;\n    assert(s.mX == 8);\n    s.x /= 2;\n    assert(s.mX == 4);\n    s.x %= 3;\n    assert(s.mX == 1);\n    s.x <<= 3;\n    assert(s.mX == 8);\n    s.x >>= 1;\n    assert(s.mX == 4);\n    s.x >>>= 1;\n    assert(s.mX == 2);\n    s.x &= 0xF;\n    assert(s.mX == 0x2);\n    s.x |= 0x8;\n    assert(s.mX == 0xA);\n    s.x ^= 0xF;\n    assert(s.mX == 0x5);\n\n    s.x ^^= 2;\n    assert(s.mX == 25);\n\n    s.mY = \"ABC\";\n    s.y ~= \"def\";\n    assert(s.mY == \"ABCdef\");\n\n    static assert(!__traits(compiles, s.err += 1));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4424\n\nvoid test4424()\n{\n    static struct S\n    {\n        this(this) {}\n        void opAssign(T)(T rhs) if (!is(T == S)) {}\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6174\n\nstruct CtorTest6174(Data)\n{\n    const Data data;\n\n    const Data[2] sa1;\n    const Data[2][1] sa2;\n    const Data[][2] sa3;\n\n    const Data[] da1;\n    const Data[2][] da2;\n\n    this(Data a)\n    {\n        auto pdata = &data;\n\n        // If compiler can determine that an assignment really sets the fields\n        // which belongs to `this` object, it can bypass const qualifier.\n        // For example, sa3, da1, da2, and pdata have indirections.\n        // As long as you don't try to rewrite values beyond the indirections,\n        // an assignment will always be succeeded inside constructor.\n\n        static assert( is(typeof( data        = a         )));    // OK\n      static if (is(Data == struct))\n      {\n        static assert( is(typeof( data.x      = 1         )));    // OK\n        static assert( is(typeof( data.y      = 2         )));    // OK\n      }\n        static assert(!is(typeof( *pdata      = a         )));    // NG\n        static assert( is(typeof( *&data      = a         )));    // OK\n\n        static assert( is(typeof( sa1         = [a,a]     )));    // OK\n        static assert( is(typeof( sa1[0]      = a         )));    // OK\n        static assert( is(typeof( sa1[]       = a         )));    // OK\n        static assert( is(typeof( sa1[][]     = a         )));    // OK\n\n        static assert( is(typeof( sa2         = [[a,a]]   )));    // OK\n        static assert( is(typeof( sa2[0][0]   = a         )));    // OK\n        static assert( is(typeof( sa2[][0][]  = a         )));    // OK\n        static assert( is(typeof( sa2[0][][0] = a         )));    // OK\n\n        static assert( is(typeof( sa3         = [[a],[]]  )));    // OK\n        static assert( is(typeof( sa3[0]      = [a,a]     )));    // OK\n        static assert(!is(typeof( sa3[0][0]   = a         )));    // NG\n        static assert( is(typeof( sa3[]       = [a]       )));    // OK\n        static assert( is(typeof( sa3[][0]    = [a]       )));    // OK\n        static assert(!is(typeof( sa3[][0][0] = a         )));    // NG\n\n        static assert( is(typeof( da1         = [a,a]     )));    // OK\n        static assert(!is(typeof( da1[0]      = a         )));    // NG\n        static assert(!is(typeof( da1[]       = a         )));    // NG\n\n        static assert( is(typeof( da2         = [[a,a]]   )));    // OK\n        static assert(!is(typeof( da2[0][0]   = a         )));    // NG\n        static assert(!is(typeof( da2[]       = [a,a]     )));    // NG\n        static assert(!is(typeof( da2[][0]    = a         )));    // NG\n        static assert(!is(typeof( da2[0][]    = a         )));    // NG\n    }\n    void func(Data a)\n    {\n        auto pdata = &data;\n\n        static assert(!is(typeof( data        = a         )));    // NG\n      static if (is(Data == struct))\n      {\n        static assert(!is(typeof( data.x      = 1         )));    // NG\n        static assert(!is(typeof( data.y      = 2         )));    // NG\n      }\n        static assert(!is(typeof( *pdata      = a         )));    // NG\n        static assert(!is(typeof( *&data      = a         )));    // NG\n\n        static assert(!is(typeof( sa1         = [a,a]     )));    // NG\n        static assert(!is(typeof( sa1[0]      = a         )));    // NG\n        static assert(!is(typeof( sa1[]       = a         )));    // NG\n        static assert(!is(typeof( sa1[][]     = a         )));    // NG\n\n        static assert(!is(typeof( sa2         = [[a,a]]   )));    // NG\n        static assert(!is(typeof( sa2[0][0]   = a         )));    // NG\n        static assert(!is(typeof( sa2[][0][]  = a         )));    // NG\n        static assert(!is(typeof( sa2[0][][0] = a         )));    // NG\n\n        static assert(!is(typeof( sa3         = [[a],[]]  )));    // NG\n        static assert(!is(typeof( sa3[0]      = [a,a]     )));    // NG\n        static assert(!is(typeof( sa3[0][0]   = a         )));    // NG\n        static assert(!is(typeof( sa3[]       = [a]       )));    // NG\n        static assert(!is(typeof( sa3[][0]    = [a]       )));    // NG\n        static assert(!is(typeof( sa3[][0][0] = a         )));    // NG\n\n        static assert(!is(typeof( da1         = [a,a]     )));    // NG\n        static assert(!is(typeof( da1[0]      = a         )));    // NG\n        static assert(!is(typeof( da1[]       = a         )));    // NG\n\n        static assert(!is(typeof( da2         = [[a,a]]   )));    // NG\n        static assert(!is(typeof( da2[0][0]   = a         )));    // NG\n        static assert(!is(typeof( da2[]       = [a,a]     )));    // NG\n        static assert(!is(typeof( da2[][0]    = a         )));    // NG\n        static assert(!is(typeof( da2[0][]    = a         )));    // NG\n    }\n}\n\nconst char gc6174;\nconst char[1] ga6174;\nstatic this()\n{\n    gc6174 = 'a';    // OK\n    ga6174[0] = 'a'; // line 5, Err\n}\nstruct Foo6174\n{\n    const char cc;\n    const char[1] array;\n    const char[1] arr;\n    this(char c)\n    {\n        cc = c;       // OK\n        array = [c];  // line 12, Err\n        arr[0] = c;   // line 12, Err\n    }\n}\nvoid test6174a()\n{\n    static struct Pair\n    {\n        const int x;\n        int y;\n    }\n    alias CtorTest6174!long CtorTest1;\n    alias CtorTest6174!Pair CtorTest2;\n\n    auto foo = Foo6174('c');\n}\n\n/***************************************************/\n\ntemplate Select(bool cond, T, F)\n{\n    static if (cond)\n        alias Select = T;\n    else\n        alias Select = F;\n}\n\nvoid test6174b()\n{\n    enum { none, unrelated, mutable, constant }\n\n    static struct FieldStruct(bool c, int k)\n    {\n        enum fieldConst = c;\n        enum assignKind = k;\n\n        Select!(fieldConst, const int, int) x;\n        int y;\n\n        static if (assignKind == none)      {}\n        static if (assignKind == unrelated) void opAssign(int) {}\n        static if (assignKind == mutable)   void opAssign(FieldStruct) {}\n        static if (assignKind == constant)  void opAssign(FieldStruct) const {}\n    }\n    static struct TestStruct(F, bool fieldConst)\n    {\n        int w;\n        Select!(fieldConst, const F, F) f;\n        Select!(fieldConst, const int, int) z;\n\n        this(int)\n        {\n            // If F has an identity `opAssign`,it is used even for initializing.\n            // Otherwise, initializing  will always succeed, by bypassing const qualifier.\n            static assert(is(typeof( f = F() )) == (\n                            F.assignKind == none ||\n                            F.assignKind == unrelated ||\n                            F.assignKind == mutable ||\n                            F.assignKind == constant));\n\n            static assert(is(typeof(   w = 1000 )) == true);\n            static assert(is(typeof( f.x = 1000 )) == true);\n            static assert(is(typeof( f.y = 1000 )) == true);\n            static assert(is(typeof(   z = 1000 )) == true);\n        }\n        void func()\n        {\n            // In mutable member functions, identity assignment is allowed\n            // when all of the fields are identity assignable,\n            // or identity `opAssign`, which callable from mutable object, is defined.\n            static assert(__traits(compiles, f = F()) == (\n                            F.assignKind == none      && !fieldConst && !F.fieldConst ||\n                            F.assignKind == unrelated && !fieldConst && !F.fieldConst ||\n                            F.assignKind == constant ||\n                            F.assignKind == mutable   && !fieldConst));\n\n            static assert(__traits(compiles,   w = 1000) == true);\n            static assert(__traits(compiles, f.x = 1000) == (!fieldConst && !F.fieldConst));\n            static assert(__traits(compiles, f.y = 1000) == (!fieldConst && true         ));\n            static assert(__traits(compiles,   z = 1000) == !fieldConst);\n        }\n        void func() const\n        {\n            // In non-mutable member functions, identity assignment is allowed\n            // just only user-defined identity `opAssign` is qualified.\n            static assert(__traits(compiles, f = F()) == (F.assignKind == constant));\n\n            static assert(__traits(compiles,   w = 1000) == false);\n            static assert(__traits(compiles, f.x = 1000) == false);\n            static assert(__traits(compiles, f.y = 1000) == false);\n            static assert(__traits(compiles,   z = 1000) == false);\n        }\n    }\n    foreach (fieldConst; TypeTuple!(false, true))\n    foreach (  hasConst; TypeTuple!(false, true))\n    foreach (assignKind; TypeTuple!(none, unrelated, mutable, constant))\n    {\n        alias TestStruct!(FieldStruct!(hasConst, assignKind), fieldConst) TestX;\n    }\n}\n\nvoid test6174c()\n{\n    static assert(!is(typeof({\n        int func1a(int n)\n        in{ n = 10; }\n        body { return n; }\n    })));\n    static assert(!is(typeof({\n        int func1b(int n)\n        out(r){ r = 20; }\n        body{ return n; }\n    })));\n\n    struct DataX\n    {\n        int x;\n    }\n    static assert(!is(typeof({\n        DataX func2a(DataX n)\n        in{ n.x = 10; }\n        body { return n; }\n    })));\n    static assert(!is(typeof({\n        DataX func2b(DataX n)\n        in{}\n        out(r){ r.x = 20; }\n        body{ return n; }\n    })));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6216\n\nvoid test6216a()\n{\n    static class C{}\n\n    static struct Xa{ int n; }\n    static struct Xb{ int[] a; }\n    static struct Xc{ C c; }\n    static struct Xd{ void opAssign(typeof(this) rhs){} }\n    static struct Xe{ void opAssign(T)(T rhs){} }\n    static struct Xf{ void opAssign(int rhs){} }\n    static struct Xg{ void opAssign(T)(T rhs)if(!is(T==typeof(this))){} }\n\n    // has value type as member\n    static struct S1 (X){ static if (!is(X==void)) X x; int n; }\n\n    // has reference type as member\n    static struct S2a(X){ static if (!is(X==void)) X x; int[] a; }\n    static struct S2b(X){ static if (!is(X==void)) X x; C c; }\n\n    // has identity opAssign\n    static struct S3a(X){ static if (!is(X==void)) X x; void opAssign(typeof(this) rhs){} }\n    static struct S3b(X){ static if (!is(X==void)) X x; void opAssign(T)(T rhs){} }\n\n    // has non identity opAssign\n    static struct S4a(X){ static if (!is(X==void)) X x; void opAssign(int rhs){} }\n    static struct S4b(X){ static if (!is(X==void)) X x; void opAssign(T)(T rhs)if(!is(T==typeof(this))){} }\n\n    enum result = [\n        /*S1,   S2a,    S2b,    S3a,    S3b,    S4a,    S4b*/\n/*- */  [true,  true,   true,   true,   true,   true,   true],\n/*Xa*/  [true,  true,   true,   true,   true,   true,   true],\n/*Xb*/  [true,  true,   true,   true,   true,   true,   true],\n/*Xc*/  [true,  true,   true,   true,   true,   true,   true],\n/*Xd*/  [true,  true,   true,   true,   true,   true,   true],\n/*Xe*/  [true,  true,   true,   true,   true,   true,   true],\n/*Xf*/  [true,  true,   true,   true,   true,   true,   true],\n/*Xg*/  [true,  true,   true,   true,   true,   true,   true],\n    ];\n\n    pragma(msg, \"\\\\\\tS1\\tS2a\\tS2b\\tS3a\\tS3b\\tS4a\\tS4b\");\n    foreach (i, X; TypeTuple!(void,Xa,Xb,Xc,Xd,Xe,Xf,Xg))\n    {\n        S1!X  s1;\n        S2a!X s2a;\n        S2b!X s2b;\n        S3a!X s3a;\n        S3b!X s3b;\n        S4a!X s4a;\n        S4b!X s4b;\n\n        pragma(msg,\n                is(X==void) ? \"-\" : X.stringof,\n                \"\\t\", __traits(compiles, (s1  = s1)),\n                \"\\t\", __traits(compiles, (s2a = s2a)),\n                \"\\t\", __traits(compiles, (s2b = s2b)),\n                \"\\t\", __traits(compiles, (s3a = s3a)),\n                \"\\t\", __traits(compiles, (s3b = s3b)),\n                \"\\t\", __traits(compiles, (s4a = s4a)),\n                \"\\t\", __traits(compiles, (s4b = s4b))  );\n\n        static assert(result[i] ==\n            [   __traits(compiles, (s1  = s1)),\n                __traits(compiles, (s2a = s2a)),\n                __traits(compiles, (s2b = s2b)),\n                __traits(compiles, (s3a = s3a)),\n                __traits(compiles, (s3b = s3b)),\n                __traits(compiles, (s4a = s4a)),\n                __traits(compiles, (s4b = s4b))  ]);\n    }\n}\n\nvoid test6216b()\n{\n    static int cnt = 0;\n\n    static struct X\n    {\n        int n;\n        void opAssign(X rhs){ cnt = 1; }\n    }\n    static struct S\n    {\n        int n;\n        X x;\n    }\n\n    S s;\n    s = s;\n    assert(cnt == 1);\n    // Built-in opAssign runs member's opAssign\n}\n\nvoid test6216c()\n{\n    static int cnt = 0;\n\n    static struct X\n    {\n        int n;\n        void opAssign(const X rhs) const { cnt = 2; }\n    }\n    static struct S\n    {\n        int n;\n        const(X) x;\n    }\n\n    S s;\n    const(S) cs;\n    s = s;\n    s = cs;     // cs is copied as mutable and assigned into s\n    assert(cnt == 2);\n    static assert(!__traits(compiles, cs = cs));\n                // built-in opAssin is only allowed with mutable object\n}\n\nvoid test6216d()\n{\n    static int cnt = 0;\n\n    static struct X\n    {\n        int[] arr;  // X has mutable indirection\n        void opAssign(const X rhs) const { ++cnt; }\n    }\n    static struct S\n    {\n        int n;\n        const(X) x;\n    }\n\n    X mx;\n    const X cx;\n    mx = mx;    // copying mx to const X is possible\n    assert(cnt == 1);\n    mx = cx;\n    assert(cnt == 2);\n    cx = mx;    // copying mx to const X is possible\n    assert(cnt == 3);\n\n    S s;\n    const(S) cs;\n    s = s;\n    s = cs;\n    //assert(cnt == 4);\n    static assert(!__traits(compiles, cs = cs));\n                // built-in opAssin is only allowed with mutable object\n}\n\nvoid test6216e()\n{\n    static struct X\n    {\n        int x;\n        @disable void opAssign(X);\n    }\n    static struct S\n    {\n        X x;\n    }\n    S s;\n    static assert(!__traits(compiles, s = s));\n                // built-in generated opAssin is marked as @disable.\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6286\n\nvoid test6286()\n{\n    const(int)[4] src = [1, 2, 3, 4];\n    int[4] dst;\n    dst = src;\n    dst[] = src[];\n    dst = 4;\n    int[4][4] x;\n    x = dst;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6336\n\nvoid test6336()\n{\n    // structs aren't identity assignable\n    static struct S1\n    {\n        immutable int n;\n    }\n    static struct S2\n    {\n        void opAssign(int n){ assert(0); }\n    }\n\n    S1 s1;\n    S2 s2;\n\n    void f(S)(out S s){}\n    static assert(!__traits(compiles, f(s1)));\n    f(s2);\n    // Out parameters refuse only S1 because it isn't blit assignable\n\n    ref S g(S)(ref S s){ return s; }\n    g(s1);\n    g(s2);\n    // Allow return by ref both S1 and S2\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8783\n\nstruct Foo8783\n{\n    int[1] bar;\n}\n\nconst Foo8783[1] foos8783;\n\nstatic this()\n{\n    foreach (i; 0 .. foos8783.length)\n        foos8783[i].bar[i] = 1; // OK\n    foreach (i, ref f; foos8783)\n        f.bar[i] = 1; // line 9, Error\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9077\n\nstruct S9077a\n{\n    void opAssign(int n) {}\n    void test() { typeof(this) s; s = this; }\n    this(this) {}\n}\nstruct S9077b\n{\n    void opAssign()(int n) {}\n    void test() { typeof(this) s; s = this; }\n    this(this) {}\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9140\n\nimmutable(int)[] bar9140()\nout(result) {\n    foreach (ref r; result) {}\n} body {\n    return null;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9154\n\nstruct S9154a\n{\n    int x;\n    void opAssign(ref S9154a s) { }\n}\nstruct S9154b\n{\n    int x;\n    void opAssign(X)(ref X s) { }\n}\nstruct T9154\n{\n    S9154a member1;\n    S9154b member2;\n}\n\nvoid test9154()\n{\n    T9154 t1, t2;\n    t1 = t2;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9258\n\nclass A9258 {}\nclass B9258 : A9258 // Error: class test.B9258 identity assignment operator overload is illegal\n{\n    void opAssign(A9258 b) {}\n}\n\nclass C9258\n{\n    int n;\n    alias n this;\n    void opAssign(int n) {}\n}\nclass D9258\n{\n    int n;\n    alias n this;\n    void opAssign(int n, int y = 0) {}\n}\nclass E9258 : A9258\n{\n    void set(A9258 a) {}\n    alias set opAssign;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9416\n\nstruct S9416\n{\n    void opAssign()(S9416)\n    {\n        static assert(0);\n    }\n}\nstruct U9416\n{\n    S9416 s;\n}\nvoid test9416()\n{\n    U9416 u;\n    static assert(__traits(allMembers, U9416)[$-1] == \"opAssign\");\n    static assert(!__traits(compiles, u = u));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9658\n\nstruct S9658\n{\n    private bool _isNull = true;\n    this(int v) const\n    {\n        _isNull = false;    // cannot modify const expression this._isNull\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11187\n\nvoid test11187()\n{\n    static struct X\n    {\n        int[] arr;\n    }\n    static struct S\n    {\n        const(X) cx;\n    }\n    static assert(is(typeof((const S).init.cx.arr) == const(int[])));\n    static assert(is(typeof((      S).init.cx.arr) == const(int[])));\n    const S sc;\n    S sm = sc;\n    static assert(is(const S : S));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12131\n\nstruct X12131\n{\n    void opAssign()(X12131 y) pure {}\n}\n\nstruct Y12131\n{\n    X12131 a;\n}\n\nvoid test12131() pure\n{\n    X12131 x;\n    x = X12131();   // OK\n\n    Y12131 y;\n    y = Y12131();   // OK <- Error\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12211\n\nvoid test12211()\n{\n    int a = 0;\n    void foo(ref int x)\n    {\n        assert(x == 10);\n        assert(&x == &a);\n        x = 3;\n    }\n    foo(a = 10);\n    assert(a == 3);\n    foo(a += 7);\n    assert(a == 3);\n\n    // array ops should make rvalue\n    int[3] sa, sb;\n    void bar(ref int[]) {}\n    static assert(!__traits(compiles, bar(sa[]  = sb[])));\n    static assert(!__traits(compiles, bar(sa[] += sb[])));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4791 (dup of 12212)\n\nvoid test4791()\n{\n    int[2] na;\n    na = na;\n\n    static struct S\n    {\n        static string res;\n        int n;\n        this(this) { ++n; res ~= \"p\" ~ cast(char)('0' + n); }\n        ~this()    {      res ~= \"d\" ~ cast(char)('0' + n); }\n    }\n    {\n        S[3] sa;\n        sa[0].n = 1, sa[1].n = 2, sa[2].n = 3;\n\n        S.res = null;\n        sa = sa;\n        assert(S.res == \"p2d1p3d2p4d3\");\n        assert(sa[0].n == 2 && sa[1].n == 3 && sa[2].n == 4);\n\n        S.res = null;\n    }\n    assert(S.res == \"d4d3d2\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12212\n\nvoid test12212()\n{\n    struct S\n    {\n        int x, y;\n        static int cpctor;\n        this(this) { cpctor++; }\n    }\n\n    void funcVal(E)(E[3] x) {}\n    auto funcRef(E)(ref E[3] x) { return &x; }\n    ref get(E)(ref E[3] a){ return a; }\n\n    {\n        int[3] a, b;\n        funcVal(a = b);\n\n        auto p = funcRef(a = b);\n        assert(p == &a);\n    }\n\n    {\n        S.cpctor = 0;\n\n        S[3] a, b;\n        assert(S.cpctor == 0);\n\n        S[3] c = a;\n        //printf(\"cpctpr = %d\\n\", S.cpctor);\n        assert(S.cpctor == 3);\n        S.cpctor = 0;\n\n        c = a;\n        //printf(\"cpctpr = %d\\n\", S.cpctor);\n        assert(S.cpctor == 3);\n        S.cpctor = 0;\n\n        c = (a = b);\n        //printf(\"cpctpr = %d\\n\", S.cpctor);\n        assert(S.cpctor == 6);\n        S.cpctor = 0;\n\n        c = (get(a) = b);\n        //printf(\"cpctpr = %d\\n\", S.cpctor);\n        assert(S.cpctor == 6);\n        S.cpctor = 0;\n    }\n    {\n        S.cpctor = 0;\n\n        S[3] a, b;\n        assert(S.cpctor == 0);\n\n        funcVal(a = b);\n        //printf(\"cpctpr = %d\\n\", S.cpctor);\n        assert(S.cpctor == 6);\n        S.cpctor = 0;\n\n        funcVal(get(a) = b);\n        //printf(\"cpctpr = %d\\n\", S.cpctor);\n        assert(S.cpctor == 6);\n        S.cpctor = 0;\n    }\n    {\n        S.cpctor = 0;\n\n        S[3] a, b;\n        assert(S.cpctor == 0);\n\n        S[3]* p;\n\n        p = funcRef(a = b);\n        //printf(\"cpctpr = %d\\n\", S.cpctor);\n        assert(p == &a);\n        assert(S.cpctor == 3);\n        S.cpctor = 0;\n\n        p = funcRef(get(a) = b);\n        assert(p == &a);\n        //printf(\"cpctpr = %d\\n\", S.cpctor);\n        assert(S.cpctor == 3);\n        S.cpctor = 0;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12650\n\nvoid test12650()\n{\n    // AssignExp::toElem should make an lvalue of e1.\n    static class A1\n    {\n        struct S { int a; }\n\n        static foo(ref const(S) s)\n        {\n            assert(s.a == 2);\n            return &s;\n        }\n\n        S s;\n\n        this()\n        {\n            const v = S(2);\n\n            // (this.s = v) will become ConstructExp\n            auto p = foo(s = v);\n            assert(p == &s);\n        }\n    }\n    assert(new A1().s.a == 2);\n\n    static class A2\n    {\n        static foo(ref int[2] sa)\n        {\n            assert(sa[1] == 2);\n            return &sa;\n        }\n\n        int[2] sa;\n\n        this()\n        {\n            // (this.sa = [1,2]) will become ConstructExp\n            auto p = foo(sa = [1,2]);\n            assert(p == &sa);\n        }\n    }\n    assert(new A2().sa[1] == 2);\n\n    static class A3\n    {\n        static foo(ref int n)\n        {\n            assert(n == 2);\n            return &n;\n        }\n\n        int n;\n\n        this()\n        {\n            const v = 2;\n\n            // (this.n = v) will become ConstructExp\n            auto p = foo(n = v);\n            assert(p == &n);\n        }\n    }\n    assert(new A3().n == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13044\n\nvoid test13044()\n{\n    static struct Good\n    {\n        const int i;\n    }\n\n    static struct Bad\n    {\n        const int i;\n        ~this() {}\n    }\n\n    Good good1, good2;\n    static assert(!__traits(compiles, { good1 = good2; })); // OK\n\n    Bad bad1, bad2;\n    static assert(!__traits(compiles, { bad1 = bad2; }));   // OK <- fails\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12500\n\nvoid test12500()\n{\n    size_t foo;\n    ++foo *= 1.5;   // Rewrite to: (foo += 1) *= 1.5;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14672\n\nvoid test14672()\n{\n    interface I {}\n\n    class B {}\n    class D : B, I {}\n\n    D d = new D();\n    D[] da = [d];\n    B[] ba = [null];\n    I[] ia = [null];\n\n    // ba and da points different payloads,\n    // so element-wise assignment should work.\n    ba[] = da[];    // OK <- e2ir ICE\n    assert(ba[0] is d);\n\n    // Today element-wise assignment is implemented as memcpy, For that reason\n    // the conversion from derived classes to base interfaces is disallowed\n    // because it requries offset adjustments.\n    static assert(!__traits(compiles, { ia[] = da[]; }));\n\n    // after the assignment, ba will wongly point the payload of da,\n    // that's typed as D[]. To aboid type system breaking, it's disallowed.\n    static assert(!__traits(compiles, { ba = da; }));\n\n    // the assigned array literal is a new payload,\n    // so rebinding ba should work.\n    ba = [d];       // OK\n    assert(ba[0] is d);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15044\n\nvoid destroy15044(T)(ref T obj)\n{\n    static if (__traits(hasMember, T, \"__xdtor\"))\n        obj.__xdtor();\n    else\n        static assert(0, T.stringof);\n}\n\nstruct V15044\n{\n    ~this()\n    {\n    }\n\n    RC15044!V15044 dup()\n    {\n        return RC15044!V15044(&this);\n    }\n}\n\nstruct RC15044(T)\n{\n    ~this()\n    {\n        destroy15044(*t);\n        static assert(__traits(hasMember, T, \"__xdtor\"));\n    }\n    T* t;\n}\n\n/***************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test4424();\n    test6174a();\n    test6174b();\n    test6174c();\n    test6216a();\n    test6216b();\n    test6216c();\n    test6216d();\n    test6216e();\n    test6286();\n    test6336();\n    test9154();\n    test9416();\n    test11187();\n    test12131();\n    test12211();\n    test4791();\n    test12212();\n    test12650();\n    test13044();\n    test12500();\n    test14672();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testbitarray.d",
    "content": "// PERMUTE_ARGS:\n\nimport std.bitmanip;\n\nvoid main() {\n        BitArray a;\n        a.length = 5;\n        foreach (ref bool b; a) {\n                assert (b == 0);\n                b = 1;\n        }\n        foreach (bool b; a)\n                assert (b == 1); // FAILS, they're all 0\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testbounds.d",
    "content": "// REQUIRED_ARGS:\n\n// Test array bounds checking\n\nimport core.exception;\nextern(C) int printf(const char*, ...);\n\ntemplate TypeTuple(T...) { alias T TypeTuple; }\n\n/******************************************/\n\nconst int[10] foos = [1,2,3,4,5,6,7,8,9,10];\nconst int[] food   = [21,22,23,24,25,26,27,28,29,30];\nconst int *foop    = cast(int*) foos;\n\nstatic int x = 2;\n\nint index()\n{\n    return x++;\n}\n\nint tests(int i)\n{\n    return foos[index()];\n}\n\nint testd(int i)\n{\n    return food[index()];\n}\n\nint testp(int i)\n{\n    return foop[i];\n}\n\nconst(int)[] slices(int lwr, int upr)\n{\n    return foos[lwr .. upr];\n}\n\nconst(int)[] sliced(int lwr, int upr)\n{\n    return food[lwr .. upr];\n}\n\nconst(int)[] slicep(int lwr, int upr)\n{\n    return foop[lwr .. upr];\n}\n\nvoid test1()\n{\n    int i;\n\n    i = tests(0);\n    assert(i == 3);\n\n    i = testd(0);\n    assert(i == 24);\n\n    i = testp(1);\n    assert(i == 2);\n\n    x = 10;\n    try\n    {\n        i = tests(0);\n    }\n    catch (RangeError a)\n    {\n        i = 73;\n    }\n    assert(i == 73);\n\n    x = -1;\n    try\n    {\n        i = testd(0);\n    }\n    catch (RangeError a)\n    {\n        i = 37;\n    }\n    assert(i == 37);\n\n    const(int)[] r;\n\n    r = slices(3,5);\n    assert(r[0] == foos[3]);\n    assert(r[1] == foos[4]);\n\n    r = sliced(3,5);\n    assert(r[0] == food[3]);\n    assert(r[1] == food[4]);\n\n    r = slicep(3,5);\n    assert(r[0] == foos[3]);\n    assert(r[1] == foos[4]);\n\n    try\n    {\n        i = 7;\n        r = slices(5,3);\n    }\n    catch (RangeError a)\n    {\n        i = 53;\n    }\n    assert(i == 53);\n\n    try\n    {\n        i = 7;\n        r = slices(5,11);\n    }\n    catch (RangeError a)\n    {\n        i = 53;\n    }\n    assert(i == 53);\n\n    try\n    {\n        i = 7;\n        r = sliced(5,11);\n    }\n    catch (RangeError a)\n    {\n        i = 53;\n    }\n    assert(i == 53);\n\n    try\n    {\n        i = 7;\n        r = slicep(5,3);\n    }\n    catch (RangeError a)\n    {\n        i = 53;\n    }\n    assert(i == 53);\n\n    // Take side effects into account\n    x = 1;\n    r = foos[index() .. 3];\n    assert(x == 2);\n    assert(r[0] == foos[1]);\n    assert(r[1] == foos[2]);\n\n    r = foos[1 .. index()];\n    assert(r.length == 1);\n    assert(x == 3);\n    assert(r[0] == foos[1]);\n\n    x = 1;\n    r = food[index() .. 3];\n    assert(x == 2);\n    assert(r[0] == food[1]);\n    assert(r[1] == food[2]);\n\n    r = food[1 .. index()];\n    assert(r.length == 1);\n    assert(x == 3);\n    assert(r[0] == food[1]);\n\n    x = 1;\n    r = foop[index() .. 3];\n    assert(x == 2);\n    assert(r[0] == foop[1]);\n    assert(r[1] == foop[2]);\n\n    r = foop[1 .. index()];\n    assert(r.length == 1);\n    assert(x == 3);\n    assert(r[0] == foop[1]);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13976\n\nvoid test13976()\n{\n    int[] da = new int[](10);\n    int[10] sa;\n    enum size_t two = 2;\n    enum size_t five = 5;\n    size_t lb = 0;                    // upperInRange\n    size_t ub = 9;                    // | lowerLessThan\n                                      // | |  check code\n    { auto s = da[lb .. ub];        } // 0 0  (ub   <= $  && lb <= ub  )\n    { auto s = da[1 .. ub];         } // 0 0  (ub   <= $  && 1  <= ub  )\n    { auto s = da[lb .. 10];        } // 0 0  (10   <= $  && lb <= 10  )\n    { auto s = da[1 .. ub%5];       } // 0 0  (ub%5 <= $  && 1  <= ub%5)\n\n    { auto s = da[lb .. ub];        } // 0 0  (ub   <= $  && lb <= ub  )\n    { auto s = da[0 .. ub];         } // 0 1  (ub   <= $               )\n    { auto s = da[lb .. 10];        } // 0 0  (10   <= $  && lb <= 10  )\n    { auto s = da[0 .. ub%5];       } // 0 1  (ub%5 <= $               )\n\n    { auto s = da[0 .. 0];          } // 1 1  NULL\n    { auto s = da[0 .. $];          } // 1 1  NULL\n    { auto s = da[1 .. $];          } // 1 0  (              1   <= $  )\n    { auto s = da[$ .. $];          } // 1 0  (              $   <= $  )\n    { auto s = da[0 .. $/two];      } // 0 1  ($/2  <= $               )\n    { auto s = da[$/two .. $];      } // 1 0  (              $/2 <= $  )\n    { auto s = da[$/five .. $/two]; } // 0 0  ($/2  <= $  && $/5 <= $/2)\n\n    { auto s = sa[lb .. ub];        } // 0 0  (ub   <= 10 && lb <= ub  )\n    { auto s = sa[1 .. ub];         } // 0 0  (ub   <= 10 && 1  <= ub  )\n    { auto s = sa[lb .. 10];        } // 1 0  (              lb <= 10  )\n    { auto s = sa[1 .. ub%5];       } // 1 0  (              1  <= ub%5)\n\n    { auto s = sa[lb .. ub];        } // 0 0  (ub   <= 10 && lb <= ub  )\n    { auto s = sa[0 .. ub];         } // 0 1  (ub   <= 10              )\n    { auto s = sa[lb .. 10];        } // 1 0  (              lb <= 10  )\n    { auto s = sa[0 .. ub%5];       } // 1 1  NULL\n\n    { auto s = sa[0 .. 0];          } // 1 1  NULL\n    { auto s = sa[0 .. $];          } // 1 1  NULL\n    { auto s = sa[1 .. $];          } // 1 1  NULL\n    { auto s = sa[$ .. $];          } // 1 1  NULL\n    { auto s = sa[0 .. $/two];      } // 1 1  NULL\n    { auto s = sa[$/two .. $];      } // 1 1  NULL\n    { auto s = sa[$/five .. $/two]; } // 1 1  NULL\n\n    int* p = new int[](10).ptr;\n    { auto s = p[0 .. ub];          } // 1 1  NULL\n    { auto s = p[lb .. ub];         } // 1 0  (lb <= ub  )\n    { auto s = p[0 .. ub%5];        } // 1 1  NULL\n    { auto s = p[1 .. ub%5];        } // 1 0  (1  <= ub%5)\n    { auto s = p[0 .. 0];           } // 1 1  NULL\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3652\n\nvoid test3652()\n{\n    int foo(int[4] x)\n    {\n        return x[0] + x[1] * x[2] - x[3];\n    }\n\n    int[] xs = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];\n\n    // simple case\n    foo(xs[0 .. 4]);\n\n  version(none)\n  {\n    // Need deformation of formula and detection of base point\n    int x = 0;\n    int y = 0;\n    foreach (i; 0 .. 4)\n    {\n        x += foo(xs[i .. i + 4]);\n        y += foo(xs[(i*4+10)/2 .. (i*8>>1)/2+9]);\n        // lwr = (i*4 + 10)/2 = i*4/2 + 10/2            = (i*2+5)\n        // upr = (i*8>>1)/2 + 5 = (i*4/2) + 5 = i*2 + 9 = (i*2+5) + 4\n    }\n    assert(x == (0,1,2,3) + (1,2,3, 4) + (2, 3, 4, 5) + ( 3, 4, 5, 6));\n    assert(y == (5,6,7,8) + (7,8,9,10) + (9,10,11,12) + (11,12,13,14));\n  }\n}\n\nvoid test3652a() @safe\n{\n    string str = \"aaaabbbbccccdddd\";\n    //printf(\"str.ptr = %p\\n\", str.ptr);\n\n    void foo(ref const(char)[16] buf)\n    {\n        //printf(\"buf.ptr = %p\\n\", buf.ptr);\n        assert(buf.ptr is str.ptr);\n    }\n\n    // can check length at runtime\n    assert(str.length == 16);\n\n    // compiler can check the length of string literal, so\n    // conversion from immutable(char)[] to ref const(char)[16] is allowed;\n    static assert(__traits(compiles, foo(\"aaaabbbbccccdddd\")));\n\n    // OK, correctly rejected by the compiler.\n    static assert(!__traits(compiles, foo(str[])));\n\n    // Ugly, furthermore does not work in safe code!\n    //foo(*cast(const(char)[16]*)(str[0..16].ptr));\n\n    // New: compiler can check the length of slice, but currently it is not allowed.\n    enum size_t m = 0;\n    size_t calc(){ return 0; }\n    foo(str[0 .. 16]);\n    foo(str[m .. 16]);\n  //foo(str[calc() .. 16]); // with CTFE\n\n    // If boundaries cannot be calculated in compile time, it's rejected.\n    size_t n;\n    size_t calc2(){ return n; }\n    static assert(!__traits(compiles, foo(str[n .. 16])));\n    static assert(!__traits(compiles, foo(str[calc2() .. 16])));\n\n    void hoo1(size_t dim)(char[dim]) { static assert(dim == 2); }\n    void hoo2(char[2]) {}\n    void hoo3(size_t dim)(ref char[dim]) {}\n    void hoo4(ref char[2]) {}\n    hoo1(str[0 .. 2]);\n    hoo2(str[0 .. 2]);\n    static assert(!__traits(compiles, hoo3(str[0 .. 2])));\n    static assert(!__traits(compiles, hoo4(str[0 .. 2])));\n}\nvoid test3652b() @safe\n{\n    int[] da = [1,2,3,4,5];\n\n    void bar(int[3] sa1, ref int[3] sa2)\n    {\n        assert(sa1 == [1,2,3] && sa1.ptr !is da.ptr);\n        assert(sa2 == [1,2,3] && sa2.ptr  is da.ptr);\n    }\n    bar(da[0..3], da[0..3]);\n    static assert(!__traits(compiles, bar(da[0..4], da[0..4])));\n\n    void baz1(T)(T[3] sa1, ref T[3] sa2)\n    {\n        assert(sa1 == [1,2,3] && sa1.ptr !is da.ptr);\n        assert(sa2 == [1,2,3] && sa2.ptr  is da.ptr);\n    }\n    void baz2(T, size_t dim)(T[dim] sa1, ref T[dim] sa2, size_t result)\n    {\n        assert(dim == result);\n        static if (dim == 3)\n        {\n            assert(sa1 == [1,2,3] && sa1.ptr !is da.ptr);\n            assert(sa2 == [1,2,3] && sa2.ptr  is da.ptr);\n        }\n        else\n        {\n            assert(sa1 == [1,2,3,4] && sa1.ptr !is da.ptr);\n            assert(sa2 == [1,2,3,4] && sa2.ptr  is da.ptr);\n        }\n    }\n    baz1(da[0..3], da[0..3]);\n    static assert(!__traits(compiles, baz1(da[0..4], da[0..4])));\n    baz2(da[0..3], da[0..3], 3);\n    baz2(da[0..4], da[0..4], 4);\n\n    void hoo1(size_t dim)(int[dim]) { static assert(dim == 2); }\n    void hoo2(int[2]) {}\n    void hoo3(size_t dim)(ref int[dim]) {}\n    void hoo4(ref int[2]) {}\n    hoo1(da.idup[0 .. 2]);\n    hoo2(da.idup[0 .. 2]);\n    static assert(!__traits(compiles, hoo3(da.idup[0 .. 2])));\n    static assert(!__traits(compiles, hoo4(da.idup[0 .. 2])));\n}\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=9654\n\nauto foo9654a(ref           char[8] str) { return str; }\nauto foo9654b(ref     const char[8] str) { return str; }\nauto foo9654c(ref immutable char[8] str) { return str; }\nstatic assert(!is(typeof(foo9654a(\"testinfo\"))));\nstatic assert( is(typeof(foo9654b(\"testinfo\")) ==     const char[8]));\nstatic assert( is(typeof(foo9654c(\"testinfo\")) == immutable char[8]));\n\nauto bar9654a(T)(ref           T[8] str) { return str; static assert(is(T == immutable char)); }\nauto bar9654b(T)(ref     const T[8] str) { return str; static assert(is(T ==           char)); }\nauto bar9654c(T)(ref immutable T[8] str) { return str; static assert(is(T ==           char)); }\nstatic assert( is(typeof(bar9654a(\"testinfo\")) == immutable char[8]));\nstatic assert( is(typeof(bar9654b(\"testinfo\")) ==     const char[8]));\nstatic assert( is(typeof(bar9654c(\"testinfo\")) == immutable char[8]));\n\nauto baz9654a(T, size_t dim)(ref           T[dim] str) { return str; static assert(is(T == immutable char)); }\nauto baz9654b(T, size_t dim)(ref     const T[dim] str) { return str; static assert(is(T ==           char)); }\nauto baz9654c(T, size_t dim)(ref immutable T[dim] str) { return str; static assert(is(T ==           char)); }\nstatic assert( is(typeof(baz9654a(\"testinfo\")) == immutable char[8]));\nstatic assert( is(typeof(baz9654b(\"testinfo\")) ==     const char[8]));\nstatic assert( is(typeof(baz9654c(\"testinfo\")) == immutable char[8]));\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9712\n\nauto func9712(T)(T[2] arg) { return arg; }\nstatic assert(is(typeof(func9712([1,2])) == int[2]));\n\nauto deduceLength9712(T,size_t n)(T[n] a) { return a; }\nstatic assert(is(typeof(deduceLength9712([1,2,3])) == int[3]));\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9743\n\nvoid test9743()\n{\n    //    +-Char\n    //    |+-Immutable or Const or Mutable\n    //    ||+-Value or Ref\n    //    |||+-Function                           or +-Template\n    void fCIVF(    immutable  char[4]) {}   void fCIVT()(    immutable  char[4]) {}\n    void fCCVF(        const  char[4]) {}   void fCCVT()(        const  char[4]) {}\n    void fCMVF(               char[4]) {}   void fCMVT()(               char[4]) {}\n    void fCIRF(ref immutable  char[4]) {}   void fCIRT()(ref immutable  char[4]) {}\n    void fCCRF(ref     const  char[4]) {}   void fCCRT()(ref     const  char[4]) {}\n    void fCMRF(ref            char[4]) {}   void fCMRT()(ref            char[4]) {}\n    alias fcOK = TypeTuple!(fCIVF, fCIVT, fCCVF, fCCVT, fCMVF, fCMVT, fCIRF, fCIRT, fCCRF, fCCRT);\n    foreach (f; fcOK)                                   f(\"1234\" )   ;\n    foreach (f; fcOK)                                   f(\"1234\"c)   ;\n    foreach (f; fcOK) static assert(!__traits(compiles, f(\"1234\"w) ));\n    foreach (f; fcOK) static assert(!__traits(compiles, f(\"1234\"d) ));\n    alias fcNG = TypeTuple!(fCMRF, fCMRT);  // cannot hold immutable data by mutable ref\n    foreach (f; fcNG) static assert(!__traits(compiles, f(\"1234\" ) ));\n    foreach (f; fcNG) static assert(!__traits(compiles, f(\"1234\"c) ));\n    foreach (f; fcNG) static assert(!__traits(compiles, f(\"1234\"w) ));\n    foreach (f; fcNG) static assert(!__traits(compiles, f(\"1234\"d) ));\n\n    //    +-Wchar\n    void fWIVF(    immutable wchar[4]) {}   void fWIVT()(    immutable wchar[4]) {}\n    void fWCVF(        const wchar[4]) {}   void fWCVT()(        const wchar[4]) {}\n    void fWMVF(              wchar[4]) {}   void fWMVT()(              wchar[4]) {}\n    void fWIRF(ref immutable wchar[4]) {}   void fWIRT()(ref immutable wchar[4]) {}\n    void fWCRF(ref     const wchar[4]) {}   void fWCRT()(ref     const wchar[4]) {}\n    void fWMRF(ref           wchar[4]) {}   void fWMRT()(ref           wchar[4]) {}\n    alias fwOK = TypeTuple!(fWIVF, fWIVT, fWCVF, fWCVT, fWMVF, fWMVT, fWIRF, fWIRT, fWCRF, fWCRT);\n    foreach (f; fwOK)                                   f(\"1234\" )   ;\n    foreach (f; fwOK) static assert(!__traits(compiles, f(\"1234\"c) ));\n    foreach (f; fwOK)                                   f(\"1234\"w)   ;\n    foreach (f; fwOK) static assert(!__traits(compiles, f(\"1234\"d) ));\n    alias fwNG = TypeTuple!(fWMRF, fWMRT);  // cannot hold immutable data by mutable ref\n    foreach (f; fwNG) static assert(!__traits(compiles, f(\"1234\" ) ));\n    foreach (f; fwNG) static assert(!__traits(compiles, f(\"1234\"c) ));\n    foreach (f; fwNG) static assert(!__traits(compiles, f(\"1234\"w) ));\n    foreach (f; fwNG) static assert(!__traits(compiles, f(\"1234\"d) ));\n\n    //    +-Dchar\n    void fDIVF(    immutable dchar[4]) {}   void fDIVT()(    immutable dchar[4]) {}\n    void fDCVF(        const dchar[4]) {}   void fDCVT()(        const dchar[4]) {}\n    void fDMVF(              dchar[4]) {}   void fDMVT()(              dchar[4]) {}\n    void fDIRF(ref immutable dchar[4]) {}   void fDIRT()(ref immutable dchar[4]) {}\n    void fDCRF(ref     const dchar[4]) {}   void fDCRT()(ref     const dchar[4]) {}\n    void fDMRF(ref           dchar[4]) {}   void fDMRT()(ref           dchar[4]) {}\n    alias fdOK = TypeTuple!(fDIVF, fDIVT, fDCVF, fDCVT, fDMVF, fDMVT, fDIRF, fDIRT, fDCRF, fDCRT);\n    foreach (f; fdOK)                                   f(\"1234\" )   ;\n    foreach (f; fdOK) static assert(!__traits(compiles, f(\"1234\"c) ));\n    foreach (f; fdOK) static assert(!__traits(compiles, f(\"1234\"w) ));\n    foreach (f; fdOK)                                   f(\"1234\"d)   ;\n    alias fdNG = TypeTuple!(fDMRF, fDMRT);  // cannot hold immutable data by mutable ref\n    foreach (f; fdNG) static assert(!__traits(compiles, f(\"1234\" ) ));\n    foreach (f; fdNG) static assert(!__traits(compiles, f(\"1234\"c) ));\n    foreach (f; fdNG) static assert(!__traits(compiles, f(\"1234\"w) ));\n    foreach (f; fdNG) static assert(!__traits(compiles, f(\"1234\"d) ));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9747\n\nvoid foo9747A(T)(T[4]) {}\nvoid foo9747C(size_t dim)(char[dim]) {}\nvoid foo9747W(size_t dim)(wchar[dim]) {}\nvoid foo9747D(size_t dim)(dchar[dim]) {}\n\nvoid test9747()\n{\n    foo9747A(\"abcd\"c);\n    foo9747A(\"abcd\"w);\n    foo9747A(\"abcd\"d);\n    foo9747C(\"abcd\"c);\n    foo9747W(\"abcd\"w);\n    foo9747D(\"abcd\"d);\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12876\n\nvoid test12876()\n{\n    void foo(int[4] b) {}\n    void bar(size_t n)(int[n] c) { static assert(n == 4); }\n\n    int[5] a;\n    foo(a[1 .. $]); // OK\n    bar(a[1 .. $]); // OK <- Error\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13775\n\nvoid test13775()\n{\n    ubyte[4] ubytes = [1,2,3,4];\n\n    // CT-known slicing (https://issues.dlang.org/show_bug.cgi?id=3652)\n    auto ok1 = cast(ubyte[2]) ubytes[0 .. 2];\n    assert(ok1 == [1, 2]);\n\n    // CT-known slicing with implicit conversion of SliceExp::e1 (https://issues.dlang.org/show_bug.cgi?id=13154)\n    enum double[] arr = [1.0, 2.0, 3.0];\n    auto ok2 = cast(float[2]) [1.0, 2.0, 3.0][0..2];\n    auto ok3 = cast(float[2]) arr[1..3];    // currently this is accepted\n    assert(ok2 == [1f, 2f]);\n    assert(ok3 == [2f, 3f]);\n\n    // CT-known slicing with type coercing (https://issues.dlang.org/show_bug.cgi?id=13775)\n    auto ok4 = cast( byte[2]) ubytes[0 .. 2];   // CT-known slicing + type coercing\n    auto ok5 = cast(short[1]) ubytes[0 .. 2];   // CT-known slicing + type coercing\n    assert(ok4 == [1, 2]);\n    version(LittleEndian) assert(ok5 == [0x0201]);\n    version(   BigEndian) assert(ok5 == [0x0102]);\n}\n\n/******************************************/\n\nint main()\n{\n    test1();\n    test13976();\n    test3652();\n    test3652a();\n    test3652b();\n    test9743();\n    test9747();\n    test13775();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testbounds_off.d",
    "content": "// REQUIRED_ARGS: -boundscheck=off\n// PERMUTE_ARGS: -inline -g -O\n\nimport core.exception : RangeError;\n\n// Check for RangeError is thrown\nbool thrown(T)(lazy T cond)\n{\n    import core.exception;\n    bool f = false;\n    try { cond(); } catch (RangeError e) { f = true; }\n    return f;\n}\n\n@safe    int safeIndex   (int[] arr) { return arr[2]; }\n@trusted int trustedIndex(int[] arr) { return arr[2]; }\n@system  int systemIndex (int[] arr) { return arr[2]; }\n\nvoid main()\n{\n    int[3] data = [1,2,3];\n    int[] arr = data[0..2];\n\n    assert(arr.   safeIndex() == 3);\n    assert(arr.trustedIndex() == 3);\n    assert(arr. systemIndex() == 3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testbounds_on.d",
    "content": "// REQUIRED_ARGS: -boundscheck=on\n// PERMUTE_ARGS: -inline -g -O\n\nimport core.exception : RangeError;\n\n// Check for RangeError is thrown\nbool thrown(T)(lazy T cond)\n{\n    import core.exception;\n    bool f = false;\n    try { cond(); } catch (RangeError e) { f = true; }\n    return f;\n}\n\n@safe    int safeIndex   (int[] arr) { return arr[2]; }\n@trusted int trustedIndex(int[] arr) { return arr[2]; }\n@system  int systemIndex (int[] arr) { return arr[2]; }\n\nvoid main()\n{\n    int[3] data = [1,2,3];\n    int[] arr = data[0..2];\n\n    assert(arr.   safeIndex().thrown);\n    assert(arr.trustedIndex().thrown);\n    assert(arr. systemIndex().thrown);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testbounds_safeonly.d",
    "content": "// REQUIRED_ARGS: -boundscheck=safeonly\n// PERMUTE_ARGS: -inline -g -O\n\nimport core.exception : RangeError;\n\n// Check for RangeError is thrown\nbool thrown(T)(lazy T cond)\n{\n    import core.exception;\n    bool f = false;\n    try { cond(); } catch (RangeError e) { f = true; }\n    return f;\n}\n\n@safe    int safeIndex   (int[] arr) { return arr[2]; }\n@trusted int trustedIndex(int[] arr) { return arr[2]; }\n@system  int systemIndex (int[] arr) { return arr[2]; }\n\nvoid main()\n{\n    int[3] data = [1,2,3];\n    int[] arr = data[0..2];\n\n    assert(arr.   safeIndex().thrown);\n    assert(arr.trustedIndex() == 3);\n    assert(arr. systemIndex() == 3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testclass.d",
    "content": "extern(C) int printf(const char*, ...);\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12078\n\nclass B12078(T)\n{\n    static assert(is(T : B12078!T), \"not related\");\n}\nclass D12078 : B12078!D12078\n{\n}\n\ninterface X12078(T)\n{\n    static assert(is(T : X12078!T), \"not related\");\n}\ninterface Y12078 : X12078!Y12078\n{\n}\n\nvoid test12078()\n{\n    static assert(is(D12078 : B12078!D12078));\n    static assert(is(Y12078 : X12078!Y12078));\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12143\n\nclass Node12143\n{\n    alias typeof(true ? Node12143.init : Class12143.init) V;\n    static assert(is(V == Node12143));\n}\n\nclass Type12143 : Node12143 {}\n\nclass Class12143 : Type12143 {}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13353\n\ninterface Base13353(T)\n{\n    static assert(is(T : Base13353!T));\n}\n\ninterface Derived13353 : Base13353!Derived13353\n{\n    void func();\n}\n\nclass Concrete13353 : Derived13353\n{\n    void func() {}\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15733\n\nclass CStmt15733 : CNode15733 {}\nclass CDecl15733 : CStmt15733 {}\nclass CNode15733 { mixin CMix!CDecl15733; }\ntemplate CMix(T){ mixin(\"static \" ~ T.stringof ~ \" x;\"); }\n\ninterface IStmt15733 : INode15733 {}\ninterface IDecl15733 : IStmt15733 {}\ninterface INode15733 { mixin IMix!IDecl15733; }\ntemplate IMix(T){ mixin(\"static \" ~ T.stringof ~ \" x;\"); }\n\n/***************************************************/\n\nint main()\n{\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testconst.d",
    "content": "\nimport core.stdc.stdio;\n\nclass C { }\n\nint ctfe() { return 3; }\n\ntemplate TypeTuple(T...) { alias T TypeTuple; }\n\n/************************************/\n\nvoid showf(string f)\n{\n    printf(\"%.*s\\n\", f.length, f.ptr);\n}\n\n/************************************/\n\nvoid test1()\n{\n    const int* p;\n    const(int)* cp;\n    cp = p;\n}\n\n/************************************/\n\nvoid test2()\n{\n    const int i = 3;\n    const(int) j = 0;\n    int k;\n//    j = i;\n    k = i;\n    k = j;\n//    assert(k == 3);\n}\n\n/************************************/\n\nvoid test3()\n{\n    char[3] p;\n    const(char)[] q;\n\n    q = p;\n}\n\n/************************************/\n\nvoid test4()\n{\n    char[] p;\n    const(char)[] q;\n\n    q = p;\n}\n\n/************************************/\n\nvoid test5()\n{\n    const(int**)* p;\n    const(int)*** cp;\n    p = cp;\n}\n\n/************************************/\n\nvoid test6()\n{\n    const(int***)[] p;\n    const(int)***[] cp;\n    p = cp;\n}\n\n/************************************/\n\nclass C8 { }\n\nvoid foo8(const char[] s, const C8 c, const int x)\n{\n}\n\nvoid test8()\n{\n    import core.demangle : demangle;\n    auto p = &foo8;\n    showf(p.mangleof);\n    assert(typeof(p).mangleof == \"PFxAaxC9testconst2C8xiZv\");\n    assert(demangle(p.mangleof) == \"void function(const(char[]), const(testconst.C8), const(int))* testconst.test8().p\");\n}\n\n/************************************/\n\nvoid test9()\n{\n    int [ const (char[]) ] aa;\n    int [ char[] ] ab;\n    int [ const char[] ] ac;\n\n    aa[\"hello\"] = 3;\n    ab[\"hello\"] = 3;\n    ac[\"hello\"] = 3;\n}\n\n/************************************/\n\nvoid test10()\n{\n    const(int) x = 3;\n    auto y = x;\n    //y++;\n    assert(is(typeof(y) == const(int)));\n}\n\n/************************************/\n\nvoid foo11(in char[] a1)\n{\n    char[3] c;\n    char[] a2 = c[];\n    a2[0..2] = a1;\n    a2[0..2] = 'c';\n\n    const char b = 'b';\n    a2[0..2] = b;\n}\n\nvoid test11()\n{\n}\n\n/************************************/\n\nvoid foo12(const char[] a1)\n{\n}\n\nvoid test12()\n{\n    foo12(\"hello\");\n}\n\n/************************************/\n\nimmutable char[16] hexdigits1 = \"0123456789ABCDE1\";\nimmutable char[  ] hexdigits2 = \"0123456789ABCDE2\";\n\nconst char[16] hexdigits3 = \"0123456789ABCDE3\";\nconst char[  ] hexdigits4 = \"0123456789ABCDE4\";\n\nvoid test13()\n{\n}\n\n/************************************/\n\nvoid test14()\n{\n    string s;\n    s = s ~ \"hello\";\n}\n\n/************************************/\n\nclass Foo15\n{\n    const string xxxx;\n\n    this(immutable char[] aaa)\n    {\n        this.xxxx = aaa;\n    }\n}\n\nvoid test15()\n{\n}\n\n/************************************/\n\nvoid test16()\n{\n    auto a = \"abc\";\n    immutable char[3] b = \"abc\";\n    const char[3] c = \"abc\";\n}\n\n/************************************/\n\nvoid test17()\n{\n    const(char)[3][] a = ([\"abc\", \"def\"]);\n\n    assert(a[0] == \"abc\");\n    assert(a[1] == \"def\");\n}\n\n/************************************/\n\nclass C18\n{\n    const(char)[] foo() { return \"abc\"; }\n}\n\nclass D18 : C18\n{\n    override char[] foo() { return null; }\n}\n\nvoid test18()\n{\n}\n\n/************************************/\n\nvoid test19()\n{\n    char[] s;\n    if (s == \"abc\")\n        s = null;\n    if (s < \"abc\")\n        s = null;\n    if (s is \"abc\")\n        s = null;\n}\n\n/************************************/\n\nvoid test20()\n{\n    string p;\n    immutable char[] q;\n\n    p = p ~ q;\n    p ~= q;\n}\n\n/************************************/\n\nvoid test21()\n{\n    string s;\n    char[] p;\n    p = s.dup;\n}\n\n/************************************/\n\nvoid fill22(const(char)[] s)\n{\n}\n\nvoid test22()\n{\n}\n\n/************************************/\n\n\nstruct S23\n{\n    int x;\n    int* p;\n}\n\n\nvoid foo23(const(S23) s, const(int) i)\n{\n    immutable int j = 3;\n//    j = 4;\n//    i = 4;\n//    s.x = 3;\n//    *s.p = 4;\n}\n\nvoid test23()\n{\n}\n\n/************************************/\n\nvoid test24()\n{\n    wchar[] r;\n\n    r ~= \"\\000\"w;\n}\n\n/************************************/\n\nvoid test25()\n{\n    char* p;\n    if (p == cast(const(char)*)\"abc\")\n    {}\n}\n\n/************************************/\n\nvoid test26()\n{\n    struct S\n    {\n        char[3] a;\n    }\n\n    static S s = { \"abc\" };\n}\n\n/************************************/\n\nclass C27\n{\n    int x;\n\n    void foo() { x = 3; }\n}\n\nvoid test27()\n{\n    C27 d = new C27;\n    d.foo();\n}\n\n/************************************/\n\nclass C28\n{\n    int x;\n\n    void foo() immutable { }\n}\n\nvoid test28()\n{\n    immutable(C28) d = cast(immutable)new C28;\n    d.foo();\n}\n\n/************************************/\n\nstruct S29 { }\n\nint foo29(const(S29)* s)\n{\n    S29 s2;\n    return *s == s2;\n}\n\nvoid test29()\n{\n}\n\n/************************************/\n\nstruct S30\n{\n    int x;\n\n    void foo() { x = 3; }\n    void bar() const\n    {   //x = 4;\n        //this.x = 5;\n    }\n}\n\nclass C30\n{\n    int x;\n\n    void foo() { x = 3; }\n    void bar() const\n    {   //x = 4;\n        //this.x = 5;\n    }\n}\n\nvoid test30()\n{   S30 s;\n\n    s.foo();\n    s.bar();\n\n    S30 t;\n    //t.foo();\n    t.bar();\n\n    C30 c = new C30;\n\n    c.foo();\n    c.bar();\n\n    C30 d = new C30;\n    d.foo();\n    d.bar();\n}\n\n\n/************************************/\n\nclass Foo31\n{\n  int x;\n\n  immutable immutable(int)* geti()\n  {\n    return &x;\n  }\n\n  const const(int)* getc()\n  {\n    return &x;\n  }\n}\n\nvoid test31()\n{\n}\n\n/************************************/\n\nint bar32;\n\nstruct Foo32\n{\n    int func() immutable\n    {\n        return bar32;\n    }\n}\n\nvoid test32()\n{\n    immutable(Foo32) foo;\n    printf(\"%d\", foo.func());\n    printf(\"%d\", foo.func());\n}\n\n/************************************/\n\nvoid test33()\n{\n    string d = \"a\"  ~  \"b\"  ~  (1?\"a\":\"\");\n    assert(d == \"aba\");\n}\n\n/************************************/\n\nstruct S34\n{\n   int value;\n}\n\nconst S34 s34 = { 5 };\n\nconst S34 t34 = s34;\nconst S34 u34 = s34;\n\nvoid test34()\n{\n    assert(u34.value == 5);\n}\n\n/************************************/\n\nconst int i35 = 20;\n\ntemplate Foo35(alias bar)\n{\n}\n\nalias Foo35!(i35) foo35;\n\nvoid test35()\n{\n}\n\n/************************************/\n\nimmutable char[10] digits    = \"0123456789\";  /// 0..9\nimmutable char[]  octdigits = digits[0 .. 8]; //// 0..7\n\nvoid test36()\n{\n}\n\n/************************************/\n\nvoid test37()\n{\n    int i = 3;\n    const int x = i;\n    i++;\n    assert(x == 3);\n}\n\n/************************************/\n\nvoid test38()\n{\n    static const string s = \"hello\"[1..$];\n    assert(s == \"ello\");\n}\n\n/************************************/\n\nstatic const int x39;\nconst int y39;\n\nstatic this()\n{\n    x39 = 3;\n    y39 = 4;\n}\n\nvoid test39()\n{\n    const int i;\n    assert(x39 == 3);\n    assert(y39 == 4);\n    const p = &x39;\n//    assert(*p == 3);\n}\n\n/************************************/\n\nstruct S40\n{\n    int a;\n    const int b = 3;    // shouldn't be allocated\n}\n\nvoid test40()\n{\n    assert(S40.sizeof == 8);\n    assert(S40.init.b == 3);\n}\n\n/************************************/\n\nstruct S41\n{\n    int a;\n    const int b;\n    static const int c = ctfe() + 1;\n}\n\nvoid test41()\n{\n    assert(S41.sizeof == 8);\n    S41 s;\n    assert(s.b == 0);\n    assert(S41.c == 4);\n\n    const(int)*p;\n    p = &s.b;\n    assert(*p == 0);\n    p = &s.c;\n    assert(*p == 4);\n}\n\n/************************************/\n\nclass C42\n{\n    int a = ctfe() - 2;\n    const int b;\n    const int c = ctfe();\n    static const int d;\n    static const int e = ctfe() + 2;\n\n    static this()\n    {\n        d = 4;\n    }\n\n    this()\n    {\n        b = 2;\n    }\n}\n\nvoid test42()\n{\n    printf(\"%d\\n\", C42.classinfo.initializer.length);\n    assert(C42.classinfo.initializer.length == 12 + (void*).sizeof +\n        (void*).sizeof);\n    C42 c = new C42;\n    assert(c.a == 1);\n    assert(c.b == 2);\n    assert(c.c == 3);\n    assert(c.d == 4);\n    assert(c.e == 5);\n\n    const(int)*p;\n    p = &c.b;\n    assert(*p == 2);\n    p = &c.c;\n    assert(*p == 3);\n    p = &c.d;\n    assert(*p == 4);\n    p = &c.e;\n    assert(*p == 5);\n}\n\n/************************************/\n\ntemplate Foo43(T)\n{\n    alias T Foo43;\n}\n\nvoid test43()\n{\n  {\n    int x;\n    alias Foo43!(typeof(x)) f;\n    showf(typeid(f).toString());\n    assert(is(typeof(x) == int));\n    assert(is(f == int));\n  }\n\n  {\n    const int x;\n    alias Foo43!(typeof(x)) f;\n    showf(typeid(f).toString());\n    assert(is(typeof(x) == const(int)));\n    assert(is(f == const(int)));\n  }\n\n  {\n    immutable int x;\n    alias Foo43!(typeof(x)) f;\n    showf(typeid(f).toString());\n    assert(is(typeof(x) == immutable(int)));\n    assert(is(f == immutable(int)));\n  }\n}\n\n/************************************/\n\ntemplate Foo44(T:T)\n{\n    alias T Foo44;\n}\n\nvoid test44()\n{\n  {\n    int x;\n    alias Foo44!(typeof(x)) f;\n    showf(typeid(f).toString());\n    assert(is(typeof(x) == int));\n    assert(is(f == int));\n  }\n\n  {\n    const int x;\n    alias Foo44!(typeof(x)) f;\n    showf(typeid(f).toString());\n    assert(is(typeof(x) == const(int)));\n    assert(is(f == const(int)));\n  }\n\n  {\n    immutable int x;\n    alias Foo44!(typeof(x)) f;\n    showf(typeid(f).toString());\n    assert(is(typeof(x) == immutable(int)));\n    assert(is(f == immutable(int)));\n  }\n}\n\n/************************************/\n\ntemplate Foo45(T:const(T))\n{\n    alias T Foo45;\n}\n\nvoid test45()\n{\n  {\n    int x;\n    alias Foo45!(typeof(x)) f;\n    showf(typeid(f).toString());\n    assert(is(typeof(x) == int));\n    assert(is(f == int));\n  }\n\n  {\n    const int x;\n    alias Foo45!(typeof(x)) f;\n    showf(typeid(f).toString());\n    assert(is(typeof(x) == const(int)));\n    assert(is(f == int));\n  }\n\n  {\n    immutable int x;\n    alias Foo45!(typeof(x)) f;\n    showf(typeid(f).toString());\n    assert(is(typeof(x) == immutable(int)));\n    assert(is(f == int));\n  }\n}\n\n/************************************/\n\ntemplate Foo46(T:immutable(T))\n{\n    alias T Foo46;\n}\n\nvoid test46()\n{\n  {\n    immutable int x;\n    alias Foo46!(typeof(x)) f;\n    showf(typeid(f).toString());\n    assert(is(typeof(x) == immutable(int)));\n    assert(is(f == int));\n  }\n}\n\n/************************************/\n\ntemplate Foo47(T:T)            { const int Foo47 = 2; }\ntemplate Foo47(T:const(T))     { const int Foo47 = 3; }\ntemplate Foo47(T:immutable(T)) { const int Foo47 = 4; }\n\nvoid test47()\n{\n    int x2;\n    const int x3;\n    immutable int x4;\n\n    printf(\"%d\\n\", Foo47!(typeof(x2)));\n    printf(\"%d\\n\", Foo47!(typeof(x3)));\n    printf(\"%d\\n\", Foo47!(typeof(x4)));\n\n    assert(Foo47!(typeof(x2)) == 2);\n    assert(Foo47!(typeof(x3)) == 3);\n    assert(Foo47!(typeof(x4)) == 4);\n}\n\n/************************************/\n\nint foo48(T)(const(T) t) { return 3; }\n\nvoid test48()\n{\n    const int x = 4;\n    assert(foo48(x) == 3);\n}\n\n/************************************/\n\nvoid foo49(T)(T[] t)\n{\n    showf(typeid(typeof(t)).toString());\n    assert(is(T == immutable(char)));\n}\n\nvoid bar49(T)(const T t)\n{\n    showf(typeid(T).toString());\n    assert(is(T == const(int)) || is(T == immutable(int)) || is(T == int));\n}\n\nvoid test49()\n{\n    string s;\n    foo49(s);\n    foo49(\"hello\");\n\n    const int c = 1;\n    bar49(c);\n\n    immutable int i = 1;\n    bar49(i);\n\n    bar49(1);\n}\n\n/************************************/\n\nvoid foo50(T)(T t)\n{\n    showf(typeid(typeof(t)).toString());\n    assert(is(T == C));\n}\n\nvoid baz50(T)(T t)\n{\n    showf(typeid(typeof(t)).toString());\n    assert(is(T == const(C)));\n}\n\nvoid bar50(T)(const T t)\n{\n    showf(typeid(T).toString());\n    showf(typeid(typeof(t)).toString());\n    assert(is(T == C));\n    assert(is(typeof(t) == const(C)));\n}\n\nvoid abc50(T)(const T t)\n{\n    showf(typeid(T).toString());\n    showf(typeid(typeof(t)).toString());\n    assert(is(T == C));\n    assert(is(typeof(t) == const(C)));\n}\n\nvoid test50()\n{\n    C c = new C;\n    const(C) d = new C;\n\n    foo50(c);\n    baz50(d);\n\n    bar50(c);\n    abc50(d);\n}\n\n/************************************/\n\nvoid test51()\n{\n    const(C) d = new C;\n    //d = new C;\n}\n\n/************************************/\n\ntemplate isStaticArray(T)\n{\n    const bool isStaticArray = false;\n}\n\ntemplate isStaticArray(T : T[N], size_t N)\n{\n    const bool isStaticArray = true;\n}\n\ntemplate isDynamicArray(T, U = void)\n{\n    static const isDynamicArray = false;\n}\n\ntemplate isDynamicArray(T : U[], U)\n{\n  static const isDynamicArray = !isStaticArray!(T);\n}\n\nvoid test52()\n{\n    immutable(char[5])[int] aa = ([3:\"hello\", 4:\"betty\"]);\n\n    showf(typeid(typeof(aa.values)).toString());\n    static assert(isDynamicArray!(typeof(aa.values)));\n}\n\n/************************************/\n\nvoid foo53(string n) { }\n\nvoid read53(in string name)\n{\n    foo53(name);\n}\n\nvoid test53()\n{\n    read53(\"hello\");\n}\n\n/************************************/\n\nvoid bar54(const(wchar)[] s) { }\n\nvoid test54()\n{\n    const(wchar)[] fmt;\n    bar54(\"Orphan format specifier: %\" ~ fmt);\n}\n\n/************************************/\n\nstruct S55\n{\n    int foo() { return 1; }\n    int foo() const { return 2; }\n    int foo() immutable { return 3; }\n}\n\nvoid test55()\n{\n    S55 s1;\n    auto i = s1.foo();\n    assert(i == 1);\n\n    const S55 s2;\n    i = s2.foo();\n    assert(i == 2);\n\n    immutable S55 s3;\n    i = s3.foo();\n    assert(i == 3);\n}\n\n/************************************/\n\nconst struct S56 { int a; }\n\nvoid test56()\n{\n    S56 s;\n    S56 t;\n    printf(\"S56.sizeof = %d\\n\", S56.sizeof);\n    //t = s;\n}\n\n/************************************/\n\nstruct S57\n{\n    const void foo(this T)(int i)\n    {\n        showf(typeid(T).toString());\n        if (i == 1)\n            assert(is(T == const));\n        if (i == 2)\n            assert(!is(T == const));\n        if (i == 3)\n            assert(is(T == immutable));\n    }\n}\n\nvoid test57()\n{\n    const(S57) s;\n    (&s).foo(1);\n    S57 s2;\n    s2.foo(2);\n    immutable(S57) s3;\n    s3.foo(3);\n}\n\n/************************************/\n\nclass C58\n{\n    const(C58) c;\n    const C58 y;\n\n    this()\n    {\n        y = null;\n        c = null;\n    }\n\n    const void foo()\n    {\n        //c = null; // should fail\n    }\n\n    void bar()\n    {\n        //c = null;\n    }\n}\n\nvoid test58()\n{\n}\n\n/************************************/\n\nclass A59\n{\n    int[] a;\n    this() { a.length = 1; }\n\n    int* ptr() { return a.ptr; }\n    const const(int)* ptr() { return a.ptr; }\n    immutable immutable(int)* ptr() { return a.ptr; }\n}\n\nvoid test59()\n{\n    auto a = new A59;\n    const b = cast(const)new A59;\n    immutable c = cast(immutable)new A59;\n}\n\n/************************************/\n\nint foo60(int i) { return 1; }\nint foo60(const int i) { return 2; }\nint foo60(immutable int i) { return 3; }\n\nvoid test60()\n{\n    int i;\n    const int j;\n    immutable int k;\n\n    assert(foo60(i) == 1);\n    assert(foo60(j) == 2);\n    assert(foo60(k) == 3);\n}\n\n/************************************/\n\nvoid foo61(T)(T arg)\n{\n    alias const(T) CT;\n    assert(is(const(int) == CT));\n    //writeln(typeid(const(T)));\n    //writeln(typeid(CT));\n}\n\nvoid test61()\n{\n    int x = 42;\n    foo61(x);\n}\n\n/************************************/\n\nclass Foo62(T) { }\n\nvoid test62()\n{\n    const(Foo62!(int)) f = new Foo62!(int);\n    assert(is(typeof(f) == const(Foo62!(int))));\n}\n\n/************************************/\n\nstruct S63\n{\n    int x;\n}\n\nvoid foo63(const ref S63 scheme)\n{\n    //scheme.x = 3;\n}\n\nvoid test63()\n{\n        S63 scheme;\n        foo63(scheme);\n}\n\n/************************************/\n\nstruct S64\n{\n    int a;\n    long b;\n}\n\nvoid test64()\n{\n    S64 s1 = S64(2,3);\n    const s2 = S64(2,3);\n    immutable S64 s3 = S64(2,3);\n\n    s1 = s1;\n    s1 = s2;\n    s1 = s3;\n}\n\n/************************************/\n\nstruct S65\n{\n    int a;\n    long b;\n    char *p;\n}\n\nvoid test65()\n{   char c;\n    S65 s1 = S65(2,3);\n    const s2 = S65(2,3);\n    immutable S65 s3 = S65(2,3);\n\n    S65 t1 = S65(2,3,null);\n    const t2 = S65(2,3,null);\n    immutable S65 t3 = S65(2,3,null);\n}\n\n/************************************/\n\nstruct S66\n{\n    int a;\n    long b;\n}\n\nvoid test66()\n{   char c;\n    S66 s1 = S66(2,3);\n    const s2 = S66(2,3);\n    immutable S66 s3 = S66(2,3);\n\n    S66 t1 = s1;\n    S66 t2 = s2;\n    S66 t3 = s3;\n\n    const(S66) u1 = s1;\n    const(S66) u2 = s2;\n    const(S66) u3 = s3;\n\n    immutable(S66) v1 = s1;\n    immutable(S66) v2 = s2;\n    immutable(S66) v3 = s3;\n}\n\n/************************************/\n\nstruct Foo68\n{\n    int z;\n    immutable int x;\n    int y;\n}\n\nvoid test68()\n{\n    Foo68 bar;\n    bar.y = 2;\n}\n\n/************************************/\n\nclass C69 {}\nstruct S69 {}\n\nvoid test69()\n{\n        immutable(S69)* si;\n        S69* sm;\n        bool a = si is sm;\n\n        immutable(C69) ci;\n        const(C69) cm;\n        bool b = ci is cm;\n}\n\n/************************************/\n\nstruct S70\n{\n  int i;\n}\n\nvoid test70()\n{\n  S70 s;\n  const(S70) cs = s;\n  S70 s1 = cs;\n  S70 s2 = cast(S70)cs;\n}\n\n/************************************/\n\nvoid test72()\n{\n    int a;\n    const int b;\n    enum { int c = 0 }\n    immutable int d = 0;\n\n    assert(__traits(isSame, a, a));\n    assert(__traits(isSame, b, b));\n    assert(__traits(isSame, c, c));\n    assert(__traits(isSame, d, d));\n}\n\n/************************************/\n\nvoid a73(const int [] data...)\n{\n    a73(1);\n}\n\nvoid test73()\n{\n}\n\n/************************************/\n\nstruct S74 { int x; }\n\nconst S74 s_const = {0};\n\nS74 s_mutable = s_const;\n\nvoid test74()\n{\n}\n\n/************************************/\n\nstruct A75 { int x; }\nstruct B75 { A75 s1; }\n\nconst A75 s1_const = {0};\nconst B75 s2_const = {s1_const};\n\nvoid test75()\n{\n}\n\n/************************************/\n\nvoid test76()\n{\n    int[int] array;\n    const(int[int]) a = array;\n}\n\n/************************************/\n\nvoid test77()\n{\n    int[][] intArrayArray;\n    int[][][] intArrayArrayArray;\n\n//    const(int)[][] f1 = intArrayArray;\n    const(int[])[] f2 = intArrayArray;\n\n//    const(int)[][][] g1 = intArrayArrayArray;\n//    const(int[])[][] g2 = intArrayArrayArray;\n    const(int[][])[] g3 = intArrayArrayArray;\n}\n\n/************************************/\n\nvoid foo78(T)(const(T)[] arg1, const(T)[] arg2) { }\n\nvoid test78()\n{\n    foo78(\"hello\", \"world\".dup);\n    foo78(\"hello\", \"world\");\n    foo78(\"hello\".dup, \"world\".dup);\n    foo78(cast(const)\"hello\", cast(const)\"world\");\n}\n\n/************************************/\n\nconst bool[string] stopWords79;\n\nstatic this()\n{\n    stopWords79 = [ \"a\"[]:1 ];\n}\n\nvoid test79()\n{\n    \"abc\" in stopWords79;\n}\n\n/************************************/\n\nvoid test80(inout(int) _ = 0)\n{\n    char x;\n    inout(char) y = x;\n\n    const(char)[] c;\n    immutable(char)[] i;\n    shared(char)[] s;\n    const(shared(char))[] sc;\n    inout(char)[] w;\n    inout(shared(char))[] sw;\n\n    c = c;\n    c = i;\n    static assert(!__traits(compiles, c = s));\n    static assert(!__traits(compiles, c = sc));\n    c = w;\n    static assert(!__traits(compiles, c = sw));\n\n    static assert(!__traits(compiles, i = c));\n    i = i;\n    static assert(!__traits(compiles, i = s));\n    static assert(!__traits(compiles, i = sc));\n    static assert(!__traits(compiles, i = w));\n    static assert(!__traits(compiles, i = sw));\n\n    static assert(!__traits(compiles, s = c));\n    static assert(!__traits(compiles, s = i));\n    s = s;\n    static assert(!__traits(compiles, s = sc));\n    static assert(!__traits(compiles, s = w));\n    static assert(!__traits(compiles, s = sw));\n\n    static assert(!__traits(compiles, sc = c));\n    sc = i;\n    sc = s;\n    sc = sc;\n    static assert(!__traits(compiles, sc = w));\n    sc = sw;\n\n    static assert(!__traits(compiles, w = c));\n    static assert(!__traits(compiles, w = i));\n    static assert(!__traits(compiles, w = s));\n    static assert(!__traits(compiles, w = sc));\n    w = w;\n    static assert(!__traits(compiles, w = sw));\n\n    static assert(!__traits(compiles, sw = c));\n    static assert(!__traits(compiles, sw = i));\n    static assert(!__traits(compiles, sw = s));\n    static assert(!__traits(compiles, sw = sc));\n    static assert(!__traits(compiles, sw = w));\n    sw = sw;\n}\n\n/************************************/\n\nvoid test81(inout(int) _ = 0)\n{\n    const(char)* c;\n    immutable(char)* i;\n    shared(char)* s;\n    const(shared(char))* sc;\n    inout(char)* w;\n\n    c = c;\n    c = i;\n    static assert(!__traits(compiles, c = s));\n    static assert(!__traits(compiles, c = sc));\n    c = w;\n\n    static assert(!__traits(compiles, i = c));\n    i = i;\n    static assert(!__traits(compiles, i = s));\n    static assert(!__traits(compiles, i = sc));\n    static assert(!__traits(compiles, i = w));\n\n    static assert(!__traits(compiles, s = c));\n    static assert(!__traits(compiles, s = i));\n    s = s;\n    static assert(!__traits(compiles, s = sc));\n    static assert(!__traits(compiles, s = w));\n\n    static assert(!__traits(compiles, sc = c));\n    sc = i;\n    sc = s;\n    sc = sc;\n    static assert(!__traits(compiles, sc = w));\n\n    static assert(!__traits(compiles, w = c));\n    static assert(!__traits(compiles, w = i));\n    static assert(!__traits(compiles, w = s));\n    static assert(!__traits(compiles, w = sc));\n    w = w;\n}\n\n/************************************/\n\n\nvoid test82(inout(int) _ = 0)\n{\n    const(immutable(char)*) c;\n    pragma(msg, typeof(c));\n    static assert(typeof(c).stringof == \"const(immutable(char)*)\");\n\n    inout(immutable(char)*) d;\n    pragma(msg, typeof(d));\n    static assert(typeof(d).stringof == \"inout(immutable(char)*)\");\n\n    inout(const(char)*) e;\n\n    pragma(msg, typeof(e));\n    static assert(is(typeof(e) == inout(const(char)*)));\n    static assert(typeof(e).stringof == \"inout(const(char)*)\");\n\n    pragma(msg, typeof(*e));\n    static assert(is(typeof(*e) == inout(const(char))));\n    static assert(typeof(*e).stringof == \"inout(const(char))\");\n\n    inout const(char)* f;\n    static assert(is(typeof(e) == typeof(f)));\n\n    inout(shared(char)) g;\n    pragma(msg, typeof(g));\n    static assert(typeof(g).stringof == \"shared(inout(char))\");\n\n    shared(inout(char)) h;\n    pragma(msg, typeof(h));\n    static assert(typeof(h).stringof == \"shared(inout(char))\");\n\n    inout(immutable(char)) i;\n    pragma(msg, typeof(i));\n    static assert(typeof(i).stringof == \"immutable(char)\");\n\n    immutable(inout(char)) j;\n    pragma(msg, typeof(j));\n    static assert(typeof(j).stringof == \"immutable(char)\");\n\n    inout(const(char)) k;\n    pragma(msg, typeof(k));\n    static assert(typeof(k).stringof == \"inout(const(char))\");\n\n    const(inout(char)) l;\n    pragma(msg, typeof(l));\n    static assert(typeof(l).stringof == \"inout(const(char))\");\n\n    shared(const(char)) m;\n    pragma(msg, typeof(m));\n    static assert(typeof(m).stringof == \"shared(const(char))\");\n\n    const(shared(char)) n;\n    pragma(msg, typeof(n));\n    static assert(typeof(n).stringof == \"shared(const(char))\");\n\n    inout(char*****) o;\n    pragma(msg, typeof(o));\n    static assert(typeof(o).stringof == \"inout(char*****)\");\n    pragma(msg, typeof(cast()o));\n    static assert(typeof(cast()o).stringof == \"inout(char****)*\");\n\n    const(char*****) p;\n    pragma(msg, typeof(p));\n    static assert(typeof(p).stringof == \"const(char*****)\");\n    pragma(msg, typeof(cast()p));\n    static assert(typeof(cast()p).stringof == \"const(char****)*\");\n\n    immutable(char*****) q;\n    pragma(msg, typeof(q));\n    static assert(typeof(q).stringof == \"immutable(char*****)\");\n    pragma(msg, typeof(cast()q));\n    static assert(typeof(cast()q).stringof == \"immutable(char****)*\");\n\n    shared(char*****) r;\n    pragma(msg, typeof(r));\n    static assert(typeof(r).stringof == \"shared(char*****)\");\n    pragma(msg, typeof(cast()r));\n    static assert(typeof(cast()r).stringof == \"shared(char****)*\");\n    pragma(msg, typeof(cast(const)r));\n    static assert(typeof(cast(const)r).stringof == \"const(shared(char****)*)\");\n    pragma(msg, typeof(cast(const shared)r));\n    static assert(typeof(cast(const shared)r).stringof == \"shared(const(char*****))\");\n    pragma(msg, typeof(cast(shared)r));\n    static assert(typeof(cast(shared)r).stringof == \"shared(char*****)\");\n    pragma(msg, typeof(cast(immutable)r));\n    static assert(typeof(cast(immutable)r).stringof == \"immutable(char*****)\");\n    pragma(msg, typeof(cast(inout)r));\n    static assert(typeof(cast(inout)r).stringof == \"inout(shared(char****)*)\");\n\n    inout(shared(char**)***) s;\n    pragma(msg, typeof(s));\n    static assert(typeof(s).stringof == \"inout(shared(char**)***)\");\n    pragma(msg, typeof(***s));\n    static assert(typeof(***s).stringof == \"shared(inout(char**))\");\n}\n\n/************************************/\n\nvoid test83(inout(int) _ = 0)\n{\n    static assert( __traits(compiles, typeid(int* function(inout int))));\n    static assert( __traits(compiles, typeid(int* delegate(inout int))));\n    static assert(!__traits(compiles, typeid(inout(int*) function(int))));\n    static assert(!__traits(compiles, typeid(inout(int*) delegate(int))));\n    static assert(!__traits(compiles, typeid(inout(int*) function())));\n    static assert(!__traits(compiles, typeid(inout(int*) delegate())));\n    inout(int*) function(inout(int)) fp;\n    inout(int*) delegate(inout(int)) dg;\n}\n\n/************************************/\n\ninout(char[]) foo84(inout char[] s) { return s; }\n\nvoid test84()\n{\n    char[] m;\n    const(char)[] c;\n    string s;\n    auto r = foo84(s);\n    pragma(msg, typeof(r).stringof);\n    static assert(typeof(r).stringof == \"immutable(string)\");\n\n    pragma(msg, typeof(foo84(c)).stringof);\n    static assert(typeof(foo84(c)).stringof == \"const(char[])\");\n\n    pragma(msg, typeof(foo84(m)).stringof);\n    static assert(typeof(foo84(m)).stringof == \"char[]\");\n}\n\n/************************************/\n\nclass foo85 { }\n\nalias shared foo85 Y85;\n\nvoid test85()\n{\n   pragma(msg, Y85);\n   shared(foo85) x = new Y85;\n}\n\n/************************************/\n\nstruct foo87\n{\n    int bar(T)(T t){ return 1; }\n    int bar(T)(T t) shared { return 2; }\n}\n\nvoid test87()\n{\n    foo87 x;\n    auto i = x.bar(1);\n    assert(i == 1);\n    shared foo87 y;\n    i = y.bar(1);\n    assert(i == 2);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2751\n\n\nvoid test88(immutable(int[3]) a)\n{\n    const(char)[26] abc1 = \"abcdefghijklmnopqrstuvwxyz\";\n    const(char[26]) abc2 = \"abcdefghijklmnopqrstuvwxyz\";\n    immutable(const(char)[26]) abc3 = \"abcdefghijklmnopqrstuvwxyz\";\n    const(immutable(char)[26]) abc4 = \"abcdefghijklmnopqrstuvwxyz\";\n\n    auto abc5 = cast()\"abcdefghijklmnopqrstuvwxyz\";\n\n    pragma(msg, typeof(abc1).stringof);\n    pragma(msg, typeof(abc2).stringof);\n    pragma(msg, typeof(abc3).stringof);\n    pragma(msg, typeof(abc4).stringof);\n    pragma(msg, typeof(abc5).stringof);\n\n    static assert(is(typeof(abc1) == typeof(abc2)));\n    static assert(is(typeof(abc1) == const(char[26])));\n    static assert(is(typeof(abc3) == typeof(abc4)));\n    static assert(is(typeof(abc3) == immutable(char[26])));\n\n    auto b = cast()a;\n    pragma(msg, typeof(b).stringof);\n    static assert(is(typeof(b) == int[3]));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3748\n\n// version = error8;\n// version = error11;\n\nclass C3748\n{\n    private int _x;\n    this(int x) { this._x = x; }\n    @property inout(int)* xptr() inout { return &_x; }\n    @property void x(int newval) { _x = newval; }\n}\n\nstruct S3748\n{\n    int x;\n    immutable int y = 5;\n    const int z = 6;\n    C3748 c;\n\n    inout(int)* getX() inout\n    {\n        static assert(!__traits(compiles, {\n            x = 4;\n        }));\n        return &x;\n    }\n    inout(int)* getCX(C3748 otherc) inout\n    {\n        inout(C3748) c2 = c;    // typeof(c) == inout(C3748)\n        static assert(!__traits(compiles, {\n            inout(C3748) err2 = new C3748(1);\n        }));\n        static assert(!__traits(compiles, {\n            inout(C3748) err3 = otherc;\n        }));\n\n        auto v1 = getLowestXptr(c, otherc);\n        static assert(is(typeof(v1) == const(int)*));\n        auto v2 = getLowestXptr(c, c);\n        static assert(is(typeof(v2) == inout(int)*));\n\n        alias typeof(return) R;\n        static assert(!__traits(compiles, {\n            c.x = 4;\n        }));\n        static assert(!__traits(compiles, {\n            R r = otherc.xptr;\n        }));\n        static assert(!__traits(compiles, {\n            R r = &y;\n        }));\n        static assert(!__traits(compiles, {\n            R r = &z;\n        }));\n\n        return c2.xptr;\n    }\n\n    version(error8)\n        inout(int) err8;    // see fail_compilation/failinout3748a.d\n}\n\ninout(int)* getLowestXptr(inout(C3748) c1, inout(C3748) c2)\n{\n    inout(int)* x1 = c1.xptr;\n    inout(int)* x2 = c2.xptr;\n    if(*x1 <= *x2)\n        return x1;\n    return x2;\n}\n\nref inout(int) getXRef(inout(C3748) c1, inout(C3748) c2)\n{\n    return *getLowestXptr(c1, c2);\n}\n\nvoid test3748()\n{\n    S3748 s;\n    s.c = new C3748(1);\n    const(S3748)* sp = &s;\n    auto s2 = new S3748;\n    s2.x = 3;\n    s2.c = new C3748(2);\n    auto s3 = cast(immutable(S3748)*) s2;\n\n    auto v1 = s.getX;\n    static assert(is(typeof(v1) == int*));\n    auto v2 = sp.getX;\n    static assert(is(typeof(v2) == const(int)*));\n    auto v3 = s3.getX;\n    static assert(is(typeof(v3) == immutable(int)*));\n\n    static assert(!__traits(compiles, {\n        int *err9 = sp.getX;\n    }));\n    static assert(!__traits(compiles, {\n        int *err10 = s3.getX;\n    }));\n    version(error11)\n        inout(int)* err11;  // see fail_compilation/failinout3748b.d\n\n    auto v4 = getLowestXptr(s.c, s3.c);\n    static assert(is(typeof(v4) == const(int)*));\n    auto v5 = getLowestXptr(s.c, s.c);\n    static assert(is(typeof(v5) == int*));\n    auto v6 = getLowestXptr(s3.c, s3.c);\n    static assert(is(typeof(v6) == immutable(int)*));\n\n    getXRef(s.c, s.c) = 3;\n}\n\n/************************************/\n\nvoid test3748a(inout int = 1)\n{\n                 int[]    ma;\n           inout(int[])   wa;\n           const(int[])   ca;\n       immutable(int[])   ia;\n          shared(int[])   sa;\n    shared(inout(int[])) swa;\n    shared(const(int[])) sca;\n\n    static foo1(E)(inout(E[]) a) { return E.init; }\n    static assert( is( typeof(foo1( ma)) == int));\n    static assert( is( typeof(foo1( wa)) == int));\n    static assert( is( typeof(foo1( ca)) == int));\n    static assert( is( typeof(foo1( ia)) == int));\n    static assert( is( typeof(foo1( sa)) == shared int));\n    static assert( is( typeof(foo1(swa)) == shared int));\n    static assert( is( typeof(foo1(sca)) == shared int));\n\n    static foo2(E)(shared inout(E[]) a) { return E.init; }\n    static assert(!is( typeof(foo2( ma)) ));\n    static assert(!is( typeof(foo2( wa)) ));\n    static assert(!is( typeof(foo2( ca)) ));\n    static assert( is( typeof(foo2( ia)) == int));\n    static assert( is( typeof(foo2( sa)) == int));\n    static assert( is( typeof(foo2(swa)) == int));\n    static assert( is( typeof(foo2(sca)) == int));\n}\n\nvoid test3748b(inout int = 1)\n{\n    // Top of the parameter type is non-ref & qualified\n    static        inout(int[])  foo1(       inout(int[])  a);\n    static shared(inout(int[])) bar1(shared(inout(int[])) a);\n\n    // Top of the parameter type is non-ref & un-qualified\n    static        inout(int) [] foo2(       inout(int) [] a);\n    static shared(inout(int))[] bar2(shared(inout(int))[] a);\n\n    // Top of the argument type is qualified\n                 int[]    ma1;\n           inout(int[])   wa1;\n           const(int[])   ca1;\n          shared(int[])   sa1;\n    shared(inout(int[])) swa1;\n    shared(const(int[])) sca1;\n       immutable(int[])   ia1;\n\n    // Top of the argument type is un-qualified\n                 int  []  ma2;\n           inout(int) []  wa2;\n           const(int) []  ca2;\n          shared(int) []  sa2;\n    shared(inout(int))[] swa2;\n    shared(const(int))[] sca2;\n       immutable(int) []  ia2;\n\n    // --> non-ref qualified param VS qualified arg\n    static assert( is( typeof(foo1( ma1)) == typeof( ma1) ));\n    static assert( is( typeof(foo1( wa1)) == typeof( wa1) ));\n    static assert( is( typeof(foo1( ca1)) == typeof( ca1) ));\n    static assert( is( typeof(bar1( sa1)) == typeof( sa1) ));\n    static assert( is( typeof(bar1(swa1)) == typeof(swa1) ));\n    static assert( is( typeof(bar1(sca1)) == typeof(sca1) ));\n    static assert( is( typeof(foo1( ia1)) == typeof( ia1) ));\n\n    // --> non-ref un-qualified param VS qualified arg\n    static assert( is( typeof(foo2( ma1)) == typeof( ma2) ));\n    static assert( is( typeof(foo2( wa1)) == typeof( wa2) ));\n    static assert( is( typeof(foo2( ca1)) == typeof( ca2) ));\n    static assert( is( typeof(bar2( sa1)) == typeof( sa2) ));\n    static assert( is( typeof(bar2(swa1)) == typeof(swa2) ));\n    static assert( is( typeof(bar2(sca1)) == typeof(sca2) ));\n    static assert( is( typeof(foo2( ia1)) == typeof( ia2) ));\n\n    // --> non-ref qualified param VS un-qualified arg\n    static assert( is( typeof(foo1( ma2)) == typeof( ma1) ));\n    static assert( is( typeof(foo1( wa2)) ));\n    static assert( is( typeof(foo1( ca2)) ));\n    static assert( is( typeof(bar1( sa2)) == typeof( sa1) ));\n    static assert( is( typeof(bar1(swa2)) ));\n    static assert( is( typeof(bar1(sca2)) ));\n    static assert( is( typeof(foo1( ia2)) ));\n\n    // --> non-ref un-qualified param VS un-qualified arg\n    static assert( is( typeof(foo2( ma2)) == typeof( ma2) ));\n    static assert( is( typeof(foo2( wa2)) == typeof( wa2) ));\n    static assert( is( typeof(foo2( ca2)) == typeof( ca2) ));\n    static assert( is( typeof(bar2( sa2)) == typeof( sa2) ));\n    static assert( is( typeof(bar2(swa2)) == typeof(swa2) ));\n    static assert( is( typeof(bar2(sca2)) == typeof(sca2) ));\n    static assert( is( typeof(foo2( ia2)) == typeof( ia2) ));\n}\n\nvoid test3748c(inout int = 1)\n{\n    // Top of the parameter type is ref & qualified\n    static        inout(int[])  foo1(ref        inout(int[])  a);\n    static shared(inout(int[])) bar1(ref shared(inout(int[])) a);\n\n    // Top of the parameter type is ref & un-qualified\n    static        inout(int) [] foo2(ref        inout(int) [] a);\n    static shared(inout(int))[] bar2(ref shared(inout(int))[] a);\n\n    // Top of the argument type is qualified\n                 int[]    ma1;\n           inout(int[])   wa1;\n           const(int[])   ca1;\n          shared(int[])   sa1;\n    shared(inout(int[])) swa1;\n    shared(const(int[])) sca1;\n       immutable(int[])   ia1;\n\n    // Top of the argument type is un-qualified\n                 int  []  ma2;\n           inout(int) []  wa2;\n           const(int) []  ca2;\n          shared(int) []  sa2;\n    shared(inout(int))[] swa2;\n    shared(const(int))[] sca2;\n       immutable(int) []  ia2;\n\n    // --> ref qualified param VS qualified arg\n    static assert( is( typeof(foo1( ma1)) == typeof( ma1) ));\n    static assert( is( typeof(foo1( wa1)) == typeof( wa1) ));\n    static assert( is( typeof(foo1( ca1)) == typeof( ca1) ));\n    static assert( is( typeof(bar1( sa1)) == typeof( sa1) ));\n    static assert( is( typeof(bar1(swa1)) == typeof(swa1) ));\n    static assert( is( typeof(bar1(sca1)) == typeof(sca1) ));\n    static assert( is( typeof(foo1( ia1)) == typeof( ia1) ));\n\n    // --> ref un-qualified param VS qualified arg\n    static assert( is( typeof(foo2( ma1)) == typeof( ma2) ));\n    static assert(!is( typeof(foo2( wa1)) ));\n    static assert(!is( typeof(foo2( ca1)) ));\n    static assert(!is( typeof(bar2( sa1)) ));\n    static assert(!is( typeof(bar2(swa1)) ));\n    static assert(!is( typeof(bar2(sca1)) ));\n    static assert(!is( typeof(foo2( ia1)) ));\n\n    // --> ref qualified param VS un-qualified arg\n    static assert( is( typeof(foo1( ma2)) == typeof( ma1) ));\n    static assert(!is( typeof(foo1( wa2)) ));\n    static assert(!is( typeof(foo1( ca2)) ));  // why this is OK? --> [*]\n    static assert(!is( typeof(bar1( sa2)) ));\n    static assert(!is( typeof(bar1(swa2)) ));\n    static assert(!is( typeof(bar1(sca2)) ));\n    static assert(!is( typeof(foo1( ia2)) ));\n\n    // --> ref un-qualified param VS un-qualified arg\n    static assert( is( typeof(foo2( ma2)) == typeof( ma2) ));\n    static assert( is( typeof(foo2( wa2)) == typeof( wa2) ));\n    static assert( is( typeof(foo2( ca2)) == typeof( ca2) ));\n    static assert( is( typeof(bar2( sa2)) == typeof( sa2) ));\n    static assert( is( typeof(bar2(swa2)) == typeof(swa2) ));\n    static assert( is( typeof(bar2(sca2)) == typeof(sca2) ));\n    static assert( is( typeof(foo2( ia2)) == typeof( ia2) ));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4968\n\nvoid test4968()\n{\n    inout(int) f1(inout(int) i) { return i; }\n    int mi;\n    const int ci;\n    immutable int ii;\n    static assert(is(typeof(f1(mi)) == int));\n    static assert(is(typeof(f1(ci)) == const(int)));\n    static assert(is(typeof(f1(ii)) == immutable(int)));\n\n    inout(int)* f2(inout(int)* p) { return p; }\n    int* mp;\n    const(int)* cp;\n    immutable(int)* ip;\n    static assert(is(typeof(f2(mp)) == int*));\n    static assert(is(typeof(f2(cp)) == const(int)*));\n    static assert(is(typeof(f2(ip)) == immutable(int)*));\n\n    inout(int)[] f3(inout(int)[] a) { return a; }\n    int[] ma;\n    const(int)[] ca;\n    immutable(int)[] ia;\n    static assert(is(typeof(f3(ma)) == int[]));\n    static assert(is(typeof(f3(ca)) == const(int)[]));\n    static assert(is(typeof(f3(ia)) == immutable(int)[]));\n\n    inout(int)[1] f4(inout(int)[1] sa) { return sa; }\n    int[1] msa;\n    const int[1] csa;\n    immutable int[1] isa;\n    static assert(is(typeof(f4(msa)) == int[1]));\n    static assert(is(typeof(f4(csa)) == const(int)[1]));\n    static assert(is(typeof(f4(isa)) == immutable(int)[1]));\n\n    inout(int)[string] f5(inout(int)[string] aa) { return aa; }\n    int[string] maa;\n    const(int)[string] caa;\n    immutable(int)[string] iaa;\n    static assert(is(typeof(f5(maa)) == int[string]));\n    static assert(is(typeof(f5(caa)) == const(int)[string]));\n    static assert(is(typeof(f5(iaa)) == immutable(int)[string]));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1961\n\ninout(char)[] strstr(inout(char)[] source, const(char)[] pattern)\n{\n    /*\n     * this would be an error, as const(char)[] is not implicitly castable to\n     * inout(char)[]\n     */\n    // return pattern;\n\n    for(int i = 0; i + pattern.length <= source.length; i++)\n    {\n        inout(char)[] tmp = source[i..pattern.length]; // ok\n        if (tmp == pattern)         // ok, tmp implicitly casts to const(char)[]\n            return source[i..$];    // implicitly casts back to call-site source\n    }\n    return source[$..$];            // to be consistent with strstr.\n}\n\nvoid test1961a()\n{\n    auto a = \"hello\";\n    a = strstr(a, \"llo\");   // cf (constancy factor) == immutable\n    static assert(!__traits(compiles, { char[] b = strstr(a, \"llo\"); }));\n                            // error, cannot cast immutable to mutable\n    char[] b = \"hello\".dup;\n    b = strstr(b, \"llo\");   // cf == mutable (note that \"llo\" doesn't play a role\n                            // because that parameter is not inout)\n    const(char)[] c = strstr(b, \"llo\");\n                            // cf = mutable, ok because mutable\n                            // implicitly casts to const\n    c = strstr(a, \"llo\");   // cf = immutable, ok immutable casts to const\n}\n\ninout(T) min(T)(inout(T) a, inout(T) b)\n{\n    return a < b ? a : b;\n}\n\nvoid test1961b()\n{\n    immutable(char)[] i = \"hello\";\n    const(char)[] c = \"there\";\n    char[] m = \"Walter\".dup;\n\n    static assert(!__traits(compiles, { i = min(i, c); }));\n                            // error, since i and c vary in constancy, the result\n                            // is const, and you cannot implicitly cast const to immutable.\n\n    c = min(i, c);          // ok, cf == const, because not homogeneous\n    c = min(m, c);          // ok, cf == const\n    c = min(m, i);          // ok, cf == const\n    i = min(i, \"blah\");     // ok, cf == immutable, homogeneous\n    static assert(!__traits(compiles, { m = min(m, c); }));\n                            // error, cf == const because not homogeneous.\n    static assert(!__traits(compiles, { m = min(m, \"blah\"); }));\n                            // error, cf == const\n    m = min(m, \"blah\".dup); // ok\n}\n\ninout(T) min2(int i, int j, T)(inout(T) a, inout(T) b)\n{\n    //pragma(msg, \"(\", i, \", \", j, \") = \", T);\n    static assert(is(T == char[]));\n    return a < b ? a : b;\n}\n\ntemplate seq(T...){ alias T seq; }\n\nvoid test1961c()\n{\n    immutable(char[]) iia = \"hello1\";\n    immutable(char)[] ima = \"hello2\";\n    const(char[]) cca = \"there1\";\n    const(char)[] cma = \"there2\";\n    char[] mma = \"Walter\".dup;\n\n    foreach (i, x; seq!(iia, ima, cca, cma, mma))\n    foreach (j, y; seq!(iia, ima, cca, cma, mma))\n    {\n        min2!(i, j)(x, y);\n        //pragma(msg, \"x: \",typeof(x), \", y: \",typeof(y), \" -> \", typeof(min2(x, y)), \" : \", __traits(compiles, min2(x, y)));\n    }\n}\n\n/************************************/\n\ninout(int) function(inout(int))   notinoutfun1() { return null; }\ninout(int) function(inout(int))[] notinoutfun2() { return null; }\ninout(int) delegate(inout(int))   notinoutfun3() { return null; }\ninout(int) delegate(inout(int))[] notinoutfun4() { return null; }\nvoid notinoutfun1(inout(int) function(inout(int))   fn) {}\nvoid notinoutfun2(inout(int) function(inout(int))[] fn) {}\nvoid notinoutfun3(inout(int) delegate(inout(int))   dg) {}\nvoid notinoutfun4(inout(int) delegate(inout(int))[] dg) {}\n\nvoid test88()\n{\n    inout(int) function(inout int) fp;\n    inout(int) delegate(inout int) dg;\n\n    inout(int) function(inout int)*   fp2p;\n    inout(int) function(inout int)[]  fp2a;\n    inout(int) function(inout int)[3] fp2s;\n\n    inout(int) delegate(inout int)*   dg3p;\n    inout(int) delegate(inout int)[]  dg3a;\n    inout(int) delegate(inout int)[3] dg3s;\n\n    int delegate() inout*   dg4p;\n    int delegate() inout[]  dg4a;\n    int delegate() inout[3] dg4s;\n\n    static assert(!__traits(compiles, { inout(int)* p; }));\n    static assert(!__traits(compiles, { inout(int delegate()) dg; }));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4251\n\nvoid test4251a()\n{\n    alias int T;\n\n    static assert(!is( immutable(T)** : const(T)** ));  // NG, tail difference\n    static assert( is( immutable(T)** : const(T**) ));  // OK, tail to const\n\n    static assert( is(           T *** :           T *** ));    // OK, tail is same\n    static assert(!is(           T *** :     const(T)*** ));\n    static assert(!is(           T *** :     const(T*)** ));\n    static assert( is(           T *** :     const(T**)* ));    // OK, tail to const\n    static assert( is(           T *** :     const(T***) ));    // OK, tail to const\n    static assert(!is(           T *** : immutable(T)*** ));\n    static assert(!is(           T *** : immutable(T*)** ));\n    static assert(!is(           T *** : immutable(T**)* ));\n    static assert(!is(           T *** : immutable(T***) ));\n\n    static assert(!is(     const(T)*** :           T *** ));\n    static assert( is(     const(T)*** :     const(T)*** ));    // OK, tail is same\n    static assert(!is(     const(T)*** :     const(T*)** ));\n    static assert( is(     const(T)*** :     const(T**)* ));    // OK, tail to const\n    static assert( is(     const(T)*** :     const(T***) ));    // OK, tail to const\n    static assert(!is(     const(T)*** : immutable(T)*** ));\n    static assert(!is(     const(T)*** : immutable(T*)** ));\n    static assert(!is(     const(T)*** : immutable(T**)* ));\n    static assert(!is(     const(T)*** : immutable(T***) ));\n\n    static assert(!is(     const(T*)** :           T *** ));\n    static assert(!is(     const(T*)** :     const(T)*** ));\n    static assert( is(     const(T*)** :     const(T*)** ));    // OK, tail is same\n    static assert( is(     const(T*)** :     const(T**)* ));    // OK, tail to const\n    static assert( is(     const(T*)** :     const(T***) ));    // OK, tail to const\n    static assert(!is(     const(T*)** : immutable(T)*** ));\n    static assert(!is(     const(T*)** : immutable(T*)** ));\n    static assert(!is(     const(T*)** : immutable(T**)* ));\n    static assert(!is(     const(T*)** : immutable(T***) ));\n\n    static assert(!is(     const(T**)* :           T *** ));\n    static assert(!is(     const(T**)* :     const(T)*** ));\n    static assert(!is(     const(T**)* :     const(T*)** ));\n    static assert( is(     const(T**)* :     const(T**)* ));    // OK, tail is same\n    static assert( is(     const(T**)* :     const(T***) ));    // OK, tail is same\n    static assert(!is(     const(T**)* : immutable(T)*** ));\n    static assert(!is(     const(T**)* : immutable(T*)** ));\n    static assert(!is(     const(T**)* : immutable(T**)* ));\n    static assert(!is(     const(T**)* : immutable(T***) ));\n\n    static assert(!is(     const(T***) :           T *** ));\n    static assert(!is(     const(T***) :     const(T)*** ));\n    static assert(!is(     const(T***) :     const(T*)** ));\n    static assert( is(     const(T***) :     const(T**)* ));    // OK, tail is same\n    static assert( is(     const(T***) :     const(T***) ));    // OK, tail is same\n    static assert(!is(     const(T***) :           T *** ));\n    static assert(!is(     const(T***) : immutable(T)*** ));\n    static assert(!is(     const(T***) : immutable(T*)** ));\n    static assert(!is(     const(T***) : immutable(T**)* ));\n    static assert(!is(     const(T***) : immutable(T***) ));\n\n    static assert(!is( immutable(T)*** :           T *** ));\n    static assert(!is( immutable(T)*** :     const(T)*** ));\n    static assert(!is( immutable(T)*** :     const(T*)** ));\n    static assert( is( immutable(T)*** :     const(T**)* ));    // OK, tail to const\n    static assert( is( immutable(T)*** :     const(T***) ));    // OK, tail to const\n    static assert( is( immutable(T)*** : immutable(T)*** ));    // OK, tail is same\n    static assert(!is( immutable(T)*** : immutable(T*)** ));\n    static assert(!is( immutable(T)*** : immutable(T**)* ));\n    static assert(!is( immutable(T)*** : immutable(T***) ));\n\n    static assert(!is( immutable(T*)** :           T *** ));\n    static assert(!is( immutable(T*)** :     const(T)*** ));\n    static assert(!is( immutable(T*)** :     const(T*)** ));\n    static assert( is( immutable(T*)** :     const(T**)* ));    // OK, tail to const\n    static assert( is( immutable(T*)** :     const(T***) ));    // OK, tail to const\n    static assert(!is( immutable(T*)** : immutable(T)*** ));\n    static assert( is( immutable(T*)** : immutable(T*)** ));    // OK, tail is same\n    static assert(!is( immutable(T*)** : immutable(T**)* ));\n    static assert(!is( immutable(T*)** : immutable(T***) ));\n\n    static assert(!is( immutable(T**)* :           T *** ));\n    static assert(!is( immutable(T**)* :     const(T)*** ));\n    static assert(!is( immutable(T**)* :     const(T*)** ));\n    static assert( is( immutable(T**)* :     const(T**)* ));    // OK, tail to const\n    static assert( is( immutable(T**)* :     const(T***) ));    // OK, tail to const\n    static assert(!is( immutable(T**)* : immutable(T)*** ));\n    static assert(!is( immutable(T**)* : immutable(T*)** ));\n    static assert( is( immutable(T**)* : immutable(T**)* ));    // OK, tail is same\n    static assert( is( immutable(T**)* : immutable(T***) ));    // OK, tail is same\n\n    static assert(!is( immutable(T***) :           T *** ));\n    static assert(!is( immutable(T***) :     const(T)*** ));\n    static assert(!is( immutable(T***) :     const(T*)** ));\n    static assert( is( immutable(T***) :     const(T**)* ));    // OK, tail to const\n    static assert( is( immutable(T***) :     const(T***) ));    // OK, tail to const\n    static assert(!is( immutable(T***) : immutable(T)*** ));\n    static assert(!is( immutable(T***) : immutable(T*)** ));\n    static assert( is( immutable(T***) : immutable(T**)* ));    // OK, tail is same\n    static assert( is( immutable(T***) : immutable(T***) ));    // OK, tail is same\n\n    static assert( is( immutable(int)** : const(immutable(int)*)* ));   // OK, tail to const\n\n    // shared level should be same\n    static assert(!is( shared(T)*** :        const(T***)  ));   // NG, tail to const but shared level is different\n    static assert( is( shared(T***) : shared(const(T***)) ));   // OK, tail to const and shared level is same\n\n    // head qualifier difference is ignored\n    static assert(is( shared(int)* : shared(int*) ));\n    static assert(is( inout (int)* : inout (int*) ));\n\n    //\n    static assert(!is( T** : T*** ));\n    static assert(!is( T[]** : T*** ));\n}\n\nvoid test4251b()\n{\n    class C {}\n    class D : C {}\n\n    static assert(!is( C[]* : const(C)[]* ));\n    static assert( is( C[]* : const(C[])* ));\n\n    // derived class to const(base class) in tail\n    static assert( is( D[]  : const(C)[] ));\n    static assert( is( D[]* : const(C[])* ));\n\n    static assert( is( D*  : const(C)* ));\n    static assert( is( D** : const(C*)* ));\n\n    // derived class to const(base interface) in tail\n    interface I {}\n    class X : I {}\n    static assert(!is( X[] : const(I)[] ));\n\n    // interface to const(base interface) in tail\n    interface J {}\n    interface K : I, J {}\n    static assert( is( K[] : const(I)[] )); // OK, runtime offset is same\n    static assert(!is( K[] : const(J)[] )); // NG, runtime offset is different\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5473\n\nvoid test5473()\n{\n    class C\n    {\n        int b;\n        void f(){}\n        static int x;\n        static void g(){};\n    }\n    struct S\n    {\n        int b;\n        void f(){}\n        static int x;\n        static void g(){};\n    }\n\n    void dummy();\n    alias typeof(dummy) VoidFunc;\n\n    const C c = new C;\n    const S s;\n\n    foreach (a; TypeTuple!(c, s))\n    {\n        alias typeof(a) A;\n\n        static assert(is(typeof(a.b) == const int));    // const(int)\n        static assert(is(typeof(a.f) == VoidFunc));\n        static assert(is(typeof(a.x) == int));\n        static assert(is(typeof(a.g) == VoidFunc));\n\n        static assert(is(typeof((const A).b) == const int));    // int, should be const(int)\n        static assert(is(typeof((const A).f) == VoidFunc));\n        static assert(is(typeof((const A).x) == int));\n        static assert(is(typeof((const A).g) == VoidFunc));\n    }\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5493\n\nvoid test5493()\n{\n    // non template function\n    void pifun(immutable(char)[]* a) {}\n    void rifun(ref immutable(char)[] a) {}\n\n    void pcfun(const(char)[]* a) {}\n    void rcfun(ref const(char)[] a) {}\n\n    immutable char[] buf1 = \"hello\";\n    static assert(!__traits(compiles, pifun(buf1)));\n    static assert(!__traits(compiles, pcfun(buf1)));\n    static assert(!__traits(compiles, rifun(buf1)));\n    static assert(!__traits(compiles, rcfun(buf1)));\n\n    immutable char[5] buf2 = \"hello\";\n    static assert(!__traits(compiles, pifun(buf2)));\n    static assert(!__traits(compiles, pcfun(buf2)));\n    static assert(!__traits(compiles, rifun(buf2)));\n    static assert(!__traits(compiles, rcfun(buf2)));\n\n    const char[] buf3 = \"hello\";\n    static assert(!__traits(compiles, pcfun(buf3)));\n    static assert(!__traits(compiles, rcfun(buf3)));\n\n    const char[5] buf4 = \"hello\";\n    static assert(!__traits(compiles, pcfun(buf4)));\n    static assert(!__traits(compiles, rcfun(buf4)));\n\n    // template function\n    void pmesswith(T)(const(T)[]* ts, const(T) t)\n    {\n        *ts ~= t;\n    }\n    void rmesswith(T)(ref const(T)[] ts, const(T) t)\n    {\n        ts ~= t;\n    }\n    class C\n    {\n        int x;\n        this(int i) immutable { x = i; }\n    }\n    C[] cs;\n    immutable C ci = new immutable(C)(6);\n    assert (ci.x == 6);\n    static assert(!__traits(compiles, pmesswith(&cs,ci)));\n    static assert(!__traits(compiles, rmesswith(cs,ci)));\n    //cs[$-1].x = 14;\n    //assert (ci.x == 14); //whoops.\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5493 + inout\n\nvoid test5493inout()\n{\n    int m;\n    const(int) c;\n    immutable(int) i;\n\n    inout(int) ptrfoo(inout(int)** a, inout(int)* b)\n    {\n        *a = b;\n        return 0;   // dummy\n    }\n    inout(int) reffoo(ref inout(int)* a, inout(int)* b)\n    {\n        a = b;\n        return 0;   // dummy\n    }\n\n    // wild matching: inout == mutable\n    int* pm;\n                                      ptrfoo(&pm, &m);    assert(pm == &m);\n    static assert(!__traits(compiles, ptrfoo(&pm, &c)));\n    static assert(!__traits(compiles, ptrfoo(&pm, &i)));\n                                      reffoo( pm, &m);    assert(pm == &m);\n    static assert(!__traits(compiles, reffoo( pm, &c)));\n    static assert(!__traits(compiles, reffoo( pm, &i)));\n\n    // wild matching: inout == const\n    const(int)* pc;\n    ptrfoo(&pc, &m);    assert(pc == &m);\n    ptrfoo(&pc, &c);    assert(pc == &c);\n    ptrfoo(&pc, &i);    assert(pc == &i);\n    reffoo( pc, &m);    assert(pc == &m);\n    reffoo( pc, &c);    assert(pc == &c);\n    reffoo( pc, &i);    assert(pc == &i);\n\n    // wild matching: inout == immutable\n    immutable(int)* pi;\n    static assert(!__traits(compiles, ptrfoo(&pi, &m)));\n    static assert(!__traits(compiles, ptrfoo(&pi, &c)));\n                                      ptrfoo(&pi, &i);    assert(pi == &i);\n    static assert(!__traits(compiles, reffoo( pi, &m)));\n    static assert(!__traits(compiles, reffoo( pi, &c)));\n                                      reffoo( pi, &i);    assert(pi == &i);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6782\n\nstruct Tuple6782(T...)\n{\n    T field;\n    alias field this;\n}\nauto tuple6782(T...)(T field)\n{\n    return Tuple6782!T(field);\n}\n\nstruct Range6782a\n{\n    int *ptr;\n    @property inout(int)* front() inout { return ptr; }\n    @property bool empty() const { return ptr is null; }\n    void popFront() { ptr = null; }\n}\nstruct Range6782b\n{\n    Tuple6782!(int, int*) e;\n    @property front() inout { return e; }\n    @property empty() const { return e[1] is null; }\n    void popFront() { e[1] = null; }\n}\n\nvoid test6782()\n{\n    int x = 5;\n    auto r1 = Range6782a(&x);\n    foreach(p; r1) {}\n\n    auto r2 = Range6782b(tuple6782(1, &x));\n    foreach(i, p; r2) {}\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6864\n\nint fn6864( const int n) { return 1; }\nint fn6864(shared int n) { return 2; }\ninout(int) fw6864(inout int s) { return 1; }\ninout(int) fw6864(shared inout int s) { return 2; }\n\nvoid test6864()\n{\n    int n;\n    assert(fn6864(n) == 1);\n    assert(fw6864(n) == 1);\n\n    shared int sn;\n    assert(fn6864(sn) == 2);\n    assert(fw6864(sn) == 2);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6865\n\nshared(inout(int)) foo6865(shared(inout(int)) n){ return n; }\nvoid test6865()\n{\n    shared(const(int)) n;\n    static assert(is(typeof(foo6865(n)) == shared(const(int))));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6866\n\nstruct S6866\n{\n    const(char)[] val;\n    alias val this;\n}\ninout(char)[] foo6866(inout(char)[] s) { return s; }\n\nvoid test6866()\n{\n    S6866 s;\n    static assert(is(typeof(foo6866(s)) == const(char)[]));\n    // Assertion failure: 'targ' on line 2029 in file 'mtype.c'\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6867\n\ninout(char)[] test6867(inout(char)[] a)\n{\n   foreach(dchar d; a) // No error if 'dchar' is removed\n   {\n       foreach(c; a) // line 5\n       {\n       }\n   }\n   return [];\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6870\n\nvoid test6870()\n{\n   shared(int) x;\n   static assert(is(typeof(x) == shared(int))); // pass\n   const(typeof(x)) y;\n   const(shared(int)) z;\n   static assert(is(typeof(y) == typeof(z))); // fail!\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6338\n// https://issues.dlang.org/show_bug.cgi?id=6922\n\nalias int T;\n\nstatic assert(is( immutable(       T )  == immutable(T) ));\nstatic assert(is( immutable( const(T))  == immutable(T) )); // 6922\nstatic assert(is( immutable(shared(T))  == immutable(T) ));\nstatic assert(is( immutable( inout(T))  == immutable(T) ));\nstatic assert(is(        immutable(T)   == immutable(T) ));\nstatic assert(is(  const(immutable(T))  == immutable(T) )); // 6922\nstatic assert(is( shared(immutable(T))  == immutable(T) )); // 6338\nstatic assert(is(  inout(immutable(T))  == immutable(T) ));\n\nstatic assert(is( immutable(shared(const(T))) == immutable(T) ));\nstatic assert(is( immutable(const(shared(T))) == immutable(T) ));\nstatic assert(is( shared(immutable(const(T))) == immutable(T) ));\nstatic assert(is( shared(const(immutable(T))) == immutable(T) ));\nstatic assert(is( const(shared(immutable(T))) == immutable(T) ));\nstatic assert(is( const(immutable(shared(T))) == immutable(T) ));\n\nstatic assert(is( immutable(shared(inout(T))) == immutable(T) ));\nstatic assert(is( immutable(inout(shared(T))) == immutable(T) ));\nstatic assert(is( shared(immutable(inout(T))) == immutable(T) ));\nstatic assert(is( shared(inout(immutable(T))) == immutable(T) ));\nstatic assert(is( inout(shared(immutable(T))) == immutable(T) ));\nstatic assert(is( inout(immutable(shared(T))) == immutable(T) ));\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6912\n\nvoid test6912()\n{\n    //                 From                      To\n    static assert( is(                 int []  :                 int []  ));\n    static assert(!is(           inout(int []) :                 int []  ));\n    static assert(!is(                 int []  :           inout(int []) ));\n    static assert( is(           inout(int []) :           inout(int []) ));\n\n    static assert( is(                 int []  :           const(int)[]  ));\n    static assert( is(           inout(int []) :           const(int)[]  ));\n    static assert(!is(                 int []  :     inout(const(int)[]) ));\n    static assert( is(           inout(int []) :     inout(const(int)[]) ));\n\n    static assert( is(           const(int)[]  :           const(int)[]  ));\n    static assert( is(     inout(const(int)[]) :           const(int)[]  ));\n    static assert(!is(           const(int)[]  :     inout(const(int)[]) ));\n    static assert( is(     inout(const(int)[]) :     inout(const(int)[]) ));\n\n    static assert( is(       immutable(int)[]  :           const(int)[]  ));\n    static assert( is( inout(immutable(int)[]) :           const(int)[]  ));\n    static assert( is(       immutable(int)[]  :     inout(const(int)[]) ));\n    static assert( is( inout(immutable(int)[]) :     inout(const(int)[]) ));\n\n    static assert( is(       immutable(int)[]  :       immutable(int)[]  ));\n    static assert( is( inout(immutable(int)[]) :       immutable(int)[]  ));\n    static assert( is(       immutable(int)[]  : inout(immutable(int)[]) ));\n    static assert( is( inout(immutable(int)[]) : inout(immutable(int)[]) ));\n\n    static assert( is(           inout(int)[]  :           inout(int)[]  ));\n    static assert( is(     inout(inout(int)[]) :           inout(int)[]  ));\n    static assert( is(           inout(int)[]  :     inout(inout(int)[]) ));\n    static assert( is(     inout(inout(int)[]) :     inout(inout(int)[]) ));\n\n    static assert( is(           inout(int)[]  :           const(int)[]  ));\n    static assert( is(     inout(inout(int)[]) :           const(int)[]  ));\n    static assert( is(           inout(int)[]  :     inout(const(int)[]) ));\n    static assert( is(     inout(inout(int)[]) :     inout(const(int)[]) ));\n\n    //                 From                         To\n    static assert( is(                 int [int]  :                 int [int]  ));\n    static assert(!is(           inout(int [int]) :                 int [int]  ));\n    static assert(!is(                 int [int]  :           inout(int [int]) ));\n    static assert( is(           inout(int [int]) :           inout(int [int]) ));\n\n    static assert( is(                 int [int]  :           const(int)[int]  ));\n    static assert(!is(           inout(int [int]) :           const(int)[int]  ));\n    static assert(!is(                 int [int]  :     inout(const(int)[int]) ));\n    static assert( is(           inout(int [int]) :     inout(const(int)[int]) ));\n\n    static assert( is(           const(int)[int]  :           const(int)[int]  ));\n    static assert(!is(     inout(const(int)[int]) :           const(int)[int]  ));\n    static assert(!is(           const(int)[int]  :     inout(const(int)[int]) ));\n    static assert( is(     inout(const(int)[int]) :     inout(const(int)[int]) ));\n\n    static assert( is(       immutable(int)[int]  :           const(int)[int]  ));\n    static assert(!is( inout(immutable(int)[int]) :           const(int)[int]  ));\n    static assert(!is(       immutable(int)[int]  :     inout(const(int)[int]) ));\n    static assert( is( inout(immutable(int)[int]) :     inout(const(int)[int]) ));\n\n    static assert( is(       immutable(int)[int]  :       immutable(int)[int]  ));\n    static assert(!is( inout(immutable(int)[int]) :       immutable(int)[int]  ));\n    static assert(!is(       immutable(int)[int]  : inout(immutable(int)[int]) ));\n    static assert( is( inout(immutable(int)[int]) : inout(immutable(int)[int]) ));\n\n    static assert( is(           inout(int)[int]  :           inout(int)[int]  ));\n    static assert(!is(     inout(inout(int)[int]) :           inout(int)[int]  ));\n    static assert(!is(           inout(int)[int]  :     inout(inout(int)[int]) ));\n    static assert( is(     inout(inout(int)[int]) :     inout(inout(int)[int]) ));\n\n    static assert( is(           inout(int)[int]  :           const(int)[int]  ));\n    static assert(!is(     inout(inout(int)[int]) :           const(int)[int]  ));\n    static assert(!is(           inout(int)[int]  :     inout(const(int)[int]) ));\n    static assert( is(     inout(inout(int)[int]) :     inout(const(int)[int]) ));\n\n    // Regression check\n    static assert( is( const(int)[] : const(int[]) ) );\n\n    //                 From                     To\n    static assert( is(                 int *  :                 int *  ));\n    static assert(!is(           inout(int *) :                 int *  ));\n    static assert(!is(                 int *  :           inout(int *) ));\n    static assert( is(           inout(int *) :           inout(int *) ));\n\n    static assert( is(                 int *  :           const(int)*  ));\n    static assert( is(           inout(int *) :           const(int)*  ));\n    static assert(!is(                 int *  :     inout(const(int)*) ));\n    static assert( is(           inout(int *) :     inout(const(int)*) ));\n\n    static assert( is(           const(int)*  :           const(int)*  ));\n    static assert( is(     inout(const(int)*) :           const(int)*  ));\n    static assert(!is(           const(int)*  :     inout(const(int)*) ));\n    static assert( is(     inout(const(int)*) :     inout(const(int)*) ));\n\n    static assert( is(       immutable(int)*  :           const(int)*  ));\n    static assert( is( inout(immutable(int)*) :           const(int)*  ));\n    static assert( is(       immutable(int)*  :     inout(const(int)*) ));\n    static assert( is( inout(immutable(int)*) :     inout(const(int)*) ));\n\n    static assert( is(       immutable(int)*  :       immutable(int)*  ));\n    static assert( is( inout(immutable(int)*) :       immutable(int)*  ));\n    static assert( is(       immutable(int)*  : inout(immutable(int)*) ));\n    static assert( is( inout(immutable(int)*) : inout(immutable(int)*) ));\n\n    static assert( is(           inout(int)*  :           inout(int)*  ));\n    static assert( is(     inout(inout(int)*) :           inout(int)*  ));\n    static assert( is(           inout(int)*  :     inout(inout(int)*) ));\n    static assert( is(     inout(inout(int)*) :     inout(inout(int)*) ));\n\n    static assert( is(           inout(int)*  :           const(int)*  ));\n    static assert( is(     inout(inout(int)*) :           const(int)*  ));\n    static assert( is(           inout(int)*  :     inout(const(int)*) ));\n    static assert( is(     inout(inout(int)*) :     inout(const(int)*) ));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6930\n\nvoid test6930a()\n{\n    inout(const int) f1(inout(const int) i) { return i; }\n              int mi;\n        const int ci;\n    immutable int ii;\n    static assert(is(typeof(f1(mi)) ==     const(int)));\n    static assert(is(typeof(f1(ci)) ==     const(int)));\n    static assert(is(typeof(f1(ii)) == immutable(int)));\n\n    inout(const int)* f2(inout(const int)* p) { return p; }\n              int * mp;\n        const(int)* cp;\n    immutable(int)* ip;\n    static assert(is(typeof(f2(mp)) ==     const(int)*));\n    static assert(is(typeof(f2(cp)) ==     const(int)*));\n    static assert(is(typeof(f2(ip)) == immutable(int)*));\n\n    inout(const int)[] f3(inout(const int)[] a) { return a; }\n              int [] ma;\n        const(int)[] ca;\n    immutable(int)[] ia;\n    static assert(is(typeof(f3(ma)) ==     const(int)[]));\n    static assert(is(typeof(f3(ca)) ==     const(int)[]));\n    static assert(is(typeof(f3(ia)) == immutable(int)[]));\n\n    inout(const int[1]) f4(inout(const int[1]) sa) { return sa; }\n              int[1] msa;\n        const int[1] csa;\n    immutable int[1] isa;\n    static assert(is(typeof(f4(msa)) ==     const(int)[1]));\n    static assert(is(typeof(f4(csa)) ==     const(int)[1]));\n    static assert(is(typeof(f4(isa)) == immutable(int)[1]));\n\n    inout(const int)[string] f5(inout(const int)[string] aa) { return aa; }\n              int [string] maa;\n        const(int)[string] caa;\n    immutable(int)[string] iaa;\n    static assert(is(typeof(f5(maa)) ==     const(int)[string]));\n    static assert(is(typeof(f5(caa)) ==     const(int)[string]));\n    static assert(is(typeof(f5(iaa)) == immutable(int)[string]));\n}\n\ninout(const(int[])) foo6930(inout(int)[] x)\n{\n    bool condition = cast(bool)(x.length / 2);\n    return condition ? x : new immutable(int[])(2);\n}\n\nvoid test6930b(inout int = 0)\n{\n    alias T1 = inout(shared(const(int)));\n    static assert(T1.stringof == \"shared(inout(const(int)))\");\n    static assert(is(T1 == shared) && is(T1 == const) && is(T1 == inout));\n\n    alias T2 = const(shared(inout(int)[]));\n    static assert(T2.stringof == \"shared(const(inout(int)[]))\");\n    static assert(is(T2 == shared) && is(T2 == const) && !is(T2 == inout) && is(typeof(T2.init[0]) == inout));\n\n              int [] ma;\n        const(int)[] ca;\n    immutable(int)[] ia;\n        inout(int)[] wa;\n    static assert(is(typeof(foo6930(ma)) ==       const int[]));\n    static assert(is(typeof(foo6930(ca)) ==       const int[]));\n    static assert(is(typeof(foo6930(ia)) ==   immutable int[]));\n    static assert(is(typeof(foo6930(wa)) == inout const int[]));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11868\n\nvoid f11868(A...)(A) { }\n\nvoid g11868(inout(const(int))[] arr)\n{\n    f11868(arr[0]);\n}\n\nvoid test11868()\n{\n    auto arr = [1,2,3];\n    g11868(arr);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11924\n\ninout(StringType) localize11924(StringType)(inout StringType str, string locale)\n{\n    return str;\n}\n\nstruct S11924\n{\n    static menuItem_1(ARGS...)()\n    {\n        enum itemTitle = ARGS;\n    }\n\n    static content_left_1()\n    {\n        menuItem!(localize11924(\"Home\", \"\"));\n    }\n    alias menuItem = menuItem_1;\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11966\n\ninout(char)[] stripped11966 (inout(char)[] path)\n{\n    return path;\n}\n\nstruct PathParser11966\n{\n    inout(const(char))[] path() inout\n    {\n        return null;\n    }\n\n    inout(const(char))[] pop() inout\n    {\n        return stripped11966(path);\n    }\n}\n\nvoid test11966()\n{\n    auto a = PathParser11966().pop();\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14788\n\nauto make14788(K, V)(inout V[K] aa)\n{\n    static struct Result\n    {\n        V[K] aa;\n        ref front() inout { return aa[1]; }\n    }\n    return inout Result(aa);\n}\n\nvoid test14788()\n{\n    int[int] aa = [1:1];\n    make14788(aa).front();\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12089\n\nvoid foo12089(inout(char[]) a)\n{\n    validate12089(a);\n}\nvoid validate12089(S)(in S str)\n{\n    decodeImpl12089(str);\n}\nvoid decodeImpl12089(S)(auto ref S str)\n{}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12524\n\ninout(int) dup12524(inout(const(int)) val)\n{\n    return val;\n}\n\nvoid test12524(inout(int))\n{\n    inout(const(int)) val;\n\n    auto bug = dup12524(val);\n\n    static assert(is(typeof(bug) == inout(int)));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6941\n\nstatic assert((const(shared(int[])[])).stringof == \"const(shared(int[])[])\");   // fail\nstatic assert((const(shared(int[])[])).stringof != \"const(shared(const(int[]))[])\"); // fail\n\nstatic assert((inout(shared(int[])[])).stringof == \"inout(shared(int[])[])\");   // fail\nstatic assert((inout(shared(int[])[])).stringof != \"inout(shared(inout(int[]))[])\");    // fail\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6872\n\nstatic assert((shared(inout(int)[])).stringof == \"shared(inout(int)[])\");\nstatic assert((shared(inout(const(int)[]))).stringof == \"shared(inout(const(int)[]))\");\nstatic assert((shared(inout(const(int)[])[])).stringof == \"shared(inout(const(int)[])[])\");\nstatic assert((shared(inout(const(immutable(int)[])[])[])).stringof == \"shared(inout(const(immutable(int)[])[])[])\");\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6939\n\nvoid test6939()\n{\n    shared    int* x;\n    immutable int* y;\n    const     int* z;\n    static assert( is(typeof(1?x:y) == shared(const(int))*));  // fail\n    static assert(!is(typeof(1?x:y) == const(int)*));          // fail\n    static assert(!is(typeof(1?x:z)));                         // fail\n\n    shared    int[] a;\n    immutable int[] b;\n    const     int[] c;\n    static assert( is(typeof(1?a:b) == shared(const(int))[])); // pass (ok)\n    static assert(!is(typeof(1?a:b) == const(int)[]));         // pass (ok)\n    static assert(!is(typeof(1?a:c)));                         // fail\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6940\n\nvoid test6940()\n{\n    immutable(int*)*    x;\n    int**               y;\n    static assert(is(typeof(x) : const(int*)*)); // ok\n    static assert(is(typeof(y) : const(int*)*)); // ok\n    static assert(is(typeof(1?x:y) == const(int*)*));\n\n    immutable(int[])[]  a;\n    int[][]             b;\n    static assert(is(typeof(a) : const(int[])[])); // ok\n    static assert(is(typeof(b) : const(int[])[])); // ok\n    static assert(is(typeof(1?a:b) == const(int[])[]));\n\n    immutable(int)**    v;\n    int**               w;\n    static assert(is(typeof(1?v:w) == const(int*)*));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6982\n\nvoid test6982()\n{\n    alias int Bla;\n    immutable(Bla[string]) ifiles = [\"a\":1, \"b\":2, \"c\":3];\n    static assert(!__traits(compiles, { immutable(Bla)[string] files = ifiles; }));  // (1)\n    static assert(!__traits(compiles, { ifiles.remove (\"a\"); }));                    // (2)\n\n          immutable(int)[int]  maa;\n    const(immutable(int)[int]) caa;\n    immutable(      int [int]) iaa;\n    static assert(!__traits(compiles, { maa = iaa; }));\n    static assert(!__traits(compiles, { maa = caa; }));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7038\n\nstatic assert(is(S7038 == const));\nconst struct S7038{ int x; }\nstatic assert(is(S7038 == const));\n\nshared struct S7038b{ int x; }\nstatic assert(is(S7038b == shared));\n\nimmutable struct S7038c{ int x; }\nstatic assert(is(S7038c == immutable));\n\nstatic assert(!is(C7038 == const));\nconst class C7038{ int x; }\nstatic assert(!is(C7038 == const));\n\nvoid test7038()\n{\n    S7038 s;\n    static assert(is(typeof(s) == const));\n    static assert(is(typeof(s.x) == const int));\n\n    C7038 c;\n    static assert(!is(typeof(c) == const));\n    static assert(is(typeof(c.x) == const int));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7105\n\nvoid copy(inout(int)** tgt, inout(int)* src){ *tgt = src; }\n\nvoid test7105()\n{\n    int* pm;\n    int m;\n    copy(&pm, &m);\n    assert(pm == &m);\n\n    const(int)* pc;\n    const(int) c;\n    copy(&pc, &c);\n    assert(pc == &c);\n\n    immutable(int)* pi;\n    immutable(int) i;\n    copy(&pi, &i);\n    assert(pi == &i);\n\n    static assert(!__traits(compiles, copy(&pm, &c)));\n    static assert(!__traits(compiles, copy(&pm, &i)));\n\n    copy(&pc, &m);\n    assert(pc == &m);\n    copy(&pc, &i);\n    assert(pc == &i);\n\n    static assert(!__traits(compiles, copy(&pi, &m)));\n    static assert(!__traits(compiles, copy(&pi, &c)));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7202\n\nvoid test7202()\n{\n    void writeln(string s) @system { printf(\"%.*s\\n\", s.length, s.ptr); }\n    void delegate() @system x = { writeln(\"I am @system\"); };\n    void delegate() @safe y = {  };\n    auto px = &x;\n    auto py = &y;\n    static assert(!__traits(compiles, px = py)); // accepts-invalid\n    *px = x;\n    y(); // \"I am @system\" -> no output, OK\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7554\n\nT outer7554(T)(immutable T function(T) pure foo) pure {\n    pure int inner() {\n        return foo(5);\n    }\n    return inner();\n}\nint sqr7554(int x) pure {\n    return x * x;\n}\nvoid test7554()\n{\n    assert(outer7554(&sqr7554) == 25);\n\n    immutable(int function(int) pure) ifp = &sqr7554;\n}\n\n/************************************/\n\nbool empty(T)(in T[] a)\n{\n    assert(is(T == shared(string)));\n    return false;\n}\n\n\nvoid test7518() {\n    shared string[] stuff;\n    stuff.empty();\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7669\n\nshared(inout U)[n] id7669(U, size_t n)( shared(inout U)[n] );\nvoid test7669()\n{\n    static assert(is(typeof( id7669((shared(int)[3]).init)) == shared(int)[3]));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7757\n\ninout(int)      foo7757a(int x, lazy inout(int)      def) { return def; }\ninout(int)[]    foo7757b(int x, lazy inout(int)[]    def) { return def; }\ninout(int)[int] foo7757c(int x, lazy inout(int)[int] def) { return def; }\n\ninout(T)      bar7757a(T)(T x, lazy inout(T)    def) { return def; }\ninout(T)[]    bar7757b(T)(T x, lazy inout(T)[]  def) { return def; }\ninout(T)[T]   bar7757c(T)(T x, lazy inout(T)[T] def) { return def; }\n\ninout(Object) get7757(lazy inout(Object) defVal) { return null; }\n\nvoid test7757()\n{\n          int       mx1  = foo7757a(1,2);\n    const(int)      cx1  = foo7757a(1,2);\n          int []    ma1  = foo7757b(1,[2]);\n    const(int)[]    ca1  = foo7757b(1,[2]);\n          int [int] maa1 = foo7757c(1,[2:3]);\n    const(int)[int] caa1 = foo7757c(1,[2:3]);\n\n          int       mx2  = bar7757a(1,2);\n    const(int)      cx2  = bar7757a(1,2);\n          int []    ma2  = bar7757b(1,[2]);\n    const(int)[]    ca2  = bar7757b(1,[2]);\n          int [int] maa2 = bar7757c(1,[2:3]);\n    const(int)[int] caa2 = bar7757c(1,[2:3]);\n\n    Object defObj = null;\n    auto resObj = get7757(defObj);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8098\n\nclass Outer8098\n{\n    int i = 6;\n\n    class Inner\n    {\n        int y=0;\n\n        void foo() const\n        {\n            static assert(is(typeof(this.outer) == const(Outer8098)));\n            static assert(is(typeof(i) == const(int)));\n            static assert(!__traits(compiles, ++i));\n        }\n    }\n\n    Inner inner;\n\n    this()\n    {\n        inner = new Inner;\n    }\n}\n\nvoid test8098()\n{\n    const(Outer8098) x = new Outer8098();\n    static assert(is(typeof(x) == const(Outer8098)));\n    static assert(is(typeof(x.inner) == const(Outer8098.Inner)));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8099\n\nvoid test8099()\n{\n    static class Outer\n    {\n        class Inner {}\n    }\n\n    auto m = new Outer;\n    auto c = new const(Outer);\n    auto i = new immutable(Outer);\n\n    auto mm = m.new Inner;            // m -> m  OK\n    auto mc = m.new const(Inner);     // m -> c  OK\n  static assert(!__traits(compiles, {\n    auto mi = m.new immutable(Inner); // m -> i  bad\n  }));\n\n  static assert(!__traits(compiles, {\n    auto cm = c.new Inner;            // c -> m  bad\n  }));\n    auto cc = c.new const(Inner);     // c -> c  OK\n  static assert(!__traits(compiles, {\n    auto ci = c.new immutable(Inner); // c -> i  bad\n  }));\n\n  static assert(!__traits(compiles, {\n    auto im = i.new Inner;            // i -> m  bad\n  }));\n    auto ic = i.new const(Inner);     // i -> c  OK\n    auto ii = i.new immutable(Inner); // i -> i  OK\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8201\n\nvoid test8201()\n{\n    uint[2] msa;\n    immutable uint[2] isa = msa;\n\n    ubyte[] buffer = [0, 1, 2, 3, 4, 5];\n    immutable ubyte[4] iArr = buffer[0 .. 4];\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8212\n\nstruct S8212 { int x; }\n\nshared S8212 s8212;\n\nshared int x8212;\n\nvoid test8212()\n{\n   int y = x8212;\n   S8212 s2 = s8212;\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8366\n\nclass B8366\n{\n    bool foo(in Object o) const { return true; }\n}\n\nclass C8366a : B8366\n{\n    bool foo(in Object o)              { return true; }\n  override\n    bool foo(in Object o) const        { return false; }\n    bool foo(in Object o) immutable    { return true; }\n    bool foo(in Object o) shared       { return true; }\n    bool foo(in Object o) shared const { return true; }\n}\n\nclass C8366b : B8366\n{\n    bool foo(in Object o)              { return false; }\n    alias super.foo foo;\n    bool foo(in Object o) immutable    { return false; }\n    bool foo(in Object o) shared       { return false; }\n    bool foo(in Object o) shared const { return false; }\n}\n\nvoid test8366()\n{\n    {\n              C8366a mca = new C8366a();\n        const C8366a cca = new C8366a();\n              B8366  mb  = mca;\n        const B8366  cb  = cca;\n        assert(mca.foo(null) == true);\n        assert(cca.foo(null) == false);\n        assert(mb .foo(null) == false);\n        assert(cb .foo(null) == false);\n    }\n    {\n              C8366b mcb = new C8366b();\n        const C8366b ccb = new C8366b();\n              B8366  mb  = mcb;\n        const B8366  cb  = ccb;\n        assert(mcb.foo(null) == false);\n        assert(ccb.foo(null) == true);\n        assert(mb .foo(null) == true);\n        assert(cb .foo(null) == true);\n    }\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8408\n\ntemplate hasMutableIndirection8408(T)\n{\n    template Unqual(T)\n    {\n             static if (is(T U == shared(const U))) alias U Unqual;\n        else static if (is(T U ==        const U )) alias U Unqual;\n        else static if (is(T U ==    immutable U )) alias U Unqual;\n        else static if (is(T U ==        inout U )) alias U Unqual;\n        else static if (is(T U ==       shared U )) alias U Unqual;\n        else                                        alias T Unqual;\n    }\n\n    enum hasMutableIndirection8408 = !is(typeof({ Unqual!T t = void; immutable T u = t; }));\n}\nstatic assert(!hasMutableIndirection8408!(int));\nstatic assert(!hasMutableIndirection8408!(int[3]));\nstatic assert( hasMutableIndirection8408!(Object));\n\nauto dup8408(E)(inout(E)[] arr) pure @trusted\n{\n    static if (hasMutableIndirection8408!E)\n    {\n        auto copy = new E[](arr.length);\n        copy[] = cast(E[])arr[];        // assume constant\n        return cast(inout(E)[])copy;    // assume constant\n    }\n    else\n    {\n        auto copy = new E[](arr.length);\n        copy[] = arr[];\n        return copy;\n    }\n}\n\nvoid test8408()\n{\n    void test(E, bool constConv)()\n    {\n                  E[] marr = [E.init, E.init, E.init];\n        immutable E[] iarr = [E.init, E.init, E.init];\n\n                  E[] m2m = marr.dup8408();    assert(m2m == marr);\n        immutable E[] i2i = iarr.dup8408();    assert(i2i == iarr);\n\n      static if (constConv)\n      { // If dup() hss strong purity, implicit conversion is allowed\n        immutable E[] m2i = marr.dup8408();    assert(m2i == marr);\n                  E[] i2m = iarr.dup8408();    assert(i2m == iarr);\n      }\n      else\n      {\n        static assert(!is(typeof({ immutable E[] m2i = marr.dup8408(); })));\n        static assert(!is(typeof({           E[] i2m = iarr.dup8408(); })));\n      }\n    }\n\n    class C {}\n    struct S1 { long n; }\n    struct S2 { int* p; }\n    struct T1 { S1 s; }\n    struct T2 { S2 s; }\n    struct T3 { S1 s1;  S2 s2; }\n\n/*\n    test!(int   , false)();\n    test!(int[3], false)();\n    test!(C     , false)();\n    test!(S1    , false)();\n    test!(S2    , false)();\n    test!(T1    , false)();\n    test!(T2    , false)();\n    test!(T3    , false)();\n*/\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8688\n\nvoid test8688()\n{\n    alias TypeTuple!(int) T;\n    foreach (i; TypeTuple!(0))\n    {\n        alias const(T[i]) X;\n        static assert(!is(X == int));           // fails\n        static assert( is(X == const(int)));    // fails\n    }\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10946 (regression by fixing bug 8688, from 2.061)\n\nenum xlen10946 = 4;\nalias immutable(char)[xlen10946] e3;\nalias immutable(char[xlen10946]) e4; // NG -> OK\nimmutable vlen10946 = 4;\nalias immutable(char)[vlen10946] i3;\nalias immutable(char[vlen10946]) i4; // NG -> OK\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9046\n\nvoid test9046()\n{\n    foreach (T; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong, char, wchar, dchar,\n                           float, double, real, ifloat, idouble, ireal, cfloat, cdouble, creal))\n    foreach (U; TypeTuple!(T, const T, immutable T, shared T, shared const T, inout T, shared inout T))\n    {\n        static assert(is(typeof(U.init) == U));\n    }\n\n    foreach (T; TypeTuple!(int[], const(char)[], immutable(string[]), shared(const(int)[])[],\n                           int[1], const(char)[1], immutable(string[1]), shared(const(int)[1])[],\n                           int[int], const(char)[long], immutable(string[string]), shared(const(int)[double])[]))\n    foreach (U; TypeTuple!(T, const T, immutable T, shared T, shared const T, inout T, shared inout T))\n    {\n        static assert(is(typeof(U.init) == U));\n    }\n\n    int i;\n    enum E { x, y }\n    static struct S {}\n    static class  C {}\n    struct NS { void f(){ i++; } }\n    class  NC { void f(){ i++; } }\n    foreach (T; TypeTuple!(E, S, C, NS, NC))\n    foreach (U; TypeTuple!(T, const T, immutable T, shared T, shared const T, inout T, shared inout T))\n    {\n        static assert(is(typeof(U.init) == U));\n    }\n\n    alias TL = TypeTuple!(int, string, int[int]);\n    foreach (U; TypeTuple!(TL, const TL, immutable TL, shared TL, shared const TL, inout TL, shared inout TL))\n    {\n        static assert(is(typeof(U.init) == U));\n    }\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9090\n\nvoid test9090()\n{\n    void test1(T)(auto ref const T[] val) {}\n\n    string a;\n    test1(a);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9461\n\nvoid test9461()\n{\n    class A {}\n    class B : A {}\n\n    void conv(S, T)(ref S x) { T y = x; }\n\n    // should be NG\n    static assert(!__traits(compiles, conv!(inout(B)[],     inout(A)[])));\n    static assert(!__traits(compiles, conv!(int[inout(B)],  int[inout(A)])));\n    static assert(!__traits(compiles, conv!(inout(B)[int],  inout(A)[int])));\n    static assert(!__traits(compiles, conv!(inout(B)*,      inout(A)*)));\n    static assert(!__traits(compiles, conv!(inout(B)[1],    inout(A)[])));\n\n    // should be OK\n    static assert( __traits(compiles, conv!(inout(B),       inout(A))));\n}\n\n/************************************/\n\nstruct S9209 { int x; }\n\nvoid bar9209(const S9209*) {}\n\nvoid test9209() {\n    const f = new S9209(1);\n    bar9209(f);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10758\n\nstruct X10758\n{\nstatic:\n        inout(int)   screwUpVal(ref inout(int) wx) { return wx; }\n    ref inout(int)   screwUpRef(ref inout(int) wx) { return wx; }\n        inout(int)*  screwUpPtr(ref inout(int) wx) { return &wx; }\n        inout(int)[] screwUpArr(ref inout(int) wx) { return (&wx)[0 .. 1]; }\n}\n\nstruct S10758\n{\n    int x;\n        inout(int)   screwUpVal(ref inout(int) _) inout { return x; }\n    ref inout(int)   screwUpRef(ref inout(int) _) inout { return x; }\n        inout(int)*  screwUpPtr(ref inout(int) _) inout { return &x; }\n        inout(int)[] screwUpArr(ref inout(int) _) inout { return (&x)[0 .. 1]; }\n}\n\nvoid test10758(ref inout(int) wx, inout(int)* wp, inout(int)[] wa, inout(S10758) ws)\n{\n        inout(int)   screwUpVal(inout(int) _) { return wx; }\n    ref inout(int)   screwUpRef(inout(int) _) { return wx; }\n        inout(int)*  screwUpPtr(inout(int) _) { return &wx; }\n        inout(int)[] screwUpArr(inout(int) _) { return (&wx)[0 .. 1]; }\n\n    struct NS\n    {\n            inout(int)   screwUpVal() inout { return wx; }\n        ref inout(int)   screwUpRef() inout { return wx; }\n            inout(int)*  screwUpPtr() inout { return &wx; }\n            inout(int)[] screwUpArr() inout { return (&wx)[0 .. 1]; }\n    }\n\n              int  mx = 1;\n        const(int) cx = 1;\n    immutable(int) ix = 1;\n\n    // nested inout function may return an inout reference of the context,\n    // so substitude inout to mutable or immutable should be disallowed.\n    {\n        // value return does not leak any inout reference, so safe.\n        screwUpVal(mx);\n        screwUpVal(ix);\n        screwUpVal(wx);\n        screwUpVal(cx);\n\n        static assert(!__traits(compiles, screwUpRef(mx)));\n        static assert(!__traits(compiles, screwUpRef(ix)));\n        screwUpRef(wx);\n        screwUpRef(cx);\n\n        static assert(!__traits(compiles, screwUpPtr(mx)));\n        static assert(!__traits(compiles, screwUpPtr(ix)));\n        screwUpPtr(wx);\n        screwUpPtr(cx);\n\n        static assert(!__traits(compiles, screwUpArr(mx)));\n        static assert(!__traits(compiles, screwUpArr(ix)));\n        screwUpArr(cx);\n        screwUpArr(wx);\n    }\n\n    // inout method of the nested struct may return an inout reference of the context,\n    {\n        (          NS()).screwUpVal();\n        (immutable NS()).screwUpVal();\n        (    inout NS()).screwUpVal();\n        (    const NS()).screwUpVal();\n\n        static assert(!__traits(compiles, (          NS()).screwUpRef()));\n        static assert(!__traits(compiles, (immutable NS()).screwUpRef()));\n        (inout NS()).screwUpRef();\n        (const NS()).screwUpRef();\n\n        static assert(!__traits(compiles, (          NS()).screwUpPtr()));\n        static assert(!__traits(compiles, (immutable NS()).screwUpPtr()));\n        (inout NS()).screwUpPtr();\n        (const NS()).screwUpPtr();\n\n        static assert(!__traits(compiles, (          NS()).screwUpArr()));\n        static assert(!__traits(compiles, (immutable NS()).screwUpArr()));\n        (inout NS()).screwUpArr();\n        (const NS()).screwUpArr();\n    }\n\n    // function pointer holds no context, so there's no screw up.\n    {\n        auto fp_screwUpVal = &X10758.screwUpVal;\n        fp_screwUpVal(mx);\n        fp_screwUpVal(ix);\n        fp_screwUpVal(wx);\n        fp_screwUpVal(cx);\n\n        auto fp_screwUpRef = &X10758.screwUpRef;\n        fp_screwUpRef(mx);\n        fp_screwUpRef(ix);\n        fp_screwUpRef(wx);\n        fp_screwUpRef(cx);\n\n        auto fp_screwUpPtr = &X10758.screwUpVal;\n        fp_screwUpPtr(mx);\n        fp_screwUpPtr(ix);\n        fp_screwUpPtr(wx);\n        fp_screwUpPtr(cx);\n\n        auto fp_screwUpArr = &X10758.screwUpVal;\n        fp_screwUpArr(mx);\n        fp_screwUpArr(ix);\n        fp_screwUpArr(wx);\n        fp_screwUpArr(cx);\n    }\n\n    // inout delegate behaves same as nested functions.\n    {\n        auto dg_screwUpVal = &ws.screwUpVal;\n        dg_screwUpVal(mx);\n        dg_screwUpVal(ix);\n        dg_screwUpVal(wx);\n        dg_screwUpVal(cx);\n\n        auto dg_screwUpRef = &ws.screwUpRef;\n        static assert(!__traits(compiles, dg_screwUpRef(mx)));\n        static assert(!__traits(compiles, dg_screwUpRef(ix)));\n        dg_screwUpRef(wx);\n        dg_screwUpRef(cx);\n\n        auto dg_screwUpPtr = &ws.screwUpPtr;\n        static assert(!__traits(compiles, dg_screwUpPtr(mx)));\n        static assert(!__traits(compiles, dg_screwUpPtr(ix)));\n        dg_screwUpPtr(wx);\n        dg_screwUpPtr(cx);\n\n        auto dg_screwUpArr = &ws.screwUpArr;\n        static assert(!__traits(compiles, dg_screwUpArr(mx)));\n        static assert(!__traits(compiles, dg_screwUpArr(ix)));\n        dg_screwUpArr(cx);\n        dg_screwUpArr(wx);\n    }\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10761\n\ninout(int)* function(inout(int)*) fptr10761(inout(int)*)\n{\n    static inout(int)* screwUp(inout(int)* x) { return x; }\n    auto fp = &screwUp;\n    static assert(is(typeof(fp) == inout(int)* function(inout(int)*) pure nothrow @nogc @safe));\n    return fp;\n}\n\ninout(int)* delegate(inout(int)*) nest10761(inout(int)* x)\n{\n    inout(int)* screwUp(inout(int)* _) { return x; }\n    auto dg = &screwUp;\n    static assert(is(typeof(dg) == inout(int)* delegate(inout(int)*) pure nothrow @nogc @safe));\n    return dg;\n}\n\nstruct S10761\n{\n    int x;\n    inout(int)* screwUp() inout { return &x; }\n}\n\ninout(int)* delegate() inout memfn10761(inout(int)* x)\n{\n    auto s = new inout S10761(1);\n    auto dg = &s.screwUp;\n    static assert(is(typeof(dg) == inout(int)* delegate() inout));\n    return dg;\n}\n\nvoid test10761()\n{\n              int  mx = 1;\n        const(int) cx = 1;\n    immutable(int) ix = 1;\n\n    // inout substitution has no effect on function pointer type\n    {\n        auto fp_m = fptr10761(&mx);\n        auto fp_c = fptr10761(&cx);\n        auto fp_i = fptr10761(&ix);\n        alias FP = inout(int)* function(inout(int)*);\n        static assert(is(typeof(fp_m) == FP));\n        static assert(is(typeof(fp_c) == FP));\n        static assert(is(typeof(fp_i) == FP));\n    }\n\n    // inout substitution on delegate type should always\n    // modify inout to const.\n    {\n        auto dg_m = nest10761(&mx);\n        auto dg_c = nest10761(&cx);\n        auto dg_i = nest10761(&ix);\n        alias DG = const(int)* delegate(const(int)*);\n        static assert(is(typeof(dg_m) == DG));\n        static assert(is(typeof(dg_c) == DG));\n        static assert(is(typeof(dg_i) == DG));\n    }\n\n    // same as above\n    {\n        auto dg_m = memfn10761(&mx);\n        auto dg_c = memfn10761(&cx);\n        auto dg_i = memfn10761(&ix);\n        alias DG = const(int)* delegate() const;\n        static assert(is(typeof(dg_m) == DG));\n        static assert(is(typeof(dg_c) == DG));\n        static assert(is(typeof(dg_i) == DG));\n    }\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11226\n\nvoid test11226()\n{\n    typeof(null) m;\n    const typeof(null) c = m;\n    immutable typeof(null) i = m;\n\n    m = m, m = c, m = i;\n    assert(m == c);\n    assert(m == i);\n    assert(c == i);\n    static assert(is(typeof(true ? m : m) ==           typeof(null)));\n    static assert(is(typeof(true ? m : c) ==     const typeof(null)));\n    static assert(is(typeof(true ? m : i) ==     const typeof(null)));\n    static assert(is(typeof(true ? c : m) ==     const typeof(null)));\n    static assert(is(typeof(true ? c : c) ==     const typeof(null)));\n    static assert(is(typeof(true ? c : i) ==     const typeof(null)));\n    static assert(is(typeof(true ? i : m) ==     const typeof(null)));\n    static assert(is(typeof(true ? i : c) ==     const typeof(null)));\n    static assert(is(typeof(true ? i : i) == immutable typeof(null)));\n\n    static assert(typeof(m).stringof ==           \"typeof(null)\" );\n    static assert(typeof(c).stringof ==     \"const(typeof(null))\");\n    static assert(typeof(i).stringof == \"immutable(typeof(null))\");\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11257\n\nstruct R11257\n{\n    union\n    {\n        const(Object) original;\n        Object stripped;\n    }\n}\nvoid test11257()\n{\n    const(R11257) cr;\n    R11257 mr = cr;  // Error: cannot implicitly convert expression (cr) of type const(R) to R\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11215\n\nshared(inout(void)**) f11215(inout int);\n\nstatic assert(is(typeof(f11215(0)) == shared(void**)));\nstatic assert(is(typeof(f11215((const int).init)) == shared(const(void)**)));\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11489\n\nvoid test11489(inout int = 0)\n{\n    static class B {}\n    static class D : B {}\n\n                 D [] dm;\n           const(D)[] dc;\n           inout(D)[] dw;\n          shared(D)[] dsm;\n    shared(const D)[] dsc;\n    shared(inout D)[] dsw;\n       immutable(D)[] di;\n\n    static assert(!__traits(compiles, {              B [] b = dm; }));\n    static assert( __traits(compiles, {        const(B)[] b = dm; }));\n    static assert(!__traits(compiles, {        inout(B)[] b = dm; }));\n    static assert(!__traits(compiles, {       shared(B)[] b = dm; }));\n    static assert(!__traits(compiles, { shared(const B)[] b = dm; }));\n    static assert(!__traits(compiles, { shared(inout B)[] b = dm; }));\n    static assert(!__traits(compiles, {    immutable(B)[] b = dm; }));\n\n    static assert(!__traits(compiles, {              B [] b = dc; }));\n    static assert( __traits(compiles, {        const(B)[] b = dc; }));\n    static assert(!__traits(compiles, {        inout(B)[] b = dc; }));\n    static assert(!__traits(compiles, {       shared(B)[] b = dc; }));\n    static assert(!__traits(compiles, { shared(const B)[] b = dc; }));\n    static assert(!__traits(compiles, { shared(inout B)[] b = dc; }));\n    static assert(!__traits(compiles, {    immutable(B)[] b = dc; }));\n\n    static assert(!__traits(compiles, {              B [] b = dw; }));\n    static assert( __traits(compiles, {        const(B)[] b = dw; }));\n    static assert(!__traits(compiles, {        inout(B)[] b = dw; }));\n    static assert(!__traits(compiles, {       shared(B)[] b = dw; }));\n    static assert(!__traits(compiles, { shared(const B)[] b = dw; }));\n    static assert(!__traits(compiles, { shared(inout B)[] b = dw; }));\n    static assert(!__traits(compiles, {    immutable(B)[] b = dw; }));\n\n    static assert(!__traits(compiles, {              B [] b = dsm; }));\n    static assert(!__traits(compiles, {        const(B)[] b = dsm; }));\n    static assert(!__traits(compiles, {        inout(B)[] b = dsm; }));\n    static assert(!__traits(compiles, {       shared(B)[] b = dsm; }));\n    static assert( __traits(compiles, { shared(const B)[] b = dsm; }));\n    static assert(!__traits(compiles, { shared(inout B)[] b = dsm; }));\n    static assert(!__traits(compiles, {    immutable(B)[] b = dsm; }));\n\n    static assert(!__traits(compiles, {              B [] b = dsc; }));\n    static assert(!__traits(compiles, {        const(B)[] b = dsc; }));\n    static assert(!__traits(compiles, {        inout(B)[] b = dsc; }));\n    static assert(!__traits(compiles, {       shared(B)[] b = dsc; }));\n    static assert( __traits(compiles, { shared(const B)[] b = dsc; }));\n    static assert(!__traits(compiles, { shared(inout B)[] b = dsc; }));\n    static assert(!__traits(compiles, {    immutable(B)[] b = dsc; }));\n\n    static assert(!__traits(compiles, {              B [] b = dsw; }));\n    static assert(!__traits(compiles, {        const(B)[] b = dsw; }));\n    static assert(!__traits(compiles, {        inout(B)[] b = dsw; }));\n    static assert(!__traits(compiles, {       shared(B)[] b = dsw; }));\n    static assert( __traits(compiles, { shared(const B)[] b = dsw; }));\n    static assert(!__traits(compiles, { shared(inout B)[] b = dsw; }));\n    static assert(!__traits(compiles, {    immutable(B)[] b = dsw; }));\n\n    static assert(!__traits(compiles, {              B [] b = di; }));\n    static assert( __traits(compiles, {        const(B)[] b = di; }));\n    static assert(!__traits(compiles, {        inout(B)[] b = di; }));\n    static assert(!__traits(compiles, {       shared(B)[] b = di; }));\n    static assert( __traits(compiles, { shared(const B)[] b = di; }));\n    static assert(!__traits(compiles, { shared(inout B)[] b = di; }));\n    static assert( __traits(compiles, {    immutable(B)[] b = di; }));\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11768\n\nvoid test11768(inout int = 0)\n{\n    const(inout(char)) k1;\n    inout(const(char)) k2;\n    static assert(typeof(k1).stringof == \"inout(const(char))\"); // OK\n    static assert(typeof(k2).stringof == \"inout(const(char))\"); // fails\n    static assert(is(typeof(k1) == typeof(k2)));                // fails\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12403\n\nvoid test12403()\n{\n    void func(K, V)(inout(V[K]) aa)\n    {\n        static assert(is(V == const int));\n        static assert(is(K == int));\n    }\n\n    const(int)[int] m;\n    func(m);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13011\n\nvoid test13011()\n{\n    static size_t hashOf(int delegate() inout val)\n    {\n        return 0;\n    }\n\n    int delegate() inout dg;\n    auto h = hashOf(dg);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13030\n\nvoid va13030(Args...)(const Args args) {}\n\nvoid func13030(int delegate(int n) a)\n{\n    va13030(a);\n}\n\n/************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13802\n// https://issues.dlang.org/show_bug.cgi?id=13803\n\nstatic assert((              string     ).stringof ==               \"string\"       );\nstatic assert((              string[]   ).stringof ==               \"string[]\"     );\nstatic assert((              string[1]  ).stringof ==               \"string[1]\"    );\nstatic assert((              string[int]).stringof ==               \"string[int]\"  );\nstatic assert((       const  string     ).stringof ==         \"const(string)\"      );\nstatic assert((       const  string[]   ).stringof ==         \"const(string[])\"    );\nstatic assert((       const  string[1]  ).stringof ==         \"const(string[1])\"   );\nstatic assert((       const  string[int]).stringof ==         \"const(string[int])\" );\nstatic assert((shared        string     ).stringof ==        \"shared(string)\"      );\nstatic assert((shared        string[]   ).stringof ==        \"shared(string[])\"    );\nstatic assert((shared        string[1]  ).stringof ==        \"shared(string[1])\"   );\nstatic assert((shared        string[int]).stringof ==        \"shared(string[int])\" );\nstatic assert((shared const  string     ).stringof ==  \"shared(const(string))\"     );\nstatic assert((shared const  string[]   ).stringof ==  \"shared(const(string[]))\"   );\nstatic assert((shared const  string[1]  ).stringof ==  \"shared(const(string[1]))\"  );\nstatic assert((shared const  string[int]).stringof ==  \"shared(const(string[int]))\");\nstatic assert((   immutable  string     ).stringof ==     \"immutable(string)\"      );\nstatic assert((   immutable  string[]   ).stringof ==     \"immutable(string[])\"    );\nstatic assert((   immutable  string[1]  ).stringof ==     \"immutable(string[1])\"   );\nstatic assert((   immutable  string[int]).stringof ==     \"immutable(string[int])\" );\n\nstatic assert((             wstring     ).stringof ==              \"wstring\"       );\nstatic assert((             wstring[]   ).stringof ==              \"wstring[]\"     );\nstatic assert((             wstring[1]  ).stringof ==              \"wstring[1]\"    );\nstatic assert((             wstring[int]).stringof ==              \"wstring[int]\"  );\nstatic assert((       const wstring     ).stringof ==        \"const(wstring)\"      );\nstatic assert((       const wstring[]   ).stringof ==        \"const(wstring[])\"    );\nstatic assert((       const wstring[1]  ).stringof ==        \"const(wstring[1])\"   );\nstatic assert((       const wstring[int]).stringof ==        \"const(wstring[int])\" );\nstatic assert((shared       wstring     ).stringof ==       \"shared(wstring)\"      );\nstatic assert((shared       wstring[]   ).stringof ==       \"shared(wstring[])\"    );\nstatic assert((shared       wstring[1]  ).stringof ==       \"shared(wstring[1])\"   );\nstatic assert((shared       wstring[int]).stringof ==       \"shared(wstring[int])\" );\nstatic assert((shared const wstring     ).stringof == \"shared(const(wstring))\"     );\nstatic assert((shared const wstring[]   ).stringof == \"shared(const(wstring[]))\"   );\nstatic assert((shared const wstring[1]  ).stringof == \"shared(const(wstring[1]))\"  );\nstatic assert((shared const wstring[int]).stringof == \"shared(const(wstring[int]))\");\nstatic assert((   immutable wstring     ).stringof ==    \"immutable(wstring)\"      );\nstatic assert((   immutable wstring[]   ).stringof ==    \"immutable(wstring[])\"    );\nstatic assert((   immutable wstring[1]  ).stringof ==    \"immutable(wstring[1])\"   );\nstatic assert((   immutable wstring[int]).stringof ==    \"immutable(wstring[int])\" );\n\nstatic assert((             dstring     ).stringof ==              \"dstring\"       );\nstatic assert((             dstring[]   ).stringof ==              \"dstring[]\"     );\nstatic assert((             dstring[1]  ).stringof ==              \"dstring[1]\"    );\nstatic assert((             dstring[int]).stringof ==              \"dstring[int]\"  );\nstatic assert((       const dstring     ).stringof ==        \"const(dstring)\"      );\nstatic assert((       const dstring[]   ).stringof ==        \"const(dstring[])\"    );\nstatic assert((       const dstring[1]  ).stringof ==        \"const(dstring[1])\"   );\nstatic assert((       const dstring[int]).stringof ==        \"const(dstring[int])\" );\nstatic assert((shared       dstring     ).stringof ==       \"shared(dstring)\"      );\nstatic assert((shared       dstring[]   ).stringof ==       \"shared(dstring[])\"    );\nstatic assert((shared       dstring[1]  ).stringof ==       \"shared(dstring[1])\"   );\nstatic assert((shared       dstring[int]).stringof ==       \"shared(dstring[int])\" );\nstatic assert((shared const dstring     ).stringof == \"shared(const(dstring))\"     );\nstatic assert((shared const dstring[]   ).stringof == \"shared(const(dstring[]))\"   );\nstatic assert((shared const dstring[1]  ).stringof == \"shared(const(dstring[1]))\"  );\nstatic assert((shared const dstring[int]).stringof == \"shared(const(dstring[int]))\");\nstatic assert((   immutable dstring     ).stringof ==    \"immutable(dstring)\"      );\nstatic assert((   immutable dstring[]   ).stringof ==    \"immutable(dstring[])\"    );\nstatic assert((   immutable dstring[1]  ).stringof ==    \"immutable(dstring[1])\"   );\nstatic assert((   immutable dstring[int]).stringof ==    \"immutable(dstring[int])\" );\n\n/************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test56();\n    test57();\n    test58();\n    test59();\n    test60();\n    test61();\n    test62();\n    test63();\n    test64();\n    test65();\n    test66();\n    test68();\n    test69();\n    test70();\n    test72();\n    test73();\n    test74();\n    test75();\n    test76();\n    test77();\n    test78();\n    test79();\n    test80();\n    test81();\n    test82();\n    test83();\n    test84();\n    test85();\n    test87();\n    test4968();\n    test3748();\n    test1961a();\n    test1961b();\n    test1961c();\n    test88();\n    test4251a();\n    test4251b();\n    test5473();\n    test5493();\n    test5493inout();\n    test6782();\n    test6864();\n    test6865();\n    test6866();\n    test6870();\n    test6912();\n    test6930a();\n    test6930b();\n    test11868();\n    test6939();\n    test6940();\n    test6982();\n    test7038();\n    test7105();\n    test7202();\n    test7554();\n    test7518();\n    test7669();\n    test7757();\n    test8098();\n    test8099();\n    test8201();\n    test8212();\n    test8366();\n    test8408();\n    test8688();\n    test9046();\n    test9090();\n    test9461();\n    test9209();\n    test11226();\n    test11768();\n    test13011();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testconstsection.d",
    "content": "\nstring tls_var = \"tls_string\";\n\n__gshared string data_var = \"data_string\";\n\n__gshared string bss_var;\n\nstruct Range\n{\n    const(void)* bot;\n    const(void)* top; // consider inclusive\n\n    void addPtr(const(void)* p)\n    {\n        if (!bot || p < bot)\n            bot = p;\n        if (!top || p > top)\n            top = p;\n    }\n\n    bool intersect(Range other)\n    {\n        return (bot <= other.top && top >= other.bot);\n    }\n}\n\nvoid testStrings()\n{\n    // check that the strings don't overlap with the variables\n    Range tls;\n    Range data;\n    Range bss;\n    Range cdata;\n\n    static string local_tls_var = \"tls_string\";\n    static __gshared string local_data_var = \"data_string\";\n    static __gshared string local_bss_var;\n\n    tls.addPtr(&tls_var);\n    tls.addPtr(&local_tls_var);\n\n    data.addPtr(&data_var);\n    data.addPtr(&local_data_var);\n\n    bss.addPtr(&bss_var);\n    bss.addPtr(&local_bss_var);\n\n    cdata.addPtr(tls_var.ptr);\n    cdata.addPtr(local_tls_var.ptr);\n    cdata.addPtr(data_var.ptr);\n    cdata.addPtr(local_data_var.ptr);\n\n    assert(!cdata.intersect(tls),  \"overlap with tls\");\n    assert(!cdata.intersect(data), \"overlap with data\");\n    assert(!cdata.intersect(bss),  \"overlap with bss\");\n}\n\nvoid main()\n{\n    testStrings();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testcontracts.d",
    "content": "// PERMUTE_ARGS: -inline -g -O\n\nextern(C) int printf(const char*, ...);\n\n/*******************************************/\n\nclass A\n{\n    int x = 7;\n\n    int foo(int i)\n    in\n    {\n        printf(\"A.foo.in %d\\n\", i);\n        assert(i == 2);\n        assert(x == 7);\n        printf(\"A.foo.in pass\\n\");\n    }\n    out (result)\n    {\n        assert(result & 1);\n        assert(x == 7);\n    }\n    do\n    {\n        return i;\n    }\n}\n\nclass B : A\n{\n    override int foo(int i)\n    in\n    {\n        float f;\n        printf(\"B.foo.in %d\\n\", i);\n        assert(i == 4);\n        assert(x == 7);\n        f = f + i;\n    }\n    out (result)\n    {\n        assert(result < 8);\n        assert(x == 7);\n    }\n    do\n    {\n        return i - 1;\n    }\n}\n\nvoid test1()\n{\n    auto b = new B();\n    b.foo(2);\n    b.foo(4);\n}\n\n/*******************************************/\n\nclass A2\n{\n    int x = 7;\n\n    int foo(int i)\n    in\n    {\n        printf(\"A2.foo.in %d\\n\", i);\n        assert(i == 2);\n        assert(x == 7);\n        printf(\"A2.foo.in pass\\n\");\n    }\n    out (result)\n    {\n        assert(result & 1);\n        assert(x == 7);\n    }\n    do\n    {\n        return i;\n    }\n}\n\nclass B2 : A2\n{\n    override int foo(int i)\n    in\n    {\n        float f;\n        printf(\"B2.foo.in %d\\n\", i);\n        assert(i == 4);\n        assert(x == 7);\n        f = f + i;\n    }\n    out (result)\n    {\n        assert(result < 8);\n        assert(x == 7);\n    }\n    do\n    {\n        return i - 1;\n    }\n}\n\nclass C : B2\n{\n    override int foo(int i)\n    in\n    {\n        float f;\n        printf(\"C.foo.in %d\\n\", i);\n        assert(i == 6);\n        assert(x == 7);\n        f = f + i;\n    }\n    out (result)\n    {\n        assert(result == 1 || result == 3 || result == 5);\n        assert(x == 7);\n    }\n    do\n    {\n        return i - 1;\n    }\n}\n\nvoid test2()\n{\n    auto c = new C();\n    c.foo(2);\n    c.foo(4);\n    c.foo(6);\n}\n\n/*******************************************/\n\nvoid fun(int x)\nin {\n    if (x < 0) throw new Exception(\"a\");\n}\ndo {\n}\n\nvoid test3()\n{\n    fun(1);\n}\n\n/*******************************************/\n\ninterface Stack {\n    int pop()\n//   in { printf(\"pop.in\\n\"); }\n    out(result) {\n        printf(\"pop.out\\n\");\n        assert(result == 3);\n    }\n}\n\nclass CC : Stack\n{\n    int pop()\n    //out (result) { printf(\"CC.pop.out\\n\"); } do\n    {\n        printf(\"CC.pop.in\\n\");\n        return 3;\n    }\n}\n\nvoid test4()\n{\n    auto cc = new CC();\n    cc.pop();\n}\n\n/*******************************************/\n\nint mul100(int n)\nout(result)\n{\n    assert(result == 500);\n}\ndo\n{\n    return n * 100;\n}\n\nvoid test5()\n{\n    mul100(5);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3273\n\n// original case\nstruct Bug3273\n{\n    ~this() {}\n    invariant() {}\n}\n\n// simplest case\nref int func3273()\nout(r)\n{\n    // Regression check of https://issues.dlang.org/show_bug.cgi?id=3390\n    static assert(!__traits(compiles, r = 1));\n}\ndo\n{\n    static int dummy;\n    return dummy;\n}\n\nvoid test6()\n{\n    func3273() = 1;\n    assert(func3273() == 1);\n}\n\n/*******************************************/\n\n/+\n// http://d.puremagic.com/issues/show_bug.cgi?id=3722\n\nclass Bug3722A\n{\n    void fun() {}\n}\nclass Bug3722B : Bug3722A\n{\n    override void fun() in { assert(false); } do {}\n}\n\nvoid test6()\n{\n    auto x = new Bug3722B();\n    x.fun();\n}\n+/\n\n/*******************************************/\n\nauto test7foo()\nin{\n    ++cnt;\n}do{\n    ++cnt;\n    return \"str\";\n}\n\nvoid test7()\n{\n    cnt = 0;\n    assert(test7foo() == \"str\");\n    assert(cnt == 2);\n}\n\n/*******************************************/\n\nauto foo8()\nout(r){\n    ++cnt;\n    assert(r == 10);\n}do{\n    ++cnt;\n    return 10;\n}\n\nauto bar8()\nout{\n    ++cnt;\n}do{\n    ++cnt;\n}\n\nvoid test8()\n{\n    cnt = 0;\n    assert(foo8() == 10);\n    assert(cnt == 2);\n\n    cnt = 0;\n    bar8();\n    assert(cnt == 2);\n}\n\n/*******************************************/\n// from fail317\n\nvoid test9()\n{\n  {\n    auto f1 = function() do { }; // fine\n    auto f2 = function() in { } do { }; // fine\n    auto f3 = function() out { } do { }; // error\n    auto f4 = function() in { } out { } do { }; // error\n\n    auto d1 = delegate() do { }; // fine\n    auto d2 = delegate() in { } do { }; // fine\n    auto d3 = delegate() out { } do { }; // error\n    auto d4 = delegate() in { } out { } do { }; // error\n  }\n  {\n    auto f1 = function() body { }; // fine\n    auto f2 = function() in { } body { }; // fine\n    auto f3 = function() out { } body { }; // error\n    auto f4 = function() in { } out { } body { }; // error\n\n    auto d1 = delegate() body { }; // fine\n    auto d2 = delegate() in { } body { }; // fine\n    auto d3 = delegate() out { } body { }; // error\n    auto d4 = delegate() in { } out { } body { }; // error\n  }\n}\n\n/*******************************************/\n\nauto test10() body { return 3; }\nauto test11()() body { return 3; }\n\nauto test12()\n{\n    auto test10() body { return 3; }\n    auto test11()() body { return 3; }\n    return 3;\n}\n\n\nvoid test13()\n{\n    int function() fp13;\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4785\n\nint cnt;\n\nauto foo4785()\nin{\n    int r;\n    ++cnt;\n}\nout(r){\n    assert(r == 10);\n    ++cnt;\n}do{\n    ++cnt;\n    int r = 10;\n    return r;\n}\nvoid test4785()\n{\n    cnt = 0;\n    assert(foo4785() == 10);\n    assert(cnt == 3);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5039\n\nclass C5039 {\n    int x;\n\n    invariant() {\n        assert( x < int.max );\n    }\n\n    auto foo() {\n        return x;\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5204\n\ninterface IFoo5204\n{\n    IFoo5204 bar()\n    out {}\n}\nclass Foo5204 : IFoo5204\n{\n    Foo5204 bar() { return null; }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6417\n\nclass Bug6417\n{\n    void bar()\n    in\n    {\n        int i = 14;\n        assert(i == 14);\n        auto dg = (){\n            //printf(\"in: i = %d\\n\", i);\n            assert(i == 14, \"in contract failure\");\n        };\n        dg();\n    }\n    out\n    {\n        int j = 10;\n        assert(j == 10);\n        auto dg = (){\n            //printf(\"out: j = %d\\n\", j);\n            assert(j == 10, \"out contract failure\");\n        };\n        dg();\n    }\n    do {}\n}\n\nvoid test6417()\n{\n    (new Bug6417).bar();\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6549\n\nclass C6549\n{\n    static int ocount = 0;\n    static int icount = 0;\n\n    abstract int foo(int)\n    in { ++icount; }\n    out { ++ocount; }\n}\n\nclass CD6549 : C6549\n{\n    override int foo(int)\n    in { assert(false); }\n    do { return 10; }\n}\n\nabstract class D6549\n{\n    static int icount = 0;\n    static int ocount = 0;\n\n    int foo(int)\n    in { ++icount; }\n    out { ++ocount; }\n}\n\nclass DD6549 : D6549\n{\n    override int foo(int)\n    in { assert(false); }\n    do { return 10; }\n}\n\nvoid test6549()\n{\n    auto c = new CD6549;\n    c.foo(10);\n    assert(C6549.icount == 1);\n    assert(C6549.ocount == 1);\n\n    auto d = new DD6549;\n    d.foo(10);\n    assert(D6549.icount == 1);\n    assert(D6549.ocount == 1);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7218\n\nvoid test7218()\n{\n  {\n    size_t foo()  in{}  out{}  do{ return 0; } // OK\n    size_t bar()  in{}/*out{}*/do{ return 0; } // OK\n    size_t hoo()/*in{}*/out{}  do{ return 0; } // NG1\n    size_t baz()/*in{}  out{}*/do{ return 0; } // NG2\n  }\n  {\n    size_t goo()  in{}  out{}  body{ return 0; } // OK\n    size_t gar()  in{}/*out{}*/body{ return 0; } // OK\n    size_t gob()/*in{}*/out{}  body{ return 0; } // NG1\n    size_t gaz()/*in{}  out{}*/body{ return 0; } // NG2\n  }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7517\n\nvoid test7517()\n{\n    static string result;\n\n    interface I\n    {\n        static I self;\n\n        void setEnable()\n        in\n        {\n            assert(self is this);\n            result ~= \"I.setEnable.in/\";\n            assert(!enabled);\n        }\n        out\n        {\n            assert(self is this);\n            result ~= \"I.setEnable.out/\";\n            assert( enabled);\n        }\n\n        void setDisable()\n        in\n        {\n            assert(self is this);\n            result ~= \"I.setDisable.in/\";\n            assert( enabled);\n        }\n        out\n        {\n            assert(self is this);\n            result ~= \"I.setDisable.out/\";\n            assert(!enabled);\n        }\n\n        @property bool enabled() const;\n    }\n\n    class C : I\n    {\n        static C self;\n\n        void setEnable()\n        in {}       // supply in-contract to invoke I.setEnable.in\n        do\n        {\n            assert(self is this);\n            result ~= \"C.setEnable/\";\n            _enabled = true;\n        }\n\n        void setDisable()\n        {\n            assert(self is this);\n            result ~= \"C.setDisable/\";\n            _enabled = false;\n        }\n\n        @property bool enabled() const\n        {\n            assert(self is this);\n            result ~= \"C.enabled/\";\n            return _enabled;\n        }\n\n        bool _enabled;\n    }\n\n    C c = C.self = new C;\n    I i = I.self = c;\n\n    result = null;\n    i.setEnable();\n    assert(result == \"I.setEnable.in/C.enabled/C.setEnable/I.setEnable.out/C.enabled/\");\n\n    result = null;\n    i.setDisable();\n    assert(result == \"C.setDisable/I.setDisable.out/C.enabled/\");\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7699\n\nclass P7699\n{\n    void f(int n) in {\n        assert (n);\n    } do { }\n}\nclass D7699 : P7699\n{\n    override void f(int n) in { } do { }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7883\n\n// Segmentation fault\nclass AA7883\n{\n    int foo()\n    out (r1) { }\n    do { return 1; }\n}\n\nclass BA7883 : AA7883\n{\n    override int foo()\n    out (r2) { }\n    do { return 1; }\n}\n\nclass CA7883 : BA7883\n{\n    override int foo()\n    do { return 1; }\n}\n\n// Error: undefined identifier r2, did you mean variable r3?\nclass AB7883\n{\n    int foo()\n    out (r1) { }\n    do { return 1; }\n}\n\nclass BB7883 : AB7883\n{\n    override int foo()\n    out (r2) { }\n    do { return 1; }\n\n}\n\nclass CB7883 : BB7883\n{\n    override int foo()\n    out (r3) { }\n    do { return 1; }\n}\n\n// Error: undefined identifier r3, did you mean variable r4?\nclass AC7883\n{\n    int foo()\n    out (r1) { }\n    do { return 1; }\n}\n\nclass BC7883 : AC7883\n{\n    override int foo()\n    out (r2) { }\n    do { return 1; }\n}\n\nclass CC7883 : BC7883\n{\n    override int foo()\n    out (r3) { }\n    do { return 1; }\n}\n\nclass DC7883 : CC7883\n{\n    override int foo()\n    out (r4) { }\n    do { return 1; }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7892\n\nstruct S7892\n{\n    @disable this();\n    this(int x) {}\n}\n\nS7892 f7892()\nout (result) {}     // case 1\ndo\n{\n    return S7892(1);\n}\n\ninterface I7892\n{\n    S7892 f();\n}\nclass C7892\n{\n    invariant() {}  // case 2\n\n    S7892 f()\n    {\n        return S7892(1);\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8066\n\nstruct CLCommandQueue\n{\n    invariant() {}\n\n//private:\n    int enqueueNativeKernel()\n    {\n        assert(0, \"implement me\");\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8073\n\nstruct Container8073\n{\n    int opApply (int delegate(ref int) dg) { return 0; }\n}\n\nclass Bug8073\n{\n    static int test;\n    int foo()\n    out(r) { test = 7; } do\n    {\n        Container8073 ww;\n        foreach( xxx ; ww ) {  }\n        return 7;\n    }\n\n    ref int bar()\n    out { } do\n    {\n        Container8073 ww;\n        foreach( xxx ; ww ) {  }\n        test = 7;\n        return test;\n    }\n}\nvoid test8073()\n{\n    auto c = new Bug8073();\n    assert(c.foo() == 7);\n    assert(c.test == 7);\n\n    auto p = &c.bar();\n    assert(p == &c.test);\n    assert(*p == 7);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8093\n\nvoid test8093()\n{\n    static int g = 10;\n    static int* p;\n\n    enum fdo = q{\n        static struct S {\n            int opApply(scope int delegate(ref int) dg) { return dg(g); }\n        }\n        S s;\n        foreach (ref e; s)\n            return g;\n        assert(0);\n    };\n\n    ref int foo_ref1() out(r) { assert(&r is &g && r == 10); }\n    do { mixin(fdo); }\n\n    ref int foo_ref2()\n    do { mixin(fdo); }\n\n    { auto q = &foo_ref1(); assert(q is &g && *q == 10); }\n    { auto q = &foo_ref2(); assert(q is &g && *q == 10); }\n\n    int foo_val1() out(r) { assert(&r !is &g && r == 10); }\n    do { mixin(fdo); }\n\n    int foo_val2()\n    do { mixin(fdo); }\n\n    { auto n = foo_val1(); assert(&n !is &g && n == 10); }\n    { auto n = foo_val2(); assert(&n !is &g && n == 10); }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9383\n\nclass A9383\n{\n    static void delegate() dg;\n    static int val;\n\n    void failInBase() { assert(typeid(this) is typeid(A9383)); }\n\n    // in-contract tests\n    void foo1(int i) in  { A9383.val = i; failInBase; } do { }                        // no closure\n    void foo2(int i) in  { A9383.val = i; failInBase; } do { int x; dg = { ++x; }; }  // closure [local]\n    void foo3(int i) in  { A9383.val = i; failInBase; } do {        dg = { ++i; }; }  // closure [parameter]\n    void foo4(int i) in  { A9383.val = i; failInBase; } do { }                        // no closure\n    void foo5(int i) in  { A9383.val = i; failInBase; } do { }                        // no closure\n    void foo6(int i) in  { A9383.val = i; failInBase; } do { int x; dg = { ++x; }; }  // closure [local]\n    void foo7(int i) in  { A9383.val = i; failInBase; } do {        dg = { ++i; }; }  // closure [parameter]\n\n    // out-contract tests\n    void bar1(int i) out { A9383.val = i;             } do { }                        // no closure\n    void bar2(int i) out { A9383.val = i;             } do { int x; dg = { ++x; }; }  // closure [local]\n    void bar3(int i) out { A9383.val = i;             } do {        dg = { ++i; }; }  // closure [parameter]\n    void bar4(int i) out { A9383.val = i;             } do { }                        // no closure\n    void bar5(int i) out { A9383.val = i;             } do { }                        // no closure\n    void bar6(int i) out { A9383.val = i;             } do { int x; dg = { ++x; }; }  // closure [local]\n    void bar7(int i) out { A9383.val = i;             } do {        dg = { ++i; }; }  // closure [parameter]\n}\n\nclass B9383 : A9383\n{\n    static int val;\n\n    // in-contract tests\n    override void foo1(int i) in  { B9383.val = i; } do { }                           // -> no closure\n    override void foo2(int i) in  { B9383.val = i; } do { int x; dg = { ++x; }; }     // -> closure [local] appears\n    override void foo3(int i) in  { B9383.val = i; } do {        dg = { ++i; }; }     // -> closure [parameter]\n    override void foo4(int i) in  { B9383.val = i; } do { int x; dg = { ++x; }; }     // -> closure [local] appears\n    override void foo5(int i) in  { B9383.val = i; } do {        dg = { ++i; }; }     // -> closure [parameter] appears\n    override void foo6(int i) in  { B9383.val = i; } do { }                           // -> closure [local] disappears\n    override void foo7(int i) in  { B9383.val = i; } do { }                           // -> closure [parameter] disappears\n\n    // out-contract tests\n    override void bar1(int i) out { B9383.val = i; } do { }                           // -> no closure\n    override void bar2(int i) out { B9383.val = i; } do { int x; dg = { ++x; }; }     // -> closure [local] appears\n    override void bar3(int i) out { B9383.val = i; } do {        dg = { ++i; }; }     // -> closure [parameter]\n    override void bar4(int i) out { B9383.val = i; } do { int x; dg = { ++x; }; }     // -> closure [local] appears\n    override void bar5(int i) out { B9383.val = i; } do {        dg = { ++i; }; }     // -> closure [parameter] appears\n    override void bar6(int i) out { B9383.val = i; } do { }                           // -> closure [local] disappears\n    override void bar7(int i) out { B9383.val = i; } do { }                           // -> closure [parameter] disappears\n}\n\nvoid test9383()\n{\n    auto a = new A9383();\n    auto b = new B9383();\n\n    // base class in-contract is used from derived class.       // base                   derived\n    b.foo1(101); assert(A9383.val == 101 && B9383.val == 101);  // no closure          -> no closure\n    b.foo2(102); assert(A9383.val == 102 && B9383.val == 102);  // closure [local]     -> closure [local] appears\n    b.foo3(103); assert(A9383.val == 103 && B9383.val == 103);  // closure [parameter] -> closure [parameter]\n    b.foo4(104); assert(A9383.val == 104 && B9383.val == 104);  // no closure          -> closure [local] appears\n    b.foo5(105); assert(A9383.val == 105 && B9383.val == 105);  // no closure          -> closure [parameter] appears\n    b.foo6(106); assert(A9383.val == 106 && B9383.val == 106);  // closure [local]     -> closure [local] disappears\n    b.foo7(107); assert(A9383.val == 107 && B9383.val == 107);  // closure [parameter] -> closure [parameter] disappears\n\n    // base class out-contract is used from derived class.      // base                   derived\n    b.bar1(101); assert(A9383.val == 101 && B9383.val == 101);  // no closure          -> no closure\n    b.bar2(102); assert(A9383.val == 102 && B9383.val == 102);  // closure [local]     -> closure [local] appears\n    b.bar3(103); assert(A9383.val == 103 && B9383.val == 103);  // closure [parameter] -> closure [parameter]\n    b.bar4(104); assert(A9383.val == 104 && B9383.val == 104);  // no closure          -> closure [local] appears\n    b.bar5(105); assert(A9383.val == 105 && B9383.val == 105);  // no closure          -> closure [parameter] appears\n    b.bar6(106); assert(A9383.val == 106 && B9383.val == 106);  // closure [local]     -> closure [local] disappears\n    b.bar7(107); assert(A9383.val == 107 && B9383.val == 107);  // closure [parameter] -> closure [parameter] disappears\n\n    // in-contract in base class.\n    a.foo1(101); assert(A9383.val == 101);      // no closure\n    a.foo2(102); assert(A9383.val == 102);      // closure [local]\n    a.foo3(103); assert(A9383.val == 103);      // closure [parameter]\n\n    // out-contract in base class.\n    a.bar1(101); assert(A9383.val == 101);      // no closure\n    a.bar2(102); assert(A9383.val == 102);      // closure [local]\n    a.bar3(103); assert(A9383.val == 103);      // closure [parameter]\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15524\n// Different from issue 9383 cases, closed variable size is bigger than REGSIZE.\n\nclass A15524\n{\n    static void delegate() dg;\n    static string val;\n\n    void failInBase() { assert(typeid(this) is typeid(A15524)); }\n\n    // in-contract tests\n    void foo1(string s) in  { A15524.val = s; failInBase; } do { }                                // no closure\n    void foo2(string s) in  { A15524.val = s; failInBase; } do { string x; dg = { x = null; }; }  // closure [local]\n    void foo3(string s) in  { A15524.val = s; failInBase; } do {           dg = { s = null; }; }  // closure [parameter]\n    void foo4(string s) in  { A15524.val = s; failInBase; } do { }                                // no closure\n    void foo5(string s) in  { A15524.val = s; failInBase; } do { }                                // no closure\n    void foo6(string s) in  { A15524.val = s; failInBase; } do { string x; dg = { x = null; }; }  // closure [local]\n    void foo7(string s) in  { A15524.val = s; failInBase; } do {           dg = { s = null; }; }  // closure [parameter]\n\n    // out-contract tests\n    void bar1(string s) out { A15524.val = s;             } do { }                                // no closure\n    void bar2(string s) out { A15524.val = s;             } do { string x; dg = { x = null; }; }  // closure [local]\n    void bar3(string s) out { A15524.val = s;             } do {           dg = { s = null; }; }  // closure [parameter]\n    void bar4(string s) out { A15524.val = s;             } do { }                                // no closure\n    void bar5(string s) out { A15524.val = s;             } do { }                                // no closure\n    void bar6(string s) out { A15524.val = s;             } do { string x; dg = { x = null; }; }  // closure [local]\n    void bar7(string s) out { A15524.val = s;             } do {           dg = { s = null; }; }  // closure [parameter]\n}\n\nclass B15524 : A15524\n{\n    static string val;\n\n    // in-contract tests\n    override void foo1(string s) in  { B15524.val = s; } do { }                                   // -> no closure\n    override void foo2(string s) in  { B15524.val = s; } do { string x; dg = { x = null; }; }     // -> closure [local] appears\n    override void foo3(string s) in  { B15524.val = s; } do {           dg = { s = null; }; }     // -> closure [parameter]\n    override void foo4(string s) in  { B15524.val = s; } do { string x; dg = { x = null; }; }     // -> closure [local] appears\n    override void foo5(string s) in  { B15524.val = s; } do {           dg = { s = null; }; }     // -> closure [parameter] appears\n    override void foo6(string s) in  { B15524.val = s; } do { }                                   // -> closure [local] disappears\n    override void foo7(string s) in  { B15524.val = s; } do { }                                   // -> closure [parameter] disappears\n\n    // out-contract tests\n    override void bar1(string s) out { B15524.val = s; } do { }                                   // -> no closure\n    override void bar2(string s) out { B15524.val = s; } do { string x; dg = { x = null; }; }     // -> closure [local] appears\n    override void bar3(string s) out { B15524.val = s; } do {           dg = { s = null; }; }     // -> closure [parameter]\n    override void bar4(string s) out { B15524.val = s; } do { string x; dg = { x = null; }; }     // -> closure [local] appears\n    override void bar5(string s) out { B15524.val = s; } do {           dg = { s = null; }; }     // -> closure [parameter] appears\n    override void bar6(string s) out { B15524.val = s; } do { }                                   // -> closure [local] disappears\n    override void bar7(string s) out { B15524.val = s; } do { }                                   // -> closure [parameter] disappears\n}\n\nvoid test15524()\n{\n    auto a = new A15524();\n    auto b = new B15524();\n\n    // base class in-contract is used from derived class.           // base                   derived\n    b.foo1(\"1\"); assert(A15524.val == \"1\" && B15524.val == \"1\");    // no closure          -> no closure\n    b.foo2(\"2\"); assert(A15524.val == \"2\" && B15524.val == \"2\");    // closure [local]     -> closure [local] appears\n    b.foo3(\"3\"); assert(A15524.val == \"3\" && B15524.val == \"3\");    // closure [parameter] -> closure [parameter]\n    b.foo4(\"4\"); assert(A15524.val == \"4\" && B15524.val == \"4\");    // no closure          -> closure [local] appears\n    b.foo5(\"5\"); assert(A15524.val == \"5\" && B15524.val == \"5\");    // no closure          -> closure [parameter] appears\n    b.foo6(\"6\"); assert(A15524.val == \"6\" && B15524.val == \"6\");    // closure [local]     -> closure [local] disappears\n    b.foo7(\"7\"); assert(A15524.val == \"7\" && B15524.val == \"7\");    // closure [parameter] -> closure [parameter] disappears\n\n    // base class out-contract is used from derived class.          // base                   derived\n    b.bar1(\"1\"); assert(A15524.val == \"1\" && B15524.val == \"1\");    // no closure          -> no closure\n    b.bar2(\"2\"); assert(A15524.val == \"2\" && B15524.val == \"2\");    // closure [local]     -> closure [local] appears\n    b.bar3(\"3\"); assert(A15524.val == \"3\" && B15524.val == \"3\");    // closure [parameter] -> closure [parameter]\n    b.bar4(\"4\"); assert(A15524.val == \"4\" && B15524.val == \"4\");    // no closure          -> closure [local] appears\n    b.bar5(\"5\"); assert(A15524.val == \"5\" && B15524.val == \"5\");    // no closure          -> closure [parameter] appears\n    b.bar6(\"6\"); assert(A15524.val == \"6\" && B15524.val == \"6\");    // closure [local]     -> closure [local] disappears\n    b.bar7(\"7\"); assert(A15524.val == \"7\" && B15524.val == \"7\");    // closure [parameter] -> closure [parameter] disappears\n\n    // in-contract in base class.\n    a.foo1(\"1\"); assert(A15524.val == \"1\");     // no closure\n    a.foo2(\"2\"); assert(A15524.val == \"2\");     // closure [local]\n    a.foo3(\"3\"); assert(A15524.val == \"3\");     // closure [parameter]\n\n    // out-contract in base class.\n    a.bar1(\"1\"); assert(A15524.val == \"1\");     // no closure\n    a.bar2(\"2\"); assert(A15524.val == \"2\");     // closure [local]\n    a.bar3(\"3\"); assert(A15524.val == \"3\");     // closure [parameter]\n}\n\nvoid test15524a()\n{\n    auto t1 = new Test15524a();\n    t1.infos[\"first\"] = 0; //t1.add(\"first\");\n    t1.add(\"second\");\n\n    auto t2 = new Test15524b();\n    t2.add(\"second\");\n}\n\nclass Test15524a\n{\n    int[string] infos;\n\n    void add(string key)\n    in\n    {\n        assert(key !in infos); // @@@ crash here at second\n    }\n    do\n    {\n        auto item = new class\n        {\n            void notCalled()\n            {\n                infos[key] = 0;\n                    // affects, key parameter is made a closure variable.\n            }\n        };\n    }\n}\n\nclass Test15524b\n{\n    void add(string key)\n    in\n    {\n        assert(key == \"second\"); // @@@ fails\n    }\n    do\n    {\n        static void delegate() dg;\n        dg = { auto x = key; };\n            // affects, key parameter is made a closure variable.\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10479\n\nclass B10479\n{\n    B10479 foo()\n    out { } do { return null; }\n}\n\nclass D10479 : B10479\n{\n    override D10479 foo() { return null; }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10596\n\nclass Foo10596\n{\n    auto bar()\n    out (result) { }\n    do { return 0; }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10721\n\nclass Foo10721\n{\n    this()\n    out { }\n    do { }\n\n    ~this()\n    out { }\n    do { }\n}\n\nstruct Bar10721\n{\n    this(this)\n    out { }\n    do { }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10981\n\nclass C10981\n{\n    void foo(int i) pure\n    in { assert(i); }\n    out { assert(i); }\n    do {}\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14779\n\nclass C14779\n{\n    final void foo(int v)\n    in  { assert(v == 0); }\n    out { assert(v == 0); }\n    do\n    {\n    }\n}\n\nvoid test14779()\n{\n    auto c = new C14779();\n    c.foo(0);\n}\n\n/*******************************************/\n\n//******************************************/\n// DIP 1009\n\nint dip1009_1(int x)\n  in  (x > 0, \"x must be positive!\")\n  out (r; r < 0, \"r must be negative!\")\n  in (true, \"cover trailing comma case\",)\n  out (; true, \"cover trailing comma case\",)\n{\n    return -x;\n}\n\nint dip1009_2(int x)\n  in  (x > 0)\n  out (r; r < 0)\n{\n    return -x;\n}\n\nint dip1009_3(int x)\nin  (x > 0,)\nout (r; r < 0,)\ndo\n{\n    return -x;\n}\n\nvoid dip1009_4(int x)\n  in  (x > 0)\n  out (; x > 1)\n{\n    x += 1;\n}\n\ninterface DIP1009_5\n{\n    void dip1009_5(int x)\n      in  (x > 0)\n      out (; x > 1);\n}\n\nint dip1009_6(int x, int y)\n  in  (x > 0)\n  out (r; r > 1)\n  out (; x > 0)\n  in  (y > 0)\n  in  (x + y > 1)\n  out (r; r > 1)\n{\n    return x+y;\n}\n\nint dip1009_7(int x)\n  in (x > 0)\n  in { assert(x > 1); }\n  out { assert(x > 2); }\n  out (; x > 3)\n  out (r; r > 3)\n{\n    x += 2;\n    return x;\n}\n\nclass DIP1009_8\n{\n    private int x = 4;\n    invariant (x > 0, \"x must stay positive\");\n    invariant (x > 1, \"x must be greater than one\",);\n    invariant (x > 2);\n    invariant (x > 3,);\n    void foo(){ x = 5; }\n}\n\n/*******************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n//    test6();\n    test7();\n    test8();\n    test9();\n    test4785();\n    test6417();\n    test6549();\n    test7218();\n    test7517();\n    test8073();\n    test8093();\n    test9383();\n    test15524();\n    test15524a();\n    test14779();\n    dip1009_1(1);\n    dip1009_2(1);\n    dip1009_3(1);\n    dip1009_4(1);\n    dip1009_6(1, 1);\n    dip1009_7(3);\n    new DIP1009_8().foo();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testdefault_after_variadic.d",
    "content": "/*\nPERMUTE_ARGS:\n*/\n\nversion (with_phobos) import std.conv : text;\n\nstruct Tuple(T...)\n{\n    T expand;\n    alias expand this;\n}\n\nauto tuple(T...)(T t)\n{\n    return Tuple!T(t);\n}\n\nvoid fun0(U, T...)(U gold, int b_gold, T a, int b)\n{\n    assert(tuple(a) == gold);\n    assert(b == b_gold);\n}\n\nvoid fun(U, T...)(U gold, T a, int b = 1)\n{\n    assert(tuple(a) == gold);\n    assert(b == 1);\n}\n\nvoid fun2(U, V, T...)(U gold, V gold2, T a, string file = __FILE__, int line = __LINE__)\n{\n    assert(tuple(a) == gold);\n    assert(tuple(file, line) == gold2);\n}\n\nvoid fun3(int[] gold, int[] a...)\n{\n    assert(gold == a);\n}\n\nvoid fun4(T...)(size_t length_gold, int b_gold, T a, int b = 1)\n{\n    assert(T.length == length_gold);\n    assert(b == b_gold);\n}\n\n// Example in changelog\nstring log(T...)(T a, string file = __FILE__, int line = __LINE__)\n{\n    return text(file, \":\", line, \" \", a);\n}\n\nvoid fun_constraint(T...)(T a, string b = \"bar\") if (T.length == 1)\n{\n}\n\n/+\nNOTE: this is disallowed by the parser:\nvoid fun5(int[] gold, int[] a ..., int b = 1)\n{\n    assert(gold==a);\n    assert(b==1);\n}\n+/\n\nvoid main()\n{\n    fun0(tuple(10), 7, 10, 7);\n\n    fun(tuple());\n    fun(tuple(10), 10);\n    fun(tuple(10, 11), 10, 11);\n\n    fun2(tuple(10), tuple(__FILE__, __LINE__), 10);\n\n    fun3([1, 2, 3], 1, 2, 3);\n\n    fun_constraint(1);\n    assert(!__traits(compiles, fun_constraint(1, \"baz\")));\n\n    version (with_phobos)\n        assert(log(10, \"abc\") == text(__FILE__, \":\", __LINE__, \" 10abc\"));\n\n    // IFTI: `b` is always default-set\n    fun4(0, 1);\n    fun4(1, 1, 10);\n    fun4(2, 1, 10, 11);\n\n    // with explicit instantiation, and default-set `b`\n    fun4!int(1, 1, 10);\n    fun4!(int, int)(2, 1, 10, 11);\n\n    // with explicit instantiation, and over-ridden `b`\n    fun4!int(1, 100, 10, 100);\n    fun4!(int, int)(2, 100, 10, 11, 100);\n\n    // fun5([1,2,3], 1,2,3);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testdstress.d",
    "content": "// PERMUTE_ARGS:\n\nmodule run.module_01;\n\nimport core.memory;\nimport core.exception;\nimport core.vararg;\n\nextern(C) void* malloc(size_t size);\n\n/* ================================ */\n\nstruct MyStruct\n{\n        int i;\n}\n\nvoid test1()\n{\n        MyStruct inner()\n        in{\n                assert(1);\n        }out (result){\n                assert(result.i==1);\n        }body{\n                MyStruct s;\n                s.i = 1;\n                return s;\n        }\n        assert(inner.i==1);\n}\n\n/* ================================ */\n\nvoid foo2()\nin{\n        assert(0);\n}\nbody{\n}\n\nvoid test2()\n{\n        try{\n                foo2();\n        }catch(Error ie){\n                return;\n        }\n        assert(0);\n}\n\n/* ================================ */\n\nclass MyClass3\n{\n\n        private int g() const {\n                return 1;\n        }\n\n        invariant()\n        {\n                assert(g()==1);\n        }\n}\n\nvoid test3()\n{\n        MyClass3 c = new MyClass3();\n        assert(c);\n}\n\n/* ================================ */\n\nclass A\n{\n        int x;\n\n        this(){\n            printf(\"A.this()\\n\");\n            x=3;\n        }\n\n        invariant()\n        {\n            printf(\"A.invariant\\n\");\n            assert(x>2);\n        }\n}\n\nclass B : A\n{\n        int y;\n\n        this(){\n            printf(\"B.this()\\n\");\n            y=5;\n        }\n\n        invariant()\n        {\n            printf(\"B.invariant\\n\");\n            assert(y>4);\n        }\n}\n\nvoid test4()\n{\n        B gc = new B();\n}\n\n/* ================================ */\n\nclass A5\n{\n\n        int x;\n\n        this(){\n            printf(\"A5.this()\\n\");\n            x=3;\n        }\n\n        invariant()\n        {\n            printf(\"A5.invariant\\n\");\n            assert(x>2);\n        }\n}\n\nclass C5 : A5 { }\n\nclass B5 : C5\n{\n\n        int y;\n\n        this(){\n            printf(\"B5.this()\\n\");\n            y=5;\n        }\n\n        invariant()\n        {\n            printf(\"B5.invariant\\n\");\n            assert(y>4);\n        }\n}\n\nvoid test5()\n{\n        B5 gc = new B5();\n}\n\n/* ================================ */\n\nvoid test6()\n{\n        long a;\n        assert(a.max == 0x7FFF_FFFF_FFFF_FFFFL);\n        //assert(a.min == 0xFFFF_FFFF_FFFF_FFFFL);\n        assert(a.min == 0x8000_0000_0000_0000L);\n        assert(a.init == 0);\n        assert(a.sizeof == 8);\n}\n\n/* ================================ */\n\nint i;\n\nvoid test7()\n{\n        assert(run.module_01.i==0);\n        run.module_01.i++;\n        assert(run.module_01.i==1);\n}\n\n/* ================================ */\n\ntemplate mix(){\n        int x;\n}\n\nmixin .mix;\n\nvoid test8()\n{\n}\n\n/* ================================ */\n\nstruct A9\n{\n    B9 next;\n}\n\nalias A9* B9;\n\nvoid test9()\n{\n    B9 n = new A9;\n}\n\n/* ================================ */\n\n\nstruct TestStruct\n{\n        void add(...)\n        {\n                TestStruct other = va_arg!TestStruct(_argptr);\n                foreach(int value; other)\n                {\n                        foo();\n                }\n        }\n\n        void foo()\n        {\n                assert(left is null);\n                bar();\n        }\n\n        void bar()\n        {\n                assert(left is null);\n        }\n\n        int opApply(int delegate(ref int val) dg)\n        {\n                return 0;\n        }\n\n        void* left;\n}\n\nvoid test10()\n{\n        TestStruct t;\n        t.foo();\n}\n\n/* ================================ */\n\nint status11;\n\nvoid check(int x){\n        status11++;\n}\n\nclass MyClass11{\n        void test(){\n                assert(status11==0);\n                .check(0);\n                assert(status11==1);\n                check();\n                assert(status11==3);\n        }\n\n        void check(){\n                assert(status11==1);\n                status11+=2;\n        }\n}\n\nvoid test11()\n{\n        MyClass11 c = new MyClass11();\n        assert(status11==0);\n        c.test();\n        assert(status11==3);\n        check(0);\n        assert(status11==4);\n}\n\n/* ================================ */\n\nint status12;\n\nclass C12{\n        void foo(){\n                status12='N';\n        }\n\n        static void foo(int x){\n                status12=x;\n        }\n}\n\nvoid test12()\n{\n        C12 m = new C12();\n\n        C12.foo('S');\n        assert(status12=='S');\n\n        m.foo('s');\n        assert(status12=='s');\n\n        m.foo();\n        assert(status12=='N');\n}\n\n/* ================================ */\n\nvoid test13()\n{\n        wstring a=\"abc\";\n        wstring b=\"efg\";\n        wstring c=a~\"d\"~b;\n\n        assert(c == \"abcdefg\");\n}\n\n/* ================================ */\n\nvoid test14()\n{\n        dstring a=\"abc\";\n        dstring b=\"efg\";\n        dstring c=a~\"d\"~b;\n\n        assert(c == \"abcdefg\");\n}\n\n/* ================================ */\n\nclass Parent15\n{\n        void test(int i){\n        }\n\n        int opCast(){\n                return 0;\n        }\n}\n\nclass Child15 : Parent15\n{\n}\n\nvoid test15()\n{\n        (new Child15()).test(2);\n}\n\n/* ================================ */\n\nclass Parent16\n{\n        void test(int i){\n        }\n}\n\nclass Child16 : Parent16\n{\n        int opCast(){\n                return 0;\n        }\n}\n\nvoid test16()\n{\n        (new Child16()).test=2;\n}\n\n/* ================================ */\n\nvoid foo17(){\n        class MyClass{\n                static int x;\n        }\n}\n\nvoid foo17(int i){\n        class MyClass{\n                static int x;\n        }\n}\n\nvoid test17()\n{\n}\n\n/* ================================ */\n\nvoid foo18(){\n        struct MyStruct{\n                static int x;\n        }\n}\n\nvoid foo18(int i){\n        struct MyStruct{\n                static int x;\n        }\n}\n\nvoid test18()\n{\n}\n\n/* ================================ */\n\nclass Class19 : Throwable\n{\n    this() { super(\"\"); }\n}\n\nalias Class19 Alias19;\n\nvoid test19()\n{\n        try{\n                throw new Alias19();\n        }catch(Throwable){\n                return;\n        }\n        assert(0);\n}\n\n/* ================================ */\n\npublic static const uint U20 = (cast(uint)(-1)) >>> 2;\n\nalias uint myType20;\npublic static const myType20 T20 = (cast(myType20)(-1)) >>> 2;\n\nvoid test20()\n{\n        assert(U20 == 0x3FFFFFFF);\n        assert(T20 == 0x3FFFFFFF);\n}\n\n/* ================================ */\n\nclass C21(T1){\n        alias T1 type1;\n}\n\nclass C21(T1, T2){\n        alias T1 type1;\n        alias .C21!(T2) type2;\n}\n\nvoid test21()\n{\n        alias C21!(int,long) CT;\n        CT c = new CT();\n}\n\n/* ================================ */\n\nscope class AutoClass{\n}\n\nvoid test22()\n{\n        scope AutoClass ac = new AutoClass();\n\n        with(ac){\n        }\n}\n\n/* ================================ */\n\nint status23;\n\nscope class C23{\n        ~this(){\n                assert(status23==0);\n                status23--;\n                throw new Exception(\"error msg\");\n        }\n}\n\nvoid foo23(){\n        assert(status23==0);\n        scope C23 ac = new C23();\n}\n\nvoid test23()\n{\n        try{\n                foo23();\n        }catch(Throwable){\n        }\n        assert(status23==-1);\n}\n\n/* ================================ */\n\nint status24;\n\nscope class C24{\n        this(){\n                assert(status24==0);\n                status24+=2;\n        }\n        ~this(){\n                assert(status24==2);\n                status24--;\n                throw new Exception(\"error msg\");\n        }\n}\n\nvoid check24(){\n        scope C24 ac = new C24();\n        throw new Exception(\"check error\");\n}\n\nvoid test24()\n{\n        assert(status24==0);\n        try{\n                check24();\n        }catch(Throwable){\n                assert(status24==1);\n                status24-=5;\n        }\n        assert(status24==-4);\n}\n\n/* ================================ */\n\nstruct S25{\n        S25 opSub(int i) { S25 s; return s; }\n}\n\nstruct GeomObject{\n        S25     mesh;\n        int     xlate;\n}\n\n\nvoid extractTriangles(GeomObject g)\n{\n    void foobar()\n    {\n        g.mesh - g.xlate;\n        //g.mesh.opSub(g.xlate);\n    }\n\n    foobar();\n}\n\nvoid test25()\n{\n}\n\n/* ================================ */\n\nstruct S26{\n        int i;\n\n        void display(){\n                assert(i==10);\n        }\n\n        void someFunc(){\n                // We never call this function\n                void bug(S26[] array){\n                        array[0].i = i+1;\n                }\n\n                assert(i==10);\n                display();\n                assert(i==10);\n        }\n}\n\nvoid test26()\n{\n        S26 m;\n        m.i = 10;\n        assert(m.i==10);\n        m.someFunc();\n        assert(m.i==10);\n}\n\n/* ================================ */\n\ntemplate foo27(T:T[],alias S) {\n        string foo(T[] a, T[] b) {\n                return a ~ S ~ b;\n        }\n}\n\nstring comma = \", \";\nalias foo27!(string,comma).foo catComma;\n\nvoid test27()\n{\n        string a = \"Heath\";\n        string b = \"Regan\";\n\n        assert(\"Heath, Regan\"==catComma(a,b));\n}\n\n/* ================================ */\n\nvoid test28()\n{\n        assert((new S28!()).i==int.sizeof);\n}\n\nstruct S28(){\n        int i=func28(0).sizeof;\n}\n\nint func28(...){\n        return 0;\n}\n\n/* ================================ */\n\nvoid test29()\n{\n        uint u;\n        u = 1 << 31;\n        assert( u == 0b1000_0000__0000_0000__0000_0000__0000_0000u);\n}\n\n/* ================================ */\n// Test for FinalizeError - it will be thrown if an Exception is thrown\n// during the class object finalization.\n\nint status30;\n\nclass C30\n{\n    this()\n    {\n        status30++;\n    }\n\n    ~this()\n    {\n        status30--;\n        throw new Exception(\"E2\");\n    }\n}\n\nvoid test30()\n{\n    try\n    {\n        //scope C30 m = new C30();\n        // It will insert one more `delete m` for the scope destruction, and it will be\n        // called during stack unwinding.\n        // Instead use bare memory chunk on stack to construct dummy class instance.\n        void[__traits(classInstanceSize, C30)] payload =\n            typeid(C30).initializer[];\n        C30 m = cast(C30)payload.ptr;\n        m.__ctor();\n\n        assert(status30 == 1);\n\n        delete m;   // _d_callfinalizer\n    }\n    catch (Error e) // FinalizeError\n    {\n        assert(status30 == 0);\n        status30--;\n    }\n\n    assert(status30 == -1);\n}\n\n/* ================================ */\n\nvoid test31()\n{\n        string str = x\"F0 9D 83 93\"; // utf-8 for U+1D0D3\n\n        int count=0;\n        dchar tmp;\n        foreach(dchar value ; str){\n                tmp=value;\n                count++;\n        }\n        assert(count==1);\n        assert(tmp==0x01D0D3);\n}\n\n/* ================================ */\n\nimport std.stdio;\n\nunion MyUnion32\n{\n        int i;\n        byte b;\n}\n\nvoid test32()\n{\n        TypeInfo ti = typeid(MyUnion32*);\n        assert(!(ti is null));\n        writefln(\"%s %d %d\", ti.toString(), ti.tsize, (MyUnion32*).sizeof);\n        assert(ti.tsize==(MyUnion32*).sizeof);\n        assert(ti.toString()==\"run.module_01.MyUnion32*\");\n}\n\n/* ================================ */\n\nvoid test33()\n{\n        creal a=1.3L+9.7Li;\n        assert(a.re == 1.3L);\n        assert(a.im == 9.7L);\n}\n\n/* ================================ */\n\nvoid test34()\n{\n        creal c = 2.7L + 0i;\n        assert(c.re==2.7L);\n        assert(c.im==0.0L);\n}\n\n/* ================================ */\n\nvoid test35()\n{\n        try{\n                onOutOfMemoryError();\n        }catch(OutOfMemoryError e){\n                return;\n        }\n        assert(0);\n}\n\n/* ================================ */\n\nvoid test36()\n{\n        try{\n                onOutOfMemoryError();\n        }catch(OutOfMemoryError e){\n                return;\n        }\n        assert(0);\n}\n\n/* ================================ */\n\nstruct S37{\n        int a;\n}\n\nconst int i37 = 15;\n\nconst S37 s1 = { i37+1 };\nconst S37 s2 = s1;\n\nvoid test37()\n{\n        assert(s1.a == 16);\n        assert(s2.a == 16);\n}\n\n/* ================================ */\n\nclass Foo38\n{\n        enum MyEnum{\n                VALUE_A=1,\n        }\n}\n\nclass Bar38\n{\n        enum MyEnum{\n                VALUE_B=2,\n        }\n}\n\nvoid test38()\n{\n        assert(Foo38.MyEnum.VALUE_A==1);\n        assert(Bar38.MyEnum.VALUE_B==2);\n}\n\n/* ================================ */\n\nvoid test39()\n{\n        bool[] bArray;\n        int[] iArray;\n\n        bArray[]=false;\n\n        foreach(int c; iArray){\n                assert(0);\n        }\n}\n\n/* ================================ */\n\nbool checked40;\n\nclass Parent40{\n        int x;\n\n        void test(){\n        }\n\n        invariant()\n        {\n                assert(!checked40);\n                checked40=true;\n                // even number\n                assert((x&1u)==0);\n        }\n}\n\nclass Child40 : Parent40{\n}\n\nclass GrandChild40 : Child40{\n        this(){\n                x=5;\n        }\n}\n\nvoid test40()\n{\n        try{\n                assert(!checked40);\n                GrandChild40 gc = new GrandChild40();\n        }catch(Throwable){\n                assert(checked40);\n                return;\n        }\n        assert(0);\n}\n\n/* ================================ */\n\nint counter41;\n\nclass C41{\n        this(){\n                printf(\"this: counter41 = %d\\n\", counter41);\n                assert(counter41==1);\n                counter41+=2;\n        }\n\n        new(size_t size){\n                printf(\"new: size = %d\\n\", size);\n                assert(counter41==0);\n                counter41++;\n                return malloc(size);\n        }\n}\n\nvoid test41()\n{\n        C41 c;\n        assert(counter41==0);\n        c = new C41();\n        assert(counter41==3);\n}\n\n/* ================================ */\n\nstruct S42{\n        int y;\n        void* x;\n}\n\nvoid test42()\n{\n        size_t t;\n        t = S42.y.offsetof;\n        assert(t == 0);\n        t = S42.x.offsetof;\n        assert((t % (void*).sizeof) == 0);\n}\n\n/* ================================ */\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testdt.d",
    "content": "// PERMUTE_ARGS:\n\n/******************************************/\n\nstatic int[100][100] bigarray;\n\nvoid test1()\n{\n  for (int i = 0; i < 100; i += 1)\n  {\n    for (int j = 0; j < 100; j += 1)\n    {\n      //printf(\"Array %i %i\\n\", i, j);\n      bigarray[i][j] = 0;\n    }\n  }\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10629\n\nclass Foo10629 {}\n\nstruct Bar10629\n{\n    void[__traits(classInstanceSize, Foo10629)] x;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11233\n\nstruct S11233\n{\n    uint[0x100000] arr;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11672\n\nvoid test11672()\n{\n    struct V { float f; }\n    struct S\n    {\n        V[3] v = V(1);\n    }\n\n    S s;\n    assert(s.v == [V(1), V(1), V(1)]); /* was [V(1), V(nan), V(nan)] */\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12509\n\nstruct A12509\n{\n    int member;\n}\nstruct B12509\n{\n    A12509[0x10000] array;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13505\n\nclass C13505 { void[10] x; }\nstruct S13505 { void[10] x; }\n\nvoid test13505()\n{\n    auto c = new C13505();\n    auto s = S13505();\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14699\n\nstruct S14699a { ubyte[0][10] values; }\nstruct S14699b { S14699a tbl; }\n// +/\n\nubyte[0][1] sa14699;\n\nvoid test14699()\n{\n    //auto p = &sa14699;  // Cannot work in Win32 (OMF)\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14805\n\nstruct S14805\n{\n    ushort one;\n}\nauto a14805 = new S14805[513*513];\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15664\n\nstruct Data15664A\n{\n    int[2] a;\n    int[2][2] b;\n    int c;\n}\n\n             Data15664A d15664a1 = {[1, 2], [[3, 4], [5, 6]], 7};   // OK\n       const Data15664A d15664a2 = {[1, 2], [[3, 4], [5, 6]], 7};   // OK <- NG\nshared       Data15664A d15664a3 = {[1, 2], [[3, 4], [5, 6]], 7};   // OK <- NG\nshared const Data15664A d15664a4 = {[1, 2], [[3, 4], [5, 6]], 7};   // OK <- NG\n   immutable Data15664A d15664a5 = {[1, 2], [[3, 4], [5, 6]], 7};   // OK <- NG\n\nstruct Data15664B\n{\n    int[2] a;\n    const int[2][2] b;\n    int c;\n}\n\n             Data15664B d15664b1 = {[1, 2], [[3, 4], [5, 6]], 7};   // OK\n       const Data15664B d15664b2 = {[1, 2], [[3, 4], [5, 6]], 7};   // OK\nshared       Data15664B d15664b3 = {[1, 2], [[3, 4], [5, 6]], 7};   // OK <- NG\nshared const Data15664B d15664b4 = {[1, 2], [[3, 4], [5, 6]], 7};   // OK <- NG\n   immutable Data15664B d15664b5 = {[1, 2], [[3, 4], [5, 6]], 7};   // OK <- NG\n\nvoid test15664()\n{\n    assert(d15664a1.a == [1, 2]);\n    assert(d15664a2.a == [1, 2]);\n    assert(d15664a3.a == cast(shared)[1, 2]);\n    assert(d15664a4.a == cast(shared)[1, 2]);\n    assert(d15664a5.a == [1, 2]);\n    assert(d15664a1.b == [[3, 4], [5, 6]]);\n    assert(d15664a2.b == [[3, 4], [5, 6]]);\n    assert(d15664a3.b == cast(shared)[[3, 4], [5, 6]]);\n    assert(d15664a4.b == cast(shared)[[3, 4], [5, 6]]);\n    assert(d15664a5.b == [[3, 4], [5, 6]]);\n    assert(d15664a1.c == 7);    // OK\n    assert(d15664a2.c == 7);    // OK <- BG\n    assert(d15664a3.c == 7);    // OK <- NG\n    assert(d15664a4.c == 7);    // OK <- NG\n    assert(d15664a5.c == 7);    // OK <- NG\n\n    assert(d15664b1.a == [1, 2]);\n    assert(d15664b2.a == [1, 2]);\n    assert(d15664b3.a == cast(shared)[1, 2]);\n    assert(d15664b4.a == cast(shared)[1, 2]);\n    assert(d15664b5.a == [1, 2]);\n    assert(d15664b1.b == [[3, 4], [5, 6]]);\n    assert(d15664b2.b == [[3, 4], [5, 6]]);\n    assert(d15664b3.b == cast(shared)[[3, 4], [5, 6]]);\n    assert(d15664b4.b == cast(shared)[[3, 4], [5, 6]]);\n    assert(d15664b5.b == [[3, 4], [5, 6]]);\n    assert(d15664b1.c == 7);    // OK\n    assert(d15664b2.c == 7);    // OK\n    assert(d15664b3.c == 7);    // OK <- NG\n    assert(d15664b4.c == 7);    // OK <- NG\n    assert(d15664b5.c == 7);    // OK <- NG\n}\n\n/******************************************/\n\nint main()\n{\n    test1();\n    test11672();\n    test15664();\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testenum.d",
    "content": "// PERMUTE_ARGS:\n\nextern(C) int printf(const char*, ...);\n\n/**********************************************/\n\nenum Bar\n{\n    bar2 = 2,\n    bar3,\n    bar4 = 0\n}\n\nvoid test1()\n{\n    Bar b;\n\n    assert(b == 2);\n}\n\n/**********************************************/\n\nvoid test2()\n{\n    enum E\n    {\n        a=-1\n    }\n\n    assert(E.min == -1);\n    assert(E.max == -1);\n}\n\n\n/**********************************************/\n\nvoid test3()\n{\n    enum E\n    {\n        a = 1,\n        b = -1,\n        c = 3,\n        d = 2\n    }\n\n    assert(E.min == -1);\n    assert(E.max == 3);\n}\n\n/**********************************************/\n\nvoid test4()\n{\n    enum E\n    {\n        a = -1,\n        b = -1,\n        c = -3,\n        d = -3\n    }\n\n    assert(E.min==-3);\n    assert(E.max==-1);\n}\n\n/**********************************************/\n\nenum Enum5\n{\n    A = 3,\n    B = 10,\n    E = -5,\n}\n\nvoid test5()\n{\n    assert(Enum5.init == Enum5.A);\n    assert(Enum5.init == 3);\n    Enum5 e;\n    assert(e == Enum5.A);\n    assert(e == 3);\n}\n\n/***********************************/\n\nenum E6 : byte\n{\n    NORMAL_VALUE = 0,\n    REFERRING_VALUE = NORMAL_VALUE + 1,\n    OTHER_NORMAL_VALUE = 2\n}\n\nvoid foo6(E6 e)\n{\n}\n\nvoid test6()\n{\n     foo6(E6.NORMAL_VALUE);\n     foo6(E6.REFERRING_VALUE);\n     foo6(E6.OTHER_NORMAL_VALUE);\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2407\n\nint i2407;\n\nvoid add2407() { ++i2407; }\nvoid sub2407() { --i2407; }\n\nenum EF2407f : void function()\n{\n    a = &add2407,\n    s = &sub2407,\n}\n\nenum EF2407s\n{\n    a = &add2407,\n    s = &sub2407,\n}\n\nenum\n{\n    a2407 = &add2407,\n    s2407 = &sub2407,\n}\n\nenum : void function()\n{\n    at2407 = &add2407,\n    st2407 = &sub2407,\n}\n\nenum EEF2407 : EF2407s\n{\n    a = EF2407s.a,\n    s = EF2407s.s,\n}\n\nvoid test2407()\n{\n    alias i2407 i;\n\n    EF2407f.a();\n    assert(i == 1);\n    EF2407f.s();\n    assert(i == 0);\n\n    EF2407s.a();\n    assert(i == 1);\n    EF2407s.s();\n    assert(i == 0);\n\n    a2407();\n    assert(i == 1);\n    s2407();\n    assert(i == 0);\n\n    at2407();\n    assert(i == 1);\n    st2407();\n    assert(i == 0);\n\n    EEF2407.a();\n    assert(i == 1);\n    EEF2407.s();\n    assert(i == 0);\n\n    EEF2407.init();\n    assert(i == 1);\n\n    struct S { int i; }\n    enum ES : S\n    {\n        a = S(1),\n        b = S(3),\n        c = S(2),\n    }\n    static assert(ES.init == S(1));\n    static assert(!__traits(compiles, ES.min));\n    static assert(!__traits(compiles, ES.max));\n\n    enum EES : ES\n    {\n        a = ES.a,\n        b = ES.b,\n        c = ES.c,\n    }\n    static assert(EES.init == S(1));\n    static assert(!__traits(compiles, EES.min));\n    static assert(!__traits(compiles, EES.max));\n\n    ES es = ES.c;\n    assert(es.i == 2);\n    es = ES.b;\n    assert(es.i == 3);\n\n    class C { this(int i) { this.i = i; } int i; }\n    enum EC : C\n    {\n        a = new C(42),\n        b = null,\n        c = new C(1),\n        d = new C(33),\n    }\n    static assert(EC.init.i == (new C(42)).i);\n    static assert(!__traits(compiles, EC.min));\n    static assert(!__traits(compiles, EC.max));\n\n    EC ec = EC.d;\n    assert(ec.i == 33);\n    ec = EC.b;\n    assert(ec is null);\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3096\n\nvoid test3096()\n{\n    template Tuple(T...) { alias Tuple = T; }\n\n    template Base(E)\n    {\n        static if(is(E B == enum))\n            alias Base = B;\n    }\n\n    template GetEnum(T)\n    {\n        enum GetEnum { v = T.init }\n    }\n\n    struct S { }\n    class C { }\n\n    foreach (Type; Tuple!(char, wchar, dchar, byte, ubyte,\n                          short, ushort, int, uint, long,\n                          ulong, float, double, real, S, C))\n    {\n        static assert(is(Base!(GetEnum!Type) == Type));\n    }\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7719\n\nenum foo7719 = bar7719;\nenum { bar7719 = 1 }\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9845\n\nenum { A9845 = B9845 }\nenum { B9845 = 1 }\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9846\n\nconst int A9846 = B9846;\nenum { B9846 = 1 }\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10105\n\nenum E10105 : char[1] { a = \"a\" }\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10113\n\nenum E10113 : string\n{\n    a = \"a\",\n    b = \"b\",\n    abc = \"abc\"\n}\n\nvoid test10113()\n{\n    E10113 v = E10113.b;\n    bool check = false;\n\n    final switch (v) {\n    case E10113.a: assert(false);\n    case E10113.b: check = true; break;\n    case E10113.abc: assert(false);\n    }\n\n    assert(check);\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10503\n\n@property int octal10503(string num)()\n{\n    return num.length;\n}\n\nenum\n{\n    A10503 = octal10503!\"2000000\",\n    B10503 = octal10503!\"4000\",\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10505\n\nenum\n{\n    a10505 = true,\n    b10505 = 10.0f,\n    c10505 = false,\n    d10505 = 10,\n    e10505 = null\n}\n\nstatic assert(is(typeof(a10505) == bool));\nstatic assert(is(typeof(b10505) == float));\nstatic assert(is(typeof(c10505) == bool));\nstatic assert(is(typeof(d10505) == int));\nstatic assert(is(typeof(e10505) == typeof(null)));\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10561\n\nvoid test10561()\n{\n    template Tuple(T...) { alias Tuple = T; }\n\n    foreach (Type; Tuple!(char, wchar, dchar, byte, ubyte,\n                          short, ushort, int, uint, long,\n                          ulong, float, double, real))\n    {\n        enum : Type { v = 0, w = 0, x, y = x }\n        static assert(is(typeof(v) == Type));\n        static assert(is(typeof(w) == Type));\n        static assert(is(typeof(x) == Type));\n        static assert(is(typeof(y) == Type));\n    }\n\n    class B { }\n    class D : B { }\n    enum : B { a = new D, b = new B, c = null }\n    static assert(is(typeof(a) == B));\n    static assert(is(typeof(b) == B));\n    static assert(is(typeof(c) == B));\n\n    struct S { this(int) { } }\n    enum : S { d = S(1), e = S(2) }\n    static assert(is(typeof(d) == S));\n    static assert(is(typeof(e) == S));\n\n    enum : float[] { f = [], g = [1.0, 2.0], h = [1.0f] }\n    static assert(is(typeof(f) == float[]));\n    static assert(is(typeof(g) == float[]));\n    static assert(is(typeof(h) == float[]));\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10612\n\nint[E10612] ie10612;\nE10612[int] ei10612;\nE10612[E10612] ee10612;\n\nenum E10612 { a }\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10788\n\nenum v10788 = e10788;\nenum : int { e10788 }\n\n/**********************************************/\n\nclass C7\n{\n    enum Policy\n    {\n        PREFER_READERS,\n        PREFER_WRITERS\n    }\n\n    void foo1( Policy policy = Policy.PREFER_READERS ) { }\n    void foo2( Policy policy = Policy.PREFER_WRITERS ) { }\n}\n\n/**********************************************/\n\nvoid test8()\n{\n    enum E\n    {\n        A = B,\n        E = D + 7,\n        B = 3,\n        C,\n        D,\n    }\n\n    assert(E.A == 3);\n    assert(E.B == 3);\n    assert(E.C == 4);\n    assert(E.D == 5);\n    assert(E.E == 12);\n    assert(E.max == 12);\n}\n\n/**********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13220\n\nenum E13220a;\n@(1) enum E13220b;\n\nvoid test13220()\n{\n    auto prot = __traits(getProtection, E13220a);\n    assert(prot == \"public\");\n\n    auto udas = __traits(getAttributes, E13220b);\n    assert(udas[0] == 1);\n}\n\n/**********************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test2407();\n    test10113();\n    test10561();\n    test8();\n    test13220();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testfile.d",
    "content": "// PERMUTE_ARGS:\n\nimport std.file;\nimport std.stdio;\n\n/***********************************************/\n\nvoid test1()\n{\n    auto p = std.file.getcwd();\n\n    writefln(\"%s '%s'\\n\", p.length, p);\n    assert(p[$ - 1] != 0);\n}\n\n/***********************************************/\n\nint main()\n{\n    test1();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testformat.d",
    "content": "// PERMUTE_ARGS:\n\nimport std.stdio;\nimport std.string;\n\n/*************************************************************/\n\nvoid test1()\n{\n    double x = 1e6;\n    float f;\n    double d;\n    real r;\n\n    while (x > 1e-5)\n    {   double y = x / 101.0;\n\n        std.stdio.writef(\"x = %g\\t%f\\t%e\\n\",x/101.0,x/101.0,x/101.0);\n        x /= 10.0;\n    }\n\n    double a = 123456789.0;\n    for (int i = 20; i--; a /= 10)\n        std.stdio.writef(\"%20.6g|%20.6e|%20.6f\\n\",a,a,a);\n\n    std.stdio.writef(\"%e %e %e %e\\n\",float.nan,double.nan,real.nan,double.infinity);\n    std.stdio.writef(\"%e %e %e\\n\",-float.nan,-double.nan,-double.infinity);\n    std.stdio.writef(\"%-5E %5E %E\\n\",float.nan,double.nan,double.infinity);\n\n    std.stdio.writef(\"%f %f %f\\n\",float.nan,double.nan,double.infinity);\n    std.stdio.writef(\"%f %f %f\\n\",-float.nan,-double.nan,-double.infinity);\n    std.stdio.writef(\"%+F %+ F %F\\n\",float.nan,double.nan,double.infinity);\n\n    std.stdio.writef(\"%g %g %g\\n\",float.nan,double.nan,double.infinity);\n    std.stdio.writef(\"%g %g %g\\n\",-float.nan,-double.nan,-double.infinity);\n    std.stdio.writef(\"% G %G %G\\n\",float.nan,double.nan,double.infinity);\n\n    r = 0x1.AAp+3L;\n    std.stdio.writef(\" r = %g\\n\", r);\n    std.stdio.writef(\" r = %a\\n\", r);\n    std.stdio.writef(\" r = %A\\n\", r);\n\n    d = 0x1.AAp+3;\n    std.stdio.writef(\" d = %.5a\\n\", d);\n    std.stdio.writef(\" d = %A\\n\", d);\n\n    f = 0x1.AAp+3f;\n    std.stdio.writef(\" f = %a\\n\", f);\n    std.stdio.writef(\" f = %A\\n\", f);\n\n    f = 0x1.FFp+3f;\n    std.stdio.writef(\" f = %.1a\\n\", f);\n    std.stdio.writef(\" f = %A\\n\", f);\n\n    r = 0;\n    std.stdio.writef(\" r = %a\\n\", r);\n    std.stdio.writef(\" r = %A\\n\", r);\n\n    std.stdio.writef(\"%e\\n\", 1e+300);\n    std.stdio.writef(\"%.0f\\n%.307f\\n\", 1e+300, 1e-300);\n    std.stdio.writef(\"%.0A\\n%.307A\\n\", 1e+300, 1e-300);\n}\n\n/*************************************************************/\n\nvoid test2()\n{\n   writefln(\"%o\", 9);\n   assert(std.string.format(\"%o\", 9) == \"11\");\n   assert(std.string.format(\"%o\", 10) == \"12\");\n   assert(std.string.format(\"%b\", 9) == \"1001\");\n   assert(std.string.format(\"%b\", 10) == \"1010\");\n}\n\n\n/*************************************************************/\n\nvoid test3()\n{\n    Object e = new Exception(\"hello\");\n    writeln(e.toString());\n    //assert(e.toString() == \"object.Exception: hello\");\n    //assert(format(e) == \"object.Exception: hello\");\n\n    alias char[] xstring;\n    assert(format(cast(xstring)\"world\") == \"world\");\n}\n\n/*************************************************************/\n\nvoid test4()\n{\n   const char[][] x = [\"%s\",\"123\"];\n   writeln(x);\n   assert(std.string.format(\"%s\", x) == `[\"%s\", \"123\"]`);\n}\n\n/*************************************************************/\n\nvoid test5()\n{\n    int[int] foo;\n\n    foo[1] = 2;\n    foo[7] = 28;\n\n    writefln(\"%s\", foo);\n\n    void[0] v;\n    assert(format(\"%s\", v) == \"[]\");\n}\n\n/*************************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n\n    std.stdio.writefln(\"Success\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testgc2.d",
    "content": "// PERMUTE_ARGS:\n\nmodule testgc2;\n\nimport core.stdc.stdio;\nimport core.exception : OutOfMemoryError;\n\n/*******************************************/\n\nvoid test1()\n{\n    printf(\"This should not take a while\\n\");\n    try\n    {\n        long[] l = new long[ptrdiff_t.max];\n        printf(\"%lu\\n\", cast(ulong)l.capacity); // Make sure l is not optimized out.\n        assert(0);\n    }\n    catch (OutOfMemoryError o)\n    {\n    }\n\n    printf(\"This may take a while\\n\");\n    try\n    {\n        byte[] b = new byte[size_t.max / 3];\n        printf(\"%lu\\n\", cast(ulong)b.capacity); // Make sure b is not optimized out.\n        version (Windows)\n            assert(0);\n    }\n    catch (OutOfMemoryError o)\n    {\n    }\n}\n\n/*******************************************/\n\nvoid main()\n{\n    test1();\n\n    printf(\"Success\\n\");\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testgc3.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS:\n\nimport core.stdc.stdio;\n\n/* This isn't a very good test. If it 'fails' it just takes a very\n * long time. The performance improved by a factor of five between\n * 2.042 and 2.043.\n */\nvoid main()\n{\n    uint[uint][] aa;\n    aa.length = 10000;\n    for(int i = 0; i < 10_000_000; i++)\n    {\n        size_t j = i % aa.length;\n        uint k = i;\n        uint l = i;\n        aa[j][k] = l;\n    }\n    printf(\"finished\\n\");\n    aa[] = null;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testinvariant.d",
    "content": "// PERMUTE_ARGS:\n\nextern(C) int printf(const char*, ...);\n\nclass Foo : Object\n{\n    void test() { }\n\n    invariant()\n    {\n        printf(\"in invariant %p\\n\", this);\n    }\n}\n\nint testinvariant()\n{\n    printf(\"hello\\n\");\n    Foo f = new Foo();\n    printf(\"f = %p\\n\", f);\n    printf(\"f.sizeof = x%x\\n\", Foo.sizeof);\n    printf(\"f.classinfo = %p\\n\", f.classinfo);\n    printf(\"f.classinfo._invariant = %p\\n\", f.classinfo.base);\n    f.test();\n    printf(\"world\\n\");\n    return 0;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6453\n\nvoid test6453()\n{\n    static class C\n    {\n        static uint called;\n        invariant() { called += 1; }\n        invariant() { called += 4; }\n        invariant() { called += 16; }\n\n        void publicMember() { assert(called == 21); }\n    }\n\n    static struct S\n    {\n        static uint called;\n        invariant() { called += 1; }\n        invariant() { called += 4; }\n        invariant() { called += 16; }\n\n        void publicMember() { assert(called == 21); }\n    }\n\n    auto c = new C();\n    C.called = 0;\n    c.publicMember();\n    assert(C.called == 42);\n\n    auto s = new S();\n    S.called = 0;\n    s.publicMember();\n    assert(S.called == 42);\n\n    // Defined symbols in one invariant cannot be seen from others.\n    static struct S6453\n    {\n        invariant()\n        {\n            struct S {}\n            int x;\n            static assert(!__traits(compiles, y));\n            static assert(!__traits(compiles, z));\n        }\n        invariant()\n        {\n            struct S {}\n            int y;\n            static assert(!__traits(compiles, x));\n            static assert(!__traits(compiles, z));\n        }\n        invariant()\n        {\n            struct S {}\n            int z;\n            static assert(!__traits(compiles, x));\n            static assert(!__traits(compiles, y));\n        }\n    }\n\n    static struct S6453a\n    {\n        pure    invariant() {}\n        nothrow invariant() {}\n        @safe   invariant() {}\n    }\n    static struct S6453b\n    {\n        pure    shared invariant() {}\n        nothrow shared invariant() {}\n        @safe   shared invariant() {}\n    }\n    static class C6453c\n    {\n        pure    synchronized invariant() {}\n        nothrow synchronized invariant() {}\n        @safe   synchronized invariant() {}\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13113\n\nstruct S13113\n{\n    static int count;\n    invariant() // impure, throwable, system, and gc-able\n    {\n        ++count;    // impure\n    }\n\n    this(int) pure nothrow @safe @nogc {}\n    // post invaiant is called directly but doesn't interfere with constructor attributes\n\n    ~this() pure nothrow @safe @nogc {}\n    // pre invaiant is called directly but doesn't interfere with destructor attributes\n\n    void foo() pure nothrow @safe @nogc {}\n    // pre & post invariant calls don't interfere with method attributes\n}\n\nvoid test13113()\n{\n    assert(S13113.count == 0);\n    {\n        auto s = S13113(1);\n        assert(S13113.count == 1);\n        s.foo();\n        assert(S13113.count == 3);\n    }\n    assert(S13113.count == 4);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13147\n\nversion (D_InlineAsm_X86)\n    enum x86iasm = true;\nelse version (D_InlineAsm_X86_64)\n    enum x86iasm = true;\nelse\n    enum x86iasm = false;\n\nclass C13147\n{\n    extern (C++) C13147 test()\n    {\n        static if (x86iasm)\n            asm { naked; ret; }\n        return this;\n    }\n}\n\nstruct S13147\n{\n    void test()\n    {\n        static if (x86iasm)\n            asm { naked; ret; }\n    }\n}\n\nvoid test13147()\n{\n    auto c = new C13147();\n    c.test();\n    S13147 s;\n    s.test();\n}\n\n\n/***************************************************/\n\nvoid main()\n{\n    testinvariant();\n    test6453();\n    test13113();\n    test13147();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testkeyword.d",
    "content": "// PERMUTE_ARGS:\n// EXTRA_SOURCES: imports/testkwd_file.d\nmodule testkeyword;\nimport imports.testkwd;\n\n/****************************************/\n// calee test\n\nstatic assert(getCalleeFile()  == thatFile);\nstatic assert(getCalleeLine()  == thatLine);\nstatic assert(getCalleeMod()   == thatMod);\nstatic assert(getCalleeFunc()  == thatFunc);\nstatic assert(getCalleeFunc2() == thatFunc2);\n\nvoid testCallee()\n{\n    static assert(getCalleeFile()  == thatFile);\n    static assert(getCalleeLine()  == thatLine);\n    static assert(getCalleeMod()   == thatMod);\n    static assert(getCalleeFunc()  == thatFunc);\n    static assert(getCalleeFunc2() == thatFunc2);\n}\n\n/****************************************/\n// caller test\n\nversion(Windows) enum sep = \"\\\\\";  else enum sep = \"/\";\n\nenum thisFile = \"runnable\"~sep~\"testkeyword.d\";\nenum thisMod  = \"testkeyword\";\n\nstatic assert(getFuncArgFile()  == thisFile);\nstatic assert(getFuncArgLine()  == 33);\nstatic assert(getFuncArgMod()   == thisMod);\nstatic assert(getFuncArgFunc()  == \"\");\nstatic assert(getFuncArgFunc2() == \"\");\n\nstatic assert(getFuncTiargFile()  == thisFile);\nstatic assert(getFuncTiargLine()  == 39);\nstatic assert(getFuncTiargMod()   == thisMod);\nstatic assert(getFuncTiargFunc()  == \"\");\nstatic assert(getFuncTiargFunc2() == \"\");\n\nstatic assert(getInstTiargFile!()  == thisFile);\nstatic assert(getInstTiargLine!()  == 45);\nstatic assert(getInstTiargMod!()   == thisMod);\nstatic assert(getInstTiargFunc!()  == \"\");\nstatic assert(getInstTiargFunc2!() == \"\");\n\nvoid main(string[] args) nothrow\n{\n    enum thisFunc       = \"testkeyword.main\";\n    enum thisFunc2 = \"void testkeyword.main(string[] args) nothrow\";\n\n    static assert(getFuncArgFile()  == thisFile);\n    static assert(getFuncArgLine()  == 56);\n    static assert(getFuncArgMod()   == thisMod);\n    static assert(getFuncArgFunc()  == thisFunc);\n    static assert(getFuncArgFunc2() == thisFunc2);\n\n    static assert(getFuncTiargFile()  == thisFile);\n    static assert(getFuncTiargLine()  == 62);\n    static assert(getFuncTiargMod()   == thisMod);\n    static assert(getFuncTiargFunc()  == thisFunc);\n    static assert(getFuncTiargFunc2() == thisFunc2);\n\n    static assert(getInstTiargFile!()  == thisFile);\n    static assert(getInstTiargLine!()  == 68);\n    static assert(getInstTiargMod!()   == thisMod);\n    static assert(getInstTiargFunc!()  == thisFunc);\n    static assert(getInstTiargFunc2!() == thisFunc2);\n\n    void nested(int x, float y) nothrow\n    {\n        enum thisFunc       = \"testkeyword.main.nested\";\n        enum thisFunc2 = \"void testkeyword.main.nested(int x, float y) nothrow\";\n\n        static assert(getFuncArgFile()  == thisFile);\n        static assert(getFuncArgLine()  == 79);\n        static assert(getFuncArgMod()   == thisMod);\n        static assert(getFuncArgFunc()  == thisFunc);\n        static assert(getFuncArgFunc2() == thisFunc2);\n\n        static assert(getFuncTiargFile()  == thisFile);\n        static assert(getFuncTiargLine()  == 85);\n        static assert(getFuncTiargMod()   == thisMod);\n        static assert(getFuncTiargFunc()  == thisFunc);\n        static assert(getFuncTiargFunc2() == thisFunc2);\n\n        static assert(getInstTiargFile!()  == thisFile);\n        static assert(getInstTiargLine!()  == 91);\n        static assert(getInstTiargMod!()   == thisMod);\n        static assert(getInstTiargFunc!()  == thisFunc);\n        static assert(getInstTiargFunc2!() == thisFunc2);\n    }\n    nested(1, 1.0);\n\n    auto funcLiteral = (int x, int y)\n    {\n        enum thisFunc  = \"testkeyword.main.__lambda3\";\n        enum thisFunc2 = \"testkeyword.main.__lambda3(int x, int y)\";\n\n        static assert(getFuncArgFile()  == thisFile);\n        static assert(getFuncArgLine()  == 104);\n        static assert(getFuncArgMod()   == thisMod);\n        static assert(getFuncArgFunc()  == thisFunc);\n        static assert(getFuncArgFunc2() == thisFunc2);\n\n        static assert(getFuncTiargFile()  == thisFile);\n        static assert(getFuncTiargLine()  == 110);\n        static assert(getFuncTiargMod()   == thisMod);\n        static assert(getFuncTiargFunc()  == thisFunc);\n        static assert(getFuncTiargFunc2() == thisFunc2);\n\n        static assert(getInstTiargFile!()  == thisFile);\n        static assert(getInstTiargLine!()  == 116);\n        static assert(getInstTiargMod!()   == thisMod);\n        static assert(getInstTiargFunc!()  == thisFunc);\n        static assert(getInstTiargFunc2!() == thisFunc2);\n    };\n    funcLiteral(1, 2);\n\n    static struct S\n    {\n        void func(string cs, T1, alias T2, T...)(int x) const\n        {\n            enum thisFunc       = `testkeyword.main.S.func!(\"foo\", int, symbol, int[], float[]).func`;\n            enum thisFunc2 = `void testkeyword.main.S.func!(\"foo\", int, symbol, int[], float[]).func(int x) const`;\n\n            static assert(getFuncArgFile()  == thisFile);\n            static assert(getFuncArgLine()  == 131);\n            static assert(getFuncArgMod()   == thisMod);\n            static assert(getFuncArgFunc()  == thisFunc);\n            static assert(getFuncArgFunc2() == thisFunc2);\n\n            static assert(getFuncTiargFile()  == thisFile);\n            static assert(getFuncTiargLine()  == 137);\n            static assert(getFuncTiargMod()   == thisMod);\n            static assert(getFuncTiargFunc()  == thisFunc);\n            static assert(getFuncTiargFunc2() == thisFunc2);\n\n            static assert(getInstTiargFile!()  == thisFile);\n            static assert(getInstTiargLine!()  == 143);\n            static assert(getInstTiargMod!()   == thisMod);\n            static assert(getInstTiargFunc!()  == thisFunc);\n            static assert(getInstTiargFunc2!() == thisFunc2);\n        }\n    }\n    static int symbol;\n    S s;\n    s.func!(\"foo\", int, symbol, int[], float[])(1);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testline.d",
    "content": "// PERMUTE_ARGS:\n\n// $HeadURL$\n// $Date$\n// $Author$\n\nmodule dstress.run.line_token_03;\n\nimport std.stdio;\nimport core.exception;\n\nint main(){\n        try{\n                #line 1 \"\"\n                assert(0);\n        }catch(AssertError o){\n                checkFileSpec(o);\n                return 0;\n        }\n\n        assert(0);\n}\n\nimport std.stdio;\n\n/*\n * @WARNING@: this code depends on the phobos implementation.\n * char[]s returned by wrong assertions have to look like:\n *       \"blah blah \"filename\" blah blah\"\n */\nvoid checkFileSpec(Object o){\n        string str=o.toString();\n\n        int start;\n        for(start=0; start<str.length; start++){\n                if(str[start]=='('){\n                        break;\n                }\n        }\n\nwriteln(str);\n        assert(str[start .. start+3]==\"(1)\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testmain.d",
    "content": "\n// REQUIRED_ARGS: -main\n\nvoid foo() { }\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testminit.d",
    "content": "// EXTRA_SOURCES: imports/testminitAA.d imports/testminitBB.d\n// PERMUTE_ARGS:\n\nimport core.stdc.stdio;\n\nimport imports.testminitAA;\nprivate import imports.testminitBB;\n\nstatic this()\n{\n    printf(\"hello\\n\");\n    assert(aa == 1);\n    assert(bb == 1);\n}\n\nint main()\n{\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testmmfile.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS:\n\nimport std.file;\nimport std.mmfile;\n\nint main()\n{\n    static string name = \"test.tmp\";\n    static string s = \"abcd\";\n\n    write(name, s);\n\n    {   scope MmFile mmf = new MmFile(name);\n        string p;\n\n        assert(mmf[0] == 'a');\n        p = cast(string)mmf[];\n        //printf(\"p.length = %d\\n\", p.length);\n        assert(p[1] == 'b');\n        p = cast(string)mmf[0 .. 4];\n        assert(p[2] == 'c');\n    }\n\n    {   scope MmFile mmf = new MmFile(name, MmFile.Mode.read, 0, null);\n        string p;\n\n        assert(mmf[0] == 'a');\n        p = cast(string)mmf[];\n        //printf(\"p.length = %d\\n\", p.length);\n        assert(mmf.length == 4);\n        assert(p[1] == 'b');\n        p = cast(string)mmf[0 .. 4];\n        assert(p[2] == 'c');\n    }\n\n    remove(name);\n\n    {   scope MmFile mmf = new MmFile(name, MmFile.Mode.readWriteNew, 4, null);\n        char[] p;\n\n        p = cast(char[])mmf[];\n        p[] = \"1234\";\n        mmf[3] = '5';\n        assert(mmf[2] == '3');\n        assert(mmf[3] == '5');\n    }\n\n    {   string p = cast(string)read(name);\n\n        assert(p[] == \"1235\");\n    }\n\n    {   scope MmFile mmf = new MmFile(name, MmFile.Mode.readWriteNew, 4, null);\n        char[] p;\n\n        p = cast(char[])mmf[];\n        p[] = \"5678\";\n        mmf[3] = '5';\n        assert(mmf[2] == '7');\n        assert(mmf[3] == '5');\n        assert(cast(string)mmf[] == \"5675\");\n    }\n\n    {   string p = cast(string)read(name);\n\n        assert(p[] == \"5675\");\n    }\n\n    {   scope MmFile mmf = new MmFile(name, MmFile.Mode.readWrite, 4, null);\n        char[] p;\n\n        p = cast(char[])mmf[];\n        assert(cast(char[])mmf[] == \"5675\");\n        p[] = \"9102\";\n        mmf[2] = '5';\n        assert(cast(string)mmf[] == \"9152\");\n    }\n\n    {   string p = cast(string)read(name);\n\n        assert(p[] == \"9152\");\n    }\n\n    remove(name);\n\n    {   scope MmFile mmf = new MmFile(name, MmFile.Mode.readWrite, 4, null);\n        char[] p;\n\n        p = cast(char[])mmf[];\n        p[] = \"abcd\";\n        mmf[2] = '5';\n        assert(cast(string)mmf[] == \"ab5d\");\n    }\n\n    {   string p = cast(string)read(name);\n\n        assert(p[] == \"ab5d\");\n    }\n\n    {   scope MmFile mmf = new MmFile(name, MmFile.Mode.readCopyOnWrite, 4, null);\n        char[] p;\n\n        p = cast(char[])mmf[];\n        assert(cast(string)mmf[] == \"ab5d\");\n        p[] = \"9102\";\n        mmf[2] = '5';\n        assert(cast(string)mmf[] == \"9152\");\n    }\n\n    {   string p = cast(string)read(name);\n\n        assert(p[] == \"ab5d\");\n    }\n\n    remove(name);\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testmod1.d",
    "content": "// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/testmod1a.d imports/testmod1b.d\n// PERMUTE_ARGS:\n\nstruct Foo(T) {\n  void foo(T arg) { }\n}\n\n\nint main()\n{\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testmod2.d",
    "content": "// EXTRA_SOURCES: imports/testmod2a.d\n\n/**********************************/\n// https://issues.dlang.org/show_bug.cgi?id=1904\n\nimport imports.testmod2a;\nvoid main()\n{\n    void whatever() {}\n    foo!(whatever)();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testmodule.d",
    "content": "// PERMUTE_ARGS:\n\n// $HeadURL$\n// $Date$\n// $Author$\n\n// @author@     Anders F Björklund <afb@algonet.se>\n// @date@       2005-01-25\n// @uri@        news:ct428n$2qoe$1@digitaldaemon.com\n// @url@        nntp://news.digitalmars.com/D.gnu/983\n\nmodule run.unicode_06_哪里;\n\nint 哪里(int ö){\n        return ö+2;\n}\n\nint main(){\n        assert(run.unicode_06_哪里.哪里(2)==4);\n        return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testpic.d",
    "content": "// PERMUTE_ARGS: -fPIC -O\n\nextern (C) int printf(const char*, ...);\n\n/***************************************************/\n\nalign(16) struct S41\n{\n    int[4] a;\n}\n\nshared int x41;\nshared S41 s41;\n\nvoid test11310()\n{\n    printf(\"&x = %p\\n\", &x41);\n    printf(\"&s = %p\\n\", &s41);\n    assert((cast(int)&s41 & 0xF) == 0);\n}\n\n/***************************************************/\n\n\nstruct S17034\n{\n@nogc pure nothrow:\n    private long v;\n    void foo()\n    {\n        v >>>= 1;\n        if (!v)\n            return;\n        v >>>= 1;\n    }\n}\n\nvoid test17034()\n{\n    auto s = S17034(1L);\n    s.foo();\n    assert(s.v == 0);\n}\n\n/***************************************************/\n\nint main()\n{\n    test11310();\n    test17034();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testptrref.d",
    "content": "\nversion(CRuntime_Microsoft)\n{\n    extern(C)\n    {\n        extern __gshared uint _DP_beg;\n        extern __gshared uint _DP_end;\n        extern __gshared uint _TP_beg;\n        extern __gshared uint _TP_end;\n        extern int _tls_start;\n        extern int _tls_end;\n    }\n    alias _DPbegin = _DP_beg;\n    alias _DPend = _DP_end;\n    alias _TPbegin = _TP_beg;\n    alias _TPend = _TP_end;\n    alias _tlsstart = _tls_start;\n    alias _tlsend = _tls_end;\n\n    __gshared void[] dataSection;\n    shared static this()\n    {\n        import core.internal.traits : externDFunc;\n        alias findImageSection = externDFunc!(\"rt.sections_win64.findImageSection\",\n                                              void[] function(string name) nothrow @nogc);\n        dataSection = findImageSection(\".data\");\n    }\n    \n    version = ptrref_supported;\n}\nelse version(Win32)\n{\n    extern(C)\n    {\n        extern __gshared void* _DPbegin;\n        extern __gshared void* _DPend;\n        extern __gshared uint _TPbegin;\n        extern __gshared uint _TPend;\n        extern int _tlsstart;\n        extern int _tlsend;\n    }\n    version = ptrref_supported;\n}\n\nstruct Struct\n{\n    int x;\n    Struct* next;\n}\n\nclass Class\n{\n    void* ptr;\n}\n\nstruct Struc(T)\n{\n\tstatic T vtls;\n\tstatic __gshared T vgshared;\n}\n\n__gshared Struct* gsharedStrctPtr2 = new Struct(7, new Struct(8, null));\n\nint tlsInt;\nvoid* tlsVar;\n\nshared int sharedInt;\nshared void* sharedVar;\n__gshared void* gsharedVar;\n__gshared void* gsharedVar2;\nimmutable int[] arr = [1, 2, 3];\nstring tlsStr;\n\n__gshared Struct gsharedStrct;\nStruct[3] tlsStrcArr;\nClass tlsClss;\n\n// expression initializers\nstring[] strArr = [ \"a\", \"b\" ];\n__gshared Class gsharedClss = new Class;\n__gshared Struct* gsharedStrctPtr = new Struct(7, new Struct(8, null));\n\ndebug(PRINT) import core.stdc.stdio;\n\nvoid main()\n{\n    version(ptrref_supported)\n        testRefPtr();\n}\n\nversion(ptrref_supported):\n\nbool findTlsPtr(const(void)* ptr)\n{    \n    debug(PRINT) printf(\"findTlsPtr %p\\n\", ptr);\n    for (uint* p = &_TPbegin; p < &_TPend; p++)\n    {\n        void* addr = cast(void*) &_tlsstart + *p;\n        debug(PRINT) printf(\"  try %p\\n\", addr);\n        assert(addr < &_tlsend);\n        if (addr == ptr)\n            return true;\n    }\n    return false;\n}\n\nbool findDataPtr(const(void)* ptr)\n{\n    debug(PRINT) printf(\"findDataPtr %p\\n\", ptr);\n    for (auto p = &_DPbegin; p < &_DPend; p++)\n    {\n        debug(PRINT) printf(\"  try %p\\n\", cast(void*) cast(size_t) *p);\n        version(CRuntime_Microsoft)\n            void* addr = dataSection.ptr + *p;\n        else\n            void* addr = *p;\n        \n        if (addr == ptr)\n            return true;\n    }\n    return false;\n}\n\nvoid testRefPtr()\n{\n    debug(PRINT) printf(\"&_DPbegin %p\\n\", &_DPbegin);\n    debug(PRINT) printf(\"&_DPend   %p\\n\", &_DPend);\n\n    assert(!findDataPtr(cast(void*)&sharedInt));\n    assert(!findTlsPtr(&tlsInt));\n\n    assert(findDataPtr(cast(void*)&sharedVar));\n    assert(findDataPtr(&gsharedVar));\n    assert(findDataPtr(&gsharedStrct.next));\n    assert(findDataPtr(&(gsharedClss)));\n    assert(findDataPtr(&(gsharedClss.ptr)));\n\n    assert(findTlsPtr(&tlsVar));\n    assert(findTlsPtr(&tlsClss));\n    assert(findTlsPtr(&tlsStrcArr[0].next));\n    assert(findTlsPtr(&tlsStrcArr[1].next));\n    assert(findTlsPtr(&tlsStrcArr[2].next));\n\n    assert(!findTlsPtr(cast(size_t*)&tlsStr)); // length\n    assert(findTlsPtr(cast(size_t*)&tlsStr + 1)); // ptr\n    \n    // monitor is manually managed\n    assert(!findDataPtr(cast(size_t*)cast(void*)Class.classinfo + 1));\n    assert(!findDataPtr(cast(size_t*)cast(void*)Class.classinfo + 1));\n\n    assert(!findDataPtr(&arr));\n    assert(!findTlsPtr(&arr));\n    assert(!findDataPtr(cast(size_t*)&arr + 1));\n    assert(!findTlsPtr(cast(size_t*)&arr + 1));\n    \n    assert(findDataPtr(cast(size_t*)&strArr[0] + 1)); // ptr in _DATA!\n    assert(findDataPtr(cast(size_t*)&strArr[1] + 1)); // ptr in _DATA!\n    strArr[1] = \"c\";\n\n    assert(findDataPtr(&gsharedStrctPtr));\n    assert(findDataPtr(&gsharedStrctPtr.next));\n    assert(findDataPtr(&gsharedStrctPtr.next.next));\n\n    assert(findDataPtr(&(Struc!(int*).vgshared)));\n    assert(!findDataPtr(&(Struc!(int).vgshared)));\n    assert(findTlsPtr(&(Struc!(int*).vtls)));\n    assert(!findTlsPtr(&(Struc!(int).vtls)));\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testreturn.d",
    "content": "extern(C) int printf(const char*, ...);\n\nalias TypeTuple(T...) = T;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13336\n\nstruct S13336\n{\n    int opApply(scope int delegate(int) dg)\n    {\n        return dg(0);\n    }\n}\n\ndouble result13336;\n\nenum fbody13336 =\nq{\n    static if (n == 1)\n    {\n        if (f)\n            return sx;\n        return sy;\n    }\n    static if (n == 2)\n    {\n        foreach (e; S13336())\n        {\n            if (f)\n                return sx;\n            return sy;\n        }\n        assert(0);\n    }\n    static if (n == 3)\n    {\n        if (f)\n            return sx;\n        foreach (e; S13336())\n        {\n            return sy;\n        }\n        assert(0);\n    }\n    static if (n == 4)\n    {\n        foreach (e; S13336())\n        {\n            if (f)\n                return sx;\n        }\n        return sy;\n    }\n    static if (n == 5)\n    {\n        if (false)\n            return 99;\n        foreach (e; S13336())\n        {\n            if (f)\n                return sx;\n            return sy;\n        }\n        assert(0);\n    }\n    static if (n == 6)\n    {\n        foreach (e; S13336())\n        {\n            if (f)\n                return sx;\n            return sy;\n        }\n        return 99;\n    }\n};\n\n// auto ref without out contract\nauto ref f13336a(int n, alias sx, alias sy)(bool f)\n{\n    mixin(fbody13336);\n}\n\n// auto without out contract\nauto f13336b(int n, alias sx, alias sy)(bool f)\n{\n    mixin(fbody13336);\n}\n\n// auto ref with out contract\nauto ref f13336c(int n, alias sx, alias sy)(bool f)\nout(r)\n{\n    static assert(is(typeof(r) == const double));\n    assert(r == (f ? sx : sy));\n    result13336 = r;\n}\nbody\n{\n    mixin(fbody13336);\n}\n\n// auto with out contract\nauto f13336d(int n, alias sx, alias sy)(bool f)\nout(r)\n{\n    static assert(is(typeof(r) == const double));\n    assert(r == (f ? sx : sy));\n    result13336 = r;\n}\nbody\n{\n    mixin(fbody13336);\n}\n\nvoid test13336()\n{\n    static int sx = 1;\n    static double sy = 2.5;\n\n    foreach (num; TypeTuple!(1, 2, 3, 4, 5, 6))\n    {\n        foreach (foo; TypeTuple!(f13336a, f13336b))\n        {\n            alias fooxy = foo!(num, sx, sy);\n            static assert(is(typeof(&fooxy) : double function(bool)));\n            assert(fooxy(1) == 1.0);\n            assert(fooxy(0) == 2.5);\n\n            alias fooyx = foo!(num, sy, sx);\n            static assert(is(typeof(&fooyx) : double function(bool)));\n            assert(fooyx(1) == 2.5);\n            assert(fooyx(0) == 1.0);\n        }\n\n        foreach (foo; TypeTuple!(f13336c, f13336d))\n        {\n            alias fooxy = foo!(num, sx, sy);\n            static assert(is(typeof(&fooxy) : double function(bool)));\n            assert(fooxy(1) == 1.0 && result13336 == 1.0);\n            assert(fooxy(0) == 2.5 && result13336 == 2.5);\n\n            alias fooyx = foo!(num, sy, sx);\n            static assert(is(typeof(&fooyx) : double function(bool)));\n            assert(fooyx(1) == 2.5 && result13336 == 2.5);\n            assert(fooyx(0) == 1.0 && result13336 == 1.0);\n        }\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15018\n\nstruct S15018(int n)\n{\n    short[n] m;\n}\n\nS15018!n f15018(int n)()\n{\n    S15018!n s;\n    foreach(i; 0..n)\n        s.m[i] = cast(short)(i * i + 3);\n    return s;\n}\n\nvoid test15018()\n{\n    // size 4\n    S15018!2[3] s3;\n    s3[] = f15018!2();\n    foreach (int i; 0..3)\n    {\n        assert(s3[i].m[0] == 3);\n        assert(s3[i].m[1] == 4);\n    }\n\n    // size 4-18\n    foreach (n; TypeTuple!(2, 3, 4, 5, 6, 7, 8, 9))\n    {\n        S15018!n[5] i5;\n        i5[] = f15018!n();\n        foreach (int j; 0..5)\n            foreach(k; 0..n)\n                if (i5[j].m[k] != k * k + 3)\n                    assert(false);\n    }\n}\n\n/***************************************************/\n\nint main()\n{\n    test13336();\n    test15018();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testrightthis.d",
    "content": "// runnable/traits.d    9091,8972,8971,7027\n// runnable/test4.d     test6()\n\nextern(C) int printf(const char*, ...);\n\ntemplate TypeTuple(TL...) { alias TypeTuple = TL; }\n\n/********************************************************/\n\nmixin(\"struct S1 {\"~aggrDecl1~\"}\");\nmixin(\"class  C1 {\"~aggrDecl1~\"}\");\nenum aggrDecl1 =\nq{\n    alias Type = typeof(this);\n\n    int x = 2;\n\n    void foo()\n    {\n        static assert( is(typeof(Type.x.offsetof)));\n        static assert( is(typeof(Type.x.mangleof)));\n        static assert( is(typeof(Type.x.sizeof  )));\n        static assert( is(typeof(Type.x.alignof )));\n        static assert( is(typeof({ auto n = Type.x.offsetof; })));\n        static assert( is(typeof({ auto n = Type.x.mangleof; })));\n        static assert( is(typeof({ auto n = Type.x.sizeof;   })));\n        static assert( is(typeof({ auto n = Type.x.alignof;  })));\n        static assert( is(typeof(Type.x)));\n        static assert( is(typeof({ auto n = Type.x; })));\n        static assert( __traits(compiles, Type.x));\n        static assert( __traits(compiles, { auto n = Type.x; }));\n\n        static assert( is(typeof(x.offsetof)));\n        static assert( is(typeof(x.mangleof)));\n        static assert( is(typeof(x.sizeof  )));\n        static assert( is(typeof(x.alignof )));\n        static assert( is(typeof({ auto n = x.offsetof; })));\n        static assert( is(typeof({ auto n = x.mangleof; })));\n        static assert( is(typeof({ auto n = x.sizeof;   })));\n        static assert( is(typeof({ auto n = x.alignof;  })));\n        static assert( is(typeof(x)));\n        static assert( is(typeof({ auto n = x; })));\n        static assert( __traits(compiles, x));\n        static assert( __traits(compiles, { auto n = x; }));\n\n        with (this)\n        {\n            static assert( is(typeof(x.offsetof)));\n            static assert( is(typeof(x.mangleof)));\n            static assert( is(typeof(x.sizeof  )));\n            static assert( is(typeof(x.alignof )));\n            static assert( is(typeof({ auto n = x.offsetof; })));\n            static assert( is(typeof({ auto n = x.mangleof; })));\n            static assert( is(typeof({ auto n = x.sizeof;   })));\n            static assert( is(typeof({ auto n = x.alignof;  })));\n            static assert( is(typeof(x)));\n            static assert( is(typeof({ auto n = x; })));\n            static assert( __traits(compiles, x));\n            static assert( __traits(compiles, { auto n = x; }));\n        }\n    }\n\n    static void bar()\n    {\n        static assert( is(typeof(Type.x.offsetof)));\n        static assert( is(typeof(Type.x.mangleof)));\n        static assert( is(typeof(Type.x.sizeof  )));\n        static assert( is(typeof(Type.x.alignof )));\n        static assert( is(typeof({ auto n = Type.x.offsetof; })));\n        static assert( is(typeof({ auto n = Type.x.mangleof; })));\n        static assert( is(typeof({ auto n = Type.x.sizeof;   })));\n        static assert( is(typeof({ auto n = Type.x.alignof;  })));\n        static assert( is(typeof(Type.x)));\n        static assert(!is(typeof({ auto n = Type.x; })));\n        static assert( __traits(compiles, Type.x));\n        static assert(!__traits(compiles, { auto n = Type.x; }));\n\n        static assert( is(typeof(x.offsetof)));\n        static assert( is(typeof(x.mangleof)));\n        static assert( is(typeof(x.sizeof  )));\n        static assert( is(typeof(x.alignof )));\n        static assert( is(typeof({ auto n = x.offsetof; })));\n        static assert( is(typeof({ auto n = x.mangleof; })));\n        static assert( is(typeof({ auto n = x.sizeof;   })));\n        static assert( is(typeof({ auto n = x.alignof;  })));\n        static assert( is(typeof(x)));\n        static assert(!is(typeof({ auto n = x; })));\n        static assert( __traits(compiles, x));\n        static assert(!__traits(compiles, { auto n = x; }));\n\n        Type t;\n        with (t)\n        {\n            static assert( is(typeof(x.offsetof)));\n            static assert( is(typeof(x.mangleof)));\n            static assert( is(typeof(x.sizeof  )));\n            static assert( is(typeof(x.alignof )));\n            static assert( is(typeof({ auto n = x.offsetof; })));\n            static assert( is(typeof({ auto n = x.mangleof; })));\n            static assert( is(typeof({ auto n = x.sizeof;   })));\n            static assert( is(typeof({ auto n = x.alignof;  })));\n            static assert( is(typeof(x)));\n            static assert( is(typeof({ auto n = x; })));\n            static assert( __traits(compiles, x));\n            static assert( __traits(compiles, { auto n = x; }));\n        }\n    }\n};\nvoid test1()\n{\n    foreach (Type; TypeTuple!(S1, C1))\n    {\n        static assert( is(typeof(Type.x.offsetof)));\n        static assert( is(typeof(Type.x.mangleof)));\n        static assert( is(typeof(Type.x.sizeof  )));\n        static assert( is(typeof(Type.x.alignof )));\n        static assert( is(typeof({ auto n = Type.x.offsetof; })));\n        static assert( is(typeof({ auto n = Type.x.mangleof; })));\n        static assert( is(typeof({ auto n = Type.x.sizeof;   })));\n        static assert( is(typeof({ auto n = Type.x.alignof;  })));\n        static assert( is(typeof(Type.x)));\n        static assert(!is(typeof({ auto n = Type.x; })));\n        static assert( __traits(compiles, Type.x));\n        static assert(!__traits(compiles, { auto n = Type.x; }));\n\n        Type t;\n        static assert( is(typeof(t.x.offsetof)));\n        static assert( is(typeof(t.x.mangleof)));\n        static assert( is(typeof(t.x.sizeof  )));\n        static assert( is(typeof(t.x.alignof )));\n        static assert( is(typeof({ auto n = t.x.offsetof; })));\n        static assert( is(typeof({ auto n = t.x.mangleof; })));\n        static assert( is(typeof({ auto n = t.x.sizeof;   })));\n        static assert( is(typeof({ auto n = t.x.alignof;  })));\n        static assert( is(typeof(t.x)));\n        static assert( is(typeof({ auto n = t.x; })));\n        static assert( __traits(compiles, t.x));\n        static assert( __traits(compiles, { auto n = t.x; }));\n\n        with (t)\n        {\n            static assert( is(typeof(x.offsetof)));\n            static assert( is(typeof(x.mangleof)));\n            static assert( is(typeof(x.sizeof  )));\n            static assert( is(typeof(x.alignof )));\n            static assert( is(typeof({ auto n = x.offsetof; })));\n            static assert( is(typeof({ auto n = x.mangleof; })));\n            static assert( is(typeof({ auto n = x.sizeof;   })));\n            static assert( is(typeof({ auto n = x.alignof;  })));\n            static assert( is(typeof(x)));\n            static assert( is(typeof({ auto n = x; })));\n            static assert( __traits(compiles, x));\n            static assert( __traits(compiles, { auto n = x; }));\n        }\n    }\n}\n\n/********************************************************/\n\nvoid test2()\n{\n    struct S\n    {\n        int val;\n        int[] arr;\n        int[int] aar;\n\n        void foo() {}\n        void boo()() {}\n\n        static void test()\n        {\n            static assert(!__traits(compiles, S.foo()));\n            static assert(!__traits(compiles, S.boo()));\n            static assert(!__traits(compiles, foo()));\n            static assert(!__traits(compiles, boo()));\n        }\n    }\n    int v;\n    int[] a;\n    void f(int n) {}\n\n    static assert( __traits(compiles, S.val));  // 'S.val' is treated just a symbol\n    static assert(!__traits(compiles, { int n = S.val; }));\n    static assert(!__traits(compiles, f(S.val)));\n\n    static assert(!__traits(compiles, v = S.val) && !__traits(compiles, S.val = v));\n\n    static assert(!__traits(compiles, 1 + S.val) && !__traits(compiles, S.val + 1));\n    static assert(!__traits(compiles, 1 - S.val) && !__traits(compiles, S.val - 1));\n    static assert(!__traits(compiles, 1 * S.val) && !__traits(compiles, S.val * 1));\n    static assert(!__traits(compiles, 1 / S.val) && !__traits(compiles, S.val / 1));\n    static assert(!__traits(compiles, 1 % S.val) && !__traits(compiles, S.val % 1));\n    static assert(!__traits(compiles, 1 ~ S.arr) && !__traits(compiles, S.arr ~ 1));\n\n    static assert(!__traits(compiles, 1 & S.val) && !__traits(compiles, S.val & 1));\n    static assert(!__traits(compiles, 1 | S.val) && !__traits(compiles, S.val | 1));\n    static assert(!__traits(compiles, 1 ^ S.val) && !__traits(compiles, S.val ^ 1));\n    static assert(!__traits(compiles, 1 ~ S.val) && !__traits(compiles, S.val ~ 1));\n\n    static assert(!__traits(compiles, 1 ^^ S.val) && !__traits(compiles, S.val ^^ 1));\n    static assert(!__traits(compiles, 1 << S.val) && !__traits(compiles, S.val << 1));\n    static assert(!__traits(compiles, 1 >> S.val) && !__traits(compiles, S.val >> 1));\n    static assert(!__traits(compiles, 1 >>>S.val) && !__traits(compiles, S.val >>>1));\n    static assert(!__traits(compiles, 1 && S.val) && !__traits(compiles, S.val && 1));\n    static assert(!__traits(compiles, 1 || S.val) && !__traits(compiles, S.val || 1));\n    static assert(!__traits(compiles, 1 in S.aar) && !__traits(compiles, S.val || [1:1]));\n\n    static assert(!__traits(compiles, 1 <= S.val) && !__traits(compiles, S.val <= 1));\n    static assert(!__traits(compiles, 1 == S.val) && !__traits(compiles, S.val == 1));\n    static assert(!__traits(compiles, 1 is S.val) && !__traits(compiles, S.val is 1));\n\n    static assert(!__traits(compiles, 1? 1:S.val) && !__traits(compiles, 1? S.val:1));\n    static assert(!__traits(compiles, (1, S.val)) && !__traits(compiles, (S.val, 1)));\n\n    static assert(!__traits(compiles, &S.val));\n    static assert(!__traits(compiles, S.arr[0]) && !__traits(compiles, [1,2][S.val]));\n    static assert(!__traits(compiles, S.val++) && !__traits(compiles, S.val--));\n    static assert(!__traits(compiles, ++S.val) && !__traits(compiles, --S.val));\n\n    static assert(!__traits(compiles, v += S.val) && !__traits(compiles, S.val += 1));\n    static assert(!__traits(compiles, v -= S.val) && !__traits(compiles, S.val -= 1));\n    static assert(!__traits(compiles, v *= S.val) && !__traits(compiles, S.val *= 1));\n    static assert(!__traits(compiles, v /= S.val) && !__traits(compiles, S.val /= 1));\n    static assert(!__traits(compiles, v %= S.val) && !__traits(compiles, S.val %= 1));\n    static assert(!__traits(compiles, v &= S.val) && !__traits(compiles, S.val &= 1));\n    static assert(!__traits(compiles, v |= S.val) && !__traits(compiles, S.val |= 1));\n    static assert(!__traits(compiles, v ^= S.val) && !__traits(compiles, S.val ^= 1));\n    static assert(!__traits(compiles, a ~= S.val) && !__traits(compiles, S.arr ~= 1));\n\n    static assert(!__traits(compiles, v ^^= S.val) && !__traits(compiles, S.val ^^= 1));\n    static assert(!__traits(compiles, v <<= S.val) && !__traits(compiles, S.val <<= 1));\n    static assert(!__traits(compiles, v >>= S.val) && !__traits(compiles, S.val >>= 1));\n    static assert(!__traits(compiles, v >>>=S.val) && !__traits(compiles, S.val >>>=1));\n\n    static assert(!__traits(compiles, { auto x = 1 + S.val; }) && !__traits(compiles, { auto x = S.val + 1; }));\n    static assert(!__traits(compiles, { auto x = 1 - S.val; }) && !__traits(compiles, { auto x = S.val - 1; }));\n    static assert(!__traits(compiles, { auto x = S.arr ~ 1; }) && !__traits(compiles, { auto x = 1 ~ S.arr; }));\n\n    static assert(!__traits(compiles, S.foo()));\n    static assert(!__traits(compiles, S.boo()));\n    S.test();\n    alias foo = S.foo;\n    alias boo = S.boo;\n    static assert(!__traits(compiles, foo()));\n    static assert(!__traits(compiles, boo()));\n\n//  static assert(S.val);\n\n    struct SW { int a; }\n    class CW { int a; }\n    static assert(!__traits(compiles, { with (SW) { int n = a; } }));\n    static assert(!__traits(compiles, { with (CW) { int n = a; } }));\n}\n\n/********************************************************/\n\nstruct S3\n{\n    struct T3 { int val; void foo() {} }\n    T3 member;\n    alias member this;\n\n    static void test()\n    {\n        static assert(!__traits(compiles,   S3.val = 1   ));\n        static assert(!__traits(compiles, { S3.val = 1; }));\n        static assert(!__traits(compiles,   T3.val = 1   ));\n        static assert(!__traits(compiles, { T3.val = 1; }));\n        static assert(!__traits(compiles,   __traits(getMember, S3, \"val\") = 1   ));\n        static assert(!__traits(compiles, { __traits(getMember, S3, \"val\") = 1; }));\n        static assert(!__traits(compiles,   __traits(getMember, T3, \"val\") = 1   ));\n        static assert(!__traits(compiles, { __traits(getMember, T3, \"val\") = 1; }));\n\n        static assert(!__traits(compiles,   S3.foo()   ));\n        static assert(!__traits(compiles, { S3.foo(); }));\n        static assert(!__traits(compiles,   T3.foo()   ));\n        static assert(!__traits(compiles, { T3.foo(); }));\n        static assert(!__traits(compiles,   __traits(getMember, S3, \"foo\")()   ));\n        static assert(!__traits(compiles, { __traits(getMember, S3, \"foo\")(); }));\n        static assert(!__traits(compiles,   __traits(getMember, T3, \"foo\")()   ));\n        static assert(!__traits(compiles, { __traits(getMember, T3, \"foo\")(); }));\n        static assert(!__traits(compiles,   __traits(getOverloads, S3, \"foo\")[0]()   ));\n        static assert(!__traits(compiles, { __traits(getOverloads, S3, \"foo\")[0](); }));\n        static assert(!__traits(compiles,   __traits(getOverloads, T3, \"foo\")[0]()   ));\n        static assert(!__traits(compiles, { __traits(getOverloads, T3, \"foo\")[0](); }));\n    }\n}\n\nvoid test3()\n{\n}\n\n/********************************************************/\n\nvoid test4()\n{\n    static struct R\n    {\n        void opIndex(int) {}\n        void opSlice() {}\n        void opSlice(int, int) {}\n        int opDollar() { return 1; }\n        alias length = opDollar;\n    }\n\n    R val;\n    static struct S\n    {\n        R val;\n        void foo()\n        {\n            static assert(__traits(compiles, val[1]));              // TypeSArray\n            static assert(__traits(compiles, val[]));               // TypeDArray\n            static assert(__traits(compiles, val[0..val.length]));  // TypeSlice\n        }\n    }\n}\n\n/********************************************************/\n\ntemplate Test5(string name, bool result)\n{\n    mixin(`static assert(__traits(compiles, `~name~`.add!\"months\"(1)) == result);`);\n}\n\nstatic struct Begin5\n{\n    void add(string s)(int n) {}\n}\n\nstruct IntervalX5(TP)\n{\n    Begin5 begin;\n\n    static assert(__traits(compiles, begin.add!\"months\"(1)) == true);\n    mixin Test5!(\"begin\", true);\n\n    void foo()\n    {\n        static assert(__traits(compiles, begin.add!\"months\"(1)) == true);\n        mixin Test5!(\"begin\", true);\n    }\n    static test()\n    {\n        static assert(__traits(compiles, begin.add!\"months\"(1)) == false);\n        mixin Test5!(\"begin\", false);\n    }\n}\n\nalias IX5 = IntervalX5!int;\nalias beginX5 = IX5.begin;\nstatic assert(__traits(compiles, beginX5.add!\"months\"(1)) == false);\nmixin Test5!(\"beginG5\", false);\n\nvoid test5()\n{\n    static struct IntervalY5(TP)\n    {\n        Begin5 begin;\n\n        static assert(__traits(compiles, begin.add!\"months\"(1)) == true);\n        mixin Test5!(\"begin\", true);\n\n        void foo()\n        {\n            static assert(__traits(compiles, begin.add!\"months\"(1)) == true);\n            mixin Test5!(\"begin\", true);\n        }\n        static test()\n        {\n            static assert(__traits(compiles, begin.add!\"months\"(1)) == false);\n            mixin Test5!(\"begin\", false);\n        }\n    }\n\n    alias IX = IntervalX5!int;\n    alias beginX = IX.begin;\n    static assert(__traits(compiles, beginX.add!\"months\"(1)) == false);\n    mixin Test5!(\"beginX\", false);\n\n    alias IY = IntervalY5!int;\n    alias beginY = IY.begin;\n    static assert(__traits(compiles, beginY.add!\"months\"(1)) == false);\n    mixin Test5!(\"beginY\", false);\n}\n\n/********************************************************/\n\nvoid test6()\n{\n    static struct Foo\n    {\n        static struct Bar\n        {\n            static int get() { return 0; }\n            static int val;\n            void set() { assert(0); }\n            int num;\n        }\n        static class Baz\n        {\n            static int get() { return 0; }\n            static int val;\n            void set() { assert(0); }\n            int num;\n        }\n        Bar bar;\n        Baz baz;\n    }\n\n    // allowed cases that do 'use' Foo.bar without this\n    assert(Foo.bar.get() == 0);         // Foo.bar.get()\n    assert(Foo.baz.get() == 0);         // Foo.bar.get()\n    static assert(!__traits(compiles, Foo.bar.set()));\n    static assert(!__traits(compiles, Foo.baz.set()));\n\n    assert(Foo.bar.val == 0);           // Foo.bar.val\n    assert(Foo.baz.val == 0);           // Foo.baz.val\n    static assert(!__traits(compiles, Foo.bar.num = 1));\n    static assert(!__traits(compiles, Foo.baz.num = 1));\n}\n\n/********************************************************/\n\nstruct Tuple7(T...)\n{\n    T field;\n\n    enum check1 = is(typeof(field[0] = 1));\n    enum check2 = is(typeof({ field[0] = 1; }));\n\n    this(U, size_t n)(U[n] values)\n    if (is(typeof({ foreach (i, _; T) field[0] = values[0]; })))\n    {}\n}\n\nvoid test7()\n{\n    alias Tuple7!(int, int) Tup7;\n    static assert(Tup7.check1);\n    static assert(Tup7.check2);\n    int[2] ints = [ 1, 2 ];\n    Tup7 t = ints;\n\n    struct S7\n    {\n        int value;\n\n        enum check1 = is(typeof(value = 1));\n        enum check2 = is(typeof({ value = 1; }));\n\n        void foo()(int v)\n        if (is(typeof({\n            value = v;  // valid\n        }))) {}\n\n        static void bar()(int v)\n        if (is(typeof({\n            value = v;  // always invalid\n        }))) {}\n    }\n    static assert(S7.check1);\n    static assert(S7.check2);\n    S7 s;\n    s.foo(1);\n    static assert(!__traits(compiles, S7.bar(1)));\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4350\n\ntemplate Mix4350() { int b; }\n\nstruct S4350\n{\n    int a;\n\n    mixin Mix4350 mix;\n\n    int c;\n    template Func() { void call(int n) { c = n; } }\n    alias func = Func!();\n}\n\nvoid test4350()\n{\n    S4350 s;\n\n    s.a = 1;\n    s.mix.b = 2;\n    s.func.call(3);\n    assert(s.a == 1);\n    assert(s.b == 2);\n    assert(s.c == 3);\n\n    with (s) { a = 2; }\n    with (s) { mix.b = 3; }\n    with (s) { func.call(4); }\n    assert(s.a == 2);\n    assert(s.b == 3);\n    assert(s.c == 4);\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6430\n\nauto bug6430(int a)\n{\n    static struct Result2 {}\n    return 4;\n}\nauto bug6430(int a, int b)\n{\n    static struct Result2\n    {\n        int z;\n        int y() { return z; }\n    }\n    auto t = Result2(1);\n    return 5;\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9619\n\nstruct Foo9619 { int x; }\nvoid test9619()\n{\n    void bar()\n    {\n        typeof(Foo9619.x) y;\n    }\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9633\n\nclass Foo9633\n{\n    void baz() {}\n    void bar()\n    {\n        // CallExp::e1->op == TOKvar\n        static assert(!compilesWithoutThis9633!baz);\n    }\n    void vaz()()\n    {\n        static class C\n        {\n            // CallExp::e1->op == TOKtemplate\n            static assert(!__traits(compiles, vaz()));\n        }\n    }\n}\n\ntemplate compilesWithoutThis9633(alias F)\n{\n    enum bool compilesWithoutThis9633 = __traits(compiles, F());\n}\n\nvoid test9633()\n{\n    auto foo = new Foo9633;\n    foo.bar();\n    foo.vaz();\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11245\n\nstruct Vec11245\n{\n    float[2] f;\n}\n\nclass Bar11245\n{\n    void func()\n    {\n        pragma(msg, \"====\");\n        float[Vec11245.f.length] newVal;\n    }\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11614\n\nstruct Tuple11614(T...)\n{\n    T field;\n    alias field this;\n}\n\nstruct Foo11614\n{\n    alias Tuple11614!(int) NEW_ARGS;\n\n    NEW_ARGS args;\n\n    void foo()\n    {\n        static if (NEW_ARGS.length == 1)\n        {}\n        else\n            static assert(0);\n    }\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11993\n\nstruct S11993\n{\n    void foo()() const\n    if (is(typeof(this) == const(S11993)))\n    {}\n\n    const void bar()()\n    if (is(typeof(this) == const(S11993)))\n    {}\n}\n\nvoid test11993()\n{\n    S11993 s;\n    s.foo();\n    s.bar();\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15934\n\nclass B15934\n{\n    int foo()       { return 1; }\n    int foo() const { return 2; }\n}\n\nclass C15934 : B15934\n{\n    override int foo()       { return 3; }\n    override int foo() const { return 4; }\n\n    void test1()\n    {\n        assert(this.foo() == 3);\n        assert(     foo() == 3);\n        assert(this.B15934.foo() == 1);\n        assert(     B15934.foo() == 1);\n    }\n\n    void test2() const\n    {\n        assert(this.foo() == 4);\n        assert(     foo() == 4);\n        assert(this.B15934.foo() == 2);  // OK <- wrongly returns 1\n        assert(     B15934.foo() == 2);  // OK <- wrongly returns 1\n    }\n}\n\nvoid test15934()\n{\n    auto c = new C15934();\n    c.test1();\n    c.test2();\n}\n\n/********************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test4350();\n    test9619();\n    test9633();\n    test15934();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testsafe.d",
    "content": "// PERMUTE_ARGS:\n\n//http://d.puremagic.com/issues/show_bug.cgi?id=5415\n\n@safe\nvoid pointercast()\n{\n    int* a;\n    void* b;\n\n    static assert( __traits(compiles, cast(void*)a));\n    static assert(!__traits(compiles, cast(int*)b));\n    static assert(!__traits(compiles, cast(int*)b));\n    static assert(!__traits(compiles, cast(short*)b));\n    static assert(!__traits(compiles, cast(byte*)b));\n    static assert( __traits(compiles, cast(short*)a));\n    static assert( __traits(compiles, cast(byte*)a));\n}\n\n@safe\nvoid pointercast2()\n{\n    size_t a;\n    int b;\n    Object c;\n\n    static assert(!__traits(compiles, cast(void*)a));\n    static assert(!__traits(compiles, cast(void*)b));\n    static assert(!__traits(compiles, cast(void*)c));\n}\n\n@safe\nvoid pointerarithmetic()\n{//http://d.puremagic.com/issues/show_bug.cgi?id=4132\n    void* a;\n    int b;\n\n    static assert(!__traits(compiles, a + b));\n    static assert(!__traits(compiles, a - b));\n    static assert(!__traits(compiles, a += b));\n    static assert(!__traits(compiles, a -= b));\n    static assert(!__traits(compiles, a++));\n    static assert(!__traits(compiles, a--));\n    static assert(!__traits(compiles, ++a));\n    static assert(!__traits(compiles, --a));\n    static assert( __traits(compiles, a + 0));\n    static assert( __traits(compiles, a - 0));\n    static assert( __traits(compiles, 0 + a));\n    static assert(!__traits(compiles, a + 1));\n    static assert(!__traits(compiles, a - 1));\n    static assert(!__traits(compiles, 1 + a));\n    static assert( __traits(compiles, a += 0));\n    static assert( __traits(compiles, a -= 0));\n    static assert(!__traits(compiles, a += 1));\n    static assert(!__traits(compiles, a -= 1));\n}\n\n\n\nunion SafeUnion1\n{\n    int a;\n    struct\n    {\n        int b;\n        int* c;\n    }\n}\nunion SafeUnion2\n{\n    int a;\n    struct\n    {\n        int b;\n        int c;\n    }\n}\nunion UnsafeUnion1\n{\n    int a;\n    int* c;\n}\nunion UnsafeUnion2\n{\n    int a;\n    align(1)\n    struct\n    {\n        byte b;\n        int* c;\n    }\n}\nunion UnsafeUnion3\n{\n    int a;\n    Object c;\n}\nunion UnsafeUnion4\n{\n    int a;\n    align(1)\n    struct\n    {\n        byte b;\n        Object c;\n    }\n}\nstruct pwrapper\n{\n    int* a;\n}\nunion UnsafeUnion5\n{\n    SafeUnion2 x;\n    pwrapper b;\n}\n\nunion uA\n{\n    struct\n    {\n        int* a;\n        void* b;\n    }\n}\nstruct uB\n{\n    uA a;\n}\nstruct uC\n{\n    uB a;\n}\nstruct uD\n{\n    uC a;\n}\n\n@safe\nvoid safeunions()   // improved for https://issues.dlang.org/show_bug.cgi?id=11510\n{\n    SafeUnion1 su1;\n    SafeUnion2 su2;\n    UnsafeUnion1 uu1;\n    UnsafeUnion2 uu2;\n    UnsafeUnion3 uu3;\n    UnsafeUnion4 uu4;\n    UnsafeUnion5 uu5;\n    uD uud;\n\n    int n;\n    void* p;\n    Object o;\n\n    // Writing field is always allowed, even if it is overlapped.\n    su1.a = 7, su1.b = 8, su1.c = null;\n    su2.a = 7, su2.b = 8, su2.c = 9;\n    uu1.a = 7,            //uu1.c = null;\n    uu2.a = 7; uu2.b = 8, //uu2.c = null;\n    uu3.a = 7;            //uu3.c = null;\n    uu4.a = 7; uu4.b = 8, //uu4.c = null;\n    uu5.x.a = 7; uu5.x.b = 8, uu5.x.c = 9;\n    uud.a.a.a.a = null, uud.a.a.a.b = null;\n\n    // Reading field is allowed, if it is not overlapped or has no pointers.\n    n = su1.a, n = su1.b, p = su1.c;\n    n = su2.a, n = su2.b, n = su2.c;\n    n = uu1.a;\n    n = uu2.a, n = uu2.b;\n    n = uu3.a;\n    n = uu4.a, n = uu4.b;\n    n = uu5.x.a, n = uu5.x.b, n = uu5.x.c;\n    p = uud.a.a.a.a, p = uud.a.a.a.b;\n\n    // Reading overlapped pointer field is not allowed.\n    static assert(!__traits(compiles, () @safe { auto p = uu1.c; }));\n    static assert(!__traits(compiles, () @safe { auto p = uu2.c; }));\n    static assert(!__traits(compiles, () @safe { auto c = uu3.c; }));\n    static assert(!__traits(compiles, () @safe { auto c = uu4.c; }));\n    static assert(!__traits(compiles, () @safe { auto p = uu5.b.a; }));\n}\n\n\n\n@safe\nvoid safeexception()\n{\n    try {}\n    catch(Exception e) {}\n\n    static assert(!__traits(compiles, () @safe {\n        try {}\n        catch(Error e) {}\n    }));\n\n    static assert(!__traits(compiles, () @safe {\n        try {}\n        catch(Throwable e) {}\n    }));\n\n    static assert(!__traits(compiles, () @safe {\n        try {}\n        catch {}\n    }));\n}\n\n@safe\nvoid inlineasm()\n{\n    version(GNU)\n    {\n        version(X86)\n            static assert(!__traits(compiles, { asm { \"nop\"; } }() ));\n        else version(X86_64)\n            static assert(!__traits(compiles, { asm { \"nop\"; } }() ));\n        else version(ARM)\n            static assert(!__traits(compiles, { asm { \"nop\"; } }() ));\n        else\n            static assert(false, \"ASM code not implemented for this architecture\");\n    }\n    else\n        static assert(!__traits(compiles, { asm { int 3; } }() ));\n}\n\n@safe\nvoid multablecast()\n{\n    Object m;\n    const(Object) c;\n    immutable(Object) i;\n\n    static assert( __traits(compiles, cast(const(Object))m));\n    static assert( __traits(compiles, cast(const(Object))i));\n\n    static assert(!__traits(compiles, cast(immutable(Object))m));\n    static assert(!__traits(compiles, cast(immutable(Object))c));\n\n    static assert(!__traits(compiles, cast(Object)c));\n    static assert(!__traits(compiles, cast(Object)i));\n\n    void* mp;\n    const(void)* cp;\n    immutable(void)* ip;\n\n    static assert( __traits(compiles, cast(const(void)*)mp));\n    static assert( __traits(compiles, cast(const(void)*)ip));\n\n    static assert(!__traits(compiles, cast(immutable(void)*)mp));\n    static assert(!__traits(compiles, cast(immutable(void)*)cp));\n\n    static assert(!__traits(compiles, cast(void*)cp));\n    static assert(!__traits(compiles, cast(void*)ip));\n}\n\n@safe\nvoid sharedcast()\n{\n    Object local;\n    shared(Object) xshared;\n    immutable(Object) ishared;\n\n    static assert(!__traits(compiles, cast()xshared));\n    static assert(!__traits(compiles, cast(shared)local));\n\n    static assert(!__traits(compiles, cast(immutable)xshared));\n    static assert(!__traits(compiles, cast(shared)ishared));\n}\n\nint threadlocalvar;\n\n@safe\nvoid takeaddr()\n{\n    static assert(!__traits(compiles, (int x) @safe { auto y = &x; } ));\n    static assert(!__traits(compiles, () @safe { int x; auto y = &x; } ));\n    static assert( __traits(compiles, () @safe { static int x; auto y = &x; } ));\n    static assert( __traits(compiles, () @safe { auto y = &threadlocalvar; } ));\n}\n\n__gshared int gsharedvar;\n\n@safe\nvoid use__gshared()\n{\n    static assert(!__traits(compiles, () @safe { int x = gsharedvar; } ));\n}\n\n@safe\nvoid voidinitializers()\n{//http://d.puremagic.com/issues/show_bug.cgi?id=4885\n    static assert(!__traits(compiles, () @safe { uint* ptr = void; } ));\n    static assert( __traits(compiles, () @safe { uint i = void; } ));\n    static assert( __traits(compiles, () @safe { uint[2] a = void; } ));\n\n    struct ValueStruct { int a; }\n    struct NonValueStruct { int* a; }\n    static assert( __traits(compiles, () @safe { ValueStruct a = void; } ));\n    static assert(!__traits(compiles, () @safe { NonValueStruct a = void; } ));\n\n    static assert(!__traits(compiles, () @safe { uint[] a = void; } ));\n    static assert(!__traits(compiles, () @safe { int** a = void; } ));\n    static assert(!__traits(compiles, () @safe { int[int] a = void; } ));\n}\n\n@safe\nvoid pointerindex()\n{//http://d.puremagic.com/issues/show_bug.cgi?id=9195\n    static assert(!__traits(compiles, () @safe { int* p; auto a = p[30]; }));\n    static assert( __traits(compiles, () @safe{ int* p; auto a = p[0]; }));\n}\n\n@safe\nvoid basiccast()\n{//http://d.puremagic.com/issues/show_bug.cgi?id=5088\n    auto a = cast(int)cast(const int)1;\n    auto b = cast(real)cast(const int)1;\n    auto c = cast(real)cast(const real)2.0;\n}\n\n@safe\nvoid arraycast()\n{\n    int[] x;\n    void[] y = x;\n    static assert( __traits(compiles, cast(void[])x));\n    static assert(!__traits(compiles, cast(int[])y));\n    static assert(!__traits(compiles, cast(int*[])y));\n    static assert(!__traits(compiles, cast(void[][])y));\n\n    int[3] a;\n    int[] b = cast(int[])a;\n    uint[3] c = cast(uint[3])a;\n\n    const char[] cc;\n    static assert( __traits(compiles, cast(const(ubyte)[])cc));\n    static assert( __traits(compiles, cast(const(ubyte[]))cc));\n    static assert(!__traits(compiles, cast(shared(ubyte)[])cc));\n\n    shared char[] sc;\n    static assert( __traits(compiles, cast(shared(ubyte)[])sc));\n    static assert( __traits(compiles, cast(shared(ubyte[]))sc));\n    static assert(!__traits(compiles, cast(const(ubyte)[])sc));\n}\n\n@safe\nvoid structcast()\n{\n    struct A { ptrdiff_t x; }\n    struct B { size_t x; }\n    struct C { void* x; }\n    A a;\n    B b;\n    C c;\n\n    static assert( __traits(compiles, a = cast(A)b));\n    static assert( __traits(compiles, a = cast(A)c));\n    static assert( __traits(compiles, b = cast(B)a));\n    static assert( __traits(compiles, b = cast(B)c));\n    static assert(!__traits(compiles, c = cast(C)a));\n    static assert(!__traits(compiles, c = cast(C)b));\n}\n\n@safe void test6497()\n{\n    int n;\n    (0 ? n : n) = 3;\n}\n\n@safe\nvoid varargs()\n{\n    static void fun(string[] val...) {}\n    fun(\"a\");\n}\n\nextern(C++) interface E {}\nextern(C++) interface F : E {}\n\n@safe\nvoid classcast()\n{\n    class A {}\n    class B : A {}\n\n    A a;\n    B b;\n\n    static assert( __traits(compiles, cast(A)a));\n    static assert( __traits(compiles, cast(B)a));\n    static assert( __traits(compiles, cast(A)b));\n    static assert( __traits(compiles, cast(B)b));\n\n    const A ca;\n    const B cb;\n\n    static assert( __traits(compiles, cast(const(A))ca));\n    static assert( __traits(compiles, cast(const(B))ca));\n    static assert( __traits(compiles, cast(const(A))cb));\n    static assert( __traits(compiles, cast(const(B))cb));\n\n    static assert(!__traits(compiles, cast(A)ca));\n    static assert(!__traits(compiles, cast(B)ca));\n    static assert(!__traits(compiles, cast(A)cb));\n    static assert(!__traits(compiles, cast(B)cb));\n\n    interface C {}\n    interface D : C {}\n\n    C c;\n    D d;\n\n    static assert( __traits(compiles, cast(C)c));\n    static assert( __traits(compiles, cast(D)c));\n    static assert( __traits(compiles, cast(C)d));\n    static assert( __traits(compiles, cast(D)d));\n\n    E e;\n    F f;\n\n    static assert( __traits(compiles, cast(E)e));\n    static assert(!__traits(compiles, cast(F)e));\n    static assert( __traits(compiles, cast(E)f));\n    static assert( __traits(compiles, cast(F)f));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6278\n\n@safe\n{\n\nclass A6278 {\n    int test()\n    in { assert(0); }\n    body { return 1; }\n}\nclass B6278 : A6278 {\n    override int test()\n    in { assert(0); }\n    body { return 1; }\n}\n\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7803\n\n@safe int f7803() {\n    scope(success) {/* ... */}\n    return 3;\n}\n\nnothrow int g7803() {\n    scope(success) {/* ... */}\n    return 3;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6405\n\nvoid foo6405(int[][] args...) @trusted { }\nvoid test6405() @safe { foo6405([1,2,3], [1,2,3]); }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12502\n\nvoid test12502() @safe\n{\n    const char[1] arr;\n    auto ax = cast(const(char) []) arr[]; // ok\n    auto a1 = cast(const(ubyte)[]) arr[]; // ok\n    auto a2 = cast(const(char) []) arr;   // ok\n    auto a3 = cast(const(ubyte)[]) arr;   // ok <- error\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14162\n\n@trusted auto trusted(alias fun)() { return fun(); }\n\n@safe void func1()()\n{\n    char[3] s = \"abc\";\n    string t = trusted!(() => cast(string)(s[]));\n    assert(t == \"abc\");\n}\n\n@safe void func2()()\n{\n    char[3] s = \"abc\";\n    string t = trusted!(() => cast(string)(s[]));\n    assert(t == \"abc\");\n}\n\n@safe void test14162()\n{\n    func1();\n    func2();\n}\n\n/***************************************************/\n\nvoid main()\n{\n    test14162();\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testscope.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -d -dip1000\n\nextern(C) int printf(const char*, ...);\n\nclass Eh : Exception\n{\n    this()\n    {\n        super(\"Eh thrown\");\n    }\n}\n\n\n/********************************************/\n\nclass Foo\n{\n    static int x;\n\n    this()\n    {\n        assert(x == 0);\n        x++;\n        printf(\"Foo.this()\\n\");\n        throw new Eh();\n        assert(0);\n    }\n\n    ~this()\n    {\n        printf(\"Foo.~this()\\n\");\n    }\n}\n\nvoid test1()\n{\n    try\n    {\n        scope Foo f = new Foo();\n        assert(0);\n    }\n    catch (Eh)\n    {\n        assert(Foo.x == 1);\n        Foo.x++;\n    }\n    finally\n    {\n        assert(Foo.x == 2);\n        Foo.x++;\n    }\n    assert(Foo.x == 3);\n}\n\n/********************************************/\n\nvoid test2()\n{\n    int x;\n    {\n        scope (exit) { printf(\"test1\\n\"); assert(x == 3); x = 4; }\n        scope (exit) { printf(\"test2\\n\"); assert(x == 2); x = 3; }\n        scope (exit) { printf(\"test3\\n\"); assert(x == 1); x = 2; }\n        printf(\"test4\\n\"); assert(x == 0); x = 1;\n    }\n    assert(x == 4);\n}\n\n/********************************************/\n\nvoid test3()\n{\n    int x;\n    {\n        scope (success) { printf(\"test1\\n\"); assert(x == 3); x = 4; }\n        scope (success) { printf(\"test2\\n\"); assert(x == 2); x = 3; }\n        scope (success) { printf(\"test3\\n\"); assert(x == 1); x = 2; }\n        printf(\"test4\\n\"); assert(x == 0); x = 1;\n    }\n    assert(x == 4);\n}\n\n/********************************************/\n\nvoid test4()\n{\n    int x;\n    try\n    {\n        scope (exit) { printf(\"test1\\n\"); assert(x == 3); x = 4; }\n        scope (exit) { printf(\"test2\\n\"); assert(x == 2); x = 3; }\n        x = 2;\n        throw new Eh;\n        scope (exit) { printf(\"test3\\n\"); assert(x == 1); x = 2; }\n        printf(\"test4\\n\"); assert(x == 0); x = 1;\n    }\n    catch (Eh e)\n    {\n    }\n    assert(x == 4);\n}\n\n/********************************************/\n\nvoid test5()\n{\n    int x;\n    try\n    {\n        scope (success) { printf(\"test1\\n\"); assert(x == 3); x = 4; }\n        scope (success) { printf(\"test2\\n\"); assert(x == 2); x = 3; }\n        x = 2;\n        throw new Eh;\n        scope (success) { printf(\"test3\\n\"); assert(x == 1); x = 2; }\n        printf(\"test4\\n\"); assert(x == 0); x = 1;\n    }\n    catch (Eh e)\n    {\n    }\n    assert(x == 2);\n}\n\n/********************************************/\n\nvoid test6()\n{\n    int x;\n    scope (failure) { assert(0); }\n    try\n    {\n        scope (failure) { printf(\"test1\\n\"); assert(x == 3); x = 4; }\n        scope (failure) { printf(\"test2\\n\"); assert(x == 2); x = 3; }\n        x = 2;\n        throw new Eh;\n        scope (failure) { printf(\"test3\\n\"); assert(x == 1); x = 2; }\n        printf(\"test4\\n\"); assert(x == 0); x = 1;\n    }\n    catch (Eh e)\n    {\n    }\n    assert(x == 4);\n}\n\n/********************************************/\n\nvoid test7()\n{   int i;\n    int x;\n\n    void foo()\n    {\n        scope (success) { assert(x == 1); x = 2; }\n        i = 2;\n        if (i == 2)\n            return;\n    }\n\n    i = 1;\n    x = 1;\n    foo();\n    assert(x == 2);\n}\n\n/********************************************/\n\n\nvoid test8()\n{\n    int i;\n    {\n        version (all)\n        {\n            scope (exit) i += 2;\n        }\n        assert(i == 0);\n        i += 1;\n        printf(\"betty\\n\");\n    }\n    assert(i == 3);\n}\n\n/********************************************/\n\nchar[] r9;\n\nint scp( int n )\n{\n    if( n==0 ) return 0;\n    scope(exit)\n    {   printf(\"%d\",n);\n        r9 ~= cast(char)(n + '0');\n    }\n    return scp(n-1);\n}\n\nvoid test9()\n{\n    scp(5);\n    assert(r9 == \"12345\");\n}\n\n/********************************************/\n\nalias real T;\n\nT readMessageBegin() { return 3.0; }\n\nT bar10() { return 8.0; }\n\nT foo10() {\n  // Send RPC request, etc.\n  readMessageBegin();\n  scope (exit) readMessageEnd();\n\n  T result = bar10();\n  // Read message off the wire.\n  return result;\n}\n\nvoid test10()\n{\n    if (foo10() != 8.0)\n        assert(0);\n}\n\nT readMessageEnd() {\n    static T d;\n    d = 4.0;\n    d = (((((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d))))+(((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d)))))/((((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d))))+(((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d)))))+((((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d))))+(((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d)))))/((((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d))))+(((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d))))))*(((((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d))))+(((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d)))))/((((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d))))+(((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d)))))+((((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d))))+(((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d)))))/((((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d))))+(((d-(2*d))+(d-(2*d)))*((d-(2*d))+(d-(2*d))))));\n    return 4.0;\n}\n\n/********************************************/\n\nvoid test7435() {\n  scope(failure)\n    debug printf(\"error\\n\");\n\n  printf(\"do something\\n\");\n}\n\n/********************************************/\n\nchar[] dup12()(char[] a) // although inferred pure, don't infer a is 'return'\n{\n    char[] res;\n    foreach (ref e; a)\n    {}\n    return res;\n}\n\nchar[] foo12()\n{\n    char[10] buf;\n    return dup12(buf);\n}\n\n/********************************************/\n\nvoid test7049() @safe\n{\n    int count = 0;\n    @safe void foo()\n    {\n        scope (failure) { count++; }\n        scope (failure) { count++; }\n        throw new Exception(\"failed\");\n    }\n\n    try {\n        foo();\n    } catch(Exception e) {\n    }\n    assert(count == 2);\n}\n\n/********************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=16747\n\nvoid test16747() @safe\n{\n    scope o = new Object();\n}\n\n/********************************************/\n\nvoid bar11(int*, int*) { }\n\nvoid test11()\n{\n    static int* p;\n    static int i;\n    bar11(p, &i);\n}\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17432\n\nint test17432(scope int delegate() dg)\n{\n        return dg();\n}\n\n// stripped down version of std.traits.Parameters\ntemplate Parameters(alias func)\n{\n    static if (is(typeof(func) P == function))\n        alias Parameters = P;\n    else\n        static assert(0, \"unsupported\");\n}\n\nalias op = Parameters!(test17432)[0];\nenum typeString = op.stringof;\nstatic assert(typeString == \"int delegate()\"); // no scope added?\nmixin(typeString ~ \" dg;\");\nalias ty = typeof(dg);\n\nstatic assert(op.stringof == ty.stringof);\nstatic assert(op.mangleof == ty.mangleof);\n\nvoid test17432_2()(scope void delegate () dg) { dg(); }\n\nstatic assert(typeof(&test17432_2!()).stringof == \"void function(scope void delegate() dg) @system\");\n\n/********************************************/\n\nbyte typify13(T)(byte val) { return val; }\nalias INT8_C13  = typify13!byte;\n\n/********************************************/\n\ntemplate test14(T)\n{\n    alias test14 = int;\n}\n\ntest14!(char[] function(return char[])) x14;\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17935\n\nstruct ByChunk(IO)\n{\n@safe:\n    ~this() scope\n    {}\n\n    ubyte[] buf;\n    IO io;\n}\n\nstruct IO\n{\n    ~this() @safe @nogc scope\n    {}\n}\n\n@safe @nogc void test17395()\n{\n    ubyte[256] buf;\n    auto chunks = ByChunk!IO(buf[], IO());\n    chunks.__xdtor(); // auto-generated inclusive (fields and struct) dtor\n}\n\n/********************************************/\n\nvoid main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test7435();\n    test7049();\n    test16747();\n    test11();\n    test17395();\n\n    printf(\"Success\\n\");\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testscope2.d",
    "content": "// REQUIRED_ARGS: -dip25\n\nimport core.stdc.stdio;\n\n/********************************************/\n\nstruct SS\n{\n    ref ulong foo1(return ref int* delegate() return p) return;\n    ref int foo2(return ref int delegate() p);\n    ref int foo3(inout ref int* p);\n    ref int foo4(return inout ref int* p);\n}\n\npragma(msg, \"foo1 \", typeof(&SS.foo1));\npragma(msg, \"foo2 \", typeof(&SS.foo2));\npragma(msg, \"foo3 \", typeof(&SS.foo3));\npragma(msg, \"foo4 \", typeof(&SS.foo4));\n\n\nvoid test3()\n{\n    version (all)\n    {\n        import std.stdio;\n        writeln(SS.foo1.mangleof);\n        writeln(SS.foo2.mangleof);\n        writeln(SS.foo3.mangleof);\n        writeln(SS.foo4.mangleof);\n        writeln(typeof(SS.foo1).stringof);\n        writeln(typeof(SS.foo2).stringof);\n        writeln(typeof(SS.foo3).stringof);\n        writeln(typeof(SS.foo4).stringof);\n    }\n\n    version (all)\n    {\n        // Test scope mangling\n        assert(SS.foo1.mangleof == \"_D10testscope22SS4foo1MFNcNjNkKDFNjZPiZm\");\n        assert(SS.foo2.mangleof == \"_D10testscope22SS4foo2MFNcNkKDFZiZi\");\n        assert(SS.foo3.mangleof == \"_D10testscope22SS4foo3MFNcNkKNgPiZi\");\n        assert(SS.foo4.mangleof == \"_D10testscope22SS4foo4MFNcNkKNgPiZi\");\n\n        // Test scope pretty-printing\n        assert(typeof(SS.foo1).stringof == \"ref ulong(return ref int* delegate() return p) return\");\n        assert(typeof(SS.foo2).stringof == \"ref int(return ref int delegate() p)\");\n        assert(typeof(SS.foo3).stringof == \"ref int(return ref inout(int*) p)\");\n        assert(typeof(SS.foo4).stringof == \"ref int(return ref inout(int*) p)\");\n    }\n}\n\n/********************************************/\n\nref int foo(return ref int x)\n{\n    return x;\n}\n\nstruct S\n{\n    int x;\n\n    ref S bar() return\n    {\n        return this;\n    }\n}\n\nref T foo2(T)(ref T x)\n{\n    return x;\n}\n\nvoid test4()\n{\n    int x;\n    foo2(x);\n}\n\n/********************************************/\n\nref int foo(return ref int x, ref int y)\n{\n    return x;\n}\n\nref int bar()\n{\n    int x;\n    static int y = 7;\n    return foo(y, x);\n}\n\nvoid test5()\n{\n    int x = bar();\n    assert(x == 7);\n}\n\n/********************************************/\n\nstruct S6\n{\n    int x = 8;\n\n    ref int bar() return\n    {\n        return x;\n    }\n}\n\nvoid test6()\n{\n    S6 s;\n    int b = s.bar();\n    assert(b == 8);\n}\n\n/********************************************/\n\nclass C\n{\n    int x;\n    ref int foo(return ref int x) { return x; }\n    ref int bar() return { return x; }\n}\n\nclass D : C\n{\n    override ref int foo(ref int x) { static int y; return y; }\n    override ref int bar() { static int y; return y; }\n}\n\nvoid test7()\n{\n}\n\n/********************************************/\n\nstruct S8(T)\n{\n    int x;\n\n    ref int bar() // infer 'return'\n    {\n        return x;\n    }\n}\n\nref int test8a(return ref S8!int s)\n{\n    return s.bar();\n}\n\nvoid test8()\n{\n}\n\n/********************************************/\n\nchar[] foo9(return out char[4] buf)\n{\n    return buf[0 .. 1];\n}\n\n/********************************************/\n\nstruct S10\n{\n    int x;\n\n    ref inout(int) foo() inout\n    {\n        return x;\n    }\n}\n\n/********************************************/\n\nstruct RC\n{\n    this(this) { }\n}\n\nstruct S11\n{\n    @disable this(this);\n\n    void remove()\n    {\n        _ptr[0] = _ptr[1];\n    }\n\n    RC* _ptr;\n}\n\n\nvoid test11()\n{\n    S11 ary;\n}\n\n/********************************************/\n\nint[10] a12;\n\nint* foo12()\n{\n    foreach (ref x; a12)\n        return &x;\n    return null;\n}\n\n/********************************************/\n\nstruct FullCaseEntry\n{\n    dchar[3] seq;\n    ubyte n, size;// n number in batch, size - size of batch\n    ubyte entry_len;\n\n    @property auto value() const @trusted pure nothrow @nogc return\n    {\n        return seq[0..entry_len];\n    }\n}\n\n/********************************************/\n\nclass C12\n{\n    void member() scope { }\n}\n\n/********************************************/\n\nvoid main()\n{\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test11();\n    printf(\"Success\\n\");\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testsignals.d",
    "content": "import std.stdio;\nimport std.signals;\n\nclass Observer\n{   // our slot\n    void watch(string msg, int i)\n    {\n        writefln(\"Observed msg '%s' and value %s\", msg, i);\n    }\n\n    void watch2(int i, int j)\n    {\n        writefln(\"Observed msg %s,%s\", i, j);\n    }\n}\n\nclass Foo\n{\n    int value() { return _value; }\n\n    int value(int v)\n    {\n        if (v != _value)\n        {   _value = v;\n            // call all the connected slots with the two parameters\n            emit(\"setting new value\", v);\n        }\n        return v;\n    }\n\n    // Mix in all the code we need to make Foo into a signal\n    mixin Signal!(string, int);\n\n  private :\n    int _value;\n}\n\nvoid test1()\n{\n    Foo a = new Foo;\n    Observer o = new Observer;\n\n    a.value = 3;                // should not call o.watch()\n    a.connect(&o.watch);        // o.watch is the slot\n    a.value = 4;                // should call o.watch()\n    a.disconnect(&o.watch);     // o.watch is no longer a slot\n    a.value = 5;                // so should not call o.watch()\n    a.connect(&o.watch);        // connect again\n    a.value = 6;                // should call o.watch()\n    delete o;                   // destroying o should automatically disconnect it\n    a.value = 7;                // should not call o.watch()\n}\n\n/******************************************/\n\nclass Input\n{\n    mixin Signal!(int, int) click;\n    mixin Signal!(char) keyDown;\n}\n\nvoid test2()\n{\n    Observer o = new Observer();\n    Input a = new Input();\n    a.click.connect(&o.watch2);\n    a.click.emit(5,6);\n}\n\n/******************************************/\n\nclass Args3\n{\n        int foo;\n}\n\nclass Base3\n{\n        ~this()\n        {\n                writefln(\"Base3 dtor!\");\n        }\n}\n\nclass Test3 : Base3\n{\n        mixin Signal!(Args3) A;\n        mixin Signal!(Args3) B;\n\n        ~this()\n        {\n                writefln(\"Test3 dtor\");\n        }\n}\n\n\nvoid test3()\n{\n        auto test = new Test3;\n}\n\n\n/******************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testsocket.d",
    "content": "// PERMUTE_ARGS:\n\nimport std.stdio;\nimport std.socket;\n\nclass Connection\n{\n        private\n        {\n                Socket sock;\n        }\n\n        void connect (string host, ushort port)\n        {\n                sock.connect (new InternetAddress (host, port));\n        }\n\n        void poll ()\n        {\n                SocketSet rset = new SocketSet (1); /** XXX: here is the bug */\n\n                rset.reset ();\n                rset.add (sock);\n        }\n\n        this ()\n        {\n\n                sock = new TcpSocket;\n                sock.blocking = false;\n        }\n}\n\nint main ()\n{\n        try\n        {\n            Connection ns;\n            ns = new Connection ();\n            ns.connect (\"localhost\", 80);\n            ns.poll ();\n            delete ns;\n        }\n        catch(SocketException e)\n        {\n        }\n        return 0;\n}\n\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/teststdio.d",
    "content": "// PERMUTE_ARGS:\n// EXTRA_FILES: extra-files/teststdio.txt\n\nimport std.stdio;\nimport core.stdc.stdio;\n\nvoid main()\n{\n    auto f = std.stdio.File(\"runnable/extra-files/teststdio.txt\", \"r\");\n    FILE* fp = f.getFP();\n    string buf;\n    int i;\n    do\n    {\n        buf = f.readln('\\n');\n        foreach (c; buf)\n            printf(\"%x\\n\", c);\n        printf(\"\\n\");\n        switch (i)\n        {\n            case 0:     assert(buf == \"asdfasdf\\n\"); break;\n            case 1:     assert(buf == \"a\\n\"); break;\n            case 2:     assert(buf == \"sdf\\n\"); break;\n            case 3:     assert(buf == \"asdf\\n\"); break;\n            case 4:     assert(buf == \"\\n\"); break;\n            case 5:     assert(buf == \"\\n\"); break;\n            case 6:     assert(buf == null); break;\n            default:    assert(0);\n        }\n        i++;\n    } while (!feof(fp));\n    //fclose(fp);\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testswitch.d",
    "content": "// PERMUTE_ARGS: -w\n\nextern(C) int printf(const char*, ...);\n\nint testswitch(string h)\n{\n    int x;\n\n    switch (h)\n    {\n        case \"abc\":\n            printf(\"abc\\n\");\n            x = 4;\n            break;\n        case \"foo\":\n            printf(\"foo\\n\");\n            x = 1;\n            break;\n        case \"bar\":\n            printf(\"bar\\n\");\n            x = 2;\n            break;\n        default:\n            printf(\"default\\n\");\n            x = 3;\n            break;\n    }\n    return x;\n}\n\nvoid test1()\n{\n    int i;\n\n    i = testswitch(\"foo\");\n    printf(\"i = %d\\n\", i);\n    assert(i == 1);\n    assert(testswitch(\"abc\") == 4);\n    assert(testswitch(\"bar\") == 2);\n    assert(testswitch(\"hello\") == 3);\n    printf(\"Success\\n\");\n}\n\n/*****************************************/\n\nvoid test2()\n{\n    int i;\n\n    switch (5)\n    {\n        case 3,4,5,6:\n            i = 20;\n            break;\n\n        case 7:\n        default:\n            assert(0);\n    }\n    assert(i == 20);\n}\n\n\n/*****************************************/\n\nvoid test3()\n{\n    int i;\n\n    switch (5)\n    {\n        case 7:\n            i = 6;\n            goto default;\n        default:\n            i = 8;\n            break;\n\n        case 3,4,5,6:\n            i = 20;\n            goto default;\n    }\n    assert(i == 8);\n}\n\n\n/*****************************************/\n\nvoid test4()\n{   int i;\n\n    switch (5)\n    {\n        case 3,4,5,6:\n            i = 20;\n            goto default;\n\n        case 7:\n            i = 6;\n            goto default;\n\n        default:\n            i = 8;\n            break;\n    }\n    assert(i == 8);\n}\n\n\n/*****************************************/\n\nvoid test5()\n{   int i;\n\n    switch (5)\n    {\n        case 7:\n            i = 6;\n            goto case;\n        default:\n            i = 8;\n            break;\n\n        case 3,4,5,6:\n            i = 20;\n            break;\n    }\n    assert(i == 20);\n}\n\n\n/*****************************************/\n\nvoid test6()\n{\n    int i;\n\n    switch (5)\n    {\n        case 7:\n            i = 6;\n            goto case 4;\n        default:\n            i = 8;\n            break;\n\n        case 3,4,5,6:\n            i = 20;\n            break;\n    }\n    assert(i == 20);\n}\n\n\n/*****************************************/\n\nvoid test7()\n{\n    int i;\n\n    switch (5)\n    {\n        case 3,4,5,6:\n            i = 20;\n            break;\n\n        case 7:\n            i = 6;\n            goto case 4;\n        default:\n            i = 8;\n            break;\n    }\n    assert(i == 20);\n}\n\n\n/*****************************************/\n\nvoid test8()\n{\n    dstring str = \"xyz\";\n    switch (str)\n    {\n        case \"xyz\":\n            printf(\"correct\\n\");\n            return;\n\n        case \"abc\":\n            break;\n\n        default:\n            assert(0);\n    }\n    assert(0);\n}\n\n/*****************************************/\n\nvoid test9()\n{\n    int i = 1;\n\n    switch(i)\n    {\n        case 2:\n            return;\n        case 1:\n            switch(i)\n            {\n                case 1:\n                    goto case 2;\n                default:\n                    assert(0);\n            }\n        default:\n            assert(0);\n    }\n    assert(0);\n}\n\n/*****************************************/\n\nvoid test10()\n{\n    int id1 = 0;\n    int id;\n    switch (id1)\n    {\n        case 0: ++id; goto case;\n        case 7: ++id; goto case;\n        case 6: ++id; goto case;\n        case 5: ++id; goto case;\n        case 4: ++id; goto case;\n        case 3: ++id; goto case;\n        case 2: ++id; goto case;\n        case 1: ++id; goto default;\n        default:\n            break;\n    }\n    assert(id == 8);\n}\n\n/*****************************************/\n\nvoid test11()\n{\n    long foo = 4;\n    switch (foo)\n    {\n        case 2: assert (false);\n        case 3: break;\n        case 4: break;\n        case 5: break;\n        default: assert(0);\n    }\n}\n\n/*****************************************/\n\nvoid test12()\n{\n    switch(\"#!\")\n    {\n        case \"#!\": printf(\"----Found #!\\n\");    break;\n        case \"\\xFF\\xFE\"c:                       break;\n        default:\n            assert(0);\n    }\n}\n\n/*****************************************/\n\nvoid test13()\n{\n    switch(\"#!\")\n    {\n        case \"#!\": printf(\"----Found #!\\n\");    break;\n        case \"#\\xFE\"c:                          break;\n        default:\n            assert(0);\n    }\n}\n\n/*****************************************/\n\nvoid foo14(A...)(int i)\n{\n    switch (i)\n    {\n            foreach(a; A)\n            {\n                goto case;\n            case a:\n                printf(\"%d\\n\", a);\n            }\n            break;\n        default:\n            assert(0);\n    }\n}\n\nvoid bar14(A...)(int i)\n{\n    switch (i)\n    {\n        foreach(j, a; A)\n        {\n            goto case;\n        case A[j]:\n            printf(\"a = %d, A[%d] = %d\\n\", a, j, A[j]);\n        }\n        break;\n    default:\n        assert(0);\n    }\n}\n\nvoid test14()\n{\n    foo14!(1,2,3,4,5)(1);\n    bar14!(1,2,3,4,5)(1);\n}\n\n/*****************************************/\n\nconst int X15;\nimmutable int Y15;\nconst int Z15;\n\nint foo15(int i)\n{\n    auto y = 1;\n    switch (i)\n    {\n        case X15:\n            y += 1;\n            goto case;\n        case 3:\n            y += 2;\n            break;\n        case Y15:\n            y += 20;\n            goto case;\n        case Z15:\n            y += 10;\n            break;\n        default:\n            y += 4;\n            break;\n    }\n    printf(\"y = %d\\n\", y);\n    return y;\n}\n\nstatic this()\n{\n    X15 = 4;\n    Y15 = 4;\n    Z15 = 5;\n}\n\nvoid test15()\n{\n    auto i = foo15(3);\n    assert(i == 3);\n    i = foo15(4);\n    assert(i == 4);\n    i = foo15(7);\n    assert(i == 5);\n    i = foo15(5);\n    assert(i == 11);\n}\n\n/*****************************************/\n\nenum E16\n{\n    A,B,C\n}\n\nvoid test16()\n{\n    E16 e = E16.A;\n    final switch (e)\n    {\n        case E16.A:\n        case E16.B:\n        case E16.C:\n        {}\n    }\n}\n\n/*****************************************/\n\nvoid test17()\n{\n    int i = 2;\n    switch (i)\n    {\n        case 1: .. case 3:\n            i = 5;\n            break;\n        default:\n            assert(0);\n    }\n    if (i != 5)\n        assert(0);\n\n    switch (i)\n    {\n        case 1: .. case 3:\n            i = 4;\n            break;\n        case 5:\n            i = 6;\n            break;\n        default:\n            assert(0);\n    }\n    if (i != 6)\n        assert(0);\n}\n\n/*****************************************/\n\nint test19()\n{\n    enum foo{ bar }\n    foo x;\n    final switch(x){ case foo.bar: return 0; }\n}\n\n/*****************************************/\n\nvoid test20()\n{\n    switch(1)\n    {\n        mixin(\"case 0:{}\");\n        case 1:\n        case 2:\n        default:\n    }\n}\n\n/*****************************************/\n\nvoid hang3139(int x)\n{\n   switch(x) {\n        case -9: .. case -1:\n        default:\n   }\n}\n\nint wrongcode3139(int x)\n{\n   switch(x) {\n        case -9: .. case 2: return 3;\n        default:\n        return 4;\n   }\n}\n\nstatic assert(wrongcode3139(-5)==3);\n\n// https://issues.dlang.org/show_bug.cgi?id=3139\nstatic assert(!is(typeof(\n        (long x) { switch(x) { case long.max: .. case -long.max:\n        default:} return 4; }(3)\n   )));\n\n\n/*****************************************/\n\nvoid test7358()\n{\n    static void test7358a()\n    {\n        enum X { A = 1, B = 2 }\n\n        auto x = X.A | X.B;\n\n        final switch(x)\n        {\n        case X.A:\n        case X.B:\n            break;\n        }\n    }\n\n    bool exception;\n    try\n        test7358a();\n    catch (Error)\n        exception = true;\n    assert(exception);\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9263\n\nvoid test9263()\n{\n    enum Foo { A }\n\n    Foo f;\n    final switch (f) with(Foo)\n    {\n        case A:\n            return;\n    }\n}\n\n/*****************************************/\n\nint bar21(int i)\n{\n    switch (i)\n    {\n//      case 1: return 11;\n        case 2: return 12;\n        case 3: return 13;\n        case 4: return 14;\n        case 5: return 15;\n        case 6: return 16;\n        case 7: return 17;\n        case 8: return 18;\n        case 9: return 19;\n        case 10: return 20;\n        default: break;\n    }\n\n    switch (i)\n    {\n        case 11: return 21;\n        case 12: return 22;\n        case 13: return 23;\n        case 14: return 24;\n        case 15: return 25;\n        case 16: return 26;\n        case 17: return 27;\n        case 18: return 28;\n        case 19: return 29;\n        case 20: return 30;\n        default: return 31;\n    }\n}\n\nvoid test21()\n{\n//      int j = bar(12);\n//      printf(\"j = %d\\n\", j);\n\n    for (int i = 2; i < 21; i++)\n    {\n        int j = bar21(i);\n        //printf(\"j = %d\\n\", j);\n        assert(j == i + 10);\n    }\n}\n\n/*****************************************/\n\nint bar22(int i)\n{\n    switch (i)\n    {\n        case 1: return i + 1;\n        case 10: return i + 2;\n        case 20: return i + 3;\n        case 50: return i + 4;\n        case 1000: return i + 5;\n        default: return 28;\n    }\n}\n\nvoid test22()\n{\n    assert(bar22(1) == 2);\n    assert(bar22(10) == 12);\n    assert(bar22(20) == 23);\n    assert(bar22(50) == 54);\n    assert(bar22(1000) == 1005);\n    assert(bar22(0) == 28);\n    assert(bar22(5) == 28);\n    assert(bar22(15) == 28);\n    assert(bar22(25) == 28);\n    assert(bar22(58) == 28);\n    assert(bar22(2000) == 28);\n}\n\n/*****************************************/\n\nlong bar23(long i)\n{\n    switch (i)\n    {\n        case 1: return i + 1;\n        case 0x10_0000_0000L: return i + 2;\n        case 0x20_0070_0000L: return i + 3;\n        case 0x50_0000_0000L: return i + 4;\n        case 0x1000_0000_8000L: return i + 5;\n        default: return 28;\n    }\n}\n\nvoid test23()\n{\n    assert(bar23(1) == 2);\n    assert(bar23(0x10_0000_0000L) == 0x10_0000_0000L + 2);\n    assert(bar23(0x20_0070_0000L) == 0x20_0070_0000L + 3);\n    assert(bar23(0x50_0000_0000L) == 0x50_0000_0000L + 4);\n    assert(bar23(0x1000_0000_8000L) == 0x1000_0000_8000L + 5);\n    assert(bar23(0) == 28);\n    assert(bar23(58) == 28);\n    assert(bar23(0x10_0000_0000L+1) == 28);\n    assert(bar23(0x20_0070_0000L+5) == 28);\n    assert(bar23(0x50_0000_0000L+25) == 28);\n    assert(bar23(0x1000_0000_8000L+1) == 28);\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14352\n\nint transmogrify14352(int input)\n{\n    int output = 0;\n    switch (input)\n    {\n        case 0, 1:\n            if (input == 0)\n                goto case;\n            else\n                output++;\n            goto case;\n        case 2:\n            output += 5;\n            goto case;\n        case 3:\n            output += 5;\n            break;\n        case 4, 5, 6:\n            goto default;\n        case 7:\n        case 8:\n            output += 20;\n            break;\n        default:\n            return -1;\n    }\n    return output;\n}\n\nvoid test14352()\n{\n    assert(transmogrify14352(0) == 10);\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14587\n// DMD 2.067.1 generating crashing binary on OSX\n\nstruct Card {\n    int value;\n    int suit;\n}\n\nvoid foo14587(Card card) {\n    switch(card.value) {\n    case 4: case 5: case 6: case 11:\n        break;\n    default:\n    }\n}\n\nvoid test14587() {\n    auto card = Card(11, 1);\n    foo14587(card);\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15396\n// static immutable not recognized as constant within switch statement\n\nvoid test15396()\n{\n    static immutable Foo = \"Foobar\";\n    static const Bar = \"BarFoo\";\n\n    foreach (var; [ \"Foobar\", \"BarFoo\" ])\n    {\n        switch (var)\n        {\n        case Foo:\n            break;\n        case Bar:\n            break;\n        default:\n            assert(0, \"test15396 failed\");\n        }\n    }\n}\n\n/*****************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15538\n\nstruct S15538\n{\n    int a = 0;\n    int b = 1;\n}\n\nint f15538(S15538 s)\n{\n    switch (s.a)\n    {\n        case 0: return 10;\n        case 1: return 20;\n        case 2: return 30;\n        case 3: return 40;\n        default: return 99;\n    }\n}\n\nvoid test15538()\n{\n    S15538 s;\n    assert(f15538(s) == 10); /* fails */\n}\n\n/*****************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test19();\n    test20();\n    test7358();\n    test9263();\n    test21();\n    test22();\n    test23();\n    test14352();\n    test14587();\n    test15396();\n    test15538();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testthread.d",
    "content": "// PERMUTE_ARGS:\n\nimport core.stdc.stdio;\nimport core.thread;\n\nversion (CRuntime_DigitalMars)\n{\n    extern (C)\n    {\n        extern int _tlsstart;\n        extern int _tlsend;\n    }\n}\n\nint tlsx;\n\nclass Foo\n{\n    int x;\n\n    void bar()\n    {\n        printf(\"bar()\\n\");\n        assert(tlsx == 0);\n        tlsx = 5;\n        Thread t = Thread.getThis();\n\n        version (CRuntime_DigitalMars)\n            printf(\"thread ptr=%p, %p &tlsx = %p %p\\n\", t, &_tlsstart, &tlsx, &_tlsend);\n        x = 3;\n        printf(\"-bar()\\n\");\n    }\n}\n\n\nint main()\n{\n    Foo f = new Foo();\n\n    Thread t = new Thread(&f.bar);\n    t.start();\n    printf(\"t.start() done\\n\");\n    // There is no analog for these in druntime.\n    //t.pause();\n    //t.resume();\n    Thread.yield();\n    t.join();\n    printf(\"Done waiting\\n\");\n    assert(f.x == 3);\n\n    int i;\n    Thread[5] tx;\n    for (i = 0; i < tx.length; i++)\n        tx[i] = new Thread(&f.bar);\n    for (i = 0; i < tx.length; i++)\n        tx[i].start();\n    for (i = 0; i < tx.length; i++)\n        tx[i].join();\n    Thread.sleep(dur!\"msecs\"(1));\n\n    printf(\"**Success**\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testthread2.d",
    "content": "// PERMUTE_ARGS:\n\nimport std.algorithm : map;\nimport std.random : Random, uniform, unpredictableSeed;\nimport std.range : repeat;\nimport std.stdio : writeln;\n\n// Quick, dirty and inefficient AA using linear search, useful for testing.\nstruct LinearAA(K, V) {\n    K[] keys;\n    V[] values;\n\n    V opIndex(K key) {\n        foreach(i, k; keys) {\n            if(k == key) {\n                return values[i];\n            }\n        }\n\n        assert(0, \"Key not present.\");\n    }\n\n    V opIndexAssign(V val, K key) {\n        foreach(i, k; keys) {\n            if(k == key) {\n                return values[i] = val;\n            }\n        }\n\n        keys ~= key;\n        values ~= val;\n        return val;\n    }\n\n    V* opIn_r(K key) {\n        foreach(i, k; keys) {\n            if(key == k) {\n                return values.ptr + i;\n            }\n        }\n\n        return null;\n    }\n\n    void remove(K key) {\n        size_t i = 0;\n        for(; i < keys.length; i++) {\n            if(keys[i] == key) {\n                break;\n            }\n        }\n\n        assert(i < keys.length);\n\n        for(; i < keys.length - 1; i++) {\n            keys[i] = keys[i + 1];\n            values[i] = values[i + 1];\n        }\n\n        keys = keys[0..$ - 1];\n        values = values[0..$ - 1];\n    }\n\n    size_t length() {\n        return values.length;\n    }\n}\n\nvoid main() {\n    Random gen;\n    uint[] seed;\n    gen.seed(map!((a) {\n        seed ~= unpredictableSeed;\n        return seed[$-1]; })(repeat(0)));\n    writeln(seed);\n    foreach(iter; 0..10) {  // Bug only happens after a few iterations.\n        writeln(iter);\n        uint[size_t] builtin;\n        LinearAA!(size_t, uint) linAA;\n        uint[] nums = new uint[100_000];\n        foreach(ref num; nums) {\n            num = uniform(0U, uint.max, gen);\n        }\n\n        foreach(i; 0..10_000) {\n            auto index = uniform(0, nums.length, gen);\n            if(index in builtin) {\n                assert(index in linAA);\n                assert(builtin[index] == nums[index]);\n                assert(linAA[index] == nums[index]);\n                builtin.remove(index);\n                linAA.remove(index);\n            } else {\n                assert(!(index in linAA));\n                builtin[index] = nums[index];\n                linAA[index] = nums[index];\n            }\n        }\n\n        assert(builtin.length == linAA.length);\n        foreach(k, v; builtin) {\n            assert(k in linAA);\n            assert(*(k in builtin) == *(k in linAA));\n            assert(linAA[k] == v);\n        }\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testtypeid.d",
    "content": "\nimport core.vararg;\nimport std.stdio;\n\n/******************************************************/\n\nvoid test2()\n{\n    assert(typeid(int) == typeid(int));\n    assert(typeid(int) != typeid(uint));\n}\n\n/******************************************************/\n\nclass FOO3 { }\n\nFOO3 foox3;\n\nvoid foo3(int x, ...)\n{\n    printf(\"%d arguments\\n\", _arguments.length);\n    for (int i = 0; i < _arguments.length; i++)\n    {\n        writeln(_arguments[i].toString());\n\n        if (_arguments[i] is typeid(int))\n        {\n            int j = va_arg!int(_argptr);\n            printf(\"\\t%d\\n\", j);\n            assert(j == 2);\n        }\n        else if (_arguments[i] == typeid(long))\n        {\n            long j = va_arg!long(_argptr);\n            printf(\"\\t%lld\\n\", j);\n            assert(j == 3);\n        }\n        else if (_arguments[i] is typeid(double))\n        {\n            double d = va_arg!double(_argptr);\n            printf(\"\\t%g\\n\", d);\n            assert(d == 4.5);\n        }\n        else if (_arguments[i] is typeid(FOO3))\n        {\n            FOO3 f = va_arg!FOO3(_argptr);\n            printf(\"\\t%p\\n\", f);\n            assert(f is foox3);\n        }\n        else\n            assert(0);\n    }\n}\n\nvoid test3()\n{\n    FOO3 f = new FOO3();\n\n    printf(\"\\t%p\\n\", f);\n    foox3 = f;\n\n    foo3(1,2,3L,4.5,f);\n    foo3(1,2,3L,4.5,f);\n}\n\n/******************************************************/\n\nvoid test4()\n{\n    TypeInfo ti;\n\n    ti = typeid(float[]);\n    assert(!(ti is null));\n    ti = typeid(double[]);\n    assert(!(ti is null));\n    ti = typeid(real[]);\n    assert(!(ti is null));\n\n    ti = typeid(ifloat[]);\n    assert(!(ti is null));\n    ti = typeid(idouble[]);\n    assert(!(ti is null));\n    ti = typeid(ireal[]);\n    assert(!(ti is null));\n\n    ti = typeid(cfloat[]);\n    assert(!(ti is null));\n    ti = typeid(cdouble[]);\n    assert(!(ti is null));\n    ti = typeid(creal[]);\n    assert(!(ti is null));\n\n    ti = typeid(void);\n    assert(!(ti is null));\n    ti = typeid(void[]);\n    assert(!(ti is null));\n    ti = typeid(bool[]);\n    assert(!(ti is null));\n}\n\n/******************************************************/\n\nvoid test6()\n{\n    TypeInfo ti = typeid(void*);\n    assert(!(ti is null));\n    assert(ti.tsize==(void*).sizeof);\n    assert(ti.toString()==\"void*\");\n}\n\n/******************************************************/\n\nvoid test7()\n{\n    TypeInfo ti = typeid(bool*);\n    assert(!(ti is null));\n    assert(ti.tsize==(bool*).sizeof);\n    assert(ti.toString()==\"bool*\");\n}\n\n/******************************************************/\n\nvoid test8()\n{\n    TypeInfo ti = typeid(byte*);\n    assert(!(ti is null));\n    assert(ti.tsize==(byte*).sizeof);\n    assert(ti.toString()==\"byte*\");\n}\n\n/******************************************************/\n\nvoid test9()\n{\n    TypeInfo ti = typeid(byte[]);\n    assert(!(ti is null));\n    assert(ti.tsize==(byte[]).sizeof);\n    assert(ti.toString()==\"byte[]\");\n}\n\n/******************************************************/\n\nvoid test10()\n{\n    TypeInfo ti = typeid(short*);\n    assert(!(ti is null));\n    assert(ti.tsize==(short*).sizeof);\n    assert(ti.toString()==\"short*\");\n}\n\n/******************************************************/\n\nvoid test11()\n{\n    TypeInfo ti = typeid(ushort*);\n    assert(!(ti is null));\n    assert(ti.tsize==(ushort*).sizeof);\n    assert(ti.toString()==\"ushort*\");\n}\n\n/******************************************************/\n\nvoid test12()\n{\n    TypeInfo ti = typeid(int*);\n    assert(!(ti is null));\n    assert(ti.tsize==(int*).sizeof);\n    assert(ti.toString()==\"int*\");\n}\n\n/******************************************************/\n\nvoid test13()\n{\n    TypeInfo ti = typeid(uint*);\n    assert(!(ti is null));\n    assert(ti.tsize==(uint*).sizeof);\n    assert(ti.toString()==\"uint*\");\n}\n\n/******************************************************/\n\nvoid test14()\n{\n    TypeInfo ti = typeid(ulong*);\n    assert(!(ti is null));\n    assert(ti.tsize==(ulong*).sizeof);\n    assert(ti.toString()==\"ulong*\");\n}\n\n/******************************************************/\n\nvoid test15()\n{\n    TypeInfo ti = typeid(long*);\n    assert(!(ti is null));\n    assert(ti.tsize==(long*).sizeof);\n    assert(ti.toString()==\"long*\");\n}\n\n/******************************************************/\n\nvoid test16()\n{\n    TypeInfo ti = typeid(float*);\n    assert(!(ti is null));\n    assert(ti.tsize==(float*).sizeof);\n    assert(ti.toString()==\"float*\");\n}\n\n/******************************************************/\n\nvoid test17()\n{\n    TypeInfo ti = typeid(ifloat*);\n    assert(!(ti is null));\n    assert(ti.tsize==(ifloat*).sizeof);\n    assert(ti.toString()==\"ifloat*\");\n}\n\n/******************************************************/\n\nvoid test18()\n{\n    TypeInfo ti = typeid(cfloat*);\n    assert(!(ti is null));\n    assert(ti.tsize==(cfloat*).sizeof);\n    assert(ti.toString()==\"cfloat*\");\n}\n\n/******************************************************/\n\nvoid test19()\n{\n    TypeInfo ti = typeid(double*);\n    assert(!(ti is null));\n    assert(ti.tsize==(double*).sizeof);\n    assert(ti.toString()==\"double*\");\n}\n\n/******************************************************/\n\nvoid test20()\n{\n    TypeInfo ti = typeid(idouble*);\n    assert(!(ti is null));\n    assert(ti.tsize==(idouble*).sizeof);\n    assert(ti.toString()==\"idouble*\");\n}\n\n/******************************************************/\n\nvoid test21()\n{\n    TypeInfo ti = typeid(cdouble*);\n    assert(!(ti is null));\n    assert(ti.tsize==(cdouble*).sizeof);\n    assert(ti.toString()==\"cdouble*\");\n}\n\n/******************************************************/\n\nvoid test22()\n{\n    TypeInfo ti = typeid(real*);\n    assert(!(ti is null));\n    assert(ti.tsize==(real*).sizeof);\n    assert(ti.toString()==\"real*\");\n}\n\n/******************************************************/\n\nvoid test23()\n{\n    TypeInfo ti = typeid(ireal*);\n    assert(!(ti is null));\n    assert(ti.tsize==(ireal*).sizeof);\n    assert(ti.toString()==\"ireal*\");\n}\n\n/******************************************************/\n\nvoid test24()\n{\n    TypeInfo ti = typeid(creal*);\n    assert(!(ti is null));\n    assert(ti.tsize==(creal*).sizeof);\n    assert(ti.toString()==\"creal*\");\n}\n\n/******************************************************/\n\nvoid test25()\n{\n    TypeInfo ti = typeid(char*);\n    assert(!(ti is null));\n    assert(ti.tsize==(char*).sizeof);\n    assert(ti.toString()==\"char*\");\n}\n\n/******************************************************/\n\nvoid test26()\n{\n    TypeInfo ti = typeid(wchar*);\n    assert(!(ti is null));\n    assert(ti.tsize==(wchar*).sizeof);\n    assert(ti.toString()==\"wchar*\");\n}\n\n/******************************************************/\n\nvoid test27()\n{\n    TypeInfo ti = typeid(dchar*);\n    assert(!(ti is null));\n    assert(ti.tsize==(dchar*).sizeof);\n    assert(ti.toString()==\"dchar*\");\n}\n\n/******************************************************/\n\nenum MyEnum { A, B }\n\nvoid test28()\n{\n    TypeInfo ti = typeid(MyEnum);\n    assert(!(ti is null));\n    assert(ti.tsize==(MyEnum).sizeof);\n    assert(ti.toString()==\"testtypeid.MyEnum\");\n}\n\n/******************************************************/\n\nvoid test29()\n{\n    alias void function() func;\n    TypeInfo ti = typeid(func);\n    assert(ti !is null);\n    assert(ti.tsize == func.sizeof);\n}\n\n/******************************************************/\n\nvoid test30()\n{\n    alias int delegate() del;\n    TypeInfo ti = typeid(del);\n    assert(ti !is null);\n    assert(ti.tsize == del.sizeof);\n}\n\n/******************************************************/\n\nvoid test31()\n{\n    TypeInfo ti = typeid(void);\n    assert(!(ti is null));\n    assert(ti.tsize == void.sizeof);\n    assert(ti.toString()==\"void\");\n}\n\n/******************************************************/\n\nclass Foo32 { int x = 3; }\nclass Bar32 { long y = 4; }\n\nvoid printargs(int x, ...)\n{\n    printf(\"%d arguments\\n\", _arguments.length);\n    for (int i = 0; i < _arguments.length; i++)\n    {\n        writeln(_arguments[i].toString());\n\n        if (_arguments[i] == typeid(int))\n        {\n            int j = va_arg!int(_argptr);\n            printf(\"\\t%d\\n\", j);\n        }\n        else if (_arguments[i] == typeid(long))\n        {\n            long j = va_arg!long(_argptr);\n            printf(\"\\t%lld\\n\", j);\n        }\n        else if (_arguments[i] == typeid(double))\n        {\n            double d = va_arg!double(_argptr);\n            printf(\"\\t%g\\n\", d);\n        }\n        else if (_arguments[i] == typeid(Foo32))\n        {\n            Foo32 f = va_arg!Foo32(_argptr);\n            assert(f.x == 3);\n            printf(\"\\t%p\\n\", f);\n        }\n        else if (_arguments[i] == typeid(Bar32))\n        {\n            Bar32 b = va_arg!Bar32(_argptr);\n            assert(b.y == 4);\n            printf(\"\\t%p\\n\", b);\n        }\n        else\n            assert(0);\n    }\n}\n\nvoid test32()\n{\n    Foo32 f = new Foo32();\n    Bar32 b = new Bar32();\n\n    printf(\"%p\\n\", f);\n    printargs(1, 2, 3L, 4.5, f, b);\n}\n\n/******************************************************/\n\nvoid test33()\n{\n}\n\n/******************************************************/\n\nvoid test34()\n{\n    class C { }\n    C c;\n    auto a = typeid(C).info;\n}\n\n/******************************************************/\n\nvoid test35()\n{\n    auto ti = typeid(shared(int));\n\n    auto sti = cast(TypeInfo_Shared)ti;\n    assert(sti);\n\n    // allow both next and base as field names in TypeInfo_Const\n    static if (is(typeof(&sti.base) == TypeInfo*))\n        assert(sti.base == typeid(int));\n    else\n        assert(sti.next == typeid(int));\n}\n\n/******************************************************/\n\nvoid test36()\n{\n    int i;\n    assert(typeid(i++) == typeid(int));\n    assert(i == 1);\n    assert(typeid(i + 1) == typeid(int));\n}\n\n/******************************************************/\n\nclass A37 {}\nclass B37 : A37 {}\n\nvoid test37()\n{\n    auto a = new B37;\n    //writeln(typeid(A));\n    assert(typeid(a) == typeid(B37));\n}\n\n/******************************************************/\n\nvoid test38()\n{\n    static if (is(cent))\n    {\n        TypeInfo ti = typeid(cent*);\n        assert(!(ti is null));\n        assert(ti.tsize==(cent*).sizeof);\n        assert(ti.toString()==\"cent*\");\n    }\n}\n\n/******************************************************/\n\nvoid test39()\n{\n    static if (is(ucent))\n    {\n        TypeInfo ti = typeid(ucent*);\n        assert(!(ti is null));\n        assert(ti.tsize==(ucent*).sizeof);\n        assert(ti.toString()==\"ucent*\");\n    }\n}\n\n/******************************************************/\n\nvoid test40()\n{\n    static if (is(cent))\n    {\n        cent i;\n        assert(typeid(i++) == typeid(cent));\n        assert(i == 1);\n        assert(typeid(i + 1) == typeid(cent));\n    }\n}\n\n/******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9442\n\nclass C\n{\n    this()\n    {\n        c = this;\n        auto x = typeid(c);         // NG\n        auto y = typeid(this.c);    // ok\n    }\n\n    C c;\n}\n\nvoid test9442()\n{\n    auto c = new C();\n}\n\n/******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10451\n\nstruct Foo10451;\n\nstruct Bar10451\n{\n    Foo10451*[] foos;\n}\n\nvoid test10451()\n{\n    Foo10451*[] foos = [];\n    foos ~= null;\n    foos = new Foo10451*[2];\n}\n\n/******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11010\n\nstruct S11010 { S11010* p; }\n\nclass C11010 { C11010 p; }\nclass D11010 : C11010 {}\n\nvoid test11010()\n{\n    TypeInfo ti;\n\n    S11010 s;\n    ti = typeid(s.p);\n    assert(cast(TypeInfo_Pointer)ti !is null);\n    assert(ti.toString() == \"testtypeid.S11010*\");\n\n    C11010 c = new C11010();\n    c.p = new D11010();\n    ti = typeid(c.p);\n    assert(cast(TypeInfo_Class)ti !is null);\n    assert(ti.toString() == \"testtypeid.D11010\");\n}\n\n/******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13045\n\nvoid test13045a()\n{\n    static struct S\n    {\n        int[] a;\n    }\n\n    auto s1 = S([1,2]);\n    auto s2 = S([1,2]);\n    assert(s1 !is s2);\n    assert(s1 == s2);\n    assert(typeid(S).getHash(&s1) == typeid(S).getHash(&s2));   // should succeed\n}\n\nvoid test13045b()\n{\n    bool thrown(T)(lazy T cond)\n    {\n        import core.exception;\n        try\n            cond();\n        catch (Error e)\n            return true;\n        return false;\n    }\n\n    struct S\n    {\n        size_t toHash() const nothrow @safe\n        {\n            // all getHash call should reach here\n            throw new Error(\"\");\n        }\n    }\n    struct T\n    {\n        S s;\n    }\n    S s;\n    assert(thrown(typeid(S).getHash(&s)));      // OK\n    S[1] ssa;\n    assert(thrown(typeid(S[1]).getHash(&ssa))); // OK\n    S[] sda = [S(), S()];\n    assert(thrown(typeid(S[]).getHash(&sda)));  // OK\n\n    T t;\n    assert(thrown(typeid(T).getHash(&t)));      // OK <- NG\n    T[1] tsa;\n    assert(thrown(typeid(T[1]).getHash(&tsa))); // OK <- NG\n    T[] tda = [T(), T()];\n    assert(thrown(typeid(T[]).getHash(&tda)));  // OK <- NG\n}\n\n/******************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15680\n\nvoid test15680()\n{\n    auto tid = typeid(null);\n    auto iz = tid.initializer();\n    assert(iz.length == typeof(null).sizeof);\n    assert(iz.ptr is null || *(cast(void**)iz.ptr) is null);\n}\n\n/******************************************************/\n\nint main()\n{\n    test2();\n    test3();\n    test4();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test9442();\n    test10451();\n    test11010();\n    test13045a();\n    test13045b();\n    test15680();\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/testv.d",
    "content": "\nextern(C) int printf(const char*, ...);\n\n/*********************************************************/\n\nint sum(int[] xx ...)\n{\n    int s;\n\n    foreach (int x; xx)\n        s += x;\n    return s;\n}\n\nvoid test1()\n{\n    static int[3] a = [5, 8, 10];\n    int[] b = a;\n    int i;\n\n    i = sum();\n    assert(i == 0);\n    i = sum(10);\n    assert(i == 10);\n    i = sum(10, 20);\n    assert(i == 30);\n    i = sum(11, 22, 34);\n    assert(i == 67);\n    i = sum(a);\n    assert(i == 23);\n    i = sum(b);\n    assert(i == 23);\n    printf(\"%d\\n\", sum());\n}\n\n/*********************************************************/\n\nint sum2(int[3] xx ...)\n{\n    int s;\n\n    foreach (int x; xx)\n        s += x;\n    return s;\n}\n\nvoid test2()\n{\n    static int[3] a = [5, 8, 10];\n    int i;\n\n    i = sum2(11, 22, 34);\n    assert(i == 67);\n    i = sum2(a);\n    assert(i == 23);\n    printf(\"%d\\n\", i);\n}\n\n/*********************************************************/\n\nint[4] bb3 = [5,6,7,8];\n\nint sum3(int[] xx = bb3 ...)\n{\n    int s;\n\n    foreach (int x; xx)\n        s += x;\n    return s;\n}\n\nvoid test3()\n{\n    static int[3] a = [5, 8, 10];\n    int i;\n\n    i = sum3(11, 22, 34);\n    assert(i == 67);\n    i = sum3(a);\n    assert(i == 23);\n    i = sum3();\n    assert(i == 26);\n    printf(\"%d\\n\", i);\n}\n\n/*********************************************************/\n\nclass Foo4\n{\n    int a;\n    float f;\n    double d;\n\n    this(int a, float f, double d)\n    {\n        this.a = a;\n        this.f = f;\n        this.d = d;\n    }\n}\n\nint sum4(Foo4 f ...)\n{\n    return cast(int)(f.a + f.f + f.d);\n}\n\nvoid test4()\n{\n    int i;\n    Foo4 foo = new Foo4(1, 2f, 3.0);\n\n    i = sum4(foo);\n    assert(i == 1+2+3);\n    i = sum4(4, 5f, 6.0);\n    assert(i == 4+5+6);\n\n    printf(\"%d\\n\", i);\n}\n\n/*********************************************************/\n\n\nvoid bug1993(int[][] y...)\n{\n}\nvoid test5()\n{\n    bug1993(null);\n    bug1993(null, null);\n    bug1993([0], null);\n    bug1993([0], [0]);\n    bug1993(null, [0]);\n}\n\n/*********************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/tls.d",
    "content": "// EXTRA_SOURCES: imports/tlsa.d\n\nimport core.stdc.stdio;\nimport imports.tlsa;\n\nint x = 3;\n\nvoid bar()\n{\n    int* px = &x;\n    assert(x == 3);\n    x++;\n    printf(\"x = %d\\n\", x);\n    px = &x;\n    printf(\"px = %p\\n\", px);\n    assert(*px == 4);\n    (*px)++;\n    assert(x == 5);\n}\n\n\nvoid test1()\n{\n    bar();\n    printf(\"%d\\n\", x);\n    printf(\"%d\\n\", foo!()());\n}\n\n/************************************/\n\nlong fooa;\nlong foob;\nint bara = 0x12345678;\nint barb = 0x9ABCDEFF;\n\nvoid test2()\n{\n    fooa++;\n    foob--;\n    bara++;\n    barb++;\n    printf(\"%lld %lld %x %x\\n\", fooa, foob, bara, barb);\n    assert(fooa == 1);\n    assert(foob == -1);\n    assert(bara == 0x12345679);\n    assert(barb == 0x9ABCDF00);\n}\n\n/************************************/\n\nint abc3(T)(T t)\n{\n    static T qqq;\n    static T rrr;\n    static T sss = 8;\n    static T ttt = 9;\n    printf(\"qqq = %d, rrr = %d, sss = %d, ttt = %d\\n\", qqq, rrr, sss, ttt);\n    assert(sss == 8);\n    assert(ttt == 9);\n    rrr += 7;\n    return t + ++qqq + rrr;\n}\n\nvoid test3()\n{\n    auto i = abc3(3);\n    printf(\"i = x%x\\n\", i);\n    assert(i == 11);\n    i = abc3(4);\n    printf(\"i = x%x\\n\", i);\n    assert(i == 20);\n}\n\n/************************************/\n\nvoid test4()\n{\n\n    auto i = bar4();\n    printf(\"i = x%x\\n\", i);\n    assert(i == 0x23);\n    i = abc4(4);\n    printf(\"i = x%x\\n\", i);\n    assert(i == 0x31);\n}\n\n/************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/tls_dup.d",
    "content": "// NOTE: this is a dup of runnable/tls.d strictly to test the same code compiled\n// separately rather than together like the original is.\n\n// COMPILE_SEPARATELY\n// EXTRA_SOURCES: imports/tlsa.d\n// PERMUTE_ARGS:\n\nimport core.stdc.stdio;\nimport imports.tlsa;\n\nint x = 3;\n\nvoid bar()\n{\n    int* px = &x;\n    assert(x == 3);\n    x++;\n    printf(\"x = %d\\n\", x);\n    px = &x;\n    printf(\"px = %p\\n\", px);\n    assert(*px == 4);\n    (*px)++;\n    assert(x == 5);\n}\n\n\nvoid test1()\n{\n    bar();\n    printf(\"%d\\n\", x);\n    printf(\"%d\\n\", foo!()());\n}\n\n/************************************/\n\nlong fooa;\nlong foob;\nint bara = 0x12345678;\nint barb = 0x9ABCDEFF;\n\nvoid test2()\n{\n    fooa++;\n    foob--;\n    bara++;\n    barb++;\n    printf(\"%lld %lld %x %x\\n\", fooa, foob, bara, barb);\n    assert(fooa == 1);\n    assert(foob == -1);\n    assert(bara == 0x12345679);\n    assert(barb == 0x9ABCDF00);\n}\n\n/************************************/\n\nint abc3(T)(T t)\n{\n    static T qqq;\n    static T rrr;\n    static T sss = 8;\n    static T ttt = 9;\n    printf(\"qqq = %d, rrr = %d, sss = %d, ttt = %d\\n\", qqq, rrr, sss, ttt);\n    assert(sss == 8);\n    assert(ttt == 9);\n    rrr += 7;\n    return t + ++qqq + rrr;\n}\n\nvoid test3()\n{\n    auto i = abc3(3);\n    printf(\"i = x%x\\n\", i);\n    assert(i == 11);\n    i = abc3(4);\n    printf(\"i = x%x\\n\", i);\n    assert(i == 20);\n}\n\n/************************************/\n\nvoid test4()\n{\n\n    auto i = bar4();\n    printf(\"i = x%x\\n\", i);\n    assert(i == 0x23);\n    i = abc4(4);\n    printf(\"i = x%x\\n\", i);\n    assert(i == 0x31);\n}\n\n/************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/traits.d",
    "content": "// PERMUTE_ARGS:\nmodule traits;\n\nimport std.stdio;\n\nalias int myint;\nstruct S { void bar() { } int x = 4; static int z = 5; }\nclass C { void bar() { } final void foo() { } static void abc() { } }\nabstract class AC { }\nclass AC2 { abstract void foo(); }\nclass AC3 : AC2 { }\nfinal class FC { void foo() { } }\nenum E { EMEM }\nstruct D1 { @disable void true_(); void false_(){} }\n\n/********************************************************/\n\nvoid test1()\n{\n    auto t = __traits(isArithmetic, int);\n    writeln(t);\n    assert(t == true);\n\n    assert(__traits(isArithmetic) == false);\n    assert(__traits(isArithmetic, myint) == true);\n    assert(__traits(isArithmetic, S) == false);\n    assert(__traits(isArithmetic, C) == false);\n    assert(__traits(isArithmetic, E) == true);\n    assert(__traits(isArithmetic, void*) == false);\n    assert(__traits(isArithmetic, void[]) == false);\n    assert(__traits(isArithmetic, void[3]) == false);\n    assert(__traits(isArithmetic, int[char]) == false);\n    assert(__traits(isArithmetic, int, int) == true);\n    assert(__traits(isArithmetic, int, S) == false);\n\n    assert(__traits(isArithmetic, void) == false);\n    assert(__traits(isArithmetic, byte) == true);\n    assert(__traits(isArithmetic, ubyte) == true);\n    assert(__traits(isArithmetic, short) == true);\n    assert(__traits(isArithmetic, ushort) == true);\n    assert(__traits(isArithmetic, int) == true);\n    assert(__traits(isArithmetic, uint) == true);\n    assert(__traits(isArithmetic, long) == true);\n    assert(__traits(isArithmetic, ulong) == true);\n    assert(__traits(isArithmetic, float) == true);\n    assert(__traits(isArithmetic, double) == true);\n    assert(__traits(isArithmetic, real) == true);\n    assert(__traits(isArithmetic, ifloat) == true);\n    assert(__traits(isArithmetic, idouble) == true);\n    assert(__traits(isArithmetic, ireal) == true);\n    assert(__traits(isArithmetic, cfloat) == true);\n    assert(__traits(isArithmetic, cdouble) == true);\n    assert(__traits(isArithmetic, creal) == true);\n    assert(__traits(isArithmetic, char) == true);\n    assert(__traits(isArithmetic, wchar) == true);\n    assert(__traits(isArithmetic, dchar) == true);\n\n    int i;\n    assert(__traits(isArithmetic, i, i+1, int) == true);\n    assert(__traits(isArithmetic) == false);\n}\n\n/********************************************************/\n\nvoid test2()\n{\n    auto t = __traits(isScalar, int);\n    writeln(t);\n    assert(t == true);\n\n    assert(__traits(isScalar) == false);\n    assert(__traits(isScalar, myint) == true);\n    assert(__traits(isScalar, S) == false);\n    assert(__traits(isScalar, C) == false);\n    assert(__traits(isScalar, E) == true);\n    assert(__traits(isScalar, void*) == true);\n    assert(__traits(isScalar, void[]) == false);\n    assert(__traits(isScalar, void[3]) == false);\n    assert(__traits(isScalar, int[char]) == false);\n    assert(__traits(isScalar, int, int) == true);\n    assert(__traits(isScalar, int, S) == false);\n\n    assert(__traits(isScalar, void) == false);\n    assert(__traits(isScalar, byte) == true);\n    assert(__traits(isScalar, ubyte) == true);\n    assert(__traits(isScalar, short) == true);\n    assert(__traits(isScalar, ushort) == true);\n    assert(__traits(isScalar, int) == true);\n    assert(__traits(isScalar, uint) == true);\n    assert(__traits(isScalar, long) == true);\n    assert(__traits(isScalar, ulong) == true);\n    assert(__traits(isScalar, float) == true);\n    assert(__traits(isScalar, double) == true);\n    assert(__traits(isScalar, real) == true);\n    assert(__traits(isScalar, ifloat) == true);\n    assert(__traits(isScalar, idouble) == true);\n    assert(__traits(isScalar, ireal) == true);\n    assert(__traits(isScalar, cfloat) == true);\n    assert(__traits(isScalar, cdouble) == true);\n    assert(__traits(isScalar, creal) == true);\n    assert(__traits(isScalar, char) == true);\n    assert(__traits(isScalar, wchar) == true);\n    assert(__traits(isScalar, dchar) == true);\n}\n\n/********************************************************/\n\nvoid test3()\n{\n    assert(__traits(isIntegral) == false);\n    assert(__traits(isIntegral, myint) == true);\n    assert(__traits(isIntegral, S) == false);\n    assert(__traits(isIntegral, C) == false);\n    assert(__traits(isIntegral, E) == true);\n    assert(__traits(isIntegral, void*) == false);\n    assert(__traits(isIntegral, void[]) == false);\n    assert(__traits(isIntegral, void[3]) == false);\n    assert(__traits(isIntegral, int[char]) == false);\n    assert(__traits(isIntegral, int, int) == true);\n    assert(__traits(isIntegral, int, S) == false);\n\n    assert(__traits(isIntegral, void) == false);\n    assert(__traits(isIntegral, byte) == true);\n    assert(__traits(isIntegral, ubyte) == true);\n    assert(__traits(isIntegral, short) == true);\n    assert(__traits(isIntegral, ushort) == true);\n    assert(__traits(isIntegral, int) == true);\n    assert(__traits(isIntegral, uint) == true);\n    assert(__traits(isIntegral, long) == true);\n    assert(__traits(isIntegral, ulong) == true);\n    assert(__traits(isIntegral, float) == false);\n    assert(__traits(isIntegral, double) == false);\n    assert(__traits(isIntegral, real) == false);\n    assert(__traits(isIntegral, ifloat) == false);\n    assert(__traits(isIntegral, idouble) == false);\n    assert(__traits(isIntegral, ireal) == false);\n    assert(__traits(isIntegral, cfloat) == false);\n    assert(__traits(isIntegral, cdouble) == false);\n    assert(__traits(isIntegral, creal) == false);\n    assert(__traits(isIntegral, char) == true);\n    assert(__traits(isIntegral, wchar) == true);\n    assert(__traits(isIntegral, dchar) == true);\n}\n\n/********************************************************/\n\nvoid test4()\n{\n    assert(__traits(isFloating) == false);\n    assert(__traits(isFloating, S) == false);\n    assert(__traits(isFloating, C) == false);\n    assert(__traits(isFloating, E) == false);\n    assert(__traits(isFloating, void*) == false);\n    assert(__traits(isFloating, void[]) == false);\n    assert(__traits(isFloating, void[3]) == false);\n    assert(__traits(isFloating, int[char]) == false);\n    assert(__traits(isFloating, float, float) == true);\n    assert(__traits(isFloating, float, S) == false);\n\n    assert(__traits(isFloating, void) == false);\n    assert(__traits(isFloating, byte) == false);\n    assert(__traits(isFloating, ubyte) == false);\n    assert(__traits(isFloating, short) == false);\n    assert(__traits(isFloating, ushort) == false);\n    assert(__traits(isFloating, int) == false);\n    assert(__traits(isFloating, uint) == false);\n    assert(__traits(isFloating, long) == false);\n    assert(__traits(isFloating, ulong) == false);\n    assert(__traits(isFloating, float) == true);\n    assert(__traits(isFloating, double) == true);\n    assert(__traits(isFloating, real) == true);\n    assert(__traits(isFloating, ifloat) == true);\n    assert(__traits(isFloating, idouble) == true);\n    assert(__traits(isFloating, ireal) == true);\n    assert(__traits(isFloating, cfloat) == true);\n    assert(__traits(isFloating, cdouble) == true);\n    assert(__traits(isFloating, creal) == true);\n    assert(__traits(isFloating, char) == false);\n    assert(__traits(isFloating, wchar) == false);\n    assert(__traits(isFloating, dchar) == false);\n}\n\n/********************************************************/\n\nvoid test5()\n{\n    assert(__traits(isUnsigned) == false);\n    assert(__traits(isUnsigned, S) == false);\n    assert(__traits(isUnsigned, C) == false);\n    assert(__traits(isUnsigned, E) == false);\n    assert(__traits(isUnsigned, void*) == false);\n    assert(__traits(isUnsigned, void[]) == false);\n    assert(__traits(isUnsigned, void[3]) == false);\n    assert(__traits(isUnsigned, int[char]) == false);\n    assert(__traits(isUnsigned, float, float) == false);\n    assert(__traits(isUnsigned, float, S) == false);\n\n    assert(__traits(isUnsigned, void) == false);\n    assert(__traits(isUnsigned, byte) == false);\n    assert(__traits(isUnsigned, ubyte) == true);\n    assert(__traits(isUnsigned, short) == false);\n    assert(__traits(isUnsigned, ushort) == true);\n    assert(__traits(isUnsigned, int) == false);\n    assert(__traits(isUnsigned, uint) == true);\n    assert(__traits(isUnsigned, long) == false);\n    assert(__traits(isUnsigned, ulong) == true);\n    assert(__traits(isUnsigned, float) == false);\n    assert(__traits(isUnsigned, double) == false);\n    assert(__traits(isUnsigned, real) == false);\n    assert(__traits(isUnsigned, ifloat) == false);\n    assert(__traits(isUnsigned, idouble) == false);\n    assert(__traits(isUnsigned, ireal) == false);\n    assert(__traits(isUnsigned, cfloat) == false);\n    assert(__traits(isUnsigned, cdouble) == false);\n    assert(__traits(isUnsigned, creal) == false);\n    assert(__traits(isUnsigned, char) == true);\n    assert(__traits(isUnsigned, wchar) == true);\n    assert(__traits(isUnsigned, dchar) == true);\n}\n\n/********************************************************/\n\nvoid test6()\n{\n    assert(__traits(isAssociativeArray) == false);\n    assert(__traits(isAssociativeArray, S) == false);\n    assert(__traits(isAssociativeArray, C) == false);\n    assert(__traits(isAssociativeArray, E) == false);\n    assert(__traits(isAssociativeArray, void*) == false);\n    assert(__traits(isAssociativeArray, void[]) == false);\n    assert(__traits(isAssociativeArray, void[3]) == false);\n    assert(__traits(isAssociativeArray, int[char]) == true);\n    assert(__traits(isAssociativeArray, float, float) == false);\n    assert(__traits(isAssociativeArray, float, S) == false);\n\n    assert(__traits(isAssociativeArray, void) == false);\n    assert(__traits(isAssociativeArray, byte) == false);\n    assert(__traits(isAssociativeArray, ubyte) == false);\n    assert(__traits(isAssociativeArray, short) == false);\n    assert(__traits(isAssociativeArray, ushort) == false);\n    assert(__traits(isAssociativeArray, int) == false);\n    assert(__traits(isAssociativeArray, uint) == false);\n    assert(__traits(isAssociativeArray, long) == false);\n    assert(__traits(isAssociativeArray, ulong) == false);\n    assert(__traits(isAssociativeArray, float) == false);\n    assert(__traits(isAssociativeArray, double) == false);\n    assert(__traits(isAssociativeArray, real) == false);\n    assert(__traits(isAssociativeArray, ifloat) == false);\n    assert(__traits(isAssociativeArray, idouble) == false);\n    assert(__traits(isAssociativeArray, ireal) == false);\n    assert(__traits(isAssociativeArray, cfloat) == false);\n    assert(__traits(isAssociativeArray, cdouble) == false);\n    assert(__traits(isAssociativeArray, creal) == false);\n    assert(__traits(isAssociativeArray, char) == false);\n    assert(__traits(isAssociativeArray, wchar) == false);\n    assert(__traits(isAssociativeArray, dchar) == false);\n}\n\n/********************************************************/\n\nvoid test7()\n{\n    assert(__traits(isStaticArray) == false);\n    assert(__traits(isStaticArray, S) == false);\n    assert(__traits(isStaticArray, C) == false);\n    assert(__traits(isStaticArray, E) == false);\n    assert(__traits(isStaticArray, void*) == false);\n    assert(__traits(isStaticArray, void[]) == false);\n    assert(__traits(isStaticArray, void[3]) == true);\n    assert(__traits(isStaticArray, int[char]) == false);\n    assert(__traits(isStaticArray, float, float) == false);\n    assert(__traits(isStaticArray, float, S) == false);\n\n    assert(__traits(isStaticArray, void) == false);\n    assert(__traits(isStaticArray, byte) == false);\n    assert(__traits(isStaticArray, ubyte) == false);\n    assert(__traits(isStaticArray, short) == false);\n    assert(__traits(isStaticArray, ushort) == false);\n    assert(__traits(isStaticArray, int) == false);\n    assert(__traits(isStaticArray, uint) == false);\n    assert(__traits(isStaticArray, long) == false);\n    assert(__traits(isStaticArray, ulong) == false);\n    assert(__traits(isStaticArray, float) == false);\n    assert(__traits(isStaticArray, double) == false);\n    assert(__traits(isStaticArray, real) == false);\n    assert(__traits(isStaticArray, ifloat) == false);\n    assert(__traits(isStaticArray, idouble) == false);\n    assert(__traits(isStaticArray, ireal) == false);\n    assert(__traits(isStaticArray, cfloat) == false);\n    assert(__traits(isStaticArray, cdouble) == false);\n    assert(__traits(isStaticArray, creal) == false);\n    assert(__traits(isStaticArray, char) == false);\n    assert(__traits(isStaticArray, wchar) == false);\n    assert(__traits(isStaticArray, dchar) == false);\n}\n\n/********************************************************/\n\nvoid test8()\n{\n    assert(__traits(isAbstractClass) == false);\n    assert(__traits(isAbstractClass, S) == false);\n    assert(__traits(isAbstractClass, C) == false);\n    assert(__traits(isAbstractClass, AC) == true);\n    assert(__traits(isAbstractClass, E) == false);\n    assert(__traits(isAbstractClass, void*) == false);\n    assert(__traits(isAbstractClass, void[]) == false);\n    assert(__traits(isAbstractClass, void[3]) == false);\n    assert(__traits(isAbstractClass, int[char]) == false);\n    assert(__traits(isAbstractClass, float, float) == false);\n    assert(__traits(isAbstractClass, float, S) == false);\n\n    assert(__traits(isAbstractClass, void) == false);\n    assert(__traits(isAbstractClass, byte) == false);\n    assert(__traits(isAbstractClass, ubyte) == false);\n    assert(__traits(isAbstractClass, short) == false);\n    assert(__traits(isAbstractClass, ushort) == false);\n    assert(__traits(isAbstractClass, int) == false);\n    assert(__traits(isAbstractClass, uint) == false);\n    assert(__traits(isAbstractClass, long) == false);\n    assert(__traits(isAbstractClass, ulong) == false);\n    assert(__traits(isAbstractClass, float) == false);\n    assert(__traits(isAbstractClass, double) == false);\n    assert(__traits(isAbstractClass, real) == false);\n    assert(__traits(isAbstractClass, ifloat) == false);\n    assert(__traits(isAbstractClass, idouble) == false);\n    assert(__traits(isAbstractClass, ireal) == false);\n    assert(__traits(isAbstractClass, cfloat) == false);\n    assert(__traits(isAbstractClass, cdouble) == false);\n    assert(__traits(isAbstractClass, creal) == false);\n    assert(__traits(isAbstractClass, char) == false);\n    assert(__traits(isAbstractClass, wchar) == false);\n    assert(__traits(isAbstractClass, dchar) == false);\n\n    assert(__traits(isAbstractClass, AC2) == true);\n    assert(__traits(isAbstractClass, AC3) == true);\n}\n\n/********************************************************/\n\nvoid test9()\n{\n    assert(__traits(isFinalClass) == false);\n    assert(__traits(isFinalClass, C) == false);\n    assert(__traits(isFinalClass, FC) == true);\n}\n\n/********************************************************/\n\nvoid test10()\n{\n    assert(__traits(isVirtualFunction, C.bar) == true);\n    assert(__traits(isVirtualFunction, S.bar) == false);\n}\n\n/********************************************************/\n\nvoid test11()\n{\n    assert(__traits(isAbstractFunction, C.bar) == false);\n    assert(__traits(isAbstractFunction, S.bar) == false);\n    assert(__traits(isAbstractFunction, AC2.foo) == true);\n}\n\n/********************************************************/\n\nvoid test12()\n{\n    assert(__traits(isFinalFunction, C.bar) == false);\n    assert(__traits(isFinalFunction, S.bar) == false);\n    assert(__traits(isFinalFunction, AC2.foo) == false);\n    assert(__traits(isFinalFunction, FC.foo) == true);\n    assert(__traits(isFinalFunction, C.foo) == true);\n}\n\n/********************************************************/\n\nvoid test13()\n{\n    S s;\n    __traits(getMember, s, \"x\") = 7;\n    auto i = __traits(getMember, s, \"x\");\n    assert(i == 7);\n    auto j = __traits(getMember, S, \"z\");\n    assert(j == 5);\n\n    writeln(__traits(hasMember, s, \"x\"));\n    assert(__traits(hasMember, s, \"x\") == true);\n    assert(__traits(hasMember, S, \"z\") == true);\n    assert(__traits(hasMember, S, \"aaa\") == false);\n\n    auto k = __traits(classInstanceSize, C);\n    writeln(k);\n    assert(k == C.classinfo.initializer.length);\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7123\n\nprivate struct DelegateFaker7123(F)\n{\n    template GeneratingPolicy() {}\n    enum WITH_BASE_CLASS = __traits(hasMember, GeneratingPolicy!(), \"x\");\n}\n\nauto toDelegate7123(F)(F fp)\n{\n    alias DelegateFaker7123!F Faker;\n}\n\n\nvoid test7123()\n{\n    static assert(is(typeof(toDelegate7123(&main))));\n}\n\n/********************************************************/\n\nclass D14\n{\n    this() { }\n    ~this() { }\n    void foo() { }\n    int foo(int) { return 0; }\n}\n\nvoid test14()\n{\n    auto a = [__traits(derivedMembers, D14)];\n    writeln(a);\n    assert(a == [\"__ctor\",\"__dtor\",\"foo\", \"__xdtor\"]);\n}\n\n/********************************************************/\n\nclass D15\n{\n    this() { }\n    ~this() { }\n    void foo() { }\n    int foo(int) { return 2; }\n}\n\nvoid test15()\n{\n    D15 d = new D15();\n\n    foreach (t; __traits(getVirtualFunctions, D15, \"foo\"))\n        writeln(typeid(typeof(t)));\n\n    alias typeof(__traits(getVirtualFunctions, D15, \"foo\")) b;\n    foreach (t; b)\n        writeln(typeid(t));\n\n    auto i = __traits(getVirtualFunctions, d, \"foo\")[1](1);\n    assert(i == 2);\n}\n\n/********************************************************/\n\nstruct S16 { }\n\nint foo16();\nint bar16();\n\nvoid test16()\n{\n    assert(__traits(isSame, foo16, foo16) == true);\n    assert(__traits(isSame, foo16, bar16) == false);\n    assert(__traits(isSame, foo16, S16) == false);\n    assert(__traits(isSame, S16, S16) == true);\n    assert(__traits(isSame, std, S16) == false);\n    assert(__traits(isSame, std, std) == true);\n}\n\n/********************************************************/\n\nstruct S17\n{\n    static int s1;\n    int s2;\n}\n\nint foo17();\n\nvoid test17()\n{\n    assert(__traits(compiles) == false);\n    assert(__traits(compiles, foo17) == true);\n    assert(__traits(compiles, foo17 + 1) == true);\n    assert(__traits(compiles, &foo17 + 1) == false);\n    assert(__traits(compiles, typeof(1)) == true);\n    assert(__traits(compiles, S17.s1) == true);\n    assert(__traits(compiles, S17.s3) == false);\n    assert(__traits(compiles, 1,2,3,int,long,std) == true);\n    assert(__traits(compiles, 3[1]) == false);\n    assert(__traits(compiles, 1,2,3,int,long,3[1]) == false);\n}\n\n/********************************************************/\n\ninterface D18\n{\n  extern(Windows):\n    void foo();\n    int foo(int);\n}\n\nvoid test18()\n{\n    auto a = __traits(allMembers, D18);\n    writeln(a);\n    assert(a.length == 1);\n}\n\n\n/********************************************************/\n\nclass C19\n{\n    void mutating_method(){}\n\n    const void const_method(){}\n\n    void bastard_method(){}\n    const void bastard_method(int){}\n}\n\n\nvoid test19()\n{\n    auto a = __traits(allMembers, C19);\n    writeln(a);\n    assert(a.length == 9);\n\n    foreach( m; __traits(allMembers, C19) )\n        writeln(m);\n}\n\n\n/********************************************************/\n\nvoid test20()\n{\n    void fooref(ref int x)\n    {\n        static assert(__traits(isRef, x));\n        static assert(!__traits(isOut, x));\n        static assert(!__traits(isLazy, x));\n    }\n\n    void fooout(out int x)\n    {\n        static assert(!__traits(isRef, x));\n        static assert(__traits(isOut, x));\n        static assert(!__traits(isLazy, x));\n    }\n\n    void foolazy(lazy int x)\n    {\n        static assert(!__traits(isRef, x));\n        static assert(!__traits(isOut, x));\n        static assert(__traits(isLazy, x));\n    }\n}\n\n/********************************************************/\n\nvoid test21()\n{\n    assert(__traits(isStaticFunction, C.bar) == false);\n    assert(__traits(isStaticFunction, C.abc) == true);\n    assert(__traits(isStaticFunction, S.bar) == false);\n}\n\n/********************************************************/\n\nclass D22\n{\n    this() { }\n    ~this() { }\n    void foo() { }\n    int foo(int) { return 2; }\n}\n\nvoid test22()\n{\n    D22 d = new D22();\n\n    foreach (t; __traits(getOverloads, D22, \"foo\"))\n        writeln(typeid(typeof(t)));\n\n    alias typeof(__traits(getOverloads, D22, \"foo\")) b;\n    foreach (t; b)\n        writeln(typeid(t));\n\n    auto i = __traits(getOverloads, d, \"foo\")[1](1);\n    assert(i == 2);\n}\n\n/********************************************************/\n\nstring toString23(E)(E value) if (is(E == enum)) {\n   foreach (s; __traits(allMembers, E)) {\n      if (value == mixin(\"E.\" ~ s)) return s;\n   }\n   return null;\n}\n\nenum OddWord { acini, alembicated, prolegomena, aprosexia }\n\nvoid test23()\n{\n   auto w = OddWord.alembicated;\n   assert(toString23(w) == \"alembicated\");\n}\n\n/********************************************************/\n\nstruct Test24\n{\n    public void test24(int){}\n    private void test24(int, int){}\n}\n\nstatic assert(__traits(getProtection, __traits(getOverloads, Test24, \"test24\")[1]) == \"private\");\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1369\n\nvoid test1369()\n{\n    class C1\n    {\n        static int count;\n        void func() { count++; }\n    }\n\n    // variable symbol\n    C1 c1 = new C1;\n    __traits(getMember, c1, \"func\")();      // TypeIdentifier -> VarExp\n    __traits(getMember, mixin(\"c1\"), \"func\")(); // Expression -> VarExp\n    assert(C1.count == 2);\n\n    // nested function symbol\n    @property C1 get() { return c1; }\n    __traits(getMember, get, \"func\")();\n    __traits(getMember, mixin(\"get\"), \"func\")();\n    assert(C1.count == 4);\n\n    class C2\n    {\n        C1 c1;\n        this() { c1 = new C1; }\n        void test()\n        {\n            // variable symbol (this.outer.c1)\n            __traits(getMember, c1, \"func\")();      // TypeIdentifier -> VarExp -> DotVarExp\n            __traits(getMember, mixin(\"c1\"), \"func\")(); // Expression -> VarExp -> DotVarExp\n            assert(C1.count == 6);\n\n            // nested function symbol (this.outer.get)\n            __traits(getMember, get, \"func\")();\n            __traits(getMember, mixin(\"get\"), \"func\")();\n            assert(C1.count == 8);\n        }\n    }\n    C2 c2 = new C2;\n    c2.test();\n}\n\n/********************************************************/\n\ntemplate Foo2234(){ int x; }\n\nstruct S2234a{ mixin Foo2234; }\nstruct S2234b{ mixin Foo2234; mixin Foo2234; }\nstruct S2234c{ alias Foo2234!() foo; }\n\nstatic assert([__traits(allMembers, S2234a)] == [\"x\"]);\nstatic assert([__traits(allMembers, S2234b)] == [\"x\"]);\nstatic assert([__traits(allMembers, S2234c)] == [\"foo\"]);\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5878\n\ntemplate J5878(A)\n{\n    static if (is(A P == super))\n        alias P J5878;\n}\n\nalias J5878!(A5878) Z5878;\n\nclass X5878 {}\nclass A5878 : X5878 {}\n\n/********************************************************/\n\nmixin template Members6674()\n{\n    static int i1;\n    static int i2;\n    static int i3;  //comment out to make func2 visible\n    static int i4;  //comment out to make func1 visible\n}\n\nclass Test6674\n{\n    mixin Members6674;\n\n    alias void function() func1;\n    alias bool function() func2;\n}\n\nstatic assert([__traits(allMembers,Test6674)] == [\n    \"i1\",\"i2\",\"i3\",\"i4\",\n    \"func1\",\"func2\",\n    \"toString\",\"toHash\",\"opCmp\",\"opEquals\",\"Monitor\",\"factory\"]);\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6073\n\nstruct S6073 {}\n\ntemplate T6073(M...) {\n    //alias int T;\n}\nalias T6073!traits V6073;                       // ok\nalias T6073!(__traits(parent, S6073)) U6073;    // error\nstatic assert(__traits(isSame, V6073, U6073));  // same instantiation == same arguemnts\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7027\n\nstruct Foo7027 { int a; }\nstatic assert(!__traits(compiles, { return Foo7027.a; }));\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9213\n\nclass Foo9213 { int a; }\nstatic assert(!__traits(compiles, { return Foo9213.a; }));\n\n/********************************************************/\n\ninterface AA\n{\n     int YYY();\n}\n\nclass CC : AA\n{\n    final int YYY() { return 4; }\n}\n\nstatic assert(__traits(isVirtualMethod, CC.YYY));\nstatic assert(__traits(getVirtualMethods, CC, \"YYY\").length == 1);\n\nclass DD\n{\n    final int YYY() { return 4; }\n}\n\nstatic assert(__traits(isVirtualMethod, DD.YYY) == false);\nstatic assert(__traits(getVirtualMethods, DD, \"YYY\").length == 0);\n\nclass EE\n{\n     int YYY() { return 0; }\n}\n\nclass FF : EE\n{\n    final override int YYY() { return 4; }\n}\n\nstatic assert(__traits(isVirtualMethod, FF.YYY));\nstatic assert(__traits(getVirtualMethods, FF, \"YYY\").length == 1);\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7608\n\nstruct S7608a(bool T)\n{\n    static if (T) { int x; }\n    int y;\n}\nstruct S7608b\n{\n    version(none) { int x; }\n    int y;\n}\ntemplate TypeTuple7608(T...){ alias T TypeTuple7608; }\nvoid test7608()\n{\n    alias TypeTuple7608!(__traits(allMembers, S7608a!false)) MembersA;\n    static assert(MembersA.length == 1);\n    static assert(MembersA[0] == \"y\");\n\n    alias TypeTuple7608!(__traits(allMembers, S7608b)) MembersB;\n    static assert(MembersB.length == 1);\n    static assert(MembersB[0] == \"y\");\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7858\n\nvoid test7858()\n{\n    class C\n    {\n        final void ffunc(){}\n        final void ffunc(int){}\n\n        void vfunc(){}\n        void vfunc(int){}\n\n        abstract void afunc();\n        abstract void afunc(int);\n\n        static void sfunc(){}\n        static void sfunc(int){}\n    }\n\n    static assert(__traits(isFinalFunction, C.ffunc) ==\n                  __traits(isFinalFunction, __traits(getOverloads, C, \"ffunc\")[0]));    // NG\n    static assert(__traits(isVirtualFunction, C.vfunc) ==\n                  __traits(isVirtualFunction, __traits(getOverloads, C, \"vfunc\")[0]));  // NG\n    static assert(__traits(isVirtualMethod, C.vfunc) ==\n                  __traits(isVirtualMethod, __traits(getOverloads, C, \"vfunc\")[0]));    // NG\n    static assert(__traits(isAbstractFunction, C.afunc) ==\n                  __traits(isAbstractFunction, __traits(getOverloads, C, \"afunc\")[0])); // OK\n    static assert(__traits(isStaticFunction, C.sfunc) ==\n                  __traits(isStaticFunction, __traits(getOverloads, C, \"sfunc\")[0]));   // OK\n\n    static assert(__traits(isSame, C.ffunc, __traits(getOverloads, C, \"ffunc\")[0]));    // NG\n    static assert(__traits(isSame, C.vfunc, __traits(getOverloads, C, \"vfunc\")[0]));    // NG\n    static assert(__traits(isSame, C.afunc, __traits(getOverloads, C, \"afunc\")[0]));    // NG\n    static assert(__traits(isSame, C.sfunc, __traits(getOverloads, C, \"sfunc\")[0]));    // NG\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8971\n\ntemplate Tuple8971(TL...){ alias TL Tuple8971; }\n\nclass A8971\n{\n    void bar() {}\n\n    void connect()\n    {\n        alias Tuple8971!(__traits(getOverloads, typeof(this), \"bar\")) overloads;\n        static assert(__traits(isSame, overloads[0], bar));\n    }\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8972\n\nstruct A8972\n{\n    void foo() {}\n\n    void connect()\n    {\n        alias Tuple8971!(__traits(getOverloads, typeof(this), \"foo\")) overloads;\n        static assert(__traits(isSame, overloads[0], foo));\n    }\n}\n\n/********************************************************/\n\nprivate   struct TestProt1 {}\npackage   struct TestProt2 {}\nprotected struct TestProt3 {}\npublic    struct TestProt4 {}\nexport    struct TestProt5 {}\n\nvoid getProtection()\n{\n    class Test\n    {\n        private   { int va; void fa(){} }\n        package   { int vb; void fb(){} }\n        protected { int vc; void fc(){} }\n        public    { int vd; void fd(){} }\n        export    { int ve; void fe(){} }\n    }\n    Test t;\n\n    // TOKvar and VarDeclaration\n    static assert(__traits(getProtection, Test.va) == \"private\");\n    static assert(__traits(getProtection, Test.vb) == \"package\");\n    static assert(__traits(getProtection, Test.vc) == \"protected\");\n    static assert(__traits(getProtection, Test.vd) == \"public\");\n    static assert(__traits(getProtection, Test.ve) == \"export\");\n\n    // TOKdotvar and VarDeclaration\n    static assert(__traits(getProtection, t.va) == \"private\");\n    static assert(__traits(getProtection, t.vb) == \"package\");\n    static assert(__traits(getProtection, t.vc) == \"protected\");\n    static assert(__traits(getProtection, t.vd) == \"public\");\n    static assert(__traits(getProtection, t.ve) == \"export\");\n\n    // TOKvar and FuncDeclaration\n    static assert(__traits(getProtection, Test.fa) == \"private\");\n    static assert(__traits(getProtection, Test.fb) == \"package\");\n    static assert(__traits(getProtection, Test.fc) == \"protected\");\n    static assert(__traits(getProtection, Test.fd) == \"public\");\n    static assert(__traits(getProtection, Test.fe) == \"export\");\n\n    // TOKdotvar and FuncDeclaration\n    static assert(__traits(getProtection, t.fa) == \"private\");\n    static assert(__traits(getProtection, t.fb) == \"package\");\n    static assert(__traits(getProtection, t.fc) == \"protected\");\n    static assert(__traits(getProtection, t.fd) == \"public\");\n    static assert(__traits(getProtection, t.fe) == \"export\");\n\n    // TOKtype\n    static assert(__traits(getProtection, TestProt1) == \"private\");\n    static assert(__traits(getProtection, TestProt2) == \"package\");\n    static assert(__traits(getProtection, TestProt3) == \"protected\");\n    static assert(__traits(getProtection, TestProt4) == \"public\");\n    static assert(__traits(getProtection, TestProt5) == \"export\");\n\n    // This specific pattern is important to ensure it always works\n    // through reflection, however that becomes implemented\n    static assert(__traits(getProtection, __traits(getMember, t, \"va\")) == \"private\");\n    static assert(__traits(getProtection, __traits(getMember, t, \"vb\")) == \"package\");\n    static assert(__traits(getProtection, __traits(getMember, t, \"vc\")) == \"protected\");\n    static assert(__traits(getProtection, __traits(getMember, t, \"vd\")) == \"public\");\n    static assert(__traits(getProtection, __traits(getMember, t, \"ve\")) == \"export\");\n    static assert(__traits(getProtection, __traits(getMember, t, \"fa\")) == \"private\");\n    static assert(__traits(getProtection, __traits(getMember, t, \"fb\")) == \"package\");\n    static assert(__traits(getProtection, __traits(getMember, t, \"fc\")) == \"protected\");\n    static assert(__traits(getProtection, __traits(getMember, t, \"fd\")) == \"public\");\n    static assert(__traits(getProtection, __traits(getMember, t, \"fe\")) == \"export\");\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9546\n\nvoid test9546()\n{\n    import imports.a9546 : S;\n\n    S s;\n    static assert(__traits(getProtection, s.privA) == \"private\");\n    static assert(__traits(getProtection, s.protA) == \"protected\");\n    static assert(__traits(getProtection, s.packA) == \"package\");\n    static assert(__traits(getProtection, S.privA) == \"private\");\n    static assert(__traits(getProtection, S.protA) == \"protected\");\n    static assert(__traits(getProtection, S.packA) == \"package\");\n\n    static assert(__traits(getProtection, mixin(\"s.privA\")) == \"private\");\n    static assert(__traits(getProtection, mixin(\"s.protA\")) == \"protected\");\n    static assert(__traits(getProtection, mixin(\"s.packA\")) == \"package\");\n    static assert(__traits(getProtection, mixin(\"S.privA\")) == \"private\");\n    static assert(__traits(getProtection, mixin(\"S.protA\")) == \"protected\");\n    static assert(__traits(getProtection, mixin(\"S.packA\")) == \"package\");\n\n    static assert(__traits(getProtection, __traits(getMember, s, \"privA\")) == \"private\");\n    static assert(__traits(getProtection, __traits(getMember, s, \"protA\")) == \"protected\");\n    static assert(__traits(getProtection, __traits(getMember, s, \"packA\")) == \"package\");\n    static assert(__traits(getProtection, __traits(getMember, S, \"privA\")) == \"private\");\n    static assert(__traits(getProtection, __traits(getMember, S, \"protA\")) == \"protected\");\n    static assert(__traits(getProtection, __traits(getMember, S, \"packA\")) == \"package\");\n\n    static assert(__traits(getProtection, s.privF) == \"private\");\n    static assert(__traits(getProtection, s.protF) == \"protected\");\n    static assert(__traits(getProtection, s.packF) == \"package\");\n    static assert(__traits(getProtection, S.privF) == \"private\");\n    static assert(__traits(getProtection, S.protF) == \"protected\");\n    static assert(__traits(getProtection, S.packF) == \"package\");\n\n    static assert(__traits(getProtection, mixin(\"s.privF\")) == \"private\");\n    static assert(__traits(getProtection, mixin(\"s.protF\")) == \"protected\");\n    static assert(__traits(getProtection, mixin(\"s.packF\")) == \"package\");\n    static assert(__traits(getProtection, mixin(\"S.privF\")) == \"private\");\n    static assert(__traits(getProtection, mixin(\"S.protF\")) == \"protected\");\n    static assert(__traits(getProtection, mixin(\"S.packF\")) == \"package\");\n\n    static assert(__traits(getProtection, __traits(getMember, s, \"privF\")) == \"private\");\n    static assert(__traits(getProtection, __traits(getMember, s, \"protF\")) == \"protected\");\n    static assert(__traits(getProtection, __traits(getMember, s, \"packF\")) == \"package\");\n    static assert(__traits(getProtection, __traits(getMember, S, \"privF\")) == \"private\");\n    static assert(__traits(getProtection, __traits(getMember, S, \"protF\")) == \"protected\");\n    static assert(__traits(getProtection, __traits(getMember, S, \"packF\")) == \"package\");\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9091\n\ntemplate isVariable9091(X...) if (X.length == 1)\n{\n    enum isVariable9091 = true;\n}\nclass C9091\n{\n    int x;  // some class members\n    void func(int n){ this.x = n; }\n\n    void test()\n    {\n        alias T = C9091;\n        enum is_x = isVariable9091!(__traits(getMember, T, \"x\"));\n\n        foreach (i, m; __traits(allMembers, T))\n        {\n            enum x = isVariable9091!(__traits(getMember, T, m));\n            static if (i == 0)  // x\n            {\n                __traits(getMember, T, m) = 10;\n                assert(this.x == 10);\n            }\n            static if (i == 1)  // func\n            {\n                __traits(getMember, T, m)(20);\n                assert(this.x == 20);\n            }\n        }\n    }\n}\nstruct S9091\n{\n    int x;  // some struct members\n    void func(int n){ this.x = n; }\n\n    void test()\n    {\n        alias T = S9091;\n        enum is_x = isVariable9091!(__traits(getMember, T, \"x\"));\n\n        foreach (i, m; __traits(allMembers, T))\n        {\n            enum x = isVariable9091!(__traits(getMember, T, m));\n            static if (i == 0)  // x\n            {\n                __traits(getMember, T, m) = 10;\n                assert(this.x == 10);\n            }\n            static if (i == 1)  // func\n            {\n                __traits(getMember, T, m)(20);\n                assert(this.x == 20);\n            }\n        }\n    }\n}\n\nvoid test9091()\n{\n    auto c = new C9091();\n    c.test();\n\n    auto s = S9091();\n    s.test();\n}\n\n/********************************************************/\n\nstruct CtorS_9237 { this(int x) { } }       // ctor -> POD\nstruct DtorS_9237 { ~this() { } }           // dtor -> nonPOD\nstruct PostblitS_9237 { this(this) { } }    // cpctor -> nonPOD\n\nstruct NonPOD1_9237\n{\n    DtorS_9237 field;  // nonPOD -> ng\n}\n\nstruct NonPOD2_9237\n{\n    DtorS_9237[2] field;  // static array of nonPOD -> ng\n}\n\nstruct POD1_9237\n{\n    DtorS_9237* field;  // pointer to nonPOD -> ok\n}\n\nstruct POD2_9237\n{\n    DtorS_9237[] field;  // dynamic array of nonPOD -> ok\n}\n\nstruct POD3_9237\n{\n    int x = 123;\n}\n\nclass C_9273 { }\n\nvoid test9237()\n{\n    int x;\n    struct NS_9237  // acceses .outer -> nested\n    {\n        void foo() { x++; }\n    }\n\n    struct NonNS_9237 { }  // doesn't access .outer -> non-nested\n    static struct StatNS_9237 { }  // can't access .outer -> non-nested\n\n    static assert(!__traits(isPOD, NS_9237));\n    static assert(__traits(isPOD, NonNS_9237));\n    static assert(__traits(isPOD, StatNS_9237));\n    static assert(__traits(isPOD, CtorS_9237));\n    static assert(!__traits(isPOD, DtorS_9237));\n    static assert(!__traits(isPOD, PostblitS_9237));\n    static assert(!__traits(isPOD, NonPOD1_9237));\n    static assert(!__traits(isPOD, NonPOD2_9237));\n    static assert(__traits(isPOD, POD1_9237));\n    static assert(__traits(isPOD, POD2_9237));\n    static assert(__traits(isPOD, POD3_9237));\n\n    // static array of POD/non-POD types\n    static assert(!__traits(isPOD, NS_9237[2]));\n    static assert(__traits(isPOD, NonNS_9237[2]));\n    static assert(__traits(isPOD, StatNS_9237[2]));\n    static assert(__traits(isPOD, CtorS_9237[2]));\n    static assert(!__traits(isPOD, DtorS_9237[2]));\n    static assert(!__traits(isPOD, PostblitS_9237[2]));\n    static assert(!__traits(isPOD, NonPOD1_9237[2]));\n    static assert(!__traits(isPOD, NonPOD2_9237[2]));\n    static assert(__traits(isPOD, POD1_9237[2]));\n    static assert(__traits(isPOD, POD2_9237[2]));\n    static assert(__traits(isPOD, POD3_9237[2]));\n\n    // non-structs are POD types\n    static assert(__traits(isPOD, C_9273));\n    static assert(__traits(isPOD, int));\n    static assert(__traits(isPOD, int*));\n    static assert(__traits(isPOD, int[]));\n    static assert(!__traits(compiles, __traits(isPOD, 123) ));\n}\n\n/*************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5978\n\nvoid test5978()\n{\n    () {\n        int x;\n        pragma(msg, __traits(identifier, __traits(parent, x)));\n    } ();\n}\n\n/*************************************************************/\n\ntemplate T7408() { }\n\nvoid test7408()\n{\n    auto x = T7408!().stringof;\n    auto y = T7408!().mangleof;\n    static assert(__traits(compiles, T7408!().stringof));\n    static assert(__traits(compiles, T7408!().mangleof));\n    static assert(!__traits(compiles, T7408!().init));\n    static assert(!__traits(compiles, T7408!().offsetof));\n}\n\n/*************************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9552\n\nclass C9552\n{\n    int f() { return 10; }\n    int f(int n) { return n * 2; }\n}\n\nvoid test9552()\n{\n    auto c = new C9552;\n    auto dg1 = &(__traits(getOverloads, c, \"f\")[0]); // DMD crashes\n    assert(dg1() == 10);\n    auto dg2 = &(__traits(getOverloads, c, \"f\")[1]);\n    assert(dg2(10) == 20);\n}\n\n/*************************************************************/\n\nvoid test9136()\n{\n    int x;\n    struct S1 { void f() { x++; } }\n    struct U1 { void f() { x++; } }\n    static struct S2 { }\n    static struct S3 { S1 s; }\n    static struct U2 { }\n    void f1() { x++; }\n    static void f2() { }\n\n    static assert(__traits(isNested, S1));\n    static assert(__traits(isNested, U1));\n    static assert(!__traits(isNested, S2));\n    static assert(!__traits(isNested, S3));\n    static assert(!__traits(isNested, U2));\n    static assert(!__traits(compiles, __traits(isNested, int) ));\n    static assert(!__traits(compiles, __traits(isNested, f1, f2) ));\n    static assert(__traits(isNested, f1));\n    static assert(!__traits(isNested, f2));\n\n    static class A { static class SC { } class NC { } }\n    static assert(!__traits(isNested, A));\n    static assert(!__traits(isNested, A.SC));\n    static assert(__traits(isNested, A.NC));\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9939\n\nstruct Test9939\n{\n    int f;\n    enum /*Anonymous enum*/\n    {\n        A,\n        B\n    }\n    enum NamedEnum\n    {\n        C,\n        D\n    }\n}\n\nstatic assert([__traits(allMembers, Test9939)] == [\"f\", \"A\", \"B\", \"NamedEnum\"]);\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10043\n\nvoid test10043()\n{\n    struct X {}\n    X d1;\n    static assert(!__traits(compiles, d1.structuralCast!Refleshable));\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10096\n\nstruct S10096X\n{\n    string str;\n\n    invariant() {}\n    invariant() {}\n    unittest {}\n\n    this(int) {}\n    this(this) {}\n    ~this() {}\n}\nstatic assert(\n    [__traits(allMembers, S10096X)] ==\n    [\"str\", \"__ctor\", \"__postblit\", \"__dtor\", \"__xdtor\", \"__xpostblit\", \"opAssign\"]);\n\n// --------\n\nstring foo10096(alias var, T = typeof(var))()\n{\n    foreach (idx, member; __traits(allMembers, T))\n    {\n        auto x = var.tupleof[idx];\n    }\n\n    return \"\";\n}\n\nstring foo10096(T)(T var)\n{\n    return \"\";\n}\n\nstruct S10096\n{\n    int i;\n    string s;\n}\n\nvoid test10096()\n{\n    S10096 s = S10096(1, \"\");\n    auto x = foo10096!s;\n}\n\n/********************************************************/\n\nunittest { }\n\nstruct GetUnitTests\n{\n    unittest { }\n}\n\nvoid test_getUnitTests ()\n{\n    // Always returns empty tuple if the -unittest flag isn't used\n    static assert(__traits(getUnitTests, mixin(__MODULE__)).length == 0);\n    static assert(__traits(getUnitTests, GetUnitTests).length == 0);\n}\n\n/********************************************************/\n\nvoid test_getFunctionAttributes()\n{\n    alias tuple(T...) = T;\n\n    struct S\n    {\n        int noF() { return 0; }\n        int constF() const { return 0; }\n        int immutableF() immutable { return 0; }\n        int inoutF() inout { return 0; }\n        int sharedF() shared { return 0; }\n\n        int x;\n        ref int refF() { return x; }\n        int propertyF() @property { return 0; }\n        int nothrowF() nothrow { return 0; }\n        int nogcF() @nogc { return 0; }\n\n        int systemF() @system { return 0; }\n        int trustedF() @trusted { return 0; }\n        int safeF() @safe { return 0; }\n\n        int pureF() pure { return 0; }\n    }\n\n    static assert(__traits(getFunctionAttributes, S.noF) == tuple!(\"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.noF)) == tuple!(\"@system\"));\n\n    static assert(__traits(getFunctionAttributes, S.constF) == tuple!(\"const\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.constF)) == tuple!(\"const\", \"@system\"));\n\n    static assert(__traits(getFunctionAttributes, S.immutableF) == tuple!(\"immutable\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.immutableF)) == tuple!(\"immutable\", \"@system\"));\n\n    static assert(__traits(getFunctionAttributes, S.inoutF) == tuple!(\"inout\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.inoutF)) == tuple!(\"inout\", \"@system\"));\n\n    static assert(__traits(getFunctionAttributes, S.sharedF) == tuple!(\"shared\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.sharedF)) == tuple!(\"shared\", \"@system\"));\n\n    static assert(__traits(getFunctionAttributes, S.refF) == tuple!(\"ref\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.refF)) == tuple!(\"ref\", \"@system\"));\n\n    static assert(__traits(getFunctionAttributes, S.propertyF) == tuple!(\"@property\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(&S.propertyF)) == tuple!(\"@property\", \"@system\"));\n\n    static assert(__traits(getFunctionAttributes, S.nothrowF) == tuple!(\"nothrow\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.nothrowF)) == tuple!(\"nothrow\", \"@system\"));\n\n    static assert(__traits(getFunctionAttributes, S.nogcF) == tuple!(\"@nogc\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.nogcF)) == tuple!(\"@nogc\", \"@system\"));\n\n    static assert(__traits(getFunctionAttributes, S.systemF) == tuple!(\"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.systemF)) == tuple!(\"@system\"));\n\n    static assert(__traits(getFunctionAttributes, S.trustedF) == tuple!(\"@trusted\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.trustedF)) == tuple!(\"@trusted\"));\n\n    static assert(__traits(getFunctionAttributes, S.safeF) == tuple!(\"@safe\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.safeF)) == tuple!(\"@safe\"));\n\n    static assert(__traits(getFunctionAttributes, S.pureF) == tuple!(\"pure\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S.pureF)) == tuple!(\"pure\", \"@system\"));\n\n    int pure_nothrow() nothrow pure { return 0; }\n    static ref int static_ref_property() @property { return *(new int); }\n    ref int ref_property() @property { return *(new int); }\n    void safe_nothrow() @safe nothrow { }\n\n    static assert(__traits(getFunctionAttributes, pure_nothrow) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n    static assert(__traits(getFunctionAttributes, typeof(pure_nothrow)) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n\n    static assert(__traits(getFunctionAttributes, static_ref_property) == tuple!(\"pure\", \"nothrow\", \"@property\", \"ref\", \"@safe\"));\n    static assert(__traits(getFunctionAttributes, typeof(&static_ref_property)) == tuple!(\"pure\", \"nothrow\", \"@property\", \"ref\", \"@safe\"));\n\n    static assert(__traits(getFunctionAttributes, ref_property) == tuple!(\"pure\", \"nothrow\", \"@property\", \"ref\", \"@safe\"));\n    static assert(__traits(getFunctionAttributes, typeof(&ref_property)) == tuple!(\"pure\", \"nothrow\", \"@property\", \"ref\", \"@safe\"));\n\n    static assert(__traits(getFunctionAttributes, safe_nothrow) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n    static assert(__traits(getFunctionAttributes, typeof(safe_nothrow)) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n\n    struct S2\n    {\n        int pure_const() const pure { return 0; }\n        int pure_sharedconst() const shared pure { return 0; }\n    }\n\n    static assert(__traits(getFunctionAttributes, S2.pure_const) == tuple!(\"const\", \"pure\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S2.pure_const)) == tuple!(\"const\", \"pure\", \"@system\"));\n\n    static assert(__traits(getFunctionAttributes, S2.pure_sharedconst) == tuple!(\"const\", \"shared\", \"pure\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(S2.pure_sharedconst)) == tuple!(\"const\", \"shared\", \"pure\", \"@system\"));\n\n    static assert(__traits(getFunctionAttributes, (int a) { }) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n    static assert(__traits(getFunctionAttributes, typeof((int a) { })) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n\n    auto safeDel = delegate() @safe { };\n    static assert(__traits(getFunctionAttributes, safeDel) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n    static assert(__traits(getFunctionAttributes, typeof(safeDel)) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n\n    auto trustedDel = delegate() @trusted { };\n    static assert(__traits(getFunctionAttributes, trustedDel) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@trusted\"));\n    static assert(__traits(getFunctionAttributes, typeof(trustedDel)) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@trusted\"));\n\n    auto systemDel = delegate() @system { };\n    static assert(__traits(getFunctionAttributes, systemDel) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@system\"));\n    static assert(__traits(getFunctionAttributes, typeof(systemDel)) == tuple!(\"pure\", \"nothrow\", \"@nogc\", \"@system\"));\n}\n\n/********************************************************/\n\nclass TestIsOverrideFunctionBase\n{\n    void bar () {}\n}\n\nclass TestIsOverrideFunctionPass : TestIsOverrideFunctionBase\n{\n    override void bar () {}\n}\n\nvoid test_isOverrideFunction ()\n{\n    assert(__traits(isOverrideFunction, TestIsOverrideFunctionPass.bar) == true);\n    assert(__traits(isOverrideFunction, TestIsOverrideFunctionBase.bar) == false);\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11711\n// Add __traits(getAliasThis)\n\nalias TypeTuple(T...) = T;\n\nvoid test11711()\n{\n    struct S1\n    {\n        string var;\n        alias var this;\n    }\n    static assert(__traits(getAliasThis, S1) == TypeTuple!(\"var\"));\n    static assert(is(typeof(__traits(getMember, S1.init, __traits(getAliasThis, S1)[0]))\n                == string));\n\n    struct S2\n    {\n        TypeTuple!(int, string) var;\n        alias var this;\n    }\n    static assert(__traits(getAliasThis, S2) == TypeTuple!(\"var\"));\n    static assert(is(typeof(__traits(getMember, S2.init, __traits(getAliasThis, S2)[0]))\n                == TypeTuple!(int, string)));\n}\n\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12278\n\nclass Foo12278\n{\n    InPlace12278!Bar12278 inside;\n}\n\nclass Bar12278 { }\n\nstruct InPlace12278(T)\n{\n    static assert(__traits(classInstanceSize, T) != 0);\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12571\n\nmixin template getScopeName12571()\n{\n    enum string scopeName = __traits(identifier, __traits(parent, scopeName));\n}\n\nvoid test12571()\n{\n    mixin getScopeName12571;\n    static assert(scopeName == \"test12571\");\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12237\n\nauto f12237(T)(T a)\n{\n    static if (is(typeof(a) == int))\n        return f12237(\"\");\n    else\n        return 10;\n}\n\nvoid test12237()\n{\n    assert(f12237(1) == 10);\n\n    assert((a){\n        static if (is(typeof(a) == int))\n        {\n            int x;\n            return __traits(parent, x)(\"\");\n        }\n        else\n            return 10;\n    }(1) == 10);\n}\n\n/********************************************************/\n\nvoid async(ARGS...)(ARGS)\n{\n        static void compute(ARGS)\n        {\n        }\n\n        auto x = __traits(getParameterStorageClasses, compute, 1);\n}\n\nalias test17495 = async!(int, int);\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15094\n\nvoid test15094()\n{\n    static struct Foo { int i; }\n    static struct Bar { Foo foo; }\n\n    Bar bar;\n    auto n = __traits(getMember, bar.foo, \"i\");\n    assert(n == bar.foo.i);\n}\n\n/********************************************************/\n\nvoid testIsDisabled()\n{\n    static assert(__traits(isDisabled, D1.true_));\n    static assert(!__traits(isDisabled, D1.false_));\n    static assert(!__traits(isDisabled, D1));\n}\n\n/********************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test7123();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test1369();\n    test7608();\n    test7858();\n    test9091();\n    test5978();\n    test7408();\n    test9552();\n    test9136();\n    test10096();\n    test_getUnitTests();\n    test_getFunctionAttributes();\n    test_isOverrideFunction();\n    test12237();\n    test15094();\n\n    writeln(\"Success\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/traits_getPointerBitmap.d",
    "content": "\nmodule traits_getPointerBitmap;\n\nimport std.stdio;\nstatic import std.traits;\n\n// version = RTInfo;\n// debug = LOG;\n\nversion(RTInfo)\n    import gc.rtinfo;\nelse\n    enum bool RTInfoMark__Monitor = false; // is __monitor GC allocated?\n\n\nenum bytesPerPtr = (size_t.sizeof);\nenum bytesPerBitmapWord = bytesPerPtr * bytesPerPtr * 8;\n\ntemplate allocatedSize(T)\n{\n    static if (is (T == class))\n        enum allocatedSize = __traits(classInstanceSize, T);\n    else\n        enum allocatedSize = T.sizeof;\n}\n\nbool testBit(const(size_t)* p, size_t biti)\n{\n    enum BITS_SHIFT = (size_t.sizeof == 8 ? 6 : 5);\n    enum BITS_MASK = (bytesPerPtr - 1);\n\n    return (p[biti >> BITS_SHIFT] & (1 << (biti & BITS_MASK))) != 0;\n}\n\nvoid __testType(T)(size_t[] expected)\n{\n    // check compile time info\n    enum bits  = (T.sizeof + bytesPerPtr - 1) / bytesPerPtr;\n    enum words = (T.sizeof + bytesPerBitmapWord - 1) / bytesPerBitmapWord;\n    version(RTInfo)\n        enum info = RTInfoImpl2!(Unqual!T); // we want the array, not the pointer\n    else\n        enum info = __traits(getPointerBitmap,T); // we want the array, not the pointer\n\n    debug(LOG) writef(\"%-20s:\", T.stringof);\n    debug(LOG) writef(\" CT:%s\", info);\n    debug(LOG) writef(\" EXP:%d %s\", allocatedSize!T, expected);\n    assert(info[0] == allocatedSize!T);\n    assert(info[1..$] == expected);\n    assert(words == expected.length);\n\n    debug(LOG) writeln();\n}\n\n///////////////////////////////////////\nstruct S(T, aliasTo = void)\n{\n    static if(!is(aliasTo == void))\n    {\n        aliasTo a;\n        alias a this;\n    }\n\n    size_t x;\n    T t = void;\n    void* p;\n\n}\n\ntemplate tOff(T)\n{\n    enum tOff = T.t.offsetof / bytesPerPtr;\n}\n\ntemplate pOff(T)\n{\n    enum pOff = T.p.offsetof / bytesPerPtr;\n}\n\nclass C(T, aliasTo = void)\n{\n    static if(!is(aliasTo == void))\n    {\n        aliasTo a;\n        alias a this;\n    }\n\n    size_t x;\n    T t = void;\n    void* p;\n}\n\n///////////////////////////////////////\n\nvoid _testType(T)(size_t[] expected)\n{\n    __testType!(T)(expected);\n    __testType!(const(T))(expected);\n    __testType!(immutable(T))(expected);\n    version(RTInfo) {} else // Unqual does not work with shared(T[N])\n        __testType!(shared(T))(expected);\n}\n\nvoid testType(T)(size_t[] expected)\n{\n    _testType!(T)(expected);\n\n    // generate bit pattern for S!T\n    assert(expected.length == 1);\n    size_t[] sexp;\n\n    sexp ~= (expected[0] << tOff!(S!T)) | (1 << pOff!((S!T)));\n    _testType!(S!T)(sexp);\n\n    // prepend Object\n    sexp[0] = (expected[0] << tOff!(S!(T, Object))) | (1 << pOff!(S!(T, Object))) | 1;\n    _testType!(S!(T, Object))(sexp);\n\n    // prepend string\n    sexp[0] = (expected[0] << tOff!(S!(T, string))) | (1 << pOff!(S!(T, string))) | 2; // arr ptr\n    _testType!(S!(T, string))(sexp);\n\n    // generate bit pattern for C!T\n    C!T ct = null;\n    size_t mutexBit = (RTInfoMark__Monitor ? 2 : 0);\n    size_t ctpOff = ct.p.offsetof / bytesPerPtr;\n    size_t cttOff = ct.t.offsetof / bytesPerPtr;\n    sexp[0] = (expected[0] << cttOff) | (1 << ctpOff) | mutexBit;\n    _testType!(C!(T))(sexp);\n\n    C!(T, string) cts = null;\n    size_t ctspOff = cts.p.offsetof / bytesPerPtr;\n    size_t ctstOff = cts.t.offsetof / bytesPerPtr;\n    // generate bit pattern for C!T\n    sexp[0] = (expected[0] << ctstOff) | (1 << ctspOff) | mutexBit | 0b1000; // arr ptr\n    _testType!(C!(T, string))(sexp);\n}\n\n///////////////////////////////////////\nalias void[2*size_t.sizeof] void2;\nalias size_t[3] int3;\nalias size_t*[3] pint3;\nalias string[3] sint3;\nalias string[3][2] sint3_2;\nalias int delegate() dg;\nalias int function() fn;\nalias typeof(null) NullType;\n\n// span multiple bitmap elements\nstruct Large\n{\n    size_t[30] data1;\n    void* p1;\n    size_t[1] val1;\n\n    size_t[28] data2;\n    void* p2;\n    size_t[3] val2;\n\n    size_t[16] data3;\n    void* p3;\n    size_t[15] val3;\n}\n\nclass N\n{\n    struct Nested\n    {\n        // no outer for structs\n        size_t x;\n        void* p1;\n        Large* s;\n\n        void foo() {} // need member fnction to not be POD\n    }\n    class CNested\n    {\n        // implicit vtptr,monitor\n        size_t x;\n        void* p1;\n        size_t y;\n        // implicit outer\n    }\n    class CNestedDerived : CNested\n    {\n        size_t[3] z;\n        void* p;\n    }\n}\n\nunion U\n{\n    size_t[4] data;\n    Large*[] arr; // { length, ptr }\n\n    struct\n    {\n        size_t d1;\n        size_t d2;\n        size_t d3;\n        void* p;\n    }\n}\n\nvoid testRTInfo()\n{\n    testType!(bool)         ([ 0b0 ]);\n    testType!(ubyte)        ([ 0b0 ]);\n    testType!(short)        ([ 0b0 ]);\n    testType!(int)          ([ 0b0 ]);\n    testType!(long)         ([ 0b00 ]);\n    testType!(double)       ([ 0b00 ]);\n    testType!(ifloat)       ([ 0b0 ]);\n    testType!(cdouble)      ([ 0b0000 ]);\n    testType!(dg)           ([ 0b01 ]);\n    testType!(fn)           ([ 0b0 ]);\n    testType!(S!fn)         ([ 0b100 ]);\n    testType!(NullType)     ([ 0b0 ]);\n    version(D_LP64)\n        testType!(__vector(float[4]))  ([ 0b00 ]);\n\n    testType!(Object[int])       ([ 0b1 ]);\n    testType!(Object[])       ([ 0b10 ]);\n    testType!(string)         ([ 0b10 ]);\n\n    testType!(int3)           ([ 0b000 ]);\n    testType!(pint3)          ([ 0b111 ]);\n    testType!(sint3)          ([ 0b101010 ]);\n    testType!(sint3_2)        ([ 0b101010101010 ]);\n    testType!(void2)          ([ 0b11 ]);\n    testType!(U)              ([ 0b1010 ]);\n\n    version(D_LP64)\n        _testType!(Large)          ([ 0x1000_0000__4000_0000, 0x0001_0000 ]);\n    else\n        _testType!(Large)          ([ 0x4000_0000, 0x1000_0000, 0x0001_0000 ]);\n\n    _testType!(N.CNested)     ([ 0b101000 ]);\n    _testType!(N.CNestedDerived) ([ 0b1000101000 ]);\n\n    testType!(N.Nested)       ([ 0b110 ]);\n\n    struct SFNested\n    {\n        size_t[2] d;\n        void* p1;\n        fn f;\n        // implicite outer\n\n        void foo() {} // need member fnction to not be POD\n    }\n\n    class CFNested\n    {\n        // implicit vtptr,monitor\n        size_t[2] d;\n        void* p1;\n        // implicite outer\n    }\n\n    testType!(SFNested)      ([ 0b10100 ]);\n    _testType!(CFNested)     ([ 0b110000 ]);\n}\n\nvoid main()\n{\n    testRTInfo();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/traits_getUnitTests.d",
    "content": "// REQUIRED_ARGS: -unittest\n// EXTRA_SOURCES: imports/traits_getUnitTests_import.d\nmodule traits_getUnitTests;\n\nimport imports.traits_getUnitTests_import;\n\ntemplate Tuple (T...)\n{\n    alias Tuple = T;\n}\n\nint i;\n\nunittest\n{\n    i++;\n}\n\nvoid test_getUnitTestsFromModule ()\n{\n   static assert(__traits(getUnitTests, mixin(__MODULE__)).length == 1);\n}\n\nstruct SGetUnitTestsFromAggregate\n{\n    unittest {}\n}\n\nclass CGetUnitTestsFromAggregate\n{\n    unittest {}\n}\n\nvoid test_getUnitTestsFromAggregate ()\n{\n    static assert(__traits(getUnitTests, SGetUnitTestsFromAggregate).length == 1);\n    static assert(__traits(getUnitTests, CGetUnitTestsFromAggregate).length == 1);\n}\n\nvoid test_callUnitTestFunction ()\n{\n    __traits(getUnitTests, mixin(__MODULE__))[0]();\n    assert(i == 2); // 2, because the standard unit test runner\n                    // will call the unit test function as well\n}\n\nstruct GetUnitTestsWithUDA\n{\n   @(\"asd\") unittest {}\n}\n\nvoid test_getUnitTestsWithUDA ()\n{\n    alias tests = Tuple!(__traits(getUnitTests, GetUnitTestsWithUDA));\n    static assert(tests.length == 1);\n    static assert(__traits(getAttributes, tests[0]).length == 1);\n}\n\nvoid test_getUnitTestsFromImport ()\n{\n   static assert(__traits(getUnitTests, imports.traits_getUnitTests_import).length == 1);\n   static assert(__traits(getUnitTests, mixin(\"imports.traits_getUnitTests_import\")).length == 1);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=11358\ndebug {  }\nenum len11358 = __traits(getUnitTests, mixin(__MODULE__)).length;\n\nvoid main ()\n{\n    test_getUnitTestsFromModule();\n    test_getUnitTestsFromAggregate();\n    test_callUnitTestFunction();\n    test_getUnitTestsWithUDA();\n    test_getUnitTestsFromImport();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/traits_getVirtualIndex.d",
    "content": "module traits_getVirtualIndex;\n\nclass VirtualIndexBase\n{\n    protected int _foo;\n\n    int doubler()\n    {\n        return foo * 2;\n    }\n\n    @property int foo() const\n    {\n        return _foo;\n    }\n\n    @property void foo(int val)\n    {\n        _foo = val;\n    }\n\n    final void finalFunc()\n    {\n\n    }\n}\n\nclass VirtualIndexDerived : VirtualIndexBase\n{\n    @property override int foo() const\n    {\n        return super.foo;\n    }\n\n    @property override void foo(int val)\n    {\n        super.foo = val;\n    }\n\n    @property @safe int foo() pure nothrow\n    {\n        return _foo * 2;\n    }\n\n    final void otherFinalFunc()\n    {\n\n    }\n}\n\nfinal class VirtualIndexFinal : VirtualIndexDerived\n{\n    @property final override int foo() const\n    {\n        return super.foo;\n    }\n\n    @property final override void foo(int val)\n    {\n        super.foo = val;\n    }\n\n    @property @safe final override int foo() pure nothrow\n    {\n        return super.foo;\n    }\n}\n\nprivate @property ptrdiff_t getIndex(T, string m, size_t index = 0)()\n{\n    return __traits(getVirtualIndex, __traits(getOverloads, T, m)[index]);\n}\n\nvoid main()\n{\n    ptrdiff_t doublerIndex = getIndex!(VirtualIndexBase, \"doubler\");\n    assert(doublerIndex > 0);\n    ptrdiff_t firstIndex = getIndex!(VirtualIndexBase, \"foo\", 0);\n    ptrdiff_t secondIndex = getIndex!(VirtualIndexBase, \"foo\", 1);\n    assert(firstIndex > 0 && secondIndex > 0);\n    // Virtual index is in definition order.\n    assert(secondIndex == firstIndex + 1);\n    assert(firstIndex == doublerIndex + 1);\n    ptrdiff_t finalIndex = getIndex!(VirtualIndexBase, \"finalFunc\");\n    assert(finalIndex == -1);\n    assert(getIndex!(VirtualIndexDerived, \"doubler\") == doublerIndex);\n    assert(getIndex!(VirtualIndexDerived, \"foo\", 0) == firstIndex);\n    assert(getIndex!(VirtualIndexDerived, \"foo\", 1) == secondIndex);\n    assert(getIndex!(VirtualIndexDerived, \"finalFunc\") == finalIndex);\n    assert(getIndex!(VirtualIndexDerived, \"otherFinalFunc\") == -1);\n    ptrdiff_t newOverloadIndex = getIndex!(VirtualIndexDerived, \"foo\", 2);\n    assert(newOverloadIndex == secondIndex + 1);\n    foreach(i, overload; __traits(getOverloads, VirtualIndexFinal, \"foo\"))\n    {\n        // It should still return the initial virtual index even if overridden to be final.\n        ptrdiff_t finalOverrideIndex = getIndex!(VirtualIndexFinal, __traits(identifier, overload), i);\n        ptrdiff_t originalIndex = getIndex!(VirtualIndexDerived, __traits(identifier, overload), i);\n        assert(finalOverrideIndex == originalIndex);\n    }\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/uda.d",
    "content": "\nimport core.stdc.stdio;\n\ntemplate Tuple(T...)\n{\n     alias T Tuple;\n}\n\n\n\nenum EEE = 7;\n@(\"hello\") struct SSS { }\n\n@(3) { @(4)@(EEE)@(SSS) int foo; }\n\npragma(msg, __traits(getAttributes, foo));\n\nalias Tuple!(__traits(getAttributes, foo)) TP;\n\npragma(msg, TP);\npragma(msg, TP[2]);\nTP[3] a;\npragma(msg, typeof(a));\n\n\nalias Tuple!(__traits(getAttributes, typeof(a))) TT;\n\npragma(msg, TT);\n\n@('c') string s;\npragma(msg, __traits(getAttributes, s));\n\n/************************************************/\n\nenum FFF;\n@(FFF) int x1;\npragma(msg, __traits(getAttributes, x1));\n\nvoid test1()\n{\n    alias Tuple!(__traits(getAttributes, x1)) tp;\n    assert(tp.length == 1);\n    if (!is(FFF == tp[0]))\n        assert(0);\n}\n\n/************************************************/\n\nvoid test2()\n{\n    int x;\n    alias Tuple!(__traits(getAttributes, x)) tp;\n    assert(tp.length == 0);\n}\n\n/************************************************/\n\nvoid test3()\n{\n    alias Tuple!(__traits(getAttributes, foo)) tp;\n    assert(tp.length == 4);\n    assert(tp[0] == 3);\n    assert(tp[1] == 4);\n    assert(tp[2] == 7);\n}\n\n/************************************************/\n\n@(1) void foo4();\n@(2) void foo4(int x);\n\nvoid test4()\n{\n    int i = 1;\n    foreach (o; __traits(getOverloads, uda, \"foo4\"))\n    {\n        alias Tuple!(__traits(getAttributes, o)) attrs;\n        pragma(msg, attrs.stringof);\n        assert(attrs[0] == i);\n        ++i;\n    }\n}\n\n/************************************************/\n\npragma(msg, __traits(getAttributes, aa));\nalias Tuple!(__traits(getAttributes, aa)) Taa;\n@(10) int aa;\n\npragma(msg, __traits(getAttributes, bb));\nalias Tuple!(__traits(getAttributes, bb)) Tbb;\n@(20) int bb;\nalias Tuple!(__traits(getAttributes, bb)) Tbbc;\n\n@(30) int cc;\npragma(msg, __traits(getAttributes, cc));\nalias Tuple!(__traits(getAttributes, cc)) Tcc;\n\nvoid test5()\n{\n    assert(Taa[0] == 10);\n    assert(Tbb[0] == 20);\n    assert(Tbbc[0] == 20);\n    assert(Tcc[0] == 30);\n}\n\n/************************************************/\n\nenum Test6;\n@Test6 int x6;\npragma(msg, __traits(getAttributes, x6));\n\nvoid test6()\n{\n    alias Tuple!(__traits(getAttributes, x6)) tp;\n\n    assert(tp.length == 1);\n\n    if (!is(Test6 == tp[0]))\n        assert(0);\n}\n\n/************************************************/\n\nstruct Test7\n{\n    int a;\n    string b;\n}\n\n@Test7(3, \"foo\") int x7;\npragma(msg, __traits(getAttributes, x7));\n\nvoid test7()\n{\n    alias Tuple!(__traits(getAttributes, x7)) tp;\n\n    assert(tp.length == 1);\n\n    if (!is(Test7 == typeof(tp[0])))\n        assert(0);\n\n    assert(tp[0] == Test7(3, \"foo\"));\n}\n\n/************************************************/\n\nstruct Test8 (string foo) {}\n\n@Test8!\"foo\" int x8;\npragma(msg, __traits(getAttributes, x8));\n\nvoid test8()\n{\n    alias Tuple!(__traits(getAttributes, x8)) tp;\n\n    assert(tp.length == 1);\n\n    if (!is(Test8!(\"foo\") == tp[0]))\n        assert(0);\n}\n\n/************************************************/\n\nstruct Test9 (string foo) {}\n\n@Test9!(\"foo\") int x9;\npragma(msg, __traits(getAttributes, x9));\n\nvoid test9()\n{\n    alias Tuple!(__traits(getAttributes, x9)) tp;\n\n    assert(tp.length == 1);\n\n    if (!is(Test9!(\"foo\") == tp[0]))\n        assert(0);\n}\n\n/************************************************/\n\nstruct Test10 (string foo)\n{\n    int a;\n}\n\n@Test10!\"foo\"(3) int x10;\npragma(msg, __traits(getAttributes, x10));\n\nvoid test10()\n{\n    alias Tuple!(__traits(getAttributes, x10)) tp;\n\n    assert(tp.length == 1);\n\n    if (!is(Test10!(\"foo\") == typeof(tp[0])))\n        assert(0);\n\n    assert(tp[0] == Test10!(\"foo\")(3));\n}\n\n/************************************************/\n\nstruct Test11 (string foo)\n{\n    int a;\n}\n\n@Test11!(\"foo\")(3) int x11;\npragma(msg, __traits(getAttributes, x11));\n\nvoid test11()\n{\n    alias Tuple!(__traits(getAttributes, x11)) tp;\n\n    assert(tp.length == 1);\n\n    if (!is(Test11!(\"foo\") == typeof(tp[0])))\n        assert(0);\n\n    assert(tp[0] == Test11!(\"foo\")(3));\n}\n\n/************************************************/\n\nvoid test12()\n{\n    @(1) static struct S1 { }\n    S1 s1;\n    static @(2) struct S2 { }\n    S2 s2;\n    @(1) @(2) struct S3 { }\n\n    @(1) static @(2) struct S { }\n    alias Tuple!(__traits(getAttributes, S)) tps;\n    assert(tps.length == 2);\n    assert(tps[0] == 1);\n    assert(tps[1] == 2);\n\n    @(3) int x;\n    alias Tuple!(__traits(getAttributes, x)) tpx;\n    assert(tpx.length == 1);\n    assert(tpx[0] == 3);\n    x = x + 1;\n\n    @(4) int bar() { return x; }\n    alias Tuple!(__traits(getAttributes, bar)) tpb;\n    assert(tpb.length == 1);\n    assert(tpb[0] == 4);\n    bar();\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9178\n\nvoid test9178()\n{\n    static class Foo { @(1) int a; }\n\n    Foo foo = new Foo;\n    static assert(__traits(getAttributes, foo.tupleof[0])[0] == 1);\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9652\n\nstruct Bug9652\n{\n    pragma(msg, __traits(getAttributes, enum_field));\n    alias Tuple!(__traits(getAttributes, enum_field)) Tenum_field;\n    private @(10) enum enum_field = 42;\n\n    static assert(Tenum_field[0] == 10);\n    static assert(__traits(getAttributes, enum_field)[0] == 10);\n    static assert(__traits(getProtection, enum_field) == \"private\");\n    static assert(__traits(isSame, __traits(parent, enum_field), Bug9652));\n    static assert(__traits(isSame, enum_field, enum_field));\n\n    pragma(msg, __traits(getAttributes, anon_enum_member));\n    alias Tuple!(__traits(getAttributes, anon_enum_member)) Tanon_enum_member;\n    private @(20) enum {anon_enum_member}\n\n    static assert(Tanon_enum_member[0] == 20);\n    static assert(__traits(getAttributes, anon_enum_member)[0] == 20);\n    static assert(__traits(getProtection, anon_enum_member) == \"private\");\n    static assert(__traits(isSame, __traits(parent, anon_enum_member), Bug9652));\n    static assert(__traits(isSame, anon_enum_member, anon_enum_member));\n\n    pragma(msg, __traits(getAttributes, Foo.enum_member));\n    alias Tuple!(__traits(getAttributes, Foo.enum_member)) Tfoo_enum_member;\n    private @(30) enum Foo {enum_member}\n    static assert(Tfoo_enum_member.length == 0); //Foo has attributes, not Foo.enum_member\n    static assert(__traits(getAttributes, Foo.enum_member).length == 0);\n    static assert(__traits(getProtection, Foo.enum_member) == \"public\");\n    static assert(__traits(isSame, __traits(parent, Foo.enum_member), Foo));\n    static assert(__traits(isSame, Foo.enum_member, Foo.enum_member));\n\n    pragma(msg, __traits(getAttributes, anon_enum_member_2));\n    alias Tuple!(__traits(getAttributes, anon_enum_member_2)) Tanon_enum_member_2;\n    private @(40) enum {long anon_enum_member_2 = 2L}\n\n    static assert(Tanon_enum_member_2[0] == 40);\n    static assert(__traits(getAttributes, anon_enum_member_2)[0] == 40);\n    static assert(__traits(getProtection, anon_enum_member_2) == \"private\");\n    static assert(__traits(isSame, __traits(parent, anon_enum_member_2), Bug9652));\n    static assert(__traits(isSame, anon_enum_member_2, anon_enum_member_2));\n\n    template Bug(alias X, bool is_exp)\n    {\n        static assert(is_exp == !__traits(compiles, __traits(parent, X)));\n        static assert(is_exp == !__traits(compiles, __traits(getAttributes, X)));\n        static assert(is_exp == !__traits(compiles, __traits(getProtection, X)));\n        enum Bug = 0;\n    }\n    enum en = 0;\n    enum dummy1 = Bug!(5, true);\n    enum dummy2 = Bug!(en, false);\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9741\n\nimport imports.a9741;\n\nstruct A9741 {}\n\nalias X9741 = ShowAttributes!(B9741);\n\n@A9741 struct B9741 {}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12160\n\nauto before12160(alias Hook)(string) { return 0; }\n\ntemplate checkUDAs12160(alias Func)\n{\n    enum x = __traits(getAttributes, Func).length;\n}\n\nvoid test12160()\n{\n    int foo() { return 42; }    // OK <- NG\n\n    @before12160!foo(\"name1\")\n    void bar(int name1, double name2) {}\n\n    alias X = checkUDAs12160!(bar);\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10208\n\n@( 10)                enum int x10208_01 =  100;\n@( 20)                     int x10208_02;\n@( 30)               const int x10208_03;\n@( 40)           immutable int x10208_04;\n@( 50)                     int x10208_05 =  500;\n@( 60)               const int x10208_06 =  600;\n@( 70)           immutable int x10208_07 =  700;\n@( 80) __gshared      enum int x10208_08 =  800;\n@( 90) __gshared           int x10208_09;\n@(100) __gshared     const int x10208_10;\n@(110) __gshared immutable int x10208_11;\n@(120) __gshared           int x10208_12 = 1200;\n@(130) __gshared     const int x10208_13 = 1300;\n@(140) __gshared immutable int x10208_14 = 1400;\nstatic assert(__traits(getAttributes, x10208_01)[0] ==  10); // OK\nstatic assert(__traits(getAttributes, x10208_02)[0] ==  20); // OK\nstatic assert(__traits(getAttributes, x10208_03)[0] ==  30); // OK\nstatic assert(__traits(getAttributes, x10208_04)[0] ==  40); // OK\nstatic assert(__traits(getAttributes, x10208_05)[0] ==  50); // OK\nstatic assert(__traits(getAttributes, x10208_06)[0] ==  60); // Error -> OK\nstatic assert(__traits(getAttributes, x10208_07)[0] ==  70); // Error -> OK\nstatic assert(__traits(getAttributes, x10208_08)[0] ==  80); // OK\nstatic assert(__traits(getAttributes, x10208_09)[0] ==  90); // OK\nstatic assert(__traits(getAttributes, x10208_10)[0] == 100); // OK\nstatic assert(__traits(getAttributes, x10208_11)[0] == 110); // OK\nstatic assert(__traits(getAttributes, x10208_12)[0] == 120); // OK\nstatic assert(__traits(getAttributes, x10208_13)[0] == 130); // Error -> OK\nstatic assert(__traits(getAttributes, x10208_14)[0] == 140); // Error -> OK\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11677\n// https://issues.dlang.org/show_bug.cgi?id=11678\n\nbool test_uda(alias func)() @safe\n{\n    alias Tuple!(__traits(getAttributes, func)) udas;\n    static assert([udas] == [10, 20]);\n\n    func(); // @safe attribute check\n\n    return true;\n}\n\n@(10) @(20) @safe void func11677a() {}  // OK\n@safe @(10) @(20) void func11677b() {}  // OK <- NG\n@(10) @safe @(20) void func11677c() {}  // OK <- NG\n\nstatic assert(test_uda!func11677a());\nstatic assert(test_uda!func11677b());\nstatic assert(test_uda!func11677c());\n\nvoid func11678a() @safe @(10) @(20) {}  // OK <- NG\nvoid func11678b() @(10) @safe @(20) {}  // OK <- NG\nvoid func11678c() @(10) @(20) @safe {}  // OK <- NG\n\nstatic assert(test_uda!func11678a());\nstatic assert(test_uda!func11678b());\nstatic assert(test_uda!func11678c());\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11678\n\nclass C11678\n{\n    this() @(10) @(20) {}\n    ~this() @(10) @(20) {}\n}\n\n//static this() @(10) @(20) {}\nstatic ~this() @(10) @(20) {}\n\n//shared static this() @(10) @(20) {}\nshared static ~this() @(10) @(20) {}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11679\n\nvoid test11679()\n{\n    @(10) @(20) auto var = 1;\n    static assert([__traits(getAttributes, var)] == [10, 20]);\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11680\n\n@(10) gvar11680 = 1;  // OK <- NG\n@(10) gfun11680() {}  // OK <- NG\n\nvoid test11680()\n{\n    @(10) lvar11680 = 1;  // OK <- NG\n    @(10) lfun11680() {}  // OK <- NG\n}\n\n/************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11844\n\nauto make_encode11844(T, string name)()\n{\n    return mixin(\"function(T self) { return self.encodeField!\\\"\"~ name ~ \"\\\"();}\");\n}\n\nclass FileData11844\n{\n    ulong _member;\n\n    @make_encode11844!(FileData11844, \"member\")()\n    ulong member() const { return _member; }\n\n    ubyte[] encodeField(string key)() { return [1,2,3]; }\n}\n\nstatic assert(__traits(getAttributes, FileData11844.member)[0](new FileData11844()) == [1,2,3]);\n\n/************************************************/\n\ntemplate AliasSeq(T...)\n{\n    alias AliasSeq = T;\n}\n\ntemplate ParameterUDA(size_t p_num, func...)\nif (func.length == 1 && is(typeof(func[0]) PT == __parameters) && PT.length > p_num)\n{\n    static if (is(typeof(func[0]) PT == __parameters))\n    {\n        template Get(size_t i)\n        {\n            static if (//!isFunctionPointer!func && !isDelegate!func\n                       // Parameters without UDA may yield CT error.\n                       /*&&*/ is(typeof(__traits(getAttributes, PT[i..i+1]))x))\n            {\n                alias Get = AliasSeq!(__traits(getAttributes, PT[i..i+1]));\n            }\n            else\n            {\n                alias Get = AliasSeq!();\n            }\n        }\n    }\n    else\n    {\n        static assert(0, func[0].stringof ~ \"is not a function\");\n\n        // Define dummy entities to avoid pointless errors\n        template Get(size_t i) { alias Get = AliasSeq!(); }\n        alias PT = AliasSeq!();\n    }\n\n    alias ParameterUDA = Get!p_num;\n}\n\nvoid test13x(@(10) int a, @(20) int, @(30) @(40) int[] arr...) {}\n\nvoid test13()\n{\n    static assert([ParameterUDA!(0, test13x)] == [10]);\n    static assert([ParameterUDA!(1, test13x)] == [20]);\n    static assert([ParameterUDA!(2, test13x)] == [30, 40]);\n}\n\ntemplate Test13t(F)\n{\n    static assert(!__traits(compiles, ParameterUDA!(0, F)));\n    static assert(!__traits(compiles, ParameterUDA!(1, F)));\n    static assert(!__traits(compiles, ParameterUDA!(2, F)));\n    enum Test13t = true;\n}\n\nalias test13t = Test13t!(typeof(test13x));\n\nenum Test14UDA1;\n\nstruct Test14UDA2\n{\n    string str;\n}\n\nTest14UDA2 test14uda3(string name)\n{\n    return Test14UDA2(name);\n}\n\nstruct Test14UDA4(string v)\n{\n}\n\nvoid test14x(@Test14UDA1 int, @Test14UDA2(\"1\") int, @test14uda3(\"2\") int, @Test14UDA4!\"3\" int) {}\nvoid test14()\n{\n    static assert(is(ParameterUDA!(0, test14x)[0] == Test14UDA1));\n    static assert(ParameterUDA!(1, test14x)[0] == Test14UDA2(\"1\"));\n    static assert(ParameterUDA!(2, test14x)[0] == test14uda3(\"2\"));\n    static assert(is(ParameterUDA!(3, test14x)[0] == Test14UDA4!\"3\"));\n}\n\nvoid test15x(@(20) void delegate(int) @safe dg)\n{\n    static assert([__traits(getAttributes, dg)] == [20]);\n    static assert(is(typeof(dg) == void delegate(int) @safe));\n}\n\ntemplate MinimalFunctionTypeOf(func...)\nif (func.length == 1)\n{\n    static if (is(func[0] T) || is(typeof(func[0]) T) && is(T Fdlg == delegate))\n        alias MinimalFunctionTypeOf = Fdlg; // HIT: delegate\n    else\n        static assert(0);\n}\n\ntemplate Parameters(func...)\nif (func.length == 1)\n{\n    static if (is(MinimalFunctionTypeOf!func P == function))\n        alias Parameters = P;\n    else\n        static assert(0, \"argument has no parameters\");\n}\n\nvoid test15y(@(20) void delegate(@Test14UDA2(\"2\") @(\"test15yUDA\") int) @safe dg)\n{\n    static assert([__traits(getAttributes, dg)] == [20]);\n    static assert(is(typeof(dg) == void delegate(int) @safe));\n    auto foo = (@(\"myUDA\") int x){\n        static assert([__traits(getAttributes, x)] == [\"myUDA\"]);\n    };\n    static assert(__traits(getAttributes, Parameters!dg)[0] == Test14UDA2(\"2\"));\n    static assert(__traits(getAttributes, Parameters!dg)[1] == \"test15yUDA\");\n}\n\nvoid test15z()\n{\n    test15y((@(15) @(16) int x){\n        static assert([__traits(getAttributes, x)] == [15, 16]);\n    });\n}\n\nvoid test16x(A)(@(22) A a)\n{\n    static assert([__traits(getAttributes, a)] == [22]);\n}\n\nvoid test16()\n{\n    static assert([ParameterUDA!(0, test16x!int)] == [22]);\n}\n\nvoid test17()\n{\n    void test17x(A)(@(23) A a)\n    {\n        static assert([__traits(getAttributes, a)] == [23]);\n    }\n    static assert([ParameterUDA!(0, test17x!int)] == [23]);\n}\n\nvoid test18()\n{\n    void test18a(@(Tuple!(18, \"a\")) int a)\n    {\n        static assert(__traits(getAttributes, a) == Tuple!(18, \"a\"));\n    }\n    void test18b(@Tuple!(18, \"b\") int a)\n    {\n        static assert(__traits(getAttributes, a) == Tuple!(18, \"b\"));\n    }\n\n    static assert(ParameterUDA!(0, test18a) == Tuple!(18, \"a\"));\n    static assert(ParameterUDA!(0, test18b) == Tuple!(18, \"b\"));\n}\n\n// Lambdas with parentheses:\nvoid test19()\n{\n    // lambdas without parentheses\n    alias test19a = @(3) b => 1 + 2;\n    alias test19b = @(3) @(4) b => 1 + 2;\n\n    alias test19c = (@(3) c, @(5) d) => 1 + 2;\n    alias test19d = (@(3) @(4) c, @(5) d) => 1 + 2;\n    auto test19e = (@(3) int c, @(5) int d) => 1 + 2;\n\n    // still allow alias function declarations\n    alias FuncType = @safe void function();\n    alias FuncType2 = @safe nothrow void function();\n    alias FuncType3 = nothrow void function();\n    alias FuncType4 = nothrow @safe void function();\n}\n\nvoid test20()\n{\n    // Using a delegate with inferred parameter type\n    void test20a(int delegate(int) t){ t(1); }\n    test20a((@(19) a) {\n        static assert([__traits(getAttributes, a)] == [19]);\n        return a + 2;\n    });\n}\n\n/************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test9178();\n    test13();\n    test14();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/ufcs.d",
    "content": "// EXTRA_SOURCES: imports/ufcs5a.d imports/ufcs5b.d imports/ufcs5c.d imports/ufcs5d.d imports/ufcs5e.d\n\nmodule ufcs;\n\nextern (C) int printf(const char*, ...);\n\n/*******************************************/\n\nstruct S {}\n\nint foo(int n)          { return 1; }\nint foo(int n, int m)   { return 2; }\nint goo(int[] a)        { return 1; }\nint goo(int[] a, int m) { return 2; }\nint bar(S s)            { return 1; }\nint bar(S s, int n)     { return 2; }\n\nint baz(X)(X x)         { return 1; }\nint baz(X)(X x, int n)  { return 2; }\n\nint temp;\nref int boo(int n)      { return temp; }\nref int coo(int[] a)    { return temp; }\nref int mar(S s)        { return temp; }\n\nref int maz(X)(X x)     { return temp; }\n\nvoid test1()\n{\n    int n;\n    int[] a;\n    S s;\n\n    assert(   foo(4)    == 1);      assert(   baz(4)    == 1);\n    assert( 4.foo()     == 1);      assert( 4.baz()     == 1);\n    assert( 4.foo       == 1);      assert( 4.baz       == 1);\n    assert(   foo(4, 2) == 2);      assert(   baz(4, 2) == 2);\n    assert( 4.foo(2)    == 2);      assert( 4.baz(2)    == 2);\n    assert((4.foo = 2)  == 2);      assert((4.baz = 2)  == 2);\n\n    assert(   goo(a)    == 1);      assert(   baz(a)    == 1);\n    assert( a.goo()     == 1);      assert( a.baz()     == 1);\n    assert( a.goo       == 1);      assert( a.baz       == 1);\n    assert(   goo(a, 2) == 2);      assert(   baz(a, 2) == 2);\n    assert( a.goo(2)    == 2);      assert( a.baz(2)    == 2);\n    assert((a.goo = 2)  == 2);      assert((a.baz = 2)  == 2);\n\n    assert(   bar(s)    == 1);      assert(   baz(s)    == 1);\n    assert( s.bar()     == 1);      assert( s.baz()     == 1);\n    assert( s.bar       == 1);      assert( s.baz       == 1);\n    assert(   bar(s, 2) == 2);      assert(   baz(s, 2) == 2);\n    assert( s.bar(2)    == 2);      assert( s.baz(2)    == 2);\n    assert((s.bar = 2)  == 2);      assert((s.baz = 2)  == 2);\n\n    assert((  boo(4) = 2) == 2);    assert((  maz(4) = 2) == 2);\n    assert((4.boo    = 2) == 2);    assert((4.maz    = 2) == 2);\n    assert((  coo(a) = 2) == 2);    assert((  maz(a) = 2) == 2);\n    assert((a.coo    = 2) == 2);    assert((a.maz    = 2) == 2);\n    assert((  mar(s) = 2) == 2);    assert((  maz(s) = 2) == 2);\n    assert((s.mar    = 2) == 2);    assert((s.maz    = 2) == 2);\n}\n\nint hoo(T)(int n)          { return 1; }\nint hoo(T)(int n, int m)   { return 2; }\nint koo(T)(int[] a)        { return 1; }\nint koo(T)(int[] a, int m) { return 2; }\nint var(T)(S s)            { return 1; }\nint var(T)(S s, int n)     { return 2; }\n\nint vaz(T, X)(X x)         { return 1; }\nint vaz(T, X)(X x, int n)  { return 2; }\n\n//int temp;\nref int voo(T)(int n)      { return temp; }\nref int woo(T)(int[] a)    { return temp; }\nref int nar(T)(S s)        { return temp; }\n\nref int naz(T, X)(X x)     { return temp; }\n\nvoid test2()\n{\n    int n;\n    int[] a;\n    S s;\n\n    assert(   hoo!int(4)    == 1);  assert(   vaz!int(4)    == 1);\n    assert( 4.hoo!int()     == 1);  assert( 4.vaz!int()     == 1);\n    assert( 4.hoo!int       == 1);  assert( 4.vaz!int       == 1);\n    assert(   hoo!int(4, 2) == 2);  assert(   vaz!int(4, 2) == 2);\n    assert( 4.hoo!int(2)    == 2);  assert( 4.vaz!int(2)    == 2);\n    assert((4.hoo!int = 2)  == 2);  assert((4.vaz!int = 2)  == 2);\n\n    assert(   koo!int(a)    == 1);  assert(   vaz!int(a)    == 1);\n    assert( a.koo!int()     == 1);  assert( a.vaz!int()     == 1);\n    assert( a.koo!int       == 1);  assert( a.vaz!int       == 1);\n    assert(   koo!int(a, 2) == 2);  assert(   vaz!int(a, 2) == 2);\n    assert( a.koo!int(2)    == 2);  assert( a.vaz!int(2)    == 2);\n    assert((a.koo!int = 2)  == 2);  assert((a.vaz!int = 2)  == 2);\n\n    assert(   var!int(s)    == 1);  assert(   vaz!int(s)    == 1);\n    assert( s.var!int()     == 1);  assert( s.vaz!int()     == 1);\n    assert( s.var!int       == 1);  assert( s.vaz!int       == 1);\n    assert(   var!int(s, 2) == 2);  assert(   vaz!int(s, 2) == 2);\n    assert( s.var!int(2)    == 2);  assert( s.vaz!int(2)    == 2);\n    assert((s.var!int = 2)  == 2);  assert((s.vaz!int = 2)  == 2);\n\n    assert((  voo!int(4) = 2) == 2);    assert((  naz!int(4) = 2) == 2);\n    assert((4.voo!int    = 2) == 2);    assert((4.naz!int    = 2) == 2);\n    assert((  woo!int(a) = 2) == 2);    assert((  naz!int(a) = 2) == 2);\n    assert((a.woo!int    = 2) == 2);    assert((a.naz!int    = 2) == 2);\n    assert((  nar!int(s) = 2) == 2);    assert((  naz!int(s) = 2) == 2);\n    assert((s.nar!int    = 2) == 2);    assert((s.naz!int    = 2) == 2);\n}\n\n/*******************************************/\n\nauto init(T)(T val) { return 1; }\n\nauto sort(alias fun, T)(T val) { return 1; }\n\n@property auto max(alias fun, T)(T val) { return 1; }\n\n@property auto infinity(alias opt, T)(T val) { return 1; }\n\nvoid test3()\n{\n    // See built-in 'init' property\n    assert(1    .init == 0);\n    assert([1]  .init == null);\n    assert([1:1].init == null);\n    assert(1.0  .init is double.nan);\n    assert(10i  .init is idouble.nan);\n    assert('c'  .init == 0xFF);\n    assert(\"s\"  .init == null);\n\n    // x.init() has parens, so it runs UFCS call\n    assert( 1   .init() == 1);\n    assert([1]  .init() == 1);\n    assert([1:1].init() == 1);\n    assert(1.0  .init() == 1);\n    assert(10i  .init() == 1);\n    assert('c'  .init() == 1);\n    assert(\"s\"  .init() == 1);\n\n    // x.init!YYY matches templatized UFCS call.\n    assert( 1   .init!int()        == 1);\n    assert([1]  .init!(int[])()    == 1);\n    assert([1:1].init!(int[int])() == 1);\n    assert(1.0  .init!double()     == 1);\n    assert(10i  .init!idouble()    == 1);\n    assert('c'  .init!char()       == 1);\n    assert(\"s\"  .init!string()     == 1);\n\n    assert([1].sort!\"a<b\"() == 1);\n\n    // templatized properties runs UFCS call.\n    assert(1024.max!\"a<b\" == 1);\n    assert(1024.max  == int.max);\n\n    assert(3.14.infinity!\"+\" == 1);\n    assert(3.14.infinity == (double).infinity);\n}\n\n/*******************************************/\n\ntemplate Signal4()\n{\n    void connect(){}\n}\nstruct S4\n{\n    mixin Signal4!() s;\n}\nvoid test4()\n{\n    S4 s;\n    s.s.connect();  // s.s is TOKdotexp, so never match UFCS\n}\n\n/*******************************************/\n\nauto f5_1(int)    { return 1; }\nauto f5_2(string) { return 2; }\nauto f5_3(double) { return 3; }\nalias f5_4 = f5_1, f5_4 = f5_2;\nalias f5_5 = f5_3, f5_5 = f5_4;\n\n@property p5_1(int)    { return 1; }    @property p5_1(int,    int) { return 1; }\n@property p5_2(string) { return 2; }    @property p5_2(string, int) { return 2; }\n@property p5_3(double) { return 3; }    @property p5_3(double, int) { return 3; }\nalias p5_4 = p5_1, p5_4 = p5_2;         alias p5_4 = p5_1, p5_4 = p5_2;\nalias p5_5 = p5_3, p5_5 = p5_4;         alias p5_5 = p5_3, p5_5 = p5_4;\n\n// import overload set 'f5ov' and 'p5ov'\nimport imports.ufcs5b, imports.ufcs5c;\n\nvoid test5()\n{\n    {\n        // f5_1 .. f5_5 are symbols which declared in module scope\n        assert(100.f5_1() == 1);\n        assert(\"s\".f5_2() == 2);\n        assert(1.4.f5_3() == 3);\n        assert(100.f5_4() == 1);\n        assert(\"s\".f5_4() == 2);\n        assert(100.f5_5() == 1);\n        assert(\"s\".f5_5() == 2);\n        assert(1.4.f5_5() == 3);\n        // overload set\n        assert(100.f5ov() == 1);\n        assert(\"s\".f5ov() == 2);\n        // UFCS does not see function local alias\n        alias func5 = f5_1;\n        static assert(!__traits(compiles, { 1.func5(); }));\n\n        // property getter/setter\n        assert(100.p5_1 == 1);      assert((100.p5_1 = 1) == 1);\n        assert(\"s\".p5_2 == 2);      assert((\"s\".p5_2 = 1) == 2);\n        assert(1.4.p5_3 == 3);      assert((1.4.p5_3 = 1) == 3);\n        assert(100.p5_4 == 1);      assert((100.p5_4 = 1) == 1);\n        assert(\"s\".p5_4 == 2);      assert((\"s\".p5_4 = 1) == 2);\n        assert(100.p5_5 == 1);      assert((100.p5_5 = 1) == 1);\n        assert(\"s\".p5_5 == 2);      assert((\"s\".p5_5 = 1) == 2);\n        assert(1.4.p5_5 == 3);      assert((1.4.p5_5 = 1) == 3);\n        // overload set     );      assert(\n        assert(100.p5ov == 1);      assert((100.p5ov = 1) == 1);\n        assert(\"s\".p5ov == 2);      assert((\"s\".p5ov = 1) == 2);\n        // local alias\n        alias prop5 = p5_1;\n        static assert(!__traits(compiles, { 1.prop5; }));\n        static assert(!__traits(compiles, { 1.prop5 = 1; }));\n    }\n\n    {\n        // f5a1 .. f5a5 are symbols which declared in module scope\n        import imports.ufcs5a;\n        // overload set 'f5ov' and 'p5ov'\n        import imports.ufcs5b, imports.ufcs5c;\n\n        assert(100.f5a1() == 1);\n        assert(\"s\".f5a2() == 2);\n        assert(1.4.f5a3() == 3);\n        assert(100.f5a4() == 1);\n        assert(\"s\".f5a4() == 2);\n        assert(100.f5a5() == 1);\n        assert(\"s\".f5a5() == 2);\n        assert(1.4.f5a5() == 3);\n        assert(100.f5ov() == 1);\n        assert(\"s\".f5ov() == 2);\n\n        assert(100.p5a1 == 1);      assert((100.p5a1 = 1) == 1);\n        assert(\"s\".p5a2 == 2);      assert((\"s\".p5a2 = 1) == 2);\n        assert(1.4.p5a3 == 3);      assert((1.4.p5a3 = 1) == 3);\n        assert(100.p5a4 == 1);      assert((100.p5a4 = 1) == 1);\n        assert(\"s\".p5a4 == 2);      assert((\"s\".p5a4 = 1) == 2);\n        assert(100.p5a5 == 1);      assert((100.p5a5 = 1) == 1);\n        assert(\"s\".p5a5 == 2);      assert((\"s\".p5a5 = 1) == 2);\n        assert(1.4.p5a5 == 3);      assert((1.4.p5a5 = 1) == 3);\n        assert(100.p5ov == 1);      assert((100.p5ov = 1) == 1);\n        assert(\"s\".p5ov == 2);      assert((\"s\".p5ov = 1) == 2);\n    }\n\n    {\n        // selective imports also work as expected\n        import imports.ufcs5a : f5a1, f5a2;\n        import imports.ufcs5a : p5a1, p5a2;\n\n        assert(100.f5a1() == 1);\n        assert(\"s\".f5a2() == 2);\n        static assert(!__traits(compiles, { 1.4.f5a3(); }));\n        static assert(!__traits(compiles, { 100.f5a4(); }));\n        static assert(!__traits(compiles, { \"s\".f5a4(); }));\n        static assert(!__traits(compiles, { 100.f5a5(); }));\n        static assert(!__traits(compiles, { \"s\".f5a5(); }));\n        static assert(!__traits(compiles, { 1.4.f5a5(); }));\n\n        assert(100.p5a1 == 1);      assert((100.p5a1 = 1) == 1);\n        assert(\"s\".p5a2 == 2);      assert((\"s\".p5a2 = 1) == 2);\n        static assert(!__traits(compiles, { 1.4.p5a3; }) && !__traits(compiles, { 1.4.p5a3 = 1; }));\n        static assert(!__traits(compiles, { 100.p5a4; }) && !__traits(compiles, { 100.p5a4 = 1; }));\n        static assert(!__traits(compiles, { \"s\".p5a4; }) && !__traits(compiles, { \"s\".p5a4 = 1; }));\n        static assert(!__traits(compiles, { 100.p5a5; }) && !__traits(compiles, { 100.p5a5 = 1; }));\n        static assert(!__traits(compiles, { \"s\".p5a5; }) && !__traits(compiles, { \"s\".p5a5 = 1; }));\n        static assert(!__traits(compiles, { 1.4.p5a5; }) && !__traits(compiles, { 1.4.p5a5 = 1; }));\n    }\n\n    {\n        // renamed imports also work as expected\n        import imports.ufcs5a : f5x1 = f5a1, f5x2 = f5a2;\n        import imports.ufcs5a : p5x1 = p5a1, p5x2 = p5a2;\n\n        assert(100.f5x1() == 1);\n        assert(\"s\".f5x2() == 2);\n        static assert(!__traits(compiles, { 100.f5a1(); }));\n        static assert(!__traits(compiles, { \"s\".f5a2(); }));\n        static assert(!__traits(compiles, { 1.4.f5a3(); }));\n        static assert(!__traits(compiles, { 100.f5a4(); }));\n        static assert(!__traits(compiles, { \"s\".f5a4(); }));\n        static assert(!__traits(compiles, { 100.f5a5(); }));\n        static assert(!__traits(compiles, { \"s\".f5a5(); }));\n        static assert(!__traits(compiles, { 1.4.f5a5(); }));\n\n        assert(100.p5x1 == 1);      assert((100.p5x1 = 1) == 1);\n        assert(\"s\".p5x2 == 2);      assert((\"s\".p5x2 = 1) == 2);\n        static assert(!__traits(compiles, { 100.p5a1; }) && !__traits(compiles, { 100.p5a1 = 1; }));\n        static assert(!__traits(compiles, { \"s\".p5a2; }) && !__traits(compiles, { \"s\".p5a2 = 1; }));\n        static assert(!__traits(compiles, { 1.4.p5a3; }) && !__traits(compiles, { 1.4.p5a3 = 1; }));\n        static assert(!__traits(compiles, { 100.p5a4; }) && !__traits(compiles, { 100.p5a4 = 1; }));\n        static assert(!__traits(compiles, { \"s\".p5a4; }) && !__traits(compiles, { \"s\".p5a4 = 1; }));\n        static assert(!__traits(compiles, { 100.p5a5; }) && !__traits(compiles, { 100.p5a5 = 1; }));\n        static assert(!__traits(compiles, { \"s\".p5a5; }) && !__traits(compiles, { \"s\".p5a5 = 1; }));\n        static assert(!__traits(compiles, { 1.4.p5a5; }) && !__traits(compiles, { 1.4.p5a5 = 1; }));\n    }\n\n    {\n        auto c5 = new C5();\n        foreach (name; __traits(allMembers, C5))\n        {\n            static if (name.length >= 4 && name[0..4] == \"test\")\n            {\n                mixin(\"c5.\"~name~\"();\");    // call test function\n            }\n        }\n    }\n}\n\nclass B5\n{\n    int g5bm(int) { return 0; }\n    static int g5bs(int) { return 0; }\n\n}\nclass C5 : B5\n{\n    // normal import works.\n    import imports.ufcs5a;\n    void test1()\n    {\n        assert(100.f5a1() == 1);\n        assert(\"s\".f5a2() == 2);\n        assert(1.4.f5a3() == 3);\n        assert(100.f5a4() == 1);\n        assert(\"s\".f5a4() == 2);\n        assert(100.f5a5() == 1);\n        assert(\"s\".f5a5() == 2);\n        assert(1.4.f5a5() == 3);\n\n        assert(100.p5a1 == 1);      assert((100.p5a1 = 1) == 1);\n        assert(\"s\".p5a2 == 2);      assert((\"s\".p5a2 = 1) == 2);\n        assert(1.4.p5a3 == 3);      assert((1.4.p5a3 = 1) == 3);\n        assert(100.p5a4 == 1);      assert((100.p5a4 = 1) == 1);\n        assert(\"s\".p5a4 == 2);      assert((\"s\".p5a4 = 1) == 2);\n        assert(100.p5a5 == 1);      assert((100.p5a5 = 1) == 1);\n        assert(\"s\".p5a5 == 2);      assert((\"s\".p5a5 = 1) == 2);\n        assert(1.4.p5a5 == 3);      assert((1.4.p5a5 = 1) == 3);\n    }\n\n    // selective imports also work as expected\n    import imports.ufcs5d : f5d1, f5d2;\n    import imports.ufcs5d : p5d1, p5d2;\n    void test2()\n    {\n        assert(100.f5d1() == 1);\n        assert(\"s\".f5d2() == 2);\n        static assert(!__traits(compiles, { 1.4.f5d3(); }));\n        static assert(!__traits(compiles, { 100.f5d4(); }));\n        static assert(!__traits(compiles, { \"s\".f5d4(); }));\n        static assert(!__traits(compiles, { 100.f5d5(); }));\n        static assert(!__traits(compiles, { \"s\".f5d5(); }));\n        static assert(!__traits(compiles, { 1.4.f5d5(); }));\n\n        assert(100.p5d1 == 1);  assert((100.p5d1 = 1) == 1);\n        assert(\"s\".p5d2 == 2);  assert((\"s\".p5d2 = 1) == 2);\n        static assert(!__traits(compiles, { 1.4.p5d3; }) && !__traits(compiles, { 1.4.p5d3 = 1; }));\n        static assert(!__traits(compiles, { 100.p5d4; }) && !__traits(compiles, { 100.p5d4 = 1; }));\n        static assert(!__traits(compiles, { \"s\".p5d4; }) && !__traits(compiles, { \"s\".p5d4 = 1; }));\n        static assert(!__traits(compiles, { 100.p5d5; }) && !__traits(compiles, { 100.p5d5 = 1; }));\n        static assert(!__traits(compiles, { \"s\".p5d5; }) && !__traits(compiles, { \"s\".p5d5 = 1; }));\n        static assert(!__traits(compiles, { 1.4.p5d5; }) && !__traits(compiles, { 1.4.p5d5 = 1; }));\n    }\n\n    // renamed imports also work as expected\n    import imports.ufcs5e : f5y1 = f5e1, f5y2 = f5e2;\n    import imports.ufcs5e : p5y1 = p5e1, p5y2 = p5e2;\n    void test3()\n    {\n        assert(100.f5y1() == 1);\n        assert(\"s\".f5y2() == 2);\n        static assert(!__traits(compiles, { 100.f5e1(); }));\n        static assert(!__traits(compiles, { \"s\".f5e2(); }));\n        static assert(!__traits(compiles, { 1.4.f5e3(); }));\n        static assert(!__traits(compiles, { 100.f5e4(); }));\n        static assert(!__traits(compiles, { \"s\".f5e4(); }));\n        static assert(!__traits(compiles, { 100.f5e5(); }));\n        static assert(!__traits(compiles, { \"s\".f5e5(); }));\n        static assert(!__traits(compiles, { 1.4.f5e5(); }));\n\n        assert(100.p5y1 == 1);  assert((100.p5y1 = 1) == 1);\n        assert(\"s\".p5y2 == 2);  assert((\"s\".p5y2 = 1) == 2);\n        static assert(!__traits(compiles, { 100.p5e1; }) && !__traits(compiles, { (100.p5e1 = 1); }));\n        static assert(!__traits(compiles, { \"s\".p5e2; }) && !__traits(compiles, { (\"s\".p5e2 = 1); }));\n        static assert(!__traits(compiles, { 1.4.p5e3; }) && !__traits(compiles, { (1.4.p5e3 = 1); }));\n        static assert(!__traits(compiles, { 100.p5e4; }) && !__traits(compiles, { (100.p5e4 = 1); }));\n        static assert(!__traits(compiles, { \"s\".p5e4; }) && !__traits(compiles, { (\"s\".p5e4 = 1); }));\n        static assert(!__traits(compiles, { 100.p5e5; }) && !__traits(compiles, { (100.p5e5 = 1); }));\n        static assert(!__traits(compiles, { \"s\".p5e5; }) && !__traits(compiles, { (\"s\".p5e5 = 1); }));\n        static assert(!__traits(compiles, { 1.4.p5e5; }) && !__traits(compiles, { (1.4.p5e5 = 1); }));\n    }\n\n    int g5cm(int) { return 0; }\n    static int g5cs(int) { return 0; }\n    void test4()\n    {\n        // UFCS does not see aggregate members\n        static assert(!__traits(compiles, { 1.g5cm(); }));\n        static assert(!__traits(compiles, { 1.g5cs(); }));\n\n        // Even if it is in base class\n        static assert(!__traits(compiles, { 1.g5bm(); }));\n        static assert(!__traits(compiles, { 1.g5bs(); }));\n    }\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=662\n\nimport std.stdio,std.string, std.conv;\n\nenum Etest\n{\n    a,b,c,d\n}\n\n//typedef int testi = 10;\n//typedef Test Test2;\n\nint test() { return 33; }\n\nclass Test\n{\n    static int test(int i) { return i; }\n}\n\nint test(Etest test)\n{\n    return cast(int)test;\n}\n\n//int test(testi i)\n//{\n//  return cast(int)i;\n//}\n\nvoid test682()\n{\n    assert(22.to!string() == \"22\");\n    assert((new Test).test(11) == 11);\n    assert(Test.test(11) == 11);\n    //assert(Test2.test(11) == 11);\n    assert(test() == 33);\n    assert(ufcs.test() == 33);\n    assert(Etest.d.test() == Etest.d);\n    //testi i;\n    //assert(i.test() == i.init);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3382\n\nimport std.range, std.algorithm;\n\n@property T twice(T)(T x){ return x * x; }\nreal toreal(ireal x){ return x.im; }\nchar toupper(char c){ return ('a'<=c && c<='z') ? cast(char)(c - 'a' + 'A') : c; }\n\n@property ref T setter(T)(ref T x, T v){ x = v; return x; }\n\nvoid test3382()\n{\n    auto r = iota(0, 10).map!\"a*3\"().filter!\"a%2 != 0\"();\n    foreach (e; r)\n        printf(\"e = %d\\n\", e);\n\n    assert(10.twice == 100);\n    assert(0.5.twice == 0.25);\n    assert(1.4i.toreal() == 1.4);\n    assert('c'.toupper() == 'C');\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6185\n\nvoid test6185()\n{\n    import std.algorithm;\n\n    auto r1 = [1,2,3].map!\"a*2\";\n    assert(equal(r1, [2,4,6]));\n\n    auto r2 = r1.map!\"a+2\"();\n    assert(equal(r2, [4,6,8]));\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6070\n\nenum test6070a = [\"test\"].foo6070();\nenum test6070b = foo6070([\"test\"]);\n\nstring foo6070(string[] s) { return \"\"; }\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7670\n\nstruct A7670\n{\n    double x;\n}\n@property ref double y7670(ref A7670 a)\n{\n    return a.x;\n}\nvoid test7670()\n{\n    A7670 a1;\n    a1.y7670() = 2.0; // OK\n    a1.y7670 = 2.0; // Error\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7703\nvoid f7703(T)(T a) { }\n\nvoid test7703()\n{\n    int x;\n    x.f7703;        // accepted\n    x.f7703();      // accepted\n    x.f7703!int;    // rejected -- \"f(x) isn't a template\"\n    x.f7703!int();  // accepted\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7773\n\n//import std.stdio;\nvoid writeln7773(int n){}\nvoid test7773()\n{\n    (int.max).writeln7773(); // OK\n    int.max.writeln7773();   // error\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7943\n\nstruct Foo7943\n{\n    int _member;\n    alias _member this;\n}\n\nint foo7943(Foo7943 f) { return 1; }\nint foo7943(int i) { return 2; }\n\nvoid test7943()\n{\n    Foo7943 f;\n    assert(f.foo7943() == 1);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8180\n\nint writeln8180(T...)(T args) { return 1; }\n\nstruct Tuple8180(T...)\n{\n    T field;\n    alias field this;\n}\n\nvoid test8180()\n{\n    auto t = Tuple8180!(int)(10);\n    assert(t.writeln8180() == 1);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8245\n\n          string toStr8245(immutable(char)* p) { return null; }\n@property string asStr8245(immutable(char)* p) { return null; }\n\nvoid test8245()\n{\n    immutable(char)* p = \"foobar\".ptr;\n    p.toStr8245();\n    p.asStr8245;    // Error: no property 'asStr' for type 'immutable(char)'\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8252\n\nbool f(int x) { return !x; }\n\nvoid test8252()\n{\n    static assert(!1.f); // ok\n    static assert( 0.f); // fail\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8453\n\nT[] sort8453(T)(T[] a) { return a; }\n\nvoid test8453()\n{\n    int[int] foo;\n    auto bar1 = foo.keys().sort8453(); // OK\n    auto bar2 = foo.keys.sort8453();   // Error\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8503\n\nvoid α8503(int i) {}\n\nvoid test8503()\n{\n    0.α8503();  // Error\n    1.α8503();  // Error\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9014\n\n@property ref int foo9014(int[] a)\n{\n    return a[0];\n}\nvoid test9014()\n{\n    int[] bar;\n  static assert(!__traits(compiles, {\n    bar.foo9014 = missing.foo9014;\n  }));\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9590\n\nauto func9590(E)(lazy E expr) { }\n\nint f9590a()  { assert(0); }\nvoid f9590b() { assert(0); }\n\nvoid test9590()\n{\n    func9590(f9590a());  // ok, no exceptions (lazy)\n    f9590a().func9590;   // ok, no exceptions (lazy)\n\n    func9590(f9590b());  // ok, no exceptions (lazy)\n    f9590b().func9590;   // L12: NG\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9946\n\nsize_t count9946(alias x)(int[] haystack)\n{\n    return 0;\n}\nvoid test9946()\n{\n    int[] data;\n    auto n1 = count9946!5(data);          // OK\n    auto n2 = data.count9946!5;           // OK\n    auto a1 = new int[count9946!5(data)]; // OK\n    auto a2 = new int[data.count9946!5];  // Error\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10618\n\ntemplate Temp10618(T)\n{\n    size_t len = 1;\n}\nvoid test10618()\n{\n    auto arr = new int[Temp10618!int.len];\n    assert(arr.length == 1);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10003\n\nvoid foo10003(void *p) {}\nvoid test10003()\n{\n    void* p;\n    p.foo10003();\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10041\n\nauto writeln10041(T...)(T args) { return typeof(args[0]).stringof; }\n\nvoid test10041()\n{\n    auto aa = [1: 2];\n    assert(aa.writeln10041 == \"int[int]\");\n    assert(writeln10041(aa) == \"int[int]\");\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10047\n\nstruct Typedef10047(T)\n{\n    template opDispatch(string name)\n    {\n        static assert(0);\n    }\n}\n\nstruct A10047 {}\nint foo10047(Typedef10047!A10047 a) { return 10; }\n\nvoid test10047()\n{\n    Typedef10047!A10047 a;\n    assert(a.foo10047() == 10);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10166\n\nauto foo10166()\n{\n    0.bar10166!({})(0);\n}\n\nvoid bar10166(alias handler, T)(T t, int i)\n{\n    t.bar10166!buzz10166(i);\n}\n\nvoid buzz10166() {}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10526\n\nstruct S10526\n{\n    int opDispatch(string s, A...)(A args)\n    if (s[0..3] == \"foo\")\n    {\n        return 1;\n    }\n}\nint bar10526(X)(X) { return 2; }\nint baz10526(T, X)(X) { return 3; }\n\nvoid test10526()\n{\n    S10526 s;\n\n    // with parenthesis\n    assert(s.foo10526() == 1);\n    assert(s.bar10526() == 2);\n    assert(s.baz10526!string() == 3);\n\n    // without parenthesis\n    assert(s.foo10526 == 1);\n    assert(s.bar10526 == 2);\n    assert(s.baz10526!string == 3);\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10609\n\nint foo10609(int x) { return x; }\n\nvoid test10609()\n{\n    int x = 1;\n    static assert(__traits(compiles, foo10609(x)));\n    static assert(__traits(compiles, 1.foo10609 ));\n    static assert(__traits(compiles, x.foo10609 ));\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11312\n\nstruct S11312;\n\nS11312* getS11312() { return null; }\nint getValue(S11312*) { return 10; }\n\nvoid test11312()\n{\n    S11312* op = getS11312();\n    int x = op.getValue();\n    assert(x == 10);\n}\n\n/*******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15123\n\nauto keys15123(K, V)(V[K] aa) { return [1]; }\nauto values15123(K, V)(V[K] aa) { return [2]; }\n\nalias id15123(alias arg) = arg;\n\nenum int[int] aa15123 = [1:2];\nstatic assert(id15123!(aa15123.keys15123) == [1]);  // TypeIdentifier + UFCS\n\nT[T] f15123(T)() { return [1:2]; }\nstatic assert(id15123!(f15123!int.values15123) == [2]); // TypeInstance + UFCS\n\n/*******************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test682();\n    test3382();\n    test6185();\n    test7670();\n    test7703();\n    test7773();\n    test7943();\n    test8180();\n    test8245();\n    test8252();\n    test8453();\n    test8503();\n    test9014();\n    test9590();\n    test9946();\n    test10618();\n    test10003();\n    test10041();\n    test10047();\n    test10526();\n    test11312();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/uniformctor.d",
    "content": "extern(C) int printf(const char*, ...);\ntemplate TypeTuple(TL...) { alias TypeTuple = TL; }\n\nimport core.stdc.math : isnan;\n\n/********************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9112\n\nvoid test9112a()    //  T() and T(v)\n{\n    void test(T)(T v)\n    {\n        foreach (string qual; TypeTuple!(\"\", \"const \", \"immutable \"))\n        {\n            mixin(\"alias U = \"~qual~T.stringof~\";\");\n            //pragma(msg, U);\n\n            mixin(\"auto x1 = \"~qual~T.stringof~\"();\");      // U()      default construction syntax\n            mixin(\"auto x2 = \"~qual~T.stringof~\"(v);\");     // U(v)\n            static assert(!__traits(compiles, mixin(qual~T.stringof~\"(v, v)\")));    // U(v, v)\n            static assert(is(typeof(x1) == U));\n            static assert(is(typeof(x2) == U));\n            static if ( is(typeof(U.nan) :  real)) assert( isnan(x1.re) && !isnan(x1.im), U.stringof);\n            static if ( is(typeof(U.nan) : ireal)) assert(!isnan(x1.re) &&  isnan(x1.im), U.stringof);\n            static if ( is(typeof(U.nan) : creal)) assert( isnan(x1.re) &&  isnan(x1.im), U.stringof);\n            static if (!is(typeof(U.nan)))         assert( x1 == U.init,                  U.stringof);\n            assert(x2 == v, U.stringof);\n        }\n    }\n    static assert(!__traits(compiles, { auto x1 = void(); }));\n    static assert(!__traits(compiles, { auto x2 = void(1); }));\n    test!( byte  )(10);\n    test!(ubyte  )(10);\n    test!( short )(10);\n    test!(ushort )(10);\n    test!( int   )(10);\n    test!(uint   )(10);\n    test!( long  )(10);\n    test!(ulong  )(10);\n    test!( float )(3.14);\n    test!( double)(3.14);\n    test!( real  )(3.14);\n    test!(ifloat )(1.4142i);\n    test!(idouble)(1.4142i);\n    test!(ireal  )(1.4142i);\n    test!(cfloat )(1.2+3.4i);\n    test!(cdouble)(1.2+3.4i);\n    test!(creal  )(1.2+3.4i);\n    test!( char  )('A');\n    test!(wchar  )('A');\n    test!(dchar  )('A');\n    test!(bool   )(true);\n\n    static assert(!__traits(compiles, int(1.42)));  // in curre,t this is disallowed\n    static assert(!__traits(compiles, double(3.14i)));\n\n    {\n        int x;\n        alias T = int*;\n      //auto p = int*(&x);      // Error: found '*' when expecting '.' following int\n      //auto p = (int*)(&x);    // Error: C style cast illegal, use cast(int*)&x\n        auto p = T(&x);\n        assert( p == &x);\n        assert(*p ==  x);\n    }\n}\n\nenum Enum : long { a = 10, b = 20 }\n\nvoid test9112b()    // new T(v)\n{\n    void test(T)(T v)\n    {\n        foreach (string qual; TypeTuple!(\"\", \"const \", \"immutable \"))\n        {\n            mixin(\"alias U = \"~qual~T.stringof~\";\");\n            //pragma(msg, U);\n\n            mixin(\"auto p1 = new \"~qual~T.stringof~\"();\");      // U()      default construction syntax\n            mixin(\"auto p2 = new \"~qual~T.stringof~\"(v);\");     // U(v)\n            static assert(!__traits(compiles, mixin(\"new \"~qual~T.stringof~\"(v, v)\")));    // U(v, v)\n            static assert(is(typeof(p1) == U*));\n            static assert(is(typeof(p2) == U*));\n            assert( p1 !is null);\n            assert( p2 !is null);\n            auto x1 = *p1;\n            auto x2 = *p2;\n            static if ( is(typeof(U.nan) :  real)) assert( isnan(x1.re) && !isnan(x1.im), U.stringof);\n            static if ( is(typeof(U.nan) : ireal)) assert(!isnan(x1.re) &&  isnan(x1.im), U.stringof);\n            static if ( is(typeof(U.nan) : creal)) assert( isnan(x1.re) &&  isnan(x1.im), U.stringof);\n            static if (!is(typeof(U.nan)))         assert( x1 == U.init,                  U.stringof);\n            assert(x2 == v, U.stringof);\n        }\n    }\n\n    static assert(!__traits(compiles, { auto x1 = new void(); }));\n    static assert(!__traits(compiles, { auto x2 = new void(1); }));\n    static assert(!__traits(compiles, { auto x2 = new void(1, 2); }));\n    test!( byte  )(10);\n    test!(ubyte  )(10);\n    test!( short )(10);\n    test!(ushort )(10);\n    test!( int   )(10);\n    test!(uint   )(10);\n    test!( long  )(10);\n    test!(ulong  )(10);\n    test!( float )(3.14);\n    test!( double)(3.14);\n    test!( real  )(3.14);\n    test!(ifloat )(1.4142i);\n    test!(idouble)(1.4142i);\n    test!(ireal  )(1.4142i);\n    test!(cfloat )(1.2+3.4i);\n    test!(cdouble)(1.2+3.4i);\n    test!(creal  )(1.2+3.4i);\n    test!( char  )('A');\n    test!(wchar  )('A');\n    test!(dchar  )('A');\n    test!(bool   )(true);\n    test!(Enum   )(Enum.a);\n\n    void testPtr(T)(T v)\n    {\n        T* pv = &v;\n        T** ppv = new T*(pv);\n        assert( *ppv == pv);\n        assert(**ppv ==  v);\n    }\n    foreach (T; TypeTuple!(int, const long, immutable double))\n    {\n        testPtr!T(10);\n    }\n    foreach (T; TypeTuple!(Enum, const Enum, immutable Enum))\n    {\n        testPtr!T(Enum.a);\n    }\n\n    static assert(!__traits(compiles, new const int(1, 2)));\n\n    static assert(!__traits(compiles, new int(1.42)));  // in curre,t this is disallowed\n    static assert(!__traits(compiles, new double(3.14i)));\n\n    // int(1) in directly on statement scope should be parsed as an expression, but\n    // would fail to compile because of \"has no effect\" error.\n    static assert(!__traits(compiles, { int(1); }));\n}\n\n/********************************************/\n\nint main()\n{\n    test9112a();\n    test9112b();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/untag.d",
    "content": "// PERMUTE_ARGS:\n// EXTRA_FILES: extra-files/untag.html\n\nimport std.algorithm, std.ascii, std.conv, std.exception,\n    std.file, std.getopt, std.path, std.range, std.stdio,\n    std.string, std.traits;\n\nauto binaryFun(string pred, T, U)(T a, U b)\n{\n    return(mixin(pred));\n}\n\n/**\nIf $(D startsWith(r1, r2)), consume the corresponding elements off $(D\nr1) and return $(D true). Otherwise, leave $(D r1) unchanged and\nreturn $(D false).\n*/\nbool startsWithConsume(alias pred = \"a == b\", R1, R2)(ref R1 r1, R2 r2)\n{\n    auto r = r1; // .save();\n    while (!r2.empty && !r.empty && binaryFun!pred(r.front, r2.front))\n    {\n        r.popFront();\n        r2.popFront();\n    }\n    return r2.empty ? (){ r1 = r; return true;}() : false;\n}\n\n\nuint bug = 1;\n\nint main(string[] args) {\n    getopt(args, \"bug\", &bug);\n    enforce(bug <= 2);\n    auto txt = readText(\"runnable/extra-files/untag.html\");\n    untag(txt, \"runnable/extra-files/untag.html\");\n    return 0;\n}\n\nvoid untag(string txt, string filename) {\n    string currentParagraph;\n    string origtxt = txt;\n    string origtxtcopy = txt.idup;\n\n    // Find beginning of content\n    txt = std.algorithm.find(txt, \"<!-- start content -->\\n\");\n\n    // Ancillary function that commits the current paragraph for\n    // writing\n    void commit() {\n        writeParagraph(strip(currentParagraph));\n    }\n\n    void writeChar(dchar c) {\n        immutable lastWritten = currentParagraph.length\n            ? currentParagraph.back\n            : dchar.init;\n        if (lastWritten == ' ' && c == ' ') {\n            // Two consecutive spaces fused\n        } else {\n            // Normal case\n            currentParagraph ~= c;\n        }\n    }\n\n    void writeWords(string s) {\n        if (bug == 0) {\n            foreach (dchar c; s) {\n                currentParagraph ~= c;\n            }\n        } else if (bug == 1) {\n            reserve(currentParagraph, currentParagraph.length + s.length);\n            currentParagraph ~= s;\n        } else {\n            currentParagraph = currentParagraph ~ s;\n        }\n    }\n\n    // Parse the content\n    while (!txt.empty) {\n        size_t i = 0;\n        while (i < txt.length && txt[i] != '<' && txt[i] != '&') {\n            ++i;\n        }\n        writeWords(txt[0 .. i]);\n        if (i == txt.length) {\n            commit();\n            return;\n        }\n        txt = txt[i .. $];\n        auto c = txt[0];\n        txt = txt[1 .. $];\n        if (c == '<') { // This is a tag\n            if (startsWithConsume(txt, `/p>`) ||\n                    startsWithConsume(txt, `/li>`)) {\n                // End of paragraph\n                commit();\n            } else {\n                // This is an uninteresting tag\n                enforce(findConsume(txt, '>'),\n                        \"Could not find closing tag: \"~txt);\n            }\n        } else {\n            auto app = appender!string();\n            findConsume(txt, ';', app);\n            switch (app.data) {\n            case \"#160;\": case \"#32;\": case \"reg;\": case \"nbsp;\":\n                writeChar(' ');\n                break;\n            case \"amp;\":\n                writeChar('&');\n                break;\n            case \"gt;\":\n                writeChar('>');\n                break;\n            case \"lt;\":\n                writeChar('<');\n                break;\n            case \"quot;\":\n                writeChar('\"');\n                break;\n            default:\n                throw new Exception(text(\"Unknown code: &\", app.data));\n                break;\n            }\n        }\n    }\n}\n\nvoid writeParagraph(string sentence) {\n    static bool isSeparator(dchar a) {\n        return !(isAlpha(a) /*|| a == '.'*/);\n    }\n\n    foreach (string cand; std.algorithm.splitter(sentence, ' ')) {\n        cand = toLower(cand);\n    }\n}\n\n/**\nIf $(D r2) can not be found in $(D r1), leave $(D r1) unchanged and\nreturn $(D false). Otherwise, consume elements in $(D r1) until $(D\nstartsWithConsume(r1, r2)), and return $(D true). Effectively\npositions $(D r1) right after $(D r2).\n */\nbool findConsume(R1, R2)(ref R1 r1, R2 r2) if (isForwardRange!R2) {\n    auto r = r1; // .save();\n    while (!r.empty) {\n        if (startsWithConsume(r, r2)) {\n            r1 = r;\n            return true;\n        }\n        r.popFront();\n    }\n    return false;\n}\n\n/**\nIf $(D r2) can not be found in $(D r1), leave $(D r1) unchanged and\nreturn $(D false). Otherwise, consume elements in $(D r1) until $(D\nstartsWith(r1, r2)), and return $(D true).\n */\nbool findConsume(R, E)(ref R r, E e) if (is(typeof(r.front == e))) {\n    auto r1 = std.algorithm.find(r, e);\n    if (r1.empty) return false;\n    r = r1;\n    r.popFront();\n    return true;\n}\n\n/**\nIf $(D r2) can not be found in $(D r1), leave $(D r1) unchanged and\nreturn $(D false). Otherwise, consume elements in $(D r1) until $(D\nstartsWith(r1, r2)), and return $(D true).\n */\nbool findConsume(R1, E, R2)(ref R1 r1, E e, R2 r2) if (is(typeof(r1.front == e))) {\n    auto r = r1;\n    while (!r.empty) {\n        r2.put(r.front);\n        if (r.front == e) {\n            r.popFront();\n            r1 = r;\n            return true;\n        }\n        r.popFront();\n    }\n    return false;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/variadic.d",
    "content": "alias TypeTuple(T...) = T;\n\nclass A { }\nclass B : A { }\nclass C : B { }\n\n/***************************************/\n\ntemplate Foo(int a, int b, int c)\n{\n    const int Foo = 1;\n}\n\ntemplate Foo(A...)\n{\n    const int Foo = 2;\n}\n\nvoid test1()\n{\n    int y = Foo!(1,2,3);\n    assert(y == 1);\n\n    y = Foo!(1,2);\n    assert(y == 2);\n\n    y = Foo!(1,2,3,4);\n    assert(y == 2);\n}\n\n/***************************************/\n\ntemplate Foo2(int a, int b, int c)\n{\n    const int Foo2 = 1;\n}\n\ntemplate Foo2(int a, int b, int c, A...)\n{\n    const int Foo2 = 2;\n}\n\nvoid test2()\n{\n    int y = Foo2!(1,2,3);\n    assert(y == 1);\n\n    y = Foo2!(1,2,3,4);\n    assert(y == 2);\n}\n\n/***************************************/\n\nvoid bar3(int x, int y)\n{\n    assert(x == 2);\n    assert(y == 3);\n}\n\ntemplate Foo3(T, A...)\n{\n    int Foo3(T t, A a)\n    {\n        assert(A.length == 2);\n        assert(a.length == 2);\n        bar3(a);\n        assert([a] == [2, 3]);\n        assert([cast(double)a] == [2.0, 3.0]);\n        assert(a[0] == 2);\n        assert(a[1] == 3);\n        assert(a[$ - 2] == 2);\n        assert(a[$ - 1] == 3);\n        static if (1 || a[6])\n            assert(1);\n        assert([a[]] == [2, 3]);\n        assert([a[0 .. $]] == [2, 3]);\n        assert([a[0 .. $ - 1]] == [2]);\n        return 3;\n    }\n}\n\nvoid test3()\n{\n    int y = Foo3(1,2,3);\n    assert(y == 3);\n}\n\n/***************************************/\n\n\nvoid foo4(A...)()\n{\n    int[] ai;\n    int[] aa;\n\n    aa = null;\n    foreach (a; A)\n    {\n        aa ~= a;\n    }\n    assert(aa == [7,4,9]);\n\n    aa = null;\n    foreach (int a; A)\n    {\n        aa ~= a;\n    }\n    assert(aa == [7,4,9]);\n\n    ai = null;\n    aa = null;\n    foreach (int i, a; A)\n    {\n        ai ~= i;\n        aa ~= a;\n    }\n    assert(ai == [0,1,2]);\n    assert(aa == [7,4,9]);\n\n    ai = null;\n    aa = null;\n    foreach_reverse (uint i, a; A)\n    {\n        ai ~= i;\n        aa ~= a;\n    }\n    assert(ai == [2,1,0]);\n    assert(aa == [9,4,7]);\n\n    ai = null;\n    aa = null;\n    foreach_reverse (i, a; A)\n    {\n        ai ~= i;\n        aa ~= a;\n    }\n    assert(ai == [2,1,0]);\n    assert(aa == [9,4,7]);\n\n    ai = null;\n    aa = null;\n    foreach (int i, a; A)\n    {\n        ai ~= i;\n        aa ~= a;\n        if (i == 1)\n            break;\n        continue;\n    }\n    assert(ai == [0,1]);\n    assert(aa == [7,4]);\n}\n\nvoid test4()\n{\n    foo4!(7,4,9)();\n}\n\n/***************************************/\n\nint a12(TypeTuple!(int, int) t)\n{\n    return t[0] + t[1];\n}\n\nint b12(TypeTuple!(TypeTuple!(int), TypeTuple!(int)) t)\n{\n    return t[0] + t[1];\n}\n\nint c12(TypeTuple!(TypeTuple!(int), TypeTuple!(TypeTuple!(), int), TypeTuple!()) t)\n{\n    return t[0] + t[1];\n}\n\nvoid test12()\n{\n    assert(a12(1, 2) == 3);\n    assert(b12(1, 2) == 3);\n    assert(c12(1, 2) == 3);\n}\n\n/***************************************/\n\n\nint plus13(TypeTuple!(int, long, float)[0 .. 2] t)\n{\n    typeof(t)[0] e;\n    assert(typeid(typeof(e)) == typeid(int));\n    typeof(t)[1] f;\n    assert(typeid(typeof(f)) == typeid(long));\n    return t[0] + cast(int)t[1];\n}\n\nvoid test13()\n{\n    assert(plus13(5, 6) == 11);\n}\n\n/***************************************/\n\nint plus14(TypeTuple!(int, long, float)[0 .. $ - 1] t)\n{\n    typeof(t)[$ - 2] e;\n    assert(typeid(typeof(e)) == typeid(int));\n    typeof(t)[1] f;\n    assert(typeid(typeof(f)) == typeid(long));\n    return t[0] + cast(int)t[1];\n}\n\nvoid test14()\n{\n    assert(plus14(5, 6) == 11);\n}\n\n/***************************************/\n\nvoid returnAndArgs(T, U...) (T delegate(U) dg)\n{\n    static if (U.length == 0)\n        assert(dg() == 0);\n    else static if (U.length == 1)\n        assert(dg(false) == 1);\n    else\n        assert(dg(false, 63L) == 2);\n}\n\nvoid test24()\n{\n    returnAndArgs(delegate int(){ return 0; });\n    returnAndArgs(delegate int(bool b){ return 1; });\n    returnAndArgs(delegate int(bool b, long c){ return 2; });\n}\n\n/***************************************/\n\nvoid test28()\n{\n    alias TypeTuple!(int, long, double) TL;\n\n    foreach (int i, T; TL)\n    {\n        switch (i)\n        {\n            case 0: assert(is(T == int));    break;\n            case 1: assert(is(T == long));   break;\n            case 2: assert(is(T == double)); break;\n            default:assert(0);\n        }\n    }\n}\n\n/***************************************/\n\ntemplate g32(alias B)\n{\n    int g32 = 2;\n}\n\nint f32(A...)(A a)\n{\n    return g32!(a);\n}\n\nvoid test32()\n{\n    assert(f32(4) == 2);\n}\n\n/***************************************/\n\nstruct S34\n{\n    int x;\n    long y;\n    double z;\n}\n\nvoid foo34(int x, long y, double z)\n{\n    assert(x == 3);\n    assert(y == 8);\n    assert(z == 6.8);\n}\n\nvoid test34()\n{\n    S34 s;\n\n    s.x = 3;\n    s.y = 8;\n    s.z = 6.8;\n    foo34(s.tupleof);\n}\n\n/***************************************/\n\nalias TypeTuple!(int, long, double) TL35;\n\nstruct S35\n{\n    TL35 tl;\n}\n\nvoid foo35(int x, long y, double z)\n{\n    assert(x == 3);\n    assert(y == 8);\n    assert(z == 6.8);\n}\n\nvoid test35()\n{\n    S35 s;\n\n    s.tl[0] = 3;\n    s.tl[1] = 8;\n    s.tl[2] = 6.8;\n    foo35(s.tupleof);\n    foo35(s.tl);\n}\n\n/***************************************/\n\nalias TypeTuple!(int, long, double) TL36;\n\nclass C36\n{\n    TL36 tl;\n}\n\nvoid foo36(int x, long y, double z)\n{\n    assert(x == 3);\n    assert(y == 8);\n    assert(z == 6.8);\n}\n\nvoid test36()\n{\n    C36 s = new C36;\n\n    s.tl[0] = 3;\n    s.tl[1] = 8;\n    s.tl[2] = 6.8;\n    foo36(s.tupleof);\n    foo36(s.tl);\n}\n\n/***************************************/\n\n\nalias TypeTuple!(int, long, double) TL37;\n\nclass C37\n{\n    TL37 tl;\n}\n\nvoid foo37(int x, long y, double z)\n{\n    assert(x == 3);\n    assert(y == 8);\n    assert(z == 6.8);\n}\n\nvoid test37()\n{\n    C37 s = new C37;\n\n    s.tl[0] = 3;\n    s.tl[1] = 8;\n    s.tl[2] = 6.8;\n    foo37(s.tupleof);\n\n    TL37 x;\n    assert(x[0] == 0);\n    x[0] = 3;\n    assert(x[0] == 3);\n    assert(x[1] == 0);\n    x[1] = 8;\n    x[2] = 6.8;\n    foo37(x);\n}\n\n/***************************************/\n\ninterface I38A { }\ninterface I38B { }\n\nalias TypeTuple!(I38A, I38B) IL38;\n\nclass C38 : IL38\n{\n}\n\nvoid test38()\n{\n    auto c = new C38;\n}\n\n/***************************************/\n\nvoid test39()\n{\n    static const string a = \"\\x01\";\n    static const char b = a[0];\n    static const string c = \"test\";\n    static assert(c[a[0]] == 'e');\n\n    alias TypeTuple!(ulong,uint,ushort,ubyte) tuple;\n    static assert(is(tuple[1] == uint));\n    static assert(is(tuple[a[0]] == uint));\n}\n\n/***************************************/\n\nstruct Foo45\n{\n    static TypeTuple!(int) selements1;\n    TypeTuple!(int) elements1;\n    static TypeTuple!() selements0;\n    TypeTuple!() elements0;\n}\n\nvoid test45()\n{\n    Foo45 foo;\n\n    static assert(Foo45.selements1.length == 1);\n    static assert(Foo45.elements1.length == 1);\n    static assert(Foo45.selements0.length == 0);\n    static assert(Foo45.elements0.length == 0);\n\n    static assert(foo.selements1.length == 1);\n    static assert(foo.elements1.length == 1);\n    static assert(foo.selements0.length == 0);\n    static assert(foo.elements0.length == 0);\n}\n\n/***************************************/\n\ntemplate Tuple46(E ...) { alias E Tuple46; }\n\nalias Tuple46!(float, float, 3) TP46;\nalias TP46[1..$] TQ46;\n\nvoid test46()\n{\n    TQ46[0] f = TQ46[1];\n    assert(is(typeof(f) == float));\n    assert(f == 3);\n}\n\n/***************************************/\n\ntemplate Foo47(T, Args...)\n{\n    void bar(Args args, T t)\n    {\n    }\n}\n\nvoid test47()\n{\n    alias Foo47!(int) aFoo;\n}\n\n/***************************************/\n\ntemplate Tuple48(E...)\n{\n    alias E Tuple48;\n}\n\nvoid VarArg48(T...)(T args)\n{\n}\n\nvoid test48()\n{\n    VarArg48( );\n    VarArg48( Tuple48!(1,2,3) );\n    VarArg48( Tuple48!()      );\n}\n\n/***************************************/\n\nalias TypeTuple!(int, long) TX49;\n\nvoid foo49(TX49 t)\n{\n    TX49 s;\n    s = t;\n    assert(s[0] == 1);\n    assert(s[1] == 2);\n}\n\nvoid test49()\n{\n    foo49(1, 2);\n}\n\n/***************************************/\n\nvoid foo51(U...)(int t, U u)\n{\n    assert(t == 1);\n    assert(u[0] == 2);\n    assert(u[1] == 3);\n}\n\nvoid bar51(U...)(U u, int t)\n{\n    assert(u[0] == 1);\n    assert(u[1] == 2);\n    assert(t == 3);\n}\n\nvoid abc51(U...)(int s, U u, int t)\n{\n    assert(s == 1);\n    assert(u[0] == 2);\n    assert(u[1] == 3);\n    assert(t == 4);\n}\n\nvoid test51()\n{\n  foo51(1, 2, 3);\n  bar51(1, 2, 3);\n  bar51!(int, int)(1, 2, 3);\n  abc51(1,2,3,4);\n}\n\n/***************************************/\n\nstring to55(U, V)(V s) { return \"he\"; }\n\nprivate S wyda(S, T...)(T args)\n{\n    S result;\n    foreach (i, arg; args)\n    {\n        result ~= to55!(S)(args[i]);\n    }\n    return result;\n}\n\nstring giba(U...)(U args)\n{\n    return wyda!(string, U)(args);\n}\n\nvoid test55()\n{\n    assert(giba(42, ' ', 1.5, \": xyz\") == \"hehehehe\");\n}\n\n/***************************************/\n\nprivate template implicitlyConverts(U, V)\n{\n    enum bool implicitlyConverts = V.sizeof >= U.sizeof\n        && is(typeof({U s; V t = s;}()));\n}\n\nT to56(T, S)(S s)\n    if (!implicitlyConverts!(S, T) /*&& isSomeString!(T)\n        && isSomeString!(S)*/)\n{\n    return T.init;\n}\n\nvoid test56()\n{\n    auto x = to56!(int)(\"4\");\n    assert(x == 0);\n    assert(!implicitlyConverts!(const(char)[], string));\n    assert(implicitlyConverts!(string, const(char)[]));\n}\n\n/***************************************/\n\nstruct A57(B...) {}\n\nvoid test57()\n{\n    alias A57!(int, float) X;\n    static if (!is(X Y == A57!(Z), Z...))\n    {\n        static assert(false);\n    }\n}\n\n/***************************************/\n\nstruct A58(B...) {}\n\nvoid test58()\n{\n    alias A58!(int, float) X;\n    static if (!is(X Y == A58!(Z), Z...))\n    {\n        static assert(false);\n    }\n}\n\n/***************************************/\n\nstruct Tuple59(T...)\n{\n    T field;\n}\n\ntemplate reduce(fun...)\n{\n    alias Reduce!(fun).reduce reduce;\n}\n\ntemplate Reduce(fun...)\n{\n    Tuple59!(double, double)\n    reduce(Range)(Range r)\n    {\n        typeof(Tuple59!(double,double).field)[0] y;\n        typeof(typeof(return).field)[0] x;\n        Tuple59!(double, double) s;\n        return s;\n    }\n}\n\nvoid test59()\n{\n    double[] a = [ 3.0, 4, 7, 11, 3, 2, 5 ];\n    static double sum(double a, double b) {return a + b;}\n    auto r = reduce!((a, b) { return a + b; },\n                     (a, b) { return a + b; })(a);\n}\n\n/***************************************/\n\ntemplate tuple60(T...)\n{\n    alias T tuple60;\n}\n\ntemplate Foo60(S : void delegate(tuple60!(int))) {}\ntemplate Foo60(S : void delegate(tuple60!(int, int))) {}\n\nalias Foo60!(void delegate(int)) Bar60;\n\nvoid test60()\n{\n}\n\n/***************************************/\n\ntemplate TypeTuple61(TList...){\n    alias TList TypeTuple61;\n}\ntemplate List61(lst...) { alias lst list; }\nalias TypeTuple61!(List61!(void)) A61;\nalias TypeTuple61!(A61[0].list) B61;\n\nvoid test61()\n{\n}\n\n/***************************************/\n\ntemplate Tuple63(T...){\n    alias T Tuple63;\n}\n// https://issues.dlang.org/show_bug.cgi?id=3336\nstatic assert(!is(int[ Tuple63!(int, int) ]));\n\nvoid test63()\n{\n}\n\n/***************************************/\n\ntemplate Tuple1411(T ...) { alias T Tuple1411; }\n\nvoid test1411()\n{\n    int delegate(ref Tuple1411!(int, char[], real)) dg; // (*)\n    int f(ref int a, ref char[] b, ref real c) { return 77; }\n    dg = &f;\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4444\n\nvoid test4444()\n{\n    alias TypeTuple!(1) index;\n    auto arr = new int[4];\n    auto x = arr[index];    // error\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13864\n\nstruct Tuple13864(T...)\n{\n    T expand;\n    alias expand this;\n}\nauto tuple13864(T...)(T args)\n{\n    return Tuple13864!T(args);\n}\n\nvoid test13864()\n{\n    int[] x = [2,3,4];\n    auto y = x[tuple13864(0).expand];\n    assert(y == 2);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4884\n\nstruct A4884(T...)\n{\n    void foo(T) {}\n    void bar(bool, T) {}\n}\n\nvoid test4884()\n{\n    auto a1 = A4884!(int)();\n    auto a2 = A4884!(int, long)();\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4920\n\nstruct Test4920(parameters_...)\n{\n    alias parameters_ parameters;\n}\n\nvoid test4920()\n{\n    Test4920!(10, 20, 30) test;\n    static assert(typeof(test).parameters[1] == 20); // okay\n    static assert(       test .parameters[1] == 20); // (7)\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4940\n\ntemplate Tuple4940(T...)\n{\n    alias T Tuple4940;\n}\n\nstruct S4940\n{\n    Tuple4940!(int, int) x;\n    this(int) { }\n}\n\nvoid test4940()\n{\n    auto w = S4940(0).x;\n}\n\n//----\n\nstruct S4940add\n{\n    string s;\n    long x;\n}\n\nref S4940add get4940add(ref S4940add s){ return s; }\n\nvoid test4940add()\n{\n    S4940add s;\n    get4940add(s).tupleof[1] = 20;\n    assert(s.x == 20);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6530\n\nstruct S6530\n{\n    int a, b, c;\n}\n\nstruct HasPostblit6530\n{\n    this(this) {}  // Bug goes away without this.\n}\n\nauto toRandomAccessTuple6530(T...)(T input, HasPostblit6530 hasPostblit)\n{\n    return S6530(1, 2, 3);\n}\n\nvoid doStuff6530(T...)(T args)\n{\n    HasPostblit6530 hasPostblit;\n\n    // Bug goes away without the .tupleof.\n    auto foo = toRandomAccessTuple6530(args, hasPostblit).tupleof;\n}\n\nvoid test6530()\n{\n    doStuff6530(1, 2, 3);\n}\n\n/***************************************/\n\nimport core.stdc.stdarg;\n\nextern(C)\nvoid func9495(int a, string format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    auto a1 = va_arg!int(ap);\n    auto a2 = va_arg!int(ap);\n    auto a3 = va_arg!int(ap);\n    assert(a1 == 0x11111111);\n    assert(a2 == 0x22222222);\n    assert(a3 == 0x33333333);\n    va_end(ap);\n}\n\nvoid test9495()\n{\n    func9495(0, \"\", 0x11111111, 0x22222222, 0x33333333);\n}\n\n/***************************************/\n\nvoid copya(int a, string format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n\n    va_list ap2;\n    va_copy(ap2, ap);\n\n    auto a1 = va_arg!int(ap);\n    auto a2 = va_arg!int(ap);\n    auto a3 = va_arg!int(ap);\n\n    assert(a1 == 0x11111111);\n    assert(a2 == 0x22222222);\n    assert(a3 == 0x33333333);\n\n    auto b1 = va_arg!int(ap2);\n    auto b2 = va_arg!int(ap2);\n    auto b3 = va_arg!int(ap2);\n\n    assert(b1 == 0x11111111);\n    assert(b2 == 0x22222222);\n    assert(b3 == 0x33333333);\n\n    va_end(ap);\n    va_end(ap2);\n}\n\nvoid testCopy()\n{\n    copya(0, \"\", 0x11111111, 0x22222222, 0x33333333);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6700\n\ntemplate bug6700(TList ...) {\n    const int bug6700 = 2;\n}\nTypeTuple!(int, long) TT6700;\n\nstatic assert(bug6700!( (TT6700[1..$]) )==2);\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6966\n\ntemplate X6966(T...)\n{\n    alias const(T[0]) X6966;\n}\nstatic assert(is(X6966!(int) == const(int)));\nstatic assert(is(X6966!(int, 0) == const(int)));\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7233\n\nstruct Foo7233 { int x, y; }\nFoo7233[] front7233(Foo7233[][] a)\n{\n    return a[0];\n}\n\nclass Bar7233 { int x, y; }\nBar7233[] front7233(Bar7233[][] a)\n{\n    return a[0];\n}\n\nvoid test7233()\n{\n    Foo7233[][] b1 = [[Foo7233()]];\n    auto xy1 = b1.front7233[0].tupleof;\n\n    Bar7233[][] b2 = [[new Bar7233()]];\n    auto xy2 = b2.front7233[0].tupleof;\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7263\n\ntemplate TypeTuple7263(T...){ alias T TypeTuple7263; }\n\nstruct tuple7263\n{\n    TypeTuple7263!(int, int) field;\n    alias field this;\n}\n\nauto front7263(T)(ref T arr){ return arr[0]; }\n\nvoid test7263()\n{\n    auto bars = [tuple7263(0, 0), tuple7263(1, 1)];\n    auto spam1 = bars.front7263[1];\n    auto spam2 = bars.front7263[1..2];\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8244\n\nTypeTuple!(int,int)[] x8244;\nstatic assert(is(typeof(x8244) == TypeTuple!(int, int)));\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9017\n\ntemplate X9017(Args...)\n{\n    static if(__traits(compiles, { enum e = Args; }))\n        enum e = Args;\n}\nalias X9017!0 x9017;\nstatic assert(x9017.e[0] == 0);\n\nvoid test9017()\n{\n    enum tup1 = TypeTuple!(11, 22);\n    enum tup2 = TypeTuple!(\"one\", \"two\");\n    static assert(tup1 == TypeTuple!(11, 22));\n    static assert(tup2 == TypeTuple!(\"one\", \"two\"));\n    static assert(tup1[0] == 11 && tup1[1] == 22);\n    static assert(tup2[0] == \"one\" && tup2[1] == \"two\");\n\n    shared const tup3 = TypeTuple!(10, 3.14);\n    immutable    tup4 = TypeTuple!(\"a\", [1,2]);\n    static assert(is(typeof(tup3[0]) == shared const int));\n    static assert(is(typeof(tup3[1]) == shared const double));\n    static assert(is(typeof(tup4[0]) == immutable string));\n    static assert(is(typeof(tup4[1]) == immutable int[]));\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10279\n\nvoid foo10279(int[][] strs...) @trusted { }\nvoid bar10279() @safe { foo10279(); }\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13508\n\nstruct S13508\n{\n    this(T)(T[] t...) {}\n}\n\ntemplate make13508(T)\n{\n    T make13508(Args...)(Args args)\n    {\n        return T(args);\n    }\n}\n\nvoid test13508() @safe @nogc\n{\n    S13508 s = make13508!S13508(5);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14395\n\nint v2u14395(uint[1] ar...)\n{\n    return ar[0];\n}\n\nvoid print14395(int size = v2u14395(7))\n{\n    assert(size == 7);\n}\n\nvoid test14395()\n{\n    print14395();\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10414\n\nvoid foo10414(void delegate()[] ...) { }\n\nvoid bar10414() { }\n\nvoid test10414()\n{\n    foo10414\n    (\n        { bar10414(); },\n        { bar10414(); },\n    );\n}\n\n/***************************************/\n\nimport core.stdc.stdarg;\n\nstruct S14179\n{\n    const(char)* filename;\n    uint linnum;\n    uint charnum;\n}\n\nextern(C++) const(char)* func14179(S14179 x, const(char)* string, ...)\n{\n    return string;\n}\n\nvoid test14179()\n{\n    const(char)* s = \"hello\";\n    assert(func14179(S14179(), s) == s);\n}\n\n/***************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10722\n\nstruct S10722\n{\n    int x;\n}\n\ntemplate GetSomething10722(S...)\n{\n    alias GetSomething = int;\n}\n\nvoid test10722()\n{\n    alias X10722 = GetSomething10722!(S10722.tupleof[0]);\n}\n\n/***************************************/\n\nvoid testx15417(ulong c1, ...)\n{\n    check(c1, _argptr, _arguments);\n}\n\nclass C15417\n{\n    private void method ()\n    {\n        void test1 (ulong c1, ...)\n        {\n            check(c1, _argptr, _arguments);\n        }\n\n        void test2 (ulong c1, ...)\n        {\n            va_list ap;\n            va_start(ap, c1);\n\n            check(c1, ap, _arguments);\n        }\n\n        testx15417(4242UL, char.init);\n        test1(4242UL, char.init);\n        test2(4242UL, char.init);\n    }\n}\n\nvoid check (ulong c1, va_list arglist, TypeInfo[] ti)\n{\n    assert(ti.length == 1);\n    assert(ti[0].toString() == \"char\");\n    assert(char.init == va_arg!(char)(arglist));\n}\n\nvoid test15417()\n{\n    auto c = new C15417;\n    c.method;\n}\n\n\n/***************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test12();\n    test13();\n    test14();\n    test24();\n    test28();\n    test32();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test51();\n    test55();\n    test56();\n    test57();\n    test58();\n    test59();\n    test60();\n    test61();\n    test63();\n    test1411();\n    test4444();\n    test13864();\n    test4884();\n    test4920();\n    test4940();\n    test4940add();\n    test6530();\n    test7233();\n    test7263();\n    test9017();\n    test14395();\n    test10414();\n    test9495();\n    testCopy();\n    test14179();\n    test15417();\n\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/version.d",
    "content": "// PERMUTE_ARGS:\n// REQUIRED_ARGS: -version=3 -version=foo\n\nextern(C) int printf(const char*, ...);\n\n/*******************************************/\n\nvoid test1()\n{\n    int i = 3;\n\n    version(2)\n    {\n        i = 2;\n    }\n    else\n    {\n        i = 0;\n    }\n    printf(\"i = %d\\n\", i);\n    assert(i == 2);\n\n    i = 3;\n\n    version(foo)\n    {\n        i = 2;\n    }\n    else\n    {\n        i = 0;\n    }\n    printf(\"i = %d\\n\", i);\n    assert(i == 2);\n}\n\n/*******************************************/\n\nversion(foo)\n{\n    version = bar;\n}\nelse\n{\n    version = 4;\n}\n\nvoid test2()\n{\n    version(bar)\n    {\n    }\n    else\n        assert(0);\n\n    version(4) assert(0);\n}\n\n/*******************************************/\n\nint main()\n{\n    test1();\n    test2();\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/warning1.d",
    "content": "// REQUIRED_ARGS: -w\n// PERMUTE_ARGS:\n\nextern(C) int printf(const char*, ...);\n\n/******************************************/\n\nclass F { }\nint foo()\n{\n    scope F f = new F(); // comment out and warning goes away\n    return 0;\n}\n\n/******************************************/\n\nint foo2()\n{\n    try\n    {\n        return 0;\n    }\n    finally { }\n}\n\n/******************************************/\n\nprivate int getNthInt(A...)(uint index, A args)\n{\n    foreach (i, arg; args)\n    {\n        static if (is(typeof(arg) : long) || is(typeof(arg) : ulong))\n        {\n            if (i != index) continue;\n            return cast(int)(arg);\n        }\n        else\n        {\n            if (i == index) break;\n        }\n    }\n    throw new Error(\"int expected\");\n}\n\n/******************************************/\n\nclass Foo2 {\n    int foo() {\n        synchronized(this){\n            return 8;\n        }\n    }\n}\n\n/******************************************/\n\nvoid mainX()\n{\n    int i=0;\n    printf(\"This number is zero: \");\n    goto inloop;\n    for(; i<10; i++) {              // this is line 7\n        printf(\"This number is nonzero: \");\ninloop:\n        printf(\"%d\\n\", i);\n    }\n}\n\n/******************************************/\n\nstring foo3(int bar)\n{\n    switch (bar)\n    {\n        case 1:\n            return \"1\";\n        case 2:\n            return \"2\";\n        default:\n            return \"3\";\n    }\n}\n\n\n/******************************************/\n\nint foo4()\n{\n    int i;\n    for (;; ++i)\n    {\n        if (i == 10) return 0;\n    }\n}\n\n/******************************************/\n\nint foo5()\n{\n    do {\n        if (false)\n            return 1;\n    } while (true);\n}\n\n/******************************************/\n\nnothrow int foo6()\n{\n    int x = 2;\n    try\n    {\n    }\n    catch(Exception e)\n    {\n        x = 4;\n        throw new Exception(\"xxx\");\n    }\n    return x;\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6518\n\ntemplate TypeTuple(T...) { alias T TypeTuple; }\nvoid test6518()\n{\n    switch(2)\n    {\n        foreach(v; TypeTuple!(1, 2, 3))\n            case v: break;\n        default: assert(0);\n    }\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7232\n\nbool test7232()\n{\n    scope(failure) return false;\n    return true;\n}\n\n/***************************************************/\n\nstruct S9332\n{\n    this(S9332)\n    {\n//      while (1) { }\n        assert(0, \"unreachable?\");\n    }\n}\n\n/******************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13201\n\nclass C13201\n{\n    void foo()\n    {\n        synchronized(this)\n        {\n            assert(0);\n        }\n    }\n}\n\nvoid test13201a()\n{\n    auto c = new C13201();\n    synchronized(c)\n    {\n        assert(0);\n    }\n}\n\nvoid test13201b()\n{\n    struct S { ~this() {} }\n\n    S s;\n    assert(0);\n}\n\n/******************************************/\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/wc.d",
    "content": "// PERMUTE_ARGS:\n// EXECUTE_ARGS: runnable/wc.d\n\nimport std.file;\n\nextern(C) int printf(const char*, ...);\n\nint main (string[] args)\n{\n    int w_total;\n    int l_total;\n    int c_total;\n\n    printf (\"   lines   words   bytes file\\n\");\n    foreach (arg; args[1 .. args.length])\n    {\n        string input;\n        int w_cnt, l_cnt, c_cnt;\n        int inword;\n\n        input = cast(string)std.file.read(arg);\n\n        foreach (char c; input)\n        {\n            if (c == '\\n')\n                ++l_cnt;\n            if (c != ' ')\n            {\n                if (!inword)\n                {\n                    inword = 1;\n                    ++w_cnt;\n                }\n            }\n            else\n                inword = 0;\n            ++c_cnt;\n        }\n        printf (\"%8lu%8lu%8lu %.*s\\n\", l_cnt, w_cnt, c_cnt, arg.length, arg.ptr);\n        l_total += l_cnt;\n        w_total += w_cnt;\n        c_total += c_cnt;\n    }\n    if (args.length > 2)\n    {\n        printf (\"--------------------------------------\\n%8lu%8lu%8lu total\",\n            l_total, w_total, c_total);\n    }\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/wc2.d",
    "content": "// PERMUTE_ARGS:\n// EXECUTE_ARGS: runnable/wc2.d\n\nimport std.file;\n\nextern(C) int printf(const char*, ...);\n\nint main (string[] args)\n{\n    int w_total;\n    int l_total;\n    int c_total;\n    int[string] dictionary;\n\n    printf(\"   lines   words   bytes file\\n\");\n    foreach (string arg; args[1 .. args.length])\n    {\n        string input;\n        int w_cnt, l_cnt, c_cnt;\n        int inword;\n        int wstart;\n\n        input = cast(string)std.file.read(arg);\n\n        for (int j = 0; j < input.length; j++)\n        {   char c;\n\n            c = input[j];\n            if (c == '\\n')\n                ++l_cnt;\n            if (c >= '0' && c <= '9')\n            {\n            }\n            else if (c >= 'a' && c <= 'z' ||\n                c >= 'A' && c <= 'Z')\n            {\n                if (!inword)\n                {\n                    wstart = j;\n                    inword = 1;\n                    ++w_cnt;\n                }\n            }\n            else if (inword)\n            {   string word = input[wstart .. j];\n\n                dictionary[word]++;\n                inword = 0;\n            }\n            ++c_cnt;\n        }\n        if (inword)\n        {   string w = input[wstart .. input.length];\n            dictionary[w]++;\n        }\n        printf(\"%8lu%8lu%8lu %.*s\\n\", l_cnt, w_cnt, c_cnt, arg.length, arg.ptr);\n        l_total += l_cnt;\n        w_total += w_cnt;\n        c_total += c_cnt;\n    }\n\n    if (args.length > 2)\n    {\n        printf(\"--------------------------------------\\n%8lu%8lu%8lu total\",\n            l_total, w_total, c_total);\n    }\n\n    printf(\"--------------------------------------\\n\");\n    foreach (string word1; dictionary.keys)\n    {\n        printf(\"%3d %.*s\\n\", dictionary[word1], word1.length, word1.ptr);\n    }\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/wc3.d",
    "content": "// PERMUTE_ARGS:\n// EXECUTE_ARGS: runnable/extra-files/alice30.txt\n// EXTRA_FILES: extra-files/alice30.txt\n\nimport std.stdio;\nimport std.file;\n\nint main (string[] args)\n{\n    int w_total;\n    int l_total;\n    int c_total;\n    int[string] dictionary;\n\n    writefln(\"   lines   words   bytes file\");\n    foreach (arg; args[1 .. args.length])\n    {\n        int w_cnt, l_cnt, c_cnt;\n        size_t wstart;\n        bool inword;\n\n        auto input = cast(string)std.file.read(arg);\n\n        foreach (j, c; input)\n        {\n            if (c == '\\n')\n                ++l_cnt;\n            if (c >= '0' && c <= '9')\n            {\n            }\n            else if (c >= 'a' && c <= 'z' ||\n                     c >= 'A' && c <= 'Z')\n            {\n                if (!inword)\n                {\n                    wstart = j;\n                    inword = true;\n                    ++w_cnt;\n                }\n            }\n            else if (inword)\n            {   auto word = input[wstart .. j];\n\n                dictionary[word]++;\n                inword = false;\n            }\n            ++c_cnt;\n        }\n        if (inword)\n        {   auto w = input[wstart .. input.length];\n            dictionary[w]++;\n        }\n        writefln(\"%8s%8s%8s %s\", l_cnt, w_cnt, c_cnt, arg);\n        l_total += l_cnt;\n        w_total += w_cnt;\n        c_total += c_cnt;\n    }\n\n    if (args.length > 2)\n    {\n        writefln(\"--------------------------------------\\n%8s%8s%8s total\",\n            l_total, w_total, c_total);\n    }\n\n    writefln(\"--------------------------------------\");\n\n    foreach (word1; dictionary.keys)\n    {\n        writefln(\"%3s %s\", dictionary[word1], word1);\n    }\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/xdtor.d",
    "content": "// PERMUTE_ARGS:\n\nstruct Field\n{\n    ~this() @safe @nogc pure nothrow {}\n}\n\nstruct Counter\n{\n    static size_t cnt;\n    ~this() @safe @nogc nothrow { ++cnt; }\n}\n\nstruct Foo\n{\n    ~this() @safe @nogc pure nothrow {}\n    Field field;\n}\n\nclass Bar\n{\n    ~this() @safe @nogc pure nothrow {}\n    Field field;\n}\n\nvoid test1() @nogc pure nothrow\n{\n    Foo foo;\n    foo.__xdtor();\n    scope bar = new Bar();\n    bar.__xdtor();\n}\n\nstatic assert(__traits(hasMember, Foo, \"__xdtor\"));\nstatic assert(__traits(hasMember, Bar, \"__xdtor\"));\n\n//\n\nstruct FieldDtor\n{\n    Counter counter;\n}\n\nstruct AggrDtor\n{\n    static size_t cnt;\n    ~this() @safe @nogc nothrow { ++cnt; }\n}\n\nstruct MixedDtor\n{\n    static size_t cnt;\n    Counter counter;\n    ~this() @safe @nogc nothrow { ++cnt; }\n}\n\nstruct SNoDtor {}\nclass CNoDtor {}\n\nstatic assert(!__traits(hasMember, SNoDtor, \"__xdtor\"));\nstatic assert(!__traits(hasMember, CNoDtor, \"__xdtor\"));\n\nvoid test2() @safe @nogc nothrow\n{\n    FieldDtor a;\n    assert(Counter.cnt == 0);\n    a.__xdtor();\n    assert(Counter.cnt == 1);\n    AggrDtor b;\n    assert(AggrDtor.cnt == 0);\n    b.__xdtor();\n    assert(AggrDtor.cnt == 1);\n    Counter.cnt = 0;\n    MixedDtor c;\n    assert(MixedDtor.cnt == 0);\n    assert(Counter.cnt == 0);\n    c.__xdtor();\n    assert(MixedDtor.cnt == 1);\n    assert(Counter.cnt == 1);\n}\n\nvoid main()\n{\n    test1();\n    test2();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/xpostblit.d",
    "content": "// PERMUTE_ARGS:\n\nstruct Field\n{\n    this(this) @safe @nogc pure nothrow {}\n}\n\nstruct Counter\n{\n    static size_t cnt;\n    this(this) @safe @nogc nothrow { ++cnt; }\n}\n\nstruct Foo\n{\n    this(this) @safe @nogc pure nothrow {}\n    Field field;\n}\n\nvoid test1() @safe @nogc pure nothrow\n{\n    Foo foo;\n    foo.__xpostblit();\n}\n\nstatic assert(__traits(hasMember, Foo, \"__xpostblit\"));\n\n//\n\nstruct FieldPostblit\n{\n    Counter counter;\n}\n\nstruct AggrPostblit\n{\n    static size_t cnt;\n    this(this) @safe @nogc nothrow { ++cnt; }\n}\n\nstruct MixedPostblit\n{\n    static size_t cnt;\n    Counter counter;\n    this(this) @safe @nogc nothrow { ++cnt; }\n}\n\nstruct SNoPostblit {}\nclass CNoPostblit {}\n\nstatic assert(!__traits(hasMember, SNoPostblit, \"__xpostblit\"));\nstatic assert(!__traits(hasMember, CNoPostblit, \"__xpostblit\"));\n\nvoid test2() @safe @nogc nothrow\n{\n    FieldPostblit a;\n    assert(Counter.cnt == 0);\n    a.__xpostblit();\n    assert(Counter.cnt == 1);\n    AggrPostblit b;\n    assert(AggrPostblit.cnt == 0);\n    b.__xpostblit();\n    assert(AggrPostblit.cnt == 1);\n    Counter.cnt = 0;\n    MixedPostblit c;\n    assert(MixedPostblit.cnt == 0);\n    assert(Counter.cnt == 0);\n    c.__xpostblit();\n    assert(MixedPostblit.cnt == 1);\n    assert(Counter.cnt == 1);\n}\n\n/****************************************************************\n This test is intended to verify the exception safety of field\n postblits\n*/\nstring trace = \"\";\n\nstruct FieldThrow\n{\n    string name;\n    this(string n)\n    {\n        name = n;\n    }\n\n    bool throwExcept;\n    this(this)\n    { \n        if (throwExcept)\n        {\n            throw new Exception(\"\");\n        }\n    }\n\n    ~this() { trace ~= name ~ \".dtor\"; }\n}\n\nstruct S\n{\n    auto f1 = FieldThrow(\"f1\");\n    FieldThrow[2] f2f3= [FieldThrow(\"f2\"), FieldThrow(\"f3\")];\n    auto f4 = FieldThrow(\"f4\");\n}\n\nvoid test3()\n{\n    trace = \"\";\n\n    S s1;\n\n    // Cause `s1.f4`'s postblit to throw\n    s1.f4.throwExcept = true;\n\n    try\n    {\n        // `s`'s postblit will be a combination of `f1`, `f2f3`, and `f4`'s\n        // postblit in that order.  However, `f4`'s postblit will throw,\n        // causing `s1.f2f3` and `s1.f1`'s destructors to execute in that\n        // order\n        S s2 = s1;\n    }\n    catch(Exception ex){ }\n\n    // Confirm the field destructors were called and were called in the\n    // corrrect order\n    assert(trace == \"f3.dtor\" ~ \"f2.dtor\" ~ \"f1.dtor\");\n}\n/****************************************************************************/\n\nvoid main()\n{\n    test1();\n    test2();\n    test3();\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/xtest46.d",
    "content": "// PERMUTE_ARGS: -unittest -O -release -inline -fPIC -g\n\n//import std.stdio;\nimport core.stdc.stdio;\n\n/******************************************/\n\nstruct S\n{\n    int opStar() { return 7; }\n}\n\nvoid test1()\n{\n    S s;\n\n    printf(\"%d\\n\", *s);\n    assert(*s == 7);\n}\n\n/******************************************/\n\nvoid test2()\n{\n  double[1][2] bar;\n  bar[0][0] = 1.0;\n  bar[1][0] = 2.0;\n  foo2(bar);\n}\n\nvoid foo2(T...)(T args)\n{\n    foreach (arg; args[0 .. $])\n    {\n        //writeln(arg);\n        bar2!(typeof(arg))(&arg);\n    }\n}\n\n\nvoid bar2(D)(const(void)* arg)\n{\n    D obj = *cast(D*) arg;\n}\n\n/***************************************************/\n\nvoid test3()\n{\n    version (unittest)\n    {\n        printf(\"unittest!\\n\");\n    }\n    else\n    {\n        printf(\"no unittest!\\n\");\n    }\n\n    version (assert)\n    {\n        printf(\"assert!\\n\");\n    }\n    else\n    {\n        printf(\"no assert!\\n\");\n    }\n}\n\n\n/***************************************************/\n\nvoid test4()\n{\n  immutable int maxi = 8;\n  int[][maxi] neighbors = [ cast(int[])[ ], [ 0 ], [ 0, 1], [ 0, 2], [1, 2], [1, 2, 3, 4],\n[ 2, 3, 5], [ 4, 5, 6 ] ];\n  int[maxi] grid;\n\n  // neighbors[0].length = 0;\n\n  void place(int k, uint mask)\n  { if(k<maxi) {\n      for(uint m = 1, d = 1; d <= maxi; d++, m<<=1)\n        if(!(mask & m)) {\n          bool ok = true;\n          int dif;\n          foreach(nb; neighbors[k])\n            if((dif=grid[nb]-d)==1 || dif==-1) {\n              ok = false; break;\n            }\n          if(ok) {\n            grid[k] = d;\n            place(k+1, mask | m);\n          }\n        }\n    } else {\n      printf(\"  %d\\n%d %d %d\\n%d %d %d\\n  %d\\n\\n\",\n             grid[0], grid[1], grid[2], grid[3], grid[4], grid[5], grid[6], grid[7]);\n    }\n  }\n  place(0, 0);\n}\n\n\n/***************************************************/\n\nstruct S5\n{\n  enum S5 some_constant = {2};\n\n  int member;\n}\n\nvoid test5()\n{\n}\n\n/***************************************************/\n\nstruct S6\n{\n    int a, b, c;\n}\n\nstruct T6\n{\n    S6 s;\n    int b = 7;\n\n    S6* opDot()\n    {\n        return &s;\n    }\n}\n\nvoid test6()\n{\n    T6 t;\n    t.a = 4;\n    t.b = 5;\n    t.c = 6;\n    assert(t.a == 4);\n    assert(t.b == 5);\n    assert(t.c == 6);\n    assert(t.s.b == 0);\n    assert(t.sizeof == 4*4);\n    assert(t.init.sizeof == 4*4);\n}\n\n/***************************************************/\n\nstruct S7\n{\n    int a, b, c;\n}\n\nclass C7\n{\n    S7 s;\n    int b = 7;\n\n    S7* opDot()\n    {\n        return &s;\n    }\n}\n\nvoid test7()\n{\n    C7 t = new C7();\n    t.a = 4;\n    t.b = 5;\n    t.c = 6;\n    assert(t.a == 4);\n    assert(t.b == 5);\n    assert(t.c == 6);\n    assert(t.s.b == 0);\n    assert(t.sizeof == (void*).sizeof);\n    assert(t.init is null);\n}\n\n/***************************************************/\n\nvoid foo8(int n1 = __LINE__ + 0, int n2 = __LINE__, string s = __FILE__)\n{\n    assert(n1 < n2);\n    printf(\"n1 = %d, n2 = %d, s = %.*s\\n\", n1, n2, s.length, s.ptr);\n}\n\nvoid test8()\n{\n    foo8();\n}\n\n/***************************************************/\n\nvoid foo9(int n1 = __LINE__ + 0, int n2 = __LINE__, string s = __FILE__)()\n{\n    assert(n1 < n2);\n    printf(\"n1 = %d, n2 = %d, s = %.*s\\n\", n1, n2, s.length, s.ptr);\n}\n\nvoid test9()\n{\n    foo9();\n}\n\n/***************************************************/\n\nint foo10(char c) pure nothrow\n{\n    return 1;\n}\n\nvoid test10()\n{\n    int function(char c) fp;\n    int function(char c) pure nothrow fq;\n\n    fp = &foo10;\n    fq = &foo10;\n}\n\n/***************************************************/\n\nclass Base11 {}\nclass Derived11 : Base11 {}\nclass MoreDerived11 : Derived11 {}\n\nint fun11(Base11) { return 1; }\nint fun11(Derived11) { return 2; }\n\nvoid test11()\n{\n    MoreDerived11 m;\n\n    auto i = fun11(m);\n    assert(i == 2);\n}\n\n/***************************************************/\n\ninterface ABC {};\ninterface AB: ABC {};\ninterface BC: ABC {};\ninterface AC: ABC {};\ninterface A: AB, AC {};\ninterface B: AB, BC {};\ninterface C: AC, BC {};\n\nint f12(AB ab) { return 1; }\nint f12(ABC abc) { return 2; }\n\nvoid test12()\n{\n    A a;\n    auto i = f12(a);\n    assert(i == 1);\n}\n\n/***************************************************/\n\ntemplate Foo13(alias x)\n{\n    enum bar = x + 1;\n}\n\nstatic assert(Foo13!(2+1).bar == 4);\n\ntemplate Bar13(alias x)\n{\n    enum bar = x;\n}\n\nstatic assert(Bar13!(\"abc\").bar == \"abc\");\n\nvoid test13()\n{\n}\n\n/***************************************************/\n\ntemplate Foo14(alias a)\n{\n    alias Bar14!(a) Foo14;\n}\n\nint Bar14(alias a)()\n{\n    return a.sizeof;\n}\n\nvoid test14()\n{\n    auto i = Foo14!(\"hello\")();\n    printf(\"i = %d\\n\", i);\n    assert(i == \"hello\".sizeof);\n    i = Foo14!(1)();\n    printf(\"i = %d\\n\", i);\n    assert(i == 4);\n}\n\n/***************************************************/\n\nauto foo15()(int x)\n{\n    return 3 + x;\n}\n\nvoid test15()\n{\n\n    auto bar()(int x)\n    {\n        return 5 + x;\n    }\n\n    printf(\"%d\\n\", foo15(4));\n    printf(\"%d\\n\", bar(4));\n}\n\n/***************************************************/\n\nint foo16(int x) { return 1; }\nint foo16(ref int x) { return 2; }\n\nvoid test16()\n{\n    int y;\n    auto i = foo16(y);\n    printf(\"i == %d\\n\", i);\n    assert(i == 2);\n    i = foo16(3);\n    assert(i == 1);\n}\n\n/***************************************************/\n\nclass A17 { }\nclass B17 : A17 { }\nclass C17 : B17 { }\n\nint foo17(A17, ref int x) { return 1; }\nint foo17(B17, ref int x) { return 2; }\n\nvoid test17()\n{\n    C17 c;\n    int y;\n    auto i = foo17(c, y);\n    printf(\"i == %d\\n\", i);\n    assert(i == 2);\n}\n\n/***************************************************/\n\nclass C18\n{\n    void foo(int x) { foo(\"abc\"); }\n    void foo(string s) { }  // this is hidden, but that's ok 'cuz no overlap\n    void bar()\n    {\n        foo(\"abc\");\n    }\n}\n\nclass D18 : C18\n{\n    override void foo(int x) { }\n}\n\nvoid test18()\n{\n    D18 d = new D18();\n    d.bar();\n}\n\n/***************************************************/\n\nint foo19(alias int a)() { return a; }\n\nvoid test19()\n{\n    int y = 7;\n    auto i = foo19!(y)();\n    printf(\"i == %d\\n\", i);\n    assert(i == 7);\n\n    i = foo19!(4)();\n    printf(\"i == %d\\n\", i);\n    assert(i == 4);\n}\n\n/***************************************************/\n\ntemplate Foo20(int x) if (x & 1)\n{\n    const int Foo20 = 6;\n}\n\ntemplate Foo20(int x) if ((x & 1) == 0)\n{\n    const int Foo20 = 7;\n}\n\nvoid test20()\n{\n    int i = Foo20!(3);\n    printf(\"%d\\n\", i);\n    assert(i == 6);\n    i = Foo20!(4);\n    printf(\"%d\\n\", i);\n    assert(i == 7);\n}\n\n/***************************************************/\n\ntemplate isArray21(T : U[], U)\n{\n  static const isArray21 = 1;\n}\n\ntemplate isArray21(T)\n{\n  static const isArray21 = 0;\n}\n\nint foo21(T)(T x) if (isArray21!(T))\n{\n    return 1;\n}\n\nint foo21(T)(T x) if (!isArray21!(T))\n{\n    return 2;\n}\n\nvoid test21()\n{\n    auto i = foo21(5);\n    assert(i == 2);\n    int[] a;\n    i = foo21(a);\n    assert(i == 1);\n}\n\n/***************************************************/\n\nvoid test22()\n{\n    immutable uint x, y;\n    foreach (i; x .. y) {}\n}\n\n/***************************************************/\n\nconst bool foo23 = is(typeof(function void() { }));\nconst bar23      = is(typeof(function void() { }));\n\nvoid test23()\n{\n    assert(foo23 == true);\n    assert(bar23 == true);\n}\n\n/***************************************************/\n\nref int foo24(int i)\n{\n    static int x;\n    x = i;\n    return x;\n}\n\nvoid test24()\n{\n    int x = foo24(3);\n    assert(x == 3);\n}\n\n/***************************************************/\n\nref int foo25(int i)\n{\n    static int x;\n    x = i;\n    return x;\n}\n\nint bar25(ref int x)\n{\n    return x + 1;\n}\n\nvoid test25()\n{\n    int x = bar25(foo25(3));\n    assert(x == 4);\n}\n\n/***************************************************/\n\nstatic int x26;\n\nref int foo26(int i)\n{\n    x26 = i;\n    return x26;\n}\n\nvoid test26()\n{\n    int* p = &foo26(3);\n    assert(*p == 3);\n}\n\n/***************************************************/\n\nstatic int x27 = 3;\n\nref int foo27(int i)\n{\n    return x27;\n}\n\nvoid test27()\n{\n    foo27(3) = 4;\n    assert(x27 == 4);\n}\n\n/***************************************************/\n\nref int foo28(ref int x) { return x; }\n\nvoid test28()\n{\n    int a;\n    foo28(a);\n}\n\n/***************************************************/\n\nvoid wyda(int[] a) { printf(\"aaa\\n\"); }\nvoid wyda(int[int] a) { printf(\"bbb\\n\"); }\n\nstruct S29\n{\n    int[] a;\n\n    void wyda()\n    {\n        a.wyda;\n        a.wyda();\n    }\n}\n\nvoid test29()\n{\n    int[] a;\n    a.wyda;\n    int[5] b;\n    b.wyda;\n    int[int] c;\n    c.wyda;\n\n    S29 s;\n    s.wyda();\n}\n\n/***************************************************/\n\nvoid foo30(D)(D arg) if (isIntegral!D)\n{\n}\n\nstruct S30(T) { }\nstruct U30(int T) { }\n\nalias int myint30;\n\nvoid test30()\n{\n\n    S30!myint30 u;\n    S30!int s;\n    S30!(int) t = s;\n\n//    U30!3 v = s;\n}\n\n/***************************************************/\n\nclass A31\n{\n    void foo(int* p) { }\n}\n\nclass B31 : A31\n{\n    override void foo(scope int* p) { }\n}\n\nvoid test31()\n{\n}\n\n/***************************************************/\n\nvoid bar32() { }\n\nnothrow void foo32(int* p)\n{\n    //try { bar32(); } catch (Object o) { }\n    try { bar32(); } catch (Throwable o) { }\n    try { bar32(); } catch (Exception o) { }\n}\n\nvoid test32()\n{   int i;\n\n    foo32(&i);\n}\n\n/***************************************************/\n\nstruct Integer\n{\n    this(int i)\n    {\n        this.i = i;\n    }\n\n    this(long ii)\n    {\n      i = 3;\n    }\n\n    const int i;\n}\n\nvoid test33()\n{\n}\n\n/***************************************************/\n\nvoid test34()\n{\n  alias uint Uint;\n  foreach(Uint u;1..10) {}\n  for(Uint u=1;u<10;u++) {}\n}\n\n/***************************************************/\n\nref int foo35(bool condition, ref int lhs, ref int rhs)\n{\n        if ( condition ) return lhs;\n        return rhs;\n}\n\nref int bar35()(bool condition, ref int lhs, ref int rhs)\n{\n        if ( condition ) return lhs;\n        return rhs;\n}\n\nvoid test35()\n{\n        int a = 10, b = 11;\n\n        foo35(a<b, a, b) = 42;\n        printf(\"a = %d and b = %d\\n\", a, b); // a = 42 and b = 11\n        assert(a == 42 && b == 11);\n\n        bar35(a<b, a, b) = 52;\n        printf(\"a = %d and b = %d\\n\", a, b);\n        assert(a == 42 && b == 52);\n}\n\n/***************************************************/\n\nint foo36(T...)(T ts)\nif (T.length > 1)\n{\n    return T.length;\n}\n\nint foo36(T...)(T ts)\nif (T.length <= 1)\n{\n    return T.length * 7;\n}\n\nvoid test36()\n{\n    auto i = foo36!(int,int)(1, 2);\n    assert(i == 2);\n    i = foo36(1, 2, 3);\n    assert(i == 3);\n    i = foo36(1);\n    assert(i == 7);\n    i = foo36();\n    assert(i == 0);\n}\n\n\n/***************************************************/\n\nvoid test6685()\n{\n    struct S { int x; }\n    with({ return S(); }())\n    {\n        x++;\n    }\n}\n\n/***************************************************/\n\nstruct A37(alias T)\n{\n}\n\nvoid foo37(X)(X x) if (is(X Y == A37!(U), alias U))\n{\n}\n\nvoid bar37() {}\n\nvoid test37()\n{\n    A37!(bar37) a2;\n    foo37(a2);\n    foo37!(A37!bar37)(a2);\n}\n\n/***************************************************/\n\nstruct A38\n{\n    this(this)\n    {\n        printf(\"B's copy\\n\");\n    }\n    bool empty() {return false;}\n    void popFront() {}\n    int front() { return 1; }\n//    ref A38 opSlice() { return this; }\n}\n\nvoid test38()\n{\n    A38 a;\n    int i;\n    foreach (e; a) { if (++i == 100) break; }\n}\n\n/***************************************************/\n\nalias int function() Fun39;\nalias ref int function() Gun39;\nstatic assert(!is(Fun39 == Gun39));\n\nvoid test39()\n{\n}\n\n/***************************************************/\n\nint x40;\n\nstruct Proxy\n{\n    ref int at(int i)() { return x40; }\n}\n\nvoid test40()\n{\n    Proxy p;\n    auto x = p.at!(1);\n}\n\n/***************************************************/\n\ntemplate Foo41(TList...)\n{\n    alias TList Foo41;\n}\n\nalias Foo41!(immutable(ubyte)[], ubyte[]) X41;\n\nvoid test41()\n{\n}\n\n\n/***************************************************/\n\nbool endsWith(A1, A2)(A1 longer, A2 shorter)\n{\n    static if (is(typeof(longer[0 .. 0] == shorter)))\n    {\n    }\n    else\n    {\n    }\n    return false;\n}\n\nvoid test42()\n{\n    char[] a;\n    byte[] b;\n    endsWith(a, b);\n}\n\n/***************************************************/\n\nvoid f43(S...)(S s) if (S.length > 3)\n{\n}\n\nvoid test43()\n{\n    f43(1, 2, 3, 4);\n}\n\n\n/***************************************************/\n\nstruct S44(int x = 1){}\n\nvoid fun()(S44!(1) b) { }\n\nvoid test44()\n{\n    S44!() s;\n    fun(s);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2006\n\nvoid test2006()\n{\n    string [][] aas = [];\n    assert(aas.length == 0);\n    aas ~= cast (string []) [];\n    assert(aas.length == 1);\n    aas = aas ~ cast (string []) [];\n    assert(aas.length == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8442\n\nvoid test8442()\n{\n    enum int[] fooEnum = [];\n    immutable fooImmutable = fooEnum;\n}\n\n/***************************************************/\n\nclass A45\n{\n  int x;\n  int f()\n  {\n    printf(\"A\\n\");\n    return 1;\n  }\n}\n\nclass B45 : A45\n{\n  override const int f()\n  {\n    printf(\"B\\n\");\n    return 2;\n  }\n}\n\nvoid test45()\n{\n    A45 y = new B45;\n    int i = y.f;\n    assert(i == 2);\n}\n\n/***************************************************/\n\nvoid text10682()\n{\n    ulong x = 1;\n    ulong y = 2 ^^ x;\n}\n\n/***************************************************/\n\nstruct Test46\n{\n int foo;\n}\n\nvoid test46()\n{\n    enum Test46 test = {};\n    enum q = test.foo;\n}\n\n/***************************************************/\n\npure int double_sqr(int x) {\n    int y = x;\n    void do_sqr() { y *= y; }\n    do_sqr();\n    return y;\n}\n\nvoid test47()\n{\n   assert(double_sqr(10) == 100);\n}\n\n/***************************************************/\n\nvoid sort(alias less)(string[] r)\n{\n            bool pred()\n            {\n                return less(\"a\", \"a\");\n            }\n            .sort!(less)(r);\n}\n\nvoid foo48()\n{\n    int[string] freqs;\n    string[] words;\n\nsort!((a, b) { return freqs[a] > freqs[b]; })(words);\nsort!((string a, string b) { return freqs[a] > freqs[b]; })(words);\n//sort!(bool (a, b) { return freqs[a] > freqs[b]; })(words);\n//sort!(function (a, b) { return freqs[a] > freqs[b]; })(words);\n//sort!(function bool(a, b) { return freqs[a] > freqs[b]; })(words);\nsort!(delegate bool(string a, string b) { return freqs[a] > freqs[b]; })(words);\n\n}\n\nvoid test48()\n{\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6408\n\nstatic assert(!is(typeof(string[0..1].init)));\nstatic assert(is(typeof(string[].init) == string[]));\nstatic assert(is(typeof(string[][].init) == string[][]));\nstatic assert(is(typeof(string[][][].init) == string[][][]));\n\nstatic assert(is(typeof(string[1].init) == string[1]));\nstatic assert(is(typeof(string[1][1].init) == string[1][1]));\nstatic assert(is(typeof(string[1][1][1].init) == string[1][1][1]));\n\nstatic assert(is(typeof(string[string].init) == string[string]));\nstatic assert(is(typeof(string[string][string].init) == string[string][string]));\nstatic assert(is(typeof(string[string][string][string].init) == string[string][string][string]));\n\ntemplate TT6408(T...) { alias T TT6408; }\nstatic assert(is(typeof(TT6408!(int, int)[].init) == TT6408!(int, int)));\nstatic assert(is(typeof(TT6408!(int, int)[0..$].init) == TT6408!(int, int)));\nstatic assert(is(typeof(TT6408!(int, int)[$-1].init) == int));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9409\n\ntemplate TT9409(T...) { alias T TT9409; }\n\ntemplate idxTypes9409(Prefix...)\n{\n    TT9409!((Prefix[$-1])) idxTypes9409;\n}\n\nalias idxTypes9409!(int) Types9409;\n\n/***************************************************/\n\nstruct S49\n{\n    static void* p;\n\n    this( string name )\n    {\n        printf( \"(ctor) &%.*s.x = %p\\n\", name.length, name.ptr, &x );\n        p = cast(void*)&x;\n    }\n\n    invariant() {}\n\n    int x;\n}\n\nvoid test49()\n{\n    auto s = new S49(\"s2\");\n\n    printf( \"&s2.x = %p\\n\", &s.x );\n    assert(cast(void*)&s.x == S49.p);\n}\n\n/***************************************************/\n\nauto max50(Ts...)(Ts args)\n  if (Ts.length >= 2\n        && is(typeof(Ts[0].init > Ts[1].init ? Ts[1].init : Ts[0].init)))\n{\n    static if (Ts.length == 2)\n        return args[1] > args[0] ? args[1] : args[0];\n    else\n        return max50(max50(args[0], args[1]), args[2 .. $]);\n}\n\nvoid test50()\n{\n   assert(max50(4, 5) == 5);\n   assert(max50(2.2, 4.5) == 4.5);\n   assert(max50(\"Little\", \"Big\") == \"Little\");\n\n   assert(max50(4, 5.5) == 5.5);\n   assert(max50(5.5, 4) == 5.5);\n}\n\n/***************************************************/\n\nvoid test51()\n{\n    static immutable int[2] array = [ 42 ];\n    enum e = array[1];\n    static immutable int[1] array2 = [ 0: 42 ];\n    enum e2 = array2[0];\n    assert(e == 0);\n    assert(e2 == 42);\n}\n\n/***************************************************/\n\nenum ubyte[4] a52 = [5,6,7,8];\n\nvoid test52()\n{\n  int x=3;\n  assert(a52[x]==8);\n}\n\n/***************************************************/\n\nvoid test53()\n{\n    size_t func2(immutable(void)[] t)\n    {\n        return 0;\n    }\n}\n\n/***************************************************/\n\nvoid foo54(void delegate(void[]) dg) { }\n\nvoid test54()\n{\n    void func(void[] t) pure { }\n    foo54(&func);\n\n//    void func2(const(void)[] t) { }\n//    foo54(&func2);\n}\n\n/***************************************************/\n\nclass Foo55\n{\n    synchronized void noop1() { }\n    void noop2() shared { }\n}\n\nvoid test55()\n{\n    auto foo = new shared(Foo55);\n    foo.noop1();\n    foo.noop2();\n}\n\n/***************************************************/\n\nenum float one56 = 1 * 1;\ntemplate X56(float E) { int X56 = 2; }\nalias X56!(one56 * one56) Y56;\n\nvoid test56()\n{\n    assert(Y56 == 2);\n}\n\n/***************************************************/\n\nvoid test57()\n{\n    alias shared(int) T;\n    assert (is(T == shared));\n}\n\n/***************************************************/\n\nstruct A58\n{\n  int a,b;\n}\n\nvoid test58()\n{\n  A58[2] rg=[{1,2},{5,6}];\n  assert(rg[0].a == 1);\n  assert(rg[0].b == 2);\n  assert(rg[1].a == 5);\n  assert(rg[1].b == 6);\n}\n\n/***************************************************/\n\nclass A59 {\n    const foo(int i)  { return i; }\n}\n\n/***************************************************/\n\nvoid test60()\n{\n    enum real ONE = 1.0;\n    real x;\n    for (x=0.0; x<10.0; x+=ONE)\n        printf(\"%Lg\\n\", x);\n    printf(\"%Lg\\n\", x);\n    assert(x == 10);\n}\n\n/***************************************************/\n\npure immutable(T)[] fooPT(T)(immutable(T)[] x, immutable(T)[] y){\n\n  immutable(T)[] fooState;\n\n  immutable(T)[] bar(immutable(T)[] x){\n    fooState = \"hello \";\n    return x ~ y;\n  }\n\n  return fooState ~ bar(x);\n\n}\n\n\nvoid test61()\n{\n    auto s = fooPT(\"p\", \"c\");\n    printf(\"%.*s\\n\", cast(int)s.length, s.ptr);\n}\n\n/***************************************************/\n\nvoid test9577()\n{\n    static int function(int)[] foo = [x => x];\n    foo[0](0);\n}\n\n/***************************************************/\n\nint[3] foo62(int[3] a)\n{\n    a[1]++;\n    return a;\n}\n\nvoid test62()\n{\n    int[3] b;\n    b[0] = 1;\n    b[1] = 2;\n    b[2] = 3;\n    auto c = foo62(b);\n    assert(b[0] == 1);\n    assert(b[1] == 2);\n    assert(b[2] == 3);\n\n    assert(c[0] == 1);\n    assert(c[1] == 3);\n    assert(c[2] == 3);\n}\n\n/***************************************************/\n\nvoid test3927()\n{\n    int[] array;\n    assert(array.length++ == 0);\n    assert(array.length == 1);\n    assert(array.length-- == 1);\n    assert(array.length == 0);\n}\n\n/***************************************************/\n\nvoid test63()\n{\n    int[3] b;\n    b[0] = 1;\n    b[1] = 2;\n    b[2] = 3;\n    auto c = b;\n    b[1]++;\n    assert(b[0] == 1);\n    assert(b[1] == 3);\n    assert(b[2] == 3);\n\n    assert(c[0] == 1);\n    assert(c[1] == 2);\n    assert(c[2] == 3);\n}\n\n/***************************************************/\n\nvoid test64()\n{\n    int[3] b;\n    b[0] = 1;\n    b[1] = 2;\n    b[2] = 3;\n    int[3] c;\n    c = b;\n    b[1]++;\n    assert(b[0] == 1);\n    assert(b[1] == 3);\n    assert(b[2] == 3);\n\n    assert(c[0] == 1);\n    assert(c[1] == 2);\n    assert(c[2] == 3);\n}\n\n/***************************************************/\n\nint[2] foo65(int[2] a)\n{\n    a[1]++;\n    return a;\n}\n\nvoid test65()\n{\n    int[2] b;\n    b[0] = 1;\n    b[1] = 2;\n    int[2] c = foo65(b);\n    assert(b[0] == 1);\n    assert(b[1] == 2);\n\n    assert(c[0] == 1);\n    assert(c[1] == 3);\n}\n\n/***************************************************/\n\nint[1] foo66(int[1] a)\n{\n    a[0]++;\n    return a;\n}\n\nvoid test66()\n{\n    int[1] b;\n    b[0] = 1;\n    int[1] c = foo66(b);\n    assert(b[0] == 1);\n    assert(c[0] == 2);\n}\n\n/***************************************************/\n\nint[2] foo67(out int[2] a)\n{\n    a[0] = 5;\n    a[1] = 6;\n    return a;\n}\n\nvoid test67()\n{\n    int[2] b;\n    b[0] = 1;\n    b[1] = 2;\n    int[2] c = foo67(b);\n    assert(b[0] == 5);\n    assert(b[1] == 6);\n\n    assert(c[0] == 5);\n    assert(c[1] == 6);\n}\n\n/***************************************************/\n\nvoid test68()\n{\n    digestToString(cast(ubyte[16])x\"c3fcd3d76192e4007dfb496cca67e13b\");\n}\n\nvoid digestToString(const ubyte[16] digest)\n{\n    assert(digest[0] == 0xc3);\n    assert(digest[15] == 0x3b);\n}\n\n/***************************************************/\n\nvoid test69()\n{\n    digestToString69(cast(ubyte[16])x\"c3fcd3d76192e4007dfb496cca67e13b\");\n}\n\nvoid digestToString69(ref const ubyte[16] digest)\n{\n    assert(digest[0] == 0xc3);\n    assert(digest[15] == 0x3b);\n}\n\n/***************************************************/\n\nvoid test70()\n{\n    digestToString70(\"1234567890123456\");\n}\n\nvoid digestToString70(ref const char[16] digest)\n{\n    assert(digest[0] == '1');\n    assert(digest[15] == '6');\n}\n\n/***************************************************/\n\nvoid foo71(out shared int o) {}\n\n/***************************************************/\n\nstruct foo72\n{\n  int bar() shared { return 1; }\n}\n\nvoid test72()\n{\n  shared foo72 f;\n  auto x = f.bar;\n}\n\n/***************************************************/\n\nclass Foo73\n{\n  static if (is(typeof(this) T : shared T))\n    static assert(0);\n  static if (is(typeof(this) U == shared U))\n    static assert(0);\n  static if (is(typeof(this) U == const U))\n    static assert(0);\n  static if (is(typeof(this) U == immutable U))\n    static assert(0);\n  static if (is(typeof(this) U == const shared U))\n    static assert(0);\n\n  static assert(!is(int == const));\n  static assert(!is(int == immutable));\n  static assert(!is(int == shared));\n\n  static assert(is(int == int));\n  static assert(is(const(int) == const));\n  static assert(is(immutable(int) == immutable));\n  static assert(is(shared(int) == shared));\n  static assert(is(const(shared(int)) == shared));\n  static assert(is(const(shared(int)) == const));\n\n  static assert(!is(const(shared(int)) == immutable));\n  static assert(!is(const(int) == immutable));\n  static assert(!is(const(int) == shared));\n  static assert(!is(shared(int) == const));\n  static assert(!is(shared(int) == immutable));\n  static assert(!is(immutable(int) == const));\n  static assert(!is(immutable(int) == shared));\n}\n\ntemplate Bar(T : T)\n{\n    alias T Bar;\n}\n\ntemplate Barc(T : const(T))\n{\n    alias T Barc;\n}\n\ntemplate Bari(T : immutable(T))\n{\n    alias T Bari;\n}\n\ntemplate Bars(T : shared(T))\n{\n    alias T Bars;\n}\n\ntemplate Barsc(T : shared(const(T)))\n{\n    alias T Barsc;\n}\n\n\nvoid test73()\n{\n    auto f = new Foo73;\n\n    alias int T;\n\n    // 5*5 == 25 combinations, plus 2 for swapping const and shared\n\n    static assert(is(Bar!(T) == T));\n    static assert(is(Bar!(const(T)) == const(T)));\n    static assert(is(Bar!(immutable(T)) == immutable(T)));\n    static assert(is(Bar!(shared(T)) == shared(T)));\n    static assert(is(Bar!(shared(const(T))) == shared(const(T))));\n\n    static assert(is(Barc!(const(T)) == T));\n    static assert(is(Bari!(immutable(T)) == T));\n    static assert(is(Bars!(shared(T)) == T));\n    static assert(is(Barsc!(shared(const(T))) == T));\n\n    static assert(is(Barc!(T) == T));\n    static assert(is(Barc!(immutable(T)) == T));\n    static assert(is(Barc!(const(shared(T))) == shared(T)));\n    static assert(is(Barsc!(immutable(T)) == T));\n\n    static assert(is(Bars!(const(shared(T))) == const(T)));\n    static assert(is(Barsc!(shared(T)) == T));\n\n    Bars!(shared(const(T))) b;\n    pragma(msg, typeof(b));\n\n    static assert(is(Bars!(shared(const(T))) == const(T)));\n    static assert(is(Barc!(shared(const(T))) == shared(T)));\n\n    static assert(!is(Bari!(T)));\n    static assert(!is(Bari!(const(T))));\n    static assert(!is(Bari!(shared(T))));\n    static assert(!is(Bari!(const(shared(T)))));\n\n    static assert(is(Barc!(shared(T))));\n\n    static assert(!is(Bars!(T)));\n    static assert(!is(Bars!(const(T))));\n    static assert(!is(Bars!(immutable(T))));\n    static assert(!is(Barsc!(T)));\n    static assert(!is(Barsc!(const(T))));\n}\n\n/***************************************************/\n\npure nothrow {\n  alias void function(int) A74;\n}\n\nalias void function(int) pure nothrow B74;\nalias pure nothrow void function(int) C74;\n\nvoid test74()\n{\n    A74 a = null;\n    B74 b = null;\n    C74 c = null;\n    a = b;\n    a = c;\n}\n\n/***************************************************/\n\nvoid test9212()\n{\n    int[int] aa;\n    foreach (const key, const val; aa) {}\n    foreach (size_t key, size_t val; aa) {}\n}\n\n/***************************************************/\n\nclass A75\n{\n    pure static void raise(string s)\n    {\n        throw new Exception(s);\n    }\n}\n\nvoid test75()\n{   int x = 0;\n    try\n    {\n        A75.raise(\"a\");\n    } catch (Exception e)\n    {\n        x = 1;\n    }\n    assert(x == 1);\n}\n\n/***************************************************/\n\nvoid test76()\n{\n    int x, y;\n    bool which;\n    (which ? x : y) += 5;\n    assert(y == 5);\n}\n\n/***************************************************/\n\nvoid test77()\n{\n    auto a = [\"hello\", \"world\"];\n    pragma(msg, typeof(a));\n    auto b = a;\n    assert(a is b);\n    assert(a == b);\n    b = a.dup;\n    assert(a == b);\n    assert(a !is b);\n}\n\n/***************************************************/\n\nvoid test78()\n{\n    auto array = [0, 2, 4, 6, 8, 10];\n    array = array[0 .. $ - 2];         // Right-shrink by two elements\n    assert(array == [0, 2, 4, 6]);\n    array = array[1 .. $];             // Left-shrink by one element\n    assert(array == [2, 4, 6]);\n    array = array[1 .. $ - 1];         // Shrink from both sides\n    assert(array == [4]);\n}\n\n/***************************************************/\n\nvoid test79()\n{\n    auto a = [87, 40, 10];\n    a ~= 42;\n    assert(a == [87, 40, 10, 42]);\n    a ~= [5, 17];\n    assert(a == [87, 40, 10, 42, 5, 17]);\n}\n\n/***************************************************/\n\nvoid test6317()\n{\n    int b = 12345;\n    struct nested { int a; int fun() { return b; } }\n    static assert(!__traits(compiles, { nested x = { 3, null }; }));\n    nested g = { 7 };\n    auto h = nested(7);\n    assert(g.fun() == 12345);\n    assert(h.fun() == 12345);\n}\n\n/***************************************************/\n\nvoid test80()\n{\n    auto array = new int[10];\n    array.length += 1000;\n    assert(array.length == 1010);\n    array.length /= 10;\n    assert(array.length == 101);\n    array.length -= 1;\n    assert(array.length == 100);\n    array.length |= 1;\n    assert(array.length == 101);\n    array.length ^= 3;\n    assert(array.length == 102);\n    array.length &= 2;\n    assert(array.length == 2);\n    array.length *= 2;\n    assert(array.length == 4);\n    array.length <<= 1;\n    assert(array.length == 8);\n    array.length >>= 1;\n    assert(array.length == 4);\n    array.length >>>= 1;\n    assert(array.length == 2);\n    array.length %= 2;\n    assert(array.length == 0);\n\n    int[]* foo()\n    {\n        static int x;\n        x++;\n        assert(x == 1);\n        auto p = &array;\n        return p;\n    }\n\n    (*foo()).length += 2;\n    assert(array.length == 2);\n}\n\n/***************************************************/\n\nvoid test81()\n{\n    int[3] a = [1, 2, 3];\n    int[3] b = a;\n    a[1] = 42;\n    assert(b[1] == 2); // b is an independent copy of a\n    int[3] fun(int[3] x, int[3] y) {\n       // x and y are copies of the arguments\n       x[0] = y[0] = 100;\n       return x;\n    }\n    auto c = fun(a, b);         // c has type int[3]\n    assert(c == [100, 42, 3]);\n    assert(b == [1, 2, 3]);     // b is unaffected by fun\n}\n\n/***************************************************/\n\nvoid test82()\n{\n    auto a1 = [ \"Jane\":10.0, \"Jack\":20, \"Bob\":15 ];\n    auto a2 = a1;                    // a1 and a2 refer to the same data\n    a1[\"Bob\"] = 100;                 // Changing a1\n    assert(a2[\"Bob\"] == 100);        //is same as changing a2\n    a2[\"Sam\"] = 3.5;                 //and vice\n    assert(a2[\"Sam\"] == 3.5);        //    versa\n}\n\n/***************************************************/\n\nvoid test7942()\n{\n    string a = \"a\";\n    wstring b = \"b\";\n    dstring c = \"c\";\n\n    a ~= \"a\"c;\n    static assert(!is(typeof(a ~= \"b\"w)));\n    static assert(!is(typeof(a ~= \"c\"d)));\n    static assert(!is(typeof(b ~= \"a\"c)));\n    b ~= \"b\"w;\n    static assert(!is(typeof(b ~= \"c\"d)));\n    static assert(!is(typeof(c ~= \"a\"c)));\n    static assert(!is(typeof(c ~= \"b\"w)));\n    c ~= \"c\"d;\n\n    assert(a == \"aa\");\n    assert(b == \"bb\");\n    assert(c == \"cc\");\n}\n\n/***************************************************/\n\nvoid bump(ref int x) { ++x; }\n\nvoid test83()\n{\n   int x = 1;\n   bump(x);\n   assert(x == 2);\n}\n\n/***************************************************/\n\ninterface Test4174\n{\n    void func(T)() {}\n}\n\n/***************************************************/\n\nauto foo84 = [1, 2.4];\n\nvoid test84()\n{\n    pragma(msg, typeof([1, 2.4]));\n    static assert(is(typeof([1, 2.4]) == double[]));\n\n    pragma(msg, typeof(foo84));\n    static assert(is(typeof(foo84) == double[]));\n}\n\n/***************************************************/\n\nvoid test85()\n{\n    dstring c = \"V\\u00E4rld\";\n    c = c ~ '!';\n    assert(c == \"V\\u00E4rld!\");\n    c = '@' ~ c;\n    assert(c == \"@V\\u00E4rld!\");\n\n    wstring w = \"V\\u00E4rld\";\n    w = w ~ '!';\n    assert(w == \"V\\u00E4rld!\");\n    w = '@' ~ w;\n    assert(w == \"@V\\u00E4rld!\");\n\n    string s = \"V\\u00E4rld\";\n    s = s ~ '!';\n    assert(s == \"V\\u00E4rld!\");\n    s = '@' ~ s;\n    assert(s == \"@V\\u00E4rld!\");\n}\n\n/***************************************************/\n\nvoid test86()\n{\n    int[][] a = [ [1], [2,3], [4] ];\n    int[][] w = [ [1, 2], [3], [4, 5], [] ];\n    int[][] x = [ [], [1, 2], [3], [4, 5], [] ];\n}\n\n/***************************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=3379\n\nT1[] find(T1, T2)(T1[] longer, T2[] shorter)\n   if (is(typeof(longer[0 .. 1] == shorter) : bool))\n{\n   while (longer.length >= shorter.length) {\n      if (longer[0 .. shorter.length] == shorter) break;\n      longer = longer[1 .. $];\n   }\n   return longer;\n}\n\nauto max(T...)(T a)\n      if (T.length == 2\n         && is(typeof(a[1] > a[0] ? a[1] : a[0]))\n       || T.length > 2\n         && is(typeof(max(max(a[0], a[1]), a[2 .. $])))) {\n   static if (T.length == 2) {\n      return a[1] > a[0] ? a[1] : a[0];\n   } else {\n      return max(max(a[0], a[1]), a[2 .. $]);\n   }\n}\n\n// Cases which would ICE or segfault\nstruct Bulldog(T){\n    static void cat(Frog)(Frog f) if (true)\n    {    }\n}\n\nvoid mouse(){\n    Bulldog!(int).cat(0);\n}\n\nvoid test87()\n{\n    double[] d1 = [ 6.0, 1.5, 2.4, 3 ];\n    double[] d2 = [ 1.5, 2.4 ];\n    assert(find(d1, d2) == d1[1 .. $]);\n    assert(find(d1, d2) == d1[1 .. $]); // Check for memory corruption\n    assert(max(4, 5) == 5);\n    assert(max(3, 4, 5) == 5);\n}\n\n/***************************************************/\n\ntemplate test4284(alias v) { enum test4284 = v.length == 0; }\nstatic assert(test4284!(cast(string)null));\nstatic assert(test4284!(cast(string[])null));\n\n/***************************************************/\n\nstruct S88\n{\n    void opDispatch(string s, T)(T i)\n    {\n        printf(\"S.opDispatch('%.*s', %d)\\n\", s.length, s.ptr, i);\n    }\n}\n\nclass C88\n{\n    void opDispatch(string s)(int i)\n    {\n        printf(\"C.opDispatch('%.*s', %d)\\n\", s.length, s.ptr, i);\n    }\n}\n\nstruct D88\n{\n    template opDispatch(string s)\n    {\n        enum int opDispatch = 8;\n    }\n}\n\nvoid test88()\n{\n    S88 s;\n    s.opDispatch!(\"hello\")(7);\n    s.foo(7);\n\n    auto c = new C88();\n    c.foo(8);\n\n    D88 d;\n    printf(\"d.foo = %d\\n\", d.foo);\n    assert(d.foo == 8);\n}\n\n/***************************************************/\n\nvoid test89() {\n    static struct X {\n        int x;\n        int bar() { return x; }\n    }\n    X s;\n    printf(\"%d\\n\", s.sizeof);\n    assert(s.sizeof == 4);\n}\n\n/***************************************************/\n\nstruct S90\n{\n    void opDispatch( string name, T... )( T values )\n    {\n        assert(values[0] == 3.14);\n    }\n}\n\nvoid test90( )\n{   S90 s;\n    s.opDispatch!(\"foo\")( 3.14 );\n    s.foo( 3.14 );\n}\n\n/***************************************************/\n\nstruct A7439(int r, int c)\n{\n    alias r R;\n    alias c C;\n    alias float[R * C] Data;\n    Data _data;\n    alias _data this;\n\n    this(Data ar){ _data = ar; }\n\n    pure ref float opIndex(size_t rr, size_t cc){ return _data[cc + rr * C]; }\n}\n\nvoid test7439()\n{\n    A7439!(2, 2) a = A7439!(2, 2)([8, 3, 2, 9]);\n    a[0,0] -= a[0,0] * 2.0;\n}\n\n/***************************************************/\n\nvoid foo91(uint line = __LINE__) { printf(\"%d\\n\", line); }\n\nvoid test91()\n{\n    foo91();\n    printf(\"%d\\n\", __LINE__);\n}\n\n/***************************************************/\n\nbool fun13468(Object e, typeof(null) needle)\n{\n    return (e == needle);\n}\n\nvoid test13468()\n{\n    assert(fun13468(null, null));\n}\n\n/***************************************************/\n\nauto ref foo92(ref int x) { return x; }\nint bar92(ref int x) { return x; }\n\nvoid test92()\n{\n    int x = 3;\n    int i = bar92(foo92(x));\n    assert(i == 3);\n}\n\n/***************************************************/\n\nstruct Foo93\n{\n    public int foo() const\n    {\n        return 2;\n    }\n}\n\nvoid test93()\n{\n    const Foo93 bar = Foo93();\n    enum bla = bar.foo();\n    assert(bla == 2);\n}\n\n/***************************************************/\n\n\nextern(C++) class C1687\n{\n    void func() {}\n}\n\nvoid test1687()\n{\n    auto c = new C1687();\n    assert(c.__vptr[0] == (&c.func).funcptr);\n}\n\n/***************************************************/\n\nstruct Foo94\n{\n    int x, y;\n    real z;\n}\n\npure nothrow Foo94 makeFoo(const int x, const int y)\n{\n    return Foo94(x, y, 3.0);\n}\n\nvoid test94()\n{\n    auto f = makeFoo(1, 2);\n    assert(f.x==1);\n    assert(f.y==2);\n    assert(f.z==3);\n}\n\n/***************************************************/\n\nstruct T95\n{\n    @disable this(this)\n    {\n    }\n}\n\nstruct S95\n{\n    T95 t;\n}\n\n@disable void foo95() { }\n\nstruct T95A\n{\n    @disable this(this);\n}\n\nstruct S95A\n{\n    T95A t;\n}\n\n@disable void foo95A() { }\n\nvoid test95()\n{\n    S95 s;\n    S95 t;\n    static assert(!__traits(compiles, t = s));\n    static assert(!__traits(compiles, foo95()));\n\n    S95A u;\n    S95A v;\n    static assert(!__traits(compiles, v = u));\n    static assert(!__traits(compiles, foo95A()));\n}\n\n/***************************************************/\n\nstruct S96(alias init)\n{\n    int[] content = init;\n}\n\nvoid test96()\n{\n    S96!([12, 3]) s1;\n    S96!([1, 23]) s2;\n    //writeln(s1.content);\n    //writeln(s2.content);\n    assert(!is(typeof(s1) == typeof(s2)));\n}\n\n/***************************************************/\n\nstruct A97\n{\n    const bool opEquals(ref const A97) { return true; }\n    ref A97 opUnary(string op)() if (op == \"++\")\n    {\n        return this;\n    }\n}\n\nvoid test97()\n{\n    A97 a, b;\n    foreach (e; a .. b) {\n    }\n}\n\n/***************************************************/\n\nvoid test98()\n{\n    auto a = new int[2];\n    // the name \"length\" should not pop up in an index expression\n    static assert(!is(typeof(a[length - 1])));\n}\n\n/***************************************************/\n\nstring s99;\n\nvoid bar99(string i)\n{\n}\n\nvoid function(string) foo99(string i)\n{\n    return &bar99;\n}\n\nvoid test99()\n{\n    foo99 (s99 ~= \"a\") (s99 ~= \"b\");\n    assert(s99 == \"ab\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5081\n\nvoid test5081()\n{\n    static pure immutable(int[]) x1()\n    {\n        int[] a = new int[](10);\n        return a;\n    }\n    static pure immutable(int[]) x2(int len)\n    {\n        int[] a = new int[](len);\n        return a;\n    }\n    static pure immutable(int[]) x3(immutable(int[]) org)\n    {\n        int[] a = new int[](org.length);\n        return a;\n    }\n\n    immutable a1 = x1();\n    immutable a2 = x2(10);\n    immutable a3 = x3([1,2]);\n\n    static pure int[] y1()\n    {\n        return new int[](10);\n    }\n\n    immutable b1 = y1();\n}\n\n/***************************************************/\n\nvoid test100()\n{\n   string s;\n\n   /* Testing order of evaluation */\n   void delegate(string, string) fun(string) {\n      s ~= \"b\";\n      return delegate void(string x, string y) { s ~= \"e\"; };\n   }\n   fun(s ~= \"a\")(s ~= \"c\", s ~= \"d\");\n   assert(s == \"abcde\", s);\n}\n\n/***************************************************/\n\nvoid test101()\n{\n   int[] d1 = [ 6, 1, 2 ];\n   byte[] d2 = [ 6, 1, 2 ];\n   assert(d1 == d2);\n   d2 ~= [ 6, 1, 2 ];\n   assert(d1 != d2);\n}\n\n/***************************************************/\n\n\nvoid test5403()\n{\n    struct S\n    {\n        static int front;\n        enum back = \"yes!\";\n        bool empty;\n        void popAny() { empty = true; }\n        alias popAny popFront;\n        alias popAny popBack;\n    }\n    S.front = 7;\n    foreach(int i; S()) assert(i == 7);\n    S.front = 2;\n    foreach(i; S()) assert(i == 2);\n    foreach_reverse(i; S()) assert(i == \"yes!\");\n}\n\n/***************************************************/\n\nstatic assert([1,2,3] == [1.0,2,3]);\n\n/***************************************************/\n\nint transmogrify(uint) { return 1; }\nint transmogrify(long) { return 2; }\n\nvoid test103()\n{\n    assert(transmogrify(42) == 1);\n}\n\n/***************************************************/\n\nint foo104(int x)\n{\n    int* p = &(x += 1);\n    return *p;\n}\n\nint bar104(int *x)\n{\n    int* p = &(*x += 1);\n    return *p;\n}\n\nvoid test104()\n{\n    auto i = foo104(1);\n    assert(i == 2);\n    i = bar104(&i);\n    assert(i == 3);\n}\n\n/***************************************************/\n\nref int bump105(ref int x) { return ++x; }\n\nvoid test105()\n{\n   int x = 1;\n   bump105(bump105(x)); // two increments\n   assert(x == 3);\n}\n\n/***************************************************/\n\npure int genFactorials(int n) {\n    static pure int factorial(int n) {\n      if (n==2) return 1;\n      return factorial(2);\n    }\n    return factorial(n);\n}\n\n/***************************************************/\n\nvoid test107()\n{\n    int[6] a;\n    //writeln(a);\n    //writeln(a.init);\n    assert(a.init == [0,0,0,0,0,0]);\n}\n\n/***************************************************/\n\nclass A109 {}\n\nvoid test109()\n{\n    immutable(A109) b;\n    A109 c;\n    auto z = true ? b : c;\n    //writeln(typeof(z).stringof);\n    static assert(is(typeof(z) == const(A109)));\n}\n\n/***************************************************/\n\ntemplate Boo(T) {}\nstruct Foo110(T, alias V = Boo!T)\n{\n    pragma(msg, V.stringof);\n    static const s = V.stringof;\n}\nalias Foo110!double B110;\nalias Foo110!int A110;\n\nstatic assert(B110.s == \"Boo!double\");\nstatic assert(A110.s == \"Boo!int\");\n\n/***************************************************/\n\nint test11247()\n{\n    static assert(is(byte[typeof(int.init).sizeof] == byte[4]));\n    static assert(is(byte[typeof(return).sizeof] == byte[4]));\n    return 0;\n}\n\n/***************************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=3716\nvoid test111()\n{\n    auto k1 = true ? [1,2] : []; // OK\n    auto k2 = true ? [[1,2]] : [[]];\n    auto k3 = true ? [] : [[1,2]];\n    auto k4 = true ? [[[]]] : [[[1,2]]];\n    auto k5 = true ? [[[1,2]]] : [[[]]];\n    auto k6 = true ? [] : [[[]]];\n    static assert(!is(typeof(true ? [[[]]] : [[1,2]]))); // Must fail\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=658\n\nvoid test658()\n{\n    struct S { int i; }\n    class C { int i; }\n\n    S s;\n    S* sp = &s;\n    with (sp) i = 42;\n    assert(s.i == 42);\n    with (&s) i = 43;\n    assert(s.i == 43);\n\n    C c = new C;\n    C* cp = &c;\n    with (cp) i = 42;\n    assert(c.i == 42);\n    with (&c) i = 43;\n    assert(c.i == 43);\n}\n\n/***************************************************/\n\nvoid test3069()\n{\n    ubyte id = 0;\n    void[] v = [id] ~ [id];\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4303\n\ntemplate foo112() if (__traits(compiles,undefined))\n{\n    enum foo112 = false;\n}\n\ntemplate foo112() if (true)\n{\n    enum foo112 = true;\n}\n\npragma(msg,__traits(compiles,foo112!()));\nstatic assert(__traits(compiles,foo112!()));\n\nconst bool bar112 = foo112!();\n\n\n/***************************************************/\n\nstruct File113\n{\n    this(int name) { }\n\n    ~this() { }\n\n    void opAssign(File113 rhs) { }\n\n    struct ByLine\n    {\n        File113 file;\n\n        this(int) { }\n\n    }\n\n    ByLine byLine()\n    {\n        return ByLine(1);\n    }\n}\n\nauto filter113(File113.ByLine rs)\n{\n    struct Filter\n    {\n        this(File113.ByLine r) { }\n    }\n\n    return Filter(rs);\n}\n\nvoid test113()\n{\n    auto f = File113(1);\n    auto rx = f.byLine();\n    auto file = filter113(rx);\n}\n\n/***************************************************/\n\ntemplate foo114(fun...)\n{\n    auto foo114(int[] args)\n    {\n        return 1;\n    }\n}\n\npragma(msg, typeof(foo114!\"a + b\"([1,2,3])));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3935\n\nstruct Foo115 {\n    void opBinary(string op)(Foo other) {\n        pragma(msg, \"op: \" ~ op);\n        assert(0);\n    }\n}\n\nvoid test115()\n{\n    Foo115 f;\n    f = f;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2477\n\nvoid foo116(T,)(T t) { T x; }\n\nvoid test116()\n{\n    int[] data = [1,2,3,];  // OK\n\n    data = [ 1,2,3, ];  // fails\n    auto i = data[1,];\n    foo116!(int)(3);\n    foo116!(int,)(3);\n    foo116!(int,)(3,);\n}\n\n/***************************************************/\n\nvoid test1891()\n{\n    struct C {\n        char[8] x = \"helloabc\";\n    }\n\n    int main()\n    {\n        C* a = new C;\n        C*[] b;\n        b ~= new C;\n\n        auto g = a ~ b;\n        assert(g[0] && g[1] && g[0].x == g[1].x);\n\n        return 0;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4291\n\nvoid test117() pure\n{\n    mixin declareVariable;\n    var = 42;\n    mixin declareFunction;\n    readVar();\n}\ntemplate declareVariable() { int var; }\ntemplate declareFunction()\n{\n    int readVar() { return var; }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4177\n\npure real log118(real x) {\n    if (__ctfe)\n        return 0.0;\n    else\n        return 1.0;\n}\n\nenum x118 = log118(4.0);\n\nvoid test118() {}\n\n/***************************************************/\n\nvoid bug4465()\n{\n    const a = 2 ^^ 2;\n    int b = a;\n}\n\n/***************************************************/\n\npure void foo(int *p)\n{\n    *p = 3;\n}\n\npure void test120()\n{\n    int i;\n    foo(&i);\n    assert(i == 3);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4866\n\nimmutable int[3] statik = [ 1, 2, 3 ];\nenum immutable(int)[] dynamic = statik;\n\nstatic assert(is(typeof(dynamic) == immutable(int)[]));\nstatic if (! is(typeof(dynamic) == immutable(int)[]))\n{\n    static assert(0);   // (7)\n}\npragma(msg, \"!! \", typeof(dynamic));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2943\n\nstruct Foo2943\n{\n    int a;\n    int b;\n    alias b this;\n}\n\nvoid test122()\n{\n    Foo2943 foo, foo2;\n    foo.a = 1;\n    foo.b = 2;\n    foo2.a = 3;\n    foo2.b = 4;\n\n    foo2 = foo;\n    assert(foo2.a == foo.a);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4641\n\nstruct S123 {\n    int i;\n    alias i this;\n}\n\nvoid test123() {\n    S123[int] ss;\n    ss[0] = S123.init; // This line causes Range Violation.\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2451\n\nstruct Foo124 {\n    int z = 3;\n    void opAssign(Foo124 x) { z= 2;}\n}\n\nstruct Bar124 {\n    int z = 3;\n    this(this){ z = 17; }\n}\n\nvoid test124() {\n    Foo124[string] stuff;\n    stuff[\"foo\"] = Foo124.init;\n    assert(stuff[\"foo\"].z == 3);\n    stuff[\"foo\"] = Foo124.init;\n    assert(stuff[\"foo\"].z == 2);\n\n    Bar124[string] stuff2;\n    Bar124 q;\n    stuff2[\"dog\"] = q;\n    assert(stuff2[\"dog\"].z == 17);\n}\n\n/***************************************************/\n\nvoid test3022()\n{\n    static class Foo3022\n    {\n        new(size_t)\n        {\n            assert(0);\n        }\n    }\n\n    scope x = new Foo3022;\n}\n\n/***************************************************/\n\nvoid doNothing() {}\n\nvoid bug5071(short d, ref short c) {\n   assert(c==0x76);\n\n    void closure() {\n        auto c2 = c;\n        auto d2 = d;\n        doNothing();\n    }\n    auto useless = &closure;\n}\n\nvoid test125()\n{\n   short c = 0x76;\n   bug5071(7, c);\n}\n\n/***************************************************/\n\nstruct Foo126\n{\n   static Foo126 opCall(in Foo126 _f) pure\n   {\n       return _f;\n   }\n}\n\n/***************************************************/\n\nvoid test796()\n{\n    struct S { invariant() { throw new Exception(\"\"); } }\n    S* s;\n    try {\n        assert(s);\n    } catch (Error) {\n    }\n}\n\n/***************************************************/\n\nvoid test7077()\n{\n    if(0) mixin(\"auto x = 2;\");\n    auto x = 1;\n}\n\n/***************************************************/\n\nstruct Tuple127(S...)\n{\n    S expand;\n    alias expand this;\n}\n\nalias Tuple127!(int, int) Foo127;\n\nvoid test127()\n{\n    Foo127[] m_array;\n    Foo127 f;\n    m_array ~= f;\n}\n\n/***************************************************/\n\nstruct Bug4434 {}\nalias const Bug4434* IceConst4434;\nalias shared Bug4434* IceShared4434;\nalias shared Bug4434[] IceSharedArray4434;\nalias immutable Bug4434* IceImmutable4434;\nalias shared const Bug4434* IceSharedConst4434;\n\nalias int MyInt4434;\nalias const MyInt4434[3] IceConstInt4434;\n\nalias immutable string[] Bug4830;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4254\n\nvoid bub(const inout int other) {}\n\nvoid test128()\n{\n    bub(1);\n}\n\n\n/***************************************************/\n\npure nothrow @safe auto bug4915a() {  return 0; }\npure nothrow @safe int  bug4915b() { return bug4915a(); }\n\nvoid bug4915c()\n{\n    pure nothrow @safe int d() { return 0; }\n    int e() pure nothrow @safe { return d(); }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5164\n\nstatic if (is(int Q == int, Z...))  { }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5195\n\nalias typeof(foo5195) food5195;\nconst int * foo5195 = null;\nalias typeof(foo5195) good5195;\nstatic assert( is (food5195 == good5195));\n\n/***************************************************/\n\nversion (Windows)\n{\n}\nelse\n{\nint[0] var5332;\nvoid test5332() { auto x = var5332; }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5191\n\nstruct Foo129\n{\n    void add(T)(T value) nothrow\n    {\n        this.value += value;\n    }\n\n    this(int value)\n    {\n        this.value = value;\n    }\n\n    int value;\n}\n\nvoid test129()\n{\n    auto foo = Foo129(5);\n    assert(foo.value == 5);\n\n    foo.add(2);\n    printf(\"%d\\n\", foo.value);\n    assert(foo.value == 7);\n\n    foo.add(3);\n    printf(\"%d\\n\", foo.value);\n    assert(foo.value == 10);\n\n    foo.add(3);\n    printf(\"%d\\n\", foo.value);\n    assert(foo.value == 13);\n\n    void delegate (int) nothrow dg = &foo.add!(int);\n    dg(7);\n    assert(foo.value == 20);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6169\n\nauto ctfefunc6169() { return \"{}\"; }\nenum ctfefptr6169 = &ctfefunc6169;\nint ctfefunc6169a() { return 1; }\ntemplate x6169(string c) { alias int x6169; }\ntemplate TT6169(T...) { alias T TT6169; }\n@property ctfeprop6169() { return \"g\"; }\n\nvoid test6169() pure @safe\n{\n    enum a = ctfefunc6169();\n    static b = ctfefunc6169();\n    x6169!(ctfefunc6169()) tt;\n    mixin(ctfefunc6169());\n    static if(ctfefunc6169()) {}\n    pragma(msg, ctfefunc6169());\n    enum xx\n    {\n        k = 0,\n        j = ctfefunc6169a()\n    }\n    auto g = mixin('\"' ~ ctfefunc6169() ~ '\"');\n    //auto h = import(\"testx.d\" ~ false ? ctfefunc() : \"\");\n    alias TT6169!(int, int)[ctfefunc6169a()..ctfefunc6169a()] i;\n    alias TT6169!(int, int)[ctfefunc6169a()] j;\n    int[ctfefunc6169a()+1] k;\n    alias int[ctfefunc6169a()] l;\n    switch(1)\n    {\n    //case ctfefunc6169a(): // Can't do this because of case variables\n    case ctfefunc6169a()+1:\n        ..\n    case ctfefunc6169a()+2:\n    default:\n        break;\n    }\n    static assert(ctfefunc6169a());\n    void fun(int i : ctfefunc6169a() = ctfefunc6169a(), alias j)() if (ctfefunc6169a()) {}\n    fun!(ctfefunc6169a(), ctfefunc6169())();\n    enum z = ctfefptr6169();\n\n    auto p = mixin(ctfeprop6169);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10506\n\nvoid impureFunc10506() {}\nstring join10506(RoR)(RoR ror)\n{\n    impureFunc10506();\n    return ror[0] ~ ror[1];\n}\n\nvoid test10506() pure\n{\n    void foobar() {}\n\n    mixin([\"foo\", \"bar\"].join10506()~\";\");\n}\n\n/***************************************************/\n\nconst shared class C5107\n{\n    int x;\n}\n\nstatic assert(is(typeof(C5107.x) ==  const)); // okay\nstatic assert(is(typeof(C5107.x) == shared)); // fails!\n\n/***************************************************/\n\nimmutable struct S3598\n{\n    static void funkcja() { }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4211\n\n@safe struct X130\n{\n    void func() {  }\n}\n\n@safe class Y130\n{\n    void func() {  }\n}\n\n@safe void test130()\n{\n    X130 x;\n    x.func();\n    auto y = new Y130;\n    y.func();\n}\n\n/***************************************************/\n\ntemplate Return(alias fun)\n{\n    static if (is(typeof(fun) R == return)) alias R Return;\n}\n\ninterface I4217\n{\n    int  square(int  n);\n    real square(real n);\n}\nalias Return!( __traits(getOverloads, I4217, \"square\")[0] ) R4217;\nalias Return!( __traits(getOverloads, I4217, \"square\")[1] ) S4217;\n\nstatic assert(! is(R4217 == S4217));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5094\n\nvoid test131()\n{\n    S131 s;\n    int[] conv = s;\n}\n\nstruct S131\n{\n    @property int[] get() { return [1,2,3]; }\n    alias get this;\n}\n\n/***************************************************/\n\nstruct S7545\n{\n    uint id;\n    alias id this;\n}\n\nvoid test7545()\n{\n    auto id = 0 ? S7545() : -1;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5020\n\nvoid test132()\n{\n    S132 s;\n    if (!s) {}\n}\n\nstruct S132\n{\n    bool cond;\n    alias cond this;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5343\n\nstruct Tuple5343(Specs...)\n{\n    Specs[0] field;\n}\n\nstruct S5343(E)\n{\n    immutable E x;\n}\nenum A5343{a,b,c}\nalias Tuple5343!(A5343) TA5343;\nalias S5343!(A5343) SA5343;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5365\n\ninterface IFactory\n{\n    void foo();\n}\n\nclass A133\n{\n    protected static class Factory : IFactory\n    {\n        void foo()\n        {\n        }\n    }\n\n    this()\n    {\n        _factory = createFactory();\n    }\n\n    protected IFactory createFactory()\n    {\n        return new Factory;\n    }\n\n    private IFactory _factory;\n    @property final IFactory factory()\n    {\n        return _factory;\n    }\n\n    alias factory this;\n}\n\nvoid test133()\n{\n\n    IFactory f = new A133;\n    f.foo(); // segfault\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5365\n\nclass B134\n{\n}\n\nclass A134\n{\n\n    B134 _b;\n\n    this()\n    {\n        _b = new B134;\n    }\n\n    B134 b()\n    {\n        return _b;\n    }\n\n    alias b this;\n}\n\nvoid test134()\n{\n\n    auto a = new A134;\n    B134 b = a; // b is null\n    assert(a._b is b); // fails\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5025\n\nstruct S135 {\n  void delegate() d;\n}\n\nvoid test135()\n{\n  shared S135[] s;\n  if (0)\n    s[0] = S135();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5545\n\nbool enforce136(bool value, lazy const(char)[] msg = null) {\n    if(!value) {\n        return false;\n    }\n\n    return value;\n}\n\nstruct Perm {\n    byte[3] perm;\n    ubyte i;\n\n    this(byte[] input) {\n        foreach(elem; input) {\n            enforce136(i < 3);\n            perm[i++] = elem;\n            printf(\"%d\\n\", i);  // Never gets incremented.  Stays at 0.\n        }\n    }\n}\n\nvoid test136() {\n    byte[] stuff = [0, 1, 2];\n    auto perm2 = Perm(stuff);\n    //writeln(perm2.perm);  // Prints [2, 0, 0]\n    assert(perm2.perm[] == [0, 1, 2]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4097\n\nvoid foo4097() { }\nalias typeof(&foo4097) T4097;\nstatic assert(is(T4097 X : X*) && is(X == function));\n\nstatic assert(!is(X));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5798\n\nvoid assign9(ref int lhs) pure {\n    lhs = 9;\n}\n\nvoid assign8(ref int rhs) pure {\n    rhs = 8;\n}\n\nint test137(){\n    int a=1,b=2;\n    assign8(b),assign9(a);\n    assert(a == 9);\n    assert(b == 8);   // <-- fail\n\n    assign9(b),assign8(a);\n    assert(a == 8);\n    assert(b == 9);   // <-- fail\n\n    return 0;\n}\n\n/***************************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=9366\nstatic assert(!is(typeof((void[]).init ~ cast(void)0)));\nstatic assert(!is(typeof(cast(void)0 ~ (void[]).init)));\n\n/***************************************************/\n\nstruct Size138\n{\n    union\n    {\n        struct\n        {\n            int width;\n            int height;\n        }\n\n        long size;\n    }\n}\n\nenum Size138 foo138 = {2 ,5};\n\nSize138 bar138 = foo138;\n\nvoid test138()\n{\n    assert(bar138.width == 2);\n    assert(bar138.height == 5);\n}\n\n/***************************************************/\n\nvoid test3822()\n{\n    import core.stdc.stdlib;\n    int i = 0;\n    void* ptr;\n    while(i++ != 2)\n    {\n        auto p = alloca(2);\n        assert(p != ptr);\n        ptr = p;\n    }\n}\n\n/***************************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=5939\n// https://issues.dlang.org/show_bug.cgi?id=5940\n\ntemplate map(fun...)\n{\n    auto map(double[] r)\n    {\n        struct Result\n        {\n            this(double[] input)\n            {\n            }\n        }\n\n        return Result(r);\n    }\n}\n\n\nvoid test139()\n{\n    double[] x;\n    alias typeof(map!\"a\"(x)) T;\n    T a = void;\n    auto b = map!\"a\"(x);\n    auto c = [map!\"a\"(x)];\n    T[3] d = void;\n}\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5966\n\nstring[] foo5966(string[] a)\n{\n    a[0] = a[0][0..$];\n    return a;\n}\n\nenum var5966 = foo5966([\"\"]);\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5975\n\nint foo5975(wstring replace)\n{\n  wstring value = \"\";\n  value ~= replace;\n  return 1;\n}\n\nenum X5975 = foo5975(\"X\"w);\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5965\n\ntemplate mapx(fun...) if (fun.length >= 1)\n{\n    int mapx(Range)(Range r)\n    {\n        return 1;\n    }\n}\n\nvoid test140()\n{\n   int foo(int i) { return i; }\n\n   int[] arr;\n   auto x = mapx!( (int a){return foo(a);} )(arr);\n}\n\n/***************************************************/\n\nvoid bug5976()\n{\n    int[] barr;\n    int * k;\n    foreach (ref b; barr)\n    {\n        scope(failure)\n            k = &b;\n        k = &b;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5771\n\nstruct S141\n{\n    this(A)(auto ref A a){}\n}\n\nvoid test141()\n{\n    S141 s = S141(10);\n}\n\n/***************************************************/\n\nclass test5498_A {}\nclass test5498_B : test5498_A {}\nclass test5498_C : test5498_A {}\n\nstatic assert(is(typeof([test5498_B.init, test5498_C.init]) == test5498_A[]));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3688\n\nstruct S142\n{\n    int v;\n    this(int n) pure { v = n; }\n    const bool opCast(T:bool)() { return true; }\n}\n\nvoid test142()\n{\n    if (int a = 1)\n        assert(a == 1);\n    else assert(0);\n\n    if (const int a = 2)\n        assert(a == 2);\n    else assert(0);\n\n    if (immutable int a = 3)\n        assert(a == 3);\n    else assert(0);\n\n    if (auto s = S142(10))\n        assert(s.v == 10);\n    else assert(0);\n\n    if (auto s = const(S142)(20))\n        assert(s.v == 20);\n    else assert(0);\n\n    if (auto s = immutable(S142)(30))\n        assert(s.v == 30);\n    else assert(0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6072\n\nstatic assert({\n    if (int x = 5) {}\n    return true;\n}());\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5959\n\nint n;\n\nvoid test143()\n{\n    ref int f(){ return n; }            // NG\n    f() = 1;\n    assert(n == 1);\n\n    nothrow ref int f1(){ return n; }    // OK\n    f1() = 2;\n    assert(n == 2);\n\n    auto ref int f2(){ return n; }       // OK\n    f2() = 3;\n    assert(n == 3);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6119\n\nvoid startsWith(alias pred) ()   if (is(typeof(pred('c', 'd')) : bool))\n{\n}\n\nvoid startsWith(alias pred) ()   if (is(typeof(pred('c', \"abc\")) : bool))\n{\n}\n\nvoid test144()\n{\n    startsWith!((a, b) { return a == b; })();\n}\n\n/***************************************************/\n\nvoid test145()\n{\n    import core.stdc.stdio;\n    printf(\"hello world 145\\n\");\n}\n\nvoid test146()\n{\n    test1();\n    static import core.stdc.stdio;\n    core.stdc.stdio.printf(\"hello world 146\\n\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5856\n\nstruct X147\n{\n    void f()       { printf(\"X.f mutable\\n\"); }\n    void f() const { printf(\"X.f const\\n\"); }\n\n    void g()()       { printf(\"X.g mutable\\n\"); }\n    void g()() const { printf(\"X.g const\\n\"); }\n\n    void opOpAssign(string op)(int n)       { printf(\"X+= mutable\\n\"); }\n    void opOpAssign(string op)(int n) const { printf(\"X+= const\\n\"); }\n}\n\nvoid test147()\n{\n    X147 xm;\n    xm.f();     // prints \"X.f mutable\"\n    xm.g();     // prints \"X.g mutable\"\n    xm += 10;   // should print \"X+= mutable\" (1)\n\n    const(X147) xc;\n    xc.f();     // prints \"X.f const\"\n    xc.g();     // prints \"X.g const\"\n    xc += 10;   // should print \"X+= const\" (2)\n}\n\n\n/***************************************************/\n\nvoid test3559()\n{\n    static class A\n    {\n        int foo(int a)   { return 0; }\n        int foo(float a) { return 1; }\n\n        int bar(float a) { return 1; }\n        int bar(int a) { return 0; }\n    }\n\n    static class B : A\n    {\n        override int foo(float a) { return 2; }\n        alias A.foo foo;\n\n        alias A.bar bar;\n        override int bar(float a) { return 2; }\n    }\n\n    {\n        auto x = new A;\n        auto f1 = cast(int delegate(int))&x.foo;\n        auto f2 = cast(int delegate(float))&x.foo;\n        int delegate(int) f3 = &x.foo;\n        int delegate(float) f4 = &x.foo;\n\n        assert(f1(0) == 0);\n        assert(f2(0) == 1);\n        assert(f3(0) == 0);\n        assert(f4(0) == 1);\n    }\n\n    {\n        auto x = new B;\n        auto f1 = cast(int delegate(int))&x.foo;\n        auto f2 = cast(int delegate(float))&x.foo;\n        int delegate(int) f3 = &x.foo;\n        int delegate(float) f4 = &x.foo;\n\n        assert(f1(0) == 0);\n        assert(f2(0) == 2);\n        assert(f3(0) == 0);\n        assert(f4(0) == 2);\n    }\n\n    {\n        auto x = new A;\n        auto f1 = cast(int delegate(int))&x.bar;\n        auto f2 = cast(int delegate(float))&x.bar;\n        int delegate(int) f3 = &x.bar;\n        int delegate(float) f4 = &x.bar;\n\n        assert(f1(0) == 0);\n        assert(f2(0) == 1);\n        assert(f3(0) == 0);\n        assert(f4(0) == 1);\n    }\n\n    {\n        auto x = new B;\n        auto f1 = cast(int delegate(int))&x.bar;\n        auto f2 = cast(int delegate(float))&x.bar;\n        int delegate(int) f3 = &x.bar;\n        int delegate(float) f4 = &x.bar;\n\n        assert(f1(0) == 0);\n        assert(f2(0) == 2);\n        assert(f3(0) == 0);\n        assert(f4(0) == 2);\n    }\n}\n\n/***************************************************/\n\nextern(C++)\nclass C13182\n{\n}\n\nvoid test13182()\n{\n    scope C13182 c = new C13182();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5897\n\nstruct A148{ int n; }\nstruct B148{\n    int n, m;\n    this(A148 a){ n = a.n, m = a.n*2; }\n}\n\nstruct C148{\n    int n, m;\n    static C148 opCall(A148 a)\n    {\n        C148 b;\n        b.n = a.n, b.m = a.n*2;\n        return b;\n    }\n}\n\nvoid test148()\n{\n    auto a = A148(10);\n    auto b = cast(B148)a;\n    assert(b.n == 10 && b.m == 20);\n    auto c = cast(C148)a;\n    assert(c.n == 10 && c.m == 20);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4969\n\nclass MyException : Exception\n{\n    this()\n    {\n        super(\"An exception!\");\n    }\n}\n\nvoid throwAway()\n{\n    throw new MyException;\n}\n\nvoid cantthrow() nothrow\n{\n    try\n        throwAway();\n    catch(MyException me)\n        assert(0);\n    catch(Exception e)\n        assert(0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2356\n\nvoid test2356()\n{\n    int[3] x = [1,2,3];\n    printf(\"x[] = [%d %d %d]\\n\", x[0], x[1], x[2]);\n    assert(x[0] == 1 && x[1] == 2 && x[2] == 3);\n\n    struct S\n    {\n        static int pblit;\n        int n;\n        this(this) { ++pblit; printf(\"postblit: %d\\n\", n); }\n    }\n    S s2 = S(2);\n    S[3] s = [S(1), s2, S(3)];\n    assert(s[0].n == 1 && s[1].n == 2 && s[2].n == 3);\n    printf(\"s[].n = [%d %d %d]\\n\", s[0].n, s[1].n, s[2].n);\n    assert(S.pblit == 1);\n\n    ubyte[1024] v;\n    v = typeof(v).init;\n    printf(\"v[] = [%d %d %d, ..., %d]\\n\", v[0], v[1], v[2], v[$-1]);\n    foreach (ref a; v) assert(a == 0);\n\n    int n = 5;\n    int[3] y = [n, n, n];\n    printf(\"y[] = [%d %d %d]\\n\", y[0], y[1], y[2]);\n    assert(y[0] == 5 && y[1] == 5 && y[2] == 5);\n\n    S[3] z = [s2, s2, s2];\n    assert(z[0].n == 2 && z[1].n == 2 && z[2].n == 2);\n    printf(\"z[].n = [%d %d %d]\\n\", z[0].n, z[1].n, z[2].n);\n    assert(S.pblit == 1 + 3);\n\n    int[0] nsa0 = [];\n    void[0] vsa0 = [];\n\n    void foo(T)(T){}\n    foo(vsa0);\n\n    ref int[0] bar() { static int[1] sa; return *cast(int[0]*)&sa; }\n    bar() = [];\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13652\n\nvoid test13652()\n{\n    // reduced case\n    uint[9][5] arr =\n        [[0, 0, 0,  0, 1, 5,  8, 0, 7],\n         [0, 3, 8,  0, 2, 0,  0, 6, 0],\n         [0, 0, 7,  0, 6, 8,  9, 4, 0],\n         [0, 0, 0,  0, 0, 1,  2, 9, 0],\n         [9, 7, 0,  0, 0, 0,  0, 8, 3]];\n    assert(arr[0][0] == 0 && arr[0][1] == 0 && arr[0][2] == 0 &&\n           arr[0][3] == 0 && arr[0][4] == 1 && arr[0][5] == 5 &&\n           arr[0][6] == 8 && arr[0][7] == 0 && arr[0][8] == 7);\n    assert(arr[1][0] == 0 && arr[1][1] == 3 && arr[1][2] == 8 &&\n           arr[1][3] == 0 && arr[1][4] == 2 && arr[1][5] == 0 &&\n           arr[1][6] == 0 && arr[1][7] == 6 && arr[1][8] == 0);\n    assert(arr[2][0] == 0 && arr[2][1] == 0 && arr[2][2] == 7 &&\n           arr[2][3] == 0 && arr[2][4] == 6 && arr[2][5] == 8 &&\n           arr[2][6] == 9 && arr[2][7] == 4 && arr[2][8] == 0);\n    assert(arr[3][0] == 0 && arr[3][1] == 0 && arr[3][2] == 0 &&\n           arr[3][3] == 0 && arr[3][4] == 0 && arr[3][5] == 1 &&\n           arr[3][6] == 2 && arr[3][7] == 9 && arr[3][8] == 0);\n    assert(arr[4][0] == 9 && arr[4][1] == 7 && arr[4][2] == 0 &&\n           arr[4][3] == 0 && arr[4][4] == 0 && arr[4][5] == 0 &&\n           arr[4][6] == 0 && arr[4][7] == 8 && arr[4][8] == 3);\n\n    // original case\n    uint[9][9] tbl =\n        [[0, 0, 0,  0, 1, 5,  8, 0, 7],\n         [0, 3, 8,  0, 2, 0,  0, 6, 0],\n         [0, 0, 7,  0, 6, 8,  9, 4, 0],\n         [0, 0, 0,  0, 0, 1,  2, 9, 0],\n         [9, 7, 0,  0, 0, 0,  0, 8, 3],\n         [0, 2, 1,  6, 0, 0,  0, 0, 0],\n         [0, 6, 9,  5, 4, 0,  3, 0, 0],\n         [0, 4, 0,  0, 8, 0,  6, 5, 0],\n         [2, 0, 5,  9, 3, 0,  0, 0, 0]];\n    assert(tbl[0][0] == 0 && tbl[0][1] == 0 && tbl[0][2] == 0 &&\n           tbl[0][3] == 0 && tbl[0][4] == 1 && tbl[0][5] == 5 &&\n           tbl[0][6] == 8 && tbl[0][7] == 0 && tbl[0][8] == 7);\n    assert(tbl[1][0] == 0 && tbl[1][1] == 3 && tbl[1][2] == 8 &&\n           tbl[1][3] == 0 && tbl[1][4] == 2 && tbl[1][5] == 0 &&\n           tbl[1][6] == 0 && tbl[1][7] == 6 && tbl[1][8] == 0);\n    assert(tbl[2][0] == 0 && tbl[2][1] == 0 && tbl[2][2] == 7 &&\n           tbl[2][3] == 0 && tbl[2][4] == 6 && tbl[2][5] == 8 &&\n           tbl[2][6] == 9 && tbl[2][7] == 4 && tbl[2][8] == 0);\n    assert(tbl[3][0] == 0 && tbl[3][1] == 0 && tbl[3][2] == 0 &&\n           tbl[3][3] == 0 && tbl[3][4] == 0 && tbl[3][5] == 1 &&\n           tbl[3][6] == 2 && tbl[3][7] == 9 && tbl[3][8] == 0);\n    assert(tbl[4][0] == 9 && tbl[4][1] == 7 && tbl[4][2] == 0 &&\n           tbl[4][3] == 0 && tbl[4][4] == 0 && tbl[4][5] == 0 &&\n           tbl[4][6] == 0 && tbl[4][7] == 8 && tbl[4][8] == 3);\n    assert(tbl[5][0] == 0 && tbl[5][1] == 2 && tbl[5][2] == 1 &&\n           tbl[5][3] == 6 && tbl[5][4] == 0 && tbl[5][5] == 0 &&\n           tbl[5][6] == 0 && tbl[5][7] == 0 && tbl[5][8] == 0);\n    assert(tbl[6][0] == 0 && tbl[6][1] == 6 && tbl[6][2] == 9 &&\n           tbl[6][3] == 5 && tbl[6][4] == 4 && tbl[6][5] == 0 &&\n           tbl[6][6] == 3 && tbl[6][7] == 0 && tbl[6][8] == 0);\n    assert(tbl[7][0] == 0 && tbl[7][1] == 4 && tbl[7][2] == 0 &&\n           tbl[7][3] == 0 && tbl[7][4] == 8 && tbl[7][5] == 0 &&\n           tbl[7][6] == 6 && tbl[7][7] == 5 && tbl[7][8] == 0);\n    assert(tbl[8][0] == 2 && tbl[8][1] == 0 && tbl[8][2] == 5 &&\n           tbl[8][3] == 9 && tbl[8][4] == 3 && tbl[8][5] == 0 &&\n           tbl[8][6] == 0 && tbl[8][6] == 0 && tbl[8][8] == 0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11238\n\nvoid test11238()\n{\n    int[2] m;\n    m[0] = 4,m[1] = 6;\n    //printf(\"%d,%d\\n\", m[0], m[1]);\n    assert(m[0] == 4 && m[1] == 6);\n\n    m = [m[1], m[0]];   // swap\n    assert(m[0] == 6 && m[1] == 4);\n    //printf(\"%d,%d\\n\", m[0], m[1]);\n\n    m = [m[1], m[0]];   // swap\n    //printf(\"%d,%d\\n\", m[0], m[1]);\n    assert(m[0] == 4 && m[1] == 6);\n}\n\n/***************************************************/\n\nvoid test11805()\n{\n    int i;\n\n    i = 47;\n    i = 1 && i;\n    assert(i == 1);\n    i = 0 || i;\n    assert(i == 1);\n}\n\n/***************************************************/\n\nclass A2540\n{\n    int a;\n    int foo() { return 0; }\n    alias int X;\n}\n\nclass B2540 : A2540\n{\n    int b;\n    override super.X foo() { return 1; }\n\n    alias this athis;\n    alias this.b thisb;\n    alias super.a supera;\n    alias super.foo superfoo;\n    alias this.foo thisfoo;\n}\n\nstruct X2540\n{\n    alias this athis;\n}\n\nvoid test2540()\n{\n    auto x = X2540.athis.init;\n    static assert(is(typeof(x) == X2540));\n\n    B2540 b = new B2540();\n\n    assert(&b.a == &b.supera);\n    assert(&b.b == &b.thisb);\n    assert(b.thisfoo() == 1);\n}\n\n/***************************************************/\n\nclass B14348\n{\n    int foo() { return 0; }\n}\n\nclass C14348 : B14348\n{\n    override int foo() { return 1; }\n\n    alias superfoo = typeof(super).foo;\n    alias thisfoo = typeof(this).foo;\n}\n\nB14348 test14348()\n{\n    alias foo = typeof(return).foo;  // currently doesn't work.\n    assert(&B14348.foo is &C14348.superfoo);\n    assert(&C14348.foo is &C14348.thisfoo);\n    return null;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7295\n\nstruct S7295\n{\n    int member;\n    @property ref int refCountedPayload() { return member; }\n    alias refCountedPayload this;\n}\n\nvoid foo7295(S)(immutable S t, int qq) pure { }\nvoid foo7295(S)(S s) pure { }\n\nvoid bar7295() pure\n{\n    S7295 b;\n    foo7295(b);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5659\n\nvoid test149()\n{\n    import std.traits;\n\n    char a;\n    immutable(char) b;\n\n    static assert(is(typeof(true ? a : b) == const(char)));\n    static assert(is(typeof([a, b][0]) == const(char)));\n\n    static assert(is(CommonType!(typeof(a), typeof(b)) == const(char)));\n}\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1373\n\nvoid func1373a(){}\n\nstatic assert(typeof(func1373a).stringof == \"void()\");\nstatic assert(typeof(func1373a).mangleof == \"FZv\");\nstatic assert(!__traits(compiles, typeof(func1373a).alignof));\nstatic assert(!__traits(compiles, typeof(func1373a).init));\nstatic assert(!__traits(compiles, typeof(func1373a).offsetof));\n\nvoid func1373b(int n){}\n\nstatic assert(typeof(func1373b).stringof == \"void(int n)\");\nstatic assert(typeof(func1373b).mangleof == \"FiZv\");\nstatic assert(!__traits(compiles, typeof(func1373b).alignof));\nstatic assert(!__traits(compiles, typeof(func1373b).init));\nstatic assert(!__traits(compiles, typeof(func1373b).offsetof));\n\n/***************************************************/\n\nvoid bar150(T)(T n) {  }\n\n@safe void test150()\n{\n    bar150(1);\n}\n\n/***************************************************/\n\nvoid test5785()\n{\n    static struct x { static int y; }\n    assert(x.y !is 1);\n    assert(x.y !in [1:0]);\n}\n\n/***************************************************/\n\nvoid bar151(T)(T n) {  }\n\nnothrow void test151()\n{\n    bar151(1);\n}\n\n/***************************************************/\n\n@property int coo() { return 1; }\n@property auto doo(int i) { return i; }\n\n@property int eoo() { return 1; }\n@property auto ref hoo(int i) { return i; }\n\n// https://issues.dlang.org/show_bug.cgi?id=3359\n\nint goo(int i) pure { return i; }\nauto ioo(int i) pure { return i; }\nauto ref boo(int i) pure nothrow { return i; }\n\nclass A152 {\n    auto hoo(int i) pure  { return i; }\n    const boo(int i) nothrow { return i; }\n    auto coo(int i) const { return i; }\n    auto doo(int i) immutable { return i; }\n    auto eoo(int i) shared { return i; }\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=4706\n\nstruct Foo152(T) {\n    @property auto ref front() {\n        return T.init;\n    }\n\n    @property void front(T num) {}\n}\n\nvoid test152() {\n    Foo152!int foo;\n    auto a = foo.front;\n    foo.front = 2;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6733\n\nvoid bug6733(int a, int b) pure nothrow { }\nvoid test6733() {\n   int z = 1;\n   bug6733(z++, z++);\n   assert(z==3);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3799\n\nvoid test153()\n{\n    void bar()\n    {\n    }\n\n    static assert(!__traits(isStaticFunction, bar));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3632\n\n\nvoid test154() {\n    float f;\n    assert(f is float.init);\n    double d;\n    assert(d is double.init);\n    real r;\n    assert(r is real.init);\n\n    assert(float.nan is float.nan);\n    assert(double.nan is double.nan);\n    assert(real.nan is real.nan);\n}\n\n/***************************************************/\n\nvoid test6545()\n{\n    static int[] func()\n    {\n        auto a = [1, 2, 3];\n        auto b = [2, 3, 4];\n        auto c = [3, 4, 5];\n\n        a[] = b[] + c[];\n\n        return a;\n    }\n\n    auto a = func();\n    enum b = func();\n    assert(a == b);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3147\n\n\nvoid test155()\n{\n    byte b = 1;\n    short s;\n    int i;\n    long l;\n\n    s = b + b;\n    b = s % b;\n    s = s >> b;\n    b = 1;\n    b = i % b;\n    b = b >> i;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2486\n\nvoid test2486()\n{\n    void foo(ref int[] arr) {}\n\n    int[] arr = [1,2,3];\n    foo(arr);   //OK\n    static assert(!__traits(compiles, foo(arr[1..2]))); // should be NG\n\n    struct S\n    {\n        int[] a;\n        auto ref opSlice(){ return a[]; }  // line 4\n    }\n    S s;\n    s[];\n    // opSlice should return rvalue\n    static assert(is(typeof(&S.opSlice) == int[] function() pure nothrow @nogc @safe));\n    static assert(!__traits(compiles, foo(s[])));       // should be NG\n}\n\n/***************************************************/\n\nextern(C++) class C15080\n{\n    uint x = 1;\n    uint y = 2;\n}\n\n__gshared c15080 = new C15080();\n\nvoid test15080()\n{\n    assert(c15080.x == 1);\n    assert(c15080.y == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2521\n\nimmutable int val = 23;\nconst int val2 = 23;\n\nref immutable(int) func2521_() {\n    return val;\n}\nref immutable(int) func2521_2() {\n    return *&val;\n}\nref immutable(int) func2521_3() {\n    return func2521_;\n}\nref const(int) func2521_4() {\n    return val2;\n}\nref const(int) func2521_5() {\n    return val;\n}\nauto ref func2521_6() {\n    return val;\n}\nref func2521_7() {\n    return val;\n}\n\n/***************************************************/\n\nvoid test5554()\n{\n    class MA { }\n    class MB : MA { }\n    class MC : MB { }\n\n    class A { abstract MA foo(); }\n    interface I { MB foo(); }\n    class B : A\n    {\n        override MC foo() { return null; }\n    }\n    class C : B, I\n    {\n        override MC foo() { return null; }\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5962\n\nstruct S156\n{\n          auto g()(){ return 1; }\n    const auto g()(){ return 2; }\n}\n\nvoid test156()\n{\n    auto ms = S156();\n    assert(ms.g() == 1);\n    auto cs = const(S156)();\n    assert(cs.g() == 2);\n}\n\n/***************************************************/\n\nvoid test10724()\n{\n    const(char)* s = \"abc\"[0..$-1];\n    assert(s[2] == '\\0');\n}\n\n/***************************************************/\n\nvoid test6708(const ref int y)\n{\n    immutable int x;\n    test6708(x);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4258\n\nstruct Vec4258 {\n    Vec4258 opOpAssign(string Op)(auto ref Vec4258 other) if (Op == \"+\") {\n        return this;\n    }\n    Vec4258 opBinary(string Op:\"+\")(Vec4258 other) {\n        Vec4258 result;\n        return result += other;\n    }\n}\nvoid test4258() {\n    Vec4258 v;\n    v += Vec4258() + Vec4258(); // line 12\n}\n\n// regression fix test\n\nstruct Foo4258 {\n    // binary ++/--\n    int opPostInc()() if (false) { return 0; }\n\n    // binary 1st\n    int opAdd(R)(R rhs) if (false) { return 0; }\n    int opAdd_r(R)(R rhs) if (false) { return 0; }\n\n    // compare\n    int opCmp(R)(R rhs) if (false) { return 0; }\n\n    // binary-op assign\n    int opAddAssign(R)(R rhs) if (false) { return 0; }\n}\nstruct Bar4258 {\n    // binary commutive 1\n    int opAdd_r(R)(R rhs) if (false) { return 0; }\n\n    // binary-op assign\n    int opOpAssign(string op, R)(R rhs) if (false) { return 0; }\n}\nstruct Baz4258 {\n    // binary commutive 2\n    int opAdd(R)(R rhs) if (false) { return 0; }\n}\nstatic assert(!is(typeof(Foo4258.init++)));\nstatic assert(!is(typeof(Foo4258.init + 1)));\nstatic assert(!is(typeof(1 + Foo4258.init)));\nstatic assert(!is(typeof(Foo4258.init < Foo4258.init)));\nstatic assert(!is(typeof(Foo4258.init += 1)));\nstatic assert(!is(typeof(Bar4258.init + 1)));\nstatic assert(!is(typeof(Bar4258.init += 1)));\nstatic assert(!is(typeof(1 + Baz4258.init)));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4539\n\nvoid test4539()\n{\n    static assert(!__traits(compiles, \"hello\" = \"red\"));\n\n    void foo1(ref string s){}\n    void foo2(ref const char[10] s){}\n    void foo3(ref char[5] s){}\n\n    void foo4(ref const char[5] s)\n    {\n        assert(s[0] == 'h');\n        assert(s[4] == 'o');\n    }\n    void foo5(ref const ubyte[5] s)\n    {\n        assert(s[0] == 0xc3);\n        assert(s[4] == 0x61);\n    }\n\n    static assert(!__traits(compiles, foo1(\"hello\")));\n    static assert(!__traits(compiles, foo2(\"hello\")));\n    static assert(!__traits(compiles, foo3(\"hello\")));\n\n    // same as test68, 69, 70\n    foo4(\"hello\");\n    foo5(cast(ubyte[5])x\"c3fcd3d761\");\n\n    //import std.conv;\n    //static assert(!__traits(compiles, parse!int(\"10\") == 10));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1471\n\nvoid test1471()\n{\n    int n;\n    string bar = \"BOOM\"[n..$-1];\n    assert(bar == \"BOO\");\n}\n\n/***************************************************/\n\ndeprecated @disable int bug6389;\nstatic assert(!is(typeof(bug6389 = bug6389)));\n\n/***************************************************/\n\nvoid test10927()\n{\n    static assert( (1+2i) ^^ 3 == -11 - 2i );\n    auto a = (1+2i) ^^ 3;\n}\n\n/***************************************************/\n\nvoid test4963()\n{\n    struct Value {\n        byte a;\n    }\n    Value single()\n    {\n        return Value();\n    }\n\n    Value[] list;\n    auto x = single() ~ list;\n}\n\n/***************************************************/\n\npure int test4031()\n{\n    static const int x = 8;\n    return x;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5437\n\ntemplate EnumMembers5437(E)\n{\n    template TypeTuple(T...){ alias T TypeTuple; }\n\n    alias TypeTuple!(\"A\", \"B\") EnumMembers5437;\n}\ntemplate IntValue5437()\n{\n    int IntValue5437 = 10;\n}\n\nvoid test5437()\n{\n    enum Foo { A, B }\n    alias EnumMembers5437!Foo members;      // OK\n    enum n1 = members.length;               // OK\n    enum n2 = (EnumMembers5437!Foo).length; // NG, type -> symbol\n\n    enum s1 = IntValue5437!().sizeof;       // OK\n    enum s2 = (IntValue5437!()).sizeof;     // NG, type -> expression\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1962\n\n\nvoid test1962()\n{\n    class C { abstract void x(); }\n    assert(C.classinfo.create() is null);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6228\n\n\nvoid test6228()\n{\n    const(int)* ptr;\n    const(int)  temp;\n    auto x = (*ptr) ^^ temp;\n}\n\n/***************************************************/\n\nint test7544()\n{\n    try { throw new Exception(\"\"); }\n    catch (Exception e) static assert(1);\n    return 1;\n}\n\nstatic assert(test7544());\n\n/***************************************************/\n\nstruct S6230 {\n    int p;\n    int q() const pure {\n        return p;\n    }\n    void r() pure {\n        p = 231;\n    }\n}\nclass C6230 {\n    int p;\n    int q() const pure {\n        return p;\n    }\n    void r() pure {\n        p = 552;\n    }\n}\nint q6230(ref const S6230 s) pure {    // <-- Currently OK\n    return s.p;\n}\nint q6230(ref const C6230 c) pure {    // <-- Currently OK\n    return c.p;\n}\nvoid r6230(ref S6230 s) pure {\n    s.p = 244;\n}\nvoid r6230(ref C6230 c) pure {\n    c.p = 156;\n}\nbool test6230pure() pure {\n    auto s = S6230(4);\n    assert(s.p == 4);\n    assert(q6230(s) == 4);\n    assert(s.q == 4);\n\n    auto c = new C6230;\n    c.p = 6;\n    assert(q6230(c) == 6);\n    assert(c.q == 6);\n\n    r6230(s);\n    assert(s.p == 244);\n    s.r();\n    assert(s.p == 231);\n\n    r6230(c);\n    assert(c.p == 156);\n    c.r();\n    assert(c.p == 552);\n\n    return true;\n}\nvoid test6230() {\n    assert(test6230pure());\n}\n\n/***************************************************/\n\nvoid test6264()\n{\n    struct S { auto opSlice() { return this; } }\n    int[] a;\n    S s;\n    static assert(!is(typeof(a[] = s[])));\n    int*[] b;\n    static assert(is(typeof(b[] = [new immutable(int)])));\n    char[] c = new char[](5);\n    c[] = \"hello\";\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5046\n\nvoid test5046()\n{\n    auto va = S5046!(\"\", int)();\n    auto vb = makeS5046!(\"\", int)();\n}\n\nstruct S5046(alias p, T)\n{\n    T s;\n    T fun() { return s; }   // (10)\n}\n\nS5046!(p, T) makeS5046(alias p, T)()\n{\n    return typeof(return)();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6335\n\nstruct S6335\n{\n    const int value;\n    this()(int n){ value = n; }\n}\nvoid test6335()\n{\n    S6335 s = S6335(10);\n}\n\n/***************************************************/\n\nstruct S6295(int N) {\n    int[N] x;\n    const nothrow pure @safe f() { return x.length; }\n}\n\nvoid test6295() {\n    auto bar(T: S6295!(N), int N)(T x) {\n        return x.f();\n    }\n    S6295!4 x;\n    assert(bar(x) == 4);\n}\n\n/***************************************************/\n\ntemplate TT4536(T...) { alias T TT4536; }\n\nvoid test4536()\n{\n    auto x = TT4536!(int, long, [1, 2]).init;\n    assert(x[0] is int.init);\n    assert(x[1] is long.init);\n    assert(x[2] is [1, 2].init);\n}\n\n/***************************************************/\n\nstruct S6284 {\n    int a;\n}\nclass C6284 {\n    int a;\n}\npure int bug6284a() {\n    S6284 s = {4};\n    auto b = s.a;   // ok\n    with (s) {\n        b += a;     // should be ok.\n    }\n    return b;\n}\npure int bug6284b() {\n    auto s = new S6284;\n    s.a = 4;\n    auto b = s.a;\n    with (*s) {\n        b += a;\n    }\n    return b;\n}\npure int bug6284c() {\n    auto s = new C6284;\n    s.a = 4;\n    auto b = s.a;\n    with (s) {\n        b += a;\n    }\n    return b;\n}\nvoid test6284() {\n    assert(bug6284a() == 8);\n    assert(bug6284b() == 8);\n    assert(bug6284c() == 8);\n}\n\n/***************************************************/\n\nclass C6293 {\n    C6293 token;\n}\nvoid f6293(in C6293[] a) pure {\n    auto x0 = a[0].token;\n    assert(x0 is a[0].token.token.token);\n    assert(x0 is (&x0).token);\n    auto p1 = &x0 + 1;\n    assert(x0 is (p1 - 1).token);\n    int c = 0;\n    assert(x0 is a[c].token);\n}\nvoid test6293() {\n    auto x = new C6293;\n    x.token = x;\n    f6293([x]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3733\n\nclass C3733\n{\n    int foo()        { return 1; }\n    int foo() shared { return 2; }\n\n    int bar()        { return foo(); }\n}\nvoid test3733()\n{\n    auto c = new C3733();\n    assert(c.bar() == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4392\n\nclass C4392\n{\n    int foo() const { return 1; }\n    int foo()       { return 2; }\n\n    int bar() const { return foo(); }\n}\nvoid test4392()\n{\n    auto c = new C4392();\n    assert(c.bar() == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6220\n\nvoid test6220() {\n    struct Foobar { real x; real y; real z;}\n    switch(\"x\") {\n        foreach(i,member; __traits(allMembers, Foobar)) {\n            case member : break;\n        }\n    default : break;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5799\n\nvoid test5799()\n{\n    int a;\n    int *u = &(a ? a : (a ? a : a));\n    assert(u == &a);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6529\n\nenum Foo6529 : char { A='a' }\nref const(Foo6529) func6529(const(Foo6529)[] arr){ return arr[0]; }\n\n/***************************************************/\n\nvoid test783()\n{\n    const arr = [ 1,2,3 ];\n    const i = 2;\n    auto jhk = new int[arr[i]]; // \"need size of rightmost array, not type arr[i]\"\n}\n\n/***************************************************/\n\ntemplate X157(alias x)\n{\n    alias x X157;\n}\n\ntemplate Parent(alias foo)\n{\n    alias X157!(__traits(parent, foo)) Parent;\n}\n\ntemplate ParameterTypeTuple(alias foo)\n{\n    static if (is(typeof(foo) P == function))\n        alias P ParameterTypeTuple;\n    else\n        static assert(0, \"argument has no parameters\");\n}\n\ntemplate Mfp(alias foo)\n{\n    auto Mfp = function(Parent!foo self, ParameterTypeTuple!foo i) { return self.foo(i); };\n}\n\nclass C157 {\n int a = 3;\n int foo(int i, int y) { return i + a + y; }\n}\n\nvoid test157()\n{\n    auto c = new C157();\n    auto mfp = Mfp!(C157.foo);\n    auto i = mfp(c, 1, 7);\n    assert(i == 11);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6473\n\nstruct Eins6473\n{\n    ~this() {}\n}\n\nstruct Zwei6473\n{\n    void build(Eins6473 devices = Eins6473())\n    {\n    }\n}\n\nvoid build(Eins6473 devices = Eins6473())\n{}\n\nvoid test6473()\n{\n    void build(Eins6473 devices = Eins6473())\n    {}\n}\n\n/***************************************************/\n\nuint rol11417(uint n)(in uint x)\n{\n    return x << n | x >> 32 - n;\n}\n\nuint ror11417(uint n)(in uint x)\n{\n    return x >> n | x << 32 - n;\n}\n\nvoid test11417()\n{\n    assert(rol11417!1(0x8000_0000) == 0x1);\n    assert(ror11417!1(0x1) == 0x8000_0000);\n}\n\n/***************************************************/\n\nvoid test6578()\n{\n    static struct Foo\n    {\n        this(int x) pure {}\n    }\n    auto f1 = new const(Foo)(1);\n    auto f2 = new immutable(Foo)(1);\n    auto f3 = new shared(Foo)(1);\n    auto f4 = const(Foo)(1);\n    auto f5 = immutable(Foo)(1);\n    auto f6 = shared(Foo)(1);\n    static assert(is(typeof(f1) == const(Foo)*));\n    static assert(is(typeof(f2) == immutable(Foo)*));\n    static assert(is(typeof(f3) == shared(Foo)*));\n    static assert(is(typeof(f4) == const(Foo)));\n    static assert(is(typeof(f5) == immutable(Foo)));\n    static assert(is(typeof(f6) == shared(Foo)));\n\n    static struct Bar\n    {\n        this(int x) const pure {}\n    }\n    auto g1 = new const(Bar)(1);\n    auto g2 = new immutable(Bar)(1);\n    auto g3 = new shared(Bar)(1);\n    auto g4 = const(Bar)(1);\n    auto g5 = immutable(Bar)(1);\n    auto g6 = shared(Bar)(1);\n    static assert(is(typeof(g1) == const(Bar)*));\n    static assert(is(typeof(g2) == immutable(Bar)*));\n    static assert(is(typeof(g3) == shared(Bar)*));\n    static assert(is(typeof(g4) == const(Bar)));\n    static assert(is(typeof(g5) == immutable(Bar)));\n    static assert(is(typeof(g6) == shared(Bar)));\n\n    static struct Baz\n    {\n        this()(int x) const pure {}\n    }\n    auto h1 = new const(Baz)(1);\n    auto h2 = new immutable(Baz)(1);\n    auto h3 = new shared(const(Baz))(1);\n    auto h4 = const(Baz)(1);\n    auto h5 = immutable(Baz)(1);\n    auto h6 = shared(const(Baz))(1);\n    static assert(is(typeof(h1) == const(Baz)*));\n    static assert(is(typeof(h2) == immutable(Baz)*));\n    static assert(is(typeof(h3) == shared(const(Baz))*));\n    static assert(is(typeof(h4) == const(Baz)));\n    static assert(is(typeof(h5) == immutable(Baz)));\n    static assert(is(typeof(h6) == shared(const(Baz))));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6630\n\nvoid test6630()\n{\n    static class B {}\n\n    static class A\n    {\n        this() { b = new B(); }\n        B b;\n        alias b this;\n    }\n\n    void fun(A a)\n    {\n        a = null;\n        assert(a is null);\n    }\n\n    auto a = new A;\n    assert(a.b !is null);\n    fun(a);\n    assert(a !is null);\n    assert(a.b !is null);\n}\n\n/***************************************************/\n\nint i199 = 1;\n\nvoid test199()\n{\n    label:\n    {\n        int i199 = 2;\n    }\n    assert(i199 == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6690\n\nT useLazy6690(T)(lazy T val)\n{\n    return val;\n    // val is converted to delegate call, but it is typed as int delegate() - not @safe!\n}\nvoid test6690() @safe\n{\n    useLazy6690(0);\n    // Error: safe function 'test6690' cannot call system function 'useLazy6690'\n}\n\n/***************************************************/\n\ntemplate Hoge6691()\n{\n    immutable static int[int] dict;\n    immutable static int value;\n\n    static this()\n    {\n        dict = [1:1, 2:2];\n        value = 10;\n    }\n}\nalias Hoge6691!() H6691;\n\n/***************************************************/\n\nvoid test10626()\n{\n    double[2] v, x;\n    struct Y { double u; }\n    double z;\n    Y y;\n    double[2] r = v[] * x[0];\n    //double[2] s = v[] * z++;\n    //double[2] t = v[] * z--;\n    double[2] a = v[] * ++z;\n    double[2] b = v[] * --z;\n    double[2] c = v[] * y.u;\n    x[] = 3;\n    double[2] d = v[] * x[0];\n    double[2] e = v[] * (v[] ~ z)[0];\n}\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2953\n\ntemplate Tuple2953(T...)\n{\n    alias T Tuple2953;\n}\ntemplate Range2953(int b)\n{\n    alias Tuple2953!(1) Range2953;\n}\nvoid foo2953()()\n{\n    Tuple2953!(int, int) args;\n    foreach( x ; Range2953!(args.length) ){ }\n}\nvoid test2953()\n{\n    foo2953!()();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2997\n\nabstract class B2997 { void foo(); }\ninterface I2997 { void bar(); }\nabstract class C2997 : B2997, I2997 {}\n//pragma(msg, __traits(allMembers, C).stringof);\n\nvoid test2997()\n{\n    enum ObjectMembers = [\"toString\",\"toHash\",\"opCmp\",\"opEquals\",\"Monitor\",\"factory\"];\n\n    static assert([__traits(allMembers, C2997)] == [\"foo\"] ~ ObjectMembers ~ [\"bar\"]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6596\n\nextern (C) int function() pfunc6596;\nextern (C) int cfunc6596(){ return 0; }\nstatic assert(typeof(pfunc6596).stringof == \"extern (C) int function()\");\nstatic assert(typeof(cfunc6596).stringof == \"extern (C) int()\");\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4423\n\nstruct S4423\n{\n    this(string phrase, int num)\n    {\n        this.phrase = phrase;\n        this.num = num;\n    }\n\n    int opCmp(const ref S4423 rhs)\n    {\n        if (phrase < rhs.phrase)\n            return -1;\n        else if (phrase > rhs.phrase)\n            return 1;\n\n        if (num < rhs.num)\n            return -1;\n        else if (num > rhs.num)\n            return 1;\n\n        return 0;\n    }\n\n    string phrase;\n    int    num;\n}\n\nenum E4423 : S4423\n{\n    a = S4423(\"hello\", 1),\n    b = S4423(\"goodbye\", 45),\n    c = S4423(\"world\", 22),\n};\n\nvoid test4423()\n{\n    E4423 e;\n    assert(e.phrase == \"hello\");\n\n    e = E4423.b;\n    assert(e.phrase == \"goodbye\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=4647\n\ninterface Timer\n{\n    final int run() { printf(\"Timer.run()\\n\"); fun(); return 1; };\n    int fun();\n}\n\ninterface Application\n{\n    final int run() { printf(\"Application.run()\\n\"); fun(); return 2; };\n    int fun();\n}\n\nclass TimedApp : Timer, Application\n{\n    int funCalls;\n    override int fun()\n    {\n        printf(\"TimedApp.fun()\\n\");\n        funCalls++;\n        return 2;\n    }\n}\n\nclass SubTimedApp : TimedApp\n{\n    int subFunCalls;\n\n    override int fun()\n    {\n        printf(\"SubTimedApp.fun()\\n\");\n        subFunCalls++;\n        return 1;\n    }\n}\n\nvoid test4647()\n{\n    //Test access to TimedApps base interfaces\n    auto app = new TimedApp();\n    assert((cast(Application)app).run() == 2);\n    assert((cast(Timer)app).run() == 1);\n    assert(app.Timer.run() == 1); // error, no Timer property\n    assert(app.Application.run() == 2); // error, no Application property\n    assert(app.run() == 1);             // This would call Timer.run() if the two calls\n                                        // above were commented out\n    assert(app.funCalls == 5);\n\n    assert(app.TimedApp.fun() == 2);\n    assert(app.funCalls == 6);\n\n    //Test direct access to SubTimedApp interfaces\n    auto app2 = new SubTimedApp();\n    assert((cast(Application)app2).run() == 2);\n    assert((cast(Timer)app2).run() == 1);\n    assert(app2.Application.run() == 2);\n    assert(app2.Timer.run() == 1);\n    assert(app2.funCalls == 0);\n    assert(app2.subFunCalls == 4);\n\n    assert(app2.fun() == 1);\n    assert(app2.SubTimedApp.fun() == 1);\n    assert(app2.funCalls == 0);\n    assert(app2.subFunCalls == 6);\n\n    //Test access to SubTimedApp interfaces via TimedApp\n    auto app3 = new SubTimedApp();\n    (cast(Timer)cast(TimedApp)app3).run();\n    app3.TimedApp.Timer.run();\n    assert((cast(Application)cast(TimedApp)app3).run() == 2);\n    assert((cast(Timer)cast(TimedApp)app3).run() == 1);\n    assert(app3.TimedApp.Application.run() == 2);\n    assert(app3.TimedApp.Timer.run() == 1);\n    assert(app3.funCalls == 0);\n    assert(app3.subFunCalls == 6);\n}\n\n/***************************************************/\n\ntemplate T1064(E...) { alias E T1064; }\n\nint[] var1064 = [ T1064!(T1064!(T1064!(1, 2), T1064!(), T1064!(3)), T1064!(4, T1064!(T1064!(T1064!(T1064!(5)))), T1064!(T1064!(T1064!(T1064!())))),6) ];\n\nvoid test1064()\n{\n    assert(var1064 == [1,2,3,4,5,6]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5696\n\ntemplate Seq5696(T...){ alias T Seq5696; }\ntemplate Pred5696(T) { alias T Pred5696; }  // TOKtemplate\ntemplate Scope5696(int n){ template X(T) { alias T X; } }   // TOKimport\nT foo5696(T)(T x) { return x; }\nvoid test5696()\n{\n    foreach (pred; Seq5696!(Pred5696, Pred5696))\n    {\n        static assert(is(pred!int == int));\n    }\n\n    foreach (scop; Seq5696!(Scope5696!0, Scope5696!1))\n    {\n        static assert(is(scop.X!int == int));\n    }\n\n    alias Seq5696!(foo5696, foo5696) funcs;\n    assert(funcs[0](0) == 0);\n    assert(funcs[1](1) == 1);\n    foreach (i, fn; funcs)\n    {\n        assert(fn(i) == i);\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5933\n\nint dummyfunc5933();\nalias typeof(dummyfunc5933) FuncType5933;\n\nstruct S5933a { auto x() { return 0; } }\nstatic assert(is(typeof(&S5933a.init.x) == int delegate() pure nothrow @nogc @safe));\n\nstruct S5933b { auto x() { return 0; } }\n//static assert(is(typeof(S5933b.init.x) == FuncType5933));\n\nstruct S5933c { auto x() { return 0; } }\nstatic assert(is(typeof(&S5933c.x) == int function()));\n\nstruct S5933d { auto x() { return 0; } }\nstatic assert(is(typeof(S5933d.x) == FuncType5933));\n\n\nclass C5933a { auto x() { return 0; } }\nstatic assert(is(typeof(&(new C5933b()).x) == int delegate()));\n\nclass C5933b { auto x() { return 0; } }\n//static assert(is(typeof((new C5933b()).x) == FuncType5933));\n\nclass C5933c { auto x() { return 0; } }\nstatic assert(is(typeof(&C5933c.x) == int function()));\n\nclass C5933d { auto x() { return 0; } }\nstatic assert(is(typeof(C5933d.x) == FuncType5933));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6084\n\ntemplate TypeTuple6084(T...){ alias T TypeTuple6084; }\nvoid test6084()\n{\n    int foo(int x)() { return x; }\n    foreach(i; TypeTuple6084!(0))\n        foo!(i);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6763\n\ntemplate TypeTuple6763(TList...)\n{\n    alias TList TypeTuple6763;\n}\n\nalias TypeTuple6763!(int) T6763;\n\nvoid f6763(      T6763) { } ///\nvoid c6763(const T6763) { } ///T now is (const int)\nvoid r6763(ref   T6763) { } ///T now is(ref const int)\nvoid i6763(in    T6763) { } ///Uncomment to get an Assertion failure in 'mtype.c'\nvoid o6763(out   T6763) { } ///ditto\n\nvoid test6763()\n{\n    int n;\n\n    f6763(0);   //With D2: Error: function main.f ((ref const const(int) _param_0)) is not callable using argument types (int)\n    c6763(0);\n    r6763(n);   static assert(!__traits(compiles, r6763(0)));\n    i6763(0);\n    o6763(n);   static assert(!__traits(compiles, o6763(0)));\n\n    // https://issues.dlang.org/show_bug.cgi?id=6755\n    static assert(typeof(f6763).stringof == \"void(int _param_0)\");\n    static assert(typeof(c6763).stringof == \"void(const(int) _param_0)\");\n    static assert(typeof(r6763).stringof == \"void(ref int _param_0)\");\n    static assert(typeof(i6763).stringof == \"void(const(int) _param_0)\");\n    static assert(typeof(o6763).stringof == \"void(out int _param_0)\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6695\n\nstruct X6695\n{\n    void mfunc()\n    {\n        static assert(is(typeof(this) == X6695));\n    }\n    void cfunc() const\n    {\n        static assert(is(typeof(this) == const(X6695)));\n    }\n    void ifunc() immutable\n    {\n        static assert(is(typeof(this) == immutable(X6695)));\n    }\n    void sfunc() shared\n    {\n        static assert(is(typeof(this) == shared(X6695)));\n    }\n    void scfunc() shared const\n    {\n        static assert(is(typeof(this) == shared(const(X6695))));\n    }\n    void wfunc() inout\n    {\n        static assert(is(typeof(this) == inout(X6695)));\n    }\n    void swfunc() shared inout\n    {\n        static assert(is(typeof(this) == shared(inout(X6695))));\n    }\n\n    static assert(is(typeof(this) == X6695));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6087\n\ntemplate True6087(T)\n{\n    immutable True6087 = true;\n}\nstruct Foo6087\n{\n    static assert( True6087!(typeof(this)) );\n}\n\nstruct Bar6087\n{\n    static assert( is(typeof(this) == Bar6087) );\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6848\n\nclass Foo6848 {}\n\nclass Bar6848 : Foo6848\n{\n    void func() immutable\n    {\n        static assert(is(typeof(this) == immutable(Bar6848)));  // immutable(Bar6848)\n        auto t = this;\n        static assert(is(typeof(t) == immutable(Bar6848)));     // immutable(Bar6848)\n\n        static assert(is(typeof(super) == immutable(Foo6848))); // Foo6848 instead of immutable(Foo6848)\n        auto s = super;\n        static assert(is(typeof(s) == immutable(Foo6848)));     // Foo6848 instead of immutable(Foo6848)\n    }\n}\n\n/***************************************************/\n\nversion(none)\n{\n    cent issue785;\n    ucent issue785;\n}\n\nstatic assert(is(cent) && is(ucent) || !is(cent) && !is(ucent));\nstatic if (is(cent))\n  static assert(__traits(compiles, { cent x; }));\nelse\n  static assert(!__traits(compiles, { cent x; }));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6847\n\ntemplate True6847(T)\n{\n    immutable True6847 = true;\n}\nclass Foo6847\n{}\n\nclass Bar6847 : Foo6847\n{\n    static assert( True6847!(typeof(super)) );\n    static assert( is(typeof(super) == Foo6847) );\n}\n\n/***************************************************/\n// http://d.puremagic.com/issues/show_bug.cgi?id=6488\n\nstruct TickDuration\n{\n    template to(T) if (__traits(isIntegral,T))\n    {\n        const T to()\n        {\n            return 1;\n        }\n    }\n\n    template to(T) if (__traits(isFloating,T))\n    {\n        const T to()\n        {\n            return 0;\n        }\n    }\n\n    const long seconds()\n    {\n        return to!(long)();\n    }\n\n}\n\nvoid test6488()\n{\n    TickDuration d;\n    d.seconds();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6565\n\nvoid foo6565(out int[2][2] m) {}\n\nvoid test6565()\n{\n    int[2][2] mat = [[1, 2], [3, 4]];\n    foo6565(mat);\n    assert(mat == [[0, 0], [0, 0]]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6836\n\ntemplate map6836(fun...) if (fun.length >= 1)\n{\n    auto map6836(Range)(Range r)\n    {\n    }\n}\nvoid test6836()\n{\n    [1].map6836!\"a\"();\n}\n\n/***************************************************/\n\nstring func12864() { return ['a', 'b', 'c']; }\n\nvoid test12864(string s)\n{\n    switch (s)\n    {\n    case func12864():\n        break;\n\n    default:\n        break;\n    }\n}\n\n/***************************************************/\n\nvoid test5448()\n{\n    int[int][] aaa = [[1: 2]];\n    int[string][] a2 = [[\"cc\":0], [\"DD\":10]];\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6837\n\nstruct Ref6837a(T)\n{\n    T storage;\n    alias storage this;\n}\n\nstruct Ref6837b(T)\n{\n    T storage;\n    @property ref T get(){ return storage; }\n    alias get this;\n}\n\nint front6837(int[] arr){ return arr[0]; }\n\nvoid popFront6837(ref int[] arr){ arr = arr[1..$]; }\n\nvoid test6837()\n{\n    assert([1,2,3].front6837 == 1);\n\n    auto r1 = Ref6837a!(int[])([1,2,3]);\n    assert(r1.front6837() == 1);    // ng\n    assert(r1.front6837 == 1);      // ok\n    r1.popFront6837();              // ng\n    r1.storage.popFront6837();      // ok\n\n    auto r2 = Ref6837b!(int[])([1,2,3]);\n    assert(r2.front6837() == 1);    // ng\n    assert(r2.front6837 == 1);      // ok\n    r2.popFront6837();              // ng\n    r2.get.popFront6837();          // ng\n    r2.get().popFront6837();        // ok\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6927\n\n@property int[] foo6927()\n{\n    return [1, 2];\n}\nint[] bar6927(int[] a)\n{\n    return a;\n}\nvoid test6927()\n{\n    bar6927(foo6927); // OK\n    foo6927.bar6927(); // line 9, Error\n}\n\n/***************************************************/\n\nstruct Foo6813(T)\n{\n    Foo6813 Bar()\n    {\n        return Foo6813(_indices.abc());\n    }\n\n    T _indices;\n}\n\nstruct SortedRange(alias pred)\n{\n    SortedRange abc()\n    {\n        return SortedRange();\n    }\n}\n\nvoid test6813() {\n    auto ind = SortedRange!({ })();\n    auto a = Foo6813!(typeof(ind))();\n}\n\n/***************************************************/\n\nstruct Interval6753{ int a,b; }\n@safe struct S6753\n{\n    int[] arr;\n    @trusted @property auto byInterval() const\n    {\n        return cast(const(Interval6753)[])arr;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6859\n\nclass Parent6859\n{\npublic:\n    bool isHage() const @property;\n\npublic:\n    abstract void fuga()\n    out\n    {\n        assert(isHage);\n    }\n    body { }\n}\n\nclass Child6859 : Parent6859\n{\n    override bool isHage() const @property\n    {\n        return true;\n    }\n    override void fuga()\n    {\n        //nop\n    }\n}\n\nvoid test6859()\n{\n    auto t = new Child6859;\n    t.fuga();\n    printf(\"done.\\n\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6910\n\ntemplate Test6910(alias i, B)\n{\n    void fn()\n    {\n        foreach(t; B.Types)\n        {\n            switch(i)\n            {\n                case 0://IndexOf!(t, B.Types):\n                {\n                    pragma(msg, __traits(allMembers, t));\n                    pragma(msg, __traits(hasMember, t, \"m\"));\n                    static assert(__traits(hasMember, t, \"m\")); // test\n                    break;\n                }\n                default: {}\n            }\n        }\n    }\n}\nvoid test6910()\n{\n    static struct Bag(S...)\n    {\n        alias S Types;\n    }\n    static struct A\n    {\n        int m;\n    }\n\n    int i;\n    alias Test6910!(i, Bag!(A)).fn func;\n}\n\n/***************************************************/\n\nvoid fun12503()\n{\n    string b = \"abc\";\n    try\n    {\n        try\n        {\n            b = null;\n            return;\n        }\n        catch(Throwable)\n        {\n        }\n    }\n    finally\n    {\n        assert(\"abc\" !is b);\n    }\n}\n\nvoid test12503()\n{\n    fun12503();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6902\n\nvoid test6902()\n{\n    static assert(is(typeof({\n        return int.init; // int, long, real, etc.\n    })));\n\n    int f() pure nothrow { assert(0); }\n    alias int T() pure nothrow @safe @nogc;\n    static if(is(typeof(&f) DT == delegate))\n    {\n        static assert(is(DT* == T*));  // ok\n\n        // Error: static assert  (is(pure nothrow int() == pure nothrow int())) is false\n        static assert(is(DT == T));\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6330\n\nstruct S6330\n{\n    void opAssign(S6330 s) @disable\n    {\n        assert(0);  // This fails.\n    }\n}\n\nvoid test6330()\n{\n    S6330 s;\n    S6330 s2;\n    static assert(!is(typeof({ s2 = s; })));\n}\n\n/***************************************************/\n\nstruct S8269\n{\n    bool dtor = false;\n    ~this()\n    {\n        dtor = true;\n    }\n}\n\nvoid test8269()\n{\n    with(S8269())\n    {\n        assert(!dtor);\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5311\n\nclass C5311\n{\n    private static int globalData;\n\n    void breaksPure() pure const\n    {\n        static assert(!__traits(compiles, { globalData++; }));      // SHOULD BE ERROR\n        static assert(!__traits(compiles, { C5311.globalData++; }));// SHOULD BE ERROR\n        static assert(!__traits(compiles, { this.globalData++; })); // SHOULD BE ERROR\n\n        static assert(!__traits(compiles, { int a = this.globalData; }));\n    }\n}\nstatic void breaksPure5311a(C5311 x) pure\n{\n    static assert(!__traits(compiles, { x.globalData++; }));        // SHOULD BE ERROR\n\n    static assert(!__traits(compiles, { int a = x.globalData; }));\n}\n\nstruct S5311\n{\n    private static int globalData;\n\n    void breaksPure() pure const\n    {\n        static assert(!__traits(compiles, { globalData++; }));      // SHOULD BE ERROR\n        static assert(!__traits(compiles, { S5311.globalData++; }));// SHOULD BE ERROR\n        static assert(!__traits(compiles, { this.globalData++; })); // SHOULD BE ERROR\n\n        static assert(!__traits(compiles, { int a = this.globalData; }));\n    }\n}\nstatic void breaksPure5311b(S5311 x) pure\n{\n    static assert(!__traits(compiles, { x.globalData++; }));        // SHOULD BE ERROR\n\n    static assert(!__traits(compiles, { int a = x.globalData; }));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6868\n\n@property bool empty6868(T)(in T[] a) @safe pure nothrow\n{\n    return !a.length;\n}\n\nvoid test6868()\n{\n    alias int[] Range;\n    static if (is(char[1 + Range.empty6868]))  // Line 9\n        enum bool isInfinite = true;\n\n    char[0] s;  // need\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=2856\n\nstruct foo2856    { static void opIndex(int i) { printf(\"foo\\n\"); } }\nstruct bar2856(T) { static void opIndex(int i) { printf(\"bar\\n\"); } }\n\nvoid test2856()\n{\n    foo2856[1];\n    bar2856!(float)[1];     // Error (# = __LINE__)\n    alias bar2856!(float) B;\n    B[1];                   // Okay\n}\n\n/***************************************************/\n\nvoid test13947()\n{\n    struct S {}\n    static assert(S.sizeof == 1);\n\n    S a;\n    S b;\n    *cast(ubyte*)&a = 1;\n    *cast(ubyte*)&b = 2;\n    assert(a == b);\n    assert(a is b);\n    assert(!(a != b));\n    assert(!(a !is b));\n    static assert(S() == S());\n    static assert(S() is S());\n    static assert(!(S() != S()));\n    static assert(!(S() !is S()));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3091\n\nvoid test3091(inout int = 0)\n{\n    struct Foo {}\n\n    auto  pm = new Foo;                 static assert(is( typeof( pm) ==              Foo  * ));\n    auto  pc = new const Foo;           static assert(is( typeof( pc) ==        const(Foo) * ));\n    auto  pw = new inout Foo;           static assert(is( typeof( pw) ==        inout(Foo) * ));\n    auto psm = new shared Foo;          static assert(is( typeof(psm) ==       shared(Foo) * ));\n    auto psc = new shared const Foo;    static assert(is( typeof(psc) == shared(const(Foo))* ));\n    auto psw = new shared inout Foo;    static assert(is( typeof(psw) == shared(inout(Foo))* ));\n    auto  pi = new immutable Foo;       static assert(is( typeof( pi) ==    immutable(Foo) * ));\n\n    auto  m = Foo();                    static assert(is( typeof( m) ==              Foo   ));\n    auto  c = const Foo();              static assert(is( typeof( c) ==        const(Foo)  ));\n    auto  w = inout Foo();              static assert(is( typeof( w) ==        inout(Foo)  ));\n    auto sm = shared Foo();             static assert(is( typeof(sm) ==       shared(Foo)  ));\n    auto sc = shared const Foo();       static assert(is( typeof(sc) == shared(const(Foo)) ));\n    auto sw = shared inout Foo();       static assert(is( typeof(sw) == shared(inout(Foo)) ));\n    auto  i = immutable Foo();          static assert(is( typeof( i) ==    immutable(Foo)  ));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6837\n\ntemplate Id6837(T)\n{\n    alias T Id6837;\n}\nstatic assert(is(Id6837!(shared const int) == shared const int));\nstatic assert(is(Id6837!(shared inout int) == shared inout int));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6056 fixup\n\ntemplate ParameterTypeTuple6056(func)\n{\n    static if (is(func Fptr : Fptr*) && is(Fptr P == function))\n        alias P ParameterTypeTuple6056;\n    else\n        static assert(0, \"argument has no parameters\");\n}\n\nextern(C) alias void function() fpw_t;\n\nalias void function(fpw_t fp) cb_t;\n\nvoid bar6056(ParameterTypeTuple6056!(cb_t) args) {\n      pragma (msg, \"TFunction1: \" ~ typeof(args[0]).stringof);\n}\n\nextern(C) void foo6056() { }\n\nvoid test6056()\n{\n    bar6056(&foo6056);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6356\n\nint f6356()(int a)\n{\n    return a*a;\n}\n\nalias f6356!() g6356;     // comment this out to eliminate the errors\n\npure nothrow @safe int i6356()\n{\n    return f6356(1);\n}\n\nvoid test6356()\n{\n    assert(i6356() == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7108\n\nstatic assert(!__traits(hasMember, int, \"x\"));\nstatic assert( __traits(hasMember, int, \"init\"));\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7073\n\nvoid test7073()\n{\n    string f(int[] arr...)\n    {\n        return \"\";\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7104\n\nvoid test7104()\n{\n    typeof(new class {}) c;\n    c = new typeof(c);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7150\n\nstruct A7150\n{\n    static int cnt;\n\n    this(T)(T thing, int i)\n    {\n        this(thing, i > 0); // Error: constructor call must be in a constructor\n        ++cnt;\n    }\n    this(T)(T thing, bool b)\n    {\n        ++cnt;\n    }\n}\n\nvoid test7150()\n{\n    auto a = A7150(5, 5); // Error: template instance constructtest.A.__ctor!(int) error instantiating\n    assert(A7150.cnt == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7159\n\nalias void delegate()  Void7159;\n\nclass HomeController7159 {\n    Void7159 foo() {\n        return cast(Void7159)&HomeController7159.displayDefault;\n    }\n    auto displayDefault() {\n        return 1;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7160\n\nclass HomeController {\n    static if (false) {\n        mixin(q{ int a; });\n    }\n    void foo() {\n        foreach (m; __traits(derivedMembers, HomeController)) {\n        }\n    }\n}\n\nvoid test7160()\n{}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7168\n\nvoid test7168()\n{\n    static class X\n    {\n        void foo(){}\n    }\n    static class Y : X\n    {\n        void bar(){}\n    }\n\n    enum ObjectMembers = [\"toString\",\"toHash\",\"opCmp\",\"opEquals\",\"Monitor\",\"factory\"];\n\n    static assert([__traits(allMembers, X)] == [\"foo\"]~ObjectMembers);          // pass\n    static assert([__traits(allMembers, Y)] == [\"bar\", \"foo\"]~ObjectMembers);   // fail\n    static assert([__traits(allMembers, Y)] != [\"bar\", \"foo\"]);                 // fail\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7170\n\nT to7170(T)(string x) { return 1; }\nvoid test7170()\n{\n//  auto i = to7170!int(\"1\");   // OK\n    auto j = \"1\".to7170!int();  // NG, Internal error: e2ir.c 683\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7196\n\nauto foo7196(int x){return x;}\nauto foo7196(double x){return x;}\n\nvoid test7196()\n{\n    auto x = (&foo7196)(1);   // ok\n    auto y = (&foo7196)(1.0); // fail\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7285\n\nint[2] spam7285()\n{\n    int[2] ab;\n    if (true)\n        return (true) ? ab : [0, 0]; // Error\n    else\n        return (true) ? [0, 0] : ab; // OK\n}\n\nvoid test7285()\n{\n    auto sa = spam7285();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14737\n\nvoid test14737()\n{\n    // compile-time\n    enum string[2] a1 = [\"d\", \"e\"];\n    enum b1x = [\"a\", \"b\", \"c\"] ~ a1;        // Tarray vs Tsarray\n    enum b1y = a1 ~ [\"a\", \"b\", \"c\"];        // Tsarray vs Tarray\n    static assert(is(typeof(b1x) == string[]));\n    static assert(is(typeof(b1y) == string[]));\n    static assert(b1x == [\"a\", \"b\", \"c\", \"d\", \"e\"]);\n    static assert(b1y == [\"d\", \"e\", \"a\", \"b\", \"c\"]);\n\n    // runtime\n    string[2] a2 = [\"d\", \"e\"];\n    auto b2x = [\"a\", \"b\", \"c\"] ~ a2;        // Tarray vs Tsarray\n    auto b2y = a2 ~ [\"a\", \"b\", \"c\"];        // Tsarray vs Tarray\n    static assert(is(typeof(b2x) == string[]));\n    static assert(is(typeof(b2y) == string[]));\n    assert(b2x == [\"a\", \"b\", \"c\", \"d\", \"e\"]);\n    assert(b2y == [\"d\", \"e\", \"a\", \"b\", \"c\"]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7321\n\nvoid test7321()\n{\n    static assert(is(typeof((){})==void function()pure nothrow @nogc @safe));         // ok\n    static assert(is(typeof((){return;})==void function()pure nothrow @nogc @safe));  // fail\n}\n\n/***************************************************/\n\nclass A158\n{\n    pure void foo1() { }\n    const void foo2() { }\n    nothrow void foo3() { }\n    @safe void foo4() { }\n}\n\nclass B158 : A158\n{\n    override void foo1() { }\n    override void foo2() const { }\n    override void foo3() { }\n    override void foo4() { }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9231\n\nclass B9231 { void foo() inout pure {} }\nclass D9231 : B9231 { override void foo() inout {} }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=3282\n\nclass Base3282\n{\n    string f()\n    {\n        return \"Base.f()\";\n    }\n}\nclass Derived3282 : Base3282\n{\n    override string f()\n    {\n        return \"Derived.f()\";\n    }\n  /*override*/ string f() const\n    {\n        return \"Derived.f() const\";\n    }\n}\n\nvoid test3282()\n{\n    auto x = new Base3282;\n    assert(x.f() == \"Base.f()\");\n    auto y = new Derived3282;\n    assert(y.f() == \"Derived.f()\");// calls \"Derived.f() const\", but it is expected that be called non-const.\n    auto z = new const(Derived3282);\n    assert(z.f() == \"Derived.f() const\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7534\n\nclass C7534\n{\n    int foo(){ return 1; }\n}\nclass D7534 : C7534\n{\n    override int foo(){ return 2; }\n  /*override*/ int foo() const { return 3; }\n    // Error: D.foo multiple overrides of same function\n}\nvoid test7534()\n{\n    C7534 mc = new C7534();\n    assert(mc.foo() == 1);\n\n    D7534 md = new D7534();\n    assert(md.foo() == 2);\n    mc = md;\n    assert(mc.foo() == 2);\n\n    const(D7534) cd = new const(D7534)();\n    assert(cd.foo() == 3);\n    md = cast()cd;\n    assert(md.foo() == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7534\n// return type covariance\n\nclass X7534 {}\nclass Y7534 : X7534\n{\n    int value; this(int n){ value = n; }\n}\n\nclass V7534\n{\n    X7534 foo(){ return new X7534(); }\n}\nclass W7534 : V7534\n{\n    override Y7534 foo(){ return new Y7534(1); }\n  /*override*/ Y7534 foo() const { return new Y7534(2); }\n}\n\nvoid test7534cov()\n{\n    auto mv = new V7534();\n    assert(typeid(mv.foo()) == typeid(X7534));\n\n    auto mw = new W7534();\n    assert(typeid(mw.foo()) == typeid(Y7534));\n    assert(mw.foo().value == 1);\n    mv = mw;\n    assert(typeid(mv.foo()) == typeid(Y7534));\n    assert((cast(Y7534)mv.foo()).value == 1);\n\n    auto cw = new const(W7534)();\n    assert(typeid(cw.foo()) == typeid(Y7534));\n    assert(cw.foo().value == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7562\n\nstatic struct MyInt\n{\n    private int value;\n    mixin ProxyOf!value;\n}\nmixin template ProxyOf(alias a)\n{\n    template X1(){}\n    template X2(){}\n    template X3(){}\n    template X4(){}\n    template X5(){}\n    template X6(){}\n    template X7(){}\n    template X8(){}\n    template X9(){}\n    template X10(){}\n\n    void test1(this X)(){}\n    void test2(this Y)(){}\n}\n\n/***************************************************/\n\nimport core.stdc.stdlib;\n\nvoid test13427(void* buffer = alloca(100))\n{\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7583\n\ntemplate Tup7583(E...) { alias E Tup7583; }\n\nstruct S7583\n{\n    Tup7583!(float, char) field;\n    alias field this;\n    this(int x) {    }\n}\n\nint bug7583() {\n    S7583[] arr;\n    arr ~= S7583(0);\n    return 1;\n}\n\nstatic assert (bug7583());\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7618\n\nvoid test7618(const int x = 1)\n{\n    int func(ref int x) { return 1; }\n    static assert(!__traits(compiles, func(x)));\n    // Error: function test.foo.func (ref int _param_0) is not callable using argument types (const(int))\n\n    int delegate(ref int) dg = (ref int x) => 1;\n    static assert(!__traits(compiles, dg(x)));\n    // --> no error, bad!\n\n    int function(ref int) fp = (ref int x) => 1;\n    static assert(!__traits(compiles, fp(x)));\n    // --> no error, bad!\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7621\n\nvoid test7621()\n{\n    enum uint N = 4u;\n    char[] A = \"hello\".dup;\n    uint[immutable char[4u]] dict;\n    dict[*cast(immutable char[4]*)(A[0 .. N].ptr)] = 0; // OK\n    dict[*cast(immutable char[N]*)(A[0 .. N].ptr)] = 0; // line 6, error\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7682\n\ntemplate ConstOf7682(T)\n{\n    alias const(T) ConstOf7682;\n}\nbool pointsTo7682(S)(ref const S source) @trusted pure nothrow\n{\n    return true;\n}\nvoid test7682()\n{\n    shared(ConstOf7682!(int[])) x;  // line A\n\n    struct S3 { int[10] a; }\n    shared(S3) sh3;\n    shared(int[]) sh3sub = sh3.a[];\n    assert(pointsTo7682(sh3sub));   // line B\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7735\n\nvoid a7735(void[][] data...)\n{\n    //writeln(data);\n    assert(data.length == 1);\n    b7735(data);\n}\n\nvoid b7735(void[][] data...)\n{\n    //writeln(data);\n    assert(data.length == 1);\n    c7735(data);\n}\n\nvoid c7735(void[][] data...)\n{\n    //writeln(data);\n    assert(data.length == 1);\n}\n\nvoid test7735()\n{\n    a7735([]);\n    a7735([]);\n}\n\n/***************************************************/\n\nstruct A7823 {\n    long a;\n    enum A7823 b = {0};\n}\n\nvoid test7823(A7823 a = A7823.b) { }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7871\n\nstruct Tuple7871\n{\n    string field;\n    alias field this;\n}\n\n//auto findSplitBefore(R1)(R1 haystack)\nauto findSplitBefore7871(string haystack)\n{\n    return Tuple7871(haystack);\n}\n\nvoid test7871()\n{\n    string line = `<bookmark href=\"https://stuff\">`;\n    auto a = findSplitBefore7871(line[0 .. $])[0];\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7906\n\nvoid test7906()\n{\n    static assert(!__traits(compiles, { enum s = [string.min]; }));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7907\n\ntemplate Id7907(E)\n{\n    alias E Id7907;\n}\ntemplate Id7907(alias E)\n{\n    alias E Id7907;\n}\n\nvoid test7907()\n{\n    static assert(!__traits(compiles, { alias Id7907!([string.min]) X; }));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=1175\n\nclass A1175\n{\n    class I1 { }\n}\n\nclass B1175 : A1175\n{\n    class I2 : I1 { }\n\n    I1 getI() { return new I2; }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7983\n\nclass A7983 {\n        void f() {\n                g7983(this);\n        }\n        unittest {\n        }\n}\n\nvoid g7983(T)(T a)\n{\n        foreach (name; __traits(allMembers, T)) {\n                pragma(msg, name);\n                static if (__traits(compiles, &__traits(getMember, a, name)))\n                {\n                }\n        }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8004\n\nvoid test8004()\n{\n    auto n = (int n = 10){ return n; }();\n    assert(n == 10);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8064\n\nvoid test8064()\n{\n    uint[5] arry;\n    ref uint acc(size_t i) {\n        return arry[i];\n    }\n    auto arryacc = &acc;\n    arryacc(3) = 5; // same error\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8220\n\nvoid foo8220(int){}\nstatic assert(!__traits(compiles, foo8220(typeof(0)))); // fail\n\n/***************************************************/\n\nvoid func8105(in ref int x) { }\n\nvoid test8105()\n{\n}\n\n/***************************************************/\n\ntemplate ParameterTypeTuple159(alias foo)\n{\n    static if (is(typeof(foo) P == __parameters))\n        alias P ParameterTypeTuple159;\n    else\n        static assert(0, \"argument has no parameters\");\n}\n\nint func159(int i, long j = 7) { return 3; }\n\nalias ParameterTypeTuple159!func159 PT;\n\nint bar159(PT) { return 4; }\n\npragma(msg, typeof(bar159));\npragma(msg, PT[1]);\n\nPT[1] boo159(PT[1..2] a) { return a[0]; }\n\nvoid test159()\n{\n    assert(bar159(1) == 4);\n    assert(boo159() == 7);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8283\n\nstruct Foo8283 {\n    this(long) { }\n}\n\nstruct FooContainer {\n    Foo8283 value;\n}\n\nauto get8283() {\n    union Buf { FooContainer result; }\n    Buf buf = {};\n    return buf.result;\n}\n\nvoid test8283() {\n    auto a = get8283();\n}\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8395\n\nstruct S8395\n{\n    int v;\n    this(T : long)(T x) { v = x * 2; }\n}\nvoid test8395()\n{\n    S8395 ms = 6;\n    assert(ms.v == 12);\n    const S8395 cs = 7;\n    assert(cs.v == 14);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=5749\n\nvoid test5749()\n{\n    static struct A\n    {\n        A foo(int x, int i)\n        {\n            //printf(\"this = %p, %d: i=%d\\n\", &this, x, i);\n            assert(i == x);\n            return this;\n        }\n        A bar(int x, ref int i)\n        {\n            //printf(\"this = %p, %d: i=%d\\n\", &this, x, i);\n            assert(i == x);\n            return this;\n        }\n    }\n\n    static     int inc1(ref int i) { return ++i; }\n    static ref int inc2(ref int i) { return ++i; }\n\n    int i;\n    A a;\n    //printf(\"&a = %p\\n\", &a);\n\n    i = 0;  a.foo(1, ++i).foo(2, ++i);          // OK <-- 2 1\n    i = 0;  a.bar(1, ++i).bar(2, ++i);          // OK <-- 2 2\n    i = 0;  a.foo(1, inc1(i)).foo(2, inc1(i));  // OK <-- 2 1\n    i = 0;  a.bar(1, inc2(i)).bar(2, inc2(i));  // OK <-- 2 2\n    //printf(\"\\n\");\n\n    A getVal() { static A a; return a; }\n    i = 0;  getVal().foo(1, ++i).foo(2, ++i);           // OK <-- 2 1\n    i = 0;  getVal().bar(1, ++i).bar(2, ++i);           // OK <-- 2 2\n    i = 0;  getVal().foo(1, inc1(i)).foo(2, inc1(i));   // OK <-- 2 1\n    i = 0;  getVal().bar(1, inc2(i)).bar(2, inc2(i));   // OK <-- 2 2\n    //printf(\"\\n\");\n\n    ref A getRef() { static A a; return a; }\n    i = 0;  getRef().foo(1, ++i).foo(2, ++i);           // OK <-- 2 1\n    i = 0;  getRef().bar(1, ++i).bar(2, ++i);           // OK <-- 2 2\n    i = 0;  getRef().foo(1, inc1(i)).foo(2, inc1(i));   // OK <-- 2 1\n    i = 0;  getRef().bar(1, inc2(i)).bar(2, inc2(i));   // OK <-- 2 2\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8396\n\nvoid test8396()\n{\n    static int g;\n\n    static extern(C) int bar(int a, int b)\n    {\n        //printf(\"a = %d, b = %d\\n\", a, b);\n        assert(b - a == 1);\n        return ++g;\n    }\n    static auto getFunc(int n)\n    {\n        assert(++g == n);\n        return &bar;\n    }\n\n    static struct Tuple { int _a, _b; }\n    static Tuple foo(int n)\n    {\n        assert(++g == n);\n        return Tuple(1, 2);\n    }\n\n    g = 0;\n    assert(bar(foo(1).tupleof) == 2);\n\n    g = 0;\n    assert(getFunc(1)(foo(2).tupleof) == 3);\n}\n\n/***************************************************/\n\nenum E160 : ubyte { jan = 1 }\n\nstruct D160\n{\n    short _year  = 1;\n    E160 _month = E160.jan;\n    ubyte _day   = 1;\n\n    this(int year, int month, int day) pure\n    {\n        _year  = cast(short)year;\n        _month = cast(E160)month;\n        _day   = cast(ubyte)day;\n    }\n}\n\nstruct T160\n{\n    ubyte _hour;\n    ubyte _minute;\n    ubyte _second;\n\n    this(int hour, int minute, int second = 0) pure\n    {\n        _hour   = cast(ubyte)hour;\n        _minute = cast(ubyte)minute;\n        _second = cast(ubyte)second;\n    }\n}\n\nstruct DT160\n{\n    D160 _date;\n    T160 _tod;\n\n    this(int year, int month, int day,\n         int hour = 0, int minute = 0, int second = 0) pure\n    {\n        _date = D160(year, month, day);\n        _tod = T160(hour, minute, second);\n    }\n}\n\nvoid foo160(DT160 dateTime)\n{\n    printf(\"test7 year %d, day %d\\n\", dateTime._date._year, dateTime._date._day);\n    assert(dateTime._date._year == 1999);\n    assert(dateTime._date._day == 6);\n}\n\nvoid test160()\n{\n    auto dateTime = DT160(1999, 7, 6, 12, 30, 33);\n    printf(\"test5 year %d, day %d\\n\", dateTime._date._year, dateTime._date._day);\n    assert(dateTime._date._year == 1999);\n    assert(dateTime._date._day == 6);\n    foo160(DT160(1999, 7, 6, 12, 30, 33));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8437\n\nclass Cgi8437\n{\n    struct PostParserState {\n        UploadedFile piece;\n    }\n\n    static struct UploadedFile {\n        string contentFilename;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8665\n\nauto foo8665a(bool val)\n{\n    if (val)\n        return 42;\n    else\n        return 1.5;\n}\nauto foo8665b(bool val)\n{\n    if (!val)\n        return 1.5;\n    else\n        return 42;\n}\n\nvoid test8665()\n{\n    static assert(is(typeof(foo8665a(true))  == double));\n    static assert(is(typeof(foo8665b(false)) == double));\n    assert(foo8665a(true) == 42); // assertion failure\n    assert(foo8665b(true) == 42); // assertion failure\n    assert(foo8665a(false) == 1.5);\n    assert(foo8665b(false) == 1.5);\n\n    static assert(foo8665a(true) == 42);\n    static assert(foo8665b(true) == 42);\n    static assert(foo8665a(false) == 1.5);\n    static assert(foo8665b(false) == 1.5);\n}\n\n/***************************************************/\n\nint foo8108(int, int);\n\nint foo8108(int a, int b)\n{\n    return a + b;\n}\n\nvoid test8108()\n{\n    foo8108(1,2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8360\n\nstruct Foo8360\n{\n    int value = 0;\n    int check = 1337;\n\n    this(int value)\n    {\n        assert(0);\n        this.value = value;\n    }\n\n    ~this()\n    {\n        assert(0);\n        assert(check == 1337);\n    }\n\n    string str()\n    {\n        assert(0);\n        return \"Foo\";\n    }\n}\n\nFoo8360 makeFoo8360()\n{\n    assert(0);\n    return Foo8360(2);\n}\n\nvoid test8360()\n{\n    size_t length = 0;\n\n    // The message part 'makeFoo().str()' should not be evaluated at all.\n    assert(length < 5, makeFoo8360().str());\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8361\n\nstruct Foo8361\n{\n    string bar = \"hello\";\n    ~this() {}\n}\n\nvoid test8361()\n{\n    assert(true, Foo8361().bar);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=6141\n// https://issues.dlang.org/show_bug.cgi?id=8526\n\nvoid test6141()\n{\n    static void takeADelegate(void delegate()) {}\n    auto items = new int[1];\n    items[0] = 17;\n    foreach (ref item; items)\n    {\n        // both asserts fail\n        assert(item == 17);\n        assert(&item == items.ptr);\n\n        takeADelegate({ auto x = &item; });\n    }\n\n    foreach(ref val; [3])\n    {\n        auto dg = { int j = val; };\n        assert(&val != null); // Assertion failure\n        assert(val == 3);\n    }\n\n    static void f(lazy int) {}\n    int i = 0;\n    auto dg = { int j = i; };\n    foreach(ref val; [3])\n    {\n        f(val);\n        assert(&val != null); // Assertion failure\n        assert(val == 3);\n    }\n}\n\nvoid test8526()\n{\n    static void call(void delegate() dg) { dg(); }\n\n    foreach (i, j; [0])\n    {\n        call({\n            assert(i == 0); // fails, i is corrupted\n        });\n    }\n\n    foreach (n; 0..1)\n    {\n        call({\n            assert(n == 0); // fails, n is corrupted\n        });\n    }\n}\n\n/***************************************************/\n\ntemplate ParameterTuple(alias func)\n{\n    static if(is(typeof(func) P == __parameters))\n        alias P ParameterTuple;\n    else\n        static assert(0);\n}\n\nint foo161(ref float y);\n\nvoid test161()\n{\n    alias PT = ParameterTuple!foo161;\n    auto x = __traits(identifier, PT);\n    assert(x == \"y\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=7175\n\nvoid test7175()\n{\n    struct S { ubyte[0] arr; }\n    S s;\n    assert(s.arr.ptr !is null);\n    assert(cast(void*)s.arr.ptr is cast(void*)&s);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8819\n\nvoid test8819()\n{\n    void[1] sa1 = (void[1]).init;\n    assert((cast(ubyte*)sa1.ptr)[0] == 0);\n\n    void[4] sa4 = [cast(ubyte)1,cast(ubyte)2,cast(ubyte)3,cast(ubyte)4];\n    assert((cast(ubyte*)sa4.ptr)[0] == 1);\n    assert((cast(ubyte*)sa4.ptr)[1] == 2);\n    assert((cast(ubyte*)sa4.ptr)[2] == 3);\n    assert((cast(ubyte*)sa4.ptr)[3] == 4);\n\n    auto sa22 = (void[2][2]).init;\n    static assert(sa22.sizeof == ubyte.sizeof * 2 * 2);\n    ubyte[4]* psa22 = cast(ubyte[4]*)sa22.ptr;\n    assert((*psa22)[0] == 0);\n    assert((*psa22)[1] == 0);\n    assert((*psa22)[2] == 0);\n    assert((*psa22)[3] == 0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8897\n\nclass C8897\n{\n    static mixin M8897!(int);\n    static class causesAnError  {}\n}\n\ntemplate M8897 ( E ) { }\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8917\n\nvoid test8917()\n{\n    int[3] a;\n    int[3] a2;\n    int[3] b = a[] + a2[];\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=8945\n\nstruct S8945 // or `class`, or `union`\n{\n    struct S0(T) { int i; }\n    struct S1(T) { this(int){} }\n}\n\nvoid test8945()\n{\n    auto cs0a = const S8945.S0!int();  // ok\n    auto cs0b = const S8945.S0!int(1); // ok\n    auto cs1  = const S8945.S1!int(1); // ok\n\n    auto s0a = S8945.S0!int();  // Error: struct S0 does not overload ()\n    auto s0b = S8945.S0!int(1); // Error: struct S0 does not overload ()\n    auto s1  = S8945.S1!int(1); // Error: struct S1 does not overload ()\n}\n\n/***************************************************/\n\nstruct S162\n{\n    static int generateMethodStubs( Class )()\n    {\n        int text;\n\n        foreach( m; __traits( allMembers, Class ) )\n        {\n            static if( is( typeof( mixin( m ) ) ) && is( typeof( mixin( m ) ) == function ) )\n            {\n                pragma(msg, __traits( getOverloads, Class, m ));\n            }\n        }\n\n        return text;\n    }\n\n    enum int ttt = generateMethodStubs!( S162 )();\n\n    float height();\n    int get( int );\n    int get( long );\n    void clear();\n\n    void draw( int );\n    void draw( long );\n}\n\n/***************************************************/\n\nvoid test163() {\n    static class C { int x; int y; }\n\n    immutable C c = new C();\n    shared C c2 = new C();\n    shared const C c3 = new C();\n\n    class D { int x; int y; }\n    immutable D d;\n    assert(!__traits(compiles, d = new D()));\n\n    static struct S { int x; int y; }\n\n    immutable S* s = new S();\n    shared S* s2 = new S();\n    shared const S* s3 = new S();\n\n    shared S* s4;\n    assert(__traits(compiles, s4 = new immutable(S)()));\n\n    struct T { int x; int y; }\n    immutable T* t;\n    assert(!__traits(compiles, t = new T()));\n\n    immutable int* pi = new int();\n    immutable void* pv = new int();\n\n    immutable int[] ai = new int[1];\n    immutable void[] av = new int[2];\n}\n\n/***************************************************/\nstruct S9000\n{ ubyte i = ubyte.max; }\n\nenum E9000 = S9000.init;\n\n/***************************************************/\n\nmixin template DefineCoreType(string type)\n{\n    struct Faulty\n    {\n        static int x;\n\n        static void instance()\n        {\n            x = 3;\n        }\n\n        X164!() xxx;\n    }\n}\n\nmixin DefineCoreType!(\"\");\n\n\nmixin template A164()\n{\n    static this()\n    {\n    }\n}\n\nstruct X164()\n{\n    mixin A164!();\n}\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9428\n\nvoid test9428()\n{\n    int[2][] items = [[1, 2]];\n    int[2] x = [3, 4];\n\n    auto r1 = items ~ [x];\n    assert(r1.length == 2);\n    assert(r1[0][0] == 1);\n    assert(r1[0][1] == 2);\n    assert(r1[1][0] == 3);\n    assert(r1[1][1] == 4);\n\n    auto r2 = items ~ x;\n    assert(r2.length == 2);\n    assert(r2[0][0] == 1);\n    assert(r2[0][1] == 2);\n    assert(r2[1][0] == 3);\n    assert(r2[1][1] == 4);\n\n    auto r3 = [x] ~ items;\n    assert(r3.length == 2);\n    assert(r3[0][0] == 3);\n    assert(r3[0][1] == 4);\n    assert(r3[1][0] == 1);\n    assert(r3[1][1] == 2);\n\n    auto r4 = x ~ items;\n    assert(r4.length == 2);\n    assert(r4[0][0] == 3);\n    assert(r4[0][1] == 4);\n    assert(r4[1][0] == 1);\n    assert(r4[1][1] == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9477\n\ntemplate Tuple9477(T...) { alias T Tuple9477; }\ntemplate Select9477(bool b, T, U) { static if (b) alias T Select9477; else alias U Select9477; }\n\nvoid test9477()\n{\n    static bool isEq (T1, T2)(T1 s1, T2 s2) { return s1 == s2; }\n    static bool isNeq(T1, T2)(T1 s1, T2 s2) { return s1 != s2; }\n\n    // Must be outside the loop due to http://d.puremagic.com/issues/show_bug.cgi?id=9748\n    int order;\n    // Must be outside the loop due to http://d.puremagic.com/issues/show_bug.cgi?id=9756\n    auto checkOrder(bool dyn, uint expected)()\n    {\n        assert(order==expected);\n        order++;\n        // Use temporary (\"v\") to work around http://d.puremagic.com/issues/show_bug.cgi?id=9402\n        auto v = cast(Select9477!(dyn, string, char[1]))\"a\";\n        return v;\n    }\n\n    foreach (b1; Tuple9477!(false, true))\n        foreach (b2; Tuple9477!(false, true))\n        {\n            version (D_PIC) {} else // Work around http://d.puremagic.com/issues/show_bug.cgi?id=9754\n            {\n                assert( isEq (cast(Select9477!(b1, string, char[0]))\"\" , cast(Select9477!(b2, string, char[0]))\"\"  ));\n                assert(!isNeq(cast(Select9477!(b1, string, char[0]))\"\" , cast(Select9477!(b2, string, char[0]))\"\"  ));\n\n                assert(!isEq (cast(Select9477!(b1, string, char[0]))\"\" , cast(Select9477!(b2, string, char[1]))\"a\" ));\n                assert( isNeq(cast(Select9477!(b1, string, char[0]))\"\" , cast(Select9477!(b2, string, char[1]))\"a\" ));\n            }\n\n            assert( isEq (cast(Select9477!(b1, string, char[1]))\"a\", cast(Select9477!(b2, string, char[1]))\"a\" ));\n            assert(!isNeq(cast(Select9477!(b1, string, char[1]))\"a\", cast(Select9477!(b2, string, char[1]))\"a\" ));\n\n            assert(!isEq (cast(Select9477!(b1, string, char[1]))\"a\", cast(Select9477!(b2, string, char[1]))\"b\" ));\n            assert( isNeq(cast(Select9477!(b1, string, char[1]))\"a\", cast(Select9477!(b2, string, char[1]))\"b\" ));\n\n            assert(!isEq (cast(Select9477!(b1, string, char[1]))\"a\", cast(Select9477!(b2, string, char[2]))\"aa\"));\n            assert( isNeq(cast(Select9477!(b1, string, char[1]))\"a\", cast(Select9477!(b2, string, char[2]))\"aa\"));\n\n            // Note: order of evaluation was not followed before this patch\n            // (thus, the test below will fail without the patch).\n            // Although the specification mentions that as implementation-defined behavior,\n            // I understand that this isn't by design, but rather an inconvenient aspect of DMD\n            // that has been moved to the specification.\n            order = 0;\n            bool result = checkOrder!(b1, 0)() == checkOrder!(b2, 1)();\n            assert(result);\n            assert(order == 2);\n        }\n\n    // need largest natural alignment to avoid unaligned access on\n    // some architectures, double in this case.\n    align(8) ubyte[64] a1, a2;\n    foreach (T; Tuple9477!(void, ubyte, ushort, uint, ulong, char, wchar, dchar, float, double))\n    {\n        auto s1 = cast(T[])(a1[]);\n        auto s2 = cast(T[])(a2[]);\n        assert(s1 == s2);\n        a2[$-1]++;\n        assert(s1 != s2);\n        assert(s1[0..$-1]==s2[0..$-1]);\n        a2[$-1]--;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9504\n\nstruct Bar9504\n{\n    template Abc(T)\n    {\n        T y;\n    }\n\n    enum size_t num = 123;\n\n    class Def {}\n}\n\ntemplate GetSym9504(alias sym) { static assert(__traits(isSame, sym, Bar9504.Abc)); }\ntemplate GetExp9504(size_t n) { static assert(n == Bar9504.num); }\ntemplate GetTyp9504(T) { static assert(is(T == Bar9504.Def)); }\n\nalias GetSym9504!(typeof(Bar9504.init).Abc) X9504; // NG\nalias GetExp9504!(typeof(Bar9504.init).num) Y9504; // NG\nalias GetTyp9504!(typeof(Bar9504.init).Def) Z9504;\n\nBar9504 test9504()\n{\n    alias GetSym9504!(typeof(return).Abc) V9504; // NG\n    alias GetExp9504!(typeof(return).num) W9504; // NG\n    alias GetTyp9504!(typeof(return).Def) X9504;\n    return Bar9504();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9538\n\nvoid test9538()\n{\n    void*[1] x;\n    auto ti = typeid(x.ptr);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9539\n\nvoid test9539()\n{\n    void f(int** ptr)\n    {\n        assert(**ptr == 10);\n    }\n    int* p = new int;\n    *p = 10;\n    int*[1] x = [p];\n    f(&x[0]);\n\n    int*[] arr = [null];\n    static assert(!__traits(compiles, p = arr));    // bad!\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9700\n\nmixin template Proxy9700(alias a)\n{\n    auto ref opOpAssign(string op, V)(V v) { return a += v; }  // NG\n  //auto ref opOpAssign(string op, V)(V v) { a += v; } // OK\n}\nstruct MyInt9700\n{\n    int value;\n    invariant() { assert(value >= 0); }\n    mixin Proxy9700!value;\n}\nvoid test9700()\n{\n    MyInt9700 a = { 2 };\n    a *= 3;   // object.Error: Access Violation\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9834\n\nstruct Event9834\n{\n    void delegate() dg;\n    void set(void delegate() h) pure { dg = h; }  // AV occurs\n    void call() { dg(); }\n}\nvoid test9834()\n{\n    Event9834 ev;\n    auto a = new class\n    {\n        Object o;\n        this()\n        {\n            o = new Object;\n            ev.set((){ o.toString(); });\n        }\n    };\n    ev.call();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9859\n\nvoid test9859(inout int[] arr)\n{\n    auto dg1 = { foreach (i, e; arr) { } };\n    dg1();\n\n    void foo() { auto v = arr; auto w = arr[0]; }\n    void bar(inout int i) { auto v = arr[i]; }\n\n    auto dg2 =\n    {\n        auto dg =\n        {\n            void foo(T)()\n            {\n                auto dg =\n                {\n                    auto dg =\n                    {\n                        auto v = arr;\n                    };\n                };\n            }\n            foo!int;\n        };\n    };\n\n    void qux(T)()\n    {\n        auto v = arr;\n        auto dg1 = { auto v = arr; };\n        auto dg2 =\n        {\n            auto dg =\n            {\n                auto v = arr;\n            };\n        };\n    }\n    qux!int;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9912\n\ntemplate TypeTuple9912(Stuff...)\n{\n    alias Stuff TypeTuple9912;\n}\n\nstruct S9912\n{\n    int i;\n    alias TypeTuple9912!i t;\n\n    void testA() {\n        auto x = t;\n    }\n\n    void testB() {\n        auto x = t;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9883\n\nstruct S9883\n{\n    @property size_t p9883(T)() { return 0; }\n}\n\n@property size_t p9883(T)() { return 0; }\n\nvoid test9883()\n{\n    S9883 s;\n    auto n1 = p9883!int; // OK\n    auto n2 = s.p9883!int; // OK\n    auto a1 = new int[p9883!int]; // Error: need size of rightmost array, not type p!(int)\n    auto a2 = new int[s.p9883!int]; // Error: no property 'p!(int)' for type 'S'\n}\n\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10091\n\nstruct S10091\n{\n    enum e = \"a\";\n}\n\nvoid test10091()\n{\n    auto arr = cast(ubyte[1]) S10091.e;\n}\n\n/***************************************************/\n\nvoid test12824()\n{\nlabel:\n    static if (0)\n    {\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=9130\n\nclass S9130 { void bar() { } }\n\nimport core.stdc.stdio : printf;\n\nstruct Function\n{\n    int[] ai = [1,2,3];\n}\n\n@property void meta(alias m)()\n{\n    static Function md;\n    printf(\"length = %d\\n\", md.ai.length);\n    printf(\"ptr = %p\\n\", md.ai.ptr);\n    md.ai[0] = 0;\n}\n\nvoid test9130()\n{\n    meta!(__traits(getOverloads, S9130, \"bar\")[0]);\n    meta!(S9130.bar);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10390\n\nclass C10390 { this() { this.c = this; } C10390 c; }\nconst c10390 = new C10390();\npragma(msg, c10390);\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10542\n\nclass B10542\n{\n    this() nothrow pure @safe { }\n}\n\nclass D10542 : B10542\n{\n}\n\nvoid test10542() nothrow pure @safe\n{\n    new D10542;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=10539\n\nvoid test10539()\n{\n    int[2][2] a;\n    int* p1 = a.ptr.ptr;    // OK <- error\n    int* p2 = (*a.ptr).ptr; // OK\n    assert(p1 is p2);\n}\n\n/***************************************************/\n\nstruct TimeOfDay\n{\n    ubyte h, m, s;\n}\n\n__gshared byte glob;\n\nstruct DateTime\n{\n    this(ubyte _d, ubyte _m, ubyte _y, TimeOfDay _tod = TimeOfDay.init)\n    {\n        d = _d;\n        m = _m;\n        y = _y;\n        tod = _tod;\n    }\n    TimeOfDay tod;\n    ubyte d, m, y;\n}\n\n\nvoid test10634()\n{\n    glob = 123;\n    DateTime date1 = DateTime(0, 0, 0);\n    DateTime date2;\n    assert(date1 == date2);\n}\n\n/***************************************************/\n\nimmutable(char)[4] bar7254(int i)\n{\n    if (i)\n    {\n        immutable(char)[4] r; return r;\n    }\n    else\n        return \"1234\";\n}\n\nvoid test7254()\n{\n    assert(bar7254(0) == \"1234\");\n}\n\n/***************************************************/\n\nstruct S11075() { int x = undefined_expr; }\n\nclass C11075() { int x = undefined_expr; }\n\ninterface I11075() { enum int x = undefined_expr; }\n\nvoid test11075()\n{\n    static assert(!is(typeof(S11075!().x)));\n    static assert(!is(typeof(S11075!().x)));\n\n    static assert(!is(typeof(C11075!().x)));\n    static assert(!is(typeof(C11075!().x)));\n\n    static assert(!is(typeof(I11075!().x)));\n    static assert(!is(typeof(I11075!().x)));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11181\n\nvoid test11181()\n{\n    auto a = [\"a\", \"b\"];\n\n    static assert(!is(typeof([a, \"x\"])));\n    static assert(!is(typeof(true ? a : \"x\")));\n\n    static assert(!is(typeof(true ? a[0 .. $] : \"x\")));\n    static assert(!is(typeof([a[0 .. $], \"x\"])));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11317\n\nvoid test11317()\n{\n    auto ref uint fun()\n    {\n        return 0;\n    }\n\n    void test(ref uint x) {}\n    static assert(!__traits(compiles, test(fun())));\n\n    assert(fun() == 0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=11888\n\nvoid test11888()\n{\n    static long val;\n\n    static ubyte* foo(size_t* len)\n    {\n        *len = val.sizeof;\n        return cast(ubyte*)&val;\n    }\n\n    size_t size;\n    ubyte[] t = foo(&size)[0..size];\n    assert(t.ptr is cast(void*)&val);\n    assert(t.length == 8);\n\n    // regression test\n    int[3] sa1 = [1,2,3];\n    int[1] sa2 = sa1[1..2]; // convert slice to Tsarray\n    assert(sa2.length == 1);\n    assert(sa2[0] == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12036\n\ntemplate T12036(alias a)\n{\n    string value;\n}\n\nstruct S12036\n{\n    auto fun() { }\n    mixin T12036!fun;\n}\n\nvoid test12036()\n{\n    S12036 s;\n    assert(s.value == \"\");\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12153\n\nvoid test12153()\n{\n    int[1] i, j;\n    bool b = true;\n    (b ? i : j)[] = [4];\n    assert(i == [4]);\n\n    // regression test\n    int[1][1] k, l;\n    (b ? k : l)[0..1][0..1] = [4];\n    assert(k == [[4]]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12498\n\nstring a12498()\n{\n    string b;\n    while (b) { }\n    for (; b; ) { }\n    return \"\";\n}\n\nvoid test12498()\n{\n    enum t = a12498();\n    string x = t;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12900\n\nstruct A12900\n{\n    char[1] b;\n}\n\nvoid test12900()\n{\n    A12900 c;\n    if (*c.b.ptr)\n        return;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12929\n\nstruct Foo12929\n{\n    union { }\n    int var;\n}\n\nstruct Bar12929\n{\n    struct { }\n    int var;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=12937\n\nvoid test12937()\n{\n    void[1] sa2 = cast(void[])[cast(ubyte)1];   // ICE!\n    assert((cast(ubyte[])sa2[])[0] == 1);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13154\n\nvoid test13154()\n{\n    int[3] ints      = [2   , 1   , 0   , 1   ][0..3];\n    float[3] floats0 = [2f  , 1f  , 0f  , 1f  ][0..3];\n    float[3] floats1 = [2.0 , 1.0 , 0.0 , 1.0 ][0..3];  // fails!\n    float[3] floats2 = [2.0f, 1.0f, 0.0f, 1.0f][0..3];\n    assert(ints == [2, 1, 0]);\n    assert(floats0 == [2, 1, 0]);\n    assert(floats1 == [2, 1, 0]); // fail!\n    assert(floats1 != [0, 0, 0]); // fail!\n    assert(floats2 == [2, 1, 0]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13437\n\nubyte[4] foo13437() { return [1,2,3,4]; }\n\nvoid test13437()\n{\n    auto n = cast(ubyte[4])foo13437()[];  // OK <- ICE: e2ir.c 4616\n    static assert(is(typeof(n) == ubyte[4]));\n    assert(n == [1,2,3,4]);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13472\n\nclass A13472\n{\n    int a;\n}\n\nvoid test13472()\n{\n    A13472[] test;\n    test.length = 4;\n    auto b = test[0..2] ~ null ~ test[2..$];\n    assert(b.length == 5);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13476\n\ntemplate ParameterTypeTuple13476(func...)\n{\n    static if (is(typeof(*func[0]) P == function))\n        alias ParameterTypeTuple13476 = P;\n    else\n        static assert(0, \"argument has no parameters\");\n}\n\nint flag13476;\n\n__gshared extern(C) void function(int) nothrow someFunc13476 = &Stub13476!someFunc13476;\n\nextern(C) auto Stub13476(alias func)(ParameterTypeTuple13476!func args)\n{\n    ++flag13476;\n    extern(C) void function(int) nothrow impl = (i) { };\n    return (func = impl)(args);\n}\n\n__gshared extern(C) void function(int) nothrow  someFunc13476Alt = &Stub13476Alt!someFunc13476AltP;\n__gshared extern(C) void function(int) nothrow* someFunc13476AltP = &someFunc13476Alt;\n\nextern(C) auto Stub13476Alt(alias func)(int args) nothrow\n{\n    ++flag13476;\n    extern(C) void function(int) nothrow impl = (i) {};\n    return (*func = impl)(args);\n}\n\nvoid test13476()\n{\n    assert(flag13476 == 0);\n\n    someFunc13476(42);\n    assert(flag13476 == 1);\n    someFunc13476(43);\n    assert(flag13476 == 1);\n\n    someFunc13476Alt(42);\n    assert(flag13476 == 2);\n    someFunc13476Alt(43);\n    assert(flag13476 == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14038\n\nstatic immutable ubyte[string] wordsAA14038;\nstatic this()\n{\n    wordsAA14038[\"zero\"] = 0;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14192\n\nvoid test14192()\n{\n    shared int[int] map;\n    map[1] = 1;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13720\n\nstruct FracSec13720\n{\n    this(int hnsecs) {}\n}\n\nstruct SysTime13720\n{\n    this(TimeOfDay13720 dateTime, FracSec13720 fracSec)\n    {\n    }\n}\n\nstruct TimeOfDay13720\n{\n    ~this() { }\n}\n\nvoid assertThrown13720(T)(lazy T) {}\n\nvoid test13720()\n{\n    assertThrown13720(SysTime13720(TimeOfDay13720.init, FracSec13720(-1)));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13952\n\nstruct Reg13952\n{\n    ubyte type;\n    ubyte regNo;\n    ushort size;\n}\n\nstruct Imm13952\n{\n    ulong imm;\n}\n\nstruct Opnd13952\n{\n    union\n    {\n        Reg13952 reg; // size == 4\n        Imm13952 imm; // size == 8\n    }\n    ubyte tag;\n\n    this(Reg13952 r) { reg = r; }\n}\n\nOpnd13952 opnd13952(Reg13952 reg)\n{\n    return Opnd13952(reg);\n}\n\nvoid test13952()\n{\n    Reg13952 reg;\n    auto op = opnd13952(reg);\n    auto buf = (cast(ubyte*)&op)[0 .. op.sizeof];\n    //debug\n    //{\n    //    import std.stdio;\n    //    writefln(\"op.reg = [%(%02x %)]\", (cast(ubyte*)&op.reg)[0 .. Reg13952.sizeof]);\n    //    writefln(\"op.imm = [%(%02x %)]\", (cast(ubyte*)&op.imm)[0 .. Imm13952.sizeof]);\n    //}\n    foreach (e; buf) assert(e == 0);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14165\n\nclass Foo14165\n{\n    @disable this();\n    this(int i) {}\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=13985\n\ninterface I13985\n{\n    void m1();\n    void m2();\n    void m3();\n\n    final void mf()\n    {\n        m3();\n    }\n}\n\nclass C13985 : I13985\n{\n    void m1() {}\n    void m2() {}\n    void m3() {}\n}\n\nclass D13985 : C13985\n{\n    void ml()\n    {\n        super.mf();\n    }\n}\n\nvoid test13985()\n{\n    auto d = new D13985();\n    d.ml();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14211\n\nextern(C++) // all derived classes won't have invariants\nclass B14211\n{\n    void func()\n    {\n    }\n}\n\nfinal class C14211 : B14211\n{\n}\n\nvoid test14211()\n{\n    auto c = new C14211();\n    *cast(void**)c = null;\n    c.func();   // called without vtbl access\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14552\n\ntemplate map14552(fun...)\n{\n    template AppliedReturnType(alias f)\n    {\n        alias typeof(f(0)) AppliedReturnType;\n    }\n\n    auto map14552(int[] r)\n    {\n        assert(!is(AppliedReturnType!fun));\n        return MapResult14552!fun();\n    }\n}\n\nstruct MapResult14552(alias fun)\n{\n    @property front()\n    {\n        fun(0);\n    }\n}\n\nclass Outer14552\n{\n    auto test()\n    {\n        [1].map14552!(j => new Inner);\n    }\n    class Inner {}\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=14853\n\nstruct Queue14853(T)\n{\n    struct Node\n    {\n        T mfPayload = T.init;\n        union\n        {\n                   typeof(this)*  mfPrev;\n            shared(typeof(this)*) mfShPrev;\n        }\n        union\n        {\n                   typeof(this)*  mfNext;\n            shared(typeof(this)*) mfShNext;\n        }\n    }\n\n    Node root;\n\n    void pfPut(T v, Node* r = null)\n    {\n        shared n = new Node(v);    // problem!\n    }\n}\n\nvoid test14853()\n{\n    auto b1 = new Queue14853!uint;\n}\n\n/********************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15045\n\nvoid test15045()\n{\n    void testName(T, bool r, string name)()\n    {\n        T t;\n\n        static assert(r ==          is(typeof(mixin(\"T.\"~name))));\n        static assert(r ==          is(typeof(mixin(\"t.\"~name))));\n        static assert(r == __traits(compiles, mixin(\"T.\"~name)));\n        static assert(r == __traits(compiles, mixin(\"t.\"~name)));\n        static assert(r == mixin(\"__traits(compiles, T.\"~name~\")\"));\n        static assert(r == mixin(\"__traits(compiles, t.\"~name~\")\"));\n\n        static assert(r ==                       __traits(hasMember, T, name) );\n        static assert(r ==                       __traits(hasMember, t, name) );\n        static assert(r == __traits(compiles,    __traits(getMember, T, name) ));\n        static assert(r == __traits(compiles,    __traits(getMember, t, name) ));\n        static assert(r == __traits(compiles, __traits(getOverloads, T, name) ));\n        static assert(r == __traits(compiles, __traits(getOverloads, t, name) ));\n    }\n    void test(T, bool r)()\n    {\n        testName!(T, r, \"__ctor\")();\n        testName!(T, r, \"__dtor\")();\n        testName!(T, r, \"__xdtor\")();\n        testName!(T, r, \"__postblit\")();\n        testName!(T, r, \"__xpostblit\")();\n    }\n\n    static struct X\n    {\n        this(int) {}\n        this(this) {}\n        ~this() {}\n    }\n\n    static struct S1\n    {\n        auto opDispatch(string name, A...)(A args) { }\n    }\n    static struct S2\n    {\n        X get() { return X(); };\n        alias get this;\n    }\n    static struct S3\n    {\n        X opDot() { return X(); };\n    }\n\n    test!(X, true)();\n    test!(S1, false)();\n    test!(S2, false)();\n    test!(S3, false)();\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15116\n\nalias TypeTuple15116(T...) = T;\n\ntemplate Mix15116()\n{\n    TypeTuple15116!(int, int) tup;\n}\n\nstruct S15116\n{\n    mixin Mix15116 mix;\n}\n\nvoid test15116()\n{\n    S15116 s;\n    auto x1 = s.tup;        // OK\n    auto x2 = s.mix.tup;    // OK <- NG\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15117\n\ntemplate Mix15117()\n{\n    int y = { typeof(this)* s; return s ? s.mix.y : 0; }();\n}\n\nstruct S15117\n{\n    int x = { typeof(this)* s; return s ? s.x : 0; }(); // OK\n\n    mixin Mix15117 mix;     // OK <- NG\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15126\n\nstruct Json15126\n{\n    ubyte[16] m_data;\n    int opDispatch(string prop)() const { return 0; }\n    int opDispatch(string prop)() { return 0; }\n}\n\ntemplate isCustomSerializable15126(T)\n{\n    enum isCustomSerializable15126 = T.init.toRepresentation();\n}\n\nalias bug15126 = isCustomSerializable15126!Json15126;\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15141\n\nclass A15141\n{\n    abstract void method();\n}\n\nclass B15141 : A15141 { }\n\nvoid test15141()\n{\n    auto a = Object.factory(__MODULE__ ~ \".A15141\");\n    assert(a is null);\n    auto b = Object.factory(__MODULE__ ~ \".B15141\");\n    assert(b is null); // OK <- oops\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15366\n\nenum E15366 : bool { A, B };\n\nstruct S15366\n{\n    void func1(E15366 e) {}\n\n    void func2(E15366 a, E15366 b)\n    {\n        func1(cast(E15366)(a && b));\n        func1(cast(E15366)(a || b));\n\n        auto x1 = cast(E15366)(a && b);\n        auto x2 = cast(E15366)(a || b);\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15369\n\nstruct MsgTable15369\n{\n    const(char)[] ident;\n    const(char)* name;\n};\n\nMsgTable15369[] msgTable15369 =\n[\n    { \"empty\", \"\" },\n];\n\nvoid test15369()\n{\n    auto id = msgTable15369[0].ident;\n    auto p = msgTable15369[0].name;\n\n    // a string literal \"\" should be zero-terminated\n    assert(*p == '\\0');\n}\n\nvoid test15638()\n{\n    class A {}\n    class B : A {}\n    class C : A {}\n\n    B b;\n    C c;\n    const(B) cb;\n    const(C) cc;\n    immutable(B) ib;\n    immutable(C) ic;\n\n    // Common type for const derived classes\n    auto constCommon = true ? cb : cc;\n    static assert(is(typeof(constCommon) == const(A)));\n\n    // Common type for immutable derived classes\n    auto immutableCommon = true ? ib : ic;\n    static assert(is(typeof(immutableCommon) == immutable(A)));\n\n    // Common type for mixed const/immutable derived classes\n    auto mixed1 = true ? cb : ic;\n    static assert(is(typeof(mixed1) == const(A)));\n    auto mixed2 = true ? ib : cc;\n    static assert(is(typeof(mixed2) == const(A)));\n\n    // Common type for mixed mutable/immutable derived classes\n    auto mixed3 = true ? b : ic;\n    static assert(is(typeof(mixed3) == const(A)));\n    auto mixed4 = true ? ib : c;\n    static assert(is(typeof(mixed4) == const(A)));\n\n    // Array literal type deduction\n    auto arr1 = [ new immutable(B), new C ];\n    auto arr2 = [ new B,            new const(C) ];\n    auto arr3 = [ new immutable(B), new immutable(C) ];\n    static assert(is(typeof(arr1) == const(A)[]));\n    static assert(is(typeof(arr2) == const(A)[]));\n    static assert(is(typeof(arr3) == immutable(A)[]));\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=15961\n\nstruct SliceOverIndexed15961(T)\n{\n    enum assignableIndex = T.init;\n}\n\nstruct Grapheme15961\n{\n    SliceOverIndexed15961!Grapheme15961 opSlice()\n    {\n        assert(0);\n    }\n\n    struct\n    {\n        ubyte* ptr_;\n    }\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16022\n\nbool test16022()\n{\n    enum Type { Colon, Comma }\n    Type type;\n    return type == Type.Comma;\n}\n\nbool test16022_structs()\n{\n    struct A\n    {\n        int i;\n        string s;\n    }\n\n    enum Type { Colon = A(0, \"zero\"), Comma = A(1, \"one\") }\n    Type type;\n    return type == Type.Comma;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16233\n\nenum valueConvertible(T1, T2) = blah;\n\nstruct Checked(T, Hook)\n{\n    bool opEquals(U)(Checked!(U, Hook) rhs)\n    {\n        alias R = typeof(payload + rhs.payload);\n        static if (valueConvertible!(T, R))\n        {\n        }\n        return false;\n    }\n}\n\nvoid test16233()\n{\n    Checked!(Checked!(int, void), void) x1;\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=16466\n\nvoid test16466()\n{\n    static struct S\n    {\n        real r;\n    }\n    real r;\n    printf(\"S.alignof: %x, r.alignof: %x\\n\", S.alignof, r.alignof);\n    assert(S.alignof == r.alignof);\n}\n\n/***************************************************/\n\n// https://issues.dlang.org/show_bug.cgi?id=16408\n\nchar[1] SDL_GetKeyName_buffer;\n\nconst(char)[] SDL_GetKeyName(char k)\n{\n    pragma(inline, false);\n    SDL_GetKeyName_buffer[0] = k;\n    return SDL_GetKeyName_buffer[];\n}\n\nvoid formattedWrite(const(char)[] strW, const(char)[] strA, const(char)[] strC)\n{\n    pragma(inline, false);\n\n    assert(strW == \"W\");\n    assert(strA == \"A\");\n    assert(strC == \"C\");\n}\n\nvoid test16408()\n{\n    pragma(inline, false);\n    formattedWrite(\n        SDL_GetKeyName('W').idup,\n        SDL_GetKeyName('A').idup,\n        SDL_GetKeyName('C').idup\n    );\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17349\n\nvoid test17349()\n{\n    static struct S\n    {\n        int bar(void delegate(ref int*)) { return 1; }\n        int bar(void delegate(ref const int*)) const { return 2; }\n    }\n\n    void dg1(ref int*) { }\n    void dg2(ref const int*) { }\n    S s;\n    int i;\n    i = s.bar(&dg1);\n    assert(i == 1);\n    i = s.bar(&dg2);\n    assert(i == 2);\n}\n\n/***************************************************/\n// https://issues.dlang.org/show_bug.cgi?id=17915\n\nvoid test17915()\n{\n    static class MyClass\n    {\n        S17915!MyClass m_member;\n    }\n}\n\nstruct S17915(T)\n{\n    T owner;\n}\n\nvoid test18232()\n{\n    static struct Canary\n    {\n        int x = 0x900D_900D;\n    }\n    union U\n    {\n        Canary method()\n        {\n            Canary c;\n            return c;\n        }\n    }\n    U u;\n    assert(u.method() == Canary.init);\n}\n\n/***************************************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n    test8();\n    test9();\n    test10();\n    test11();\n    test12();\n    test13();\n    test14();\n    test15();\n    test16();\n    test17();\n    test18();\n    test19();\n    test20();\n    test21();\n    test22();\n    test23();\n    test24();\n    test25();\n    test26();\n    test27();\n    test28();\n    test29();\n    test30();\n    test31();\n    test32();\n    test33();\n    test34();\n    test35();\n    test36();\n    test37();\n    test38();\n    test39();\n    test40();\n    test41();\n    test42();\n    test43();\n    test44();\n    test45();\n    test46();\n    test47();\n    test48();\n    test49();\n    test796();\n    test50();\n    test51();\n    test52();\n    test53();\n    test54();\n    test55();\n    test56();\n    test57();\n    test58();\n\n    test60();\n    test61();\n    test62();\n    test63();\n    test64();\n    test65();\n    test66();\n    test67();\n    test68();\n    test69();\n    test70();\n\n    test5785();\n    test72();\n    test73();\n    test74();\n    test75();\n    test76();\n    test77();\n    test78();\n    test79();\n    test80();\n    test81();\n    test82();\n    test83();\n    test3559();\n    test84();\n    test85();\n    test2006();\n    test8442();\n    test86();\n    test87();\n    test2486();\n    test5554();\n    test88();\n    test7545();\n    test89();\n    test90();\n    test91();\n    test92();\n    test4536();\n    test93();\n    test94();\n    test95();\n    test5403();\n    test96();\n    test97();\n    test98();\n    test99();\n    test100();\n    test101();\n\n    test103();\n    test104();\n    test105();\n    test3927();\n    test107();\n\n    test109();\n\n    test111();\n\n    test113();\n\n    test115();\n    test116();\n    test117();\n    test3822();\n    test6545();\n    test118();\n    test5081();\n\n    test120();\n    test10724();\n    test122();\n    test123();\n    test124();\n    test125();\n    test6763();\n\n    test127();\n    test128();\n    test1891();\n    test129();\n    test130();\n    test1064();\n    test131();\n    test132();\n    test133();\n    test134();\n    test135();\n    test136();\n    test137();\n    test138();\n    test1962();\n    test139();\n    test140();\n    test141();\n    test6317();\n    test142();\n    test143();\n    test144();\n    test145();\n    test146();\n    test147();\n    test6685();\n    test148();\n    test149();\n    test2356();\n    test13652();\n    test11238();\n    test2540();\n    test14348();\n    test150();\n    test151();\n    test152();\n    test153();\n    test154();\n    test155();\n    test156();\n    test658();\n    test4258();\n    test4539();\n    test4963();\n    test4031();\n    test5437();\n    test6230();\n    test6264();\n    test6284();\n    test6295();\n    test6293();\n    test5046();\n    test1471();\n    test6335();\n    test1687();\n    test6228();\n    test3733();\n    test4392();\n    test7942();\n    test6220();\n    test5799();\n    test157();\n    test6473();\n    test6630();\n    test6690();\n    test2953();\n    test2997();\n    test4423();\n    test4647();\n    test5696();\n    test6084();\n    test6488();\n    test6565();\n    test6836();\n    test6837();\n    test6927();\n    test6733();\n    test6813();\n    test6859();\n    test3022();\n    test6910();\n    test6902();\n    test6330();\n    test6868();\n    test2856();\n    test3091();\n    test6056();\n    test6356();\n    test7073();\n    test7104();\n    test7150();\n    test7160();\n    test7168();\n    test7170();\n    test7196();\n    test7285();\n    test14737();\n    test7321();\n    test3282();\n    test7534();\n    test7534cov();\n    test7618();\n    test7621();\n    test11417();\n    test7682();\n    test7735();\n    test7823();\n    test7871();\n    test7906();\n    test7907();\n    test12503();\n    test8004();\n    test8064();\n    test8105();\n    test159();\n    test12824();\n    test8283();\n    test13182();\n    test8269();\n    test8395();\n    test13427();\n    test5749();\n    test8396();\n    test160();\n    test8665();\n    test8108();\n    test8360();\n    test9577();\n    test6141();\n    test199();\n    test8526();\n    test161();\n    test7175();\n    test8819();\n    test8917();\n    test8945();\n    test11805();\n    test14192();\n    test163();\n    test9428();\n    test9477();\n    test9538();\n    test9700();\n    test9834();\n    test13947();\n    test9883();\n    test10091();\n    test9130();\n    test10542();\n    test10539();\n    test10634();\n    test15080();\n    test7254();\n    test13468();\n    test11075();\n    test11181();\n    test11317();\n    test11888();\n    test12036();\n    test12153();\n    test12937();\n    test13154();\n    test13437();\n    test13472();\n    test13476();\n    test13720();\n    test13952();\n    test13985();\n    test14211();\n    test15141();\n    test15369();\n    test15638();\n    test16233();\n    test16466();\n    test16408();\n    test17349();\n    test17915();\n    test18232();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/xtest55.d",
    "content": "// PERMUTE_ARGS:\n\nimport core.memory, std.stdio;\n\nStuff* stuff1;\n\nstruct Stuff {\n    uint num;\n}\n\nint main()\n{\n    stuff1 = new Stuff;\n    stuff1.num = 1;\n    auto bar = new byte[1024 * 1024];\n    auto stuff2 = new Stuff;\n    stuff2.num = 2;\n    writeln(stuff1, \"\\t\", stuff2);  // Same address.\n    assert(stuff1 != stuff2);\n    writeln(stuff1.num, \"\\t\", stuff2.num);  // Both 2.\n    assert(stuff1.num == 1);\n    return 0;\n}\n\n"
  },
  {
    "path": "gcc/testsuite/gdc.test/runnable/xtestenum.d",
    "content": "// PERMUTE_ARGS:\n\nextern(C) int printf(const char*, ...);\n\n/***********************************/\n\nenum : float\n{\n    E1a,\n    E1b,\n    E1c\n}\n\nvoid test1()\n{\n    assert(E1a == 0.0f);\n    assert(E1b == 1.0f);\n    assert(E1c == 2.0f);\n}\n\n/***********************************/\n\nenum : string\n{\n    E2a = \"foo\",\n    E2b = \"bar\",\n    E2c = \"abc\"\n}\n\nvoid test2()\n{\n    assert(E2a == \"foo\");\n    assert(E2b == \"bar\");\n    assert(E2c == \"abc\");\n}\n\n/***********************************/\n\nenum E3 : string\n{\n    E3a = \"foo\",\n    E3b = \"bar\",\n    E3c = \"abc\"\n}\n\nvoid test3()\n{\n    printf(\"%.*s\\n\", E3.E3a.length, E3.E3a.ptr);\n\n    assert(E3.E3a == \"foo\");\n    assert(E3.E3b == \"bar\");\n    assert(E3.E3c == \"abc\");\n}\n\n/***********************************/\n\nenum E4 : char\n{\n    Tvoid     = 'v',\n    Tbool     = 'b',\n}\n\nvoid test4()\n{\n    E4 m;\n}\n\n/***********************************/\n\nenum E5 : byte\n{\n    e1,\n    e2\n}\n\nvoid test5()\n{\n    E5 m;\n}\n\n/***********************************/\n\nenum : ubyte\n{\n    REend,\n    REchar,\n    REichar,\n    REdchar,\n    REidchar,\n    REanychar,\n}\n\nvoid foo6(ubyte) { }\nvoid foo6(int) { assert(0); }\n\nvoid test6()\n{\n    foo6(REchar);\n}\n\n/***********************************/\n\nenum\n{\n        foo7 = 1,\n        long bar7 = 2,\n        abc7,\n}\n\nenum x7 = 3;\n\nvoid test7()\n{\n    assert(x7 == 3);\n    assert(is(typeof(foo7) == int));\n    assert(is(typeof(bar7) == long));\n    assert(is(typeof(abc7) == long));\n    assert(abc7 == 3L);\n}\n\n/***********************************/\n\nenum E8 : real { a, b }\n\n/***********************************/\n\nstruct S7379\n{\n\n    enum ENUM\n    {\n        M1,\n        M2,\n        M3\n    }\n    alias ENUM this;\n}\n\nclass C7379\n{\n    this(S7379 test)\n    {\n    }\n\n    this(string test)\n    {\n        this(S7379());\n    }\n}\n\n/***********************************/\n\nint main()\n{\n    test1();\n    test2();\n    test3();\n    test4();\n    test5();\n    test6();\n    test7();\n\n    printf(\"Success\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "gcc/testsuite/lib/gdc-dg.exp",
    "content": "# Copyright (C) 2012-2018 Free Software Foundation, Inc.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib gcc-dg.exp\n\n# Define gdc callbacks for dg.exp.\n\nproc gdc-dg-test { prog do_what extra_tool_flags } {\n    set result \\\n        [gcc-dg-test-1 gdc_target_compile $prog $do_what $extra_tool_flags]\n\n    set comp_output [lindex $result 0]\n    set output_file [lindex $result 1]\n\n    return [list $comp_output $output_file]\n}\n\nproc gdc-dg-prune { system text } {\n    return [gcc-dg-prune $system $text]\n}\n\n# Utility routines.\n\n#\n# Modified dg-runtest that can cycle through a list of optimization options\n# as c-torture does.\n#\n\nproc gdc-dg-runtest { testcases flags default-extra-flags } {\n    global runtests\n\n    foreach test $testcases {\n        # If we're only testing specific files and this isn't one of\n        # them, skip it.\n        if ![runtest_file_p $runtests $test] {\n            continue\n        }\n\n        # Use TORTURE_OPTIONS to cycle through an option list.\n        if [torture-options-exist] then {\n            global torture_with_loops\n            set option_list $torture_with_loops\n        } else {\n            set option_list { \"\" }\n        }\n\n        set nshort [file tail [file dirname $test]]/[file tail $test]\n\n        foreach flags_t $option_list {\n            verbose \"Testing $nshort, $flags $flags_t\" 1\n            dg-test $test \"$flags $flags_t\" ${default-extra-flags}\n        }\n    }\n}\n\n#\n# gdc_load -- wrapper around default gdc_load to handle tests that\n# require program arguments passed to them.\n#\n\nif { [info procs gdc_load] != [list] \\\n      && [info procs prev_gdc_load] == [list] } {\n    rename gdc_load prev_gdc_load\n\n    proc gdc_load { program args } {\n        global GDC_EXECUTE_ARGS\n        if [info exists GDC_EXECUTE_ARGS] then {\n            set args [concat \"{$GDC_EXECUTE_ARGS}\"]\n        }\n        #print \"Running: $program [lindex $args 0]\"\n        set result [eval [list prev_gdc_load $program] $args ]\n        return $result\n    }\n}\n\n"
  },
  {
    "path": "gcc/testsuite/lib/gdc.exp",
    "content": "# Copyright (C) 2012-2018 Free Software Foundation, Inc.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\n#\n# gdc support library routines\n#\n\nload_lib prune.exp\nload_lib gcc-defs.exp\nload_lib timeout.exp\nload_lib target-libpath.exp\n\n#\n# GDC_UNDER_TEST is the compiler under test.\n#\n\nset gdc_compile_options \"\"\n\n\n#\n# gdc_version -- extract and print the version number of the compiler\n#\n\nproc gdc_version { } {\n    global GDC_UNDER_TEST\n\n    gdc_init\n\n    # ignore any arguments after the command\n    set compiler [lindex $GDC_UNDER_TEST 0]\n\n    # verify that the compiler exists\n    if { [is_remote host] || [which $compiler] != 0 } then {\n        set tmp [remote_exec host \"$compiler -v\"]\n        set status [lindex $tmp 0]\n        set output [lindex $tmp 1]\n        regexp \" version \\[^\\n\\r\\]*\" $output version\n        if { $status == 0 && [info exists version] } then {\n            if [is_remote host] {\n                clone_output \"$compiler $version\\n\"\n            } else {\n                clone_output \"[which $compiler] $version\\n\"\n            }\n        } else {\n            clone_output \"Couldn't determine version of [which $compiler]\\n\"\n        }\n    } else {\n        # compiler does not exist (this should have already been detected)\n        warning \"$compiler does not exist\"\n    }\n}\n\n#\n# gdc_include_flags -- include flags for the gcc tree structure\n#\n\nproc gdc_include_flags { paths } {\n    global srcdir\n    global TESTING_IN_BUILD_TREE\n\n    set flags \"\"\n\n    if { [is_remote host] || ![info exists TESTING_IN_BUILD_TREE] } {\n        return \"${flags}\"\n    }\n\n    set gccpath ${paths}\n    set target [file tail [file normalize ${paths}]]\n\n    if { $gccpath != \"\" } {\n        if [file exists \"${gccpath}/libphobos/libdruntime\"] {\n            append flags \"-I${gccpath}/libphobos/libdruntime \"\n        }\n    }\n    append flags \"-I${srcdir}/../../libphobos/libdruntime \"\n    append flags \"-I${srcdir}/../../libphobos/src \"\n\n    # For the tests that mix C++ and D, we should try and handle this better.\n    if { $gccpath != \"\" } {\n        if [file exists \"${gccpath}/libstdc++-v3/include\"] {\n            append flags \"-I${gccpath}/libstdc++-v3/include \"\n            append flags \"-I${gccpath}/libstdc++-v3/include/$target \"\n        }\n    }\n    append flags \"-I${srcdir}/../../libstdc++-v3/libsupc++\"\n}\n\n#\n# gdc_link_flags -- linker flags for the gcc tree structure\n#\n\nproc gdc_link_flags { paths } {\n    global srcdir\n    global ld_library_path\n    global GDC_UNDER_TEST\n    global shlib_ext\n    global SHARED_OPTION\n\n    set gccpath ${paths}\n    set libio_dir \"\"\n    set flags \"\"\n    set ld_library_path \".\"\n    set shlib_ext [get_shlib_extension]\n    set SHARED_OPTION \"\"\n    verbose \"shared lib extension: $shlib_ext\"\n\n    if { $gccpath != \"\" } {\n        # Path to libgphobos.spec.\n        append flags \"-B${gccpath}/libphobos/src \"\n\n        if { [file exists \"${gccpath}/libphobos/src/.libs/libgphobos.a\"] \\\n             || [file exists \"${gccpath}/libphobos/src/.libs/libgphobos.${shlib_ext}\"] } {\n            append flags \"-L${gccpath}/libphobos/src/.libs \"\n            append ld_library_path \":${gccpath}/libphobos/src/.libs\"\n        }\n        if { [file exists \"${gccpath}/libphobos/libdruntime/.libs/libgdruntime.a\"] \\\n             || [file exists \"${gccpath}/libphobos/libdruntime/.libs/libgdruntime.${shlib_ext}\"] } {\n            append flags \"-L${gccpath}/libphobos/libdruntime/.libs \"\n            append ld_library_path \":${gccpath}/libphobos/libdruntime/.libs\"\n        }\n        # Static linking is default. If only the shared lib is available adjust\n        # flags to always use it. If both are available, set SHARED_OPTION which\n        # will be added to PERMUTE_ARGS\n        if { [file exists \"${gccpath}/libphobos/libdruntime/.libs/libgdruntime.${shlib_ext}\"] } {\n            if { [file exists \"${gccpath}/libphobos/libdruntime/.libs/libgdruntime.a\"] } {\n                set SHARED_OPTION \"-shared-libphobos\"\n            } else {\n                append flags \"-shared-libphobos \"\n            }\n        }\n        if [file exists \"${gccpath}/libiberty/libiberty.a\"] {\n            append flags \"-L${gccpath}/libiberty \"\n        }\n        # For the tests that mix C++ and D, we should try and handle this better.\n        if { [file exists \"${gccpath}/libstdc++-v3/src/.libs/libstdc++.a\"] \\\n             || [file exists \"${gccpath}/libstdc++-v3/src/.libs/libstdc++.${shlib_ext}\"] } {\n            append flags \"-L${gccpath}/libstdc++-v3/src/.libs \"\n            append ld_library_path \":${gccpath}/libstdc++-v3/src/.libs\"\n        }\n        append ld_library_path [gcc-set-multilib-library-path $GDC_UNDER_TEST]\n    } else {\n        global tool_root_dir\n\n        set libphobos [lookfor_file ${tool_root_dir} libgphobos]\n        if { $libphobos != \"\" } {\n            append flags \"-B${libphobos} -L${libphobos} \"\n            append ld_library_path \":${libphobos}\"\n        }\n        set libdruntime [lookfor_file ${tool_root_dir} libgdruntime]\n        if { $libdruntime != \"\" } {\n            append flags \"-L${libdruntime} \"\n            append ld_library_path \":${libdruntime}\"\n        }\n        set libiberty [lookfor_file ${tool_root_dir} libiberty]\n        if { $libiberty != \"\" } {\n            append flags \"-L${libiberty} \"\n        }\n    }\n\n    set_ld_library_path_env_vars\n\n    return \"$flags\"\n}\n\n#\n# gdc_init -- called at the start of each subdir of tests\n#\n\nproc gdc_init { args } {\n    global subdir\n    global gdc_initialized\n    global base_dir\n    global tmpdir\n    global libdir\n    global gluefile wrap_flags\n    global objdir srcdir\n    global ALWAYS_DFLAGS\n    global TOOL_EXECUTABLE TOOL_OPTIONS\n    global GDC_UNDER_TEST\n    global TESTING_IN_BUILD_TREE\n    global TEST_ALWAYS_FLAGS\n\n    # We set LC_ALL and LANG to C so that we get the same error messages as expected.\n    setenv LC_ALL C\n    setenv LANG C\n\n    if ![info exists GDC_UNDER_TEST] then {\n        if [info exists TOOL_EXECUTABLE] {\n            set GDC_UNDER_TEST $TOOL_EXECUTABLE\n        } else {\n            if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } {\n                set GDC_UNDER_TEST [transform gdc]\n            } else {\n                set GDC_UNDER_TEST [findfile $base_dir/../../gdc \"$base_dir/../../gdc -B$base_dir/../../\" [findfile $base_dir/gdc \"$base_dir/gdc -B$base_dir/\" [transform gdc]]]\n            }\n        }\n    }\n\n    if ![is_remote host] {\n        if { [which $GDC_UNDER_TEST] == 0 } then {\n            perror \"GDC_UNDER_TEST ($GDC_UNDER_TEST) does not exist\"\n            exit 1\n        }\n    }\n    if ![info exists tmpdir] {\n        set tmpdir \"/tmp\"\n    }\n\n    if [info exists gluefile] {\n        unset gluefile\n    }\n\n    gdc_maybe_build_wrapper \"${tmpdir}/d-testglue.o\"\n\n    set ALWAYS_DFLAGS \"\"\n\n    # TEST_ALWAYS_FLAGS are flags that should be passed to every\n    # compilation.  They are passed first to allow individual\n    # tests to override them.\n    if [info exists TEST_ALWAYS_FLAGS] {\n        lappend ALWAYS_DFLAGS \"additional_flags=$TEST_ALWAYS_FLAGS\"\n    }\n\n    if ![is_remote host] {\n        if [info exists TOOL_OPTIONS] {\n            lappend ALWAYS_DFLAGS \"additional_flags=[gdc_include_flags [get_multilibs ${TOOL_OPTIONS}] ]\"\n            lappend ALWAYS_DFLAGS \"ldflags=[gdc_link_flags [get_multilibs ${TOOL_OPTIONS}] ]\"\n        } else {\n            lappend ALWAYS_DFLAGS \"additional_flags=[gdc_include_flags [get_multilibs] ]\"\n            lappend ALWAYS_DFLAGS \"ldflags=[gdc_link_flags [get_multilibs] ]\"\n        }\n    }\n\n    if [info exists TOOL_OPTIONS] {\n        lappend ALWAYS_DFLAGS \"additional_flags=$TOOL_OPTIONS\"\n    }\n\n    verbose -log \"ALWAYS_DFLAGS set to $ALWAYS_DFLAGS\"\n\n    verbose \"gdc is initialized\" 3\n}\n\n#\n# gdc_target_compile -- compile a source file\n#\n\nproc gdc_target_compile { source dest type options } {\n    global tmpdir\n    global gluefile wrap_flags\n    global ALWAYS_DFLAGS\n    global GDC_UNDER_TEST\n\n    if { [target_info needs_status_wrapper] != \"\" && [info exists gluefile] } {\n        lappend options \"libs=${gluefile}\"\n        lappend options \"ldflags=${wrap_flags}\"\n    }\n\n    lappend options \"timeout=[timeout_value]\"\n    lappend options \"compiler=$GDC_UNDER_TEST\"\n\n    set options [concat \"$ALWAYS_DFLAGS\" $options]\n    set options [dg-additional-files-options $options $source]\n    return [target_compile $source $dest $type $options]\n}\n"
  },
  {
    "path": "gcc.version",
    "content": "gcc-9-20181021\n"
  },
  {
    "path": "libphobos/Makefile.am",
    "content": "# Makefile for the toplevel directory of the D Standard library.\n# Copyright (C) 2006-2018 Free Software Foundation, Inc.\n#\n# GCC is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3, or (at your option)\n# any later version.\n#\n# GCC is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nSUBDIRS = libdruntime src testsuite\n\nACLOCAL_AMFLAGS = -I . -I .. -I ../config\n\n# Multilib support.\nMAKEOVERRIDES=\n\n# Work around what appears to be a GNU make bug handling MAKEFLAGS\n# values defined in terms of make variables, as is the case for CC and\n# friends when we are called from the top level Makefile.\nAM_MAKEFLAGS = \\\n\t\"AR_FLAGS=$(AR_FLAGS)\" \\\n\t\"CC_FOR_BUILD=$(CC_FOR_BUILD)\" \\\n\t\"CC_FOR_TARGET=$(CC_FOR_TARGET)\" \\\n\t\"CFLAGS=$(CFLAGS)\" \\\n\t\"CXXFLAGS=$(CXXFLAGS)\" \\\n\t\"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)\" \\\n\t\"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)\" \\\n\t\"GDC_FOR_TARGET=$(GDC_FOR_TARGET)\" \\\n\t\"GDC=$(GDC)\" \\\n\t\"INSTALL=$(INSTALL)\" \\\n\t\"INSTALL_DATA=$(INSTALL_DATA)\" \\\n\t\"INSTALL_PROGRAM=$(INSTALL_PROGRAM)\" \\\n\t\"INSTALL_SCRIPT=$(INSTALL_SCRIPT)\" \\\n\t\"LDFLAGS=$(LDFLAGS)\" \\\n\t\"LIBCFLAGS=$(LIBCFLAGS)\" \\\n\t\"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)\" \\\n\t\"MAKE=$(MAKE)\" \\\n\t\"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)\" \\\n\t\"PICFLAG=$(PICFLAG)\" \\\n\t\"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)\" \\\n\t\"SHELL=$(SHELL)\" \\\n\t\"RUNTESTFLAGS=$(RUNTESTFLAGS)\" \\\n\t\"exec_prefix=$(exec_prefix)\" \\\n\t\"infodir=$(infodir)\" \\\n\t\"libdir=$(libdir)\" \\\n\t\"includedir=$(includedir)\" \\\n\t\"prefix=$(prefix)\" \\\n\t\"tooldir=$(tooldir)\" \\\n\t\"gdc_include_dir=$(gdc_include_dir)\" \\\n\t\"AR=$(AR)\" \\\n\t\"AS=$(AS)\" \\\n\t\"LD=$(LD)\" \\\n\t\"RANLIB=$(RANLIB)\" \\\n\t\"NM=$(NM)\" \\\n\t\"NM_FOR_BUILD=$(NM_FOR_BUILD)\" \\\n\t\"NM_FOR_TARGET=$(NM_FOR_TARGET)\" \\\n\t\"DESTDIR=$(DESTDIR)\" \\\n\t\"WERROR=$(WERROR)\"\n\n# Subdir rules rely on $(FLAGS_TO_PASS)\nFLAGS_TO_PASS = $(AM_MAKEFLAGS)\n"
  },
  {
    "path": "libphobos/Makefile.in",
    "content": "# Makefile.in generated by automake 1.11.6 from Makefile.am.\n# @configure_input@\n\n# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,\n# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software\n# Foundation, Inc.\n# This Makefile.in is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY, to the extent permitted by law; without\n# even the implied warranty of MERCHANTABILITY or FITNESS FOR A\n# PARTICULAR PURPOSE.\n\n@SET_MAKE@\n\n# Makefile for the toplevel directory of the D Standard library.\n# Copyright (C) 2006-2018 Free Software Foundation, Inc.\n#\n# GCC is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3, or (at your option)\n# any later version.\n#\n# GCC is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\nVPATH = @srcdir@\nam__make_dryrun = \\\n  { \\\n    am__dry=no; \\\n    case $$MAKEFLAGS in \\\n      *\\\\[\\ \\\t]*) \\\n        echo 'am--echo: ; @echo \"AM\"  OK' | $(MAKE) -f - 2>/dev/null \\\n          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \\\n      *) \\\n        for am__flg in $$MAKEFLAGS; do \\\n          case $$am__flg in \\\n            *=*|--*) ;; \\\n            *n*) am__dry=yes; break;; \\\n          esac; \\\n        done;; \\\n    esac; \\\n    test $$am__dry = yes; \\\n  }\npkgdatadir = $(datadir)/@PACKAGE@\npkgincludedir = $(includedir)/@PACKAGE@\npkglibdir = $(libdir)/@PACKAGE@\npkglibexecdir = $(libexecdir)/@PACKAGE@\nam__cd = CDPATH=\"$${ZSH_VERSION+.}$(PATH_SEPARATOR)\" && cd\ninstall_sh_DATA = $(install_sh) -c -m 644\ninstall_sh_PROGRAM = $(install_sh) -c\ninstall_sh_SCRIPT = $(install_sh) -c\nINSTALL_HEADER = $(INSTALL_DATA)\ntransform = $(program_transform_name)\nNORMAL_INSTALL = :\nPRE_INSTALL = :\nPOST_INSTALL = :\nNORMAL_UNINSTALL = :\nPRE_UNINSTALL = :\nPOST_UNINSTALL = :\nbuild_triplet = @build@\nhost_triplet = @host@\ntarget_triplet = @target@\nsubdir = .\nDIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \\\n\t$(top_srcdir)/configure $(am__configure_deps) \\\n\t$(srcdir)/config.h.in $(srcdir)/../mkinstalldirs \\\n\t$(top_srcdir)/libdruntime/gcc/config.d.in \\\n\t$(top_srcdir)/libdruntime/gcc/libbacktrace.d.in\nACLOCAL_M4 = $(top_srcdir)/aclocal.m4\nam__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \\\n\t$(top_srcdir)/../config/lead-dot.m4 \\\n\t$(top_srcdir)/../config/multi.m4 \\\n\t$(top_srcdir)/../config/override.m4 \\\n\t$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \\\n\t$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \\\n\t$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \\\n\t$(top_srcdir)/m4/gcc_support.m4 $(top_srcdir)/m4/autoconf.m4 \\\n\t$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/gdc.m4 \\\n\t$(top_srcdir)/m4/druntime.m4 $(top_srcdir)/m4/druntime/cpu.m4 \\\n\t$(top_srcdir)/m4/druntime/os.m4 \\\n\t$(top_srcdir)/m4/druntime/libraries.m4 \\\n\t$(top_srcdir)/configure.ac\nam__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \\\n\t$(ACLOCAL_M4)\nam__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \\\n configure.lineno config.status.lineno\nmkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs\nCONFIG_HEADER = config.h\nCONFIG_CLEAN_FILES = libdruntime/gcc/config.d \\\n\tlibdruntime/gcc/libbacktrace.d\nCONFIG_CLEAN_VPATH_FILES =\ndepcomp =\nam__depfiles_maybe =\nSOURCES =\nMULTISRCTOP = \nMULTIBUILDTOP = \nMULTIDIRS = \nMULTISUBDIR = \nMULTIDO = true\nMULTICLEAN = true\nRECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \\\n\thtml-recursive info-recursive install-data-recursive \\\n\tinstall-dvi-recursive install-exec-recursive \\\n\tinstall-html-recursive install-info-recursive \\\n\tinstall-pdf-recursive install-ps-recursive install-recursive \\\n\tinstallcheck-recursive installdirs-recursive pdf-recursive \\\n\tps-recursive uninstall-recursive\nam__can_run_installinfo = \\\n  case $$AM_UPDATE_INFO_DIR in \\\n    n|no|NO) false;; \\\n    *) (install-info --version) >/dev/null 2>&1;; \\\n  esac\nRECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive\t\\\n  distclean-recursive maintainer-clean-recursive\nAM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \\\n\t$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS\nETAGS = etags\nCTAGS = ctags\nDIST_SUBDIRS = $(SUBDIRS)\nACLOCAL = @ACLOCAL@\nAMTAR = @AMTAR@\nAR = @AR@\nAUTOCONF = @AUTOCONF@\nAUTOHEADER = @AUTOHEADER@\nAUTOMAKE = @AUTOMAKE@\nAWK = @AWK@\nBACKTRACE_SUPPORTED = @BACKTRACE_SUPPORTED@\nBACKTRACE_SUPPORTS_THREADS = @BACKTRACE_SUPPORTS_THREADS@\nBACKTRACE_USES_MALLOC = @BACKTRACE_USES_MALLOC@\nCC = @CC@\nCCAS = @CCAS@\nCCASFLAGS = @CCASFLAGS@\nCC_FOR_BUILD = @CC_FOR_BUILD@\nCFLAGS = @CFLAGS@\nCFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@\nCPP = @CPP@\nCPPFLAGS = @CPPFLAGS@\nCYGPATH_W = @CYGPATH_W@\nDCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@\nDCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@\nDCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@\nDCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@\nDCFG_MINFO_BRACKETING = @DCFG_MINFO_BRACKETING@\nDCFG_THREAD_MODEL = @DCFG_THREAD_MODEL@\nDEFS = @DEFS@\nDRUNTIME_SOVERSION = @DRUNTIME_SOVERSION@\nDSYMUTIL = @DSYMUTIL@\nDUMPBIN = @DUMPBIN@\nECHO_C = @ECHO_C@\nECHO_N = @ECHO_N@\nECHO_T = @ECHO_T@\nEGREP = @EGREP@\nEXEEXT = @EXEEXT@\nFGREP = @FGREP@\nGDC = @GDC@\nGDCFLAGS = @GDCFLAGS@\nGDCFLAGSX = @GDCFLAGSX@\nGREP = @GREP@\nINSTALL = @INSTALL@\nINSTALL_DATA = @INSTALL_DATA@\nINSTALL_PROGRAM = @INSTALL_PROGRAM@\nINSTALL_SCRIPT = @INSTALL_SCRIPT@\nINSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@\nLD = @LD@\nLDFLAGS = @LDFLAGS@\nLIBATOMIC = @LIBATOMIC@\nLIBBACKTRACE = @LIBBACKTRACE@\nLIBOBJS = @LIBOBJS@\nLIBS = @LIBS@\nLIBTOOL = @LIBTOOL@\nLIPO = @LIPO@\nLN_S = @LN_S@\nLTLIBOBJS = @LTLIBOBJS@\nMAINT = @MAINT@\nMAKEINFO = @MAKEINFO@\nMKDIR_P = @MKDIR_P@\nNM = @NM@\nNMEDIT = @NMEDIT@\nOBJDUMP = @OBJDUMP@\nOBJEXT = @OBJEXT@\nOTOOL = @OTOOL@\nOTOOL64 = @OTOOL64@\nPACKAGE = @PACKAGE@\nPACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@\nPACKAGE_NAME = @PACKAGE_NAME@\nPACKAGE_STRING = @PACKAGE_STRING@\nPACKAGE_TARNAME = @PACKAGE_TARNAME@\nPACKAGE_URL = @PACKAGE_URL@\nPACKAGE_VERSION = @PACKAGE_VERSION@\nPATH_SEPARATOR = @PATH_SEPARATOR@\nPHOBOS_SOVERSION = @PHOBOS_SOVERSION@\nRANLIB = @RANLIB@\nSED = @SED@\nSET_MAKE = @SET_MAKE@\nSHELL = @SHELL@\nSPEC_PHOBOS_DEPS = @SPEC_PHOBOS_DEPS@\nSTRIP = @STRIP@\nVERSION = @VERSION@\nabs_builddir = @abs_builddir@\nabs_srcdir = @abs_srcdir@\nabs_top_builddir = @abs_top_builddir@\nabs_top_srcdir = @abs_top_srcdir@\nac_ct_CC = @ac_ct_CC@\nac_ct_DUMPBIN = @ac_ct_DUMPBIN@\nam__leading_dot = @am__leading_dot@\nam__tar = @am__tar@\nam__untar = @am__untar@\nbindir = @bindir@\nbuild = @build@\nbuild_alias = @build_alias@\nbuild_cpu = @build_cpu@\nbuild_os = @build_os@\nbuild_vendor = @build_vendor@\nbuilddir = @builddir@\ndatadir = @datadir@\ndatarootdir = @datarootdir@\ndocdir = @docdir@\ndvidir = @dvidir@\nexec_prefix = @exec_prefix@\ngcc_version = @gcc_version@\ngdc_include_dir = @gdc_include_dir@\nget_gcc_base_ver = @get_gcc_base_ver@\nhost = @host@\nhost_alias = @host_alias@\nhost_cpu = @host_cpu@\nhost_os = @host_os@\nhost_vendor = @host_vendor@\nhtmldir = @htmldir@\nincludedir = @includedir@\ninfodir = @infodir@\ninstall_sh = @install_sh@\nlibdir = @libdir@\nlibexecdir = @libexecdir@\nlibphobos_builddir = @libphobos_builddir@\nlibphobos_srcdir = @libphobos_srcdir@\nlocaledir = @localedir@\nlocalstatedir = @localstatedir@\nmandir = @mandir@\nmkdir_p = @mkdir_p@\nmulti_basedir = @multi_basedir@\noldincludedir = @oldincludedir@\npdfdir = @pdfdir@\nphobos_compiler_pic_flag = @phobos_compiler_pic_flag@\nphobos_compiler_shared_flag = @phobos_compiler_shared_flag@\nprefix = @prefix@\nprogram_transform_name = @program_transform_name@\npsdir = @psdir@\nsbindir = @sbindir@\nsharedstatedir = @sharedstatedir@\nsrcdir = @srcdir@\nsysconfdir = @sysconfdir@\ntarget = @target@\ntarget_alias = @target_alias@\ntarget_cpu = @target_cpu@\ntarget_os = @target_os@\ntarget_vendor = @target_vendor@\ntoolexecdir = @toolexecdir@\ntoolexeclibdir = @toolexeclibdir@\ntop_build_prefix = @top_build_prefix@\ntop_builddir = @top_builddir@\ntop_srcdir = @top_srcdir@\nSUBDIRS = libdruntime src testsuite\nACLOCAL_AMFLAGS = -I . -I .. -I ../config\n\n# Multilib support.\nMAKEOVERRIDES = \n\n# Work around what appears to be a GNU make bug handling MAKEFLAGS\n# values defined in terms of make variables, as is the case for CC and\n# friends when we are called from the top level Makefile.\nAM_MAKEFLAGS = \\\n\t\"AR_FLAGS=$(AR_FLAGS)\" \\\n\t\"CC_FOR_BUILD=$(CC_FOR_BUILD)\" \\\n\t\"CC_FOR_TARGET=$(CC_FOR_TARGET)\" \\\n\t\"CFLAGS=$(CFLAGS)\" \\\n\t\"CXXFLAGS=$(CXXFLAGS)\" \\\n\t\"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)\" \\\n\t\"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)\" \\\n\t\"GDC_FOR_TARGET=$(GDC_FOR_TARGET)\" \\\n\t\"GDC=$(GDC)\" \\\n\t\"INSTALL=$(INSTALL)\" \\\n\t\"INSTALL_DATA=$(INSTALL_DATA)\" \\\n\t\"INSTALL_PROGRAM=$(INSTALL_PROGRAM)\" \\\n\t\"INSTALL_SCRIPT=$(INSTALL_SCRIPT)\" \\\n\t\"LDFLAGS=$(LDFLAGS)\" \\\n\t\"LIBCFLAGS=$(LIBCFLAGS)\" \\\n\t\"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)\" \\\n\t\"MAKE=$(MAKE)\" \\\n\t\"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)\" \\\n\t\"PICFLAG=$(PICFLAG)\" \\\n\t\"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)\" \\\n\t\"SHELL=$(SHELL)\" \\\n\t\"RUNTESTFLAGS=$(RUNTESTFLAGS)\" \\\n\t\"exec_prefix=$(exec_prefix)\" \\\n\t\"infodir=$(infodir)\" \\\n\t\"libdir=$(libdir)\" \\\n\t\"includedir=$(includedir)\" \\\n\t\"prefix=$(prefix)\" \\\n\t\"tooldir=$(tooldir)\" \\\n\t\"gdc_include_dir=$(gdc_include_dir)\" \\\n\t\"AR=$(AR)\" \\\n\t\"AS=$(AS)\" \\\n\t\"LD=$(LD)\" \\\n\t\"RANLIB=$(RANLIB)\" \\\n\t\"NM=$(NM)\" \\\n\t\"NM_FOR_BUILD=$(NM_FOR_BUILD)\" \\\n\t\"NM_FOR_TARGET=$(NM_FOR_TARGET)\" \\\n\t\"DESTDIR=$(DESTDIR)\" \\\n\t\"WERROR=$(WERROR)\"\n\n\n# Subdir rules rely on $(FLAGS_TO_PASS)\nFLAGS_TO_PASS = $(AM_MAKEFLAGS)\nall: config.h\n\t$(MAKE) $(AM_MAKEFLAGS) all-recursive\n\n.SUFFIXES:\nam--refresh: Makefile\n\t@:\n$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)\n\t@for dep in $?; do \\\n\t  case '$(am__configure_deps)' in \\\n\t    *$$dep*) \\\n\t      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign --ignore-deps'; \\\n\t      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign --ignore-deps \\\n\t\t&& exit 0; \\\n\t      exit 1;; \\\n\t  esac; \\\n\tdone; \\\n\techo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps Makefile'; \\\n\t$(am__cd) $(top_srcdir) && \\\n\t  $(AUTOMAKE) --foreign --ignore-deps Makefile\n.PRECIOUS: Makefile\nMakefile: $(srcdir)/Makefile.in $(top_builddir)/config.status\n\t@case '$?' in \\\n\t  *config.status*) \\\n\t    echo ' $(SHELL) ./config.status'; \\\n\t    $(SHELL) ./config.status;; \\\n\t  *) \\\n\t    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \\\n\t    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \\\n\tesac;\n\n$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)\n\t$(SHELL) ./config.status --recheck\n\n$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)\n\t$(am__cd) $(srcdir) && $(AUTOCONF)\n$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)\n\t$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)\n$(am__aclocal_m4_deps):\n\nconfig.h: stamp-h1\n\t@if test ! -f $@; then rm -f stamp-h1; else :; fi\n\t@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi\n\nstamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status\n\t@rm -f stamp-h1\n\tcd $(top_builddir) && $(SHELL) ./config.status config.h\n$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) \n\t($(am__cd) $(top_srcdir) && $(AUTOHEADER))\n\trm -f stamp-h1\n\ttouch $@\n\ndistclean-hdr:\n\t-rm -f config.h stamp-h1\nlibdruntime/gcc/config.d: $(top_builddir)/config.status $(top_srcdir)/libdruntime/gcc/config.d.in\n\tcd $(top_builddir) && $(SHELL) ./config.status $@\nlibdruntime/gcc/libbacktrace.d: $(top_builddir)/config.status $(top_srcdir)/libdruntime/gcc/libbacktrace.d.in\n\tcd $(top_builddir) && $(SHELL) ./config.status $@\n\nmostlyclean-libtool:\n\t-rm -f *.lo\n\nclean-libtool:\n\t-rm -rf .libs _libs\n\ndistclean-libtool:\n\t-rm -f libtool config.lt\n\n# GNU Make needs to see an explicit $(MAKE) variable in the command it\n# runs to enable its job server during parallel builds.  Hence the\n# comments below.\nall-multi:\n\t$(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)\ninstall-multi:\n\t$(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do # $(MAKE)\n\nmostlyclean-multi:\n\t$(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean # $(MAKE)\nclean-multi:\n\t$(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean # $(MAKE)\ndistclean-multi:\n\t$(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)\nmaintainer-clean-multi:\n\t$(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)\n\n# This directory's subdirectories are mostly independent; you can cd\n# into them and run `make' without going through this Makefile.\n# To change the values of `make' variables: instead of editing Makefiles,\n# (1) if the variable is set in `config.status', edit `config.status'\n#     (which will cause the Makefiles to be regenerated when you run `make');\n# (2) otherwise, pass the desired values on the `make' command line.\n$(RECURSIVE_TARGETS):\n\t@fail= failcom='exit 1'; \\\n\tfor f in x $$MAKEFLAGS; do \\\n\t  case $$f in \\\n\t    *=* | --[!k]*);; \\\n\t    *k*) failcom='fail=yes';; \\\n\t  esac; \\\n\tdone; \\\n\tdot_seen=no; \\\n\ttarget=`echo $@ | sed s/-recursive//`; \\\n\tlist='$(SUBDIRS)'; for subdir in $$list; do \\\n\t  echo \"Making $$target in $$subdir\"; \\\n\t  if test \"$$subdir\" = \".\"; then \\\n\t    dot_seen=yes; \\\n\t    local_target=\"$$target-am\"; \\\n\t  else \\\n\t    local_target=\"$$target\"; \\\n\t  fi; \\\n\t  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \\\n\t  || eval $$failcom; \\\n\tdone; \\\n\tif test \"$$dot_seen\" = \"no\"; then \\\n\t  $(MAKE) $(AM_MAKEFLAGS) \"$$target-am\" || exit 1; \\\n\tfi; test -z \"$$fail\"\n\n$(RECURSIVE_CLEAN_TARGETS):\n\t@fail= failcom='exit 1'; \\\n\tfor f in x $$MAKEFLAGS; do \\\n\t  case $$f in \\\n\t    *=* | --[!k]*);; \\\n\t    *k*) failcom='fail=yes';; \\\n\t  esac; \\\n\tdone; \\\n\tdot_seen=no; \\\n\tcase \"$@\" in \\\n\t  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \\\n\t  *) list='$(SUBDIRS)' ;; \\\n\tesac; \\\n\trev=''; for subdir in $$list; do \\\n\t  if test \"$$subdir\" = \".\"; then :; else \\\n\t    rev=\"$$subdir $$rev\"; \\\n\t  fi; \\\n\tdone; \\\n\trev=\"$$rev .\"; \\\n\ttarget=`echo $@ | sed s/-recursive//`; \\\n\tfor subdir in $$rev; do \\\n\t  echo \"Making $$target in $$subdir\"; \\\n\t  if test \"$$subdir\" = \".\"; then \\\n\t    local_target=\"$$target-am\"; \\\n\t  else \\\n\t    local_target=\"$$target\"; \\\n\t  fi; \\\n\t  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \\\n\t  || eval $$failcom; \\\n\tdone && test -z \"$$fail\"\ntags-recursive:\n\tlist='$(SUBDIRS)'; for subdir in $$list; do \\\n\t  test \"$$subdir\" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \\\n\tdone\nctags-recursive:\n\tlist='$(SUBDIRS)'; for subdir in $$list; do \\\n\t  test \"$$subdir\" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \\\n\tdone\n\nID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)\n\tlist='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\tmkid -fID $$unique\ntags: TAGS\n\nTAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \\\n\t\t$(TAGS_FILES) $(LISP)\n\tset x; \\\n\there=`pwd`; \\\n\tif ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \\\n\t  include_option=--etags-include; \\\n\t  empty_fix=.; \\\n\telse \\\n\t  include_option=--include; \\\n\t  empty_fix=; \\\n\tfi; \\\n\tlist='$(SUBDIRS)'; for subdir in $$list; do \\\n\t  if test \"$$subdir\" = .; then :; else \\\n\t    test ! -f $$subdir/TAGS || \\\n\t      set \"$$@\" \"$$include_option=$$here/$$subdir/TAGS\"; \\\n\t  fi; \\\n\tdone; \\\n\tlist='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\tshift; \\\n\tif test -z \"$(ETAGS_ARGS)$$*$$unique\"; then :; else \\\n\t  test -n \"$$unique\" || unique=$$empty_fix; \\\n\t  if test $$# -gt 0; then \\\n\t    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \\\n\t      \"$$@\" $$unique; \\\n\t  else \\\n\t    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \\\n\t      $$unique; \\\n\t  fi; \\\n\tfi\nctags: CTAGS\nCTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \\\n\t\t$(TAGS_FILES) $(LISP)\n\tlist='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\ttest -z \"$(CTAGS_ARGS)$$unique\" \\\n\t  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \\\n\t     $$unique\n\nGTAGS:\n\there=`$(am__cd) $(top_builddir) && pwd` \\\n\t  && $(am__cd) $(top_srcdir) \\\n\t  && gtags -i $(GTAGS_ARGS) \"$$here\"\n\ndistclean-tags:\n\t-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags\ncheck-am: all-am\ncheck: check-recursive\nall-am: Makefile all-multi config.h\ninstalldirs: installdirs-recursive\ninstalldirs-am:\ninstall: install-recursive\ninstall-exec: install-exec-recursive\ninstall-data: install-data-recursive\nuninstall: uninstall-recursive\n\ninstall-am: all-am\n\t@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am\n\ninstallcheck: installcheck-recursive\ninstall-strip:\n\tif test -z '$(STRIP)'; then \\\n\t  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" \\\n\t    install_sh_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" INSTALL_STRIP_FLAG=-s \\\n\t      install; \\\n\telse \\\n\t  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" \\\n\t    install_sh_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" INSTALL_STRIP_FLAG=-s \\\n\t    \"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'\" install; \\\n\tfi\nmostlyclean-generic:\n\nclean-generic:\n\ndistclean-generic:\n\t-test -z \"$(CONFIG_CLEAN_FILES)\" || rm -f $(CONFIG_CLEAN_FILES)\n\t-test . = \"$(srcdir)\" || test -z \"$(CONFIG_CLEAN_VPATH_FILES)\" || rm -f $(CONFIG_CLEAN_VPATH_FILES)\n\nmaintainer-clean-generic:\n\t@echo \"This command is intended for maintainers to use\"\n\t@echo \"it deletes files that may require special tools to rebuild.\"\nclean: clean-multi clean-recursive\n\nclean-am: clean-generic clean-libtool mostlyclean-am\n\ndistclean: distclean-multi distclean-recursive\n\t-rm -f $(am__CONFIG_DISTCLEAN_FILES)\n\t-rm -f Makefile\ndistclean-am: clean-am distclean-generic distclean-hdr \\\n\tdistclean-libtool distclean-tags\n\ndvi: dvi-recursive\n\ndvi-am:\n\nhtml: html-recursive\n\nhtml-am:\n\ninfo: info-recursive\n\ninfo-am:\n\ninstall-data-am:\n\ninstall-dvi: install-dvi-recursive\n\ninstall-dvi-am:\n\ninstall-exec-am: install-multi\n\ninstall-html: install-html-recursive\n\ninstall-html-am:\n\ninstall-info: install-info-recursive\n\ninstall-info-am:\n\ninstall-man:\n\ninstall-pdf: install-pdf-recursive\n\ninstall-pdf-am:\n\ninstall-ps: install-ps-recursive\n\ninstall-ps-am:\n\ninstallcheck-am:\n\nmaintainer-clean: maintainer-clean-multi maintainer-clean-recursive\n\t-rm -f $(am__CONFIG_DISTCLEAN_FILES)\n\t-rm -rf $(top_srcdir)/autom4te.cache\n\t-rm -f Makefile\nmaintainer-clean-am: distclean-am maintainer-clean-generic\n\nmostlyclean: mostlyclean-multi mostlyclean-recursive\n\nmostlyclean-am: mostlyclean-generic mostlyclean-libtool\n\npdf: pdf-recursive\n\npdf-am:\n\nps: ps-recursive\n\nps-am:\n\nuninstall-am:\n\n.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all all-multi \\\n\tclean-multi ctags-recursive distclean-multi install-am \\\n\tinstall-multi install-strip maintainer-clean-multi \\\n\tmostlyclean-multi tags-recursive\n\n.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \\\n\tall all-am all-multi am--refresh check check-am clean \\\n\tclean-generic clean-libtool clean-multi ctags ctags-recursive \\\n\tdistclean distclean-generic distclean-hdr distclean-libtool \\\n\tdistclean-multi distclean-tags dvi dvi-am html html-am info \\\n\tinfo-am install install-am install-data install-data-am \\\n\tinstall-dvi install-dvi-am install-exec install-exec-am \\\n\tinstall-html install-html-am install-info install-info-am \\\n\tinstall-man install-multi install-pdf install-pdf-am \\\n\tinstall-ps install-ps-am install-strip installcheck \\\n\tinstallcheck-am installdirs installdirs-am maintainer-clean \\\n\tmaintainer-clean-generic maintainer-clean-multi mostlyclean \\\n\tmostlyclean-generic mostlyclean-libtool mostlyclean-multi pdf \\\n\tpdf-am ps ps-am tags tags-recursive uninstall uninstall-am\n\n\n# Tell versions [3.59,3.63) of GNU make to not export all variables.\n# Otherwise a system limit (for SysV at least) may be exceeded.\n.NOEXPORT:\n"
  },
  {
    "path": "libphobos/acinclude.m4",
    "content": "dnl Copyright (C) 2013-2018 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl This program is distributed in the hope that it will be useful,\ndnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without\ndnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A\ndnl PARTICULAR PURPOSE.\n\nm4_include([m4/gcc_support.m4])\nm4_include([m4/autoconf.m4])\nm4_include([m4/libtool.m4])\nm4_include([m4/gdc.m4])\nm4_include([m4/druntime.m4])\nm4_include([m4/druntime/cpu.m4])\nm4_include([m4/druntime/os.m4])\nm4_include([m4/druntime/libraries.m4])\n"
  },
  {
    "path": "libphobos/aclocal.m4",
    "content": "# generated automatically by aclocal 1.11.6 -*- Autoconf -*-\n\n# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,\n# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,\n# Inc.\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY, to the extent permitted by law; without\n# even the implied warranty of MERCHANTABILITY or FITNESS FOR A\n# PARTICULAR PURPOSE.\n\nm4_ifndef([AC_AUTOCONF_VERSION],\n  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl\nm4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,\n[m4_warning([this file was generated for autoconf 2.64.\nYou have another version of autoconf.  It may work, but is not guaranteed to.\nIf you have problems, you may need to regenerate the build system entirely.\nTo do so, use the procedure documented by the package, typically `autoreconf'.])])\n\n# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software\n# Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 1\n\n# AM_AUTOMAKE_VERSION(VERSION)\n# ----------------------------\n# Automake X.Y traces this macro to ensure aclocal.m4 has been\n# generated from the m4 files accompanying Automake X.Y.\n# (This private macro should not be called outside this file.)\nAC_DEFUN([AM_AUTOMAKE_VERSION],\n[am__api_version='1.11'\ndnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to\ndnl require some minimum version.  Point them to the right macro.\nm4_if([$1], [1.11.6], [],\n      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl\n])\n\n# _AM_AUTOCONF_VERSION(VERSION)\n# -----------------------------\n# aclocal traces this macro to find the Autoconf version.\n# This is a private macro too.  Using m4_define simplifies\n# the logic in aclocal, which can simply ignore this definition.\nm4_define([_AM_AUTOCONF_VERSION], [])\n\n# AM_SET_CURRENT_AUTOMAKE_VERSION\n# -------------------------------\n# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.\n# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.\nAC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],\n[AM_AUTOMAKE_VERSION([1.11.6])dnl\nm4_ifndef([AC_AUTOCONF_VERSION],\n  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl\n_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])\n\n# Figure out how to run the assembler.                      -*- Autoconf -*-\n\n# Copyright (C) 2001, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 5\n\n# AM_PROG_AS\n# ----------\nAC_DEFUN([AM_PROG_AS],\n[# By default we simply use the C compiler to build assembly code.\nAC_REQUIRE([AC_PROG_CC])\ntest \"${CCAS+set}\" = set || CCAS=$CC\ntest \"${CCASFLAGS+set}\" = set || CCASFLAGS=$CFLAGS\nAC_ARG_VAR([CCAS],      [assembler compiler command (defaults to CC)])\nAC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)])\n_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl\n])\n\n# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-\n\n# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 1\n\n# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets\n# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to\n# `$srcdir', `$srcdir/..', or `$srcdir/../..'.\n#\n# Of course, Automake must honor this variable whenever it calls a\n# tool from the auxiliary directory.  The problem is that $srcdir (and\n# therefore $ac_aux_dir as well) can be either absolute or relative,\n# depending on how configure is run.  This is pretty annoying, since\n# it makes $ac_aux_dir quite unusable in subdirectories: in the top\n# source directory, any form will work fine, but in subdirectories a\n# relative path needs to be adjusted first.\n#\n# $ac_aux_dir/missing\n#    fails when called from a subdirectory if $ac_aux_dir is relative\n# $top_srcdir/$ac_aux_dir/missing\n#    fails if $ac_aux_dir is absolute,\n#    fails when called from a subdirectory in a VPATH build with\n#          a relative $ac_aux_dir\n#\n# The reason of the latter failure is that $top_srcdir and $ac_aux_dir\n# are both prefixed by $srcdir.  In an in-source build this is usually\n# harmless because $srcdir is `.', but things will broke when you\n# start a VPATH build or use an absolute $srcdir.\n#\n# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,\n# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:\n#   am_aux_dir='\\$(top_srcdir)/'`expr \"$ac_aux_dir\" : \"$srcdir//*\\(.*\\)\"`\n# and then we would define $MISSING as\n#   MISSING=\"\\${SHELL} $am_aux_dir/missing\"\n# This will work as long as MISSING is not called from configure, because\n# unfortunately $(top_srcdir) has no meaning in configure.\n# However there are other variables, like CC, which are often used in\n# configure, and could therefore not use this \"fixed\" $ac_aux_dir.\n#\n# Another solution, used here, is to always expand $ac_aux_dir to an\n# absolute PATH.  The drawback is that using absolute paths prevent a\n# configured tree to be moved without reconfiguration.\n\nAC_DEFUN([AM_AUX_DIR_EXPAND],\n[dnl Rely on autoconf to set up CDPATH properly.\nAC_PREREQ([2.50])dnl\n# expand $ac_aux_dir to an absolute path\nam_aux_dir=`cd $ac_aux_dir && pwd`\n])\n\n# AM_CONDITIONAL                                            -*- Autoconf -*-\n\n# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008\n# Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 9\n\n# AM_CONDITIONAL(NAME, SHELL-CONDITION)\n# -------------------------------------\n# Define a conditional.\nAC_DEFUN([AM_CONDITIONAL],\n[AC_PREREQ(2.52)dnl\n ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],\n\t[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl\nAC_SUBST([$1_TRUE])dnl\nAC_SUBST([$1_FALSE])dnl\n_AM_SUBST_NOTMAKE([$1_TRUE])dnl\n_AM_SUBST_NOTMAKE([$1_FALSE])dnl\nm4_define([_AM_COND_VALUE_$1], [$2])dnl\nif $2; then\n  $1_TRUE=\n  $1_FALSE='#'\nelse\n  $1_TRUE='#'\n  $1_FALSE=\nfi\nAC_CONFIG_COMMANDS_PRE(\n[if test -z \"${$1_TRUE}\" && test -z \"${$1_FALSE}\"; then\n  AC_MSG_ERROR([[conditional \"$1\" was never defined.\nUsually this means the macro was only invoked conditionally.]])\nfi])])\n\n# Do all the work for Automake.                             -*- Autoconf -*-\n\n# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,\n# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 16\n\n# This macro actually does too much.  Some checks are only needed if\n# your package does certain things.  But this isn't really a big deal.\n\n# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])\n# AM_INIT_AUTOMAKE([OPTIONS])\n# -----------------------------------------------\n# The call with PACKAGE and VERSION arguments is the old style\n# call (pre autoconf-2.50), which is being phased out.  PACKAGE\n# and VERSION should now be passed to AC_INIT and removed from\n# the call to AM_INIT_AUTOMAKE.\n# We support both call styles for the transition.  After\n# the next Automake release, Autoconf can make the AC_INIT\n# arguments mandatory, and then we can depend on a new Autoconf\n# release and drop the old call support.\nAC_DEFUN([AM_INIT_AUTOMAKE],\n[AC_PREREQ([2.62])dnl\ndnl Autoconf wants to disallow AM_ names.  We explicitly allow\ndnl the ones we care about.\nm4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl\nAC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl\nAC_REQUIRE([AC_PROG_INSTALL])dnl\nif test \"`cd $srcdir && pwd`\" != \"`pwd`\"; then\n  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output\n  # is not polluted with repeated \"-I.\"\n  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl\n  # test to see if srcdir already configured\n  if test -f $srcdir/config.status; then\n    AC_MSG_ERROR([source directory already configured; run \"make distclean\" there first])\n  fi\nfi\n\n# test whether we have cygpath\nif test -z \"$CYGPATH_W\"; then\n  if (cygpath --version) >/dev/null 2>/dev/null; then\n    CYGPATH_W='cygpath -w'\n  else\n    CYGPATH_W=echo\n  fi\nfi\nAC_SUBST([CYGPATH_W])\n\n# Define the identity of the package.\ndnl Distinguish between old-style and new-style calls.\nm4_ifval([$2],\n[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl\n AC_SUBST([PACKAGE], [$1])dnl\n AC_SUBST([VERSION], [$2])],\n[_AM_SET_OPTIONS([$1])dnl\ndnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.\nm4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,\n  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl\n AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl\n AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl\n\n_AM_IF_OPTION([no-define],,\n[AC_DEFINE_UNQUOTED(PACKAGE, \"$PACKAGE\", [Name of package])\n AC_DEFINE_UNQUOTED(VERSION, \"$VERSION\", [Version number of package])])dnl\n\n# Some tools Automake needs.\nAC_REQUIRE([AM_SANITY_CHECK])dnl\nAC_REQUIRE([AC_ARG_PROGRAM])dnl\nAM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})\nAM_MISSING_PROG(AUTOCONF, autoconf)\nAM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})\nAM_MISSING_PROG(AUTOHEADER, autoheader)\nAM_MISSING_PROG(MAKEINFO, makeinfo)\nAC_REQUIRE([AM_PROG_INSTALL_SH])dnl\nAC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl\nAC_REQUIRE([AM_PROG_MKDIR_P])dnl\n# We need awk for the \"check\" target.  The system \"awk\" is bad on\n# some platforms.\nAC_REQUIRE([AC_PROG_AWK])dnl\nAC_REQUIRE([AC_PROG_MAKE_SET])dnl\nAC_REQUIRE([AM_SET_LEADING_DOT])dnl\n_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],\n\t      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],\n\t\t\t     [_AM_PROG_TAR([v7])])])\n_AM_IF_OPTION([no-dependencies],,\n[AC_PROVIDE_IFELSE([AC_PROG_CC],\n\t\t  [_AM_DEPENDENCIES(CC)],\n\t\t  [define([AC_PROG_CC],\n\t\t\t  defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl\nAC_PROVIDE_IFELSE([AC_PROG_CXX],\n\t\t  [_AM_DEPENDENCIES(CXX)],\n\t\t  [define([AC_PROG_CXX],\n\t\t\t  defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl\nAC_PROVIDE_IFELSE([AC_PROG_OBJC],\n\t\t  [_AM_DEPENDENCIES(OBJC)],\n\t\t  [define([AC_PROG_OBJC],\n\t\t\t  defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl\n])\n_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl\ndnl The `parallel-tests' driver may need to know about EXEEXT, so add the\ndnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This macro\ndnl is hooked onto _AC_COMPILER_EXEEXT early, see below.\nAC_CONFIG_COMMANDS_PRE(dnl\n[m4_provide_if([_AM_COMPILER_EXEEXT],\n  [AM_CONDITIONAL([am__EXEEXT], [test -n \"$EXEEXT\"])])])dnl\n])\n\ndnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not\ndnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further\ndnl mangled by Autoconf and run in a shell conditional statement.\nm4_define([_AC_COMPILER_EXEEXT],\nm4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])\n\n\n# When config.status generates a header, we must update the stamp-h file.\n# This file resides in the same directory as the config header\n# that is generated.  The stamp files are numbered to have different names.\n\n# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the\n# loop where config.status creates the headers, so we can generate\n# our stamp files there.\nAC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],\n[# Compute $1's index in $config_headers.\n_am_arg=$1\n_am_stamp_count=1\nfor _am_header in $config_headers :; do\n  case $_am_header in\n    $_am_arg | $_am_arg:* )\n      break ;;\n    * )\n      _am_stamp_count=`expr $_am_stamp_count + 1` ;;\n  esac\ndone\necho \"timestamp for $_am_arg\" >`AS_DIRNAME([\"$_am_arg\"])`/stamp-h[]$_am_stamp_count])\n\n# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,\n# Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 1\n\n# AM_PROG_INSTALL_SH\n# ------------------\n# Define $install_sh.\nAC_DEFUN([AM_PROG_INSTALL_SH],\n[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl\nif test x\"${install_sh}\" != xset; then\n  case $am_aux_dir in\n  *\\ * | *\\\t*)\n    install_sh=\"\\${SHELL} '$am_aux_dir/install-sh'\" ;;\n  *)\n    install_sh=\"\\${SHELL} $am_aux_dir/install-sh\"\n  esac\nfi\nAC_SUBST(install_sh)])\n\n# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-\n# From Jim Meyering\n\n# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008,\n# 2011 Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 5\n\n# AM_MAINTAINER_MODE([DEFAULT-MODE])\n# ----------------------------------\n# Control maintainer-specific portions of Makefiles.\n# Default is to disable them, unless `enable' is passed literally.\n# For symmetry, `disable' may be passed as well.  Anyway, the user\n# can override the default with the --enable/--disable switch.\nAC_DEFUN([AM_MAINTAINER_MODE],\n[m4_case(m4_default([$1], [disable]),\n       [enable], [m4_define([am_maintainer_other], [disable])],\n       [disable], [m4_define([am_maintainer_other], [enable])],\n       [m4_define([am_maintainer_other], [enable])\n        m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])\nAC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])\n  dnl maintainer-mode's default is 'disable' unless 'enable' is passed\n  AC_ARG_ENABLE([maintainer-mode],\n[  --][am_maintainer_other][-maintainer-mode  am_maintainer_other make rules and dependencies not useful\n\t\t\t  (and sometimes confusing) to the casual installer],\n      [USE_MAINTAINER_MODE=$enableval],\n      [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))\n  AC_MSG_RESULT([$USE_MAINTAINER_MODE])\n  AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])\n  MAINT=$MAINTAINER_MODE_TRUE\n  AC_SUBST([MAINT])dnl\n]\n)\n\nAU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])\n\n# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-\n\n# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008\n# Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 6\n\n# AM_MISSING_PROG(NAME, PROGRAM)\n# ------------------------------\nAC_DEFUN([AM_MISSING_PROG],\n[AC_REQUIRE([AM_MISSING_HAS_RUN])\n$1=${$1-\"${am_missing_run}$2\"}\nAC_SUBST($1)])\n\n\n# AM_MISSING_HAS_RUN\n# ------------------\n# Define MISSING if not defined so far and test if it supports --run.\n# If it does, set am_missing_run to use it, otherwise, to nothing.\nAC_DEFUN([AM_MISSING_HAS_RUN],\n[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl\nAC_REQUIRE_AUX_FILE([missing])dnl\nif test x\"${MISSING+set}\" != xset; then\n  case $am_aux_dir in\n  *\\ * | *\\\t*)\n    MISSING=\"\\${SHELL} \\\"$am_aux_dir/missing\\\"\" ;;\n  *)\n    MISSING=\"\\${SHELL} $am_aux_dir/missing\" ;;\n  esac\nfi\n# Use eval to expand $SHELL\nif eval \"$MISSING --run true\"; then\n  am_missing_run=\"$MISSING --run \"\nelse\n  am_missing_run=\n  AC_MSG_WARN([`missing' script is too old or missing])\nfi\n])\n\n# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,\n# Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 1\n\n# AM_PROG_MKDIR_P\n# ---------------\n# Check for `mkdir -p'.\nAC_DEFUN([AM_PROG_MKDIR_P],\n[AC_PREREQ([2.60])dnl\nAC_REQUIRE([AC_PROG_MKDIR_P])dnl\ndnl Automake 1.8 to 1.9.6 used to define mkdir_p.  We now use MKDIR_P,\ndnl while keeping a definition of mkdir_p for backward compatibility.\ndnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.\ndnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of\ndnl Makefile.ins that do not define MKDIR_P, so we do our own\ndnl adjustment using top_builddir (which is defined more often than\ndnl MKDIR_P).\nAC_SUBST([mkdir_p], [\"$MKDIR_P\"])dnl\ncase $mkdir_p in\n  [[\\\\/$]]* | ?:[[\\\\/]]*) ;;\n  */*) mkdir_p=\"\\$(top_builddir)/$mkdir_p\" ;;\nesac\n])\n\n# Helper functions for option handling.                     -*- Autoconf -*-\n\n# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software\n# Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 5\n\n# _AM_MANGLE_OPTION(NAME)\n# -----------------------\nAC_DEFUN([_AM_MANGLE_OPTION],\n[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])\n\n# _AM_SET_OPTION(NAME)\n# --------------------\n# Set option NAME.  Presently that only means defining a flag for this option.\nAC_DEFUN([_AM_SET_OPTION],\n[m4_define(_AM_MANGLE_OPTION([$1]), 1)])\n\n# _AM_SET_OPTIONS(OPTIONS)\n# ------------------------\n# OPTIONS is a space-separated list of Automake options.\nAC_DEFUN([_AM_SET_OPTIONS],\n[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])\n\n# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])\n# -------------------------------------------\n# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.\nAC_DEFUN([_AM_IF_OPTION],\n[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])\n\n# Check to make sure that the build environment is sane.    -*- Autoconf -*-\n\n# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008\n# Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 5\n\n# AM_SANITY_CHECK\n# ---------------\nAC_DEFUN([AM_SANITY_CHECK],\n[AC_MSG_CHECKING([whether build environment is sane])\n# Just in case\nsleep 1\necho timestamp > conftest.file\n# Reject unsafe characters in $srcdir or the absolute working directory\n# name.  Accept space and tab only in the latter.\nam_lf='\n'\ncase `pwd` in\n  *[[\\\\\\\"\\#\\$\\&\\'\\`$am_lf]]*)\n    AC_MSG_ERROR([unsafe absolute working directory name]);;\nesac\ncase $srcdir in\n  *[[\\\\\\\"\\#\\$\\&\\'\\`$am_lf\\ \\\t]]*)\n    AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;\nesac\n\n# Do `set' in a subshell so we don't clobber the current shell's\n# arguments.  Must try -L first in case configure is actually a\n# symlink; some systems play weird games with the mod time of symlinks\n# (eg FreeBSD returns the mod time of the symlink's containing\n# directory).\nif (\n   set X `ls -Lt \"$srcdir/configure\" conftest.file 2> /dev/null`\n   if test \"$[*]\" = \"X\"; then\n      # -L didn't work.\n      set X `ls -t \"$srcdir/configure\" conftest.file`\n   fi\n   rm -f conftest.file\n   if test \"$[*]\" != \"X $srcdir/configure conftest.file\" \\\n      && test \"$[*]\" != \"X conftest.file $srcdir/configure\"; then\n\n      # If neither matched, then we have a broken ls.  This can happen\n      # if, for instance, CONFIG_SHELL is bash and it inherits a\n      # broken ls alias from the environment.  This has actually\n      # happened.  Such a system could not be considered \"sane\".\n      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken\nalias in your environment])\n   fi\n\n   test \"$[2]\" = conftest.file\n   )\nthen\n   # Ok.\n   :\nelse\n   AC_MSG_ERROR([newly created file is older than distributed files!\nCheck your system clock])\nfi\nAC_MSG_RESULT(yes)])\n\n# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 1\n\n# AM_PROG_INSTALL_STRIP\n# ---------------------\n# One issue with vendor `install' (even GNU) is that you can't\n# specify the program used to strip binaries.  This is especially\n# annoying in cross-compiling environments, where the build's strip\n# is unlikely to handle the host's binaries.\n# Fortunately install-sh will honor a STRIPPROG variable, so we\n# always use install-sh in `make install-strip', and initialize\n# STRIPPROG with the value of the STRIP variable (set by the user).\nAC_DEFUN([AM_PROG_INSTALL_STRIP],\n[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl\n# Installed binaries are usually stripped using `strip' when the user\n# run `make install-strip'.  However `strip' might not be the right\n# tool to use in cross-compilation environments, therefore Automake\n# will honor the `STRIP' environment variable to overrule this program.\ndnl Don't test for $cross_compiling = yes, because it might be `maybe'.\nif test \"$cross_compiling\" != no; then\n  AC_CHECK_TOOL([STRIP], [strip], :)\nfi\nINSTALL_STRIP_PROGRAM=\"\\$(install_sh) -c -s\"\nAC_SUBST([INSTALL_STRIP_PROGRAM])])\n\n# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 3\n\n# _AM_SUBST_NOTMAKE(VARIABLE)\n# ---------------------------\n# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.\n# This macro is traced by Automake.\nAC_DEFUN([_AM_SUBST_NOTMAKE])\n\n# AM_SUBST_NOTMAKE(VARIABLE)\n# --------------------------\n# Public sister of _AM_SUBST_NOTMAKE.\nAC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])\n\n# Check how to create a tarball.                            -*- Autoconf -*-\n\n# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 2\n\n# _AM_PROG_TAR(FORMAT)\n# --------------------\n# Check how to create a tarball in format FORMAT.\n# FORMAT should be one of `v7', `ustar', or `pax'.\n#\n# Substitute a variable $(am__tar) that is a command\n# writing to stdout a FORMAT-tarball containing the directory\n# $tardir.\n#     tardir=directory && $(am__tar) > result.tar\n#\n# Substitute a variable $(am__untar) that extract such\n# a tarball read from stdin.\n#     $(am__untar) < result.tar\nAC_DEFUN([_AM_PROG_TAR],\n[# Always define AMTAR for backward compatibility.  Yes, it's still used\n# in the wild :-(  We should find a proper way to deprecate it ...\nAC_SUBST([AMTAR], ['$${TAR-tar}'])\nm4_if([$1], [v7],\n     [am__tar='$${TAR-tar} chof - \"$$tardir\"' am__untar='$${TAR-tar} xf -'],\n     [m4_case([$1], [ustar],, [pax],,\n              [m4_fatal([Unknown tar format])])\nAC_MSG_CHECKING([how to create a $1 tar archive])\n# Loop over all known methods to create a tar archive until one works.\n_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'\n_am_tools=${am_cv_prog_tar_$1-$_am_tools}\n# Do not fold the above two line into one, because Tru64 sh and\n# Solaris sh will not grok spaces in the rhs of `-'.\nfor _am_tool in $_am_tools\ndo\n  case $_am_tool in\n  gnutar)\n    for _am_tar in tar gnutar gtar;\n    do\n      AM_RUN_LOG([$_am_tar --version]) && break\n    done\n    am__tar=\"$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - \"'\"$$tardir\"'\n    am__tar_=\"$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - \"'\"$tardir\"'\n    am__untar=\"$_am_tar -xf -\"\n    ;;\n  plaintar)\n    # Must skip GNU tar: if it does not support --format= it doesn't create\n    # ustar tarball either.\n    (tar --version) >/dev/null 2>&1 && continue\n    am__tar='tar chf - \"$$tardir\"'\n    am__tar_='tar chf - \"$tardir\"'\n    am__untar='tar xf -'\n    ;;\n  pax)\n    am__tar='pax -L -x $1 -w \"$$tardir\"'\n    am__tar_='pax -L -x $1 -w \"$tardir\"'\n    am__untar='pax -r'\n    ;;\n  cpio)\n    am__tar='find \"$$tardir\" -print | cpio -o -H $1 -L'\n    am__tar_='find \"$tardir\" -print | cpio -o -H $1 -L'\n    am__untar='cpio -i -H $1 -d'\n    ;;\n  none)\n    am__tar=false\n    am__tar_=false\n    am__untar=false\n    ;;\n  esac\n\n  # If the value was cached, stop now.  We just wanted to have am__tar\n  # and am__untar set.\n  test -n \"${am_cv_prog_tar_$1}\" && break\n\n  # tar/untar a dummy directory, and stop if the command works\n  rm -rf conftest.dir\n  mkdir conftest.dir\n  echo GrepMe > conftest.dir/file\n  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])\n  rm -rf conftest.dir\n  if test -s conftest.tar; then\n    AM_RUN_LOG([$am__untar <conftest.tar])\n    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break\n  fi\ndone\nrm -rf conftest.dir\n\nAC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])\nAC_MSG_RESULT([$am_cv_prog_tar_$1])])\nAC_SUBST([am__tar])\nAC_SUBST([am__untar])\n]) # _AM_PROG_TAR\n\nm4_include([../config/acx.m4])\nm4_include([../config/lead-dot.m4])\nm4_include([../config/multi.m4])\nm4_include([../config/override.m4])\nm4_include([../libtool.m4])\nm4_include([../ltoptions.m4])\nm4_include([../ltsugar.m4])\nm4_include([../ltversion.m4])\nm4_include([../lt~obsolete.m4])\nm4_include([acinclude.m4])\n"
  },
  {
    "path": "libphobos/config.h.in",
    "content": "/* config.h.in.  Generated from configure.ac by autoheader.  */\n\n/* Define to 1 if you have the <dlfcn.h> header file. */\n#undef HAVE_DLFCN_H\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n#undef HAVE_INTTYPES_H\n\n/* Define to 1 if you have the <memory.h> header file. */\n#undef HAVE_MEMORY_H\n\n/* Define to 1 if you have the <stdint.h> header file. */\n#undef HAVE_STDINT_H\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n#undef HAVE_STDLIB_H\n\n/* Define to 1 if you have the <strings.h> header file. */\n#undef HAVE_STRINGS_H\n\n/* Define to 1 if you have the <string.h> header file. */\n#undef HAVE_STRING_H\n\n/* Define to 1 if you have the <sys/stat.h> header file. */\n#undef HAVE_SYS_STAT_H\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#undef HAVE_SYS_TYPES_H\n\n/* Define to 1 if you have the <unistd.h> header file. */\n#undef HAVE_UNISTD_H\n\n/* Define to the sub-directory in which libtool stores uninstalled libraries.\n   */\n#undef LT_OBJDIR\n\n/* Define to the address where bug reports for this package should be sent. */\n#undef PACKAGE_BUGREPORT\n\n/* Define to the full name of this package. */\n#undef PACKAGE_NAME\n\n/* Define to the full name and version of this package. */\n#undef PACKAGE_STRING\n\n/* Define to the one symbol short name of this package. */\n#undef PACKAGE_TARNAME\n\n/* Define to the home page for this package. */\n#undef PACKAGE_URL\n\n/* Define to the version of this package. */\n#undef PACKAGE_VERSION\n\n/* Define to 1 if you have the ANSI C header files. */\n#undef STDC_HEADERS\n"
  },
  {
    "path": "libphobos/configure",
    "content": "#! /bin/sh\n# Guess values for system-dependent variables and create Makefiles.\n# Generated by GNU Autoconf 2.64 for package-unused version-unused.\n#\n# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,\n# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software\n# Foundation, Inc.\n#\n# This configure script is free software; the Free Software Foundation\n# gives unlimited permission to copy, distribute and modify it.\n## -------------------- ##\n## M4sh Initialization. ##\n## -------------------- ##\n\n# Be more Bourne compatible\nDUALCASE=1; export DUALCASE # for MKS sh\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\n  setopt NO_GLOB_SUBST\nelse\n  case `(set -o) 2>/dev/null` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\n\nas_nl='\n'\nexport as_nl\n# Printing a long string crashes Solaris 7 /usr/bin/printf.\nas_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo\n# Prefer a ksh shell builtin over an external printf program on Solaris,\n# but without wasting forks for bash or zsh.\nif test -z \"$BASH_VERSION$ZSH_VERSION\" \\\n    && (test \"X`print -r -- $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='print -r --'\n  as_echo_n='print -rn --'\nelif (test \"X`printf %s $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='printf %s\\n'\n  as_echo_n='printf %s'\nelse\n  if test \"X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`\" = \"X-n $as_echo\"; then\n    as_echo_body='eval /usr/ucb/echo -n \"$1$as_nl\"'\n    as_echo_n='/usr/ucb/echo -n'\n  else\n    as_echo_body='eval expr \"X$1\" : \"X\\\\(.*\\\\)\"'\n    as_echo_n_body='eval\n      arg=$1;\n      case $arg in #(\n      *\"$as_nl\"*)\n\texpr \"X$arg\" : \"X\\\\(.*\\\\)$as_nl\";\n\targ=`expr \"X$arg\" : \".*$as_nl\\\\(.*\\\\)\"`;;\n      esac;\n      expr \"X$arg\" : \"X\\\\(.*\\\\)\" | tr -d \"$as_nl\"\n    '\n    export as_echo_n_body\n    as_echo_n='sh -c $as_echo_n_body as_echo'\n  fi\n  export as_echo_body\n  as_echo='sh -c $as_echo_body as_echo'\nfi\n\n# The user is always right.\nif test \"${PATH_SEPARATOR+set}\" != set; then\n  PATH_SEPARATOR=:\n  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {\n    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||\n      PATH_SEPARATOR=';'\n  }\nfi\n\n\n# IFS\n# We need space, tab and new line, in precisely that order.  Quoting is\n# there to prevent editors from complaining about space-tab.\n# (If _AS_PATH_WALK were called with IFS unset, it would disable word\n# splitting by setting IFS to empty value.)\nIFS=\" \"\"\t$as_nl\"\n\n# Find who we are.  Look in the path if we contain no directory separator.\ncase $0 in #((\n  *[\\\\/]* ) as_myself=$0 ;;\n  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    test -r \"$as_dir/$0\" && as_myself=$as_dir/$0 && break\n  done\nIFS=$as_save_IFS\n\n     ;;\nesac\n# We did not find ourselves, most probably we were run as `sh COMMAND'\n# in which case we are not to be found in the path.\nif test \"x$as_myself\" = x; then\n  as_myself=$0\nfi\nif test ! -f \"$as_myself\"; then\n  $as_echo \"$as_myself: error: cannot find myself; rerun with an absolute file name\" >&2\n  exit 1\nfi\n\n# Unset variables that we do not need and which cause bugs (e.g. in\n# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the \"|| exit 1\"\n# suppresses any \"Segmentation fault\" message there.  '((' could\n# trigger a bug in pdksh 5.2.14.\nfor as_var in BASH_ENV ENV MAIL MAILPATH\ndo eval test x\\${$as_var+set} = xset \\\n  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :\ndone\nPS1='$ '\nPS2='> '\nPS4='+ '\n\n# NLS nuisances.\nLC_ALL=C\nexport LC_ALL\nLANGUAGE=C\nexport LANGUAGE\n\n# CDPATH.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\nif test \"x$CONFIG_SHELL\" = x; then\n  as_bourne_compatible=\"if test -n \\\"\\${ZSH_VERSION+set}\\\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on \\${1+\\\"\\$@\\\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '\\${1+\\\"\\$@\\\"}'='\\\"\\$@\\\"'\n  setopt NO_GLOB_SUBST\nelse\n  case \\`(set -o) 2>/dev/null\\` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\"\n  as_required=\"as_fn_return () { (exit \\$1); }\nas_fn_success () { as_fn_return 0; }\nas_fn_failure () { as_fn_return 1; }\nas_fn_ret_success () { return 0; }\nas_fn_ret_failure () { return 1; }\n\nexitcode=0\nas_fn_success || { exitcode=1; echo as_fn_success failed.; }\nas_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }\nas_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }\nas_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }\nif ( set x; as_fn_ret_success y && test x = \\\"\\$1\\\" ); then :\n\nelse\n  exitcode=1; echo positional parameters were not saved.\nfi\ntest x\\$exitcode = x0 || exit 1\"\n  as_suggested=\"  as_lineno_1=\";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested\" as_lineno_1a=\\$LINENO\n  as_lineno_2=\";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested\" as_lineno_2a=\\$LINENO\n  eval 'test \\\"x\\$as_lineno_1'\\$as_run'\\\" != \\\"x\\$as_lineno_2'\\$as_run'\\\" &&\n  test \\\"x\\`expr \\$as_lineno_1'\\$as_run' + 1\\`\\\" = \\\"x\\$as_lineno_2'\\$as_run'\\\"' || exit 1\n\n  test -n \\\"\\${ZSH_VERSION+set}\\${BASH_VERSION+set}\\\" || (\n    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\n    ECHO=\\$ECHO\\$ECHO\\$ECHO\\$ECHO\\$ECHO\n    ECHO=\\$ECHO\\$ECHO\\$ECHO\\$ECHO\\$ECHO\\$ECHO\n    PATH=/empty FPATH=/empty; export PATH FPATH\n    test \\\"X\\`printf %s \\$ECHO\\`\\\" = \\\"X\\$ECHO\\\" \\\\\n      || test \\\"X\\`print -r -- \\$ECHO\\`\\\" = \\\"X\\$ECHO\\\" ) || exit 1\ntest \\$(( 1 + 1 )) = 2 || exit 1\"\n  if (eval \"$as_required\") 2>/dev/null; then :\n  as_have_required=yes\nelse\n  as_have_required=no\nfi\n  if test x$as_have_required = xyes && (eval \"$as_suggested\") 2>/dev/null; then :\n\nelse\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nas_found=false\nfor as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  as_found=:\n  case $as_dir in #(\n\t /*)\n\t   for as_base in sh bash ksh sh5; do\n\t     # Try only shells that exist, to save several forks.\n\t     as_shell=$as_dir/$as_base\n\t     if { test -f \"$as_shell\" || test -f \"$as_shell.exe\"; } &&\n\t\t    { $as_echo \"$as_bourne_compatible\"\"$as_required\" | as_run=a \"$as_shell\"; } 2>/dev/null; then :\n  CONFIG_SHELL=$as_shell as_have_required=yes\n\t\t   if { $as_echo \"$as_bourne_compatible\"\"$as_suggested\" | as_run=a \"$as_shell\"; } 2>/dev/null; then :\n  break 2\nfi\nfi\n\t   done;;\n       esac\n  as_found=false\ndone\n$as_found || { if { test -f \"$SHELL\" || test -f \"$SHELL.exe\"; } &&\n\t      { $as_echo \"$as_bourne_compatible\"\"$as_required\" | as_run=a \"$SHELL\"; } 2>/dev/null; then :\n  CONFIG_SHELL=$SHELL as_have_required=yes\nfi; }\nIFS=$as_save_IFS\n\n\n      if test \"x$CONFIG_SHELL\" != x; then :\n  # We cannot yet assume a decent shell, so we have to provide a\n\t# neutralization value for shells without unset; and this also\n\t# works around shells that cannot unset nonexistent variables.\n\tBASH_ENV=/dev/null\n\tENV=/dev/null\n\t(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV\n\texport CONFIG_SHELL\n\texec \"$CONFIG_SHELL\" \"$as_myself\" ${1+\"$@\"}\nfi\n\n    if test x$as_have_required = xno; then :\n  $as_echo \"$0: This script requires a shell more modern than all\"\n  $as_echo \"$0: the shells that I found on your system.\"\n  if test x${ZSH_VERSION+set} = xset ; then\n    $as_echo \"$0: In particular, zsh $ZSH_VERSION has bugs and should\"\n    $as_echo \"$0: be upgraded to zsh 4.3.4 or later.\"\n  else\n    $as_echo \"$0: Please tell bug-autoconf@gnu.org about your system,\n$0: including any error possibly output before this\n$0: message. Then install a modern shell, or manually run\n$0: the script under such a shell if you do have one.\"\n  fi\n  exit 1\nfi\nfi\nfi\nSHELL=${CONFIG_SHELL-/bin/sh}\nexport SHELL\n# Unset more variables known to interfere with behavior of common tools.\nCLICOLOR_FORCE= GREP_OPTIONS=\nunset CLICOLOR_FORCE GREP_OPTIONS\n\n## --------------------- ##\n## M4sh Shell Functions. ##\n## --------------------- ##\n# as_fn_unset VAR\n# ---------------\n# Portably unset VAR.\nas_fn_unset ()\n{\n  { eval $1=; unset $1;}\n}\nas_unset=as_fn_unset\n\n# as_fn_set_status STATUS\n# -----------------------\n# Set $? to STATUS, without forking.\nas_fn_set_status ()\n{\n  return $1\n} # as_fn_set_status\n\n# as_fn_exit STATUS\n# -----------------\n# Exit the shell with STATUS, even in a \"trap 0\" or \"set -e\" context.\nas_fn_exit ()\n{\n  set +e\n  as_fn_set_status $1\n  exit $1\n} # as_fn_exit\n\n# as_fn_mkdir_p\n# -------------\n# Create \"$as_dir\" as a directory, including parents if necessary.\nas_fn_mkdir_p ()\n{\n\n  case $as_dir in #(\n  -*) as_dir=./$as_dir;;\n  esac\n  test -d \"$as_dir\" || eval $as_mkdir_p || {\n    as_dirs=\n    while :; do\n      case $as_dir in #(\n      *\\'*) as_qdir=`$as_echo \"$as_dir\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; #'(\n      *) as_qdir=$as_dir;;\n      esac\n      as_dirs=\"'$as_qdir' $as_dirs\"\n      as_dir=`$as_dirname -- \"$as_dir\" ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n      test -d \"$as_dir\" && break\n    done\n    test -z \"$as_dirs\" || eval \"mkdir $as_dirs\"\n  } || test -d \"$as_dir\" || as_fn_error \"cannot create directory $as_dir\"\n\n\n} # as_fn_mkdir_p\n# as_fn_append VAR VALUE\n# ----------------------\n# Append the text in VALUE to the end of the definition contained in VAR. Take\n# advantage of any shell optimizations that allow amortized linear growth over\n# repeated appends, instead of the typical quadratic growth present in naive\n# implementations.\nif (eval \"as_var=1; as_var+=2; test x\\$as_var = x12\") 2>/dev/null; then :\n  eval 'as_fn_append ()\n  {\n    eval $1+=\\$2\n  }'\nelse\n  as_fn_append ()\n  {\n    eval $1=\\$$1\\$2\n  }\nfi # as_fn_append\n\n# as_fn_arith ARG...\n# ------------------\n# Perform arithmetic evaluation on the ARGs, and store the result in the\n# global $as_val. Take advantage of shells that can avoid forks. The arguments\n# must be portable across $(()) and expr.\nif (eval \"test \\$(( 1 + 1 )) = 2\") 2>/dev/null; then :\n  eval 'as_fn_arith ()\n  {\n    as_val=$(( $* ))\n  }'\nelse\n  as_fn_arith ()\n  {\n    as_val=`expr \"$@\" || test $? -eq 1`\n  }\nfi # as_fn_arith\n\n\n# as_fn_error ERROR [LINENO LOG_FD]\n# ---------------------------------\n# Output \"`basename $0`: error: ERROR\" to stderr. If LINENO and LOG_FD are\n# provided, also output the error to LOG_FD, referencing LINENO. Then exit the\n# script with status $?, using 1 if that was 0.\nas_fn_error ()\n{\n  as_status=$?; test $as_status -eq 0 && as_status=1\n  if test \"$3\"; then\n    as_lineno=${as_lineno-\"$2\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n    $as_echo \"$as_me:${as_lineno-$LINENO}: error: $1\" >&$3\n  fi\n  $as_echo \"$as_me: error: $1\" >&2\n  as_fn_exit $as_status\n} # as_fn_error\n\nif expr a : '\\(a\\)' >/dev/null 2>&1 &&\n   test \"X`expr 00001 : '.*\\(...\\)'`\" = X001; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nif (basename -- /) >/dev/null 2>&1 && test \"X`basename -- / 2>&1`\" = \"X/\"; then\n  as_basename=basename\nelse\n  as_basename=false\nfi\n\nif (as_dir=`dirname -- /` && test \"X$as_dir\" = X/) >/dev/null 2>&1; then\n  as_dirname=dirname\nelse\n  as_dirname=false\nfi\n\nas_me=`$as_basename -- \"$0\" ||\n$as_expr X/\"$0\" : '.*/\\([^/][^/]*\\)/*$' \\| \\\n\t X\"$0\" : 'X\\(//\\)$' \\| \\\n\t X\"$0\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X/\"$0\" |\n    sed '/^.*\\/\\([^/][^/]*\\)\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n\n# Avoid depending upon Character Ranges.\nas_cr_letters='abcdefghijklmnopqrstuvwxyz'\nas_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nas_cr_Letters=$as_cr_letters$as_cr_LETTERS\nas_cr_digits='0123456789'\nas_cr_alnum=$as_cr_Letters$as_cr_digits\n\n\n  as_lineno_1=$LINENO as_lineno_1a=$LINENO\n  as_lineno_2=$LINENO as_lineno_2a=$LINENO\n  eval 'test \"x$as_lineno_1'$as_run'\" != \"x$as_lineno_2'$as_run'\" &&\n  test \"x`expr $as_lineno_1'$as_run' + 1`\" = \"x$as_lineno_2'$as_run'\"' || {\n  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)\n  sed -n '\n    p\n    /[$]LINENO/=\n  ' <$as_myself |\n    sed '\n      s/[$]LINENO.*/&-/\n      t lineno\n      b\n      :lineno\n      N\n      :loop\n      s/[$]LINENO\\([^'$as_cr_alnum'_].*\\n\\)\\(.*\\)/\\2\\1\\2/\n      t loop\n      s/-\\n.*//\n    ' >$as_me.lineno &&\n  chmod +x \"$as_me.lineno\" ||\n    { $as_echo \"$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell\" >&2; as_fn_exit 1; }\n\n  # Don't try to exec as it changes $[0], causing all sort of problems\n  # (the dirname of $[0] is not the place where we might find the\n  # original and so on.  Autoconf is especially sensitive to this).\n  . \"./$as_me.lineno\"\n  # Exit status is that of the last command.\n  exit\n}\n\nECHO_C= ECHO_N= ECHO_T=\ncase `echo -n x` in #(((((\n-n*)\n  case `echo 'xy\\c'` in\n  *c*) ECHO_T='\t';;\t# ECHO_T is single tab character.\n  xy)  ECHO_C='\\c';;\n  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null\n       ECHO_T='\t';;\n  esac;;\n*)\n  ECHO_N='-n';;\nesac\n\nrm -f conf$$ conf$$.exe conf$$.file\nif test -d conf$$.dir; then\n  rm -f conf$$.dir/conf$$.file\nelse\n  rm -f conf$$.dir\n  mkdir conf$$.dir 2>/dev/null\nfi\nif (echo >conf$$.file) 2>/dev/null; then\n  if ln -s conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s='ln -s'\n    # ... but there are two gotchas:\n    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.\n    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.\n    # In both cases, we have to default to `cp -p'.\n    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||\n      as_ln_s='cp -p'\n  elif ln conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s=ln\n  else\n    as_ln_s='cp -p'\n  fi\nelse\n  as_ln_s='cp -p'\nfi\nrm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file\nrmdir conf$$.dir 2>/dev/null\n\nif mkdir -p . 2>/dev/null; then\n  as_mkdir_p='mkdir -p \"$as_dir\"'\nelse\n  test -d ./-p && rmdir ./-p\n  as_mkdir_p=false\nfi\n\nif test -x / >/dev/null 2>&1; then\n  as_test_x='test -x'\nelse\n  if ls -dL / >/dev/null 2>&1; then\n    as_ls_L_option=L\n  else\n    as_ls_L_option=\n  fi\n  as_test_x='\n    eval sh -c '\\''\n      if test -d \"$1\"; then\n\ttest -d \"$1/.\";\n      else\n\tcase $1 in #(\n\t-*)set \"./$1\";;\n\tesac;\n\tcase `ls -ld'$as_ls_L_option' \"$1\" 2>/dev/null` in #((\n\t???[sx]*):;;*)false;;esac;fi\n    '\\'' sh\n  '\nfi\nas_executable_p=$as_test_x\n\n# Sed expression to map a string onto a valid CPP name.\nas_tr_cpp=\"eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'\"\n\n# Sed expression to map a string onto a valid variable name.\nas_tr_sh=\"eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'\"\n\nSHELL=${CONFIG_SHELL-/bin/sh}\n\n\nexec 7<&0 </dev/null 6>&1\n\n# Name of the host.\n# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,\n# so uname gets run too.\nac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`\n\n#\n# Initializations.\n#\nac_default_prefix=/usr/local\nac_clean_files=\nac_config_libobj_dir=.\nLIBOBJS=\ncross_compiling=no\nsubdirs=\nMFLAGS=\nMAKEFLAGS=\n\n# Identity of this package.\nPACKAGE_NAME='package-unused'\nPACKAGE_TARNAME='libphobos'\nPACKAGE_VERSION='version-unused'\nPACKAGE_STRING='package-unused version-unused'\nPACKAGE_BUGREPORT=''\nPACKAGE_URL=''\n\nac_unique_file=\"libdruntime/gcc/attribute.d\"\n# Factoring default headers for most tests.\nac_includes_default=\"\\\n#include <stdio.h>\n#ifdef HAVE_SYS_TYPES_H\n# include <sys/types.h>\n#endif\n#ifdef HAVE_SYS_STAT_H\n# include <sys/stat.h>\n#endif\n#ifdef STDC_HEADERS\n# include <stdlib.h>\n# include <stddef.h>\n#else\n# ifdef HAVE_STDLIB_H\n#  include <stdlib.h>\n# endif\n#endif\n#ifdef HAVE_STRING_H\n# if !defined STDC_HEADERS && defined HAVE_MEMORY_H\n#  include <memory.h>\n# endif\n# include <string.h>\n#endif\n#ifdef HAVE_STRINGS_H\n# include <strings.h>\n#endif\n#ifdef HAVE_INTTYPES_H\n# include <inttypes.h>\n#endif\n#ifdef HAVE_STDINT_H\n# include <stdint.h>\n#endif\n#ifdef HAVE_UNISTD_H\n# include <unistd.h>\n#endif\"\n\nac_subst_vars='am__EXEEXT_FALSE\nam__EXEEXT_TRUE\nLTLIBOBJS\nLIBOBJS\nGDCFLAGSX\nPHOBOS_SOVERSION\nDRUNTIME_SOVERSION\nSPEC_PHOBOS_DEPS\ngdc_include_dir\ntoolexeclibdir\ntoolexecdir\ngcc_version\nDRUNTIME_ZLIB_SYSTEM_FALSE\nDRUNTIME_ZLIB_SYSTEM_TRUE\nBACKTRACE_SUPPORTS_THREADS\nBACKTRACE_USES_MALLOC\nBACKTRACE_SUPPORTED\nLIBBACKTRACE\nLIBATOMIC\nDCFG_HAVE_LIBATOMIC\nDCFG_HAVE_64BIT_ATOMICS\nDCFG_HAVE_ATOMIC_BUILTINS\nDCFG_MINFO_BRACKETING\nDRUNTIME_OS_ARM_EABI_UNWINDER_FALSE\nDRUNTIME_OS_ARM_EABI_UNWINDER_TRUE\nDCFG_ARM_EABI_UNWINDER\nDCFG_THREAD_MODEL\nDRUNTIME_OS_SOLARIS_FALSE\nDRUNTIME_OS_SOLARIS_TRUE\nDRUNTIME_OS_MINGW_FALSE\nDRUNTIME_OS_MINGW_TRUE\nDRUNTIME_OS_LINUX_FALSE\nDRUNTIME_OS_LINUX_TRUE\nDRUNTIME_OS_OPENBSD_FALSE\nDRUNTIME_OS_OPENBSD_TRUE\nDRUNTIME_OS_NETBSD_FALSE\nDRUNTIME_OS_NETBSD_TRUE\nDRUNTIME_OS_FREEBSD_FALSE\nDRUNTIME_OS_FREEBSD_TRUE\nDRUNTIME_OS_DRAGONFLYBSD_FALSE\nDRUNTIME_OS_DRAGONFLYBSD_TRUE\nDRUNTIME_OS_DARWIN_FALSE\nDRUNTIME_OS_DARWIN_TRUE\nDRUNTIME_OS_ANDROID_FALSE\nDRUNTIME_OS_ANDROID_TRUE\nDRUNTIME_OS_AIX_FALSE\nDRUNTIME_OS_AIX_TRUE\nDRUNTIME_OS_UNIX_FALSE\nDRUNTIME_OS_UNIX_TRUE\nDRUNTIME_GC_ENABLE_FALSE\nDRUNTIME_GC_ENABLE_TRUE\nlibphobos_srcdir\nlibphobos_builddir\nget_gcc_base_ver\nphobos_compiler_shared_flag\nphobos_compiler_pic_flag\nENABLE_STATIC_FALSE\nENABLE_STATIC_TRUE\nENABLE_SHARED_FALSE\nENABLE_SHARED_TRUE\nCPP\nOTOOL64\nOTOOL\nLIPO\nNMEDIT\nDSYMUTIL\nOBJDUMP\nLN_S\nNM\nac_ct_DUMPBIN\nDUMPBIN\nLD\nFGREP\nEGREP\nGREP\nSED\nLIBTOOL\nCFLAGS_FOR_BUILD\nCC_FOR_BUILD\nAR\nRANLIB\nMAINT\nMAINTAINER_MODE_FALSE\nMAINTAINER_MODE_TRUE\nGDCFLAGS\nGDC\nCCASFLAGS\nCCAS\nOBJEXT\nEXEEXT\nac_ct_CC\nCPPFLAGS\nLDFLAGS\nCFLAGS\nCC\nam__untar\nam__tar\nAMTAR\nam__leading_dot\nSET_MAKE\nAWK\nmkdir_p\nMKDIR_P\nINSTALL_STRIP_PROGRAM\nSTRIP\ninstall_sh\nMAKEINFO\nAUTOHEADER\nAUTOMAKE\nAUTOCONF\nACLOCAL\nVERSION\nPACKAGE\nCYGPATH_W\nam__isrc\nINSTALL_DATA\nINSTALL_SCRIPT\nINSTALL_PROGRAM\ntarget_os\ntarget_vendor\ntarget_cpu\ntarget\nhost_os\nhost_vendor\nhost_cpu\nhost\nbuild_os\nbuild_vendor\nbuild_cpu\nbuild\nmulti_basedir\ntarget_alias\nhost_alias\nbuild_alias\nLIBS\nECHO_T\nECHO_N\nECHO_C\nDEFS\nmandir\nlocaledir\nlibdir\npsdir\npdfdir\ndvidir\nhtmldir\ninfodir\ndocdir\noldincludedir\nincludedir\nlocalstatedir\nsharedstatedir\nsysconfdir\ndatadir\ndatarootdir\nlibexecdir\nsbindir\nbindir\nprogram_transform_name\nprefix\nexec_prefix\nPACKAGE_URL\nPACKAGE_BUGREPORT\nPACKAGE_STRING\nPACKAGE_VERSION\nPACKAGE_TARNAME\nPACKAGE_NAME\nPATH_SEPARATOR\nSHELL'\nac_subst_files=''\nac_user_opts='\nenable_option_checking\nenable_multilib\nenable_maintainer_mode\nenable_shared\nenable_static\nwith_pic\nenable_fast_install\nwith_gnu_ld\nenable_libtool_lock\nwith_gcc_major_version_only\nenable_werror\nenable_druntime_gc\nenable_unix\nenable_thread_lib\nwith_libatomic\nwith_libbacktrace\nwith_target_system_zlib\nwith_cross_host\n'\n      ac_precious_vars='build_alias\nhost_alias\ntarget_alias\nCPP\nCPPFLAGS'\n\n\n# Initialize some variables set by options.\nac_init_help=\nac_init_version=false\nac_unrecognized_opts=\nac_unrecognized_sep=\n# The variables have the same names as the options, with\n# dashes changed to underlines.\ncache_file=/dev/null\nexec_prefix=NONE\nno_create=\nno_recursion=\nprefix=NONE\nprogram_prefix=NONE\nprogram_suffix=NONE\nprogram_transform_name=s,x,x,\nsilent=\nsite=\nsrcdir=\nverbose=\nx_includes=NONE\nx_libraries=NONE\n\n# Installation directory options.\n# These are left unexpanded so users can \"make install exec_prefix=/foo\"\n# and all the variables that are supposed to be based on exec_prefix\n# by default will actually change.\n# Use braces instead of parens because sh, perl, etc. also accept them.\n# (The list follows the same order as the GNU Coding Standards.)\nbindir='${exec_prefix}/bin'\nsbindir='${exec_prefix}/sbin'\nlibexecdir='${exec_prefix}/libexec'\ndatarootdir='${prefix}/share'\ndatadir='${datarootdir}'\nsysconfdir='${prefix}/etc'\nsharedstatedir='${prefix}/com'\nlocalstatedir='${prefix}/var'\nincludedir='${prefix}/include'\noldincludedir='/usr/include'\ndocdir='${datarootdir}/doc/${PACKAGE_TARNAME}'\ninfodir='${datarootdir}/info'\nhtmldir='${docdir}'\ndvidir='${docdir}'\npdfdir='${docdir}'\npsdir='${docdir}'\nlibdir='${exec_prefix}/lib'\nlocaledir='${datarootdir}/locale'\nmandir='${datarootdir}/man'\n\nac_prev=\nac_dashdash=\nfor ac_option\ndo\n  # If the previous option needs an argument, assign it.\n  if test -n \"$ac_prev\"; then\n    eval $ac_prev=\\$ac_option\n    ac_prev=\n    continue\n  fi\n\n  case $ac_option in\n  *=*)\tac_optarg=`expr \"X$ac_option\" : '[^=]*=\\(.*\\)'` ;;\n  *)\tac_optarg=yes ;;\n  esac\n\n  # Accept the important Cygnus configure options, so we can diagnose typos.\n\n  case $ac_dashdash$ac_option in\n  --)\n    ac_dashdash=yes ;;\n\n  -bindir | --bindir | --bindi | --bind | --bin | --bi)\n    ac_prev=bindir ;;\n  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)\n    bindir=$ac_optarg ;;\n\n  -build | --build | --buil | --bui | --bu)\n    ac_prev=build_alias ;;\n  -build=* | --build=* | --buil=* | --bui=* | --bu=*)\n    build_alias=$ac_optarg ;;\n\n  -cache-file | --cache-file | --cache-fil | --cache-fi \\\n  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)\n    ac_prev=cache_file ;;\n  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \\\n  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)\n    cache_file=$ac_optarg ;;\n\n  --config-cache | -C)\n    cache_file=config.cache ;;\n\n  -datadir | --datadir | --datadi | --datad)\n    ac_prev=datadir ;;\n  -datadir=* | --datadir=* | --datadi=* | --datad=*)\n    datadir=$ac_optarg ;;\n\n  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \\\n  | --dataroo | --dataro | --datar)\n    ac_prev=datarootdir ;;\n  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \\\n  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)\n    datarootdir=$ac_optarg ;;\n\n  -disable-* | --disable-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*disable-\\(.*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error \"invalid feature name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"enable_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval enable_$ac_useropt=no ;;\n\n  -docdir | --docdir | --docdi | --doc | --do)\n    ac_prev=docdir ;;\n  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)\n    docdir=$ac_optarg ;;\n\n  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)\n    ac_prev=dvidir ;;\n  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)\n    dvidir=$ac_optarg ;;\n\n  -enable-* | --enable-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*enable-\\([^=]*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error \"invalid feature name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"enable_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval enable_$ac_useropt=\\$ac_optarg ;;\n\n  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \\\n  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \\\n  | --exec | --exe | --ex)\n    ac_prev=exec_prefix ;;\n  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \\\n  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \\\n  | --exec=* | --exe=* | --ex=*)\n    exec_prefix=$ac_optarg ;;\n\n  -gas | --gas | --ga | --g)\n    # Obsolete; use --with-gas.\n    with_gas=yes ;;\n\n  -help | --help | --hel | --he | -h)\n    ac_init_help=long ;;\n  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)\n    ac_init_help=recursive ;;\n  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)\n    ac_init_help=short ;;\n\n  -host | --host | --hos | --ho)\n    ac_prev=host_alias ;;\n  -host=* | --host=* | --hos=* | --ho=*)\n    host_alias=$ac_optarg ;;\n\n  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)\n    ac_prev=htmldir ;;\n  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \\\n  | --ht=*)\n    htmldir=$ac_optarg ;;\n\n  -includedir | --includedir | --includedi | --included | --include \\\n  | --includ | --inclu | --incl | --inc)\n    ac_prev=includedir ;;\n  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \\\n  | --includ=* | --inclu=* | --incl=* | --inc=*)\n    includedir=$ac_optarg ;;\n\n  -infodir | --infodir | --infodi | --infod | --info | --inf)\n    ac_prev=infodir ;;\n  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)\n    infodir=$ac_optarg ;;\n\n  -libdir | --libdir | --libdi | --libd)\n    ac_prev=libdir ;;\n  -libdir=* | --libdir=* | --libdi=* | --libd=*)\n    libdir=$ac_optarg ;;\n\n  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \\\n  | --libexe | --libex | --libe)\n    ac_prev=libexecdir ;;\n  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \\\n  | --libexe=* | --libex=* | --libe=*)\n    libexecdir=$ac_optarg ;;\n\n  -localedir | --localedir | --localedi | --localed | --locale)\n    ac_prev=localedir ;;\n  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)\n    localedir=$ac_optarg ;;\n\n  -localstatedir | --localstatedir | --localstatedi | --localstated \\\n  | --localstate | --localstat | --localsta | --localst | --locals)\n    ac_prev=localstatedir ;;\n  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \\\n  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)\n    localstatedir=$ac_optarg ;;\n\n  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)\n    ac_prev=mandir ;;\n  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)\n    mandir=$ac_optarg ;;\n\n  -nfp | --nfp | --nf)\n    # Obsolete; use --without-fp.\n    with_fp=no ;;\n\n  -no-create | --no-create | --no-creat | --no-crea | --no-cre \\\n  | --no-cr | --no-c | -n)\n    no_create=yes ;;\n\n  -no-recursion | --no-recursion | --no-recursio | --no-recursi \\\n  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)\n    no_recursion=yes ;;\n\n  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \\\n  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \\\n  | --oldin | --oldi | --old | --ol | --o)\n    ac_prev=oldincludedir ;;\n  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \\\n  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \\\n  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)\n    oldincludedir=$ac_optarg ;;\n\n  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)\n    ac_prev=prefix ;;\n  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)\n    prefix=$ac_optarg ;;\n\n  -program-prefix | --program-prefix | --program-prefi | --program-pref \\\n  | --program-pre | --program-pr | --program-p)\n    ac_prev=program_prefix ;;\n  -program-prefix=* | --program-prefix=* | --program-prefi=* \\\n  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)\n    program_prefix=$ac_optarg ;;\n\n  -program-suffix | --program-suffix | --program-suffi | --program-suff \\\n  | --program-suf | --program-su | --program-s)\n    ac_prev=program_suffix ;;\n  -program-suffix=* | --program-suffix=* | --program-suffi=* \\\n  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)\n    program_suffix=$ac_optarg ;;\n\n  -program-transform-name | --program-transform-name \\\n  | --program-transform-nam | --program-transform-na \\\n  | --program-transform-n | --program-transform- \\\n  | --program-transform | --program-transfor \\\n  | --program-transfo | --program-transf \\\n  | --program-trans | --program-tran \\\n  | --progr-tra | --program-tr | --program-t)\n    ac_prev=program_transform_name ;;\n  -program-transform-name=* | --program-transform-name=* \\\n  | --program-transform-nam=* | --program-transform-na=* \\\n  | --program-transform-n=* | --program-transform-=* \\\n  | --program-transform=* | --program-transfor=* \\\n  | --program-transfo=* | --program-transf=* \\\n  | --program-trans=* | --program-tran=* \\\n  | --progr-tra=* | --program-tr=* | --program-t=*)\n    program_transform_name=$ac_optarg ;;\n\n  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)\n    ac_prev=pdfdir ;;\n  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)\n    pdfdir=$ac_optarg ;;\n\n  -psdir | --psdir | --psdi | --psd | --ps)\n    ac_prev=psdir ;;\n  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)\n    psdir=$ac_optarg ;;\n\n  -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n  | -silent | --silent | --silen | --sile | --sil)\n    silent=yes ;;\n\n  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)\n    ac_prev=sbindir ;;\n  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \\\n  | --sbi=* | --sb=*)\n    sbindir=$ac_optarg ;;\n\n  -sharedstatedir | --sharedstatedir | --sharedstatedi \\\n  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \\\n  | --sharedst | --shareds | --shared | --share | --shar \\\n  | --sha | --sh)\n    ac_prev=sharedstatedir ;;\n  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \\\n  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \\\n  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \\\n  | --sha=* | --sh=*)\n    sharedstatedir=$ac_optarg ;;\n\n  -site | --site | --sit)\n    ac_prev=site ;;\n  -site=* | --site=* | --sit=*)\n    site=$ac_optarg ;;\n\n  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)\n    ac_prev=srcdir ;;\n  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)\n    srcdir=$ac_optarg ;;\n\n  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \\\n  | --syscon | --sysco | --sysc | --sys | --sy)\n    ac_prev=sysconfdir ;;\n  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \\\n  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)\n    sysconfdir=$ac_optarg ;;\n\n  -target | --target | --targe | --targ | --tar | --ta | --t)\n    ac_prev=target_alias ;;\n  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)\n    target_alias=$ac_optarg ;;\n\n  -v | -verbose | --verbose | --verbos | --verbo | --verb)\n    verbose=yes ;;\n\n  -version | --version | --versio | --versi | --vers | -V)\n    ac_init_version=: ;;\n\n  -with-* | --with-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*with-\\([^=]*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error \"invalid package name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"with_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval with_$ac_useropt=\\$ac_optarg ;;\n\n  -without-* | --without-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*without-\\(.*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error \"invalid package name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"with_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval with_$ac_useropt=no ;;\n\n  --x)\n    # Obsolete; use --with-x.\n    with_x=yes ;;\n\n  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \\\n  | --x-incl | --x-inc | --x-in | --x-i)\n    ac_prev=x_includes ;;\n  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \\\n  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)\n    x_includes=$ac_optarg ;;\n\n  -x-libraries | --x-libraries | --x-librarie | --x-librari \\\n  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)\n    ac_prev=x_libraries ;;\n  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \\\n  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)\n    x_libraries=$ac_optarg ;;\n\n  -*) as_fn_error \"unrecognized option: \\`$ac_option'\nTry \\`$0 --help' for more information.\"\n    ;;\n\n  *=*)\n    ac_envvar=`expr \"x$ac_option\" : 'x\\([^=]*\\)='`\n    # Reject names that are not valid shell variable names.\n    case $ac_envvar in #(\n      '' | [0-9]* | *[!_$as_cr_alnum]* )\n      as_fn_error \"invalid variable name: \\`$ac_envvar'\" ;;\n    esac\n    eval $ac_envvar=\\$ac_optarg\n    export $ac_envvar ;;\n\n  *)\n    # FIXME: should be removed in autoconf 3.0.\n    $as_echo \"$as_me: WARNING: you should use --build, --host, --target\" >&2\n    expr \"x$ac_option\" : \".*[^-._$as_cr_alnum]\" >/dev/null &&\n      $as_echo \"$as_me: WARNING: invalid host type: $ac_option\" >&2\n    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}\n    ;;\n\n  esac\ndone\n\nif test -n \"$ac_prev\"; then\n  ac_option=--`echo $ac_prev | sed 's/_/-/g'`\n  as_fn_error \"missing argument to $ac_option\"\nfi\n\nif test -n \"$ac_unrecognized_opts\"; then\n  case $enable_option_checking in\n    no) ;;\n    fatal) as_fn_error \"unrecognized options: $ac_unrecognized_opts\" ;;\n    *)     $as_echo \"$as_me: WARNING: unrecognized options: $ac_unrecognized_opts\" >&2 ;;\n  esac\nfi\n\n# Check all directory arguments for consistency.\nfor ac_var in\texec_prefix prefix bindir sbindir libexecdir datarootdir \\\n\t\tdatadir sysconfdir sharedstatedir localstatedir includedir \\\n\t\toldincludedir docdir infodir htmldir dvidir pdfdir psdir \\\n\t\tlibdir localedir mandir\ndo\n  eval ac_val=\\$$ac_var\n  # Remove trailing slashes.\n  case $ac_val in\n    */ )\n      ac_val=`expr \"X$ac_val\" : 'X\\(.*[^/]\\)' \\| \"X$ac_val\" : 'X\\(.*\\)'`\n      eval $ac_var=\\$ac_val;;\n  esac\n  # Be sure to have absolute directory names.\n  case $ac_val in\n    [\\\\/$]* | ?:[\\\\/]* )  continue;;\n    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;\n  esac\n  as_fn_error \"expected an absolute directory name for --$ac_var: $ac_val\"\ndone\n\n# There might be people who depend on the old broken behavior: `$host'\n# used to hold the argument of --host etc.\n# FIXME: To remove some day.\nbuild=$build_alias\nhost=$host_alias\ntarget=$target_alias\n\n# FIXME: To remove some day.\nif test \"x$host_alias\" != x; then\n  if test \"x$build_alias\" = x; then\n    cross_compiling=maybe\n    $as_echo \"$as_me: WARNING: If you wanted to set the --build type, don't use --host.\n    If a cross compiler is detected then cross compile mode will be used.\" >&2\n  elif test \"x$build_alias\" != \"x$host_alias\"; then\n    cross_compiling=yes\n  fi\nfi\n\nac_tool_prefix=\ntest -n \"$host_alias\" && ac_tool_prefix=$host_alias-\n\ntest \"$silent\" = yes && exec 6>/dev/null\n\n\nac_pwd=`pwd` && test -n \"$ac_pwd\" &&\nac_ls_di=`ls -di .` &&\nac_pwd_ls_di=`cd \"$ac_pwd\" && ls -di .` ||\n  as_fn_error \"working directory cannot be determined\"\ntest \"X$ac_ls_di\" = \"X$ac_pwd_ls_di\" ||\n  as_fn_error \"pwd does not report name of working directory\"\n\n\n# Find the source files, if location was not specified.\nif test -z \"$srcdir\"; then\n  ac_srcdir_defaulted=yes\n  # Try the directory containing this script, then the parent directory.\n  ac_confdir=`$as_dirname -- \"$as_myself\" ||\n$as_expr X\"$as_myself\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_myself\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_myself\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_myself\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_myself\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n  srcdir=$ac_confdir\n  if test ! -r \"$srcdir/$ac_unique_file\"; then\n    srcdir=..\n  fi\nelse\n  ac_srcdir_defaulted=no\nfi\nif test ! -r \"$srcdir/$ac_unique_file\"; then\n  test \"$ac_srcdir_defaulted\" = yes && srcdir=\"$ac_confdir or ..\"\n  as_fn_error \"cannot find sources ($ac_unique_file) in $srcdir\"\nfi\nac_msg=\"sources are in $srcdir, but \\`cd $srcdir' does not work\"\nac_abs_confdir=`(\n\tcd \"$srcdir\" && test -r \"./$ac_unique_file\" || as_fn_error \"$ac_msg\"\n\tpwd)`\n# When building in place, set srcdir=.\nif test \"$ac_abs_confdir\" = \"$ac_pwd\"; then\n  srcdir=.\nfi\n# Remove unnecessary trailing slashes from srcdir.\n# Double slashes in file names in object file debugging info\n# mess up M-x gdb in Emacs.\ncase $srcdir in\n*/) srcdir=`expr \"X$srcdir\" : 'X\\(.*[^/]\\)' \\| \"X$srcdir\" : 'X\\(.*\\)'`;;\nesac\nfor ac_var in $ac_precious_vars; do\n  eval ac_env_${ac_var}_set=\\${${ac_var}+set}\n  eval ac_env_${ac_var}_value=\\$${ac_var}\n  eval ac_cv_env_${ac_var}_set=\\${${ac_var}+set}\n  eval ac_cv_env_${ac_var}_value=\\$${ac_var}\ndone\n\n#\n# Report the --help message.\n#\nif test \"$ac_init_help\" = \"long\"; then\n  # Omit some internal or obsolete options to make the list less imposing.\n  # This message is too long to be a string in the A/UX 3.1 sh.\n  cat <<_ACEOF\n\\`configure' configures package-unused version-unused to adapt to many kinds of systems.\n\nUsage: $0 [OPTION]... [VAR=VALUE]...\n\nTo assign environment variables (e.g., CC, CFLAGS...), specify them as\nVAR=VALUE.  See below for descriptions of some of the useful variables.\n\nDefaults for the options are specified in brackets.\n\nConfiguration:\n  -h, --help              display this help and exit\n      --help=short        display options specific to this package\n      --help=recursive    display the short help of all the included packages\n  -V, --version           display version information and exit\n  -q, --quiet, --silent   do not print \\`checking...' messages\n      --cache-file=FILE   cache test results in FILE [disabled]\n  -C, --config-cache      alias for \\`--cache-file=config.cache'\n  -n, --no-create         do not create output files\n      --srcdir=DIR        find the sources in DIR [configure dir or \\`..']\n\nInstallation directories:\n  --prefix=PREFIX         install architecture-independent files in PREFIX\n                          [$ac_default_prefix]\n  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX\n                          [PREFIX]\n\nBy default, \\`make install' will install all the files in\n\\`$ac_default_prefix/bin', \\`$ac_default_prefix/lib' etc.  You can specify\nan installation prefix other than \\`$ac_default_prefix' using \\`--prefix',\nfor instance \\`--prefix=\\$HOME'.\n\nFor better control, use the options below.\n\nFine tuning of the installation directories:\n  --bindir=DIR            user executables [EPREFIX/bin]\n  --sbindir=DIR           system admin executables [EPREFIX/sbin]\n  --libexecdir=DIR        program executables [EPREFIX/libexec]\n  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]\n  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]\n  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]\n  --libdir=DIR            object code libraries [EPREFIX/lib]\n  --includedir=DIR        C header files [PREFIX/include]\n  --oldincludedir=DIR     C header files for non-gcc [/usr/include]\n  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]\n  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]\n  --infodir=DIR           info documentation [DATAROOTDIR/info]\n  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]\n  --mandir=DIR            man documentation [DATAROOTDIR/man]\n  --docdir=DIR            documentation root [DATAROOTDIR/doc/libphobos]\n  --htmldir=DIR           html documentation [DOCDIR]\n  --dvidir=DIR            dvi documentation [DOCDIR]\n  --pdfdir=DIR            pdf documentation [DOCDIR]\n  --psdir=DIR             ps documentation [DOCDIR]\n_ACEOF\n\n  cat <<\\_ACEOF\n\nProgram names:\n  --program-prefix=PREFIX            prepend PREFIX to installed program names\n  --program-suffix=SUFFIX            append SUFFIX to installed program names\n  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names\n\nSystem types:\n  --build=BUILD     configure for building on BUILD [guessed]\n  --host=HOST       cross-compile to build programs to run on HOST [BUILD]\n  --target=TARGET   configure for building compilers for TARGET [HOST]\n_ACEOF\nfi\n\nif test -n \"$ac_init_help\"; then\n  case $ac_init_help in\n     short | recursive ) echo \"Configuration of package-unused version-unused:\";;\n   esac\n  cat <<\\_ACEOF\n\nOptional Features:\n  --disable-option-checking  ignore unrecognized --enable/--with options\n  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)\n  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]\n  --enable-multilib       build many library versions (default)\n  --enable-maintainer-mode  enable make rules and dependencies not useful\n\t\t\t  (and sometimes confusing) to the casual installer\n  --enable-shared[=PKGS]  build shared libraries [default=yes]\n  --enable-static[=PKGS]  build static libraries [default=yes]\n  --enable-fast-install[=PKGS]\n                          optimize for fast installation [default=yes]\n  --disable-libtool-lock  avoid locking (might break parallel builds)\n  --enable-werror         turns on -Werror [default=no]\n  --enable-druntime-gc    enable D runtime garbage collector (default: yes)\n  --enable-unix           enables Unix runtime (default: yes, for Unix\n                          targets)\n  --enable-thread-lib=<arg>\n                          specify linker option for the system thread library\n                          (default: autodetect)\n\nOptional Packages:\n  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]\n  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)\n  --with-pic              try to use only PIC/non-PIC objects [default=use\n                          both]\n  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]\n  --with-gcc-major-version-only\n                          use only GCC major number in filesystem paths\n  --without-libatomic     Do not use libatomic in core.atomic (default: auto)\n  --without-libbacktrace  Do not use libbacktrace in core.runtime (default:\n                          auto)\n  --with-target-system-zlib\n                          use installed libz (default: no)\n  --with-cross-host=HOST  configuring with a cross compiler\n\nSome influential environment variables:\n  CC          C compiler command\n  CFLAGS      C compiler flags\n  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a\n              nonstandard directory <lib dir>\n  LIBS        libraries to pass to the linker, e.g. -l<library>\n  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if\n              you have headers in a nonstandard directory <include dir>\n  CCAS        assembler compiler command (defaults to CC)\n  CCASFLAGS   assembler compiler flags (defaults to CFLAGS)\n  GDC         D compiler command\n  GDCFLAGS    D compiler flags\n  CPP         C preprocessor\n\nUse these variables to override the choices made by `configure' or to help\nit to find libraries and programs with nonstandard names/locations.\n\nReport bugs to the package provider.\n_ACEOF\nac_status=$?\nfi\n\nif test \"$ac_init_help\" = \"recursive\"; then\n  # If there are subdirs, report their specific --help.\n  for ac_dir in : $ac_subdirs_all; do test \"x$ac_dir\" = x: && continue\n    test -d \"$ac_dir\" ||\n      { cd \"$srcdir\" && ac_pwd=`pwd` && srcdir=. && test -d \"$ac_dir\"; } ||\n      continue\n    ac_builddir=.\n\ncase \"$ac_dir\" in\n.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;\n*)\n  ac_dir_suffix=/`$as_echo \"$ac_dir\" | sed 's|^\\.[\\\\/]||'`\n  # A \"..\" for each directory in $ac_dir_suffix.\n  ac_top_builddir_sub=`$as_echo \"$ac_dir_suffix\" | sed 's|/[^\\\\/]*|/..|g;s|/||'`\n  case $ac_top_builddir_sub in\n  \"\") ac_top_builddir_sub=. ac_top_build_prefix= ;;\n  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;\n  esac ;;\nesac\nac_abs_top_builddir=$ac_pwd\nac_abs_builddir=$ac_pwd$ac_dir_suffix\n# for backward compatibility:\nac_top_builddir=$ac_top_build_prefix\n\ncase $srcdir in\n  .)  # We are building in place.\n    ac_srcdir=.\n    ac_top_srcdir=$ac_top_builddir_sub\n    ac_abs_top_srcdir=$ac_pwd ;;\n  [\\\\/]* | ?:[\\\\/]* )  # Absolute name.\n    ac_srcdir=$srcdir$ac_dir_suffix;\n    ac_top_srcdir=$srcdir\n    ac_abs_top_srcdir=$srcdir ;;\n  *) # Relative name.\n    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix\n    ac_top_srcdir=$ac_top_build_prefix$srcdir\n    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;\nesac\nac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix\n\n    cd \"$ac_dir\" || { ac_status=$?; continue; }\n    # Check for guested configure.\n    if test -f \"$ac_srcdir/configure.gnu\"; then\n      echo &&\n      $SHELL \"$ac_srcdir/configure.gnu\" --help=recursive\n    elif test -f \"$ac_srcdir/configure\"; then\n      echo &&\n      $SHELL \"$ac_srcdir/configure\" --help=recursive\n    else\n      $as_echo \"$as_me: WARNING: no configuration information is in $ac_dir\" >&2\n    fi || ac_status=$?\n    cd \"$ac_pwd\" || { ac_status=$?; break; }\n  done\nfi\n\ntest -n \"$ac_init_help\" && exit $ac_status\nif $ac_init_version; then\n  cat <<\\_ACEOF\npackage-unused configure version-unused\ngenerated by GNU Autoconf 2.64\n\nCopyright (C) 2009 Free Software Foundation, Inc.\nThis configure script is free software; the Free Software Foundation\ngives unlimited permission to copy, distribute and modify it.\n_ACEOF\n  exit\nfi\n\n## ------------------------ ##\n## Autoconf initialization. ##\n## ------------------------ ##\n\n# ac_fn_c_try_compile LINENO\n# --------------------------\n# Try to compile conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext\n  if { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest.$ac_objext; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  return $ac_retval\n\n} # ac_fn_c_try_compile\n\n# ac_fn_d_try_compile LINENO\n# --------------------------\n# Try to compile conftest.$ac_ext, and return whether this succeeded.\nac_fn_d_try_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext\n  if { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_d_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest.$ac_objext; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  return $ac_retval\n\n} # ac_fn_d_try_compile\n\n# ac_fn_c_try_link LINENO\n# -----------------------\n# Try to link conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_link ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext conftest$ac_exeext\n  if { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest$ac_exeext && {\n\t test \"$cross_compiling\" = yes ||\n\t $as_test_x conftest$ac_exeext\n       }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information\n  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would\n  # interfere with the next link command; also delete a directory that is\n  # left behind by Apple's compiler.  We do this before executing the actions.\n  rm -rf conftest.dSYM conftest_ipa8_conftest.oo\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  return $ac_retval\n\n} # ac_fn_c_try_link\n\n# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES\n# -------------------------------------------------------\n# Tests whether HEADER exists and can be compiled using the include files in\n# INCLUDES, setting the cache variable VAR accordingly.\nac_fn_c_check_header_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$4\n#include <$2>\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  eval \"$3=yes\"\nelse\n  eval \"$3=no\"\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n\n} # ac_fn_c_check_header_compile\n\n# ac_fn_c_try_cpp LINENO\n# ----------------------\n# Try to preprocess conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_cpp ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if { { ac_try=\"$ac_cpp conftest.$ac_ext\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_cpp conftest.$ac_ext\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } >/dev/null && {\n\t test -z \"$ac_c_preproc_warn_flag$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n    ac_retval=1\nfi\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  return $ac_retval\n\n} # ac_fn_c_try_cpp\n\n# ac_fn_c_try_run LINENO\n# ----------------------\n# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes\n# that executables *can* be run.\nac_fn_c_try_run ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'\n  { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: program exited with status $ac_status\" >&5\n       $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n       ac_retval=$ac_status\nfi\n  rm -rf conftest.dSYM conftest_ipa8_conftest.oo\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  return $ac_retval\n\n} # ac_fn_c_try_run\n\n# ac_fn_c_check_func LINENO FUNC VAR\n# ----------------------------------\n# Tests whether FUNC exists, setting the cache variable VAR accordingly\nac_fn_c_check_func ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n/* Define $2 to an innocuous variant, in case <limits.h> declares $2.\n   For example, HP-UX 11i <limits.h> declares gettimeofday.  */\n#define $2 innocuous_$2\n\n/* System header to define __stub macros and hopefully few prototypes,\n    which can conflict with char $2 (); below.\n    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n    <limits.h> exists even on freestanding compilers.  */\n\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\n#undef $2\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar $2 ();\n/* The GNU C library defines this for functions which it implements\n    to always fail with ENOSYS.  Some functions are actually named\n    something starting with __ and the normal name is an alias.  */\n#if defined __stub_$2 || defined __stub___$2\nchoke me\n#endif\n\nint\nmain ()\n{\nreturn $2 ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  eval \"$3=yes\"\nelse\n  eval \"$3=no\"\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n\n} # ac_fn_c_check_func\n\n# ac_fn_d_try_link LINENO\n# -----------------------\n# Try to link conftest.$ac_ext, and return whether this succeeded.\nac_fn_d_try_link ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext conftest$ac_exeext\n  if { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_d_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest$ac_exeext && {\n\t test \"$cross_compiling\" = yes ||\n\t $as_test_x conftest$ac_exeext\n       }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information\n  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would\n  # interfere with the next link command; also delete a directory that is\n  # left behind by Apple's compiler.  We do this before executing the actions.\n  rm -rf conftest.dSYM conftest_ipa8_conftest.oo\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  return $ac_retval\n\n} # ac_fn_d_try_link\n\n# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES\n# -------------------------------------------------------\n# Tests whether HEADER exists, giving a warning if it cannot be compiled using\n# the include files in INCLUDES and setting the cache variable VAR\n# accordingly.\nac_fn_c_check_header_mongrel ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\nelse\n  # Is the header compilable?\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking $2 usability\" >&5\n$as_echo_n \"checking $2 usability... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$4\n#include <$2>\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_header_compiler=yes\nelse\n  ac_header_compiler=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler\" >&5\n$as_echo \"$ac_header_compiler\" >&6; }\n\n# Is the header present?\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking $2 presence\" >&5\n$as_echo_n \"checking $2 presence... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <$2>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  ac_header_preproc=yes\nelse\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc\" >&5\n$as_echo \"$ac_header_preproc\" >&6; }\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((\n  yes:no: )\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!\" >&5\n$as_echo \"$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result\" >&5\n$as_echo \"$as_me: WARNING: $2: proceeding with the compiler's result\" >&2;}\n    ;;\n  no:yes:* )\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled\" >&5\n$as_echo \"$as_me: WARNING: $2: present but cannot be compiled\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?\" >&5\n$as_echo \"$as_me: WARNING: $2:     check for missing prerequisite headers?\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation\" >&5\n$as_echo \"$as_me: WARNING: $2: see the Autoconf documentation\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\n$as_echo \"$as_me: WARNING: $2:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result\" >&5\n$as_echo \"$as_me: WARNING: $2: proceeding with the compiler's result\" >&2;}\n    ;;\nesac\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  eval \"$3=\\$ac_header_compiler\"\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\nfi\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n\n} # ac_fn_c_check_header_mongrel\ncat >config.log <<_ACEOF\nThis file contains any messages produced by compilers while\nrunning configure, to aid debugging if configure makes a mistake.\n\nIt was created by package-unused $as_me version-unused, which was\ngenerated by GNU Autoconf 2.64.  Invocation command line was\n\n  $ $0 $@\n\n_ACEOF\nexec 5>>config.log\n{\ncat <<_ASUNAME\n## --------- ##\n## Platform. ##\n## --------- ##\n\nhostname = `(hostname || uname -n) 2>/dev/null | sed 1q`\nuname -m = `(uname -m) 2>/dev/null || echo unknown`\nuname -r = `(uname -r) 2>/dev/null || echo unknown`\nuname -s = `(uname -s) 2>/dev/null || echo unknown`\nuname -v = `(uname -v) 2>/dev/null || echo unknown`\n\n/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`\n/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`\n\n/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`\n/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`\n/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`\n/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`\n/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`\n/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`\n/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`\n\n_ASUNAME\n\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    $as_echo \"PATH: $as_dir\"\n  done\nIFS=$as_save_IFS\n\n} >&5\n\ncat >&5 <<_ACEOF\n\n\n## ----------- ##\n## Core tests. ##\n## ----------- ##\n\n_ACEOF\n\n\n# Keep a trace of the command line.\n# Strip out --no-create and --no-recursion so they do not pile up.\n# Strip out --silent because we don't want to record it for future runs.\n# Also quote any args containing shell meta-characters.\n# Make two passes to allow for proper duplicate-argument suppression.\nac_configure_args=\nac_configure_args0=\nac_configure_args1=\nac_must_keep_next=false\nfor ac_pass in 1 2\ndo\n  for ac_arg\n  do\n    case $ac_arg in\n    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;\n    -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n    | -silent | --silent | --silen | --sile | --sil)\n      continue ;;\n    *\\'*)\n      ac_arg=`$as_echo \"$ac_arg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    esac\n    case $ac_pass in\n    1) as_fn_append ac_configure_args0 \" '$ac_arg'\" ;;\n    2)\n      as_fn_append ac_configure_args1 \" '$ac_arg'\"\n      if test $ac_must_keep_next = true; then\n\tac_must_keep_next=false # Got value, back to normal.\n      else\n\tcase $ac_arg in\n\t  *=* | --config-cache | -C | -disable-* | --disable-* \\\n\t  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \\\n\t  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \\\n\t  | -with-* | --with-* | -without-* | --without-* | --x)\n\t    case \"$ac_configure_args0 \" in\n\t      \"$ac_configure_args1\"*\" '$ac_arg' \"* ) continue ;;\n\t    esac\n\t    ;;\n\t  -* ) ac_must_keep_next=true ;;\n\tesac\n      fi\n      as_fn_append ac_configure_args \" '$ac_arg'\"\n      ;;\n    esac\n  done\ndone\n{ ac_configure_args0=; unset ac_configure_args0;}\n{ ac_configure_args1=; unset ac_configure_args1;}\n\n# When interrupted or exit'd, cleanup temporary files, and complete\n# config.log.  We remove comments because anyway the quotes in there\n# would cause problems or look ugly.\n# WARNING: Use '\\'' to represent an apostrophe within the trap.\n# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.\ntrap 'exit_status=$?\n  # Save into config.log some information that might help in debugging.\n  {\n    echo\n\n    cat <<\\_ASBOX\n## ---------------- ##\n## Cache variables. ##\n## ---------------- ##\n_ASBOX\n    echo\n    # The following way of writing the cache mishandles newlines in values,\n(\n  for ac_var in `(set) 2>&1 | sed -n '\\''s/^\\([a-zA-Z_][a-zA-Z0-9_]*\\)=.*/\\1/p'\\''`; do\n    eval ac_val=\\$$ac_var\n    case $ac_val in #(\n    *${as_nl}*)\n      case $ac_var in #(\n      *_cv_*) { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline\" >&5\n$as_echo \"$as_me: WARNING: cache variable $ac_var contains a newline\" >&2;} ;;\n      esac\n      case $ac_var in #(\n      _ | IFS | as_nl) ;; #(\n      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(\n      *) { eval $ac_var=; unset $ac_var;} ;;\n      esac ;;\n    esac\n  done\n  (set) 2>&1 |\n    case $as_nl`(ac_space='\\'' '\\''; set) 2>&1` in #(\n    *${as_nl}ac_space=\\ *)\n      sed -n \\\n\t\"s/'\\''/'\\''\\\\\\\\'\\'''\\''/g;\n\t  s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1='\\''\\\\2'\\''/p\"\n      ;; #(\n    *)\n      sed -n \"/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p\"\n      ;;\n    esac |\n    sort\n)\n    echo\n\n    cat <<\\_ASBOX\n## ----------------- ##\n## Output variables. ##\n## ----------------- ##\n_ASBOX\n    echo\n    for ac_var in $ac_subst_vars\n    do\n      eval ac_val=\\$$ac_var\n      case $ac_val in\n      *\\'\\''*) ac_val=`$as_echo \"$ac_val\" | sed \"s/'\\''/'\\''\\\\\\\\\\\\\\\\'\\'''\\''/g\"`;;\n      esac\n      $as_echo \"$ac_var='\\''$ac_val'\\''\"\n    done | sort\n    echo\n\n    if test -n \"$ac_subst_files\"; then\n      cat <<\\_ASBOX\n## ------------------- ##\n## File substitutions. ##\n## ------------------- ##\n_ASBOX\n      echo\n      for ac_var in $ac_subst_files\n      do\n\teval ac_val=\\$$ac_var\n\tcase $ac_val in\n\t*\\'\\''*) ac_val=`$as_echo \"$ac_val\" | sed \"s/'\\''/'\\''\\\\\\\\\\\\\\\\'\\'''\\''/g\"`;;\n\tesac\n\t$as_echo \"$ac_var='\\''$ac_val'\\''\"\n      done | sort\n      echo\n    fi\n\n    if test -s confdefs.h; then\n      cat <<\\_ASBOX\n## ----------- ##\n## confdefs.h. ##\n## ----------- ##\n_ASBOX\n      echo\n      cat confdefs.h\n      echo\n    fi\n    test \"$ac_signal\" != 0 &&\n      $as_echo \"$as_me: caught signal $ac_signal\"\n    $as_echo \"$as_me: exit $exit_status\"\n  } >&5\n  rm -f core *.core core.conftest.* &&\n    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&\n    exit $exit_status\n' 0\nfor ac_signal in 1 2 13 15; do\n  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal\ndone\nac_signal=0\n\n# confdefs.h avoids OS command line length limits that DEFS can exceed.\nrm -f -r conftest* confdefs.h\n\n$as_echo \"/* confdefs.h */\" > confdefs.h\n\n# Predefined preprocessor variables.\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_NAME \"$PACKAGE_NAME\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_VERSION \"$PACKAGE_VERSION\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_STRING \"$PACKAGE_STRING\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_URL \"$PACKAGE_URL\"\n_ACEOF\n\n\n# Let the site file select an alternate cache file if it wants to.\n# Prefer an explicitly selected file to automatically selected ones.\nac_site_file1=NONE\nac_site_file2=NONE\nif test -n \"$CONFIG_SITE\"; then\n  ac_site_file1=$CONFIG_SITE\nelif test \"x$prefix\" != xNONE; then\n  ac_site_file1=$prefix/share/config.site\n  ac_site_file2=$prefix/etc/config.site\nelse\n  ac_site_file1=$ac_default_prefix/share/config.site\n  ac_site_file2=$ac_default_prefix/etc/config.site\nfi\nfor ac_site_file in \"$ac_site_file1\" \"$ac_site_file2\"\ndo\n  test \"x$ac_site_file\" = xNONE && continue\n  if test -r \"$ac_site_file\"; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file\" >&5\n$as_echo \"$as_me: loading site script $ac_site_file\" >&6;}\n    sed 's/^/| /' \"$ac_site_file\" >&5\n    . \"$ac_site_file\"\n  fi\ndone\n\nif test -r \"$cache_file\"; then\n  # Some versions of bash will fail to source /dev/null (special\n  # files actually), so we avoid doing that.\n  if test -f \"$cache_file\"; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: loading cache $cache_file\" >&5\n$as_echo \"$as_me: loading cache $cache_file\" >&6;}\n    case $cache_file in\n      [\\\\/]* | ?:[\\\\/]* ) . \"$cache_file\";;\n      *)                      . \"./$cache_file\";;\n    esac\n  fi\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: creating cache $cache_file\" >&5\n$as_echo \"$as_me: creating cache $cache_file\" >&6;}\n  >$cache_file\nfi\n\n# Check that the precious variables saved in the cache have kept the same\n# value.\nac_cache_corrupted=false\nfor ac_var in $ac_precious_vars; do\n  eval ac_old_set=\\$ac_cv_env_${ac_var}_set\n  eval ac_new_set=\\$ac_env_${ac_var}_set\n  eval ac_old_val=\\$ac_cv_env_${ac_var}_value\n  eval ac_new_val=\\$ac_env_${ac_var}_value\n  case $ac_old_set,$ac_new_set in\n    set,)\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' was set to \\`$ac_old_val' in the previous run\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' was set to \\`$ac_old_val' in the previous run\" >&2;}\n      ac_cache_corrupted=: ;;\n    ,set)\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' was not set in the previous run\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' was not set in the previous run\" >&2;}\n      ac_cache_corrupted=: ;;\n    ,);;\n    *)\n      if test \"x$ac_old_val\" != \"x$ac_new_val\"; then\n\t# differences in whitespace do not lead to failure.\n\tac_old_val_w=`echo x $ac_old_val`\n\tac_new_val_w=`echo x $ac_new_val`\n\tif test \"$ac_old_val_w\" != \"$ac_new_val_w\"; then\n\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' has changed since the previous run:\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' has changed since the previous run:\" >&2;}\n\t  ac_cache_corrupted=:\n\telse\n\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \\`$ac_var' since the previous run:\" >&5\n$as_echo \"$as_me: warning: ignoring whitespace changes in \\`$ac_var' since the previous run:\" >&2;}\n\t  eval $ac_var=\\$ac_old_val\n\tfi\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}:   former value:  \\`$ac_old_val'\" >&5\n$as_echo \"$as_me:   former value:  \\`$ac_old_val'\" >&2;}\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}:   current value: \\`$ac_new_val'\" >&5\n$as_echo \"$as_me:   current value: \\`$ac_new_val'\" >&2;}\n      fi;;\n  esac\n  # Pass precious variables to config.status.\n  if test \"$ac_new_set\" = set; then\n    case $ac_new_val in\n    *\\'*) ac_arg=$ac_var=`$as_echo \"$ac_new_val\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    *) ac_arg=$ac_var=$ac_new_val ;;\n    esac\n    case \" $ac_configure_args \" in\n      *\" '$ac_arg' \"*) ;; # Avoid dups.  Use of quotes ensures accuracy.\n      *) as_fn_append ac_configure_args \" '$ac_arg'\" ;;\n    esac\n  fi\ndone\nif $ac_cache_corrupted; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build\" >&5\n$as_echo \"$as_me: error: changes in the environment can compromise the build\" >&2;}\n  as_fn_error \"run \\`make distclean' and/or \\`rm $cache_file' and start over\" \"$LINENO\" 5\nfi\n## -------------------- ##\n## Main body of script. ##\n## -------------------- ##\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n\n\n\n\nac_config_headers=\"$ac_config_headers config.h\"\n\n\n# Default to --enable-multilib\n# Check whether --enable-multilib was given.\nif test \"${enable_multilib+set}\" = set; then :\n  enableval=$enable_multilib; case \"$enableval\" in\n  yes) multilib=yes ;;\n  no)  multilib=no ;;\n  *)   as_fn_error \"bad value $enableval for multilib option\" \"$LINENO\" 5 ;;\n esac\nelse\n  multilib=yes\nfi\n\n\n# We may get other options which we leave undocumented:\n# --with-target-subdir, --with-multisrctop, --with-multisubdir\n# See config-ml.in if you want the gory details.\n\nif test \"$srcdir\" = \".\"; then\n  if test \"$with_target_subdir\" != \".\"; then\n    multi_basedir=\"$srcdir/$with_multisrctop../..\"\n  else\n    multi_basedir=\"$srcdir/$with_multisrctop..\"\n  fi\nelse\n  multi_basedir=\"$srcdir/..\"\nfi\n\n\n# Even if the default multilib is not a cross compilation,\n# it may be that some of the other multilibs are.\nif test $cross_compiling = no && test $multilib = yes \\\n   && test \"x${with_multisubdir}\" != x ; then\n   cross_compiling=maybe\nfi\n\nac_config_commands=\"$ac_config_commands default-1\"\n\nac_aux_dir=\nfor ac_dir in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"; do\n  for ac_t in install-sh install.sh shtool; do\n    if test -f \"$ac_dir/$ac_t\"; then\n      ac_aux_dir=$ac_dir\n      ac_install_sh=\"$ac_aux_dir/$ac_t -c\"\n      break 2\n    fi\n  done\ndone\nif test -z \"$ac_aux_dir\"; then\n  as_fn_error \"cannot find install-sh, install.sh, or shtool in \\\"$srcdir\\\" \\\"$srcdir/..\\\" \\\"$srcdir/../..\\\"\" \"$LINENO\" 5\nfi\n\n# These three variables are undocumented and unsupported,\n# and are intended to be withdrawn in a future Autoconf release.\n# They can cause serious problems if a builder's source tree is in a directory\n# whose full name contains unusual characters.\nac_config_guess=\"$SHELL $ac_aux_dir/config.guess\"  # Please don't use this var.\nac_config_sub=\"$SHELL $ac_aux_dir/config.sub\"  # Please don't use this var.\nac_configure=\"$SHELL $ac_aux_dir/configure\"  # Please don't use this var.\n\n\n# Make sure we can run config.sub.\n$SHELL \"$ac_aux_dir/config.sub\" sun4 >/dev/null 2>&1 ||\n  as_fn_error \"cannot run $SHELL $ac_aux_dir/config.sub\" \"$LINENO\" 5\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking build system type\" >&5\n$as_echo_n \"checking build system type... \" >&6; }\nif test \"${ac_cv_build+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_build_alias=$build_alias\ntest \"x$ac_build_alias\" = x &&\n  ac_build_alias=`$SHELL \"$ac_aux_dir/config.guess\"`\ntest \"x$ac_build_alias\" = x &&\n  as_fn_error \"cannot guess build type; you must specify one\" \"$LINENO\" 5\nac_cv_build=`$SHELL \"$ac_aux_dir/config.sub\" $ac_build_alias` ||\n  as_fn_error \"$SHELL $ac_aux_dir/config.sub $ac_build_alias failed\" \"$LINENO\" 5\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_build\" >&5\n$as_echo \"$ac_cv_build\" >&6; }\ncase $ac_cv_build in\n*-*-*) ;;\n*) as_fn_error \"invalid value of canonical build\" \"$LINENO\" 5;;\nesac\nbuild=$ac_cv_build\nac_save_IFS=$IFS; IFS='-'\nset x $ac_cv_build\nshift\nbuild_cpu=$1\nbuild_vendor=$2\nshift; shift\n# Remember, the first character of IFS is used to create $*,\n# except with old shells:\nbuild_os=$*\nIFS=$ac_save_IFS\ncase $build_os in *\\ *) build_os=`echo \"$build_os\" | sed 's/ /-/g'`;; esac\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking host system type\" >&5\n$as_echo_n \"checking host system type... \" >&6; }\nif test \"${ac_cv_host+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test \"x$host_alias\" = x; then\n  ac_cv_host=$ac_cv_build\nelse\n  ac_cv_host=`$SHELL \"$ac_aux_dir/config.sub\" $host_alias` ||\n    as_fn_error \"$SHELL $ac_aux_dir/config.sub $host_alias failed\" \"$LINENO\" 5\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_host\" >&5\n$as_echo \"$ac_cv_host\" >&6; }\ncase $ac_cv_host in\n*-*-*) ;;\n*) as_fn_error \"invalid value of canonical host\" \"$LINENO\" 5;;\nesac\nhost=$ac_cv_host\nac_save_IFS=$IFS; IFS='-'\nset x $ac_cv_host\nshift\nhost_cpu=$1\nhost_vendor=$2\nshift; shift\n# Remember, the first character of IFS is used to create $*,\n# except with old shells:\nhost_os=$*\nIFS=$ac_save_IFS\ncase $host_os in *\\ *) host_os=`echo \"$host_os\" | sed 's/ /-/g'`;; esac\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking target system type\" >&5\n$as_echo_n \"checking target system type... \" >&6; }\nif test \"${ac_cv_target+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test \"x$target_alias\" = x; then\n  ac_cv_target=$ac_cv_host\nelse\n  ac_cv_target=`$SHELL \"$ac_aux_dir/config.sub\" $target_alias` ||\n    as_fn_error \"$SHELL $ac_aux_dir/config.sub $target_alias failed\" \"$LINENO\" 5\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_target\" >&5\n$as_echo \"$ac_cv_target\" >&6; }\ncase $ac_cv_target in\n*-*-*) ;;\n*) as_fn_error \"invalid value of canonical target\" \"$LINENO\" 5;;\nesac\ntarget=$ac_cv_target\nac_save_IFS=$IFS; IFS='-'\nset x $ac_cv_target\nshift\ntarget_cpu=$1\ntarget_vendor=$2\nshift; shift\n# Remember, the first character of IFS is used to create $*,\n# except with old shells:\ntarget_os=$*\nIFS=$ac_save_IFS\ncase $target_os in *\\ *) target_os=`echo \"$target_os\" | sed 's/ /-/g'`;; esac\n\n\n# The aliases save the names the user supplied, while $host etc.\n# will get canonicalized.\ntest -n \"$target_alias\" &&\n  test \"$program_prefix$program_suffix$program_transform_name\" = \\\n    NONENONEs,x,x, &&\n  program_prefix=${target_alias}-\n\n\ntarget_alias=${target_alias-$target}\n\n\n# 1.11.1: Require that version of automake.\n# foreign: Don't require README, INSTALL, NEWS, etc.\n# no-define: Don't define PACKAGE and VERSION.\n# no-dependencies: Don't generate automatic dependencies.\n#    (because it breaks when using bootstrap-lean, since some of the\n#    headers are gone at \"make install\" time).\n# -Wall: Issue all automake warnings.\n# -Wno-portability: Don't warn about constructs supported by GNU make.\n#    (because GCC requires GNU make anyhow).\nam__api_version='1.11'\n\n# Find a good install program.  We prefer a C program (faster),\n# so one script is as good as another.  But avoid the broken or\n# incompatible versions:\n# SysV /etc/install, /usr/sbin/install\n# SunOS /usr/etc/install\n# IRIX /sbin/install\n# AIX /bin/install\n# AmigaOS /C/install, which installs bootblocks on floppy discs\n# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag\n# AFS /usr/afsws/bin/install, which mishandles nonexistent args\n# SVR4 /usr/ucb/install, which tries to use the nonexistent group \"staff\"\n# OS/2's system install, which has a completely different semantic\n# ./install, which can be erroneously created by make from ./install.sh.\n# Reject install programs that cannot install multiple files.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install\" >&5\n$as_echo_n \"checking for a BSD-compatible install... \" >&6; }\nif test -z \"$INSTALL\"; then\nif test \"${ac_cv_path_install+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    # Account for people who put trailing slashes in PATH elements.\ncase $as_dir/ in #((\n  ./ | .// | /[cC]/* | \\\n  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \\\n  ?:[\\\\/]os2[\\\\/]install[\\\\/]* | ?:[\\\\/]OS2[\\\\/]INSTALL[\\\\/]* | \\\n  /usr/ucb/* ) ;;\n  *)\n    # OSF1 and SCO ODT 3.0 have their own names for install.\n    # Don't use installbsd from OSF since it installs stuff as root\n    # by default.\n    for ac_prog in ginstall scoinst install; do\n      for ac_exec_ext in '' $ac_executable_extensions; do\n\tif { test -f \"$as_dir/$ac_prog$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_prog$ac_exec_ext\"; }; then\n\t  if test $ac_prog = install &&\n\t    grep dspmsg \"$as_dir/$ac_prog$ac_exec_ext\" >/dev/null 2>&1; then\n\t    # AIX install.  It has an incompatible calling convention.\n\t    :\n\t  elif test $ac_prog = install &&\n\t    grep pwplus \"$as_dir/$ac_prog$ac_exec_ext\" >/dev/null 2>&1; then\n\t    # program-specific install script used by HP pwplus--don't use.\n\t    :\n\t  else\n\t    rm -rf conftest.one conftest.two conftest.dir\n\t    echo one > conftest.one\n\t    echo two > conftest.two\n\t    mkdir conftest.dir\n\t    if \"$as_dir/$ac_prog$ac_exec_ext\" -c conftest.one conftest.two \"`pwd`/conftest.dir\" &&\n\t      test -s conftest.one && test -s conftest.two &&\n\t      test -s conftest.dir/conftest.one &&\n\t      test -s conftest.dir/conftest.two\n\t    then\n\t      ac_cv_path_install=\"$as_dir/$ac_prog$ac_exec_ext -c\"\n\t      break 3\n\t    fi\n\t  fi\n\tfi\n      done\n    done\n    ;;\nesac\n\n  done\nIFS=$as_save_IFS\n\nrm -rf conftest.one conftest.two conftest.dir\n\nfi\n  if test \"${ac_cv_path_install+set}\" = set; then\n    INSTALL=$ac_cv_path_install\n  else\n    # As a last resort, use the slow shell script.  Don't cache a\n    # value for INSTALL within a source directory, because that will\n    # break other packages using the cache if that directory is\n    # removed, or if the value is a relative name.\n    INSTALL=$ac_install_sh\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $INSTALL\" >&5\n$as_echo \"$INSTALL\" >&6; }\n\n# Use test -z because SunOS4 sh mishandles braces in ${var-val}.\n# It thinks the first close brace ends the variable substitution.\ntest -z \"$INSTALL_PROGRAM\" && INSTALL_PROGRAM='${INSTALL}'\n\ntest -z \"$INSTALL_SCRIPT\" && INSTALL_SCRIPT='${INSTALL}'\n\ntest -z \"$INSTALL_DATA\" && INSTALL_DATA='${INSTALL} -m 644'\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether build environment is sane\" >&5\n$as_echo_n \"checking whether build environment is sane... \" >&6; }\n# Just in case\nsleep 1\necho timestamp > conftest.file\n# Reject unsafe characters in $srcdir or the absolute working directory\n# name.  Accept space and tab only in the latter.\nam_lf='\n'\ncase `pwd` in\n  *[\\\\\\\"\\#\\$\\&\\'\\`$am_lf]*)\n    as_fn_error \"unsafe absolute working directory name\" \"$LINENO\" 5;;\nesac\ncase $srcdir in\n  *[\\\\\\\"\\#\\$\\&\\'\\`$am_lf\\ \\\t]*)\n    as_fn_error \"unsafe srcdir value: \\`$srcdir'\" \"$LINENO\" 5;;\nesac\n\n# Do `set' in a subshell so we don't clobber the current shell's\n# arguments.  Must try -L first in case configure is actually a\n# symlink; some systems play weird games with the mod time of symlinks\n# (eg FreeBSD returns the mod time of the symlink's containing\n# directory).\nif (\n   set X `ls -Lt \"$srcdir/configure\" conftest.file 2> /dev/null`\n   if test \"$*\" = \"X\"; then\n      # -L didn't work.\n      set X `ls -t \"$srcdir/configure\" conftest.file`\n   fi\n   rm -f conftest.file\n   if test \"$*\" != \"X $srcdir/configure conftest.file\" \\\n      && test \"$*\" != \"X conftest.file $srcdir/configure\"; then\n\n      # If neither matched, then we have a broken ls.  This can happen\n      # if, for instance, CONFIG_SHELL is bash and it inherits a\n      # broken ls alias from the environment.  This has actually\n      # happened.  Such a system could not be considered \"sane\".\n      as_fn_error \"ls -t appears to fail.  Make sure there is not a broken\nalias in your environment\" \"$LINENO\" 5\n   fi\n\n   test \"$2\" = conftest.file\n   )\nthen\n   # Ok.\n   :\nelse\n   as_fn_error \"newly created file is older than distributed files!\nCheck your system clock\" \"$LINENO\" 5\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\ntest \"$program_prefix\" != NONE &&\n  program_transform_name=\"s&^&$program_prefix&;$program_transform_name\"\n# Use a double $ so make ignores it.\ntest \"$program_suffix\" != NONE &&\n  program_transform_name=\"s&\\$&$program_suffix&;$program_transform_name\"\n# Double any \\ or $.\n# By default was `s,x,x', remove it if useless.\nac_script='s/[\\\\$]/&&/g;s/;s,x,x,$//'\nprogram_transform_name=`$as_echo \"$program_transform_name\" | sed \"$ac_script\"`\n\n# expand $ac_aux_dir to an absolute path\nam_aux_dir=`cd $ac_aux_dir && pwd`\n\nif test x\"${MISSING+set}\" != xset; then\n  case $am_aux_dir in\n  *\\ * | *\\\t*)\n    MISSING=\"\\${SHELL} \\\"$am_aux_dir/missing\\\"\" ;;\n  *)\n    MISSING=\"\\${SHELL} $am_aux_dir/missing\" ;;\n  esac\nfi\n# Use eval to expand $SHELL\nif eval \"$MISSING --run true\"; then\n  am_missing_run=\"$MISSING --run \"\nelse\n  am_missing_run=\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: \\`missing' script is too old or missing\" >&5\n$as_echo \"$as_me: WARNING: \\`missing' script is too old or missing\" >&2;}\nfi\n\nif test x\"${install_sh}\" != xset; then\n  case $am_aux_dir in\n  *\\ * | *\\\t*)\n    install_sh=\"\\${SHELL} '$am_aux_dir/install-sh'\" ;;\n  *)\n    install_sh=\"\\${SHELL} $am_aux_dir/install-sh\"\n  esac\nfi\n\n# Installed binaries are usually stripped using `strip' when the user\n# run `make install-strip'.  However `strip' might not be the right\n# tool to use in cross-compilation environments, therefore Automake\n# will honor the `STRIP' environment variable to overrule this program.\nif test \"$cross_compiling\" != no; then\n  if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}strip\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}strip; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_STRIP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$STRIP\"; then\n  ac_cv_prog_STRIP=\"$STRIP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_STRIP=\"${ac_tool_prefix}strip\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nSTRIP=$ac_cv_prog_STRIP\nif test -n \"$STRIP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $STRIP\" >&5\n$as_echo \"$STRIP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_STRIP\"; then\n  ac_ct_STRIP=$STRIP\n  # Extract the first word of \"strip\", so it can be a program name with args.\nset dummy strip; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_STRIP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_STRIP\"; then\n  ac_cv_prog_ac_ct_STRIP=\"$ac_ct_STRIP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_STRIP=\"strip\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP\nif test -n \"$ac_ct_STRIP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP\" >&5\n$as_echo \"$ac_ct_STRIP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_STRIP\" = x; then\n    STRIP=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    STRIP=$ac_ct_STRIP\n  fi\nelse\n  STRIP=\"$ac_cv_prog_STRIP\"\nfi\n\nfi\nINSTALL_STRIP_PROGRAM=\"\\$(install_sh) -c -s\"\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p\" >&5\n$as_echo_n \"checking for a thread-safe mkdir -p... \" >&6; }\nif test -z \"$MKDIR_P\"; then\n  if test \"${ac_cv_path_mkdir+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in mkdir gmkdir; do\n\t for ac_exec_ext in '' $ac_executable_extensions; do\n\t   { test -f \"$as_dir/$ac_prog$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_prog$ac_exec_ext\"; } || continue\n\t   case `\"$as_dir/$ac_prog$ac_exec_ext\" --version 2>&1` in #(\n\t     'mkdir (GNU coreutils) '* | \\\n\t     'mkdir (coreutils) '* | \\\n\t     'mkdir (fileutils) '4.1*)\n\t       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext\n\t       break 3;;\n\t   esac\n\t done\n       done\n  done\nIFS=$as_save_IFS\n\nfi\n\n  if test \"${ac_cv_path_mkdir+set}\" = set; then\n    MKDIR_P=\"$ac_cv_path_mkdir -p\"\n  else\n    # As a last resort, use the slow shell script.  Don't cache a\n    # value for MKDIR_P within a source directory, because that will\n    # break other packages using the cache if that directory is\n    # removed, or if the value is a relative name.\n    test -d ./--version && rmdir ./--version\n    MKDIR_P=\"$ac_install_sh -d\"\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $MKDIR_P\" >&5\n$as_echo \"$MKDIR_P\" >&6; }\n\nmkdir_p=\"$MKDIR_P\"\ncase $mkdir_p in\n  [\\\\/$]* | ?:[\\\\/]*) ;;\n  */*) mkdir_p=\"\\$(top_builddir)/$mkdir_p\" ;;\nesac\n\nfor ac_prog in gawk mawk nawk awk\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_AWK+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$AWK\"; then\n  ac_cv_prog_AWK=\"$AWK\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_AWK=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nAWK=$ac_cv_prog_AWK\nif test -n \"$AWK\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $AWK\" >&5\n$as_echo \"$AWK\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$AWK\" && break\ndone\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \\$(MAKE)\" >&5\n$as_echo_n \"checking whether ${MAKE-make} sets \\$(MAKE)... \" >&6; }\nset x ${MAKE-make}\nac_make=`$as_echo \"$2\" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`\nif { as_var=ac_cv_prog_make_${ac_make}_set; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat >conftest.make <<\\_ACEOF\nSHELL = /bin/sh\nall:\n\t@echo '@@@%%%=$(MAKE)=@@@%%%'\n_ACEOF\n# GNU make sometimes prints \"make[1]: Entering...\", which would confuse us.\ncase `${MAKE-make} -f conftest.make 2>/dev/null` in\n  *@@@%%%=?*=@@@%%%*)\n    eval ac_cv_prog_make_${ac_make}_set=yes;;\n  *)\n    eval ac_cv_prog_make_${ac_make}_set=no;;\nesac\nrm -f conftest.make\nfi\nif eval test \\$ac_cv_prog_make_${ac_make}_set = yes; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n  SET_MAKE=\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n  SET_MAKE=\"MAKE=${MAKE-make}\"\nfi\n\nrm -rf .tst 2>/dev/null\nmkdir .tst 2>/dev/null\nif test -d .tst; then\n  am__leading_dot=.\nelse\n  am__leading_dot=_\nfi\nrmdir .tst 2>/dev/null\n\nif test \"`cd $srcdir && pwd`\" != \"`pwd`\"; then\n  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output\n  # is not polluted with repeated \"-I.\"\n  am__isrc=' -I$(srcdir)'\n  # test to see if srcdir already configured\n  if test -f $srcdir/config.status; then\n    as_fn_error \"source directory already configured; run \\\"make distclean\\\" there first\" \"$LINENO\" 5\n  fi\nfi\n\n# test whether we have cygpath\nif test -z \"$CYGPATH_W\"; then\n  if (cygpath --version) >/dev/null 2>/dev/null; then\n    CYGPATH_W='cygpath -w'\n  else\n    CYGPATH_W=echo\n  fi\nfi\n\n\n# Define the identity of the package.\n PACKAGE='libphobos'\n VERSION='version-unused'\n\n\n# Some tools Automake needs.\n\nACLOCAL=${ACLOCAL-\"${am_missing_run}aclocal-${am__api_version}\"}\n\n\nAUTOCONF=${AUTOCONF-\"${am_missing_run}autoconf\"}\n\n\nAUTOMAKE=${AUTOMAKE-\"${am_missing_run}automake-${am__api_version}\"}\n\n\nAUTOHEADER=${AUTOHEADER-\"${am_missing_run}autoheader\"}\n\n\nMAKEINFO=${MAKEINFO-\"${am_missing_run}makeinfo\"}\n\n# We need awk for the \"check\" target.  The system \"awk\" is bad on\n# some platforms.\n# Always define AMTAR for backward compatibility.  Yes, it's still used\n# in the wild :-(  We should find a proper way to deprecate it ...\nAMTAR='$${TAR-tar}'\n\nam__tar='$${TAR-tar} chof - \"$$tardir\"' am__untar='$${TAR-tar} xf -'\n\n\n\n\n\n\n\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}gcc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}gcc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}gcc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_CC\"; then\n  ac_ct_CC=$CC\n  # Extract the first word of \"gcc\", so it can be a program name with args.\nset dummy gcc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_CC=\"gcc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC\" >&5\n$as_echo \"$ac_ct_CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_CC\" = x; then\n    CC=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CC=$ac_ct_CC\n  fi\nelse\n  CC=\"$ac_cv_prog_CC\"\nfi\n\nif test -z \"$CC\"; then\n          if test -n \"$ac_tool_prefix\"; then\n    # Extract the first word of \"${ac_tool_prefix}cc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}cc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}cc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  fi\nfi\nif test -z \"$CC\"; then\n  # Extract the first word of \"cc\", so it can be a program name with args.\nset dummy cc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\n  ac_prog_rejected=no\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    if test \"$as_dir/$ac_word$ac_exec_ext\" = \"/usr/ucb/cc\"; then\n       ac_prog_rejected=yes\n       continue\n     fi\n    ac_cv_prog_CC=\"cc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nif test $ac_prog_rejected = yes; then\n  # We found a bogon in the path, so make sure we never use it.\n  set dummy $ac_cv_prog_CC\n  shift\n  if test $# != 0; then\n    # We chose a different compiler from the bogus one.\n    # However, it has the same basename, so the bogon will be chosen\n    # first if we set CC to just the basename; use the full file name.\n    shift\n    ac_cv_prog_CC=\"$as_dir/$ac_word${1+' '}$@\"\n  fi\nfi\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$CC\"; then\n  if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in cl.exe\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_CC=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$CC\" && break\n  done\nfi\nif test -z \"$CC\"; then\n  ac_ct_CC=$CC\n  for ac_prog in cl.exe\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_CC=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC\" >&5\n$as_echo \"$ac_ct_CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_CC\" && break\ndone\n\n  if test \"x$ac_ct_CC\" = x; then\n    CC=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CC=$ac_ct_CC\n  fi\nfi\n\nfi\n\n\ntest -z \"$CC\" && { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error \"no acceptable C compiler found in \\$PATH\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }\n\n# Provide some information about the compiler.\n$as_echo \"$as_me:${as_lineno-$LINENO}: checking for C compiler version\" >&5\nset X $ac_compile\nac_compiler=$2\nfor ac_option in --version -v -V -qversion; do\n  { { ac_try=\"$ac_compiler $ac_option >&5\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compiler $ac_option >&5\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    sed '10a\\\n... rest of stderr output deleted ...\n         10q' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    rm -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\ndone\n\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nac_clean_files_save=$ac_clean_files\nac_clean_files=\"$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out\"\n# Try to create an executable without -o first, disregard a.out.\n# It will help us diagnose broken compilers, and finding out an intuition\n# of exeext.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name\" >&5\n$as_echo_n \"checking for C compiler default output file name... \" >&6; }\nac_link_default=`$as_echo \"$ac_link\" | sed 's/ -o *conftest[^ ]*//'`\n\n# The possible output files:\nac_files=\"a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*\"\n\nac_rmfiles=\nfor ac_file in $ac_files\ndo\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;\n    * ) ac_rmfiles=\"$ac_rmfiles $ac_file\";;\n  esac\ndone\nrm -f $ac_rmfiles\n\nif { { ac_try=\"$ac_link_default\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link_default\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.\n# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'\n# in a Makefile.  We should not override ac_cv_exeext if it was cached,\n# so that the user can short-circuit this test for compilers unknown to\n# Autoconf.\nfor ac_file in $ac_files ''\ndo\n  test -f \"$ac_file\" || continue\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )\n\t;;\n    [ab].out )\n\t# We found the default executable, but exeext='' is most\n\t# certainly right.\n\tbreak;;\n    *.* )\n\tif test \"${ac_cv_exeext+set}\" = set && test \"$ac_cv_exeext\" != no;\n\tthen :; else\n\t   ac_cv_exeext=`expr \"$ac_file\" : '[^.]*\\(\\..*\\)'`\n\tfi\n\t# We set ac_cv_exeext here because the later test for it is not\n\t# safe: cross compilers may not add the suffix if given an `-o'\n\t# argument, so we may need to know it at that point already.\n\t# Even if this section looks crufty: it has the advantage of\n\t# actually working.\n\tbreak;;\n    * )\n\tbreak;;\n  esac\ndone\ntest \"$ac_cv_exeext\" = no && ac_cv_exeext=\n\nelse\n  ac_file=''\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_file\" >&5\n$as_echo \"$ac_file\" >&6; }\nif test -z \"$ac_file\"; then :\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\n{ as_fn_set_status 77\nas_fn_error \"C compiler cannot create executables\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }; }\nfi\nac_exeext=$ac_cv_exeext\n\n# Check that the compiler produces executables we can run.  If not, either\n# the compiler is broken, or we cross compile.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the C compiler works\" >&5\n$as_echo_n \"checking whether the C compiler works... \" >&6; }\n# If not cross compiling, check that we can run a simple program.\nif test \"$cross_compiling\" != yes; then\n  if { ac_try='./$ac_file'\n  { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; }; then\n    cross_compiling=no\n  else\n    if test \"$cross_compiling\" = maybe; then\n\tcross_compiling=yes\n    else\n\t{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error \"cannot run C compiled programs.\nIf you meant to cross compile, use \\`--host'.\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }\n    fi\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\nrm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out\nac_clean_files=$ac_clean_files_save\n# Check that the compiler produces executables we can run.  If not, either\n# the compiler is broken, or we cross compile.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling\" >&5\n$as_echo_n \"checking whether we are cross compiling... \" >&6; }\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $cross_compiling\" >&5\n$as_echo \"$cross_compiling\" >&6; }\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for suffix of executables\" >&5\n$as_echo_n \"checking for suffix of executables... \" >&6; }\nif { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  # If both `conftest.exe' and `conftest' are `present' (well, observable)\n# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will\n# work properly (i.e., refer to `conftest.exe'), while it won't with\n# `rm'.\nfor ac_file in conftest.exe conftest conftest.*; do\n  test -f \"$ac_file\" || continue\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;\n    *.* ) ac_cv_exeext=`expr \"$ac_file\" : '[^.]*\\(\\..*\\)'`\n\t  break;;\n    * ) break;;\n  esac\ndone\nelse\n  { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error \"cannot compute suffix of executables: cannot compile and link\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }\nfi\nrm -f conftest$ac_cv_exeext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext\" >&5\n$as_echo \"$ac_cv_exeext\" >&6; }\n\nrm -f conftest.$ac_ext\nEXEEXT=$ac_cv_exeext\nac_exeext=$EXEEXT\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for suffix of object files\" >&5\n$as_echo_n \"checking for suffix of object files... \" >&6; }\nif test \"${ac_cv_objext+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.o conftest.obj\nif { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  for ac_file in conftest.o conftest.obj conftest.*; do\n  test -f \"$ac_file\" || continue;\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;\n    *) ac_cv_objext=`expr \"$ac_file\" : '.*\\.\\(.*\\)'`\n       break;;\n  esac\ndone\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error \"cannot compute suffix of object files: cannot compile\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }\nfi\nrm -f conftest.$ac_cv_objext conftest.$ac_ext\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext\" >&5\n$as_echo \"$ac_cv_objext\" >&6; }\nOBJEXT=$ac_cv_objext\nac_objext=$OBJEXT\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler\" >&5\n$as_echo_n \"checking whether we are using the GNU C compiler... \" >&6; }\nif test \"${ac_cv_c_compiler_gnu+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n#ifndef __GNUC__\n       choke me\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_compiler_gnu=yes\nelse\n  ac_compiler_gnu=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nac_cv_c_compiler_gnu=$ac_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu\" >&5\n$as_echo \"$ac_cv_c_compiler_gnu\" >&6; }\nif test $ac_compiler_gnu = yes; then\n  GCC=yes\nelse\n  GCC=\nfi\nac_test_CFLAGS=${CFLAGS+set}\nac_save_CFLAGS=$CFLAGS\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g\" >&5\n$as_echo_n \"checking whether $CC accepts -g... \" >&6; }\nif test \"${ac_cv_prog_cc_g+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_save_c_werror_flag=$ac_c_werror_flag\n   ac_c_werror_flag=yes\n   ac_cv_prog_cc_g=no\n   CFLAGS=\"-g\"\n   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_g=yes\nelse\n  CFLAGS=\"\"\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\nelse\n  ac_c_werror_flag=$ac_save_c_werror_flag\n\t CFLAGS=\"-g\"\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_g=yes\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n   ac_c_werror_flag=$ac_save_c_werror_flag\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g\" >&5\n$as_echo \"$ac_cv_prog_cc_g\" >&6; }\nif test \"$ac_test_CFLAGS\" = set; then\n  CFLAGS=$ac_save_CFLAGS\nelif test $ac_cv_prog_cc_g = yes; then\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-g -O2\"\n  else\n    CFLAGS=\"-g\"\n  fi\nelse\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-O2\"\n  else\n    CFLAGS=\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89\" >&5\n$as_echo_n \"checking for $CC option to accept ISO C89... \" >&6; }\nif test \"${ac_cv_prog_cc_c89+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_cv_prog_cc_c89=no\nac_save_CC=$CC\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdarg.h>\n#include <stdio.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */\nstruct buf { int x; };\nFILE * (*rcsopen) (struct buf *, struct stat *, int);\nstatic char *e (p, i)\n     char **p;\n     int i;\n{\n  return p[i];\n}\nstatic char *f (char * (*g) (char **, int), char **p, ...)\n{\n  char *s;\n  va_list v;\n  va_start (v,p);\n  s = g (p, va_arg (v,int));\n  va_end (v);\n  return s;\n}\n\n/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has\n   function prototypes and stuff, but not '\\xHH' hex character constants.\n   These don't provoke an error unfortunately, instead are silently treated\n   as 'x'.  The following induces an error, until -std is added to get\n   proper ANSI mode.  Curiously '\\x00'!='x' always comes out true, for an\n   array size at least.  It's necessary to write '\\x00'==0 to get something\n   that's true only with -std.  */\nint osf4_cc_array ['\\x00' == 0 ? 1 : -1];\n\n/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters\n   inside strings and character constants.  */\n#define FOO(x) 'x'\nint xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];\n\nint test (int i, double x);\nstruct s1 {int (*f) (int a);};\nstruct s2 {int (*f) (double a);};\nint pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);\nint argc;\nchar **argv;\nint\nmain ()\n{\nreturn f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];\n  ;\n  return 0;\n}\n_ACEOF\nfor ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \\\n\t-Ae \"-Aa -D_HPUX_SOURCE\" \"-Xc -D__EXTENSIONS__\"\ndo\n  CC=\"$ac_save_CC $ac_arg\"\n  if ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_c89=$ac_arg\nfi\nrm -f core conftest.err conftest.$ac_objext\n  test \"x$ac_cv_prog_cc_c89\" != \"xno\" && break\ndone\nrm -f conftest.$ac_ext\nCC=$ac_save_CC\n\nfi\n# AC_CACHE_VAL\ncase \"x$ac_cv_prog_cc_c89\" in\n  x)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: none needed\" >&5\n$as_echo \"none needed\" >&6; } ;;\n  xno)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: unsupported\" >&5\n$as_echo \"unsupported\" >&6; } ;;\n  *)\n    CC=\"$CC $ac_cv_prog_cc_c89\"\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89\" >&5\n$as_echo \"$ac_cv_prog_cc_c89\" >&6; } ;;\nesac\nif test \"x$ac_cv_prog_cc_c89\" != xno; then :\n\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n# By default we simply use the C compiler to build assembly code.\n\ntest \"${CCAS+set}\" = set || CCAS=$CC\ntest \"${CCASFLAGS+set}\" = set || CCASFLAGS=$CFLAGS\n\n\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}gcc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}gcc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}gcc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_CC\"; then\n  ac_ct_CC=$CC\n  # Extract the first word of \"gcc\", so it can be a program name with args.\nset dummy gcc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_CC=\"gcc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC\" >&5\n$as_echo \"$ac_ct_CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_CC\" = x; then\n    CC=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CC=$ac_ct_CC\n  fi\nelse\n  CC=\"$ac_cv_prog_CC\"\nfi\n\nif test -z \"$CC\"; then\n          if test -n \"$ac_tool_prefix\"; then\n    # Extract the first word of \"${ac_tool_prefix}cc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}cc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}cc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  fi\nfi\nif test -z \"$CC\"; then\n  # Extract the first word of \"cc\", so it can be a program name with args.\nset dummy cc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\n  ac_prog_rejected=no\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    if test \"$as_dir/$ac_word$ac_exec_ext\" = \"/usr/ucb/cc\"; then\n       ac_prog_rejected=yes\n       continue\n     fi\n    ac_cv_prog_CC=\"cc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nif test $ac_prog_rejected = yes; then\n  # We found a bogon in the path, so make sure we never use it.\n  set dummy $ac_cv_prog_CC\n  shift\n  if test $# != 0; then\n    # We chose a different compiler from the bogus one.\n    # However, it has the same basename, so the bogon will be chosen\n    # first if we set CC to just the basename; use the full file name.\n    shift\n    ac_cv_prog_CC=\"$as_dir/$ac_word${1+' '}$@\"\n  fi\nfi\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$CC\"; then\n  if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in cl.exe\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_CC=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$CC\" && break\n  done\nfi\nif test -z \"$CC\"; then\n  ac_ct_CC=$CC\n  for ac_prog in cl.exe\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_CC=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC\" >&5\n$as_echo \"$ac_ct_CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_CC\" && break\ndone\n\n  if test \"x$ac_ct_CC\" = x; then\n    CC=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CC=$ac_ct_CC\n  fi\nfi\n\nfi\n\n\ntest -z \"$CC\" && { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error \"no acceptable C compiler found in \\$PATH\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }\n\n# Provide some information about the compiler.\n$as_echo \"$as_me:${as_lineno-$LINENO}: checking for C compiler version\" >&5\nset X $ac_compile\nac_compiler=$2\nfor ac_option in --version -v -V -qversion; do\n  { { ac_try=\"$ac_compiler $ac_option >&5\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compiler $ac_option >&5\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    sed '10a\\\n... rest of stderr output deleted ...\n         10q' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    rm -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\ndone\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler\" >&5\n$as_echo_n \"checking whether we are using the GNU C compiler... \" >&6; }\nif test \"${ac_cv_c_compiler_gnu+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n#ifndef __GNUC__\n       choke me\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_compiler_gnu=yes\nelse\n  ac_compiler_gnu=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nac_cv_c_compiler_gnu=$ac_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu\" >&5\n$as_echo \"$ac_cv_c_compiler_gnu\" >&6; }\nif test $ac_compiler_gnu = yes; then\n  GCC=yes\nelse\n  GCC=\nfi\nac_test_CFLAGS=${CFLAGS+set}\nac_save_CFLAGS=$CFLAGS\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g\" >&5\n$as_echo_n \"checking whether $CC accepts -g... \" >&6; }\nif test \"${ac_cv_prog_cc_g+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_save_c_werror_flag=$ac_c_werror_flag\n   ac_c_werror_flag=yes\n   ac_cv_prog_cc_g=no\n   CFLAGS=\"-g\"\n   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_g=yes\nelse\n  CFLAGS=\"\"\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\nelse\n  ac_c_werror_flag=$ac_save_c_werror_flag\n\t CFLAGS=\"-g\"\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_g=yes\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n   ac_c_werror_flag=$ac_save_c_werror_flag\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g\" >&5\n$as_echo \"$ac_cv_prog_cc_g\" >&6; }\nif test \"$ac_test_CFLAGS\" = set; then\n  CFLAGS=$ac_save_CFLAGS\nelif test $ac_cv_prog_cc_g = yes; then\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-g -O2\"\n  else\n    CFLAGS=\"-g\"\n  fi\nelse\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-O2\"\n  else\n    CFLAGS=\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89\" >&5\n$as_echo_n \"checking for $CC option to accept ISO C89... \" >&6; }\nif test \"${ac_cv_prog_cc_c89+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_cv_prog_cc_c89=no\nac_save_CC=$CC\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdarg.h>\n#include <stdio.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */\nstruct buf { int x; };\nFILE * (*rcsopen) (struct buf *, struct stat *, int);\nstatic char *e (p, i)\n     char **p;\n     int i;\n{\n  return p[i];\n}\nstatic char *f (char * (*g) (char **, int), char **p, ...)\n{\n  char *s;\n  va_list v;\n  va_start (v,p);\n  s = g (p, va_arg (v,int));\n  va_end (v);\n  return s;\n}\n\n/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has\n   function prototypes and stuff, but not '\\xHH' hex character constants.\n   These don't provoke an error unfortunately, instead are silently treated\n   as 'x'.  The following induces an error, until -std is added to get\n   proper ANSI mode.  Curiously '\\x00'!='x' always comes out true, for an\n   array size at least.  It's necessary to write '\\x00'==0 to get something\n   that's true only with -std.  */\nint osf4_cc_array ['\\x00' == 0 ? 1 : -1];\n\n/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters\n   inside strings and character constants.  */\n#define FOO(x) 'x'\nint xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];\n\nint test (int i, double x);\nstruct s1 {int (*f) (int a);};\nstruct s2 {int (*f) (double a);};\nint pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);\nint argc;\nchar **argv;\nint\nmain ()\n{\nreturn f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];\n  ;\n  return 0;\n}\n_ACEOF\nfor ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \\\n\t-Ae \"-Aa -D_HPUX_SOURCE\" \"-Xc -D__EXTENSIONS__\"\ndo\n  CC=\"$ac_save_CC $ac_arg\"\n  if ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_c89=$ac_arg\nfi\nrm -f core conftest.err conftest.$ac_objext\n  test \"x$ac_cv_prog_cc_c89\" != \"xno\" && break\ndone\nrm -f conftest.$ac_ext\nCC=$ac_save_CC\n\nfi\n# AC_CACHE_VAL\ncase \"x$ac_cv_prog_cc_c89\" in\n  x)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: none needed\" >&5\n$as_echo \"none needed\" >&6; } ;;\n  xno)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: unsupported\" >&5\n$as_echo \"unsupported\" >&6; } ;;\n  *)\n    CC=\"$CC $ac_cv_prog_cc_c89\"\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89\" >&5\n$as_echo \"$ac_cv_prog_cc_c89\" >&6; } ;;\nesac\nif test \"x$ac_cv_prog_cc_c89\" != xno; then :\n\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nac_ext=d\nac_compile='$GDC -c $GDCFLAGS conftest.$ac_ext >&5'\nac_link='$GDC -o conftest$ac_exeext $GDCFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=yes\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}gdc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}gdc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_GDC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$GDC\"; then\n  ac_cv_prog_GDC=\"$GDC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_GDC=\"${ac_tool_prefix}gdc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nGDC=$ac_cv_prog_GDC\nif test -n \"$GDC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $GDC\" >&5\n$as_echo \"$GDC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_GDC\"; then\n  ac_ct_GDC=$GDC\n  # Extract the first word of \"gdc\", so it can be a program name with args.\nset dummy gdc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_GDC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_GDC\"; then\n  ac_cv_prog_ac_ct_GDC=\"$ac_ct_GDC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_GDC=\"gdc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_GDC=$ac_cv_prog_ac_ct_GDC\nif test -n \"$ac_ct_GDC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_GDC\" >&5\n$as_echo \"$ac_ct_GDC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_GDC\" = x; then\n    GDC=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    GDC=$ac_ct_GDC\n  fi\nelse\n  GDC=\"$ac_cv_prog_GDC\"\nfi\n\nif test -z \"$GDC\"; then\n  if test -n \"$ac_tool_prefix\"; then\n    # Extract the first word of \"${ac_tool_prefix}gdc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}gdc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_GDC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$GDC\"; then\n  ac_cv_prog_GDC=\"$GDC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_GDC=\"$ac_tool_prefix}gdc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nGDC=$ac_cv_prog_GDC\nif test -n \"$GDC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $GDC\" >&5\n$as_echo \"$GDC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  fi\nfi\nif test -z \"$GDC\"; then\n  # Extract the first word of \"gdc\", so it can be a program name with args.\nset dummy gdc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_GDC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$GDC\"; then\n  ac_cv_prog_GDC=\"$GDC\" # Let the user override the test.\nelse\n  ac_prog_rejected=no\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    if test \"$as_dir/$ac_word$ac_exec_ext\" = \"false\"; then\n       ac_prog_rejected=yes\n       continue\n     fi\n    ac_cv_prog_GDC=\"gdc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nif test $ac_prog_rejected = yes; then\n  # We found a bogon in the path, so make sure we never use it.\n  set dummy $ac_cv_prog_GDC\n  shift\n  if test $# != 0; then\n    # We chose a different compiler from the bogus one.\n    # However, it has the same basename, so the bogon will be chosen\n    # first if we set GDC to just the basename; use the full file name.\n    shift\n    ac_cv_prog_GDC=\"$as_dir/$ac_word${1+' '}$@\"\n  fi\nfi\nfi\nfi\nGDC=$ac_cv_prog_GDC\nif test -n \"$GDC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $GDC\" >&5\n$as_echo \"$GDC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\n\n\n# Provide some information about the compiler.\n$as_echo \"$as_me:${as_lineno-$LINENO}: checking for D compiler version\" >&5\nset X $ac_compile\nac_compiler=$2\n{ { ac_try=\"$ac_compiler --version >&5\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compiler --version >&5\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    sed '10a\\\n... rest of stderr output deleted ...\n         10q' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    rm -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for absolute libphobos source path\" >&5\n$as_echo_n \"checking for absolute libphobos source path... \" >&6; }\nif test \"${phobos_cv_abs_srcdir+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  phobos_cv_abs_srcdir=`cd $srcdir && pwd`\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $phobos_cv_abs_srcdir\" >&5\n$as_echo \"$phobos_cv_abs_srcdir\" >&6; }\n    if test -d \"$phobos_cv_abs_srcdir\"; then :\n\nelse\n  as_fn_error \"can't find absolute libphobos source path\" \"$LINENO\" 5\nfi\n\n\n\n\n  gdc_save_DFLAGS=$GDCFLAGS\n  GDCFLAGS=\"-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime  $GDCFLAGS\"\n\n  ac_ext=d\nac_compile='$GDC -c $GDCFLAGS conftest.$ac_ext >&5'\nac_link='$GDC -o conftest$ac_exeext $GDCFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=yes\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking If $GDC can compile D sources\" >&5\n$as_echo_n \"checking If $GDC can compile D sources... \" >&6; }\n    cat > conftest.$ac_ext <<_ACEOF\nmodule mod;\n\n\nextern(C) int main() {\n  return 0;\n}\n_ACEOF\nif ac_fn_d_try_compile \"$LINENO\"; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n       as_fn_error \"can't compile D sources!\" \"$LINENO\" 5\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n  ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n  GDCFLAGS=$gdc_save_DFLAGS\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles\" >&5\n$as_echo_n \"checking whether to enable maintainer-specific portions of Makefiles... \" >&6; }\n    # Check whether --enable-maintainer-mode was given.\nif test \"${enable_maintainer_mode+set}\" = set; then :\n  enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval\nelse\n  USE_MAINTAINER_MODE=no\nfi\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE\" >&5\n$as_echo \"$USE_MAINTAINER_MODE\" >&6; }\n   if test $USE_MAINTAINER_MODE = yes; then\n  MAINTAINER_MODE_TRUE=\n  MAINTAINER_MODE_FALSE='#'\nelse\n  MAINTAINER_MODE_TRUE='#'\n  MAINTAINER_MODE_FALSE=\nfi\n\n  MAINT=$MAINTAINER_MODE_TRUE\n\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}ranlib\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}ranlib; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_RANLIB+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$RANLIB\"; then\n  ac_cv_prog_RANLIB=\"$RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_RANLIB=\"${ac_tool_prefix}ranlib\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nRANLIB=$ac_cv_prog_RANLIB\nif test -n \"$RANLIB\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $RANLIB\" >&5\n$as_echo \"$RANLIB\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_RANLIB\"; then\n  ac_ct_RANLIB=$RANLIB\n  # Extract the first word of \"ranlib\", so it can be a program name with args.\nset dummy ranlib; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_RANLIB+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_RANLIB\"; then\n  ac_cv_prog_ac_ct_RANLIB=\"$ac_ct_RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_RANLIB=\"ranlib\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB\nif test -n \"$ac_ct_RANLIB\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB\" >&5\n$as_echo \"$ac_ct_RANLIB\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_RANLIB\" = x; then\n    RANLIB=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    RANLIB=$ac_ct_RANLIB\n  fi\nelse\n  RANLIB=\"$ac_cv_prog_RANLIB\"\nfi\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \\$(MAKE)\" >&5\n$as_echo_n \"checking whether ${MAKE-make} sets \\$(MAKE)... \" >&6; }\nset x ${MAKE-make}\nac_make=`$as_echo \"$2\" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`\nif { as_var=ac_cv_prog_make_${ac_make}_set; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat >conftest.make <<\\_ACEOF\nSHELL = /bin/sh\nall:\n\t@echo '@@@%%%=$(MAKE)=@@@%%%'\n_ACEOF\n# GNU make sometimes prints \"make[1]: Entering...\", which would confuse us.\ncase `${MAKE-make} -f conftest.make 2>/dev/null` in\n  *@@@%%%=?*=@@@%%%*)\n    eval ac_cv_prog_make_${ac_make}_set=yes;;\n  *)\n    eval ac_cv_prog_make_${ac_make}_set=no;;\nesac\nrm -f conftest.make\nfi\nif eval test \\$ac_cv_prog_make_${ac_make}_set = yes; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n  SET_MAKE=\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n  SET_MAKE=\"MAKE=${MAKE-make}\"\nfi\n\n\n# This should be inherited in the recursive make, but ensure it is defined.\ntest \"$AR\" || AR=ar\n\n\nCC_FOR_BUILD=${CC_FOR_BUILD:-gcc}\n\n\n\n# Enable libtool\ncase `pwd` in\n  *\\ * | *\\\t*)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \\`pwd\\`\" >&5\n$as_echo \"$as_me: WARNING: Libtool does not cope well with whitespace in \\`pwd\\`\" >&2;} ;;\nesac\n\n\n\nmacro_version='2.2.7a'\nmacro_revision='1.3134'\n\n\n\n\n\n\n\n\n\n\n\n\n\nltmain=\"$ac_aux_dir/ltmain.sh\"\n\n# Backslashify metacharacters that are still active within\n# double-quoted strings.\nsed_quote_subst='s/\\([\"`$\\\\]\\)/\\\\\\1/g'\n\n# Same as above, but do not quote variable references.\ndouble_quote_subst='s/\\([\"`\\\\]\\)/\\\\\\1/g'\n\n# Sed substitution to delay expansion of an escaped shell variable in a\n# double_quote_subst'ed string.\ndelay_variable_subst='s/\\\\\\\\\\\\\\\\\\\\\\$/\\\\\\\\\\\\$/g'\n\n# Sed substitution to delay expansion of an escaped single quote.\ndelay_single_quote_subst='s/'\\''/'\\'\\\\\\\\\\\\\\'\\''/g'\n\n# Sed substitution to avoid accidental globbing in evaled expressions\nno_glob_subst='s/\\*/\\\\\\*/g'\n\nECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nECHO=$ECHO$ECHO$ECHO$ECHO$ECHO\nECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to print strings\" >&5\n$as_echo_n \"checking how to print strings... \" >&6; }\n# Test print first, because it will be a builtin if present.\nif test \"X`print -r -- -n 2>/dev/null`\" = X-n && \\\n   test \"X`print -r -- $ECHO 2>/dev/null`\" = \"X$ECHO\"; then\n  ECHO='print -r --'\nelif test \"X`printf %s $ECHO 2>/dev/null`\" = \"X$ECHO\"; then\n  ECHO='printf %s\\n'\nelse\n  # Use this function as a fallback that always works.\n  func_fallback_echo ()\n  {\n    eval 'cat <<_LTECHO_EOF\n$1\n_LTECHO_EOF'\n  }\n  ECHO='func_fallback_echo'\nfi\n\n# func_echo_all arg...\n# Invoke $ECHO with all args, space-separated.\nfunc_echo_all ()\n{\n    $ECHO \"\"\n}\n\ncase \"$ECHO\" in\n  printf*) { $as_echo \"$as_me:${as_lineno-$LINENO}: result: printf\" >&5\n$as_echo \"printf\" >&6; } ;;\n  print*) { $as_echo \"$as_me:${as_lineno-$LINENO}: result: print -r\" >&5\n$as_echo \"print -r\" >&6; } ;;\n  *) { $as_echo \"$as_me:${as_lineno-$LINENO}: result: cat\" >&5\n$as_echo \"cat\" >&6; } ;;\nesac\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output\" >&5\n$as_echo_n \"checking for a sed that does not truncate output... \" >&6; }\nif test \"${ac_cv_path_SED+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/\n     for ac_i in 1 2 3 4 5 6 7; do\n       ac_script=\"$ac_script$as_nl$ac_script\"\n     done\n     echo \"$ac_script\" 2>/dev/null | sed 99q >conftest.sed\n     { ac_script=; unset ac_script;}\n     if test -z \"$SED\"; then\n  ac_path_SED_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in sed gsed; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_SED=\"$as_dir/$ac_prog$ac_exec_ext\"\n      { test -f \"$ac_path_SED\" && $as_test_x \"$ac_path_SED\"; } || continue\n# Check for GNU ac_path_SED and select it if it is found.\n  # Check for GNU $ac_path_SED\ncase `\"$ac_path_SED\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_SED=\"$ac_path_SED\" ac_path_SED_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo '' >> \"conftest.nl\"\n    \"$ac_path_SED\" -f conftest.sed < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_SED_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_SED=\"$ac_path_SED\"\n      ac_path_SED_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_SED_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_SED\"; then\n    as_fn_error \"no acceptable sed could be found in \\$PATH\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_SED=$SED\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED\" >&5\n$as_echo \"$ac_cv_path_SED\" >&6; }\n SED=\"$ac_cv_path_SED\"\n  rm -f conftest.sed\n\ntest -z \"$SED\" && SED=sed\nXsed=\"$SED -e 1s/^X//\"\n\n\n\n\n\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e\" >&5\n$as_echo_n \"checking for grep that handles long lines and -e... \" >&6; }\nif test \"${ac_cv_path_GREP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -z \"$GREP\"; then\n  ac_path_GREP_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in grep ggrep; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_GREP=\"$as_dir/$ac_prog$ac_exec_ext\"\n      { test -f \"$ac_path_GREP\" && $as_test_x \"$ac_path_GREP\"; } || continue\n# Check for GNU ac_path_GREP and select it if it is found.\n  # Check for GNU $ac_path_GREP\ncase `\"$ac_path_GREP\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_GREP=\"$ac_path_GREP\" ac_path_GREP_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo 'GREP' >> \"conftest.nl\"\n    \"$ac_path_GREP\" -e 'GREP$' -e '-(cannot match)-' < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_GREP_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_GREP=\"$ac_path_GREP\"\n      ac_path_GREP_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_GREP_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_GREP\"; then\n    as_fn_error \"no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_GREP=$GREP\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP\" >&5\n$as_echo \"$ac_cv_path_GREP\" >&6; }\n GREP=\"$ac_cv_path_GREP\"\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for egrep\" >&5\n$as_echo_n \"checking for egrep... \" >&6; }\nif test \"${ac_cv_path_EGREP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1\n   then ac_cv_path_EGREP=\"$GREP -E\"\n   else\n     if test -z \"$EGREP\"; then\n  ac_path_EGREP_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in egrep; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_EGREP=\"$as_dir/$ac_prog$ac_exec_ext\"\n      { test -f \"$ac_path_EGREP\" && $as_test_x \"$ac_path_EGREP\"; } || continue\n# Check for GNU ac_path_EGREP and select it if it is found.\n  # Check for GNU $ac_path_EGREP\ncase `\"$ac_path_EGREP\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_EGREP=\"$ac_path_EGREP\" ac_path_EGREP_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo 'EGREP' >> \"conftest.nl\"\n    \"$ac_path_EGREP\" 'EGREP$' < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_EGREP_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_EGREP=\"$ac_path_EGREP\"\n      ac_path_EGREP_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_EGREP_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_EGREP\"; then\n    as_fn_error \"no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_EGREP=$EGREP\nfi\n\n   fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP\" >&5\n$as_echo \"$ac_cv_path_EGREP\" >&6; }\n EGREP=\"$ac_cv_path_EGREP\"\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for fgrep\" >&5\n$as_echo_n \"checking for fgrep... \" >&6; }\nif test \"${ac_cv_path_FGREP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1\n   then ac_cv_path_FGREP=\"$GREP -F\"\n   else\n     if test -z \"$FGREP\"; then\n  ac_path_FGREP_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in fgrep; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_FGREP=\"$as_dir/$ac_prog$ac_exec_ext\"\n      { test -f \"$ac_path_FGREP\" && $as_test_x \"$ac_path_FGREP\"; } || continue\n# Check for GNU ac_path_FGREP and select it if it is found.\n  # Check for GNU $ac_path_FGREP\ncase `\"$ac_path_FGREP\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_FGREP=\"$ac_path_FGREP\" ac_path_FGREP_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo 'FGREP' >> \"conftest.nl\"\n    \"$ac_path_FGREP\" FGREP < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_FGREP_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_FGREP=\"$ac_path_FGREP\"\n      ac_path_FGREP_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_FGREP_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_FGREP\"; then\n    as_fn_error \"no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_FGREP=$FGREP\nfi\n\n   fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP\" >&5\n$as_echo \"$ac_cv_path_FGREP\" >&6; }\n FGREP=\"$ac_cv_path_FGREP\"\n\n\ntest -z \"$GREP\" && GREP=grep\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n# Check whether --with-gnu-ld was given.\nif test \"${with_gnu_ld+set}\" = set; then :\n  withval=$with_gnu_ld; test \"$withval\" = no || with_gnu_ld=yes\nelse\n  with_gnu_ld=no\nfi\n\nac_prog=ld\nif test \"$GCC\" = yes; then\n  # Check if gcc -print-prog-name=ld gives a path.\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ld used by $CC\" >&5\n$as_echo_n \"checking for ld used by $CC... \" >&6; }\n  case $host in\n  *-*-mingw*)\n    # gcc leaves a trailing carriage return which upsets mingw\n    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\\015'` ;;\n  *)\n    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;\n  esac\n  case $ac_prog in\n    # Accept absolute paths.\n    [\\\\/]* | ?:[\\\\/]*)\n      re_direlt='/[^/][^/]*/\\.\\./'\n      # Canonicalize the pathname of ld\n      ac_prog=`$ECHO \"$ac_prog\"| $SED 's%\\\\\\\\%/%g'`\n      while $ECHO \"$ac_prog\" | $GREP \"$re_direlt\" > /dev/null 2>&1; do\n\tac_prog=`$ECHO $ac_prog| $SED \"s%$re_direlt%/%\"`\n      done\n      test -z \"$LD\" && LD=\"$ac_prog\"\n      ;;\n  \"\")\n    # If it fails, then pretend we aren't using GCC.\n    ac_prog=ld\n    ;;\n  *)\n    # If it is relative, then search for the first ld in PATH.\n    with_gnu_ld=unknown\n    ;;\n  esac\nelif test \"$with_gnu_ld\" = yes; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for GNU ld\" >&5\n$as_echo_n \"checking for GNU ld... \" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for non-GNU ld\" >&5\n$as_echo_n \"checking for non-GNU ld... \" >&6; }\nfi\nif test \"${lt_cv_path_LD+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -z \"$LD\"; then\n  lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n  for ac_dir in $PATH; do\n    IFS=\"$lt_save_ifs\"\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f \"$ac_dir/$ac_prog\" || test -f \"$ac_dir/$ac_prog$ac_exeext\"; then\n      lt_cv_path_LD=\"$ac_dir/$ac_prog\"\n      # Check to see if the program is GNU ld.  I'd rather use --version,\n      # but apparently some variants of GNU ld only accept -v.\n      # Break only if it was the GNU/non-GNU ld that we prefer.\n      case `\"$lt_cv_path_LD\" -v 2>&1 </dev/null` in\n      *GNU* | *'with BFD'*)\n\ttest \"$with_gnu_ld\" != no && break\n\t;;\n      *)\n\ttest \"$with_gnu_ld\" != yes && break\n\t;;\n      esac\n    fi\n  done\n  IFS=\"$lt_save_ifs\"\nelse\n  lt_cv_path_LD=\"$LD\" # Let the user override the test with a path.\nfi\nfi\n\nLD=\"$lt_cv_path_LD\"\nif test -n \"$LD\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $LD\" >&5\n$as_echo \"$LD\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\ntest -z \"$LD\" && as_fn_error \"no acceptable ld found in \\$PATH\" \"$LINENO\" 5\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld\" >&5\n$as_echo_n \"checking if the linker ($LD) is GNU ld... \" >&6; }\nif test \"${lt_cv_prog_gnu_ld+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  # I'd rather use --version here, but apparently some GNU lds only accept -v.\ncase `$LD -v 2>&1 </dev/null` in\n*GNU* | *'with BFD'*)\n  lt_cv_prog_gnu_ld=yes\n  ;;\n*)\n  lt_cv_prog_gnu_ld=no\n  ;;\nesac\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld\" >&5\n$as_echo \"$lt_cv_prog_gnu_ld\" >&6; }\nwith_gnu_ld=$lt_cv_prog_gnu_ld\n\n\n\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)\" >&5\n$as_echo_n \"checking for BSD- or MS-compatible name lister (nm)... \" >&6; }\nif test \"${lt_cv_path_NM+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$NM\"; then\n  # Let the user override the test.\n  lt_cv_path_NM=\"$NM\"\nelse\n  lt_nm_to_check=\"${ac_tool_prefix}nm\"\n  if test -n \"$ac_tool_prefix\" && test \"$build\" = \"$host\"; then\n    lt_nm_to_check=\"$lt_nm_to_check nm\"\n  fi\n  for lt_tmp_nm in $lt_nm_to_check; do\n    lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do\n      IFS=\"$lt_save_ifs\"\n      test -z \"$ac_dir\" && ac_dir=.\n      tmp_nm=\"$ac_dir/$lt_tmp_nm\"\n      if test -f \"$tmp_nm\" || test -f \"$tmp_nm$ac_exeext\" ; then\n\t# Check to see if the nm accepts a BSD-compat flag.\n\t# Adding the `sed 1q' prevents false positives on HP-UX, which says:\n\t#   nm: unknown option \"B\" ignored\n\t# Tru64's nm complains that /dev/null is an invalid object file\n\tcase `\"$tmp_nm\" -B /dev/null 2>&1 | sed '1q'` in\n\t*/dev/null* | *'Invalid file or object type'*)\n\t  lt_cv_path_NM=\"$tmp_nm -B\"\n\t  break\n\t  ;;\n\t*)\n\t  case `\"$tmp_nm\" -p /dev/null 2>&1 | sed '1q'` in\n\t  */dev/null*)\n\t    lt_cv_path_NM=\"$tmp_nm -p\"\n\t    break\n\t    ;;\n\t  *)\n\t    lt_cv_path_NM=${lt_cv_path_NM=\"$tmp_nm\"} # keep the first match, but\n\t    continue # so that we can try to find one that supports BSD flags\n\t    ;;\n\t  esac\n\t  ;;\n\tesac\n      fi\n    done\n    IFS=\"$lt_save_ifs\"\n  done\n  : ${lt_cv_path_NM=no}\nfi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM\" >&5\n$as_echo \"$lt_cv_path_NM\" >&6; }\nif test \"$lt_cv_path_NM\" != \"no\"; then\n  NM=\"$lt_cv_path_NM\"\nelse\n  # Didn't find any BSD compatible name lister, look for dumpbin.\n  if test -n \"$DUMPBIN\"; then :\n    # Let the user override the test.\n  else\n    if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in dumpbin \"link -dump\"\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_DUMPBIN+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$DUMPBIN\"; then\n  ac_cv_prog_DUMPBIN=\"$DUMPBIN\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_DUMPBIN=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nDUMPBIN=$ac_cv_prog_DUMPBIN\nif test -n \"$DUMPBIN\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $DUMPBIN\" >&5\n$as_echo \"$DUMPBIN\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$DUMPBIN\" && break\n  done\nfi\nif test -z \"$DUMPBIN\"; then\n  ac_ct_DUMPBIN=$DUMPBIN\n  for ac_prog in dumpbin \"link -dump\"\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_DUMPBIN+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_DUMPBIN\"; then\n  ac_cv_prog_ac_ct_DUMPBIN=\"$ac_ct_DUMPBIN\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_DUMPBIN=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN\nif test -n \"$ac_ct_DUMPBIN\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN\" >&5\n$as_echo \"$ac_ct_DUMPBIN\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_DUMPBIN\" && break\ndone\n\n  if test \"x$ac_ct_DUMPBIN\" = x; then\n    DUMPBIN=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    DUMPBIN=$ac_ct_DUMPBIN\n  fi\nfi\n\n    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in\n    *COFF*)\n      DUMPBIN=\"$DUMPBIN -symbols\"\n      ;;\n    *)\n      DUMPBIN=:\n      ;;\n    esac\n  fi\n\n  if test \"$DUMPBIN\" != \":\"; then\n    NM=\"$DUMPBIN\"\n  fi\nfi\ntest -z \"$NM\" && NM=nm\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface\" >&5\n$as_echo_n \"checking the name lister ($NM) interface... \" >&6; }\nif test \"${lt_cv_nm_interface+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_nm_interface=\"BSD nm\"\n  echo \"int some_variable = 0;\" > conftest.$ac_ext\n  (eval echo \"\\\"\\$as_me:$LINENO: $ac_compile\\\"\" >&5)\n  (eval \"$ac_compile\" 2>conftest.err)\n  cat conftest.err >&5\n  (eval echo \"\\\"\\$as_me:$LINENO: $NM \\\\\\\"conftest.$ac_objext\\\\\\\"\\\"\" >&5)\n  (eval \"$NM \\\"conftest.$ac_objext\\\"\" 2>conftest.err > conftest.out)\n  cat conftest.err >&5\n  (eval echo \"\\\"\\$as_me:$LINENO: output\\\"\" >&5)\n  cat conftest.out >&5\n  if $GREP 'External.*some_variable' conftest.out > /dev/null; then\n    lt_cv_nm_interface=\"MS dumpbin\"\n  fi\n  rm -f conftest*\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface\" >&5\n$as_echo \"$lt_cv_nm_interface\" >&6; }\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether ln -s works\" >&5\n$as_echo_n \"checking whether ln -s works... \" >&6; }\nLN_S=$as_ln_s\nif test \"$LN_S\" = \"ln -s\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no, using $LN_S\" >&5\n$as_echo \"no, using $LN_S\" >&6; }\nfi\n\n# find the maximum length of command line arguments\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments\" >&5\n$as_echo_n \"checking the maximum length of command line arguments... \" >&6; }\nif test \"${lt_cv_sys_max_cmd_len+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n    i=0\n  teststring=\"ABCD\"\n\n  case $build_os in\n  msdosdjgpp*)\n    # On DJGPP, this test can blow up pretty badly due to problems in libc\n    # (any single argument exceeding 2000 bytes causes a buffer overrun\n    # during glob expansion).  Even if it were fixed, the result of this\n    # check would be larger than it should be.\n    lt_cv_sys_max_cmd_len=12288;    # 12K is about right\n    ;;\n\n  gnu*)\n    # Under GNU Hurd, this test is not required because there is\n    # no limit to the length of command line arguments.\n    # Libtool will interpret -1 as no limit whatsoever\n    lt_cv_sys_max_cmd_len=-1;\n    ;;\n\n  cygwin* | mingw* | cegcc*)\n    # On Win9x/ME, this test blows up -- it succeeds, but takes\n    # about 5 minutes as the teststring grows exponentially.\n    # Worse, since 9x/ME are not pre-emptively multitasking,\n    # you end up with a \"frozen\" computer, even though with patience\n    # the test eventually succeeds (with a max line length of 256k).\n    # Instead, let's just punt: use the minimum linelength reported by\n    # all of the supported platforms: 8192 (on NT/2K/XP).\n    lt_cv_sys_max_cmd_len=8192;\n    ;;\n\n  mint*)\n    # On MiNT this can take a long time and run out of memory.\n    lt_cv_sys_max_cmd_len=8192;\n    ;;\n\n  amigaos*)\n    # On AmigaOS with pdksh, this test takes hours, literally.\n    # So we just punt and use a minimum line length of 8192.\n    lt_cv_sys_max_cmd_len=8192;\n    ;;\n\n  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)\n    # This has been around since 386BSD, at least.  Likely further.\n    if test -x /sbin/sysctl; then\n      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`\n    elif test -x /usr/sbin/sysctl; then\n      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`\n    else\n      lt_cv_sys_max_cmd_len=65536\t# usable default for all BSDs\n    fi\n    # And add a safety zone\n    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 4`\n    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\* 3`\n    ;;\n\n  interix*)\n    # We know the value 262144 and hardcode it with a safety zone (like BSD)\n    lt_cv_sys_max_cmd_len=196608\n    ;;\n\n  osf*)\n    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure\n    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not\n    # nice to cause kernel panics so lets avoid the loop below.\n    # First set a reasonable default.\n    lt_cv_sys_max_cmd_len=16384\n    #\n    if test -x /sbin/sysconfig; then\n      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in\n        *1*) lt_cv_sys_max_cmd_len=-1 ;;\n      esac\n    fi\n    ;;\n  sco3.2v5*)\n    lt_cv_sys_max_cmd_len=102400\n    ;;\n  sysv5* | sco5v6* | sysv4.2uw2*)\n    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`\n    if test -n \"$kargmax\"; then\n      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[\t ]//'`\n    else\n      lt_cv_sys_max_cmd_len=32768\n    fi\n    ;;\n  *)\n    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`\n    if test -n \"$lt_cv_sys_max_cmd_len\"; then\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 4`\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\* 3`\n    else\n      # Make teststring a little bigger before we do anything with it.\n      # a 1K string should be a reasonable start.\n      for i in 1 2 3 4 5 6 7 8 ; do\n        teststring=$teststring$teststring\n      done\n      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}\n      # If test is not a shell built-in, we'll probably end up computing a\n      # maximum length that is only half of the actual maximum length, but\n      # we can't tell.\n      while { test \"X\"`func_fallback_echo \"$teststring$teststring\" 2>/dev/null` \\\n\t         = \"X$teststring$teststring\"; } >/dev/null 2>&1 &&\n\t      test $i != 17 # 1/2 MB should be enough\n      do\n        i=`expr $i + 1`\n        teststring=$teststring$teststring\n      done\n      # Only check the string length outside the loop.\n      lt_cv_sys_max_cmd_len=`expr \"X$teststring\" : \".*\" 2>&1`\n      teststring=\n      # Add a significant safety factor because C++ compilers can tack on\n      # massive amounts of additional arguments before passing them to the\n      # linker.  It appears as though 1/2 is a usable value.\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 2`\n    fi\n    ;;\n  esac\n\nfi\n\nif test -n $lt_cv_sys_max_cmd_len ; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len\" >&5\n$as_echo \"$lt_cv_sys_max_cmd_len\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: none\" >&5\n$as_echo \"none\" >&6; }\nfi\nmax_cmd_len=$lt_cv_sys_max_cmd_len\n\n\n\n\n\n\n: ${CP=\"cp -f\"}\n: ${MV=\"mv -f\"}\n: ${RM=\"rm -f\"}\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs\" >&5\n$as_echo_n \"checking whether the shell understands some XSI constructs... \" >&6; }\n# Try some XSI features\nxsi_shell=no\n( _lt_dummy=\"a/b/c\"\n  test \"${_lt_dummy##*/},${_lt_dummy%/*},\"${_lt_dummy%\"$_lt_dummy\"}, \\\n      = c,a/b,, \\\n    && eval 'test $(( 1 + 1 )) -eq 2 \\\n    && test \"${#_lt_dummy}\" -eq 5' ) >/dev/null 2>&1 \\\n  && xsi_shell=yes\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $xsi_shell\" >&5\n$as_echo \"$xsi_shell\" >&6; }\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the shell understands \\\"+=\\\"\" >&5\n$as_echo_n \"checking whether the shell understands \\\"+=\\\"... \" >&6; }\nlt_shell_append=no\n( foo=bar; set foo baz; eval \"$1+=\\$2\" && test \"$foo\" = barbaz ) \\\n    >/dev/null 2>&1 \\\n  && lt_shell_append=yes\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_shell_append\" >&5\n$as_echo \"$lt_shell_append\" >&6; }\n\n\nif ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then\n  lt_unset=unset\nelse\n  lt_unset=false\nfi\n\n\n\n\n\n# test EBCDIC or ASCII\ncase `echo X|tr X '\\101'` in\n A) # ASCII based system\n    # \\n is not interpreted correctly by Solaris 8 /usr/ucb/tr\n  lt_SP2NL='tr \\040 \\012'\n  lt_NL2SP='tr \\015\\012 \\040\\040'\n  ;;\n *) # EBCDIC based system\n  lt_SP2NL='tr \\100 \\n'\n  lt_NL2SP='tr \\r\\n \\100\\100'\n  ;;\nesac\n\n\n\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files\" >&5\n$as_echo_n \"checking for $LD option to reload object files... \" >&6; }\nif test \"${lt_cv_ld_reload_flag+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_ld_reload_flag='-r'\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag\" >&5\n$as_echo \"$lt_cv_ld_reload_flag\" >&6; }\nreload_flag=$lt_cv_ld_reload_flag\ncase $reload_flag in\n\"\" | \" \"*) ;;\n*) reload_flag=\" $reload_flag\" ;;\nesac\nreload_cmds='$LD$reload_flag -o $output$reload_objs'\ncase $host_os in\n  darwin*)\n    if test \"$GCC\" = yes; then\n      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'\n    else\n      reload_cmds='$LD$reload_flag -o $output$reload_objs'\n    fi\n    ;;\nesac\n\n\n\n\n\n\n\n\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}objdump\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}objdump; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_OBJDUMP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$OBJDUMP\"; then\n  ac_cv_prog_OBJDUMP=\"$OBJDUMP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_OBJDUMP=\"${ac_tool_prefix}objdump\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nOBJDUMP=$ac_cv_prog_OBJDUMP\nif test -n \"$OBJDUMP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $OBJDUMP\" >&5\n$as_echo \"$OBJDUMP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_OBJDUMP\"; then\n  ac_ct_OBJDUMP=$OBJDUMP\n  # Extract the first word of \"objdump\", so it can be a program name with args.\nset dummy objdump; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_OBJDUMP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_OBJDUMP\"; then\n  ac_cv_prog_ac_ct_OBJDUMP=\"$ac_ct_OBJDUMP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_OBJDUMP=\"objdump\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP\nif test -n \"$ac_ct_OBJDUMP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP\" >&5\n$as_echo \"$ac_ct_OBJDUMP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_OBJDUMP\" = x; then\n    OBJDUMP=\"false\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    OBJDUMP=$ac_ct_OBJDUMP\n  fi\nelse\n  OBJDUMP=\"$ac_cv_prog_OBJDUMP\"\nfi\n\ntest -z \"$OBJDUMP\" && OBJDUMP=objdump\n\n\n\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries\" >&5\n$as_echo_n \"checking how to recognize dependent libraries... \" >&6; }\nif test \"${lt_cv_deplibs_check_method+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_file_magic_cmd='$MAGIC_CMD'\nlt_cv_file_magic_test_file=\nlt_cv_deplibs_check_method='unknown'\n# Need to set the preceding variable on all platforms that support\n# interlibrary dependencies.\n# 'none' -- dependencies not supported.\n# `unknown' -- same as none, but documents that we really don't know.\n# 'pass_all' -- all dependencies passed with no checks.\n# 'test_compile' -- check by making test program.\n# 'file_magic [[regex]]' -- check by looking for files in library path\n# which responds to the $file_magic_cmd with a given extended regex.\n# If you have `file' or equivalent on your system and you're not sure\n# whether `pass_all' will *always* work, you probably want this one.\n\ncase $host_os in\naix[4-9]*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nbeos*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nbsdi[45]*)\n  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'\n  lt_cv_file_magic_cmd='/usr/bin/file -L'\n  lt_cv_file_magic_test_file=/shlib/libc.so\n  ;;\n\ncygwin*)\n  # func_win32_libid is a shell function defined in ltmain.sh\n  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'\n  lt_cv_file_magic_cmd='func_win32_libid'\n  ;;\n\nmingw* | pw32*)\n  # Base MSYS/MinGW do not provide the 'file' command needed by\n  # func_win32_libid shell function, so use a weaker test based on 'objdump',\n  # unless we find 'file', for example because we are cross-compiling.\n  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.\n  if ( test \"$lt_cv_nm_interface\" = \"BSD nm\" && file / ) >/dev/null 2>&1; then\n    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'\n    lt_cv_file_magic_cmd='func_win32_libid'\n  else\n    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'\n    lt_cv_file_magic_cmd='$OBJDUMP -f'\n  fi\n  ;;\n\ncegcc*)\n  # use the weaker test based on 'objdump'. See mingw*.\n  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'\n  lt_cv_file_magic_cmd='$OBJDUMP -f'\n  ;;\n\ndarwin* | rhapsody*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nfreebsd* | dragonfly*)\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then\n    case $host_cpu in\n    i*86 )\n      # Not sure whether the presence of OpenBSD here was a mistake.\n      # Let's accept both of them until this is cleared up.\n      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'\n      lt_cv_file_magic_cmd=/usr/bin/file\n      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`\n      ;;\n    esac\n  else\n    lt_cv_deplibs_check_method=pass_all\n  fi\n  ;;\n\ngnu*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nhaiku*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nhpux10.20* | hpux11*)\n  lt_cv_file_magic_cmd=/usr/bin/file\n  case $host_cpu in\n  ia64*)\n    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'\n    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so\n    ;;\n  hppa*64*)\n    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\\.[0-9]'\n    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl\n    ;;\n  *)\n    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\\.[0-9]) shared library'\n    lt_cv_file_magic_test_file=/usr/lib/libc.sl\n    ;;\n  esac\n  ;;\n\ninterix[3-9]*)\n  # PIC code is broken on Interix 3.x, that's why |\\.a not |_pic\\.a here\n  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\\.so|\\.a)$'\n  ;;\n\nirix5* | irix6* | nonstopux*)\n  case $LD in\n  *-32|*\"-32 \") libmagic=32-bit;;\n  *-n32|*\"-n32 \") libmagic=N32;;\n  *-64|*\"-64 \") libmagic=64-bit;;\n  *) libmagic=never-match;;\n  esac\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\n# This must be Linux ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nnetbsd*)\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then\n    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\\.so\\.[0-9]+\\.[0-9]+|_pic\\.a)$'\n  else\n    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\\.so|_pic\\.a)$'\n  fi\n  ;;\n\nnewos6*)\n  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'\n  lt_cv_file_magic_cmd=/usr/bin/file\n  lt_cv_file_magic_test_file=/usr/lib/libnls.so\n  ;;\n\n*nto* | *qnx*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nopenbsd*)\n  if test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\\.so\\.[0-9]+\\.[0-9]+|\\.so|_pic\\.a)$'\n  else\n    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\\.so\\.[0-9]+\\.[0-9]+|_pic\\.a)$'\n  fi\n  ;;\n\nosf3* | osf4* | osf5*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nrdos*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsolaris*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsysv4 | sysv4.3*)\n  case $host_vendor in\n  motorola)\n    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'\n    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`\n    ;;\n  ncr)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  sequent)\n    lt_cv_file_magic_cmd='/bin/file'\n    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'\n    ;;\n  sni)\n    lt_cv_file_magic_cmd='/bin/file'\n    lt_cv_deplibs_check_method=\"file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib\"\n    lt_cv_file_magic_test_file=/lib/libc.so\n    ;;\n  siemens)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  pc)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  esac\n  ;;\n\ntpf*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\nesac\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method\" >&5\n$as_echo \"$lt_cv_deplibs_check_method\" >&6; }\nfile_magic_cmd=$lt_cv_file_magic_cmd\ndeplibs_check_method=$lt_cv_deplibs_check_method\ntest -z \"$deplibs_check_method\" && deplibs_check_method=unknown\n\n\n\n\n\n\n\n\n\n\n\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}ar\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}ar; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_AR+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$AR\"; then\n  ac_cv_prog_AR=\"$AR\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_AR=\"${ac_tool_prefix}ar\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nAR=$ac_cv_prog_AR\nif test -n \"$AR\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $AR\" >&5\n$as_echo \"$AR\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_AR\"; then\n  ac_ct_AR=$AR\n  # Extract the first word of \"ar\", so it can be a program name with args.\nset dummy ar; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_AR+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_AR\"; then\n  ac_cv_prog_ac_ct_AR=\"$ac_ct_AR\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_AR=\"ar\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_AR=$ac_cv_prog_ac_ct_AR\nif test -n \"$ac_ct_AR\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR\" >&5\n$as_echo \"$ac_ct_AR\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_AR\" = x; then\n    AR=\"false\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    AR=$ac_ct_AR\n  fi\nelse\n  AR=\"$ac_cv_prog_AR\"\nfi\n\ntest -z \"$AR\" && AR=ar\ntest -z \"$AR_FLAGS\" && AR_FLAGS=cru\n\n\n\n\n\n\n\n\n\n\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}strip\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}strip; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_STRIP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$STRIP\"; then\n  ac_cv_prog_STRIP=\"$STRIP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_STRIP=\"${ac_tool_prefix}strip\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nSTRIP=$ac_cv_prog_STRIP\nif test -n \"$STRIP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $STRIP\" >&5\n$as_echo \"$STRIP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_STRIP\"; then\n  ac_ct_STRIP=$STRIP\n  # Extract the first word of \"strip\", so it can be a program name with args.\nset dummy strip; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_STRIP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_STRIP\"; then\n  ac_cv_prog_ac_ct_STRIP=\"$ac_ct_STRIP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_STRIP=\"strip\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP\nif test -n \"$ac_ct_STRIP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP\" >&5\n$as_echo \"$ac_ct_STRIP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_STRIP\" = x; then\n    STRIP=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    STRIP=$ac_ct_STRIP\n  fi\nelse\n  STRIP=\"$ac_cv_prog_STRIP\"\nfi\n\ntest -z \"$STRIP\" && STRIP=:\n\n\n\n\n\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}ranlib\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}ranlib; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_RANLIB+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$RANLIB\"; then\n  ac_cv_prog_RANLIB=\"$RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_RANLIB=\"${ac_tool_prefix}ranlib\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nRANLIB=$ac_cv_prog_RANLIB\nif test -n \"$RANLIB\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $RANLIB\" >&5\n$as_echo \"$RANLIB\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_RANLIB\"; then\n  ac_ct_RANLIB=$RANLIB\n  # Extract the first word of \"ranlib\", so it can be a program name with args.\nset dummy ranlib; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_RANLIB+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_RANLIB\"; then\n  ac_cv_prog_ac_ct_RANLIB=\"$ac_ct_RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_RANLIB=\"ranlib\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB\nif test -n \"$ac_ct_RANLIB\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB\" >&5\n$as_echo \"$ac_ct_RANLIB\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_RANLIB\" = x; then\n    RANLIB=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    RANLIB=$ac_ct_RANLIB\n  fi\nelse\n  RANLIB=\"$ac_cv_prog_RANLIB\"\nfi\n\ntest -z \"$RANLIB\" && RANLIB=:\n\n\n\n\n\n\n# Determine commands to create old-style static archives.\nold_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'\nold_postinstall_cmds='chmod 644 $oldlib'\nold_postuninstall_cmds=\n\nif test -n \"$RANLIB\"; then\n  case $host_os in\n  openbsd*)\n    old_postinstall_cmds=\"$old_postinstall_cmds~\\$RANLIB -t \\$oldlib\"\n    ;;\n  *)\n    old_postinstall_cmds=\"$old_postinstall_cmds~\\$RANLIB \\$oldlib\"\n    ;;\n  esac\n  old_archive_cmds=\"$old_archive_cmds~\\$RANLIB \\$oldlib\"\nfi\n\ncase $host_os in\n  darwin*)\n    lock_old_archive_extraction=yes ;;\n  *)\n    lock_old_archive_extraction=no ;;\nesac\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n# If no C compiler was specified, use CC.\nLTCC=${LTCC-\"$CC\"}\n\n# If no C compiler flags were specified, use CFLAGS.\nLTCFLAGS=${LTCFLAGS-\"$CFLAGS\"}\n\n# Allow CC to be a program name with arguments.\ncompiler=$CC\n\n\n# Check for command to grab the raw symbol name followed by C symbol from nm.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object\" >&5\n$as_echo_n \"checking command to parse $NM output from $compiler object... \" >&6; }\nif test \"${lt_cv_sys_global_symbol_pipe+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n\n# These are sane defaults that work on at least a few old systems.\n# [They come from Ultrix.  What could be older than Ultrix?!! ;)]\n\n# Character class describing NM global symbol codes.\nsymcode='[BCDEGRST]'\n\n# Regexp to match symbols that can be accessed directly from C.\nsympat='\\([_A-Za-z][_A-Za-z0-9]*\\)'\n\n# Define system-specific variables.\ncase $host_os in\naix*)\n  symcode='[BCDT]'\n  ;;\ncygwin* | mingw* | pw32* | cegcc*)\n  symcode='[ABCDGISTW]'\n  ;;\nhpux*)\n  if test \"$host_cpu\" = ia64; then\n    symcode='[ABCDEGRST]'\n  fi\n  ;;\nirix* | nonstopux*)\n  symcode='[BCDEGRST]'\n  ;;\nosf*)\n  symcode='[BCDEGQRST]'\n  ;;\nsolaris*)\n  symcode='[BDRT]'\n  ;;\nsco3.2v5*)\n  symcode='[DT]'\n  ;;\nsysv4.2uw2*)\n  symcode='[DT]'\n  ;;\nsysv5* | sco5v6* | unixware* | OpenUNIX*)\n  symcode='[ABDT]'\n  ;;\nsysv4)\n  symcode='[DFNSTU]'\n  ;;\nesac\n\n# If we're using GNU nm, then use its standard symbol codes.\ncase `$NM -V 2>&1` in\n*GNU* | *'with BFD'*)\n  symcode='[ABCDGIRSTW]' ;;\nesac\n\n# Transform an extracted symbol line into a proper C declaration.\n# Some systems (esp. on ia64) link data and code symbols differently,\n# so use this general approach.\nlt_cv_sys_global_symbol_to_cdecl=\"sed -n -e 's/^T .* \\(.*\\)$/extern int \\1();/p' -e 's/^$symcode* .* \\(.*\\)$/extern char \\1;/p'\"\n\n# Transform an extracted symbol line into symbol name and symbol address\nlt_cv_sys_global_symbol_to_c_name_address=\"sed -n -e 's/^: \\([^ ]*\\) $/  {\\\\\\\"\\1\\\\\\\", (void *) 0},/p' -e 's/^$symcode* \\([^ ]*\\) \\([^ ]*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/p'\"\nlt_cv_sys_global_symbol_to_c_name_address_lib_prefix=\"sed -n -e 's/^: \\([^ ]*\\) $/  {\\\\\\\"\\1\\\\\\\", (void *) 0},/p' -e 's/^$symcode* \\([^ ]*\\) \\(lib[^ ]*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/p' -e 's/^$symcode* \\([^ ]*\\) \\([^ ]*\\)$/  {\\\"lib\\2\\\", (void *) \\&\\2},/p'\"\n\n# Handle CRLF in mingw tool chain\nopt_cr=\ncase $build_os in\nmingw*)\n  opt_cr=`$ECHO 'x\\{0,1\\}' | tr x '\\015'` # option cr in regexp\n  ;;\nesac\n\n# Try without a prefix underscore, then with it.\nfor ac_symprfx in \"\" \"_\"; do\n\n  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.\n  symxfrm=\"\\\\1 $ac_symprfx\\\\2 \\\\2\"\n\n  # Write the raw and C identifiers.\n  if test \"$lt_cv_nm_interface\" = \"MS dumpbin\"; then\n    # Fake it for dumpbin and say T for any non-static function\n    # and D for any global variable.\n    # Also find C++ and __fastcall symbols from MSVC++,\n    # which start with @ or ?.\n    lt_cv_sys_global_symbol_pipe=\"$AWK '\"\\\n\"     {last_section=section; section=\\$ 3};\"\\\n\"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};\"\\\n\"     \\$ 0!~/External *\\|/{next};\"\\\n\"     / 0+ UNDEF /{next}; / UNDEF \\([^|]\\)*()/{next};\"\\\n\"     {if(hide[section]) next};\"\\\n\"     {f=0}; \\$ 0~/\\(\\).*\\|/{f=1}; {printf f ? \\\"T \\\" : \\\"D \\\"};\"\\\n\"     {split(\\$ 0, a, /\\||\\r/); split(a[2], s)};\"\\\n\"     s[1]~/^[@?]/{print s[1], s[1]; next};\"\\\n\"     s[1]~prfx {split(s[1],t,\\\"@\\\"); print t[1], substr(t[1],length(prfx))}\"\\\n\"     ' prfx=^$ac_symprfx\"\n  else\n    lt_cv_sys_global_symbol_pipe=\"sed -n -e 's/^.*[\t ]\\($symcode$symcode*\\)[\t ][\t ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'\"\n  fi\n\n  # Check to see that the pipe works correctly.\n  pipe_works=no\n\n  rm -f conftest*\n  cat > conftest.$ac_ext <<_LT_EOF\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nchar nm_test_var;\nvoid nm_test_func(void);\nvoid nm_test_func(void){}\n#ifdef __cplusplus\n}\n#endif\nint main(){nm_test_var='a';nm_test_func();return(0);}\n_LT_EOF\n\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n    # Now try to grab the symbols.\n    nlist=conftest.nm\n    if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$NM conftest.$ac_objext \\| \"$lt_cv_sys_global_symbol_pipe\" \\> $nlist\\\"\"; } >&5\n  (eval $NM conftest.$ac_objext \\| \"$lt_cv_sys_global_symbol_pipe\" \\> $nlist) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && test -s \"$nlist\"; then\n      # Try sorting and uniquifying the output.\n      if sort \"$nlist\" | uniq > \"$nlist\"T; then\n\tmv -f \"$nlist\"T \"$nlist\"\n      else\n\trm -f \"$nlist\"T\n      fi\n\n      # Make sure that we snagged all the symbols we need.\n      if $GREP ' nm_test_var$' \"$nlist\" >/dev/null; then\n\tif $GREP ' nm_test_func$' \"$nlist\" >/dev/null; then\n\t  cat <<_LT_EOF > conftest.$ac_ext\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n_LT_EOF\n\t  # Now generate the symbol file.\n\t  eval \"$lt_cv_sys_global_symbol_to_cdecl\"' < \"$nlist\" | $GREP -v main >> conftest.$ac_ext'\n\n\t  cat <<_LT_EOF >> conftest.$ac_ext\n\n/* The mapping between symbol names and symbols.  */\nconst struct {\n  const char *name;\n  void       *address;\n}\nlt__PROGRAM__LTX_preloaded_symbols[] =\n{\n  { \"@PROGRAM@\", (void *) 0 },\n_LT_EOF\n\t  $SED \"s/^$symcode$symcode* \\(.*\\) \\(.*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/\" < \"$nlist\" | $GREP -v main >> conftest.$ac_ext\n\t  cat <<\\_LT_EOF >> conftest.$ac_ext\n  {0, (void *) 0}\n};\n\n/* This works around a problem in FreeBSD linker */\n#ifdef FREEBSD_WORKAROUND\nstatic const void *lt_preloaded_setup() {\n  return lt__PROGRAM__LTX_preloaded_symbols;\n}\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n_LT_EOF\n\t  # Now try linking the two files.\n\t  mv conftest.$ac_objext conftstm.$ac_objext\n\t  lt_save_LIBS=\"$LIBS\"\n\t  lt_save_CFLAGS=\"$CFLAGS\"\n\t  LIBS=\"conftstm.$ac_objext\"\n\t  CFLAGS=\"$CFLAGS$lt_prog_compiler_no_builtin_flag\"\n\t  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_link\\\"\"; } >&5\n  (eval $ac_link) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && test -s conftest${ac_exeext}; then\n\t    pipe_works=yes\n\t  fi\n\t  LIBS=\"$lt_save_LIBS\"\n\t  CFLAGS=\"$lt_save_CFLAGS\"\n\telse\n\t  echo \"cannot find nm_test_func in $nlist\" >&5\n\tfi\n      else\n\techo \"cannot find nm_test_var in $nlist\" >&5\n      fi\n    else\n      echo \"cannot run $lt_cv_sys_global_symbol_pipe\" >&5\n    fi\n  else\n    echo \"$progname: failed program was:\" >&5\n    cat conftest.$ac_ext >&5\n  fi\n  rm -rf conftest* conftst*\n\n  # Do not use the global_symbol_pipe unless it works.\n  if test \"$pipe_works\" = yes; then\n    break\n  else\n    lt_cv_sys_global_symbol_pipe=\n  fi\ndone\n\nfi\n\nif test -z \"$lt_cv_sys_global_symbol_pipe\"; then\n  lt_cv_sys_global_symbol_to_cdecl=\nfi\nif test -z \"$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: failed\" >&5\n$as_echo \"failed\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: ok\" >&5\n$as_echo \"ok\" >&6; }\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n# Check whether --enable-libtool-lock was given.\nif test \"${enable_libtool_lock+set}\" = set; then :\n  enableval=$enable_libtool_lock;\nfi\n\ntest \"x$enable_libtool_lock\" != xno && enable_libtool_lock=yes\n\n# Some flags need to be propagated to the compiler or linker for good\n# libtool support.\ncase $host in\nia64-*-hpux*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n    case `/usr/bin/file conftest.$ac_objext` in\n      *ELF-32*)\n\tHPUX_IA64_MODE=\"32\"\n\t;;\n      *ELF-64*)\n\tHPUX_IA64_MODE=\"64\"\n\t;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\n*-*-irix6*)\n  # Find out which ABI we are using.\n  echo '#line '$LINENO' \"configure\"' > conftest.$ac_ext\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n    if test \"$lt_cv_prog_gnu_ld\" = yes; then\n      case `/usr/bin/file conftest.$ac_objext` in\n\t*32-bit*)\n\t  LD=\"${LD-ld} -melf32bsmip\"\n\t  ;;\n\t*N32*)\n\t  LD=\"${LD-ld} -melf32bmipn32\"\n\t  ;;\n\t*64-bit*)\n\t  LD=\"${LD-ld} -melf64bmip\"\n\t;;\n      esac\n    else\n      case `/usr/bin/file conftest.$ac_objext` in\n\t*32-bit*)\n\t  LD=\"${LD-ld} -32\"\n\t  ;;\n\t*N32*)\n\t  LD=\"${LD-ld} -n32\"\n\t  ;;\n\t*64-bit*)\n\t  LD=\"${LD-ld} -64\"\n\t  ;;\n      esac\n    fi\n  fi\n  rm -rf conftest*\n  ;;\n\nx86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \\\ns390*-*linux*|s390*-*tpf*|sparc*-*linux*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n    case `/usr/bin/file conftest.o` in\n      *32-bit*)\n\tcase $host in\n\t  x86_64-*kfreebsd*-gnu)\n\t    LD=\"${LD-ld} -m elf_i386_fbsd\"\n\t    ;;\n\t  x86_64-*linux*)\n\t    case `/usr/bin/file conftest.o` in\n\t      *x86-64*)\n\t\tLD=\"${LD-ld} -m elf32_x86_64\"\n\t\t;;\n\t      *)\n\t\tLD=\"${LD-ld} -m elf_i386\"\n\t\t;;\n\t    esac\n\t    ;;\n\t  powerpc64le-*linux*)\n\t    LD=\"${LD-ld} -m elf32lppclinux\"\n\t    ;;\n\t  powerpc64-*linux*)\n\t    LD=\"${LD-ld} -m elf32ppclinux\"\n\t    ;;\n\t  s390x-*linux*)\n\t    LD=\"${LD-ld} -m elf_s390\"\n\t    ;;\n\t  sparc64-*linux*)\n\t    LD=\"${LD-ld} -m elf32_sparc\"\n\t    ;;\n\tesac\n\t;;\n      *64-bit*)\n\tcase $host in\n\t  x86_64-*kfreebsd*-gnu)\n\t    LD=\"${LD-ld} -m elf_x86_64_fbsd\"\n\t    ;;\n\t  x86_64-*linux*)\n\t    LD=\"${LD-ld} -m elf_x86_64\"\n\t    ;;\n\t  powerpcle-*linux*)\n\t    LD=\"${LD-ld} -m elf64lppc\"\n\t    ;;\n\t  powerpc-*linux*)\n\t    LD=\"${LD-ld} -m elf64ppc\"\n\t    ;;\n\t  s390*-*linux*|s390*-*tpf*)\n\t    LD=\"${LD-ld} -m elf64_s390\"\n\t    ;;\n\t  sparc*-*linux*)\n\t    LD=\"${LD-ld} -m elf64_sparc\"\n\t    ;;\n\tesac\n\t;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\n\n*-*-sco3.2v5*)\n  # On SCO OpenServer 5, we need -belf to get full-featured binaries.\n  SAVE_CFLAGS=\"$CFLAGS\"\n  CFLAGS=\"$CFLAGS -belf\"\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf\" >&5\n$as_echo_n \"checking whether the C compiler needs -belf... \" >&6; }\nif test \"${lt_cv_cc_needs_belf+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n     cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  lt_cv_cc_needs_belf=yes\nelse\n  lt_cv_cc_needs_belf=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n     ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf\" >&5\n$as_echo \"$lt_cv_cc_needs_belf\" >&6; }\n  if test x\"$lt_cv_cc_needs_belf\" != x\"yes\"; then\n    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf\n    CFLAGS=\"$SAVE_CFLAGS\"\n  fi\n  ;;\nsparc*-*solaris*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n    case `/usr/bin/file conftest.o` in\n    *64-bit*)\n      case $lt_cv_prog_gnu_ld in\n      yes*) LD=\"${LD-ld} -m elf64_sparc\" ;;\n      *)\n\tif ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then\n\t  LD=\"${LD-ld} -64\"\n\tfi\n\t;;\n      esac\n      ;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\nesac\n\nneed_locks=\"$enable_libtool_lock\"\n\n\n  case $host_os in\n    rhapsody* | darwin*)\n    if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}dsymutil\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}dsymutil; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_DSYMUTIL+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$DSYMUTIL\"; then\n  ac_cv_prog_DSYMUTIL=\"$DSYMUTIL\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_DSYMUTIL=\"${ac_tool_prefix}dsymutil\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nDSYMUTIL=$ac_cv_prog_DSYMUTIL\nif test -n \"$DSYMUTIL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL\" >&5\n$as_echo \"$DSYMUTIL\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_DSYMUTIL\"; then\n  ac_ct_DSYMUTIL=$DSYMUTIL\n  # Extract the first word of \"dsymutil\", so it can be a program name with args.\nset dummy dsymutil; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_DSYMUTIL+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_DSYMUTIL\"; then\n  ac_cv_prog_ac_ct_DSYMUTIL=\"$ac_ct_DSYMUTIL\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_DSYMUTIL=\"dsymutil\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL\nif test -n \"$ac_ct_DSYMUTIL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL\" >&5\n$as_echo \"$ac_ct_DSYMUTIL\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_DSYMUTIL\" = x; then\n    DSYMUTIL=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    DSYMUTIL=$ac_ct_DSYMUTIL\n  fi\nelse\n  DSYMUTIL=\"$ac_cv_prog_DSYMUTIL\"\nfi\n\n    if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}nmedit\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}nmedit; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_NMEDIT+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$NMEDIT\"; then\n  ac_cv_prog_NMEDIT=\"$NMEDIT\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_NMEDIT=\"${ac_tool_prefix}nmedit\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nNMEDIT=$ac_cv_prog_NMEDIT\nif test -n \"$NMEDIT\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $NMEDIT\" >&5\n$as_echo \"$NMEDIT\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_NMEDIT\"; then\n  ac_ct_NMEDIT=$NMEDIT\n  # Extract the first word of \"nmedit\", so it can be a program name with args.\nset dummy nmedit; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_NMEDIT+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_NMEDIT\"; then\n  ac_cv_prog_ac_ct_NMEDIT=\"$ac_ct_NMEDIT\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_NMEDIT=\"nmedit\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT\nif test -n \"$ac_ct_NMEDIT\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT\" >&5\n$as_echo \"$ac_ct_NMEDIT\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_NMEDIT\" = x; then\n    NMEDIT=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    NMEDIT=$ac_ct_NMEDIT\n  fi\nelse\n  NMEDIT=\"$ac_cv_prog_NMEDIT\"\nfi\n\n    if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}lipo\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}lipo; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_LIPO+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$LIPO\"; then\n  ac_cv_prog_LIPO=\"$LIPO\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_LIPO=\"${ac_tool_prefix}lipo\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nLIPO=$ac_cv_prog_LIPO\nif test -n \"$LIPO\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $LIPO\" >&5\n$as_echo \"$LIPO\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_LIPO\"; then\n  ac_ct_LIPO=$LIPO\n  # Extract the first word of \"lipo\", so it can be a program name with args.\nset dummy lipo; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_LIPO+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_LIPO\"; then\n  ac_cv_prog_ac_ct_LIPO=\"$ac_ct_LIPO\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_LIPO=\"lipo\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO\nif test -n \"$ac_ct_LIPO\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO\" >&5\n$as_echo \"$ac_ct_LIPO\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_LIPO\" = x; then\n    LIPO=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    LIPO=$ac_ct_LIPO\n  fi\nelse\n  LIPO=\"$ac_cv_prog_LIPO\"\nfi\n\n    if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}otool\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}otool; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_OTOOL+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$OTOOL\"; then\n  ac_cv_prog_OTOOL=\"$OTOOL\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_OTOOL=\"${ac_tool_prefix}otool\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nOTOOL=$ac_cv_prog_OTOOL\nif test -n \"$OTOOL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $OTOOL\" >&5\n$as_echo \"$OTOOL\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_OTOOL\"; then\n  ac_ct_OTOOL=$OTOOL\n  # Extract the first word of \"otool\", so it can be a program name with args.\nset dummy otool; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_OTOOL+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_OTOOL\"; then\n  ac_cv_prog_ac_ct_OTOOL=\"$ac_ct_OTOOL\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_OTOOL=\"otool\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL\nif test -n \"$ac_ct_OTOOL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL\" >&5\n$as_echo \"$ac_ct_OTOOL\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_OTOOL\" = x; then\n    OTOOL=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    OTOOL=$ac_ct_OTOOL\n  fi\nelse\n  OTOOL=\"$ac_cv_prog_OTOOL\"\nfi\n\n    if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}otool64\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}otool64; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_OTOOL64+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$OTOOL64\"; then\n  ac_cv_prog_OTOOL64=\"$OTOOL64\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_OTOOL64=\"${ac_tool_prefix}otool64\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nOTOOL64=$ac_cv_prog_OTOOL64\nif test -n \"$OTOOL64\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $OTOOL64\" >&5\n$as_echo \"$OTOOL64\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_OTOOL64\"; then\n  ac_ct_OTOOL64=$OTOOL64\n  # Extract the first word of \"otool64\", so it can be a program name with args.\nset dummy otool64; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_OTOOL64+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_OTOOL64\"; then\n  ac_cv_prog_ac_ct_OTOOL64=\"$ac_ct_OTOOL64\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_OTOOL64=\"otool64\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64\nif test -n \"$ac_ct_OTOOL64\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64\" >&5\n$as_echo \"$ac_ct_OTOOL64\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_OTOOL64\" = x; then\n    OTOOL64=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    OTOOL64=$ac_ct_OTOOL64\n  fi\nelse\n  OTOOL64=\"$ac_cv_prog_OTOOL64\"\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag\" >&5\n$as_echo_n \"checking for -single_module linker flag... \" >&6; }\nif test \"${lt_cv_apple_cc_single_mod+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_apple_cc_single_mod=no\n      if test -z \"${LT_MULTI_MODULE}\"; then\n\t# By default we will add the -single_module flag. You can override\n\t# by either setting the environment variable LT_MULTI_MODULE\n\t# non-empty at configure time, or by adding -multi_module to the\n\t# link flags.\n\trm -rf libconftest.dylib*\n\techo \"int foo(void){return 1;}\" > conftest.c\n\techo \"$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \\\n-dynamiclib -Wl,-single_module conftest.c\" >&5\n\t$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \\\n\t  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err\n        _lt_result=$?\n\tif test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then\n\t  lt_cv_apple_cc_single_mod=yes\n\telse\n\t  cat conftest.err >&5\n\tfi\n\trm -rf libconftest.dylib*\n\trm -f conftest.*\n      fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod\" >&5\n$as_echo \"$lt_cv_apple_cc_single_mod\" >&6; }\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag\" >&5\n$as_echo_n \"checking for -exported_symbols_list linker flag... \" >&6; }\nif test \"${lt_cv_ld_exported_symbols_list+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_ld_exported_symbols_list=no\n      save_LDFLAGS=$LDFLAGS\n      echo \"_main\" > conftest.sym\n      LDFLAGS=\"$LDFLAGS -Wl,-exported_symbols_list,conftest.sym\"\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  lt_cv_ld_exported_symbols_list=yes\nelse\n  lt_cv_ld_exported_symbols_list=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\tLDFLAGS=\"$save_LDFLAGS\"\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list\" >&5\n$as_echo \"$lt_cv_ld_exported_symbols_list\" >&6; }\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag\" >&5\n$as_echo_n \"checking for -force_load linker flag... \" >&6; }\nif test \"${lt_cv_ld_force_load+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_ld_force_load=no\n      cat > conftest.c << _LT_EOF\nint forced_loaded() { return 2;}\n_LT_EOF\n      echo \"$LTCC $LTCFLAGS -c -o conftest.o conftest.c\" >&5\n      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5\n      echo \"$AR cru libconftest.a conftest.o\" >&5\n      $AR cru libconftest.a conftest.o 2>&5\n      cat > conftest.c << _LT_EOF\nint main() { return 0;}\n_LT_EOF\n      echo \"$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a\" >&5\n      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err\n      _lt_result=$?\n      if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then\n\tlt_cv_ld_force_load=yes\n      else\n\tcat conftest.err >&5\n      fi\n        rm -f conftest.err libconftest.a conftest conftest.c\n        rm -rf conftest.dSYM\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load\" >&5\n$as_echo \"$lt_cv_ld_force_load\" >&6; }\n    case $host_os in\n    rhapsody* | darwin1.[012])\n      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;\n    darwin1.*)\n      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;\n    darwin*) # darwin 5.x on\n      # if running on 10.5 or later, the deployment target defaults\n      # to the OS version, if on x86, and 10.4, the deployment\n      # target defaults to 10.4. Don't you love it?\n      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in\n\t10.0,*86*-darwin8*|10.0,*-darwin[91]*)\n\t  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;\n\t10.[012][,.]*)\n\t  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;\n\t10.*)\n\t  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;\n      esac\n    ;;\n  esac\n    if test \"$lt_cv_apple_cc_single_mod\" = \"yes\"; then\n      _lt_dar_single_mod='$single_module'\n    fi\n    if test \"$lt_cv_ld_exported_symbols_list\" = \"yes\"; then\n      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'\n    else\n      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'\n    fi\n    if test \"$DSYMUTIL\" != \":\" && test \"$lt_cv_ld_force_load\" = \"no\"; then\n      _lt_dsymutil='~$DSYMUTIL $lib || :'\n    else\n      _lt_dsymutil=\n    fi\n    ;;\n  esac\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor\" >&5\n$as_echo_n \"checking how to run the C preprocessor... \" >&6; }\n# On Suns, sometimes $CPP names a directory.\nif test -n \"$CPP\" && test -d \"$CPP\"; then\n  CPP=\nfi\nif test -z \"$CPP\"; then\n  if test \"${ac_cv_prog_CPP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n      # Double quotes because CPP needs to be expanded\n    for CPP in \"$CC -E\" \"$CC -E -traditional-cpp\" \"/lib/cpp\"\n    do\n      ac_preproc_ok=false\nfor ac_c_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n\nelse\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether nonexistent headers\n  # can be detected and how.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  # Broken: success on invalid input.\ncontinue\nelse\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then :\n  break\nfi\n\n    done\n    ac_cv_prog_CPP=$CPP\n\nfi\n  CPP=$ac_cv_prog_CPP\nelse\n  ac_cv_prog_CPP=$CPP\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CPP\" >&5\n$as_echo \"$CPP\" >&6; }\nac_preproc_ok=false\nfor ac_c_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n\nelse\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether nonexistent headers\n  # can be detected and how.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  # Broken: success on invalid input.\ncontinue\nelse\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then :\n\nelse\n  { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error \"C preprocessor \\\"$CPP\\\" fails sanity check\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ANSI C header files\" >&5\n$as_echo_n \"checking for ANSI C header files... \" >&6; }\nif test \"${ac_cv_header_stdc+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdlib.h>\n#include <stdarg.h>\n#include <string.h>\n#include <float.h>\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_header_stdc=yes\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\nif test $ac_cv_header_stdc = yes; then\n  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <string.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"memchr\" >/dev/null 2>&1; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdlib.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"free\" >/dev/null 2>&1; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.\n  if test \"$cross_compiling\" = yes; then :\n  :\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ctype.h>\n#include <stdlib.h>\n#if ((' ' & 0x0FF) == 0x020)\n# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')\n# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))\n#else\n# define ISLOWER(c) \\\n\t\t   (('a' <= (c) && (c) <= 'i') \\\n\t\t     || ('j' <= (c) && (c) <= 'r') \\\n\t\t     || ('s' <= (c) && (c) <= 'z'))\n# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))\n#endif\n\n#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))\nint\nmain ()\n{\n  int i;\n  for (i = 0; i < 256; i++)\n    if (XOR (islower (i), ISLOWER (i))\n\t|| toupper (i) != TOUPPER (i))\n      return 2;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_run \"$LINENO\"; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \\\n  conftest.$ac_objext conftest.beam conftest.$ac_ext\nfi\n\nfi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc\" >&5\n$as_echo \"$ac_cv_header_stdc\" >&6; }\nif test $ac_cv_header_stdc = yes; then\n\n$as_echo \"#define STDC_HEADERS 1\" >>confdefs.h\n\nfi\n\n# On IRIX 5.3, sys/types and inttypes.h are conflicting.\nfor ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \\\n\t\t  inttypes.h stdint.h unistd.h\ndo :\n  as_ac_Header=`$as_echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nac_fn_c_check_header_compile \"$LINENO\" \"$ac_header\" \"$as_ac_Header\" \"$ac_includes_default\n\"\neval as_val=\\$$as_ac_Header\n   if test \"x$as_val\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define `$as_echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nfor ac_header in dlfcn.h\ndo :\n  ac_fn_c_check_header_compile \"$LINENO\" \"dlfcn.h\" \"ac_cv_header_dlfcn_h\" \"$ac_includes_default\n\"\nif test \"x$ac_cv_header_dlfcn_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_DLFCN_H 1\n_ACEOF\n\nfi\n\ndone\n\n\n\n\n\n# Set options\nenable_dlopen=yes\n\n\n\n\n  enable_win32_dll=no\n\n\n            # Check whether --enable-shared was given.\nif test \"${enable_shared+set}\" = set; then :\n  enableval=$enable_shared; p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_shared=yes ;;\n    no) enable_shared=no ;;\n    *)\n      enable_shared=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_shared=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac\nelse\n  enable_shared=yes\nfi\n\n\n\n\n\n\n\n\n\n  # Check whether --enable-static was given.\nif test \"${enable_static+set}\" = set; then :\n  enableval=$enable_static; p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_static=yes ;;\n    no) enable_static=no ;;\n    *)\n     enable_static=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_static=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac\nelse\n  enable_static=yes\nfi\n\n\n\n\n\n\n\n\n\n\n# Check whether --with-pic was given.\nif test \"${with_pic+set}\" = set; then :\n  withval=$with_pic; pic_mode=\"$withval\"\nelse\n  pic_mode=default\nfi\n\n\ntest -z \"$pic_mode\" && pic_mode=default\n\n\n\n\n\n\n\n  # Check whether --enable-fast-install was given.\nif test \"${enable_fast_install+set}\" = set; then :\n  enableval=$enable_fast_install; p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_fast_install=yes ;;\n    no) enable_fast_install=no ;;\n    *)\n      enable_fast_install=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_fast_install=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac\nelse\n  enable_fast_install=yes\nfi\n\n\n\n\n\n\n\n\n\n\n\n# This can be used to rebuild libtool when needed\nLIBTOOL_DEPS=\"$ltmain\"\n\n# Always use our own libtool.\nLIBTOOL='$(SHELL) $(top_builddir)/libtool'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ntest -z \"$LN_S\" && LN_S=\"ln -s\"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nif test -n \"${ZSH_VERSION+set}\" ; then\n   setopt NO_GLOB_SUBST\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for objdir\" >&5\n$as_echo_n \"checking for objdir... \" >&6; }\nif test \"${lt_cv_objdir+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  rm -f .libs 2>/dev/null\nmkdir .libs 2>/dev/null\nif test -d .libs; then\n  lt_cv_objdir=.libs\nelse\n  # MS-DOS does not allow filenames that begin with a dot.\n  lt_cv_objdir=_libs\nfi\nrmdir .libs 2>/dev/null\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir\" >&5\n$as_echo \"$lt_cv_objdir\" >&6; }\nobjdir=$lt_cv_objdir\n\n\n\n\n\ncat >>confdefs.h <<_ACEOF\n#define LT_OBJDIR \"$lt_cv_objdir/\"\n_ACEOF\n\n\n\n\ncase $host_os in\naix3*)\n  # AIX sometimes has problems with the GCC collect2 program.  For some\n  # reason, if we set the COLLECT_NAMES environment variable, the problems\n  # vanish in a puff of smoke.\n  if test \"X${COLLECT_NAMES+set}\" != Xset; then\n    COLLECT_NAMES=\n    export COLLECT_NAMES\n  fi\n  ;;\nesac\n\n# Global variables:\nofile=libtool\ncan_build_shared=yes\n\n# All known linkers require a `.a' archive for static linking (except MSVC,\n# which needs '.lib').\nlibext=a\n\nwith_gnu_ld=\"$lt_cv_prog_gnu_ld\"\n\nold_CC=\"$CC\"\nold_CFLAGS=\"$CFLAGS\"\n\n# Set sane defaults for various variables\ntest -z \"$CC\" && CC=cc\ntest -z \"$LTCC\" && LTCC=$CC\ntest -z \"$LTCFLAGS\" && LTCFLAGS=$CFLAGS\ntest -z \"$LD\" && LD=ld\ntest -z \"$ac_objext\" && ac_objext=o\n\nfor cc_temp in $compiler\"\"; do\n  case $cc_temp in\n    compile | *[\\\\/]compile | ccache | *[\\\\/]ccache ) ;;\n    distcc | *[\\\\/]distcc | purify | *[\\\\/]purify ) ;;\n    \\-*) ;;\n    *) break;;\n  esac\ndone\ncc_basename=`$ECHO \"$cc_temp\" | $SED \"s%.*/%%; s%^$host_alias-%%\"`\n\n\n# Only perform the check for file, if the check method requires it\ntest -z \"$MAGIC_CMD\" && MAGIC_CMD=file\ncase $deplibs_check_method in\nfile_magic*)\n  if test \"$file_magic_cmd\" = '$MAGIC_CMD'; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file\" >&5\n$as_echo_n \"checking for ${ac_tool_prefix}file... \" >&6; }\nif test \"${lt_cv_path_MAGIC_CMD+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  case $MAGIC_CMD in\n[\\\\/*] |  ?:[\\\\/]*)\n  lt_cv_path_MAGIC_CMD=\"$MAGIC_CMD\" # Let the user override the test with a path.\n  ;;\n*)\n  lt_save_MAGIC_CMD=\"$MAGIC_CMD\"\n  lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n  ac_dummy=\"/usr/bin$PATH_SEPARATOR$PATH\"\n  for ac_dir in $ac_dummy; do\n    IFS=\"$lt_save_ifs\"\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f $ac_dir/${ac_tool_prefix}file; then\n      lt_cv_path_MAGIC_CMD=\"$ac_dir/${ac_tool_prefix}file\"\n      if test -n \"$file_magic_test_file\"; then\n\tcase $deplibs_check_method in\n\t\"file_magic \"*)\n\t  file_magic_regex=`expr \"$deplibs_check_method\" : \"file_magic \\(.*\\)\"`\n\t  MAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\n\t  if eval $file_magic_cmd \\$file_magic_test_file 2> /dev/null |\n\t    $EGREP \"$file_magic_regex\" > /dev/null; then\n\t    :\n\t  else\n\t    cat <<_LT_EOF 1>&2\n\n*** Warning: the command libtool uses to detect shared libraries,\n*** $file_magic_cmd, produces output that libtool cannot recognize.\n*** The result is that libtool may fail to recognize shared libraries\n*** as such.  This will affect the creation of libtool libraries that\n*** depend on shared libraries, but programs linked with such libtool\n*** libraries will work regardless of this problem.  Nevertheless, you\n*** may want to report the problem to your system manager and/or to\n*** bug-libtool@gnu.org\n\n_LT_EOF\n\t  fi ;;\n\tesac\n      fi\n      break\n    fi\n  done\n  IFS=\"$lt_save_ifs\"\n  MAGIC_CMD=\"$lt_save_MAGIC_CMD\"\n  ;;\nesac\nfi\n\nMAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\nif test -n \"$MAGIC_CMD\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD\" >&5\n$as_echo \"$MAGIC_CMD\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n\n\n\nif test -z \"$lt_cv_path_MAGIC_CMD\"; then\n  if test -n \"$ac_tool_prefix\"; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for file\" >&5\n$as_echo_n \"checking for file... \" >&6; }\nif test \"${lt_cv_path_MAGIC_CMD+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  case $MAGIC_CMD in\n[\\\\/*] |  ?:[\\\\/]*)\n  lt_cv_path_MAGIC_CMD=\"$MAGIC_CMD\" # Let the user override the test with a path.\n  ;;\n*)\n  lt_save_MAGIC_CMD=\"$MAGIC_CMD\"\n  lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n  ac_dummy=\"/usr/bin$PATH_SEPARATOR$PATH\"\n  for ac_dir in $ac_dummy; do\n    IFS=\"$lt_save_ifs\"\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f $ac_dir/file; then\n      lt_cv_path_MAGIC_CMD=\"$ac_dir/file\"\n      if test -n \"$file_magic_test_file\"; then\n\tcase $deplibs_check_method in\n\t\"file_magic \"*)\n\t  file_magic_regex=`expr \"$deplibs_check_method\" : \"file_magic \\(.*\\)\"`\n\t  MAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\n\t  if eval $file_magic_cmd \\$file_magic_test_file 2> /dev/null |\n\t    $EGREP \"$file_magic_regex\" > /dev/null; then\n\t    :\n\t  else\n\t    cat <<_LT_EOF 1>&2\n\n*** Warning: the command libtool uses to detect shared libraries,\n*** $file_magic_cmd, produces output that libtool cannot recognize.\n*** The result is that libtool may fail to recognize shared libraries\n*** as such.  This will affect the creation of libtool libraries that\n*** depend on shared libraries, but programs linked with such libtool\n*** libraries will work regardless of this problem.  Nevertheless, you\n*** may want to report the problem to your system manager and/or to\n*** bug-libtool@gnu.org\n\n_LT_EOF\n\t  fi ;;\n\tesac\n      fi\n      break\n    fi\n  done\n  IFS=\"$lt_save_ifs\"\n  MAGIC_CMD=\"$lt_save_MAGIC_CMD\"\n  ;;\nesac\nfi\n\nMAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\nif test -n \"$MAGIC_CMD\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD\" >&5\n$as_echo \"$MAGIC_CMD\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  else\n    MAGIC_CMD=:\n  fi\nfi\n\n  fi\n  ;;\nesac\n\n# Use C for the default configuration in the libtool script\n\nlt_save_CC=\"$CC\"\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n# Source file extension for C test sources.\nac_ext=c\n\n# Object file extension for compiled C test sources.\nobjext=o\nobjext=$objext\n\n# Code to be used in simple compile tests\nlt_simple_compile_test_code=\"int some_variable = 0;\"\n\n# Code to be used in simple link tests\nlt_simple_link_test_code='int main(){return(0);}'\n\n\n\n\n\n\n\n# If no C compiler was specified, use CC.\nLTCC=${LTCC-\"$CC\"}\n\n# If no C compiler flags were specified, use CFLAGS.\nLTCFLAGS=${LTCFLAGS-\"$CFLAGS\"}\n\n# Allow CC to be a program name with arguments.\ncompiler=$CC\n\n# Save the default compiler, since it gets overwritten when the other\n# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.\ncompiler_DEFAULT=$CC\n\n# save warnings/boilerplate of simple test code\nac_outfile=conftest.$ac_objext\necho \"$lt_simple_compile_test_code\" >conftest.$ac_ext\neval \"$ac_compile\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_compiler_boilerplate=`cat conftest.err`\n$RM conftest*\n\nac_outfile=conftest.$ac_objext\necho \"$lt_simple_link_test_code\" >conftest.$ac_ext\neval \"$ac_link\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_linker_boilerplate=`cat conftest.err`\n$RM -r conftest*\n\n\n## CAVEAT EMPTOR:\n## There is no encapsulation within the following macros, do not change\n## the running order or otherwise move them around unless you know exactly\n## what you are doing...\nif test -n \"$compiler\"; then\n\nlt_prog_compiler_no_builtin_flag=\n\nif test \"$GCC\" = yes; then\n  case $cc_basename in\n  nvcc*)\n    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;\n  *)\n    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;\n  esac\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions\" >&5\n$as_echo_n \"checking if $compiler supports -fno-rtti -fno-exceptions... \" >&6; }\nif test \"${lt_cv_prog_compiler_rtti_exceptions+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_rtti_exceptions=no\n   ac_outfile=conftest.$ac_objext\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n   lt_compiler_flag=\"-fno-rtti -fno-exceptions\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   # The option is referenced via a variable to avoid confusing sed.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s \"$ac_outfile\"; then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings other than the usual output.\n     $ECHO \"$_lt_compiler_boilerplate\" | $SED '/^$/d' >conftest.exp\n     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_rtti_exceptions=yes\n     fi\n   fi\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions\" >&5\n$as_echo \"$lt_cv_prog_compiler_rtti_exceptions\" >&6; }\n\nif test x\"$lt_cv_prog_compiler_rtti_exceptions\" = xyes; then\n    lt_prog_compiler_no_builtin_flag=\"$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions\"\nelse\n    :\nfi\n\nfi\n\n\n\n\n\n\n  lt_prog_compiler_wl=\nlt_prog_compiler_pic=\nlt_prog_compiler_static=\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC\" >&5\n$as_echo_n \"checking for $compiler option to produce PIC... \" >&6; }\n\n  if test \"$GCC\" = yes; then\n    lt_prog_compiler_wl='-Wl,'\n    lt_prog_compiler_static='-static'\n\n    case $host_os in\n      aix*)\n      # All AIX code is PIC.\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\tlt_prog_compiler_static='-Bstatic'\n      fi\n      lt_prog_compiler_pic='-fPIC'\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            lt_prog_compiler_pic='-fPIC'\n        ;;\n      m68k)\n            # FIXME: we need at least 68020 code to build shared libraries, but\n            # adding the `-m68020' flag to GCC prevents building anything better,\n            # like `-m68040'.\n            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'\n        ;;\n      esac\n      ;;\n\n    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)\n      # PIC is the default for these OSes.\n      ;;\n\n    mingw* | cygwin* | pw32* | os2* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      # Although the cygwin gcc ignores -fPIC, still need this for old-style\n      # (--disable-auto-import) libraries\n      lt_prog_compiler_pic='-DDLL_EXPORT'\n      ;;\n\n    darwin* | rhapsody*)\n      # PIC is the default on this platform\n      # Common symbols not allowed in MH_DYLIB files\n      lt_prog_compiler_pic='-fno-common'\n      ;;\n\n    haiku*)\n      # PIC is the default for Haiku.\n      # The \"-static\" flag exists, but is broken.\n      lt_prog_compiler_static=\n      ;;\n\n    hpux*)\n      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit\n      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag\n      # sets the default TLS model and affects inlining.\n      case $host_cpu in\n      hppa*64*)\n\t# +Z the default\n\t;;\n      *)\n\tlt_prog_compiler_pic='-fPIC'\n\t;;\n      esac\n      ;;\n\n    interix[3-9]*)\n      # Interix 3.x gcc -fpic/-fPIC options generate broken code.\n      # Instead, we relocate shared libraries at runtime.\n      ;;\n\n    msdosdjgpp*)\n      # Just because we use GCC doesn't mean we suddenly get shared libraries\n      # on systems that don't support them.\n      lt_prog_compiler_can_build_shared=no\n      enable_shared=no\n      ;;\n\n    *nto* | *qnx*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      lt_prog_compiler_pic='-fPIC -shared'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\tlt_prog_compiler_pic=-Kconform_pic\n      fi\n      ;;\n\n    *)\n      lt_prog_compiler_pic='-fPIC'\n      ;;\n    esac\n\n    case $cc_basename in\n    nvcc*) # Cuda Compiler Driver 2.2\n      lt_prog_compiler_wl='-Xlinker '\n      lt_prog_compiler_pic='-Xcompiler -fPIC'\n      ;;\n    esac\n  else\n    # PORTME Check for flag to pass linker flags through the system compiler.\n    case $host_os in\n    aix*)\n      lt_prog_compiler_wl='-Wl,'\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\tlt_prog_compiler_static='-Bstatic'\n      else\n\tlt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'\n      fi\n      ;;\n\n    mingw* | cygwin* | pw32* | os2* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      lt_prog_compiler_pic='-DDLL_EXPORT'\n      ;;\n\n    hpux9* | hpux10* | hpux11*)\n      lt_prog_compiler_wl='-Wl,'\n      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but\n      # not for PA HP-UX.\n      case $host_cpu in\n      hppa*64*|ia64*)\n\t# +Z the default\n\t;;\n      *)\n\tlt_prog_compiler_pic='+Z'\n\t;;\n      esac\n      # Is there a better lt_prog_compiler_static that works with the bundled CC?\n      lt_prog_compiler_static='${wl}-a ${wl}archive'\n      ;;\n\n    irix5* | irix6* | nonstopux*)\n      lt_prog_compiler_wl='-Wl,'\n      # PIC (with -KPIC) is the default.\n      lt_prog_compiler_static='-non_shared'\n      ;;\n\n    linux* | k*bsd*-gnu | kopensolaris*-gnu)\n      case $cc_basename in\n      # old Intel for x86_64 which still supported -KPIC.\n      ecc*)\n\tlt_prog_compiler_wl='-Wl,'\n\tlt_prog_compiler_pic='-KPIC'\n\tlt_prog_compiler_static='-static'\n        ;;\n      # icc used to be incompatible with GCC.\n      # ICC 10 doesn't accept -KPIC any more.\n      icc* | ifort*)\n\tlt_prog_compiler_wl='-Wl,'\n\tlt_prog_compiler_pic='-fPIC'\n\tlt_prog_compiler_static='-static'\n        ;;\n      # Lahey Fortran 8.1.\n      lf95*)\n\tlt_prog_compiler_wl='-Wl,'\n\tlt_prog_compiler_pic='--shared'\n\tlt_prog_compiler_static='--static'\n\t;;\n      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)\n        # Portland Group compilers (*not* the Pentium gcc compiler,\n\t# which looks to be a dead project)\n\tlt_prog_compiler_wl='-Wl,'\n\tlt_prog_compiler_pic='-fpic'\n\tlt_prog_compiler_static='-Bstatic'\n        ;;\n      ccc*)\n        lt_prog_compiler_wl='-Wl,'\n        # All Alpha code is PIC.\n        lt_prog_compiler_static='-non_shared'\n        ;;\n      xl* | bgxl* | bgf* | mpixl*)\n\t# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene\n\tlt_prog_compiler_wl='-Wl,'\n\tlt_prog_compiler_pic='-qpic'\n\tlt_prog_compiler_static='-qstaticlink'\n\t;;\n      *)\n\tcase `$CC -V 2>&1 | sed 5q` in\n\t*Sun\\ F* | *Sun*Fortran*)\n\t  # Sun Fortran 8.3 passes all unrecognized flags to the linker\n\t  lt_prog_compiler_pic='-KPIC'\n\t  lt_prog_compiler_static='-Bstatic'\n\t  lt_prog_compiler_wl=''\n\t  ;;\n\t*Sun\\ C*)\n\t  # Sun C 5.9\n\t  lt_prog_compiler_pic='-KPIC'\n\t  lt_prog_compiler_static='-Bstatic'\n\t  lt_prog_compiler_wl='-Wl,'\n\t  ;;\n\tesac\n\t;;\n      esac\n      ;;\n\n    newsos6)\n      lt_prog_compiler_pic='-KPIC'\n      lt_prog_compiler_static='-Bstatic'\n      ;;\n\n    *nto* | *qnx*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      lt_prog_compiler_pic='-fPIC -shared'\n      ;;\n\n    osf3* | osf4* | osf5*)\n      lt_prog_compiler_wl='-Wl,'\n      # All OSF/1 code is PIC.\n      lt_prog_compiler_static='-non_shared'\n      ;;\n\n    rdos*)\n      lt_prog_compiler_static='-non_shared'\n      ;;\n\n    solaris*)\n      lt_prog_compiler_pic='-KPIC'\n      lt_prog_compiler_static='-Bstatic'\n      case $cc_basename in\n      f77* | f90* | f95*)\n\tlt_prog_compiler_wl='-Qoption ld ';;\n      *)\n\tlt_prog_compiler_wl='-Wl,';;\n      esac\n      ;;\n\n    sunos4*)\n      lt_prog_compiler_wl='-Qoption ld '\n      lt_prog_compiler_pic='-PIC'\n      lt_prog_compiler_static='-Bstatic'\n      ;;\n\n    sysv4 | sysv4.2uw2* | sysv4.3*)\n      lt_prog_compiler_wl='-Wl,'\n      lt_prog_compiler_pic='-KPIC'\n      lt_prog_compiler_static='-Bstatic'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec ;then\n\tlt_prog_compiler_pic='-Kconform_pic'\n\tlt_prog_compiler_static='-Bstatic'\n      fi\n      ;;\n\n    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)\n      lt_prog_compiler_wl='-Wl,'\n      lt_prog_compiler_pic='-KPIC'\n      lt_prog_compiler_static='-Bstatic'\n      ;;\n\n    unicos*)\n      lt_prog_compiler_wl='-Wl,'\n      lt_prog_compiler_can_build_shared=no\n      ;;\n\n    uts4*)\n      lt_prog_compiler_pic='-pic'\n      lt_prog_compiler_static='-Bstatic'\n      ;;\n\n    *)\n      lt_prog_compiler_can_build_shared=no\n      ;;\n    esac\n  fi\n\ncase $host_os in\n  # For platforms which do not support PIC, -DPIC is meaningless:\n  *djgpp*)\n    lt_prog_compiler_pic=\n    ;;\n  *)\n    lt_prog_compiler_pic=\"$lt_prog_compiler_pic -DPIC\"\n    ;;\nesac\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic\" >&5\n$as_echo \"$lt_prog_compiler_pic\" >&6; }\n\n\n\n\n\n\n#\n# Check to make sure the PIC flag actually works.\n#\nif test -n \"$lt_prog_compiler_pic\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works\" >&5\n$as_echo_n \"checking if $compiler PIC flag $lt_prog_compiler_pic works... \" >&6; }\nif test \"${lt_cv_prog_compiler_pic_works+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_pic_works=no\n   ac_outfile=conftest.$ac_objext\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n   lt_compiler_flag=\"$lt_prog_compiler_pic -DPIC\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   # The option is referenced via a variable to avoid confusing sed.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s \"$ac_outfile\"; then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings other than the usual output.\n     $ECHO \"$_lt_compiler_boilerplate\" | $SED '/^$/d' >conftest.exp\n     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_pic_works=yes\n     fi\n   fi\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works\" >&5\n$as_echo \"$lt_cv_prog_compiler_pic_works\" >&6; }\n\nif test x\"$lt_cv_prog_compiler_pic_works\" = xyes; then\n    case $lt_prog_compiler_pic in\n     \"\" | \" \"*) ;;\n     *) lt_prog_compiler_pic=\" $lt_prog_compiler_pic\" ;;\n     esac\nelse\n    lt_prog_compiler_pic=\n     lt_prog_compiler_can_build_shared=no\nfi\n\nfi\n\n\n\n\n\n\n#\n# Check to make sure the static flag actually works.\n#\nwl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\\\"$lt_prog_compiler_static\\\"\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works\" >&5\n$as_echo_n \"checking if $compiler static flag $lt_tmp_static_flag works... \" >&6; }\nif test \"${lt_cv_prog_compiler_static_works+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_static_works=no\n   save_LDFLAGS=\"$LDFLAGS\"\n   LDFLAGS=\"$LDFLAGS $lt_tmp_static_flag\"\n   echo \"$lt_simple_link_test_code\" > conftest.$ac_ext\n   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then\n     # The linker can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     if test -s conftest.err; then\n       # Append any errors to the config.log.\n       cat conftest.err 1>&5\n       $ECHO \"$_lt_linker_boilerplate\" | $SED '/^$/d' > conftest.exp\n       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n       if diff conftest.exp conftest.er2 >/dev/null; then\n         lt_cv_prog_compiler_static_works=yes\n       fi\n     else\n       lt_cv_prog_compiler_static_works=yes\n     fi\n   fi\n   $RM -r conftest*\n   LDFLAGS=\"$save_LDFLAGS\"\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works\" >&5\n$as_echo \"$lt_cv_prog_compiler_static_works\" >&6; }\n\nif test x\"$lt_cv_prog_compiler_static_works\" = xyes; then\n    :\nelse\n    lt_prog_compiler_static=\nfi\n\n\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext\" >&5\n$as_echo_n \"checking if $compiler supports -c -o file.$ac_objext... \" >&6; }\nif test \"${lt_cv_prog_compiler_c_o+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_c_o=no\n   $RM -r conftest 2>/dev/null\n   mkdir conftest\n   cd conftest\n   mkdir out\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n   lt_compiler_flag=\"-o out/conftest2.$ac_objext\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s out/conftest2.$ac_objext\n   then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     $ECHO \"$_lt_compiler_boilerplate\" | $SED '/^$/d' > out/conftest.exp\n     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2\n     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_c_o=yes\n     fi\n   fi\n   chmod u+w . 2>&5\n   $RM conftest*\n   # SGI C++ compiler will create directory out/ii_files/ for\n   # template instantiation\n   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files\n   $RM out/* && rmdir out\n   cd ..\n   $RM -r conftest\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o\" >&5\n$as_echo \"$lt_cv_prog_compiler_c_o\" >&6; }\n\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext\" >&5\n$as_echo_n \"checking if $compiler supports -c -o file.$ac_objext... \" >&6; }\nif test \"${lt_cv_prog_compiler_c_o+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_c_o=no\n   $RM -r conftest 2>/dev/null\n   mkdir conftest\n   cd conftest\n   mkdir out\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n   lt_compiler_flag=\"-o out/conftest2.$ac_objext\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s out/conftest2.$ac_objext\n   then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     $ECHO \"$_lt_compiler_boilerplate\" | $SED '/^$/d' > out/conftest.exp\n     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2\n     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_c_o=yes\n     fi\n   fi\n   chmod u+w . 2>&5\n   $RM conftest*\n   # SGI C++ compiler will create directory out/ii_files/ for\n   # template instantiation\n   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files\n   $RM out/* && rmdir out\n   cd ..\n   $RM -r conftest\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o\" >&5\n$as_echo \"$lt_cv_prog_compiler_c_o\" >&6; }\n\n\n\n\nhard_links=\"nottested\"\nif test \"$lt_cv_prog_compiler_c_o\" = no && test \"$need_locks\" != no; then\n  # do not overwrite the value of need_locks provided by the user\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links\" >&5\n$as_echo_n \"checking if we can lock with hard links... \" >&6; }\n  hard_links=yes\n  $RM conftest*\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  touch conftest.a\n  ln conftest.a conftest.b 2>&5 || hard_links=no\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $hard_links\" >&5\n$as_echo \"$hard_links\" >&6; }\n  if test \"$hard_links\" = no; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: \\`$CC' does not support \\`-c -o', so \\`make -j' may be unsafe\" >&5\n$as_echo \"$as_me: WARNING: \\`$CC' does not support \\`-c -o', so \\`make -j' may be unsafe\" >&2;}\n    need_locks=warn\n  fi\nelse\n  need_locks=no\nfi\n\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries\" >&5\n$as_echo_n \"checking whether the $compiler linker ($LD) supports shared libraries... \" >&6; }\n\n  runpath_var=\n  allow_undefined_flag=\n  always_export_symbols=no\n  archive_cmds=\n  archive_expsym_cmds=\n  compiler_needs_object=no\n  enable_shared_with_static_runtimes=no\n  export_dynamic_flag_spec=\n  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\\''s/.* //'\\'' | sort | uniq > $export_symbols'\n  hardcode_automatic=no\n  hardcode_direct=no\n  hardcode_direct_absolute=no\n  hardcode_libdir_flag_spec=\n  hardcode_libdir_flag_spec_ld=\n  hardcode_libdir_separator=\n  hardcode_minus_L=no\n  hardcode_shlibpath_var=unsupported\n  inherit_rpath=no\n  link_all_deplibs=unknown\n  module_cmds=\n  module_expsym_cmds=\n  old_archive_from_new_cmds=\n  old_archive_from_expsyms_cmds=\n  thread_safe_flag_spec=\n  whole_archive_flag_spec=\n  # include_expsyms should be a list of space-separated symbols to be *always*\n  # included in the symbol list\n  include_expsyms=\n  # exclude_expsyms can be an extended regexp of symbols to exclude\n  # it will be wrapped by ` (' and `)$', so one must not match beginning or\n  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',\n  # as well as any symbol that contains `d'.\n  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'\n  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out\n  # platforms (ab)use it in PIC code, but their linkers get confused if\n  # the symbol is explicitly referenced.  Since portable code cannot\n  # rely on this symbol name, it's probably fine to never include it in\n  # preloaded symbol tables.\n  # Exclude shared library initialization/finalization symbols.\n  extract_expsyms_cmds=\n\n  case $host_os in\n  cygwin* | mingw* | pw32* | cegcc*)\n    # FIXME: the MSVC++ port hasn't been tested in a loooong time\n    # When not using gcc, we currently assume that we are using\n    # Microsoft Visual C++.\n    if test \"$GCC\" != yes; then\n      with_gnu_ld=no\n    fi\n    ;;\n  interix*)\n    # we just hope/assume this is gcc and not c89 (= MSVC++)\n    with_gnu_ld=yes\n    ;;\n  openbsd*)\n    with_gnu_ld=no\n    ;;\n  esac\n\n  ld_shlibs=yes\n\n  # On some targets, GNU ld is compatible enough with the native linker\n  # that we're better off using the native interface for both.\n  lt_use_gnu_ld_interface=no\n  if test \"$with_gnu_ld\" = yes; then\n    case $host_os in\n      aix*)\n\t# The AIX port of GNU ld has always aspired to compatibility\n\t# with the native linker.  However, as the warning in the GNU ld\n\t# block says, versions before 2.19.5* couldn't really create working\n\t# shared libraries, regardless of the interface used.\n\tcase `$LD -v 2>&1` in\n\t  *\\ \\(GNU\\ Binutils\\)\\ 2.19.5*) ;;\n\t  *\\ \\(GNU\\ Binutils\\)\\ 2.[2-9]*) ;;\n\t  *\\ \\(GNU\\ Binutils\\)\\ [3-9]*) ;;\n\t  *)\n\t    lt_use_gnu_ld_interface=yes\n\t    ;;\n\tesac\n\t;;\n      *)\n\tlt_use_gnu_ld_interface=yes\n\t;;\n    esac\n  fi\n\n  if test \"$lt_use_gnu_ld_interface\" = yes; then\n    # If archive_cmds runs LD, not CC, wlarc should be empty\n    wlarc='${wl}'\n\n    # Set some defaults for GNU ld with shared library support. These\n    # are reset later if shared libraries are not supported. Putting them\n    # here allows them to be overridden if necessary.\n    runpath_var=LD_RUN_PATH\n    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n    export_dynamic_flag_spec='${wl}--export-dynamic'\n    # ancient GNU ld didn't support --whole-archive et. al.\n    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then\n      whole_archive_flag_spec=\"$wlarc\"'--whole-archive$convenience '\"$wlarc\"'--no-whole-archive'\n    else\n      whole_archive_flag_spec=\n    fi\n    supports_anon_versioning=no\n    case `$LD -v 2>&1` in\n      *GNU\\ gold*) supports_anon_versioning=yes ;;\n      *\\ [01].* | *\\ 2.[0-9].* | *\\ 2.10.*) ;; # catch versions < 2.11\n      *\\ 2.11.93.0.2\\ *) supports_anon_versioning=yes ;; # RH7.3 ...\n      *\\ 2.11.92.0.12\\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...\n      *\\ 2.11.*) ;; # other 2.11 versions\n      *) supports_anon_versioning=yes ;;\n    esac\n\n    # See if GNU ld supports shared libraries.\n    case $host_os in\n    aix[3-9]*)\n      # On AIX/PPC, the GNU linker is very broken\n      if test \"$host_cpu\" != ia64; then\n\tld_shlibs=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: the GNU linker, at least up to release 2.19, is reported\n*** to be unable to reliably create shared libraries on AIX.\n*** Therefore, libtool is disabling shared libraries support.  If you\n*** really care for shared libraries, you may want to install binutils\n*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.\n*** You will then need to restart the configuration process.\n\n_LT_EOF\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n            archive_expsym_cmds=''\n        ;;\n      m68k)\n            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO \"#define NAME $libname\" > $output_objdir/a2ixlibrary.data~$ECHO \"#define LIBRARY_ID 1\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define VERSION $major\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define REVISION $revision\" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'\n            hardcode_libdir_flag_spec='-L$libdir'\n            hardcode_minus_L=yes\n        ;;\n      esac\n      ;;\n\n    beos*)\n      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\tallow_undefined_flag=unsupported\n\t# Joseph Beckenbach <jrb3@best.com> says some releases of gcc\n\t# support --undefined.  This deserves some investigation.  FIXME\n\tarchive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n      else\n\tld_shlibs=no\n      fi\n      ;;\n\n    cygwin* | mingw* | pw32* | cegcc*)\n      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,\n      # as there is no search path for DLLs.\n      hardcode_libdir_flag_spec='-L$libdir'\n      export_dynamic_flag_spec='${wl}--export-all-symbols'\n      allow_undefined_flag=unsupported\n      always_export_symbols=no\n      enable_shared_with_static_runtimes=yes\n      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[BCDGRS][ ]/s/.*[ ]\\([^ ]*\\)/\\1 DATA/'\\'' | $SED -e '\\''/^[AITW][ ]/s/.*[ ]//'\\'' | sort | uniq > $export_symbols'\n\n      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then\n        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n\t# If the export-symbols file already is a .def file (1st line\n\t# is EXPORTS), use it as is; otherwise, prepend...\n\tarchive_expsym_cmds='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t  cp $export_symbols $output_objdir/$soname.def;\n\telse\n\t  echo EXPORTS > $output_objdir/$soname.def;\n\t  cat $export_symbols >> $output_objdir/$soname.def;\n\tfi~\n\t$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n      else\n\tld_shlibs=no\n      fi\n      ;;\n\n    haiku*)\n      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n      link_all_deplibs=yes\n      ;;\n\n    interix[3-9]*)\n      hardcode_direct=no\n      hardcode_shlibpath_var=no\n      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'\n      export_dynamic_flag_spec='${wl}-E'\n      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.\n      # Instead, shared libraries are loaded at an image base (0x10000000 by\n      # default) and relocated if they conflict, which is a slow very memory\n      # consuming and fragmenting process.  To avoid this, we pick a random,\n      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link\n      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.\n      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n      archive_expsym_cmds='sed \"s,^,_,\" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n      ;;\n\n    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)\n      tmp_diet=no\n      if test \"$host_os\" = linux-dietlibc; then\n\tcase $cc_basename in\n\t  diet\\ *) tmp_diet=yes;;\t# linux-dietlibc with static linking (!diet-dyn)\n\tesac\n      fi\n      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \\\n\t && test \"$tmp_diet\" = no\n      then\n\ttmp_addflag=' $pic_flag'\n\ttmp_sharedflag='-shared'\n\tcase $cc_basename,$host_cpu in\n        pgcc*)\t\t\t\t# Portland Group C compiler\n\t  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag'\n\t  ;;\n\tpgf77* | pgf90* | pgf95* | pgfortran*)\n\t\t\t\t\t# Portland Group f77 and f90 compilers\n\t  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag -Mnomain' ;;\n\tecc*,ia64* | icc*,ia64*)\t# Intel C compiler on ia64\n\t  tmp_addflag=' -i_dynamic' ;;\n\tefc*,ia64* | ifort*,ia64*)\t# Intel Fortran compiler on ia64\n\t  tmp_addflag=' -i_dynamic -nofor_main' ;;\n\tifc* | ifort*)\t\t\t# Intel Fortran compiler\n\t  tmp_addflag=' -nofor_main' ;;\n\tlf95*)\t\t\t\t# Lahey Fortran 8.1\n\t  whole_archive_flag_spec=\n\t  tmp_sharedflag='--shared' ;;\n\txl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)\n\t  tmp_sharedflag='-qmkshrobj'\n\t  tmp_addflag= ;;\n\tnvcc*)\t# Cuda Compiler Driver 2.2\n\t  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  compiler_needs_object=yes\n\t  ;;\n\tesac\n\tcase `$CC -V 2>&1 | sed 5q` in\n\t*Sun\\ C*)\t\t\t# Sun C 5.9\n\t  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\\\"\\\"; do test -z \\\"$conv\\\" || new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  compiler_needs_object=yes\n\t  tmp_sharedflag='-G' ;;\n\t*Sun\\ F*)\t\t\t# Sun Fortran 8.3\n\t  tmp_sharedflag='-G' ;;\n\tesac\n\tarchive_cmds='$CC '\"$tmp_sharedflag\"\"$tmp_addflag\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\n        if test \"x$supports_anon_versioning\" = xyes; then\n          archive_expsym_cmds='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t    cat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t    echo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t    $CC '\"$tmp_sharedflag\"\"$tmp_addflag\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'\n        fi\n\n\tcase $cc_basename in\n\txlf* | bgf* | bgxlf* | mpixlf*)\n\t  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself\n\t  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'\n\t  hardcode_libdir_flag_spec=\n\t  hardcode_libdir_flag_spec_ld='-rpath $libdir'\n\t  archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'\n\t  if test \"x$supports_anon_versioning\" = xyes; then\n\t    archive_expsym_cmds='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t      cat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t      echo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'\n\t  fi\n\t  ;;\n\tesac\n      else\n        ld_shlibs=no\n      fi\n      ;;\n\n    netbsd*)\n      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\tarchive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'\n\twlarc=\n      else\n\tarchive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      fi\n      ;;\n\n    solaris*)\n      if $LD -v 2>&1 | $GREP 'BFD 2\\.8' > /dev/null; then\n\tld_shlibs=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: The releases 2.8.* of the GNU linker cannot reliably\n*** create shared libraries on Solaris systems.  Therefore, libtool\n*** is disabling shared libraries support.  We urge you to upgrade GNU\n*** binutils to release 2.9.1 or newer.  Another option is to modify\n*** your PATH or compiler configuration so that the native linker is\n*** used, and then restart.\n\n_LT_EOF\n      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\tarchive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      else\n\tld_shlibs=no\n      fi\n      ;;\n\n    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)\n      case `$LD -v 2>&1` in\n        *\\ [01].* | *\\ 2.[0-9].* | *\\ 2.1[0-5].*)\n\tld_shlibs=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not\n*** reliably create shared libraries on SCO systems.  Therefore, libtool\n*** is disabling shared libraries support.  We urge you to upgrade GNU\n*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify\n*** your PATH or compiler configuration so that the native linker is\n*** used, and then restart.\n\n_LT_EOF\n\t;;\n\t*)\n\t  # For security reasons, it is highly recommended that you always\n\t  # use absolute paths for naming shared libraries, and exclude the\n\t  # DT_RUNPATH tag from executables and libraries.  But doing so\n\t  # requires that you compile everything twice, which is a pain.\n\t  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n\t    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\t  else\n\t    ld_shlibs=no\n\t  fi\n\t;;\n      esac\n      ;;\n\n    sunos4*)\n      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n      wlarc=\n      hardcode_direct=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    *)\n      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\tarchive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      else\n\tld_shlibs=no\n      fi\n      ;;\n    esac\n\n    if test \"$ld_shlibs\" = no; then\n      runpath_var=\n      hardcode_libdir_flag_spec=\n      export_dynamic_flag_spec=\n      whole_archive_flag_spec=\n    fi\n  else\n    # PORTME fill in a description of your system's linker (not GNU ld)\n    case $host_os in\n    aix3*)\n      allow_undefined_flag=unsupported\n      always_export_symbols=yes\n      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'\n      # Note: this linker hardcodes the directories in LIBPATH if there\n      # are no directories specified by -L.\n      hardcode_minus_L=yes\n      if test \"$GCC\" = yes && test -z \"$lt_prog_compiler_static\"; then\n\t# Neither direct hardcoding nor static linking is supported with a\n\t# broken collect2.\n\thardcode_direct=unsupported\n      fi\n      ;;\n\n    aix[4-9]*)\n      if test \"$host_cpu\" = ia64; then\n\t# On IA64, the linker does run time linking by default, so we don't\n\t# have to do anything special.\n\taix_use_runtimelinking=no\n\texp_sym_flag='-Bexport'\n\tno_entry_flag=\"\"\n      else\n\t# If we're using GNU nm, then we don't want the \"-C\" option.\n\t# -C means demangle to AIX nm, but means don't demangle with GNU nm\n\t# Also, AIX nm treats weak defined symbols like other global\n\t# defined symbols, whereas GNU nm marks them as \"W\".\n\tif $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then\n\t  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\") || (\\$ 2 == \"W\")) && (substr(\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n\telse\n\t  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\") || (\\$ 2 == \"L\")) && (substr(\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n\tfi\n\taix_use_runtimelinking=no\n\n\t# Test if we are trying to use run time linking or normal\n\t# AIX style linking. If -brtl is somewhere in LDFLAGS, we\n\t# need to do runtime linking.\n\tcase $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)\n\t  for ld_flag in $LDFLAGS; do\n\t  if (test $ld_flag = \"-brtl\" || test $ld_flag = \"-Wl,-brtl\"); then\n\t    aix_use_runtimelinking=yes\n\t    break\n\t  fi\n\t  done\n\t  ;;\n\tesac\n\n\texp_sym_flag='-bexport'\n\tno_entry_flag='-bnoentry'\n      fi\n\n      # When large executables or shared objects are built, AIX ld can\n      # have problems creating the table of contents.  If linking a library\n      # or program results in \"error TOC overflow\" add -mminimal-toc to\n      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not\n      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.\n\n      archive_cmds=''\n      hardcode_direct=yes\n      hardcode_direct_absolute=yes\n      hardcode_libdir_separator=':'\n      link_all_deplibs=yes\n      file_list_spec='${wl}-f,'\n\n      if test \"$GCC\" = yes; then\n\tcase $host_os in aix4.[012]|aix4.[012].*)\n\t# We only want to do this on AIX 4.2 and lower, the check\n\t# below for broken collect2 doesn't work under 4.3+\n\t  collect2name=`${CC} -print-prog-name=collect2`\n\t  if test -f \"$collect2name\" &&\n\t   strings \"$collect2name\" | $GREP resolve_lib_name >/dev/null\n\t  then\n\t  # We have reworked collect2\n\t  :\n\t  else\n\t  # We have old collect2\n\t  hardcode_direct=unsupported\n\t  # It fails to find uninstalled libraries when the uninstalled\n\t  # path is not listed in the libpath.  Setting hardcode_minus_L\n\t  # to unsupported forces relinking\n\t  hardcode_minus_L=yes\n\t  hardcode_libdir_flag_spec='-L$libdir'\n\t  hardcode_libdir_separator=\n\t  fi\n\t  ;;\n\tesac\n\tshared_flag='-shared'\n\tif test \"$aix_use_runtimelinking\" = yes; then\n\t  shared_flag=\"$shared_flag \"'${wl}-G'\n\tfi\n      else\n\t# not using gcc\n\tif test \"$host_cpu\" = ia64; then\n\t# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release\n\t# chokes on -Wl,-G. The following line is correct:\n\t  shared_flag='-G'\n\telse\n\t  if test \"$aix_use_runtimelinking\" = yes; then\n\t    shared_flag='${wl}-G'\n\t  else\n\t    shared_flag='${wl}-bM:SRE'\n\t  fi\n\tfi\n      fi\n\n      export_dynamic_flag_spec='${wl}-bexpall'\n      # It seems that -bexpall does not export symbols beginning with\n      # underscore (_), so it is better to generate a list of symbols to export.\n      always_export_symbols=yes\n      if test \"$aix_use_runtimelinking\" = yes; then\n\t# Warning - without using the other runtime loading flags (-brtl),\n\t# -berok will link without error, but may produce a broken library.\n\tallow_undefined_flag='-berok'\n        # Determine the default libpath from the value encoded in an\n        # empty executable.\n        cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n\nlt_aix_libpath_sed='\n    /Import File Strings/,/^$/ {\n\t/^0/ {\n\t    s/^0  *\\(.*\\)$/\\1/\n\t    p\n\t}\n    }'\naix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n# Check for a 64-bit object if we didn't find anything.\nif test -z \"$aix_libpath\"; then\n  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\nfi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nif test -z \"$aix_libpath\"; then aix_libpath=\"/usr/lib:/lib\"; fi\n\n        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags `if test \"x${allow_undefined_flag}\" != \"x\"; then func_echo_all \"${wl}${allow_undefined_flag}\"; else :; fi` '\"\\${wl}$exp_sym_flag:\\$export_symbols $shared_flag\"\n      else\n\tif test \"$host_cpu\" = ia64; then\n\t  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'\n\t  allow_undefined_flag=\"-z nodefs\"\n\t  archive_expsym_cmds=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags ${wl}${allow_undefined_flag} '\"\\${wl}$exp_sym_flag:\\$export_symbols\"\n\telse\n\t # Determine the default libpath from the value encoded in an\n\t # empty executable.\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n\nlt_aix_libpath_sed='\n    /Import File Strings/,/^$/ {\n\t/^0/ {\n\t    s/^0  *\\(.*\\)$/\\1/\n\t    p\n\t}\n    }'\naix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n# Check for a 64-bit object if we didn't find anything.\nif test -z \"$aix_libpath\"; then\n  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\nfi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nif test -z \"$aix_libpath\"; then aix_libpath=\"/usr/lib:/lib\"; fi\n\n\t hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n\t  # Warning - without using the other run time loading flags,\n\t  # -berok will link without error, but may produce a broken library.\n\t  no_undefined_flag=' ${wl}-bernotok'\n\t  allow_undefined_flag=' ${wl}-berok'\n\t  if test \"$with_gnu_ld\" = yes; then\n\t    # We only use this code for GNU lds that support --whole-archive.\n\t    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'\n\t  else\n\t    # Exported symbols can be pulled into shared objects from archives\n\t    whole_archive_flag_spec='$convenience'\n\t  fi\n\t  archive_cmds_need_lc=yes\n\t  # This is similar to how AIX traditionally builds its shared libraries.\n\t  archive_expsym_cmds=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'\n\tfi\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n            archive_expsym_cmds=''\n        ;;\n      m68k)\n            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO \"#define NAME $libname\" > $output_objdir/a2ixlibrary.data~$ECHO \"#define LIBRARY_ID 1\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define VERSION $major\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define REVISION $revision\" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'\n            hardcode_libdir_flag_spec='-L$libdir'\n            hardcode_minus_L=yes\n        ;;\n      esac\n      ;;\n\n    bsdi[45]*)\n      export_dynamic_flag_spec=-rdynamic\n      ;;\n\n    cygwin* | mingw* | pw32* | cegcc*)\n      # When not using gcc, we currently assume that we are using\n      # Microsoft Visual C++.\n      # hardcode_libdir_flag_spec is actually meaningless, as there is\n      # no search path for DLLs.\n      hardcode_libdir_flag_spec=' '\n      allow_undefined_flag=unsupported\n      # Tell ltmain to make .lib files, not .a files.\n      libext=lib\n      # Tell ltmain to make .dll files, not .so files.\n      shrext_cmds=\".dll\"\n      # FIXME: Setting linknames here is a bad hack.\n      archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all \"$deplibs\" | $SED '\\''s/ -lc$//'\\''` -link -dll~linknames='\n      # The linker will automatically build a .lib file if we build a DLL.\n      old_archive_from_new_cmds='true'\n      # FIXME: Should let the user specify the lib program.\n      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'\n      fix_srcfile_path='`cygpath -w \"$srcfile\"`'\n      enable_shared_with_static_runtimes=yes\n      ;;\n\n    darwin* | rhapsody*)\n\n\n  archive_cmds_need_lc=no\n  hardcode_direct=no\n  hardcode_automatic=yes\n  hardcode_shlibpath_var=unsupported\n  if test \"$lt_cv_ld_force_load\" = \"yes\"; then\n    whole_archive_flag_spec='`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience ${wl}-force_load,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"`'\n  else\n    whole_archive_flag_spec=''\n  fi\n  link_all_deplibs=yes\n  allow_undefined_flag=\"$_lt_dar_allow_undefined\"\n  case $cc_basename in\n     ifort*) _lt_dar_can_shared=yes ;;\n     *) _lt_dar_can_shared=$GCC ;;\n  esac\n  if test \"$_lt_dar_can_shared\" = \"yes\"; then\n    output_verbose_link_cmd=func_echo_all\n    archive_cmds=\"\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring $_lt_dar_single_mod${_lt_dsymutil}\"\n    module_cmds=\"\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dsymutil}\"\n    archive_expsym_cmds=\"sed 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}\"\n    module_expsym_cmds=\"sed -e 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}\"\n\n  else\n  ld_shlibs=no\n  fi\n\n      ;;\n\n    dgux*)\n      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_shlibpath_var=no\n      ;;\n\n    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor\n    # support.  Future versions do this automatically, but an explicit c++rt0.o\n    # does not break anything, and helps significantly (at the cost of a little\n    # extra space).\n    freebsd2.2*)\n      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'\n      hardcode_libdir_flag_spec='-R$libdir'\n      hardcode_direct=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    # Unfortunately, older versions of FreeBSD 2 do not have this feature.\n    freebsd2.*)\n      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_direct=yes\n      hardcode_minus_L=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.\n    freebsd* | dragonfly*)\n      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'\n      hardcode_libdir_flag_spec='-R$libdir'\n      hardcode_direct=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    hpux9*)\n      if test \"$GCC\" = yes; then\n\tarchive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n      else\n\tarchive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n      fi\n      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'\n      hardcode_libdir_separator=:\n      hardcode_direct=yes\n\n      # hardcode_minus_L: Not really in the search PATH,\n      # but as the default location of the library.\n      hardcode_minus_L=yes\n      export_dynamic_flag_spec='${wl}-E'\n      ;;\n\n    hpux10*)\n      if test \"$GCC\" = yes && test \"$with_gnu_ld\" = no; then\n\tarchive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'\n      fi\n      if test \"$with_gnu_ld\" = no; then\n\thardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'\n\thardcode_libdir_flag_spec_ld='+b $libdir'\n\thardcode_libdir_separator=:\n\thardcode_direct=yes\n\thardcode_direct_absolute=yes\n\texport_dynamic_flag_spec='${wl}-E'\n\t# hardcode_minus_L: Not really in the search PATH,\n\t# but as the default location of the library.\n\thardcode_minus_L=yes\n      fi\n      ;;\n\n    hpux11*)\n      if test \"$GCC\" = yes && test \"$with_gnu_ld\" = no; then\n\tcase $host_cpu in\n\thppa*64*)\n\t  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tia64*)\n\t  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\t  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tesac\n      else\n\tcase $host_cpu in\n\thppa*64*)\n\t  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tia64*)\n\t  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\n\t  # Older versions of the 11.00 compiler do not understand -b yet\n\t  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)\n\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $CC understands -b\" >&5\n$as_echo_n \"checking if $CC understands -b... \" >&6; }\nif test \"${lt_cv_prog_compiler__b+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler__b=no\n   save_LDFLAGS=\"$LDFLAGS\"\n   LDFLAGS=\"$LDFLAGS -b\"\n   echo \"$lt_simple_link_test_code\" > conftest.$ac_ext\n   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then\n     # The linker can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     if test -s conftest.err; then\n       # Append any errors to the config.log.\n       cat conftest.err 1>&5\n       $ECHO \"$_lt_linker_boilerplate\" | $SED '/^$/d' > conftest.exp\n       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n       if diff conftest.exp conftest.er2 >/dev/null; then\n         lt_cv_prog_compiler__b=yes\n       fi\n     else\n       lt_cv_prog_compiler__b=yes\n     fi\n   fi\n   $RM -r conftest*\n   LDFLAGS=\"$save_LDFLAGS\"\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b\" >&5\n$as_echo \"$lt_cv_prog_compiler__b\" >&6; }\n\nif test x\"$lt_cv_prog_compiler__b\" = xyes; then\n    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\nelse\n    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'\nfi\n\n\t  ;;\n\tesac\n      fi\n      if test \"$with_gnu_ld\" = no; then\n\thardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'\n\thardcode_libdir_separator=:\n\n\tcase $host_cpu in\n\thppa*64*|ia64*)\n\t  hardcode_direct=no\n\t  hardcode_shlibpath_var=no\n\t  ;;\n\t*)\n\t  hardcode_direct=yes\n\t  hardcode_direct_absolute=yes\n\t  export_dynamic_flag_spec='${wl}-E'\n\n\t  # hardcode_minus_L: Not really in the search PATH,\n\t  # but as the default location of the library.\n\t  hardcode_minus_L=yes\n\t  ;;\n\tesac\n      fi\n      ;;\n\n    irix5* | irix6* | nonstopux*)\n      if test \"$GCC\" = yes; then\n\tarchive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t# Try to use the -exported_symbol ld option, if it does not\n\t# work, assume that -exports_file does not work either and\n\t# implicitly export all symbols.\n        save_LDFLAGS=\"$LDFLAGS\"\n        LDFLAGS=\"$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null\"\n        cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\nint foo(void) {}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'\n\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n        LDFLAGS=\"$save_LDFLAGS\"\n      else\n\tarchive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n\tarchive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'\n      fi\n      archive_cmds_need_lc='no'\n      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator=:\n      inherit_rpath=yes\n      link_all_deplibs=yes\n      ;;\n\n    netbsd*)\n      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\tarchive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out\n      else\n\tarchive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF\n      fi\n      hardcode_libdir_flag_spec='-R$libdir'\n      hardcode_direct=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    newsos6)\n      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_direct=yes\n      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator=:\n      hardcode_shlibpath_var=no\n      ;;\n\n    *nto* | *qnx*)\n      ;;\n\n    openbsd*)\n      if test -f /usr/libexec/ld.so; then\n\thardcode_direct=yes\n\thardcode_shlibpath_var=no\n\thardcode_direct_absolute=yes\n\tif test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n\t  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'\n\t  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'\n\t  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'\n\t  export_dynamic_flag_spec='${wl}-E'\n\telse\n\t  case $host_os in\n\t   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)\n\t     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n\t     hardcode_libdir_flag_spec='-R$libdir'\n\t     ;;\n\t   *)\n\t     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'\n\t     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'\n\t     ;;\n\t  esac\n\tfi\n      else\n\tld_shlibs=no\n      fi\n      ;;\n\n    os2*)\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_minus_L=yes\n      allow_undefined_flag=unsupported\n      archive_cmds='$ECHO \"LIBRARY $libname INITINSTANCE\" > $output_objdir/$libname.def~$ECHO \"DESCRIPTION \\\"$libname\\\"\" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo \" SINGLE NONSHARED\" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'\n      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'\n      ;;\n\n    osf3*)\n      if test \"$GCC\" = yes; then\n\tallow_undefined_flag=' ${wl}-expect_unresolved ${wl}\\*'\n\tarchive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n      else\n\tallow_undefined_flag=' -expect_unresolved \\*'\n\tarchive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n      fi\n      archive_cmds_need_lc='no'\n      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator=:\n      ;;\n\n    osf4* | osf5*)\t# as osf3* with the addition of -msym flag\n      if test \"$GCC\" = yes; then\n\tallow_undefined_flag=' ${wl}-expect_unresolved ${wl}\\*'\n\tarchive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\thardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      else\n\tallow_undefined_flag=' -expect_unresolved \\*'\n\tarchive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n\tarchive_expsym_cmds='for i in `cat $export_symbols`; do printf \"%s %s\\\\n\" -exported_symbol \"\\$i\" >> $lib.exp; done; printf \"%s\\\\n\" \"-hidden\">> $lib.exp~\n\t$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n \"$verstring\" && $ECHO \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'\n\n\t# Both c and cxx compiler support -rpath directly\n\thardcode_libdir_flag_spec='-rpath $libdir'\n      fi\n      archive_cmds_need_lc='no'\n      hardcode_libdir_separator=:\n      ;;\n\n    solaris*)\n      no_undefined_flag=' -z defs'\n      if test \"$GCC\" = yes; then\n\twlarc='${wl}'\n\tarchive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'\n      else\n\tcase `$CC -V 2>&1` in\n\t*\"Compilers 5.0\"*)\n\t  wlarc=''\n\t  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  archive_expsym_cmds='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'\n\t  ;;\n\t*)\n\t  wlarc='${wl}'\n\t  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  archive_expsym_cmds='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'\n\t  ;;\n\tesac\n      fi\n      hardcode_libdir_flag_spec='-R$libdir'\n      hardcode_shlibpath_var=no\n      case $host_os in\n      solaris2.[0-5] | solaris2.[0-5].*) ;;\n      *)\n\t# The compiler driver will combine and reorder linker options,\n\t# but understands `-z linker_flag'.  GCC discards it without `$wl',\n\t# but is careful enough not to reorder.\n\t# Supported since Solaris 2.6 (maybe 2.5.1?)\n\tif test \"$GCC\" = yes; then\n\t  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'\n\telse\n\t  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'\n\tfi\n\t;;\n      esac\n      link_all_deplibs=yes\n      ;;\n\n    sunos4*)\n      if test \"x$host_vendor\" = xsequent; then\n\t# Use $CC to link under sequent, because it throws in some extra .o\n\t# files that make .init and .fini sections work.\n\tarchive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'\n      fi\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_direct=yes\n      hardcode_minus_L=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    sysv4)\n      case $host_vendor in\n\tsni)\n\t  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  hardcode_direct=yes # is this really true???\n\t;;\n\tsiemens)\n\t  ## LD is ld it makes a PLAMLIB\n\t  ## CC just makes a GrossModule.\n\t  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'\n\t  reload_cmds='$CC -r -o $output$reload_objs'\n\t  hardcode_direct=no\n        ;;\n\tmotorola)\n\t  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  hardcode_direct=no #Motorola manual says yes, but my tests say they lie\n\t;;\n      esac\n      runpath_var='LD_RUN_PATH'\n      hardcode_shlibpath_var=no\n      ;;\n\n    sysv4.3*)\n      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_shlibpath_var=no\n      export_dynamic_flag_spec='-Bexport'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\tarchive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\thardcode_shlibpath_var=no\n\trunpath_var=LD_RUN_PATH\n\thardcode_runpath_var=yes\n\tld_shlibs=yes\n      fi\n      ;;\n\n    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)\n      no_undefined_flag='${wl}-z,text'\n      archive_cmds_need_lc=no\n      hardcode_shlibpath_var=no\n      runpath_var='LD_RUN_PATH'\n\n      if test \"$GCC\" = yes; then\n\tarchive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      fi\n      ;;\n\n    sysv5* | sco3.2v5* | sco5v6*)\n      # Note: We can NOT use -z defs as we might desire, because we do not\n      # link with -lc, and that would cause any symbols used from libc to\n      # always be unresolved, which means just about no library would\n      # ever link correctly.  If we're not using GNU ld we use -z text\n      # though, which does catch some bad symbols but isn't as heavy-handed\n      # as -z defs.\n      no_undefined_flag='${wl}-z,text'\n      allow_undefined_flag='${wl}-z,nodefs'\n      archive_cmds_need_lc=no\n      hardcode_shlibpath_var=no\n      hardcode_libdir_flag_spec='${wl}-R,$libdir'\n      hardcode_libdir_separator=':'\n      link_all_deplibs=yes\n      export_dynamic_flag_spec='${wl}-Bexport'\n      runpath_var='LD_RUN_PATH'\n\n      if test \"$GCC\" = yes; then\n\tarchive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      fi\n      ;;\n\n    uts4*)\n      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_shlibpath_var=no\n      ;;\n\n    *)\n      ld_shlibs=no\n      ;;\n    esac\n\n    if test x$host_vendor = xsni; then\n      case $host in\n      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)\n\texport_dynamic_flag_spec='${wl}-Blargedynsym'\n\t;;\n      esac\n    fi\n  fi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ld_shlibs\" >&5\n$as_echo \"$ld_shlibs\" >&6; }\ntest \"$ld_shlibs\" = no && can_build_shared=no\n\nwith_gnu_ld=$with_gnu_ld\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n#\n# Do we need to explicitly link libc?\n#\ncase \"x$archive_cmds_need_lc\" in\nx|xyes)\n  # Assume -lc should be added\n  archive_cmds_need_lc=yes\n\n  if test \"$enable_shared\" = yes && test \"$GCC\" = yes; then\n    case $archive_cmds in\n    *'~'*)\n      # FIXME: we may have to deal with multi-command sequences.\n      ;;\n    '$CC '*)\n      # Test whether the compiler implicitly links with -lc since on some\n      # systems, -lgcc has to come before -lc. If gcc already passes -lc\n      # to ld, don't add -lc before -lgcc.\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in\" >&5\n$as_echo_n \"checking whether -lc should be explicitly linked in... \" >&6; }\nif test \"${lt_cv_archive_cmds_need_lc+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  $RM conftest*\n\techo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n\tif { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } 2>conftest.err; then\n\t  soname=conftest\n\t  lib=conftest\n\t  libobjs=conftest.$ac_objext\n\t  deplibs=\n\t  wl=$lt_prog_compiler_wl\n\t  pic_flag=$lt_prog_compiler_pic\n\t  compiler_flags=-v\n\t  linker_flags=-v\n\t  verstring=\n\t  output_objdir=.\n\t  libname=conftest\n\t  lt_save_allow_undefined_flag=$allow_undefined_flag\n\t  allow_undefined_flag=\n\t  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$archive_cmds 2\\>\\&1 \\| $GREP \\\" -lc \\\" \\>/dev/null 2\\>\\&1\\\"\"; } >&5\n  (eval $archive_cmds 2\\>\\&1 \\| $GREP \\\" -lc \\\" \\>/dev/null 2\\>\\&1) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\n\t  then\n\t    lt_cv_archive_cmds_need_lc=no\n\t  else\n\t    lt_cv_archive_cmds_need_lc=yes\n\t  fi\n\t  allow_undefined_flag=$lt_save_allow_undefined_flag\n\telse\n\t  cat conftest.err 1>&5\n\tfi\n\t$RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc\" >&5\n$as_echo \"$lt_cv_archive_cmds_need_lc\" >&6; }\n      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc\n      ;;\n    esac\n  fi\n  ;;\nesac\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics\" >&5\n$as_echo_n \"checking dynamic linker characteristics... \" >&6; }\n\nif test \"$GCC\" = yes; then\n  case $host_os in\n    darwin*) lt_awk_arg=\"/^libraries:/,/LR/\" ;;\n    *) lt_awk_arg=\"/^libraries:/\" ;;\n  esac\n  case $host_os in\n    mingw* | cegcc*) lt_sed_strip_eq=\"s,=\\([A-Za-z]:\\),\\1,g\" ;;\n    *) lt_sed_strip_eq=\"s,=/,/,g\" ;;\n  esac\n  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e \"s/^libraries://\" -e $lt_sed_strip_eq`\n  case $lt_search_path_spec in\n  *\\;*)\n    # if the path contains \";\" then we assume it to be the separator\n    # otherwise default to the standard path separator (i.e. \":\") - it is\n    # assumed that no part of a normal pathname contains \";\" but that should\n    # okay in the real world where \";\" in dirpaths is itself problematic.\n    lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $SED 's/;/ /g'`\n    ;;\n  *)\n    lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $SED \"s/$PATH_SEPARATOR/ /g\"`\n    ;;\n  esac\n  # Ok, now we have the path, separated by spaces, we can step through it\n  # and add multilib dir if necessary.\n  lt_tmp_lt_search_path_spec=\n  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`\n  for lt_sys_path in $lt_search_path_spec; do\n    if test -d \"$lt_sys_path/$lt_multi_os_dir\"; then\n      lt_tmp_lt_search_path_spec=\"$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir\"\n    else\n      test -d \"$lt_sys_path\" && \\\n\tlt_tmp_lt_search_path_spec=\"$lt_tmp_lt_search_path_spec $lt_sys_path\"\n    fi\n  done\n  lt_search_path_spec=`$ECHO \"$lt_tmp_lt_search_path_spec\" | awk '\nBEGIN {RS=\" \"; FS=\"/|\\n\";} {\n  lt_foo=\"\";\n  lt_count=0;\n  for (lt_i = NF; lt_i > 0; lt_i--) {\n    if ($lt_i != \"\" && $lt_i != \".\") {\n      if ($lt_i == \"..\") {\n        lt_count++;\n      } else {\n        if (lt_count == 0) {\n          lt_foo=\"/\" $lt_i lt_foo;\n        } else {\n          lt_count--;\n        }\n      }\n    }\n  }\n  if (lt_foo != \"\") { lt_freq[lt_foo]++; }\n  if (lt_freq[lt_foo] == 1) { print lt_foo; }\n}'`\n  # AWK program above erroneously prepends '/' to C:/dos/paths\n  # for these hosts.\n  case $host_os in\n    mingw* | cegcc*) lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" |\\\n      $SED 's,/\\([A-Za-z]:\\),\\1,g'` ;;\n  esac\n  sys_lib_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $lt_NL2SP`\nelse\n  sys_lib_search_path_spec=\"/lib /usr/lib /usr/local/lib\"\nfi\nlibrary_names_spec=\nlibname_spec='lib$name'\nsoname_spec=\nshrext_cmds=\".so\"\npostinstall_cmds=\npostuninstall_cmds=\nfinish_cmds=\nfinish_eval=\nshlibpath_var=\nshlibpath_overrides_runpath=unknown\nversion_type=none\ndynamic_linker=\"$host_os ld.so\"\nsys_lib_dlsearch_path_spec=\"/lib /usr/lib\"\nneed_lib_prefix=unknown\nhardcode_into_libs=no\n\n# when you set need_version to no, make sure it does not cause -set_version\n# flags to be left without arguments\nneed_version=unknown\n\ncase $host_os in\naix3*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'\n  shlibpath_var=LIBPATH\n\n  # AIX 3 has no versioning support, so we append a major version to the name.\n  soname_spec='${libname}${release}${shared_ext}$major'\n  ;;\n\naix[4-9]*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  hardcode_into_libs=yes\n  if test \"$host_cpu\" = ia64; then\n    # AIX 5 supports IA64\n    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'\n    shlibpath_var=LD_LIBRARY_PATH\n  else\n    # With GCC up to 2.95.x, collect2 would create an import file\n    # for dependence libraries.  The import file would start with\n    # the line `#! .'.  This would cause the generated library to\n    # depend on `.', always an invalid library.  This was fixed in\n    # development snapshots of GCC prior to 3.0.\n    case $host_os in\n      aix4 | aix4.[01] | aix4.[01].*)\n      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'\n\t   echo ' yes '\n\t   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then\n\t:\n      else\n\tcan_build_shared=no\n      fi\n      ;;\n    esac\n    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct\n    # soname into executable. Probably we can add versioning support to\n    # collect2, so additional links can be useful in future.\n    if test \"$aix_use_runtimelinking\" = yes; then\n      # If using run time linking (on AIX 4.2 or later) use lib<name>.so\n      # instead of lib<name>.a to let people know that these are not\n      # typical AIX shared libraries.\n      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    else\n      # We preserve .a as extension for shared libraries through AIX4.2\n      # and later when we are not doing run time linking.\n      library_names_spec='${libname}${release}.a $libname.a'\n      soname_spec='${libname}${release}${shared_ext}$major'\n    fi\n    shlibpath_var=LIBPATH\n  fi\n  ;;\n\namigaos*)\n  case $host_cpu in\n  powerpc)\n    # Since July 2007 AmigaOS4 officially supports .so libraries.\n    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    ;;\n  m68k)\n    library_names_spec='$libname.ixlibrary $libname.a'\n    # Create ${libname}_ixlibrary.a entries in /sys/libs.\n    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all \"$lib\" | $SED '\\''s%^.*/\\([^/]*\\)\\.ixlibrary$%\\1%'\\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show \"cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a\"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'\n    ;;\n  esac\n  ;;\n\nbeos*)\n  library_names_spec='${libname}${shared_ext}'\n  dynamic_linker=\"$host_os ld.so\"\n  shlibpath_var=LIBRARY_PATH\n  ;;\n\nbsdi[45]*)\n  version_type=linux\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  sys_lib_search_path_spec=\"/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib\"\n  sys_lib_dlsearch_path_spec=\"/shlib /usr/lib /usr/local/lib\"\n  # the default ld.so.conf also contains /usr/contrib/lib and\n  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow\n  # libtool to hard-code these into programs\n  ;;\n\ncygwin* | mingw* | pw32* | cegcc*)\n  version_type=windows\n  shrext_cmds=\".dll\"\n  need_version=no\n  need_lib_prefix=no\n\n  case $GCC,$host_os in\n  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)\n    library_names_spec='$libname.dll.a'\n    # DLL is installed to $(libdir)/../bin by postinstall_cmds\n    postinstall_cmds='base_file=`basename \\${file}`~\n      dlpath=`$SHELL 2>&1 -c '\\''. $dir/'\\''\\${base_file}'\\''i; echo \\$dlname'\\''`~\n      dldir=$destdir/`dirname \\$dlpath`~\n      test -d \\$dldir || mkdir -p \\$dldir~\n      $install_prog $dir/$dlname \\$dldir/$dlname~\n      chmod a+x \\$dldir/$dlname~\n      if test -n '\\''$stripme'\\'' && test -n '\\''$striplib'\\''; then\n        eval '\\''$striplib \\$dldir/$dlname'\\'' || exit \\$?;\n      fi'\n    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\\''. $file; echo \\$dlname'\\''`~\n      dlpath=$dir/\\$dldll~\n       $RM \\$dlpath'\n    shlibpath_overrides_runpath=yes\n\n    case $host_os in\n    cygwin*)\n      # Cygwin DLLs use 'cyg' prefix rather than 'lib'\n      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'\n\n      sys_lib_search_path_spec=\"$sys_lib_search_path_spec /usr/lib/w32api\"\n      ;;\n    mingw* | cegcc*)\n      # MinGW DLLs use traditional 'lib' prefix\n      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'\n      ;;\n    pw32*)\n      # pw32 DLLs use 'pw' prefix rather than 'lib'\n      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'\n      ;;\n    esac\n    ;;\n\n  *)\n    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'\n    ;;\n  esac\n  dynamic_linker='Win32 ld.exe'\n  # FIXME: first we should search . and the directory the executable is in\n  shlibpath_var=PATH\n  ;;\n\ndarwin* | rhapsody*)\n  dynamic_linker=\"$host_os dyld\"\n  version_type=darwin\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'\n  soname_spec='${libname}${release}${major}$shared_ext'\n  shlibpath_overrides_runpath=yes\n  shlibpath_var=DYLD_LIBRARY_PATH\n  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'\n\n  sys_lib_search_path_spec=\"$sys_lib_search_path_spec /usr/local/lib\"\n  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'\n  ;;\n\ndgux*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  ;;\n\nfreebsd* | dragonfly*)\n  # DragonFly does not have aout.  When/if they implement a new\n  # versioning mechanism, adjust this.\n  if test -x /usr/bin/objformat; then\n    objformat=`/usr/bin/objformat`\n  else\n    case $host_os in\n    freebsd[23].*) objformat=aout ;;\n    *) objformat=elf ;;\n    esac\n  fi\n  version_type=freebsd-$objformat\n  case $version_type in\n    freebsd-elf*)\n      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'\n      need_version=no\n      need_lib_prefix=no\n      ;;\n    freebsd-*)\n      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'\n      need_version=yes\n      ;;\n  esac\n  shlibpath_var=LD_LIBRARY_PATH\n  case $host_os in\n  freebsd2.*)\n    shlibpath_overrides_runpath=yes\n    ;;\n  freebsd3.[01]* | freebsdelf3.[01]*)\n    shlibpath_overrides_runpath=yes\n    hardcode_into_libs=yes\n    ;;\n  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \\\n  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)\n    shlibpath_overrides_runpath=no\n    hardcode_into_libs=yes\n    ;;\n  *) # from 4.6 on, and DragonFly\n    shlibpath_overrides_runpath=yes\n    hardcode_into_libs=yes\n    ;;\n  esac\n  ;;\n\ngnu*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  hardcode_into_libs=yes\n  ;;\n\nhaiku*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  dynamic_linker=\"$host_os runtime_loader\"\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'\n  hardcode_into_libs=yes\n  ;;\n\nhpux9* | hpux10* | hpux11*)\n  # Give a soname corresponding to the major version so that dld.sl refuses to\n  # link against other versions.\n  version_type=sunos\n  need_lib_prefix=no\n  need_version=no\n  case $host_cpu in\n  ia64*)\n    shrext_cmds='.so'\n    hardcode_into_libs=yes\n    dynamic_linker=\"$host_os dld.so\"\n    shlibpath_var=LD_LIBRARY_PATH\n    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    if test \"X$HPUX_IA64_MODE\" = X32; then\n      sys_lib_search_path_spec=\"/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib\"\n    else\n      sys_lib_search_path_spec=\"/usr/lib/hpux64 /usr/local/lib/hpux64\"\n    fi\n    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec\n    ;;\n  hppa*64*)\n    shrext_cmds='.sl'\n    hardcode_into_libs=yes\n    dynamic_linker=\"$host_os dld.sl\"\n    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH\n    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    sys_lib_search_path_spec=\"/usr/lib/pa20_64 /usr/ccs/lib/pa20_64\"\n    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec\n    ;;\n  *)\n    shrext_cmds='.sl'\n    dynamic_linker=\"$host_os dld.sl\"\n    shlibpath_var=SHLIB_PATH\n    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    ;;\n  esac\n  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...\n  postinstall_cmds='chmod 555 $lib'\n  # or fails outright, so override atomically:\n  install_override_mode=555\n  ;;\n\ninterix[3-9]*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\nirix5* | irix6* | nonstopux*)\n  case $host_os in\n    nonstopux*) version_type=nonstopux ;;\n    *)\n\tif test \"$lt_cv_prog_gnu_ld\" = yes; then\n\t\tversion_type=linux\n\telse\n\t\tversion_type=irix\n\tfi ;;\n  esac\n  need_lib_prefix=no\n  need_version=no\n  soname_spec='${libname}${release}${shared_ext}$major'\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'\n  case $host_os in\n  irix5* | nonstopux*)\n    libsuff= shlibsuff=\n    ;;\n  *)\n    case $LD in # libtool.m4 will add one of these switches to LD\n    *-32|*\"-32 \"|*-melf32bsmip|*\"-melf32bsmip \")\n      libsuff= shlibsuff= libmagic=32-bit;;\n    *-n32|*\"-n32 \"|*-melf32bmipn32|*\"-melf32bmipn32 \")\n      libsuff=32 shlibsuff=N32 libmagic=N32;;\n    *-64|*\"-64 \"|*-melf64bmip|*\"-melf64bmip \")\n      libsuff=64 shlibsuff=64 libmagic=64-bit;;\n    *) libsuff= shlibsuff= libmagic=never-match;;\n    esac\n    ;;\n  esac\n  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH\n  shlibpath_overrides_runpath=no\n  sys_lib_search_path_spec=\"/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}\"\n  sys_lib_dlsearch_path_spec=\"/usr/lib${libsuff} /lib${libsuff}\"\n  hardcode_into_libs=yes\n  ;;\n\n# No shared lib support for Linux oldld, aout, or coff.\nlinux*oldld* | linux*aout* | linux*coff*)\n  dynamic_linker=no\n  ;;\n\n# This must be Linux ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -n $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n\n  # Some binutils ld are patched to set DT_RUNPATH\n  if test \"${lt_cv_shlibpath_overrides_runpath+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_shlibpath_overrides_runpath=no\n    save_LDFLAGS=$LDFLAGS\n    save_libdir=$libdir\n    eval \"libdir=/foo; wl=\\\"$lt_prog_compiler_wl\\\"; \\\n\t LDFLAGS=\\\"\\$LDFLAGS $hardcode_libdir_flag_spec\\\"\"\n    cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep \"RUNPATH.*$libdir\" >/dev/null; then :\n  lt_cv_shlibpath_overrides_runpath=yes\nfi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n    LDFLAGS=$save_LDFLAGS\n    libdir=$save_libdir\n\nfi\n\n  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath\n\n  # This implies no fast_install, which is unacceptable.\n  # Some rework will be needed to allow for fast_install\n  # before this can be enabled.\n  hardcode_into_libs=yes\n\n  # Append ld.so.conf contents to the search path\n  if test -f /etc/ld.so.conf; then\n    lt_ld_extra=`awk '/^include / { system(sprintf(\"cd /etc; cat %s 2>/dev/null\", \\$2)); skip = 1; } { if (!skip) print \\$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[\t ]*hwcap[\t ]/d;s/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/\"//g;/^$/d' | tr '\\n' ' '`\n    sys_lib_dlsearch_path_spec=\"/lib /usr/lib $lt_ld_extra\"\n  fi\n\n  # We used to test for /lib/ld.so.1 and disable shared libraries on\n  # powerpc, because MkLinux only supported shared libraries with the\n  # GNU dynamic linker.  Since this was broken with cross compilers,\n  # most powerpc-linux boxes support dynamic linking these days and\n  # people can always --disable-shared, the test was removed, and we\n  # assume the GNU/Linux dynamic linker is in use.\n  dynamic_linker='GNU/Linux ld.so'\n  ;;\n\nnetbsd*)\n  version_type=sunos\n  need_lib_prefix=no\n  need_version=no\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n    finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -m $libdir'\n    dynamic_linker='NetBSD (a.out) ld.so'\n  else\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    dynamic_linker='NetBSD ld.elf_so'\n  fi\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  ;;\n\nnewsos6)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  ;;\n\n*nto* | *qnx*)\n  version_type=qnx\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  dynamic_linker='ldqnx.so'\n  ;;\n\nopenbsd*)\n  version_type=sunos\n  sys_lib_dlsearch_path_spec=\"/usr/lib\"\n  need_lib_prefix=no\n  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.\n  case $host_os in\n    openbsd3.3 | openbsd3.3.*)\tneed_version=yes ;;\n    *)\t\t\t\tneed_version=no  ;;\n  esac\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -m $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  if test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n    case $host_os in\n      openbsd2.[89] | openbsd2.[89].*)\n\tshlibpath_overrides_runpath=no\n\t;;\n      *)\n\tshlibpath_overrides_runpath=yes\n\t;;\n      esac\n  else\n    shlibpath_overrides_runpath=yes\n  fi\n  ;;\n\nos2*)\n  libname_spec='$name'\n  shrext_cmds=\".dll\"\n  need_lib_prefix=no\n  library_names_spec='$libname${shared_ext} $libname.a'\n  dynamic_linker='OS/2 ld.exe'\n  shlibpath_var=LIBPATH\n  ;;\n\nosf3* | osf4* | osf5*)\n  version_type=osf\n  need_lib_prefix=no\n  need_version=no\n  soname_spec='${libname}${release}${shared_ext}$major'\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  sys_lib_search_path_spec=\"/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib\"\n  sys_lib_dlsearch_path_spec=\"$sys_lib_search_path_spec\"\n  ;;\n\nrdos*)\n  dynamic_linker=no\n  ;;\n\nsolaris*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  # ldd complains unless libraries are executable\n  postinstall_cmds='chmod +x $lib'\n  ;;\n\nsunos4*)\n  version_type=sunos\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n  finish_cmds='PATH=\"\\$PATH:/usr/etc\" ldconfig $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  if test \"$with_gnu_ld\" = yes; then\n    need_lib_prefix=no\n  fi\n  need_version=yes\n  ;;\n\nsysv4 | sysv4.3*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  case $host_vendor in\n    sni)\n      shlibpath_overrides_runpath=no\n      need_lib_prefix=no\n      runpath_var=LD_RUN_PATH\n      ;;\n    siemens)\n      need_lib_prefix=no\n      ;;\n    motorola)\n      need_lib_prefix=no\n      need_version=no\n      shlibpath_overrides_runpath=no\n      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'\n      ;;\n  esac\n  ;;\n\nsysv4*MP*)\n  if test -d /usr/nec ;then\n    version_type=linux\n    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'\n    soname_spec='$libname${shared_ext}.$major'\n    shlibpath_var=LD_LIBRARY_PATH\n  fi\n  ;;\n\nsysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)\n  version_type=freebsd-elf\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  if test \"$with_gnu_ld\" = yes; then\n    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'\n  else\n    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'\n    case $host_os in\n      sco3.2v5*)\n        sys_lib_search_path_spec=\"$sys_lib_search_path_spec /lib\"\n\t;;\n    esac\n  fi\n  sys_lib_dlsearch_path_spec='/usr/lib'\n  ;;\n\ntpf*)\n  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\nuts4*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  ;;\n\n*)\n  dynamic_linker=no\n  ;;\nesac\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $dynamic_linker\" >&5\n$as_echo \"$dynamic_linker\" >&6; }\ntest \"$dynamic_linker\" = no && can_build_shared=no\n\nvariables_saved_for_relink=\"PATH $shlibpath_var $runpath_var\"\nif test \"$GCC\" = yes; then\n  variables_saved_for_relink=\"$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH\"\nfi\n\nif test \"${lt_cv_sys_lib_search_path_spec+set}\" = set; then\n  sys_lib_search_path_spec=\"$lt_cv_sys_lib_search_path_spec\"\nfi\nif test \"${lt_cv_sys_lib_dlsearch_path_spec+set}\" = set; then\n  sys_lib_dlsearch_path_spec=\"$lt_cv_sys_lib_dlsearch_path_spec\"\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs\" >&5\n$as_echo_n \"checking how to hardcode library paths into programs... \" >&6; }\nhardcode_action=\nif test -n \"$hardcode_libdir_flag_spec\" ||\n   test -n \"$runpath_var\" ||\n   test \"X$hardcode_automatic\" = \"Xyes\" ; then\n\n  # We can hardcode non-existent directories.\n  if test \"$hardcode_direct\" != no &&\n     # If the only mechanism to avoid hardcoding is shlibpath_var, we\n     # have to relink, otherwise we might link with an installed library\n     # when we should be linking with a yet-to-be-installed one\n     ## test \"$_LT_TAGVAR(hardcode_shlibpath_var, )\" != no &&\n     test \"$hardcode_minus_L\" != no; then\n    # Linking always hardcodes the temporary library directory.\n    hardcode_action=relink\n  else\n    # We can link without hardcoding, and we can hardcode nonexisting dirs.\n    hardcode_action=immediate\n  fi\nelse\n  # We cannot hardcode anything, or else we can only hardcode existing\n  # directories.\n  hardcode_action=unsupported\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $hardcode_action\" >&5\n$as_echo \"$hardcode_action\" >&6; }\n\nif test \"$hardcode_action\" = relink ||\n   test \"$inherit_rpath\" = yes; then\n  # Fast installation is not supported\n  enable_fast_install=no\nelif test \"$shlibpath_overrides_runpath\" = yes ||\n     test \"$enable_shared\" = no; then\n  # Fast installation is not necessary\n  enable_fast_install=needless\nfi\n\n\n\n\n\n\n  if test \"x$enable_dlopen\" != xyes; then\n  enable_dlopen=unknown\n  enable_dlopen_self=unknown\n  enable_dlopen_self_static=unknown\nelse\n  lt_cv_dlopen=no\n  lt_cv_dlopen_libs=\n\n  case $host_os in\n  beos*)\n    lt_cv_dlopen=\"load_add_on\"\n    lt_cv_dlopen_libs=\n    lt_cv_dlopen_self=yes\n    ;;\n\n  mingw* | pw32* | cegcc*)\n    lt_cv_dlopen=\"LoadLibrary\"\n    lt_cv_dlopen_libs=\n    ;;\n\n  cygwin*)\n    lt_cv_dlopen=\"dlopen\"\n    lt_cv_dlopen_libs=\n    ;;\n\n  darwin*)\n  # if libdl is installed we need to link against it\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl\" >&5\n$as_echo_n \"checking for dlopen in -ldl... \" >&6; }\nif test \"${ac_cv_lib_dl_dlopen+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-ldl  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar dlopen ();\nint\nmain ()\n{\nreturn dlopen ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_dl_dlopen=yes\nelse\n  ac_cv_lib_dl_dlopen=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen\" >&5\n$as_echo \"$ac_cv_lib_dl_dlopen\" >&6; }\nif test \"x$ac_cv_lib_dl_dlopen\" = x\"\"yes; then :\n  lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-ldl\"\nelse\n\n    lt_cv_dlopen=\"dyld\"\n    lt_cv_dlopen_libs=\n    lt_cv_dlopen_self=yes\n\nfi\n\n    ;;\n\n  *)\n    ac_fn_c_check_func \"$LINENO\" \"shl_load\" \"ac_cv_func_shl_load\"\nif test \"x$ac_cv_func_shl_load\" = x\"\"yes; then :\n  lt_cv_dlopen=\"shl_load\"\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld\" >&5\n$as_echo_n \"checking for shl_load in -ldld... \" >&6; }\nif test \"${ac_cv_lib_dld_shl_load+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-ldld  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar shl_load ();\nint\nmain ()\n{\nreturn shl_load ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_dld_shl_load=yes\nelse\n  ac_cv_lib_dld_shl_load=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load\" >&5\n$as_echo \"$ac_cv_lib_dld_shl_load\" >&6; }\nif test \"x$ac_cv_lib_dld_shl_load\" = x\"\"yes; then :\n  lt_cv_dlopen=\"shl_load\" lt_cv_dlopen_libs=\"-ldld\"\nelse\n  ac_fn_c_check_func \"$LINENO\" \"dlopen\" \"ac_cv_func_dlopen\"\nif test \"x$ac_cv_func_dlopen\" = x\"\"yes; then :\n  lt_cv_dlopen=\"dlopen\"\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl\" >&5\n$as_echo_n \"checking for dlopen in -ldl... \" >&6; }\nif test \"${ac_cv_lib_dl_dlopen+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-ldl  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar dlopen ();\nint\nmain ()\n{\nreturn dlopen ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_dl_dlopen=yes\nelse\n  ac_cv_lib_dl_dlopen=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen\" >&5\n$as_echo \"$ac_cv_lib_dl_dlopen\" >&6; }\nif test \"x$ac_cv_lib_dl_dlopen\" = x\"\"yes; then :\n  lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-ldl\"\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld\" >&5\n$as_echo_n \"checking for dlopen in -lsvld... \" >&6; }\nif test \"${ac_cv_lib_svld_dlopen+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lsvld  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar dlopen ();\nint\nmain ()\n{\nreturn dlopen ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_svld_dlopen=yes\nelse\n  ac_cv_lib_svld_dlopen=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen\" >&5\n$as_echo \"$ac_cv_lib_svld_dlopen\" >&6; }\nif test \"x$ac_cv_lib_svld_dlopen\" = x\"\"yes; then :\n  lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-lsvld\"\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld\" >&5\n$as_echo_n \"checking for dld_link in -ldld... \" >&6; }\nif test \"${ac_cv_lib_dld_dld_link+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-ldld  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar dld_link ();\nint\nmain ()\n{\nreturn dld_link ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_dld_dld_link=yes\nelse\n  ac_cv_lib_dld_dld_link=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link\" >&5\n$as_echo \"$ac_cv_lib_dld_dld_link\" >&6; }\nif test \"x$ac_cv_lib_dld_dld_link\" = x\"\"yes; then :\n  lt_cv_dlopen=\"dld_link\" lt_cv_dlopen_libs=\"-ldld\"\nfi\n\n\nfi\n\n\nfi\n\n\nfi\n\n\nfi\n\n\nfi\n\n    ;;\n  esac\n\n  if test \"x$lt_cv_dlopen\" != xno; then\n    enable_dlopen=yes\n  else\n    enable_dlopen=no\n  fi\n\n  case $lt_cv_dlopen in\n  dlopen)\n    save_CPPFLAGS=\"$CPPFLAGS\"\n    test \"x$ac_cv_header_dlfcn_h\" = xyes && CPPFLAGS=\"$CPPFLAGS -DHAVE_DLFCN_H\"\n\n    save_LDFLAGS=\"$LDFLAGS\"\n    wl=$lt_prog_compiler_wl eval LDFLAGS=\\\"\\$LDFLAGS $export_dynamic_flag_spec\\\"\n\n    save_LIBS=\"$LIBS\"\n    LIBS=\"$lt_cv_dlopen_libs $LIBS\"\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself\" >&5\n$as_echo_n \"checking whether a program can dlopen itself... \" >&6; }\nif test \"${lt_cv_dlopen_self+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  \t  if test \"$cross_compiling\" = yes; then :\n  lt_cv_dlopen_self=cross\nelse\n  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2\n  lt_status=$lt_dlunknown\n  cat > conftest.$ac_ext <<_LT_EOF\n#line 11209 \"configure\"\n#include \"confdefs.h\"\n\n#if HAVE_DLFCN_H\n#include <dlfcn.h>\n#endif\n\n#include <stdio.h>\n\n#ifdef RTLD_GLOBAL\n#  define LT_DLGLOBAL\t\tRTLD_GLOBAL\n#else\n#  ifdef DL_GLOBAL\n#    define LT_DLGLOBAL\t\tDL_GLOBAL\n#  else\n#    define LT_DLGLOBAL\t\t0\n#  endif\n#endif\n\n/* We may have to define LT_DLLAZY_OR_NOW in the command line if we\n   find out it does not work in some platform. */\n#ifndef LT_DLLAZY_OR_NOW\n#  ifdef RTLD_LAZY\n#    define LT_DLLAZY_OR_NOW\t\tRTLD_LAZY\n#  else\n#    ifdef DL_LAZY\n#      define LT_DLLAZY_OR_NOW\t\tDL_LAZY\n#    else\n#      ifdef RTLD_NOW\n#        define LT_DLLAZY_OR_NOW\tRTLD_NOW\n#      else\n#        ifdef DL_NOW\n#          define LT_DLLAZY_OR_NOW\tDL_NOW\n#        else\n#          define LT_DLLAZY_OR_NOW\t0\n#        endif\n#      endif\n#    endif\n#  endif\n#endif\n\n/* When -fvisbility=hidden is used, assume the code has been annotated\n   correspondingly for the symbols needed.  */\n#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))\nvoid fnord () __attribute__((visibility(\"default\")));\n#endif\n\nvoid fnord () { int i=42; }\nint main ()\n{\n  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);\n  int status = $lt_dlunknown;\n\n  if (self)\n    {\n      if (dlsym (self,\"fnord\"))       status = $lt_dlno_uscore;\n      else\n        {\n\t  if (dlsym( self,\"_fnord\"))  status = $lt_dlneed_uscore;\n          else puts (dlerror ());\n\t}\n      /* dlclose (self); */\n    }\n  else\n    puts (dlerror ());\n\n  return status;\n}\n_LT_EOF\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_link\\\"\"; } >&5\n  (eval $ac_link) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then\n    (./conftest; exit; ) >&5 2>/dev/null\n    lt_status=$?\n    case x$lt_status in\n      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;\n      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;\n      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;\n    esac\n  else :\n    # compilation failed\n    lt_cv_dlopen_self=no\n  fi\nfi\nrm -fr conftest*\n\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self\" >&5\n$as_echo \"$lt_cv_dlopen_self\" >&6; }\n\n    if test \"x$lt_cv_dlopen_self\" = xyes; then\n      wl=$lt_prog_compiler_wl eval LDFLAGS=\\\"\\$LDFLAGS $lt_prog_compiler_static\\\"\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself\" >&5\n$as_echo_n \"checking whether a statically linked program can dlopen itself... \" >&6; }\nif test \"${lt_cv_dlopen_self_static+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  \t  if test \"$cross_compiling\" = yes; then :\n  lt_cv_dlopen_self_static=cross\nelse\n  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2\n  lt_status=$lt_dlunknown\n  cat > conftest.$ac_ext <<_LT_EOF\n#line 11315 \"configure\"\n#include \"confdefs.h\"\n\n#if HAVE_DLFCN_H\n#include <dlfcn.h>\n#endif\n\n#include <stdio.h>\n\n#ifdef RTLD_GLOBAL\n#  define LT_DLGLOBAL\t\tRTLD_GLOBAL\n#else\n#  ifdef DL_GLOBAL\n#    define LT_DLGLOBAL\t\tDL_GLOBAL\n#  else\n#    define LT_DLGLOBAL\t\t0\n#  endif\n#endif\n\n/* We may have to define LT_DLLAZY_OR_NOW in the command line if we\n   find out it does not work in some platform. */\n#ifndef LT_DLLAZY_OR_NOW\n#  ifdef RTLD_LAZY\n#    define LT_DLLAZY_OR_NOW\t\tRTLD_LAZY\n#  else\n#    ifdef DL_LAZY\n#      define LT_DLLAZY_OR_NOW\t\tDL_LAZY\n#    else\n#      ifdef RTLD_NOW\n#        define LT_DLLAZY_OR_NOW\tRTLD_NOW\n#      else\n#        ifdef DL_NOW\n#          define LT_DLLAZY_OR_NOW\tDL_NOW\n#        else\n#          define LT_DLLAZY_OR_NOW\t0\n#        endif\n#      endif\n#    endif\n#  endif\n#endif\n\n/* When -fvisbility=hidden is used, assume the code has been annotated\n   correspondingly for the symbols needed.  */\n#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))\nvoid fnord () __attribute__((visibility(\"default\")));\n#endif\n\nvoid fnord () { int i=42; }\nint main ()\n{\n  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);\n  int status = $lt_dlunknown;\n\n  if (self)\n    {\n      if (dlsym (self,\"fnord\"))       status = $lt_dlno_uscore;\n      else\n        {\n\t  if (dlsym( self,\"_fnord\"))  status = $lt_dlneed_uscore;\n          else puts (dlerror ());\n\t}\n      /* dlclose (self); */\n    }\n  else\n    puts (dlerror ());\n\n  return status;\n}\n_LT_EOF\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_link\\\"\"; } >&5\n  (eval $ac_link) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then\n    (./conftest; exit; ) >&5 2>/dev/null\n    lt_status=$?\n    case x$lt_status in\n      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;\n      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;\n      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;\n    esac\n  else :\n    # compilation failed\n    lt_cv_dlopen_self_static=no\n  fi\nfi\nrm -fr conftest*\n\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static\" >&5\n$as_echo \"$lt_cv_dlopen_self_static\" >&6; }\n    fi\n\n    CPPFLAGS=\"$save_CPPFLAGS\"\n    LDFLAGS=\"$save_LDFLAGS\"\n    LIBS=\"$save_LIBS\"\n    ;;\n  esac\n\n  case $lt_cv_dlopen_self in\n  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;\n  *) enable_dlopen_self=unknown ;;\n  esac\n\n  case $lt_cv_dlopen_self_static in\n  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;\n  *) enable_dlopen_self_static=unknown ;;\n  esac\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nstriplib=\nold_striplib=\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible\" >&5\n$as_echo_n \"checking whether stripping libraries is possible... \" >&6; }\nif test -n \"$STRIP\" && $STRIP -V 2>&1 | $GREP \"GNU strip\" >/dev/null; then\n  test -z \"$old_striplib\" && old_striplib=\"$STRIP --strip-debug\"\n  test -z \"$striplib\" && striplib=\"$STRIP --strip-unneeded\"\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n# FIXME - insert some real tests, host_os isn't really good enough\n  case $host_os in\n  darwin*)\n    if test -n \"$STRIP\" ; then\n      striplib=\"$STRIP -x\"\n      old_striplib=\"$STRIP -S\"\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n    else\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n    fi\n    ;;\n  *)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n    ;;\n  esac\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n  # Report which library types will actually be built\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries\" >&5\n$as_echo_n \"checking if libtool supports shared libraries... \" >&6; }\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $can_build_shared\" >&5\n$as_echo \"$can_build_shared\" >&6; }\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries\" >&5\n$as_echo_n \"checking whether to build shared libraries... \" >&6; }\n  test \"$can_build_shared\" = \"no\" && enable_shared=no\n\n  # On AIX, shared libraries and static libraries use the same namespace, and\n  # are all built from PIC.\n  case $host_os in\n  aix3*)\n    test \"$enable_shared\" = yes && enable_static=no\n    if test -n \"$RANLIB\"; then\n      archive_cmds=\"$archive_cmds~\\$RANLIB \\$lib\"\n      postinstall_cmds='$RANLIB $lib'\n    fi\n    ;;\n\n  aix[4-9]*)\n    if test \"$host_cpu\" != ia64 && test \"$aix_use_runtimelinking\" = no ; then\n      test \"$enable_shared\" = yes && enable_static=no\n    fi\n    ;;\n  esac\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $enable_shared\" >&5\n$as_echo \"$enable_shared\" >&6; }\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether to build static libraries\" >&5\n$as_echo_n \"checking whether to build static libraries... \" >&6; }\n  # Make sure either enable_shared or enable_static is yes.\n  test \"$enable_shared\" = yes || enable_static=yes\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $enable_static\" >&5\n$as_echo \"$enable_static\" >&6; }\n\n\n\n\nfi\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nCC=\"$lt_save_CC\"\n\n\n\n\n\n\n\n\n\n\n\n\n\n        ac_config_commands=\"$ac_config_commands libtool\"\n\n\n\n\n# Only expand once:\n\n\n\n\n\n  gdc_save_DFLAGS=$GDCFLAGS\n  GDCFLAGS=\"-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime  $GDCFLAGS\"\n\n\n# Source file extension for D test sources.\nac_ext=d\n\n# Object file extension for compiled D test sources.\nobjext=o\nobjext_D=$objext\n\n# Code to be used in simple compile tests\nlt_simple_compile_test_code=\"module mod; extern(C) int main() { return 0; }\"\n\n# Code to be used in simple link tests\nlt_simple_link_test_code='module mod; extern(C) int main() { return 0; }'\n\n# ltmain only uses $CC for tagged configurations so make sure $CC is set.\n\n\n\n\n\n\n# If no C compiler was specified, use CC.\nLTCC=${LTCC-\"$CC\"}\n\n# If no C compiler flags were specified, use CFLAGS.\nLTCFLAGS=${LTCFLAGS-\"$CFLAGS\"}\n\n# Allow CC to be a program name with arguments.\ncompiler=$CC\n\n\n# save warnings/boilerplate of simple test code\nac_outfile=conftest.$ac_objext\necho \"$lt_simple_compile_test_code\" >conftest.$ac_ext\neval \"$ac_compile\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_compiler_boilerplate=`cat conftest.err`\n$RM conftest*\n\nac_outfile=conftest.$ac_objext\necho \"$lt_simple_link_test_code\" >conftest.$ac_ext\neval \"$ac_link\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_linker_boilerplate=`cat conftest.err`\n$RM -r conftest*\n\n\n# Allow CC to be a program name with arguments.\nlt_save_CC=$CC\nlt_save_CFLAGS=$CFLAGS\nlt_save_DFLAGS=$GDCFLAGS\nlt_save_GCC=$GCC\nGCC=yes\nCC=${GDC-\"gdc\"}\n# Need to specify location for object.d\nGDCFLAGS=\"-nophoboslib $GDCFLAGS\"\nCFLAGS=$GDCFLAGS\ncompiler=$CC\ncompiler_D=$CC\nLD_D=$CC\nfor cc_temp in $compiler\"\"; do\n  case $cc_temp in\n    compile | *[\\\\/]compile | ccache | *[\\\\/]ccache ) ;;\n    distcc | *[\\\\/]distcc | purify | *[\\\\/]purify ) ;;\n    \\-*) ;;\n    *) break;;\n  esac\ndone\ncc_basename=`$ECHO \"$cc_temp\" | $SED \"s%.*/%%; s%^$host_alias-%%\"`\n\n\n# GDC did not exist at the time GCC didn't implicitly link libc in.\narchive_cmds_need_lc_D=no\n\nold_archive_cmds_D=$old_archive_cmds\nreload_flag_D=$reload_flag\nreload_cmds_D=$reload_cmds\n\n## CAVEAT EMPTOR:\n## There is no encapsulation within the following macros, do not change\n## the running order or otherwise move them around unless you know exactly\n## what you are doing...\nif test -n \"$compiler\"; then\n\nlt_prog_compiler_no_builtin_flag_D=\n\nif test \"$GCC\" = yes; then\n  case $cc_basename in\n  nvcc*)\n    lt_prog_compiler_no_builtin_flag_D=' -Xcompiler -fno-builtin' ;;\n  *)\n    lt_prog_compiler_no_builtin_flag_D=' -fno-builtin' ;;\n  esac\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions\" >&5\n$as_echo_n \"checking if $compiler supports -fno-rtti -fno-exceptions... \" >&6; }\nif test \"${lt_cv_prog_compiler_rtti_exceptions+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_rtti_exceptions=no\n   ac_outfile=conftest.$ac_objext\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n   lt_compiler_flag=\"-fno-rtti -fno-exceptions\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   # The option is referenced via a variable to avoid confusing sed.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s \"$ac_outfile\"; then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings other than the usual output.\n     $ECHO \"$_lt_compiler_boilerplate\" | $SED '/^$/d' >conftest.exp\n     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_rtti_exceptions=yes\n     fi\n   fi\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions\" >&5\n$as_echo \"$lt_cv_prog_compiler_rtti_exceptions\" >&6; }\n\nif test x\"$lt_cv_prog_compiler_rtti_exceptions\" = xyes; then\n    lt_prog_compiler_no_builtin_flag_D=\"$lt_prog_compiler_no_builtin_flag_D -fno-rtti -fno-exceptions\"\nelse\n    :\nfi\n\nfi\n\n\n\n  lt_prog_compiler_wl_D=\nlt_prog_compiler_pic_D=\nlt_prog_compiler_static_D=\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC\" >&5\n$as_echo_n \"checking for $compiler option to produce PIC... \" >&6; }\n\n  if test \"$GCC\" = yes; then\n    lt_prog_compiler_wl_D='-Wl,'\n    lt_prog_compiler_static_D='-static'\n\n    case $host_os in\n      aix*)\n      # All AIX code is PIC.\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\tlt_prog_compiler_static_D='-Bstatic'\n      fi\n      lt_prog_compiler_pic_D='-fPIC'\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            lt_prog_compiler_pic_D='-fPIC'\n        ;;\n      m68k)\n            # FIXME: we need at least 68020 code to build shared libraries, but\n            # adding the `-m68020' flag to GCC prevents building anything better,\n            # like `-m68040'.\n            lt_prog_compiler_pic_D='-m68020 -resident32 -malways-restore-a4'\n        ;;\n      esac\n      ;;\n\n    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)\n      # PIC is the default for these OSes.\n      ;;\n\n    mingw* | cygwin* | pw32* | os2* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      # Although the cygwin gcc ignores -fPIC, still need this for old-style\n      # (--disable-auto-import) libraries\n      lt_prog_compiler_pic_D='-DDLL_EXPORT'\n      ;;\n\n    darwin* | rhapsody*)\n      # PIC is the default on this platform\n      # Common symbols not allowed in MH_DYLIB files\n      lt_prog_compiler_pic_D='-fno-common'\n      ;;\n\n    haiku*)\n      # PIC is the default for Haiku.\n      # The \"-static\" flag exists, but is broken.\n      lt_prog_compiler_static_D=\n      ;;\n\n    hpux*)\n      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit\n      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag\n      # sets the default TLS model and affects inlining.\n      case $host_cpu in\n      hppa*64*)\n\t# +Z the default\n\t;;\n      *)\n\tlt_prog_compiler_pic_D='-fPIC'\n\t;;\n      esac\n      ;;\n\n    interix[3-9]*)\n      # Interix 3.x gcc -fpic/-fPIC options generate broken code.\n      # Instead, we relocate shared libraries at runtime.\n      ;;\n\n    msdosdjgpp*)\n      # Just because we use GCC doesn't mean we suddenly get shared libraries\n      # on systems that don't support them.\n      lt_prog_compiler_can_build_shared_D=no\n      enable_shared=no\n      ;;\n\n    *nto* | *qnx*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      lt_prog_compiler_pic_D='-fPIC -shared'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\tlt_prog_compiler_pic_D=-Kconform_pic\n      fi\n      ;;\n\n    *)\n      lt_prog_compiler_pic_D='-fPIC'\n      ;;\n    esac\n\n    case $cc_basename in\n    nvcc*) # Cuda Compiler Driver 2.2\n      lt_prog_compiler_wl_D='-Xlinker '\n      lt_prog_compiler_pic_D='-Xcompiler -fPIC'\n      ;;\n    esac\n  else\n    # PORTME Check for flag to pass linker flags through the system compiler.\n    case $host_os in\n    aix*)\n      lt_prog_compiler_wl_D='-Wl,'\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\tlt_prog_compiler_static_D='-Bstatic'\n      else\n\tlt_prog_compiler_static_D='-bnso -bI:/lib/syscalls.exp'\n      fi\n      ;;\n\n    mingw* | cygwin* | pw32* | os2* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      lt_prog_compiler_pic_D='-DDLL_EXPORT'\n      ;;\n\n    hpux9* | hpux10* | hpux11*)\n      lt_prog_compiler_wl_D='-Wl,'\n      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but\n      # not for PA HP-UX.\n      case $host_cpu in\n      hppa*64*|ia64*)\n\t# +Z the default\n\t;;\n      *)\n\tlt_prog_compiler_pic_D='+Z'\n\t;;\n      esac\n      # Is there a better lt_prog_compiler_static that works with the bundled CC?\n      lt_prog_compiler_static_D='${wl}-a ${wl}archive'\n      ;;\n\n    irix5* | irix6* | nonstopux*)\n      lt_prog_compiler_wl_D='-Wl,'\n      # PIC (with -KPIC) is the default.\n      lt_prog_compiler_static_D='-non_shared'\n      ;;\n\n    linux* | k*bsd*-gnu | kopensolaris*-gnu)\n      case $cc_basename in\n      # old Intel for x86_64 which still supported -KPIC.\n      ecc*)\n\tlt_prog_compiler_wl_D='-Wl,'\n\tlt_prog_compiler_pic_D='-KPIC'\n\tlt_prog_compiler_static_D='-static'\n        ;;\n      # icc used to be incompatible with GCC.\n      # ICC 10 doesn't accept -KPIC any more.\n      icc* | ifort*)\n\tlt_prog_compiler_wl_D='-Wl,'\n\tlt_prog_compiler_pic_D='-fPIC'\n\tlt_prog_compiler_static_D='-static'\n        ;;\n      # Lahey Fortran 8.1.\n      lf95*)\n\tlt_prog_compiler_wl_D='-Wl,'\n\tlt_prog_compiler_pic_D='--shared'\n\tlt_prog_compiler_static_D='--static'\n\t;;\n      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)\n        # Portland Group compilers (*not* the Pentium gcc compiler,\n\t# which looks to be a dead project)\n\tlt_prog_compiler_wl_D='-Wl,'\n\tlt_prog_compiler_pic_D='-fpic'\n\tlt_prog_compiler_static_D='-Bstatic'\n        ;;\n      ccc*)\n        lt_prog_compiler_wl_D='-Wl,'\n        # All Alpha code is PIC.\n        lt_prog_compiler_static_D='-non_shared'\n        ;;\n      xl* | bgxl* | bgf* | mpixl*)\n\t# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene\n\tlt_prog_compiler_wl_D='-Wl,'\n\tlt_prog_compiler_pic_D='-qpic'\n\tlt_prog_compiler_static_D='-qstaticlink'\n\t;;\n      *)\n\tcase `$CC -V 2>&1 | sed 5q` in\n\t*Sun\\ F* | *Sun*Fortran*)\n\t  # Sun Fortran 8.3 passes all unrecognized flags to the linker\n\t  lt_prog_compiler_pic_D='-KPIC'\n\t  lt_prog_compiler_static_D='-Bstatic'\n\t  lt_prog_compiler_wl_D=''\n\t  ;;\n\t*Sun\\ C*)\n\t  # Sun C 5.9\n\t  lt_prog_compiler_pic_D='-KPIC'\n\t  lt_prog_compiler_static_D='-Bstatic'\n\t  lt_prog_compiler_wl_D='-Wl,'\n\t  ;;\n\tesac\n\t;;\n      esac\n      ;;\n\n    newsos6)\n      lt_prog_compiler_pic_D='-KPIC'\n      lt_prog_compiler_static_D='-Bstatic'\n      ;;\n\n    *nto* | *qnx*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      lt_prog_compiler_pic_D='-fPIC -shared'\n      ;;\n\n    osf3* | osf4* | osf5*)\n      lt_prog_compiler_wl_D='-Wl,'\n      # All OSF/1 code is PIC.\n      lt_prog_compiler_static_D='-non_shared'\n      ;;\n\n    rdos*)\n      lt_prog_compiler_static_D='-non_shared'\n      ;;\n\n    solaris*)\n      lt_prog_compiler_pic_D='-KPIC'\n      lt_prog_compiler_static_D='-Bstatic'\n      case $cc_basename in\n      f77* | f90* | f95*)\n\tlt_prog_compiler_wl_D='-Qoption ld ';;\n      *)\n\tlt_prog_compiler_wl_D='-Wl,';;\n      esac\n      ;;\n\n    sunos4*)\n      lt_prog_compiler_wl_D='-Qoption ld '\n      lt_prog_compiler_pic_D='-PIC'\n      lt_prog_compiler_static_D='-Bstatic'\n      ;;\n\n    sysv4 | sysv4.2uw2* | sysv4.3*)\n      lt_prog_compiler_wl_D='-Wl,'\n      lt_prog_compiler_pic_D='-KPIC'\n      lt_prog_compiler_static_D='-Bstatic'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec ;then\n\tlt_prog_compiler_pic_D='-Kconform_pic'\n\tlt_prog_compiler_static_D='-Bstatic'\n      fi\n      ;;\n\n    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)\n      lt_prog_compiler_wl_D='-Wl,'\n      lt_prog_compiler_pic_D='-KPIC'\n      lt_prog_compiler_static_D='-Bstatic'\n      ;;\n\n    unicos*)\n      lt_prog_compiler_wl_D='-Wl,'\n      lt_prog_compiler_can_build_shared_D=no\n      ;;\n\n    uts4*)\n      lt_prog_compiler_pic_D='-pic'\n      lt_prog_compiler_static_D='-Bstatic'\n      ;;\n\n    *)\n      lt_prog_compiler_can_build_shared_D=no\n      ;;\n    esac\n  fi\n\ncase $host_os in\n  # For platforms which do not support PIC, -DPIC is meaningless:\n  *djgpp*)\n    lt_prog_compiler_pic_D=\n    ;;\n  *)\n    lt_prog_compiler_pic_D=\"$lt_prog_compiler_pic_D\"\n    ;;\nesac\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_D\" >&5\n$as_echo \"$lt_prog_compiler_pic_D\" >&6; }\n\n\n\n#\n# Check to make sure the PIC flag actually works.\n#\nif test -n \"$lt_prog_compiler_pic_D\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_D works\" >&5\n$as_echo_n \"checking if $compiler PIC flag $lt_prog_compiler_pic_D works... \" >&6; }\nif test \"${lt_cv_prog_compiler_pic_works_D+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_pic_works_D=no\n   ac_outfile=conftest.$ac_objext\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n   lt_compiler_flag=\"$lt_prog_compiler_pic_D\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   # The option is referenced via a variable to avoid confusing sed.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s \"$ac_outfile\"; then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings other than the usual output.\n     $ECHO \"$_lt_compiler_boilerplate\" | $SED '/^$/d' >conftest.exp\n     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_pic_works_D=yes\n     fi\n   fi\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_D\" >&5\n$as_echo \"$lt_cv_prog_compiler_pic_works_D\" >&6; }\n\nif test x\"$lt_cv_prog_compiler_pic_works_D\" = xyes; then\n    case $lt_prog_compiler_pic_D in\n     \"\" | \" \"*) ;;\n     *) lt_prog_compiler_pic_D=\" $lt_prog_compiler_pic_D\" ;;\n     esac\nelse\n    lt_prog_compiler_pic_D=\n     lt_prog_compiler_can_build_shared_D=no\nfi\n\nfi\n\n\n\n#\n# Check to make sure the static flag actually works.\n#\nwl=$lt_prog_compiler_wl_D eval lt_tmp_static_flag=\\\"$lt_prog_compiler_static_D\\\"\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works\" >&5\n$as_echo_n \"checking if $compiler static flag $lt_tmp_static_flag works... \" >&6; }\nif test \"${lt_cv_prog_compiler_static_works_D+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_static_works_D=no\n   save_LDFLAGS=\"$LDFLAGS\"\n   LDFLAGS=\"$LDFLAGS $lt_tmp_static_flag\"\n   echo \"$lt_simple_link_test_code\" > conftest.$ac_ext\n   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then\n     # The linker can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     if test -s conftest.err; then\n       # Append any errors to the config.log.\n       cat conftest.err 1>&5\n       $ECHO \"$_lt_linker_boilerplate\" | $SED '/^$/d' > conftest.exp\n       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n       if diff conftest.exp conftest.er2 >/dev/null; then\n         lt_cv_prog_compiler_static_works_D=yes\n       fi\n     else\n       lt_cv_prog_compiler_static_works_D=yes\n     fi\n   fi\n   $RM -r conftest*\n   LDFLAGS=\"$save_LDFLAGS\"\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_D\" >&5\n$as_echo \"$lt_cv_prog_compiler_static_works_D\" >&6; }\n\nif test x\"$lt_cv_prog_compiler_static_works_D\" = xyes; then\n    :\nelse\n    lt_prog_compiler_static_D=\nfi\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext\" >&5\n$as_echo_n \"checking if $compiler supports -c -o file.$ac_objext... \" >&6; }\nif test \"${lt_cv_prog_compiler_c_o_D+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_c_o_D=no\n   $RM -r conftest 2>/dev/null\n   mkdir conftest\n   cd conftest\n   mkdir out\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n   lt_compiler_flag=\"-o out/conftest2.$ac_objext\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s out/conftest2.$ac_objext\n   then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     $ECHO \"$_lt_compiler_boilerplate\" | $SED '/^$/d' > out/conftest.exp\n     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2\n     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_c_o_D=yes\n     fi\n   fi\n   chmod u+w . 2>&5\n   $RM conftest*\n   # SGI C++ compiler will create directory out/ii_files/ for\n   # template instantiation\n   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files\n   $RM out/* && rmdir out\n   cd ..\n   $RM -r conftest\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_D\" >&5\n$as_echo \"$lt_cv_prog_compiler_c_o_D\" >&6; }\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext\" >&5\n$as_echo_n \"checking if $compiler supports -c -o file.$ac_objext... \" >&6; }\nif test \"${lt_cv_prog_compiler_c_o_D+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_c_o_D=no\n   $RM -r conftest 2>/dev/null\n   mkdir conftest\n   cd conftest\n   mkdir out\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n   lt_compiler_flag=\"-o out/conftest2.$ac_objext\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:$LINENO: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:$LINENO: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s out/conftest2.$ac_objext\n   then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     $ECHO \"$_lt_compiler_boilerplate\" | $SED '/^$/d' > out/conftest.exp\n     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2\n     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_c_o_D=yes\n     fi\n   fi\n   chmod u+w . 2>&5\n   $RM conftest*\n   # SGI C++ compiler will create directory out/ii_files/ for\n   # template instantiation\n   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files\n   $RM out/* && rmdir out\n   cd ..\n   $RM -r conftest\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_D\" >&5\n$as_echo \"$lt_cv_prog_compiler_c_o_D\" >&6; }\n\n\n\n\nhard_links=\"nottested\"\nif test \"$lt_cv_prog_compiler_c_o_D\" = no && test \"$need_locks\" != no; then\n  # do not overwrite the value of need_locks provided by the user\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links\" >&5\n$as_echo_n \"checking if we can lock with hard links... \" >&6; }\n  hard_links=yes\n  $RM conftest*\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  touch conftest.a\n  ln conftest.a conftest.b 2>&5 || hard_links=no\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $hard_links\" >&5\n$as_echo \"$hard_links\" >&6; }\n  if test \"$hard_links\" = no; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: \\`$CC' does not support \\`-c -o', so \\`make -j' may be unsafe\" >&5\n$as_echo \"$as_me: WARNING: \\`$CC' does not support \\`-c -o', so \\`make -j' may be unsafe\" >&2;}\n    need_locks=warn\n  fi\nelse\n  need_locks=no\nfi\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries\" >&5\n$as_echo_n \"checking whether the $compiler linker ($LD) supports shared libraries... \" >&6; }\n\n  runpath_var=\n  allow_undefined_flag_D=\n  always_export_symbols_D=no\n  archive_cmds_D=\n  archive_expsym_cmds_D=\n  compiler_needs_object_D=no\n  enable_shared_with_static_runtimes_D=no\n  export_dynamic_flag_spec_D=\n  export_symbols_cmds_D='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\\''s/.* //'\\'' | sort | uniq > $export_symbols'\n  hardcode_automatic_D=no\n  hardcode_direct_D=no\n  hardcode_direct_absolute_D=no\n  hardcode_libdir_flag_spec_D=\n  hardcode_libdir_flag_spec_ld_D=\n  hardcode_libdir_separator_D=\n  hardcode_minus_L_D=no\n  hardcode_shlibpath_var_D=unsupported\n  inherit_rpath_D=no\n  link_all_deplibs_D=unknown\n  module_cmds_D=\n  module_expsym_cmds_D=\n  old_archive_from_new_cmds_D=\n  old_archive_from_expsyms_cmds_D=\n  thread_safe_flag_spec_D=\n  whole_archive_flag_spec_D=\n  # include_expsyms should be a list of space-separated symbols to be *always*\n  # included in the symbol list\n  include_expsyms_D=\n  # exclude_expsyms can be an extended regexp of symbols to exclude\n  # it will be wrapped by ` (' and `)$', so one must not match beginning or\n  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',\n  # as well as any symbol that contains `d'.\n  exclude_expsyms_D='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'\n  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out\n  # platforms (ab)use it in PIC code, but their linkers get confused if\n  # the symbol is explicitly referenced.  Since portable code cannot\n  # rely on this symbol name, it's probably fine to never include it in\n  # preloaded symbol tables.\n  # Exclude shared library initialization/finalization symbols.\n  extract_expsyms_cmds=\n\n  case $host_os in\n  cygwin* | mingw* | pw32* | cegcc*)\n    # FIXME: the MSVC++ port hasn't been tested in a loooong time\n    # When not using gcc, we currently assume that we are using\n    # Microsoft Visual C++.\n    if test \"$GCC\" != yes; then\n      with_gnu_ld=no\n    fi\n    ;;\n  interix*)\n    # we just hope/assume this is gcc and not c89 (= MSVC++)\n    with_gnu_ld=yes\n    ;;\n  openbsd*)\n    with_gnu_ld=no\n    ;;\n  esac\n\n  ld_shlibs_D=yes\n\n  # On some targets, GNU ld is compatible enough with the native linker\n  # that we're better off using the native interface for both.\n  lt_use_gnu_ld_interface=no\n  if test \"$with_gnu_ld\" = yes; then\n    case $host_os in\n      aix*)\n\t# The AIX port of GNU ld has always aspired to compatibility\n\t# with the native linker.  However, as the warning in the GNU ld\n\t# block says, versions before 2.19.5* couldn't really create working\n\t# shared libraries, regardless of the interface used.\n\tcase `$LD -v 2>&1` in\n\t  *\\ \\(GNU\\ Binutils\\)\\ 2.19.5*) ;;\n\t  *\\ \\(GNU\\ Binutils\\)\\ 2.[2-9]*) ;;\n\t  *\\ \\(GNU\\ Binutils\\)\\ [3-9]*) ;;\n\t  *)\n\t    lt_use_gnu_ld_interface=yes\n\t    ;;\n\tesac\n\t;;\n      *)\n\tlt_use_gnu_ld_interface=yes\n\t;;\n    esac\n  fi\n\n  if test \"$lt_use_gnu_ld_interface\" = yes; then\n    # If archive_cmds runs LD, not CC, wlarc should be empty\n    wlarc='${wl}'\n\n    # Set some defaults for GNU ld with shared library support. These\n    # are reset later if shared libraries are not supported. Putting them\n    # here allows them to be overridden if necessary.\n    runpath_var=LD_RUN_PATH\n    hardcode_libdir_flag_spec_D='${wl}-rpath ${wl}$libdir'\n    export_dynamic_flag_spec_D='${wl}--export-dynamic'\n    # ancient GNU ld didn't support --whole-archive et. al.\n    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then\n      whole_archive_flag_spec_D=\"$wlarc\"'--whole-archive$convenience '\"$wlarc\"'--no-whole-archive'\n    else\n      whole_archive_flag_spec_D=\n    fi\n    supports_anon_versioning=no\n    case `$LD -v 2>&1` in\n      *GNU\\ gold*) supports_anon_versioning=yes ;;\n      *\\ [01].* | *\\ 2.[0-9].* | *\\ 2.10.*) ;; # catch versions < 2.11\n      *\\ 2.11.93.0.2\\ *) supports_anon_versioning=yes ;; # RH7.3 ...\n      *\\ 2.11.92.0.12\\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...\n      *\\ 2.11.*) ;; # other 2.11 versions\n      *) supports_anon_versioning=yes ;;\n    esac\n\n    # See if GNU ld supports shared libraries.\n    case $host_os in\n    aix[3-9]*)\n      # On AIX/PPC, the GNU linker is very broken\n      if test \"$host_cpu\" != ia64; then\n\tld_shlibs_D=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: the GNU linker, at least up to release 2.19, is reported\n*** to be unable to reliably create shared libraries on AIX.\n*** Therefore, libtool is disabling shared libraries support.  If you\n*** really care for shared libraries, you may want to install binutils\n*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.\n*** You will then need to restart the configuration process.\n\n_LT_EOF\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            archive_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n            archive_expsym_cmds_D=''\n        ;;\n      m68k)\n            archive_cmds_D='$RM $output_objdir/a2ixlibrary.data~$ECHO \"#define NAME $libname\" > $output_objdir/a2ixlibrary.data~$ECHO \"#define LIBRARY_ID 1\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define VERSION $major\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define REVISION $revision\" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'\n            hardcode_libdir_flag_spec_D='-L$libdir'\n            hardcode_minus_L_D=yes\n        ;;\n      esac\n      ;;\n\n    beos*)\n      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\tallow_undefined_flag_D=unsupported\n\t# Joseph Beckenbach <jrb3@best.com> says some releases of gcc\n\t# support --undefined.  This deserves some investigation.  FIXME\n\tarchive_cmds_D='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n      else\n\tld_shlibs_D=no\n      fi\n      ;;\n\n    cygwin* | mingw* | pw32* | cegcc*)\n      # _LT_TAGVAR(hardcode_libdir_flag_spec, D) is actually meaningless,\n      # as there is no search path for DLLs.\n      hardcode_libdir_flag_spec_D='-L$libdir'\n      export_dynamic_flag_spec_D='${wl}--export-all-symbols'\n      allow_undefined_flag_D=unsupported\n      always_export_symbols_D=no\n      enable_shared_with_static_runtimes_D=yes\n      export_symbols_cmds_D='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[BCDGRS][ ]/s/.*[ ]\\([^ ]*\\)/\\1 DATA/'\\'' | $SED -e '\\''/^[AITW][ ]/s/.*[ ]//'\\'' | sort | uniq > $export_symbols'\n\n      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then\n        archive_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n\t# If the export-symbols file already is a .def file (1st line\n\t# is EXPORTS), use it as is; otherwise, prepend...\n\tarchive_expsym_cmds_D='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t  cp $export_symbols $output_objdir/$soname.def;\n\telse\n\t  echo EXPORTS > $output_objdir/$soname.def;\n\t  cat $export_symbols >> $output_objdir/$soname.def;\n\tfi~\n\t$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n      else\n\tld_shlibs_D=no\n      fi\n      ;;\n\n    haiku*)\n      archive_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n      link_all_deplibs_D=yes\n      ;;\n\n    interix[3-9]*)\n      hardcode_direct_D=no\n      hardcode_shlibpath_var_D=no\n      hardcode_libdir_flag_spec_D='${wl}-rpath,$libdir'\n      export_dynamic_flag_spec_D='${wl}-E'\n      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.\n      # Instead, shared libraries are loaded at an image base (0x10000000 by\n      # default) and relocated if they conflict, which is a slow very memory\n      # consuming and fragmenting process.  To avoid this, we pick a random,\n      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link\n      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.\n      archive_cmds_D='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n      archive_expsym_cmds_D='sed \"s,^,_,\" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n      ;;\n\n    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)\n      tmp_diet=no\n      if test \"$host_os\" = linux-dietlibc; then\n\tcase $cc_basename in\n\t  diet\\ *) tmp_diet=yes;;\t# linux-dietlibc with static linking (!diet-dyn)\n\tesac\n      fi\n      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \\\n\t && test \"$tmp_diet\" = no\n      then\n\ttmp_addflag=' $pic_flag'\n\ttmp_sharedflag='-shared'\n\tcase $cc_basename,$host_cpu in\n        pgcc*)\t\t\t\t# Portland Group C compiler\n\t  whole_archive_flag_spec_D='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag'\n\t  ;;\n\tpgf77* | pgf90* | pgf95* | pgfortran*)\n\t\t\t\t\t# Portland Group f77 and f90 compilers\n\t  whole_archive_flag_spec_D='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag -Mnomain' ;;\n\tecc*,ia64* | icc*,ia64*)\t# Intel C compiler on ia64\n\t  tmp_addflag=' -i_dynamic' ;;\n\tefc*,ia64* | ifort*,ia64*)\t# Intel Fortran compiler on ia64\n\t  tmp_addflag=' -i_dynamic -nofor_main' ;;\n\tifc* | ifort*)\t\t\t# Intel Fortran compiler\n\t  tmp_addflag=' -nofor_main' ;;\n\tlf95*)\t\t\t\t# Lahey Fortran 8.1\n\t  whole_archive_flag_spec_D=\n\t  tmp_sharedflag='--shared' ;;\n\txl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)\n\t  tmp_sharedflag='-qmkshrobj'\n\t  tmp_addflag= ;;\n\tnvcc*)\t# Cuda Compiler Driver 2.2\n\t  whole_archive_flag_spec_D='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  compiler_needs_object_D=yes\n\t  ;;\n\tesac\n\tcase `$CC -V 2>&1 | sed 5q` in\n\t*Sun\\ C*)\t\t\t# Sun C 5.9\n\t  whole_archive_flag_spec_D='${wl}--whole-archive`new_convenience=; for conv in $convenience\\\"\\\"; do test -z \\\"$conv\\\" || new_convenience=\\\"$new_convenience,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  compiler_needs_object_D=yes\n\t  tmp_sharedflag='-G' ;;\n\t*Sun\\ F*)\t\t\t# Sun Fortran 8.3\n\t  tmp_sharedflag='-G' ;;\n\tesac\n\tarchive_cmds_D='$CC '\"$tmp_sharedflag\"\"$tmp_addflag\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\n        if test \"x$supports_anon_versioning\" = xyes; then\n          archive_expsym_cmds_D='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t    cat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t    echo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t    $CC '\"$tmp_sharedflag\"\"$tmp_addflag\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'\n        fi\n\n\tcase $cc_basename in\n\txlf* | bgf* | bgxlf* | mpixlf*)\n\t  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself\n\t  whole_archive_flag_spec_D='--whole-archive$convenience --no-whole-archive'\n\t  hardcode_libdir_flag_spec_D=\n\t  hardcode_libdir_flag_spec_ld_D='-rpath $libdir'\n\t  archive_cmds_D='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'\n\t  if test \"x$supports_anon_versioning\" = xyes; then\n\t    archive_expsym_cmds_D='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t      cat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t      echo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'\n\t  fi\n\t  ;;\n\tesac\n      else\n        ld_shlibs_D=no\n      fi\n      ;;\n\n    netbsd*)\n      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\tarchive_cmds_D='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'\n\twlarc=\n      else\n\tarchive_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      fi\n      ;;\n\n    solaris*)\n      if $LD -v 2>&1 | $GREP 'BFD 2\\.8' > /dev/null; then\n\tld_shlibs_D=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: The releases 2.8.* of the GNU linker cannot reliably\n*** create shared libraries on Solaris systems.  Therefore, libtool\n*** is disabling shared libraries support.  We urge you to upgrade GNU\n*** binutils to release 2.9.1 or newer.  Another option is to modify\n*** your PATH or compiler configuration so that the native linker is\n*** used, and then restart.\n\n_LT_EOF\n      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\tarchive_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      else\n\tld_shlibs_D=no\n      fi\n      ;;\n\n    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)\n      case `$LD -v 2>&1` in\n        *\\ [01].* | *\\ 2.[0-9].* | *\\ 2.1[0-5].*)\n\tld_shlibs_D=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not\n*** reliably create shared libraries on SCO systems.  Therefore, libtool\n*** is disabling shared libraries support.  We urge you to upgrade GNU\n*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify\n*** your PATH or compiler configuration so that the native linker is\n*** used, and then restart.\n\n_LT_EOF\n\t;;\n\t*)\n\t  # For security reasons, it is highly recommended that you always\n\t  # use absolute paths for naming shared libraries, and exclude the\n\t  # DT_RUNPATH tag from executables and libraries.  But doing so\n\t  # requires that you compile everything twice, which is a pain.\n\t  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t    hardcode_libdir_flag_spec_D='${wl}-rpath ${wl}$libdir'\n\t    archive_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t    archive_expsym_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\t  else\n\t    ld_shlibs_D=no\n\t  fi\n\t;;\n      esac\n      ;;\n\n    sunos4*)\n      archive_cmds_D='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n      wlarc=\n      hardcode_direct_D=yes\n      hardcode_shlibpath_var_D=no\n      ;;\n\n    *)\n      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\tarchive_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      else\n\tld_shlibs_D=no\n      fi\n      ;;\n    esac\n\n    if test \"$ld_shlibs_D\" = no; then\n      runpath_var=\n      hardcode_libdir_flag_spec_D=\n      export_dynamic_flag_spec_D=\n      whole_archive_flag_spec_D=\n    fi\n  else\n    # PORTME fill in a description of your system's linker (not GNU ld)\n    case $host_os in\n    aix3*)\n      allow_undefined_flag_D=unsupported\n      always_export_symbols_D=yes\n      archive_expsym_cmds_D='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'\n      # Note: this linker hardcodes the directories in LIBPATH if there\n      # are no directories specified by -L.\n      hardcode_minus_L_D=yes\n      if test \"$GCC\" = yes && test -z \"$lt_prog_compiler_static\"; then\n\t# Neither direct hardcoding nor static linking is supported with a\n\t# broken collect2.\n\thardcode_direct_D=unsupported\n      fi\n      ;;\n\n    aix[4-9]*)\n      if test \"$host_cpu\" = ia64; then\n\t# On IA64, the linker does run time linking by default, so we don't\n\t# have to do anything special.\n\taix_use_runtimelinking=no\n\texp_sym_flag='-Bexport'\n\tno_entry_flag=\"\"\n      else\n\t# If we're using GNU nm, then we don't want the \"-C\" option.\n\t# -C means demangle to AIX nm, but means don't demangle with GNU nm\n\t# Also, AIX nm treats weak defined symbols like other global\n\t# defined symbols, whereas GNU nm marks them as \"W\".\n\tif $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then\n\t  export_symbols_cmds_D='$NM -Bpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\") || (\\$ 2 == \"W\")) && (substr(\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n\telse\n\t  export_symbols_cmds_D='$NM -BCpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\") || (\\$ 2 == \"L\")) && (substr(\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n\tfi\n\taix_use_runtimelinking=no\n\n\t# Test if we are trying to use run time linking or normal\n\t# AIX style linking. If -brtl is somewhere in LDFLAGS, we\n\t# need to do runtime linking.\n\tcase $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)\n\t  for ld_flag in $LDFLAGS; do\n\t  if (test $ld_flag = \"-brtl\" || test $ld_flag = \"-Wl,-brtl\"); then\n\t    aix_use_runtimelinking=yes\n\t    break\n\t  fi\n\t  done\n\t  ;;\n\tesac\n\n\texp_sym_flag='-bexport'\n\tno_entry_flag='-bnoentry'\n      fi\n\n      # When large executables or shared objects are built, AIX ld can\n      # have problems creating the table of contents.  If linking a library\n      # or program results in \"error TOC overflow\" add -mminimal-toc to\n      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not\n      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.\n\n      archive_cmds_D=''\n      hardcode_direct_D=yes\n      hardcode_direct_absolute_D=yes\n      hardcode_libdir_separator_D=':'\n      link_all_deplibs_D=yes\n      file_list_spec_D='${wl}-f,'\n\n      if test \"$GCC\" = yes; then\n\tcase $host_os in aix4.[012]|aix4.[012].*)\n\t# We only want to do this on AIX 4.2 and lower, the check\n\t# below for broken collect2 doesn't work under 4.3+\n\t  collect2name=`${CC} -print-prog-name=collect2`\n\t  if test -f \"$collect2name\" &&\n\t   strings \"$collect2name\" | $GREP resolve_lib_name >/dev/null\n\t  then\n\t  # We have reworked collect2\n\t  :\n\t  else\n\t  # We have old collect2\n\t  hardcode_direct_D=unsupported\n\t  # It fails to find uninstalled libraries when the uninstalled\n\t  # path is not listed in the libpath.  Setting hardcode_minus_L\n\t  # to unsupported forces relinking\n\t  hardcode_minus_L_D=yes\n\t  hardcode_libdir_flag_spec_D='-L$libdir'\n\t  hardcode_libdir_separator_D=\n\t  fi\n\t  ;;\n\tesac\n\tshared_flag='-shared'\n\tif test \"$aix_use_runtimelinking\" = yes; then\n\t  shared_flag=\"$shared_flag \"'${wl}-G'\n\tfi\n      else\n\t# not using gcc\n\tif test \"$host_cpu\" = ia64; then\n\t# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release\n\t# chokes on -Wl,-G. The following line is correct:\n\t  shared_flag='-G'\n\telse\n\t  if test \"$aix_use_runtimelinking\" = yes; then\n\t    shared_flag='${wl}-G'\n\t  else\n\t    shared_flag='${wl}-bM:SRE'\n\t  fi\n\tfi\n      fi\n\n      export_dynamic_flag_spec_D='${wl}-bexpall'\n      # It seems that -bexpall does not export symbols beginning with\n      # underscore (_), so it is better to generate a list of symbols to export.\n      always_export_symbols_D=yes\n      if test \"$aix_use_runtimelinking\" = yes; then\n\t# Warning - without using the other runtime loading flags (-brtl),\n\t# -berok will link without error, but may produce a broken library.\n\tallow_undefined_flag_D='-berok'\n        # Determine the default libpath from the value encoded in an\n        # empty executable.\n        cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n\nlt_aix_libpath_sed='\n    /Import File Strings/,/^$/ {\n\t/^0/ {\n\t    s/^0  *\\(.*\\)$/\\1/\n\t    p\n\t}\n    }'\naix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n# Check for a 64-bit object if we didn't find anything.\nif test -z \"$aix_libpath\"; then\n  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\nfi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nif test -z \"$aix_libpath\"; then aix_libpath=\"/usr/lib:/lib\"; fi\n\n        hardcode_libdir_flag_spec_D='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n        archive_expsym_cmds_D='$CC -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags `if test \"x${allow_undefined_flag}\" != \"x\"; then func_echo_all \"${wl}${allow_undefined_flag}\"; else :; fi` '\"\\${wl}$exp_sym_flag:\\$export_symbols $shared_flag\"\n      else\n\tif test \"$host_cpu\" = ia64; then\n\t  hardcode_libdir_flag_spec_D='${wl}-R $libdir:/usr/lib:/lib'\n\t  allow_undefined_flag_D=\"-z nodefs\"\n\t  archive_expsym_cmds_D=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags ${wl}${allow_undefined_flag} '\"\\${wl}$exp_sym_flag:\\$export_symbols\"\n\telse\n\t # Determine the default libpath from the value encoded in an\n\t # empty executable.\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n\nlt_aix_libpath_sed='\n    /Import File Strings/,/^$/ {\n\t/^0/ {\n\t    s/^0  *\\(.*\\)$/\\1/\n\t    p\n\t}\n    }'\naix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n# Check for a 64-bit object if we didn't find anything.\nif test -z \"$aix_libpath\"; then\n  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\nfi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nif test -z \"$aix_libpath\"; then aix_libpath=\"/usr/lib:/lib\"; fi\n\n\t hardcode_libdir_flag_spec_D='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n\t  # Warning - without using the other run time loading flags,\n\t  # -berok will link without error, but may produce a broken library.\n\t  no_undefined_flag_D=' ${wl}-bernotok'\n\t  allow_undefined_flag_D=' ${wl}-berok'\n\t  if test \"$with_gnu_ld\" = yes; then\n\t    # We only use this code for GNU lds that support --whole-archive.\n\t    whole_archive_flag_spec_D='${wl}--whole-archive$convenience ${wl}--no-whole-archive'\n\t  else\n\t    # Exported symbols can be pulled into shared objects from archives\n\t    whole_archive_flag_spec_D='$convenience'\n\t  fi\n\t  archive_cmds_need_lc_D=yes\n\t  # This is similar to how AIX traditionally builds its shared libraries.\n\t  archive_expsym_cmds_D=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'\n\tfi\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            archive_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n            archive_expsym_cmds_D=''\n        ;;\n      m68k)\n            archive_cmds_D='$RM $output_objdir/a2ixlibrary.data~$ECHO \"#define NAME $libname\" > $output_objdir/a2ixlibrary.data~$ECHO \"#define LIBRARY_ID 1\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define VERSION $major\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define REVISION $revision\" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'\n            hardcode_libdir_flag_spec_D='-L$libdir'\n            hardcode_minus_L_D=yes\n        ;;\n      esac\n      ;;\n\n    bsdi[45]*)\n      export_dynamic_flag_spec_D=-rdynamic\n      ;;\n\n    cygwin* | mingw* | pw32* | cegcc*)\n      # When not using gcc, we currently assume that we are using\n      # Microsoft Visual C++.\n      # hardcode_libdir_flag_spec is actually meaningless, as there is\n      # no search path for DLLs.\n      hardcode_libdir_flag_spec_D=' '\n      allow_undefined_flag_D=unsupported\n      # Tell ltmain to make .lib files, not .a files.\n      libext=lib\n      # Tell ltmain to make .dll files, not .so files.\n      shrext_cmds=\".dll\"\n      # FIXME: Setting linknames here is a bad hack.\n      archive_cmds_D='$CC -o $lib $libobjs $compiler_flags `func_echo_all \"$deplibs\" | $SED '\\''s/ -lc$//'\\''` -link -dll~linknames='\n      # The linker will automatically build a .lib file if we build a DLL.\n      old_archive_from_new_cmds_D='true'\n      # FIXME: Should let the user specify the lib program.\n      old_archive_cmds_D='lib -OUT:$oldlib$oldobjs$old_deplibs'\n      fix_srcfile_path_D='`cygpath -w \"$srcfile\"`'\n      enable_shared_with_static_runtimes_D=yes\n      ;;\n\n    darwin* | rhapsody*)\n\n\n  archive_cmds_need_lc_D=no\n  hardcode_direct_D=no\n  hardcode_automatic_D=yes\n  hardcode_shlibpath_var_D=unsupported\n  if test \"$lt_cv_ld_force_load\" = \"yes\"; then\n    whole_archive_flag_spec_D='`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience ${wl}-force_load,$conv\\\"; done; func_echo_all \\\"$new_convenience\\\"`'\n  else\n    whole_archive_flag_spec_D=''\n  fi\n  link_all_deplibs_D=yes\n  allow_undefined_flag_D=\"$_lt_dar_allow_undefined\"\n  case $cc_basename in\n     ifort*) _lt_dar_can_shared=yes ;;\n     *) _lt_dar_can_shared=$GCC ;;\n  esac\n  if test \"$_lt_dar_can_shared\" = \"yes\"; then\n    output_verbose_link_cmd=func_echo_all\n    archive_cmds_D=\"\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring $_lt_dar_single_mod${_lt_dsymutil}\"\n    module_cmds_D=\"\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dsymutil}\"\n    archive_expsym_cmds_D=\"sed 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}\"\n    module_expsym_cmds_D=\"sed -e 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}\"\n\n  else\n  ld_shlibs_D=no\n  fi\n\n      ;;\n\n    dgux*)\n      archive_cmds_D='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_libdir_flag_spec_D='-L$libdir'\n      hardcode_shlibpath_var_D=no\n      ;;\n\n    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor\n    # support.  Future versions do this automatically, but an explicit c++rt0.o\n    # does not break anything, and helps significantly (at the cost of a little\n    # extra space).\n    freebsd2.2*)\n      archive_cmds_D='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'\n      hardcode_libdir_flag_spec_D='-R$libdir'\n      hardcode_direct_D=yes\n      hardcode_shlibpath_var_D=no\n      ;;\n\n    # Unfortunately, older versions of FreeBSD 2 do not have this feature.\n    freebsd2.*)\n      archive_cmds_D='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_direct_D=yes\n      hardcode_minus_L_D=yes\n      hardcode_shlibpath_var_D=no\n      ;;\n\n    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.\n    freebsd* | dragonfly*)\n      archive_cmds_D='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'\n      hardcode_libdir_flag_spec_D='-R$libdir'\n      hardcode_direct_D=yes\n      hardcode_shlibpath_var_D=no\n      ;;\n\n    hpux9*)\n      if test \"$GCC\" = yes; then\n\tarchive_cmds_D='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n      else\n\tarchive_cmds_D='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n      fi\n      hardcode_libdir_flag_spec_D='${wl}+b ${wl}$libdir'\n      hardcode_libdir_separator_D=:\n      hardcode_direct_D=yes\n\n      # hardcode_minus_L: Not really in the search PATH,\n      # but as the default location of the library.\n      hardcode_minus_L_D=yes\n      export_dynamic_flag_spec_D='${wl}-E'\n      ;;\n\n    hpux10*)\n      if test \"$GCC\" = yes && test \"$with_gnu_ld\" = no; then\n\tarchive_cmds_D='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds_D='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'\n      fi\n      if test \"$with_gnu_ld\" = no; then\n\thardcode_libdir_flag_spec_D='${wl}+b ${wl}$libdir'\n\thardcode_libdir_flag_spec_ld_D='+b $libdir'\n\thardcode_libdir_separator_D=:\n\thardcode_direct_D=yes\n\thardcode_direct_absolute_D=yes\n\texport_dynamic_flag_spec_D='${wl}-E'\n\t# hardcode_minus_L: Not really in the search PATH,\n\t# but as the default location of the library.\n\thardcode_minus_L_D=yes\n      fi\n      ;;\n\n    hpux11*)\n      if test \"$GCC\" = yes && test \"$with_gnu_ld\" = no; then\n\tcase $host_cpu in\n\thppa*64*)\n\t  archive_cmds_D='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tia64*)\n\t  archive_cmds_D='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\t  archive_cmds_D='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tesac\n      else\n\tcase $host_cpu in\n\thppa*64*)\n\t  archive_cmds_D='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tia64*)\n\t  archive_cmds_D='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\tarchive_cmds_D='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tesac\n      fi\n      if test \"$with_gnu_ld\" = no; then\n\thardcode_libdir_flag_spec_D='${wl}+b ${wl}$libdir'\n\thardcode_libdir_separator_D=:\n\n\tcase $host_cpu in\n\thppa*64*|ia64*)\n\t  hardcode_direct_D=no\n\t  hardcode_shlibpath_var_D=no\n\t  ;;\n\t*)\n\t  hardcode_direct_D=yes\n\t  hardcode_direct_absolute_D=yes\n\t  export_dynamic_flag_spec_D='${wl}-E'\n\n\t  # hardcode_minus_L: Not really in the search PATH,\n\t  # but as the default location of the library.\n\t  hardcode_minus_L_D=yes\n\t  ;;\n\tesac\n      fi\n      ;;\n\n    irix5* | irix6* | nonstopux*)\n      if test \"$GCC\" = yes; then\n\tarchive_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t# Try to use the -exported_symbol ld option, if it does not\n\t# work, assume that -exports_file does not work either and\n\t# implicitly export all symbols.\n        save_LDFLAGS=\"$LDFLAGS\"\n        LDFLAGS=\"$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null\"\n        cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\nint foo(void) {}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  archive_expsym_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'\n\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n        LDFLAGS=\"$save_LDFLAGS\"\n      else\n\tarchive_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n\tarchive_expsym_cmds_D='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'\n      fi\n      archive_cmds_need_lc_D='no'\n      hardcode_libdir_flag_spec_D='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator_D=:\n      inherit_rpath_D=yes\n      link_all_deplibs_D=yes\n      ;;\n\n    netbsd*)\n      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\tarchive_cmds_D='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out\n      else\n\tarchive_cmds_D='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF\n      fi\n      hardcode_libdir_flag_spec_D='-R$libdir'\n      hardcode_direct_D=yes\n      hardcode_shlibpath_var_D=no\n      ;;\n\n    newsos6)\n      archive_cmds_D='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_direct_D=yes\n      hardcode_libdir_flag_spec_D='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator_D=:\n      hardcode_shlibpath_var_D=no\n      ;;\n\n    *nto* | *qnx*)\n      ;;\n\n    openbsd*)\n      if test -f /usr/libexec/ld.so; then\n\thardcode_direct_D=yes\n\thardcode_shlibpath_var_D=no\n\thardcode_direct_absolute_D=yes\n\tif test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n\t  archive_cmds_D='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'\n\t  archive_expsym_cmds_D='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'\n\t  hardcode_libdir_flag_spec_D='${wl}-rpath,$libdir'\n\t  export_dynamic_flag_spec_D='${wl}-E'\n\telse\n\t  case $host_os in\n\t   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)\n\t     archive_cmds_D='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n\t     hardcode_libdir_flag_spec_D='-R$libdir'\n\t     ;;\n\t   *)\n\t     archive_cmds_D='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'\n\t     hardcode_libdir_flag_spec_D='${wl}-rpath,$libdir'\n\t     ;;\n\t  esac\n\tfi\n      else\n\tld_shlibs_D=no\n      fi\n      ;;\n\n    os2*)\n      hardcode_libdir_flag_spec_D='-L$libdir'\n      hardcode_minus_L_D=yes\n      allow_undefined_flag_D=unsupported\n      archive_cmds_D='$ECHO \"LIBRARY $libname INITINSTANCE\" > $output_objdir/$libname.def~$ECHO \"DESCRIPTION \\\"$libname\\\"\" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo \" SINGLE NONSHARED\" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'\n      old_archive_from_new_cmds_D='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'\n      ;;\n\n    osf3*)\n      if test \"$GCC\" = yes; then\n\tallow_undefined_flag_D=' ${wl}-expect_unresolved ${wl}\\*'\n\tarchive_cmds_D='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n      else\n\tallow_undefined_flag_D=' -expect_unresolved \\*'\n\tarchive_cmds_D='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n      fi\n      archive_cmds_need_lc_D='no'\n      hardcode_libdir_flag_spec_D='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator_D=:\n      ;;\n\n    osf4* | osf5*)\t# as osf3* with the addition of -msym flag\n      if test \"$GCC\" = yes; then\n\tallow_undefined_flag_D=' ${wl}-expect_unresolved ${wl}\\*'\n\tarchive_cmds_D='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && func_echo_all \"${wl}-set_version ${wl}$verstring\"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\thardcode_libdir_flag_spec_D='${wl}-rpath ${wl}$libdir'\n      else\n\tallow_undefined_flag_D=' -expect_unresolved \\*'\n\tarchive_cmds_D='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n \"$verstring\" && func_echo_all \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib'\n\tarchive_expsym_cmds_D='for i in `cat $export_symbols`; do printf \"%s %s\\\\n\" -exported_symbol \"\\$i\" >> $lib.exp; done; printf \"%s\\\\n\" \"-hidden\">> $lib.exp~\n\t$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n \"$verstring\" && $ECHO \"-set_version $verstring\"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'\n\n\t# Both c and cxx compiler support -rpath directly\n\thardcode_libdir_flag_spec_D='-rpath $libdir'\n      fi\n      archive_cmds_need_lc_D='no'\n      hardcode_libdir_separator_D=:\n      ;;\n\n    solaris*)\n      no_undefined_flag_D=' -z defs'\n      if test \"$GCC\" = yes; then\n\twlarc='${wl}'\n\tarchive_cmds_D='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds_D='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'\n      else\n\tcase `$CC -V 2>&1` in\n\t*\"Compilers 5.0\"*)\n\t  wlarc=''\n\t  archive_cmds_D='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  archive_expsym_cmds_D='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'\n\t  ;;\n\t*)\n\t  wlarc='${wl}'\n\t  archive_cmds_D='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  archive_expsym_cmds_D='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'\n\t  ;;\n\tesac\n      fi\n      hardcode_libdir_flag_spec_D='-R$libdir'\n      hardcode_shlibpath_var_D=no\n      case $host_os in\n      solaris2.[0-5] | solaris2.[0-5].*) ;;\n      *)\n\t# The compiler driver will combine and reorder linker options,\n\t# but understands `-z linker_flag'.  GCC discards it without `$wl',\n\t# but is careful enough not to reorder.\n\t# Supported since Solaris 2.6 (maybe 2.5.1?)\n\tif test \"$GCC\" = yes; then\n\t  whole_archive_flag_spec_D='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'\n\telse\n\t  whole_archive_flag_spec_D='-z allextract$convenience -z defaultextract'\n\tfi\n\t;;\n      esac\n      link_all_deplibs_D=yes\n      ;;\n\n    sunos4*)\n      if test \"x$host_vendor\" = xsequent; then\n\t# Use $CC to link under sequent, because it throws in some extra .o\n\t# files that make .init and .fini sections work.\n\tarchive_cmds_D='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds_D='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'\n      fi\n      hardcode_libdir_flag_spec_D='-L$libdir'\n      hardcode_direct_D=yes\n      hardcode_minus_L_D=yes\n      hardcode_shlibpath_var_D=no\n      ;;\n\n    sysv4)\n      case $host_vendor in\n\tsni)\n\t  archive_cmds_D='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  hardcode_direct_D=yes # is this really true???\n\t;;\n\tsiemens)\n\t  ## LD is ld it makes a PLAMLIB\n\t  ## CC just makes a GrossModule.\n\t  archive_cmds_D='$LD -G -o $lib $libobjs $deplibs $linker_flags'\n\t  reload_cmds_D='$CC -r -o $output$reload_objs'\n\t  hardcode_direct_D=no\n        ;;\n\tmotorola)\n\t  archive_cmds_D='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  hardcode_direct_D=no #Motorola manual says yes, but my tests say they lie\n\t;;\n      esac\n      runpath_var='LD_RUN_PATH'\n      hardcode_shlibpath_var_D=no\n      ;;\n\n    sysv4.3*)\n      archive_cmds_D='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_shlibpath_var_D=no\n      export_dynamic_flag_spec_D='-Bexport'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\tarchive_cmds_D='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\thardcode_shlibpath_var_D=no\n\trunpath_var=LD_RUN_PATH\n\thardcode_runpath_var=yes\n\tld_shlibs_D=yes\n      fi\n      ;;\n\n    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)\n      no_undefined_flag_D='${wl}-z,text'\n      archive_cmds_need_lc_D=no\n      hardcode_shlibpath_var_D=no\n      runpath_var='LD_RUN_PATH'\n\n      if test \"$GCC\" = yes; then\n\tarchive_cmds_D='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds_D='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds_D='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds_D='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      fi\n      ;;\n\n    sysv5* | sco3.2v5* | sco5v6*)\n      # Note: We can NOT use -z defs as we might desire, because we do not\n      # link with -lc, and that would cause any symbols used from libc to\n      # always be unresolved, which means just about no library would\n      # ever link correctly.  If we're not using GNU ld we use -z text\n      # though, which does catch some bad symbols but isn't as heavy-handed\n      # as -z defs.\n      no_undefined_flag_D='${wl}-z,text'\n      allow_undefined_flag_D='${wl}-z,nodefs'\n      archive_cmds_need_lc_D=no\n      hardcode_shlibpath_var_D=no\n      hardcode_libdir_flag_spec_D='${wl}-R,$libdir'\n      hardcode_libdir_separator_D=':'\n      link_all_deplibs_D=yes\n      export_dynamic_flag_spec_D='${wl}-Bexport'\n      runpath_var='LD_RUN_PATH'\n\n      if test \"$GCC\" = yes; then\n\tarchive_cmds_D='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds_D='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds_D='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds_D='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      fi\n      ;;\n\n    uts4*)\n      archive_cmds_D='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_libdir_flag_spec_D='-L$libdir'\n      hardcode_shlibpath_var_D=no\n      ;;\n\n    *)\n      ld_shlibs_D=no\n      ;;\n    esac\n\n    if test x$host_vendor = xsni; then\n      case $host in\n      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)\n\texport_dynamic_flag_spec_D='${wl}-Blargedynsym'\n\t;;\n      esac\n    fi\n  fi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_D\" >&5\n$as_echo \"$ld_shlibs_D\" >&6; }\ntest \"$ld_shlibs_D\" = no && can_build_shared=no\n\nwith_gnu_ld_D=$with_gnu_ld\n\n\n\n\n\n\n#\n# Do we need to explicitly link libc?\n#\ncase \"x$archive_cmds_need_lc_D\" in\nx|xyes)\n  # Assume -lc should be added\n  archive_cmds_need_lc_D=yes\n\n  if test \"$enable_shared\" = yes && test \"$GCC\" = yes; then\n    case $archive_cmds_D in\n    *'~'*)\n      # FIXME: we may have to deal with multi-command sequences.\n      ;;\n    '$CC '*)\n      # Test whether the compiler implicitly links with -lc since on some\n      # systems, -lgcc has to come before -lc. If gcc already passes -lc\n      # to ld, don't add -lc before -lgcc.\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in\" >&5\n$as_echo_n \"checking whether -lc should be explicitly linked in... \" >&6; }\nif test \"${lt_cv_archive_cmds_need_lc_D+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  $RM conftest*\n\techo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n\tif { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } 2>conftest.err; then\n\t  soname=conftest\n\t  lib=conftest\n\t  libobjs=conftest.$ac_objext\n\t  deplibs=\n\t  wl=$lt_prog_compiler_wl_D\n\t  pic_flag=$lt_prog_compiler_pic_D\n\t  compiler_flags=-v\n\t  linker_flags=-v\n\t  verstring=\n\t  output_objdir=.\n\t  libname=conftest\n\t  lt_save_allow_undefined_flag=$allow_undefined_flag_D\n\t  allow_undefined_flag_D=\n\t  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$archive_cmds_D 2\\>\\&1 \\| $GREP \\\" -lc \\\" \\>/dev/null 2\\>\\&1\\\"\"; } >&5\n  (eval $archive_cmds_D 2\\>\\&1 \\| $GREP \\\" -lc \\\" \\>/dev/null 2\\>\\&1) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\n\t  then\n\t    lt_cv_archive_cmds_need_lc_D=no\n\t  else\n\t    lt_cv_archive_cmds_need_lc_D=yes\n\t  fi\n\t  allow_undefined_flag_D=$lt_save_allow_undefined_flag\n\telse\n\t  cat conftest.err 1>&5\n\tfi\n\t$RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_D\" >&5\n$as_echo \"$lt_cv_archive_cmds_need_lc_D\" >&6; }\n      archive_cmds_need_lc_D=$lt_cv_archive_cmds_need_lc_D\n      ;;\n    esac\n  fi\n  ;;\nesac\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs\" >&5\n$as_echo_n \"checking how to hardcode library paths into programs... \" >&6; }\nhardcode_action_D=\nif test -n \"$hardcode_libdir_flag_spec_D\" ||\n   test -n \"$runpath_var_D\" ||\n   test \"X$hardcode_automatic_D\" = \"Xyes\" ; then\n\n  # We can hardcode non-existent directories.\n  if test \"$hardcode_direct_D\" != no &&\n     # If the only mechanism to avoid hardcoding is shlibpath_var, we\n     # have to relink, otherwise we might link with an installed library\n     # when we should be linking with a yet-to-be-installed one\n     ## test \"$_LT_TAGVAR(hardcode_shlibpath_var, D)\" != no &&\n     test \"$hardcode_minus_L_D\" != no; then\n    # Linking always hardcodes the temporary library directory.\n    hardcode_action_D=relink\n  else\n    # We can link without hardcoding, and we can hardcode nonexisting dirs.\n    hardcode_action_D=immediate\n  fi\nelse\n  # We cannot hardcode anything, or else we can only hardcode existing\n  # directories.\n  hardcode_action_D=unsupported\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $hardcode_action_D\" >&5\n$as_echo \"$hardcode_action_D\" >&6; }\n\nif test \"$hardcode_action_D\" = relink ||\n   test \"$inherit_rpath_D\" = yes; then\n  # Fast installation is not supported\n  enable_fast_install=no\nelif test \"$shlibpath_overrides_runpath\" = yes ||\n     test \"$enable_shared\" = no; then\n  # Fast installation is not necessary\n  enable_fast_install=needless\nfi\n\n\n\n\n\n\n\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\nGCC=$lt_save_GCC\nCC=$lt_save_CC\nCFLAGS=$lt_save_CFLAGS\nGDCFLAGS=$lt_save_DFLAGS\n\n  GDCFLAGS=$gdc_save_DFLAGS\n\n if test \"$enable_shared\" = \"yes\"; then\n  ENABLE_SHARED_TRUE=\n  ENABLE_SHARED_FALSE='#'\nelse\n  ENABLE_SHARED_TRUE='#'\n  ENABLE_SHARED_FALSE=\nfi\n\n if test \"$enable_static\" = \"yes\"; then\n  ENABLE_STATIC_TRUE=\n  ENABLE_STATIC_FALSE='#'\nelse\n  ENABLE_STATIC_TRUE='#'\n  ENABLE_STATIC_FALSE=\nfi\n\n\n# libtool variables for Phobos shared and position-independent compiles.\n#\n# Use phobos_compiler_shared_flag to designate the compile-time flags for\n# creating shared objects. Default: -fversion=Shared.\n#\n# Use phobos_compiler_pic_flag to designate the compile-time flags for\n# creating position-independent objects. This varies with the target\n# hardware and operating system, but is often: -fPIC.\n#\n# The distinction between pic and shared compilation flags is not present in\n# libtool, and so we make it here.  How it is handled is that in shared\n# compilations the `lt_prog_compiler_pic_D' variable is used to instead\n# ensure that conditional compilation of shared runtime code is compiled in.\n# The original PIC flags are then used in the compilation of every object.\n#\n# Why are objects destined for libgphobos.a compiled with -fPIC?\n# Because -fPIC is not harmful to use for objects destined for static\n# libraries. In addition, using -fPIC will allow the use of static\n# libgphobos.a in the creation of other D shared libraries.\nif test \"$enable_shared\" = yes; then\n  phobos_compiler_pic_flag=\"$lt_prog_compiler_pic_D\"\n  phobos_compiler_shared_flag=\"-fversion=Shared\"\nelse\n  phobos_compiler_pic_flag=\n  phobos_compiler_shared_flag=\nfi\n\n\n\n# Override the libtool's pic_flag and pic_mode.\n# Do this step after AM_PROG_LIBTOOL, but before AC_OUTPUT.\n# NB: this impacts --with-pic and --without-pic.\nlt_prog_compiler_pic_D=\"$phobos_compiler_shared_flag\"\npic_mode='default'\n\n# Determine what GCC version number to use in filesystem paths.\n\n  get_gcc_base_ver=\"cat\"\n\n# Check whether --with-gcc-major-version-only was given.\nif test \"${with_gcc_major_version_only+set}\" = set; then :\n  withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then\n        get_gcc_base_ver=\"sed -e 's/^\\([0-9]*\\).*/\\1/'\"\n      fi\n\nfi\n\n\n\n\n# libphobos/libdruntime specific options and feature detection\n\n  # These need to be absolute paths, yet at the same time need to\n  # canonicalize only relative paths, because then amd will not unmount\n  # drives. Thus the use of PWDCMD: set it to 'pawd' or 'amq -w' if using amd.\n  libphobos_builddir=`${PWDCMD-pwd}`\n  case $srcdir in\n    \\\\/$* | ?:\\\\/*) libphobos_srcdir=${srcdir} ;;\n    *) libphobos_srcdir=`cd \"$srcdir\" && ${PWDCMD-pwd} || echo \"$srcdir\"` ;;\n  esac\n\n\n\n\n  if test ${multilib} = yes; then\n    multilib_arg=\"--enable-multilib\"\n  else\n    multilib_arg=\n  fi\n\n\n  # Check whether --enable-werror was given.\nif test \"${enable_werror+set}\" = set; then :\n  enableval=$enable_werror;\nfi\n\n  WERROR_FLAG=\"\"\n  if test \"x$enable_werror\" = \"xyes\"; then\n      WERROR_FLAG=\"-Werror\"\n  fi\n\n\n    # Check whether --enable-druntime-gc was given.\nif test \"${enable_druntime_gc+set}\" = set; then :\n  enableval=$enable_druntime_gc; enable_druntime_gc=no\nelse\n  enable_druntime_gc=yes\nfi\n\n\n   if test \"$enable_druntime_gc\" = \"yes\"; then\n  DRUNTIME_GC_ENABLE_TRUE=\n  DRUNTIME_GC_ENABLE_FALSE='#'\nelse\n  DRUNTIME_GC_ENABLE_TRUE='#'\n  DRUNTIME_GC_ENABLE_FALSE=\nfi\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for target OS\" >&5\n$as_echo_n \"checking for target OS... \" >&6; }\nif test \"${druntime_cv_target_os+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  druntime_cv_target_os=`echo $target_os | sed 's/^\\([A-Za-z_]+\\)/\\1/'`\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $druntime_cv_target_os\" >&5\n$as_echo \"$druntime_cv_target_os\" >&6; }\n    if test -z \"$druntime_cv_target_os\"; then :\n  as_fn_error \"can't detect target OS\" \"$LINENO\" 5\nfi\n\n\n\n  # Check whether --enable-unix was given.\nif test \"${enable_unix+set}\" = set; then :\n  enableval=$enable_unix; :\nelse\n  enable_unix=auto\nfi\n\n\n  case \"$druntime_cv_target_os\" in\n    aix*|*bsd*|cygwin*|darwin*|gnu*|linux*|skyos*|*solaris*|sysv*) d_have_unix=1 ;;\n  esac\n  if test -n \"$d_have_unix\" && test \"$enable_unix\" = auto ; then\n    enable_unix=yes\n  fi\n   if test \"$enable_unix\" = \"yes\"; then\n  DRUNTIME_OS_UNIX_TRUE=\n  DRUNTIME_OS_UNIX_FALSE='#'\nelse\n  DRUNTIME_OS_UNIX_TRUE='#'\n  DRUNTIME_OS_UNIX_FALSE=\nfi\n\n\n\n\n\n  druntime_target_os_parsed=\"\"\n  case \"$druntime_cv_target_os\" in\n      aix*)    druntime_target_os_parsed=\"aix\"\n               ;;\n      *android*)\n               druntime_target_os_parsed=\"android\"\n               ;;\n      darwin*) druntime_target_os_parsed=\"darwin\"\n               ;;\n      dragonfly*) druntime_target_os_parsed=\"dragonfly\"\n               ;;\n      freebsd*|k*bsd*-gnu)\n               druntime_target_os_parsed=\"freebsd\"\n               ;;\n      openbsd*)\n               druntime_target_os_parsed=\"openbsd\"\n               ;;\n      netbsd*)\n               druntime_target_os_parsed=\"netbsd\"\n               ;;\n      linux*)  druntime_target_os_parsed=\"linux\"\n               ;;\n      mingw*)  druntime_target_os_parsed=\"mingw\"\n             ;;\n      *solaris*) druntime_target_os_parsed=\"solaris\"\n  esac\n   if test \"$druntime_target_os_parsed\" = \"aix\"; then\n  DRUNTIME_OS_AIX_TRUE=\n  DRUNTIME_OS_AIX_FALSE='#'\nelse\n  DRUNTIME_OS_AIX_TRUE='#'\n  DRUNTIME_OS_AIX_FALSE=\nfi\n\n   if test \"$druntime_target_os_parsed\" = \"android\"; then\n  DRUNTIME_OS_ANDROID_TRUE=\n  DRUNTIME_OS_ANDROID_FALSE='#'\nelse\n  DRUNTIME_OS_ANDROID_TRUE='#'\n  DRUNTIME_OS_ANDROID_FALSE=\nfi\n\n   if test \"$druntime_target_os_parsed\" = \"darwin\"; then\n  DRUNTIME_OS_DARWIN_TRUE=\n  DRUNTIME_OS_DARWIN_FALSE='#'\nelse\n  DRUNTIME_OS_DARWIN_TRUE='#'\n  DRUNTIME_OS_DARWIN_FALSE=\nfi\n\n   if test \"$druntime_target_os_parsed\" = \"dragonfly\"; then\n  DRUNTIME_OS_DRAGONFLYBSD_TRUE=\n  DRUNTIME_OS_DRAGONFLYBSD_FALSE='#'\nelse\n  DRUNTIME_OS_DRAGONFLYBSD_TRUE='#'\n  DRUNTIME_OS_DRAGONFLYBSD_FALSE=\nfi\n\n   if test \"$druntime_target_os_parsed\" = \"freebsd\"; then\n  DRUNTIME_OS_FREEBSD_TRUE=\n  DRUNTIME_OS_FREEBSD_FALSE='#'\nelse\n  DRUNTIME_OS_FREEBSD_TRUE='#'\n  DRUNTIME_OS_FREEBSD_FALSE=\nfi\n\n   if test \"$druntime_target_os_parsed\" = \"netbsd\"; then\n  DRUNTIME_OS_NETBSD_TRUE=\n  DRUNTIME_OS_NETBSD_FALSE='#'\nelse\n  DRUNTIME_OS_NETBSD_TRUE='#'\n  DRUNTIME_OS_NETBSD_FALSE=\nfi\n\n   if test \"$druntime_target_os_parsed\" = \"openbsd\"; then\n  DRUNTIME_OS_OPENBSD_TRUE=\n  DRUNTIME_OS_OPENBSD_FALSE='#'\nelse\n  DRUNTIME_OS_OPENBSD_TRUE='#'\n  DRUNTIME_OS_OPENBSD_FALSE=\nfi\n\n   if test \"$druntime_target_os_parsed\" = \"linux\"; then\n  DRUNTIME_OS_LINUX_TRUE=\n  DRUNTIME_OS_LINUX_FALSE='#'\nelse\n  DRUNTIME_OS_LINUX_TRUE='#'\n  DRUNTIME_OS_LINUX_FALSE=\nfi\n\n   if test \"$druntime_target_os_parsed\" = \"mingw\"; then\n  DRUNTIME_OS_MINGW_TRUE=\n  DRUNTIME_OS_MINGW_FALSE='#'\nelse\n  DRUNTIME_OS_MINGW_TRUE='#'\n  DRUNTIME_OS_MINGW_FALSE=\nfi\n\n   if test \"$druntime_target_os_parsed\" = \"solaris\"; then\n  DRUNTIME_OS_SOLARIS_TRUE=\n  DRUNTIME_OS_SOLARIS_FALSE='#'\nelse\n  DRUNTIME_OS_SOLARIS_TRUE='#'\n  DRUNTIME_OS_SOLARIS_FALSE=\nfi\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for thread model used by GDC\" >&5\n$as_echo_n \"checking for thread model used by GDC... \" >&6; }\n  d_thread_model=`$GDC -v 2>&1 | sed -n 's/^Thread model: //p'`\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $d_thread_model\" >&5\n$as_echo \"$d_thread_model\" >&6; }\n\n  # Map from thread model to thread interface.\n\ncase $d_thread_model in\n    aix)    DCFG_THREAD_MODEL=\"Posix\" ;;\n    lynx)   DCFG_THREAD_MODEL=\"Posix\" ;;\n    posix)  DCFG_THREAD_MODEL=\"Posix\" ;;\n    single) DCFG_THREAD_MODEL=\"Single\" ;;\n    win32)  DCFG_THREAD_MODEL=\"Win32\" ;;\n    # TODO: These targets need porting.\n    dce|mipssde|rtems|tpf|vxworks)\n\t    DCFG_THREAD_MODEL=\"Single\" ;;\n    *)\t    as_fn_error \"Thread implementation '$d_thread_model' not recognised\" \"$LINENO\" 5 ;;\nesac\n\n\n\n\n  ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ARM unwinder\" >&5\n$as_echo_n \"checking for ARM unwinder... \" >&6; }\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <unwind.h>\nint\nmain ()\n{\n\n  #if __ARM_EABI_UNWINDER__\n  #error Yes, it is.\n  #endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n     DCFG_ARM_EABI_UNWINDER=false\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n     DCFG_ARM_EABI_UNWINDER=true\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\n   if test \"$DCFG_ARM_EABI_UNWINDER\" = \"true\"; then\n  DRUNTIME_OS_ARM_EABI_UNWINDER_TRUE=\n  DRUNTIME_OS_ARM_EABI_UNWINDER_FALSE='#'\nelse\n  DRUNTIME_OS_ARM_EABI_UNWINDER_TRUE='#'\n  DRUNTIME_OS_ARM_EABI_UNWINDER_FALSE=\nfi\n\n  ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n\n  ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for minfo section bracketing\" >&5\n$as_echo_n \"checking for minfo section bracketing... \" >&6; }\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n    void* module_info_ptr __attribute__((section (\"minfo\")));\n    extern void* __start_minfo __attribute__((visibility (\"hidden\")));\n    extern void* __stop_minfo __attribute__((visibility (\"hidden\")));\n\n    int main()\n    {\n        // Never run, just to prevent compiler from optimizing access\n        return &__start_minfo == &__stop_minfo;\n    }\n\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n     DCFG_MINFO_BRACKETING=true\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n     DCFG_MINFO_BRACKETING=false\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n  ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n\n\n\n  gdc_save_DFLAGS=$GDCFLAGS\n  GDCFLAGS=\"-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime -nophoboslib $GDCFLAGS\"\n\n  ac_ext=d\nac_compile='$GDC -c $GDCFLAGS conftest.$ac_ext >&5'\nac_link='$GDC -o conftest$ac_exeext $GDCFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=yes\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for library containing malloc\" >&5\n$as_echo_n \"checking for library containing malloc... \" >&6; }\nif test \"${ac_cv_search_malloc+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_func_search_save_LIBS=$LIBS\ncat > conftest.$ac_ext <<_ACEOF\nmodule mod;\n extern(C) int malloc();\n\nextern(C) int main() {\n  malloc(); return 0;\n}\n_ACEOF\nfor ac_lib in '' c; do\n  if test -z \"$ac_lib\"; then\n    ac_res=\"none required\"\n  else\n    ac_res=-l$ac_lib\n    LIBS=\"-l$ac_lib  $ac_func_search_save_LIBS\"\n  fi\n  if ac_fn_d_try_link \"$LINENO\"; then :\n  ac_cv_search_malloc=$ac_res\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext\n  if test \"${ac_cv_search_malloc+set}\" = set; then :\n  break\nfi\ndone\nif test \"${ac_cv_search_malloc+set}\" = set; then :\n\nelse\n  ac_cv_search_malloc=no\nfi\nrm conftest.$ac_ext\nLIBS=$ac_func_search_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_malloc\" >&5\n$as_echo \"$ac_cv_search_malloc\" >&6; }\nac_res=$ac_cv_search_malloc\nif test \"$ac_res\" != no; then :\n  test \"$ac_res\" = \"none required\" || LIBS=\"$ac_res $LIBS\"\n\nfi\n\n\n  enable_thread_lib=yes\n  # Check whether --enable-thread-lib was given.\nif test \"${enable_thread_lib+set}\" = set; then :\n  enableval=$enable_thread_lib;\nfi\n\n\n  if test \"x$enable_thread_lib\" = \"xyes\"; then :\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create\" >&5\n$as_echo_n \"checking for library containing pthread_create... \" >&6; }\nif test \"${ac_cv_search_pthread_create+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_func_search_save_LIBS=$LIBS\ncat > conftest.$ac_ext <<_ACEOF\nmodule mod;\n extern(C) int pthread_create();\n\nextern(C) int main() {\n  pthread_create(); return 0;\n}\n_ACEOF\nfor ac_lib in '' pthread; do\n  if test -z \"$ac_lib\"; then\n    ac_res=\"none required\"\n  else\n    ac_res=-l$ac_lib\n    LIBS=\"-l$ac_lib  $ac_func_search_save_LIBS\"\n  fi\n  if ac_fn_d_try_link \"$LINENO\"; then :\n  ac_cv_search_pthread_create=$ac_res\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext\n  if test \"${ac_cv_search_pthread_create+set}\" = set; then :\n  break\nfi\ndone\nif test \"${ac_cv_search_pthread_create+set}\" = set; then :\n\nelse\n  ac_cv_search_pthread_create=no\nfi\nrm conftest.$ac_ext\nLIBS=$ac_func_search_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create\" >&5\n$as_echo \"$ac_cv_search_pthread_create\" >&6; }\nac_res=$ac_cv_search_pthread_create\nif test \"$ac_res\" != no; then :\n  test \"$ac_res\" = \"none required\" || LIBS=\"$ac_res $LIBS\"\n\nfi\n\n\nelse\n\n    if test \"x$enable_thread_lib\" = \"xno\"; then :\n\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for thread library\" >&5\n$as_echo_n \"checking for thread library... \" >&6; }\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: disabled\" >&5\n$as_echo \"disabled\" >&6; }\n\nelse\n\n      as_ac_Lib=`$as_echo \"ac_cv_lib_$enable_thread_lib''_pthread_create\" | $as_tr_sh`\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for pthread_create in -l$enable_thread_lib\" >&5\n$as_echo_n \"checking for pthread_create in -l$enable_thread_lib... \" >&6; }\nif { as_var=$as_ac_Lib; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-l$enable_thread_lib  $LIBS\"\ncat > conftest.$ac_ext <<_ACEOF\nmodule mod;\n extern(C) int pthread_create();\n\nextern(C) int main() {\n  pthread_create(); return 0;\n}\n_ACEOF\nif ac_fn_d_try_link \"$LINENO\"; then :\n  eval \"$as_ac_Lib=yes\"\nelse\n  eval \"$as_ac_Lib=no\"\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\neval ac_res=\\$$as_ac_Lib\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\neval as_val=\\$$as_ac_Lib\n   if test \"x$as_val\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define `$as_echo \"HAVE_LIB$enable_thread_lib\" | $as_tr_cpp` 1\n_ACEOF\n\n  LIBS=\"-l$enable_thread_lib $LIBS\"\n\nelse\n\n        as_fn_error \"Thread library not found\" \"$LINENO\" 5\n\nfi\n\n\nfi\n\nfi\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for library containing cosf\" >&5\n$as_echo_n \"checking for library containing cosf... \" >&6; }\nif test \"${ac_cv_search_cosf+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_func_search_save_LIBS=$LIBS\ncat > conftest.$ac_ext <<_ACEOF\nmodule mod;\n extern(C) int cosf();\n\nextern(C) int main() {\n  cosf(); return 0;\n}\n_ACEOF\nfor ac_lib in '' m; do\n  if test -z \"$ac_lib\"; then\n    ac_res=\"none required\"\n  else\n    ac_res=-l$ac_lib\n    LIBS=\"-l$ac_lib  $ac_func_search_save_LIBS\"\n  fi\n  if ac_fn_d_try_link \"$LINENO\"; then :\n  ac_cv_search_cosf=$ac_res\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext\n  if test \"${ac_cv_search_cosf+set}\" = set; then :\n  break\nfi\ndone\nif test \"${ac_cv_search_cosf+set}\" = set; then :\n\nelse\n  ac_cv_search_cosf=no\nfi\nrm conftest.$ac_ext\nLIBS=$ac_func_search_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_cosf\" >&5\n$as_echo \"$ac_cv_search_cosf\" >&6; }\nac_res=$ac_cv_search_cosf\nif test \"$ac_res\" != no; then :\n  test \"$ac_res\" = \"none required\" || LIBS=\"$ac_res $LIBS\"\n\nfi\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime\" >&5\n$as_echo_n \"checking for library containing clock_gettime... \" >&6; }\nif test \"${ac_cv_search_clock_gettime+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_func_search_save_LIBS=$LIBS\ncat > conftest.$ac_ext <<_ACEOF\nmodule mod;\n extern(C) int clock_gettime();\n\nextern(C) int main() {\n  clock_gettime(); return 0;\n}\n_ACEOF\nfor ac_lib in '' rt; do\n  if test -z \"$ac_lib\"; then\n    ac_res=\"none required\"\n  else\n    ac_res=-l$ac_lib\n    LIBS=\"-l$ac_lib  $ac_func_search_save_LIBS\"\n  fi\n  if ac_fn_d_try_link \"$LINENO\"; then :\n  ac_cv_search_clock_gettime=$ac_res\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext\n  if test \"${ac_cv_search_clock_gettime+set}\" = set; then :\n  break\nfi\ndone\nif test \"${ac_cv_search_clock_gettime+set}\" = set; then :\n\nelse\n  ac_cv_search_clock_gettime=no\nfi\nrm conftest.$ac_ext\nLIBS=$ac_func_search_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime\" >&5\n$as_echo \"$ac_cv_search_clock_gettime\" >&6; }\nac_res=$ac_cv_search_clock_gettime\nif test \"$ac_res\" != no; then :\n  test \"$ac_res\" = \"none required\" || LIBS=\"$ac_res $LIBS\"\n\nfi\n\n\n  # This checks to see if the host supports the compiler-generated builtins\n  # for atomic operations for various integral sizes. Note, this is intended\n  # to be an all-or-nothing switch, so all the atomic operations that are\n  # used should be checked.\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for atomic builtins for byte\" >&5\n$as_echo_n \"checking for atomic builtins for byte... \" >&6; }\n  if test \"${druntime_cv_atomic_byte+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n\n    cat > conftest.$ac_ext <<_ACEOF\nmodule mod;\nimport gcc.builtins;\n\nextern(C) int main() {\n\n      shared(byte) c1;\n       byte c2, c3;\n       __atomic_compare_exchange_1(&c1, &c2, c3, false, 5, 5);\n       __atomic_load_1(&c1, 5);\n       __atomic_store_1(&c1, c2, 5);\n       return 0;\n\n}\n_ACEOF\nif ac_fn_d_try_link \"$LINENO\"; then :\n  druntime_cv_atomic_byte=yes\nelse\n  druntime_cv_atomic_byte=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\nfi\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $druntime_cv_atomic_byte\" >&5\n$as_echo \"$druntime_cv_atomic_byte\" >&6; }\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for atomic builtins for short\" >&5\n$as_echo_n \"checking for atomic builtins for short... \" >&6; }\n  if test \"${druntime_cv_atomic_short+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n\n    cat > conftest.$ac_ext <<_ACEOF\nmodule mod;\nimport gcc.builtins;\n\nextern(C) int main() {\n\n      shared(short) c1;\n       short c2, c3;\n       __atomic_compare_exchange_2(&c1, &c2, c3, false, 5, 5);\n       __atomic_load_2(&c1, 5);\n       __atomic_store_2(&c1, c2, 5);\n       return 0;\n\n}\n_ACEOF\nif ac_fn_d_try_link \"$LINENO\"; then :\n  druntime_cv_atomic_short=yes\nelse\n  druntime_cv_atomic_short=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\nfi\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $druntime_cv_atomic_short\" >&5\n$as_echo \"$druntime_cv_atomic_short\" >&6; }\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for atomic builtins for int\" >&5\n$as_echo_n \"checking for atomic builtins for int... \" >&6; }\n  if test \"${druntime_cv_atomic_int+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n\n    cat > conftest.$ac_ext <<_ACEOF\nmodule mod;\nimport gcc.builtins;\n\nextern(C) int main() {\n\n      shared(int) c1;\n       int c2, c3;\n       __atomic_compare_exchange_4(&c1, &c2, c3, false, 5, 5);\n       __atomic_load_4(&c1, 5);\n       __atomic_store_4(&c1, c2, 5);\n       return 0;\n\n}\n_ACEOF\nif ac_fn_d_try_link \"$LINENO\"; then :\n  druntime_cv_atomic_int=yes\nelse\n  druntime_cv_atomic_int=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\nfi\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $druntime_cv_atomic_int\" >&5\n$as_echo \"$druntime_cv_atomic_int\" >&6; }\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for atomic builtins for long\" >&5\n$as_echo_n \"checking for atomic builtins for long... \" >&6; }\n  if test \"${druntime_cv_atomic_long+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n\n    cat > conftest.$ac_ext <<_ACEOF\nmodule mod;\nimport gcc.builtins;\n\nextern(C) int main() {\n\n       shared(long) c1;\n       long c2, c3;\n       __atomic_compare_exchange_8(&c1, &c2, c3, false, 5, 5);\n       __atomic_load_8(&c1, 5);\n       __atomic_store_8(&c1, c2, 5);\n       return 0;\n\n}\n_ACEOF\nif ac_fn_d_try_link \"$LINENO\"; then :\n  druntime_cv_atomic_long=yes\nelse\n  druntime_cv_atomic_long=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\nfi\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $druntime_cv_atomic_long\" >&5\n$as_echo \"$druntime_cv_atomic_long\" >&6; }\n\n  # Have atomic builtin support if all but the long test above passes.\n  DCFG_HAVE_ATOMIC_BUILTINS=false\n  if test \"$druntime_cv_atomic_byte\" = yes \\\n     && test \"$druntime_cv_atomic_short\" = yes \\\n     && test \"$druntime_cv_atomic_int\" = yes; then \\\n    DCFG_HAVE_ATOMIC_BUILTINS=true\n  fi\n\n  # Have 64-bit atomic support if the long test above passes.\n  DCFG_HAVE_64BIT_ATOMICS=false\n  if test \"$druntime_cv_atomic_long\" = yes; then\n    DCFG_HAVE_64BIT_ATOMICS=true\n  fi\n\n\n\n\n  ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n  GDCFLAGS=$gdc_save_DFLAGS\n\n\n\n\n# Check whether --with-libatomic was given.\nif test \"${with_libatomic+set}\" = set; then :\n  withval=$with_libatomic;\nfi\n\n\n  DCFG_HAVE_LIBATOMIC=false\n  LIBATOMIC=\n  if test \"x$with_libatomic\" != \"xno\"; then :\n\n    DCFG_HAVE_LIBATOMIC=true\n    LIBATOMIC=../../libatomic/libatomic_convenience.la\n\nelse\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for libatomic\" >&5\n$as_echo_n \"checking for libatomic... \" >&6; }\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: disabled\" >&5\n$as_echo \"disabled\" >&6; }\n\nfi\n\n\n\n\n\n  ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n  BACKTRACE_SUPPORTED=false\n  BACKTRACE_USES_MALLOC=false\n  BACKTRACE_SUPPORTS_THREADS=false\n  LIBBACKTRACE=\"\"\n\n\n# Check whether --with-libbacktrace was given.\nif test \"${with_libbacktrace+set}\" = set; then :\n  withval=$with_libbacktrace;\nfi\n\n\n  if test \"x$with_libbacktrace\" != \"xno\"; then :\n\n    LIBBACKTRACE=../../libbacktrace/libbacktrace.la\n\n    gdc_save_CPPFLAGS=$CPPFLAGS\n    CPPFLAGS+=\" -I../libbacktrace \"\n\n    ac_fn_c_check_header_mongrel \"$LINENO\" \"backtrace-supported.h\" \"ac_cv_header_backtrace_supported_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_backtrace_supported_h\" = x\"\"yes; then :\n  have_libbacktrace_h=true\nelse\n  have_libbacktrace_h=false\nfi\n\n\n\n    if $have_libbacktrace_h; then\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: checking libbacktrace: BACKTRACE_SUPPORTED\" >&5\n$as_echo_n \"checking libbacktrace: BACKTRACE_SUPPORTED... \" >&6; }\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n      #include <backtrace-supported.h>\n      #if BACKTRACE_SUPPORTED\n        FOUND_LIBBACKTRACE_RESULT_GDC\n      #endif\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"FOUND_LIBBACKTRACE_RESULT_GDC\" >/dev/null 2>&1; then :\n  BACKTRACE_SUPPORTED=true\nelse\n  BACKTRACE_SUPPORTED=false\nfi\nrm -f conftest*\n\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $BACKTRACE_SUPPORTED\" >&5\n$as_echo \"$BACKTRACE_SUPPORTED\" >&6; }\n\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: checking libbacktrace: BACKTRACE_USES_MALLOC\" >&5\n$as_echo_n \"checking libbacktrace: BACKTRACE_USES_MALLOC... \" >&6; }\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n      #include <backtrace-supported.h>\n      #if BACKTRACE_USES_MALLOC\n        FOUND_LIBBACKTRACE_RESULT_GDC\n      #endif\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"FOUND_LIBBACKTRACE_RESULT_GDC\" >/dev/null 2>&1; then :\n  BACKTRACE_USES_MALLOC=true\nelse\n  BACKTRACE_USES_MALLOC=false\nfi\nrm -f conftest*\n\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $BACKTRACE_USES_MALLOC\" >&5\n$as_echo \"$BACKTRACE_USES_MALLOC\" >&6; }\n\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: checking libbacktrace: BACKTRACE_SUPPORTS_THREADS\" >&5\n$as_echo_n \"checking libbacktrace: BACKTRACE_SUPPORTS_THREADS... \" >&6; }\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n      #include <backtrace-supported.h>\n      #if BACKTRACE_SUPPORTS_THREADS\n        FOUND_LIBBACKTRACE_RESULT_GDC\n      #endif\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"FOUND_LIBBACKTRACE_RESULT_GDC\" >/dev/null 2>&1; then :\n  BACKTRACE_SUPPORTS_THREADS=true\nelse\n  BACKTRACE_SUPPORTS_THREADS=false\nfi\nrm -f conftest*\n\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $BACKTRACE_SUPPORTS_THREADS\" >&5\n$as_echo \"$BACKTRACE_SUPPORTS_THREADS\" >&6; }\n    fi\n    CPPFLAGS=$gdc_save_CPPFLAGS\n\nelse\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for libbacktrace\" >&5\n$as_echo_n \"checking for libbacktrace... \" >&6; }\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: disabled\" >&5\n$as_echo \"disabled\" >&6; }\n\nfi\n\n\n\n\n\n  ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n\n  # Libtool has already checked this, so re-use the inferred dlopen lib.\n  if test \"x$enable_dlopen\" = \"xyes\" && test -n \"$lt_cv_dlopen_libs\"; then :\n\n    LIBS=\"$LIBS $lt_cv_dlopen_libs\"\n\nfi\n\n\n\n# Check whether --with-target-system-zlib was given.\nif test \"${with_target_system_zlib+set}\" = set; then :\n  withval=$with_target_system_zlib;\nfi\n\n\n  system_zlib=false\n  if test \"x$with_target_system_zlib\" = \"xyes\"; then :\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for deflate in -lz\" >&5\n$as_echo_n \"checking for deflate in -lz... \" >&6; }\nif test \"${ac_cv_lib_z_deflate+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lz  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar deflate ();\nint\nmain ()\n{\nreturn deflate ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_z_deflate=yes\nelse\n  ac_cv_lib_z_deflate=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflate\" >&5\n$as_echo \"$ac_cv_lib_z_deflate\" >&6; }\nif test \"x$ac_cv_lib_z_deflate\" = x\"\"yes; then :\n\n      system_zlib=yes\n\nelse\n\n      as_fn_error \"System zlib not found\" \"$LINENO\" 5\n\nfi\n\n\nelse\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for zlib\" >&5\n$as_echo_n \"checking for zlib... \" >&6; }\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: just compiled\" >&5\n$as_echo \"just compiled\" >&6; }\n\nfi\n\n   if test \"$with_target_system_zlib\" = yes; then\n  DRUNTIME_ZLIB_SYSTEM_TRUE=\n  DRUNTIME_ZLIB_SYSTEM_FALSE='#'\nelse\n  DRUNTIME_ZLIB_SYSTEM_TRUE='#'\n  DRUNTIME_ZLIB_SYSTEM_FALSE=\nfi\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking D GCC version\" >&5\n$as_echo_n \"checking D GCC version... \" >&6; }\n  gcc_version=`eval $get_gcc_base_ver $srcdir/../gcc/BASE-VER`\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $gcc_version\" >&5\n$as_echo \"$gcc_version\" >&6; }\n\n\n\n# Check whether --with-cross-host was given.\nif test \"${with_cross_host+set}\" = set; then :\n  withval=$with_cross_host;\nfi\n\n\n  toolexecdir=no\n  toolexeclibdir=no\n\n  version_specific_libs=no\n\n  # Version-specific runtime libs processing.\n  if test $version_specific_libs = yes; then\n      toolexecdir='${libdir}/gcc/${host_alias}'\n      toolexeclibdir='${toolexecdir}/${gcc_version}$(MULTISUBDIR)'\n  else\n      # Calculate toolexecdir, toolexeclibdir\n      # Install a library built with a cross compiler in tooldir, not libdir.\n      if test -n \"$with_cross_host\" && test x\"$with_cross_host\" != x\"no\"; then\n          toolexecdir='${exec_prefix}/${host_alias}'\n          toolexeclibdir='${toolexecdir}/lib'\n      else\n          toolexecdir='${libdir}/gcc/${host_alias}'\n          toolexeclibdir='${libdir}'\n      fi\n      multi_os_directory=`$GDC -print-multi-os-directory`\n      case $multi_os_directory in\n          .) ;; # Avoid trailing /.\n          *) toolexeclibdir=${toolexeclibdir}/${multi_os_directory} ;;\n      esac\n  fi\n\n\n\n  # Default case for install directory for D sources files.\n  gdc_include_dir='$(libdir)/gcc/${target_alias}/${gcc_version}/include/d'\n\n\n\n# Add dependencies for libgphobos.spec file\nSPEC_PHOBOS_DEPS=\"$LIBS\"\n\n\n# Libdruntime / phobos soname version\nDRUNTIME_SOVERSION=\"83:0:0\"\nPHOBOS_SOVERSION=\"83:0:0\"\n\n\n\n# Set default flags (after DRUNTIME_WERROR!)\nif test -z \"$GDCFLAGS\"; then\n    GDCFLAGS=\"-Wall $WERROR_FLAG -g -frelease -O2\"\nfi\n\n\nif test -z \"$GDCFLAGSX\"; then\n    GDCFLAGSX=\"-Wall $WERROR_FLAG -g -fno-release -funittest\"\nfi\n\n\n# Sanity check for the cross-compilation case:\nac_fn_c_check_header_mongrel \"$LINENO\" \"stdio.h\" \"ac_cv_header_stdio_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_stdio_h\" = x\"\"yes; then :\n  :\nelse\n  as_fn_error \"cannot find stdio.h.\" \"$LINENO\" 5\nfi\n\n\n\nac_config_files=\"$ac_config_files Makefile src/Makefile libdruntime/Makefile testsuite/Makefile\"\n\n\nac_config_files=\"$ac_config_files libdruntime/gcc/config.d libdruntime/gcc/libbacktrace.d\"\n\nac_config_files=\"$ac_config_files src/libgphobos.spec\"\n\nac_config_files=\"$ac_config_files testsuite/testsuite_flags\"\n\n\n# We need multilib support, but only if configuring for the target.\nac_config_commands=\"$ac_config_commands default\"\n\n\ncat >confcache <<\\_ACEOF\n# This file is a shell script that caches the results of configure\n# tests run on this system so they can be shared between configure\n# scripts and configure runs, see configure's option --config-cache.\n# It is not useful on other systems.  If it contains results you don't\n# want to keep, you may remove or edit it.\n#\n# config.status only pays attention to the cache file if you give it\n# the --recheck option to rerun configure.\n#\n# `ac_cv_env_foo' variables (set or unset) will be overridden when\n# loading this file, other *unset* `ac_cv_foo' will be assigned the\n# following values.\n\n_ACEOF\n\n# The following way of writing the cache mishandles newlines in values,\n# but we know of no workaround that is simple, portable, and efficient.\n# So, we kill variables containing newlines.\n# Ultrix sh set writes to stderr and can't be redirected directly,\n# and sets the high bit in the cache file unless we assign to the vars.\n(\n  for ac_var in `(set) 2>&1 | sed -n 's/^\\([a-zA-Z_][a-zA-Z0-9_]*\\)=.*/\\1/p'`; do\n    eval ac_val=\\$$ac_var\n    case $ac_val in #(\n    *${as_nl}*)\n      case $ac_var in #(\n      *_cv_*) { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline\" >&5\n$as_echo \"$as_me: WARNING: cache variable $ac_var contains a newline\" >&2;} ;;\n      esac\n      case $ac_var in #(\n      _ | IFS | as_nl) ;; #(\n      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(\n      *) { eval $ac_var=; unset $ac_var;} ;;\n      esac ;;\n    esac\n  done\n\n  (set) 2>&1 |\n    case $as_nl`(ac_space=' '; set) 2>&1` in #(\n    *${as_nl}ac_space=\\ *)\n      # `set' does not quote correctly, so add quotes: double-quote\n      # substitution turns \\\\\\\\ into \\\\, and sed turns \\\\ into \\.\n      sed -n \\\n\t\"s/'/'\\\\\\\\''/g;\n\t  s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1='\\\\2'/p\"\n      ;; #(\n    *)\n      # `set' quotes correctly as required by POSIX, so do not add quotes.\n      sed -n \"/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p\"\n      ;;\n    esac |\n    sort\n) |\n  sed '\n     /^ac_cv_env_/b end\n     t clear\n     :clear\n     s/^\\([^=]*\\)=\\(.*[{}].*\\)$/test \"${\\1+set}\" = set || &/\n     t end\n     s/^\\([^=]*\\)=\\(.*\\)$/\\1=${\\1=\\2}/\n     :end' >>confcache\nif diff \"$cache_file\" confcache >/dev/null 2>&1; then :; else\n  if test -w \"$cache_file\"; then\n    test \"x$cache_file\" != \"x/dev/null\" &&\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: updating cache $cache_file\" >&5\n$as_echo \"$as_me: updating cache $cache_file\" >&6;}\n    cat confcache >$cache_file\n  else\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file\" >&5\n$as_echo \"$as_me: not updating unwritable cache $cache_file\" >&6;}\n  fi\nfi\nrm -f confcache\n\ntest \"x$prefix\" = xNONE && prefix=$ac_default_prefix\n# Let make expand exec_prefix.\ntest \"x$exec_prefix\" = xNONE && exec_prefix='${prefix}'\n\nDEFS=-DHAVE_CONFIG_H\n\nac_libobjs=\nac_ltlibobjs=\nfor ac_i in : $LIBOBJS; do test \"x$ac_i\" = x: && continue\n  # 1. Remove the extension, and $U if already installed.\n  ac_script='s/\\$U\\././;s/\\.o$//;s/\\.obj$//'\n  ac_i=`$as_echo \"$ac_i\" | sed \"$ac_script\"`\n  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR\n  #    will be set to the directory where LIBOBJS objects are built.\n  as_fn_append ac_libobjs \" \\${LIBOBJDIR}$ac_i\\$U.$ac_objext\"\n  as_fn_append ac_ltlibobjs \" \\${LIBOBJDIR}$ac_i\"'$U.lo'\ndone\nLIBOBJS=$ac_libobjs\n\nLTLIBOBJS=$ac_ltlibobjs\n\n\n if test -n \"$EXEEXT\"; then\n  am__EXEEXT_TRUE=\n  am__EXEEXT_FALSE='#'\nelse\n  am__EXEEXT_TRUE='#'\n  am__EXEEXT_FALSE=\nfi\n\nif test -z \"${MAINTAINER_MODE_TRUE}\" && test -z \"${MAINTAINER_MODE_FALSE}\"; then\n  as_fn_error \"conditional \\\"MAINTAINER_MODE\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${ENABLE_SHARED_TRUE}\" && test -z \"${ENABLE_SHARED_FALSE}\"; then\n  as_fn_error \"conditional \\\"ENABLE_SHARED\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${ENABLE_STATIC_TRUE}\" && test -z \"${ENABLE_STATIC_FALSE}\"; then\n  as_fn_error \"conditional \\\"ENABLE_STATIC\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_GC_ENABLE_TRUE}\" && test -z \"${DRUNTIME_GC_ENABLE_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_GC_ENABLE\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_UNIX_TRUE}\" && test -z \"${DRUNTIME_OS_UNIX_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_UNIX\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_AIX_TRUE}\" && test -z \"${DRUNTIME_OS_AIX_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_AIX\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_ANDROID_TRUE}\" && test -z \"${DRUNTIME_OS_ANDROID_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_ANDROID\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_DARWIN_TRUE}\" && test -z \"${DRUNTIME_OS_DARWIN_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_DARWIN\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_DRAGONFLYBSD_TRUE}\" && test -z \"${DRUNTIME_OS_DRAGONFLYBSD_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_DRAGONFLYBSD\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_FREEBSD_TRUE}\" && test -z \"${DRUNTIME_OS_FREEBSD_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_FREEBSD\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_NETBSD_TRUE}\" && test -z \"${DRUNTIME_OS_NETBSD_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_NETBSD\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_OPENBSD_TRUE}\" && test -z \"${DRUNTIME_OS_OPENBSD_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_OPENBSD\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_LINUX_TRUE}\" && test -z \"${DRUNTIME_OS_LINUX_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_LINUX\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_MINGW_TRUE}\" && test -z \"${DRUNTIME_OS_MINGW_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_MINGW\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_SOLARIS_TRUE}\" && test -z \"${DRUNTIME_OS_SOLARIS_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_SOLARIS\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_OS_ARM_EABI_UNWINDER_TRUE}\" && test -z \"${DRUNTIME_OS_ARM_EABI_UNWINDER_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_OS_ARM_EABI_UNWINDER\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${DRUNTIME_ZLIB_SYSTEM_TRUE}\" && test -z \"${DRUNTIME_ZLIB_SYSTEM_FALSE}\"; then\n  as_fn_error \"conditional \\\"DRUNTIME_ZLIB_SYSTEM\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\n\n: ${CONFIG_STATUS=./config.status}\nac_write_fail=0\nac_clean_files_save=$ac_clean_files\nac_clean_files=\"$ac_clean_files $CONFIG_STATUS\"\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS\" >&5\n$as_echo \"$as_me: creating $CONFIG_STATUS\" >&6;}\nas_write_fail=0\ncat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1\n#! $SHELL\n# Generated by $as_me.\n# Run this file to recreate the current configuration.\n# Compiler output produced by configure, useful for debugging\n# configure, is in config.log if it exists.\n\ndebug=false\nac_cs_recheck=false\nac_cs_silent=false\n\nSHELL=\\${CONFIG_SHELL-$SHELL}\nexport SHELL\n_ASEOF\ncat >>$CONFIG_STATUS <<\\_ASEOF || as_write_fail=1\n## -------------------- ##\n## M4sh Initialization. ##\n## -------------------- ##\n\n# Be more Bourne compatible\nDUALCASE=1; export DUALCASE # for MKS sh\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\n  setopt NO_GLOB_SUBST\nelse\n  case `(set -o) 2>/dev/null` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\n\nas_nl='\n'\nexport as_nl\n# Printing a long string crashes Solaris 7 /usr/bin/printf.\nas_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo\n# Prefer a ksh shell builtin over an external printf program on Solaris,\n# but without wasting forks for bash or zsh.\nif test -z \"$BASH_VERSION$ZSH_VERSION\" \\\n    && (test \"X`print -r -- $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='print -r --'\n  as_echo_n='print -rn --'\nelif (test \"X`printf %s $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='printf %s\\n'\n  as_echo_n='printf %s'\nelse\n  if test \"X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`\" = \"X-n $as_echo\"; then\n    as_echo_body='eval /usr/ucb/echo -n \"$1$as_nl\"'\n    as_echo_n='/usr/ucb/echo -n'\n  else\n    as_echo_body='eval expr \"X$1\" : \"X\\\\(.*\\\\)\"'\n    as_echo_n_body='eval\n      arg=$1;\n      case $arg in #(\n      *\"$as_nl\"*)\n\texpr \"X$arg\" : \"X\\\\(.*\\\\)$as_nl\";\n\targ=`expr \"X$arg\" : \".*$as_nl\\\\(.*\\\\)\"`;;\n      esac;\n      expr \"X$arg\" : \"X\\\\(.*\\\\)\" | tr -d \"$as_nl\"\n    '\n    export as_echo_n_body\n    as_echo_n='sh -c $as_echo_n_body as_echo'\n  fi\n  export as_echo_body\n  as_echo='sh -c $as_echo_body as_echo'\nfi\n\n# The user is always right.\nif test \"${PATH_SEPARATOR+set}\" != set; then\n  PATH_SEPARATOR=:\n  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {\n    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||\n      PATH_SEPARATOR=';'\n  }\nfi\n\n\n# IFS\n# We need space, tab and new line, in precisely that order.  Quoting is\n# there to prevent editors from complaining about space-tab.\n# (If _AS_PATH_WALK were called with IFS unset, it would disable word\n# splitting by setting IFS to empty value.)\nIFS=\" \"\"\t$as_nl\"\n\n# Find who we are.  Look in the path if we contain no directory separator.\ncase $0 in #((\n  *[\\\\/]* ) as_myself=$0 ;;\n  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    test -r \"$as_dir/$0\" && as_myself=$as_dir/$0 && break\n  done\nIFS=$as_save_IFS\n\n     ;;\nesac\n# We did not find ourselves, most probably we were run as `sh COMMAND'\n# in which case we are not to be found in the path.\nif test \"x$as_myself\" = x; then\n  as_myself=$0\nfi\nif test ! -f \"$as_myself\"; then\n  $as_echo \"$as_myself: error: cannot find myself; rerun with an absolute file name\" >&2\n  exit 1\nfi\n\n# Unset variables that we do not need and which cause bugs (e.g. in\n# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the \"|| exit 1\"\n# suppresses any \"Segmentation fault\" message there.  '((' could\n# trigger a bug in pdksh 5.2.14.\nfor as_var in BASH_ENV ENV MAIL MAILPATH\ndo eval test x\\${$as_var+set} = xset \\\n  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :\ndone\nPS1='$ '\nPS2='> '\nPS4='+ '\n\n# NLS nuisances.\nLC_ALL=C\nexport LC_ALL\nLANGUAGE=C\nexport LANGUAGE\n\n# CDPATH.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\n\n# as_fn_error ERROR [LINENO LOG_FD]\n# ---------------------------------\n# Output \"`basename $0`: error: ERROR\" to stderr. If LINENO and LOG_FD are\n# provided, also output the error to LOG_FD, referencing LINENO. Then exit the\n# script with status $?, using 1 if that was 0.\nas_fn_error ()\n{\n  as_status=$?; test $as_status -eq 0 && as_status=1\n  if test \"$3\"; then\n    as_lineno=${as_lineno-\"$2\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n    $as_echo \"$as_me:${as_lineno-$LINENO}: error: $1\" >&$3\n  fi\n  $as_echo \"$as_me: error: $1\" >&2\n  as_fn_exit $as_status\n} # as_fn_error\n\n\n# as_fn_set_status STATUS\n# -----------------------\n# Set $? to STATUS, without forking.\nas_fn_set_status ()\n{\n  return $1\n} # as_fn_set_status\n\n# as_fn_exit STATUS\n# -----------------\n# Exit the shell with STATUS, even in a \"trap 0\" or \"set -e\" context.\nas_fn_exit ()\n{\n  set +e\n  as_fn_set_status $1\n  exit $1\n} # as_fn_exit\n\n# as_fn_unset VAR\n# ---------------\n# Portably unset VAR.\nas_fn_unset ()\n{\n  { eval $1=; unset $1;}\n}\nas_unset=as_fn_unset\n# as_fn_append VAR VALUE\n# ----------------------\n# Append the text in VALUE to the end of the definition contained in VAR. Take\n# advantage of any shell optimizations that allow amortized linear growth over\n# repeated appends, instead of the typical quadratic growth present in naive\n# implementations.\nif (eval \"as_var=1; as_var+=2; test x\\$as_var = x12\") 2>/dev/null; then :\n  eval 'as_fn_append ()\n  {\n    eval $1+=\\$2\n  }'\nelse\n  as_fn_append ()\n  {\n    eval $1=\\$$1\\$2\n  }\nfi # as_fn_append\n\n# as_fn_arith ARG...\n# ------------------\n# Perform arithmetic evaluation on the ARGs, and store the result in the\n# global $as_val. Take advantage of shells that can avoid forks. The arguments\n# must be portable across $(()) and expr.\nif (eval \"test \\$(( 1 + 1 )) = 2\") 2>/dev/null; then :\n  eval 'as_fn_arith ()\n  {\n    as_val=$(( $* ))\n  }'\nelse\n  as_fn_arith ()\n  {\n    as_val=`expr \"$@\" || test $? -eq 1`\n  }\nfi # as_fn_arith\n\n\nif expr a : '\\(a\\)' >/dev/null 2>&1 &&\n   test \"X`expr 00001 : '.*\\(...\\)'`\" = X001; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nif (basename -- /) >/dev/null 2>&1 && test \"X`basename -- / 2>&1`\" = \"X/\"; then\n  as_basename=basename\nelse\n  as_basename=false\nfi\n\nif (as_dir=`dirname -- /` && test \"X$as_dir\" = X/) >/dev/null 2>&1; then\n  as_dirname=dirname\nelse\n  as_dirname=false\nfi\n\nas_me=`$as_basename -- \"$0\" ||\n$as_expr X/\"$0\" : '.*/\\([^/][^/]*\\)/*$' \\| \\\n\t X\"$0\" : 'X\\(//\\)$' \\| \\\n\t X\"$0\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X/\"$0\" |\n    sed '/^.*\\/\\([^/][^/]*\\)\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n\n# Avoid depending upon Character Ranges.\nas_cr_letters='abcdefghijklmnopqrstuvwxyz'\nas_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nas_cr_Letters=$as_cr_letters$as_cr_LETTERS\nas_cr_digits='0123456789'\nas_cr_alnum=$as_cr_Letters$as_cr_digits\n\nECHO_C= ECHO_N= ECHO_T=\ncase `echo -n x` in #(((((\n-n*)\n  case `echo 'xy\\c'` in\n  *c*) ECHO_T='\t';;\t# ECHO_T is single tab character.\n  xy)  ECHO_C='\\c';;\n  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null\n       ECHO_T='\t';;\n  esac;;\n*)\n  ECHO_N='-n';;\nesac\n\nrm -f conf$$ conf$$.exe conf$$.file\nif test -d conf$$.dir; then\n  rm -f conf$$.dir/conf$$.file\nelse\n  rm -f conf$$.dir\n  mkdir conf$$.dir 2>/dev/null\nfi\nif (echo >conf$$.file) 2>/dev/null; then\n  if ln -s conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s='ln -s'\n    # ... but there are two gotchas:\n    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.\n    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.\n    # In both cases, we have to default to `cp -p'.\n    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||\n      as_ln_s='cp -p'\n  elif ln conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s=ln\n  else\n    as_ln_s='cp -p'\n  fi\nelse\n  as_ln_s='cp -p'\nfi\nrm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file\nrmdir conf$$.dir 2>/dev/null\n\n\n# as_fn_mkdir_p\n# -------------\n# Create \"$as_dir\" as a directory, including parents if necessary.\nas_fn_mkdir_p ()\n{\n\n  case $as_dir in #(\n  -*) as_dir=./$as_dir;;\n  esac\n  test -d \"$as_dir\" || eval $as_mkdir_p || {\n    as_dirs=\n    while :; do\n      case $as_dir in #(\n      *\\'*) as_qdir=`$as_echo \"$as_dir\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; #'(\n      *) as_qdir=$as_dir;;\n      esac\n      as_dirs=\"'$as_qdir' $as_dirs\"\n      as_dir=`$as_dirname -- \"$as_dir\" ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n      test -d \"$as_dir\" && break\n    done\n    test -z \"$as_dirs\" || eval \"mkdir $as_dirs\"\n  } || test -d \"$as_dir\" || as_fn_error \"cannot create directory $as_dir\"\n\n\n} # as_fn_mkdir_p\nif mkdir -p . 2>/dev/null; then\n  as_mkdir_p='mkdir -p \"$as_dir\"'\nelse\n  test -d ./-p && rmdir ./-p\n  as_mkdir_p=false\nfi\n\nif test -x / >/dev/null 2>&1; then\n  as_test_x='test -x'\nelse\n  if ls -dL / >/dev/null 2>&1; then\n    as_ls_L_option=L\n  else\n    as_ls_L_option=\n  fi\n  as_test_x='\n    eval sh -c '\\''\n      if test -d \"$1\"; then\n\ttest -d \"$1/.\";\n      else\n\tcase $1 in #(\n\t-*)set \"./$1\";;\n\tesac;\n\tcase `ls -ld'$as_ls_L_option' \"$1\" 2>/dev/null` in #((\n\t???[sx]*):;;*)false;;esac;fi\n    '\\'' sh\n  '\nfi\nas_executable_p=$as_test_x\n\n# Sed expression to map a string onto a valid CPP name.\nas_tr_cpp=\"eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'\"\n\n# Sed expression to map a string onto a valid variable name.\nas_tr_sh=\"eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'\"\n\n\nexec 6>&1\n## ----------------------------------- ##\n## Main body of $CONFIG_STATUS script. ##\n## ----------------------------------- ##\n_ASEOF\ntest $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# Save the log message, to keep $0 and so on meaningful, and to\n# report actual input values of CONFIG_FILES etc. instead of their\n# values after options handling.\nac_log=\"\nThis file was extended by package-unused $as_me version-unused, which was\ngenerated by GNU Autoconf 2.64.  Invocation command line was\n\n  CONFIG_FILES    = $CONFIG_FILES\n  CONFIG_HEADERS  = $CONFIG_HEADERS\n  CONFIG_LINKS    = $CONFIG_LINKS\n  CONFIG_COMMANDS = $CONFIG_COMMANDS\n  $ $0 $@\n\non `(hostname || uname -n) 2>/dev/null | sed 1q`\n\"\n\n_ACEOF\n\ncase $ac_config_files in *\"\n\"*) set x $ac_config_files; shift; ac_config_files=$*;;\nesac\n\ncase $ac_config_headers in *\"\n\"*) set x $ac_config_headers; shift; ac_config_headers=$*;;\nesac\n\n\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n# Files that config.status was made for.\nconfig_files=\"$ac_config_files\"\nconfig_headers=\"$ac_config_headers\"\nconfig_commands=\"$ac_config_commands\"\n\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nac_cs_usage=\"\\\n\\`$as_me' instantiates files and other configuration actions\nfrom templates according to the current configuration.  Unless the files\nand actions are specified as TAGs, all are instantiated by default.\n\nUsage: $0 [OPTION]... [TAG]...\n\n  -h, --help       print this help, then exit\n  -V, --version    print version number and configuration settings, then exit\n  -q, --quiet, --silent\n                   do not print progress messages\n  -d, --debug      don't remove temporary files\n      --recheck    update $as_me by reconfiguring in the same conditions\n      --file=FILE[:TEMPLATE]\n                   instantiate the configuration file FILE\n      --header=FILE[:TEMPLATE]\n                   instantiate the configuration header FILE\n\nConfiguration files:\n$config_files\n\nConfiguration headers:\n$config_headers\n\nConfiguration commands:\n$config_commands\n\nReport bugs to the package provider.\"\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nac_cs_version=\"\\\\\npackage-unused config.status version-unused\nconfigured by $0, generated by GNU Autoconf 2.64,\n  with options \\\\\"`$as_echo \"$ac_configure_args\" | sed 's/^ //; s/[\\\\\"\"\\`\\$]/\\\\\\\\&/g'`\\\\\"\n\nCopyright (C) 2009 Free Software Foundation, Inc.\nThis config.status script is free software; the Free Software Foundation\ngives unlimited permission to copy, distribute and modify it.\"\n\nac_pwd='$ac_pwd'\nsrcdir='$srcdir'\nINSTALL='$INSTALL'\nMKDIR_P='$MKDIR_P'\nAWK='$AWK'\ntest -n \"\\$AWK\" || AWK=awk\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# The default lists apply if the user does not specify any file.\nac_need_defaults=:\nwhile test $# != 0\ndo\n  case $1 in\n  --*=*)\n    ac_option=`expr \"X$1\" : 'X\\([^=]*\\)='`\n    ac_optarg=`expr \"X$1\" : 'X[^=]*=\\(.*\\)'`\n    ac_shift=:\n    ;;\n  *)\n    ac_option=$1\n    ac_optarg=$2\n    ac_shift=shift\n    ;;\n  esac\n\n  case $ac_option in\n  # Handling of the options.\n  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)\n    ac_cs_recheck=: ;;\n  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )\n    $as_echo \"$ac_cs_version\"; exit ;;\n  --debug | --debu | --deb | --de | --d | -d )\n    debug=: ;;\n  --file | --fil | --fi | --f )\n    $ac_shift\n    case $ac_optarg in\n    *\\'*) ac_optarg=`$as_echo \"$ac_optarg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    esac\n    as_fn_append CONFIG_FILES \" '$ac_optarg'\"\n    ac_need_defaults=false;;\n  --header | --heade | --head | --hea )\n    $ac_shift\n    case $ac_optarg in\n    *\\'*) ac_optarg=`$as_echo \"$ac_optarg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    esac\n    as_fn_append CONFIG_HEADERS \" '$ac_optarg'\"\n    ac_need_defaults=false;;\n  --he | --h)\n    # Conflict between --help and --header\n    as_fn_error \"ambiguous option: \\`$1'\nTry \\`$0 --help' for more information.\";;\n  --help | --hel | -h )\n    $as_echo \"$ac_cs_usage\"; exit ;;\n  -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n  | -silent | --silent | --silen | --sile | --sil | --si | --s)\n    ac_cs_silent=: ;;\n\n  # This is an error.\n  -*) as_fn_error \"unrecognized option: \\`$1'\nTry \\`$0 --help' for more information.\" ;;\n\n  *) as_fn_append ac_config_targets \" $1\"\n     ac_need_defaults=false ;;\n\n  esac\n  shift\ndone\n\nac_configure_extra_args=\n\nif $ac_cs_silent; then\n  exec 6>/dev/null\n  ac_configure_extra_args=\"$ac_configure_extra_args --silent\"\nfi\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nif \\$ac_cs_recheck; then\n  set X '$SHELL' '$0' $ac_configure_args \\$ac_configure_extra_args --no-create --no-recursion\n  shift\n  \\$as_echo \"running CONFIG_SHELL=$SHELL \\$*\" >&6\n  CONFIG_SHELL='$SHELL'\n  export CONFIG_SHELL\n  exec \"\\$@\"\nfi\n\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nexec 5>>config.log\n{\n  echo\n  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX\n## Running $as_me. ##\n_ASBOX\n  $as_echo \"$ac_log\"\n} >&5\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n#\n# INIT-COMMANDS\n#\n\nsrcdir=\"$srcdir\"\nhost=\"$host\"\ntarget=\"$target\"\nwith_multisubdir=\"$with_multisubdir\"\nwith_multisrctop=\"$with_multisrctop\"\nwith_target_subdir=\"$with_target_subdir\"\nac_configure_args=\"${multilib_arg} ${ac_configure_args}\"\nmulti_basedir=\"$multi_basedir\"\nCONFIG_SHELL=${CONFIG_SHELL-/bin/sh}\nCC=\"$CC\"\nCXX=\"$CXX\"\nGFORTRAN=\"$GFORTRAN\"\nGDC=\"$GDC\"\n\n\n# The HP-UX ksh and POSIX shell print the target directory to stdout\n# if CDPATH is set.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\nsed_quote_subst='$sed_quote_subst'\ndouble_quote_subst='$double_quote_subst'\ndelay_variable_subst='$delay_variable_subst'\nmacro_version='`$ECHO \"$macro_version\" | $SED \"$delay_single_quote_subst\"`'\nmacro_revision='`$ECHO \"$macro_revision\" | $SED \"$delay_single_quote_subst\"`'\nenable_shared='`$ECHO \"$enable_shared\" | $SED \"$delay_single_quote_subst\"`'\nenable_static='`$ECHO \"$enable_static\" | $SED \"$delay_single_quote_subst\"`'\npic_mode='`$ECHO \"$pic_mode\" | $SED \"$delay_single_quote_subst\"`'\nenable_fast_install='`$ECHO \"$enable_fast_install\" | $SED \"$delay_single_quote_subst\"`'\nSHELL='`$ECHO \"$SHELL\" | $SED \"$delay_single_quote_subst\"`'\nECHO='`$ECHO \"$ECHO\" | $SED \"$delay_single_quote_subst\"`'\nhost_alias='`$ECHO \"$host_alias\" | $SED \"$delay_single_quote_subst\"`'\nhost='`$ECHO \"$host\" | $SED \"$delay_single_quote_subst\"`'\nhost_os='`$ECHO \"$host_os\" | $SED \"$delay_single_quote_subst\"`'\nbuild_alias='`$ECHO \"$build_alias\" | $SED \"$delay_single_quote_subst\"`'\nbuild='`$ECHO \"$build\" | $SED \"$delay_single_quote_subst\"`'\nbuild_os='`$ECHO \"$build_os\" | $SED \"$delay_single_quote_subst\"`'\nSED='`$ECHO \"$SED\" | $SED \"$delay_single_quote_subst\"`'\nXsed='`$ECHO \"$Xsed\" | $SED \"$delay_single_quote_subst\"`'\nGREP='`$ECHO \"$GREP\" | $SED \"$delay_single_quote_subst\"`'\nEGREP='`$ECHO \"$EGREP\" | $SED \"$delay_single_quote_subst\"`'\nFGREP='`$ECHO \"$FGREP\" | $SED \"$delay_single_quote_subst\"`'\nLD='`$ECHO \"$LD\" | $SED \"$delay_single_quote_subst\"`'\nNM='`$ECHO \"$NM\" | $SED \"$delay_single_quote_subst\"`'\nLN_S='`$ECHO \"$LN_S\" | $SED \"$delay_single_quote_subst\"`'\nmax_cmd_len='`$ECHO \"$max_cmd_len\" | $SED \"$delay_single_quote_subst\"`'\nac_objext='`$ECHO \"$ac_objext\" | $SED \"$delay_single_quote_subst\"`'\nexeext='`$ECHO \"$exeext\" | $SED \"$delay_single_quote_subst\"`'\nlt_unset='`$ECHO \"$lt_unset\" | $SED \"$delay_single_quote_subst\"`'\nlt_SP2NL='`$ECHO \"$lt_SP2NL\" | $SED \"$delay_single_quote_subst\"`'\nlt_NL2SP='`$ECHO \"$lt_NL2SP\" | $SED \"$delay_single_quote_subst\"`'\nreload_flag='`$ECHO \"$reload_flag\" | $SED \"$delay_single_quote_subst\"`'\nreload_cmds='`$ECHO \"$reload_cmds\" | $SED \"$delay_single_quote_subst\"`'\nOBJDUMP='`$ECHO \"$OBJDUMP\" | $SED \"$delay_single_quote_subst\"`'\ndeplibs_check_method='`$ECHO \"$deplibs_check_method\" | $SED \"$delay_single_quote_subst\"`'\nfile_magic_cmd='`$ECHO \"$file_magic_cmd\" | $SED \"$delay_single_quote_subst\"`'\nAR='`$ECHO \"$AR\" | $SED \"$delay_single_quote_subst\"`'\nAR_FLAGS='`$ECHO \"$AR_FLAGS\" | $SED \"$delay_single_quote_subst\"`'\nSTRIP='`$ECHO \"$STRIP\" | $SED \"$delay_single_quote_subst\"`'\nRANLIB='`$ECHO \"$RANLIB\" | $SED \"$delay_single_quote_subst\"`'\nold_postinstall_cmds='`$ECHO \"$old_postinstall_cmds\" | $SED \"$delay_single_quote_subst\"`'\nold_postuninstall_cmds='`$ECHO \"$old_postuninstall_cmds\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_cmds='`$ECHO \"$old_archive_cmds\" | $SED \"$delay_single_quote_subst\"`'\nlock_old_archive_extraction='`$ECHO \"$lock_old_archive_extraction\" | $SED \"$delay_single_quote_subst\"`'\nCC='`$ECHO \"$CC\" | $SED \"$delay_single_quote_subst\"`'\nCFLAGS='`$ECHO \"$CFLAGS\" | $SED \"$delay_single_quote_subst\"`'\ncompiler='`$ECHO \"$compiler\" | $SED \"$delay_single_quote_subst\"`'\nGCC='`$ECHO \"$GCC\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_pipe='`$ECHO \"$lt_cv_sys_global_symbol_pipe\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_to_cdecl='`$ECHO \"$lt_cv_sys_global_symbol_to_cdecl\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_to_c_name_address='`$ECHO \"$lt_cv_sys_global_symbol_to_c_name_address\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO \"$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix\" | $SED \"$delay_single_quote_subst\"`'\nobjdir='`$ECHO \"$objdir\" | $SED \"$delay_single_quote_subst\"`'\nMAGIC_CMD='`$ECHO \"$MAGIC_CMD\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_no_builtin_flag='`$ECHO \"$lt_prog_compiler_no_builtin_flag\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_wl='`$ECHO \"$lt_prog_compiler_wl\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_pic='`$ECHO \"$lt_prog_compiler_pic\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_static='`$ECHO \"$lt_prog_compiler_static\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_prog_compiler_c_o='`$ECHO \"$lt_cv_prog_compiler_c_o\" | $SED \"$delay_single_quote_subst\"`'\nneed_locks='`$ECHO \"$need_locks\" | $SED \"$delay_single_quote_subst\"`'\nDSYMUTIL='`$ECHO \"$DSYMUTIL\" | $SED \"$delay_single_quote_subst\"`'\nNMEDIT='`$ECHO \"$NMEDIT\" | $SED \"$delay_single_quote_subst\"`'\nLIPO='`$ECHO \"$LIPO\" | $SED \"$delay_single_quote_subst\"`'\nOTOOL='`$ECHO \"$OTOOL\" | $SED \"$delay_single_quote_subst\"`'\nOTOOL64='`$ECHO \"$OTOOL64\" | $SED \"$delay_single_quote_subst\"`'\nlibext='`$ECHO \"$libext\" | $SED \"$delay_single_quote_subst\"`'\nshrext_cmds='`$ECHO \"$shrext_cmds\" | $SED \"$delay_single_quote_subst\"`'\nextract_expsyms_cmds='`$ECHO \"$extract_expsyms_cmds\" | $SED \"$delay_single_quote_subst\"`'\narchive_cmds_need_lc='`$ECHO \"$archive_cmds_need_lc\" | $SED \"$delay_single_quote_subst\"`'\nenable_shared_with_static_runtimes='`$ECHO \"$enable_shared_with_static_runtimes\" | $SED \"$delay_single_quote_subst\"`'\nexport_dynamic_flag_spec='`$ECHO \"$export_dynamic_flag_spec\" | $SED \"$delay_single_quote_subst\"`'\nwhole_archive_flag_spec='`$ECHO \"$whole_archive_flag_spec\" | $SED \"$delay_single_quote_subst\"`'\ncompiler_needs_object='`$ECHO \"$compiler_needs_object\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_from_new_cmds='`$ECHO \"$old_archive_from_new_cmds\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_from_expsyms_cmds='`$ECHO \"$old_archive_from_expsyms_cmds\" | $SED \"$delay_single_quote_subst\"`'\narchive_cmds='`$ECHO \"$archive_cmds\" | $SED \"$delay_single_quote_subst\"`'\narchive_expsym_cmds='`$ECHO \"$archive_expsym_cmds\" | $SED \"$delay_single_quote_subst\"`'\nmodule_cmds='`$ECHO \"$module_cmds\" | $SED \"$delay_single_quote_subst\"`'\nmodule_expsym_cmds='`$ECHO \"$module_expsym_cmds\" | $SED \"$delay_single_quote_subst\"`'\nwith_gnu_ld='`$ECHO \"$with_gnu_ld\" | $SED \"$delay_single_quote_subst\"`'\nallow_undefined_flag='`$ECHO \"$allow_undefined_flag\" | $SED \"$delay_single_quote_subst\"`'\nno_undefined_flag='`$ECHO \"$no_undefined_flag\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_libdir_flag_spec='`$ECHO \"$hardcode_libdir_flag_spec\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_libdir_flag_spec_ld='`$ECHO \"$hardcode_libdir_flag_spec_ld\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_libdir_separator='`$ECHO \"$hardcode_libdir_separator\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_direct='`$ECHO \"$hardcode_direct\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_direct_absolute='`$ECHO \"$hardcode_direct_absolute\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_minus_L='`$ECHO \"$hardcode_minus_L\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_shlibpath_var='`$ECHO \"$hardcode_shlibpath_var\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_automatic='`$ECHO \"$hardcode_automatic\" | $SED \"$delay_single_quote_subst\"`'\ninherit_rpath='`$ECHO \"$inherit_rpath\" | $SED \"$delay_single_quote_subst\"`'\nlink_all_deplibs='`$ECHO \"$link_all_deplibs\" | $SED \"$delay_single_quote_subst\"`'\nfix_srcfile_path='`$ECHO \"$fix_srcfile_path\" | $SED \"$delay_single_quote_subst\"`'\nalways_export_symbols='`$ECHO \"$always_export_symbols\" | $SED \"$delay_single_quote_subst\"`'\nexport_symbols_cmds='`$ECHO \"$export_symbols_cmds\" | $SED \"$delay_single_quote_subst\"`'\nexclude_expsyms='`$ECHO \"$exclude_expsyms\" | $SED \"$delay_single_quote_subst\"`'\ninclude_expsyms='`$ECHO \"$include_expsyms\" | $SED \"$delay_single_quote_subst\"`'\nprelink_cmds='`$ECHO \"$prelink_cmds\" | $SED \"$delay_single_quote_subst\"`'\nfile_list_spec='`$ECHO \"$file_list_spec\" | $SED \"$delay_single_quote_subst\"`'\nvariables_saved_for_relink='`$ECHO \"$variables_saved_for_relink\" | $SED \"$delay_single_quote_subst\"`'\nneed_lib_prefix='`$ECHO \"$need_lib_prefix\" | $SED \"$delay_single_quote_subst\"`'\nneed_version='`$ECHO \"$need_version\" | $SED \"$delay_single_quote_subst\"`'\nversion_type='`$ECHO \"$version_type\" | $SED \"$delay_single_quote_subst\"`'\nrunpath_var='`$ECHO \"$runpath_var\" | $SED \"$delay_single_quote_subst\"`'\nshlibpath_var='`$ECHO \"$shlibpath_var\" | $SED \"$delay_single_quote_subst\"`'\nshlibpath_overrides_runpath='`$ECHO \"$shlibpath_overrides_runpath\" | $SED \"$delay_single_quote_subst\"`'\nlibname_spec='`$ECHO \"$libname_spec\" | $SED \"$delay_single_quote_subst\"`'\nlibrary_names_spec='`$ECHO \"$library_names_spec\" | $SED \"$delay_single_quote_subst\"`'\nsoname_spec='`$ECHO \"$soname_spec\" | $SED \"$delay_single_quote_subst\"`'\ninstall_override_mode='`$ECHO \"$install_override_mode\" | $SED \"$delay_single_quote_subst\"`'\npostinstall_cmds='`$ECHO \"$postinstall_cmds\" | $SED \"$delay_single_quote_subst\"`'\npostuninstall_cmds='`$ECHO \"$postuninstall_cmds\" | $SED \"$delay_single_quote_subst\"`'\nfinish_cmds='`$ECHO \"$finish_cmds\" | $SED \"$delay_single_quote_subst\"`'\nfinish_eval='`$ECHO \"$finish_eval\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_into_libs='`$ECHO \"$hardcode_into_libs\" | $SED \"$delay_single_quote_subst\"`'\nsys_lib_search_path_spec='`$ECHO \"$sys_lib_search_path_spec\" | $SED \"$delay_single_quote_subst\"`'\nsys_lib_dlsearch_path_spec='`$ECHO \"$sys_lib_dlsearch_path_spec\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_action='`$ECHO \"$hardcode_action\" | $SED \"$delay_single_quote_subst\"`'\nenable_dlopen='`$ECHO \"$enable_dlopen\" | $SED \"$delay_single_quote_subst\"`'\nenable_dlopen_self='`$ECHO \"$enable_dlopen_self\" | $SED \"$delay_single_quote_subst\"`'\nenable_dlopen_self_static='`$ECHO \"$enable_dlopen_self_static\" | $SED \"$delay_single_quote_subst\"`'\nold_striplib='`$ECHO \"$old_striplib\" | $SED \"$delay_single_quote_subst\"`'\nstriplib='`$ECHO \"$striplib\" | $SED \"$delay_single_quote_subst\"`'\nLD_D='`$ECHO \"$LD_D\" | $SED \"$delay_single_quote_subst\"`'\nreload_flag_D='`$ECHO \"$reload_flag_D\" | $SED \"$delay_single_quote_subst\"`'\nreload_cmds_D='`$ECHO \"$reload_cmds_D\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_cmds_D='`$ECHO \"$old_archive_cmds_D\" | $SED \"$delay_single_quote_subst\"`'\ncompiler_D='`$ECHO \"$compiler_D\" | $SED \"$delay_single_quote_subst\"`'\nGCC_D='`$ECHO \"$GCC_D\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_no_builtin_flag_D='`$ECHO \"$lt_prog_compiler_no_builtin_flag_D\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_wl_D='`$ECHO \"$lt_prog_compiler_wl_D\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_pic_D='`$ECHO \"$lt_prog_compiler_pic_D\" | $SED \"$delay_single_quote_subst\"`'\nlt_prog_compiler_static_D='`$ECHO \"$lt_prog_compiler_static_D\" | $SED \"$delay_single_quote_subst\"`'\nlt_cv_prog_compiler_c_o_D='`$ECHO \"$lt_cv_prog_compiler_c_o_D\" | $SED \"$delay_single_quote_subst\"`'\narchive_cmds_need_lc_D='`$ECHO \"$archive_cmds_need_lc_D\" | $SED \"$delay_single_quote_subst\"`'\nenable_shared_with_static_runtimes_D='`$ECHO \"$enable_shared_with_static_runtimes_D\" | $SED \"$delay_single_quote_subst\"`'\nexport_dynamic_flag_spec_D='`$ECHO \"$export_dynamic_flag_spec_D\" | $SED \"$delay_single_quote_subst\"`'\nwhole_archive_flag_spec_D='`$ECHO \"$whole_archive_flag_spec_D\" | $SED \"$delay_single_quote_subst\"`'\ncompiler_needs_object_D='`$ECHO \"$compiler_needs_object_D\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_from_new_cmds_D='`$ECHO \"$old_archive_from_new_cmds_D\" | $SED \"$delay_single_quote_subst\"`'\nold_archive_from_expsyms_cmds_D='`$ECHO \"$old_archive_from_expsyms_cmds_D\" | $SED \"$delay_single_quote_subst\"`'\narchive_cmds_D='`$ECHO \"$archive_cmds_D\" | $SED \"$delay_single_quote_subst\"`'\narchive_expsym_cmds_D='`$ECHO \"$archive_expsym_cmds_D\" | $SED \"$delay_single_quote_subst\"`'\nmodule_cmds_D='`$ECHO \"$module_cmds_D\" | $SED \"$delay_single_quote_subst\"`'\nmodule_expsym_cmds_D='`$ECHO \"$module_expsym_cmds_D\" | $SED \"$delay_single_quote_subst\"`'\nwith_gnu_ld_D='`$ECHO \"$with_gnu_ld_D\" | $SED \"$delay_single_quote_subst\"`'\nallow_undefined_flag_D='`$ECHO \"$allow_undefined_flag_D\" | $SED \"$delay_single_quote_subst\"`'\nno_undefined_flag_D='`$ECHO \"$no_undefined_flag_D\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_libdir_flag_spec_D='`$ECHO \"$hardcode_libdir_flag_spec_D\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_libdir_flag_spec_ld_D='`$ECHO \"$hardcode_libdir_flag_spec_ld_D\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_libdir_separator_D='`$ECHO \"$hardcode_libdir_separator_D\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_direct_D='`$ECHO \"$hardcode_direct_D\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_direct_absolute_D='`$ECHO \"$hardcode_direct_absolute_D\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_minus_L_D='`$ECHO \"$hardcode_minus_L_D\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_shlibpath_var_D='`$ECHO \"$hardcode_shlibpath_var_D\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_automatic_D='`$ECHO \"$hardcode_automatic_D\" | $SED \"$delay_single_quote_subst\"`'\ninherit_rpath_D='`$ECHO \"$inherit_rpath_D\" | $SED \"$delay_single_quote_subst\"`'\nlink_all_deplibs_D='`$ECHO \"$link_all_deplibs_D\" | $SED \"$delay_single_quote_subst\"`'\nfix_srcfile_path_D='`$ECHO \"$fix_srcfile_path_D\" | $SED \"$delay_single_quote_subst\"`'\nalways_export_symbols_D='`$ECHO \"$always_export_symbols_D\" | $SED \"$delay_single_quote_subst\"`'\nexport_symbols_cmds_D='`$ECHO \"$export_symbols_cmds_D\" | $SED \"$delay_single_quote_subst\"`'\nexclude_expsyms_D='`$ECHO \"$exclude_expsyms_D\" | $SED \"$delay_single_quote_subst\"`'\ninclude_expsyms_D='`$ECHO \"$include_expsyms_D\" | $SED \"$delay_single_quote_subst\"`'\nprelink_cmds_D='`$ECHO \"$prelink_cmds_D\" | $SED \"$delay_single_quote_subst\"`'\nfile_list_spec_D='`$ECHO \"$file_list_spec_D\" | $SED \"$delay_single_quote_subst\"`'\nhardcode_action_D='`$ECHO \"$hardcode_action_D\" | $SED \"$delay_single_quote_subst\"`'\n\nLTCC='$LTCC'\nLTCFLAGS='$LTCFLAGS'\ncompiler='$compiler_DEFAULT'\n\n# A function that is used when there is no print builtin or printf.\nfunc_fallback_echo ()\n{\n  eval 'cat <<_LTECHO_EOF\n\\$1\n_LTECHO_EOF'\n}\n\n# Quote evaled strings.\nfor var in SHELL \\\nECHO \\\nSED \\\nGREP \\\nEGREP \\\nFGREP \\\nLD \\\nNM \\\nLN_S \\\nlt_SP2NL \\\nlt_NL2SP \\\nreload_flag \\\nOBJDUMP \\\ndeplibs_check_method \\\nfile_magic_cmd \\\nAR \\\nAR_FLAGS \\\nSTRIP \\\nRANLIB \\\nCC \\\nCFLAGS \\\ncompiler \\\nlt_cv_sys_global_symbol_pipe \\\nlt_cv_sys_global_symbol_to_cdecl \\\nlt_cv_sys_global_symbol_to_c_name_address \\\nlt_cv_sys_global_symbol_to_c_name_address_lib_prefix \\\nlt_prog_compiler_no_builtin_flag \\\nlt_prog_compiler_wl \\\nlt_prog_compiler_pic \\\nlt_prog_compiler_static \\\nlt_cv_prog_compiler_c_o \\\nneed_locks \\\nDSYMUTIL \\\nNMEDIT \\\nLIPO \\\nOTOOL \\\nOTOOL64 \\\nshrext_cmds \\\nexport_dynamic_flag_spec \\\nwhole_archive_flag_spec \\\ncompiler_needs_object \\\nwith_gnu_ld \\\nallow_undefined_flag \\\nno_undefined_flag \\\nhardcode_libdir_flag_spec \\\nhardcode_libdir_flag_spec_ld \\\nhardcode_libdir_separator \\\nfix_srcfile_path \\\nexclude_expsyms \\\ninclude_expsyms \\\nfile_list_spec \\\nvariables_saved_for_relink \\\nlibname_spec \\\nlibrary_names_spec \\\nsoname_spec \\\ninstall_override_mode \\\nfinish_eval \\\nold_striplib \\\nstriplib \\\nLD_D \\\nreload_flag_D \\\ncompiler_D \\\nlt_prog_compiler_no_builtin_flag_D \\\nlt_prog_compiler_wl_D \\\nlt_prog_compiler_pic_D \\\nlt_prog_compiler_static_D \\\nlt_cv_prog_compiler_c_o_D \\\nexport_dynamic_flag_spec_D \\\nwhole_archive_flag_spec_D \\\ncompiler_needs_object_D \\\nwith_gnu_ld_D \\\nallow_undefined_flag_D \\\nno_undefined_flag_D \\\nhardcode_libdir_flag_spec_D \\\nhardcode_libdir_flag_spec_ld_D \\\nhardcode_libdir_separator_D \\\nfix_srcfile_path_D \\\nexclude_expsyms_D \\\ninclude_expsyms_D \\\nfile_list_spec_D; do\n    case \\`eval \\\\\\\\\\$ECHO \\\\\\\\\"\"\\\\\\\\\\$\\$var\"\\\\\\\\\"\\` in\n    *[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"\\\\\\$\\$var\\\\\" | \\\\\\$SED \\\\\"\\\\\\$sed_quote_subst\\\\\"\\\\\\`\\\\\\\\\\\\\"\"\n      ;;\n    *)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\$\\$var\\\\\\\\\\\\\"\"\n      ;;\n    esac\ndone\n\n# Double-quote double-evaled strings.\nfor var in reload_cmds \\\nold_postinstall_cmds \\\nold_postuninstall_cmds \\\nold_archive_cmds \\\nextract_expsyms_cmds \\\nold_archive_from_new_cmds \\\nold_archive_from_expsyms_cmds \\\narchive_cmds \\\narchive_expsym_cmds \\\nmodule_cmds \\\nmodule_expsym_cmds \\\nexport_symbols_cmds \\\nprelink_cmds \\\npostinstall_cmds \\\npostuninstall_cmds \\\nfinish_cmds \\\nsys_lib_search_path_spec \\\nsys_lib_dlsearch_path_spec \\\nreload_cmds_D \\\nold_archive_cmds_D \\\nold_archive_from_new_cmds_D \\\nold_archive_from_expsyms_cmds_D \\\narchive_cmds_D \\\narchive_expsym_cmds_D \\\nmodule_cmds_D \\\nmodule_expsym_cmds_D \\\nexport_symbols_cmds_D \\\nprelink_cmds_D; do\n    case \\`eval \\\\\\\\\\$ECHO \\\\\\\\\"\"\\\\\\\\\\$\\$var\"\\\\\\\\\"\\` in\n    *[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"\\\\\\$\\$var\\\\\" | \\\\\\$SED -e \\\\\"\\\\\\$double_quote_subst\\\\\" -e \\\\\"\\\\\\$sed_quote_subst\\\\\" -e \\\\\"\\\\\\$delay_variable_subst\\\\\"\\\\\\`\\\\\\\\\\\\\"\"\n      ;;\n    *)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\$\\$var\\\\\\\\\\\\\"\"\n      ;;\n    esac\ndone\n\nac_aux_dir='$ac_aux_dir'\nxsi_shell='$xsi_shell'\nlt_shell_append='$lt_shell_append'\n\n# See if we are running on zsh, and set the options which allow our\n# commands through without removal of \\ escapes INIT.\nif test -n \"\\${ZSH_VERSION+set}\" ; then\n   setopt NO_GLOB_SUBST\nfi\n\n\n    PACKAGE='$PACKAGE'\n    VERSION='$VERSION'\n    TIMESTAMP='$TIMESTAMP'\n    RM='$RM'\n    ofile='$ofile'\n\n\n\n\n\n\n# Variables needed in config.status (file generation) which aren't already\n# passed by autoconf.\nSUBDIRS=\"$SUBDIRS\"\n\n\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n\n# Handling of arguments.\nfor ac_config_target in $ac_config_targets\ndo\n  case $ac_config_target in\n    \"config.h\") CONFIG_HEADERS=\"$CONFIG_HEADERS config.h\" ;;\n    \"default-1\") CONFIG_COMMANDS=\"$CONFIG_COMMANDS default-1\" ;;\n    \"libtool\") CONFIG_COMMANDS=\"$CONFIG_COMMANDS libtool\" ;;\n    \"Makefile\") CONFIG_FILES=\"$CONFIG_FILES Makefile\" ;;\n    \"src/Makefile\") CONFIG_FILES=\"$CONFIG_FILES src/Makefile\" ;;\n    \"libdruntime/Makefile\") CONFIG_FILES=\"$CONFIG_FILES libdruntime/Makefile\" ;;\n    \"testsuite/Makefile\") CONFIG_FILES=\"$CONFIG_FILES testsuite/Makefile\" ;;\n    \"libdruntime/gcc/config.d\") CONFIG_FILES=\"$CONFIG_FILES libdruntime/gcc/config.d\" ;;\n    \"libdruntime/gcc/libbacktrace.d\") CONFIG_FILES=\"$CONFIG_FILES libdruntime/gcc/libbacktrace.d\" ;;\n    \"src/libgphobos.spec\") CONFIG_FILES=\"$CONFIG_FILES src/libgphobos.spec\" ;;\n    \"testsuite/testsuite_flags\") CONFIG_FILES=\"$CONFIG_FILES testsuite/testsuite_flags\" ;;\n    \"default\") CONFIG_COMMANDS=\"$CONFIG_COMMANDS default\" ;;\n\n  *) as_fn_error \"invalid argument: \\`$ac_config_target'\" \"$LINENO\" 5;;\n  esac\ndone\n\n\n# If the user did not use the arguments to specify the items to instantiate,\n# then the envvar interface is used.  Set only those that are not.\n# We use the long form for the default assignment because of an extremely\n# bizarre bug on SunOS 4.1.3.\nif $ac_need_defaults; then\n  test \"${CONFIG_FILES+set}\" = set || CONFIG_FILES=$config_files\n  test \"${CONFIG_HEADERS+set}\" = set || CONFIG_HEADERS=$config_headers\n  test \"${CONFIG_COMMANDS+set}\" = set || CONFIG_COMMANDS=$config_commands\nfi\n\n# Have a temporary directory for convenience.  Make it in the build tree\n# simply because there is no reason against having it here, and in addition,\n# creating and moving files from /tmp can sometimes cause problems.\n# Hook for its removal unless debugging.\n# Note that there is a small window in which the directory will not be cleaned:\n# after its creation but before its name has been assigned to `$tmp'.\n$debug ||\n{\n  tmp=\n  trap 'exit_status=$?\n  { test -z \"$tmp\" || test ! -d \"$tmp\" || rm -fr \"$tmp\"; } && exit $exit_status\n' 0\n  trap 'as_fn_exit 1' 1 2 13 15\n}\n# Create a (secure) tmp directory for tmp files.\n\n{\n  tmp=`(umask 077 && mktemp -d \"./confXXXXXX\") 2>/dev/null` &&\n  test -n \"$tmp\" && test -d \"$tmp\"\n}  ||\n{\n  tmp=./conf$$-$RANDOM\n  (umask 077 && mkdir \"$tmp\")\n} || as_fn_error \"cannot create a temporary directory in .\" \"$LINENO\" 5\n\n# Set up the scripts for CONFIG_FILES section.\n# No need to generate them if there are no CONFIG_FILES.\n# This happens for instance with `./config.status config.h'.\nif test -n \"$CONFIG_FILES\"; then\n\n\nac_cr=`echo X | tr X '\\015'`\n# On cygwin, bash can eat \\r inside `` if the user requested igncr.\n# But we know of no other shell where ac_cr would be empty at this\n# point, so we can use a bashism as a fallback.\nif test \"x$ac_cr\" = x; then\n  eval ac_cr=\\$\\'\\\\r\\'\nfi\nac_cs_awk_cr=`$AWK 'BEGIN { print \"a\\rb\" }' </dev/null 2>/dev/null`\nif test \"$ac_cs_awk_cr\" = \"a${ac_cr}b\"; then\n  ac_cs_awk_cr='\\r'\nelse\n  ac_cs_awk_cr=$ac_cr\nfi\n\necho 'BEGIN {' >\"$tmp/subs1.awk\" &&\n_ACEOF\n\n\n{\n  echo \"cat >conf$$subs.awk <<_ACEOF\" &&\n  echo \"$ac_subst_vars\" | sed 's/.*/&!$&$ac_delim/' &&\n  echo \"_ACEOF\"\n} >conf$$subs.sh ||\n  as_fn_error \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\nac_delim_num=`echo \"$ac_subst_vars\" | grep -c '$'`\nac_delim='%!_!# '\nfor ac_last_try in false false false false false :; do\n  . ./conf$$subs.sh ||\n    as_fn_error \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\n\n  ac_delim_n=`sed -n \"s/.*$ac_delim\\$/X/p\" conf$$subs.awk | grep -c X`\n  if test $ac_delim_n = $ac_delim_num; then\n    break\n  elif $ac_last_try; then\n    as_fn_error \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\n  else\n    ac_delim=\"$ac_delim!$ac_delim _$ac_delim!! \"\n  fi\ndone\nrm -f conf$$subs.sh\n\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\ncat >>\"\\$tmp/subs1.awk\" <<\\\\_ACAWK &&\n_ACEOF\nsed -n '\nh\ns/^/S[\"/; s/!.*/\"]=/\np\ng\ns/^[^!]*!//\n:repl\nt repl\ns/'\"$ac_delim\"'$//\nt delim\n:nl\nh\ns/\\(.\\{148\\}\\).*/\\1/\nt more1\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\\\\n\"\\\\/\np\nn\nb repl\n:more1\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"\\\\/\np\ng\ns/.\\{148\\}//\nt nl\n:delim\nh\ns/\\(.\\{148\\}\\).*/\\1/\nt more2\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"/\np\nb\n:more2\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"\\\\/\np\ng\ns/.\\{148\\}//\nt delim\n' <conf$$subs.awk | sed '\n/^[^\"\"]/{\n  N\n  s/\\n//\n}\n' >>$CONFIG_STATUS || ac_write_fail=1\nrm -f conf$$subs.awk\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n_ACAWK\ncat >>\"\\$tmp/subs1.awk\" <<_ACAWK &&\n  for (key in S) S_is_set[key] = 1\n  FS = \"\u0007\"\n\n}\n{\n  line = $ 0\n  nfields = split(line, field, \"@\")\n  substed = 0\n  len = length(field[1])\n  for (i = 2; i < nfields; i++) {\n    key = field[i]\n    keylen = length(key)\n    if (S_is_set[key]) {\n      value = S[key]\n      line = substr(line, 1, len) \"\" value \"\" substr(line, len + keylen + 3)\n      len += length(value) + length(field[++i])\n      substed = 1\n    } else\n      len += 1 + keylen\n  }\n\n  print line\n}\n\n_ACAWK\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nif sed \"s/$ac_cr//\" < /dev/null > /dev/null 2>&1; then\n  sed \"s/$ac_cr\\$//; s/$ac_cr/$ac_cs_awk_cr/g\"\nelse\n  cat\nfi < \"$tmp/subs1.awk\" > \"$tmp/subs.awk\" \\\n  || as_fn_error \"could not setup config files machinery\" \"$LINENO\" 5\n_ACEOF\n\n# VPATH may cause trouble with some makes, so we remove $(srcdir),\n# ${srcdir} and @srcdir@ from VPATH if srcdir is \".\", strip leading and\n# trailing colons and then remove the whole line if VPATH becomes empty\n# (actually we leave an empty line to preserve line numbers).\nif test \"x$srcdir\" = x.; then\n  ac_vpsub='/^[\t ]*VPATH[\t ]*=/{\ns/:*\\$(srcdir):*/:/\ns/:*\\${srcdir}:*/:/\ns/:*@srcdir@:*/:/\ns/^\\([^=]*=[\t ]*\\):*/\\1/\ns/:*$//\ns/^[^=]*=[\t ]*$//\n}'\nfi\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nfi # test -n \"$CONFIG_FILES\"\n\n# Set up the scripts for CONFIG_HEADERS section.\n# No need to generate them if there are no CONFIG_HEADERS.\n# This happens for instance with `./config.status Makefile'.\nif test -n \"$CONFIG_HEADERS\"; then\ncat >\"$tmp/defines.awk\" <<\\_ACAWK ||\nBEGIN {\n_ACEOF\n\n# Transform confdefs.h into an awk script `defines.awk', embedded as\n# here-document in config.status, that substitutes the proper values into\n# config.h.in to produce config.h.\n\n# Create a delimiter string that does not exist in confdefs.h, to ease\n# handling of long lines.\nac_delim='%!_!# '\nfor ac_last_try in false false :; do\n  ac_t=`sed -n \"/$ac_delim/p\" confdefs.h`\n  if test -z \"$ac_t\"; then\n    break\n  elif $ac_last_try; then\n    as_fn_error \"could not make $CONFIG_HEADERS\" \"$LINENO\" 5\n  else\n    ac_delim=\"$ac_delim!$ac_delim _$ac_delim!! \"\n  fi\ndone\n\n# For the awk script, D is an array of macro values keyed by name,\n# likewise P contains macro parameters if any.  Preserve backslash\n# newline sequences.\n\nac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*\nsed -n '\ns/.\\{148\\}/&'\"$ac_delim\"'/g\nt rset\n:rset\ns/^[\t ]*#[\t ]*define[\t ][\t ]*/ /\nt def\nd\n:def\ns/\\\\$//\nt bsnl\ns/[\"\\\\]/\\\\&/g\ns/^ \\('\"$ac_word_re\"'\\)\\(([^()]*)\\)[\t ]*\\(.*\\)/P[\"\\1\"]=\"\\2\"\\\nD[\"\\1\"]=\" \\3\"/p\ns/^ \\('\"$ac_word_re\"'\\)[\t ]*\\(.*\\)/D[\"\\1\"]=\" \\2\"/p\nd\n:bsnl\ns/[\"\\\\]/\\\\&/g\ns/^ \\('\"$ac_word_re\"'\\)\\(([^()]*)\\)[\t ]*\\(.*\\)/P[\"\\1\"]=\"\\2\"\\\nD[\"\\1\"]=\" \\3\\\\\\\\\\\\n\"\\\\/p\nt cont\ns/^ \\('\"$ac_word_re\"'\\)[\t ]*\\(.*\\)/D[\"\\1\"]=\" \\2\\\\\\\\\\\\n\"\\\\/p\nt cont\nd\n:cont\nn\ns/.\\{148\\}/&'\"$ac_delim\"'/g\nt clear\n:clear\ns/\\\\$//\nt bsnlc\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"/p\nd\n:bsnlc\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\\\\\\\\\\\\n\"\\\\/p\nb cont\n' <confdefs.h | sed '\ns/'\"$ac_delim\"'/\"\\\\\\\n\"/g' >>$CONFIG_STATUS || ac_write_fail=1\n\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n  for (key in D) D_is_set[key] = 1\n  FS = \"\u0007\"\n}\n/^[\\t ]*#[\\t ]*(define|undef)[\\t ]+$ac_word_re([\\t (]|\\$)/ {\n  line = \\$ 0\n  split(line, arg, \" \")\n  if (arg[1] == \"#\") {\n    defundef = arg[2]\n    mac1 = arg[3]\n  } else {\n    defundef = substr(arg[1], 2)\n    mac1 = arg[2]\n  }\n  split(mac1, mac2, \"(\") #)\n  macro = mac2[1]\n  prefix = substr(line, 1, index(line, defundef) - 1)\n  if (D_is_set[macro]) {\n    # Preserve the white space surrounding the \"#\".\n    print prefix \"define\", macro P[macro] D[macro]\n    next\n  } else {\n    # Replace #undef with comments.  This is necessary, for example,\n    # in the case of _POSIX_SOURCE, which is predefined and required\n    # on some systems where configure will not decide to define it.\n    if (defundef == \"undef\") {\n      print \"/*\", prefix defundef, macro, \"*/\"\n      next\n    }\n  }\n}\n{ print }\n_ACAWK\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n  as_fn_error \"could not setup config headers machinery\" \"$LINENO\" 5\nfi # test -n \"$CONFIG_HEADERS\"\n\n\neval set X \"  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS\"\nshift\nfor ac_tag\ndo\n  case $ac_tag in\n  :[FHLC]) ac_mode=$ac_tag; continue;;\n  esac\n  case $ac_mode$ac_tag in\n  :[FHL]*:*);;\n  :L* | :C*:*) as_fn_error \"invalid tag \\`$ac_tag'\" \"$LINENO\" 5;;\n  :[FH]-) ac_tag=-:-;;\n  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;\n  esac\n  ac_save_IFS=$IFS\n  IFS=:\n  set x $ac_tag\n  IFS=$ac_save_IFS\n  shift\n  ac_file=$1\n  shift\n\n  case $ac_mode in\n  :L) ac_source=$1;;\n  :[FH])\n    ac_file_inputs=\n    for ac_f\n    do\n      case $ac_f in\n      -) ac_f=\"$tmp/stdin\";;\n      *) # Look for the file first in the build tree, then in the source tree\n\t # (if the path is not absolute).  The absolute path cannot be DOS-style,\n\t # because $ac_f cannot contain `:'.\n\t test -f \"$ac_f\" ||\n\t   case $ac_f in\n\t   [\\\\/$]*) false;;\n\t   *) test -f \"$srcdir/$ac_f\" && ac_f=\"$srcdir/$ac_f\";;\n\t   esac ||\n\t   as_fn_error \"cannot find input file: \\`$ac_f'\" \"$LINENO\" 5;;\n      esac\n      case $ac_f in *\\'*) ac_f=`$as_echo \"$ac_f\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; esac\n      as_fn_append ac_file_inputs \" '$ac_f'\"\n    done\n\n    # Let's still pretend it is `configure' which instantiates (i.e., don't\n    # use $as_me), people would be surprised to read:\n    #    /* config.h.  Generated by config.status.  */\n    configure_input='Generated from '`\n\t  $as_echo \"$*\" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'\n\t`' by configure.'\n    if test x\"$ac_file\" != x-; then\n      configure_input=\"$ac_file.  $configure_input\"\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: creating $ac_file\" >&5\n$as_echo \"$as_me: creating $ac_file\" >&6;}\n    fi\n    # Neutralize special characters interpreted by sed in replacement strings.\n    case $configure_input in #(\n    *\\&* | *\\|* | *\\\\* )\n       ac_sed_conf_input=`$as_echo \"$configure_input\" |\n       sed 's/[\\\\\\\\&|]/\\\\\\\\&/g'`;; #(\n    *) ac_sed_conf_input=$configure_input;;\n    esac\n\n    case $ac_tag in\n    *:-:* | *:-) cat >\"$tmp/stdin\" \\\n      || as_fn_error \"could not create $ac_file\" \"$LINENO\" 5 ;;\n    esac\n    ;;\n  esac\n\n  ac_dir=`$as_dirname -- \"$ac_file\" ||\n$as_expr X\"$ac_file\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)$' \\| \\\n\t X\"$ac_file\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$ac_file\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n  as_dir=\"$ac_dir\"; as_fn_mkdir_p\n  ac_builddir=.\n\ncase \"$ac_dir\" in\n.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;\n*)\n  ac_dir_suffix=/`$as_echo \"$ac_dir\" | sed 's|^\\.[\\\\/]||'`\n  # A \"..\" for each directory in $ac_dir_suffix.\n  ac_top_builddir_sub=`$as_echo \"$ac_dir_suffix\" | sed 's|/[^\\\\/]*|/..|g;s|/||'`\n  case $ac_top_builddir_sub in\n  \"\") ac_top_builddir_sub=. ac_top_build_prefix= ;;\n  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;\n  esac ;;\nesac\nac_abs_top_builddir=$ac_pwd\nac_abs_builddir=$ac_pwd$ac_dir_suffix\n# for backward compatibility:\nac_top_builddir=$ac_top_build_prefix\n\ncase $srcdir in\n  .)  # We are building in place.\n    ac_srcdir=.\n    ac_top_srcdir=$ac_top_builddir_sub\n    ac_abs_top_srcdir=$ac_pwd ;;\n  [\\\\/]* | ?:[\\\\/]* )  # Absolute name.\n    ac_srcdir=$srcdir$ac_dir_suffix;\n    ac_top_srcdir=$srcdir\n    ac_abs_top_srcdir=$srcdir ;;\n  *) # Relative name.\n    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix\n    ac_top_srcdir=$ac_top_build_prefix$srcdir\n    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;\nesac\nac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix\n\n\n  case $ac_mode in\n  :F)\n  #\n  # CONFIG_FILE\n  #\n\n  case $INSTALL in\n  [\\\\/$]* | ?:[\\\\/]* ) ac_INSTALL=$INSTALL ;;\n  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;\n  esac\n  ac_MKDIR_P=$MKDIR_P\n  case $MKDIR_P in\n  [\\\\/$]* | ?:[\\\\/]* ) ;;\n  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;\n  esac\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# If the template does not know about datarootdir, expand it.\n# FIXME: This hack should be removed a few years after 2.60.\nac_datarootdir_hack=; ac_datarootdir_seen=\nac_sed_dataroot='\n/datarootdir/ {\n  p\n  q\n}\n/@datadir@/p\n/@docdir@/p\n/@infodir@/p\n/@localedir@/p\n/@mandir@/p'\ncase `eval \"sed -n \\\"\\$ac_sed_dataroot\\\" $ac_file_inputs\"` in\n*datarootdir*) ac_datarootdir_seen=yes;;\n*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting\" >&5\n$as_echo \"$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting\" >&2;}\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n  ac_datarootdir_hack='\n  s&@datadir@&$datadir&g\n  s&@docdir@&$docdir&g\n  s&@infodir@&$infodir&g\n  s&@localedir@&$localedir&g\n  s&@mandir@&$mandir&g\n  s&\\\\\\${datarootdir}&$datarootdir&g' ;;\nesac\n_ACEOF\n\n# Neutralize VPATH when `$srcdir' = `.'.\n# Shell code in configure.ac might set extrasub.\n# FIXME: do we really want to maintain this feature?\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nac_sed_extra=\"$ac_vpsub\n$extrasub\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n:t\n/@[a-zA-Z_][a-zA-Z_0-9]*@/!b\ns|@configure_input@|$ac_sed_conf_input|;t t\ns&@top_builddir@&$ac_top_builddir_sub&;t t\ns&@top_build_prefix@&$ac_top_build_prefix&;t t\ns&@srcdir@&$ac_srcdir&;t t\ns&@abs_srcdir@&$ac_abs_srcdir&;t t\ns&@top_srcdir@&$ac_top_srcdir&;t t\ns&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t\ns&@builddir@&$ac_builddir&;t t\ns&@abs_builddir@&$ac_abs_builddir&;t t\ns&@abs_top_builddir@&$ac_abs_top_builddir&;t t\ns&@INSTALL@&$ac_INSTALL&;t t\ns&@MKDIR_P@&$ac_MKDIR_P&;t t\n$ac_datarootdir_hack\n\"\neval sed \\\"\\$ac_sed_extra\\\" \"$ac_file_inputs\" | $AWK -f \"$tmp/subs.awk\" >$tmp/out \\\n  || as_fn_error \"could not create $ac_file\" \"$LINENO\" 5\n\ntest -z \"$ac_datarootdir_hack$ac_datarootdir_seen\" &&\n  { ac_out=`sed -n '/\\${datarootdir}/p' \"$tmp/out\"`; test -n \"$ac_out\"; } &&\n  { ac_out=`sed -n '/^[\t ]*datarootdir[\t ]*:*=/p' \"$tmp/out\"`; test -z \"$ac_out\"; } &&\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \\`datarootdir'\nwhich seems to be undefined.  Please make sure it is defined.\" >&5\n$as_echo \"$as_me: WARNING: $ac_file contains a reference to the variable \\`datarootdir'\nwhich seems to be undefined.  Please make sure it is defined.\" >&2;}\n\n  rm -f \"$tmp/stdin\"\n  case $ac_file in\n  -) cat \"$tmp/out\" && rm -f \"$tmp/out\";;\n  *) rm -f \"$ac_file\" && mv \"$tmp/out\" \"$ac_file\";;\n  esac \\\n  || as_fn_error \"could not create $ac_file\" \"$LINENO\" 5\n ;;\n  :H)\n  #\n  # CONFIG_HEADER\n  #\n  if test x\"$ac_file\" != x-; then\n    {\n      $as_echo \"/* $configure_input  */\" \\\n      && eval '$AWK -f \"$tmp/defines.awk\"' \"$ac_file_inputs\"\n    } >\"$tmp/config.h\" \\\n      || as_fn_error \"could not create $ac_file\" \"$LINENO\" 5\n    if diff \"$ac_file\" \"$tmp/config.h\" >/dev/null 2>&1; then\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: $ac_file is unchanged\" >&5\n$as_echo \"$as_me: $ac_file is unchanged\" >&6;}\n    else\n      rm -f \"$ac_file\"\n      mv \"$tmp/config.h\" \"$ac_file\" \\\n\t|| as_fn_error \"could not create $ac_file\" \"$LINENO\" 5\n    fi\n  else\n    $as_echo \"/* $configure_input  */\" \\\n      && eval '$AWK -f \"$tmp/defines.awk\"' \"$ac_file_inputs\" \\\n      || as_fn_error \"could not create -\" \"$LINENO\" 5\n  fi\n# Compute \"$ac_file\"'s index in $config_headers.\n_am_arg=\"$ac_file\"\n_am_stamp_count=1\nfor _am_header in $config_headers :; do\n  case $_am_header in\n    $_am_arg | $_am_arg:* )\n      break ;;\n    * )\n      _am_stamp_count=`expr $_am_stamp_count + 1` ;;\n  esac\ndone\necho \"timestamp for $_am_arg\" >`$as_dirname -- \"$_am_arg\" ||\n$as_expr X\"$_am_arg\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$_am_arg\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$_am_arg\" : 'X\\(//\\)$' \\| \\\n\t X\"$_am_arg\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$_am_arg\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`/stamp-h$_am_stamp_count\n ;;\n\n  :C)  { $as_echo \"$as_me:${as_lineno-$LINENO}: executing $ac_file commands\" >&5\n$as_echo \"$as_me: executing $ac_file commands\" >&6;}\n ;;\n  esac\n\n\n  case $ac_file$ac_mode in\n    \"default-1\":C)\n# Only add multilib support code if we just rebuilt the top-level\n# Makefile.\ncase \" $CONFIG_FILES \" in\n *\" Makefile \"*)\n   ac_file=Makefile . ${multi_basedir}/config-ml.in\n   ;;\nesac ;;\n    \"libtool\":C)\n\n    # See if we are running on zsh, and set the options which allow our\n    # commands through without removal of \\ escapes.\n    if test -n \"${ZSH_VERSION+set}\" ; then\n      setopt NO_GLOB_SUBST\n    fi\n\n    cfgfile=\"${ofile}T\"\n    trap \"$RM \\\"$cfgfile\\\"; exit 1\" 1 2 15\n    $RM \"$cfgfile\"\n\n    cat <<_LT_EOF >> \"$cfgfile\"\n#! $SHELL\n\n# `$ECHO \"$ofile\" | sed 's%^.*/%%'` - Provide generalized library-building support services.\n# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION\n# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:\n# NOTE: Changes made to this file will be lost: look at ltmain.sh.\n#\n#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,\n#                 2006, 2007, 2008, 2009 Free Software Foundation, Inc.\n#   Written by Gordon Matzigkeit, 1996\n#\n#   This file is part of GNU Libtool.\n#\n# GNU Libtool is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# As a special exception to the GNU General Public License,\n# if you distribute this file as part of a program or library that\n# is built using GNU Libtool, you may include this file under the\n# same distribution terms that you use for the rest of that program.\n#\n# GNU Libtool is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GNU Libtool; see the file COPYING.  If not, a copy\n# can be downloaded from http://www.gnu.org/licenses/gpl.html, or\n# obtained by writing to the Free Software Foundation, Inc.,\n# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n\n\n# The names of the tagged configurations supported by this script.\navailable_tags=\"D \"\n\n# ### BEGIN LIBTOOL CONFIG\n\n# Which release of libtool.m4 was used?\nmacro_version=$macro_version\nmacro_revision=$macro_revision\n\n# Whether or not to build shared libraries.\nbuild_libtool_libs=$enable_shared\n\n# Whether or not to build static libraries.\nbuild_old_libs=$enable_static\n\n# What type of objects to build.\npic_mode=$pic_mode\n\n# Whether or not to optimize for fast installation.\nfast_install=$enable_fast_install\n\n# Shell to use when invoking shell scripts.\nSHELL=$lt_SHELL\n\n# An echo program that protects backslashes.\nECHO=$lt_ECHO\n\n# The host system.\nhost_alias=$host_alias\nhost=$host\nhost_os=$host_os\n\n# The build system.\nbuild_alias=$build_alias\nbuild=$build\nbuild_os=$build_os\n\n# A sed program that does not truncate output.\nSED=$lt_SED\n\n# Sed that helps us avoid accidentally triggering echo(1) options like -n.\nXsed=\"\\$SED -e 1s/^X//\"\n\n# A grep program that handles long lines.\nGREP=$lt_GREP\n\n# An ERE matcher.\nEGREP=$lt_EGREP\n\n# A literal string matcher.\nFGREP=$lt_FGREP\n\n# A BSD- or MS-compatible name lister.\nNM=$lt_NM\n\n# Whether we need soft or hard links.\nLN_S=$lt_LN_S\n\n# What is the maximum length of a command?\nmax_cmd_len=$max_cmd_len\n\n# Object file suffix (normally \"o\").\nobjext=$ac_objext\n\n# Executable file suffix (normally \"\").\nexeext=$exeext\n\n# whether the shell understands \"unset\".\nlt_unset=$lt_unset\n\n# turn spaces into newlines.\nSP2NL=$lt_lt_SP2NL\n\n# turn newlines into spaces.\nNL2SP=$lt_lt_NL2SP\n\n# An object symbol dumper.\nOBJDUMP=$lt_OBJDUMP\n\n# Method to check whether dependent libraries are shared objects.\ndeplibs_check_method=$lt_deplibs_check_method\n\n# Command to use when deplibs_check_method == \"file_magic\".\nfile_magic_cmd=$lt_file_magic_cmd\n\n# The archiver.\nAR=$lt_AR\nAR_FLAGS=$lt_AR_FLAGS\n\n# A symbol stripping program.\nSTRIP=$lt_STRIP\n\n# Commands used to install an old-style archive.\nRANLIB=$lt_RANLIB\nold_postinstall_cmds=$lt_old_postinstall_cmds\nold_postuninstall_cmds=$lt_old_postuninstall_cmds\n\n# Whether to use a lock for old archive extraction.\nlock_old_archive_extraction=$lock_old_archive_extraction\n\n# A C compiler.\nLTCC=$lt_CC\n\n# LTCC compiler flags.\nLTCFLAGS=$lt_CFLAGS\n\n# Take the output of nm and produce a listing of raw symbols and C names.\nglobal_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe\n\n# Transform the output of nm in a proper C declaration.\nglobal_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl\n\n# Transform the output of nm in a C name address pair.\nglobal_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address\n\n# Transform the output of nm in a C name address pair when lib prefix is needed.\nglobal_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix\n\n# The name of the directory that contains temporary libtool files.\nobjdir=$objdir\n\n# Used to examine libraries when file_magic_cmd begins with \"file\".\nMAGIC_CMD=$MAGIC_CMD\n\n# Must we lock files when doing compilation?\nneed_locks=$lt_need_locks\n\n# Tool to manipulate archived DWARF debug symbol files on Mac OS X.\nDSYMUTIL=$lt_DSYMUTIL\n\n# Tool to change global to local symbols on Mac OS X.\nNMEDIT=$lt_NMEDIT\n\n# Tool to manipulate fat objects and archives on Mac OS X.\nLIPO=$lt_LIPO\n\n# ldd/readelf like tool for Mach-O binaries on Mac OS X.\nOTOOL=$lt_OTOOL\n\n# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.\nOTOOL64=$lt_OTOOL64\n\n# Old archive suffix (normally \"a\").\nlibext=$libext\n\n# Shared library suffix (normally \".so\").\nshrext_cmds=$lt_shrext_cmds\n\n# The commands to extract the exported symbol list from a shared archive.\nextract_expsyms_cmds=$lt_extract_expsyms_cmds\n\n# Variables whose values should be saved in libtool wrapper scripts and\n# restored at link time.\nvariables_saved_for_relink=$lt_variables_saved_for_relink\n\n# Do we need the \"lib\" prefix for modules?\nneed_lib_prefix=$need_lib_prefix\n\n# Do we need a version for libraries?\nneed_version=$need_version\n\n# Library versioning type.\nversion_type=$version_type\n\n# Shared library runtime path variable.\nrunpath_var=$runpath_var\n\n# Shared library path variable.\nshlibpath_var=$shlibpath_var\n\n# Is shlibpath searched before the hard-coded library search path?\nshlibpath_overrides_runpath=$shlibpath_overrides_runpath\n\n# Format of library name prefix.\nlibname_spec=$lt_libname_spec\n\n# List of archive names.  First name is the real one, the rest are links.\n# The last name is the one that the linker finds with -lNAME\nlibrary_names_spec=$lt_library_names_spec\n\n# The coded name of the library, if different from the real name.\nsoname_spec=$lt_soname_spec\n\n# Permission mode override for installation of shared libraries.\ninstall_override_mode=$lt_install_override_mode\n\n# Command to use after installation of a shared archive.\npostinstall_cmds=$lt_postinstall_cmds\n\n# Command to use after uninstallation of a shared archive.\npostuninstall_cmds=$lt_postuninstall_cmds\n\n# Commands used to finish a libtool library installation in a directory.\nfinish_cmds=$lt_finish_cmds\n\n# As \"finish_cmds\", except a single script fragment to be evaled but\n# not shown.\nfinish_eval=$lt_finish_eval\n\n# Whether we should hardcode library paths into libraries.\nhardcode_into_libs=$hardcode_into_libs\n\n# Compile-time system search path for libraries.\nsys_lib_search_path_spec=$lt_sys_lib_search_path_spec\n\n# Run-time system search path for libraries.\nsys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec\n\n# Whether dlopen is supported.\ndlopen_support=$enable_dlopen\n\n# Whether dlopen of programs is supported.\ndlopen_self=$enable_dlopen_self\n\n# Whether dlopen of statically linked programs is supported.\ndlopen_self_static=$enable_dlopen_self_static\n\n# Commands to strip libraries.\nold_striplib=$lt_old_striplib\nstriplib=$lt_striplib\n\n\n# The linker used to build libraries.\nLD=$lt_LD\n\n# How to create reloadable object files.\nreload_flag=$lt_reload_flag\nreload_cmds=$lt_reload_cmds\n\n# Commands used to build an old-style archive.\nold_archive_cmds=$lt_old_archive_cmds\n\n# A language specific compiler.\nCC=$lt_compiler\n\n# Is the compiler the GNU compiler?\nwith_gcc=$GCC\n\n# Compiler flag to turn off builtin functions.\nno_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag\n\n# How to pass a linker flag through the compiler.\nwl=$lt_lt_prog_compiler_wl\n\n# Additional compiler flags for building library objects.\npic_flag=$lt_lt_prog_compiler_pic\n\n# Compiler flag to prevent dynamic linking.\nlink_static_flag=$lt_lt_prog_compiler_static\n\n# Does compiler simultaneously support -c and -o options?\ncompiler_c_o=$lt_lt_cv_prog_compiler_c_o\n\n# Whether or not to add -lc for building shared libraries.\nbuild_libtool_need_lc=$archive_cmds_need_lc\n\n# Whether or not to disallow shared libs when runtime libs are static.\nallow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes\n\n# Compiler flag to allow reflexive dlopens.\nexport_dynamic_flag_spec=$lt_export_dynamic_flag_spec\n\n# Compiler flag to generate shared objects directly from archives.\nwhole_archive_flag_spec=$lt_whole_archive_flag_spec\n\n# Whether the compiler copes with passing no objects directly.\ncompiler_needs_object=$lt_compiler_needs_object\n\n# Create an old-style archive from a shared archive.\nold_archive_from_new_cmds=$lt_old_archive_from_new_cmds\n\n# Create a temporary old-style archive to link instead of a shared archive.\nold_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds\n\n# Commands used to build a shared archive.\narchive_cmds=$lt_archive_cmds\narchive_expsym_cmds=$lt_archive_expsym_cmds\n\n# Commands used to build a loadable module if different from building\n# a shared archive.\nmodule_cmds=$lt_module_cmds\nmodule_expsym_cmds=$lt_module_expsym_cmds\n\n# Whether we are building with GNU ld or not.\nwith_gnu_ld=$lt_with_gnu_ld\n\n# Flag that allows shared libraries with undefined symbols to be built.\nallow_undefined_flag=$lt_allow_undefined_flag\n\n# Flag that enforces no undefined symbols.\nno_undefined_flag=$lt_no_undefined_flag\n\n# Flag to hardcode \\$libdir into a binary during linking.\n# This must work even if \\$libdir does not exist\nhardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec\n\n# If ld is used when linking, flag to hardcode \\$libdir into a binary\n# during linking.  This must work even if \\$libdir does not exist.\nhardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld\n\n# Whether we need a single \"-rpath\" flag with a separated argument.\nhardcode_libdir_separator=$lt_hardcode_libdir_separator\n\n# Set to \"yes\" if using DIR/libNAME\\${shared_ext} during linking hardcodes\n# DIR into the resulting binary.\nhardcode_direct=$hardcode_direct\n\n# Set to \"yes\" if using DIR/libNAME\\${shared_ext} during linking hardcodes\n# DIR into the resulting binary and the resulting library dependency is\n# \"absolute\",i.e impossible to change by setting \\${shlibpath_var} if the\n# library is relocated.\nhardcode_direct_absolute=$hardcode_direct_absolute\n\n# Set to \"yes\" if using the -LDIR flag during linking hardcodes DIR\n# into the resulting binary.\nhardcode_minus_L=$hardcode_minus_L\n\n# Set to \"yes\" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR\n# into the resulting binary.\nhardcode_shlibpath_var=$hardcode_shlibpath_var\n\n# Set to \"yes\" if building a shared library automatically hardcodes DIR\n# into the library and all subsequent libraries and executables linked\n# against it.\nhardcode_automatic=$hardcode_automatic\n\n# Set to yes if linker adds runtime paths of dependent libraries\n# to runtime path list.\ninherit_rpath=$inherit_rpath\n\n# Whether libtool must link a program against all its dependency libraries.\nlink_all_deplibs=$link_all_deplibs\n\n# Fix the shell variable \\$srcfile for the compiler.\nfix_srcfile_path=$lt_fix_srcfile_path\n\n# Set to \"yes\" if exported symbols are required.\nalways_export_symbols=$always_export_symbols\n\n# The commands to list exported symbols.\nexport_symbols_cmds=$lt_export_symbols_cmds\n\n# Symbols that should not be listed in the preloaded symbols.\nexclude_expsyms=$lt_exclude_expsyms\n\n# Symbols that must always be exported.\ninclude_expsyms=$lt_include_expsyms\n\n# Commands necessary for linking programs (against libraries) with templates.\nprelink_cmds=$lt_prelink_cmds\n\n# Specify filename containing input files.\nfile_list_spec=$lt_file_list_spec\n\n# How to hardcode a shared library path into an executable.\nhardcode_action=$hardcode_action\n\n# ### END LIBTOOL CONFIG\n\n_LT_EOF\n\n  case $host_os in\n  aix3*)\n    cat <<\\_LT_EOF >> \"$cfgfile\"\n# AIX sometimes has problems with the GCC collect2 program.  For some\n# reason, if we set the COLLECT_NAMES environment variable, the problems\n# vanish in a puff of smoke.\nif test \"X${COLLECT_NAMES+set}\" != Xset; then\n  COLLECT_NAMES=\n  export COLLECT_NAMES\nfi\n_LT_EOF\n    ;;\n  esac\n\n\nltmain=\"$ac_aux_dir/ltmain.sh\"\n\n\n  # We use sed instead of cat because bash on DJGPP gets confused if\n  # if finds mixed CR/LF and LF-only lines.  Since sed operates in\n  # text mode, it properly converts lines to CR/LF.  This bash problem\n  # is reportedly fixed, but why not run on old versions too?\n  sed '/^# Generated shell functions inserted here/q' \"$ltmain\" >> \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\"; exit 1)\n\n  case $xsi_shell in\n  yes)\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_dirname file append nondir_replacement\n# Compute the dirname of FILE.  If nonempty, add APPEND to the result,\n# otherwise set result to NONDIR_REPLACEMENT.\nfunc_dirname ()\n{\n  case ${1} in\n    */*) func_dirname_result=\"${1%/*}${2}\" ;;\n    *  ) func_dirname_result=\"${3}\" ;;\n  esac\n}\n\n# func_basename file\nfunc_basename ()\n{\n  func_basename_result=\"${1##*/}\"\n}\n\n# func_dirname_and_basename file append nondir_replacement\n# perform func_basename and func_dirname in a single function\n# call:\n#   dirname:  Compute the dirname of FILE.  If nonempty,\n#             add APPEND to the result, otherwise set result\n#             to NONDIR_REPLACEMENT.\n#             value returned in \"$func_dirname_result\"\n#   basename: Compute filename of FILE.\n#             value retuned in \"$func_basename_result\"\n# Implementation must be kept synchronized with func_dirname\n# and func_basename. For efficiency, we do not delegate to\n# those functions but instead duplicate the functionality here.\nfunc_dirname_and_basename ()\n{\n  case ${1} in\n    */*) func_dirname_result=\"${1%/*}${2}\" ;;\n    *  ) func_dirname_result=\"${3}\" ;;\n  esac\n  func_basename_result=\"${1##*/}\"\n}\n\n# func_stripname prefix suffix name\n# strip PREFIX and SUFFIX off of NAME.\n# PREFIX and SUFFIX must not contain globbing or regex special\n# characters, hashes, percent signs, but SUFFIX may contain a leading\n# dot (in which case that matches only a dot).\nfunc_stripname ()\n{\n  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\n  # positional parameters, so assign one to ordinary parameter first.\n  func_stripname_result=${3}\n  func_stripname_result=${func_stripname_result#\"${1}\"}\n  func_stripname_result=${func_stripname_result%\"${2}\"}\n}\n\n# func_opt_split\nfunc_opt_split ()\n{\n  func_opt_split_opt=${1%%=*}\n  func_opt_split_arg=${1#*=}\n}\n\n# func_lo2o object\nfunc_lo2o ()\n{\n  case ${1} in\n    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\n    *)    func_lo2o_result=${1} ;;\n  esac\n}\n\n# func_xform libobj-or-source\nfunc_xform ()\n{\n  func_xform_result=${1%.*}.lo\n}\n\n# func_arith arithmetic-term...\nfunc_arith ()\n{\n  func_arith_result=$(( $* ))\n}\n\n# func_len string\n# STRING may not start with a hyphen.\nfunc_len ()\n{\n  func_len_result=${#1}\n}\n\n_LT_EOF\n    ;;\n  *) # Bourne compatible functions.\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_dirname file append nondir_replacement\n# Compute the dirname of FILE.  If nonempty, add APPEND to the result,\n# otherwise set result to NONDIR_REPLACEMENT.\nfunc_dirname ()\n{\n  # Extract subdirectory from the argument.\n  func_dirname_result=`$ECHO \"${1}\" | $SED \"$dirname\"`\n  if test \"X$func_dirname_result\" = \"X${1}\"; then\n    func_dirname_result=\"${3}\"\n  else\n    func_dirname_result=\"$func_dirname_result${2}\"\n  fi\n}\n\n# func_basename file\nfunc_basename ()\n{\n  func_basename_result=`$ECHO \"${1}\" | $SED \"$basename\"`\n}\n\n\n# func_stripname prefix suffix name\n# strip PREFIX and SUFFIX off of NAME.\n# PREFIX and SUFFIX must not contain globbing or regex special\n# characters, hashes, percent signs, but SUFFIX may contain a leading\n# dot (in which case that matches only a dot).\n# func_strip_suffix prefix name\nfunc_stripname ()\n{\n  case ${2} in\n    .*) func_stripname_result=`$ECHO \"${3}\" | $SED \"s%^${1}%%; s%\\\\\\\\${2}\\$%%\"`;;\n    *)  func_stripname_result=`$ECHO \"${3}\" | $SED \"s%^${1}%%; s%${2}\\$%%\"`;;\n  esac\n}\n\n# sed scripts:\nmy_sed_long_opt='1s/^\\(-[^=]*\\)=.*/\\1/;q'\nmy_sed_long_arg='1s/^-[^=]*=//'\n\n# func_opt_split\nfunc_opt_split ()\n{\n  func_opt_split_opt=`$ECHO \"${1}\" | $SED \"$my_sed_long_opt\"`\n  func_opt_split_arg=`$ECHO \"${1}\" | $SED \"$my_sed_long_arg\"`\n}\n\n# func_lo2o object\nfunc_lo2o ()\n{\n  func_lo2o_result=`$ECHO \"${1}\" | $SED \"$lo2o\"`\n}\n\n# func_xform libobj-or-source\nfunc_xform ()\n{\n  func_xform_result=`$ECHO \"${1}\" | $SED 's/\\.[^.]*$/.lo/'`\n}\n\n# func_arith arithmetic-term...\nfunc_arith ()\n{\n  func_arith_result=`expr \"$@\"`\n}\n\n# func_len string\n# STRING may not start with a hyphen.\nfunc_len ()\n{\n  func_len_result=`expr \"$1\" : \".*\" 2>/dev/null || echo $max_cmd_len`\n}\n\n_LT_EOF\nesac\n\ncase $lt_shell_append in\n  yes)\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_append var value\n# Append VALUE to the end of shell variable VAR.\nfunc_append ()\n{\n  eval \"$1+=\\$2\"\n}\n_LT_EOF\n    ;;\n  *)\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_append var value\n# Append VALUE to the end of shell variable VAR.\nfunc_append ()\n{\n  eval \"$1=\\$$1\\$2\"\n}\n\n_LT_EOF\n    ;;\n  esac\n\n\n  sed -n '/^# Generated shell functions inserted here/,$p' \"$ltmain\" >> \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\"; exit 1)\n\n  mv -f \"$cfgfile\" \"$ofile\" ||\n    (rm -f \"$ofile\" && cp \"$cfgfile\" \"$ofile\" && rm -f \"$cfgfile\")\n  chmod +x \"$ofile\"\n\n\n    cat <<_LT_EOF >> \"$ofile\"\n\n# ### BEGIN LIBTOOL TAG CONFIG: D\n\n# The linker used to build libraries.\nLD=$lt_LD_D\n\n# How to create reloadable object files.\nreload_flag=$lt_reload_flag_D\nreload_cmds=$lt_reload_cmds_D\n\n# Commands used to build an old-style archive.\nold_archive_cmds=$lt_old_archive_cmds_D\n\n# A language specific compiler.\nCC=$lt_compiler_D\n\n# Is the compiler the GNU compiler?\nwith_gcc=$GCC_D\n\n# Compiler flag to turn off builtin functions.\nno_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_D\n\n# How to pass a linker flag through the compiler.\nwl=$lt_lt_prog_compiler_wl_D\n\n# Additional compiler flags for building library objects.\npic_flag=$lt_lt_prog_compiler_pic_D\n\n# Compiler flag to prevent dynamic linking.\nlink_static_flag=$lt_lt_prog_compiler_static_D\n\n# Does compiler simultaneously support -c and -o options?\ncompiler_c_o=$lt_lt_cv_prog_compiler_c_o_D\n\n# Whether or not to add -lc for building shared libraries.\nbuild_libtool_need_lc=$archive_cmds_need_lc_D\n\n# Whether or not to disallow shared libs when runtime libs are static.\nallow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_D\n\n# Compiler flag to allow reflexive dlopens.\nexport_dynamic_flag_spec=$lt_export_dynamic_flag_spec_D\n\n# Compiler flag to generate shared objects directly from archives.\nwhole_archive_flag_spec=$lt_whole_archive_flag_spec_D\n\n# Whether the compiler copes with passing no objects directly.\ncompiler_needs_object=$lt_compiler_needs_object_D\n\n# Create an old-style archive from a shared archive.\nold_archive_from_new_cmds=$lt_old_archive_from_new_cmds_D\n\n# Create a temporary old-style archive to link instead of a shared archive.\nold_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_D\n\n# Commands used to build a shared archive.\narchive_cmds=$lt_archive_cmds_D\narchive_expsym_cmds=$lt_archive_expsym_cmds_D\n\n# Commands used to build a loadable module if different from building\n# a shared archive.\nmodule_cmds=$lt_module_cmds_D\nmodule_expsym_cmds=$lt_module_expsym_cmds_D\n\n# Whether we are building with GNU ld or not.\nwith_gnu_ld=$lt_with_gnu_ld_D\n\n# Flag that allows shared libraries with undefined symbols to be built.\nallow_undefined_flag=$lt_allow_undefined_flag_D\n\n# Flag that enforces no undefined symbols.\nno_undefined_flag=$lt_no_undefined_flag_D\n\n# Flag to hardcode \\$libdir into a binary during linking.\n# This must work even if \\$libdir does not exist\nhardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_D\n\n# If ld is used when linking, flag to hardcode \\$libdir into a binary\n# during linking.  This must work even if \\$libdir does not exist.\nhardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_D\n\n# Whether we need a single \"-rpath\" flag with a separated argument.\nhardcode_libdir_separator=$lt_hardcode_libdir_separator_D\n\n# Set to \"yes\" if using DIR/libNAME\\${shared_ext} during linking hardcodes\n# DIR into the resulting binary.\nhardcode_direct=$hardcode_direct_D\n\n# Set to \"yes\" if using DIR/libNAME\\${shared_ext} during linking hardcodes\n# DIR into the resulting binary and the resulting library dependency is\n# \"absolute\",i.e impossible to change by setting \\${shlibpath_var} if the\n# library is relocated.\nhardcode_direct_absolute=$hardcode_direct_absolute_D\n\n# Set to \"yes\" if using the -LDIR flag during linking hardcodes DIR\n# into the resulting binary.\nhardcode_minus_L=$hardcode_minus_L_D\n\n# Set to \"yes\" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR\n# into the resulting binary.\nhardcode_shlibpath_var=$hardcode_shlibpath_var_D\n\n# Set to \"yes\" if building a shared library automatically hardcodes DIR\n# into the library and all subsequent libraries and executables linked\n# against it.\nhardcode_automatic=$hardcode_automatic_D\n\n# Set to yes if linker adds runtime paths of dependent libraries\n# to runtime path list.\ninherit_rpath=$inherit_rpath_D\n\n# Whether libtool must link a program against all its dependency libraries.\nlink_all_deplibs=$link_all_deplibs_D\n\n# Fix the shell variable \\$srcfile for the compiler.\nfix_srcfile_path=$lt_fix_srcfile_path_D\n\n# Set to \"yes\" if exported symbols are required.\nalways_export_symbols=$always_export_symbols_D\n\n# The commands to list exported symbols.\nexport_symbols_cmds=$lt_export_symbols_cmds_D\n\n# Symbols that should not be listed in the preloaded symbols.\nexclude_expsyms=$lt_exclude_expsyms_D\n\n# Symbols that must always be exported.\ninclude_expsyms=$lt_include_expsyms_D\n\n# Commands necessary for linking programs (against libraries) with templates.\nprelink_cmds=$lt_prelink_cmds_D\n\n# Specify filename containing input files.\nfile_list_spec=$lt_file_list_spec_D\n\n# How to hardcode a shared library path into an executable.\nhardcode_action=$hardcode_action_D\n\n# ### END LIBTOOL TAG CONFIG: D\n_LT_EOF\n\n ;;\n    \"testsuite/testsuite_flags\":F) chmod +x testsuite/testsuite_flags ;;\n    \"default\":C) if test -n \"$CONFIG_FILES\"; then\n   if test -n \"${with_target_subdir}\"; then\n     # Multilibs need MULTISUBDIR defined correctly in certain makefiles so\n     # that multilib installs will end up installed in the correct place.\n     # The testsuite needs it for multilib-aware ABI baseline files.\n     # To work around this not being passed down from config-ml.in ->\n     # srcdir/Makefile.am -> srcdir/{src,libdruntime,...}/Makefile.am, manually\n     # append it here.  Only modify Makefiles that have just been created.\n     #\n     # Also, get rid of this simulated-VPATH thing that automake does.\n     cat > vpsed << \\_EOF\n  s!`test -f '$<' || echo '$(srcdir)/'`!!\n_EOF\n     for i in $SUBDIRS; do\n      case $CONFIG_FILES in\n       *${i}/Makefile*)\n\t #echo \"Adding MULTISUBDIR to $i/Makefile\"\n\t sed -f vpsed $i/Makefile > tmp\n\t grep '^MULTISUBDIR =' Makefile >> tmp\n\t mv tmp $i/Makefile\n\t ;;\n      esac\n     done\n     rm vpsed\n   fi\n fi\n ;;\n\n  esac\ndone # for ac_tag\n\n\nas_fn_exit 0\n_ACEOF\nac_clean_files=$ac_clean_files_save\n\ntest $ac_write_fail = 0 ||\n  as_fn_error \"write failure creating $CONFIG_STATUS\" \"$LINENO\" 5\n\n\n# configure is writing to config.log, and then calls config.status.\n# config.status does its own redirection, appending to config.log.\n# Unfortunately, on DOS this fails, as config.log is still kept open\n# by configure, so config.status won't be able to write to it; its\n# output is simply discarded.  So we exec the FD to /dev/null,\n# effectively closing config.log, so it can be properly (re)opened and\n# appended to by config.status.  When coming back to configure, we\n# need to make the FD available again.\nif test \"$no_create\" != yes; then\n  ac_cs_success=:\n  ac_config_status_args=\n  test \"$silent\" = yes &&\n    ac_config_status_args=\"$ac_config_status_args --quiet\"\n  exec 5>/dev/null\n  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false\n  exec 5>>config.log\n  # Use ||, not &&, to avoid exiting from the if with $? = 1, which\n  # would make configure fail if this is the last instruction.\n  $ac_cs_success || as_fn_exit $?\nfi\nif test -n \"$ac_unrecognized_opts\" && test \"$enable_option_checking\" != no; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts\" >&5\n$as_echo \"$as_me: WARNING: unrecognized options: $ac_unrecognized_opts\" >&2;}\nfi\n\n"
  },
  {
    "path": "libphobos/configure.ac",
    "content": "# Process this file with autoconf to produce a configure script.\n# Copyright (C) 2006-2018 Free Software Foundation, Inc.\n#\n# GCC is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3, or (at your option)\n# any later version.\n#\n# GCC is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\n# This requires that you have your environment set-up to use explicit\n# versions of automake and autoconf.\n#\n#    export ACLOCAL=/usr/bin/aclocal-1.11\n#    export AUTOMAKE=/usr/bin/automake-1.11\n#    export AUTOM4TE=/usr/bin/autom4te2.64\n#    export AUTOCONF=/usr/bin/autoconf2.64\n#\n#    autoreconf2.64\n#\n\nAC_PREREQ(2.64)\nAC_INIT(package-unused, version-unused,, libphobos)\nAC_CONFIG_SRCDIR(libdruntime/gcc/attribute.d)\nAC_CONFIG_HEADERS(config.h)\n\nAM_ENABLE_MULTILIB(, ..)\nAC_CANONICAL_SYSTEM\n\ntarget_alias=${target_alias-$target}\nAC_SUBST(target_alias)\n\n# 1.11.1: Require that version of automake.\n# foreign: Don't require README, INSTALL, NEWS, etc.\n# no-define: Don't define PACKAGE and VERSION.\n# no-dependencies: Don't generate automatic dependencies.\n#    (because it breaks when using bootstrap-lean, since some of the\n#    headers are gone at \"make install\" time).\n# -Wall: Issue all automake warnings.\n# -Wno-portability: Don't warn about constructs supported by GNU make.\n#    (because GCC requires GNU make anyhow).\nAM_INIT_AUTOMAKE([1.11.1 foreign no-dist no-define no-dependencies -Wall -Wno-portability])\n\nm4_rename([_AC_ARG_VAR_PRECIOUS],[glibd_PRECIOUS])\nm4_define([_AC_ARG_VAR_PRECIOUS],[])\nAM_PROG_AS\nAC_PROG_CC\nAC_PROG_GDC\nWITH_LOCAL_DRUNTIME([GDC_CHECK_COMPILE], [])\n\nm4_rename_force([glibd_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])\n\nAC_SUBST(CFLAGS)\nAM_MAINTAINER_MODE\nAC_PROG_RANLIB\nAC_PROG_INSTALL\nAC_PROG_MAKE_SET\n\n# This should be inherited in the recursive make, but ensure it is defined.\ntest \"$AR\" || AR=ar\nAC_SUBST(AR)\n\nCC_FOR_BUILD=${CC_FOR_BUILD:-gcc}\nAC_SUBST(CC_FOR_BUILD)\nAC_SUBST(CFLAGS_FOR_BUILD)\n\n# Enable libtool\nLT_INIT(dlopen)\nAM_PROG_LIBTOOL\nWITH_LOCAL_DRUNTIME([LT_LANG([D])], [])\nAM_CONDITIONAL([ENABLE_SHARED], [test \"$enable_shared\" = \"yes\"])\nAM_CONDITIONAL([ENABLE_STATIC], [test \"$enable_static\" = \"yes\"])\n\n# libtool variables for Phobos shared and position-independent compiles.\n#\n# Use phobos_compiler_shared_flag to designate the compile-time flags for\n# creating shared objects. Default: -fversion=Shared.\n#\n# Use phobos_compiler_pic_flag to designate the compile-time flags for\n# creating position-independent objects. This varies with the target\n# hardware and operating system, but is often: -fPIC.\n#\n# The distinction between pic and shared compilation flags is not present in\n# libtool, and so we make it here.  How it is handled is that in shared\n# compilations the `lt_prog_compiler_pic_D' variable is used to instead\n# ensure that conditional compilation of shared runtime code is compiled in.\n# The original PIC flags are then used in the compilation of every object.\n#\n# Why are objects destined for libgphobos.a compiled with -fPIC?\n# Because -fPIC is not harmful to use for objects destined for static\n# libraries. In addition, using -fPIC will allow the use of static\n# libgphobos.a in the creation of other D shared libraries.\nif test \"$enable_shared\" = yes; then\n  phobos_compiler_pic_flag=\"$lt_prog_compiler_pic_D\"\n  phobos_compiler_shared_flag=\"-fversion=Shared\"\nelse\n  phobos_compiler_pic_flag=\n  phobos_compiler_shared_flag=\nfi\nAC_SUBST(phobos_compiler_pic_flag)\nAC_SUBST(phobos_compiler_shared_flag)\n\n# Override the libtool's pic_flag and pic_mode.\n# Do this step after AM_PROG_LIBTOOL, but before AC_OUTPUT.\n# NB: this impacts --with-pic and --without-pic.\nlt_prog_compiler_pic_D=\"$phobos_compiler_shared_flag\"\npic_mode='default'\n\n# Determine what GCC version number to use in filesystem paths.\nGCC_BASE_VER\n\n# libphobos/libdruntime specific options and feature detection\nDRUNTIME_CONFIGURE\nDRUNTIME_MULTILIB\nDRUNTIME_WERROR\nDRUNTIME_GC\nDRUNTIME_OS_UNIX\nDRUNTIME_OS_SOURCES\nDRUNTIME_OS_THREAD_MODEL\nDRUNTIME_OS_ARM_EABI_UNWINDER\nDRUNTIME_OS_MINFO_BRACKETING\n\nWITH_LOCAL_DRUNTIME([\n  AC_LANG_PUSH([D])\n  AC_SEARCH_LIBS([malloc], [c])\n  DRUNTIME_LIBRARIES_THREAD\n  AC_SEARCH_LIBS([cosf], [m])\n  AC_SEARCH_LIBS([clock_gettime], [rt])\n  DRUNTIME_ENABLE_ATOMIC_BUILTINS\n  AC_LANG_POP([D])\n], [-nophoboslib])\n\nDRUNTIME_LIBRARIES_ATOMIC\nDRUNTIME_LIBRARIES_BACKTRACE\nDRUNTIME_LIBRARIES_DLOPEN\nDRUNTIME_LIBRARIES_ZLIB\nDRUNTIME_INSTALL_DIRECTORIES\n\n# Add dependencies for libgphobos.spec file\nSPEC_PHOBOS_DEPS=\"$LIBS\"\nAC_SUBST(SPEC_PHOBOS_DEPS)\n\n# Libdruntime / phobos soname version\nDRUNTIME_SOVERSION=\"83:0:0\"\nPHOBOS_SOVERSION=\"83:0:0\"\nAC_SUBST([DRUNTIME_SOVERSION])\nAC_SUBST([PHOBOS_SOVERSION])\n\n# Set default flags (after DRUNTIME_WERROR!)\nif test -z \"$GDCFLAGS\"; then\n    GDCFLAGS=\"-Wall $WERROR_FLAG -g -frelease -O2\"\nfi\nAC_SUBST(GDCFLAGS)\n\nif test -z \"$GDCFLAGSX\"; then\n    GDCFLAGSX=\"-Wall $WERROR_FLAG -g -fno-release -funittest\"\nfi\nAC_SUBST(GDCFLAGSX)\n\n# Sanity check for the cross-compilation case:\nAC_CHECK_HEADER(stdio.h,:,\n  [AC_MSG_ERROR([cannot find stdio.h.])])\n\nAC_CONFIG_FILES(Makefile src/Makefile libdruntime/Makefile testsuite/Makefile)\n\nAC_CONFIG_FILES(libdruntime/gcc/config.d libdruntime/gcc/libbacktrace.d)\nAC_CONFIG_FILES(src/libgphobos.spec)\nAC_CONFIG_FILES([testsuite/testsuite_flags],[chmod +x testsuite/testsuite_flags])\n\n# We need multilib support, but only if configuring for the target.\nAC_CONFIG_COMMANDS([default],\n[if test -n \"$CONFIG_FILES\"; then\n   if test -n \"${with_target_subdir}\"; then\n     # Multilibs need MULTISUBDIR defined correctly in certain makefiles so\n     # that multilib installs will end up installed in the correct place.\n     # The testsuite needs it for multilib-aware ABI baseline files.\n     # To work around this not being passed down from config-ml.in ->\n     # srcdir/Makefile.am -> srcdir/{src,libdruntime,...}/Makefile.am, manually\n     # append it here.  Only modify Makefiles that have just been created.\n     #\n     # Also, get rid of this simulated-VPATH thing that automake does.\n     cat > vpsed << \\_EOF\n  s!`test -f '$<' || echo '$(srcdir)/'`!!\n_EOF\n     for i in $SUBDIRS; do\n      case $CONFIG_FILES in\n       *${i}/Makefile*)\n\t #echo \"Adding MULTISUBDIR to $i/Makefile\"\n\t sed -f vpsed $i/Makefile > tmp\n\t grep '^MULTISUBDIR =' Makefile >> tmp\n\t mv tmp $i/Makefile\n\t ;;\n      esac\n     done\n     rm vpsed\n   fi\n fi\n],\n[\n# Variables needed in config.status (file generation) which aren't already\n# passed by autoconf.\nSUBDIRS=\"$SUBDIRS\"\n])\n\nAC_OUTPUT\n"
  },
  {
    "path": "libphobos/d_rules.am",
    "content": "## Common rules for D source compilation used in all Makefile.am's.\n## Copyright (C) 2016-2018 Free Software Foundation, Inc.\n##\n## GCC is free software; you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation; either version 3, or (at your option)\n## any later version.\n##\n## GCC is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License\n## along with GCC; see the file COPYING3.  If not see\n## <http://www.gnu.org/licenses/>.\n\n# If there are no sources with known extension (i.e. only D sources)\n# automake forgets to set this\nCCLD = $(CC)\n\n# Compile D into normal object files\n.d.o:\n\t$(GDC) $(GDCFLAGS) $(MULTIFLAGS) $(D_EXTRA_DFLAGS) -c -o $@ $<\n\n# Compile D sources with libtool\n.d.lo:\n\t$(LTDCOMPILE) $(GDCFLAGS) $(MULTIFLAGS) $(D_EXTRA_DFLAGS) -c -o $@ $<\n\nLTDCOMPILE = $(LIBTOOL) --tag=D $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \\\n\t--mode=compile $(GDC) $(AM_DFLAGS)\n\n# Unittest rules. Unfortunately we can't use _DFLAGS in automake without\n# explicit D support, so use this hack.\n# Compile D sources with libtool and test flags\n%.t.lo : %.d\n\t$(LTDCOMPILE) $(GDCFLAGSX) $(MULTIFLAGS) $(D_EXTRA_DFLAGS) -c -o $@ $<\n\n# Compile objects for static linking with test flags\n# Automake breaks empty rules, so use the shell NOP :\n%.t.o : %.t.lo\n\t@:\n\n# Override executable linking commands: We have to use GDC for linking\n# to make sure we link pthreads and other dependencies\nunittest_static_LINK = $(LIBTOOL) --tag=D \\\n\t$(unittest_static_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \\\n\t$(GDC) $(AM_CFLAGS) $(CFLAGS) $(unittest_static_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\n\nunittest_LINK = $(LIBTOOL) --tag=D \\\n\t$(unittest_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \\\n\t$(GDC) $(AM_CFLAGS) $(CFLAGS) $(unittest_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\n\n# Also override library link commands: This is not strictly\n# required, but we want to record additional dependencies such\n# as pthread in the library\nlibgdruntime_la_LINK = $(LIBTOOL) --tag=D $(AM_LIBTOOLFLAGS) \\\n\t$(LIBTOOLFLAGS) --mode=link $(GDC) $(AM_CFLAGS) $(CFLAGS) \\\n\t$(libgdruntime_la_LDFLAGS) $(LDFLAGS) -o $@\n\nlibgdruntime_t_la_LINK = $(LIBTOOL) --tag=D $(AM_LIBTOOLFLAGS) \\\n\t$(LIBTOOLFLAGS) --mode=link $(GDC) $(AM_CFLAGS) $(CFLAGS) \\\n\t$(libgdruntime_t_la_LDFLAGS) $(LDFLAGS) -o $@\n\nlibgphobos_la_LINK = $(LIBTOOL) --tag=D $(libgphobos_la_LIBTOOLFLAGS) \\\n\t$(LIBTOOLFLAGS) --mode=link $(GDC) $(AM_CFLAGS) $(CFLAGS) \\\n\t$(libgphobos_la_LDFLAGS) $(LDFLAGS) -o $@\n\nlibgphobos_t_la_LINK = $(LIBTOOL) --tag=D \\\n\t$(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \\\n\t$(GDC) $(AM_CFLAGS) $(CFLAGS) $(libgphobos_t_la_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\n"
  },
  {
    "path": "libphobos/libdruntime/LICENSE",
    "content": "DRuntime: Runtime Library for the D Programming Language\n========================================================\n\nBoost Software License - Version 1.0 - August 17th, 2003\n\nPermission is hereby granted, free of charge, to any person or organization\nobtaining a copy of the software and accompanying documentation covered by\nthis license (the \"Software\") to use, reproduce, display, distribute,\nexecute, and transmit the Software, and to prepare derivative works of the\nSoftware, and to permit third-parties to whom the Software is furnished to\ndo so, all subject to the following:\n\nThe copyright notices in the Software and this entire statement, including\nthe above license grant, this restriction and the following disclaimer,\nmust be included in all copies of the Software, in whole or in part, and\nall derivative works of the Software, unless such copies or derivative\nworks are solely in the form of machine-executable object code generated by\na source language processor.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "libphobos/libdruntime/MERGE",
    "content": "ebccd9887592cbe712cca7e02b858abdf0b0bc61\n\nThe first line of this file holds the git revision number of the last\nmerge done from the dlang/druntime repository.\n"
  },
  {
    "path": "libphobos/libdruntime/Makefile.am",
    "content": "# Makefile for the D runtime library.\n# Copyright (C) 2012-2018 Free Software Foundation, Inc.\n#\n# GCC is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3, or (at your option)\n# any later version.\n#\n# GCC is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\n# Include D build rules\ninclude $(top_srcdir)/d_rules.am\n\n# Make sure GDC can find libdruntime include files\nD_EXTRA_DFLAGS=-nostdinc -I $(srcdir) -I .\n\n# D flags for compilation\nAM_DFLAGS=$(phobos_compiler_pic_flag)\n\n# Install all D and DI files\nALL_DRUNTIME_INSTALL_DSOURCES = $(DRUNTIME_DSOURCES) \\\n\t$(DRUNTIME_DSOURCES_GC) $(DRUNTIME_DSOURCES_GCSTUB) \\\n\t$(DRUNTIME_DSOURCES_BIONIC) $(DRUNTIME_DSOURCES_DARWIN) \\\n\t$(DRUNTIME_DSOURCES_DRAGONFLYBSD) $(DRUNTIME_DSOURCES_FREEBSD) \\\n\t$(DRUNTIME_DSOURCES_LINUX) $(DRUNTIME_DSOURCES_OPENBSD) \\\n\t$(DRUNTIME_DSOURCES_OSX) $(DRUNTIME_DSOURCES_POSIX) \\\n\t$(DRUNTIME_DSOURCES_SOLARIS) $(DRUNTIME_DSOURCES_WINDOWS) \\\n\t$(DRUNTIME_DSOURCES_GENERATED) $(DRUNTIME_DSOURCES_STDCXX) \\\n\t$(DRUNTIME_DISOURCES)\n\n# Setup source files depending on configure\nALL_DRUNTIME_COMPILE_DSOURCES = $(DRUNTIME_DSOURCES)\n# GC sources\nif DRUNTIME_GC_ENABLE\n    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_GC)\nelse\n    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_GCSTUB)\nendif\n# OS specific sources\nif DRUNTIME_OS_UNIX\n    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_POSIX)\nendif\nif DRUNTIME_OS_DARWIN\n    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_DARWIN) \\\n\t\t\t\t     $(DRUNTIME_DSOURCES_OSX)\nendif\nif DRUNTIME_OS_ANDROID\n    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_BIONIC)\nendif\nif DRUNTIME_OS_FREEBSD\n    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_FREEBSD)\nendif\nif DRUNTIME_OS_OPENBSD\n    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_OPENBSD)\nendif\nif DRUNTIME_OS_LINUX\n    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_LINUX)\nendif\nif DRUNTIME_OS_MINGW\n    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_WINDOWS)\nendif\nif DRUNTIME_OS_SOLARIS\n    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_SOLARIS)\nendif\nif DRUNTIME_OS_DRAGONFLYBSD\n    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_DRAGONFLYBSD)\nendif\n# Generated by configure\nALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_GENERATED)\n\nALL_DRUNTIME_SOURCES = $(ALL_DRUNTIME_COMPILE_DSOURCES) $(DRUNTIME_CSOURCES) \\\n\t$(DRUNTIME_SSOURCES)\nREAL_DRUNTIME_TEST_LOBJECTS = $(ALL_DRUNTIME_COMPILE_DSOURCES:.d=.t.lo)\nREAL_DRUNTIME_TEST_OBJECTS  = $(ALL_DRUNTIME_COMPILE_DSOURCES:.d=.t.o)\n# Workaround issue #\nDRUNTIME_TEST_OBJECTS  = $(filter-out rt/util/typeinfo.t.o \\\n\tcore/internal/convert.t.o, $(REAL_DRUNTIME_TEST_OBJECTS)) \\\n\trt/util/typeinfo.o core/internal/convert.o\n\nDRUNTIME_TEST_LOBJECTS  = $(filter-out rt/util/typeinfo.t.lo \\\n\tcore/internal/convert.t.lo, $(REAL_DRUNTIME_TEST_LOBJECTS)) \\\n\trt/util/typeinfo.lo core/internal/convert.lo\n\n\n# Main library build definitions\ncheck_PROGRAMS =\nif ENABLE_SHARED\n  check_LTLIBRARIES = libgdruntime_t.la\n  check_PROGRAMS += unittest\nendif\nif ENABLE_STATIC\n  check_PROGRAMS += unittest_static\nendif\n\ntoolexeclib_LTLIBRARIES = libgdruntime.la\nlibgdruntime_la_SOURCES = $(ALL_DRUNTIME_SOURCES)\nlibgdruntime_la_LIBTOOLFLAGS =\nlibgdruntime_la_LDFLAGS = -Xcompiler -nophoboslib -version-info $(DRUNTIME_SOVERSION)\nlibgdruntime_la_LIBADD = $(LIBATOMIC) $(LIBBACKTRACE)\n\n# For static unittest, link objects directly\nunittest_static_SOURCES = ../testsuite/test_runner.d $(DRUNTIME_CSOURCES) \\\n    $(DRUNTIME_SSOURCES)\nunittest_static_LIBTOOLFLAGS =\nunittest_static_LDFLAGS = -Xcompiler -nophoboslib\nunittest_static_LDADD = $(DRUNTIME_TEST_OBJECTS) $(LIBATOMIC) $(LIBBACKTRACE)\nEXTRA_unittest_static_DEPENDENCIES = $(DRUNTIME_TEST_OBJECTS)\n\n# For unittest with dynamic library\nlibgdruntime_t_la_SOURCES = $(DRUNTIME_CSOURCES) $(DRUNTIME_SSOURCES)\nlibgdruntime_t_la_LIBTOOLFLAGS =\n# Automake by default does not generate shared libs for non-installed\n# libraries. Use -rpath to force shared lib generation.\nlibgdruntime_t_la_LDFLAGS = -Xcompiler -nophoboslib -rpath /foo -shared\nlibgdruntime_t_la_LIBADD = $(DRUNTIME_TEST_LOBJECTS) $(LIBATOMIC) $(LIBBACKTRACE)\nEXTRA_libgdruntime_t_la_DEPENDENCIES = $(DRUNTIME_TEST_LOBJECTS)\n\n# For unittest\nunittest_SOURCES = ../testsuite/test_runner.d\nunittest_LIBTOOLFLAGS =\nunittest_LDFLAGS = -Xcompiler -nophoboslib\nunittest_LDADD = libgdruntime_t.la\n\n# Extra install and clean rules.\n# This does not delete the .libs/.t.o files, but deleting\n# the .lo is good enough to rerun the rules\nclean-local:\n\trm -f $(DRUNTIME_TEST_LOBJECTS)\n\trm -f $(DRUNTIME_TEST_OBJECTS)\n\n# Handles generated files as well\ninstall-data-local:\n\tfor file in $(ALL_DRUNTIME_INSTALL_DSOURCES); do \\\n\t  if test -f $$file; then \\\n\t    $(INSTALL_HEADER) -D $$file $(DESTDIR)$(gdc_include_dir)/$$file ; \\\n\t  else \\\n\t    $(INSTALL_HEADER) -D $(srcdir)/$$file \\\n\t      $(DESTDIR)$(gdc_include_dir)/$$file ; \\\n\t  fi ; \\\n\tdone\n\n\nDRUNTIME_DSOURCES_GENERATED = gcc/config.d gcc/libbacktrace.d\n# Source file definitions. Boring stuff, auto-generated with\n# https://gist.github.com/jpf91/8ad1dbc9902d6ad876313f134c6527d1\n# Can't use wildcards here:\n# https://www.gnu.org/software/automake/manual/html_node/Wildcards.html\nDRUNTIME_SSOURCES = core/threadasm.S\n\nDRUNTIME_CSOURCES = core/stdc/errno_.c\n\nDRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \\\n\tcore/checkedint.d core/cpuid.d core/demangle.d core/exception.d \\\n\tcore/internal/abort.d core/internal/arrayop.d core/internal/convert.d \\\n\tcore/internal/hash.d core/internal/parseoptions.d \\\n\tcore/internal/spinlock.d core/internal/string.d core/internal/traits.d \\\n\tcore/math.d core/memory.d core/runtime.d core/simd.d \\\n\tcore/stdc/assert_.d core/stdc/complex.d core/stdc/config.d \\\n\tcore/stdc/ctype.d core/stdc/errno.d core/stdc/fenv.d \\\n\tcore/stdc/float_.d core/stdc/inttypes.d core/stdc/limits.d \\\n\tcore/stdc/locale.d core/stdc/math.d core/stdc/signal.d \\\n\tcore/stdc/stdarg.d core/stdc/stddef.d core/stdc/stdint.d \\\n\tcore/stdc/stdio.d core/stdc/stdlib.d core/stdc/string.d \\\n\tcore/stdc/tgmath.d core/stdc/time.d core/stdc/wchar_.d \\\n\tcore/stdc/wctype.d core/sync/barrier.d core/sync/condition.d \\\n\tcore/sync/config.d core/sync/exception.d core/sync/mutex.d \\\n\tcore/sync/rwmutex.d core/sync/semaphore.d core/thread.d core/time.d \\\n\tcore/vararg.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \\\n\tgcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \\\n\tgcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \\\n\trt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arrayassign.d \\\n\trt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d rt/critical_.d \\\n\trt/deh.d rt/dmain2.d rt/ehalloc.d rt/invariant.d rt/lifetime.d \\\n\trt/memory.d rt/minfo.d rt/monitor_.d rt/obj.d rt/qsort.d rt/sections.d \\\n\trt/sections_android.d rt/sections_elf_shared.d rt/sections_osx_x86.d \\\n\trt/sections_osx_x86_64.d rt/sections_solaris.d rt/sections_win32.d \\\n\trt/sections_win64.d rt/tlsgc.d rt/typeinfo/ti_Acdouble.d \\\n\trt/typeinfo/ti_Acfloat.d rt/typeinfo/ti_Acreal.d \\\n\trt/typeinfo/ti_Adouble.d rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d \\\n\trt/typeinfo/ti_Aint.d rt/typeinfo/ti_Along.d rt/typeinfo/ti_Areal.d \\\n\trt/typeinfo/ti_Ashort.d rt/typeinfo/ti_C.d rt/typeinfo/ti_byte.d \\\n\trt/typeinfo/ti_cdouble.d rt/typeinfo/ti_cent.d rt/typeinfo/ti_cfloat.d \\\n\trt/typeinfo/ti_char.d rt/typeinfo/ti_creal.d rt/typeinfo/ti_dchar.d \\\n\trt/typeinfo/ti_delegate.d rt/typeinfo/ti_double.d \\\n\trt/typeinfo/ti_float.d rt/typeinfo/ti_idouble.d \\\n\trt/typeinfo/ti_ifloat.d rt/typeinfo/ti_int.d rt/typeinfo/ti_ireal.d \\\n\trt/typeinfo/ti_long.d rt/typeinfo/ti_n.d rt/typeinfo/ti_ptr.d \\\n\trt/typeinfo/ti_real.d rt/typeinfo/ti_short.d rt/typeinfo/ti_ubyte.d \\\n\trt/typeinfo/ti_ucent.d rt/typeinfo/ti_uint.d rt/typeinfo/ti_ulong.d \\\n\trt/typeinfo/ti_ushort.d rt/typeinfo/ti_void.d rt/typeinfo/ti_wchar.d \\\n\trt/util/array.d rt/util/container/array.d rt/util/container/common.d \\\n\trt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \\\n\trt/util/typeinfo.d rt/util/utf.d\n\nDRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \\\n\tcore/stdcpp/typeinfo.d\n\nDRUNTIME_DSOURCES_GC = gc/bits.d gc/config.d gc/gcinterface.d \\\n\tgc/impl/conservative/gc.d gc/impl/manual/gc.d gc/impl/proto/gc.d \\\n\tgc/os.d gc/pooltable.d gc/proxy.d\n\nDRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \\\n\tcore/sys/bionic/unistd.d\n\nDRUNTIME_DSOURCES_DARWIN = core/sys/darwin/dlfcn.d \\\n\tcore/sys/darwin/execinfo.d core/sys/darwin/mach/dyld.d \\\n\tcore/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \\\n\tcore/sys/darwin/mach/loader.d core/sys/darwin/mach/port.d \\\n\tcore/sys/darwin/mach/semaphore.d core/sys/darwin/mach/thread_act.d \\\n\tcore/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \\\n\tcore/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \\\n\tcore/sys/darwin/sys/mman.d\n\nDRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \\\n\tcore/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \\\n\tcore/sys/dragonflybsd/pthread_np.d core/sys/dragonflybsd/sys/_bitset.d \\\n\tcore/sys/dragonflybsd/sys/_cpuset.d core/sys/dragonflybsd/sys/cdefs.d \\\n\tcore/sys/dragonflybsd/sys/elf.d core/sys/dragonflybsd/sys/elf32.d \\\n\tcore/sys/dragonflybsd/sys/elf64.d \\\n\tcore/sys/dragonflybsd/sys/elf_common.d \\\n\tcore/sys/dragonflybsd/sys/event.d core/sys/dragonflybsd/sys/link_elf.d \\\n\tcore/sys/dragonflybsd/sys/mman.d core/sys/dragonflybsd/time.d\n\nDRUNTIME_DSOURCES_FREEBSD = core/sys/freebsd/dlfcn.d \\\n\tcore/sys/freebsd/execinfo.d core/sys/freebsd/netinet/in_.d \\\n\tcore/sys/freebsd/pthread_np.d core/sys/freebsd/sys/_bitset.d \\\n\tcore/sys/freebsd/sys/_cpuset.d core/sys/freebsd/sys/cdefs.d \\\n\tcore/sys/freebsd/sys/elf.d core/sys/freebsd/sys/elf32.d \\\n\tcore/sys/freebsd/sys/elf64.d core/sys/freebsd/sys/elf_common.d \\\n\tcore/sys/freebsd/sys/event.d core/sys/freebsd/sys/link_elf.d \\\n\tcore/sys/freebsd/sys/mman.d core/sys/freebsd/sys/mount.d \\\n\tcore/sys/freebsd/time.d core/sys/freebsd/unistd.d\n\nDRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \\\n\tcore/sys/linux/dlfcn.d core/sys/linux/elf.d core/sys/linux/epoll.d \\\n\tcore/sys/linux/errno.d core/sys/linux/execinfo.d \\\n\tcore/sys/linux/fcntl.d core/sys/linux/ifaddrs.d core/sys/linux/link.d \\\n\tcore/sys/linux/netinet/in_.d core/sys/linux/netinet/tcp.d \\\n\tcore/sys/linux/sched.d core/sys/linux/stdio.d \\\n\tcore/sys/linux/sys/auxv.d core/sys/linux/sys/eventfd.d \\\n\tcore/sys/linux/sys/file.d core/sys/linux/sys/inotify.d \\\n\tcore/sys/linux/sys/mman.d core/sys/linux/sys/netinet/tcp.d \\\n\tcore/sys/linux/sys/prctl.d core/sys/linux/sys/signalfd.d \\\n\tcore/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \\\n\tcore/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \\\n\tcore/sys/linux/termios.d core/sys/linux/time.d \\\n\tcore/sys/linux/timerfd.d core/sys/linux/tipc.d core/sys/linux/unistd.d\n\nDRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \\\n\tcore/sys/netbsd/execinfo.d core/sys/netbsd/sys/elf.d \\\n\tcore/sys/netbsd/sys/elf32.d core/sys/netbsd/sys/elf64.d \\\n\tcore/sys/netbsd/sys/elf_common.d core/sys/netbsd/sys/event.d \\\n\tcore/sys/netbsd/sys/link_elf.d core/sys/netbsd/sys/mman.d \\\n\tcore/sys/netbsd/time.d\n\nDRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d\n\nDRUNTIME_DSOURCES_OSX = core/sys/osx/execinfo.d \\\n\tcore/sys/osx/mach/dyld.d core/sys/osx/mach/getsect.d \\\n\tcore/sys/osx/mach/kern_return.d core/sys/osx/mach/loader.d \\\n\tcore/sys/osx/mach/port.d core/sys/osx/mach/semaphore.d \\\n\tcore/sys/osx/mach/thread_act.d core/sys/osx/pthread.d \\\n\tcore/sys/osx/sys/cdefs.d core/sys/osx/sys/event.d \\\n\tcore/sys/osx/sys/mman.d\n\nDRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \\\n\tcore/sys/posix/arpa/inet.d core/sys/posix/config.d \\\n\tcore/sys/posix/dirent.d core/sys/posix/dlfcn.d core/sys/posix/fcntl.d \\\n\tcore/sys/posix/grp.d core/sys/posix/iconv.d core/sys/posix/inttypes.d \\\n\tcore/sys/posix/libgen.d core/sys/posix/mqueue.d \\\n\tcore/sys/posix/net/if_.d core/sys/posix/netdb.d \\\n\tcore/sys/posix/netinet/in_.d core/sys/posix/netinet/tcp.d \\\n\tcore/sys/posix/poll.d core/sys/posix/pthread.d core/sys/posix/pwd.d \\\n\tcore/sys/posix/sched.d core/sys/posix/semaphore.d \\\n\tcore/sys/posix/setjmp.d core/sys/posix/signal.d core/sys/posix/spawn.d \\\n\tcore/sys/posix/stdio.d core/sys/posix/stdlib.d \\\n\tcore/sys/posix/sys/filio.d core/sys/posix/sys/ioccom.d \\\n\tcore/sys/posix/sys/ioctl.d core/sys/posix/sys/ipc.d \\\n\tcore/sys/posix/sys/mman.d core/sys/posix/sys/msg.d \\\n\tcore/sys/posix/sys/resource.d core/sys/posix/sys/select.d \\\n\tcore/sys/posix/sys/shm.d core/sys/posix/sys/socket.d \\\n\tcore/sys/posix/sys/stat.d core/sys/posix/sys/statvfs.d \\\n\tcore/sys/posix/sys/time.d core/sys/posix/sys/ttycom.d \\\n\tcore/sys/posix/sys/types.d core/sys/posix/sys/uio.d \\\n\tcore/sys/posix/sys/un.d core/sys/posix/sys/utsname.d \\\n\tcore/sys/posix/sys/wait.d core/sys/posix/syslog.d \\\n\tcore/sys/posix/termios.d core/sys/posix/time.d \\\n\tcore/sys/posix/ucontext.d core/sys/posix/unistd.d \\\n\tcore/sys/posix/utime.d\n\nDRUNTIME_DSOURCES_SOLARIS = core/sys/solaris/dlfcn.d \\\n\tcore/sys/solaris/elf.d core/sys/solaris/execinfo.d \\\n\tcore/sys/solaris/libelf.d core/sys/solaris/link.d \\\n\tcore/sys/solaris/sys/elf.d core/sys/solaris/sys/elf_386.d \\\n\tcore/sys/solaris/sys/elf_SPARC.d core/sys/solaris/sys/elf_amd64.d \\\n\tcore/sys/solaris/sys/elf_notes.d core/sys/solaris/sys/elftypes.d \\\n\tcore/sys/solaris/sys/link.d core/sys/solaris/sys/priocntl.d \\\n\tcore/sys/solaris/sys/procset.d core/sys/solaris/sys/types.d \\\n\tcore/sys/solaris/time.d\n\nDRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \\\n\tcore/sys/windows/aclapi.d core/sys/windows/aclui.d \\\n\tcore/sys/windows/basetsd.d core/sys/windows/basetyps.d \\\n\tcore/sys/windows/cderr.d core/sys/windows/cguid.d \\\n\tcore/sys/windows/com.d core/sys/windows/comcat.d \\\n\tcore/sys/windows/commctrl.d core/sys/windows/commdlg.d \\\n\tcore/sys/windows/core.d core/sys/windows/cpl.d \\\n\tcore/sys/windows/cplext.d core/sys/windows/custcntl.d \\\n\tcore/sys/windows/dbghelp.d core/sys/windows/dbghelp_types.d \\\n\tcore/sys/windows/dbt.d core/sys/windows/dde.d core/sys/windows/ddeml.d \\\n\tcore/sys/windows/dhcpcsdk.d core/sys/windows/dlgs.d \\\n\tcore/sys/windows/dll.d core/sys/windows/docobj.d \\\n\tcore/sys/windows/errorrep.d core/sys/windows/exdisp.d \\\n\tcore/sys/windows/exdispid.d core/sys/windows/httpext.d \\\n\tcore/sys/windows/idispids.d core/sys/windows/imagehlp.d \\\n\tcore/sys/windows/imm.d core/sys/windows/intshcut.d \\\n\tcore/sys/windows/ipexport.d core/sys/windows/iphlpapi.d \\\n\tcore/sys/windows/ipifcons.d core/sys/windows/iprtrmib.d \\\n\tcore/sys/windows/iptypes.d core/sys/windows/isguids.d \\\n\tcore/sys/windows/lm.d core/sys/windows/lmaccess.d \\\n\tcore/sys/windows/lmalert.d core/sys/windows/lmapibuf.d \\\n\tcore/sys/windows/lmat.d core/sys/windows/lmaudit.d \\\n\tcore/sys/windows/lmbrowsr.d core/sys/windows/lmchdev.d \\\n\tcore/sys/windows/lmconfig.d core/sys/windows/lmcons.d \\\n\tcore/sys/windows/lmerr.d core/sys/windows/lmerrlog.d \\\n\tcore/sys/windows/lmmsg.d core/sys/windows/lmremutl.d \\\n\tcore/sys/windows/lmrepl.d core/sys/windows/lmserver.d \\\n\tcore/sys/windows/lmshare.d core/sys/windows/lmsname.d \\\n\tcore/sys/windows/lmstats.d core/sys/windows/lmsvc.d \\\n\tcore/sys/windows/lmuse.d core/sys/windows/lmuseflg.d \\\n\tcore/sys/windows/lmwksta.d core/sys/windows/lzexpand.d \\\n\tcore/sys/windows/mapi.d core/sys/windows/mciavi.d \\\n\tcore/sys/windows/mcx.d core/sys/windows/mgmtapi.d \\\n\tcore/sys/windows/mmsystem.d core/sys/windows/msacm.d \\\n\tcore/sys/windows/mshtml.d core/sys/windows/mswsock.d \\\n\tcore/sys/windows/nb30.d core/sys/windows/nddeapi.d \\\n\tcore/sys/windows/nspapi.d core/sys/windows/ntdef.d \\\n\tcore/sys/windows/ntdll.d core/sys/windows/ntldap.d \\\n\tcore/sys/windows/ntsecapi.d core/sys/windows/ntsecpkg.d \\\n\tcore/sys/windows/oaidl.d core/sys/windows/objbase.d \\\n\tcore/sys/windows/objfwd.d core/sys/windows/objidl.d \\\n\tcore/sys/windows/objsafe.d core/sys/windows/ocidl.d \\\n\tcore/sys/windows/odbcinst.d core/sys/windows/ole.d \\\n\tcore/sys/windows/ole2.d core/sys/windows/ole2ver.d \\\n\tcore/sys/windows/oleacc.d core/sys/windows/oleauto.d \\\n\tcore/sys/windows/olectl.d core/sys/windows/olectlid.d \\\n\tcore/sys/windows/oledlg.d core/sys/windows/oleidl.d \\\n\tcore/sys/windows/pbt.d core/sys/windows/powrprof.d \\\n\tcore/sys/windows/prsht.d core/sys/windows/psapi.d \\\n\tcore/sys/windows/rapi.d core/sys/windows/ras.d \\\n\tcore/sys/windows/rasdlg.d core/sys/windows/raserror.d \\\n\tcore/sys/windows/rassapi.d core/sys/windows/reason.d \\\n\tcore/sys/windows/regstr.d core/sys/windows/richedit.d \\\n\tcore/sys/windows/richole.d core/sys/windows/rpc.d \\\n\tcore/sys/windows/rpcdce.d core/sys/windows/rpcdce2.d \\\n\tcore/sys/windows/rpcdcep.d core/sys/windows/rpcndr.d \\\n\tcore/sys/windows/rpcnsi.d core/sys/windows/rpcnsip.d \\\n\tcore/sys/windows/rpcnterr.d core/sys/windows/schannel.d \\\n\tcore/sys/windows/secext.d core/sys/windows/security.d \\\n\tcore/sys/windows/servprov.d core/sys/windows/setupapi.d \\\n\tcore/sys/windows/shellapi.d core/sys/windows/shldisp.d \\\n\tcore/sys/windows/shlguid.d core/sys/windows/shlobj.d \\\n\tcore/sys/windows/shlwapi.d core/sys/windows/snmp.d \\\n\tcore/sys/windows/sql.d core/sys/windows/sqlext.d \\\n\tcore/sys/windows/sqltypes.d core/sys/windows/sqlucode.d \\\n\tcore/sys/windows/sspi.d core/sys/windows/stacktrace.d \\\n\tcore/sys/windows/stat.d core/sys/windows/subauth.d \\\n\tcore/sys/windows/threadaux.d core/sys/windows/tlhelp32.d \\\n\tcore/sys/windows/tmschema.d core/sys/windows/unknwn.d \\\n\tcore/sys/windows/uuid.d core/sys/windows/vfw.d \\\n\tcore/sys/windows/w32api.d core/sys/windows/winbase.d \\\n\tcore/sys/windows/winber.d core/sys/windows/wincon.d \\\n\tcore/sys/windows/wincrypt.d core/sys/windows/windef.d \\\n\tcore/sys/windows/windows.d core/sys/windows/winerror.d \\\n\tcore/sys/windows/wingdi.d core/sys/windows/winhttp.d \\\n\tcore/sys/windows/wininet.d core/sys/windows/winioctl.d \\\n\tcore/sys/windows/winldap.d core/sys/windows/winnetwk.d \\\n\tcore/sys/windows/winnls.d core/sys/windows/winnt.d \\\n\tcore/sys/windows/winperf.d core/sys/windows/winreg.d \\\n\tcore/sys/windows/winsock2.d core/sys/windows/winspool.d \\\n\tcore/sys/windows/winsvc.d core/sys/windows/winuser.d \\\n\tcore/sys/windows/winver.d core/sys/windows/wtsapi32.d \\\n\tcore/sys/windows/wtypes.d\n\nDRUNTIME_DISOURCES = __entrypoint.di __main.di\n"
  },
  {
    "path": "libphobos/libdruntime/Makefile.in",
    "content": "# Makefile.in generated by automake 1.11.6 from Makefile.am.\n# @configure_input@\n\n# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,\n# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software\n# Foundation, Inc.\n# This Makefile.in is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY, to the extent permitted by law; without\n# even the implied warranty of MERCHANTABILITY or FITNESS FOR A\n# PARTICULAR PURPOSE.\n\n@SET_MAKE@\n\n# Makefile for the D runtime library.\n# Copyright (C) 2012-2018 Free Software Foundation, Inc.\n#\n# GCC is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3, or (at your option)\n# any later version.\n#\n# GCC is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nVPATH = @srcdir@\nam__make_dryrun = \\\n  { \\\n    am__dry=no; \\\n    case $$MAKEFLAGS in \\\n      *\\\\[\\ \\\t]*) \\\n        echo 'am--echo: ; @echo \"AM\"  OK' | $(MAKE) -f - 2>/dev/null \\\n          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \\\n      *) \\\n        for am__flg in $$MAKEFLAGS; do \\\n          case $$am__flg in \\\n            *=*|--*) ;; \\\n            *n*) am__dry=yes; break;; \\\n          esac; \\\n        done;; \\\n    esac; \\\n    test $$am__dry = yes; \\\n  }\npkgdatadir = $(datadir)/@PACKAGE@\npkgincludedir = $(includedir)/@PACKAGE@\npkglibdir = $(libdir)/@PACKAGE@\npkglibexecdir = $(libexecdir)/@PACKAGE@\nam__cd = CDPATH=\"$${ZSH_VERSION+.}$(PATH_SEPARATOR)\" && cd\ninstall_sh_DATA = $(install_sh) -c -m 644\ninstall_sh_PROGRAM = $(install_sh) -c\ninstall_sh_SCRIPT = $(install_sh) -c\nINSTALL_HEADER = $(INSTALL_DATA)\ntransform = $(program_transform_name)\nNORMAL_INSTALL = :\nPRE_INSTALL = :\nPOST_INSTALL = :\nNORMAL_UNINSTALL = :\nPRE_UNINSTALL = :\nPOST_UNINSTALL = :\nbuild_triplet = @build@\nhost_triplet = @host@\ntarget_triplet = @target@\nDIST_COMMON = $(top_srcdir)/d_rules.am $(srcdir)/Makefile.in \\\n\t$(srcdir)/Makefile.am\n# GC sources\n@DRUNTIME_GC_ENABLE_TRUE@am__append_1 = $(DRUNTIME_DSOURCES_GC)\n@DRUNTIME_GC_ENABLE_FALSE@am__append_2 = $(DRUNTIME_DSOURCES_GCSTUB)\n# OS specific sources\n@DRUNTIME_OS_UNIX_TRUE@am__append_3 = $(DRUNTIME_DSOURCES_POSIX)\n@DRUNTIME_OS_DARWIN_TRUE@am__append_4 = $(DRUNTIME_DSOURCES_DARWIN) \\\n@DRUNTIME_OS_DARWIN_TRUE@\t\t\t\t     $(DRUNTIME_DSOURCES_OSX)\n\n@DRUNTIME_OS_ANDROID_TRUE@am__append_5 = $(DRUNTIME_DSOURCES_BIONIC)\n@DRUNTIME_OS_FREEBSD_TRUE@am__append_6 = $(DRUNTIME_DSOURCES_FREEBSD)\n@DRUNTIME_OS_OPENBSD_TRUE@am__append_7 = $(DRUNTIME_DSOURCES_OPENBSD)\n@DRUNTIME_OS_LINUX_TRUE@am__append_8 = $(DRUNTIME_DSOURCES_LINUX)\n@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS)\n@DRUNTIME_OS_SOLARIS_TRUE@am__append_10 = $(DRUNTIME_DSOURCES_SOLARIS)\n@DRUNTIME_OS_DRAGONFLYBSD_TRUE@am__append_11 = $(DRUNTIME_DSOURCES_DRAGONFLYBSD)\ncheck_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)\n@ENABLE_SHARED_TRUE@am__append_12 = unittest\n@ENABLE_STATIC_TRUE@am__append_13 = unittest_static\nsubdir = libdruntime\nACLOCAL_M4 = $(top_srcdir)/aclocal.m4\nam__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \\\n\t$(top_srcdir)/../config/lead-dot.m4 \\\n\t$(top_srcdir)/../config/multi.m4 \\\n\t$(top_srcdir)/../config/override.m4 \\\n\t$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \\\n\t$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \\\n\t$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \\\n\t$(top_srcdir)/m4/gcc_support.m4 $(top_srcdir)/m4/autoconf.m4 \\\n\t$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/gdc.m4 \\\n\t$(top_srcdir)/m4/druntime.m4 $(top_srcdir)/m4/druntime/cpu.m4 \\\n\t$(top_srcdir)/m4/druntime/os.m4 \\\n\t$(top_srcdir)/m4/druntime/libraries.m4 \\\n\t$(top_srcdir)/configure.ac\nam__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \\\n\t$(ACLOCAL_M4)\nmkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs\nCONFIG_HEADER = $(top_builddir)/config.h\nCONFIG_CLEAN_FILES =\nCONFIG_CLEAN_VPATH_FILES =\nam__vpath_adj_setup = srcdirstrip=`echo \"$(srcdir)\" | sed 's|.|.|g'`;\nam__vpath_adj = case $$p in \\\n    $(srcdir)/*) f=`echo \"$$p\" | sed \"s|^$$srcdirstrip/||\"`;; \\\n    *) f=$$p;; \\\n  esac;\nam__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;\nam__install_max = 40\nam__nobase_strip_setup = \\\n  srcdirstrip=`echo \"$(srcdir)\" | sed 's/[].[^$$\\\\*|]/\\\\\\\\&/g'`\nam__nobase_strip = \\\n  for p in $$list; do echo \"$$p\"; done | sed -e \"s|$$srcdirstrip/||\"\nam__nobase_list = $(am__nobase_strip_setup); \\\n  for p in $$list; do echo \"$$p $$p\"; done | \\\n  sed \"s| $$srcdirstrip/| |;\"' / .*\\//!s/ .*/ ./; s,\\( .*\\)/[^/]*$$,\\1,' | \\\n  $(AWK) 'BEGIN { files[\".\"] = \"\" } { files[$$2] = files[$$2] \" \" $$1; \\\n    if (++n[$$2] == $(am__install_max)) \\\n      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = \"\" } } \\\n    END { for (dir in files) print dir, files[dir] }'\nam__base_list = \\\n  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\\n/ /g' | \\\n  sed '$$!N;$$!N;$$!N;$$!N;s/\\n/ /g'\nam__uninstall_files_from_dir = { \\\n  test -z \"$$files\" \\\n    || { test ! -d \"$$dir\" && test ! -f \"$$dir\" && test ! -r \"$$dir\"; } \\\n    || { echo \" ( cd '$$dir' && rm -f\" $$files \")\"; \\\n         $(am__cd) \"$$dir\" && rm -f $$files; }; \\\n  }\nam__installdirs = \"$(DESTDIR)$(toolexeclibdir)\"\nLTLIBRARIES = $(toolexeclib_LTLIBRARIES)\nam__DEPENDENCIES_1 =\nlibgdruntime_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \\\n\t$(am__DEPENDENCIES_1)\nam__dirstamp = $(am__leading_dot)dirstamp\nam__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \\\n\tcore/checkedint.lo core/cpuid.lo core/demangle.lo \\\n\tcore/exception.lo core/internal/abort.lo \\\n\tcore/internal/arrayop.lo core/internal/convert.lo \\\n\tcore/internal/hash.lo core/internal/parseoptions.lo \\\n\tcore/internal/spinlock.lo core/internal/string.lo \\\n\tcore/internal/traits.lo core/math.lo core/memory.lo \\\n\tcore/runtime.lo core/simd.lo core/stdc/assert_.lo \\\n\tcore/stdc/complex.lo core/stdc/config.lo core/stdc/ctype.lo \\\n\tcore/stdc/errno.lo core/stdc/fenv.lo core/stdc/float_.lo \\\n\tcore/stdc/inttypes.lo core/stdc/limits.lo core/stdc/locale.lo \\\n\tcore/stdc/math.lo core/stdc/signal.lo core/stdc/stdarg.lo \\\n\tcore/stdc/stddef.lo core/stdc/stdint.lo core/stdc/stdio.lo \\\n\tcore/stdc/stdlib.lo core/stdc/string.lo core/stdc/tgmath.lo \\\n\tcore/stdc/time.lo core/stdc/wchar_.lo core/stdc/wctype.lo \\\n\tcore/sync/barrier.lo core/sync/condition.lo \\\n\tcore/sync/config.lo core/sync/exception.lo core/sync/mutex.lo \\\n\tcore/sync/rwmutex.lo core/sync/semaphore.lo core/thread.lo \\\n\tcore/time.lo core/vararg.lo gcc/attribute.lo gcc/backtrace.lo \\\n\tgcc/builtins.lo gcc/deh.lo gcc/unwind/arm.lo \\\n\tgcc/unwind/arm_common.lo gcc/unwind/c6x.lo \\\n\tgcc/unwind/generic.lo gcc/unwind/package.lo gcc/unwind/pe.lo \\\n\tobject.lo rt/aApply.lo rt/aApplyR.lo rt/aaA.lo rt/adi.lo \\\n\trt/arrayassign.lo rt/arraycast.lo rt/arraycat.lo rt/cast_.lo \\\n\trt/config.lo rt/critical_.lo rt/deh.lo rt/dmain2.lo \\\n\trt/ehalloc.lo rt/invariant.lo rt/lifetime.lo rt/memory.lo \\\n\trt/minfo.lo rt/monitor_.lo rt/obj.lo rt/qsort.lo \\\n\trt/sections.lo rt/sections_android.lo \\\n\trt/sections_elf_shared.lo rt/sections_osx_x86.lo \\\n\trt/sections_osx_x86_64.lo rt/sections_solaris.lo \\\n\trt/sections_win32.lo rt/sections_win64.lo rt/tlsgc.lo \\\n\trt/typeinfo/ti_Acdouble.lo rt/typeinfo/ti_Acfloat.lo \\\n\trt/typeinfo/ti_Acreal.lo rt/typeinfo/ti_Adouble.lo \\\n\trt/typeinfo/ti_Afloat.lo rt/typeinfo/ti_Ag.lo \\\n\trt/typeinfo/ti_Aint.lo rt/typeinfo/ti_Along.lo \\\n\trt/typeinfo/ti_Areal.lo rt/typeinfo/ti_Ashort.lo \\\n\trt/typeinfo/ti_C.lo rt/typeinfo/ti_byte.lo \\\n\trt/typeinfo/ti_cdouble.lo rt/typeinfo/ti_cent.lo \\\n\trt/typeinfo/ti_cfloat.lo rt/typeinfo/ti_char.lo \\\n\trt/typeinfo/ti_creal.lo rt/typeinfo/ti_dchar.lo \\\n\trt/typeinfo/ti_delegate.lo rt/typeinfo/ti_double.lo \\\n\trt/typeinfo/ti_float.lo rt/typeinfo/ti_idouble.lo \\\n\trt/typeinfo/ti_ifloat.lo rt/typeinfo/ti_int.lo \\\n\trt/typeinfo/ti_ireal.lo rt/typeinfo/ti_long.lo \\\n\trt/typeinfo/ti_n.lo rt/typeinfo/ti_ptr.lo \\\n\trt/typeinfo/ti_real.lo rt/typeinfo/ti_short.lo \\\n\trt/typeinfo/ti_ubyte.lo rt/typeinfo/ti_ucent.lo \\\n\trt/typeinfo/ti_uint.lo rt/typeinfo/ti_ulong.lo \\\n\trt/typeinfo/ti_ushort.lo rt/typeinfo/ti_void.lo \\\n\trt/typeinfo/ti_wchar.lo rt/util/array.lo \\\n\trt/util/container/array.lo rt/util/container/common.lo \\\n\trt/util/container/hashtab.lo rt/util/container/treap.lo \\\n\trt/util/random.lo rt/util/typeinfo.lo rt/util/utf.lo\nam__objects_2 = gc/bits.lo gc/config.lo gc/gcinterface.lo \\\n\tgc/impl/conservative/gc.lo gc/impl/manual/gc.lo \\\n\tgc/impl/proto/gc.lo gc/os.lo gc/pooltable.lo gc/proxy.lo\n@DRUNTIME_GC_ENABLE_TRUE@am__objects_3 = $(am__objects_2)\nam__objects_4 =\nam__objects_5 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \\\n\tcore/sys/posix/config.lo core/sys/posix/dirent.lo \\\n\tcore/sys/posix/dlfcn.lo core/sys/posix/fcntl.lo \\\n\tcore/sys/posix/grp.lo core/sys/posix/iconv.lo \\\n\tcore/sys/posix/inttypes.lo core/sys/posix/libgen.lo \\\n\tcore/sys/posix/mqueue.lo core/sys/posix/net/if_.lo \\\n\tcore/sys/posix/netdb.lo core/sys/posix/netinet/in_.lo \\\n\tcore/sys/posix/netinet/tcp.lo core/sys/posix/poll.lo \\\n\tcore/sys/posix/pthread.lo core/sys/posix/pwd.lo \\\n\tcore/sys/posix/sched.lo core/sys/posix/semaphore.lo \\\n\tcore/sys/posix/setjmp.lo core/sys/posix/signal.lo \\\n\tcore/sys/posix/spawn.lo core/sys/posix/stdio.lo \\\n\tcore/sys/posix/stdlib.lo core/sys/posix/sys/filio.lo \\\n\tcore/sys/posix/sys/ioccom.lo core/sys/posix/sys/ioctl.lo \\\n\tcore/sys/posix/sys/ipc.lo core/sys/posix/sys/mman.lo \\\n\tcore/sys/posix/sys/msg.lo core/sys/posix/sys/resource.lo \\\n\tcore/sys/posix/sys/select.lo core/sys/posix/sys/shm.lo \\\n\tcore/sys/posix/sys/socket.lo core/sys/posix/sys/stat.lo \\\n\tcore/sys/posix/sys/statvfs.lo core/sys/posix/sys/time.lo \\\n\tcore/sys/posix/sys/ttycom.lo core/sys/posix/sys/types.lo \\\n\tcore/sys/posix/sys/uio.lo core/sys/posix/sys/un.lo \\\n\tcore/sys/posix/sys/utsname.lo core/sys/posix/sys/wait.lo \\\n\tcore/sys/posix/syslog.lo core/sys/posix/termios.lo \\\n\tcore/sys/posix/time.lo core/sys/posix/ucontext.lo \\\n\tcore/sys/posix/unistd.lo core/sys/posix/utime.lo\n@DRUNTIME_OS_UNIX_TRUE@am__objects_6 = $(am__objects_5)\nam__objects_7 = core/sys/darwin/dlfcn.lo core/sys/darwin/execinfo.lo \\\n\tcore/sys/darwin/mach/dyld.lo core/sys/darwin/mach/getsect.lo \\\n\tcore/sys/darwin/mach/kern_return.lo \\\n\tcore/sys/darwin/mach/loader.lo core/sys/darwin/mach/port.lo \\\n\tcore/sys/darwin/mach/semaphore.lo \\\n\tcore/sys/darwin/mach/thread_act.lo \\\n\tcore/sys/darwin/netinet/in_.lo core/sys/darwin/pthread.lo \\\n\tcore/sys/darwin/sys/cdefs.lo core/sys/darwin/sys/event.lo \\\n\tcore/sys/darwin/sys/mman.lo\nam__objects_8 = core/sys/osx/execinfo.lo core/sys/osx/mach/dyld.lo \\\n\tcore/sys/osx/mach/getsect.lo core/sys/osx/mach/kern_return.lo \\\n\tcore/sys/osx/mach/loader.lo core/sys/osx/mach/port.lo \\\n\tcore/sys/osx/mach/semaphore.lo core/sys/osx/mach/thread_act.lo \\\n\tcore/sys/osx/pthread.lo core/sys/osx/sys/cdefs.lo \\\n\tcore/sys/osx/sys/event.lo core/sys/osx/sys/mman.lo\n@DRUNTIME_OS_DARWIN_TRUE@am__objects_9 = $(am__objects_7) \\\n@DRUNTIME_OS_DARWIN_TRUE@\t$(am__objects_8)\nam__objects_10 = core/sys/bionic/fcntl.lo core/sys/bionic/unistd.lo\n@DRUNTIME_OS_ANDROID_TRUE@am__objects_11 = $(am__objects_10)\nam__objects_12 = core/sys/freebsd/dlfcn.lo \\\n\tcore/sys/freebsd/execinfo.lo core/sys/freebsd/netinet/in_.lo \\\n\tcore/sys/freebsd/pthread_np.lo core/sys/freebsd/sys/_bitset.lo \\\n\tcore/sys/freebsd/sys/_cpuset.lo core/sys/freebsd/sys/cdefs.lo \\\n\tcore/sys/freebsd/sys/elf.lo core/sys/freebsd/sys/elf32.lo \\\n\tcore/sys/freebsd/sys/elf64.lo \\\n\tcore/sys/freebsd/sys/elf_common.lo \\\n\tcore/sys/freebsd/sys/event.lo core/sys/freebsd/sys/link_elf.lo \\\n\tcore/sys/freebsd/sys/mman.lo core/sys/freebsd/sys/mount.lo \\\n\tcore/sys/freebsd/time.lo core/sys/freebsd/unistd.lo\n@DRUNTIME_OS_FREEBSD_TRUE@am__objects_13 = $(am__objects_12)\nam__objects_14 = core/sys/openbsd/dlfcn.lo\n@DRUNTIME_OS_OPENBSD_TRUE@am__objects_15 = $(am__objects_14)\nam__objects_16 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \\\n\tcore/sys/linux/elf.lo core/sys/linux/epoll.lo \\\n\tcore/sys/linux/errno.lo core/sys/linux/execinfo.lo \\\n\tcore/sys/linux/fcntl.lo core/sys/linux/ifaddrs.lo \\\n\tcore/sys/linux/link.lo core/sys/linux/netinet/in_.lo \\\n\tcore/sys/linux/netinet/tcp.lo core/sys/linux/sched.lo \\\n\tcore/sys/linux/stdio.lo core/sys/linux/sys/auxv.lo \\\n\tcore/sys/linux/sys/eventfd.lo core/sys/linux/sys/file.lo \\\n\tcore/sys/linux/sys/inotify.lo core/sys/linux/sys/mman.lo \\\n\tcore/sys/linux/sys/netinet/tcp.lo core/sys/linux/sys/prctl.lo \\\n\tcore/sys/linux/sys/signalfd.lo core/sys/linux/sys/socket.lo \\\n\tcore/sys/linux/sys/sysinfo.lo core/sys/linux/sys/time.lo \\\n\tcore/sys/linux/sys/xattr.lo core/sys/linux/termios.lo \\\n\tcore/sys/linux/time.lo core/sys/linux/timerfd.lo \\\n\tcore/sys/linux/tipc.lo core/sys/linux/unistd.lo\n@DRUNTIME_OS_LINUX_TRUE@am__objects_17 = $(am__objects_16)\nam__objects_18 = core/sys/windows/accctrl.lo \\\n\tcore/sys/windows/aclapi.lo core/sys/windows/aclui.lo \\\n\tcore/sys/windows/basetsd.lo core/sys/windows/basetyps.lo \\\n\tcore/sys/windows/cderr.lo core/sys/windows/cguid.lo \\\n\tcore/sys/windows/com.lo core/sys/windows/comcat.lo \\\n\tcore/sys/windows/commctrl.lo core/sys/windows/commdlg.lo \\\n\tcore/sys/windows/core.lo core/sys/windows/cpl.lo \\\n\tcore/sys/windows/cplext.lo core/sys/windows/custcntl.lo \\\n\tcore/sys/windows/dbghelp.lo core/sys/windows/dbghelp_types.lo \\\n\tcore/sys/windows/dbt.lo core/sys/windows/dde.lo \\\n\tcore/sys/windows/ddeml.lo core/sys/windows/dhcpcsdk.lo \\\n\tcore/sys/windows/dlgs.lo core/sys/windows/dll.lo \\\n\tcore/sys/windows/docobj.lo core/sys/windows/errorrep.lo \\\n\tcore/sys/windows/exdisp.lo core/sys/windows/exdispid.lo \\\n\tcore/sys/windows/httpext.lo core/sys/windows/idispids.lo \\\n\tcore/sys/windows/imagehlp.lo core/sys/windows/imm.lo \\\n\tcore/sys/windows/intshcut.lo core/sys/windows/ipexport.lo \\\n\tcore/sys/windows/iphlpapi.lo core/sys/windows/ipifcons.lo \\\n\tcore/sys/windows/iprtrmib.lo core/sys/windows/iptypes.lo \\\n\tcore/sys/windows/isguids.lo core/sys/windows/lm.lo \\\n\tcore/sys/windows/lmaccess.lo core/sys/windows/lmalert.lo \\\n\tcore/sys/windows/lmapibuf.lo core/sys/windows/lmat.lo \\\n\tcore/sys/windows/lmaudit.lo core/sys/windows/lmbrowsr.lo \\\n\tcore/sys/windows/lmchdev.lo core/sys/windows/lmconfig.lo \\\n\tcore/sys/windows/lmcons.lo core/sys/windows/lmerr.lo \\\n\tcore/sys/windows/lmerrlog.lo core/sys/windows/lmmsg.lo \\\n\tcore/sys/windows/lmremutl.lo core/sys/windows/lmrepl.lo \\\n\tcore/sys/windows/lmserver.lo core/sys/windows/lmshare.lo \\\n\tcore/sys/windows/lmsname.lo core/sys/windows/lmstats.lo \\\n\tcore/sys/windows/lmsvc.lo core/sys/windows/lmuse.lo \\\n\tcore/sys/windows/lmuseflg.lo core/sys/windows/lmwksta.lo \\\n\tcore/sys/windows/lzexpand.lo core/sys/windows/mapi.lo \\\n\tcore/sys/windows/mciavi.lo core/sys/windows/mcx.lo \\\n\tcore/sys/windows/mgmtapi.lo core/sys/windows/mmsystem.lo \\\n\tcore/sys/windows/msacm.lo core/sys/windows/mshtml.lo \\\n\tcore/sys/windows/mswsock.lo core/sys/windows/nb30.lo \\\n\tcore/sys/windows/nddeapi.lo core/sys/windows/nspapi.lo \\\n\tcore/sys/windows/ntdef.lo core/sys/windows/ntdll.lo \\\n\tcore/sys/windows/ntldap.lo core/sys/windows/ntsecapi.lo \\\n\tcore/sys/windows/ntsecpkg.lo core/sys/windows/oaidl.lo \\\n\tcore/sys/windows/objbase.lo core/sys/windows/objfwd.lo \\\n\tcore/sys/windows/objidl.lo core/sys/windows/objsafe.lo \\\n\tcore/sys/windows/ocidl.lo core/sys/windows/odbcinst.lo \\\n\tcore/sys/windows/ole.lo core/sys/windows/ole2.lo \\\n\tcore/sys/windows/ole2ver.lo core/sys/windows/oleacc.lo \\\n\tcore/sys/windows/oleauto.lo core/sys/windows/olectl.lo \\\n\tcore/sys/windows/olectlid.lo core/sys/windows/oledlg.lo \\\n\tcore/sys/windows/oleidl.lo core/sys/windows/pbt.lo \\\n\tcore/sys/windows/powrprof.lo core/sys/windows/prsht.lo \\\n\tcore/sys/windows/psapi.lo core/sys/windows/rapi.lo \\\n\tcore/sys/windows/ras.lo core/sys/windows/rasdlg.lo \\\n\tcore/sys/windows/raserror.lo core/sys/windows/rassapi.lo \\\n\tcore/sys/windows/reason.lo core/sys/windows/regstr.lo \\\n\tcore/sys/windows/richedit.lo core/sys/windows/richole.lo \\\n\tcore/sys/windows/rpc.lo core/sys/windows/rpcdce.lo \\\n\tcore/sys/windows/rpcdce2.lo core/sys/windows/rpcdcep.lo \\\n\tcore/sys/windows/rpcndr.lo core/sys/windows/rpcnsi.lo \\\n\tcore/sys/windows/rpcnsip.lo core/sys/windows/rpcnterr.lo \\\n\tcore/sys/windows/schannel.lo core/sys/windows/secext.lo \\\n\tcore/sys/windows/security.lo core/sys/windows/servprov.lo \\\n\tcore/sys/windows/setupapi.lo core/sys/windows/shellapi.lo \\\n\tcore/sys/windows/shldisp.lo core/sys/windows/shlguid.lo \\\n\tcore/sys/windows/shlobj.lo core/sys/windows/shlwapi.lo \\\n\tcore/sys/windows/snmp.lo core/sys/windows/sql.lo \\\n\tcore/sys/windows/sqlext.lo core/sys/windows/sqltypes.lo \\\n\tcore/sys/windows/sqlucode.lo core/sys/windows/sspi.lo \\\n\tcore/sys/windows/stacktrace.lo core/sys/windows/stat.lo \\\n\tcore/sys/windows/subauth.lo core/sys/windows/threadaux.lo \\\n\tcore/sys/windows/tlhelp32.lo core/sys/windows/tmschema.lo \\\n\tcore/sys/windows/unknwn.lo core/sys/windows/uuid.lo \\\n\tcore/sys/windows/vfw.lo core/sys/windows/w32api.lo \\\n\tcore/sys/windows/winbase.lo core/sys/windows/winber.lo \\\n\tcore/sys/windows/wincon.lo core/sys/windows/wincrypt.lo \\\n\tcore/sys/windows/windef.lo core/sys/windows/windows.lo \\\n\tcore/sys/windows/winerror.lo core/sys/windows/wingdi.lo \\\n\tcore/sys/windows/winhttp.lo core/sys/windows/wininet.lo \\\n\tcore/sys/windows/winioctl.lo core/sys/windows/winldap.lo \\\n\tcore/sys/windows/winnetwk.lo core/sys/windows/winnls.lo \\\n\tcore/sys/windows/winnt.lo core/sys/windows/winperf.lo \\\n\tcore/sys/windows/winreg.lo core/sys/windows/winsock2.lo \\\n\tcore/sys/windows/winspool.lo core/sys/windows/winsvc.lo \\\n\tcore/sys/windows/winuser.lo core/sys/windows/winver.lo \\\n\tcore/sys/windows/wtsapi32.lo core/sys/windows/wtypes.lo\n@DRUNTIME_OS_MINGW_TRUE@am__objects_19 = $(am__objects_18)\nam__objects_20 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \\\n\tcore/sys/solaris/execinfo.lo core/sys/solaris/libelf.lo \\\n\tcore/sys/solaris/link.lo core/sys/solaris/sys/elf.lo \\\n\tcore/sys/solaris/sys/elf_386.lo \\\n\tcore/sys/solaris/sys/elf_SPARC.lo \\\n\tcore/sys/solaris/sys/elf_amd64.lo \\\n\tcore/sys/solaris/sys/elf_notes.lo \\\n\tcore/sys/solaris/sys/elftypes.lo core/sys/solaris/sys/link.lo \\\n\tcore/sys/solaris/sys/priocntl.lo \\\n\tcore/sys/solaris/sys/procset.lo core/sys/solaris/sys/types.lo \\\n\tcore/sys/solaris/time.lo\n@DRUNTIME_OS_SOLARIS_TRUE@am__objects_21 = $(am__objects_20)\nam__objects_22 = core/sys/dragonflybsd/dlfcn.lo \\\n\tcore/sys/dragonflybsd/execinfo.lo \\\n\tcore/sys/dragonflybsd/netinet/in_.lo \\\n\tcore/sys/dragonflybsd/pthread_np.lo \\\n\tcore/sys/dragonflybsd/sys/_bitset.lo \\\n\tcore/sys/dragonflybsd/sys/_cpuset.lo \\\n\tcore/sys/dragonflybsd/sys/cdefs.lo \\\n\tcore/sys/dragonflybsd/sys/elf.lo \\\n\tcore/sys/dragonflybsd/sys/elf32.lo \\\n\tcore/sys/dragonflybsd/sys/elf64.lo \\\n\tcore/sys/dragonflybsd/sys/elf_common.lo \\\n\tcore/sys/dragonflybsd/sys/event.lo \\\n\tcore/sys/dragonflybsd/sys/link_elf.lo \\\n\tcore/sys/dragonflybsd/sys/mman.lo \\\n\tcore/sys/dragonflybsd/time.lo\n@DRUNTIME_OS_DRAGONFLYBSD_TRUE@am__objects_23 = $(am__objects_22)\nam__objects_24 = gcc/config.lo gcc/libbacktrace.lo\nam__objects_25 = $(am__objects_1) $(am__objects_3) $(am__objects_4) \\\n\t$(am__objects_6) $(am__objects_9) $(am__objects_11) \\\n\t$(am__objects_13) $(am__objects_15) $(am__objects_17) \\\n\t$(am__objects_19) $(am__objects_21) $(am__objects_23) \\\n\t$(am__objects_24)\nam__objects_26 = libgdruntime_la-errno_.lo\nam__objects_27 = libgdruntime_la-threadasm.lo\nam__objects_28 = $(am__objects_25) $(am__objects_26) $(am__objects_27)\nam_libgdruntime_la_OBJECTS = $(am__objects_28)\nlibgdruntime_la_OBJECTS = $(am_libgdruntime_la_OBJECTS)\nlibgdruntime_t_la_DEPENDENCIES = $(DRUNTIME_TEST_LOBJECTS) \\\n\t$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)\nam__objects_29 = libgdruntime_t_la-errno_.lo\nam__objects_30 = libgdruntime_t_la-threadasm.lo\nam_libgdruntime_t_la_OBJECTS = $(am__objects_29) $(am__objects_30)\nlibgdruntime_t_la_OBJECTS = $(am_libgdruntime_t_la_OBJECTS)\n@ENABLE_SHARED_TRUE@am_libgdruntime_t_la_rpath =\n@ENABLE_SHARED_TRUE@am__EXEEXT_1 = unittest$(EXEEXT)\n@ENABLE_STATIC_TRUE@am__EXEEXT_2 = unittest_static$(EXEEXT)\nam_unittest_OBJECTS = ../testsuite/test_runner.$(OBJEXT)\nunittest_OBJECTS = $(am_unittest_OBJECTS)\nunittest_DEPENDENCIES = libgdruntime_t.la\nam__objects_31 = errno_.$(OBJEXT)\nam__objects_32 = threadasm.$(OBJEXT)\nam_unittest_static_OBJECTS = ../testsuite/test_runner.$(OBJEXT) \\\n\t$(am__objects_31) $(am__objects_32)\nunittest_static_OBJECTS = $(am_unittest_static_OBJECTS)\nunittest_static_DEPENDENCIES = $(DRUNTIME_TEST_OBJECTS) \\\n\t$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)\nDEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)\ndepcomp =\nam__depfiles_maybe =\nCPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \\\n\t$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)\nLTCPPASCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \\\n\t--mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \\\n\t$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)\nCOMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \\\n\t$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)\nLTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \\\n\t--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \\\n\t$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)\nLINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \\\n\t--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\nSOURCES = $(libgdruntime_la_SOURCES) $(libgdruntime_t_la_SOURCES) \\\n\t$(unittest_SOURCES) $(unittest_static_SOURCES)\nam__can_run_installinfo = \\\n  case $$AM_UPDATE_INFO_DIR in \\\n    n|no|NO) false;; \\\n    *) (install-info --version) >/dev/null 2>&1;; \\\n  esac\nETAGS = etags\nCTAGS = ctags\nACLOCAL = @ACLOCAL@\nAMTAR = @AMTAR@\nAR = @AR@\nAUTOCONF = @AUTOCONF@\nAUTOHEADER = @AUTOHEADER@\nAUTOMAKE = @AUTOMAKE@\nAWK = @AWK@\nBACKTRACE_SUPPORTED = @BACKTRACE_SUPPORTED@\nBACKTRACE_SUPPORTS_THREADS = @BACKTRACE_SUPPORTS_THREADS@\nBACKTRACE_USES_MALLOC = @BACKTRACE_USES_MALLOC@\nCC = @CC@\nCCAS = @CCAS@\nCCASFLAGS = @CCASFLAGS@\nCC_FOR_BUILD = @CC_FOR_BUILD@\nCFLAGS = @CFLAGS@\nCFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@\nCPP = @CPP@\nCPPFLAGS = @CPPFLAGS@\nCYGPATH_W = @CYGPATH_W@\nDCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@\nDCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@\nDCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@\nDCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@\nDCFG_MINFO_BRACKETING = @DCFG_MINFO_BRACKETING@\nDCFG_THREAD_MODEL = @DCFG_THREAD_MODEL@\nDEFS = @DEFS@\nDRUNTIME_SOVERSION = @DRUNTIME_SOVERSION@\nDSYMUTIL = @DSYMUTIL@\nDUMPBIN = @DUMPBIN@\nECHO_C = @ECHO_C@\nECHO_N = @ECHO_N@\nECHO_T = @ECHO_T@\nEGREP = @EGREP@\nEXEEXT = @EXEEXT@\nFGREP = @FGREP@\nGDC = @GDC@\nGDCFLAGS = @GDCFLAGS@\nGDCFLAGSX = @GDCFLAGSX@\nGREP = @GREP@\nINSTALL = @INSTALL@\nINSTALL_DATA = @INSTALL_DATA@\nINSTALL_PROGRAM = @INSTALL_PROGRAM@\nINSTALL_SCRIPT = @INSTALL_SCRIPT@\nINSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@\nLD = @LD@\nLDFLAGS = @LDFLAGS@\nLIBATOMIC = @LIBATOMIC@\nLIBBACKTRACE = @LIBBACKTRACE@\nLIBOBJS = @LIBOBJS@\nLIBS = @LIBS@\nLIBTOOL = @LIBTOOL@\nLIPO = @LIPO@\nLN_S = @LN_S@\nLTLIBOBJS = @LTLIBOBJS@\nMAINT = @MAINT@\nMAKEINFO = @MAKEINFO@\nMKDIR_P = @MKDIR_P@\nNM = @NM@\nNMEDIT = @NMEDIT@\nOBJDUMP = @OBJDUMP@\nOBJEXT = @OBJEXT@\nOTOOL = @OTOOL@\nOTOOL64 = @OTOOL64@\nPACKAGE = @PACKAGE@\nPACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@\nPACKAGE_NAME = @PACKAGE_NAME@\nPACKAGE_STRING = @PACKAGE_STRING@\nPACKAGE_TARNAME = @PACKAGE_TARNAME@\nPACKAGE_URL = @PACKAGE_URL@\nPACKAGE_VERSION = @PACKAGE_VERSION@\nPATH_SEPARATOR = @PATH_SEPARATOR@\nPHOBOS_SOVERSION = @PHOBOS_SOVERSION@\nRANLIB = @RANLIB@\nSED = @SED@\nSET_MAKE = @SET_MAKE@\nSHELL = @SHELL@\nSPEC_PHOBOS_DEPS = @SPEC_PHOBOS_DEPS@\nSTRIP = @STRIP@\nVERSION = @VERSION@\nabs_builddir = @abs_builddir@\nabs_srcdir = @abs_srcdir@\nabs_top_builddir = @abs_top_builddir@\nabs_top_srcdir = @abs_top_srcdir@\nac_ct_CC = @ac_ct_CC@\nac_ct_DUMPBIN = @ac_ct_DUMPBIN@\nam__leading_dot = @am__leading_dot@\nam__tar = @am__tar@\nam__untar = @am__untar@\nbindir = @bindir@\nbuild = @build@\nbuild_alias = @build_alias@\nbuild_cpu = @build_cpu@\nbuild_os = @build_os@\nbuild_vendor = @build_vendor@\nbuilddir = @builddir@\ndatadir = @datadir@\ndatarootdir = @datarootdir@\ndocdir = @docdir@\ndvidir = @dvidir@\nexec_prefix = @exec_prefix@\ngcc_version = @gcc_version@\ngdc_include_dir = @gdc_include_dir@\nget_gcc_base_ver = @get_gcc_base_ver@\nhost = @host@\nhost_alias = @host_alias@\nhost_cpu = @host_cpu@\nhost_os = @host_os@\nhost_vendor = @host_vendor@\nhtmldir = @htmldir@\nincludedir = @includedir@\ninfodir = @infodir@\ninstall_sh = @install_sh@\nlibdir = @libdir@\nlibexecdir = @libexecdir@\nlibphobos_builddir = @libphobos_builddir@\nlibphobos_srcdir = @libphobos_srcdir@\nlocaledir = @localedir@\nlocalstatedir = @localstatedir@\nmandir = @mandir@\nmkdir_p = @mkdir_p@\nmulti_basedir = @multi_basedir@\noldincludedir = @oldincludedir@\npdfdir = @pdfdir@\nphobos_compiler_pic_flag = @phobos_compiler_pic_flag@\nphobos_compiler_shared_flag = @phobos_compiler_shared_flag@\nprefix = @prefix@\nprogram_transform_name = @program_transform_name@\npsdir = @psdir@\nsbindir = @sbindir@\nsharedstatedir = @sharedstatedir@\nsrcdir = @srcdir@\nsysconfdir = @sysconfdir@\ntarget = @target@\ntarget_alias = @target_alias@\ntarget_cpu = @target_cpu@\ntarget_os = @target_os@\ntarget_vendor = @target_vendor@\ntoolexecdir = @toolexecdir@\ntoolexeclibdir = @toolexeclibdir@\ntop_build_prefix = @top_build_prefix@\ntop_builddir = @top_builddir@\ntop_srcdir = @top_srcdir@\n\n# If there are no sources with known extension (i.e. only D sources)\n# automake forgets to set this\nCCLD = $(CC)\nLTDCOMPILE = $(LIBTOOL) --tag=D $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \\\n\t--mode=compile $(GDC) $(AM_DFLAGS)\n\n\n# Override executable linking commands: We have to use GDC for linking\n# to make sure we link pthreads and other dependencies\nunittest_static_LINK = $(LIBTOOL) --tag=D \\\n\t$(unittest_static_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \\\n\t$(GDC) $(AM_CFLAGS) $(CFLAGS) $(unittest_static_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\n\nunittest_LINK = $(LIBTOOL) --tag=D \\\n\t$(unittest_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \\\n\t$(GDC) $(AM_CFLAGS) $(CFLAGS) $(unittest_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\n\n\n# Also override library link commands: This is not strictly\n# required, but we want to record additional dependencies such\n# as pthread in the library\nlibgdruntime_la_LINK = $(LIBTOOL) --tag=D $(AM_LIBTOOLFLAGS) \\\n\t$(LIBTOOLFLAGS) --mode=link $(GDC) $(AM_CFLAGS) $(CFLAGS) \\\n\t$(libgdruntime_la_LDFLAGS) $(LDFLAGS) -o $@\n\nlibgdruntime_t_la_LINK = $(LIBTOOL) --tag=D $(AM_LIBTOOLFLAGS) \\\n\t$(LIBTOOLFLAGS) --mode=link $(GDC) $(AM_CFLAGS) $(CFLAGS) \\\n\t$(libgdruntime_t_la_LDFLAGS) $(LDFLAGS) -o $@\n\nlibgphobos_la_LINK = $(LIBTOOL) --tag=D $(libgphobos_la_LIBTOOLFLAGS) \\\n\t$(LIBTOOLFLAGS) --mode=link $(GDC) $(AM_CFLAGS) $(CFLAGS) \\\n\t$(libgphobos_la_LDFLAGS) $(LDFLAGS) -o $@\n\nlibgphobos_t_la_LINK = $(LIBTOOL) --tag=D \\\n\t$(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \\\n\t$(GDC) $(AM_CFLAGS) $(CFLAGS) $(libgphobos_t_la_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\n\n\n# Include D build rules\n\n# Make sure GDC can find libdruntime include files\nD_EXTRA_DFLAGS = -nostdinc -I $(srcdir) -I .\n\n# D flags for compilation\nAM_DFLAGS = $(phobos_compiler_pic_flag)\n\n# Install all D and DI files\nALL_DRUNTIME_INSTALL_DSOURCES = $(DRUNTIME_DSOURCES) \\\n\t$(DRUNTIME_DSOURCES_GC) $(DRUNTIME_DSOURCES_GCSTUB) \\\n\t$(DRUNTIME_DSOURCES_BIONIC) $(DRUNTIME_DSOURCES_DARWIN) \\\n\t$(DRUNTIME_DSOURCES_DRAGONFLYBSD) $(DRUNTIME_DSOURCES_FREEBSD) \\\n\t$(DRUNTIME_DSOURCES_LINUX) $(DRUNTIME_DSOURCES_OPENBSD) \\\n\t$(DRUNTIME_DSOURCES_OSX) $(DRUNTIME_DSOURCES_POSIX) \\\n\t$(DRUNTIME_DSOURCES_SOLARIS) $(DRUNTIME_DSOURCES_WINDOWS) \\\n\t$(DRUNTIME_DSOURCES_GENERATED) $(DRUNTIME_DSOURCES_STDCXX) \\\n\t$(DRUNTIME_DISOURCES)\n\n\n# Setup source files depending on configure\n# Generated by configure\nALL_DRUNTIME_COMPILE_DSOURCES = $(DRUNTIME_DSOURCES) $(am__append_1) \\\n\t$(am__append_2) $(am__append_3) $(am__append_4) \\\n\t$(am__append_5) $(am__append_6) $(am__append_7) \\\n\t$(am__append_8) $(am__append_9) $(am__append_10) \\\n\t$(am__append_11) $(DRUNTIME_DSOURCES_GENERATED)\nALL_DRUNTIME_SOURCES = $(ALL_DRUNTIME_COMPILE_DSOURCES) $(DRUNTIME_CSOURCES) \\\n\t$(DRUNTIME_SSOURCES)\n\nREAL_DRUNTIME_TEST_LOBJECTS = $(ALL_DRUNTIME_COMPILE_DSOURCES:.d=.t.lo)\nREAL_DRUNTIME_TEST_OBJECTS = $(ALL_DRUNTIME_COMPILE_DSOURCES:.d=.t.o)\n# Workaround issue #\nDRUNTIME_TEST_OBJECTS = $(filter-out rt/util/typeinfo.t.o \\\n\tcore/internal/convert.t.o, $(REAL_DRUNTIME_TEST_OBJECTS)) \\\n\trt/util/typeinfo.o core/internal/convert.o\n\nDRUNTIME_TEST_LOBJECTS = $(filter-out rt/util/typeinfo.t.lo \\\n\tcore/internal/convert.t.lo, $(REAL_DRUNTIME_TEST_LOBJECTS)) \\\n\trt/util/typeinfo.lo core/internal/convert.lo\n\n@ENABLE_SHARED_TRUE@check_LTLIBRARIES = libgdruntime_t.la\ntoolexeclib_LTLIBRARIES = libgdruntime.la\nlibgdruntime_la_SOURCES = $(ALL_DRUNTIME_SOURCES)\nlibgdruntime_la_LIBTOOLFLAGS = \nlibgdruntime_la_LDFLAGS = -Xcompiler -nophoboslib -version-info $(DRUNTIME_SOVERSION)\nlibgdruntime_la_LIBADD = $(LIBATOMIC) $(LIBBACKTRACE)\n\n# For static unittest, link objects directly\nunittest_static_SOURCES = ../testsuite/test_runner.d $(DRUNTIME_CSOURCES) \\\n    $(DRUNTIME_SSOURCES)\n\nunittest_static_LIBTOOLFLAGS = \nunittest_static_LDFLAGS = -Xcompiler -nophoboslib\nunittest_static_LDADD = $(DRUNTIME_TEST_OBJECTS) $(LIBATOMIC) $(LIBBACKTRACE)\nEXTRA_unittest_static_DEPENDENCIES = $(DRUNTIME_TEST_OBJECTS)\n\n# For unittest with dynamic library\nlibgdruntime_t_la_SOURCES = $(DRUNTIME_CSOURCES) $(DRUNTIME_SSOURCES)\nlibgdruntime_t_la_LIBTOOLFLAGS = \n# Automake by default does not generate shared libs for non-installed\n# libraries. Use -rpath to force shared lib generation.\nlibgdruntime_t_la_LDFLAGS = -Xcompiler -nophoboslib -rpath /foo -shared\nlibgdruntime_t_la_LIBADD = $(DRUNTIME_TEST_LOBJECTS) $(LIBATOMIC) $(LIBBACKTRACE)\nEXTRA_libgdruntime_t_la_DEPENDENCIES = $(DRUNTIME_TEST_LOBJECTS)\n\n# For unittest\nunittest_SOURCES = ../testsuite/test_runner.d\nunittest_LIBTOOLFLAGS = \nunittest_LDFLAGS = -Xcompiler -nophoboslib\nunittest_LDADD = libgdruntime_t.la\nDRUNTIME_DSOURCES_GENERATED = gcc/config.d gcc/libbacktrace.d\n# Source file definitions. Boring stuff, auto-generated with\n# https://gist.github.com/jpf91/8ad1dbc9902d6ad876313f134c6527d1\n# Can't use wildcards here:\n# https://www.gnu.org/software/automake/manual/html_node/Wildcards.html\nDRUNTIME_SSOURCES = core/threadasm.S\nDRUNTIME_CSOURCES = core/stdc/errno_.c\nDRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \\\n\tcore/checkedint.d core/cpuid.d core/demangle.d core/exception.d \\\n\tcore/internal/abort.d core/internal/arrayop.d core/internal/convert.d \\\n\tcore/internal/hash.d core/internal/parseoptions.d \\\n\tcore/internal/spinlock.d core/internal/string.d core/internal/traits.d \\\n\tcore/math.d core/memory.d core/runtime.d core/simd.d \\\n\tcore/stdc/assert_.d core/stdc/complex.d core/stdc/config.d \\\n\tcore/stdc/ctype.d core/stdc/errno.d core/stdc/fenv.d \\\n\tcore/stdc/float_.d core/stdc/inttypes.d core/stdc/limits.d \\\n\tcore/stdc/locale.d core/stdc/math.d core/stdc/signal.d \\\n\tcore/stdc/stdarg.d core/stdc/stddef.d core/stdc/stdint.d \\\n\tcore/stdc/stdio.d core/stdc/stdlib.d core/stdc/string.d \\\n\tcore/stdc/tgmath.d core/stdc/time.d core/stdc/wchar_.d \\\n\tcore/stdc/wctype.d core/sync/barrier.d core/sync/condition.d \\\n\tcore/sync/config.d core/sync/exception.d core/sync/mutex.d \\\n\tcore/sync/rwmutex.d core/sync/semaphore.d core/thread.d core/time.d \\\n\tcore/vararg.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \\\n\tgcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \\\n\tgcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \\\n\trt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arrayassign.d \\\n\trt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d rt/critical_.d \\\n\trt/deh.d rt/dmain2.d rt/ehalloc.d rt/invariant.d rt/lifetime.d \\\n\trt/memory.d rt/minfo.d rt/monitor_.d rt/obj.d rt/qsort.d rt/sections.d \\\n\trt/sections_android.d rt/sections_elf_shared.d rt/sections_osx_x86.d \\\n\trt/sections_osx_x86_64.d rt/sections_solaris.d rt/sections_win32.d \\\n\trt/sections_win64.d rt/tlsgc.d rt/typeinfo/ti_Acdouble.d \\\n\trt/typeinfo/ti_Acfloat.d rt/typeinfo/ti_Acreal.d \\\n\trt/typeinfo/ti_Adouble.d rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d \\\n\trt/typeinfo/ti_Aint.d rt/typeinfo/ti_Along.d rt/typeinfo/ti_Areal.d \\\n\trt/typeinfo/ti_Ashort.d rt/typeinfo/ti_C.d rt/typeinfo/ti_byte.d \\\n\trt/typeinfo/ti_cdouble.d rt/typeinfo/ti_cent.d rt/typeinfo/ti_cfloat.d \\\n\trt/typeinfo/ti_char.d rt/typeinfo/ti_creal.d rt/typeinfo/ti_dchar.d \\\n\trt/typeinfo/ti_delegate.d rt/typeinfo/ti_double.d \\\n\trt/typeinfo/ti_float.d rt/typeinfo/ti_idouble.d \\\n\trt/typeinfo/ti_ifloat.d rt/typeinfo/ti_int.d rt/typeinfo/ti_ireal.d \\\n\trt/typeinfo/ti_long.d rt/typeinfo/ti_n.d rt/typeinfo/ti_ptr.d \\\n\trt/typeinfo/ti_real.d rt/typeinfo/ti_short.d rt/typeinfo/ti_ubyte.d \\\n\trt/typeinfo/ti_ucent.d rt/typeinfo/ti_uint.d rt/typeinfo/ti_ulong.d \\\n\trt/typeinfo/ti_ushort.d rt/typeinfo/ti_void.d rt/typeinfo/ti_wchar.d \\\n\trt/util/array.d rt/util/container/array.d rt/util/container/common.d \\\n\trt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \\\n\trt/util/typeinfo.d rt/util/utf.d\n\nDRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \\\n\tcore/stdcpp/typeinfo.d\n\nDRUNTIME_DSOURCES_GC = gc/bits.d gc/config.d gc/gcinterface.d \\\n\tgc/impl/conservative/gc.d gc/impl/manual/gc.d gc/impl/proto/gc.d \\\n\tgc/os.d gc/pooltable.d gc/proxy.d\n\nDRUNTIME_DSOURCES_BIONIC = core/sys/bionic/fcntl.d \\\n\tcore/sys/bionic/unistd.d\n\nDRUNTIME_DSOURCES_DARWIN = core/sys/darwin/dlfcn.d \\\n\tcore/sys/darwin/execinfo.d core/sys/darwin/mach/dyld.d \\\n\tcore/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \\\n\tcore/sys/darwin/mach/loader.d core/sys/darwin/mach/port.d \\\n\tcore/sys/darwin/mach/semaphore.d core/sys/darwin/mach/thread_act.d \\\n\tcore/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \\\n\tcore/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \\\n\tcore/sys/darwin/sys/mman.d\n\nDRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \\\n\tcore/sys/dragonflybsd/execinfo.d core/sys/dragonflybsd/netinet/in_.d \\\n\tcore/sys/dragonflybsd/pthread_np.d core/sys/dragonflybsd/sys/_bitset.d \\\n\tcore/sys/dragonflybsd/sys/_cpuset.d core/sys/dragonflybsd/sys/cdefs.d \\\n\tcore/sys/dragonflybsd/sys/elf.d core/sys/dragonflybsd/sys/elf32.d \\\n\tcore/sys/dragonflybsd/sys/elf64.d \\\n\tcore/sys/dragonflybsd/sys/elf_common.d \\\n\tcore/sys/dragonflybsd/sys/event.d core/sys/dragonflybsd/sys/link_elf.d \\\n\tcore/sys/dragonflybsd/sys/mman.d core/sys/dragonflybsd/time.d\n\nDRUNTIME_DSOURCES_FREEBSD = core/sys/freebsd/dlfcn.d \\\n\tcore/sys/freebsd/execinfo.d core/sys/freebsd/netinet/in_.d \\\n\tcore/sys/freebsd/pthread_np.d core/sys/freebsd/sys/_bitset.d \\\n\tcore/sys/freebsd/sys/_cpuset.d core/sys/freebsd/sys/cdefs.d \\\n\tcore/sys/freebsd/sys/elf.d core/sys/freebsd/sys/elf32.d \\\n\tcore/sys/freebsd/sys/elf64.d core/sys/freebsd/sys/elf_common.d \\\n\tcore/sys/freebsd/sys/event.d core/sys/freebsd/sys/link_elf.d \\\n\tcore/sys/freebsd/sys/mman.d core/sys/freebsd/sys/mount.d \\\n\tcore/sys/freebsd/time.d core/sys/freebsd/unistd.d\n\nDRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \\\n\tcore/sys/linux/dlfcn.d core/sys/linux/elf.d core/sys/linux/epoll.d \\\n\tcore/sys/linux/errno.d core/sys/linux/execinfo.d \\\n\tcore/sys/linux/fcntl.d core/sys/linux/ifaddrs.d core/sys/linux/link.d \\\n\tcore/sys/linux/netinet/in_.d core/sys/linux/netinet/tcp.d \\\n\tcore/sys/linux/sched.d core/sys/linux/stdio.d \\\n\tcore/sys/linux/sys/auxv.d core/sys/linux/sys/eventfd.d \\\n\tcore/sys/linux/sys/file.d core/sys/linux/sys/inotify.d \\\n\tcore/sys/linux/sys/mman.d core/sys/linux/sys/netinet/tcp.d \\\n\tcore/sys/linux/sys/prctl.d core/sys/linux/sys/signalfd.d \\\n\tcore/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \\\n\tcore/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \\\n\tcore/sys/linux/termios.d core/sys/linux/time.d \\\n\tcore/sys/linux/timerfd.d core/sys/linux/tipc.d core/sys/linux/unistd.d\n\nDRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \\\n\tcore/sys/netbsd/execinfo.d core/sys/netbsd/sys/elf.d \\\n\tcore/sys/netbsd/sys/elf32.d core/sys/netbsd/sys/elf64.d \\\n\tcore/sys/netbsd/sys/elf_common.d core/sys/netbsd/sys/event.d \\\n\tcore/sys/netbsd/sys/link_elf.d core/sys/netbsd/sys/mman.d \\\n\tcore/sys/netbsd/time.d\n\nDRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d\nDRUNTIME_DSOURCES_OSX = core/sys/osx/execinfo.d \\\n\tcore/sys/osx/mach/dyld.d core/sys/osx/mach/getsect.d \\\n\tcore/sys/osx/mach/kern_return.d core/sys/osx/mach/loader.d \\\n\tcore/sys/osx/mach/port.d core/sys/osx/mach/semaphore.d \\\n\tcore/sys/osx/mach/thread_act.d core/sys/osx/pthread.d \\\n\tcore/sys/osx/sys/cdefs.d core/sys/osx/sys/event.d \\\n\tcore/sys/osx/sys/mman.d\n\nDRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \\\n\tcore/sys/posix/arpa/inet.d core/sys/posix/config.d \\\n\tcore/sys/posix/dirent.d core/sys/posix/dlfcn.d core/sys/posix/fcntl.d \\\n\tcore/sys/posix/grp.d core/sys/posix/iconv.d core/sys/posix/inttypes.d \\\n\tcore/sys/posix/libgen.d core/sys/posix/mqueue.d \\\n\tcore/sys/posix/net/if_.d core/sys/posix/netdb.d \\\n\tcore/sys/posix/netinet/in_.d core/sys/posix/netinet/tcp.d \\\n\tcore/sys/posix/poll.d core/sys/posix/pthread.d core/sys/posix/pwd.d \\\n\tcore/sys/posix/sched.d core/sys/posix/semaphore.d \\\n\tcore/sys/posix/setjmp.d core/sys/posix/signal.d core/sys/posix/spawn.d \\\n\tcore/sys/posix/stdio.d core/sys/posix/stdlib.d \\\n\tcore/sys/posix/sys/filio.d core/sys/posix/sys/ioccom.d \\\n\tcore/sys/posix/sys/ioctl.d core/sys/posix/sys/ipc.d \\\n\tcore/sys/posix/sys/mman.d core/sys/posix/sys/msg.d \\\n\tcore/sys/posix/sys/resource.d core/sys/posix/sys/select.d \\\n\tcore/sys/posix/sys/shm.d core/sys/posix/sys/socket.d \\\n\tcore/sys/posix/sys/stat.d core/sys/posix/sys/statvfs.d \\\n\tcore/sys/posix/sys/time.d core/sys/posix/sys/ttycom.d \\\n\tcore/sys/posix/sys/types.d core/sys/posix/sys/uio.d \\\n\tcore/sys/posix/sys/un.d core/sys/posix/sys/utsname.d \\\n\tcore/sys/posix/sys/wait.d core/sys/posix/syslog.d \\\n\tcore/sys/posix/termios.d core/sys/posix/time.d \\\n\tcore/sys/posix/ucontext.d core/sys/posix/unistd.d \\\n\tcore/sys/posix/utime.d\n\nDRUNTIME_DSOURCES_SOLARIS = core/sys/solaris/dlfcn.d \\\n\tcore/sys/solaris/elf.d core/sys/solaris/execinfo.d \\\n\tcore/sys/solaris/libelf.d core/sys/solaris/link.d \\\n\tcore/sys/solaris/sys/elf.d core/sys/solaris/sys/elf_386.d \\\n\tcore/sys/solaris/sys/elf_SPARC.d core/sys/solaris/sys/elf_amd64.d \\\n\tcore/sys/solaris/sys/elf_notes.d core/sys/solaris/sys/elftypes.d \\\n\tcore/sys/solaris/sys/link.d core/sys/solaris/sys/priocntl.d \\\n\tcore/sys/solaris/sys/procset.d core/sys/solaris/sys/types.d \\\n\tcore/sys/solaris/time.d\n\nDRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \\\n\tcore/sys/windows/aclapi.d core/sys/windows/aclui.d \\\n\tcore/sys/windows/basetsd.d core/sys/windows/basetyps.d \\\n\tcore/sys/windows/cderr.d core/sys/windows/cguid.d \\\n\tcore/sys/windows/com.d core/sys/windows/comcat.d \\\n\tcore/sys/windows/commctrl.d core/sys/windows/commdlg.d \\\n\tcore/sys/windows/core.d core/sys/windows/cpl.d \\\n\tcore/sys/windows/cplext.d core/sys/windows/custcntl.d \\\n\tcore/sys/windows/dbghelp.d core/sys/windows/dbghelp_types.d \\\n\tcore/sys/windows/dbt.d core/sys/windows/dde.d core/sys/windows/ddeml.d \\\n\tcore/sys/windows/dhcpcsdk.d core/sys/windows/dlgs.d \\\n\tcore/sys/windows/dll.d core/sys/windows/docobj.d \\\n\tcore/sys/windows/errorrep.d core/sys/windows/exdisp.d \\\n\tcore/sys/windows/exdispid.d core/sys/windows/httpext.d \\\n\tcore/sys/windows/idispids.d core/sys/windows/imagehlp.d \\\n\tcore/sys/windows/imm.d core/sys/windows/intshcut.d \\\n\tcore/sys/windows/ipexport.d core/sys/windows/iphlpapi.d \\\n\tcore/sys/windows/ipifcons.d core/sys/windows/iprtrmib.d \\\n\tcore/sys/windows/iptypes.d core/sys/windows/isguids.d \\\n\tcore/sys/windows/lm.d core/sys/windows/lmaccess.d \\\n\tcore/sys/windows/lmalert.d core/sys/windows/lmapibuf.d \\\n\tcore/sys/windows/lmat.d core/sys/windows/lmaudit.d \\\n\tcore/sys/windows/lmbrowsr.d core/sys/windows/lmchdev.d \\\n\tcore/sys/windows/lmconfig.d core/sys/windows/lmcons.d \\\n\tcore/sys/windows/lmerr.d core/sys/windows/lmerrlog.d \\\n\tcore/sys/windows/lmmsg.d core/sys/windows/lmremutl.d \\\n\tcore/sys/windows/lmrepl.d core/sys/windows/lmserver.d \\\n\tcore/sys/windows/lmshare.d core/sys/windows/lmsname.d \\\n\tcore/sys/windows/lmstats.d core/sys/windows/lmsvc.d \\\n\tcore/sys/windows/lmuse.d core/sys/windows/lmuseflg.d \\\n\tcore/sys/windows/lmwksta.d core/sys/windows/lzexpand.d \\\n\tcore/sys/windows/mapi.d core/sys/windows/mciavi.d \\\n\tcore/sys/windows/mcx.d core/sys/windows/mgmtapi.d \\\n\tcore/sys/windows/mmsystem.d core/sys/windows/msacm.d \\\n\tcore/sys/windows/mshtml.d core/sys/windows/mswsock.d \\\n\tcore/sys/windows/nb30.d core/sys/windows/nddeapi.d \\\n\tcore/sys/windows/nspapi.d core/sys/windows/ntdef.d \\\n\tcore/sys/windows/ntdll.d core/sys/windows/ntldap.d \\\n\tcore/sys/windows/ntsecapi.d core/sys/windows/ntsecpkg.d \\\n\tcore/sys/windows/oaidl.d core/sys/windows/objbase.d \\\n\tcore/sys/windows/objfwd.d core/sys/windows/objidl.d \\\n\tcore/sys/windows/objsafe.d core/sys/windows/ocidl.d \\\n\tcore/sys/windows/odbcinst.d core/sys/windows/ole.d \\\n\tcore/sys/windows/ole2.d core/sys/windows/ole2ver.d \\\n\tcore/sys/windows/oleacc.d core/sys/windows/oleauto.d \\\n\tcore/sys/windows/olectl.d core/sys/windows/olectlid.d \\\n\tcore/sys/windows/oledlg.d core/sys/windows/oleidl.d \\\n\tcore/sys/windows/pbt.d core/sys/windows/powrprof.d \\\n\tcore/sys/windows/prsht.d core/sys/windows/psapi.d \\\n\tcore/sys/windows/rapi.d core/sys/windows/ras.d \\\n\tcore/sys/windows/rasdlg.d core/sys/windows/raserror.d \\\n\tcore/sys/windows/rassapi.d core/sys/windows/reason.d \\\n\tcore/sys/windows/regstr.d core/sys/windows/richedit.d \\\n\tcore/sys/windows/richole.d core/sys/windows/rpc.d \\\n\tcore/sys/windows/rpcdce.d core/sys/windows/rpcdce2.d \\\n\tcore/sys/windows/rpcdcep.d core/sys/windows/rpcndr.d \\\n\tcore/sys/windows/rpcnsi.d core/sys/windows/rpcnsip.d \\\n\tcore/sys/windows/rpcnterr.d core/sys/windows/schannel.d \\\n\tcore/sys/windows/secext.d core/sys/windows/security.d \\\n\tcore/sys/windows/servprov.d core/sys/windows/setupapi.d \\\n\tcore/sys/windows/shellapi.d core/sys/windows/shldisp.d \\\n\tcore/sys/windows/shlguid.d core/sys/windows/shlobj.d \\\n\tcore/sys/windows/shlwapi.d core/sys/windows/snmp.d \\\n\tcore/sys/windows/sql.d core/sys/windows/sqlext.d \\\n\tcore/sys/windows/sqltypes.d core/sys/windows/sqlucode.d \\\n\tcore/sys/windows/sspi.d core/sys/windows/stacktrace.d \\\n\tcore/sys/windows/stat.d core/sys/windows/subauth.d \\\n\tcore/sys/windows/threadaux.d core/sys/windows/tlhelp32.d \\\n\tcore/sys/windows/tmschema.d core/sys/windows/unknwn.d \\\n\tcore/sys/windows/uuid.d core/sys/windows/vfw.d \\\n\tcore/sys/windows/w32api.d core/sys/windows/winbase.d \\\n\tcore/sys/windows/winber.d core/sys/windows/wincon.d \\\n\tcore/sys/windows/wincrypt.d core/sys/windows/windef.d \\\n\tcore/sys/windows/windows.d core/sys/windows/winerror.d \\\n\tcore/sys/windows/wingdi.d core/sys/windows/winhttp.d \\\n\tcore/sys/windows/wininet.d core/sys/windows/winioctl.d \\\n\tcore/sys/windows/winldap.d core/sys/windows/winnetwk.d \\\n\tcore/sys/windows/winnls.d core/sys/windows/winnt.d \\\n\tcore/sys/windows/winperf.d core/sys/windows/winreg.d \\\n\tcore/sys/windows/winsock2.d core/sys/windows/winspool.d \\\n\tcore/sys/windows/winsvc.d core/sys/windows/winuser.d \\\n\tcore/sys/windows/winver.d core/sys/windows/wtsapi32.d \\\n\tcore/sys/windows/wtypes.d\n\nDRUNTIME_DISOURCES = __entrypoint.di __main.di\nall: all-am\n\n.SUFFIXES:\n.SUFFIXES: .S .c .d .lo .o .obj\n$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/d_rules.am $(am__configure_deps)\n\t@for dep in $?; do \\\n\t  case '$(am__configure_deps)' in \\\n\t    *$$dep*) \\\n\t      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \\\n\t        && { if test -f $@; then exit 0; else break; fi; }; \\\n\t      exit 1;; \\\n\t  esac; \\\n\tdone; \\\n\techo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps libdruntime/Makefile'; \\\n\t$(am__cd) $(top_srcdir) && \\\n\t  $(AUTOMAKE) --foreign --ignore-deps libdruntime/Makefile\n.PRECIOUS: Makefile\nMakefile: $(srcdir)/Makefile.in $(top_builddir)/config.status\n\t@case '$?' in \\\n\t  *config.status*) \\\n\t    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \\\n\t  *) \\\n\t    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \\\n\t    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \\\n\tesac;\n$(top_srcdir)/d_rules.am:\n\n$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)\n\tcd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh\n\n$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)\n\tcd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh\n$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)\n\tcd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh\n$(am__aclocal_m4_deps):\n\nclean-checkLTLIBRARIES:\n\t-test -z \"$(check_LTLIBRARIES)\" || rm -f $(check_LTLIBRARIES)\n\t@list='$(check_LTLIBRARIES)'; for p in $$list; do \\\n\t  dir=\"`echo $$p | sed -e 's|/[^/]*$$||'`\"; \\\n\t  test \"$$dir\" != \"$$p\" || dir=.; \\\n\t  echo \"rm -f \\\"$${dir}/so_locations\\\"\"; \\\n\t  rm -f \"$${dir}/so_locations\"; \\\n\tdone\ninstall-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)\n\t@$(NORMAL_INSTALL)\n\t@list='$(toolexeclib_LTLIBRARIES)'; test -n \"$(toolexeclibdir)\" || list=; \\\n\tlist2=; for p in $$list; do \\\n\t  if test -f $$p; then \\\n\t    list2=\"$$list2 $$p\"; \\\n\t  else :; fi; \\\n\tdone; \\\n\ttest -z \"$$list2\" || { \\\n\t  echo \" $(MKDIR_P) '$(DESTDIR)$(toolexeclibdir)'\"; \\\n\t  $(MKDIR_P) \"$(DESTDIR)$(toolexeclibdir)\" || exit 1; \\\n\t  echo \" $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'\"; \\\n\t  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 \"$(DESTDIR)$(toolexeclibdir)\"; \\\n\t}\n\nuninstall-toolexeclibLTLIBRARIES:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(toolexeclib_LTLIBRARIES)'; test -n \"$(toolexeclibdir)\" || list=; \\\n\tfor p in $$list; do \\\n\t  $(am__strip_dir) \\\n\t  echo \" $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$f'\"; \\\n\t  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f \"$(DESTDIR)$(toolexeclibdir)/$$f\"; \\\n\tdone\n\nclean-toolexeclibLTLIBRARIES:\n\t-test -z \"$(toolexeclib_LTLIBRARIES)\" || rm -f $(toolexeclib_LTLIBRARIES)\n\t@list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \\\n\t  dir=\"`echo $$p | sed -e 's|/[^/]*$$||'`\"; \\\n\t  test \"$$dir\" != \"$$p\" || dir=.; \\\n\t  echo \"rm -f \\\"$${dir}/so_locations\\\"\"; \\\n\t  rm -f \"$${dir}/so_locations\"; \\\n\tdone\ncore/$(am__dirstamp):\n\t@$(MKDIR_P) core\n\t@: > core/$(am__dirstamp)\ncore/atomic.lo: core/$(am__dirstamp)\ncore/attribute.lo: core/$(am__dirstamp)\ncore/bitop.lo: core/$(am__dirstamp)\ncore/checkedint.lo: core/$(am__dirstamp)\ncore/cpuid.lo: core/$(am__dirstamp)\ncore/demangle.lo: core/$(am__dirstamp)\ncore/exception.lo: core/$(am__dirstamp)\ncore/internal/$(am__dirstamp):\n\t@$(MKDIR_P) core/internal\n\t@: > core/internal/$(am__dirstamp)\ncore/internal/abort.lo: core/internal/$(am__dirstamp)\ncore/internal/arrayop.lo: core/internal/$(am__dirstamp)\ncore/internal/convert.lo: core/internal/$(am__dirstamp)\ncore/internal/hash.lo: core/internal/$(am__dirstamp)\ncore/internal/parseoptions.lo: core/internal/$(am__dirstamp)\ncore/internal/spinlock.lo: core/internal/$(am__dirstamp)\ncore/internal/string.lo: core/internal/$(am__dirstamp)\ncore/internal/traits.lo: core/internal/$(am__dirstamp)\ncore/math.lo: core/$(am__dirstamp)\ncore/memory.lo: core/$(am__dirstamp)\ncore/runtime.lo: core/$(am__dirstamp)\ncore/simd.lo: core/$(am__dirstamp)\ncore/stdc/$(am__dirstamp):\n\t@$(MKDIR_P) core/stdc\n\t@: > core/stdc/$(am__dirstamp)\ncore/stdc/assert_.lo: core/stdc/$(am__dirstamp)\ncore/stdc/complex.lo: core/stdc/$(am__dirstamp)\ncore/stdc/config.lo: core/stdc/$(am__dirstamp)\ncore/stdc/ctype.lo: core/stdc/$(am__dirstamp)\ncore/stdc/errno.lo: core/stdc/$(am__dirstamp)\ncore/stdc/fenv.lo: core/stdc/$(am__dirstamp)\ncore/stdc/float_.lo: core/stdc/$(am__dirstamp)\ncore/stdc/inttypes.lo: core/stdc/$(am__dirstamp)\ncore/stdc/limits.lo: core/stdc/$(am__dirstamp)\ncore/stdc/locale.lo: core/stdc/$(am__dirstamp)\ncore/stdc/math.lo: core/stdc/$(am__dirstamp)\ncore/stdc/signal.lo: core/stdc/$(am__dirstamp)\ncore/stdc/stdarg.lo: core/stdc/$(am__dirstamp)\ncore/stdc/stddef.lo: core/stdc/$(am__dirstamp)\ncore/stdc/stdint.lo: core/stdc/$(am__dirstamp)\ncore/stdc/stdio.lo: core/stdc/$(am__dirstamp)\ncore/stdc/stdlib.lo: core/stdc/$(am__dirstamp)\ncore/stdc/string.lo: core/stdc/$(am__dirstamp)\ncore/stdc/tgmath.lo: core/stdc/$(am__dirstamp)\ncore/stdc/time.lo: core/stdc/$(am__dirstamp)\ncore/stdc/wchar_.lo: core/stdc/$(am__dirstamp)\ncore/stdc/wctype.lo: core/stdc/$(am__dirstamp)\ncore/sync/$(am__dirstamp):\n\t@$(MKDIR_P) core/sync\n\t@: > core/sync/$(am__dirstamp)\ncore/sync/barrier.lo: core/sync/$(am__dirstamp)\ncore/sync/condition.lo: core/sync/$(am__dirstamp)\ncore/sync/config.lo: core/sync/$(am__dirstamp)\ncore/sync/exception.lo: core/sync/$(am__dirstamp)\ncore/sync/mutex.lo: core/sync/$(am__dirstamp)\ncore/sync/rwmutex.lo: core/sync/$(am__dirstamp)\ncore/sync/semaphore.lo: core/sync/$(am__dirstamp)\ncore/thread.lo: core/$(am__dirstamp)\ncore/time.lo: core/$(am__dirstamp)\ncore/vararg.lo: core/$(am__dirstamp)\ngcc/$(am__dirstamp):\n\t@$(MKDIR_P) gcc\n\t@: > gcc/$(am__dirstamp)\ngcc/attribute.lo: gcc/$(am__dirstamp)\ngcc/backtrace.lo: gcc/$(am__dirstamp)\ngcc/builtins.lo: gcc/$(am__dirstamp)\ngcc/deh.lo: gcc/$(am__dirstamp)\ngcc/unwind/$(am__dirstamp):\n\t@$(MKDIR_P) gcc/unwind\n\t@: > gcc/unwind/$(am__dirstamp)\ngcc/unwind/arm.lo: gcc/unwind/$(am__dirstamp)\ngcc/unwind/arm_common.lo: gcc/unwind/$(am__dirstamp)\ngcc/unwind/c6x.lo: gcc/unwind/$(am__dirstamp)\ngcc/unwind/generic.lo: gcc/unwind/$(am__dirstamp)\ngcc/unwind/package.lo: gcc/unwind/$(am__dirstamp)\ngcc/unwind/pe.lo: gcc/unwind/$(am__dirstamp)\nrt/$(am__dirstamp):\n\t@$(MKDIR_P) rt\n\t@: > rt/$(am__dirstamp)\nrt/aApply.lo: rt/$(am__dirstamp)\nrt/aApplyR.lo: rt/$(am__dirstamp)\nrt/aaA.lo: rt/$(am__dirstamp)\nrt/adi.lo: rt/$(am__dirstamp)\nrt/arrayassign.lo: rt/$(am__dirstamp)\nrt/arraycast.lo: rt/$(am__dirstamp)\nrt/arraycat.lo: rt/$(am__dirstamp)\nrt/cast_.lo: rt/$(am__dirstamp)\nrt/config.lo: rt/$(am__dirstamp)\nrt/critical_.lo: rt/$(am__dirstamp)\nrt/deh.lo: rt/$(am__dirstamp)\nrt/dmain2.lo: rt/$(am__dirstamp)\nrt/ehalloc.lo: rt/$(am__dirstamp)\nrt/invariant.lo: rt/$(am__dirstamp)\nrt/lifetime.lo: rt/$(am__dirstamp)\nrt/memory.lo: rt/$(am__dirstamp)\nrt/minfo.lo: rt/$(am__dirstamp)\nrt/monitor_.lo: rt/$(am__dirstamp)\nrt/obj.lo: rt/$(am__dirstamp)\nrt/qsort.lo: rt/$(am__dirstamp)\nrt/sections.lo: rt/$(am__dirstamp)\nrt/sections_android.lo: rt/$(am__dirstamp)\nrt/sections_elf_shared.lo: rt/$(am__dirstamp)\nrt/sections_osx_x86.lo: rt/$(am__dirstamp)\nrt/sections_osx_x86_64.lo: rt/$(am__dirstamp)\nrt/sections_solaris.lo: rt/$(am__dirstamp)\nrt/sections_win32.lo: rt/$(am__dirstamp)\nrt/sections_win64.lo: rt/$(am__dirstamp)\nrt/tlsgc.lo: rt/$(am__dirstamp)\nrt/typeinfo/$(am__dirstamp):\n\t@$(MKDIR_P) rt/typeinfo\n\t@: > rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_Acdouble.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_Acfloat.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_Acreal.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_Adouble.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_Afloat.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_Ag.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_Aint.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_Along.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_Areal.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_Ashort.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_C.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_byte.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_cdouble.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_cent.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_cfloat.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_char.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_creal.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_dchar.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_delegate.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_double.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_float.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_idouble.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_ifloat.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_int.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_ireal.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_long.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_n.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_ptr.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_real.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_short.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_ubyte.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_ucent.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_uint.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_ulong.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_ushort.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_void.lo: rt/typeinfo/$(am__dirstamp)\nrt/typeinfo/ti_wchar.lo: rt/typeinfo/$(am__dirstamp)\nrt/util/$(am__dirstamp):\n\t@$(MKDIR_P) rt/util\n\t@: > rt/util/$(am__dirstamp)\nrt/util/array.lo: rt/util/$(am__dirstamp)\nrt/util/container/$(am__dirstamp):\n\t@$(MKDIR_P) rt/util/container\n\t@: > rt/util/container/$(am__dirstamp)\nrt/util/container/array.lo: rt/util/container/$(am__dirstamp)\nrt/util/container/common.lo: rt/util/container/$(am__dirstamp)\nrt/util/container/hashtab.lo: rt/util/container/$(am__dirstamp)\nrt/util/container/treap.lo: rt/util/container/$(am__dirstamp)\nrt/util/random.lo: rt/util/$(am__dirstamp)\nrt/util/typeinfo.lo: rt/util/$(am__dirstamp)\nrt/util/utf.lo: rt/util/$(am__dirstamp)\ngc/$(am__dirstamp):\n\t@$(MKDIR_P) gc\n\t@: > gc/$(am__dirstamp)\ngc/bits.lo: gc/$(am__dirstamp)\ngc/config.lo: gc/$(am__dirstamp)\ngc/gcinterface.lo: gc/$(am__dirstamp)\ngc/impl/conservative/$(am__dirstamp):\n\t@$(MKDIR_P) gc/impl/conservative\n\t@: > gc/impl/conservative/$(am__dirstamp)\ngc/impl/conservative/gc.lo: gc/impl/conservative/$(am__dirstamp)\ngc/impl/manual/$(am__dirstamp):\n\t@$(MKDIR_P) gc/impl/manual\n\t@: > gc/impl/manual/$(am__dirstamp)\ngc/impl/manual/gc.lo: gc/impl/manual/$(am__dirstamp)\ngc/impl/proto/$(am__dirstamp):\n\t@$(MKDIR_P) gc/impl/proto\n\t@: > gc/impl/proto/$(am__dirstamp)\ngc/impl/proto/gc.lo: gc/impl/proto/$(am__dirstamp)\ngc/os.lo: gc/$(am__dirstamp)\ngc/pooltable.lo: gc/$(am__dirstamp)\ngc/proxy.lo: gc/$(am__dirstamp)\ncore/sys/posix/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/posix\n\t@: > core/sys/posix/$(am__dirstamp)\ncore/sys/posix/aio.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/arpa/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/posix/arpa\n\t@: > core/sys/posix/arpa/$(am__dirstamp)\ncore/sys/posix/arpa/inet.lo: core/sys/posix/arpa/$(am__dirstamp)\ncore/sys/posix/config.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/dirent.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/dlfcn.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/fcntl.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/grp.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/iconv.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/inttypes.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/libgen.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/mqueue.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/net/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/posix/net\n\t@: > core/sys/posix/net/$(am__dirstamp)\ncore/sys/posix/net/if_.lo: core/sys/posix/net/$(am__dirstamp)\ncore/sys/posix/netdb.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/netinet/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/posix/netinet\n\t@: > core/sys/posix/netinet/$(am__dirstamp)\ncore/sys/posix/netinet/in_.lo: core/sys/posix/netinet/$(am__dirstamp)\ncore/sys/posix/netinet/tcp.lo: core/sys/posix/netinet/$(am__dirstamp)\ncore/sys/posix/poll.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/pthread.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/pwd.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/sched.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/semaphore.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/setjmp.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/signal.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/spawn.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/stdio.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/stdlib.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/sys/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/posix/sys\n\t@: > core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/filio.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/ioccom.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/ioctl.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/ipc.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/mman.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/msg.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/resource.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/select.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/shm.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/socket.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/stat.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/statvfs.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/time.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/ttycom.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/types.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/uio.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/un.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/utsname.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/sys/wait.lo: core/sys/posix/sys/$(am__dirstamp)\ncore/sys/posix/syslog.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/termios.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/time.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/ucontext.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/unistd.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/posix/utime.lo: core/sys/posix/$(am__dirstamp)\ncore/sys/darwin/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/darwin\n\t@: > core/sys/darwin/$(am__dirstamp)\ncore/sys/darwin/dlfcn.lo: core/sys/darwin/$(am__dirstamp)\ncore/sys/darwin/execinfo.lo: core/sys/darwin/$(am__dirstamp)\ncore/sys/darwin/mach/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/darwin/mach\n\t@: > core/sys/darwin/mach/$(am__dirstamp)\ncore/sys/darwin/mach/dyld.lo: core/sys/darwin/mach/$(am__dirstamp)\ncore/sys/darwin/mach/getsect.lo: core/sys/darwin/mach/$(am__dirstamp)\ncore/sys/darwin/mach/kern_return.lo:  \\\n\tcore/sys/darwin/mach/$(am__dirstamp)\ncore/sys/darwin/mach/loader.lo: core/sys/darwin/mach/$(am__dirstamp)\ncore/sys/darwin/mach/port.lo: core/sys/darwin/mach/$(am__dirstamp)\ncore/sys/darwin/mach/semaphore.lo:  \\\n\tcore/sys/darwin/mach/$(am__dirstamp)\ncore/sys/darwin/mach/thread_act.lo:  \\\n\tcore/sys/darwin/mach/$(am__dirstamp)\ncore/sys/darwin/netinet/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/darwin/netinet\n\t@: > core/sys/darwin/netinet/$(am__dirstamp)\ncore/sys/darwin/netinet/in_.lo:  \\\n\tcore/sys/darwin/netinet/$(am__dirstamp)\ncore/sys/darwin/pthread.lo: core/sys/darwin/$(am__dirstamp)\ncore/sys/darwin/sys/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/darwin/sys\n\t@: > core/sys/darwin/sys/$(am__dirstamp)\ncore/sys/darwin/sys/cdefs.lo: core/sys/darwin/sys/$(am__dirstamp)\ncore/sys/darwin/sys/event.lo: core/sys/darwin/sys/$(am__dirstamp)\ncore/sys/darwin/sys/mman.lo: core/sys/darwin/sys/$(am__dirstamp)\ncore/sys/osx/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/osx\n\t@: > core/sys/osx/$(am__dirstamp)\ncore/sys/osx/execinfo.lo: core/sys/osx/$(am__dirstamp)\ncore/sys/osx/mach/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/osx/mach\n\t@: > core/sys/osx/mach/$(am__dirstamp)\ncore/sys/osx/mach/dyld.lo: core/sys/osx/mach/$(am__dirstamp)\ncore/sys/osx/mach/getsect.lo: core/sys/osx/mach/$(am__dirstamp)\ncore/sys/osx/mach/kern_return.lo: core/sys/osx/mach/$(am__dirstamp)\ncore/sys/osx/mach/loader.lo: core/sys/osx/mach/$(am__dirstamp)\ncore/sys/osx/mach/port.lo: core/sys/osx/mach/$(am__dirstamp)\ncore/sys/osx/mach/semaphore.lo: core/sys/osx/mach/$(am__dirstamp)\ncore/sys/osx/mach/thread_act.lo: core/sys/osx/mach/$(am__dirstamp)\ncore/sys/osx/pthread.lo: core/sys/osx/$(am__dirstamp)\ncore/sys/osx/sys/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/osx/sys\n\t@: > core/sys/osx/sys/$(am__dirstamp)\ncore/sys/osx/sys/cdefs.lo: core/sys/osx/sys/$(am__dirstamp)\ncore/sys/osx/sys/event.lo: core/sys/osx/sys/$(am__dirstamp)\ncore/sys/osx/sys/mman.lo: core/sys/osx/sys/$(am__dirstamp)\ncore/sys/bionic/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/bionic\n\t@: > core/sys/bionic/$(am__dirstamp)\ncore/sys/bionic/fcntl.lo: core/sys/bionic/$(am__dirstamp)\ncore/sys/bionic/unistd.lo: core/sys/bionic/$(am__dirstamp)\ncore/sys/freebsd/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/freebsd\n\t@: > core/sys/freebsd/$(am__dirstamp)\ncore/sys/freebsd/dlfcn.lo: core/sys/freebsd/$(am__dirstamp)\ncore/sys/freebsd/execinfo.lo: core/sys/freebsd/$(am__dirstamp)\ncore/sys/freebsd/netinet/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/freebsd/netinet\n\t@: > core/sys/freebsd/netinet/$(am__dirstamp)\ncore/sys/freebsd/netinet/in_.lo:  \\\n\tcore/sys/freebsd/netinet/$(am__dirstamp)\ncore/sys/freebsd/pthread_np.lo: core/sys/freebsd/$(am__dirstamp)\ncore/sys/freebsd/sys/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/freebsd/sys\n\t@: > core/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/sys/_bitset.lo: core/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/sys/_cpuset.lo: core/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/sys/cdefs.lo: core/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/sys/elf.lo: core/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/sys/elf32.lo: core/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/sys/elf64.lo: core/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/sys/elf_common.lo:  \\\n\tcore/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/sys/event.lo: core/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/sys/link_elf.lo:  \\\n\tcore/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/sys/mman.lo: core/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/sys/mount.lo: core/sys/freebsd/sys/$(am__dirstamp)\ncore/sys/freebsd/time.lo: core/sys/freebsd/$(am__dirstamp)\ncore/sys/freebsd/unistd.lo: core/sys/freebsd/$(am__dirstamp)\ncore/sys/openbsd/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/openbsd\n\t@: > core/sys/openbsd/$(am__dirstamp)\ncore/sys/openbsd/dlfcn.lo: core/sys/openbsd/$(am__dirstamp)\ncore/sys/linux/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/linux\n\t@: > core/sys/linux/$(am__dirstamp)\ncore/sys/linux/config.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/dlfcn.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/elf.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/epoll.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/errno.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/execinfo.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/fcntl.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/ifaddrs.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/link.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/netinet/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/linux/netinet\n\t@: > core/sys/linux/netinet/$(am__dirstamp)\ncore/sys/linux/netinet/in_.lo: core/sys/linux/netinet/$(am__dirstamp)\ncore/sys/linux/netinet/tcp.lo: core/sys/linux/netinet/$(am__dirstamp)\ncore/sys/linux/sched.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/stdio.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/sys/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/linux/sys\n\t@: > core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/sys/auxv.lo: core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/sys/eventfd.lo: core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/sys/file.lo: core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/sys/inotify.lo: core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/sys/mman.lo: core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/sys/netinet/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/linux/sys/netinet\n\t@: > core/sys/linux/sys/netinet/$(am__dirstamp)\ncore/sys/linux/sys/netinet/tcp.lo:  \\\n\tcore/sys/linux/sys/netinet/$(am__dirstamp)\ncore/sys/linux/sys/prctl.lo: core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/sys/signalfd.lo: core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/sys/socket.lo: core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/sys/sysinfo.lo: core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/sys/time.lo: core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/sys/xattr.lo: core/sys/linux/sys/$(am__dirstamp)\ncore/sys/linux/termios.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/time.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/timerfd.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/tipc.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/linux/unistd.lo: core/sys/linux/$(am__dirstamp)\ncore/sys/windows/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/windows\n\t@: > core/sys/windows/$(am__dirstamp)\ncore/sys/windows/accctrl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/aclapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/aclui.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/basetsd.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/basetyps.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/cderr.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/cguid.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/com.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/comcat.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/commctrl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/commdlg.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/core.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/cpl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/cplext.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/custcntl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/dbghelp.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/dbghelp_types.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/dbt.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/dde.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ddeml.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/dhcpcsdk.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/dlgs.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/dll.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/docobj.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/errorrep.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/exdisp.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/exdispid.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/httpext.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/idispids.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/imagehlp.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/imm.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/intshcut.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ipexport.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/iphlpapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ipifcons.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/iprtrmib.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/iptypes.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/isguids.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lm.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmaccess.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmalert.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmapibuf.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmat.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmaudit.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmbrowsr.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmchdev.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmconfig.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmcons.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmerr.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmerrlog.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmmsg.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmremutl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmrepl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmserver.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmshare.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmsname.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmstats.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmsvc.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmuse.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmuseflg.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lmwksta.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/lzexpand.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/mapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/mciavi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/mcx.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/mgmtapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/mmsystem.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/msacm.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/mshtml.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/mswsock.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/nb30.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/nddeapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/nspapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ntdef.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ntdll.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ntldap.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ntsecapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ntsecpkg.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/oaidl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/objbase.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/objfwd.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/objidl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/objsafe.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ocidl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/odbcinst.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ole.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ole2.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ole2ver.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/oleacc.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/oleauto.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/olectl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/olectlid.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/oledlg.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/oleidl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/pbt.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/powrprof.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/prsht.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/psapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/rapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/ras.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/rasdlg.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/raserror.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/rassapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/reason.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/regstr.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/richedit.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/richole.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/rpc.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/rpcdce.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/rpcdce2.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/rpcdcep.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/rpcndr.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/rpcnsi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/rpcnsip.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/rpcnterr.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/schannel.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/secext.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/security.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/servprov.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/setupapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/shellapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/shldisp.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/shlguid.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/shlobj.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/shlwapi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/snmp.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/sql.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/sqlext.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/sqltypes.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/sqlucode.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/sspi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/stacktrace.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/stat.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/subauth.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/threadaux.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/tlhelp32.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/tmschema.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/unknwn.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/uuid.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/vfw.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/w32api.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winbase.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winber.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/wincon.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/wincrypt.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/windef.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/windows.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winerror.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/wingdi.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winhttp.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/wininet.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winioctl.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winldap.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winnetwk.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winnls.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winnt.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winperf.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winreg.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winsock2.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winspool.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winsvc.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winuser.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/winver.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/wtsapi32.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/windows/wtypes.lo: core/sys/windows/$(am__dirstamp)\ncore/sys/solaris/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/solaris\n\t@: > core/sys/solaris/$(am__dirstamp)\ncore/sys/solaris/dlfcn.lo: core/sys/solaris/$(am__dirstamp)\ncore/sys/solaris/elf.lo: core/sys/solaris/$(am__dirstamp)\ncore/sys/solaris/execinfo.lo: core/sys/solaris/$(am__dirstamp)\ncore/sys/solaris/libelf.lo: core/sys/solaris/$(am__dirstamp)\ncore/sys/solaris/link.lo: core/sys/solaris/$(am__dirstamp)\ncore/sys/solaris/sys/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/solaris/sys\n\t@: > core/sys/solaris/sys/$(am__dirstamp)\ncore/sys/solaris/sys/elf.lo: core/sys/solaris/sys/$(am__dirstamp)\ncore/sys/solaris/sys/elf_386.lo: core/sys/solaris/sys/$(am__dirstamp)\ncore/sys/solaris/sys/elf_SPARC.lo:  \\\n\tcore/sys/solaris/sys/$(am__dirstamp)\ncore/sys/solaris/sys/elf_amd64.lo:  \\\n\tcore/sys/solaris/sys/$(am__dirstamp)\ncore/sys/solaris/sys/elf_notes.lo:  \\\n\tcore/sys/solaris/sys/$(am__dirstamp)\ncore/sys/solaris/sys/elftypes.lo:  \\\n\tcore/sys/solaris/sys/$(am__dirstamp)\ncore/sys/solaris/sys/link.lo: core/sys/solaris/sys/$(am__dirstamp)\ncore/sys/solaris/sys/priocntl.lo:  \\\n\tcore/sys/solaris/sys/$(am__dirstamp)\ncore/sys/solaris/sys/procset.lo: core/sys/solaris/sys/$(am__dirstamp)\ncore/sys/solaris/sys/types.lo: core/sys/solaris/sys/$(am__dirstamp)\ncore/sys/solaris/time.lo: core/sys/solaris/$(am__dirstamp)\ncore/sys/dragonflybsd/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/dragonflybsd\n\t@: > core/sys/dragonflybsd/$(am__dirstamp)\ncore/sys/dragonflybsd/dlfcn.lo: core/sys/dragonflybsd/$(am__dirstamp)\ncore/sys/dragonflybsd/execinfo.lo:  \\\n\tcore/sys/dragonflybsd/$(am__dirstamp)\ncore/sys/dragonflybsd/netinet/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/dragonflybsd/netinet\n\t@: > core/sys/dragonflybsd/netinet/$(am__dirstamp)\ncore/sys/dragonflybsd/netinet/in_.lo:  \\\n\tcore/sys/dragonflybsd/netinet/$(am__dirstamp)\ncore/sys/dragonflybsd/pthread_np.lo:  \\\n\tcore/sys/dragonflybsd/$(am__dirstamp)\ncore/sys/dragonflybsd/sys/$(am__dirstamp):\n\t@$(MKDIR_P) core/sys/dragonflybsd/sys\n\t@: > core/sys/dragonflybsd/sys/$(am__dirstamp)\ncore/sys/dragonflybsd/sys/_bitset.lo:  \\\n\tcore/sys/dragonflybsd/sys/$(am__dirstamp)\ncore/sys/dragonflybsd/sys/_cpuset.lo:  \\\n\tcore/sys/dragonflybsd/sys/$(am__dirstamp)\ncore/sys/dragonflybsd/sys/cdefs.lo:  \\\n\tcore/sys/dragonflybsd/sys/$(am__dirstamp)\ncore/sys/dragonflybsd/sys/elf.lo:  \\\n\tcore/sys/dragonflybsd/sys/$(am__dirstamp)\ncore/sys/dragonflybsd/sys/elf32.lo:  \\\n\tcore/sys/dragonflybsd/sys/$(am__dirstamp)\ncore/sys/dragonflybsd/sys/elf64.lo:  \\\n\tcore/sys/dragonflybsd/sys/$(am__dirstamp)\ncore/sys/dragonflybsd/sys/elf_common.lo:  \\\n\tcore/sys/dragonflybsd/sys/$(am__dirstamp)\ncore/sys/dragonflybsd/sys/event.lo:  \\\n\tcore/sys/dragonflybsd/sys/$(am__dirstamp)\ncore/sys/dragonflybsd/sys/link_elf.lo:  \\\n\tcore/sys/dragonflybsd/sys/$(am__dirstamp)\ncore/sys/dragonflybsd/sys/mman.lo:  \\\n\tcore/sys/dragonflybsd/sys/$(am__dirstamp)\ncore/sys/dragonflybsd/time.lo: core/sys/dragonflybsd/$(am__dirstamp)\ngcc/config.lo: gcc/$(am__dirstamp)\ngcc/libbacktrace.lo: gcc/$(am__dirstamp)\nlibgdruntime.la: $(libgdruntime_la_OBJECTS) $(libgdruntime_la_DEPENDENCIES) $(EXTRA_libgdruntime_la_DEPENDENCIES) \n\t$(libgdruntime_la_LINK) -rpath $(toolexeclibdir) $(libgdruntime_la_OBJECTS) $(libgdruntime_la_LIBADD) $(LIBS)\nlibgdruntime_t.la: $(libgdruntime_t_la_OBJECTS) $(libgdruntime_t_la_DEPENDENCIES) $(EXTRA_libgdruntime_t_la_DEPENDENCIES) \n\t$(libgdruntime_t_la_LINK) $(am_libgdruntime_t_la_rpath) $(libgdruntime_t_la_OBJECTS) $(libgdruntime_t_la_LIBADD) $(LIBS)\n\nclean-checkPROGRAMS:\n\t@list='$(check_PROGRAMS)'; test -n \"$$list\" || exit 0; \\\n\techo \" rm -f\" $$list; \\\n\trm -f $$list || exit $$?; \\\n\ttest -n \"$(EXEEXT)\" || exit 0; \\\n\tlist=`for p in $$list; do echo \"$$p\"; done | sed 's/$(EXEEXT)$$//'`; \\\n\techo \" rm -f\" $$list; \\\n\trm -f $$list\n../testsuite/$(am__dirstamp):\n\t@$(MKDIR_P) ../testsuite\n\t@: > ../testsuite/$(am__dirstamp)\n../testsuite/test_runner.$(OBJEXT): ../testsuite/$(am__dirstamp)\nunittest$(EXEEXT): $(unittest_OBJECTS) $(unittest_DEPENDENCIES) $(EXTRA_unittest_DEPENDENCIES) \n\t@rm -f unittest$(EXEEXT)\n\t$(unittest_LINK) $(unittest_OBJECTS) $(unittest_LDADD) $(LIBS)\nunittest_static$(EXEEXT): $(unittest_static_OBJECTS) $(unittest_static_DEPENDENCIES) $(EXTRA_unittest_static_DEPENDENCIES) \n\t@rm -f unittest_static$(EXEEXT)\n\t$(unittest_static_LINK) $(unittest_static_OBJECTS) $(unittest_static_LDADD) $(LIBS)\n\nmostlyclean-compile:\n\t-rm -f *.$(OBJEXT)\n\t-rm -f ../testsuite/test_runner.$(OBJEXT)\n\t-rm -f core/atomic.$(OBJEXT)\n\t-rm -f core/atomic.lo\n\t-rm -f core/attribute.$(OBJEXT)\n\t-rm -f core/attribute.lo\n\t-rm -f core/bitop.$(OBJEXT)\n\t-rm -f core/bitop.lo\n\t-rm -f core/checkedint.$(OBJEXT)\n\t-rm -f core/checkedint.lo\n\t-rm -f core/cpuid.$(OBJEXT)\n\t-rm -f core/cpuid.lo\n\t-rm -f core/demangle.$(OBJEXT)\n\t-rm -f core/demangle.lo\n\t-rm -f core/exception.$(OBJEXT)\n\t-rm -f core/exception.lo\n\t-rm -f core/internal/abort.$(OBJEXT)\n\t-rm -f core/internal/abort.lo\n\t-rm -f core/internal/arrayop.$(OBJEXT)\n\t-rm -f core/internal/arrayop.lo\n\t-rm -f core/internal/convert.$(OBJEXT)\n\t-rm -f core/internal/convert.lo\n\t-rm -f core/internal/hash.$(OBJEXT)\n\t-rm -f core/internal/hash.lo\n\t-rm -f core/internal/parseoptions.$(OBJEXT)\n\t-rm -f core/internal/parseoptions.lo\n\t-rm -f core/internal/spinlock.$(OBJEXT)\n\t-rm -f core/internal/spinlock.lo\n\t-rm -f core/internal/string.$(OBJEXT)\n\t-rm -f core/internal/string.lo\n\t-rm -f core/internal/traits.$(OBJEXT)\n\t-rm -f core/internal/traits.lo\n\t-rm -f core/math.$(OBJEXT)\n\t-rm -f core/math.lo\n\t-rm -f core/memory.$(OBJEXT)\n\t-rm -f core/memory.lo\n\t-rm -f core/runtime.$(OBJEXT)\n\t-rm -f core/runtime.lo\n\t-rm -f core/simd.$(OBJEXT)\n\t-rm -f core/simd.lo\n\t-rm -f core/stdc/assert_.$(OBJEXT)\n\t-rm -f core/stdc/assert_.lo\n\t-rm -f core/stdc/complex.$(OBJEXT)\n\t-rm -f core/stdc/complex.lo\n\t-rm -f core/stdc/config.$(OBJEXT)\n\t-rm -f core/stdc/config.lo\n\t-rm -f core/stdc/ctype.$(OBJEXT)\n\t-rm -f core/stdc/ctype.lo\n\t-rm -f core/stdc/errno.$(OBJEXT)\n\t-rm -f core/stdc/errno.lo\n\t-rm -f core/stdc/fenv.$(OBJEXT)\n\t-rm -f core/stdc/fenv.lo\n\t-rm -f core/stdc/float_.$(OBJEXT)\n\t-rm -f core/stdc/float_.lo\n\t-rm -f core/stdc/inttypes.$(OBJEXT)\n\t-rm -f core/stdc/inttypes.lo\n\t-rm -f core/stdc/limits.$(OBJEXT)\n\t-rm -f core/stdc/limits.lo\n\t-rm -f core/stdc/locale.$(OBJEXT)\n\t-rm -f core/stdc/locale.lo\n\t-rm -f core/stdc/math.$(OBJEXT)\n\t-rm -f core/stdc/math.lo\n\t-rm -f core/stdc/signal.$(OBJEXT)\n\t-rm -f core/stdc/signal.lo\n\t-rm -f core/stdc/stdarg.$(OBJEXT)\n\t-rm -f core/stdc/stdarg.lo\n\t-rm -f core/stdc/stddef.$(OBJEXT)\n\t-rm -f core/stdc/stddef.lo\n\t-rm -f core/stdc/stdint.$(OBJEXT)\n\t-rm -f core/stdc/stdint.lo\n\t-rm -f core/stdc/stdio.$(OBJEXT)\n\t-rm -f core/stdc/stdio.lo\n\t-rm -f core/stdc/stdlib.$(OBJEXT)\n\t-rm -f core/stdc/stdlib.lo\n\t-rm -f core/stdc/string.$(OBJEXT)\n\t-rm -f core/stdc/string.lo\n\t-rm -f core/stdc/tgmath.$(OBJEXT)\n\t-rm -f core/stdc/tgmath.lo\n\t-rm -f core/stdc/time.$(OBJEXT)\n\t-rm -f core/stdc/time.lo\n\t-rm -f core/stdc/wchar_.$(OBJEXT)\n\t-rm -f core/stdc/wchar_.lo\n\t-rm -f core/stdc/wctype.$(OBJEXT)\n\t-rm -f core/stdc/wctype.lo\n\t-rm -f core/sync/barrier.$(OBJEXT)\n\t-rm -f core/sync/barrier.lo\n\t-rm -f core/sync/condition.$(OBJEXT)\n\t-rm -f core/sync/condition.lo\n\t-rm -f core/sync/config.$(OBJEXT)\n\t-rm -f core/sync/config.lo\n\t-rm -f core/sync/exception.$(OBJEXT)\n\t-rm -f core/sync/exception.lo\n\t-rm -f core/sync/mutex.$(OBJEXT)\n\t-rm -f core/sync/mutex.lo\n\t-rm -f core/sync/rwmutex.$(OBJEXT)\n\t-rm -f core/sync/rwmutex.lo\n\t-rm -f core/sync/semaphore.$(OBJEXT)\n\t-rm -f core/sync/semaphore.lo\n\t-rm -f core/sys/bionic/fcntl.$(OBJEXT)\n\t-rm -f core/sys/bionic/fcntl.lo\n\t-rm -f core/sys/bionic/unistd.$(OBJEXT)\n\t-rm -f core/sys/bionic/unistd.lo\n\t-rm -f core/sys/darwin/dlfcn.$(OBJEXT)\n\t-rm -f core/sys/darwin/dlfcn.lo\n\t-rm -f core/sys/darwin/execinfo.$(OBJEXT)\n\t-rm -f core/sys/darwin/execinfo.lo\n\t-rm -f core/sys/darwin/mach/dyld.$(OBJEXT)\n\t-rm -f core/sys/darwin/mach/dyld.lo\n\t-rm -f core/sys/darwin/mach/getsect.$(OBJEXT)\n\t-rm -f core/sys/darwin/mach/getsect.lo\n\t-rm -f core/sys/darwin/mach/kern_return.$(OBJEXT)\n\t-rm -f core/sys/darwin/mach/kern_return.lo\n\t-rm -f core/sys/darwin/mach/loader.$(OBJEXT)\n\t-rm -f core/sys/darwin/mach/loader.lo\n\t-rm -f core/sys/darwin/mach/port.$(OBJEXT)\n\t-rm -f core/sys/darwin/mach/port.lo\n\t-rm -f core/sys/darwin/mach/semaphore.$(OBJEXT)\n\t-rm -f core/sys/darwin/mach/semaphore.lo\n\t-rm -f core/sys/darwin/mach/thread_act.$(OBJEXT)\n\t-rm -f core/sys/darwin/mach/thread_act.lo\n\t-rm -f core/sys/darwin/netinet/in_.$(OBJEXT)\n\t-rm -f core/sys/darwin/netinet/in_.lo\n\t-rm -f core/sys/darwin/pthread.$(OBJEXT)\n\t-rm -f core/sys/darwin/pthread.lo\n\t-rm -f core/sys/darwin/sys/cdefs.$(OBJEXT)\n\t-rm -f core/sys/darwin/sys/cdefs.lo\n\t-rm -f core/sys/darwin/sys/event.$(OBJEXT)\n\t-rm -f core/sys/darwin/sys/event.lo\n\t-rm -f core/sys/darwin/sys/mman.$(OBJEXT)\n\t-rm -f core/sys/darwin/sys/mman.lo\n\t-rm -f core/sys/dragonflybsd/dlfcn.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/dlfcn.lo\n\t-rm -f core/sys/dragonflybsd/execinfo.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/execinfo.lo\n\t-rm -f core/sys/dragonflybsd/netinet/in_.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/netinet/in_.lo\n\t-rm -f core/sys/dragonflybsd/pthread_np.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/pthread_np.lo\n\t-rm -f core/sys/dragonflybsd/sys/_bitset.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/sys/_bitset.lo\n\t-rm -f core/sys/dragonflybsd/sys/_cpuset.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/sys/_cpuset.lo\n\t-rm -f core/sys/dragonflybsd/sys/cdefs.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/sys/cdefs.lo\n\t-rm -f core/sys/dragonflybsd/sys/elf.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/sys/elf.lo\n\t-rm -f core/sys/dragonflybsd/sys/elf32.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/sys/elf32.lo\n\t-rm -f core/sys/dragonflybsd/sys/elf64.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/sys/elf64.lo\n\t-rm -f core/sys/dragonflybsd/sys/elf_common.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/sys/elf_common.lo\n\t-rm -f core/sys/dragonflybsd/sys/event.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/sys/event.lo\n\t-rm -f core/sys/dragonflybsd/sys/link_elf.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/sys/link_elf.lo\n\t-rm -f core/sys/dragonflybsd/sys/mman.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/sys/mman.lo\n\t-rm -f core/sys/dragonflybsd/time.$(OBJEXT)\n\t-rm -f core/sys/dragonflybsd/time.lo\n\t-rm -f core/sys/freebsd/dlfcn.$(OBJEXT)\n\t-rm -f core/sys/freebsd/dlfcn.lo\n\t-rm -f core/sys/freebsd/execinfo.$(OBJEXT)\n\t-rm -f core/sys/freebsd/execinfo.lo\n\t-rm -f core/sys/freebsd/netinet/in_.$(OBJEXT)\n\t-rm -f core/sys/freebsd/netinet/in_.lo\n\t-rm -f core/sys/freebsd/pthread_np.$(OBJEXT)\n\t-rm -f core/sys/freebsd/pthread_np.lo\n\t-rm -f core/sys/freebsd/sys/_bitset.$(OBJEXT)\n\t-rm -f core/sys/freebsd/sys/_bitset.lo\n\t-rm -f core/sys/freebsd/sys/_cpuset.$(OBJEXT)\n\t-rm -f core/sys/freebsd/sys/_cpuset.lo\n\t-rm -f core/sys/freebsd/sys/cdefs.$(OBJEXT)\n\t-rm -f core/sys/freebsd/sys/cdefs.lo\n\t-rm -f core/sys/freebsd/sys/elf.$(OBJEXT)\n\t-rm -f core/sys/freebsd/sys/elf.lo\n\t-rm -f core/sys/freebsd/sys/elf32.$(OBJEXT)\n\t-rm -f core/sys/freebsd/sys/elf32.lo\n\t-rm -f core/sys/freebsd/sys/elf64.$(OBJEXT)\n\t-rm -f core/sys/freebsd/sys/elf64.lo\n\t-rm -f core/sys/freebsd/sys/elf_common.$(OBJEXT)\n\t-rm -f core/sys/freebsd/sys/elf_common.lo\n\t-rm -f core/sys/freebsd/sys/event.$(OBJEXT)\n\t-rm -f core/sys/freebsd/sys/event.lo\n\t-rm -f core/sys/freebsd/sys/link_elf.$(OBJEXT)\n\t-rm -f core/sys/freebsd/sys/link_elf.lo\n\t-rm -f core/sys/freebsd/sys/mman.$(OBJEXT)\n\t-rm -f core/sys/freebsd/sys/mman.lo\n\t-rm -f core/sys/freebsd/sys/mount.$(OBJEXT)\n\t-rm -f core/sys/freebsd/sys/mount.lo\n\t-rm -f core/sys/freebsd/time.$(OBJEXT)\n\t-rm -f core/sys/freebsd/time.lo\n\t-rm -f core/sys/freebsd/unistd.$(OBJEXT)\n\t-rm -f core/sys/freebsd/unistd.lo\n\t-rm -f core/sys/linux/config.$(OBJEXT)\n\t-rm -f core/sys/linux/config.lo\n\t-rm -f core/sys/linux/dlfcn.$(OBJEXT)\n\t-rm -f core/sys/linux/dlfcn.lo\n\t-rm -f core/sys/linux/elf.$(OBJEXT)\n\t-rm -f core/sys/linux/elf.lo\n\t-rm -f core/sys/linux/epoll.$(OBJEXT)\n\t-rm -f core/sys/linux/epoll.lo\n\t-rm -f core/sys/linux/errno.$(OBJEXT)\n\t-rm -f core/sys/linux/errno.lo\n\t-rm -f core/sys/linux/execinfo.$(OBJEXT)\n\t-rm -f core/sys/linux/execinfo.lo\n\t-rm -f core/sys/linux/fcntl.$(OBJEXT)\n\t-rm -f core/sys/linux/fcntl.lo\n\t-rm -f core/sys/linux/ifaddrs.$(OBJEXT)\n\t-rm -f core/sys/linux/ifaddrs.lo\n\t-rm -f core/sys/linux/link.$(OBJEXT)\n\t-rm -f core/sys/linux/link.lo\n\t-rm -f core/sys/linux/netinet/in_.$(OBJEXT)\n\t-rm -f core/sys/linux/netinet/in_.lo\n\t-rm -f core/sys/linux/netinet/tcp.$(OBJEXT)\n\t-rm -f core/sys/linux/netinet/tcp.lo\n\t-rm -f core/sys/linux/sched.$(OBJEXT)\n\t-rm -f core/sys/linux/sched.lo\n\t-rm -f core/sys/linux/stdio.$(OBJEXT)\n\t-rm -f core/sys/linux/stdio.lo\n\t-rm -f core/sys/linux/sys/auxv.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/auxv.lo\n\t-rm -f core/sys/linux/sys/eventfd.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/eventfd.lo\n\t-rm -f core/sys/linux/sys/file.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/file.lo\n\t-rm -f core/sys/linux/sys/inotify.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/inotify.lo\n\t-rm -f core/sys/linux/sys/mman.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/mman.lo\n\t-rm -f core/sys/linux/sys/netinet/tcp.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/netinet/tcp.lo\n\t-rm -f core/sys/linux/sys/prctl.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/prctl.lo\n\t-rm -f core/sys/linux/sys/signalfd.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/signalfd.lo\n\t-rm -f core/sys/linux/sys/socket.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/socket.lo\n\t-rm -f core/sys/linux/sys/sysinfo.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/sysinfo.lo\n\t-rm -f core/sys/linux/sys/time.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/time.lo\n\t-rm -f core/sys/linux/sys/xattr.$(OBJEXT)\n\t-rm -f core/sys/linux/sys/xattr.lo\n\t-rm -f core/sys/linux/termios.$(OBJEXT)\n\t-rm -f core/sys/linux/termios.lo\n\t-rm -f core/sys/linux/time.$(OBJEXT)\n\t-rm -f core/sys/linux/time.lo\n\t-rm -f core/sys/linux/timerfd.$(OBJEXT)\n\t-rm -f core/sys/linux/timerfd.lo\n\t-rm -f core/sys/linux/tipc.$(OBJEXT)\n\t-rm -f core/sys/linux/tipc.lo\n\t-rm -f core/sys/linux/unistd.$(OBJEXT)\n\t-rm -f core/sys/linux/unistd.lo\n\t-rm -f core/sys/openbsd/dlfcn.$(OBJEXT)\n\t-rm -f core/sys/openbsd/dlfcn.lo\n\t-rm -f core/sys/osx/execinfo.$(OBJEXT)\n\t-rm -f core/sys/osx/execinfo.lo\n\t-rm -f core/sys/osx/mach/dyld.$(OBJEXT)\n\t-rm -f core/sys/osx/mach/dyld.lo\n\t-rm -f core/sys/osx/mach/getsect.$(OBJEXT)\n\t-rm -f core/sys/osx/mach/getsect.lo\n\t-rm -f core/sys/osx/mach/kern_return.$(OBJEXT)\n\t-rm -f core/sys/osx/mach/kern_return.lo\n\t-rm -f core/sys/osx/mach/loader.$(OBJEXT)\n\t-rm -f core/sys/osx/mach/loader.lo\n\t-rm -f core/sys/osx/mach/port.$(OBJEXT)\n\t-rm -f core/sys/osx/mach/port.lo\n\t-rm -f core/sys/osx/mach/semaphore.$(OBJEXT)\n\t-rm -f core/sys/osx/mach/semaphore.lo\n\t-rm -f core/sys/osx/mach/thread_act.$(OBJEXT)\n\t-rm -f core/sys/osx/mach/thread_act.lo\n\t-rm -f core/sys/osx/pthread.$(OBJEXT)\n\t-rm -f core/sys/osx/pthread.lo\n\t-rm -f core/sys/osx/sys/cdefs.$(OBJEXT)\n\t-rm -f core/sys/osx/sys/cdefs.lo\n\t-rm -f core/sys/osx/sys/event.$(OBJEXT)\n\t-rm -f core/sys/osx/sys/event.lo\n\t-rm -f core/sys/osx/sys/mman.$(OBJEXT)\n\t-rm -f core/sys/osx/sys/mman.lo\n\t-rm -f core/sys/posix/aio.$(OBJEXT)\n\t-rm -f core/sys/posix/aio.lo\n\t-rm -f core/sys/posix/arpa/inet.$(OBJEXT)\n\t-rm -f core/sys/posix/arpa/inet.lo\n\t-rm -f core/sys/posix/config.$(OBJEXT)\n\t-rm -f core/sys/posix/config.lo\n\t-rm -f core/sys/posix/dirent.$(OBJEXT)\n\t-rm -f core/sys/posix/dirent.lo\n\t-rm -f core/sys/posix/dlfcn.$(OBJEXT)\n\t-rm -f core/sys/posix/dlfcn.lo\n\t-rm -f core/sys/posix/fcntl.$(OBJEXT)\n\t-rm -f core/sys/posix/fcntl.lo\n\t-rm -f core/sys/posix/grp.$(OBJEXT)\n\t-rm -f core/sys/posix/grp.lo\n\t-rm -f core/sys/posix/iconv.$(OBJEXT)\n\t-rm -f core/sys/posix/iconv.lo\n\t-rm -f core/sys/posix/inttypes.$(OBJEXT)\n\t-rm -f core/sys/posix/inttypes.lo\n\t-rm -f core/sys/posix/libgen.$(OBJEXT)\n\t-rm -f core/sys/posix/libgen.lo\n\t-rm -f core/sys/posix/mqueue.$(OBJEXT)\n\t-rm -f core/sys/posix/mqueue.lo\n\t-rm -f core/sys/posix/net/if_.$(OBJEXT)\n\t-rm -f core/sys/posix/net/if_.lo\n\t-rm -f core/sys/posix/netdb.$(OBJEXT)\n\t-rm -f core/sys/posix/netdb.lo\n\t-rm -f core/sys/posix/netinet/in_.$(OBJEXT)\n\t-rm -f core/sys/posix/netinet/in_.lo\n\t-rm -f core/sys/posix/netinet/tcp.$(OBJEXT)\n\t-rm -f core/sys/posix/netinet/tcp.lo\n\t-rm -f core/sys/posix/poll.$(OBJEXT)\n\t-rm -f core/sys/posix/poll.lo\n\t-rm -f core/sys/posix/pthread.$(OBJEXT)\n\t-rm -f core/sys/posix/pthread.lo\n\t-rm -f core/sys/posix/pwd.$(OBJEXT)\n\t-rm -f core/sys/posix/pwd.lo\n\t-rm -f core/sys/posix/sched.$(OBJEXT)\n\t-rm -f core/sys/posix/sched.lo\n\t-rm -f core/sys/posix/semaphore.$(OBJEXT)\n\t-rm -f core/sys/posix/semaphore.lo\n\t-rm -f core/sys/posix/setjmp.$(OBJEXT)\n\t-rm -f core/sys/posix/setjmp.lo\n\t-rm -f core/sys/posix/signal.$(OBJEXT)\n\t-rm -f core/sys/posix/signal.lo\n\t-rm -f core/sys/posix/spawn.$(OBJEXT)\n\t-rm -f core/sys/posix/spawn.lo\n\t-rm -f core/sys/posix/stdio.$(OBJEXT)\n\t-rm -f core/sys/posix/stdio.lo\n\t-rm -f core/sys/posix/stdlib.$(OBJEXT)\n\t-rm -f core/sys/posix/stdlib.lo\n\t-rm -f core/sys/posix/sys/filio.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/filio.lo\n\t-rm -f core/sys/posix/sys/ioccom.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/ioccom.lo\n\t-rm -f core/sys/posix/sys/ioctl.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/ioctl.lo\n\t-rm -f core/sys/posix/sys/ipc.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/ipc.lo\n\t-rm -f core/sys/posix/sys/mman.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/mman.lo\n\t-rm -f core/sys/posix/sys/msg.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/msg.lo\n\t-rm -f core/sys/posix/sys/resource.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/resource.lo\n\t-rm -f core/sys/posix/sys/select.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/select.lo\n\t-rm -f core/sys/posix/sys/shm.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/shm.lo\n\t-rm -f core/sys/posix/sys/socket.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/socket.lo\n\t-rm -f core/sys/posix/sys/stat.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/stat.lo\n\t-rm -f core/sys/posix/sys/statvfs.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/statvfs.lo\n\t-rm -f core/sys/posix/sys/time.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/time.lo\n\t-rm -f core/sys/posix/sys/ttycom.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/ttycom.lo\n\t-rm -f core/sys/posix/sys/types.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/types.lo\n\t-rm -f core/sys/posix/sys/uio.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/uio.lo\n\t-rm -f core/sys/posix/sys/un.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/un.lo\n\t-rm -f core/sys/posix/sys/utsname.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/utsname.lo\n\t-rm -f core/sys/posix/sys/wait.$(OBJEXT)\n\t-rm -f core/sys/posix/sys/wait.lo\n\t-rm -f core/sys/posix/syslog.$(OBJEXT)\n\t-rm -f core/sys/posix/syslog.lo\n\t-rm -f core/sys/posix/termios.$(OBJEXT)\n\t-rm -f core/sys/posix/termios.lo\n\t-rm -f core/sys/posix/time.$(OBJEXT)\n\t-rm -f core/sys/posix/time.lo\n\t-rm -f core/sys/posix/ucontext.$(OBJEXT)\n\t-rm -f core/sys/posix/ucontext.lo\n\t-rm -f core/sys/posix/unistd.$(OBJEXT)\n\t-rm -f core/sys/posix/unistd.lo\n\t-rm -f core/sys/posix/utime.$(OBJEXT)\n\t-rm -f core/sys/posix/utime.lo\n\t-rm -f core/sys/solaris/dlfcn.$(OBJEXT)\n\t-rm -f core/sys/solaris/dlfcn.lo\n\t-rm -f core/sys/solaris/elf.$(OBJEXT)\n\t-rm -f core/sys/solaris/elf.lo\n\t-rm -f core/sys/solaris/execinfo.$(OBJEXT)\n\t-rm -f core/sys/solaris/execinfo.lo\n\t-rm -f core/sys/solaris/libelf.$(OBJEXT)\n\t-rm -f core/sys/solaris/libelf.lo\n\t-rm -f core/sys/solaris/link.$(OBJEXT)\n\t-rm -f core/sys/solaris/link.lo\n\t-rm -f core/sys/solaris/sys/elf.$(OBJEXT)\n\t-rm -f core/sys/solaris/sys/elf.lo\n\t-rm -f core/sys/solaris/sys/elf_386.$(OBJEXT)\n\t-rm -f core/sys/solaris/sys/elf_386.lo\n\t-rm -f core/sys/solaris/sys/elf_SPARC.$(OBJEXT)\n\t-rm -f core/sys/solaris/sys/elf_SPARC.lo\n\t-rm -f core/sys/solaris/sys/elf_amd64.$(OBJEXT)\n\t-rm -f core/sys/solaris/sys/elf_amd64.lo\n\t-rm -f core/sys/solaris/sys/elf_notes.$(OBJEXT)\n\t-rm -f core/sys/solaris/sys/elf_notes.lo\n\t-rm -f core/sys/solaris/sys/elftypes.$(OBJEXT)\n\t-rm -f core/sys/solaris/sys/elftypes.lo\n\t-rm -f core/sys/solaris/sys/link.$(OBJEXT)\n\t-rm -f core/sys/solaris/sys/link.lo\n\t-rm -f core/sys/solaris/sys/priocntl.$(OBJEXT)\n\t-rm -f core/sys/solaris/sys/priocntl.lo\n\t-rm -f core/sys/solaris/sys/procset.$(OBJEXT)\n\t-rm -f core/sys/solaris/sys/procset.lo\n\t-rm -f core/sys/solaris/sys/types.$(OBJEXT)\n\t-rm -f core/sys/solaris/sys/types.lo\n\t-rm -f core/sys/solaris/time.$(OBJEXT)\n\t-rm -f core/sys/solaris/time.lo\n\t-rm -f core/sys/windows/accctrl.$(OBJEXT)\n\t-rm -f core/sys/windows/accctrl.lo\n\t-rm -f core/sys/windows/aclapi.$(OBJEXT)\n\t-rm -f core/sys/windows/aclapi.lo\n\t-rm -f core/sys/windows/aclui.$(OBJEXT)\n\t-rm -f core/sys/windows/aclui.lo\n\t-rm -f core/sys/windows/basetsd.$(OBJEXT)\n\t-rm -f core/sys/windows/basetsd.lo\n\t-rm -f core/sys/windows/basetyps.$(OBJEXT)\n\t-rm -f core/sys/windows/basetyps.lo\n\t-rm -f core/sys/windows/cderr.$(OBJEXT)\n\t-rm -f core/sys/windows/cderr.lo\n\t-rm -f core/sys/windows/cguid.$(OBJEXT)\n\t-rm -f core/sys/windows/cguid.lo\n\t-rm -f core/sys/windows/com.$(OBJEXT)\n\t-rm -f core/sys/windows/com.lo\n\t-rm -f core/sys/windows/comcat.$(OBJEXT)\n\t-rm -f core/sys/windows/comcat.lo\n\t-rm -f core/sys/windows/commctrl.$(OBJEXT)\n\t-rm -f core/sys/windows/commctrl.lo\n\t-rm -f core/sys/windows/commdlg.$(OBJEXT)\n\t-rm -f core/sys/windows/commdlg.lo\n\t-rm -f core/sys/windows/core.$(OBJEXT)\n\t-rm -f core/sys/windows/core.lo\n\t-rm -f core/sys/windows/cpl.$(OBJEXT)\n\t-rm -f core/sys/windows/cpl.lo\n\t-rm -f core/sys/windows/cplext.$(OBJEXT)\n\t-rm -f core/sys/windows/cplext.lo\n\t-rm -f core/sys/windows/custcntl.$(OBJEXT)\n\t-rm -f core/sys/windows/custcntl.lo\n\t-rm -f core/sys/windows/dbghelp.$(OBJEXT)\n\t-rm -f core/sys/windows/dbghelp.lo\n\t-rm -f core/sys/windows/dbghelp_types.$(OBJEXT)\n\t-rm -f core/sys/windows/dbghelp_types.lo\n\t-rm -f core/sys/windows/dbt.$(OBJEXT)\n\t-rm -f core/sys/windows/dbt.lo\n\t-rm -f core/sys/windows/dde.$(OBJEXT)\n\t-rm -f core/sys/windows/dde.lo\n\t-rm -f core/sys/windows/ddeml.$(OBJEXT)\n\t-rm -f core/sys/windows/ddeml.lo\n\t-rm -f core/sys/windows/dhcpcsdk.$(OBJEXT)\n\t-rm -f core/sys/windows/dhcpcsdk.lo\n\t-rm -f core/sys/windows/dlgs.$(OBJEXT)\n\t-rm -f core/sys/windows/dlgs.lo\n\t-rm -f core/sys/windows/dll.$(OBJEXT)\n\t-rm -f core/sys/windows/dll.lo\n\t-rm -f core/sys/windows/docobj.$(OBJEXT)\n\t-rm -f core/sys/windows/docobj.lo\n\t-rm -f core/sys/windows/errorrep.$(OBJEXT)\n\t-rm -f core/sys/windows/errorrep.lo\n\t-rm -f core/sys/windows/exdisp.$(OBJEXT)\n\t-rm -f core/sys/windows/exdisp.lo\n\t-rm -f core/sys/windows/exdispid.$(OBJEXT)\n\t-rm -f core/sys/windows/exdispid.lo\n\t-rm -f core/sys/windows/httpext.$(OBJEXT)\n\t-rm -f core/sys/windows/httpext.lo\n\t-rm -f core/sys/windows/idispids.$(OBJEXT)\n\t-rm -f core/sys/windows/idispids.lo\n\t-rm -f core/sys/windows/imagehlp.$(OBJEXT)\n\t-rm -f core/sys/windows/imagehlp.lo\n\t-rm -f core/sys/windows/imm.$(OBJEXT)\n\t-rm -f core/sys/windows/imm.lo\n\t-rm -f core/sys/windows/intshcut.$(OBJEXT)\n\t-rm -f core/sys/windows/intshcut.lo\n\t-rm -f core/sys/windows/ipexport.$(OBJEXT)\n\t-rm -f core/sys/windows/ipexport.lo\n\t-rm -f core/sys/windows/iphlpapi.$(OBJEXT)\n\t-rm -f core/sys/windows/iphlpapi.lo\n\t-rm -f core/sys/windows/ipifcons.$(OBJEXT)\n\t-rm -f core/sys/windows/ipifcons.lo\n\t-rm -f core/sys/windows/iprtrmib.$(OBJEXT)\n\t-rm -f core/sys/windows/iprtrmib.lo\n\t-rm -f core/sys/windows/iptypes.$(OBJEXT)\n\t-rm -f core/sys/windows/iptypes.lo\n\t-rm -f core/sys/windows/isguids.$(OBJEXT)\n\t-rm -f core/sys/windows/isguids.lo\n\t-rm -f core/sys/windows/lm.$(OBJEXT)\n\t-rm -f core/sys/windows/lm.lo\n\t-rm -f core/sys/windows/lmaccess.$(OBJEXT)\n\t-rm -f core/sys/windows/lmaccess.lo\n\t-rm -f core/sys/windows/lmalert.$(OBJEXT)\n\t-rm -f core/sys/windows/lmalert.lo\n\t-rm -f core/sys/windows/lmapibuf.$(OBJEXT)\n\t-rm -f core/sys/windows/lmapibuf.lo\n\t-rm -f core/sys/windows/lmat.$(OBJEXT)\n\t-rm -f core/sys/windows/lmat.lo\n\t-rm -f core/sys/windows/lmaudit.$(OBJEXT)\n\t-rm -f core/sys/windows/lmaudit.lo\n\t-rm -f core/sys/windows/lmbrowsr.$(OBJEXT)\n\t-rm -f core/sys/windows/lmbrowsr.lo\n\t-rm -f core/sys/windows/lmchdev.$(OBJEXT)\n\t-rm -f core/sys/windows/lmchdev.lo\n\t-rm -f core/sys/windows/lmconfig.$(OBJEXT)\n\t-rm -f core/sys/windows/lmconfig.lo\n\t-rm -f core/sys/windows/lmcons.$(OBJEXT)\n\t-rm -f core/sys/windows/lmcons.lo\n\t-rm -f core/sys/windows/lmerr.$(OBJEXT)\n\t-rm -f core/sys/windows/lmerr.lo\n\t-rm -f core/sys/windows/lmerrlog.$(OBJEXT)\n\t-rm -f core/sys/windows/lmerrlog.lo\n\t-rm -f core/sys/windows/lmmsg.$(OBJEXT)\n\t-rm -f core/sys/windows/lmmsg.lo\n\t-rm -f core/sys/windows/lmremutl.$(OBJEXT)\n\t-rm -f core/sys/windows/lmremutl.lo\n\t-rm -f core/sys/windows/lmrepl.$(OBJEXT)\n\t-rm -f core/sys/windows/lmrepl.lo\n\t-rm -f core/sys/windows/lmserver.$(OBJEXT)\n\t-rm -f core/sys/windows/lmserver.lo\n\t-rm -f core/sys/windows/lmshare.$(OBJEXT)\n\t-rm -f core/sys/windows/lmshare.lo\n\t-rm -f core/sys/windows/lmsname.$(OBJEXT)\n\t-rm -f core/sys/windows/lmsname.lo\n\t-rm -f core/sys/windows/lmstats.$(OBJEXT)\n\t-rm -f core/sys/windows/lmstats.lo\n\t-rm -f core/sys/windows/lmsvc.$(OBJEXT)\n\t-rm -f core/sys/windows/lmsvc.lo\n\t-rm -f core/sys/windows/lmuse.$(OBJEXT)\n\t-rm -f core/sys/windows/lmuse.lo\n\t-rm -f core/sys/windows/lmuseflg.$(OBJEXT)\n\t-rm -f core/sys/windows/lmuseflg.lo\n\t-rm -f core/sys/windows/lmwksta.$(OBJEXT)\n\t-rm -f core/sys/windows/lmwksta.lo\n\t-rm -f core/sys/windows/lzexpand.$(OBJEXT)\n\t-rm -f core/sys/windows/lzexpand.lo\n\t-rm -f core/sys/windows/mapi.$(OBJEXT)\n\t-rm -f core/sys/windows/mapi.lo\n\t-rm -f core/sys/windows/mciavi.$(OBJEXT)\n\t-rm -f core/sys/windows/mciavi.lo\n\t-rm -f core/sys/windows/mcx.$(OBJEXT)\n\t-rm -f core/sys/windows/mcx.lo\n\t-rm -f core/sys/windows/mgmtapi.$(OBJEXT)\n\t-rm -f core/sys/windows/mgmtapi.lo\n\t-rm -f core/sys/windows/mmsystem.$(OBJEXT)\n\t-rm -f core/sys/windows/mmsystem.lo\n\t-rm -f core/sys/windows/msacm.$(OBJEXT)\n\t-rm -f core/sys/windows/msacm.lo\n\t-rm -f core/sys/windows/mshtml.$(OBJEXT)\n\t-rm -f core/sys/windows/mshtml.lo\n\t-rm -f core/sys/windows/mswsock.$(OBJEXT)\n\t-rm -f core/sys/windows/mswsock.lo\n\t-rm -f core/sys/windows/nb30.$(OBJEXT)\n\t-rm -f core/sys/windows/nb30.lo\n\t-rm -f core/sys/windows/nddeapi.$(OBJEXT)\n\t-rm -f core/sys/windows/nddeapi.lo\n\t-rm -f core/sys/windows/nspapi.$(OBJEXT)\n\t-rm -f core/sys/windows/nspapi.lo\n\t-rm -f core/sys/windows/ntdef.$(OBJEXT)\n\t-rm -f core/sys/windows/ntdef.lo\n\t-rm -f core/sys/windows/ntdll.$(OBJEXT)\n\t-rm -f core/sys/windows/ntdll.lo\n\t-rm -f core/sys/windows/ntldap.$(OBJEXT)\n\t-rm -f core/sys/windows/ntldap.lo\n\t-rm -f core/sys/windows/ntsecapi.$(OBJEXT)\n\t-rm -f core/sys/windows/ntsecapi.lo\n\t-rm -f core/sys/windows/ntsecpkg.$(OBJEXT)\n\t-rm -f core/sys/windows/ntsecpkg.lo\n\t-rm -f core/sys/windows/oaidl.$(OBJEXT)\n\t-rm -f core/sys/windows/oaidl.lo\n\t-rm -f core/sys/windows/objbase.$(OBJEXT)\n\t-rm -f core/sys/windows/objbase.lo\n\t-rm -f core/sys/windows/objfwd.$(OBJEXT)\n\t-rm -f core/sys/windows/objfwd.lo\n\t-rm -f core/sys/windows/objidl.$(OBJEXT)\n\t-rm -f core/sys/windows/objidl.lo\n\t-rm -f core/sys/windows/objsafe.$(OBJEXT)\n\t-rm -f core/sys/windows/objsafe.lo\n\t-rm -f core/sys/windows/ocidl.$(OBJEXT)\n\t-rm -f core/sys/windows/ocidl.lo\n\t-rm -f core/sys/windows/odbcinst.$(OBJEXT)\n\t-rm -f core/sys/windows/odbcinst.lo\n\t-rm -f core/sys/windows/ole.$(OBJEXT)\n\t-rm -f core/sys/windows/ole.lo\n\t-rm -f core/sys/windows/ole2.$(OBJEXT)\n\t-rm -f core/sys/windows/ole2.lo\n\t-rm -f core/sys/windows/ole2ver.$(OBJEXT)\n\t-rm -f core/sys/windows/ole2ver.lo\n\t-rm -f core/sys/windows/oleacc.$(OBJEXT)\n\t-rm -f core/sys/windows/oleacc.lo\n\t-rm -f core/sys/windows/oleauto.$(OBJEXT)\n\t-rm -f core/sys/windows/oleauto.lo\n\t-rm -f core/sys/windows/olectl.$(OBJEXT)\n\t-rm -f core/sys/windows/olectl.lo\n\t-rm -f core/sys/windows/olectlid.$(OBJEXT)\n\t-rm -f core/sys/windows/olectlid.lo\n\t-rm -f core/sys/windows/oledlg.$(OBJEXT)\n\t-rm -f core/sys/windows/oledlg.lo\n\t-rm -f core/sys/windows/oleidl.$(OBJEXT)\n\t-rm -f core/sys/windows/oleidl.lo\n\t-rm -f core/sys/windows/pbt.$(OBJEXT)\n\t-rm -f core/sys/windows/pbt.lo\n\t-rm -f core/sys/windows/powrprof.$(OBJEXT)\n\t-rm -f core/sys/windows/powrprof.lo\n\t-rm -f core/sys/windows/prsht.$(OBJEXT)\n\t-rm -f core/sys/windows/prsht.lo\n\t-rm -f core/sys/windows/psapi.$(OBJEXT)\n\t-rm -f core/sys/windows/psapi.lo\n\t-rm -f core/sys/windows/rapi.$(OBJEXT)\n\t-rm -f core/sys/windows/rapi.lo\n\t-rm -f core/sys/windows/ras.$(OBJEXT)\n\t-rm -f core/sys/windows/ras.lo\n\t-rm -f core/sys/windows/rasdlg.$(OBJEXT)\n\t-rm -f core/sys/windows/rasdlg.lo\n\t-rm -f core/sys/windows/raserror.$(OBJEXT)\n\t-rm -f core/sys/windows/raserror.lo\n\t-rm -f core/sys/windows/rassapi.$(OBJEXT)\n\t-rm -f core/sys/windows/rassapi.lo\n\t-rm -f core/sys/windows/reason.$(OBJEXT)\n\t-rm -f core/sys/windows/reason.lo\n\t-rm -f core/sys/windows/regstr.$(OBJEXT)\n\t-rm -f core/sys/windows/regstr.lo\n\t-rm -f core/sys/windows/richedit.$(OBJEXT)\n\t-rm -f core/sys/windows/richedit.lo\n\t-rm -f core/sys/windows/richole.$(OBJEXT)\n\t-rm -f core/sys/windows/richole.lo\n\t-rm -f core/sys/windows/rpc.$(OBJEXT)\n\t-rm -f core/sys/windows/rpc.lo\n\t-rm -f core/sys/windows/rpcdce.$(OBJEXT)\n\t-rm -f core/sys/windows/rpcdce.lo\n\t-rm -f core/sys/windows/rpcdce2.$(OBJEXT)\n\t-rm -f core/sys/windows/rpcdce2.lo\n\t-rm -f core/sys/windows/rpcdcep.$(OBJEXT)\n\t-rm -f core/sys/windows/rpcdcep.lo\n\t-rm -f core/sys/windows/rpcndr.$(OBJEXT)\n\t-rm -f core/sys/windows/rpcndr.lo\n\t-rm -f core/sys/windows/rpcnsi.$(OBJEXT)\n\t-rm -f core/sys/windows/rpcnsi.lo\n\t-rm -f core/sys/windows/rpcnsip.$(OBJEXT)\n\t-rm -f core/sys/windows/rpcnsip.lo\n\t-rm -f core/sys/windows/rpcnterr.$(OBJEXT)\n\t-rm -f core/sys/windows/rpcnterr.lo\n\t-rm -f core/sys/windows/schannel.$(OBJEXT)\n\t-rm -f core/sys/windows/schannel.lo\n\t-rm -f core/sys/windows/secext.$(OBJEXT)\n\t-rm -f core/sys/windows/secext.lo\n\t-rm -f core/sys/windows/security.$(OBJEXT)\n\t-rm -f core/sys/windows/security.lo\n\t-rm -f core/sys/windows/servprov.$(OBJEXT)\n\t-rm -f core/sys/windows/servprov.lo\n\t-rm -f core/sys/windows/setupapi.$(OBJEXT)\n\t-rm -f core/sys/windows/setupapi.lo\n\t-rm -f core/sys/windows/shellapi.$(OBJEXT)\n\t-rm -f core/sys/windows/shellapi.lo\n\t-rm -f core/sys/windows/shldisp.$(OBJEXT)\n\t-rm -f core/sys/windows/shldisp.lo\n\t-rm -f core/sys/windows/shlguid.$(OBJEXT)\n\t-rm -f core/sys/windows/shlguid.lo\n\t-rm -f core/sys/windows/shlobj.$(OBJEXT)\n\t-rm -f core/sys/windows/shlobj.lo\n\t-rm -f core/sys/windows/shlwapi.$(OBJEXT)\n\t-rm -f core/sys/windows/shlwapi.lo\n\t-rm -f core/sys/windows/snmp.$(OBJEXT)\n\t-rm -f core/sys/windows/snmp.lo\n\t-rm -f core/sys/windows/sql.$(OBJEXT)\n\t-rm -f core/sys/windows/sql.lo\n\t-rm -f core/sys/windows/sqlext.$(OBJEXT)\n\t-rm -f core/sys/windows/sqlext.lo\n\t-rm -f core/sys/windows/sqltypes.$(OBJEXT)\n\t-rm -f core/sys/windows/sqltypes.lo\n\t-rm -f core/sys/windows/sqlucode.$(OBJEXT)\n\t-rm -f core/sys/windows/sqlucode.lo\n\t-rm -f core/sys/windows/sspi.$(OBJEXT)\n\t-rm -f core/sys/windows/sspi.lo\n\t-rm -f core/sys/windows/stacktrace.$(OBJEXT)\n\t-rm -f core/sys/windows/stacktrace.lo\n\t-rm -f core/sys/windows/stat.$(OBJEXT)\n\t-rm -f core/sys/windows/stat.lo\n\t-rm -f core/sys/windows/subauth.$(OBJEXT)\n\t-rm -f core/sys/windows/subauth.lo\n\t-rm -f core/sys/windows/threadaux.$(OBJEXT)\n\t-rm -f core/sys/windows/threadaux.lo\n\t-rm -f core/sys/windows/tlhelp32.$(OBJEXT)\n\t-rm -f core/sys/windows/tlhelp32.lo\n\t-rm -f core/sys/windows/tmschema.$(OBJEXT)\n\t-rm -f core/sys/windows/tmschema.lo\n\t-rm -f core/sys/windows/unknwn.$(OBJEXT)\n\t-rm -f core/sys/windows/unknwn.lo\n\t-rm -f core/sys/windows/uuid.$(OBJEXT)\n\t-rm -f core/sys/windows/uuid.lo\n\t-rm -f core/sys/windows/vfw.$(OBJEXT)\n\t-rm -f core/sys/windows/vfw.lo\n\t-rm -f core/sys/windows/w32api.$(OBJEXT)\n\t-rm -f core/sys/windows/w32api.lo\n\t-rm -f core/sys/windows/winbase.$(OBJEXT)\n\t-rm -f core/sys/windows/winbase.lo\n\t-rm -f core/sys/windows/winber.$(OBJEXT)\n\t-rm -f core/sys/windows/winber.lo\n\t-rm -f core/sys/windows/wincon.$(OBJEXT)\n\t-rm -f core/sys/windows/wincon.lo\n\t-rm -f core/sys/windows/wincrypt.$(OBJEXT)\n\t-rm -f core/sys/windows/wincrypt.lo\n\t-rm -f core/sys/windows/windef.$(OBJEXT)\n\t-rm -f core/sys/windows/windef.lo\n\t-rm -f core/sys/windows/windows.$(OBJEXT)\n\t-rm -f core/sys/windows/windows.lo\n\t-rm -f core/sys/windows/winerror.$(OBJEXT)\n\t-rm -f core/sys/windows/winerror.lo\n\t-rm -f core/sys/windows/wingdi.$(OBJEXT)\n\t-rm -f core/sys/windows/wingdi.lo\n\t-rm -f core/sys/windows/winhttp.$(OBJEXT)\n\t-rm -f core/sys/windows/winhttp.lo\n\t-rm -f core/sys/windows/wininet.$(OBJEXT)\n\t-rm -f core/sys/windows/wininet.lo\n\t-rm -f core/sys/windows/winioctl.$(OBJEXT)\n\t-rm -f core/sys/windows/winioctl.lo\n\t-rm -f core/sys/windows/winldap.$(OBJEXT)\n\t-rm -f core/sys/windows/winldap.lo\n\t-rm -f core/sys/windows/winnetwk.$(OBJEXT)\n\t-rm -f core/sys/windows/winnetwk.lo\n\t-rm -f core/sys/windows/winnls.$(OBJEXT)\n\t-rm -f core/sys/windows/winnls.lo\n\t-rm -f core/sys/windows/winnt.$(OBJEXT)\n\t-rm -f core/sys/windows/winnt.lo\n\t-rm -f core/sys/windows/winperf.$(OBJEXT)\n\t-rm -f core/sys/windows/winperf.lo\n\t-rm -f core/sys/windows/winreg.$(OBJEXT)\n\t-rm -f core/sys/windows/winreg.lo\n\t-rm -f core/sys/windows/winsock2.$(OBJEXT)\n\t-rm -f core/sys/windows/winsock2.lo\n\t-rm -f core/sys/windows/winspool.$(OBJEXT)\n\t-rm -f core/sys/windows/winspool.lo\n\t-rm -f core/sys/windows/winsvc.$(OBJEXT)\n\t-rm -f core/sys/windows/winsvc.lo\n\t-rm -f core/sys/windows/winuser.$(OBJEXT)\n\t-rm -f core/sys/windows/winuser.lo\n\t-rm -f core/sys/windows/winver.$(OBJEXT)\n\t-rm -f core/sys/windows/winver.lo\n\t-rm -f core/sys/windows/wtsapi32.$(OBJEXT)\n\t-rm -f core/sys/windows/wtsapi32.lo\n\t-rm -f core/sys/windows/wtypes.$(OBJEXT)\n\t-rm -f core/sys/windows/wtypes.lo\n\t-rm -f core/thread.$(OBJEXT)\n\t-rm -f core/thread.lo\n\t-rm -f core/time.$(OBJEXT)\n\t-rm -f core/time.lo\n\t-rm -f core/vararg.$(OBJEXT)\n\t-rm -f core/vararg.lo\n\t-rm -f gc/bits.$(OBJEXT)\n\t-rm -f gc/bits.lo\n\t-rm -f gc/config.$(OBJEXT)\n\t-rm -f gc/config.lo\n\t-rm -f gc/gcinterface.$(OBJEXT)\n\t-rm -f gc/gcinterface.lo\n\t-rm -f gc/impl/conservative/gc.$(OBJEXT)\n\t-rm -f gc/impl/conservative/gc.lo\n\t-rm -f gc/impl/manual/gc.$(OBJEXT)\n\t-rm -f gc/impl/manual/gc.lo\n\t-rm -f gc/impl/proto/gc.$(OBJEXT)\n\t-rm -f gc/impl/proto/gc.lo\n\t-rm -f gc/os.$(OBJEXT)\n\t-rm -f gc/os.lo\n\t-rm -f gc/pooltable.$(OBJEXT)\n\t-rm -f gc/pooltable.lo\n\t-rm -f gc/proxy.$(OBJEXT)\n\t-rm -f gc/proxy.lo\n\t-rm -f gcc/attribute.$(OBJEXT)\n\t-rm -f gcc/attribute.lo\n\t-rm -f gcc/backtrace.$(OBJEXT)\n\t-rm -f gcc/backtrace.lo\n\t-rm -f gcc/builtins.$(OBJEXT)\n\t-rm -f gcc/builtins.lo\n\t-rm -f gcc/config.$(OBJEXT)\n\t-rm -f gcc/config.lo\n\t-rm -f gcc/deh.$(OBJEXT)\n\t-rm -f gcc/deh.lo\n\t-rm -f gcc/libbacktrace.$(OBJEXT)\n\t-rm -f gcc/libbacktrace.lo\n\t-rm -f gcc/unwind/arm.$(OBJEXT)\n\t-rm -f gcc/unwind/arm.lo\n\t-rm -f gcc/unwind/arm_common.$(OBJEXT)\n\t-rm -f gcc/unwind/arm_common.lo\n\t-rm -f gcc/unwind/c6x.$(OBJEXT)\n\t-rm -f gcc/unwind/c6x.lo\n\t-rm -f gcc/unwind/generic.$(OBJEXT)\n\t-rm -f gcc/unwind/generic.lo\n\t-rm -f gcc/unwind/package.$(OBJEXT)\n\t-rm -f gcc/unwind/package.lo\n\t-rm -f gcc/unwind/pe.$(OBJEXT)\n\t-rm -f gcc/unwind/pe.lo\n\t-rm -f rt/aApply.$(OBJEXT)\n\t-rm -f rt/aApply.lo\n\t-rm -f rt/aApplyR.$(OBJEXT)\n\t-rm -f rt/aApplyR.lo\n\t-rm -f rt/aaA.$(OBJEXT)\n\t-rm -f rt/aaA.lo\n\t-rm -f rt/adi.$(OBJEXT)\n\t-rm -f rt/adi.lo\n\t-rm -f rt/arrayassign.$(OBJEXT)\n\t-rm -f rt/arrayassign.lo\n\t-rm -f rt/arraycast.$(OBJEXT)\n\t-rm -f rt/arraycast.lo\n\t-rm -f rt/arraycat.$(OBJEXT)\n\t-rm -f rt/arraycat.lo\n\t-rm -f rt/cast_.$(OBJEXT)\n\t-rm -f rt/cast_.lo\n\t-rm -f rt/config.$(OBJEXT)\n\t-rm -f rt/config.lo\n\t-rm -f rt/critical_.$(OBJEXT)\n\t-rm -f rt/critical_.lo\n\t-rm -f rt/deh.$(OBJEXT)\n\t-rm -f rt/deh.lo\n\t-rm -f rt/dmain2.$(OBJEXT)\n\t-rm -f rt/dmain2.lo\n\t-rm -f rt/ehalloc.$(OBJEXT)\n\t-rm -f rt/ehalloc.lo\n\t-rm -f rt/invariant.$(OBJEXT)\n\t-rm -f rt/invariant.lo\n\t-rm -f rt/lifetime.$(OBJEXT)\n\t-rm -f rt/lifetime.lo\n\t-rm -f rt/memory.$(OBJEXT)\n\t-rm -f rt/memory.lo\n\t-rm -f rt/minfo.$(OBJEXT)\n\t-rm -f rt/minfo.lo\n\t-rm -f rt/monitor_.$(OBJEXT)\n\t-rm -f rt/monitor_.lo\n\t-rm -f rt/obj.$(OBJEXT)\n\t-rm -f rt/obj.lo\n\t-rm -f rt/qsort.$(OBJEXT)\n\t-rm -f rt/qsort.lo\n\t-rm -f rt/sections.$(OBJEXT)\n\t-rm -f rt/sections.lo\n\t-rm -f rt/sections_android.$(OBJEXT)\n\t-rm -f rt/sections_android.lo\n\t-rm -f rt/sections_elf_shared.$(OBJEXT)\n\t-rm -f rt/sections_elf_shared.lo\n\t-rm -f rt/sections_osx_x86.$(OBJEXT)\n\t-rm -f rt/sections_osx_x86.lo\n\t-rm -f rt/sections_osx_x86_64.$(OBJEXT)\n\t-rm -f rt/sections_osx_x86_64.lo\n\t-rm -f rt/sections_solaris.$(OBJEXT)\n\t-rm -f rt/sections_solaris.lo\n\t-rm -f rt/sections_win32.$(OBJEXT)\n\t-rm -f rt/sections_win32.lo\n\t-rm -f rt/sections_win64.$(OBJEXT)\n\t-rm -f rt/sections_win64.lo\n\t-rm -f rt/tlsgc.$(OBJEXT)\n\t-rm -f rt/tlsgc.lo\n\t-rm -f rt/typeinfo/ti_Acdouble.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_Acdouble.lo\n\t-rm -f rt/typeinfo/ti_Acfloat.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_Acfloat.lo\n\t-rm -f rt/typeinfo/ti_Acreal.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_Acreal.lo\n\t-rm -f rt/typeinfo/ti_Adouble.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_Adouble.lo\n\t-rm -f rt/typeinfo/ti_Afloat.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_Afloat.lo\n\t-rm -f rt/typeinfo/ti_Ag.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_Ag.lo\n\t-rm -f rt/typeinfo/ti_Aint.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_Aint.lo\n\t-rm -f rt/typeinfo/ti_Along.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_Along.lo\n\t-rm -f rt/typeinfo/ti_Areal.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_Areal.lo\n\t-rm -f rt/typeinfo/ti_Ashort.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_Ashort.lo\n\t-rm -f rt/typeinfo/ti_C.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_C.lo\n\t-rm -f rt/typeinfo/ti_byte.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_byte.lo\n\t-rm -f rt/typeinfo/ti_cdouble.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_cdouble.lo\n\t-rm -f rt/typeinfo/ti_cent.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_cent.lo\n\t-rm -f rt/typeinfo/ti_cfloat.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_cfloat.lo\n\t-rm -f rt/typeinfo/ti_char.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_char.lo\n\t-rm -f rt/typeinfo/ti_creal.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_creal.lo\n\t-rm -f rt/typeinfo/ti_dchar.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_dchar.lo\n\t-rm -f rt/typeinfo/ti_delegate.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_delegate.lo\n\t-rm -f rt/typeinfo/ti_double.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_double.lo\n\t-rm -f rt/typeinfo/ti_float.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_float.lo\n\t-rm -f rt/typeinfo/ti_idouble.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_idouble.lo\n\t-rm -f rt/typeinfo/ti_ifloat.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_ifloat.lo\n\t-rm -f rt/typeinfo/ti_int.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_int.lo\n\t-rm -f rt/typeinfo/ti_ireal.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_ireal.lo\n\t-rm -f rt/typeinfo/ti_long.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_long.lo\n\t-rm -f rt/typeinfo/ti_n.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_n.lo\n\t-rm -f rt/typeinfo/ti_ptr.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_ptr.lo\n\t-rm -f rt/typeinfo/ti_real.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_real.lo\n\t-rm -f rt/typeinfo/ti_short.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_short.lo\n\t-rm -f rt/typeinfo/ti_ubyte.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_ubyte.lo\n\t-rm -f rt/typeinfo/ti_ucent.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_ucent.lo\n\t-rm -f rt/typeinfo/ti_uint.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_uint.lo\n\t-rm -f rt/typeinfo/ti_ulong.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_ulong.lo\n\t-rm -f rt/typeinfo/ti_ushort.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_ushort.lo\n\t-rm -f rt/typeinfo/ti_void.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_void.lo\n\t-rm -f rt/typeinfo/ti_wchar.$(OBJEXT)\n\t-rm -f rt/typeinfo/ti_wchar.lo\n\t-rm -f rt/util/array.$(OBJEXT)\n\t-rm -f rt/util/array.lo\n\t-rm -f rt/util/container/array.$(OBJEXT)\n\t-rm -f rt/util/container/array.lo\n\t-rm -f rt/util/container/common.$(OBJEXT)\n\t-rm -f rt/util/container/common.lo\n\t-rm -f rt/util/container/hashtab.$(OBJEXT)\n\t-rm -f rt/util/container/hashtab.lo\n\t-rm -f rt/util/container/treap.$(OBJEXT)\n\t-rm -f rt/util/container/treap.lo\n\t-rm -f rt/util/random.$(OBJEXT)\n\t-rm -f rt/util/random.lo\n\t-rm -f rt/util/typeinfo.$(OBJEXT)\n\t-rm -f rt/util/typeinfo.lo\n\t-rm -f rt/util/utf.$(OBJEXT)\n\t-rm -f rt/util/utf.lo\n\ndistclean-compile:\n\t-rm -f *.tab.c\n\n.S.o:\n\t$(CPPASCOMPILE) -c -o $@ $<\n\n.S.obj:\n\t$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`\n\n.S.lo:\n\t$(LTCPPASCOMPILE) -c -o $@ $<\n\nlibgdruntime_la-threadasm.lo: core/threadasm.S\n\t$(LIBTOOL)  $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o libgdruntime_la-threadasm.lo `test -f 'core/threadasm.S' || echo '$(srcdir)/'`core/threadasm.S\n\nlibgdruntime_t_la-threadasm.lo: core/threadasm.S\n\t$(LIBTOOL)  $(libgdruntime_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o libgdruntime_t_la-threadasm.lo `test -f 'core/threadasm.S' || echo '$(srcdir)/'`core/threadasm.S\n\nthreadasm.o: core/threadasm.S\n\t$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o threadasm.o `test -f 'core/threadasm.S' || echo '$(srcdir)/'`core/threadasm.S\n\nthreadasm.obj: core/threadasm.S\n\t$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o threadasm.obj `if test -f 'core/threadasm.S'; then $(CYGPATH_W) 'core/threadasm.S'; else $(CYGPATH_W) '$(srcdir)/core/threadasm.S'; fi`\n\n.c.o:\n\t$(COMPILE) -c $<\n\n.c.obj:\n\t$(COMPILE) -c `$(CYGPATH_W) '$<'`\n\n.c.lo:\n\t$(LTCOMPILE) -c -o $@ $<\n\nlibgdruntime_la-errno_.lo: core/stdc/errno_.c\n\t$(LIBTOOL)  --tag=CC $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgdruntime_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c\n\nlibgdruntime_t_la-errno_.lo: core/stdc/errno_.c\n\t$(LIBTOOL)  --tag=CC $(libgdruntime_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgdruntime_t_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c\n\nerrno_.o: core/stdc/errno_.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errno_.o `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c\n\nerrno_.obj: core/stdc/errno_.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errno_.obj `if test -f 'core/stdc/errno_.c'; then $(CYGPATH_W) 'core/stdc/errno_.c'; else $(CYGPATH_W) '$(srcdir)/core/stdc/errno_.c'; fi`\n\nmostlyclean-libtool:\n\t-rm -f *.lo\n\nclean-libtool:\n\t-rm -rf .libs _libs\n\t-rm -rf core/.libs core/_libs\n\t-rm -rf core/internal/.libs core/internal/_libs\n\t-rm -rf core/stdc/.libs core/stdc/_libs\n\t-rm -rf core/sync/.libs core/sync/_libs\n\t-rm -rf core/sys/bionic/.libs core/sys/bionic/_libs\n\t-rm -rf core/sys/darwin/.libs core/sys/darwin/_libs\n\t-rm -rf core/sys/darwin/mach/.libs core/sys/darwin/mach/_libs\n\t-rm -rf core/sys/darwin/netinet/.libs core/sys/darwin/netinet/_libs\n\t-rm -rf core/sys/darwin/sys/.libs core/sys/darwin/sys/_libs\n\t-rm -rf core/sys/dragonflybsd/.libs core/sys/dragonflybsd/_libs\n\t-rm -rf core/sys/dragonflybsd/netinet/.libs core/sys/dragonflybsd/netinet/_libs\n\t-rm -rf core/sys/dragonflybsd/sys/.libs core/sys/dragonflybsd/sys/_libs\n\t-rm -rf core/sys/freebsd/.libs core/sys/freebsd/_libs\n\t-rm -rf core/sys/freebsd/netinet/.libs core/sys/freebsd/netinet/_libs\n\t-rm -rf core/sys/freebsd/sys/.libs core/sys/freebsd/sys/_libs\n\t-rm -rf core/sys/linux/.libs core/sys/linux/_libs\n\t-rm -rf core/sys/linux/netinet/.libs core/sys/linux/netinet/_libs\n\t-rm -rf core/sys/linux/sys/.libs core/sys/linux/sys/_libs\n\t-rm -rf core/sys/linux/sys/netinet/.libs core/sys/linux/sys/netinet/_libs\n\t-rm -rf core/sys/openbsd/.libs core/sys/openbsd/_libs\n\t-rm -rf core/sys/osx/.libs core/sys/osx/_libs\n\t-rm -rf core/sys/osx/mach/.libs core/sys/osx/mach/_libs\n\t-rm -rf core/sys/osx/sys/.libs core/sys/osx/sys/_libs\n\t-rm -rf core/sys/posix/.libs core/sys/posix/_libs\n\t-rm -rf core/sys/posix/arpa/.libs core/sys/posix/arpa/_libs\n\t-rm -rf core/sys/posix/net/.libs core/sys/posix/net/_libs\n\t-rm -rf core/sys/posix/netinet/.libs core/sys/posix/netinet/_libs\n\t-rm -rf core/sys/posix/sys/.libs core/sys/posix/sys/_libs\n\t-rm -rf core/sys/solaris/.libs core/sys/solaris/_libs\n\t-rm -rf core/sys/solaris/sys/.libs core/sys/solaris/sys/_libs\n\t-rm -rf core/sys/windows/.libs core/sys/windows/_libs\n\t-rm -rf gc/.libs gc/_libs\n\t-rm -rf gc/impl/conservative/.libs gc/impl/conservative/_libs\n\t-rm -rf gc/impl/manual/.libs gc/impl/manual/_libs\n\t-rm -rf gc/impl/proto/.libs gc/impl/proto/_libs\n\t-rm -rf gcc/.libs gcc/_libs\n\t-rm -rf gcc/unwind/.libs gcc/unwind/_libs\n\t-rm -rf rt/.libs rt/_libs\n\t-rm -rf rt/typeinfo/.libs rt/typeinfo/_libs\n\t-rm -rf rt/util/.libs rt/util/_libs\n\t-rm -rf rt/util/container/.libs rt/util/container/_libs\n\nID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)\n\tlist='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\tmkid -fID $$unique\ntags: TAGS\n\nTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \\\n\t\t$(TAGS_FILES) $(LISP)\n\tset x; \\\n\there=`pwd`; \\\n\tlist='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\tshift; \\\n\tif test -z \"$(ETAGS_ARGS)$$*$$unique\"; then :; else \\\n\t  test -n \"$$unique\" || unique=$$empty_fix; \\\n\t  if test $$# -gt 0; then \\\n\t    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \\\n\t      \"$$@\" $$unique; \\\n\t  else \\\n\t    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \\\n\t      $$unique; \\\n\t  fi; \\\n\tfi\nctags: CTAGS\nCTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \\\n\t\t$(TAGS_FILES) $(LISP)\n\tlist='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\ttest -z \"$(CTAGS_ARGS)$$unique\" \\\n\t  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \\\n\t     $$unique\n\nGTAGS:\n\there=`$(am__cd) $(top_builddir) && pwd` \\\n\t  && $(am__cd) $(top_srcdir) \\\n\t  && gtags -i $(GTAGS_ARGS) \"$$here\"\n\ndistclean-tags:\n\t-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags\ncheck-am: all-am\n\t$(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS)\ncheck: check-am\nall-am: Makefile $(LTLIBRARIES)\ninstalldirs:\n\tfor dir in \"$(DESTDIR)$(toolexeclibdir)\"; do \\\n\t  test -z \"$$dir\" || $(MKDIR_P) \"$$dir\"; \\\n\tdone\ninstall: install-am\ninstall-exec: install-exec-am\ninstall-data: install-data-am\nuninstall: uninstall-am\n\ninstall-am: all-am\n\t@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am\n\ninstallcheck: installcheck-am\ninstall-strip:\n\tif test -z '$(STRIP)'; then \\\n\t  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" \\\n\t    install_sh_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" INSTALL_STRIP_FLAG=-s \\\n\t      install; \\\n\telse \\\n\t  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" \\\n\t    install_sh_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" INSTALL_STRIP_FLAG=-s \\\n\t    \"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'\" install; \\\n\tfi\nmostlyclean-generic:\n\nclean-generic:\n\ndistclean-generic:\n\t-test -z \"$(CONFIG_CLEAN_FILES)\" || rm -f $(CONFIG_CLEAN_FILES)\n\t-test . = \"$(srcdir)\" || test -z \"$(CONFIG_CLEAN_VPATH_FILES)\" || rm -f $(CONFIG_CLEAN_VPATH_FILES)\n\t-rm -f ../testsuite/$(am__dirstamp)\n\t-rm -f core/$(am__dirstamp)\n\t-rm -f core/internal/$(am__dirstamp)\n\t-rm -f core/stdc/$(am__dirstamp)\n\t-rm -f core/sync/$(am__dirstamp)\n\t-rm -f core/sys/bionic/$(am__dirstamp)\n\t-rm -f core/sys/darwin/$(am__dirstamp)\n\t-rm -f core/sys/darwin/mach/$(am__dirstamp)\n\t-rm -f core/sys/darwin/netinet/$(am__dirstamp)\n\t-rm -f core/sys/darwin/sys/$(am__dirstamp)\n\t-rm -f core/sys/dragonflybsd/$(am__dirstamp)\n\t-rm -f core/sys/dragonflybsd/netinet/$(am__dirstamp)\n\t-rm -f core/sys/dragonflybsd/sys/$(am__dirstamp)\n\t-rm -f core/sys/freebsd/$(am__dirstamp)\n\t-rm -f core/sys/freebsd/netinet/$(am__dirstamp)\n\t-rm -f core/sys/freebsd/sys/$(am__dirstamp)\n\t-rm -f core/sys/linux/$(am__dirstamp)\n\t-rm -f core/sys/linux/netinet/$(am__dirstamp)\n\t-rm -f core/sys/linux/sys/$(am__dirstamp)\n\t-rm -f core/sys/linux/sys/netinet/$(am__dirstamp)\n\t-rm -f core/sys/openbsd/$(am__dirstamp)\n\t-rm -f core/sys/osx/$(am__dirstamp)\n\t-rm -f core/sys/osx/mach/$(am__dirstamp)\n\t-rm -f core/sys/osx/sys/$(am__dirstamp)\n\t-rm -f core/sys/posix/$(am__dirstamp)\n\t-rm -f core/sys/posix/arpa/$(am__dirstamp)\n\t-rm -f core/sys/posix/net/$(am__dirstamp)\n\t-rm -f core/sys/posix/netinet/$(am__dirstamp)\n\t-rm -f core/sys/posix/sys/$(am__dirstamp)\n\t-rm -f core/sys/solaris/$(am__dirstamp)\n\t-rm -f core/sys/solaris/sys/$(am__dirstamp)\n\t-rm -f core/sys/windows/$(am__dirstamp)\n\t-rm -f gc/$(am__dirstamp)\n\t-rm -f gc/impl/conservative/$(am__dirstamp)\n\t-rm -f gc/impl/manual/$(am__dirstamp)\n\t-rm -f gc/impl/proto/$(am__dirstamp)\n\t-rm -f gcc/$(am__dirstamp)\n\t-rm -f gcc/unwind/$(am__dirstamp)\n\t-rm -f rt/$(am__dirstamp)\n\t-rm -f rt/typeinfo/$(am__dirstamp)\n\t-rm -f rt/util/$(am__dirstamp)\n\t-rm -f rt/util/container/$(am__dirstamp)\n\nmaintainer-clean-generic:\n\t@echo \"This command is intended for maintainers to use\"\n\t@echo \"it deletes files that may require special tools to rebuild.\"\nclean: clean-am\n\nclean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \\\n\tclean-libtool clean-local clean-toolexeclibLTLIBRARIES \\\n\tmostlyclean-am\n\ndistclean: distclean-am\n\t-rm -f Makefile\ndistclean-am: clean-am distclean-compile distclean-generic \\\n\tdistclean-tags\n\ndvi: dvi-am\n\ndvi-am:\n\nhtml: html-am\n\nhtml-am:\n\ninfo: info-am\n\ninfo-am:\n\ninstall-data-am: install-data-local\n\ninstall-dvi: install-dvi-am\n\ninstall-dvi-am:\n\ninstall-exec-am: install-toolexeclibLTLIBRARIES\n\ninstall-html: install-html-am\n\ninstall-html-am:\n\ninstall-info: install-info-am\n\ninstall-info-am:\n\ninstall-man:\n\ninstall-pdf: install-pdf-am\n\ninstall-pdf-am:\n\ninstall-ps: install-ps-am\n\ninstall-ps-am:\n\ninstallcheck-am:\n\nmaintainer-clean: maintainer-clean-am\n\t-rm -f Makefile\nmaintainer-clean-am: distclean-am maintainer-clean-generic\n\nmostlyclean: mostlyclean-am\n\nmostlyclean-am: mostlyclean-compile mostlyclean-generic \\\n\tmostlyclean-libtool\n\npdf: pdf-am\n\npdf-am:\n\nps: ps-am\n\nps-am:\n\nuninstall-am: uninstall-toolexeclibLTLIBRARIES\n\n.MAKE: check-am install-am install-strip\n\n.PHONY: CTAGS GTAGS all all-am check check-am clean \\\n\tclean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \\\n\tclean-libtool clean-local clean-toolexeclibLTLIBRARIES ctags \\\n\tdistclean distclean-compile distclean-generic \\\n\tdistclean-libtool distclean-tags dvi dvi-am html html-am info \\\n\tinfo-am install install-am install-data install-data-am \\\n\tinstall-data-local install-dvi install-dvi-am install-exec \\\n\tinstall-exec-am install-html install-html-am install-info \\\n\tinstall-info-am install-man install-pdf install-pdf-am \\\n\tinstall-ps install-ps-am install-strip \\\n\tinstall-toolexeclibLTLIBRARIES installcheck installcheck-am \\\n\tinstalldirs maintainer-clean maintainer-clean-generic \\\n\tmostlyclean mostlyclean-compile mostlyclean-generic \\\n\tmostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \\\n\tuninstall-am uninstall-toolexeclibLTLIBRARIES\n\n\n# Compile D into normal object files\n.d.o:\n\t$(GDC) $(GDCFLAGS) $(MULTIFLAGS) $(D_EXTRA_DFLAGS) -c -o $@ $<\n\n# Compile D sources with libtool\n.d.lo:\n\t$(LTDCOMPILE) $(GDCFLAGS) $(MULTIFLAGS) $(D_EXTRA_DFLAGS) -c -o $@ $<\n\n# Unittest rules. Unfortunately we can't use _DFLAGS in automake without\n# explicit D support, so use this hack.\n# Compile D sources with libtool and test flags\n%.t.lo : %.d\n\t$(LTDCOMPILE) $(GDCFLAGSX) $(MULTIFLAGS) $(D_EXTRA_DFLAGS) -c -o $@ $<\n\n# Compile objects for static linking with test flags\n# Automake breaks empty rules, so use the shell NOP :\n%.t.o : %.t.lo\n\t@:\n\n# Extra install and clean rules.\n# This does not delete the .libs/.t.o files, but deleting\n# the .lo is good enough to rerun the rules\nclean-local:\n\trm -f $(DRUNTIME_TEST_LOBJECTS)\n\trm -f $(DRUNTIME_TEST_OBJECTS)\n\n# Handles generated files as well\ninstall-data-local:\n\tfor file in $(ALL_DRUNTIME_INSTALL_DSOURCES); do \\\n\t  if test -f $$file; then \\\n\t    $(INSTALL_HEADER) -D $$file $(DESTDIR)$(gdc_include_dir)/$$file ; \\\n\t  else \\\n\t    $(INSTALL_HEADER) -D $(srcdir)/$$file \\\n\t      $(DESTDIR)$(gdc_include_dir)/$$file ; \\\n\t  fi ; \\\n\tdone\n\n# Tell versions [3.59,3.63) of GNU make to not export all variables.\n# Otherwise a system limit (for SysV at least) may be exceeded.\n.NOEXPORT:\n"
  },
  {
    "path": "libphobos/libdruntime/__entrypoint.di",
    "content": "/* GDC -- D front-end for GCC\n   Copyright (C) 2013-2018 Free Software Foundation, Inc.\n\n   GCC is free software; you can redistribute it and/or modify it under\n   the terms of the GNU General Public License as published by the Free\n   Software Foundation; either version 3, or (at your option) any later\n   version.\n\n   GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n   WARRANTY; without even the implied warranty of MERCHANTABILITY or\n   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n   for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with GCC; see the file COPYING3.  If not see\n   <http://www.gnu.org/licenses/>.\n*/\n\n/* This module provides the C main() function supplied by the user's program.  */\n\nmodule __entrypoint;\n\nextern(C):\n\n/* The D main() function supplied by the user's program\n\n   It always has `_Dmain` symbol name and uses C calling convention.\n   But D frontend returns its type as `extern(D)` because of Issue 9028.\n   As we need to deal with actual calling convention we have to mark it\n   as `extern(C)` and use its symbol name.\n*/\n\nint _Dmain(char[][] args);\nint _d_run_main(int argc, char **argv, void* mainFunc);\n\n/* Substitutes for the C main() function.  Just calls into d_run_main with\n   the default main function.  Applications are free to implement their own\n   main function and call the _d_run_main function themselves with any main\n   function.\n*/\n\nint main(int argc, char **argv)\n{\n    return _d_run_main(argc, argv, &_Dmain);\n}\n\n/* This is apparently needed on Solaris because the C tool chain seems to\n   expect the main function to be called _main.  It needs both not just one!\n*/\n\nversion (Solaris)\nint _main(int argc, char** argv)\n{\n    return main(argc, argv);\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/__main.di",
    "content": "/* GDC -- D front-end for GCC\n   Copyright (C) 2018 Free Software Foundation, Inc.\n\n   GCC is free software; you can redistribute it and/or modify it under\n   the terms of the GNU General Public License as published by the Free\n   Software Foundation; either version 3, or (at your option) any later\n   version.\n\n   GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n   WARRANTY; without even the implied warranty of MERCHANTABILITY or\n   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n   for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with GCC; see the file COPYING3.  If not see\n   <http://www.gnu.org/licenses/>.\n*/\n\n/* This module provides the D main() function supplied by the user's program.  */\n\nmodule __main;\n\nint main(char[][])\n{\n    return 0;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/atomic.d",
    "content": "/**\n * The atomic module provides basic support for lock-free\n * concurrent programming.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2016.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Source:    $(DRUNTIMESRC core/_atomic.d)\n */\n\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule core.atomic;\n\nversion (D_InlineAsm_X86)\n{\n    version = AsmX86;\n    version = AsmX86_32;\n    enum has64BitCAS = true;\n    enum has128BitCAS = false;\n}\nelse version (D_InlineAsm_X86_64)\n{\n    version = AsmX86;\n    version = AsmX86_64;\n    enum has64BitCAS = true;\n    enum has128BitCAS = true;\n}\nelse version (GNU)\n{\n    import gcc.config;\n    enum has64BitCAS = GNU_Have_64Bit_Atomics;\n    enum has128BitCAS = GNU_Have_LibAtomic;\n}\nelse\n{\n    enum has64BitCAS = false;\n    enum has128BitCAS = false;\n}\n\nprivate\n{\n    /* Construct a type with a shared tail, and if possible with an unshared\n    head. */\n    template TailShared(U) if (!is(U == shared))\n    {\n        alias TailShared = .TailShared!(shared U);\n    }\n    template TailShared(S) if (is(S == shared))\n    {\n        // Get the unshared variant of S.\n        static if (is(S U == shared U)) {}\n        else static assert(false, \"Should never be triggered. The `static \" ~\n            \"if` declares `U` as the unshared version of the shared type \" ~\n            \"`S`. `S` is explicitly declared as shared, so getting `U` \" ~\n            \"should always work.\");\n\n        static if (is(S : U))\n            alias TailShared = U;\n        else static if (is(S == struct))\n        {\n            enum implName = () {\n                /* Start with \"_impl\". If S has a field with that name, append\n                underscores until the clash is resolved. */\n                string name = \"_impl\";\n                string[] fieldNames;\n                static foreach (alias field; S.tupleof)\n                {\n                    fieldNames ~= __traits(identifier, field);\n                }\n                static bool canFind(string[] haystack, string needle)\n                {\n                    foreach (candidate; haystack)\n                    {\n                        if (candidate == needle) return true;\n                    }\n                    return false;\n                }\n                while (canFind(fieldNames, name)) name ~= \"_\";\n                return name;\n            } ();\n            struct TailShared\n            {\n                static foreach (i, alias field; S.tupleof)\n                {\n                    /* On @trusted: This is casting the field from shared(Foo)\n                    to TailShared!Foo. The cast is safe because the field has\n                    been loaded and is not shared anymore. */\n                    mixin(\"\n                        @trusted @property\n                        ref \" ~ __traits(identifier, field) ~ \"()\n                        {\n                            alias R = TailShared!(typeof(field));\n                            return * cast(R*) &\" ~ implName ~ \".tupleof[i];\n                        }\n                    \");\n                }\n                mixin(\"\n                    S \" ~ implName ~ \";\n                    alias \" ~ implName ~ \" this;\n                \");\n            }\n        }\n        else\n            alias TailShared = S;\n    }\n    @safe unittest\n    {\n        // No tail (no indirections) -> fully unshared.\n\n        static assert(is(TailShared!int == int));\n        static assert(is(TailShared!(shared int) == int));\n\n        static struct NoIndir { int i; }\n        static assert(is(TailShared!NoIndir == NoIndir));\n        static assert(is(TailShared!(shared NoIndir) == NoIndir));\n\n        // Tail can be independently shared or is already -> tail-shared.\n\n        static assert(is(TailShared!(int*) == shared(int)*));\n        static assert(is(TailShared!(shared int*) == shared(int)*));\n        static assert(is(TailShared!(shared(int)*) == shared(int)*));\n\n        static assert(is(TailShared!(int[]) == shared(int)[]));\n        static assert(is(TailShared!(shared int[]) == shared(int)[]));\n        static assert(is(TailShared!(shared(int)[]) == shared(int)[]));\n\n        static struct S1 { shared int* p; }\n        static assert(is(TailShared!S1 == S1));\n        static assert(is(TailShared!(shared S1) == S1));\n\n        static struct S2 { shared(int)* p; }\n        static assert(is(TailShared!S2 == S2));\n        static assert(is(TailShared!(shared S2) == S2));\n\n        // Tail follows shared-ness of head -> fully shared.\n\n        static class C { int i; }\n        static assert(is(TailShared!C == shared C));\n        static assert(is(TailShared!(shared C) == shared C));\n\n        /* However, structs get a wrapper that has getters which cast to\n        TailShared. */\n\n        static struct S3 { int* p; int _impl; int _impl_; int _impl__; }\n        static assert(!is(TailShared!S3 : S3));\n        static assert(is(TailShared!S3 : shared S3));\n        static assert(is(TailShared!(shared S3) == TailShared!S3));\n\n        static struct S4 { shared(int)** p; }\n        static assert(!is(TailShared!S4 : S4));\n        static assert(is(TailShared!S4 : shared S4));\n        static assert(is(TailShared!(shared S4) == TailShared!S4));\n    }\n}\n\n\nversion (AsmX86)\n{\n    // NOTE: Strictly speaking, the x86 supports atomic operations on\n    //       unaligned values.  However, this is far slower than the\n    //       common case, so such behavior should be prohibited.\n    private bool atomicValueIsProperlyAligned(T)( ref T val ) pure nothrow @nogc @trusted\n    {\n        return atomicPtrIsProperlyAligned(&val);\n    }\n\n    private bool atomicPtrIsProperlyAligned(T)( T* ptr ) pure nothrow @nogc @safe\n    {\n        // NOTE: 32 bit x86 systems support 8 byte CAS, which only requires\n        //       4 byte alignment, so use size_t as the align type here.\n        static if ( T.sizeof > size_t.sizeof )\n            return cast(size_t)ptr % size_t.sizeof == 0;\n        else\n            return cast(size_t)ptr % T.sizeof == 0;\n    }\n}\n\n\nversion (CoreDdoc)\n{\n    /**\n     * Performs the binary operation 'op' on val using 'mod' as the modifier.\n     *\n     * Params:\n     *  val = The target variable.\n     *  mod = The modifier to apply.\n     *\n     * Returns:\n     *  The result of the operation.\n     */\n    TailShared!T atomicOp(string op, T, V1)( ref shared T val, V1 mod ) pure nothrow @nogc @safe\n        if ( __traits( compiles, mixin( \"*cast(T*)&val\" ~ op ~ \"mod\" ) ) )\n    {\n        return TailShared!T.init;\n    }\n\n\n    /**\n     * Stores 'writeThis' to the memory referenced by 'here' if the value\n     * referenced by 'here' is equal to 'ifThis'.  This operation is both\n     * lock-free and atomic.\n     *\n     * Params:\n     *  here      = The address of the destination variable.\n     *  writeThis = The value to store.\n     *  ifThis    = The comparison value.\n     *\n     * Returns:\n     *  true if the store occurred, false if not.\n     */\n    bool cas(T,V1,V2)( shared(T)* here, const V1 ifThis, V2 writeThis ) pure nothrow @nogc @safe\n        if ( !is(T == class) && !is(T U : U*) && __traits( compiles, { *here = writeThis; } ) );\n\n    /// Ditto\n    bool cas(T,V1,V2)( shared(T)* here, const shared(V1) ifThis, shared(V2) writeThis ) pure nothrow @nogc @safe\n        if ( is(T == class) && __traits( compiles, { *here = writeThis; } ) );\n\n    /// Ditto\n    bool cas(T,V1,V2)( shared(T)* here, const shared(V1)* ifThis, shared(V2)* writeThis ) pure nothrow @nogc @safe\n        if ( is(T U : U*) && __traits( compiles, { *here = writeThis; } ) );\n\n    /**\n     * Loads 'val' from memory and returns it.  The memory barrier specified\n     * by 'ms' is applied to the operation, which is fully sequenced by\n     * default.  Valid memory orders are MemoryOrder.raw, MemoryOrder.acq,\n     * and MemoryOrder.seq.\n     *\n     * Params:\n     *  val = The target variable.\n     *\n     * Returns:\n     *  The value of 'val'.\n     */\n    TailShared!T atomicLoad(MemoryOrder ms = MemoryOrder.seq,T)( ref const shared T val ) pure nothrow @nogc @safe\n    {\n        return TailShared!T.init;\n    }\n\n\n    /**\n     * Writes 'newval' into 'val'.  The memory barrier specified by 'ms' is\n     * applied to the operation, which is fully sequenced by default.\n     * Valid memory orders are MemoryOrder.raw, MemoryOrder.rel, and\n     * MemoryOrder.seq.\n     *\n     * Params:\n     *  val    = The target variable.\n     *  newval = The value to store.\n     */\n    void atomicStore(MemoryOrder ms = MemoryOrder.seq,T,V1)( ref shared T val, V1 newval ) pure nothrow @nogc @safe\n        if ( __traits( compiles, { val = newval; } ) )\n    {\n\n    }\n\n\n    /**\n     * Specifies the memory ordering semantics of an atomic operation.\n     */\n    enum MemoryOrder\n    {\n        raw,    /// Not sequenced.\n        acq,    /// Hoist-load + hoist-store barrier.\n        rel,    /// Sink-load + sink-store barrier.\n        seq,    /// Fully sequenced (acquire + release).\n    }\n\n    deprecated(\"Please use MemoryOrder instead.\")\n    alias MemoryOrder msync;\n\n    /**\n     * Inserts a full load/store memory fence (on platforms that need it). This ensures\n     * that all loads and stores before a call to this function are executed before any\n     * loads and stores after the call.\n     */\n    void atomicFence() nothrow @nogc;\n}\nelse version (AsmX86_32)\n{\n    // Uses specialized asm for fast fetch and add operations\n    private TailShared!(T) atomicFetchAdd(T)( ref shared T val, size_t mod ) pure nothrow @nogc @safe\n        if ( T.sizeof <= 4 )\n    {\n        size_t tmp = mod;\n        asm pure nothrow @nogc @trusted\n        {\n            mov EAX, tmp;\n            mov EDX, val;\n        }\n        static if (T.sizeof == 1) asm pure nothrow @nogc @trusted { lock; xadd[EDX], AL; }\n        else static if (T.sizeof == 2) asm pure nothrow @nogc @trusted { lock; xadd[EDX], AX; }\n        else static if (T.sizeof == 4) asm pure nothrow @nogc @trusted { lock; xadd[EDX], EAX; }\n\n        asm pure nothrow @nogc @trusted\n        {\n            mov tmp, EAX;\n        }\n\n        return cast(T)tmp;\n    }\n\n    private TailShared!(T) atomicFetchSub(T)( ref shared T val, size_t mod ) pure nothrow @nogc @safe\n        if ( T.sizeof <= 4)\n    {\n        return atomicFetchAdd(val, -mod);\n    }\n\n    TailShared!T atomicOp(string op, T, V1)( ref shared T val, V1 mod ) pure nothrow @nogc\n        if ( __traits( compiles, mixin( \"*cast(T*)&val\" ~ op ~ \"mod\" ) ) )\n    in\n    {\n        assert(atomicValueIsProperlyAligned(val));\n    }\n    do\n    {\n        // binary operators\n        //\n        // +    -   *   /   %   ^^  &\n        // |    ^   <<  >>  >>> ~   in\n        // ==   !=  <   <=  >   >=\n        static if (op == \"+\"  || op == \"-\"  || op == \"*\"  || op == \"/\"   ||\n                   op == \"%\"  || op == \"^^\" || op == \"&\"  || op == \"|\"   ||\n                   op == \"^\"  || op == \"<<\" || op == \">>\" || op == \">>>\" ||\n                   op == \"~\"  || // skip \"in\"\n                   op == \"==\" || op == \"!=\" || op == \"<\"  || op == \"<=\"  ||\n                   op == \">\"  || op == \">=\")\n        {\n            TailShared!T get = atomicLoad!(MemoryOrder.raw)( val );\n            mixin( \"return get \" ~ op ~ \" mod;\" );\n        }\n        else\n        // assignment operators\n        //\n        // +=   -=  *=  /=  %=  ^^= &=\n        // |=   ^=  <<= >>= >>>=    ~=\n        static if ( op == \"+=\" && __traits(isIntegral, T) && T.sizeof <= 4 && V1.sizeof <= 4)\n        {\n            return cast(T)(atomicFetchAdd!(T)(val, mod) + mod);\n        }\n        else static if ( op == \"-=\" && __traits(isIntegral, T) && T.sizeof <= 4 && V1.sizeof <= 4)\n        {\n            return cast(T)(atomicFetchSub!(T)(val, mod) - mod);\n        }\n        else static if ( op == \"+=\" || op == \"-=\"  || op == \"*=\"  || op == \"/=\" ||\n                   op == \"%=\" || op == \"^^=\" || op == \"&=\"  || op == \"|=\" ||\n                   op == \"^=\" || op == \"<<=\" || op == \">>=\" || op == \">>>=\" ) // skip \"~=\"\n        {\n            TailShared!T get, set;\n\n            do\n            {\n                get = set = atomicLoad!(MemoryOrder.raw)( val );\n                mixin( \"set \" ~ op ~ \" mod;\" );\n            } while ( !casByRef( val, get, set ) );\n            return set;\n        }\n        else\n        {\n            static assert( false, \"Operation not supported.\" );\n        }\n    }\n\n    bool casByRef(T,V1,V2)( ref T value, V1 ifThis, V2 writeThis ) pure nothrow @nogc @trusted\n    {\n        return cas(&value, ifThis, writeThis);\n    }\n\n    bool cas(T,V1,V2)( shared(T)* here, const V1 ifThis, V2 writeThis ) pure nothrow @nogc @safe\n        if ( !is(T == class) && !is(T U : U*) && __traits( compiles, { *here = writeThis; } ) )\n    {\n        return casImpl(here, ifThis, writeThis);\n    }\n\n    bool cas(T,V1,V2)( shared(T)* here, const shared(V1) ifThis, shared(V2) writeThis ) pure nothrow @nogc @safe\n        if ( is(T == class) && __traits( compiles, { *here = writeThis; } ) )\n    {\n        return casImpl(here, ifThis, writeThis);\n    }\n\n    bool cas(T,V1,V2)( shared(T)* here, const shared(V1)* ifThis, shared(V2)* writeThis ) pure nothrow @nogc @safe\n        if ( is(T U : U*) && __traits( compiles, { *here = writeThis; } ) )\n    {\n        return casImpl(here, ifThis, writeThis);\n    }\n\n    private bool casImpl(T,V1,V2)( shared(T)* here, V1 ifThis, V2 writeThis ) pure nothrow @nogc @safe\n    in\n    {\n        assert( atomicPtrIsProperlyAligned( here ) );\n    }\n    do\n    {\n        static if ( T.sizeof == byte.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 1 Byte CAS\n            //////////////////////////////////////////////////////////////////\n\n            asm pure nothrow @nogc @trusted\n            {\n                mov DL, writeThis;\n                mov AL, ifThis;\n                mov ECX, here;\n                lock; // lock always needed to make this op atomic\n                cmpxchg [ECX], DL;\n                setz AL;\n            }\n        }\n        else static if ( T.sizeof == short.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 2 Byte CAS\n            //////////////////////////////////////////////////////////////////\n\n            asm pure nothrow @nogc @trusted\n            {\n                mov DX, writeThis;\n                mov AX, ifThis;\n                mov ECX, here;\n                lock; // lock always needed to make this op atomic\n                cmpxchg [ECX], DX;\n                setz AL;\n            }\n        }\n        else static if ( T.sizeof == int.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 4 Byte CAS\n            //////////////////////////////////////////////////////////////////\n\n            asm pure nothrow @nogc @trusted\n            {\n                mov EDX, writeThis;\n                mov EAX, ifThis;\n                mov ECX, here;\n                lock; // lock always needed to make this op atomic\n                cmpxchg [ECX], EDX;\n                setz AL;\n            }\n        }\n        else static if ( T.sizeof == long.sizeof && has64BitCAS )\n        {\n\n            //////////////////////////////////////////////////////////////////\n            // 8 Byte CAS on a 32-Bit Processor\n            //////////////////////////////////////////////////////////////////\n\n            asm pure nothrow @nogc @trusted\n            {\n                push EDI;\n                push EBX;\n                lea EDI, writeThis;\n                mov EBX, [EDI];\n                mov ECX, 4[EDI];\n                lea EDI, ifThis;\n                mov EAX, [EDI];\n                mov EDX, 4[EDI];\n                mov EDI, here;\n                lock; // lock always needed to make this op atomic\n                cmpxchg8b [EDI];\n                setz AL;\n                pop EBX;\n                pop EDI;\n\n            }\n\n        }\n        else\n        {\n            static assert( false, \"Invalid template type specified.\" );\n        }\n    }\n\n\n    enum MemoryOrder\n    {\n        raw,\n        acq,\n        rel,\n        seq,\n    }\n\n    deprecated(\"Please use MemoryOrder instead.\")\n    alias MemoryOrder msync;\n\n\n    private\n    {\n        // NOTE: x86 loads implicitly have acquire semantics so a memory\n        //       barrier is only necessary on releases.\n        template needsLoadBarrier( MemoryOrder ms )\n        {\n            enum bool needsLoadBarrier = ms == MemoryOrder.seq;\n        }\n\n\n        // NOTE: x86 stores implicitly have release semantics so a memory\n        //       barrier is only necessary on acquires.\n        template needsStoreBarrier( MemoryOrder ms )\n        {\n            enum bool needsStoreBarrier = ms == MemoryOrder.seq;\n        }\n    }\n\n\n    TailShared!T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)( ref const shared T val ) pure nothrow @nogc @safe\n    if (!__traits(isFloating, T))\n    {\n        static assert( ms != MemoryOrder.rel, \"invalid MemoryOrder for atomicLoad()\" );\n        static assert( __traits(isPOD, T), \"argument to atomicLoad() must be POD\" );\n\n        static if ( T.sizeof == byte.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 1 Byte Load\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsLoadBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov DL, 0;\n                    mov AL, 0;\n                    mov ECX, val;\n                    lock; // lock always needed to make this op atomic\n                    cmpxchg [ECX], DL;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov EAX, val;\n                    mov AL, [EAX];\n                }\n            }\n        }\n        else static if ( T.sizeof == short.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 2 Byte Load\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsLoadBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov DX, 0;\n                    mov AX, 0;\n                    mov ECX, val;\n                    lock; // lock always needed to make this op atomic\n                    cmpxchg [ECX], DX;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov EAX, val;\n                    mov AX, [EAX];\n                }\n            }\n        }\n        else static if ( T.sizeof == int.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 4 Byte Load\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsLoadBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov EDX, 0;\n                    mov EAX, 0;\n                    mov ECX, val;\n                    lock; // lock always needed to make this op atomic\n                    cmpxchg [ECX], EDX;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov EAX, val;\n                    mov EAX, [EAX];\n                }\n            }\n        }\n        else static if ( T.sizeof == long.sizeof && has64BitCAS )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 8 Byte Load on a 32-Bit Processor\n            //////////////////////////////////////////////////////////////////\n\n            asm pure nothrow @nogc @trusted\n            {\n                push EDI;\n                push EBX;\n                mov EBX, 0;\n                mov ECX, 0;\n                mov EAX, 0;\n                mov EDX, 0;\n                mov EDI, val;\n                lock; // lock always needed to make this op atomic\n                cmpxchg8b [EDI];\n                pop EBX;\n                pop EDI;\n            }\n        }\n        else\n        {\n            static assert( false, \"Invalid template type specified.\" );\n        }\n    }\n\n    void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V1)( ref shared T val, V1 newval ) pure nothrow @nogc @safe\n        if ( __traits( compiles, { val = newval; } ) )\n    {\n        static assert( ms != MemoryOrder.acq, \"invalid MemoryOrder for atomicStore()\" );\n        static assert( __traits(isPOD, T), \"argument to atomicStore() must be POD\" );\n\n        static if ( T.sizeof == byte.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 1 Byte Store\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsStoreBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov EAX, val;\n                    mov DL, newval;\n                    lock;\n                    xchg [EAX], DL;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov EAX, val;\n                    mov DL, newval;\n                    mov [EAX], DL;\n                }\n            }\n        }\n        else static if ( T.sizeof == short.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 2 Byte Store\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsStoreBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov EAX, val;\n                    mov DX, newval;\n                    lock;\n                    xchg [EAX], DX;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov EAX, val;\n                    mov DX, newval;\n                    mov [EAX], DX;\n                }\n            }\n        }\n        else static if ( T.sizeof == int.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 4 Byte Store\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsStoreBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov EAX, val;\n                    mov EDX, newval;\n                    lock;\n                    xchg [EAX], EDX;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov EAX, val;\n                    mov EDX, newval;\n                    mov [EAX], EDX;\n                }\n            }\n        }\n        else static if ( T.sizeof == long.sizeof && has64BitCAS )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 8 Byte Store on a 32-Bit Processor\n            //////////////////////////////////////////////////////////////////\n\n            asm pure nothrow @nogc @trusted\n            {\n                push EDI;\n                push EBX;\n                lea EDI, newval;\n                mov EBX, [EDI];\n                mov ECX, 4[EDI];\n                mov EDI, val;\n                mov EAX, [EDI];\n                mov EDX, 4[EDI];\n            L1: lock; // lock always needed to make this op atomic\n                cmpxchg8b [EDI];\n                jne L1;\n                pop EBX;\n                pop EDI;\n            }\n        }\n        else\n        {\n            static assert( false, \"Invalid template type specified.\" );\n        }\n    }\n\n\n    void atomicFence() nothrow @nogc @safe\n    {\n        import core.cpuid;\n\n        asm pure nothrow @nogc @trusted\n        {\n            naked;\n\n            call sse2;\n            test AL, AL;\n            jne Lcpuid;\n\n            // Fast path: We have SSE2, so just use mfence.\n            mfence;\n            jmp Lend;\n\n        Lcpuid:\n\n            // Slow path: We use cpuid to serialize. This is\n            // significantly slower than mfence, but is the\n            // only serialization facility we have available\n            // on older non-SSE2 chips.\n            push EBX;\n\n            mov EAX, 0;\n            cpuid;\n\n            pop EBX;\n\n        Lend:\n\n            ret;\n        }\n    }\n}\nelse version (AsmX86_64)\n{\n    // Uses specialized asm for fast fetch and add operations\n    private TailShared!(T) atomicFetchAdd(T)( ref shared T val, size_t mod ) pure nothrow @nogc @trusted\n        if ( __traits(isIntegral, T) )\n    in\n    {\n        assert( atomicValueIsProperlyAligned(val));\n    }\n    do\n    {\n        size_t tmp = mod;\n        asm pure nothrow @nogc @trusted\n        {\n            mov RAX, tmp;\n            mov RDX, val;\n        }\n        static if (T.sizeof == 1) asm pure nothrow @nogc @trusted { lock; xadd[RDX], AL; }\n        else static if (T.sizeof == 2) asm pure nothrow @nogc @trusted { lock; xadd[RDX], AX; }\n        else static if (T.sizeof == 4) asm pure nothrow @nogc @trusted { lock; xadd[RDX], EAX; }\n        else static if (T.sizeof == 8) asm pure nothrow @nogc @trusted { lock; xadd[RDX], RAX; }\n\n        asm pure nothrow @nogc @trusted\n        {\n            mov tmp, RAX;\n        }\n\n        return cast(T)tmp;\n    }\n\n    private TailShared!(T) atomicFetchSub(T)( ref shared T val, size_t mod ) pure nothrow @nogc @safe\n        if ( __traits(isIntegral, T) )\n    {\n        return atomicFetchAdd(val, -mod);\n    }\n\n    TailShared!T atomicOp(string op, T, V1)( ref shared T val, V1 mod ) pure nothrow @nogc\n        if ( __traits( compiles, mixin( \"*cast(T*)&val\" ~ op ~ \"mod\" ) ) )\n    in\n    {\n        assert( atomicValueIsProperlyAligned(val));\n    }\n    do\n    {\n        // binary operators\n        //\n        // +    -   *   /   %   ^^  &\n        // |    ^   <<  >>  >>> ~   in\n        // ==   !=  <   <=  >   >=\n        static if ( op == \"+\"  || op == \"-\"  || op == \"*\"  || op == \"/\"   ||\n                   op == \"%\"  || op == \"^^\" || op == \"&\"  || op == \"|\"   ||\n                   op == \"^\"  || op == \"<<\" || op == \">>\" || op == \">>>\" ||\n                   op == \"~\"  || // skip \"in\"\n                   op == \"==\" || op == \"!=\" || op == \"<\"  || op == \"<=\"  ||\n                   op == \">\"  || op == \">=\" )\n        {\n            TailShared!T get = atomicLoad!(MemoryOrder.raw)( val );\n            mixin( \"return get \" ~ op ~ \" mod;\" );\n        }\n        else\n        // assignment operators\n        //\n        // +=   -=  *=  /=  %=  ^^= &=\n        // |=   ^=  <<= >>= >>>=    ~=\n        static if ( op == \"+=\" && __traits(isIntegral, T) && __traits(isIntegral, V1))\n        {\n            return cast(T)(atomicFetchAdd!(T)(val, mod) + mod);\n        }\n        else static if ( op == \"-=\" && __traits(isIntegral, T) && __traits(isIntegral, V1))\n        {\n            return cast(T)(atomicFetchSub!(T)(val, mod) - mod);\n        }\n        else static if ( op == \"+=\" || op == \"-=\"  || op == \"*=\"  || op == \"/=\" ||\n                   op == \"%=\" || op == \"^^=\" || op == \"&=\"  || op == \"|=\" ||\n                   op == \"^=\" || op == \"<<=\" || op == \">>=\" || op == \">>>=\" ) // skip \"~=\"\n        {\n            TailShared!T get, set;\n\n            do\n            {\n                get = set = atomicLoad!(MemoryOrder.raw)( val );\n                mixin( \"set \" ~ op ~ \" mod;\" );\n            } while ( !casByRef( val, get, set ) );\n            return set;\n        }\n        else\n        {\n            static assert( false, \"Operation not supported.\" );\n        }\n    }\n\n\n    bool casByRef(T,V1,V2)( ref T value, V1 ifThis, V2 writeThis ) pure nothrow @nogc @trusted\n    {\n        return cas(&value, ifThis, writeThis);\n    }\n\n    bool cas(T,V1,V2)( shared(T)* here, const V1 ifThis, V2 writeThis ) pure nothrow @nogc @safe\n        if ( !is(T == class) && !is(T U : U*) &&  __traits( compiles, { *here = writeThis; } ) )\n    {\n        return casImpl(here, ifThis, writeThis);\n    }\n\n    bool cas(T,V1,V2)( shared(T)* here, const shared(V1) ifThis, shared(V2) writeThis ) pure nothrow @nogc @safe\n        if ( is(T == class) && __traits( compiles, { *here = writeThis; } ) )\n    {\n        return casImpl(here, ifThis, writeThis);\n    }\n\n    bool cas(T,V1,V2)( shared(T)* here, const shared(V1)* ifThis, shared(V2)* writeThis ) pure nothrow @nogc @safe\n        if ( is(T U : U*) && __traits( compiles, { *here = writeThis; } ) )\n    {\n        return casImpl(here, ifThis, writeThis);\n    }\n\n    private bool casImpl(T,V1,V2)( shared(T)* here, V1 ifThis, V2 writeThis ) pure nothrow @nogc @safe\n    in\n    {\n        assert( atomicPtrIsProperlyAligned( here ) );\n    }\n    do\n    {\n        static if ( T.sizeof == byte.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 1 Byte CAS\n            //////////////////////////////////////////////////////////////////\n\n            asm pure nothrow @nogc @trusted\n            {\n                mov DL, writeThis;\n                mov AL, ifThis;\n                mov RCX, here;\n                lock; // lock always needed to make this op atomic\n                cmpxchg [RCX], DL;\n                setz AL;\n            }\n        }\n        else static if ( T.sizeof == short.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 2 Byte CAS\n            //////////////////////////////////////////////////////////////////\n\n            asm pure nothrow @nogc @trusted\n            {\n                mov DX, writeThis;\n                mov AX, ifThis;\n                mov RCX, here;\n                lock; // lock always needed to make this op atomic\n                cmpxchg [RCX], DX;\n                setz AL;\n            }\n        }\n        else static if ( T.sizeof == int.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 4 Byte CAS\n            //////////////////////////////////////////////////////////////////\n\n            asm pure nothrow @nogc @trusted\n            {\n                mov EDX, writeThis;\n                mov EAX, ifThis;\n                mov RCX, here;\n                lock; // lock always needed to make this op atomic\n                cmpxchg [RCX], EDX;\n                setz AL;\n            }\n        }\n        else static if ( T.sizeof == long.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 8 Byte CAS on a 64-Bit Processor\n            //////////////////////////////////////////////////////////////////\n\n            asm pure nothrow @nogc @trusted\n            {\n                mov RDX, writeThis;\n                mov RAX, ifThis;\n                mov RCX, here;\n                lock; // lock always needed to make this op atomic\n                cmpxchg [RCX], RDX;\n                setz AL;\n            }\n        }\n        else static if ( T.sizeof == long.sizeof*2 && has128BitCAS)\n        {\n            //////////////////////////////////////////////////////////////////\n            // 16 Byte CAS on a 64-Bit Processor\n            //////////////////////////////////////////////////////////////////\n            version (Win64){\n                //Windows 64 calling convention uses different registers.\n                //DMD appears to reverse the register order.\n                asm pure nothrow @nogc @trusted\n                {\n                    push RDI;\n                    push RBX;\n                    mov R9, writeThis;\n                    mov R10, ifThis;\n                    mov R11, here;\n\n                    mov RDI, R9;\n                    mov RBX, [RDI];\n                    mov RCX, 8[RDI];\n\n                    mov RDI, R10;\n                    mov RAX, [RDI];\n                    mov RDX, 8[RDI];\n\n                    mov RDI, R11;\n                    lock;\n                    cmpxchg16b [RDI];\n                    setz AL;\n                    pop RBX;\n                    pop RDI;\n                }\n\n            }else{\n\n                asm pure nothrow @nogc @trusted\n                {\n                    push RDI;\n                    push RBX;\n                    lea RDI, writeThis;\n                    mov RBX, [RDI];\n                    mov RCX, 8[RDI];\n                    lea RDI, ifThis;\n                    mov RAX, [RDI];\n                    mov RDX, 8[RDI];\n                    mov RDI, here;\n                    lock; // lock always needed to make this op atomic\n                    cmpxchg16b [RDI];\n                    setz AL;\n                    pop RBX;\n                    pop RDI;\n                }\n            }\n        }\n        else\n        {\n            static assert( false, \"Invalid template type specified.\" );\n        }\n    }\n\n\n    enum MemoryOrder\n    {\n        raw,\n        acq,\n        rel,\n        seq,\n    }\n\n    deprecated(\"Please use MemoryOrder instead.\")\n    alias MemoryOrder msync;\n\n\n    private\n    {\n        // NOTE: x86 loads implicitly have acquire semantics so a memory\n        //       barrier is only necessary on releases.\n        template needsLoadBarrier( MemoryOrder ms )\n        {\n            enum bool needsLoadBarrier = ms == MemoryOrder.seq;\n        }\n\n\n        // NOTE: x86 stores implicitly have release semantics so a memory\n        //       barrier is only necessary on acquires.\n        template needsStoreBarrier( MemoryOrder ms )\n        {\n            enum bool needsStoreBarrier = ms == MemoryOrder.seq;\n        }\n    }\n\n\n    TailShared!T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)( ref const shared T val ) pure nothrow @nogc @safe\n    if (!__traits(isFloating, T))\n    {\n        static assert( ms != MemoryOrder.rel, \"invalid MemoryOrder for atomicLoad()\" );\n        static assert( __traits(isPOD, T), \"argument to atomicLoad() must be POD\" );\n\n        static if ( T.sizeof == byte.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 1 Byte Load\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsLoadBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov DL, 0;\n                    mov AL, 0;\n                    mov RCX, val;\n                    lock; // lock always needed to make this op atomic\n                    cmpxchg [RCX], DL;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov AL, [RAX];\n                }\n            }\n        }\n        else static if ( T.sizeof == short.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 2 Byte Load\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsLoadBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov DX, 0;\n                    mov AX, 0;\n                    mov RCX, val;\n                    lock; // lock always needed to make this op atomic\n                    cmpxchg [RCX], DX;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov AX, [RAX];\n                }\n            }\n        }\n        else static if ( T.sizeof == int.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 4 Byte Load\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsLoadBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov EDX, 0;\n                    mov EAX, 0;\n                    mov RCX, val;\n                    lock; // lock always needed to make this op atomic\n                    cmpxchg [RCX], EDX;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov EAX, [RAX];\n                }\n            }\n        }\n        else static if ( T.sizeof == long.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 8 Byte Load\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsLoadBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RDX, 0;\n                    mov RAX, 0;\n                    mov RCX, val;\n                    lock; // lock always needed to make this op atomic\n                    cmpxchg [RCX], RDX;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov RAX, [RAX];\n                }\n            }\n        }\n        else static if ( T.sizeof == long.sizeof*2 && has128BitCAS )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 16 Byte Load on a 64-Bit Processor\n            //////////////////////////////////////////////////////////////////\n            version (Win64){\n                size_t[2] retVal;\n                asm pure nothrow @nogc @trusted\n                {\n                    push RDI;\n                    push RBX;\n                    mov RDI, val;\n                    mov RBX, 0;\n                    mov RCX, 0;\n                    mov RAX, 0;\n                    mov RDX, 0;\n                    lock; // lock always needed to make this op atomic\n                    cmpxchg16b [RDI];\n                    lea RDI, retVal;\n                    mov [RDI], RAX;\n                    mov 8[RDI], RDX;\n                    pop RBX;\n                    pop RDI;\n                }\n\n                static if (is(T:U[], U))\n                {\n                    pragma(inline, true)\n                    static typeof(return) toTrusted(size_t[2] retVal) @trusted\n                    {\n                        return *(cast(typeof(return)*) retVal.ptr);\n                    }\n\n                    return toTrusted(retVal);\n                }\n                else\n                {\n                    return cast(typeof(return)) retVal;\n                }\n            }else{\n                asm pure nothrow @nogc @trusted\n                {\n                    push RDI;\n                    push RBX;\n                    mov RBX, 0;\n                    mov RCX, 0;\n                    mov RAX, 0;\n                    mov RDX, 0;\n                    mov RDI, val;\n                    lock; // lock always needed to make this op atomic\n                    cmpxchg16b [RDI];\n                    pop RBX;\n                    pop RDI;\n                }\n            }\n        }\n        else\n        {\n            static assert( false, \"Invalid template type specified.\" );\n        }\n    }\n\n\n    void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V1)( ref shared T val, V1 newval ) pure nothrow @nogc @safe\n        if ( __traits( compiles, { val = newval; } ) )\n    {\n        static assert( ms != MemoryOrder.acq, \"invalid MemoryOrder for atomicStore()\" );\n        static assert( __traits(isPOD, T), \"argument to atomicStore() must be POD\" );\n\n        static if ( T.sizeof == byte.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 1 Byte Store\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsStoreBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov DL, newval;\n                    lock;\n                    xchg [RAX], DL;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov DL, newval;\n                    mov [RAX], DL;\n                }\n            }\n        }\n        else static if ( T.sizeof == short.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 2 Byte Store\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsStoreBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov DX, newval;\n                    lock;\n                    xchg [RAX], DX;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov DX, newval;\n                    mov [RAX], DX;\n                }\n            }\n        }\n        else static if ( T.sizeof == int.sizeof )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 4 Byte Store\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsStoreBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov EDX, newval;\n                    lock;\n                    xchg [RAX], EDX;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov EDX, newval;\n                    mov [RAX], EDX;\n                }\n            }\n        }\n        else static if ( T.sizeof == long.sizeof && has64BitCAS )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 8 Byte Store on a 64-Bit Processor\n            //////////////////////////////////////////////////////////////////\n\n            static if ( needsStoreBarrier!(ms) )\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov RDX, newval;\n                    lock;\n                    xchg [RAX], RDX;\n                }\n            }\n            else\n            {\n                asm pure nothrow @nogc @trusted\n                {\n                    mov RAX, val;\n                    mov RDX, newval;\n                    mov [RAX], RDX;\n                }\n            }\n        }\n        else static if ( T.sizeof == long.sizeof*2 && has128BitCAS )\n        {\n            //////////////////////////////////////////////////////////////////\n            // 16 Byte Store on a 64-Bit Processor\n            //////////////////////////////////////////////////////////////////\n            version (Win64){\n                asm pure nothrow @nogc @trusted\n                {\n                    push RDI;\n                    push RBX;\n                    mov R9, val;\n                    mov R10, newval;\n\n                    mov RDI, R10;\n                    mov RBX, [RDI];\n                    mov RCX, 8[RDI];\n\n                    mov RDI, R9;\n                    mov RAX, [RDI];\n                    mov RDX, 8[RDI];\n\n                    L1: lock; // lock always needed to make this op atomic\n                    cmpxchg16b [RDI];\n                    jne L1;\n                    pop RBX;\n                    pop RDI;\n                }\n            }else{\n                asm pure nothrow @nogc @trusted\n                {\n                    push RDI;\n                    push RBX;\n                    lea RDI, newval;\n                    mov RBX, [RDI];\n                    mov RCX, 8[RDI];\n                    mov RDI, val;\n                    mov RAX, [RDI];\n                    mov RDX, 8[RDI];\n                    L1: lock; // lock always needed to make this op atomic\n                    cmpxchg16b [RDI];\n                    jne L1;\n                    pop RBX;\n                    pop RDI;\n                }\n            }\n        }\n        else\n        {\n            static assert( false, \"Invalid template type specified.\" );\n        }\n    }\n\n\n    void atomicFence() nothrow @nogc @safe\n    {\n        // SSE2 is always present in 64-bit x86 chips.\n        asm nothrow @nogc @trusted\n        {\n            naked;\n\n            mfence;\n            ret;\n        }\n    }\n}\nelse version (GNU)\n{\n    import gcc.builtins;\n\n    TailShared!T atomicOp(string op, T, V1)(ref shared T val, V1 mod) pure nothrow @nogc @trusted\n        if (__traits(compiles, mixin(\"*cast(T*)&val\" ~ op ~ \"mod\")))\n    {\n        // binary operators\n        //\n        // +    -   *   /   %   ^^  &\n        // |    ^   <<  >>  >>> ~   in\n        // ==   !=  <   <=  >   >=\n        static if (op == \"+\"  || op == \"-\"  || op == \"*\"  || op == \"/\"   ||\n                   op == \"%\"  || op == \"^^\" || op == \"&\"  || op == \"|\"   ||\n                   op == \"^\"  || op == \"<<\" || op == \">>\" || op == \">>>\" ||\n                   op == \"~\"  || // skip \"in\"\n                   op == \"==\" || op == \"!=\" || op == \"<\"  || op == \"<=\"  ||\n                   op == \">\"  || op == \">=\")\n        {\n            TailShared!T get = atomicLoad!(MemoryOrder.raw)(val);\n            mixin(\"return get \" ~ op ~ \" mod;\");\n        }\n        else\n        // assignment operators\n        //\n        // +=   -=  *=  /=  %=  ^^= &=\n        // |=   ^=  <<= >>= >>>=    ~=\n        static if (op == \"+=\" || op == \"-=\"  || op == \"*=\"  || op == \"/=\" ||\n                   op == \"%=\" || op == \"^^=\" || op == \"&=\"  || op == \"|=\" ||\n                   op == \"^=\" || op == \"<<=\" || op == \">>=\" || op == \">>>=\") // skip \"~=\"\n        {\n            TailShared!T get, set;\n\n            do\n            {\n                get = set = atomicLoad!(MemoryOrder.raw)(val);\n                mixin(\"set \" ~ op ~ \" mod;\");\n            } while (!cas(&val, get, set));\n            return set;\n        }\n        else\n        {\n            static assert(false, \"Operation not supported.\");\n        }\n    }\n\n\n    bool cas(T,V1,V2)(shared(T)* here, const V1 ifThis, V2 writeThis) pure nothrow @nogc @safe\n        if (!is(T == class) && !is(T U : U*) && __traits(compiles, { *here = writeThis; }))\n    {\n        return casImpl(here, ifThis, writeThis);\n    }\n\n    bool cas(T,V1,V2)(shared(T)* here, const shared(V1) ifThis, shared(V2) writeThis) pure nothrow @nogc @safe\n        if (is(T == class) && __traits(compiles, { *here = writeThis; }))\n    {\n        return casImpl(here, ifThis, writeThis);\n    }\n\n    bool cas(T,V1,V2)(shared(T)* here, const shared(V1)* ifThis, shared(V2)* writeThis) pure nothrow @nogc @safe\n        if (is(T U : U*) && __traits(compiles, { *here = writeThis; }))\n    {\n        return casImpl(here, ifThis, writeThis);\n    }\n\n    private bool casImpl(T,V1,V2)(shared(T)* here, V1 ifThis, V2 writeThis) pure nothrow @nogc @trusted\n    {\n        static assert(GNU_Have_Atomics, \"cas() not supported on this architecture\");\n        bool res = void;\n\n        static if (T.sizeof == byte.sizeof)\n        {\n            res = __atomic_compare_exchange_1(here, cast(void*) &ifThis, *cast(ubyte*) &writeThis,\n                                              false, MemoryOrder.seq, MemoryOrder.seq);\n        }\n        else static if (T.sizeof == short.sizeof)\n        {\n            res = __atomic_compare_exchange_2(here, cast(void*) &ifThis, *cast(ushort*) &writeThis,\n                                              false, MemoryOrder.seq, MemoryOrder.seq);\n        }\n        else static if (T.sizeof == int.sizeof)\n        {\n            res = __atomic_compare_exchange_4(here, cast(void*) &ifThis, *cast(uint*) &writeThis,\n                                              false, MemoryOrder.seq, MemoryOrder.seq);\n        }\n        else static if (T.sizeof == long.sizeof && GNU_Have_64Bit_Atomics)\n        {\n            res = __atomic_compare_exchange_8(here, cast(void*) &ifThis, *cast(ulong*) &writeThis,\n                                              false, MemoryOrder.seq, MemoryOrder.seq);\n        }\n        else static if (GNU_Have_LibAtomic)\n        {\n            res = __atomic_compare_exchange(T.sizeof, here, cast(void*) &ifThis, cast(void*) &writeThis,\n                                            MemoryOrder.seq, MemoryOrder.seq);\n        }\n        else\n            static assert(0, \"Invalid template type specified.\");\n\n        return res;\n    }\n\n\n    // Memory model types for the __atomic* builtins.\n    enum MemoryOrder\n    {\n        raw = 0,\n        acq = 2,\n        rel = 3,\n        seq = 5,\n    }\n\n    deprecated(\"Please use MemoryOrder instead.\")\n    alias MemoryOrder msync;\n\n\n    TailShared!T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(ref const shared T val) pure nothrow @nogc @trusted\n    if (!__traits(isFloating, T))\n    {\n        static assert(ms != MemoryOrder.rel, \"Invalid MemoryOrder for atomicLoad\");\n        static assert(__traits(isPOD, T), \"argument to atomicLoad() must be POD\");\n        static assert(GNU_Have_Atomics, \"atomicLoad() not supported on this architecture\");\n\n        static if (T.sizeof == ubyte.sizeof)\n        {\n            ubyte value = __atomic_load_1(&val, ms);\n            return *cast(TailShared!T*) &value;\n        }\n        else static if (T.sizeof == ushort.sizeof)\n        {\n            ushort value = __atomic_load_2(&val, ms);\n            return *cast(TailShared!T*) &value;\n        }\n        else static if (T.sizeof == uint.sizeof)\n        {\n            uint value = __atomic_load_4(&val, ms);\n            return *cast(TailShared!T*) &value;\n        }\n        else static if (T.sizeof == ulong.sizeof && GNU_Have_64Bit_Atomics)\n        {\n            ulong value = __atomic_load_8(&val, ms);\n            return *cast(TailShared!T*) &value;\n        }\n        else static if (GNU_Have_LibAtomic)\n        {\n            T value;\n            __atomic_load(T.sizeof, &val, cast(void*)&value, ms);\n            return *cast(TailShared!T*) &value;\n        }\n        else\n            static assert(0, \"Invalid template type specified.\");\n    }\n\n\n    void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V1)(ref shared T val, V1 newval) pure nothrow @nogc @trusted\n        if (__traits(compiles, { val = newval; }))\n    {\n        static assert(ms != MemoryOrder.acq, \"Invalid MemoryOrder for atomicStore\");\n        static assert(__traits(isPOD, T), \"argument to atomicLoad() must be POD\");\n        static assert(GNU_Have_Atomics, \"atomicStore() not supported on this architecture\");\n\n        static if (T.sizeof == ubyte.sizeof)\n        {\n            __atomic_store_1(&val, *cast(ubyte*) &newval, ms);\n        }\n        else static if (T.sizeof == ushort.sizeof)\n        {\n            __atomic_store_2(&val, *cast(ushort*) &newval, ms);\n        }\n        else static if (T.sizeof == uint.sizeof)\n        {\n            __atomic_store_4(&val, *cast(uint*) &newval, ms);\n        }\n        else static if (T.sizeof == ulong.sizeof && GNU_Have_64Bit_Atomics)\n        {\n            __atomic_store_8(&val, *cast(ulong*) &newval, ms);\n        }\n        else static if (GNU_Have_LibAtomic)\n        {\n            __atomic_store(T.sizeof, &val, cast(void*)&newval, ms);\n        }\n        else\n            static assert(0, \"Invalid template type specified.\");\n    }\n\n\n    void atomicFence() nothrow @nogc\n    {\n        __atomic_thread_fence(MemoryOrder.seq);\n    }\n}\n\n// This is an ABI adapter that works on all architectures.  It type puns\n// floats and doubles to ints and longs, atomically loads them, then puns\n// them back.  This is necessary so that they get returned in floating\n// point instead of integer registers.\nTailShared!T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)( ref const shared T val ) pure nothrow @nogc @trusted\nif (__traits(isFloating, T))\n{\n    static if (T.sizeof == int.sizeof)\n    {\n        static assert(is(T : float));\n        auto ptr = cast(const shared int*) &val;\n        auto asInt = atomicLoad!(ms)(*ptr);\n        return *(cast(typeof(return)*) &asInt);\n    }\n    else static if (T.sizeof == long.sizeof)\n    {\n        static assert(is(T : double));\n        auto ptr = cast(const shared long*) &val;\n        auto asLong = atomicLoad!(ms)(*ptr);\n        return *(cast(typeof(return)*) &asLong);\n    }\n    else\n    {\n        static assert(0, \"Cannot atomically load 80-bit reals.\");\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Unit Tests\n////////////////////////////////////////////////////////////////////////////////\n\n\nversion (unittest)\n{\n    void testCAS(T)( T val ) pure nothrow @nogc @trusted\n    in\n    {\n        assert(val !is T.init);\n    }\n    do\n    {\n        T         base = cast(T)null;\n        shared(T) atom = cast(shared(T))null;\n\n        assert( base !is val, T.stringof );\n        assert( atom is base, T.stringof );\n\n        assert( cas( &atom, base, val ), T.stringof );\n        assert( atom is val, T.stringof );\n        assert( !cas( &atom, base, base ), T.stringof );\n        assert( atom is val, T.stringof );\n    }\n\n    void testLoadStore(MemoryOrder ms = MemoryOrder.seq, T)( T val = T.init + 1 ) pure nothrow @nogc @trusted\n    {\n        T         base = cast(T) 0;\n        shared(T) atom = cast(T) 0;\n\n        assert( base !is val );\n        assert( atom is base );\n        atomicStore!(ms)( atom, val );\n        base = atomicLoad!(ms)( atom );\n\n        assert( base is val, T.stringof );\n        assert( atom is val );\n    }\n\n\n    void testType(T)( T val = T.init + 1 ) pure nothrow @nogc @safe\n    {\n        testCAS!(T)( val );\n        testLoadStore!(MemoryOrder.seq, T)( val );\n        testLoadStore!(MemoryOrder.raw, T)( val );\n    }\n\n    @safe pure nothrow unittest\n    {\n        testType!(bool)();\n\n        testType!(byte)();\n        testType!(ubyte)();\n\n        testType!(short)();\n        testType!(ushort)();\n\n        testType!(int)();\n        testType!(uint)();\n\n        testType!(shared int*)();\n\n        static class Klass {}\n        testCAS!(shared Klass)( new shared(Klass) );\n\n        testType!(float)(1.0f);\n\n        static if ( has64BitCAS )\n        {\n            testType!(double)(1.0);\n            testType!(long)();\n            testType!(ulong)();\n        }\n\n        shared(size_t) i;\n\n        atomicOp!\"+=\"( i, cast(size_t) 1 );\n        assert( i == 1 );\n\n        atomicOp!\"-=\"( i, cast(size_t) 1 );\n        assert( i == 0 );\n\n        shared float f = 0;\n        atomicOp!\"+=\"( f, 1 );\n        assert( f == 1 );\n\n        static if ( has64BitCAS )\n        {\n            shared double d = 0;\n            atomicOp!\"+=\"( d, 1 );\n            assert( d == 1 );\n        }\n    }\n\n    pure nothrow unittest\n    {\n        static if (has128BitCAS)\n        {\n            struct DoubleValue\n            {\n                long value1;\n                long value2;\n            }\n\n            align(16) shared DoubleValue a;\n            atomicStore(a, DoubleValue(1,2));\n            assert(a.value1 == 1 && a.value2 ==2);\n\n            while (!cas(&a, DoubleValue(1,2), DoubleValue(3,4))){}\n            assert(a.value1 == 3 && a.value2 ==4);\n\n            align(16) DoubleValue b = atomicLoad(a);\n            assert(b.value1 == 3 && b.value2 ==4);\n        }\n\n        version (D_LP64)\n        {\n            enum hasDWCAS = has128BitCAS;\n        }\n        else\n        {\n            enum hasDWCAS = has64BitCAS;\n        }\n\n        static if (hasDWCAS)\n        {\n            static struct List { size_t gen; List* next; }\n            shared(List) head;\n            assert(cas(&head, shared(List)(0, null), shared(List)(1, cast(List*)1)));\n            assert(head.gen == 1);\n            assert(cast(size_t)head.next == 1);\n        }\n    }\n\n    pure nothrow unittest\n    {\n        static struct S { int val; }\n        auto s = shared(S)(1);\n\n        shared(S*) ptr;\n\n        // head unshared\n        shared(S)* ifThis = null;\n        shared(S)* writeThis = &s;\n        assert(ptr is null);\n        assert(cas(&ptr, ifThis, writeThis));\n        assert(ptr is writeThis);\n\n        // head shared\n        shared(S*) ifThis2 = writeThis;\n        shared(S*) writeThis2 = null;\n        assert(cas(&ptr, ifThis2, writeThis2));\n        assert(ptr is null);\n\n        // head unshared target doesn't want atomic CAS\n        shared(S)* ptr2;\n        static assert(!__traits(compiles, cas(&ptr2, ifThis, writeThis)));\n        static assert(!__traits(compiles, cas(&ptr2, ifThis2, writeThis2)));\n    }\n\n    unittest\n    {\n        import core.thread;\n\n        // Use heap memory to ensure an optimizing\n        // compiler doesn't put things in registers.\n        uint* x = new uint();\n        bool* f = new bool();\n        uint* r = new uint();\n\n        auto thr = new Thread(()\n        {\n            while (!*f)\n            {\n            }\n\n            atomicFence();\n\n            *r = *x;\n        });\n\n        thr.start();\n\n        *x = 42;\n\n        atomicFence();\n\n        *f = true;\n\n        atomicFence();\n\n        thr.join();\n\n        assert(*r == 42);\n    }\n\n    // === atomicFetchAdd and atomicFetchSub operations ====\n    pure nothrow @nogc @safe unittest\n    {\n        shared ubyte u8 = 1;\n        shared ushort u16 = 2;\n        shared uint u32 = 3;\n        shared byte i8 = 5;\n        shared short i16 = 6;\n        shared int i32 = 7;\n\n        assert(atomicOp!\"+=\"(u8, 8) == 9);\n        assert(atomicOp!\"+=\"(u16, 8) == 10);\n        assert(atomicOp!\"+=\"(u32, 8) == 11);\n        assert(atomicOp!\"+=\"(i8, 8) == 13);\n        assert(atomicOp!\"+=\"(i16, 8) == 14);\n        assert(atomicOp!\"+=\"(i32, 8) == 15);\n        version (AsmX86_64)\n        {\n            shared ulong u64 = 4;\n            shared long i64 = 8;\n            assert(atomicOp!\"+=\"(u64, 8) == 12);\n            assert(atomicOp!\"+=\"(i64, 8) == 16);\n        }\n    }\n\n    pure nothrow @nogc @safe unittest\n    {\n        shared ubyte u8 = 1;\n        shared ushort u16 = 2;\n        shared uint u32 = 3;\n        shared byte i8 = 5;\n        shared short i16 = 6;\n        shared int i32 = 7;\n\n        assert(atomicOp!\"-=\"(u8, 1) == 0);\n        assert(atomicOp!\"-=\"(u16, 1) == 1);\n        assert(atomicOp!\"-=\"(u32, 1) == 2);\n        assert(atomicOp!\"-=\"(i8, 1) == 4);\n        assert(atomicOp!\"-=\"(i16, 1) == 5);\n        assert(atomicOp!\"-=\"(i32, 1) == 6);\n        version (AsmX86_64)\n        {\n            shared ulong u64 = 4;\n            shared long i64 = 8;\n            assert(atomicOp!\"-=\"(u64, 1) == 3);\n            assert(atomicOp!\"-=\"(i64, 1) == 7);\n        }\n    }\n\n    pure nothrow @nogc @safe unittest // issue 16651\n    {\n        shared ulong a = 2;\n        uint b = 1;\n        atomicOp!\"-=\"( a, b );\n        assert(a == 1);\n\n        shared uint c = 2;\n        ubyte d = 1;\n        atomicOp!\"-=\"( c, d );\n        assert(c == 1);\n    }\n\n    pure nothrow @safe unittest // issue 16230\n    {\n        shared int i;\n        static assert(is(typeof(atomicLoad(i)) == int));\n\n        shared int* p;\n        static assert(is(typeof(atomicLoad(p)) == shared(int)*));\n\n        shared int[] a;\n        static if (__traits(compiles, atomicLoad(a)))\n        {\n            static assert(is(typeof(atomicLoad(a)) == shared(int)[]));\n        }\n\n        static struct S { int* _impl; }\n        shared S s;\n        static assert(is(typeof(atomicLoad(s)) : shared S));\n        static assert(is(typeof(atomicLoad(s)._impl) == shared(int)*));\n        auto u = atomicLoad(s);\n        assert(u._impl is null);\n        u._impl = new shared int(42);\n        assert(atomicLoad(*u._impl) == 42);\n\n        static struct S2 { S s; }\n        shared S2 s2;\n        static assert(is(typeof(atomicLoad(s2).s) == TailShared!S));\n\n        static struct S3 { size_t head; int* tail; }\n        shared S3 s3;\n        static if (__traits(compiles, atomicLoad(s3)))\n        {\n            static assert(is(typeof(atomicLoad(s3).head) == size_t));\n            static assert(is(typeof(atomicLoad(s3).tail) == shared(int)*));\n        }\n\n        static class C { int i; }\n        shared C c;\n        static assert(is(typeof(atomicLoad(c)) == shared C));\n\n        static struct NoIndirections { int i; }\n        shared NoIndirections n;\n        static assert(is(typeof(atomicLoad(n)) == NoIndirections));\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/attribute.d",
    "content": "/**\n * This module contains UDA's (User Defined Attributes) either used in\n * the runtime or special UDA's recognized by compiler.\n *\n * Copyright: Copyright Jacob Carlborg 2015.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Jacob Carlborg\n * Source:    $(DRUNTIMESRC core/_attribute.d)\n */\n\n/*          Copyright Jacob Carlborg 2015.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.attribute;\n\n/**\n * Use this attribute to attach an Objective-C selector to a method.\n *\n * This is a special compiler recognized attribute, it has several\n * requirements, which all will be enforced by the compiler:\n *\n * $(UL\n *  $(LI\n *      The attribute can only be attached to methods or constructors which\n *      have Objective-C linkage. That is, a method or a constructor in a\n *      class or interface declared as $(D_CODE extern(Objective-C)).\n *  ),\n *\n *  $(LI It cannot be attached to a method or constructor that is a template),\n *\n *  $(LI\n *      The number of colons in the string need to match the number of\n *      arguments the method accept.\n *  ),\n *\n *  $(LI It can only be used once in a method declaration)\n * )\n *\n * Examples:\n * ---\n * extern (Objective-C)\n * class NSObject\n * {\n *  this() @selector(\"init\");\n *  static NSObject alloc() @selector(\"alloc\");\n *  NSObject initWithUTF8String(in char* str) @selector(\"initWithUTF8String:\");\n *  ObjcObject copyScriptingValue(ObjcObject value, NSString key, NSDictionary properties)\n *      @selector(\"copyScriptingValue:forKey:withProperties:\");\n * }\n * ---\n */\nversion (D_ObjectiveC) struct selector\n{\n    string selector;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/bitop.d",
    "content": "/**\n * This module contains a collection of bit-level operations.\n *\n * Copyright: Copyright Don Clugston 2005 - 2013.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Don Clugston, Sean Kelly, Walter Bright, Alex Rønne Petersen, Thomas Stuart Bockman\n * Source:    $(DRUNTIMESRC core/_bitop.d)\n */\n\nmodule core.bitop;\n\nnothrow:\n@safe:\n@nogc:\n\nversion (D_InlineAsm_X86_64)\n    version = AsmX86;\nelse version (D_InlineAsm_X86)\n    version = AsmX86;\n\nversion (X86_64)\n    version = AnyX86;\nelse version (X86)\n    version = AnyX86;\n\n// Use to implement 64-bit bitops on 32-bit arch.\nprivate union Split64\n{\n    ulong u64;\n    struct\n    {\n        version (LittleEndian)\n        {\n            uint lo;\n            uint hi;\n        }\n        else\n        {\n            uint hi;\n            uint lo;\n        }\n    }\n\n    pragma(inline, true)\n    this(ulong u64) @safe pure nothrow @nogc\n    {\n        if (__ctfe)\n        {\n            lo = cast(uint) u64;\n            hi = cast(uint) (u64 >>> 32);\n        }\n        else\n            this.u64 = u64;\n    }\n}\n\nunittest\n{\n    const rt = Split64(1);\n    assert((rt.lo == 1) && (rt.hi == 0));\n\n    enum ct = Split64(1);\n    assert((ct.lo == rt.lo) && (ct.hi == rt.hi));\n}\n\n/**\n * Scans the bits in v starting with bit 0, looking\n * for the first set bit.\n * Returns:\n *      The bit number of the first bit set.\n *      The return value is undefined if v is zero.\n */\nint bsf(uint v) pure\n{\n    pragma(inline, false);  // so intrinsic detection will work\n    return softBsf!uint(v);\n}\n\n/// ditto\nint bsf(ulong v) pure\n{\n    static if (size_t.sizeof == ulong.sizeof)  // 64 bit code gen\n    {\n        pragma(inline, false);   // so intrinsic detection will work\n        return softBsf!ulong(v);\n    }\n    else\n    {\n        /* intrinsic not available for 32 bit code,\n         * make do with 32 bit bsf\n         */\n        const sv = Split64(v);\n        return (sv.lo == 0)?\n            bsf(sv.hi) + 32 :\n            bsf(sv.lo);\n    }\n}\n\n///\nunittest\n{\n    assert(bsf(0x21) == 0);\n    assert(bsf(ulong.max << 39) == 39);\n}\n\nunittest\n{\n    // Make sure bsf() is available at CTFE\n    enum test_ctfe = bsf(ulong.max);\n    assert(test_ctfe == 0);\n}\n\n/**\n * Scans the bits in v from the most significant bit\n * to the least significant bit, looking\n * for the first set bit.\n * Returns:\n *      The bit number of the first bit set.\n *      The return value is undefined if v is zero.\n */\nint bsr(uint v) pure\n{\n    pragma(inline, false);  // so intrinsic detection will work\n    return softBsr!uint(v);\n}\n\n/// ditto\nint bsr(ulong v) pure\n{\n    static if (size_t.sizeof == ulong.sizeof)  // 64 bit code gen\n    {\n        pragma(inline, false);   // so intrinsic detection will work\n        return softBsr!ulong(v);\n    }\n    else\n    {\n        /* intrinsic not available for 32 bit code,\n         * make do with 32 bit bsr\n         */\n        const sv = Split64(v);\n        return (sv.hi == 0)?\n            bsr(sv.lo) :\n            bsr(sv.hi) + 32;\n    }\n}\n\n///\nunittest\n{\n    assert(bsr(0x21) == 5);\n    assert(bsr((ulong.max >> 15) - 1) == 48);\n}\n\nunittest\n{\n    // Make sure bsr() is available at CTFE\n    enum test_ctfe = bsr(ulong.max);\n    assert(test_ctfe == 63);\n}\n\nprivate alias softBsf(N) = softScan!(N, true);\nprivate alias softBsr(N) = softScan!(N, false);\n\n/* Shared software fallback implementation for bit scan foward and reverse.\n\nIf forward is true, bsf is computed (the index of the first set bit).\nIf forward is false, bsr is computed (the index of the last set bit).\n\n-1 is returned if no bits are set (v == 0).\n*/\nprivate int softScan(N, bool forward)(N v) pure\n    if (is(N == uint) || is(N == ulong))\n{\n    // bsf() and bsr() are officially undefined for v == 0.\n    if (!v)\n        return -1;\n\n    // This is essentially an unrolled binary search:\n    enum mask(ulong lo) = forward ? cast(N) lo : cast(N)~lo;\n    enum inc(int up) = forward ? up : -up;\n\n    N x;\n    int ret;\n    static if (is(N == ulong))\n    {\n        x = v & mask!0x0000_0000_FFFF_FFFFL;\n        if (x)\n        {\n            v = x;\n            ret = forward ? 0 : 63;\n        }\n        else\n            ret = forward ? 32 : 31;\n\n        x = v & mask!0x0000_FFFF_0000_FFFFL;\n        if (x)\n            v = x;\n        else\n            ret += inc!16;\n    }\n    else static if (is(N == uint))\n    {\n        x = v & mask!0x0000_FFFF;\n        if (x)\n        {\n            v = x;\n            ret = forward ? 0 : 31;\n        }\n        else\n            ret = forward ? 16 : 15;\n    }\n    else\n        static assert(false);\n\n    x = v & mask!0x00FF_00FF_00FF_00FFL;\n    if (x)\n        v = x;\n    else\n        ret += inc!8;\n\n    x = v & mask!0x0F0F_0F0F_0F0F_0F0FL;\n    if (x)\n        v = x;\n    else\n        ret += inc!4;\n\n    x = v & mask!0x3333_3333_3333_3333L;\n    if (x)\n        v = x;\n    else\n        ret += inc!2;\n\n    x = v & mask!0x5555_5555_5555_5555L;\n    if (!x)\n        ret += inc!1;\n\n    return ret;\n}\n\nunittest\n{\n    assert(softBsf!uint(0u) == -1);\n    assert(softBsr!uint(0u) == -1);\n    assert(softBsf!ulong(0uL) == -1);\n    assert(softBsr!ulong(0uL) == -1);\n\n    assert(softBsf!uint(0x0031_A000) == 13);\n    assert(softBsr!uint(0x0031_A000) == 21);\n    assert(softBsf!ulong(0x0000_0001_8000_0000L) == 31);\n    assert(softBsr!ulong(0x0000_0001_8000_0000L) == 32);\n\n    foreach (b; 0 .. 64)\n    {\n        if (b < 32)\n        {\n            assert(softBsf!uint(1u << b) == b);\n            assert(softBsr!uint(1u << b) == b);\n        }\n\n        assert(softBsf!ulong(1uL << b) == b);\n        assert(softBsr!ulong(1uL << b) == b);\n    }\n}\n\n/**\n * Tests the bit.\n * (No longer an intrisic - the compiler recognizes the patterns\n * in the body.)\n */\nint bt(in size_t* p, size_t bitnum) pure @system\n{\n    static if (size_t.sizeof == 8)\n        return ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0;\n    else static if (size_t.sizeof == 4)\n        return ((p[bitnum >> 5] & (1  << (bitnum & 31)))) != 0;\n    else\n        static assert(0);\n}\n///\n@system pure unittest\n{\n    size_t[2] array;\n\n    array[0] = 2;\n    array[1] = 0x100;\n\n    assert(bt(array.ptr, 1));\n    assert(array[0] == 2);\n    assert(array[1] == 0x100);\n}\n\n/**\n * Tests and complements the bit.\n */\nint btc(size_t* p, size_t bitnum) pure @system;\n\n\n/**\n * Tests and resets (sets to 0) the bit.\n */\nint btr(size_t* p, size_t bitnum) pure @system;\n\n\n/**\n * Tests and sets the bit.\n * Params:\n * p = a non-NULL pointer to an array of size_ts.\n * bitnum = a bit number, starting with bit 0 of p[0],\n * and progressing. It addresses bits like the expression:\n---\np[index / (size_t.sizeof*8)] & (1 << (index & ((size_t.sizeof*8) - 1)))\n---\n * Returns:\n *      A non-zero value if the bit was set, and a zero\n *      if it was clear.\n */\nint bts(size_t* p, size_t bitnum) pure @system;\n\n///\n@system pure unittest\n{\n    size_t[2] array;\n\n    array[0] = 2;\n    array[1] = 0x100;\n\n    assert(btc(array.ptr, 35) == 0);\n    if (size_t.sizeof == 8)\n    {\n        assert(array[0] == 0x8_0000_0002);\n        assert(array[1] == 0x100);\n    }\n    else\n    {\n        assert(array[0] == 2);\n        assert(array[1] == 0x108);\n    }\n\n    assert(btc(array.ptr, 35));\n    assert(array[0] == 2);\n    assert(array[1] == 0x100);\n\n    assert(bts(array.ptr, 35) == 0);\n    if (size_t.sizeof == 8)\n    {\n        assert(array[0] == 0x8_0000_0002);\n        assert(array[1] == 0x100);\n    }\n    else\n    {\n        assert(array[0] == 2);\n        assert(array[1] == 0x108);\n    }\n\n    assert(btr(array.ptr, 35));\n    assert(array[0] == 2);\n    assert(array[1] == 0x100);\n}\n\n/**\n * Range over bit set. Each element is the bit number that is set.\n *\n * This is more efficient than testing each bit in a sparsely populated bit\n * set. Note that the first bit in the bit set would be bit 0.\n */\nstruct BitRange\n{\n    /// Number of bits in each size_t\n    enum bitsPerWord = size_t.sizeof * 8;\n\n    private\n    {\n        const(size_t)*bits; // points at next word of bits to check\n        size_t cur; // needed to allow searching bits using bsf\n        size_t idx; // index of current set bit\n        size_t len; // number of bits in the bit set.\n    }\n    @nogc nothrow pure:\n\n    /**\n     * Construct a BitRange.\n     *\n     * Params:\n     *   bitarr = The array of bits to iterate over\n     *   numBits = The total number of valid bits in the given bit array\n     */\n    this(const(size_t)* bitarr, size_t numBits) @system\n    {\n        bits = bitarr;\n        len = numBits;\n        if (len)\n        {\n            // prime the first bit\n            cur = *bits++ ^ 1;\n            popFront();\n        }\n    }\n\n    /// Range functions\n    size_t front()\n    {\n        assert(!empty);\n        return idx;\n    }\n\n    /// ditto\n    bool empty() const\n    {\n        return idx >= len;\n    }\n\n    /// ditto\n    void popFront() @system\n    {\n        // clear the current bit\n        auto curbit = idx % bitsPerWord;\n        cur ^= size_t(1) << curbit;\n        if (!cur)\n        {\n            // find next size_t with set bit\n            idx -= curbit;\n            while (!cur)\n            {\n                if ((idx += bitsPerWord) >= len)\n                    // now empty\n                    return;\n                cur = *bits++;\n            }\n            idx += bsf(cur);\n        }\n        else\n        {\n            idx += bsf(cur) - curbit;\n        }\n    }\n}\n\n///\n@system unittest\n{\n    import core.stdc.stdlib : malloc, free;\n    import core.stdc.string : memset;\n\n    // initialize a bit array\n    enum nBytes = (100 + BitRange.bitsPerWord - 1) / 8;\n    size_t *bitArr = cast(size_t *)malloc(nBytes);\n    scope(exit) free(bitArr);\n    memset(bitArr, 0, nBytes);\n\n    // set some bits\n    bts(bitArr, 48);\n    bts(bitArr, 24);\n    bts(bitArr, 95);\n    bts(bitArr, 78);\n\n    enum sum = 48 + 24 + 95 + 78;\n\n    // iterate\n    size_t testSum;\n    size_t nBits;\n    foreach (b; BitRange(bitArr, 100))\n    {\n        testSum += b;\n        ++nBits;\n    }\n\n    assert(testSum == sum);\n    assert(nBits == 4);\n}\n\n@system unittest\n{\n    void testIt(size_t numBits, size_t[] bitsToTest...)\n    {\n        import core.stdc.stdlib : malloc, free;\n        import core.stdc.string : memset;\n        immutable numBytes = (numBits + size_t.sizeof * 8 - 1) / 8;\n        size_t* bitArr = cast(size_t *)malloc(numBytes);\n        scope(exit) free(bitArr);\n        memset(bitArr, 0, numBytes);\n        foreach (b; bitsToTest)\n            bts(bitArr, b);\n        auto br = BitRange(bitArr, numBits);\n        foreach (b; bitsToTest)\n        {\n            assert(!br.empty);\n            assert(b == br.front);\n            br.popFront();\n        }\n        assert(br.empty);\n    }\n\n    testIt(100, 0, 1, 31, 63, 85);\n    testIt(100, 6, 45, 89, 92, 99);\n}\n\n/**\n * Swaps bytes in a 4 byte uint end-to-end, i.e. byte 0 becomes\n * byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3\n * becomes byte 0.\n */\nuint bswap(uint v) pure;\n\n/**\n * Swaps bytes in an 8 byte ulong end-to-end, i.e. byte 0 becomes\n * byte 7, byte 1 becomes byte 6, etc.\n */\nulong bswap(ulong v) pure\n{\n    auto sv = Split64(v);\n\n    const temp = sv.lo;\n    sv.lo = bswap(sv.hi);\n    sv.hi = bswap(temp);\n\n    return (cast(ulong) sv.hi << 32) | sv.lo;\n}\n\nversion (DigitalMars) version (AnyX86) @system // not pure\n{\n    /**\n     * Reads I/O port at port_address.\n     */\n    ubyte inp(uint port_address);\n\n\n    /**\n     * ditto\n     */\n    ushort inpw(uint port_address);\n\n\n    /**\n     * ditto\n     */\n    uint inpl(uint port_address);\n\n\n    /**\n     * Writes and returns value to I/O port at port_address.\n     */\n    ubyte outp(uint port_address, ubyte value);\n\n\n    /**\n     * ditto\n     */\n    ushort outpw(uint port_address, ushort value);\n\n\n    /**\n     * ditto\n     */\n    uint outpl(uint port_address, uint value);\n}\n\n\n/**\n *  Calculates the number of set bits in an integer.\n */\nint popcnt(uint x) pure\n{\n    // Select the fastest method depending on the compiler and CPU architecture\n    version (DigitalMars)\n    {\n        static if (is(typeof(_popcnt(uint.max))))\n        {\n            import core.cpuid;\n            if (!__ctfe && hasPopcnt)\n                return _popcnt(x);\n        }\n    }\n\n    return softPopcnt!uint(x);\n}\n\nunittest\n{\n    assert( popcnt( 0 ) == 0 );\n    assert( popcnt( 7 ) == 3 );\n    assert( popcnt( 0xAA )== 4 );\n    assert( popcnt( 0x8421_1248 ) == 8 );\n    assert( popcnt( 0xFFFF_FFFF ) == 32 );\n    assert( popcnt( 0xCCCC_CCCC ) == 16 );\n    assert( popcnt( 0x7777_7777 ) == 24 );\n\n    // Make sure popcnt() is available at CTFE\n    enum test_ctfe = popcnt(uint.max);\n    assert(test_ctfe == 32);\n}\n\n/// ditto\nint popcnt(ulong x) pure\n{\n    // Select the fastest method depending on the compiler and CPU architecture\n    import core.cpuid;\n\n    static if (size_t.sizeof == uint.sizeof)\n    {\n        const sx = Split64(x);\n        version (DigitalMars)\n        {\n            static if (is(typeof(_popcnt(uint.max))))\n            {\n                if (!__ctfe && hasPopcnt)\n                    return _popcnt(sx.lo) + _popcnt(sx.hi);\n            }\n        }\n\n        return softPopcnt!uint(sx.lo) + softPopcnt!uint(sx.hi);\n    }\n    else static if (size_t.sizeof == ulong.sizeof)\n    {\n        version (DigitalMars)\n        {\n            static if (is(typeof(_popcnt(ulong.max))))\n            {\n                if (!__ctfe && hasPopcnt)\n                    return _popcnt(x);\n            }\n        }\n\n        return softPopcnt!ulong(x);\n    }\n    else\n        static assert(false);\n}\n\nunittest\n{\n    assert(popcnt(0uL) == 0);\n    assert(popcnt(1uL) == 1);\n    assert(popcnt((1uL << 32) - 1) == 32);\n    assert(popcnt(0x48_65_6C_6C_6F_3F_21_00uL) == 28);\n    assert(popcnt(ulong.max) == 64);\n\n    // Make sure popcnt() is available at CTFE\n    enum test_ctfe = popcnt(ulong.max);\n    assert(test_ctfe == 64);\n}\n\nprivate int softPopcnt(N)(N x) pure\n    if (is(N == uint) || is(N == ulong))\n{\n    // Avoid branches, and the potential for cache misses which\n    // could be incurred with a table lookup.\n\n    // We need to mask alternate bits to prevent the\n    // sum from overflowing.\n    // add neighbouring bits. Each bit is 0 or 1.\n    enum mask1 = cast(N) 0x5555_5555_5555_5555L;\n    x = x - ((x>>1) & mask1);\n    // now each two bits of x is a number 00,01 or 10.\n    // now add neighbouring pairs\n    enum mask2a = cast(N) 0xCCCC_CCCC_CCCC_CCCCL;\n    enum mask2b = cast(N) 0x3333_3333_3333_3333L;\n    x = ((x & mask2a)>>2) + (x & mask2b);\n    // now each nibble holds 0000-0100. Adding them won't\n    // overflow any more, so we don't need to mask any more\n\n    enum mask4 = cast(N) 0x0F0F_0F0F_0F0F_0F0FL;\n    x = (x + (x >> 4)) & mask4;\n\n    enum shiftbits = is(N == uint)? 24 : 56;\n    enum maskMul = cast(N) 0x0101_0101_0101_0101L;\n    x = (x * maskMul) >> shiftbits;\n\n    return cast(int) x;\n}\n\nversion (DigitalMars) version (AnyX86)\n{\n    /**\n     * Calculates the number of set bits in an integer\n     * using the X86 SSE4 POPCNT instruction.\n     * POPCNT is not available on all X86 CPUs.\n     */\n    ushort _popcnt( ushort x ) pure;\n    /// ditto\n    int _popcnt( uint x ) pure;\n    version (X86_64)\n    {\n        /// ditto\n        int _popcnt( ulong x ) pure;\n    }\n\n    unittest\n    {\n        // Not everyone has SSE4 instructions\n        import core.cpuid;\n        if (!hasPopcnt)\n            return;\n\n        static int popcnt_x(ulong u) nothrow @nogc\n        {\n            int c;\n            while (u)\n            {\n                c += u & 1;\n                u >>= 1;\n            }\n            return c;\n        }\n\n        for (uint u = 0; u < 0x1_0000; ++u)\n        {\n            //writefln(\"%x %x %x\", u,   _popcnt(cast(ushort)u), popcnt_x(cast(ushort)u));\n            assert(_popcnt(cast(ushort)u) == popcnt_x(cast(ushort)u));\n\n            assert(_popcnt(cast(uint)u) == popcnt_x(cast(uint)u));\n            uint ui = u * 0x3_0001;\n            assert(_popcnt(ui) == popcnt_x(ui));\n\n            version (X86_64)\n            {\n                assert(_popcnt(cast(ulong)u) == popcnt_x(cast(ulong)u));\n                ulong ul = u * 0x3_0003_0001;\n                assert(_popcnt(ul) == popcnt_x(ul));\n            }\n        }\n    }\n}\n\n\n/*************************************\n * Read/write value from/to the memory location indicated by ptr.\n *\n * These functions are recognized by the compiler, and calls to them are guaranteed\n * to not be removed (as dead assignment elimination or presumed to have no effect)\n * or reordered in the same thread.\n *\n * These reordering guarantees are only made with regards to other\n * operations done through these functions; the compiler is free to reorder regular\n * loads/stores with regards to loads/stores done through these functions.\n *\n * This is useful when dealing with memory-mapped I/O (MMIO) where a store can\n * have an effect other than just writing a value, or where sequential loads\n * with no intervening stores can retrieve\n * different values from the same location due to external stores to the location.\n *\n * These functions will, when possible, do the load/store as a single operation. In\n * general, this is possible when the size of the operation is less than or equal to\n * $(D (void*).sizeof), although some targets may support larger operations. If the\n * load/store cannot be done as a single operation, multiple smaller operations will be used.\n *\n * These are not to be conflated with atomic operations. They do not guarantee any\n * atomicity. This may be provided by coincidence as a result of the instructions\n * used on the target, but this should not be relied on for portable programs.\n * Further, no memory fences are implied by these functions.\n * They should not be used for communication between threads.\n * They may be used to guarantee a write or read cycle occurs at a specified address.\n */\n\nubyte  volatileLoad(ubyte * ptr);\nushort volatileLoad(ushort* ptr);  /// ditto\nuint   volatileLoad(uint  * ptr);  /// ditto\nulong  volatileLoad(ulong * ptr);  /// ditto\n\nvoid volatileStore(ubyte * ptr, ubyte  value);   /// ditto\nvoid volatileStore(ushort* ptr, ushort value);   /// ditto\nvoid volatileStore(uint  * ptr, uint   value);   /// ditto\nvoid volatileStore(ulong * ptr, ulong  value);   /// ditto\n\n@system unittest\n{\n    alias TT(T...) = T;\n\n    foreach (T; TT!(ubyte, ushort, uint, ulong))\n    {\n        T u;\n        T* p = &u;\n        volatileStore(p, 1);\n        T r = volatileLoad(p);\n        assert(r == u);\n    }\n}\n\n\n/**\n * Reverses the order of bits in a 32-bit integer.\n */\npragma(inline, true)\nuint bitswap( uint x ) pure\n{\n    if (!__ctfe)\n    {\n        static if (is(typeof(asmBitswap32(x))))\n            return asmBitswap32(x);\n    }\n\n    return softBitswap!uint(x);\n}\n\nunittest\n{\n    static void test(alias impl)()\n    {\n        assert (impl( 0x8000_0100 ) == 0x0080_0001);\n        foreach (i; 0 .. 32)\n            assert (impl(1 << i) == 1 << 32 - i - 1);\n    }\n\n    test!(bitswap)();\n    test!(softBitswap!uint)();\n    static if (is(typeof(asmBitswap32(0u))))\n        test!(asmBitswap32)();\n\n    // Make sure bitswap() is available at CTFE\n    enum test_ctfe = bitswap(1U);\n    assert(test_ctfe == (1U << 31));\n}\n\n/**\n * Reverses the order of bits in a 64-bit integer.\n */\npragma(inline, true)\nulong bitswap ( ulong x ) pure\n{\n    if (!__ctfe)\n    {\n        static if (is(typeof(asmBitswap64(x))))\n            return asmBitswap64(x);\n    }\n\n    return softBitswap!ulong(x);\n}\n\nunittest\n{\n    static void test(alias impl)()\n    {\n        assert (impl( 0b1000000000000000000000010000000000000000100000000000000000000001)\n            == 0b1000000000000000000000010000000000000000100000000000000000000001);\n        assert (impl( 0b1110000000000000000000010000000000000000100000000000000000000001)\n            == 0b1000000000000000000000010000000000000000100000000000000000000111);\n        foreach (i; 0 .. 64)\n            assert (impl(1UL << i) == 1UL << 64 - i - 1);\n    }\n\n    test!(bitswap)();\n    test!(softBitswap!ulong)();\n    static if (is(typeof(asmBitswap64(0uL))))\n        test!(asmBitswap64)();\n\n    // Make sure bitswap() is available at CTFE\n    enum test_ctfe = bitswap(1UL);\n    assert(test_ctfe == (1UL << 63));\n}\n\nprivate N softBitswap(N)(N x) pure\n    if (is(N == uint) || is(N == ulong))\n{\n    // swap 1-bit pairs:\n    enum mask1 = cast(N) 0x5555_5555_5555_5555L;\n    x = ((x >> 1) & mask1) | ((x & mask1) << 1);\n    // swap 2-bit pairs:\n    enum mask2 = cast(N) 0x3333_3333_3333_3333L;\n    x = ((x >> 2) & mask2) | ((x & mask2) << 2);\n    // swap 4-bit pairs:\n    enum mask4 = cast(N) 0x0F0F_0F0F_0F0F_0F0FL;\n    x = ((x >> 4) & mask4) | ((x & mask4) << 4);\n\n    // reverse the order of all bytes:\n    x = bswap(x);\n\n    return x;\n}\n\nversion (AsmX86)\n{\n    private uint asmBitswap32(uint x) @trusted pure\n    {\n        asm pure nothrow @nogc { naked; }\n\n        version (D_InlineAsm_X86_64)\n        {\n            version (Win64)\n                asm pure nothrow @nogc { mov EAX, ECX; }\n            else\n                asm pure nothrow @nogc { mov EAX, EDI; }\n        }\n\n        asm pure nothrow @nogc\n        {\n            // Author: Tiago Gasiba.\n            mov EDX, EAX;\n            shr EAX, 1;\n            and EDX, 0x5555_5555;\n            and EAX, 0x5555_5555;\n            shl EDX, 1;\n            or  EAX, EDX;\n            mov EDX, EAX;\n            shr EAX, 2;\n            and EDX, 0x3333_3333;\n            and EAX, 0x3333_3333;\n            shl EDX, 2;\n            or  EAX, EDX;\n            mov EDX, EAX;\n            shr EAX, 4;\n            and EDX, 0x0f0f_0f0f;\n            and EAX, 0x0f0f_0f0f;\n            shl EDX, 4;\n            or  EAX, EDX;\n            bswap EAX;\n            ret;\n        }\n    }\n}\n\nversion (D_InlineAsm_X86_64)\n{\n    private ulong asmBitswap64(ulong x) @trusted pure\n    {\n        asm pure nothrow @nogc { naked; }\n\n        version (Win64)\n            asm pure nothrow @nogc { mov RAX, RCX; }\n        else\n            asm pure nothrow @nogc { mov RAX, RDI; }\n\n        asm pure nothrow @nogc\n        {\n            // Author: Tiago Gasiba.\n            mov RDX, RAX;\n            shr RAX, 1;\n            mov RCX, 0x5555_5555_5555_5555L;\n            and RDX, RCX;\n            and RAX, RCX;\n            shl RDX, 1;\n            or  RAX, RDX;\n\n            mov RDX, RAX;\n            shr RAX, 2;\n            mov RCX, 0x3333_3333_3333_3333L;\n            and RDX, RCX;\n            and RAX, RCX;\n            shl RDX, 2;\n            or  RAX, RDX;\n\n            mov RDX, RAX;\n            shr RAX, 4;\n            mov RCX, 0x0f0f_0f0f_0f0f_0f0fL;\n            and RDX, RCX;\n            and RAX, RCX;\n            shl RDX, 4;\n            or  RAX, RDX;\n            bswap RAX;\n            ret;\n        }\n    }\n}\n\n/**\n *  Bitwise rotate `value` left (`rol`) or right (`ror`) by\n *  `count` bit positions.\n */\npure T rol(T)(in T value, in uint count)\n    if (__traits(isIntegral, T) && __traits(isUnsigned, T))\n{\n    assert(count < 8 * T.sizeof);\n    return cast(T) ((value << count) | (value >> (-count & (T.sizeof * 8 - 1))));\n}\n/// ditto\npure T ror(T)(in T value, in uint count)\n    if (__traits(isIntegral, T) && __traits(isUnsigned, T))\n{\n    assert(count < 8 * T.sizeof);\n    return cast(T) ((value >> count) | (value << (-count & (T.sizeof * 8 - 1))));\n}\n/// ditto\npure T rol(uint count, T)(in T value)\n    if (__traits(isIntegral, T) && __traits(isUnsigned, T))\n{\n    static assert(count < 8 * T.sizeof);\n    return cast(T) ((value << count) | (value >> (-count & (T.sizeof * 8 - 1))));\n}\n/// ditto\npure T ror(uint count, T)(in T value)\n    if (__traits(isIntegral, T) && __traits(isUnsigned, T))\n{\n    static assert(count < 8 * T.sizeof);\n    return cast(T) ((value >> count) | (value << (-count & (T.sizeof * 8 - 1))));\n}\n\n///\nunittest\n{\n    ubyte a = 0b10101010U;\n    ulong b = ulong.max;\n\n    assert(rol(a, 1) == 0b01010101);\n    assert(ror(a, 1) == 0b01010101);\n    assert(rol(a, 3) == 0b01010101);\n    assert(ror(a, 3) == 0b01010101);\n\n    assert(rol(a, 0) == a);\n    assert(ror(a, 0) == a);\n\n    assert(rol(b, 63) == ulong.max);\n    assert(ror(b, 63) == ulong.max);\n\n    assert(rol!3(a) == 0b01010101);\n    assert(ror!3(a) == 0b01010101);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/checkedint.d",
    "content": "\n/**********************************************\n * This module implements integral arithmetic primitives that check\n * for out-of-range results.\n *\n * Integral arithmetic operators operate on fixed width types.\n * Results that are not representable in those fixed widths are silently\n * truncated to fit.\n * This module offers integral arithmetic primitives that produce the\n * same results, but set an 'overflow' flag when such truncation occurs.\n * The setting is sticky, meaning that numerous operations can be cascaded\n * and then the flag need only be checked at the end.\n * Whether the operation is signed or unsigned is indicated by an 's' or 'u'\n * suffix, respectively. While this could be achieved without such suffixes by\n * using overloading on the signedness of the types, the suffix makes it clear\n * which is happening without needing to examine the types.\n *\n * While the generic versions of these functions are computationally expensive\n * relative to the cost of the operation itself, compiler implementations are free\n * to recognize them and generate equivalent and faster code.\n *\n * References: $(LINK2 http://blog.regehr.org/archives/1139, Fast Integer Overflow Checks)\n * Copyright: Copyright (c) Walter Bright 2014.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Walter Bright\n * Source:    $(DRUNTIMESRC core/_checkedint.d)\n */\n\nmodule core.checkedint;\n\nnothrow:\n@safe:\n@nogc:\npure:\n\n/*******************************\n * Add two signed integers, checking for overflow.\n *\n * The overflow is sticky, meaning a sequence of operations can\n * be done and overflow need only be checked at the end.\n * Params:\n *      x = left operand\n *      y = right operand\n *      overflow = set if an overflow occurs, is not affected otherwise\n * Returns:\n *      the sum\n */\n\npragma(inline, true)\nint adds(int x, int y, ref bool overflow)\n{\n    long r = cast(long)x + cast(long)y;\n    if (r < int.min || r > int.max)\n        overflow = true;\n    return cast(int)r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(adds(2, 3, overflow) == 5);\n    assert(!overflow);\n    assert(adds(1, int.max - 1, overflow) == int.max);\n    assert(!overflow);\n    assert(adds(int.min + 1, -1, overflow) == int.min);\n    assert(!overflow);\n    assert(adds(int.max, 1, overflow) == int.min);\n    assert(overflow);\n    overflow = false;\n    assert(adds(int.min, -1, overflow) == int.max);\n    assert(overflow);\n    assert(adds(0, 0, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\n/// ditto\npragma(inline, true)\nlong adds(long x, long y, ref bool overflow)\n{\n    long r = cast(ulong)x + cast(ulong)y;\n    if (x <  0 && y <  0 && r >= 0 ||\n        x >= 0 && y >= 0 && r <  0)\n        overflow = true;\n    return r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(adds(2L, 3L, overflow) == 5);\n    assert(!overflow);\n    assert(adds(1L, long.max - 1, overflow) == long.max);\n    assert(!overflow);\n    assert(adds(long.min + 1, -1, overflow) == long.min);\n    assert(!overflow);\n    assert(adds(long.max, 1, overflow) == long.min);\n    assert(overflow);\n    overflow = false;\n    assert(adds(long.min, -1, overflow) == long.max);\n    assert(overflow);\n    assert(adds(0L, 0L, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\nstatic if (is(cent))\n{\n/// ditto\npragma(inline, true)\ncent adds(cent x, cent y, ref bool overflow)\n{\n    cent r = cast(ucent)x + cast(ucent)y;\n    if (x <  0 && y <  0 && r >= 0 ||\n        x >= 0 && y >= 0 && r <  0)\n        overflow = true;\n    return r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(adds(cast(cent)2L, 3L, overflow) == 5);\n    assert(!overflow);\n    assert(adds(1L, cent.max - 1, overflow) == cent.max);\n    assert(!overflow);\n    assert(adds(cent.min + 1, -1, overflow) == cent.min);\n    assert(!overflow);\n    assert(adds(cent.max, 1, overflow) == cent.min);\n    assert(overflow);\n    overflow = false;\n    assert(adds(cent.min, -1, overflow) == cent.max);\n    assert(overflow);\n    assert(adds(cast(cent)0L, 0L, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n}\n\n\n/*******************************\n * Add two unsigned integers, checking for overflow (aka carry).\n *\n * The overflow is sticky, meaning a sequence of operations can\n * be done and overflow need only be checked at the end.\n * Params:\n *      x = left operand\n *      y = right operand\n *      overflow = set if an overflow occurs, is not affected otherwise\n * Returns:\n *      the sum\n */\n\npragma(inline, true)\nuint addu(uint x, uint y, ref bool overflow)\n{\n    immutable uint r = x + y;\n    if (r < x || r < y)\n        overflow = true;\n    return r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(addu(2, 3, overflow) == 5);\n    assert(!overflow);\n    assert(addu(1, uint.max - 1, overflow) == uint.max);\n    assert(!overflow);\n    assert(addu(uint.min, -1, overflow) == uint.max);\n    assert(!overflow);\n    assert(addu(uint.max, 1, overflow) == uint.min);\n    assert(overflow);\n    overflow = false;\n    assert(addu(uint.min + 1, -1, overflow) == uint.min);\n    assert(overflow);\n    assert(addu(0, 0, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\n/// ditto\npragma(inline, true)\nulong addu(ulong x, ulong y, ref bool overflow)\n{\n    immutable ulong r = x + y;\n    if (r < x || r < y)\n        overflow = true;\n    return r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(addu(2L, 3L, overflow) == 5);\n    assert(!overflow);\n    assert(addu(1, ulong.max - 1, overflow) == ulong.max);\n    assert(!overflow);\n    assert(addu(ulong.min, -1L, overflow) == ulong.max);\n    assert(!overflow);\n    assert(addu(ulong.max, 1, overflow) == ulong.min);\n    assert(overflow);\n    overflow = false;\n    assert(addu(ulong.min + 1, -1L, overflow) == ulong.min);\n    assert(overflow);\n    assert(addu(0L, 0L, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\nstatic if (is(ucent))\n{\n/// ditto\npragma(inline, true)\nucent addu(ucent x, ucent y, ref bool overflow)\n{\n    immutable ucent r = x + y;\n    if (r < x || r < y)\n        overflow = true;\n    return r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(addu(cast(ucent)2L, 3L, overflow) == 5);\n    assert(!overflow);\n    assert(addu(1, ucent.max - 1, overflow) == ucent.max);\n    assert(!overflow);\n    assert(addu(ucent.min, -1L, overflow) == ucent.max);\n    assert(!overflow);\n    assert(addu(ucent.max, 1, overflow) == ucent.min);\n    assert(overflow);\n    overflow = false;\n    assert(addu(ucent.min + 1, -1L, overflow) == ucent.min);\n    assert(overflow);\n    assert(addu(cast(ucent)0L, 0L, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n}\n\n\n/*******************************\n * Subtract two signed integers, checking for overflow.\n *\n * The overflow is sticky, meaning a sequence of operations can\n * be done and overflow need only be checked at the end.\n * Params:\n *      x = left operand\n *      y = right operand\n *      overflow = set if an overflow occurs, is not affected otherwise\n * Returns:\n *      the difference\n */\n\npragma(inline, true)\nint subs(int x, int y, ref bool overflow)\n{\n    immutable long r = cast(long)x - cast(long)y;\n    if (r < int.min || r > int.max)\n        overflow = true;\n    return cast(int)r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(subs(2, -3, overflow) == 5);\n    assert(!overflow);\n    assert(subs(1, -int.max + 1, overflow) == int.max);\n    assert(!overflow);\n    assert(subs(int.min + 1, 1, overflow) == int.min);\n    assert(!overflow);\n    assert(subs(int.max, -1, overflow) == int.min);\n    assert(overflow);\n    overflow = false;\n    assert(subs(int.min, 1, overflow) == int.max);\n    assert(overflow);\n    assert(subs(0, 0, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\n/// ditto\npragma(inline, true)\nlong subs(long x, long y, ref bool overflow)\n{\n    immutable long r = cast(ulong)x - cast(ulong)y;\n    if (x <  0 && y >= 0 && r >= 0 ||\n        x >= 0 && y <  0 && (r <  0 || y == long.min))\n        overflow = true;\n    return r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(subs(2L, -3L, overflow) == 5);\n    assert(!overflow);\n    assert(subs(1L, -long.max + 1, overflow) == long.max);\n    assert(!overflow);\n    assert(subs(long.min + 1, 1, overflow) == long.min);\n    assert(!overflow);\n    assert(subs(-1L, long.min, overflow) == long.max);\n    assert(!overflow);\n    assert(subs(long.max, -1, overflow) == long.min);\n    assert(overflow);\n    overflow = false;\n    assert(subs(long.min, 1, overflow) == long.max);\n    assert(overflow);\n    assert(subs(0L, 0L, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\nstatic if (is(cent))\n{\n/// ditto\npragma(inline, true)\ncent subs(cent x, cent y, ref bool overflow)\n{\n    immutable cent r = cast(ucent)x - cast(ucent)y;\n    if (x <  0 && y >= 0 && r >= 0 ||\n        x >= 0 && y <  0 && (r <  0 || y == long.min))\n        overflow = true;\n    return r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(subs(cast(cent)2L, -3L, overflow) == 5);\n    assert(!overflow);\n    assert(subs(1L, -cent.max + 1, overflow) == cent.max);\n    assert(!overflow);\n    assert(subs(cent.min + 1, 1, overflow) == cent.min);\n    assert(!overflow);\n    assert(subs(-1L, cent.min, overflow) == cent.max);\n    assert(!overflow);\n    assert(subs(cent.max, -1, overflow) == cent.min);\n    assert(overflow);\n    overflow = false;\n    assert(subs(cent.min, 1, overflow) == cent.max);\n    assert(overflow);\n    assert(subs(cast(cent)0L, 0L, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n}\n\n\n/*******************************\n * Subtract two unsigned integers, checking for overflow (aka borrow).\n *\n * The overflow is sticky, meaning a sequence of operations can\n * be done and overflow need only be checked at the end.\n * Params:\n *      x = left operand\n *      y = right operand\n *      overflow = set if an overflow occurs, is not affected otherwise\n * Returns:\n *      the difference\n */\n\npragma(inline, true)\nuint subu(uint x, uint y, ref bool overflow)\n{\n    if (x < y)\n        overflow = true;\n    return x - y;\n}\n\nunittest\n{\n    bool overflow;\n    assert(subu(3, 2, overflow) == 1);\n    assert(!overflow);\n    assert(subu(uint.max, 1, overflow) == uint.max - 1);\n    assert(!overflow);\n    assert(subu(1, 1, overflow) == uint.min);\n    assert(!overflow);\n    assert(subu(0, 1, overflow) == uint.max);\n    assert(overflow);\n    overflow = false;\n    assert(subu(uint.max - 1, uint.max, overflow) == uint.max);\n    assert(overflow);\n    assert(subu(0, 0, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\n\n/// ditto\npragma(inline, true)\nulong subu(ulong x, ulong y, ref bool overflow)\n{\n    if (x < y)\n        overflow = true;\n    return x - y;\n}\n\nunittest\n{\n    bool overflow;\n    assert(subu(3UL, 2UL, overflow) == 1);\n    assert(!overflow);\n    assert(subu(ulong.max, 1, overflow) == ulong.max - 1);\n    assert(!overflow);\n    assert(subu(1UL, 1UL, overflow) == ulong.min);\n    assert(!overflow);\n    assert(subu(0UL, 1UL, overflow) == ulong.max);\n    assert(overflow);\n    overflow = false;\n    assert(subu(ulong.max - 1, ulong.max, overflow) == ulong.max);\n    assert(overflow);\n    assert(subu(0UL, 0UL, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\nstatic if (is(ucent))\n{\n/// ditto\npragma(inline, true)\nucent subu(ucent x, ucent y, ref bool overflow)\n{\n    if (x < y)\n        overflow = true;\n    return x - y;\n}\n\nunittest\n{\n    bool overflow;\n    assert(subu(cast(ucent)3UL, 2UL, overflow) == 1);\n    assert(!overflow);\n    assert(subu(ucent.max, 1, overflow) == ucent.max - 1);\n    assert(!overflow);\n    assert(subu(1UL, 1UL, overflow) == ucent.min);\n    assert(!overflow);\n    assert(subu(cast(ucent)0UL, 1UL, overflow) == ucent.max);\n    assert(overflow);\n    overflow = false;\n    assert(subu(ucent.max - 1, ucent.max, overflow) == ucent.max);\n    assert(overflow);\n    assert(subu(cast(ucent)0UL, 0UL, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n}\n\n\n/***********************************************\n * Negate an integer.\n *\n * Params:\n *      x = operand\n *      overflow = set if x cannot be negated, is not affected otherwise\n * Returns:\n *      the negation of x\n */\n\npragma(inline, true)\nint negs(int x, ref bool overflow)\n{\n    if (x == int.min)\n        overflow = true;\n    return -x;\n}\n\nunittest\n{\n    bool overflow;\n    assert(negs(0, overflow) == -0);\n    assert(!overflow);\n    assert(negs(1234, overflow) == -1234);\n    assert(!overflow);\n    assert(negs(-5678, overflow) == 5678);\n    assert(!overflow);\n    assert(negs(int.min, overflow) == -int.min);\n    assert(overflow);\n    assert(negs(0, overflow) == -0);\n    assert(overflow);                   // sticky\n}\n\n/// ditto\npragma(inline, true)\nlong negs(long x, ref bool overflow)\n{\n    if (x == long.min)\n        overflow = true;\n    return -x;\n}\n\nunittest\n{\n    bool overflow;\n    assert(negs(0L, overflow) == -0);\n    assert(!overflow);\n    assert(negs(1234L, overflow) == -1234);\n    assert(!overflow);\n    assert(negs(-5678L, overflow) == 5678);\n    assert(!overflow);\n    assert(negs(long.min, overflow) == -long.min);\n    assert(overflow);\n    assert(negs(0L, overflow) == -0);\n    assert(overflow);                   // sticky\n}\n\nstatic if (is(cent))\n{\n/// ditto\npragma(inline, true)\ncent negs(cent x, ref bool overflow)\n{\n    if (x == cent.min)\n        overflow = true;\n    return -x;\n}\n\nunittest\n{\n    bool overflow;\n    assert(negs(cast(cent)0L, overflow) == -0);\n    assert(!overflow);\n    assert(negs(cast(cent)1234L, overflow) == -1234);\n    assert(!overflow);\n    assert(negs(cast(cent)-5678L, overflow) == 5678);\n    assert(!overflow);\n    assert(negs(cent.min, overflow) == -cent.min);\n    assert(overflow);\n    assert(negs(cast(cent)0L, overflow) == -0);\n    assert(overflow);                   // sticky\n}\n}\n\n\n/*******************************\n * Multiply two signed integers, checking for overflow.\n *\n * The overflow is sticky, meaning a sequence of operations can\n * be done and overflow need only be checked at the end.\n * Params:\n *      x = left operand\n *      y = right operand\n *      overflow = set if an overflow occurs, is not affected otherwise\n * Returns:\n *      the product\n */\n\npragma(inline, true)\nint muls(int x, int y, ref bool overflow)\n{\n    long r = cast(long)x * cast(long)y;\n    if (r < int.min || r > int.max)\n        overflow = true;\n    return cast(int)r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(muls(2, 3, overflow) == 6);\n    assert(!overflow);\n    assert(muls(-200, 300, overflow) == -60_000);\n    assert(!overflow);\n    assert(muls(1, int.max, overflow) == int.max);\n    assert(!overflow);\n    assert(muls(int.min, 1, overflow) == int.min);\n    assert(!overflow);\n    assert(muls(int.max, 2, overflow) == (int.max * 2));\n    assert(overflow);\n    overflow = false;\n    assert(muls(int.min, -1, overflow) == int.min);\n    assert(overflow);\n    assert(muls(0, 0, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\n/// ditto\npragma(inline, true)\nlong muls(long x, long y, ref bool overflow)\n{\n    immutable long r = cast(ulong)x * cast(ulong)y;\n    enum not0or1 = ~1L;\n    if ((x & not0or1) && ((r == y)? r : (r / x) != y))\n        overflow = true;\n    return r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(muls(2L, 3L, overflow) == 6);\n    assert(!overflow);\n    assert(muls(-200L, 300L, overflow) == -60_000);\n    assert(!overflow);\n    assert(muls(1, long.max, overflow) == long.max);\n    assert(!overflow);\n    assert(muls(long.min, 1L, overflow) == long.min);\n    assert(!overflow);\n    assert(muls(long.max, 2L, overflow) == (long.max * 2));\n    assert(overflow);\n    overflow = false;\n    assert(muls(-1L, long.min, overflow) == long.min);\n    assert(overflow);\n    overflow = false;\n    assert(muls(long.min, -1L, overflow) == long.min);\n    assert(overflow);\n    assert(muls(0L, 0L, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\nstatic if (is(cent))\n{\n/// ditto\npragma(inline, true)\ncent muls(cent x, cent y, ref bool overflow)\n{\n    immutable cent r = cast(ucent)x * cast(ucent)y;\n    enum not0or1 = ~1L;\n    if ((x & not0or1) && ((r == y)? r : (r / x) != y))\n        overflow = true;\n    return r;\n}\n\nunittest\n{\n    bool overflow;\n    assert(muls(cast(cent)2L, 3L, overflow) == 6);\n    assert(!overflow);\n    assert(muls(cast(cent)-200L, 300L, overflow) == -60_000);\n    assert(!overflow);\n    assert(muls(1, cent.max, overflow) == cent.max);\n    assert(!overflow);\n    assert(muls(cent.min, 1L, overflow) == cent.min);\n    assert(!overflow);\n    assert(muls(cent.max, 2L, overflow) == (cent.max * 2));\n    assert(overflow);\n    overflow = false;\n    assert(muls(-1L, cent.min, overflow) == cent.min);\n    assert(overflow);\n    overflow = false;\n    assert(muls(cent.min, -1L, overflow) == cent.min);\n    assert(overflow);\n    assert(muls(cast(cent)0L, 0L, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n}\n\n\n/*******************************\n * Multiply two unsigned integers, checking for overflow (aka carry).\n *\n * The overflow is sticky, meaning a sequence of operations can\n * be done and overflow need only be checked at the end.\n * Params:\n *      x = left operand\n *      y = right operand\n *      overflow = set if an overflow occurs, is not affected otherwise\n * Returns:\n *      the product\n */\n\npragma(inline, true)\nuint mulu(uint x, uint y, ref bool overflow)\n{\n    immutable ulong r = ulong(x) * ulong(y);\n    if (r >> 32)\n        overflow = true;\n    return cast(uint) r;\n}\n\nunittest\n{\n    void test(uint x, uint y, uint r, bool overflow) @nogc nothrow\n    {\n        bool o;\n        assert(mulu(x, y, o) == r);\n        assert(o == overflow);\n    }\n    test(2, 3, 6, false);\n    test(1, uint.max, uint.max, false);\n    test(0, 1, 0, false);\n    test(0, uint.max, 0, false);\n    test(uint.max, 2, 2 * uint.max, true);\n    test(1 << 16, 1U << 16, 0, true);\n\n    bool overflow = true;\n    assert(mulu(0, 0, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\n/// ditto\npragma(inline, true)\nulong mulu(ulong x, uint y, ref bool overflow)\n{\n    ulong r = x * y;\n    if (x >> 32 &&\n            r / x != y)\n        overflow = true;\n    return r;\n}\n\n/// ditto\npragma(inline, true)\nulong mulu(ulong x, ulong y, ref bool overflow)\n{\n    immutable ulong r = x * y;\n    if ((x | y) >> 32 &&\n            x &&\n            r / x != y)\n        overflow = true;\n    return r;\n}\n\nunittest\n{\n    void test(T, U)(T x, U y, ulong r, bool overflow) @nogc nothrow\n    {\n        bool o;\n        assert(mulu(x, y, o) == r);\n        assert(o == overflow);\n    }\n    // One operand is zero\n    test(0, 3, 0, false);\n    test(0UL, 3, 0, false);\n    test(0UL, 3UL, 0, false);\n    test(3, 0, 0, false);\n    test(3UL, 0, 0, false);\n    test(3UL, 0UL, 0, false);\n    // Small numbers\n    test(2, 3, 6, false);\n    test(2UL, 3, 6, false);\n    test(2UL, 3UL, 6, false);\n    // At the 32/64 border\n    test(1, ulong(uint.max), uint.max, false);\n    test(1UL, ulong(uint.max), uint.max, false);\n    test(ulong(uint.max), 1, uint.max, false);\n    test(ulong(uint.max), 1UL, uint.max, false);\n    test(1, 1 + ulong(uint.max), 1 + ulong(uint.max), false);\n    test(1UL, 1 + ulong(uint.max), 1 + ulong(uint.max), false);\n    test(1 + ulong(uint.max), 1, 1 + ulong(uint.max), false);\n    test(1 + ulong(uint.max), 1UL, 1 + ulong(uint.max), false);\n    // At the limit\n    test(1, ulong.max, ulong.max, false);\n    test(1UL, ulong.max, ulong.max, false);\n    test(ulong.max, 1, ulong.max, false);\n    test(ulong.max, 1UL, ulong.max, false);\n    // Miscellaneous\n    test(0, 1, 0, false);\n    test(0, ulong.max, 0, false);\n    test(ulong.max, 2, 2 * ulong.max, true);\n    test(1UL << 32, 1UL << 32, 0, true);\n    // Must be sticky\n    bool overflow = true;\n    assert(mulu(0UL, 0UL, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n\nstatic if (is(ucent))\n{\n/// ditto\npragma(inline, true)\nucent mulu(ucent x, ucent y, ref bool overflow)\n{\n    immutable ucent r = x * y;\n    if (x && (r / x) != y)\n        overflow = true;\n    return r;\n}\n\nunittest\n{\n    void test(ucent x, ucent y, ucent r, bool overflow) @nogc nothrow\n    {\n        bool o;\n        assert(mulu(x, y, o) == r);\n        assert(o == overflow);\n    }\n    test(2, 3, 6, false);\n    test(1, ucent.max, ucent.max, false);\n    test(0, 1, 0, false);\n    test(0, ucent.max, 0, false);\n    test(ucent.max, 2, 2 * ucent.max, true);\n    test(cast(ucent)1UL << 64, cast(ucent)1UL << 64, 0, true);\n\n    bool overflow = true;\n    assert(mulu(0UL, 0UL, overflow) == 0);\n    assert(overflow);                   // sticky\n}\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/cpuid.d",
    "content": "/**\n * Identify the characteristics of the host CPU, providing information\n * about cache sizes and assembly optimisation hints. This module is\n * provided primarily for assembly language programmers.\n *\n * References:\n * Some of this information was extremely difficult to track down. Some of the\n * documents below were found only in cached versions stored by search engines!\n * This code relies on information found in:\n *\n * $(UL\n * $(LI \"Intel(R) 64 and IA-32 Architectures Software Developers Manual,\n *    Volume 2A: Instruction Set Reference, A-M\" (2007).\n * )\n * $(LI \"AMD CPUID Specification\", Advanced Micro Devices, Rev 2.28 (2008).\n * )\n * $(LI \"AMD Processor Recognition Application Note For Processors Prior to AMD\n *    Family 0Fh Processors\", Advanced Micro Devices, Rev 3.13 (2005).\n * )\n * $(LI \"AMD Geode(TM) GX Processors Data Book\",\n *    Advanced Micro Devices, Publication ID 31505E, (2005).\n * )\n * $(LI \"AMD K6 Processor Code Optimisation\", Advanced Micro Devices, Rev D (2000).\n * )\n * $(LI \"Application note 106: Software Customization for the 6x86 Family\",\n *    Cyrix Corporation, Rev 1.5 (1998)\n * )\n * $(LI $(LINK http://www.datasheetcatalog.org/datasheet/nationalsemiconductor/GX1.pdf))\n * $(LI \"Geode(TM) GX1 Processor Series Low Power Integrated X86 Solution\",\n *   National Semiconductor, (2002)\n * )\n * $(LI \"The VIA Isaiah Architecture\", G. Glenn Henry, Centaur Technology, Inc (2008).\n * )\n * $(LI $(LINK http://www.sandpile.org/ia32/cpuid.htm))\n * $(LI $(LINK http://www.akkadia.org/drepper/cpumemory.pdf))\n * $(LI \"What every programmer should know about memory\",\n *    Ulrich Depper, Red Hat, Inc., (2007).\n * )\n * $(LI \"CPU Identification by the Windows Kernel\", G. Chappell (2009).\n *   $(LINK http://www.geoffchappell.com/viewer.htm?doc=studies/windows/km/cpu/cx8.htm)\n * )\n * $(LI \"Intel(R) Processor Identification and the CPUID Instruction, Application\n *    Note 485\" (2009).\n * )\n * )\n *\n * Bugs: Currently only works on x86 and Itanium CPUs.\n *      Many processors have bugs in their microcode for the CPUID instruction,\n *      so sometimes the cache information may be incorrect.\n *\n * Copyright: Copyright Don Clugston 2007 - 2009.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Don Clugston, Tomas Lindquist Olsen &lt;tomas@famolsen.dk&gt;\n * Source:    $(DRUNTIMESRC core/_cpuid.d)\n */\n\nmodule core.cpuid;\n\n@trusted:\nnothrow:\n@nogc:\n\n// If optimizing for a particular processor, it is generally better\n// to identify based on features rather than model. NOTE: Normally\n// it's only worthwhile to optimise for the latest Intel and AMD CPU,\n// with a backup for other CPUs.\n// Pentium    -- preferPentium1()\n// PMMX       --   + mmx()\n// PPro       -- default\n// PII        --   + mmx()\n// PIII       --   + mmx() + sse()\n// PentiumM   --   + mmx() + sse() + sse2()\n// Pentium4   -- preferPentium4()\n// PentiumD   --   + isX86_64()\n// Core2      -- default + isX86_64()\n// AMD K5     -- preferPentium1()\n// AMD K6     --   + mmx()\n// AMD K6-II  --   + mmx() + 3dnow()\n// AMD K7     -- preferAthlon()\n// AMD K8     --   + sse2()\n// AMD K10    --   + isX86_64()\n// Cyrix 6x86 -- preferPentium1()\n//    6x86MX  --   + mmx()\n\n// GDC support uses extended inline assembly:\n//   https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html        (general information and hints)\n//   https://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html  (binding variables to registers)\n//   https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html (x86 specific register short names)\n\npublic:\n\n/// Cache size and behaviour\nstruct CacheInfo\n{\n    /// Size of the cache, in kilobytes, per CPU.\n    /// For L1 unified (data + code) caches, this size is half the physical size.\n    /// (we don't halve it for larger sizes, since normally\n    /// data size is much greater than code size for critical loops).\n    size_t size;\n    /// Number of ways of associativity, eg:\n    /// $(UL\n    /// $(LI 1 = direct mapped)\n    /// $(LI 2 = 2-way set associative)\n    /// $(LI 3 = 3-way set associative)\n    /// $(LI ubyte.max = fully associative)\n    /// )\n    ubyte associativity;\n    /// Number of bytes read into the cache when a cache miss occurs.\n    uint lineSize;\n}\n\npublic:\n    /// $(RED Scheduled for deprecation. Please use $(D dataCaches) instead.)\n    // Note: When we deprecate it, we simply make it private.\n    __gshared CacheInfo[5] datacache;\n\n@property pure\n{\n    /// The data caches. If there are fewer than 5 physical caches levels,\n    /// the remaining levels are set to size_t.max (== entire memory space)\n    const(CacheInfo)[5] dataCaches() { return _dataCaches; }\n\n    /// Returns vendor string, for display purposes only.\n    /// Do NOT use this to determine features!\n    /// Note that some CPUs have programmable vendorIDs.\n    string vendor()     {return _vendor;}\n    /// Returns processor string, for display purposes only\n    string processor()  {return _processor;}\n\n    /// Does it have an x87 FPU on-chip?\n    bool x87onChip()    {return _x87onChip;}\n    /// Is MMX supported?\n    bool mmx()          {return _mmx;}\n    /// Is SSE supported?\n    bool sse()          {return _sse;}\n    /// Is SSE2 supported?\n    bool sse2()         {return _sse2;}\n    /// Is SSE3 supported?\n    bool sse3()         {return _sse3;}\n    /// Is SSSE3 supported?\n    bool ssse3()         {return _ssse3;}\n    /// Is SSE4.1 supported?\n    bool sse41()        {return _sse41;}\n    /// Is SSE4.2 supported?\n    bool sse42()        {return _sse42;}\n    /// Is SSE4a supported?\n    bool sse4a()        {return _sse4a;}\n    /// Is AES supported\n    bool aes()          {return _aes;}\n    /// Is pclmulqdq supported\n    bool hasPclmulqdq() {return _hasPclmulqdq;}\n    /// Is rdrand supported\n    bool hasRdrand()    {return _hasRdrand;}\n    /// Is AVX supported\n    bool avx()          {return _avx;}\n    /// Is VEX-Encoded AES supported\n    bool vaes()         {return _vaes;}\n    /// Is vpclmulqdq supported\n    bool hasVpclmulqdq(){return _hasVpclmulqdq; }\n    /// Is FMA supported\n    bool fma()          {return _fma;}\n    /// Is FP16C supported\n    bool fp16c()        {return _fp16c;}\n    /// Is AVX2 supported\n    bool avx2()         {return _avx2;}\n    /// Is HLE (hardware lock elision) supported\n    bool hle()          {return _hle;}\n    /// Is RTM (restricted transactional memory) supported\n    bool rtm()          {return _rtm;}\n    /// Is rdseed supported\n    bool hasRdseed()    {return _hasRdseed;}\n    /// Is SHA supported\n    bool hasSha()       {return _hasSha;}\n    /// Is AMD 3DNOW supported?\n    bool amd3dnow()     {return _amd3dnow;}\n    /// Is AMD 3DNOW Ext supported?\n    bool amd3dnowExt()  {return _amd3dnowExt;}\n    /// Are AMD extensions to MMX supported?\n    bool amdMmx()       {return _amdMmx;}\n    /// Is fxsave/fxrstor supported?\n    bool hasFxsr()          {return _hasFxsr;}\n    /// Is cmov supported?\n    bool hasCmov()          {return _hasCmov;}\n    /// Is rdtsc supported?\n    bool hasRdtsc()         {return _hasRdtsc;}\n    /// Is cmpxchg8b supported?\n    bool hasCmpxchg8b()     {return _hasCmpxchg8b;}\n    /// Is cmpxchg8b supported?\n    bool hasCmpxchg16b()    {return _hasCmpxchg16b;}\n    /// Is SYSENTER/SYSEXIT supported?\n    bool hasSysEnterSysExit() {return _hasSysEnterSysExit;}\n    /// Is 3DNow prefetch supported?\n    bool has3dnowPrefetch()   {return _has3dnowPrefetch;}\n    /// Are LAHF and SAHF supported in 64-bit mode?\n    bool hasLahfSahf()        {return _hasLahfSahf;}\n    /// Is POPCNT supported?\n    bool hasPopcnt()        {return _hasPopcnt;}\n    /// Is LZCNT supported?\n    bool hasLzcnt()         {return _hasLzcnt;}\n    /// Is this an Intel64 or AMD 64?\n    bool isX86_64()         {return _isX86_64;}\n\n    /// Is this an IA64 (Itanium) processor?\n    bool isItanium()        { return _isItanium; }\n\n    /// Is hyperthreading supported?\n    bool hyperThreading()   { return _hyperThreading; }\n    /// Returns number of threads per CPU\n    uint threadsPerCPU()    {return _threadsPerCPU;}\n    /// Returns number of cores in CPU\n    uint coresPerCPU()      {return _coresPerCPU;}\n\n    /// Optimisation hints for assembly code.\n    ///\n    /// For forward compatibility, the CPU is compared against different\n    /// microarchitectures. For 32-bit x86, comparisons are made against\n    /// the Intel PPro/PII/PIII/PM family.\n    ///\n    /// The major 32-bit x86 microarchitecture 'dynasties' have been:\n    ///\n    /// $(UL\n    /// $(LI Intel P6 (PentiumPro, PII, PIII, PM, Core, Core2). )\n    /// $(LI AMD Athlon (K7, K8, K10). )\n    /// $(LI Intel NetBurst (Pentium 4, Pentium D). )\n    /// $(LI In-order Pentium (Pentium1, PMMX, Atom) )\n    /// )\n    ///\n    /// Other early CPUs (Nx586, AMD K5, K6, Centaur C3, Transmeta,\n    /// Cyrix, Rise) were mostly in-order.\n    ///\n    /// Some new processors do not fit into the existing categories:\n    ///\n    /// $(UL\n    /// $(LI Intel Atom 230/330 (family 6, model 0x1C) is an in-order core. )\n    /// $(LI Centaur Isiah = VIA Nano (family 6, model F) is an out-of-order core. )\n    /// )\n    ///\n    /// Within each dynasty, the optimisation techniques are largely\n    /// identical (eg, use instruction pairing for group 4). Major\n    /// instruction set improvements occur within each dynasty.\n\n    /// Does this CPU perform better on AMD K7 code than PentiumPro..Core2 code?\n    bool preferAthlon() { return _preferAthlon; }\n    /// Does this CPU perform better on Pentium4 code than PentiumPro..Core2 code?\n    bool preferPentium4() { return _preferPentium4; }\n    /// Does this CPU perform better on Pentium I code than Pentium Pro code?\n    bool preferPentium1() { return _preferPentium1; }\n}\n\nprivate immutable\n{\n    /* These exist as immutables so that the query property functions can\n     * be backwards compatible with code that called them with ().\n     * Also, immutables can only be set by the static this().\n     */\n    const(CacheInfo)[5] _dataCaches;\n    string _vendor;\n    string _processor;\n    bool _x87onChip;\n    bool _mmx;\n    bool _sse;\n    bool _sse2;\n    bool _sse3;\n    bool _ssse3;\n    bool _sse41;\n    bool _sse42;\n    bool _sse4a;\n    bool _aes;\n    bool _hasPclmulqdq;\n    bool _hasRdrand;\n    bool _avx;\n    bool _vaes;\n    bool _hasVpclmulqdq;\n    bool _fma;\n    bool _fp16c;\n    bool _avx2;\n    bool _hle;\n    bool _rtm;\n    bool _hasRdseed;\n    bool _hasSha;\n    bool _amd3dnow;\n    bool _amd3dnowExt;\n    bool _amdMmx;\n    bool _hasFxsr;\n    bool _hasCmov;\n    bool _hasRdtsc;\n    bool _hasCmpxchg8b;\n    bool _hasCmpxchg16b;\n    bool _hasSysEnterSysExit;\n    bool _has3dnowPrefetch;\n    bool _hasLahfSahf;\n    bool _hasPopcnt;\n    bool _hasLzcnt;\n    bool _isX86_64;\n    bool _isItanium;\n    bool _hyperThreading;\n    uint _threadsPerCPU;\n    uint _coresPerCPU;\n    bool _preferAthlon;\n    bool _preferPentium4;\n    bool _preferPentium1;\n}\n\n__gshared:\n    // All these values are set only once, and never subsequently modified.\npublic:\n    /// $(RED Warning: This field will be turned into a property in a future release.)\n    ///\n    /// Processor type (vendor-dependent).\n    /// This should be visible ONLY for display purposes.\n    uint stepping, model, family;\n    /// $(RED This field has been deprecated. Please use $(D cacheLevels) instead.)\n    uint numCacheLevels = 1;\n    /// The number of cache levels in the CPU.\n    @property uint cacheLevels() { return numCacheLevels; }\nprivate:\n\nstruct CpuFeatures\n{\n    bool probablyIntel; // true = _probably_ an Intel processor, might be faking\n    bool probablyAMD; // true = _probably_ an AMD processor\n    string processorName;\n    char [12] vendorID;\n    char [48] processorNameBuffer;\n    uint features = 0;     // mmx, sse, sse2, hyperthreading, etc\n    uint miscfeatures = 0; // sse3, etc.\n    uint extfeatures = 0;  // HLE, AVX2, RTM, etc.\n    uint amdfeatures = 0;  // 3DNow!, mmxext, etc\n    uint amdmiscfeatures = 0; // sse4a, sse5, svm, etc\n    ulong xfeatures = 0;   // XFEATURES_ENABLED_MASK\n    uint maxCores = 1;\n    uint maxThreads = 1;\n}\n\nCpuFeatures cpuFeatures;\n\n/* Hide from the optimizer where cf (a register) is coming from, so that\n * cf doesn't get \"optimized away\". The idea is to  reference\n * the global data through cf so not so many fixups are inserted\n * into the executable image.\n */\nCpuFeatures* getCpuFeatures() @nogc nothrow\n{\n    pragma(inline, false);\n    return &cpuFeatures;\n}\n\n    // Note that this may indicate multi-core rather than hyperthreading.\n    @property bool hyperThreadingBit()    { return (cpuFeatures.features&HTT_BIT)!=0;}\n\n    // feature flags CPUID1_EDX\n    enum : uint\n    {\n        FPU_BIT = 1,\n        TIMESTAMP_BIT = 1<<4, // rdtsc\n        MDSR_BIT = 1<<5,      // RDMSR/WRMSR\n        CMPXCHG8B_BIT = 1<<8,\n        SYSENTERSYSEXIT_BIT = 1<<11,\n        CMOV_BIT = 1<<15,\n        MMX_BIT = 1<<23,\n        FXSR_BIT = 1<<24,\n        SSE_BIT = 1<<25,\n        SSE2_BIT = 1<<26,\n        HTT_BIT = 1<<28,\n        IA64_BIT = 1<<30\n    }\n    // feature flags misc CPUID1_ECX\n    enum : uint\n    {\n        SSE3_BIT = 1,\n        PCLMULQDQ_BIT = 1<<1, // from AVX\n        MWAIT_BIT = 1<<3,\n        SSSE3_BIT = 1<<9,\n        FMA_BIT = 1<<12,     // from AVX\n        CMPXCHG16B_BIT = 1<<13,\n        SSE41_BIT = 1<<19,\n        SSE42_BIT = 1<<20,\n        POPCNT_BIT = 1<<23,\n        AES_BIT = 1<<25, // AES instructions from AVX\n        OSXSAVE_BIT = 1<<27, // Used for AVX\n        AVX_BIT = 1<<28,\n        FP16C_BIT = 1<<29,\n        RDRAND_BIT = 1<<30,\n    }\n    // Feature flags for cpuid.{EAX = 7, ECX = 0}.EBX.\n    enum : uint\n    {\n        FSGSBASE_BIT = 1 << 0,\n        BMI1_BIT = 1 << 3,\n        HLE_BIT = 1 << 4,\n        AVX2_BIT = 1 << 5,\n        SMEP_BIT = 1 << 7,\n        BMI2_BIT = 1 << 8,\n        ERMS_BIT = 1 << 9,\n        INVPCID_BIT = 1 << 10,\n        RTM_BIT = 1 << 11,\n        RDSEED_BIT = 1 << 18,\n        SHA_BIT = 1 << 29,\n    }\n    // feature flags XFEATURES_ENABLED_MASK\n    enum : ulong\n    {\n        XF_FP_BIT  = 0x1,\n        XF_SSE_BIT = 0x2,\n        XF_YMM_BIT = 0x4,\n    }\n    // AMD feature flags CPUID80000001_EDX\n    enum : uint\n    {\n        AMD_MMX_BIT = 1<<22,\n//      FXR_OR_CYRIXMMX_BIT = 1<<24, // Cyrix/NS: 6x86MMX instructions.\n        FFXSR_BIT = 1<<25,\n        PAGE1GB_BIT = 1<<26, // support for 1GB pages\n        RDTSCP_BIT = 1<<27,\n        AMD64_BIT = 1<<29,\n        AMD_3DNOW_EXT_BIT = 1<<30,\n        AMD_3DNOW_BIT = 1<<31\n    }\n    // AMD misc feature flags CPUID80000001_ECX\n    enum : uint\n    {\n        LAHFSAHF_BIT = 1,\n        LZCNT_BIT = 1<<5,\n        SSE4A_BIT = 1<<6,\n        AMD_3DNOW_PREFETCH_BIT = 1<<8,\n    }\n\n\nversion (GNU) {\n    version (X86)\n        enum supportedX86 = true;\n    else version (X86_64)\n        enum supportedX86 = true;\n    else\n        enum supportedX86 = false;\n} else version (D_InlineAsm_X86) {\n    enum supportedX86 = true;\n} else version (D_InlineAsm_X86_64) {\n    enum supportedX86 = true;\n} else {\n    enum supportedX86 = false;\n}\n\nstatic if (supportedX86) {\n// Note that this code will also work for Itanium in x86 mode.\n\n__gshared uint max_cpuid, max_extended_cpuid;\n\n// CPUID2: \"cache and tlb information\"\nvoid getcacheinfoCPUID2()\n{\n    // We are only interested in the data caches\n    void decipherCpuid2(ubyte x) @nogc nothrow {\n        if (x==0) return;\n        // Values from http://www.sandpile.org/ia32/cpuid.htm.\n        // Includes Itanium and non-Intel CPUs.\n        //\n        static immutable ubyte [63] ids = [\n            0x0A, 0x0C, 0x0D, 0x2C, 0x60, 0x0E, 0x66, 0x67, 0x68,\n            // level 2 cache\n            0x41, 0x42, 0x43, 0x44, 0x45, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7F,\n            0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x49, 0x4E,\n            0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x48, 0x80, 0x81,\n            // level 3 cache\n            0x22, 0x23, 0x25, 0x29, 0x46, 0x47, 0x4A, 0x4B, 0x4C, 0x4D,\n\n            0xD0, 0xD1, 0xD2, 0xD6, 0xD7, 0xD8, 0xDC, 0xDD, 0xDE,\n            0xE2, 0xE3, 0xE4, 0xEA, 0xEB, 0xEC\n        ];\n        static immutable uint [63] sizes = [\n            8, 16, 16, 64, 16, 24, 8, 16, 32,\n            128, 256, 512, 1024, 2048, 1024, 128, 256, 512, 1024, 2048, 512,\n            256, 512, 1024, 2048, 512, 1024, 4096, 6*1024,\n            128, 192, 128, 256, 384, 512, 3072, 512, 128,\n            512, 1024, 2048, 4096, 4096, 8192, 6*1024, 8192, 12*1024, 16*1024,\n\n            512, 1024, 2048, 1024, 2048, 4096, 1024+512, 3*1024, 6*1024,\n            2*1024, 4*1024, 8*1024, 12*1024, 28*1024, 24*1024\n        ];\n    // CPUBUG: Pentium M reports 0x2C but tests show it is only 4-way associative\n        static immutable ubyte [63] ways = [\n            2, 4, 4, 8, 8, 6, 4, 4, 4,\n            4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 2,\n            8, 8, 8, 8, 4, 8, 16, 24,\n            4, 6, 2, 4, 6, 4, 12, 8, 8,\n            4, 8, 8, 8, 4, 8, 12, 16, 12, 16,\n            4, 4, 4, 8, 8, 8, 12, 12, 12,\n            16, 16, 16, 24, 24, 24\n        ];\n        enum { FIRSTDATA2 = 8, FIRSTDATA3 = 28+9 }\n        for (size_t i=0; i< ids.length; ++i) {\n            if (x==ids[i]) {\n                int level = i< FIRSTDATA2 ? 0: i<FIRSTDATA3 ? 1 : 2;\n                if (x==0x49 && family==0xF && model==0x6) level=2;\n                datacache[level].size=sizes[i];\n                datacache[level].associativity=ways[i];\n                if (level == 3 || x==0x2C || x==0x0D || (x>=0x48 && x<=0x80)\n                                   || x==0x86 || x==0x87\n                                   || (x>=0x66 && x<=0x68) || (x>=0x39 && x<=0x3E)){\n                    datacache[level].lineSize = 64;\n                } else datacache[level].lineSize = 32;\n            }\n        }\n    }\n\n    uint[4] a;\n    bool firstTime = true;\n    // On a multi-core system, this could theoretically fail, but it's only used\n    // for old single-core CPUs.\n    uint numinfos = 1;\n    do {\n        version (GNU) asm pure nothrow @nogc {\n            \"cpuid\" : \"=a\" a[0], \"=b\" a[1], \"=c\" a[2], \"=d\" a[3] : \"a\" 2;\n        } else asm pure nothrow @nogc {\n            mov EAX, 2;\n            cpuid;\n            mov a, EAX;\n            mov a+4, EBX;\n            mov a+8, ECX;\n            mov a+12, EDX;\n        }\n        if (firstTime) {\n            if (a[0]==0x0000_7001 && a[3]==0x80 && a[1]==0 && a[2]==0) {\n        // Cyrix MediaGX MMXEnhanced returns: EAX= 00007001, EDX=00000080.\n        // These are NOT standard Intel values\n        // (TLB = 32 entry, 4 way associative, 4K pages)\n        // (L1 cache = 16K, 4way, linesize16)\n                datacache[0].size=8;\n                datacache[0].associativity=4;\n                datacache[0].lineSize=16;\n                return;\n            }\n            // lsb of a is how many times to loop.\n            numinfos = a[0] & 0xFF;\n            // and otherwise it should be ignored\n            a[0] &= 0xFFFF_FF00;\n            firstTime = false;\n        }\n        for (int c=0; c<4;++c) {\n            // high bit set == no info.\n            if (a[c] & 0x8000_0000) continue;\n            decipherCpuid2(cast(ubyte)(a[c] & 0xFF));\n            decipherCpuid2(cast(ubyte)((a[c]>>8) & 0xFF));\n            decipherCpuid2(cast(ubyte)((a[c]>>16) & 0xFF));\n            decipherCpuid2(cast(ubyte)((a[c]>>24) & 0xFF));\n        }\n    } while (--numinfos);\n}\n\n// CPUID4: \"Deterministic cache parameters\" leaf\nvoid getcacheinfoCPUID4()\n{\n    int cachenum = 0;\n    for (;;) {\n        uint a, b, number_of_sets;\n        version (GNU) asm pure nothrow @nogc {\n            \"cpuid\" : \"=a\" a, \"=b\" b, \"=c\" number_of_sets : \"a\" 4, \"c\" cachenum : \"edx\";\n        } else asm pure nothrow @nogc {\n            mov EAX, 4;\n            mov ECX, cachenum;\n            cpuid;\n            mov a, EAX;\n            mov b, EBX;\n            mov number_of_sets, ECX;\n        }\n        ++cachenum;\n        if ((a&0x1F)==0) break; // no more caches\n        immutable uint numthreads = ((a>>14) & 0xFFF)  + 1;\n        immutable uint numcores = ((a>>26) & 0x3F) + 1;\n        if (numcores > cpuFeatures.maxCores) cpuFeatures.maxCores = numcores;\n        if ((a&0x1F)!=1 && ((a&0x1F)!=3)) continue; // we only want data & unified caches\n\n        ++number_of_sets;\n        immutable ubyte level = cast(ubyte)(((a>>5)&7)-1);\n        if (level > datacache.length) continue; // ignore deep caches\n        datacache[level].associativity = a & 0x200 ? ubyte.max :cast(ubyte)((b>>22)+1);\n        datacache[level].lineSize = (b & 0xFFF)+ 1; // system coherency line size\n        immutable uint line_partitions = ((b >> 12)& 0x3FF) + 1;\n        // Size = number of sets * associativity * cachelinesize * linepartitions\n        // and must convert to Kb, also dividing by the number of hyperthreads using this cache.\n        immutable ulong sz = (datacache[level].associativity< ubyte.max)? number_of_sets *\n            datacache[level].associativity : number_of_sets;\n        datacache[level].size = cast(size_t)(\n                (sz * datacache[level].lineSize * line_partitions ) / (numthreads *1024));\n        if (level == 0 && (a&0xF)==3) {\n            // Halve the size for unified L1 caches\n            datacache[level].size/=2;\n        }\n    }\n}\n\n// CPUID8000_0005 & 6\nvoid getAMDcacheinfo()\n{\n    uint dummy, c5, c6, d6;\n    version (GNU) asm pure nothrow @nogc {\n        \"cpuid\" : \"=a\" dummy, \"=c\" c5 : \"a\" 0x8000_0005 : \"ebx\", \"edx\";\n    } else asm pure nothrow @nogc {\n        mov EAX, 0x8000_0005; // L1 cache\n        cpuid;\n        // EAX has L1_TLB_4M.\n        // EBX has L1_TLB_4K\n        // EDX has L1 instruction cache\n        mov c5, ECX;\n    }\n\n    datacache[0].size = ( (c5>>24) & 0xFF);\n    datacache[0].associativity = cast(ubyte)( (c5 >> 16) & 0xFF);\n    datacache[0].lineSize = c5 & 0xFF;\n\n    if (max_extended_cpuid >= 0x8000_0006) {\n        // AMD K6-III or K6-2+ or later.\n        ubyte numcores = 1;\n        if (max_extended_cpuid >= 0x8000_0008) {\n            version (GNU) asm pure nothrow @nogc {\n                \"cpuid\" : \"=a\" dummy, \"=c\" numcores : \"a\" 0x8000_0008 : \"ebx\", \"edx\";\n            } else asm pure nothrow @nogc {\n                mov EAX, 0x8000_0008;\n                cpuid;\n                mov numcores, CL;\n            }\n            ++numcores;\n            if (numcores>cpuFeatures.maxCores) cpuFeatures.maxCores = numcores;\n        }\n\n        version (GNU) asm pure nothrow @nogc {\n            \"cpuid\" : \"=a\" dummy, \"=c\" c6, \"=d\" d6 : \"a\" 0x8000_0006 : \"ebx\";\n        } else asm pure nothrow @nogc {\n            mov EAX, 0x8000_0006; // L2/L3 cache\n            cpuid;\n            mov c6, ECX; // L2 cache info\n            mov d6, EDX; // L3 cache info\n        }\n\n        static immutable ubyte [] assocmap = [ 0, 1, 2, 0, 4, 0, 8, 0, 16, 0, 32, 48, 64, 96, 128, 0xFF ];\n        datacache[1].size = (c6>>16) & 0xFFFF;\n        datacache[1].associativity = assocmap[(c6>>12)&0xF];\n        datacache[1].lineSize = c6 & 0xFF;\n\n        // The L3 cache value is TOTAL, not per core.\n        datacache[2].size = ((d6>>18)*512)/numcores; // could be up to 2 * this, -1.\n        datacache[2].associativity = assocmap[(d6>>12)&0xF];\n        datacache[2].lineSize = d6 & 0xFF;\n    }\n}\n\n// For Intel CoreI7 and later, use function 0x0B\n// to determine number of processors.\nvoid getCpuInfo0B()\n{\n    int level=0;\n    int threadsPerCore;\n    uint a, b, c, d;\n    do {\n        version (GNU) asm pure nothrow @nogc {\n            \"cpuid\" : \"=a\" a, \"=b\" b, \"=c\" c, \"=d\" d : \"a\" 0x0B, \"c\" level;\n        } else asm pure nothrow @nogc {\n            mov EAX, 0x0B;\n            mov ECX, level;\n            cpuid;\n            mov a, EAX;\n            mov b, EBX;\n            mov c, ECX;\n            mov d, EDX;\n        }\n        if (b!=0) {\n           // I'm not sure about this. The docs state that there\n           // are 2 hyperthreads per core if HT is factory enabled.\n            if (level==0)\n                threadsPerCore = b & 0xFFFF;\n            else if (level==1) {\n                cpuFeatures.maxThreads = b & 0xFFFF;\n                cpuFeatures.maxCores = cpuFeatures.maxThreads / threadsPerCore;\n            }\n\n        }\n        ++level;\n    } while (a!=0 || b!=0);\n}\n\nvoid cpuidX86()\n{\n    auto cf = getCpuFeatures();\n\n    uint a, b, c, d;\n    uint* venptr = cast(uint*)cf.vendorID.ptr;\n    version (GNU)\n    {\n        asm pure nothrow @nogc { \"cpuid\" : \"=a\" max_cpuid, \"=b\" venptr[0], \"=d\" venptr[1], \"=c\" venptr[2] : \"a\" 0; }\n        asm pure nothrow @nogc { \"cpuid\" : \"=a\" max_extended_cpuid : \"a\" 0x8000_0000 : \"ebx\", \"ecx\", \"edx\"; }\n    }\n    else\n    {\n        uint a2;\n        version (D_InlineAsm_X86)\n        {\n            asm pure nothrow @nogc {\n                mov EAX, 0;\n                cpuid;\n                mov a, EAX;\n                mov EAX, venptr;\n                mov [EAX], EBX;\n                mov [EAX + 4], EDX;\n                mov [EAX + 8], ECX;\n            }\n        }\n        else version (D_InlineAsm_X86_64)\n        {\n            asm pure nothrow @nogc {\n                mov EAX, 0;\n                cpuid;\n                mov a, EAX;\n                mov RAX, venptr;\n                mov [RAX], EBX;\n                mov [RAX + 4], EDX;\n                mov [RAX + 8], ECX;\n            }\n        }\n        asm pure nothrow @nogc {\n            mov EAX, 0x8000_0000;\n            cpuid;\n            mov a2, EAX;\n        }\n        max_cpuid = a;\n        max_extended_cpuid = a2;\n    }\n\n\n    cf.probablyIntel = cf.vendorID == \"GenuineIntel\";\n    cf.probablyAMD = cf.vendorID == \"AuthenticAMD\";\n    uint apic = 0; // brand index, apic id\n    version (GNU) asm pure nothrow @nogc {\n        \"cpuid\" : \"=a\" a, \"=b\" apic, \"=c\" cf.miscfeatures, \"=d\" cf.features : \"a\" 1;\n    } else {\n        asm pure nothrow @nogc {\n            mov EAX, 1; // model, stepping\n            cpuid;\n            mov a, EAX;\n            mov apic, EBX;\n            mov c, ECX;\n            mov d, EDX;\n        }\n        cf.features = d;\n        cf.miscfeatures = c;\n    }\n    stepping = a & 0xF;\n    immutable uint fbase = (a >> 8) & 0xF;\n    immutable uint mbase = (a >> 4) & 0xF;\n    family = ((fbase == 0xF) || (fbase == 0)) ? fbase + (a >> 20) & 0xFF : fbase;\n    model = ((fbase == 0xF) || (fbase == 6 && cf.probablyIntel) ) ?\n         mbase + ((a >> 12) & 0xF0) : mbase;\n\n    if (max_cpuid >= 7)\n    {\n        version (GNU) asm pure nothrow @nogc {\n            \"cpuid\" : \"=a\" a, \"=b\" cf.extfeatures, \"=c\" c : \"a\" 7, \"c\" 0 : \"edx\";\n        } else {\n            uint ext;\n            asm pure nothrow @nogc {\n                mov EAX, 7; // Structured extended feature leaf.\n                mov ECX, 0; // Main leaf.\n                cpuid;\n                mov ext, EBX; // HLE, AVX2, RTM, etc.\n            }\n            cf.extfeatures = ext;\n        }\n    }\n\n    if (cf.miscfeatures & OSXSAVE_BIT)\n    {\n        version (GNU) asm pure nothrow @nogc {\n            \"xgetbv\" : \"=a\" a, \"=d\" d : \"c\" 0;\n        } else asm pure nothrow @nogc {\n            mov ECX, 0;\n            xgetbv;\n            mov d, EDX;\n            mov a, EAX;\n        }\n        cf.xfeatures = cast(ulong)d << 32 | a;\n    }\n\n    cf.amdfeatures = 0;\n    cf.amdmiscfeatures = 0;\n    if (max_extended_cpuid >= 0x8000_0001) {\n        version (GNU) asm pure nothrow @nogc {\n            \"cpuid\" : \"=a\" a, \"=c\" cf.amdmiscfeatures, \"=d\" cf.amdfeatures : \"a\" 0x8000_0001 : \"ebx\";\n        } else {\n            asm pure nothrow @nogc {\n                mov EAX, 0x8000_0001;\n                cpuid;\n                mov c, ECX;\n                mov d, EDX;\n            }\n            cf.amdmiscfeatures = c;\n            cf.amdfeatures = d;\n        }\n    }\n    // Try to detect fraudulent vendorIDs\n    if (amd3dnow) cf.probablyIntel = false;\n\n    if (!cf.probablyIntel && max_extended_cpuid >= 0x8000_0008) {\n        //http://support.amd.com/TechDocs/25481.pdf pg.36\n        cf.maxCores = 1;\n        if (hyperThreadingBit) {\n            // determine max number of cores for AMD\n            version (GNU) asm pure nothrow @nogc {\n                \"cpuid\" : \"=a\" a, \"=c\" c : \"a\" 0x8000_0008 : \"ebx\", \"edx\";\n            } else asm pure nothrow @nogc {\n                mov EAX, 0x8000_0008;\n                cpuid;\n                mov c, ECX;\n            }\n            cf.maxCores += c & 0xFF;\n        }\n    }\n\n    if (max_extended_cpuid >= 0x8000_0004) {\n        uint* pnb = cast(uint*)cf.processorNameBuffer.ptr;\n        version (GNU)\n        {\n            asm pure nothrow @nogc { \"cpuid\" : \"=a\" pnb[0], \"=b\" pnb[1], \"=c\" pnb[ 2], \"=d\" pnb[ 3] : \"a\" 0x8000_0002; }\n            asm pure nothrow @nogc { \"cpuid\" : \"=a\" pnb[4], \"=b\" pnb[5], \"=c\" pnb[ 6], \"=d\" pnb[ 7] : \"a\" 0x8000_0003; }\n            asm pure nothrow @nogc { \"cpuid\" : \"=a\" pnb[8], \"=b\" pnb[9], \"=c\" pnb[10], \"=d\" pnb[11] : \"a\" 0x8000_0004; }\n        }\n        else version (D_InlineAsm_X86)\n        {\n            asm pure nothrow @nogc {\n                push ESI;\n                mov ESI, pnb;\n                mov EAX, 0x8000_0002;\n                cpuid;\n                mov [ESI], EAX;\n                mov [ESI+4], EBX;\n                mov [ESI+8], ECX;\n                mov [ESI+12], EDX;\n                mov EAX, 0x8000_0003;\n                cpuid;\n                mov [ESI+16], EAX;\n                mov [ESI+20], EBX;\n                mov [ESI+24], ECX;\n                mov [ESI+28], EDX;\n                mov EAX, 0x8000_0004;\n                cpuid;\n                mov [ESI+32], EAX;\n                mov [ESI+36], EBX;\n                mov [ESI+40], ECX;\n                mov [ESI+44], EDX;\n                pop ESI;\n            }\n        }\n        else version (D_InlineAsm_X86_64)\n        {\n            asm pure nothrow @nogc {\n                push RSI;\n                mov RSI, pnb;\n                mov EAX, 0x8000_0002;\n                cpuid;\n                mov [RSI], EAX;\n                mov [RSI+4], EBX;\n                mov [RSI+8], ECX;\n                mov [RSI+12], EDX;\n                mov EAX, 0x8000_0003;\n                cpuid;\n                mov [RSI+16], EAX;\n                mov [RSI+20], EBX;\n                mov [RSI+24], ECX;\n                mov [RSI+28], EDX;\n                mov EAX, 0x8000_0004;\n                cpuid;\n                mov [RSI+32], EAX;\n                mov [RSI+36], EBX;\n                mov [RSI+40], ECX;\n                mov [RSI+44], EDX;\n                pop RSI;\n            }\n        }\n        // Intel P4 and PM pad at front with spaces.\n        // Other CPUs pad at end with nulls.\n        int start = 0, end = 0;\n        while (cf.processorNameBuffer[start] == ' ') { ++start; }\n        while (cf.processorNameBuffer[cf.processorNameBuffer.length-end-1] == 0) { ++end; }\n        cf.processorName = cast(string)(cf.processorNameBuffer[start..$-end]);\n    } else {\n        cf.processorName = \"Unknown CPU\";\n    }\n    // Determine cache sizes\n\n    // Intel docs specify that they return 0 for 0x8000_0005.\n    // AMD docs do not specify the behaviour for 0004 and 0002.\n    // Centaur/VIA and most other manufacturers use the AMD method,\n    // except Cyrix MediaGX MMX Enhanced uses their OWN form of CPUID2!\n    // NS Geode GX1 provides CyrixCPUID2 _and_ does the same wrong behaviour\n    // for CPUID80000005. But Geode GX uses the AMD method\n\n    // Deal with Geode GX1 - make it same as MediaGX MMX.\n    if (max_extended_cpuid==0x8000_0005 && max_cpuid==2) {\n        max_extended_cpuid = 0x8000_0004;\n    }\n    // Therefore, we try the AMD method unless it's an Intel chip.\n    // If we still have no info, try the Intel methods.\n    datacache[0].size = 0;\n    if (max_cpuid<2 || !cf.probablyIntel) {\n        if (max_extended_cpuid >= 0x8000_0005) {\n            getAMDcacheinfo();\n        } else if (cf.probablyAMD) {\n            // According to AMDProcRecognitionAppNote, this means CPU\n            // K5 model 0, or Am5x86 (model 4), or Am4x86DX4 (model 4)\n            // Am5x86 has 16Kb 4-way unified data & code cache.\n            datacache[0].size = 8;\n            datacache[0].associativity = 4;\n            datacache[0].lineSize = 32;\n        } else {\n            // Some obscure CPU.\n            // Values for Cyrix 6x86MX (family 6, model 0)\n            datacache[0].size = 64;\n            datacache[0].associativity = 4;\n            datacache[0].lineSize = 32;\n        }\n    }\n    if ((datacache[0].size == 0) && max_cpuid>=4) {\n        getcacheinfoCPUID4();\n    }\n    if ((datacache[0].size == 0) && max_cpuid>=2) {\n        getcacheinfoCPUID2();\n    }\n    if (datacache[0].size == 0) {\n        // Pentium, PMMX, late model 486, or an obscure CPU\n        if (mmx) { // Pentium MMX. Also has 8kB code cache.\n            datacache[0].size = 16;\n            datacache[0].associativity = 4;\n            datacache[0].lineSize = 32;\n        } else { // Pentium 1 (which also has 8kB code cache)\n                 // or 486.\n            // Cyrix 6x86: 16, 4way, 32 linesize\n            datacache[0].size = 8;\n            datacache[0].associativity = 2;\n            datacache[0].lineSize = 32;\n        }\n    }\n    if (max_cpuid >= 0x0B) {\n        // For Intel i7 and later, use function 0x0B to determine\n        // cores and hyperthreads.\n        getCpuInfo0B();\n    } else {\n        if (hyperThreadingBit) cf.maxThreads = (apic>>>16) & 0xFF;\n        else cf.maxThreads = cf.maxCores;\n    }\n}\n\n// Return true if the cpuid instruction is supported.\n// BUG(WONTFIX): Returns false for Cyrix 6x86 and 6x86L. They will be treated as 486 machines.\nbool hasCPUID()\n{\n    version (X86_64)\n        return true;\n    else\n    {\n        uint flags;\n        version (GNU)\n        {\n            // http://wiki.osdev.org/CPUID#Checking_CPUID_availability\n            // ASM template supports both AT&T and Intel syntax.\n            asm nothrow @nogc { \"\n                pushf{l|d}                 # Save EFLAGS\n                pushf{l|d}                 # Store EFLAGS\n                xor{l $0x00200000, (%%esp)| dword ptr [esp], 0x00200000}\n                                           # Invert the ID bit in stored EFLAGS\n                popf{l|d}                  # Load stored EFLAGS (with ID bit inverted)\n                pushf{l|d}                 # Store EFLAGS again (ID bit may or may not be inverted)\n                pop {%%}eax                # eax = modified EFLAGS (ID bit may or may not be inverted)\n                xor {(%%esp), %%eax|eax, [esp]}\n                                           # eax = whichever bits were changed\n                popf{l|d}                  # Restore original EFLAGS\n                \" : \"=a\" flags;\n            }\n        }\n        else version (D_InlineAsm_X86)\n        {\n            asm nothrow @nogc {\n                pushfd;\n                pop EAX;\n                mov flags, EAX;\n                xor EAX, 0x0020_0000;\n                push EAX;\n                popfd;\n                pushfd;\n                pop EAX;\n                xor flags, EAX;\n            }\n        }\n        return (flags & 0x0020_0000) != 0;\n    }\n}\n\n} else { // supported X86\n\n    bool hasCPUID() { return false; }\n\n    void cpuidX86()\n    {\n            datacache[0].size = 8;\n            datacache[0].associativity = 2;\n            datacache[0].lineSize = 32;\n    }\n}\n\n/*\n// TODO: Implement this function with OS support\nvoid cpuidPPC()\n{\n    enum :int  { PPC601, PPC603, PPC603E, PPC604,\n                 PPC604E, PPC620, PPCG3, PPCG4, PPCG5 }\n\n    // TODO:\n    // asm { mfpvr; } returns the CPU version but unfortunately it can\n    // only be used in kernel mode. So OS support is required.\n    int cputype = PPC603;\n\n    // 601 has a 8KB combined data & code L1 cache.\n    uint sizes[] = [4, 8, 16, 16, 32, 32, 32, 32, 64];\n    ubyte ways[] = [8, 2,  4,  4,  4,  8,  8,  8,  8];\n    uint L2size[]= [0, 0,  0,  0,  0,  0,  0,  256,  512];\n    uint L3size[]= [0, 0,  0,  0,  0,  0,  0,  2048,  0];\n\n    datacache[0].size = sizes[cputype];\n    datacache[0].associativity = ways[cputype];\n    datacache[0].lineSize = (cputype==PPCG5)? 128 :\n        (cputype == PPC620 || cputype == PPCG3)? 64 : 32;\n    datacache[1].size = L2size[cputype];\n    datacache[2].size = L3size[cputype];\n    datacache[1].lineSize = datacache[0].lineSize;\n    datacache[2].lineSize = datacache[0].lineSize;\n}\n\n// TODO: Implement this function with OS support\nvoid cpuidSparc()\n{\n    // UltaSparcIIi  : L1 = 16,  2way. L2 = 512, 4 way.\n    // UltraSparcIII : L1 = 64,  4way. L2= 4096 or 8192.\n    // UltraSparcIIIi: L1 = 64,  4way. L2= 1024, 4 way\n    // UltraSparcIV  : L1 = 64,  4way. L2 = 16*1024.\n    // UltraSparcIV+ : L1 = 64,  4way. L2 = 2048, L3=32*1024.\n    // Sparc64V      : L1 = 128, 2way. L2 = 4096 4way.\n}\n*/\n\nshared static this()\n{\n    auto cf = getCpuFeatures();\n\n    if (hasCPUID()) {\n        cpuidX86();\n    } else {\n        // it's a 386 or 486, or a Cyrix 6x86.\n        //Probably still has an external cache.\n    }\n    if (datacache[0].size==0) {\n            // Guess same as Pentium 1.\n            datacache[0].size = 8;\n            datacache[0].associativity = 2;\n            datacache[0].lineSize = 32;\n    }\n    numCacheLevels = 1;\n    // And now fill up all the unused levels with full memory space.\n    for (size_t i=1; i< datacache.length; ++i) {\n        if (datacache[i].size==0) {\n            // Set all remaining levels of cache equal to full address space.\n            datacache[i].size = size_t.max/1024;\n            datacache[i].associativity = 1;\n            datacache[i].lineSize = datacache[i-1].lineSize;\n        }\n        else\n            ++numCacheLevels;\n    }\n\n    // Set the immortals\n\n    _dataCaches =     datacache;\n    _vendor =         cast(string)cf.vendorID;\n    _processor =      cf.processorName;\n    _x87onChip =      (cf.features&FPU_BIT)!=0;\n    _mmx =            (cf.features&MMX_BIT)!=0;\n    _sse =            (cf.features&SSE_BIT)!=0;\n    _sse2 =           (cf.features&SSE2_BIT)!=0;\n    _sse3 =           (cf.miscfeatures&SSE3_BIT)!=0;\n    _ssse3 =          (cf.miscfeatures&SSSE3_BIT)!=0;\n    _sse41 =          (cf.miscfeatures&SSE41_BIT)!=0;\n    _sse42 =          (cf.miscfeatures&SSE42_BIT)!=0;\n    _sse4a =          (cf.amdmiscfeatures&SSE4A_BIT)!=0;\n    _aes =            (cf.miscfeatures&AES_BIT)!=0;\n    _hasPclmulqdq =   (cf.miscfeatures&PCLMULQDQ_BIT)!=0;\n    _hasRdrand =      (cf.miscfeatures&RDRAND_BIT)!=0;\n\n    enum avx_mask = XF_SSE_BIT|XF_YMM_BIT;\n    _avx =            (cf.xfeatures & avx_mask) == avx_mask && (cf.miscfeatures&AVX_BIT)!=0;\n\n    _vaes =           avx && aes;\n    _hasVpclmulqdq =  avx && hasPclmulqdq;\n    _fma =            avx && (cf.miscfeatures&FMA_BIT)!=0;\n    _fp16c =          avx && (cf.miscfeatures&FP16C_BIT)!=0;\n    _avx2 =           avx && (cf.extfeatures & AVX2_BIT) != 0;\n    _hle =            (cf.extfeatures & HLE_BIT) != 0;\n    _rtm =            (cf.extfeatures & RTM_BIT) != 0;\n    _hasRdseed =      (cf.extfeatures&RDSEED_BIT)!=0;\n    _hasSha =         (cf.extfeatures&SHA_BIT)!=0;\n    _amd3dnow =       (cf.amdfeatures&AMD_3DNOW_BIT)!=0;\n    _amd3dnowExt =    (cf.amdfeatures&AMD_3DNOW_EXT_BIT)!=0;\n    _amdMmx =         (cf.amdfeatures&AMD_MMX_BIT)!=0;\n    _hasFxsr =        (cf.features&FXSR_BIT)!=0;\n    _hasCmov =        (cf.features&CMOV_BIT)!=0;\n    _hasRdtsc =       (cf.features&TIMESTAMP_BIT)!=0;\n    _hasCmpxchg8b =   (cf.features&CMPXCHG8B_BIT)!=0;\n    _hasCmpxchg16b =  (cf.miscfeatures&CMPXCHG16B_BIT)!=0;\n    _hasSysEnterSysExit =\n        // The SYSENTER/SYSEXIT features were buggy on Pentium Pro and early PentiumII.\n        // (REF: www.geoffchappell.com).\n        (cf.probablyIntel && (family < 6 || (family==6 && (model< 3 || (model==3 && stepping<3)))))\n            ? false\n            : (cf.features & SYSENTERSYSEXIT_BIT)!=0;\n    _has3dnowPrefetch = (cf.amdmiscfeatures&AMD_3DNOW_PREFETCH_BIT)!=0;\n    _hasLahfSahf =    (cf.amdmiscfeatures&LAHFSAHF_BIT)!=0;\n    _hasPopcnt =      (cf.miscfeatures&POPCNT_BIT)!=0;\n    _hasLzcnt =       (cf.amdmiscfeatures&LZCNT_BIT)!=0;\n    _isX86_64 =       (cf.amdfeatures&AMD64_BIT)!=0;\n    _isItanium =      (cf.features&IA64_BIT)!=0;\n    _hyperThreading = cf.maxThreads>cf.maxCores;\n    _threadsPerCPU =  cf.maxThreads;\n    _coresPerCPU =    cf.maxCores;\n    _preferAthlon =   cf.probablyAMD && family >=6;\n    _preferPentium4 = cf.probablyIntel && family == 0xF;\n    _preferPentium1 = family < 6 || (family==6 && model < 0xF && !cf.probablyIntel);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/demangle.d",
    "content": "/**\n * The demangle module converts mangled D symbols to a representation similar\n * to what would have existed in code.\n *\n * Copyright: Copyright Sean Kelly 2010 - 2014.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/_demangle.d)\n */\n\nmodule core.demangle;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\ndebug(trace) import core.stdc.stdio : printf;\ndebug(info) import core.stdc.stdio : printf;\n\nprivate struct NoHooks\n{\n    // supported hooks\n    // static bool parseLName(ref Demangle);\n    // static char[] parseType(ref Demangle, char[])\n}\n\nprivate struct Demangle(Hooks = NoHooks)\n{\n    // NOTE: This implementation currently only works with mangled function\n    //       names as they exist in an object file.  Type names mangled via\n    //       the .mangleof property are effectively incomplete as far as the\n    //       ABI is concerned and so are not considered to be mangled symbol\n    //       names.\n\n    // NOTE: This implementation builds the demangled buffer in place by\n    //       writing data as it is decoded and then rearranging it later as\n    //       needed.  In practice this results in very little data movement,\n    //       and the performance cost is more than offset by the gain from\n    //       not allocating dynamic memory to assemble the name piecemeal.\n    //\n    //       If the destination buffer is too small, parsing will restart\n    //       with a larger buffer.  Since this generally means only one\n    //       allocation during the course of a parsing run, this is still\n    //       faster than assembling the result piecemeal.\n\npure @safe:\n    enum AddType { no, yes }\n\n\n    this( const(char)[] buf_, char[] dst_ = null )\n    {\n        this( buf_, AddType.yes, dst_ );\n    }\n\n\n    this( const(char)[] buf_, AddType addType_, char[] dst_ = null )\n    {\n        buf     = buf_;\n        addType = addType_;\n        dst     = dst_;\n    }\n\n\n    enum size_t minBufSize = 4000;\n\n\n    const(char)[]   buf     = null;\n    char[]          dst     = null;\n    size_t          pos     = 0;\n    size_t          len     = 0;\n    size_t          brp     = 0; // current back reference pos\n    AddType         addType = AddType.yes;\n    bool            mute    = false;\n    Hooks           hooks;\n\n    static class ParseException : Exception\n    {\n        @safe pure nothrow this( string msg )\n        {\n            super( msg );\n        }\n    }\n\n\n    static class OverflowException : Exception\n    {\n        @safe pure nothrow this( string msg )\n        {\n            super( msg );\n        }\n    }\n\n\n    static void error( string msg = \"Invalid symbol\" ) @trusted /* exception only used in module */\n    {\n        pragma(inline, false); // tame dmd inliner\n\n        //throw new ParseException( msg );\n        debug(info) printf( \"error: %.*s\\n\", cast(int) msg.length, msg.ptr );\n        throw __ctfe ? new ParseException(msg)\n                     : cast(ParseException) cast(void*) typeid(ParseException).initializer;\n\n    }\n\n\n    static void overflow( string msg = \"Buffer overflow\" ) @trusted /* exception only used in module */\n    {\n        pragma(inline, false); // tame dmd inliner\n\n        //throw new OverflowException( msg );\n        debug(info) printf( \"overflow: %.*s\\n\", cast(int) msg.length, msg.ptr );\n        throw cast(OverflowException) cast(void*) typeid(OverflowException).initializer;\n    }\n\n\n    //////////////////////////////////////////////////////////////////////////\n    // Type Testing and Conversion\n    //////////////////////////////////////////////////////////////////////////\n\n\n    static bool isAlpha( char val )\n    {\n        return ('a' <= val && 'z' >= val) ||\n               ('A' <= val && 'Z' >= val) ||\n               (0x80 & val); // treat all unicode as alphabetic\n    }\n\n\n    static bool isDigit( char val )\n    {\n        return '0' <= val && '9' >= val;\n    }\n\n\n    static bool isHexDigit( char val )\n    {\n        return ('0' <= val && '9' >= val) ||\n               ('a' <= val && 'f' >= val) ||\n               ('A' <= val && 'F' >= val);\n    }\n\n\n    static ubyte ascii2hex( char val )\n    {\n        if (val >= 'a' && val <= 'f')\n            return cast(ubyte)(val - 'a' + 10);\n        if (val >= 'A' && val <= 'F')\n            return cast(ubyte)(val - 'A' + 10);\n        if (val >= '0' && val <= '9')\n            return cast(ubyte)(val - '0');\n        error();\n        return 0;\n    }\n\n\n    //////////////////////////////////////////////////////////////////////////\n    // Data Output\n    //////////////////////////////////////////////////////////////////////////\n\n\n    static bool contains( const(char)[] a, const(char)[] b ) @trusted\n    {\n        if (a.length && b.length)\n        {\n            auto bend = b.ptr + b.length;\n            auto aend = a.ptr + a.length;\n            return a.ptr <= b.ptr && bend <= aend;\n        }\n        return false;\n    }\n\n\n    // move val to the end of the dst buffer\n    char[] shift( const(char)[] val )\n    {\n        pragma(inline, false); // tame dmd inliner\n\n        if ( val.length && !mute )\n        {\n            assert( contains( dst[0 .. len], val ) );\n            debug(info) printf( \"shifting (%.*s)\\n\", cast(int) val.length, val.ptr );\n\n            if (len + val.length > dst.length)\n                overflow();\n            size_t v = &val[0] - &dst[0];\n            dst[len .. len + val.length] = val[];\n            for (size_t p = v; p < len; p++)\n                dst[p] = dst[p + val.length];\n\n            return dst[len - val.length .. len];\n        }\n        return null;\n    }\n\n    // remove val from dst buffer\n    void remove( const(char)[] val )\n    {\n        pragma(inline, false); // tame dmd inliner\n\n        if ( val.length )\n        {\n            assert( contains( dst[0 .. len], val ) );\n            debug(info) printf( \"removing (%.*s)\\n\", cast(int) val.length, val.ptr );\n            size_t v = &val[0] - &dst[0];\n            assert( len >= val.length && len <= dst.length );\n            len -= val.length;\n            for (size_t p = v; p < len; p++)\n                dst[p] = dst[p + val.length];\n        }\n    }\n\n    char[] append( const(char)[] val )\n    {\n        pragma(inline, false); // tame dmd inliner\n\n        if ( val.length && !mute )\n        {\n            if ( !dst.length )\n                dst.length = minBufSize;\n            assert( !contains( dst[0 .. len], val ) );\n            debug(info) printf( \"appending (%.*s)\\n\", cast(int) val.length, val.ptr );\n\n            if ( dst.length - len >= val.length && &dst[len] == &val[0] )\n            {\n                // data is already in place\n                auto t = dst[len .. len + val.length];\n                len += val.length;\n                return t;\n            }\n            if ( dst.length - len >= val.length )\n            {\n                dst[len .. len + val.length] = val[];\n                auto t = dst[len .. len + val.length];\n                len += val.length;\n                return t;\n            }\n            overflow();\n        }\n        return null;\n    }\n\n    void putComma(size_t n)\n    {\n        pragma(inline, false);\n        if (n)\n            put(\", \");\n    }\n\n    char[] put(char c)\n    {\n        char[1] val = c;\n        return put(val[]);\n    }\n\n    char[] put( const(char)[] val )\n    {\n        pragma(inline, false); // tame dmd inliner\n\n        if ( val.length )\n        {\n            if ( !contains( dst[0 .. len], val ) )\n                return append( val );\n            return shift( val );\n        }\n        return null;\n    }\n\n\n    void putAsHex( size_t val, int width = 0 )\n    {\n        import core.internal.string;\n\n        UnsignedStringBuf buf;\n\n        auto s = unsignedToTempString(val, buf, 16);\n        int slen = cast(int)s.length;\n        if (slen < width)\n        {\n            foreach (i; slen .. width)\n                put('0');\n        }\n        put(s);\n    }\n\n\n    void pad( const(char)[] val )\n    {\n        if ( val.length )\n        {\n            append( \" \" );\n            put( val );\n        }\n    }\n\n\n    void silent( lazy void dg )\n    {\n        debug(trace) printf( \"silent+\\n\" );\n        debug(trace) scope(success) printf( \"silent-\\n\" );\n        auto n = len; dg(); len = n;\n    }\n\n\n    //////////////////////////////////////////////////////////////////////////\n    // Parsing Utility\n    //////////////////////////////////////////////////////////////////////////\n\n    @property bool empty()\n    {\n        return pos >= buf.length;\n    }\n\n    @property char front()\n    {\n        if ( pos < buf.length )\n            return buf[pos];\n        return char.init;\n    }\n\n    char peek( size_t n )\n    {\n        if ( pos + n < buf.length )\n            return buf[pos + n];\n        return char.init;\n    }\n\n\n    void test( char val )\n    {\n        if ( val != front )\n            error();\n    }\n\n\n    void popFront()\n    {\n        if ( pos++ >= buf.length )\n            error();\n    }\n\n\n    void match( char val )\n    {\n        test( val );\n        popFront();\n    }\n\n\n    void match( const(char)[] val )\n    {\n        foreach (char e; val )\n        {\n            test( e );\n            popFront();\n        }\n    }\n\n\n    void eat( char val )\n    {\n        if ( val == front )\n            popFront();\n    }\n\n    bool isSymbolNameFront()\n    {\n        char val = front;\n        if ( isDigit( val ) || val == '_' )\n            return true;\n        if ( val != 'Q' )\n            return false;\n\n        // check the back reference encoding after 'Q'\n        val = peekBackref();\n        return isDigit( val ); // identifier ref\n    }\n\n    // return the first character at the back reference\n    char peekBackref()\n    {\n        assert( front == 'Q' );\n        auto n = decodeBackref!1();\n        if (!n || n > pos)\n            error(\"invalid back reference\");\n\n        return buf[pos - n];\n    }\n\n    size_t decodeBackref(size_t peekAt = 0)()\n    {\n        enum base = 26;\n        size_t n = 0;\n        for (size_t p; ; p++)\n        {\n            char t;\n            static if (peekAt > 0)\n            {\n                t = peek(peekAt + p);\n            }\n            else\n            {\n                t = front;\n                popFront();\n            }\n            if (t < 'A' || t > 'Z')\n            {\n                if (t < 'a' || t > 'z')\n                    error(\"invalid back reference\");\n                n = base * n + t - 'a';\n                return n;\n            }\n            n = base * n + t - 'A';\n        }\n    }\n\n    //////////////////////////////////////////////////////////////////////////\n    // Parsing Implementation\n    //////////////////////////////////////////////////////////////////////////\n\n\n    /*\n    Number:\n        Digit\n        Digit Number\n    */\n    const(char)[] sliceNumber()\n    {\n        debug(trace) printf( \"sliceNumber+\\n\" );\n        debug(trace) scope(success) printf( \"sliceNumber-\\n\" );\n\n        auto beg = pos;\n\n        while ( true )\n        {\n            auto t = front;\n            if (t >= '0' && t <= '9')\n                popFront();\n            else\n                return buf[beg .. pos];\n        }\n    }\n\n\n    size_t decodeNumber()\n    {\n        debug(trace) printf( \"decodeNumber+\\n\" );\n        debug(trace) scope(success) printf( \"decodeNumber-\\n\" );\n\n        return decodeNumber( sliceNumber() );\n    }\n\n\n    size_t decodeNumber( const(char)[] num )\n    {\n        debug(trace) printf( \"decodeNumber+\\n\" );\n        debug(trace) scope(success) printf( \"decodeNumber-\\n\" );\n\n        size_t val = 0;\n\n        foreach ( c; num )\n        {\n            import core.checkedint : mulu, addu;\n\n            bool overflow = false;\n            val = mulu(val, 10, overflow);\n            val = addu(val, c - '0',  overflow);\n            if (overflow)\n                error();\n        }\n        return val;\n    }\n\n\n    void parseReal()\n    {\n        debug(trace) printf( \"parseReal+\\n\" );\n        debug(trace) scope(success) printf( \"parseReal-\\n\" );\n\n        char[64] tbuf = void;\n        size_t   tlen = 0;\n        real     val  = void;\n\n        if ( 'I' == front )\n        {\n            match( \"INF\" );\n            put( \"real.infinity\" );\n            return;\n        }\n        if ( 'N' == front )\n        {\n            popFront();\n            if ( 'I' == front )\n            {\n                match( \"INF\" );\n                put( \"-real.infinity\" );\n                return;\n            }\n            if ( 'A' == front )\n            {\n                match( \"AN\" );\n                put( \"real.nan\" );\n                return;\n            }\n            tbuf[tlen++] = '-';\n        }\n\n        tbuf[tlen++] = '0';\n        tbuf[tlen++] = 'X';\n        if ( !isHexDigit( front ) )\n            error( \"Expected hex digit\" );\n        tbuf[tlen++] = front;\n        tbuf[tlen++] = '.';\n        popFront();\n\n        while ( isHexDigit( front ) )\n        {\n            tbuf[tlen++] = front;\n            popFront();\n        }\n        match( 'P' );\n        tbuf[tlen++] = 'p';\n        if ( 'N' == front )\n        {\n            tbuf[tlen++] = '-';\n            popFront();\n        }\n        else\n        {\n            tbuf[tlen++] = '+';\n        }\n        while ( isDigit( front ) )\n        {\n            tbuf[tlen++] = front;\n            popFront();\n        }\n\n        tbuf[tlen] = 0;\n        debug(info) printf( \"got (%s)\\n\", tbuf.ptr );\n        pureReprintReal( tbuf[] );\n        debug(info) printf( \"converted (%.*s)\\n\", cast(int) tlen, tbuf.ptr );\n        put( tbuf[0 .. tlen] );\n    }\n\n\n    /*\n    LName:\n        Number Name\n\n    Name:\n        Namestart\n        Namestart Namechars\n\n    Namestart:\n        _\n        Alpha\n\n    Namechar:\n        Namestart\n        Digit\n\n    Namechars:\n        Namechar\n        Namechar Namechars\n    */\n    void parseLName()\n    {\n        debug(trace) printf( \"parseLName+\\n\" );\n        debug(trace) scope(success) printf( \"parseLName-\\n\" );\n\n        static if (__traits(hasMember, Hooks, \"parseLName\"))\n            if (hooks.parseLName(this))\n                return;\n\n        if ( front == 'Q' )\n        {\n            // back reference to LName\n            auto refPos = pos;\n            popFront();\n            size_t n = decodeBackref();\n            if ( !n || n > refPos )\n                error( \"Invalid LName back reference\" );\n            if ( !mute )\n            {\n                auto savePos = pos;\n                scope(exit) pos = savePos;\n                pos = refPos - n;\n                parseLName();\n            }\n            return;\n        }\n        auto n = decodeNumber();\n        if ( n == 0 )\n        {\n            put( \"__anonymous\" );\n            return;\n        }\n        if ( n > buf.length || n > buf.length - pos )\n            error( \"LName must be at least 1 character\" );\n        if ( '_' != front && !isAlpha( front ) )\n            error( \"Invalid character in LName\" );\n        foreach (char e; buf[pos + 1 .. pos + n] )\n        {\n            if ( '_' != e && !isAlpha( e ) && !isDigit( e ) )\n                error( \"Invalid character in LName\" );\n        }\n\n        put( buf[pos .. pos + n] );\n        pos += n;\n    }\n\n\n    /*\n    Type:\n        Shared\n        Const\n        Immutable\n        Wild\n        TypeArray\n        TypeVector\n        TypeStaticArray\n        TypeAssocArray\n        TypePointer\n        TypeFunction\n        TypeIdent\n        TypeClass\n        TypeStruct\n        TypeEnum\n        TypeTypedef\n        TypeDelegate\n        TypeNone\n        TypeVoid\n        TypeByte\n        TypeUbyte\n        TypeShort\n        TypeUshort\n        TypeInt\n        TypeUint\n        TypeLong\n        TypeUlong\n        TypeCent\n        TypeUcent\n        TypeFloat\n        TypeDouble\n        TypeReal\n        TypeIfloat\n        TypeIdouble\n        TypeIreal\n        TypeCfloat\n        TypeCdouble\n        TypeCreal\n        TypeBool\n        TypeChar\n        TypeWchar\n        TypeDchar\n        TypeTuple\n\n    Shared:\n        O Type\n\n    Const:\n        x Type\n\n    Immutable:\n        y Type\n\n    Wild:\n        Ng Type\n\n    TypeArray:\n        A Type\n\n    TypeVector:\n        Nh Type\n\n    TypeStaticArray:\n        G Number Type\n\n    TypeAssocArray:\n        H Type Type\n\n    TypePointer:\n        P Type\n\n    TypeFunction:\n        CallConvention FuncAttrs Arguments ArgClose Type\n\n    TypeIdent:\n        I LName\n\n    TypeClass:\n        C LName\n\n    TypeStruct:\n        S LName\n\n    TypeEnum:\n        E LName\n\n    TypeTypedef:\n        T LName\n\n    TypeDelegate:\n        D TypeFunction\n\n    TypeNone:\n        n\n\n    TypeVoid:\n        v\n\n    TypeByte:\n        g\n\n    TypeUbyte:\n        h\n\n    TypeShort:\n        s\n\n    TypeUshort:\n        t\n\n    TypeInt:\n        i\n\n    TypeUint:\n        k\n\n    TypeLong:\n        l\n\n    TypeUlong:\n        m\n\n    TypeCent\n        zi\n\n    TypeUcent\n        zk\n\n    TypeFloat:\n        f\n\n    TypeDouble:\n        d\n\n    TypeReal:\n        e\n\n    TypeIfloat:\n        o\n\n    TypeIdouble:\n        p\n\n    TypeIreal:\n        j\n\n    TypeCfloat:\n        q\n\n    TypeCdouble:\n        r\n\n    TypeCreal:\n        c\n\n    TypeBool:\n        b\n\n    TypeChar:\n        a\n\n    TypeWchar:\n        u\n\n    TypeDchar:\n        w\n\n    TypeTuple:\n        B Number Arguments\n    */\n    char[] parseType( char[] name = null )\n    {\n        static immutable string[23] primitives = [\n            \"char\", // a\n            \"bool\", // b\n            \"creal\", // c\n            \"double\", // d\n            \"real\", // e\n            \"float\", // f\n            \"byte\", // g\n            \"ubyte\", // h\n            \"int\", // i\n            \"ireal\", // j\n            \"uint\", // k\n            \"long\", // l\n            \"ulong\", // m\n            null, // n\n            \"ifloat\", // o\n            \"idouble\", // p\n            \"cfloat\", // q\n            \"cdouble\", // r\n            \"short\", // s\n            \"ushort\", // t\n            \"wchar\", // u\n            \"void\", // v\n            \"dchar\", // w\n        ];\n\n        static if (__traits(hasMember, Hooks, \"parseType\"))\n            if (auto n = hooks.parseType(this, name))\n                return n;\n\n        debug(trace) printf( \"parseType+\\n\" );\n        debug(trace) scope(success) printf( \"parseType-\\n\" );\n        auto beg = len;\n        auto t = front;\n\n        char[] parseBackrefType(scope char[] delegate() pure @safe parseDg) pure @safe\n        {\n            if (pos == brp)\n                error(\"recursive back reference\");\n            auto refPos = pos;\n            popFront();\n            auto n = decodeBackref();\n            if (n == 0 || n > pos)\n                error(\"invalid back reference\");\n            if ( mute )\n                return null;\n            auto savePos = pos;\n            auto saveBrp = brp;\n            scope(success) { pos = savePos; brp = saveBrp; }\n            pos = refPos - n;\n            brp = refPos;\n            auto ret = parseDg();\n            return ret;\n        }\n\n        switch ( t )\n        {\n        case 'Q': // Type back reference\n            return parseBackrefType( () => parseType( name ) );\n        case 'O': // Shared (O Type)\n            popFront();\n            put( \"shared(\" );\n            parseType();\n            put( ')' );\n            pad( name );\n            return dst[beg .. len];\n        case 'x': // Const (x Type)\n            popFront();\n            put( \"const(\" );\n            parseType();\n            put( ')' );\n            pad( name );\n            return dst[beg .. len];\n        case 'y': // Immutable (y Type)\n            popFront();\n            put( \"immutable(\" );\n            parseType();\n            put( ')' );\n            pad( name );\n            return dst[beg .. len];\n        case 'N':\n            popFront();\n            switch ( front )\n            {\n            case 'g': // Wild (Ng Type)\n                popFront();\n                // TODO: Anything needed here?\n                put( \"inout(\" );\n                parseType();\n                put( ')' );\n                return dst[beg .. len];\n            case 'h': // TypeVector (Nh Type)\n                popFront();\n                put( \"__vector(\" );\n                parseType();\n                put( ')' );\n                return dst[beg .. len];\n            default:\n                error();\n                assert( 0 );\n            }\n        case 'A': // TypeArray (A Type)\n            popFront();\n            parseType();\n            put( \"[]\" );\n            pad( name );\n            return dst[beg .. len];\n        case 'G': // TypeStaticArray (G Number Type)\n            popFront();\n            auto num = sliceNumber();\n            parseType();\n            put( '[' );\n            put( num );\n            put( ']' );\n            pad( name );\n            return dst[beg .. len];\n        case 'H': // TypeAssocArray (H Type Type)\n            popFront();\n            // skip t1\n            auto tx = parseType();\n            parseType();\n            put( '[' );\n            put( tx );\n            put( ']' );\n            pad( name );\n            return dst[beg .. len];\n        case 'P': // TypePointer (P Type)\n            popFront();\n            parseType();\n            put( '*' );\n            pad( name );\n            return dst[beg .. len];\n        case 'F': case 'U': case 'W': case 'V': case 'R': // TypeFunction\n            return parseTypeFunction( name );\n        case 'I': // TypeIdent (I LName)\n        case 'C': // TypeClass (C LName)\n        case 'S': // TypeStruct (S LName)\n        case 'E': // TypeEnum (E LName)\n        case 'T': // TypeTypedef (T LName)\n            popFront();\n            parseQualifiedName();\n            pad( name );\n            return dst[beg .. len];\n        case 'D': // TypeDelegate (D TypeFunction)\n            popFront();\n            auto modbeg = len;\n            parseModifier();\n            auto modend = len;\n            if ( front == 'Q' )\n                parseBackrefType( () => parseTypeFunction( name, IsDelegate.yes ) );\n            else\n                parseTypeFunction( name, IsDelegate.yes );\n            if (modend > modbeg)\n            {\n                // move modifiers behind the function arguments\n                shift(dst[modend-1 .. modend]); // trailing space\n                shift(dst[modbeg .. modend-1]);\n            }\n            return dst[beg .. len];\n        case 'n': // TypeNone (n)\n            popFront();\n            // TODO: Anything needed here?\n            return dst[beg .. len];\n        case 'B': // TypeTuple (B Number Arguments)\n            popFront();\n            // TODO: Handle this.\n            return dst[beg .. len];\n        case 'Z': // Internal symbol\n            // This 'type' is used for untyped internal symbols, i.e.:\n            // __array\n            // __init\n            // __vtbl\n            // __Class\n            // __Interface\n            // __ModuleInfo\n            popFront();\n            return dst[beg .. len];\n        default:\n            if (t >= 'a' && t <= 'w')\n            {\n                popFront();\n                put( primitives[cast(size_t)(t - 'a')] );\n                pad( name );\n                return dst[beg .. len];\n            }\n            else if (t == 'z')\n            {\n                popFront();\n                switch ( front )\n                {\n                case 'i':\n                    popFront();\n                    put( \"cent\" );\n                    pad( name );\n                    return dst[beg .. len];\n                case 'k':\n                    popFront();\n                    put( \"ucent\" );\n                    pad( name );\n                    return dst[beg .. len];\n                default:\n                    error();\n                    assert( 0 );\n                }\n            }\n            error();\n            return null;\n        }\n    }\n\n\n    /*\n    TypeFunction:\n        CallConvention FuncAttrs Arguments ArgClose Type\n\n    CallConvention:\n        F       // D\n        U       // C\n        W       // Windows\n        V       // Pascal\n        R       // C++\n\n    FuncAttrs:\n        FuncAttr\n        FuncAttr FuncAttrs\n\n    FuncAttr:\n        empty\n        FuncAttrPure\n        FuncAttrNothrow\n        FuncAttrProperty\n        FuncAttrRef\n        FuncAttrReturn\n        FuncAttrScope\n        FuncAttrTrusted\n        FuncAttrSafe\n\n    FuncAttrPure:\n        Na\n\n    FuncAttrNothrow:\n        Nb\n\n    FuncAttrRef:\n        Nc\n\n    FuncAttrProperty:\n        Nd\n\n    FuncAttrTrusted:\n        Ne\n\n    FuncAttrSafe:\n        Nf\n\n    FuncAttrNogc:\n        Ni\n\n    FuncAttrReturn:\n        Nj\n\n    FuncAttrScope:\n        Nl\n\n    Arguments:\n        Argument\n        Argument Arguments\n\n    Argument:\n        Argument2\n        M Argument2     // scope\n\n    Argument2:\n        Type\n        J Type     // out\n        K Type     // ref\n        L Type     // lazy\n\n    ArgClose\n        X     // variadic T t,...) style\n        Y     // variadic T t...) style\n        Z     // not variadic\n    */\n    void parseCallConvention()\n    {\n        // CallConvention\n        switch ( front )\n        {\n        case 'F': // D\n            popFront();\n            break;\n        case 'U': // C\n            popFront();\n            put( \"extern (C) \" );\n            break;\n        case 'W': // Windows\n            popFront();\n            put( \"extern (Windows) \" );\n            break;\n        case 'V': // Pascal\n            popFront();\n            put( \"extern (Pascal) \" );\n            break;\n        case 'R': // C++\n            popFront();\n            put( \"extern (C++) \" );\n            break;\n        default:\n            error();\n        }\n    }\n\n    void parseModifier()\n    {\n        switch ( front )\n        {\n        case 'y':\n            popFront();\n            put( \"immutable \" );\n            break;\n        case 'O':\n            popFront();\n            put( \"shared \" );\n            if ( front == 'x' )\n                goto case 'x';\n            if ( front == 'N' )\n                goto case 'N';\n            break;\n        case 'N':\n            if ( peek( 1 ) != 'g' )\n                break;\n            popFront();\n            popFront();\n            put( \"inout \" );\n            if ( front == 'x' )\n                goto case 'x';\n            break;\n        case 'x':\n            popFront();\n            put( \"const \" );\n            break;\n        default: break;\n        }\n    }\n\n    void parseFuncAttr()\n    {\n        // FuncAttrs\n        breakFuncAttrs:\n        while ('N' == front)\n        {\n            popFront();\n            switch ( front )\n            {\n            case 'a': // FuncAttrPure\n                popFront();\n                put( \"pure \" );\n                continue;\n            case 'b': // FuncAttrNoThrow\n                popFront();\n                put( \"nothrow \" );\n                continue;\n            case 'c': // FuncAttrRef\n                popFront();\n                put( \"ref \" );\n                continue;\n            case 'd': // FuncAttrProperty\n                popFront();\n                put( \"@property \" );\n                continue;\n            case 'e': // FuncAttrTrusted\n                popFront();\n                put( \"@trusted \" );\n                continue;\n            case 'f': // FuncAttrSafe\n                popFront();\n                put( \"@safe \" );\n                continue;\n            case 'g':\n            case 'h':\n            case 'k':\n                // NOTE: The inout parameter type is represented as \"Ng\".\n                //       The vector parameter type is represented as \"Nh\".\n                //       The return parameter type is represented as \"Nk\".\n                //       These make it look like a FuncAttr, but infact\n                //       if we see these, then we know we're really in\n                //       the parameter list.  Rewind and break.\n                pos--;\n                break breakFuncAttrs;\n            case 'i': // FuncAttrNogc\n                popFront();\n                put( \"@nogc \" );\n                continue;\n            case 'j': // FuncAttrReturn\n                popFront();\n                put( \"return \" );\n                continue;\n            case 'l': // FuncAttrScope\n                popFront();\n                put( \"scope \" );\n                continue;\n            default:\n                error();\n            }\n        }\n    }\n\n    void parseFuncArguments()\n    {\n        // Arguments\n        for ( size_t n = 0; true; n++ )\n        {\n            debug(info) printf( \"tok (%c)\\n\", front );\n            switch ( front )\n            {\n            case 'X': // ArgClose (variadic T t...) style)\n                popFront();\n                put( \"...\" );\n                return;\n            case 'Y': // ArgClose (variadic T t,...) style)\n                popFront();\n                put( \", ...\" );\n                return;\n            case 'Z': // ArgClose (not variadic)\n                popFront();\n                return;\n            default:\n                break;\n            }\n            putComma(n);\n            if ( 'M' == front )\n            {\n                popFront();\n                put( \"scope \" );\n            }\n            if ( 'N' == front )\n            {\n                popFront();\n                if ( 'k' == front ) // Return (Nk Parameter2)\n                {\n                    popFront();\n                    put( \"return \" );\n                }\n                else\n                    pos--;\n            }\n            switch ( front )\n            {\n            case 'J': // out (J Type)\n                popFront();\n                put( \"out \" );\n                parseType();\n                continue;\n            case 'K': // ref (K Type)\n                popFront();\n                put( \"ref \" );\n                parseType();\n                continue;\n            case 'L': // lazy (L Type)\n                popFront();\n                put( \"lazy \" );\n                parseType();\n                continue;\n            default:\n                parseType();\n            }\n        }\n    }\n\n    enum IsDelegate { no, yes }\n\n    /*\n        TypeFunction:\n            CallConvention FuncAttrs Arguments ArgClose Type\n    */\n    char[] parseTypeFunction( char[] name = null, IsDelegate isdg = IsDelegate.no )\n    {\n        debug(trace) printf( \"parseTypeFunction+\\n\" );\n        debug(trace) scope(success) printf( \"parseTypeFunction-\\n\" );\n        auto beg = len;\n\n        parseCallConvention();\n        auto attrbeg = len;\n        parseFuncAttr();\n\n        auto argbeg = len;\n        put( '(' );\n        parseFuncArguments();\n        put( ')' );\n        if (attrbeg < argbeg)\n        {\n            // move function attributes behind arguments\n            shift( dst[argbeg - 1 .. argbeg] ); // trailing space\n            shift( dst[attrbeg .. argbeg - 1] ); // attributes\n            argbeg = attrbeg;\n        }\n        auto retbeg = len;\n        parseType();\n        put( ' ' );\n        // append name/delegate/function\n        if ( name.length )\n        {\n            if ( !contains( dst[0 .. len], name ) )\n                put( name );\n            else if ( shift( name ).ptr != name.ptr )\n            {\n                argbeg -= name.length;\n                retbeg -= name.length;\n            }\n        }\n        else if ( IsDelegate.yes == isdg )\n            put( \"delegate\" );\n        else\n            put( \"function\" );\n        // move arguments and attributes behind name\n        shift( dst[argbeg .. retbeg] );\n        return dst[beg..len];\n    }\n\n    static bool isCallConvention( char ch )\n    {\n        switch ( ch )\n        {\n            case 'F', 'U', 'V', 'W', 'R':\n                return true;\n            default:\n                return false;\n        }\n    }\n\n    /*\n    Value:\n        n\n        Number\n        i Number\n        N Number\n        e HexFloat\n        c HexFloat c HexFloat\n        A Number Value...\n\n    HexFloat:\n        NAN\n        INF\n        NINF\n        N HexDigits P Exponent\n        HexDigits P Exponent\n\n    Exponent:\n        N Number\n        Number\n\n    HexDigits:\n        HexDigit\n        HexDigit HexDigits\n\n    HexDigit:\n        Digit\n        A\n        B\n        C\n        D\n        E\n        F\n    */\n    void parseValue( char[] name = null, char type = '\\0' )\n    {\n        debug(trace) printf( \"parseValue+\\n\" );\n        debug(trace) scope(success) printf( \"parseValue-\\n\" );\n\n//        printf( \"*** %c\\n\", front );\n        switch ( front )\n        {\n        case 'n':\n            popFront();\n            put( \"null\" );\n            return;\n        case 'i':\n            popFront();\n            if ( '0' > front || '9' < front )\n                error( \"Number expected\" );\n            goto case;\n        case '0': .. case '9':\n            parseIntegerValue( name, type );\n            return;\n        case 'N':\n            popFront();\n            put( '-' );\n            parseIntegerValue( name, type );\n            return;\n        case 'e':\n            popFront();\n            parseReal();\n            return;\n        case 'c':\n            popFront();\n            parseReal();\n            put( '+' );\n            match( 'c' );\n            parseReal();\n            put( 'i' );\n            return;\n        case 'a': case 'w': case 'd':\n            char t = front;\n            popFront();\n            auto n = decodeNumber();\n            match( '_' );\n            put( '\"' );\n            foreach (i; 0..n)\n            {\n                auto a = ascii2hex( front ); popFront();\n                auto b = ascii2hex( front ); popFront();\n                auto v = cast(char)((a << 4) | b);\n                if (' ' <= v && v <= '~')   // ASCII printable\n                {\n                    put(v);\n                }\n                else\n                {\n                    put(\"\\\\x\");\n                    putAsHex(v, 2);\n                }\n            }\n            put( '\"' );\n            if ( 'a' != t )\n                put(t);\n            return;\n        case 'A':\n            // NOTE: This is kind of a hack.  An associative array literal\n            //       [1:2, 3:4] is represented as HiiA2i1i2i3i4, so the type\n            //       is \"Hii\" and the value is \"A2i1i2i3i4\".  Thus the only\n            //       way to determine that this is an AA value rather than an\n            //       array value is for the caller to supply the type char.\n            //       Hopefully, this will change so that the value is\n            //       \"H2i1i2i3i4\", rendering this unnecesary.\n            if ( 'H' == type )\n                goto LassocArray;\n            // A Number Value...\n            // An array literal. Value is repeated Number times.\n            popFront();\n            put( '[' );\n            auto n = decodeNumber();\n            foreach ( i; 0 .. n )\n            {\n                putComma(i);\n                parseValue();\n            }\n            put( ']' );\n            return;\n        case 'H':\n        LassocArray:\n            // H Number Value...\n            // An associative array literal. Value is repeated 2*Number times.\n            popFront();\n            put( '[' );\n            auto n = decodeNumber();\n            foreach ( i; 0 .. n )\n            {\n                putComma(i);\n                parseValue();\n                put(':');\n                parseValue();\n            }\n            put( ']' );\n            return;\n        case 'S':\n            // S Number Value...\n            // A struct literal. Value is repeated Number times.\n            popFront();\n            if ( name.length )\n                put( name );\n            put( '(' );\n            auto n = decodeNumber();\n            foreach ( i; 0 .. n )\n            {\n                putComma(i);\n                parseValue();\n            }\n            put( ')' );\n            return;\n        default:\n            error();\n        }\n    }\n\n\n    void parseIntegerValue( char[] name = null, char type = '\\0' )\n    {\n        debug(trace) printf( \"parseIntegerValue+\\n\" );\n        debug(trace) scope(success) printf( \"parseIntegerValue-\\n\" );\n\n        switch ( type )\n        {\n        case 'a': // char\n        case 'u': // wchar\n        case 'w': // dchar\n        {\n            auto val = sliceNumber();\n            auto num = decodeNumber( val );\n\n            switch ( num )\n            {\n            case '\\'':\n                put( \"'\\\\''\" );\n                return;\n            // \\\", \\?\n            case '\\\\':\n                put( \"'\\\\\\\\'\" );\n                return;\n            case '\\a':\n                put( \"'\\\\a'\" );\n                return;\n            case '\\b':\n                put( \"'\\\\b'\" );\n                return;\n            case '\\f':\n                put( \"'\\\\f'\" );\n                return;\n            case '\\n':\n                put( \"'\\\\n'\" );\n                return;\n            case '\\r':\n                put( \"'\\\\r'\" );\n                return;\n            case '\\t':\n                put( \"'\\\\t'\" );\n                return;\n            case '\\v':\n                put( \"'\\\\v'\" );\n                return;\n            default:\n                switch ( type )\n                {\n                case 'a':\n                    if ( num >= 0x20 && num < 0x7F )\n                    {\n                        put( '\\'' );\n                        put( cast(char)num );\n                        put( '\\'' );\n                        return;\n                    }\n                    put( \"\\\\x\" );\n                    putAsHex( num, 2 );\n                    return;\n                case 'u':\n                    put( \"'\\\\u\" );\n                    putAsHex( num, 4 );\n                    put( '\\'' );\n                    return;\n                case 'w':\n                    put( \"'\\\\U\" );\n                    putAsHex( num, 8 );\n                    put( '\\'' );\n                    return;\n                default:\n                    assert( 0 );\n                }\n            }\n        }\n        case 'b': // bool\n            put( decodeNumber() ? \"true\" : \"false\" );\n            return;\n        case 'h', 't', 'k': // ubyte, ushort, uint\n            put( sliceNumber() );\n            put( 'u' );\n            return;\n        case 'l': // long\n            put( sliceNumber() );\n            put( 'L' );\n            return;\n        case 'm': // ulong\n            put( sliceNumber() );\n            put( \"uL\" );\n            return;\n        default:\n            put( sliceNumber() );\n            return;\n        }\n    }\n\n\n    /*\n    TemplateArgs:\n        TemplateArg\n        TemplateArg TemplateArgs\n\n    TemplateArg:\n        TemplateArgX\n        H TemplateArgX\n\n    TemplateArgX:\n        T Type\n        V Type Value\n        S Number_opt QualifiedName\n        X ExternallyMangledName\n    */\n    void parseTemplateArgs()\n    {\n        debug(trace) printf( \"parseTemplateArgs+\\n\" );\n        debug(trace) scope(success) printf( \"parseTemplateArgs-\\n\" );\n\n    L_nextArg:\n        for ( size_t n = 0; true; n++ )\n        {\n            if ( front == 'H' )\n                popFront();\n\n            switch ( front )\n            {\n            case 'T':\n                popFront();\n                putComma(n);\n                parseType();\n                continue;\n            case 'V':\n                popFront();\n                putComma(n);\n                // NOTE: In the few instances where the type is actually\n                //       desired in the output it should precede the value\n                //       generated by parseValue, so it is safe to simply\n                //       decrement len and let put/append do its thing.\n                char t = front; // peek at type for parseValue\n                if ( t == 'Q' )\n                    t = peekBackref();\n                char[] name; silent( name = parseType() );\n                parseValue( name, t );\n                continue;\n            case 'S':\n                popFront();\n                putComma(n);\n\n                if ( mayBeMangledNameArg() )\n                {\n                    auto l = len;\n                    auto p = pos;\n                    auto b = brp;\n                    try\n                    {\n                        debug(trace) printf( \"may be mangled name arg\\n\" );\n                        parseMangledNameArg();\n                        continue;\n                    }\n                    catch ( ParseException e )\n                    {\n                        len = l;\n                        pos = p;\n                        brp = b;\n                        debug(trace) printf( \"not a mangled name arg\\n\" );\n                    }\n                }\n                if ( isDigit( front ) && isDigit( peek( 1 ) ) )\n                {\n                    // ambiguity: length followed by qualified name (starting with number)\n                    // try all possible pairs of numbers\n                    auto qlen = decodeNumber() / 10; // last digit needed for QualifiedName\n                    pos--;\n                    auto l = len;\n                    auto p = pos;\n                    auto b = brp;\n                    while ( qlen > 0 )\n                    {\n                        try\n                        {\n                            parseQualifiedName();\n                            if ( pos == p + qlen )\n                                continue L_nextArg;\n                        }\n                        catch ( ParseException e )\n                        {\n                        }\n                        qlen /= 10; // retry with one digit less\n                        pos = --p;\n                        len = l;\n                        brp = b;\n                    }\n                }\n                parseQualifiedName();\n                continue;\n            case 'X':\n                popFront();\n                putComma(n);\n                parseLName();\n                continue;\n            default:\n                return;\n            }\n        }\n    }\n\n\n    bool mayBeMangledNameArg()\n    {\n        debug(trace) printf( \"mayBeMangledNameArg+\\n\" );\n        debug(trace) scope(success) printf( \"mayBeMangledNameArg-\\n\" );\n\n        auto p = pos;\n        scope(exit) pos = p;\n        if ( isDigit( buf[pos] ) )\n        {\n            auto n = decodeNumber();\n            return n >= 4 &&\n                pos < buf.length && '_' == buf[pos++] &&\n                pos < buf.length && 'D' == buf[pos++] &&\n                isDigit( buf[pos] );\n        }\n        else\n        {\n            return pos < buf.length && '_' == buf[pos++] &&\n                   pos < buf.length && 'D' == buf[pos++] &&\n                   isSymbolNameFront();\n        }\n    }\n\n\n    void parseMangledNameArg()\n    {\n        debug(trace) printf( \"parseMangledNameArg+\\n\" );\n        debug(trace) scope(success) printf( \"parseMangledNameArg-\\n\" );\n\n        size_t n = 0;\n        if ( isDigit( front ) )\n            n = decodeNumber();\n        parseMangledName( false, n );\n    }\n\n\n    /*\n    TemplateInstanceName:\n        Number __T LName TemplateArgs Z\n    */\n    void parseTemplateInstanceName(bool hasNumber)\n    {\n        debug(trace) printf( \"parseTemplateInstanceName+\\n\" );\n        debug(trace) scope(success) printf( \"parseTemplateInstanceName-\\n\" );\n\n        auto sav = pos;\n        auto saveBrp = brp;\n        scope(failure)\n        {\n            pos = sav;\n            brp = saveBrp;\n        }\n        auto n = hasNumber ? decodeNumber() : 0;\n        auto beg = pos;\n        match( \"__T\" );\n        parseLName();\n        put( \"!(\" );\n        parseTemplateArgs();\n        match( 'Z' );\n        if ( hasNumber && pos - beg != n )\n            error( \"Template name length mismatch\" );\n        put( ')' );\n    }\n\n\n    bool mayBeTemplateInstanceName()\n    {\n        debug(trace) printf( \"mayBeTemplateInstanceName+\\n\" );\n        debug(trace) scope(success) printf( \"mayBeTemplateInstanceName-\\n\" );\n\n        auto p = pos;\n        scope(exit) pos = p;\n        auto n = decodeNumber();\n        return n >= 5 &&\n               pos < buf.length && '_' == buf[pos++] &&\n               pos < buf.length && '_' == buf[pos++] &&\n               pos < buf.length && 'T' == buf[pos++];\n    }\n\n\n    /*\n    SymbolName:\n        LName\n        TemplateInstanceName\n    */\n    void parseSymbolName()\n    {\n        debug(trace) printf( \"parseSymbolName+\\n\" );\n        debug(trace) scope(success) printf( \"parseSymbolName-\\n\" );\n\n        // LName -> Number\n        // TemplateInstanceName -> Number \"__T\"\n        switch ( front )\n        {\n        case '_':\n            // no length encoding for templates for new mangling\n            parseTemplateInstanceName(false);\n            return;\n\n        case '0': .. case '9':\n            if ( mayBeTemplateInstanceName() )\n            {\n                auto t = len;\n\n                try\n                {\n                    debug(trace) printf( \"may be template instance name\\n\" );\n                    parseTemplateInstanceName(true);\n                    return;\n                }\n                catch ( ParseException e )\n                {\n                    debug(trace) printf( \"not a template instance name\\n\" );\n                    len = t;\n                }\n            }\n            goto case;\n        case 'Q':\n            parseLName();\n            return;\n        default:\n            error();\n        }\n    }\n\n    // parse optional function arguments as part of a symbol name, i.e without return type\n    // if keepAttr, the calling convention and function attributes are not discarded, but returned\n    char[] parseFunctionTypeNoReturn( bool keepAttr = false )\n    {\n        // try to demangle a function, in case we are pointing to some function local\n        auto prevpos = pos;\n        auto prevlen = len;\n        auto prevbrp = brp;\n\n        char[] attr;\n        try\n        {\n            if ( 'M' == front )\n            {\n                // do not emit \"needs this\"\n                popFront();\n                parseModifier();\n            }\n            if ( isCallConvention( front ) )\n            {\n                // we don't want calling convention and attributes in the qualified name\n                parseCallConvention();\n                parseFuncAttr();\n                if ( keepAttr )\n                {\n                    attr = dst[prevlen .. len];\n                }\n                else\n                {\n                    len = prevlen;\n                }\n\n                put( '(' );\n                parseFuncArguments();\n                put( ')' );\n            }\n        }\n        catch ( ParseException )\n        {\n            // not part of a qualified name, so back up\n            pos = prevpos;\n            len = prevlen;\n            brp = prevbrp;\n            attr = null;\n        }\n        return attr;\n    }\n\n    /*\n    QualifiedName:\n        SymbolName\n        SymbolName QualifiedName\n    */\n    char[] parseQualifiedName()\n    {\n        debug(trace) printf( \"parseQualifiedName+\\n\" );\n        debug(trace) scope(success) printf( \"parseQualifiedName-\\n\" );\n        size_t  beg = len;\n        size_t  n   = 0;\n\n        do\n        {\n            if ( n++ )\n                put( '.' );\n            parseSymbolName();\n            parseFunctionTypeNoReturn();\n\n        } while ( isSymbolNameFront() );\n        return dst[beg .. len];\n    }\n\n\n    /*\n    MangledName:\n        _D QualifiedName Type\n        _D QualifiedName M Type\n    */\n    void parseMangledName( bool displayType, size_t n = 0 )\n    {\n        debug(trace) printf( \"parseMangledName+\\n\" );\n        debug(trace) scope(success) printf( \"parseMangledName-\\n\" );\n        char[] name = null;\n\n        auto end = pos + n;\n\n        eat( '_' );\n        match( 'D' );\n        do\n        {\n            size_t  beg = len;\n            size_t  nameEnd = len;\n            char[] attr;\n            do\n            {\n                if ( attr )\n                    remove( attr ); // dump attributes of parent symbols\n                if ( beg != len )\n                    put( '.' );\n                parseSymbolName();\n                nameEnd = len;\n                attr = parseFunctionTypeNoReturn( displayType );\n\n            } while ( isSymbolNameFront() );\n\n            if ( displayType )\n            {\n                attr = shift( attr );\n                nameEnd = len - attr.length;  // name includes function arguments\n            }\n            name = dst[beg .. nameEnd];\n\n            debug(info) printf( \"name (%.*s)\\n\", cast(int) name.length, name.ptr );\n            if ( 'M' == front )\n                popFront(); // has 'this' pointer\n\n            auto lastlen = len;\n            auto type = parseType();\n            if ( displayType )\n            {\n                if ( type.length )\n                    put( ' ' );\n                // sort (name,attr,type) -> (attr,type,name)\n                shift( name );\n            }\n            else\n            {\n                // remove type\n                assert( attr.length == 0 );\n                len = lastlen;\n            }\n            if ( pos >= buf.length || (n != 0 && pos >= end) )\n                return;\n\n            switch ( front )\n            {\n            case 'T': // terminators when used as template alias parameter\n            case 'V':\n            case 'S':\n            case 'Z':\n                return;\n            default:\n            }\n            put( '.' );\n\n        } while ( true );\n    }\n\n    void parseMangledName()\n    {\n        parseMangledName( AddType.yes == addType );\n    }\n\n    char[] doDemangle(alias FUNC)()\n    {\n        while ( true )\n        {\n            try\n            {\n                debug(info) printf( \"demangle(%.*s)\\n\", cast(int) buf.length, buf.ptr );\n                FUNC();\n                return dst[0 .. len];\n            }\n            catch ( OverflowException e )\n            {\n                debug(trace) printf( \"overflow... restarting\\n\" );\n                auto a = minBufSize;\n                auto b = 2 * dst.length;\n                auto newsz = a < b ? b : a;\n                debug(info) printf( \"growing dst to %lu bytes\\n\", newsz );\n                dst.length = newsz;\n                pos = len = brp = 0;\n                continue;\n            }\n            catch ( ParseException e )\n            {\n                debug(info)\n                {\n                    auto msg = e.toString();\n                    printf( \"error: %.*s\\n\", cast(int) msg.length, msg.ptr );\n                }\n                if ( dst.length < buf.length )\n                    dst.length = buf.length;\n                dst[0 .. buf.length] = buf[];\n                return dst[0 .. buf.length];\n            }\n            catch ( Exception e )\n            {\n                assert( false ); // no other exceptions thrown\n            }\n        }\n    }\n\n    char[] demangleName() nothrow\n    {\n        return doDemangle!parseMangledName();\n    }\n\n    char[] demangleType() nothrow\n    {\n        return doDemangle!parseType();\n    }\n}\n\n\n/**\n * Demangles D mangled names.  If it is not a D mangled name, it returns its\n * argument name.\n *\n * Params:\n *  buf = The string to demangle.\n *  dst = An optional destination buffer.\n *\n * Returns:\n *  The demangled name or the original string if the name is not a mangled D\n *  name.\n */\nchar[] demangle( const(char)[] buf, char[] dst = null ) nothrow pure @safe\n{\n    //return Demangle(buf, dst)();\n    auto d = Demangle!()(buf, dst);\n    return d.demangleName();\n}\n\n\n/**\n * Demangles a D mangled type.\n *\n * Params:\n *  buf = The string to demangle.\n *  dst = An optional destination buffer.\n *\n * Returns:\n *  The demangled type name or the original string if the name is not a\n *  mangled D type.\n*/\nchar[] demangleType( const(char)[] buf, char[] dst = null ) nothrow pure @safe\n{\n    auto d = Demangle!()(buf, dst);\n    return d.demangleType();\n}\n\n/**\n* reencode a mangled symbol name that might include duplicate occurrences\n* of the same identifier by replacing all but the first occurence with\n* a back reference.\n*\n* Params:\n*  mangled = The mangled string representing the type\n*\n* Returns:\n*  The mangled name with deduplicated identifiers\n*/\nchar[] reencodeMangled(const(char)[] mangled) nothrow pure @safe\n{\n    static struct PrependHooks\n    {\n        size_t lastpos;\n        char[] result;\n        size_t[const(char)[]] idpos; // identifier positions\n\n        static struct Replacement\n        {\n            size_t pos;    // postion in original mangled string\n            size_t respos; // postion in result string\n        }\n        Replacement [] replacements;\n\n    pure @safe:\n        size_t positionInResult(size_t pos)\n        {\n            foreach_reverse (r; replacements)\n                if (pos >= r.pos)\n                    return r.respos + pos - r.pos;\n            return pos;\n        }\n\n        alias Remangle = Demangle!(PrependHooks);\n\n        void flushPosition(ref Remangle d)\n        {\n            if (lastpos < d.pos)\n            {\n                result ~= d.buf[lastpos .. d.pos];\n            }\n            else if (lastpos > d.pos)\n            {\n                // roll back to earlier position\n                while (replacements.length > 0 && replacements[$-1].pos > d.pos)\n                    replacements = replacements[0 .. $-1];\n\n                if (replacements.length > 0)\n                    result.length = replacements[$-1].respos + d.pos - replacements[$-1].pos;\n                else\n                    result.length = d.pos;\n            }\n        }\n\n        bool parseLName(ref Remangle d)\n        {\n            flushPosition(d);\n\n            auto reslen = result.length;\n            auto refpos = d.pos;\n            if (d.front == 'Q')\n            {\n                size_t npos;\n                {\n                    scope(exit) result.length = reslen; // remove all intermediate additions\n                    // only support identifier back references\n                    d.popFront();\n                    size_t n = d.decodeBackref();\n                    if (!n || n > refpos)\n                        d.error(\"invalid back reference\");\n\n                    auto savepos = d.pos;\n                    scope(exit) d.pos = savepos;\n                    size_t srcpos = refpos - n;\n\n                    auto idlen = d.decodeNumber();\n                    if (d.pos + idlen > d.buf.length)\n                        d.error(\"invalid back reference\");\n                    auto id = d.buf[d.pos .. d.pos + idlen];\n                    auto pid = id in idpos;\n                    if (!pid)\n                        d.error(\"invalid back reference\");\n                    npos = positionInResult(*pid);\n                }\n                encodeBackref(reslen - npos);\n                replacements ~= Replacement(d.pos, result.length);\n            }\n            else\n            {\n                auto n = d.decodeNumber();\n                if (!n || n > d.buf.length || n > d.buf.length - d.pos)\n                    d.error(\"LName too shot or too long\");\n                auto id = d.buf[d.pos .. d.pos + n];\n                d.pos += n;\n                if (auto pid = id in idpos)\n                {\n                    size_t npos = positionInResult(*pid);\n                    result.length = reslen;\n                    encodeBackref(reslen - npos);\n                    replacements ~= Replacement(d.pos, result.length);\n                }\n                else\n                {\n                    idpos[id] = refpos;\n                    result ~= d.buf[refpos .. d.pos];\n                }\n            }\n            lastpos = d.pos;\n            return true;\n        }\n\n        char[] parseType( ref Remangle d, char[] name = null )\n        {\n            if (d.front != 'Q')\n                return null;\n\n            flushPosition(d);\n\n            auto refPos = d.pos;\n            d.popFront();\n            auto n = d.decodeBackref();\n            if (n == 0 || n > refPos)\n                d.error(\"invalid back reference\");\n\n            size_t npos = positionInResult(refPos - n);\n            size_t reslen = result.length;\n            encodeBackref(reslen - npos);\n\n            lastpos = d.pos;\n            return result[reslen .. $]; // anything but null\n        }\n\n        void encodeBackref(size_t relpos)\n        {\n            result ~= 'Q';\n            enum base = 26;\n            size_t div = 1;\n            while (relpos >= div * base)\n                div *= base;\n            while (div >= base)\n            {\n                auto dig = (relpos / div);\n                result ~= cast(char)('A' + dig);\n                relpos -= dig * div;\n                div /= base;\n            }\n            result ~= cast(char)('a' + relpos);\n        }\n    }\n\n    auto d = Demangle!(PrependHooks)(mangled, null);\n    d.hooks = PrependHooks();\n    d.mute = true; // no demangled output\n    try\n    {\n        d.parseMangledName();\n        if (d.hooks.lastpos < d.pos)\n            d.hooks.result ~= d.buf[d.hooks.lastpos .. d.pos];\n        return d.hooks.result;\n    }\n    catch (Exception)\n    {\n        // overflow exception cannot occur\n        return mangled.dup;\n    }\n}\n\n/**\n * Mangles a D symbol.\n *\n * Params:\n *  T = The type of the symbol.\n *  fqn = The fully qualified name of the symbol.\n *  dst = An optional destination buffer.\n *\n * Returns:\n *  The mangled name for a symbols of type T and the given fully\n *  qualified name.\n */\nchar[] mangle(T)(const(char)[] fqn, char[] dst = null) @safe pure nothrow\n{\n    import core.internal.string : numDigits, unsignedToTempString;\n\n    static struct DotSplitter\n    {\n    @safe pure nothrow:\n        const(char)[] s;\n\n        @property bool empty() const { return !s.length; }\n\n        @property const(char)[] front() const\n        {\n            immutable i = indexOfDot();\n            return i == -1 ? s[0 .. $] : s[0 .. i];\n        }\n\n        void popFront()\n        {\n            immutable i = indexOfDot();\n            s = i == -1 ? s[$ .. $] : s[i+1 .. $];\n        }\n\n        private ptrdiff_t indexOfDot() const\n        {\n            foreach (i, c; s) if (c == '.') return i;\n            return -1;\n        }\n    }\n\n    size_t len = \"_D\".length;\n    foreach (comp; DotSplitter(fqn))\n        len += numDigits(comp.length) + comp.length;\n    len += T.mangleof.length;\n    if (dst.length < len) dst.length = len;\n\n    size_t i = \"_D\".length;\n    dst[0 .. i] = \"_D\";\n    foreach (comp; DotSplitter(fqn))\n    {\n        const ndigits = numDigits(comp.length);\n        unsignedToTempString(comp.length, dst[i .. i + ndigits]);\n        i += ndigits;\n        dst[i .. i + comp.length] = comp[];\n        i += comp.length;\n    }\n    dst[i .. i + T.mangleof.length] = T.mangleof[];\n    i += T.mangleof.length;\n\n    static if (hasTypeBackRef)\n        return reencodeMangled(dst[0 .. i]);\n    else\n        return dst[0 .. i];\n}\n\n\n///\n@safe pure nothrow unittest\n{\n    assert(mangle!int(\"a.b\") == \"_D1a1bi\");\n    assert(mangle!(char[])(\"test.foo\") == \"_D4test3fooAa\");\n    assert(mangle!(int function(int))(\"a.b\") == \"_D1a1bPFiZi\");\n}\n\n@safe pure nothrow unittest\n{\n    static assert(mangle!int(\"a.b\") == \"_D1a1bi\");\n\n    auto buf = new char[](10);\n    buf = mangle!int(\"a.b\", buf);\n    assert(buf == \"_D1a1bi\");\n    buf = mangle!(char[])(\"test.foo\", buf);\n    assert(buf == \"_D4test3fooAa\");\n    buf = mangle!(real delegate(int))(\"modµ.dg\");\n    assert(buf == \"_D5modµ2dgDFiZe\", buf);\n}\n\n\n/**\n * Mangles a D function.\n *\n * Params:\n *  T = function pointer type.\n *  fqn = The fully qualified name of the symbol.\n *  dst = An optional destination buffer.\n *\n * Returns:\n *  The mangled name for a function with function pointer type T and\n *  the given fully qualified name.\n */\nchar[] mangleFunc(T:FT*, FT)(const(char)[] fqn, char[] dst = null) @safe pure nothrow if (is(FT == function))\n{\n    static if (isExternD!FT)\n    {\n        return mangle!FT(fqn, dst);\n    }\n    else static if (hasPlainMangling!FT)\n    {\n        dst.length = fqn.length;\n        dst[] = fqn[];\n        return dst;\n    }\n    else static if (isExternCPP!FT)\n    {\n        static assert(0, \"Can't mangle extern(C++) functions.\");\n    }\n    else\n    {\n        static assert(0, \"Can't mangle function with unknown linkage (\"~FT.stringof~\").\");\n    }\n}\n\nprivate enum hasTypeBackRef = (int function(void**,void**)).mangleof[$-4 .. $] == \"QdZi\";\n\n///\n@safe pure nothrow unittest\n{\n    assert(mangleFunc!(int function(int))(\"a.b\") == \"_D1a1bFiZi\");\n    static if (hasTypeBackRef)\n    {\n        assert(mangleFunc!(int function(Object))(\"object.Object.opEquals\") == \"_D6object6Object8opEqualsFCQsZi\");\n        assert(mangleFunc!(int function(Object, Object))(\"object.Object.opEquals\") == \"_D6object6Object8opEqualsFCQsQdZi\");\n    }\n    else\n    {\n        auto mngl = mangleFunc!(int function(Object))(\"object.Object.opEquals\");\n        assert(mngl == \"_D6object6Object8opEqualsFC6ObjectZi\");\n        auto remngl = reencodeMangled(mngl);\n        assert(remngl == \"_D6object6Object8opEqualsFCQsZi\");\n    }\n    // trigger back tracking with ambiguity on '__T', template or identifier\n    assert(reencodeMangled(\"_D3std4conv4conv7__T3std4convi\") == \"_D3std4convQf7__T3stdQpi\");\n}\n\n@safe pure nothrow unittest\n{\n    int function(lazy int[], ...) fp;\n    assert(mangle!(typeof(fp))(\"demangle.test\") == \"_D8demangle4testPFLAiYi\");\n    assert(mangle!(typeof(*fp))(\"demangle.test\") == \"_D8demangle4testFLAiYi\");\n}\n\nprivate template isExternD(FT) if (is(FT == function))\n{\n    enum isExternD = __traits(getLinkage, FT) == \"D\";\n}\n\nprivate template isExternCPP(FT) if (is(FT == function))\n{\n    enum isExternCPP = __traits(getLinkage, FT) == \"C++\";\n}\n\nprivate template hasPlainMangling(FT) if (is(FT == function))\n{\n    enum lnk = __traits(getLinkage, FT);\n    // C || Pascal || Windows\n    enum hasPlainMangling = lnk == \"C\" || lnk == \"Pascal\" || lnk == \"Windows\";\n}\n\n@safe pure nothrow unittest\n{\n    static extern(D) void fooD();\n    static extern(C) void fooC();\n    static extern(Pascal) void fooP();\n    static extern(Windows) void fooW();\n    static extern(C++) void fooCPP();\n\n    bool check(FT)(bool isD, bool isCPP, bool isPlain)\n    {\n        return isExternD!FT == isD && isExternCPP!FT == isCPP &&\n            hasPlainMangling!FT == isPlain;\n    }\n    static assert(check!(typeof(fooD))(true, false, false));\n    static assert(check!(typeof(fooC))(false, false, true));\n    static assert(check!(typeof(fooP))(false, false, true));\n    static assert(check!(typeof(fooW))(false, false, true));\n    static assert(check!(typeof(fooCPP))(false, true, false));\n\n    static assert(__traits(compiles, mangleFunc!(typeof(&fooD))(\"\")));\n    static assert(__traits(compiles, mangleFunc!(typeof(&fooC))(\"\")));\n    static assert(__traits(compiles, mangleFunc!(typeof(&fooP))(\"\")));\n    static assert(__traits(compiles, mangleFunc!(typeof(&fooW))(\"\")));\n    static assert(!__traits(compiles, mangleFunc!(typeof(&fooCPP))(\"\")));\n}\n\n/***\n * C name mangling is done by adding a prefix on some platforms.\n */\nversion (Win32)\n    enum string cPrefix = \"_\";\nelse version (Darwin)\n    enum string cPrefix = \"_\";\nelse\n    enum string cPrefix = \"\";\n\nversion (unittest)\n{\n    immutable string[2][] table =\n    [\n        [\"printf\", \"printf\"],\n        [\"_foo\", \"_foo\"],\n        [\"_D88\", \"_D88\"],\n        [\"_D4test3fooAa\", \"char[] test.foo\"],\n        [\"_D8demangle8demangleFAaZAa\", \"char[] demangle.demangle(char[])\"],\n        [\"_D6object6Object8opEqualsFC6ObjectZi\", \"int object.Object.opEquals(Object)\"],\n        [\"_D4test2dgDFiYd\", \"double delegate(int, ...) test.dg\"],\n        [\"_D4test2dgDxFNfiYd\", \"double delegate(int, ...) @safe const test.dg\"],\n        //[\"_D4test58__T9factorialVde67666666666666860140VG5aa5_68656c6c6fVPvnZ9factorialf\", \"\"],\n        //[\"_D4test101__T9factorialVde67666666666666860140Vrc9a999999999999d9014000000000000000c00040VG5aa5_68656c6c6fVPvnZ9factorialf\", \"\"],\n        [\"_D4test34__T3barVG3uw3_616263VG3wd3_646566Z1xi\", \"int test.bar!(\\\"abc\\\"w, \\\"def\\\"d).x\"],\n        [\"_D8demangle4testFLC6ObjectLDFLiZiZi\", \"int demangle.test(lazy Object, lazy int delegate(lazy int))\"],\n        [\"_D8demangle4testFAiXi\", \"int demangle.test(int[]...)\"],\n        [\"_D8demangle4testFAiYi\", \"int demangle.test(int[], ...)\"],\n        [\"_D8demangle4testFLAiXi\", \"int demangle.test(lazy int[]...)\"],\n        [\"_D8demangle4testFLAiYi\", \"int demangle.test(lazy int[], ...)\"],\n        [\"_D6plugin8generateFiiZAya\", \"immutable(char)[] plugin.generate(int, int)\"],\n        [\"_D6plugin8generateFiiZAxa\", \"const(char)[] plugin.generate(int, int)\"],\n        [\"_D6plugin8generateFiiZAOa\", \"shared(char)[] plugin.generate(int, int)\"],\n        [\"_D8demangle3fnAFZ3fnBMFZv\", \"void demangle.fnA().fnB()\"],\n        [\"_D8demangle4mainFZ1S3fnCMFZv\", \"void demangle.main().S.fnC()\"],\n        [\"_D8demangle4mainFZ1S3fnDMFZv\", \"void demangle.main().S.fnD()\"],\n        [\"_D8demangle20__T2fnVAiA4i1i2i3i4Z2fnFZv\", \"void demangle.fn!([1, 2, 3, 4]).fn()\"],\n        [\"_D8demangle10__T2fnVi1Z2fnFZv\", \"void demangle.fn!(1).fn()\"],\n        [\"_D8demangle26__T2fnVS8demangle1SS2i1i2Z2fnFZv\", \"void demangle.fn!(demangle.S(1, 2)).fn()\"],\n        [\"_D8demangle13__T2fnVeeNANZ2fnFZv\", \"void demangle.fn!(real.nan).fn()\"],\n        [\"_D8demangle14__T2fnVeeNINFZ2fnFZv\", \"void demangle.fn!(-real.infinity).fn()\"],\n        [\"_D8demangle13__T2fnVeeINFZ2fnFZv\", \"void demangle.fn!(real.infinity).fn()\"],\n        [\"_D8demangle21__T2fnVHiiA2i1i2i3i4Z2fnFZv\", \"void demangle.fn!([1:2, 3:4]).fn()\"],\n        [\"_D8demangle2fnFNgiZNgi\", \"inout(int) demangle.fn(inout(int))\"],\n        [\"_D8demangle29__T2fnVa97Va9Va0Vu257Vw65537Z2fnFZv\", \"void demangle.fn!('a', '\\\\t', \\\\x00, '\\\\u0101', '\\\\U00010001').fn()\"],\n        [\"_D2gc11gctemplates56__T8mkBitmapTS3std5range13__T4iotaTiTiZ4iotaFiiZ6ResultZ8mkBitmapFNbNiNfPmmZv\",\n         \"nothrow @nogc @safe void gc.gctemplates.mkBitmap!(std.range.iota!(int, int).iota(int, int).Result).mkBitmap(ulong*, ulong)\"],\n        [\"_D8serenity9persister6Sqlite69__T15SqlitePersisterTS8serenity9persister6Sqlite11__unittest6FZ4TestZ15SqlitePersister12__T7opIndexZ7opIndexMFmZS8serenity9persister6Sqlite11__unittest6FZ4Test\",\n         \"serenity.persister.Sqlite.__unittest6().Test serenity.persister.Sqlite.SqlitePersister!(serenity.persister.Sqlite.__unittest6().Test).SqlitePersister.opIndex!().opIndex(ulong)\"],\n        [\"_D8bug100274mainFZ5localMFZi\",\"int bug10027.main().local()\"],\n        [\"_D8demangle4testFNhG16gZv\", \"void demangle.test(__vector(byte[16]))\"],\n        [\"_D8demangle4testFNhG8sZv\", \"void demangle.test(__vector(short[8]))\"],\n        [\"_D8demangle4testFNhG4iZv\", \"void demangle.test(__vector(int[4]))\"],\n        [\"_D8demangle4testFNhG2lZv\", \"void demangle.test(__vector(long[2]))\"],\n        [\"_D8demangle4testFNhG4fZv\", \"void demangle.test(__vector(float[4]))\"],\n        [\"_D8demangle4testFNhG2dZv\", \"void demangle.test(__vector(double[2]))\"],\n        [\"_D8demangle4testFNhG4fNhG4fZv\", \"void demangle.test(__vector(float[4]), __vector(float[4]))\"],\n        [\"_D8bug1119234__T3fooS23_D8bug111924mainFZ3bariZ3fooMFZv\",\"void bug11192.foo!(bug11192.main().bar).foo()\"],\n        [\"_D13libd_demangle12__ModuleInfoZ\", \"libd_demangle.__ModuleInfo\"],\n        [\"_D15TypeInfo_Struct6__vtblZ\", \"TypeInfo_Struct.__vtbl\"],\n        [\"_D3std5stdio12__ModuleInfoZ\", \"std.stdio.__ModuleInfo\"],\n        [\"_D3std6traits15__T8DemangleTkZ8Demangle6__initZ\", \"std.traits.Demangle!(uint).Demangle.__init\"],\n        [\"_D3foo3Bar7__ClassZ\", \"foo.Bar.__Class\"],\n        [\"_D3foo3Bar6__vtblZ\", \"foo.Bar.__vtbl\"],\n        [\"_D3foo3Bar11__interfaceZ\", \"foo.Bar.__interface\"],\n        [\"_D3foo7__arrayZ\", \"foo.__array\"],\n        [\"_D8link657428__T3fooVE8link65746Methodi0Z3fooFZi\", \"int link6574.foo!(0).foo()\"],\n        [\"_D8link657429__T3fooHVE8link65746Methodi0Z3fooFZi\", \"int link6574.foo!(0).foo()\"],\n        [\"_D4test22__T4funcVAyaa3_610a62Z4funcFNaNbNiNfZAya\", `pure nothrow @nogc @safe immutable(char)[] test.func!(\"a\\x0ab\").func()`],\n        [\"_D3foo3barFzkZzi\", \"cent foo.bar(ucent)\"],\n        [\"_D5bug145Class3fooMFNlZPv\", \"scope void* bug14.Class.foo()\"],\n        [\"_D5bug145Class3barMFNjZPv\", \"return void* bug14.Class.bar()\"],\n        [\"_D5bug143fooFMPvZPv\", \"void* bug14.foo(scope void*)\"],\n        [\"_D5bug143barFMNkPvZPv\", \"void* bug14.bar(scope return void*)\"],\n        [\"_D3std5range15__T4iotaTtTtTtZ4iotaFtttZ6Result7opIndexMNgFNaNbNiNfmZNgt\",\n         \"inout pure nothrow @nogc @safe inout(ushort) std.range.iota!(ushort, ushort, ushort).iota(ushort, ushort, ushort).Result.opIndex(ulong)\"],\n        [\"_D3std6format77__T6getNthVAyaa13_696e7465676572207769647468S233std6traits10isIntegralTiTkTkZ6getNthFNaNfkkkZi\",\n         \"pure @safe int std.format.getNth!(\\\"integer width\\\", std.traits.isIntegral, int, uint, uint).getNth(uint, uint, uint)\"],\n        [\"_D3std11parallelism42__T16RoundRobinBufferTDFKAaZvTDxFNaNdNeZbZ16RoundRobinBuffer5primeMFZv\",\n         \"void std.parallelism.RoundRobinBuffer!(void delegate(ref char[]), bool delegate() pure @property @trusted const).RoundRobinBuffer.prime()\"],\n        // Lname '0'\n        [\"_D3std9algorithm9iteration__T9MapResultSQBmQBlQBe005stripTAAyaZQBi7opSliceMFNaNbNiNfmmZSQDiQDhQDa__TQCtSQDyQDxQDq00QCmTQCjZQDq\",\n         \"pure nothrow @nogc @safe std.algorithm.iteration.MapResult!(std.algorithm.iteration.__anonymous.strip, \"\n        ~\"immutable(char)[][]).MapResult std.algorithm.iteration.MapResult!(std.algorithm.iteration.strip, immutable(char)[][]).MapResult.opSlice(ulong, ulong)\"],\n\n        // back references\n        [\"_D4core4stdc5errnoQgFZi\", \"int core.stdc.errno.errno()\"], // identifier back reference\n        [\"_D4testFS10structnameQnZb\", \"bool test(structname, structname)\"], // type back reference\n        [\"_D3std11parallelism__T4TaskS8unittest3cmpTAyaTQeZQBb6__dtorMFNfZv\",\n        \"@safe void std.parallelism.Task!(unittest.cmp, immutable(char)[], immutable(char)[]).Task.__dtor()\"],\n        // 1.s.s.foo from https://issues.dlang.org/show_bug.cgi?id=15831\n        [\"_D13testexpansion44__T1sTS13testexpansion8__T1sTiZ1sFiZ6ResultZ1sFS13testexpansion8__T1sTiZ1sFiZ6ResultZ6Result3fooMFNaNfZv\",\n         \"pure @safe void testexpansion.s!(testexpansion.s!(int).s(int).Result).s(testexpansion.s!(int).s(int).Result).Result.foo()\"],\n        [\"_D13testexpansion__T1sTSQw__TQjTiZQoFiZ6ResultZQBbFQBcZQq3fooMFNaNfZv\",\n         \"pure @safe void testexpansion.s!(testexpansion.s!(int).s(int).Result).s(testexpansion.s!(int).s(int).Result).Result.foo()\"],\n        // ambiguity on 'V', template value argument or pascal function\n        [\"_D3std4conv__T7enumRepTyAaTEQBa12experimental9allocator15building_blocks15stats_collector7OptionsVQCti64ZQDnyQDh\",\n         \"immutable(char[]) std.conv.enumRep!(immutable(char[]), std.experimental.allocator.building_blocks.stats_collector.Options, 64).enumRep\"],\n        // symbol back reference to location with symbol back reference\n        [\"_D3std12experimental9allocator6common__T10reallocateTSQCaQBzQBo15building_blocks17kernighan_ritchie__T8KRRegionTSQEhQEgQDvQCh14null_allocator13NullAllocatorZQCdZQErFNaNbNiKQEpKAvmZb\",\n         \"pure nothrow @nogc bool std.experimental.allocator.common.reallocate!(std.experimental.allocator.building_blocks.kernighan_ritchie.KRRegion!(\"\n        ~\"std.experimental.allocator.building_blocks.null_allocator.NullAllocator).KRRegion).reallocate(ref \"\n        ~\"std.experimental.allocator.building_blocks.kernighan_ritchie.KRRegion!(std.experimental.allocator.building_blocks.null_allocator.NullAllocator).KRRegion, ref void[], ulong)\"],\n        [\"_D3std9exception__T11doesPointToTASQBh5regex8internal2ir10NamedGroupTQBkTvZQCeFNaNbNiNeKxASQDlQCeQCbQBvQBvKxQtZb\",\n         \"pure nothrow @nogc @trusted bool std.exception.doesPointTo!(std.regex.internal.ir.NamedGroup[], \"\n        ~\"std.regex.internal.ir.NamedGroup[], void).doesPointTo(ref const(std.regex.internal.ir.NamedGroup[]), ref const(std.regex.internal.ir.NamedGroup[]))\"],\n        [\"_D3std9algorithm9iteration__T14SplitterResultS_DQBu3uni7isWhiteFNaNbNiNfwZbTAyaZQBz9__xtoHashFNbNeKxSQDvQDuQDn__TQDgS_DQEnQCtQCsQCnTQCeZQEdZm\",\n         \"nothrow @trusted ulong std.algorithm.iteration.SplitterResult!(std.uni.isWhite(dchar), immutable(char)[]).SplitterResult.\"\n        ~\"__xtoHash(ref const(std.algorithm.iteration.SplitterResult!(std.uni.isWhite, immutable(char)[]).SplitterResult))\"],\n        [\"_D3std8typecons__T7TypedefTCQBaQz19__unittestL6513_208FNfZ7MyClassVQBonVAyanZQCh6__ctorMFNaNbNcNiNfQCuZSQDyQDx__TQDrTQDmVQDqnVQCcnZQEj\",\n         \"pure nothrow ref @nogc @safe std.typecons.Typedef!(std.typecons.__unittestL6513_208().MyClass, null, null).Typedef \"\n        ~\"std.typecons.Typedef!(std.typecons.__unittestL6513_208().MyClass, null, null).Typedef.__ctor(std.typecons.__unittestL6513_208().MyClass)\"],\n        [\"_D3std6getopt__TQkTAyaTDFNaNbNiNfQoZvTQtTDQsZQBnFNfKAQBiQBlQBkQBrQyZSQCpQCo12GetoptResult\",\n         \"@safe std.getopt.GetoptResult std.getopt.getopt!(immutable(char)[], void delegate(immutable(char)[]) pure nothrow @nogc @safe, \"\n        ~\"immutable(char)[], void delegate(immutable(char)[]) pure nothrow @nogc @safe).\"\n        ~\"getopt(ref immutable(char)[][], immutable(char)[], void delegate(immutable(char)[]) pure nothrow @nogc @safe, \"\n        ~\"immutable(char)[], void delegate(immutable(char)[]) pure nothrow @nogc @safe)\"],\n        [\"_D3std5regex8internal9kickstart__T7ShiftOrTaZQl11ShiftThread__T3setS_DQCqQCpQCmQCg__TQBzTaZQCfQBv10setInvMaskMFNaNbNiNfkkZvZQCjMFNaNfwZv\",\n         \"pure @safe void std.regex.internal.kickstart.ShiftOr!(char).ShiftOr.ShiftThread.set!(std.regex.internal.kickstart.ShiftOr!(char).ShiftOr.ShiftThread.setInvMask(uint, uint)).set(dchar)\"],\n        [\"_D3std5stdio4File__T8lockImplX10LockFileExTykZQBaMFmmykZi\", // C function as template alias parameter\n         \"int std.stdio.File.lockImpl!(LockFileEx, immutable(uint)).lockImpl(ulong, ulong, immutable(uint))\"],\n        // back reference for type in template AA parameter value\n        [\"_D3std9algorithm9iteration__T12FilterResultSQBq8typecons__T5TupleTiVAyaa1_61TiVQla1_62TiVQva1_63ZQBm__T6renameVHiQBtA2i0a1_63i2a1_61ZQBeMFNcZ9__lambda1TAiZQEw9__xtoHashFNbNeKxSQGsQGrQGk__TQGdSQHiQFs__TQFmTiVQFja1_61TiVQFua1_62TiVQGfa1_63ZQGx__TQFlVQFhA2i0a1_63i2a1_61ZQGjMFNcZQFfTQEyZQJvZm\",\n         `nothrow @trusted ulong std.algorithm.iteration.FilterResult!(std.typecons.Tuple!(int, \"a\", int, \"b\", int, \"c\").`\n        ~`Tuple.rename!([0:\"c\", 2:\"a\"]).rename().__lambda1, int[]).FilterResult.__xtoHash(ref const(std.algorithm.iteration.`\n        ~`FilterResult!(std.typecons.Tuple!(int, \"a\", int, \"b\", int, \"c\").Tuple.rename!([0:\"c\", 2:\"a\"]).rename().__lambda1, int[]).FilterResult))`],\n    ];\n\n\n    template staticIota(int x)\n    {\n        template Seq(T...){ alias Seq = T; }\n\n        static if (x == 0)\n            alias staticIota = Seq!();\n        else\n            alias staticIota = Seq!(staticIota!(x - 1), x - 1);\n    }\n}\n@safe pure nothrow unittest\n{\n    foreach ( i, name; table )\n    {\n        auto r = demangle( name[0] );\n        assert( r == name[1],\n                \"demangled \\\"\" ~ name[0] ~ \"\\\" as \\\"\" ~ r ~ \"\\\" but expected \\\"\" ~ name[1] ~ \"\\\"\");\n    }\n    foreach ( i; staticIota!(table.length) )\n    {\n        enum r = demangle( table[i][0] );\n        static assert( r == table[i][1],\n                \"demangled \\\"\" ~ table[i][0] ~ \"\\\" as \\\"\" ~ r ~ \"\\\" but expected \\\"\" ~ table[i][1] ~ \"\\\"\");\n    }\n\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=18531\n        auto symbol = `_D3std3uni__T6toCaseS_DQvQt12toLowerIndexFNaNbNiNewZtVii1043S_DQCjQCi10toLowerTabFNaNbNiNemZwSQDo5ascii7toLowerTAyaZQDzFNaNeQmZ14__foreachbody2MFNaNeKmKwZ14__foreachbody3MFNaNeKwZi`;\n        auto demangled = `pure @trusted int std.uni.toCase!(std.uni.toLowerIndex(dchar), 1043, std.uni.toLowerTab(ulong), std.ascii.toLower, immutable(char)[]).toCase(immutable(char)[]).__foreachbody2(ref ulong, ref dchar).__foreachbody3(ref dchar)`;\n        auto dst = new char[200];\n        auto ret = demangle( symbol, dst);\n        assert( ret == demangled );\n    }\n}\n\nunittest\n{\n    // https://issues.dlang.org/show_bug.cgi?id=18300\n    string s = demangle.mangleof;\n    foreach (i; 1..77)\n    {\n        char[] buf = new char[i];\n        auto ds = demangle(s, buf);\n        assert(ds == \"pure nothrow @safe char[] core.demangle.demangle(const(char)[], char[])\");\n    }\n}\n\nunittest\n{\n    // https://issues.dlang.org/show_bug.cgi?id=18300\n    string s = \"_D1\";\n    string expected = \"int \";\n    foreach (_; 0..10_000)\n    {\n        s ~= \"a1\";\n        expected ~= \"a.\";\n    }\n    s ~= \"FiZi\";\n    expected ~= \"F\";\n    assert(s.demangle == expected);\n}\n\n/*\n *\n */\nstring decodeDmdString( const(char)[] ln, ref size_t p ) nothrow pure @safe\n{\n    string s;\n    uint zlen, zpos;\n\n    // decompress symbol\n    while ( p < ln.length )\n    {\n        int ch = cast(ubyte) ln[p++];\n        if ( (ch & 0xc0) == 0xc0 )\n        {\n            zlen = (ch & 0x7) + 1;\n            zpos = ((ch >> 3) & 7) + 1; // + zlen;\n            if ( zpos > s.length )\n                break;\n            s ~= s[$ - zpos .. $ - zpos + zlen];\n        }\n        else if ( ch >= 0x80 )\n        {\n            if ( p >= ln.length )\n                break;\n            int ch2 = cast(ubyte) ln[p++];\n            zlen = (ch2 & 0x7f) | ((ch & 0x38) << 4);\n            if ( p >= ln.length )\n                break;\n            int ch3 = cast(ubyte) ln[p++];\n            zpos = (ch3 & 0x7f) | ((ch & 7) << 7);\n            if ( zpos > s.length )\n                break;\n            s ~= s[$ - zpos .. $ - zpos + zlen];\n        }\n        else if ( Demangle!().isAlpha(cast(char)ch) || Demangle!().isDigit(cast(char)ch) || ch == '_' )\n            s ~= cast(char) ch;\n        else\n        {\n            p--;\n            break;\n        }\n    }\n    return s;\n}\n\n// locally purified for internal use here only\nextern (C) private\n{\n    pure @trusted @nogc nothrow pragma(mangle, \"fakePureReprintReal\") void pureReprintReal(char[] nptr);\n\n    void fakePureReprintReal(char[] nptr)\n    {\n        import core.stdc.stdlib : strtold;\n        import core.stdc.stdio : snprintf;\n        import core.stdc.errno : errno;\n\n        const err = errno;\n        real val = strtold(nptr.ptr, null);\n        snprintf(nptr.ptr, nptr.length, \"%#Lg\", val);\n        errno = err;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/exception.d",
    "content": "/**\n    The exception module defines all system-level exceptions and provides a\n    mechanism to alter system-level error handling.\n\n    Copyright: Copyright Sean Kelly 2005 - 2013.\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   Sean Kelly and $(HTTP jmdavisprog.com, Jonathan M Davis)\n    Source:    $(DRUNTIMESRC core/_exception.d)\n*/\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule core.exception;\n\n/**\n * Thrown on a range error.\n */\nclass RangeError : Error\n{\n    @safe pure nothrow this( string file = __FILE__, size_t line = __LINE__, Throwable next = null )\n    {\n        super( \"Range violation\", file, line, next );\n    }\n}\n\nunittest\n{\n    {\n        auto re = new RangeError();\n        assert(re.file == __FILE__);\n        assert(re.line == __LINE__ - 2);\n        assert(re.next is null);\n        assert(re.msg == \"Range violation\");\n    }\n\n    {\n        auto re = new RangeError(\"hello\", 42, new Exception(\"It's an Exception!\"));\n        assert(re.file == \"hello\");\n        assert(re.line == 42);\n        assert(re.next !is null);\n        assert(re.msg == \"Range violation\");\n    }\n}\n\n\n/**\n * Thrown on an assert error.\n */\nclass AssertError : Error\n{\n    @safe pure nothrow this( string file, size_t line )\n    {\n        this(cast(Throwable)null, file, line);\n    }\n\n    @safe pure nothrow this( Throwable next, string file = __FILE__, size_t line = __LINE__ )\n    {\n        this( \"Assertion failure\", file, line, next);\n    }\n\n    @safe pure nothrow this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null )\n    {\n        super( msg, file, line, next );\n    }\n}\n\nunittest\n{\n    {\n        auto ae = new AssertError(\"hello\", 42);\n        assert(ae.file == \"hello\");\n        assert(ae.line == 42);\n        assert(ae.next is null);\n        assert(ae.msg == \"Assertion failure\");\n    }\n\n    {\n        auto ae = new AssertError(new Exception(\"It's an Exception!\"));\n        assert(ae.file == __FILE__);\n        assert(ae.line == __LINE__ - 2);\n        assert(ae.next !is null);\n        assert(ae.msg == \"Assertion failure\");\n    }\n\n    {\n        auto ae = new AssertError(new Exception(\"It's an Exception!\"), \"hello\", 42);\n        assert(ae.file == \"hello\");\n        assert(ae.line == 42);\n        assert(ae.next !is null);\n        assert(ae.msg == \"Assertion failure\");\n    }\n\n    {\n        auto ae = new AssertError(\"msg\");\n        assert(ae.file == __FILE__);\n        assert(ae.line == __LINE__ - 2);\n        assert(ae.next is null);\n        assert(ae.msg == \"msg\");\n    }\n\n    {\n        auto ae = new AssertError(\"msg\", \"hello\", 42);\n        assert(ae.file == \"hello\");\n        assert(ae.line == 42);\n        assert(ae.next is null);\n        assert(ae.msg == \"msg\");\n    }\n\n    {\n        auto ae = new AssertError(\"msg\", \"hello\", 42, new Exception(\"It's an Exception!\"));\n        assert(ae.file == \"hello\");\n        assert(ae.line == 42);\n        assert(ae.next !is null);\n        assert(ae.msg == \"msg\");\n    }\n}\n\n\n/**\n * Thrown on finalize error.\n */\nclass FinalizeError : Error\n{\n    TypeInfo   info;\n\n    this( TypeInfo ci, Throwable next, string file = __FILE__, size_t line = __LINE__ ) @safe pure nothrow @nogc\n    {\n        this(ci, file, line, next);\n    }\n\n    this( TypeInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc\n    {\n        super( \"Finalization error\", file, line, next );\n        super.info = SuppressTraceInfo.instance;\n        info = ci;\n    }\n\n    override string toString() const @safe\n    {\n        return \"An exception was thrown while finalizing an instance of \" ~ info.toString();\n    }\n}\n\nunittest\n{\n    ClassInfo info = new ClassInfo;\n    info.name = \"testInfo\";\n\n    {\n        auto fe = new FinalizeError(info);\n        assert(fe.file == __FILE__);\n        assert(fe.line == __LINE__ - 2);\n        assert(fe.next is null);\n        assert(fe.msg == \"Finalization error\");\n        assert(fe.info == info);\n    }\n\n    {\n        auto fe = new FinalizeError(info, new Exception(\"It's an Exception!\"));\n        assert(fe.file == __FILE__);\n        assert(fe.line == __LINE__ - 2);\n        assert(fe.next !is null);\n        assert(fe.msg == \"Finalization error\");\n        assert(fe.info == info);\n    }\n\n    {\n        auto fe = new FinalizeError(info, \"hello\", 42);\n        assert(fe.file == \"hello\");\n        assert(fe.line == 42);\n        assert(fe.next is null);\n        assert(fe.msg == \"Finalization error\");\n        assert(fe.info == info);\n    }\n\n    {\n        auto fe = new FinalizeError(info, \"hello\", 42, new Exception(\"It's an Exception!\"));\n        assert(fe.file == \"hello\");\n        assert(fe.line == 42);\n        assert(fe.next !is null);\n        assert(fe.msg == \"Finalization error\");\n        assert(fe.info == info);\n    }\n}\n\n/**\n * Thrown on hidden function error.\n * $(RED Deprecated.\n *   This feature is not longer part of the language.)\n */\ndeprecated class HiddenFuncError : Error\n{\n    @safe pure nothrow this( ClassInfo ci )\n    {\n        super( \"Hidden method called for \" ~ ci.name );\n    }\n}\n\ndeprecated unittest\n{\n    ClassInfo info = new ClassInfo;\n    info.name = \"testInfo\";\n\n    {\n        auto hfe = new HiddenFuncError(info);\n        assert(hfe.next is null);\n        assert(hfe.msg == \"Hidden method called for testInfo\");\n    }\n}\n\n\n/**\n * Thrown on an out of memory error.\n */\nclass OutOfMemoryError : Error\n{\n    this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc\n    {\n        this(true, file, line, next);\n    }\n\n    this(bool trace, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc\n    {\n        super(\"Memory allocation failed\", file, line, next);\n        if (!trace)\n            this.info = SuppressTraceInfo.instance;\n    }\n\n    override string toString() const @trusted\n    {\n        return msg.length ? (cast()this).superToString() : \"Memory allocation failed\";\n    }\n\n    // kludge to call non-const super.toString\n    private string superToString() @trusted\n    {\n        return super.toString();\n    }\n}\n\nunittest\n{\n    {\n        auto oome = new OutOfMemoryError();\n        assert(oome.file == __FILE__);\n        assert(oome.line == __LINE__ - 2);\n        assert(oome.next is null);\n        assert(oome.msg == \"Memory allocation failed\");\n        assert(oome.toString.length);\n    }\n\n    {\n        auto oome = new OutOfMemoryError(\"hello\", 42, new Exception(\"It's an Exception!\"));\n        assert(oome.file == \"hello\");\n        assert(oome.line == 42);\n        assert(oome.next !is null);\n        assert(oome.msg == \"Memory allocation failed\");\n    }\n}\n\n\n/**\n * Thrown on an invalid memory operation.\n *\n * An invalid memory operation error occurs in circumstances when the garbage\n * collector has detected an operation it cannot reliably handle. The default\n * D GC is not re-entrant, so this can happen due to allocations done from\n * within finalizers called during a garbage collection cycle.\n */\nclass InvalidMemoryOperationError : Error\n{\n    this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc\n    {\n        super( \"Invalid memory operation\", file, line, next );\n        this.info = SuppressTraceInfo.instance;\n    }\n\n    override string toString() const @trusted\n    {\n        return msg.length ? (cast()this).superToString() : \"Invalid memory operation\";\n    }\n\n    // kludge to call non-const super.toString\n    private string superToString() @trusted\n    {\n        return super.toString();\n    }\n}\n\nunittest\n{\n    {\n        auto oome = new InvalidMemoryOperationError();\n        assert(oome.file == __FILE__);\n        assert(oome.line == __LINE__ - 2);\n        assert(oome.next is null);\n        assert(oome.msg == \"Invalid memory operation\");\n        assert(oome.toString.length);\n    }\n\n    {\n        auto oome = new InvalidMemoryOperationError(\"hello\", 42, new Exception(\"It's an Exception!\"));\n        assert(oome.file == \"hello\");\n        assert(oome.line == 42);\n        assert(oome.next !is null);\n        assert(oome.msg == \"Invalid memory operation\");\n    }\n}\n\n\n/**\n * Thrown on a switch error.\n */\nclass SwitchError : Error\n{\n    @safe pure nothrow @nogc this( string file = __FILE__, size_t line = __LINE__, Throwable next = null )\n    {\n        super( \"No appropriate switch clause found\", file, line, next );\n    }\n}\n\nunittest\n{\n    {\n        auto se = new SwitchError();\n        assert(se.file == __FILE__);\n        assert(se.line == __LINE__ - 2);\n        assert(se.next is null);\n        assert(se.msg == \"No appropriate switch clause found\");\n    }\n\n    {\n        auto se = new SwitchError(\"hello\", 42, new Exception(\"It's an Exception!\"));\n        assert(se.file == \"hello\");\n        assert(se.line == 42);\n        assert(se.next !is null);\n        assert(se.msg == \"No appropriate switch clause found\");\n    }\n}\n\n\n/**\n * Thrown on a unicode conversion error.\n */\nclass UnicodeException : Exception\n{\n    size_t idx;\n\n    this( string msg, size_t idx, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow\n    {\n        super( msg, file, line, next );\n        this.idx = idx;\n    }\n}\n\nunittest\n{\n    {\n        auto ue = new UnicodeException(\"msg\", 2);\n        assert(ue.file == __FILE__);\n        assert(ue.line == __LINE__ - 2);\n        assert(ue.next is null);\n        assert(ue.msg == \"msg\");\n        assert(ue.idx == 2);\n    }\n\n    {\n        auto ue = new UnicodeException(\"msg\", 2, \"hello\", 42, new Exception(\"It's an Exception!\"));\n        assert(ue.file == \"hello\");\n        assert(ue.line == 42);\n        assert(ue.next !is null);\n        assert(ue.msg == \"msg\");\n        assert(ue.idx == 2);\n    }\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Overrides\n///////////////////////////////////////////////////////////////////////////////\n\n\n// NOTE: One assert handler is used for all threads.  Thread-local\n//       behavior should occur within the handler itself.  This delegate\n//       is __gshared for now based on the assumption that it will only\n//       set by the main thread during program initialization.\nprivate __gshared AssertHandler _assertHandler = null;\n\n\n/**\nGets/sets assert hander. null means the default handler is used.\n*/\nalias AssertHandler = void function(string file, size_t line, string msg) nothrow;\n\n/// ditto\n@property AssertHandler assertHandler() @trusted nothrow @nogc\n{\n    return _assertHandler;\n}\n\n/// ditto\n@property void assertHandler(AssertHandler handler) @trusted nothrow @nogc\n{\n    _assertHandler = handler;\n}\n\n/**\n * Overrides the default assert hander with a user-supplied version.\n * $(RED Deprecated.\n *   Please use $(LREF assertHandler) instead.)\n *\n * Params:\n *  h = The new assert handler.  Set to null to use the default handler.\n */\ndeprecated void setAssertHandler( AssertHandler h ) @trusted nothrow @nogc\n{\n    assertHandler = h;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Overridable Callbacks\n///////////////////////////////////////////////////////////////////////////////\n\n\n/**\n * A callback for assert errors in D.  The user-supplied assert handler will\n * be called if one has been supplied, otherwise an $(LREF AssertError) will be\n * thrown.\n *\n * Params:\n *  file = The name of the file that signaled this error.\n *  line = The line number on which this error occurred.\n */\nextern (C) void onAssertError( string file = __FILE__, size_t line = __LINE__ ) nothrow\n{\n    if ( _assertHandler is null )\n        throw new AssertError( file, line );\n    _assertHandler( file, line, null);\n}\n\n\n/**\n * A callback for assert errors in D.  The user-supplied assert handler will\n * be called if one has been supplied, otherwise an $(LREF AssertError) will be\n * thrown.\n *\n * Params:\n *  file = The name of the file that signaled this error.\n *  line = The line number on which this error occurred.\n *  msg  = An error message supplied by the user.\n */\nextern (C) void onAssertErrorMsg( string file, size_t line, string msg ) nothrow\n{\n    if ( _assertHandler is null )\n        throw new AssertError( msg, file, line );\n    _assertHandler( file, line, msg );\n}\n\n\n/**\n * A callback for unittest errors in D.  The user-supplied unittest handler\n * will be called if one has been supplied, otherwise the error will be\n * written to stderr.\n *\n * Params:\n *  file = The name of the file that signaled this error.\n *  line = The line number on which this error occurred.\n *  msg  = An error message supplied by the user.\n */\nextern (C) void onUnittestErrorMsg( string file, size_t line, string msg ) nothrow\n{\n    onAssertErrorMsg( file, line, msg );\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Internal Error Callbacks\n///////////////////////////////////////////////////////////////////////////////\n\n/**\n * A callback for array bounds errors in D.  A $(LREF RangeError) will be thrown.\n *\n * Params:\n *  file = The name of the file that signaled this error.\n *  line = The line number on which this error occurred.\n *\n * Throws:\n *  $(LREF RangeError).\n */\nextern (C) void onRangeError( string file = __FILE__, size_t line = __LINE__ ) @safe pure nothrow\n{\n    throw new RangeError( file, line, null );\n}\n\n\n/**\n * A callback for finalize errors in D.  A $(LREF FinalizeError) will be thrown.\n *\n * Params:\n *  info = The TypeInfo instance for the object that failed finalization.\n *  e = The exception thrown during finalization.\n *  file = The name of the file that signaled this error.\n *  line = The line number on which this error occurred.\n *\n * Throws:\n *  $(LREF FinalizeError).\n */\nextern (C) void onFinalizeError( TypeInfo info, Throwable e, string file = __FILE__, size_t line = __LINE__ ) @trusted nothrow\n{\n    // This error is thrown during a garbage collection, so no allocation must occur while\n    //  generating this object. So we use a preallocated instance\n    throw staticError!FinalizeError(info, e, file, line);\n}\n\n\n/**\n * A callback for hidden function errors in D.  A $(LREF HiddenFuncError) will be\n * thrown.\n * $(RED Deprecated.\n *   This feature is not longer part of the language.)\n *\n * Throws:\n *  $(LREF HiddenFuncError).\n */\ndeprecated extern (C) void onHiddenFuncError( Object o ) @safe pure nothrow\n{\n    throw new HiddenFuncError( typeid(o) );\n}\n\n\n/**\n * A callback for out of memory errors in D.  An $(LREF OutOfMemoryError) will be\n * thrown.\n *\n * Throws:\n *  $(LREF OutOfMemoryError).\n */\nextern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */\n{\n    // NOTE: Since an out of memory condition exists, no allocation must occur\n    //       while generating this object.\n    throw staticError!OutOfMemoryError();\n}\n\nextern (C) void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc\n{\n    // suppress stacktrace until they are @nogc\n    throw staticError!OutOfMemoryError(false);\n}\n\n\n/**\n * A callback for invalid memory operations in D.  An\n * $(LREF InvalidMemoryOperationError) will be thrown.\n *\n * Throws:\n *  $(LREF InvalidMemoryOperationError).\n */\nextern (C) void onInvalidMemoryOperationError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */\n{\n    // The same restriction applies as for onOutOfMemoryError. The GC is in an\n    // undefined state, thus no allocation must occur while generating this object.\n    throw staticError!InvalidMemoryOperationError();\n}\n\n\n/**\n * A callback for switch errors in D.  A $(LREF SwitchError) will be thrown.\n *\n * Params:\n *  file = The name of the file that signaled this error.\n *  line = The line number on which this error occurred.\n *\n * Throws:\n *  $(LREF SwitchError).\n */\nextern (C) void onSwitchError( string file = __FILE__, size_t line = __LINE__ ) @safe pure nothrow\n{\n    version (D_Exceptions)\n        throw new SwitchError( file, line, null );\n    else\n        assert(0, \"No appropriate switch clause found\");\n}\n\n// Compiler lowers final switch default case to this (which is a runtime error)\nvoid __switch_errorT()(string file = __FILE__, size_t line = __LINE__) @trusted\n{\n    // Consider making this a compile time check.\n    version (D_Exceptions)\n        throw staticError!SwitchError(file, line, null);\n    else\n        assert(0, \"No appropriate switch clause found\");\n}\n\n/**\n * A callback for unicode errors in D.  A $(LREF UnicodeException) will be thrown.\n *\n * Params:\n *  msg = Information about the error.\n *  idx = String index where this error was detected.\n *  file = The name of the file that signaled this error.\n *  line = The line number on which this error occurred.\n *\n * Throws:\n *  $(LREF UnicodeException).\n */\nextern (C) void onUnicodeError( string msg, size_t idx, string file = __FILE__, size_t line = __LINE__ ) @safe pure\n{\n    throw new UnicodeException( msg, idx, file, line );\n}\n\n/***********************************\n * These functions must be defined for any D program linked\n * against this library.\n */\n/+\nextern (C) void onAssertError(string file, size_t line);\nextern (C) void onAssertErrorMsg(string file, size_t line, string msg);\nextern (C) void onUnittestErrorMsg(string file, size_t line, string msg);\nextern (C) void onRangeError(string file, size_t line);\nextern (C) void onHiddenFuncError(Object o);\nextern (C) void onSwitchError(string file, size_t line);\n+/\n\n/***********************************\n * Function calls to these are generated by the compiler and inserted into\n * the object code.\n */\n\nextern (C)\n{\n    // Use ModuleInfo to get file name for \"m\" versions\n\n    /* One of these three is called upon an assert() fail.\n     */\n    void _d_assertp(immutable(char)* file, uint line)\n    {\n        import core.stdc.string : strlen;\n        onAssertError(file[0 .. strlen(file)], line);\n    }\n\n    void _d_assert_msg(string msg, string file, uint line)\n    {\n        onAssertErrorMsg(file, line, msg);\n    }\n\n    void _d_assert(string file, uint line)\n    {\n        onAssertError(file, line);\n    }\n\n    /* One of these three is called upon an assert() fail inside of a unittest block\n     */\n    void _d_unittestp(immutable(char)* file, uint line)\n    {\n        import core.stdc.string : strlen;\n        _d_unittest(file[0 .. strlen(file)], line);\n    }\n\n    void _d_unittest_msg(string msg, string file, uint line)\n    {\n        onUnittestErrorMsg(file, line, msg);\n    }\n\n    void _d_unittest(string file, uint line)\n    {\n        _d_unittest_msg(\"unittest failure\", file, line);\n    }\n\n    /* Called when an array index is out of bounds\n     */\n    void _d_arrayboundsp(immutable(char*) file, uint line)\n    {\n        import core.stdc.string : strlen;\n        onRangeError(file[0 .. strlen(file)], line);\n    }\n\n    void _d_arraybounds(string file, uint line)\n    {\n        onRangeError(file, line);\n    }\n\n    /* Called when a switch statement has no DefaultStatement, yet none of the cases match\n     */\n    void _d_switch_errorm(immutable(ModuleInfo)* m, uint line)\n    {\n        onSwitchError(m.name, line);\n    }\n\n    void _d_switch_error(string file, uint line)\n    {\n        onSwitchError(file, line);\n    }\n}\n\n// TLS storage shared for all errors, chaining might create circular reference\nprivate void[128] _store;\n\n// only Errors for now as those are rarely chained\nprivate T staticError(T, Args...)(auto ref Args args)\n    if (is(T : Error))\n{\n    // pure hack, what we actually need is @noreturn and allow to call that in pure functions\n    static T get()\n    {\n        static assert(__traits(classInstanceSize, T) <= _store.length,\n                      T.stringof ~ \" is too large for staticError()\");\n\n        _store[0 .. __traits(classInstanceSize, T)] = typeid(T).initializer[];\n        return cast(T) _store.ptr;\n    }\n    auto res = (cast(T function() @trusted pure nothrow @nogc) &get)();\n    res.__ctor(args);\n    return res;\n}\n\n// Suppress traceinfo generation when the GC cannot be used.  Workaround for\n// Bugzilla 14993. We should make stack traces @nogc instead.\npackage class SuppressTraceInfo : Throwable.TraceInfo\n{\n    override int opApply(scope int delegate(ref const(char[]))) const { return 0; }\n    override int opApply(scope int delegate(ref size_t, ref const(char[]))) const { return 0; }\n    override string toString() const { return null; }\n    static SuppressTraceInfo instance() @trusted @nogc pure nothrow\n    {\n        static immutable SuppressTraceInfo it = new SuppressTraceInfo;\n        return cast(SuppressTraceInfo)it;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/internal/abort.d",
    "content": "module core.internal.abort;\n\n/*\n * Use instead of assert(0, msg), since this does not print a message for -release compiled\n * code, and druntime is -release compiled.\n */\nvoid abort(scope string msg, scope string filename = __FILE__, size_t line = __LINE__) @nogc nothrow @safe\n{\n    import core.stdc.stdlib: c_abort = abort;\n    // use available OS system calls to print the message to stderr\n    version (Posix)\n    {\n        import core.sys.posix.unistd: write;\n        static void writeStr(scope const(char)[][] m...) @nogc nothrow @trusted\n        {\n            foreach (s; m)\n                write(2, s.ptr, s.length);\n        }\n    }\n    else version (Windows)\n    {\n        import core.sys.windows.windows: GetStdHandle, STD_ERROR_HANDLE, WriteFile, INVALID_HANDLE_VALUE;\n        auto h = (() @trusted => GetStdHandle(STD_ERROR_HANDLE))();\n        if (h == INVALID_HANDLE_VALUE)\n            // attempt best we can to print the message\n            assert(0, msg);\n        void writeStr(scope const(char)[][] m...) @nogc nothrow @trusted\n        {\n            foreach (s; m)\n            {\n                assert(s.length <= uint.max);\n                WriteFile(h, s.ptr, cast(uint)s.length, null, null);\n            }\n        }\n    }\n    else\n        static assert(0, \"Unsupported OS\");\n\n    import core.internal.string;\n    UnsignedStringBuf strbuff;\n\n    // write an appropriate message, then abort the program\n    writeStr(\"Aborting from \", filename, \"(\", line.unsignedToTempString(strbuff, 10), \") \", msg);\n    c_abort();\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/internal/arrayop.d",
    "content": "module core.internal.arrayop;\nimport core.internal.traits : Filter, staticMap, TypeTuple, Unqual;\n\nversion (GNU) version = GNU_OR_LDC;\nversion (LDC) version = GNU_OR_LDC;\n\n/**\n * Perform array (vector) operations and store the result in `res`.  Operand\n * types and operations are passed as template arguments in Reverse Polish\n * Notation (RPN).\n\n * Operands can be slices or scalar types. The element types of all\n * slices and all scalar types must be implicitly convertible to `T`.\n *\n * Operations are encoded as strings, e.g. `\"+\"`, `\"%\"`, `\"*=\"`. Unary\n * operations are prefixed with \"u\", e.g. `\"u-\"`, `\"u~\"`. Only the last\n * operation can and must be an assignment (`\"=\"`) or op-assignment (`\"op=\"`).\n *\n * All slice operands must have the same length as the result slice.\n *\n * Params: T[] = type of result slice\n *        Args = operand types and operations in RPN\n *         res = the slice in which to store the results\n *        args = operand values\n *\n * Returns: the slice containing the result\n */\nT[] arrayOp(T : T[], Args...)(T[] res, Filter!(isType, Args) args) @trusted @nogc pure nothrow\n{\n    alias scalarizedExp = staticMap!(toElementType, Args);\n    alias check = typeCheck!(true, T, scalarizedExp); // must support all scalar ops\n\n    size_t pos;\n    static if (vectorizeable!(T[], Args))\n    {\n        alias vec = .vec!T;\n        alias load = .load!(T, vec.length);\n        alias store = .store!(T, vec.length);\n\n        // Given that there are at most as many scalars broadcast as there are\n        // operations in any `ary[] = ary[] op const op const`, it should always be\n        // worthwhile to choose vector operations.\n        if (!__ctfe && res.length >= vec.length)\n        {\n            mixin(initScalarVecs!Args);\n\n            auto n = res.length / vec.length;\n            do\n            {\n                mixin(vectorExp!Args ~ \";\");\n                pos += vec.length;\n            }\n            while (--n);\n        }\n    }\n    for (; pos < res.length; ++pos)\n        mixin(scalarExp!Args ~ \";\");\n\n    return res;\n}\n\nprivate:\n\n// SIMD helpers\n\nversion (DigitalMars)\n{\n    import core.simd;\n\n    template vec(T)\n    {\n        enum regsz = 16; // SSE2\n        enum N = regsz / T.sizeof;\n        alias vec = __vector(T[N]);\n    }\n\n    void store(T, size_t N)(T* p, in __vector(T[N]) val)\n    {\n        pragma(inline, true);\n        alias vec = __vector(T[N]);\n\n        static if (is(T == float))\n            cast(void) __simd_sto(XMM.STOUPS, *cast(vec*) p, val);\n        else static if (is(T == double))\n            cast(void) __simd_sto(XMM.STOUPD, *cast(vec*) p, val);\n        else\n            cast(void) __simd_sto(XMM.STODQU, *cast(vec*) p, val);\n    }\n\n    const(__vector(T[N])) load(T, size_t N)(in T* p)\n    {\n        import core.simd;\n\n        pragma(inline, true);\n        alias vec = __vector(T[N]);\n\n        static if (is(T == float))\n            return __simd(XMM.LODUPS, *cast(const vec*) p);\n        else static if (is(T == double))\n            return __simd(XMM.LODUPD, *cast(const vec*) p);\n        else\n            return __simd(XMM.LODDQU, *cast(const vec*) p);\n    }\n\n    __vector(T[N]) binop(string op, T, size_t N)(in __vector(T[N]) a, in __vector(T[N]) b)\n    {\n        pragma(inline, true);\n        return mixin(\"a \" ~ op ~ \" b\");\n    }\n\n    __vector(T[N]) unaop(string op, T, size_t N)(in __vector(T[N]) a)\n            if (op[0] == 'u')\n    {\n        pragma(inline, true);\n        return mixin(op[1 .. $] ~ \"a\");\n    }\n}\n\n// mixin gen\n\n/**\nCheck whether operations on operand types are supported.  This\ntemplate recursively reduces the expression tree and determines\nintermediate types.\nType checking is done here rather than in the compiler to provide more\ndetailed error messages.\n\nParams:\n    fail = whether to fail (static assert) with a human-friendly error message\n       T = type of result\n    Args = operand types and operations in RPN\nReturns:\n    The resulting type of the expression\nSee_Also:\n    $(LREF arrayOp)\n*/\ntemplate typeCheck(bool fail, T, Args...)\n{\n    enum idx = staticIndexOf!(not!isType, Args);\n    static if (isUnaryOp(Args[idx]))\n    {\n        alias UT = Args[idx - 1];\n        enum op = Args[idx][1 .. $];\n        static if (is(typeof((UT a) => mixin(op ~ \" a\")) RT == return))\n            alias typeCheck = typeCheck!(fail, T, Args[0 .. idx - 1], RT, Args[idx + 1 .. $]);\n        else static if (fail)\n            static assert(0, \"Unary `\" ~ op ~ \"` not supported for type `\" ~ UT.stringof ~ \"`.\");\n    }\n    else static if (isBinaryOp(Args[idx]))\n    {\n        alias LHT = Args[idx - 2];\n        alias RHT = Args[idx - 1];\n        enum op = Args[idx];\n        static if (is(typeof((LHT a, RHT b) => mixin(\"a \" ~ op ~ \" b\")) RT == return))\n            alias typeCheck = typeCheck!(fail, T, Args[0 .. idx - 2], RT, Args[idx + 1 .. $]);\n        else static if (fail)\n            static assert(0,\n                    \"Binary `\" ~ op ~ \"` not supported for types `\"\n                    ~ LHT.stringof ~ \"` and `\" ~ RHT.stringof ~ \"`.\");\n    }\n    else static if (Args[idx] == \"=\" || isBinaryAssignOp(Args[idx]))\n    {\n        alias RHT = Args[idx - 1];\n        enum op = Args[idx];\n        static if (is(T == __vector(ET[N]), ET, size_t N))\n        {\n            // no `cast(T)` before assignment for vectors\n            static if (is(typeof((T res, RHT b) => mixin(\"res \" ~ op ~ \" b\")) RT == return)\n                    && // workaround https://issues.dlang.org/show_bug.cgi?id=17758\n                    (op != \"=\" || is(Unqual!T == Unqual!RHT)))\n                alias typeCheck = typeCheck!(fail, T, Args[0 .. idx - 1], RT, Args[idx + 1 .. $]);\n            else static if (fail)\n                static assert(0,\n                        \"Binary op `\" ~ op ~ \"` not supported for types `\"\n                        ~ T.stringof ~ \"` and `\" ~ RHT.stringof ~ \"`.\");\n        }\n        else\n        {\n            static if (is(typeof((RHT b) => mixin(\"cast(T) b\"))))\n            {\n                static if (is(typeof((T res, T b) => mixin(\"res \" ~ op ~ \" b\")) RT == return))\n                    alias typeCheck = typeCheck!(fail, T, Args[0 .. idx - 1], RT, Args[idx + 1 .. $]);\n                else static if (fail)\n                    static assert(0,\n                            \"Binary op `\" ~ op ~ \"` not supported for types `\"\n                            ~ T.stringof ~ \"` and `\" ~ T.stringof ~ \"`.\");\n            }\n            else static if (fail)\n                static assert(0,\n                        \"`cast(\" ~ T.stringof ~ \")` not supported for type `\" ~ RHT.stringof ~ \"`.\");\n        }\n    }\n    else\n        static assert(0);\n}\n/// ditto\ntemplate typeCheck(bool fail, T, ResultType)\n{\n    alias typeCheck = ResultType;\n}\n\nversion (GNU_OR_LDC)\n{\n    // leave it to the auto-vectorizer\n    enum vectorizeable(E : E[], Args...) = false;\n}\nelse\n{\n    // check whether arrayOp is vectorizable\n    template vectorizeable(E : E[], Args...)\n    {\n        static if (is(vec!E))\n        {\n            // type check with vector types\n            enum vectorizeable = is(typeCheck!(false, vec!E, staticMap!(toVecType, Args)));\n        }\n        else\n            enum vectorizeable = false;\n    }\n\n    version (X86_64) unittest\n    {\n        pragma(msg, vectorizeable!(double[], const(double)[], double[], \"+\", \"=\"));\n        static assert(vectorizeable!(double[], const(double)[], double[], \"+\", \"=\"));\n        static assert(!vectorizeable!(double[], const(ulong)[], double[], \"+\", \"=\"));\n        // Vector type are (atm.) not implicitly convertible and would require\n        // lots of SIMD intrinsics. Therefor leave mixed type array ops to\n        // GDC/LDC's auto-vectorizers.\n        static assert(!vectorizeable!(double[], const(uint)[], uint, \"+\", \"=\"));\n    }\n}\n\nbool isUnaryOp(scope string op) pure nothrow @safe @nogc\n{\n    return op[0] == 'u';\n}\n\nbool isBinaryOp(scope string op) pure nothrow @safe @nogc\n{\n    if (op == \"^^\")\n        return true;\n    if (op.length != 1)\n        return false;\n    switch (op[0])\n    {\n    case '+', '-', '*', '/', '%', '|', '&', '^':\n        return true;\n    default:\n        return false;\n    }\n}\n\nbool isBinaryAssignOp(string op)\n{\n    return op.length >= 2 && op[$ - 1] == '=' && isBinaryOp(op[0 .. $ - 1]);\n}\n\n// Generate mixin expression to perform scalar arrayOp loop expression, assumes\n// `pos` to be the current slice index, `args` to contain operand values, and\n// `res` the target slice.\nstring scalarExp(Args...)()\n{\n    string[] stack;\n    size_t argsIdx;\n    foreach (i, arg; Args)\n    {\n        static if (is(arg == T[], T))\n            stack ~= \"args[\" ~ argsIdx++.toString ~ \"][pos]\";\n        else static if (is(arg))\n            stack ~= \"args[\" ~ argsIdx++.toString ~ \"]\";\n        else static if (isUnaryOp(arg))\n        {\n            auto op = arg[0] == 'u' ? arg[1 .. $] : arg;\n            stack[$ - 1] = op ~ stack[$ - 1];\n        }\n        else static if (arg == \"=\")\n        {\n            stack[$ - 1] = \"res[pos] = cast(T)(\" ~ stack[$ - 1] ~ \")\";\n        }\n        else static if (isBinaryAssignOp(arg))\n        {\n            stack[$ - 1] = \"res[pos] \" ~ arg ~ \" cast(T)(\" ~ stack[$ - 1] ~ \")\";\n        }\n        else static if (isBinaryOp(arg))\n        {\n            stack[$ - 2] = \"(\" ~ stack[$ - 2] ~ \" \" ~ arg ~ \" \" ~ stack[$ - 1] ~ \")\";\n            stack.length -= 1;\n        }\n        else\n            assert(0, \"Unexpected op \" ~ arg);\n    }\n    assert(stack.length == 1);\n    return stack[0];\n}\n\n// Generate mixin statement to perform vector loop initialization, assumes\n// `args` to contain operand values.\nstring initScalarVecs(Args...)()\n{\n    size_t scalarsIdx, argsIdx;\n    string res;\n    foreach (arg; Args)\n    {\n        static if (is(arg == T[], T))\n        {\n            ++argsIdx;\n        }\n        else static if (is(arg))\n            res ~= \"immutable vec scalar\" ~ scalarsIdx++.toString ~ \" = args[\"\n                ~ argsIdx++.toString ~ \"];\\n\";\n    }\n    return res;\n}\n\n// Generate mixin expression to perform vector arrayOp loop expression, assumes\n// `pos` to be the current slice index, `args` to contain operand values, and\n// `res` the target slice.\nstring vectorExp(Args...)()\n{\n    size_t scalarsIdx, argsIdx;\n    string[] stack;\n    foreach (arg; Args)\n    {\n        static if (is(arg == T[], T))\n            stack ~= \"load(&args[\" ~ argsIdx++.toString ~ \"][pos])\";\n        else static if (is(arg))\n        {\n            ++argsIdx;\n            stack ~= \"scalar\" ~ scalarsIdx++.toString;\n        }\n        else static if (isUnaryOp(arg))\n        {\n            auto op = arg[0] == 'u' ? arg[1 .. $] : arg;\n            stack[$ - 1] = \"unaop!\\\"\" ~ arg ~ \"\\\"(\" ~ stack[$ - 1] ~ \")\";\n        }\n        else static if (arg == \"=\")\n        {\n            stack[$ - 1] = \"store(&res[pos], \" ~ stack[$ - 1] ~ \")\";\n        }\n        else static if (isBinaryAssignOp(arg))\n        {\n            stack[$ - 1] = \"store(&res[pos], binop!\\\"\" ~ arg[0 .. $ - 1]\n                ~ \"\\\"(load(&res[pos]), \" ~ stack[$ - 1] ~ \"))\";\n        }\n        else static if (isBinaryOp(arg))\n        {\n            stack[$ - 2] = \"binop!\\\"\" ~ arg ~ \"\\\"(\" ~ stack[$ - 2] ~ \", \" ~ stack[$ - 1] ~ \")\";\n            stack.length -= 1;\n        }\n        else\n            assert(0, \"Unexpected op \" ~ arg);\n    }\n    assert(stack.length == 1);\n    return stack[0];\n}\n\n// other helpers\n\nenum isType(T) = true;\nenum isType(alias a) = false;\ntemplate not(alias tmlp)\n{\n    enum not(Args...) = !tmlp!Args;\n}\n/**\nFind element in `haystack` for which `pred` is true.\n\nParams:\n    pred = the template predicate\n    haystack = elements to search\nReturns:\n    The first index for which `pred!haystack[index]` is true or -1.\n */\ntemplate staticIndexOf(alias pred, haystack...)\n{\n    static if (pred!(haystack[0]))\n        enum staticIndexOf = 0;\n    else\n    {\n        enum next = staticIndexOf!(pred, haystack[1 .. $]);\n        enum staticIndexOf = next == -1 ? -1 : next + 1;\n    }\n}\n/// converts slice types to their element type, preserves anything else\nalias toElementType(E : E[]) = E;\nalias toElementType(S) = S;\nalias toElementType(alias op) = op;\n/// converts slice types to their element type, preserves anything else\nalias toVecType(E : E[]) = vec!E;\nalias toVecType(S) = vec!S;\nalias toVecType(alias op) = op;\n\nstring toString(size_t num)\n{\n    import core.internal.string : unsignedToTempString;\n\n    char[20] buf = void;\n    return unsignedToTempString(num, buf).idup;\n}\n\nbool contains(T)(in T[] ary, in T[] vals...)\n{\n    foreach (v1; ary)\n        foreach (v2; vals)\n            if (v1 == v2)\n                return true;\n    return false;\n}\n\n// tests\n\nversion (unittest) template TT(T...)\n{\n    alias TT = T;\n}\n\nversion (unittest) template _arrayOp(Args...)\n{\n    alias _arrayOp = arrayOp!Args;\n}\n\nunittest\n{\n    static void check(string op, TA, TB, T, size_t N)(TA a, TB b, in ref T[N] exp)\n    {\n        T[N] res;\n        _arrayOp!(T[], TA, TB, op, \"=\")(res[], a, b);\n        foreach (i; 0 .. N)\n            assert(res[i] == exp[i]);\n    }\n\n    static void check2(string unaOp, string binOp, TA, TB, T, size_t N)(TA a, TB b, in ref T[N] exp)\n    {\n        T[N] res;\n        _arrayOp!(T[], TA, TB, unaOp, binOp, \"=\")(res[], a, b);\n        foreach (i; 0 .. N)\n            assert(res[i] == exp[i]);\n    }\n\n    static void test(T, string op, size_t N = 16)(T a, T b, T exp)\n    {\n        T[N] va = a, vb = b, vexp = exp;\n\n        check!op(va[], vb[], vexp);\n        check!op(va[], b, vexp);\n        check!op(a, vb[], vexp);\n    }\n\n    static void test2(T, string unaOp, string binOp, size_t N = 16)(T a, T b, T exp)\n    {\n        T[N] va = a, vb = b, vexp = exp;\n\n        check2!(unaOp, binOp)(va[], vb[], vexp);\n        check2!(unaOp, binOp)(va[], b, vexp);\n        check2!(unaOp, binOp)(a, vb[], vexp);\n    }\n\n    alias UINTS = TT!(ubyte, ushort, uint, ulong);\n    alias INTS = TT!(byte, short, int, long);\n    alias FLOATS = TT!(float, double);\n\n    foreach (T; TT!(UINTS, INTS, FLOATS))\n    {\n        test!(T, \"+\")(1, 2, 3);\n        test!(T, \"-\")(3, 2, 1);\n        static if (__traits(compiles, { import std.math; }))\n            test!(T, \"^^\")(2, 3, 8);\n\n        test2!(T, \"u-\", \"+\")(3, 2, 1);\n    }\n\n    foreach (T; TT!(UINTS, INTS))\n    {\n        test!(T, \"|\")(1, 2, 3);\n        test!(T, \"&\")(3, 1, 1);\n        test!(T, \"^\")(3, 1, 2);\n\n        test2!(T, \"u~\", \"+\")(3, cast(T)~2, 5);\n    }\n\n    foreach (T; TT!(INTS, FLOATS))\n    {\n        test!(T, \"-\")(1, 2, -1);\n        test2!(T, \"u-\", \"+\")(-3, -2, -1);\n        test2!(T, \"u-\", \"*\")(-3, -2, -6);\n    }\n\n    foreach (T; TT!(UINTS, INTS, FLOATS))\n    {\n        test!(T, \"*\")(2, 3, 6);\n        test!(T, \"/\")(8, 4, 2);\n        test!(T, \"%\")(8, 6, 2);\n    }\n}\n\n// test handling of v op= exp\nunittest\n{\n    uint[32] c;\n    arrayOp!(uint[], uint, \"+=\")(c[], 2);\n    foreach (v; c)\n        assert(v == 2);\n    static if (__traits(compiles, { import std.math; }))\n    {\n        arrayOp!(uint[], uint, \"^^=\")(c[], 3);\n        foreach (v; c)\n            assert(v == 8);\n    }\n}\n\n// proper error message for UDT lacking certain ops\nunittest\n{\n    static assert(!is(typeof(&arrayOp!(int[4][], int[4], \"+=\"))));\n    static assert(!is(typeof(&arrayOp!(int[4][], int[4], \"u-\", \"=\"))));\n\n    static struct S\n    {\n    }\n\n    static assert(!is(typeof(&arrayOp!(S[], S, \"+=\"))));\n    static assert(!is(typeof(&arrayOp!(S[], S[], \"*\", S, \"+=\"))));\n    static struct S2\n    {\n        S2 opBinary(string op)(in S2) @nogc pure nothrow\n        {\n            return this;\n        }\n\n        ref S2 opOpAssign(string op)(in S2) @nogc pure nothrow\n        {\n            return this;\n        }\n    }\n\n    static assert(is(typeof(&arrayOp!(S2[], S2[], S2[], S2, \"*\", \"+\", \"=\"))));\n    static assert(is(typeof(&arrayOp!(S2[], S2[], S2, \"*\", \"+=\"))));\n}\n\n// test mixed type array op\nunittest\n{\n    uint[32] a = 0xF;\n    float[32] res = 2.0f;\n    arrayOp!(float[], const(uint)[], uint, \"&\", \"*=\")(res[], a[], 12);\n    foreach (v; res[])\n        assert(v == 24.0f);\n}\n\n// test mixed type array op\nunittest\n{\n    static struct S\n    {\n        float opBinary(string op)(in S) @nogc const pure nothrow\n        {\n            return 2.0f;\n        }\n    }\n\n    float[32] res = 24.0f;\n    S[32] s;\n    arrayOp!(float[], const(S)[], const(S)[], \"+\", \"/=\")(res[], s[], s[]);\n    foreach (v; res[])\n        assert(v == 12.0f);\n}\n\n// test scalar after operation argument\nunittest\n{\n    float[32] res, a = 2, b = 3;\n    float c = 4;\n    arrayOp!(float[], const(float)[], const(float)[], \"*\", float, \"+\", \"=\")(res[], a[], b[], c);\n    foreach (v; res[])\n        assert(v == 2 * 3 + 4);\n}\n\nunittest\n{\n    // https://issues.dlang.org/show_bug.cgi?id=17964\n    uint bug(){\n        uint[] a = [1, 2, 3, 5, 6, 7];\n        uint[] b = [1, 2, 3, 5, 6, 7];\n        a[] |= ~b[];\n        return a[1];\n    }\n    enum x = bug();\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/internal/convert.d",
    "content": "/**\n * Written in the D programming language.\n * This module provides functions to converting different values to const(ubyte)[]\n *\n * Copyright: Copyright Igor Stepanov 2013-2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Igor Stepanov\n * Source: $(DRUNTIMESRC core/internal/_convert.d)\n */\nmodule core.internal.convert;\nimport core.internal.traits : Unqual;\n\n/+\nA @nogc function can allocate memory during CTFE.\n+/\n@nogc nothrow pure @trusted\nprivate ubyte[] ctfe_alloc()(size_t n)\n{\n    if (!__ctfe)\n    {\n        assert(0, \"CTFE only\");\n    }\n    else\n    {\n        static ubyte[] alloc(size_t x) nothrow pure\n        {\n            if (__ctfe) // Needed to prevent _d_newarray from appearing in compiled prorgam.\n                return new ubyte[x];\n            else\n                assert(0);\n        }\n        return (cast(ubyte[] function(size_t) @nogc nothrow pure) &alloc)(n);\n    }\n}\n\n@trusted pure nothrow @nogc\nconst(ubyte)[] toUbyte(T)(const ref T val) if (is(Unqual!T == float) || is(Unqual!T == double) || is(Unqual!T == real) ||\n                                        is(Unqual!T == ifloat) || is(Unqual!T == idouble) || is(Unqual!T == ireal))\n{\n    static const(ubyte)[] reverse_(const(ubyte)[] arr)\n    {\n        ubyte[] buff = ctfe_alloc(arr.length);\n        foreach (k, v; arr)\n        {\n            buff[$-k-1] = v;\n        }\n        return buff;\n    }\n    if (__ctfe)\n    {\n        auto parsed = parse(val);\n\n        ulong mantissa = parsed.mantissa;\n        uint exp = parsed.exponent;\n        uint sign = parsed.sign;\n\n        ubyte[] buff = ctfe_alloc(T.sizeof);\n        size_t off_bytes = 0;\n        size_t off_bits  = 0;\n        // Quadruples won't fit in one ulong, so check for that.\n        enum mantissaMax = FloatTraits!T.MANTISSA < ulong.sizeof*8 ?\n                           FloatTraits!T.MANTISSA : ulong.sizeof*8;\n\n        for (; off_bytes < mantissaMax/8; ++off_bytes)\n        {\n            buff[off_bytes] = cast(ubyte)mantissa;\n            mantissa >>= 8;\n        }\n\n        static if (floatFormat!T == FloatFormat.Quadruple)\n        {\n            ulong mantissa2 = parsed.mantissa2;\n            off_bytes--; // go back one, since mantissa only stored data in 56\n                         // bits, ie 7 bytes\n            for (; off_bytes < FloatTraits!T.MANTISSA/8; ++off_bytes)\n            {\n                buff[off_bytes] = cast(ubyte)mantissa2;\n                mantissa2 >>= 8;\n            }\n        }\n        else\n        {\n            off_bits = FloatTraits!T.MANTISSA%8;\n            buff[off_bytes] = cast(ubyte)mantissa;\n        }\n\n        for (size_t i=0; i<FloatTraits!T.EXPONENT/8; ++i)\n        {\n            ubyte cur_exp = cast(ubyte)exp;\n            exp >>= 8;\n            buff[off_bytes] |= (cur_exp << off_bits);\n            ++off_bytes;\n            buff[off_bytes] |= cur_exp >> 8 - off_bits;\n        }\n\n\n        exp <<= 8 - FloatTraits!T.EXPONENT%8 - 1;\n        buff[off_bytes] |= exp;\n        sign <<= 7;\n        buff[off_bytes] |= sign;\n\n        version (LittleEndian)\n        {\n            return buff;\n        }\n        else\n        {\n            return reverse_(buff);\n        }\n    }\n    else\n    {\n        return (cast(const(ubyte)*)&val)[0 .. T.sizeof];\n    }\n}\n\n@safe pure nothrow @nogc\nprivate Float parse(bool is_denormalized = false, T)(T x) if (is(Unqual!T == ifloat) || is(Unqual!T == idouble) || is(Unqual!T == ireal))\n{\n    return parse(x.im);\n}\n\n@safe pure nothrow @nogc\nprivate Float parse(bool is_denormalized = false, T:real)(T x_) if (floatFormat!T != FloatFormat.Real80)\n{\n    Unqual!T x = x_;\n    static assert(floatFormat!T != FloatFormat.DoubleDouble,\n           \"doubledouble float format not supported in CTFE\");\n    if (x is cast(T)0.0) return FloatTraits!T.ZERO;\n    if (x is cast(T)-0.0) return FloatTraits!T.NZERO;\n    if (x is T.nan) return FloatTraits!T.NAN;\n    if (x is -T.nan) return FloatTraits!T.NNAN;\n    if (x is T.infinity || x > T.max) return FloatTraits!T.INF;\n    if (x is -T.infinity || x < -T.max) return FloatTraits!T.NINF;\n\n    uint sign = x < 0;\n    x = sign ? -x : x;\n    int e = binLog2(x);\n    real x2 = x;\n    uint exp = cast(uint)(e + (2^^(FloatTraits!T.EXPONENT-1) - 1));\n\n    if (!exp)\n    {\n        if (is_denormalized)\n            return Float(0, 0, sign);\n        else\n            return denormalizedMantissa(x, sign);\n    }\n\n    x2 /= binPow2(e);\n\n    static if (!is_denormalized)\n        x2 -= 1.0;\n\n    static if (floatFormat!T == FloatFormat.Quadruple)\n    {\n        // Store the 112-bit mantissa in two ulongs, specifically the lower 56\n        // bits of each, with the most significant bits in mantissa2. There's\n        // an edge case exposed by the labeled test below, where only a subnormal\n        // with the highest bit set being the 57th bit will \"overflow\" to the\n        // 57th bit in mantissa2 with the following logic, but that special case\n        // is handled by an additional check in denormalizedMantissa for\n        // Quadruples below.\n\n        x2 *=  2UL<<(FloatTraits!T.MANTISSA - (ulong.sizeof - 1)*8 - 1);\n        ulong mant2 = cast(ulong) x2;\n        x2 -= mant2;\n\n        x2 *=  2UL<<((ulong.sizeof - 1)*8 - 1);\n        ulong mant = cast(ulong) x2;\n        return Float(mant, exp, sign, mant2);\n    }\n    else\n    {\n        x2 *=  2UL<<(FloatTraits!T.MANTISSA);\n        ulong mant = shiftrRound(cast(ulong)x2);\n        return Float(mant, exp, sign);\n    }\n}\n\n@safe pure nothrow @nogc\nprivate Float parse(bool _ = false, T:real)(T x_) if (floatFormat!T == FloatFormat.Real80)\n{\n    Unqual!T x = x_;\n    //HACK @@@3632@@@\n\n    if (x == 0.0L)\n    {\n        real y = 1.0L/x;\n        if (y == real.infinity) // -0.0\n            return FloatTraits!T.ZERO;\n        else\n            return FloatTraits!T.NZERO; //0.0\n    }\n\n    if (x != x) //HACK: should be if (x is real.nan) and if (x is -real.nan)\n    {\n        auto y = cast(double)x;\n        if (y is double.nan)\n            return FloatTraits!T.NAN;\n        else\n            return FloatTraits!T.NNAN;\n    }\n\n    if (x == real.infinity) return FloatTraits!T.INF;\n    if (x == -real.infinity) return FloatTraits!T.NINF;\n\n    enum EXPONENT_MED = (2^^(FloatTraits!T.EXPONENT-1) - 1);\n    uint sign = x < 0;\n    x = sign ? -x : x;\n\n    int e = binLog2(x);\n    uint exp = cast(uint)(e + EXPONENT_MED);\n    if (!exp)\n    {\n        return denormalizedMantissa(x, sign);\n    }\n    int pow = (FloatTraits!T.MANTISSA-1-e);\n    x *=  binPow2((pow / EXPONENT_MED)*EXPONENT_MED); //To avoid overflow in 2.0L ^^ pow\n    x *=  binPow2(pow % EXPONENT_MED);\n    ulong mant = cast(ulong)x;\n    return Float(mant, exp, sign);\n}\n\nprivate struct Float\n{\n    ulong mantissa;\n    uint exponent;\n    uint sign;\n    ulong mantissa2;\n}\n\nprivate template FloatTraits(T) if (floatFormat!T == FloatFormat.Float)\n{\n    enum EXPONENT = 8;\n    enum MANTISSA = 23;\n    enum ZERO     = Float(0, 0, 0);\n    enum NZERO    = Float(0, 0, 1);\n    enum NAN      = Float(0x400000UL, 0xff, 0);\n    enum NNAN     = Float(0x400000UL, 0xff, 1);\n    enum INF      = Float(0, 255, 0);\n    enum NINF     = Float(0, 255, 1);\n}\n\nprivate template FloatTraits(T) if (floatFormat!T == FloatFormat.Double)\n{\n    enum EXPONENT = 11;\n    enum MANTISSA = 52;\n    enum ZERO     = Float(0, 0, 0);\n    enum NZERO    = Float(0, 0, 1);\n    enum NAN      = Float(0x8000000000000UL, 0x7ff, 0);\n    enum NNAN     = Float(0x8000000000000UL, 0x7ff, 1);\n    enum INF      = Float(0, 0x7ff, 0);\n    enum NINF     = Float(0, 0x7ff, 1);\n}\n\nprivate template FloatTraits(T) if (floatFormat!T == FloatFormat.Real80)\n{\n    enum EXPONENT = 15;\n    enum MANTISSA = 64;\n    enum ZERO     = Float(0, 0, 0);\n    enum NZERO    = Float(0, 0, 1);\n    enum NAN      = Float(0xC000000000000000UL, 0x7fff, 0);\n    enum NNAN     = Float(0xC000000000000000UL, 0x7fff, 1);\n    enum INF      = Float(0x8000000000000000UL, 0x7fff, 0);\n    enum NINF     = Float(0x8000000000000000UL, 0x7fff, 1);\n}\n\nprivate template FloatTraits(T) if (floatFormat!T == FloatFormat.DoubleDouble) //Unsupported in CTFE\n{\n    enum EXPONENT = 11;\n    enum MANTISSA = 106;\n    enum ZERO     = Float(0, 0, 0);\n    enum NZERO    = Float(0, 0, 1);\n    enum NAN      = Float(0x8000000000000UL, 0x7ff, 0);\n    enum NNAN     = Float(0x8000000000000UL, 0x7ff, 1);\n    enum INF      = Float(0, 0x7ff, 0);\n    enum NINF     = Float(0, 0x7ff, 1);\n}\n\nprivate template FloatTraits(T) if (floatFormat!T == FloatFormat.Quadruple)\n{\n    enum EXPONENT = 15;\n    enum MANTISSA = 112;\n    enum ZERO     = Float(0, 0, 0);\n    enum NZERO    = Float(0, 0, 1);\n    enum NAN      = Float(0, 0x7fff, 0, 0x80000000000000UL);\n    enum NNAN     = Float(0, 0x7fff, 1, 0x80000000000000UL);\n    enum INF      = Float(0, 0x7fff, 0);\n    enum NINF     = Float(0, 0x7fff, 1);\n}\n\n\n@safe pure nothrow @nogc\nprivate real binPow2(int pow)\n{\n    static real binPosPow2(int pow) @safe pure nothrow @nogc\n    {\n        assert(pow > 0);\n\n        if (pow == 1) return 2.0L;\n\n        int subpow = pow/2;\n        real p = binPosPow2(subpow);\n        real ret = p*p;\n\n        if (pow%2)\n        {\n            ret *= 2.0L;\n        }\n\n        return ret;\n    }\n\n    if (!pow) return 1.0L;\n    if (pow > 0) return binPosPow2(pow);\n    return 1.0L/binPosPow2(-pow);\n}\n\n\n//Need in CTFE, because CTFE float and double expressions computed more precisely that run-time expressions.\n@safe pure nothrow @nogc\nprivate ulong shiftrRound(ulong x)\n{\n    return (x >> 1) + (x & 1);\n}\n\n@safe pure nothrow @nogc\nprivate uint binLog2(T)(const T x)\n{\n    assert(x > 0);\n    int max = 2 ^^ (FloatTraits!T.EXPONENT-1)-1;\n    int min = -max+1;\n    int med = (min + max) / 2;\n\n    if (x < T.min_normal) return -max;\n\n    while ((max - min) > 1)\n    {\n        if (binPow2(med) > x)\n        {\n            max = med;\n        }\n        else\n        {\n            min = med;\n        }\n        med = (min + max) / 2;\n    }\n\n    if (x < binPow2(max))\n        return min;\n    return max;\n}\n\n@safe pure nothrow @nogc\nprivate Float denormalizedMantissa(T)(T x, uint sign) if (floatFormat!T == FloatFormat.Real80)\n{\n    x *= 2.0L^^FloatTraits!T.MANTISSA;\n    auto fl = parse(x);\n    uint pow = FloatTraits!T.MANTISSA - fl.exponent + 1;\n    return Float(fl.mantissa >> pow, 0, sign);\n}\n\n@safe pure nothrow @nogc\nprivate Float denormalizedMantissa(T)(T x, uint sign)\n    if (floatFormat!T == FloatFormat.Float || floatFormat!T == FloatFormat.Double)\n{\n    x *= 2.0L^^FloatTraits!T.MANTISSA;\n    auto fl = parse!true(x);\n    ulong mant = fl.mantissa >> (FloatTraits!T.MANTISSA - fl.exponent);\n    return Float(shiftrRound(mant), 0, sign);\n}\n\n@safe pure nothrow @nogc\nprivate Float denormalizedMantissa(T)(T x, uint sign) if (floatFormat!T == FloatFormat.Quadruple)\n{\n    x *= 2.0L^^FloatTraits!T.MANTISSA;\n    auto fl = parse!true(x);\n    uint offset = FloatTraits!T.MANTISSA - fl.exponent + 1;\n    enum mantissaSize = (ulong.sizeof - 1) * 8;\n\n    if (offset < mantissaSize)\n    {   // Create a new mantissa ulong with the trailing mantissa2 bits that\n        // need to be shifted into mantissa, by shifting the needed bits left,\n        // zeroing out the first byte, and then ORing it with mantissa shifted\n        // right by offset.\n\n        ulong shiftedMantissa = ((fl.mantissa2 << (mantissaSize - offset)) &\n                                 0x00FFFFFFFFFFFFFFUL) | fl.mantissa >> offset;\n        return Float(shiftedMantissa, 0, sign, fl.mantissa2 >> offset);\n    }\n    else if (offset > mantissaSize)\n        return Float(fl.mantissa2 >> offset - mantissaSize , 0, sign, 0);\n    else\n        // Handle special case mentioned in parse() above by zeroing out the\n        // 57'th bit of mantissa2, \"shifting\" it into mantissa, and setting the\n        // first bit of mantissa2.\n        return Float(fl.mantissa2 & 0x00FFFFFFFFFFFFFFUL , 0, sign, 1);\n}\n\nversion (unittest)\n{\n    private const(ubyte)[] toUbyte2(T)(T val)\n    {\n        return toUbyte(val).dup;\n    }\n\n    private void testNumberConvert(string v)()\n    {\n        enum ctval = mixin(v);\n\n        alias TYPE = typeof(ctval);\n        auto rtval = ctval;\n        auto rtbytes = *cast(ubyte[TYPE.sizeof]*)&rtval;\n\n        enum ctbytes = toUbyte2(ctval);\n\n        // don't test pad bytes because can be anything\n        enum testsize =\n            (FloatTraits!TYPE.EXPONENT + FloatTraits!TYPE.MANTISSA + 1)/8;\n        assert(rtbytes[0..testsize] == ctbytes[0..testsize]);\n    }\n\n    private void testConvert()\n    {\n        /**Test special values*/\n        testNumberConvert!(\"-float.infinity\");\n        testNumberConvert!(\"float.infinity\");\n        testNumberConvert!(\"-0.0F\");\n        testNumberConvert!(\"0.0F\");\n        //testNumberConvert!(\"-float.nan\"); //BUG @@@3632@@@\n        testNumberConvert!(\"float.nan\");\n\n        testNumberConvert!(\"-double.infinity\");\n        testNumberConvert!(\"double.infinity\");\n        testNumberConvert!(\"-0.0\");\n        testNumberConvert!(\"0.0\");\n        //testNumberConvert!(\"-double.nan\"); //BUG @@@3632@@@\n        testNumberConvert!(\"double.nan\");\n\n        testNumberConvert!(\"-real.infinity\");\n        testNumberConvert!(\"real.infinity\");\n        testNumberConvert!(\"-0.0L\");\n        testNumberConvert!(\"0.0L\");\n        //testNumberConvert!(\"-real.nan\"); //BUG @@@3632@@@\n        testNumberConvert!(\"real.nan\");\n\n        /**\n            Test min and max values values: min value has an '1' mantissa and minimal exponent,\n            Max value has an all '1' bits mantissa and max exponent.\n        */\n        testNumberConvert!(\"float.min_normal\");\n        testNumberConvert!(\"float.max\");\n\n        /**Test common values*/\n        testNumberConvert!(\"-0.17F\");\n        testNumberConvert!(\"3.14F\");\n\n        /**Test immutable and const*/\n        testNumberConvert!(\"cast(const)3.14F\");\n        testNumberConvert!(\"cast(immutable)3.14F\");\n\n        /**The same tests for double and real*/\n        testNumberConvert!(\"double.min_normal\");\n        testNumberConvert!(\"double.max\");\n        testNumberConvert!(\"-0.17\");\n        testNumberConvert!(\"3.14\");\n        testNumberConvert!(\"cast(const)3.14\");\n        testNumberConvert!(\"cast(immutable)3.14\");\n\n        testNumberConvert!(\"real.min_normal\");\n        testNumberConvert!(\"real.max\");\n        testNumberConvert!(\"-0.17L\");\n        testNumberConvert!(\"3.14L\");\n        testNumberConvert!(\"cast(const)3.14L\");\n        testNumberConvert!(\"cast(immutable)3.14L\");\n\n        /**Test denormalized values*/\n\n        /**Max denormalized value, first bit is 1*/\n        testNumberConvert!(\"float.min_normal/2\");\n        /**Min denormalized value, last bit is 1*/\n        testNumberConvert!(\"float.min_normal/2UL^^23\");\n\n        /**Denormalized values with round*/\n        testNumberConvert!(\"float.min_normal/19\");\n        testNumberConvert!(\"float.min_normal/17\");\n\n        testNumberConvert!(\"double.min_normal/2\");\n        testNumberConvert!(\"double.min_normal/2UL^^52\");\n        testNumberConvert!(\"double.min_normal/19\");\n        testNumberConvert!(\"double.min_normal/17\");\n\n        testNumberConvert!(\"real.min_normal/2\");\n        testNumberConvert!(\"real.min_normal/2UL^^63\");\n        // check subnormal storage edge case for Quadruple\n        testNumberConvert!(\"real.min_normal/2UL^^56\");\n        testNumberConvert!(\"real.min_normal/19\");\n        testNumberConvert!(\"real.min_normal/17\");\n\n        /**Test imaginary values: convert algorithm is same with real values*/\n        testNumberConvert!(\"0.0Fi\");\n        testNumberConvert!(\"0.0i\");\n        testNumberConvert!(\"0.0Li\");\n\n        /**True random values*/\n        testNumberConvert!(\"-0x9.0f7ee55df77618fp-13829L\");\n        testNumberConvert!(\"0x7.36e6e2640120d28p+8797L\");\n        testNumberConvert!(\"-0x1.05df6ce4702ccf8p+15835L\");\n        testNumberConvert!(\"0x9.54bb0d88806f714p-7088L\");\n\n        testNumberConvert!(\"-0x9.0f7ee55df7ffp-338\");\n        testNumberConvert!(\"0x7.36e6e264012dp+879\");\n        testNumberConvert!(\"-0x1.05df6ce4708ep+658\");\n        testNumberConvert!(\"0x9.54bb0d888061p-708\");\n\n        testNumberConvert!(\"-0x9.0f7eefp-101F\");\n        testNumberConvert!(\"0x7.36e6ep+87F\");\n        testNumberConvert!(\"-0x1.05df6p+112F\");\n        testNumberConvert!(\"0x9.54bb0p-70F\");\n\n        /**Big overflow or underflow*/\n        testNumberConvert!(\"cast(double)-0x9.0f7ee55df77618fp-13829L\");\n        testNumberConvert!(\"cast(double)0x7.36e6e2640120d28p+8797L\");\n        testNumberConvert!(\"cast(double)-0x1.05df6ce4702ccf8p+15835L\");\n        testNumberConvert!(\"cast(double)0x9.54bb0d88806f714p-7088L\");\n\n        testNumberConvert!(\"cast(float)-0x9.0f7ee55df77618fp-13829L\");\n        testNumberConvert!(\"cast(float)0x7.36e6e2640120d28p+8797L\");\n        testNumberConvert!(\"cast(float)-0x1.05df6ce4702ccf8p+15835L\");\n        testNumberConvert!(\"cast(float)0x9.54bb0d88806f714p-7088L\");\n    }\n\n\n    unittest\n    {\n        testConvert();\n    }\n}\n\n\n\nprivate enum FloatFormat\n{\n    Float,\n    Double,\n    Real80,\n    DoubleDouble,\n    Quadruple\n}\n\ntemplate floatFormat(T) if (is(T:real) || is(T:ireal))\n{\n    static if (T.mant_dig == 24)\n        enum floatFormat = FloatFormat.Float;\n    else static if (T.mant_dig == 53)\n        enum floatFormat = FloatFormat.Double;\n    else static if (T.mant_dig == 64)\n        enum floatFormat = FloatFormat.Real80;\n    else static if (T.mant_dig == 106)\n        enum floatFormat = FloatFormat.DoubleDouble;\n    else static if (T.mant_dig == 113)\n        enum floatFormat = FloatFormat.Quadruple;\n    else\n        static assert(0);\n\n}\n\n//  all toUbyte functions must be evaluable at compile time\n@trusted pure nothrow @nogc\nconst(ubyte)[] toUbyte(T)(const T[] arr) if (T.sizeof == 1)\n{\n    return cast(const(ubyte)[])arr;\n}\n\n@trusted pure nothrow @nogc\nconst(ubyte)[] toUbyte(T)(const T[] arr) if ((is(typeof(toUbyte(arr[0])) == const(ubyte)[])) && (T.sizeof > 1))\n{\n    if (__ctfe)\n    {\n        ubyte[] ret = ctfe_alloc(T.sizeof * arr.length);\n        size_t offset = 0;\n        foreach (cur; arr)\n        {\n            ret[offset .. offset + T.sizeof] = toUbyte(cur)[0 .. T.sizeof];\n            offset += T.sizeof;\n        }\n        return ret;\n    }\n    else\n    {\n        return (cast(const(ubyte)*)(arr.ptr))[0 .. T.sizeof*arr.length];\n    }\n}\n\n@trusted pure nothrow @nogc\nconst(ubyte)[] toUbyte(T)(const ref T val) if (__traits(isIntegral, T) && !is(T == enum) && !is(T == __vector))\n{\n    static if (T.sizeof == 1)\n    {\n        if (__ctfe)\n        {\n            ubyte[] result = ctfe_alloc(1);\n            result[0] = cast(ubyte) val;\n            return result;\n        }\n        else\n        {\n            return (cast(const(ubyte)*)(&val))[0 .. T.sizeof];\n        }\n    }\n    else if (__ctfe)\n    {\n        ubyte[] tmp = ctfe_alloc(T.sizeof);\n        Unqual!T val_ = val;\n        for (size_t i = 0; i < T.sizeof; ++i)\n        {\n            size_t idx;\n            version (LittleEndian) idx = i;\n            else idx = T.sizeof-i-1;\n            tmp[idx] = cast(ubyte)(val_&0xff);\n            val_ >>= 8;\n        }\n        return tmp;\n    }\n    else\n    {\n        return (cast(const(ubyte)*)(&val))[0 .. T.sizeof];\n    }\n}\n\n@trusted pure nothrow @nogc\nconst(ubyte)[] toUbyte(T)(const ref T val) if (is(T == __vector))\n{\n    if (!__ctfe)\n        return (cast(const ubyte*) &val)[0 .. T.sizeof];\n    else static if (is(typeof(val[0]) : void))\n        assert(0, \"Unable to compute byte representation of \" ~ T.stringof ~ \" at compile time.\");\n    else\n    {\n        // This code looks like it should work in CTFE but it segfaults:\n        //    auto a = val.array;\n        //    return toUbyte(a);\n        alias E = typeof(val[0]);\n        ubyte[] result = ctfe_alloc(T.sizeof);\n        for (size_t i = 0, j = 0; i < T.sizeof; i += E.sizeof, ++j)\n        {\n            result[i .. i + E.sizeof] = toUbyte(val[j]);\n        }\n        return result;\n    }\n}\n\n@trusted pure nothrow @nogc\nconst(ubyte)[] toUbyte(T)(const ref T val) if (is(Unqual!T == cfloat) || is(Unqual!T == cdouble) ||is(Unqual!T == creal))\n{\n    if (__ctfe)\n    {\n        auto re = val.re;\n        auto im = val.im;\n        auto a = re.toUbyte();\n        auto b = im.toUbyte();\n        ubyte[] result = ctfe_alloc(a.length + b.length);\n        result[0 .. a.length] = a[0 .. a.length];\n        result[a.length .. $] = b[0 .. b.length];\n        return result;\n    }\n    else\n    {\n        return (cast(const(ubyte)*)&val)[0 .. T.sizeof];\n    }\n}\n\n@trusted pure nothrow @nogc\nconst(ubyte)[] toUbyte(T)(const ref T val) if (is(T V == enum) && is(typeof(toUbyte(cast(const V)val)) == const(ubyte)[]))\n{\n    if (__ctfe)\n    {\n        static if (is(T V == enum)){}\n        return toUbyte(cast(const V) val);\n    }\n    else\n    {\n        return (cast(const(ubyte)*)&val)[0 .. T.sizeof];\n    }\n}\n\nnothrow pure @safe unittest\n{\n    // Issue 19008 - check toUbyte works on enums.\n    enum Month : uint { jan = 1}\n    Month m = Month.jan;\n    const bytes = toUbyte(m);\n    enum ctfe_works = (() => { Month x = Month.jan; return toUbyte(x).length > 0; })();\n}\n\npackage(core.internal) bool isNonReference(T)()\n{\n    static if (is(T == struct) || is(T == union))\n    {\n        return isNonReferenceStruct!T();\n    }\n    else static if (__traits(isStaticArray, T))\n    {\n        static if (T.length > 0)\n            return isNonReference!(typeof(T.init[0]))();\n        else\n            return true;\n    }\n    else static if (is(T E == enum))\n    {\n      return isNonReference!(E)();\n    }\n    else static if (!__traits(isScalar, T))\n    {\n        return false;\n    }\n    else static if (is(T V : V*))\n    {\n        return false;\n    }\n    else static if (is(T == function))\n    {\n        return false;\n    }\n    else\n    {\n        return true;\n    }\n}\n\nprivate bool isNonReferenceStruct(T)() if (is(T == struct) || is(T == union))\n{\n    static foreach (cur; T.tupleof)\n    {\n        if (!isNonReference!(typeof(cur))()) return false;\n    }\n\n    return true;\n}\n\n@trusted pure nothrow @nogc\nconst(ubyte)[] toUbyte(T)(const ref T val) if (is(T == struct) || is(T == union))\n{\n    if (__ctfe)\n    {\n        ubyte[] bytes = ctfe_alloc(T.sizeof);\n        foreach (key, cur; val.tupleof)\n        {\n            alias CUR_TYPE = typeof(cur);\n            static if (isNonReference!(CUR_TYPE)())\n            {\n                bytes[val.tupleof[key].offsetof .. val.tupleof[key].offsetof + cur.sizeof] = toUbyte(cur)[];\n            }\n            else static if (is(typeof(val.tupleof[key] is null)))\n            {\n                assert(val.tupleof[key] is null, \"Unable to compute byte representation of non-null reference field at compile time\");\n                //skip, because val bytes are zeros\n            }\n            else\n            {\n                //pragma(msg, \"is null: \", typeof(CUR_TYPE).stringof);\n                assert(0, \"Unable to compute byte representation of \"~typeof(CUR_TYPE).stringof~\" field at compile time\");\n            }\n        }\n        return bytes;\n    }\n    else\n    {\n        return (cast(const(ubyte)*)&val)[0 .. T.sizeof];\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/internal/hash.d",
    "content": "/**\n * Written in the D programming language.\n * This module provides functions to uniform calculating hash values for different types\n *\n * Copyright: Copyright Igor Stepanov 2013-2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Igor Stepanov\n * Source: $(DRUNTIMESRC core/internal/_hash.d)\n */\nmodule core.internal.hash;\n\nimport core.internal.convert;\nimport core.internal.traits : allSatisfy, Unconst;\n\n// If true ensure that positive zero and negative zero have the same hash.\n// Historically typeid(float).getHash did this but hashOf(float) did not.\nprivate enum floatCoalesceZeroes = true;\n// If true ensure that all NaNs of the same floating point type have the same hash.\n// Historically typeid(float).getHash didn't do this but hashOf(float) did.\nprivate enum floatCoalesceNaNs = true;\n\n// If either of the above are true then no struct or array that contains the\n// representation of a floating point number may be hashed with `bytesHash`.\n\n@nogc nothrow pure @safe unittest\n{\n    static if (floatCoalesceZeroes)\n        assert(hashOf(+0.0) == hashOf(-0.0)); // Same hash for +0.0 and -0.0.\n    static if (floatCoalesceNaNs)\n        assert(hashOf(double.nan) == hashOf(-double.nan)); // Same hash for different NaN.\n}\n\nprivate enum hasCallableToHash(T) = __traits(compiles,\n    {\n        size_t hash = ((T* x) => (*x).toHash())(null);\n    });\n\n@nogc nothrow pure @safe unittest\n{\n    static struct S { size_t toHash() { return 4; } }\n    assert(hasCallableToHash!S);\n    assert(!hasCallableToHash!(shared const S));\n}\n\nprivate enum isFinalClassWithAddressBasedHash(T) = __traits(isFinalClass, T)\n    // Use __traits(compiles, ...) in case there are multiple overloads of `toHash`.\n    && __traits(compiles, {static assert(&Object.toHash is &T.toHash);});\n\n@nogc nothrow pure @safe unittest\n{\n    static class C1 {}\n    final static class C2 : C1 {}\n    final static class C3 : C1 { override size_t toHash() const nothrow { return 1; }}\n    static assert(!isFinalClassWithAddressBasedHash!Object);\n    static assert(!isFinalClassWithAddressBasedHash!C1);\n    static assert(isFinalClassWithAddressBasedHash!C2);\n    static assert(!isFinalClassWithAddressBasedHash!C3);\n}\n\nprivate template isCppClassWithoutHash(T)\n{\n    static if (!is(T == class) && !is(T == interface))\n        enum isCppClassWithoutHash = false;\n    else\n    {\n        import core.internal.traits : Unqual;\n        enum bool isCppClassWithoutHash = __traits(getLinkage, T) == \"C++\"\n            && !is(Unqual!T : Object) && !hasCallableToHash!T;\n    }\n}\n\n/+\nIs it valid to calculate a hash code for T based on the bits of its\nrepresentation? Always false for interfaces, dynamic arrays, and\nassociative arrays. False for all classes except final classes that do\nnot override `toHash`.\n\nNote: according to the spec as of\nhttps://github.com/dlang/dlang.org/commit/d66eff16491b0664c0fc00ba80a7aa291703f1f2\nthe contents of unnamed paddings between fields is undefined. Currently\nthis hashing implementation assumes that the padding contents (if any)\nfor all instances of `T` are the same. The correctness of this\nassumption is yet to be verified.\n+/\nprivate template canBitwiseHash(T)\n{\n    static if (is(T EType == enum))\n        enum canBitwiseHash = .canBitwiseHash!EType;\n    else static if (__traits(isFloating, T))\n        enum canBitwiseHash = !(floatCoalesceZeroes || floatCoalesceNaNs);\n    else static if (__traits(isScalar, T))\n        enum canBitwiseHash = true;\n    else static if (is(T == class))\n    {\n        enum canBitwiseHash = isFinalClassWithAddressBasedHash!T || isCppClassWithoutHash!T;\n    }\n    else static if (is(T == interface))\n    {\n        enum canBitwiseHash = isCppClassWithoutHash!T;\n    }\n    else static if (is(T == struct))\n    {\n        static if (hasCallableToHash!T || __traits(isNested, T))\n            enum canBitwiseHash = false;\n        else\n            enum canBitwiseHash = allSatisfy!(.canBitwiseHash, typeof(T.tupleof));\n    }\n    else static if (is(T == union))\n    {\n        // Right now we always bytewise hash unions that lack callable `toHash`.\n        enum canBitwiseHash = !hasCallableToHash!T;\n    }\n    else static if (is(T E : E[]))\n    {\n        static if (__traits(isStaticArray, T))\n            enum canBitwiseHash = (T.length == 0) || .canBitwiseHash!E;\n        else\n            enum canBitwiseHash = false;\n    }\n    else static if (__traits(isAssociativeArray, T))\n    {\n        enum canBitwiseHash = false;\n    }\n    else\n    {\n        static assert(is(T == delegate) || is(T : void) || is(T : typeof(null)),\n            \"Internal error: unanticipated type \"~T.stringof);\n        enum canBitwiseHash = true;\n    }\n}\n\nprivate template UnqualUnsigned(T) if (__traits(isIntegral, T) && !is(T == __vector))\n{\n    static if (T.sizeof == ubyte.sizeof) alias UnqualUnsigned = ubyte;\n    else static if (T.sizeof == ushort.sizeof) alias UnqualUnsigned = ushort;\n    else static if (T.sizeof == uint.sizeof) alias UnqualUnsigned = uint;\n    else static if (T.sizeof == ulong.sizeof) alias UnqualUnsigned = ulong;\n    else static if (T.sizeof == ulong.sizeof * 2)\n    {\n        static assert(T.sizeof == ucent.sizeof);\n        alias UnqualUnsigned = ucent;\n    }\n    else\n    {\n        static assert(0, \"No known unsigned equivalent of \" ~ T.stringof);\n    }\n\n    static assert(UnqualUnsigned.sizeof == T.sizeof && __traits(isUnsigned, UnqualUnsigned));\n}\n\n// Overly restrictive for simplicity: has false negatives but no false positives.\nprivate template useScopeConstPassByValue(T)\n{\n    static if (__traits(isScalar, T))\n        enum useScopeConstPassByValue = true;\n    else static if (is(T == class) || is(T == interface))\n        // Overly restrictive for simplicity.\n        enum useScopeConstPassByValue = isFinalClassWithAddressBasedHash!T;\n    else static if (is(T == struct) || is(T == union))\n    {\n        // Overly restrictive for simplicity.\n        enum useScopeConstPassByValue = T.sizeof <= (int[]).sizeof &&\n            __traits(isPOD, T) && // \"isPOD\" just to check there's no dtor or postblit.\n            canBitwiseHash!T; // We can't verify toHash doesn't leak.\n    }\n    else static if (is(T : E[], E))\n    {\n        static if (!__traits(isStaticArray, T))\n            // Overly restrictive for simplicity.\n            enum useScopeConstPassByValue = .useScopeConstPassByValue!E;\n        else static if (T.length == 0)\n            enum useScopeConstPassByValue = true;\n        else\n            enum useScopeConstPassByValue = T.sizeof <= (uint[]).sizeof\n                && .useScopeConstPassByValue!(typeof(T.init[0]));\n    }\n    else static if (is(T : V[K], K, V))\n    {\n        // Overly restrictive for simplicity.\n        enum useScopeConstPassByValue = .useScopeConstPassByValue!K\n            && .useScopeConstPassByValue!V;\n    }\n    else\n    {\n        static assert(is(T == delegate) || is(T : void) || is(T : typeof(null)),\n            \"Internal error: unanticipated type \"~T.stringof);\n        enum useScopeConstPassByValue = true;\n    }\n}\n\n@safe unittest\n{\n    static assert(useScopeConstPassByValue!int);\n    static assert(useScopeConstPassByValue!string);\n\n    static int ctr;\n    static struct S1 { ~this() { ctr++; } }\n    static struct S2 { this(this) { ctr++; } }\n    static assert(!useScopeConstPassByValue!S1,\n        \"Don't default pass by value a struct with a non-vacuous destructor.\");\n    static assert(!useScopeConstPassByValue!S2,\n        \"Don't default pass by value a struct with a non-vacuous postblit.\");\n}\n\n//enum hash. CTFE depends on base type\nsize_t hashOf(T)(scope const T val)\nif (is(T EType == enum) && useScopeConstPassByValue!EType)\n{\n    static if (is(T EType == enum)) //for EType\n    {\n        return hashOf(cast(const EType) val);\n    }\n    else\n    {\n        static assert(0);\n    }\n}\n\n//enum hash. CTFE depends on base type\nsize_t hashOf(T)(scope const T val, size_t seed)\nif (is(T EType == enum) && useScopeConstPassByValue!EType)\n{\n    static if (is(T EType == enum)) //for EType\n    {\n        return hashOf(cast(const EType) val, seed);\n    }\n    else\n    {\n        static assert(0);\n    }\n}\n\n//enum hash. CTFE depends on base type\nsize_t hashOf(T)(auto ref T val, size_t seed = 0)\nif (is(T EType == enum) && !useScopeConstPassByValue!EType)\n{\n    static if (is(T EType == enum)) //for EType\n    {\n        EType e_val = cast(EType)val;\n        return hashOf(e_val, seed);\n    }\n    else\n    {\n        static assert(0);\n    }\n}\n\n//CTFE ready (depends on base type).\nsize_t hashOf(T)(scope const auto ref T val, size_t seed = 0)\nif (!is(T == enum) && __traits(isStaticArray, T) && canBitwiseHash!T)\n{\n    // FIXME:\n    // We would like to to do this:\n    //\n    //static if (T.length == 0)\n    //    return seed;\n    //else static if (T.length == 1)\n    //    return hashOf(val[0], seed);\n    //else\n    //    /+ hash like a dynamic array +/\n    //\n    // ... but that's inefficient when using a runtime TypeInfo (introduces a branch)\n    // and PR #2243 wants typeid(T).getHash(&val) to produce the same result as\n    // hashOf(val).\n    static if (T.length == 0)\n    {\n        return bytesHashAlignedBy!size_t((ubyte[]).init, seed);\n    }\n    static if (is(typeof(toUbyte(val)) == const(ubyte)[]))\n    {\n        return bytesHashAlignedBy!T(toUbyte(val), seed);\n    }\n    else //Other types. CTFE unsupported\n    {\n        assert(!__ctfe, \"unable to compute hash of \"~T.stringof~\" at compile time\");\n        return bytesHashAlignedBy!T((cast(const(ubyte)*) &val)[0 .. T.sizeof], seed);\n    }\n}\n\n//CTFE ready (depends on base type).\nsize_t hashOf(T)(auto ref T val, size_t seed = 0)\nif (!is(T == enum) && __traits(isStaticArray, T) && !canBitwiseHash!T)\n{\n    // FIXME:\n    // We would like to to do this:\n    //\n    //static if (T.length == 0)\n    //    return seed;\n    //else static if (T.length == 1)\n    //    return hashOf(val[0], seed);\n    //else\n    //    /+ hash like a dynamic array +/\n    //\n    // ... but that's inefficient when using a runtime TypeInfo (introduces a branch)\n    // and PR #2243 wants typeid(T).getHash(&val) to produce the same result as\n    // hashOf(val).\n    return hashOf(val[], seed);\n}\n\n//dynamic array hash\nsize_t hashOf(T)(scope const T val, size_t seed = 0)\nif (!is(T == enum) && !is(T : typeof(null)) && is(T S: S[]) && !__traits(isStaticArray, T)\n    && !is(T == struct) && !is(T == class) && !is(T == union)\n    && (__traits(isScalar, S) || canBitwiseHash!S))\n{\n    alias ElementType = typeof(val[0]);\n    static if (!canBitwiseHash!ElementType)\n    {\n        size_t hash = seed;\n        foreach (ref o; val)\n        {\n            hash = hashOf(hashOf(o), hash); // double hashing to match TypeInfo.getHash\n        }\n        return hash;\n    }\n    else static if (is(typeof(toUbyte(val)) == const(ubyte)[]))\n    //ubyteble array (arithmetic types and structs without toHash) CTFE ready for arithmetic types and structs without reference fields\n    {\n        return bytesHashAlignedBy!ElementType(toUbyte(val), seed);\n    }\n    else //Other types. CTFE unsupported\n    {\n        assert(!__ctfe, \"unable to compute hash of \"~T.stringof~\" at compile time\");\n        return bytesHashAlignedBy!ElementType((cast(const(ubyte)*) val.ptr)[0 .. ElementType.sizeof*val.length], seed);\n    }\n}\n\n//dynamic array hash\nsize_t hashOf(T)(T val, size_t seed = 0)\nif (!is(T == enum) && !is(T : typeof(null)) && is(T S: S[]) && !__traits(isStaticArray, T)\n    && !is(T == struct) && !is(T == class) && !is(T == union)\n    && !(__traits(isScalar, S) || canBitwiseHash!S))\n{\n    size_t hash = seed;\n    foreach (ref o; val)\n    {\n        hash = hashOf(hashOf(o), hash); // double hashing because TypeInfo.getHash doesn't allow to pass seed value\n    }\n    return hash;\n}\n\n//arithmetic type hash\n@trusted @nogc nothrow pure\nsize_t hashOf(T)(scope const T val) if (!is(T == enum) && __traits(isArithmetic, T)\n    && __traits(isIntegral, T) && T.sizeof <= size_t.sizeof && !is(T == __vector))\n{\n    return cast(UnqualUnsigned!T) val;\n}\n\n//arithmetic type hash\n@trusted @nogc nothrow pure\nsize_t hashOf(T)(scope const T val, size_t seed) if (!is(T == enum) && __traits(isArithmetic, T)\n    && __traits(isIntegral, T) && T.sizeof <= size_t.sizeof && !is(T == __vector))\n{\n    static if (size_t.sizeof < ulong.sizeof)\n    {\n        //MurmurHash3 32-bit single round\n        enum uint c1 = 0xcc9e2d51;\n        enum uint c2 = 0x1b873593;\n        enum uint c3 = 0xe6546b64;\n        enum uint r1 = 15;\n        enum uint r2 = 13;\n    }\n    else\n    {\n        //Half of MurmurHash3 64-bit single round\n        //(omits second interleaved update)\n        enum ulong c1 = 0x87c37b91114253d5;\n        enum ulong c2 = 0x4cf5ad432745937f;\n        enum ulong c3 = 0x52dce729;\n        enum uint r1 = 31;\n        enum uint r2 = 27;\n    }\n    auto h = c1 * cast(UnqualUnsigned!T) val;\n    h = (h << r1) | (h >>> (typeof(h).sizeof * 8 - r1));\n    h = (h * c2) ^ seed;\n    h = (h << r2) | (h >>> (typeof(h).sizeof * 8 - r2));\n    return h * 5 + c3;\n}\n\n//arithmetic type hash\n@trusted @nogc nothrow pure\nsize_t hashOf(T)(scope const T val, size_t seed = 0) if (!is(T == enum) && __traits(isArithmetic, T)\n    && (!__traits(isIntegral, T) || T.sizeof > size_t.sizeof) && !is(T == __vector))\n{\n    static if (__traits(isFloating, val))\n    {\n        static if (floatCoalesceZeroes || floatCoalesceNaNs)\n        {\n            import core.internal.traits : Unqual;\n            Unqual!T data = val;\n            // +0.0 and -0.0 become the same.\n            static if (floatCoalesceZeroes && is(typeof(data = 0)))\n                if (data == 0) data = 0;\n            static if (floatCoalesceZeroes && is(typeof(data = 0.0i)))\n                if (data == 0.0i) data = 0.0i;\n            static if (floatCoalesceZeroes && is(typeof(data = 0.0 + 0.0i)))\n            {\n                if (data.re == 0.0) data = 0.0 + (data.im * 1.0i);\n                if (data.im == 0.0i) data = data.re + 0.0i;\n            }\n            static if (floatCoalesceNaNs)\n                if (data != data) data = T.nan; // All NaN patterns become the same.\n        }\n        else\n        {\n            alias data = val;\n        }\n\n        static if (T.mant_dig == float.mant_dig && T.sizeof == uint.sizeof)\n            return hashOf(*cast(const uint*) &data, seed);\n        else static if (T.mant_dig == double.mant_dig && T.sizeof == ulong.sizeof)\n            return hashOf(*cast(const ulong*) &data, seed);\n        else\n            return bytesHashAlignedBy!T(toUbyte(data), seed);\n    }\n    else\n    {\n        static assert(T.sizeof > size_t.sizeof && __traits(isIntegral, T));\n        static foreach (i; 0 .. T.sizeof / size_t.sizeof)\n            seed = hashOf(cast(size_t) (val >>> (size_t.sizeof * 8 * i)), seed);\n        return seed;\n    }\n}\n\nsize_t hashOf(T)(scope const auto ref T val, size_t seed = 0) @safe @nogc nothrow pure\nif (is(T == __vector) && !is(T == enum))\n{\n    static if (__traits(isFloating, T) && (floatCoalesceZeroes || floatCoalesceNaNs))\n    {\n        if (__ctfe)\n        {\n            // Workaround for CTFE bug.\n            alias E = Unqual!(typeof(val[0]));\n            E[T.sizeof / E.sizeof] array;\n            foreach (i; 0 .. T.sizeof / E.sizeof)\n                array[i] = val[i];\n            return hashOf(array, seed);\n        }\n        return hashOf(val.array, seed);\n    }\n    else\n    {\n        return bytesHashAlignedBy!T(toUbyte(val), seed);\n    }\n}\n\n//typeof(null) hash. CTFE supported\n@trusted @nogc nothrow pure\nsize_t hashOf(T)(scope const T val) if (!is(T == enum) && is(T : typeof(null)))\n{\n    return 0;\n}\n\n//typeof(null) hash. CTFE supported\n@trusted @nogc nothrow pure\nsize_t hashOf(T)(scope const T val, size_t seed) if (!is(T == enum) && is(T : typeof(null)))\n{\n    return hashOf(size_t(0), seed);\n}\n\n//Pointers hash. CTFE unsupported if not null\n@trusted @nogc nothrow pure\nsize_t hashOf(T)(scope const T val)\nif (!is(T == enum) && is(T V : V*) && !is(T : typeof(null))\n    && !is(T == struct) && !is(T == class) && !is(T == union))\n{\n    if (__ctfe)\n    {\n        if (val is null)\n        {\n            return 0;\n        }\n        else\n        {\n            assert(0, \"Unable to calculate hash of non-null pointer at compile time\");\n        }\n\n    }\n    auto addr = cast(size_t) val;\n    return addr ^ (addr >>> 4);\n}\n\n//Pointers hash. CTFE unsupported if not null\n@trusted @nogc nothrow pure\nsize_t hashOf(T)(scope const T val, size_t seed)\nif (!is(T == enum) && is(T V : V*) && !is(T : typeof(null))\n    && !is(T == struct) && !is(T == class) && !is(T == union))\n{\n    if (__ctfe)\n    {\n        if (val is null)\n        {\n            return hashOf(cast(size_t)0, seed);\n        }\n        else\n        {\n            assert(0, \"Unable to calculate hash of non-null pointer at compile time\");\n        }\n\n    }\n    return hashOf(cast(size_t)val, seed);\n}\n\nprivate enum _hashOfStruct =\nq{\n    enum bool isChained = is(typeof(seed) : size_t);\n    static if (!isChained) enum size_t seed = 0;\n    static if (hasCallableToHash!(typeof(val))) //CTFE depends on toHash()\n    {\n        static if (isChained)\n            return hashOf(cast(size_t) val.toHash(), seed);\n        else\n            return val.toHash();\n    }\n    else\n    {\n        static if (__traits(hasMember, T, \"toHash\") && is(typeof(T.toHash) == function))\n        {\n            // TODO: in the future maybe this should be changed to a static\n            // assert(0), because if there's a `toHash` the programmer probably\n            // expected it to be called and a compilation failure here will\n            // expose a bug in his code.\n            //   In the future we also might want to disallow non-const toHash\n            // altogether.\n            pragma(msg, \"Warning: struct \"~__traits(identifier, T)\n                ~\" has method toHash, however it cannot be called with \"\n                ~typeof(val).stringof~\" this.\");\n        }\n\n        static if (T.tupleof.length == 0)\n        {\n            return seed;\n        }\n        else static if ((is(T == struct) && !canBitwiseHash!T) || T.tupleof.length == 1)\n        {\n            static foreach (i, F; typeof(val.tupleof))\n            {\n                static if (i != 0)\n                    h = hashOf(val.tupleof[i], h);\n                else static if (isChained)\n                    size_t h = hashOf(val.tupleof[i], seed);\n                else\n                    size_t h = hashOf(val.tupleof[i]);\n            }\n            return h;\n        }\n        else static if (is(typeof(toUbyte(val)) == const(ubyte)[]))//CTFE ready for structs without reference fields\n        {\n            return bytesHashAlignedBy!T(toUbyte(val), seed);\n        }\n        else // CTFE unsupported\n        {\n            assert(!__ctfe, \"unable to compute hash of \"~T.stringof);\n            const(ubyte)[] bytes = (() @trusted => (cast(const(ubyte)*)&val)[0 .. T.sizeof])();\n            return bytesHashAlignedBy!T(bytes, seed);\n        }\n    }\n};\n\n//struct or union hash\nsize_t hashOf(T)(scope const auto ref T val, size_t seed = 0)\nif (!is(T == enum) && (is(T == struct) || is(T == union))\n    && !is(T == const) && !is(T == immutable)\n    && canBitwiseHash!T)\n{\n    mixin(_hashOfStruct);\n}\n\n//struct or union hash\nsize_t hashOf(T)(auto ref T val)\nif (!is(T == enum) && (is(T == struct) || is(T == union))\n    && !canBitwiseHash!T)\n{\n    mixin(_hashOfStruct);\n}\n\n//struct or union hash\nsize_t hashOf(T)(auto ref T val, size_t seed)\nif (!is(T == enum) && (is(T == struct) || is(T == union))\n    && !canBitwiseHash!T)\n{\n    mixin(_hashOfStruct);\n}\n\n//struct or union hash - https://issues.dlang.org/show_bug.cgi?id=19332 (support might be removed in future)\nsize_t hashOf(T)(scope auto ref T val, size_t seed = 0)\nif (!is(T == enum) && (is(T == struct) || is(T == union))\n    && (is(T == const) || is(T == immutable))\n    && canBitwiseHash!T && !canBitwiseHash!(Unconst!T))\n{\n    mixin(_hashOfStruct);\n}\n\n//delegate hash. CTFE unsupported\n@trusted @nogc nothrow pure\nsize_t hashOf(T)(scope const T val, size_t seed = 0) if (!is(T == enum) && is(T == delegate))\n{\n    assert(!__ctfe, \"unable to compute hash of \"~T.stringof);\n    const(ubyte)[] bytes = (cast(const(ubyte)*)&val)[0 .. T.sizeof];\n    return bytesHashAlignedBy!T(bytes, seed);\n}\n\n//address-based class hash. CTFE only if null.\n@nogc nothrow pure @trusted\nsize_t hashOf(T)(scope const T val)\nif (!is(T == enum) && (is(T == interface) || is(T == class))\n    && canBitwiseHash!T)\n{\n    if (__ctfe) if (val is null) return 0;\n    return hashOf(cast(const void*) val);\n}\n\n//address-based class hash. CTFE only if null.\n@nogc nothrow pure @trusted\nsize_t hashOf(T)(scope const T val, size_t seed)\nif (!is(T == enum) && (is(T == interface) || is(T == class))\n    && canBitwiseHash!T)\n{\n    if (__ctfe) if (val is null) return hashOf(size_t(0), seed);\n    return hashOf(cast(const void*) val, seed);\n}\n\n//class or interface hash. CTFE depends on toHash\nsize_t hashOf(T)(T val)\nif (!is(T == enum) && (is(T == interface) || is(T == class))\n    && !canBitwiseHash!T)\n{\n    static if (__traits(compiles, {size_t h = val.toHash();}))\n        return val ? val.toHash() : 0;\n    else\n        return val ? (cast(Object)val).toHash() : 0;\n}\n\n//class or interface hash. CTFE depends on toHash\nsize_t hashOf(T)(T val, size_t seed)\nif (!is(T == enum) && (is(T == interface) || is(T == class))\n    && !canBitwiseHash!T)\n{\n    static if (__traits(compiles, {size_t h = val.toHash();}))\n        return hashOf(val ? cast(size_t) val.toHash() : size_t(0), seed);\n    else\n        return hashOf(val ? (cast(Object)val).toHash() : 0, seed);\n}\n\n//associative array hash. CTFE depends on base types\nsize_t hashOf(T)(T aa) if (!is(T == enum) && __traits(isAssociativeArray, T))\n{\n    static if (is(typeof(aa) : V[K], K, V)) {} // Put K & V in scope.\n    static if (__traits(compiles, (ref K k, ref V v) nothrow => .hashOf(k) + .hashOf(v)))\n        scope (failure) assert(0); // Allow compiler to infer nothrow.\n\n    if (!aa.length) return 0;\n    size_t h = 0;\n\n    // The computed hash is independent of the foreach traversal order.\n    foreach (key, ref val; aa)\n    {\n        size_t[2] hpair;\n        hpair[0] = key.hashOf();\n        hpair[1] = val.hashOf();\n        h += hpair.hashOf();\n    }\n    return h;\n}\n\n//associative array hash. CTFE depends on base types\nsize_t hashOf(T)(T aa, size_t seed) if (!is(T == enum) && __traits(isAssociativeArray, T))\n{\n    return hashOf(hashOf(aa), seed);\n}\n\n// MurmurHash3 was written by Austin Appleby, and is placed in the public\n// domain. The author hereby disclaims copyright to this source code.\n\n// This overload is for backwards compatibility.\n@system pure nothrow @nogc\nsize_t bytesHash()(scope const(void)* buf, size_t len, size_t seed)\n{\n    return bytesHashAlignedBy!ubyte((cast(const(ubyte)*) buf)[0 .. len], seed);\n}\n\nprivate template bytesHashAlignedBy(AlignType)\n{\n    alias bytesHashAlignedBy = bytesHash!(AlignType.alignof >= uint.alignof);\n}\n\n//-----------------------------------------------------------------------------\n// Block read - if your platform needs to do endian-swapping or can only\n// handle aligned reads, do the conversion here\nprivate uint get32bits()(scope const(ubyte)* x) @nogc nothrow pure @system\n{\n    version (BigEndian)\n    {\n        return ((cast(uint) x[0]) << 24) | ((cast(uint) x[1]) << 16) | ((cast(uint) x[2]) << 8) | (cast(uint) x[3]);\n    }\n    else\n    {\n        return ((cast(uint) x[3]) << 24) | ((cast(uint) x[2]) << 16) | ((cast(uint) x[1]) << 8) | (cast(uint) x[0]);\n    }\n}\n\n/+\nParams:\n    dataKnownToBeAligned = whether the data is known at compile time to be uint-aligned.\n+/\n@nogc nothrow pure @trusted\nprivate size_t bytesHash(bool dataKnownToBeAligned)(scope const(ubyte)[] bytes, size_t seed)\n{\n    auto len = bytes.length;\n    auto data = bytes.ptr;\n    auto nblocks = len / 4;\n\n    uint h1 = cast(uint)seed;\n\n    enum uint c1 = 0xcc9e2d51;\n    enum uint c2 = 0x1b873593;\n    enum uint c3 = 0xe6546b64;\n\n    //----------\n    // body\n    auto end_data = data+nblocks*uint.sizeof;\n    for (; data!=end_data; data += uint.sizeof)\n    {\n        static if (dataKnownToBeAligned)\n            uint k1 = __ctfe ? get32bits(data) : *(cast(const uint*) data);\n        else\n            uint k1 = get32bits(data);\n        k1 *= c1;\n        k1 = (k1 << 15) | (k1 >> (32 - 15));\n        k1 *= c2;\n\n        h1 ^= k1;\n        h1 = (h1 << 13) | (h1 >> (32 - 13));\n        h1 = h1*5+c3;\n    }\n\n    //----------\n    // tail\n    uint k1 = 0;\n\n    switch (len & 3)\n    {\n        case 3: k1 ^= data[2] << 16; goto case;\n        case 2: k1 ^= data[1] << 8;  goto case;\n        case 1: k1 ^= data[0];\n                k1 *= c1; k1 = (k1 << 15) | (k1 >> (32 - 15)); k1 *= c2; h1 ^= k1;\n                goto default;\n        default:\n    }\n\n    //----------\n    // finalization\n    h1 ^= len;\n    // Force all bits of the hash block to avalanche.\n    h1 = (h1 ^ (h1 >> 16)) * 0x85ebca6b;\n    h1 = (h1 ^ (h1 >> 13)) * 0xc2b2ae35;\n    h1 ^= h1 >> 16;\n    return h1;\n}\n\n//  Check that bytesHash works with CTFE\npure nothrow @system @nogc unittest\n{\n    size_t ctfeHash(string x)\n    {\n        return bytesHash(x.ptr, x.length, 0);\n    }\n\n    enum test_str = \"Sample string\";\n    enum size_t hashVal = ctfeHash(test_str);\n    assert(hashVal == bytesHash(&test_str[0], test_str.length, 0));\n\n    // Detect unintended changes to bytesHash on unaligned and aligned inputs.\n    version (BigEndian)\n    {\n        const ubyte[7] a = [99, 4, 3, 2, 1, 5, 88];\n        const uint[2] b = [0x01_02_03_04, 0x05_ff_ff_ff];\n    }\n    else\n    {\n        const ubyte[7] a = [99, 1, 2, 3, 4, 5, 88];\n        const uint[2] b = [0x04_03_02_01, 0xff_ff_ff_05];\n    }\n    // It is okay to change the below values if you make a change\n    // that you expect to change the result of bytesHash.\n    assert(bytesHash(&a[1], a.length - 2, 0) == 2727459272);\n    assert(bytesHash(&b, 5, 0) == 2727459272);\n    assert(bytesHashAlignedBy!uint((cast(const ubyte*) &b)[0 .. 5], 0) == 2727459272);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/internal/parseoptions.d",
    "content": "/**\n* parse configuration options\n*\n* Copyright: Copyright Digital Mars 2017\n* License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n*\n* Source: $(DRUNTIMESRC src/core/internal/parseoptions.d)\n*/\n\nmodule core.internal.parseoptions;\n\nimport core.stdc.stdlib;\nimport core.stdc.stdio;\nimport core.stdc.ctype;\nimport core.stdc.string;\nimport core.vararg;\nimport core.internal.traits : externDFunc;\n\n\n@nogc nothrow:\nextern extern(C) string[] rt_args();\n\nextern extern(C) __gshared bool rt_envvars_enabled;\nextern extern(C) __gshared bool rt_cmdline_enabled;\nextern extern(C) __gshared string[] rt_options;\n\nalias rt_configCallBack = string delegate(string) @nogc nothrow;\nalias fn_configOption = string function(string opt, scope rt_configCallBack dg, bool reverse) @nogc nothrow;\nalias rt_configOption = externDFunc!(\"rt.config.rt_configOption\", fn_configOption);\n\n/**\n* initialize members of struct CFG from rt_config options\n*\n* options will be read from the environment, the command line or embedded\n* into the executable as configured (see rt.config)\n*\n* fields of the struct are populated by parseOptions().\n*/\nbool initConfigOptions(CFG)(ref CFG cfg, string cfgname)\n{\n    string parse(string opt) @nogc nothrow\n    {\n        if (!parseOptions(cfg, opt))\n            return \"err\";\n        return null; // continue processing\n    }\n    string s = rt_configOption(cfgname, &parse, true);\n    return s is null;\n}\n\n/**\n* initialize members of struct CFG from a string of sub-options.\n*\n* fields of the struct are populated by listing them as space separated\n* sub-options <field-name>:value, e.g. \"precise:1 profile:1\"\n*\n* supported field value types:\n*  - strings (without spaces)\n*  - integer types (positive values only)\n*  - bool\n*  - float\n*\n* If the struct has a member \"help\" it is called if it is found as a sub-option.\n* If the struct has a member \"errorName\", is used as the name reported in error\n* messages. Otherwise the struct name is used.\n*/\nbool parseOptions(CFG)(ref CFG cfg, string opt)\n{\n    static if (is(typeof(__traits(getMember, CFG, \"errorName\"))))\n        string errName = cfg.errorName;\n    else\n        string errName = CFG.stringof;\n    opt = skip!isspace(opt);\n    while (opt.length)\n    {\n        auto tail = find!(c => c == ':' || c == '=' || c == ' ')(opt);\n        auto name = opt[0 .. $ - tail.length];\n        static if (is(typeof(__traits(getMember, CFG, \"help\"))))\n            if (name == \"help\")\n            {\n                version (unittest) {} else\n                cfg.help();\n                opt = skip!isspace(tail);\n                continue;\n            }\n        if (tail.length <= 1 || tail[0] == ' ')\n            return optError(\"Missing argument for\", name, errName);\n        tail = tail[1 .. $];\n\n        switch (name)\n        {\n            foreach (field; __traits(allMembers, CFG))\n            {\n                static if (!is(typeof(__traits(getMember, cfg, field)) == function))\n                {\n                    case field:\n                        if (!parse(name, tail, __traits(getMember, cfg, field), errName))\n                            return false;\n                        break;\n                }\n            }\n            break;\n\n            default:\n                return optError(\"Unknown\", name, errName);\n        }\n        opt = skip!isspace(tail);\n    }\n    return true;\n}\n\n/**\nParses an individual option `optname` value from a provided string `str`.\nThe option type is given by the type `T` of the field `res` to which the parsed\nvalue will be written too.\nIn case of an error, `errName` will be used to display an error message and\nthe failure of the parsing will be indicated by a falsy return value.\n\nFor boolean values, '0/n/N' (false) or '1/y/Y' (true) are accepted.\n\nParams:\n    optname = name of the option to parse\n    str = raw string to parse the option value from\n    res = reference to the resulting data field that the option should be parsed too\n    errName = full-text name of the option which should be displayed in case of errors\n\nReturns: `false` if a parsing error happened.\n*/\nbool rt_parseOption(T)(const(char)[] optname, ref inout(char)[] str, ref T res, const(char)[] errName)\n{\n    return parse(optname, str, res, errName);\n}\n\nprivate:\n\nbool optError(in char[] msg, in char[] name, const(char)[] errName)\n{\n    version (unittest) if (inUnittest) return false;\n\n    fprintf(stderr, \"%.*s %.*s option '%.*s'.\\n\",\n            cast(int)msg.length, msg.ptr,\n            cast(int)errName.length, errName.ptr,\n            cast(int)name.length, name.ptr);\n    return false;\n}\n\ninout(char)[] skip(alias pred)(inout(char)[] str)\n{\n    return find!(c => !pred(c))(str);\n}\n\ninout(char)[] find(alias pred)(inout(char)[] str)\n{\n    foreach (i; 0 .. str.length)\n        if (pred(str[i])) return str[i .. $];\n    return null;\n}\n\nbool parse(T:size_t)(const(char)[] optname, ref inout(char)[] str, ref T res, const(char)[] errName)\nin { assert(str.length); }\ndo\n{\n    size_t i, v;\n    for (; i < str.length && isdigit(str[i]); ++i)\n        v = 10 * v + str[i] - '0';\n\n    if (!i)\n        return parseError(\"a number\", optname, str, errName);\n    if (v > res.max)\n        return parseError(\"a number \" ~ T.max.stringof ~ \" or below\", optname, str[0 .. i], errName);\n    str = str[i .. $];\n    res = cast(T) v;\n    return true;\n}\n\nbool parse(const(char)[] optname, ref inout(char)[] str, ref bool res, const(char)[] errName)\nin { assert(str.length); }\ndo\n{\n    if (str[0] == '1' || str[0] == 'y' || str[0] == 'Y')\n        res = true;\n    else if (str[0] == '0' || str[0] == 'n' || str[0] == 'N')\n        res = false;\n    else\n        return parseError(\"'0/n/N' or '1/y/Y'\", optname, str, errName);\n    str = str[1 .. $];\n    return true;\n}\n\nbool parse(const(char)[] optname, ref inout(char)[] str, ref float res, const(char)[] errName)\nin { assert(str.length); }\ndo\n{\n    // % uint f %n \\0\n    char[1 + 10 + 1 + 2 + 1] fmt=void;\n    // specify max-width\n    immutable n = snprintf(fmt.ptr, fmt.length, \"%%%uf%%n\", cast(uint)str.length);\n    assert(n > 4 && n < fmt.length);\n\n    int nscanned;\n    version (CRuntime_DigitalMars)\n    {\n        /* Older sscanf's in snn.lib can write to its first argument, causing a crash\n        * if the string is in readonly memory. Recent updates to DMD\n        * https://github.com/dlang/dmd/pull/6546\n        * put string literals in readonly memory.\n        * Although sscanf has been fixed,\n        * http://ftp.digitalmars.com/snn.lib\n        * this workaround is here so it still works with the older snn.lib.\n        */\n        // Create mutable copy of str\n        const length = str.length;\n        char* mptr = cast(char*)malloc(length + 1);\n        assert(mptr);\n        memcpy(mptr, str.ptr, length);\n        mptr[length] = 0;\n        const result = sscanf(mptr, fmt.ptr, &res, &nscanned);\n        free(mptr);\n        if (result < 1)\n            return parseError(\"a float\", optname, str, errName);\n    }\n    else\n    {\n        if (sscanf(str.ptr, fmt.ptr, &res, &nscanned) < 1)\n            return parseError(\"a float\", optname, str, errName);\n    }\n    str = str[nscanned .. $];\n    return true;\n}\n\nbool parse(const(char)[] optname, ref inout(char)[] str, ref inout(char)[] res, const(char)[] errName)\nin { assert(str.length); }\ndo\n{\n    auto tail = str.find!(c => c == ' ');\n    res = str[0 .. $ - tail.length];\n    if (!res.length)\n        return parseError(\"an identifier\", optname, str, errName);\n    str = tail;\n    return true;\n}\n\nbool parseError(in char[] exp, in char[] opt, in char[] got, const(char)[] errName)\n{\n    version (unittest) if (inUnittest) return false;\n\n    fprintf(stderr, \"Expecting %.*s as argument for %.*s option '%.*s', got '%.*s' instead.\\n\",\n            cast(int)exp.length, exp.ptr,\n            cast(int)errName.length, errName.ptr,\n            cast(int)opt.length, opt.ptr,\n            cast(int)got.length, got.ptr);\n    return false;\n}\n\nsize_t min(size_t a, size_t b) { return a <= b ? a : b; }\n\nversion (unittest) __gshared bool inUnittest;\n\nunittest\n{\n    inUnittest = true;\n    scope (exit) inUnittest = false;\n\n    static struct Config\n    {\n        bool disable;            // start disabled\n        ubyte profile;           // enable profiling with summary when terminating program\n        string gc = \"conservative\"; // select gc implementation conservative|manual\n\n        size_t initReserve;      // initial reserve (MB)\n        size_t minPoolSize = 1;  // initial and minimum pool size (MB)\n        float heapSizeFactor = 2.0; // heap size to used memory ratio\n\n        @nogc nothrow:\n        void help();\n        string errorName() @nogc nothrow { return \"GC\"; }\n    }\n    Config conf;\n\n    assert(!conf.parseOptions(\"disable\"));\n    assert(!conf.parseOptions(\"disable:\"));\n    assert(!conf.parseOptions(\"disable:5\"));\n    assert(conf.parseOptions(\"disable:y\") && conf.disable);\n    assert(conf.parseOptions(\"disable:n\") && !conf.disable);\n    assert(conf.parseOptions(\"disable:Y\") && conf.disable);\n    assert(conf.parseOptions(\"disable:N\") && !conf.disable);\n    assert(conf.parseOptions(\"disable:1\") && conf.disable);\n    assert(conf.parseOptions(\"disable:0\") && !conf.disable);\n\n    assert(conf.parseOptions(\"disable=y\") && conf.disable);\n    assert(conf.parseOptions(\"disable=n\") && !conf.disable);\n\n    assert(conf.parseOptions(\"profile=0\") && conf.profile == 0);\n    assert(conf.parseOptions(\"profile=1\") && conf.profile == 1);\n    assert(conf.parseOptions(\"profile=2\") && conf.profile == 2);\n    assert(!conf.parseOptions(\"profile=256\"));\n\n    assert(conf.parseOptions(\"disable:1 minPoolSize:16\"));\n    assert(conf.disable);\n    assert(conf.minPoolSize == 16);\n\n    assert(conf.parseOptions(\"heapSizeFactor:3.1\"));\n    assert(conf.heapSizeFactor == 3.1f);\n    assert(conf.parseOptions(\"heapSizeFactor:3.1234567890 disable:0\"));\n    assert(conf.heapSizeFactor > 3.123f);\n    assert(!conf.disable);\n    assert(!conf.parseOptions(\"heapSizeFactor:3.0.2.5\"));\n    assert(conf.parseOptions(\"heapSizeFactor:2\"));\n    assert(conf.heapSizeFactor == 2.0f);\n\n    assert(!conf.parseOptions(\"initReserve:foo\"));\n    assert(!conf.parseOptions(\"initReserve:y\"));\n    assert(!conf.parseOptions(\"initReserve:20.5\"));\n\n    assert(conf.parseOptions(\"help\"));\n    assert(conf.parseOptions(\"help profile:1\"));\n    assert(conf.parseOptions(\"help profile:1 help\"));\n\n    assert(conf.parseOptions(\"gc:manual\") && conf.gc == \"manual\");\n    assert(conf.parseOptions(\"gc:my-gc~modified\") && conf.gc == \"my-gc~modified\");\n    assert(conf.parseOptions(\"gc:conservative help profile:1\") && conf.gc == \"conservative\" && conf.profile == 1);\n\n    // the config parse doesn't know all available GC names, so should accept unknown ones\n    assert(conf.parseOptions(\"gc:whatever\"));\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/internal/spinlock.d",
    "content": "/**\n * SpinLock for runtime internal usage.\n *\n * Copyright: Copyright Digital Mars 2015 -.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n * Source: $(DRUNTIMESRC core/internal/_spinlock.d)\n */\nmodule core.internal.spinlock;\n\nimport core.atomic, core.thread;\n\nshared struct SpinLock\n{\n    /// for how long is the lock usually contended\n    enum Contention : ubyte\n    {\n        brief,\n        medium,\n        lengthy,\n    }\n\n@trusted @nogc nothrow:\n    this(Contention contention)\n    {\n        this.contention = contention;\n    }\n\n    void lock()\n    {\n        if (cas(&val, size_t(0), size_t(1)))\n            return;\n        // Try to reduce the chance of another cas failure\n        // TTAS lock (https://en.wikipedia.org/wiki/Test_and_test-and-set)\n        immutable step = 1 << contention;\n        while (true)\n        {\n            for (size_t n; atomicLoad!(MemoryOrder.raw)(val); n += step)\n                yield(n);\n            if (cas(&val, size_t(0), size_t(1)))\n                return;\n        }\n    }\n\n    void unlock()\n    {\n        atomicStore!(MemoryOrder.rel)(val, size_t(0));\n    }\n\n    /// yield with backoff\n    void yield(size_t k)\n    {\n        if (k < pauseThresh)\n            return pause();\n        else if (k < 32)\n            return Thread.yield();\n        Thread.sleep(1.msecs);\n    }\n\nprivate:\n    version (D_InlineAsm_X86)\n        enum X86 = true;\n    else version (D_InlineAsm_X86_64)\n        enum X86 = true;\n    else\n        enum X86 = false;\n\n    static if (X86)\n    {\n        enum pauseThresh = 16;\n        void pause()\n        {\n            asm @trusted @nogc nothrow\n            {\n                // pause instruction\n                rep;\n                nop;\n            }\n        }\n    }\n    else\n    {\n        enum pauseThresh = 4;\n        void pause()\n        {\n        }\n    }\n\n    size_t val;\n    Contention contention;\n}\n\n// aligned to cacheline to avoid false sharing\nshared align(64) struct AlignedSpinLock\n{\n    this(SpinLock.Contention contention) @trusted @nogc nothrow\n    {\n        impl = shared(SpinLock)(contention);\n    }\n\n    SpinLock impl;\n    alias impl this;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/internal/string.d",
    "content": "/**\n * String manipulation and comparison utilities.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Walter Bright\n * Source: $(DRUNTIMESRC rt/util/_string.d)\n */\n\nmodule core.internal.string;\n\npure:\nnothrow:\n@nogc:\n\nalias UnsignedStringBuf = char[20];\n\n/**\nConverts an unsigned integer value to a string of characters.\n\nThis implementation is a template so it can be used when compiling with -betterC.\n\nParams:\n    value = the unsigned integer value to convert\n    buf   = the pre-allocated buffer used to store the result\n    radix = the numeric base to use in the conversion (defaults to 10)\n\nReturns:\n    The unsigned integer value as a string of characters\n*/\nchar[] unsignedToTempString()(ulong value, return scope char[] buf, uint radix = 10) @safe\n{\n    if (radix < 2)\n        // not a valid radix, just return an empty string\n        return buf[$ .. $];\n\n    size_t i = buf.length;\n    do\n    {\n        if (value < radix)\n        {\n            ubyte x = cast(ubyte)value;\n            buf[--i] = cast(char)((x < 10) ? x + '0' : x - 10 + 'a');\n            break;\n        }\n        else\n        {\n            ubyte x = cast(ubyte)(value % radix);\n            value = value / radix;\n            buf[--i] = cast(char)((x < 10) ? x + '0' : x - 10 + 'a');\n        }\n    } while (value);\n    return buf[i .. $];\n}\n\nprivate struct TempStringNoAlloc\n{\n    // need to handle 65 bytes for radix of 2 with negative sign.\n    private char[65] _buf;\n    private ubyte _len;\n    auto get() return\n    {\n        return _buf[$-_len..$];\n    }\n    alias get this;\n}\n\n/**\nConverts an unsigned integer value to a string of characters.\n\nThis implementation is a template so it can be used when compiling with -betterC.\n\nParams:\n    value = the unsigned integer value to convert\n    radix = the numeric base to use in the conversion (defaults to 10)\n\nReturns:\n    The unsigned integer value as a string of characters\n*/\nauto unsignedToTempString()(ulong value, uint radix = 10) @safe\n{\n    TempStringNoAlloc result = void;\n    result._len = unsignedToTempString(value, result._buf, radix).length & 0xff;\n    return result;\n}\n\nunittest\n{\n    UnsignedStringBuf buf;\n    assert(0.unsignedToTempString(buf, 10) == \"0\");\n    assert(1.unsignedToTempString(buf, 10) == \"1\");\n    assert(12.unsignedToTempString(buf, 10) == \"12\");\n    assert(0x12ABCF .unsignedToTempString(buf, 16) == \"12abcf\");\n    assert(long.sizeof.unsignedToTempString(buf, 10) == \"8\");\n    assert(uint.max.unsignedToTempString(buf, 10) == \"4294967295\");\n    assert(ulong.max.unsignedToTempString(buf, 10) == \"18446744073709551615\");\n\n    // use stack allocated struct version\n    assert(0.unsignedToTempString(10) == \"0\");\n    assert(1.unsignedToTempString == \"1\");\n    assert(12.unsignedToTempString == \"12\");\n    assert(0x12ABCF .unsignedToTempString(16) == \"12abcf\");\n    assert(long.sizeof.unsignedToTempString == \"8\");\n    assert(uint.max.unsignedToTempString == \"4294967295\");\n    assert(ulong.max.unsignedToTempString == \"18446744073709551615\");\n\n    // test bad radices\n    assert(100.unsignedToTempString(buf, 1) == \"\");\n    assert(100.unsignedToTempString(buf, 0) == \"\");\n}\n\nalias SignedStringBuf = char[20];\n\nchar[] signedToTempString(long value, return scope char[] buf, uint radix = 10) @safe\n{\n    bool neg = value < 0;\n    if (neg)\n        value = cast(ulong)-value;\n    auto r = unsignedToTempString(value, buf, radix);\n    if (neg)\n    {\n        // about to do a slice without a bounds check\n        auto trustedSlice(return char[] r) @trusted { assert(r.ptr > buf.ptr); return (r.ptr-1)[0..r.length+1]; }\n        r = trustedSlice(r);\n        r[0] = '-';\n    }\n    return r;\n}\n\nauto signedToTempString(long value, uint radix = 10) @safe\n{\n    bool neg = value < 0;\n    if (neg)\n        value = cast(ulong)-value;\n    auto r = unsignedToTempString(value, radix);\n    if (neg)\n    {\n        r._len++;\n        r.get()[0] = '-';\n    }\n    return r;\n}\n\nunittest\n{\n    SignedStringBuf buf;\n    assert(0.signedToTempString(buf, 10) == \"0\");\n    assert(1.signedToTempString(buf) == \"1\");\n    assert((-1).signedToTempString(buf) == \"-1\");\n    assert(12.signedToTempString(buf) == \"12\");\n    assert((-12).signedToTempString(buf) == \"-12\");\n    assert(0x12ABCF .signedToTempString(buf, 16) == \"12abcf\");\n    assert((-0x12ABCF) .signedToTempString(buf, 16) == \"-12abcf\");\n    assert(long.sizeof.signedToTempString(buf) == \"8\");\n    assert(int.max.signedToTempString(buf) == \"2147483647\");\n    assert(int.min.signedToTempString(buf) == \"-2147483648\");\n    assert(long.max.signedToTempString(buf) == \"9223372036854775807\");\n    assert(long.min.signedToTempString(buf) == \"-9223372036854775808\");\n\n    // use stack allocated struct version\n    assert(0.signedToTempString(10) == \"0\");\n    assert(1.signedToTempString == \"1\");\n    assert((-1).signedToTempString == \"-1\");\n    assert(12.signedToTempString == \"12\");\n    assert((-12).signedToTempString == \"-12\");\n    assert(0x12ABCF .signedToTempString(16) == \"12abcf\");\n    assert((-0x12ABCF) .signedToTempString(16) == \"-12abcf\");\n    assert(long.sizeof.signedToTempString == \"8\");\n    assert(int.max.signedToTempString == \"2147483647\");\n    assert(int.min.signedToTempString == \"-2147483648\");\n    assert(long.max.signedToTempString == \"9223372036854775807\");\n    assert(long.min.signedToTempString == \"-9223372036854775808\");\n    assert(long.max.signedToTempString(2) == \"111111111111111111111111111111111111111111111111111111111111111\");\n    assert(long.min.signedToTempString(2) == \"-1000000000000000000000000000000000000000000000000000000000000000\");\n}\n\n\n/********************************\n * Determine number of digits that will result from a\n * conversion of value to a string.\n * Params:\n *      value = number to convert\n *      radix = radix\n * Returns:\n *      number of digits\n */\nint numDigits(uint radix = 10)(ulong value) @safe if (radix >= 2 && radix <= 36)\n{\n     int n = 1;\n     while (1)\n     {\n        if (value <= uint.max)\n        {\n            uint v = cast(uint)value;\n            while (1)\n            {\n                if (v < radix)\n                    return n;\n                if (v < radix * radix)\n                    return n + 1;\n                if (v < radix * radix * radix)\n                    return n + 2;\n                if (v < radix * radix * radix * radix)\n                    return n + 3;\n                n += 4;\n                v /= radix * radix * radix * radix;\n            }\n        }\n        n += 4;\n        value /= radix * radix * radix * radix;\n     }\n}\n\nunittest\n{\n    assert(0.numDigits == 1);\n    assert(9.numDigits == 1);\n    assert(10.numDigits == 2);\n    assert(99.numDigits == 2);\n    assert(100.numDigits == 3);\n    assert(999.numDigits == 3);\n    assert(1000.numDigits == 4);\n    assert(9999.numDigits == 4);\n    assert(10000.numDigits == 5);\n    assert(99999.numDigits == 5);\n    assert(uint.max.numDigits == 10);\n    assert(ulong.max.numDigits == 20);\n\n    assert(0.numDigits!2 == 1);\n    assert(1.numDigits!2 == 1);\n    assert(2.numDigits!2 == 2);\n    assert(3.numDigits!2 == 2);\n\n    // test bad radices\n    static assert(!__traits(compiles, 100.numDigits!1()));\n    static assert(!__traits(compiles, 100.numDigits!0()));\n    static assert(!__traits(compiles, 100.numDigits!37()));\n}\n\nint dstrcmp()( scope const char[] s1, scope const char[] s2 ) @trusted\n{\n    immutable len = s1.length <= s2.length ? s1.length : s2.length;\n    if (__ctfe)\n    {\n        foreach (const u; 0 .. len)\n        {\n            if (s1[u] != s2[u])\n                return s1[u] > s2[u] ? 1 : -1;\n        }\n    }\n    else\n    {\n        import core.stdc.string : memcmp;\n\n        const ret = memcmp( s1.ptr, s2.ptr, len );\n        if ( ret )\n            return ret;\n    }\n    return s1.length < s2.length ? -1 : (s1.length > s2.length);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/internal/traits.d",
    "content": "/**\n * Contains traits for runtime internal usage.\n *\n * Copyright: Copyright Digital Mars 2014 -.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n * Source: $(DRUNTIMESRC core/internal/_traits.d)\n */\nmodule core.internal.traits;\n\n/// taken from std.typetuple.TypeTuple\ntemplate TypeTuple(TList...)\n{\n    alias TypeTuple = TList;\n}\n\nT trustedCast(T, U)(auto ref U u) @trusted pure nothrow\n{\n    return cast(T)u;\n}\n\ntemplate Unconst(T)\n{\n         static if (is(T U ==   immutable U)) alias Unconst = U;\n    else static if (is(T U == inout const U)) alias Unconst = U;\n    else static if (is(T U == inout       U)) alias Unconst = U;\n    else static if (is(T U ==       const U)) alias Unconst = U;\n    else                                      alias Unconst = T;\n}\n\n/// taken from std.traits.Unqual\ntemplate Unqual(T)\n{\n    version (none) // Error: recursive alias declaration @@@BUG1308@@@\n    {\n             static if (is(T U ==     const U)) alias Unqual = Unqual!U;\n        else static if (is(T U == immutable U)) alias Unqual = Unqual!U;\n        else static if (is(T U ==     inout U)) alias Unqual = Unqual!U;\n        else static if (is(T U ==    shared U)) alias Unqual = Unqual!U;\n        else                                    alias Unqual =        T;\n    }\n    else // workaround\n    {\n             static if (is(T U ==          immutable U)) alias Unqual = U;\n        else static if (is(T U == shared inout const U)) alias Unqual = U;\n        else static if (is(T U == shared inout       U)) alias Unqual = U;\n        else static if (is(T U == shared       const U)) alias Unqual = U;\n        else static if (is(T U == shared             U)) alias Unqual = U;\n        else static if (is(T U ==        inout const U)) alias Unqual = U;\n        else static if (is(T U ==        inout       U)) alias Unqual = U;\n        else static if (is(T U ==              const U)) alias Unqual = U;\n        else                                             alias Unqual = T;\n    }\n}\n\n// Substitute all `inout` qualifiers that appears in T to `const`\ntemplate substInout(T)\n{\n    static if (is(T == immutable))\n    {\n        alias substInout = T;\n    }\n    else static if (is(T : shared const U, U) || is(T : const U, U))\n    {\n        // U is top-unqualified\n        mixin(\"alias substInout = \"\n            ~ (is(T == shared) ? \"shared \" : \"\")\n            ~ (is(T == const) || is(T == inout) ? \"const \" : \"\")    // substitute inout to const\n            ~ \"substInoutForm!U;\");\n    }\n    else\n        static assert(0);\n}\n\nprivate template substInoutForm(T)\n{\n    static if (is(T == struct) || is(T == class) || is(T == union) || is(T == interface))\n    {\n        alias substInoutForm = T;   // prevent matching to the form of alias-this-ed type\n    }\n    else static if (is(T : V[K], K, V))        alias substInoutForm = substInout!V[substInout!K];\n    else static if (is(T : U[n], U, size_t n)) alias substInoutForm = substInout!U[n];\n    else static if (is(T : U[], U))            alias substInoutForm = substInout!U[];\n    else static if (is(T : U*, U))             alias substInoutForm = substInout!U*;\n    else                                       alias substInoutForm = T;\n}\n\n/// used to declare an extern(D) function that is defined in a different module\ntemplate externDFunc(string fqn, T:FT*, FT) if (is(FT == function))\n{\n    static if (is(FT RT == return) && is(FT Args == function))\n    {\n        import core.demangle : mangleFunc;\n        enum decl = {\n            string s = \"extern(D) RT externDFunc(Args)\";\n            foreach (attr; __traits(getFunctionAttributes, FT))\n                s ~= \" \" ~ attr;\n            return s ~ \";\";\n        }();\n        pragma(mangle, mangleFunc!T(fqn)) mixin(decl);\n    }\n    else\n        static assert(0);\n}\n\ntemplate staticIota(int beg, int end)\n{\n    static if (beg + 1 >= end)\n    {\n        static if (beg >= end)\n        {\n            alias staticIota = TypeTuple!();\n        }\n        else\n        {\n            alias staticIota = TypeTuple!(+beg);\n        }\n    }\n    else\n    {\n        enum mid = beg + (end - beg) / 2;\n        alias staticIota = TypeTuple!(staticIota!(beg, mid), staticIota!(mid, end));\n    }\n}\n\ntemplate dtorIsNothrow(T)\n{\n    enum dtorIsNothrow = is(typeof(function{T t=void;}) : void function() nothrow);\n}\n\n// taken from std.meta.allSatisfy\npackage(core.internal)\ntemplate allSatisfy(alias F, T...)\n{\n    static foreach (Ti; T)\n    {\n        static if (!is(typeof(allSatisfy) == bool) && // not yet defined\n                   !F!(Ti))\n        {\n            enum allSatisfy = false;\n        }\n    }\n    static if (!is(typeof(allSatisfy) == bool)) // if not yet defined\n    {\n        enum allSatisfy = true;\n    }\n}\n\n// taken from std.meta.anySatisfy\ntemplate anySatisfy(alias F, T...)\n{\n    static foreach (Ti; T)\n    {\n        static if (!is(typeof(anySatisfy) == bool) && // not yet defined\n                   F!(Ti))\n        {\n            enum anySatisfy = true;\n        }\n    }\n    static if (!is(typeof(anySatisfy) == bool)) // if not yet defined\n    {\n        enum anySatisfy = false;\n    }\n}\n\n// Somehow fails for non-static nested structs without support for aliases\ntemplate hasElaborateDestructor(T...)\n{\n    static if (is(T[0]))\n        alias S = T[0];\n    else\n        alias S = typeof(T[0]);\n\n    static if (is(S : E[n], E, size_t n) && S.length)\n    {\n        enum bool hasElaborateDestructor = hasElaborateDestructor!E;\n    }\n    else static if (is(S == struct))\n    {\n        enum hasElaborateDestructor = __traits(hasMember, S, \"__dtor\")\n            || anySatisfy!(.hasElaborateDestructor, S.tupleof);\n    }\n    else\n        enum bool hasElaborateDestructor = false;\n}\n\n// Somehow fails for non-static nested structs without support for aliases\ntemplate hasElaborateCopyConstructor(T...)\n{\n    static if (is(T[0]))\n        alias S = T[0];\n    else\n        alias S = typeof(T[0]);\n\n    static if (is(S : E[n], E, size_t n) && S.length)\n    {\n        enum bool hasElaborateCopyConstructor = hasElaborateCopyConstructor!E;\n    }\n    else static if (is(S == struct))\n    {\n        enum hasElaborateCopyConstructor = __traits(hasMember, S, \"__postblit\")\n            || anySatisfy!(.hasElaborateCopyConstructor, S.tupleof);\n    }\n    else\n        enum bool hasElaborateCopyConstructor = false;\n}\n\n// std.meta.Filter\ntemplate Filter(alias pred, TList...)\n{\n    static if (TList.length == 0)\n    {\n        alias Filter = TypeTuple!();\n    }\n    else static if (TList.length == 1)\n    {\n        static if (pred!(TList[0]))\n            alias Filter = TypeTuple!(TList[0]);\n        else\n            alias Filter = TypeTuple!();\n    }\n    else\n    {\n        alias Filter =\n            TypeTuple!(\n                Filter!(pred, TList[ 0  .. $/2]),\n                Filter!(pred, TList[$/2 ..  $ ]));\n    }\n}\n\n// std.meta.staticMap\ntemplate staticMap(alias F, T...)\n{\n    static if (T.length == 0)\n    {\n        alias staticMap = TypeTuple!();\n    }\n    else static if (T.length == 1)\n    {\n        alias staticMap = TypeTuple!(F!(T[0]));\n    }\n    else\n    {\n        alias staticMap =\n            TypeTuple!(\n                staticMap!(F, T[ 0  .. $/2]),\n                staticMap!(F, T[$/2 ..  $ ]));\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/math.d",
    "content": "﻿// Written in the D programming language.\n\n/**\n * Builtin mathematical intrinsics\n *\n * Source: $(DRUNTIMESRC core/_math.d)\n * Macros:\n *      TABLE_SV = <table border=\"1\" cellpadding=\"4\" cellspacing=\"0\">\n *              <caption>Special Values</caption>\n *              $0</table>\n *\n *      NAN = $(RED NAN)\n *      SUP = <span style=\"vertical-align:super;font-size:smaller\">$0</span>\n *      POWER = $1<sup>$2</sup>\n *      PLUSMN = &plusmn;\n *      INFIN = &infin;\n *      PLUSMNINF = &plusmn;&infin;\n *      LT = &lt;\n *      GT = &gt;\n *\n * Copyright: Copyright Digital Mars 2000 - 2011.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright),\n *                        Don Clugston\n */\nmodule core.math;\n\npublic:\n@nogc:\n\n/***********************************\n * Returns cosine of x. x is in radians.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)                 $(TH cos(x)) $(TH invalid?))\n *      $(TR $(TD $(NAN))            $(TD $(NAN)) $(TD yes)     )\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(NAN)) $(TD yes)     )\n *      )\n * Bugs:\n *      Results are undefined if |x| >= $(POWER 2,64).\n */\n\nreal cos(real x) @safe pure nothrow;       /* intrinsic */\n\n/***********************************\n * Returns sine of x. x is in radians.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)               $(TH sin(x))      $(TH invalid?))\n *      $(TR $(TD $(NAN))          $(TD $(NAN))      $(TD yes))\n *      $(TR $(TD $(PLUSMN)0.0)    $(TD $(PLUSMN)0.0) $(TD no))\n *      $(TR $(TD $(PLUSMNINF))    $(TD $(NAN))      $(TD yes))\n *      )\n * Bugs:\n *      Results are undefined if |x| >= $(POWER 2,64).\n */\n\nreal sin(real x) @safe pure nothrow;       /* intrinsic */\n\n/*****************************************\n * Returns x rounded to a long value using the current rounding mode.\n * If the integer value of x is\n * greater than long.max, the result is\n * indeterminate.\n */\nlong rndtol(real x) @safe pure nothrow;    /* intrinsic */\n\n\n/*****************************************\n * Returns x rounded to a long value using the FE_TONEAREST rounding mode.\n * If the integer value of x is\n * greater than long.max, the result is\n * indeterminate.\n */\nextern (C) real rndtonl(real x);\n\n/***************************************\n * Compute square root of x.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)         $(TH sqrt(x))   $(TH invalid?))\n *      $(TR $(TD -0.0)      $(TD -0.0)      $(TD no))\n *      $(TR $(TD $(LT)0.0)  $(TD $(NAN))    $(TD yes))\n *      $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no))\n *      )\n */\n\n@safe pure nothrow\n{\n    float sqrt(float x);    /* intrinsic */\n    double sqrt(double x);  /* intrinsic */ /// ditto\n    real sqrt(real x);      /* intrinsic */ /// ditto\n}\n\n/*******************************************\n * Compute n * 2$(SUPERSCRIPT exp)\n * References: frexp\n */\n\nreal ldexp(real n, int exp) @safe pure nothrow;    /* intrinsic */\n\nunittest {\n    static if (real.mant_dig == 113)\n    {\n        assert(ldexp(1, -16384) == 0x1p-16384L);\n        assert(ldexp(1, -16382) == 0x1p-16382L);\n    }\n    else static if (real.mant_dig == 106)\n    {\n        assert(ldexp(1,  1023) == 0x1p1023L);\n        assert(ldexp(1, -1022) == 0x1p-1022L);\n        assert(ldexp(1, -1021) == 0x1p-1021L);\n    }\n    else static if (real.mant_dig == 64)\n    {\n        assert(ldexp(1, -16384) == 0x1p-16384L);\n        assert(ldexp(1, -16382) == 0x1p-16382L);\n    }\n    else static if (real.mant_dig == 53)\n    {\n        assert(ldexp(1,  1023) == 0x1p1023L);\n        assert(ldexp(1, -1022) == 0x1p-1022L);\n        assert(ldexp(1, -1021) == 0x1p-1021L);\n    }\n    else\n        assert(false, \"Only 128bit, 80bit and 64bit reals expected here\");\n}\n\n/*******************************\n * Returns |x|\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)                 $(TH fabs(x)))\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD +0.0) )\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD +$(INFIN)) )\n *      )\n */\nreal fabs(real x) @safe pure nothrow;      /* intrinsic */\n\n/**********************************\n * Rounds x to the nearest integer value, using the current rounding\n * mode.\n * If the return value is not equal to x, the FE_INEXACT\n * exception is raised.\n * $(B nearbyint) performs\n * the same operation, but does not set the FE_INEXACT exception.\n */\nreal rint(real x) @safe pure nothrow;      /* intrinsic */\n\n/***********************************\n * Building block functions, they\n * translate to a single x87 instruction.\n */\n\nreal yl2x(real x, real y)   @safe pure nothrow;       // y * log2(x)\nreal yl2xp1(real x, real y) @safe pure nothrow;       // y * log2(x + 1)\n\nunittest\n{\n    version (INLINE_YL2X)\n    {\n        assert(yl2x(1024, 1) == 10);\n        assert(yl2xp1(1023, 1) == 10);\n    }\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/memory.d",
    "content": "/**\n * This module provides an interface to the garbage collector used by\n * applications written in the D programming language. It allows the\n * garbage collector in the runtime to be swapped without affecting\n * binary compatibility of applications.\n *\n * Using this module is not necessary in typical D code. It is mostly\n * useful when doing low-level _memory management.\n *\n * Notes_to_users:\n *\n   $(OL\n   $(LI The GC is a conservative mark-and-sweep collector. It only runs a\n        collection cycle when an allocation is requested of it, never\n        otherwise. Hence, if the program is not doing allocations,\n        there will be no GC collection pauses. The pauses occur because\n        all threads the GC knows about are halted so the threads' stacks\n        and registers can be scanned for references to GC allocated data.\n   )\n\n   $(LI The GC does not know about threads that were created by directly calling\n        the OS/C runtime thread creation APIs and D threads that were detached\n        from the D runtime after creation.\n        Such threads will not be paused for a GC collection, and the GC might not detect\n        references to GC allocated data held by them. This can cause memory corruption.\n        There are several ways to resolve this issue:\n        $(OL\n        $(LI Do not hold references to GC allocated data in such threads.)\n        $(LI Register/unregister such data with calls to $(LREF addRoot)/$(LREF removeRoot) and\n        $(LREF addRange)/$(LREF removeRange).)\n        $(LI Maintain another reference to that same data in another thread that the\n        GC does know about.)\n        $(LI Disable GC collection cycles while that thread is active with $(LREF disable)/$(LREF enable).)\n        $(LI Register the thread with the GC using $(REF thread_attachThis, core,thread)/$(REF thread_detachThis, core,thread).)\n        )\n   )\n   )\n *\n * Notes_to_implementors:\n * $(UL\n * $(LI On POSIX systems, the signals SIGUSR1 and SIGUSR2 are reserved\n *   by this module for use in the garbage collector implementation.\n *   Typically, they will be used to stop and resume other threads\n *   when performing a collection, but an implementation may choose\n *   not to use this mechanism (or not stop the world at all, in the\n *   case of concurrent garbage collectors).)\n *\n * $(LI Registers, the stack, and any other _memory locations added through\n *   the $(D GC.$(LREF addRange)) function are always scanned conservatively.\n *   This means that even if a variable is e.g. of type $(D float),\n *   it will still be scanned for possible GC pointers. And, if the\n *   word-interpreted representation of the variable matches a GC-managed\n *   _memory block's address, that _memory block is considered live.)\n *\n * $(LI Implementations are free to scan the non-root heap in a precise\n *   manner, so that fields of types like $(D float) will not be considered\n *   relevant when scanning the heap. Thus, casting a GC pointer to an\n *   integral type (e.g. $(D size_t)) and storing it in a field of that\n *   type inside the GC heap may mean that it will not be recognized\n *   if the _memory block was allocated with precise type info or with\n *   the $(D GC.BlkAttr.$(LREF NO_SCAN)) attribute.)\n *\n * $(LI Destructors will always be executed while other threads are\n *   active; that is, an implementation that stops the world must not\n *   execute destructors until the world has been resumed.)\n *\n * $(LI A destructor of an object must not access object references\n *   within the object. This means that an implementation is free to\n *   optimize based on this rule.)\n *\n * $(LI An implementation is free to perform heap compaction and copying\n *   so long as no valid GC pointers are invalidated in the process.\n *   However, _memory allocated with $(D GC.BlkAttr.$(LREF NO_MOVE)) must\n *   not be moved/copied.)\n *\n * $(LI Implementations must support interior pointers. That is, if the\n *   only reference to a GC-managed _memory block points into the\n *   middle of the block rather than the beginning (for example), the\n *   GC must consider the _memory block live. The exception to this\n *   rule is when a _memory block is allocated with the\n *   $(D GC.BlkAttr.$(LREF NO_INTERIOR)) attribute; it is the user's\n *   responsibility to make sure such _memory blocks have a proper pointer\n *   to them when they should be considered live.)\n *\n * $(LI It is acceptable for an implementation to store bit flags into\n *   pointer values and GC-managed _memory blocks, so long as such a\n *   trick is not visible to the application. In practice, this means\n *   that only a stop-the-world collector can do this.)\n *\n * $(LI Implementations are free to assume that GC pointers are only\n *   stored on word boundaries. Unaligned pointers may be ignored\n *   entirely.)\n *\n * $(LI Implementations are free to run collections at any point. It is,\n *   however, recommendable to only do so when an allocation attempt\n *   happens and there is insufficient _memory available.)\n * )\n *\n * Copyright: Copyright Sean Kelly 2005 - 2015.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Source:    $(DRUNTIMESRC core/_memory.d)\n */\n\nmodule core.memory;\n\n\nprivate\n{\n    extern (C) void gc_init();\n    extern (C) void gc_term();\n\n    extern (C) void gc_enable() nothrow;\n    extern (C) void gc_disable() nothrow;\n    extern (C) void gc_collect() nothrow;\n    extern (C) void gc_minimize() nothrow;\n\n    extern (C) uint gc_getAttr( void* p ) pure nothrow;\n    extern (C) uint gc_setAttr( void* p, uint a ) pure nothrow;\n    extern (C) uint gc_clrAttr( void* p, uint a ) pure nothrow;\n\n    extern (C) void*    gc_malloc( size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow;\n    extern (C) void*    gc_calloc( size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow;\n    extern (C) BlkInfo_ gc_qalloc( size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow;\n    extern (C) void*    gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow;\n    extern (C) size_t   gc_extend( void* p, size_t mx, size_t sz, const TypeInfo = null ) pure nothrow;\n    extern (C) size_t   gc_reserve( size_t sz ) nothrow;\n    extern (C) void     gc_free( void* p ) pure nothrow @nogc;\n\n    extern (C) void*   gc_addrOf( void* p ) pure nothrow @nogc;\n    extern (C) size_t  gc_sizeOf( void* p ) pure nothrow @nogc;\n\n    struct BlkInfo_\n    {\n        void*  base;\n        size_t size;\n        uint   attr;\n    }\n\n    extern (C) BlkInfo_ gc_query( void* p ) pure nothrow;\n    extern (C) GC.Stats gc_stats ( ) nothrow @nogc;\n\n    extern (C) void gc_addRoot( in void* p ) nothrow @nogc;\n    extern (C) void gc_addRange( in void* p, size_t sz, const TypeInfo ti = null ) nothrow @nogc;\n\n    extern (C) void gc_removeRoot( in void* p ) nothrow @nogc;\n    extern (C) void gc_removeRange( in void* p ) nothrow @nogc;\n    extern (C) void gc_runFinalizers( in void[] segment );\n\n    package extern (C) bool gc_inFinalizer();\n}\n\n\n/**\n * This struct encapsulates all garbage collection functionality for the D\n * programming language.\n */\nstruct GC\n{\n    @disable this();\n\n    /**\n     * Aggregation of GC stats to be exposed via public API\n     */\n    static struct Stats\n    {\n        /// number of used bytes on the GC heap (might only get updated after a collection)\n        size_t usedSize;\n        /// number of free bytes on the GC heap (might only get updated after a collection)\n        size_t freeSize;\n    }\n\n    /**\n     * Enables automatic garbage collection behavior if collections have\n     * previously been suspended by a call to disable.  This function is\n     * reentrant, and must be called once for every call to disable before\n     * automatic collections are enabled.\n     */\n    static void enable() nothrow /* FIXME pure */\n    {\n        gc_enable();\n    }\n\n\n    /**\n     * Disables automatic garbage collections performed to minimize the\n     * process footprint.  Collections may continue to occur in instances\n     * where the implementation deems necessary for correct program behavior,\n     * such as during an out of memory condition.  This function is reentrant,\n     * but enable must be called once for each call to disable.\n     */\n    static void disable() nothrow /* FIXME pure */\n    {\n        gc_disable();\n    }\n\n\n    /**\n     * Begins a full collection.  While the meaning of this may change based\n     * on the garbage collector implementation, typical behavior is to scan\n     * all stack segments for roots, mark accessible memory blocks as alive,\n     * and then to reclaim free space.  This action may need to suspend all\n     * running threads for at least part of the collection process.\n     */\n    static void collect() nothrow /* FIXME pure */\n    {\n        gc_collect();\n    }\n\n    /**\n     * Indicates that the managed memory space be minimized by returning free\n     * physical memory to the operating system.  The amount of free memory\n     * returned depends on the allocator design and on program behavior.\n     */\n    static void minimize() nothrow /* FIXME pure */\n    {\n        gc_minimize();\n    }\n\n\n    /**\n     * Elements for a bit field representing memory block attributes.  These\n     * are manipulated via the getAttr, setAttr, clrAttr functions.\n     */\n    enum BlkAttr : uint\n    {\n        NONE        = 0b0000_0000, /// No attributes set.\n        FINALIZE    = 0b0000_0001, /// Finalize the data in this block on collect.\n        NO_SCAN     = 0b0000_0010, /// Do not scan through this block on collect.\n        NO_MOVE     = 0b0000_0100, /// Do not move this memory block on collect.\n        /**\n        This block contains the info to allow appending.\n\n        This can be used to manually allocate arrays. Initial slice size is 0.\n\n        Note: The slice's usable size will not match the block size. Use\n        $(LREF capacity) to retrieve actual usable capacity.\n\n        Example:\n        ----\n        // Allocate the underlying array.\n        int*  pToArray = cast(int*)GC.malloc(10 * int.sizeof, GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE);\n        // Bind a slice. Check the slice has capacity information.\n        int[] slice = pToArray[0 .. 0];\n        assert(capacity(slice) > 0);\n        // Appending to the slice will not relocate it.\n        slice.length = 5;\n        slice ~= 1;\n        assert(slice.ptr == p);\n        ----\n        */\n        APPENDABLE  = 0b0000_1000,\n\n        /**\n        This block is guaranteed to have a pointer to its base while it is\n        alive.  Interior pointers can be safely ignored.  This attribute is\n        useful for eliminating false pointers in very large data structures\n        and is only implemented for data structures at least a page in size.\n        */\n        NO_INTERIOR = 0b0001_0000,\n\n        STRUCTFINAL = 0b0010_0000, // the block has a finalizer for (an array of) structs\n    }\n\n\n    /**\n     * Contains aggregate information about a block of managed memory.  The\n     * purpose of this struct is to support a more efficient query style in\n     * instances where detailed information is needed.\n     *\n     * base = A pointer to the base of the block in question.\n     * size = The size of the block, calculated from base.\n     * attr = Attribute bits set on the memory block.\n     */\n    alias BlkInfo = BlkInfo_;\n\n\n    /**\n     * Returns a bit field representing all block attributes set for the memory\n     * referenced by p.  If p references memory not originally allocated by\n     * this garbage collector, points to the interior of a memory block, or if\n     * p is null, zero will be returned.\n     *\n     * Params:\n     *  p = A pointer to the root of a valid memory block or to null.\n     *\n     * Returns:\n     *  A bit field containing any bits set for the memory block referenced by\n     *  p or zero on error.\n     */\n    static uint getAttr( in void* p ) nothrow\n    {\n        return getAttr(cast()p);\n    }\n\n\n    /// ditto\n    static uint getAttr(void* p) pure nothrow\n    {\n        return gc_getAttr( p );\n    }\n\n\n    /**\n     * Sets the specified bits for the memory references by p.  If p references\n     * memory not originally allocated by this garbage collector, points to the\n     * interior of a memory block, or if p is null, no action will be\n     * performed.\n     *\n     * Params:\n     *  p = A pointer to the root of a valid memory block or to null.\n     *  a = A bit field containing any bits to set for this memory block.\n     *\n     * Returns:\n     *  The result of a call to getAttr after the specified bits have been\n     *  set.\n     */\n    static uint setAttr( in void* p, uint a ) nothrow\n    {\n        return setAttr(cast()p, a);\n    }\n\n\n    /// ditto\n    static uint setAttr(void* p, uint a) pure nothrow\n    {\n        return gc_setAttr( p, a );\n    }\n\n\n    /**\n     * Clears the specified bits for the memory references by p.  If p\n     * references memory not originally allocated by this garbage collector,\n     * points to the interior of a memory block, or if p is null, no action\n     * will be performed.\n     *\n     * Params:\n     *  p = A pointer to the root of a valid memory block or to null.\n     *  a = A bit field containing any bits to clear for this memory block.\n     *\n     * Returns:\n     *  The result of a call to getAttr after the specified bits have been\n     *  cleared.\n     */\n    static uint clrAttr( in void* p, uint a ) nothrow\n    {\n        return clrAttr(cast()p, a);\n    }\n\n\n    /// ditto\n    static uint clrAttr(void* p, uint a) pure nothrow\n    {\n        return gc_clrAttr( p, a );\n    }\n\n\n    /**\n     * Requests an aligned block of managed memory from the garbage collector.\n     * This memory may be deleted at will with a call to free, or it may be\n     * discarded and cleaned up automatically during a collection run.  If\n     * allocation fails, this function will call onOutOfMemory which is\n     * expected to throw an OutOfMemoryError.\n     *\n     * Params:\n     *  sz = The desired allocation size in bytes.\n     *  ba = A bitmask of the attributes to set on this block.\n     *  ti = TypeInfo to describe the memory. The GC might use this information\n     *       to improve scanning for pointers or to call finalizers.\n     *\n     * Returns:\n     *  A reference to the allocated memory or null if insufficient memory\n     *  is available.\n     *\n     * Throws:\n     *  OutOfMemoryError on allocation failure.\n     */\n    static void* malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow\n    {\n        return gc_malloc( sz, ba, ti );\n    }\n\n\n    /**\n     * Requests an aligned block of managed memory from the garbage collector.\n     * This memory may be deleted at will with a call to free, or it may be\n     * discarded and cleaned up automatically during a collection run.  If\n     * allocation fails, this function will call onOutOfMemory which is\n     * expected to throw an OutOfMemoryError.\n     *\n     * Params:\n     *  sz = The desired allocation size in bytes.\n     *  ba = A bitmask of the attributes to set on this block.\n     *  ti = TypeInfo to describe the memory. The GC might use this information\n     *       to improve scanning for pointers or to call finalizers.\n     *\n     * Returns:\n     *  Information regarding the allocated memory block or BlkInfo.init on\n     *  error.\n     *\n     * Throws:\n     *  OutOfMemoryError on allocation failure.\n     */\n    static BlkInfo qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow\n    {\n        return gc_qalloc( sz, ba, ti );\n    }\n\n\n    /**\n     * Requests an aligned block of managed memory from the garbage collector,\n     * which is initialized with all bits set to zero.  This memory may be\n     * deleted at will with a call to free, or it may be discarded and cleaned\n     * up automatically during a collection run.  If allocation fails, this\n     * function will call onOutOfMemory which is expected to throw an\n     * OutOfMemoryError.\n     *\n     * Params:\n     *  sz = The desired allocation size in bytes.\n     *  ba = A bitmask of the attributes to set on this block.\n     *  ti = TypeInfo to describe the memory. The GC might use this information\n     *       to improve scanning for pointers or to call finalizers.\n     *\n     * Returns:\n     *  A reference to the allocated memory or null if insufficient memory\n     *  is available.\n     *\n     * Throws:\n     *  OutOfMemoryError on allocation failure.\n     */\n    static void* calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow\n    {\n        return gc_calloc( sz, ba, ti );\n    }\n\n\n    /**\n     * If sz is zero, the memory referenced by p will be deallocated as if\n     * by a call to free.  A new memory block of size sz will then be\n     * allocated as if by a call to malloc, or the implementation may instead\n     * resize the memory block in place.  The contents of the new memory block\n     * will be the same as the contents of the old memory block, up to the\n     * lesser of the new and old sizes.  Note that existing memory will only\n     * be freed by realloc if sz is equal to zero.  The garbage collector is\n     * otherwise expected to later reclaim the memory block if it is unused.\n     * If allocation fails, this function will call onOutOfMemory which is\n     * expected to throw an OutOfMemoryError.  If p references memory not\n     * originally allocated by this garbage collector, or if it points to the\n     * interior of a memory block, no action will be taken.  If ba is zero\n     * (the default) and p references the head of a valid, known memory block\n     * then any bits set on the current block will be set on the new block if a\n     * reallocation is required.  If ba is not zero and p references the head\n     * of a valid, known memory block then the bits in ba will replace those on\n     * the current memory block and will also be set on the new block if a\n     * reallocation is required.\n     *\n     * Params:\n     *  p  = A pointer to the root of a valid memory block or to null.\n     *  sz = The desired allocation size in bytes.\n     *  ba = A bitmask of the attributes to set on this block.\n     *  ti = TypeInfo to describe the memory. The GC might use this information\n     *       to improve scanning for pointers or to call finalizers.\n     *\n     * Returns:\n     *  A reference to the allocated memory on success or null if sz is\n     *  zero.  On failure, the original value of p is returned.\n     *\n     * Throws:\n     *  OutOfMemoryError on allocation failure.\n     */\n    static void* realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow\n    {\n        return gc_realloc( p, sz, ba, ti );\n    }\n\n    /// Issue 13111\n    unittest\n    {\n        enum size1 = 1 << 11 + 1; // page in large object pool\n        enum size2 = 1 << 22 + 1; // larger than large object pool size\n\n        auto data1 = cast(ubyte*)GC.calloc(size1);\n        auto data2 = cast(ubyte*)GC.realloc(data1, size2);\n\n        BlkInfo info = query(data2);\n        assert(info.size >= size2);\n    }\n\n\n    /**\n     * Requests that the managed memory block referenced by p be extended in\n     * place by at least mx bytes, with a desired extension of sz bytes.  If an\n     * extension of the required size is not possible or if p references memory\n     * not originally allocated by this garbage collector, no action will be\n     * taken.\n     *\n     * Params:\n     *  p  = A pointer to the root of a valid memory block or to null.\n     *  mx = The minimum extension size in bytes.\n     *  sz = The desired extension size in bytes.\n     *  ti = TypeInfo to describe the full memory block. The GC might use\n     *       this information to improve scanning for pointers or to\n     *       call finalizers.\n     *\n     * Returns:\n     *  The size in bytes of the extended memory block referenced by p or zero\n     *  if no extension occurred.\n     *\n     * Note:\n     *  Extend may also be used to extend slices (or memory blocks with\n     *  $(LREF APPENDABLE) info). However, use the return value only\n     *  as an indicator of success. $(LREF capacity) should be used to\n     *  retrieve actual usable slice capacity.\n     */\n    static size_t extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) pure nothrow\n    {\n        return gc_extend( p, mx, sz, ti );\n    }\n    /// Standard extending\n    unittest\n    {\n        size_t size = 1000;\n        int* p = cast(int*)GC.malloc(size * int.sizeof, GC.BlkAttr.NO_SCAN);\n\n        //Try to extend the allocated data by 1000 elements, preferred 2000.\n        size_t u = GC.extend(p, 1000 * int.sizeof, 2000 * int.sizeof);\n        if (u != 0)\n            size = u / int.sizeof;\n    }\n    /// slice extending\n    unittest\n    {\n        int[] slice = new int[](1000);\n        int*  p     = slice.ptr;\n\n        //Check we have access to capacity before attempting the extend\n        if (slice.capacity)\n        {\n            //Try to extend slice by 1000 elements, preferred 2000.\n            size_t u = GC.extend(p, 1000 * int.sizeof, 2000 * int.sizeof);\n            if (u != 0)\n            {\n                slice.length = slice.capacity;\n                assert(slice.length >= 2000);\n            }\n        }\n    }\n\n\n    /**\n     * Requests that at least sz bytes of memory be obtained from the operating\n     * system and marked as free.\n     *\n     * Params:\n     *  sz = The desired size in bytes.\n     *\n     * Returns:\n     *  The actual number of bytes reserved or zero on error.\n     */\n    static size_t reserve( size_t sz ) nothrow /* FIXME pure */\n    {\n        return gc_reserve( sz );\n    }\n\n\n    /**\n     * Deallocates the memory referenced by p.  If p is null, no action occurs.\n     * If p references memory not originally allocated by this garbage\n     * collector, if p points to the interior of a memory block, or if this\n     * method is called from a finalizer, no action will be taken.  The block\n     * will not be finalized regardless of whether the FINALIZE attribute is\n     * set.  If finalization is desired, use delete instead.\n     *\n     * Params:\n     *  p = A pointer to the root of a valid memory block or to null.\n     */\n    static void free( void* p ) pure nothrow @nogc\n    {\n        gc_free( p );\n    }\n\n\n    /**\n     * Returns the base address of the memory block containing p.  This value\n     * is useful to determine whether p is an interior pointer, and the result\n     * may be passed to routines such as sizeOf which may otherwise fail.  If p\n     * references memory not originally allocated by this garbage collector, if\n     * p is null, or if the garbage collector does not support this operation,\n     * null will be returned.\n     *\n     * Params:\n     *  p = A pointer to the root or the interior of a valid memory block or to\n     *      null.\n     *\n     * Returns:\n     *  The base address of the memory block referenced by p or null on error.\n     */\n    static inout(void)* addrOf( inout(void)* p ) nothrow @nogc /* FIXME pure */\n    {\n        return cast(inout(void)*)gc_addrOf(cast(void*)p);\n    }\n\n\n    /// ditto\n    static void* addrOf(void* p) pure nothrow @nogc\n    {\n        return gc_addrOf(p);\n    }\n\n\n    /**\n     * Returns the true size of the memory block referenced by p.  This value\n     * represents the maximum number of bytes for which a call to realloc may\n     * resize the existing block in place.  If p references memory not\n     * originally allocated by this garbage collector, points to the interior\n     * of a memory block, or if p is null, zero will be returned.\n     *\n     * Params:\n     *  p = A pointer to the root of a valid memory block or to null.\n     *\n     * Returns:\n     *  The size in bytes of the memory block referenced by p or zero on error.\n     */\n    static size_t sizeOf( in void* p ) nothrow @nogc /* FIXME pure */\n    {\n        return gc_sizeOf(cast(void*)p);\n    }\n\n\n    /// ditto\n    static size_t sizeOf(void* p) pure nothrow @nogc\n    {\n        return gc_sizeOf( p );\n    }\n\n    // verify that the reallocation doesn't leave the size cache in a wrong state\n    unittest\n    {\n        auto data = cast(int*)realloc(null, 4096);\n        size_t size = GC.sizeOf(data);\n        assert(size >= 4096);\n        data = cast(int*)GC.realloc(data, 4100);\n        size = GC.sizeOf(data);\n        assert(size >= 4100);\n    }\n\n    /**\n     * Returns aggregate information about the memory block containing p.  If p\n     * references memory not originally allocated by this garbage collector, if\n     * p is null, or if the garbage collector does not support this operation,\n     * BlkInfo.init will be returned.  Typically, support for this operation\n     * is dependent on support for addrOf.\n     *\n     * Params:\n     *  p = A pointer to the root or the interior of a valid memory block or to\n     *      null.\n     *\n     * Returns:\n     *  Information regarding the memory block referenced by p or BlkInfo.init\n     *  on error.\n     */\n    static BlkInfo query( in void* p ) nothrow\n    {\n        return gc_query(cast(void*)p);\n    }\n\n\n    /// ditto\n    static BlkInfo query(void* p) pure nothrow\n    {\n        return gc_query( p );\n    }\n\n    /**\n     * Returns runtime stats for currently active GC implementation\n     * See `core.memory.GC.Stats` for list of available metrics.\n     */\n    static Stats stats() nothrow\n    {\n        return gc_stats();\n    }\n\n    /**\n     * Adds an internal root pointing to the GC memory block referenced by p.\n     * As a result, the block referenced by p itself and any blocks accessible\n     * via it will be considered live until the root is removed again.\n     *\n     * If p is null, no operation is performed.\n     *\n     * Params:\n     *  p = A pointer into a GC-managed memory block or null.\n     *\n     * Example:\n     * ---\n     * // Typical C-style callback mechanism; the passed function\n     * // is invoked with the user-supplied context pointer at a\n     * // later point.\n     * extern(C) void addCallback(void function(void*), void*);\n     *\n     * // Allocate an object on the GC heap (this would usually be\n     * // some application-specific context data).\n     * auto context = new Object;\n     *\n     * // Make sure that it is not collected even if it is no\n     * // longer referenced from D code (stack, GC heap, …).\n     * GC.addRoot(cast(void*)context);\n     *\n     * // Also ensure that a moving collector does not relocate\n     * // the object.\n     * GC.setAttr(cast(void*)context, GC.BlkAttr.NO_MOVE);\n     *\n     * // Now context can be safely passed to the C library.\n     * addCallback(&myHandler, cast(void*)context);\n     *\n     * extern(C) void myHandler(void* ctx)\n     * {\n     *     // Assuming that the callback is invoked only once, the\n     *     // added root can be removed again now to allow the GC\n     *     // to collect it later.\n     *     GC.removeRoot(ctx);\n     *     GC.clrAttr(ctx, GC.BlkAttr.NO_MOVE);\n     *\n     *     auto context = cast(Object)ctx;\n     *     // Use context here…\n     * }\n     * ---\n     */\n    static void addRoot( in void* p ) nothrow @nogc /* FIXME pure */\n    {\n        gc_addRoot( p );\n    }\n\n\n    /**\n     * Removes the memory block referenced by p from an internal list of roots\n     * to be scanned during a collection.  If p is null or is not a value\n     * previously passed to addRoot() then no operation is performed.\n     *\n     * Params:\n     *  p = A pointer into a GC-managed memory block or null.\n     */\n    static void removeRoot( in void* p ) nothrow @nogc /* FIXME pure */\n    {\n        gc_removeRoot( p );\n    }\n\n\n    /**\n     * Adds $(D p[0 .. sz]) to the list of memory ranges to be scanned for\n     * pointers during a collection. If p is null, no operation is performed.\n     *\n     * Note that $(D p[0 .. sz]) is treated as an opaque range of memory assumed\n     * to be suitably managed by the caller. In particular, if p points into a\n     * GC-managed memory block, addRange does $(I not) mark this block as live.\n     *\n     * Params:\n     *  p  = A pointer to a valid memory address or to null.\n     *  sz = The size in bytes of the block to add. If sz is zero then the\n     *       no operation will occur. If p is null then sz must be zero.\n     *  ti = TypeInfo to describe the memory. The GC might use this information\n     *       to improve scanning for pointers or to call finalizers\n     *\n     * Example:\n     * ---\n     * // Allocate a piece of memory on the C heap.\n     * enum size = 1_000;\n     * auto rawMemory = core.stdc.stdlib.malloc(size);\n     *\n     * // Add it as a GC range.\n     * GC.addRange(rawMemory, size);\n     *\n     * // Now, pointers to GC-managed memory stored in\n     * // rawMemory will be recognized on collection.\n     * ---\n     */\n    static void addRange( in void* p, size_t sz, const TypeInfo ti = null ) @nogc nothrow /* FIXME pure */\n    {\n        gc_addRange( p, sz, ti );\n    }\n\n\n    /**\n     * Removes the memory range starting at p from an internal list of ranges\n     * to be scanned during a collection. If p is null or does not represent\n     * a value previously passed to addRange() then no operation is\n     * performed.\n     *\n     * Params:\n     *  p  = A pointer to a valid memory address or to null.\n     */\n    static void removeRange( in void* p ) nothrow @nogc /* FIXME pure */\n    {\n        gc_removeRange( p );\n    }\n\n\n    /**\n     * Runs any finalizer that is located in address range of the\n     * given code segment.  This is used before unloading shared\n     * libraries.  All matching objects which have a finalizer in this\n     * code segment are assumed to be dead, using them while or after\n     * calling this method has undefined behavior.\n     *\n     * Params:\n     *  segment = address range of a code segment.\n     */\n    static void runFinalizers( in void[] segment )\n    {\n        gc_runFinalizers( segment );\n    }\n}\n\n/**\n * Pure variants of C's memory allocation functions `malloc`, `calloc`, and\n * `realloc` and deallocation function `free`.\n *\n * UNIX 98 requires that errno be set to ENOMEM upon failure.\n * Purity is achieved by saving and restoring the value of `errno`, thus\n * behaving as if it were never changed.\n *\n * See_Also:\n *     $(LINK2 https://dlang.org/spec/function.html#pure-functions, D's rules for purity),\n *     which allow for memory allocation under specific circumstances.\n */\nvoid* pureMalloc(size_t size) @trusted pure @nogc nothrow\n{\n    const errnosave = fakePureErrno();\n    void* ret = fakePureMalloc(size);\n    fakePureErrno() = errnosave;\n    return ret;\n}\n/// ditto\nvoid* pureCalloc(size_t nmemb, size_t size) @trusted pure @nogc nothrow\n{\n    const errnosave = fakePureErrno();\n    void* ret = fakePureCalloc(nmemb, size);\n    fakePureErrno() = errnosave;\n    return ret;\n}\n/// ditto\nvoid* pureRealloc(void* ptr, size_t size) @system pure @nogc nothrow\n{\n    const errnosave = fakePureErrno();\n    void* ret = fakePureRealloc(ptr, size);\n    fakePureErrno() = errnosave;\n    return ret;\n}\n/// ditto\nvoid pureFree(void* ptr) @system pure @nogc nothrow\n{\n    const errnosave = fakePureErrno();\n    fakePureFree(ptr);\n    fakePureErrno() = errnosave;\n}\n\n///\n@system pure nothrow @nogc unittest\n{\n    ubyte[] fun(size_t n) pure\n    {\n        void* p = pureMalloc(n);\n        p !is null || n == 0 || assert(0);\n        scope(failure) p = pureRealloc(p, 0);\n        p = pureRealloc(p, n *= 2);\n        p !is null || n == 0 || assert(0);\n        return cast(ubyte[]) p[0 .. n];\n    }\n\n    auto buf = fun(100);\n    assert(buf.length == 200);\n    pureFree(buf.ptr);\n}\n\n@system pure nothrow @nogc unittest\n{\n    const int errno = fakePureErrno();\n\n    void* x = pureMalloc(10);            // normal allocation\n    assert(errno == fakePureErrno()); // errno shouldn't change\n    assert(x !is null);                   // allocation should succeed\n\n    x = pureRealloc(x, 10);              // normal reallocation\n    assert(errno == fakePureErrno()); // errno shouldn't change\n    assert(x !is null);                   // allocation should succeed\n\n    fakePureFree(x);\n\n    void* y = pureCalloc(10, 1);         // normal zeroed allocation\n    assert(errno == fakePureErrno()); // errno shouldn't change\n    assert(y !is null);                   // allocation should succeed\n\n    fakePureFree(y);\n\n    // Workaround bug in glibc 2.26\n    // See also: https://issues.dlang.org/show_bug.cgi?id=17956\n    void* z = pureMalloc(size_t.max & ~255); // won't affect `errno`\n    assert(errno == fakePureErrno()); // errno shouldn't change\n    assert(z is null);\n}\n\n// locally purified for internal use here only\n\nextern (C) private @system @nogc nothrow\n{\n    ref int fakePureErrnoImpl()\n    {\n        import core.stdc.errno;\n        return errno();\n    }\n}\n\nextern (C) private pure @system @nogc nothrow\n{\n    pragma(mangle, \"fakePureErrnoImpl\") ref int fakePureErrno();\n\n    pragma(mangle, \"malloc\") void* fakePureMalloc(size_t);\n    pragma(mangle, \"calloc\") void* fakePureCalloc(size_t nmemb, size_t size);\n    pragma(mangle, \"realloc\") void* fakePureRealloc(void* ptr, size_t size);\n\n    pragma(mangle, \"free\") void fakePureFree(void* ptr);\n}\n\nextern(C) private @system nothrow @nogc\n{\n    pragma(mangle, \"_d_delinterface\") void _d_delinterface(void**);\n    pragma(mangle, \"_d_delclass\") void _d_delclass(Object*);\n    pragma(mangle, \"_d_delstruct\") void _d_delstruct(void**, TypeInfo_Struct);\n    pragma(mangle, \"_d_delmemory\") void _d_delmemory(void**);\n    pragma(mangle, \"_d_delarray_t\") void _d_delarray_t(void**, TypeInfo_Struct);\n}\n\n/**\nDestroys and then deallocates an object.\n\nIn detail, `__delete(x)` returns with no effect if `x` is `null`. Otherwise, it\nperforms the following actions in sequence:\n$(UL\n    $(LI\n        Calls the destructor `~this()` for the object referred to by `x`\n        (if `x` is a class or interface reference) or\n        for the object pointed to by `x` (if `x` is a pointer to a `struct`).\n        Arrays of structs call the destructor, if defined, for each element in the array.\n        If no destructor is defined, this step has no effect.\n    )\n    $(LI\n        Frees the memory allocated for `x`. If `x` is a reference to a class\n        or interface, the memory allocated for the underlying instance is freed. If `x` is\n        a pointer, the memory allocated for the pointed-to object is freed. If `x` is a\n        built-in array, the memory allocated for the array is freed.\n        If `x` does not refer to memory previously allocated with `new` (or the lower-level\n        equivalents in the GC API), the behavior is undefined.\n    )\n    $(LI\n        Lastly, `x` is set to `null`. Any attempt to read or write the freed memory via\n        other references will result in undefined behavior.\n    )\n)\n\nNote: Users should prefer $(REF1 destroy, object) to explicitly finalize objects,\nand only resort to $(REF __delete, core,memory) when $(REF destroy, object)\nwouldn't be a feasible option.\n\nParams:\n    x = aggregate object that should be destroyed\n\nSee_Also: $(REF1 destroy, object), $(REF free, core,GC)\n\nHistory:\n\nThe `delete` keyword allowed to free GC-allocated memory.\nAs this is inherently not `@safe`, it has been deprecated.\nThis function has been added to provide an easy transition from `delete`.\nIt performs the same functionality as the former `delete` keyword.\n*/\nvoid __delete(T)(ref T x) @system\n{\n    static void _destructRecurse(S)(ref S s)\n    if (is(S == struct))\n    {\n        static if (__traits(hasMember, S, \"__xdtor\") &&\n                   // Bugzilla 14746: Check that it's the exact member of S.\n                   __traits(isSame, S, __traits(parent, s.__xdtor)))\n            s.__xdtor();\n    }\n\n    // See also: https://github.com/dlang/dmd/blob/v2.078.0/src/dmd/e2ir.d#L3886\n    static if (is(T == interface))\n    {\n        .object.destroy(x);\n    }\n    else static if (is(T == class))\n    {\n        .object.destroy(x);\n    }\n    else static if (is(T == U*, U))\n    {\n        static if (is(U == struct))\n            _destructRecurse(*x);\n    }\n    else static if (is(T : E[], E))\n    {\n        static if (is(E == struct))\n        {\n            foreach (ref e; x)\n                _destructRecurse(e);\n        }\n    }\n    else\n    {\n        static assert(0, \"It is not possible to delete: `\" ~ T.stringof ~ \"`\");\n    }\n\n    static if (is(T == interface) ||\n              is(T == class) ||\n              is(T == U2*, U2))\n    {\n        GC.free(cast(void*) x);\n        x = null;\n    }\n    else static if (is(T : E2[], E2))\n    {\n        GC.free(cast(void*) x.ptr);\n        x = null;\n    }\n}\n\n/// Deleting classes\nunittest\n{\n    bool dtorCalled;\n    class B\n    {\n        int test;\n        ~this()\n        {\n            dtorCalled = true;\n        }\n    }\n    B b = new B();\n    B a = b;\n    b.test = 10;\n\n    assert(GC.addrOf(cast(void*) b) != null);\n    __delete(b);\n    assert(b is null);\n    assert(dtorCalled);\n    assert(GC.addrOf(cast(void*) b) == null);\n    // but be careful, a still points to it\n    assert(a !is null);\n    assert(GC.addrOf(cast(void*) a) !is null);\n}\n\n/// Deleting interfaces\nunittest\n{\n    bool dtorCalled;\n    interface A\n    {\n        int quack();\n    }\n    class B : A\n    {\n        int a;\n        int quack()\n        {\n            a++;\n            return a;\n        }\n        ~this()\n        {\n            dtorCalled = true;\n        }\n    }\n    A a = new B();\n    a.quack();\n\n    assert(GC.addrOf(cast(void*) a) != null);\n    __delete(a);\n    assert(a is null);\n    assert(dtorCalled);\n    assert(GC.addrOf(cast(void*) a) == null);\n}\n\n/// Deleting structs\nunittest\n{\n    bool dtorCalled;\n    struct A\n    {\n        string test;\n        ~this()\n        {\n            dtorCalled = true;\n        }\n    }\n    auto a = new A(\"foo\");\n\n    assert(GC.addrOf(cast(void*) a) != null);\n    __delete(a);\n    assert(a is null);\n    assert(dtorCalled);\n    assert(GC.addrOf(cast(void*) a) == null);\n}\n\n/// Deleting arrays\nunittest\n{\n    int[] a = [1, 2, 3];\n    auto b = a;\n\n    assert(GC.addrOf(b.ptr) != null);\n    __delete(b);\n    assert(b is null);\n    assert(GC.addrOf(b.ptr) == null);\n    // but be careful, a still points to it\n    assert(a !is null);\n    assert(GC.addrOf(a.ptr) !is null);\n}\n\n/// Deleting arrays of structs\nunittest\n{\n    int dtorCalled;\n    struct A\n    {\n        int a;\n        ~this()\n        {\n            dtorCalled++;\n        }\n    }\n    auto arr = [A(1), A(2), A(3)];\n\n    assert(GC.addrOf(arr.ptr) != null);\n    __delete(arr);\n    assert(dtorCalled == 3);\n    assert(GC.addrOf(arr.ptr) == null);\n}\n\n// Deleting raw memory\nunittest\n{\n    import core.memory : GC;\n    auto a = GC.malloc(5);\n    assert(GC.addrOf(cast(void*) a) != null);\n    __delete(a);\n    assert(a is null);\n    assert(GC.addrOf(cast(void*) a) == null);\n}\n\n// __delete returns with no effect if x is null\nunittest\n{\n    Object x = null;\n    __delete(x);\n\n    struct S { ~this() { } }\n    class C { }\n    interface I { }\n\n    int[] a; __delete(a);\n    S[] as; __delete(as);\n    C c; __delete(c);\n    I i; __delete(i);\n    C* pc = &c; __delete(*pc);\n    I* pi = &i; __delete(*pi);\n    int* pint; __delete(pint);\n    S* ps; __delete(ps);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=19092\nunittest\n{\n    const(int)[] x = [1, 2, 3];\n    assert(GC.addrOf(x.ptr) != null);\n    __delete(x);\n    assert(x is null);\n    assert(GC.addrOf(x.ptr) == null);\n\n    immutable(int)[] y = [1, 2, 3];\n    assert(GC.addrOf(y.ptr) != null);\n    __delete(y);\n    assert(y is null);\n    assert(GC.addrOf(y.ptr) == null);\n}\n\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/runtime.d",
    "content": "/**\n * The runtime module exposes information specific to the D runtime code.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/_runtime.d)\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule core.runtime;\n\nversion (Windows) import core.stdc.wchar_ : wchar_t;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\n/// C interface for Runtime.loadLibrary\nextern (C) void* rt_loadLibrary(const char* name);\n/// ditto\nversion (Windows) extern (C) void* rt_loadLibraryW(const wchar_t* name);\n/// C interface for Runtime.unloadLibrary, returns 1/0 instead of bool\nextern (C) int rt_unloadLibrary(void* ptr);\n\n/// C interface for Runtime.initialize, returns 1/0 instead of bool\nextern(C) int rt_init();\n/// C interface for Runtime.terminate, returns 1/0 instead of bool\nextern(C) int rt_term();\n\n/**\n * This type is returned by the module unit test handler to indicate testing\n * results.\n */\nstruct UnitTestResult\n{\n    /**\n     * Number of modules which were tested\n     */\n    size_t executed;\n\n    /**\n     * Number of modules passed the unittests\n     */\n    size_t passed;\n\n    /**\n     * Should the main function be run or not? This is ignored if any tests\n     * failed.\n     */\n    bool runMain;\n\n    /**\n     * Should we print a summary of the results?\n     */\n    bool summarize;\n\n    /**\n     * Simple check for whether execution should continue after unit tests\n     * have been run. Works with legacy code that expected a bool return.\n     *\n     * Returns:\n     *    true if execution should continue after testing is complete, false if\n     *    not.\n     */\n    bool opCast(T : bool)() const\n    {\n        return runMain && (executed == passed);\n    }\n\n    /// Simple return code that says unit tests pass, and main should be run\n    enum UnitTestResult pass = UnitTestResult(0, 0, true, false);\n    /// Simple return code that says unit tests failed.\n    enum UnitTestResult fail = UnitTestResult(1, 0, false, false);\n}\n\n/// Legacy module unit test handler\nalias bool function() ModuleUnitTester;\n/// Module unit test handler\nalias UnitTestResult function() ExtendedModuleUnitTester;\nprivate\n{\n    alias bool function(Object) CollectHandler;\n    alias Throwable.TraceInfo function( void* ptr ) TraceHandler;\n\n    extern (C) void rt_setCollectHandler( CollectHandler h );\n    extern (C) CollectHandler rt_getCollectHandler();\n\n    extern (C) void rt_setTraceHandler( TraceHandler h );\n    extern (C) TraceHandler rt_getTraceHandler();\n\n    alias void delegate( Throwable ) ExceptionHandler;\n    extern (C) void _d_print_throwable(Throwable t);\n\n    extern (C) void* thread_stackBottom();\n\n    extern (C) string[] rt_args();\n    extern (C) CArgs rt_cArgs() @nogc;\n}\n\n\nstatic this()\n{\n    // NOTE: Some module ctors will run before this handler is set, so it's\n    //       still possible the app could exit without a stack trace.  If\n    //       this becomes an issue, the handler could be set in C main\n    //       before the module ctors are run.\n    Runtime.traceHandler = &defaultTraceHandler;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Runtime\n///////////////////////////////////////////////////////////////////////////////\n\n/**\n * Stores the unprocessed arguments supplied when the\n * process was started.\n */\nstruct CArgs\n{\n    int argc; /// The argument count.\n    char** argv; /// The arguments as a C array of strings.\n}\n\n/**\n * This struct encapsulates all functionality related to the underlying runtime\n * module for the calling context.\n */\nstruct Runtime\n{\n    /**\n     * Initializes the runtime.  This call is to be used in instances where the\n     * standard program initialization process is not executed.  This is most\n     * often in shared libraries or in libraries linked to a C program.\n     * If the runtime was already successfully initialized this returns true.\n     * Each call to initialize must be paired by a call to $(LREF terminate).\n     *\n     * Returns:\n     *  true if initialization succeeded or false if initialization failed.\n     */\n    static bool initialize()\n    {\n        return !!rt_init();\n    }\n\n    deprecated(\"Please use the overload of Runtime.initialize that takes no argument.\")\n    static bool initialize(ExceptionHandler dg = null)\n    {\n        return !!rt_init();\n    }\n\n\n    /**\n     * Terminates the runtime.  This call is to be used in instances where the\n     * standard program termination process will not be not executed.  This is\n     * most often in shared libraries or in libraries linked to a C program.\n     * If the runtime was not successfully initialized the function returns false.\n     *\n     * Returns:\n     *  true if termination succeeded or false if termination failed.\n     */\n    static bool terminate()\n    {\n        return !!rt_term();\n    }\n\n    deprecated(\"Please use the overload of Runtime.terminate that takes no argument.\")\n    static bool terminate(ExceptionHandler dg = null)\n    {\n        return !!rt_term();\n    }\n\n\n    /**\n     * Returns the arguments supplied when the process was started.\n     *\n     * Returns:\n     *  The arguments supplied when this process was started.\n     */\n    static @property string[] args()\n    {\n        return rt_args();\n    }\n\n    /**\n     * Returns the unprocessed C arguments supplied when the process was started.\n     * Use this when you need to supply argc and argv to C libraries.\n     *\n     * Returns:\n     *  A $(LREF CArgs) struct with the arguments supplied when this process was started.\n     *\n     * Example:\n     * ---\n     * import core.runtime;\n     *\n     * // A C library function requiring char** arguments\n     * extern(C) void initLibFoo(int argc, char** argv);\n     *\n     * void main()\n     * {\n     *     auto args = Runtime.cArgs;\n     *     initLibFoo(args.argc, args.argv);\n     * }\n     * ---\n     */\n    static @property CArgs cArgs() @nogc\n    {\n        return rt_cArgs();\n    }\n\n    /**\n     * Locates a dynamic library with the supplied library name and dynamically\n     * loads it into the caller's address space.  If the library contains a D\n     * runtime it will be integrated with the current runtime.\n     *\n     * Params:\n     *  name = The name of the dynamic library to load.\n     *\n     * Returns:\n     *  A reference to the library or null on error.\n     */\n    static void* loadLibrary()(in char[] name)\n    {\n        import core.stdc.stdlib : free, malloc;\n        version (Windows)\n        {\n            import core.sys.windows.windows;\n\n            if (name.length == 0) return null;\n            // Load a DLL at runtime\n            auto len = MultiByteToWideChar(\n                CP_UTF8, 0, name.ptr, cast(int)name.length, null, 0);\n            if (len == 0)\n                return null;\n\n            auto buf = cast(wchar_t*)malloc((len+1) * wchar_t.sizeof);\n            if (buf is null) return null;\n            scope (exit) free(buf);\n\n            len = MultiByteToWideChar(\n                CP_UTF8, 0, name.ptr, cast(int)name.length, buf, len);\n            if (len == 0)\n                return null;\n\n            buf[len] = '\\0';\n\n            return rt_loadLibraryW(buf);\n        }\n        else version (Posix)\n        {\n            /* Need a 0-terminated C string for the dll name\n             */\n            immutable len = name.length;\n            auto buf = cast(char*)malloc(len + 1);\n            if (!buf) return null;\n            scope (exit) free(buf);\n\n            buf[0 .. len] = name[];\n            buf[len] = 0;\n\n            return rt_loadLibrary(buf);\n        }\n    }\n\n\n    /**\n     * Unloads the dynamic library referenced by p.  If this library contains a\n     * D runtime then any necessary finalization or cleanup of that runtime\n     * will be performed.\n     *\n     * Params:\n     *  p = A reference to the library to unload.\n     */\n    static bool unloadLibrary()(void* p)\n    {\n        return !!rt_unloadLibrary(p);\n    }\n\n\n    /**\n     * Overrides the default trace mechanism with a user-supplied version.  A\n     * trace represents the context from which an exception was thrown, and the\n     * trace handler will be called when this occurs.  The pointer supplied to\n     * this routine indicates the base address from which tracing should occur.\n     * If the supplied pointer is null then the trace routine should determine\n     * an appropriate calling context from which to begin the trace.\n     *\n     * Params:\n     *  h = The new trace handler.  Set to null to use the default handler.\n     */\n    static @property void traceHandler( TraceHandler h )\n    {\n        rt_setTraceHandler( h );\n    }\n\n    /**\n     * Gets the current trace handler.\n     *\n     * Returns:\n     *  The current trace handler or null if none has been set.\n     */\n    static @property TraceHandler traceHandler()\n    {\n        return rt_getTraceHandler();\n    }\n\n    /**\n     * Overrides the default collect hander with a user-supplied version.  This\n     * routine will be called for each resource object that is finalized in a\n     * non-deterministic manner--typically during a garbage collection cycle.\n     * If the supplied routine returns true then the object's dtor will called\n     * as normal, but if the routine returns false than the dtor will not be\n     * called.  The default behavior is for all object dtors to be called.\n     *\n     * Params:\n     *  h = The new collect handler.  Set to null to use the default handler.\n     */\n    static @property void collectHandler( CollectHandler h )\n    {\n        rt_setCollectHandler( h );\n    }\n\n\n    /**\n     * Gets the current collect handler.\n     *\n     * Returns:\n     *  The current collect handler or null if none has been set.\n     */\n    static @property CollectHandler collectHandler()\n    {\n        return rt_getCollectHandler();\n    }\n\n\n    /**\n     * Overrides the default module unit tester with a user-supplied version.\n     * This routine will be called once on program initialization.  The return\n     * value of this routine indicates to the runtime whether the tests ran\n     * without error.\n     *\n     * There are two options for handlers. The `bool` version is deprecated but\n     * will be kept for legacy support. Returning `true` from the handler is\n     * equivalent to returning `UnitTestResult.pass` from the extended version.\n     * Returning `false` from the handler is equivalent to returning\n     * `UnitTestResult.fail` from the extended version.\n     *\n     * See the documentation for `UnitTestResult` to see how you should set up\n     * the return structure.\n     *\n     * See the documentation for `runModuleUnitTests` for how the default\n     * algorithm works, or read the example below.\n     *\n     * Params:\n     *  h = The new unit tester.  Set both to null to use the default unit\n     *  tester.\n     *\n     * Example:\n     * ---------\n     * shared static this()\n     * {\n     *     import core.runtime;\n     *\n     *     Runtime.extendedModuleUnitTester = &customModuleUnitTester;\n     * }\n     *\n     * UnitTestResult customModuleUnitTester()\n     * {\n     *     import std.stdio;\n     *\n     *     writeln(\"Using customModuleUnitTester\");\n     *\n     *     // Do the same thing as the default moduleUnitTester:\n     *     UnitTestResult result;\n     *     foreach (m; ModuleInfo)\n     *     {\n     *         if (m)\n     *         {\n     *             auto fp = m.unitTest;\n     *\n     *             if (fp)\n     *             {\n     *                 ++result.executed;\n     *                 try\n     *                 {\n     *                     fp();\n     *                     ++result.passed;\n     *                 }\n     *                 catch (Throwable e)\n     *                 {\n     *                     writeln(e);\n     *                 }\n     *             }\n     *         }\n     *     }\n     *     if (result.executed != result.passed)\n     *     {\n     *         result.runMain = false;  // don't run main\n     *         result.summarize = true; // print failure\n     *     }\n     *     else\n     *     {\n     *         result.runMain = true;    // all UT passed\n     *         result.summarize = false; // be quiet about it.\n     *     }\n     *     return result;\n     * }\n     * ---------\n     */\n    static @property void extendedModuleUnitTester( ExtendedModuleUnitTester h )\n    {\n        sm_extModuleUnitTester = h;\n    }\n\n    /// Ditto\n    static @property void moduleUnitTester( ModuleUnitTester h )\n    {\n        sm_moduleUnitTester = h;\n    }\n\n    /**\n     * Gets the current legacy module unit tester.\n     *\n     * This property should not be used, but is supported for legacy purposes.\n     *\n     * Note that if the extended unit test handler is set, this handler will\n     * be ignored.\n     *\n     * Returns:\n     *  The current legacy module unit tester handler or null if none has been\n     *  set.\n     */\n    static @property ModuleUnitTester moduleUnitTester()\n    {\n        return sm_moduleUnitTester;\n    }\n\n    /**\n     * Gets the current module unit tester.\n     *\n     * This handler overrides any legacy module unit tester set by the\n     * moduleUnitTester property.\n     *\n     * Returns:\n     *  The current  module unit tester handler or null if none has been\n     *  set.\n     */\n    static @property ExtendedModuleUnitTester extendedModuleUnitTester()\n    {\n        return sm_extModuleUnitTester;\n    }\n\nprivate:\n\n    // NOTE: This field will only ever be set in a static ctor and should\n    //       never occur within any but the main thread, so it is safe to\n    //       make it __gshared.\n    __gshared ExtendedModuleUnitTester sm_extModuleUnitTester = null;\n    __gshared ModuleUnitTester sm_moduleUnitTester = null;\n}\n\n/**\n * Set source file path for coverage reports.\n *\n * Params:\n *  path = The new path name.\n * Note:\n *  This is a dmd specific setting.\n */\nextern (C) void dmd_coverSourcePath(string path);\n\n/**\n * Set output path for coverage reports.\n *\n * Params:\n *  path = The new path name.\n * Note:\n *  This is a dmd specific setting.\n */\nextern (C) void dmd_coverDestPath(string path);\n\n/**\n * Enable merging of coverage reports with existing data.\n *\n * Params:\n *  flag = enable/disable coverage merge mode\n * Note:\n *  This is a dmd specific setting.\n */\nextern (C) void dmd_coverSetMerge(bool flag);\n\n/**\n * Set the output file name for profile reports (-profile switch).\n * An empty name will set the output to stdout.\n *\n * Params:\n *  name = file name\n * Note:\n *  This is a dmd specific setting.\n */\nextern (C) void trace_setlogfilename(string name);\n\n/**\n * Set the output file name for the optimized profile linker DEF file (-profile switch).\n * An empty name will set the output to stdout.\n *\n * Params:\n *  name = file name\n * Note:\n *  This is a dmd specific setting.\n */\nextern (C) void trace_setdeffilename(string name);\n\n/**\n * Set the output file name for memory profile reports (-profile=gc switch).\n * An empty name will set the output to stdout.\n *\n * Params:\n *  name = file name\n * Note:\n *  This is a dmd specific setting.\n */\nextern (C) void profilegc_setlogfilename(string name);\n\n///////////////////////////////////////////////////////////////////////////////\n// Overridable Callbacks\n///////////////////////////////////////////////////////////////////////////////\n\n\n/**\n * This routine is called by the runtime to run module unit tests on startup.\n * The user-supplied unit tester will be called if one has been set,\n * otherwise all unit tests will be run in sequence.\n *\n * If the extended unittest handler is registered, this function returns the\n * result from that handler directly.\n *\n * If a legacy boolean returning custom handler is used, `false` maps to\n * `UnitTestResult.fail`, and `true` maps to `UnitTestResult.pass`. This was\n * the original behavior of the unit testing system.\n *\n * If no unittest custom handlers are registered, the following algorithm is\n * executed (the behavior can be affected by the `--DRT-testmode` switch\n * below):\n * 1. Run all unit tests, tracking tests executed and passes. For each that\n *    fails, print the stack trace, and continue.\n * 2. If there are no failures, set the summarize flag to false, and the\n *    runMain flag to true.\n * 3. If there are failures, set the summarize flag to true, and the runMain\n *    flag to false.\n *\n * See the documentation for `UnitTestResult` for details on how the runtime\n * treats the return value from this function.\n *\n * If the switch `--DRT-testmode` is passed to the executable, it can have\n * one of 3 values:\n * 1. \"run-main\": even if unit tests are run (and all pass), main is still run.\n *    This is currently the default.\n * 2. \"test-or-main\": any unit tests present will cause the program to\n *    summarize the results and exit regardless of the result. This will be the\n *    default in 2.080.\n * 3. \"test-only\", the runtime will always summarize and never run main, even\n *    if no tests are present.\n *\n * This command-line parameter does not affect custom unit test handlers.\n *\n * Returns:\n *   A `UnitTestResult` struct indicating the result of running unit tests.\n */\nextern (C) UnitTestResult runModuleUnitTests()\n{\n    // backtrace\n    version (GNU)\n        import gcc.backtrace;\n    else version (CRuntime_Glibc)\n        import core.sys.linux.execinfo;\n    else version (Darwin)\n        import core.sys.darwin.execinfo;\n    else version (FreeBSD)\n        import core.sys.freebsd.execinfo;\n    else version (NetBSD)\n        import core.sys.netbsd.execinfo;\n    else version (DragonFlyBSD)\n        import core.sys.dragonflybsd.execinfo;\n    else version (Windows)\n        import core.sys.windows.stacktrace;\n    else version (Solaris)\n        import core.sys.solaris.execinfo;\n    else version (CRuntime_UClibc)\n        import core.sys.linux.execinfo;\n\n    static if ( __traits( compiles, backtrace ) )\n    {\n        import core.sys.posix.signal; // segv handler\n\n        static extern (C) void unittestSegvHandler( int signum, siginfo_t* info, void* ptr ) nothrow\n        {\n            static enum MAXFRAMES = 128;\n            void*[MAXFRAMES]  callstack;\n            int               numframes;\n\n            numframes = backtrace( callstack.ptr, MAXFRAMES );\n            backtrace_symbols_fd( callstack.ptr, numframes, 2 );\n        }\n\n        sigaction_t action = void;\n        sigaction_t oldseg = void;\n        sigaction_t oldbus = void;\n\n        (cast(byte*) &action)[0 .. action.sizeof] = 0;\n        sigfillset( &action.sa_mask ); // block other signals\n        action.sa_flags = SA_SIGINFO | SA_RESETHAND;\n        action.sa_sigaction = &unittestSegvHandler;\n        sigaction( SIGSEGV, &action, &oldseg );\n        sigaction( SIGBUS, &action, &oldbus );\n        scope( exit )\n        {\n            sigaction( SIGSEGV, &oldseg, null );\n            sigaction( SIGBUS, &oldbus, null );\n        }\n    }\n    else static if ( __traits( compiles, new LibBacktrace(0) ) )\n    {\n        import core.sys.posix.signal; // segv handler\n\n        static extern (C) void unittestSegvHandler( int signum, siginfo_t* info, void* ptr )\n        {\n            import core.stdc.stdio;\n            fprintf(stderr, \"Segmentation fault while running unittests:\\n\");\n            fprintf(stderr, \"----------------\\n\");\n\n            enum alignment = LibBacktrace.MaxAlignment;\n            enum classSize = __traits(classInstanceSize, LibBacktrace);\n\n            void[classSize + alignment] bt_store = void;\n            void* alignedAddress = cast(byte*)((cast(size_t)(bt_store.ptr + alignment - 1))\n                & ~(alignment - 1));\n\n            (alignedAddress[0 .. classSize]) = typeid(LibBacktrace).initializer[];\n            auto bt = cast(LibBacktrace)(alignedAddress);\n            // First frame is LibBacktrace ctor. Second is signal handler, but include that for now\n            bt.__ctor(1);\n\n            foreach (size_t i, const(char[]) msg; bt)\n                fprintf(stderr, \"%s\\n\", msg.ptr ? msg.ptr : \"???\");\n        }\n\n        sigaction_t action = void;\n        sigaction_t oldseg = void;\n        sigaction_t oldbus = void;\n\n        (cast(byte*) &action)[0 .. action.sizeof] = 0;\n        sigfillset( &action.sa_mask ); // block other signals\n        action.sa_flags = SA_SIGINFO | SA_RESETHAND;\n        action.sa_sigaction = &unittestSegvHandler;\n        sigaction( SIGSEGV, &action, &oldseg );\n        sigaction( SIGBUS, &action, &oldbus );\n        scope( exit )\n        {\n            sigaction( SIGSEGV, &oldseg, null );\n            sigaction( SIGBUS, &oldbus, null );\n        }\n    }\n\n    if (Runtime.sm_extModuleUnitTester !is null)\n        return Runtime.sm_extModuleUnitTester();\n    else if (Runtime.sm_moduleUnitTester !is null)\n        return Runtime.sm_moduleUnitTester() ? UnitTestResult.pass : UnitTestResult.fail;\n    UnitTestResult results;\n    foreach ( m; ModuleInfo )\n    {\n        if ( m )\n        {\n            auto fp = m.unitTest;\n\n            if ( fp )\n            {\n                ++results.executed;\n                try\n                {\n                    fp();\n                    ++results.passed;\n                }\n                catch ( Throwable e )\n                {\n                    _d_print_throwable(e);\n                }\n            }\n        }\n    }\n\n    import core.internal.parseoptions : rt_configOption;\n\n    if (results.passed != results.executed)\n    {\n        // by default, we always print a summary if there are failures.\n        results.summarize = true;\n    }\n    else switch (rt_configOption(\"testmode\", null, false))\n    {\n    case \"\":\n        // By default, run main. Switch to only doing unit tests in 2.080\n    case \"run-main\":\n        results.runMain = true;\n        break;\n    case \"test-only\":\n        // Never run main, always summarize\n        results.summarize = true;\n        break;\n    case \"test-or-main\":\n        // only run main if there were no tests. Only summarize if we are not\n        // running main.\n        results.runMain = (results.executed == 0);\n        results.summarize = !results.runMain;\n        break;\n    default:\n        throw new Error(\"Unknown --DRT-testmode option: \" ~ rt_configOption(\"testmode\", null, false));\n    }\n\n    return results;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Default Implementations\n///////////////////////////////////////////////////////////////////////////////\n\n\n/**\n *\n */\nThrowable.TraceInfo defaultTraceHandler( void* ptr = null )\n{\n    // backtrace\n    version (GNU)\n        import gcc.backtrace;\n    else version (CRuntime_Glibc)\n        import core.sys.linux.execinfo;\n    else version (Darwin)\n        import core.sys.darwin.execinfo;\n    else version (FreeBSD)\n        import core.sys.freebsd.execinfo;\n    else version (NetBSD)\n        import core.sys.netbsd.execinfo;\n    else version (DragonFlyBSD)\n        import core.sys.dragonflybsd.execinfo;\n    else version (Windows)\n        import core.sys.windows.stacktrace;\n    else version (Solaris)\n        import core.sys.solaris.execinfo;\n    else version (CRuntime_UClibc)\n        import core.sys.linux.execinfo;\n\n    // avoid recursive GC calls in finalizer, trace handlers should be made @nogc instead\n    import core.memory : gc_inFinalizer;\n    if (gc_inFinalizer)\n        return null;\n\n    //printf(\"runtime.defaultTraceHandler()\\n\");\n    static if ( __traits( compiles, backtrace ) )\n    {\n        import core.demangle;\n        import core.stdc.stdlib : free;\n        import core.stdc.string : strlen, memchr, memmove;\n\n        class DefaultTraceInfo : Throwable.TraceInfo\n        {\n            this()\n            {\n                numframes = 0; //backtrace( callstack, MAXFRAMES );\n                if (numframes < 2) // backtrace() failed, do it ourselves\n                {\n                    static void** getBasePtr()\n                    {\n                        version (D_InlineAsm_X86)\n                            asm { naked; mov EAX, EBP; ret; }\n                        else\n                        version (D_InlineAsm_X86_64)\n                            asm { naked; mov RAX, RBP; ret; }\n                        else\n                            return null;\n                    }\n\n                    auto  stackTop    = getBasePtr();\n                    auto  stackBottom = cast(void**) thread_stackBottom();\n                    void* dummy;\n\n                    if ( stackTop && &dummy < stackTop && stackTop < stackBottom )\n                    {\n                        auto stackPtr = stackTop;\n\n                        for ( numframes = 0; stackTop <= stackPtr &&\n                                            stackPtr < stackBottom &&\n                                            numframes < MAXFRAMES; )\n                        {\n                            enum CALL_INSTRUCTION_SIZE = 1; // it may not be 1 but it is good enough to get\n                                                            // in CALL instruction address range for backtrace\n                            callstack[numframes++] = *(stackPtr + 1) - CALL_INSTRUCTION_SIZE;\n                            stackPtr = cast(void**) *stackPtr;\n                        }\n                    }\n                }\n            }\n\n            override int opApply( scope int delegate(ref const(char[])) dg ) const\n            {\n                return opApply( (ref size_t, ref const(char[]) buf)\n                                {\n                                    return dg( buf );\n                                } );\n            }\n\n            override int opApply( scope int delegate(ref size_t, ref const(char[])) dg ) const\n            {\n                version (Posix)\n                {\n                    // NOTE: The first 4 frames with the current implementation are\n                    //       inside core.runtime and the object code, so eliminate\n                    //       these for readability.  The alternative would be to\n                    //       exclude the first N frames that are in a list of\n                    //       mangled function names.\n                    enum FIRSTFRAME = 4;\n                }\n                else version (Windows)\n                {\n                    // NOTE: On Windows, the number of frames to exclude is based on\n                    //       whether the exception is user or system-generated, so\n                    //       it may be necessary to exclude a list of function names\n                    //       instead.\n                    enum FIRSTFRAME = 0;\n                }\n\n                version (linux) enum enableDwarf = true;\n                else version (FreeBSD) enum enableDwarf = true;\n                else version (DragonFlyBSD) enum enableDwarf = true;\n                else version (Darwin) enum enableDwarf = true;\n                else enum enableDwarf = false;\n\n                static if (enableDwarf)\n                {\n                    import core.internal.traits : externDFunc;\n\n                    alias traceHandlerOpApplyImpl = externDFunc!(\n                        \"rt.backtrace.dwarf.traceHandlerOpApplyImpl\",\n                        int function(const void*[], scope int delegate(ref size_t, ref const(char[])))\n                    );\n\n                    if (numframes >= FIRSTFRAME)\n                    {\n                        return traceHandlerOpApplyImpl(\n                            callstack[FIRSTFRAME .. numframes],\n                            dg\n                        );\n                    }\n                    else\n                    {\n                        return 0;\n                    }\n                }\n                else\n                {\n                    const framelist = backtrace_symbols( callstack.ptr, numframes );\n                    scope(exit) free(cast(void*) framelist);\n\n                    int ret = 0;\n                    for ( int i = FIRSTFRAME; i < numframes; ++i )\n                    {\n                        char[4096] fixbuf;\n                        auto buf = framelist[i][0 .. strlen(framelist[i])];\n                        auto pos = cast(size_t)(i - FIRSTFRAME);\n                        buf = fixline( buf, fixbuf );\n                        ret = dg( pos, buf );\n                        if ( ret )\n                            break;\n                    }\n                    return ret;\n                }\n\n            }\n\n            override string toString() const\n            {\n                string buf;\n                foreach ( i, line; this )\n                    buf ~= i ? \"\\n\" ~ line : line;\n                return buf;\n            }\n\n        private:\n            int     numframes;\n            static enum MAXFRAMES = 128;\n            void*[MAXFRAMES]  callstack = void;\n\n        private:\n            const(char)[] fixline( const(char)[] buf, return ref char[4096] fixbuf ) const\n            {\n                size_t symBeg, symEnd;\n                version (Darwin)\n                {\n                    // format is:\n                    //  1  module    0x00000000 D6module4funcAFZv + 0\n                    for ( size_t i = 0, n = 0; i < buf.length; i++ )\n                    {\n                        if ( ' ' == buf[i] )\n                        {\n                            n++;\n                            while ( i < buf.length && ' ' == buf[i] )\n                                i++;\n                            if ( 3 > n )\n                                continue;\n                            symBeg = i;\n                            while ( i < buf.length && ' ' != buf[i] )\n                                i++;\n                            symEnd = i;\n                            break;\n                        }\n                    }\n                }\n                else version (CRuntime_Glibc)\n                {\n                    // format is:  module(_D6module4funcAFZv) [0x00000000]\n                    // or:         module(_D6module4funcAFZv+0x78) [0x00000000]\n                    auto bptr = cast(char*) memchr( buf.ptr, '(', buf.length );\n                    auto eptr = cast(char*) memchr( buf.ptr, ')', buf.length );\n                    auto pptr = cast(char*) memchr( buf.ptr, '+', buf.length );\n\n                    if (pptr && pptr < eptr)\n                        eptr = pptr;\n\n                    if ( bptr++ && eptr )\n                    {\n                        symBeg = bptr - buf.ptr;\n                        symEnd = eptr - buf.ptr;\n                    }\n                }\n                else version (FreeBSD)\n                {\n                    // format is: 0x00000000 <_D6module4funcAFZv+0x78> at module\n                    auto bptr = cast(char*) memchr( buf.ptr, '<', buf.length );\n                    auto eptr = cast(char*) memchr( buf.ptr, '+', buf.length );\n\n                    if ( bptr++ && eptr )\n                    {\n                        symBeg = bptr - buf.ptr;\n                        symEnd = eptr - buf.ptr;\n                    }\n                }\n                else version (NetBSD)\n                {\n                    // format is: 0x00000000 <_D6module4funcAFZv+0x78> at module\n                    auto bptr = cast(char*) memchr( buf.ptr, '<', buf.length );\n                    auto eptr = cast(char*) memchr( buf.ptr, '+', buf.length );\n\n                    if ( bptr++ && eptr )\n                    {\n                        symBeg = bptr - buf.ptr;\n                        symEnd = eptr - buf.ptr;\n                    }\n                }\n                else version (DragonFlyBSD)\n                {\n                    // format is: 0x00000000 <_D6module4funcAFZv+0x78> at module\n                    auto bptr = cast(char*) memchr( buf.ptr, '<', buf.length );\n                    auto eptr = cast(char*) memchr( buf.ptr, '+', buf.length );\n\n                    if ( bptr++ && eptr )\n                    {\n                        symBeg = bptr - buf.ptr;\n                        symEnd = eptr - buf.ptr;\n                    }\n                }\n                else version (Solaris)\n                {\n                    // format is object'symbol+offset [pc]\n                    auto bptr = cast(char*) memchr( buf.ptr, '\\'', buf.length );\n                    auto eptr = cast(char*) memchr( buf.ptr, '+', buf.length );\n\n                    if ( bptr++ && eptr )\n                    {\n                        symBeg = bptr - buf.ptr;\n                        symEnd = eptr - buf.ptr;\n                    }\n                }\n                else\n                {\n                    // fallthrough\n                }\n\n                assert(symBeg < buf.length && symEnd < buf.length);\n                assert(symBeg <= symEnd);\n\n                enum min = (size_t a, size_t b) => a <= b ? a : b;\n                if (symBeg == symEnd || symBeg >= fixbuf.length)\n                {\n                    immutable len = min(buf.length, fixbuf.length);\n                    fixbuf[0 .. len] = buf[0 .. len];\n                    return fixbuf[0 .. len];\n                }\n                else\n                {\n                    fixbuf[0 .. symBeg] = buf[0 .. symBeg];\n\n                    auto sym = demangle(buf[symBeg .. symEnd], fixbuf[symBeg .. $]);\n\n                    if (sym.ptr !is fixbuf.ptr + symBeg)\n                    {\n                        // demangle reallocated the buffer, copy the symbol to fixbuf\n                        immutable len = min(fixbuf.length - symBeg, sym.length);\n                        memmove(fixbuf.ptr + symBeg, sym.ptr, len);\n                        if (symBeg + len == fixbuf.length)\n                            return fixbuf[];\n                    }\n\n                    immutable pos = symBeg + sym.length;\n                    assert(pos < fixbuf.length);\n                    immutable tail = buf.length - symEnd;\n                    immutable len = min(fixbuf.length - pos, tail);\n                    fixbuf[pos .. pos + len] = buf[symEnd .. symEnd + len];\n                    return fixbuf[0 .. pos + len];\n                }\n            }\n        }\n\n        return new DefaultTraceInfo;\n    }\n    else static if ( __traits( compiles, new StackTrace(0, null) ) )\n    {\n        version (Win64)\n        {\n            static enum FIRSTFRAME = 4;\n        }\n        else version (Win32)\n        {\n            static enum FIRSTFRAME = 0;\n        }\n        import core.sys.windows.windows : CONTEXT;\n        auto s = new StackTrace(FIRSTFRAME, cast(CONTEXT*)ptr);\n        return s;\n    }\n    else static if ( __traits( compiles, new LibBacktrace(0) ) )\n    {\n        version (Posix)\n        {\n            static enum FIRSTFRAME = 4;\n        }\n        else version (Win64)\n        {\n            static enum FIRSTFRAME = 4;\n        }\n        else\n        {\n            static enum FIRSTFRAME = 0;\n        }\n        return new LibBacktrace(FIRSTFRAME);\n    }\n    else static if ( __traits( compiles, new UnwindBacktrace(0) ) )\n    {\n        version (Posix)\n        {\n            static enum FIRSTFRAME = 5;\n        }\n        else version (Win64)\n        {\n            static enum FIRSTFRAME = 4;\n        }\n        else\n        {\n            static enum FIRSTFRAME = 0;\n        }\n        return new UnwindBacktrace(FIRSTFRAME);\n    }\n    else\n    {\n        return null;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/simd.d",
    "content": "// Written in the D programming language.\n\n/**\n * Builtin SIMD intrinsics\n *\n * Source: $(DRUNTIMESRC core/_simd.d)\n *\n * Copyright: Copyright Digital Mars 2012.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright),\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule core.simd;\n\npure:\nnothrow:\n@safe:\n@nogc:\n\n/*******************************\n * Create a vector type.\n *\n * Parameters:\n *      T = one of double[2], float[4], void[16], byte[16], ubyte[16],\n *      short[8], ushort[8], int[4], uint[4], long[2], ulong[2].\n *      For 256 bit vectors,\n *      one of double[4], float[8], void[32], byte[32], ubyte[32],\n *      short[16], ushort[16], int[8], uint[8], long[4], ulong[4]\n */\n\ntemplate Vector(T)\n{\n    /* __vector is compiler magic, hide it behind a template.\n     * The compiler will reject T's that don't work.\n     */\n    alias __vector(T) Vector;\n}\n\n/* Handy aliases\n */\nstatic if (is(Vector!(void[8])))    alias Vector!(void[8])  void8;          ///\nstatic if (is(Vector!(float[2])))   alias Vector!(float[2])  float2;        ///\nstatic if (is(Vector!(byte[8])))    alias Vector!(byte[8])  byte8;          ///\nstatic if (is(Vector!(ubyte[8])))   alias Vector!(ubyte[8]) ubyte8;         ///\nstatic if (is(Vector!(short[4])))   alias Vector!(short[4])  short4;        ///\nstatic if (is(Vector!(ushort[4])))  alias Vector!(ushort[4]) ushort4;       ///\nstatic if (is(Vector!(int[2])))     alias Vector!(int[2])    int2;          ///\nstatic if (is(Vector!(uint[2])))    alias Vector!(uint[2])   uint2;         ///\n\nstatic if (is(Vector!(void[16])))   alias Vector!(void[16])  void16;        ///\nstatic if (is(Vector!(double[2])))  alias Vector!(double[2]) double2;       ///\nstatic if (is(Vector!(float[4])))   alias Vector!(float[4])  float4;        ///\nstatic if (is(Vector!(byte[16])))   alias Vector!(byte[16])  byte16;        ///\nstatic if (is(Vector!(ubyte[16])))  alias Vector!(ubyte[16]) ubyte16;       ///\nstatic if (is(Vector!(short[8])))   alias Vector!(short[8])  short8;        ///\nstatic if (is(Vector!(ushort[8])))  alias Vector!(ushort[8]) ushort8;       ///\nstatic if (is(Vector!(int[4])))     alias Vector!(int[4])    int4;          ///\nstatic if (is(Vector!(uint[4])))    alias Vector!(uint[4])   uint4;         ///\nstatic if (is(Vector!(long[2])))    alias Vector!(long[2])   long2;         ///\nstatic if (is(Vector!(ulong[2])))   alias Vector!(ulong[2])  ulong2;        ///\n\nstatic if (is(Vector!(void[32])))   alias Vector!(void[32])   void32;        ///\nstatic if (is(Vector!(double[4])))  alias Vector!(double[4])  double4;       ///\nstatic if (is(Vector!(float[8])))   alias Vector!(float[8])   float8;        ///\nstatic if (is(Vector!(byte[32])))   alias Vector!(byte[32])   byte32;        ///\nstatic if (is(Vector!(ubyte[32])))  alias Vector!(ubyte[32])  ubyte32;       ///\nstatic if (is(Vector!(short[16])))  alias Vector!(short[16])  short16;       ///\nstatic if (is(Vector!(ushort[16]))) alias Vector!(ushort[16]) ushort16;      ///\nstatic if (is(Vector!(int[8])))     alias Vector!(int[8])     int8;          ///\nstatic if (is(Vector!(uint[8])))    alias Vector!(uint[8])    uint8;         ///\nstatic if (is(Vector!(long[4])))    alias Vector!(long[4])    long4;         ///\nstatic if (is(Vector!(ulong[4])))   alias Vector!(ulong[4])   ulong4;        ///\n\nversion (D_SIMD)\n{\n  /** XMM opcodes that conform to the following:\n   *\n   *  opcode xmm1,xmm2/mem\n   *\n   * and do not have side effects (i.e. do not write to memory).\n   */\n  enum XMM\n  {\n    ADDSS = 0xF30F58,\n    ADDSD = 0xF20F58,\n    ADDPS = 0x000F58,\n    ADDPD = 0x660F58,\n    PADDB = 0x660FFC,\n    PADDW = 0x660FFD,\n    PADDD = 0x660FFE,\n    PADDQ = 0x660FD4,\n\n    SUBSS = 0xF30F5C,\n    SUBSD = 0xF20F5C,\n    SUBPS = 0x000F5C,\n    SUBPD = 0x660F5C,\n    PSUBB = 0x660FF8,\n    PSUBW = 0x660FF9,\n    PSUBD = 0x660FFA,\n    PSUBQ = 0x660FFB,\n\n    MULSS = 0xF30F59,\n    MULSD = 0xF20F59,\n    MULPS = 0x000F59,\n    MULPD = 0x660F59,\n    PMULLW = 0x660FD5,\n\n    DIVSS = 0xF30F5E,\n    DIVSD = 0xF20F5E,\n    DIVPS = 0x000F5E,\n    DIVPD = 0x660F5E,\n\n    PAND  = 0x660FDB,\n    POR   = 0x660FEB,\n\n    UCOMISS = 0x000F2E,\n    UCOMISD = 0x660F2E,\n\n    XORPS = 0x000F57,\n    XORPD = 0x660F57,\n\n    // Use STO and LOD instead of MOV to distinguish the direction\n    STOSS  = 0xF30F11,\n    STOSD  = 0xF20F11,\n    STOAPS = 0x000F29,\n    STOAPD = 0x660F29,\n    STODQA = 0x660F7F,\n    STOD   = 0x660F7E,        // MOVD reg/mem64, xmm   66 0F 7E /r\n    STOQ   = 0x660FD6,\n\n    LODSS  = 0xF30F10,\n    LODSD  = 0xF20F10,\n    LODAPS = 0x000F28,\n    LODAPD = 0x660F28,\n    LODDQA = 0x660F6F,\n    LODD   = 0x660F6E,        // MOVD xmm, reg/mem64   66 0F 6E /r\n    LODQ   = 0xF30F7E,\n\n    LODDQU   = 0xF30F6F,      // MOVDQU xmm1, xmm2/mem128  F3 0F 6F /r\n    STODQU   = 0xF30F7F,      // MOVDQU xmm1/mem128, xmm2  F3 0F 7F /r\n    MOVDQ2Q  = 0xF20FD6,      // MOVDQ2Q mmx, xmm          F2 0F D6 /r\n    MOVHLPS  = 0x0F12,        // MOVHLPS xmm1, xmm2        0F 12 /r\n    LODHPD   = 0x660F16,\n    STOHPD   = 0x660F17,      // MOVHPD mem64, xmm         66 0F 17 /r\n    LODHPS   = 0x0F16,\n    STOHPS   = 0x0F17,\n    MOVLHPS  = 0x0F16,\n    LODLPD   = 0x660F12,\n    STOLPD   = 0x660F13,\n    LODLPS   = 0x0F12,\n    STOLPS   = 0x0F13,\n    MOVMSKPD = 0x660F50,\n    MOVMSKPS = 0x0F50,\n    MOVNTDQ  = 0x660FE7,\n    MOVNTI   = 0x0FC3,\n    MOVNTPD  = 0x660F2B,\n    MOVNTPS  = 0x0F2B,\n    MOVNTQ   = 0x0FE7,\n    MOVQ2DQ  = 0xF30FD6,\n    LODUPD   = 0x660F10,\n    STOUPD   = 0x660F11,\n    LODUPS   = 0x0F10,\n    STOUPS   = 0x0F11,\n\n    PACKSSDW = 0x660F6B,\n    PACKSSWB = 0x660F63,\n    PACKUSWB = 0x660F67,\n    PADDSB = 0x660FEC,\n    PADDSW = 0x660FED,\n    PADDUSB = 0x660FDC,\n    PADDUSW = 0x660FDD,\n    PANDN = 0x660FDF,\n    PCMPEQB = 0x660F74,\n    PCMPEQD = 0x660F76,\n    PCMPEQW = 0x660F75,\n    PCMPGTB = 0x660F64,\n    PCMPGTD = 0x660F66,\n    PCMPGTW = 0x660F65,\n    PMADDWD = 0x660FF5,\n    PSLLW = 0x660FF1,\n    PSLLD = 0x660FF2,\n    PSLLQ = 0x660FF3,\n    PSRAW = 0x660FE1,\n    PSRAD = 0x660FE2,\n    PSRLW = 0x660FD1,\n    PSRLD = 0x660FD2,\n    PSRLQ = 0x660FD3,\n    PSUBSB = 0x660FE8,\n    PSUBSW = 0x660FE9,\n    PSUBUSB = 0x660FD8,\n    PSUBUSW = 0x660FD9,\n    PUNPCKHBW = 0x660F68,\n    PUNPCKHDQ = 0x660F6A,\n    PUNPCKHWD = 0x660F69,\n    PUNPCKLBW = 0x660F60,\n    PUNPCKLDQ = 0x660F62,\n    PUNPCKLWD = 0x660F61,\n    PXOR = 0x660FEF,\n    ANDPD = 0x660F54,\n    ANDPS = 0x0F54,\n    ANDNPD = 0x660F55,\n    ANDNPS = 0x0F55,\n    CMPPS = 0x0FC2,\n    CMPPD = 0x660FC2,\n    CMPSD = 0xF20FC2,\n    CMPSS = 0xF30FC2,\n    COMISD = 0x660F2F,\n    COMISS = 0x0F2F,\n    CVTDQ2PD = 0xF30FE6,\n    CVTDQ2PS = 0x0F5B,\n    CVTPD2DQ = 0xF20FE6,\n    CVTPD2PI = 0x660F2D,\n    CVTPD2PS = 0x660F5A,\n    CVTPI2PD = 0x660F2A,\n    CVTPI2PS = 0x0F2A,\n    CVTPS2DQ = 0x660F5B,\n    CVTPS2PD = 0x0F5A,\n    CVTPS2PI = 0x0F2D,\n    CVTSD2SI = 0xF20F2D,\n    CVTSD2SS = 0xF20F5A,\n    CVTSI2SD = 0xF20F2A,\n    CVTSI2SS = 0xF30F2A,\n    CVTSS2SD = 0xF30F5A,\n    CVTSS2SI = 0xF30F2D,\n    CVTTPD2PI = 0x660F2C,\n    CVTTPD2DQ = 0x660FE6,\n    CVTTPS2DQ = 0xF30F5B,\n    CVTTPS2PI = 0x0F2C,\n    CVTTSD2SI = 0xF20F2C,\n    CVTTSS2SI = 0xF30F2C,\n    MASKMOVDQU = 0x660FF7,\n    MASKMOVQ = 0x0FF7,\n    MAXPD = 0x660F5F,\n    MAXPS = 0x0F5F,\n    MAXSD = 0xF20F5F,\n    MAXSS = 0xF30F5F,\n    MINPD = 0x660F5D,\n    MINPS = 0x0F5D,\n    MINSD = 0xF20F5D,\n    MINSS = 0xF30F5D,\n    ORPD = 0x660F56,\n    ORPS = 0x0F56,\n    PAVGB = 0x660FE0,\n    PAVGW = 0x660FE3,\n    PMAXSW = 0x660FEE,\n    //PINSRW = 0x660FC4,\n    PMAXUB = 0x660FDE,\n    PMINSW = 0x660FEA,\n    PMINUB = 0x660FDA,\n    //PMOVMSKB = 0x660FD7,\n    PMULHUW = 0x660FE4,\n    PMULHW = 0x660FE5,\n    PMULUDQ = 0x660FF4,\n    PSADBW = 0x660FF6,\n    PUNPCKHQDQ = 0x660F6D,\n    PUNPCKLQDQ = 0x660F6C,\n    RCPPS = 0x0F53,\n    RCPSS = 0xF30F53,\n    RSQRTPS = 0x0F52,\n    RSQRTSS = 0xF30F52,\n    SQRTPD = 0x660F51,\n    SHUFPD = 0x660FC6,\n    SHUFPS = 0x0FC6,\n    SQRTPS = 0x0F51,\n    SQRTSD = 0xF20F51,\n    SQRTSS = 0xF30F51,\n    UNPCKHPD = 0x660F15,\n    UNPCKHPS = 0x0F15,\n    UNPCKLPD = 0x660F14,\n    UNPCKLPS = 0x0F14,\n\n    PSHUFD = 0x660F70,\n    PSHUFHW = 0xF30F70,\n    PSHUFLW = 0xF20F70,\n    PSHUFW = 0x0F70,\n    PSLLDQ = 0x07660F73,\n    PSRLDQ = 0x03660F73,\n\n    //PREFETCH = 0x0F18,\n\n// SSE3 Pentium 4 (Prescott)\n\n    ADDSUBPD = 0x660FD0,\n    ADDSUBPS = 0xF20FD0,\n    HADDPD   = 0x660F7C,\n    HADDPS   = 0xF20F7C,\n    HSUBPD   = 0x660F7D,\n    HSUBPS   = 0xF20F7D,\n    MOVDDUP  = 0xF20F12,\n    MOVSHDUP = 0xF30F16,\n    MOVSLDUP = 0xF30F12,\n    LDDQU    = 0xF20FF0,\n    MONITOR  = 0x0F01C8,\n    MWAIT    = 0x0F01C9,\n\n// SSSE3\n    PALIGNR = 0x660F3A0F,\n    PHADDD = 0x660F3802,\n    PHADDW = 0x660F3801,\n    PHADDSW = 0x660F3803,\n    PABSB = 0x660F381C,\n    PABSD = 0x660F381E,\n    PABSW = 0x660F381D,\n    PSIGNB = 0x660F3808,\n    PSIGND = 0x660F380A,\n    PSIGNW = 0x660F3809,\n    PSHUFB = 0x660F3800,\n    PMADDUBSW = 0x660F3804,\n    PMULHRSW = 0x660F380B,\n    PHSUBD = 0x660F3806,\n    PHSUBW = 0x660F3805,\n    PHSUBSW = 0x660F3807,\n\n// SSE4.1\n\n    BLENDPD   = 0x660F3A0D,\n    BLENDPS   = 0x660F3A0C,\n    BLENDVPD  = 0x660F3815,\n    BLENDVPS  = 0x660F3814,\n    DPPD      = 0x660F3A41,\n    DPPS      = 0x660F3A40,\n    EXTRACTPS = 0x660F3A17,\n    INSERTPS  = 0x660F3A21,\n    MPSADBW   = 0x660F3A42,\n    PBLENDVB  = 0x660F3810,\n    PBLENDW   = 0x660F3A0E,\n    PEXTRD    = 0x660F3A16,\n    PEXTRQ    = 0x660F3A16,\n    PINSRB    = 0x660F3A20,\n    PINSRD    = 0x660F3A22,\n    PINSRQ    = 0x660F3A22,\n\n    MOVNTDQA = 0x660F382A,\n    PACKUSDW = 0x660F382B,\n    PCMPEQQ = 0x660F3829,\n    PEXTRB = 0x660F3A14,\n    PHMINPOSUW = 0x660F3841,\n    PMAXSB = 0x660F383C,\n    PMAXSD = 0x660F383D,\n    PMAXUD = 0x660F383F,\n    PMAXUW = 0x660F383E,\n    PMINSB = 0x660F3838,\n    PMINSD = 0x660F3839,\n    PMINUD = 0x660F383B,\n    PMINUW = 0x660F383A,\n    PMOVSXBW = 0x660F3820,\n    PMOVSXBD = 0x660F3821,\n    PMOVSXBQ = 0x660F3822,\n    PMOVSXWD = 0x660F3823,\n    PMOVSXWQ = 0x660F3824,\n    PMOVSXDQ = 0x660F3825,\n    PMOVZXBW = 0x660F3830,\n    PMOVZXBD = 0x660F3831,\n    PMOVZXBQ = 0x660F3832,\n    PMOVZXWD = 0x660F3833,\n    PMOVZXWQ = 0x660F3834,\n    PMOVZXDQ = 0x660F3835,\n    PMULDQ   = 0x660F3828,\n    PMULLD   = 0x660F3840,\n    PTEST    = 0x660F3817,\n\n    ROUNDPD = 0x660F3A09,\n    ROUNDPS = 0x660F3A08,\n    ROUNDSD = 0x660F3A0B,\n    ROUNDSS = 0x660F3A0A,\n\n// SSE4.2\n    PCMPESTRI  = 0x660F3A61,\n    PCMPESTRM  = 0x660F3A60,\n    PCMPISTRI  = 0x660F3A63,\n    PCMPISTRM  = 0x660F3A62,\n    PCMPGTQ    = 0x660F3837,\n    //CRC32\n\n// SSE4a (AMD only)\n    // EXTRQ,INSERTQ,MOVNTSD,MOVNTSS\n\n// POPCNT and LZCNT (have their own CPUID bits)\n    POPCNT     = 0xF30FB8,\n    // LZCNT\n  }\n\n  /**\n   * Generate two operand instruction with XMM 128 bit operands.\n   *\n   * This is a compiler magic function - it doesn't behave like\n   * regular D functions.\n   *\n   * Parameters:\n   *      opcode  any of the XMM opcodes; it must be a compile time constant\n   *      op1     first operand\n   *      op2     second operand\n   * Returns:\n   *      result of opcode\n   */\n  pure @safe V1 simd(XMM opcode, V1, V2)(V1 op1, V2 op2)\n      if (is(V1 == __vector) && is(V2 == __vector))\n  {\n      pragma(inline, true);\n      return cast(V1)__simd(opcode, op1, op2);\n  }\n\n  pure @safe void16 __simd(XMM opcode, void16 op1, void16 op2); // intrinsic\n\n  ///\n  unittest\n  {\n      float4 a;\n      a = simd!(XMM.PXOR)(a, a);\n  }\n\n  /**\n   * Unary SIMD instructions.\n   */\n  pure @safe V1 simd(XMM opcode, V1)(V1 op1)\n      if (is(V1 == __vector))\n  {\n      pragma(inline, true);\n      return cast(V1)__simd(opcode, op1);\n  }\n\n  ///\n  pure @safe V1 simd(XMM opcode, V1)(double d)\n      if (is(V1 == __vector))\n  {\n      pragma(inline, true);\n      return cast(V1)__simd(opcode, d);\n  }\n\n  ///\n  pure @safe V1 simd(XMM opcode, V1)(float f)\n      if (is(V1 == __vector))\n  {\n      pragma(inline, true);\n      return cast(V1)__simd(opcode, f);\n  }\n\n  pure @safe void16 __simd(XMM opcode, void16 op1); // intrinsic\n  pure @safe void16 __simd(XMM opcode, double d);   // intrinsic\n  pure @safe void16 __simd(XMM opcode, float f);    // intrinsic\n\n  ///\n  unittest\n  {\n      float4 a;\n      a = simd!(XMM.LODSS)(a);\n  }\n\n  /****\n   * For instructions:\n   * CMPPD, CMPSS, CMPSD, CMPPS,\n   * PSHUFD, PSHUFHW, PSHUFLW,\n   * BLENDPD, BLENDPS, DPPD, DPPS,\n   * MPSADBW, PBLENDW,\n   * ROUNDPD, ROUNDPS, ROUNDSD, ROUNDSS\n   * Parameters:\n   *      opcode  any of the above XMM opcodes; it must be a compile time constant\n   *      op1     first operand\n   *      op2     second operand\n   *      imm8    third operand; must be a compile time constant\n   * Returns:\n   *      result of opcode\n   */\n  pure @safe V1 simd(XMM opcode, ubyte imm8, V1, V2)(V1 op1, V2 op2)\n      if (is(V1 == __vector) && is(V2 == __vector))\n  {\n      pragma(inline, true);\n      return cast(V1)__simd(opcode, op1, op2, imm8);\n  }\n\n  pure @safe void16 __simd(XMM opcode, void16 op1, void16 op2, ubyte imm8); // intrinsic\n\n  ///\n  unittest\n  {\n      float4 a;\n      a = simd!(XMM.CMPPD, 0x7A)(a, a);\n  }\n\n  /***\n   * For instructions with the imm8 version:\n   * PSLLD, PSLLQ, PSLLW, PSRAD, PSRAW, PSRLD, PSRLQ, PSRLW,\n   * PSRLDQ, PSLLDQ\n   * Parameters:\n   *      opcode  any of the XMM opcodes; it must be a compile time constant\n   *      op1     first operand\n   *      imm8    second operand; must be a compile time constant\n   * Returns:\n   *      result of opcode\n   */\n  pure @safe V1 simd(XMM opcode, ubyte imm8, V1)(V1 op1)\n      if (is(V1 == __vector))\n  {\n      pragma(inline, true);\n      return cast(V1)__simd_ib(opcode, op1, imm8);\n  }\n\n  pure @safe void16 __simd_ib(XMM opcode, void16 op1, ubyte imm8);  // intrinsic\n\n  ///\n  unittest\n  {\n      float4 a;\n      a = simd!(XMM.PSRLQ, 0x7A)(a);\n  }\n\n  /*****\n   * For \"store\" operations of the form:\n   *    op1 op= op2\n   * Returns:\n   *    op2\n   * These cannot be marked as pure, as semantic() doesn't check them.\n   */\n  @safe V1 simd_sto(XMM opcode, V1, V2)(V1 op1, V2 op2)\n      if (is(V1 == __vector) && is(V2 == __vector))\n  {\n      pragma(inline, true);\n      return cast(V1)__simd_sto(opcode, op1, op2);\n  }\n\n  ///\n  @safe V1 simd_stod(XMM opcode, V1, V2)(double op1, V1 op2)\n      if (is(V1 == __vector))\n  {\n      pragma(inline, true);\n      return cast(V1)__simd_sto(opcode, op1, op2);\n  }\n\n  ///\n  @safe V1 simd_stof(XMM opcode, V1)(float op1, V1 op2)\n      if (is(V1 == __vector))\n  {\n      pragma(inline, true);\n      return cast(V1)__simd_sto(opcode, op1, op2);\n  }\n\n  @safe void16 __simd_sto(XMM opcode, void16 op1, void16 op2);  // intrinsic\n  @safe void16 __simd_sto(XMM opcode, double op1, void16 op2);  // intrinsic\n  @safe void16 __simd_sto(XMM opcode, float op1, void16 op2);   // intrinsic\n\n  ///\n  unittest\n  {\n      void16 a;\n      float f = 1;\n      double d = 1;\n\n      cast(void)simd_sto!(XMM.STOUPS)(a, a);\n      //simd_sto!(XMM.STOUPS)(f, a);\n      //simd_sto!(XMM.STOUPS)(d, a);\n  }\n\n  /* The following use overloading to ensure correct typing.\n   * Compile with inlining on for best performance.\n   */\n\n  pure @safe short8 pcmpeq()(short8 v1, short8 v2)\n  {\n      return cast(short8)__simd(XMM.PCMPEQW, v1, v2);\n  }\n\n  pure @safe ushort8 pcmpeq()(ushort8 v1, ushort8 v2)\n  {\n      return cast(ushort8)__simd(XMM.PCMPEQW, v1, v2);\n  }\n\n  /*********************\n   * Emit prefetch instruction.\n   * Params:\n   *    address = address to be prefetched\n   *    writeFetch = true for write fetch, false for read fetch\n   *    locality = 0..3 (0 meaning least local, 3 meaning most local)\n   * Note:\n   *    The Intel mappings are:\n   *    $(TABLE\n   *    $(THEAD writeFetch, locality, Instruction)\n   *    $(TROW false, 0, prefetchnta)\n   *    $(TROW false, 1, prefetch2)\n   *    $(TROW false, 2, prefetch1)\n   *    $(TROW false, 3, prefetch0)\n   *    $(TROW false, 0, prefetchw)\n   *    $(TROW false, 1, prefetchw)\n   *    $(TROW false, 2, prefetchw)\n   *    $(TROW false, 3, prefetchw)\n   *    )\n   */\n  void prefetch(bool writeFetch, ubyte locality)(const(void)* address)\n  {\n        static if (writeFetch)\n            __prefetch(address, 4);\n        else static if (locality < 4)\n            __prefetch(address, 3 - locality);\n        else\n            static assert(0, \"0..3 expected for locality\");\n  }\n\n  private void __prefetch(const(void*) address, ubyte encoding);\n\n  /*************************************\n   * Load unaligned vector from address.\n   * This is a compiler intrinsic.\n   * Params:\n   *    p = pointer to vector\n   * Returns:\n   *    vector\n   */\n\n  V loadUnaligned(V)(const V* p)\n        if (is(V == void16) ||\n            is(V == byte16) ||\n            is(V == ubyte16) ||\n            is(V == short8) ||\n            is(V == ushort8) ||\n            is(V == int4) ||\n            is(V == uint4) ||\n            is(V == long2) ||\n            is(V == ulong2))\n  {\n        pragma(inline, true);\n        static if (is(V == double2))\n            return cast(V)__simd(XMM.LODUPD, *cast(const void16*)p);\n        else static if (is(V == float4))\n            return cast(V)__simd(XMM.LODUPS, *cast(const void16*)p);\n        else\n            return cast(V)__simd(XMM.LODDQU, *cast(const void16*)p);\n  }\n\n  /*************************************\n   * Store vector to unaligned address.\n   * This is a compiler intrinsic.\n   * Params:\n   *    p = pointer to vector\n   *    value = value to store\n   * Returns:\n   *    value\n   */\n\n  V storeUnaligned(V)(V* p, V value)\n        if (is(V == void16) ||\n            is(V == byte16) ||\n            is(V == ubyte16) ||\n            is(V == short8) ||\n            is(V == ushort8) ||\n            is(V == int4) ||\n            is(V == uint4) ||\n            is(V == long2) ||\n            is(V == ulong2))\n  {\n        pragma(inline, true);\n        static if (is(V == double2))\n            return cast(V)__simd_sto(XMM.STOUPD, *cast(void16*)p, value);\n        else static if (is(V == float4))\n            return cast(V)__simd_sto(XMM.STOUPS, *cast(void16*)p, value);\n        else\n            return cast(V)__simd_sto(XMM.STODQU, *cast(void16*)p, value);\n  }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/assert_.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_assert.h.html, _assert.h)\n *\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Source:    $(DRUNTIMESRC core/stdc/_assert_.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\n/****************************\n * These are the various functions called by the assert() macro.\n * They are all noreturn functions, although D doesn't have a specific attribute for that.\n */\n\nmodule core.stdc.assert_;\n\nextern (C):\n@trusted:\nnothrow:\n@nogc:\n\nversion (CRuntime_DigitalMars)\n{\n    /***\n     * Assert failure function in the Digital Mars C library.\n     */\n    void _assert(const(void)* exp, const(void)* file, uint line);\n}\nelse version (CRuntime_Microsoft)\n{\n    /***\n     * Assert failure function in the Microsoft C library.\n     * `_assert` is not in assert.h, but it is in the library.\n     */\n    void _wassert(const(wchar)* exp, const(wchar)* file, uint line);\n    ///\n    void _assert(const(char)* exp, const(char)* file, uint line);\n}\nelse version (OSX)\n{\n    /***\n     * Assert failure function in the OSX C library.\n     */\n    void __assert_rtn(const(char)* func, const(char)* file, uint line, const(char)* exp);\n}\nelse version (FreeBSD)\n{\n    /***\n     * Assert failure function in the FreeBSD C library.\n     */\n    void __assert(const(char)* exp, const(char)* file, uint line);\n}\nelse version (DragonFlyBSD)\n{\n    /***\n     * Assert failure function in the DragonFlyBSD C library.\n     */\n    void __assert(const(char)* exp, const(char)* file, uint line);\n}\nelse version (CRuntime_Glibc)\n{\n    /***\n     * Assert failure functions in the GLIBC library.\n     */\n    void __assert(const(char)* exp, const(char)* file, uint line);\n    ///\n    void __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func);\n    ///\n    void __assert_perror_fail(int errnum, const(char)* file, uint line, const(char)* func);\n}\nelse version (CRuntime_Bionic)\n{\n    void __assert(const(char)* __file, int __line, const(char)* __msg);\n}\nelse version (CRuntime_Musl)\n{\n     /***\n     * Assert failure function in the Musl C library.\n     */\n    void __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func);\n}\nelse version (CRuntime_UClibc)\n{\n    void __assert(const(char)* exp, const(char)* file, uint line, const(char)* func);\n}\nelse version (Solaris)\n{\n    void __assert_c99(const(char)* exp, const(char)* file, uint line, const(char)* func);\n}\nelse\n{\n    static assert(0);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/complex.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_complex.h.html, _complex.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_complex.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.complex;\n\nextern (C):\n@trusted: // All of these operate on floating point values only.\nnothrow:\n@nogc:\n\n///\nalias creal complex;\n///\nalias ireal imaginary;\n///\ncdouble cacos(cdouble z);\n///\ncfloat  cacosf(cfloat z);\n///\ncreal   cacosl(creal z);\n\n///\ncdouble casin(cdouble z);\n///\ncfloat  casinf(cfloat z);\n///\ncreal   casinl(creal z);\n\n///\ncdouble catan(cdouble z);\n///\ncfloat  catanf(cfloat z);\n///\ncreal   catanl(creal z);\n\n///\ncdouble ccos(cdouble z);\n///\ncfloat  ccosf(cfloat z);\n///\ncreal   ccosl(creal z);\n\n///\ncdouble csin(cdouble z);\n///\ncfloat  csinf(cfloat z);\n///\ncreal   csinl(creal z);\n\n///\ncdouble ctan(cdouble z);\n///\ncfloat  ctanf(cfloat z);\n///\ncreal   ctanl(creal z);\n\n///\ncdouble cacosh(cdouble z);\n///\ncfloat  cacoshf(cfloat z);\n///\ncreal   cacoshl(creal z);\n\n///\ncdouble casinh(cdouble z);\n///\ncfloat  casinhf(cfloat z);\n///\ncreal   casinhl(creal z);\n\n///\ncdouble catanh(cdouble z);\n///\ncfloat  catanhf(cfloat z);\n///\ncreal   catanhl(creal z);\n\n///\ncdouble ccosh(cdouble z);\n///\ncfloat  ccoshf(cfloat z);\n///\ncreal   ccoshl(creal z);\n\n///\ncdouble csinh(cdouble z);\n///\ncfloat  csinhf(cfloat z);\n///\ncreal   csinhl(creal z);\n\n///\ncdouble ctanh(cdouble z);\n///\ncfloat  ctanhf(cfloat z);\n///\ncreal   ctanhl(creal z);\n\n///\ncdouble cexp(cdouble z);\n///\ncfloat  cexpf(cfloat z);\n///\ncreal   cexpl(creal z);\n\n///\ncdouble clog(cdouble z);\n///\ncfloat  clogf(cfloat z);\n///\ncreal   clogl(creal z);\n\n///\n double cabs(cdouble z);\n ///\n float  cabsf(cfloat z);\n ///\n real   cabsl(creal z);\n\n ///\ncdouble cpow(cdouble x, cdouble y);\n///\ncfloat  cpowf(cfloat x, cfloat y);\n///\ncreal   cpowl(creal x, creal y);\n\n///\ncdouble csqrt(cdouble z);\n///\ncfloat  csqrtf(cfloat z);\n///\ncreal   csqrtl(creal z);\n\n///\n double carg(cdouble z);\n ///\n float  cargf(cfloat z);\n ///\n real   cargl(creal z);\n\n ///\n double cimag(cdouble z);\n ///\n float  cimagf(cfloat z);\n ///\n real   cimagl(creal z);\n\n ///\ncdouble conj(cdouble z);\n///\ncfloat  conjf(cfloat z);\n///\ncreal   conjl(creal z);\n\n///\ncdouble cproj(cdouble z);\n///\ncfloat  cprojf(cfloat z);\n///\ncreal   cprojl(creal z);\n\n// double creal(cdouble z);\n///\n float  crealf(cfloat z);\n ///\n real   creall(creal z);\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/config.d",
    "content": "/***\n * D compatible types that correspond to various basic types in associated\n * C and C++ compilers.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_config.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule core.stdc.config;\n\nversion (StdDdoc)\n{\n    private\n    {\n        version (Posix)\n            enum isPosix = true;\n        else\n            enum isPosix = false;\n        static if (isPosix && (void*).sizeof > int.sizeof)\n        {\n            alias ddoc_long = long;\n            alias ddoc_ulong = ulong;\n        }\n        else\n        {\n            alias ddoc_long = int;\n            alias ddoc_ulong = uint;\n        }\n    }\n\n    /***\n     * Used for a signed integer type that corresponds in size to the associated\n     * C compiler's `long` type.\n     */\n    alias c_long = ddoc_long;\n\n    /***\n     * Used for an unsigned integer type that corresponds in size to the associated\n     * C compiler's `unsigned long` type.\n     */\n    alias c_ulong = ddoc_ulong;\n\n    /***\n     * Used for a signed integer type that corresponds in size and mangling to the associated\n     * C++ compiler's `long` type.\n     */\n    alias cpp_long = c_long;\n\n    /***\n     * Used for an unsigned integer type that corresponds in size and mangling to the associated\n     * C++ compiler's `unsigned long` type.\n     */\n    alias cpp_ulong = c_ulong;\n\n    /***\n     * Used for a signed integer type that corresponds in size and mangling to the associated\n     * C++ compiler's `long long` type.\n     */\n    alias cpp_longlong = long;\n\n    /***\n     * Used for an unsigned integer type that corresponds in size and mangling to the associated\n     * C++ compiler's `unsigned long long` type.\n     */\n    alias cpp_ulonglong = ulong;\n\n    /***\n     * Used for a floating point type that corresponds in size and mangling to the associated\n     * C++ compiler's `long double` type.\n     */\n    alias c_long_double = real;\n\n    /***\n     * Used for an unsigned integer type that corresponds in size and mangling to the associated\n     * C++ compiler's `size_t` type.\n     */\n    alias cpp_size_t = size_t;\n\n    /***\n     * Used for a signed integer type that corresponds in size and mangling to the associated\n     * C++ compiler's `ptrdiff_t` type.\n     */\n    alias cpp_ptrdiff_t = ptrdiff_t;\n}\nelse\n{\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (GNU)\n{\n    import gcc.builtins;\n\n    alias __builtin_clong  c_long;\n    alias __builtin_culong c_ulong;\n\n    enum __c_long  : __builtin_clong;\n    enum __c_ulong : __builtin_culong;\n\n    alias __c_long  cpp_long;\n    alias __c_ulong cpp_ulong;\n\n    enum __c_longlong  : __builtin_clonglong;\n    enum __c_ulonglong : __builtin_culonglong;\n\n    alias __c_longlong  cpp_longlong;\n    alias __c_ulonglong cpp_ulonglong;\n}\nelse version (Windows)\n{\n    enum __c_long  : int;\n    enum __c_ulong : uint;\n\n    alias int   c_long;\n    alias uint  c_ulong;\n\n    alias __c_long   cpp_long;\n    alias __c_ulong  cpp_ulong;\n\n    alias long  cpp_longlong;\n    alias ulong cpp_ulonglong;\n}\nelse version (Posix)\n{\n  static if ( (void*).sizeof > int.sizeof )\n  {\n    enum __c_longlong  : long;\n    enum __c_ulonglong : ulong;\n\n    alias long  c_long;\n    alias ulong c_ulong;\n\n    alias long   cpp_long;\n    alias ulong  cpp_ulong;\n\n    alias __c_longlong  cpp_longlong;\n    alias __c_ulonglong cpp_ulonglong;\n  }\n  else\n  {\n    enum __c_long  : int;\n    enum __c_ulong : uint;\n\n    alias int   c_long;\n    alias uint  c_ulong;\n\n    alias __c_long   cpp_long;\n    alias __c_ulong  cpp_ulong;\n\n    alias long  cpp_longlong;\n    alias ulong cpp_ulonglong;\n  }\n}\n\nversion (CRuntime_Microsoft)\n{\n    /* long double is 64 bits, not 80 bits, but is mangled differently\n     * than double. To distinguish double from long double, create a wrapper to represent\n     * long double, then recognize that wrapper specially in the compiler\n     * to generate the correct name mangling and correct function call/return\n     * ABI conformance.\n     */\n    enum __c_long_double : double;\n\n    alias __c_long_double c_long_double;\n}\nelse version (DigitalMars)\n{\n    version (X86)\n    {\n        alias real c_long_double;\n    }\n    else version (X86_64)\n    {\n        version (linux)\n            alias real c_long_double;\n        else version (FreeBSD)\n            alias real c_long_double;\n        else version (OpenBSD)\n            alias real c_long_double;\n        else version (NetBSD)\n            alias real c_long_double;\n        else version (DragonFlyBSD)\n            alias real c_long_double;\n        else version (Solaris)\n            alias real c_long_double;\n        else version (Darwin)\n            alias real c_long_double;\n    }\n}\nelse version (GNU)\n    alias real c_long_double;\nelse version (LDC)\n    alias real c_long_double;\nelse version (SDC)\n{\n    version (X86)\n        alias real c_long_double;\n    else version (X86_64)\n        alias real c_long_double;\n}\n\nstatic assert(is(c_long_double), \"c_long_double needs to be declared for this platform/architecture.\");\n\nversion (Darwin)\n{\n    alias cpp_size_t = cpp_ulong;\n    version (D_LP64)\n        alias cpp_ptrdiff_t = cpp_long;\n    else\n        alias cpp_ptrdiff_t = ptrdiff_t;\n}\nelse\n{\n    alias cpp_size_t = size_t;\n    alias cpp_ptrdiff_t = ptrdiff_t;\n}\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/ctype.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_ctype.h.html, _ctype.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_ctype.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.ctype;\n\nextern (C):\n@trusted: // All of these operate on integers only.\nnothrow:\n@nogc:\n\n    ///\npure int isalnum(int c);\n///\npure int isalpha(int c);\n///\npure int isblank(int c);\n///\npure int iscntrl(int c);\n///\npure int isdigit(int c);\n///\npure int isgraph(int c);\n///\npure int islower(int c);\n///\npure int isprint(int c);\n///\npure int ispunct(int c);\n///\npure int isspace(int c);\n///\npure int isupper(int c);\n///\npure int isxdigit(int c);\n///\npure int tolower(int c);\n///\npure int toupper(int c);\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/errno.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_errno.h.html, _errno.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Source:    https://github.com/dlang/druntime/blob/master/src/core/stdc/errno.d\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.errno;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\n@trusted: // Only manipulates errno.\nnothrow:\n@nogc:\n\nversion (CRuntime_DigitalMars)\n{\n    extern (C)\n    {\n        ref int _errno();\n        alias errno = _errno;\n    }\n}\nelse version (CRuntime_Microsoft)\n{\n    extern (C)\n    {\n        ref int _errno();\n        alias errno = _errno;\n    }\n}\nelse version (CRuntime_Glibc)\n{\n    extern (C)\n    {\n        ref int __errno_location();\n        alias errno = __errno_location;\n    }\n}\nelse version (CRuntime_Musl)\n{\n    extern (C)\n    {\n        ref int __errno_location();\n        alias errno = __errno_location;\n    }\n}\nelse version (FreeBSD)\n{\n    extern (C)\n    {\n        ref int __error();\n        alias errno = __error;\n    }\n}\nelse version (DragonFlyBSD)\n{\n    pragma(mangle, \"errno\") extern int __errno;\n    ref int errno() { return __errno;}\n}\nelse version (CRuntime_Bionic)\n{\n    extern (C)\n    {\n        ref int __errno();\n        alias errno = __errno;\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    extern (C)\n    {\n        ref int __errno_location();\n        alias errno = __errno_location;\n    }\n}\nelse version (Darwin)\n{\n    extern (C)\n    {\n        ref int __error();\n        alias errno = __error;\n    }\n}\nelse version (Solaris)\n{\n    extern (C)\n    {\n        ref int ___errno();\n        alias errno = ___errno;\n    }\n}\nelse\n{\n    ///\n    @property int errno() { return getErrno(); }\n    ///\n    @property int errno(int n) { return setErrno(n); }\n\n    extern (C)\n    {\n        private int getErrno();      // for internal use\n        private int setErrno(int);   // for internal use\n    }\n}\n\nextern (C):\n\n\nversion (Windows)\n{\n    enum EPERM              = 1;        /// Operation not permitted\n    enum ENOENT             = 2;        /// No such file or directory\n    enum ESRCH              = 3;        /// No such process\n    enum EINTR              = 4;        /// Interrupted system call\n    enum EIO                = 5;        /// I/O error\n    enum ENXIO              = 6;        /// No such device or address\n    enum E2BIG              = 7;        /// Argument list too long\n    enum ENOEXEC            = 8;        /// Exec format error\n    enum EBADF              = 9;        /// Bad file number\n    enum ECHILD             = 10;       /// No child processes\n    enum EAGAIN             = 11;       /// Try again\n    enum ENOMEM             = 12;       /// Out of memory\n    enum EACCES             = 13;       /// Permission denied\n    enum EFAULT             = 14;       /// Bad address\n    enum EBUSY              = 16;       /// Device or resource busy\n    enum EEXIST             = 17;       /// File exists\n    enum EXDEV              = 18;       /// Cross-device link\n    enum ENODEV             = 19;       /// No such device\n    enum ENOTDIR            = 20;       /// Not a directory\n    enum EISDIR             = 21;       /// Is a directory\n    enum EINVAL             = 22;       /// Invalid argument\n    enum ENFILE             = 23;       /// File table overflow\n    enum EMFILE             = 24;       /// Too many open files\n    enum ENOTTY             = 25;       /// Not a typewriter\n    enum EFBIG              = 27;       /// File too large\n    enum ENOSPC             = 28;       /// No space left on device\n    enum ESPIPE             = 29;       /// Illegal seek\n    enum EROFS              = 30;       /// Read-only file system\n    enum EMLINK             = 31;       /// Too many links\n    enum EPIPE              = 32;       /// Broken pipe\n    enum EDOM               = 33;       /// Math argument out of domain of func\n    enum ERANGE             = 34;       /// Math result not representable\n    enum EDEADLK            = 36;       /// Resource deadlock would occur\n    enum ENAMETOOLONG       = 38;       /// File name too long\n    enum ENOLCK             = 39;       /// No record locks available\n    enum ENOSYS             = 40;       /// Function not implemented\n    enum ENOTEMPTY          = 41;       /// Directory not empty\n    enum EILSEQ             = 42;       /// Illegal byte sequence\n    enum EDEADLOCK          = EDEADLK;  /// Resource deadlock would occur\n}\nelse version (linux)\n{\n    enum EPERM              = 1;  ///\n    enum ENOENT             = 2;  ///\n    enum ESRCH              = 3;  ///\n    enum EINTR              = 4;  ///\n    enum EIO                = 5;  ///\n    enum ENXIO              = 6;  ///\n    enum E2BIG              = 7;  ///\n    enum ENOEXEC            = 8;  ///\n    enum EBADF              = 9;  ///\n    enum ECHILD             = 10; ///\n    enum EAGAIN             = 11; ///\n    enum ENOMEM             = 12; ///\n    enum EACCES             = 13; ///\n    enum EFAULT             = 14; ///\n    enum ENOTBLK            = 15; ///\n    enum EBUSY              = 16; ///\n    enum EEXIST             = 17; ///\n    enum EXDEV              = 18; ///\n    enum ENODEV             = 19; ///\n    enum ENOTDIR            = 20; ///\n    enum EISDIR             = 21; ///\n    enum EINVAL             = 22; ///\n    enum ENFILE             = 23; ///\n    enum EMFILE             = 24; ///\n    enum ENOTTY             = 25; ///\n    enum ETXTBSY            = 26; ///\n    enum EFBIG              = 27; ///\n    enum ENOSPC             = 28; ///\n    enum ESPIPE             = 29; ///\n    enum EROFS              = 30; ///\n    enum EMLINK             = 31; ///\n    enum EPIPE              = 32; ///\n    enum EDOM               = 33; ///\n    enum ERANGE             = 34; ///\n\n    version (X86)\n    {\n        enum EDEADLK            = 35;         ///\n        enum ENAMETOOLONG       = 36;         ///\n        enum ENOLCK             = 37;         ///\n        enum ENOSYS             = 38;         ///\n        enum ENOTEMPTY          = 39;         ///\n        enum ELOOP              = 40;         ///\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum ENOMSG             = 42;         ///\n        enum EIDRM              = 43;         ///\n        enum ECHRNG             = 44;         ///\n        enum EL2NSYNC           = 45;         ///\n        enum EL3HLT             = 46;         ///\n        enum EL3RST             = 47;         ///\n        enum ELNRNG             = 48;         ///\n        enum EUNATCH            = 49;         ///\n        enum ENOCSI             = 50;         ///\n        enum EL2HLT             = 51;         ///\n        enum EBADE              = 52;         ///\n        enum EBADR              = 53;         ///\n        enum EXFULL             = 54;         ///\n        enum ENOANO             = 55;         ///\n        enum EBADRQC            = 56;         ///\n        enum EBADSLT            = 57;         ///\n        enum EDEADLOCK          = EDEADLK;    ///\n        enum EBFONT             = 59;         ///\n        enum ENOSTR             = 60;         ///\n        enum ENODATA            = 61;         ///\n        enum ETIME              = 62;         ///\n        enum ENOSR              = 63;         ///\n        enum ENONET             = 64;         ///\n        enum ENOPKG             = 65;         ///\n        enum EREMOTE            = 66;         ///\n        enum ENOLINK            = 67;         ///\n        enum EADV               = 68;         ///\n        enum ESRMNT             = 69;         ///\n        enum ECOMM              = 70;         ///\n        enum EPROTO             = 71;         ///\n        enum EMULTIHOP          = 72;         ///\n        enum EDOTDOT            = 73;         ///\n        enum EBADMSG            = 74;         ///\n        enum EOVERFLOW          = 75;         ///\n        enum ENOTUNIQ           = 76;         ///\n        enum EBADFD             = 77;         ///\n        enum EREMCHG            = 78;         ///\n        enum ELIBACC            = 79;         ///\n        enum ELIBBAD            = 80;         ///\n        enum ELIBSCN            = 81;         ///\n        enum ELIBMAX            = 82;         ///\n        enum ELIBEXEC           = 83;         ///\n        enum EILSEQ             = 84;         ///\n        enum ERESTART           = 85;         ///\n        enum ESTRPIPE           = 86;         ///\n        enum EUSERS             = 87;         ///\n        enum ENOTSOCK           = 88;         ///\n        enum EDESTADDRREQ       = 89;         ///\n        enum EMSGSIZE           = 90;         ///\n        enum EPROTOTYPE         = 91;         ///\n        enum ENOPROTOOPT        = 92;         ///\n        enum EPROTONOSUPPORT    = 93;         ///\n        enum ESOCKTNOSUPPORT    = 94;         ///\n        enum EOPNOTSUPP         = 95;         ///\n        enum ENOTSUP            = EOPNOTSUPP; ///\n        enum EPFNOSUPPORT       = 96;         ///\n        enum EAFNOSUPPORT       = 97;         ///\n        enum EADDRINUSE         = 98;         ///\n        enum EADDRNOTAVAIL      = 99;         ///\n        enum ENETDOWN           = 100;        ///\n        enum ENETUNREACH        = 101;        ///\n        enum ENETRESET          = 102;        ///\n        enum ECONNABORTED       = 103;        ///\n        enum ECONNRESET         = 104;        ///\n        enum ENOBUFS            = 105;        ///\n        enum EISCONN            = 106;        ///\n        enum ENOTCONN           = 107;        ///\n        enum ESHUTDOWN          = 108;        ///\n        enum ETOOMANYREFS       = 109;        ///\n        enum ETIMEDOUT          = 110;        ///\n        enum ECONNREFUSED       = 111;        ///\n        enum EHOSTDOWN          = 112;        ///\n        enum EHOSTUNREACH       = 113;        ///\n        enum EALREADY           = 114;        ///\n        enum EINPROGRESS        = 115;        ///\n        enum ESTALE             = 116;        ///\n        enum EUCLEAN            = 117;        ///\n        enum ENOTNAM            = 118;        ///\n        enum ENAVAIL            = 119;        ///\n        enum EISNAM             = 120;        ///\n        enum EREMOTEIO          = 121;        ///\n        enum EDQUOT             = 122;        ///\n        enum ENOMEDIUM          = 123;        ///\n        enum EMEDIUMTYPE        = 124;        ///\n        enum ECANCELED          = 125;        ///\n        enum ENOKEY             = 126;        ///\n        enum EKEYEXPIRED        = 127;        ///\n        enum EKEYREVOKED        = 128;        ///\n        enum EKEYREJECTED       = 129;        ///\n        enum EOWNERDEAD         = 130;        ///\n        enum ENOTRECOVERABLE    = 131;        ///\n        enum ERFKILL            = 132;        ///\n        enum EHWPOISON          = 133;        ///\n    }\n    else version (X86_64)\n    {\n        enum EDEADLK            = 35;         ///\n        enum ENAMETOOLONG       = 36;         ///\n        enum ENOLCK             = 37;         ///\n        enum ENOSYS             = 38;         ///\n        enum ENOTEMPTY          = 39;         ///\n        enum ELOOP              = 40;         ///\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum ENOMSG             = 42;         ///\n        enum EIDRM              = 43;         ///\n        enum ECHRNG             = 44;         ///\n        enum EL2NSYNC           = 45;         ///\n        enum EL3HLT             = 46;         ///\n        enum EL3RST             = 47;         ///\n        enum ELNRNG             = 48;         ///\n        enum EUNATCH            = 49;         ///\n        enum ENOCSI             = 50;         ///\n        enum EL2HLT             = 51;         ///\n        enum EBADE              = 52;         ///\n        enum EBADR              = 53;         ///\n        enum EXFULL             = 54;         ///\n        enum ENOANO             = 55;         ///\n        enum EBADRQC            = 56;         ///\n        enum EBADSLT            = 57;         ///\n        enum EDEADLOCK          = EDEADLK;    ///\n        enum EBFONT             = 59;         ///\n        enum ENOSTR             = 60;         ///\n        enum ENODATA            = 61;         ///\n        enum ETIME              = 62;         ///\n        enum ENOSR              = 63;         ///\n        enum ENONET             = 64;         ///\n        enum ENOPKG             = 65;         ///\n        enum EREMOTE            = 66;         ///\n        enum ENOLINK            = 67;         ///\n        enum EADV               = 68;         ///\n        enum ESRMNT             = 69;         ///\n        enum ECOMM              = 70;         ///\n        enum EPROTO             = 71;         ///\n        enum EMULTIHOP          = 72;         ///\n        enum EDOTDOT            = 73;         ///\n        enum EBADMSG            = 74;         ///\n        enum EOVERFLOW          = 75;         ///\n        enum ENOTUNIQ           = 76;         ///\n        enum EBADFD             = 77;         ///\n        enum EREMCHG            = 78;         ///\n        enum ELIBACC            = 79;         ///\n        enum ELIBBAD            = 80;         ///\n        enum ELIBSCN            = 81;         ///\n        enum ELIBMAX            = 82;         ///\n        enum ELIBEXEC           = 83;         ///\n        enum EILSEQ             = 84;         ///\n        enum ERESTART           = 85;         ///\n        enum ESTRPIPE           = 86;         ///\n        enum EUSERS             = 87;         ///\n        enum ENOTSOCK           = 88;         ///\n        enum EDESTADDRREQ       = 89;         ///\n        enum EMSGSIZE           = 90;         ///\n        enum EPROTOTYPE         = 91;         ///\n        enum ENOPROTOOPT        = 92;         ///\n        enum EPROTONOSUPPORT    = 93;         ///\n        enum ESOCKTNOSUPPORT    = 94;         ///\n        enum EOPNOTSUPP         = 95;         ///\n        enum ENOTSUP            = EOPNOTSUPP; ///\n        enum EPFNOSUPPORT       = 96;         ///\n        enum EAFNOSUPPORT       = 97;         ///\n        enum EADDRINUSE         = 98;         ///\n        enum EADDRNOTAVAIL      = 99;         ///\n        enum ENETDOWN           = 100;        ///\n        enum ENETUNREACH        = 101;        ///\n        enum ENETRESET          = 102;        ///\n        enum ECONNABORTED       = 103;        ///\n        enum ECONNRESET         = 104;        ///\n        enum ENOBUFS            = 105;        ///\n        enum EISCONN            = 106;        ///\n        enum ENOTCONN           = 107;        ///\n        enum ESHUTDOWN          = 108;        ///\n        enum ETOOMANYREFS       = 109;        ///\n        enum ETIMEDOUT          = 110;        ///\n        enum ECONNREFUSED       = 111;        ///\n        enum EHOSTDOWN          = 112;        ///\n        enum EHOSTUNREACH       = 113;        ///\n        enum EALREADY           = 114;        ///\n        enum EINPROGRESS        = 115;        ///\n        enum ESTALE             = 116;        ///\n        enum EUCLEAN            = 117;        ///\n        enum ENOTNAM            = 118;        ///\n        enum ENAVAIL            = 119;        ///\n        enum EISNAM             = 120;        ///\n        enum EREMOTEIO          = 121;        ///\n        enum EDQUOT             = 122;        ///\n        enum ENOMEDIUM          = 123;        ///\n        enum EMEDIUMTYPE        = 124;        ///\n        enum ECANCELED          = 125;        ///\n        enum ENOKEY             = 126;        ///\n        enum EKEYEXPIRED        = 127;        ///\n        enum EKEYREVOKED        = 128;        ///\n        enum EKEYREJECTED       = 129;        ///\n        enum EOWNERDEAD         = 130;        ///\n        enum ENOTRECOVERABLE    = 131;        ///\n        enum ERFKILL            = 132;        ///\n        enum EHWPOISON          = 133;        ///\n    }\n    else version (ARM)\n    {\n        enum EDEADLK            = 35;         ///\n        enum ENAMETOOLONG       = 36;         ///\n        enum ENOLCK             = 37;         ///\n        enum ENOSYS             = 38;         ///\n        enum ENOTEMPTY          = 39;         ///\n        enum ELOOP              = 40;         ///\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum ENOMSG             = 42;         ///\n        enum EIDRM              = 43;         ///\n        enum ECHRNG             = 44;         ///\n        enum EL2NSYNC           = 45;         ///\n        enum EL3HLT             = 46;         ///\n        enum EL3RST             = 47;         ///\n        enum ELNRNG             = 48;         ///\n        enum EUNATCH            = 49;         ///\n        enum ENOCSI             = 50;         ///\n        enum EL2HLT             = 51;         ///\n        enum EBADE              = 52;         ///\n        enum EBADR              = 53;         ///\n        enum EXFULL             = 54;         ///\n        enum ENOANO             = 55;         ///\n        enum EBADRQC            = 56;         ///\n        enum EBADSLT            = 57;         ///\n        enum EDEADLOCK          = EDEADLK;    ///\n        enum EBFONT             = 59;         ///\n        enum ENOSTR             = 60;         ///\n        enum ENODATA            = 61;         ///\n        enum ETIME              = 62;         ///\n        enum ENOSR              = 63;         ///\n        enum ENONET             = 64;         ///\n        enum ENOPKG             = 65;         ///\n        enum EREMOTE            = 66;         ///\n        enum ENOLINK            = 67;         ///\n        enum EADV               = 68;         ///\n        enum ESRMNT             = 69;         ///\n        enum ECOMM              = 70;         ///\n        enum EPROTO             = 71;         ///\n        enum EMULTIHOP          = 72;         ///\n        enum EDOTDOT            = 73;         ///\n        enum EBADMSG            = 74;         ///\n        enum EOVERFLOW          = 75;         ///\n        enum ENOTUNIQ           = 76;         ///\n        enum EBADFD             = 77;         ///\n        enum EREMCHG            = 78;         ///\n        enum ELIBACC            = 79;         ///\n        enum ELIBBAD            = 80;         ///\n        enum ELIBSCN            = 81;         ///\n        enum ELIBMAX            = 82;         ///\n        enum ELIBEXEC           = 83;         ///\n        enum EILSEQ             = 84;         ///\n        enum ERESTART           = 85;         ///\n        enum ESTRPIPE           = 86;         ///\n        enum EUSERS             = 87;         ///\n        enum ENOTSOCK           = 88;         ///\n        enum EDESTADDRREQ       = 89;         ///\n        enum EMSGSIZE           = 90;         ///\n        enum EPROTOTYPE         = 91;         ///\n        enum ENOPROTOOPT        = 92;         ///\n        enum EPROTONOSUPPORT    = 93;         ///\n        enum ESOCKTNOSUPPORT    = 94;         ///\n        enum EOPNOTSUPP         = 95;         ///\n        enum ENOTSUP            = EOPNOTSUPP; ///\n        enum EPFNOSUPPORT       = 96;         ///\n        enum EAFNOSUPPORT       = 97;         ///\n        enum EADDRINUSE         = 98;         ///\n        enum EADDRNOTAVAIL      = 99;         ///\n        enum ENETDOWN           = 100;        ///\n        enum ENETUNREACH        = 101;        ///\n        enum ENETRESET          = 102;        ///\n        enum ECONNABORTED       = 103;        ///\n        enum ECONNRESET         = 104;        ///\n        enum ENOBUFS            = 105;        ///\n        enum EISCONN            = 106;        ///\n        enum ENOTCONN           = 107;        ///\n        enum ESHUTDOWN          = 108;        ///\n        enum ETOOMANYREFS       = 109;        ///\n        enum ETIMEDOUT          = 110;        ///\n        enum ECONNREFUSED       = 111;        ///\n        enum EHOSTDOWN          = 112;        ///\n        enum EHOSTUNREACH       = 113;        ///\n        enum EALREADY           = 114;        ///\n        enum EINPROGRESS        = 115;        ///\n        enum ESTALE             = 116;        ///\n        enum EUCLEAN            = 117;        ///\n        enum ENOTNAM            = 118;        ///\n        enum ENAVAIL            = 119;        ///\n        enum EISNAM             = 120;        ///\n        enum EREMOTEIO          = 121;        ///\n        enum EDQUOT             = 122;        ///\n        enum ENOMEDIUM          = 123;        ///\n        enum EMEDIUMTYPE        = 124;        ///\n        enum ECANCELED          = 125;        ///\n        enum ENOKEY             = 126;        ///\n        enum EKEYEXPIRED        = 127;        ///\n        enum EKEYREVOKED        = 128;        ///\n        enum EKEYREJECTED       = 129;        ///\n        enum EOWNERDEAD         = 130;        ///\n        enum ENOTRECOVERABLE    = 131;        ///\n        enum ERFKILL            = 132;        ///\n        enum EHWPOISON          = 133;        ///\n    }\n    else version (AArch64)\n    {\n        enum EDEADLK            = 35;         ///\n        enum ENAMETOOLONG       = 36;         ///\n        enum ENOLCK             = 37;         ///\n        enum ENOSYS             = 38;         ///\n        enum ENOTEMPTY          = 39;         ///\n        enum ELOOP              = 40;         ///\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum ENOMSG             = 42;         ///\n        enum EIDRM              = 43;         ///\n        enum ECHRNG             = 44;         ///\n        enum EL2NSYNC           = 45;         ///\n        enum EL3HLT             = 46;         ///\n        enum EL3RST             = 47;         ///\n        enum ELNRNG             = 48;         ///\n        enum EUNATCH            = 49;         ///\n        enum ENOCSI             = 50;         ///\n        enum EL2HLT             = 51;         ///\n        enum EBADE              = 52;         ///\n        enum EBADR              = 53;         ///\n        enum EXFULL             = 54;         ///\n        enum ENOANO             = 55;         ///\n        enum EBADRQC            = 56;         ///\n        enum EBADSLT            = 57;         ///\n        enum EDEADLOCK          = EDEADLK;    ///\n        enum EBFONT             = 59;         ///\n        enum ENOSTR             = 60;         ///\n        enum ENODATA            = 61;         ///\n        enum ETIME              = 62;         ///\n        enum ENOSR              = 63;         ///\n        enum ENONET             = 64;         ///\n        enum ENOPKG             = 65;         ///\n        enum EREMOTE            = 66;         ///\n        enum ENOLINK            = 67;         ///\n        enum EADV               = 68;         ///\n        enum ESRMNT             = 69;         ///\n        enum ECOMM              = 70;         ///\n        enum EPROTO             = 71;         ///\n        enum EMULTIHOP          = 72;         ///\n        enum EDOTDOT            = 73;         ///\n        enum EBADMSG            = 74;         ///\n        enum EOVERFLOW          = 75;         ///\n        enum ENOTUNIQ           = 76;         ///\n        enum EBADFD             = 77;         ///\n        enum EREMCHG            = 78;         ///\n        enum ELIBACC            = 79;         ///\n        enum ELIBBAD            = 80;         ///\n        enum ELIBSCN            = 81;         ///\n        enum ELIBMAX            = 82;         ///\n        enum ELIBEXEC           = 83;         ///\n        enum EILSEQ             = 84;         ///\n        enum ERESTART           = 85;         ///\n        enum ESTRPIPE           = 86;         ///\n        enum EUSERS             = 87;         ///\n        enum ENOTSOCK           = 88;         ///\n        enum EDESTADDRREQ       = 89;         ///\n        enum EMSGSIZE           = 90;         ///\n        enum EPROTOTYPE         = 91;         ///\n        enum ENOPROTOOPT        = 92;         ///\n        enum EPROTONOSUPPORT    = 93;         ///\n        enum ESOCKTNOSUPPORT    = 94;         ///\n        enum EOPNOTSUPP         = 95;         ///\n        enum ENOTSUP            = EOPNOTSUPP; ///\n        enum EPFNOSUPPORT       = 96;         ///\n        enum EAFNOSUPPORT       = 97;         ///\n        enum EADDRINUSE         = 98;         ///\n        enum EADDRNOTAVAIL      = 99;         ///\n        enum ENETDOWN           = 100;        ///\n        enum ENETUNREACH        = 101;        ///\n        enum ENETRESET          = 102;        ///\n        enum ECONNABORTED       = 103;        ///\n        enum ECONNRESET         = 104;        ///\n        enum ENOBUFS            = 105;        ///\n        enum EISCONN            = 106;        ///\n        enum ENOTCONN           = 107;        ///\n        enum ESHUTDOWN          = 108;        ///\n        enum ETOOMANYREFS       = 109;        ///\n        enum ETIMEDOUT          = 110;        ///\n        enum ECONNREFUSED       = 111;        ///\n        enum EHOSTDOWN          = 112;        ///\n        enum EHOSTUNREACH       = 113;        ///\n        enum EALREADY           = 114;        ///\n        enum EINPROGRESS        = 115;        ///\n        enum ESTALE             = 116;        ///\n        enum EUCLEAN            = 117;        ///\n        enum ENOTNAM            = 118;        ///\n        enum ENAVAIL            = 119;        ///\n        enum EISNAM             = 120;        ///\n        enum EREMOTEIO          = 121;        ///\n        enum EDQUOT             = 122;        ///\n        enum ENOMEDIUM          = 123;        ///\n        enum EMEDIUMTYPE        = 124;        ///\n        enum ECANCELED          = 125;        ///\n        enum ENOKEY             = 126;        ///\n        enum EKEYEXPIRED        = 127;        ///\n        enum EKEYREVOKED        = 128;        ///\n        enum EKEYREJECTED       = 129;        ///\n        enum EOWNERDEAD         = 130;        ///\n        enum ENOTRECOVERABLE    = 131;        ///\n        enum ERFKILL            = 132;        ///\n        enum EHWPOISON          = 133;        ///\n    }\n    else version (MIPS32)\n    {\n        enum ENOMSG             = 35;         ///\n        enum EIDRM              = 36;         ///\n        enum ECHRNG             = 37;         ///\n        enum EL2NSYNC           = 38;         ///\n        enum EL3HLT             = 39;         ///\n        enum EL3RST             = 40;         ///\n        enum ELNRNG             = 41;         ///\n        enum EUNATCH            = 42;         ///\n        enum ENOCSI             = 43;         ///\n        enum EL2HLT             = 44;         ///\n        enum EDEADLK            = 45;         ///\n        enum ENOLCK             = 46;         ///\n        enum EBADE              = 50;         ///\n        enum EBADR              = 51;         ///\n        enum EXFULL             = 52;         ///\n        enum ENOANO             = 53;         ///\n        enum EBADRQC            = 54;         ///\n        enum EBADSLT            = 55;         ///\n        enum EDEADLOCK          = 56;         ///\n        enum EBFONT             = 59;         ///\n        enum ENOSTR             = 60;         ///\n        enum ENODATA            = 61;         ///\n        enum ETIME              = 62;         ///\n        enum ENOSR              = 63;         ///\n        enum ENONET             = 64;         ///\n        enum ENOPKG             = 65;         ///\n        enum EREMOTE            = 66;         ///\n        enum ENOLINK            = 67;         ///\n        enum EADV               = 68;         ///\n        enum ESRMNT             = 69;         ///\n        enum ECOMM              = 70;         ///\n        enum EPROTO             = 71;         ///\n        enum EDOTDOT            = 73;         ///\n        enum EMULTIHOP          = 74;         ///\n        enum EBADMSG            = 77;         ///\n        enum ENAMETOOLONG       = 78;         ///\n        enum EOVERFLOW          = 79;         ///\n        enum ENOTUNIQ           = 80;         ///\n        enum EBADFD             = 81;         ///\n        enum EREMCHG            = 82;         ///\n        enum ELIBACC            = 83;         ///\n        enum ELIBBAD            = 84;         ///\n        enum ELIBSCN            = 85;         ///\n        enum ELIBMAX            = 86;         ///\n        enum ELIBEXEC           = 87;         ///\n        enum EILSEQ             = 88;         ///\n        enum ENOSYS             = 89;         ///\n        enum ELOOP              = 90;         ///\n        enum ERESTART           = 91;         ///\n        enum ESTRPIPE           = 92;         ///\n        enum ENOTEMPTY          = 93;         ///\n        enum EUSERS             = 94;         ///\n        enum ENOTSOCK           = 95;         ///\n        enum EDESTADDRREQ       = 96;         ///\n        enum EMSGSIZE           = 97;         ///\n        enum EPROTOTYPE         = 98;         ///\n        enum ENOPROTOOPT        = 99;         ///\n        enum EPROTONOSUPPORT    = 120;        ///\n        enum ESOCKTNOSUPPORT    = 121;        ///\n        enum EOPNOTSUPP         = 122;        ///\n        enum ENOTSUP            = EOPNOTSUPP; ///\n        enum EPFNOSUPPORT       = 123;        ///\n        enum EAFNOSUPPORT       = 124;        ///\n        enum EADDRINUSE         = 125;        ///\n        enum EADDRNOTAVAIL      = 126;        ///\n        enum ENETDOWN           = 127;        ///\n        enum ENETUNREACH        = 128;        ///\n        enum ENETRESET          = 129;        ///\n        enum ECONNABORTED       = 130;        ///\n        enum ECONNRESET         = 131;        ///\n        enum ENOBUFS            = 132;        ///\n        enum EISCONN            = 133;        ///\n        enum ENOTCONN           = 134;        ///\n        enum EUCLEAN            = 135;        ///\n        enum ENOTNAM            = 137;        ///\n        enum ENAVAIL            = 138;        ///\n        enum EISNAM             = 139;        ///\n        enum EREMOTEIO          = 140;        ///\n        enum EINIT              = 141;        ///\n        enum EREMDEV            = 142;        ///\n        enum ESHUTDOWN          = 143;        ///\n        enum ETOOMANYREFS       = 144;        ///\n        enum ETIMEDOUT          = 145;        ///\n        enum ECONNREFUSED       = 146;        ///\n        enum EHOSTDOWN          = 147;        ///\n        enum EHOSTUNREACH       = 148;        ///\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum EALREADY           = 149;        ///\n        enum EINPROGRESS        = 150;        ///\n        enum ESTALE             = 151;        ///\n        enum ECANCELED          = 158;        ///\n        enum ENOMEDIUM          = 159;        ///\n        enum EMEDIUMTYPE        = 160;        ///\n        enum ENOKEY             = 161;        ///\n        enum EKEYEXPIRED        = 162;        ///\n        enum EKEYREVOKED        = 163;        ///\n        enum EKEYREJECTED       = 164;        ///\n        enum EOWNERDEAD         = 165;        ///\n        enum ENOTRECOVERABLE    = 166;        ///\n        enum ERFKILL            = 167;        ///\n        enum EHWPOISON          = 168;        ///\n        enum EDQUOT             = 1133;       ///\n    }\n    else version (MIPS64)\n    {\n        enum ENOMSG             = 35;         ///\n        enum EIDRM              = 36;         ///\n        enum ECHRNG             = 37;         ///\n        enum EL2NSYNC           = 38;         ///\n        enum EL3HLT             = 39;         ///\n        enum EL3RST             = 40;         ///\n        enum ELNRNG             = 41;         ///\n        enum EUNATCH            = 42;         ///\n        enum ENOCSI             = 43;         ///\n        enum EL2HLT             = 44;         ///\n        enum EDEADLK            = 45;         ///\n        enum ENOLCK             = 46;         ///\n        enum EBADE              = 50;         ///\n        enum EBADR              = 51;         ///\n        enum EXFULL             = 52;         ///\n        enum ENOANO             = 53;         ///\n        enum EBADRQC            = 54;         ///\n        enum EBADSLT            = 55;         ///\n        enum EDEADLOCK          = 56;         ///\n        enum EBFONT             = 59;         ///\n        enum ENOSTR             = 60;         ///\n        enum ENODATA            = 61;         ///\n        enum ETIME              = 62;         ///\n        enum ENOSR              = 63;         ///\n        enum ENONET             = 64;         ///\n        enum ENOPKG             = 65;         ///\n        enum EREMOTE            = 66;         ///\n        enum ENOLINK            = 67;         ///\n        enum EADV               = 68;         ///\n        enum ESRMNT             = 69;         ///\n        enum ECOMM              = 70;         ///\n        enum EPROTO             = 71;         ///\n        enum EDOTDOT            = 73;         ///\n        enum EMULTIHOP          = 74;         ///\n        enum EBADMSG            = 77;         ///\n        enum ENAMETOOLONG       = 78;         ///\n        enum EOVERFLOW          = 79;         ///\n        enum ENOTUNIQ           = 80;         ///\n        enum EBADFD             = 81;         ///\n        enum EREMCHG            = 82;         ///\n        enum ELIBACC            = 83;         ///\n        enum ELIBBAD            = 84;         ///\n        enum ELIBSCN            = 85;         ///\n        enum ELIBMAX            = 86;         ///\n        enum ELIBEXEC           = 87;         ///\n        enum EILSEQ             = 88;         ///\n        enum ENOSYS             = 89;         ///\n        enum ELOOP              = 90;         ///\n        enum ERESTART           = 91;         ///\n        enum ESTRPIPE           = 92;         ///\n        enum ENOTEMPTY          = 93;         ///\n        enum EUSERS             = 94;         ///\n        enum ENOTSOCK           = 95;         ///\n        enum EDESTADDRREQ       = 96;         ///\n        enum EMSGSIZE           = 97;         ///\n        enum EPROTOTYPE         = 98;         ///\n        enum ENOPROTOOPT        = 99;         ///\n        enum EPROTONOSUPPORT    = 120;        ///\n        enum ESOCKTNOSUPPORT    = 121;        ///\n        enum EOPNOTSUPP         = 122;        ///\n        enum ENOTSUP            = EOPNOTSUPP; ///\n        enum EPFNOSUPPORT       = 123;        ///\n        enum EAFNOSUPPORT       = 124;        ///\n        enum EADDRINUSE         = 125;        ///\n        enum EADDRNOTAVAIL      = 126;        ///\n        enum ENETDOWN           = 127;        ///\n        enum ENETUNREACH        = 128;        ///\n        enum ENETRESET          = 129;        ///\n        enum ECONNABORTED       = 130;        ///\n        enum ECONNRESET         = 131;        ///\n        enum ENOBUFS            = 132;        ///\n        enum EISCONN            = 133;        ///\n        enum ENOTCONN           = 134;        ///\n        enum EUCLEAN            = 135;        ///\n        enum ENOTNAM            = 137;        ///\n        enum ENAVAIL            = 138;        ///\n        enum EISNAM             = 139;        ///\n        enum EREMOTEIO          = 140;        ///\n        enum EINIT              = 141;        ///\n        enum EREMDEV            = 142;        ///\n        enum ESHUTDOWN          = 143;        ///\n        enum ETOOMANYREFS       = 144;        ///\n        enum ETIMEDOUT          = 145;        ///\n        enum ECONNREFUSED       = 146;        ///\n        enum EHOSTDOWN          = 147;        ///\n        enum EHOSTUNREACH       = 148;        ///\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum EALREADY           = 149;        ///\n        enum EINPROGRESS        = 150;        ///\n        enum ESTALE             = 151;        ///\n        enum ECANCELED          = 158;        ///\n        enum ENOMEDIUM          = 159;        ///\n        enum EMEDIUMTYPE        = 160;        ///\n        enum ENOKEY             = 161;        ///\n        enum EKEYEXPIRED        = 162;        ///\n        enum EKEYREVOKED        = 163;        ///\n        enum EKEYREJECTED       = 164;        ///\n        enum EOWNERDEAD         = 165;        ///\n        enum ENOTRECOVERABLE    = 166;        ///\n        enum ERFKILL            = 167;        ///\n        enum EHWPOISON          = 168;        ///\n        enum EDQUOT             = 1133;       ///\n    }\n    else version (PPC)\n    {\n        enum EDEADLK            = 35;         ///\n        enum ENAMETOOLONG       = 36;         ///\n        enum ENOLCK             = 37;         ///\n        enum ENOSYS             = 38;         ///\n        enum ENOTEMPTY          = 39;         ///\n        enum ELOOP              = 40;         ///\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum ENOMSG             = 42;         ///\n        enum EIDRM              = 43;         ///\n        enum ECHRNG             = 44;         ///\n        enum EL2NSYNC           = 45;         ///\n        enum EL3HLT             = 46;         ///\n        enum EL3RST             = 47;         ///\n        enum ELNRNG             = 48;         ///\n        enum EUNATCH            = 49;         ///\n        enum ENOCSI             = 50;         ///\n        enum EL2HLT             = 51;         ///\n        enum EBADE              = 52;         ///\n        enum EBADR              = 53;         ///\n        enum EXFULL             = 54;         ///\n        enum ENOANO             = 55;         ///\n        enum EBADRQC            = 56;         ///\n        enum EBADSLT            = 57;         ///\n        enum EDEADLOCK          = 58;         ///\n        enum EBFONT             = 59;         ///\n        enum ENOSTR             = 60;         ///\n        enum ENODATA            = 61;         ///\n        enum ETIME              = 62;         ///\n        enum ENOSR              = 63;         ///\n        enum ENONET             = 64;         ///\n        enum ENOPKG             = 65;         ///\n        enum EREMOTE            = 66;         ///\n        enum ENOLINK            = 67;         ///\n        enum EADV               = 68;         ///\n        enum ESRMNT             = 69;         ///\n        enum ECOMM              = 70;         ///\n        enum EPROTO             = 71;         ///\n        enum EMULTIHOP          = 72;         ///\n        enum EDOTDOT            = 73;         ///\n        enum EBADMSG            = 74;         ///\n        enum EOVERFLOW          = 75;         ///\n        enum ENOTUNIQ           = 76;         ///\n        enum EBADFD             = 77;         ///\n        enum EREMCHG            = 78;         ///\n        enum ELIBACC            = 79;         ///\n        enum ELIBBAD            = 80;         ///\n        enum ELIBSCN            = 81;         ///\n        enum ELIBMAX            = 82;         ///\n        enum ELIBEXEC           = 83;         ///\n        enum EILSEQ             = 84;         ///\n        enum ERESTART           = 85;         ///\n        enum ESTRPIPE           = 86;         ///\n        enum EUSERS             = 87;         ///\n        enum ENOTSOCK           = 88;         ///\n        enum EDESTADDRREQ       = 89;         ///\n        enum EMSGSIZE           = 90;         ///\n        enum EPROTOTYPE         = 91;         ///\n        enum ENOPROTOOPT        = 92;         ///\n        enum EPROTONOSUPPORT    = 93;         ///\n        enum ESOCKTNOSUPPORT    = 94;         ///\n        enum EOPNOTSUPP         = 95;         ///\n        enum ENOTSUP            = EOPNOTSUPP; ///\n        enum EPFNOSUPPORT       = 96;         ///\n        enum EAFNOSUPPORT       = 97;         ///\n        enum EADDRINUSE         = 98;         ///\n        enum EADDRNOTAVAIL      = 99;         ///\n        enum ENETDOWN           = 100;        ///\n        enum ENETUNREACH        = 101;        ///\n        enum ENETRESET          = 102;        ///\n        enum ECONNABORTED       = 103;        ///\n        enum ECONNRESET         = 104;        ///\n        enum ENOBUFS            = 105;        ///\n        enum EISCONN            = 106;        ///\n        enum ENOTCONN           = 107;        ///\n        enum ESHUTDOWN          = 108;        ///\n        enum ETOOMANYREFS       = 109;        ///\n        enum ETIMEDOUT          = 110;        ///\n        enum ECONNREFUSED       = 111;        ///\n        enum EHOSTDOWN          = 112;        ///\n        enum EHOSTUNREACH       = 113;        ///\n        enum EALREADY           = 114;        ///\n        enum EINPROGRESS        = 115;        ///\n        enum ESTALE             = 116;        ///\n        enum EUCLEAN            = 117;        ///\n        enum ENOTNAM            = 118;        ///\n        enum ENAVAIL            = 119;        ///\n        enum EISNAM             = 120;        ///\n        enum EREMOTEIO          = 121;        ///\n        enum EDQUOT             = 122;        ///\n        enum ENOMEDIUM          = 123;        ///\n        enum EMEDIUMTYPE        = 124;        ///\n        enum ECANCELED          = 125;        ///\n        enum ENOKEY             = 126;        ///\n        enum EKEYEXPIRED        = 127;        ///\n        enum EKEYREVOKED        = 128;        ///\n        enum EKEYREJECTED       = 129;        ///\n        enum EOWNERDEAD         = 130;        ///\n        enum ENOTRECOVERABLE    = 131;        ///\n        enum ERFKILL            = 132;        ///\n        enum EHWPOISON          = 133;        ///\n    }\n    else version (PPC64)\n    {\n        enum EDEADLK            = 35;         ///\n        enum ENAMETOOLONG       = 36;         ///\n        enum ENOLCK             = 37;         ///\n        enum ENOSYS             = 38;         ///\n        enum ENOTEMPTY          = 39;         ///\n        enum ELOOP              = 40;         ///\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum ENOMSG             = 42;         ///\n        enum EIDRM              = 43;         ///\n        enum ECHRNG             = 44;         ///\n        enum EL2NSYNC           = 45;         ///\n        enum EL3HLT             = 46;         ///\n        enum EL3RST             = 47;         ///\n        enum ELNRNG             = 48;         ///\n        enum EUNATCH            = 49;         ///\n        enum ENOCSI             = 50;         ///\n        enum EL2HLT             = 51;         ///\n        enum EBADE              = 52;         ///\n        enum EBADR              = 53;         ///\n        enum EXFULL             = 54;         ///\n        enum ENOANO             = 55;         ///\n        enum EBADRQC            = 56;         ///\n        enum EBADSLT            = 57;         ///\n        enum EDEADLOCK          = 58;         ///\n        enum EBFONT             = 59;         ///\n        enum ENOSTR             = 60;         ///\n        enum ENODATA            = 61;         ///\n        enum ETIME              = 62;         ///\n        enum ENOSR              = 63;         ///\n        enum ENONET             = 64;         ///\n        enum ENOPKG             = 65;         ///\n        enum EREMOTE            = 66;         ///\n        enum ENOLINK            = 67;         ///\n        enum EADV               = 68;         ///\n        enum ESRMNT             = 69;         ///\n        enum ECOMM              = 70;         ///\n        enum EPROTO             = 71;         ///\n        enum EMULTIHOP          = 72;         ///\n        enum EDOTDOT            = 73;         ///\n        enum EBADMSG            = 74;         ///\n        enum EOVERFLOW          = 75;         ///\n        enum ENOTUNIQ           = 76;         ///\n        enum EBADFD             = 77;         ///\n        enum EREMCHG            = 78;         ///\n        enum ELIBACC            = 79;         ///\n        enum ELIBBAD            = 80;         ///\n        enum ELIBSCN            = 81;         ///\n        enum ELIBMAX            = 82;         ///\n        enum ELIBEXEC           = 83;         ///\n        enum EILSEQ             = 84;         ///\n        enum ERESTART           = 85;         ///\n        enum ESTRPIPE           = 86;         ///\n        enum EUSERS             = 87;         ///\n        enum ENOTSOCK           = 88;         ///\n        enum EDESTADDRREQ       = 89;         ///\n        enum EMSGSIZE           = 90;         ///\n        enum EPROTOTYPE         = 91;         ///\n        enum ENOPROTOOPT        = 92;         ///\n        enum EPROTONOSUPPORT    = 93;         ///\n        enum ESOCKTNOSUPPORT    = 94;         ///\n        enum EOPNOTSUPP         = 95;         ///\n        enum ENOTSUP            = EOPNOTSUPP; ///\n        enum EPFNOSUPPORT       = 96;         ///\n        enum EAFNOSUPPORT       = 97;         ///\n        enum EADDRINUSE         = 98;         ///\n        enum EADDRNOTAVAIL      = 99;         ///\n        enum ENETDOWN           = 100;        ///\n        enum ENETUNREACH        = 101;        ///\n        enum ENETRESET          = 102;        ///\n        enum ECONNABORTED       = 103;        ///\n        enum ECONNRESET         = 104;        ///\n        enum ENOBUFS            = 105;        ///\n        enum EISCONN            = 106;        ///\n        enum ENOTCONN           = 107;        ///\n        enum ESHUTDOWN          = 108;        ///\n        enum ETOOMANYREFS       = 109;        ///\n        enum ETIMEDOUT          = 110;        ///\n        enum ECONNREFUSED       = 111;        ///\n        enum EHOSTDOWN          = 112;        ///\n        enum EHOSTUNREACH       = 113;        ///\n        enum EALREADY           = 114;        ///\n        enum EINPROGRESS        = 115;        ///\n        enum ESTALE             = 116;        ///\n        enum EUCLEAN            = 117;        ///\n        enum ENOTNAM            = 118;        ///\n        enum ENAVAIL            = 119;        ///\n        enum EISNAM             = 120;        ///\n        enum EREMOTEIO          = 121;        ///\n        enum EDQUOT             = 122;        ///\n        enum ENOMEDIUM          = 123;        ///\n        enum EMEDIUMTYPE        = 124;        ///\n        enum ECANCELED          = 125;        ///\n        enum ENOKEY             = 126;        ///\n        enum EKEYEXPIRED        = 127;        ///\n        enum EKEYREVOKED        = 128;        ///\n        enum EKEYREJECTED       = 129;        ///\n        enum EOWNERDEAD         = 130;        ///\n        enum ENOTRECOVERABLE    = 131;        ///\n        enum ERFKILL            = 132;        ///\n        enum EHWPOISON          = 133;        ///\n    }\n    else version (RISCV32)\n    {\n        enum EDEADLK            = 35;         ///\n        enum ENAMETOOLONG       = 36;         ///\n        enum ENOLCK             = 37;         ///\n        enum ENOSYS             = 38;         ///\n        enum ENOTEMPTY          = 39;         ///\n        enum ELOOP              = 40;         ///\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum ENOMSG             = 42;         ///\n        enum EIDRM              = 43;         ///\n        enum ECHRNG             = 44;         ///\n        enum EL2NSYNC           = 45;         ///\n        enum EL3HLT             = 46;         ///\n        enum EL3RST             = 47;         ///\n        enum ELNRNG             = 48;         ///\n        enum EUNATCH            = 49;         ///\n        enum ENOCSI             = 50;         ///\n        enum EL2HLT             = 51;         ///\n        enum EBADE              = 52;         ///\n        enum EBADR              = 53;         ///\n        enum EXFULL             = 54;         ///\n        enum ENOANO             = 55;         ///\n        enum EBADRQC            = 56;         ///\n        enum EBADSLT            = 57;         ///\n        enum EDEADLOCK          = EDEADLK;    ///\n        enum EBFONT             = 59;         ///\n        enum ENOSTR             = 60;         ///\n        enum ENODATA            = 61;         ///\n        enum ETIME              = 62;         ///\n        enum ENOSR              = 63;         ///\n        enum ENONET             = 64;         ///\n        enum ENOPKG             = 65;         ///\n        enum EREMOTE            = 66;         ///\n        enum ENOLINK            = 67;         ///\n        enum EADV               = 68;         ///\n        enum ESRMNT             = 69;         ///\n        enum ECOMM              = 70;         ///\n        enum EPROTO             = 71;         ///\n        enum EMULTIHOP          = 72;         ///\n        enum EDOTDOT            = 73;         ///\n        enum EBADMSG            = 74;         ///\n        enum EOVERFLOW          = 75;         ///\n        enum ENOTUNIQ           = 76;         ///\n        enum EBADFD             = 77;         ///\n        enum EREMCHG            = 78;         ///\n        enum ELIBACC            = 79;         ///\n        enum ELIBBAD            = 80;         ///\n        enum ELIBSCN            = 81;         ///\n        enum ELIBMAX            = 82;         ///\n        enum ELIBEXEC           = 83;         ///\n        enum EILSEQ             = 84;         ///\n        enum ERESTART           = 85;         ///\n        enum ESTRPIPE           = 86;         ///\n        enum EUSERS             = 87;         ///\n        enum ENOTSOCK           = 88;         ///\n        enum EDESTADDRREQ       = 89;         ///\n        enum EMSGSIZE           = 90;         ///\n        enum EPROTOTYPE         = 91;         ///\n        enum ENOPROTOOPT        = 92;         ///\n        enum EPROTONOSUPPORT    = 93;         ///\n        enum ESOCKTNOSUPPORT    = 94;         ///\n        enum EOPNOTSUPP         = 95;         ///\n        enum EPFNOSUPPORT       = 96;         ///\n        enum EAFNOSUPPORT       = 97;         ///\n        enum EADDRINUSE         = 98;         ///\n        enum EADDRNOTAVAIL      = 99;         ///\n        enum ENETDOWN           = 100;        ///\n        enum ENETUNREACH        = 101;        ///\n        enum ENETRESET          = 102;        ///\n        enum ECONNABORTED       = 103;        ///\n        enum ECONNRESET         = 104;        ///\n        enum ENOBUFS            = 105;        ///\n        enum EISCONN            = 106;        ///\n        enum ENOTCONN           = 107;        ///\n        enum ESHUTDOWN          = 108;        ///\n        enum ETOOMANYREFS       = 109;        ///\n        enum ETIMEDOUT          = 110;        ///\n        enum ECONNREFUSED       = 111;        ///\n        enum EHOSTDOWN          = 112;        ///\n        enum EHOSTUNREACH       = 113;        ///\n        enum EALREADY           = 114;        ///\n        enum EINPROGRESS        = 115;        ///\n        enum ESTALE             = 116;        ///\n        enum EUCLEAN            = 117;        ///\n        enum ENOTNAM            = 118;        ///\n        enum ENAVAIL            = 119;        ///\n        enum EISNAM             = 120;        ///\n        enum EREMOTEIO          = 121;        ///\n        enum EDQUOT             = 122;        ///\n        enum ENOMEDIUM          = 123;        ///\n        enum EMEDIUMTYPE        = 124;        ///\n        enum ECANCELED          = 125;        ///\n        enum ENOKEY             = 126;        ///\n        enum EKEYEXPIRED        = 127;        ///\n        enum EKEYREVOKED        = 128;        ///\n        enum EKEYREJECTED       = 129;        ///\n        enum EOWNERDEAD         = 130;        ///\n        enum ENOTRECOVERABLE    = 131;        ///\n        enum ERFKILL            = 132;        ///\n        enum EHWPOISON          = 133;        ///\n    }\n    else version (RISCV64)\n    {\n        enum EDEADLK            = 35;         ///\n        enum ENAMETOOLONG       = 36;         ///\n        enum ENOLCK             = 37;         ///\n        enum ENOSYS             = 38;         ///\n        enum ENOTEMPTY          = 39;         ///\n        enum ELOOP              = 40;         ///\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum ENOMSG             = 42;         ///\n        enum EIDRM              = 43;         ///\n        enum ECHRNG             = 44;         ///\n        enum EL2NSYNC           = 45;         ///\n        enum EL3HLT             = 46;         ///\n        enum EL3RST             = 47;         ///\n        enum ELNRNG             = 48;         ///\n        enum EUNATCH            = 49;         ///\n        enum ENOCSI             = 50;         ///\n        enum EL2HLT             = 51;         ///\n        enum EBADE              = 52;         ///\n        enum EBADR              = 53;         ///\n        enum EXFULL             = 54;         ///\n        enum ENOANO             = 55;         ///\n        enum EBADRQC            = 56;         ///\n        enum EBADSLT            = 57;         ///\n        enum EDEADLOCK          = EDEADLK;    ///\n        enum EBFONT             = 59;         ///\n        enum ENOSTR             = 60;         ///\n        enum ENODATA            = 61;         ///\n        enum ETIME              = 62;         ///\n        enum ENOSR              = 63;         ///\n        enum ENONET             = 64;         ///\n        enum ENOPKG             = 65;         ///\n        enum EREMOTE            = 66;         ///\n        enum ENOLINK            = 67;         ///\n        enum EADV               = 68;         ///\n        enum ESRMNT             = 69;         ///\n        enum ECOMM              = 70;         ///\n        enum EPROTO             = 71;         ///\n        enum EMULTIHOP          = 72;         ///\n        enum EDOTDOT            = 73;         ///\n        enum EBADMSG            = 74;         ///\n        enum EOVERFLOW          = 75;         ///\n        enum ENOTUNIQ           = 76;         ///\n        enum EBADFD             = 77;         ///\n        enum EREMCHG            = 78;         ///\n        enum ELIBACC            = 79;         ///\n        enum ELIBBAD            = 80;         ///\n        enum ELIBSCN            = 81;         ///\n        enum ELIBMAX            = 82;         ///\n        enum ELIBEXEC           = 83;         ///\n        enum EILSEQ             = 84;         ///\n        enum ERESTART           = 85;         ///\n        enum ESTRPIPE           = 86;         ///\n        enum EUSERS             = 87;         ///\n        enum ENOTSOCK           = 88;         ///\n        enum EDESTADDRREQ       = 89;         ///\n        enum EMSGSIZE           = 90;         ///\n        enum EPROTOTYPE         = 91;         ///\n        enum ENOPROTOOPT        = 92;         ///\n        enum EPROTONOSUPPORT    = 93;         ///\n        enum ESOCKTNOSUPPORT    = 94;         ///\n        enum EOPNOTSUPP         = 95;         ///\n        enum EPFNOSUPPORT       = 96;         ///\n        enum EAFNOSUPPORT       = 97;         ///\n        enum EADDRINUSE         = 98;         ///\n        enum EADDRNOTAVAIL      = 99;         ///\n        enum ENETDOWN           = 100;        ///\n        enum ENETUNREACH        = 101;        ///\n        enum ENETRESET          = 102;        ///\n        enum ECONNABORTED       = 103;        ///\n        enum ECONNRESET         = 104;        ///\n        enum ENOBUFS            = 105;        ///\n        enum EISCONN            = 106;        ///\n        enum ENOTCONN           = 107;        ///\n        enum ESHUTDOWN          = 108;        ///\n        enum ETOOMANYREFS       = 109;        ///\n        enum ETIMEDOUT          = 110;        ///\n        enum ECONNREFUSED       = 111;        ///\n        enum EHOSTDOWN          = 112;        ///\n        enum EHOSTUNREACH       = 113;        ///\n        enum EALREADY           = 114;        ///\n        enum EINPROGRESS        = 115;        ///\n        enum ESTALE             = 116;        ///\n        enum EUCLEAN            = 117;        ///\n        enum ENOTNAM            = 118;        ///\n        enum ENAVAIL            = 119;        ///\n        enum EISNAM             = 120;        ///\n        enum EREMOTEIO          = 121;        ///\n        enum EDQUOT             = 122;        ///\n        enum ENOMEDIUM          = 123;        ///\n        enum EMEDIUMTYPE        = 124;        ///\n        enum ECANCELED          = 125;        ///\n        enum ENOKEY             = 126;        ///\n        enum EKEYEXPIRED        = 127;        ///\n        enum EKEYREVOKED        = 128;        ///\n        enum EKEYREJECTED       = 129;        ///\n        enum EOWNERDEAD         = 130;        ///\n        enum ENOTRECOVERABLE    = 131;        ///\n        enum ERFKILL            = 132;        ///\n        enum EHWPOISON          = 133;        ///\n    }\n    else version (SPARC64)\n    {\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum EINPROGRESS        = 36;         ///\n        enum EALREADY           = 37;         ///\n        enum ENOTSOCK           = 38;         ///\n        enum EDESTADDRREQ       = 39;         ///\n        enum EMSGSIZE           = 40;         ///\n        enum EPROTOTYPE         = 41;         ///\n        enum ENOPROTOOPT        = 42;         ///\n        enum EPROTONOSUPPORT    = 43;         ///\n        enum ESOCKTNOSUPPORT    = 44;         ///\n        enum EOPNOTSUPP         = 45;         ///\n        enum ENOTSUP            = EOPNOTSUPP; ///\n        enum EPFNOSUPPORT       = 46;         ///\n        enum EAFNOSUPPORT       = 47;         ///\n        enum EADDRINUSE         = 48;         ///\n        enum EADDRNOTAVAIL      = 49;         ///\n        enum ENETDOWN           = 50;         ///\n        enum ENETUNREACH        = 51;         ///\n        enum ENETRESET          = 52;         ///\n        enum ECONNABORTED       = 53;         ///\n        enum ECONNRESET         = 54;         ///\n        enum ENOBUFS            = 55;         ///\n        enum EISCONN            = 56;         ///\n        enum ENOTCONN           = 57;         ///\n        enum ESHUTDOWN          = 58;         ///\n        enum ETOOMANYREFS       = 59;         ///\n        enum ETIMEDOUT          = 60;         ///\n        enum ECONNREFUSED       = 61;         ///\n        enum ELOOP              = 62;         ///\n        enum ENAMETOOLONG       = 63;         ///\n        enum EHOSTDOWN          = 64;         ///\n        enum EHOSTUNREACH       = 65;         ///\n        enum ENOTEMPTY          = 66;         ///\n        enum EPROCLIM           = 67;         ///\n        enum EUSERS             = 68;         ///\n        enum EDQUOT             = 69;         ///\n        enum ESTALE             = 70;         ///\n        enum EREMOTE            = 71;         ///\n        enum ENOSTR             = 72;         ///\n        enum ETIME              = 73;         ///\n        enum ENOSR              = 74;         ///\n        enum ENOMSG             = 75;         ///\n        enum EBADMSG            = 76;         ///\n        enum EIDRM              = 77;         ///\n        enum EDEADLK            = 78;         ///\n        enum ENOLCK             = 79;         ///\n        enum ENONET             = 80;         ///\n        enum ERREMOTE           = 81;         ///\n        enum ENOLINK            = 82;         ///\n        enum EADV               = 83;         ///\n        enum ESRMNT             = 84;         ///\n        enum ECOMM              = 85;         ///\n        enum EPROTO             = 86;         ///\n        enum EMULTIHOP          = 87;         ///\n        enum EDOTDOT            = 88;         ///\n        enum EREMCHG            = 89;         ///\n        enum ENOSYS             = 90;         ///\n        enum ESTRPIPE           = 91;         ///\n        enum EOVERFLOW          = 92;         ///\n        enum EBADFD             = 93;         ///\n        enum ECHRNG             = 94;         ///\n        enum EL2NSYNC           = 95;         ///\n        enum EL3HLT             = 96;         ///\n        enum EL3RST             = 97;         ///\n        enum ELNRNG             = 98;         ///\n        enum EUNATCH            = 99;         ///\n        enum ENOCSI             = 100;        ///\n        enum EL2HLT             = 101;        ///\n        enum EBADE              = 102;        ///\n        enum EBADR              = 103;        ///\n        enum EXFULL             = 104;        ///\n        enum ENOANO             = 105;        ///\n        enum EBADRQC            = 106;        ///\n        enum EBADSLT            = 107;        ///\n        enum EDEADLOCK          = 108;        ///\n        enum EBFONT             = 109;        ///\n        enum ELIBEXEC           = 110;        ///\n        enum ENODATA            = 111;        ///\n        enum ELIBBAD            = 112;        ///\n        enum ENOPKG             = 113;        ///\n        enum ELIBACC            = 114;        ///\n        enum ENOTUNIQ           = 115;        ///\n        enum ERESTART           = 116;        ///\n        enum EUCLEAN            = 117;        ///\n        enum ENOTNAM            = 118;        ///\n        enum ENAVAIL            = 119;        ///\n        enum EISNAM             = 120;        ///\n        enum EREMOTEIO          = 121;        ///\n        enum EILSEQ             = 122;        ///\n        enum ELIBMAX            = 123;        ///\n        enum ELIBSCN            = 124;        ///\n        enum ENOMEDIUM          = 125;        ///\n        enum EMEDIUMTYPE        = 126;        ///\n        enum ECANCELED          = 127;        ///\n        enum ENOKEY             = 128;        ///\n        enum EKEYEXPIRED        = 129;        ///\n        enum EKEYREVOKED        = 130;        ///\n        enum EKEYREJECTED       = 131;        ///\n        enum EOWNERDEAD         = 132;        ///\n        enum ENOTRECOVERABLE    = 133;        ///\n        enum ERFKILL            = 134;        ///\n        enum EHWPOISON          = 135;        ///\n    }\n    else version (SystemZ)\n    {\n        enum EDEADLK            = 35;         ///\n        enum ENAMETOOLONG       = 36;         ///\n        enum ENOLCK             = 37;         ///\n        enum ENOSYS             = 38;         ///\n        enum ENOTEMPTY          = 39;         ///\n        enum ELOOP              = 40;         ///\n        enum EWOULDBLOCK        = EAGAIN;     ///\n        enum ENOMSG             = 42;         ///\n        enum EIDRM              = 43;         ///\n        enum ECHRNG             = 44;         ///\n        enum EL2NSYNC           = 45;         ///\n        enum EL3HLT             = 46;         ///\n        enum EL3RST             = 47;         ///\n        enum ELNRNG             = 48;         ///\n        enum EUNATCH            = 49;         ///\n        enum ENOCSI             = 50;         ///\n        enum EL2HLT             = 51;         ///\n        enum EBADE              = 52;         ///\n        enum EBADR              = 53;         ///\n        enum EXFULL             = 54;         ///\n        enum ENOANO             = 55;         ///\n        enum EBADRQC            = 56;         ///\n        enum EBADSLT            = 57;         ///\n        enum EDEADLOCK          = EDEADLK;    ///\n        enum EBFONT             = 59;         ///\n        enum ENOSTR             = 60;         ///\n        enum ENODATA            = 61;         ///\n        enum ETIME              = 62;         ///\n        enum ENOSR              = 63;         ///\n        enum ENONET             = 64;         ///\n        enum ENOPKG             = 65;         ///\n        enum EREMOTE            = 66;         ///\n        enum ENOLINK            = 67;         ///\n        enum EADV               = 68;         ///\n        enum ESRMNT             = 69;         ///\n        enum ECOMM              = 70;         ///\n        enum EPROTO             = 71;         ///\n        enum EMULTIHOP          = 72;         ///\n        enum EDOTDOT            = 73;         ///\n        enum EBADMSG            = 74;         ///\n        enum EOVERFLOW          = 75;         ///\n        enum ENOTUNIQ           = 76;         ///\n        enum EBADFD             = 77;         ///\n        enum EREMCHG            = 78;         ///\n        enum ELIBACC            = 79;         ///\n        enum ELIBBAD            = 80;         ///\n        enum ELIBSCN            = 81;         ///\n        enum ELIBMAX            = 82;         ///\n        enum ELIBEXEC           = 83;         ///\n        enum EILSEQ             = 84;         ///\n        enum ERESTART           = 85;         ///\n        enum ESTRPIPE           = 86;         ///\n        enum EUSERS             = 87;         ///\n        enum ENOTSOCK           = 88;         ///\n        enum EDESTADDRREQ       = 89;         ///\n        enum EMSGSIZE           = 90;         ///\n        enum EPROTOTYPE         = 91;         ///\n        enum ENOPROTOOPT        = 92;         ///\n        enum EPROTONOSUPPORT    = 93;         ///\n        enum ESOCKTNOSUPPORT    = 94;         ///\n        enum EOPNOTSUPP         = 95;         ///\n        enum ENOTSUP            = EOPNOTSUPP; ///\n        enum EPFNOSUPPORT       = 96;         ///\n        enum EAFNOSUPPORT       = 97;         ///\n        enum EADDRINUSE         = 98;         ///\n        enum EADDRNOTAVAIL      = 99;         ///\n        enum ENETDOWN           = 100;        ///\n        enum ENETUNREACH        = 101;        ///\n        enum ENETRESET          = 102;        ///\n        enum ECONNABORTED       = 103;        ///\n        enum ECONNRESET         = 104;        ///\n        enum ENOBUFS            = 105;        ///\n        enum EISCONN            = 106;        ///\n        enum ENOTCONN           = 107;        ///\n        enum ESHUTDOWN          = 108;        ///\n        enum ETOOMANYREFS       = 109;        ///\n        enum ETIMEDOUT          = 110;        ///\n        enum ECONNREFUSED       = 111;        ///\n        enum EHOSTDOWN          = 112;        ///\n        enum EHOSTUNREACH       = 113;        ///\n        enum EALREADY           = 114;        ///\n        enum EINPROGRESS        = 115;        ///\n        enum ESTALE             = 116;        ///\n        enum EUCLEAN            = 117;        ///\n        enum ENOTNAM            = 118;        ///\n        enum ENAVAIL            = 119;        ///\n        enum EISNAM             = 120;        ///\n        enum EREMOTEIO          = 121;        ///\n        enum EDQUOT             = 122;        ///\n        enum ENOMEDIUM          = 123;        ///\n        enum EMEDIUMTYPE        = 124;        ///\n        enum ECANCELED          = 125;        ///\n        enum ENOKEY             = 126;        ///\n        enum EKEYEXPIRED        = 127;        ///\n        enum EKEYREVOKED        = 128;        ///\n        enum EKEYREJECTED       = 129;        ///\n        enum EOWNERDEAD         = 130;        ///\n        enum ENOTRECOVERABLE    = 131;        ///\n        enum ERFKILL            = 132;        ///\n        enum EHWPOISON          = 133;        ///\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n}\nelse version (Darwin)\n{\n    enum EPERM              = 1;        /// Operation not permitted\n    enum ENOENT             = 2;        /// No such file or directory\n    enum ESRCH              = 3;        /// No such process\n    enum EINTR              = 4;        /// Interrupted system call\n    enum EIO                = 5;        /// Input/output error\n    enum ENXIO              = 6;        /// Device not configured\n    enum E2BIG              = 7;        /// Argument list too long\n    enum ENOEXEC            = 8;        /// Exec format error\n    enum EBADF              = 9;        /// Bad file descriptor\n    enum ECHILD             = 10;       /// No child processes\n    enum EDEADLK            = 11;       /// Resource deadlock avoided\n    enum ENOMEM             = 12;       /// Cannot allocate memory\n    enum EACCES             = 13;       /// Permission denied\n    enum EFAULT             = 14;       /// Bad address\n    enum EBUSY              = 16;       /// Device busy\n    enum EEXIST             = 17;       /// File exists\n    enum EXDEV              = 18;       /// Cross-device link\n    enum ENODEV             = 19;       /// Operation not supported by device\n    enum ENOTDIR            = 20;       /// Not a directory\n    enum EISDIR             = 21;       /// Is a directory\n    enum EINVAL             = 22;       /// Invalid argument\n    enum ENFILE             = 23;       /// Too many open files in system\n    enum EMFILE             = 24;       /// Too many open files\n    enum ENOTTY             = 25;       /// Inappropriate ioctl for device\n    enum ETXTBSY            = 26;       /// Text file busy\n    enum EFBIG              = 27;       /// File too large\n    enum ENOSPC             = 28;       /// No space left on device\n    enum ESPIPE             = 29;       /// Illegal seek\n    enum EROFS              = 30;       /// Read-only file system\n    enum EMLINK             = 31;       /// Too many links\n    enum EPIPE              = 32;       /// Broken pipe\n    enum EDOM               = 33;       /// Numerical argument out of domain\n    enum ERANGE             = 34;       /// Result too large\n    enum EAGAIN             = 35;       /// Resource temporarily unavailable\n    enum EWOULDBLOCK        = EAGAIN;   /// Operation would block\n    enum EINPROGRESS        = 36;       /// Operation now in progress\n    enum EALREADY           = 37;       /// Operation already in progress\n    enum ENOTSOCK           = 38;       /// Socket operation on non-socket\n    enum EDESTADDRREQ       = 39;       /// Destination address required\n    enum EMSGSIZE           = 40;       /// Message too long\n    enum EPROTOTYPE         = 41;       /// Protocol wrong type for socket\n    enum ENOPROTOOPT        = 42;       /// Protocol not available\n    enum EPROTONOSUPPORT    = 43;       /// Protocol not supported\n    enum ENOTSUP            = 45;       /// Operation not supported\n    enum EOPNOTSUPP         = ENOTSUP;  /// Operation not supported on socket\n    enum EAFNOSUPPORT       = 47;       /// Address family not supported by protocol family\n    enum EADDRINUSE         = 48;       /// Address already in use\n    enum EADDRNOTAVAIL      = 49;       /// Can't assign requested address\n    enum ENETDOWN           = 50;       /// Network is down\n    enum ENETUNREACH        = 51;       /// Network is unreachable\n    enum ENETRESET          = 52;       /// Network dropped connection on reset\n    enum ECONNABORTED       = 53;       /// Software caused connection abort\n    enum ECONNRESET         = 54;       /// Connection reset by peer\n    enum ENOBUFS            = 55;       /// No buffer space available\n    enum EISCONN            = 56;       /// Socket is already connected\n    enum ENOTCONN           = 57;       /// Socket is not connected\n    enum ETIMEDOUT          = 60;       /// Operation timed out\n    enum ECONNREFUSED       = 61;       /// Connection refused\n    enum ELOOP              = 62;       /// Too many levels of symbolic links\n    enum ENAMETOOLONG       = 63;       /// File name too long\n    enum EHOSTUNREACH       = 65;       /// No route to host\n    enum ENOTEMPTY          = 66;       /// Directory not empty\n    enum EDQUOT             = 69;       /// Disc quota exceeded\n    enum ESTALE             = 70;       /// Stale NFS file handle\n    enum ENOLCK             = 77;       /// No locks available\n    enum ENOSYS             = 78;       /// Function not implemented\n    enum EOVERFLOW          = 84;       /// Value too large to be stored in data type\n    enum ECANCELED          = 89;       /// Operation canceled\n    enum EIDRM              = 90;       /// Identifier removed\n    enum ENOMSG             = 91;       /// No message of desired type\n    enum EILSEQ             = 92;       /// Illegal byte sequence\n    enum EBADMSG            = 94;       /// Bad message\n    enum EMULTIHOP          = 95;       /// Reserved\n    enum ENODATA            = 96;       /// No message available on STREAM\n    enum ENOLINK            = 97;       /// Reserved\n    enum ENOSR              = 98;       /// No STREAM resources\n    enum ENOSTR             = 99;       /// Not a STREAM\n    enum EPROTO             = 100;      /// Protocol error\n    enum ETIME              = 101;      /// STREAM ioctl timeout\n    enum ELAST              = 101;      /// Must be equal largest errno\n}\nelse version (FreeBSD)\n{\n    enum EPERM              = 1;        /// Operation not permitted\n    enum ENOENT             = 2;        /// No such file or directory\n    enum ESRCH              = 3;        /// No such process\n    enum EINTR              = 4;        /// Interrupted system call\n    enum EIO                = 5;        /// Input/output error\n    enum ENXIO              = 6;        /// Device not configured\n    enum E2BIG              = 7;        /// Argument list too long\n    enum ENOEXEC            = 8;        /// Exec format error\n    enum EBADF              = 9;        /// Bad file descriptor\n    enum ECHILD             = 10;       /// No child processes\n    enum EDEADLK            = 11;       /// Resource deadlock avoided\n    enum ENOMEM             = 12;       /// Cannot allocate memory\n    enum EACCES             = 13;       /// Permission denied\n    enum EFAULT             = 14;       /// Bad address\n    enum ENOTBLK            = 15;       /// Block device required\n    enum EBUSY              = 16;       /// Device busy\n    enum EEXIST             = 17;       /// File exists\n    enum EXDEV              = 18;       /// Cross-device link\n    enum ENODEV             = 19;       /// Operation not supported by device\n    enum ENOTDIR            = 20;       /// Not a directory\n    enum EISDIR             = 21;       /// Is a directory\n    enum EINVAL             = 22;       /// Invalid argument\n    enum ENFILE             = 23;       /// Too many open files in system\n    enum EMFILE             = 24;       /// Too many open files\n    enum ENOTTY             = 25;       /// Inappropriate ioctl for device\n    enum ETXTBSY            = 26;       /// Text file busy\n    enum EFBIG              = 27;       /// File too large\n    enum ENOSPC             = 28;       /// No space left on device\n    enum ESPIPE             = 29;       /// Illegal seek\n    enum EROFS              = 30;       /// Read-only file system\n    enum EMLINK             = 31;       /// Too many links\n    enum EPIPE              = 32;       /// Broken pipe\n    enum EDOM               = 33;       /// Numerical argument out of domain\n    enum ERANGE             = 34;       /// Result too large\n    enum EAGAIN             = 35;       /// Resource temporarily unavailable\n    enum EWOULDBLOCK        = EAGAIN;   /// Operation would block\n    enum EINPROGRESS        = 36;       /// Operation now in progress\n    enum EALREADY           = 37;       /// Operation already in progress\n    enum ENOTSOCK           = 38;       /// Socket operation on non-socket\n    enum EDESTADDRREQ       = 39;       /// Destination address required\n    enum EMSGSIZE           = 40;       /// Message too long\n    enum EPROTOTYPE         = 41;       /// Protocol wrong type for socket\n    enum ENOPROTOOPT        = 42;       /// Protocol not available\n    enum EPROTONOSUPPORT    = 43;       /// Protocol not supported\n    enum ENOTSUP            = 45;       /// Operation not supported\n    enum EOPNOTSUPP         = ENOTSUP;  /// Operation not supported on socket\n    enum EAFNOSUPPORT       = 47;       /// Address family not supported by protocol family\n    enum EADDRINUSE         = 48;       /// Address already in use\n    enum EADDRNOTAVAIL      = 49;       /// Can't assign requested address\n    enum ENETDOWN           = 50;       /// Network is down\n    enum ENETUNREACH        = 51;       /// Network is unreachable\n    enum ENETRESET          = 52;       /// Network dropped connection on reset\n    enum ECONNABORTED       = 53;       /// Software caused connection abort\n    enum ECONNRESET         = 54;       /// Connection reset by peer\n    enum ENOBUFS            = 55;       /// No buffer space available\n    enum EISCONN            = 56;       /// Socket is already connected\n    enum ENOTCONN           = 57;       /// Socket is not connected\n    enum ESHUTDOWN          = 58;       /// Can't send after socket shutdown\n    enum ETOOMANYREFS       = 59;       /// Too many refrences; can't splice\n    enum ETIMEDOUT          = 60;       /// Operation timed out\n    enum ECONNREFUSED       = 61;       /// Connection refused\n    enum ELOOP              = 62;       /// Too many levels of symbolic links\n    enum ENAMETOOLONG       = 63;       /// File name too long\n    enum EHOSTUNREACH       = 65;       /// No route to host\n    enum ENOTEMPTY          = 66;       /// Directory not empty\n    enum EPROCLIM           = 67;       /// Too many processes\n    enum EUSERS             = 68;       /// Too many users\n    enum EDQUOT             = 69;       /// Disc quota exceeded\n    enum ESTALE             = 70;       /// Stale NFS file handle\n    enum EREMOTE            = 71;       /// Too many levels of remote in path\n    enum EBADRPC            = 72;       /// RPC struct is bad\n    enum ERPCMISMATCH       = 73;       /// RPC version wrong\n    enum EPROGUNAVAIL       = 74;       /// RPC prog. not avail\n    enum EPROGMISMATCH      = 75;       /// Program version wrong\n    enum EPROCUNAVAIL       = 76;       /// Bad procedure for program\n    enum ENOLCK             = 77;       /// No locks available\n    enum ENOSYS             = 78;       /// Function not implemented\n    enum EFTYPE             = 79;       /// Inappropriate file type or format\n    enum EAUTH              = 80;       /// Authentication error\n    enum ENEEDAUTH          = 81;       /// Need authenticator\n    enum EIDRM              = 82;       /// Itendifier removed\n    enum ENOMSG             = 83;       /// No message of desired type\n    enum EOVERFLOW          = 84;       /// Value too large to be stored in data type\n    enum ECANCELED          = 85;       /// Operation canceled\n    enum EILSEQ             = 86;       /// Illegal byte sequence\n    enum ENOATTR            = 87;       /// Attribute not found\n    enum EDOOFUS            = 88;       /// Programming error\n    enum EBADMSG            = 89;       /// Bad message\n    enum EMULTIHOP          = 90;       /// Multihop attempted\n    enum ENOLINK            = 91;       /// Link has been severed\n    enum EPROTO             = 92;       /// Protocol error\n    enum ELAST              = 92;       /// Must be equal largest errno\n}\nelse version (NetBSD)\n{\n    // http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/sys/errno.h\n    enum EPERM           = 1;\n    enum ENOENT          = 2;\n    enum ESRCH           = 3;\n    enum EINTR           = 4;\n    enum EIO             = 5;\n    enum ENXIO           = 6;\n    enum E2BIG           = 7;\n    enum ENOEXEC         = 8;\n    enum EBADF           = 9;\n    enum ECHILD          = 10;\n    enum EDEADLK         = 11;\n    ///\n    enum ENOMEM          = 12;\n    enum EACCES          = 13;\n    enum EFAULT          = 14;\n    enum ENOTBLK         = 15;\n    enum EBUSY           = 16;\n    enum EEXIST          = 17;\n    enum EXDEV           = 18;\n    enum ENODEV          = 19;\n    enum ENOTDIR         = 20;\n    enum EISDIR          = 21;\n    enum EINVAL          = 22;\n    enum ENFILE          = 23;\n    enum EMFILE          = 24;\n    enum ENOTTY          = 25;\n    enum ETXTBSY         = 26;\n    enum EFBIG           = 27;\n    enum ENOSPC          = 28;\n    enum ESPIPE          = 29;\n    enum EROFS           = 30;\n    enum EMLINK          = 31;\n    enum EPIPE           = 32;\n    ///\n    enum EDOM            = 33;\n    enum ERANGE          = 34;\n\n    ///\n    enum EAGAIN          = 35;\n    enum EWOULDBLOCK     = EAGAIN;\n    enum EINPROGRESS     = 36;\n    enum EALREADY        = 37;\n\n    ///\n    enum ENOTSOCK        = 38;\n    enum EDESTADDRREQ    = 39;\n    enum EMSGSIZE        = 40;\n    enum EPROTOTYPE      = 41;\n    enum ENOPROTOOPT     = 42;\n    enum EPROTONOSUPPORT = 43;\n    enum ESOCKTNOSUPPORT = 44;\n    enum EOPNOTSUPP      = 45;\n    enum EPFNOSUPPORT    = 46;\n    enum EAFNOSUPPORT    = 47;\n    enum EADDRINUSE      = 48;\n    enum EADDRNOTAVAIL   = 49;\n\n    ///\n    enum ENETDOWN        = 50;\n    enum ENETUNREACH     = 51;\n    enum ENETRESET       = 52;\n    enum ECONNABORTED    = 53;\n    enum ECONNRESET      = 54;\n    enum ENOBUFS         = 55;\n    enum EISCONN         = 56;\n    enum ENOTCONN        = 57;\n    enum ESHUTDOWN       = 58;\n    enum ETOOMANYREFS    = 59;\n    enum ETIMEDOUT       = 60;\n    enum ECONNREFUSED    = 61;\n    enum ELOOP           = 62;\n    enum ENAMETOOLONG    = 63;\n\n    ///\n    enum EHOSTDOWN       = 64;\n    enum EHOSTUNREACH    = 65;\n    enum ENOTEMPTY       = 66;\n\n    ///\n    enum EPROCLIM        = 67;\n    enum EUSERS          = 68;\n    enum EDQUOT          = 69;\n\n    ///\n    enum ESTALE          = 70;\n    enum EREMOTE         = 71;\n    enum EBADRPC         = 72;\n    enum ERPCMISMATCH    = 73;\n    enum EPROGUNAVAIL    = 74;\n    enum EPROGMISMATCH   = 75;\n    enum EPROCUNAVAIL    = 76;\n\n    enum ENOLCK          = 77;\n    enum ENOSYS          = 78;\n\n    enum EFTYPE          = 79;\n    enum EAUTH           = 80;\n    enum ENEEDAUTH       = 81;\n\n    ///\n    enum EIDRM           = 82;\n    enum ENOMSG          = 83;\n    enum EOVERFLOW       = 84;\n    ///\n    enum EILSEQ          = 85;\n\n    ///\n    enum ENOTSUP         = 86;\n\n    ///\n    enum ECANCELED       = 87;\n\n    ///\n    enum EBADMSG         = 88;\n\n    ///\n    enum ENODATA         = 89;\n    enum ENOSR           = 90;\n    enum ENOSTR          = 91;\n    enum ETIME           = 92;\n\n    ///\n    enum ENOATTR         = 93;\n\n    ///\n    enum EMULTIHOP       = 94;\n    enum ENOLINK         = 95;\n    enum EPROTO          = 96;\n}\nelse version (OpenBSD)\n{\n    enum EPERM              = 1;        /// Operation not permitted\n    enum ENOENT             = 2;        /// No such file or directory\n    enum ESRCH              = 3;        /// No such process\n    enum EINTR              = 4;        /// Interrupted system call\n    enum EIO                = 5;        /// Input/output error\n    enum ENXIO              = 6;        /// Device not configured\n    enum E2BIG              = 7;        /// Argument list too long\n    enum ENOEXEC            = 8;        /// Exec format error\n    enum EBADF              = 9;        /// Bad file descriptor\n    enum ECHILD             = 10;       /// No child processes\n    enum EDEADLK            = 11;       /// Resource deadlock avoided\n    enum ENOMEM             = 12;       /// Cannot allocate memory\n    enum EACCES             = 13;       /// Permission denied\n    enum EFAULT             = 14;       /// Bad address\n    enum ENOTBLK            = 15;       /// Block device required\n    enum EBUSY              = 16;       /// Device busy\n    enum EEXIST             = 17;       /// File exists\n    enum EXDEV              = 18;       /// Cross-device link\n    enum ENODEV             = 19;       /// Operation not supported by device\n    enum ENOTDIR            = 20;       /// Not a directory\n    enum EISDIR             = 21;       /// Is a directory\n    enum EINVAL             = 22;       /// Invalid argument\n    enum ENFILE             = 23;       /// Too many open files in system\n    enum EMFILE             = 24;       /// Too many open files\n    enum ENOTTY             = 25;       /// Inappropriate ioctl for device\n    enum ETXTBSY            = 26;       /// Text file busy\n    enum EFBIG              = 27;       /// File too large\n    enum ENOSPC             = 28;       /// No space left on device\n    enum ESPIPE             = 29;       /// Illegal seek\n    enum EROFS              = 30;       /// Read-only file system\n    enum EMLINK             = 31;       /// Too many links\n    enum EPIPE              = 32;       /// Broken pipe\n    enum EDOM               = 33;       /// Numerical argument out of domain\n    enum ERANGE             = 34;       /// Result too large\n    enum EAGAIN             = 35;       /// Resource temporarily unavailable\n    enum EWOULDBLOCK        = EAGAIN;   /// Operation would block\n    enum EINPROGRESS        = 36;       /// Operation now in progress\n    enum EALREADY           = 37;       /// Operation already in progress\n    enum ENOTSOCK           = 38;       /// Socket operation on non-socket\n    enum EDESTADDRREQ       = 39;       /// Destination address required\n    enum EMSGSIZE           = 40;       /// Message too long\n    enum EPROTOTYPE         = 41;       /// Protocol wrong type for socket\n    enum ENOPROTOOPT        = 42;       /// Protocol not available\n    enum EPROTONOSUPPORT    = 43;       /// Protocol not supported\n    enum ESOCKTNOSUPPORT    = 44;       /// Socket type not supported\n    enum EOPNOTSUPP         = 45;       /// Operation not supported\n    enum EPFNOSUPPORT       = 46;       /// Protocol family not supported\n    enum EAFNOSUPPORT       = 47;       /// Address family not supported by protocol family\n    enum EADDRINUSE         = 48;       /// Address already in use\n    enum EADDRNOTAVAIL      = 49;       /// Can't assign requested address\n    enum ENETDOWN           = 50;       /// Network is down\n    enum ENETUNREACH        = 51;       /// Network is unreachable\n    enum ENETRESET          = 52;       /// Network dropped connection on reset\n    enum ECONNABORTED       = 53;       /// Software caused connection abort\n    enum ECONNRESET         = 54;       /// Connection reset by peer\n    enum ENOBUFS            = 55;       /// No buffer space available\n    enum EISCONN            = 56;       /// Socket is already connected\n    enum ENOTCONN           = 57;       /// Socket is not connected\n    enum ESHUTDOWN          = 58;       /// Can't send after socket shutdown\n    enum ETOOMANYREFS       = 59;       /// Too many references: can't splice\n    enum ETIMEDOUT          = 60;       /// Operation timed out\n    enum ECONNREFUSED       = 61;       /// Connection refused\n    enum ELOOP              = 62;       /// Too many levels of symbolic links\n    enum ENAMETOOLONG       = 63;       /// File name too long\n    enum EHOSTDOWN          = 64;       /// Host is down\n    enum EHOSTUNREACH       = 65;       /// No route to host\n    enum ENOTEMPTY          = 66;       /// Directory not empty\n    enum EPROCLIM           = 67;       /// Too many processes\n    enum EUSERS             = 68;       /// Too many users\n    enum EDQUOT             = 69;       /// Disk quota exceeded\n    enum ESTALE             = 70;       /// Stale NFS file handle\n    enum EREMOTE            = 71;       /// Too many levels of remote in path\n    enum EBADRPC            = 72;       /// RPC struct is bad\n    enum ERPCMISMATCH       = 73;       /// RPC version wrong\n    enum EPROGUNAVAIL       = 74;       /// RPC program not available\n    enum EPROGMISMATCH      = 75;       /// Program version wrong\n    enum EPROCUNAVAIL       = 76;       /// Bad procedure for program\n    enum ENOLCK             = 77;       /// No locks available\n    enum ENOSYS             = 78;       /// Function not implemented\n    enum EFTYPE             = 79;       /// Inappropriate file type or format\n    enum EAUTH              = 80;       /// Authentication error\n    enum ENEEDAUTH          = 81;       /// Need authenticator\n    enum EIPSEC             = 82;       /// IPsec processing failure\n    enum ENOATTR            = 83;       /// Attribute not found\n    enum EILSEQ             = 84;       /// Illegal byte sequence\n    enum ENOMEDIUM          = 85;       /// No medium found\n    enum EMEDIUMTYPE        = 86;       /// Wrong medium type\n    enum EOVERFLOW          = 87;       /// Value too large to be stored in data type\n    enum ECANCELED          = 88;       /// Operation canceled\n    enum EIDRM              = 89;       /// Identifier removed\n    enum ENOMSG             = 90;       /// No message of desired type\n    enum ENOTSUP            = 91;       /// Not supported\n    enum ELAST              = 91;       /// Must be equal largest errno\n}\nelse version (DragonFlyBSD)\n{\n    enum EPERM              = 1;\n    enum ENOENT             = 2;\n    enum ESRCH              = 3;\n    enum EINTR              = 4;\n    enum EIO                = 5;\n    enum ENXIO              = 6;\n    enum E2BIG              = 7;\n    enum ENOEXEC            = 8;\n    enum EBADF              = 9;\n    enum ECHILD             = 10;\n    enum EDEADLK            = 11;\n    enum ENOMEM             = 12;\n    enum EACCES             = 13;\n    enum EFAULT             = 14;\n    enum ENOTBLK            = 15;\n    enum EBUSY              = 16;\n    enum EEXIST             = 17;\n    enum EXDEV              = 18;\n    enum ENODEV             = 19;\n    enum ENOTDIR            = 20;\n    enum EISDIR             = 21;\n    enum EINVAL             = 22;\n    enum ENFILE             = 23;\n    enum EMFILE             = 24;\n    enum ENOTTY             = 25;\n    enum ETXTBSY            = 26;\n    enum EFBIG              = 27;\n    enum ENOSPC             = 28;\n    enum ESPIPE             = 29;\n    enum EROFS              = 30;\n    enum EMLINK             = 31;\n    enum EPIPE              = 32;\n    enum EDOM               = 33;\n    enum ERANGE             = 34;\n    enum EAGAIN             = 35;\n    enum EWOULDBLOCK        = EAGAIN;\n    enum EINPROGRESS        = 36;\n    enum EALREADY           = 37;\n    enum ENOTSOCK           = 38;\n    enum EDESTADDRREQ       = 39;\n    enum EMSGSIZE           = 40;\n    enum EPROTOTYPE         = 41;\n    enum ENOPROTOOPT        = 42;\n    enum EPROTONOSUPPORT    = 43;\n    enum ENOTSUP            = 45;\n    enum EOPNOTSUPP         = ENOTSUP;\n    enum EPFNOSUPPORT       = 46;\n    enum EAFNOSUPPORT       = 47;\n    enum EADDRINUSE         = 48;\n    enum EADDRNOTAVAIL      = 49;\n    enum ENETDOWN           = 50;\n    enum ENETUNREACH        = 51;\n    enum ENETRESET          = 52;\n    enum ECONNABORTED       = 53;\n    enum ECONNRESET         = 54;\n    enum ENOBUFS            = 55;\n    enum EISCONN            = 56;\n    enum ENOTCONN           = 57;\n    enum ESHUTDOWN          = 58;\n    enum ETOOMANYREFS       = 59;\n    enum ETIMEDOUT          = 60;\n    enum ECONNREFUSED       = 61;\n    enum ELOOP              = 62;\n    enum ENAMETOOLONG       = 63;\n    enum EHOSTUNREACH       = 65;\n    enum ENOTEMPTY          = 66;\n    enum EPROCLIM           = 67;\n    enum EUSERS             = 68;\n    enum EDQUOT             = 69;\n    enum ESTALE             = 70;\n    enum EREMOTE            = 71;\n    enum EBADRPC            = 72;\n    enum ERPCMISMATCH       = 73;\n    enum EPROGUNAVAIL       = 74;\n    enum EPROGMISMATCH      = 75;\n    enum EPROCUNAVAIL       = 76;\n    enum ENOLCK             = 77;\n    enum ENOSYS             = 78;\n    enum EFTYPE             = 79;\n    enum EAUTH              = 80;\n    enum ENEEDAUTH          = 81;\n    enum EIDRM              = 82;\n    enum ENOMSG             = 83;\n    enum EOVERFLOW          = 84;\n    enum ECANCELED          = 85;\n    enum EILSEQ             = 86;\n    enum ENOATTR            = 87;\n    enum EDOOFUS            = 88;\n    enum EBADMSG            = 89;\n    enum EMULTIHOP          = 90;\n    enum ENOLINK            = 91;\n    enum EPROTO             = 92;\n    enum ENOMEDIUM          = 93;\n    enum EUNUSED94          = 94;\n    enum EUNUSED95          = 95;\n    enum EUNUSED96          = 96;\n    enum EUNUSED97          = 97;\n    enum EUNUSED98          = 98;\n    enum EASYNC             = 99;\n    enum ELAST              = 99;\n}\nelse version (Solaris)\n{\n    enum EPERM =  1       /** Not super-user                       */;\n    enum ENOENT = 2       /** No such file or directory            */;\n    enum ESRCH =  3       /** No such process                      */;\n    enum EINTR =  4       /** interrupted system call              */;\n    enum EIO =    5       /** I/O error                            */;\n    enum ENXIO =  6       /** No such device or address            */;\n    enum E2BIG =  7       /** Arg list too long                    */;\n    enum ENOEXEC = 8       /** Exec format error                    */;\n    enum EBADF =  9       /** Bad file number                      */;\n    enum ECHILD = 10      /** No children                          */;\n    enum EAGAIN = 11      /** Resource temporarily unavailable     */;\n    enum ENOMEM = 12      /** Not enough core                      */;\n    enum EACCES = 13      /** Permission denied                    */;\n    enum EFAULT = 14      /** Bad address                          */;\n    enum ENOTBLK = 15      /** Block device required                */;\n    enum EBUSY =  16      /** Mount device busy                    */;\n    enum EEXIST = 17      /** File exists                          */;\n    enum EXDEV =  18      /** Cross-device link                    */;\n    enum ENODEV = 19      /** No such device                       */;\n    enum ENOTDIR = 20      /** Not a directory                      */;\n    enum EISDIR = 21      /** Is a directory                       */;\n    enum EINVAL = 22      /** Invalid argument                     */;\n    enum ENFILE = 23      /** File table overflow                  */;\n    enum EMFILE = 24      /** Too many open files                  */;\n    enum ENOTTY = 25      /** Inappropriate ioctl for device       */;\n    enum ETXTBSY = 26      /** Text file busy                       */;\n    enum EFBIG =  27      /** File too large                       */;\n    enum ENOSPC = 28      /** No space left on device              */;\n    enum ESPIPE = 29      /** Illegal seek                         */;\n    enum EROFS =  30      /** Read only file system                */;\n    enum EMLINK = 31      /** Too many links                       */;\n    enum EPIPE =  32      /** Broken pipe                          */;\n    enum EDOM =   33      /** Math arg out of domain of func       */;\n    enum ERANGE = 34      /** Math result not representable        */;\n    enum ENOMSG = 35      /** No message of desired type           */;\n    enum EIDRM =  36      /** Identifier removed                   */;\n    enum ECHRNG = 37      /** Channel number out of range          */;\n    enum EL2NSYNC = 38     /** Level 2 not synchronized             */;\n    enum EL3HLT = 39      /** Level 3 halted                       */;\n    enum EL3RST = 40      /** Level 3 reset                        */;\n    enum ELNRNG = 41      /** Link number out of range             */;\n    enum EUNATCH = 42      /** Protocol driver not attached         */;\n    enum ENOCSI = 43      /** No CSI structure available           */;\n    enum EL2HLT = 44      /** Level 2 halted                       */;\n    enum EDEADLK = 45      /** Deadlock condition.                  */;\n    enum ENOLCK = 46      /** No record locks available.           */;\n    enum ECANCELED = 47    /** Operation canceled                   */;\n    enum ENOTSUP = 48      /** Operation not supported              */;\n    enum EDQUOT = 49      /** Disc quota exceeded                  */;\n    enum EBADE =  50      /** invalid exchange                     */;\n    enum EBADR =  51      /** invalid request descriptor           */;\n    enum EXFULL = 52      /** exchange full                        */;\n    enum ENOANO = 53      /** no anode                             */;\n    enum EBADRQC = 54      /** invalid request code                 */;\n    enum EBADSLT = 55      /** invalid slot                         */;\n    enum EDEADLOCK = 56    /** file locking deadlock error          */;\n    enum EBFONT = 57      /** bad font file fmt                    */;\n    enum EOWNERDEAD =     58      /** process died with the lock */;\n    enum ENOTRECOVERABLE = 59      /** lock is not recoverable */;\n    enum ENOSTR = 60      /** Device not a stream                  */;\n    enum ENODATA = 61      /** no data (for no delay io)            */;\n    enum ETIME =  62      /** timer expired                        */;\n    enum ENOSR =  63      /** out of streams resources             */;\n    enum ENONET = 64      /** Machine is not on the network        */;\n    enum ENOPKG = 65      /** Package not installed                */;\n    enum EREMOTE = 66      /** The object is remote                 */;\n    enum ENOLINK = 67      /** the link has been severed            */;\n    enum EADV =   68      /** advertise error                      */;\n    enum ESRMNT = 69      /** srmount error                        */;\n    enum ECOMM =  70      /** Communication error on send          */;\n    enum EPROTO = 71      /** Protocol error                       */;\n    enum ELOCKUNMAPPED =  72      /** locked lock was unmapped */;\n    enum ENOTACTIVE = 73   /** Facility is not active               */;\n    enum EMULTIHOP = 74    /** multihop attempted                   */;\n    enum EBADMSG = 77      /** trying to read unreadable message    */;\n    enum ENAMETOOLONG = 78 /** path name is too long                */;\n    enum EOVERFLOW = 79    /** value too large to be stored in data type */;\n    enum ENOTUNIQ = 80     /** given log. name not unique           */;\n    enum EBADFD =  81      /** f.d. invalid for this operation      */;\n    enum EREMCHG = 82      /** Remote address changed               */;\n    enum ELIBACC = 83      /** Can't access a needed shared lib.    */;\n    enum ELIBBAD = 84      /** Accessing a corrupted shared lib.    */;\n    enum ELIBSCN = 85      /** .lib section in a.out corrupted.     */;\n    enum ELIBMAX = 86      /** Attempting to link in too many libs. */;\n    enum ELIBEXEC = 87     /** Attempting to exec a shared library. */;\n    enum EILSEQ = 88      /** Illegal byte sequence.               */;\n    enum ENOSYS = 89      /** Unsupported file system operation    */;\n    enum ELOOP =  90      /** Symbolic link loop                   */;\n    enum ERESTART = 91     /** Restartable system call              */;\n    enum ESTRPIPE = 92     /** if pipe/FIFO, don't sleep in stream head */;\n    enum ENOTEMPTY = 93    /** directory not empty                  */;\n    enum EUSERS = 94      /** Too many users (for UFS)             */;\n    enum ENOTSOCK =       95      /** Socket operation on non-socket */;\n    enum EDESTADDRREQ =   96      /** Destination address required */;\n    enum EMSGSIZE =       97      /** Message too long */;\n    enum EPROTOTYPE =     98      /** Protocol wrong type for socket */;\n    enum ENOPROTOOPT =    99      /** Protocol not available */;\n    enum EPROTONOSUPPORT = 120     /** Protocol not supported */;\n    enum ESOCKTNOSUPPORT = 121     /** Socket type not supported */;\n    enum EOPNOTSUPP =     122     /** Operation not supported on socket */;\n    enum EPFNOSUPPORT =   123     /** Protocol family not supported */;\n    enum EAFNOSUPPORT =   124     /** Address family not supported by the protocol family */;\n    enum EADDRINUSE =     125     /** Address already in use */;\n    enum EADDRNOTAVAIL =   126     /** Can't assign requested address */;\n    enum ENETDOWN =       127     /** Network is down */;\n    enum ENETUNREACH =    128     /** Network is unreachable */;\n    enum ENETRESET =      129     /** Network dropped connection because of reset */;\n    enum ECONNABORTED =   130     /** Software caused connection abort */;\n    enum ECONNRESET =     131     /** Connection reset by peer */;\n    enum ENOBUFS =        132     /** No buffer space available */;\n    enum EISCONN =        133     /** Socket is already connected */;\n    enum ENOTCONN =       134     /** Socket is not connected */;\n    enum ESHUTDOWN =      143     /** Can't send after socket shutdown */;\n    enum ETOOMANYREFS =   144     /** Too many references: can't splice */;\n    enum ETIMEDOUT =      145     /** Connection timed out */;\n    enum ECONNREFUSED =   146     /** Connection refused */;\n    enum EHOSTDOWN =      147     /** Host is down */;\n    enum EHOSTUNREACH =   148     /** No route to host */;\n    enum EWOULDBLOCK =    EAGAIN;      /** Resource temporarily unavailable     */;\n    enum EALREADY =       149     /** operation already in progress */;\n    enum EINPROGRESS =    150     /** operation now in progress */;\n    enum ESTALE =         151     /** Stale NFS file handle */;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/errno_.c",
    "content": "/**\n * This file contains wrapper functions for macro-defined C routines.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/errno.c)\n */\n\n#include <errno.h>\n\n\nint getErrno()\n{\n    return errno;\n}\n\n\nint setErrno( int val )\n{\n    errno = val;\n    return val;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/fenv.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_fenv.h.html, _fenv.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_fenv.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.fenv;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nextern (C):\n@system:\nnothrow:\n@nogc:\n\nversion (PPC)\n    version = PPC_Any;\nelse version (PPC64)\n    version = PPC_Any;\n\nversion (MinGW)\n    version = GNUFP;\nversion (CRuntime_Glibc)\n    version = GNUFP;\n\nversion (GNUFP)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h\n    version (X86)\n    {\n        struct fenv_t\n        {\n            ushort __control_word;\n            ushort __unused1;\n            ushort __status_word;\n            ushort __unused2;\n            ushort __tags;\n            ushort __unused3;\n            uint   __eip;\n            ushort __cs_selector;\n            ushort __opcode;\n            uint   __data_offset;\n            ushort __data_selector;\n            ushort __unused5;\n        }\n\n        alias fexcept_t = ushort;\n    }\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h\n    else version (X86_64)\n    {\n        struct fenv_t\n        {\n            ushort __control_word;\n            ushort __unused1;\n            ushort __status_word;\n            ushort __unused2;\n            ushort __tags;\n            ushort __unused3;\n            uint   __eip;\n            ushort __cs_selector;\n            ushort __opcode;\n            uint   __data_offset;\n            ushort __data_selector;\n            ushort __unused5;\n            uint   __mxcsr;\n        }\n\n        alias fexcept_t = ushort;\n    }\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/mips/bits/fenv.h\n    else version (MIPS32)\n    {\n        struct fenv_t\n        {\n            uint   __fp_control_register;\n        }\n\n        alias fexcept_t = ushort;\n    }\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/mips/bits/fenv.h\n    else version (MIPS64)\n    {\n        struct fenv_t\n        {\n            uint   __fp_control_register;\n        }\n\n        alias fexcept_t = ushort;\n    }\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/aarch64/bits/fenv.h\n    else version (AArch64)\n    {\n        struct fenv_t\n        {\n            uint __fpcr;\n            uint __fpsr;\n        }\n\n        alias fexcept_t = uint;\n    }\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/bits/fenv.h\n    else version (ARM)\n    {\n        struct fenv_t\n        {\n            uint __cw;\n        }\n\n        alias fexcept_t = uint;\n    }\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/bits/fenv.h\n    else version (PPC_Any)\n    {\n        alias fenv_t = double;\n        alias fexcept_t = uint;\n    }\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/sparc/fpu/bits/fenv.h\n    else version (SPARC64)\n    {\n        alias fenv_t = ulong;\n        alias fexcept_t = ulong;\n    }\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/s390/fpu/bits/fenv.h\n    else version (SystemZ)\n    {\n        struct fenv_t\n        {\n            fexcept_t __fpc;\n            void*     __unused;\n        }\n\n        alias fexcept_t = uint;\n    }\n    else\n    {\n        static assert(0, \"Unimplemented architecture\");\n    }\n}\nelse version (CRuntime_DigitalMars)\n{\n    struct fenv_t\n    {\n        ushort    status;\n        ushort    control;\n        ushort    round;\n        ushort[2] reserved;\n    }\n    alias fexcept_t = int;\n}\nelse version (CRuntime_Microsoft)\n{\n    struct fenv_t\n    {\n        uint ctl;\n        uint stat;\n    }\n\n    alias fexcept_t = uint;\n}\nelse version (Darwin)\n{\n    version (BigEndian)\n    {\n        alias uint fenv_t;\n        alias uint fexcept_t;\n    }\n    version (LittleEndian)\n    {\n        struct fenv_t\n        {\n            ushort  __control;\n            ushort  __status;\n            uint    __mxcsr;\n            byte[8] __reserved;\n        }\n\n        alias ushort fexcept_t;\n    }\n}\nelse version (FreeBSD)\n{\n    struct fenv_t\n    {\n        ushort __control;\n        ushort __mxcsr_hi;\n        ushort __status;\n        ushort __mxcsr_lo;\n        uint __tag;\n        byte[16] __other;\n    }\n\n    alias ushort fexcept_t;\n}\nelse version (NetBSD)\n{\n    version (X86_64)\n    {\n        struct fenv_t\n        {\n            struct _x87\n            {\n                    uint control;       /* Control word register */\n                    uint status;        /* Status word register */\n                    uint tag;           /* Tag word register */\n                    uint[4] others;     /* EIP, Pointer Selector, etc */\n            };\n            _x87 x87;\n\n            uint mxcsr;                 /* Control and status register */\n        }\n   }\n   version (X86)\n   {\n        struct fenv_t\n        {\n            struct _x87\n            {\n                    ushort control;       /* Control word register */\n                    ushort unused1;\n                    ushort status;        /* Status word register */\n                    ushort unused2;\n                    ushort tag;           /* Tag word register */\n                    ushort unused3;\n                    uint[4] others;     /* EIP, Pointer Selector, etc */\n            };\n            _x87 x87;\n            uint32_t mxcsr;                 /* Control and status register */\n        };\n\n    }\n\n    alias uint fexcept_t;\n}\nelse version (OpenBSD)\n{\n    struct fenv_t\n    {\n        struct __x87\n        {\n            uint    __control;\n            uint    __status;\n            uint    __tag;\n            uint[4] __others;\n        }\n    }\n    uint __mxcsr;\n\n    alias fexcept_t = uint;\n}\nelse version (DragonFlyBSD)\n{\n    struct fenv_t\n    {\n        struct _x87\n        {\n                uint control;\n                uint status;\n                uint tag;\n                uint[4] others;\n        };\n        _x87 x87;\n\n        uint mxcsr;\n    }\n\n    alias uint fexcept_t;\n}\nelse version (CRuntime_Bionic)\n{\n    version (X86)\n    {\n        struct fenv_t\n        {\n            ushort   __control;\n            ushort   __mxcsr_hi;\n            ushort   __status;\n            ushort   __mxcsr_lo;\n            uint     __tag;\n            byte[16] __other;\n        }\n\n        alias ushort fexcept_t;\n    }\n    else version (ARM)\n    {\n        alias uint fenv_t;\n        alias uint fexcept_t;\n    }\n    else version (AArch64)\n    {\n        struct fenv_t\n        {\n            uint   __control;\n            uint   __status;\n        }\n\n        alias uint fexcept_t;\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n}\nelse version (Solaris)\n{\n    import core.stdc.config : c_ulong;\n\n    enum FEX_NUM_EXC = 12;\n\n    struct fex_handler_t\n    {\n        int             __mode;\n        void function() __handler;\n    }\n\n    struct fenv_t\n    {\n        fex_handler_t[FEX_NUM_EXC]  __handler;\n        c_ulong                     __fsr;\n    }\n\n    alias int fexcept_t;\n}\nelse version (CRuntime_Musl)\n{\n    version (X86_64)\n    {\n        struct fenv_t\n        {\n            ushort __control_word;\n            ushort __unused1;\n            ushort __status_word;\n            ushort __unused2;\n            ushort __tags;\n            ushort __unused3;\n            uint   __eip;\n            ushort __cs_selector;\n            ushort __opcode;\n            uint   __data_offset;\n            ushort __data_selector;\n            ushort __unused5;\n            uint   __mxcsr;\n        }\n        alias ushort fexcept_t;\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    version (X86)\n    {\n        struct fenv_t\n        {\n            ushort __control_word;\n            ushort __unused1;\n            ushort __status_word;\n            ushort __unused2;\n            ushort __tags;\n            ushort __unused3;\n            uint   __eip;\n            ushort __cs_selector;\n            ushort __opcode;\n            uint   __data_offset;\n            ushort __data_selector;\n            ushort __unused5;\n        }\n\n        alias fexcept_t = ushort;\n    }\n    else version (X86_64)\n    {\n        struct fenv_t\n        {\n            ushort __control_word;\n            ushort __unused1;\n            ushort __status_word;\n            ushort __unused2;\n            ushort __tags;\n            ushort __unused3;\n            uint   __eip;\n            ushort __cs_selector;\n            ushort __opcode;\n            uint   __data_offset;\n            ushort __data_selector;\n            ushort __unused5;\n            uint   __mxcsr;\n        }\n\n        alias fexcept_t = ushort;\n    }\n    else version (MIPS32)\n    {\n        struct fenv_t\n        {\n            uint __fp_control_register;\n        }\n\n        alias fexcept_t = ushort;\n    }\n    else version (ARM)\n    {\n        struct fenv_t\n        {\n            uint __cw;\n        }\n\n        alias fexcept_t = uint;\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n}\nelse\n{\n    static assert( false, \"Unsupported platform\" );\n}\n\nversion (CRuntime_Microsoft)\n{\n    enum\n    {\n        FE_INEXACT      = 1, ///\n        FE_UNDERFLOW    = 2, ///\n        FE_OVERFLOW     = 4, ///\n        FE_DIVBYZERO    = 8, ///\n        FE_INVALID      = 0x10, ///\n        FE_ALL_EXCEPT   = 0x1F, ///\n        FE_TONEAREST    = 0, ///\n        FE_UPWARD       = 0x100, ///\n        FE_DOWNWARD     = 0x200, ///\n        FE_TOWARDZERO   = 0x300, ///\n    }\n}\nelse\n{\n    version (X86)\n    {\n        // Define bits representing the exception.\n        enum\n        {\n            FE_INVALID      = 0x01, ///\n            FE_DENORMAL     = 0x02, /// non-standard\n            FE_DIVBYZERO    = 0x04, ///\n            FE_OVERFLOW     = 0x08, ///\n            FE_UNDERFLOW    = 0x10, ///\n            FE_INEXACT      = 0x20, ///\n            FE_ALL_EXCEPT   = 0x3F, ///\n        }\n\n        // The ix87 FPU supports all of the four defined rounding modes.\n        enum\n        {\n            FE_TONEAREST    = 0, ///\n            FE_DOWNWARD     = 0x400, ///\n            FE_UPWARD       = 0x800, ///\n            FE_TOWARDZERO   = 0xC00, ///\n        }\n    }\n    else version (X86_64)\n    {\n        // Define bits representing the exception.\n        enum\n        {\n            FE_INVALID      = 0x01, ///\n            FE_DENORMAL     = 0x02, /// non-standard\n            FE_DIVBYZERO    = 0x04, ///\n            FE_OVERFLOW     = 0x08, ///\n            FE_UNDERFLOW    = 0x10, ///\n            FE_INEXACT      = 0x20, ///\n            FE_ALL_EXCEPT   = 0x3F, ///\n        }\n\n        // The ix87 FPU supports all of the four defined rounding modes.\n        enum\n        {\n            FE_TONEAREST    = 0, ///\n            FE_DOWNWARD     = 0x400, ///\n            FE_UPWARD       = 0x800, ///\n            FE_TOWARDZERO   = 0xC00, ///\n        }\n    }\n    else version (ARM)\n    {\n        // Define bits representing exceptions in the FPU status word.\n        enum\n        {\n            FE_INVALID      = 1,  ///\n            FE_DIVBYZERO    = 2,  ///\n            FE_OVERFLOW     = 4,  ///\n            FE_UNDERFLOW    = 8,  ///\n            FE_INEXACT      = 16, ///\n            FE_ALL_EXCEPT   = 31, ///\n        }\n\n        // VFP supports all of the four defined rounding modes.\n        enum\n        {\n            FE_TONEAREST    = 0,        ///\n            FE_UPWARD       = 0x400000, ///\n            FE_DOWNWARD     = 0x800000, ///\n            FE_TOWARDZERO   = 0xC00000, ///\n        }\n    }\n    else version (AArch64)\n    {\n        // Define bits representing exceptions in the FPSR status word.\n        enum\n        {\n            FE_INVALID      = 1,  ///\n            FE_DIVBYZERO    = 2,  ///\n            FE_OVERFLOW     = 4,  ///\n            FE_UNDERFLOW    = 8,  ///\n            FE_INEXACT      = 16, ///\n            FE_ALL_EXCEPT   = 31, ///\n        }\n\n        // Define bits representing rounding modes in the FPCR Rmode field.\n        enum\n        {\n            FE_TONEAREST    = 0x000000, ///\n            FE_UPWARD       = 0x400000, ///\n            FE_DOWNWARD     = 0x800000, ///\n            FE_TOWARDZERO   = 0xC00000, ///\n        }\n    }\n    else version (MIPS32)\n    {\n        // Define bits representing the exception.\n        enum\n        {\n            FE_INEXACT      = 0x04, ///\n            FE_UNDERFLOW    = 0x08, ///\n            FE_OVERFLOW     = 0x10, ///\n            FE_DIVBYZERO    = 0x20, ///\n            FE_INVALID      = 0x40, ///\n            FE_ALL_EXCEPT   = 0x7C, ///\n        }\n\n        // The MIPS FPU supports all of the four defined rounding modes.\n        enum\n        {\n            FE_TONEAREST    = 0x0, ///\n            FE_TOWARDZERO   = 0x1, ///\n            FE_UPWARD       = 0x2, ///\n            FE_DOWNWARD     = 0x3, ///\n        }\n    }\n    else version (MIPS64)\n    {\n        // Define bits representing the exception.\n        enum\n        {\n            FE_INEXACT      = 0x04, ///\n            FE_UNDERFLOW    = 0x08, ///\n            FE_OVERFLOW     = 0x10, ///\n            FE_DIVBYZERO    = 0x20, ///\n            FE_INVALID      = 0x40, ///\n            FE_ALL_EXCEPT   = 0x7C, ///\n        }\n\n        // The MIPS FPU supports all of the four defined rounding modes.\n        enum\n        {\n            FE_TONEAREST    = 0x0, ///\n            FE_TOWARDZERO   = 0x1, ///\n            FE_UPWARD       = 0x2, ///\n            FE_DOWNWARD     = 0x3, ///\n        }\n    }\n    else version (PPC)\n    {\n        // Define bits representing the exception.\n        enum\n        {\n            FE_INEXACT                    = 0x2000000,  ///\n            FE_DIVBYZERO                  = 0x4000000,  ///\n            FE_UNDERFLOW                  = 0x8000000,  ///\n            FE_OVERFLOW                   = 0x10000000, ///\n            FE_INVALID                    = 0x20000000, ///\n            FE_INVALID_SNAN               = 0x1000000,  /// non-standard\n            FE_INVALID_ISI                = 0x800000,   /// non-standard\n            FE_INVALID_IDI                = 0x400000,   /// non-standard\n            FE_INVALID_ZDZ                = 0x200000,   /// non-standard\n            FE_INVALID_IMZ                = 0x100000,   /// non-standard\n            FE_INVALID_COMPARE            = 0x80000,    /// non-standard\n            FE_INVALID_SOFTWARE           = 0x400,      /// non-standard\n            FE_INVALID_SQRT               = 0x200,      /// non-standard\n            FE_INVALID_INTEGER_CONVERSION = 0x100,      /// non-standard\n            FE_ALL_INVALID                = 0x1F80700,  /// non-standard\n            FE_ALL_EXCEPT                 = 0x3E000000, ///\n        }\n\n        // PowerPC chips support all of the four defined rounding modes.\n        enum\n        {\n            FE_TONEAREST    = 0, ///\n            FE_TOWARDZERO   = 1, ///\n            FE_UPWARD       = 2, ///\n            FE_DOWNWARD     = 3, ///\n        }\n    }\n    else version (PPC64)\n    {\n        // Define bits representing the exception.\n        enum\n        {\n            FE_INEXACT                    = 0x2000000,  ///\n            FE_DIVBYZERO                  = 0x4000000,  ///\n            FE_UNDERFLOW                  = 0x8000000,  ///\n            FE_OVERFLOW                   = 0x10000000, ///\n            FE_INVALID                    = 0x20000000, ///\n            FE_INVALID_SNAN               = 0x1000000,  /// non-standard\n            FE_INVALID_ISI                = 0x800000,   /// non-standard\n            FE_INVALID_IDI                = 0x400000,   /// non-standard\n            FE_INVALID_ZDZ                = 0x200000,   /// non-standard\n            FE_INVALID_IMZ                = 0x100000,   /// non-standard\n            FE_INVALID_COMPARE            = 0x80000,    /// non-standard\n            FE_INVALID_SOFTWARE           = 0x400,      /// non-standard\n            FE_INVALID_SQRT               = 0x200,      /// non-standard\n            FE_INVALID_INTEGER_CONVERSION = 0x100,      /// non-standard\n            FE_ALL_INVALID                = 0x1F80700,  /// non-standard\n            FE_ALL_EXCEPT                 = 0x3E000000, ///\n        }\n\n        // PowerPC chips support all of the four defined rounding modes.\n        enum\n        {\n            FE_TONEAREST    = 0, ///\n            FE_TOWARDZERO   = 1, ///\n            FE_UPWARD       = 2, ///\n            FE_DOWNWARD     = 3, ///\n        }\n    }\n    else version (SPARC64)\n    {\n        // Define bits representing the exception.\n        enum\n        {\n            FE_INVALID      = 0x200, ///\n            FE_OVERFLOW     = 0x100, ///\n            FE_UNDERFLOW    = 0x80,  ///\n            FE_DIVBYZERO    = 0x40,  ///\n            FE_INEXACT      = 0x20,  ///\n            FE_ALL_EXCEPT   = 0x3E0, ///\n        }\n\n        // The Sparc FPU supports all of the four defined rounding modes.\n        enum\n        {\n            FE_TONEAREST    = 0x0,        ///\n            FE_TOWARDZERO   = 0x40000000, ///\n            FE_UPWARD       = 0x80000000, ///\n            FE_DOWNWARD     = 0xc0000000, ///\n        }\n    }\n    else version (SystemZ)\n    {\n        // Define bits representing the exception.\n        enum\n        {\n            FE_INVALID      = 0x80, ///\n            FE_DIVBYZERO    = 0x40, ///\n            FE_OVERFLOW     = 0x20, ///\n            FE_UNDERFLOW    = 0x10, ///\n            FE_INEXACT      = 0x08, ///\n            FE_ALL_EXCEPT   = 0xF8, ///\n        }\n\n        // SystemZ supports all of the four defined rounding modes.\n        enum\n        {\n            FE_TONEAREST    = 0x0, ///\n            FE_DOWNWARD     = 0x3, ///\n            FE_UPWARD       = 0x2, ///\n            FE_TOWARDZERO   = 0x1, ///\n        }\n    }\n    else\n    {\n        static assert(0, \"Unimplemented architecture\");\n    }\n\n}\n\nversion (GNUFP)\n{\n    ///\n    enum FE_DFL_ENV = cast(fenv_t*)(-1);\n}\nelse version (CRuntime_DigitalMars)\n{\n    private extern __gshared fenv_t _FE_DFL_ENV;\n    ///\n    enum fenv_t* FE_DFL_ENV = &_FE_DFL_ENV;\n}\nelse version (CRuntime_Microsoft)\n{\n    private extern __gshared fenv_t _Fenv0;\n    ///\n    enum FE_DFL_ENV = &_Fenv0;\n}\nelse version (Darwin)\n{\n    private extern __gshared fenv_t _FE_DFL_ENV;\n    ///\n    enum FE_DFL_ENV = &_FE_DFL_ENV;\n}\nelse version (FreeBSD)\n{\n    private extern const fenv_t __fe_dfl_env;\n    ///\n    enum FE_DFL_ENV = &__fe_dfl_env;\n}\nelse version (NetBSD)\n{\n    private extern const fenv_t __fe_dfl_env;\n    ///\n    enum FE_DFL_ENV = &__fe_dfl_env;\n}\nelse version (OpenBSD)\n{\n    private extern const fenv_t __fe_dfl_env;\n    ///\n    enum FE_DFL_ENV = &__fe_dfl_env;\n}\nelse version (DragonFlyBSD)\n{\n    private extern const fenv_t __fe_dfl_env;\n    ///\n    enum FE_DFL_ENV = &__fe_dfl_env;\n}\nelse version (CRuntime_Bionic)\n{\n    private extern const fenv_t __fe_dfl_env;\n    ///\n    enum FE_DFL_ENV = &__fe_dfl_env;\n}\nelse version (Solaris)\n{\n    private extern const fenv_t __fenv_def_env;\n    ///\n    enum FE_DFL_ENV = &__fenv_def_env;\n}\nelse version (CRuntime_Musl)\n{\n    ///\n    enum FE_DFL_ENV = cast(fenv_t*)(-1);\n}\nelse version (CRuntime_UClibc)\n{\n    ///\n    enum FE_DFL_ENV = cast(fenv_t*)(-1);\n}\nelse\n{\n    static assert( false, \"Unsupported platform\" );\n}\n\n///\nint feclearexcept(int excepts);\n\n///\nint fetestexcept(int excepts);\n///\nint feholdexcept(fenv_t* envp);\n\n///\nint fegetexceptflag(fexcept_t* flagp, int excepts);\n///\nint fesetexceptflag(in fexcept_t* flagp, int excepts);\n\n///\nint fegetround();\n///\nint fesetround(int round);\n\n///\nint fegetenv(fenv_t* envp);\n///\nint fesetenv(in fenv_t* envp);\n\n// MS define feraiseexcept() and feupdateenv() inline.\nversion (CRuntime_Microsoft) // supported since MSVCRT 12 (VS 2013) only\n{\n    ///\n    int feraiseexcept()(int excepts)\n    {\n        struct Entry\n        {\n            int    exceptVal;\n            double num;\n            double denom;\n        }\n        static __gshared immutable(Entry[5]) table =\n        [ // Raise exception by evaluating num / denom:\n            { FE_INVALID,   0.0,    0.0    },\n            { FE_DIVBYZERO, 1.0,    0.0    },\n            { FE_OVERFLOW,  1e+300, 1e-300 },\n            { FE_UNDERFLOW, 1e-300, 1e+300 },\n            { FE_INEXACT,   2.0,    3.0    }\n        ];\n\n        if ((excepts &= FE_ALL_EXCEPT) == 0)\n            return 0;\n\n        // Raise the exceptions not masked:\n        double ans = void;\n        foreach (i; 0 .. table.length)\n        {\n            if ((excepts & table[i].exceptVal) != 0)\n                ans = table[i].num / table[i].denom;\n        }\n\n        return 0;\n    }\n\n    ///\n    int feupdateenv()(in fenv_t* envp)\n    {\n        int excepts = fetestexcept(FE_ALL_EXCEPT);\n        return (fesetenv(envp) != 0 || feraiseexcept(excepts) != 0 ? 1 : 0);\n    }\n}\nelse\n{\n    ///\n    int feraiseexcept(int excepts);\n    ///\n    int feupdateenv(in fenv_t* envp);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/float_.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_float.h.html, _float.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_float_.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.float_;\n\nextern (C):\n@trusted: // Constants only.\nnothrow:\n@nogc:\n\n///\nenum FLT_ROUNDS                 = 1;\n///\nenum FLT_EVAL_METHOD    = 2;\n///\nenum FLT_RADIX                  = 2;\n\n///\nenum DECIMAL_DIG                = real.dig;\n///\nenum FLT_DIG                    = float.dig;\n///\nenum DBL_DIG                    = double.dig;\n///\nenum LDBL_DIG                   = real.dig;\n\n///\nenum FLT_MANT_DIG               = float.mant_dig;\n///\nenum DBL_MANT_DIG               = double.mant_dig;\n///\nenum LDBL_MANT_DIG              = real.mant_dig;\n\n///\nenum FLT_MIN                    = float.min_normal;\n///\nenum DBL_MIN                    = double.min_normal;\n///\nenum LDBL_MIN                   = real.min_normal;\n\n///\nenum FLT_MAX                    = float.max;\n///\nenum DBL_MAX                    = double.max;\n///\nenum LDBL_MAX                   = real.max;\n\n///\nenum FLT_EPSILON                = float.epsilon;\n///\nenum DBL_EPSILON                = double.epsilon;\n///\nenum LDBL_EPSILON               = real.epsilon;\n\n///\nenum FLT_MIN_EXP                = float.min_exp;\n///\nenum DBL_MIN_EXP                = double.min_exp;\n///\nenum LDBL_MIN_EXP               = real.min_exp;\n\n///\nenum FLT_MAX_EXP                = float.max_exp;\n///\nenum DBL_MAX_EXP                = double.max_exp;\n///\nenum LDBL_MAX_EXP               = real.max_exp;\n\n///\nenum FLT_MIN_10_EXP             = float.min_10_exp;\n///\nenum DBL_MIN_10_EXP             = double.min_10_exp;\n///\nenum LDBL_MIN_10_EXP    = real.min_10_exp;\n\n///\nenum FLT_MAX_10_EXP             = float.max_10_exp;\n///\nenum DBL_MAX_10_EXP             = double.max_10_exp;\n///\nenum LDBL_MAX_10_EXP    = real.max_10_exp;\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/inttypes.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_inttypes.h.html, _inttypes.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_inttypes.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.inttypes;\n\npublic import core.stdc.stddef; // for wchar_t\npublic import core.stdc.stdint; // required by spec\n\nextern (C):\n@trusted: // Types and constants only.\nnothrow:\n@nogc:\n\n///\nstruct imaxdiv_t\n{\n    intmax_t    quot,\n                rem;\n}\n\nprivate alias immutable(char)* _cstr;\n\n///\nenum _cstr PRId8            = \"hhd\";\n///\nenum _cstr PRId16           = \"hd\";\n///\nenum _cstr PRId32           = \"ld\";\n///\nenum _cstr PRId64           = \"lld\";\n\n///\nenum _cstr PRIdLEAST8       = \"hhd\";\n///\nenum _cstr PRIdLEAST16      = \"hd\";\n///\nenum _cstr PRIdLEAST32      = \"ld\";\n///\nenum _cstr PRIdLEAST64      = \"lld\";\n\n///\nenum _cstr PRIdFAST8        = \"hhd\";\n///\nenum _cstr PRIdFAST16       = \"d\";\n///\nenum _cstr PRIdFAST32       = \"ld\";\n///\nenum _cstr PRIdFAST64       = \"lld\";\n\n///\nenum _cstr PRIi8            = \"hhi\";\n///\nenum _cstr PRIi16           = \"hi\";\n///\nenum _cstr PRIi32           = \"li\";\n///\nenum _cstr PRIi64           = \"lli\";\n\n///\nenum _cstr PRIiLEAST8       = \"hhi\";\n///\nenum _cstr PRIiLEAST16      = \"hi\";\n///\nenum _cstr PRIiLEAST32      = \"li\";\n///\nenum _cstr PRIiLEAST64      = \"lli\";\n\n///\nenum _cstr PRIiFAST8        = \"hhi\";\n///\nenum _cstr PRIiFAST16       = \"i\";\n///\nenum _cstr PRIiFAST32       = \"li\";\n///\nenum _cstr PRIiFAST64       = \"lli\";\n\n///\nenum _cstr PRIo8            = \"hho\";\n///\nenum _cstr PRIo16           = \"ho\";\n///\nenum _cstr PRIo32           = \"lo\";\n///\nenum _cstr PRIo64           = \"llo\";\n\n///\nenum _cstr PRIoLEAST8       = \"hho\";\n///\nenum _cstr PRIoLEAST16      = \"ho\";\n///\nenum _cstr PRIoLEAST32      = \"lo\";\n///\nenum _cstr PRIoLEAST64      = \"llo\";\n\n///\nenum _cstr PRIoFAST8        = \"hho\";\n///\nenum _cstr PRIoFAST16       = \"o\";\n///\nenum _cstr PRIoFAST32       = \"lo\";\n///\nenum _cstr PRIoFAST64       = \"llo\";\n\n///\nenum _cstr PRIu8            = \"hhu\";\n///\nenum _cstr PRIu16           = \"hu\";\n///\nenum _cstr PRIu32           = \"lu\";\n///\nenum _cstr PRIu64           = \"llu\";\n\n///\nenum _cstr PRIuLEAST8       = \"hhu\";\n///\nenum _cstr PRIuLEAST16      = \"hu\";\n///\nenum _cstr PRIuLEAST32      = \"lu\";\n///\nenum _cstr PRIuLEAST64      = \"llu\";\n\n///\nenum _cstr PRIuFAST8        = \"hhu\";\n///\nenum _cstr PRIuFAST16       = \"u\";\n///\nenum _cstr PRIuFAST32       = \"lu\";\n///\nenum _cstr PRIuFAST64       = \"llu\";\n\n///\nenum _cstr PRIx8            = \"hhx\";\n///\nenum _cstr PRIx16           = \"hx\";\n///\nenum _cstr PRIx32           = \"lx\";\n///\nenum _cstr PRIx64           = \"llx\";\n\n///\nenum _cstr PRIxLEAST8       = \"hhx\";\n///\nenum _cstr PRIxLEAST16      = \"hx\";\n///\nenum _cstr PRIxLEAST32      = \"lx\";\n///\nenum _cstr PRIxLEAST64      = \"llx\";\n\n///\nenum _cstr PRIxFAST8        = \"hhx\";\n///\nenum _cstr PRIxFAST16       = \"x\";\n///\nenum _cstr PRIxFAST32       = \"lx\";\n///\nenum _cstr PRIxFAST64       = \"llx\";\n\n///\nenum _cstr PRIX8            = \"hhX\";\n///\nenum _cstr PRIX16           = \"hX\";\n///\nenum _cstr PRIX32           = \"lX\";\n///\nenum _cstr PRIX64           = \"llX\";\n\n///\nenum _cstr PRIXLEAST8       = \"hhX\";\n///\nenum _cstr PRIXLEAST16      = \"hX\";\n///\nenum _cstr PRIXLEAST32      = \"lX\";\n///\nenum _cstr PRIXLEAST64      = \"llX\";\n\n///\nenum _cstr PRIXFAST8        = \"hhX\";\n///\nenum _cstr PRIXFAST16       = \"X\";\n///\nenum _cstr PRIXFAST32       = \"lX\";\n///\nenum _cstr PRIXFAST64       = \"llX\";\n\n///\nenum _cstr SCNd8            = \"hhd\";\n///\nenum _cstr SCNd16           = \"hd\";\n///\nenum _cstr SCNd32           = \"ld\";\n///\nenum _cstr SCNd64           = \"lld\";\n\n///\nenum _cstr SCNdLEAST8       = \"hhd\";\n///\nenum _cstr SCNdLEAST16      = \"hd\";\n///\nenum _cstr SCNdLEAST32      = \"ld\";\n///\nenum _cstr SCNdLEAST64      = \"lld\";\n\n///\nenum _cstr SCNdFAST8        = \"hhd\";\n///\nenum _cstr SCNdFAST16       = \"d\";\n///\nenum _cstr SCNdFAST32       = \"ld\";\n///\nenum _cstr SCNdFAST64       = \"lld\";\n\n///\nenum _cstr SCNi8            = \"hhd\";\n///\nenum _cstr SCNi16           = \"hi\";\n///\nenum _cstr SCNi32           = \"li\";\n///\nenum _cstr SCNi64           = \"lli\";\n\n///\nenum _cstr SCNiLEAST8       = \"hhd\";\n///\nenum _cstr SCNiLEAST16      = \"hi\";\n///\nenum _cstr SCNiLEAST32      = \"li\";\n///\nenum _cstr SCNiLEAST64      = \"lli\";\n\n///\nenum _cstr SCNiFAST8        = \"hhd\";\n///\nenum _cstr SCNiFAST16       = \"i\";\n///\nenum _cstr SCNiFAST32       = \"li\";\n///\nenum _cstr SCNiFAST64       = \"lli\";\n\n///\nenum _cstr SCNo8            = \"hhd\";\n///\nenum _cstr SCNo16           = \"ho\";\n///\nenum _cstr SCNo32           = \"lo\";\n///\nenum _cstr SCNo64           = \"llo\";\n\n///\nenum _cstr SCNoLEAST8       = \"hhd\";\n///\nenum _cstr SCNoLEAST16      = \"ho\";\n///\nenum _cstr SCNoLEAST32      = \"lo\";\n///\nenum _cstr SCNoLEAST64      = \"llo\";\n\n///\nenum _cstr SCNoFAST8        = \"hhd\";\n///\nenum _cstr SCNoFAST16       = \"o\";\n///\nenum _cstr SCNoFAST32       = \"lo\";\n///\nenum _cstr SCNoFAST64       = \"llo\";\n\n///\nenum _cstr SCNu8            = \"hhd\";\n///\nenum _cstr SCNu16           = \"hu\";\n///\nenum _cstr SCNu32           = \"lu\";\n///\nenum _cstr SCNu64           = \"llu\";\n\n///\nenum _cstr SCNuLEAST8       = \"hhd\";\n///\nenum _cstr SCNuLEAST16      = \"hu\";\n///\nenum _cstr SCNuLEAST32      = \"lu\";\n///\nenum _cstr SCNuLEAST64      = \"llu\";\n\n///\nenum _cstr SCNuFAST8        = \"hhd\";\n///\nenum _cstr SCNuFAST16       = \"u\";\n///\nenum _cstr SCNuFAST32       = \"lu\";\n///\nenum _cstr SCNuFAST64       = \"llu\";\n\n///\nenum _cstr SCNx8            = \"hhd\";\n///\nenum _cstr SCNx16           = \"hx\";\n///\nenum _cstr SCNx32           = \"lx\";\n///\nenum _cstr SCNx64           = \"llx\";\n\n///\nenum _cstr SCNxLEAST8       = \"hhd\";\n///\nenum _cstr SCNxLEAST16      = \"hx\";\n///\nenum _cstr SCNxLEAST32      = \"lx\";\n///\nenum _cstr SCNxLEAST64      = \"llx\";\n\n///\nenum _cstr SCNxFAST8        = \"hhd\";\n///\nenum _cstr SCNxFAST16       = \"x\";\n///\nenum _cstr SCNxFAST32       = \"lx\";\n///\nenum _cstr SCNxFAST64       = \"llx\";\n\nversion (D_LP64)\n{\n    ///\n    enum _cstr PRIdMAX      = PRId64;\n    ///\n    enum _cstr PRIiMAX      = PRIi64;\n    ///\n    enum _cstr PRIoMAX      = PRIo64;\n    ///\n    enum _cstr PRIuMAX      = PRIu64;\n    ///\n    enum _cstr PRIxMAX      = PRIx64;\n    ///\n    enum _cstr PRIXMAX      = PRIX64;\n\n    ///\n    enum _cstr SCNdMAX      = SCNd64;\n    ///\n    enum _cstr SCNiMAX      = SCNi64;\n    ///\n    enum _cstr SCNoMAX      = SCNo64;\n    ///\n    enum _cstr SCNuMAX      = SCNu64;\n    ///\n    enum _cstr SCNxMAX      = SCNx64;\n\n    ///\n    enum _cstr PRIdPTR      = PRId64;\n    ///\n    enum _cstr PRIiPTR      = PRIi64;\n    ///\n    enum _cstr PRIoPTR      = PRIo64;\n    ///\n    enum _cstr PRIuPTR      = PRIu64;\n    ///\n    enum _cstr PRIxPTR      = PRIx64;\n    ///\n    enum _cstr PRIXPTR      = PRIX64;\n\n    ///\n    enum _cstr SCNdPTR      = SCNd64;\n    ///\n    enum _cstr SCNiPTR      = SCNi64;\n    ///\n    enum _cstr SCNoPTR      = SCNo64;\n    ///\n    enum _cstr SCNuPTR      = SCNu64;\n    ///\n    enum _cstr SCNxPTR      = SCNx64;\n}\nelse\n{\n    ///\n    enum _cstr PRIdMAX      = PRId32;\n    ///\n    enum _cstr PRIiMAX      = PRIi32;\n    ///\n    enum _cstr PRIoMAX      = PRIo32;\n    ///\n    enum _cstr PRIuMAX      = PRIu32;\n    ///\n    enum _cstr PRIxMAX      = PRIx32;\n    ///\n    enum _cstr PRIXMAX      = PRIX32;\n\n    ///\n    enum _cstr SCNdMAX      = SCNd32;\n    ///\n    enum _cstr SCNiMAX      = SCNi32;\n    ///\n    enum _cstr SCNoMAX      = SCNo32;\n    ///\n    enum _cstr SCNuMAX      = SCNu32;\n    ///\n    enum _cstr SCNxMAX      = SCNx32;\n\n    ///\n    enum _cstr PRIdPTR      = PRId32;\n    ///\n    enum _cstr PRIiPTR      = PRIi32;\n    ///\n    enum _cstr PRIoPTR      = PRIo32;\n    ///\n    enum _cstr PRIuPTR      = PRIu32;\n    ///\n    enum _cstr PRIxPTR      = PRIx32;\n    ///\n    enum _cstr PRIXPTR      = PRIX32;\n\n    ///\n    enum _cstr SCNdPTR      = SCNd32;\n    ///\n    enum _cstr SCNiPTR      = SCNi32;\n    ///\n    enum _cstr SCNoPTR      = SCNo32;\n    ///\n    enum _cstr SCNuPTR      = SCNu32;\n    ///\n    enum _cstr SCNxPTR      = SCNx32;\n}\n\n///\nintmax_t  imaxabs(intmax_t j);\n///\nimaxdiv_t imaxdiv(intmax_t numer, intmax_t denom);\n///\nintmax_t  strtoimax(in char* nptr, char** endptr, int base);\n///\nuintmax_t strtoumax(in char* nptr, char** endptr, int base);\n///\nintmax_t  wcstoimax(in wchar_t* nptr, wchar_t** endptr, int base);\n///\nuintmax_t wcstoumax(in wchar_t* nptr, wchar_t** endptr, int base);\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/limits.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_limits.h.html, _limits.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_limits.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.limits;\n\nprivate import core.stdc.config;\n\nextern (C):\n@trusted: // Constants only.\nnothrow:\n@nogc:\n\n///\nenum CHAR_BIT       = 8;\n///\nenum SCHAR_MIN      = byte.min;\n///\nenum SCHAR_MAX      = byte.max;\n///\nenum UCHAR_MAX      = ubyte.max;\n///\nenum CHAR_MIN       = char.min;\n///\nenum CHAR_MAX       = char.max;\n///\nenum MB_LEN_MAX     = 2;\n///\nenum SHRT_MIN       = short.min;\n///\nenum SHRT_MAX       = short.max;\n///\nenum USHRT_MAX      = ushort.max;\n///\nenum INT_MIN        = int.min;\n///\nenum INT_MAX        = int.max;\n///\nenum UINT_MAX       = uint.max;\n///\nenum LONG_MIN       = c_long.min;\n///\nenum LONG_MAX       = c_long.max;\n///\nenum ULONG_MAX      = c_ulong.max;\n///\nenum LLONG_MIN      = long.min;\n///\nenum LLONG_MAX      = long.max;\n///\nenum ULLONG_MAX     = ulong.max;\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/locale.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_locale.h.html, _locale.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_locale.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.locale;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nextern (C):\n@trusted: // Only setlocale operates on C strings.\nnothrow:\n@nogc:\n\n///\nstruct lconv\n{\n    char* decimal_point;\n    char* thousands_sep;\n    char* grouping;\n    char* int_curr_symbol;\n    char* currency_symbol;\n    char* mon_decimal_point;\n    char* mon_thousands_sep;\n    char* mon_grouping;\n    char* positive_sign;\n    char* negative_sign;\n    byte  int_frac_digits;\n    byte  frac_digits;\n    byte  p_cs_precedes;\n    byte  p_sep_by_space;\n    byte  n_cs_precedes;\n    byte  n_sep_by_space;\n    byte  p_sign_posn;\n    byte  n_sign_posn;\n    byte  int_p_cs_precedes;\n    byte  int_p_sep_by_space;\n    byte  int_n_cs_precedes;\n    byte  int_n_sep_by_space;\n    byte  int_p_sign_posn;\n    byte  int_n_sign_posn;\n}\n\nversion (CRuntime_Glibc)\n{\n    ///\n    enum LC_CTYPE          = 0;\n    ///\n    enum LC_NUMERIC        = 1;\n    ///\n    enum LC_TIME           = 2;\n    ///\n    enum LC_COLLATE        = 3;\n    ///\n    enum LC_MONETARY       = 4;\n    ///\n    enum LC_MESSAGES       = 5;\n    ///\n    enum LC_ALL            = 6;\n    ///\n    enum LC_PAPER          = 7;  // non-standard\n    ///\n    enum LC_NAME           = 8;  // non-standard\n    ///\n    enum LC_ADDRESS        = 9;  // non-standard\n    ///\n    enum LC_TELEPHONE      = 10; // non-standard\n    ///\n    enum LC_MEASUREMENT    = 11; // non-standard\n    ///\n    enum LC_IDENTIFICATION = 12; // non-standard\n}\nelse version (Windows)\n{\n    ///\n    enum LC_ALL            = 0;\n    ///\n    enum LC_COLLATE        = 1;\n    ///\n    enum LC_CTYPE          = 2;\n    ///\n    enum LC_MONETARY       = 3;\n    ///\n    enum LC_NUMERIC        = 4;\n    ///\n    enum LC_TIME           = 5;\n}\nelse version (Darwin)\n{\n    ///\n    enum LC_ALL            = 0;\n    ///\n    enum LC_COLLATE        = 1;\n    ///\n    enum LC_CTYPE          = 2;\n    ///\n    enum LC_MONETARY       = 3;\n    ///\n    enum LC_NUMERIC        = 4;\n    ///\n    enum LC_TIME           = 5;\n    ///\n    enum LC_MESSAGES       = 6;\n}\nelse version (FreeBSD)\n{\n    ///\n    enum LC_ALL            = 0;\n    ///\n    enum LC_COLLATE        = 1;\n    ///\n    enum LC_CTYPE          = 2;\n    ///\n    enum LC_MONETARY       = 3;\n    ///\n    enum LC_NUMERIC        = 4;\n    ///\n    enum LC_TIME           = 5;\n    ///\n    enum LC_MESSAGES       = 6;\n}\nelse version (NetBSD)\n{\n    ///\n    enum LC_ALL            = 0;\n    ///\n    enum LC_COLLATE        = 1;\n    ///\n    enum LC_CTYPE          = 2;\n    ///\n    enum LC_MONETARY       = 3;\n    ///\n    enum LC_NUMERIC        = 4;\n    ///\n    enum LC_TIME           = 5;\n    ///\n    enum LC_MESSAGES       = 6;\n}\nelse version (OpenBSD)\n{\n    ///\n    enum LC_ALL            = 0;\n    ///\n    enum LC_COLLATE        = 1;\n    ///\n    enum LC_CTYPE          = 2;\n    ///\n    enum LC_MONETARY       = 3;\n    ///\n    enum LC_NUMERIC        = 4;\n    ///\n    enum LC_TIME           = 5;\n    ///\n    enum LC_MESSAGES       = 6;\n}\nelse version (DragonFlyBSD)\n{\n    ///\n    enum LC_ALL            = 0;\n    ///\n    enum LC_COLLATE        = 1;\n    ///\n    enum LC_CTYPE          = 2;\n    ///\n    enum LC_MONETARY       = 3;\n    ///\n    enum LC_NUMERIC        = 4;\n    ///\n    enum LC_TIME           = 5;\n    ///\n    enum LC_MESSAGES       = 6;\n}\nelse version (CRuntime_Bionic)\n{\n    enum\n    {\n        ///\n        LC_CTYPE          = 0,\n        ///\n        LC_NUMERIC        = 1,\n        ///\n        LC_TIME           = 2,\n        ///\n        LC_COLLATE        = 3,\n        ///\n        LC_MONETARY       = 4,\n        ///\n        LC_MESSAGES       = 5,\n        ///\n        LC_ALL            = 6,\n        ///\n        LC_PAPER          = 7,\n        ///\n        LC_NAME           = 8,\n        ///\n        LC_ADDRESS        = 9,\n        ///\n        LC_TELEPHONE      = 10,\n        ///\n        LC_MEASUREMENT    = 11,\n        ///\n        LC_IDENTIFICATION = 12,\n    }\n}\nelse version (Solaris)\n{\n    ///\n    enum LC_CTYPE       = 0;\n    ///\n    enum LC_NUMERIC     = 1;\n    ///\n    enum LC_TIME        = 2;\n    ///\n    enum LC_COLLATE     = 3;\n    ///\n    enum LC_MONETARY    = 4;\n    ///\n    enum LC_MESSAGES    = 5;\n    ///\n    enum LC_ALL         = 6;\n}\nelse version (CRuntime_Musl)\n{\n    ///\n    enum LC_CTYPE          = 0;\n    ///\n    enum LC_NUMERIC        = 1;\n    ///\n    enum LC_TIME           = 2;\n    ///\n    enum LC_COLLATE        = 3;\n    ///\n    enum LC_MONETARY       = 4;\n    ///\n    enum LC_MESSAGES       = 5;\n    ///\n    enum LC_ALL            = 6;\n}\nelse version (CRuntime_UClibc)\n{\n    ///\n    enum LC_CTYPE          = 0;\n    ///\n    enum LC_NUMERIC        = 1;\n    ///\n    enum LC_TIME           = 2;\n    ///\n    enum LC_COLLATE        = 3;\n    ///\n    enum LC_MONETARY       = 4;\n    ///\n    enum LC_MESSAGES       = 5;\n    ///\n    enum LC_ALL            = 6;\n    ///\n    enum LC_PAPER          = 7;\n    ///\n    enum LC_NAME           = 8;\n    ///\n    enum LC_ADDRESS        = 9;\n    ///\n    enum LC_TELEPHONE      = 10;\n    ///\n    enum LC_MEASUREMENT    = 11;\n    ///\n    enum LC_IDENTIFICATION = 12;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n///\n@system char*  setlocale(int category, in char* locale);\n///\nlconv* localeconv();\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/math.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_math.h.html, _math.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2012.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_math.d)\n */\n\nmodule core.stdc.math;\n\nprivate import core.stdc.config;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nextern (C):\n@trusted: // All functions here operate on floating point and integer values only.\nnothrow:\n@nogc:\n\n///\nalias float  float_t;\n///\nalias double double_t;\n\n///\nenum double HUGE_VAL      = double.infinity;\n///\nenum double HUGE_VALF     = float.infinity;\n///\nenum double HUGE_VALL     = real.infinity;\n\n///\nenum float INFINITY       = float.infinity;\n///\nenum float NAN            = float.nan;\n\nversion (FreeBSD)\n{\n    ///\n    enum int FP_ILOGB0        = -int.max;\n    ///\n    enum int FP_ILOGBNAN      = int.max;\n}\nelse version (NetBSD)\n{\n    ///\n    enum int FP_ILOGB0        = -int.max;\n    ///\n    enum int FP_ILOGBNAN      = int.max;\n}\nelse version (OpenBSD)\n{\n    ///\n    enum int FP_ILOGB0        = -int.max;\n    ///\n    enum int FP_ILOGBNAN      = int.max;\n}\nelse version (DragonFlyBSD)\n{\n    ///\n    enum int FP_ILOGB0        = -int.max;\n    ///\n    enum int FP_ILOGBNAN      = int.max;\n}\nelse version (CRuntime_Bionic)\n{\n    ///\n    enum int FP_ILOGB0        = -int.max;\n    ///\n    enum int FP_ILOGBNAN      = int.max;\n}\nelse version (CRuntime_UClibc)\n{\n    version (X86)\n    {\n        ///\n        enum int FP_ILOGB0        = int.min;\n        ///\n        enum int FP_ILOGBNAN      = int.min;\n    }\n    else version (X86_64)\n    {\n        ///\n        enum int FP_ILOGB0        = int.min;\n        ///\n        enum int FP_ILOGBNAN      = int.min;\n    }\n    else version (MIPS32)\n    {\n        ///\n        enum int FP_ILOGB0        = -int.max;\n        ///\n        enum int FP_ILOGBNAN      = int.max;\n    }\n    else version (ARM)\n    {\n        ///\n        enum int FP_ILOGB0        = -int.max;\n        ///\n        enum int FP_ILOGBNAN      = int.max;\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n}\nelse version (CRuntime_Glibc)\n{\n    version (X86)\n    {\n        ///\n        enum int FP_ILOGB0        = int.min;\n        ///\n        enum int FP_ILOGBNAN      = int.min;\n    }\n    else version (X86_64)\n    {\n        ///\n        enum int FP_ILOGB0        = int.min;\n        ///\n        enum int FP_ILOGBNAN      = int.min;\n    }\n    else version (ARM)\n    {\n        ///\n        enum int FP_ILOGB0        = -int.max;\n        ///\n        enum int FP_ILOGBNAN      = int.max;\n    }\n    else version (AArch64)\n    {\n        ///\n        enum int FP_ILOGB0        = -int.max;\n        ///\n        enum int FP_ILOGBNAN      = int.max;\n    }\n    else version (MIPS32)\n    {\n        ///\n        enum int FP_ILOGB0        = -int.max;\n        ///\n        enum int FP_ILOGBNAN      = int.max;\n    }\n    else version (MIPS64)\n    {\n        ///\n        enum int FP_ILOGB0        = -int.max;\n        ///\n        enum int FP_ILOGBNAN      = int.max;\n    }\n    else version (PPC)\n    {\n        ///\n        enum int FP_ILOGB0        = -int.max;\n        ///\n        enum int FP_ILOGBNAN      = int.max;\n    }\n    else version (PPC64)\n    {\n        ///\n        enum int FP_ILOGB0        = -int.max;\n        ///\n        enum int FP_ILOGBNAN      = int.max;\n    }\n    else version (SPARC64)\n    {\n        ///\n        enum int FP_ILOGB0        = -int.max;\n        ///\n        enum int FP_ILOGBNAN      = int.max;\n    }\n    else version (SystemZ)\n    {\n        ///\n        enum int FP_ILOGB0        = -int.max;\n        ///\n        enum int FP_ILOGBNAN      = int.max;\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n}\nelse\n{\n    ///\n    enum int FP_ILOGB0        = int.min;\n    ///\n    enum int FP_ILOGBNAN      = int.min;\n}\n\n///\nenum int MATH_ERRNO       = 1;\n///\nenum int MATH_ERREXCEPT   = 2;\n///\nenum int math_errhandling = MATH_ERRNO | MATH_ERREXCEPT;\n\nversion (none)\n{\n    //\n    // these functions are all macros in C\n    //\n\n    //int fpclassify(real-floating x);\n    pure int fpclassify(float x);\n    pure int fpclassify(double x);\n    pure int fpclassify(real x);\n\n    //int isfinite(real-floating x);\n    pure int isfinite(float x);\n    pure int isfinite(double x);\n    pure int isfinite(real x);\n\n    //int isinf(real-floating x);\n    pure int isinf(float x);\n    pure int isinf(double x);\n    pure int isinf(real x);\n\n    //int isnan(real-floating x);\n    pure int isnan(float x);\n    pure int isnan(double x);\n    pure int isnan(real x);\n\n    //int isnormal(real-floating x);\n    pure int isnormal(float x);\n    pure int isnormal(double x);\n    pure int isnormal(real x);\n\n    //int signbit(real-floating x);\n    pure int signbit(float x);\n    pure int signbit(double x);\n    pure int signbit(real x);\n\n    //int isgreater(real-floating x, real-floating y);\n    pure int isgreater(float x, float y);\n    pure int isgreater(double x, double y);\n    pure int isgreater(real x, real y);\n\n    //int isgreaterequal(real-floating x, real-floating y);\n    pure int isgreaterequal(float x, float y);\n    pure int isgreaterequal(double x, double y);\n    pure int isgreaterequal(real x, real y);\n\n    //int isless(real-floating x, real-floating y);\n    pure int isless(float x, float y);\n    pure int isless(double x, double y);\n    pure int isless(real x, real y);\n\n    //int islessequal(real-floating x, real-floating y);\n    pure int islessequal(float x, float y);\n    pure int islessequal(double x, double y);\n    pure int islessequal(real x, real y);\n\n    //int islessgreater(real-floating x, real-floating y);\n    pure int islessgreater(float x, float y);\n    pure int islessgreater(double x, double y);\n    pure int islessgreater(real x, real y);\n\n    //int isunordered(real-floating x, real-floating y);\n    pure int isunordered(float x, float y);\n    pure int isunordered(double x, double y);\n    pure int isunordered(real x, real y);\n}\n\nversion (CRuntime_DigitalMars)\n{\n    enum\n    {\n        ///\n        FP_NANS        = 0,\n        ///\n        FP_NANQ        = 1,\n        ///\n        FP_INFINITE    = 2,\n        ///\n        FP_NORMAL      = 3,\n        ///\n        FP_SUBNORMAL   = 4,\n        ///\n        FP_ZERO        = 5,\n        ///\n        FP_NAN         = FP_NANQ,\n        ///\n        FP_EMPTY       = 6,\n        ///\n        FP_UNSUPPORTED = 7,\n    }\n\n    enum\n    {\n        ///\n        FP_FAST_FMA  = 0,\n        ///\n        FP_FAST_FMAF = 0,\n        ///\n        FP_FAST_FMAL = 0,\n    }\n\n    pure uint __fpclassify_f(float x);\n    pure uint __fpclassify_d(double x);\n    pure uint __fpclassify_ld(real x);\n\n  extern (D)\n  {\n    //int fpclassify(real-floating x);\n    ///\n    pure int fpclassify(float x)     { return __fpclassify_f(x); }\n    ///\n    pure int fpclassify(double x)    { return __fpclassify_d(x); }\n    ///\n    pure int fpclassify(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __fpclassify_d(x)\n            : __fpclassify_ld(x);\n    }\n\n    //int isfinite(real-floating x);\n    ///\n    pure int isfinite(float x)       { return fpclassify(x) >= FP_NORMAL; }\n    ///\n    pure int isfinite(double x)      { return fpclassify(x) >= FP_NORMAL; }\n    ///\n    pure int isfinite(real x)        { return fpclassify(x) >= FP_NORMAL; }\n\n    //int isinf(real-floating x);\n    ///\n    pure int isinf(float x)          { return fpclassify(x) == FP_INFINITE; }\n    ///\n    pure int isinf(double x)         { return fpclassify(x) == FP_INFINITE; }\n    ///\n    pure int isinf(real x)           { return fpclassify(x) == FP_INFINITE; }\n\n    //int isnan(real-floating x);\n    ///\n    pure int isnan(float x)          { return fpclassify(x) <= FP_NANQ;   }\n    ///\n    pure int isnan(double x)         { return fpclassify(x) <= FP_NANQ;   }\n    ///\n    pure int isnan(real x)           { return fpclassify(x) <= FP_NANQ;   }\n\n    //int isnormal(real-floating x);\n    ///\n    pure int isnormal(float x)       { return fpclassify(x) == FP_NORMAL; }\n    ///\n    pure int isnormal(double x)      { return fpclassify(x) == FP_NORMAL; }\n    ///\n    pure int isnormal(real x)        { return fpclassify(x) == FP_NORMAL; }\n\n    //int signbit(real-floating x);\n    ///\n    pure int signbit(float x)     { return (cast(short*)&(x))[1] & 0x8000; }\n    ///\n    pure int signbit(double x)    { return (cast(short*)&(x))[3] & 0x8000; }\n    ///\n    pure int signbit(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? (cast(short*)&(x))[3] & 0x8000\n            : (cast(short*)&(x))[4] & 0x8000;\n    }\n  }\n}\nelse version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) only\n{\n  version (all) // legacy stuff to be removed in the future\n  {\n    enum\n    {\n        _FPCLASS_SNAN = 1,\n        _FPCLASS_QNAN = 2,\n        _FPCLASS_NINF = 4,\n        _FPCLASS_NN   = 8,\n        _FPCLASS_ND   = 0x10,\n        _FPCLASS_NZ   = 0x20,\n        _FPCLASS_PZ   = 0x40,\n        _FPCLASS_PD   = 0x80,\n        _FPCLASS_PN   = 0x100,\n        _FPCLASS_PINF = 0x200,\n    }\n\n    //deprecated(\"Please use the standard C99 function copysignf() instead.\")\n    pure float _copysignf(float x, float s);\n\n    //deprecated(\"_chgsignf(x) is a non-standard MS extension. Please consider using -x instead.\")\n    pure float _chgsignf(float x);\n\n    version (Win64) // not available in 32-bit runtimes\n    {\n        //deprecated(\"Please use the standard C99 function isfinite() instead.\")\n        pure int _finitef(float x);\n\n        //deprecated(\"Please use the standard C99 function isnan() instead.\")\n        pure int _isnanf(float x);\n\n        //deprecated(\"Please use the standard C99 function fpclassify() instead.\")\n        pure int _fpclassf(float x);\n    }\n\n    //deprecated(\"Please use the standard C99 function copysign() instead.\")\n    pure double _copysign(double x, double s);\n\n    //deprecated(\"_chgsign(x) is a non-standard MS extension. Please consider using -x instead.\")\n    pure double _chgsign(double x);\n\n    //deprecated(\"Please use the standard C99 function isfinite() instead.\")\n    pure int _finite(double x);\n\n    //deprecated(\"Please use the standard C99 function isnan() instead.\")\n    pure int _isnan(double x);\n\n    //deprecated(\"Please use the standard C99 function fpclassify() instead.\")\n    pure int _fpclass(double x);\n  }\n\n    enum\n    {\n        ///\n        FP_SUBNORMAL = -2,\n        ///\n        FP_NORMAL    = -1,\n        ///\n        FP_ZERO      =  0,\n        ///\n        FP_INFINITE  =  1,\n        ///\n        FP_NAN       =  2,\n    }\n\n    pure private short _fdclass(float x);\n    pure private short _dclass(double x);\n\n    pure private int _fdsign(float x);\n    pure private int _dsign(double x);\n\n  extern(D)\n  {\n    //int fpclassify(real-floating x);\n    ///\n    pure int fpclassify()(float x)   { return _fdclass(x); }\n    ///\n    pure int fpclassify()(double x)  { return _dclass(x);  }\n    ///\n    pure int fpclassify()(real x)\n    {\n        static if (real.sizeof == double.sizeof)\n            return _dclass(cast(double) x);\n        else\n            static assert(false, \"fpclassify(real) not supported by MS C runtime\");\n    }\n\n    //int isfinite(real-floating x);\n    ///\n    pure int isfinite()(float x)     { return fpclassify(x) <= 0; }\n    ///\n    pure int isfinite()(double x)    { return fpclassify(x) <= 0; }\n    ///\n    pure int isfinite()(real x)      { return fpclassify(x) <= 0; }\n\n    //int isinf(real-floating x);\n    ///\n    pure int isinf()(float x)        { return fpclassify(x) == FP_INFINITE; }\n    ///\n    pure int isinf()(double x)       { return fpclassify(x) == FP_INFINITE; }\n    ///\n    pure int isinf()(real x)         { return fpclassify(x) == FP_INFINITE; }\n\n    //int isnan(real-floating x);\n    version (none) // requires MSVCRT 12+ (VS 2013)\n    {\n        ///\n        pure int isnan(float x)      { return fpclassify(x) == FP_NAN; }\n        ///\n        pure int isnan(double x)     { return fpclassify(x) == FP_NAN; }\n        ///\n        pure int isnan(real x)       { return fpclassify(x) == FP_NAN; }\n    }\n    else // for backward compatibility with older runtimes\n    {\n        ///\n        pure int isnan(float x)      { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); }\n        ///\n        pure int isnan(double x)     { return _isnan(x); }\n        ///\n        pure int isnan(real x)       { return _isnan(cast(double) x); }\n    }\n\n    //int isnormal(real-floating x);\n    ///\n    pure int isnormal()(float x)     { return fpclassify(x) == FP_NORMAL; }\n    ///\n    pure int isnormal()(double x)    { return fpclassify(x) == FP_NORMAL; }\n    ///\n    pure int isnormal()(real x)      { return fpclassify(x) == FP_NORMAL; }\n\n    //int signbit(real-floating x);\n    ///\n    pure int signbit()(float x)   { return _fdsign(x); }\n    ///\n    pure int signbit()(double x)  { return _dsign(x);  }\n    ///\n    pure int signbit()(real x)\n    {\n        static if (real.sizeof == double.sizeof)\n            return _dsign(cast(double) x);\n        else\n            return (cast(short*)&(x))[4] & 0x8000;\n    }\n  }\n}\nelse version (CRuntime_Glibc)\n{\n    enum\n    {\n        ///\n        FP_NAN,\n        ///\n        FP_INFINITE,\n        ///\n        FP_ZERO,\n        ///\n        FP_SUBNORMAL,\n        ///\n        FP_NORMAL,\n    }\n\n    enum\n    {\n        ///\n        FP_FAST_FMA  = 0,\n        ///\n        FP_FAST_FMAF = 0,\n        ///\n        FP_FAST_FMAL = 0,\n    }\n\n    pure int __fpclassifyf(float x);\n    pure int __fpclassify(double x);\n    pure int __fpclassifyl(real x);\n\n    pure int __finitef(float x);\n    pure int __finite(double x);\n    pure int __finitel(real x);\n\n    pure int __isinff(float x);\n    pure int __isinf(double x);\n    pure int __isinfl(real x);\n\n    pure int __isnanf(float x);\n    pure int __isnan(double x);\n    pure int __isnanl(real x);\n\n    pure int __signbitf(float x);\n    pure int __signbit(double x);\n    pure int __signbitl(real x);\n\n  extern (D)\n  {\n    //int fpclassify(real-floating x);\n      ///\n    pure int fpclassify(float x)     { return __fpclassifyf(x); }\n    ///\n    pure int fpclassify(double x)    { return __fpclassify(x);  }\n    ///\n    pure int fpclassify(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __fpclassify(x)\n            : __fpclassifyl(x);\n    }\n\n    //int isfinite(real-floating x);\n    ///\n    pure int isfinite(float x)       { return __finitef(x); }\n    ///\n    pure int isfinite(double x)      { return __finite(x);  }\n    ///\n    pure int isfinite(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __finite(x)\n            : __finitel(x);\n    }\n\n    //int isinf(real-floating x);\n    ///\n    pure int isinf(float x)          { return __isinff(x);  }\n    ///\n    pure int isinf(double x)         { return __isinf(x);   }\n    ///\n    pure int isinf(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __isinf(x)\n            : __isinfl(x);\n    }\n\n    //int isnan(real-floating x);\n    ///\n    pure int isnan(float x)          { return __isnanf(x);  }\n    ///\n    pure int isnan(double x)         { return __isnan(x);   }\n    ///\n    pure int isnan(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __isnan(x)\n            : __isnanl(x);\n    }\n\n    //int isnormal(real-floating x);\n    ///\n    pure int isnormal(float x)       { return fpclassify(x) == FP_NORMAL; }\n    ///\n    pure int isnormal(double x)      { return fpclassify(x) == FP_NORMAL; }\n    ///\n    pure int isnormal(real x)        { return fpclassify(x) == FP_NORMAL; }\n\n    //int signbit(real-floating x);\n    ///\n    pure int signbit(float x)     { return __signbitf(x); }\n    ///\n    pure int signbit(double x)    { return __signbit(x);  }\n    ///\n    pure int signbit(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __signbit(x)\n            : __signbitl(x);\n    }\n  }\n}\nelse version (CRuntime_Musl)\n{\n    enum\n    {\n        ///\n        FP_NAN,\n        ///\n        FP_INFINITE,\n        ///\n        FP_ZERO,\n        ///\n        FP_SUBNORMAL,\n        ///\n        FP_NORMAL,\n    }\n\n    enum\n    {\n        ///\n        FP_FAST_FMA  = 0,\n        ///\n        FP_FAST_FMAF = 0,\n        ///\n        FP_FAST_FMAL = 0,\n    }\n\n  pure {\n    int __fpclassifyf(float x);\n    int __fpclassify(double x);\n    int __fpclassifyl(real x);\n\n    int __signbitf(float x);\n    int __signbit(double x);\n    int __signbitl(real x);\n  }\n\n  extern (D) pure\n  {\n    //int fpclassify(real-floating x);\n      ///\n    int fpclassify(float x)     { return __fpclassifyf(x); }\n    ///\n    int fpclassify(double x)    { return __fpclassify(x);  }\n    ///\n    int fpclassify(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __fpclassify(x)\n            : __fpclassifyl(x);\n    }\n    private uint __FLOAT_BITS(float __f)\n    {\n        union __u_t {\n            float __f;\n            uint __i;\n        }\n        __u_t __u;\n        __u.__f = __f;\n        return __u.__i;\n    }\n    private ulong __DOUBLE_BITS(double __f)\n    {\n        union __u_t {\n            double __f;\n            ulong __i;\n        }\n        __u_t __u;\n        __u.__f = __f;\n        return __u.__i;\n    }\n\n    //int isfinite(real-floating x);\n    ///\n    int isfinite(float x)       { return (__FLOAT_BITS(x) & 0x7fffffff) < 0x7f800000; }\n    ///\n    int isfinite(double x)      { return (__DOUBLE_BITS(x) & -1UL>>1) < 0x7ffUL<<52;  }\n    ///\n    int isfinite(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? isfinite(cast(double)x)\n            : __fpclassifyl(x) > FP_INFINITE;\n    }\n\n    //int isinf(real-floating x);\n    ///\n    int isinf(float x)          { return (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000;  }\n    ///\n    int isinf(double x)         { return (__DOUBLE_BITS(x) & -1UL>>1) == 0x7ffUL<<52;   }\n    ///\n    int isinf(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? isinf(cast(double)x)\n            : __fpclassifyl(x) == FP_INFINITE;\n    }\n\n    //int isnan(real-floating x);\n    ///\n    int isnan(float x)          { return (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000;  }\n    ///\n    int isnan(double x)         { return (__DOUBLE_BITS(x) & -1UL>>1) > 0x7ffUL<<52;   }\n    ///\n    int isnan(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? isnan(cast(double)x)\n            : __fpclassifyl(x) == FP_NAN;\n    }\n\n    //int isnormal(real-floating x);\n    ///\n    int isnormal(float x)       { return fpclassify(x) == FP_NORMAL; }\n    ///\n    int isnormal(double x)      { return fpclassify(x) == FP_NORMAL; }\n    ///\n    int isnormal(real x)        { return fpclassify(x) == FP_NORMAL; }\n\n    //int signbit(real-floating x);\n    ///\n    int signbit(float x)     { return __signbitf(x); }\n    ///\n    int signbit(double x)    { return __signbit(x);  }\n    ///\n    int signbit(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __signbit(x)\n            : __signbitl(x);\n    }\n  }\n}\nelse version (CRuntime_UClibc)\n{\n    enum\n    {\n        ///\n        FP_NAN,\n        ///\n        FP_INFINITE,\n        ///\n        FP_ZERO,\n        ///\n        FP_SUBNORMAL,\n        ///\n        FP_NORMAL,\n    }\n\n    enum\n    {\n        ///\n        FP_FAST_FMA  = 0,\n        ///\n        FP_FAST_FMAF = 0,\n        ///\n        FP_FAST_FMAL = 0,\n    }\n\n    int __fpclassifyf(float x);\n    int __fpclassify(double x);\n    int __fpclassifyl(real x);\n\n    int __finitef(float x);\n    int __finite(double x);\n    int __finitel(real x);\n\n    int __isinff(float x);\n    int __isinf(double x);\n    int __isinfl(real x);\n\n    int __isnanf(float x);\n    int __isnan(double x);\n    int __isnanl(real x);\n\n    int __signbitf(float x);\n    int __signbit(double x);\n    int __signbitl(real x);\n\n  extern (D)\n  {\n    ///\n    int fpclassify(float x)     { return __fpclassifyf(x); }\n    ///\n    int fpclassify(double x)    { return __fpclassify(x);  }\n    ///\n    int fpclassify(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __fpclassify(x)\n            : __fpclassifyl(x);\n    }\n\n    ///\n    int isfinite(float x)       { return __finitef(x); }\n    ///\n    int isfinite(double x)      { return __finite(x);  }\n    ///\n    int isfinite(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __finite(x)\n            : __finitel(x);\n    }\n\n    ///\n    int isinf(float x)          { return __isinff(x);  }\n    ///\n    int isinf(double x)         { return __isinf(x);   }\n    ///\n    int isinf(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __isinf(x)\n            : __isinfl(x);\n    }\n\n    ///\n    int isnan(float x)          { return __isnanf(x);  }\n    ///\n    int isnan(double x)         { return __isnan(x);   }\n    ///\n    int isnan(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __isnan(x)\n            : __isnanl(x);\n    }\n\n    ///\n    int isnormal(float x)       { return fpclassify(x) == FP_NORMAL; }\n    ///\n    int isnormal(double x)      { return fpclassify(x) == FP_NORMAL; }\n    ///\n    int isnormal(real x)        { return fpclassify(x) == FP_NORMAL; }\n\n    ///\n    int signbit(float x)     { return __signbitf(x); }\n    ///\n    int signbit(double x)    { return __signbit(x);  }\n    ///\n    int signbit(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __signbit(x)\n            : __signbitl(x);\n    }\n  }\n}\nelse version (MinGW)\n{\n    enum\n    {\n        ///\n        FP_NAN = 0x0100,\n        ///\n        FP_NORMAL = 0x0400,\n        ///\n        FP_INFINITE = FP_NAN | FP_NORMAL,\n        ///\n        FP_ZERO = 0x0400,\n        ///\n        FP_SUBNORMAL = FP_NORMAL | FP_ZERO\n    }\n\n    pure int __fpclassifyf(float x);\n    pure int __fpclassify(double x);\n    pure int __fpclassifyl(real x);\n\n    pure int __isnanf(float x);\n    pure int __isnan(double x);\n    pure int __isnanl(real x);\n\n    pure int __signbitf(float x);\n    pure int __signbit(double x);\n    pure int __signbitl(real x);\n\n  extern (D)\n  {\n    //int fpclassify(real-floating x);\n      ///\n    pure int fpclassify(float x)     { return __fpclassifyf(x); }\n    ///\n    pure int fpclassify(double x)    { return __fpclassify(x);  }\n    ///\n    pure int fpclassify(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __fpclassify(x)\n            : __fpclassifyl(x);\n    }\n\n    //int isfinite(real-floating x);\n    ///\n    pure int isfinite(float x)       { return (fpclassify(x) & FP_NORMAL) == 0; }\n    ///\n    pure int isfinite(double x)      { return (fpclassify(x) & FP_NORMAL) == 0; }\n    ///\n    pure int isfinite(real x)        { return (fpclassify(x) & FP_NORMAL) == 0; }\n\n    //int isinf(real-floating x);\n    ///\n    pure int isinf(float x)          { return fpclassify(x) == FP_INFINITE; }\n    ///\n    pure int isinf(double x)         { return fpclassify(x) == FP_INFINITE; }\n    ///\n    pure int isinf(real x)           { return fpclassify(x) == FP_INFINITE; }\n\n    //int isnan(real-floating x);\n    ///\n    pure int isnan(float x)          { return __isnanf(x);  }\n    ///\n    pure int isnan(double x)         { return __isnan(x);   }\n    ///\n    pure int isnan(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __isnan(x)\n            : __isnanl(x);\n    }\n\n    //int isnormal(real-floating x);\n    ///\n    int isnormal(float x)       { return fpclassify(x) == FP_NORMAL; }\n    ///\n    int isnormal(double x)      { return fpclassify(x) == FP_NORMAL; }\n    ///\n    int isnormal(real x)        { return fpclassify(x) == FP_NORMAL; }\n\n    //int signbit(real-floating x);\n    ///\n    int signbit(float x)     { return __signbitf(x); }\n    ///\n    int signbit(double x)    { return __signbit(x);  }\n    ///\n    int signbit(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __signbit(x)\n            : __signbitl(x);\n    }\n  }\n}\nelse version (Darwin)\n{\n    enum\n    {\n        ///\n        FP_NAN         = 1,\n        ///\n        FP_INFINITE    = 2,\n        ///\n        FP_ZERO        = 3,\n        ///\n        FP_NORMAL      = 4,\n        ///\n        FP_SUBNORMAL   = 5,\n    }\n\n    enum\n    {\n        ///\n        FP_FAST_FMA  = 0,\n        ///\n        FP_FAST_FMAF = 0,\n        ///\n        FP_FAST_FMAL = 0,\n    }\n\n    pure int __fpclassifyf(float x);\n    pure int __fpclassifyd(double x);\n\n    pure int __isfinitef(float x);\n    pure int __isfinited(double x);\n\n    pure int __isinff(float x);\n    pure int __isinfd(double x);\n\n    pure int __isnanf(float x);\n    pure int __isnand(double x);\n\n    // __isnormal family exists, but iOS implementation returns wrong results\n    // for subnormals\n\n    pure int __signbitf(float x);\n    pure int __signbitd(double x);\n    pure int __signbitl(real x);\n\n    // Support of OSX < 10.8 needs legacy function names without \"l\" suffix\n    // with exception of __signbitl.  Otherwise could use else version like\n    // other Darwins\n    version (OSX)\n    {\n        pure int __fpclassify(real x);\n        pure int __isfinite(real x);\n        pure int __isinf(real x);\n        pure int __isnan(real x);\n        alias __fpclassifyl = __fpclassify;\n        alias __isfinitel = __isfinite;\n        alias __isinfl = __isinf;\n        alias __isnanl = __isnan;\n    }\n    else\n    {\n        // Available OSX >= 10.8, iOS >= 6.0, all TVOS and WatchOS\n        pure int __fpclassifyl(real x);\n        pure int __isfinitel(real x);\n        pure int __isinfl(real x);\n        pure int __isnanl(real x);\n    }\n\n  extern (D)\n  {\n    //int fpclassify(real-floating x);\n    ///\n    pure int fpclassify(float x)     { return __fpclassifyf(x); }\n    ///\n    pure int fpclassify(double x)    { return __fpclassifyd(x); }\n    ///\n    pure int fpclassify(real x)      { return __fpclassifyl(x); }\n\n    //int isfinite(real-floating x);\n    ///\n    pure int isfinite(float x)       { return __isfinitef(x); }\n    ///\n    pure int isfinite(double x)      { return __isfinited(x); }\n    ///\n    pure int isfinite(real x)        { return __isfinitel(x); }\n\n    //int isinf(real-floating x);\n    ///\n    pure int isinf(float x)          { return __isinff(x); }\n    ///\n    pure int isinf(double x)         { return __isinfd(x); }\n    ///\n    pure int isinf(real x)           { return __isinfl(x); }\n\n    //int isnan(real-floating x);\n    ///\n    pure int isnan(float x)          { return __isnanf(x); }\n    ///\n    pure int isnan(double x)         { return __isnand(x); }\n    ///\n    pure int isnan(real x)           { return __isnanl(x); }\n\n    //int isnormal(real-floating x);\n    ///\n    pure int isnormal(float x)       { return fpclassify(x) == FP_NORMAL; }\n    ///\n    pure int isnormal(double x)      { return fpclassify(x) == FP_NORMAL; }\n    ///\n    pure int isnormal(real x)        { return fpclassify(x) == FP_NORMAL; }\n\n    //int signbit(real-floating x);\n    ///\n    pure int signbit(float x)     { return __signbitf(x); }\n    ///\n    pure int signbit(double x)    { return __signbitd(x); }\n    ///\n    pure int signbit(real x)      { return __signbitl(x); }\n  }\n}\nelse version (FreeBSD)\n{\n    enum\n    {\n        ///\n        FP_INFINITE  = 0x01,\n        ///\n        FP_NAN       = 0x02,\n        ///\n        FP_NORMAL    = 0x04,\n        ///\n        FP_SUBNORMAL = 0x08,\n        ///\n        FP_ZERO      = 0x10,\n    }\n\n    enum\n    {\n        ///\n        FP_FAST_FMA  = 0,\n        ///\n        FP_FAST_FMAF = 0,\n        ///\n        FP_FAST_FMAL = 0,\n    }\n\n    pure int __fpclassifyd(double);\n    pure int __fpclassifyf(float);\n    pure int __fpclassifyl(real);\n    pure int __isfinitef(float);\n    pure int __isfinite(double);\n    pure int __isfinitel(real);\n    pure int __isinff(float);\n    pure int __isinfl(real);\n    pure int __isnanl(real);\n    pure int __isnormalf(float);\n    pure int __isnormal(double);\n    pure int __isnormall(real);\n    pure int __signbit(double);\n    pure int __signbitf(float);\n    pure int __signbitl(real);\n\n  extern (D)\n  {\n    //int fpclassify(real-floating x);\n      ///\n    pure int fpclassify(float x)     { return __fpclassifyf(x); }\n    ///\n    pure int fpclassify(double x)    { return __fpclassifyd(x); }\n    ///\n    pure int fpclassify(real x)      { return __fpclassifyl(x); }\n\n    //int isfinite(real-floating x);\n    ///\n    pure int isfinite(float x)       { return __isfinitef(x); }\n    ///\n    pure int isfinite(double x)      { return __isfinite(x); }\n    ///\n    pure int isfinite(real x)        { return __isfinitel(x); }\n\n    //int isinf(real-floating x);\n    ///\n    pure int isinf(float x)          { return __isinff(x); }\n    ///\n    pure int isinf(double x)         { return __isinfl(x); }\n    ///\n    pure int isinf(real x)           { return __isinfl(x); }\n\n    //int isnan(real-floating x);\n    ///\n    pure int isnan(float x)          { return __isnanl(x); }\n    ///\n    pure int isnan(double x)         { return __isnanl(x); }\n    ///\n    pure int isnan(real x)           { return __isnanl(x); }\n\n    //int isnormal(real-floating x);\n    ///\n    pure int isnormal(float x)       { return __isnormalf(x); }\n    ///\n    pure int isnormal(double x)      { return __isnormal(x); }\n    ///\n    pure int isnormal(real x)        { return __isnormall(x); }\n\n    //int signbit(real-floating x);\n    ///\n    pure int signbit(float x)        { return __signbitf(x); }\n    ///\n    pure int signbit(double x)       { return __signbit(x); }\n    ///\n    pure int signbit(real x)         { return __signbit(x); }\n  }\n}\nelse version (OpenBSD)\n{\n    enum\n    {\n        ///\n        FP_INFINITE  = 0x01,\n        ///\n        FP_NAN       = 0x02,\n        ///\n        FP_NORMAL    = 0x04,\n        ///\n        FP_SUBNORMAL = 0x08,\n        ///\n        FP_ZERO      = 0x10,\n    }\n\n    enum\n    {\n        ///\n        FP_FAST_FMA  = 1,\n        ///\n        FP_FAST_FMAF = 1,\n        ///\n        FP_FAST_FMAL = 1,\n    }\n\n    pure int __fpclassifyd(double);\n    pure int __fpclassifyf(float);\n    pure int __fpclassifyl(real);\n    pure int __isfinitef(float);\n    pure int __isfinite(double);\n    pure int __isfinitel(real);\n    pure int __isinff(float);\n    pure int __isinfl(real);\n    pure int __isnanl(real);\n    pure int __isnormalf(float);\n    pure int __isnormal(double);\n    pure int __isnormall(real);\n    pure int __signbit(double);\n    pure int __signbitf(float);\n    pure int __signbitl(real);\n\n  extern (D)\n  {\n    //int fpclassify(real-floating x);\n      ///\n    pure int fpclassify(float x)     { return __fpclassifyf(x); }\n    ///\n    pure int fpclassify(double x)    { return __fpclassifyd(x); }\n    ///\n    pure int fpclassify(real x)      { return __fpclassifyl(x); }\n\n    //int isfinite(real-floating x);\n    ///\n    pure int isfinite(float x)       { return __isfinitef(x); }\n    ///\n    pure int isfinite(double x)      { return __isfinite(x); }\n    ///\n    pure int isfinite(real x)        { return __isfinitel(x); }\n\n    //int isinf(real-floating x);\n    ///\n    pure int isinf(float x)          { return __isinff(x); }\n    ///\n    pure int isinf(double x)         { return __isinfl(x); }\n    ///\n    pure int isinf(real x)           { return __isinfl(x); }\n\n    //int isnan(real-floating x);\n    ///\n    pure int isnan(float x)          { return __isnanl(x); }\n    ///\n    pure int isnan(double x)         { return __isnanl(x); }\n    ///\n    pure int isnan(real x)           { return __isnanl(x); }\n\n    //int isnormal(real-floating x);\n    ///\n    pure int isnormal(float x)       { return __isnormalf(x); }\n    ///\n    pure int isnormal(double x)      { return __isnormal(x); }\n    ///\n    pure int isnormal(real x)        { return __isnormall(x); }\n\n    //int signbit(real-floating x);\n    ///\n    pure int signbit(float x)        { return __signbitf(x); }\n    ///\n    pure int signbit(double x)       { return __signbit(x); }\n    ///\n    pure int signbit(real x)         { return __signbit(x); }\n  }\n}\nelse version (NetBSD)\n{\n    enum\n    {\n        ///\n        FP_INFINITE    = 0,\n        ///\n        FP_NAN         = 1,\n        ///\n        FP_NORMAL      = 2,\n        ///\n        FP_SUBNORMAL   = 3,\n        ///\n        FP_ZERO        = 4,\n    }\n\n    enum\n    {\n        ///\n        FP_FAST_FMA  = 0,\n        ///\n        FP_FAST_FMAF = 0,\n        ///\n        FP_FAST_FMAL = 0,\n    }\n\n    pure uint __fpclassifyf(float x);\n    pure uint __fpclassifyd(double x);\n    pure uint __fpclassifyl(real x);\n\n  extern (D)\n  {\n    //int fpclassify(real-floating x);\n    ///\n    pure int fpclassify(float x)     { return __fpclassifyf(x); }\n    ///\n    pure int fpclassify(double x)    { return __fpclassifyd(x); }\n    ///\n    pure int fpclassify(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __fpclassifyd(x)\n            : __fpclassifyl(x);\n    }\n\n    //int isfinite(real-floating x);\n    ///\n    pure int isfinite(float x)       { return fpclassify(x) >= FP_NORMAL; }\n    ///\n    pure int isfinite(double x)      { return fpclassify(x) >= FP_NORMAL; }\n    ///\n    pure int isfinite(real x)        { return fpclassify(x) >= FP_NORMAL; }\n\n    //int isinf(real-floating x);\n    ///\n    pure int isinf(float x)          { return fpclassify(x) == FP_INFINITE; }\n    ///\n    pure int isinf(double x)         { return fpclassify(x) == FP_INFINITE; }\n    ///\n    pure int isinf(real x)           { return fpclassify(x) == FP_INFINITE; }\n\n    //int isnan(real-floating x);\n    ///\n    pure int isnan(float x)          { return fpclassify(x) == FP_NAN;   }\n    ///\n    pure int isnan(double x)         { return fpclassify(x) == FP_NAN;   }\n    ///\n    pure int isnan(real x)           { return fpclassify(x) == FP_NAN;   }\n\n    //int isnormal(real-floating x);\n    ///\n    pure int isnormal(float x)       { return fpclassify(x) == FP_NORMAL; }\n    ///\n    pure int isnormal(double x)      { return fpclassify(x) == FP_NORMAL; }\n    ///\n    pure int isnormal(real x)        { return fpclassify(x) == FP_NORMAL; }\n\n    //int signbit(real-floating x);\n    ///\n    pure int signbit(float x)     { return (cast(short*)&(x))[1] & 0x8000; }\n    ///\n    pure int signbit(double x)    { return (cast(short*)&(x))[3] & 0x8000; }\n    ///\n    pure int signbit(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? (cast(short*)&(x))[3] & 0x8000\n            : (cast(short*)&(x))[4] & 0x8000;\n    }\n  }\n}\nelse version (DragonFlyBSD)\n{\n    enum\n    {\n        FP_INFINITE  = 0x01,\n        FP_NAN       = 0x02,\n        FP_NORMAL    = 0x04,\n        FP_SUBNORMAL = 0x08,\n        FP_ZERO      = 0x10,\n    }\n\n    /*\n     * /usr/include/math.h : martynas@openbsd believes only F version is true.\n       enum FP_FAST_FMA  = 1;\n       enum FP_FAST_FMAL = 1;\n     */\n    enum  FP_FAST_FMAF = 1;\n\n    pure int __fpclassifyd(double);\n    pure int __fpclassifyf(float);\n    pure int __fpclassifyl(real);\n    pure int __isfinitef(float);\n    pure int __isfinite(double);\n    pure int __isfinitel(real);\n    pure int __isinff(float);\n    pure int __isinf(double);\n    pure int __isinfl(real);\n    pure int __isnanf(float);\n    pure int __isnan(double);\n    pure int __isnanl(real);\n    pure int __isnormalf(float);\n    pure int __isnormal(double);\n    pure int __isnormall(real);\n    pure int __signbit(double);\n    pure int __signbitf(float);\n    pure int __signbitl(real);\n\n  extern (D)\n  {\n    pure int fpclassify(float x)     { return __fpclassifyf(x); }\n    pure int fpclassify(double x)    { return __fpclassifyd(x); }\n    pure int fpclassify(real x)      { return __fpclassifyl(x); }\n\n    pure int isfinite(float x)       { return __isfinitef(x); }\n    pure int isfinite(double x)      { return __isfinite(x); }\n    pure int isfinite(real x)        { return __isfinitel(x); }\n\n    pure int isinf(float x)          { return __isinff(x); }\n    pure int isinf(double x)         { return __isinf(x); }\n    pure int isinf(real x)           { return __isinfl(x); }\n\n    pure int isnan(float x)          { return __isnanf(x); }\n    pure int isnan(double x)         { return __isnan(x); }\n    pure int isnan(real x)           { return __isnanl(x); }\n\n    pure int isnormal(float x)       { return __isnormalf(x); }\n    pure int isnormal(double x)      { return __isnormal(x); }\n    pure int isnormal(real x)        { return __isnormall(x); }\n\n    pure int signbit(float x)        { return __signbitf(x); }\n    pure int signbit(double x)       { return __signbit(x); }\n    pure int signbit(real x)         { return __signbitl(x); }\n  }\n}\nelse version (Solaris)\n{\n    pure int __isnanf(float x);\n    pure int __isnan(double x);\n    pure int __isnanl(real x);\n\n  extern (D)\n  {\n    //int isnan(real-floating x);\n      ///\n    pure int isnan(float x)          { return __isnanf(x);  }\n    ///\n    pure int isnan(double x)         { return __isnan(x);   }\n    ///\n    pure int isnan(real x)\n    {\n        return (real.sizeof == double.sizeof)\n            ? __isnan(x)\n            : __isnanl(x);\n    }\n  }\n}\nelse version (CRuntime_Bionic)\n{\n    enum\n    {\n        ///\n        FP_INFINITE  = 0x01,\n        ///\n        FP_NAN       = 0x02,\n        ///\n        FP_NORMAL    = 0x04,\n        ///\n        FP_SUBNORMAL = 0x08,\n        ///\n        FP_ZERO      = 0x10,\n    }\n\n    ///\n    enum FP_FAST_FMAF;\n\n    pure int __fpclassifyd(double);\n    pure int __fpclassifyf(float);\n    pure int __fpclassifyl(real);\n\n    pure int __isfinitef(float);\n    pure int __isfinite(double);\n    pure int __isfinitel(real);\n\n    pure int __isinff(float);\n    pure int __isinf(double);\n    pure int __isinfl(real);\n\n    pure int isnanf(float);\n    pure int isnan(double);\n    pure int __isnanl(real);\n\n    pure int __isnormalf(float);\n    pure int __isnormal(double);\n    pure int __isnormall(real);\n\n    pure int __signbit(double);\n    pure int __signbitf(float);\n    pure int __signbitl(real);\n\n  extern (D)\n  {\n    //int fpclassify(real-floating x);\n      ///\n    pure int fpclassify(float x)     { return __fpclassifyf(x); }\n    ///\n    pure int fpclassify(double x)    { return __fpclassifyd(x); }\n    ///\n    pure int fpclassify(real x)      { return __fpclassifyl(x); }\n\n    //int isfinite(real-floating x);\n    ///\n    pure int isfinite(float x)       { return __isfinitef(x); }\n    ///\n    pure int isfinite(double x)      { return __isfinite(x); }\n    ///\n    pure int isfinite(real x)        { return __isfinitel(x); }\n\n    //int isinf(real-floating x);\n    ///\n    pure int isinf(float x)          { return __isinff(x); }\n    ///\n    pure int isinf(double x)         { return __isinf(x); }\n    ///\n    pure int isinf(real x)           { return __isinfl(x); }\n\n    //int isnan(real-floating x);\n    ///\n    pure int isnan(float x)          { return isnanf(x); }\n    ///\n    pure int isnan(real x)           { return __isnanl(x); }\n\n    //int isnormal(real-floating x);\n    ///\n    pure int isnormal(float x)       { return __isnormalf(x); }\n    ///\n    pure int isnormal(double x)      { return __isnormal(x); }\n    ///\n    pure int isnormal(real x)        { return __isnormall(x); }\n\n    //int signbit(real-floating x);\n    ///\n    pure int signbit(float x)        { return __signbitf(x); }\n    ///\n    pure int signbit(double x)       { return __signbit(x); }\n    ///\n    pure int signbit(real x)         { return __signbitl(x); }\n  }\n}\n\nextern (D)\n{\n    //int isgreater(real-floating x, real-floating y);\n    ///\n    pure int isgreater(float x, float y)        { return x > y && !isunordered(x, y); }\n    ///\n    pure int isgreater(double x, double y)      { return x > y && !isunordered(x, y); }\n    ///\n    pure int isgreater(real x, real y)          { return x > y && !isunordered(x, y); }\n\n    //int isgreaterequal(real-floating x, real-floating y);\n    ///\n    pure int isgreaterequal(float x, float y)   { return x >= y && !isunordered(x, y); }\n    ///\n    pure int isgreaterequal(double x, double y) { return x >= y && !isunordered(x, y); }\n    ///\n    pure int isgreaterequal(real x, real y)     { return x >= y && !isunordered(x, y); }\n\n    //int isless(real-floating x, real-floating y);\n    ///\n    pure int isless(float x, float y)           { return x < y && !isunordered(x, y); }\n    ///\n    pure int isless(double x, double y)         { return x < y && !isunordered(x, y); }\n    ///\n    pure int isless(real x, real y)             { return x < y && !isunordered(x, y); }\n\n    //int islessequal(real-floating x, real-floating y);\n    ///\n    pure int islessequal(float x, float y)      { return x <= y && !isunordered(x, y); }\n    ///\n    pure int islessequal(double x, double y)    { return x <= y && !isunordered(x, y); }\n    ///\n    pure int islessequal(real x, real y)        { return x <= y && !isunordered(x, y); }\n\n    //int islessgreater(real-floating x, real-floating y);\n    ///\n    pure int islessgreater(float x, float y)    { return x != y && !isunordered(x, y); }\n    ///\n    pure int islessgreater(double x, double y)  { return x != y && !isunordered(x, y); }\n    ///\n    pure int islessgreater(real x, real y)      { return x != y && !isunordered(x, y); }\n\n    //int isunordered(real-floating x, real-floating y);\n    ///\n    pure int isunordered(float x, float y)      { return isnan(x) || isnan(y); }\n    ///\n    pure int isunordered(double x, double y)    { return isnan(x) || isnan(y); }\n    ///\n    pure int isunordered(real x, real y)        { return isnan(x) || isnan(y); }\n}\n\n/* MS define some functions inline.\n * Additionally, their *l functions work with a 64-bit long double and are thus\n * useless for 80-bit D reals. So we use our own wrapper implementations working\n * internally with reduced 64-bit precision.\n * This also enables relaxing real to 64-bit double.\n */\nversion (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) only\n{\n    ///\n    double  acos(double x);\n    ///\n    float   acosf(float x);\n    ///\n    extern(D) real acosl()(real x)   { return acos(cast(double) x); }\n\n    ///\n    double  asin(double x);\n    ///\n    float   asinf(float x);\n    ///\n    extern(D) real asinl()(real x)   { return asin(cast(double) x); }\n\n    ///\n    pure double  atan(double x);\n    ///\n    pure float   atanf(float x);\n    ///\n    pure extern(D) real atanl()(real x)   { return atan(cast(double) x); }\n\n    ///\n    double  atan2(double y, double x);\n    ///\n    float   atan2f(float y, float x);\n    ///\n    extern(D) real atan2l()(real y, real x) { return atan2(cast(double) y, cast(double) x); }\n\n    ///\n    pure double  cos(double x);\n    ///\n    pure float   cosf(float x);\n    ///\n    extern(D) pure real cosl()(real x)    { return cos(cast(double) x); }\n\n    ///\n    pure double  sin(double x);\n    ///\n    pure float   sinf(float x);\n    ///\n    extern(D) pure real sinl()(real x)    { return sin(cast(double) x); }\n\n    ///\n    pure double  tan(double x);\n    ///\n    pure float   tanf(float x);\n    ///\n    extern(D) pure real tanl()(real x)    { return tan(cast(double) x); }\n\n    ///\n    double  acosh(double x);\n    ///\n    float   acoshf(float x);\n    ///\n    extern(D) real acoshl()(real x)  { return acosh(cast(double) x); }\n\n    ///\n    pure double  asinh(double x);\n    ///\n    pure float   asinhf(float x);\n    ///\n    pure extern(D) real asinhl()(real x)  { return asinh(cast(double) x); }\n\n    ///\n    double  atanh(double x);\n    ///\n    float   atanhf(float x);\n    ///\n    extern(D) real atanhl()(real x)  { return atanh(cast(double) x); }\n\n    ///\n    double  cosh(double x);\n    ///\n    float   coshf(float x);\n    ///\n    extern(D) real coshl()(real x)   { return cosh(cast(double) x); }\n\n    ///\n    double  sinh(double x);\n    ///\n    float   sinhf(float x);\n    ///\n    extern(D) real sinhl()(real x)   { return sinh(cast(double) x); }\n\n    ///\n    pure double  tanh(double x);\n    ///\n    pure float   tanhf(float x);\n    ///\n    extern(D) pure real tanhl()(real x)   { return tanh(cast(double) x); }\n\n    ///\n    double  exp(double x);\n    ///\n    float   expf(float x);\n    ///\n    extern(D) real expl()(real x)    { return exp(cast(double) x); }\n\n    ///\n    double  exp2(double x);\n    ///\n    float   exp2f(float x);\n    ///\n    extern(D) real exp2l()(real x)   { return exp2(cast(double) x); }\n\n    ///\n    double  expm1(double x);\n    ///\n    float   expm1f(float x);\n    ///\n    extern(D) real expm1l()(real x)  { return expm1(cast(double) x); }\n\n    ///\n    pure double  frexp(double value, int* exp);\n    ///\n    extern(D) pure float frexpf()(float value, int* exp) { return cast(float) frexp(value, exp); }\n    ///\n    extern(D) pure real  frexpl()(real value, int* exp)  { return frexp(cast(double) value, exp); }\n\n    ///\n    int     ilogb(double x);\n    ///\n    int     ilogbf(float x);\n    ///\n    extern(D) int ilogbl()(real x)   { return ilogb(cast(double) x); }\n\n    ///\n    double  ldexp(double x, int exp);\n    ///\n    extern(D) float ldexpf()(float x, int exp) { return cast(float) ldexp(x, exp); }\n    ///\n    extern(D) real  ldexpl()(real x, int exp)  { return ldexp(cast(double) x, exp); }\n\n    ///\n    double  log(double x);\n    ///\n    float   logf(float x);\n    ///\n    extern(D) real logl()(real x)    { return log(cast(double) x); }\n\n    ///\n    double  log10(double x);\n    ///\n    float   log10f(float x);\n    ///\n    extern(D) real log10l()(real x)  { return log10(cast(double) x); }\n\n    ///\n    double  log1p(double x);\n    ///\n    float   log1pf(float x);\n    ///\n    extern(D) real log1pl()(real x)  { return log1p(cast(double) x); }\n\n    ///\n    double  log2(double x);\n    ///\n    float   log2f(float x);\n    ///\n    extern(D) real log2l()(real x)   { return log2(cast(double) x); }\n\n    ///\n    double  logb(double x);\n    ///\n    float   logbf(float x);\n    ///\n    extern(D) real logbl()(real x)   { return logb(cast(double) x); }\n\n    ///\n    pure double  modf(double value, double* iptr);\n    ///\n    pure float   modff(float value, float* iptr);\n    ///\n    extern(D) pure real modfl()(real value, real* iptr)\n    {\n        double i;\n        double r = modf(cast(double) value, &i);\n        *iptr = i;\n        return r;\n    }\n\n    ///\n    double  scalbn(double x, int n);\n    ///\n    float   scalbnf(float x, int n);\n    ///\n    extern(D) real scalbnl()(real x, int n) { return scalbn(cast(double) x, n); }\n\n    ///\n    double  scalbln(double x, c_long n);\n    ///\n    float   scalblnf(float x, c_long n);\n    ///\n    extern(D) real scalblnl()(real x, c_long n) { return scalbln(cast(double) x, n); }\n\n    ///\n    pure double  cbrt(double x);\n    ///\n    pure float   cbrtf(float x);\n    ///\n    extern(D) pure real cbrtl()(real x)   { return cbrt(cast(double) x); }\n\n    ///\n    pure double  fabs(double x);\n    ///\n    extern(D) pure float fabsf()(float x) { return cast(float) fabs(x); }\n    ///\n    extern(D) pure real  fabsl()(real x)  { return fabs(cast(double) x); }\n\n    private double _hypot(double x, double y);\n    private float  _hypotf(float x, float y);\n    ///\n    extern(D) double hypot(double x, double y) { return _hypot(x, y); }\n    ///\n    extern(D) float  hypotf(float x, float y)  { return _hypotf(x, y); }\n    ///\n    extern(D) real   hypotl(real x, real y)    { return _hypot(cast(double) x, cast(double) y); }\n\n    ///\n    double  pow(double x, double y);\n    ///\n    float   powf(float x, float y);\n    ///\n    extern(D) real powl()(real x, real y) { return pow(cast(double) x, cast(double) y); }\n\n    ///\n    double  sqrt(double x);\n    ///\n    float   sqrtf(float x);\n    ///\n    extern(D) real sqrtl()(real x)   { return sqrt(cast(double) x); }\n\n    ///\n    pure double  erf(double x);\n    ///\n    pure float   erff(float x);\n    ///\n    extern(D) pure real erfl()(real x)    { return erf(cast(double) x); }\n\n    ///\n    double  erfc(double x);\n    ///\n    float   erfcf(float x);\n    ///\n    extern(D) real erfcl()(real x)   { return erfc(cast(double) x); }\n\n    ///\n    double  lgamma(double x);\n    ///\n    float   lgammaf(float x);\n    ///\n    extern(D) real lgammal()(real x) { return lgamma(cast(double) x); }\n\n    ///\n    double  tgamma(double x);\n    ///\n    float   tgammaf(float x);\n    ///\n    extern(D) real tgammal()(real x) { return tgamma(cast(double) x); }\n\n    ///\n    pure double  ceil(double x);\n    ///\n    pure float   ceilf(float x);\n    ///\n    extern(D) pure real ceill()(real x)   { return ceil(cast(double) x); }\n\n    ///\n    pure double  floor(double x);\n    ///\n    pure float   floorf(float x);\n    ///\n    extern(D) pure real floorl()(real x)  { return floor(cast(double) x); }\n\n    ///\n    pure double  nearbyint(double x);\n    ///\n    pure float   nearbyintf(float x);\n    ///\n    extern(D) pure real nearbyintl()(real x) { return nearbyint(cast(double) x); }\n\n    ///\n    pure double  rint(double x);\n    ///\n    pure float   rintf(float x);\n    ///\n    extern(D) pure real rintl()(real x)   { return rint(cast(double) x); }\n\n    ///\n    c_long  lrint(double x);\n    ///\n    c_long  lrintf(float x);\n    ///\n    extern(D) c_long lrintl()(real x) { return lrint(cast(double) x); }\n\n    ///\n    long    llrint(double x);\n    ///\n    long    llrintf(float x);\n    ///\n    extern(D) long llrintl()(real x) { return llrint(cast(double) x); }\n\n    ///\n    pure double  round(double x);\n    ///\n    pure float   roundf(float x);\n    ///\n    extern(D) pure real roundl()(real x)  { return round(cast(double) x); }\n\n    ///\n    c_long  lround(double x);\n    ///\n    c_long  lroundf(float x);\n    ///\n    extern(D) c_long lroundl()(real x) { return lround(cast(double) x); }\n\n    ///\n    long    llround(double x);\n    ///\n    long    llroundf(float x);\n    ///\n    extern(D) long llroundl()(real x) { return llround(cast(double) x); }\n\n    ///\n    pure double  trunc(double x);\n    ///\n    pure float   truncf(float x);\n    ///\n    extern(D) pure real truncl()(real x)  { return trunc(cast(double) x); }\n\n    ///\n    double  fmod(double x, double y);\n    ///\n    float   fmodf(float x, float y);\n    ///\n    extern(D) real fmodl()(real x, real y) { return fmod(cast(double) x, cast(double) y); }\n\n    ///\n    double  remainder(double x, double y);\n    ///\n    float   remainderf(float x, float y);\n    ///\n    extern(D) real remainderl()(real x, real y) { return remainder(cast(double) x, cast(double) y); }\n\n    ///\n    double  remquo(double x, double y, int* quo);\n    ///\n    float   remquof(float x, float y, int* quo);\n    ///\n    extern(D) real remquol()(real x, real y, int* quo) { return remquo(cast(double) x, cast(double) y, quo); }\n\n    ///\n    pure double  copysign(double x, double y);\n    ///\n    pure float   copysignf(float x, float y);\n    ///\n    extern(D) pure real copysignl()(real x, real y) { return copysign(cast(double) x, cast(double) y); }\n\n    ///\n    pure double  nan(char* tagp);\n    ///\n    pure float   nanf(char* tagp);\n    ///\n    extern(D) pure real nanl()(char* tagp) { return nan(tagp); }\n\n    ///\n    double  nextafter(double x, double y);\n    ///\n    float   nextafterf(float x, float y);\n    ///\n    extern(D) real nextafterl()(real x, real y) { return nextafter(cast(double) x, cast(double) y); }\n\n    ///\n    double  nexttoward(double x, real y);\n    ///\n    float   nexttowardf(float x, real y);\n    ///\n    extern(D) real nexttowardl()(real x, real y) { return nexttoward(cast(double) x, cast(double) y); }\n\n    ///\n    double  fdim(double x, double y);\n    ///\n    float   fdimf(float x, float y);\n    ///\n    extern(D) real fdiml()(real x, real y) { return fdim(cast(double) x, cast(double) y); }\n\n    ///\n    pure double  fmax(double x, double y);\n    ///\n    pure float   fmaxf(float x, float y);\n    ///\n    extern(D) pure real fmaxl()(real x, real y) { return fmax(cast(double) x, cast(double) y); }\n\n    ///\n    pure double  fmin(double x, double y);\n    ///\n    pure float   fminf(float x, float y);\n    ///\n    extern(D) pure real fminl()(real x, real y) { return fmin(cast(double) x, cast(double) y); }\n\n    ///\n    pure double  fma(double x, double y, double z);\n    ///\n    pure float   fmaf(float x, float y, float z);\n    ///\n    extern(D) pure real fmal()(real x, real y, real z) { return fma(cast(double) x, cast(double) y, cast(double) z); }\n}\n/* NOTE: freebsd < 8-CURRENT doesn't appear to support *l, but we can\n *       approximate.\n * A lot of them were added in 8.0-RELEASE, and so a lot of these workarounds\n * should then be removed.\n */\n// NOTE: FreeBSD 8.0-RELEASE doesn't support log2* nor these *l functions:\n//         acoshl, asinhl, atanhl, coshl, sinhl, tanhl, cbrtl, powl, expl,\n//         expm1l, logl, log1pl, log10l, erfcl, erfl, lgammal, tgammal;\n//       but we can approximate.\nelse version (FreeBSD)\n{\n  version (none) // < 8-CURRENT\n  {\n    real    acosl(real x) { return acos(x); }\n    real    asinl(real x) { return asin(x); }\n    pure real    atanl(real x) { return atan(x); }\n    real    atan2l(real y, real x) { return atan2(y, x); }\n    pure real    cosl(real x) { return cos(x); }\n    pure real    sinl(real x) { return sin(x); }\n    pure real    tanl(real x) { return tan(x); }\n    real    exp2l(real x) { return exp2(x); }\n    pure real    frexpl(real value, int* exp) { return frexp(value, exp); }\n    int     ilogbl(real x) { return ilogb(x); }\n    real    ldexpl(real x, int exp) { return ldexp(x, exp); }\n    real    logbl(real x) { return logb(x); }\n    //real    modfl(real value, real *iptr); // nontrivial conversion\n    real    scalbnl(real x, int n) { return scalbn(x, n); }\n    real    scalblnl(real x, c_long n) { return scalbln(x, n); }\n    pure real    fabsl(real x) { return fabs(x); }\n    real    hypotl(real x, real y) { return hypot(x, y); }\n    real    sqrtl(real x) { return sqrt(x); }\n    pure real    ceill(real x) { return ceil(x); }\n    pure real    floorl(real x) { return floor(x); }\n    pure real    nearbyintl(real x) { return nearbyint(x); }\n    pure real    rintl(real x) { return rint(x); }\n    c_long  lrintl(real x) { return lrint(x); }\n    pure real    roundl(real x) { return round(x); }\n    c_long  lroundl(real x) { return lround(x); }\n    long    llroundl(real x) { return llround(x); }\n    pure real    truncl(real x) { return trunc(x); }\n    real    fmodl(real x, real y) { return fmod(x, y); }\n    real    remainderl(real x, real y) { return remainder(x, y); }\n    real    remquol(real x, real y, int* quo) { return remquo(x, y, quo); }\n    pure real    copysignl(real x, real y) { return copysign(x, y); }\n//  pure double  nan(char* tagp);\n//  pure float   nanf(char* tagp);\n//  pure real    nanl(char* tagp);\n    real    nextafterl(real x, real y) { return nextafter(x, y); }\n    real    nexttowardl(real x, real y) { return nexttoward(x, y); }\n    real    fdiml(real x, real y) { return fdim(x, y); }\n    pure real    fmaxl(real x, real y) { return fmax(x, y); }\n    pure real    fminl(real x, real y) { return fmin(x, y); }\n    pure real    fmal(real x, real y, real z) { return fma(x, y, z); }\n  }\n  else\n  {\n    ///\n    real    acosl(real x);\n    ///\n    real    asinl(real x);\n    ///\n    pure real    atanl(real x);\n    ///\n    real    atan2l(real y, real x);\n    ///\n    pure real    cosl(real x);\n    ///\n    pure real    sinl(real x);\n    ///\n    pure real    tanl(real x);\n    ///\n    real    exp2l(real x);\n    ///\n    pure real    frexpl(real value, int* exp);\n    ///\n    int     ilogbl(real x);\n    ///\n    real    ldexpl(real x, int exp);\n    ///\n    real    logbl(real x);\n    ///\n    pure real    modfl(real value, real *iptr);\n    ///\n    real    scalbnl(real x, int n);\n    ///\n    real    scalblnl(real x, c_long n);\n    ///\n    pure real    fabsl(real x);\n    ///\n    real    hypotl(real x, real y);\n    ///\n    real    sqrtl(real x);\n    ///\n    pure real    ceill(real x);\n    ///\n    pure real    floorl(real x);\n    ///\n    pure real    nearbyintl(real x);\n    ///\n    pure real    rintl(real x);\n    ///\n    c_long  lrintl(real x);\n    ///\n    pure real    roundl(real x);\n    ///\n    c_long  lroundl(real x);\n    ///\n    long    llroundl(real x);\n    ///\n    pure real    truncl(real x);\n    ///\n    real    fmodl(real x, real y);\n    ///\n    real    remainderl(real x, real y);\n    ///\n    real    remquol(real x, real y, int* quo);\n    ///\n    pure real    copysignl(real x, real y);\n    ///\n    pure double  nan(char* tagp);\n    ///\n    pure float   nanf(char* tagp);\n    ///\n    pure real    nanl(char* tagp);\n    ///\n    real    nextafterl(real x, real y);\n    ///\n    real    nexttowardl(real x, real y);\n    ///\n    real    fdiml(real x, real y);\n    ///\n    pure real    fmaxl(real x, real y);\n    ///\n    pure real    fminl(real x, real y);\n    ///\n    pure real    fmal(real x, real y, real z);\n  }\n  ///\n    double  acos(double x);\n    ///\n    float   acosf(float x);\n\n    ///\n    double  asin(double x);\n    ///\n    float   asinf(float x);\n\n    ///\n    pure double  atan(double x);\n    ///\n    pure float   atanf(float x);\n\n    ///\n    double  atan2(double y, double x);\n    ///\n    float   atan2f(float y, float x);\n\n    ///\n    pure double  cos(double x);\n    ///\n    pure float   cosf(float x);\n\n    ///\n    pure double  sin(double x);\n    ///\n    pure float   sinf(float x);\n\n    ///\n    pure double  tan(double x);\n    ///\n    pure float   tanf(float x);\n\n    ///\n    double  acosh(double x);\n    ///\n    float   acoshf(float x);\n    ///\n    real    acoshl(real x) { return acosh(x); }\n\n    ///\n    pure double  asinh(double x);\n    ///\n    pure float   asinhf(float x);\n    ///\n    pure real    asinhl(real x) { return asinh(x); }\n\n    ///\n    double  atanh(double x);\n    ///\n    float   atanhf(float x);\n    ///\n    real    atanhl(real x) { return atanh(x); }\n\n    ///\n    double  cosh(double x);\n    ///\n    float   coshf(float x);\n    ///\n    real    coshl(real x) { return cosh(x); }\n\n    ///\n    double  sinh(double x);\n    ///\n    float   sinhf(float x);\n    ///\n    real    sinhl(real x) { return sinh(x); }\n\n    ///\n    pure double  tanh(double x);\n    ///\n    pure float   tanhf(float x);\n    ///\n    pure real    tanhl(real x) { return tanh(x); }\n\n    ///\n    double  exp(double x);\n    ///\n    float   expf(float x);\n    ///\n    real    expl(real x) { return exp(x); }\n\n    ///\n    double  exp2(double x);\n    ///\n    float   exp2f(float x);\n\n    ///\n    double  expm1(double x);\n    ///\n    float   expm1f(float x);\n    ///\n    real    expm1l(real x) { return expm1(x); }\n\n    ///\n    pure double  frexp(double value, int* exp);\n    ///\n    pure float   frexpf(float value, int* exp);\n\n    ///\n    int     ilogb(double x);\n    ///\n    int     ilogbf(float x);\n\n    ///\n    double  ldexp(double x, int exp);\n    ///\n    float   ldexpf(float x, int exp);\n\n    ///\n    double  log(double x);\n    ///\n    float   logf(float x);\n    ///\n    real    logl(real x) { return log(x); }\n\n    ///\n    double  log10(double x);\n    ///\n    float   log10f(float x);\n    ///\n    real    log10l(real x) { return log10(x); }\n\n    ///\n    double  log1p(double x);\n    ///\n    float   log1pf(float x);\n    ///\n    real    log1pl(real x) { return log1p(x); }\n\n    private enum real ONE_LN2 = 1 / 0x1.62e42fefa39ef358p-1L;\n    ///\n    double  log2(double x) { return log(x) * ONE_LN2; }\n    ///\n    float   log2f(float x) { return logf(x) * ONE_LN2; }\n    ///\n    real    log2l(real x)  { return logl(x) * ONE_LN2; }\n\n    ///\n    double  logb(double x);\n    ///\n    float   logbf(float x);\n\n    ///\n    pure double  modf(double value, double* iptr);\n    ///\n    pure float   modff(float value, float* iptr);\n\n    ///\n    double  scalbn(double x, int n);\n    ///\n    float   scalbnf(float x, int n);\n\n    ///\n    double  scalbln(double x, c_long n);\n    ///\n    float   scalblnf(float x, c_long n);\n\n    ///\n    pure double  cbrt(double x);\n    ///\n    pure float   cbrtf(float x);\n    ///\n    pure real    cbrtl(real x) { return cbrt(x); }\n\n    ///\n    pure double  fabs(double x);\n    ///\n    pure float   fabsf(float x);\n\n    ///\n    double  hypot(double x, double y);\n    ///\n    float   hypotf(float x, float y);\n\n    ///\n    double  pow(double x, double y);\n    ///\n    float   powf(float x, float y);\n    ///\n    real    powl(real x, real y) { return pow(x, y); }\n\n    ///\n    double  sqrt(double x);\n    ///\n    float   sqrtf(float x);\n\n    ///\n    pure double  erf(double x);\n    ///\n    pure float   erff(float x);\n    ///\n    pure real    erfl(real x) { return erf(x); }\n\n    ///\n    double  erfc(double x);\n    ///\n    float   erfcf(float x);\n    ///\n    real    erfcl(real x) { return erfc(x); }\n\n    ///\n    double  lgamma(double x);\n    ///\n    float   lgammaf(float x);\n    ///\n    real    lgammal(real x) { return lgamma(x); }\n\n    ///\n    double  tgamma(double x);\n    ///\n    float   tgammaf(float x);\n    ///\n    real    tgammal(real x) { return tgamma(x); }\n\n    ///\n    pure double  ceil(double x);\n    ///\n    pure float   ceilf(float x);\n\n    ///\n    pure double  floor(double x);\n    ///\n    pure float   floorf(float x);\n\n    ///\n    pure double  nearbyint(double x);\n    ///\n    pure float   nearbyintf(float x);\n\n    ///\n    pure double  rint(double x);\n    ///\n    pure float   rintf(float x);\n\n    ///\n    c_long  lrint(double x);\n    ///\n    c_long  lrintf(float x);\n\n    ///\n    long    llrint(double x);\n    ///\n    long    llrintf(float x);\n    ///\n    long    llrintl(real x) { return llrint(x); }\n\n    ///\n    pure double  round(double x);\n    ///\n    pure float   roundf(float x);\n\n    ///\n    c_long  lround(double x);\n    ///\n    c_long  lroundf(float x);\n\n    ///\n    long    llround(double x);\n    ///\n    long    llroundf(float x);\n\n    ///\n    pure double  trunc(double x);\n    ///\n    pure float   truncf(float x);\n\n    ///\n    double  fmod(double x, double y);\n    ///\n    float   fmodf(float x, float y);\n\n    ///\n    double  remainder(double x, double y);\n    ///\n    float   remainderf(float x, float y);\n\n    ///\n    double  remquo(double x, double y, int* quo);\n    ///\n    float   remquof(float x, float y, int* quo);\n\n    ///\n    pure double  copysign(double x, double y);\n    ///\n    pure float   copysignf(float x, float y);\n\n    ///\n    double  nextafter(double x, double y);\n    ///\n    float   nextafterf(float x, float y);\n\n    ///\n    double  nexttoward(double x, real y);\n    ///\n    float   nexttowardf(float x, real y);\n\n    ///\n    double  fdim(double x, double y);\n    ///\n    float   fdimf(float x, float y);\n\n    ///\n    pure double  fmax(double x, double y);\n    ///\n    pure float   fmaxf(float x, float y);\n\n    ///\n    pure double  fmin(double x, double y);\n    ///\n    pure float   fminf(float x, float y);\n\n    ///\n    pure double  fma(double x, double y, double z);\n    ///\n    pure float   fmaf(float x, float y, float z);\n}\nelse version (NetBSD)\n{\n\n    ///\n    real    acosl(real x);\n    ///\n    real    asinl(real x);\n    ///\n    pure real    atanl(real x);\n    ///\n    real    atan2l(real y, real x);\n    ///\n    pure real    cosl(real x);\n    ///\n    pure real    sinl(real x);\n    ///\n    pure real    tanl(real x);\n    ///\n    real    exp2l(real x);\n    ///\n    pure real    frexpl(real value, int* exp);\n    ///\n    int     ilogbl(real x);\n    ///\n    real    ldexpl(real x, int exp);\n    ///\n    real    logbl(real x);\n    ///\n    pure real    modfl(real value, real *iptr);\n    ///\n    real    scalbnl(real x, int n);\n    ///\n    real    scalblnl(real x, c_long n);\n    ///\n    pure real    fabsl(real x);\n    ///\n    real    hypotl(real x, real y);\n    ///\n    real    sqrtl(real x);\n    ///\n    pure real    ceill(real x);\n    ///\n    pure real    floorl(real x);\n    ///\n    pure real    nearbyintl(real x);\n    ///\n    pure real    rintl(real x);\n    ///\n    c_long  lrintl(real x) { return cast(c_long)rintl(x); }\n    ///\n    pure real    roundl(real x);\n    ///\n    c_long  lroundl(real x) { return cast(c_long)roundl(x);}\n    ///\n    long    llroundl(real x) { return cast(long)roundl(x);}\n    ///\n    pure real    truncl(real x);\n    ///\n    real    fmodl(real x, real y);\n    ///\n    real    remainderl(real x, real y)  { return remainder(x,y); }\n    ///\n    real    remquol(real x, real y, int* quo){ return remquo(x,y,quo); }\n    ///\n    pure real    copysignl(real x, real y);\n    ///\n    pure double  nan(char* tagp);\n    ///\n    pure float   nanf(char* tagp);\n    ///\n    pure real    nanl(char* tagp);\n    ///\n    real    nextafterl(real x, real y);\n    ///\n    real    nexttowardl(real x, real y) { return nexttoward(cast(double) x, cast(double) y); }\n    ///\n    real    fdiml(real x, real y);\n    ///\n    pure real    fmaxl(real x, real y);\n    ///\n    pure real    fminl(real x, real y);\n    ///\n    pure real    fmal(real x, real y, real z);\n\n    ///\n    double  acos(double x);\n    ///\n    float   acosf(float x);\n\n    ///\n    double  asin(double x);\n    ///\n    float   asinf(float x);\n\n    ///\n    pure double  atan(double x);\n    ///\n    pure float   atanf(float x);\n\n    ///\n    double  atan2(double y, double x);\n    ///\n    float   atan2f(float y, float x);\n\n    ///\n    pure double  cos(double x);\n    ///\n    pure float   cosf(float x);\n\n    ///\n    pure double  sin(double x);\n    ///\n    pure float   sinf(float x);\n\n    ///\n    pure double  tan(double x);\n    ///\n    pure float   tanf(float x);\n\n    ///\n    double  acosh(double x);\n    ///\n    float   acoshf(float x);\n    ///\n    real    acoshl(real x);\n\n    ///\n    pure double  asinh(double x);\n    ///\n    pure float   asinhf(float x);\n    ///\n    pure real    asinhl(real x);\n\n    ///\n    double  atanh(double x);\n    ///\n    float   atanhf(float x);\n    ///\n    real    atanhl(real x);\n\n    ///\n    double  cosh(double x);\n    ///\n    float   coshf(float x);\n    ///\n    real    coshl(real x);\n\n    ///\n    double  sinh(double x);\n    ///\n    float   sinhf(float x);\n    ///\n    real    sinhl(real x);\n\n    ///\n    pure double  tanh(double x);\n    ///\n    pure float   tanhf(float x);\n    ///\n    pure real    tanhl(real x);\n\n    ///\n    double  exp(double x);\n    ///\n    float   expf(float x);\n    ///\n    real    expl(real x);\n\n    ///\n    double  exp2(double x);\n    ///\n    float   exp2f(float x);\n\n    ///\n    double  expm1(double x);\n    ///\n    float   expm1f(float x);\n    ///\n    real    expm1l(real x)  { return expm1(cast(double) x); }\n\n    ///\n    pure double  frexp(double value, int* exp);\n    ///\n    pure float   frexpf(float value, int* exp);\n\n    ///\n    int     ilogb(double x);\n    ///\n    int     ilogbf(float x);\n\n    ///\n    double  ldexp(double x, int exp);\n    ///\n    float   ldexpf(float x, int exp);\n\n    ///\n    double  log(double x);\n    ///\n    float   logf(float x);\n    /// NetBSD has no logl. It is just alias log(double)\n    real    logl(real x)\n    {\n        if (x<0) return real.nan;\n        if (x==0) return -real.infinity;\n        if (isnan(x) || isinf(x)) return x;\n        real rs = 0;\n        if (x>double.max)\n        {\n            immutable MAX = log(double.max);\n            for (; x>double.max; x /= double.max)\n                rs += MAX;\n        }\n        else if (x<double.min_normal)\n        {\n            immutable MIN = log(double.min_normal);\n            for (; x<double.min_normal; x /= double.min_normal)\n                rs += MIN;\n        }\n        rs += log(x);\n        return rs;\n    }\n\n    ///\n    double  log10(double x);\n    ///\n    float   log10f(float x);\n    ///NetBSD has no log10l. It is just alias log(double)\n    real    log10l(real x)\n    {\n        if (x<0) return real.nan;\n        if (x==0) return -real.infinity;\n        if (isnan(x) || isinf(x)) return x;\n\n        real rs = 0;\n        if (x>double.max)\n        {\n            immutable MAX = log10(double.max);\n            for (; x>double.max; x /= double.max)\n                rs += MAX;\n        }\n        else if (x<double.min_normal)\n        {\n            immutable MIN = log10(double.min_normal);\n            for (; x<double.min_normal; x /= double.min_normal)\n                rs += MIN;\n        }\n        rs += log10(x);\n        return rs;\n    }\n\n\n    ///\n    double  log1p(double x);\n    ///\n    float   log1pf(float x);\n    ///\n    real    log1pl(real x) { return log1p(cast(double) x); }\n\n    private enum real ONE_LN2 = 1 / 0x1.62e42fefa39ef358p-1L;\n    ///\n    double  log2(double x) { return log(x) * ONE_LN2; }\n    ///\n    float   log2f(float x) { return logf(x) * ONE_LN2; }\n    ///\n    real    log2l(real x)  { return logl(x) * ONE_LN2; }\n\n    ///\n    double  logb(double x);\n    ///\n    float   logbf(float x);\n\n    ///\n    pure double  modf(double value, double* iptr);\n    ///\n    pure float   modff(float value, float* iptr);\n\n    ///\n    double  scalbn(double x, int n);\n    ///\n    float   scalbnf(float x, int n);\n\n    ///\n    double  scalbln(double x, c_long n);\n    ///\n    float   scalblnf(float x, c_long n);\n\n    ///\n    pure double  cbrt(double x);\n    ///\n    pure float   cbrtf(float x);\n    ///\n    pure real    cbrtl(real x);\n\n    ///\n    pure double  fabs(double x);\n    ///\n    pure float   fabsf(float x);\n\n    ///\n    double  hypot(double x, double y);\n    ///\n    float   hypotf(float x, float y);\n\n    ///\n    double  pow(double x, double y);\n    ///\n    float   powf(float x, float y);\n    ///\n    real    powl(real x, real y);\n\n    ///\n    double  sqrt(double x);\n    ///\n    float   sqrtf(float x);\n\n    ///\n    pure double  erf(double x);\n    ///\n    pure float   erff(float x);\n    ///\n    pure real    erfl(real x) { return erf(cast(double) x); }\n\n    ///\n    double  erfc(double x);\n    ///\n    float   erfcf(float x);\n    ///\n    real    erfcl(real x)  { return erfc(cast(double) x); }\n\n    ///\n    double  lgamma(double x);\n    ///\n    float   lgammaf(float x);\n    ///\n    real    lgammal(real x){ return lgamma(x); }\n\n    ///\n    double  tgamma(double x);\n    ///\n    float   tgammaf(float x);\n    ///\n    real    tgammal(real x){ return tgamma(cast(double) x); }\n\n    ///\n    pure double  ceil(double x);\n    ///\n    pure float   ceilf(float x);\n\n    ///\n    pure double  floor(double x);\n    ///\n    pure float   floorf(float x);\n\n    ///\n    pure double  nearbyint(double x);\n    ///\n    pure float   nearbyintf(float x);\n\n    ///\n    pure double  rint(double x);\n    ///\n    pure float   rintf(float x);\n\n    ///\n    c_long  lrint(double x);\n    ///\n    c_long  lrintf(float x);\n\n    ///\n    long    llrint(double x);\n    ///\n    long    llrintf(float x);\n    ///\n    long    llrintl(real x) { return cast(long)rintl(x); }\n\n    ///\n    pure double  round(double x);\n    ///\n    pure float   roundf(float x);\n\n    ///\n    c_long  lround(double x);\n    ///\n    c_long  lroundf(float x);\n\n    ///\n    long    llround(double x);\n    ///\n    long    llroundf(float x);\n\n    ///\n    pure double  trunc(double x);\n    ///\n    pure float   truncf(float x);\n\n    ///\n    double  fmod(double x, double y);\n    ///\n    float   fmodf(float x, float y);\n\n    ///\n    double  remainder(double x, double y);\n    ///\n    float   remainderf(float x, float y);\n\n    ///\n    double  remquo(double x, double y, int* quo);\n    ///\n    float   remquof(float x, float y, int* quo);\n\n    ///\n    pure double  copysign(double x, double y);\n    ///\n    pure float   copysignf(float x, float y);\n\n    ///\n    double  nextafter(double x, double y);\n    ///\n    float   nextafterf(float x, float y);\n\n    ///\n    double  nexttoward(double x, real y);\n    ///\n    float   nexttowardf(float x, real y);\n\n    ///\n    double  fdim(double x, double y);\n    ///\n    float   fdimf(float x, float y);\n\n    ///\n    pure double  fmax(double x, double y);\n    ///\n    pure float   fmaxf(float x, float y);\n\n    ///\n    pure double  fmin(double x, double y);\n    ///\n    pure float   fminf(float x, float y);\n\n    ///\n    pure double  fma(double x, double y, double z);\n    ///\n    pure float   fmaf(float x, float y, float z);\n}\nelse version (OpenBSD)\n{\n    ///\n    real    acosl(real x);\n    ///\n    real    asinl(real x);\n    ///\n    pure real    atanl(real x);\n    ///\n    real    atan2l(real y, real x);\n    ///\n    pure real    cosl(real x);\n    ///\n    pure real    sinl(real x);\n    ///\n    pure real    tanl(real x);\n    ///\n    real    acoshl(real x);\n    ///\n    pure real    asinhl(real x);\n    ///\n    real    atanhl(real x);\n    ///\n    real    coshl(real x);\n    ///\n    real    sinhl(real x);\n    ///\n    pure real    tanhl(real x);\n    ///\n    real    expl(real x);\n    ///\n    real    exp2l(real x);\n    ///\n    real    expm1l(real x);\n    ///\n    pure real    frexpl(real value, int* exp);\n    ///\n    int     ilogbl(real x);\n    ///\n    real    ldexpl(real x, int exp);\n    ///\n    real    logbl(real x);\n    ///\n    real    logb10l(real x);\n    ///\n    real    logb1pl(real x);\n    ///\n    real    logb2l(real x);\n    ///\n    real    logbl(real x);\n    ///\n    pure real    modfl(real value, real *iptr);\n    ///\n    real    scalbnl(real x, int n);\n    ///\n    real    scalblnl(real x, c_long n);\n    ///\n    pure real    cbrtl(real x);\n    ///\n    pure real    fabsl(real x);\n    ///\n    real    hypotl(real x, real y);\n    ///\n    real    powl(real x, real y);\n    ///\n    real    sqrtl(real x);\n    ///\n    pure real    ceill(real x);\n    ///\n    pure real    floorl(real x);\n    ///\n    pure real    nearbyintl(real x);\n    ///\n    pure real    rintl(real x);\n    ///\n    c_long  lrintl(real x);\n    ///\n    long    llrintl(real x);\n    ///\n    pure real    roundl(real x);\n    ///\n    c_long  lroundl(real x);\n    ///\n    long    llroundl(real x);\n    ///\n    pure real    truncl(real x);\n    ///\n    real    fmodl(real x, real y);\n    ///\n    real    remainderl(real x, real y);\n    ///\n    real    remquol(real x, real y, int* quo);\n    ///\n    pure real    copysignl(real x, real y);\n    ///\n    pure double  nan(char* tagp);\n    ///\n    pure float   nanf(char* tagp);\n    ///\n    pure real    nanl(char* tagp);\n    ///\n    real    nextafterl(real x, real y);\n    ///\n    real    nexttowardl(real x, real y);\n    ///\n    real    fdiml(real x, real y);\n    ///\n    pure real    fmaxl(real x, real y);\n    ///\n    pure real    fminl(real x, real y);\n    ///\n    pure real    fmal(real x, real y, real z);\n\n    ///\n    double  acos(double x);\n    ///\n    float   acosf(float x);\n\n    ///\n    double  asin(double x);\n    ///\n    float   asinf(float x);\n\n    ///\n    pure double  atan(double x);\n    ///\n    pure float   atanf(float x);\n\n    ///\n    double  atan2(double y, double x);\n    ///\n    float   atan2f(float y, float x);\n\n    ///\n    pure double  cos(double x);\n    ///\n    pure float   cosf(float x);\n\n    ///\n    pure double  sin(double x);\n    ///\n    pure float   sinf(float x);\n\n    ///\n    pure double  tan(double x);\n    ///\n    pure float   tanf(float x);\n\n    ///\n    double  acosh(double x);\n    ///\n    float   acoshf(float x);\n\n    ///\n    pure double  asinh(double x);\n    ///\n    pure float   asinhf(float x);\n\n    ///\n    double  atanh(double x);\n    ///\n    float   atanhf(float x);\n\n    ///\n    double  cosh(double x);\n    ///\n    float   coshf(float x);\n\n    ///\n    double  sinh(double x);\n    ///\n    float   sinhf(float x);\n\n    ///\n    pure double  tanh(double x);\n    ///\n    pure float   tanhf(float x);\n\n    ///\n    double  exp(double x);\n    ///\n    float   expf(float x);\n\n    ///\n    double  exp2(double x);\n    ///\n    float   exp2f(float x);\n    ///\n    real    exp2l(real x);\n\n    ///\n    double  expm1(double x);\n    ///\n    float   expm1f(float x);\n\n    ///\n    pure double  frexp(double value, int* exp);\n    ///\n    pure float   frexpf(float value, int* exp);\n\n    ///\n    int     ilogb(double x);\n    ///\n    int     ilogbf(float x);\n\n    ///\n    double  ldexp(double x, int exp);\n    ///\n    float   ldexpf(float x, int exp);\n\n    ///\n    double  log(double x);\n    ///\n    float   logf(float x);\n\n    ///\n    double  log10(double x);\n    ///\n    float   log10f(float x);\n\n    ///\n    double  log1p(double x);\n    ///\n    float   log1pf(float x);\n\n    ///\n    double  log2(double x);\n    ///\n    float   log2f(float x);\n    ///\n    real    log2l(real x);\n\n    ///\n    double  logb(double x);\n    ///\n    float   logbf(float x);\n\n    ///\n    pure double  modf(double value, double* iptr);\n    ///\n    pure float   modff(float value, float* iptr);\n\n    ///\n    double  scalbn(double x, int n);\n    ///\n    float   scalbnf(float x, int n);\n\n    ///\n    double  scalbln(double x, c_long n);\n    ///\n    float   scalblnf(float x, c_long n);\n\n    ///\n    pure double  cbrt(double x);\n    ///\n    pure float   cbrtf(float x);\n\n    ///\n    pure double  fabs(double x);\n    ///\n    pure float   fabsf(float x);\n\n    ///\n    double  hypot(double x, double y);\n    ///\n    float   hypotf(float x, float y);\n\n    ///\n    double  pow(double x, double y);\n    ///\n    float   powf(float x, float y);\n\n    ///\n    double  sqrt(double x);\n    ///\n    float   sqrtf(float x);\n\n    ///\n    pure double  erf(double x);\n    ///\n    pure float   erff(float x);\n    ///\n    pure real    erfl(real x);\n\n    ///\n    double  erfc(double x);\n    ///\n    float   erfcf(float x);\n    ///\n    real    erfcl(real x);\n\n    ///\n    double  lgamma(double x);\n    ///\n    float   lgammaf(float x);\n    ///\n    real    lgammal(real x);\n\n    ///\n    double  tgamma(double x);\n    ///\n    float   tgammaf(float x);\n    ///\n    real    tgammal(real x);\n\n    ///\n    pure double  ceil(double x);\n    ///\n    pure float   ceilf(float x);\n\n    ///\n    pure double  floor(double x);\n    ///\n    pure float   floorf(float x);\n\n    ///\n    pure double  nearbyint(double x);\n    ///\n    pure float   nearbyintf(float x);\n\n    ///\n    pure double  rint(double x);\n    ///\n    pure float   rintf(float x);\n\n    ///\n    c_long  lrint(double x);\n    ///\n    c_long  lrintf(float x);\n\n    ///\n    long    llrint(double x);\n    ///\n    long    llrintf(float x);\n\n    ///\n    pure double  round(double x);\n    ///\n    pure float   roundf(float x);\n\n    ///\n    c_long  lround(double x);\n    ///\n    c_long  lroundf(float x);\n\n    ///\n    long    llround(double x);\n    ///\n    long    llroundf(float x);\n\n    ///\n    pure double  trunc(double x);\n    ///\n    pure float   truncf(float x);\n\n    ///\n    double  fmod(double x, double y);\n    ///\n    float   fmodf(float x, float y);\n\n    ///\n    double  remainder(double x, double y);\n    ///\n    float   remainderf(float x, float y);\n\n    ///\n    double  remquo(double x, double y, int* quo);\n    ///\n    float   remquof(float x, float y, int* quo);\n\n    ///\n    pure double  copysign(double x, double y);\n    ///\n    pure float   copysignf(float x, float y);\n\n    ///\n    double  nextafter(double x, double y);\n    ///\n    float   nextafterf(float x, float y);\n\n    ///\n    double  nexttoward(double x, real y);\n    ///\n    float   nexttowardf(float x, real y);\n\n    ///\n    double  fdim(double x, double y);\n    ///\n    float   fdimf(float x, float y);\n\n    ///\n    pure double  fmax(double x, double y);\n    ///\n    pure float   fmaxf(float x, float y);\n\n    ///\n    pure double  fmin(double x, double y);\n    ///\n    pure float   fminf(float x, float y);\n\n    ///\n    pure double  fma(double x, double y, double z);\n    ///\n    pure float   fmaf(float x, float y, float z);\n}\nelse version (DragonFlyBSD)\n{\n    /* double */\n    double acos(double x);\n    double asin(double x);\n    pure double atan(double x);\n    double atan2(double, double);\n    pure double cos(double x);\n    pure double sin(double x);\n    pure double tan(double x);\n\n    double cosh(double x);\n    double sinh(double x);\n    pure double tanh(double x);\n\n    double exp(double x);\n    pure double frexp(double, int *exp);\n    double ldexp(double, int exp);\n    double log(double x);\n    double log10(double x);\n    pure double modf(double x, double *iptr);\n\n    double pow(double x, double y);\n    double sqrt(double x);\n\n    pure double ceil(double x);\n    pure double fabs(double x);\n    pure double floor(double x);\n    double fmod(double x, double);\n\n    double acosh(double x);\n    pure double asinh(double x);\n    double atanh(double x);\n\n    double exp2(double x);\n    double expm1(double x);\n    int ilogb(double x);\n    double log1p(double x);\n    double log2(double x);\n    double logb(double x);\n    double scalbn(double x, int n);\n    double scalbln(double x, c_long n);\n\n    pure double cbrt(double x);\n    double hypot(double x, double y);\n\n    pure double erf(double x);\n    double erfc(double x);\n    double lgamma(double x);\n    double tgamma(double x);\n\n    pure double nearbyint(double x);\n    pure double rint(double x);\n    c_long lrint(double x);\n    long llrint(double x);\n    pure double round(double x);\n    c_long lround(double x);\n    long  llround(double x);\n    pure double trunc(double x);\n\n    double remainder(double x , double y);\n    double remquo(double x, double y, int * quo);\n\n    pure double copysign(double x, double y);\n    pure double nan(const char *);\n    double nextafter(double x, double y);\n    double nexttoward(double x, real y);\n\n    double fdim(double x, double y);\n    pure double fmax(double x, double y);\n    pure double fmin(double x, double y);\n\n    pure double fma(double x, double y, double z);\n\n    double j0(double x);\n    double j1(double x);\n    double jn(int, double);\n    double y0(double x);\n    double y1(double x);\n    double yn(int, double);\n\n    double gamma(double x);\n    double scalb(double x, double y);\n\n    double drem(double x, double y);\n    int finite(double x);\n    double gamma_r(double x, int *);\n    double lgamma_r(double x, int *);\n\n    double significand(double x);\n\n    /* float */\n    float acosf(float x);\n    float asinf(float x);\n    pure float atanf(float x);\n    float atan2f(float x, float y);\n    pure float cosf(float x);\n    pure float sinf(float x);\n    pure float tanf(float x);\n\n    float acoshf(float x);\n    pure float asinhf(float x);\n    float atanhf(float x);\n    float coshf(float x);\n    float sinhf(float x);\n    pure float tanhf(float x);\n\n    float expf(float x);\n    float exp2f(float x);\n    float expm1f(float x);\n    pure float frexpf(float x, int *exp);\n    int ilogbf(float x);\n    float ldexpf(float x, int exp);\n    float logf(float x);\n    float log10f(float x);\n    float log1pf(float x);\n    float log2f(float x);\n    float logbf(float x);\n    pure float modff(float x, float *iptr);\n    float scalbnf(float x, int y);\n    float scalblnf(float x, c_long y);\n\n    pure float cbrtf(float x);\n    pure float fabsf(float x);\n    float hypotf(float x, float y);\n    float powf(float x, float y);\n    float sqrtf(float x);\n\n    pure float erff(float x);\n    float erfcf(float x);\n    float lgammaf(float x);\n    float tgammaf(float x);\n\n    pure float ceilf(float x);\n    pure float floorf(float x);\n    pure float nearbyintf(float x);\n    pure float rintf(float x);\n    c_long lrintf(float x);\n    long llrintf(float x);\n    pure float roundf(float x);\n    c_long lroundf(float x);\n    long llroundf(float x);\n    pure float truncf(float x);\n\n    pure float fmodf(float x, float y);\n    float remainderf(float x, float y);\n    float remquof(float x, float y, int *iptr);\n\n    pure float copysignf(float x, float y);\n    pure float nanf(const char *);\n    float nextafterf(float x, float y);\n    float nexttowardf(float x, real y);\n\n    float fdimf(float x, float y);\n    pure float fmaxf(float x, float y);\n    pure float fminf(float x, float y);\n\n    pure float fmaf(float x, float y, float z);\n\n    float j0f(float x);\n    float j1f(float x);\n    float jnf(int, float);\n    float scalbf(float x, float);\n    float y0f(float x);\n    float y1f(float x);\n    float ynf(int, float);\n    float gammaf(float x);\n    float dremf(float x, float);\n    pure int finitef(float x);\n    pure int isinff(float x);\n    pure int isnanf(float x);\n\n    float gammaf_r(float x, int *);\n    float lgammaf_r(float x, int *);\n    float significandf(float x);\n\n    /* real */\n    pure real acosl(real x);\n    pure real asinl(real x);\n    pure real atanl(real x);\n    real atan2l(real x, real y);\n    pure real cosl(real x);\n    pure real sinl(real x);\n    pure real tanl(real x);\n\n    real acoshl(real x);\n    pure real asinhl(real x);\n    real atanhl(real x);\n    real coshl(real x);\n    real sinhl(real x);\n    pure real tanhl(real x);\n\n    real expl(real x);\n    real exp2l(real x);\n    real expm1l(real x);\n    pure real frexpl(real x, int *exp);\n    int ilogbl(real x);\n    real ldexpl(real x, int exp);\n    real logl(real x);\n    real log10l(real x);\n    real log1pl(real x);\n    real log2l(real x);\n    real logbl(real x);\n    pure real modfl(real x, real *iptr);\n    real scalbnl(real x, int y);\n    real scalblnl(real x, c_long y);\n\n    pure real cbrtl(real x);\n    pure real fabsl(real x);\n    real hypotl(real x, real y);\n    real powl(real x, real y);\n    real sqrtl(real x);\n\n    pure real erfl(real x);\n    real erfcl(real x);\n    real lgammal(real x);\n    real tgammal(real x);\n\n    pure real ceill(real x);\n    pure real floorl(real x);\n    pure real nearbyintl(real x);\n    pure real rintl(real x);\n    c_long lrintl(real x);\n    long llrintl(real x);\n    pure real roundl(real x);\n    c_long lroundl(real x);\n    long llroundl(real x);\n    pure real truncl(real x);\n\n    pure real fmodl(real x, real);\n    pure real remainderl(real x, real);\n    pure real remquol(real x, real y, int *iptr);\n\n    pure real copysignl(real x, real y);\n    pure real nanl(const char *);\n    real nextafterl(real x, real y);\n    real nexttowardl(real x, real y);\n\n    real fdiml(real x, real y);\n    pure real fmaxl(real x, real y);\n    pure real fminl(real x, real y);\n\n    pure real fmal(real x, real, real);\n}\nelse version (CRuntime_Bionic)\n{\n    ///\n    double  acos(double x);\n    ///\n    float   acosf(float x);\n    /// Added since Lollipop\n    real    acosl(real x);\n\n    ///\n    double  asin(double x);\n    ///\n    float   asinf(float x);\n    /// Added since Lollipop\n    real    asinl(real x);\n\n    ///\n    pure double  atan(double x);\n    ///\n    pure float   atanf(float x);\n    /// Added since Lollipop\n    pure real    atanl(real x);\n\n    ///\n    double  atan2(double y, double x);\n    ///\n    float   atan2f(float y, float x);\n    /// Added since Lollipop\n    real    atan2l(real y, real x);\n\n    ///\n    pure double  cos(double x);\n    ///\n    pure float   cosf(float x);\n    ///\n    pure real    cosl(real x);\n\n    ///\n    pure double  sin(double x);\n    ///\n    pure float   sinf(float x);\n    /// Added since Lollipop\n    pure real    sinl(real x);\n\n    ///\n    pure double  tan(double x);\n    ///\n    pure float   tanf(float x);\n    /// Added since Lollipop\n    pure real    tanl(real x);\n\n    ///\n    double  acosh(double x);\n    ///\n    float   acoshf(float x);\n    /// Added since Lollipop\n    real    acoshl(real x);\n\n    ///\n    pure double  asinh(double x);\n    ///\n    pure float   asinhf(float x);\n    /// Added since Lollipop\n    pure real    asinhl(real x);\n\n    ///\n    double  atanh(double x);\n    ///\n    float   atanhf(float x);\n    /// Added since Lollipop\n    real    atanhl(real x);\n\n    ///\n    double  cosh(double x);\n    ///\n    float   coshf(float x);\n    /// Added since Lollipop\n    real    coshl(real x);\n\n    ///\n    double  sinh(double x);\n    ///\n    float   sinhf(float x);\n    /// Added since Lollipop\n    real    sinhl(real x);\n\n    ///\n    pure double  tanh(double x);\n    ///\n    pure float   tanhf(float x);\n    /// Added since Lollipop\n    pure real    tanhl(real x);\n\n    ///\n    double  exp(double x);\n    ///\n    float   expf(float x);\n    ///\n    real    expl(real x);\n\n    ///\n    double  exp2(double x);\n    ///\n    float   exp2f(float x);\n    /// Added since Lollipop\n    real    exp2l(real x);\n\n    ///\n    double  expm1(double x);\n    ///\n    float   expm1f(float x);\n    /// Added since Lollipop\n    real    expm1l(real x);\n\n    ///\n    pure double  frexp(double value, int* exp);\n    ///\n    pure float   frexpf(float value, int* exp);\n    /// Added since Lollipop\n    pure real    frexpl(real value, int* exp);\n\n    ///\n    int     ilogb(double x);\n    ///\n    int     ilogbf(float x);\n    ///\n    int     ilogbl(real x);\n\n    ///\n    double  ldexp(double x, int exp);\n    ///\n    float   ldexpf(float x, int exp);\n    ///\n    real    ldexpl(real x, int exp);\n\n    ///\n    double  log(double x);\n    ///\n    float   logf(float x);\n    /// Added since Lollipop\n    real    logl(real x);\n\n    ///\n    double  log10(double x);\n    ///\n    float   log10f(float x);\n    /// Added since Lollipop\n    real    log10l(real x);\n\n    ///\n    double  log1p(double x);\n    ///\n    float   log1pf(float x);\n    /// Added since Lollipop\n    real    log1pl(real x);\n\n    ///\n    double  log2(double x);\n    ///\n    float   log2f(float x);\n    ///\n    real    log2l(real x);\n\n    ///\n    double  logb(double x);\n    ///\n    float   logbf(float x);\n    ///\n    real    logbl(real x);\n\n    ///\n    pure double  modf(double value, double* iptr);\n    ///\n    pure float   modff(float value, float* iptr);\n    /// Added since Lollipop\n    pure real    modfl(real value, real *iptr);\n\n    ///\n    double  scalbn(double x, int n);\n    ///\n    float   scalbnf(float x, int n);\n    ///\n    real    scalbnl(real x, int n);\n\n    ///\n    double  scalbln(double x, c_long n);\n    ///\n    float   scalblnf(float x, c_long n);\n    ///\n    real    scalblnl(real x, c_long n);\n\n    ///\n    pure double  cbrt(double x);\n    ///\n    pure float   cbrtf(float x);\n    /// Added since Lollipop\n    pure real    cbrtl(real x);\n\n    ///\n    pure double  fabs(double x);\n    ///\n    pure float   fabsf(float x);\n    ///\n    pure real    fabsl(real x);\n\n    ///\n    double  hypot(double x, double y);\n    ///\n    float   hypotf(float x, float y);\n    /// Added since Lollipop\n    real    hypotl(real x, real y);\n\n    ///\n    double  pow(double x, double y);\n    ///\n    float   powf(float x, float y);\n    /// Added since Lollipop\n    real    powl(real x, real y);\n\n    ///\n    double  sqrt(double x);\n    ///\n    float   sqrtf(float x);\n    /// Added since Lollipop\n    real    sqrtl(real x);\n\n    ///\n    pure double  erf(double x);\n    ///\n    pure float   erff(float x);\n    /// Added since Lollipop\n    pure real    erfl(real x);\n\n    ///\n    double  erfc(double x);\n    ///\n    float   erfcf(float x);\n    /// Added since Lollipop\n    real    erfcl(real x);\n\n    ///\n    double  lgamma(double x);\n    ///\n    float   lgammaf(float x);\n    /// Added since Lollipop\n    real    lgammal(real x);\n\n    ///\n    double  tgamma(double x);\n    ///\n    float   tgammaf(float x);\n    /// Added since Lollipop\n    real    tgammal(real x);\n\n    ///\n    pure double  ceil(double x);\n    ///\n    pure float   ceilf(float x);\n    ///\n    pure real    ceill(real x);\n\n    ///\n    pure double  floor(double x);\n    ///\n    pure float   floorf(float x);\n    ///\n    pure real    floorl(real x);\n\n    ///\n    pure double  nearbyint(double x);\n    ///\n    pure float   nearbyintf(float x);\n    /// Added since Lollipop\n    pure real    nearbyintl(real x);\n\n    ///\n    pure double  rint(double x);\n    ///\n    pure float   rintf(float x);\n    /// Added since Lollipop\n    pure real    rintl(real x);\n\n    ///\n    c_long  lrint(double x);\n    ///\n    c_long  lrintf(float x);\n    /// Added since Lollipop\n    c_long  lrintl(real x);\n\n    ///\n    long    llrint(double x);\n    ///\n    long    llrintf(float x);\n    /// Added since Lollipop\n    long    llrintl(real x);\n\n    ///\n    pure double  round(double x);\n    ///\n    pure float   roundf(float x);\n    ///\n    pure real    roundl(real x);\n\n    ///\n    c_long  lround(double x);\n    ///\n    c_long  lroundf(float x);\n    ///\n    c_long  lroundl(real x);\n\n    ///\n    long    llround(double x);\n    ///\n    long    llroundf(float x);\n    ///\n    long    llroundl(real x);\n\n    ///\n    pure double  trunc(double x);\n    ///\n    pure float   truncf(float x);\n    ///\n    pure real    truncl(real x);\n\n    ///\n    double  fmod(double x, double y);\n    ///\n    float   fmodf(float x, float y);\n    /// Added since Lollipop\n    real    fmodl(real x, real y);\n\n    ///\n    double  remainder(double x, double y);\n    ///\n    float   remainderf(float x, float y);\n    /// Added since Lollipop\n    real    remainderl(real x, real y);\n\n    ///\n    double  remquo(double x, double y, int* quo);\n    ///\n    float   remquof(float x, float y, int* quo);\n    /// Added since Lollipop\n    real    remquol(real x, real y, int* quo);\n\n    ///\n    pure double  copysign(double x, double y);\n    ///\n    pure float   copysignf(float x, float y);\n    ///\n    pure real    copysignl(real x, real y);\n\n    ///\n    pure double  nan(char* tagp);\n    ///\n    pure float   nanf(char* tagp);\n    ///\n    pure real    nanl(char* tagp);\n\n    ///\n    double  nextafter(double x, double y);\n    ///\n    float   nextafterf(float x, float y);\n    /// Added since Lollipop\n    real    nextafterl(real x, real y);\n\n    ///\n    double  nexttoward(double x, real y);\n    ///\n    float   nexttowardf(float x, real y);\n    ///\n    real    nexttowardl(real x, real y);\n\n    ///\n    double  fdim(double x, double y);\n    ///\n    float   fdimf(float x, float y);\n    ///\n    real    fdiml(real x, real y);\n\n    ///\n    pure double  fmax(double x, double y);\n    ///\n    pure float   fmaxf(float x, float y);\n    ///\n    pure real    fmaxl(real x, real y);\n\n    ///\n    pure double  fmin(double x, double y);\n    ///\n    pure float   fminf(float x, float y);\n    ///\n    pure real    fminl(real x, real y);\n\n    ///\n    pure double  fma(double x, double y, double z);\n    ///\n    pure float   fmaf(float x, float y, float z);\n    /// Added since Lollipop\n    pure real    fmal(real x, real y, real z);\n}\nelse version (CRuntime_UClibc)\n{\n    // uClibc wraps 'long double' to double, so we do the same for 'real'\n\n    ///\n    double  acos(double x);\n    ///\n    float   acosf(float x);\n    ///\n    real    acosl(real x) { return acos(cast(double) x); }\n\n    ///\n    double  asin(double x);\n    ///\n    float   asinf(float x);\n    ///\n    real    asinl(real x) { return asin(cast(double) x); }\n\n    ///\n    pure double  atan(double x);\n    ///\n    pure float   atanf(float x);\n    ///\n    pure real    atanl(real x) { return atan(cast(double) x); }\n\n    ///\n    double  atan2(double y, double x);\n    ///\n    float   atan2f(float y, float x);\n    ///\n    real    atan2l(real y, real x) { return atan2(cast(double) x, cast(double) y); }\n\n    ///\n    pure double  cos(double x);\n    ///\n    pure float   cosf(float x);\n    ///\n    pure real    cosl(real x) { return cos(cast(double) x); }\n\n    ///\n    pure double  sin(double x);\n    ///\n    pure float   sinf(float x);\n    ///\n    pure real    sinl(real x) { return sin(cast(double) x); }\n\n    ///\n    pure double  tan(double x);\n    ///\n    pure float   tanf(float x);\n    ///\n    pure real    tanl(real x) { return tan(cast(double) x); }\n\n    ///\n    double  acosh(double x);\n    ///\n    float   acoshf(float x);\n    ///\n    real    acoshl(real x) { return acosh(cast(double) x); }\n\n    ///\n    pure double  asinh(double x);\n    ///\n    pure float   asinhf(float x);\n    ///\n    pure real    asinhl(real x) { return asinh(cast(double) x); }\n\n    ///\n    double  atanh(double x);\n    ///\n    float   atanhf(float x);\n    ///\n    real    atanhl(real x) { return atanh(cast(double) x); }\n\n    ///\n    double  cosh(double x);\n    ///\n    float   coshf(float x);\n    ///\n    real    coshl(real x) { return cosh(cast(double) x); }\n\n    ///\n    double  sinh(double x);\n    ///\n    float   sinhf(float x);\n    ///\n    real    sinhl(real x) { return sinh(cast(double) x); }\n\n    ///\n    double  tanh(double x);\n    ///\n    float   tanhf(float x);\n    ///\n    real    tanhl(real x) { return tanh(cast(double) x); }\n\n    ///\n    double  exp(double x);\n    ///\n    float   expf(float x);\n    ///\n    real    expl(real x) { return exp(cast(double) x); }\n\n    ///\n    double  exp2(double x);\n    ///\n    float   exp2f(float x);\n    ///\n    real    exp2l(real x) { return exp2(cast(double) x); }\n\n    ///\n    double  expm1(double x);\n    ///\n    float   expm1f(float x);\n    ///\n    real    expm1l(real x) { return expm1(cast(double) x); }\n\n    ///\n    pure double  frexp(double value, int* exp);\n    ///\n    pure float   frexpf(float value, int* exp);\n    ///\n    pure real    frexpl(real value, int* exp) { return frexp(cast(double) value, exp); }\n\n    ///\n    int     ilogb(double x);\n    ///\n    int     ilogbf(float x);\n    ///\n    int     ilogbl(real x) { return ilogb(cast(double) x); }\n\n    ///\n    double  ldexp(double x, int exp);\n    ///\n    float   ldexpf(float x, int exp);\n    ///\n    real    ldexpl(real x, int exp) { return ldexp(cast(double) x, exp); }\n\n    ///\n    double  log(double x);\n    ///\n    float   logf(float x);\n    ///\n    real    logl(real x) { return log(cast(double) x); }\n\n    ///\n    double  log10(double x);\n    ///\n    float   log10f(float x);\n    ///\n    real    log10l(real x) { return log10(cast(double) x); }\n\n    ///\n    double  log1p(double x);\n    ///\n    float   log1pf(float x);\n    ///\n    real    log1pl(real x) { return log1p(cast(double) x); }\n\n    ///\n    double  log2(double x);\n    ///\n    float   log2f(float x);\n    ///\n    real    log2l(real x) { return log2(cast(double) x); }\n\n    ///\n    double  logb(double x);\n    ///\n    float   logbf(float x);\n    ///\n    real    logbl(real x) { return logb(cast(double) x); }\n\n    ///\n    pure double  modf(double value, double* iptr);\n    ///\n    pure float   modff(float value, float* iptr);\n    ///\n    pure real    modfl(real value, real *iptr) { return modf(cast(double) value, cast(double*) iptr); }\n\n    ///\n    double  scalbn(double x, int n);\n    ///\n    float   scalbnf(float x, int n);\n    ///\n    real    scalbnl(real x, int n) { return scalbln(cast(double) x, n); }\n\n    ///\n    double  scalbln(double x, c_long n);\n    ///\n    float   scalblnf(float x, c_long n);\n    ///\n    real    scalblnl(real x, c_long n) { return scalbln(cast(double) x, n); }\n\n    ///\n    pure double  cbrt(double x);\n    ///\n    pure float   cbrtf(float x);\n    ///\n    pure real    cbrtl(real x) { return cbrt(cast(double) x); }\n\n    ///\n    pure double  fabs(double x);\n    ///\n    pure float   fabsf(float x);\n    ///\n    pure real    fabsl(real x) { return fabs(cast(double) x); }\n\n    ///\n    double  hypot(double x, double y);\n    ///\n    float   hypotf(float x, float y);\n    ///\n    real    hypotl(real x, real y) { return hypot(cast(double) x, cast(double) y); }\n\n    ///\n    double  pow(double x, double y);\n    ///\n    float   powf(float x, float y);\n    ///\n    real    powl(real x, real y) { return pow(cast(double) x, cast(double) y); }\n\n    ///\n    double  sqrt(double x);\n    ///\n    float   sqrtf(float x);\n    ///\n    real    sqrtl(real x) { return sqrt(cast(double) x); }\n\n    ///\n    pure double  erf(double x);\n    ///\n    pure float   erff(float x);\n    ///\n    pure real    erfl(real x) { return erf(cast(double) x); }\n\n    ///\n    double  erfc(double x);\n    ///\n    float   erfcf(float x);\n    ///\n    real    erfcl(real x) { return erfc(cast(double) x); }\n\n    ///\n    double  lgamma(double x);\n    ///\n    float   lgammaf(float x);\n    ///\n    real    lgammal(real x) { return lgamma(cast(double) x); }\n\n    ///\n    double  tgamma(double x);\n    ///\n    float   tgammaf(float x);\n    ///\n    real    tgammal(real x) { return tgamma(cast(double) x); }\n\n    ///\n    pure double  ceil(double x);\n    ///\n    pure float   ceilf(float x);\n    ///\n    pure real    ceill(real x) { return ceil(cast(double) x); }\n\n    ///\n    pure double  floor(double x);\n    ///\n    pure float   floorf(float x);\n    ///\n    pure real    floorl(real x) { return floor(cast(double) x); }\n\n    ///\n    pure double  nearbyint(double x);\n    ///\n    pure float   nearbyintf(float x);\n    ///\n    pure real    nearbyintl(real x) { return nearbyint(cast(double) x); }\n\n    ///\n    pure double  rint(double x);\n    ///\n    pure float   rintf(float x);\n    ///\n    pure real    rintl(real x) { return rint(cast(double) x); }\n\n    ///\n    c_long  lrint(double x);\n    ///\n    c_long  lrintf(float x);\n    ///\n    c_long  lrintl(real x) { return lrint(cast(double) x); }\n\n    ///\n    long    llrint(double x);\n    ///\n    long    llrintf(float x);\n    ///\n    long    llrintl(real x) { return llrint(cast(double) x); }\n\n    ///\n    pure double  round(double x);\n    ///\n    pure float   roundf(float x);\n    ///\n    pure real    roundl(real x) { return round(cast(double) x); }\n\n    ///\n    c_long  lround(double x);\n    ///\n    c_long  lroundf(float x);\n    ///\n    c_long  lroundl(real x) { return lround(cast(double) x); }\n\n    ///\n    long    llround(double x);\n    ///\n    long    llroundf(float x);\n    ///\n    long    llroundl(real x) { return llround(cast(double) x); }\n\n    ///\n    pure double  trunc(double x);\n    ///\n    pure float   truncf(float x);\n    ///\n    pure real    truncl(real x) { return trunc(cast(double) x); }\n\n    ///\n    double  fmod(double x, double y);\n    ///\n    float   fmodf(float x, float y);\n    ///\n    real    fmodl(real x, real y) { return fmod(cast(double) x, cast(double) y); }\n\n    ///\n    double  remainder(double x, double y);\n    ///\n    float   remainderf(float x, float y);\n    ///\n    real    remainderl(real x, real y) { return remainder(cast(double) x, cast(double) y); }\n\n    ///\n    double  remquo(double x, double y, int* quo);\n    ///\n    float   remquof(float x, float y, int* quo);\n    ///\n    real    remquol(real x, real y, int* quo) { return remquo(cast(double) x, cast(double) y, quo); }\n\n    ///\n    pure double  copysign(double x, double y);\n    ///\n    pure float   copysignf(float x, float y);\n    ///\n    pure real    copysignl(real x, real y) { return copysign(cast(double) x, cast(double) y); }\n\n    ///\n    pure double  nan(char* tagp);\n    ///\n    pure float   nanf(char* tagp);\n    ///\n    pure real    nanl(char* tagp) { return nan(tagp); }\n\n    ///\n    double  nextafter(double x, double y);\n    ///\n    float   nextafterf(float x, float y);\n    ///\n    real    nextafterl(real x, real y) { return nextafter(cast(double) x, cast(double) y); }\n\n    ///\n    double  nexttoward(double x, real y);\n    ///\n    float   nexttowardf(float x, real y);\n    ///\n    real    nexttowardl(real x, real y) { return nexttoward(cast(double) x, cast(double) y); }\n\n    ///\n    double  fdim(double x, double y);\n    ///\n    float   fdimf(float x, float y);\n    ///\n    real    fdiml(real x, real y) { return fdim(cast(double) x, cast(double) y); }\n\n    ///\n    pure double  fmax(double x, double y);\n    ///\n    pure float   fmaxf(float x, float y);\n    ///\n    pure real    fmaxl(real x, real y) { return fmax(cast(double) x, cast(double) y); }\n\n    ///\n    pure double  fmin(double x, double y);\n    ///\n    pure float   fminf(float x, float y);\n    ///\n    pure real    fminl(real x, real y) { return fmin(cast(double) x, cast(double) y); }\n\n    ///\n    pure double  fma(double x, double y, double z);\n    ///\n    pure float   fmaf(float x, float y, float z);\n    ///\n    pure real    fmal(real x, real y, real z) { return fma(cast(double) x, cast(double) y, cast(double) z); }\n}\nelse\n{\n    ///\n    double  acos(double x);\n    ///\n    float   acosf(float x);\n    ///\n    real    acosl(real x);\n\n    ///\n    double  asin(double x);\n    ///\n    float   asinf(float x);\n    ///\n    real    asinl(real x);\n\n    ///\n    pure double  atan(double x);\n    ///\n    pure float   atanf(float x);\n    ///\n    pure real    atanl(real x);\n\n    ///\n    double  atan2(double y, double x);\n    ///\n    float   atan2f(float y, float x);\n    ///\n    real    atan2l(real y, real x);\n\n    ///\n    pure double  cos(double x);\n    ///\n    pure float   cosf(float x);\n    ///\n    pure real    cosl(real x);\n\n    ///\n    pure double  sin(double x);\n    ///\n    pure float   sinf(float x);\n    ///\n    pure real    sinl(real x);\n\n    ///\n    pure double  tan(double x);\n    ///\n    pure float   tanf(float x);\n    ///\n    pure real    tanl(real x);\n\n    ///\n    double  acosh(double x);\n    ///\n    float   acoshf(float x);\n    ///\n    real    acoshl(real x);\n\n    ///\n    pure double  asinh(double x);\n    ///\n    pure float   asinhf(float x);\n    ///\n    pure real    asinhl(real x);\n\n    ///\n    double  atanh(double x);\n    ///\n    float   atanhf(float x);\n    ///\n    real    atanhl(real x);\n\n    ///\n    double  cosh(double x);\n    ///\n    float   coshf(float x);\n    ///\n    real    coshl(real x);\n\n    ///\n    double  sinh(double x);\n    ///\n    float   sinhf(float x);\n    ///\n    real    sinhl(real x);\n\n    ///\n    pure double  tanh(double x);\n    ///\n    pure float   tanhf(float x);\n    ///\n    pure real    tanhl(real x);\n\n    ///\n    double  exp(double x);\n    ///\n    float   expf(float x);\n    ///\n    real    expl(real x);\n\n    ///\n    double  exp2(double x);\n    ///\n    float   exp2f(float x);\n    ///\n    real    exp2l(real x);\n\n    ///\n    double  expm1(double x);\n    ///\n    float   expm1f(float x);\n    ///\n    real    expm1l(real x);\n\n    ///\n    pure double  frexp(double value, int* exp);\n    ///\n    pure float   frexpf(float value, int* exp);\n    ///\n    pure real    frexpl(real value, int* exp);\n\n    ///\n    int     ilogb(double x);\n    ///\n    int     ilogbf(float x);\n    ///\n    int     ilogbl(real x);\n\n    ///\n    double  ldexp(double x, int exp);\n    ///\n    float   ldexpf(float x, int exp);\n    ///\n    real    ldexpl(real x, int exp);\n\n    ///\n    double  log(double x);\n    ///\n    float   logf(float x);\n    ///\n    real    logl(real x);\n\n    ///\n    double  log10(double x);\n    ///\n    float   log10f(float x);\n    ///\n    real    log10l(real x);\n\n    ///\n    double  log1p(double x);\n    ///\n    float   log1pf(float x);\n    ///\n    real    log1pl(real x);\n\n    ///\n    double  log2(double x);\n    ///\n    float   log2f(float x);\n    ///\n    real    log2l(real x);\n\n    ///\n    double  logb(double x);\n    ///\n    float   logbf(float x);\n    ///\n    real    logbl(real x);\n\n    ///\n    pure double  modf(double value, double* iptr);\n    ///\n    pure float   modff(float value, float* iptr);\n    ///\n    pure real    modfl(real value, real *iptr);\n\n    ///\n    double  scalbn(double x, int n);\n    ///\n    float   scalbnf(float x, int n);\n    ///\n    real    scalbnl(real x, int n);\n\n    ///\n    double  scalbln(double x, c_long n);\n    ///\n    float   scalblnf(float x, c_long n);\n    ///\n    real    scalblnl(real x, c_long n);\n\n    ///\n    pure double  cbrt(double x);\n    ///\n    pure float   cbrtf(float x);\n    ///\n    pure real    cbrtl(real x);\n\n    ///\n    pure double  fabs(double x);\n    version (CRuntime_Microsoft)\n    {\n    }\n    else\n    {\n        ///\n        pure float   fabsf(float x);\n        ///\n        pure real    fabsl(real x);\n    }\n\n    ///\n    double  hypot(double x, double y);\n    ///\n    float   hypotf(float x, float y);\n    ///\n    real    hypotl(real x, real y);\n\n    ///\n    double  pow(double x, double y);\n    ///\n    float   powf(float x, float y);\n    ///\n    real    powl(real x, real y);\n\n    ///\n    double  sqrt(double x);\n    ///\n    float   sqrtf(float x);\n    ///\n    real    sqrtl(real x);\n\n    ///\n    pure double  erf(double x);\n    ///\n    pure float   erff(float x);\n    ///\n    pure real    erfl(real x);\n\n    ///\n    double  erfc(double x);\n    ///\n    float   erfcf(float x);\n    ///\n    real    erfcl(real x);\n\n    ///\n    double  lgamma(double x);\n    ///\n    float   lgammaf(float x);\n    ///\n    real    lgammal(real x);\n\n    ///\n    double  tgamma(double x);\n    ///\n    float   tgammaf(float x);\n    ///\n    real    tgammal(real x);\n\n    ///\n    pure double  ceil(double x);\n    ///\n    pure float   ceilf(float x);\n    ///\n    pure real    ceill(real x);\n\n    ///\n    pure double  floor(double x);\n    ///\n    pure float   floorf(float x);\n    ///\n    pure real    floorl(real x);\n\n    ///\n    pure double  nearbyint(double x);\n    ///\n    pure float   nearbyintf(float x);\n    ///\n    pure real    nearbyintl(real x);\n\n    ///\n    pure double  rint(double x);\n    ///\n    pure float   rintf(float x);\n    ///\n    pure real    rintl(real x);\n\n    ///\n    c_long  lrint(double x);\n    ///\n    c_long  lrintf(float x);\n    ///\n    c_long  lrintl(real x);\n\n    ///\n    long    llrint(double x);\n    ///\n    long    llrintf(float x);\n    ///\n    long    llrintl(real x);\n\n    ///\n    pure double  round(double x);\n    ///\n    pure float   roundf(float x);\n    ///\n    pure real    roundl(real x);\n\n    ///\n    c_long  lround(double x);\n    ///\n    c_long  lroundf(float x);\n    ///\n    c_long  lroundl(real x);\n\n    ///\n    long    llround(double x);\n    ///\n    long    llroundf(float x);\n    ///\n    long    llroundl(real x);\n\n    ///\n    pure double  trunc(double x);\n    ///\n    pure float   truncf(float x);\n    ///\n    pure real    truncl(real x);\n\n    ///\n    double  fmod(double x, double y);\n    ///\n    float   fmodf(float x, float y);\n    ///\n    real    fmodl(real x, real y);\n\n    ///\n    double  remainder(double x, double y);\n    ///\n    float   remainderf(float x, float y);\n    ///\n    real    remainderl(real x, real y);\n\n    ///\n    double  remquo(double x, double y, int* quo);\n    ///\n    float   remquof(float x, float y, int* quo);\n    ///\n    real    remquol(real x, real y, int* quo);\n\n    ///\n    pure double  copysign(double x, double y);\n    ///\n    pure float   copysignf(float x, float y);\n    ///\n    pure real    copysignl(real x, real y);\n\n    ///\n    pure double  nan(char* tagp);\n    ///\n    pure float   nanf(char* tagp);\n    ///\n    pure real    nanl(char* tagp);\n\n    ///\n    double  nextafter(double x, double y);\n    ///\n    float   nextafterf(float x, float y);\n    ///\n    real    nextafterl(real x, real y);\n\n    ///\n    double  nexttoward(double x, real y);\n    ///\n    float   nexttowardf(float x, real y);\n    ///\n    real    nexttowardl(real x, real y);\n\n    ///\n    double  fdim(double x, double y);\n    ///\n    float   fdimf(float x, float y);\n    ///\n    real    fdiml(real x, real y);\n\n    ///\n    pure double  fmax(double x, double y);\n    ///\n    pure float   fmaxf(float x, float y);\n    ///\n    pure real    fmaxl(real x, real y);\n\n    ///\n    pure double  fmin(double x, double y);\n    ///\n    pure float   fminf(float x, float y);\n    ///\n    pure real    fminl(real x, real y);\n\n    ///\n    pure double  fma(double x, double y, double z);\n    ///\n    pure float   fmaf(float x, float y, float z);\n    ///\n    pure real    fmal(real x, real y, real z);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/signal.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_signal.h.html, _signal.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_signal.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.signal;\n\nextern (C):\n@system:\nnothrow:\n@nogc:\n\n// this should be volatile\n///\nalias int sig_atomic_t;\n\nprivate alias void function(int) sigfn_t;\n\nversion (Posix)\n{\n    ///\n    enum SIG_ERR    = cast(sigfn_t) -1;\n    ///\n    enum SIG_DFL    = cast(sigfn_t) 0;\n    ///\n    enum SIG_IGN    = cast(sigfn_t) 1;\n\n    // standard C signals\n    ///\n    enum SIGABRT    = 6;  // Abnormal termination\n    ///\n    enum SIGFPE     = 8;  // Floating-point error\n    ///\n    enum SIGILL     = 4;  // Illegal hardware instruction\n    ///\n    enum SIGINT     = 2;  // Terminal interrupt character\n    ///\n    enum SIGSEGV    = 11; // Invalid memory reference\n    ///\n    enum SIGTERM    = 15; // Termination\n}\nelse version (Windows)\n{\n    ///\n    enum SIG_ERR    = cast(sigfn_t) -1;\n    ///\n    enum SIG_DFL    = cast(sigfn_t) 0;\n    ///\n    enum SIG_IGN    = cast(sigfn_t) 1;\n\n    // standard C signals\n    ///\n    enum SIGABRT    = 22; // Abnormal termination\n    ///\n    enum SIGFPE     = 8;  // Floating-point error\n    ///\n    enum SIGILL     = 4;  // Illegal hardware instruction\n    ///\n    enum SIGINT     = 2;  // Terminal interrupt character\n    ///\n    enum SIGSEGV    = 11; // Invalid memory reference\n    ///\n    enum SIGTERM    = 15; // Termination\n}\n\n///\nsigfn_t signal(int sig, sigfn_t func);\n///\nint     raise(int sig);\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/stdarg.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdarg.h.html, _stdarg.h)\n *\n * Copyright: Copyright Digital Mars 2000 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, Hauke Duden\n * Standards: ISO/IEC 9899:1999 (E)\n * Source: $(DRUNTIMESRC core/stdc/_stdarg.d)\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule core.stdc.stdarg;\n\n@system:\n//@nogc:    // Not yet, need to make TypeInfo's member functions @nogc first\nnothrow:\n\nversion (GNU)\n{\n    import gcc.builtins;\n    alias __builtin_va_list __gnuc_va_list;\n\n\n    /*********************\n     * The argument pointer type.\n     */\n    alias __gnuc_va_list va_list;\n\n\n    /**********\n     * Initialize ap.\n     * parmn should be the last named parameter.\n     */\n    void va_start(T)(out va_list ap, ref T parmn);\n\n\n    /************\n     * Retrieve and return the next value that is type T.\n     */\n    T va_arg(T)(ref va_list ap);\n\n\n    /*************\n     * Retrieve and store through parmn the next value that is of type T.\n     */\n    void va_arg(T)(ref va_list ap, ref T parmn);\n\n\n    /*************\n     * Retrieve and store through parmn the next value that is of TypeInfo ti.\n     * Used when the static type is not known.\n     */\n    version (X86)\n    {\n        ///\n        void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)\n        {\n            auto p = ap;\n            auto tsize = ti.tsize;\n            ap = cast(va_list)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));\n            parmn[0..tsize] = p[0..tsize];\n        }\n    }\n    else version (X86_64)\n    {\n        /// Layout of this struct must match __builtin_va_list for C ABI compatibility\n        struct __va_list\n        {\n            uint offset_regs = 6 * 8;            // no regs\n            uint offset_fpregs = 6 * 8 + 8 * 16; // no fp regs\n            void* stack_args;\n            void* reg_args;\n        }\n\n        ///\n        void va_arg()(ref va_list apx, TypeInfo ti, void* parmn)\n        {\n            __va_list* ap = cast(__va_list*)apx;\n            TypeInfo arg1, arg2;\n            if (!ti.argTypes(arg1, arg2))\n            {\n                bool inXMMregister(TypeInfo arg) pure nothrow @safe\n                {\n                    return (arg.flags & 2) != 0;\n                }\n\n                TypeInfo_Vector v1 = arg1 ? cast(TypeInfo_Vector)arg1 : null;\n                if (arg1 && (arg1.tsize() <= 8 || v1))\n                {   // Arg is passed in one register\n                    auto tsize = arg1.tsize();\n                    void* p;\n                    bool stack = false;\n                    auto offset_fpregs_save = ap.offset_fpregs;\n                    auto offset_regs_save = ap.offset_regs;\n                L1:\n                    if (inXMMregister(arg1) || v1)\n                    {   // Passed in XMM register\n                        if (ap.offset_fpregs < (6 * 8 + 16 * 8) && !stack)\n                        {\n                            p = ap.reg_args + ap.offset_fpregs;\n                            ap.offset_fpregs += 16;\n                        }\n                        else\n                        {\n                            p = ap.stack_args;\n                            ap.stack_args += (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);\n                            stack = true;\n                        }\n                    }\n                    else\n                    {   // Passed in regular register\n                        if (ap.offset_regs < 6 * 8 && !stack)\n                        {\n                            p = ap.reg_args + ap.offset_regs;\n                            ap.offset_regs += 8;\n                        }\n                        else\n                        {\n                            p = ap.stack_args;\n                            ap.stack_args += 8;\n                            stack = true;\n                        }\n                    }\n                    parmn[0..tsize] = p[0..tsize];\n\n                    if (arg2)\n                    {\n                        if (inXMMregister(arg2))\n                        {   // Passed in XMM register\n                            if (ap.offset_fpregs < (6 * 8 + 16 * 8) && !stack)\n                            {\n                                p = ap.reg_args + ap.offset_fpregs;\n                                ap.offset_fpregs += 16;\n                            }\n                            else\n                            {\n                                if (!stack)\n                                {   // arg1 is really on the stack, so rewind and redo\n                                    ap.offset_fpregs = offset_fpregs_save;\n                                    ap.offset_regs = offset_regs_save;\n                                    stack = true;\n                                    goto L1;\n                                }\n                                p = ap.stack_args;\n                                ap.stack_args += (arg2.tsize() + size_t.sizeof - 1) & ~(size_t.sizeof - 1);\n                            }\n                        }\n                        else\n                        {   // Passed in regular register\n                            if (ap.offset_regs < 6 * 8 && !stack)\n                            {\n                                p = ap.reg_args + ap.offset_regs;\n                                ap.offset_regs += 8;\n                            }\n                            else\n                            {\n                                if (!stack)\n                                {   // arg1 is really on the stack, so rewind and redo\n                                    ap.offset_fpregs = offset_fpregs_save;\n                                    ap.offset_regs = offset_regs_save;\n                                    stack = true;\n                                    goto L1;\n                                }\n                                p = ap.stack_args;\n                                ap.stack_args += 8;\n                            }\n                        }\n                        auto sz = ti.tsize() - 8;\n                        (parmn + 8)[0..sz] = p[0..sz];\n                    }\n                }\n                else\n                {   // Always passed in memory\n                    // The arg may have more strict alignment than the stack\n                    auto talign = ti.talign();\n                    auto tsize = ti.tsize();\n                    auto p = cast(void*)((cast(size_t)ap.stack_args + talign - 1) & ~(talign - 1));\n                    ap.stack_args = cast(void*)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));\n                    parmn[0..tsize] = p[0..tsize];\n                }\n            }\n            else\n            {\n                assert(false, \"not a valid argument type for va_arg\");\n            }\n        }\n    }\n    else version (ARM)\n    {\n        ///\n        void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)\n        {\n            auto p = *cast(void**) &ap;\n            auto tsize = ti.tsize();\n            *cast(void**) &ap += ( tsize + size_t.sizeof - 1 ) & ~( size_t.sizeof - 1 );\n            parmn[0..tsize] = p[0..tsize];\n        }\n    }\n    else\n    {\n        ///\n        void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)\n        {\n            static assert(false, \"Unsupported platform\");\n        }\n    }\n\n\n    /***********************\n     * End use of ap.\n     */\n    alias __builtin_va_end va_end;\n\n\n    /***********************\n     * Make a copy of ap.\n     */\n    alias __builtin_va_copy va_copy;\n\n}\nelse version (X86)\n{\n    /*********************\n     * The argument pointer type.\n     */\n    alias char* va_list;\n\n    /**********\n     * Initialize ap.\n     * For 32 bit code, parmn should be the last named parameter.\n     * For 64 bit code, parmn should be __va_argsave.\n     */\n    void va_start(T)(out va_list ap, ref T parmn)\n    {\n        ap = cast(va_list)( cast(void*) &parmn + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) );\n    }\n\n    /************\n     * Retrieve and return the next value that is type T.\n     * Should use the other va_arg instead, as this won't work for 64 bit code.\n     */\n    T va_arg(T)(ref va_list ap)\n    {\n        T arg = *cast(T*) ap;\n        ap = cast(va_list)( cast(void*) ap + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) );\n        return arg;\n    }\n\n    /************\n     * Retrieve and return the next value that is type T.\n     * This is the preferred version.\n     */\n    void va_arg(T)(ref va_list ap, ref T parmn)\n    {\n        parmn = *cast(T*)ap;\n        ap = cast(va_list)(cast(void*)ap + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1)));\n    }\n\n    /*************\n     * Retrieve and store through parmn the next value that is of TypeInfo ti.\n     * Used when the static type is not known.\n     */\n    void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)\n    {\n        // Wait until everyone updates to get TypeInfo.talign\n        //auto talign = ti.talign;\n        //auto p = cast(void*)(cast(size_t)ap + talign - 1) & ~(talign - 1);\n        auto p = ap;\n        auto tsize = ti.tsize;\n        ap = cast(va_list)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));\n        parmn[0..tsize] = p[0..tsize];\n    }\n\n    /***********************\n     * End use of ap.\n     */\n    void va_end(va_list ap)\n    {\n    }\n\n    ///\n    void va_copy(out va_list dest, va_list src)\n    {\n        dest = src;\n    }\n}\nelse version (Windows) // Win64\n{   /* Win64 is characterized by all arguments fitting into a register size.\n     * Smaller ones are padded out to register size, and larger ones are passed by\n     * reference.\n     */\n\n    /*********************\n     * The argument pointer type.\n     */\n    alias char* va_list;\n\n    /**********\n     * Initialize ap.\n     * parmn should be the last named parameter.\n     */\n    void va_start(T)(out va_list ap, ref T parmn); // Compiler intrinsic\n\n    /************\n     * Retrieve and return the next value that is type T.\n     */\n    T va_arg(T)(ref va_list ap)\n    {\n        static if (T.sizeof > size_t.sizeof)\n            T arg = **cast(T**)ap;\n        else\n            T arg = *cast(T*)ap;\n        ap = cast(va_list)(cast(void*)ap + ((size_t.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));\n        return arg;\n    }\n\n    /************\n     * Retrieve and return the next value that is type T.\n     * This is the preferred version.\n     */\n    void va_arg(T)(ref va_list ap, ref T parmn)\n    {\n        static if (T.sizeof > size_t.sizeof)\n            parmn = **cast(T**)ap;\n        else\n            parmn = *cast(T*)ap;\n        ap = cast(va_list)(cast(void*)ap + ((size_t.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));\n    }\n\n    /*************\n     * Retrieve and store through parmn the next value that is of TypeInfo ti.\n     * Used when the static type is not known.\n     */\n    void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)\n    {\n        // Wait until everyone updates to get TypeInfo.talign\n        //auto talign = ti.talign;\n        //auto p = cast(void*)(cast(size_t)ap + talign - 1) & ~(talign - 1);\n        auto p = ap;\n        auto tsize = ti.tsize;\n        ap = cast(va_list)(cast(size_t)p + ((size_t.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));\n        void* q = (tsize > size_t.sizeof) ? *cast(void**)p : p;\n        parmn[0..tsize] = q[0..tsize];\n    }\n\n    /***********************\n     * End use of ap.\n     */\n    void va_end(va_list ap)\n    {\n    }\n\n    ///\n    void va_copy(out va_list dest, va_list src)\n    {\n        dest = src;\n    }\n}\nelse version (X86_64)\n{\n    // Determine if type is a vector type\n    template isVectorType(T)\n    {\n        enum isVectorType = false;\n    }\n\n    template isVectorType(T : __vector(T[N]), size_t N)\n    {\n        enum isVectorType = true;\n    }\n\n    // Layout of this struct must match __gnuc_va_list for C ABI compatibility\n    struct __va_list_tag\n    {\n        uint offset_regs = 6 * 8;            // no regs\n        uint offset_fpregs = 6 * 8 + 8 * 16; // no fp regs\n        void* stack_args;\n        void* reg_args;\n    }\n    alias __va_list = __va_list_tag;\n\n    align(16) struct __va_argsave_t\n    {\n        size_t[6] regs;   // RDI,RSI,RDX,RCX,R8,R9\n        real[8] fpregs;   // XMM0..XMM7\n        __va_list va;\n    }\n\n    /*\n     * Making it an array of 1 causes va_list to be passed as a pointer in\n     * function argument lists\n     */\n    alias va_list = __va_list*;\n\n    ///\n    void va_start(T)(out va_list ap, ref T parmn); // Compiler intrinsic\n\n    ///\n    T va_arg(T)(va_list ap)\n    {   T a;\n        va_arg(ap, a);\n        return a;\n    }\n\n    ///\n    void va_arg(T)(va_list apx, ref T parmn)\n    {\n        __va_list* ap = cast(__va_list*)apx;\n        static if (is(T U == __argTypes))\n        {\n            static if (U.length == 0 || T.sizeof > 16 || (U[0].sizeof > 8 && !isVectorType!(U[0])))\n            {   // Always passed in memory\n                // The arg may have more strict alignment than the stack\n                auto p = (cast(size_t)ap.stack_args + T.alignof - 1) & ~(T.alignof - 1);\n                ap.stack_args = cast(void*)(p + ((T.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));\n                parmn = *cast(T*)p;\n            }\n            else static if (U.length == 1)\n            {   // Arg is passed in one register\n                alias U[0] T1;\n                static if (is(T1 == double) || is(T1 == float) || isVectorType!(T1))\n                {   // Passed in XMM register\n                    if (ap.offset_fpregs < (6 * 8 + 16 * 8))\n                    {\n                        parmn = *cast(T*)(ap.reg_args + ap.offset_fpregs);\n                        ap.offset_fpregs += 16;\n                    }\n                    else\n                    {\n                        parmn = *cast(T*)ap.stack_args;\n                        ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);\n                    }\n                }\n                else\n                {   // Passed in regular register\n                    if (ap.offset_regs < 6 * 8 && T.sizeof <= 8)\n                    {\n                        parmn = *cast(T*)(ap.reg_args + ap.offset_regs);\n                        ap.offset_regs += 8;\n                    }\n                    else\n                    {\n                        auto p = (cast(size_t)ap.stack_args + T.alignof - 1) & ~(T.alignof - 1);\n                        ap.stack_args = cast(void*)(p + ((T.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));\n                        parmn = *cast(T*)p;\n                    }\n                }\n            }\n            else static if (U.length == 2)\n            {   // Arg is passed in two registers\n                alias U[0] T1;\n                alias U[1] T2;\n                auto p = cast(void*)&parmn + 8;\n\n                // Both must be in registers, or both on stack, hence 4 cases\n\n                static if ((is(T1 == double) || is(T1 == float)) &&\n                           (is(T2 == double) || is(T2 == float)))\n                {\n                    if (ap.offset_fpregs < (6 * 8 + 16 * 8) - 16)\n                    {\n                        *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_fpregs);\n                        *cast(T2*)p = *cast(T2*)(ap.reg_args + ap.offset_fpregs + 16);\n                        ap.offset_fpregs += 32;\n                    }\n                    else\n                    {\n                        *cast(T1*)&parmn = *cast(T1*)ap.stack_args;\n                        ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);\n                        *cast(T2*)p = *cast(T2*)ap.stack_args;\n                        ap.stack_args += (T2.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);\n                    }\n                }\n                else static if (is(T1 == double) || is(T1 == float))\n                {\n                    void* a = void;\n                    if (ap.offset_fpregs < (6 * 8 + 16 * 8) &&\n                        ap.offset_regs < 6 * 8 && T2.sizeof <= 8)\n                    {\n                        *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_fpregs);\n                        ap.offset_fpregs += 16;\n                        a = ap.reg_args + ap.offset_regs;\n                        ap.offset_regs += 8;\n                    }\n                    else\n                    {\n                        *cast(T1*)&parmn = *cast(T1*)ap.stack_args;\n                        ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);\n                        a = ap.stack_args;\n                        ap.stack_args += 8;\n                    }\n                    // Be careful not to go past the size of the actual argument\n                    const sz2 = T.sizeof - 8;\n                    p[0..sz2] = a[0..sz2];\n                }\n                else static if (is(T2 == double) || is(T2 == float))\n                {\n                    if (ap.offset_regs < 6 * 8 && T1.sizeof <= 8 &&\n                        ap.offset_fpregs < (6 * 8 + 16 * 8))\n                    {\n                        *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_regs);\n                        ap.offset_regs += 8;\n                        *cast(T2*)p = *cast(T2*)(ap.reg_args + ap.offset_fpregs);\n                        ap.offset_fpregs += 16;\n                    }\n                    else\n                    {\n                        *cast(T1*)&parmn = *cast(T1*)ap.stack_args;\n                        ap.stack_args += 8;\n                        *cast(T2*)p = *cast(T2*)ap.stack_args;\n                        ap.stack_args += (T2.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);\n                    }\n                }\n                else // both in regular registers\n                {\n                    void* a = void;\n                    if (ap.offset_regs < 5 * 8 && T1.sizeof <= 8 && T2.sizeof <= 8)\n                    {\n                        *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_regs);\n                        ap.offset_regs += 8;\n                        a = ap.reg_args + ap.offset_regs;\n                        ap.offset_regs += 8;\n                    }\n                    else\n                    {\n                        *cast(T1*)&parmn = *cast(T1*)ap.stack_args;\n                        ap.stack_args += 8;\n                        a = ap.stack_args;\n                        ap.stack_args += 8;\n                    }\n                    // Be careful not to go past the size of the actual argument\n                    const sz2 = T.sizeof - 8;\n                    p[0..sz2] = a[0..sz2];\n                }\n            }\n            else\n            {\n                static assert(false);\n            }\n        }\n        else\n        {\n            static assert(false, \"not a valid argument type for va_arg\");\n        }\n    }\n\n    ///\n    void va_arg()(va_list apx, TypeInfo ti, void* parmn)\n    {\n        __va_list* ap = cast(__va_list*)apx;\n        TypeInfo arg1, arg2;\n        if (!ti.argTypes(arg1, arg2))\n        {\n            bool inXMMregister(TypeInfo arg) pure nothrow @safe\n            {\n                return (arg.flags & 2) != 0;\n            }\n\n            TypeInfo_Vector v1 = arg1 ? cast(TypeInfo_Vector)arg1 : null;\n            if (arg1 && (arg1.tsize <= 8 || v1))\n            {   // Arg is passed in one register\n                auto tsize = arg1.tsize;\n                void* p;\n                bool stack = false;\n                auto offset_fpregs_save = ap.offset_fpregs;\n                auto offset_regs_save = ap.offset_regs;\n            L1:\n                if (inXMMregister(arg1) || v1)\n                {   // Passed in XMM register\n                    if (ap.offset_fpregs < (6 * 8 + 16 * 8) && !stack)\n                    {\n                        p = ap.reg_args + ap.offset_fpregs;\n                        ap.offset_fpregs += 16;\n                    }\n                    else\n                    {\n                        p = ap.stack_args;\n                        ap.stack_args += (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);\n                        stack = true;\n                    }\n                }\n                else\n                {   // Passed in regular register\n                    if (ap.offset_regs < 6 * 8 && !stack)\n                    {\n                        p = ap.reg_args + ap.offset_regs;\n                        ap.offset_regs += 8;\n                    }\n                    else\n                    {\n                        p = ap.stack_args;\n                        ap.stack_args += 8;\n                        stack = true;\n                    }\n                }\n                parmn[0..tsize] = p[0..tsize];\n\n                if (arg2)\n                {\n                    if (inXMMregister(arg2))\n                    {   // Passed in XMM register\n                        if (ap.offset_fpregs < (6 * 8 + 16 * 8) && !stack)\n                        {\n                            p = ap.reg_args + ap.offset_fpregs;\n                            ap.offset_fpregs += 16;\n                        }\n                        else\n                        {\n                            if (!stack)\n                            {   // arg1 is really on the stack, so rewind and redo\n                                ap.offset_fpregs = offset_fpregs_save;\n                                ap.offset_regs = offset_regs_save;\n                                stack = true;\n                                goto L1;\n                            }\n                            p = ap.stack_args;\n                            ap.stack_args += (arg2.tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);\n                        }\n                    }\n                    else\n                    {   // Passed in regular register\n                        if (ap.offset_regs < 6 * 8 && !stack)\n                        {\n                            p = ap.reg_args + ap.offset_regs;\n                            ap.offset_regs += 8;\n                        }\n                        else\n                        {\n                            if (!stack)\n                            {   // arg1 is really on the stack, so rewind and redo\n                                ap.offset_fpregs = offset_fpregs_save;\n                                ap.offset_regs = offset_regs_save;\n                                stack = true;\n                                goto L1;\n                            }\n                            p = ap.stack_args;\n                            ap.stack_args += 8;\n                        }\n                    }\n                    auto sz = ti.tsize - 8;\n                    (parmn + 8)[0..sz] = p[0..sz];\n                }\n            }\n            else\n            {   // Always passed in memory\n                // The arg may have more strict alignment than the stack\n                auto talign = ti.talign;\n                auto tsize = ti.tsize;\n                auto p = cast(void*)((cast(size_t)ap.stack_args + talign - 1) & ~(talign - 1));\n                ap.stack_args = cast(void*)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));\n                parmn[0..tsize] = p[0..tsize];\n            }\n        }\n        else\n        {\n            assert(false, \"not a valid argument type for va_arg\");\n        }\n    }\n\n    ///\n    void va_end(va_list ap)\n    {\n    }\n\n    import core.stdc.stdlib : alloca;\n\n    ///\n    void va_copy(out va_list dest, va_list src, void* storage = alloca(__va_list_tag.sizeof))\n    {\n        // Instead of copying the pointers, and aliasing the source va_list,\n        // the default argument alloca will allocate storage in the caller's\n        // stack frame.  This is still not correct (it should be allocated in\n        // the place where the va_list variable is declared) but most of the\n        // time the caller's stack frame _is_ the place where the va_list is\n        // allocated, so in most cases this will now work.\n        dest = cast(va_list)storage;\n        *dest = *src;\n    }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/stddef.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stddef.h.html, _stddef.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_stddef.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.stddef;\n\nextern (C):\n@trusted: // Types only.\nnothrow:\n@nogc:\n\n///\nalias nullptr_t = typeof(null);\n\n// size_t and ptrdiff_t are defined in the object module.\n\nversion (Windows)\n{\n    ///\n    alias wchar wchar_t;\n}\nelse version (Posix)\n{\n    ///\n    alias dchar wchar_t;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/stdint.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdint.h.html, _stdint.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2018\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_stdint.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.stdint;\n\nprivate import core.stdc.config;\nprivate import core.stdc.stddef; // for wchar_t\nprivate import core.stdc.signal; // for sig_atomic_t\nprivate import core.stdc.wchar_; // for wint_t\n\n\n// Can't be `private` because of @@@BUG11173@@@.\nT _typify(T)(T val) @safe pure nothrow { return val; }\n\nextern (C):\n@trusted: // Types and constants only.\nnothrow:\n@nogc:\n\n\nstatic if (is(ucent))\n{\n    alias int128_t = cent;   ///\n    alias uint128_t = ucent; ///\n}\n\nversion (Windows)\n{\n    alias int8_t   = byte;   ///\n    alias int16_t  = short;  ///\n    alias uint8_t  = ubyte;  ///\n    alias uint16_t = ushort; ///\n    version (CRuntime_DigitalMars)\n    {\n        alias int32_t  = cpp_long;  ///\n        alias uint32_t = cpp_ulong; ///\n    }\n    else\n    {\n        alias int32_t  = int;  ///\n        alias uint32_t = uint; ///\n    }\n    alias int64_t  = long;   ///\n    alias uint64_t = ulong;  ///\n\n    alias int_least8_t   = byte;     ///\n    alias uint_least8_t  = ubyte;    ///\n    alias int_least16_t  = short;    ///\n    alias uint_least16_t = ushort;   ///\n    alias int_least32_t  = int32_t;  ///\n    alias uint_least32_t = uint32_t; ///\n    alias int_least64_t  = long;     ///\n    alias uint_least64_t = ulong;    ///\n\n    alias int_fast8_t   = byte;     ///\n    alias uint_fast8_t  = ubyte;    ///\n    alias int_fast16_t  = int;      ///\n    alias uint_fast16_t = uint;     ///\n    alias int_fast32_t  = int32_t;  ///\n    alias uint_fast32_t = uint32_t; ///\n    alias int_fast64_t  = long;     ///\n    alias uint_fast64_t = ulong;    ///\n\n    alias intptr_t  = ptrdiff_t; ///\n    alias uintptr_t = size_t;    ///\n    alias intmax_t  = long;      ///\n    alias uintmax_t = ulong;     ///\n}\nelse version (OSX)\n{\n    alias int8_t   = byte;          ///\n    alias int16_t  = short;         ///\n    alias uint8_t  = ubyte;         ///\n    alias uint16_t = ushort;        ///\n    alias int32_t  = int;           ///\n    alias uint32_t = uint;          ///\n    alias int64_t  = cpp_longlong;  ///\n    alias uint64_t = cpp_ulonglong; ///\n\n    alias int_least8_t   = byte;     ///\n    alias uint_least8_t  = ubyte;    ///\n    alias int_least16_t  = short;    ///\n    alias uint_least16_t = ushort;   ///\n    alias int_least32_t  = int;      ///\n    alias uint_least32_t = uint;     ///\n    alias int_least64_t  = int64_t;  ///\n    alias uint_least64_t = uint64_t; ///\n\n    alias int_fast8_t   = byte;     ///\n    alias uint_fast8_t  = ubyte;    ///\n    alias int_fast16_t  = short;    ///\n    alias uint_fast16_t = ushort;   ///\n    alias int_fast32_t  = int;      ///\n    alias uint_fast32_t = uint;     ///\n    alias int_fast64_t  = int64_t;  ///\n    alias uint_fast64_t = uint64_t; ///\n\n    alias intptr_t  = cpp_long;  ///\n    alias uintptr_t = cpp_ulong; ///\n    alias intmax_t  = long;      ///\n    alias uintmax_t = ulong;     ///\n}\nelse version (Posix)\n{\n    alias int8_t   = byte;   ///\n    alias int16_t  = short;  ///\n    alias uint8_t  = ubyte;  ///\n    alias uint16_t = ushort; ///\n    alias int32_t  = int;    ///\n    alias uint32_t = uint;   ///\n    alias int64_t  = long;   ///\n    alias uint64_t = ulong;  ///\n\n    alias int_least8_t   = byte;   ///\n    alias uint_least8_t  = ubyte;  ///\n    alias int_least16_t  = short;  ///\n    alias uint_least16_t = ushort; ///\n    alias int_least32_t  = int;    ///\n    alias uint_least32_t = uint;   ///\n    alias int_least64_t  = long;   ///\n    alias uint_least64_t = ulong;  ///\n\n    version (FreeBSD)\n    {\n        alias int_fast8_t   = int;  ///\n        alias uint_fast8_t  = uint; ///\n        alias int_fast16_t  = int;  ///\n        alias uint_fast16_t = uint; ///\n        alias int_fast32_t  = int;  ///\n        alias uint_fast32_t = uint; ///\n    }\n    else\n    {\n        alias int_fast8_t   = byte;      ///\n        alias uint_fast8_t  = ubyte;     ///\n        alias int_fast16_t  = ptrdiff_t; ///\n        alias uint_fast16_t = size_t;    ///\n        alias int_fast32_t  = ptrdiff_t; ///\n        alias uint_fast32_t = size_t;    ///\n    }\n    alias int_fast64_t  = long;      ///\n    alias uint_fast64_t = ulong;     ///\n\n    alias intptr_t  = ptrdiff_t; ///\n    alias uintptr_t = size_t;    ///\n    alias intmax_t  = long;      ///\n    alias uintmax_t = ulong;     ///\n}\nelse\n{\n    static assert(0);\n}\n\n\n\n///\nenum int8_t   INT8_MIN  = int8_t.min;\n///\nenum int8_t   INT8_MAX  = int8_t.max;\n///\nenum int16_t  INT16_MIN = int16_t.min;\n///\nenum int16_t  INT16_MAX = int16_t.max;\n///\nenum int32_t  INT32_MIN = int32_t.min;\n///\nenum int32_t  INT32_MAX = int32_t.max;\n///\nenum int64_t  INT64_MIN = int64_t.min;\n///\nenum int64_t  INT64_MAX = int64_t.max;\n\n///\nenum uint8_t  UINT8_MAX  = uint8_t.max;\n///\nenum uint16_t UINT16_MAX = uint16_t.max;\n///\nenum uint32_t UINT32_MAX = uint32_t.max;\n///\nenum uint64_t UINT64_MAX = uint64_t.max;\n\n///\nenum int_least8_t    INT_LEAST8_MIN   = int_least8_t.min;\n///\nenum int_least8_t    INT_LEAST8_MAX   = int_least8_t.max;\n///\nenum int_least16_t   INT_LEAST16_MIN  = int_least16_t.min;\n///\nenum int_least16_t   INT_LEAST16_MAX  = int_least16_t.max;\n///\nenum int_least32_t   INT_LEAST32_MIN  = int_least32_t.min;\n///\nenum int_least32_t   INT_LEAST32_MAX  = int_least32_t.max;\n///\nenum int_least64_t   INT_LEAST64_MIN  = int_least64_t.min;\n///\nenum int_least64_t   INT_LEAST64_MAX  = int_least64_t.max;\n\n///\nenum uint_least8_t   UINT_LEAST8_MAX  = uint_least8_t.max;\n///\nenum uint_least16_t  UINT_LEAST16_MAX = uint_least16_t.max;\n///\nenum uint_least32_t  UINT_LEAST32_MAX = uint_least32_t.max;\n///\nenum uint_least64_t  UINT_LEAST64_MAX = uint_least64_t.max;\n\n///\nenum int_fast8_t   INT_FAST8_MIN   = int_fast8_t.min;\n///\nenum int_fast8_t   INT_FAST8_MAX   = int_fast8_t.max;\n///\nenum int_fast16_t  INT_FAST16_MIN  = int_fast16_t.min;\n///\nenum int_fast16_t  INT_FAST16_MAX  = int_fast16_t.max;\n///\nenum int_fast32_t  INT_FAST32_MIN  = int_fast32_t.min;\n///\nenum int_fast32_t  INT_FAST32_MAX  = int_fast32_t.max;\n///\nenum int_fast64_t  INT_FAST64_MIN  = int_fast64_t.min;\n///\nenum int_fast64_t  INT_FAST64_MAX  = int_fast64_t.max;\n\n///\nenum uint_fast8_t  UINT_FAST8_MAX  = uint_fast8_t.max;\n///\nenum uint_fast16_t UINT_FAST16_MAX = uint_fast16_t.max;\n///\nenum uint_fast32_t UINT_FAST32_MAX = uint_fast32_t.max;\n///\nenum uint_fast64_t UINT_FAST64_MAX = uint_fast64_t.max;\n\n///\nenum intptr_t  INTPTR_MIN  = intptr_t.min;\n///\nenum intptr_t  INTPTR_MAX  = intptr_t.max;\n\n///\nenum uintptr_t UINTPTR_MIN = uintptr_t.min;\n///\nenum uintptr_t UINTPTR_MAX = uintptr_t.max;\n\n///\nenum intmax_t  INTMAX_MIN  = intmax_t.min;\n///\nenum intmax_t  INTMAX_MAX  = intmax_t.max;\n\n///\nenum uintmax_t UINTMAX_MAX = uintmax_t.max;\n\n///\nenum ptrdiff_t PTRDIFF_MIN = ptrdiff_t.min;\n///\nenum ptrdiff_t PTRDIFF_MAX = ptrdiff_t.max;\n\n///\nenum sig_atomic_t SIG_ATOMIC_MIN = sig_atomic_t.min;\n///\nenum sig_atomic_t SIG_ATOMIC_MAX = sig_atomic_t.max;\n\n///\nenum size_t  SIZE_MAX  = size_t.max;\n\n///\nenum wchar_t WCHAR_MIN = wchar_t.min;\n///\nenum wchar_t WCHAR_MAX = wchar_t.max;\n\n///\nenum wint_t  WINT_MIN  = wint_t.min;\n///\nenum wint_t  WINT_MAX  = wint_t.max;\n\n///\nalias INT8_C  = _typify!int8_t ;\n///\nalias INT16_C = _typify!int16_t;\n///\nalias INT32_C = _typify!int32_t;\n///\nalias INT64_C = _typify!int64_t;\n\n///\nalias UINT8_C  = _typify!uint8_t ;\n///\nalias UINT16_C = _typify!uint16_t;\n///\nalias UINT32_C = _typify!uint32_t;\n///\nalias UINT64_C = _typify!uint64_t;\n\n///\nalias INTMAX_C  = _typify!intmax_t ;\n///\nalias UINTMAX_C = _typify!uintmax_t;\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/stdio.d",
    "content": "/**\n * D header file for C99 <stdio.h>\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdio.h.html, _stdio.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly,\n *            Alex Rønne Petersen\n * Source:    https://github.com/dlang/druntime/blob/master/src/core/stdc/stdio.d\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.stdio;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nprivate\n{\n    import core.stdc.config;\n    import core.stdc.stdarg; // for va_list\n    import core.stdc.stdint : intptr_t;\n\n  version (FreeBSD)\n  {\n    import core.sys.posix.sys.types;\n  }\n  else version (OpenBSD)\n  {\n    import core.sys.posix.sys.types;\n  }\n  version (NetBSD)\n  {\n    import core.sys.posix.sys.types;\n  }\n  version (DragonFlyBSD)\n  {\n    import core.sys.posix.sys.types;\n  }\n}\n\nextern (C):\n@system:\nnothrow:\n@nogc:\n\nversion (CRuntime_DigitalMars)\n{\n    enum\n    {\n        ///\n        BUFSIZ       = 0x4000,\n        ///\n        EOF          = -1,\n        ///\n        FOPEN_MAX    = 20,\n        ///\n        FILENAME_MAX = 256, // 255 plus NULL\n        ///\n        TMP_MAX      = 32767,\n        ///\n        SYS_OPEN     = 20,      // non-standard\n    }\n\n    ///\n    enum int     _NFILE     = 60;       // non-standard\n    ///\n    enum string  _P_tmpdir  = \"\\\\\"; // non-standard\n    ///\n    enum wstring _wP_tmpdir = \"\\\\\"; // non-standard\n    ///\n    enum int     L_tmpnam   = _P_tmpdir.length + 12;\n}\nelse version (CRuntime_Microsoft)\n{\n    enum\n    {\n        ///\n        BUFSIZ       = 512,\n        ///\n        EOF          = -1,\n        ///\n        FOPEN_MAX    = 20,\n        ///\n        FILENAME_MAX = 260,\n        /// Actually int.max since Visual Studio 2015.\n        TMP_MAX      = 32767,\n        ///\n        _SYS_OPEN    = 20,      // non-standard\n    }\n\n    ///\n    enum int     _NFILE     = 512;       // non-standard\n    /// Removed since Visual Studio 2015.\n    enum string  _P_tmpdir  = \"\\\\\"; // non-standard\n    /// Removed since Visual Studio 2015.\n    enum wstring _wP_tmpdir = \"\\\\\"; // non-standard\n    /// Actually 260 since Visual Studio 2015.\n    enum int     L_tmpnam   = _P_tmpdir.length + 12;\n}\nelse version (CRuntime_Glibc)\n{\n    enum\n    {\n        ///\n        BUFSIZ       = 8192,\n        ///\n        EOF          = -1,\n        ///\n        FOPEN_MAX    = 16,\n        ///\n        FILENAME_MAX = 4095,\n        ///\n        TMP_MAX      = 238328,\n        ///\n        L_tmpnam     = 20\n    }\n}\nelse version (CRuntime_Musl)\n{\n    enum\n    {\n        ///\n        BUFSIZ       = 1024,\n        ///\n        EOF          = -1,\n        ///\n        FOPEN_MAX    = 1000,\n        ///\n        FILENAME_MAX = 4096,\n        ///\n        TMP_MAX      = 10000,\n        ///\n        L_tmpnam     = 20\n    }\n}\nelse version (Darwin)\n{\n    enum\n    {\n        ///\n        BUFSIZ       = 1024,\n        ///\n        EOF          = -1,\n        ///\n        FOPEN_MAX    = 20,\n        ///\n        FILENAME_MAX = 1024,\n        ///\n        TMP_MAX      = 308915776,\n        ///\n        L_tmpnam     = 1024,\n    }\n\n    private\n    {\n        struct __sbuf\n        {\n            ubyte*  _base;\n            int     _size;\n        }\n\n        struct __sFILEX\n        {\n\n        }\n    }\n}\nelse version (FreeBSD)\n{\n    enum\n    {\n        ///\n        BUFSIZ       = 1024,\n        ///\n        EOF          = -1,\n        ///\n        FOPEN_MAX    = 20,\n        ///\n        FILENAME_MAX = 1024,\n        ///\n        TMP_MAX      = 308915776,\n        ///\n        L_tmpnam     = 1024\n    }\n\n    struct __sbuf\n    {\n        ubyte *_base;\n        int _size;\n    }\n\n    union __mbstate_t // <sys/_types.h>\n    {\n        char[128]   _mbstate8;\n        long        _mbstateL;\n    }\n}\nelse version (NetBSD)\n{\n    enum\n    {\n        ///\n        BUFSIZ       = 1024,\n        ///\n        EOF          = -1,\n        ///\n        FOPEN_MAX    = 20,\n        ///\n        FILENAME_MAX = 1024,\n        ///\n        TMP_MAX      = 308915776,\n        ///\n        L_tmpnam     = 1024\n    }\n\n    struct __sbuf\n    {\n        ubyte *_base;\n        int _size;\n    }\n\n    union __mbstate_t // <sys/_types.h>\n    {\n        char[128]   _mbstate8;\n        long        _mbstateL;\n    }\n}\nelse version (OpenBSD)\n{\n    enum\n    {\n        ///\n        BUFSIZ       = 1024,\n        ///\n        EOF          = -1,\n        ///\n        FOPEN_MAX    = 20,\n        ///\n        FILENAME_MAX = 1024,\n        ///\n        TMP_MAX      = 0x7fffffff,\n        ///\n        L_tmpnam     = 1024\n    }\n\n    struct __sbuf\n    {\n        ubyte *_base;\n        int _size;\n    }\n\n    union __mbstate_t // <sys/_types.h>\n    {\n        char[128]   __mbstate8;\n        long        __mbstateL;\n    }\n}\nelse version (DragonFlyBSD)\n{\n    enum\n    {\n        BUFSIZ       = 1024,\n        EOF          = -1,\n        FOPEN_MAX    = 20,\n        FILENAME_MAX = 1024,\n        TMP_MAX      = 308915776,\n        L_tmpnam     = 1024\n    }\n\n    struct __sbuf {                     // <sys/sbuf.h>\n        byte*            s_buf;         // storage buffer\n        int function(void *, const char *, int) sbuf_drain_func;\n        void*            s_drain_arg;   // user-supplied drain argument\n        int              s_error;       // current error code\n        ssize_t          s_size;        // size of storage buffer\n        ssize_t          s_len;         // current length of string\n        int              s_flags;       // flags\n        ssize_t          s_sect_len;    // current length of section\n    };\n\n    enum {\n        SBUF_FIXEDLEN   = 0x00000000,   // fixed length buffer (default)\n        SBUF_AUTOEXTEND = 0x00000001,   // automatically extend buffer\n        SBUF_USRFLAGMSK = 0x0000ffff,   // mask of flags the user may specify\n        SBUF_DYNAMIC    = 0x00010000,   // s_buf must be freed\n        SBUF_FINISHED   = 0x00020000,   // set by sbuf_finish()\n        SBUF_DYNSTRUCT  = 0x00080000,   // sbuf must be freed\n        SBUF_INSECTION  = 0x00100000,   // set by sbuf_start_section()\n    }\n\n    union __mbstate_t                   // <sys/stdint.h>\n    {\n        char[128]   _mbstate8;\n        long        _mbstateL;\n    }\n}\nelse version (Solaris)\n{\n    enum\n    {\n        ///\n        BUFSIZ = 1024,\n        ///\n        EOF = -1,\n        ///\n        FOPEN_MAX = _NFILE,\n        ///\n        FILENAME_MAX = 1024,\n        ///\n        TMP_MAX = 17576,\n        ///\n        L_tmpnam = 25,\n    }\n\n    version (X86)\n        ///\n        enum int _NFILE = 60;\n    else\n        ///\n        enum int _NFILE = 20;\n}\nelse version (CRuntime_Bionic)\n{\n    enum\n    {\n        ///\n        BUFSIZ       = 1024,\n        ///\n        EOF          = -1,\n        ///\n        FOPEN_MAX    = 20,\n        ///\n        FILENAME_MAX = 1024,\n        ///\n        TMP_MAX      = 308915776,\n        ///\n        L_tmpnam     = 1024\n    }\n\n    struct __sbuf\n    {\n        ubyte* _base;\n        int _size;\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    enum\n    {\n        ///\n        BUFSIZ       = 4096,\n        ///\n        EOF          = -1,\n        ///\n        FOPEN_MAX    = 16,\n        ///\n        FILENAME_MAX = 4095,\n        ///\n        TMP_MAX      = 238328,\n        ///\n        L_tmpnam     = 20\n    }\n}\nelse\n{\n    static assert( false, \"Unsupported platform\" );\n}\n\nenum\n{\n    /// Offset is relative to the beginning\n    SEEK_SET,\n    /// Offset is relative to the current position\n    SEEK_CUR,\n    /// Offset is relative to the end\n    SEEK_END\n}\n\nversion (CRuntime_DigitalMars)\n{\n    ///\n    alias c_long fpos_t;\n\n    ///\n    struct _iobuf\n    {\n        char* _ptr;\n        int   _cnt;\n        char* _base;\n        int   _flag;\n        int   _file;\n        int   _charbuf;\n        int   _bufsiz;\n        char* __tmpnum;\n    }\n\n    ///\n    alias shared(_iobuf) FILE;\n}\nelse version (CRuntime_Microsoft)\n{\n    ///\n    alias long fpos_t;\n\n    ///\n    struct _iobuf\n    {\n        void* undefined;\n    }\n\n    ///\n    alias shared(_iobuf) FILE;\n}\nelse version (CRuntime_Glibc)\n{\n    import core.stdc.wchar_ : mbstate_t;\n    ///\n    struct fpos_t\n    {\n        long __pos; // couldn't use off_t because of static if issue\n        mbstate_t __state;\n    }\n\n    ///\n    struct _IO_FILE\n    {\n        int     _flags;\n        char*   _read_ptr;\n        char*   _read_end;\n        char*   _read_base;\n        char*   _write_base;\n        char*   _write_ptr;\n        char*   _write_end;\n        char*   _buf_base;\n        char*   _buf_end;\n        char*   _save_base;\n        char*   _backup_base;\n        char*   _save_end;\n        void*   _markers;\n        _IO_FILE* _chain;\n        int     _fileno;\n        int     _blksize;\n        int     _old_offset;\n        ushort  _cur_column;\n        byte    _vtable_offset;\n        char[1] _shortbuf;\n        void*   _lock;\n    }\n\n    ///\n    alias _IO_FILE _iobuf;\n    ///\n    alias shared(_IO_FILE) FILE;\n}\nelse version (CRuntime_Musl)\n{\n    union fpos_t\n    {\n        char[16] __opaque;\n        double __align;\n    }\n    struct _IO_FILE;\n\n    ///\n    alias _IO_FILE _iobuf; // needed for phobos\n    ///\n    alias shared(_IO_FILE) FILE;\n}\nelse version (Darwin)\n{\n    ///\n    alias long fpos_t;\n\n    ///\n    struct __sFILE\n    {\n        ubyte*    _p;\n        int       _r;\n        int       _w;\n        short     _flags;\n        short     _file;\n        __sbuf    _bf;\n        int       _lbfsize;\n\n        void*     _cookie;\n        int     function(void*)                    _close;\n        int     function(void*, char*, int)        _read;\n        fpos_t  function(void*, fpos_t, int)       _seek;\n        int     function(void*, char *, int)       _write;\n\n        __sbuf    _ub;\n        __sFILEX* _extra;\n        int       _ur;\n\n        ubyte[3]  _ubuf;\n        ubyte[1]  _nbuf;\n\n        __sbuf    _lb;\n\n        int       _blksize;\n        fpos_t    _offset;\n    }\n\n    ///\n    alias __sFILE _iobuf;\n    ///\n    alias shared(__sFILE) FILE;\n}\nelse version (FreeBSD)\n{\n    ///\n    alias off_t fpos_t;\n\n    ///\n    struct __sFILE\n    {\n        ubyte*          _p;\n        int             _r;\n        int             _w;\n        short           _flags;\n        short           _file;\n        __sbuf          _bf;\n        int             _lbfsize;\n\n        void*           _cookie;\n        int     function(void*)                 _close;\n        int     function(void*, char*, int)     _read;\n        fpos_t  function(void*, fpos_t, int)    _seek;\n        int     function(void*, in char*, int)  _write;\n\n        __sbuf          _ub;\n        ubyte*          _up;\n        int             _ur;\n\n        ubyte[3]        _ubuf;\n        ubyte[1]        _nbuf;\n\n        __sbuf          _lb;\n\n        int             _blksize;\n        fpos_t          _offset;\n\n        pthread_mutex_t _fl_mutex;\n        pthread_t       _fl_owner;\n        int             _fl_count;\n        int             _orientation;\n        __mbstate_t     _mbstate;\n    }\n\n    ///\n    alias __sFILE _iobuf;\n    ///\n    alias shared(__sFILE) FILE;\n}\nelse version (NetBSD)\n{\n    ///\n    alias off_t fpos_t;\n\n    ///\n    struct __sFILE\n    {\n        ubyte*          _p;\n        int             _r;\n        int             _w;\n        ushort           _flags;\n        short           _file;\n        __sbuf          _bf;\n        int             _lbfsize;\n\n        void*           _cookie;\n        int     function(void*)                 _close;\n        ssize_t     function(void*, char*, size_t)     _read;\n        fpos_t  function(void*, fpos_t, int)    _seek;\n        ssize_t     function(void*, in char*, size_t)  _write;\n\n        __sbuf          _ub;\n        ubyte*          _up;\n        int             _ur;\n\n        ubyte[3]        _ubuf;\n        ubyte[1]        _nbuf;\n\n        int     function(void *)    _flush;\n        /* Formerly used by fgetln/fgetwln; kept for binary compatibility */\n        char[__sbuf.sizeof - _flush.sizeof]    _lb_unused;\n\n\n        int             _blksize;\n        off_t          _offset;\n        static assert(off_t.sizeof==8);\n    }\n\n    ///\n    alias __sFILE _iobuf;\n    ///\n    alias shared(__sFILE) FILE;\n}\nelse version (OpenBSD)\n{\n    ///\n    alias fpos_t = off_t;\n\n    ///\n    struct __sFILE\n    {\n        ubyte*          _p;\n        int             _r;\n        int             _w;\n        short           _flags;\n        short           _file;\n        __sbuf          _bf;\n        int             _lbfsize;\n\n        void*           _cookie;\n        int     function(void*)                         _close;\n        int     function(void*, scope char*, int)       _read;\n        fpos_t  function(void*, fpos_t, int)            _seek;\n        int     function(void*, scope const char*, int) _write;\n\n        __sbuf          _ext;\n        ubyte*          _up;\n        int             _ur;\n\n        ubyte[3]        _ubuf;\n        ubyte[1]        _nbuf;\n\n        __sbuf          _lb;\n\n        int             _blksize;\n        fpos_t          _offset;\n    }\n\n    ///\n    alias shared(__sFILE) FILE;\n}\nelse version (DragonFlyBSD)\n{\n    alias off_t fpos_t;\n\n    /// See /usr/include/stdio.h\n    struct __FILE_public\n    {\n        ubyte*          *_p;            /* current position in (some) buffer */\n        int             _flags;         /* flags, below; this FILE is free if 0 */\n        int             _fileno;        /* fileno, if Unix descriptor, else -1 */\n        ssize_t         _r;             /* read space left for getc() */\n        ssize_t         _w;             /* write space left for putc() */\n        ssize_t         _lbfsize;       /* 0 or -_bf._size, for inline putc */\n    }\n\n    alias __FILE_public _iobuf;\n    alias shared(__FILE_public) FILE;\n}\nelse version (Solaris)\n{\n    import core.stdc.wchar_ : __mbstate_t;\n\n    ///\n    alias mbstate_t = __mbstate_t;\n\n    ///\n    alias c_long fpos_t;\n\n    version (D_LP64)\n    {\n        ///\n        struct _iobuf\n        {\n            char*      _ptr;   /* next character from/to here in buffer */\n            char*      _base;  /* the buffer */\n            char*      _end;   /* the end of the buffer */\n            size_t     _cnt;   /* number of available characters in buffer */\n            int        _file;  /* UNIX System file descriptor */\n            int        _flag;  /* the state of the stream */\n            ubyte[24]  _lock;  //rmutex_t   _lock; /* lock for this structure */\n            mbstate_t  _state; /* mbstate_t */\n            ubyte[32]  __fill; /* filler to bring size to 128 bytes */\n        }\n    }\n    else\n    {\n        ///\n        struct _iobuf\n        {\n            char* _ptr;\n            int _cnt;\n            char* _base;\n            char _flag;\n            char _magic;\n            ushort __flags; // __orientation:2\n                            // __ionolock:1\n                            // __seekable:1\n                            // __extendedfd:1\n                            // __xf_nocheck:1\n                            // __filler:10\n        }\n    }\n    ///\n    alias shared(_iobuf) FILE;\n}\nelse version (CRuntime_Bionic)\n{\n    import core.sys.posix.sys.types : off_t;\n    ///\n    alias off_t fpos_t;\n\n    ///\n    struct __sFILE\n    {\n        ubyte*    _p;\n        int       _r;\n        int       _w;\n        short     _flags;\n        short     _file;\n        __sbuf    _bf;\n        int       _lbfsize;\n\n        void*     _cookie;\n        int      function(void*)                          _close;\n        int      function(void*, scope char*, int)        _read;\n        fpos_t   function(void*, fpos_t, int)             _seek;\n        int      function(void*, scope const char*, int)  _write;\n\n        __sbuf    _ext;\n        ubyte*    _up;\n        int       _ur;\n\n        ubyte[3]  _ubuf;\n        ubyte[1]  _nbuf;\n\n        __sbuf    _lb;\n\n        int       _blksize;\n        fpos_t    _offset;\n    }\n\n    ///\n    alias __sFILE _iobuf;\n    ///\n    alias shared(__sFILE) FILE;\n}\nelse version (CRuntime_UClibc)\n{\n    import core.stdc.wchar_ : mbstate_t;\n    import core.stdc.stddef : wchar_t;\n    import core.sys.posix.sys.types : ssize_t, pthread_mutex_t;\n\n    alias long off_t;\n\n    ///\n    struct fpos_t\n    {\n        off_t __pos;\n        mbstate_t __state;\n        int __mblen_pending;\n    }\n\n    struct _IO_cookie_io_functions_t\n    {\n       ssize_t function(void* __cookie, char* __buf, size_t __bufsize)          read;\n       ssize_t function(void* __cookie, const char* __buf, size_t __bufsize)    write;\n       int function(void* __cookie, off_t* __pos, int __whence)                 seek;\n       int function(void* __cookie)                                             close;\n    }\n\n    alias _IO_cookie_io_functions_t cookie_io_functions_t;\n\n    ///\n    struct __STDIO_FILE_STRUCT\n    {\n        ushort __modeflags;\n        char[2] __ungot_width;\n        int __filedes;\n        char* __bufstart;\n        char* __bufend;\n        char* __bufpos;\n        char* __bufread;\n        char* __bufgetc_u;\n        char*__bufputc_u;\n        __STDIO_FILE_STRUCT* __nextopen;\n        void *__cookie;\n        _IO_cookie_io_functions_t __gcs;\n        wchar_t[2] __ungot;\n        mbstate_t __state;\n        void *__unused;\n        int __user_locking;\n        pthread_mutex_t __lock;\n    }\n\n    ///\n    alias __STDIO_FILE_STRUCT _iobuf;\n    ///\n    alias shared(__STDIO_FILE_STRUCT) FILE;\n}\nelse\n{\n    static assert( false, \"Unsupported platform\" );\n}\n\nenum\n{\n    ///\n    _F_RDWR = 0x0003, // non-standard\n    ///\n    _F_READ = 0x0001, // non-standard\n    ///\n    _F_WRIT = 0x0002, // non-standard\n    ///\n    _F_BUF  = 0x0004, // non-standard\n    ///\n    _F_LBUF = 0x0008, // non-standard\n    ///\n    _F_ERR  = 0x0010, // non-standard\n    ///\n    _F_EOF  = 0x0020, // non-standard\n    ///\n    _F_BIN  = 0x0040, // non-standard\n    ///\n    _F_IN   = 0x0080, // non-standard\n    ///\n    _F_OUT  = 0x0100, // non-standard\n    ///\n    _F_TERM = 0x0200, // non-standard\n}\n\nversion (CRuntime_DigitalMars)\n{\n    enum\n    {\n        ///\n        _IOFBF   = 0,\n        ///\n        _IOLBF   = 0x40,\n        ///\n        _IONBF   = 4,\n        ///\n        _IOREAD  = 1,     // non-standard\n        ///\n        _IOWRT   = 2,     // non-standard\n        ///\n        _IOMYBUF = 8,     // non-standard\n        ///\n        _IOEOF   = 0x10,  // non-standard\n        ///\n        _IOERR   = 0x20,  // non-standard\n        ///\n        _IOSTRG  = 0x40,  // non-standard\n        ///\n        _IORW    = 0x80,  // non-standard\n        ///\n        _IOTRAN  = 0x100, // non-standard\n        ///\n        _IOAPP   = 0x200, // non-standard\n    }\n\n    extern shared void function() _fcloseallp;\n\n    private extern shared FILE[_NFILE] _iob;\n\n    ///\n    enum stdin  = &_iob[0];\n    ///\n    enum stdout = &_iob[1];\n    ///\n    enum stderr = &_iob[2];\n    ///\n    enum stdaux = &_iob[3];\n    ///\n    enum stdprn = &_iob[4];\n}\nelse version (CRuntime_Microsoft)\n{\n    enum\n    {\n        ///\n        _IOFBF   = 0,\n        ///\n        _IOLBF   = 0x40,\n        ///\n        _IONBF   = 4,\n        /// Removed since Visual Studio 2015.\n        _IOREAD  = 1,     // non-standard\n        /// Removed since Visual Studio 2015.\n        _IOWRT   = 2,     // non-standard\n        /// Removed since Visual Studio 2015.\n        _IOMYBUF = 8,     // non-standard\n        /// Removed since Visual Studio 2015.\n        _IOEOF   = 0x10,  // non-standard\n        /// Removed since Visual Studio 2015.\n        _IOERR   = 0x20,  // non-standard\n        /// Removed since Visual Studio 2015.\n        _IOSTRG  = 0x40,  // non-standard\n        /// Removed since Visual Studio 2015.\n        _IORW    = 0x80,  // non-standard\n        /// Removed since Visual Studio 2015.\n        _IOAPP   = 0x200, // non-standard\n        /// Removed since Visual Studio 2015.\n        _IOAPPEND = 0x200, // non-standard\n    }\n\n    extern shared void function() _fcloseallp;\n\n    ///\n    shared FILE* stdin;  // = &__iob_func()[0];\n    ///\n    shared FILE* stdout; // = &__iob_func()[1];\n    ///\n    shared FILE* stderr; // = &__iob_func()[2];\n}\nelse version (CRuntime_Glibc)\n{\n    enum\n    {\n        ///\n        _IOFBF = 0,\n        ///\n        _IOLBF = 1,\n        ///\n        _IONBF = 2,\n    }\n\n    ///\n    extern shared FILE* stdin;\n    ///\n    extern shared FILE* stdout;\n    ///\n    extern shared FILE* stderr;\n}\nelse version (Darwin)\n{\n    enum\n    {\n        ///\n        _IOFBF = 0,\n        ///\n        _IOLBF = 1,\n        ///\n        _IONBF = 2,\n    }\n\n    private extern shared FILE* __stdinp;\n    private extern shared FILE* __stdoutp;\n    private extern shared FILE* __stderrp;\n\n    ///\n    alias __stdinp  stdin;\n    ///\n    alias __stdoutp stdout;\n    ///\n    alias __stderrp stderr;\n}\nelse version (FreeBSD)\n{\n    enum\n    {\n        ///\n        _IOFBF = 0,\n        ///\n        _IOLBF = 1,\n        ///\n        _IONBF = 2,\n    }\n\n    private extern shared FILE* __stdinp;\n    private extern shared FILE* __stdoutp;\n    private extern shared FILE* __stderrp;\n\n    ///\n    alias __stdinp  stdin;\n    ///\n    alias __stdoutp stdout;\n    ///\n    alias __stderrp stderr;\n}\nelse version (NetBSD)\n{\n    enum\n    {\n        ///\n        _IOFBF = 0,\n        ///\n        _IOLBF = 1,\n        ///\n        _IONBF = 2,\n    }\n\n    private extern __gshared FILE[3] __sF;\n    @property auto __stdin()() { return &__sF[0]; }\n    @property auto __stdout()() { return &__sF[1]; }\n    @property auto __stderr()() { return &__sF[2]; }\n    ///\n    alias __stdin stdin;\n    ///\n    alias __stdout stdout;\n    ///\n    alias __stderr stderr;\n}\nelse version (OpenBSD)\n{\n    enum\n    {\n        ///\n        _IOFBF = 0,\n        ///\n        _IOLBF = 1,\n        ///\n        _IONBF = 2,\n    }\n\n    private extern shared FILE[] __sF;\n\n    ///\n    shared stdin  = &__sF[0];\n    ///\n    shared stdout = &__sF[1];\n    ///\n    shared stderr = &__sF[2];\n}\nelse version (DragonFlyBSD)\n{\n    enum\n    {\n        _IOFBF = 0,\n        _IOLBF = 1,\n        _IONBF = 2,\n    }\n\n    private extern shared FILE* __stdinp;\n    private extern shared FILE* __stdoutp;\n    private extern shared FILE* __stderrp;\n\n    alias __stdinp  stdin;\n    alias __stdoutp stdout;\n    alias __stderrp stderr;\n}\nelse version (Solaris)\n{\n    enum\n    {\n        ///\n        _IOFBF = 0x00,\n        ///\n        _IOLBF = 0x40,\n        ///\n        _IONBF = 0x04,\n        ///\n        _IOEOF = 0x20,\n        ///\n        _IOERR = 0x40,\n        ///\n        _IOREAD = 0x01,\n        ///\n        _IOWRT = 0x02,\n        ///\n        _IORW = 0x80,\n        ///\n        _IOMYBUF = 0x08,\n    }\n\n    private extern shared FILE[_NFILE] __iob;\n\n    ///\n    shared stdin = &__iob[0];\n    ///\n    shared stdout = &__iob[1];\n    ///\n    shared stderr = &__iob[2];\n}\nelse version (CRuntime_Bionic)\n{\n    enum\n    {\n        ///\n        _IOFBF = 0,\n        ///\n        _IOLBF = 1,\n        ///\n        _IONBF = 2,\n    }\n\n    private extern shared FILE[3] __sF;\n\n    ///\n    shared stdin  = &__sF[0];\n    ///\n    shared stdout = &__sF[1];\n    ///\n    shared stderr = &__sF[2];\n}\nelse version (CRuntime_Musl)\n{\n    // needs tail const\n    extern shared FILE* stdin;\n    ///\n    extern shared FILE* stdout;\n    ///\n    extern shared FILE* stderr;\n    enum\n    {\n        ///\n        _IOFBF = 0,\n        ///\n        _IOLBF = 1,\n        ///\n        _IONBF = 2,\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    enum\n    {\n        ///\n        _IOFBF = 0,\n        ///\n        _IOLBF = 1,\n        ///\n        _IONBF = 2,\n    }\n\n    ///\n    extern shared FILE* stdin;\n    ///\n    extern shared FILE* stdout;\n    ///\n    extern shared FILE* stderr;\n}\nelse\n{\n    static assert( false, \"Unsupported platform\" );\n}\n\n///\nint remove(scope const char* filename);\n///\nint rename(scope const char* from, scope const char* to);\n\n///\n@trusted FILE* tmpfile(); // No unsafe pointer manipulation.\n///\nchar* tmpnam(char* s);\n\n///\nint   fclose(FILE* stream);\n\n// No unsafe pointer manipulation.\n@trusted\n{\n    ///\n    int   fflush(FILE* stream);\n}\n\n///\nFILE* fopen(scope const char* filename, scope const char* mode);\n///\nFILE* freopen(scope const char* filename, scope const char* mode, FILE* stream);\n\n///\nvoid setbuf(FILE* stream, char* buf);\n///\nint  setvbuf(FILE* stream, char* buf, int mode, size_t size);\n\nversion (MinGW)\n{\n    // Prefer the MinGW versions over the MSVC ones, as the latter don't handle\n    // reals at all.\n    ///\n    int __mingw_fprintf(FILE* stream, scope const char* format, ...);\n    ///\n    alias __mingw_fprintf fprintf;\n\n    ///\n    int __mingw_fscanf(FILE* stream, scope const char* format, ...);\n    ///\n    alias __mingw_fscanf fscanf;\n\n    ///\n    int __mingw_sprintf(scope char* s, scope const char* format, ...);\n    ///\n    alias __mingw_sprintf sprintf;\n\n    ///\n    int __mingw_sscanf(scope const char* s, scope const char* format, ...);\n    ///\n    alias __mingw_sscanf sscanf;\n\n    ///\n    int __mingw_vfprintf(FILE* stream, scope const char* format, va_list arg);\n    ///\n    alias __mingw_vfprintf vfprintf;\n\n    ///\n    int __mingw_vfscanf(FILE* stream, scope const char* format, va_list arg);\n    ///\n    alias __mingw_vfscanf vfscanf;\n\n    ///\n    int __mingw_vsprintf(scope char* s, scope const char* format, va_list arg);\n    ///\n    alias __mingw_vsprintf vsprintf;\n\n    ///\n    int __mingw_vsscanf(scope const char* s, scope const char* format, va_list arg);\n    ///\n    alias __mingw_vsscanf vsscanf;\n\n    ///\n    int __mingw_vprintf(scope const char* format, va_list arg);\n    ///\n    alias __mingw_vprintf vprintf;\n\n    ///\n    int __mingw_vscanf(scope const char* format, va_list arg);\n    ///\n    alias __mingw_vscanf vscanf;\n\n    ///\n    int __mingw_printf(scope const char* format, ...);\n    ///\n    alias __mingw_printf printf;\n\n    ///\n    int __mingw_scanf(scope const char* format, ...);\n    ///\n    alias __mingw_scanf scanf;\n}\nelse\n{\n    ///\n    int fprintf(FILE* stream, scope const char* format, ...);\n    ///\n    int fscanf(FILE* stream, scope const char* format, ...);\n    ///\n    int sprintf(scope char* s, scope const char* format, ...);\n    ///\n    int sscanf(scope const char* s, scope const char* format, ...);\n    ///\n    int vfprintf(FILE* stream, scope const char* format, va_list arg);\n    ///\n    int vfscanf(FILE* stream, scope const char* format, va_list arg);\n    ///\n    int vsprintf(scope char* s, scope const char* format, va_list arg);\n    ///\n    int vsscanf(scope const char* s, scope const char* format, va_list arg);\n    ///\n    int vprintf(scope const char* format, va_list arg);\n    ///\n    int vscanf(scope const char* format, va_list arg);\n    ///\n    int printf(scope const char* format, ...);\n    ///\n    int scanf(scope const char* format, ...);\n}\n\n// No unsafe pointer manipulation.\n@trusted\n{\n    ///\n    int fgetc(FILE* stream);\n    ///\n    int fputc(int c, FILE* stream);\n}\n\n///\nchar* fgets(char* s, int n, FILE* stream);\n///\nint   fputs(scope const char* s, FILE* stream);\n///\nchar* gets(char* s);\n///\nint   puts(scope const char* s);\n\n// No unsafe pointer manipulation.\nextern (D) @trusted\n{\n    ///\n    int getchar()()                 { return getc(stdin);     }\n    ///\n    int putchar()(int c)            { return putc(c,stdout);  }\n    ///\n    int getc()(FILE* stream)        { return fgetc(stream);   }\n    ///\n    int putc()(int c, FILE* stream) { return fputc(c,stream); }\n}\n\n///\n@trusted int ungetc(int c, FILE* stream); // No unsafe pointer manipulation.\n\n///\nsize_t fread(scope void* ptr, size_t size, size_t nmemb, FILE* stream);\n///\nsize_t fwrite(scope const void* ptr, size_t size, size_t nmemb, FILE* stream);\n\n// No unsafe pointer manipulation.\n@trusted\n{\n    ///\n    int fgetpos(FILE* stream, scope fpos_t * pos);\n    ///\n    int fsetpos(FILE* stream, scope const fpos_t* pos);\n\n    ///\n    int    fseek(FILE* stream, c_long offset, int whence);\n    ///\n    c_long ftell(FILE* stream);\n}\n\nversion (MinGW)\n{\n  // No unsafe pointer manipulation.\n  extern (D) @trusted\n  {\n    ///\n    void rewind()(FILE* stream)   { fseek(stream,0L,SEEK_SET); stream._flag = stream._flag & ~_IOERR; }\n    ///\n    pure void clearerr()(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); }\n    ///\n    pure int  feof()(FILE* stream)     { return stream._flag&_IOEOF; }\n    ///\n    pure int  ferror()(FILE* stream)   { return stream._flag&_IOERR; }\n  }\n  ///\n    int   __mingw_snprintf(scope char* s, size_t n, scope const char* fmt, ...);\n    ///\n    alias __mingw_snprintf _snprintf;\n    ///\n    alias __mingw_snprintf snprintf;\n\n    ///\n    int   __mingw_vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n    ///\n    alias __mingw_vsnprintf _vsnprintf;\n    ///\n    alias __mingw_vsnprintf vsnprintf;\n}\nelse version (CRuntime_DigitalMars)\n{\n  // No unsafe pointer manipulation.\n  extern (D) @trusted\n  {\n    ///\n    void rewind()(FILE* stream)   { fseek(stream,0L,SEEK_SET); stream._flag= stream._flag & ~_IOERR; }\n    ///\n    pure void clearerr()(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); }\n    ///\n    pure int  feof()(FILE* stream)     { return stream._flag&_IOEOF; }\n    ///\n    pure int  ferror()(FILE* stream)   { return stream._flag&_IOERR; }\n    ///\n    pure int  fileno()(FILE* stream)   { return stream._file; }\n  }\n  ///\n    int   _snprintf(scope char* s, size_t n, scope const char* fmt, ...);\n    ///\n    alias _snprintf snprintf;\n\n    ///\n    int   _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n    ///\n    alias _vsnprintf vsnprintf;\n}\nelse version (CRuntime_Microsoft)\n{\n  // No unsafe pointer manipulation.\n  @trusted\n  {\n    ///\n    void rewind(FILE* stream);\n    ///\n    pure void clearerr(FILE* stream);\n    ///\n    pure int  feof(FILE* stream);\n    ///\n    pure int  ferror(FILE* stream);\n    ///\n    pure int  fileno(FILE* stream);\n  }\n\n    ///\n    int _snprintf(scope char* s, size_t n, scope const char* format, ...);\n    ///\n    int  snprintf(scope char* s, size_t n, scope const char* format, ...);\n\n    ///\n    int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n    ///\n    int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n\n    ///\n    int _fputc_nolock(int c, FILE *fp);\n    ///\n    int _fgetc_nolock(FILE *fp);\n\n    ///\n    int _lock_file(FILE *fp);\n    ///\n    int _unlock_file(FILE *fp);\n\n    ///\n    intptr_t _get_osfhandle(int fd);\n    ///\n    int _open_osfhandle(intptr_t osfhandle, int flags);\n}\nelse version (CRuntime_Glibc)\n{\n  // No unsafe pointer manipulation.\n  @trusted\n  {\n    ///\n    void rewind(FILE* stream);\n    ///\n    pure void clearerr(FILE* stream);\n    ///\n    pure int  feof(FILE* stream);\n    ///\n    pure int  ferror(FILE* stream);\n    ///\n    int  fileno(FILE *);\n  }\n\n    ///\n    int  snprintf(scope char* s, size_t n, scope const char* format, ...);\n    ///\n    int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n}\nelse version (Darwin)\n{\n  // No unsafe pointer manipulation.\n  @trusted\n  {\n    ///\n    void rewind(FILE*);\n    ///\n    pure void clearerr(FILE*);\n    ///\n    pure int  feof(FILE*);\n    ///\n    pure int  ferror(FILE*);\n    ///\n    int  fileno(FILE*);\n  }\n\n    ///\n    int  snprintf(scope char* s, size_t n, scope const char* format, ...);\n    ///\n    int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n}\nelse version (FreeBSD)\n{\n  // No unsafe pointer manipulation.\n  @trusted\n  {\n    ///\n    void rewind(FILE*);\n    ///\n    pure void clearerr(FILE*);\n    ///\n    pure int  feof(FILE*);\n    ///\n    pure int  ferror(FILE*);\n    ///\n    int  fileno(FILE*);\n  }\n\n    ///\n    int  snprintf(scope char* s, size_t n, scope const char* format, ...);\n    ///\n    int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n}\nelse version (NetBSD)\n{\n  // No unsafe pointer manipulation.\n  @trusted\n  {\n    ///\n    void rewind(FILE*);\n    ///\n    pure void clearerr(FILE*);\n    ///\n    pure int  feof(FILE*);\n    ///\n    pure int  ferror(FILE*);\n    ///\n    int  fileno(FILE*);\n  }\n\n    ///\n    int  snprintf(char* s, size_t n, in char* format, ...);\n    ///\n    int  vsnprintf(char* s, size_t n, in char* format, va_list arg);\n}\nelse version (OpenBSD)\n{\n    // No unsafe pointer manipulation.\n    @trusted\n    {\n        ///\n        void rewind(FILE*);\n    }\n    @trusted private\n    {\n        ///\n        pure void clearerr(FILE*);\n        alias __clearerr = clearerr;\n        ///\n        pure int  feof(FILE*);\n        alias __feof = feof;\n        ///\n        pure int  ferror(FILE*);\n        alias __ferror = ferror;\n        ///\n        int  fileno(FILE*);\n        alias __fileno = fileno;\n    }\n\n    enum __SLBF = 0x0001;\n    enum __SNBF = 0x0002;\n    enum __SRD  = 0x0004;\n    enum __SWR  = 0x0008;\n    enum __SRW  = 0x0010;\n    enum __SEOF = 0x0020;\n    enum __SERR = 0x0040;\n    enum __SMBF = 0x0080;\n    enum __SAPP = 0x0100;\n    enum __SSTR = 0x0200;\n    enum __SOPT = 0x0400;\n    enum __SNPT = 0x0800;\n    enum __SOFF = 0x1000;\n    enum __SMOD = 0x2000;\n    enum __SALC = 0x4000;\n    enum __SIGN = 0x8000;\n\n    extern int __isthreaded;\n\n    extern (D)\n    {\n        void __sclearerr()(FILE* p)\n        {\n            p._flags &= ~(__SERR|__SEOF);\n        }\n\n        int __sfeof()(FILE* p)\n        {\n            return (p._flags & __SEOF) != 0;\n        }\n\n        int __sferror()(FILE* p)\n        {\n            return (p._flags & __SERR) != 0;\n        }\n\n        int __sfileno()(FILE* p)\n        {\n            return p._file;\n        }\n\n        int clearerr()(FILE* file)\n        {\n            return !__isthreaded ? __sclearerr(file) : __clearerr(file);\n        }\n\n        int feof()(FILE* file)\n        {\n            return !__isthreaded ? __sfeof(file) : __feof(file);\n        }\n\n        int ferror()(FILE* file)\n        {\n            return !__isthreaded ? __sferror(file) : __ferror(file);\n        }\n\n        int fileno()(FILE* file)\n        {\n            return !__isthreaded ? __sfileno(file) : __fileno(file);\n        }\n    }\n\n    ///\n    int  snprintf(scope char* s, size_t n, scope const char* format, ...);\n    ///\n    int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n}\nelse version (DragonFlyBSD)\n{\n  // No unsafe pointer manipulation.\n  @trusted\n  {\n    void rewind(FILE*);\n    pure void clearerr(FILE*);\n    pure int  feof(FILE*);\n    pure int  ferror(FILE*);\n    int  fileno(FILE*);\n  }\n  enum __SLBF = 0x0001;\n  enum __SNBF = 0x0002;\n  enum __SRD  = 0x0004;\n  enum __SWR  = 0x0008;\n  enum __SRW  = 0x0010;\n  enum __SEOF = 0x0020;\n  enum __SERR = 0x0040;\n  enum __SMBF = 0x0080;\n  enum __SAPP = 0x0100;\n  enum __SSTR = 0x0200;\n  enum __SOPT = 0x0400;\n  enum __SNPT = 0x0800;\n  enum __SOFF = 0x1000;\n  enum __SMOD = 0x2000;\n  enum __SALC = 0x4000;\n  enum __SIGN = 0x8000;\n\n  int  snprintf(scope char* s, size_t n, scope const char* format, ...);\n  int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n}\nelse version (Solaris)\n{\n  // No unsafe pointer manipulation.\n  @trusted\n  {\n    ///\n    void rewind(FILE*);\n    ///\n    pure void clearerr(FILE*);\n    ///\n    pure int  feof(FILE*);\n    ///\n    pure int  ferror(FILE*);\n    ///\n    int  fileno(FILE*);\n  }\n\n    ///\n    int  snprintf(scope char* s, size_t n, scope const char* format, ...);\n    ///\n    int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n}\nelse version (CRuntime_Bionic)\n{\n  // No unsafe pointer manipulation.\n  @trusted\n  {\n    ///\n    void rewind(FILE*);\n    ///\n    pure void clearerr(FILE*);\n    ///\n    pure int  feof(FILE*);\n    ///\n    pure int  ferror(FILE*);\n    ///\n    int  fileno(FILE*);\n  }\n\n  ///\n    int  snprintf(scope char* s, size_t n, scope const char* format, ...);\n    ///\n    int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n}\nelse version (CRuntime_Musl)\n{\n    import core.sys.posix.sys.types : off_t;\n    ///\n    int fseeko(FILE *, off_t, int);\n    @trusted\n    {\n        ///\n        void rewind(FILE* stream);\n        ///\n        pure void clearerr(FILE* stream);\n        ///\n        pure int  feof(FILE* stream);\n        ///\n        pure int  ferror(FILE* stream);\n        ///\n        int  fileno(FILE *);\n    }\n\n    ///\n    int snprintf(scope char* s, size_t n, scope const char* format, ...);\n    ///\n    int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n}\nelse version (CRuntime_UClibc)\n{\n  // No unsafe pointer manipulation.\n  @trusted\n  {\n    ///\n    void rewind(FILE* stream);\n    ///\n    pure void clearerr(FILE* stream);\n    ///\n    pure int  feof(FILE* stream);\n    ///\n    pure int  ferror(FILE* stream);\n    ///\n    int  fileno(FILE *);\n  }\n\n    ///\n    int  snprintf(scope char* s, size_t n, scope const char* format, ...);\n    ///\n    int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);\n}\nelse\n{\n    static assert( false, \"Unsupported platform\" );\n}\n\n///\nvoid perror(scope const char* s);\n\nversion (CRuntime_DigitalMars)\n{\n    version (none)\n        import core.sys.windows.windows : HANDLE, _WaitSemaphore, _ReleaseSemaphore;\n    else\n    {\n        // too slow to import windows\n        private alias void* HANDLE;\n        private void _WaitSemaphore(int iSemaphore);\n        private void _ReleaseSemaphore(int iSemaphore);\n    }\n\n    enum\n    {\n        ///\n        FHND_APPEND     = 0x04,\n        ///\n        FHND_DEVICE     = 0x08,\n        ///\n        FHND_TEXT       = 0x10,\n        ///\n        FHND_BYTE       = 0x20,\n        ///\n        FHND_WCHAR      = 0x40,\n    }\n\n    private enum _MAX_SEMAPHORES = 10 + _NFILE;\n    private enum _semIO = 3;\n\n    private extern __gshared short[_MAX_SEMAPHORES] _iSemLockCtrs;\n    private extern __gshared int[_MAX_SEMAPHORES] _iSemThreadIds;\n    private extern __gshared int[_MAX_SEMAPHORES] _iSemNestCount;\n    private extern __gshared HANDLE[_NFILE] _osfhnd;\n    extern shared ubyte[_NFILE] __fhnd_info;\n\n    // this is copied from semlock.h in DMC's runtime.\n    private void LockSemaphore()(uint num)\n    {\n        asm nothrow @nogc\n        {\n            mov EDX, num;\n            lock;\n            inc _iSemLockCtrs[EDX * 2];\n            jz lsDone;\n            push EDX;\n            call _WaitSemaphore;\n            add ESP, 4;\n        }\n\n    lsDone: {}\n    }\n\n    // this is copied from semlock.h in DMC's runtime.\n    private void UnlockSemaphore()(uint num)\n    {\n        asm nothrow @nogc\n        {\n            mov EDX, num;\n            lock;\n            dec _iSemLockCtrs[EDX * 2];\n            js usDone;\n            push EDX;\n            call _ReleaseSemaphore;\n            add ESP, 4;\n        }\n\n    usDone: {}\n    }\n\n    // This converts a HANDLE to a file descriptor in DMC's runtime\n    ///\n    int _handleToFD()(HANDLE h, int flags)\n    {\n        LockSemaphore(_semIO);\n        scope(exit) UnlockSemaphore(_semIO);\n\n        foreach (fd; 0 .. _NFILE)\n        {\n            if (!_osfhnd[fd])\n            {\n                _osfhnd[fd] = h;\n                __fhnd_info[fd] = cast(ubyte)flags;\n                return fd;\n            }\n        }\n\n        return -1;\n    }\n\n    ///\n    HANDLE _fdToHandle()(int fd)\n    {\n        // no semaphore is required, once inserted, a file descriptor\n        // doesn't change.\n        if (fd < 0 || fd >= _NFILE)\n            return null;\n\n        return _osfhnd[fd];\n    }\n\n    enum\n    {\n        ///\n        STDIN_FILENO  = 0,\n        ///\n        STDOUT_FILENO = 1,\n        ///\n        STDERR_FILENO = 2,\n    }\n\n    int open(scope const(char)* filename, int flags, ...); ///\n    alias _open = open; ///\n    int _wopen(scope const wchar* filename, int oflag, ...); ///\n    int sopen(scope const char* filename, int oflag, int shflag, ...); ///\n    alias _sopen = sopen; ///\n    int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); ///\n    int close(int fd); ///\n    alias _close = close; ///\n    FILE *fdopen(int fd, scope const(char)* flags); ///\n    alias _fdopen = fdopen; ///\n    FILE *_wfdopen(int fd, scope const(wchar)* flags); ///\n\n}\nelse version (CRuntime_Microsoft)\n{\n    int _open(scope const char* filename, int oflag, ...); ///\n    int _wopen(scope const wchar* filename, int oflag, ...); ///\n    int _sopen(scope const char* filename, int oflag, int shflag, ...); ///\n    int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); ///\n    int _close(int fd); ///\n    FILE *_fdopen(int fd, scope const(char)* flags); ///\n    FILE *_wfdopen(int fd, scope const(wchar)* flags); ///\n}\n\nversion (Windows)\n{\n    // file open flags\n    enum\n    {\n        _O_RDONLY = 0x0000, ///\n        O_RDONLY = _O_RDONLY, ///\n        _O_WRONLY = 0x0001, ///\n        O_WRONLY = _O_WRONLY, ///\n        _O_RDWR   = 0x0002, ///\n        O_RDWR = _O_RDWR, ///\n        _O_APPEND = 0x0008, ///\n        O_APPEND = _O_APPEND, ///\n        _O_CREAT  = 0x0100, ///\n        O_CREAT = _O_CREAT, ///\n        _O_TRUNC  = 0x0200, ///\n        O_TRUNC = _O_TRUNC, ///\n        _O_EXCL   = 0x0400, ///\n        O_EXCL = _O_EXCL, ///\n        _O_TEXT   = 0x4000, ///\n        O_TEXT = _O_TEXT, ///\n        _O_BINARY = 0x8000, ///\n        O_BINARY = _O_BINARY, ///\n    }\n\n    enum\n    {\n        _S_IREAD  = 0x0100, /// read permission, owner\n        S_IREAD = _S_IREAD, /// read permission, owner\n        _S_IWRITE = 0x0080, /// write permission, owner\n        S_IWRITE = _S_IWRITE, /// write permission, owner\n    }\n\n    enum\n    {\n        _SH_DENYRW = 0x10, /// deny read/write mode\n        SH_DENYRW = _SH_DENYRW, /// deny read/write mode\n        _SH_DENYWR = 0x20, /// deny write mode\n        SH_DENYWR = _SH_DENYWR, /// deny write mode\n        _SH_DENYRD = 0x30, /// deny read mode\n        SH_DENYRD = _SH_DENYRD, /// deny read mode\n        _SH_DENYNO = 0x40, /// deny none mode\n        SH_DENYNO = _SH_DENYNO, /// deny none mode\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/stdlib.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdlib.h.html, _stdlib.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2014.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Standards: ISO/IEC 9899:1999 (E)\n * Source: $(DRUNTIMESRC src/core/stdc/_stdlib.d)\n */\n\nmodule core.stdc.stdlib;\n\nprivate import core.stdc.config;\npublic import core.stdc.stddef; // for wchar_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nextern (C):\n@system:\n\n/* Placed outside `nothrow` and `@nogc` in order to not constrain what the callback does.\n */\n///\nalias _compare_fp_t = int function(const void*, const void*);\n\nnothrow:\n@nogc:\n\n///\ninout(void)* bsearch(const void* key, inout(void)* base, size_t nmemb, size_t size, _compare_fp_t compar);\n///\nvoid    qsort(void* base, size_t nmemb, size_t size, _compare_fp_t compar);\n\n// https://issues.dlang.org/show_bug.cgi?id=17188\n@system unittest\n{\n    struct S\n    {\n        extern(C) static int cmp(const void*, const void*) { return 0; }\n    }\n    int[4] arr;\n    qsort(arr.ptr, arr[0].sizeof, arr.length, &S.cmp);\n    int key;\n    bsearch(&key, arr.ptr, arr[0].sizeof, arr.length, &S.cmp);\n}\n\n///\nstruct div_t\n{\n    int quot,\n        rem;\n}\n\n///\nstruct ldiv_t\n{\n    int quot,\n        rem;\n}\n\n///\nstruct lldiv_t\n{\n    long quot,\n         rem;\n}\n\n///\nenum EXIT_SUCCESS = 0;\n///\nenum EXIT_FAILURE = 1;\n///\nenum MB_CUR_MAX   = 1;\n\n///\nversion (Windows)      enum RAND_MAX = 0x7fff;\nelse version (CRuntime_Glibc)  enum RAND_MAX = 0x7fffffff;\nelse version (Darwin)  enum RAND_MAX = 0x7fffffff;\nelse version (FreeBSD) enum RAND_MAX = 0x7ffffffd;\nelse version (NetBSD)  enum RAND_MAX = 0x7fffffff;\nelse version (OpenBSD) enum RAND_MAX = 0x7fffffff;\nelse version (DragonFlyBSD) enum RAND_MAX = 0x7fffffff;\nelse version (Solaris) enum RAND_MAX = 0x7fff;\nelse version (CRuntime_Bionic) enum RAND_MAX = 0x7fffffff;\nelse version (CRuntime_Musl) enum RAND_MAX = 0x7fffffff;\nelse version (CRuntime_UClibc) enum RAND_MAX = 0x7fffffff;\nelse static assert( false, \"Unsupported platform\" );\n\n///\ndouble  atof(scope const char* nptr);\n///\nint     atoi(scope const char* nptr);\n///\nc_long  atol(scope const char* nptr);\n///\nlong    atoll(scope const char* nptr);\n\n///\ndouble  strtod(scope inout(char)* nptr, scope inout(char)** endptr);\n///\nfloat   strtof(scope inout(char)* nptr, scope inout(char)** endptr);\n///\nc_long  strtol(scope inout(char)* nptr, scope inout(char)** endptr, int base);\n///\nlong    strtoll(scope inout(char)* nptr, scope inout(char)** endptr, int base);\n///\nc_ulong strtoul(scope inout(char)* nptr, scope inout(char)** endptr, int base);\n///\nulong   strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);\n\nversion (CRuntime_Microsoft)\n{\n    // strtold exists starting from VS2013, so we give it D linkage to avoid link errors\n    ///\n    extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)\n    {   // Fake it 'till we make it\n        return strtod(nptr, endptr);\n    }\n}\nelse version (MinGW)\n{\n    ///\n    real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);\n    ///\n    alias __mingw_strtold strtold;\n}\nelse\n{\n    /// Added to Bionic since Lollipop.\n    real strtold(scope inout(char)* nptr, scope inout(char)** endptr);\n}\n\n// No unsafe pointer manipulation.\n@trusted\n{\n    /// These two were added to Bionic in Lollipop.\n    int     rand();\n    ///\n    void    srand(uint seed);\n}\n\n// We don't mark these @trusted. Given that they return a void*, one has\n// to do a pointer cast to do anything sensible with the result. Thus,\n// functions using these already have to be @trusted, allowing them to\n// call @system stuff anyway.\n///\nvoid*   malloc(size_t size);\n///\nvoid*   calloc(size_t nmemb, size_t size);\n///\nvoid*   realloc(void* ptr, size_t size);\n///\nvoid    free(void* ptr);\n\n///\nvoid    abort() @safe;\n///\nvoid    exit(int status);\n///\nint     atexit(void function() func);\n///\nvoid    _Exit(int status);\n\n///\nchar*   getenv(scope const char* name);\n///\nint     system(scope const char* string);\n\n// These only operate on integer values.\n@trusted\n{\n    ///\n    pure int     abs(int j);\n    ///\n    pure c_long  labs(c_long j);\n    ///\n    pure long    llabs(long j);\n\n    ///\n    div_t   div(int numer, int denom);\n    ///\n    ldiv_t  ldiv(c_long numer, c_long denom);\n    ///\n    lldiv_t lldiv(long numer, long denom);\n}\n\n///\nint     mblen(scope const char* s, size_t n);\n///\nint     mbtowc(scope wchar_t* pwc, scope const char* s, size_t n);\n///\nint     wctomb(scope char* s, wchar_t wc);\n///\nsize_t  mbstowcs(scope wchar_t* pwcs, scope const char* s, size_t n);\n///\nsize_t  wcstombs(scope char* s, scope const wchar_t* pwcs, size_t n);\n\n///\nversion (DigitalMars)\n{\n    // See malloc comment about @trusted.\n    void* alloca(size_t size) pure; // non-standard\n}\nelse version (GNU)\n{\n    void* alloca(size_t size) pure; // compiler intrinsic\n}\nelse version (LDC)\n{\n    pragma(LDC_alloca)\n    void* alloca(size_t size) pure;\n}\n\nversion (CRuntime_Microsoft)\n{\n    ///\n    ulong  _strtoui64(scope inout(char)*, scope inout(char)**,int);\n    ///\n    ulong  _wcstoui64(scope inout(wchar)*, scope inout(wchar)**,int);\n\n    ///\n    long  _strtoi64(scope inout(char)*, scope inout(char)**,int);\n    ///\n    long  _wcstoi64(scope inout(wchar)*, scope inout(wchar)**,int);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/string.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_string.h.html, _string.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_string.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.string;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nextern (C):\n@system:\nnothrow:\n@nogc:\n\n///\npure void* memchr(return const void* s, int c, size_t n);\n///\npure int   memcmp(scope const void* s1, scope const void* s2, size_t n);\n///\npure void* memcpy(return void* s1, scope const void* s2, size_t n);\nversion (Windows)\n{\n    ///\n    int memicmp(scope const char* s1, scope const char* s2, size_t n);\n}\n///\npure void* memmove(return void* s1, scope const void* s2, size_t n);\n///\npure void* memset(return void* s, int c, size_t n);\n\n///\npure char*  strcpy(return char* s1, scope const char* s2);\n///\npure char*  strncpy(return char* s1, scope const char* s2, size_t n);\n///\npure char*  strcat(return char* s1, scope const char* s2);\n///\npure char*  strncat(return char* s1, scope const char* s2, size_t n);\n///\npure int    strcmp(scope const char* s1, scope const char* s2);\n///\nint    strcoll(scope const char* s1, scope const char* s2);\n///\npure int    strncmp(scope const char* s1, scope const char* s2, size_t n);\n///\nsize_t strxfrm(scope char* s1, scope const char* s2, size_t n);\n///\npure inout(char)*  strchr(return inout(char)* s, int c);\n///\npure size_t strcspn(scope const char* s1, scope const char* s2);\n///\npure inout(char)*  strpbrk(return inout(char)* s1, scope const char* s2);\n///\npure inout(char)*  strrchr(return inout(char)* s, int c);\n///\npure size_t strspn(scope const char* s1, scope const char* s2);\n///\npure inout(char)*  strstr(return inout(char)* s1, scope const char* s2);\n///\nchar*  strtok(return char* s1, scope const char* s2);\n///\nchar*  strerror(int errnum);\nversion (CRuntime_Glibc)\n{\n    ///\n    const(char)* strerror_r(int errnum, return char* buf, size_t buflen);\n}\nelse version (Darwin)\n{\n    int strerror_r(int errnum, scope char* buf, size_t buflen);\n}\nelse version (FreeBSD)\n{\n    int strerror_r(int errnum, scope char* buf, size_t buflen);\n}\nelse version (NetBSD)\n{\n    int strerror_r(int errnum, char* buf, size_t buflen);\n}\nelse version (OpenBSD)\n{\n    int strerror_r(int errnum, scope char* buf, size_t buflen);\n}\nelse version (DragonFlyBSD)\n{\n    int strerror_r(int errnum, scope char* buf, size_t buflen);\n}\nelse version (Solaris)\n{\n    int strerror_r(int errnum, scope char* buf, size_t buflen);\n}\nelse version (CRuntime_Bionic)\n{\n    ///\n    int strerror_r(int errnum, scope char* buf, size_t buflen);\n}\nelse version (CRuntime_Musl)\n{\n    ///\n    int strerror_r(int errnum, scope char *buf, size_t buflen);\n}\nelse version (CRuntime_UClibc)\n{\n    ///\n    const(char)* strerror_r(int errnum, return char* buf, size_t buflen);\n}\n///\npure size_t strlen(scope const char* s);\n///\nchar*  strdup(scope const char *s);\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/tgmath.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_tgmath.h.html, _tgmath.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_tgmath.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.tgmath;\n\nprivate import core.stdc.config;\nprivate static import core.stdc.math;\nprivate static import core.stdc.complex;\n\nextern (C):\n@trusted: // Everything here operates on floating point and integer values.\nnothrow:\n@nogc:\n\nversion (FreeBSD)\n{\n    ///\n    alias core.stdc.math.acos          acos;\n    ///\n    alias core.stdc.math.acosf         acos;\n    ///\n    alias core.stdc.math.acosl         acos;\n\n    ///\n    alias core.stdc.complex.cacos      acos;\n    ///\n    alias core.stdc.complex.cacosf     acos;\n    ///\n    alias core.stdc.complex.cacosl     acos;\n\n    ///\n    alias core.stdc.math.asin          asin;\n    ///\n    alias core.stdc.math.asinf         asin;\n    ///\n    alias core.stdc.math.asinl         asin;\n\n    ///\n    alias core.stdc.complex.casin      asin;\n    ///\n    alias core.stdc.complex.casinf     asin;\n    ///\n    alias core.stdc.complex.casinl     asin;\n\n    ///\n    alias core.stdc.math.atan          atan;\n    ///\n    alias core.stdc.math.atanf         atan;\n    ///\n    alias core.stdc.math.atanl         atan;\n\n    ///\n    alias core.stdc.complex.catan      atan;\n    ///\n    alias core.stdc.complex.catanf     atan;\n    ///\n    alias core.stdc.complex.catanl     atan;\n\n    ///\n    alias core.stdc.math.atan2         atan2;\n    ///\n    alias core.stdc.math.atan2f        atan2;\n    ///\n    alias core.stdc.math.atan2l        atan2;\n\n    ///\n    alias core.stdc.math.cos           cos;\n    ///\n    alias core.stdc.math.cosf          cos;\n    ///\n    alias core.stdc.math.cosl          cos;\n\n    ///\n    alias core.stdc.complex.ccos       cos;\n    ///\n    alias core.stdc.complex.ccosf      cos;\n    ///\n    alias core.stdc.complex.ccosl      cos;\n\n    ///\n    alias core.stdc.math.sin           sin;\n    ///\n    alias core.stdc.math.sinf          sin;\n    ///\n    alias core.stdc.math.sinl          sin;\n\n    ///\n    alias core.stdc.complex.csin       csin;\n    ///\n    alias core.stdc.complex.csinf      csin;\n    ///\n    alias core.stdc.complex.csinl      csin;\n\n    ///\n    alias core.stdc.math.tan           tan;\n    ///\n    alias core.stdc.math.tanf          tan;\n    ///\n    alias core.stdc.math.tanl          tan;\n\n    ///\n    alias core.stdc.complex.ctan       tan;\n    ///\n    alias core.stdc.complex.ctanf      tan;\n    ///\n    alias core.stdc.complex.ctanl      tan;\n\n    ///\n    alias core.stdc.math.acosh         acosh;\n    ///\n    alias core.stdc.math.acoshf        acosh;\n    ///\n    alias core.stdc.math.acoshl        acosh;\n\n    ///\n    alias core.stdc.complex.cacosh     acosh;\n    ///\n    alias core.stdc.complex.cacoshf    acosh;\n    ///\n    alias core.stdc.complex.cacoshl    acosh;\n\n    ///\n    alias core.stdc.math.asinh         asinh;\n    ///\n    alias core.stdc.math.asinhf        asinh;\n    ///\n    alias core.stdc.math.asinhl        asinh;\n\n    ///\n    alias core.stdc.complex.casinh     asinh;\n    ///\n    alias core.stdc.complex.casinhf    asinh;\n    ///\n    alias core.stdc.complex.casinhl    asinh;\n\n    ///\n    alias core.stdc.math.atanh         atanh;\n    ///\n    alias core.stdc.math.atanhf        atanh;\n    ///\n    alias core.stdc.math.atanhl        atanh;\n\n    ///\n    alias core.stdc.complex.catanh     atanh;\n    ///\n    alias core.stdc.complex.catanhf    atanh;\n    ///\n    alias core.stdc.complex.catanhl    atanh;\n\n    ///\n    alias core.stdc.math.cosh          cosh;\n    ///\n    alias core.stdc.math.coshf         cosh;\n    ///\n    alias core.stdc.math.coshl         cosh;\n\n    ///\n    alias core.stdc.complex.ccosh      cosh;\n    ///\n    alias core.stdc.complex.ccoshf     cosh;\n    ///\n    alias core.stdc.complex.ccoshl     cosh;\n\n    ///\n    alias core.stdc.math.sinh          sinh;\n    ///\n    alias core.stdc.math.sinhf         sinh;\n    ///\n    alias core.stdc.math.sinhl         sinh;\n\n    ///\n    alias core.stdc.complex.csinh      sinh;\n    ///\n    alias core.stdc.complex.csinhf     sinh;\n    ///\n    alias core.stdc.complex.csinhl     sinh;\n\n    ///\n    alias core.stdc.math.tanh          tanh;\n    ///\n    alias core.stdc.math.tanhf         tanh;\n    ///\n    alias core.stdc.math.tanhl         tanh;\n\n    ///\n    alias core.stdc.complex.ctanh      tanh;\n    ///\n    alias core.stdc.complex.ctanhf     tanh;\n    ///\n    alias core.stdc.complex.ctanhl     tanh;\n\n    ///\n    alias core.stdc.math.exp           exp;\n    ///\n    alias core.stdc.math.expf          exp;\n    ///\n    alias core.stdc.math.expl          exp;\n\n    ///\n    alias core.stdc.complex.cexp       exp;\n    ///\n    alias core.stdc.complex.cexpf      exp;\n    ///\n    alias core.stdc.complex.cexpl      exp;\n\n    ///\n    alias core.stdc.math.exp2          exp2;\n    ///\n    alias core.stdc.math.exp2f         exp2;\n    ///\n    alias core.stdc.math.exp2l         exp2;\n\n    ///\n    alias core.stdc.math.expm1         expm1;\n    ///\n    alias core.stdc.math.expm1f        expm1;\n    ///\n    alias core.stdc.math.expm1l        expm1;\n\n    ///\n    alias core.stdc.math.frexp         frexp;\n    ///\n    alias core.stdc.math.frexpf        frexp;\n    ///\n    alias core.stdc.math.frexpl        frexp;\n\n    ///\n    alias core.stdc.math.ilogb         ilogb;\n    ///\n    alias core.stdc.math.ilogbf        ilogb;\n    ///\n    alias core.stdc.math.ilogbl        ilogb;\n\n    ///\n    alias core.stdc.math.ldexp         ldexp;\n    ///\n    alias core.stdc.math.ldexpf        ldexp;\n    ///\n    alias core.stdc.math.ldexpl        ldexp;\n\n    ///\n    alias core.stdc.math.log           log;\n    ///\n    alias core.stdc.math.logf          log;\n    ///\n    alias core.stdc.math.logl          log;\n\n    ///\n    alias core.stdc.complex.clog       log;\n    ///\n    alias core.stdc.complex.clogf      log;\n    ///\n    alias core.stdc.complex.clogl      log;\n\n    ///\n    alias core.stdc.math.log10         log10;\n    ///\n    alias core.stdc.math.log10f        log10;\n    ///\n    alias core.stdc.math.log10l        log10;\n\n    ///\n    alias core.stdc.math.log1p         log1p;\n    ///\n    alias core.stdc.math.log1pf        log1p;\n    ///\n    alias core.stdc.math.log1pl        log1p;\n\n    ///\n    alias core.stdc.math.log2          log2;\n    ///\n    alias core.stdc.math.log2f         log2;\n    ///\n    alias core.stdc.math.log2l         log2;\n\n    ///\n    alias core.stdc.math.logb          logb;\n    ///\n    alias core.stdc.math.logbf         logb;\n    ///\n    alias core.stdc.math.logbl         logb;\n\n    ///\n    alias core.stdc.math.modf          modf;\n    ///\n    alias core.stdc.math.modff         modf;\n//  alias core.stdc.math.modfl         modf;\n\n    ///\n    alias core.stdc.math.scalbn        scalbn;\n    ///\n    alias core.stdc.math.scalbnf       scalbn;\n    ///\n    alias core.stdc.math.scalbnl       scalbn;\n\n    ///\n    alias core.stdc.math.scalbln       scalbln;\n    ///\n    alias core.stdc.math.scalblnf      scalbln;\n    ///\n    alias core.stdc.math.scalblnl      scalbln;\n\n    ///\n    alias core.stdc.math.cbrt          cbrt;\n    ///\n    alias core.stdc.math.cbrtf         cbrt;\n    ///\n    alias core.stdc.math.cbrtl         cbrt;\n\n    ///\n    alias core.stdc.math.fabs          fabs;\n    ///\n    alias core.stdc.math.fabsf         fabs;\n    ///\n    alias core.stdc.math.fabsl         fabs;\n\n    ///\n    alias core.stdc.complex.cabs       fabs;\n    ///\n    alias core.stdc.complex.cabsf      fabs;\n    ///\n    alias core.stdc.complex.cabsl      fabs;\n\n    ///\n    alias core.stdc.math.hypot         hypot;\n    ///\n    alias core.stdc.math.hypotf        hypot;\n    ///\n    alias core.stdc.math.hypotl        hypot;\n\n    ///\n    alias core.stdc.math.pow           pow;\n    ///\n    alias core.stdc.math.powf          pow;\n    ///\n    alias core.stdc.math.powl          pow;\n\n    ///\n    alias core.stdc.complex.cpow       pow;\n    ///\n    alias core.stdc.complex.cpowf      pow;\n    ///\n    alias core.stdc.complex.cpowl      pow;\n\n    ///\n    alias core.stdc.math.sqrt          sqrt;\n    ///\n    alias core.stdc.math.sqrtf         sqrt;\n    ///\n    alias core.stdc.math.sqrtl         sqrt;\n\n    ///\n    alias core.stdc.complex.csqrt      sqrt;\n    ///\n    alias core.stdc.complex.csqrtf     sqrt;\n    ///\n    alias core.stdc.complex.csqrtl     sqrt;\n\n    ///\n    alias core.stdc.math.erf           erf;\n    ///\n    alias core.stdc.math.erff          erf;\n    ///\n    alias core.stdc.math.erfl          erf;\n\n    ///\n    alias core.stdc.math.erfc          erfc;\n    ///\n    alias core.stdc.math.erfcf         erfc;\n    ///\n    alias core.stdc.math.erfcl         erfc;\n\n    ///\n    alias core.stdc.math.lgamma        lgamma;\n    ///\n    alias core.stdc.math.lgammaf       lgamma;\n    ///\n    alias core.stdc.math.lgammal       lgamma;\n\n    ///\n    alias core.stdc.math.tgamma        tgamma;\n    ///\n    alias core.stdc.math.tgammaf       tgamma;\n    ///\n    alias core.stdc.math.tgammal       tgamma;\n\n    ///\n    alias core.stdc.math.ceil          ceil;\n    ///\n    alias core.stdc.math.ceilf         ceil;\n    ///\n    alias core.stdc.math.ceill         ceil;\n\n    ///\n    alias core.stdc.math.floor         floor;\n    ///\n    alias core.stdc.math.floorf        floor;\n    ///\n    alias core.stdc.math.floorl        floor;\n\n    ///\n    alias core.stdc.math.nearbyint     nearbyint;\n    ///\n    alias core.stdc.math.nearbyintf    nearbyint;\n    ///\n    alias core.stdc.math.nearbyintl    nearbyint;\n\n    ///\n    alias core.stdc.math.rint          rint;\n    ///\n    alias core.stdc.math.rintf         rint;\n    ///\n    alias core.stdc.math.rintl         rint;\n\n    ///\n    alias core.stdc.math.lrint         lrint;\n    ///\n    alias core.stdc.math.lrintf        lrint;\n    ///\n    alias core.stdc.math.lrintl        lrint;\n\n    ///\n    alias core.stdc.math.llrint        llrint;\n    ///\n    alias core.stdc.math.llrintf       llrint;\n    ///\n    alias core.stdc.math.llrintl       llrint;\n\n    ///\n    alias core.stdc.math.round         round;\n    ///\n    alias core.stdc.math.roundf        round;\n    ///\n    alias core.stdc.math.roundl        round;\n\n    ///\n    alias core.stdc.math.lround        lround;\n    ///\n    alias core.stdc.math.lroundf       lround;\n    ///\n    alias core.stdc.math.lroundl       lround;\n\n    ///\n    alias core.stdc.math.llround       llround;\n    ///\n    alias core.stdc.math.llroundf      llround;\n    ///\n    alias core.stdc.math.llroundl      llround;\n\n    ///\n    alias core.stdc.math.trunc         trunc;\n    ///\n    alias core.stdc.math.truncf        trunc;\n    ///\n    alias core.stdc.math.truncl        trunc;\n\n    ///\n    alias core.stdc.math.fmod          fmod;\n    ///\n    alias core.stdc.math.fmodf         fmod;\n    ///\n    alias core.stdc.math.fmodl         fmod;\n\n    ///\n    alias core.stdc.math.remainder     remainder;\n    ///\n    alias core.stdc.math.remainderf    remainder;\n    ///\n    alias core.stdc.math.remainderl    remainder;\n\n    ///\n    alias core.stdc.math.remquo        remquo;\n    ///\n    alias core.stdc.math.remquof       remquo;\n    ///\n    alias core.stdc.math.remquol       remquo;\n\n    ///\n    alias core.stdc.math.copysign      copysign;\n    ///\n    alias core.stdc.math.copysignf     copysign;\n    ///\n    alias core.stdc.math.copysignl     copysign;\n\n//  alias core.stdc.math.nan           nan;\n//  alias core.stdc.math.nanf          nan;\n//  alias core.stdc.math.nanl          nan;\n\n    ///\n    alias core.stdc.math.nextafter     nextafter;\n    ///\n    alias core.stdc.math.nextafterf    nextafter;\n    ///\n    alias core.stdc.math.nextafterl    nextafter;\n\n    ///\n    alias core.stdc.math.nexttoward    nexttoward;\n    ///\n    alias core.stdc.math.nexttowardf   nexttoward;\n    ///\n    alias core.stdc.math.nexttowardl   nexttoward;\n\n    ///\n    alias core.stdc.math.fdim          fdim;\n    ///\n    alias core.stdc.math.fdimf         fdim;\n    ///\n    alias core.stdc.math.fdiml         fdim;\n\n    ///\n    alias core.stdc.math.fmax          fmax;\n    ///\n    alias core.stdc.math.fmaxf         fmax;\n    ///\n    alias core.stdc.math.fmaxl         fmax;\n\n    ///\n    alias core.stdc.math.fmin          fmin;\n    ///\n    alias core.stdc.math.fmin          fmin;\n    ///\n    alias core.stdc.math.fminl         fmin;\n\n    ///\n    alias core.stdc.math.fma           fma;\n    ///\n    alias core.stdc.math.fmaf          fma;\n    ///\n    alias core.stdc.math.fmal          fma;\n\n    ///\n    alias core.stdc.complex.carg       carg;\n    ///\n    alias core.stdc.complex.cargf      carg;\n    ///\n    alias core.stdc.complex.cargl      carg;\n\n    ///\n    alias core.stdc.complex.cimag      cimag;\n    ///\n    alias core.stdc.complex.cimagf     cimag;\n    ///\n    alias core.stdc.complex.cimagl     cimag;\n\n    ///\n    alias core.stdc.complex.conj       conj;\n    ///\n    alias core.stdc.complex.conjf      conj;\n    ///\n    alias core.stdc.complex.conjl      conj;\n\n    ///\n    alias core.stdc.complex.cproj      cproj;\n    ///\n    alias core.stdc.complex.cprojf     cproj;\n    ///\n    alias core.stdc.complex.cprojl     cproj;\n\n//  alias core.stdc.complex.creal      creal;\n//  alias core.stdc.complex.crealf     creal;\n//  alias core.stdc.complex.creall     creal;\n}\nversion (NetBSD)\n{\n    ///\n    alias core.stdc.math.acos          acos;\n    ///\n    alias core.stdc.math.acosf         acos;\n    ///\n    alias core.stdc.math.acosl         acos;\n\n    ///\n    alias core.stdc.complex.cacos      acos;\n    ///\n    alias core.stdc.complex.cacosf     acos;\n    ///\n    alias core.stdc.complex.cacosl     acos;\n\n    ///\n    alias core.stdc.math.asin          asin;\n    ///\n    alias core.stdc.math.asinf         asin;\n    ///\n    alias core.stdc.math.asinl         asin;\n\n    ///\n    alias core.stdc.complex.casin      asin;\n    ///\n    alias core.stdc.complex.casinf     asin;\n    ///\n    alias core.stdc.complex.casinl     asin;\n\n    ///\n    alias core.stdc.math.atan          atan;\n    ///\n    alias core.stdc.math.atanf         atan;\n    ///\n    alias core.stdc.math.atanl         atan;\n\n    ///\n    alias core.stdc.complex.catan      atan;\n    ///\n    alias core.stdc.complex.catanf     atan;\n    ///\n    alias core.stdc.complex.catanl     atan;\n\n    ///\n    alias core.stdc.math.atan2         atan2;\n    ///\n    alias core.stdc.math.atan2f        atan2;\n    ///\n    alias core.stdc.math.atan2l        atan2;\n\n    ///\n    alias core.stdc.math.cos           cos;\n    ///\n    alias core.stdc.math.cosf          cos;\n    ///\n    alias core.stdc.math.cosl          cos;\n\n    ///\n    alias core.stdc.complex.ccos       cos;\n    ///\n    alias core.stdc.complex.ccosf      cos;\n    ///\n    alias core.stdc.complex.ccosl      cos;\n\n    ///\n    alias core.stdc.math.sin           sin;\n    ///\n    alias core.stdc.math.sinf          sin;\n    ///\n    alias core.stdc.math.sinl          sin;\n\n    ///\n    alias core.stdc.complex.csin       csin;\n    ///\n    alias core.stdc.complex.csinf      csin;\n    ///\n    alias core.stdc.complex.csinl      csin;\n\n    ///\n    alias core.stdc.math.tan           tan;\n    ///\n    alias core.stdc.math.tanf          tan;\n    ///\n    alias core.stdc.math.tanl          tan;\n\n    ///\n    alias core.stdc.complex.ctan       tan;\n    ///\n    alias core.stdc.complex.ctanf      tan;\n    ///\n    alias core.stdc.complex.ctanl      tan;\n\n    ///\n    alias core.stdc.math.acosh         acosh;\n    ///\n    alias core.stdc.math.acoshf        acosh;\n    ///\n    alias core.stdc.math.acoshl        acosh;\n\n    ///\n    alias core.stdc.complex.cacosh     acosh;\n    ///\n    alias core.stdc.complex.cacoshf    acosh;\n    ///\n    alias core.stdc.complex.cacoshl    acosh;\n\n    ///\n    alias core.stdc.math.asinh         asinh;\n    ///\n    alias core.stdc.math.asinhf        asinh;\n    ///\n    alias core.stdc.math.asinhl        asinh;\n\n    ///\n    alias core.stdc.complex.casinh     asinh;\n    ///\n    alias core.stdc.complex.casinhf    asinh;\n    ///\n    alias core.stdc.complex.casinhl    asinh;\n\n    ///\n    alias core.stdc.math.atanh         atanh;\n    ///\n    alias core.stdc.math.atanhf        atanh;\n    ///\n    alias core.stdc.math.atanhl        atanh;\n\n    ///\n    alias core.stdc.complex.catanh     atanh;\n    ///\n    alias core.stdc.complex.catanhf    atanh;\n    ///\n    alias core.stdc.complex.catanhl    atanh;\n\n    ///\n    alias core.stdc.math.cosh          cosh;\n    ///\n    alias core.stdc.math.coshf         cosh;\n    ///\n    alias core.stdc.math.coshl         cosh;\n\n    ///\n    alias core.stdc.complex.ccosh      cosh;\n    ///\n    alias core.stdc.complex.ccoshf     cosh;\n    ///\n    alias core.stdc.complex.ccoshl     cosh;\n\n    ///\n    alias core.stdc.math.sinh          sinh;\n    ///\n    alias core.stdc.math.sinhf         sinh;\n    ///\n    alias core.stdc.math.sinhl         sinh;\n\n    ///\n    alias core.stdc.complex.csinh      sinh;\n    ///\n    alias core.stdc.complex.csinhf     sinh;\n    ///\n    alias core.stdc.complex.csinhl     sinh;\n\n    ///\n    alias core.stdc.math.tanh          tanh;\n    ///\n    alias core.stdc.math.tanhf         tanh;\n    ///\n    alias core.stdc.math.tanhl         tanh;\n\n    ///\n    alias core.stdc.complex.ctanh      tanh;\n    ///\n    alias core.stdc.complex.ctanhf     tanh;\n    ///\n    alias core.stdc.complex.ctanhl     tanh;\n\n    ///\n    alias core.stdc.math.exp           exp;\n    ///\n    alias core.stdc.math.expf          exp;\n    ///\n    alias core.stdc.math.expl          exp;\n\n    ///\n    alias core.stdc.complex.cexp       exp;\n    ///\n    alias core.stdc.complex.cexpf      exp;\n    ///\n    alias core.stdc.complex.cexpl      exp;\n\n    ///\n    alias core.stdc.math.exp2          exp2;\n    ///\n    alias core.stdc.math.exp2f         exp2;\n    ///\n    alias core.stdc.math.exp2l         exp2;\n\n    ///\n    alias core.stdc.math.expm1         expm1;\n    ///\n    alias core.stdc.math.expm1f        expm1;\n    ///\n    alias core.stdc.math.expm1l        expm1;\n\n    ///\n    alias core.stdc.math.frexp         frexp;\n    ///\n    alias core.stdc.math.frexpf        frexp;\n    ///\n    alias core.stdc.math.frexpl        frexp;\n\n    ///\n    alias core.stdc.math.ilogb         ilogb;\n    ///\n    alias core.stdc.math.ilogbf        ilogb;\n    ///\n    alias core.stdc.math.ilogbl        ilogb;\n\n    ///\n    alias core.stdc.math.ldexp         ldexp;\n    ///\n    alias core.stdc.math.ldexpf        ldexp;\n    ///\n    alias core.stdc.math.ldexpl        ldexp;\n\n    ///\n    alias core.stdc.math.log           log;\n    ///\n    alias core.stdc.math.logf          log;\n    ///\n    alias core.stdc.math.logl          log;\n\n    ///\n    alias core.stdc.complex.clog       log;\n    ///\n    alias core.stdc.complex.clogf      log;\n    ///\n    alias core.stdc.complex.clogl      log;\n\n    ///\n    alias core.stdc.math.log10         log10;\n    ///\n    alias core.stdc.math.log10f        log10;\n    ///\n    alias core.stdc.math.log10l        log10;\n\n    ///\n    alias core.stdc.math.log1p         log1p;\n    ///\n    alias core.stdc.math.log1pf        log1p;\n    ///\n    alias core.stdc.math.log1pl        log1p;\n\n    ///\n    alias core.stdc.math.log2          log2;\n    ///\n    alias core.stdc.math.log2f         log2;\n    ///\n    alias core.stdc.math.log2l         log2;\n\n    ///\n    alias core.stdc.math.logb          logb;\n    ///\n    alias core.stdc.math.logbf         logb;\n    ///\n    alias core.stdc.math.logbl         logb;\n\n    ///\n    alias core.stdc.math.modf          modf;\n    ///\n    alias core.stdc.math.modff         modf;\n//  alias core.stdc.math.modfl         modf;\n\n    ///\n    alias core.stdc.math.scalbn        scalbn;\n    ///\n    alias core.stdc.math.scalbnf       scalbn;\n    ///\n    alias core.stdc.math.scalbnl       scalbn;\n\n    ///\n    alias core.stdc.math.scalbln       scalbln;\n    ///\n    alias core.stdc.math.scalblnf      scalbln;\n    ///\n    alias core.stdc.math.scalblnl      scalbln;\n\n    ///\n    alias core.stdc.math.cbrt          cbrt;\n    ///\n    alias core.stdc.math.cbrtf         cbrt;\n    ///\n    alias core.stdc.math.cbrtl         cbrt;\n\n    ///\n    alias core.stdc.math.fabs          fabs;\n    ///\n    alias core.stdc.math.fabsf         fabs;\n    ///\n    alias core.stdc.math.fabsl         fabs;\n\n    ///\n    alias core.stdc.complex.cabs       fabs;\n    ///\n    alias core.stdc.complex.cabsf      fabs;\n    ///\n    alias core.stdc.complex.cabsl      fabs;\n\n    ///\n    alias core.stdc.math.hypot         hypot;\n    ///\n    alias core.stdc.math.hypotf        hypot;\n    ///\n    alias core.stdc.math.hypotl        hypot;\n\n    ///\n    alias core.stdc.math.pow           pow;\n    ///\n    alias core.stdc.math.powf          pow;\n    ///\n    alias core.stdc.math.powl          pow;\n\n    ///\n    alias core.stdc.complex.cpow       pow;\n    ///\n    alias core.stdc.complex.cpowf      pow;\n    ///\n    alias core.stdc.complex.cpowl      pow;\n\n    ///\n    alias core.stdc.math.sqrt          sqrt;\n    ///\n    alias core.stdc.math.sqrtf         sqrt;\n    ///\n    alias core.stdc.math.sqrtl         sqrt;\n\n    ///\n    alias core.stdc.complex.csqrt      sqrt;\n    ///\n    alias core.stdc.complex.csqrtf     sqrt;\n    ///\n    alias core.stdc.complex.csqrtl     sqrt;\n\n    ///\n    alias core.stdc.math.erf           erf;\n    ///\n    alias core.stdc.math.erff          erf;\n    ///\n    alias core.stdc.math.erfl          erf;\n\n    ///\n    alias core.stdc.math.erfc          erfc;\n    ///\n    alias core.stdc.math.erfcf         erfc;\n    ///\n    alias core.stdc.math.erfcl         erfc;\n\n    ///\n    alias core.stdc.math.lgamma        lgamma;\n    ///\n    alias core.stdc.math.lgammaf       lgamma;\n    ///\n    alias core.stdc.math.lgammal       lgamma;\n\n    ///\n    alias core.stdc.math.tgamma        tgamma;\n    ///\n    alias core.stdc.math.tgammaf       tgamma;\n    ///\n    alias core.stdc.math.tgammal       tgamma;\n\n    ///\n    alias core.stdc.math.ceil          ceil;\n    ///\n    alias core.stdc.math.ceilf         ceil;\n    ///\n    alias core.stdc.math.ceill         ceil;\n\n    ///\n    alias core.stdc.math.floor         floor;\n    ///\n    alias core.stdc.math.floorf        floor;\n    ///\n    alias core.stdc.math.floorl        floor;\n\n    ///\n    alias core.stdc.math.nearbyint     nearbyint;\n    ///\n    alias core.stdc.math.nearbyintf    nearbyint;\n    ///\n    alias core.stdc.math.nearbyintl    nearbyint;\n\n    ///\n    alias core.stdc.math.rint          rint;\n    ///\n    alias core.stdc.math.rintf         rint;\n    ///\n    alias core.stdc.math.rintl         rint;\n\n    ///\n    alias core.stdc.math.lrint         lrint;\n    ///\n    alias core.stdc.math.lrintf        lrint;\n    ///\n    alias core.stdc.math.lrintl        lrint;\n\n    ///\n    alias core.stdc.math.llrint        llrint;\n    ///\n    alias core.stdc.math.llrintf       llrint;\n    ///\n    alias core.stdc.math.llrintl       llrint;\n\n    ///\n    alias core.stdc.math.round         round;\n    ///\n    alias core.stdc.math.roundf        round;\n    ///\n    alias core.stdc.math.roundl        round;\n\n    ///\n    alias core.stdc.math.lround        lround;\n    ///\n    alias core.stdc.math.lroundf       lround;\n    ///\n    alias core.stdc.math.lroundl       lround;\n\n    ///\n    alias core.stdc.math.llround       llroundl;\n    ///\n    alias core.stdc.math.llroundf      llroundl;\n    ///\n    alias core.stdc.math.llroundl      llroundl;\n\n    ///\n    alias core.stdc.math.trunc         trunc;\n    ///\n    alias core.stdc.math.truncf        trunc;\n    ///\n    alias core.stdc.math.truncl        trunc;\n\n    ///\n    alias core.stdc.math.fmod          fmod;\n    ///\n    alias core.stdc.math.fmodf         fmod;\n    ///\n    alias core.stdc.math.fmodl         fmod;\n\n    ///\n    alias core.stdc.math.remainder     remainder;\n    ///\n    alias core.stdc.math.remainderf    remainder;\n    ///\n    alias core.stdc.math.remainderl    remainder;\n\n    ///\n    alias core.stdc.math.remquo        remquo;\n    ///\n    alias core.stdc.math.remquof       remquo;\n    ///\n    alias core.stdc.math.remquol       remquo;\n\n    ///\n    alias core.stdc.math.copysign      copysign;\n    ///\n    alias core.stdc.math.copysignf     copysign;\n    ///\n    alias core.stdc.math.copysignl     copysign;\n\n//  alias core.stdc.math.nan           nan;\n//  alias core.stdc.math.nanf          nan;\n//  alias core.stdc.math.nanl          nan;\n\n    ///\n    alias core.stdc.math.nextafter     nextafter;\n    ///\n    alias core.stdc.math.nextafterf    nextafter;\n    ///\n    alias core.stdc.math.nextafterl    nextafter;\n\n    ///\n    alias core.stdc.math.nexttoward    nexttoward;\n    ///\n    alias core.stdc.math.nexttowardf   nexttoward;\n    ///\n    alias core.stdc.math.nexttowardl   nexttoward;\n\n    ///\n    alias core.stdc.math.fdim          fdim;\n    ///\n    alias core.stdc.math.fdimf         fdim;\n    ///\n    alias core.stdc.math.fdiml         fdim;\n\n    ///\n    alias core.stdc.math.fmax          fmax;\n    ///\n    alias core.stdc.math.fmaxf         fmax;\n    ///\n    alias core.stdc.math.fmaxl         fmax;\n\n    ///\n    alias core.stdc.math.fmin          fmin;\n    ///\n    alias core.stdc.math.fmin          fmin;\n    ///\n    alias core.stdc.math.fminl         fmin;\n\n    ///\n    alias core.stdc.math.fma           fma;\n    ///\n    alias core.stdc.math.fmaf          fma;\n    ///\n    alias core.stdc.math.fmal          fma;\n\n    ///\n    alias core.stdc.complex.carg       carg;\n    ///\n    alias core.stdc.complex.cargf      carg;\n    ///\n    alias core.stdc.complex.cargl      carg;\n\n    ///\n    alias core.stdc.complex.cimag      cimag;\n    ///\n    alias core.stdc.complex.cimagf     cimag;\n    ///\n    alias core.stdc.complex.cimagl     cimag;\n\n    ///\n    alias core.stdc.complex.conj       conj;\n    ///\n    alias core.stdc.complex.conjf      conj;\n    ///\n    alias core.stdc.complex.conjl      conj;\n\n    ///\n    alias core.stdc.complex.cproj      cproj;\n    ///\n    alias core.stdc.complex.cprojf     cproj;\n    ///\n    alias core.stdc.complex.cprojl     cproj;\n\n//  alias core.stdc.complex.creal      creal;\n//  alias core.stdc.complex.crealf     creal;\n//  alias core.stdc.complex.creall     creal;\n}\nelse version (OpenBSD)\n{\n    ///\n    alias core.stdc.math.acos          acos;\n    ///\n    alias core.stdc.math.acosf         acos;\n    ///\n    alias core.stdc.math.acosl         acos;\n\n    ///\n    alias core.stdc.complex.cacos      acos;\n    ///\n    alias core.stdc.complex.cacosf     acos;\n    ///\n    alias core.stdc.complex.cacosl     acos;\n\n    ///\n    alias core.stdc.math.asin          asin;\n    ///\n    alias core.stdc.math.asinf         asin;\n    ///\n    alias core.stdc.math.asinl         asin;\n\n    ///\n    alias core.stdc.complex.casin      asin;\n    ///\n    alias core.stdc.complex.casinf     asin;\n    ///\n    alias core.stdc.complex.casinl     asin;\n\n    ///\n    alias core.stdc.math.atan          atan;\n    ///\n    alias core.stdc.math.atanf         atan;\n    ///\n    alias core.stdc.math.atanl         atan;\n\n    ///\n    alias core.stdc.complex.catan      atan;\n    ///\n    alias core.stdc.complex.catanf     atan;\n    ///\n    alias core.stdc.complex.catanl     atan;\n\n    ///\n    alias core.stdc.math.atan2         atan2;\n    ///\n    alias core.stdc.math.atan2f        atan2;\n    ///\n    alias core.stdc.math.atan2l        atan2;\n\n    ///\n    alias core.stdc.math.cos           cos;\n    ///\n    alias core.stdc.math.cosf          cos;\n    ///\n    alias core.stdc.math.cosl          cos;\n\n    ///\n    alias core.stdc.complex.ccos       cos;\n    ///\n    alias core.stdc.complex.ccosf      cos;\n    ///\n    alias core.stdc.complex.ccosl      cos;\n\n    ///\n    alias core.stdc.math.sin           sin;\n    ///\n    alias core.stdc.math.sinf          sin;\n    ///\n    alias core.stdc.math.sinl          sin;\n\n    ///\n    alias core.stdc.complex.csin       csin;\n    ///\n    alias core.stdc.complex.csinf      csin;\n    ///\n    alias core.stdc.complex.csinl      csin;\n\n    ///\n    alias core.stdc.math.tan           tan;\n    ///\n    alias core.stdc.math.tanf          tan;\n    ///\n    alias core.stdc.math.tanl          tan;\n\n    ///\n    alias core.stdc.complex.ctan       tan;\n    ///\n    alias core.stdc.complex.ctanf      tan;\n    ///\n    alias core.stdc.complex.ctanl      tan;\n\n    ///\n    alias core.stdc.math.acosh         acosh;\n    ///\n    alias core.stdc.math.acoshf        acosh;\n    ///\n    alias core.stdc.math.acoshl        acosh;\n\n    ///\n    alias core.stdc.complex.cacosh     acosh;\n    ///\n    alias core.stdc.complex.cacoshf    acosh;\n    ///\n    alias core.stdc.complex.cacoshl    acosh;\n\n    ///\n    alias core.stdc.math.asinh         asinh;\n    ///\n    alias core.stdc.math.asinhf        asinh;\n    ///\n    alias core.stdc.math.asinhl        asinh;\n\n    ///\n    alias core.stdc.complex.casinh     asinh;\n    ///\n    alias core.stdc.complex.casinhf    asinh;\n    ///\n    alias core.stdc.complex.casinhl    asinh;\n\n    ///\n    alias core.stdc.math.atanh         atanh;\n    ///\n    alias core.stdc.math.atanhf        atanh;\n    ///\n    alias core.stdc.math.atanhl        atanh;\n\n    ///\n    alias core.stdc.complex.catanh     atanh;\n    ///\n    alias core.stdc.complex.catanhf    atanh;\n    ///\n    alias core.stdc.complex.catanhl    atanh;\n\n    ///\n    alias core.stdc.math.cosh          cosh;\n    ///\n    alias core.stdc.math.coshf         cosh;\n    ///\n    alias core.stdc.math.coshl         cosh;\n\n    ///\n    alias core.stdc.complex.ccosh      cosh;\n    ///\n    alias core.stdc.complex.ccoshf     cosh;\n    ///\n    alias core.stdc.complex.ccoshl     cosh;\n\n    ///\n    alias core.stdc.math.sinh          sinh;\n    ///\n    alias core.stdc.math.sinhf         sinh;\n    ///\n    alias core.stdc.math.sinhl         sinh;\n\n    ///\n    alias core.stdc.complex.csinh      sinh;\n    ///\n    alias core.stdc.complex.csinhf     sinh;\n    ///\n    alias core.stdc.complex.csinhl     sinh;\n\n    ///\n    alias core.stdc.math.tanh          tanh;\n    ///\n    alias core.stdc.math.tanhf         tanh;\n    ///\n    alias core.stdc.math.tanhl         tanh;\n\n    ///\n    alias core.stdc.complex.ctanh      tanh;\n    ///\n    alias core.stdc.complex.ctanhf     tanh;\n    ///\n    alias core.stdc.complex.ctanhl     tanh;\n\n    ///\n    alias core.stdc.math.exp           exp;\n    ///\n    alias core.stdc.math.expf          exp;\n    ///\n    alias core.stdc.math.expl          exp;\n\n    ///\n    alias core.stdc.complex.cexp       exp;\n    ///\n    alias core.stdc.complex.cexpf      exp;\n    ///\n    alias core.stdc.complex.cexpl      exp;\n\n    ///\n    alias core.stdc.math.exp2          exp2;\n    ///\n    alias core.stdc.math.exp2f         exp2;\n    ///\n    alias core.stdc.math.exp2l         exp2;\n\n    ///\n    alias core.stdc.math.expm1         expm1;\n    ///\n    alias core.stdc.math.expm1f        expm1;\n    ///\n    alias core.stdc.math.expm1l        expm1;\n\n    ///\n    alias core.stdc.math.frexp         frexp;\n    ///\n    alias core.stdc.math.frexpf        frexp;\n    ///\n    alias core.stdc.math.frexpl        frexp;\n\n    ///\n    alias core.stdc.math.ilogb         ilogb;\n    ///\n    alias core.stdc.math.ilogbf        ilogb;\n    ///\n    alias core.stdc.math.ilogbl        ilogb;\n\n    ///\n    alias core.stdc.math.ldexp         ldexp;\n    ///\n    alias core.stdc.math.ldexpf        ldexp;\n    ///\n    alias core.stdc.math.ldexpl        ldexp;\n\n    ///\n    alias core.stdc.math.log           log;\n    ///\n    alias core.stdc.math.logf          log;\n    ///\n    alias core.stdc.math.logl          log;\n\n    ///\n    alias core.stdc.complex.clog       log;\n    ///\n    alias core.stdc.complex.clogf      log;\n    ///\n    alias core.stdc.complex.clogl      log;\n\n    ///\n    alias core.stdc.math.log10         log10;\n    ///\n    alias core.stdc.math.log10f        log10;\n    ///\n    alias core.stdc.math.log10l        log10;\n\n    ///\n    alias core.stdc.math.log1p         log1p;\n    ///\n    alias core.stdc.math.log1pf        log1p;\n    ///\n    alias core.stdc.math.log1pl        log1p;\n\n    ///\n    alias core.stdc.math.log2          log2;\n    ///\n    alias core.stdc.math.log2f         log2;\n    ///\n    alias core.stdc.math.log2l         log2;\n\n    ///\n    alias core.stdc.math.logb          logb;\n    ///\n    alias core.stdc.math.logbf         logb;\n    ///\n    alias core.stdc.math.logbl         logb;\n\n    ///\n    alias core.stdc.math.fmod          fmod;\n    ///\n    alias core.stdc.math.fmodf         fmod;\n    ///\n    alias core.stdc.math.fmodl         fmod;\n\n    ///\n    alias core.stdc.math.scalbn        scalbn;\n    ///\n    alias core.stdc.math.scalbnf       scalbn;\n    ///\n    alias core.stdc.math.scalbnl       scalbn;\n\n    ///\n    alias core.stdc.math.scalbln       scalbln;\n    ///\n    alias core.stdc.math.scalblnf      scalbln;\n    ///\n    alias core.stdc.math.scalblnl      scalbln;\n\n    ///\n    alias core.stdc.math.cbrt          cbrt;\n    ///\n    alias core.stdc.math.cbrtf         cbrt;\n    ///\n    alias core.stdc.math.cbrtl         cbrt;\n\n    ///\n    alias core.stdc.math.fabs          fabs;\n    ///\n    alias core.stdc.math.fabsf         fabs;\n    ///\n    alias core.stdc.math.fabsl         fabs;\n\n    ///\n    alias core.stdc.complex.cabs       fabs;\n    ///\n    alias core.stdc.complex.cabsf      fabs;\n    ///\n    alias core.stdc.complex.cabsl      fabs;\n\n    ///\n    alias core.stdc.math.hypot         hypot;\n    ///\n    alias core.stdc.math.hypotf        hypot;\n    ///\n    alias core.stdc.math.hypotl        hypot;\n\n    ///\n    alias core.stdc.math.pow           pow;\n    ///\n    alias core.stdc.math.powf          pow;\n    ///\n    alias core.stdc.math.powl          pow;\n\n    ///\n    alias core.stdc.complex.cpow       pow;\n    ///\n    alias core.stdc.complex.cpowf      pow;\n    ///\n    alias core.stdc.complex.cpowl      pow;\n\n    ///\n    alias core.stdc.math.sqrt          sqrt;\n    ///\n    alias core.stdc.math.sqrtf         sqrt;\n    ///\n    alias core.stdc.math.sqrtl         sqrt;\n\n    ///\n    alias core.stdc.complex.csqrt      sqrt;\n    ///\n    alias core.stdc.complex.csqrtf     sqrt;\n    ///\n    alias core.stdc.complex.csqrtl     sqrt;\n\n    ///\n    alias core.stdc.math.erf           erf;\n    ///\n    alias core.stdc.math.erff          erf;\n    ///\n    alias core.stdc.math.erfl          erf;\n\n    ///\n    alias core.stdc.math.erfc          erfc;\n    ///\n    alias core.stdc.math.erfcf         erfc;\n    ///\n    alias core.stdc.math.erfcl         erfc;\n\n    ///\n    alias core.stdc.math.lgamma        lgamma;\n    ///\n    alias core.stdc.math.lgammaf       lgamma;\n    ///\n    alias core.stdc.math.lgammal       lgamma;\n\n    ///\n    alias core.stdc.math.tgamma        tgamma;\n    ///\n    alias core.stdc.math.tgammaf       tgamma;\n    ///\n    alias core.stdc.math.tgammal       tgamma;\n\n    ///\n    alias core.stdc.math.ceil          ceil;\n    ///\n    alias core.stdc.math.ceilf         ceil;\n    ///\n    alias core.stdc.math.ceill         ceil;\n\n    ///\n    alias core.stdc.math.floor         floor;\n    ///\n    alias core.stdc.math.floorf        floor;\n    ///\n    alias core.stdc.math.floorl        floor;\n\n    ///\n    alias core.stdc.math.nearbyint     nearbyint;\n    ///\n    alias core.stdc.math.nearbyintf    nearbyint;\n    ///\n    alias core.stdc.math.nearbyintl    nearbyint;\n\n    ///\n    alias core.stdc.math.rint          rint;\n    ///\n    alias core.stdc.math.rintf         rint;\n    ///\n    alias core.stdc.math.rintl         rint;\n\n    ///\n    alias core.stdc.math.lrint         lrint;\n    ///\n    alias core.stdc.math.lrintf        lrint;\n    ///\n    alias core.stdc.math.lrintl        lrint;\n\n    ///\n    alias core.stdc.math.llrint        llrint;\n    ///\n    alias core.stdc.math.llrintf       llrint;\n    ///\n    alias core.stdc.math.llrintl       llrint;\n\n    ///\n    alias core.stdc.math.round         round;\n    ///\n    alias core.stdc.math.roundf        round;\n    ///\n    alias core.stdc.math.roundl        round;\n\n    ///\n    alias core.stdc.math.lround        lround;\n    ///\n    alias core.stdc.math.lroundf       lround;\n    ///\n    alias core.stdc.math.lroundl       lround;\n\n    ///\n    alias core.stdc.math.llround       llround;\n    ///\n    alias core.stdc.math.llroundf      llround;\n    ///\n    alias core.stdc.math.llroundl      llround;\n\n    ///\n    alias core.stdc.math.trunc         trunc;\n    ///\n    alias core.stdc.math.truncf        trunc;\n    ///\n    alias core.stdc.math.truncl        trunc;\n\n    ///\n    alias core.stdc.math.remainder     remainder;\n    ///\n    alias core.stdc.math.remainderf    remainder;\n    ///\n    alias core.stdc.math.remainderl    remainder;\n\n    ///\n    alias core.stdc.math.remquo        remquo;\n    ///\n    alias core.stdc.math.remquof       remquo;\n    ///\n    alias core.stdc.math.remquol       remquo;\n\n    ///\n    alias core.stdc.math.copysign      copysign;\n    ///\n    alias core.stdc.math.copysignf     copysign;\n    ///\n    alias core.stdc.math.copysignl     copysign;\n\n    ///\n    alias core.stdc.math.nextafter     nextafter;\n    ///\n    alias core.stdc.math.nextafterf    nextafter;\n    ///\n    alias core.stdc.math.nextafterl    nextafter;\n\n    ///\n    alias core.stdc.math.nexttoward    nexttoward;\n    ///\n    alias core.stdc.math.nexttowardf   nexttoward;\n    ///\n    alias core.stdc.math.nexttowardl   nexttoward;\n\n    ///\n    alias core.stdc.math.fdim          fdim;\n    ///\n    alias core.stdc.math.fdimf         fdim;\n    ///\n    alias core.stdc.math.fdiml         fdim;\n\n    ///\n    alias core.stdc.math.fmax          fmax;\n    ///\n    alias core.stdc.math.fmaxf         fmax;\n    ///\n    alias core.stdc.math.fmaxl         fmax;\n\n    ///\n    alias core.stdc.math.fmin          fmin;\n    ///\n    alias core.stdc.math.fmin          fmin;\n    ///\n    alias core.stdc.math.fminl         fmin;\n\n    ///\n    alias core.stdc.math.fma           fma;\n    ///\n    alias core.stdc.math.fmaf          fma;\n    ///\n    alias core.stdc.math.fmal          fma;\n\n    ///\n    alias core.stdc.complex.carg       carg;\n    ///\n    alias core.stdc.complex.cargf      carg;\n    ///\n    alias core.stdc.complex.cargl      carg;\n\n    ///\n    alias core.stdc.complex.cimag      cimag;\n    ///\n    alias core.stdc.complex.cimagf     cimag;\n    ///\n    alias core.stdc.complex.cimagl     cimag;\n\n    ///\n    alias core.stdc.complex.conj       conj;\n    ///\n    alias core.stdc.complex.conjf      conj;\n    ///\n    alias core.stdc.complex.conjl      conj;\n\n    ///\n    alias core.stdc.complex.cproj      cproj;\n    ///\n    alias core.stdc.complex.cprojf     cproj;\n    ///\n    alias core.stdc.complex.cprojl     cproj;\n\n//  alias core.stdc.complex.creal      creal;\n//  alias core.stdc.complex.crealf     creal;\n//  alias core.stdc.complex.creall     creal;\n}\nelse\n{\n    ///\n    alias core.stdc.math.acos          acos;\n    ///\n    alias core.stdc.math.acosf         acos;\n    ///\n    alias core.stdc.math.acosl         acos;\n\n    ///\n    alias core.stdc.complex.cacos      acos;\n    ///\n    alias core.stdc.complex.cacosf     acos;\n    ///\n    alias core.stdc.complex.cacosl     acos;\n\n    ///\n    alias core.stdc.math.asin          asin;\n    ///\n    alias core.stdc.math.asinf         asin;\n    ///\n    alias core.stdc.math.asinl         asin;\n\n    ///\n    alias core.stdc.complex.casin      asin;\n    ///\n    alias core.stdc.complex.casinf     asin;\n    ///\n    alias core.stdc.complex.casinl     asin;\n\n    ///\n    alias core.stdc.math.atan          atan;\n    ///\n    alias core.stdc.math.atanf         atan;\n    ///\n    alias core.stdc.math.atanl         atan;\n\n    ///\n    alias core.stdc.complex.catan      atan;\n    ///\n    alias core.stdc.complex.catanf     atan;\n    ///\n    alias core.stdc.complex.catanl     atan;\n\n    ///\n    alias core.stdc.math.atan2         atan2;\n    ///\n    alias core.stdc.math.atan2f        atan2;\n    ///\n    alias core.stdc.math.atan2l        atan2;\n\n    ///\n    alias core.stdc.math.cos           cos;\n    ///\n    alias core.stdc.math.cosf          cos;\n    ///\n    alias core.stdc.math.cosl          cos;\n\n    ///\n    alias core.stdc.complex.ccos       cos;\n    ///\n    alias core.stdc.complex.ccosf      cos;\n    ///\n    alias core.stdc.complex.ccosl      cos;\n\n    ///\n    alias core.stdc.math.sin           sin;\n    ///\n    alias core.stdc.math.sinf          sin;\n    ///\n    alias core.stdc.math.sinl          sin;\n\n    ///\n    alias core.stdc.complex.csin       csin;\n    ///\n    alias core.stdc.complex.csinf      csin;\n    ///\n    alias core.stdc.complex.csinl      csin;\n\n    ///\n    alias core.stdc.math.tan           tan;\n    ///\n    alias core.stdc.math.tanf          tan;\n    ///\n    alias core.stdc.math.tanl          tan;\n\n    ///\n    alias core.stdc.complex.ctan       tan;\n    ///\n    alias core.stdc.complex.ctanf      tan;\n    ///\n    alias core.stdc.complex.ctanl      tan;\n\n    ///\n    alias core.stdc.math.acosh         acosh;\n    ///\n    alias core.stdc.math.acoshf        acosh;\n    ///\n    alias core.stdc.math.acoshl        acosh;\n\n    ///\n    alias core.stdc.complex.cacosh     acosh;\n    ///\n    alias core.stdc.complex.cacoshf    acosh;\n    ///\n    alias core.stdc.complex.cacoshl    acosh;\n\n    ///\n    alias core.stdc.math.asinh         asinh;\n    ///\n    alias core.stdc.math.asinhf        asinh;\n    ///\n    alias core.stdc.math.asinhl        asinh;\n\n    ///\n    alias core.stdc.complex.casinh     asinh;\n    ///\n    alias core.stdc.complex.casinhf    asinh;\n    ///\n    alias core.stdc.complex.casinhl    asinh;\n\n    ///\n    alias core.stdc.math.atanh         atanh;\n    ///\n    alias core.stdc.math.atanhf        atanh;\n    ///\n    alias core.stdc.math.atanhl        atanh;\n\n    ///\n    alias core.stdc.complex.catanh     atanh;\n    ///\n    alias core.stdc.complex.catanhf    atanh;\n    ///\n    alias core.stdc.complex.catanhl    atanh;\n\n    ///\n    alias core.stdc.math.cosh          cosh;\n    ///\n    alias core.stdc.math.coshf         cosh;\n    ///\n    alias core.stdc.math.coshl         cosh;\n\n    ///\n    alias core.stdc.complex.ccosh      cosh;\n    ///\n    alias core.stdc.complex.ccoshf     cosh;\n    ///\n    alias core.stdc.complex.ccoshl     cosh;\n\n    ///\n    alias core.stdc.math.sinh          sinh;\n    ///\n    alias core.stdc.math.sinhf         sinh;\n    ///\n    alias core.stdc.math.sinhl         sinh;\n\n    ///\n    alias core.stdc.complex.csinh      sinh;\n    ///\n    alias core.stdc.complex.csinhf     sinh;\n    ///\n    alias core.stdc.complex.csinhl     sinh;\n\n    ///\n    alias core.stdc.math.tanh          tanh;\n    ///\n    alias core.stdc.math.tanhf         tanh;\n    ///\n    alias core.stdc.math.tanhl         tanh;\n\n    ///\n    alias core.stdc.complex.ctanh      tanh;\n    ///\n    alias core.stdc.complex.ctanhf     tanh;\n    ///\n    alias core.stdc.complex.ctanhl     tanh;\n\n    ///\n    alias core.stdc.math.exp           exp;\n    ///\n    alias core.stdc.math.expf          exp;\n    ///\n    alias core.stdc.math.expl          exp;\n\n    ///\n    alias core.stdc.complex.cexp       exp;\n    ///\n    alias core.stdc.complex.cexpf      exp;\n    ///\n    alias core.stdc.complex.cexpl      exp;\n\n    ///\n    alias core.stdc.math.exp2          exp2;\n    ///\n    alias core.stdc.math.exp2f         exp2;\n    ///\n    alias core.stdc.math.exp2l         exp2;\n\n    ///\n    alias core.stdc.math.expm1         expm1;\n    ///\n    alias core.stdc.math.expm1f        expm1;\n    ///\n    alias core.stdc.math.expm1l        expm1;\n\n    ///\n    alias core.stdc.math.frexp         frexp;\n    ///\n    alias core.stdc.math.frexpf        frexp;\n    ///\n    alias core.stdc.math.frexpl        frexp;\n\n    ///\n    alias core.stdc.math.ilogb         ilogb;\n    ///\n    alias core.stdc.math.ilogbf        ilogb;\n    ///\n    alias core.stdc.math.ilogbl        ilogb;\n\n    ///\n    alias core.stdc.math.ldexp         ldexp;\n    ///\n    alias core.stdc.math.ldexpf        ldexp;\n    ///\n    alias core.stdc.math.ldexpl        ldexp;\n\n    ///\n    alias core.stdc.math.log           log;\n    ///\n    alias core.stdc.math.logf          log;\n    ///\n    alias core.stdc.math.logl          log;\n\n    ///\n    alias core.stdc.complex.clog       log;\n    ///\n    alias core.stdc.complex.clogf      log;\n    ///\n    alias core.stdc.complex.clogl      log;\n\n    ///\n    alias core.stdc.math.log10         log10;\n    ///\n    alias core.stdc.math.log10f        log10;\n    ///\n    alias core.stdc.math.log10l        log10;\n\n    ///\n    alias core.stdc.math.log1p         log1p;\n    ///\n    alias core.stdc.math.log1pf        log1p;\n    ///\n    alias core.stdc.math.log1pl        log1p;\n\n    ///\n    alias core.stdc.math.log2          log2;\n    ///\n    alias core.stdc.math.log2f         log2;\n    ///\n    alias core.stdc.math.log2l         log2;\n\n    ///\n    alias core.stdc.math.logb          logb;\n    ///\n    alias core.stdc.math.logbf         logb;\n    ///\n    alias core.stdc.math.logbl         logb;\n\n    ///\n    alias core.stdc.math.modf          modf;\n    ///\n    alias core.stdc.math.modff         modf;\n    ///\n    alias core.stdc.math.modfl         modf;\n\n    ///\n    alias core.stdc.math.scalbn        scalbn;\n    ///\n    alias core.stdc.math.scalbnf       scalbn;\n    ///\n    alias core.stdc.math.scalbnl       scalbn;\n\n    ///\n    alias core.stdc.math.scalbln       scalbln;\n    ///\n    alias core.stdc.math.scalblnf      scalbln;\n    ///\n    alias core.stdc.math.scalblnl      scalbln;\n\n    ///\n    alias core.stdc.math.cbrt          cbrt;\n    ///\n    alias core.stdc.math.cbrtf         cbrt;\n    ///\n    alias core.stdc.math.cbrtl         cbrt;\n\n    ///\n    alias core.stdc.math.fabs          fabs;\n    version (CRuntime_Microsoft)\n    {\n    }\n    else\n    {\n        ///\n        alias core.stdc.math.fabsf         fabs;\n        ///\n        alias core.stdc.math.fabsl         fabs;\n    }\n\n    ///\n    alias core.stdc.complex.cabs       fabs;\n    ///\n    alias core.stdc.complex.cabsf      fabs;\n    ///\n    alias core.stdc.complex.cabsl      fabs;\n\n    ///\n    alias core.stdc.math.hypot         hypot;\n    ///\n    alias core.stdc.math.hypotf        hypot;\n    ///\n    alias core.stdc.math.hypotl        hypot;\n\n    ///\n    alias core.stdc.math.pow           pow;\n    ///\n    alias core.stdc.math.powf          pow;\n    ///\n    alias core.stdc.math.powl          pow;\n\n    ///\n    alias core.stdc.complex.cpow       pow;\n    ///\n    alias core.stdc.complex.cpowf      pow;\n    ///\n    alias core.stdc.complex.cpowl      pow;\n\n    ///\n    alias core.stdc.math.sqrt          sqrt;\n    ///\n    alias core.stdc.math.sqrtf         sqrt;\n    ///\n    alias core.stdc.math.sqrtl         sqrt;\n\n    ///\n    alias core.stdc.complex.csqrt      sqrt;\n    ///\n    alias core.stdc.complex.csqrtf     sqrt;\n    ///\n    alias core.stdc.complex.csqrtl     sqrt;\n\n    ///\n    alias core.stdc.math.erf           erf;\n    ///\n    alias core.stdc.math.erff          erf;\n    ///\n    alias core.stdc.math.erfl          erf;\n\n    ///\n    alias core.stdc.math.erfc          erfc;\n    ///\n    alias core.stdc.math.erfcf         erfc;\n    ///\n    alias core.stdc.math.erfcl         erfc;\n\n    ///\n    alias core.stdc.math.lgamma        lgamma;\n    ///\n    alias core.stdc.math.lgammaf       lgamma;\n    ///\n    alias core.stdc.math.lgammal       lgamma;\n\n    ///\n    alias core.stdc.math.tgamma        tgamma;\n    ///\n    alias core.stdc.math.tgammaf       tgamma;\n    ///\n    alias core.stdc.math.tgammal       tgamma;\n\n    ///\n    alias core.stdc.math.ceil          ceil;\n    ///\n    alias core.stdc.math.ceilf         ceil;\n    ///\n    alias core.stdc.math.ceill         ceil;\n\n    ///\n    alias core.stdc.math.floor         floor;\n    ///\n    alias core.stdc.math.floorf        floor;\n    ///\n    alias core.stdc.math.floorl        floor;\n\n    ///\n    alias core.stdc.math.nearbyint     nearbyint;\n    ///\n    alias core.stdc.math.nearbyintf    nearbyint;\n    ///\n    alias core.stdc.math.nearbyintl    nearbyint;\n\n    ///\n    alias core.stdc.math.rint          rint;\n    ///\n    alias core.stdc.math.rintf         rint;\n    ///\n    alias core.stdc.math.rintl         rint;\n\n    ///\n    alias core.stdc.math.lrint         lrint;\n    ///\n    alias core.stdc.math.lrintf        lrint;\n    ///\n    alias core.stdc.math.lrintl        lrint;\n\n    ///\n    alias core.stdc.math.llrint        llrint;\n    ///\n    alias core.stdc.math.llrintf       llrint;\n    ///\n    alias core.stdc.math.llrintl       llrint;\n\n    ///\n    alias core.stdc.math.round         round;\n    ///\n    alias core.stdc.math.roundf        round;\n    ///\n    alias core.stdc.math.roundl        round;\n\n    ///\n    alias core.stdc.math.lround        lround;\n    ///\n    alias core.stdc.math.lroundf       lround;\n    ///\n    alias core.stdc.math.lroundl       lround;\n\n    ///\n    alias core.stdc.math.llround       llround;\n    ///\n    alias core.stdc.math.llroundf      llround;\n    ///\n    alias core.stdc.math.llroundl      llround;\n\n    ///\n    alias core.stdc.math.trunc         trunc;\n    ///\n    alias core.stdc.math.truncf        trunc;\n    ///\n    alias core.stdc.math.truncl        trunc;\n\n    ///\n    alias core.stdc.math.fmod          fmod;\n    ///\n    alias core.stdc.math.fmodf         fmod;\n    ///\n    alias core.stdc.math.fmodl         fmod;\n\n    ///\n    alias core.stdc.math.remainder     remainder;\n    ///\n    alias core.stdc.math.remainderf    remainder;\n    ///\n    alias core.stdc.math.remainderl    remainder;\n\n    ///\n    alias core.stdc.math.remquo        remquo;\n    ///\n    alias core.stdc.math.remquof       remquo;\n    ///\n    alias core.stdc.math.remquol       remquo;\n\n    ///\n    alias core.stdc.math.copysign      copysign;\n    ///\n    alias core.stdc.math.copysignf     copysign;\n    ///\n    alias core.stdc.math.copysignl     copysign;\n\n    ///\n    alias core.stdc.math.nan           nan;\n    ///\n    alias core.stdc.math.nanf          nan;\n    ///\n    alias core.stdc.math.nanl          nan;\n\n    ///\n    alias core.stdc.math.nextafter     nextafter;\n    ///\n    alias core.stdc.math.nextafterf    nextafter;\n    ///\n    alias core.stdc.math.nextafterl    nextafter;\n\n    ///\n    alias core.stdc.math.nexttoward    nexttoward;\n    ///\n    alias core.stdc.math.nexttowardf   nexttoward;\n    ///\n    alias core.stdc.math.nexttowardl   nexttoward;\n\n    ///\n    alias core.stdc.math.fdim          fdim;\n    ///\n    alias core.stdc.math.fdimf         fdim;\n    ///\n    alias core.stdc.math.fdiml         fdim;\n\n    ///\n    alias core.stdc.math.fmax          fmax;\n    ///\n    alias core.stdc.math.fmaxf         fmax;\n    ///\n    alias core.stdc.math.fmaxl         fmax;\n\n    ///\n    alias core.stdc.math.fmin          fmin;\n    ///\n    alias core.stdc.math.fmin          fmin;\n    ///\n    alias core.stdc.math.fminl         fmin;\n\n    ///\n    alias core.stdc.math.fma           fma;\n    ///\n    alias core.stdc.math.fmaf          fma;\n    ///\n    alias core.stdc.math.fmal          fma;\n\n    ///\n    alias core.stdc.complex.carg       carg;\n    ///\n    alias core.stdc.complex.cargf      carg;\n    ///\n    alias core.stdc.complex.cargl      carg;\n\n    ///\n    alias core.stdc.complex.cimag      cimag;\n    ///\n    alias core.stdc.complex.cimagf     cimag;\n    ///\n    alias core.stdc.complex.cimagl     cimag;\n\n    ///\n    alias core.stdc.complex.conj       conj;\n    ///\n    alias core.stdc.complex.conjf      conj;\n    ///\n    alias core.stdc.complex.conjl      conj;\n\n    ///\n    alias core.stdc.complex.cproj      cproj;\n    ///\n    alias core.stdc.complex.cprojf     cproj;\n    ///\n    alias core.stdc.complex.cprojl     cproj;\n\n//  alias core.stdc.complex.creal      creal;\n//  alias core.stdc.complex.crealf     creal;\n//  alias core.stdc.complex.creall     creal;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/time.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_time.h.html, _time.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly,\n *            Alex Rønne Petersen\n * Source:    $(DRUNTIMESRC core/stdc/_time.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.time;\n\nprivate import core.stdc.config;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nextern (C):\n@trusted: // There are only a few functions here that use unsafe C strings.\nnothrow:\n@nogc:\n\nversion (Windows)\n{\n    ///\n    struct tm\n    {\n        int     tm_sec;     /// seconds after the minute - [0, 60]\n        int     tm_min;     /// minutes after the hour - [0, 59]\n        int     tm_hour;    /// hours since midnight - [0, 23]\n        int     tm_mday;    /// day of the month - [1, 31]\n        int     tm_mon;     /// months since January - [0, 11]\n        int     tm_year;    /// years since 1900\n        int     tm_wday;    /// days since Sunday - [0, 6]\n        int     tm_yday;    /// days since January 1 - [0, 365]\n        int     tm_isdst;   /// Daylight Saving Time flag\n    }\n}\nelse version (Posix)\n{\n    ///\n    struct tm\n    {\n        int     tm_sec;     /// seconds after the minute [0-60]\n        int     tm_min;     /// minutes after the hour [0-59]\n        int     tm_hour;    /// hours since midnight [0-23]\n        int     tm_mday;    /// day of the month [1-31]\n        int     tm_mon;     /// months since January [0-11]\n        int     tm_year;    /// years since 1900\n        int     tm_wday;    /// days since Sunday [0-6]\n        int     tm_yday;    /// days since January 1 [0-365]\n        int     tm_isdst;   /// Daylight Savings Time flag\n        c_long  tm_gmtoff;  /// offset from CUT in seconds\n        char*   tm_zone;    /// timezone abbreviation\n    }\n}\n\nversion (Posix)\n{\n    public import core.sys.posix.sys.types : time_t, clock_t;\n}\nelse version (Windows)\n{\n    ///\n    alias c_long time_t;\n    ///\n    alias c_long clock_t;\n}\n\n///\nversion (Windows)\n{\n    enum clock_t CLOCKS_PER_SEC = 1000;\n    clock_t clock();\n}\nelse version (OSX)\n{\n    enum clock_t CLOCKS_PER_SEC = 1_000_000; // was 100 until OSX 10.4/10.5\n    version (X86)\n        extern (C) pragma(mangle, \"clock$UNIX2003\") clock_t clock();\n    else\n        clock_t clock();\n}\nelse version (Darwin) // other Darwins (iOS, TVOS, WatchOS)\n{\n    enum clock_t CLOCKS_PER_SEC = 1_000_000;\n    clock_t clock();\n}\nelse version (FreeBSD)\n{\n    enum clock_t CLOCKS_PER_SEC = 128;\n    clock_t clock();\n}\nelse version (NetBSD)\n{\n    enum clock_t CLOCKS_PER_SEC = 100;\n    clock_t clock();\n}\nelse version (OpenBSD)\n{\n    enum clock_t CLOCKS_PER_SEC = 100;\n    clock_t clock();\n}\nelse version (DragonFlyBSD)\n{\n    enum clock_t CLOCKS_PER_SEC = 128;\n    clock_t clock();\n}\nelse version (Solaris)\n{\n    enum clock_t CLOCKS_PER_SEC = 1_000_000;\n    clock_t clock();\n}\nelse version (CRuntime_Glibc)\n{\n    enum clock_t CLOCKS_PER_SEC = 1_000_000;\n    clock_t clock();\n}\nelse version (CRuntime_Musl)\n{\n    enum clock_t CLOCKS_PER_SEC = 1_000_000;\n    clock_t clock();\n}\nelse version (CRuntime_Bionic)\n{\n    enum clock_t CLOCKS_PER_SEC = 1_000_000;\n    clock_t clock();\n}\nelse version (CRuntime_UClibc)\n{\n    enum clock_t CLOCKS_PER_SEC = 1_000_000;\n    clock_t clock();\n}\nelse\n{\n    static assert(0, \"unsupported system\");\n}\n\n///\ndouble  difftime(time_t time1, time_t time0);\n///\ntime_t  mktime(tm* timeptr);\n///\ntime_t  time(time_t* timer);\n///\nchar*   asctime(in tm* timeptr);\n///\nchar*   ctime(in time_t* timer);\n///\ntm*     gmtime(in time_t* timer);\n///\ntm*     localtime(in time_t* timer);\n///\n@system size_t  strftime(char* s, size_t maxsize, in char* format, in tm* timeptr);\n\nversion (Windows)\n{\n    ///\n    void  tzset();                           // non-standard\n    ///\n    void  _tzset();                          // non-standard\n    ///\n    @system char* _strdate(char* s);                 // non-standard\n    ///\n    @system char* _strtime(char* s);                 // non-standard\n\n    ///\n    extern __gshared const(char)*[2] tzname; // non-standard\n}\nelse version (Darwin)\n{\n    ///\n    void tzset();                            // non-standard\n    ///\n    extern __gshared const(char)*[2] tzname; // non-standard\n}\nelse version (CRuntime_Glibc)\n{\n    ///\n    void tzset();                            // non-standard\n    ///\n    extern __gshared const(char)*[2] tzname; // non-standard\n}\nelse version (FreeBSD)\n{\n    ///\n    void tzset();                            // non-standard\n    ///\n    extern __gshared const(char)*[2] tzname; // non-standard\n}\nelse version (NetBSD)\n{\n    ///\n    void tzset();                            // non-standard\n    ///\n    extern __gshared const(char)*[2] tzname; // non-standard\n}\nelse version (OpenBSD)\n{\n    ///\n    void tzset();                            // non-standard\n    ///\n    extern __gshared const(char)*[2] tzname; // non-standard\n}\nelse version (DragonFlyBSD)\n{\n    ///\n    void tzset();                            // non-standard\n    ///\n    extern __gshared const(char)*[2] tzname; // non-standard\n}\nelse version (Solaris)\n{\n    ///\n    void tzset();\n    ///\n    extern __gshared const(char)*[2] tzname;\n}\nelse version (CRuntime_Bionic)\n{\n    ///\n    void tzset();\n    ///\n    extern __gshared const(char)*[2] tzname;\n}\nelse version (CRuntime_Musl)\n{\n    ///\n    void tzset();                            // non-standard\n    ///\n    extern __gshared const(char)*[2] tzname; // non-standard\n}\nelse version (CRuntime_UClibc)\n{\n    ///\n    void tzset();\n    ///\n    extern __gshared const(char)*[2] tzname;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/wchar_.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_wchar.h.html, _wchar.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_wchar_.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule core.stdc.wchar_;\n\nprivate import core.stdc.config;\nprivate import core.stdc.stdarg; // for va_list\nprivate import core.stdc.stdio;  // for FILE, not exposed per spec\npublic import core.stdc.stddef;  // for wchar_t\npublic import core.stdc.time;    // for tm\npublic import core.stdc.stdint;  // for WCHAR_MIN, WCHAR_MAX\n\nextern (C):\n@system:\nnothrow:\n@nogc:\n\nversion (CRuntime_Glibc)\n{\n    ///\n    struct mbstate_t\n    {\n        int __count;\n        union ___value\n        {\n            wint_t __wch;\n            char[4] __wchb;\n        }\n        ___value __value;\n    }\n}\nelse version (OpenBSD)\n{\n    union __mbstate_t\n    {\n        char[128] __mbstate8;\n        int64_t   __mbstateL;\n    }\n    alias mbstate_t = __mbstate_t;\n}\nelse version (Solaris)\n{\n    ///\n    struct __mbstate_t\n    {\n        version (D_LP64)\n        {\n            long[4] __filler;\n        }\n        else\n        {\n            int[6] __filler;\n        }\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    ///\n    struct mbstate_t\n    {\n        wchar_t __mask;\n        wchar_t __wc;\n    }\n}\nelse\n{\n    ///\n    alias int mbstate_t;\n}\n\n///\nalias wchar_t wint_t;\n\n///\nenum wchar_t WEOF = 0xFFFF;\n\n///\nint fwprintf(FILE* stream, in wchar_t* format, ...);\n///\nint fwscanf(FILE* stream, in wchar_t* format, ...);\nint swscanf(in wchar_t* s, in wchar_t* format, ...);\n///\nint vfwprintf(FILE* stream, in wchar_t* format, va_list arg);\n///\nint vfwscanf(FILE* stream, in wchar_t* format, va_list arg);\nint vswscanf(in wchar_t* s, in wchar_t* format, va_list arg);\n///\nint vwprintf(in wchar_t* format, va_list arg);\n///\nint vwscanf(in wchar_t* format, va_list arg);\n///\nint wprintf(in wchar_t* format, ...);\n///\nint wscanf(in wchar_t* format, ...);\n\n/*\n * Windows has 2 versions of swprintf and vswprintf.  MinGW defaults to the\n * Microsoft signature.  Alias to match DMD/ANSI signature.\n */\nversion (MinGW)\n{\n    ///\n    int _snwprintf(wchar_t* s, size_t n, in wchar_t* format, ...);\n    alias _snwprintf swprintf;\n    ///\n    int _vsnwprintf(wchar_t* s, size_t n, in wchar_t* format, va_list arg);\n    alias _vsnwprintf vswprintf;\t\n}\nelse\n{\n    ///\n    int swprintf(wchar_t* s, size_t n, in wchar_t* format, ...);\n    ///\n    int vswprintf(wchar_t* s, size_t n, in wchar_t* format, va_list arg);\n}\n\n// No unsafe pointer manipulation.\n@trusted\n{\n    ///\n    wint_t fgetwc(FILE* stream);\n    ///\n    wint_t fputwc(wchar_t c, FILE* stream);\n}\n\n///\nwchar_t* fgetws(wchar_t* s, int n, FILE* stream);\n///\nint      fputws(in wchar_t* s, FILE* stream);\n\n// No unsafe pointer manipulation.\nextern (D) @trusted\n{\n    ///\n    wint_t getwchar()                     { return fgetwc(stdin);     }\n    ///\n    wint_t putwchar(wchar_t c)            { return fputwc(c,stdout);  }\n    ///\n    wint_t getwc(FILE* stream)            { return fgetwc(stream);    }\n    ///\n    wint_t putwc(wchar_t c, FILE* stream) { return fputwc(c, stream); }\n}\n\n// No unsafe pointer manipulation.\n@trusted\n{\n    ///\n    wint_t ungetwc(wint_t c, FILE* stream);\n    ///\n    version (CRuntime_Microsoft)\n    {\n        // MSVC defines this as an inline function.\n        int fwide(FILE* stream, int mode) { return mode; }\n    }\n    else\n    {\n        int    fwide(FILE* stream, int mode);\n    }\n}\n\n///\ndouble  wcstod(in wchar_t* nptr, wchar_t** endptr);\n///\nfloat   wcstof(in wchar_t* nptr, wchar_t** endptr);\n///\nreal    wcstold(in wchar_t* nptr, wchar_t** endptr);\n///\nc_long  wcstol(in wchar_t* nptr, wchar_t** endptr, int base);\n///\nlong    wcstoll(in wchar_t* nptr, wchar_t** endptr, int base);\n///\nc_ulong wcstoul(in wchar_t* nptr, wchar_t** endptr, int base);\n///\nulong   wcstoull(in wchar_t* nptr, wchar_t** endptr, int base);\n\n///\npure wchar_t* wcscpy(return wchar_t* s1, scope const wchar_t* s2);\n///\npure wchar_t* wcsncpy(return wchar_t* s1, scope const wchar_t* s2, size_t n);\n///\npure wchar_t* wcscat(return wchar_t* s1, scope const wchar_t* s2);\n///\npure wchar_t* wcsncat(return wchar_t* s1, scope const wchar_t* s2, size_t n);\n///\npure int wcscmp(scope const wchar_t* s1, scope const wchar_t* s2);\n///\nint      wcscoll(scope const wchar_t* s1, scope const wchar_t* s2);\n///\npure int wcsncmp(scope const wchar_t* s1, scope const wchar_t* s2, size_t n);\n///\nsize_t   wcsxfrm(scope wchar_t* s1, scope const wchar_t* s2, size_t n);\n///\npure inout(wchar_t)* wcschr(return inout(wchar_t)* s, wchar_t c);\n///\npure size_t wcscspn(scope const wchar_t* s1, scope const wchar_t* s2);\n///\npure inout(wchar_t)* wcspbrk(return inout(wchar_t)* s1, scope const wchar_t* s2);\n///\npure inout(wchar_t)* wcsrchr(return inout(wchar_t)* s, wchar_t c);\n///\npure size_t wcsspn(scope const wchar_t* s1, scope const wchar_t* s2);\n///\npure inout(wchar_t)* wcsstr(return inout(wchar_t)* s1, scope const wchar_t* s2);\n///\nwchar_t* wcstok(return wchar_t* s1, scope const wchar_t* s2, wchar_t** ptr);\n///\npure size_t wcslen(scope const wchar_t* s);\n\n///\npure wchar_t* wmemchr(return const wchar_t* s, wchar_t c, size_t n);\n///\npure int      wmemcmp(scope const wchar_t* s1, scope const wchar_t* s2, size_t n);\n///\npure wchar_t* wmemcpy(return wchar_t* s1, scope const wchar_t* s2, size_t n);\n///\npure wchar_t* wmemmove(return wchar_t* s1, scope const wchar_t* s2, size_t n);\n///\npure wchar_t* wmemset(return wchar_t* s, wchar_t c, size_t n);\n\n///\nsize_t wcsftime(wchar_t* s, size_t maxsize, in wchar_t* format, in tm* timeptr);\n\nversion (Windows)\n{\n    ///\n    wchar_t* _wasctime(tm*);      // non-standard\n    ///\n    wchar_t* _wctime(time_t*);    // non-standard\n    ///\n    wchar_t* _wstrdate(wchar_t*); // non-standard\n    ///\n    wchar_t* _wstrtime(wchar_t*); // non-standard\n}\n\n// No unsafe pointer manipulation.\n@trusted\n{\n    ///\n    wint_t btowc(int c);\n    ///\n    int    wctob(wint_t c);\n}\n\n///\nint    mbsinit(in mbstate_t* ps);\n///\nsize_t mbrlen(in char* s, size_t n, mbstate_t* ps);\n///\nsize_t mbrtowc(wchar_t* pwc, in char* s, size_t n, mbstate_t* ps);\n///\nsize_t wcrtomb(char* s, wchar_t wc, mbstate_t* ps);\n///\nsize_t mbsrtowcs(wchar_t* dst, in char** src, size_t len, mbstate_t* ps);\n///\nsize_t wcsrtombs(char* dst, in wchar_t** src, size_t len, mbstate_t* ps);\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdc/wctype.d",
    "content": "/**\n * D header file for C99.\n *\n * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_wctype.h.html, _wctype.h)\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/stdc/_wctype.d)\n * Standards: ISO/IEC 9899:1999 (E)\n */\n\nmodule core.stdc.wctype;\n\npublic  import core.stdc.wchar_; // for wint_t, WEOF\n\nextern (C):\n@trusted: // Only a couple of functions below operate on unsafe C strings.\nnothrow:\n@nogc:\n\n///\nalias wchar_t wctrans_t;\n///\nalias wchar_t wctype_t;\n\n///\npure int iswalnum(wint_t wc);\n///\npure int iswalpha(wint_t wc);\n///\npure int iswblank(wint_t wc);\n///\npure int iswcntrl(wint_t wc);\n///\npure int iswdigit(wint_t wc);\n///\npure int iswgraph(wint_t wc);\n///\npure int iswlower(wint_t wc);\n///\npure int iswprint(wint_t wc);\n///\npure int iswpunct(wint_t wc);\n///\npure int iswspace(wint_t wc);\n///\npure int iswupper(wint_t wc);\n///\npure int iswxdigit(wint_t wc);\n\n///\nint       iswctype(wint_t wc, wctype_t desc);\n///\n@system wctype_t  wctype(in char* property);\n///\npure wint_t    towlower(wint_t wc);\n///\npure wint_t    towupper(wint_t wc);\n///\nwint_t    towctrans(wint_t wc, wctrans_t desc);\n///\n@system wctrans_t wctrans(in char* property);\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdcpp/exception.d",
    "content": "// Written in the D programming language.\n\n/**\n * Interface to C++ <exception>\n *\n * Copyright: Copyright (c) 2016 D Language Foundation\n * License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright)\n * Source:    $(DRUNTIMESRC core/stdcpp/_exception.d)\n */\n\nmodule core.stdcpp.exception;\n\nextern (C++, \"std\"):\n\nversion (CppRuntime_DigitalMars)\n{\n    import core.stdcpp.typeinfo;\n\n    alias void function() unexpected_handler;\n    unexpected_handler set_unexpected(unexpected_handler f) nothrow;\n    void unexpected();\n\n    alias void function() terminate_handler;\n    terminate_handler set_terminate(terminate_handler f) nothrow;\n    void terminate();\n\n    bool uncaught_exception();\n\n    class exception\n    {\n        this() nothrow { }\n        this(const exception) nothrow { }\n        //exception operator=(const exception) nothrow { return this; }\n        //virtual ~this() nothrow;\n        void dtor() { }\n        const(char)* what() const nothrow;\n    }\n\n    class bad_exception : exception\n    {\n        this() nothrow { }\n        this(const bad_exception) nothrow { }\n        //bad_exception operator=(const bad_exception) nothrow { return this; }\n        //virtual ~this() nothrow;\n        override const(char)* what() const nothrow;\n    }\n}\nelse version (CppRuntime_Gcc)\n{\n    alias void function() unexpected_handler;\n    unexpected_handler set_unexpected(unexpected_handler f) nothrow;\n    void unexpected();\n\n    alias void function() terminate_handler;\n    terminate_handler set_terminate(terminate_handler f) nothrow;\n    void terminate();\n\n    pure bool uncaught_exception();\n\n    class exception\n    {\n        this();\n        //virtual ~this();\n        void dtor1();\n        void dtor2();\n        const(char)* what() const;\n    }\n\n    class bad_exception : exception\n    {\n        this();\n        //virtual ~this();\n        override const(char)* what() const;\n    }\n}\nelse version (CppRuntime_Microsoft)\n{\n    class exception\n    {\n        this();\n        this(const exception);\n        //exception operator=(const exception) { return this; }\n            //virtual ~this();\n        void dtor() { }\n        const(char)* what() const;\n\n    private:\n        const(char)* mywhat;\n        bool dofree;\n    }\n\n    class bad_exception : exception\n    {\n        this(const(char)* msg = \"bad exception\");\n        //virtual ~this();\n    }\n}\nelse\n    static assert(0, \"Missing std::exception binding for this platform\");\n"
  },
  {
    "path": "libphobos/libdruntime/core/stdcpp/typeinfo.d",
    "content": "// Written in the D programming language.\n\n/**\n * Interface to C++ <typeinfo>\n *\n * Copyright: Copyright (c) 2016 D Language Foundation\n * License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright)\n * Source:    $(DRUNTIMESRC core/stdcpp/_typeinfo.d)\n */\n\nmodule core.stdcpp.typeinfo;\n\nversion (CppRuntime_DigitalMars)\n{\n    import core.stdcpp.exception;\n\n    extern (C++, \"std\"):\n\n    class type_info\n    {\n        void* pdata;\n\n    public:\n        //virtual ~this();\n        void dtor() { }     // reserve slot in vtbl[]\n\n        //bool operator==(const type_info rhs) const;\n        //bool operator!=(const type_info rhs) const;\n        final bool before(const type_info rhs) const;\n        final const(char)* name() const;\n    protected:\n        //type_info();\n    private:\n        //this(const type_info rhs);\n        //type_info operator=(const type_info rhs);\n    }\n\n    class bad_cast : exception\n    {\n        this() nothrow { }\n        this(const bad_cast) nothrow { }\n        //bad_cast operator=(const bad_cast) nothrow { return this; }\n        //virtual ~this() nothrow;\n        override const(char)* what() const nothrow;\n    }\n\n    class bad_typeid : exception\n    {\n        this() nothrow { }\n        this(const bad_typeid) nothrow { }\n        //bad_typeid operator=(const bad_typeid) nothrow { return this; }\n        //virtual ~this() nothrow;\n        override const (char)* what() const nothrow;\n    }\n}\nelse version (CppRuntime_Microsoft)\n{\n    import core.stdcpp.exception;\n\n    extern (C++, \"std\"):\n\n    struct __type_info_node\n    {\n        void* _MemPtr;\n        __type_info_node* _Next;\n    }\n\n    extern __gshared __type_info_node __type_info_root_node;\n\n    class type_info\n    {\n        //virtual ~this();\n        void dtor() { }     // reserve slot in vtbl[]\n        //bool operator==(const type_info rhs) const;\n        //bool operator!=(const type_info rhs) const;\n        final bool before(const type_info rhs) const;\n        final const(char)* name(__type_info_node* p = &__type_info_root_node) const;\n\n    private:\n        void* pdata;\n        char[1] _name;\n        //type_info operator=(const type_info rhs);\n    }\n\n    class bad_cast : exception\n    {\n        this(const(char)* msg = \"bad cast\");\n        //virtual ~this();\n    }\n\n    class bad_typeid : exception\n    {\n        this(const(char)* msg = \"bad typeid\");\n        //virtual ~this();\n    }\n}\nelse version (CppRuntime_Gcc)\n{\n    import core.stdcpp.exception;\n\n    extern (C++, \"__cxxabiv1\")\n    {\n        class __class_type_info;\n    }\n\n    extern (C++, \"std\"):\n\n    class type_info\n    {\n        void dtor1();                           // consume destructor slot in vtbl[]\n        void dtor2();                           // consume destructor slot in vtbl[]\n        final const(char)* name()() const nothrow {\n            return _name[0] == '*' ? _name + 1 : _name;\n        }\n        final bool before()(const type_info _arg) const {\n            import core.stdc.string : strcmp;\n            return (_name[0] == '*' && _arg._name[0] == '*')\n                ? _name < _arg._name\n                : strcmp(_name, _arg._name) < 0;\n        }\n        //bool operator==(const type_info) const;\n        bool __is_pointer_p() const;\n        bool __is_function_p() const;\n        bool __do_catch(const type_info, void**, uint) const;\n        bool __do_upcast(const __class_type_info, void**) const;\n\n        const(char)* _name;\n        this(const(char)*);\n    }\n\n    class bad_cast : exception\n    {\n        this();\n        //~this();\n        override const(char)* what() const;\n    }\n\n    class bad_typeid : exception\n    {\n        this();\n        //~this();\n        override const(char)* what() const;\n    }\n}\nelse\n    static assert(0, \"Missing std::type_info binding for this platform\");\n"
  },
  {
    "path": "libphobos/libdruntime/core/sync/barrier.d",
    "content": "/**\n * The barrier module provides a primitive for synchronizing the progress of\n * a group of threads.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/sync/_barrier.d)\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sync.barrier;\n\n\npublic import core.sync.exception;\nprivate import core.sync.condition;\nprivate import core.sync.mutex;\n\nversion (Posix)\n{\n    private import core.stdc.errno;\n    private import core.sys.posix.pthread;\n}\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Barrier\n//\n// void wait();\n////////////////////////////////////////////////////////////////////////////////\n\n\n/**\n * This class represents a barrier across which threads may only travel in\n * groups of a specific size.\n */\nclass Barrier\n{\n    ////////////////////////////////////////////////////////////////////////////\n    // Initialization\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Initializes a barrier object which releases threads in groups of limit\n     * in size.\n     *\n     * Params:\n     *  limit = The number of waiting threads to release in unison.\n     *\n     * Throws:\n     *  SyncError on error.\n     */\n    this( uint limit )\n    in\n    {\n        assert( limit > 0 );\n    }\n    do\n    {\n        m_lock  = new Mutex;\n        m_cond  = new Condition( m_lock );\n        m_group = 0;\n        m_limit = limit;\n        m_count = limit;\n    }\n\n\n    ////////////////////////////////////////////////////////////////////////////\n    // General Actions\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Wait for the pre-determined number of threads and then proceed.\n     *\n     * Throws:\n     *  SyncError on error.\n     */\n    void wait()\n    {\n        synchronized( m_lock )\n        {\n            uint group = m_group;\n\n            if ( --m_count == 0 )\n            {\n                m_group++;\n                m_count = m_limit;\n                m_cond.notifyAll();\n            }\n            while ( group == m_group )\n                m_cond.wait();\n        }\n    }\n\n\nprivate:\n    Mutex       m_lock;\n    Condition   m_cond;\n    uint        m_group;\n    uint        m_limit;\n    uint        m_count;\n}\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Unit Tests\n////////////////////////////////////////////////////////////////////////////////\n\n\nversion (unittest)\n{\n    private import core.thread;\n\n\n    unittest\n    {\n        int  numThreads = 10;\n        auto barrier    = new Barrier( numThreads );\n        auto synInfo    = new Object;\n        int  numReady   = 0;\n        int  numPassed  = 0;\n\n        void threadFn()\n        {\n            synchronized( synInfo )\n            {\n                ++numReady;\n            }\n            barrier.wait();\n            synchronized( synInfo )\n            {\n                ++numPassed;\n            }\n        }\n\n        auto group = new ThreadGroup;\n\n        for ( int i = 0; i < numThreads; ++i )\n        {\n            group.create( &threadFn );\n        }\n        group.joinAll();\n        assert( numReady == numThreads && numPassed == numThreads );\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sync/condition.d",
    "content": "/**\n * The condition module provides a primitive for synchronized condition\n * checking.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/sync/_condition.d)\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sync.condition;\n\n\npublic import core.sync.exception;\npublic import core.sync.mutex;\npublic import core.time;\n\nversion (Windows)\n{\n    private import core.sync.semaphore;\n    private import core.sys.windows.windows;\n}\nelse version (Posix)\n{\n    private import core.sync.config;\n    private import core.stdc.errno;\n    private import core.sys.posix.pthread;\n    private import core.sys.posix.time;\n}\nelse\n{\n    static assert(false, \"Platform not supported\");\n}\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Condition\n//\n// void wait();\n// void notify();\n// void notifyAll();\n////////////////////////////////////////////////////////////////////////////////\n\n\n/**\n * This class represents a condition variable as conceived by C.A.R. Hoare.  As\n * per Mesa type monitors however, \"signal\" has been replaced with \"notify\" to\n * indicate that control is not transferred to the waiter when a notification\n * is sent.\n */\nclass Condition\n{\n    ////////////////////////////////////////////////////////////////////////////\n    // Initialization\n    ////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * Initializes a condition object which is associated with the supplied\n     * mutex object.\n     *\n     * Params:\n     *  m = The mutex with which this condition will be associated.\n     *\n     * Throws:\n     *  SyncError on error.\n     */\n    this( Mutex m ) nothrow @safe\n    {\n        version (Windows)\n        {\n            m_blockLock = CreateSemaphoreA( null, 1, 1, null );\n            if ( m_blockLock == m_blockLock.init )\n                throw new SyncError( \"Unable to initialize condition\" );\n            scope(failure) CloseHandle( m_blockLock );\n\n            m_blockQueue = CreateSemaphoreA( null, 0, int.max, null );\n            if ( m_blockQueue == m_blockQueue.init )\n                throw new SyncError( \"Unable to initialize condition\" );\n            scope(failure) CloseHandle( m_blockQueue );\n\n            InitializeCriticalSection( &m_unblockLock );\n            m_assocMutex = m;\n        }\n        else version (Posix)\n        {\n            m_assocMutex = m;\n            int rc = pthread_cond_init( &m_hndl, null );\n            if ( rc )\n                throw new SyncError( \"Unable to initialize condition\" );\n        }\n    }\n\n\n    ~this()\n    {\n        version (Windows)\n        {\n            BOOL rc = CloseHandle( m_blockLock );\n            assert( rc, \"Unable to destroy condition\" );\n            rc = CloseHandle( m_blockQueue );\n            assert( rc, \"Unable to destroy condition\" );\n            DeleteCriticalSection( &m_unblockLock );\n        }\n        else version (Posix)\n        {\n            int rc = pthread_cond_destroy( &m_hndl );\n            assert( !rc, \"Unable to destroy condition\" );\n        }\n    }\n\n\n    ////////////////////////////////////////////////////////////////////////////\n    // General Properties\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Gets the mutex associated with this condition.\n     *\n     * Returns:\n     *  The mutex associated with this condition.\n     */\n    @property Mutex mutex()\n    {\n        return m_assocMutex;\n    }\n\n    // undocumented function for internal use\n    final @property Mutex mutex_nothrow() pure nothrow @safe @nogc\n    {\n        return m_assocMutex;\n    }\n\n\n    ////////////////////////////////////////////////////////////////////////////\n    // General Actions\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Wait until notified.\n     *\n     * Throws:\n     *  SyncError on error.\n     */\n    void wait()\n    {\n        version (Windows)\n        {\n            timedWait( INFINITE );\n        }\n        else version (Posix)\n        {\n            int rc = pthread_cond_wait( &m_hndl, m_assocMutex.handleAddr() );\n            if ( rc )\n                throw new SyncError( \"Unable to wait for condition\" );\n        }\n    }\n\n\n    /**\n     * Suspends the calling thread until a notification occurs or until the\n     * supplied time period has elapsed.\n     *\n     * Params:\n     *  val = The time to wait.\n     *\n     * In:\n     *  val must be non-negative.\n     *\n     * Throws:\n     *  SyncError on error.\n     *\n     * Returns:\n     *  true if notified before the timeout and false if not.\n     */\n    bool wait( Duration val )\n    in\n    {\n        assert( !val.isNegative );\n    }\n    do\n    {\n        version (Windows)\n        {\n            auto maxWaitMillis = dur!(\"msecs\")( uint.max - 1 );\n\n            while ( val > maxWaitMillis )\n            {\n                if ( timedWait( cast(uint)\n                               maxWaitMillis.total!\"msecs\" ) )\n                    return true;\n                val -= maxWaitMillis;\n            }\n            return timedWait( cast(uint) val.total!\"msecs\" );\n        }\n        else version (Posix)\n        {\n            timespec t = void;\n            mktspec( t, val );\n\n            int rc = pthread_cond_timedwait( &m_hndl,\n                                             m_assocMutex.handleAddr(),\n                                             &t );\n            if ( !rc )\n                return true;\n            if ( rc == ETIMEDOUT )\n                return false;\n            throw new SyncError( \"Unable to wait for condition\" );\n        }\n    }\n\n\n    /**\n     * Notifies one waiter.\n     *\n     * Throws:\n     *  SyncError on error.\n     */\n    void notify()\n    {\n        version (Windows)\n        {\n            notify( false );\n        }\n        else version (Posix)\n        {\n            int rc = pthread_cond_signal( &m_hndl );\n            if ( rc )\n                throw new SyncError( \"Unable to notify condition\" );\n        }\n    }\n\n\n    /**\n     * Notifies all waiters.\n     *\n     * Throws:\n     *  SyncError on error.\n     */\n    void notifyAll()\n    {\n        version (Windows)\n        {\n            notify( true );\n        }\n        else version (Posix)\n        {\n            int rc = pthread_cond_broadcast( &m_hndl );\n            if ( rc )\n                throw new SyncError( \"Unable to notify condition\" );\n        }\n    }\n\n\nprivate:\n    version (Windows)\n    {\n        bool timedWait( DWORD timeout )\n        {\n            int   numSignalsLeft;\n            int   numWaitersGone;\n            DWORD rc;\n\n            rc = WaitForSingleObject( m_blockLock, INFINITE );\n            assert( rc == WAIT_OBJECT_0 );\n\n            m_numWaitersBlocked++;\n\n            rc = ReleaseSemaphore( m_blockLock, 1, null );\n            assert( rc );\n\n            m_assocMutex.unlock();\n            scope(failure) m_assocMutex.lock();\n\n            rc = WaitForSingleObject( m_blockQueue, timeout );\n            assert( rc == WAIT_OBJECT_0 || rc == WAIT_TIMEOUT );\n            bool timedOut = (rc == WAIT_TIMEOUT);\n\n            EnterCriticalSection( &m_unblockLock );\n            scope(failure) LeaveCriticalSection( &m_unblockLock );\n\n            if ( (numSignalsLeft = m_numWaitersToUnblock) != 0 )\n            {\n                if ( timedOut )\n                {\n                    // timeout (or canceled)\n                    if ( m_numWaitersBlocked != 0 )\n                    {\n                        m_numWaitersBlocked--;\n                        // do not unblock next waiter below (already unblocked)\n                        numSignalsLeft = 0;\n                    }\n                    else\n                    {\n                        // spurious wakeup pending!!\n                        m_numWaitersGone = 1;\n                    }\n                }\n                if ( --m_numWaitersToUnblock == 0 )\n                {\n                    if ( m_numWaitersBlocked != 0 )\n                    {\n                        // open the gate\n                        rc = ReleaseSemaphore( m_blockLock, 1, null );\n                        assert( rc );\n                        // do not open the gate below again\n                        numSignalsLeft = 0;\n                    }\n                    else if ( (numWaitersGone = m_numWaitersGone) != 0 )\n                    {\n                        m_numWaitersGone = 0;\n                    }\n                }\n            }\n            else if ( ++m_numWaitersGone == int.max / 2 )\n            {\n                // timeout/canceled or spurious event :-)\n                rc = WaitForSingleObject( m_blockLock, INFINITE );\n                assert( rc == WAIT_OBJECT_0 );\n                // something is going on here - test of timeouts?\n                m_numWaitersBlocked -= m_numWaitersGone;\n                rc = ReleaseSemaphore( m_blockLock, 1, null );\n                assert( rc == WAIT_OBJECT_0 );\n                m_numWaitersGone = 0;\n            }\n\n            LeaveCriticalSection( &m_unblockLock );\n\n            if ( numSignalsLeft == 1 )\n            {\n                // better now than spurious later (same as ResetEvent)\n                for ( ; numWaitersGone > 0; --numWaitersGone )\n                {\n                    rc = WaitForSingleObject( m_blockQueue, INFINITE );\n                    assert( rc == WAIT_OBJECT_0 );\n                }\n                // open the gate\n                rc = ReleaseSemaphore( m_blockLock, 1, null );\n                assert( rc );\n            }\n            else if ( numSignalsLeft != 0 )\n            {\n                // unblock next waiter\n                rc = ReleaseSemaphore( m_blockQueue, 1, null );\n                assert( rc );\n            }\n            m_assocMutex.lock();\n            return !timedOut;\n        }\n\n\n        void notify( bool all )\n        {\n            DWORD rc;\n\n            EnterCriticalSection( &m_unblockLock );\n            scope(failure) LeaveCriticalSection( &m_unblockLock );\n\n            if ( m_numWaitersToUnblock != 0 )\n            {\n                if ( m_numWaitersBlocked == 0 )\n                {\n                    LeaveCriticalSection( &m_unblockLock );\n                    return;\n                }\n                if ( all )\n                {\n                    m_numWaitersToUnblock += m_numWaitersBlocked;\n                    m_numWaitersBlocked = 0;\n                }\n                else\n                {\n                    m_numWaitersToUnblock++;\n                    m_numWaitersBlocked--;\n                }\n                LeaveCriticalSection( &m_unblockLock );\n            }\n            else if ( m_numWaitersBlocked > m_numWaitersGone )\n            {\n                rc = WaitForSingleObject( m_blockLock, INFINITE );\n                assert( rc == WAIT_OBJECT_0 );\n                if ( 0 != m_numWaitersGone )\n                {\n                    m_numWaitersBlocked -= m_numWaitersGone;\n                    m_numWaitersGone = 0;\n                }\n                if ( all )\n                {\n                    m_numWaitersToUnblock = m_numWaitersBlocked;\n                    m_numWaitersBlocked = 0;\n                }\n                else\n                {\n                    m_numWaitersToUnblock = 1;\n                    m_numWaitersBlocked--;\n                }\n                LeaveCriticalSection( &m_unblockLock );\n                rc = ReleaseSemaphore( m_blockQueue, 1, null );\n                assert( rc );\n            }\n            else\n            {\n                LeaveCriticalSection( &m_unblockLock );\n            }\n        }\n\n\n        // NOTE: This implementation uses Algorithm 8c as described here:\n        //       http://groups.google.com/group/comp.programming.threads/\n        //              browse_frm/thread/1692bdec8040ba40/e7a5f9d40e86503a\n        HANDLE              m_blockLock;    // auto-reset event (now semaphore)\n        HANDLE              m_blockQueue;   // auto-reset event (now semaphore)\n        Mutex               m_assocMutex;   // external mutex/CS\n        CRITICAL_SECTION    m_unblockLock;  // internal mutex/CS\n        int                 m_numWaitersGone        = 0;\n        int                 m_numWaitersBlocked     = 0;\n        int                 m_numWaitersToUnblock   = 0;\n    }\n    else version (Posix)\n    {\n        Mutex               m_assocMutex;\n        pthread_cond_t      m_hndl;\n    }\n}\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Unit Tests\n////////////////////////////////////////////////////////////////////////////////\n\n\nversion (unittest)\n{\n    private import core.thread;\n    private import core.sync.mutex;\n    private import core.sync.semaphore;\n\n\n    void testNotify()\n    {\n        auto mutex      = new Mutex;\n        auto condReady  = new Condition( mutex );\n        auto semDone    = new Semaphore;\n        auto synLoop    = new Object;\n        int  numWaiters = 10;\n        int  numTries   = 10;\n        int  numReady   = 0;\n        int  numTotal   = 0;\n        int  numDone    = 0;\n        int  numPost    = 0;\n\n        void waiter()\n        {\n            for ( int i = 0; i < numTries; ++i )\n            {\n                synchronized( mutex )\n                {\n                    while ( numReady < 1 )\n                    {\n                        condReady.wait();\n                    }\n                    --numReady;\n                    ++numTotal;\n                }\n\n                synchronized( synLoop )\n                {\n                    ++numDone;\n                }\n                semDone.wait();\n            }\n        }\n\n        auto group = new ThreadGroup;\n\n        for ( int i = 0; i < numWaiters; ++i )\n            group.create( &waiter );\n\n        for ( int i = 0; i < numTries; ++i )\n        {\n            for ( int j = 0; j < numWaiters; ++j )\n            {\n                synchronized( mutex )\n                {\n                    ++numReady;\n                    condReady.notify();\n                }\n            }\n            while ( true )\n            {\n                synchronized( synLoop )\n                {\n                    if ( numDone >= numWaiters )\n                        break;\n                }\n                Thread.yield();\n            }\n            for ( int j = 0; j < numWaiters; ++j )\n            {\n                semDone.notify();\n            }\n        }\n\n        group.joinAll();\n        assert( numTotal == numWaiters * numTries );\n    }\n\n\n    void testNotifyAll()\n    {\n        auto mutex      = new Mutex;\n        auto condReady  = new Condition( mutex );\n        int  numWaiters = 10;\n        int  numReady   = 0;\n        int  numDone    = 0;\n        bool alert      = false;\n\n        void waiter()\n        {\n            synchronized( mutex )\n            {\n                ++numReady;\n                while ( !alert )\n                    condReady.wait();\n                ++numDone;\n            }\n        }\n\n        auto group = new ThreadGroup;\n\n        for ( int i = 0; i < numWaiters; ++i )\n            group.create( &waiter );\n\n        while ( true )\n        {\n            synchronized( mutex )\n            {\n                if ( numReady >= numWaiters )\n                {\n                    alert = true;\n                    condReady.notifyAll();\n                    break;\n                }\n            }\n            Thread.yield();\n        }\n        group.joinAll();\n        assert( numReady == numWaiters && numDone == numWaiters );\n    }\n\n\n    void testWaitTimeout()\n    {\n        auto mutex      = new Mutex;\n        auto condReady  = new Condition( mutex );\n        bool waiting    = false;\n        bool alertedOne = true;\n        bool alertedTwo = true;\n\n        void waiter()\n        {\n            synchronized( mutex )\n            {\n                waiting    = true;\n                // we never want to miss the notification (30s)\n                alertedOne = condReady.wait( dur!\"seconds\"(30) );\n                // but we don't want to wait long for the timeout (10ms)\n                alertedTwo = condReady.wait( dur!\"msecs\"(10) );\n            }\n        }\n\n        auto thread = new Thread( &waiter );\n        thread.start();\n\n        while ( true )\n        {\n            synchronized( mutex )\n            {\n                if ( waiting )\n                {\n                    condReady.notify();\n                    break;\n                }\n            }\n            Thread.yield();\n        }\n        thread.join();\n        assert( waiting );\n        assert( alertedOne );\n        assert( !alertedTwo );\n    }\n\n\n    unittest\n    {\n        testNotify();\n        testNotifyAll();\n        testWaitTimeout();\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sync/config.d",
    "content": "/**\n * The config module contains utility routines and configuration information\n * specific to this package.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/sync/_config.d)\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sync.config;\n\n\nversion (Posix)\n{\n    private import core.sys.posix.time;\n    private import core.sys.posix.sys.time;\n    private import core.time;\n\n\n    void mktspec( ref timespec t ) nothrow\n    {\n        static if ( false && is( typeof( clock_gettime ) ) )\n        {\n            clock_gettime( CLOCK_REALTIME, &t );\n        }\n        else\n        {\n            timeval tv;\n\n            gettimeofday( &tv, null );\n            (cast(byte*) &t)[0 .. t.sizeof] = 0;\n            t.tv_sec  = cast(typeof(t.tv_sec))  tv.tv_sec;\n            t.tv_nsec = cast(typeof(t.tv_nsec)) tv.tv_usec * 1_000;\n        }\n    }\n\n\n    void mktspec( ref timespec t, Duration delta ) nothrow\n    {\n        mktspec( t );\n        mvtspec( t, delta );\n    }\n\n\n    void mvtspec( ref timespec t, Duration delta ) nothrow\n    {\n        auto val  = delta;\n             val += dur!\"seconds\"( t.tv_sec );\n             val += dur!\"nsecs\"( t.tv_nsec );\n\n        //auto val = delta + dur!\"seconds\"( t.tv_sec ) +\n        //                 + dur!\"nsecs\"( t.tv_nsec );\n\n        if ( val.total!\"seconds\" > t.tv_sec.max )\n        {\n            t.tv_sec  = t.tv_sec.max;\n            t.tv_nsec = cast(typeof(t.tv_nsec)) val.split!(\"seconds\", \"nsecs\")().nsecs;\n        }\n        else\n            val.split!(\"seconds\", \"nsecs\")(t.tv_sec, t.tv_nsec);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sync/exception.d",
    "content": "/**\n * Define base class for synchronization exceptions.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/sync/_exception.d)\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sync.exception;\n\n\n/**\n * Base class for synchronization errors.\n */\nclass SyncError : Error\n{\n    @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)\n    {\n        super(msg, file, line, next);\n    }\n\n    @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__)\n    {\n        super(msg, file, line, next);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sync/mutex.d",
    "content": "/**\n * The mutex module provides a primitive for maintaining mutually exclusive\n * access.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/sync/_mutex.d)\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sync.mutex;\n\n\npublic import core.sync.exception;\n\nversion (Windows)\n{\n    private import core.sys.windows.windows;\n}\nelse version (Posix)\n{\n    private import core.sys.posix.pthread;\n}\nelse\n{\n    static assert(false, \"Platform not supported\");\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Mutex\n//\n// void lock();\n// void unlock();\n// bool tryLock();\n////////////////////////////////////////////////////////////////////////////////\n\n\n/**\n * This class represents a general purpose, recursive mutex.\n *\n * Implemented using `pthread_mutex` on Posix and `CRITICAL_SECTION`\n * on Windows.\n */\nclass Mutex :\n    Object.Monitor\n{\n    ////////////////////////////////////////////////////////////////////////////\n    // Initialization\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Initializes a mutex object.\n     *\n     */\n    this() @trusted nothrow @nogc\n    {\n        this(true);\n    }\n\n    /// ditto\n    this() shared @trusted nothrow @nogc\n    {\n        this(true);\n    }\n\n    // Undocumented, useful only in Mutex.this().\n    private this(this Q)(bool _unused_) @trusted nothrow @nogc\n        if (is(Q == Mutex) || is(Q == shared Mutex))\n    {\n        version (Windows)\n        {\n            InitializeCriticalSection(cast(CRITICAL_SECTION*) &m_hndl);\n        }\n        else version (Posix)\n        {\n            import core.internal.abort : abort;\n            pthread_mutexattr_t attr = void;\n\n            !pthread_mutexattr_init(&attr) ||\n                abort(\"Error: pthread_mutexattr_init failed.\");\n\n            scope (exit) !pthread_mutexattr_destroy(&attr) ||\n                abort(\"Error: pthread_mutexattr_destroy failed.\");\n\n            !pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) ||\n                abort(\"Error: pthread_mutexattr_settype failed.\");\n\n            !pthread_mutex_init(cast(pthread_mutex_t*) &m_hndl, &attr) ||\n                abort(\"Error: pthread_mutex_init failed.\");\n        }\n\n        m_proxy.link = this;\n        this.__monitor = cast(void*) &m_proxy;\n    }\n\n\n    /**\n     * Initializes a mutex object and sets it as the monitor for `obj`.\n     *\n     * In:\n     *  `obj` must not already have a monitor.\n     */\n    this(Object obj) @trusted nothrow @nogc\n    {\n        this(obj, true);\n    }\n\n    /// ditto\n    this(Object obj) shared @trusted nothrow @nogc\n    {\n        this(obj, true);\n    }\n\n    // Undocumented, useful only in Mutex.this(Object).\n    private this(this Q)(Object obj, bool _unused_) @trusted nothrow @nogc\n        if (is(Q == Mutex) || is(Q == shared Mutex))\n    in\n    {\n        assert(obj !is null,\n            \"The provided object must not be null.\");\n        assert(obj.__monitor is null,\n            \"The provided object has a monitor already set!\");\n    }\n    do\n    {\n        this();\n        obj.__monitor = cast(void*) &m_proxy;\n    }\n\n\n    ~this() @trusted nothrow @nogc\n    {\n        version (Windows)\n        {\n            DeleteCriticalSection(&m_hndl);\n        }\n        else version (Posix)\n        {\n            import core.internal.abort : abort;\n            !pthread_mutex_destroy(&m_hndl) ||\n                abort(\"Error: pthread_mutex_init failed.\");\n        }\n        this.__monitor = null;\n    }\n\n\n    ////////////////////////////////////////////////////////////////////////////\n    // General Actions\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * If this lock is not already held by the caller, the lock is acquired,\n     * then the internal counter is incremented by one.\n     *\n     * Note:\n     *    `Mutex.lock` does not throw, but a class derived from Mutex can throw.\n     *    Use `lock_nothrow` in `nothrow @nogc` code.\n     */\n    @trusted void lock()\n    {\n        lock_nothrow();\n    }\n\n    /// ditto\n    @trusted void lock() shared\n    {\n        lock_nothrow();\n    }\n\n    /// ditto\n    final void lock_nothrow(this Q)() nothrow @trusted @nogc\n        if (is(Q == Mutex) || is(Q == shared Mutex))\n    {\n        version (Windows)\n        {\n            EnterCriticalSection(&m_hndl);\n        }\n        else version (Posix)\n        {\n            if (pthread_mutex_lock(&m_hndl) == 0)\n                return;\n\n            SyncError syncErr = cast(SyncError) cast(void*) typeid(SyncError).initializer;\n            syncErr.msg = \"Unable to lock mutex.\";\n            throw syncErr;\n        }\n    }\n\n    /**\n     * Decrements the internal lock count by one.  If this brings the count to\n     * zero, the lock is released.\n     *\n     * Note:\n     *    `Mutex.unlock` does not throw, but a class derived from Mutex can throw.\n     *    Use `unlock_nothrow` in `nothrow @nogc` code.\n     */\n    @trusted void unlock()\n    {\n        unlock_nothrow();\n    }\n\n    /// ditto\n    @trusted void unlock() shared\n    {\n        unlock_nothrow();\n    }\n\n    /// ditto\n    final void unlock_nothrow(this Q)() nothrow @trusted @nogc\n        if (is(Q == Mutex) || is(Q == shared Mutex))\n    {\n        version (Windows)\n        {\n            LeaveCriticalSection(&m_hndl);\n        }\n        else version (Posix)\n        {\n            if (pthread_mutex_unlock(&m_hndl) == 0)\n                return;\n\n            SyncError syncErr = cast(SyncError) cast(void*) typeid(SyncError).initializer;\n            syncErr.msg = \"Unable to unlock mutex.\";\n            throw syncErr;\n        }\n    }\n\n    /**\n     * If the lock is held by another caller, the method returns.  Otherwise,\n     * the lock is acquired if it is not already held, and then the internal\n     * counter is incremented by one.\n     *\n     * Returns:\n     *  true if the lock was acquired and false if not.\n     *\n     * Note:\n     *    `Mutex.tryLock` does not throw, but a class derived from Mutex can throw.\n     *    Use `tryLock_nothrow` in `nothrow @nogc` code.\n     */\n    bool tryLock() @trusted\n    {\n        return tryLock_nothrow();\n    }\n\n    /// ditto\n    bool tryLock() shared @trusted\n    {\n        return tryLock_nothrow();\n    }\n\n    /// ditto\n    final bool tryLock_nothrow(this Q)() nothrow @trusted @nogc\n        if (is(Q == Mutex) || is(Q == shared Mutex))\n    {\n        version (Windows)\n        {\n            return TryEnterCriticalSection(&m_hndl) != 0;\n        }\n        else version (Posix)\n        {\n            return pthread_mutex_trylock(&m_hndl) == 0;\n        }\n    }\n\n\nprivate:\n    version (Windows)\n    {\n        CRITICAL_SECTION    m_hndl;\n    }\n    else version (Posix)\n    {\n        pthread_mutex_t     m_hndl;\n    }\n\n    struct MonitorProxy\n    {\n        Object.Monitor link;\n    }\n\n    MonitorProxy            m_proxy;\n\n\npackage:\n    version (Posix)\n    {\n        pthread_mutex_t* handleAddr()\n        {\n            return &m_hndl;\n        }\n    }\n}\n\n///\n/* @safe nothrow -> see druntime PR 1726 */\n// Test regular usage.\nunittest\n{\n    import core.thread : Thread;\n\n    class Resource\n    {\n        Mutex mtx;\n        int cargo;\n\n        this() shared @safe nothrow\n        {\n            mtx = new shared Mutex();\n            cargo = 42;\n        }\n\n        void useResource() shared @safe nothrow @nogc\n        {\n            mtx.lock_nothrow();\n            (cast() cargo) += 1;\n            mtx.unlock_nothrow();\n        }\n    }\n\n    shared Resource res = new shared Resource();\n\n    auto otherThread = new Thread(\n    {\n        foreach (i; 0 .. 10000)\n            res.useResource();\n    }).start();\n\n    foreach (i; 0 .. 10000)\n        res.useResource();\n\n    otherThread.join();\n\n    assert (res.cargo == 20042);\n}\n\n// Test @nogc usage.\n@system @nogc nothrow unittest\n{\n    import core.stdc.stdlib : malloc, free;\n\n    void* p = malloc(__traits(classInstanceSize, Mutex));\n\n    auto ti = typeid(Mutex);\n    p[0 .. ti.initializer.length] = ti.initializer[];\n\n    shared Mutex mtx = cast(shared(Mutex)) p;\n    mtx.__ctor();\n\n    mtx.lock_nothrow();\n\n    { // test recursive locking\n        mtx.tryLock_nothrow();\n        mtx.unlock_nothrow();\n    }\n\n    mtx.unlock_nothrow();\n\n    // In general destorying classes like this is not\n    // safe, but since we know that the only base class\n    // of Mutex is Object and it doesn't have a dtor\n    // we can simply call the non-virtual __dtor() here.\n\n    // Ok to cast away shared because destruction\n    // should happen only from a single thread.\n    (cast(Mutex) mtx).__dtor();\n\n    // Verify that the underlying implementation has been destroyed\n    // by checking that locking is not possible. This assumes\n    // that the underlying implementation is well behaved\n    // and makes the object non-lockable upon destruction.\n    // The Bionic and Musl C runtimes and DragonFly don't appear to do so, so skip this test.\n    version (CRuntime_Bionic) {} else\n    version (CRuntime_Musl) {} else\n    version (DragonFlyBSD) {} else\n    assert(!mtx.tryLock_nothrow());\n\n    free(cast(void*) mtx);\n}\n\n// Test single-thread (non-shared) use.\nunittest\n{\n    Mutex m = new Mutex();\n\n    m.lock();\n\n    m.tryLock();\n    m.unlock();\n\n    m.unlock();\n}\n\nunittest\n{\n    import core.thread;\n\n    auto mutex      = new Mutex;\n    int  numThreads = 10;\n    int  numTries   = 1000;\n    int  lockCount  = 0;\n\n    void testFn()\n    {\n        for (int i = 0; i < numTries; ++i)\n        {\n            synchronized (mutex)\n            {\n                ++lockCount;\n            }\n        }\n    }\n\n    auto group = new ThreadGroup;\n\n    for (int i = 0; i < numThreads; ++i)\n        group.create(&testFn);\n\n    group.joinAll();\n    assert(lockCount == numThreads * numTries);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sync/rwmutex.d",
    "content": "/**\n * The read/write mutex module provides a primitive for maintaining shared read\n * access and mutually exclusive write access.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/sync/_rwmutex.d)\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sync.rwmutex;\n\n\npublic import core.sync.exception;\nprivate import core.sync.condition;\nprivate import core.sync.mutex;\nprivate import core.memory;\n\nversion (Posix)\n{\n    private import core.sys.posix.pthread;\n}\n\n\n////////////////////////////////////////////////////////////////////////////////\n// ReadWriteMutex\n//\n// Reader reader();\n// Writer writer();\n////////////////////////////////////////////////////////////////////////////////\n\n\n/**\n * This class represents a mutex that allows any number of readers to enter,\n * but when a writer enters, all other readers and writers are blocked.\n *\n * Please note that this mutex is not recursive and is intended to guard access\n * to data only.  Also, no deadlock checking is in place because doing so would\n * require dynamic memory allocation, which would reduce performance by an\n * unacceptable amount.  As a result, any attempt to recursively acquire this\n * mutex may well deadlock the caller, particularly if a write lock is acquired\n * while holding a read lock, or vice-versa.  In practice, this should not be\n * an issue however, because it is uncommon to call deeply into unknown code\n * while holding a lock that simply protects data.\n */\nclass ReadWriteMutex\n{\n    /**\n     * Defines the policy used by this mutex.  Currently, two policies are\n     * defined.\n     *\n     * The first will queue writers until no readers hold the mutex, then\n     * pass the writers through one at a time.  If a reader acquires the mutex\n     * while there are still writers queued, the reader will take precedence.\n     *\n     * The second will queue readers if there are any writers queued.  Writers\n     * are passed through one at a time, and once there are no writers present,\n     * all queued readers will be alerted.\n     *\n     * Future policies may offer a more even balance between reader and writer\n     * precedence.\n     */\n    enum Policy\n    {\n        PREFER_READERS, /// Readers get preference.  This may starve writers.\n        PREFER_WRITERS  /// Writers get preference.  This may starve readers.\n    }\n\n\n    ////////////////////////////////////////////////////////////////////////////\n    // Initialization\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Initializes a read/write mutex object with the supplied policy.\n     *\n     * Params:\n     *  policy = The policy to use.\n     *\n     * Throws:\n     *  SyncError on error.\n     */\n    this( Policy policy = Policy.PREFER_WRITERS )\n    {\n        m_commonMutex = new Mutex;\n        if ( !m_commonMutex )\n            throw new SyncError( \"Unable to initialize mutex\" );\n\n        m_readerQueue = new Condition( m_commonMutex );\n        if ( !m_readerQueue )\n            throw new SyncError( \"Unable to initialize mutex\" );\n\n        m_writerQueue = new Condition( m_commonMutex );\n        if ( !m_writerQueue )\n            throw new SyncError( \"Unable to initialize mutex\" );\n\n        m_policy = policy;\n        m_reader = new Reader;\n        m_writer = new Writer;\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    // General Properties\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Gets the policy used by this mutex.\n     *\n     * Returns:\n     *  The policy used by this mutex.\n     */\n    @property Policy policy()\n    {\n        return m_policy;\n    }\n\n\n    ////////////////////////////////////////////////////////////////////////////\n    // Reader/Writer Handles\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Gets an object representing the reader lock for the associated mutex.\n     *\n     * Returns:\n     *  A reader sub-mutex.\n     */\n    @property Reader reader()\n    {\n        return m_reader;\n    }\n\n\n    /**\n     * Gets an object representing the writer lock for the associated mutex.\n     *\n     * Returns:\n     *  A writer sub-mutex.\n     */\n    @property Writer writer()\n    {\n        return m_writer;\n    }\n\n\n    ////////////////////////////////////////////////////////////////////////////\n    // Reader\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * This class can be considered a mutex in its own right, and is used to\n     * negotiate a read lock for the enclosing mutex.\n     */\n    class Reader :\n        Object.Monitor\n    {\n        /**\n         * Initializes a read/write mutex reader proxy object.\n         */\n        this()\n        {\n            m_proxy.link = this;\n            this.__monitor = &m_proxy;\n        }\n\n\n        /**\n         * Acquires a read lock on the enclosing mutex.\n         */\n        @trusted void lock()\n        {\n            synchronized( m_commonMutex )\n            {\n                ++m_numQueuedReaders;\n                scope(exit) --m_numQueuedReaders;\n\n                while ( shouldQueueReader )\n                    m_readerQueue.wait();\n                ++m_numActiveReaders;\n            }\n        }\n\n\n        /**\n         * Releases a read lock on the enclosing mutex.\n         */\n        @trusted void unlock()\n        {\n            synchronized( m_commonMutex )\n            {\n                if ( --m_numActiveReaders < 1 )\n                {\n                    if ( m_numQueuedWriters > 0 )\n                        m_writerQueue.notify();\n                }\n            }\n        }\n\n\n        /**\n         * Attempts to acquire a read lock on the enclosing mutex.  If one can\n         * be obtained without blocking, the lock is acquired and true is\n         * returned.  If not, the lock is not acquired and false is returned.\n         *\n         * Returns:\n         *  true if the lock was acquired and false if not.\n         */\n        bool tryLock()\n        {\n            synchronized( m_commonMutex )\n            {\n                if ( shouldQueueReader )\n                    return false;\n                ++m_numActiveReaders;\n                return true;\n            }\n        }\n\n\n    private:\n        @property bool shouldQueueReader()\n        {\n            if ( m_numActiveWriters > 0 )\n                return true;\n\n            switch ( m_policy )\n            {\n            case Policy.PREFER_WRITERS:\n                 return m_numQueuedWriters > 0;\n\n            case Policy.PREFER_READERS:\n            default:\n                 break;\n            }\n\n        return false;\n        }\n\n        struct MonitorProxy\n        {\n            Object.Monitor link;\n        }\n\n        MonitorProxy    m_proxy;\n    }\n\n\n    ////////////////////////////////////////////////////////////////////////////\n    // Writer\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * This class can be considered a mutex in its own right, and is used to\n     * negotiate a write lock for the enclosing mutex.\n     */\n    class Writer :\n        Object.Monitor\n    {\n        /**\n         * Initializes a read/write mutex writer proxy object.\n         */\n        this()\n        {\n            m_proxy.link = this;\n            this.__monitor = &m_proxy;\n        }\n\n\n        /**\n         * Acquires a write lock on the enclosing mutex.\n         */\n        @trusted void lock()\n        {\n            synchronized( m_commonMutex )\n            {\n                ++m_numQueuedWriters;\n                scope(exit) --m_numQueuedWriters;\n\n                while ( shouldQueueWriter )\n                    m_writerQueue.wait();\n                ++m_numActiveWriters;\n            }\n        }\n\n\n        /**\n         * Releases a write lock on the enclosing mutex.\n         */\n        @trusted void unlock()\n        {\n            synchronized( m_commonMutex )\n            {\n                if ( --m_numActiveWriters < 1 )\n                {\n                    switch ( m_policy )\n                    {\n                    default:\n                    case Policy.PREFER_READERS:\n                        if ( m_numQueuedReaders > 0 )\n                            m_readerQueue.notifyAll();\n                        else if ( m_numQueuedWriters > 0 )\n                            m_writerQueue.notify();\n                        break;\n                    case Policy.PREFER_WRITERS:\n                        if ( m_numQueuedWriters > 0 )\n                            m_writerQueue.notify();\n                        else if ( m_numQueuedReaders > 0 )\n                            m_readerQueue.notifyAll();\n                    }\n                }\n            }\n        }\n\n\n        /**\n         * Attempts to acquire a write lock on the enclosing mutex.  If one can\n         * be obtained without blocking, the lock is acquired and true is\n         * returned.  If not, the lock is not acquired and false is returned.\n         *\n         * Returns:\n         *  true if the lock was acquired and false if not.\n         */\n        bool tryLock()\n        {\n            synchronized( m_commonMutex )\n            {\n                if ( shouldQueueWriter )\n                    return false;\n                ++m_numActiveWriters;\n                return true;\n            }\n        }\n\n\n    private:\n        @property bool shouldQueueWriter()\n        {\n            if ( m_numActiveWriters > 0 ||\n                m_numActiveReaders > 0 )\n                return true;\n            switch ( m_policy )\n            {\n            case Policy.PREFER_READERS:\n                return m_numQueuedReaders > 0;\n\n            case Policy.PREFER_WRITERS:\n            default:\n                 break;\n            }\n\n        return false;\n        }\n\n        struct MonitorProxy\n        {\n            Object.Monitor link;\n        }\n\n        MonitorProxy    m_proxy;\n    }\n\n\nprivate:\n    Policy      m_policy;\n    Reader      m_reader;\n    Writer      m_writer;\n\n    Mutex       m_commonMutex;\n    Condition   m_readerQueue;\n    Condition   m_writerQueue;\n\n    int         m_numQueuedReaders;\n    int         m_numActiveReaders;\n    int         m_numQueuedWriters;\n    int         m_numActiveWriters;\n}\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Unit Tests\n////////////////////////////////////////////////////////////////////////////////\n\n\nunittest\n{\n    import core.atomic, core.thread, core.sync.semaphore;\n\n    static void runTest(ReadWriteMutex.Policy policy)\n    {\n        scope mutex = new ReadWriteMutex(policy);\n        scope rdSemA = new Semaphore, rdSemB = new Semaphore,\n              wrSemA = new Semaphore, wrSemB = new Semaphore;\n        shared size_t numReaders, numWriters;\n\n        void readerFn()\n        {\n            synchronized (mutex.reader)\n            {\n                atomicOp!\"+=\"(numReaders, 1);\n                rdSemA.notify();\n                rdSemB.wait();\n                atomicOp!\"-=\"(numReaders, 1);\n            }\n        }\n\n        void writerFn()\n        {\n            synchronized (mutex.writer)\n            {\n                atomicOp!\"+=\"(numWriters, 1);\n                wrSemA.notify();\n                wrSemB.wait();\n                atomicOp!\"-=\"(numWriters, 1);\n            }\n        }\n\n        void waitQueued(size_t queuedReaders, size_t queuedWriters)\n        {\n            for (;;)\n            {\n                synchronized (mutex.m_commonMutex)\n                {\n                    if (mutex.m_numQueuedReaders == queuedReaders &&\n                        mutex.m_numQueuedWriters == queuedWriters)\n                        break;\n                }\n                Thread.yield();\n            }\n        }\n\n        scope group = new ThreadGroup;\n\n        // 2 simultaneous readers\n        group.create(&readerFn); group.create(&readerFn);\n        rdSemA.wait(); rdSemA.wait();\n        assert(numReaders == 2);\n        rdSemB.notify(); rdSemB.notify();\n        group.joinAll();\n        assert(numReaders == 0);\n        foreach (t; group) group.remove(t);\n\n        // 1 writer at a time\n        group.create(&writerFn); group.create(&writerFn);\n        wrSemA.wait();\n        assert(!wrSemA.tryWait());\n        assert(numWriters == 1);\n        wrSemB.notify();\n        wrSemA.wait();\n        assert(numWriters == 1);\n        wrSemB.notify();\n        group.joinAll();\n        assert(numWriters == 0);\n        foreach (t; group) group.remove(t);\n\n        // reader and writer are mutually exclusive\n        group.create(&readerFn);\n        rdSemA.wait();\n        group.create(&writerFn);\n        waitQueued(0, 1);\n        assert(!wrSemA.tryWait());\n        assert(numReaders == 1 && numWriters == 0);\n        rdSemB.notify();\n        wrSemA.wait();\n        assert(numReaders == 0 && numWriters == 1);\n        wrSemB.notify();\n        group.joinAll();\n        assert(numReaders == 0 && numWriters == 0);\n        foreach (t; group) group.remove(t);\n\n        // writer and reader are mutually exclusive\n        group.create(&writerFn);\n        wrSemA.wait();\n        group.create(&readerFn);\n        waitQueued(1, 0);\n        assert(!rdSemA.tryWait());\n        assert(numReaders == 0 && numWriters == 1);\n        wrSemB.notify();\n        rdSemA.wait();\n        assert(numReaders == 1 && numWriters == 0);\n        rdSemB.notify();\n        group.joinAll();\n        assert(numReaders == 0 && numWriters == 0);\n        foreach (t; group) group.remove(t);\n\n        // policy determines whether queued reader or writers progress first\n        group.create(&writerFn);\n        wrSemA.wait();\n        group.create(&readerFn);\n        group.create(&writerFn);\n        waitQueued(1, 1);\n        assert(numReaders == 0 && numWriters == 1);\n        wrSemB.notify();\n\n        if (policy == ReadWriteMutex.Policy.PREFER_READERS)\n        {\n            rdSemA.wait();\n            assert(numReaders == 1 && numWriters == 0);\n            rdSemB.notify();\n            wrSemA.wait();\n            assert(numReaders == 0 && numWriters == 1);\n            wrSemB.notify();\n        }\n        else if (policy == ReadWriteMutex.Policy.PREFER_WRITERS)\n        {\n            wrSemA.wait();\n            assert(numReaders == 0 && numWriters == 1);\n            wrSemB.notify();\n            rdSemA.wait();\n            assert(numReaders == 1 && numWriters == 0);\n            rdSemB.notify();\n        }\n        group.joinAll();\n        assert(numReaders == 0 && numWriters == 0);\n        foreach (t; group) group.remove(t);\n    }\n    runTest(ReadWriteMutex.Policy.PREFER_READERS);\n    runTest(ReadWriteMutex.Policy.PREFER_WRITERS);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sync/semaphore.d",
    "content": "/**\n * The semaphore module provides a general use semaphore for synchronization.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Sean Kelly\n * Source:    $(DRUNTIMESRC core/sync/_semaphore.d)\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sync.semaphore;\n\n\npublic import core.sync.exception;\npublic import core.time;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Windows)\n{\n    private import core.sys.windows.windows;\n}\nelse version (Darwin)\n{\n    private import core.sync.config;\n    private import core.stdc.errno;\n    private import core.sys.posix.time;\n    private import core.sys.darwin.mach.semaphore;\n}\nelse version (Posix)\n{\n    private import core.sync.config;\n    private import core.stdc.errno;\n    private import core.sys.posix.pthread;\n    private import core.sys.posix.semaphore;\n}\nelse\n{\n    static assert(false, \"Platform not supported\");\n}\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Semaphore\n//\n// void wait();\n// void notify();\n// bool tryWait();\n////////////////////////////////////////////////////////////////////////////////\n\n\n/**\n * This class represents a general counting semaphore as concieved by Edsger\n * Dijkstra.  As per Mesa type monitors however, \"signal\" has been replaced\n * with \"notify\" to indicate that control is not transferred to the waiter when\n * a notification is sent.\n */\nclass Semaphore\n{\n    ////////////////////////////////////////////////////////////////////////////\n    // Initialization\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Initializes a semaphore object with the specified initial count.\n     *\n     * Params:\n     *  count = The initial count for the semaphore.\n     *\n     * Throws:\n     *  SyncError on error.\n     */\n    this( uint count = 0 )\n    {\n        version (Windows)\n        {\n            m_hndl = CreateSemaphoreA( null, count, int.max, null );\n            if ( m_hndl == m_hndl.init )\n                throw new SyncError( \"Unable to create semaphore\" );\n        }\n        else version (Darwin)\n        {\n            auto rc = semaphore_create( mach_task_self(), &m_hndl, SYNC_POLICY_FIFO, count );\n            if ( rc )\n                throw new SyncError( \"Unable to create semaphore\" );\n        }\n        else version (Posix)\n        {\n            int rc = sem_init( &m_hndl, 0, count );\n            if ( rc )\n                throw new SyncError( \"Unable to create semaphore\" );\n        }\n    }\n\n\n    ~this()\n    {\n        version (Windows)\n        {\n            BOOL rc = CloseHandle( m_hndl );\n            assert( rc, \"Unable to destroy semaphore\" );\n        }\n        else version (Darwin)\n        {\n            auto rc = semaphore_destroy( mach_task_self(), m_hndl );\n            assert( !rc, \"Unable to destroy semaphore\" );\n        }\n        else version (Posix)\n        {\n            int rc = sem_destroy( &m_hndl );\n            assert( !rc, \"Unable to destroy semaphore\" );\n        }\n    }\n\n\n    ////////////////////////////////////////////////////////////////////////////\n    // General Actions\n    ////////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Wait until the current count is above zero, then atomically decrement\n     * the count by one and return.\n     *\n     * Throws:\n     *  SyncError on error.\n     */\n    void wait()\n    {\n        version (Windows)\n        {\n            DWORD rc = WaitForSingleObject( m_hndl, INFINITE );\n            if ( rc != WAIT_OBJECT_0 )\n                throw new SyncError( \"Unable to wait for semaphore\" );\n        }\n        else version (Darwin)\n        {\n            while ( true )\n            {\n                auto rc = semaphore_wait( m_hndl );\n                if ( !rc )\n                    return;\n                if ( rc == KERN_ABORTED && errno == EINTR )\n                    continue;\n                throw new SyncError( \"Unable to wait for semaphore\" );\n            }\n        }\n        else version (Posix)\n        {\n            while ( true )\n            {\n                if ( !sem_wait( &m_hndl ) )\n                    return;\n                if ( errno != EINTR )\n                    throw new SyncError( \"Unable to wait for semaphore\" );\n            }\n        }\n    }\n\n\n    /**\n     * Suspends the calling thread until the current count moves above zero or\n     * until the supplied time period has elapsed.  If the count moves above\n     * zero in this interval, then atomically decrement the count by one and\n     * return true.  Otherwise, return false.\n     *\n     * Params:\n     *  period = The time to wait.\n     *\n     * In:\n     *  period must be non-negative.\n     *\n     * Throws:\n     *  SyncError on error.\n     *\n     * Returns:\n     *  true if notified before the timeout and false if not.\n     */\n    bool wait( Duration period )\n    in\n    {\n        assert( !period.isNegative );\n    }\n    do\n    {\n        version (Windows)\n        {\n            auto maxWaitMillis = dur!(\"msecs\")( uint.max - 1 );\n\n            while ( period > maxWaitMillis )\n            {\n                auto rc = WaitForSingleObject( m_hndl, cast(uint)\n                                                       maxWaitMillis.total!\"msecs\" );\n                switch ( rc )\n                {\n                case WAIT_OBJECT_0:\n                    return true;\n                case WAIT_TIMEOUT:\n                    period -= maxWaitMillis;\n                    continue;\n                default:\n                    throw new SyncError( \"Unable to wait for semaphore\" );\n                }\n            }\n            switch ( WaitForSingleObject( m_hndl, cast(uint) period.total!\"msecs\" ) )\n            {\n            case WAIT_OBJECT_0:\n                return true;\n            case WAIT_TIMEOUT:\n                return false;\n            default:\n                throw new SyncError( \"Unable to wait for semaphore\" );\n            }\n        }\n        else version (Darwin)\n        {\n            mach_timespec_t t = void;\n            (cast(byte*) &t)[0 .. t.sizeof] = 0;\n\n            if ( period.total!\"seconds\" > t.tv_sec.max )\n            {\n                t.tv_sec  = t.tv_sec.max;\n                t.tv_nsec = cast(typeof(t.tv_nsec)) period.split!(\"seconds\", \"nsecs\")().nsecs;\n            }\n            else\n                period.split!(\"seconds\", \"nsecs\")(t.tv_sec, t.tv_nsec);\n            while ( true )\n            {\n                auto rc = semaphore_timedwait( m_hndl, t );\n                if ( !rc )\n                    return true;\n                if ( rc == KERN_OPERATION_TIMED_OUT )\n                    return false;\n                if ( rc != KERN_ABORTED || errno != EINTR )\n                    throw new SyncError( \"Unable to wait for semaphore\" );\n            }\n        }\n        else version (Posix)\n        {\n            timespec t = void;\n            mktspec( t, period );\n\n            while ( true )\n            {\n                if ( !sem_timedwait( &m_hndl, &t ) )\n                    return true;\n                if ( errno == ETIMEDOUT )\n                    return false;\n                if ( errno != EINTR )\n                    throw new SyncError( \"Unable to wait for semaphore\" );\n            }\n        }\n    }\n\n\n    /**\n     * Atomically increment the current count by one.  This will notify one\n     * waiter, if there are any in the queue.\n     *\n     * Throws:\n     *  SyncError on error.\n     */\n    void notify()\n    {\n        version (Windows)\n        {\n            if ( !ReleaseSemaphore( m_hndl, 1, null ) )\n                throw new SyncError( \"Unable to notify semaphore\" );\n        }\n        else version (Darwin)\n        {\n            auto rc = semaphore_signal( m_hndl );\n            if ( rc )\n                throw new SyncError( \"Unable to notify semaphore\" );\n        }\n        else version (Posix)\n        {\n            int rc = sem_post( &m_hndl );\n            if ( rc )\n                throw new SyncError( \"Unable to notify semaphore\" );\n        }\n    }\n\n\n    /**\n     * If the current count is equal to zero, return.  Otherwise, atomically\n     * decrement the count by one and return true.\n     *\n     * Throws:\n     *  SyncError on error.\n     *\n     * Returns:\n     *  true if the count was above zero and false if not.\n     */\n    bool tryWait()\n    {\n        version (Windows)\n        {\n            switch ( WaitForSingleObject( m_hndl, 0 ) )\n            {\n            case WAIT_OBJECT_0:\n                return true;\n            case WAIT_TIMEOUT:\n                return false;\n            default:\n                throw new SyncError( \"Unable to wait for semaphore\" );\n            }\n        }\n        else version (Darwin)\n        {\n            return wait( dur!\"hnsecs\"(0) );\n        }\n        else version (Posix)\n        {\n            while ( true )\n            {\n                if ( !sem_trywait( &m_hndl ) )\n                    return true;\n                if ( errno == EAGAIN )\n                    return false;\n                if ( errno != EINTR )\n                    throw new SyncError( \"Unable to wait for semaphore\" );\n            }\n        }\n    }\n\n\nprotected:\n\n    /// Aliases the operating-system-specific semaphore type.\n    version (Windows)        alias Handle = HANDLE;\n    /// ditto\n    else version (Darwin)    alias Handle = semaphore_t;\n    /// ditto\n    else version (Posix)     alias Handle = sem_t;\n\n    /// Handle to the system-specific semaphore.\n    Handle m_hndl;\n}\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Unit Tests\n////////////////////////////////////////////////////////////////////////////////\n\n\nversion (unittest)\n{\n    import core.thread, core.atomic;\n\n    void testWait()\n    {\n        auto semaphore = new Semaphore;\n        shared bool stopConsumption = false;\n        immutable numToProduce = 20;\n        immutable numConsumers = 10;\n        shared size_t numConsumed;\n        shared size_t numComplete;\n\n        void consumer()\n        {\n            while (true)\n            {\n                semaphore.wait();\n\n                if (atomicLoad(stopConsumption))\n                    break;\n                atomicOp!\"+=\"(numConsumed, 1);\n            }\n            atomicOp!\"+=\"(numComplete, 1);\n        }\n\n        void producer()\n        {\n            assert(!semaphore.tryWait());\n\n            foreach (_; 0 .. numToProduce)\n                semaphore.notify();\n\n            // wait until all items are consumed\n            while (atomicLoad(numConsumed) != numToProduce)\n                Thread.yield();\n\n            // mark consumption as finished\n            atomicStore(stopConsumption, true);\n\n            // wake all consumers\n            foreach (_; 0 .. numConsumers)\n                semaphore.notify();\n\n            // wait until all consumers completed\n            while (atomicLoad(numComplete) != numConsumers)\n                Thread.yield();\n\n            assert(!semaphore.tryWait());\n            semaphore.notify();\n            assert(semaphore.tryWait());\n            assert(!semaphore.tryWait());\n        }\n\n        auto group = new ThreadGroup;\n\n        for ( int i = 0; i < numConsumers; ++i )\n            group.create(&consumer);\n        group.create(&producer);\n        group.joinAll();\n    }\n\n\n    void testWaitTimeout()\n    {\n        auto sem = new Semaphore;\n        shared bool semReady;\n        bool alertedOne, alertedTwo;\n\n        void waiter()\n        {\n            while (!atomicLoad(semReady))\n                Thread.yield();\n            alertedOne = sem.wait(dur!\"msecs\"(1));\n            alertedTwo = sem.wait(dur!\"msecs\"(1));\n            assert(alertedOne && !alertedTwo);\n        }\n\n        auto thread = new Thread(&waiter);\n        thread.start();\n\n        sem.notify();\n        atomicStore(semReady, true);\n        thread.join();\n        assert(alertedOne && !alertedTwo);\n    }\n\n\n    unittest\n    {\n        testWait();\n        testWaitTimeout();\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/bionic/fcntl.d",
    "content": "module core.sys.bionic.fcntl;\n\nversion (CRuntime_Bionic) extern(C) nothrow @nogc:\n\nenum LOCK_EX = 2;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/bionic/unistd.d",
    "content": "module core.sys.bionic.unistd;\n\nversion (CRuntime_Bionic) extern(C) nothrow @nogc:\n\nint flock(int, int) @trusted;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/dlfcn.d",
    "content": "/**\n * D header file for Darwin.\n *\n * $(LINK2 https://opensource.apple.com/source/dyld/dyld-360.22/include/dlfcn.h, Apple dyld/dlfcn.h)\n *\n * Copyright: Copyright David Nadlinger 2016.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   David Nadlinger\n */\nmodule core.sys.darwin.dlfcn;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern(C):\nnothrow:\n@nogc:\n\npublic import core.sys.posix.dlfcn;\n\nstruct Dl_info\n{\n    const(char)* dli_fname;\n    void*        dli_fbase;\n    const(char)* dli_sname;\n    void*        dli_saddr;\n}\n\nint dladdr(in void* addr, Dl_info* info);\n\nenum RTLD_NOLOAD = 0x10;\nenum RTLD_NODELETE = 0x80;\nenum RTLD_FIRST = 0x100;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/execinfo.d",
    "content": "/**\n * D header file for Darwin.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Martin Nowak\n */\nmodule core.sys.darwin.execinfo;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern (C):\nnothrow:\n@nogc:\n\nint backtrace(void** buffer, int size);\nchar** backtrace_symbols(const(void*)* buffer, int size);\nvoid backtrace_symbols_fd(const(void*)* buffer, int size, int fd);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/mach/dyld.d",
    "content": "/**\n * Copyright: Copyright Digital Mars 2010.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Jacob Carlborg\n * Version: Initial created: Feb 20, 2010\n */\n\n/*          Copyright Digital Mars 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.darwin.mach.dyld;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern (C):\nnothrow:\n@nogc:\n\npublic import core.stdc.stdint; // for intptr_t\npublic import core.sys.darwin.mach.loader;\n\nuint         _dyld_image_count();\nconst(char)* _dyld_get_image_name(uint image_index);\nmach_header* _dyld_get_image_header(uint image_index);\nvoid         _dyld_register_func_for_add_image(void function(in mach_header* mh, intptr_t vmaddr_slide));\nvoid         _dyld_register_func_for_remove_image(void function(in mach_header* mh, intptr_t vmaddr_slide));\n\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/mach/getsect.d",
    "content": "/**\n * D header file for $(LINK2 https://opensource.apple.com/source/cctools/cctools-895/include/mach-o/getsect.h.auto.html, mach-o/getsect.h).\n *\n * Copyright: Copyright Digital Mars 2010-2018.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Jacob Carlborg\n * Version: Initial created: Mar 16, 2010\n * Source: $(DRUNTIMESRC core/sys/darwin/mach/_getsect.d)\n */\nmodule core.sys.darwin.mach.getsect;\n\nextern (C):\nnothrow:\n@nogc:\n\nversion (CoreDdoc)\n{\n    import core.stdc.config : c_ulong;\n\n    /**\n     * In reality this will be $(REF mach_header, core, sys, darwin, mach, loader)\n     * on 32-bit platforms and $(REF mach_header_64, core, sys, darwin, mach, loader)\n     * 64-bit platforms.\n     */\n    struct MachHeader;\n\n    /**\n     * In reality this will be $(REF segment_command, core, sys, darwin, mach, loader)\n     * on 32-bit platforms and $(REF segment_command_64, core, sys, darwin, mach, loader)\n     * 64-bit platforms.\n     */\n    struct SegmentCommand;\n\n    /**\n     * In reality this will be $(REF section, core, sys, darwin, mach, loader)\n     * on 32-bit platforms and $(REF section_64, core, sys, darwin, mach, loader)\n     * 64-bit platforms.\n     */\n    struct Section;\n\n    /**\n     * Returns the section data of section with the given section name.\n     *\n     * Returns the section data of the given section in the given segment in the\n     * mach executable it is linked into.\n     *\n     * ___\n     * void main()\n     * {\n     *      import core.sys.darwin.mach.getsect;\n     *      int size;\n     *      assert(getsectdata(\"__TEXT\", \"__text\", &size));\n     *      assert(size > 0);\n     * }\n     * ___\n     *\n     * Params:\n     *  segname = the name of the segment\n     *  sectname = the name of the section\n     *  size = this will be set to the size of the section or 0 if the section\n     *      doesn't exist\n     *\n     * Returns: a pointer to the section data or `null` if it doesn't exist\n     */\n    char* getsectdata(\n        in char* segname,\n        in char* sectname,\n        c_ulong *size\n    );\n\n    /**\n     * Returns the section data of section with the given section name.\n     *\n     * Returns the section data of the given section in the given segment in the\n     * given framework.\n     *\n     * ___\n     * void main()\n     * {\n     *      import core.sys.darwin.mach.getsect;\n     *      int size;\n     *      assert(getsectdatafromFramework(\"Foundation\", \"__TEXT\", \"__text\", &size));\n     *      assert(size > 0);\n     * }\n     * ___\n     *\n     * Params:\n     *  FrameworkName = the name of the framework to get the section data from\n     *  segname = the name of the segment\n     *  sectname = the name of the section\n     *  size = this will be set to the size of the section or 0 if the section\n     *      doesn't exist\n     *\n     * Returns: a pointer to the section data or `null` if it doesn't exist\n     */\n    char* getsectdatafromFramework(\n        in char* FrameworkName,\n        in char* segname,\n        in char* sectname,\n        c_ulong* size\n    );\n\n    ///\n    c_ulong get_end();\n\n    ///\n    c_ulong get_etext();\n\n    ///\n    c_ulong get_edata();\n\n    /**\n     * Returns the section with the given section name.\n     *\n     * Returns the section structure of the given section in the given segment\n     * in the mach executable it is linked into.\n     *\n     * ___\n     * void main()\n     * {\n     *      import core.sys.darwin.mach.getsect;\n     *      assert(getsectbyname(\"__TEXT\", \"__text\"));\n     * }\n     * ___\n     *\n     * Params:\n     *  segname = the name of the segment\n     *  sectname = the name of the section\n     *\n     * Returns: a pointer to the section structure or `null` if it doesn't exist\n     */\n    const(Section)* getsectbyname(\n        in char* segname,\n        in char* sectname\n    );\n\n    /**\n     * Returns the section data of section with the given section name.\n     *\n     * Returns the section data of the given section in the given segment in the\n     * image pointed to by the given mach header.\n     *\n     * ___\n     * void main()\n     * {\n     *      import core.sys.darwin.mach.getsect;\n     *      import core.sys.darwin.crt_externs;\n     *\n     *      auto mph = _NSGetMachExecuteHeader();\n     *      int size;\n     *      assert(getsectdata(mph, \"__TEXT\", \"__text\", &size));\n     *      assert(size > 0);\n     * }\n     * ___\n     *\n     * Params:\n     *  mhp = the mach header to get the section data from\n     *  segname = the name of the segment\n     *  sectname = the name of the section\n     *  size = this will be set to the size of the section or 0 if the section\n     *      doesn't exist\n     *\n     * Returns: a pointer to the section data or `null` if it doesn't exist\n     */\n    ubyte* getsectiondata(\n        in MachHeader* mhp,\n        in char* segname,\n        in char* sectname,\n        c_ulong* size\n    );\n\n    /**\n     * Returns the segment with the given segment name.\n     *\n     * Returns the segment structure of the given segment in the mach executable\n     * it is linked into.\n     *\n     * ___\n     * void main()\n     * {\n     *      import core.sys.darwin.mach.getsect;\n     *      assert(getsegbyname(\"__TEXT\"));\n     * }\n     * ___\n     *\n     * Params:\n     *  segname = the name of the segment\n     *\n     * Returns: a pointer to the section structure or `null` if it doesn't exist\n     */\n    const(SegmentCommand)* getsegbyname(\n        in char* segname\n    );\n\n    /**\n     * Returns the segment data of segment with the given segment name.\n     *\n     * Returns the segment data of the given segment in the image pointed to by\n     * the given mach header.\n     *\n     * ___\n     * void main()\n     * {\n     *      import core.sys.darwin.mach.getsect;\n     *      import core.sys.darwin.crt_externs;\n     *\n     *      auto mph = _NSGetMachExecuteHeader();\n     *      int size;\n     *      assert(getsegmentdata(mph, \"__TEXT\", &size));\n     *      assert(size > 0);\n     * }\n     * ___\n     *\n     * Params:\n     *  mhp = the mach header to get the section data from\n     *  segname = the name of the segment\n     *  size = this will be set to the size of the section or 0 if the section\n     *      doesn't exist\n     *\n     * Returns: a pointer to the section data or `null` if it doesn't exist\n     */\n    ubyte* getsegmentdata(\n        in MachHeader* mhp,\n        in char* segname,\n        c_ulong* size\n    );\n\n    struct mach_header;\n    struct mach_header_64;\n    struct section;\n    struct section_64;\n\n    /**\n     * Returns the section data of section with the given section name.\n     *\n     * Returns the section data of the given section in the given segment in the\n     * image pointed to by the given mach header.\n     *\n     * ___\n     * void main()\n     * {\n     *      import core.sys.darwin.mach.getsect;\n     *      import core.sys.darwin.crt_externs;\n     *\n     *      auto mph = _NSGetMachExecuteHeader();\n     *      int size;\n     *      assert(getsectdatafromheader(mph, \"__TEXT\", \"__text\", &size));\n     *      assert(size > 0);\n     * }\n     * ___\n     *\n     * Params:\n     *  mhp = the mach header to get the section data from\n     *  segname = the name of the segment\n     *  sectname = the name of the section\n     *  size = this will be set to the size of the section or 0 if the section\n     *      doesn't exist\n     *\n     * Returns: a pointer to the section data or `null` if it doesn't exist\n     */\n    ubyte* getsectdatafromheader(\n        in mach_header* mhp,\n        in char* segname,\n        in char* sectname,\n        c_ulong* size\n    );\n\n    /// ditto\n    ubyte* getsectdatafromheader_64(\n        in mach_header_64* mhp,\n        in char* segname,\n        in char* sectname,\n        c_ulong* size\n    );\n\n\n    /**\n     * Returns the section with the given section name.\n     *\n     * Returns the section structure of the given section in the given segment\n     * in image pointed to by the given mach header.\n     *\n     * ___\n     * void main()\n     * {\n     *      import core.sys.darwin.mach.getsect;\n     *      import core.sys.darwin.crt_externs;\n     *\n     *      auto mph = _NSGetMachExecuteHeader();\n     *      assert(getsectbynamefromheader(mph, \"__TEXT\", \"__text\"));\n     * }\n     * ___\n     *\n     * Params:\n     *  mhp = the mach header to get the section from\n     *  segname = the name of the segment\n     *  sectname = the name of the section\n     *\n     * Returns: a pointer to the section structure or `null` if it doesn't exist\n     */\n    const(section)* getsectbynamefromheader(\n        in mach_header* mhp,\n        in char* segname,\n        in char* sectname\n    );\n\n    /// ditto\n    const(section_64)* getsectbynamefromheader_64(\n        in mach_header_64* mhp,\n        in char* segname,\n        in char* sectname\n    );\n\n    /**\n     * Returns the section with the given section name.\n     *\n     * Returns the section structure of the given section in the given segment\n     * in image pointed to by the given mach header.\n     *\n     * Params:\n     *  mhp = the mach header to get the section from\n     *  segname = the name of the segment\n     *  sectname = the name of the section\n     *  fSwap = ?\n     *\n     * Returns: a pointer to the section structure or `null` if it doesn't exist\n     */\n    const(section)* getsectbynamefromheaderwithswap(\n        in mach_header* mhp,\n        in char* segname,\n        in char* section,\n        int fSwap\n    );\n\n    /// ditto\n    const(section)* getsectbynamefromheaderwithswap_64(\n        in mach_header_64* mhp,\n        in char* segname,\n        in char* section,\n        int fSwap\n    );\n}\n\nelse version (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\n\npublic import core.sys.darwin.mach.loader;\n\nimport core.stdc.config : c_ulong;\n\nchar* getsectdata(\n    in char* segname,\n    in char* sectname,\n    c_ulong *size\n);\n\nchar* getsectdatafromFramework(\n    in char* FrameworkName,\n    in char* segname,\n    in char* sectname,\n    c_ulong* size\n);\n\nc_ulong get_end();\nc_ulong get_etext();\nc_ulong get_edata();\n\n// Runtime interfaces for 64-bit Mach-O programs.\nversion (D_LP64)\n{\n    const(section_64)* getsectbyname(\n        in char* segname,\n        in char* sectname\n    );\n\n    ubyte* getsectiondata(\n        in mach_header_64* mhp,\n        in char* segname,\n        in char* sectname,\n        c_ulong* size\n    );\n\n    const(segment_command_64)* getsegbyname(\n        in char* segname\n    );\n\n    ubyte* getsegmentdata(\n        in mach_header_64* mhp,\n        in char* segname,\n        c_ulong* size\n    );\n}\n\n// Runtime interfaces for 32-bit Mach-O programs.\nelse\n{\n    const(section)* getsectbyname(\n        in char* segname,\n        in char* sectname\n    );\n\n    ubyte* getsectiondata(\n        in mach_header* mhp,\n        in char* segname,\n        in char* sectname,\n        c_ulong* size\n    );\n\n    const(segment_command)* getsegbyname(\n        in char* segname\n    );\n\n    ubyte* getsegmentdata(\n        in mach_header* mhp,\n        in char* segname,\n        c_ulong* size\n    );\n}\n\n// Interfaces for tools working with 32-bit Mach-O files.\n\nubyte* getsectdatafromheader(\n    in mach_header* mhp,\n    in char* segname,\n    in char* sectname,\n    c_ulong* size\n);\n\nconst(section)* getsectbynamefromheader(\n    in mach_header* mhp,\n    in char* segname,\n    in char* sectname\n);\n\nconst(section)* getsectbynamefromheaderwithswap(\n    in mach_header* mhp,\n    in char* segname,\n    in char* section,\n    int fSwap\n);\n\n// Interfaces for tools working with 64-bit Mach-O files.\n\nubyte* getsectdatafromheader_64(\n    in mach_header_64* mhp,\n    in char* segname,\n    in char* sectname,\n    c_ulong* size\n);\n\nconst(section_64)* getsectbynamefromheader_64(\n    in mach_header_64* mhp,\n    in char* segname,\n    in char* sectname\n);\n\nconst(section)* getsectbynamefromheaderwithswap_64(\n    in mach_header_64* mhp,\n    in char* segname,\n    in char* section,\n    int fSwap\n);\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/mach/kern_return.d",
    "content": "/**\n * D header file for Darwin.\n *\n * Copyright: Copyright Sean Kelly 2008 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n */\n\n/*          Copyright Sean Kelly 2008 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.darwin.mach.kern_return;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern (C):\n\nalias int kern_return_t;\n\nenum : kern_return_t\n{\n    KERN_SUCCESS                = 0,\n    KERN_INVALID_ADDRESS        = 1,\n    KERN_PROTECTION_FAILURE     = 2,\n    KERN_NO_SPACE               = 3,\n    KERN_INVALID_ARGUMENT       = 4,\n    KERN_FAILURE                = 5,\n    KERN_RESOURCE_SHORTAGE      = 6,\n    KERN_NOT_RECEIVER           = 7,\n    KERN_NO_ACCESS              = 8,\n    KERN_MEMORY_FAILURE         = 9,\n    KERN_MEMORY_ERROR           = 10,\n    KERN_ALREADY_IN_SET         = 11,\n    KERN_NOT_IN_SET             = 12,\n    KERN_NAME_EXISTS            = 13,\n    KERN_ABORTED                = 14,\n    KERN_INVALID_NAME           = 15,\n    KERN_INVALID_TASK           = 16,\n    KERN_INVALID_RIGHT          = 17,\n    KERN_INVALID_VALUE          = 18,\n    KERN_UREFS_OVERFLOW         = 19,\n    KERN_INVALID_CAPABILITY     = 20,\n    KERN_RIGHT_EXISTS           = 21,\n    KERN_INVALID_HOST           = 22,\n    KERN_MEMORY_PRESENT         = 23,\n    KERN_MEMORY_DATA_MOVED      = 24,\n    KERN_MEMORY_RESTART_COPY    = 25,\n    KERN_INVALID_PROCESSOR_SET  = 26,\n    KERN_POLICY_LIMIT           = 27,\n    KERN_INVALID_POLICY         = 28,\n    KERN_INVALID_OBJECT         = 29,\n    KERN_ALREADY_WAITING        = 30,\n    KERN_DEFAULT_SET            = 31,\n    KERN_EXCEPTION_PROTECTED    = 32,\n    KERN_INVALID_LEDGER         = 33,\n    KERN_INVALID_MEMORY_CONTROL = 34,\n    KERN_INVALID_SECURITY       = 35,\n    KERN_NOT_DEPRESSED          = 36,\n    KERN_TERMINATED             = 37,\n    KERN_LOCK_SET_DESTROYED     = 38,\n    KERN_LOCK_UNSTABLE          = 39,\n    KERN_LOCK_OWNED             = 40,\n    KERN_LOCK_OWNED_SELF        = 41,\n    KERN_SEMAPHORE_DESTROYED    = 42,\n    KERN_RPC_SERVER_TERMINATED  = 43,\n    KERN_RPC_TERMINATE_ORPHAN   = 44,\n    KERN_RPC_CONTINUE_ORPHAN    = 45,\n    KERN_NOT_SUPPORTED          = 46,\n    KERN_NODE_DOWN              = 47,\n    KERN_OPERATION_TIMED_OUT    = 49,\n    KERN_RETURN_MAX             = 0x100,\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/mach/loader.d",
    "content": "/**\n * Copyright: Copyright Digital Mars 2010-2018.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Jacob Carlborg\n * Version: Initial created: Feb 20, 2010-2018\n * Source: $(DRUNTIMESRC core/sys/darwin/mach/_loade.d)\n */\nmodule core.sys.darwin.mach.loader;\n\nversion (CoreDdoc)\n{\n    /// Represents the header of a Mach-O file for 32-bit architecture.\n    struct mach_header\n    {\n        /// The mach magic number identifier.\n        uint magic;\n\n        /// CPU specifier.\n        int cputype;\n\n        /// Machine specifier.\n        int cpusubtype;\n\n        /// The type of the file.\n        uint filetype;\n\n        /// Number of load commands.\n        uint ncmds;\n\n        /// The size of all the load commands.\n        uint sizeofcmds;\n\n        /// Flags.\n        uint flags;\n    }\n\n    /// Represents the header of a Mach-O file for 64-bit architecture.\n    struct mach_header_64\n    {\n        /// The mach magic number identifier.\n        uint magic;\n\n        /// CPU specifier.\n        int cputype;\n\n        /// Machine specifier.\n        int cpusubtype;\n\n        /// The type of the file.\n        uint filetype;\n\n        /// Number of load commands.\n        uint ncmds;\n\n        /// The size of all the load commands.\n        uint sizeofcmds;\n\n        /// Flags.\n        uint flags;\n\n        /// Reserved.\n        uint reserved;\n    }\n\n    ///\n    enum MH_MAGIC : uint;\n\n    ///\n    enum MH_CIGAM : uint;\n\n    ///\n    enum MH_MAGIC_64 : uint;\n\n    ///\n    enum MH_CIGAM_64 : uint;\n\n    ///\n    enum SEG_PAGEZERO : string;\n\n    ///\n    enum SEG_TEXT : string;\n\n    ///\n    enum SECT_TEXT : string;\n\n    ///\n    enum SECT_FVMLIB_INIT0 : string;\n\n    ///\n    enum SECT_FVMLIB_INIT1 : string;\n\n    ///\n    enum SEG_DATA : string;\n\n    ///\n    enum SECT_DATA : string;\n\n    ///\n    enum SECT_BSS : string;\n\n    ///\n    enum SECT_COMMON : string;\n\n    ///\n    enum SEG_OBJC : string;\n\n    ///\n    enum SECT_OBJC_SYMBOLS : string;\n\n    ///\n    enum SECT_OBJC_MODULES : string;\n\n    ///\n    enum SECT_OBJC_STRINGS : string;\n\n    ///\n    enum SECT_OBJC_REFS : string;\n\n    ///\n    enum SEG_ICON : string;\n\n    ///\n    enum SECT_ICON_HEADER : string;\n\n    ///\n    enum SECT_ICON_TIFF : string;\n\n    ///\n    enum SEG_LINKEDIT : string;\n\n    ///\n    enum SEG_UNIXSTACK : string;\n\n    ///\n    enum SEG_IMPORT : string;\n\n    /// Represents a segment command in a Mach-O file for 32-bit architecture.\n    struct segment_command\n    {\n        /// Type of load command, i.e. `LC_SEGMENT`.\n        uint cmd;\n\n        /// The size of this segment, includes size of section structs.\n        uint cmdsize;\n\n        /// The name of this segment.\n        char[16] segname;\n\n        /// Memory address of this segment.\n        uint vmaddr;\n\n        /// Memory size of this segment.\n        uint vmsize;\n\n        /// File offset of this segment.\n        uint fileoff;\n\n        /// Amount to map from the file.\n        uint filesize;\n\n        /// Maximum VM protection.\n        int maxprot;\n\n        /// Initial VM protection.\n        int initprot;\n\n        /// Number of sections in this segment.\n        uint nsects;\n\n        /// Flags.\n        uint flags;\n    }\n\n    /// Represents a segment command in a Mach-O file for 64-bit architecture.\n    struct segment_command_64\n    {\n        /// Type of load command, i.e. `LC_SEGMENT`.\n        uint cmd;\n\n        /// The size of this segment, includes size of section structs.\n        uint cmdsize;\n\n        /// The name of this segment.\n        char[16] segname;\n\n        /// Memory address of this segment.\n        long vmaddr;\n\n        /// Memory size of this segment.\n        long vmsize;\n\n        /// File offset of this segment.\n        long fileoff;\n\n        /// Amount to map from the file.\n        long filesize;\n\n        /// Maximum VM protection.\n        int maxprot;\n\n        /// Initial VM protection.\n        int initprot;\n\n        /// Number of sections in this segment.\n        uint nsects;\n\n        /// Flags.\n        uint flags;\n    }\n\n    /// Represents a section in a Mach-O file for 32-bit architecture.\n    struct section\n    {\n        /// The name of this this section.\n        char[16] sectname;\n\n        /// The name of the segment this section belongs to.\n        char[16] segname;\n\n        /// The memory address of this section.\n        uint addr;\n\n        /// The size of this section in bytes.\n        uint size;\n\n        /// The file offset of this section.\n        uint offset;\n\n        /// The alignment (power of two) of this section.\n        uint align_;\n\n        /// The file offset of the relocation entries.\n        uint reloff;\n\n        /// The number of relocation entries.\n        uint nreloc;\n\n        /// Flags, section type and attributes.\n        uint flags;\n\n        /// Reserved.\n        uint reserved1;\n\n        /// Reserved.\n        uint reserved2;\n    }\n\n    /// Represents a section in a Mach-O file for 64-bit architecture.\n    struct section_64\n    {\n        /// The name of this this section.\n        char[16] sectname;\n\n        /// The name of the segment this section belongs to.\n        char[16] segname;\n\n        /// The memory address of this section.\n        ulong addr;\n\n        /// The size of this section in bytes.\n        ulong size;\n\n        /// The file offset of this section.\n        uint offset;\n\n        /// The alignment (power of two) of this section.\n        uint align_;\n\n        /// The file offset of the relocation entries.\n        uint reloff;\n\n        /// The number of relocation entries.\n        uint nreloc;\n\n        /// Flags, section type and attributes.\n        uint flags;\n\n        /// Reserved.\n        uint reserved1;\n\n        /// Reserved.\n        uint reserved2;\n\n        /// Reserved.\n        uint reserved3;\n    }\n}\n\nelse version (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern (C):\n\nstruct mach_header\n{\n    uint magic;\n    int  cputype;\n    int  cpusubtype;\n    uint filetype;\n    uint ncmds;\n    uint sizeofcmds;\n    uint flags;\n}\n\nstruct mach_header_64\n{\n    uint magic;\n    int  cputype;\n    int  cpusubtype;\n    uint filetype;\n    uint ncmds;\n    uint sizeofcmds;\n    uint flags;\n    uint reserved;\n}\n\nenum uint MH_MAGIC      = 0xfeedface;\nenum uint MH_CIGAM      = 0xcefaedfe;\nenum uint MH_MAGIC_64   = 0xfeedfacf;\nenum uint MH_CIGAM_64   = 0xcffaedfe;\n\nenum SEG_PAGEZERO       = \"__PAGEZERO\";\nenum SEG_TEXT           = \"__TEXT\";\nenum SECT_TEXT          = \"__text\";\nenum SECT_FVMLIB_INIT0  = \"__fvmlib_init0\";\nenum SECT_FVMLIB_INIT1  = \"__fvmlib_init1\";\nenum SEG_DATA           = \"__DATA\";\nenum SECT_DATA          = \"__data\";\nenum SECT_BSS           = \"__bss\";\nenum SECT_COMMON        = \"__common\";\nenum SEG_OBJC           = \"__OBJC\";\nenum SECT_OBJC_SYMBOLS  = \"__symbol_table\";\nenum SECT_OBJC_MODULES  = \"__module_info\";\nenum SECT_OBJC_STRINGS  = \"__selector_strs\";\nenum SECT_OBJC_REFS     = \"__selector_refs\";\nenum SEG_ICON           = \"__ICON\";\nenum SECT_ICON_HEADER   = \"__header\";\nenum SECT_ICON_TIFF     = \"__tiff\";\nenum SEG_LINKEDIT       = \"__LINKEDIT\";\nenum SEG_UNIXSTACK      = \"__UNIXSTACK\";\nenum SEG_IMPORT         = \"__IMPORT\";\n\nstruct segment_command\n{\n    uint cmd;\n    uint cmdsize;\n    char[16] segname;\n    uint vmaddr;\n    uint vmsize;\n    uint fileoff;\n    uint filesize;\n    int maxprot;\n    int initprot;\n    uint nsects;\n    uint flags;\n}\n\nstruct segment_command_64\n{\n    uint cmd;\n    uint cmdsize;\n    char[16] segname;\n    long vmaddr;\n    long vmsize;\n    long fileoff;\n    long filesize;\n    int maxprot;\n    int initprot;\n    uint nsects;\n    uint flags;\n}\n\nstruct section\n{\n    char[16] sectname;\n    char[16] segname;\n    uint     addr;\n    uint     size;\n    uint     offset;\n    uint     align_;\n    uint     reloff;\n    uint     nreloc;\n    uint     flags;\n    uint     reserved1;\n    uint     reserved2;\n}\n\nstruct section_64\n{\n    char[16] sectname;\n    char[16] segname;\n    ulong    addr;\n    ulong    size;\n    uint     offset;\n    uint     align_;\n    uint     reloff;\n    uint     nreloc;\n    uint     flags;\n    uint     reserved1;\n    uint     reserved2;\n    uint     reserved3;\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/mach/port.d",
    "content": "/**\n * D header file for Darwin.\n *\n * Copyright: Copyright Sean Kelly 2008 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n */\n\n/*          Copyright Sean Kelly 2008 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.darwin.mach.port;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern (C):\n\nversion (X86)\n    version = i386;\nversion (X86_64)\n    version = i386;\nversion (i386)\n{\n    alias uint        natural_t;\n    alias natural_t   mach_port_t;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/mach/semaphore.d",
    "content": "/**\n * D header file for Darwin.\n *\n * Copyright: Copyright Sean Kelly 2008 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n */\n\n/*          Copyright Sean Kelly 2008 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.darwin.mach.semaphore;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern (C):\nnothrow:\n@nogc:\n\npublic import core.sys.darwin.mach.kern_return;\npublic import core.sys.darwin.mach.port;\n\nalias mach_port_t   task_t;\nalias mach_port_t   thread_t;\nalias mach_port_t   semaphore_t;\nalias int           sync_policy_t;\n\nalias int clock_res_t;\nstruct mach_timespec_t\n{\n        uint        tv_sec;\n        clock_res_t     tv_nsec;\n}\n\nenum\n{\n    SYNC_POLICY_FIFO            = 0x0,\n    SYNC_POLICY_FIXED_PRIORITY  = 0x1,\n    SYNC_POLICY_REVERSED        = 0x2,\n    SYNC_POLICY_ORDER_MASK      = 0x3,\n    SYNC_POLICY_LIFO            = (SYNC_POLICY_FIFO | SYNC_POLICY_REVERSED),\n    SYNC_POLICY_MAX                         = 0x7,\n}\n\ntask_t        mach_task_self();\nkern_return_t semaphore_create(task_t, semaphore_t*, int, int);\nkern_return_t semaphore_destroy(task_t, semaphore_t);\n\nkern_return_t semaphore_signal(semaphore_t);\nkern_return_t semaphore_signal_all(semaphore_t);\nkern_return_t semaphore_signal_thread(semaphore_t, thread_t);\n\nkern_return_t semaphore_wait(semaphore_t);\nkern_return_t semaphore_wait_signal(semaphore_t, semaphore_t);\n\nkern_return_t semaphore_timedwait(semaphore_t, mach_timespec_t);\nkern_return_t semaphore_timedwait_signal(semaphore_t, semaphore_t, mach_timespec_t);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/mach/thread_act.d",
    "content": "/**\n * D header file for Darwin.\n *\n * Copyright: Copyright Sean Kelly 2008 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n */\n\n/*          Copyright Sean Kelly 2008 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.darwin.mach.thread_act;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern (C):\nnothrow:\n@nogc:\n\npublic import core.sys.darwin.mach.kern_return;\npublic import core.sys.darwin.mach.port;\n\nversion (X86)\n    version = i386;\nversion (X86_64)\n    version = i386;\nversion (i386)\n{\n    alias mach_port_t thread_act_t;\n    alias void        thread_state_t;\n    alias int         thread_state_flavor_t;\n    alias natural_t   mach_msg_type_number_t;\n\n    enum\n    {\n        x86_THREAD_STATE32      = 1,\n        x86_FLOAT_STATE32       = 2,\n        x86_EXCEPTION_STATE32   = 3,\n        x86_THREAD_STATE64      = 4,\n        x86_FLOAT_STATE64       = 5,\n        x86_EXCEPTION_STATE64   = 6,\n        x86_THREAD_STATE        = 7,\n        x86_FLOAT_STATE         = 8,\n        x86_EXCEPTION_STATE     = 9,\n        x86_DEBUG_STATE32       = 10,\n        x86_DEBUG_STATE64       = 11,\n        x86_DEBUG_STATE         = 12,\n        THREAD_STATE_NONE       = 13,\n    }\n\n    struct x86_thread_state32_t\n    {\n        uint    eax;\n        uint    ebx;\n        uint    ecx;\n        uint    edx;\n        uint    edi;\n        uint    esi;\n        uint    ebp;\n        uint    esp;\n        uint    ss;\n        uint    eflags;\n        uint    eip;\n        uint    cs;\n        uint    ds;\n        uint    es;\n        uint    fs;\n        uint    gs;\n    }\n\n    struct x86_thread_state64_t\n    {\n        ulong   rax;\n        ulong   rbx;\n        ulong   rcx;\n        ulong   rdx;\n        ulong   rdi;\n        ulong   rsi;\n        ulong   rbp;\n        ulong   rsp;\n        ulong   r8;\n        ulong   r9;\n        ulong   r10;\n        ulong   r11;\n        ulong   r12;\n        ulong   r13;\n        ulong   r14;\n        ulong   r15;\n        ulong   rip;\n        ulong   rflags;\n        ulong   cs;\n        ulong   fs;\n        ulong   gs;\n    }\n\n    struct x86_state_hdr_t\n    {\n        int     flavor;\n        int     count;\n    }\n\n    struct x86_thread_state_t\n    {\n        x86_state_hdr_t             tsh;\n        union _uts\n        {\n            x86_thread_state32_t    ts32;\n            x86_thread_state64_t    ts64;\n        }\n        _uts                        uts;\n    }\n\n    enum : mach_msg_type_number_t\n    {\n        x86_THREAD_STATE32_COUNT = cast(mach_msg_type_number_t)( x86_thread_state32_t.sizeof / int.sizeof ),\n        x86_THREAD_STATE64_COUNT = cast(mach_msg_type_number_t)( x86_thread_state64_t.sizeof / int.sizeof ),\n        x86_THREAD_STATE_COUNT   = cast(mach_msg_type_number_t)( x86_thread_state_t.sizeof / int.sizeof ),\n    }\n\n    alias x86_THREAD_STATE          MACHINE_THREAD_STATE;\n    alias x86_THREAD_STATE_COUNT    MACHINE_THREAD_STATE_COUNT;\n\n    mach_port_t   mach_thread_self();\n    kern_return_t thread_suspend(thread_act_t);\n    kern_return_t thread_resume(thread_act_t);\n    kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/netinet/in_.d",
    "content": "//Written in the D programming language\n\n/++\n    D header file for Darwin's extensions to POSIX's netinet/in.h.\n\n    Copyright: Copyright 2017 -\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n +/\nmodule core.sys.darwin.netinet.in_;\n\nimport core.sys.darwin.sys.cdefs;\n\npublic import core.sys.posix.netinet.in_;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern(C) nothrow @nogc:\n\nenum IPPROTO_IP = 0;\nstatic if (_DARWIN_C_SOURCE)\n    enum IPPROTO_HOPOPTS = 0;\nenum IPPROTO_ICMP = 1;\nstatic if (_DARWIN_C_SOURCE)\n{\n    enum IPPROTO_IGMP = 2;\n    enum IPPROTO_GGP  = 3;\n    enum IPPROTO_IPV4 = 4;\n    enum IPPROTO_IPIP = IPPROTO_IPV4;\n}\nenum IPPROTO_TCP = 6;\nstatic if (_DARWIN_C_SOURCE)\n{\n    enum IPPROTO_ST     = 7;\n    enum IPPROTO_EGP    = 8;\n    enum IPPROTO_PIGP   = 9;\n    enum IPPROTO_RCCMON = 10;\n    enum IPPROTO_NVPII  = 11;\n    enum IPPROTO_PUP    = 12;\n    enum IPPROTO_ARGUS  = 13;\n    enum IPPROTO_EMCON  = 14;\n    enum IPPROTO_XNET   = 15;\n    enum IPPROTO_CHAOS  = 16;\n}\nenum IPPROTO_UDP = 17;\nstatic if (_DARWIN_C_SOURCE)\n{\n    enum IPPROTO_MUX    = 18;\n    enum IPPROTO_MEAS   = 19;\n    enum IPPROTO_HMP    = 20;\n    enum IPPROTO_PRM    = 21;\n    enum IPPROTO_IDP    = 22;\n    enum IPPROTO_TRUNK1 = 23;\n    enum IPPROTO_TRUNK2 = 24;\n    enum IPPROTO_LEAF1  = 25;\n    enum IPPROTO_LEAF2  = 26;\n    enum IPPROTO_RDP    = 27;\n    enum IPPROTO_IRTP   = 28;\n    enum IPPROTO_TP     = 29;\n    enum IPPROTO_BLT    = 30;\n    enum IPPROTO_NSP    = 31;\n    enum IPPROTO_INP    = 32;\n    enum IPPROTO_SEP    = 33;\n    enum IPPROTO_3PC    = 34;\n    enum IPPROTO_IDPR   = 35;\n    enum IPPROTO_XTP    = 36;\n    enum IPPROTO_DDP    = 37;\n    enum IPPROTO_CMTP   = 38;\n    enum IPPROTO_TPXX   = 39;\n    enum IPPROTO_IL     = 40;\n}\nenum IPPROTO_IPV6 = 41;\nstatic if (_DARWIN_C_SOURCE)\n{\n    enum IPPROTO_SDRP      = 42;\n    enum IPPROTO_ROUTING   = 43;\n    enum IPPROTO_FRAGMENT  = 44;\n    enum IPPROTO_IDRP      = 45;\n    enum IPPROTO_RSVP      = 46;\n    enum IPPROTO_GRE       = 47;\n    enum IPPROTO_MHRP      = 48;\n    enum IPPROTO_BHA       = 49;\n    enum IPPROTO_ESP       = 50;\n    enum IPPROTO_AH        = 51;\n    enum IPPROTO_INLSP     = 52;\n    enum IPPROTO_SWIPE     = 53;\n    enum IPPROTO_NHRP      = 54;\n    enum IPPROTO_ICMPV6    = 58;\n    enum IPPROTO_NONE      = 59;\n    enum IPPROTO_DSTOPTS   = 60;\n    enum IPPROTO_AHIP      = 61;\n    enum IPPROTO_CFTP      = 62;\n    enum IPPROTO_HELLO     = 63;\n    enum IPPROTO_SATEXPAK  = 64;\n    enum IPPROTO_KRYPTOLAN = 65;\n    enum IPPROTO_RVD       = 66;\n    enum IPPROTO_IPPC      = 67;\n    enum IPPROTO_ADFS      = 68;\n    enum IPPROTO_SATMON    = 69;\n    enum IPPROTO_VISA      = 70;\n    enum IPPROTO_IPCV      = 71;\n    enum IPPROTO_CPNX      = 72;\n    enum IPPROTO_CPHB      = 73;\n    enum IPPROTO_WSN       = 74;\n    enum IPPROTO_PVP       = 75;\n    enum IPPROTO_BRSATMON  = 76;\n    enum IPPROTO_ND        = 77;\n    enum IPPROTO_WBMON     = 78;\n    enum IPPROTO_WBEXPAK   = 79;\n    enum IPPROTO_EON       = 80;\n    enum IPPROTO_VMTP      = 81;\n    enum IPPROTO_SVMTP     = 82;\n    enum IPPROTO_VINES     = 83;\n    enum IPPROTO_TTP       = 84;\n    enum IPPROTO_IGP       = 85;\n    enum IPPROTO_DGP       = 86;\n    enum IPPROTO_TCF       = 87;\n    enum IPPROTO_IGRP      = 88;\n    enum IPPROTO_OSPFIGP   = 89;\n    enum IPPROTO_SRPC      = 90;\n    enum IPPROTO_LARP      = 91;\n    enum IPPROTO_MTP       = 92;\n    enum IPPROTO_AX25      = 93;\n    enum IPPROTO_IPEIP     = 94;\n    enum IPPROTO_MICP      = 95;\n    enum IPPROTO_SCCSP     = 96;\n    enum IPPROTO_ETHERIP   = 97;\n    enum IPPROTO_ENCAP     = 98;\n    enum IPPROTO_APES      = 99;\n    enum IPPROTO_GMTP      = 100;\n    enum IPPROTO_PIM       = 103;\n    enum IPPROTO_IPCOMP    = 108;\n    enum IPPROTO_PGM       = 113;\n    enum IPPROTO_SCTP      = 132;\n    enum IPPROTO_DIVERT    = 254;\n}\nenum IPPROTO_RAW = 255;\n\nstatic if (_DARWIN_C_SOURCE)\n{\n    enum IPPROTO_MAX  = 256;\n    enum IPPROTO_DONE = 257;\n}\n\nstatic if (_DARWIN_C_SOURCE)\n{\n    enum IPPORT_RESERVED = 1024;\n    enum IPPORT_USERRESERVED = 5000;\n\n    enum IPPORT_HIFIRSTAUTO = 49152;\n    enum IPPORT_HILASTAUTO  = 65535;\n\n    enum IPPORT_RESERVEDSTART = 600;\n}\n\nstatic if (_DARWIN_C_SOURCE)\n{\n    extern(D) bool IN_CLASSA(in_addr_t i) pure @safe { return (i & 0x80000000) == 0; }\n    enum IN_CLASSA_NET    = 0xff000000;\n    enum IN_CLASSA_NSHIFT = 24;\n    enum IN_CLASSA_HOST   = 0x00ffffff;\n    enum IN_CLASSA_MAX    = 128;\n\n    extern(D) bool IN_CLASSB(in_addr_t i) pure @safe { return (i & 0xc0000000) == 0x80000000; }\n    enum IN_CLASSB_NET    = 0xffff0000;\n    enum IN_CLASSB_NSHIFT = 16;\n    enum IN_CLASSB_HOST   = 0x0000ffff;\n    enum IN_CLASSB_MAX    = 65536;\n\n    extern(D) bool IN_CLASSC(in_addr_t i) pure @safe { return (i & 0xe0000000) == 0xc0000000; }\n    enum IN_CLASSC_NET    = 0xffffff00;\n    enum IN_CLASSC_NSHIFT = 8;\n    enum IN_CLASSC_HOST   = 0x000000ff;\n\n    extern(D) bool IN_CLASSD(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xe0000000; }\n    enum IN_CLASSD_NET    = 0xf0000000;\n    enum IN_CLASSD_NSHIFT = 28;\n    enum IN_CLASSD_HOST   = 0x0fffffff;\n    extern(D) bool IN_MULTICAST(in_addr_t i) pure @safe { return IN_CLASSD(i); }\n\n    // The fact that these are identical looks suspicious (they're not quite\n    // identical on Linux). However, this _is_ how they're defined in FreeBSD\n    // and on OS X. So, while it _might_ be a bug, if it is, it's an upstream\n    // one, and we're compatible with it.\n    extern(D) bool IN_EXPERIMENTAL(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xf0000000; }\n    extern(D) bool IN_BADCLASS(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xf0000000; }\n\n    enum INADDR_UNSPEC_GROUP    = 0xe0000000;\n    enum INADDR_ALLHOSTS_GROUP  = 0xe0000001;\n    enum INADDR_ALLRTRS_GROUP   = 0xe0000002;\n    enum INADDR_ALLRPTS_GROUP   = 0xe0000016;\n    enum INADDR_CARP_GROUP      = 0xe0000012;\n    enum INADDR_PFSYNC_GROUP    = 0xe00000f0;\n    enum INADDR_ALLMDNS_GROUP   = 0xe00000fb;\n    enum INADDR_MAX_LOCAL_GROUP = 0xe00000ff;\n\n    enum IN_LINKLOCALNETNUM = 0xA9FE0000;\n    extern(D) bool IN_LINKLOCAL(in_addr_t i) pure @safe { return (i & IN_CLASSB_NET) == IN_LINKLOCALNETNUM; }\n    extern(D) bool IN_LOOPBACK(in_addr_t i) pure @safe { return (i & 0xff000000) == 0x7f000000; }\n    extern(D) bool IN_ZERONET(in_addr_t i) pure @safe { return (i & 0xff000000) == 0; }\n\n    extern(D) bool IN_PRIVATE(in_addr_t i) pure @safe\n    {\n        return (i & 0xff000000) == 0x0a000000 ||\n               (i & 0xfff00000) == 0xac100000 ||\n               (i & 0xffff0000) == 0xc0a80000;\n    }\n\n    extern(D) bool IN_LOCAL_GROUP(in_addr_t i) pure @safe { return (i & 0xffffff00) == 0xe0000000; }\n\n    extern(D) bool IN_ANY_LOCAL(in_addr_t i) pure @safe { return IN_LINKLOCAL(i) || IN_LOCAL_GROUP(i); }\n\n    enum IN_LOOPBACKNET = 127;\n\n\n    struct ip_opts\n    {\n        in_addr  ip_dst;\n        char[40] ip_opts;\n    };\n\n    enum IP_OPTIONS         = 1;\n    enum IP_HDRINCL         = 2;\n    enum IP_TOS             = 3;\n    enum IP_TTL             = 4;\n    enum IP_RECVOPTS        = 5;\n    enum IP_RECVRETOPTS     = 6;\n    enum IP_RECVDSTADDR     = 7;\n    enum IP_RETOPTS         = 8;\n    enum IP_MULTICAST_IF    = 9;\n    enum IP_MULTICAST_TTL   = 10;\n    enum IP_MULTICAST_LOOP  = 11;\n    enum IP_ADD_MEMBERSHIP  = 12;\n    enum IP_DROP_MEMBERSHIP = 13;\n    enum IP_MULTICAST_VIF   = 14;\n    enum IP_RSVP_ON         = 15;\n    enum IP_RSVP_OFF        = 16;\n    enum IP_RSVP_VIF_ON     = 17;\n    enum IP_RSVP_VIF_OFF    = 18;\n    enum IP_PORTRANGE       = 19;\n    enum IP_RECVIF          = 20;\n\n    enum IP_IPSEC_POLICY = 21;\n    enum IP_STRIPHDR     = 23;\n    enum IP_RECVTTL      = 24;\n    enum IP_BOUND_IF     = 25;\n    enum IP_PKTINFO      = 26;\n    enum IP_RECVPKTINFO  = IP_PKTINFO;\n    enum IP_RECVTOS      = 27;\n\n    enum IP_FW_ADD      = 40;\n    enum IP_FW_DEL      = 41;\n    enum IP_FW_FLUSH    = 42;\n    enum IP_FW_ZERO     = 43;\n    enum IP_FW_GET      = 44;\n    enum IP_FW_RESETLOG = 45;\n\n    enum IP_OLD_FW_ADD      = 50;\n    enum IP_OLD_FW_DEL      = 51;\n    enum IP_OLD_FW_FLUSH    = 52;\n    enum IP_OLD_FW_ZERO     = 53;\n    enum IP_OLD_FW_GET      = 54;\n    enum IP_NAT__XXX        = 55;\n    enum IP_OLD_FW_RESETLOG = 56;\n\n    enum IP_DUMMYNET_CONFIGURE = 60;\n    enum IP_DUMMYNET_DEL       = 61;\n    enum IP_DUMMYNET_FLUSH     = 62;\n    enum IP_DUMMYNET_GET       = 64;\n\n    enum IP_TRAFFIC_MGT_BACKGROUND = 65;\n    enum IP_MULTICAST_IFINDEX      = 66;\n\n    enum IP_ADD_SOURCE_MEMBERSHIP  = 70;\n    enum IP_DROP_SOURCE_MEMBERSHIP = 71;\n    enum IP_BLOCK_SOURCE           = 72;\n    enum IP_UNBLOCK_SOURCE         = 73;\n\n    enum IP_MSFILTER = 74;\n\n    enum MCAST_JOIN_GROUP         = 80;\n    enum MCAST_LEAVE_GROUP        = 81;\n    enum MCAST_JOIN_SOURCE_GROUP  = 82;\n    enum MCAST_LEAVE_SOURCE_GROUP = 83;\n    enum MCAST_BLOCK_SOURCE       = 84;\n    enum MCAST_UNBLOCK_SOURCE     = 85;\n\n    enum IP_DEFAULT_MULTICAST_TTL  = 1;\n    enum IP_DEFAULT_MULTICAST_LOOP = 1;\n\n    enum IP_MIN_MEMBERSHIPS = 31;\n    enum IP_MAX_MEMBERSHIPS = 4095;\n\n    enum IP_MAX_GROUP_SRC_FILTER = 512;\n    enum IP_MAX_SOCK_SRC_FILTER  = 128;\n    enum IP_MAX_SOCK_MUTE_FILTER = 128;\n\n    struct ip_mreq\n    {\n        in_addr imr_multiaddr;\n        in_addr imr_interface;\n    };\n\n    struct ip_mreqn\n    {\n        in_addr imr_multiaddr;\n        in_addr imr_address;\n        int     imr_ifindex;\n    };\n\n    struct ip_mreq_source\n    {\n        align(4):\n        in_addr imr_multiaddr;\n        in_addr imr_sourceaddr;\n        in_addr imr_interface;\n    };\n\n    struct group_req\n    {\n        align(4):\n        uint             gr_interface;\n        sockaddr_storage gr_group;\n    };\n\n    struct group_source_req\n    {\n        align(4):\n        uint             gsr_interface;\n        sockaddr_storage gsr_group;\n        sockaddr_storage gsr_source;\n    };\n\n    int setipv4sourcefilter(int, in_addr, in_addr, uint, uint, in_addr*);\n    int getipv4sourcefilter(int, in_addr, in_addr, uint*, uint*, in_addr*);\n    int setsourcefilter(int, uint, sockaddr*, socklen_t, uint, uint, sockaddr_storage*);\n    int getsourcefilter(int, uint, sockaddr*, socklen_t, uint*, uint*, sockaddr_storage*);\n\n    enum MCAST_UNDEFINED = 0;\n    enum MCAST_INCLUDE   = 1;\n    enum MCAST_EXCLUDE   = 2;\n\n    enum IP_PORTRANGE_DEFAULT = 0;\n    enum IP_PORTRANGE_HIGH    = 1;\n    enum IP_PORTRANGE_LOW     = 2;\n\n    struct in_pktinfo\n    {\n        uint     ipi_ifindex;\n        in_addr  ipi_spec_dst;\n        in_addr  ipi_addr;\n    };\n\n    enum IPPROTO_MAXID = IPPROTO_AH + 1;\n\n\n    enum IPCTL_FORWARDING        = 1;\n    enum IPCTL_SENDREDIRECTS     = 2;\n    enum IPCTL_DEFTTL            = 3;\n    enum IPCTL_DEFMTU            = 4;\n    enum IPCTL_RTEXPIRE          = 5;\n    enum IPCTL_RTMINEXPIRE       = 6;\n    enum IPCTL_RTMAXCACHE        = 7;\n    enum IPCTL_SOURCEROUTE       = 8;\n    enum IPCTL_DIRECTEDBROADCAST = 9;\n    enum IPCTL_INTRQMAXLEN       = 10;\n    enum IPCTL_INTRQDROPS        = 11;\n    enum IPCTL_STATS             = 12;\n    enum IPCTL_ACCEPTSOURCEROUTE = 13;\n    enum IPCTL_FASTFORWARDING    = 14;\n    enum IPCTL_KEEPFAITH         = 15;\n    enum IPCTL_GIF_TTL           = 16;\n    enum IPCTL_MAXID             = 17;\n\n    int bindresvport(int, sockaddr_in*);\n    int bindresvport_sa(int, sockaddr*);\n}\n\n// =============================================================================\n// What follows is from netinet6/in6.h, but since netinet6/in6.h specifically\n// says that it should only be #included by #including netinet/in.h, it makes\n// more sense to put them in here so that the way they're imported corresponds\n// with the correct way of #including them in C/C++.\n// =============================================================================\n\nstatic if (_DARWIN_C_SOURCE)\n{\n    enum IPV6PORT_RESERVED    = 1024;\n    enum IPV6PORT_ANONMIN     = 49152;\n    enum IPV6PORT_ANONMAX     = 65535;\n    enum IPV6PORT_RESERVEDMIN = 600;\n    enum IPV6PORT_RESERVEDMAX = IPV6PORT_RESERVED - 1;\n}\n\n\nenum IN6ADDR_ANY_INIT = in6_addr.init;\nenum IN6ADDR_LOOPBACK_INIT = in6_addr([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\n\nstatic if (_DARWIN_C_SOURCE)\n{\n    enum IN6ADDR_NODELOCAL_ALLNODES_INIT = in6_addr([0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\n    enum IN6ADDR_INTFACELOCAL_ALLNODES_INIT = in6_addr([0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\n    enum IN6ADDR_LINKLOCAL_ALLNODES_INIT = in6_addr([0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\n    enum IN6ADDR_LINKLOCAL_ALLROUTERS_INIT = in6_addr([0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02]);\n    enum IN6ADDR_LINKLOCAL_ALLV2ROUTERS_INIT = in6_addr([0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16]);\n    enum IN6ADDR_V4MAPPED_INIT = in6_addr([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                           0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]);\n}\n\n__gshared const in6_addr in6addr_any;\n__gshared const in6_addr in6addr_loopback;\nstatic if (_DARWIN_C_SOURCE)\n{\n    __gshared const in6_addr in6addr_nodelocal_allnodes;\n    __gshared const in6_addr in6addr_linklocal_allnodes;\n    __gshared const in6_addr in6addr_linklocal_allrouters;\n    __gshared const in6_addr in6addr_linklocal_allv2routers;\n\n    extern(D) bool IN6_ARE_ADDR_EQUAL(in6_addr* a, in6_addr* b) pure @safe { return *a == *b; }\n}\n\nextern(D) bool IN6_IS_ADDR_6TO4(in6_addr* x) pure @safe { return ntohs(x.s6_addr16[0]) == 0x2002; }\n\nenum __IPV6_ADDR_SCOPE_NODELOCAL    = 0x01;\nenum __IPV6_ADDR_SCOPE_INTFACELOCAL = 0x01;\nenum __IPV6_ADDR_SCOPE_LINKLOCAL    = 0x02;\nenum __IPV6_ADDR_SCOPE_SITELOCAL    = 0x05;\nenum __IPV6_ADDR_SCOPE_GLOBAL       = 0x0e;\n\nextern(D) bool IN6_IS_ADDR_UNIQUE_LOCAL(in6_addr* a) pure @safe\n{\n    return a.s6_addr[0] == 0xfc || a.s6_addr[0] == 0xfd;\n}\n\nstatic if (_DARWIN_C_SOURCE)\n    enum IPV6_SOCKOPT_RESERVED1 = 3;\nenum IPV6_UNICAST_HOPS   = 4;\nenum IPV6_MULTICAST_IF   = 9;\nenum IPV6_MULTICAST_HOPS = 10;\nenum IPV6_MULTICAST_LOOP = 11;\nenum IPV6_JOIN_GROUP     = 12;\nenum IPV6_LEAVE_GROUP    = 13;\n\nstatic if (_DARWIN_C_SOURCE)\n{\n    enum IPV6_PORTRANGE    = 14;\n    enum ICMP6_FILTER      = 18;\n\n    enum IPV6_CHECKSUM = 26;\n}\nenum IPV6_V6ONLY = 27;\nstatic if (_DARWIN_C_SOURCE)\n{\n    enum IPV6_BINDV6ONLY = IPV6_V6ONLY;\n\n    enum IPV6_IPSEC_POLICY = 28;\n\n    enum IPV6_FW_ADD   = 30;\n    enum IPV6_FW_DEL   = 31;\n    enum IPV6_FW_FLUSH = 32;\n    enum IPV6_FW_ZERO  = 33;\n    enum IPV6_FW_GET   = 34;\n\n    enum IPV6_RECVTCLASS = 35;\n    enum IPV6_TCLASS     = 36;\n\n    enum IPV6_RTHDRDSTOPTS = 57;\n\n    enum IPV6_RECVPKTINFO = 61;\n\n    enum IPV6_RECVHOPLIMIT = 37;\n    enum IPV6_RECVRTHDR    = 38;\n    enum IPV6_RECVHOPOPTS  = 39;\n    enum IPV6_RECVDSTOPTS  = 40;\n\n    enum IPV6_USE_MIN_MTU  = 42;\n    enum IPV6_RECVPATHMTU  = 43;\n\n    enum IPV6_PATHMTU = 44;\n\n    enum IPV6_PKTINFO  = 46;\n    enum IPV6_HOPLIMIT = 47;\n    enum IPV6_NEXTHOP  = 48;\n    enum IPV6_HOPOPTS  = 49;\n    enum IPV6_DSTOPTS  = 50;\n    enum IPV6_RTHDR    = 51;\n\n    enum IPV6_AUTOFLOWLABEL = 59;\n\n    enum IPV6_DONTFRAG = 62;\n\n    enum IPV6_PREFER_TEMPADDR = 63;\n\n    enum IPV6_BOUND_IF = 125;\n\n    enum IPV6_RTHDR_LOOSE  = 0;\n    enum IPV6_RTHDR_STRICT = 1;\n    enum IPV6_RTHDR_TYPE_0 = 0;\n\n    enum IPV6_DEFAULT_MULTICAST_HOPS = 1;\n    enum IPV6_DEFAULT_MULTICAST_LOOP = 1;\n\n    enum IPV6_MIN_MEMBERSHIPS = 31;\n    enum IPV6_MAX_MEMBERSHIPS = 4095;\n\n    enum IPV6_MAX_GROUP_SRC_FILTER = 512;\n    enum IPV6_MAX_SOCK_SRC_FILTER  = 128;\n\n    struct in6_pktinfo\n    {\n        in6_addr ipi6_addr;\n        uint     ipi6_ifindex;\n    };\n\n    struct ip6_mtuinfo\n    {\n        sockaddr_in6 ip6m_addr;\n        uint         ip6m_mtu;\n    };\n\n    enum IPV6_PORTRANGE_DEFAULT = 0;\n    enum IPV6_PORTRANGE_HIGH    = 1;\n    enum IPV6_PORTRANGE_LOW     = 2;\n\n    enum IPV6PROTO_MAXID = IPPROTO_PIM + 1;\n\n    enum IPV6CTL_FORWARDING         = 1;\n    enum IPV6CTL_SENDREDIRECTS      = 2;\n    enum IPV6CTL_DEFHLIM            = 3;\n    enum IPV6CTL_DEFMTU             = 4;\n    enum IPV6CTL_FORWSRCRT          = 5;\n    enum IPV6CTL_STATS              = 6;\n    enum IPV6CTL_MRTSTATS           = 7;\n    enum IPV6CTL_MRTPROTO           = 8;\n    enum IPV6CTL_MAXFRAGPACKETS     = 9;\n    enum IPV6CTL_SOURCECHECK        = 10;\n    enum IPV6CTL_SOURCECHECK_LOGINT = 11;\n    enum IPV6CTL_ACCEPT_RTADV       = 12;\n\n    enum IPV6CTL_LOG_INTERVAL   = 14;\n    enum IPV6CTL_HDRNESTLIMIT   = 15;\n    enum IPV6CTL_DAD_COUNT      = 16;\n    enum IPV6CTL_AUTO_FLOWLABEL = 17;\n    enum IPV6CTL_DEFMCASTHLIM   = 18;\n    enum IPV6CTL_GIF_HLIM       = 19;\n    enum IPV6CTL_KAME_VERSION   = 20;\n    enum IPV6CTL_USE_DEPRECATED = 21;\n    enum IPV6CTL_RR_PRUNE       = 22;\n    enum IPV6CTL_V6ONLY         = 24;\n    enum IPV6CTL_RTEXPIRE       = 25;\n    enum IPV6CTL_RTMINEXPIRE    = 26;\n    enum IPV6CTL_RTMAXCACHE     = 27;\n\n    enum IPV6CTL_USETEMPADDR     = 32;\n    enum IPV6CTL_TEMPPLTIME      = 33;\n    enum IPV6CTL_TEMPVLTIME      = 34;\n    enum IPV6CTL_AUTO_LINKLOCAL  = 35;\n    enum IPV6CTL_RIP6STATS       = 36;\n    enum IPV6CTL_PREFER_TEMPADDR = 37;\n    enum IPV6CTL_ADDRCTLPOLICY   = 38;\n    enum IPV6CTL_USE_DEFAULTZONE = 39;\n\n    enum IPV6CTL_MAXFRAGS   = 41;\n    enum IPV6CTL_MCAST_PMTU = 44;\n\n    enum IPV6CTL_NEIGHBORGCTHRESH      = 46;\n    enum IPV6CTL_MAXIFPREFIXES         = 47;\n    enum IPV6CTL_MAXIFDEFROUTERS       = 48;\n    enum IPV6CTL_MAXDYNROUTES          = 49;\n    enum ICMPV6CTL_ND6_ONLINKNSRFC4861 = 50;\n\n    enum IPV6CTL_MAXID = 51;\n\n    size_t inet6_rthdr_space(int, int) @trusted;\n    cmsghdr* inet6_rthdr_init(void*, int);\n    int inet6_rthdr_add(cmsghdr*, const in6_addr*, uint);\n    int inet6_rthdr_lasthop(cmsghdr*, uint);\n    int inet6_rthdr_segments(const cmsghdr*);\n    in6_addr* inet6_rthdr_getaddr(cmsghdr*, int);\n    int inet6_rthdr_getflags(const cmsghdr*, int);\n\n    int inet6_opt_init(void*, socklen_t);\n    int inet6_opt_append(void*, socklen_t, int, ubyte, socklen_t, ubyte, void**);\n    int inet6_opt_finish(void*, socklen_t, int);\n    int inet6_opt_set_val(void*, int, void*, socklen_t);\n\n    int inet6_opt_next(void*, socklen_t, int, ubyte*, socklen_t*, void**);\n    int inet6_opt_find(void*, socklen_t, int, ubyte, socklen_t*, void**);\n    int inet6_opt_get_val(void*, int, void*, socklen_t);\n    socklen_t inet6_rth_space(int, int) @trusted;\n    void* inet6_rth_init(void*, socklen_t, int, int);\n    int inet6_rth_add(void*, const in6_addr*);\n    int inet6_rth_reverse(const void*, void*);\n    int inet6_rth_segments(const void*);\n    in6_addr* inet6_rth_getaddr(const void*, int);\n    void addrsel_policy_init();\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/pthread.d",
    "content": "/**\n * D header file for Darwin.\n *\n * Copyright: Copyright Sean Kelly 2008 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n */\n\n/*          Copyright Sean Kelly 2008 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.darwin.pthread;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern (C):\nnothrow:\n@nogc:\n\npublic import core.sys.posix.pthread;\npublic import core.sys.darwin.mach.port;\n\nint pthread_is_threaded_np();\nint pthread_threadid_np(pthread_t, ulong*);\n// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)\nint pthread_rwlock_longrdlock_np(pthread_rwlock_t*);\nint pthread_rwlock_yieldwrlock_np(pthread_rwlock_t*);\n// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);\nint pthread_rwlock_downgrade_np(pthread_rwlock_t*);\nint pthread_rwlock_upgrade_np(pthread_rwlock_t*);\nint pthread_rwlock_tryupgrade_np(pthread_rwlock_t*);\nint pthread_rwlock_held_np(pthread_rwlock_t*);\nint pthread_rwlock_rdheld_np(pthread_rwlock_t*);\nint pthread_rwlock_wrheld_np(pthread_rwlock_t*);\nint pthread_getname_np(pthread_t, char*, size_t);\nint pthread_setname_np(in char*);\n// ^ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)\nint pthread_main_np();\nmach_port_t pthread_mach_thread_np(pthread_t);\nsize_t pthread_get_stacksize_np(pthread_t);\nvoid* pthread_get_stackaddr_np(pthread_t);\nint pthread_cond_signal_thread_np(pthread_cond_t*, pthread_t);\nint pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, in timespec*);\nint pthread_create_suspended_np(pthread_t*, in pthread_attr_t*, void* function(void*), void*);\nint pthread_kill(pthread_t, int);\npthread_t pthread_from_mach_thread_np(mach_port_t);\n// ^ __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)\nint pthread_sigmask(int, in sigset_t*, sigset_t*);\n// ^ __DARWIN_ALIAS(pthread_sigmask)\nvoid pthread_yield_np();\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/sys/cdefs.d",
    "content": "/**\n * D header file for Darwin\n *\n * Authors: Martin Nowak\n */\nmodule core.sys.darwin.sys.cdefs;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\n\npublic import core.sys.posix.config;\n\n// http://www.opensource.apple.com/source/xnu/xnu-2422.115.4/bsd/sys/cdefs.h\nenum _DARWIN_C_SOURCE = true;\n\nenum __DARWIN_C_FULL = 900_000L;\nenum __DARWIN_C_LEVEL = __DARWIN_C_FULL;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/sys/event.d",
    "content": "/**\n * D header file for Darwin.\n *\n * Copyright: Copyright Martin Nowak 2012. Etienne Cimon 2015.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n */\n\n/*          Copyright Martin Nowak 2012. Etienne Cimon 2015.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.darwin.sys.event;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern (C):\nnothrow:\n@nogc:\n\nimport core.stdc.stdint;    // intptr_t, uintptr_t\nimport core.sys.posix.time; // timespec\n\nenum : short\n{\n    EVFILT_READ     =  -1,\n    EVFILT_WRITE    =  -2,\n    EVFILT_AIO      =  -3,\n    EVFILT_VNODE    =  -4,\n    EVFILT_PROC     =  -5,\n    EVFILT_SIGNAL   =  -6,\n    EVFILT_TIMER    =  -7,\n    EVFILT_MACHPORT =  -8,\n    EVFILT_FS       =  -9,\n    EVFILT_USER     = -10,\n    EVFILT_VM       = -12,\n    EVFILT_EXCEPT   = -15,\n}\n\nextern(D) void EV_SET(kevent_t* kevp, typeof(kevent_t.tupleof) args)\n{\n    *kevp = kevent_t(args);\n}\n\nextern(D) void EV_SET64(kevent64_s* kevp, typeof(kevent64_s.tupleof) args)\n{\n    *kevp = kevent64_s(args);\n}\n\nstruct kevent_t\n{\n    uintptr_t    ident;\n    short       filter;\n    ushort       flags;\n    uint        fflags;\n    intptr_t      data;\n    void        *udata;\n}\n\nstruct kevent64_s\n{\n    ulong        ident;\n    short       filter;\n    ushort       flags;\n    uint        fflags;\n    long          data;\n    ulong        udata;\n    ulong[2]       ext;\n}\n\nenum\n{\n\n    KEVENT_FLAG_NONE         = 0x000,\n    KEVENT_FLAG_IMMEDIATE    = 0x001,\n    KEVENT_FLAG_ERROR_EVENTS = 0x002,\n\n    EV_ADD      = 0x0001,\n    EV_DELETE   = 0x0002,\n    EV_ENABLE   = 0x0004,\n    EV_DISABLE  = 0x0008,\n\n    EV_ONESHOT        = 0x0010,\n    EV_CLEAR          = 0x0020,\n    EV_RECEIPT        = 0x0040,\n\n    EV_DISPATCH       = 0x0080,\n    EV_UDATA_SPECIFIC = 0x0100,\n\n    EV_DISPATCH2      = EV_DISPATCH | EV_UDATA_SPECIFIC,\n\n    EV_VANISHED       = 0x0200,\n\n    EV_SYSFLAGS       = 0xF000,\n    EV_FLAG0          = 0x1000,\n    EV_FLAG1          = 0x2000,\n\n    EV_EOF      = 0x8000,\n    EV_ERROR    = 0x4000,\n}\n\nenum\n{\n    EV_POLL   = EV_FLAG0,\n    EV_OOBAND = EV_FLAG1,\n}\n\nenum\n{\n    NOTE_TRIGGER = 0x01000000,\n\n    NOTE_FFNOP      = 0x00000000,\n    NOTE_FFAND      = 0x40000000,\n    NOTE_FFOR       = 0x80000000,\n    NOTE_FFCOPY     = 0xc0000000,\n    NOTE_FFCTRLMASK = 0xc0000000,\n    NOTE_FFLAGSMASK = 0x00ffffff,\n\n    NOTE_LOWAT      = 0x0001,\n\n    NOTE_OOB        = 0x0002,\n\n    NOTE_DELETE     = 0x0001,\n    NOTE_WRITE      = 0x0002,\n    NOTE_EXTEND     = 0x0004,\n    NOTE_ATTRIB     = 0x0008,\n    NOTE_LINK       = 0x0010,\n    NOTE_RENAME     = 0x0020,\n    NOTE_REVOKE     = 0x0040,\n    NOTE_NONE       = 0x0080,\n    NOTE_FUNLOCK    = 0x0100,\n\n    NOTE_EXIT        = 0x80000000,\n    NOTE_FORK        = 0x40000000,\n    NOTE_EXEC        = 0x20000000,\n    NOTE_REAP        = 0x10000000,\n    NOTE_SIGNAL      = 0x08000000,\n    NOTE_EXITSTATUS  = 0x04000000,\n    NOTE_EXIT_DETAIL = 0x02000000,\n    NOTE_PDATAMASK   = 0x000fffff,\n    NOTE_PCTRLMASK   = ~NOTE_PDATAMASK,\n\n    NOTE_EXIT_REPARENTED = 0x00080000,\n\n    NOTE_EXIT_DETAIL_MASK = 0x00070000,\n    NOTE_EXIT_DECRYPTFAIL = 0x00010000,\n    NOTE_EXIT_MEMORY      = 0x00020000,\n    NOTE_EXIT_CSERROR     = 0x00040000,\n\n    NOTE_VM_PRESSURE                  = 0x80000000,\n    NOTE_VM_PRESSURE_TERMINATE        = 0x40000000,\n    NOTE_VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000,\n    NOTE_VM_ERROR                     = 0x10000000,\n\n    NOTE_SECONDS              = 0x00000001,\n    NOTE_USECONDS             = 0x00000002,\n    NOTE_NSECONDS             = 0x00000004,\n    NOTE_ABSOLUTE             = 0x00000008,\n\n    NOTE_LEEWAY               = 0x00000010,\n    NOTE_CRITICAL             = 0x00000020,\n    NOTE_BACKGROUND           = 0x00000040,\n    NOTE_MACH_CONTINUOUS_TIME = 0x00000080,\n\n    NOTE_TRACK      = 0x00000001,\n    NOTE_TRACKERR   = 0x00000002,\n    NOTE_CHILD      = 0x00000004,\n}\n\nint kqueue();\nint kevent(int kq, const kevent_t *changelist, int nchanges,\n           kevent_t *eventlist, int nevents,\n           const timespec *timeout);\nint kevent64(int kq,\n             const kevent64_s *changelist, int nchanges,\n             kevent64_s *eventlist, int nevents,\n             uint flags,\n             const timespec *timeout);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/darwin/sys/mman.d",
    "content": "/**\n * D header file for Darwin\n *\n * Authors: Martin Nowak\n */\nmodule core.sys.darwin.sys.mman;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nextern (C):\nnothrow:\n@nogc:\n\npublic import core.sys.posix.sys.mman;\nimport core.sys.darwin.sys.cdefs;\nimport core.sys.posix.sys.types;\n\n// already in core.sys.posix.sys.mman\n// enum PROT_NONE = 0x00;\n// enum PROT_READ = 0x01;\n// enum PROT_WRITE = 0x02;\n// enum PROT_EXEC = 0x04;\n\n// already in core.sys.posix.sys.mman\n// enum MAP_SHARED = 0x0001;\n// enum MAP_PRIVATE = 0x0002;\nstatic if (_DARWIN_C_SOURCE)\n    alias MAP_COPY = MAP_PRIVATE;\n// enum MAP_FIXED = 0x0010;\n\nstatic if (_DARWIN_C_SOURCE)\n{\n     enum MAP_RENAME = 0x0020;\n     enum MAP_NORESERVE = 0x0040;\n     enum MAP_RESERVED0080 = 0x0080;\n     enum MAP_NOEXTEND = 0x0100;\n     enum MAP_HASSEMAPHORE = 0x0200;\n     enum MAP_NOCACHE = 0x0400;\n     enum MAP_JIT = 0x0800;\n}\n\n// already in core.sys.posix.sys.mman\n// enum MCL_CURRENT = 0x0001;\n// enum MCL_FUTURE = 0x0002;\n\n// enum MAP_FAILED = cast(void*)-1;\n\n// enum MS_ASYNC = 0x0001;\n// enum MS_INVALIDATE = 0x0002;\n// enum MS_SYNC = 0x0010;\n\nstatic if (_DARWIN_C_SOURCE)\n{\n    enum MS_KILLPAGES = 0x0004;\n    enum MS_DEACTIVATE = 0x0008;\n\n    enum MAP_FILE = 0x0000;\n\n// already in core.sys.posix.sys.mman\n// enum MAP_ANON = 0x1000;\n\n// enum POSIX_MADV_NORMAL = 0;\n// enum POSIX_MADV_RANDOM = 1;\n// enum POSIX_MADV_SEQUENTIAL = 2;\n// enum POSIX_MADV_WILLNEED = 3;\n// enum POSIX_MADV_DONTNEED = 4;\n\n    alias MADV_NORMAL = POSIX_MADV_NORMAL;\n    alias MADV_RANDOM = POSIX_MADV_RANDOM;\n    alias MADV_SEQUENTIAL = POSIX_MADV_SEQUENTIAL;\n    alias MADV_WILLNEED = POSIX_MADV_WILLNEED;\n    alias MADV_DONTNEED = POSIX_MADV_DONTNEED;\n    enum MADV_FREE = 5;\n    enum MADV_ZERO_WIRED_PAGES = 6;\n    enum MADV_FREE_REUSABLE = 7;\n    enum MADV_FREE_REUSE = 8;\n    enum MADV_CAN_REUSE = 9;\n\n    enum MINCORE_INCORE = 0x1;\n    enum MINCORE_REFERENCED = 0x2;\n    enum MINCORE_MODIFIED = 0x4;\n    enum MINCORE_REFERENCED_OTHER = 0x8;\n    enum MINCORE_MODIFIED_OTHER = 0x10;\n}\n\n// already in core.sys.posix.sys.mman\n// int mlockall(int);\n// int munlockall(void);\n// int mlock(const void *, size_t);\n// void *  mmap(void *, size_t, int, int, int, off_t);\n// int mprotect(void *, size_t, int);\n// int msync(void *, size_t, int);\n// int munlock(const void *, size_t);\n// int munmap(void *, size_t);\n// int shm_open(const char *, int, ...);\n// int shm_unlink(const char *);\n// int posix_madvise(void *, size_t, int);\n\nstatic if (_DARWIN_C_SOURCE)\n{\n    int madvise(void *, size_t, int);\n    int mincore(const(void)*, size_t, char *);\n    int minherit(void *, size_t, int);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d",
    "content": "/**\n * D header file for DragonFlyBSD\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors: Martin Nowak,Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.dlfcn;\n\nversion (DragonFlyBSD):\n\npublic import core.sys.posix.dlfcn;\n\nextern (C) nothrow @nogc @system:\n\n/*\n * Modes and flags for dlopen().\n */\nstatic assert(RTLD_LAZY   == 1);\nstatic assert(RTLD_NOW    == 2);\nenum RTLD_MODEMASK        =  0x3;\nstatic assert(RTLD_GLOBAL == 0x100);\nstatic assert(RTLD_LOCAL  == 0);\nenum RTLD_TRACE           =  0x200;\nenum RTLD_NODELETE        =  0x01000;\nenum RTLD_NOLOAD          =  0x02000;\n\n/*\n * Request arguments for dlinfo().\n */\nenum RTLD_DI_LINKMAP     = 2;    /* Obtain link map. */\nenum RTLD_DI_SERINFO     = 4;    /* Obtain search path info. */\nenum RTLD_DI_SERINFOSIZE = 5;    /*  ... query for required space. */\nenum RTLD_DI_ORIGIN      = 6;    /* Obtain object origin */\nenum RTLD_DI_MAX         = RTLD_DI_ORIGIN;\n\n/*\n * Special handle arguments for dlsym()/dlinfo().\n */\nenum RTLD_NEXT    = cast(void *)-1;    /* Search subsequent objects. */\nenum RTLD_DEFAULT = cast(void *)-2;    /* Use default search algorithm. */\nenum RTLD_SELF    = cast(void *)-3;    /* Search the caller itself. */\n\n/*\n * Structure filled in by dladdr().\n */\nstruct Dl_info {\n    const(char)     *dli_fname;     /* Pathname of shared object. */\n    void            *dli_fbase;     /* Base address of shared object. */\n    const(char)     *dli_sname;     /* Name of nearest symbol. */\n    void            *dli_saddr;     /* Address of nearest symbol. */\n};\n\n\n/*\n * Structures, returned by the RTLD_DI_SERINFO dlinfo() request.\n */\nstruct Dl_serpath {\n    char *          dls_name;       /* single search path entry */\n    uint            dls_flags;      /* path information */\n};\n\nstruct Dl_serinfo {\n    size_t          dls_size;       /* total buffer size */\n    uint            dls_cnt;        /* number of path entries */\n    Dl_serpath[1]   dls_serpath;    /* there may be more than one */\n};\n\n/*-\n * The actual type declared by this typedef is immaterial, provided that\n * it is a function pointer.  Its purpose is to provide a return type for\n * dlfunc() which can be cast to a function pointer type without depending\n * on behavior undefined by the C standard, which might trigger a compiler\n * diagnostic.  We intentionally declare a unique type signature to force\n * a diagnostic should the application not cast the return value of dlfunc()\n * appropriately.\n */\nstruct __dlfunc_arg {\n    int     __dlfunc_dummy;\n};\n\nalias dlfunc_t = void function(__dlfunc_arg);\n\nprivate template __externC(RT, P...)\n{\n    alias __externC = extern(C) RT function(P) nothrow @nogc @system;\n}\n\n/* XSI functions first. */\nstatic assert(is(typeof(&dlclose) == __externC!(int, void*)));\nstatic assert(is(typeof(&dlerror) == __externC!(char*)));\nstatic assert(is(typeof(&dlopen)  == __externC!(void*, const char*, int)));\nstatic assert(is(typeof(&dlsym)   == __externC!(void*, void*, const char*)));\n\nvoid*    fdlopen(int, int);\nint      dladdr(const(void)*, Dl_info*);\ndlfunc_t dlfunc(void*, const(char)*);\nint      dlinfo(void*, int, void*);\n/*void     dllockinit(void* _context,\n    void* function(void* _context) _lock_create,\n    void  function(void* _lock)    _rlock_acquire,\n    void  function(void* _lock)    _wlock_acquire,\n    void  function(void* _lock)    _lock_release,\n    void  function(void* _lock)    _lock_destroy,\n    void  function(void* _context) _context_destroy);*/\nvoid*    dlvsym(void*, const(char)*, const(char)*);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/execinfo.d",
    "content": "/**\n * DragonFlyBSD implementation of glibc's $(LINK2 http://www.gnu.org/software/libc/manual/html_node/Backtraces.html backtrace) facility.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors: Martin Nowak,Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.execinfo;\n\nversion (DragonFlyBSD):\n\nextern (C) nothrow @system:\n\nimport core.sys.dragonflybsd.dlfcn;\n\n// Use extern (D) so that these functions don't collide with libexecinfo.\n\nextern (D) int backtrace(void** buffer, int size)\n{\n    import core.thread : thread_stackBottom;\n\n    void** p, pend=cast(void**)thread_stackBottom();\n    version (D_InlineAsm_X86)\n        asm nothrow @trusted { mov p[EBP], EBP; }\n    else version (D_InlineAsm_X86_64)\n        asm nothrow @trusted { mov p[RBP], RBP; }\n    else\n        static assert(false, \"Architecture not supported.\");\n\n    int i;\n    for (; i < size && p < pend; ++i)\n    {\n        buffer[i] = *(p + 1);\n        auto pnext = cast(void**)*p;\n        if (pnext <= p) break;\n        p = pnext;\n    }\n    return i;\n}\n\n\nextern (D) char** backtrace_symbols(const(void*)* buffer, int size)\n{\n    static void* realloc(void* p, size_t len) nothrow\n    {\n        static import cstdlib=core.stdc.stdlib;\n        auto res = cstdlib.realloc(p, len);\n        if (res is null) cstdlib.free(p);\n        return res;\n    }\n\n    if (size <= 0) return null;\n\n    size_t pos = size * (char*).sizeof;\n    char** p = cast(char**)realloc(null, pos);\n    if (p is null) return null;\n\n    Dl_info info;\n    foreach (i, addr; buffer[0 .. size])\n    {\n        if (dladdr(addr, &info) == 0)\n            (cast(ubyte*)&info)[0 .. info.sizeof] = 0;\n        fixupDLInfo(addr, info);\n\n        immutable len = formatStackFrame(null, 0, addr, info);\n        assert(len > 0);\n\n        p = cast(char**)realloc(p, pos + len);\n        if (p is null) return null;\n\n        formatStackFrame(cast(char*)p + pos, len, addr, info) == len || assert(0);\n\n        p[i] = cast(char*)pos;\n        pos += len;\n    }\n    foreach (i; 0 .. size)\n    {\n        pos = cast(size_t)p[i];\n        p[i] = cast(char*)p + pos;\n    }\n    return p;\n}\n\n\nextern (D) void backtrace_symbols_fd(const(void*)* buffer, int size, int fd)\n{\n    import core.sys.posix.unistd : write;\n    import core.stdc.stdlib : alloca;\n\n    if (size <= 0) return;\n\n    Dl_info info;\n    foreach (i, addr; buffer[0 .. size])\n    {\n        if (dladdr(addr, &info) == 0)\n            (cast(ubyte*)&info)[0 .. info.sizeof] = 0;\n        fixupDLInfo(addr, info);\n\n        enum maxAlloca = 1024;\n        enum min = (size_t a, size_t b) => a <= b ? a : b;\n        immutable len = min(formatStackFrame(null, 0, addr, info), maxAlloca);\n        assert(len > 0);\n\n        auto p = cast(char*)alloca(len);\n        if (p is null) return;\n\n        formatStackFrame(p, len, addr, info) >= len || assert(0);\n        p[len - 1] = '\\n';\n        write(fd, p, len);\n    }\n}\n\n\nprivate void fixupDLInfo(const(void)* addr, ref Dl_info info)\n{\n    if (info.dli_fname is null) info.dli_fname = \"???\";\n    if (info.dli_fbase is null) info.dli_fbase = null;\n    if (info.dli_sname is null) info.dli_sname = \"???\";\n    if (info.dli_saddr is null) info.dli_saddr = cast(void*)addr;\n}\n\n\nprivate size_t formatStackFrame(char* p, size_t plen, const(void)* addr, const ref Dl_info info)\n{\n    import core.stdc.stdio : snprintf;\n\n    immutable off = addr - info.dli_saddr;\n    immutable len = snprintf(p, plen, \"%p <%s+%zd> at %s\",\n                             addr, info.dli_sname, off, info.dli_fname);\n    assert(len > 0);\n    return cast(size_t)len + 1; // + '\\0'\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/netinet/in_.d",
    "content": "/**\n    D header file for DragonFlyBSD's extensions to POSIX's netinet/in.h.\n\n    Copyright: Copyright 2017 -\n    License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors: $(HTTP jmdavisprog.com, Jonathan M Davis) and Diederik de Groot\n */\nmodule core.sys.dragonflybsd.netinet.in_;\n\nversion (DragonFlyBSD):\n\nimport core.sys.dragonflybsd.sys.cdefs;\n\npublic import core.sys.posix.netinet.in_;\n\nextern(C) nothrow @nogc @system:\n\nenum IPPROTO_HOPOPTS   = 0;\n\nenum IPPROTO_IPV4      = 4;\nenum IPPROTO_IPIP      = IPPROTO_IPV4;\nenum IPPROTO_ST        = 7;\nenum IPPROTO_EGP       = 8;\nenum IPPROTO_PIGP      = 9;\nenum IPPROTO_RCCMON    = 10;\nenum IPPROTO_NVPII     = 11;\n\nenum IPPROTO_ARGUS     = 13;\nenum IPPROTO_EMCON     = 14;\nenum IPPROTO_XNET      = 15;\nenum IPPROTO_CHAOS     = 16;\nenum IPPROTO_MUX       = 18;\nenum IPPROTO_MEAS      = 19;\nenum IPPROTO_HMP       = 20;\nenum IPPROTO_PRM       = 21;\n\nenum IPPROTO_TRUNK1    = 23;\nenum IPPROTO_TRUNK2    = 24;\nenum IPPROTO_LEAF1     = 25;\nenum IPPROTO_LEAF2     = 26;\nenum IPPROTO_RDP       = 27;\nenum IPPROTO_IRTP      = 28;\nenum IPPROTO_TP        = 29;\nenum IPPROTO_BLT       = 30;\nenum IPPROTO_NSP       = 31;\nenum IPPROTO_INP       = 32;\nenum IPPROTO_SEP       = 33;\nenum IPPROTO_3PC       = 34;\nenum IPPROTO_IDPR      = 35;\nenum IPPROTO_XTP       = 36;\nenum IPPROTO_DDP       = 37;\nenum IPPROTO_CMTP      = 38;\nenum IPPROTO_TPXX      = 39;\nenum IPPROTO_IL        = 40;\nenum IPPROTO_SDRP      = 42;\nenum IPPROTO_ROUTING   = 43;\nenum IPPROTO_FRAGMENT  = 44;\nenum IPPROTO_IDRP      = 45;\nenum IPPROTO_RSVP      = 46;\nenum IPPROTO_GRE       = 47;\nenum IPPROTO_MHRP      = 48;\nenum IPPROTO_BHA       = 49;\nenum IPPROTO_ESP       = 50;\nenum IPPROTO_AH        = 51;\nenum IPPROTO_INLSP     = 52;\nenum IPPROTO_SWIPE     = 53;\nenum IPPROTO_NHRP      = 54;\nenum IPPROTO_MOBILE    = 55;\nenum IPPROTO_TLSP      = 56;\nenum IPPROTO_SKIP      = 57;\nenum IPPROTO_ICMPV6    = 58;\nenum IPPROTO_NONE      = 59;\nenum IPPROTO_DSTOPTS   = 60;\nenum IPPROTO_AHIP      = 61;\nenum IPPROTO_CFTP      = 62;\nenum IPPROTO_HELLO     = 63;\nenum IPPROTO_SATEXPAK  = 64;\nenum IPPROTO_KRYPTOLAN = 65;\nenum IPPROTO_RVD       = 66;\nenum IPPROTO_IPPC      = 67;\nenum IPPROTO_ADFS      = 68;\nenum IPPROTO_SATMON    = 69;\nenum IPPROTO_VISA      = 70;\nenum IPPROTO_IPCV      = 71;\nenum IPPROTO_CPNX      = 72;\nenum IPPROTO_CPHB      = 73;\nenum IPPROTO_WSN       = 74;\nenum IPPROTO_PVP       = 75;\nenum IPPROTO_BRSATMON  = 76;\n\nenum IPPROTO_WBMON     = 78;\nenum IPPROTO_WBEXPAK   = 79;\nenum IPPROTO_EON       = 80;\nenum IPPROTO_VMTP      = 81;\nenum IPPROTO_SVMTP     = 82;\nenum IPPROTO_VINES     = 83;\nenum IPPROTO_TTP       = 84;\nenum IPPROTO_IGP       = 85;\nenum IPPROTO_DGP       = 86;\nenum IPPROTO_TCF       = 87;\nenum IPPROTO_IGRP      = 88;\nenum IPPROTO_OSPFIGP   = 89;\nenum IPPROTO_SRPC      = 90;\nenum IPPROTO_LARP      = 91;\nenum IPPROTO_MTP       = 92;\nenum IPPROTO_AX25      = 93;\nenum IPPROTO_IPEIP     = 94;\nenum IPPROTO_MICP      = 95;\nenum IPPROTO_SCCSP     = 96;\nenum IPPROTO_ETHERIP   = 97;\nenum IPPROTO_ENCAP     = 98;\nenum IPPROTO_APES      = 99;\nenum IPPROTO_GMTP      = 100;\nenum IPPROTO_IPCOMP    = 108;\nenum IPPROTO_SCTP      = 132;\nenum IPPROTO_MH        = 135;\nenum IPPROTO_UDPLITE   = 136;\nenum IPPROTO_HIP       = 139;\nenum IPPROTO_SHIM6     = 140;\n\nenum IPPROTO_PIM          = 103;\nenum IPPROTO_CARP         = 112;\nenum IPPROTO_PGM          = 113;\nenum IPPROTO_MPLS         = 137;\nenum IPPROTO_PFSYNC       = 240;\nenum IPPROTO_RESERVED_253 = 253;\nenum IPPROTO_RESERVED_254 = 254;\n\nenum IPPROTO_DONE = 257;\n\nenum IPPORT_RESERVED = 1024;\n\nenum IPPORT_EPHEMERALFIRST = 10000;\nenum IPPORT_EPHEMERALLAST  = 65535;\n\nenum IPPORT_HIFIRSTAUTO = 49152;\nenum IPPORT_HILASTAUTO  = 65535;\n\nenum IPPORT_RESERVEDSTART = 600;\n\nenum IPPORT_MAX = 65535;\n\nextern(D) bool IN_CLASSA(in_addr_t i) pure @safe { return (i & 0x80000000) == 0; }\nenum IN_CLASSA_NET    = 0xff000000;\nenum IN_CLASSA_NSHIFT = 24;\nenum IN_CLASSA_HOST   = 0x00ffffff;\nenum IN_CLASSA_MAX    = 128;\n\nextern(D) bool IN_CLASSB(in_addr_t i) pure @safe { return (i & 0xc0000000) == 0x80000000; }\nenum IN_CLASSB_NET    = 0xffff0000;\nenum IN_CLASSB_NSHIFT = 16;\nenum IN_CLASSB_HOST   = 0x0000ffff;\nenum IN_CLASSB_MAX    = 65536;\n\nextern(D) bool IN_CLASSC(in_addr_t i) pure @safe { return (i & 0xe0000000) == 0xc0000000; }\nenum IN_CLASSC_NET    = 0xffffff00;\nenum IN_CLASSC_NSHIFT = 8;\nenum IN_CLASSC_HOST   = 0x000000ff;\n\nextern(D) bool IN_CLASSD(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xe0000000; }\nenum IN_CLASSD_NET     = 0xf0000000;\nenum IN_CLASSD_NSHIFT  = 28;\nenum IN_CLASSD_HOST    = 0x0fffffff;\nextern(D) bool IN_MULTICAST(in_addr_t i) { return IN_CLASSD(i); }\n\n// The fact that these are identical looks suspicious (they're not quite\n// identical on Linux). However, this _is_ how they're defined in DragonFlyBSD\n// and on OS X. So, while it _might_ be a bug, if it is, it's an upstream\n// one, and we're compatible with it.\nextern(D) bool IN_EXPERIMENTAL(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xf0000000; }\nextern(D) bool IN_BADCLASS(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xf0000000; }\n\nextern(D) bool IN_LINKLOCAL(in_addr_t i) pure @safe { return (i & 0xffff0000) == 0xa9fe0000; }\nextern(D) bool IN_LOOPBACK(in_addr_t i) pure @safe { return (i & 0xff000000) == 0x7f000000; }\nextern(D) bool IN_ZERONET(in_addr_t i) pure @safe { return (i & 0xff000000) == 0; }\n\nextern(D) bool IN_PRIVATE(in_addr_t i) pure @safe\n{\n    return  (i & 0xff000000) == 0x0a000000 ||\n            (i & 0xfff00000) == 0xac100000 ||\n            (i & 0xffff0000) == 0xc0a80000;\n}\n\nextern(D) bool IN_LOCAL_GROUP(in_addr_t i) pure @safe { return (i & 0xffffff00) == 0xe0000000; }\n\nextern(D) bool IN_ANY_LOCAL(in_addr_t i) pure @safe { return IN_LINKLOCAL(i) || IN_LOCAL_GROUP(i); }\n\nenum INADDR_UNSPEC_GROUP    = 0xe0000000;\nenum INADDR_ALLHOSTS_GROUP  = 0xe0000001;\nenum INADDR_ALLRTRS_GROUP   = 0xe0000002;\nenum INADDR_ALLRPTS_GROUP   = 0xe0000016;\nenum INADDR_CARP_GROUP      = 0xe0000012;\nenum INADDR_PFSYNC_GROUP    = 0xe00000f0;\nenum INADDR_ALLMDNS_GROUP   = 0xe00000fb;\nenum INADDR_MAX_LOCAL_GROUP = 0xe00000ff;\n\nenum IN_LOOPBACKNET = 127;\n\nenum IN_RFC3021_MASK = 0xfffffffe;\n\nenum IP_OPTIONS      = 1;\nenum IP_HDRINCL      = 2;\nenum IP_TOS          = 3;\nenum IP_TTL          = 4;\nenum IP_RECVOPTS     = 5;\nenum IP_RECVRETOPTS  = 6;\nenum IP_RECVDSTADDR  = 7;\nenum IP_SENDSRCADDR  = IP_RECVDSTADDR;\nenum IP_RETOPTS      = 8;\nenum IP_MULTICAST_IF = 9;\n\nenum IP_MULTICAST_TTL   = 10;\nenum IP_MULTICAST_LOOP  = 11;\nenum IP_ADD_MEMBERSHIP  = 12;\nenum IP_DROP_MEMBERSHIP = 13;\nenum IP_MULTICAST_VIF   = 14;\nenum IP_RSVP_ON         = 15;\nenum IP_RSVP_OFF        = 16;\nenum IP_RSVP_VIF_ON     = 17;\nenum IP_RSVP_VIF_OFF    = 18;\nenum IP_PORTRANGE       = 19;\nenum IP_RECVIF          = 20;\n\nenum IP_IPSEC_POLICY = 21;\n\nenum IP_ONESBCAST         = 23;\nenum IP_BINDANY           = 24;\nenum IP_BINDMULTI         = 25;\nenum IP_RSS_LISTEN_BUCKET = 26;\nenum IP_ORIGDSTADDR       = 27;\nenum IP_RECVORIGDSTADDR   = IP_ORIGDSTADDR;\n\nenum IP_FW3       = 48;\nenum IP_DUMMYNET3 = 49;\n\nenum IP_ADD_SOURCE_MEMBERSHIP  = 70;\nenum IP_DROP_SOURCE_MEMBERSHIP = 71;\nenum IP_BLOCK_SOURCE           = 72;\nenum IP_UNBLOCK_SOURCE         = 73;\n\nenum MCAST_JOIN_GROUP         = 80;\nenum MCAST_LEAVE_GROUP        = 81;\nenum MCAST_JOIN_SOURCE_GROUP  = 82;\nenum MCAST_LEAVE_SOURCE_GROUP = 83;\nenum MCAST_BLOCK_SOURCE       = 84;\nenum MCAST_UNBLOCK_SOURCE     = 85;\n\nenum IP_FLOWID          = 90;\nenum IP_FLOWTYPE        = 91;\nenum IP_RSSBUCKETID     = 92;\nenum IP_RECVFLOWID      = 93;\nenum IP_RECVRSSBUCKETID = 94;\n\nenum IP_DEFAULT_MULTICAST_TTL  = 1;\nenum IP_DEFAULT_MULTICAST_LOOP = 1;\n\nenum IP_MIN_MEMBERSHIPS   = 31;\nenum IP_MAX_MEMBERSHIPS   = 4095;\n\nenum IP_MAX_GROUP_SRC_FILTER = 512;\nenum IP_MAX_SOCK_SRC_FILTER  = 128;\n\nstruct ip_mreq\n{\n    in_addr imr_multiaddr;\n    in_addr imr_interface;\n};\n\nstruct ip_mreqn\n{\n    in_addr imr_multiaddr;\n    in_addr imr_address;\n    int     imr_ifindex;\n};\n\nstruct ip_mreq_source\n{\n    in_addr imr_multiaddr;\n    in_addr imr_sourceaddr;\n    in_addr imr_interface;\n};\n\nstruct group_req\n{\n    uint gr_interface;\n    sockaddr_storage gr_group;\n};\n\nstruct group_source_req\n{\n    uint gsr_interface;\n    sockaddr_storage gsr_group;\n    sockaddr_storage gsr_source;\n};\n\nint setipv4sourcefilter(int, in_addr, in_addr, uint, uint, in_addr*);\nint getipv4sourcefilter(int, in_addr, in_addr, uint*, uint*, in_addr*);\nint setsourcefilter(int, uint, sockaddr*, socklen_t, uint, uint, sockaddr_storage*);\nint getsourcefilter(int, uint, sockaddr*, socklen_t, uint*, uint*, sockaddr_storage*);\n\nenum MCAST_UNDEFINED = 0;\nenum MCAST_INCLUDE   = 1;\nenum MCAST_EXCLUDE   = 2;\n\nenum IP_PORTRANGE_DEFAULT = 0;\nenum IP_PORTRANGE_HIGH    = 1;\nenum IP_PORTRANGE_LOW     = 2;\n\nenum IPCTL_FORWARDING        = 1;\nenum IPCTL_SENDREDIRECTS     = 2;\nenum IPCTL_DEFTTL            = 3;\nenum IPCTL_DEFMTU            = 4;\nenum IPCTL_SOURCEROUTE       = 8;\nenum IPCTL_DIRECTEDBROADCAST = 9;\nenum IPCTL_INTRQMAXLEN       = 10;\nenum IPCTL_INTRQDROPS        = 11;\nenum IPCTL_STATS             = 12;\nenum IPCTL_ACCEPTSOURCEROUTE = 13;\nenum IPCTL_FASTFORWARDING    = 14;\nenum IPCTL_GIF_TTL           = 16;\nenum IPCTL_INTRDQMAXLEN      = 17;\nenum IPCTL_INTRDQDROPS       = 18;\n\n// =============================================================================\n// What follows is from netinet6/in6.h, but since netinet6/in6.h specifically\n// says that it should only be #included by #including netinet/in.h, it makes\n// more sense to put them in here so that the way they're imported corresponds\n// with the correct way of #including them in C/C++.\n// =============================================================================\n\n// The #if was around the #include of in6.h at the end of in.h.\nenum IPV6PORT_RESERVED    = 1024;\nenum IPV6PORT_ANONMIN     = 49152;\nenum IPV6PORT_ANONMAX     = 65535;\nenum IPV6PORT_RESERVEDMIN = 600;\nenum IPV6PORT_RESERVEDMAX = IPV6PORT_RESERVED - 1;\n\nenum IN6ADDR_ANY_INIT = in6_addr.init;\nenum IN6ADDR_LOOPBACK_INIT = in6_addr([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\nenum IN6ADDR_NODELOCAL_ALLNODES_INIT = in6_addr([0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\nenum IN6ADDR_INTFACELOCAL_ALLNODES_INIT = in6_addr([0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\nenum IN6ADDR_LINKLOCAL_ALLNODES_INIT = in6_addr([0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\nenum IN6ADDR_LINKLOCAL_ALLROUTERS_INIT = in6_addr([0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02]);\nenum IN6ADDR_LINKLOCAL_ALLV2ROUTERS_INIT = in6_addr([0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16]);\n\n__gshared const in6_addr in6addr_nodelocal_allnodes;\n__gshared const in6_addr in6addr_linklocal_allnodes;\n__gshared const in6_addr in6addr_linklocal_allrouters;\n__gshared const in6_addr in6addr_linklocal_allv2routers;\n\nextern(D) bool IN6_ARE_ADDR_EQUAL(in6_addr* a, in6_addr* b) pure @safe { return *a == *b; }\n\nenum __IPV6_ADDR_SCOPE_NODELOCAL    = 0x01;\nenum __IPV6_ADDR_SCOPE_INTFACELOCAL = 0x01;\nenum __IPV6_ADDR_SCOPE_LINKLOCAL    = 0x02;\nenum __IPV6_ADDR_SCOPE_SITELOCAL    = 0x05;\nenum __IPV6_ADDR_SCOPE_GLOBAL       = 0x0e;\n\n// TODO - requires declarations from elsewhere that we don't currently have bindings for.\n/+\n    struct route_in6\n    {\n        rtentry* ro_rt;\n        llentry* ro_lle;\n        char*    ro_prepend;\n        ushort   ro_plen;\n        ushort   ro_flags;\n        ushort   ro_mtu;\n        ushort   spare;\n        sockaddr_in6 ro_dst;\n    };\n+/\n\nenum IPV6_SOCKOPT_RESERVED1 = 3;\nenum IPV6_PORTRANGE         = 14;\nenum ICMP6_FILTER           = 18;\n\nenum IPV6_CHECKSUM = 26;\n\nenum IPV6_IPSEC_POLICY = 28;\n\nenum IPV6_FW_ADD   = 30;\nenum IPV6_FW_DEL   = 31;\nenum IPV6_FW_FLUSH = 32;\nenum IPV6_FW_ZERO  = 33;\nenum IPV6_FW_GET   = 34;\n\nenum IPV6_RTHDRDSTOPTS = 35;\n\nenum IPV6_RECVPKTINFO  = 36;\nenum IPV6_RECVHOPLIMIT = 37;\nenum IPV6_RECVRTHDR    = 38;\nenum IPV6_RECVHOPOPTS  = 39;\nenum IPV6_RECVDSTOPTS  = 40;\n\nenum IPV6_USE_MIN_MTU = 42;\nenum IPV6_RECVPATHMTU = 43;\n\nenum IPV6_PATHMTU = 44;\n\nenum IPV6_PKTINFO  = 46;\nenum IPV6_HOPLIMIT = 47;\nenum IPV6_NEXTHOP  = 48;\nenum IPV6_HOPOPTS  = 49;\nenum IPV6_DSTOPTS  = 50;\nenum IPV6_RTHDR    = 51;\n\nenum IPV6_RECVTCLASS = 57;\n\nenum IPV6_AUTOFLOWLABEL = 59;\n\nenum IPV6_TCLASS   = 61;\nenum IPV6_DONTFRAG = 62;\n\nenum IPV6_PREFER_TEMPADDR = 63;\n\nenum IPV6_BINDANY   = 64;\n\nenum IPV6_BINDMULTI         = 65;\nenum IPV6_RSS_LISTEN_BUCKET = 66;\nenum IPV6_FLOWID            = 67;\nenum IPV6_FLOWTYPE          = 68;\nenum IPV6_RSSBUCKETID       = 69;\nenum IPV6_RECVFLOWID        = 70;\nenum IPV6_RECVRSSBUCKETID   = 71;\n\nenum IPV6_ORIGDSTADDR     = 72;\nenum IPV6_RECVORIGDSTADDR = IPV6_ORIGDSTADDR;\n\nenum IPV6_RTHDR_LOOSE  = 0;\nenum IPV6_RTHDR_STRICT = 1;\nenum IPV6_RTHDR_TYPE_0 = 0;\n\nenum IPV6_DEFAULT_MULTICAST_HOPS = 1;\nenum IPV6_DEFAULT_MULTICAST_LOOP = 1;\n\nenum IPV6_MIN_MEMBERSHIPS = 31;\nenum IPV6_MAX_MEMBERSHIPS = 4095;\n\nenum IPV6_MAX_GROUP_SRC_FILTER = 512;\nenum IPV6_MAX_SOCK_SRC_FILTER  = 128;\n\nstruct in6_pktinfo\n{\n    in6_addr ipi6_addr;\n    uint     ipi6_ifindex;\n};\n\nstruct ip6_mtuinfo\n{\n    sockaddr_in6 ip6m_addr;\n    uint         ip6m_mtu;\n};\n\nenum IPV6_PORTRANGE_DEFAULT = 0;\nenum IPV6_PORTRANGE_HIGH    = 1;\nenum IPV6_PORTRANGE_LOW     = 2;\n\nenum IPV6PROTO_MAXID =  IPPROTO_PIM + 1;\n\nenum IPV6CTL_FORWARDING         = 1;\nenum IPV6CTL_SENDREDIRECTS      = 2;\nenum IPV6CTL_DEFHLIM            = 3;\nenum IPV6CTL_DEFMTU             = 4;\nenum IPV6CTL_FORWSRCRT          = 5;\nenum IPV6CTL_STATS              = 6;\nenum IPV6CTL_MRTSTATS           = 7;\nenum IPV6CTL_MRTPROTO           = 8;\nenum IPV6CTL_MAXFRAGPACKETS     = 9;\nenum IPV6CTL_SOURCECHECK        = 10;\nenum IPV6CTL_SOURCECHECK_LOGINT = 11;\nenum IPV6CTL_ACCEPT_RTADV       = 12;\n\nenum IPV6CTL_LOG_INTERVAL   = 14;\nenum IPV6CTL_HDRNESTLIMIT   = 15;\nenum IPV6CTL_DAD_COUNT      = 16;\nenum IPV6CTL_AUTO_FLOWLABEL = 17;\nenum IPV6CTL_DEFMCASTHLIM   = 18;\nenum IPV6CTL_GIF_HLIM       = 19;\nenum IPV6CTL_KAME_VERSION   = 20;\nenum IPV6CTL_USE_DEPRECATED = 21;\nenum IPV6CTL_RR_PRUNE       = 22;\nenum IPV6CTL_V6ONLY         = 24;\n\nenum IPV6CTL_USETEMPADDR     = 32;\nenum IPV6CTL_TEMPPLTIME      = 33;\nenum IPV6CTL_TEMPVLTIME      = 34;\nenum IPV6CTL_AUTO_LINKLOCAL  = 35;\nenum IPV6CTL_RIP6STATS       = 36;\nenum IPV6CTL_PREFER_TEMPADDR = 37;\nenum IPV6CTL_ADDRCTLPOLICY   = 38;\nenum IPV6CTL_USE_DEFAULTZONE = 39;\n\nenum IPV6CTL_MAXFRAGS   = 41;\nenum IPV6CTL_MCAST_PMTU = 44;\n\nenum IPV6CTL_STEALTH = 45;\n\nenum ICMPV6CTL_ND6_ONLINKNSRFC4861 = 47;\nenum IPV6CTL_NO_RADR     = 48;\nenum IPV6CTL_NORBIT_RAIF = 49;\n\nenum IPV6CTL_RFC6204W3 = 50;\n\nenum IPV6CTL_INTRQMAXLEN  = 51;\nenum IPV6CTL_INTRDQMAXLEN = 52;\n\nenum IPV6CTL_MAXID = 53;\n\n// TODO - require declarations from elsewhere that we don't currently have bindings for.\n/+\nenum M_FASTFWD_OURS  = M_PROTO1;\nenum M_IP6_NEXTHOP   = M_PROTO2;\nenum M_IP_NEXTHOP    = M_PROTO2;\nenum M_SKIP_FIREWALL = M_PROTO3;\nenum M_AUTHIPHDR     = M_PROTO4;\nenum M_DECRYPTED     = M_PROTO5;\nenum M_LOOP          = M_PROTO6;\nenum M_AUTHIPDGM     = M_PROTO7;\nenum M_RTALERT_MLD   = M_PROTO8;\n+/\n\nsize_t inet6_rthdr_space(int, int) @trusted;\ncmsghdr* inet6_rthdr_init(void*, int);\nint inet6_rthdr_add(cmsghdr*, const in6_addr*, uint);\nint inet6_rthdr_lasthop(cmsghdr*, uint);\nint inet6_rthdr_segments(const cmsghdr*);\nin6_addr* inet6_rthdr_getaddr(cmsghdr*, int);\nint inet6_rthdr_getflags(const cmsghdr*, int);\n\nint inet6_opt_init(void*, socklen_t);\nint inet6_opt_append(void*, socklen_t, int, ubyte, socklen_t, ubyte, void**);\nint inet6_opt_finish(void*, socklen_t, int);\nint inet6_opt_set_val(void*, int, void*, socklen_t);\n\nint inet6_opt_next(void*, socklen_t, int, ubyte*, socklen_t*, void**);\nint inet6_opt_find(void*, socklen_t, int, ubyte, socklen_t*, void**);\nint inet6_opt_get_val(void*, int, void*, socklen_t);\nsocklen_t inet6_rth_space(int, int) @trusted;\nvoid* inet6_rth_init(void*, socklen_t, int, int);\nint inet6_rth_add(void*, const in6_addr*);\nint inet6_rth_reverse(const void*, void*);\nint inet6_rth_segments(const void*);\nin6_addr* inet6_rth_getaddr(const void*, int);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/pthread_np.d",
    "content": "/**\n * D header file for DragonFlyBSD\n *\n * Authors: Martin Nowak,Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.pthread_np;\n\nversion (DragonFlyBSD):\n\nextern (C) nothrow @nogc @system:\n\npublic import core.sys.posix.sys.types;\n// TODO: add full core.sys.dragonflybsd.sys.cpuset;\npublic import core.sys.dragonflybsd.sys._cpuset;\npublic import core.sys.posix.time;\n\nalias pthread_switch_routine_t = void function(pthread_t, pthread_t);\n\nint pthread_attr_get_np(pthread_t, pthread_attr_t *);\nint pthread_attr_getaffinity_np(const(pthread_attr_t)*, size_t, cpuset_t *);\nint pthread_attr_setaffinity_np(pthread_attr_t *, size_t, const(cpuset_t)*);\nint pthread_attr_setcreatesuspend_np(pthread_attr_t *);\nint pthread_getaffinity_np(pthread_t, size_t, cpuset_t *);\nint pthread_main_np();\nint pthread_multi_np();\nint pthread_mutexattr_getkind_np(pthread_mutexattr_t);\nint pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int);\nvoid pthread_resume_all_np();\nint pthread_resume_np(pthread_t);\nvoid pthread_set_name_np(pthread_t, const(char)*);\nint pthread_setaffinity_np(pthread_t, size_t, const(cpuset_t)*);\nint pthread_single_np();\nvoid pthread_suspend_all_np();\nint pthread_suspend_np(pthread_t);\nint pthread_switch_add_np(pthread_switch_routine_t);\nint pthread_switch_delete_np(pthread_switch_routine_t);\nint pthread_timedjoin_np(pthread_t, void **, const(timespec)*);\n\n//int pthread_getthreadid_np();\n//int pthread_mutex_getspinloops_np(pthread_mutex_t *mutex, int *count);\n//int pthread_mutex_setspinloops_np(pthread_mutex_t *mutex, int count);\n//int pthread_mutex_getyieldloops_np(pthread_mutex_t *mutex, int *count);\n//int pthread_mutex_setyieldloops_np(pthread_mutex_t *mutex, int count);\n//int pthread_mutex_isowned_np(pthread_mutex_t *mutex);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/sys/_bitset.d",
    "content": "/**\n * D header file for DragonFlyBSD.\n *\n * Authors: Martin Nowak, Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.sys._bitset;\n\nversion (DragonFlyBSD):\nextern (C) pure nothrow @nogc @system:\n\nimport core.stdc.config : c_long;\n\nenum NBBY = 8; // number of bits per byte\n\nenum _BITSET_BITS = c_long.sizeof * NBBY;\n\nenum __bitset_words(size_t s) = (s + _BITSET_BITS - 1) / _BITSET_BITS;\n\nc_long __bitset_mask(size_t s)(size_t n)\n{\n    static if (__bitset_words!s == 1)\n        return (cast(c_long)1) << n;\n    else\n        return (cast(c_long)1) << n % _BITSET_BITS;\n}\n\nsize_t __bitset_word(size_t s)(size_t n)\n{\n    static if (__bitset_words!s == 1)\n        return 0;\n    else\n        return n / _BITSET_BITS;\n}\n\nstruct BITSET_DEFINE(size_t s)\n{\n    c_long[__bitset_words!s] __bits;\n}\n\n// no idea how to translate those\n//#define BITSET_T_INITIALIZER(x)                     \\\n//    { .__bits = { x } }\n//\n//#define BITSET_FSET(n)                          \\\n//    [ 0 ... ((n) - 1) ] = (-1L)\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/sys/_cpuset.d",
    "content": "/**\n * D header file for DragonFlyBSD.\n *\n * Authors: Martin Nowak, Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.sys._cpuset;\n\nversion (DragonFlyBSD):\n\npublic import core.sys.dragonflybsd.sys._bitset;\n\nstatic if (is(typeof(_KERNEL)))\n    alias CPU_SETSIZE = MAXCPU;\n\nenum CPU_MAXSIZE = 256;\n\nstatic if (!is(typeof(CPU_SETSIZE)))\n    alias CPU_SETSIZE = CPU_MAXSIZE;\n\nenum _NCPUBITS = _BITSET_BITS;\nenum _NCPUWORDS = __bitset_words!CPU_SETSIZE;\n\nalias _cpuset = BITSET_DEFINE!(CPU_SETSIZE);\nalias cpuset_t = _cpuset;\n\n// no idea how to translate those\n//#define CPUSET_FSET BITSET_FSET(_NCPUWORDS)\n//#define CPUSET_T_INITIALIZER BITSET_T_INITIALIZER\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/sys/cdefs.d",
    "content": "/**\n * D header file for DragonFlyBSD\n *\n * Authors: Martin Nowak,Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.sys.cdefs;\n\nversion (DragonFlyBSD):\n\npublic import core.sys.posix.config;\n\nenum __POSIX_VISIBLE = 200112;\nenum __XSI_VISIBLE = 700;\nenum __BSD_VISIBLE = true;\nenum __ISO_C_VISIBLE = 1999;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/sys/elf.d",
    "content": "/**\n * D header file for DragonFlyBSD.\n *\n * Authors: Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.sys.elf;\n\nversion (DragonFlyBSD):\n\npublic import core.sys.dragonflybsd.sys.elf32;\npublic import core.sys.dragonflybsd.sys.elf64;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/sys/elf32.d",
    "content": "/**\n * D header file for DragonFlyBSD.\n *\n * Authors: Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.sys.elf32;\n\nversion (DragonFlyBSD):\n\nextern (C):\n\nimport core.stdc.stdint;\npublic import core.sys.dragonflybsd.sys.elf_common;\n\nalias uint16_t Elf32_Half;\nalias uint32_t Elf32_Word;\nalias int32_t  Elf32_Sword;\nalias uint64_t Elf32_Lword;\nalias uint32_t Elf32_Addr;\nalias uint32_t Elf32_Off;\nalias Elf32_Word Elf32_Hashelt;\nalias Elf32_Word Elf32_Size;\nalias Elf32_Sword Elf32_Ssize;\n\nstruct Elf32_Ehdr\n{\n    char[EI_NIDENT] e_ident;\n    Elf32_Half    e_type;\n    Elf32_Half    e_machine;\n    Elf32_Word    e_version;\n    Elf32_Addr    e_entry;\n    Elf32_Off     e_phoff;\n    Elf32_Off     e_shoff;\n    Elf32_Word    e_flags;\n    Elf32_Half    e_ehsize;\n    Elf32_Half    e_phentsize;\n    Elf32_Half    e_phnum;\n    Elf32_Half    e_shentsize;\n    Elf32_Half    e_shnum;\n    Elf32_Half    e_shstrndx;\n}\n\nstruct Elf32_Shdr\n{\n    Elf32_Word    sh_name;\n    Elf32_Word    sh_type;\n    Elf32_Word    sh_flags;\n    Elf32_Addr    sh_addr;\n    Elf32_Off     sh_offset;\n    Elf32_Word    sh_size;\n    Elf32_Word    sh_link;\n    Elf32_Word    sh_info;\n    Elf32_Word    sh_addralign;\n    Elf32_Word    sh_entsize;\n}\n\nstruct Elf32_Phdr\n{\n    Elf32_Word    p_type;\n    Elf32_Off     p_offset;\n    Elf32_Addr    p_vaddr;\n    Elf32_Addr    p_paddr;\n    Elf32_Word    p_filesz;\n    Elf32_Word    p_memsz;\n    Elf32_Word    p_flags;\n    Elf32_Word    p_align;\n}\n\nstruct Elf32_Dyn\n{\n  Elf32_Sword   d_tag;\n  union _d_un\n  {\n      Elf32_Word d_val;\n      Elf32_Addr d_ptr;\n  } _d_un d_un;\n}\n\nstruct Elf32_Rel\n{\n    Elf32_Addr    r_offset;\n    Elf32_Word    r_info;\n}\n\nstruct Elf32_Rela\n{\n    Elf32_Addr    r_offset;\n    Elf32_Word    r_info;\n    Elf32_Sword   r_addend;\n}\n\nextern (D) pure @safe\n{\n    auto ELF32_R_SYM(V)(V val) { return val >> 8; }\n    auto ELF32_R_TYPE(V)(V val) { return val & 0xff; }\n    auto ELF32_R_INFO(S, T)(S sym, T type) { return (sym << 8) + (type & 0xff); }\n}\n\nalias Elf_Note Elf32_Nhdr;\n\nstruct Elf32_Move\n{\n    Elf32_Lword   m_value;\n    Elf32_Word    m_info;\n    Elf32_Word    m_poffset;\n    Elf32_Half    m_repeat;\n    Elf32_Half    m_stride;\n}\n\nextern (D) pure\n{\n    auto ELF32_M_SYM(I)(I info) @safe { return info >> 8; }\n    auto ELF32_M_SIZE(I)(I info) { return cast(ubyte)info; }\n    auto ELF32_M_INFO(S, SZ)(S sym, SZ size) { return (sym << 8) + cast(ubye)size; }\n}\n\nstruct Elf32_Cap\n{\n    Elf32_Word    c_tag;\n    union _c_un\n    {\n        Elf32_Word      c_val;\n        Elf32_Addr      c_ptr;\n    } _c_un c_un;\n}\n\nstruct Elf32_Sym\n{\n    Elf32_Word    st_name;\n    Elf32_Addr    st_value;\n    Elf32_Word    st_size;\n    ubyte st_info;\n    ubyte st_other;\n    Elf32_Half st_shndx;\n}\n\nextern (D) pure\n{\n    auto ELF32_ST_BIND(T)(T val) { return cast(ubyte)val >> 4; }\n    auto ELF32_ST_TYPE(T)(T val) @safe { return val & 0xf; }\n    auto ELF32_ST_INFO(B, T)(B bind, T type) @safe { return (bind << 4) + (type & 0xf); }\n    auto ELF32_ST_VISIBILITY(O)(O o) @safe { return o & 0x03; }\n}\n\nstruct Elf32_Verdef\n{\n    Elf32_Half    vd_version;\n    Elf32_Half    vd_flags;\n    Elf32_Half    vd_ndx;\n    Elf32_Half    vd_cnt;\n    Elf32_Word    vd_hash;\n    Elf32_Word    vd_aux;\n    Elf32_Word    vd_next;\n}\n\nstruct Elf32_Verdaux\n{\n    Elf32_Word    vda_name;\n    Elf32_Word    vda_next;\n}\n\nstruct Elf32_Verneed\n{\n    Elf32_Half    vn_version;\n    Elf32_Half    vn_cnt;\n    Elf32_Word    vn_file;\n    Elf32_Word    vn_aux;\n    Elf32_Word    vn_next;\n}\n\nstruct Elf32_Vernaux\n{\n    Elf32_Word    vna_hash;\n    Elf32_Half    vna_flags;\n    Elf32_Half    vna_other;\n    Elf32_Word    vna_name;\n    Elf32_Word    vna_next;\n}\n\nalias Elf32_Half Elf32_Versym;\n\nstruct Elf32_Syminfo\n{\n    Elf32_Half si_boundto;\n    Elf32_Half si_flags;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/sys/elf64.d",
    "content": "/**\n * D header file for DragonFlyBSD.\n *\n * Authors: Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.sys.elf64;\n\nversion (DragonFlyBSD):\n\nextern (C):\n\nimport core.stdc.stdint;\npublic import core.sys.dragonflybsd.sys.elf_common;\n\nalias uint16_t Elf64_Half;\nalias uint32_t Elf64_Word;\nalias int32_t  Elf64_Sword;\nalias uint64_t Elf64_Lword;\nalias uint64_t Elf64_Xword;\nalias int64_t  Elf64_Sxword;\nalias uint64_t Elf64_Addr;\nalias uint64_t Elf64_Off;\nalias Elf64_Word Elf64_Hashelt;\nalias Elf64_Xword Elf64_Size;\nalias Elf64_Sxword Elf64_Ssize;\n\nstruct Elf64_Ehdr\n{\n    char[EI_NIDENT] e_ident;\n    Elf64_Half    e_type;\n    Elf64_Half    e_machine;\n    Elf64_Word    e_version;\n    Elf64_Addr    e_entry;\n    Elf64_Off     e_phoff;\n    Elf64_Off     e_shoff;\n    Elf64_Word    e_flags;\n    Elf64_Half    e_ehsize;\n    Elf64_Half    e_phentsize;\n    Elf64_Half    e_phnum;\n    Elf64_Half    e_shentsize;\n    Elf64_Half    e_shnum;\n    Elf64_Half    e_shstrndx;\n}\n\nstruct Elf64_Shdr\n{\n    Elf64_Word    sh_name;\n    Elf64_Word    sh_type;\n    Elf64_Xword   sh_flags;\n    Elf64_Addr    sh_addr;\n    Elf64_Off     sh_offset;\n    Elf64_Xword   sh_size;\n    Elf64_Word    sh_link;\n    Elf64_Word    sh_info;\n    Elf64_Xword   sh_addralign;\n    Elf64_Xword   sh_entsize;\n}\n\nstruct Elf64_Phdr\n{\n    Elf64_Word    p_type;\n    Elf64_Word    p_flags;\n    Elf64_Off     p_offset;\n    Elf64_Addr    p_vaddr;\n    Elf64_Addr    p_paddr;\n    Elf64_Xword   p_filesz;\n    Elf64_Xword   p_memsz;\n    Elf64_Xword   p_align;\n}\n\nstruct Elf64_Dyn\n{\n  Elf64_Sxword  d_tag;\n  union _d_un\n  {\n      Elf64_Xword d_val;\n      Elf64_Addr d_ptr;\n  } _d_un d_un;\n}\n\nstruct Elf64_Rel\n{\n    Elf64_Addr    r_offset;\n    Elf64_Xword   r_info;\n}\n\nstruct Elf64_Rela\n{\n    Elf64_Addr    r_offset;\n    Elf64_Xword   r_info;\n    Elf64_Sxword  r_addend;\n}\n\nextern (D) pure\n{\n    auto ELF64_R_SYM(I)(I i) @safe { return i >> 32; }\n    auto ELF64_R_TYPE(I)(I i) @safe { return i & 0xffffffff; }\n    auto ELF64_R_INFO(S, T)(S sym, T type) @safe { return (sym << 32) + (type & 0xffffffff); }\n\n    auto ELF64_R_TYPE_DATA(I)(I i) { return (cast(Elf64_Xword) i << 32) >> 40; }\n    auto ELF64_R_TYPE_ID(I)(I i) { return (cast(Elf64_Xword) i << 56 ) >> 56; }\n    auto ELF64_R_TYPE_INFO(D, T)(D d, T t) { return cast(Elf64_Xword) d << 8 + cast(Elf64_Xword) t; }\n}\n\nalias Elf_Note Elf64_Nhdr;\n\nstruct Elf64_Move\n{\n    Elf64_Lword   m_value;\n    Elf64_Xword   m_info;\n    Elf64_Xword   m_poffset;\n    Elf64_Half    m_repeat;\n    Elf64_Half    m_stride;\n}\n\nextern (D) pure\n{\n    auto ELF64_M_SYM(I)(I info) @safe { return info >> 8; }\n    auto ELF64_M_SIZE(I)(I info) { return cast(ubyte)info; }\n    auto ELF64_M_INFO(S, SZ)(S sym, SZ size) @safe { return (sym << 8) + cast(ubye)size; }\n}\n\nstruct Elf64_Cap\n{\n    Elf64_Xword   c_tag;\n    union _c_un\n    {\n        Elf64_Xword     c_val;\n        Elf64_Addr      c_ptr;\n    } _c_un c_un;\n}\n\nstruct Elf64_Sym\n{\n    Elf64_Word    st_name;\n    ubyte st_info;\n    ubyte st_other;\n    Elf64_Half st_shndx;\n    Elf64_Addr    st_value;\n    Elf64_Xword   st_size;\n}\n\nextern (D) pure\n{\n    auto ELF64_ST_BIND(T)(T val) { return cast(ubyte)val >> 4; }\n    auto ELF64_ST_TYPE(T)(T val) @safe { return val & 0xf; }\n    auto ELF64_ST_INFO(B, T)(B bind, T type) @safe { return (bind << 4) + (type & 0xf); }\n    auto ELF64_ST_VISIBILITY(O)(O o) @safe { return o & 0x03; }\n}\n\nstruct Elf64_Verdef\n{\n    Elf64_Half    vd_version;\n    Elf64_Half    vd_flags;\n    Elf64_Half    vd_ndx;\n    Elf64_Half    vd_cnt;\n    Elf64_Word    vd_hash;\n    Elf64_Word    vd_aux;\n    Elf64_Word    vd_next;\n}\n\nstruct Elf64_Verdaux\n{\n    Elf64_Word    vda_name;\n    Elf64_Word    vda_next;\n}\n\nstruct Elf64_Verneed\n{\n    Elf64_Half    vn_version;\n    Elf64_Half    vn_cnt;\n    Elf64_Word    vn_file;\n    Elf64_Word    vn_aux;\n    Elf64_Word    vn_next;\n}\n\nstruct Elf64_Vernaux\n{\n    Elf64_Word    vna_hash;\n    Elf64_Half    vna_flags;\n    Elf64_Half    vna_other;\n    Elf64_Word    vna_name;\n    Elf64_Word    vna_next;\n}\n\nalias Elf64_Half Elf64_Versym;\n\nstruct Elf64_Syminfo\n{\n    Elf64_Half si_boundto;\n    Elf64_Half si_flags;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/sys/elf_common.d",
    "content": "/**\n * D header file for DragonFlyBSD.\n *\n * Authors: Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.sys.elf_common;\n\nversion (DragonFlyBSD):\n\nextern (C):\n\nimport core.stdc.stdint;\n\nstruct Elf_Note\n{\n    uint32_t      n_namesz;\n    uint32_t      n_descsz;\n    uint32_t      n_type;\n}\n\nstruct Elf_GNU_Hash_Header\n{\n    uint32_t      gh_nbuckets;\n    uint32_t      gh_symndx;\n    uint32_t      gh_maskwords;\n    uint32_t      gh_shift2;\n}\n\nenum EI_MAG0 =         0;\nenum EI_MAG1 =         1;\nenum EI_MAG2 =         2;\nenum EI_MAG3 =         3;\nenum EI_CLASS =        4;\nenum EI_DATA =         5;\nenum EI_VERSION =      6;\nenum EI_OSABI =        7;\nenum EI_ABIVERSION =   8;\nenum OLD_EI_BRAND =    8;\nenum EI_PAD =          9;\nenum EI_NIDENT =       16;\n\nenum ELFMAG0 =         0x7f;\nenum ELFMAG1 =         'E';\nenum ELFMAG2 =         'L';\nenum ELFMAG3 =         'F';\nenum ELFMAG =          \"\\177ELF\";\nenum SELFMAG =         4;\n\nenum EV_NONE =         0;\nenum EV_CURRENT =      1;\n\nenum ELFCLASSNONE =    0;\nenum ELFCLASS32 =      1;\nenum ELFCLASS64 =      2;\n\nenum ELFDATANONE =     0;\nenum ELFDATA2LSB =     1;\nenum ELFDATA2MSB =     2;\n\nenum ELFOSABI_NONE =           0;\nenum ELFOSABI_SYSV =           0;\nenum ELFOSABI_HPUX =           1;\nenum ELFOSABI_NETBSD =         2;\nenum ELFOSABI_LINUX =          3;\nenum ELFOSABI_HURD  =          4;\nenum ELFOSABI_86OPEN =         5;\nenum ELFOSABI_SOLARIS =        6;\nenum ELFOSABI_AIX =            7;\nenum ELFOSABI_MONTEREY =       7;\nenum ELFOSABI_IRIX =           8;\nenum ELFOSABI_FREEBSD =        9;\nenum ELFOSABI_TRU64 =          10;\nenum ELFOSABI_MODESTO =        11;\nenum ELFOSABI_OPENBSD =        12;\nenum ELFOSABI_OPENVMS =        13;\nenum ELFOSABI_NSK =            14;\nenum ELFOSABI_AROS =           15;\nenum ELFOSABI_ARM =            97;\nenum ELFOSABI_STANDALONE =     255;\n\n// just a pointer\nenum ELFOSABI_DRAGONFLYBSD =   ELFOSABI_NONE;\n\nextern (D) pure @safe\n{\n    auto IS_ELF(T)(T ehdr) { return ehdr.e_ident[EI_MAG0] == ELFMAG0 &&\n                                    ehdr.e_ident[EI_MAG1] == ELFMAG1 &&\n                                    ehdr.e_ident[EI_MAG2] == ELFMAG2 &&\n                                    ehdr.e_ident[EI_MAG3] == ELFMAG3; }\n}\n\nenum ET_NONE =         0;\nenum ET_REL =          1;\nenum ET_EXEC =         2;\nenum ET_DYN =          3;\nenum ET_CORE =         4;\nenum ET_LOOS =         0xfe00;\nenum ET_HIOS =         0xfeff;\nenum ET_LOPROC =       0xff00;\nenum ET_HIPROC =       0xffff;\n\nenum EM_NONE =          0;\nenum EM_M32 =           1;\nenum EM_SPARC =         2;\nenum EM_386 =           3;\nenum EM_68K =           4;\nenum EM_88K =           5;\nenum EM_860 =           7;\nenum EM_MIPS =          8;\nenum EM_S370 =          9;\nenum EM_MIPS_RS3_LE =  10;\nenum EM_PARISC =       15;\nenum EM_VPP500 =       17;\nenum EM_SPARC32PLUS =  18;\nenum EM_960 =          19;\nenum EM_PPC =          20;\nenum EM_PPC64 =        21;\nenum EM_S390 =         22;\nenum EM_V800 =         36;\nenum EM_FR20 =         37;\nenum EM_RH32 =         38;\nenum EM_RCE =          39;\nenum EM_ARM =          40;\nenum EM_SH =           42;\nenum EM_SPARCV9 =      43;\nenum EM_TRICORE =      44;\nenum EM_ARC =          45;\nenum EM_H8_300 =       46;\nenum EM_H8_300H =      47;\nenum EM_H8S =          48;\nenum EM_H8_500 =       49;\nenum EM_IA_64 =        50;\nenum EM_MIPS_X =       51;\nenum EM_COLDFIRE =     52;\nenum EM_68HC12 =       53;\nenum EM_MMA =          54;\nenum EM_PCP =          55;\nenum EM_NCPU =         56;\nenum EM_NDR1 =         57;\nenum EM_STARCORE =     58;\nenum EM_ME16 =         59;\nenum EM_ST100 =        60;\nenum EM_TINYJ =        61;\nenum EM_X86_64 =       62;\nenum EM_AMD64 =        62;\nenum EM_PDSP =         63;\nenum EM_FX66 =         66;\nenum EM_ST9PLUS =      67;\nenum EM_ST7 =          68;\nenum EM_68HC16 =       69;\nenum EM_68HC11 =       70;\nenum EM_68HC08 =       71;\nenum EM_68HC05 =       72;\nenum EM_SVX =          73;\nenum EM_ST19 =         74;\nenum EM_VAX =          75;\nenum EM_CRIS =         76;\nenum EM_JAVELIN =      77;\nenum EM_FIREPATH =     78;\nenum EM_ZSP =          79;\nenum EM_MMIX =         80;\nenum EM_HUANY =        81;\nenum EM_PRISM =        82;\nenum EM_AVR =          83;\nenum EM_FR30 =         84;\nenum EM_D10V =         85;\nenum EM_D30V =         86;\nenum EM_V850 =         87;\nenum EM_M32R =         88;\nenum EM_MN10300 =      89;\nenum EM_MN10200 =      90;\nenum EM_PJ =           91;\nenum EM_OPENRISC =     92;\nenum EM_ARC_A5 =       93;\nenum EM_XTENSA =       94;\nenum EM_VIDEOCORE =    95;\nenum EM_TMM_GPP =      96;\nenum EM_NS32K =        97;\nenum EM_TPC =          98;\nenum EM_SNP1K =        99;\nenum EM_ST200 =       100;\nenum EM_IP2K =        101;\nenum EM_MAX =         102;\nenum EM_CR =          103;\nenum EM_F2MC16 =      104;\nenum EM_MSP430 =      105;\nenum EM_BLACKFIN =    106;\nenum EM_SE_C33 =      107;\nenum EM_SEP =         108;\nenum EM_ARCA =        109;\nenum EM_UNICORE =     110;\nenum EM_DXP =         112;\nenum EM_ALTERA_NIOS2 =113;\nenum EM_CRX =         114;\nenum EM_XGATE =       115;\nenum EM_C166  =       116;\nenum EM_M16C  =       117;\nenum EM_DSPIC30F =    118;\nenum EM_CE =          119;\nenum EM_M32C  =       120;\nenum EM_res121 =      121;\nenum EM_res122 =      122;\nenum EM_res123 =      123;\nenum EM_res124 =      124;\nenum EM_res125 =      125;\nenum EM_res126 =      126;\nenum EM_res127 =      127;\nenum EM_res128 =      128;\nenum EM_res129 =      129;\nenum EM_res130 =      130;\nenum EM_TSK3000 =     131;\nenum EM_RS08  =       132;\nenum EM_res133 =      133;\nenum EM_ECOG2 =       134;\nenum EM_SCORE =       135;\nenum EM_SCORE7 =      135;\nenum EM_DSP24 =       136;\nenum EM_VIDEOCORE3 =  137;\nenum EM_LATTICEMICO32 = 138;\nenum EM_SE_C17 =      139;\nenum EM_TI_C6000 =    140;\nenum EM_TI_C2000 =    141;\nenum EM_TI_C5500 =    142;\nenum EM_res143 =      143;\nenum EM_res144 =      144;\nenum EM_res145 =      145;\nenum EM_res146 =      146;\nenum EM_res147 =      147;\nenum EM_res148 =      148;\nenum EM_res149 =      149;\nenum EM_res150 =      150;\nenum EM_res151 =      151;\nenum EM_res152 =      152;\nenum EM_res153 =      153;\nenum EM_res154 =      154;\nenum EM_res155 =      155;\nenum EM_res156 =      156;\nenum EM_res157 =      157;\nenum EM_res158 =      158;\nenum EM_res159 =      159;\nenum EM_MMDSP_PLUS =  160;\nenum EM_CYPRESS_M8C = 161;\nenum EM_R32C  =       162;\nenum EM_TRIMEDIA =    163;\nenum EM_QDSP6 =       164;\nenum EM_8051  =       165;\nenum EM_STXP7X =      166;\nenum EM_NDS32 =       167;\nenum EM_ECOG1 =       168;\nenum EM_ECOG1X =      168;\nenum EM_MAXQ30 =      169;\nenum EM_XIMO16 =      170;\nenum EM_MANIK =       171;\nenum EM_CRAYNV2 =     172;\nenum EM_RX =          173;\nenum EM_METAG =       174;\nenum EM_MCST_ELBRUS = 175;\nenum EM_ECOG16 =      176;\nenum EM_CR16  =       177;\nenum EM_ETPU  =       178;\nenum EM_SLE9X =       179;\nenum EM_L1OM  =       180;\nenum EM_K1OM  =       181;\nenum EM_INTEL182 =    182;\nenum EM_res183 =      183;\nenum EM_res184 =      184;\nenum EM_AVR32 =       185;\nenum EM_STM8  =       186;\nenum EM_TILE64 =      187;\nenum EM_TILEPRO =     188;\nenum EM_MICROBLAZE =  189;\nenum EM_CUDA  =       190;\nenum EM_TILEGX =      191;\n\nenum EM_486 =           6;\nenum EM_MIPS_RS4_BE =  10;\nenum EM_ALPHA_STD =    41;\nenum EM_ALPHA =    0x9026;\n\nenum SHN_UNDEF =       0;\nenum SHN_LORESERVE =   0xff00;\nenum SHN_LOPROC =      0xff00;\nenum SHN_HIPROC =      0xff1f;\nenum SHN_LOOS =        0xff20;\nenum SHN_HIOS =        0xff3f;\nenum SHN_ABS =         0xfff1;\nenum SHN_COMMON =      0xfff2;\nenum SHN_XINDEX =      0xffff;\nenum SHN_HIRESERVE =   0xffff;\n\nenum PT_NULL =         0;\nenum PT_LOAD =         1;\nenum PT_DYNAMIC =      2;\nenum PT_INTERP =       3;\nenum PT_NOTE =         4;\nenum PT_SHLIB =        5;\nenum PT_PHDR =         6;\nenum PT_TLS =          7;\nenum PT_LOOS =         0x60000000;\nenum PT_HIOS =         0x6fffffff;\nenum PT_LOPROC =       0x70000000;\nenum PT_HIPROC =       0x7fffffff;\n\nenum PT_GNU_EH_FRAME =  PT_LOOS + 0x474e550; /* Frame unwind information */\nenum PT_SUNW_EH_FRAME = PT_GNU_EH_FRAME;     /* Solaris uses the same value */\nenum PT_GNU_STACK =     PT_LOOS + 0x474e551; /* Stack flags */\nenum PT_GNU_RELRO =     PT_LOOS + 0x474e552;  /* Read-only after relocation */\n\nenum PF_X =            0x1;\nenum PF_W =            0x2;\nenum PF_R =            0x4;\nenum PF_MASKOS =       0x0ff00000;\nenum PF_MASKPROC =     0xf0000000;\n\nenum PN_XNUM =         0xffff;\n\nenum SHT_NULL =          0;\nenum SHT_PROGBITS =      1;\nenum SHT_SYMTAB =        2;\nenum SHT_STRTAB =        3;\nenum SHT_RELA =          4;\nenum SHT_HASH =          5;\nenum SHT_DYNAMIC =       6;\nenum SHT_NOTE =          7;\nenum SHT_NOBITS =        8;\nenum SHT_REL =           9;\nenum SHT_SHLIB =         10;\nenum SHT_DYNSYM =        11;\n\nenum SHT_INIT_ARRAY =    14;\nenum SHT_FINI_ARRAY =    15;\nenum SHT_PREINIT_ARRAY = 16;\nenum SHT_GROUP =         17;\nenum SHT_SYMTAB_SHNDX =  18;\n\nenum SHT_LOOS =          0x60000000;\nenum SHT_LOSUNW =        0x6ffffff4;\n\nenum SHT_GNU_INCREMENTAL_INPUTS =  0x6fff4700;\nenum SHT_GNU_ATTRIBUTES =       0x6ffffff5;\nenum SHT_GNU_HASH =             0x6ffffff6;\nenum SHT_GNU_LIBLIST =          0x6ffffff7;\n\n//enum SHT_SUNW_dof =      0x6ffffff4;\n//enum SHT_SUNW_cap =      0x6ffffff5;\n//enum SHT_SUNW_SIGNATURE = 0x6ffffff6;\nenum SHT_SUNW_verdef =   0x6ffffffd;\nenum SHT_SUNW_verneed =  0x6ffffffe;\nenum SHT_SUNW_versym =   0x6fffffff;\n\nenum SHT_GNU_verdef =    SHT_SUNW_verdef;\nenum SHT_GNU_verneed =   SHT_SUNW_verneed;\nenum SHT_GNU_versym =    SHT_SUNW_versym;\n\nenum SHT_LOPROC =        0x70000000;\nenum SHT_HIPROC =        0x7fffffff;\nenum SHT_LOUSER =        0x80000000;\nenum SHT_HIUSER =        0x8fffffff;\n\n/*\nenum SHT_GNU_HASH =      0x6ffffff6;\nenum SHT_SUNW_ANNOTATE = 0x6ffffff7;\nenum SHT_SUNW_DEBUGSTR = 0x6ffffff8;\nenum SHT_SUNW_DEBUG =    0x6ffffff9;\nenum SHT_SUNW_move =     0x6ffffffa;\nenum SHT_SUNW_COMDAT =   0x6ffffffb;\nenum SHT_SUNW_syminfo =  0x6ffffffc;\nenum SHT_HISUNW =        0x6fffffff;\nenum SHT_HIOS =          0x6fffffff;\nenum SHT_AMD64_UNWIND =  0x70000001;\nenum SHT_ARM_EXIDX =     0x70000001;\nenum SHT_ARM_PREEMPTMAP = 0x70000002;\nenum SHT_ARM_ATTRIBUTES = 0x70000003;\nenum SHT_ARM_DEBUGOVERLAY = 0x70000004;\nenum SHT_ARM_OVERLAYSECTION = 0x70000005;\nenum SHT_MIPS_REGINFO =  0x70000006;\nenum SHT_MIPS_OPTIONS =  0x7000000d;\nenum SHT_MIPS_DWARF =    0x7000001e;\n*/\n\nenum SHF_WRITE =            (1 << 0);\nenum SHF_ALLOC =            (1 << 1);\nenum SHF_EXECINSTR =        (1 << 2);\nenum SHF_MERGE =            (1 << 4);\nenum SHF_STRINGS =          (1 << 5);\nenum SHF_INFO_LINK =        (1 << 6);\nenum SHF_LINK_ORDER =       (1 << 7);\nenum SHF_OS_NONCONFORMING = (1 << 8);\nenum SHF_GROUP =            (1 << 9);\nenum SHF_TLS =              (1 << 10);\nenum SHF_COMPRESSED =       (1 << 11);\n\nenum SHF_MASKOS =           0x0ff00000;\nenum SHF_MASKPROC =         0xf0000000;\n\nenum NT_PRSTATUS =     1;\nenum NT_FPREGSET =     2;\nenum NT_PRPSINFO =     3;\nenum NT_TASKSTRUCT =   4;\nenum NT_AUXV =         6;\n\n/*\nenum NT_THRMISC =      7;\nenum NT_PROCSTAT_PROC = 8;\nenum NT_PROCSTAT_FILES = 9;\nenum NT_PROCSTAT_VMMAP = 10;\nenum NT_PROCSTAT_GROUPS = 11;\nenum NT_PROCSTAT_UMASK = 12;\nenum NT_PROCSTAT_RLIMIT = 13;\nenum NT_PROCSTAT_OSREL = 14;\nenum NT_PROCSTAT_PSSTRINGS = 15;\nenum NT_PROCSTAT_AUXV = 16;\n*/\n\nenum STN_UNDEF =       0;\n\nenum STB_LOCAL =       0;\nenum STB_GLOBAL =      1;\nenum STB_WEAK =        2;\nenum STB_NUM =         3;\nenum STB_LOOS =        10;\nenum STB_HIOS =        12;\nenum STB_LOPROC =      13;\nenum STB_HIPROC =      15;\n\nenum STT_NOTYPE =      0;\nenum STT_OBJECT =      1;\nenum STT_FUNC =        2;\nenum STT_SECTION =     3;\nenum STT_FILE =        4;\nenum STT_COMMON =      5;\nenum STT_TLS =         6;\nenum STT_NUM =         7;\nenum STT_LOOS =        10;\nenum STT_GNU_IFUNC =   10;\nenum STT_HIOS =        12;\nenum STT_LOPROC =      13;\nenum STT_HIPROC =      15;\n\nenum STV_DEFAULT =     0;\nenum STV_INTERNAL =    1;\nenum STV_HIDDEN =      2;\nenum STV_PROTECTED =   3;\n/*\nenum STV_EXPORTED =    4;\nenum STV_SINGLETON =   5;\nenum STV_ELIMINATE =   6;\n*/\n\nenum DT_NULL =         0;\nenum DT_NEEDED =       1;\nenum DT_PLTRELSZ =     2;\nenum DT_PLTGOT =       3;\nenum DT_HASH =         4;\nenum DT_STRTAB =       5;\nenum DT_SYMTAB =       6;\nenum DT_RELA =         7;\nenum DT_RELASZ =       8;\nenum DT_RELAENT =      9;\nenum DT_STRSZ =        10;\nenum DT_SYMENT =       11;\nenum DT_INIT =         12;\nenum DT_FINI =         13;\nenum DT_SONAME =       14;\nenum DT_RPATH =        15;\nenum DT_SYMBOLIC =     16;\nenum DT_REL =          17;\nenum DT_RELSZ =        18;\nenum DT_RELENT =       19;\nenum DT_PLTREL =       20;\nenum DT_DEBUG =        21;\nenum DT_TEXTREL =      22;\nenum DT_JMPREL =       23;\nenum DT_BIND_NOW =     24;\nenum DT_INIT_ARRAY =   25;\nenum DT_FINI_ARRAY =   26;\nenum DT_INIT_ARRAYSZ = 27;\nenum DT_FINI_ARRAYSZ = 28;\nenum DT_RUNPATH =      29;\nenum DT_FLAGS =        30;\n\nenum DT_ENCODING =     32;\nenum DT_PREINIT_ARRAY = 32;\nenum DT_PREINIT_ARRAYSZ = 33;\n//enum DT_MAXPOSTAGS =   34;\nenum DT_LOOS =         0x6000000d;\nenum DT_HIOS =         0x6ffff000;\n/*\nenum DT_SUNW_AUXILIARY = 0x6000000d;\nenum DT_SUNW_RTLDINF = 0x6000000e;\nenum DT_SUNW_FILTER =  0x6000000f;\nenum DT_SUNW_CAP =     0x60000010;\n*/\n\nenum DT_VALRNGLO =     0x6ffffd00;\nenum DT_GNU_PRELINKED = 0x6ffffdf5;\nenum DT_GNU_CONFLICTSZ =0x6ffffdf6;\nenum DT_GNU_LIBLISTSZ = 0x6ffffdf7;\nenum DT_CHECKSUM =     0x6ffffdf8;\nenum DT_PLTPADSZ =     0x6ffffdf9;\nenum DT_MOVEENT =      0x6ffffdfa;\nenum DT_MOVESZ =       0x6ffffdfb;\nenum DT_FEATURE_1 =    0x6ffffdfc;\nenum DT_POSFLAG_1 =    0x6ffffdfd;\nenum DT_SYMINSZ =      0x6ffffdfe;\nenum DT_SYMINENT =     0x6ffffdff;\nenum DT_VALRNGHI =     0x6ffffdff;\nenum DT_ADDRRNGLO =    0x6ffffe00;\nenum DT_GNU_HASH =     0x6ffffef5;\nenum DT_TLSDESC_PLT =  0x6ffffef6;\nenum DT_TLSDESC_GOT =  0x6ffffef7;\nenum DT_GNU_CONFLICT = 0x6ffffef8;\nenum DT_GNU_LIBLIST =  0x6ffffef9;\nenum DT_CONFIG =       0x6ffffefa;\nenum DT_DEPAUDIT =     0x6ffffefb;\nenum DT_AUDIT =        0x6ffffefc;\nenum DT_PLTPAD =       0x6ffffefd;\nenum DT_MOVETAB =      0x6ffffefe;\nenum DT_SYMINFO =      0x6ffffeff;\nenum DT_ADDRRNGHI =    0x6ffffeff;\nenum DT_RELACOUNT =    0x6ffffff9;\nenum DT_RELCOUNT =     0x6ffffffa;\nenum DT_FLAGS_1 =      0x6ffffffb;\nenum DT_VERDEF =       0x6ffffffc;\nenum DT_VERDEFNUM =    0x6ffffffd;\nenum DT_VERNEED =      0x6ffffffe;\nenum DT_VERNEEDNUM =   0x6fffffff;\nenum DT_VERSYM =       0x6ffffff0;\nenum DT_LOPROC =       0x70000000;\n//enum DT_DEPRECATED_SPARC_REGISTER = 0x7000001;\nenum DT_AUXILIARY =    0x7ffffffd;\nenum DT_USED =         0x7ffffffe;\nenum DT_FILTER =       0x7fffffff;\nenum DT_HIPROC =       0x7fffffff;\n\nenum DTF_1_PARINIT =   0x00000001;\nenum DTF_1_CONFEXP =   0x00000002;\n\nenum DF_P1_LAZYLOAD =  0x00000001;\nenum DF_P1_GROUPPERM=  0x00000002;\n\nenum DF_1_NOW =        0x00000001;\nenum DF_1_BIND_NOW =   0x00000001;\nenum DF_1_GLOBAL =     0x00000002;\nenum DF_1_GROUP =      0x00000004;\nenum DF_1_NODELETE =   0x00000008;\nenum DF_1_LOADFLTR =   0x00000010;\nenum DF_1_INITFIRST =  0x00000020;\nenum DF_1_NOOPEN =     0x00000040;\nenum DF_1_ORIGIN =     0x00000080;\nenum DF_1_DIRECT =     0x00000100;\nenum DF_1_TRANS =      0x00000200;\nenum DF_1_INTERPOSE =  0x00000400;\nenum DF_1_NODEFLIB =   0x00000800;\nenum DF_1_NODUMP =     0x00001000;\nenum DF_1_CONLFAT =    0x00002000;\n\nenum DF_ORIGIN =       0x00000001;\nenum DF_SYMBOLIC =     0x00000002;\nenum DF_TEXTREL =      0x00000004;\nenum DF_BIND_NOW =     0x00000008;\nenum DF_STATIC_TLS =   0x00000010;\n\nenum VER_DEF_NONE =    0;\nenum VER_DEF_CURRENT = 1;\nalias VER_NDX VER_DEF_IDX;\n\nenum VER_FLG_BASE =    0x1;\nenum VER_FLG_WEAK =    0x2;\nenum VER_FLG_INFO =    0x4;\n\nenum VER_NDX_LOCAL =           0;\nenum VER_NDX_GLOBAL =          1;\nenum VER_NDX_GIVEN =           2;\nenum VER_NDX_HIDDEN =      32768;\nextern (D) pure @safe\n{\n    auto VER_NDX(V)(V v) { return v & ~(1u << 15); }\n}\n\nenum VER_NEED_NONE   = 0;\nenum VER_NEED_CURRENT = 1;\nenum VER_NEED_WEAK =    32768;\nenum VER_NEED_HIDDEN = VER_NDX_HIDDEN;\nalias VER_NDX VER_NEED_IDX;\n\n/*\nenum CA_SUNW_NULL =    0;\nenum CA_SUNW_HW_1 =    1;\nenum CA_SUNW_SF_1 =    2;\n*/\n\nenum VERSYM_HIDDEN =   0x8000;\nenum VERSYM_VERSION =  0x7fff;\nenum ELF_VER_CHR =     '@';\n\nenum SYMINFO_BT_SELF =         0xffff;\nenum SYMINFO_BT_PARENT =       0xfffe;\n//enum SYMINFO_BT_NONE =         0xfffd;\n//enum SYMINFO_BT_EXTERN =       0xfffc;\nenum SYMINFO_BT_LOWRESERVE =   0xff00;\n\nenum SYMINFO_FLG_DIRECT =      0x0001;\nenum SYMINFO_FLG_PASSTHRU =    0x0002;\nenum SYMINFO_FLG_COPY =        0x0004;\nenum SYMINFO_FLG_LAZYLOAD =    0x0008;\n//enum SYMINFO_FLG_DIRECTBIND =  0x0010;\n//enum SYMINFO_FLG_NOEXTDIRECT = 0x0020;\n//enum SYMINFO_FLG_FILTER =      0x0002;\n//enum SYMINFO_FLG_AUXILIARY =   0x0040;\n\nenum SYMINFO_NONE =            0;\nenum SYMINFO_CURRENT =         1;\nenum SYMINFO_NUM =             2;\n\nenum GRP_COMDAT =              0x1;\n\nenum R_386_NONE =               0;\nenum R_386_32 =                 1;\nenum R_386_PC32 =               2;\nenum R_386_GOT32 =              3;\nenum R_386_PLT32 =              4;\nenum R_386_COPY =               5;\nenum R_386_GLOB_DAT =           6;\nenum R_386_JMP_SLOT =           7;\nenum R_386_RELATIVE =           8;\nenum R_386_GOTOFF =             9;\nenum R_386_GOTPC =              10;\nenum R_386_TLS_TPOFF =          14;\nenum R_386_TLS_IE =             15;\nenum R_386_TLS_GOTIE =          16;\nenum R_386_TLS_LE =             17;\nenum R_386_TLS_GD =             18;\nenum R_386_TLS_LDM =            19;\nenum R_386_TLS_GD_32 =          24;\nenum R_386_TLS_GD_PUSH =        25;\nenum R_386_TLS_GD_CALL =        26;\nenum R_386_TLS_GD_POP =         27;\nenum R_386_TLS_LDM_32 =         28;\nenum R_386_TLS_LDM_PUSH =       29;\nenum R_386_TLS_LDM_CALL =       30;\nenum R_386_TLS_LDM_POP =        31;\nenum R_386_TLS_LDO_32 =         32;\nenum R_386_TLS_IE_32 =          33;\nenum R_386_TLS_LE_32 =          34;\nenum R_386_TLS_DTPMOD32 =       35;\nenum R_386_TLS_DTPOFF32 =       36;\nenum R_386_TLS_TPOFF32 =        37;\nenum R_386_IRELATIVE =          42;\n\nenum R_X86_64_NONE =            0;\nenum R_X86_64_64 =              1;\nenum R_X86_64_PC32 =            2;\nenum R_X86_64_GOT32 =           3;\nenum R_X86_64_PLT32 =           4;\nenum R_X86_64_COPY =            5;\nenum R_X86_64_GLOB_DAT =        6;\nenum R_X86_64_JMP_SLOT =        7;\nenum R_X86_64_RELATIVE =        8;\nenum R_X86_64_GOTPCREL =        9;\nenum R_X86_64_32 =              10;\nenum R_X86_64_32S =             11;\nenum R_X86_64_16 =              12;\nenum R_X86_64_PC16 =            13;\nenum R_X86_64_8 =               14;\nenum R_X86_64_PC8 =             15;\nenum R_X86_64_DTPMOD64 =        16;\nenum R_X86_64_DTPOFF64 =        17;\nenum R_X86_64_TPOFF64 =         18;\nenum R_X86_64_TLSGD =           19;\nenum R_X86_64_TLSLD =           20;\nenum R_X86_64_DTPOFF32 =        21;\nenum R_X86_64_GOTTPOFF =        22;\nenum R_X86_64_TPOFF32 =         23;\nenum R_X86_64_IRELATIVE =       37;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/sys/event.d",
    "content": "/**\n * D header file for DragonFlyBSD.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak,Diederik de Groot(port:DragonFlyBSD)\n * Copied:    From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.sys.event;\n\nversion (DragonFlyBSD):\n\nextern (C) nothrow @nogc @system:\n\nimport core.stdc.stdint;    // intptr_t, uintptr_t\nimport core.sys.posix.time; // timespec\n\nenum\n{\n    EVFILT_READ     =  -1,\n    EVFILT_WRITE    =  -2,\n    EVFILT_AIO      =  -3, /* attached to aio requests */\n    EVFILT_VNODE    =  -4, /* attached to vnodes */\n    EVFILT_PROC     =  -5, /* attached to struct proc */\n    EVFILT_SIGNAL   =  -6, /* attached to struct proc */\n    EVFILT_TIMER    =  -7, /* timers */\n    EVFILT_EXCEPT   =  -8, /* exceptional conditions */\n    EVFILT_USER     =  -9, /* user events */\n    EVFILT_FS       = -10, /* filesystem events */\n    EVFILT_MARKER   = 0xF, /* placemarker for tailq */\n    EVFILT_SYSCOUNT =  10,\n}\n\nextern(D) void EV_SET(kevent_t* kevp, typeof(kevent_t.tupleof) args)\n{\n    *kevp = kevent_t(args);\n}\n\nstruct kevent_t\n{\n    uintptr_t    ident; /* identifier for this event */\n    short       filter; /* filter for event */\n    ushort       flags;\n    uint        fflags;\n    intptr_t      data;\n    void        *udata; /* opaque user data identifier */\n}\n\nenum\n{\n    /* actions */\n    EV_ADD          = 0x0001, /* add event to kq (implies enable) */\n    EV_DELETE       = 0x0002, /* delete event from kq */\n    EV_ENABLE       = 0x0004, /* enable event */\n    EV_DISABLE      = 0x0008, /* disable event (not reported) */\n\n    /* flags */\n    EV_ONESHOT      = 0x0010, /* only report one occurrence */\n    EV_CLEAR        = 0x0020, /* clear event state after reporting */\n    EV_RECEIPT      = 0x0040, /* force EV_ERROR on success, data=0 */\n    EV_DISPATCH     = 0x0080, /* disable event after reporting */\n\n    EV_SYSFLAGS     = 0xF000, /* reserved by system */\n    EV_FLAG1        = 0x2000, /* filter-specific flag */\n\n    /* returned values */\n    EV_EOF          = 0x8000, /* EOF detected */\n    EV_ERROR        = 0x4000, /* error, data contains errno */\n    EV_NODATA       = 0x1000, /* EOF and no more data */\n}\n\nenum\n{\n    /*\n     * data/hint flags/masks for EVFILT_USER, shared with userspace\n     *\n     * On input, the top two bits of fflags specifies how the lower twenty four\n     * bits should be applied to the stored value of fflags.\n     *\n     * On output, the top two bits will always be set to NOTE_FFNOP and the\n     * remaining twenty four bits will contain the stored fflags value.\n     */\n    NOTE_FFNOP      = 0x00000000, /* ignore input fflags */\n    NOTE_FFAND      = 0x40000000, /* AND fflags */\n    NOTE_FFOR       = 0x80000000, /* OR fflags */\n    NOTE_FFCOPY     = 0xc0000000, /* copy fflags */\n    NOTE_FFCTRLMASK = 0xc0000000, /* masks for operations */\n    NOTE_FFLAGSMASK = 0x00ffffff,\n\n    NOTE_TRIGGER    = 0x01000000, /* Cause the event to be\n                                  triggered for output. */\n\n    /*\n     * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace\n     */\n    NOTE_LOWAT      = 0x0001, /* low water mark */\n    NOTE_OOB        = 0x0002, /* OOB data on a socket */\n\n    /*\n     * data/hint flags for EVFILT_VNODE, shared with userspace\n     */\n    NOTE_DELETE     = 0x0001, /* vnode was removed */\n    NOTE_WRITE      = 0x0002, /* data contents changed */\n    NOTE_EXTEND     = 0x0004, /* size increased */\n    NOTE_ATTRIB     = 0x0008, /* attributes changed */\n    NOTE_LINK       = 0x0010, /* link count changed */\n    NOTE_RENAME     = 0x0020, /* vnode was renamed */\n    NOTE_REVOKE     = 0x0040, /* vnode access was revoked */\n\n    NOTE_EXIT       = 0x80000000, /* process exited */\n    NOTE_FORK       = 0x40000000, /* process forked */\n    NOTE_EXEC       = 0x20000000, /* process exec'd */\n    NOTE_PCTRLMASK  = 0xf0000000, /* mask for hint bits */\n    NOTE_PDATAMASK  = 0x000fffff, /* mask for pid */\n\n    /* additional flags for EVFILT_PROC */\n    NOTE_TRACK      = 0x00000001, /* follow across forks */\n    NOTE_TRACKERR   = 0x00000002, /* could not track child */\n    NOTE_CHILD      = 0x00000004, /* am a child process */\n}\n\nint kqueue();\nint kevent(int kq, const kevent_t *changelist, int nchanges,\n           int nevents, const timespec *timeout);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/sys/link_elf.d",
    "content": "/**\n * D header file for DragonFlyBSD.\n *\n * $(LINK2 http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?view=markup, sys/link_elf.h)\n * Authors: Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.sys.link_elf;\n\nversion (DragonFlyBSD):\n\nextern (C) nothrow @system:\n\nimport core.stdc.stdint : uint64_t;\nimport core.sys.dragonflybsd.sys.elf;\n\nversion (D_LP64)\n    enum __ELF_NATIVE_CLASS = 64;\nelse\n    enum __ELF_NATIVE_CLASS = 32;\n\ntemplate ElfW(string type)\n{\n    mixin(\"alias Elf\"~__ELF_NATIVE_CLASS.stringof~\"_\"~type~\" ElfW;\");\n}\n\nenum LA_SER_ORIG =      0x01;\nenum LA_SER_LIBPATH =   0x02;\nenum LA_SER_RUNPATH =   0x04;\nenum LA_SER_CONFIG =    0x08;\nenum LA_SER_DEFAULT =   0x40;\nenum LA_SER_SECURE =    0x80;\n\nstruct link_map\n{\n    char*           l_addr;\n\n    version (MIPS32)\n        char*       l_offs;\n    version (MIPS64)\n        char*       l_offs;\n\n    char*           l_name;\n    void*           l_ld;\n    link_map*       l_next, l_prev;\n}\nalias link_map Link_map;\n\nenum\n{\n    RT_CONSISTENT,\n    RT_ADD,\n    RT_DELETE,\n}\n\nstruct r_debug\n{\n    int             r_version;\n    link_map*       r_map;\n    void function(r_debug*, link_map*) r_brk;\n};\n\nstruct dl_phdr_info\n{\n    ElfW!\"Addr\"     dlpi_addr;\n    char*           dlpi_name;\n    ElfW!\"Phdr\"*    dlpi_phdr;\n    ElfW!\"Half\"     dlpi_phnum;\n    uint64_t        dlpi_adds;\n    uint64_t        dlpi_subs;\n    size_t          dlpi_tls_modid;\n    void*           dlpi_tls_data;\n};\n\n\nprivate alias int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;\nprivate alias int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_cb_ngc;\n\nint dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data);\nint dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc;\nint _rtld_addr_phdr(const void*, dl_phdr_info*) @nogc;\nint _rtld_get_stack_prot() @nogc;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/sys/mman.d",
    "content": "/**\n * D header file for DragonFlyBSD\n *\n * Authors:   Martin Nowak,Diederik de Groot(port:DragonFlyBSD)\n * Copied:  From core/sys/freebsd/sys\n */\nmodule core.sys.dragonflybsd.sys.mman;\n\nversion (DragonFlyBSD):\nextern (C) nothrow @nogc @system:\n\npublic import core.sys.posix.sys.mman;\nimport core.sys.dragonflybsd.sys.cdefs;\nimport core.sys.posix.sys.types;\n\nenum INHERIT_SHARE        = 0;\nenum INHERIT_COPY         = 1;\nenum INHERIT_NONE         = 2;\n\n// already in core.sys.posix.sys.mman\n// enum PROT_NONE             = 0x00;\n// enum PROT_READ             = 0x01;\n// enum PROT_WRITE            = 0x02;\n// enum PROT_EXEC             = 0x04;\n// enum MAP_SHARED            = 0x0001;\n// enum MAP_PRIVATE           = 0x0002;\nalias MAP_COPY            = MAP_PRIVATE;\n\nenum MAP_FIXED                = 0x00010;\nenum MAP_RENAME           = 0x00020;\nenum MAP_NORESERVE        = 0x00040;\nenum MAP_INHERIT          = 0x00080;\nenum MAP_NOEXTEND         = 0x00100;\nenum MAP_HASSEMAPHORE     = 0x00200;\nenum MAP_STACK            = 0x00400;\nenum MAP_NOSYNC           = 0x00800;\n\nenum MAP_FILE             = 0x00000;\n//enum MAP_ANON           = 0x01000;        // already in core.sys.posix.sys.mman\nalias MAP_ANONYMOUS       = MAP_ANON;\nenum MAP_VPAGETABLE       = 0x02000;\n\nenum MAP_TRYFIXED         = 0x10000;\nenum MAP_NOCORE           = 0x20000;\nenum MAP_SIZEALIGN        = 0x40000;\n\n//enum MAP_EXCL           = 0x00004000;\n//enum MAP_NOCORE         = 0x00020000;\n//enum MAP_PREFAULT_READ  = 0x00040000;\n//version (LP64)\n//    enum MAP_32BIT      = 0x00080000;\n\n//extern(D) int MAP_ALIGNED(int n) { return n << MAP_ALIGNMENT_SHIFT; }\n//enum MAP_ALIGNMENT_SHIFT = 24;\n//enum MAP_ALIGNMENT_MASK = MAP_ALIGNED(0xff);\n//enum MAP_ALIGNED_SUPER = MAP_ALIGNED(1);\n\n// enum MCL_CURRENT       = 0x0001;           // already in core.sys.posix.sys.mman\n// enum MCL_FUTURE        = 0x0002;            // already in core.sys.posix.sys.mman\n\n// already in core.sys.posix.sys.mman\nenum MAP_FAILED = cast(void*)-1;\n// enum MS_SYNC               = 0x0000;         // already in core.sys.posix.sys.mman\n// enum MS_ASYNC              = 0x0001;         // already in core.sys.posix.sys.mman\n// enum MS_INVALIDATE         = 0x0002;         // already in core.sys.posix.sys.mman\n\nenum _MADV_NORMAL             = 0;\nenum _MADV_RANDOM             = 1;\nenum _MADV_SEQUENTIAL         = 2;\nenum _MADV_WILLNEED           = 3;\nenum _MADV_DONTNEED           = 4;\n\nalias MADV_NORMAL         = _MADV_NORMAL;\nalias MADV_RANDOM         = _MADV_RANDOM;\nalias MADV_SEQUENTIAL     = _MADV_SEQUENTIAL;\nalias MADV_WILLNEED       = _MADV_WILLNEED;\nalias MADV_DONTNEED       = _MADV_DONTNEED;\nenum MADV_FREE            = 5;\nenum MADV_NOSYNC          = 6;\nenum MADV_AUTOSYNC        = 7;\nenum MADV_NOCORE          = 8;\nenum MADV_CORE            = 9;\nenum MADV_INVAL           = 10;\nenum MADV_SETMAP          = 11;\n\nalias MADV_CONTROL_START  = MADV_INVAL;\nalias MADV_CONTROL_END    = MADV_SETMAP;\n\nenum MINCORE_INCORE       = 0x1;\nenum MINCORE_REFERENCED   = 0x2;\nenum MINCORE_MODIFIED     = 0x4;\nenum MINCORE_REFERENCED_OTHER = 0x8;\nenum MINCORE_MODIFIED_OTHER   = 0x10;\nenum MINCORE_SUPER        = 0x20;\n\nenum SHM_ANON             = cast(const(char) *)1;\n\n// already in core.sys.posix.sys.mman\n// alias POSIX_MADV_NORMAL    = _MADV_NORMAL;\n// alias POSIX_MADV_RANDOM    = _MADV_RANDOM;\n// alias POSIX_MADV_SEQUENTIAL= _MADV_SEQUENTIAL;\n// alias POSIX_MADV_WILLNEED  = _MADV_WILLNEED;\n// alias POSIX_MADV_DONTNEED  = _MADV_DONTNEED;\n\nint getpagesizes(size_t *, int);\nint madvise(void *, size_t, int);\nint mincore(const(void) *, size_t, char *);\nint minherit(void *, size_t, int);\n\n// already in core.sys.posix.sys.mman\n// int mlock(const void *, size_t);\n// void * mmap(void *, size_t, int, int, int, off_t);\n// int mprotect(const void *, size_t, int);\n// int msync(void *, size_t, int);\n// int munlock(const void *, size_t);\n// int munmap(void *, size_t);\n// int posix_madvise(void *, size_t, int);\n\n// int mlockall(int);\n// int munlockall();\n// int shm_open(const(char) *, int, mode_t);\n// int shm_unlink(const(char) *);\n\n// int madvise(void *, size_t, int);\n// int mcontrol(void *, size_t, int, off_t);\n// int mincore(const void *, size_t, char *);\n// int minherit(void *, size_t, int);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/dragonflybsd/time.d",
    "content": "/**\n    D header file for DragonFlyBSD's extensions to POSIX's time.h.\n\n    Copyright: Copyright 2014\n    License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors: $(HTTP jmdavisprog.com, Jonathan M Davis) and Diederik de Groot\n */\nmodule core.sys.dragonflybsd.time;\n\nversion (DragonFlyBSD):\n\npublic import core.sys.posix.time;\n\nimport core.sys.dragonflybsd.sys.cdefs;\n\nenum CLOCK_REALTIME          = 0;\nenum CLOCK_VIRTUAL           = 1;\nenum CLOCK_PROF              = 2;\nenum CLOCK_MONOTONIC         = 4;\nenum CLOCK_UPTIME            = 5;\nenum CLOCK_UPTIME_PRECISE    = 7;\nenum CLOCK_UPTIME_FAST       = 8;\nenum CLOCK_REALTIME_PRECISE  = 9;\nenum CLOCK_REALTIME_FAST     = 10;\nenum CLOCK_MONOTONIC_PRECISE = 11;\nenum CLOCK_MONOTONIC_FAST    = 12;\nenum CLOCK_SECOND            = 13;\nenum CLOCK_THREAD_CPUTIME_ID = 14;\nenum CLOCK_PROCESS_CPUTIME_ID= 15;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/dlfcn.d",
    "content": "/**\n * D header file for FreeBSD.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n */\nmodule core.sys.freebsd.dlfcn;\n\npublic import core.sys.posix.dlfcn;\n\nversion (FreeBSD):\nextern (C):\nnothrow:\n@nogc:\n\nenum __BSD_VISIBLE = true;\n\n/*\n * Modes and flags for dlopen().\n */\nstatic assert(RTLD_LAZY   == 1);\nstatic assert(RTLD_NOW    == 2);\nenum RTLD_MODEMASK        =  0x3;\nstatic assert(RTLD_GLOBAL == 0x100);\nstatic assert(RTLD_LOCAL  == 0);\nenum RTLD_TRACE           =  0x200;\nenum RTLD_NODELETE        =  0x01000;\nenum RTLD_NOLOAD          =  0x02000;\n\n/*\n * Request arguments for dlinfo().\n */\nenum RTLD_DI_LINKMAP     = 2;    /* Obtain link map. */\nenum RTLD_DI_SERINFO     = 4;    /* Obtain search path info. */\nenum RTLD_DI_SERINFOSIZE = 5;    /*  ... query for required space. */\nenum RTLD_DI_ORIGIN      = 6;    /* Obtain object origin */\nenum RTLD_DI_MAX         = RTLD_DI_ORIGIN;\n\n/*\n * Special handle arguments for dlsym()/dlinfo().\n */\nenum RTLD_NEXT    = cast(void *)-1;    /* Search subsequent objects. */\nenum RTLD_DEFAULT = cast(void *)-2;    /* Use default search algorithm. */\nenum RTLD_SELF    = cast(void *)-3;    /* Search the caller itself. */\n\nstatic if (__BSD_VISIBLE)\n{\n    /*\n     * Structure filled in by dladdr().\n     */\n    struct Dl_info {\n        const(char)     *dli_fname;     /* Pathname of shared object. */\n        void            *dli_fbase;     /* Base address of shared object. */\n        const(char)     *dli_sname;     /* Name of nearest symbol. */\n        void            *dli_saddr;     /* Address of nearest symbol. */\n    };\n\n    /*-\n     * The actual type declared by this typedef is immaterial, provided that\n     * it is a function pointer.  Its purpose is to provide a return type for\n     * dlfunc() which can be cast to a function pointer type without depending\n     * on behavior undefined by the C standard, which might trigger a compiler\n     * diagnostic.  We intentionally declare a unique type signature to force\n     * a diagnostic should the application not cast the return value of dlfunc()\n     * appropriately.\n     */\n    struct __dlfunc_arg {\n        int     __dlfunc_dummy;\n    };\n\n    alias dlfunc_t = void function(__dlfunc_arg);\n\n    /*\n     * Structures, returned by the RTLD_DI_SERINFO dlinfo() request.\n     */\n    struct Dl_serpath {\n        char *          dls_name;       /* single search path entry */\n        uint            dls_flags;      /* path information */\n    };\n\n    struct Dl_serinfo {\n        size_t          dls_size;       /* total buffer size */\n        uint            dls_cnt;        /* number of path entries */\n        Dl_serpath[1]   dls_serpath;    /* there may be more than one */\n    };\n}\n\nprivate template __externC(RT, P...)\n{\n    alias __externC = extern(C) RT function(P) nothrow @nogc;\n}\n\n/* XSI functions first. */\nstatic assert(is(typeof(&dlclose) == __externC!(int, void*)));\nstatic assert(is(typeof(&dlerror) == __externC!(char*)));\nstatic assert(is(typeof(&dlopen)  == __externC!(void*, const char*, int)));\nstatic assert(is(typeof(&dlsym)   == __externC!(void*, void*, const char*)));\n\nstatic if (__BSD_VISIBLE)\n{\n    void*    fdlopen(int, int);\n    int      dladdr(const(void)*, Dl_info*);\n    dlfunc_t dlfunc(void*, const(char)*);\n    int      dlinfo(void*, int, void*);\n    void     dllockinit(void* _context,\n        void* function(void* _context) _lock_create,\n        void  function(void* _lock)    _rlock_acquire,\n        void  function(void* _lock)    _wlock_acquire,\n        void  function(void* _lock)    _lock_release,\n        void  function(void* _lock)    _lock_destroy,\n        void  function(void* _context) _context_destroy);\n    void*    dlvsym(void*, const(char)*, const(char)*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/execinfo.d",
    "content": "/**\n * FreeBSD implementation of glibc's $(LINK2 http://www.gnu.org/software/libc/manual/html_node/Backtraces.html backtrace) facility.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Martin Nowak\n * Source:    $(DRUNTIMESRC core/sys/freebsd/_execinfo.d)\n */\nmodule core.sys.freebsd.execinfo;\n\nversion (FreeBSD):\nextern (C):\nnothrow:\n\nimport core.sys.freebsd.dlfcn;\n\n// Use extern (D) so that these functions don't collide with libexecinfo.\n\nextern (D) int backtrace(void** buffer, int size)\n{\n    import core.thread : thread_stackBottom;\n\n    void** p, pend=cast(void**)thread_stackBottom();\n    version (D_InlineAsm_X86)\n        asm nothrow @trusted { mov p[EBP], EBP; }\n    else version (D_InlineAsm_X86_64)\n        asm nothrow @trusted { mov p[RBP], RBP; }\n    else\n        static assert(false, \"Architecture not supported.\");\n\n    int i;\n    for (; i < size && p < pend; ++i)\n    {\n        buffer[i] = *(p + 1);\n        auto pnext = cast(void**)*p;\n        if (pnext <= p) break;\n        p = pnext;\n    }\n    return i;\n}\n\n\nextern (D) char** backtrace_symbols(const(void*)* buffer, int size)\n{\n    static void* realloc(void* p, size_t len) nothrow\n    {\n        static import cstdlib=core.stdc.stdlib;\n        auto res = cstdlib.realloc(p, len);\n        if (res is null) cstdlib.free(p);\n        return res;\n    }\n\n    if (size <= 0) return null;\n\n    size_t pos = size * (char*).sizeof;\n    char** p = cast(char**)realloc(null, pos);\n    if (p is null) return null;\n\n    Dl_info info;\n    foreach (i, addr; buffer[0 .. size])\n    {\n        if (dladdr(addr, &info) == 0)\n            (cast(ubyte*)&info)[0 .. info.sizeof] = 0;\n        fixupDLInfo(addr, info);\n\n        immutable len = formatStackFrame(null, 0, addr, info);\n        assert(len > 0);\n\n        p = cast(char**)realloc(p, pos + len);\n        if (p is null) return null;\n\n        formatStackFrame(cast(char*)p + pos, len, addr, info) == len || assert(0);\n\n        p[i] = cast(char*)pos;\n        pos += len;\n    }\n    foreach (i; 0 .. size)\n    {\n        pos = cast(size_t)p[i];\n        p[i] = cast(char*)p + pos;\n    }\n    return p;\n}\n\n\nextern (D) void backtrace_symbols_fd(const(void*)* buffer, int size, int fd)\n{\n    import core.sys.posix.unistd : write;\n    import core.stdc.stdlib : alloca;\n\n    if (size <= 0) return;\n\n    Dl_info info;\n    foreach (i, addr; buffer[0 .. size])\n    {\n        if (dladdr(addr, &info) == 0)\n            (cast(ubyte*)&info)[0 .. info.sizeof] = 0;\n        fixupDLInfo(addr, info);\n\n        enum maxAlloca = 1024;\n        enum min = (size_t a, size_t b) => a <= b ? a : b;\n        immutable len = min(formatStackFrame(null, 0, addr, info), maxAlloca);\n        assert(len > 0);\n\n        auto p = cast(char*)alloca(len);\n        if (p is null) return;\n\n        formatStackFrame(p, len, addr, info) >= len || assert(0);\n        p[len - 1] = '\\n';\n        write(fd, p, len);\n    }\n}\n\n\nprivate void fixupDLInfo(const(void)* addr, ref Dl_info info)\n{\n    if (info.dli_fname is null) info.dli_fname = \"???\";\n    if (info.dli_fbase is null) info.dli_fbase = null;\n    if (info.dli_sname is null) info.dli_sname = \"???\";\n    if (info.dli_saddr is null) info.dli_saddr = cast(void*)addr;\n}\n\n\nprivate size_t formatStackFrame(char* p, size_t plen, const(void)* addr, const ref Dl_info info)\n{\n    import core.stdc.stdio : snprintf;\n\n    immutable off = addr - info.dli_saddr;\n    immutable len = snprintf(p, plen, \"%p <%s+%zd> at %s\",\n                             addr, info.dli_sname, off, info.dli_fname);\n    assert(len > 0);\n    return cast(size_t)len + 1; // + '\\0'\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/netinet/in_.d",
    "content": "//Written in the D programming language\n\n/++\n    D header file for FreeBSD's extensions to POSIX's netinet/in.h.\n\n    Copyright: Copyright 2017 -\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n +/\nmodule core.sys.freebsd.netinet.in_;\n\nimport core.sys.freebsd.sys.cdefs;\n\npublic import core.sys.posix.netinet.in_;\n\nversion (FreeBSD):\n\nextern(C) nothrow @nogc:\n\nstatic if (__BSD_VISIBLE)\n{\n    enum IPPROTO_HOPOPTS   = 0;\n\n    enum IPPROTO_IPV4      = 4;\n    enum IPPROTO_IPIP      = IPPROTO_IPV4;\n    enum IPPROTO_ST        = 7;\n    enum IPPROTO_EGP       = 8;\n    enum IPPROTO_PIGP      = 9;\n    enum IPPROTO_RCCMON    = 10;\n    enum IPPROTO_NVPII     = 11;\n\n    enum IPPROTO_ARGUS     = 13;\n    enum IPPROTO_EMCON     = 14;\n    enum IPPROTO_XNET      = 15;\n    enum IPPROTO_CHAOS     = 16;\n    enum IPPROTO_MUX       = 18;\n    enum IPPROTO_MEAS      = 19;\n    enum IPPROTO_HMP       = 20;\n    enum IPPROTO_PRM       = 21;\n\n    enum IPPROTO_TRUNK1    = 23;\n    enum IPPROTO_TRUNK2    = 24;\n    enum IPPROTO_LEAF1     = 25;\n    enum IPPROTO_LEAF2     = 26;\n    enum IPPROTO_RDP       = 27;\n    enum IPPROTO_IRTP      = 28;\n    enum IPPROTO_TP        = 29;\n    enum IPPROTO_BLT       = 30;\n    enum IPPROTO_NSP       = 31;\n    enum IPPROTO_INP       = 32;\n    enum IPPROTO_SEP       = 33;\n    enum IPPROTO_3PC       = 34;\n    enum IPPROTO_IDPR      = 35;\n    enum IPPROTO_XTP       = 36;\n    enum IPPROTO_DDP       = 37;\n    enum IPPROTO_CMTP      = 38;\n    enum IPPROTO_TPXX      = 39;\n    enum IPPROTO_IL        = 40;\n    enum IPPROTO_SDRP      = 42;\n    enum IPPROTO_ROUTING   = 43;\n    enum IPPROTO_FRAGMENT  = 44;\n    enum IPPROTO_IDRP      = 45;\n    enum IPPROTO_RSVP      = 46;\n    enum IPPROTO_GRE       = 47;\n    enum IPPROTO_MHRP      = 48;\n    enum IPPROTO_BHA       = 49;\n    enum IPPROTO_ESP       = 50;\n    enum IPPROTO_AH        = 51;\n    enum IPPROTO_INLSP     = 52;\n    enum IPPROTO_SWIPE     = 53;\n    enum IPPROTO_NHRP      = 54;\n    enum IPPROTO_MOBILE    = 55;\n    enum IPPROTO_TLSP      = 56;\n    enum IPPROTO_SKIP      = 57;\n    enum IPPROTO_ICMPV6    = 58;\n    enum IPPROTO_NONE      = 59;\n    enum IPPROTO_DSTOPTS   = 60;\n    enum IPPROTO_AHIP      = 61;\n    enum IPPROTO_CFTP      = 62;\n    enum IPPROTO_HELLO     = 63;\n    enum IPPROTO_SATEXPAK  = 64;\n    enum IPPROTO_KRYPTOLAN = 65;\n    enum IPPROTO_RVD       = 66;\n    enum IPPROTO_IPPC      = 67;\n    enum IPPROTO_ADFS      = 68;\n    enum IPPROTO_SATMON    = 69;\n    enum IPPROTO_VISA      = 70;\n    enum IPPROTO_IPCV      = 71;\n    enum IPPROTO_CPNX      = 72;\n    enum IPPROTO_CPHB      = 73;\n    enum IPPROTO_WSN       = 74;\n    enum IPPROTO_PVP       = 75;\n    enum IPPROTO_BRSATMON  = 76;\n\n    enum IPPROTO_WBMON     = 78;\n    enum IPPROTO_WBEXPAK   = 79;\n    enum IPPROTO_EON       = 80;\n    enum IPPROTO_VMTP      = 81;\n    enum IPPROTO_SVMTP     = 82;\n    enum IPPROTO_VINES     = 83;\n    enum IPPROTO_TTP       = 84;\n    enum IPPROTO_IGP       = 85;\n    enum IPPROTO_DGP       = 86;\n    enum IPPROTO_TCF       = 87;\n    enum IPPROTO_IGRP      = 88;\n    enum IPPROTO_OSPFIGP   = 89;\n    enum IPPROTO_SRPC      = 90;\n    enum IPPROTO_LARP      = 91;\n    enum IPPROTO_MTP       = 92;\n    enum IPPROTO_AX25      = 93;\n    enum IPPROTO_IPEIP     = 94;\n    enum IPPROTO_MICP      = 95;\n    enum IPPROTO_SCCSP     = 96;\n    enum IPPROTO_ETHERIP   = 97;\n    enum IPPROTO_ENCAP     = 98;\n    enum IPPROTO_APES      = 99;\n    enum IPPROTO_GMTP      = 100;\n    enum IPPROTO_IPCOMP    = 108;\n    enum IPPROTO_SCTP      = 132;\n    enum IPPROTO_MH        = 135;\n    enum IPPROTO_UDPLITE   = 136;\n    enum IPPROTO_HIP       = 139;\n    enum IPPROTO_SHIM6     = 140;\n\n    enum IPPROTO_PIM          = 103;\n    enum IPPROTO_CARP         = 112;\n    enum IPPROTO_PGM          = 113;\n    enum IPPROTO_MPLS         = 137;\n    enum IPPROTO_PFSYNC       = 240;\n    enum IPPROTO_RESERVED_253 = 253;\n    enum IPPROTO_RESERVED_254 = 254;\n\n    enum IPPROTO_DONE = 257;\n\n    enum IPPORT_RESERVED = 1024;\n\n    enum IPPORT_EPHEMERALFIRST = 10000;\n    enum IPPORT_EPHEMERALLAST  = 65535;\n\n    enum IPPORT_HIFIRSTAUTO = 49152;\n    enum IPPORT_HILASTAUTO  = 65535;\n\n    enum IPPORT_RESERVEDSTART = 600;\n\n    enum IPPORT_MAX = 65535;\n\n    extern(D) bool IN_CLASSA(in_addr_t i) pure @safe { return (i & 0x80000000) == 0; }\n    enum IN_CLASSA_NET    = 0xff000000;\n    enum IN_CLASSA_NSHIFT = 24;\n    enum IN_CLASSA_HOST   = 0x00ffffff;\n    enum IN_CLASSA_MAX    = 128;\n\n    extern(D) bool IN_CLASSB(in_addr_t i) pure @safe { return (i & 0xc0000000) == 0x80000000; }\n    enum IN_CLASSB_NET    = 0xffff0000;\n    enum IN_CLASSB_NSHIFT = 16;\n    enum IN_CLASSB_HOST   = 0x0000ffff;\n    enum IN_CLASSB_MAX    = 65536;\n\n    extern(D) bool IN_CLASSC(in_addr_t i) pure @safe { return (i & 0xe0000000) == 0xc0000000; }\n    enum IN_CLASSC_NET    = 0xffffff00;\n    enum IN_CLASSC_NSHIFT = 8;\n    enum IN_CLASSC_HOST   = 0x000000ff;\n\n    extern(D) bool IN_CLASSD(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xe0000000; }\n    enum IN_CLASSD_NET     = 0xf0000000;\n    enum IN_CLASSD_NSHIFT  = 28;\n    enum IN_CLASSD_HOST    = 0x0fffffff;\n    extern(D) bool IN_MULTICAST(in_addr_t i) { return IN_CLASSD(i); }\n\n    // The fact that these are identical looks suspicious (they're not quite\n    // identical on Linux). However, this _is_ how they're defined in FreeBSD\n    // and on OS X. So, while it _might_ be a bug, if it is, it's an upstream\n    // one, and we're compatible with it.\n    extern(D) bool IN_EXPERIMENTAL(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xf0000000; }\n    extern(D) bool IN_BADCLASS(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xf0000000; }\n\n    extern(D) bool IN_LINKLOCAL(in_addr_t i) pure @safe { return (i & 0xffff0000) == 0xa9fe0000; }\n    extern(D) bool IN_LOOPBACK(in_addr_t i) pure @safe { return (i & 0xff000000) == 0x7f000000; }\n    extern(D) bool IN_ZERONET(in_addr_t i) pure @safe { return (i & 0xff000000) == 0; }\n\n    extern(D) bool IN_PRIVATE(in_addr_t i) pure @safe\n    {\n        return  (i & 0xff000000) == 0x0a000000 ||\n                (i & 0xfff00000) == 0xac100000 ||\n                (i & 0xffff0000) == 0xc0a80000;\n    }\n\n    extern(D) bool IN_LOCAL_GROUP(in_addr_t i) pure @safe { return (i & 0xffffff00) == 0xe0000000; }\n\n    extern(D) bool IN_ANY_LOCAL(in_addr_t i) pure @safe { return IN_LINKLOCAL(i) || IN_LOCAL_GROUP(i); }\n\n    enum INADDR_UNSPEC_GROUP    = 0xe0000000;\n    enum INADDR_ALLHOSTS_GROUP  = 0xe0000001;\n    enum INADDR_ALLRTRS_GROUP   = 0xe0000002;\n    enum INADDR_ALLRPTS_GROUP   = 0xe0000016;\n    enum INADDR_CARP_GROUP      = 0xe0000012;\n    enum INADDR_PFSYNC_GROUP    = 0xe00000f0;\n    enum INADDR_ALLMDNS_GROUP   = 0xe00000fb;\n    enum INADDR_MAX_LOCAL_GROUP = 0xe00000ff;\n\n    enum IN_LOOPBACKNET = 127;\n\n    enum IN_RFC3021_MASK = 0xfffffffe;\n\n    enum IP_OPTIONS      = 1;\n    enum IP_HDRINCL      = 2;\n    enum IP_TOS          = 3;\n    enum IP_TTL          = 4;\n    enum IP_RECVOPTS     = 5;\n    enum IP_RECVRETOPTS  = 6;\n    enum IP_RECVDSTADDR  = 7;\n    enum IP_SENDSRCADDR  = IP_RECVDSTADDR;\n    enum IP_RETOPTS      = 8;\n    enum IP_MULTICAST_IF = 9;\n\n    enum IP_MULTICAST_TTL   = 10;\n    enum IP_MULTICAST_LOOP  = 11;\n    enum IP_ADD_MEMBERSHIP  = 12;\n    enum IP_DROP_MEMBERSHIP = 13;\n    enum IP_MULTICAST_VIF   = 14;\n    enum IP_RSVP_ON         = 15;\n    enum IP_RSVP_OFF        = 16;\n    enum IP_RSVP_VIF_ON     = 17;\n    enum IP_RSVP_VIF_OFF    = 18;\n    enum IP_PORTRANGE       = 19;\n    enum IP_RECVIF          = 20;\n\n    enum IP_IPSEC_POLICY = 21;\n\n    enum IP_ONESBCAST         = 23;\n    enum IP_BINDANY           = 24;\n    enum IP_BINDMULTI         = 25;\n    enum IP_RSS_LISTEN_BUCKET = 26;\n    enum IP_ORIGDSTADDR       = 27;\n    enum IP_RECVORIGDSTADDR   = IP_ORIGDSTADDR;\n\n    enum IP_FW3       = 48;\n    enum IP_DUMMYNET3 = 49;\n\n    enum IP_ADD_SOURCE_MEMBERSHIP  = 70;\n    enum IP_DROP_SOURCE_MEMBERSHIP = 71;\n    enum IP_BLOCK_SOURCE           = 72;\n    enum IP_UNBLOCK_SOURCE         = 73;\n\n    enum MCAST_JOIN_GROUP         = 80;\n    enum MCAST_LEAVE_GROUP        = 81;\n    enum MCAST_JOIN_SOURCE_GROUP  = 82;\n    enum MCAST_LEAVE_SOURCE_GROUP = 83;\n    enum MCAST_BLOCK_SOURCE       = 84;\n    enum MCAST_UNBLOCK_SOURCE     = 85;\n\n    enum IP_FLOWID          = 90;\n    enum IP_FLOWTYPE        = 91;\n    enum IP_RSSBUCKETID     = 92;\n    enum IP_RECVFLOWID      = 93;\n    enum IP_RECVRSSBUCKETID = 94;\n\n    enum IP_DEFAULT_MULTICAST_TTL  = 1;\n    enum IP_DEFAULT_MULTICAST_LOOP = 1;\n\n    enum IP_MIN_MEMBERSHIPS   = 31;\n    enum IP_MAX_MEMBERSHIPS   = 4095;\n\n    enum IP_MAX_GROUP_SRC_FILTER = 512;\n    enum IP_MAX_SOCK_SRC_FILTER  = 128;\n\n    struct ip_mreq\n    {\n        in_addr imr_multiaddr;\n        in_addr imr_interface;\n    };\n\n    struct ip_mreqn\n    {\n        in_addr imr_multiaddr;\n        in_addr imr_address;\n        int     imr_ifindex;\n    };\n\n    struct ip_mreq_source\n    {\n        in_addr imr_multiaddr;\n        in_addr imr_sourceaddr;\n        in_addr imr_interface;\n    };\n\n    struct group_req\n    {\n        uint gr_interface;\n        sockaddr_storage gr_group;\n    };\n\n    struct group_source_req\n    {\n        uint gsr_interface;\n        sockaddr_storage gsr_group;\n        sockaddr_storage gsr_source;\n    };\n\n    int setipv4sourcefilter(int, in_addr, in_addr, uint, uint, in_addr*);\n    int getipv4sourcefilter(int, in_addr, in_addr, uint*, uint*, in_addr*);\n    int setsourcefilter(int, uint, sockaddr*, socklen_t, uint, uint, sockaddr_storage*);\n    int getsourcefilter(int, uint, sockaddr*, socklen_t, uint*, uint*, sockaddr_storage*);\n\n    enum MCAST_UNDEFINED = 0;\n    enum MCAST_INCLUDE   = 1;\n    enum MCAST_EXCLUDE   = 2;\n\n    enum IP_PORTRANGE_DEFAULT = 0;\n    enum IP_PORTRANGE_HIGH    = 1;\n    enum IP_PORTRANGE_LOW     = 2;\n\n    enum IPCTL_FORWARDING        = 1;\n    enum IPCTL_SENDREDIRECTS     = 2;\n    enum IPCTL_DEFTTL            = 3;\n    enum IPCTL_DEFMTU            = 4;\n    enum IPCTL_SOURCEROUTE       = 8;\n    enum IPCTL_DIRECTEDBROADCAST = 9;\n    enum IPCTL_INTRQMAXLEN       = 10;\n    enum IPCTL_INTRQDROPS        = 11;\n    enum IPCTL_STATS             = 12;\n    enum IPCTL_ACCEPTSOURCEROUTE = 13;\n    enum IPCTL_FASTFORWARDING    = 14;\n    enum IPCTL_GIF_TTL           = 16;\n    enum IPCTL_INTRDQMAXLEN      = 17;\n    enum IPCTL_INTRDQDROPS       = 18;\n}\n\n// =============================================================================\n// What follows is from netinet6/in6.h, but since netinet6/in6.h specifically\n// says that it should only be #included by #including netinet/in.h, it makes\n// more sense to put them in here so that the way they're imported corresponds\n// with the correct way of #including them in C/C++.\n// =============================================================================\n\n// The #if was around the #include of in6.h at the end of in.h.\nstatic if (__POSIX_VISIBLE)\n{\n    static if (__BSD_VISIBLE)\n    {\n        enum IPV6PORT_RESERVED    = 1024;\n        enum IPV6PORT_ANONMIN     = 49152;\n        enum IPV6PORT_ANONMAX     = 65535;\n        enum IPV6PORT_RESERVEDMIN = 600;\n        enum IPV6PORT_RESERVEDMAX = IPV6PORT_RESERVED - 1;\n\n        enum IN6ADDR_ANY_INIT = in6_addr.init;\n        enum IN6ADDR_LOOPBACK_INIT = in6_addr([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\n        enum IN6ADDR_NODELOCAL_ALLNODES_INIT = in6_addr([0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\n        enum IN6ADDR_INTFACELOCAL_ALLNODES_INIT = in6_addr([0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\n        enum IN6ADDR_LINKLOCAL_ALLNODES_INIT = in6_addr([0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);\n        enum IN6ADDR_LINKLOCAL_ALLROUTERS_INIT = in6_addr([0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02]);\n        enum IN6ADDR_LINKLOCAL_ALLV2ROUTERS_INIT = in6_addr([0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                                                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16]);\n\n        __gshared const in6_addr in6addr_nodelocal_allnodes;\n        __gshared const in6_addr in6addr_linklocal_allnodes;\n        __gshared const in6_addr in6addr_linklocal_allrouters;\n        __gshared const in6_addr in6addr_linklocal_allv2routers;\n\n        extern(D) bool IN6_ARE_ADDR_EQUAL(in6_addr* a, in6_addr* b) pure @safe { return *a == *b; }\n    }\n\n    enum __IPV6_ADDR_SCOPE_NODELOCAL    = 0x01;\n    enum __IPV6_ADDR_SCOPE_INTFACELOCAL = 0x01;\n    enum __IPV6_ADDR_SCOPE_LINKLOCAL    = 0x02;\n    enum __IPV6_ADDR_SCOPE_SITELOCAL    = 0x05;\n    enum __IPV6_ADDR_SCOPE_GLOBAL       = 0x0e;\n\n    static if (__BSD_VISIBLE)\n    {\n// TODO - requires declarations from elsewhere that we don't currently have bindings for.\n/+\n        struct route_in6\n        {\n            rtentry* ro_rt;\n            llentry* ro_lle;\n            char*    ro_prepend;\n            ushort   ro_plen;\n            ushort   ro_flags;\n            ushort   ro_mtu;\n            ushort   spare;\n            sockaddr_in6 ro_dst;\n        };\n +/\n    }\n\n    enum IPV6_SOCKOPT_RESERVED1 = 3;\n    enum IPV6_PORTRANGE         = 14;\n    enum ICMP6_FILTER           = 18;\n\n    enum IPV6_CHECKSUM = 26;\n\n    enum IPV6_IPSEC_POLICY = 28;\n\n    enum IPV6_FW_ADD   = 30;\n    enum IPV6_FW_DEL   = 31;\n    enum IPV6_FW_FLUSH = 32;\n    enum IPV6_FW_ZERO  = 33;\n    enum IPV6_FW_GET   = 34;\n\n    enum IPV6_RTHDRDSTOPTS = 35;\n\n    enum IPV6_RECVPKTINFO  = 36;\n    enum IPV6_RECVHOPLIMIT = 37;\n    enum IPV6_RECVRTHDR    = 38;\n    enum IPV6_RECVHOPOPTS  = 39;\n    enum IPV6_RECVDSTOPTS  = 40;\n\n    enum IPV6_USE_MIN_MTU = 42;\n    enum IPV6_RECVPATHMTU = 43;\n\n    enum IPV6_PATHMTU = 44;\n\n    enum IPV6_PKTINFO  = 46;\n    enum IPV6_HOPLIMIT = 47;\n    enum IPV6_NEXTHOP  = 48;\n    enum IPV6_HOPOPTS  = 49;\n    enum IPV6_DSTOPTS  = 50;\n    enum IPV6_RTHDR    = 51;\n\n    enum IPV6_RECVTCLASS = 57;\n\n    enum IPV6_AUTOFLOWLABEL = 59;\n\n    enum IPV6_TCLASS   = 61;\n    enum IPV6_DONTFRAG = 62;\n\n    enum IPV6_PREFER_TEMPADDR = 63;\n\n    enum IPV6_BINDANY   = 64;\n\n    enum IPV6_BINDMULTI         = 65;\n    enum IPV6_RSS_LISTEN_BUCKET = 66;\n    enum IPV6_FLOWID            = 67;\n    enum IPV6_FLOWTYPE          = 68;\n    enum IPV6_RSSBUCKETID       = 69;\n    enum IPV6_RECVFLOWID        = 70;\n    enum IPV6_RECVRSSBUCKETID   = 71;\n\n    enum IPV6_ORIGDSTADDR     = 72;\n    enum IPV6_RECVORIGDSTADDR = IPV6_ORIGDSTADDR;\n\n    enum IPV6_RTHDR_LOOSE  = 0;\n    enum IPV6_RTHDR_STRICT = 1;\n    enum IPV6_RTHDR_TYPE_0 = 0;\n\n    enum IPV6_DEFAULT_MULTICAST_HOPS = 1;\n    enum IPV6_DEFAULT_MULTICAST_LOOP = 1;\n\n    enum IPV6_MIN_MEMBERSHIPS = 31;\n    enum IPV6_MAX_MEMBERSHIPS = 4095;\n\n    enum IPV6_MAX_GROUP_SRC_FILTER = 512;\n    enum IPV6_MAX_SOCK_SRC_FILTER  = 128;\n\n    struct in6_pktinfo\n    {\n        in6_addr ipi6_addr;\n        uint     ipi6_ifindex;\n    };\n\n    struct ip6_mtuinfo\n    {\n        sockaddr_in6 ip6m_addr;\n        uint         ip6m_mtu;\n    };\n\n    enum IPV6_PORTRANGE_DEFAULT = 0;\n    enum IPV6_PORTRANGE_HIGH    = 1;\n    enum IPV6_PORTRANGE_LOW     = 2;\n\n    static if (__BSD_VISIBLE)\n    {\n        enum IPV6PROTO_MAXID =  IPPROTO_PIM + 1;\n\n        enum IPV6CTL_FORWARDING         = 1;\n        enum IPV6CTL_SENDREDIRECTS      = 2;\n        enum IPV6CTL_DEFHLIM            = 3;\n        enum IPV6CTL_DEFMTU             = 4;\n        enum IPV6CTL_FORWSRCRT          = 5;\n        enum IPV6CTL_STATS              = 6;\n        enum IPV6CTL_MRTSTATS           = 7;\n        enum IPV6CTL_MRTPROTO           = 8;\n        enum IPV6CTL_MAXFRAGPACKETS     = 9;\n        enum IPV6CTL_SOURCECHECK        = 10;\n        enum IPV6CTL_SOURCECHECK_LOGINT = 11;\n        enum IPV6CTL_ACCEPT_RTADV       = 12;\n\n        enum IPV6CTL_LOG_INTERVAL   = 14;\n        enum IPV6CTL_HDRNESTLIMIT   = 15;\n        enum IPV6CTL_DAD_COUNT      = 16;\n        enum IPV6CTL_AUTO_FLOWLABEL = 17;\n        enum IPV6CTL_DEFMCASTHLIM   = 18;\n        enum IPV6CTL_GIF_HLIM       = 19;\n        enum IPV6CTL_KAME_VERSION   = 20;\n        enum IPV6CTL_USE_DEPRECATED = 21;\n        enum IPV6CTL_RR_PRUNE       = 22;\n        enum IPV6CTL_V6ONLY         = 24;\n\n        enum IPV6CTL_USETEMPADDR     = 32;\n        enum IPV6CTL_TEMPPLTIME      = 33;\n        enum IPV6CTL_TEMPVLTIME      = 34;\n        enum IPV6CTL_AUTO_LINKLOCAL  = 35;\n        enum IPV6CTL_RIP6STATS       = 36;\n        enum IPV6CTL_PREFER_TEMPADDR = 37;\n        enum IPV6CTL_ADDRCTLPOLICY   = 38;\n        enum IPV6CTL_USE_DEFAULTZONE = 39;\n\n        enum IPV6CTL_MAXFRAGS   = 41;\n        enum IPV6CTL_MCAST_PMTU = 44;\n\n        enum IPV6CTL_STEALTH = 45;\n\n        enum ICMPV6CTL_ND6_ONLINKNSRFC4861 = 47;\n        enum IPV6CTL_NO_RADR     = 48;\n        enum IPV6CTL_NORBIT_RAIF = 49;\n\n        enum IPV6CTL_RFC6204W3 = 50;\n\n        enum IPV6CTL_INTRQMAXLEN  = 51;\n        enum IPV6CTL_INTRDQMAXLEN = 52;\n\n        enum IPV6CTL_MAXID = 53;\n    }\n\n// TODO - require declarations from elsewhere that we don't currently have bindings for.\n/+\n    enum M_FASTFWD_OURS  = M_PROTO1;\n    enum M_IP6_NEXTHOP   = M_PROTO2;\n    enum M_IP_NEXTHOP    = M_PROTO2;\n    enum M_SKIP_FIREWALL = M_PROTO3;\n    enum M_AUTHIPHDR     = M_PROTO4;\n    enum M_DECRYPTED     = M_PROTO5;\n    enum M_LOOP          = M_PROTO6;\n    enum M_AUTHIPDGM     = M_PROTO7;\n    enum M_RTALERT_MLD   = M_PROTO8;\n +/\n\n    static if (__BSD_VISIBLE)\n    {\n        size_t inet6_rthdr_space(int, int) @trusted;\n        cmsghdr* inet6_rthdr_init(void*, int);\n        int inet6_rthdr_add(cmsghdr*, const in6_addr*, uint);\n        int inet6_rthdr_lasthop(cmsghdr*, uint);\n        int inet6_rthdr_segments(const cmsghdr*);\n        in6_addr* inet6_rthdr_getaddr(cmsghdr*, int);\n        int inet6_rthdr_getflags(const cmsghdr*, int);\n\n        int inet6_opt_init(void*, socklen_t);\n        int inet6_opt_append(void*, socklen_t, int, ubyte, socklen_t, ubyte, void**);\n        int inet6_opt_finish(void*, socklen_t, int);\n        int inet6_opt_set_val(void*, int, void*, socklen_t);\n\n        int inet6_opt_next(void*, socklen_t, int, ubyte*, socklen_t*, void**);\n        int inet6_opt_find(void*, socklen_t, int, ubyte, socklen_t*, void**);\n        int inet6_opt_get_val(void*, int, void*, socklen_t);\n        socklen_t inet6_rth_space(int, int) @trusted;\n        void* inet6_rth_init(void*, socklen_t, int, int);\n        int inet6_rth_add(void*, const in6_addr*);\n        int inet6_rth_reverse(const void*, void*);\n        int inet6_rth_segments(const void*);\n        in6_addr* inet6_rth_getaddr(const void*, int);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/pthread_np.d",
    "content": "/**\n * D header file for FreeBSD.\n *\n * Authors:   Martin Nowak\n */\nmodule core.sys.freebsd.pthread;\n\nversion (FreeBSD):\nextern (C) nothrow @nogc:\n\npublic import core.sys.posix.sys.types;\n// TODO: add full core.sys.freebsd.sys.cpuset;\npublic import core.sys.freebsd.sys._cpuset;\npublic import core.sys.posix.time;\n\nenum __BSD_VISIBLE = true;\n\nalias pthread_switch_routine_t = void function(pthread_t, pthread_t);\n\nint pthread_attr_setcreatesuspend_np(pthread_attr_t *);\nint pthread_attr_get_np(pthread_t, pthread_attr_t *);\nint pthread_attr_getaffinity_np(const(pthread_attr_t)*, size_t, cpuset_t *);\nint pthread_attr_setaffinity_np(pthread_attr_t *, size_t, const(cpuset_t)*);\nint pthread_getaffinity_np(pthread_t, size_t, cpuset_t *);\nint pthread_getthreadid_np();\nint pthread_main_np();\nint pthread_multi_np();\nint pthread_mutexattr_getkind_np(pthread_mutexattr_t);\nint pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int);\nvoid pthread_resume_all_np();\nint pthread_resume_np(pthread_t);\nvoid pthread_set_name_np(pthread_t, const(char)*);\nint pthread_mutex_getspinloops_np(pthread_mutex_t *mutex, int *count);\nint pthread_mutex_setspinloops_np(pthread_mutex_t *mutex, int count);\nint pthread_mutex_getyieldloops_np(pthread_mutex_t *mutex, int *count);\nint pthread_mutex_setyieldloops_np(pthread_mutex_t *mutex, int count);\nint pthread_mutex_isowned_np(pthread_mutex_t *mutex);\nint pthread_setaffinity_np(pthread_t, size_t, const(cpuset_t)*);\nint pthread_single_np();\nvoid pthread_suspend_all_np();\nint pthread_suspend_np(pthread_t);\nint pthread_switch_add_np(pthread_switch_routine_t);\nint pthread_switch_delete_np(pthread_switch_routine_t);\nint pthread_timedjoin_np(pthread_t, void **, const(timespec)*);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/sys/_bitset.d",
    "content": "/**\n * D header file for FreeBSD.\n *\n * Authors:   Martin Nowak\n */\nmodule core.sys.freebsd.sys._bitset;\n\nversion (FreeBSD):\nextern (C) pure nothrow @nogc:\n\nimport core.stdc.config : c_long;\n\nenum NBBY = 8; // number of bits per byte\n\nenum _BITSET_BITS = c_long.sizeof * NBBY;\n\nenum __bitset_words(size_t s) = (s + _BITSET_BITS - 1) / _BITSET_BITS;\n\nc_long __bitset_mask(size_t s)(size_t n)\n{\n    static if (__bitset_words!s == 1)\n        return (cast(c_long)1) << n;\n    else\n        return (cast(c_long)1) << n % _BITSET_BITS;\n}\n\nsize_t __bitset_word(size_t s)(size_t n)\n{\n    static if (__bitset_words!s == 1)\n        return 0;\n    else\n        return n / _BITSET_BITS;\n}\n\nstruct BITSET_DEFINE(size_t s)\n{\n    c_long[__bitset_words!s] __bits;\n}\n\n// no idea how to translate those\n//#define BITSET_T_INITIALIZER(x)                     \\\n//    { .__bits = { x } }\n//\n//#define BITSET_FSET(n)                          \\\n//    [ 0 ... ((n) - 1) ] = (-1L)\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/sys/_cpuset.d",
    "content": "/**\n * D header file for FreeBSD.\n *\n * Authors:   Martin Nowak\n */\nmodule core.sys.freebsd.sys._cpuset;\n\nversion (FreeBSD):\nextern (C) pure nothrow @nogc:\n\npublic import core.sys.freebsd.sys._bitset;\n\nstatic if (is(typeof(_KERNEL)))\n    alias CPU_SETSIZE = MAXCPU;\n\nenum CPU_MAXSIZE = 256;\n\nstatic if (!is(typeof(CPU_SETSIZE)))\n    alias CPU_SETSIZE = CPU_MAXSIZE;\n\nenum _NCPUBITS = _BITSET_BITS;\nenum _NCPUWORDS = __bitset_words!CPU_SETSIZE;\n\nalias _cpuset = BITSET_DEFINE!(CPU_SETSIZE);\nalias cpuset_t = _cpuset;\n\n// no idea how to translate those\n//#define CPUSET_FSET BITSET_FSET(_NCPUWORDS)\n//#define CPUSET_T_INITIALIZER BITSET_T_INITIALIZER\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/sys/cdefs.d",
    "content": "/**\n * D header file for FreeBSD\n *\n * Authors: Martin Nowak\n */\nmodule core.sys.freebsd.sys.cdefs;\n\nversion (FreeBSD):\n\npublic import core.sys.posix.config;\n\n// https://svnweb.freebsd.org/base/head/sys/sys/cdefs.h?revision=271155&view=markup\nenum __POSIX_VISIBLE = 200112;\nenum __XSI_VISIBLE = 700;\nenum __BSD_VISIBLE = true;\nenum __ISO_C_VISIBLE = 1999;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/sys/elf.d",
    "content": "/**\n * D header file for FreeBSD.\n *\n * $(LINK2 http://svnweb.freebsd.org/base/head/sys/sys/elf.h?view=markup, sys/elf.h)\n */\nmodule core.sys.freebsd.sys.elf;\n\nversion (FreeBSD):\n\npublic import core.sys.freebsd.sys.elf32;\npublic import core.sys.freebsd.sys.elf64;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/sys/elf32.d",
    "content": "/**\n * D header file for FreeBSD.\n *\n * $(LINK2 http://svnweb.freebsd.org/base/head/sys/sys/elf32.h?view=markup, sys/elf32.h)\n */\nmodule core.sys.freebsd.sys.elf32;\n\nversion (FreeBSD):\nextern (C):\npure:\nnothrow:\n\nimport core.stdc.stdint;\npublic import core.sys.freebsd.sys.elf_common;\n\nalias uint16_t Elf32_Half;\nalias uint32_t Elf32_Word;\nalias int32_t  Elf32_Sword;\nalias uint64_t Elf32_Lword;\nalias uint32_t Elf32_Addr;\nalias uint32_t Elf32_Off;\nalias Elf32_Word Elf32_Hashelt;\nalias Elf32_Word Elf32_Size;\nalias Elf32_Sword Elf32_Ssize;\n\nstruct Elf32_Ehdr\n{\n    char[EI_NIDENT] e_ident;\n    Elf32_Half    e_type;\n    Elf32_Half    e_machine;\n    Elf32_Word    e_version;\n    Elf32_Addr    e_entry;\n    Elf32_Off     e_phoff;\n    Elf32_Off     e_shoff;\n    Elf32_Word    e_flags;\n    Elf32_Half    e_ehsize;\n    Elf32_Half    e_phentsize;\n    Elf32_Half    e_phnum;\n    Elf32_Half    e_shentsize;\n    Elf32_Half    e_shnum;\n    Elf32_Half    e_shstrndx;\n}\n\nstruct Elf32_Shdr\n{\n    Elf32_Word    sh_name;\n    Elf32_Word    sh_type;\n    Elf32_Word    sh_flags;\n    Elf32_Addr    sh_addr;\n    Elf32_Off     sh_offset;\n    Elf32_Word    sh_size;\n    Elf32_Word    sh_link;\n    Elf32_Word    sh_info;\n    Elf32_Word    sh_addralign;\n    Elf32_Word    sh_entsize;\n}\n\nstruct Elf32_Phdr\n{\n    Elf32_Word    p_type;\n    Elf32_Off     p_offset;\n    Elf32_Addr    p_vaddr;\n    Elf32_Addr    p_paddr;\n    Elf32_Word    p_filesz;\n    Elf32_Word    p_memsz;\n    Elf32_Word    p_flags;\n    Elf32_Word    p_align;\n}\n\nstruct Elf32_Dyn\n{\n  Elf32_Sword   d_tag;\n  union _d_un\n  {\n      Elf32_Word d_val;\n      Elf32_Addr d_ptr;\n  } _d_un d_un;\n}\n\nstruct Elf32_Rel\n{\n    Elf32_Addr    r_offset;\n    Elf32_Word    r_info;\n}\n\nstruct Elf32_Rela\n{\n    Elf32_Addr    r_offset;\n    Elf32_Word    r_info;\n    Elf32_Sword   r_addend;\n}\n\nextern (D)\n{\n    auto ELF32_R_SYM(V)(V val) { return val >> 8; }\n    auto ELF32_R_TYPE(V)(V val) { return val & 0xff; }\n    auto ELF32_R_INFO(S, T)(S sym, T type) { return (sym << 8) + (type & 0xff); }\n}\n\nalias Elf_Note Elf32_Nhdr;\n\nstruct Elf32_Move\n{\n    Elf32_Lword   m_value;\n    Elf32_Word    m_info;\n    Elf32_Word    m_poffset;\n    Elf32_Half    m_repeat;\n    Elf32_Half    m_stride;\n}\n\nextern (D)\n{\n    auto ELF32_M_SYM(I)(I info) { return info >> 8; }\n    auto ELF32_M_SIZE(I)(I info) { return cast(ubyte)info; }\n    auto ELF32_M_INFO(S, SZ)(S sym, SZ size) { return (sym << 8) + cast(ubye)size; }\n}\n\nstruct Elf32_Cap\n{\n    Elf32_Word    c_tag;\n    union _c_un\n    {\n        Elf32_Word      c_val;\n        Elf32_Addr      c_ptr;\n    } _c_un c_un;\n}\n\nstruct Elf32_Sym\n{\n    Elf32_Word    st_name;\n    Elf32_Addr    st_value;\n    Elf32_Word    st_size;\n    ubyte st_info;\n    ubyte st_other;\n    Elf32_Half st_shndx;\n}\n\nextern (D)\n{\n    auto ELF32_ST_BIND(T)(T val) { return cast(ubyte)val >> 4; }\n    auto ELF32_ST_TYPE(T)(T val) { return val & 0xf; }\n    auto ELF32_ST_INFO(B, T)(B bind, T type) { return (bind << 4) + (type & 0xf); }\n    auto ELF32_ST_VISIBILITY(O)(O o) { return o & 0x03; }\n}\n\nstruct Elf32_Verdef\n{\n    Elf32_Half    vd_version;\n    Elf32_Half    vd_flags;\n    Elf32_Half    vd_ndx;\n    Elf32_Half    vd_cnt;\n    Elf32_Word    vd_hash;\n    Elf32_Word    vd_aux;\n    Elf32_Word    vd_next;\n}\n\nstruct Elf32_Verdaux\n{\n    Elf32_Word    vda_name;\n    Elf32_Word    vda_next;\n}\n\nstruct Elf32_Verneed\n{\n    Elf32_Half    vn_version;\n    Elf32_Half    vn_cnt;\n    Elf32_Word    vn_file;\n    Elf32_Word    vn_aux;\n    Elf32_Word    vn_next;\n}\n\nstruct Elf32_Vernaux\n{\n    Elf32_Word    vna_hash;\n    Elf32_Half    vna_flags;\n    Elf32_Half    vna_other;\n    Elf32_Word    vna_name;\n    Elf32_Word    vna_next;\n}\n\nalias Elf32_Half Elf32_Versym;\n\nstruct Elf32_Syminfo\n{\n    Elf32_Half si_boundto;\n    Elf32_Half si_flags;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/sys/elf64.d",
    "content": "/**\n * D header file for FreeBSD.\n *\n * $(LINK2 http://svnweb.freebsd.org/base/head/sys/sys/elf64.h?view=markup, sys/elf64.h)\n */\nmodule core.sys.freebsd.sys.elf64;\n\nversion (FreeBSD):\nextern (C):\npure:\nnothrow:\n\nimport core.stdc.stdint;\npublic import core.sys.freebsd.sys.elf_common;\n\nalias uint16_t Elf64_Half;\nalias uint32_t Elf64_Word;\nalias int32_t  Elf64_Sword;\nalias uint64_t Elf64_Lword;\nalias uint64_t Elf64_Xword;\nalias int64_t  Elf64_Sxword;\nalias uint64_t Elf64_Addr;\nalias uint64_t Elf64_Off;\nalias Elf64_Word Elf64_Hashelt;\nalias Elf64_Xword Elf64_Size;\nalias Elf64_Sxword Elf64_Ssize;\n\nstruct Elf64_Ehdr\n{\n    char[EI_NIDENT] e_ident;\n    Elf64_Half    e_type;\n    Elf64_Half    e_machine;\n    Elf64_Word    e_version;\n    Elf64_Addr    e_entry;\n    Elf64_Off     e_phoff;\n    Elf64_Off     e_shoff;\n    Elf64_Word    e_flags;\n    Elf64_Half    e_ehsize;\n    Elf64_Half    e_phentsize;\n    Elf64_Half    e_phnum;\n    Elf64_Half    e_shentsize;\n    Elf64_Half    e_shnum;\n    Elf64_Half    e_shstrndx;\n}\n\nstruct Elf64_Shdr\n{\n    Elf64_Word    sh_name;\n    Elf64_Word    sh_type;\n    Elf64_Xword   sh_flags;\n    Elf64_Addr    sh_addr;\n    Elf64_Off     sh_offset;\n    Elf64_Xword   sh_size;\n    Elf64_Word    sh_link;\n    Elf64_Word    sh_info;\n    Elf64_Xword   sh_addralign;\n    Elf64_Xword   sh_entsize;\n}\n\nstruct Elf64_Phdr\n{\n    Elf64_Word    p_type;\n    Elf64_Word    p_flags;\n    Elf64_Off     p_offset;\n    Elf64_Addr    p_vaddr;\n    Elf64_Addr    p_paddr;\n    Elf64_Xword   p_filesz;\n    Elf64_Xword   p_memsz;\n    Elf64_Xword   p_align;\n}\n\nstruct Elf64_Dyn\n{\n  Elf64_Sxword  d_tag;\n  union _d_un\n  {\n      Elf64_Xword d_val;\n      Elf64_Addr d_ptr;\n  } _d_un d_un;\n}\n\nstruct Elf64_Rel\n{\n    Elf64_Addr    r_offset;\n    Elf64_Xword   r_info;\n}\n\nstruct Elf64_Rela\n{\n    Elf64_Addr    r_offset;\n    Elf64_Xword   r_info;\n    Elf64_Sxword  r_addend;\n}\n\nextern (D)\n{\n    auto ELF64_R_SYM(I)(I i) { return i >> 32; }\n    auto ELF64_R_TYPE(I)(I i) { return i & 0xffffffff; }\n    auto ELF64_R_INFO(S, T)(S sym, T type) { return (sym << 32) + (type & 0xffffffff); }\n\n    auto ELF64_R_TYPE_DATA(I)(I i) { return (cast(Elf64_Xword) i << 32) >> 40; }\n    auto ELF64_R_TYPE_ID(I)(I i) { return (cast(Elf64_Xword) i << 56 ) >> 56; }\n    auto ELF64_R_TYPE_INFO(D, T)(D d, T t) { return cast(Elf64_Xword) d << 8 + cast(Elf64_Xword) t; }\n}\n\nalias Elf_Note Elf64_Nhdr;\n\nstruct Elf64_Move\n{\n    Elf64_Lword   m_value;\n    Elf64_Xword   m_info;\n    Elf64_Xword   m_poffset;\n    Elf64_Half    m_repeat;\n    Elf64_Half    m_stride;\n}\n\nextern (D)\n{\n    auto ELF64_M_SYM(I)(I info) { return info >> 8; }\n    auto ELF64_M_SIZE(I)(I info) { return cast(ubyte)info; }\n    auto ELF64_M_INFO(S, SZ)(S sym, SZ size) { return (sym << 8) + cast(ubye)size; }\n}\n\nstruct Elf64_Cap\n{\n    Elf64_Xword   c_tag;\n    union _c_un\n    {\n        Elf64_Xword     c_val;\n        Elf64_Addr      c_ptr;\n    } _c_un c_un;\n}\n\nstruct Elf64_Sym\n{\n    Elf64_Word    st_name;\n    ubyte st_info;\n    ubyte st_other;\n    Elf64_Half st_shndx;\n    Elf64_Addr    st_value;\n    Elf64_Xword   st_size;\n}\n\nextern (D)\n{\n    auto ELF64_ST_BIND(T)(T val) { return cast(ubyte)val >> 4; }\n    auto ELF64_ST_TYPE(T)(T val) { return val & 0xf; }\n    auto ELF64_ST_INFO(B, T)(B bind, T type) { return (bind << 4) + (type & 0xf); }\n    auto ELF64_ST_VISIBILITY(O)(O o) { return o & 0x03; }\n}\n\nstruct Elf64_Verdef\n{\n    Elf64_Half    vd_version;\n    Elf64_Half    vd_flags;\n    Elf64_Half    vd_ndx;\n    Elf64_Half    vd_cnt;\n    Elf64_Word    vd_hash;\n    Elf64_Word    vd_aux;\n    Elf64_Word    vd_next;\n}\n\nstruct Elf64_Verdaux\n{\n    Elf64_Word    vda_name;\n    Elf64_Word    vda_next;\n}\n\nstruct Elf64_Verneed\n{\n    Elf64_Half    vn_version;\n    Elf64_Half    vn_cnt;\n    Elf64_Word    vn_file;\n    Elf64_Word    vn_aux;\n    Elf64_Word    vn_next;\n}\n\nstruct Elf64_Vernaux\n{\n    Elf64_Word    vna_hash;\n    Elf64_Half    vna_flags;\n    Elf64_Half    vna_other;\n    Elf64_Word    vna_name;\n    Elf64_Word    vna_next;\n}\n\nalias Elf64_Half Elf64_Versym;\n\nstruct Elf64_Syminfo\n{\n    Elf64_Half si_boundto;\n    Elf64_Half si_flags;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/sys/elf_common.d",
    "content": "/**\n * D header file for FreeBSD.\n *\n * $(LINK2 http://svnweb.freebsd.org/base/head/sys/sys/elf_common.h?view=markup, sys/elf_common.h)\n */\nmodule core.sys.freebsd.sys.elf_common;\n\nversion (FreeBSD):\nextern (C):\npure:\nnothrow:\n\nimport core.stdc.stdint;\n\nstruct Elf_Note\n{\n    uint32_t      n_namesz;\n    uint32_t      n_descsz;\n    uint32_t      n_type;\n}\n\nstruct Elf_GNU_Hash_Header\n{\n    uint32_t      gh_nbuckets;\n    uint32_t      gh_symndx;\n    uint32_t      gh_maskwords;\n    uint32_t      gh_shift2;\n}\n\nenum EI_MAG0 =         0;\nenum EI_MAG1 =         1;\nenum EI_MAG2 =         2;\nenum EI_MAG3 =         3;\nenum EI_CLASS =        4;\nenum EI_DATA =         5;\nenum EI_VERSION =      6;\nenum EI_OSABI =        7;\nenum EI_ABIVERSION =   8;\nenum OLD_EI_BRAND =    8;\nenum EI_PAD =          9;\nenum EI_NIDENT =       16;\n\nenum ELFMAG0 =         0x7f;\nenum ELFMAG1 =         'E';\nenum ELFMAG2 =         'L';\nenum ELFMAG3 =         'F';\nenum ELFMAG =          \"\\177ELF\";\nenum SELFMAG =         4;\n\nenum EV_NONE =         0;\nenum EV_CURRENT =      1;\n\nenum ELFCLASSNONE =    0;\nenum ELFCLASS32 =      1;\nenum ELFCLASS64 =      2;\n\nenum ELFDATANONE =     0;\nenum ELFDATA2LSB =     1;\nenum ELFDATA2MSB =     2;\n\nenum ELFOSABI_NONE =           0;\nenum ELFOSABI_SYSV =           0;\nenum ELFOSABI_HPUX =           1;\nenum ELFOSABI_NETBSD =         2;\nenum ELFOSABI_LINUX =          3;\nenum ELFOSABI_HURD  =          4;\nenum ELFOSABI_86OPEN =         5;\nenum ELFOSABI_SOLARIS =        6;\nenum ELFOSABI_AIX =            7;\nenum ELFOSABI_MONTEREY =       7;\nenum ELFOSABI_IRIX =           8;\nenum ELFOSABI_FREEBSD =        9;\nenum ELFOSABI_TRU64 =          10;\nenum ELFOSABI_MODESTO =        11;\nenum ELFOSABI_OPENBSD =        12;\nenum ELFOSABI_OPENVMS =        13;\nenum ELFOSABI_NSK =            14;\nenum ELFOSABI_AROS =           15;\nenum ELFOSABI_ARM =            97;\nenum ELFOSABI_STANDALONE =     255;\n\nextern (D)\n{\n    auto IS_ELF(T)(T ehdr) { return ehdr.e_ident[EI_MAG0] == ELFMAG0 &&\n                                    ehdr.e_ident[EI_MAG1] == ELFMAG1 &&\n                                    ehdr.e_ident[EI_MAG2] == ELFMAG2 &&\n                                    ehdr.e_ident[EI_MAG3] == ELFMAG3; }\n}\n\nenum ET_NONE =         0;\nenum ET_REL =          1;\nenum ET_EXEC =         2;\nenum ET_DYN =          3;\nenum ET_CORE =         4;\nenum ET_LOOS =         0xfe00;\nenum ET_HIOS =         0xfeff;\nenum ET_LOPROC =       0xff00;\nenum ET_HIPROC =       0xffff;\n\nenum EM_NONE =          0;\nenum EM_M32 =           1;\nenum EM_SPARC =         2;\nenum EM_386 =           3;\nenum EM_68K =           4;\nenum EM_88K =           5;\nenum EM_860 =           7;\nenum EM_MIPS =          8;\nenum EM_S370 =          9;\nenum EM_MIPS_RS3_LE =  10;\nenum EM_PARISC =       15;\nenum EM_VPP500 =       17;\nenum EM_SPARC32PLUS =  18;\nenum EM_960 =          19;\nenum EM_PPC =          20;\nenum EM_PPC64 =        21;\nenum EM_S390 =         22;\nenum EM_V800 =         36;\nenum EM_FR20 =         37;\nenum EM_RH32 =         38;\nenum EM_RCE =          39;\nenum EM_ARM =          40;\nenum EM_SH =           42;\nenum EM_SPARCV9 =      43;\nenum EM_TRICORE =      44;\nenum EM_ARC =          45;\nenum EM_H8_300 =       46;\nenum EM_H8_300H =      47;\nenum EM_H8S =          48;\nenum EM_H8_500 =       49;\nenum EM_IA_64 =        50;\nenum EM_MIPS_X =       51;\nenum EM_COLDFIRE =     52;\nenum EM_68HC12 =       53;\nenum EM_MMA =          54;\nenum EM_PCP =          55;\nenum EM_NCPU =         56;\nenum EM_NDR1 =         57;\nenum EM_STARCORE =     58;\nenum EM_ME16 =         59;\nenum EM_ST100 =        60;\nenum EM_TINYJ =        61;\nenum EM_X86_64 =       62;\nenum EM_AMD64 =        62;\nenum EM_PDSP =         63;\nenum EM_FX66 =         66;\nenum EM_ST9PLUS =      67;\nenum EM_ST7 =          68;\nenum EM_68HC16 =       69;\nenum EM_68HC11 =       70;\nenum EM_68HC08 =       71;\nenum EM_68HC05 =       72;\nenum EM_SVX =          73;\nenum EM_ST19 =         74;\nenum EM_VAX =          75;\nenum EM_CRIS =         76;\nenum EM_JAVELIN =      77;\nenum EM_FIREPATH =     78;\nenum EM_ZSP =          79;\nenum EM_MMIX =         80;\nenum EM_HUANY =        81;\nenum EM_PRISM =        82;\nenum EM_AVR =          83;\nenum EM_FR30 =         84;\nenum EM_D10V =         85;\nenum EM_D30V =         86;\nenum EM_V850 =         87;\nenum EM_M32R =         88;\nenum EM_MN10300 =      89;\nenum EM_MN10200 =      90;\nenum EM_PJ =           91;\nenum EM_OPENRISC =     92;\nenum EM_ARC_A5 =       93;\nenum EM_XTENSA =       94;\nenum EM_VIDEOCORE =    95;\nenum EM_TMM_GPP =      96;\nenum EM_NS32K =        97;\nenum EM_TPC =          98;\nenum EM_SNP1K =        99;\nenum EM_ST200 =       100;\nenum EM_IP2K =        101;\nenum EM_MAX =         102;\nenum EM_CR =          103;\nenum EM_F2MC16 =      104;\nenum EM_MSP430 =      105;\nenum EM_BLACKFIN =    106;\nenum EM_SE_C33 =      107;\nenum EM_SEP =         108;\nenum EM_ARCA =        109;\nenum EM_UNICORE =     110;\n\nenum EM_486 =           6;\nenum EM_MIPS_RS4_BE =  10;\nenum EM_ALPHA_STD =    41;\nenum EM_ALPHA =    0x9026;\n\nenum SHN_UNDEF =       0;\nenum SHN_LORESERVE =   0xff00;\nenum SHN_LOPROC =      0xff00;\nenum SHN_HIPROC =      0xff1f;\nenum SHN_LOOS =        0xff20;\nenum SHN_HIOS =        0xff3f;\nenum SHN_ABS =         0xfff1;\nenum SHN_COMMON =      0xfff2;\nenum SHN_XINDEX =      0xffff;\nenum SHN_HIRESERVE =   0xffff;\n\nenum SHT_NULL =          0;\nenum SHT_PROGBITS =      1;\nenum SHT_SYMTAB =        2;\nenum SHT_STRTAB =        3;\nenum SHT_RELA =          4;\nenum SHT_HASH =          5;\nenum SHT_DYNAMIC =       6;\nenum SHT_NOTE =          7;\nenum SHT_NOBITS =        8;\nenum SHT_REL =           9;\nenum SHT_SHLIB =         10;\nenum SHT_DYNSYM =        11;\nenum SHT_INIT_ARRAY =    14;\nenum SHT_FINI_ARRAY =    15;\nenum SHT_PREINIT_ARRAY = 16;\nenum SHT_GROUP =         17;\nenum SHT_SYMTAB_SHNDX =  18;\nenum SHT_LOOS =          0x60000000;\nenum SHT_LOSUNW =        0x6ffffff4;\nenum SHT_SUNW_dof =      0x6ffffff4;\nenum SHT_SUNW_cap =      0x6ffffff5;\nenum SHT_SUNW_SIGNATURE = 0x6ffffff6;\nenum SHT_GNU_HASH =      0x6ffffff6;\nenum SHT_SUNW_ANNOTATE = 0x6ffffff7;\nenum SHT_SUNW_DEBUGSTR = 0x6ffffff8;\nenum SHT_SUNW_DEBUG =    0x6ffffff9;\nenum SHT_SUNW_move =     0x6ffffffa;\nenum SHT_SUNW_COMDAT =   0x6ffffffb;\nenum SHT_SUNW_syminfo =  0x6ffffffc;\nenum SHT_SUNW_verdef =   0x6ffffffd;\nenum SHT_GNU_verdef =    0x6ffffffd;\nenum SHT_SUNW_verneed =  0x6ffffffe;\nenum SHT_GNU_verneed =   0x6ffffffe;\nenum SHT_SUNW_versym =   0x6fffffff;\nenum SHT_GNU_versym =    0x6fffffff;\nenum SHT_HISUNW =        0x6fffffff;\nenum SHT_HIOS =          0x6fffffff;\nenum SHT_LOPROC =        0x70000000;\nenum SHT_AMD64_UNWIND =  0x70000001;\nenum SHT_ARM_EXIDX =     0x70000001;\nenum SHT_ARM_PREEMPTMAP = 0x70000002;\nenum SHT_ARM_ATTRIBUTES = 0x70000003;\nenum SHT_ARM_DEBUGOVERLAY = 0x70000004;\nenum SHT_ARM_OVERLAYSECTION = 0x70000005;\nenum SHT_MIPS_REGINFO =  0x70000006;\nenum SHT_MIPS_OPTIONS =  0x7000000d;\nenum SHT_MIPS_DWARF =    0x7000001e;\nenum SHT_HIPROC =        0x7fffffff;\nenum SHT_LOUSER =        0x80000000;\nenum SHT_HIUSER =        0x8fffffff;\n\nenum SHF_WRITE =            (1 << 0);\nenum SHF_ALLOC =            (1 << 1);\nenum SHF_EXECINSTR =        (1 << 2);\nenum SHF_MERGE =            (1 << 4);\nenum SHF_STRINGS =          (1 << 5);\nenum SHF_INFO_LINK =        (1 << 6);\nenum SHF_LINK_ORDER =       (1 << 7);\nenum SHF_OS_NONCONFORMING = (1 << 8);\nenum SHF_GROUP =            (1 << 9);\nenum SHF_TLS =              (1 << 10);\nenum SHF_COMPRESSED =       (1 << 11);\nenum SHF_MASKOS =           0x0ff00000;\nenum SHF_MASKPROC =         0xf0000000;\n\nenum PT_NULL =         0;\nenum PT_LOAD =         1;\nenum PT_DYNAMIC =      2;\nenum PT_INTERP =       3;\nenum PT_NOTE =         4;\nenum PT_SHLIB =        5;\nenum PT_PHDR =         6;\nenum PT_TLS =          7;\nenum PT_LOOS =         0x60000000;\nenum PT_SUNW_UNWIND =  0x6464e550;\nenum PT_GNU_EH_FRAME = 0x6474e550;\nenum PT_GNU_STACK =    0x6474e551;\nenum PT_GNU_RELRO =    0x6474e552;\nenum PT_LOSUNW =       0x6ffffffa;\nenum PT_SUNWBSS =      0x6ffffffa;\nenum PT_SUNWSTACK =    0x6ffffffb;\nenum PT_SUNWDTRACE =   0x6ffffffc;\nenum PT_SUNWCAP =      0x6ffffffd;\nenum PT_HISUNW =       0x6fffffff;\nenum PT_HIOS =         0x6fffffff;\nenum PT_LOPROC =       0x70000000;\nenum PT_HIPROC =       0x7fffffff;\n\nenum PF_X =            (1 << 0);\nenum PF_W =            (1 << 1);\nenum PF_R =            (1 << 2);\nenum PF_MASKOS =       0x0ff00000;\nenum PF_MASKPROC =     0xf0000000;\n\nenum PN_XNUM =         0xffff;\n\nenum DT_NULL =         0;\nenum DT_NEEDED =       1;\nenum DT_PLTRELSZ =     2;\nenum DT_PLTGOT =       3;\nenum DT_HASH =         4;\nenum DT_STRTAB =       5;\nenum DT_SYMTAB =       6;\nenum DT_RELA =         7;\nenum DT_RELASZ =       8;\nenum DT_RELAENT =      9;\nenum DT_STRSZ =        10;\nenum DT_SYMENT =       11;\nenum DT_INIT =         12;\nenum DT_FINI =         13;\nenum DT_SONAME =       14;\nenum DT_RPATH =        15;\nenum DT_SYMBOLIC =     16;\nenum DT_REL =          17;\nenum DT_RELSZ =        18;\nenum DT_RELENT =       19;\nenum DT_PLTREL =       20;\nenum DT_DEBUG =        21;\nenum DT_TEXTREL =      22;\nenum DT_JMPREL =       23;\nenum DT_BIND_NOW =     24;\nenum DT_INIT_ARRAY =   25;\nenum DT_FINI_ARRAY =   26;\nenum DT_INIT_ARRAYSZ = 27;\nenum DT_FINI_ARRAYSZ = 28;\nenum DT_RUNPATH =      29;\nenum DT_FLAGS =        30;\nenum DT_ENCODING =     32;\nenum DT_PREINIT_ARRAY = 32;\nenum DT_PREINIT_ARRAYSZ = 33;\nenum DT_MAXPOSTAGS =   34;\nenum DT_LOOS =         0x6000000d;\nenum DT_SUNW_AUXILIARY = 0x6000000d;\nenum DT_SUNW_RTLDINF = 0x6000000e;\nenum DT_SUNW_FILTER =  0x6000000f;\nenum DT_SUNW_CAP =     0x60000010;\nenum DT_HIOS =         0x6ffff000;\nenum DT_VALRNGLO =     0x6ffffd00;\nenum DT_CHECKSUM =     0x6ffffdf8;\nenum DT_PLTPADSZ =     0x6ffffdf9;\nenum DT_MOVEENT =      0x6ffffdfa;\nenum DT_MOVESZ =       0x6ffffdfb;\nenum DT_FEATURE_1 =    0x6ffffdfc;\nenum DT_POSFLAG_1 =    0x6ffffdfd;\nenum DT_SYMINSZ =      0x6ffffdfe;\nenum DT_SYMINENT =     0x6ffffdff;\nenum DT_VALRNGHI =     0x6ffffdff;\nenum DT_ADDRRNGLO =    0x6ffffe00;\nenum DT_GNU_HASH =     0x6ffffef5;\nenum DT_CONFIG =       0x6ffffefa;\nenum DT_DEPAUDIT =     0x6ffffefb;\nenum DT_AUDIT =        0x6ffffefc;\nenum DT_PLTPAD =       0x6ffffefd;\nenum DT_MOVETAB =      0x6ffffefe;\nenum DT_SYMINFO =      0x6ffffeff;\nenum DT_ADDRRNGHI =    0x6ffffeff;\nenum DT_VERSYM =       0x6ffffff0;\nenum DT_RELACOUNT =    0x6ffffff9;\nenum DT_RELCOUNT =     0x6ffffffa;\nenum DT_FLAGS_1 =      0x6ffffffb;\nenum DT_VERDEF =       0x6ffffffc;\nenum DT_VERDEFNUM =    0x6ffffffd;\nenum DT_VERNEED =      0x6ffffffe;\nenum DT_VERNEEDNUM =   0x6fffffff;\nenum DT_LOPROC =       0x70000000;\nenum DT_DEPRECATED_SPARC_REGISTER = 0x7000001;\nenum DT_AUXILIARY =    0x7ffffffd;\nenum DT_USED =         0x7ffffffe;\nenum DT_FILTER =       0x7fffffff;\nenum DT_HIPROC =       0x7fffffff;\n\nenum DF_ORIGIN =       0x00000001;\nenum DF_SYMBOLIC =     0x00000002;\nenum DF_TEXTREL =      0x00000004;\nenum DF_BIND_NOW =     0x00000008;\nenum DF_STATIC_TLS =   0x00000010;\n\nenum DF_1_BIND_NOW =   0x00000001;\nenum DF_1_GLOBAL =     0x00000002;\nenum DF_1_NODELETE =   0x00000008;\nenum DF_1_LOADFLTR =   0x00000010;\nenum DF_1_NOOPEN =     0x00000040;\nenum DF_1_NODEFLIB =   0x00000800;\n\nenum NT_PRSTATUS =     1;\nenum NT_FPREGSET =     2;\nenum NT_PRPSINFO =     3;\nenum NT_THRMISC =      7;\nenum NT_PROCSTAT_PROC = 8;\nenum NT_PROCSTAT_FILES = 9;\nenum NT_PROCSTAT_VMMAP = 10;\nenum NT_PROCSTAT_GROUPS = 11;\nenum NT_PROCSTAT_UMASK = 12;\nenum NT_PROCSTAT_RLIMIT = 13;\nenum NT_PROCSTAT_OSREL = 14;\nenum NT_PROCSTAT_PSSTRINGS = 15;\nenum NT_PROCSTAT_AUXV = 16;\n\nenum STB_LOCAL =       0;\nenum STB_GLOBAL =      1;\nenum STB_WEAK =        2;\nenum STB_NUM =         3;\nenum STB_LOOS =        10;\nenum STB_HIOS =        12;\nenum STB_LOPROC =      13;\nenum STB_HIPROC =      15;\n\nenum STT_NOTYPE =      0;\nenum STT_OBJECT =      1;\nenum STT_FUNC =        2;\nenum STT_SECTION =     3;\nenum STT_FILE =        4;\nenum STT_COMMON =      5;\nenum STT_TLS =         6;\nenum STT_NUM =         7;\nenum STT_LOOS =        10;\nenum STT_GNU_IFUNC =   10;\nenum STT_HIOS =        12;\nenum STT_LOPROC =      13;\nenum STT_HIPROC =      15;\n\nenum STV_DEFAULT =     0;\nenum STV_INTERNAL =    1;\nenum STV_HIDDEN =      2;\nenum STV_PROTECTED =   3;\nenum STV_EXPORTED =    4;\nenum STV_SINGLETON =   5;\nenum STV_ELIMINATE =   6;\n\nenum STN_UNDEF =       0;\n\nenum VER_DEF_CURRENT = 1;\nalias VER_NDX VER_DEF_IDX;\n\nenum VER_FLG_BASE =    0x1;\nenum VER_FLG_WEAK =    0x2;\n\nenum VER_NEED_CURRENT = 1;\nenum VER_NEED_WEAK =    32768;\nenum VER_NEED_HIDDEN = VER_NDX_HIDDEN;\nalias VER_NDX VER_NEED_IDX;\n\nenum VER_NDX_LOCAL =           0;\nenum VER_NDX_GLOBAL =          1;\nenum VER_NDX_GIVEN =           2;\n\nenum VER_NDX_HIDDEN =      32768;\nextern (D)\n{\n    auto VER_NDX(V)(V v) { return v & ~(1u << 15); }\n}\n\nenum CA_SUNW_NULL =    0;\nenum CA_SUNW_HW_1 =    1;\nenum CA_SUNW_SF_1 =    2;\n\nenum SYMINFO_FLG_DIRECT =      0x0001;\nenum SYMINFO_FLG_PASSTHRU =    0x0002;\nenum SYMINFO_FLG_COPY =        0x0004;\nenum SYMINFO_FLG_LAZYLOAD =    0x0008;\nenum SYMINFO_FLG_DIRECTBIND =  0x0010;\nenum SYMINFO_FLG_NOEXTDIRECT = 0x0020;\nenum SYMINFO_FLG_FILTER =      0x0002;\nenum SYMINFO_FLG_AUXILIARY =   0x0040;\n\nenum SYMINFO_BT_SELF =         0xffff;\nenum SYMINFO_BT_PARENT =       0xfffe;\nenum SYMINFO_BT_NONE =         0xfffd;\nenum SYMINFO_BT_EXTERN =       0xfffc;\nenum SYMINFO_BT_LOWRESERVE =   0xff00;\n\nenum SYMINFO_NONE =            0;\nenum SYMINFO_CURRENT =         1;\nenum SYMINFO_NUM =             2;\n\nenum R_386_NONE =               0;\nenum R_386_32 =                 1;\nenum R_386_PC32 =               2;\nenum R_386_GOT32 =              3;\nenum R_386_PLT32 =              4;\nenum R_386_COPY =               5;\nenum R_386_GLOB_DAT =           6;\nenum R_386_JMP_SLOT =           7;\nenum R_386_RELATIVE =           8;\nenum R_386_GOTOFF =             9;\nenum R_386_GOTPC =              10;\nenum R_386_TLS_TPOFF =          14;\nenum R_386_TLS_IE =             15;\nenum R_386_TLS_GOTIE =          16;\nenum R_386_TLS_LE =             17;\nenum R_386_TLS_GD =             18;\nenum R_386_TLS_LDM =            19;\nenum R_386_TLS_GD_32 =          24;\nenum R_386_TLS_GD_PUSH =        25;\nenum R_386_TLS_GD_CALL =        26;\nenum R_386_TLS_GD_POP =         27;\nenum R_386_TLS_LDM_32 =         28;\nenum R_386_TLS_LDM_PUSH =       29;\nenum R_386_TLS_LDM_CALL =       30;\nenum R_386_TLS_LDM_POP =        31;\nenum R_386_TLS_LDO_32 =         32;\nenum R_386_TLS_IE_32 =          33;\nenum R_386_TLS_LE_32 =          34;\nenum R_386_TLS_DTPMOD32 =       35;\nenum R_386_TLS_DTPOFF32 =       36;\nenum R_386_TLS_TPOFF32 =        37;\nenum R_386_IRELATIVE =          42;\n\nenum R_ARM_NONE =               0;\nenum R_ARM_PC24 =               1;\nenum R_ARM_ABS32 =              2;\nenum R_ARM_REL32 =              3;\nenum R_ARM_PC13 =               4;\nenum R_ARM_ABS16 =              5;\nenum R_ARM_ABS12 =              6;\nenum R_ARM_THM_ABS5 =           7;\nenum R_ARM_ABS8 =               8;\nenum R_ARM_SBREL32 =            9;\nenum R_ARM_THM_PC22 =           10;\nenum R_ARM_THM_PC8 =            11;\nenum R_ARM_AMP_VCALL9 =         12;\nenum R_ARM_SWI24 =              13;\nenum R_ARM_THM_SWI8 =           14;\nenum R_ARM_XPC25 =              15;\nenum R_ARM_THM_XPC22 =          16;\nenum R_ARM_TLS_DTPMOD32 =       17;\nenum R_ARM_TLS_DTPOFF32 =       18;\nenum R_ARM_TLS_TPOFF32 =        19;\nenum R_ARM_COPY =               20;\nenum R_ARM_GLOB_DAT =           21;\nenum R_ARM_JUMP_SLOT =          22;\nenum R_ARM_RELATIVE =           23;\nenum R_ARM_GOTOFF =             24;\nenum R_ARM_GOTPC =              25;\nenum R_ARM_GOT32 =              26;\nenum R_ARM_PLT32 =              27;\nenum R_ARM_GNU_VTENTRY =        100;\nenum R_ARM_GNU_VTINHERIT =      101;\nenum R_ARM_RSBREL32 =           250;\nenum R_ARM_THM_RPC22 =          251;\nenum R_ARM_RREL32 =             252;\nenum R_ARM_RABS32 =             253;\nenum R_ARM_RPC24 =              254;\nenum R_ARM_RBASE =              255;\n\nenum R_IA_64_NONE =             0;\nenum R_IA_64_IMM14 =            0x21;\nenum R_IA_64_IMM22 =            0x22;\nenum R_IA_64_IMM64 =            0x23;\nenum R_IA_64_DIR32MSB =         0x24;\nenum R_IA_64_DIR32LSB =         0x25;\nenum R_IA_64_DIR64MSB =         0x26;\nenum R_IA_64_DIR64LSB =         0x27;\nenum R_IA_64_GPREL22 =          0x2a;\nenum R_IA_64_GPREL64I =         0x2b;\nenum R_IA_64_GPREL32MSB =       0x2c;\nenum R_IA_64_GPREL32LSB =       0x2d;\nenum R_IA_64_GPREL64MSB =       0x2e;\nenum R_IA_64_GPREL64LSB =       0x2f;\nenum R_IA_64_LTOFF22 =          0x32;\nenum R_IA_64_LTOFF64I =         0x33;\nenum R_IA_64_PLTOFF22 =         0x3a;\nenum R_IA_64_PLTOFF64I =        0x3b;\nenum R_IA_64_PLTOFF64MSB =      0x3e;\nenum R_IA_64_PLTOFF64LSB =      0x3f;\nenum R_IA_64_FPTR64I =          0x43;\nenum R_IA_64_FPTR32MSB =        0x44;\nenum R_IA_64_FPTR32LSB =        0x45;\nenum R_IA_64_FPTR64MSB =        0x46;\nenum R_IA_64_FPTR64LSB =        0x47;\nenum R_IA_64_PCREL60B =         0x48;\nenum R_IA_64_PCREL21B =         0x49;\nenum R_IA_64_PCREL21M =         0x4a;\nenum R_IA_64_PCREL21F =         0x4b;\nenum R_IA_64_PCREL32MSB =       0x4c;\nenum R_IA_64_PCREL32LSB =       0x4d;\nenum R_IA_64_PCREL64MSB =       0x4e;\nenum R_IA_64_PCREL64LSB =       0x4f;\nenum R_IA_64_LTOFF_FPTR22 =     0x52;\nenum R_IA_64_LTOFF_FPTR64I =    0x53;\nenum R_IA_64_LTOFF_FPTR32MSB =  0x54;\nenum R_IA_64_LTOFF_FPTR32LSB =  0x55;\nenum R_IA_64_LTOFF_FPTR64MSB =  0x56;\nenum R_IA_64_LTOFF_FPTR64LSB =  0x57;\nenum R_IA_64_SEGREL32MSB =      0x5c;\nenum R_IA_64_SEGREL32LSB =      0x5d;\nenum R_IA_64_SEGREL64MSB =      0x5e;\nenum R_IA_64_SEGREL64LSB =      0x5f;\nenum R_IA_64_SECREL32MSB =      0x64;\nenum R_IA_64_SECREL32LSB =      0x65;\nenum R_IA_64_SECREL64MSB =      0x66;\nenum R_IA_64_SECREL64LSB =      0x67;\nenum R_IA_64_REL32MSB =         0x6c;\nenum R_IA_64_REL32LSB =         0x6d;\nenum R_IA_64_REL64MSB =         0x6e;\nenum R_IA_64_REL64LSB =         0x6f;\nenum R_IA_64_LTV32MSB =         0x74;\nenum R_IA_64_LTV32LSB =         0x75;\nenum R_IA_64_LTV64MSB =         0x76;\nenum R_IA_64_LTV64LSB =         0x77;\nenum R_IA_64_PCREL21BI =        0x79;\nenum R_IA_64_PCREL22 =          0x7a;\nenum R_IA_64_PCREL64I =         0x7b;\nenum R_IA_64_IPLTMSB =          0x80;\nenum R_IA_64_IPLTLSB =          0x81;\nenum R_IA_64_SUB =              0x85;\nenum R_IA_64_LTOFF22X =         0x86;\nenum R_IA_64_LDXMOV =           0x87;\nenum R_IA_64_TPREL14 =          0x91;\nenum R_IA_64_TPREL22 =          0x92;\nenum R_IA_64_TPREL64I =         0x93;\nenum R_IA_64_TPREL64MSB =       0x96;\nenum R_IA_64_TPREL64LSB =       0x97;\nenum R_IA_64_LTOFF_TPREL22 =    0x9a;\nenum R_IA_64_DTPMOD64MSB =      0xa6;\nenum R_IA_64_DTPMOD64LSB =      0xa7;\nenum R_IA_64_LTOFF_DTPMOD22 =   0xaa;\nenum R_IA_64_DTPREL14 =         0xb1;\nenum R_IA_64_DTPREL22 =         0xb2;\nenum R_IA_64_DTPREL64I =        0xb3;\nenum R_IA_64_DTPREL32MSB =      0xb4;\nenum R_IA_64_DTPREL32LSB =      0xb5;\nenum R_IA_64_DTPREL64MSB =      0xb6;\nenum R_IA_64_DTPREL64LSB =      0xb7;\nenum R_IA_64_LTOFF_DTPREL22 =   0xba;\n\nenum R_MIPS_NONE =              0;\nenum R_MIPS_16 =                1;\nenum R_MIPS_32 =                2;\nenum R_MIPS_REL32 =             3;\nenum R_MIPS_26 =                4;\nenum R_MIPS_HI16 =              5;\nenum R_MIPS_LO16 =              6;\nenum R_MIPS_GPREL16 =           7;\nenum R_MIPS_LITERAL =           8;\nenum R_MIPS_GOT16 =             9;\nenum R_MIPS_PC16 =              10;\nenum R_MIPS_CALL16 =            11;\nenum R_MIPS_GPREL32 =           12;\nenum R_MIPS_GOTHI16 =           21;\nenum R_MIPS_GOTLO16 =           22;\nenum R_MIPS_CALLHI16 =          30;\nenum R_MIPS_CALLLO16 =          31;\n\nenum R_PPC_NONE =               0;\nenum R_PPC_ADDR32 =             1;\nenum R_PPC_ADDR24 =             2;\nenum R_PPC_ADDR16 =             3;\nenum R_PPC_ADDR16_LO =          4;\nenum R_PPC_ADDR16_HI =          5;\nenum R_PPC_ADDR16_HA =          6;\nenum R_PPC_ADDR14 =             7;\nenum R_PPC_ADDR14_BRTAKEN =     8;\nenum R_PPC_ADDR14_BRNTAKEN =    9;\nenum R_PPC_REL24 =              10;\nenum R_PPC_REL14 =              11;\nenum R_PPC_REL14_BRTAKEN =      12;\nenum R_PPC_REL14_BRNTAKEN =     13;\nenum R_PPC_GOT16 =              14;\nenum R_PPC_GOT16_LO =           15;\nenum R_PPC_GOT16_HI =           16;\nenum R_PPC_GOT16_HA =           17;\nenum R_PPC_PLTREL24 =           18;\nenum R_PPC_COPY =               19;\nenum R_PPC_GLOB_DAT =           20;\nenum R_PPC_JMP_SLOT =           21;\nenum R_PPC_RELATIVE =           22;\nenum R_PPC_LOCAL24PC =          23;\nenum R_PPC_UADDR32 =            24;\nenum R_PPC_UADDR16 =            25;\nenum R_PPC_REL32 =              26;\nenum R_PPC_PLT32 =              27;\nenum R_PPC_PLTREL32 =           28;\nenum R_PPC_PLT16_LO =           29;\nenum R_PPC_PLT16_HI =           30;\nenum R_PPC_PLT16_HA =           31;\nenum R_PPC_SDAREL16 =           32;\nenum R_PPC_SECTOFF =            33;\nenum R_PPC_SECTOFF_LO =         34;\nenum R_PPC_SECTOFF_HI =         35;\nenum R_PPC_SECTOFF_HA =         36;\n\nenum R_PPC64_ADDR64 =           38;\nenum R_PPC64_ADDR16_HIGHER =    39;\nenum R_PPC64_ADDR16_HIGHERA =   40;\nenum R_PPC64_ADDR16_HIGHEST =   41;\nenum R_PPC64_ADDR16_HIGHESTA =  42;\nenum R_PPC64_UADDR64 =          43;\nenum R_PPC64_REL64 =            44;\nenum R_PPC64_PLT64 =            45;\nenum R_PPC64_PLTREL64 =         46;\nenum R_PPC64_TOC16 =            47;\nenum R_PPC64_TOC16_LO =         48;\nenum R_PPC64_TOC16_HI =         49;\nenum R_PPC64_TOC16_HA =         50;\nenum R_PPC64_TOC =              51;\nenum R_PPC64_DTPMOD64 =         68;\nenum R_PPC64_TPREL64 =          73;\nenum R_PPC64_DTPREL64 =         78;\n\nenum R_PPC_TLS =                67;\nenum R_PPC_DTPMOD32 =           68;\nenum R_PPC_TPREL16 =            69;\nenum R_PPC_TPREL16_LO =         70;\nenum R_PPC_TPREL16_HI =         71;\nenum R_PPC_TPREL16_HA =         72;\nenum R_PPC_TPREL32 =            73;\nenum R_PPC_DTPREL16 =           74;\nenum R_PPC_DTPREL16_LO =        75;\nenum R_PPC_DTPREL16_HI =        76;\nenum R_PPC_DTPREL16_HA =        77;\nenum R_PPC_DTPREL32 =           78;\nenum R_PPC_GOT_TLSGD16 =        79;\nenum R_PPC_GOT_TLSGD16_LO =     80;\nenum R_PPC_GOT_TLSGD16_HI =     81;\nenum R_PPC_GOT_TLSGD16_HA =     82;\nenum R_PPC_GOT_TLSLD16 =        83;\nenum R_PPC_GOT_TLSLD16_LO =     84;\nenum R_PPC_GOT_TLSLD16_HI =     85;\nenum R_PPC_GOT_TLSLD16_HA =     86;\nenum R_PPC_GOT_TPREL16 =        87;\nenum R_PPC_GOT_TPREL16_LO =     88;\nenum R_PPC_GOT_TPREL16_HI =     89;\nenum R_PPC_GOT_TPREL16_HA =     90;\n\nenum R_PPC_EMB_NADDR32 =        101;\nenum R_PPC_EMB_NADDR16 =        102;\nenum R_PPC_EMB_NADDR16_LO =     103;\nenum R_PPC_EMB_NADDR16_HI =     104;\nenum R_PPC_EMB_NADDR16_HA =     105;\nenum R_PPC_EMB_SDAI16 =         106;\nenum R_PPC_EMB_SDA2I16 =        107;\nenum R_PPC_EMB_SDA2REL =        108;\nenum R_PPC_EMB_SDA21 =          109;\nenum R_PPC_EMB_MRKREF =         110;\nenum R_PPC_EMB_RELSEC16 =       111;\nenum R_PPC_EMB_RELST_LO =       112;\nenum R_PPC_EMB_RELST_HI =       113;\nenum R_PPC_EMB_RELST_HA =       114;\nenum R_PPC_EMB_BIT_FLD =        115;\nenum R_PPC_EMB_RELSDA =         116;\n\nenum R_SPARC_NONE =             0;\nenum R_SPARC_8 =                1;\nenum R_SPARC_16 =               2;\nenum R_SPARC_32 =               3;\nenum R_SPARC_DISP8 =            4;\nenum R_SPARC_DISP16 =           5;\nenum R_SPARC_DISP32 =           6;\nenum R_SPARC_WDISP30 =          7;\nenum R_SPARC_WDISP22 =          8;\nenum R_SPARC_HI22 =             9;\nenum R_SPARC_22 =               10;\nenum R_SPARC_13 =               11;\nenum R_SPARC_LO10 =             12;\nenum R_SPARC_GOT10 =            13;\nenum R_SPARC_GOT13 =            14;\nenum R_SPARC_GOT22 =            15;\nenum R_SPARC_PC10 =             16;\nenum R_SPARC_PC22 =             17;\nenum R_SPARC_WPLT30 =           18;\nenum R_SPARC_COPY =             19;\nenum R_SPARC_GLOB_DAT =         20;\nenum R_SPARC_JMP_SLOT =         21;\nenum R_SPARC_RELATIVE =         22;\nenum R_SPARC_UA32 =             23;\nenum R_SPARC_PLT32 =            24;\nenum R_SPARC_HIPLT22 =          25;\nenum R_SPARC_LOPLT10 =          26;\nenum R_SPARC_PCPLT32 =          27;\nenum R_SPARC_PCPLT22 =          28;\nenum R_SPARC_PCPLT10 =          29;\nenum R_SPARC_10 =               30;\nenum R_SPARC_11 =               31;\nenum R_SPARC_64 =               32;\nenum R_SPARC_OLO10 =            33;\nenum R_SPARC_HH22 =             34;\nenum R_SPARC_HM10 =             35;\nenum R_SPARC_LM22 =             36;\nenum R_SPARC_PC_HH22 =          37;\nenum R_SPARC_PC_HM10 =          38;\nenum R_SPARC_PC_LM22 =          39;\nenum R_SPARC_WDISP16 =          40;\nenum R_SPARC_WDISP19 =          41;\nenum R_SPARC_GLOB_JMP =         42;\nenum R_SPARC_7 =                43;\nenum R_SPARC_5 =                44;\nenum R_SPARC_6 =                45;\nenum R_SPARC_DISP64 =           46;\nenum R_SPARC_PLT64 =            47;\nenum R_SPARC_HIX22 =            48;\nenum R_SPARC_LOX10 =            49;\nenum R_SPARC_H44 =              50;\nenum R_SPARC_M44 =              51;\nenum R_SPARC_L44 =              52;\nenum R_SPARC_REGISTER =         53;\nenum R_SPARC_UA64 =             54;\nenum R_SPARC_UA16 =             55;\nenum R_SPARC_TLS_GD_HI22 =      56;\nenum R_SPARC_TLS_GD_LO10 =      57;\nenum R_SPARC_TLS_GD_ADD =       58;\nenum R_SPARC_TLS_GD_CALL =      59;\nenum R_SPARC_TLS_LDM_HI22 =     60;\nenum R_SPARC_TLS_LDM_LO10 =     61;\nenum R_SPARC_TLS_LDM_ADD =      62;\nenum R_SPARC_TLS_LDM_CALL =     63;\nenum R_SPARC_TLS_LDO_HIX22 =    64;\nenum R_SPARC_TLS_LDO_LOX10 =    65;\nenum R_SPARC_TLS_LDO_ADD =      66;\nenum R_SPARC_TLS_IE_HI22 =      67;\nenum R_SPARC_TLS_IE_LO10 =      68;\nenum R_SPARC_TLS_IE_LD =        69;\nenum R_SPARC_TLS_IE_LDX =       70;\nenum R_SPARC_TLS_IE_ADD =       71;\nenum R_SPARC_TLS_LE_HIX22 =     72;\nenum R_SPARC_TLS_LE_LOX10 =     73;\nenum R_SPARC_TLS_DTPMOD32 =     74;\nenum R_SPARC_TLS_DTPMOD64 =     75;\nenum R_SPARC_TLS_DTPOFF32 =     76;\nenum R_SPARC_TLS_DTPOFF64 =     77;\nenum R_SPARC_TLS_TPOFF32 =      78;\nenum R_SPARC_TLS_TPOFF64 =      79;\n\nenum R_X86_64_NONE =            0;\nenum R_X86_64_64 =              1;\nenum R_X86_64_PC32 =            2;\nenum R_X86_64_GOT32 =           3;\nenum R_X86_64_PLT32 =           4;\nenum R_X86_64_COPY =            5;\nenum R_X86_64_GLOB_DAT =        6;\nenum R_X86_64_JMP_SLOT =        7;\nenum R_X86_64_RELATIVE =        8;\nenum R_X86_64_GOTPCREL =        9;\nenum R_X86_64_32 =              10;\nenum R_X86_64_32S =             11;\nenum R_X86_64_16 =              12;\nenum R_X86_64_PC16 =            13;\nenum R_X86_64_8 =               14;\nenum R_X86_64_PC8 =             15;\nenum R_X86_64_DTPMOD64 =        16;\nenum R_X86_64_DTPOFF64 =        17;\nenum R_X86_64_TPOFF64 =         18;\nenum R_X86_64_TLSGD =           19;\nenum R_X86_64_TLSLD =           20;\nenum R_X86_64_DTPOFF32 =        21;\nenum R_X86_64_GOTTPOFF =        22;\nenum R_X86_64_TPOFF32 =         23;\nenum R_X86_64_IRELATIVE =       37;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/sys/event.d",
    "content": "/**\n * D header file for FreeBSD.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n */\n\n/*          Copyright Martin Nowak 2012.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.freebsd.sys.event;\n\nversion (FreeBSD):\nextern (C):\nnothrow:\n@nogc:\n\nimport core.stdc.stdint;    // intptr_t, uintptr_t\nimport core.sys.posix.time; // timespec\n\nenum\n{\n    EVFILT_READ     =  -1,\n    EVFILT_WRITE    =  -2,\n    EVFILT_AIO      =  -3, /* attached to aio requests */\n    EVFILT_VNODE    =  -4, /* attached to vnodes */\n    EVFILT_PROC     =  -5, /* attached to struct proc */\n    EVFILT_SIGNAL   =  -6, /* attached to struct proc */\n    EVFILT_TIMER    =  -7, /* timers */\n    EVFILT_PROCDESC =  -8, /* attached to process descriptors */\n    EVFILT_FS       =  -9, /* filesystem events */\n    EVFILT_LIO      = -10, /* attached to lio requests */\n    EVFILT_USER     = -11, /* User events */\n    EVFILT_SENDFILE = -12, /* attached to sendfile requests */\n    EVFILT_SYSCOUNT =  11,\n}\n\nextern(D) void EV_SET(kevent_t* kevp, typeof(kevent_t.tupleof) args)\n{\n    *kevp = kevent_t(args);\n}\n\nstruct kevent_t\n{\n    uintptr_t    ident; /* identifier for this event */\n    short       filter; /* filter for event */\n    ushort       flags;\n    uint        fflags;\n    intptr_t      data;\n    void        *udata; /* opaque user data identifier */\n}\n\nenum\n{\n    /* actions */\n    EV_ADD          = 0x0001, /* add event to kq (implies enable) */\n    EV_DELETE       = 0x0002, /* delete event from kq */\n    EV_ENABLE       = 0x0004, /* enable event */\n    EV_DISABLE      = 0x0008, /* disable event (not reported) */\n    EV_FORCEONESHOT = 0x0100,          /* enable _ONESHOT and force trigger */\n\n    /* flags */\n    EV_ONESHOT      = 0x0010, /* only report one occurrence */\n    EV_CLEAR        = 0x0020, /* clear event state after reporting */\n    EV_RECEIPT      = 0x0040, /* force EV_ERROR on success, data=0 */\n    EV_DISPATCH     = 0x0080, /* disable event after reporting */\n\n    EV_SYSFLAGS     = 0xF000, /* reserved by system */\n    EV_DROP         = 0x1000, /* note should be dropped */\n    EV_FLAG1        = 0x2000, /* filter-specific flag */\n    EV_FLAG2        = 0x4000, /* filter-specific flag */\n\n    /* returned values */\n    EV_EOF          = 0x8000, /* EOF detected */\n    EV_ERROR        = 0x4000, /* error, data contains errno */\n}\n\nenum\n{\n    /*\n     * data/hint flags/masks for EVFILT_USER, shared with userspace\n     *\n     * On input, the top two bits of fflags specifies how the lower twenty four\n     * bits should be applied to the stored value of fflags.\n     *\n     * On output, the top two bits will always be set to NOTE_FFNOP and the\n     * remaining twenty four bits will contain the stored fflags value.\n     */\n    NOTE_FFNOP      = 0x00000000, /* ignore input fflags */\n    NOTE_FFAND      = 0x40000000, /* AND fflags */\n    NOTE_FFOR       = 0x80000000, /* OR fflags */\n    NOTE_FFCOPY     = 0xc0000000, /* copy fflags */\n    NOTE_FFCTRLMASK = 0xc0000000, /* masks for operations */\n    NOTE_FFLAGSMASK = 0x00ffffff,\n\n    NOTE_TRIGGER    = 0x01000000, /* Cause the event to be\n                                  triggered for output. */\n\n    /*\n     * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace\n     */\n    NOTE_LOWAT      = 0x0001, /* low water mark */\n    NOTE_FILE_POLL  = 0x0002, /* behave like poll() */\n\n    /*\n     * data/hint flags for EVFILT_VNODE, shared with userspace\n     */\n    NOTE_DELETE     = 0x0001, /* vnode was removed */\n    NOTE_WRITE      = 0x0002, /* data contents changed */\n    NOTE_EXTEND     = 0x0004, /* size increased */\n    NOTE_ATTRIB     = 0x0008, /* attributes changed */\n    NOTE_LINK       = 0x0010, /* link count changed */\n    NOTE_RENAME     = 0x0020, /* vnode was renamed */\n    NOTE_REVOKE     = 0x0040, /* vnode access was revoked */\n    NOTE_OPEN       = 0x0080, /* vnode was opened */\n    NOTE_CLOSE      = 0x0100, /* file closed, fd did not\n                                 allowed write */\n    NOTE_CLOSE_WRITE = 0x0200, /* file closed, fd did allowed\n                                  write */\n    NOTE_READ       = 0x0400, /* file was read */\n\n    /*\n     * data/hint flags for EVFILT_PROC and EVFILT_PROCDESC, shared with userspace\n     */\n    NOTE_EXIT       = 0x80000000, /* process exited */\n    NOTE_FORK       = 0x40000000, /* process forked */\n    NOTE_EXEC       = 0x20000000, /* process exec'd */\n    NOTE_PCTRLMASK  = 0xf0000000, /* mask for hint bits */\n    NOTE_PDATAMASK  = 0x000fffff, /* mask for pid */\n\n    /* additional flags for EVFILT_PROC */\n    NOTE_TRACK      = 0x00000001, /* follow across forks */\n    NOTE_TRACKERR   = 0x00000002, /* could not track child */\n    NOTE_CHILD      = 0x00000004, /* am a child process */\n\n    /* additional flags for EVFILT_TIMER */\n    NOTE_SECONDS    = 0x00000001, /* data is seconds */\n    NOTE_MSECONDS   = 0x00000002, /* data is milliseconds */\n    NOTE_USECONDS   = 0x00000004, /* data is microseconds */\n    NOTE_NSECONDS   = 0x00000008, /* data is nanoseconds */\n}\n\nint kqueue();\nint kevent(int kq, const kevent_t *changelist, int nchanges,\n           kevent_t *eventlist, int nevents,\n           const timespec *timeout);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/sys/link_elf.d",
    "content": "/**\n * D header file for FreeBSD.\n *\n * $(LINK2 http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?view=markup, sys/link_elf.h)\n */\nmodule core.sys.freebsd.sys.link_elf;\n\nversion (FreeBSD):\nextern (C):\nnothrow:\n\nimport core.stdc.stdint : uint64_t;\nimport core.sys.freebsd.sys.elf;\n\nversion (D_LP64)\n    enum __ELF_NATIVE_CLASS = 64;\nelse\n    enum __ELF_NATIVE_CLASS = 32;\n\ntemplate ElfW(string type)\n{\n    mixin(\"alias Elf\"~__ELF_NATIVE_CLASS.stringof~\"_\"~type~\" ElfW;\");\n}\n\nenum LA_SER_ORIG =      0x01;\nenum LA_SER_LIBPATH =   0x02;\nenum LA_SER_RUNPATH =   0x04;\nenum LA_SER_CONFIG =    0x08;\nenum LA_SER_DEFAULT =   0x40;\nenum LA_SER_SECURE =    0x80;\n\nstruct link_map\n{\n    char*           l_addr;\n\n    version (MIPS32)\n        char*       l_offs;\n    version (MIPS64)\n        char*       l_offs;\n\n    char*           l_name;\n    void*           l_ld;\n    link_map*       l_next, l_prev;\n}\nalias link_map Link_map;\n\nenum\n{\n    RT_CONSISTENT,\n    RT_ADD,\n    RT_DELETE,\n}\n\nstruct r_debug\n{\n    int             r_version;\n    link_map*       r_map;\n    void function(r_debug*, link_map*) r_brk;\n};\n\nstruct dl_phdr_info\n{\n    ElfW!\"Addr\"     dlpi_addr;\n    char*           dlpi_name;\n    ElfW!\"Phdr\"*    dlpi_phdr;\n    ElfW!\"Half\"     dlpi_phnum;\n    uint64_t        dlpi_adds;\n    uint64_t        dlpi_subs;\n    size_t          dlpi_tls_modid;\n    void*           dlpi_tls_data;\n};\n\n\nprivate alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;\nprivate alias extern(C) int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_cb_ngc;\nextern int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data);\nextern int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc;\nextern int _rtld_addr_phdr(const void*, dl_phdr_info*) @nogc;\nextern int _rtld_get_stack_prot() @nogc;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/sys/mman.d",
    "content": "/**\n * D header file for FreeBSD\n *\n * Authors: Martin Nowak\n */\nmodule core.sys.freebsd.sys.mman;\n\nversion (FreeBSD):\nextern (C):\nnothrow:\n\npublic import core.sys.posix.sys.mman;\nimport core.sys.freebsd.sys.cdefs;\nimport core.sys.posix.sys.types;\n// https://svnweb.freebsd.org/base/head/sys/sys/mman.h?revision=270825&view=markup\n\nstatic if (__BSD_VISIBLE)\n{\n    enum INHERIT_SHARE = 0;\n    enum INHERIT_COPY = 1;\n    enum INHERIT_NONE = 2;\n}\n\n// already in core.sys.posix.sys.mman\n// enum PROT_NONE = 0x00;\n// enum PROT_READ = 0x01;\n// enum PROT_WRITE = 0x02;\n// enum PROT_EXEC = 0x04;\n// enum MAP_SHARED = 0x0001;\n// enum MAP_PRIVATE = 0x0002;\nstatic if (__BSD_VISIBLE)\n    alias MAP_COPY = MAP_PRIVATE;\n// enum MAP_FIXED = 0x0010;\n\nstatic if (__BSD_VISIBLE)\n{\n    enum MAP_RENAME = 0x0020;\n    enum MAP_NORESERVE = 0x0040;\n    enum MAP_RESERVED0080 = 0x0080;\n    enum MAP_RESERVED0100 = 0x0100;\n    enum MAP_HASSEMAPHORE = 0x0200;\n    enum MAP_STACK = 0x0400;\n    enum MAP_NOSYNC = 0x0800;\n\n    enum MAP_FILE = 0x0000;\n\n    // already in core.sys.posix.sys.mman\n    // enum MAP_ANON = 0x1000;\n    //#ifndef _KERNEL\n    alias MAP_ANONYMOUS = MAP_ANON;\n    //#endif /* !_KERNEL */\n\n    enum MAP_EXCL = 0x00004000;\n    enum MAP_NOCORE = 0x00020000;\n    enum MAP_PREFAULT_READ = 0x00040000;\n    version (LP64)\n        enum MAP_32BIT = 0x00080000;\n\n\n    extern(D) int MAP_ALIGNED(int n) { return n << MAP_ALIGNMENT_SHIFT; }\n    enum MAP_ALIGNMENT_SHIFT = 24;\n    enum MAP_ALIGNMENT_MASK = MAP_ALIGNED(0xff);\n    enum MAP_ALIGNED_SUPER = MAP_ALIGNED(1);\n}\n\nstatic if (__POSIX_VISIBLE >= 199309)\n{\n    // already in core.sys.posix.sys.mman\n    // enum MCL_CURRENT = 0x0001;\n    // enum MCL_FUTURE = 0x0002;\n}\n\n// already in core.sys.posix.sys.mman\nenum MAP_FAILED = cast(void*)-1;\n\n// already in core.sys.posix.sys.mman\n// enum MS_SYNC = 0x0000;\n// enum MS_ASYNC = 0x0001;\n// enum MS_INVALIDATE = 0x0002;\n\nenum _MADV_NORMAL = 0;\nenum _MADV_RANDOM = 1;\nenum _MADV_SEQUENTIAL = 2;\nenum _MADV_WILLNEED = 3;\nenum _MADV_DONTNEED = 4;\n\nstatic if (__BSD_VISIBLE)\n{\n    alias MADV_NORMAL = _MADV_NORMAL;\n    alias MADV_RANDOM = _MADV_RANDOM;\n    alias MADV_SEQUENTIAL = _MADV_SEQUENTIAL;\n    alias MADV_WILLNEED = _MADV_WILLNEED;\n    alias MADV_DONTNEED = _MADV_DONTNEED;\n    enum MADV_FREE = 5;\n    enum MADV_NOSYNC = 6;\n    enum MADV_AUTOSYNC = 7;\n    enum MADV_NOCORE = 8;\n    enum MADV_CORE = 9;\n    enum MADV_PROTECT = 10;\n\n    enum MINCORE_INCORE = 0x1;\n    enum MINCORE_REFERENCED = 0x2;\n    enum MINCORE_MODIFIED = 0x4;\n    enum MINCORE_REFERENCED_OTHER = 0x8;\n    enum MINCORE_MODIFIED_OTHER = 0x10;\n    enum MINCORE_SUPER = 0x20;\n\n    enum SHM_ANON = cast(const(char) *)1;\n}\n\nstatic if (__POSIX_VISIBLE >= 200112)\n{\n    // already in core.sys.posix.sys.mman\n    // alias POSIX_MADV_NORMAL = _MADV_NORMAL;\n    // alias POSIX_MADV_RANDOM = _MADV_RANDOM;\n    // alias POSIX_MADV_SEQUENTIAL = _MADV_SEQUENTIAL;\n    // alias POSIX_MADV_WILLNEED = _MADV_WILLNEED;\n    // alias POSIX_MADV_DONTNEED = _MADV_DONTNEED;\n}\n\nstatic if (__BSD_VISIBLE)\n{\n    int getpagesizes(size_t *, int);\n    int madvise(void *, size_t, int);\n    int mincore(const(void) *, size_t, char *);\n    int minherit(void *, size_t, int);\n}\n// already in core.sys.posix.sys.mman\n// int mlock(const void *, size_t);\n// void *  mmap(void *, size_t, int, int, int, off_t);\n// int mprotect(const void *, size_t, int);\n// int msync(void *, size_t, int);\n// int munlock(const void *, size_t);\n// int munmap(void *, size_t);\nstatic if (__POSIX_VISIBLE >= 200112)\n    // int posix_madvise(void *, size_t, int);\nstatic if (__POSIX_VISIBLE >= 199309)\n{\n    // int mlockall(int);\n    // int munlockall();\n    // int shm_open(const(char) *, int, mode_t);\n    // int shm_unlink(const(char) *);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/sys/mount.d",
    "content": "//Written in the D programming language\n\n/++\n    D header file for FreeBSD's sys/mount.h.\n\n    Copyright: Copyright 2018 -\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n +/\nmodule core.sys.freebsd.sys.mount;\n\nversion (FreeBSD):\n\nimport core.stdc.config : c_long;\nimport core.sys.posix.sys.stat : stat_t;\nimport core.sys.posix.sys.types : uid_t;\n\nextern(C) @nogc nothrow:\n\nstruct fsid_t\n{\n    int[2] val;\n}\n\nenum MAXFIDSZ = 16;\n\nstruct fid\n{\n    ushort         fid_len;\n    ushort         fid_data0;\n    char[MAXFIDSZ] fid_data;\n}\n\nenum MFSNAMELEN = 16;\nenum MNAMELEN   = 88;\nenum STATFS_VERSION = 0x20030518;\n\nstruct statfs_t\n{\n    uint f_version;\n    uint f_type;\n    ulong f_flags;\n    ulong f_bsize;\n    ulong f_iosize;\n    ulong f_blocks;\n    ulong f_bfree;\n    long  f_bavail;\n    ulong f_files;\n    long  f_ffree;\n    ulong f_syncwrites;\n    ulong f_asyncwrites;\n    ulong f_syncreads;\n    ulong f_asyncreads;\n    ulong[10] f_spare;\n    uint f_namemax;\n    uid_t f_owner;\n    fsid_t f_fsid;\n    char[80] f_charspare;\n    char[MFSNAMELEN] f_fstypename;\n    char[MNAMELEN] f_mntfromname;\n    char[MNAMELEN] f_mntonname;\n}\n\n\nenum ulong MNT_RDONLY = 0x0000000000000001;\nenum ulong MNT_SYNCHRONOUS = 0x0000000000000002;\nenum ulong MNT_NOEXEC = 0x0000000000000004;\nenum ulong MNT_NOSUID = 0x0000000000000008;\nenum ulong MNT_NFS4ACLS = 0x0000000000000010;\nenum ulong MNT_UNION = 0x0000000000000020;\nenum ulong MNT_ASYNC = 0x0000000000000040;\nenum ulong MNT_SUIDDIR = 0x0000000000100000;\nenum ulong MNT_SOFTDEP = 0x0000000000200000;\nenum ulong MNT_NOSYMFOLLOW = 0x0000000000400000;\nenum ulong MNT_GJOURNAL = 0x0000000002000000;\nenum ulong MNT_MULTILABEL = 0x0000000004000000;\nenum ulong MNT_ACLS = 0x0000000008000000;\nenum ulong MNT_NOATIME = 0x0000000010000000;\nenum ulong MNT_NOCLUSTERR = 0x0000000040000000;\nenum ulong MNT_NOCLUSTERW = 0x0000000080000000;\nenum ulong MNT_SUJ = 0x0000000100000000;\nenum ulong MNT_AUTOMOUNTED = 0x0000000200000000;\n\nenum ulong MNT_EXRDONLY = 0x0000000000000080;\nenum ulong MNT_EXPORTED = 0x0000000000000100;\nenum ulong MNT_DEFEXPORTED = 0x0000000000000200;\nenum ulong MNT_EXPORTANON = 0x0000000000000400;\nenum ulong MNT_EXKERB = 0x0000000000000800;\nenum ulong MNT_EXPUBLIC = 0x0000000020000000;\n\nenum ulong MNT_LOCAL  = 0x0000000000001000;\nenum ulong MNT_QUOTA  = 0x0000000000002000;\nenum ulong MNT_ROOTFS = 0x0000000000004000;\nenum ulong MNT_USER   = 0x0000000000008000;\nenum ulong MNT_IGNORE = 0x0000000000800000;\n\nenum MNT_VISFLAGMASK = MNT_RDONLY | MNT_SYNCHRONOUS | MNT_NOEXEC |\n                       MNT_NOSUID | MNT_UNION | MNT_SUJ |\n                       MNT_ASYNC | MNT_EXRDONLY  | MNT_EXPORTED |\n                       MNT_DEFEXPORTED | MNT_EXPORTANON| MNT_EXKERB |\n                       MNT_LOCAL | MNT_USER  | MNT_QUOTA |\n                       MNT_ROOTFS | MNT_NOATIME   | MNT_NOCLUSTERR |\n                       MNT_NOCLUSTERW | MNT_SUIDDIR | MNT_SOFTDEP |\n                       MNT_IGNORE | MNT_EXPUBLIC  | MNT_NOSYMFOLLOW |\n                       MNT_GJOURNAL | MNT_MULTILABEL | MNT_ACLS |\n                       MNT_NFS4ACLS | MNT_AUTOMOUNTED;\n\nenum MNT_UPDATEMASK = MNT_NOSUID | MNT_NOEXEC |\n                      MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC |\n                      MNT_NOATIME |\n                      MNT_NOSYMFOLLOW | MNT_IGNORE |\n                      MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR |\n                      MNT_ACLS | MNT_USER | MNT_NFS4ACLS  |\n                      MNT_AUTOMOUNTED;\n\nenum ulong MNT_UPDATE = 0x0000000000010000;\nenum ulong MNT_DELEXPORT = 0x0000000000020000;\nenum ulong MNT_RELOAD = 0x0000000000040000;\nenum ulong MNT_FORCE = 0x0000000000080000;\nenum ulong MNT_SNAPSHOT = 0x0000000001000000;\nenum ulong MNT_NONBUSY = 0x0000000004000000;\nenum ulong MNT_BYFSID = 0x0000000008000000;\nenum ulong MNT_CMDFLAGS = MNT_UPDATE | MNT_DELEXPORT | MNT_RELOAD |\n                          MNT_FORCE  | MNT_SNAPSHOT  | MNT_NONBUSY |\n                          MNT_BYFSID;\n\nenum uint MNTK_UNMOUNTF = 0x00000001;\nenum uint MNTK_ASYNC = 0x00000002;\nenum uint MNTK_SOFTDEP = 0x00000004;\nenum uint MNTK_NOINSMNTQ = 0x00000008;\nenum uint MNTK_DRAINING = 0x00000010;\nenum uint MNTK_REFEXPIRE = 0x00000020;\nenum uint MNTK_EXTENDED_SHARED = 0x00000040;\nenum uint MNTK_SHARED_WRITES = 0x00000080;\nenum uint MNTK_NO_IOPF = 0x00000100;\nenum uint MNTK_VGONE_UPPER = 0x00000200;\nenum uint MNTK_VGONE_WAITER = 0x00000400;\nenum uint MNTK_LOOKUP_EXCL_DOTDOT = 0x00000800;\nenum uint MNTK_MARKER = 0x00001000;\nenum uint MNTK_UNMAPPED_BUFS = 0x00002000;\nenum uint MNTK_USES_BCACHE = 0x00004000;\nenum uint MNTK_NOASYNC = 0x00800000;\nenum uint MNTK_UNMOUNT = 0x01000000;\nenum uint MNTK_MWAIT = 0x02000000;\nenum uint MNTK_SUSPEND = 0x08000000;\nenum uint MNTK_SUSPEND2 = 0x04000000;\nenum uint MNTK_SUSPENDED = 0x10000000;\nenum uint MNTK_NULL_NOCACHE = 0x20000000;\nenum uint MNTK_LOOKUP_SHARED = 0x40000000;\nenum uint MNTK_NOKNOTE = 0x80000000;\n\nenum VFS_VFSCONF = 0;\nenum VFS_GENERIC = 0;\n\nenum VFS_MAXTYPENUM = 1;\nenum VFS_CONF       = 2;\n\nenum MNT_WAIT    = 1;\nenum MNT_NOWAIT  = 2;\nenum MNT_LAZY    = 3;\nenum MNT_SUSPEND = 4;\n\nstruct fhandle_t\n{\n    fsid_t fh_fsid;\n    fid fh_fid;\n}\n\n// TODO - requires declarations from elsewhere that we don't currently have bindings for.\n/+\nstruct oexport_args\n{\n    int ex_flags;\n    uid_t ex_root;\n    xucred ex_anon;\n    sockaddr* ex_addr;\n    ubyte ex_addrlen;\n    sockaddr* ex_mask;\n    ubyte ex_masklen;\n    char* ex_indexfile;\n}\n\nenum MAXSECFLAVORS = 5;\n\nstruct export_args\n{\n    int ex_flags;\n    uid_t ex_root;\n    xucred ex_anon;\n    sockaddr* ex_addr;\n    ubyte ex_addrlen;\n    sockaddr* ex_mask;\n    ubyte ex_masklen;\n    char* ex_indexfile;\n    int ex_numsecflavors;\n    int[MAXSECFLAVORS] ex_secflavors;\n}\n\nstruct nfs_public\n{\n    int np_valid;\n    fhandle_t np_handle;\n    mount_t* np_mount;\n    char* np_index;\n}\n\nstruct vfsconf\n{\n    uint vfc_version;\n    char[MFSNAMELEN] vfc_name;\n    vfsops* vfc_vfsops;\n    int vfc_typenum;\n    int vfc_refcount;\n    int vfc_flags;\n    vfsoptdecl* vfc_opts;\n    TAILQ_ENTRY(vfsconf) vfc_list;\n}\n\nstruct xvfsconf\n{\n    vfsops* vfc_vfsops;\n    char[MFSNAMELEN] vfc_name;\n    int vfc_typenum;\n    int vfc_refcount;\n    int vfc_flags;\n    vfsconf* vfc_next;\n}\n+/\n\nstruct ovfsconf\n{\n    void* vfc_vfsops;\n    char[32] vfc_name;\n    int vfc_index;\n    int vfc_refcount;\n    int vfc_flags;\n}\n\nenum uint VFCF_STATIC = 0x00010000;\nenum uint VFCF_NETWORK = 0x00020000;\nenum uint VFCF_READONLY = 0x00040000;\nenum uint VFCF_SYNTHETIC = 0x00080000;\nenum uint VFCF_LOOPBACK = 0x00100000;\nenum uint VFCF_UNICODE = 0x00200000;\nenum uint VFCF_JAIL = 0x00400000;\nenum uint VFCF_DELEGADMIN = 0x00800000;\nenum uint VFCF_SBDRY = 0x01000000;\n\nalias fsctlop_t = uint;\n\nstruct vfsidctl\n{\n    int vc_vers;\n    fsid_t vc_fsid;\n    char[MFSNAMELEN] vc_fstypename;\n    fsctlop_t vc_op;\n    void* vc_ptr;\n    size_t vc_len;\n    uint[12] vc_spare;\n}\n\nenum uint VFS_CTL_VERS1 = 0x01;\n\nenum uint VFS_CTL_QUERY   = 0x00010001;\nenum uint VFS_CTL_TIMEO   = 0x00010002;\nenum uint VFS_CTL_NOLOCKS = 0x00010003;\n\nstruct vfsquery\n{\n    uint vq_flags;\n    uint[31] vq_spare;\n}\n\nenum uint VQ_NOTRESP  = 0x0001;\nenum uint VQ_NEEDAUTH = 0x0002;\nenum uint VQ_LOWDISK  = 0x0004;\nenum uint VQ_MOUNT    = 0x0008;\nenum uint VQ_UNMOUNT  = 0x0010;\nenum uint VQ_DEAD     = 0x0020;\nenum uint VQ_ASSIST   = 0x0040;\nenum uint VQ_NOTRESPLOCK = 0x0080;\nenum uint VQ_FLAG0100 = 0x0100;\nenum uint VQ_FLAG0200 = 0x0200;\nenum uint VQ_FLAG0400 = 0x0400;\nenum uint VQ_FLAG0800 = 0x0800;\nenum uint VQ_FLAG1000 = 0x1000;\nenum uint VQ_FLAG2000 = 0x2000;\nenum uint VQ_FLAG4000 = 0x4000;\nenum uint VQ_FLAG8000 = 0x8000;\n\nint fhopen(const fhandle_t*, int);\nint fhstat(const fhandle_t*, stat_t*);\nint fhstatfs(const fhandle_t*, statfs_t*);\nint fstatfs(int, statfs_t*);\nint getfh(const char*, fhandle_t*);\nint getfsstat(statfs_t*, c_long, int);\nint getmntinfo(statfs_t**, int);\nint lgetfh(const char*, fhandle_t*);\nint mount(const char*, const char*, int, void*);\n//int nmount(iovec*, uint, int);\nint statfs(const char*, statfs_t*);\nint unmount(const char*, int);\n\n//int getvfsbyname(const char*, xvfsconf*);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/time.d",
    "content": "//Written in the D programming language\n\n/++\n    D header file for FreeBSD's extensions to POSIX's time.h.\n\n    Copyright: Copyright 2014\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n +/\nmodule core.sys.freebsd.time;\n\npublic import core.sys.posix.time;\n\nversion (FreeBSD):\n\nenum CLOCK_VIRTUAL           = 1;\nenum CLOCK_PROF              = 2;\nenum CLOCK_UPTIME            = 5;\nenum CLOCK_UPTIME_PRECISE    = 7;\nenum CLOCK_UPTIME_FAST       = 8;\nenum CLOCK_REALTIME_PRECISE  = 9;\nenum CLOCK_REALTIME_FAST     = 10;\nenum CLOCK_MONOTONIC_PRECISE = 11;\nenum CLOCK_MONOTONIC_FAST    = 12;\nenum CLOCK_SECOND            = 13;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/freebsd/unistd.d",
    "content": "//Written in the D programming language\n\n/++\n    D header file for FreeBSD's extensions to POSIX's unistd.h.\n\n    Copyright: Copyright 2018\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n +/\nmodule core.sys.freebsd.unistd;\n\npublic import core.sys.posix.unistd;\n\nversion (FreeBSD):\nextern(C):\n@nogc:\nnothrow:\n\nint getosreldate() pure @trusted;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/config.d",
    "content": "/**\n * D header file for GNU/Linux\n *\n * Authors: Martin Nowak\n */\nmodule core.sys.linux.config;\n\nversion (linux):\n\npublic import core.sys.posix.config;\n\n// man 7 feature_test_macros\n// http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html\nenum _GNU_SOURCE = true;\n// deduced <features.h>\n// http://sourceware.org/git/?p=glibc.git;a=blob;f=include/features.h\nenum _DEFAULT_SOURCE = true;\nenum _ATFILE_SOURCE = true;\n\n// _BSD_SOURCE and _SVID_SOURCE are deprecated aliases for _DEFAULT_SOURCE.\ndeprecated(\"use _DEFAULT_SOURCE\")\n{\n    enum _BSD_SOURCE = true;\n    enum _SVID_SOURCE = true;\n}\n\nenum __USE_MISC = _DEFAULT_SOURCE;\nenum __USE_ATFILE = _ATFILE_SOURCE;\nenum __USE_GNU = _GNU_SOURCE;\n\n// Available in bionic from API 21\nversion (CRuntime_Bionic) enum __WORDSIZE = 32;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/dlfcn.d",
    "content": "/**\n * D header file for GNU/Linux\n *\n * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=dlfcn/dlfcn.h, glibc dlfcn/dlfcn.h)\n */\nmodule core.sys.linux.dlfcn;\n\nversion (linux):\nextern (C):\nnothrow:\n@nogc:\n\npublic import core.sys.posix.dlfcn;\nimport core.sys.linux.config;\n\n// <bits/dlfcn.h>\nversion (X86)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/dlfcn.h\n    // enum RTLD_LAZY = 0x00001; // POSIX\n    // enum RTLD_NOW = 0x00002; // POSIX\n    enum RTLD_BINDING_MASK = 0x3;\n    enum RTLD_NOLOAD = 0x00004;\n    enum RTLD_DEEPBIND = 0x00008;\n\n    // enum RTLD_GLOBAL = 0x00100; // POSIX\n    // enum RTLD_LOCAL = 0; // POSIX\n    enum RTLD_NODELETE = 0x01000;\n\n    static if (__USE_GNU)\n    {\n        RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)\n        {\n            _dl_mcount_wrapper_check(cast(void*)fctp);\n            return fctp(args);\n        }\n\n        void _dl_mcount_wrapper_check(void* __selfpc);\n    }\n}\nelse version (X86_64)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/dlfcn.h\n    // enum RTLD_LAZY = 0x00001; // POSIX\n    // enum RTLD_NOW = 0x00002; // POSIX\n    enum RTLD_BINDING_MASK = 0x3;\n    enum RTLD_NOLOAD = 0x00004;\n    enum RTLD_DEEPBIND = 0x00008;\n\n    // enum RTLD_GLOBAL = 0x00100; // POSIX\n    // enum RTLD_LOCAL = 0; // POSIX\n    enum RTLD_NODELETE = 0x01000;\n\n    static if (__USE_GNU)\n    {\n        RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)\n        {\n            _dl_mcount_wrapper_check(cast(void*)fctp);\n            return fctp(args);\n        }\n\n        void _dl_mcount_wrapper_check(void* __selfpc);\n    }\n}\nelse version (MIPS32)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=ports/sysdeps/mips/bits/dlfcn.h\n    // enum RTLD_LAZY = 0x0001; // POSIX\n    // enum RTLD_NOW = 0x0002; // POSIX\n    enum RTLD_BINDING_MASK = 0x3;\n    enum RTLD_NOLOAD = 0x00008;\n    enum RTLD_DEEPBIND = 0x00010;\n\n    // enum RTLD_GLOBAL = 0x0004; // POSIX\n    // enum RTLD_LOCAL = 0; // POSIX\n    enum RTLD_NODELETE = 0x01000;\n\n    static if (__USE_GNU)\n    {\n        RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)\n        {\n            _dl_mcount_wrapper_check(cast(void*)fctp);\n            return fctp(args);\n        }\n\n        void _dl_mcount_wrapper_check(void* __selfpc);\n    }\n}\nelse version (MIPS64)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=ports/sysdeps/mips/bits/dlfcn.h\n    // enum RTLD_LAZY = 0x0001; // POSIX\n    // enum RTLD_NOW = 0x0002; // POSIX\n    enum RTLD_BINDING_MASK = 0x3;\n    enum RTLD_NOLOAD = 0x00008;\n    enum RTLD_DEEPBIND = 0x00010;\n\n    // enum RTLD_GLOBAL = 0x0004; // POSIX\n    // enum RTLD_LOCAL = 0; // POSIX\n    enum RTLD_NODELETE = 0x01000;\n\n    static if (__USE_GNU)\n    {\n        RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)\n        {\n            _dl_mcount_wrapper_check(cast(void*)fctp);\n            return fctp(args);\n        }\n\n        void _dl_mcount_wrapper_check(void* __selfpc);\n    }\n}\nelse version (PPC)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/dlfcn.h\n    // enum RTLD_LAZY = 0x0001; // POSIX\n    // enum RTLD_NOW = 0x0002; // POSIX\n    enum RTLD_BINDING_MASK = 0x3;\n    enum RTLD_NOLOAD = 0x00004;\n    enum RTLD_DEEPBIND = 0x00008;\n\n    // enum RTLD_GLOBAL = 0x00100; // POSIX\n    // enum RTLD_LOCAL = 0; // POSIX\n    enum RTLD_NODELETE = 0x01000;\n\n    static if (__USE_GNU)\n    {\n        RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)\n        {\n            _dl_mcount_wrapper_check(cast(void*)fctp);\n            return fctp(args);\n        }\n\n        void _dl_mcount_wrapper_check(void* __selfpc);\n    }\n}\nelse version (PPC64)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/dlfcn.h\n    // enum RTLD_LAZY = 0x0001; // POSIX\n    // enum RTLD_NOW = 0x0002; // POSIX\n    enum RTLD_BINDING_MASK = 0x3;\n    enum RTLD_NOLOAD = 0x00004;\n    enum RTLD_DEEPBIND = 0x00008;\n\n    // enum RTLD_GLOBAL = 0x00100; // POSIX\n    // enum RTLD_LOCAL = 0; // POSIX\n    enum RTLD_NODELETE = 0x01000;\n\n    static if (__USE_GNU)\n    {\n        RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)\n        {\n            _dl_mcount_wrapper_check(cast(void*)fctp);\n            return fctp(args);\n        }\n\n        void _dl_mcount_wrapper_check(void* __selfpc);\n    }\n}\nelse version (ARM)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/dlfcn.h\n    // enum RTLD_LAZY = 0x0001; // POSIX\n    // enum RTLD_NOW = 0x0002; // POSIX\n    enum RTLD_BINDING_MASK = 0x3;\n    enum RTLD_NOLOAD = 0x00004;\n    enum RTLD_DEEPBIND = 0x00008;\n\n    // enum RTLD_GLOBAL = 0x00100; // POSIX\n    // enum RTLD_LOCAL = 0; // POSIX\n    enum RTLD_NODELETE = 0x01000;\n\n    static if (__USE_GNU)\n    {\n        RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)\n        {\n            _dl_mcount_wrapper_check(cast(void*)fctp);\n            return fctp(args);\n        }\n\n        void _dl_mcount_wrapper_check(void* __selfpc);\n    }\n}\nelse version (AArch64)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/dlfcn.h\n    // enum RTLD_LAZY = 0x0001; // POSIX\n    // enum RTLD_NOW = 0x0002; // POSIX\n    enum RTLD_BINDING_MASK = 0x3;\n    enum RTLD_NOLOAD = 0x00004;\n    enum RTLD_DEEPBIND = 0x00008;\n\n    // enum RTLD_GLOBAL = 0x00100; // POSIX\n    // enum RTLD_LOCAL = 0; // POSIX\n    enum RTLD_NODELETE = 0x01000;\n\n    static if (__USE_GNU)\n    {\n        RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)\n        {\n            _dl_mcount_wrapper_check(cast(void*)fctp);\n            return fctp(args);\n        }\n\n        void _dl_mcount_wrapper_check(void* __selfpc);\n    }\n}\nelse version (SPARC64)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/dlfcn.h\n    // enum RTLD_LAZY = 0x0001; // POSIX\n    // enum RTLD_NOW = 0x0002; // POSIX\n    enum RTLD_BINDING_MASK = 0x3;\n    enum RTLD_NOLOAD = 0x00004;\n    enum RTLD_DEEPBIND = 0x00008;\n\n    // enum RTLD_GLOBAL = 0x00100; // POSIX\n    // enum RTLD_LOCAL = 0; // POSIX\n    enum RTLD_NODELETE = 0x01000;\n\n    static if (__USE_GNU)\n    {\n        RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)\n        {\n            _dl_mcount_wrapper_check(cast(void*)fctp);\n            return fctp(args);\n        }\n\n        void _dl_mcount_wrapper_check(void* __selfpc);\n    }\n}\nelse version (SystemZ)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/dlfcn.h\n    // enum RTLD_LAZY = 0x0001; // POSIX\n    // enum RTLD_NOW = 0x0002; // POSIX\n    enum RTLD_BINDING_MASK = 0x3;\n    enum RTLD_NOLOAD = 0x00004;\n    enum RTLD_DEEPBIND = 0x00008;\n\n    // enum RTLD_GLOBAL = 0x00100; // POSIX\n    // enum RTLD_LOCAL = 0; // POSIX\n    enum RTLD_NODELETE = 0x01000;\n\n    static if (__USE_GNU)\n    {\n        RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)\n        {\n            _dl_mcount_wrapper_check(cast(void*)fctp);\n            return fctp(args);\n        }\n\n        void _dl_mcount_wrapper_check(void* __selfpc);\n    }\n}\nelse\n    static assert(0, \"unimplemented\");\n\n// <bits/dlfcn.h>\n\nstatic if (__USE_GNU)\n{\n    enum RTLD_NEXT = cast(void *)-1L;\n    enum RTLD_DEFAULT = cast(void *)0;\n    alias c_long Lmid_t;\n    enum LM_ID_BASE = 0;\n    enum LM_ID_NEWLM = -1;\n}\n\n// void* dlopen(in char* __file, int __mode); // POSIX\n// int dlclose(void* __handle); // POSIX\n// void* dlsym(void* __handle, in char* __name); // POSIX\n\nstatic if (__USE_GNU)\n{\n    void* dlmopen(Lmid_t __nsid, in char* __file, int __mode);\n    void* dlvsym(void* __handle, in char* __name, in char* __version);\n}\n\n// char* dlerror(); // POSIX\n\nstatic if (__USE_GNU)\n{\n    struct Dl_info\n    {\n        const(char)* dli_fname;\n        void* dli_fbase;\n        const(char)* dli_sname;\n        void* dli_saddr;\n    }\n\n    int dladdr(in void* __address, Dl_info* __info);\n    int dladdr1(void* __address, Dl_info* __info, void** __extra_info, int __flags);\n\n    enum\n    {\n        RTLD_DL_SYMENT = 1,\n        RTLD_DL_LINKMAP = 2,\n    }\n\n    int dlinfo(void* __handle, int __request, void* __arg);\n\n    enum\n    {\n        RTLD_DI_LMID = 1,\n        RTLD_DI_LINKMAP = 2,\n        RTLD_DI_CONFIGADDR = 3,\n        RTLD_DI_SERINFO = 4,\n        RTLD_DI_SERINFOSIZE = 5,\n        RTLD_DI_ORIGIN = 6,\n        RTLD_DI_PROFILENAME = 7,\n        RTLD_DI_PROFILEOUT = 8,\n        RTLD_DI_TLS_MODID = 9,\n        RTLD_DI_TLS_DATA = 10,\n        RTLD_DI_MAX = 10,\n    }\n\n    struct Dl_serpath\n    {\n        char* dls_name;\n        uint dls_flags;\n    }\n\n    struct Dl_serinfo\n    {\n        size_t dls_size;\n        uint dls_cnt;\n        Dl_serpath[1] dls_serpath;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/elf.d",
    "content": "/**\n * D header file for GNU/Linux\n *\n * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=elf/elf.h, glibc elf/elf.h)\n */\nmodule core.sys.linux.elf;\n\nversion (linux):\nextern (C):\npure:\nnothrow:\n\nimport core.stdc.stdint;\n\nalias uint16_t Elf32_Half;\nalias uint16_t Elf64_Half;\n\nalias uint32_t Elf32_Word;\nalias int32_t  Elf32_Sword;\nalias uint32_t Elf64_Word;\nalias int32_t  Elf64_Sword;\n\nalias uint64_t Elf32_Xword;\nalias int64_t  Elf32_Sxword;\nalias uint64_t Elf64_Xword;\nalias int64_t  Elf64_Sxword;\n\nalias uint32_t Elf32_Addr;\nalias uint64_t Elf64_Addr;\n\nalias uint32_t Elf32_Off;\nalias uint64_t Elf64_Off;\n\nalias uint16_t Elf32_Section;\nalias uint16_t Elf64_Section;\n\nalias Elf32_Half Elf32_Versym;\nalias Elf64_Half Elf64_Versym;\n\n\nenum EI_NIDENT = 16;\n\nstruct Elf32_Ehdr\n{\n    char[EI_NIDENT] e_ident;\n    Elf32_Half    e_type;\n    Elf32_Half    e_machine;\n    Elf32_Word    e_version;\n    Elf32_Addr    e_entry;\n    Elf32_Off     e_phoff;\n    Elf32_Off     e_shoff;\n    Elf32_Word    e_flags;\n    Elf32_Half    e_ehsize;\n    Elf32_Half    e_phentsize;\n    Elf32_Half    e_phnum;\n    Elf32_Half    e_shentsize;\n    Elf32_Half    e_shnum;\n    Elf32_Half    e_shstrndx;\n}\n\nstruct Elf64_Ehdr\n{\n    char[EI_NIDENT] e_ident;\n    Elf64_Half    e_type;\n    Elf64_Half    e_machine;\n    Elf64_Word    e_version;\n    Elf64_Addr    e_entry;\n    Elf64_Off     e_phoff;\n    Elf64_Off     e_shoff;\n    Elf64_Word    e_flags;\n    Elf64_Half    e_ehsize;\n    Elf64_Half    e_phentsize;\n    Elf64_Half    e_phnum;\n    Elf64_Half    e_shentsize;\n    Elf64_Half    e_shnum;\n    Elf64_Half    e_shstrndx;\n}\n\nenum EI_MAG0 =         0;\nenum ELFMAG0 =         0x7f;\n\nenum EI_MAG1 =         1;\nenum ELFMAG1 =         'E';\n\nenum EI_MAG2 =         2;\nenum ELFMAG2 =         'L';\n\nenum EI_MAG3 =         3;\nenum ELFMAG3 =         'F';\nenum ELFMAG =          \"\\177ELF\";\nenum SELFMAG =         4;\n\nenum EI_CLASS =        4;\nenum ELFCLASSNONE =    0;\nenum ELFCLASS32 =      1;\nenum ELFCLASS64 =      2;\nenum ELFCLASSNUM =     3;\n\nenum EI_DATA =         5;\nenum ELFDATANONE =     0;\nenum ELFDATA2LSB =     1;\nenum ELFDATA2MSB =     2;\nenum ELFDATANUM =      3;\n\nenum EI_VERSION =      6;\n\nenum EI_OSABI =        7;\nenum ELFOSABI_NONE =           0;\nenum ELFOSABI_SYSV =           0;\nenum ELFOSABI_HPUX =           1;\nenum ELFOSABI_NETBSD =         2;\nenum ELFOSABI_GNU =            3;\nenum ELFOSABI_LINUX =          ELFOSABI_GNU;\nenum ELFOSABI_SOLARIS =        6;\nenum ELFOSABI_AIX =            7;\nenum ELFOSABI_IRIX =           8;\nenum ELFOSABI_FREEBSD =        9;\nenum ELFOSABI_TRU64 =          10;\nenum ELFOSABI_MODESTO =        11;\nenum ELFOSABI_OPENBSD =        12;\nenum ELFOSABI_ARM_AEABI =      64;\nenum ELFOSABI_ARM =            97;\nenum ELFOSABI_STANDALONE =     255;\nenum ELFOSABI_DRAGONFLYBSD =   ELFOSABI_NONE;\n\nenum EI_ABIVERSION =   8;\n\nenum EI_PAD =          9;\n\nenum ET_NONE =         0;\nenum ET_REL =          1;\nenum ET_EXEC =         2;\nenum ET_DYN =          3;\nenum ET_CORE =         4;\nenum ET_NUM =          5;\nenum ET_LOOS =         0xfe00;\nenum ET_HIOS =         0xfeff;\nenum ET_LOPROC =       0xff00;\nenum ET_HIPROC =       0xffff;\n\nenum EM_NONE =          0;\nenum EM_M32 =           1;\nenum EM_SPARC =         2;\nenum EM_386 =           3;\nenum EM_68K =           4;\nenum EM_88K =           5;\nenum EM_860 =           7;\nenum EM_MIPS =          8;\nenum EM_S370 =          9;\nenum EM_MIPS_RS3_LE =  10;\n\nenum EM_PARISC =       15;\nenum EM_VPP500 =       17;\nenum EM_SPARC32PLUS =  18;\nenum EM_960 =          19;\nenum EM_PPC =          20;\nenum EM_PPC64 =        21;\nenum EM_S390 =         22;\n\nenum EM_V800 =         36;\nenum EM_FR20 =         37;\nenum EM_RH32 =         38;\nenum EM_RCE =          39;\nenum EM_ARM =          40;\nenum EM_FAKE_ALPHA =   41;\nenum EM_SH =           42;\nenum EM_SPARCV9 =      43;\nenum EM_TRICORE =      44;\nenum EM_ARC =          45;\nenum EM_H8_300 =       46;\nenum EM_H8_300H =      47;\nenum EM_H8S =          48;\nenum EM_H8_500 =       49;\nenum EM_IA_64 =        50;\nenum EM_MIPS_X =       51;\nenum EM_COLDFIRE =     52;\nenum EM_68HC12 =       53;\nenum EM_MMA =          54;\nenum EM_PCP =          55;\nenum EM_NCPU =         56;\nenum EM_NDR1 =         57;\nenum EM_STARCORE =     58;\nenum EM_ME16 =         59;\nenum EM_ST100 =        60;\nenum EM_TINYJ =        61;\nenum EM_X86_64 =       62;\nenum EM_PDSP =         63;\n\nenum EM_FX66 =         66;\nenum EM_ST9PLUS =      67;\nenum EM_ST7 =          68;\nenum EM_68HC16 =       69;\nenum EM_68HC11 =       70;\nenum EM_68HC08 =       71;\nenum EM_68HC05 =       72;\nenum EM_SVX =          73;\nenum EM_ST19 =         74;\nenum EM_VAX =          75;\nenum EM_CRIS =         76;\nenum EM_JAVELIN =      77;\nenum EM_FIREPATH =     78;\nenum EM_ZSP =          79;\nenum EM_MMIX =         80;\nenum EM_HUANY =        81;\nenum EM_PRISM =        82;\nenum EM_AVR =          83;\nenum EM_FR30 =         84;\nenum EM_D10V =         85;\nenum EM_D30V =         86;\nenum EM_V850 =         87;\nenum EM_M32R =         88;\nenum EM_MN10300 =      89;\nenum EM_MN10200 =      90;\nenum EM_PJ =           91;\nenum EM_OPENRISC =     92;\nenum EM_ARC_A5 =       93;\nenum EM_XTENSA =       94;\nenum EM_AARCH64 =      183;\nenum EM_TILEPRO =      188;\nenum EM_TILEGX =       191;\nenum EM_NUM =          192;\n\nenum EM_ALPHA =        0x9026;\n\nenum EV_NONE =         0;\nenum EV_CURRENT =      1;\nenum EV_NUM =          2;\n\nstruct Elf32_Shdr\n{\n  Elf32_Word    sh_name;\n  Elf32_Word    sh_type;\n  Elf32_Word    sh_flags;\n  Elf32_Addr    sh_addr;\n  Elf32_Off     sh_offset;\n  Elf32_Word    sh_size;\n  Elf32_Word    sh_link;\n  Elf32_Word    sh_info;\n  Elf32_Word    sh_addralign;\n  Elf32_Word    sh_entsize;\n}\n\nstruct Elf64_Shdr\n{\n  Elf64_Word    sh_name;\n  Elf64_Word    sh_type;\n  Elf64_Xword   sh_flags;\n  Elf64_Addr    sh_addr;\n  Elf64_Off     sh_offset;\n  Elf64_Xword   sh_size;\n  Elf64_Word    sh_link;\n  Elf64_Word    sh_info;\n  Elf64_Xword   sh_addralign;\n  Elf64_Xword   sh_entsize;\n}\n\nenum SHN_UNDEF =       0;\nenum SHN_LORESERVE =   0xff00;\nenum SHN_LOPROC =      0xff00;\nenum SHN_BEFORE =      0xff00;\nenum SHN_AFTER =       0xff01;\nenum SHN_HIPROC =      0xff1f;\nenum SHN_LOOS =        0xff20;\nenum SHN_HIOS =        0xff3f;\nenum SHN_ABS =         0xfff1;\nenum SHN_COMMON =      0xfff2;\nenum SHN_XINDEX =      0xffff;\nenum SHN_HIRESERVE =   0xffff;\n\nenum SHT_NULL =          0;\nenum SHT_PROGBITS =      1;\nenum SHT_SYMTAB =        2;\nenum SHT_STRTAB =        3;\nenum SHT_RELA =          4;\nenum SHT_HASH =          5;\nenum SHT_DYNAMIC =       6;\nenum SHT_NOTE =          7;\nenum SHT_NOBITS =        8;\nenum SHT_REL =           9;\nenum SHT_SHLIB =         10;\nenum SHT_DYNSYM =        11;\nenum SHT_INIT_ARRAY =    14;\nenum SHT_FINI_ARRAY =    15;\nenum SHT_PREINIT_ARRAY = 16;\nenum SHT_GROUP =         17;\nenum SHT_SYMTAB_SHNDX =  18;\nenum SHT_NUM =           19;\nenum SHT_LOOS =          0x60000000;\nenum SHT_GNU_ATTRIBUTES = 0x6ffffff5;\nenum SHT_GNU_HASH =      0x6ffffff6;\nenum SHT_GNU_LIBLIST =   0x6ffffff7;\nenum SHT_CHECKSUM =      0x6ffffff8;\nenum SHT_LOSUNW =        0x6ffffffa;\nenum SHT_SUNW_move =     0x6ffffffa;\nenum SHT_SUNW_COMDAT =   0x6ffffffb;\nenum SHT_SUNW_syminfo =  0x6ffffffc;\nenum SHT_GNU_verdef =    0x6ffffffd;\nenum SHT_GNU_verneed =   0x6ffffffe;\nenum SHT_GNU_versym =    0x6fffffff;\nenum SHT_HISUNW =        0x6fffffff;\nenum SHT_HIOS =          0x6fffffff;\nenum SHT_LOPROC =        0x70000000;\nenum SHT_HIPROC =        0x7fffffff;\nenum SHT_LOUSER =        0x80000000;\nenum SHT_HIUSER =        0x8fffffff;\n\nenum SHF_WRITE =            (1 << 0);\nenum SHF_ALLOC =            (1 << 1);\nenum SHF_EXECINSTR =        (1 << 2);\nenum SHF_MERGE =            (1 << 4);\nenum SHF_STRINGS =          (1 << 5);\nenum SHF_INFO_LINK =        (1 << 6);\nenum SHF_LINK_ORDER =       (1 << 7);\nenum SHF_OS_NONCONFORMING = (1 << 8);\nenum SHF_GROUP =            (1 << 9);\nenum SHF_TLS =              (1 << 10);\nenum SHF_COMPRESSED =       (1 << 11);\nenum SHF_MASKOS =           0x0ff00000;\nenum SHF_MASKPROC =         0xf0000000;\nenum SHF_ORDERED =          (1 << 30);\nenum SHF_EXCLUDE =          (1 << 31);\nenum GRP_COMDAT =      0x1;\n\nstruct Elf32_Sym\n{\n  Elf32_Word    st_name;\n  Elf32_Addr    st_value;\n  Elf32_Word    st_size;\n  ubyte st_info;\n  ubyte st_other;\n  Elf32_Section st_shndx;\n}\n\nstruct Elf64_Sym\n{\n  Elf64_Word    st_name;\n  ubyte st_info;\n  ubyte st_other;\n  Elf64_Section st_shndx;\n  Elf64_Addr    st_value;\n  Elf64_Xword   st_size;\n}\n\nstruct Elf32_Syminfo\n{\n  Elf32_Half si_boundto;\n  Elf32_Half si_flags;\n}\n\nstruct Elf64_Syminfo\n{\n  Elf64_Half si_boundto;\n  Elf64_Half si_flags;\n}\nenum SYMINFO_BT_SELF =         0xffff;\nenum SYMINFO_BT_PARENT =       0xfffe;\nenum SYMINFO_BT_LOWRESERVE =   0xff00;\nenum SYMINFO_FLG_DIRECT =      0x0001;\nenum SYMINFO_FLG_PASSTHRU =    0x0002;\nenum SYMINFO_FLG_COPY =        0x0004;\nenum SYMINFO_FLG_LAZYLOAD =    0x0008;\nenum SYMINFO_NONE =            0;\nenum SYMINFO_CURRENT =         1;\nenum SYMINFO_NUM =             2;\n\nextern (D)\n{\n    auto ELF32_ST_BIND(T)(T val) { return cast(ubyte)val >> 4; }\n    auto ELF32_ST_TYPE(T)(T val) { return val & 0xf; }\n    auto ELF32_ST_INFO(B, T)(B bind, T type) { return (bind << 4) + (type & 0xf); }\n    alias ELF32_ST_BIND ELF64_ST_BIND;\n    alias ELF32_ST_TYPE ELF64_ST_TYPE;\n    alias ELF32_ST_INFO ELF64_ST_INFO;\n}\n\nenum STB_LOCAL =       0;\nenum STB_GLOBAL =      1;\nenum STB_WEAK =        2;\nenum STB_NUM =         3;\nenum STB_LOOS =        10;\nenum STB_GNU_UNIQUE =  10;\nenum STB_HIOS =        12;\nenum STB_LOPROC =      13;\nenum STB_HIPROC =      15;\n\nenum STT_NOTYPE =      0;\nenum STT_OBJECT =      1;\nenum STT_FUNC =        2;\nenum STT_SECTION =     3;\nenum STT_FILE =        4;\nenum STT_COMMON =      5;\nenum STT_TLS =         6;\nenum STT_NUM =         7;\nenum STT_LOOS =        10;\nenum STT_GNU_IFUNC =   10;\nenum STT_HIOS =        12;\nenum STT_LOPROC =      13;\nenum STT_HIPROC =      15;\n\nenum STN_UNDEF =       0;\n\nextern (D)\n{\n    auto ELF32_ST_VISIBILITY(O)(O o) { return o & 0x03; }\n    alias ELF32_ST_VISIBILITY ELF64_ST_VISIBILITY;\n}\nenum STV_DEFAULT =     0;\nenum STV_INTERNAL =    1;\nenum STV_HIDDEN =      2;\nenum STV_PROTECTED =   3;\n\nstruct Elf32_Rel\n{\n  Elf32_Addr    r_offset;\n  Elf32_Word    r_info;\n}\n\nstruct Elf64_Rel\n{\n  Elf64_Addr    r_offset;\n  Elf64_Xword   r_info;\n}\n\nstruct Elf32_Rela\n{\n  Elf32_Addr    r_offset;\n  Elf32_Word    r_info;\n  Elf32_Sword   r_addend;\n}\n\nstruct Elf64_Rela\n{\n  Elf64_Addr    r_offset;\n  Elf64_Xword   r_info;\n  Elf64_Sxword  r_addend;\n}\n\nextern (D)\n{\n    auto ELF32_R_SYM(V)(V val) { return val >> 8; }\n    auto ELF32_R_TYPE(V)(V val) { return val & 0xff; }\n    auto ELF32_R_INFO(S, T)(S sym, T type) { return (sym << 8) + (type & 0xff); }\n\n    auto ELF64_R_SYM(I)(I i) { return i >> 32; }\n    auto ELF64_R_TYPE(I)(I i) { return i & 0xffffffff; }\n    auto ELF64_R_INFO(S, T)(S sym, T type) { return (sym << 32) + (type); }\n}\n\nstruct Elf32_Phdr\n{\n  Elf32_Word    p_type;\n  Elf32_Off     p_offset;\n  Elf32_Addr    p_vaddr;\n  Elf32_Addr    p_paddr;\n  Elf32_Word    p_filesz;\n  Elf32_Word    p_memsz;\n  Elf32_Word    p_flags;\n  Elf32_Word    p_align;\n}\n\nstruct Elf64_Phdr\n{\n  Elf64_Word    p_type;\n  Elf64_Word    p_flags;\n  Elf64_Off     p_offset;\n  Elf64_Addr    p_vaddr;\n  Elf64_Addr    p_paddr;\n  Elf64_Xword   p_filesz;\n  Elf64_Xword   p_memsz;\n  Elf64_Xword   p_align;\n}\n\nenum PN_XNUM =         0xffff;\n\nenum PT_NULL =         0;\nenum PT_LOAD =         1;\nenum PT_DYNAMIC =      2;\nenum PT_INTERP =       3;\nenum PT_NOTE =         4;\nenum PT_SHLIB =        5;\nenum PT_PHDR =         6;\nenum PT_TLS =          7;\nenum PT_NUM =          8;\nenum PT_LOOS =         0x60000000;\nenum PT_GNU_EH_FRAME = 0x6474e550;\nenum PT_GNU_STACK =    0x6474e551;\nenum PT_GNU_RELRO =    0x6474e552;\nenum PT_LOSUNW =       0x6ffffffa;\nenum PT_SUNWBSS =      0x6ffffffa;\nenum PT_SUNWSTACK =    0x6ffffffb;\nenum PT_HISUNW =       0x6fffffff;\nenum PT_HIOS =         0x6fffffff;\nenum PT_LOPROC =       0x70000000;\nenum PT_HIPROC =       0x7fffffff;\n\nenum PF_X =            (1 << 0);\nenum PF_W =            (1 << 1);\nenum PF_R =            (1 << 2);\nenum PF_MASKOS =       0x0ff00000;\nenum PF_MASKPROC =     0xf0000000;\n\nenum NT_PRSTATUS =     1;\nenum NT_FPREGSET =     2;\nenum NT_PRPSINFO =     3;\nenum NT_PRXREG =       4;\nenum NT_TASKSTRUCT =   4;\nenum NT_PLATFORM =     5;\nenum NT_AUXV =         6;\nenum NT_GWINDOWS =     7;\nenum NT_ASRS =         8;\nenum NT_PSTATUS =      10;\nenum NT_PSINFO =       13;\nenum NT_PRCRED =       14;\nenum NT_UTSNAME =      15;\nenum NT_LWPSTATUS =    16;\nenum NT_LWPSINFO =     17;\nenum NT_PRFPXREG =     20;\nenum NT_SIGINFO =      0x53494749;\nenum NT_FILE =         0x46494c45;\nenum NT_PRXFPREG =     0x46e62b7f;\nenum NT_PPC_VMX =      0x100;\nenum NT_PPC_SPE =      0x101;\nenum NT_PPC_VSX =      0x102;\nenum NT_386_TLS =      0x200;\nenum NT_386_IOPERM =   0x201;\nenum NT_X86_XSTATE =   0x202;\nenum NT_S390_HIGH_GPRS =       0x300;\nenum NT_S390_TIMER =   0x301;\nenum NT_S390_TODCMP =  0x302;\nenum NT_S390_TODPREG = 0x303;\nenum NT_S390_CTRS =    0x304;\nenum NT_S390_PREFIX =  0x305;\nenum NT_S390_LAST_BREAK =      0x306;\nenum NT_S390_SYSTEM_CALL =     0x307;\nenum NT_S390_TDB =     0x308;\nenum NT_ARM_VFP =      0x400;\nenum NT_ARM_TLS =      0x401;\nenum NT_ARM_HW_BREAK = 0x402;\nenum NT_ARM_HW_WATCH = 0x403;\n\nenum NT_VERSION =      1;\n\nstruct Elf32_Dyn\n{\n  Elf32_Sword   d_tag;\n  union _d_un\n  {\n      Elf32_Word d_val;\n      Elf32_Addr d_ptr;\n  } _d_un d_un;\n}\n\nstruct Elf64_Dyn\n{\n  Elf64_Sxword  d_tag;\n  union _d_un\n  {\n      Elf64_Xword d_val;\n      Elf64_Addr d_ptr;\n  } _d_un d_un;\n}\n\nenum DT_NULL =         0;\nenum DT_NEEDED =       1;\nenum DT_PLTRELSZ =     2;\nenum DT_PLTGOT =       3;\nenum DT_HASH =         4;\nenum DT_STRTAB =       5;\nenum DT_SYMTAB =       6;\nenum DT_RELA =         7;\nenum DT_RELASZ =       8;\nenum DT_RELAENT =      9;\nenum DT_STRSZ =        10;\nenum DT_SYMENT =       11;\nenum DT_INIT =         12;\nenum DT_FINI =         13;\nenum DT_SONAME =       14;\nenum DT_RPATH =        15;\nenum DT_SYMBOLIC =     16;\nenum DT_REL =          17;\nenum DT_RELSZ =        18;\nenum DT_RELENT =       19;\nenum DT_PLTREL =       20;\nenum DT_DEBUG =        21;\nenum DT_TEXTREL =      22;\nenum DT_JMPREL =       23;\nenum DT_BIND_NOW =     24;\nenum DT_INIT_ARRAY =   25;\nenum DT_FINI_ARRAY =   26;\nenum DT_INIT_ARRAYSZ = 27;\nenum DT_FINI_ARRAYSZ = 28;\nenum DT_RUNPATH =      29;\nenum DT_FLAGS =        30;\nenum DT_ENCODING =     32;\nenum DT_PREINIT_ARRAY = 32;\nenum DT_PREINIT_ARRAYSZ = 33;\nenum DT_NUM =          34;\nenum DT_LOOS =         0x6000000d;\nenum DT_HIOS =         0x6ffff000;\nenum DT_LOPROC =       0x70000000;\nenum DT_HIPROC =       0x7fffffff;\nenum DT_PROCNUM =      DT_MIPS_NUM;\nenum DT_VALRNGLO =     0x6ffffd00;\nenum DT_GNU_PRELINKED = 0x6ffffdf5;\nenum DT_GNU_CONFLICTSZ = 0x6ffffdf6;\nenum DT_GNU_LIBLISTSZ = 0x6ffffdf7;\nenum DT_CHECKSUM =     0x6ffffdf8;\nenum DT_PLTPADSZ =     0x6ffffdf9;\nenum DT_MOVEENT =      0x6ffffdfa;\nenum DT_MOVESZ =       0x6ffffdfb;\nenum DT_FEATURE_1 =    0x6ffffdfc;\nenum DT_POSFLAG_1 =    0x6ffffdfd;\nenum DT_SYMINSZ =      0x6ffffdfe;\nenum DT_SYMINENT =     0x6ffffdff;\nenum DT_VALRNGHI =     0x6ffffdff;\nextern (D) auto DT_VALTAGIDX(T)(T tag)\n{\n    return DT_VALRNGHI - tag;\n}\nenum DT_VALNUM = 12;\nenum DT_ADDRRNGLO =    0x6ffffe00;\nenum DT_GNU_HASH =     0x6ffffef5;\nenum DT_TLSDESC_PLT =  0x6ffffef6;\nenum DT_TLSDESC_GOT =  0x6ffffef7;\nenum DT_GNU_CONFLICT = 0x6ffffef8;\nenum DT_GNU_LIBLIST =  0x6ffffef9;\nenum DT_CONFIG =       0x6ffffefa;\nenum DT_DEPAUDIT =     0x6ffffefb;\nenum DT_AUDIT =        0x6ffffefc;\nenum DT_PLTPAD =       0x6ffffefd;\nenum DT_MOVETAB =      0x6ffffefe;\nenum DT_SYMINFO =      0x6ffffeff;\nenum DT_ADDRRNGHI =    0x6ffffeff;\nextern (D) auto DT_ADDRTAGIDX(T)(T tag)\n{\n    return DT_ADDRRNGHI - tag;\n}\nenum DT_ADDRNUM = 11;\nenum DT_VERSYM =       0x6ffffff0;\n\nenum DT_RELACOUNT =    0x6ffffff9;\nenum DT_RELCOUNT =     0x6ffffffa;\nenum DT_FLAGS_1 =      0x6ffffffb;\nenum DT_VERDEF =       0x6ffffffc;\nenum DT_VERDEFNUM =    0x6ffffffd;\nenum DT_VERNEED =      0x6ffffffe;\nenum DT_VERNEEDNUM =   0x6fffffff;\nextern (D) auto DT_VERSIONTAGIDX(T)(T tag)\n{\n    return DT_VERNEEDNUM - tag;\n}\nenum DT_VERSIONTAGNUM = 16;\nenum DT_AUXILIARY =    0x7ffffffd;\nenum DT_FILTER =       0x7fffffff;\nextern (D) auto DT_EXTRATAGIDX(T)(T tag)\n{\n    return cast(Elf32_Word)(-(cast(Elf32_Sword)(tag) <<1>>1)-1);\n}\nenum DT_EXTRANUM =     3;\nenum DF_ORIGIN =       0x00000001;\nenum DF_SYMBOLIC =     0x00000002;\nenum DF_TEXTREL =      0x00000004;\nenum DF_BIND_NOW =     0x00000008;\nenum DF_STATIC_TLS =   0x00000010;\nenum DF_1_NOW =        0x00000001;\nenum DF_1_GLOBAL =     0x00000002;\nenum DF_1_GROUP =      0x00000004;\nenum DF_1_NODELETE =   0x00000008;\nenum DF_1_LOADFLTR =   0x00000010;\nenum DF_1_INITFIRST =  0x00000020;\nenum DF_1_NOOPEN =     0x00000040;\nenum DF_1_ORIGIN =     0x00000080;\nenum DF_1_DIRECT =     0x00000100;\nenum DF_1_TRANS =      0x00000200;\nenum DF_1_INTERPOSE =  0x00000400;\nenum DF_1_NODEFLIB =   0x00000800;\nenum DF_1_NODUMP =     0x00001000;\nenum DF_1_CONFALT =    0x00002000;\nenum DF_1_ENDFILTEE =  0x00004000;\nenum DF_1_DISPRELDNE = 0x00008000;\nenum DF_1_DISPRELPND = 0x00010000;\nenum DF_1_NODIRECT =   0x00020000;\nenum DF_1_IGNMULDEF =  0x00040000;\nenum DF_1_NOKSYMS =    0x00080000;\nenum DF_1_NOHDR =      0x00100000;\nenum DF_1_EDITED =     0x00200000;\nenum DF_1_NORELOC =    0x00400000;\nenum DF_1_SYMINTPOSE = 0x00800000;\nenum DF_1_GLOBAUDIT =  0x01000000;\nenum DF_1_SINGLETON =  0x02000000;\nenum DTF_1_PARINIT =   0x00000001;\nenum DTF_1_CONFEXP =   0x00000002;\nenum DF_P1_LAZYLOAD =  0x00000001;\nenum DF_P1_GROUPPERM = 0x00000002;\n\nstruct Elf32_Verdef\n{\n    Elf32_Half    vd_version;\n    Elf32_Half    vd_flags;\n    Elf32_Half    vd_ndx;\n    Elf32_Half    vd_cnt;\n    Elf32_Word    vd_hash;\n    Elf32_Word    vd_aux;\n    Elf32_Word    vd_next;\n}\n\nstruct Elf64_Verdef\n{\n    Elf64_Half    vd_version;\n    Elf64_Half    vd_flags;\n    Elf64_Half    vd_ndx;\n    Elf64_Half    vd_cnt;\n    Elf64_Word    vd_hash;\n    Elf64_Word    vd_aux;\n    Elf64_Word    vd_next;\n}\nenum VER_DEF_NONE =    0;\nenum VER_DEF_CURRENT = 1;\nenum VER_DEF_NUM =     2;\nenum VER_FLG_BASE =    0x1;\nenum VER_FLG_WEAK =    0x2;\nenum VER_NDX_LOCAL =           0;\nenum VER_NDX_GLOBAL =          1;\nenum VER_NDX_LORESERVE =       0xff00;\nenum VER_NDX_ELIMINATE =       0xff01;\n\nstruct Elf32_Verdaux\n{\n    Elf32_Word    vda_name;\n    Elf32_Word    vda_next;\n}\n\nstruct Elf64_Verdaux\n{\n    Elf64_Word    vda_name;\n    Elf64_Word    vda_next;\n}\n\nstruct Elf32_Verneed\n{\n    Elf32_Half    vn_version;\n    Elf32_Half    vn_cnt;\n    Elf32_Word    vn_file;\n    Elf32_Word    vn_aux;\n    Elf32_Word    vn_next;\n}\n\nstruct Elf64_Verneed\n{\n    Elf64_Half    vn_version;\n    Elf64_Half    vn_cnt;\n    Elf64_Word    vn_file;\n    Elf64_Word    vn_aux;\n    Elf64_Word    vn_next;\n}\nenum VER_NEED_NONE =    0;\nenum VER_NEED_CURRENT = 1;\nenum VER_NEED_NUM =     2;\n\nstruct Elf32_Vernaux\n{\n    Elf32_Word    vna_hash;\n    Elf32_Half    vna_flags;\n    Elf32_Half    vna_other;\n    Elf32_Word    vna_name;\n    Elf32_Word    vna_next;\n}\n\nstruct Elf64_Vernaux\n{\n    Elf64_Word    vna_hash;\n    Elf64_Half    vna_flags;\n    Elf64_Half    vna_other;\n    Elf64_Word    vna_name;\n    Elf64_Word    vna_next;\n}\n// duplicate\n// enum VER_FLG_WEAK =    0x2;\n\nstruct Elf32_auxv_t\n{\n    uint32_t a_type;\n    union _a_un\n    {\n        uint32_t a_val;\n    } _a_un a_un;\n}\n\nstruct Elf64_auxv_t\n{\n    uint64_t a_type;\n    union _a_un\n    {\n        uint64_t a_val;\n    } _a_un a_un;\n}\n\nenum AT_NULL =         0;\nenum AT_IGNORE =       1;\nenum AT_EXECFD =       2;\nenum AT_PHDR =         3;\nenum AT_PHENT =        4;\nenum AT_PHNUM =        5;\nenum AT_PAGESZ =       6;\nenum AT_BASE =         7;\nenum AT_FLAGS =        8;\nenum AT_ENTRY =        9;\nenum AT_NOTELF =       10;\nenum AT_UID =          11;\nenum AT_EUID =         12;\nenum AT_GID =          13;\nenum AT_EGID =         14;\nenum AT_CLKTCK =       17;\nenum AT_PLATFORM =     15;\nenum AT_HWCAP =        16;\nenum AT_FPUCW =        18;\nenum AT_DCACHEBSIZE =  19;\nenum AT_ICACHEBSIZE =  20;\nenum AT_UCACHEBSIZE =  21;\nenum AT_IGNOREPPC =    22;\n\nenum AT_SECURE =       23;\n\nenum AT_BASE_PLATFORM = 24;\n\nenum AT_RANDOM =       25;\n\nenum AT_HWCAP2 =       26;\n\nenum AT_EXECFN =       31;\nenum AT_SYSINFO =      32;\nenum AT_SYSINFO_EHDR = 33;\n\n;\nenum AT_L1I_CACHESHAPE =       34;\nenum AT_L1D_CACHESHAPE =       35;\nenum AT_L2_CACHESHAPE =        36;\nenum AT_L3_CACHESHAPE =        37;\n\nstruct Elf32_Nhdr\n{\n  Elf32_Word n_namesz;\n  Elf32_Word n_descsz;\n  Elf32_Word n_type;\n}\n\nstruct Elf64_Nhdr\n{\n  Elf64_Word n_namesz;\n  Elf64_Word n_descsz;\n  Elf64_Word n_type;\n}\nenum ELF_NOTE_SOLARIS =        \"SUNW Solaris\";\nenum ELF_NOTE_GNU =            \"GNU\";\nenum ELF_NOTE_PAGESIZE_HINT =  1;\nenum NT_GNU_ABI_TAG =  1;\nenum ELF_NOTE_ABI =    NT_GNU_ABI_TAG;\nenum ELF_NOTE_OS_LINUX =       0;\nenum ELF_NOTE_OS_GNU =         1;\nenum ELF_NOTE_OS_SOLARIS2 =    2;\nenum ELF_NOTE_OS_FREEBSD =     3;\nenum NT_GNU_HWCAP =    2;\nenum NT_GNU_BUILD_ID = 3;\nenum NT_GNU_GOLD_VERSION =     4;\nstruct Elf32_Move\n{\n  Elf32_Xword m_value;\n  Elf32_Word m_info;\n  Elf32_Word m_poffset;\n  Elf32_Half m_repeat;\n  Elf32_Half m_stride;\n}\n\nstruct Elf64_Move\n{\n  Elf64_Xword m_value;\n  Elf64_Xword m_info;\n  Elf64_Xword m_poffset;\n  Elf64_Half m_repeat;\n  Elf64_Half m_stride;\n}\nextern (D)\n{\n    auto ELF32_M_SYM(I)(I info) { return info >> 8; }\n    auto ELF32_M_SIZE(I)(I info) { return cast(ubyte)info; }\n    auto ELF32_M_INFO(S, SZ)(S sym, SZ size) { return (sym << 8) + cast(ubyte)size; }\n}\n\nalias ELF32_M_SYM ELF64_M_SYM;\nalias ELF32_M_SIZE ELF64_M_SIZE;\nalias ELF32_M_INFO ELF64_M_INFO;\nenum EF_CPU32 =        0x00810000;\n\nenum R_68K_NONE =      0;\nenum R_68K_32 =        1;\nenum R_68K_16 =        2;\nenum R_68K_8 =         3;\nenum R_68K_PC32 =      4;\nenum R_68K_PC16 =      5;\nenum R_68K_PC8 =       6;\nenum R_68K_GOT32 =     7;\nenum R_68K_GOT16 =     8;\nenum R_68K_GOT8 =      9;\nenum R_68K_GOT32O =    10;\nenum R_68K_GOT16O =    11;\nenum R_68K_GOT8O =     12;\nenum R_68K_PLT32 =     13;\nenum R_68K_PLT16 =     14;\nenum R_68K_PLT8 =      15;\nenum R_68K_PLT32O =    16;\nenum R_68K_PLT16O =    17;\nenum R_68K_PLT8O =     18;\nenum R_68K_COPY =      19;\nenum R_68K_GLOB_DAT =  20;\nenum R_68K_JMP_SLOT =  21;\nenum R_68K_RELATIVE =  22;\nenum R_68K_TLS_GD32 =      25;\nenum R_68K_TLS_GD16 =      26;\nenum R_68K_TLS_GD8 =       27;\nenum R_68K_TLS_LDM32 =     28;\nenum R_68K_TLS_LDM16 =     29;\nenum R_68K_TLS_LDM8 =      30;\nenum R_68K_TLS_LDO32 =     31;\nenum R_68K_TLS_LDO16 =     32;\nenum R_68K_TLS_LDO8 =      33;\nenum R_68K_TLS_IE32 =      34;\nenum R_68K_TLS_IE16 =      35;\nenum R_68K_TLS_IE8 =       36;\nenum R_68K_TLS_LE32 =      37;\nenum R_68K_TLS_LE16 =      38;\nenum R_68K_TLS_LE8 =       39;\nenum R_68K_TLS_DTPMOD32 =  40;\nenum R_68K_TLS_DTPREL32 =  41;\nenum R_68K_TLS_TPREL32 =   42;\nenum R_68K_NUM =       43;\n\nenum R_386_NONE =         0;\nenum R_386_32 =           1;\nenum R_386_PC32 =         2;\nenum R_386_GOT32 =        3;\nenum R_386_PLT32 =        4;\nenum R_386_COPY =         5;\nenum R_386_GLOB_DAT =     6;\nenum R_386_JMP_SLOT =     7;\nenum R_386_RELATIVE =     8;\nenum R_386_GOTOFF =       9;\nenum R_386_GOTPC =        10;\nenum R_386_32PLT =        11;\nenum R_386_TLS_TPOFF =    14;\nenum R_386_TLS_IE =       15;\nenum R_386_TLS_GOTIE =    16;\nenum R_386_TLS_LE =       17;\nenum R_386_TLS_GD =       18;\nenum R_386_TLS_LDM =      19;\nenum R_386_16 =           20;\nenum R_386_PC16 =         21;\nenum R_386_8 =            22;\nenum R_386_PC8 =          23;\nenum R_386_TLS_GD_32 =    24;\nenum R_386_TLS_GD_PUSH =  25;\nenum R_386_TLS_GD_CALL =  26;\nenum R_386_TLS_GD_POP =   27;\nenum R_386_TLS_LDM_32 =   28;\nenum R_386_TLS_LDM_PUSH = 29;\nenum R_386_TLS_LDM_CALL = 30;\nenum R_386_TLS_LDM_POP =  31;\nenum R_386_TLS_LDO_32 =   32;\nenum R_386_TLS_IE_32 =    33;\nenum R_386_TLS_LE_32 =    34;\nenum R_386_TLS_DTPMOD32 = 35;\nenum R_386_TLS_DTPOFF32 = 36;\nenum R_386_TLS_TPOFF32 =  37;\nenum R_386_SIZE32 =       38;\nenum R_386_TLS_GOTDESC =  39;\nenum R_386_TLS_DESC_CALL = 40;\nenum R_386_TLS_DESC =     41;\nenum R_386_IRELATIVE =    42;\nenum R_386_NUM =          43;\n\nenum STT_SPARC_REGISTER =      13;\n\nenum EF_SPARCV9_MM =           3;\nenum EF_SPARCV9_TSO =          0;\nenum EF_SPARCV9_PSO =          1;\nenum EF_SPARCV9_RMO =          2;\nenum EF_SPARC_LEDATA =         0x800000;\nenum EF_SPARC_EXT_MASK =       0xFFFF00;\nenum EF_SPARC_32PLUS =         0x000100;\nenum EF_SPARC_SUN_US1 =        0x000200;\nenum EF_SPARC_HAL_R1 =         0x000400;\nenum EF_SPARC_SUN_US3 =        0x000800;\n\nenum R_SPARC_NONE =            0;\nenum R_SPARC_8 =               1;\nenum R_SPARC_16 =              2;\nenum R_SPARC_32 =              3;\nenum R_SPARC_DISP8 =           4;\nenum R_SPARC_DISP16 =          5;\nenum R_SPARC_DISP32 =          6;\nenum R_SPARC_WDISP30 =         7;\nenum R_SPARC_WDISP22 =         8;\nenum R_SPARC_HI22 =            9;\nenum R_SPARC_22 =              10;\nenum R_SPARC_13 =              11;\nenum R_SPARC_LO10 =            12;\nenum R_SPARC_GOT10 =           13;\nenum R_SPARC_GOT13 =           14;\nenum R_SPARC_GOT22 =           15;\nenum R_SPARC_PC10 =            16;\nenum R_SPARC_PC22 =            17;\nenum R_SPARC_WPLT30 =          18;\nenum R_SPARC_COPY =            19;\nenum R_SPARC_GLOB_DAT =        20;\nenum R_SPARC_JMP_SLOT =        21;\nenum R_SPARC_RELATIVE =        22;\nenum R_SPARC_UA32 =            23;\n\nenum R_SPARC_PLT32 =           24;\nenum R_SPARC_HIPLT22 =         25;\nenum R_SPARC_LOPLT10 =         26;\nenum R_SPARC_PCPLT32 =         27;\nenum R_SPARC_PCPLT22 =         28;\nenum R_SPARC_PCPLT10 =         29;\nenum R_SPARC_10 =              30;\nenum R_SPARC_11 =              31;\nenum R_SPARC_64 =              32;\nenum R_SPARC_OLO10 =           33;\nenum R_SPARC_HH22 =            34;\nenum R_SPARC_HM10 =            35;\nenum R_SPARC_LM22 =            36;\nenum R_SPARC_PC_HH22 =         37;\nenum R_SPARC_PC_HM10 =         38;\nenum R_SPARC_PC_LM22 =         39;\nenum R_SPARC_WDISP16 =         40;\nenum R_SPARC_WDISP19 =         41;\nenum R_SPARC_GLOB_JMP =        42;\nenum R_SPARC_7 =               43;\nenum R_SPARC_5 =               44;\nenum R_SPARC_6 =               45;\nenum R_SPARC_DISP64 =          46;\nenum R_SPARC_PLT64 =           47;\nenum R_SPARC_HIX22 =           48;\nenum R_SPARC_LOX10 =           49;\nenum R_SPARC_H44 =             50;\nenum R_SPARC_M44 =             51;\nenum R_SPARC_L44 =             52;\nenum R_SPARC_REGISTER =        53;\nenum R_SPARC_UA64 =            54;\nenum R_SPARC_UA16 =            55;\nenum R_SPARC_TLS_GD_HI22 =     56;\nenum R_SPARC_TLS_GD_LO10 =     57;\nenum R_SPARC_TLS_GD_ADD =      58;\nenum R_SPARC_TLS_GD_CALL =     59;\nenum R_SPARC_TLS_LDM_HI22 =    60;\nenum R_SPARC_TLS_LDM_LO10 =    61;\nenum R_SPARC_TLS_LDM_ADD =     62;\nenum R_SPARC_TLS_LDM_CALL =    63;\nenum R_SPARC_TLS_LDO_HIX22 =   64;\nenum R_SPARC_TLS_LDO_LOX10 =   65;\nenum R_SPARC_TLS_LDO_ADD =     66;\nenum R_SPARC_TLS_IE_HI22 =     67;\nenum R_SPARC_TLS_IE_LO10 =     68;\nenum R_SPARC_TLS_IE_LD =       69;\nenum R_SPARC_TLS_IE_LDX =      70;\nenum R_SPARC_TLS_IE_ADD =      71;\nenum R_SPARC_TLS_LE_HIX22 =    72;\nenum R_SPARC_TLS_LE_LOX10 =    73;\nenum R_SPARC_TLS_DTPMOD32 =    74;\nenum R_SPARC_TLS_DTPMOD64 =    75;\nenum R_SPARC_TLS_DTPOFF32 =    76;\nenum R_SPARC_TLS_DTPOFF64 =    77;\nenum R_SPARC_TLS_TPOFF32 =     78;\nenum R_SPARC_TLS_TPOFF64 =     79;\nenum R_SPARC_GOTDATA_HIX22 =   80;\nenum R_SPARC_GOTDATA_LOX10 =   81;\nenum R_SPARC_GOTDATA_OP_HIX22 =        82;\nenum R_SPARC_GOTDATA_OP_LOX10 =        83;\nenum R_SPARC_GOTDATA_OP =      84;\nenum R_SPARC_H34 =             85;\nenum R_SPARC_SIZE32 =          86;\nenum R_SPARC_SIZE64 =          87;\nenum R_SPARC_WDISP10 =         88;\nenum R_SPARC_JMP_IREL =        248;\nenum R_SPARC_IRELATIVE =       249;\nenum R_SPARC_GNU_VTINHERIT =   250;\nenum R_SPARC_GNU_VTENTRY =     251;\nenum R_SPARC_REV32 =           252;\nenum R_SPARC_NUM =             253;\n\nenum DT_SPARC_REGISTER =       0x70000001;\nenum DT_SPARC_NUM =            2;\n\nenum EF_MIPS_NOREORDER =       1;\nenum EF_MIPS_PIC =             2;\nenum EF_MIPS_CPIC =            4;\nenum EF_MIPS_XGOT =            8;\nenum EF_MIPS_64BIT_WHIRL =     16;\nenum EF_MIPS_ABI2 =            32;\nenum EF_MIPS_ABI_ON32 =        64;\nenum EF_MIPS_ARCH =            0xf0000000;\n\nenum EF_MIPS_ARCH_1 =          0x00000000;\nenum EF_MIPS_ARCH_2 =          0x10000000;\nenum EF_MIPS_ARCH_3 =          0x20000000;\nenum EF_MIPS_ARCH_4 =          0x30000000;\nenum EF_MIPS_ARCH_5 =          0x40000000;\nenum EF_MIPS_ARCH_32 =         0x50000000;\nenum EF_MIPS_ARCH_64 =         0x60000000;\nenum EF_MIPS_ARCH_32R2 =       0x70000000;\nenum EF_MIPS_ARCH_64R2 =       0x80000000;\n\nenum E_MIPS_ARCH_1 =           EF_MIPS_ARCH_1;\nenum E_MIPS_ARCH_2 =           EF_MIPS_ARCH_2;\nenum E_MIPS_ARCH_3 =           EF_MIPS_ARCH_3;\nenum E_MIPS_ARCH_4 =           EF_MIPS_ARCH_4;\nenum E_MIPS_ARCH_5 =           EF_MIPS_ARCH_5;\nenum E_MIPS_ARCH_32 =          EF_MIPS_ARCH_32;\nenum E_MIPS_ARCH_64 =          EF_MIPS_ARCH_64;\n\nenum SHN_MIPS_ACOMMON =        0xff00;\nenum SHN_MIPS_TEXT =           0xff01;\nenum SHN_MIPS_DATA =           0xff02;\nenum SHN_MIPS_SCOMMON =        0xff03;\nenum SHN_MIPS_SUNDEFINED =     0xff04;\n\nenum SHT_MIPS_LIBLIST =        0x70000000;\nenum SHT_MIPS_MSYM =           0x70000001;\nenum SHT_MIPS_CONFLICT =       0x70000002;\nenum SHT_MIPS_GPTAB =          0x70000003;\nenum SHT_MIPS_UCODE =          0x70000004;\nenum SHT_MIPS_DEBUG =          0x70000005;\nenum SHT_MIPS_REGINFO =        0x70000006;\nenum SHT_MIPS_PACKAGE =        0x70000007;\nenum SHT_MIPS_PACKSYM =        0x70000008;\nenum SHT_MIPS_RELD =           0x70000009;\nenum SHT_MIPS_IFACE =          0x7000000b;\nenum SHT_MIPS_CONTENT =        0x7000000c;\nenum SHT_MIPS_OPTIONS =        0x7000000d;\nenum SHT_MIPS_SHDR =           0x70000010;\nenum SHT_MIPS_FDESC =          0x70000011;\nenum SHT_MIPS_EXTSYM =         0x70000012;\nenum SHT_MIPS_DENSE =          0x70000013;\nenum SHT_MIPS_PDESC =          0x70000014;\nenum SHT_MIPS_LOCSYM =         0x70000015;\nenum SHT_MIPS_AUXSYM =         0x70000016;\nenum SHT_MIPS_OPTSYM =         0x70000017;\nenum SHT_MIPS_LOCSTR =         0x70000018;\nenum SHT_MIPS_LINE =           0x70000019;\nenum SHT_MIPS_RFDESC =         0x7000001a;\nenum SHT_MIPS_DELTASYM =       0x7000001b;\nenum SHT_MIPS_DELTAINST =      0x7000001c;\nenum SHT_MIPS_DELTACLASS =     0x7000001d;\nenum SHT_MIPS_DWARF =          0x7000001e;\nenum SHT_MIPS_DELTADECL =      0x7000001f;\nenum SHT_MIPS_SYMBOL_LIB =     0x70000020;\nenum SHT_MIPS_EVENTS =         0x70000021;\nenum SHT_MIPS_TRANSLATE =      0x70000022;\nenum SHT_MIPS_PIXIE =          0x70000023;\nenum SHT_MIPS_XLATE =          0x70000024;\nenum SHT_MIPS_XLATE_DEBUG =    0x70000025;\nenum SHT_MIPS_WHIRL =          0x70000026;\nenum SHT_MIPS_EH_REGION =      0x70000027;\nenum SHT_MIPS_XLATE_OLD =      0x70000028;\nenum SHT_MIPS_PDR_EXCEPTION =  0x70000029;\n\nenum SHF_MIPS_GPREL =          0x10000000;\nenum SHF_MIPS_MERGE =          0x20000000;\nenum SHF_MIPS_ADDR =           0x40000000;\nenum SHF_MIPS_STRINGS =        0x80000000;\nenum SHF_MIPS_NOSTRIP =        0x08000000;\nenum SHF_MIPS_LOCAL =          0x04000000;\nenum SHF_MIPS_NAMES =          0x02000000;\nenum SHF_MIPS_NODUPE =         0x01000000;\nenum STO_MIPS_DEFAULT =                0x0;\nenum STO_MIPS_INTERNAL =               0x1;\nenum STO_MIPS_HIDDEN =                 0x2;\nenum STO_MIPS_PROTECTED =              0x3;\nenum STO_MIPS_PLT =                    0x8;\nenum STO_MIPS_SC_ALIGN_UNUSED =        0xff;\nenum STB_MIPS_SPLIT_COMMON =           13;\n\nunion Elf32_gptab\n{\n    struct _gt_header\n    {\n        Elf32_Word gt_current_g_value;\n        Elf32_Word gt_unused;\n    } _gt_header gt_header;\n    struct _gt_entry\n    {\n        Elf32_Word gt_g_value;\n        Elf32_Word gt_bytes;\n    } _gt_entry gt_entry;\n}\n\nstruct Elf32_RegInfo\n{\n    Elf32_Word ri_gprmask;\n    Elf32_Word[4] ri_cprmask;\n    Elf32_Sword ri_gp_value;\n}\n\nstruct Elf_Options\n{\n    ubyte kind;\n    ubyte size;\n    Elf32_Section section;\n    Elf32_Word info;\n}\n\nenum ODK_NULL =        0;\nenum ODK_REGINFO =     1;\nenum ODK_EXCEPTIONS =  2;\nenum ODK_PAD =         3;\nenum ODK_HWPATCH =     4;\nenum ODK_FILL =        5;\nenum ODK_TAGS =        6;\nenum ODK_HWAND =       7;\nenum ODK_HWOR =        8;\n\nenum OEX_FPU_MIN =     0x1f;\nenum OEX_FPU_MAX =     0x1f00;\nenum OEX_PAGE0 =       0x10000;\nenum OEX_SMM =         0x20000;\nenum OEX_FPDBUG =      0x40000;\nenum OEX_PRECISEFP =   OEX_FPDBUG;\nenum OEX_DISMISS =     0x80000;\n\nenum OEX_FPU_INVAL =   0x10;\nenum OEX_FPU_DIV0 =    0x08;\nenum OEX_FPU_OFLO =    0x04;\nenum OEX_FPU_UFLO =    0x02;\nenum OEX_FPU_INEX =    0x01;\n\nenum OHW_R4KEOP =      0x1;\nenum OHW_R8KPFETCH =   0x2;\nenum OHW_R5KEOP =      0x4;\nenum OHW_R5KCVTL =     0x8;\n\nenum OPAD_PREFIX =     0x1;\nenum OPAD_POSTFIX =    0x2;\nenum OPAD_SYMBOL =     0x4;\n\nstruct Elf_Options_Hw\n{\n    Elf32_Word hwp_flags1;\n    Elf32_Word hwp_flags2;\n}\n\nenum OHWA0_R4KEOP_CHECKED =    0x00000001;\nenum OHWA1_R4KEOP_CLEAN =      0x00000002;\n\nenum R_MIPS_NONE =             0;\nenum R_MIPS_16 =               1;\nenum R_MIPS_32 =               2;\nenum R_MIPS_REL32 =            3;\nenum R_MIPS_26 =               4;\nenum R_MIPS_HI16 =             5;\nenum R_MIPS_LO16 =             6;\nenum R_MIPS_GPREL16 =          7;\nenum R_MIPS_LITERAL =          8;\nenum R_MIPS_GOT16 =            9;\nenum R_MIPS_PC16 =             10;\nenum R_MIPS_CALL16 =           11;\nenum R_MIPS_GPREL32 =          12;\n\nenum R_MIPS_SHIFT5 =           16;\nenum R_MIPS_SHIFT6 =           17;\nenum R_MIPS_64 =               18;\nenum R_MIPS_GOT_DISP =         19;\nenum R_MIPS_GOT_PAGE =         20;\nenum R_MIPS_GOT_OFST =         21;\nenum R_MIPS_GOT_HI16 =         22;\nenum R_MIPS_GOT_LO16 =         23;\nenum R_MIPS_SUB =              24;\nenum R_MIPS_INSERT_A =         25;\nenum R_MIPS_INSERT_B =         26;\nenum R_MIPS_DELETE =           27;\nenum R_MIPS_HIGHER =           28;\nenum R_MIPS_HIGHEST =          29;\nenum R_MIPS_CALL_HI16 =        30;\nenum R_MIPS_CALL_LO16 =        31;\nenum R_MIPS_SCN_DISP =         32;\nenum R_MIPS_REL16 =            33;\nenum R_MIPS_ADD_IMMEDIATE =    34;\nenum R_MIPS_PJUMP =            35;\nenum R_MIPS_RELGOT =           36;\nenum R_MIPS_JALR =             37;\nenum R_MIPS_TLS_DTPMOD32 =     38;\nenum R_MIPS_TLS_DTPREL32 =     39;\nenum R_MIPS_TLS_DTPMOD64 =     40;\nenum R_MIPS_TLS_DTPREL64 =     41;\nenum R_MIPS_TLS_GD =           42;\nenum R_MIPS_TLS_LDM =          43;\nenum R_MIPS_TLS_DTPREL_HI16 =  44;\nenum R_MIPS_TLS_DTPREL_LO16 =  45;\nenum R_MIPS_TLS_GOTTPREL =     46;\nenum R_MIPS_TLS_TPREL32 =      47;\nenum R_MIPS_TLS_TPREL64 =      48;\nenum R_MIPS_TLS_TPREL_HI16 =   49;\nenum R_MIPS_TLS_TPREL_LO16 =   50;\nenum R_MIPS_GLOB_DAT =         51;\nenum R_MIPS_COPY =             126;\nenum R_MIPS_JUMP_SLOT =        127;\nenum R_MIPS_NUM =              128;\n\nenum PT_MIPS_REGINFO = 0x70000000;\nenum PT_MIPS_RTPROC =  0x70000001;\nenum PT_MIPS_OPTIONS = 0x70000002;\n\nenum PF_MIPS_LOCAL =   0x10000000;\n\nenum DT_MIPS_RLD_VERSION =  0x70000001;\nenum DT_MIPS_TIME_STAMP =   0x70000002;\nenum DT_MIPS_ICHECKSUM =    0x70000003;\nenum DT_MIPS_IVERSION =     0x70000004;\nenum DT_MIPS_FLAGS =        0x70000005;\nenum DT_MIPS_BASE_ADDRESS = 0x70000006;\nenum DT_MIPS_MSYM =         0x70000007;\nenum DT_MIPS_CONFLICT =     0x70000008;\nenum DT_MIPS_LIBLIST =      0x70000009;\nenum DT_MIPS_LOCAL_GOTNO =  0x7000000a;\nenum DT_MIPS_CONFLICTNO =   0x7000000b;\nenum DT_MIPS_LIBLISTNO =    0x70000010;\nenum DT_MIPS_SYMTABNO =     0x70000011;\nenum DT_MIPS_UNREFEXTNO =   0x70000012;\nenum DT_MIPS_GOTSYM =       0x70000013;\nenum DT_MIPS_HIPAGENO =     0x70000014;\nenum DT_MIPS_RLD_MAP =      0x70000016;\nenum DT_MIPS_DELTA_CLASS =  0x70000017;\nenum DT_MIPS_DELTA_CLASS_NO =    0x70000018;\nenum DT_MIPS_DELTA_INSTANCE =    0x70000019;\nenum DT_MIPS_DELTA_INSTANCE_NO = 0x7000001a;\nenum DT_MIPS_DELTA_RELOC =  0x7000001b;\nenum DT_MIPS_DELTA_RELOC_NO = 0x7000001c;\nenum DT_MIPS_DELTA_SYM =    0x7000001d;\nenum DT_MIPS_DELTA_SYM_NO = 0x7000001e;\nenum DT_MIPS_DELTA_CLASSSYM = 0x70000020;\nenum DT_MIPS_DELTA_CLASSSYM_NO = 0x70000021;\nenum DT_MIPS_CXX_FLAGS =    0x70000022;\nenum DT_MIPS_PIXIE_INIT =   0x70000023;\nenum DT_MIPS_SYMBOL_LIB =   0x70000024;\nenum DT_MIPS_LOCALPAGE_GOTIDX = 0x70000025;\nenum DT_MIPS_LOCAL_GOTIDX = 0x70000026;\nenum DT_MIPS_HIDDEN_GOTIDX = 0x70000027;\nenum DT_MIPS_PROTECTED_GOTIDX = 0x70000028;\nenum DT_MIPS_OPTIONS =      0x70000029;\nenum DT_MIPS_INTERFACE =    0x7000002a;\nenum DT_MIPS_DYNSTR_ALIGN = 0x7000002b;\nenum DT_MIPS_INTERFACE_SIZE = 0x7000002c;\nenum DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 0x7000002d;\nenum DT_MIPS_PERF_SUFFIX =  0x7000002e;\nenum DT_MIPS_COMPACT_SIZE = 0x7000002f;\nenum DT_MIPS_GP_VALUE =     0x70000030;\nenum DT_MIPS_AUX_DYNAMIC =  0x70000031;\nenum DT_MIPS_PLTGOT =       0x70000032;\nenum DT_MIPS_RWPLT =        0x70000034;\nenum DT_MIPS_NUM =          0x35;\n\nenum RHF_NONE =                   0;\nenum RHF_QUICKSTART =             (1 << 0);\nenum RHF_NOTPOT =                 (1 << 1);\nenum RHF_NO_LIBRARY_REPLACEMENT = (1 << 2);\nenum RHF_NO_MOVE =                (1 << 3);\nenum RHF_SGI_ONLY =               (1 << 4);\nenum RHF_GUARANTEE_INIT =         (1 << 5);\nenum RHF_DELTA_C_PLUS_PLUS =      (1 << 6);\nenum RHF_GUARANTEE_START_INIT =   (1 << 7);\nenum RHF_PIXIE =                  (1 << 8);\nenum RHF_DEFAULT_DELAY_LOAD =     (1 << 9);\nenum RHF_REQUICKSTART =           (1 << 10);\nenum RHF_REQUICKSTARTED =         (1 << 11);\nenum RHF_CORD =                   (1 << 12);\nenum RHF_NO_UNRES_UNDEF =         (1 << 13);\nenum RHF_RLD_ORDER_SAFE =         (1 << 14);\n\nstruct Elf32_Lib\n{\n    Elf32_Word l_name;\n    Elf32_Word l_time_stamp;\n    Elf32_Word l_checksum;\n    Elf32_Word l_version;\n    Elf32_Word l_flags;\n}\n\nstruct Elf64_Lib\n{\n    Elf64_Word l_name;\n    Elf64_Word l_time_stamp;\n    Elf64_Word l_checksum;\n    Elf64_Word l_version;\n    Elf64_Word l_flags;\n}\n\nenum LL_NONE =           0;\nenum LL_EXACT_MATCH =    (1 << 0);\nenum LL_IGNORE_INT_VER = (1 << 1);\nenum LL_REQUIRE_MINOR =  (1 << 2);\nenum LL_EXPORTS =        (1 << 3);\nenum LL_DELAY_LOAD =     (1 << 4);\nenum LL_DELTA =          (1 << 5);\n\nalias Elf32_Addr Elf32_Conflict;\n\nenum EF_PARISC_TRAPNIL =       0x00010000;\nenum EF_PARISC_EXT =           0x00020000;\nenum EF_PARISC_LSB =           0x00040000;\nenum EF_PARISC_WIDE =          0x00080000;\nenum EF_PARISC_NO_KABP =       0x00100000;\nenum EF_PARISC_LAZYSWAP =      0x00400000;\nenum EF_PARISC_ARCH =          0x0000ffff;\n\nenum EFA_PARISC_1_0 =              0x020b;\nenum EFA_PARISC_1_1 =              0x0210;\nenum EFA_PARISC_2_0 =              0x0214;\n\nenum SHN_PARISC_ANSI_COMMON =  0xff00;\nenum SHN_PARISC_HUGE_COMMON =  0xff01;\n\nenum SHT_PARISC_EXT =          0x70000000;\nenum SHT_PARISC_UNWIND =       0x70000001;\nenum SHT_PARISC_DOC =          0x70000002;\n\nenum SHF_PARISC_SHORT =        0x20000000;\nenum SHF_PARISC_HUGE =         0x40000000;\nenum SHF_PARISC_SBP =          0x80000000;\n\nenum STT_PARISC_MILLICODE =    13;\n\nenum STT_HP_OPAQUE =           (STT_LOOS + 0x1);\nenum STT_HP_STUB =             (STT_LOOS + 0x2);\n\nenum R_PARISC_NONE =           0;\nenum R_PARISC_DIR32 =          1;\nenum R_PARISC_DIR21L =         2;\nenum R_PARISC_DIR17R =         3;\nenum R_PARISC_DIR17F =         4;\nenum R_PARISC_DIR14R =         6;\nenum R_PARISC_PCREL32 =        9;\nenum R_PARISC_PCREL21L =       10;\nenum R_PARISC_PCREL17R =       11;\nenum R_PARISC_PCREL17F =       12;\nenum R_PARISC_PCREL14R =       14;\nenum R_PARISC_DPREL21L =       18;\nenum R_PARISC_DPREL14R =       22;\nenum R_PARISC_GPREL21L =       26;\nenum R_PARISC_GPREL14R =       30;\nenum R_PARISC_LTOFF21L =       34;\nenum R_PARISC_LTOFF14R =       38;\nenum R_PARISC_SECREL32 =       41;\nenum R_PARISC_SEGBASE =        48;\nenum R_PARISC_SEGREL32 =       49;\nenum R_PARISC_PLTOFF21L =      50;\nenum R_PARISC_PLTOFF14R =      54;\nenum R_PARISC_LTOFF_FPTR32 =   57;\nenum R_PARISC_LTOFF_FPTR21L =  58;\nenum R_PARISC_LTOFF_FPTR14R =  62;\nenum R_PARISC_FPTR64 =         64;\nenum R_PARISC_PLABEL32 =       65;\nenum R_PARISC_PLABEL21L =      66;\nenum R_PARISC_PLABEL14R =      70;\nenum R_PARISC_PCREL64 =        72;\nenum R_PARISC_PCREL22F =       74;\nenum R_PARISC_PCREL14WR =      75;\nenum R_PARISC_PCREL14DR =      76;\nenum R_PARISC_PCREL16F =       77;\nenum R_PARISC_PCREL16WF =      78;\nenum R_PARISC_PCREL16DF =      79;\nenum R_PARISC_DIR64 =          80;\nenum R_PARISC_DIR14WR =        83;\nenum R_PARISC_DIR14DR =        84;\nenum R_PARISC_DIR16F =         85;\nenum R_PARISC_DIR16WF =        86;\nenum R_PARISC_DIR16DF =        87;\nenum R_PARISC_GPREL64 =        88;\nenum R_PARISC_GPREL14WR =      91;\nenum R_PARISC_GPREL14DR =      92;\nenum R_PARISC_GPREL16F =       93;\nenum R_PARISC_GPREL16WF =      94;\nenum R_PARISC_GPREL16DF =      95;\nenum R_PARISC_LTOFF64 =        96;\nenum R_PARISC_LTOFF14WR =      99;\nenum R_PARISC_LTOFF14DR =      100;\nenum R_PARISC_LTOFF16F =       101;\nenum R_PARISC_LTOFF16WF =      102;\nenum R_PARISC_LTOFF16DF =      103;\nenum R_PARISC_SECREL64 =       104;\nenum R_PARISC_SEGREL64 =       112;\nenum R_PARISC_PLTOFF14WR =     115;\nenum R_PARISC_PLTOFF14DR =     116;\nenum R_PARISC_PLTOFF16F =      117;\nenum R_PARISC_PLTOFF16WF =     118;\nenum R_PARISC_PLTOFF16DF =     119;\nenum R_PARISC_LTOFF_FPTR64 =   120;\nenum R_PARISC_LTOFF_FPTR14WR = 123;\nenum R_PARISC_LTOFF_FPTR14DR = 124;\nenum R_PARISC_LTOFF_FPTR16F =  125;\nenum R_PARISC_LTOFF_FPTR16WF = 126;\nenum R_PARISC_LTOFF_FPTR16DF = 127;\nenum R_PARISC_LORESERVE =      128;\nenum R_PARISC_COPY =           128;\nenum R_PARISC_IPLT =           129;\nenum R_PARISC_EPLT =           130;\nenum R_PARISC_TPREL32 =        153;\nenum R_PARISC_TPREL21L =       154;\nenum R_PARISC_TPREL14R =       158;\nenum R_PARISC_LTOFF_TP21L =    162;\nenum R_PARISC_LTOFF_TP14R =    166;\nenum R_PARISC_LTOFF_TP14F =    167;\nenum R_PARISC_TPREL64 =        216;\nenum R_PARISC_TPREL14WR =      219;\nenum R_PARISC_TPREL14DR =      220;\nenum R_PARISC_TPREL16F =       221;\nenum R_PARISC_TPREL16WF =      222;\nenum R_PARISC_TPREL16DF =      223;\nenum R_PARISC_LTOFF_TP64 =     224;\nenum R_PARISC_LTOFF_TP14WR =   227;\nenum R_PARISC_LTOFF_TP14DR =   228;\nenum R_PARISC_LTOFF_TP16F =    229;\nenum R_PARISC_LTOFF_TP16WF =   230;\nenum R_PARISC_LTOFF_TP16DF =   231;\nenum R_PARISC_GNU_VTENTRY =    232;\nenum R_PARISC_GNU_VTINHERIT =  233;\nenum R_PARISC_TLS_GD21L =      234;\nenum R_PARISC_TLS_GD14R =      235;\nenum R_PARISC_TLS_GDCALL =     236;\nenum R_PARISC_TLS_LDM21L =     237;\nenum R_PARISC_TLS_LDM14R =     238;\nenum R_PARISC_TLS_LDMCALL =    239;\nenum R_PARISC_TLS_LDO21L =     240;\nenum R_PARISC_TLS_LDO14R =     241;\nenum R_PARISC_TLS_DTPMOD32 =   242;\nenum R_PARISC_TLS_DTPMOD64 =   243;\nenum R_PARISC_TLS_DTPOFF32 =   244;\nenum R_PARISC_TLS_DTPOFF64 =   245;\nenum R_PARISC_TLS_LE21L =      R_PARISC_TPREL21L;\nenum R_PARISC_TLS_LE14R =      R_PARISC_TPREL14R;\nenum R_PARISC_TLS_IE21L =      R_PARISC_LTOFF_TP21L;\nenum R_PARISC_TLS_IE14R =      R_PARISC_LTOFF_TP14R;\nenum R_PARISC_TLS_TPREL32 =    R_PARISC_TPREL32;\nenum R_PARISC_TLS_TPREL64 =    R_PARISC_TPREL64;\nenum R_PARISC_HIRESERVE =      255;\n\nenum PT_HP_TLS =               (PT_LOOS + 0x0);\nenum PT_HP_CORE_NONE =         (PT_LOOS + 0x1);\nenum PT_HP_CORE_VERSION =      (PT_LOOS + 0x2);\nenum PT_HP_CORE_KERNEL =       (PT_LOOS + 0x3);\nenum PT_HP_CORE_COMM =         (PT_LOOS + 0x4);\nenum PT_HP_CORE_PROC =         (PT_LOOS + 0x5);\nenum PT_HP_CORE_LOADABLE =     (PT_LOOS + 0x6);\nenum PT_HP_CORE_STACK =        (PT_LOOS + 0x7);\nenum PT_HP_CORE_SHM =          (PT_LOOS + 0x8);\nenum PT_HP_CORE_MMF =          (PT_LOOS + 0x9);\nenum PT_HP_PARALLEL =          (PT_LOOS + 0x10);\nenum PT_HP_FASTBIND =          (PT_LOOS + 0x11);\nenum PT_HP_OPT_ANNOT =         (PT_LOOS + 0x12);\nenum PT_HP_HSL_ANNOT =         (PT_LOOS + 0x13);\nenum PT_HP_STACK =             (PT_LOOS + 0x14);\n\nenum PT_PARISC_ARCHEXT =       0x70000000;\nenum PT_PARISC_UNWIND =        0x70000001;\n\nenum PF_PARISC_SBP =           0x08000000;\n\nenum PF_HP_PAGE_SIZE =         0x00100000;\nenum PF_HP_FAR_SHARED =        0x00200000;\nenum PF_HP_NEAR_SHARED =       0x00400000;\nenum PF_HP_CODE =              0x01000000;\nenum PF_HP_MODIFY =            0x02000000;\nenum PF_HP_LAZYSWAP =          0x04000000;\nenum PF_HP_SBP =               0x08000000;\n\nenum EF_ALPHA_32BIT =          1;\nenum EF_ALPHA_CANRELAX =       2;\nenum SHT_ALPHA_DEBUG =         0x70000001;\nenum SHT_ALPHA_REGINFO =       0x70000002;\n\nenum SHF_ALPHA_GPREL =         0x10000000;\nenum STO_ALPHA_NOPV =          0x80;\nenum STO_ALPHA_STD_GPLOAD =    0x88;\n\nenum R_ALPHA_NONE =            0;\nenum R_ALPHA_REFLONG =         1;\nenum R_ALPHA_REFQUAD =         2;\nenum R_ALPHA_GPREL32 =         3;\nenum R_ALPHA_LITERAL =         4;\nenum R_ALPHA_LITUSE =          5;\nenum R_ALPHA_GPDISP =          6;\nenum R_ALPHA_BRADDR =          7;\nenum R_ALPHA_HINT =            8;\nenum R_ALPHA_SREL16 =          9;\nenum R_ALPHA_SREL32 =          10;\nenum R_ALPHA_SREL64 =          11;\nenum R_ALPHA_GPRELHIGH =       17;\nenum R_ALPHA_GPRELLOW =        18;\nenum R_ALPHA_GPREL16 =         19;\nenum R_ALPHA_COPY =            24;\nenum R_ALPHA_GLOB_DAT =        25;\nenum R_ALPHA_JMP_SLOT =        26;\nenum R_ALPHA_RELATIVE =        27;\nenum R_ALPHA_TLS_GD_HI =       28;\nenum R_ALPHA_TLSGD =           29;\nenum R_ALPHA_TLS_LDM =         30;\nenum R_ALPHA_DTPMOD64 =        31;\nenum R_ALPHA_GOTDTPREL =       32;\nenum R_ALPHA_DTPREL64 =        33;\nenum R_ALPHA_DTPRELHI =        34;\nenum R_ALPHA_DTPRELLO =        35;\nenum R_ALPHA_DTPREL16 =        36;\nenum R_ALPHA_GOTTPREL =        37;\nenum R_ALPHA_TPREL64 =         38;\nenum R_ALPHA_TPRELHI =         39;\nenum R_ALPHA_TPRELLO =         40;\nenum R_ALPHA_TPREL16 =         41;\nenum R_ALPHA_NUM =             46;\nenum LITUSE_ALPHA_ADDR =       0;\nenum LITUSE_ALPHA_BASE =       1;\nenum LITUSE_ALPHA_BYTOFF =     2;\nenum LITUSE_ALPHA_JSR =        3;\nenum LITUSE_ALPHA_TLS_GD =     4;\nenum LITUSE_ALPHA_TLS_LDM =    5;\nenum DT_ALPHA_PLTRO =          (DT_LOPROC + 0);\nenum DT_ALPHA_NUM =            1;\nenum EF_PPC_EMB =              0x80000000;\nenum EF_PPC_RELOCATABLE =      0x00010000;\nenum EF_PPC_RELOCATABLE_LIB =  0x00008000;\nenum R_PPC_NONE =              0;\nenum R_PPC_ADDR32 =            1;\nenum R_PPC_ADDR24 =            2;\nenum R_PPC_ADDR16 =            3;\nenum R_PPC_ADDR16_LO =         4;\nenum R_PPC_ADDR16_HI =         5;\nenum R_PPC_ADDR16_HA =         6;\nenum R_PPC_ADDR14 =            7;\nenum R_PPC_ADDR14_BRTAKEN =    8;\nenum R_PPC_ADDR14_BRNTAKEN =   9;\nenum R_PPC_REL24 =             10;\nenum R_PPC_REL14 =             11;\nenum R_PPC_REL14_BRTAKEN =     12;\nenum R_PPC_REL14_BRNTAKEN =    13;\nenum R_PPC_GOT16 =             14;\nenum R_PPC_GOT16_LO =          15;\nenum R_PPC_GOT16_HI =          16;\nenum R_PPC_GOT16_HA =          17;\nenum R_PPC_PLTREL24 =          18;\nenum R_PPC_COPY =              19;\nenum R_PPC_GLOB_DAT =          20;\nenum R_PPC_JMP_SLOT =          21;\nenum R_PPC_RELATIVE =          22;\nenum R_PPC_LOCAL24PC =         23;\nenum R_PPC_UADDR32 =           24;\nenum R_PPC_UADDR16 =           25;\nenum R_PPC_REL32 =             26;\nenum R_PPC_PLT32 =             27;\nenum R_PPC_PLTREL32 =          28;\nenum R_PPC_PLT16_LO =          29;\nenum R_PPC_PLT16_HI =          30;\nenum R_PPC_PLT16_HA =          31;\nenum R_PPC_SDAREL16 =          32;\nenum R_PPC_SECTOFF =           33;\nenum R_PPC_SECTOFF_LO =        34;\nenum R_PPC_SECTOFF_HI =        35;\nenum R_PPC_SECTOFF_HA =        36;\nenum R_PPC_TLS =               67;\nenum R_PPC_DTPMOD32 =          68;\nenum R_PPC_TPREL16 =           69;\nenum R_PPC_TPREL16_LO =        70;\nenum R_PPC_TPREL16_HI =        71;\nenum R_PPC_TPREL16_HA =        72;\nenum R_PPC_TPREL32 =           73;\nenum R_PPC_DTPREL16 =          74;\nenum R_PPC_DTPREL16_LO =       75;\nenum R_PPC_DTPREL16_HI =       76;\nenum R_PPC_DTPREL16_HA =       77;\nenum R_PPC_DTPREL32 =          78;\nenum R_PPC_GOT_TLSGD16 =       79;\nenum R_PPC_GOT_TLSGD16_LO =    80;\nenum R_PPC_GOT_TLSGD16_HI =    81;\nenum R_PPC_GOT_TLSGD16_HA =    82;\nenum R_PPC_GOT_TLSLD16 =       83;\nenum R_PPC_GOT_TLSLD16_LO =    84;\nenum R_PPC_GOT_TLSLD16_HI =    85;\nenum R_PPC_GOT_TLSLD16_HA =    86;\nenum R_PPC_GOT_TPREL16 =       87;\nenum R_PPC_GOT_TPREL16_LO =    88;\nenum R_PPC_GOT_TPREL16_HI =    89;\nenum R_PPC_GOT_TPREL16_HA =    90;\nenum R_PPC_GOT_DTPREL16 =      91;\nenum R_PPC_GOT_DTPREL16_LO =   92;\nenum R_PPC_GOT_DTPREL16_HI =   93;\nenum R_PPC_GOT_DTPREL16_HA =   94;\nenum R_PPC_EMB_NADDR32 =       101;\nenum R_PPC_EMB_NADDR16 =       102;\nenum R_PPC_EMB_NADDR16_LO =    103;\nenum R_PPC_EMB_NADDR16_HI =    104;\nenum R_PPC_EMB_NADDR16_HA =    105;\nenum R_PPC_EMB_SDAI16 =        106;\nenum R_PPC_EMB_SDA2I16 =       107;\nenum R_PPC_EMB_SDA2REL =       108;\nenum R_PPC_EMB_SDA21 =         109;\nenum R_PPC_EMB_MRKREF =        110;\nenum R_PPC_EMB_RELSEC16 =      111;\nenum R_PPC_EMB_RELST_LO =      112;\nenum R_PPC_EMB_RELST_HI =      113;\nenum R_PPC_EMB_RELST_HA =      114;\nenum R_PPC_EMB_BIT_FLD =       115;\nenum R_PPC_EMB_RELSDA =        116;\nenum R_PPC_DIAB_SDA21_LO =     180;\nenum R_PPC_DIAB_SDA21_HI =     181;\nenum R_PPC_DIAB_SDA21_HA =     182;\nenum R_PPC_DIAB_RELSDA_LO =    183;\nenum R_PPC_DIAB_RELSDA_HI =    184;\nenum R_PPC_DIAB_RELSDA_HA =    185;\nenum R_PPC_IRELATIVE =         248;\nenum R_PPC_REL16 =             249;\nenum R_PPC_REL16_LO =          250;\nenum R_PPC_REL16_HI =          251;\nenum R_PPC_REL16_HA =          252;\nenum R_PPC_TOC16 =             255;\nenum DT_PPC_GOT =              (DT_LOPROC + 0);\nenum DT_PPC_NUM =              1;\nenum R_PPC64_NONE =            R_PPC_NONE;\nenum R_PPC64_ADDR32 =          R_PPC_ADDR32;\nenum R_PPC64_ADDR24 =          R_PPC_ADDR24;\nenum R_PPC64_ADDR16 =          R_PPC_ADDR16;\nenum R_PPC64_ADDR16_LO =       R_PPC_ADDR16_LO;\nenum R_PPC64_ADDR16_HI =       R_PPC_ADDR16_HI;\nenum R_PPC64_ADDR16_HA =       R_PPC_ADDR16_HA;\nenum R_PPC64_ADDR14 =          R_PPC_ADDR14;\nenum R_PPC64_ADDR14_BRTAKEN =  R_PPC_ADDR14_BRTAKEN;\nenum R_PPC64_ADDR14_BRNTAKEN = R_PPC_ADDR14_BRNTAKEN;\nenum R_PPC64_REL24 =           R_PPC_REL24;\nenum R_PPC64_REL14 =           R_PPC_REL14;\nenum R_PPC64_REL14_BRTAKEN =   R_PPC_REL14_BRTAKEN;\nenum R_PPC64_REL14_BRNTAKEN =  R_PPC_REL14_BRNTAKEN;\nenum R_PPC64_GOT16 =           R_PPC_GOT16;\nenum R_PPC64_GOT16_LO =        R_PPC_GOT16_LO;\nenum R_PPC64_GOT16_HI =        R_PPC_GOT16_HI;\nenum R_PPC64_GOT16_HA =        R_PPC_GOT16_HA;\n\nenum R_PPC64_COPY =            R_PPC_COPY;\nenum R_PPC64_GLOB_DAT =        R_PPC_GLOB_DAT;\nenum R_PPC64_JMP_SLOT =        R_PPC_JMP_SLOT;\nenum R_PPC64_RELATIVE =        R_PPC_RELATIVE;\n\nenum R_PPC64_UADDR32 =         R_PPC_UADDR32;\nenum R_PPC64_UADDR16 =         R_PPC_UADDR16;\nenum R_PPC64_REL32 =           R_PPC_REL32;\nenum R_PPC64_PLT32 =           R_PPC_PLT32;\nenum R_PPC64_PLTREL32 =        R_PPC_PLTREL32;\nenum R_PPC64_PLT16_LO =        R_PPC_PLT16_LO;\nenum R_PPC64_PLT16_HI =        R_PPC_PLT16_HI;\nenum R_PPC64_PLT16_HA =        R_PPC_PLT16_HA;\n\nenum R_PPC64_SECTOFF =         R_PPC_SECTOFF;\nenum R_PPC64_SECTOFF_LO =      R_PPC_SECTOFF_LO;\nenum R_PPC64_SECTOFF_HI =      R_PPC_SECTOFF_HI;\nenum R_PPC64_SECTOFF_HA =      R_PPC_SECTOFF_HA;\nenum R_PPC64_ADDR30 =          37;\nenum R_PPC64_ADDR64 =          38;\nenum R_PPC64_ADDR16_HIGHER =   39;\nenum R_PPC64_ADDR16_HIGHERA =  40;\nenum R_PPC64_ADDR16_HIGHEST =  41;\nenum R_PPC64_ADDR16_HIGHESTA = 42;\nenum R_PPC64_UADDR64 =         43;\nenum R_PPC64_REL64 =           44;\nenum R_PPC64_PLT64 =           45;\nenum R_PPC64_PLTREL64 =        46;\nenum R_PPC64_TOC16 =           47;\nenum R_PPC64_TOC16_LO =        48;\nenum R_PPC64_TOC16_HI =        49;\nenum R_PPC64_TOC16_HA =        50;\nenum R_PPC64_TOC =             51;\nenum R_PPC64_PLTGOT16 =        52;\nenum R_PPC64_PLTGOT16_LO =     53;\nenum R_PPC64_PLTGOT16_HI =     54;\nenum R_PPC64_PLTGOT16_HA =     55;\n\nenum R_PPC64_ADDR16_DS =       56;\nenum R_PPC64_ADDR16_LO_DS =    57;\nenum R_PPC64_GOT16_DS =        58;\nenum R_PPC64_GOT16_LO_DS =     59;\nenum R_PPC64_PLT16_LO_DS =     60;\nenum R_PPC64_SECTOFF_DS =      61;\nenum R_PPC64_SECTOFF_LO_DS =   62;\nenum R_PPC64_TOC16_DS =        63;\nenum R_PPC64_TOC16_LO_DS =     64;\nenum R_PPC64_PLTGOT16_DS =     65;\nenum R_PPC64_PLTGOT16_LO_DS =  66;\nenum R_PPC64_TLS =             67;\nenum R_PPC64_DTPMOD64 =        68;\nenum R_PPC64_TPREL16 =         69;\nenum R_PPC64_TPREL16_LO =      70;\nenum R_PPC64_TPREL16_HI =      71;\nenum R_PPC64_TPREL16_HA =      72;\nenum R_PPC64_TPREL64 =         73;\nenum R_PPC64_DTPREL16 =        74;\nenum R_PPC64_DTPREL16_LO =     75;\nenum R_PPC64_DTPREL16_HI =     76;\nenum R_PPC64_DTPREL16_HA =     77;\nenum R_PPC64_DTPREL64 =        78;\nenum R_PPC64_GOT_TLSGD16 =     79;\nenum R_PPC64_GOT_TLSGD16_LO =  80;\nenum R_PPC64_GOT_TLSGD16_HI =  81;\nenum R_PPC64_GOT_TLSGD16_HA =  82;\nenum R_PPC64_GOT_TLSLD16 =     83;\nenum R_PPC64_GOT_TLSLD16_LO =  84;\nenum R_PPC64_GOT_TLSLD16_HI =  85;\nenum R_PPC64_GOT_TLSLD16_HA =  86;\nenum R_PPC64_GOT_TPREL16_DS =  87;\nenum R_PPC64_GOT_TPREL16_LO_DS = 88;\nenum R_PPC64_GOT_TPREL16_HI =  89;\nenum R_PPC64_GOT_TPREL16_HA =  90;\nenum R_PPC64_GOT_DTPREL16_DS = 91;\nenum R_PPC64_GOT_DTPREL16_LO_DS = 92;\nenum R_PPC64_GOT_DTPREL16_HI = 93;\nenum R_PPC64_GOT_DTPREL16_HA = 94;\nenum R_PPC64_TPREL16_DS =      95;\nenum R_PPC64_TPREL16_LO_DS =   96;\nenum R_PPC64_TPREL16_HIGHER =  97;\nenum R_PPC64_TPREL16_HIGHERA = 98;\nenum R_PPC64_TPREL16_HIGHEST = 99;\nenum R_PPC64_TPREL16_HIGHESTA = 100;\nenum R_PPC64_DTPREL16_DS =     101;\nenum R_PPC64_DTPREL16_LO_DS =  102;\nenum R_PPC64_DTPREL16_HIGHER = 103;\nenum R_PPC64_DTPREL16_HIGHERA = 104;\nenum R_PPC64_DTPREL16_HIGHEST = 105;\nenum R_PPC64_DTPREL16_HIGHESTA = 106;\nenum R_PPC64_JMP_IREL =        247;\nenum R_PPC64_IRELATIVE =       248;\nenum R_PPC64_REL16 =           249;\nenum R_PPC64_REL16_LO =        250;\nenum R_PPC64_REL16_HI =        251;\nenum R_PPC64_REL16_HA =        252;\nenum DT_PPC64_GLINK =  (DT_LOPROC + 0);\nenum DT_PPC64_OPD =    (DT_LOPROC + 1);\nenum DT_PPC64_OPDSZ =  (DT_LOPROC + 2);\nenum DT_PPC64_NUM =    3;\nenum EF_ARM_RELEXEC =          0x01;\nenum EF_ARM_HASENTRY =         0x02;\nenum EF_ARM_INTERWORK =        0x04;\nenum EF_ARM_APCS_26 =          0x08;\nenum EF_ARM_APCS_FLOAT =       0x10;\nenum EF_ARM_PIC =              0x20;\nenum EF_ARM_ALIGN8 =           0x40;\nenum EF_ARM_NEW_ABI =          0x80;\nenum EF_ARM_OLD_ABI =          0x100;\nenum EF_ARM_SOFT_FLOAT =       0x200;\nenum EF_ARM_VFP_FLOAT =        0x400;\nenum EF_ARM_MAVERICK_FLOAT =   0x800;\n\nenum EF_ARM_ABI_FLOAT_SOFT =   0x200;\nenum EF_ARM_ABI_FLOAT_HARD =   0x400;\nenum EF_ARM_SYMSARESORTED =    0x04;\nenum EF_ARM_DYNSYMSUSESEGIDX = 0x08;\nenum EF_ARM_MAPSYMSFIRST =     0x10;\nenum EF_ARM_EABIMASK =         0XFF000000;\nenum EF_ARM_BE8 =          0x00800000;\nenum EF_ARM_LE8 =          0x00400000;\n\nextern (D) auto EF_ARM_EABI_VERSION(F)(F flags) { return flags & EF_ARM_EABIMASK; }\nenum EF_ARM_EABI_UNKNOWN =     0x00000000;\nenum EF_ARM_EABI_VER1 =        0x01000000;\nenum EF_ARM_EABI_VER2 =        0x02000000;\nenum EF_ARM_EABI_VER3 =        0x03000000;\nenum EF_ARM_EABI_VER4 =        0x04000000;\nenum EF_ARM_EABI_VER5 =        0x05000000;\nenum STT_ARM_TFUNC =           STT_LOPROC;\nenum STT_ARM_16BIT =           STT_HIPROC;\nenum SHF_ARM_ENTRYSECT =       0x10000000;\nenum SHF_ARM_COMDEF =          0x80000000;\nenum PF_ARM_SB =               0x10000000;\nenum PF_ARM_PI =               0x20000000;\nenum PF_ARM_ABS =              0x40000000;\nenum PT_ARM_EXIDX =            (PT_LOPROC + 1);\nenum SHT_ARM_EXIDX =           (SHT_LOPROC + 1);\nenum SHT_ARM_PREEMPTMAP =      (SHT_LOPROC + 2);\nenum SHT_ARM_ATTRIBUTES =      (SHT_LOPROC + 3);\n\nenum R_AARCH64_NONE =            0;\nenum R_AARCH64_ABS64 =         257;\nenum R_AARCH64_ABS32 =         258;\nenum R_AARCH64_COPY =         1024;\nenum R_AARCH64_GLOB_DAT =     1025;\nenum R_AARCH64_JUMP_SLOT =    1026;\nenum R_AARCH64_RELATIVE =     1027;\nenum R_AARCH64_TLS_DTPMOD64 = 1028;\nenum R_AARCH64_TLS_DTPREL64 = 1029;\nenum R_AARCH64_TLS_TPREL64 =  1030;\nenum R_AARCH64_TLSDESC =      1031;\n\nenum R_ARM_NONE =              0;\nenum R_ARM_PC24 =              1;\nenum R_ARM_ABS32 =             2;\nenum R_ARM_REL32 =             3;\nenum R_ARM_PC13 =              4;\nenum R_ARM_ABS16 =             5;\nenum R_ARM_ABS12 =             6;\nenum R_ARM_THM_ABS5 =          7;\nenum R_ARM_ABS8 =              8;\nenum R_ARM_SBREL32 =           9;\nenum R_ARM_THM_PC22 =          10;\nenum R_ARM_THM_PC8 =           11;\nenum R_ARM_AMP_VCALL9 =        12;\nenum R_ARM_SWI24 =             13;\nenum R_ARM_TLS_DESC =          13;\nenum R_ARM_THM_SWI8 =          14;\nenum R_ARM_XPC25 =             15;\nenum R_ARM_THM_XPC22 =         16;\nenum R_ARM_TLS_DTPMOD32 =      17;\nenum R_ARM_TLS_DTPOFF32 =      18;\nenum R_ARM_TLS_TPOFF32 =       19;\nenum R_ARM_COPY =              20;\nenum R_ARM_GLOB_DAT =          21;\nenum R_ARM_JUMP_SLOT =         22;\nenum R_ARM_RELATIVE =          23;\nenum R_ARM_GOTOFF =            24;\nenum R_ARM_GOTPC =             25;\nenum R_ARM_GOT32 =             26;\nenum R_ARM_PLT32 =             27;\nenum R_ARM_ALU_PCREL_7_0 =     32;\nenum R_ARM_ALU_PCREL_15_8 =    33;\nenum R_ARM_ALU_PCREL_23_15 =   34;\nenum R_ARM_LDR_SBREL_11_0 =    35;\nenum R_ARM_ALU_SBREL_19_12 =   36;\nenum R_ARM_ALU_SBREL_27_20 =   37;\nenum R_ARM_TLS_GOTDESC =       90;\nenum R_ARM_TLS_CALL =          91;\nenum R_ARM_TLS_DESCSEQ =       92;\nenum R_ARM_THM_TLS_CALL =      93;\nenum R_ARM_GNU_VTENTRY =       100;\nenum R_ARM_GNU_VTINHERIT =     101;\nenum R_ARM_THM_PC11 =          102;\nenum R_ARM_THM_PC9 =           103;\nenum R_ARM_TLS_GD32 =          104;\nenum R_ARM_TLS_LDM32 =         105;\nenum R_ARM_TLS_LDO32 =         106;\nenum R_ARM_TLS_IE32 =          107;\nenum R_ARM_TLS_LE32 =          108;\nenum R_ARM_THM_TLS_DESCSEQ =   129;\nenum R_ARM_IRELATIVE =         160;\nenum R_ARM_RXPC25 =            249;\nenum R_ARM_RSBREL32 =          250;\nenum R_ARM_THM_RPC22 =         251;\nenum R_ARM_RREL32 =            252;\nenum R_ARM_RABS22 =            253;\nenum R_ARM_RPC24 =             254;\nenum R_ARM_RBASE =             255;\nenum R_ARM_NUM =               256;\nenum EF_IA_64_MASKOS =         0x0000000f;\nenum EF_IA_64_ABI64 =          0x00000010;\nenum EF_IA_64_ARCH =           0xff000000;\nenum PT_IA_64_ARCHEXT =        (PT_LOPROC + 0);\nenum PT_IA_64_UNWIND =         (PT_LOPROC + 1);\nenum PT_IA_64_HP_OPT_ANOT =    (PT_LOOS + 0x12);\nenum PT_IA_64_HP_HSL_ANOT =    (PT_LOOS + 0x13);\nenum PT_IA_64_HP_STACK =       (PT_LOOS + 0x14);\nenum PF_IA_64_NORECOV =        0x80000000;\nenum SHT_IA_64_EXT =           (SHT_LOPROC + 0);\nenum SHT_IA_64_UNWIND =        (SHT_LOPROC + 1);\nenum SHF_IA_64_SHORT =         0x10000000;\nenum SHF_IA_64_NORECOV =       0x20000000;\nenum DT_IA_64_PLT_RESERVE =    (DT_LOPROC + 0);\nenum DT_IA_64_NUM =            1;\nenum R_IA64_NONE =             0x00;\nenum R_IA64_IMM14 =            0x21;\nenum R_IA64_IMM22 =            0x22;\nenum R_IA64_IMM64 =            0x23;\nenum R_IA64_DIR32MSB =         0x24;\nenum R_IA64_DIR32LSB =         0x25;\nenum R_IA64_DIR64MSB =         0x26;\nenum R_IA64_DIR64LSB =         0x27;\nenum R_IA64_GPREL22 =          0x2a;\nenum R_IA64_GPREL64I =         0x2b;\nenum R_IA64_GPREL32MSB =       0x2c;\nenum R_IA64_GPREL32LSB =       0x2d;\nenum R_IA64_GPREL64MSB =       0x2e;\nenum R_IA64_GPREL64LSB =       0x2f;\nenum R_IA64_LTOFF22 =          0x32;\nenum R_IA64_LTOFF64I =         0x33;\nenum R_IA64_PLTOFF22 =         0x3a;\nenum R_IA64_PLTOFF64I =        0x3b;\nenum R_IA64_PLTOFF64MSB =      0x3e;\nenum R_IA64_PLTOFF64LSB =      0x3f;\nenum R_IA64_FPTR64I =          0x43;\nenum R_IA64_FPTR32MSB =        0x44;\nenum R_IA64_FPTR32LSB =        0x45;\nenum R_IA64_FPTR64MSB =        0x46;\nenum R_IA64_FPTR64LSB =        0x47;\nenum R_IA64_PCREL60B =         0x48;\nenum R_IA64_PCREL21B =         0x49;\nenum R_IA64_PCREL21M =         0x4a;\nenum R_IA64_PCREL21F =         0x4b;\nenum R_IA64_PCREL32MSB =       0x4c;\nenum R_IA64_PCREL32LSB =       0x4d;\nenum R_IA64_PCREL64MSB =       0x4e;\nenum R_IA64_PCREL64LSB =       0x4f;\nenum R_IA64_LTOFF_FPTR22 =     0x52;\nenum R_IA64_LTOFF_FPTR64I =    0x53;\nenum R_IA64_LTOFF_FPTR32MSB =  0x54;\nenum R_IA64_LTOFF_FPTR32LSB =  0x55;\nenum R_IA64_LTOFF_FPTR64MSB =  0x56;\nenum R_IA64_LTOFF_FPTR64LSB =  0x57;\nenum R_IA64_SEGREL32MSB =      0x5c;\nenum R_IA64_SEGREL32LSB =      0x5d;\nenum R_IA64_SEGREL64MSB =      0x5e;\nenum R_IA64_SEGREL64LSB =      0x5f;\nenum R_IA64_SECREL32MSB =      0x64;\nenum R_IA64_SECREL32LSB =      0x65;\nenum R_IA64_SECREL64MSB =      0x66;\nenum R_IA64_SECREL64LSB =      0x67;\nenum R_IA64_REL32MSB =         0x6c;\nenum R_IA64_REL32LSB =         0x6d;\nenum R_IA64_REL64MSB =         0x6e;\nenum R_IA64_REL64LSB =         0x6f;\nenum R_IA64_LTV32MSB =         0x74;\nenum R_IA64_LTV32LSB =         0x75;\nenum R_IA64_LTV64MSB =         0x76;\nenum R_IA64_LTV64LSB =         0x77;\nenum R_IA64_PCREL21BI =        0x79;\nenum R_IA64_PCREL22 =          0x7a;\nenum R_IA64_PCREL64I =         0x7b;\nenum R_IA64_IPLTMSB =          0x80;\nenum R_IA64_IPLTLSB =          0x81;\nenum R_IA64_COPY =             0x84;\nenum R_IA64_SUB =              0x85;\nenum R_IA64_LTOFF22X =         0x86;\nenum R_IA64_LDXMOV =           0x87;\nenum R_IA64_TPREL14 =          0x91;\nenum R_IA64_TPREL22 =          0x92;\nenum R_IA64_TPREL64I =         0x93;\nenum R_IA64_TPREL64MSB =       0x96;\nenum R_IA64_TPREL64LSB =       0x97;\nenum R_IA64_LTOFF_TPREL22 =    0x9a;\nenum R_IA64_DTPMOD64MSB =      0xa6;\nenum R_IA64_DTPMOD64LSB =      0xa7;\nenum R_IA64_LTOFF_DTPMOD22 =   0xaa;\nenum R_IA64_DTPREL14 =         0xb1;\nenum R_IA64_DTPREL22 =         0xb2;\nenum R_IA64_DTPREL64I =        0xb3;\nenum R_IA64_DTPREL32MSB =      0xb4;\nenum R_IA64_DTPREL32LSB =      0xb5;\nenum R_IA64_DTPREL64MSB =      0xb6;\nenum R_IA64_DTPREL64LSB =      0xb7;\nenum R_IA64_LTOFF_DTPREL22 =   0xba;\nenum EF_SH_MACH_MASK =         0x1f;\nenum EF_SH_UNKNOWN =           0x0;\nenum EF_SH1 =                  0x1;\nenum EF_SH2 =                  0x2;\nenum EF_SH3 =                  0x3;\nenum EF_SH_DSP =               0x4;\nenum EF_SH3_DSP =              0x5;\nenum EF_SH4AL_DSP =            0x6;\nenum EF_SH3E =                 0x8;\nenum EF_SH4 =                  0x9;\nenum EF_SH2E =                 0xb;\nenum EF_SH4A =                 0xc;\nenum EF_SH2A =                 0xd;\nenum EF_SH4_NOFPU =            0x10;\nenum EF_SH4A_NOFPU =           0x11;\nenum EF_SH4_NOMMU_NOFPU =      0x12;\nenum EF_SH2A_NOFPU =           0x13;\nenum EF_SH3_NOMMU =            0x14;\nenum EF_SH2A_SH4_NOFPU =       0x15;\nenum EF_SH2A_SH3_NOFPU =       0x16;\nenum EF_SH2A_SH4 =             0x17;\nenum EF_SH2A_SH3E =            0x18;\nenum R_SH_NONE =               0;\nenum R_SH_DIR32 =              1;\nenum R_SH_REL32 =              2;\nenum R_SH_DIR8WPN =            3;\nenum R_SH_IND12W =             4;\nenum R_SH_DIR8WPL =            5;\nenum R_SH_DIR8WPZ =            6;\nenum R_SH_DIR8BP =             7;\nenum R_SH_DIR8W =              8;\nenum R_SH_DIR8L =              9;\nenum R_SH_SWITCH16 =           25;\nenum R_SH_SWITCH32 =           26;\nenum R_SH_USES =               27;\nenum R_SH_COUNT =              28;\nenum R_SH_ALIGN =              29;\nenum R_SH_CODE =               30;\nenum R_SH_DATA =               31;\nenum R_SH_LABEL =              32;\nenum R_SH_SWITCH8 =            33;\nenum R_SH_GNU_VTINHERIT =      34;\nenum R_SH_GNU_VTENTRY =        35;\nenum R_SH_TLS_GD_32 =          144;\nenum R_SH_TLS_LD_32 =          145;\nenum R_SH_TLS_LDO_32 =         146;\nenum R_SH_TLS_IE_32 =          147;\nenum R_SH_TLS_LE_32 =          148;\nenum R_SH_TLS_DTPMOD32 =       149;\nenum R_SH_TLS_DTPOFF32 =       150;\nenum R_SH_TLS_TPOFF32 =        151;\nenum R_SH_GOT32 =              160;\nenum R_SH_PLT32 =              161;\nenum R_SH_COPY =               162;\nenum R_SH_GLOB_DAT =           163;\nenum R_SH_JMP_SLOT =           164;\nenum R_SH_RELATIVE =           165;\nenum R_SH_GOTOFF =             166;\nenum R_SH_GOTPC =              167;\nenum R_SH_NUM =                256;\n\nenum EF_S390_HIGH_GPRS =    0x00000001;\n\nenum R_390_NONE =              0;\nenum R_390_8 =                 1;\nenum R_390_12 =                2;\nenum R_390_16 =                3;\nenum R_390_32 =                4;\nenum R_390_PC32 =              5;\nenum R_390_GOT12 =             6;\nenum R_390_GOT32 =             7;\nenum R_390_PLT32 =             8;\nenum R_390_COPY =              9;\nenum R_390_GLOB_DAT =          10;\nenum R_390_JMP_SLOT =          11;\nenum R_390_RELATIVE =          12;\nenum R_390_GOTOFF32 =          13;\nenum R_390_GOTPC =             14;\nenum R_390_GOT16 =             15;\nenum R_390_PC16 =              16;\nenum R_390_PC16DBL =           17;\nenum R_390_PLT16DBL =          18;\nenum R_390_PC32DBL =           19;\nenum R_390_PLT32DBL =          20;\nenum R_390_GOTPCDBL =          21;\nenum R_390_64 =                22;\nenum R_390_PC64 =              23;\nenum R_390_GOT64 =             24;\nenum R_390_PLT64 =             25;\nenum R_390_GOTENT =            26;\nenum R_390_GOTOFF16 =          27;\nenum R_390_GOTOFF64 =          28;\nenum R_390_GOTPLT12 =          29;\nenum R_390_GOTPLT16 =          30;\nenum R_390_GOTPLT32 =          31;\nenum R_390_GOTPLT64 =          32;\nenum R_390_GOTPLTENT =         33;\nenum R_390_PLTOFF16 =          34;\nenum R_390_PLTOFF32 =          35;\nenum R_390_PLTOFF64 =          36;\nenum R_390_TLS_LOAD =          37;\nenum R_390_TLS_GDCALL =        38;\nenum R_390_TLS_LDCALL =        39;\nenum R_390_TLS_GD32 =          40;\nenum R_390_TLS_GD64 =          41;\nenum R_390_TLS_GOTIE12 =       42;\nenum R_390_TLS_GOTIE32 =       43;\nenum R_390_TLS_GOTIE64 =       44;\nenum R_390_TLS_LDM32 =         45;\nenum R_390_TLS_LDM64 =         46;\nenum R_390_TLS_IE32 =          47;\nenum R_390_TLS_IE64 =          48;\nenum R_390_TLS_IEENT =         49;\nenum R_390_TLS_LE32 =          50;\nenum R_390_TLS_LE64 =          51;\nenum R_390_TLS_LDO32 =         52;\nenum R_390_TLS_LDO64 =         53;\nenum R_390_TLS_DTPMOD =        54;\nenum R_390_TLS_DTPOFF =        55;\nenum R_390_TLS_TPOFF =         56;\nenum R_390_20 =                57;\nenum R_390_GOT20 =             58;\nenum R_390_GOTPLT20 =          59;\nenum R_390_TLS_GOTIE20 =       60;\nenum R_390_IRELATIVE =         61;\nenum R_390_NUM =               62;\nenum R_CRIS_NONE =             0;\nenum R_CRIS_8 =                1;\nenum R_CRIS_16 =               2;\nenum R_CRIS_32 =               3;\nenum R_CRIS_8_PCREL =          4;\nenum R_CRIS_16_PCREL =         5;\nenum R_CRIS_32_PCREL =         6;\nenum R_CRIS_GNU_VTINHERIT =    7;\nenum R_CRIS_GNU_VTENTRY =      8;\nenum R_CRIS_COPY =             9;\nenum R_CRIS_GLOB_DAT =         10;\nenum R_CRIS_JUMP_SLOT =        11;\nenum R_CRIS_RELATIVE =         12;\nenum R_CRIS_16_GOT =           13;\nenum R_CRIS_32_GOT =           14;\nenum R_CRIS_16_GOTPLT =        15;\nenum R_CRIS_32_GOTPLT =        16;\nenum R_CRIS_32_GOTREL =        17;\nenum R_CRIS_32_PLT_GOTREL =    18;\nenum R_CRIS_32_PLT_PCREL =     19;\n\nenum R_CRIS_NUM =              20;\nenum R_X86_64_NONE =           0;\nenum R_X86_64_64 =             1;\nenum R_X86_64_PC32 =           2;\nenum R_X86_64_GOT32 =          3;\nenum R_X86_64_PLT32 =          4;\nenum R_X86_64_COPY =           5;\nenum R_X86_64_GLOB_DAT =       6;\nenum R_X86_64_JUMP_SLOT =      7;\nenum R_X86_64_RELATIVE =       8;\nenum R_X86_64_GOTPCREL =       9;\nenum R_X86_64_32 =             10;\nenum R_X86_64_32S =            11;\nenum R_X86_64_16 =             12;\nenum R_X86_64_PC16 =           13;\nenum R_X86_64_8 =              14;\nenum R_X86_64_PC8 =            15;\nenum R_X86_64_DTPMOD64 =       16;\nenum R_X86_64_DTPOFF64 =       17;\nenum R_X86_64_TPOFF64 =        18;\nenum R_X86_64_TLSGD =          19;\nenum R_X86_64_TLSLD =          20;\nenum R_X86_64_DTPOFF32 =       21;\nenum R_X86_64_GOTTPOFF =       22;\nenum R_X86_64_TPOFF32 =        23;\nenum R_X86_64_PC64 =           24;\nenum R_X86_64_GOTOFF64 =       25;\nenum R_X86_64_GOTPC32 =        26;\nenum R_X86_64_GOT64 =          27;\nenum R_X86_64_GOTPCREL64 =     28;\nenum R_X86_64_GOTPC64 =        29;\nenum R_X86_64_GOTPLT64 =       30;\nenum R_X86_64_PLTOFF64 =       31;\nenum R_X86_64_SIZE32 =         32;\nenum R_X86_64_SIZE64 =         33;\nenum R_X86_64_GOTPC32_TLSDESC = 34;\nenum R_X86_64_TLSDESC_CALL =   35;\nenum R_X86_64_TLSDESC =        36;\nenum R_X86_64_IRELATIVE =      37;\nenum R_X86_64_RELATIVE64 =     38;\n\nenum R_X86_64_NUM =            39;\nenum R_MN10300_NONE =          0;\nenum R_MN10300_32 =            1;\nenum R_MN10300_16 =            2;\nenum R_MN10300_8 =             3;\nenum R_MN10300_PCREL32 =       4;\nenum R_MN10300_PCREL16 =       5;\nenum R_MN10300_PCREL8 =        6;\nenum R_MN10300_GNU_VTINHERIT = 7;\nenum R_MN10300_GNU_VTENTRY =   8;\nenum R_MN10300_24 =            9;\nenum R_MN10300_GOTPC32 =       10;\nenum R_MN10300_GOTPC16 =       11;\nenum R_MN10300_GOTOFF32 =      12;\nenum R_MN10300_GOTOFF24 =      13;\nenum R_MN10300_GOTOFF16 =      14;\nenum R_MN10300_PLT32 =         15;\nenum R_MN10300_PLT16 =         16;\nenum R_MN10300_GOT32 =         17;\nenum R_MN10300_GOT24 =         18;\nenum R_MN10300_GOT16 =         19;\nenum R_MN10300_COPY =          20;\nenum R_MN10300_GLOB_DAT =      21;\nenum R_MN10300_JMP_SLOT =      22;\nenum R_MN10300_RELATIVE =      23;\nenum R_MN10300_TLS_GD =        24;\nenum R_MN10300_TLS_LD =        25;\nenum R_MN10300_TLS_LDO =       26;\nenum R_MN10300_TLS_GOTIE =     27;\nenum R_MN10300_TLS_IE =        28;\nenum R_MN10300_TLS_LE =        29;\nenum R_MN10300_TLS_DTPMOD =    30;\nenum R_MN10300_TLS_DTPOFF =    31;\nenum R_MN10300_TLS_TPOFF =     32;\nenum R_MN10300_SYM_DIFF =      33;\nenum R_MN10300_ALIGN =         34;\nenum R_MN10300_NUM =           35;\nenum R_M32R_NONE =             0;\nenum R_M32R_16 =               1;\nenum R_M32R_32 =               2;\nenum R_M32R_24 =               3;\nenum R_M32R_10_PCREL =         4;\nenum R_M32R_18_PCREL =         5;\nenum R_M32R_26_PCREL =         6;\nenum R_M32R_HI16_ULO =         7;\nenum R_M32R_HI16_SLO =         8;\nenum R_M32R_LO16 =             9;\nenum R_M32R_SDA16 =            10;\nenum R_M32R_GNU_VTINHERIT =    11;\nenum R_M32R_GNU_VTENTRY =      12;\nenum R_M32R_16_RELA =          33;\nenum R_M32R_32_RELA =          34;\nenum R_M32R_24_RELA =          35;\nenum R_M32R_10_PCREL_RELA =    36;\nenum R_M32R_18_PCREL_RELA =    37;\nenum R_M32R_26_PCREL_RELA =    38;\nenum R_M32R_HI16_ULO_RELA =    39;\nenum R_M32R_HI16_SLO_RELA =    40;\nenum R_M32R_LO16_RELA =        41;\nenum R_M32R_SDA16_RELA =       42;\nenum R_M32R_RELA_GNU_VTINHERIT =       43;\nenum R_M32R_RELA_GNU_VTENTRY = 44;\nenum R_M32R_REL32 =            45;\n\nenum R_M32R_GOT24 =            48;\nenum R_M32R_26_PLTREL =        49;\nenum R_M32R_COPY =             50;\nenum R_M32R_GLOB_DAT =         51;\nenum R_M32R_JMP_SLOT =         52;\nenum R_M32R_RELATIVE =         53;\nenum R_M32R_GOTOFF =           54;\nenum R_M32R_GOTPC24 =          55;\nenum R_M32R_GOT16_HI_ULO =     56;\nenum R_M32R_GOT16_HI_SLO =     57;\nenum R_M32R_GOT16_LO =         58;\nenum R_M32R_GOTPC_HI_ULO =     59;\nenum R_M32R_GOTPC_HI_SLO =     60;\nenum R_M32R_GOTPC_LO =         61;\nenum R_M32R_GOTOFF_HI_ULO =    62;\nenum R_M32R_GOTOFF_HI_SLO =    63;\nenum R_M32R_GOTOFF_LO =        64;\nenum R_M32R_NUM =              256;\nenum R_TILEPRO_NONE =          0;\nenum R_TILEPRO_32 =            1;\nenum R_TILEPRO_16 =            2;\nenum R_TILEPRO_8 =             3;\nenum R_TILEPRO_32_PCREL =      4;\nenum R_TILEPRO_16_PCREL =      5;\nenum R_TILEPRO_8_PCREL =       6;\nenum R_TILEPRO_LO16 =          7;\nenum R_TILEPRO_HI16 =          8;\nenum R_TILEPRO_HA16 =          9;\nenum R_TILEPRO_COPY =          10;\nenum R_TILEPRO_GLOB_DAT =      11;\nenum R_TILEPRO_JMP_SLOT =      12;\nenum R_TILEPRO_RELATIVE =      13;\nenum R_TILEPRO_BROFF_X1 =      14;\nenum R_TILEPRO_JOFFLONG_X1 =   15;\nenum R_TILEPRO_JOFFLONG_X1_PLT = 16;\nenum R_TILEPRO_IMM8_X0 =       17;\nenum R_TILEPRO_IMM8_Y0 =       18;\nenum R_TILEPRO_IMM8_X1 =       19;\nenum R_TILEPRO_IMM8_Y1 =       20;\nenum R_TILEPRO_MT_IMM15_X1 =   21;\nenum R_TILEPRO_MF_IMM15_X1 =   22;\nenum R_TILEPRO_IMM16_X0 =      23;\nenum R_TILEPRO_IMM16_X1 =      24;\nenum R_TILEPRO_IMM16_X0_LO =   25;\nenum R_TILEPRO_IMM16_X1_LO =   26;\nenum R_TILEPRO_IMM16_X0_HI =   27;\nenum R_TILEPRO_IMM16_X1_HI =   28;\nenum R_TILEPRO_IMM16_X0_HA =   29;\nenum R_TILEPRO_IMM16_X1_HA =   30;\nenum R_TILEPRO_IMM16_X0_PCREL = 31;\nenum R_TILEPRO_IMM16_X1_PCREL = 32;\nenum R_TILEPRO_IMM16_X0_LO_PCREL = 33;\nenum R_TILEPRO_IMM16_X1_LO_PCREL = 34;\nenum R_TILEPRO_IMM16_X0_HI_PCREL = 35;\nenum R_TILEPRO_IMM16_X1_HI_PCREL = 36;\nenum R_TILEPRO_IMM16_X0_HA_PCREL = 37;\nenum R_TILEPRO_IMM16_X1_HA_PCREL = 38;\nenum R_TILEPRO_IMM16_X0_GOT =  39;\nenum R_TILEPRO_IMM16_X1_GOT =  40;\nenum R_TILEPRO_IMM16_X0_GOT_LO = 41;\nenum R_TILEPRO_IMM16_X1_GOT_LO = 42;\nenum R_TILEPRO_IMM16_X0_GOT_HI = 43;\nenum R_TILEPRO_IMM16_X1_GOT_HI = 44;\nenum R_TILEPRO_IMM16_X0_GOT_HA = 45;\nenum R_TILEPRO_IMM16_X1_GOT_HA = 46;\nenum R_TILEPRO_MMSTART_X0 =    47;\nenum R_TILEPRO_MMEND_X0 =      48;\nenum R_TILEPRO_MMSTART_X1 =    49;\nenum R_TILEPRO_MMEND_X1 =      50;\nenum R_TILEPRO_SHAMT_X0 =      51;\nenum R_TILEPRO_SHAMT_X1 =      52;\nenum R_TILEPRO_SHAMT_Y0 =      53;\nenum R_TILEPRO_SHAMT_Y1 =      54;\nenum R_TILEPRO_DEST_IMM8_X1 =  55;\nenum R_TILEPRO_TLS_GD_CALL =   60;\nenum R_TILEPRO_IMM8_X0_TLS_GD_ADD = 61;\nenum R_TILEPRO_IMM8_X1_TLS_GD_ADD = 62;\nenum R_TILEPRO_IMM8_Y0_TLS_GD_ADD = 63;\nenum R_TILEPRO_IMM8_Y1_TLS_GD_ADD = 64;\nenum R_TILEPRO_TLS_IE_LOAD =   65;\nenum R_TILEPRO_IMM16_X0_TLS_GD = 66;\nenum R_TILEPRO_IMM16_X1_TLS_GD = 67;\nenum R_TILEPRO_IMM16_X0_TLS_GD_LO = 68;\nenum R_TILEPRO_IMM16_X1_TLS_GD_LO = 69;\nenum R_TILEPRO_IMM16_X0_TLS_GD_HI = 70;\nenum R_TILEPRO_IMM16_X1_TLS_GD_HI = 71;\nenum R_TILEPRO_IMM16_X0_TLS_GD_HA = 72;\nenum R_TILEPRO_IMM16_X1_TLS_GD_HA = 73;\nenum R_TILEPRO_IMM16_X0_TLS_IE = 74;\nenum R_TILEPRO_IMM16_X1_TLS_IE = 75;\nenum R_TILEPRO_IMM16_X0_TLS_IE_LO = 76;\nenum R_TILEPRO_IMM16_X1_TLS_IE_LO = 77;\nenum R_TILEPRO_IMM16_X0_TLS_IE_HI = 78;\nenum R_TILEPRO_IMM16_X1_TLS_IE_HI = 79;\nenum R_TILEPRO_IMM16_X0_TLS_IE_HA = 80;\nenum R_TILEPRO_IMM16_X1_TLS_IE_HA = 81;\nenum R_TILEPRO_TLS_DTPMOD32 =  82;\nenum R_TILEPRO_TLS_DTPOFF32 =  83;\nenum R_TILEPRO_TLS_TPOFF32 =   84;\nenum R_TILEPRO_IMM16_X0_TLS_LE = 85;\nenum R_TILEPRO_IMM16_X1_TLS_LE = 86;\nenum R_TILEPRO_IMM16_X0_TLS_LE_LO = 87;\nenum R_TILEPRO_IMM16_X1_TLS_LE_LO = 88;\nenum R_TILEPRO_IMM16_X0_TLS_LE_HI = 89;\nenum R_TILEPRO_IMM16_X1_TLS_LE_HI = 90;\nenum R_TILEPRO_IMM16_X0_TLS_LE_HA = 91;\nenum R_TILEPRO_IMM16_X1_TLS_LE_HA = 92;\n\nenum R_TILEPRO_GNU_VTINHERIT = 128;\nenum R_TILEPRO_GNU_VTENTRY =   129;\n\nenum R_TILEPRO_NUM =           130;\nenum R_TILEGX_NONE =           0;\nenum R_TILEGX_64 =             1;\nenum R_TILEGX_32 =             2;\nenum R_TILEGX_16 =             3;\nenum R_TILEGX_8 =              4;\nenum R_TILEGX_64_PCREL =       5;\nenum R_TILEGX_32_PCREL =       6;\nenum R_TILEGX_16_PCREL =       7;\nenum R_TILEGX_8_PCREL =        8;\nenum R_TILEGX_HW0 =            9;\nenum R_TILEGX_HW1 =            10;\nenum R_TILEGX_HW2 =            11;\nenum R_TILEGX_HW3 =            12;\nenum R_TILEGX_HW0_LAST =       13;\nenum R_TILEGX_HW1_LAST =       14;\nenum R_TILEGX_HW2_LAST =       15;\nenum R_TILEGX_COPY =           16;\nenum R_TILEGX_GLOB_DAT =       17;\nenum R_TILEGX_JMP_SLOT =       18;\nenum R_TILEGX_RELATIVE =       19;\nenum R_TILEGX_BROFF_X1 =       20;\nenum R_TILEGX_JUMPOFF_X1 =     21;\nenum R_TILEGX_JUMPOFF_X1_PLT = 22;\nenum R_TILEGX_IMM8_X0 =        23;\nenum R_TILEGX_IMM8_Y0 =        24;\nenum R_TILEGX_IMM8_X1 =        25;\nenum R_TILEGX_IMM8_Y1 =        26;\nenum R_TILEGX_DEST_IMM8_X1 =   27;\nenum R_TILEGX_MT_IMM14_X1 =    28;\nenum R_TILEGX_MF_IMM14_X1 =    29;\nenum R_TILEGX_MMSTART_X0 =     30;\nenum R_TILEGX_MMEND_X0 =       31;\nenum R_TILEGX_SHAMT_X0 =       32;\nenum R_TILEGX_SHAMT_X1 =       33;\nenum R_TILEGX_SHAMT_Y0 =       34;\nenum R_TILEGX_SHAMT_Y1 =       35;\nenum R_TILEGX_IMM16_X0_HW0 =   36;\nenum R_TILEGX_IMM16_X1_HW0 =   37;\nenum R_TILEGX_IMM16_X0_HW1 =   38;\nenum R_TILEGX_IMM16_X1_HW1 =   39;\nenum R_TILEGX_IMM16_X0_HW2 =   40;\nenum R_TILEGX_IMM16_X1_HW2 =   41;\nenum R_TILEGX_IMM16_X0_HW3 =   42;\nenum R_TILEGX_IMM16_X1_HW3 =   43;\nenum R_TILEGX_IMM16_X0_HW0_LAST = 44;\nenum R_TILEGX_IMM16_X1_HW0_LAST = 45;\nenum R_TILEGX_IMM16_X0_HW1_LAST = 46;\nenum R_TILEGX_IMM16_X1_HW1_LAST = 47;\nenum R_TILEGX_IMM16_X0_HW2_LAST = 48;\nenum R_TILEGX_IMM16_X1_HW2_LAST = 49;\nenum R_TILEGX_IMM16_X0_HW0_PCREL = 50;\nenum R_TILEGX_IMM16_X1_HW0_PCREL = 51;\nenum R_TILEGX_IMM16_X0_HW1_PCREL = 52;\nenum R_TILEGX_IMM16_X1_HW1_PCREL = 53;\nenum R_TILEGX_IMM16_X0_HW2_PCREL = 54;\nenum R_TILEGX_IMM16_X1_HW2_PCREL = 55;\nenum R_TILEGX_IMM16_X0_HW3_PCREL = 56;\nenum R_TILEGX_IMM16_X1_HW3_PCREL = 57;\nenum R_TILEGX_IMM16_X0_HW0_LAST_PCREL = 58;\nenum R_TILEGX_IMM16_X1_HW0_LAST_PCREL = 59;\nenum R_TILEGX_IMM16_X0_HW1_LAST_PCREL = 60;\nenum R_TILEGX_IMM16_X1_HW1_LAST_PCREL = 61;\nenum R_TILEGX_IMM16_X0_HW2_LAST_PCREL = 62;\nenum R_TILEGX_IMM16_X1_HW2_LAST_PCREL = 63;\nenum R_TILEGX_IMM16_X0_HW0_GOT = 64;\nenum R_TILEGX_IMM16_X1_HW0_GOT = 65;\nenum R_TILEGX_IMM16_X0_HW0_PLT_PCREL = 66;\nenum R_TILEGX_IMM16_X1_HW0_PLT_PCREL = 67;\nenum R_TILEGX_IMM16_X0_HW1_PLT_PCREL = 68;\nenum R_TILEGX_IMM16_X1_HW1_PLT_PCREL = 69;\nenum R_TILEGX_IMM16_X0_HW2_PLT_PCREL = 70;\nenum R_TILEGX_IMM16_X1_HW2_PLT_PCREL = 71;\nenum R_TILEGX_IMM16_X0_HW0_LAST_GOT = 72;\nenum R_TILEGX_IMM16_X1_HW0_LAST_GOT = 73;\nenum R_TILEGX_IMM16_X0_HW1_LAST_GOT = 74;\nenum R_TILEGX_IMM16_X1_HW1_LAST_GOT = 75;\nenum R_TILEGX_IMM16_X0_HW3_PLT_PCREL = 76;\nenum R_TILEGX_IMM16_X1_HW3_PLT_PCREL = 77;\nenum R_TILEGX_IMM16_X0_HW0_TLS_GD = 78;\nenum R_TILEGX_IMM16_X1_HW0_TLS_GD = 79;\nenum R_TILEGX_IMM16_X0_HW0_TLS_LE = 80;\nenum R_TILEGX_IMM16_X1_HW0_TLS_LE = 81;\nenum R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE = 82;\nenum R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE = 83;\nenum R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE = 84;\nenum R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE = 85;\nenum R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD = 86;\nenum R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD = 87;\nenum R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD = 88;\nenum R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD = 89;\nenum R_TILEGX_IMM16_X0_HW0_TLS_IE = 92;\nenum R_TILEGX_IMM16_X1_HW0_TLS_IE = 93;\nenum R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL = 94;\nenum R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL = 95;\nenum R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL = 96;\nenum R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL = 97;\nenum R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL = 98;\nenum R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL = 99;\nenum R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE = 100;\nenum R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE = 101;\nenum R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE = 102;\nenum R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE = 103;\nenum R_TILEGX_TLS_DTPMOD64 =   106;\nenum R_TILEGX_TLS_DTPOFF64 =   107;\nenum R_TILEGX_TLS_TPOFF64 =    108;\nenum R_TILEGX_TLS_DTPMOD32 =   109;\nenum R_TILEGX_TLS_DTPOFF32 =   110;\nenum R_TILEGX_TLS_TPOFF32 =    111;\nenum R_TILEGX_TLS_GD_CALL =    112;\nenum R_TILEGX_IMM8_X0_TLS_GD_ADD = 113;\nenum R_TILEGX_IMM8_X1_TLS_GD_ADD = 114;\nenum R_TILEGX_IMM8_Y0_TLS_GD_ADD = 115;\nenum R_TILEGX_IMM8_Y1_TLS_GD_ADD = 116;\nenum R_TILEGX_TLS_IE_LOAD =    117;\nenum R_TILEGX_IMM8_X0_TLS_ADD = 118;\nenum R_TILEGX_IMM8_X1_TLS_ADD = 119;\nenum R_TILEGX_IMM8_Y0_TLS_ADD = 120;\nenum R_TILEGX_IMM8_Y1_TLS_ADD = 121;\n\nenum R_TILEGX_GNU_VTINHERIT =  128;\nenum R_TILEGX_GNU_VTENTRY =    129;\n\nenum R_TILEGX_NUM =            130;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/epoll.d",
    "content": "/**\n * D header file to interface with the Linux epoll API (http://man7.org/linux/man-pages/man7/epoll.7.html).\n * Available since Linux 2.6\n *\n * Copyright: Copyright Adil Baig 2012.\n * License : $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors  : Adil Baig (github.com/adilbaig)\n */\nmodule core.sys.linux.epoll;\n\nversion (linux):\n\nextern (C):\n@system:\n@nogc:\nnothrow:\n\nenum\n{\n    EPOLL_CLOEXEC  = 0x80000,\n    EPOLL_NONBLOCK = 0x800\n}\n\nenum\n{\n    EPOLLIN     = 0x001,\n    EPOLLPRI    = 0x002,\n    EPOLLOUT    = 0x004,\n    EPOLLRDNORM = 0x040,\n    EPOLLRDBAND = 0x080,\n    EPOLLWRNORM = 0x100,\n    EPOLLWRBAND = 0x200,\n    EPOLLMSG    = 0x400,\n    EPOLLERR    = 0x008,\n    EPOLLHUP    = 0x010,\n    EPOLLRDHUP  = 0x2000, // since Linux 2.6.17\n    EPOLLONESHOT = 1u << 30,\n    EPOLLET     = 1u << 31\n}\n\n/* Valid opcodes ( \"op\" parameter ) to issue to epoll_ctl().  */\nenum\n{\n    EPOLL_CTL_ADD = 1, // Add a file descriptor to the interface.\n    EPOLL_CTL_DEL = 2, // Remove a file descriptor from the interface.\n    EPOLL_CTL_MOD = 3, // Change file descriptor epoll_event structure.\n}\n\nversion (X86)\n{\n    align(1) struct epoll_event\n    {\n    align(1):\n        uint events;\n        epoll_data_t data;\n    }\n}\nelse version (X86_64)\n{\n    align(1) struct epoll_event\n    {\n    align(1):\n        uint events;\n        epoll_data_t data;\n    }\n}\nelse version (ARM)\n{\n    struct epoll_event\n    {\n        uint events;\n        epoll_data_t data;\n    }\n}\nelse version (AArch64)\n{\n    struct epoll_event\n    {\n        uint events;\n        epoll_data_t data;\n    }\n}\nelse version (PPC)\n{\n    struct epoll_event\n    {\n        uint events;\n        epoll_data_t data;\n    }\n}\nelse version (PPC64)\n{\n    struct epoll_event\n    {\n        uint events;\n        epoll_data_t data;\n    }\n}\nelse version (MIPS32)\n{\n    struct epoll_event\n    {\n        uint events;\n        epoll_data_t data;\n    }\n}\nelse version (MIPS64)\n{\n    struct epoll_event\n    {\n        uint events;\n        epoll_data_t data;\n    }\n}\nelse version (SPARC64)\n{\n    struct epoll_event\n    {\n        uint events;\n        epoll_data_t data;\n    }\n}\nelse version (SystemZ)\n{\n    struct epoll_event\n    {\n        uint events;\n        epoll_data_t data;\n    }\n}\nelse\n{\n    static assert(false, \"Platform not supported\");\n}\n\nunion epoll_data_t\n{\n    void *ptr;\n    int fd;\n    uint u32;\n    ulong u64;\n}\n\nint epoll_create (int size);\nint epoll_create1 (int flags);\nint epoll_ctl (int epfd, int op, int fd, epoll_event *event);\nint epoll_wait (int epfd, epoll_event *events, int maxevents, int timeout);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/errno.d",
    "content": "/**\n * D header file for GNU/Linux\n *\n * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/errno.h, glibc stdlib/errno.h)\n */\nmodule core.sys.linux.errno;\n\nversion (linux):\nextern (C):\nnothrow:\n\npublic import core.stdc.errno;\nimport core.sys.linux.config;\n\nstatic if (__USE_GNU)\n{\n    extern __gshared char* program_invocation_name, program_invocation_short_name;\n    alias error_t = int;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/execinfo.d",
    "content": "/**\n * D header file for GNU/Linux.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Martin Nowak\n */\nmodule core.sys.linux.execinfo;\n\nversion (linux):\nextern (C):\nnothrow:\n\nint backtrace(void** buffer, int size);\nchar** backtrace_symbols(const(void*)* buffer, int size);\nvoid backtrace_symbols_fd(const(void*)* buffer, int size, int fd);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/fcntl.d",
    "content": "module core.sys.linux.fcntl;\n\npublic import core.sys.posix.fcntl;\n\nversion (linux):\nextern(C):\nnothrow:\n\n// From linux/falloc.h\n/// fallocate(2) params\nenum {\n    /// Allocates and initializes to zero the disk space\n    /// within the specified range, but the file size\n    /// will not be modified.\n    FALLOC_FL_KEEP_SIZE = 0x01,\n    /// Deallocates space (i.e. creates a hole)\n    FALLOC_FL_PUNCH_HOLE = 0x02,\n    /// Newly allocated blocks will be marked as initialized.\n    FALLOC_FL_NO_HIDE_STALE = 0x04,\n    /// Removes a byte range from a file, without leaving a hole\n    FALLOC_FL_COLLAPSE_RANGE = 0x08,\n    /// Zeroes space in the specified byte range\n    FALLOC_FL_ZERO_RANGE = 0x10,\n    /// Increases the file space by inserting a hole\n    /// without overwriting any existing data\n    FALLOC_FL_INSERT_RANGE = 0x20,\n    /// Used to unshare shared blocks within\n    /// the file size without overwriting any existing data\n    FALLOC_FL_UNSHARE_RANGE = 0x40\n}\n\n// From asm-generic/fcntl.h\n/**\n\nOpen File Description locks\n\nUsually record locks held by a process are released on *any* close and are\nnot inherited across a fork().\n\nThese cmd values will set locks that conflict with process-associated\nrecord  locks, but are \"owned\" by the open file description, not the\nprocess. This means that they are inherited across fork() like BSD (flock)\nlocks, and they are only released automatically when the last reference to\nthe the open file against which they were acquired is put.\n\n*/\nenum\n{\n    /// Queries the system if the lock could be placed\n    F_OFD_GETLK  = 36,\n    /// Acquires or releases an open file description lock\n    F_OFD_SETLK  = 37,\n    /// Same as F_OFD_SETLK, but waits if a conflicting lock is held on the file\n    F_OFD_SETLKW = 38\n}\n\n// Linux-specific fallocate\n// (http://man7.org/linux/man-pages/man2/fallocate.2.html)\nint fallocate(int fd, int mode, off_t offset, off_t len);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/ifaddrs.d",
    "content": "/*******************************************************************************\n\n    D binding for the interface addresses querying\n\n    Defines functions getifaddrs/freeifaddrs and the structure\n    they operate on.\n\n    getifaddrs(3)   get interface addresses\n    freeifaddrs(3)  deallocates the structure returned from getifaddrs\n\n    Copyright:  Copyright (c) 2016 Sociomantic Labs. All rights reserved.\n    License:    $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:    Nemanja Boric\n\n*******************************************************************************/\n\nmodule core.sys.linux.ifaddrs;\n\nimport core.sys.posix.sys.socket;\n\nversion (linux):\nextern (C):\nnothrow:\n@nogc:\n\nstruct ifaddrs\n{\n    /// Next item in the list\n    ifaddrs*         ifa_next;\n    /// Name of the interface\n    char*            ifa_name;\n    /// Flags from SIOCGIFFLAGS\n    uint      ifa_flags;\n    /// Address of interface\n    sockaddr* ifa_addr;\n    /// Netmask of interface\n    sockaddr* ifa_netmask;\n\n    union\n    {\n        /// Broadcast address of the interface\n        sockaddr* ifu_broadaddr;\n        /// Point-to-point destination addresss\n        sockaddr* if_dstaddr;\n    }\n\n    /// Address specific data\n    void* ifa_data;\n};\n\n/// Returns: linked list of ifaddrs structures describing interfaces\nint getifaddrs(ifaddrs** );\n/// Frees the linked list returned by getifaddrs\nvoid freeifaddrs(ifaddrs* );\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/link.d",
    "content": "/**\n * D header file for GNU/Linux\n *\n * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=elf/link.h, glibc elf/link.h)\n */\nmodule core.sys.linux.link;\n\nversion (linux):\nextern (C):\nnothrow:\n\nimport core.stdc.stdint : uintptr_t, uint32_t, uint64_t;\nimport core.sys.linux.config : __WORDSIZE;\nimport core.sys.linux.dlfcn : Lmid_t;\nimport core.sys.linux.elf;\n\n// <bits/elfclass.h>\nversion (X86)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h\n    alias __WORDSIZE __ELF_NATIVE_CLASS;\n    alias uint32_t Elf_Symndx;\n}\nelse version (X86_64)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h\n    alias __WORDSIZE __ELF_NATIVE_CLASS;\n    alias uint32_t Elf_Symndx;\n}\nelse version (MIPS32)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h\n    alias __WORDSIZE __ELF_NATIVE_CLASS;\n    alias uint32_t Elf_Symndx;\n}\nelse version (MIPS64)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h\n    alias __WORDSIZE __ELF_NATIVE_CLASS;\n    alias uint32_t Elf_Symndx;\n}\nelse version (PPC)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h\n    alias __WORDSIZE __ELF_NATIVE_CLASS;\n    alias uint32_t Elf_Symndx;\n}\nelse version (PPC64)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h\n    alias __WORDSIZE __ELF_NATIVE_CLASS;\n    alias uint32_t Elf_Symndx;\n}\nelse version (ARM)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h\n    alias __WORDSIZE __ELF_NATIVE_CLASS;\n    alias uint32_t Elf_Symndx;\n}\nelse version (AArch64)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h\n    alias __WORDSIZE __ELF_NATIVE_CLASS;\n    alias uint32_t Elf_Symndx;\n}\nelse version (SPARC64)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h\n    alias __WORDSIZE __ELF_NATIVE_CLASS;\n    alias uint32_t Elf_Symndx;\n}\nelse version (SystemZ)\n{\n    // http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/s390/bits/elfclass.h\n    alias __WORDSIZE __ELF_NATIVE_CLASS;\n    alias uint64_t Elf_Symndx;\n}\nelse\n    static assert(0, \"unimplemented\");\n// <bits/elfclass.h>\n\ntemplate ElfW(string type)\n{\n    mixin(\"alias Elf\"~__ELF_NATIVE_CLASS.stringof~\"_\"~type~\" ElfW;\");\n}\n\nenum\n{\n    RT_CONSISTENT,\n    RT_ADD,\n    RT_DELETE,\n}\n\nstruct r_debug\n{\n    int r_version;\n    link_map* r_map;\n    ElfW!\"Addr\" r_brk;\n    typeof(RT_CONSISTENT) r_state;\n    ElfW!\"Addr\" r_ldbase;\n}\n\nextern r_debug _r_debug;\nextern ElfW!\"Dyn\"* _DYNAMIC;\n\nstruct link_map\n{\n    ElfW!\"Addr\" l_addr;\n    char* l_name;\n    ElfW!\"Dyn\"* l_ld;\n    link_map* l_next, l_prev;\n}\n\nenum\n{\n    LA_ACT_CONSISTENT,\n    LA_ACT_ADD,\n    LA_ACT_DELETE,\n}\n\nenum\n{\n    LA_SER_ORIG = 0x01,\n    LA_SER_LIBPATH = 0x02,\n    LA_SER_RUNPATH = 0x04,\n    LA_SER_CONFIG = 0x08,\n    LA_SER_DEFAULT = 0x40,\n    LA_SER_SECURE = 0x80,\n}\n\n\nenum\n{\n    LA_FLG_BINDTO = 0x01,\n    LA_FLG_BINDFROM = 0x02,\n}\n\n\nenum\n{\n    LA_SYMB_NOPLTENTER = 0x01,\n    LA_SYMB_NOPLTEXIT = 0x02,\n    LA_SYMB_STRUCTCALL = 0x04,\n    LA_SYMB_DLSYM = 0x08,\n    LA_SYMB_ALTVALUE = 0x10,\n}\n\nstruct dl_phdr_info\n{\n    ElfW!\"Addr\" dlpi_addr;\n    const(char)* dlpi_name;\n    const(ElfW!\"Phdr\")* dlpi_phdr;\n    ElfW!\"Half\" dlpi_phnum;\n\n    // check the SIZE argument of the dl_iterate_phdr callback whether\n    // the following members are available\n    ulong dlpi_adds;\n    ulong dlpi_subs;\n\n    size_t dlpi_tls_modid;\n    void *dlpi_tls_data;\n}\n\nprivate alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;\nprivate alias extern(C) int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_cb_ngc;\nextern int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data);\nextern int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc;\n\n// ld.so auditing interfaces prototypes have to be defined by the auditing DSO.\nextern uint la_version(uint __version);\nextern void la_activity(uintptr_t *__cookie, uint __flag);\nextern char* la_objsearch(const(char)* __name, uintptr_t* __cookie,\n                          uint __flag);\nextern uint la_objopen(link_map* __map, Lmid_t __lmid,\n                       uintptr_t* __cookie);\nextern void la_preinit(uintptr_t* __cookie);\nextern uintptr_t la_symbind32(Elf32_Sym* __sym, uint __ndx,\n                              uintptr_t* __refcook, uintptr_t* __defcook,\n                              uint *__flags, const(char)* __symname);\nextern uintptr_t la_symbind64(Elf64_Sym* __sym, uint __ndx,\n                              uintptr_t* __refcook, uintptr_t* __defcook,\n                              uint* __flags, const(char)* __symname);\nextern uint la_objclose(uintptr_t *__cookie);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/netinet/in_.d",
    "content": "//Written in the D programming language\n\n/++\n    D header file for Linux's extensions to POSIX's netinet/in.h.\n\n    Copyright: Copyright 2017 -\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n +/\nmodule core.sys.linux.netinet.in_;\n\nimport core.sys.posix.config;\n\npublic import core.sys.posix.netinet.in_;\n\nversion (CRuntime_Glibc)         version = linux_libc;\nelse version (CRuntime_Musl)     version = linux_libc;\nelse version (CRuntime_Bionic)   version = linux_libc;\nelse version (CRuntime_UClibc)   version = linux_libc;\n\nversion (CRuntime_Glibc)         version = gnu_libc;\nelse version (CRuntime_UClibc)   version = gnu_libc;\n\nversion (linux_libc)\n{\n    extern(C) nothrow @nogc:\n\n    enum IPPROTO_IPIP    = 4;\n    enum IPPROTO_EGP     = 8;\n    enum IPPROTO_TP      = 29;\n    enum IPPROTO_DCCP    = 33;\n    enum IPPROTO_RSVP    = 46;\n    enum IPPROTO_GRE     = 47;\n    enum IPPROTO_ESP     = 50;\n    enum IPPROTO_AH      = 51;\n    enum IPPROTO_MTP     = 92;\n    enum IPPROTO_BEETPH  = 94;\n    enum IPPROTO_ENCAP   = 98;\n    enum IPPROTO_PIM     = 103;\n    enum IPPROTO_COMP    = 108;\n    enum IPPROTO_SCTP    = 132;\n    enum IPPROTO_UDPLITE = 136;\n    enum IPPROTO_MPLS    = 137;\n\n    enum IPPROTO_HOPOPTS  = 0;\n    enum IPPROTO_ROUTING  = 43;\n    enum IPPROTO_FRAGMENT = 44;\n    enum IPPROTO_ICMPV6   = 58;\n    enum IPPROTO_NONE     = 59;\n    enum IPPROTO_DSTOPTS  = 60;\n    enum IPPROTO_MH       = 135;\n\n    enum IPPORT_ECHO       = 7;\n    enum IPPORT_DISCARD    = 9;\n    enum IPPORT_SYSTAT     = 11;\n    enum IPPORT_DAYTIME    = 13;\n    enum IPPORT_NETSTAT    = 15;\n    enum IPPORT_FTP        = 21;\n    enum IPPORT_TELNET     = 23;\n    enum IPPORT_SMTP       = 25;\n    enum IPPORT_TIMESERVER = 37;\n    enum IPPORT_NAMESERVER = 42;\n    enum IPPORT_WHOIS      = 43;\n    enum IPPORT_MTP        = 57;\n\n    enum IPPORT_TFTP    = 69;\n    enum IPPORT_RJE     = 77;\n    enum IPPORT_FINGER  = 79;\n    enum IPPORT_TTYLINK = 87;\n    enum IPPORT_SUPDUP  = 95;\n\n    enum IPPORT_EXECSERVER = 512;\n    enum IPPORT_LOGINSERVER = 513;\n    enum IPPORT_CMDSERVER = 514;\n    enum IPPORT_EFSSERVER = 520;\n\n    enum IPPORT_BIFFUDP = 512;\n    enum IPPORT_WHOSERVER = 513;\n    enum IPPORT_ROUTESERVER = 520;\n\n    enum IPPORT_RESERVED = 1024;\n\n    enum IPPORT_USERRESERVED = 5000;\n\n    extern(D) bool IN_CLASSA(in_addr_t i) pure @safe { return (i & 0x80000000) == 0; }\n    enum IN_CLASSA_NET    = 0xff000000;\n    enum IN_CLASSA_NSHIFT = 24;\n    enum IN_CLASSA_HOST   = 0xffffffff & ~IN_CLASSA_NET;\n    enum IN_CLASSA_MAX    = 128;\n\n    extern(D) bool IN_CLASSB(in_addr_t i) pure @safe { return (i & 0xc0000000) == 0x80000000; }\n    enum IN_CLASSB_NET    = 0xffff0000;\n    enum IN_CLASSB_NSHIFT = 16;\n    enum IN_CLASSB_HOST   = 0xffffffff & ~IN_CLASSB_NET;\n    enum IN_CLASSB_MAX    = 65536;\n\n    extern(D) bool IN_CLASSC(in_addr_t i) pure @safe { return (i & 0xe0000000) == 0xc0000000; }\n    enum IN_CLASSC_NET    = 0xffffff00;\n    enum IN_CLASSC_NSHIFT = 8;\n    enum IN_CLASSC_HOST   = 0xffffffff & ~IN_CLASSC_NET;\n\n    extern(D) bool IN_CLASSD(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xe0000000; }\n    extern(D) bool IN_MULTICAST(in_addr_t i) { return IN_CLASSD(i); }\n\n    extern(D) bool IN_EXPERIMENTAL(in_addr_t i) pure @safe { return (i & 0xe0000000) == 0xe0000000; }\n    extern(D) bool IN_BADCLASS(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xf0000000; }\n\n    enum IN_LOOPBACKNET = 127;\n\n    enum INADDR_UNSPEC_GROUP    = 0xe0000000;\n    enum INADDR_ALLHOSTS_GROUP  = 0xe0000001;\n    enum INADDR_ALLRTRS_GROUP   = 0xe0000002;\n    enum INADDR_MAX_LOCAL_GROUP = 0xe00000ff;\n\n    enum IN6ADDR_ANY_INIT      = in6_addr.init;\n    enum IN6ADDR_LOOPBACK_INIT = in6_addr([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);\n\n    version (gnu_libc) static if (__USE_MISC)\n    {\n        struct ip_mreq\n        {\n            in_addr imr_multiaddr;\n            in_addr imr_interface;\n        };\n\n        struct ip_mreq_source\n        {\n            in_addr imr_multiaddr;\n            in_addr imr_interface;\n            in_addr imr_sourceaddr;\n        };\n\n        struct group_req\n        {\n            uint gr_interface;\n            sockaddr_storage gr_group;\n        };\n\n        struct group_source_req\n        {\n            uint gsr_interface;\n            sockaddr_storage gsr_group;\n            sockaddr_storage gsr_source;\n        };\n\n        struct ip_msfilter\n        {\n            in_addr imsf_multiaddr;\n            in_addr imsf_interface;\n            uint imsf_fmode;\n            uint imsf_numsrc;\n            in_addr[1] imsf_slist;\n        };\n\n        extern(D) size_t IP_MSFILTER_SIZE(int numsrc)\n        {\n            return ip_msfilter.sizeof - in_addr.sizeof + numsrc * in_addr.sizeof;\n        }\n\n        struct group_filter\n        {\n            uint gf_interface;\n            sockaddr_storage gf_group;\n            uint gf_fmode;\n            uint gf_numsrc;\n            sockaddr_storage[1] gf_slist;\n        };\n\n        extern(D) size_t GROUP_FILTER_SIZE(int numsrc) pure @safe\n        {\n            return group_filter.sizeof - sockaddr_storage.sizeof + numsrc * sockaddr_storage.sizeof;\n        }\n    }\n\n    extern(D) bool IN6_ARE_ADDR_EQUAL(in6_addr* a, in6_addr* b) pure @safe { return *a == *b; }\n\n    version (gnu_libc) static if (__USE_MISC)\n    {\n        int bindresvport(int __sockfd, sockaddr_in* __sock_in);\n        int bindresvport6(int __sockfd, sockaddr_in6* _);\n    }\n\n    version (gnu_libc) static if (__USE_GNU)\n    {\n        struct in6_pktinfo\n        {\n            in6_addr ipi6_addr;\n            uint ipi6_ifindex;\n        };\n\n        struct ip6_mtuinfo\n        {\n            sockaddr_in6 ip6m_addr;\n            uint ip6m_mtu;\n        };\n\n        int inet6_opt_init(void* __extbuf, socklen_t __extlen);\n        int inet6_opt_append(void* __extbuf, socklen_t __extlen, int __offset,\n                             ubyte __type, socklen_t __len, ubyte __align, void** __databufp);\n        int inet6_opt_finish(void* __extbuf, socklen_t __extlen, int __offset);\n        int inet6_opt_set_val(void* __databuf, int __offset, void* __val, socklen_t __vallen);\n        int inet6_opt_next(void* __extbuf, socklen_t __extlen, int __offset,\n                           ubyte* __typep, socklen_t* __lenp, void** __databufp);\n        int inet6_opt_find(void* __extbuf, socklen_t __extlen, int __offset,\n                           ubyte __type, socklen_t* __lenp, void** __databufp);\n        int inet6_opt_get_val(void* __databuf, int __offset, void* __val, socklen_t __vallen);\n\n        socklen_t inet6_rth_space(int __type, int __segments);\n        void* inet6_rth_init(void* __bp, socklen_t __bp_len, int __type, int __segments);\n        int inet6_rth_add(void* __bp, const in6_addr* __addr);\n        int inet6_rth_reverse(const void* __in, void* __out);\n        int inet6_rth_segments(const void* __bp);\n        in6_addr* inet6_rth_getaddr(const void* __bp, int __index);\n\n        int getipv4sourcefilter(int __s, in_addr __interface_addr, in_addr __group,\n                                uint* __fmode, uint* __numsrc, in_addr* __slist);\n\n        int setipv4sourcefilter(int __s, in_addr __interface_addr, in_addr __group,\n                                uint __fmode, uint __numsrc, const in_addr* __slist);\n\n\n        int getsourcefilter(int __s, uint __interface_addr, const sockaddr* __group,\n                            socklen_t __grouplen, uint* __fmode, uint* __numsrc,\n                            sockaddr_storage* __slist);\n\n        int setsourcefilter(int __s, uint __interface_addr, const sockaddr* __group,\n                            socklen_t __grouplen, uint __fmode, uint __numsrc,\n                            const sockaddr_storage* __slist);\n    }\n\n    // =============================================================================\n    // What follows is from bits/in.h, but since bits/in.h specifically says that it\n    // should only be #included by #including netinet/in.h, it makes more sense to\n    // put them in here so that the way they're imported corresponds with the\n    // correct way of #including them in C/C++.\n    // =============================================================================\n\n    enum IP_OPTIONS  = 4;\n    enum IP_HDRINCL  = 3;\n    enum IP_TOS      = 1;\n    enum IP_TTL      = 2;\n    enum IP_RECVOPTS = 6;\n\n    enum IP_RECVRETOPTS            = IP_RETOPTS;\n    enum IP_RETOPTS                = 7;\n    enum IP_MULTICAST_IF           = 32;\n    enum IP_MULTICAST_TTL          = 33;\n    enum IP_MULTICAST_LOOP         = 34;\n    enum IP_ADD_MEMBERSHIP         = 35;\n    enum IP_DROP_MEMBERSHIP        = 36;\n    enum IP_UNBLOCK_SOURCE         = 37;\n    enum IP_BLOCK_SOURCE           = 38;\n    enum IP_ADD_SOURCE_MEMBERSHIP  = 39;\n    enum IP_DROP_SOURCE_MEMBERSHIP = 40;\n    enum IP_MSFILTER               = 41;\n\n    version (gnu_libc) static if (__USE_MISC)\n    {\n        enum MCAST_JOIN_GROUP         = 42;\n        enum MCAST_BLOCK_SOURCE       = 43;\n        enum MCAST_UNBLOCK_SOURCE     = 44;\n        enum MCAST_LEAVE_GROUP        = 45;\n        enum MCAST_JOIN_SOURCE_GROUP  = 46;\n        enum MCAST_LEAVE_SOURCE_GROUP = 47;\n        enum MCAST_MSFILTER           = 48;\n        enum IP_MULTICAST_ALL         = 49;\n        enum IP_UNICAST_IF            = 50;\n\n        enum MCAST_EXCLUDE = 0;\n        enum MCAST_INCLUDE = 1;\n    }\n\n    enum IP_ROUTER_ALERT  = 5;\n    enum IP_PKTINFO       = 8;\n    enum IP_PKTOPTIONS    = 9;\n    enum IP_PMTUDISC      = 10;\n    enum IP_MTU_DISCOVER  = 10;\n    enum IP_RECVERR       = 11;\n    enum IP_RECVTTL       = 12;\n    enum IP_RECVTOS       = 13;\n    enum IP_MTU           = 14;\n    enum IP_FREEBIND      = 15;\n    enum IP_IPSEC_POLICY  = 16;\n    enum IP_XFRM_POLICY   = 17;\n    enum IP_PASSSEC       = 18;\n    enum IP_TRANSPARENT   = 19;\n    enum IP_MULTICAST_ALL = 49;\n\n    enum IP_ORIGDSTADDR     = 20;\n    enum IP_RECVORIGDSTADDR = IP_ORIGDSTADDR;\n\n    enum IP_MINTTL               = 21;\n    enum IP_NODEFRAG             = 22;\n    enum IP_CHECKSUM             = 23;\n    enum IP_BIND_ADDRESS_NO_PORT = 24;\n\n    enum IP_PMTUDISC_DONT      = 0;\n    enum IP_PMTUDISC_WANT      = 1;\n    enum IP_PMTUDISC_DO        = 2;\n    enum IP_PMTUDISC_PROBE     = 3;\n    enum IP_PMTUDISC_INTERFACE = 4;\n    enum IP_PMTUDISC_OMIT      = 5;\n\n    enum SOL_IP = 0;\n\n    enum IP_DEFAULT_MULTICAST_TTL  = 1;\n    enum IP_DEFAULT_MULTICAST_LOOP = 1;\n    enum IP_MAX_MEMBERSHIPS        = 20;\n\n    version (gnu_libc) static if (__USE_MISC)\n    {\n        struct ip_opts\n        {\n            in_addr ip_dst;\n            char[40] ip_opts;\n        };\n\n        struct ip_mreqn\n        {\n            in_addr imr_multiaddr;\n            in_addr imr_address;\n            int imr_ifindex;\n        };\n\n        struct in_pktinfo\n        {\n            int ipi_ifindex;\n            in_addr ipi_spec_dst;\n            in_addr ipi_addr;\n        };\n    }\n\n    enum IPV6_ADDRFORM       = 1;\n    enum IPV6_2292PKTINFO    = 2;\n    enum IPV6_2292HOPOPTS    = 3;\n    enum IPV6_2292DSTOPTS    = 4;\n    enum IPV6_2292RTHDR      = 5;\n    enum IPV6_2292PKTOPTIONS = 6;\n    enum IPV6_CHECKSUM       = 7;\n    enum IPV6_2292HOPLIMIT   = 8;\n\n    enum IPV6_NEXTHOP        = 9;\n    enum IPV6_AUTHHDR        = 10;\n    enum IPV6_UNICAST_HOPS   = 16;\n    enum IPV6_MULTICAST_IF   = 17;\n    enum IPV6_MULTICAST_HOPS = 18;\n    enum IPV6_MULTICAST_LOOP = 19;\n    enum IPV6_JOIN_GROUP     = 20;\n    enum IPV6_LEAVE_GROUP    = 21;\n    enum IPV6_ROUTER_ALERT   = 22;\n    enum IPV6_MTU_DISCOVER   = 23;\n    enum IPV6_MTU            = 24;\n    enum IPV6_RECVERR        = 25;\n    enum IPV6_V6ONLY         = 26;\n    enum IPV6_JOIN_ANYCAST   = 27;\n    enum IPV6_LEAVE_ANYCAST  = 28;\n    enum IPV6_IPSEC_POLICY   = 34;\n    enum IPV6_XFRM_POLICY    = 35;\n    enum IPV6_HDRINCL        = 36;\n\n    enum IPV6_RECVPKTINFO  = 49;\n    enum IPV6_PKTINFO      = 50;\n    enum IPV6_RECVHOPLIMIT = 51;\n    enum IPV6_HOPLIMIT     = 52;\n    enum IPV6_RECVHOPOPTS  = 53;\n    enum IPV6_HOPOPTS      = 54;\n    enum IPV6_RTHDRDSTOPTS = 55;\n    enum IPV6_RECVRTHDR    = 56;\n    enum IPV6_RTHDR        = 57;\n    enum IPV6_RECVDSTOPTS  = 58;\n    enum IPV6_DSTOPTS      = 59;\n    enum IPV6_RECVPATHMTU  = 60;\n    enum IPV6_PATHMTU      = 61;\n    enum IPV6_DONTFRAG     = 62;\n\n    enum IPV6_RECVTCLASS = 66;\n    enum IPV6_TCLASS     = 67;\n\n    enum IPV6_PMTUDISC_DONT      = 0;\n    enum IPV6_PMTUDISC_WANT      = 1;\n    enum IPV6_PMTUDISC_DO        = 2;\n    enum IPV6_PMTUDISC_PROBE     = 3;\n    enum IPV6_PMTUDISC_INTERFACE = 4;\n    enum IPV6_PMTUDISC_OMIT      = 5;\n\n    enum SOL_IPV6   = 41;\n    enum SOL_ICMPV6 = 58;\n\n    enum IPV6_RTHDR_LOOSE  = 0;\n    enum IPV6_RTHDR_STRICT = 1;\n\n    enum IPV6_RTHDR_TYPE_0 = 0;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/netinet/tcp.d",
    "content": "/*******************************************************************************\n\n    D bindings for the Linux's netinet/tcp.h structures.\n\n    Defines constants found in tcp.h header on Linux system.\n\n    Copyright:  Copyright (c) 2016 Sociomantic Labs. All rights reserved.\n    License:    $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:    Nemanja Boric\n\n*******************************************************************************/\n\nmodule core.sys.linux.netinet.tcp;\n\n/*\n* Copyright (c) 1982, 1986, 1993\n* The Regents of the University of California.  All rights reserved.\n*\n* Redistribution and use in source and binary forms, with or without\n* modification, are permitted provided that the following conditions\n* are met:\n* 1. Redistributions of source code must retain the above copyright\n*    notice, this list of conditions and the following disclaimer.\n* 2. Redistributions in binary form must reproduce the above copyright\n*    notice, this list of conditions and the following disclaimer in the\n*    documentation and/or other materials provided with the distribution.\n* 4. Neither the name of the University nor the names of its contributors\n*    may be used to endorse or promote products derived from this software\n*    without specific prior written permission.\n*\n* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n* ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n* SUCH DAMAGE.\n*\n* @(#)tcp.h 8.1 (Berkeley) 6/10/93\n*/\n\nversion (linux):\n\n/// User-settable options (used with setsockopt).\nenum\n{\n     TCP_NODELAY            = 1,  /// Don't delay send to coalesce packets\n     TCP_MAXSEG             = 2,  /// Set maximum segment size\n     TCP_CORK               = 3,  /// Control sending of partial frames\n     TCP_KEEPIDLE           = 4,  /// Start keeplives after this period\n     TCP_KEEPINTVL          = 5,  /// Interval between keepalives\n     TCP_KEEPCNT            = 6,  /// Number of keepalives before death\n     TCP_SYNCNT             = 7,  /// Number of SYN retransmits\n     TCP_LINGER2            = 8,  /// Life time of orphaned FIN-WAIT-2 state\n     TCP_DEFER_ACCEPT       = 9,  /// Wake up listener only when data arrive\n     TCP_WINDOW_CLAMP       = 10, /// Bound advertised window\n     TCP_INFO               = 11, /// Information about this connection.\n     TCP_QUICKACK           = 12, /// Bock/reenable quick ACKs.\n     TCP_CONGESTION         = 13, /// Congestion control algorithm.\n     TCP_MD5SIG             = 14, /// TCP MD5 Signature (RFC2385)\n     TCP_COOKIE_TRANSACTIONS     = 15, /// TCP Cookie Transactions\n     TCP_THIN_LINEAR_TIMEOUTS    = 16, /// Use linear timeouts for thin streams\n     TCP_THIN_DUPACK             = 17, /// Fast retrans. after 1 dupack\n     TCP_USER_TIMEOUT       = 18, /// How long for loss retry before timeout\n     TCP_REPAIR             = 19, /// TCP sock is under repair right now\n     TCP_REPAIR_QUEUE       = 20, /// Set TCP queue to repair\n     TCP_QUEUE_SEQ          = 21, /// Set sequence number of repaired queue.\n     TCP_REPAIR_OPTIONS     = 22, /// Repair TCP connection options\n     TCP_FASTOPEN           = 23, /// Enable FastOpen on listeners\n     TCP_TIMESTAMP          = 24, /// TCP time stamp\n     TCP_NOTSENT_LOWAT      = 25, /// Limit number of unsent bytes in  write queue.\n     TCP_CC_INFO            = 26, /// Get Congestion Control (optional) info.\n     TCP_SAVE_SYN           = 27, /// Record SYN headers for new connections.\n     TCP_SAVED_SYN          = 28, /// Get SYN headers recorded for connection.\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sched.d",
    "content": "/*******************************************************************************\n\n    D binding for Linux specific scheduler control methods.\n\n    Defines functions sched_setaffinity and sched_getaffinity  and the data\n    types they operate on.\n\n    Copyright:  Copyright (c) 2016 Sociomantic Labs. All rights reserved.\n    License:    $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:    Nemanja Boric\n\n*******************************************************************************/\n\n\nmodule core.sys.linux.sched;\n\nimport core.sys.posix.sched;\nimport core.sys.posix.config;\nimport core.sys.posix.sys.types;\n\nversion (linux):\nextern (C):\n@nogc:\nnothrow:\n\n\nprivate // helpers\n{\n\n    /* Size definition for CPU sets.  */\n    enum\n    {\n        __CPU_SETSIZE = 1024,\n        __NCPUBITS  = 8 * cpu_mask.sizeof,\n    }\n\n    /* Macros */\n\n    /* Basic access functions.  */\n    size_t __CPUELT(size_t cpu) pure\n    {\n        return cpu / __NCPUBITS;\n    }\n    cpu_mask __CPUMASK(size_t cpu) pure\n    {\n        return 1UL << (cpu % __NCPUBITS);\n    }\n\n    cpu_mask __CPU_SET_S(size_t cpu, size_t setsize, cpu_set_t* cpusetp) pure\n    {\n        if (cpu < 8 * setsize)\n        {\n            cpusetp.__bits[__CPUELT(cpu)] |= __CPUMASK(cpu);\n            return __CPUMASK(cpu);\n        }\n\n        return 0;\n    }\n}\n\n/// Type for array elements in 'cpu_set_t'.\nalias c_ulong cpu_mask;\n\n/// Data structure to describe CPU mask.\nstruct cpu_set_t\n{\n    cpu_mask[__CPU_SETSIZE / __NCPUBITS] __bits;\n}\n\n/// Access macros for 'cpu_set' (missing a lot of them)\n\ncpu_mask CPU_SET(size_t cpu, cpu_set_t* cpusetp) pure\n{\n     return __CPU_SET_S(cpu, cpu_set_t.sizeof, cpusetp);\n}\n\n/* Functions */\nint sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);\nint sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/stdio.d",
    "content": "/**\n  * D header file for GNU stdio.\n  *\n  * Copyright: Danny Milosavljevic 2014\n  * License: <a href=\"http://www.boost.org/LICENSE_1_0.txt\">Boost License 1.0</a>.\n  * Authors: Danny Milosavljevic\n  */\nmodule core.sys.linux.stdio;\nversion (CRuntime_Glibc):\npublic import core.sys.posix.stdio;\nimport core.sys.posix.sys.types : ssize_t, off64_t = off_t;\nimport core.sys.linux.config : __USE_FILE_OFFSET64;\nimport core.stdc.stdio : FILE;\nimport core.stdc.stddef : wchar_t;\n\nextern(C) nothrow\n{\n    alias ssize_t function(void *cookie, char *buf, size_t size) cookie_read_function_t;\n    alias ssize_t function(void *cookie, const(char) *buf, size_t size) cookie_write_function_t;\n    alias int function(void *cookie, off64_t *offset, int whence) cookie_seek_function_t;\n    alias int function(void *cookie) cookie_close_function_t;\n\n    struct cookie_io_functions_t\n    {\n        cookie_read_function_t read;\n        cookie_write_function_t write;\n        cookie_seek_function_t seek;\n        cookie_close_function_t close;\n    }\n    FILE* fopencookie(in void* cookie, in char* mode, cookie_io_functions_t io_funcs);\n    void setbuffer(FILE *stream, char *buf, size_t size); // note: _DEFAULT_SOURCE\n}\n\nunittest\n{\n    static int flag = 0;\n    static int written = 0;\n    static int closed = 0;\n    // Note: this test needs to run on both a 32 and a 64 bit machine, both have to pass.\n    import core.stdc.errno : errno, EBADF;\n    //import core.sys.posix.sys.stat : off64_t;\n    import core.stdc.stdio : FILE, fflush, fileno, fprintf, fgetc, EOF, fclose;\n    import core.stdc.string : memcpy, memset;\n    extern (C) ssize_t specialRead(void *cookie, char *buf, size_t size) nothrow\n    {\n        memset(buf, 'a', size);\n        return size;\n    }\n    extern (C) int specialClose(void* cookie) nothrow\n    {\n        ++closed;\n        return 0;\n    }\n    extern (C) ssize_t specialWrite(void *cookie, const(char) *buf, size_t size) nothrow\n    {\n        int* c = cast(int*) cookie;\n        flag = *c;\n        written += size;\n        return size;\n    }\n    int dummy = 42;\n    cookie_io_functions_t fns =\n    {\n        read: &specialRead,\n        write: &specialWrite,\n        close: &specialClose,\n    };\n    FILE* f = fopencookie(&dummy, \"r+\", fns);\n    assert(f !is null);\n    //File.open();\n    //auto g = File(f);\n    assert(fileno(f) == -1 && errno == EBADF);\n    assert(fprintf(f, \"hello\") == \"hello\".length);\n    //assert(errno == EBADF);\n    assert(fflush(f) == 0);\n    assert(written == \"hello\".length);\n    // Note: do not swap reading and writing here.\n    int c = 0;\n    while ((c = fgetc(f)) != EOF)\n    {\n        assert(c == 'a');\n        break; // endless otherwise\n    }\n    assert(c == 'a');\n    assert(fclose(f) == 0);\n    assert(closed == 1);\n    assert(flag == dummy);\n    //stdin.getFP();\n    //assert(stdin.fileno() == 0);\n}\n\nunittest\n{ /* setbuffer */\n    char buf;\n    int c;\n    byte[10] dummy = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    FILE* f = fmemopen(dummy.ptr, 10, \"r\");\n    assert(f !is null);\n    setbuffer(f, &buf, 1);\n    assert(fgetc(f) == 1);\n    assert(fgetc(f) == 2);\n    assert(fgetc(f) == 3);\n    assert(fgetc(f) == 4);\n    assert(fclose(f) == 0);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/auxv.d",
    "content": "/**\n * D header file for GNU/Linux.\n *\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Kai Nacke\n */\nmodule core.sys.linux.sys.auxv;\n\nimport core.stdc.config;\n\nversion (linux):\nextern (C):\n\nc_ulong getauxval(c_ulong type) nothrow pure @nogc @system;\n\nversion (ARM)\n{\n  // See https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/arm/bits/hwcap.h\n\n  enum HWCAP_ARM_SWP                      = 1;\n  enum HWCAP_ARM_HALF                     = 2;\n  enum HWCAP_ARM_THUMB                    = 4;\n  enum HWCAP_ARM_26BIT                    = 8;\n  enum HWCAP_ARM_FAST_MULT                = 16;\n  enum HWCAP_ARM_FPA                      = 32;\n  enum HWCAP_ARM_VFP                      = 64;\n  enum HWCAP_ARM_EDSP                     = 128;\n  enum HWCAP_ARM_JAVA                     = 256;\n  enum HWCAP_ARM_IWMMXT                   = 512;\n  enum HWCAP_ARM_CRUNCH                   = 1024;\n  enum HWCAP_ARM_THUMBEE                  = 2048;\n  enum HWCAP_ARM_NEON                     = 4096;\n  enum HWCAP_ARM_VFPv3                    = 8192;\n  enum HWCAP_ARM_VFPv3D16                 = 16384;\n  enum HWCAP_ARM_TLS                      = 32768;\n  enum HWCAP_ARM_VFPv4                    = 65536;\n  enum HWCAP_ARM_IDIVA                    = 131072;\n  enum HWCAP_ARM_IDIVT                    = 262144;\n  enum HWCAP_ARM_VFPD32                   = 524288;\n  enum HWCAP_ARM_LPAE                     = 1048576;\n  enum HWCAP_ARM_EVTSTRM                  = 2097152;\n}\nelse version (AArch64)\n{\n  // See https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h\n\n  enum HWCAP_FP                           = 1;\n  enum HWCAP_ASIMD                        = 2;\n  enum HWCAP_EVTSTRM                      = 4;\n  enum HWCAP_AES                          = 8;\n  enum HWCAP_PMULL                        = 16;\n  enum HWCAP_SHA1                         = 32;\n  enum HWCAP_SHA2                         = 64;\n  enum HWCAP_CRC32                        = 128;\n  enum HWCAP_ATOMICS                      = 256;\n  enum HWCAP_FPHP                         = 512;\n  enum HWCAP_ASIMDHP                      = 1024;\n}\nelse version (PPC)\n{\n  // See https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/bits/hwcap.h\n\n  enum PPC_FEATURE_32                     = 0x80000000;\n  enum PPC_FEATURE_64                     = 0x40000000;\n  enum PPC_FEATURE_601_INSTR              = 0x20000000;\n  enum PPC_FEATURE_HAS_ALTIVEC            = 0x10000000;\n  enum PPC_FEATURE_HAS_FPU                = 0x08000000;\n  enum PPC_FEATURE_HAS_MMU                = 0x04000000;\n  enum PPC_FEATURE_HAS_4xxMAC             = 0x02000000;\n  enum PPC_FEATURE_UNIFIED_CACHE          = 0x01000000;\n  enum PPC_FEATURE_HAS_SPE                = 0x00800000;\n  enum PPC_FEATURE_HAS_EFP_SINGLE         = 0x00400000;\n  enum PPC_FEATURE_HAS_EFP_DOUBLE         = 0x00200000;\n  enum PPC_FEATURE_NO_TB                  = 0x00100000;\n  enum PPC_FEATURE_POWER4                 = 0x00080000;\n  enum PPC_FEATURE_POWER5                 = 0x00040000;\n  enum PPC_FEATURE_POWER5_PLUS            = 0x00020000;\n  enum PPC_FEATURE_CELL_BE                = 0x00010000;\n  enum PPC_FEATURE_BOOKE                  = 0x00008000;\n  enum PPC_FEATURE_SMT                    = 0x00004000;\n\n  enum PPC_FEATURE_ICACHE_SNOOP           = 0x00002000;\n  enum PPC_FEATURE_ARCH_2_05              = 0x00001000;\n  enum PPC_FEATURE_PA6T                   = 0x00000800;\n  enum PPC_FEATURE_HAS_DFP                = 0x00000400;\n  enum PPC_FEATURE_POWER6_EXT             = 0x00000200;\n  enum PPC_FEATURE_ARCH_2_06              = 0x00000100;\n  enum PPC_FEATURE_HAS_VSX                = 0x00000080;\n  enum PPC_FEATURE_PSERIES_PERFMON_COMPAT = 0x00000040;\n  enum PPC_FEATURE_TRUE_LE                = 0x00000002;\n  enum PPC_FEATURE_PPC_LE                 = 0x00000001;\n\n  enum PPC_FEATURE2_ARCH_2_07             = 0x80000000;\n  enum PPC_FEATURE2_HAS_HTM               = 0x40000000;\n  enum PPC_FEATURE2_HAS_DSCR              = 0x20000000;\n  enum PPC_FEATURE2_HAS_EBB               = 0x10000000;\n  enum PPC_FEATURE2_HAS_ISEL              = 0x08000000;\n  enum PPC_FEATURE2_HAS_TAR               = 0x04000000;\n  enum PPC_FEATURE2_HAS_VEC_CRYPTO        = 0x02000000;\n}\nelse version (PPC64)\n{\n  // See https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/bits/hwcap.h\n\n  enum PPC_FEATURE_32                     = 0x80000000;\n  enum PPC_FEATURE_64                     = 0x40000000;\n  enum PPC_FEATURE_601_INSTR              = 0x20000000;\n  enum PPC_FEATURE_HAS_ALTIVEC            = 0x10000000;\n  enum PPC_FEATURE_HAS_FPU                = 0x08000000;\n  enum PPC_FEATURE_HAS_MMU                = 0x04000000;\n  enum PPC_FEATURE_HAS_4xxMAC             = 0x02000000;\n  enum PPC_FEATURE_UNIFIED_CACHE          = 0x01000000;\n  enum PPC_FEATURE_HAS_SPE                = 0x00800000;\n  enum PPC_FEATURE_HAS_EFP_SINGLE         = 0x00400000;\n  enum PPC_FEATURE_HAS_EFP_DOUBLE         = 0x00200000;\n  enum PPC_FEATURE_NO_TB                  = 0x00100000;\n  enum PPC_FEATURE_POWER4                 = 0x00080000;\n  enum PPC_FEATURE_POWER5                 = 0x00040000;\n  enum PPC_FEATURE_POWER5_PLUS            = 0x00020000;\n  enum PPC_FEATURE_CELL_BE                = 0x00010000;\n  enum PPC_FEATURE_BOOKE                  = 0x00008000;\n  enum PPC_FEATURE_SMT                    = 0x00004000;\n\n  enum PPC_FEATURE_ICACHE_SNOOP           = 0x00002000;\n  enum PPC_FEATURE_ARCH_2_05              = 0x00001000;\n  enum PPC_FEATURE_PA6T                   = 0x00000800;\n  enum PPC_FEATURE_HAS_DFP                = 0x00000400;\n  enum PPC_FEATURE_POWER6_EXT             = 0x00000200;\n  enum PPC_FEATURE_ARCH_2_06              = 0x00000100;\n  enum PPC_FEATURE_HAS_VSX                = 0x00000080;\n  enum PPC_FEATURE_PSERIES_PERFMON_COMPAT = 0x00000040;\n  enum PPC_FEATURE_TRUE_LE                = 0x00000002;\n  enum PPC_FEATURE_PPC_LE                 = 0x00000001;\n\n  enum PPC_FEATURE2_ARCH_2_07             = 0x80000000;\n  enum PPC_FEATURE2_HAS_HTM               = 0x40000000;\n  enum PPC_FEATURE2_HAS_DSCR              = 0x20000000;\n  enum PPC_FEATURE2_HAS_EBB               = 0x10000000;\n  enum PPC_FEATURE2_HAS_ISEL              = 0x08000000;\n  enum PPC_FEATURE2_HAS_TAR               = 0x04000000;\n  enum PPC_FEATURE2_HAS_VEC_CRYPTO        = 0x02000000;\n}\nelse version (SPARC)\n{\n  // See https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/sparc/bits/hwcap.h\n\n  enum HWCAP_SPARC_FLUSH                  = 0x00000001;\n  enum HWCAP_SPARC_STBAR                  = 0x00000002;\n  enum HWCAP_SPARC_SWAP                   = 0x00000004;\n  enum HWCAP_SPARC_MULDIV                 = 0x00000008;\n  enum HWCAP_SPARC_V9                     = 0x00000010;\n  enum HWCAP_SPARC_ULTRA3                 = 0x00000020;\n  enum HWCAP_SPARC_BLKINIT                = 0x00000040;\n  enum HWCAP_SPARC_N2                     = 0x00000080;\n  enum HWCAP_SPARC_MUL32                  = 0x00000100;\n  enum HWCAP_SPARC_DIV32                  = 0x00000200;\n  enum HWCAP_SPARC_FSMULD                 = 0x00000400;\n  enum HWCAP_SPARC_V8PLUS                 = 0x00000800;\n  enum HWCAP_SPARC_POPC                   = 0x00001000;\n  enum HWCAP_SPARC_VIS                    = 0x00002000;\n  enum HWCAP_SPARC_VIS2                   = 0x00004000;\n  enum HWCAP_SPARC_ASI_BLK_INIT           = 0x00008000;\n  enum HWCAP_SPARC_FMAF                   = 0x00010000;\n  enum HWCAP_SPARC_VIS3                   = 0x00020000;\n  enum HWCAP_SPARC_HPC                    = 0x00040000;\n  enum HWCAP_SPARC_RANDOM                 = 0x00080000;\n  enum HWCAP_SPARC_TRANS                  = 0x00100000;\n  enum HWCAP_SPARC_FJFMAU                 = 0x00200000;\n  enum HWCAP_SPARC_IMA                    = 0x00400000;\n  enum HWCAP_SPARC_ASI_CACHE_SPARING      = 0x00800000;\n  enum HWCAP_SPARC_PAUSE                  = 0x01000000;\n  enum HWCAP_SPARC_CBCOND                 = 0x02000000;\n  enum HWCAP_SPARC_CRYPTO                 = 0x04000000;\n}\nelse version (SPARC64)\n{\n  // See https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/sparc/bits/hwcap.h\n\n  enum HWCAP_SPARC_FLUSH                  = 0x00000001;\n  enum HWCAP_SPARC_STBAR                  = 0x00000002;\n  enum HWCAP_SPARC_SWAP                   = 0x00000004;\n  enum HWCAP_SPARC_MULDIV                 = 0x00000008;\n  enum HWCAP_SPARC_V9                     = 0x00000010;\n  enum HWCAP_SPARC_ULTRA3                 = 0x00000020;\n  enum HWCAP_SPARC_BLKINIT                = 0x00000040;\n  enum HWCAP_SPARC_N2                     = 0x00000080;\n  enum HWCAP_SPARC_MUL32                  = 0x00000100;\n  enum HWCAP_SPARC_DIV32                  = 0x00000200;\n  enum HWCAP_SPARC_FSMULD                 = 0x00000400;\n  enum HWCAP_SPARC_V8PLUS                 = 0x00000800;\n  enum HWCAP_SPARC_POPC                   = 0x00001000;\n  enum HWCAP_SPARC_VIS                    = 0x00002000;\n  enum HWCAP_SPARC_VIS2                   = 0x00004000;\n  enum HWCAP_SPARC_ASI_BLK_INIT           = 0x00008000;\n  enum HWCAP_SPARC_FMAF                   = 0x00010000;\n  enum HWCAP_SPARC_VIS3                   = 0x00020000;\n  enum HWCAP_SPARC_HPC                    = 0x00040000;\n  enum HWCAP_SPARC_RANDOM                 = 0x00080000;\n  enum HWCAP_SPARC_TRANS                  = 0x00100000;\n  enum HWCAP_SPARC_FJFMAU                 = 0x00200000;\n  enum HWCAP_SPARC_IMA                    = 0x00400000;\n  enum HWCAP_SPARC_ASI_CACHE_SPARING      = 0x00800000;\n  enum HWCAP_SPARC_PAUSE                  = 0x01000000;\n  enum HWCAP_SPARC_CBCOND                 = 0x02000000;\n  enum HWCAP_SPARC_CRYPTO                 = 0x04000000;\n}\nelse version (SystemZ)\n{\n  // See https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/s390/bits/hwcap.h\n\n  enum HWCAP_S390_ESAN3                   = 1;\n  enum HWCAP_S390_ZARCH                   = 2;\n  enum HWCAP_S390_STFLE                   = 4;\n  enum HWCAP_S390_MSA                     = 8;\n  enum HWCAP_S390_LDISP                   = 16;\n  enum HWCAP_S390_EIMM                    = 32;\n  enum HWCAP_S390_DFP                     = 64;\n  enum HWCAP_S390_HPAGE                   = 128;\n  enum HWCAP_S390_ETF3EH                  = 256;\n  enum HWCAP_S390_HIGH_GPRS               = 512;\n  enum HWCAP_S390_TE                      = 1024;\n  enum HWCAP_S390_VX                      = 2048;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/eventfd.d",
    "content": "/**\n * D header file for GNU/Linux.\n *\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Nemanja Boric\n */\nmodule core.sys.linux.sys.eventfd;\n\nversion (linux):\nextern (C):\n@nogc:\n@system:\nnothrow:\n\nimport core.stdc.stdint: uint64_t;\n\n/// Type for the event counter\nalias uint64_t eventfd_t;\n\n/* Return file descriptor for generic event channel.  Set initial\n   value to count.  */\nint eventfd (uint count, int flags);\n\n/* Read event counter and possibly wait for events.  */\nint eventfd_read (int fd, eventfd_t* value);\n\n/* Increment event counter.  */\nint eventfd_write (int fd, eventfd_t value);\n\nversion (X86)\n{\n    enum EFD_SEMAPHORE = 1;\n    enum EFD_CLOEXEC = 0x80000; // octal!2000000\n    enum EFD_NONBLOCK = 0x800; // octal!4000\n}\nelse version (X86_64)\n{\n    enum EFD_SEMAPHORE = 1;\n    enum EFD_CLOEXEC = 0x80000; // octal!2000000\n    enum EFD_NONBLOCK = 0x800; // octal!4000\n}\nelse version (MIPS32)\n{\n    enum EFD_SEMAPHORE = 1;\n    enum EFD_CLOEXEC = 0x80000; // octal!2000000\n    enum EFD_NONBLOCK = 0x80; // octal!200\n}\nelse version (MIPS64)\n{\n    enum EFD_SEMAPHORE = 1;\n    enum EFD_CLOEXEC = 0x80000; // octal!2000000\n    enum EFD_NONBLOCK = 0x80; // octal!200\n}\nelse version (PPC)\n{\n    enum EFD_SEMAPHORE = 1;\n    enum EFD_CLOEXEC = 0x80000; // octal!2000000\n    enum EFD_NONBLOCK = 0x800; // octal!4000\n}\nelse version (PPC64)\n{\n    enum EFD_SEMAPHORE = 1;\n    enum EFD_CLOEXEC = 0x80000; // octal!2000000\n    enum EFD_NONBLOCK = 0x800; // octal!4000\n}\nelse version (ARM)\n{\n    enum EFD_SEMAPHORE = 1;\n    enum EFD_CLOEXEC = 0x80000; // octal!2000000\n    enum EFD_NONBLOCK = 0x800; // octal!4000\n}\nelse version (AArch64)\n{\n    enum EFD_SEMAPHORE = 1;\n    enum EFD_CLOEXEC = 0x80000; // octal!2000000\n    enum EFD_NONBLOCK = 0x800; // octal!4000\n}\nelse version (SPARC64)\n{\n    enum EFD_SEMAPHORE = 1;\n    enum EFD_CLOEXEC = 0x80000; // octal!2000000\n    enum EFD_NONBLOCK = 0x800; // octal!4000\n}\nelse version (SystemZ)\n{\n    enum EFD_SEMAPHORE = 1;\n    enum EFD_CLOEXEC = 0x80000; // octal!2000000\n    enum EFD_NONBLOCK = 0x800; // octal!4000\n}\nelse\n    static assert(0, \"unimplemented\");\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/file.d",
    "content": "/**\n * D header file for Linux file ops.\n *\n * Copyright: Copyright Nemanja Boric 2016.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Nemanja Boric\n */\nmodule core.sys.linux.sys.file;\n\nversion (linux):\nextern (C):\nnothrow:\n@nogc:\n\n/* Operations for the `flock' call. */\n/// Shared lock\nenum LOCK_SH              = 0x01;\n/// Exclusive lock\nenum LOCK_EX              = 0x02;\n/// Unlock\nenum LOCK_UN              = 0x08;\n\n/// Don't block when locking.\n/// Can be OR'd into one of the above.\nenum LOCK_NB              = 0x04;\n\n/// Apply or remove an advisory lock on an open file\n/// Params:\n///     fd = file to apply or remove lock from\n///     operation = lock operation to perform\n/// Returns:\n///     0 on success, -1 on failure, with .errno\n///     set appropriately.\nint     flock(int fd, int operation) @trusted;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/inotify.d",
    "content": "/**\n * D header file for GNU/Linux.\n *\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Gary Willoughby\n */\nmodule core.sys.linux.sys.inotify;\n\nversion (linux):\nextern (C):\n@system:\nnothrow:\n\nstruct inotify_event\n{\n    int wd;\n    uint mask;\n    uint cookie;\n    uint len;\n    char[0] name;\n\n    @disable this(this);\n}\n\nenum: uint\n{\n    IN_ACCESS        = 0x00000000,\n    IN_MODIFY        = 0x00000002,\n    IN_ATTRIB        = 0x00000004,\n    IN_CLOSE_WRITE   = 0x00000008,\n    IN_CLOSE_NOWRITE = 0x00000010,\n    IN_OPEN          = 0x00000020,\n    IN_MOVED_FROM    = 0x00000040,\n    IN_MOVED_TO      = 0x00000080,\n    IN_CREATE        = 0x00000100,\n    IN_DELETE        = 0x00000200,\n    IN_DELETE_SELF   = 0x00000400,\n    IN_MOVE_SELF     = 0x00000800,\n    IN_UNMOUNT       = 0x00002000,\n    IN_Q_OVERFLOW    = 0x00004000,\n    IN_IGNORED       = 0x00008000,\n    IN_CLOSE         = 0x00000018,\n    IN_MOVE          = 0x000000C0,\n    IN_ONLYDIR       = 0x01000000,\n    IN_DONT_FOLLOW   = 0x02000000,\n    IN_EXCL_UNLINK   = 0x04000000,\n    IN_MASK_ADD      = 0x20000000,\n    IN_ISDIR         = 0x40000000,\n    IN_ONESHOT       = 0x80000000,\n    IN_ALL_EVENTS    = 0x80000FFF,\n}\n\n// Old typo, preserved for compatibility\nenum IN_UMOUNT = IN_UNMOUNT;\n\nversion (X86)\n{\n    enum IN_CLOEXEC = 0x80000; // octal!2000000\n    enum IN_NONBLOCK = 0x800; // octal!4000\n}\nelse version (X86_64)\n{\n    enum IN_CLOEXEC = 0x80000; // octal!2000000\n    enum IN_NONBLOCK = 0x800; // octal!4000\n}\nelse version (MIPS32)\n{\n    enum IN_CLOEXEC = 0x80000; // octal!2000000\n    enum IN_NONBLOCK = 0x80; // octal!200\n}\nelse version (MIPS64)\n{\n    enum IN_CLOEXEC = 0x80000; // octal!2000000\n    enum IN_NONBLOCK = 0x80; // octal!200\n}\nelse version (PPC)\n{\n    enum IN_CLOEXEC = 0x80000; // octal!2000000\n    enum IN_NONBLOCK = 0x800; // octal!4000\n}\nelse version (PPC64)\n{\n    enum IN_CLOEXEC = 0x80000; // octal!2000000\n    enum IN_NONBLOCK = 0x800; // octal!4000\n}\nelse version (ARM)\n{\n    enum IN_CLOEXEC = 0x80000; // octal!2000000\n    enum IN_NONBLOCK = 0x800; // octal!4000\n}\nelse version (AArch64)\n{\n    enum IN_CLOEXEC = 0x80000; // octal!2000000\n    enum IN_NONBLOCK = 0x800; // octal!4000\n}\nelse version (SPARC64)\n{\n    enum IN_CLOEXEC = 0x80000; // octal!2000000\n    enum IN_NONBLOCK = 0x800; // octal!4000\n}\nelse version (SystemZ)\n{\n    enum IN_CLOEXEC = 0x80000; // octal!2000000\n    enum IN_NONBLOCK = 0x800; // octal!4000\n}\nelse\n    static assert(0, \"unimplemented\");\n\nint inotify_init();\nint inotify_init1(int flags);\nint inotify_add_watch(int fd, const(char)* name, uint mask);\nint inotify_rm_watch(int fd, uint wd);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/mman.d",
    "content": "/**\n * D header file for GNU/Linux\n *\n * Authors: Martin Nowak\n */\nmodule core.sys.linux.sys.mman;\n\nversion (linux):\nextern (C):\nnothrow:\n\npublic import core.sys.posix.sys.mman;\nimport core.sys.linux.config;\n\n// <bits/mman.h>\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/powerpc/bits/mman.h\nversion (PPC)\n{\n    enum PROT_SAO = 0x10;\n\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x00100,\n        MAP_DENYWRITE = 0x00800,\n        MAP_EXECUTABLE = 0x01000,\n        MAP_LOCKED = 0x00080,\n        MAP_NORESERVE = 0x00040,\n        MAP_POPULATE = 0x08000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //     MCL_CURRENT = 0x2000,\n    //     MCL_FUTURE = 0x4000,\n    // }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/powerpc/bits/mman.h\nelse version (PPC64)\n{\n    enum PROT_SAO = 0x10;\n\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x00100,\n        MAP_DENYWRITE = 0x00800,\n        MAP_EXECUTABLE = 0x01000,\n        MAP_LOCKED = 0x00080,\n        MAP_NORESERVE = 0x00040,\n        MAP_POPULATE = 0x08000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //     MCL_CURRENT = 0x2000,\n    //     MCL_FUTURE = 0x4000,\n    // }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/s390/bits/mman.h\nelse version (S390)\n{\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x00100,\n        MAP_DENYWRITE = 0x00800,\n        MAP_EXECUTABLE = 0x01000,\n        MAP_LOCKED = 0x02000,\n        MAP_NORESERVE = 0x04000,\n        MAP_POPULATE = 0x08000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/s390/bits/mman.h\nelse version (SystemZ)\n{\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x00100,\n        MAP_DENYWRITE = 0x00800,\n        MAP_EXECUTABLE = 0x01000,\n        MAP_LOCKED = 0x02000,\n        MAP_NORESERVE = 0x04000,\n        MAP_POPULATE = 0x08000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/sh/bits/mman.h\nelse version (SH)\n{\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x0100,\n        MAP_DENYWRITE = 0x0800,\n        MAP_EXECUTABLE = 0x1000,\n        MAP_LOCKED = 0x2000,\n        MAP_NORESERVE = 0x4000,\n        MAP_POPULATE = 0x8000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/sparc/bits/mman.h\nelse version (SPARC)\n{\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x0200,\n        MAP_DENYWRITE = 0x0800,\n        MAP_EXECUTABLE = 0x1000,\n        MAP_LOCKED = 0x0100,\n        MAP_NORESERVE = 0x0040,\n        _MAP_NEW = 0x80000000,\n        MAP_POPULATE = 0x8000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //     MCL_CURRENT = 0x2000,\n    //     MCL_FUTURE = 0x4000,\n    // }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/sparc/bits/mman.h\nelse version (SPARC64)\n{\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x0200,\n        MAP_DENYWRITE = 0x0800,\n        MAP_EXECUTABLE = 0x1000,\n        MAP_LOCKED = 0x0100,\n        MAP_NORESERVE = 0x0040,\n        _MAP_NEW = 0x80000000,\n        MAP_POPULATE = 0x8000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //     MCL_CURRENT = 0x2000,\n    //     MCL_FUTURE = 0x4000,\n    // }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/x86/bits/mman.h\nelse version (X86)\n{\n    static if (__USE_MISC) enum MAP_32BIT = 0x40;\n\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x00100,\n        MAP_DENYWRITE = 0x00800,\n        MAP_EXECUTABLE = 0x01000,\n        MAP_LOCKED = 0x02000,\n        MAP_NORESERVE = 0x04000,\n        MAP_POPULATE = 0x08000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/x86/bits/mman.h\nelse version (X86_64)\n{\n    static if (__USE_MISC) enum MAP_32BIT = 0x40;\n\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x00100,\n        MAP_DENYWRITE = 0x00800,\n        MAP_EXECUTABLE = 0x01000,\n        MAP_LOCKED = 0x02000,\n        MAP_NORESERVE = 0x04000,\n        MAP_POPULATE = 0x08000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/aarch64/bits/mman.h\nelse version (AArch64)\n{\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x00100,\n        MAP_DENYWRITE = 0x00800,\n        MAP_EXECUTABLE = 0x01000,\n        MAP_LOCKED = 0x02000,\n        MAP_NORESERVE = 0x04000,\n        MAP_POPULATE = 0x08000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/alpha/bits/mman.h\nelse version (Alpha)\n{\n    enum\n    {\n        PROT_READ = 0x1,\n        PROT_WRITE = 0x2,\n        PROT_EXEC = 0x4,\n        PROT_NONE = 0x0,\n        PROT_GROWSDOWN = 0x01000000,\n        PROT_GROWSUP = 0x02000000,\n    }\n\n    enum MAP_SHARED = 0x01;\n    enum MAP_PRIVATE = 0x02;\n    static if (__USE_MISC)\n        enum MAP_TYPE = 0x0f;\n\n    enum MAP_FIXED = 0x10;\n    static if (__USE_MISC) enum\n    {\n        MAP_FILE = 0,\n        MAP_ANONYMOUS = MAP_ANON,\n        // in core.sys.posix.sys.mman\n        // MAP_ANON = MAP_ANONYMOUS,\n        MAP_HUGE_SHIFT = 26,\n        MAP_HUGE_MASK = 0x3f,\n    }\n\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x01000,\n        MAP_DENYWRITE = 0x02000,\n        MAP_EXECUTABLE = 0x04000,\n        MAP_LOCKED = 0x08000,\n        MAP_NORESERVE = 0x10000,\n        MAP_POPULATE = 0x20000,\n        MAP_NONBLOCK = 0x40000,\n        MAP_STACK = 0x80000,\n        MAP_HUGETLB = 0x100000,\n    }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //     MS_ASYNC = 1,\n    //     MS_SYNC = 2,\n    //     MS_INVALIDATE = 4,\n    // }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //     MCL_CURRENT = 8192,\n    //     MCL_FUTURE = 16384,\n    // }\n\n    static if (__USE_GNU) enum\n    {\n        MREMAP_MAYMOVE = 1,\n        MREMAP_FIXED = 2,\n    }\n\n    static if (__USE_MISC) enum\n    {\n        MADV_NORMAL = 0,\n        MADV_RANDOM = 1,\n        MADV_SEQUENTIAL = 2,\n        MADV_WILLNEED = 3,\n        MADV_DONTNEED = 6,\n        MADV_REMOVE = 9,\n        MADV_DONTFORK = 10,\n        MADV_DOFORK = 11,\n        MADV_MERGEABLE = 12,\n        MADV_UNMERGEABLE = 13,\n        MADV_HUGEPAGE = 14,\n        MADV_NOHUGEPAGE = 15,\n        MADV_DONTDUMP = 16,\n        MADV_DODUMP = 17,\n        MADV_HWPOISON = 100,\n    }\n\n    // in core.sys.posix.sys.mman\n    // static if (__USE_XOPEN2K) enum\n    // {\n    //         POSIX_MADV_NORMAL = 0,\n    //         POSIX_MADV_RANDOM = 1,\n    //         POSIX_MADV_SEQUENTIAL = 2,\n    //         POSIX_MADV_WILLNEED = 3,\n    //         POSIX_MADV_DONTNEED = 6,\n    // }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/arm/bits/mman.h\nelse version (ARM)\n{\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x00100,\n        MAP_DENYWRITE = 0x00800,\n        MAP_EXECUTABLE = 0x01000,\n        MAP_LOCKED = 0x02000,\n        MAP_NORESERVE = 0x04000,\n        MAP_POPULATE = 0x08000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/hppa/bits/mman.h\nelse version (HPPA)\n{\n    enum\n    {\n        PROT_READ = 0x1,\n        PROT_WRITE = 0x2,\n        PROT_EXEC = 0x4,\n        PROT_NONE = 0x0,\n        PROT_GROWSDOWN = 0x01000000,\n        PROT_GROWSUP = 0x02000000,\n    }\n\n    enum MAP_SHARED = 0x01;\n    enum MAP_PRIVATE = 0x02;\n    static if (__USE_MISC)\n        enum MAP_TYPE = 0x0f;\n\n    enum MAP_FIXED = 0x04;\n    static if (__USE_MISC) enum\n    {\n        MAP_FILE = 0,\n        MAP_ANONYMOUS = MAP_ANON,\n        // in core.sys.posix.sys.mman\n        // MAP_ANON = MAP_ANONYMOUS,\n        MAP_VARIABLE = 0,\n        MAP_HUGE_SHIFT = 26,\n        MAP_HUGE_MASK = 0x3f,\n    }\n\n    static if (__USE_MISC) enum\n    {\n        MAP_DENYWRITE = 0x0800,\n        MAP_EXECUTABLE = 0x1000,\n        MAP_LOCKED = 0x2000,\n        MAP_NORESERVE = 0x4000,\n        MAP_GROWSDOWN = 0x8000,\n        MAP_POPULATE = 0x10000,\n        MAP_NONBLOCK = 0x20000,\n    }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //     MS_ASYNC = 1,\n    //     MS_SYNC = 2,\n    //     MS_INVALIDATE = 4,\n    // }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //     MCL_CURRENT = 1,\n    //     MCL_FUTURE = 2,\n    // }\n\n    static if (__USE_GNU) enum\n    {\n        MREMAP_MAYMOVE = 1,\n        MREMAP_FIXED = 2,\n    }\n\n    static if (__USE_MISC) enum\n    {\n        MADV_NORMAL = 0,\n        MADV_RANDOM = 1,\n        MADV_SEQUENTIAL = 2,\n        MADV_WILLNEED = 3,\n        MADV_DONTNEED = 4,\n        MADV_SPACEAVAIL = 5,\n        MADV_VPS_PURGE = 6,\n        MADV_VPS_INHERIT = 7,\n        MADV_REMOVE = 9,\n        MADV_DONTFORK = 10,\n        MADV_DOFORK = 11,\n        MADV_MERGEABLE = 65,\n        MADV_UNMERGEABLE = 66,\n        MADV_HUGEPAGE = 67,\n        MADV_NOHUGEPAGE = 68,\n        MADV_DONTDUMP = 69,\n    }\n\n    deprecated(\"MADV_*_PAGES are gone and never had any effect\") enum\n    {\n        MADV_4K_PAGES = 12,\n        MADV_16K_PAGES = 14,\n        MADV_64K_PAGES = 16,\n        MADV_256K_PAGES = 18,\n        MADV_1M_PAGES = 20,\n        MADV_4M_PAGES = 22,\n        MADV_16M_PAGES = 24,\n        MADV_64M_PAGES = 26,\n    }\n\n    // in core.sys.posix.sys.mman\n    // static if (__USE_XOPEN2K) enum\n    // {\n    //     POSIX_MADV_NORMAL = 0,\n    //     POSIX_MADV_RANDOM = 1,\n    //     POSIX_MADV_SEQUENTIAL = 2,\n    //     POSIX_MADV_WILLNEED = 3,\n    //     POSIX_MADV_DONTNEED = 4,\n    // }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/hppa/bits/mman.h\nelse version (HPPA64)\n{\n    enum\n    {\n        PROT_READ = 0x1,\n        PROT_WRITE = 0x2,\n        PROT_EXEC = 0x4,\n        PROT_NONE = 0x0,\n        PROT_GROWSDOWN = 0x01000000,\n        PROT_GROWSUP = 0x02000000,\n    }\n\n    enum MAP_SHARED = 0x01;\n    enum MAP_PRIVATE = 0x02;\n    static if (__USE_MISC)\n        enum MAP_TYPE = 0x0f;\n\n    enum MAP_FIXED = 0x04;\n    static if (__USE_MISC) enum\n    {\n        MAP_FILE = 0,\n        MAP_ANONYMOUS = MAP_ANON,\n        // in core.sys.posix.sys.mman\n        // MAP_ANON = MAP_ANONYMOUS,\n        MAP_VARIABLE = 0,\n        MAP_HUGE_SHIFT = 26,\n        MAP_HUGE_MASK = 0x3f,\n    }\n\n    static if (__USE_MISC) enum\n    {\n        MAP_DENYWRITE = 0x0800,\n        MAP_EXECUTABLE = 0x1000,\n        MAP_LOCKED = 0x2000,\n        MAP_NORESERVE = 0x4000,\n        MAP_GROWSDOWN = 0x8000,\n        MAP_POPULATE = 0x10000,\n        MAP_NONBLOCK = 0x20000,\n    }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //     MS_ASYNC = 1,\n    //     MS_SYNC = 2,\n    //     MS_INVALIDATE = 4,\n    // }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //     MCL_CURRENT = 1,\n    //     MCL_FUTURE = 2,\n    // }\n\n    static if (__USE_GNU) enum\n    {\n        MREMAP_MAYMOVE = 1,\n        MREMAP_FIXED = 2,\n    }\n\n    static if (__USE_MISC) enum\n    {\n        MADV_NORMAL = 0,\n        MADV_RANDOM = 1,\n        MADV_SEQUENTIAL = 2,\n        MADV_WILLNEED = 3,\n        MADV_DONTNEED = 4,\n        MADV_SPACEAVAIL = 5,\n        MADV_VPS_PURGE = 6,\n        MADV_VPS_INHERIT = 7,\n        MADV_REMOVE = 9,\n        MADV_DONTFORK = 10,\n        MADV_DOFORK = 11,\n        MADV_MERGEABLE = 65,\n        MADV_UNMERGEABLE = 66,\n        MADV_HUGEPAGE = 67,\n        MADV_NOHUGEPAGE = 68,\n        MADV_DONTDUMP = 69,\n        MADV_DODUMP = 70,\n    }\n\n    deprecated(\"MADV_*_PAGES are gone and never had any effect\") enum\n    {\n        MADV_4K_PAGES = 12,\n        MADV_16K_PAGES = 14,\n        MADV_64K_PAGES = 16,\n        MADV_256K_PAGES = 18,\n        MADV_1M_PAGES = 20,\n        MADV_4M_PAGES = 22,\n        MADV_16M_PAGES = 24,\n        MADV_64M_PAGES = 26,\n    }\n\n    // in core.sys.posix.sys.mman\n    // static if (__USE_XOPEN2K) enum\n    // {\n    //     POSIX_MADV_NORMAL = 0,\n    //     POSIX_MADV_RANDOM = 1,\n    //     POSIX_MADV_SEQUENTIAL = 2,\n    //     POSIX_MADV_WILLNEED = 3,\n    //     POSIX_MADV_DONTNEED = 4,\n    // }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/ia64/bits/mman.h\nelse version (IA64)\n{\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x00100,\n        MAP_GROWSUP = 0x00200,\n        MAP_DENYWRITE = 0x00800,\n        MAP_EXECUTABLE = 0x01000,\n        MAP_LOCKED = 0x02000,\n        MAP_NORESERVE = 0x04000,\n        MAP_POPULATE = 0x08000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/m68k/bits/mman.h\nelse version (M68K)\n{\n    static if (__USE_MISC) enum\n    {\n        MAP_GROWSDOWN = 0x00100,\n        MAP_DENYWRITE = 0x00800,\n        MAP_EXECUTABLE = 0x01000,\n        MAP_LOCKED = 0x02000,\n        MAP_NORESERVE = 0x04000,\n        MAP_POPULATE = 0x08000,\n        MAP_NONBLOCK = 0x10000,\n        MAP_STACK = 0x20000,\n        MAP_HUGETLB = 0x40000,\n    }\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/mips/bits/mman.h\nelse version (MIPS32)\n{\n    static if (__USE_MISC) enum\n    {\n        MAP_NORESERVE = 0x0400,\n        MAP_GROWSDOWN = 0x1000,\n        MAP_DENYWRITE = 0x2000,\n        MAP_EXECUTABLE = 0x4000,\n        MAP_LOCKED = 0x8000,\n        MAP_POPULATE = 0x10000,\n        MAP_NONBLOCK = 0x20000,\n        MAP_STACK = 0x40000,\n        MAP_HUGETLB = 0x80000,\n    }\n}\n// https://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/mips/bits/mman.h\nelse version (MIPS64)\n{\n    static if (__USE_MISC) enum\n    {\n        MAP_NORESERVE = 0x0400,\n        MAP_GROWSDOWN = 0x1000,\n        MAP_DENYWRITE = 0x2000,\n        MAP_EXECUTABLE = 0x4000,\n        MAP_LOCKED = 0x8000,\n        MAP_POPULATE = 0x10000,\n        MAP_NONBLOCK = 0x20000,\n        MAP_STACK = 0x40000,\n        MAP_HUGETLB = 0x80000,\n    }\n}\nelse\n{\n    static assert(0, \"unimplemented\");\n}\n\n\n// <bits/mman-linux.h>\n// https://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=bits/mman-linux.h\nversion (Alpha)\n{\n}\nelse version (HPPA)\n{\n}\nelse version (HPPA64)\n{\n}\nelse\n{\n    // in core.sys.posix.sys.mman\n    // enum PROT_READ = 0x1;\n    // enum PROT_WRITE = 0x2;\n    // enum PROT_EXEC = 0x4;\n    // enum PROT_NONE = 0x0;\n\n    enum PROT_GROWSDOWN = 0x01000000;\n    enum PROT_GROWSUP = 0x02000000;\n\n    enum MAP_SHARED = 0x01;\n    enum MAP_PRIVATE = 0x02;\n    static if (__USE_MISC)\n        enum MAP_TYPE = 0x0f;\n\n    enum MAP_FIXED = 0x10;\n    static if (__USE_MISC) enum\n    {\n        MAP_FILE = 0,\n        MAP_ANONYMOUS = MAP_ANON,\n        // in core.sys.posix.sys.mman\n        // MAP_ANON = 0xXX,\n        MAP_HUGE_SHIFT = 26,\n        MAP_HUGE_MASK = 0x3f,\n    }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //     MS_ASYNC = 1,\n    //     MS_SYNC = 4,\n    //     MS_INVALIDATE = 2,\n    // }\n\n    static if (__USE_GNU) enum\n    {\n        MREMAP_MAYMOVE = 1,\n        MREMAP_FIXED = 2,\n    }\n\n    static if (__USE_MISC) enum\n    {\n        MADV_NORMAL = 0,\n        MADV_RANDOM = 1,\n        MADV_SEQUENTIAL = 2,\n        MADV_WILLNEED = 3,\n        MADV_DONTNEED = 4,\n        MADV_REMOVE = 9,\n        MADV_DONTFORK = 10,\n        MADV_DOFORK = 11,\n        MADV_MERGEABLE = 12,\n        MADV_UNMERGEABLE = 13,\n        MADV_HUGEPAGE = 14,\n        MADV_NOHUGEPAGE = 15,\n        MADV_DONTDUMP = 16,\n        MADV_DODUMP = 17,\n        MADV_HWPOISON = 100,\n    }\n\n    // in core.sys.posix.sys.mman\n    // static if (__USE_XOPEN2K) enum\n    // {\n    //     POSIX_MADV_NORMAL = 0,\n    //     POSIX_MADV_RANDOM = 1,\n    //     POSIX_MADV_SEQUENTIAL = 2,\n    //     POSIX_MADV_WILLNEED = 3,\n    //     POSIX_MADV_DONTNEED = 4,\n    // }\n\n    // in core.sys.posix.sys.mman\n    // enum\n    // {\n    //\n    //     MCL_CURRENT = 1,\n    //     MCL_FUTURE = 2,\n    // }\n}\n\n// Workaround https://issues.dlang.org/show_bug.cgi?id=17883\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/sparc/bits/mman.h\nversion (SPARC)\n{\n    static if (__USE_MISC) enum MAP_RENAME = MAP_ANONYMOUS;\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/sparc/bits/mman.h\nelse version (SPARC64)\n{\n    static if (__USE_MISC) enum MAP_RENAME = MAP_ANONYMOUS;\n}\n// http://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/mips/bits/mman.h\nelse version (MIPS32)\n{\n    static if (__USE_MISC) enum MAP_RENAME = MAP_ANONYMOUS;\n}\n// https://sourceware.org/git/?p=glibc.git;a=blob;hb=51e945a8f950a6695754b11c1e6fba8bb750e100;f=sysdeps/unix/sysv/linux/mips/bits/mman.h\nelse version (MIPS64)\n{\n    static if (__USE_MISC) enum MAP_RENAME = MAP_ANONYMOUS;\n}\n\n// http://sourceware.org/git/?p=glibc.git;a=blob;f=misc/sys/mman.h\n// in core.sys.posix.sys.mman\n// static if (__USE_LARGEFILE64) void* mmap64(void*, size_t, int, int, int, off_t);\n// static if (__USE_FILE_OFFSET64)\n//     alias mmap64 mmap;\n// else\n//     void* mmap(void*, size_t, int, int, int, off_t);\n// int munmap(void*, size_t);\n// int mprotect(void *__addr, size_t __len, int __prot);\n// int msync(void *__addr, size_t __len, int __flags);\nstatic if (__USE_MISC) int madvise(void *__addr, size_t __len, int __advice);\n// static if (__USE_XOPEN2K) int posix_madvise(void *__addr, size_t __len, int __advice);\n// int mlock(const(void) *__addr, size_t __len);\n// int munlock(const(void) *__addr, size_t __len);\n// int mlockall(int __flags);\n// int munlockall();\nstatic if (__USE_MISC) int mincore(void *__start, size_t __len, ubyte *__vec);\nstatic if (__USE_GNU) void *mremap(void *__addr, size_t __old_len, size_t __new_len, int __flags, ...);\nstatic if (__USE_GNU) int remap_file_pages(void *__start, size_t __size, int __prot, size_t __pgoff, int __flags);\n// int shm_open(in char *__name, int __oflag, mode_t __mode);\n// int shm_unlink(in char *__name);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/netinet/tcp.d",
    "content": "/**\n * D header file for GNU/Linux\n *\n * Authors: Martin Nowak\n */\ndeprecated(\"Import core.sys.linux.netinet.tcp instead\")\nmodule core.sys.linux.sys.netinet.tcp;\n\npublic import core.sys.linux.netinet.tcp;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/prctl.d",
    "content": "/**\n * D header file for GNU/Linux.\n *\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Arun Chandrasekaran <aruncxy@gmail.com>\n */\nmodule core.sys.linux.sys.prctl;\n\nversion (linux):\nextern (C):\n@system:\n@nogc:\nnothrow:\n\nenum: uint\n{\n    PR_SET_PDEATHSIG                    = 1,\n    PR_GET_PDEATHSIG                    = 2,\n\n    PR_GET_DUMPABLE                     = 3,\n    PR_SET_DUMPABLE                     = 4,\n\n    PR_GET_UNALIGN                      = 5,\n    PR_SET_UNALIGN                      = 6,\n\n    PR_UNALIGN_NOPRINT                  = 1,\n    PR_UNALIGN_SIGBUS                   = 2,\n\n    PR_GET_KEEPCAPS                     = 7,\n    PR_SET_KEEPCAPS                     = 8,\n\n    PR_GET_FPEMU                        = 9,\n    PR_SET_FPEMU                        = 10,\n    PR_FPEMU_NOPRINT                    = 1,\n    PR_FPEMU_SIGFPE                     = 2,\n\n    PR_GET_FPEXC                        = 11,\n    PR_SET_FPEXC                        = 12,\n    PR_FP_EXC_SW_ENABLE                 = 0x80,\n    PR_FP_EXC_DIV                       = 0x010000,\n    PR_FP_EXC_OVF                       = 0x020000,\n    PR_FP_EXC_UND                       = 0x040000,\n    PR_FP_EXC_RES                       = 0x080000,\n    PR_FP_EXC_INV                       = 0x100000,\n    PR_FP_EXC_DISABLED                  = 0,\n    PR_FP_EXC_NONRECOV                  = 1,\n    PR_FP_EXC_ASYNC                     = 2,\n    PR_FP_EXC_PRECISE                   = 3,\n\n    PR_GET_TIMING                       = 13,\n    PR_SET_TIMING                       = 14,\n    PR_TIMING_STATISTICAL               = 0,\n    PR_TIMING_TIMESTAMP                 = 1,\n\n    PR_SET_NAME                         = 15,\n    PR_GET_NAME                         = 16,\n\n    PR_GET_ENDIAN                       = 19,\n    PR_SET_ENDIAN                       = 20,\n    PR_ENDIAN_BIG                       = 0,\n    PR_ENDIAN_LITTLE                    = 1,\n    PR_ENDIAN_PPC_LITTLE                = 2,\n\n    PR_GET_SECCOMP                      = 21,\n    PR_SET_SECCOMP                      = 22,\n\n    PR_CAPBSET_READ                     = 23,\n    PR_CAPBSET_DROP                     = 24,\n\n    PR_GET_TSC                          = 25,\n    PR_SET_TSC                          = 26,\n    PR_TSC_ENABLE                       = 1,\n    PR_TSC_SIGSEGV                      = 2,\n\n    PR_GET_SECUREBITS                   = 27,\n    PR_SET_SECUREBITS                   = 28,\n\n\n    PR_SET_TIMERSLACK                   = 29,\n    PR_GET_TIMERSLACK                   = 30,\n\n    PR_TASK_PERF_EVENTS_DISABLE         = 31,\n    PR_TASK_PERF_EVENTS_ENABLE          = 32,\n\n\n    PR_MCE_KILL                         = 33,\n    PR_MCE_KILL_CLEAR                   = 0,\n    PR_MCE_KILL_SET                     = 1,\n\n    PR_MCE_KILL_LATE                    = 0,\n    PR_MCE_KILL_EARLY                   = 1,\n    PR_MCE_KILL_DEFAULT                 = 2,\n\n    PR_MCE_KILL_GET                     = 34,\n\n    PR_SET_MM                           = 35,\n    PR_SET_MM_START_CODE                = 1,\n    PR_SET_MM_END_CODE                  = 2,\n    PR_SET_MM_START_DATA                = 3,\n    PR_SET_MM_END_DATA                  = 4,\n    PR_SET_MM_START_STACK               = 5,\n    PR_SET_MM_START_BRK                 = 6,\n    PR_SET_MM_BRK                       = 7,\n    PR_SET_MM_ARG_START                 = 8,\n    PR_SET_MM_ARG_END                   = 9,\n    PR_SET_MM_ENV_START                 = 10,\n    PR_SET_MM_ENV_END                   = 11,\n    PR_SET_MM_AUXV                      = 12,\n    PR_SET_MM_EXE_FILE                  = 13,\n    PR_SET_MM_MAP                       = 14,\n    PR_SET_MM_MAP_SIZE                  = 15,\n\n    PR_SET_PTRACER                      = 0x59616d61,\n    PR_SET_PTRACER_ANY                  = (cast (uint)-1),\n\n    PR_SET_CHILD_SUBREAPER              = 36,\n    PR_GET_CHILD_SUBREAPER              = 37,\n\n    PR_SET_NO_NEW_PRIVS                 = 38,\n    PR_GET_NO_NEW_PRIVS                 = 39,\n\n    PR_GET_TID_ADDRESS                  = 40,\n\n    PR_SET_THP_DISABLE                  = 41,\n    PR_GET_THP_DISABLE                  = 42,\n}\n\nstruct prctl_mm_map\n{\n    ulong    start_code;\n    ulong    end_code;\n    ulong    start_data;\n    ulong    end_data;\n    ulong    start_brk;\n    ulong    brk;\n    ulong    start_stack;\n    ulong    arg_start;\n    ulong    arg_end;\n    ulong    env_start;\n    ulong    env_end;\n    ulong*   auxv;\n    uint     auxv_size;\n    uint     exe_fd;\n};\n\nint prctl(int option, size_t arg2, size_t arg3, size_t arg4, size_t arg5);\n\n//\n// Example usage to set and get the task name.\n//\n// byte[16] oldname = cast(byte[]) \"1234567890123456\";\n// oldname[oldname.length-1] = 0;\n// prctl(PR_SET_NAME, cast(size_t) oldname.ptr, cast(size_t) null, cast(size_t) null, cast(size_t) null);\n// byte[16] newname;\n// prctl(PR_GET_NAME, cast(size_t) newname.ptr, cast(size_t) null, cast(size_t) null, cast(size_t) null);\n// int i;\n// foreach (b; newname)\n// {\n//         assert(b == oldname[i]);\n//             i++;\n// }\n// writeln(cast(string) newname);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/signalfd.d",
    "content": "/**\n * D header file for Linux.\n *\n * Copyright: Copyright Alex Rønne Petersen 2012.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Alex Rønne Petersen\n */\nmodule core.sys.linux.sys.signalfd;\n\nimport core.sys.posix.signal;\n\nversion (linux):\n\nextern (C):\n@system:\nnothrow:\n\nstruct signalfd_siginfo\n{\n    uint ssi_signo;\n    int ssi_errno;\n    int ssi_code;\n    uint ssi_pid;\n    uint ssi_uid;\n    int ssi_fd;\n    uint ssi_tid;\n    uint ssi_band;\n    uint ssi_overrun;\n    uint ssi_trapno;\n    int ssi_status;\n    int ssi_int;\n    ulong ssi_ptr;\n    ulong ssi_utime;\n    ulong ssi_stime;\n    ulong ssi_addr;\n    ubyte[48] __pad;\n}\n\nenum SFD_CLOEXEC = 0x80000; // 02000000\nenum SFD_NONBLOCK = 0x800; // 04000\n\nint signalfd (int __fd, const(sigset_t)* __mask, int __flags);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/socket.d",
    "content": "/**\n * D header file for GNU/Linux.\n *\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Paul O'Neil\n */\nmodule core.sys.linux.sys.socket;\n\npublic import core.sys.posix.sys.socket;\n\nversion (linux):\nextern(C):\n@nogc:\nnothrow:\n\nenum\n{\n    // Protocol families.\n    PF_UNSPEC     = 0,\n    PF_LOCAL      = 1,\n    PF_UNIX       = PF_LOCAL,\n    PF_FILE       = PF_LOCAL,\n    PF_INET       = 2,\n    PF_AX25       = 3,\n    PF_NETROM     = 6,\n    PF_BRIDGE     = 7,\n    PF_ATMPVC     = 8,\n    PF_X25        = 9,\n    PF_INET6      = 10,\n    PF_ROSE       = 11,\n    PF_DECnet     = 12,\n    PF_NETBEUI    = 13,\n    PF_SECURITY   = 14,\n    PF_KEY        = 15,\n    PF_NETLINK    = 16,\n    PF_ROUTE      = PF_NETLINK,\n    PF_PACKET     = 17,\n    PF_ASH        = 18,\n    PF_ECONET     = 19,\n    PF_ATMSVC     = 20,\n    PF_RDS        = 21,\n    PF_SNA        = 22,\n    PF_IRDA       = 23,\n    PF_PPPOX      = 24,\n    PF_WANPIPE    = 25,\n    PF_LLC        = 26,\n    PF_IB         = 27,\n    PF_MPLS       = 28,\n    PF_CAN        = 29,\n    PF_TIPC       = 30,\n    PF_BLUETOOTH  = 31,\n    PF_IUCV       = 32,\n    PF_RXRPC      = 33,\n    PF_ISDN       = 34,\n    PF_PHONET     = 35,\n    PF_IEEE802154 = 36,\n    PF_CAIF       = 37,\n    PF_ALG        = 38,\n    PF_NFC        = 39,\n    PF_VSOCK      = 40,\n    PF_KCM        = 41,\n    PF_QIPCRTR    = 42,\n    PF_SMC        = 43,\n    PF_MAX        = 44,\n\n    // Address families.\n    AF_LOCAL      = PF_LOCAL,\n    AF_FILE       = AF_LOCAL,\n    AF_AX25       = PF_AX25,\n    AF_NETROM     = PF_NETROM,\n    AF_BRIDGE     = PF_BRIDGE,\n    AF_ATMPVC     = PF_ATMPVC,\n    AF_X25        = PF_X25,\n    AF_INET6      = PF_INET6,\n    AF_ROSE       = PF_ROSE,\n    AF_DECnet     = PF_DECnet,\n    AF_NETBEUI    = PF_NETBEUI,\n    AF_SECURITY   = PF_SECURITY,\n    AF_KEY        = PF_KEY,\n    AF_NETLINK    = PF_NETLINK,\n    AF_ROUTE      = PF_ROUTE,\n    AF_PACKET     = PF_PACKET,\n    AF_ASH        = PF_ASH,\n    AF_ECONET     = PF_ECONET,\n    AF_ATMSVC     = PF_ATMSVC,\n    AF_RDS        = PF_RDS,\n    AF_SNA        = PF_SNA,\n    AF_IRDA       = PF_IRDA,\n    AF_PPPOX      = PF_PPPOX,\n    AF_WANPIPE    = PF_WANPIPE,\n    AF_LLC        = PF_LLC,\n    AF_IB         = PF_IB,\n    AF_MPLS       = PF_MPLS,\n    AF_CAN        = PF_CAN,\n    AF_TIPC       = PF_TIPC,\n    AF_BLUETOOTH  = PF_BLUETOOTH,\n    AF_IUCV       = PF_IUCV,\n    AF_RXRPC      = PF_RXRPC,\n    AF_ISDN       = PF_ISDN,\n    AF_PHONET     = PF_PHONET,\n    AF_IEEE802154 = PF_IEEE802154,\n    AF_CAIF       = PF_CAIF,\n    AF_ALG        = PF_ALG,\n    AF_NFC        = PF_NFC,\n    AF_VSOCK      = PF_VSOCK,\n    AF_KCM        = PF_KCM,\n    AF_QIPCRTR    = PF_QIPCRTR,\n    AF_SMC        = PF_SMC,\n    AF_MAX        = PF_MAX,\n}\n\n// For getsockopt() and setsockopt()\nenum\n{\n    SO_SECURITY_AUTHENTICATION       = 22,\n    SO_SECURITY_ENCRYPTION_TRANSPORT = 23,\n    SO_SECURITY_ENCRYPTION_NETWORK   = 24,\n\n    SO_BINDTODEVICE            = 25,\n\n    SO_ATTACH_FILTER           = 26,\n    SO_DETACH_FILTER           = 27,\n    SO_GET_FILTER              = SO_ATTACH_FILTER,\n\n    SO_PEERNAME                = 28,\n    SO_TIMESTAMP               = 29,\n    SCM_TIMESTAMP              = SO_TIMESTAMP,\n\n    SO_PASSSEC                 = 34,\n    SO_TIMESTAMPNS             = 35,\n    SCM_TIMESTAMPNS            = SO_TIMESTAMPNS,\n    SO_MARK                    = 36,\n    SO_TIMESTAMPING            = 37,\n    SCM_TIMESTAMPING           = SO_TIMESTAMPING,\n    SO_RXQ_OVFL                = 40,\n    SO_WIFI_STATUS             = 41,\n    SCM_WIFI_STATUS            = SO_WIFI_STATUS,\n    SO_PEEK_OFF                = 42,\n    SO_NOFCS                   = 43,\n    SO_LOCK_FILTER             = 44,\n    SO_SELECT_ERR_QUEUE        = 45,\n    SO_BUSY_POLL               = 46,\n    SO_MAX_PACING_RATE         = 47,\n    SO_BPF_EXTENSIONS          = 48,\n    SO_INCOMING_CPU            = 49,\n    SO_ATTACH_BPF              = 50,\n    SO_DETACH_BPF              = SO_DETACH_FILTER,\n    SO_ATTACH_REUSEPORT_CBPF   = 51,\n    SO_ATTACH_REUSEPORT_EBPF   = 52,\n    SO_CNX_ADVICE              = 53,\n    SCM_TIMESTAMPING_OPT_STATS = 54,\n    SO_MEMINFO                 = 55,\n    SO_INCOMING_NAPI_ID        = 56,\n    SO_COOKIE                  = 57,\n    SCM_TIMESTAMPING_PKTINFO   = 58,\n    SO_PEERGROUPS              = 59,\n    SO_ZEROCOPY                = 60,\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/sysinfo.d",
    "content": "/**\n * D header file for GNU/Linux.\n *\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Martin Nowak\n */\nmodule core.sys.linux.sys.sysinfo;\n\nversion (linux) extern(C) @nogc nothrow:\n\nimport core.sys.linux.config;\n\n// linux/sysinfo.h\nenum SI_LOAD_SHIFT = 16;\n\nstruct sysinfo_\n{\n    c_long uptime;     /* Seconds since boot */\n    c_ulong[3] loads;  /* 1, 5, and 15 minute load averages */\n    c_ulong totalram;  /* Total usable main memory size */\n    c_ulong freeram;   /* Available memory size */\n    c_ulong sharedram; /* Amount of shared memory */\n    c_ulong bufferram; /* Memory used by buffers */\n    c_ulong totalswap; /* Total swap space size */\n    c_ulong freeswap;  /* swap space still available */\n    ushort procs;      /* Number of current processes */\n    ushort pad;        /* Explicit padding for m68k */\n    c_ulong totalhigh; /* Total high memory size */\n    c_ulong freehigh;  /* Available high memory size */\n    uint mem_unit;     /* Memory unit size in bytes */\n    ubyte[20-2 * c_ulong.sizeof - uint.sizeof] _f; /* Padding: libc5 uses this.. */\n}\n\n\nint sysinfo(sysinfo_ *info);\nint get_nprocs_conf();\nint get_nprocs();\nc_long get_phys_pages();\nc_long get_avphys_pages();\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/time.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sociomantic Labs GmbH.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Leandro Lucarella\n */\n\n/*          Copyright Sociomantic Labs GmbH.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.linux.sys.time;\n\nprivate import core.sys.linux.config;\npublic import core.sys.posix.sys.time;  // timeval\n\nversion (linux):\n\n/* macros provided to operate on timeval structures\n * they are extern(D) because they are not really C symbols, just macros\n */\nextern (D) pure @safe @nogc nothrow {\n\n    void timeradd(const timeval* a, const timeval* b,\n            timeval* result)\n    {\n        result.tv_sec = a.tv_sec + b.tv_sec;\n        result.tv_usec = a.tv_usec + b.tv_usec;\n        if (result.tv_usec >= 1_000_000)\n        {\n            ++result.tv_sec;\n            result.tv_usec -= 1_000_000;\n        }\n    }\n\n    void timersub(const timeval* a, const timeval* b,\n            timeval *result)\n    {\n        result.tv_sec = a.tv_sec - b.tv_sec;\n        result.tv_usec = a.tv_usec - b.tv_usec;\n        if (result.tv_usec < 0) {\n            --result.tv_sec;\n            result.tv_usec += 1_000_000;\n        }\n    }\n\n    void timerclear(timeval* tvp)\n    {\n        (tvp.tv_sec = tvp.tv_usec = 0);\n    }\n\n    int timerisset(timeval* tvp)\n    {\n        return cast(int) (tvp.tv_sec || tvp.tv_usec);\n    }\n\n    int timercmp(string CMP)(const timeval* a, const timeval* b)\n    {\n        return cast(int)\n               mixin(\"((a.tv_sec == b.tv_sec) ?\" ~\n                     \"(a.tv_usec\" ~ CMP ~ \"b.tv_usec) :\" ~\n                     \"(a.tv_sec\"  ~ CMP ~ \"b.tv_sec))\");\n    }\n\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/sys/xattr.d",
    "content": "/**\n * D header file for GNU/Linux.\n *\n * Copyright: Copyright Robert Klotzner 2012.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Robert Klotzner\n */\nmodule core.sys.linux.sys.xattr;\n\nimport core.sys.posix.sys.types;\n\nversion (linux):\nextern (C):\n@system:\nnothrow:\n\nenum {\n    XATTR_CREATE = 1, /* set value, fail if attr already exists.  */\n    XATTR_REPLACE = 2 /* set value, fail if attr does not exist.  */\n}\n\nenum XATTR_OS2_PREFIX = \"os2.\";\nenum XATTR_OS2_PREFIX_LEN = XATTR_OS2_PREFIX.length;\nenum XATTR_SECURITY_PREFIX = \"security.\";\nenum XATTR_SECURITY_PREFIX_LEN = XATTR_SECURITY_PREFIX.length;\nenum XATTR_SYSTEM_PREFIX = \"system.\";\nenum XATTR_SYSTEM_PREFIX_LEN = XATTR_SYSTEM_PREFIX.length;\nenum XATTR_TRUSTED_PREFIX = \"trusted.\";\nenum XATTR_TRUSTED_PREFIX_LEN = XATTR_TRUSTED_PREFIX.length;\nenum XATTR_USER_PREFIX = \"user.\";\nenum XATTR_USER_PREFIX_LEN = XATTR_USER_PREFIX.length;\n\n/* Security namespace */\nenum XATTR_SELINUX_SUFFIX = \"selinux.\";\nenum XATTR_NAME_SELINUX = XATTR_SECURITY_PREFIX ~ XATTR_SELINUX_SUFFIX;\n\nenum XATTR_SMACK_SUFFIX = \"SMACK64\";\nenum XATTR_SMACK_IPIN = \"SMACK64IPIN\";\nenum XATTR_SMACK_IPOUT = \"SMACK64IPOUT\";\nenum XATTR_SMACK_EXEC = \"SMACK64EXEC\";\nenum XATTR_SMACK_TRANSMUTE = \"SMACK64TRANSMUTE\";\nenum XATTR_SMACK_MMAP = \"SMACK64MMAP\";\n\nenum XATTR_NAME_SMACK = XATTR_SECURITY_PREFIX ~ XATTR_SMACK_SUFFIX;\nenum XATTR_NAME_SMACKIPIN = XATTR_SECURITY_PREFIX ~ XATTR_SMACK_IPIN;\nenum XATTR_NAME_SMACKIPOUT = XATTR_SECURITY_PREFIX ~ XATTR_SMACK_IPOUT;\nenum XATTR_NAME_SMACKEXEC = XATTR_SECURITY_PREFIX ~ XATTR_SMACK_EXEC;\nenum XATTR_NAME_SMACKTRANSMUTE = XATTR_SECURITY_PREFIX ~ XATTR_SMACK_TRANSMUTE;\nenum XATTR_NAME_SMACKMMAP = XATTR_SECURITY_PREFIX ~ XATTR_SMACK_MMAP;\n\nenum XATTR_CAPS_SUFFIX = \"capability\";\nenum XATTR_NAME_CAPS = XATTR_SECURITY_PREFIX ~ XATTR_CAPS_SUFFIX;\n\n\nint setxattr(in char* path, in char* name, in void* value, size_t size, int flags);\n\nint lsetxattr(in char* path, in char* name, in void* value, size_t size, int flags);\nint fsetxattr(int fd, in char* name, in void* value, size_t size, int flags);\nssize_t getxattr(in char* path, in char* name, void* value, size_t size);\nssize_t lgetxattr(in char* path, in char* name, void* value, size_t size);\nssize_t fgetxattr(int fd, in char* name, void* value, size_t size);\nssize_t listxattr(in char* path, char* list, size_t size);\nssize_t llistxattr(in char* path, char* list, size_t size);\nssize_t flistxattr (int __fd, char *list, size_t size);\nint removexattr (in char *path, in char *name);\nint lremovexattr (in char *path, in char *name);\nint fremovexattr (int fd, in char *name);\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/termios.d",
    "content": "/**\n * D header file for GNU/Linux\n */\n/* Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\n\nmodule core.sys.linux.termios;\n\nversion (linux):\n    public import core.sys.posix.termios;\n\n    enum B57600 = 0x1001; // 0010001\n    enum B115200 = 0x1002; // 0010002\n    enum B230400 = 0x1003; // 0010003\n    enum B460800 = 0x1004; // 0010004\n    enum B500000 = 0x1005; // 0010005\n    enum B576000 = 0x1006; // 0010006\n    enum B921600 = 0x1007; // 0010007\n    enum B1000000 = 0x1008; // 0010010\n    enum B1152000 = 0x1009; // 0010011\n    enum B1500000 = 0x100A; // 0010012\n    enum B2000000 = 0x100B; // 0010013\n    enum B2500000 = 0x100C; // 0010014\n    enum B3000000 = 0x100D; // 0010015\n    enum B3500000 = 0x100E; // 0010016\n    enum B4000000 = 0x100F; // 0010017\n\n    enum CRTSCTS = 0x80000000; // 020000000000\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/time.d",
    "content": "//Written in the D programming language\n\n/++\n    D header file for Linux extensions to POSIX's time.h.\n\n    Copyright: Copyright 2014\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n +/\nmodule core.sys.linux.time;\n\npublic import core.sys.posix.time;\n\nversion (linux):\n\nenum CLOCK_MONOTONIC_RAW      = 4;\nenum CLOCK_REALTIME_COARSE    = 5;\nenum CLOCK_MONOTONIC_COARSE   = 6;\nenum CLOCK_BOOTTIME           = 7;\nenum CLOCK_REALTIME_ALARM     = 8;\nenum CLOCK_BOOTTIME_ALARM     = 9;\nenum CLOCK_SGI_CYCLE          = 10;\nenum CLOCK_TAI                = 11;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/timerfd.d",
    "content": "/**\n * D header file to interface with the Linux timefd API <http://man7.org/linux/man-pages/man2/timerfd_create.2.html>\n * Available since Linux 2.6\n *\n * License : $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n */\nmodule core.sys.linux.timerfd;\n\nversion (linux):\n\npublic import core.sys.posix.time;\n\nextern (C):\n@system:\n@nogc:\nnothrow:\n\nint timerfd_create(int clockid, int flags);\nint timerfd_settime(int fd, int flags, const itimerspec* new_value, itimerspec* old_value);\nint timerfd_gettime(int fd, itimerspec* curr_value);\n\nenum TFD_TIMER_ABSTIME = 1 << 0;\nenum TFD_CLOEXEC       = 0x80000;\nenum TFD_NONBLOCK      = 0x800;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/tipc.d",
    "content": "/**\n * Interface for Linux TIPC sockets, /usr/include/linux/tipc.h\n *\n * Copyright: Public Domain\n * License:   Public Domain\n * Authors:   Leandro Lucarella\n */\n\nmodule core.sys.linux.tipc;\n\nversion (linux):\nextern (C) nothrow @nogc:\n\nstruct tipc_portid\n{\n        uint ref_;\n        uint node;\n}\n\nstruct tipc_name\n{\n        uint type;\n        uint instance;\n}\n\nstruct tipc_name_seq\n{\n        uint type;\n        uint lower;\n        uint upper;\n}\n\nstruct tipc_subscr\n{\n        tipc_name_seq seq;\n        uint timeout;\n        uint filter;\n        ubyte[8] usr_handle;\n}\n\nstruct tipc_event\n{\n        uint event;\n        uint found_lower;\n        uint found_upper;\n        tipc_portid port;\n        tipc_subscr s;\n}\n\nstruct sockaddr_tipc\n{\n        ushort family;\n        ubyte addrtype;\n        byte scope_;\n        union Addr\n        {\n                tipc_portid id;\n                tipc_name_seq nameseq;\n                static struct Name\n                {\n                        tipc_name name;\n                        uint domain;\n                }\n                Name name;\n        }\n        Addr addr;\n}\n\nuint tipc_addr(uint zone, uint cluster, uint node)\n{\n        return (zone << 24) | (cluster << 12) | node;\n}\n\nunittest\n{\n        assert (tipc_addr(0, 0, 0) == 0);\n        assert (tipc_addr(1, 1, 1) == 16781313);\n        assert (tipc_addr(2, 1, 27) == 33558555);\n        assert (tipc_addr(3, 1, 63) == 50335807);\n}\n\nuint tipc_zone(uint addr)\n{\n        return addr >> 24;\n}\n\nunittest\n{\n        assert (tipc_zone(0u) == 0);\n        assert (tipc_zone(16781313u) == 1);\n        assert (tipc_zone(33558555u) == 2);\n        assert (tipc_zone(50335807u) == 3);\n}\n\nuint tipc_cluster(uint addr)\n{\n        return (addr >> 12) & 0xfff;\n}\n\nunittest\n{\n        assert (tipc_cluster(0u) == 0);\n        assert (tipc_cluster(16781313u) == 1);\n        assert (tipc_cluster(33558555u) == 1);\n        assert (tipc_cluster(50335807u) == 1);\n}\n\nuint tipc_node(uint addr)\n{\n        return addr & 0xfff;\n}\n\nunittest\n{\n        assert (tipc_node(0u) == 0);\n        assert (tipc_node(16781313u) == 1);\n        assert (tipc_node(33558555u) == 27);\n        assert (tipc_node(50335807u) == 63);\n}\n\nenum: int\n{\n        TIPC_CFG_SRV    = 0,\n        TIPC_TOP_SRV    = 1,\n        TIPC_RESERVED_TYPES = 64,\n}\n\nenum: int\n{\n        TIPC_ZONE_SCOPE    = 1,\n        TIPC_CLUSTER_SCOPE = 2,\n        TIPC_NODE_SCOPE    = 3,\n}\n\nenum: int\n{\n        TIPC_MAX_USER_MSG_SIZE = 66000,\n}\n\nenum: int\n{\n        TIPC_LOW_IMPORTANCE      = 0,\n        TIPC_MEDIUM_IMPORTANCE   = 1,\n        TIPC_HIGH_IMPORTANCE     = 2,\n        TIPC_CRITICAL_IMPORTANCE = 3,\n}\n\nenum: int\n{\n        TIPC_OK     = 0,\n        TIPC_ERR_NO_NAME   = 1,\n        TIPC_ERR_NO_PORT   = 2,\n        TIPC_ERR_NO_NODE   = 3,\n        TIPC_ERR_OVERLOAD  = 4,\n        TIPC_CONN_SHUTDOWN = 5,\n}\n\nenum: int\n{\n        TIPC_SUB_PORTS    = 0x01,\n        TIPC_SUB_SERVICE  = 0x02,\n        TIPC_SUB_CANCEL   = 0x04,\n}\n\nversion (none) enum: int\n{\n        TIPC_SUB_NO_BIND_EVTS   = 0x04,\n        TIPC_SUB_NO_UNBIND_EVTS = 0x08,\n        TIPC_SUB_SINGLE_EVT     = 0x10,\n}\n\nenum: int\n{\n        TIPC_WAIT_FOREVER = ~0,\n}\n\nenum: int\n{\n\n        TIPC_PUBLISHED      = 1,\n        TIPC_WITHDRAWN      = 2,\n        TIPC_SUBSCR_TIMEOUT = 3,\n}\n\nenum: int\n{\n        AF_TIPC    = 30,\n        PF_TIPC    = 30,\n        SOL_TIPC          = 271,\n        TIPC_ADDR_NAMESEQ = 1,\n        TIPC_ADDR_MCAST   = 1,\n        TIPC_ADDR_NAME    = 2,\n        TIPC_ADDR_ID      = 3,\n}\n\nenum: int\n{\n        TIPC_ERRINFO  = 1,\n        TIPC_RETDATA  = 2,\n        TIPC_DESTNAME = 3,\n}\n\nenum: int\n{\n        TIPC_IMPORTANCE     = 127,\n        TIPC_SRC_DROPPABLE  = 128,\n        TIPC_DEST_DROPPABLE = 129,\n        TIPC_CONN_TIMEOUT   = 130,\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/linux/unistd.d",
    "content": "module core.sys.linux.unistd;\n\npublic import core.sys.posix.unistd;\n\nversion (linux):\nextern(C):\nnothrow:\n\n// Additional seek constants for sparse file handling\n// from Linux's unistd.h, stdio.h, and linux/fs.h\n// (see http://man7.org/linux/man-pages/man2/lseek.2.html)\nenum {\n    /// Offset is relative to the next location containing data\n    SEEK_DATA = 3,\n    /// Offset is relative to the next hole (or EOF if file is not sparse)\n    SEEK_HOLE = 4\n}\n\n/// Prompt for a password without echoing it.\nchar* getpass(const(char)* prompt);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/netbsd/dlfcn.d",
    "content": "/**\n * D header file for NetBSD.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n *\n * http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/include/dlfcn.h\n */\nmodule core.sys.netbsd.dlfcn;\n\npublic import core.sys.posix.dlfcn;\n\nversion (NetBSD):\nextern (C):\nnothrow:\n@nogc:\n\nenum __BSD_VISIBLE = true;\n\n/*\n * Modes and flags for dlopen().\n */\nstatic assert(RTLD_LAZY   == 1);\nstatic assert(RTLD_NOW    == 2);\nstatic assert(RTLD_GLOBAL == 0x100);\nstatic assert(RTLD_LOCAL  == 0x200);\n//enum RTLD_TRACE           =  0x200;\nenum RTLD_NODELETE        =  0x01000;\nenum RTLD_NOLOAD          =  0x02000;\n\n/*\n * Request arguments for dlinfo().\n */\nenum RTLD_DI_LINKMAP     = 3;    /* Obtain link map. */\nenum RTLD_DI_SERINFO     = 5;    /* Obtain search path info. */\nenum RTLD_DI_SERINFOSIZE = 6;    /*  ... query for required space. */\nenum RTLD_DI_ORIGIN      = 7;    /* Obtain object origin */\nenum RTLD_DI_MAX         = RTLD_DI_ORIGIN;\n\n/*\n * Special handle arguments for dlsym()/dlinfo().\n */\nenum RTLD_NEXT    = cast(void *)-1;    /* Search subsequent objects. */\nenum RTLD_DEFAULT = cast(void *)-2;    /* Use default search algorithm. */\nenum RTLD_SELF    = cast(void *)-3;    /* Search the caller itself. */\n\nstatic if (__BSD_VISIBLE)\n{\n    /*\n     * Structure filled in by dladdr().\n     */\n    struct Dl_info {\n        const(char)     *dli_fname;     /* Pathname of shared object. */\n        void            *dli_fbase;     /* Base address of shared object. */\n        const(char)     *dli_sname;     /* Name of nearest symbol. */\n        void            *dli_saddr;     /* Address of nearest symbol. */\n    };\n\n    /*-\n     * The actual type declared by this typedef is immaterial, provided that\n     * it is a function pointer.  Its purpose is to provide a return type for\n     * dlfunc() which can be cast to a function pointer type without depending\n     * on behavior undefined by the C standard, which might trigger a compiler\n     * diagnostic.  We intentionally declare a unique type signature to force\n     * a diagnostic should the application not cast the return value of dlfunc()\n     * appropriately.\n     */\n    struct __dlfunc_arg {\n        int     __dlfunc_dummy;\n    };\n\n    alias dlfunc_t = void function(__dlfunc_arg);\n\n    /*\n     * Structures, returned by the RTLD_DI_SERINFO dlinfo() request.\n     */\n    struct Dl_serpath {\n        char *          dls_name;       /* single search path entry */\n        uint            dls_flags;      /* path information */\n    };\n\n    struct Dl_serinfo {\n        size_t          dls_size;       /* total buffer size */\n        uint            dls_cnt;        /* number of path entries */\n        Dl_serpath[1]   dls_serpath;    /* there may be more than one */\n    };\n}\n\nprivate template __externC(RT, P...)\n{\n    alias __externC = extern(C) RT function(P) nothrow @nogc;\n}\n\n/* XSI functions first. */\nstatic assert(is(typeof(&dlclose) == __externC!(int, void*)));\nstatic assert(is(typeof(&dlerror) == __externC!(char*)));\nstatic assert(is(typeof(&dlopen)  == __externC!(void*, const char*, int)));\nstatic assert(is(typeof(&dlsym)   == __externC!(void*, void*, const char*)));\n\nstatic if (__BSD_VISIBLE)\n{\n    //void*    fdlopen(int, int);\n    int      dladdr(const(void)*, Dl_info*);\n    //dlfunc_t dlfunc(void*, const(char)*);\n    //int      dlinfo(void*, int, void*);\n    /+void     dllockinit(void* _context,\n        void* function(void* _context) _lock_create,\n        void  function(void* _lock)    _rlock_acquire,\n        void  function(void* _lock)    _wlock_acquire,\n        void  function(void* _lock)    _lock_release,\n        void  function(void* _lock)    _lock_destroy,\n        void  function(void* _context) _context_destroy);+/\n    void*    dlvsym(void*, const(char)*, const(char)*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/netbsd/execinfo.d",
    "content": "/**\n * NetBSD implementation of glibc's $(LINK2 http://www.gnu.org/software/libc/manual/html_node/Backtraces.html backtrace) facility.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Martin Nowak\n * Source:    $(DRUNTIMESRC core/sys/netbsd/_execinfo.d)\n */\nmodule core.sys.netbsd.execinfo;\n\nversion (NetBSD):\nextern (C):\nnothrow:\n\nimport core.sys.netbsd.dlfcn;\n\n// Use extern (D) so that these functions don't collide with libexecinfo.\n\nextern (D) int backtrace(void** buffer, int size)\n{\n    import core.thread : thread_stackBottom;\n\n    void** p, pend=cast(void**)thread_stackBottom();\n    version (D_InlineAsm_X86)\n        asm nothrow @trusted { mov p[EBP], EBP; }\n    else version (D_InlineAsm_X86_64)\n        asm nothrow @trusted { mov p[RBP], RBP; }\n    else\n        static assert(false, \"Architecture not supported.\");\n\n    int i;\n    for (; i < size && p < pend; ++i)\n    {\n        buffer[i] = *(p + 1);\n        auto pnext = cast(void**)*p;\n        if (pnext <= p) break;\n        p = pnext;\n    }\n    return i;\n}\n\n\nextern (D) char** backtrace_symbols(const(void*)* buffer, int size)\n{\n    static void* realloc(void* p, size_t len) nothrow\n    {\n        static import cstdlib=core.stdc.stdlib;\n        auto res = cstdlib.realloc(p, len);\n        if (res is null) cstdlib.free(p);\n        return res;\n    }\n\n    if (size <= 0) return null;\n\n    size_t pos = size * (char*).sizeof;\n    char** p = cast(char**)realloc(null, pos);\n    if (p is null) return null;\n\n    Dl_info info;\n    foreach (i, addr; buffer[0 .. size])\n    {\n        if (dladdr(addr, &info) == 0)\n            (cast(ubyte*)&info)[0 .. info.sizeof] = 0;\n        fixupDLInfo(addr, info);\n\n        immutable len = formatStackFrame(null, 0, addr, info);\n        assert(len > 0);\n\n        p = cast(char**)realloc(p, pos + len);\n        if (p is null) return null;\n\n        formatStackFrame(cast(char*)p + pos, len, addr, info) == len || assert(0);\n\n        p[i] = cast(char*)pos;\n        pos += len;\n    }\n    foreach (i; 0 .. size)\n    {\n        pos = cast(size_t)p[i];\n        p[i] = cast(char*)p + pos;\n    }\n    return p;\n}\n\n\nextern (D) void backtrace_symbols_fd(const(void*)* buffer, int size, int fd)\n{\n    import core.sys.posix.unistd : write;\n    import core.stdc.stdlib : alloca;\n\n    if (size <= 0) return;\n\n    Dl_info info;\n    foreach (i, addr; buffer[0 .. size])\n    {\n        if (dladdr(addr, &info) == 0)\n            (cast(ubyte*)&info)[0 .. info.sizeof] = 0;\n        fixupDLInfo(addr, info);\n\n        enum maxAlloca = 1024;\n        enum min = (size_t a, size_t b) => a <= b ? a : b;\n        immutable len = min(formatStackFrame(null, 0, addr, info), maxAlloca);\n        assert(len > 0);\n\n        auto p = cast(char*)alloca(len);\n        if (p is null) return;\n\n        formatStackFrame(p, len, addr, info) >= len || assert(0);\n        p[len - 1] = '\\n';\n        write(fd, p, len);\n    }\n}\n\n\nprivate void fixupDLInfo(const(void)* addr, ref Dl_info info)\n{\n    if (info.dli_fname is null) info.dli_fname = \"???\";\n    if (info.dli_fbase is null) info.dli_fbase = null;\n    if (info.dli_sname is null) info.dli_sname = \"???\";\n    if (info.dli_saddr is null) info.dli_saddr = cast(void*)addr;\n}\n\n\nprivate size_t formatStackFrame(char* p, size_t plen, const(void)* addr, const ref Dl_info info)\n{\n    import core.stdc.stdio : snprintf;\n\n    immutable off = addr - info.dli_saddr;\n    immutable len = snprintf(p, plen, \"%p <%s+%zd> at %s\",\n                             addr, info.dli_sname, off, info.dli_fname);\n    assert(len > 0);\n    return cast(size_t)len + 1; // + '\\0'\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/netbsd/sys/elf.d",
    "content": "/**\n * D header file for NetBSD.\n *\n */\nmodule core.sys.netbsd.sys.elf;\n\nversion (NetBSD):\n\npublic import core.sys.netbsd.sys.elf32;\npublic import core.sys.netbsd.sys.elf64;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/netbsd/sys/elf32.d",
    "content": "/**\n * D header file for NetBSD.\n *\n * http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/sys/exec_elf.h\n */\nmodule core.sys.netbsd.sys.elf32;\n\nversion (NetBSD):\nextern (C):\npure:\nnothrow:\n\nimport core.stdc.stdint;\npublic import core.sys.netbsd.sys.elf_common;\n\nalias uint16_t Elf32_Half;\nalias uint32_t Elf32_Word;\nalias int32_t  Elf32_Sword;\nalias uint64_t Elf32_Lword;\nalias uint32_t Elf32_Addr;\nalias uint32_t Elf32_Off;\nalias Elf32_Word Elf32_Hashelt;\nalias Elf32_Word Elf32_Size;\nalias Elf32_Sword Elf32_Ssize;\n\nstruct Elf32_Ehdr\n{\n    char[EI_NIDENT] e_ident;\n    Elf32_Half    e_type;\n    Elf32_Half    e_machine;\n    Elf32_Word    e_version;\n    Elf32_Addr    e_entry;\n    Elf32_Off     e_phoff;\n    Elf32_Off     e_shoff;\n    Elf32_Word    e_flags;\n    Elf32_Half    e_ehsize;\n    Elf32_Half    e_phentsize;\n    Elf32_Half    e_phnum;\n    Elf32_Half    e_shentsize;\n    Elf32_Half    e_shnum;\n    Elf32_Half    e_shstrndx;\n}\n\nstruct Elf32_Shdr\n{\n    Elf32_Word    sh_name;\n    Elf32_Word    sh_type;\n    Elf32_Word    sh_flags;\n    Elf32_Addr    sh_addr;\n    Elf32_Off     sh_offset;\n    Elf32_Word    sh_size;\n    Elf32_Word    sh_link;\n    Elf32_Word    sh_info;\n    Elf32_Word    sh_addralign;\n    Elf32_Word    sh_entsize;\n}\n\nstruct Elf32_Phdr\n{\n    Elf32_Word    p_type;\n    Elf32_Off     p_offset;\n    Elf32_Addr    p_vaddr;\n    Elf32_Addr    p_paddr;\n    Elf32_Word    p_filesz;\n    Elf32_Word    p_memsz;\n    Elf32_Word    p_flags;\n    Elf32_Word    p_align;\n}\n\nstruct Elf32_Dyn\n{\n  Elf32_Sword   d_tag;\n  union _d_un\n  {\n      Elf32_Word d_val;\n      Elf32_Addr d_ptr;\n  } _d_un d_un;\n}\n\nstruct Elf32_Rel\n{\n    Elf32_Addr    r_offset;\n    Elf32_Word    r_info;\n}\n\nstruct Elf32_Rela\n{\n    Elf32_Addr    r_offset;\n    Elf32_Word    r_info;\n    Elf32_Sword   r_addend;\n}\n\nextern (D)\n{\n    auto ELF32_R_SYM(V)(V val) { return val >> 8; }\n    auto ELF32_R_TYPE(V)(V val) { return val & 0xff; }\n    auto ELF32_R_INFO(S, T)(S sym, T type) { return (sym << 8) + (type & 0xff); }\n}\n\nalias Elf_Note Elf32_Nhdr;\n\nstruct Elf32_Move\n{\n    Elf32_Lword   m_value;\n    Elf32_Word    m_info;\n    Elf32_Word    m_poffset;\n    Elf32_Half    m_repeat;\n    Elf32_Half    m_stride;\n}\n\nextern (D)\n{\n    auto ELF32_M_SYM(I)(I info) { return info >> 8; }\n    auto ELF32_M_SIZE(I)(I info) { return cast(ubyte)info; }\n    auto ELF32_M_INFO(S, SZ)(S sym, SZ size) { return (sym << 8) + cast(ubye)size; }\n}\n\nstruct Elf32_Cap\n{\n    Elf32_Word    c_tag;\n    union _c_un\n    {\n        Elf32_Word      c_val;\n        Elf32_Addr      c_ptr;\n    } _c_un c_un;\n}\n\nstruct Elf32_Sym\n{\n    Elf32_Word    st_name;\n    Elf32_Addr    st_value;\n    Elf32_Word    st_size;\n    ubyte st_info;\n    ubyte st_other;\n    Elf32_Half st_shndx;\n}\n\nextern (D)\n{\n    auto ELF32_ST_BIND(T)(T val) { return cast(ubyte)val >> 4; }\n    auto ELF32_ST_TYPE(T)(T val) { return val & 0xf; }\n    auto ELF32_ST_INFO(B, T)(B bind, T type) { return (bind << 4) + (type & 0xf); }\n    auto ELF32_ST_VISIBILITY(O)(O o) { return o & 0x03; }\n}\n\nstruct Elf32_Verdef\n{\n    Elf32_Half    vd_version;\n    Elf32_Half    vd_flags;\n    Elf32_Half    vd_ndx;\n    Elf32_Half    vd_cnt;\n    Elf32_Word    vd_hash;\n    Elf32_Word    vd_aux;\n    Elf32_Word    vd_next;\n}\n\nstruct Elf32_Verdaux\n{\n    Elf32_Word    vda_name;\n    Elf32_Word    vda_next;\n}\n\nstruct Elf32_Verneed\n{\n    Elf32_Half    vn_version;\n    Elf32_Half    vn_cnt;\n    Elf32_Word    vn_file;\n    Elf32_Word    vn_aux;\n    Elf32_Word    vn_next;\n}\n\nstruct Elf32_Vernaux\n{\n    Elf32_Word    vna_hash;\n    Elf32_Half    vna_flags;\n    Elf32_Half    vna_other;\n    Elf32_Word    vna_name;\n    Elf32_Word    vna_next;\n}\n\nalias Elf32_Half Elf32_Versym;\n\nstruct Elf32_Syminfo\n{\n    Elf32_Half si_boundto;\n    Elf32_Half si_flags;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/netbsd/sys/elf64.d",
    "content": "/**\n * D header file for NetBSD.\n *\n * http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/sys/exec_elf.h\n */\nmodule core.sys.netbsd.sys.elf64;\n\nversion (NetBSD):\nextern (C):\npure:\nnothrow:\n\nimport core.stdc.stdint;\npublic import core.sys.netbsd.sys.elf_common;\n\nalias uint16_t Elf64_Half;\nalias uint32_t Elf64_Word;\nalias int32_t  Elf64_Sword;\nalias uint64_t Elf64_Lword;\nalias uint64_t Elf64_Xword;\nalias int64_t  Elf64_Sxword;\nalias uint64_t Elf64_Addr;\nalias uint64_t Elf64_Off;\nalias Elf64_Word Elf64_Hashelt;\nalias Elf64_Xword Elf64_Size;\nalias Elf64_Sxword Elf64_Ssize;\n\nstruct Elf64_Ehdr\n{\n    char[EI_NIDENT] e_ident;\n    Elf64_Half    e_type;\n    Elf64_Half    e_machine;\n    Elf64_Word    e_version;\n    Elf64_Addr    e_entry;\n    Elf64_Off     e_phoff;\n    Elf64_Off     e_shoff;\n    Elf64_Word    e_flags;\n    Elf64_Half    e_ehsize;\n    Elf64_Half    e_phentsize;\n    Elf64_Half    e_phnum;\n    Elf64_Half    e_shentsize;\n    Elf64_Half    e_shnum;\n    Elf64_Half    e_shstrndx;\n}\n\nstruct Elf64_Shdr\n{\n    Elf64_Word    sh_name;\n    Elf64_Word    sh_type;\n    Elf64_Xword   sh_flags;\n    Elf64_Addr    sh_addr;\n    Elf64_Off     sh_offset;\n    Elf64_Xword   sh_size;\n    Elf64_Word    sh_link;\n    Elf64_Word    sh_info;\n    Elf64_Xword   sh_addralign;\n    Elf64_Xword   sh_entsize;\n}\n\nstruct Elf64_Phdr\n{\n    Elf64_Word    p_type;\n    Elf64_Word    p_flags;\n    Elf64_Off     p_offset;\n    Elf64_Addr    p_vaddr;\n    Elf64_Addr    p_paddr;\n    Elf64_Xword   p_filesz;\n    Elf64_Xword   p_memsz;\n    Elf64_Xword   p_align;\n}\n\nstruct Elf64_Dyn\n{\n  Elf64_Sxword  d_tag;\n  union _d_un\n  {\n      Elf64_Xword d_val;\n      Elf64_Addr d_ptr;\n  } _d_un d_un;\n}\n\nstruct Elf64_Rel\n{\n    Elf64_Addr    r_offset;\n    Elf64_Xword   r_info;\n}\n\nstruct Elf64_Rela\n{\n    Elf64_Addr    r_offset;\n    Elf64_Xword   r_info;\n    Elf64_Sxword  r_addend;\n}\n\nextern (D)\n{\n    auto ELF64_R_SYM(I)(I i) { return i >> 32; }\n    auto ELF64_R_TYPE(I)(I i) { return i & 0xffffffff; }\n    auto ELF64_R_INFO(S, T)(S sym, T type) { return (sym << 32) + (type & 0xffffffff); }\n\n    auto ELF64_R_TYPE_DATA(I)(I i) { return (cast(Elf64_Xword) i << 32) >> 40; }\n    auto ELF64_R_TYPE_ID(I)(I i) { return (cast(Elf64_Xword) i << 56 ) >> 56; }\n    auto ELF64_R_TYPE_INFO(D, T)(D d, T t) { return cast(Elf64_Xword) d << 8 + cast(Elf64_Xword) t; }\n}\n\nalias Elf_Note Elf64_Nhdr;\n\nstruct Elf64_Move\n{\n    Elf64_Lword   m_value;\n    Elf64_Xword   m_info;\n    Elf64_Xword   m_poffset;\n    Elf64_Half    m_repeat;\n    Elf64_Half    m_stride;\n}\n\nextern (D)\n{\n    auto ELF64_M_SYM(I)(I info) { return info >> 8; }\n    auto ELF64_M_SIZE(I)(I info) { return cast(ubyte)info; }\n    auto ELF64_M_INFO(S, SZ)(S sym, SZ size) { return (sym << 8) + cast(ubye)size; }\n}\n\nstruct Elf64_Cap\n{\n    Elf64_Xword   c_tag;\n    union _c_un\n    {\n        Elf64_Xword     c_val;\n        Elf64_Addr      c_ptr;\n    } _c_un c_un;\n}\n\nstruct Elf64_Sym\n{\n    Elf64_Word    st_name;\n    ubyte st_info;\n    ubyte st_other;\n    Elf64_Half st_shndx;\n    Elf64_Addr    st_value;\n    Elf64_Xword   st_size;\n}\n\nextern (D)\n{\n    auto ELF64_ST_BIND(T)(T val) { return cast(ubyte)val >> 4; }\n    auto ELF64_ST_TYPE(T)(T val) { return val & 0xf; }\n    auto ELF64_ST_INFO(B, T)(B bind, T type) { return (bind << 4) + (type & 0xf); }\n    auto ELF64_ST_VISIBILITY(O)(O o) { return o & 0x03; }\n}\n\nstruct Elf64_Verdef\n{\n    Elf64_Half    vd_version;\n    Elf64_Half    vd_flags;\n    Elf64_Half    vd_ndx;\n    Elf64_Half    vd_cnt;\n    Elf64_Word    vd_hash;\n    Elf64_Word    vd_aux;\n    Elf64_Word    vd_next;\n}\n\nstruct Elf64_Verdaux\n{\n    Elf64_Word    vda_name;\n    Elf64_Word    vda_next;\n}\n\nstruct Elf64_Verneed\n{\n    Elf64_Half    vn_version;\n    Elf64_Half    vn_cnt;\n    Elf64_Word    vn_file;\n    Elf64_Word    vn_aux;\n    Elf64_Word    vn_next;\n}\n\nstruct Elf64_Vernaux\n{\n    Elf64_Word    vna_hash;\n    Elf64_Half    vna_flags;\n    Elf64_Half    vna_other;\n    Elf64_Word    vna_name;\n    Elf64_Word    vna_next;\n}\n\nalias Elf64_Half Elf64_Versym;\n\nstruct Elf64_Syminfo\n{\n    Elf64_Half si_boundto;\n    Elf64_Half si_flags;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/netbsd/sys/elf_common.d",
    "content": "/**\n * D header file for NetBSD.\n *\n * http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/sys/exec_elf.h\n */\nmodule core.sys.netbsd.sys.elf_common;\n\nversion (NetBSD):\nextern (C):\npure:\nnothrow:\n\nimport core.stdc.stdint;\n\nstruct Elf_Note\n{\n    uint32_t      n_namesz;\n    uint32_t      n_descsz;\n    uint32_t      n_type;\n}\n\nstruct Elf_GNU_Hash_Header\n{\n    uint32_t      gh_nbuckets;\n    uint32_t      gh_symndx;\n    uint32_t      gh_maskwords;\n    uint32_t      gh_shift2;\n}\n\nenum EI_MAG0 =         0;\nenum EI_MAG1 =         1;\nenum EI_MAG2 =         2;\nenum EI_MAG3 =         3;\nenum EI_CLASS =        4;\nenum EI_DATA =         5;\nenum EI_VERSION =      6;\nenum EI_OSABI =        7;\nenum EI_ABIVERSION =   8;\nenum OLD_EI_BRAND =    8;\nenum EI_PAD =          9;\nenum EI_NIDENT =       16;\n\nenum ELFMAG0 =         0x7f;\nenum ELFMAG1 =         'E';\nenum ELFMAG2 =         'L';\nenum ELFMAG3 =         'F';\nenum ELFMAG =          \"\\177ELF\";\nenum SELFMAG =         4;\n\nenum EV_NONE =         0;\nenum EV_CURRENT =      1;\n\nenum ELFCLASSNONE =    0;\nenum ELFCLASS32 =      1;\nenum ELFCLASS64 =      2;\n\nenum ELFDATANONE =     0;\nenum ELFDATA2LSB =     1;\nenum ELFDATA2MSB =     2;\n\nenum ELFOSABI_NONE =           0;\nenum ELFOSABI_SYSV =           0;\nenum ELFOSABI_HPUX =           1;\nenum ELFOSABI_NETBSD =         2;\nenum ELFOSABI_LINUX =          3;\nenum ELFOSABI_HURD  =          4;\nenum ELFOSABI_86OPEN =         5;\nenum ELFOSABI_SOLARIS =        6;\nenum ELFOSABI_AIX =            7;\nenum ELFOSABI_MONTEREY =       7;\nenum ELFOSABI_IRIX =           8;\nenum ELFOSABI_FREEBSD =        9;\nenum ELFOSABI_TRU64 =          10;\nenum ELFOSABI_MODESTO =        11;\nenum ELFOSABI_OPENBSD =        12;\nenum ELFOSABI_OPENVMS =        13;\nenum ELFOSABI_NSK =            14;\nenum ELFOSABI_AROS =           15;\nenum ELFOSABI_ARM =            97;\nenum ELFOSABI_STANDALONE =     255;\nenum ELFOSABI_DRAGONFLYBSD =   ELFOSABI_NONE;\n\nextern (D)\n{\n    auto IS_ELF(T)(T ehdr) { return ehdr.e_ident[EI_MAG0] == ELFMAG0 &&\n                                    ehdr.e_ident[EI_MAG1] == ELFMAG1 &&\n                                    ehdr.e_ident[EI_MAG2] == ELFMAG2 &&\n                                    ehdr.e_ident[EI_MAG3] == ELFMAG3; }\n}\n\nenum ET_NONE =         0;\nenum ET_REL =          1;\nenum ET_EXEC =         2;\nenum ET_DYN =          3;\nenum ET_CORE =         4;\nenum ET_LOOS =         0xfe00;\nenum ET_HIOS =         0xfeff;\nenum ET_LOPROC =       0xff00;\nenum ET_HIPROC =       0xffff;\n\nenum EM_NONE =          0;\nenum EM_M32 =           1;\nenum EM_SPARC =         2;\nenum EM_386 =           3;\nenum EM_68K =           4;\nenum EM_88K =           5;\nenum EM_860 =           7;\nenum EM_MIPS =          8;\nenum EM_S370 =          9;\nenum EM_MIPS_RS3_LE =  10;\nenum EM_PARISC =       15;\nenum EM_VPP500 =       17;\nenum EM_SPARC32PLUS =  18;\nenum EM_960 =          19;\nenum EM_PPC =          20;\nenum EM_PPC64 =        21;\nenum EM_S390 =         22;\nenum EM_V800 =         36;\nenum EM_FR20 =         37;\nenum EM_RH32 =         38;\nenum EM_RCE =          39;\nenum EM_ARM =          40;\nenum EM_SH =           42;\nenum EM_SPARCV9 =      43;\nenum EM_TRICORE =      44;\nenum EM_ARC =          45;\nenum EM_H8_300 =       46;\nenum EM_H8_300H =      47;\nenum EM_H8S =          48;\nenum EM_H8_500 =       49;\nenum EM_IA_64 =        50;\nenum EM_MIPS_X =       51;\nenum EM_COLDFIRE =     52;\nenum EM_68HC12 =       53;\nenum EM_MMA =          54;\nenum EM_PCP =          55;\nenum EM_NCPU =         56;\nenum EM_NDR1 =         57;\nenum EM_STARCORE =     58;\nenum EM_ME16 =         59;\nenum EM_ST100 =        60;\nenum EM_TINYJ =        61;\nenum EM_X86_64 =       62;\nenum EM_AMD64 =        62;\nenum EM_PDSP =         63;\nenum EM_FX66 =         66;\nenum EM_ST9PLUS =      67;\nenum EM_ST7 =          68;\nenum EM_68HC16 =       69;\nenum EM_68HC11 =       70;\nenum EM_68HC08 =       71;\nenum EM_68HC05 =       72;\nenum EM_SVX =          73;\nenum EM_ST19 =         74;\nenum EM_VAX =          75;\nenum EM_CRIS =         76;\nenum EM_JAVELIN =      77;\nenum EM_FIREPATH =     78;\nenum EM_ZSP =          79;\nenum EM_MMIX =         80;\nenum EM_HUANY =        81;\nenum EM_PRISM =        82;\nenum EM_AVR =          83;\nenum EM_FR30 =         84;\nenum EM_D10V =         85;\nenum EM_D30V =         86;\nenum EM_V850 =         87;\nenum EM_M32R =         88;\nenum EM_MN10300 =      89;\nenum EM_MN10200 =      90;\nenum EM_PJ =           91;\nenum EM_OPENRISC =     92;\nenum EM_ARC_A5 =       93;\nenum EM_XTENSA =       94;\nenum EM_VIDEOCORE =    95;\nenum EM_TMM_GPP =      96;\nenum EM_NS32K =        97;\nenum EM_TPC =          98;\nenum EM_SNP1K =        99;\nenum EM_ST200 =       100;\nenum EM_IP2K =        101;\nenum EM_MAX =         102;\nenum EM_CR =          103;\nenum EM_F2MC16 =      104;\nenum EM_MSP430 =      105;\nenum EM_BLACKFIN =    106;\nenum EM_SE_C33 =      107;\nenum EM_SEP =         108;\nenum EM_ARCA =        109;\nenum EM_UNICORE =     110;\nenum EM_AARCH64 =     183;     /* AArch64 64-bit ARM microprocessor */\n\n/* Unofficial machine types follow */\nenum EM_AVR32  =       6317;    /* used by NetBSD/avr32 */\nenum EM_ALPHA_EXP  =  36902;   /* used by NetBSD/alpha; obsolete */\n\nenum EM_486 =           6;\nenum EM_MIPS_RS4_BE =  10;\nenum EM_ALPHA_STD =    41;\nenum EM_ALPHA =    0x9026;\n\nenum SHN_UNDEF =       0;\nenum SHN_LORESERVE =   0xff00;\nenum SHN_LOPROC =      0xff00;\nenum SHN_HIPROC =      0xff1f;\nenum SHN_LOOS =        0xff20;\nenum SHN_HIOS =        0xff3f;\nenum SHN_ABS =         0xfff1;\nenum SHN_COMMON =      0xfff2;\nenum SHN_XINDEX =      0xffff;\nenum SHN_HIRESERVE =   0xffff;\n\nenum SHT_NULL =          0;\nenum SHT_PROGBITS =      1;\nenum SHT_SYMTAB =        2;\nenum SHT_STRTAB =        3;\nenum SHT_RELA =          4;\nenum SHT_HASH =          5;\nenum SHT_DYNAMIC =       6;\nenum SHT_NOTE =          7;\nenum SHT_NOBITS =        8;\nenum SHT_REL =           9;\nenum SHT_SHLIB =         10;\nenum SHT_DYNSYM =        11;\nenum SHT_INIT_ARRAY =    14;\nenum SHT_FINI_ARRAY =    15;\nenum SHT_PREINIT_ARRAY = 16;\nenum SHT_GROUP =         17;\nenum SHT_SYMTAB_SHNDX =  18;\nenum SHT_LOOS =          0x60000000;\nenum SHT_LOSUNW =        0x6ffffff4;\nenum SHT_SUNW_dof =      0x6ffffff4;\nenum SHT_SUNW_cap =      0x6ffffff5;\nenum SHT_SUNW_SIGNATURE = 0x6ffffff6;\nenum SHT_GNU_HASH =      0x6ffffff6;\nenum SHT_SUNW_ANNOTATE = 0x6ffffff7;\nenum SHT_SUNW_DEBUGSTR = 0x6ffffff8;\nenum SHT_SUNW_DEBUG =    0x6ffffff9;\nenum SHT_SUNW_move =     0x6ffffffa;\nenum SHT_SUNW_COMDAT =   0x6ffffffb;\nenum SHT_SUNW_syminfo =  0x6ffffffc;\nenum SHT_SUNW_verdef =   0x6ffffffd;\nenum SHT_GNU_verdef =    0x6ffffffd;\nenum SHT_SUNW_verneed =  0x6ffffffe;\nenum SHT_GNU_verneed =   0x6ffffffe;\nenum SHT_SUNW_versym =   0x6fffffff;\nenum SHT_GNU_versym =    0x6fffffff;\nenum SHT_HISUNW =        0x6fffffff;\nenum SHT_HIOS =          0x6fffffff;\nenum SHT_LOPROC =        0x70000000;\nenum SHT_AMD64_UNWIND =  0x70000001;\nenum SHT_ARM_EXIDX =     0x70000001;\nenum SHT_ARM_PREEMPTMAP = 0x70000002;\nenum SHT_ARM_ATTRIBUTES = 0x70000003;\nenum SHT_ARM_DEBUGOVERLAY = 0x70000004;\nenum SHT_ARM_OVERLAYSECTION = 0x70000005;\nenum SHT_MIPS_REGINFO =  0x70000006;\nenum SHT_MIPS_OPTIONS =  0x7000000d;\nenum SHT_MIPS_DWARF =    0x7000001e;\nenum SHT_HIPROC =        0x7fffffff;\nenum SHT_LOUSER =        0x80000000;\nenum SHT_HIUSER =        0x8fffffff;\n\nenum SHF_WRITE =            (1 << 0);\nenum SHF_ALLOC =            (1 << 1);\nenum SHF_EXECINSTR =        (1 << 2);\nenum SHF_MERGE =            (1 << 4);\nenum SHF_STRINGS =          (1 << 5);\nenum SHF_INFO_LINK =        (1 << 6);\nenum SHF_LINK_ORDER =       (1 << 7);\nenum SHF_OS_NONCONFORMING = (1 << 8);\nenum SHF_GROUP =            (1 << 9);\nenum SHF_TLS =              (1 << 10);\nenum SHF_MASKOS =           0x0ff00000;\nenum SHF_MASKPROC =         0xf0000000;\n\nenum PT_NULL =         0;\nenum PT_LOAD =         1;\nenum PT_DYNAMIC =      2;\nenum PT_INTERP =       3;\nenum PT_NOTE =         4;\nenum PT_SHLIB =        5;\nenum PT_PHDR =         6;\nenum PT_TLS =          7;\nenum PT_LOOS =         0x60000000;\nenum PT_SUNW_UNWIND =  0x6464e550;\nenum PT_GNU_EH_FRAME = 0x6474e550;\nenum PT_GNU_STACK =    0x6474e551;\nenum PT_GNU_RELRO =    0x6474e552;\nenum PT_LOSUNW =       0x6ffffffa;\nenum PT_SUNWBSS =      0x6ffffffa;\nenum PT_SUNWSTACK =    0x6ffffffb;\nenum PT_SUNWDTRACE =   0x6ffffffc;\nenum PT_SUNWCAP =      0x6ffffffd;\nenum PT_HISUNW =       0x6fffffff;\nenum PT_HIOS =         0x6fffffff;\nenum PT_LOPROC =       0x70000000;\nenum PT_HIPROC =       0x7fffffff;\n\nenum PF_X =            (1 << 0);\nenum PF_W =            (1 << 1);\nenum PF_R =            (1 << 2);\nenum PF_MASKOS =       0x0ff00000;\nenum PF_MASKPROC =     0xf0000000;\n\nenum PN_XNUM =         0xffff;\n\nenum DT_NULL =         0;\nenum DT_NEEDED =       1;\nenum DT_PLTRELSZ =     2;\nenum DT_PLTGOT =       3;\nenum DT_HASH =         4;\nenum DT_STRTAB =       5;\nenum DT_SYMTAB =       6;\nenum DT_RELA =         7;\nenum DT_RELASZ =       8;\nenum DT_RELAENT =      9;\nenum DT_STRSZ =        10;\nenum DT_SYMENT =       11;\nenum DT_INIT =         12;\nenum DT_FINI =         13;\nenum DT_SONAME =       14;\nenum DT_RPATH =        15;\nenum DT_SYMBOLIC =     16;\nenum DT_REL =          17;\nenum DT_RELSZ =        18;\nenum DT_RELENT =       19;\nenum DT_PLTREL =       20;\nenum DT_DEBUG =        21;\nenum DT_TEXTREL =      22;\nenum DT_JMPREL =       23;\nenum DT_BIND_NOW =     24;\nenum DT_INIT_ARRAY =   25;\nenum DT_FINI_ARRAY =   26;\nenum DT_INIT_ARRAYSZ = 27;\nenum DT_FINI_ARRAYSZ = 28;\nenum DT_RUNPATH =      29;\nenum DT_FLAGS =        30;\nenum DT_ENCODING =     32;\nenum DT_PREINIT_ARRAY = 32;\nenum DT_PREINIT_ARRAYSZ = 33;\nenum DT_MAXPOSTAGS =   34;\nenum DT_LOOS =         0x6000000d;\nenum DT_SUNW_AUXILIARY = 0x6000000d;\nenum DT_SUNW_RTLDINF = 0x6000000e;\nenum DT_SUNW_FILTER =  0x6000000f;\nenum DT_SUNW_CAP =     0x60000010;\nenum DT_HIOS =         0x6ffff000;\nenum DT_VALRNGLO =     0x6ffffd00;\nenum DT_CHECKSUM =     0x6ffffdf8;\nenum DT_PLTPADSZ =     0x6ffffdf9;\nenum DT_MOVEENT =      0x6ffffdfa;\nenum DT_MOVESZ =       0x6ffffdfb;\nenum DT_FEATURE_1 =    0x6ffffdfc;\nenum DT_POSFLAG_1 =    0x6ffffdfd;\nenum DT_SYMINSZ =      0x6ffffdfe;\nenum DT_SYMINENT =     0x6ffffdff;\nenum DT_VALRNGHI =     0x6ffffdff;\nenum DT_ADDRRNGLO =    0x6ffffe00;\nenum DT_GNU_HASH =     0x6ffffef5;\nenum DT_CONFIG =       0x6ffffefa;\nenum DT_DEPAUDIT =     0x6ffffefb;\nenum DT_AUDIT =        0x6ffffefc;\nenum DT_PLTPAD =       0x6ffffefd;\nenum DT_MOVETAB =      0x6ffffefe;\nenum DT_SYMINFO =      0x6ffffeff;\nenum DT_ADDRRNGHI =    0x6ffffeff;\nenum DT_VERSYM =       0x6ffffff0;\nenum DT_RELACOUNT =    0x6ffffff9;\nenum DT_RELCOUNT =     0x6ffffffa;\nenum DT_FLAGS_1 =      0x6ffffffb;\nenum DT_VERDEF =       0x6ffffffc;\nenum DT_VERDEFNUM =    0x6ffffffd;\nenum DT_VERNEED =      0x6ffffffe;\nenum DT_VERNEEDNUM =   0x6fffffff;\nenum DT_LOPROC =       0x70000000;\nenum DT_DEPRECATED_SPARC_REGISTER = 0x7000001;\nenum DT_AUXILIARY =    0x7ffffffd;\nenum DT_USED =         0x7ffffffe;\nenum DT_FILTER =       0x7fffffff;\nenum DT_HIPROC =       0x7fffffff;\n\nenum DF_ORIGIN =       0x00000001;\nenum DF_SYMBOLIC =     0x00000002;\nenum DF_TEXTREL =      0x00000004;\nenum DF_BIND_NOW =     0x00000008;\nenum DF_STATIC_TLS =   0x00000010;\n\nenum DF_1_BIND_NOW =   0x00000001;\nenum DF_1_GLOBAL =     0x00000002;\nenum DF_1_NODELETE =   0x00000008;\nenum DF_1_LOADFLTR =   0x00000010;\nenum DF_1_NOOPEN =     0x00000040;\nenum DF_1_NODEFLIB =   0x00000800;\n\nenum NT_PRSTATUS =     1;\nenum NT_FPREGSET =     2;\nenum NT_PRPSINFO =     3;\nenum NT_THRMISC =      7;\nenum NT_PROCSTAT_PROC = 8;\nenum NT_PROCSTAT_FILES = 9;\nenum NT_PROCSTAT_VMMAP = 10;\nenum NT_PROCSTAT_GROUPS = 11;\nenum NT_PROCSTAT_UMASK = 12;\nenum NT_PROCSTAT_RLIMIT = 13;\nenum NT_PROCSTAT_OSREL = 14;\nenum NT_PROCSTAT_PSSTRINGS = 15;\nenum NT_PROCSTAT_AUXV = 16;\n\nenum STB_LOCAL =       0;\nenum STB_GLOBAL =      1;\nenum STB_WEAK =        2;\nenum STB_NUM =         3;\nenum STB_LOOS =        10;\nenum STB_HIOS =        12;\nenum STB_LOPROC =      13;\nenum STB_HIPROC =      15;\n\nenum STT_NOTYPE =      0;\nenum STT_OBJECT =      1;\nenum STT_FUNC =        2;\nenum STT_SECTION =     3;\nenum STT_FILE =        4;\nenum STT_COMMON =      5;\nenum STT_TLS =         6;\nenum STT_NUM =         7;\nenum STT_LOOS =        10;\nenum STT_GNU_IFUNC =   10;\nenum STT_HIOS =        12;\nenum STT_LOPROC =      13;\nenum STT_HIPROC =      15;\n\nenum STV_DEFAULT =     0;\nenum STV_INTERNAL =    1;\nenum STV_HIDDEN =      2;\nenum STV_PROTECTED =   3;\nenum STV_EXPORTED =    4;\nenum STV_SINGLETON =   5;\nenum STV_ELIMINATE =   6;\n\nenum STN_UNDEF =       0;\n\nenum VER_DEF_CURRENT = 1;\nalias VER_NDX VER_DEF_IDX;\n\nenum VER_FLG_BASE =    0x1;\nenum VER_FLG_WEAK =    0x2;\n\nenum VER_NEED_CURRENT = 1;\nenum VER_NEED_WEAK =    32768;\nenum VER_NEED_HIDDEN = VER_NDX_HIDDEN;\nalias VER_NDX VER_NEED_IDX;\n\nenum VER_NDX_LOCAL =           0;\nenum VER_NDX_GLOBAL =          1;\nenum VER_NDX_GIVEN =           2;\n\nenum VER_NDX_HIDDEN =      32768;\nextern (D)\n{\n    auto VER_NDX(V)(V v) { return v & ~(1u << 15); }\n}\n\nenum CA_SUNW_NULL =    0;\nenum CA_SUNW_HW_1 =    1;\nenum CA_SUNW_SF_1 =    2;\n\nenum SYMINFO_FLG_DIRECT =      0x0001;\nenum SYMINFO_FLG_PASSTHRU =    0x0002;\nenum SYMINFO_FLG_COPY =        0x0004;\nenum SYMINFO_FLG_LAZYLOAD =    0x0008;\nenum SYMINFO_FLG_DIRECTBIND =  0x0010;\nenum SYMINFO_FLG_NOEXTDIRECT = 0x0020;\nenum SYMINFO_FLG_FILTER =      0x0002;\nenum SYMINFO_FLG_AUXILIARY =   0x0040;\n\nenum SYMINFO_BT_SELF =         0xffff;\nenum SYMINFO_BT_PARENT =       0xfffe;\nenum SYMINFO_BT_NONE =         0xfffd;\nenum SYMINFO_BT_EXTERN =       0xfffc;\nenum SYMINFO_BT_LOWRESERVE =   0xff00;\n\nenum SYMINFO_NONE =            0;\nenum SYMINFO_CURRENT =         1;\nenum SYMINFO_NUM =             2;\n\nenum R_386_NONE =               0;\nenum R_386_32 =                 1;\nenum R_386_PC32 =               2;\nenum R_386_GOT32 =              3;\nenum R_386_PLT32 =              4;\nenum R_386_COPY =               5;\nenum R_386_GLOB_DAT =           6;\nenum R_386_JMP_SLOT =           7;\nenum R_386_RELATIVE =           8;\nenum R_386_GOTOFF =             9;\nenum R_386_GOTPC =              10;\nenum R_386_TLS_TPOFF =          14;\nenum R_386_TLS_IE =             15;\nenum R_386_TLS_GOTIE =          16;\nenum R_386_TLS_LE =             17;\nenum R_386_TLS_GD =             18;\nenum R_386_TLS_LDM =            19;\nenum R_386_TLS_GD_32 =          24;\nenum R_386_TLS_GD_PUSH =        25;\nenum R_386_TLS_GD_CALL =        26;\nenum R_386_TLS_GD_POP =         27;\nenum R_386_TLS_LDM_32 =         28;\nenum R_386_TLS_LDM_PUSH =       29;\nenum R_386_TLS_LDM_CALL =       30;\nenum R_386_TLS_LDM_POP =        31;\nenum R_386_TLS_LDO_32 =         32;\nenum R_386_TLS_IE_32 =          33;\nenum R_386_TLS_LE_32 =          34;\nenum R_386_TLS_DTPMOD32 =       35;\nenum R_386_TLS_DTPOFF32 =       36;\nenum R_386_TLS_TPOFF32 =        37;\nenum R_386_IRELATIVE =          42;\n\nenum R_ARM_NONE =               0;\nenum R_ARM_PC24 =               1;\nenum R_ARM_ABS32 =              2;\nenum R_ARM_REL32 =              3;\nenum R_ARM_PC13 =               4;\nenum R_ARM_ABS16 =              5;\nenum R_ARM_ABS12 =              6;\nenum R_ARM_THM_ABS5 =           7;\nenum R_ARM_ABS8 =               8;\nenum R_ARM_SBREL32 =            9;\nenum R_ARM_THM_PC22 =           10;\nenum R_ARM_THM_PC8 =            11;\nenum R_ARM_AMP_VCALL9 =         12;\nenum R_ARM_SWI24 =              13;\nenum R_ARM_THM_SWI8 =           14;\nenum R_ARM_XPC25 =              15;\nenum R_ARM_THM_XPC22 =          16;\nenum R_ARM_TLS_DTPMOD32 =       17;\nenum R_ARM_TLS_DTPOFF32 =       18;\nenum R_ARM_TLS_TPOFF32 =        19;\nenum R_ARM_COPY =               20;\nenum R_ARM_GLOB_DAT =           21;\nenum R_ARM_JUMP_SLOT =          22;\nenum R_ARM_RELATIVE =           23;\nenum R_ARM_GOTOFF =             24;\nenum R_ARM_GOTPC =              25;\nenum R_ARM_GOT32 =              26;\nenum R_ARM_PLT32 =              27;\nenum R_ARM_GNU_VTENTRY =        100;\nenum R_ARM_GNU_VTINHERIT =      101;\nenum R_ARM_RSBREL32 =           250;\nenum R_ARM_THM_RPC22 =          251;\nenum R_ARM_RREL32 =             252;\nenum R_ARM_RABS32 =             253;\nenum R_ARM_RPC24 =              254;\nenum R_ARM_RBASE =              255;\n\nenum R_IA_64_NONE =             0;\nenum R_IA_64_IMM14 =            0x21;\nenum R_IA_64_IMM22 =            0x22;\nenum R_IA_64_IMM64 =            0x23;\nenum R_IA_64_DIR32MSB =         0x24;\nenum R_IA_64_DIR32LSB =         0x25;\nenum R_IA_64_DIR64MSB =         0x26;\nenum R_IA_64_DIR64LSB =         0x27;\nenum R_IA_64_GPREL22 =          0x2a;\nenum R_IA_64_GPREL64I =         0x2b;\nenum R_IA_64_GPREL32MSB =       0x2c;\nenum R_IA_64_GPREL32LSB =       0x2d;\nenum R_IA_64_GPREL64MSB =       0x2e;\nenum R_IA_64_GPREL64LSB =       0x2f;\nenum R_IA_64_LTOFF22 =          0x32;\nenum R_IA_64_LTOFF64I =         0x33;\nenum R_IA_64_PLTOFF22 =         0x3a;\nenum R_IA_64_PLTOFF64I =        0x3b;\nenum R_IA_64_PLTOFF64MSB =      0x3e;\nenum R_IA_64_PLTOFF64LSB =      0x3f;\nenum R_IA_64_FPTR64I =          0x43;\nenum R_IA_64_FPTR32MSB =        0x44;\nenum R_IA_64_FPTR32LSB =        0x45;\nenum R_IA_64_FPTR64MSB =        0x46;\nenum R_IA_64_FPTR64LSB =        0x47;\nenum R_IA_64_PCREL60B =         0x48;\nenum R_IA_64_PCREL21B =         0x49;\nenum R_IA_64_PCREL21M =         0x4a;\nenum R_IA_64_PCREL21F =         0x4b;\nenum R_IA_64_PCREL32MSB =       0x4c;\nenum R_IA_64_PCREL32LSB =       0x4d;\nenum R_IA_64_PCREL64MSB =       0x4e;\nenum R_IA_64_PCREL64LSB =       0x4f;\nenum R_IA_64_LTOFF_FPTR22 =     0x52;\nenum R_IA_64_LTOFF_FPTR64I =    0x53;\nenum R_IA_64_LTOFF_FPTR32MSB =  0x54;\nenum R_IA_64_LTOFF_FPTR32LSB =  0x55;\nenum R_IA_64_LTOFF_FPTR64MSB =  0x56;\nenum R_IA_64_LTOFF_FPTR64LSB =  0x57;\nenum R_IA_64_SEGREL32MSB =      0x5c;\nenum R_IA_64_SEGREL32LSB =      0x5d;\nenum R_IA_64_SEGREL64MSB =      0x5e;\nenum R_IA_64_SEGREL64LSB =      0x5f;\nenum R_IA_64_SECREL32MSB =      0x64;\nenum R_IA_64_SECREL32LSB =      0x65;\nenum R_IA_64_SECREL64MSB =      0x66;\nenum R_IA_64_SECREL64LSB =      0x67;\nenum R_IA_64_REL32MSB =         0x6c;\nenum R_IA_64_REL32LSB =         0x6d;\nenum R_IA_64_REL64MSB =         0x6e;\nenum R_IA_64_REL64LSB =         0x6f;\nenum R_IA_64_LTV32MSB =         0x74;\nenum R_IA_64_LTV32LSB =         0x75;\nenum R_IA_64_LTV64MSB =         0x76;\nenum R_IA_64_LTV64LSB =         0x77;\nenum R_IA_64_PCREL21BI =        0x79;\nenum R_IA_64_PCREL22 =          0x7a;\nenum R_IA_64_PCREL64I =         0x7b;\nenum R_IA_64_IPLTMSB =          0x80;\nenum R_IA_64_IPLTLSB =          0x81;\nenum R_IA_64_SUB =              0x85;\nenum R_IA_64_LTOFF22X =         0x86;\nenum R_IA_64_LDXMOV =           0x87;\nenum R_IA_64_TPREL14 =          0x91;\nenum R_IA_64_TPREL22 =          0x92;\nenum R_IA_64_TPREL64I =         0x93;\nenum R_IA_64_TPREL64MSB =       0x96;\nenum R_IA_64_TPREL64LSB =       0x97;\nenum R_IA_64_LTOFF_TPREL22 =    0x9a;\nenum R_IA_64_DTPMOD64MSB =      0xa6;\nenum R_IA_64_DTPMOD64LSB =      0xa7;\nenum R_IA_64_LTOFF_DTPMOD22 =   0xaa;\nenum R_IA_64_DTPREL14 =         0xb1;\nenum R_IA_64_DTPREL22 =         0xb2;\nenum R_IA_64_DTPREL64I =        0xb3;\nenum R_IA_64_DTPREL32MSB =      0xb4;\nenum R_IA_64_DTPREL32LSB =      0xb5;\nenum R_IA_64_DTPREL64MSB =      0xb6;\nenum R_IA_64_DTPREL64LSB =      0xb7;\nenum R_IA_64_LTOFF_DTPREL22 =   0xba;\n\nenum R_MIPS_NONE =              0;\nenum R_MIPS_16 =                1;\nenum R_MIPS_32 =                2;\nenum R_MIPS_REL32 =             3;\nenum R_MIPS_26 =                4;\nenum R_MIPS_HI16 =              5;\nenum R_MIPS_LO16 =              6;\nenum R_MIPS_GPREL16 =           7;\nenum R_MIPS_LITERAL =           8;\nenum R_MIPS_GOT16 =             9;\nenum R_MIPS_PC16 =              10;\nenum R_MIPS_CALL16 =            11;\nenum R_MIPS_GPREL32 =           12;\nenum R_MIPS_GOTHI16 =           21;\nenum R_MIPS_GOTLO16 =           22;\nenum R_MIPS_CALLHI16 =          30;\nenum R_MIPS_CALLLO16 =          31;\n\nenum R_PPC_NONE =               0;\nenum R_PPC_ADDR32 =             1;\nenum R_PPC_ADDR24 =             2;\nenum R_PPC_ADDR16 =             3;\nenum R_PPC_ADDR16_LO =          4;\nenum R_PPC_ADDR16_HI =          5;\nenum R_PPC_ADDR16_HA =          6;\nenum R_PPC_ADDR14 =             7;\nenum R_PPC_ADDR14_BRTAKEN =     8;\nenum R_PPC_ADDR14_BRNTAKEN =    9;\nenum R_PPC_REL24 =              10;\nenum R_PPC_REL14 =              11;\nenum R_PPC_REL14_BRTAKEN =      12;\nenum R_PPC_REL14_BRNTAKEN =     13;\nenum R_PPC_GOT16 =              14;\nenum R_PPC_GOT16_LO =           15;\nenum R_PPC_GOT16_HI =           16;\nenum R_PPC_GOT16_HA =           17;\nenum R_PPC_PLTREL24 =           18;\nenum R_PPC_COPY =               19;\nenum R_PPC_GLOB_DAT =           20;\nenum R_PPC_JMP_SLOT =           21;\nenum R_PPC_RELATIVE =           22;\nenum R_PPC_LOCAL24PC =          23;\nenum R_PPC_UADDR32 =            24;\nenum R_PPC_UADDR16 =            25;\nenum R_PPC_REL32 =              26;\nenum R_PPC_PLT32 =              27;\nenum R_PPC_PLTREL32 =           28;\nenum R_PPC_PLT16_LO =           29;\nenum R_PPC_PLT16_HI =           30;\nenum R_PPC_PLT16_HA =           31;\nenum R_PPC_SDAREL16 =           32;\nenum R_PPC_SECTOFF =            33;\nenum R_PPC_SECTOFF_LO =         34;\nenum R_PPC_SECTOFF_HI =         35;\nenum R_PPC_SECTOFF_HA =         36;\n\nenum R_PPC64_ADDR64 =           38;\nenum R_PPC64_ADDR16_HIGHER =    39;\nenum R_PPC64_ADDR16_HIGHERA =   40;\nenum R_PPC64_ADDR16_HIGHEST =   41;\nenum R_PPC64_ADDR16_HIGHESTA =  42;\nenum R_PPC64_UADDR64 =          43;\nenum R_PPC64_REL64 =            44;\nenum R_PPC64_PLT64 =            45;\nenum R_PPC64_PLTREL64 =         46;\nenum R_PPC64_TOC16 =            47;\nenum R_PPC64_TOC16_LO =         48;\nenum R_PPC64_TOC16_HI =         49;\nenum R_PPC64_TOC16_HA =         50;\nenum R_PPC64_TOC =              51;\nenum R_PPC64_DTPMOD64 =         68;\nenum R_PPC64_TPREL64 =          73;\nenum R_PPC64_DTPREL64 =         78;\n\nenum R_PPC_TLS =                67;\nenum R_PPC_DTPMOD32 =           68;\nenum R_PPC_TPREL16 =            69;\nenum R_PPC_TPREL16_LO =         70;\nenum R_PPC_TPREL16_HI =         71;\nenum R_PPC_TPREL16_HA =         72;\nenum R_PPC_TPREL32 =            73;\nenum R_PPC_DTPREL16 =           74;\nenum R_PPC_DTPREL16_LO =        75;\nenum R_PPC_DTPREL16_HI =        76;\nenum R_PPC_DTPREL16_HA =        77;\nenum R_PPC_DTPREL32 =           78;\nenum R_PPC_GOT_TLSGD16 =        79;\nenum R_PPC_GOT_TLSGD16_LO =     80;\nenum R_PPC_GOT_TLSGD16_HI =     81;\nenum R_PPC_GOT_TLSGD16_HA =     82;\nenum R_PPC_GOT_TLSLD16 =        83;\nenum R_PPC_GOT_TLSLD16_LO =     84;\nenum R_PPC_GOT_TLSLD16_HI =     85;\nenum R_PPC_GOT_TLSLD16_HA =     86;\nenum R_PPC_GOT_TPREL16 =        87;\nenum R_PPC_GOT_TPREL16_LO =     88;\nenum R_PPC_GOT_TPREL16_HI =     89;\nenum R_PPC_GOT_TPREL16_HA =     90;\n\nenum R_PPC_EMB_NADDR32 =        101;\nenum R_PPC_EMB_NADDR16 =        102;\nenum R_PPC_EMB_NADDR16_LO =     103;\nenum R_PPC_EMB_NADDR16_HI =     104;\nenum R_PPC_EMB_NADDR16_HA =     105;\nenum R_PPC_EMB_SDAI16 =         106;\nenum R_PPC_EMB_SDA2I16 =        107;\nenum R_PPC_EMB_SDA2REL =        108;\nenum R_PPC_EMB_SDA21 =          109;\nenum R_PPC_EMB_MRKREF =         110;\nenum R_PPC_EMB_RELSEC16 =       111;\nenum R_PPC_EMB_RELST_LO =       112;\nenum R_PPC_EMB_RELST_HI =       113;\nenum R_PPC_EMB_RELST_HA =       114;\nenum R_PPC_EMB_BIT_FLD =        115;\nenum R_PPC_EMB_RELSDA =         116;\n\nenum R_SPARC_NONE =             0;\nenum R_SPARC_8 =                1;\nenum R_SPARC_16 =               2;\nenum R_SPARC_32 =               3;\nenum R_SPARC_DISP8 =            4;\nenum R_SPARC_DISP16 =           5;\nenum R_SPARC_DISP32 =           6;\nenum R_SPARC_WDISP30 =          7;\nenum R_SPARC_WDISP22 =          8;\nenum R_SPARC_HI22 =             9;\nenum R_SPARC_22 =               10;\nenum R_SPARC_13 =               11;\nenum R_SPARC_LO10 =             12;\nenum R_SPARC_GOT10 =            13;\nenum R_SPARC_GOT13 =            14;\nenum R_SPARC_GOT22 =            15;\nenum R_SPARC_PC10 =             16;\nenum R_SPARC_PC22 =             17;\nenum R_SPARC_WPLT30 =           18;\nenum R_SPARC_COPY =             19;\nenum R_SPARC_GLOB_DAT =         20;\nenum R_SPARC_JMP_SLOT =         21;\nenum R_SPARC_RELATIVE =         22;\nenum R_SPARC_UA32 =             23;\nenum R_SPARC_PLT32 =            24;\nenum R_SPARC_HIPLT22 =          25;\nenum R_SPARC_LOPLT10 =          26;\nenum R_SPARC_PCPLT32 =          27;\nenum R_SPARC_PCPLT22 =          28;\nenum R_SPARC_PCPLT10 =          29;\nenum R_SPARC_10 =               30;\nenum R_SPARC_11 =               31;\nenum R_SPARC_64 =               32;\nenum R_SPARC_OLO10 =            33;\nenum R_SPARC_HH22 =             34;\nenum R_SPARC_HM10 =             35;\nenum R_SPARC_LM22 =             36;\nenum R_SPARC_PC_HH22 =          37;\nenum R_SPARC_PC_HM10 =          38;\nenum R_SPARC_PC_LM22 =          39;\nenum R_SPARC_WDISP16 =          40;\nenum R_SPARC_WDISP19 =          41;\nenum R_SPARC_GLOB_JMP =         42;\nenum R_SPARC_7 =                43;\nenum R_SPARC_5 =                44;\nenum R_SPARC_6 =                45;\nenum R_SPARC_DISP64 =           46;\nenum R_SPARC_PLT64 =            47;\nenum R_SPARC_HIX22 =            48;\nenum R_SPARC_LOX10 =            49;\nenum R_SPARC_H44 =              50;\nenum R_SPARC_M44 =              51;\nenum R_SPARC_L44 =              52;\nenum R_SPARC_REGISTER =         53;\nenum R_SPARC_UA64 =             54;\nenum R_SPARC_UA16 =             55;\nenum R_SPARC_TLS_GD_HI22 =      56;\nenum R_SPARC_TLS_GD_LO10 =      57;\nenum R_SPARC_TLS_GD_ADD =       58;\nenum R_SPARC_TLS_GD_CALL =      59;\nenum R_SPARC_TLS_LDM_HI22 =     60;\nenum R_SPARC_TLS_LDM_LO10 =     61;\nenum R_SPARC_TLS_LDM_ADD =      62;\nenum R_SPARC_TLS_LDM_CALL =     63;\nenum R_SPARC_TLS_LDO_HIX22 =    64;\nenum R_SPARC_TLS_LDO_LOX10 =    65;\nenum R_SPARC_TLS_LDO_ADD =      66;\nenum R_SPARC_TLS_IE_HI22 =      67;\nenum R_SPARC_TLS_IE_LO10 =      68;\nenum R_SPARC_TLS_IE_LD =        69;\nenum R_SPARC_TLS_IE_LDX =       70;\nenum R_SPARC_TLS_IE_ADD =       71;\nenum R_SPARC_TLS_LE_HIX22 =     72;\nenum R_SPARC_TLS_LE_LOX10 =     73;\nenum R_SPARC_TLS_DTPMOD32 =     74;\nenum R_SPARC_TLS_DTPMOD64 =     75;\nenum R_SPARC_TLS_DTPOFF32 =     76;\nenum R_SPARC_TLS_DTPOFF64 =     77;\nenum R_SPARC_TLS_TPOFF32 =      78;\nenum R_SPARC_TLS_TPOFF64 =      79;\n\nenum R_X86_64_NONE =            0;\nenum R_X86_64_64 =              1;\nenum R_X86_64_PC32 =            2;\nenum R_X86_64_GOT32 =           3;\nenum R_X86_64_PLT32 =           4;\nenum R_X86_64_COPY =            5;\nenum R_X86_64_GLOB_DAT =        6;\nenum R_X86_64_JMP_SLOT =        7;\nenum R_X86_64_RELATIVE =        8;\nenum R_X86_64_GOTPCREL =        9;\nenum R_X86_64_32 =              10;\nenum R_X86_64_32S =             11;\nenum R_X86_64_16 =              12;\nenum R_X86_64_PC16 =            13;\nenum R_X86_64_8 =               14;\nenum R_X86_64_PC8 =             15;\nenum R_X86_64_DTPMOD64 =        16;\nenum R_X86_64_DTPOFF64 =        17;\nenum R_X86_64_TPOFF64 =         18;\nenum R_X86_64_TLSGD =           19;\nenum R_X86_64_TLSLD =           20;\nenum R_X86_64_DTPOFF32 =        21;\nenum R_X86_64_GOTTPOFF =        22;\nenum R_X86_64_TPOFF32 =         23;\nenum R_X86_64_IRELATIVE =       37;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/netbsd/sys/event.d",
    "content": "/**\n * D header file for NetBSD.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n *\n * http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/sys/event.h\n */\n\n/*          Copyright Martin Nowak 2012.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.netbsd.sys.event;\n\nversion (NetBSD):\nextern (C):\n\nimport core.stdc.stdint;    // intptr_t, uintptr_t\nimport core.sys.posix.time; // timespec\n\n\nenum\n{\n    EVFILT_READ     =  0,\n    EVFILT_WRITE    =  1,\n    EVFILT_AIO      =  2,\n    EVFILT_VNODE    =  3,\n    EVFILT_PROC     =  4,\n    EVFILT_SIGNAL   =  5,\n    EVFILT_TIMER    =  6,\n    EVFILT_SYSCOUNT =  7\n}\n\nextern(D) void EV_SET(kevent_t* kevp, typeof(kevent_t.tupleof) args)\n{\n    *kevp = kevent_t(args);\n}\n\nstruct kevent_t\n{\n    uintptr_t    ident;\n    uint        filter;\n    uint        flags;\n    uint        fflags;\n    ulong       data;\n    void        *udata;\n}\n\nenum\n{\n    /* actions */\n    EV_ADD      = 0x0001,\n    EV_DELETE   = 0x0002,\n    EV_ENABLE   = 0x0004,\n    EV_DISABLE  = 0x0008,\n\n    /* flags */\n    EV_ONESHOT  = 0x0010,\n    EV_CLEAR    = 0x0020,\n\n    EV_SYSFLAGS = 0xF000,\n    EV_FLAG1    = 0x2000,\n\n    /* returned values */\n    EV_EOF      = 0x8000,\n    EV_ERROR    = 0x4000\n}\n\nenum\n{\n    /*\n     * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace\n     */\n    NOTE_LOWAT      = 0x0001,\n\n    /*\n     * data/hint flags for EVFILT_VNODE, shared with userspace\n     */\n    NOTE_DELETE     = 0x0001,\n    NOTE_WRITE      = 0x0002,\n    NOTE_EXTEND     = 0x0004,\n    NOTE_ATTRIB     = 0x0008,\n    NOTE_LINK       = 0x0010,\n    NOTE_RENAME     = 0x0020,\n    NOTE_REVOKE     = 0x0040,\n\n    /*\n     * data/hint flags for EVFILT_PROC, shared with userspace\n     */\n    NOTE_EXIT       = 0x80000000,\n    NOTE_FORK       = 0x40000000,\n    NOTE_EXEC       = 0x20000000,\n    NOTE_PCTRLMASK  = 0xf0000000,\n    NOTE_PDATAMASK  = 0x000fffff,\n\n    /* additional flags for EVFILT_PROC */\n    NOTE_TRACK      = 0x00000001,\n    NOTE_TRACKERR   = 0x00000002,\n    NOTE_CHILD      = 0x00000004\n\n}\n\nint kqueue();\nint __kevent50(int kq, const kevent_t *changelist, int nchanges,\n           kevent_t *eventlist, int nevents,\n           const timespec *timeout);\nalias kevent = __kevent50;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/netbsd/sys/link_elf.d",
    "content": "/**\n * D header file for NetBSD.\n *\n * http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/include/link_elf.h\n */\nmodule core.sys.netbsd.sys.link_elf;\n\nversion (NetBSD):\nextern (C):\nnothrow:\n\nimport core.stdc.stdint : uint64_t;\nimport core.sys.netbsd.sys.elf;\n\nversion (D_LP64)\n    enum __ELF_NATIVE_CLASS = 64;\nelse\n    enum __ELF_NATIVE_CLASS = 32;\n\ntemplate ElfW(string type)\n{\n    mixin(\"alias Elf\"~__ELF_NATIVE_CLASS.stringof~\"_\"~type~\" ElfW;\");\n}\n\nstruct link_map\n{\n    char*           l_addr;\n\n    version (MIPS32)\n        char*       l_offs;\n    version (MIPS64)\n        char*       l_offs;\n\n    char*           l_name;\n    void*           l_ld;\n    link_map*       l_next;\n    link_map*       l_prev;\n}\nalias link_map Link_map;\n\nenum\n{\n    RT_CONSISTENT,\n    RT_ADD,\n    RT_DELETE,\n}\n\nstruct r_debug\n{\n    int             r_version;\n    link_map*       r_map;\n    void function(r_debug*, link_map*) r_brk;\n};\n\nstruct dl_phdr_info\n{\n    ElfW!\"Addr\"     dlpi_addr;\n    char*           dlpi_name;\n    ElfW!\"Phdr\"*    dlpi_phdr;\n    ElfW!\"Half\"     dlpi_phnum;\n    uint64_t        dlpi_adds;\n    uint64_t        dlpi_subs;\n    size_t          dlpi_tls_modid;\n    void*           dlpi_tls_data;\n};\n\n\nprivate alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;\nprivate alias extern(C) int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_cb_ngc;\nextern int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data);\nextern int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/netbsd/sys/mman.d",
    "content": "/**\n * D header file for NetBSD\n *\n * Authors: Martin Nowak\n *\n * http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/sys/mman.h\n */\nmodule core.sys.netbsd.sys.mman;\n\nversion (NetBSD):\nextern (C):\nnothrow:\n\npublic import core.sys.posix.sys.mman;\nimport core.sys.posix.sys.types;\n\nenum __BSD_VISIBLE = true;\n\nstatic if (__BSD_VISIBLE)\n{\n    enum INHERIT_SHARE = 0;\n    enum INHERIT_COPY = 1;\n    enum INHERIT_NONE = 2;\n    enum INHERIT_DONATE_COPY = 3;\n    enum INHERIT_ZERO = 4;\n}\n\n// already in core.sys.posix.sys.mman\n// enum PROT_NONE = 0x00;\n// enum PROT_READ = 0x01;\n// enum PROT_WRITE = 0x02;\n// enum PROT_EXEC = 0x04;\n// enum MAP_SHARED = 0x0001;\n// enum MAP_PRIVATE = 0x0002;\nstatic if (__BSD_VISIBLE)\n    enum MAP_COPY = 0x0002;\n// enum MAP_FIXED = 0x0010;\n\nstatic if (__BSD_VISIBLE)\n{\n    enum MAP_RENAME = 0x0020;\n    enum MAP_NORESERVE = 0x0040;\n    enum MAP_HASSEMAPHORE = 0x0200;\n    enum MAP_STACK = 0x2000;\n    enum MAP_WIRED = 0x0800;\n\n    enum MAP_FILE = 0x0000;\n\n    // already in core.sys.posix.sys.mman\n    // enum MAP_ANON = 0x1000;\n    //#ifndef _KERNEL\n    alias MAP_ANONYMOUS = MAP_ANON;\n    //#endif /* !_KERNEL */\n\n\n    extern(D) int MAP_ALIGNED(int n) { return n << MAP_ALIGNMENT_SHIFT; }\n    enum MAP_ALIGNMENT_SHIFT = 24;\n    enum MAP_ALIGNMENT_MASK = MAP_ALIGNED(0xff);\n}\n\n//static if (__POSIX_VISIBLE >= 199309)\n//{\n    // already in core.sys.posix.sys.mman\n    // enum MCL_CURRENT = 0x0001;\n    // enum MCL_FUTURE = 0x0002;\n//}\n\n// already in core.sys.posix.sys.mman\nenum MAP_FAILED = cast(void*)-1;\n\n// already in core.sys.posix.sys.mman\n// enum MS_SYNC = 0x0000;\n// enum MS_ASYNC = 0x0001;\n// enum MS_INVALIDATE = 0x0002;\n\nenum _MADV_NORMAL = 0;\nenum _MADV_RANDOM = 1;\nenum _MADV_SEQUENTIAL = 2;\nenum _MADV_WILLNEED = 3;\nenum _MADV_DONTNEED = 4;\n\nstatic if (__BSD_VISIBLE)\n{\n    alias MADV_NORMAL = _MADV_NORMAL;\n    alias MADV_RANDOM = _MADV_RANDOM;\n    alias MADV_SEQUENTIAL = _MADV_SEQUENTIAL;\n    alias MADV_WILLNEED = _MADV_WILLNEED;\n    alias MADV_DONTNEED = _MADV_DONTNEED;\n    enum MADV_SPACEAVAIL = 5;\n    enum MADV_FREE = 6;\n}\n\n//static if (__POSIX_VISIBLE >= 200112)\n//{\n    // already in core.sys.posix.sys.mman\n    // alias POSIX_MADV_NORMAL = _MADV_NORMAL;\n    // alias POSIX_MADV_RANDOM = _MADV_RANDOM;\n    // alias POSIX_MADV_SEQUENTIAL = _MADV_SEQUENTIAL;\n    // alias POSIX_MADV_WILLNEED = _MADV_WILLNEED;\n    // alias POSIX_MADV_DONTNEED = _MADV_DONTNEED;\n//}\n\nstatic if (__BSD_VISIBLE)\n{\n    //int getpagesizes(size_t *, int);\n    int madvise(void *, size_t, int);\n    int mincore(const(void) *, size_t, char *);\n    int minherit(void *, size_t, int);\n}\n// already in core.sys.posix.sys.mman\n// int mlock(const void *, size_t);\n// void *  mmap(void *, size_t, int, int, int, off_t);\n// int mprotect(const void *, size_t, int);\n// int msync(void *, size_t, int);\n// int munlock(const void *, size_t);\n// int munmap(void *, size_t);\n//static if (__POSIX_VISIBLE >= 200112)\n    // int posix_madvise(void *, size_t, int);\n//static if (__POSIX_VISIBLE >= 199309)\n//{\n    // int mlockall(int);\n    // int munlockall();\n    // int shm_open(const(char) *, int, mode_t);\n    // int shm_unlink(const(char) *);\n//}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/netbsd/time.d",
    "content": "//Written in the D programming language\n\n/++\n    D header file for NetBSD's extensions to POSIX's time.h.\n\n    Copyright: Copyright 2014\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n\n    http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/sys/time.h\n +/\nmodule core.sys.netbsd.time;\n\npublic import core.sys.posix.time;\n\nversion (NetBSD):\n\nenum CLOCK_REALTIME          = 0;\nenum CLOCK_VIRTUAL           = 1;\nenum CLOCK_PROF              = 2;\nenum CLOCK_MONOTONIC         = 3;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/openbsd/dlfcn.d",
    "content": "/**\n * D header file for OpenBSD.\n *\n * $(LINK2 http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/include/link_elf.h?rev=1.6&content-type=text/x-cvsweb-markup, dlfcn.h)\n */\nmodule core.sys.openbsd.dlfcn;\n\npublic import core.sys.posix.dlfcn;\n\nversion (OpenBSD):\nextern (C):\nnothrow:\n\nstatic assert(RTLD_LAZY   == 1);\nstatic assert(RTLD_NOW    == 2);\nstatic assert(RTLD_GLOBAL == 0x100);\nstatic assert(RTLD_LOCAL  == 0);\nenum RTLD_TRACE           =  0x200;\n\nenum RTLD_NEXT    = cast(void *)-1;\nenum RTLD_DEFAULT = cast(void *)-2;\nenum RTLD_SELF    = cast(void *)-3;\n\nenum DL_GETERRNO     = 1;\nenum DL_SETTHREADLCK = 2;\nenum DL_SETBINDLCK   = 3;\n\nenum DL_LAZY         = RTLD_LAZY;\n\nint dlctl(void *, int, void *);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/execinfo.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.execinfo) instead. This module\n *       will be removed in June 2018.)\n *\n * D header file for OSX.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Martin Nowak\n */\nmodule core.sys.osx.execinfo;\n\npublic import core.sys.darwin.execinfo;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/mach/dyld.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.mach.dyld) instead. This module\n *       will be removed in June 2018.)\n *\n * Copyright: Copyright Digital Mars 2010.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Jacob Carlborg\n * Version: Initial created: Feb 20, 2010\n */\n\n/*          Copyright Digital Mars 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.osx.mach.dyld;\n\npublic import core.sys.darwin.mach.dyld;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/mach/getsect.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.mach.getsect) instead. This\n *       module will be removed in June 2018.)\n *\n * Copyright: Copyright Digital Mars 2010.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Jacob Carlborg\n * Version: Initial created: Mar 16, 2010\n */\n\n/*          Copyright Digital Mars 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.osx.mach.getsect;\n\npublic import core.sys.darwin.mach.getsect;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/mach/kern_return.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.mach.kern_return) instead. This\n *       module will be removed in June 2018.)\n *\n * D header file for OSX.\n *\n * Copyright: Copyright Sean Kelly 2008 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n */\n\n/*          Copyright Sean Kelly 2008 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.osx.mach.kern_return;\n\npublic import core.sys.darwin.mach.kern_return;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/mach/loader.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.mach.loader) instead. This module\n *       will be removed in June 2018.)\n *\n * Copyright: Copyright Digital Mars 2010.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Jacob Carlborg\n * Version: Initial created: Feb 20, 2010\n */\n\n/*          Copyright Digital Mars 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.osx.mach.loader;\n\npublic import core.sys.darwin.mach.loader;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/mach/port.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.mach.port) instead. This module\n *       will be removed in June 2018.)\n *\n * D header file for OSX.\n *\n * Copyright: Copyright Sean Kelly 2008 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n */\n\n/*          Copyright Sean Kelly 2008 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.osx.mach.port;\n\npublic import core.sys.darwin.mach.port;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/mach/semaphore.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.mach.semaphore) instead. This\n *       module will be removed in June 2018.)\n *\n * D header file for OSX.\n *\n * Copyright: Copyright Sean Kelly 2008 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n */\n\n/*          Copyright Sean Kelly 2008 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.osx.mach.semaphore;\n\npublic import core.sys.darwin.mach.semaphore;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/mach/thread_act.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.mach.thread_act) instead. This\n *       module will be removed in June 2018.)\n *\n * D header file for OSX.\n *\n * Copyright: Copyright Sean Kelly 2008 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n */\n\n/*          Copyright Sean Kelly 2008 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.osx.mach.thread_act;\n\npublic import core.sys.darwin.mach.thread_act;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/pthread.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.pthread) instead. This module\n *       will be removed in June 2018.)\n *\n * D header file for OSX.\n *\n * Copyright: Copyright Sean Kelly 2008 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n */\n\n/*          Copyright Sean Kelly 2008 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.osx.pthread;\n\npublic import core.sys.darwin.pthread;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/sys/cdefs.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.sys.cdefs) instead. This module\n *       will be removed in June 2018.)\n *\n * D header file for OSX\n *\n * Authors: Martin Nowak\n */\nmodule core.sys.osx.sys.cdefs;\n\npublic import core.sys.darwin.sys.cdefs;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/sys/event.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.sys.event) instead. This module\n *       will be removed in June 2018.)\n *\n * D header file for OSX.\n *\n * Copyright: Copyright Martin Nowak 2012. Etienne Cimon 2015.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n */\n\n/*          Copyright Martin Nowak 2012. Etienne Cimon 2015.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.osx.sys.event;\n\npublic import core.sys.darwin.sys.event;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/osx/sys/mman.d",
    "content": "/**\n * $(RED Deprecated. Use $(D core.sys.darwin.sys.mman) instead. This module\n *       will be removed in June 2018.)\n *\n * D header file for OSX\n *\n * Authors: Martin Nowak\n */\nmodule core.sys.osx.sys.mman;\n\npublic import core.sys.darwin.sys.mman;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/aio.d",
    "content": "/**\n * D header file to interface with the\n * $(HTTP pubs.opengroup.org/onlinepubs/9699919799/basedefs/aio.h.html, Posix AIO API).\n *\n * Copyright: Copyright D Language Foundation 2018.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   $(HTTPS github.com/darredevil, Alexandru Razvan Caciulescu)\n */\nmodule core.sys.posix.aio;\n\nprivate import core.sys.posix.signal;\nprivate import core.sys.posix.sys.types;\n\nversion (Posix):\n\nextern (C):\n@system:\n@nogc:\nnothrow:\n\nversion (CRuntime_Glibc)\n{\n    import core.sys.posix.config;\n\n    struct aiocb\n    {\n        int aio_fildes;\n        int aio_lio_opcode;\n        int aio_reqprio;\n        void* aio_buf;   //volatile\n        size_t aio_nbytes;\n        sigevent aio_sigevent;\n\n        aiocb* __next_prio;\n        int __abs_prio;\n        int __policy;\n        int __error_code;\n        ssize_t __return_value;\n\n        off_t aio_offset;\n        ubyte[32] __glibc_reserved;\n    }\n\n    static if (__USE_LARGEFILE64)\n    {\n        struct aiocb64\n        {\n            int aio_fildes;\n            int aio_lio_opcode;\n            int aio_reqprio;\n            void* aio_buf;   //volatile\n            size_t aio_nbytes;\n            sigevent aio_sigevent;\n\n            aiocb* __next_prio;\n            int __abs_prio;\n            int __policy;\n            int __error_code;\n            ssize_t __return_value;\n\n            off_t aio_offset;\n            ubyte[32] __glibc_reserved;\n        }\n    }\n}\nelse version (OSX)\n{\n    struct aiocb\n    {\n        int aio_filedes;\n        off_t aio_offset;\n        void* aio_buf;   // volatile\n        size_t aio_nbytes;\n        int reqprio;\n        sigevent aio_sigevent;\n        int aio_lio_opcode;\n    }\n}\nelse version (FreeBSD)\n{\n    struct __aiocb_private\n    {\n        long status;\n        long error;\n        void* kernelinfo;\n    }\n\n    struct aiocb\n    {\n        int aio_fildes;\n        off_t aio_offset;\n        void* aio_buf;   // volatile\n        size_t aio_nbytes;\n        private int[2] __spare;\n        private void* _spare2__;\n        int aio_lio_opcode;\n        int aio_reqprio;\n        private __aiocb_private _aiocb_private;\n        sigevent aio_sigevent;\n    }\n\n    version = BSD_Posix;\n}\nelse version (NetBSD)\n{\n    struct aiocb\n    {\n        off_t aio_offset;\n        void* aio_buf;   // volatile\n        size_t aio_nbytes;\n        int aio_fildes;\n        int aio_lio_opcode;\n        int aio_reqprio;\n        sigevent aio_sigevent;\n        private int _state;\n        private int _errno;\n        private ssize_t _retval;\n    }\n\n    version = BSD_Posix;\n}\nelse version (DragonFlyBSD)\n{\n    struct aiocb\n    {\n        int aio_fildes;\n        off_t aio_offset;\n        void* aio_buf;   // volatile\n        size_t aio_nbytes;\n        sigevent aio_sigevent;\n        int aio_lio_opcode;\n        int aio_reqprio;\n        private int _aio_val;\n        private int _aio_err;\n    }\n\n    version = BSD_Posix;\n}\nelse\n    static assert(false, \"Unsupported platform\");\n\n/* Return values of cancelation function.  */\nversion (CRuntime_Glibc)\n{\n    enum\n    {\n        AIO_CANCELED,\n        AIO_NOTCANCELED,\n        AIO_ALLDONE\n    }\n}\nelse version (OSX)\n{\n    enum\n    {\n        AIO_ALLDONE = 0x1,\n        AIO_CANCELED = 0x2,\n        AIO_NOTCANCELED = 0x4,\n    }\n}\nelse version (BSD_Posix)\n{\n    enum\n    {\n        AIO_CANCELED,\n        AIO_NOTCANCELED,\n        AIO_ALLDONE\n    }\n}\n\n/* Operation codes for `aio_lio_opcode'.  */\nversion (CRuntime_Glibc)\n{\n    enum\n    {\n        LIO_READ,\n        LIO_WRITE,\n        LIO_NOP\n    }\n}\nelse version (OSX)\n{\n    enum\n    {\n        LIO_NOP = 0x0,\n        LIO_READ = 0x1,\n        LIO_WRITE = 0x2,\n    }\n}\nelse version (BSD_Posix)\n{\n    enum\n    {\n        LIO_NOP,\n        LIO_WRITE,\n        LIO_READ\n    }\n}\n\n/* Synchronization options for `lio_listio' function.  */\nversion (CRuntime_Glibc)\n{\n    enum\n    {\n        LIO_WAIT,\n        LIO_NOWAIT\n    }\n}\nelse version (OSX)\n{\n    enum\n    {\n        LIO_NOWAIT = 0x1,\n        LIO_WAIT = 0x2,\n    }\n}\nelse version (BSD_Posix)\n{\n    enum\n    {\n        LIO_NOWAIT,\n        LIO_WAIT\n    }\n}\n\n/* Functions implementing POSIX AIO.  */\nversion (CRuntime_Glibc)\n{\n    static if (__USE_LARGEFILE64)\n    {\n        int aio_read64(aiocb64* aiocbp);\n        int aio_write64(aiocb64* aiocbp);\n        int aio_fsync64(int op, aiocb64* aiocbp);\n        int aio_error64(const(aiocb64)* aiocbp);\n        ssize_t aio_return64(aiocb64* aiocbp);\n        int aio_suspend64(const(aiocb64*)* aiocb_list, int nitems, const(timespec)* timeout);\n        int aio_cancel64(int fd, aiocb64* aiocbp);\n        int lio_listio64(int mode, const(aiocb64*)* aiocb_list, int nitems, sigevent* sevp);\n\n        alias aio_read = aio_read64;\n        alias aio_write = aio_write64;\n        alias aio_fsync = aio_fsync64;\n        alias aio_error = aio_error64;\n        alias aio_return = aio_return64;\n        alias aio_suspend = aio_suspend64;\n        alias aio_cancel = aio_cancel64;\n        alias lio_listio = lio_listio64;\n    }\n    else\n    {\n        int aio_read(aiocb* aiocbp);\n        int aio_write(aiocb* aiocbp);\n        int aio_fsync(int op, aiocb* aiocbp);\n        int aio_error(const(aiocb)* aiocbp);\n        ssize_t aio_return(aiocb* aiocbp);\n        int aio_suspend(const(aiocb*)* aiocb_list, int nitems, const(timespec)* timeout);\n        int aio_cancel(int fd, aiocb* aiocbp);\n        int lio_listio(int mode, const(aiocb*)* aiocb_list, int nitems, sigevent* sevp);\n    }\n}\nelse\n{\n    int aio_read(aiocb* aiocbp);\n    int aio_write(aiocb* aiocbp);\n    int aio_fsync(int op, aiocb* aiocbp);\n    int aio_error(const(aiocb)* aiocbp);\n    ssize_t aio_return(aiocb* aiocbp);\n    int aio_suspend(const(aiocb*)* aiocb_list, int nitems, const(timespec)* timeout);\n    int aio_cancel(int fd, aiocb* aiocbp);\n    int lio_listio(int mode, const(aiocb*)* aiocb_list, int nitems, sigevent* sevp);\n}\n\n/* Functions outside/extending POSIX requirement.  */\nversion (CRuntime_Glibc)\n{\n    static if (__USE_GNU)\n    {\n        /* To customize the implementation one can use the following struct.  */\n        struct aioinit\n        {\n            int aio_threads;\n            int aio_num;\n            int aio_locks;\n            int aio_usedba;\n            int aio_debug;\n            int aio_numusers;\n            int aio_idle_time;\n            int aio_reserved;\n        }\n\n        void aio_init(const(aioinit)* init);\n    }\n}\nelse version (FreeBSD)\n{\n    int aio_waitcomplete(aiocb** aiocb_list, const(timespec)* timeout);\n    int aio_mlock(aiocb* aiocbp);\n}\nelse version (DragonFlyBSD)\n{\n    int aio_waitcomplete(aiocb** aiocb_list, const(timespec)* timeout);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/arpa/inet.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.arpa.inet;\n\nprivate import core.sys.posix.config;\npublic import core.stdc.inttypes; // for uint32_t, uint16_t\npublic import core.sys.posix.sys.socket; // for socklen_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// Required\n//\n/*\nNOTE: The following must must be defined in core.sys.posix.arpa.inet to break\n      a circular import: in_port_t, in_addr_t, struct in_addr, INET_ADDRSTRLEN.\n\nin_port_t // from core.sys.posix.netinet.in_\nin_addr_t // from core.sys.posix.netinet.in_\n\nstruct in_addr  // from core.sys.posix.netinet.in_\nINET_ADDRSTRLEN // from core.sys.posix.netinet.in_\n\nuint32_t // from core.stdc.inttypes\nuint16_t // from core.stdc.inttypes\n\nuint32_t htonl(uint32_t);\nuint16_t htons(uint16_t);\nuint32_t ntohl(uint32_t);\nuint16_t ntohs(uint16_t);\n\nin_addr_t inet_addr(in char*);\nchar*     inet_ntoa(in_addr);\n// per spec: const char* inet_ntop(int, const void*, char*, socklen_t);\nchar*     inet_ntop(int, in void*, char*, socklen_t);\nint       inet_pton(int, in char*, void*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    alias uint16_t in_port_t;\n    alias uint32_t in_addr_t;\n\n    struct in_addr\n    {\n        in_addr_t s_addr;\n    }\n\n    enum INET_ADDRSTRLEN = 16;\n\n    @trusted pure\n    {\n    uint32_t htonl(uint32_t);\n    uint16_t htons(uint16_t);\n    uint32_t ntohl(uint32_t);\n    uint16_t ntohs(uint16_t);\n    }\n\n    in_addr_t       inet_addr(in char*);\n    char*           inet_ntoa(in_addr);\n    const(char)*    inet_ntop(int, in void*, char*, socklen_t);\n    int             inet_pton(int, in char*, void*);\n}\nelse version (Darwin)\n{\n    alias uint16_t in_port_t;\n    alias uint32_t in_addr_t;\n\n    struct in_addr\n    {\n        in_addr_t s_addr;\n    }\n\n    enum INET_ADDRSTRLEN = 16;\n\n    @trusted pure\n    {\n    uint32_t htonl(uint32_t);\n    uint16_t htons(uint16_t);\n    uint32_t ntohl(uint32_t);\n    uint16_t ntohs(uint16_t);\n    }\n\n    in_addr_t       inet_addr(in char*);\n    char*           inet_ntoa(in_addr);\n    const(char)*    inet_ntop(int, in void*, char*, socklen_t);\n    int             inet_pton(int, in char*, void*);\n}\nelse version (FreeBSD)\n{\n    alias uint16_t in_port_t;\n    alias uint32_t in_addr_t;\n\n    struct in_addr\n    {\n        in_addr_t s_addr;\n    }\n\n    enum INET_ADDRSTRLEN = 16;\n\n    @trusted pure\n    {\n    uint32_t htonl(uint32_t);\n    uint16_t htons(uint16_t);\n    uint32_t ntohl(uint32_t);\n    uint16_t ntohs(uint16_t);\n    }\n\n    in_addr_t       inet_addr(in char*);\n    char*           inet_ntoa(in_addr);\n    const(char)*    inet_ntop(int, in void*, char*, socklen_t);\n    int             inet_pton(int, in char*, void*);\n}\nelse version (NetBSD)\n{\n    alias uint16_t in_port_t;\n    alias uint32_t in_addr_t;\n\n    struct in_addr\n    {\n        in_addr_t s_addr;\n    }\n\n    enum INET_ADDRSTRLEN = 16;\n\n    @trusted pure\n    {\n    uint32_t htonl(uint32_t);\n    uint16_t htons(uint16_t);\n    uint32_t ntohl(uint32_t);\n    uint16_t ntohs(uint16_t);\n    }\n\n    in_addr_t       inet_addr(in char*);\n    char*           inet_ntoa(in_addr);\n    const(char)*    inet_ntop(int, in void*, char*, socklen_t);\n    int             inet_pton(int, in char*, void*);\n}\nelse version (DragonFlyBSD)\n{\n    alias uint16_t in_port_t;\n    alias uint32_t in_addr_t;\n\n    struct in_addr\n    {\n        in_addr_t s_addr;\n    }\n\n    enum INET_ADDRSTRLEN = 16;\n\n    @trusted pure\n    {\n    uint32_t htonl(uint32_t);\n    uint16_t htons(uint16_t);\n    uint32_t ntohl(uint32_t);\n    uint16_t ntohs(uint16_t);\n    }\n\n    in_addr_t       inet_addr(in char*);\n    char*           inet_ntoa(in_addr);\n    const(char)*    inet_ntop(int, in void*, char*, socklen_t);\n    int             inet_pton(int, in char*, void*);\n}\nelse version (Solaris)\n{\n    alias uint16_t in_port_t;\n    alias uint32_t in_addr_t;\n\n    struct in_addr\n    {\n        in_addr_t s_addr;\n    }\n    enum INET_ADDRSTRLEN = 16;\n\n    @trusted pure\n    {\n    uint32_t htonl(uint32_t);\n    uint16_t htons(uint16_t);\n    uint32_t ntohl(uint32_t);\n    uint16_t ntohs(uint16_t);\n    }\n\n    in_addr_t       inet_addr(in char*);\n    char*           inet_ntoa(in_addr);\n    const(char)*    inet_ntop(int, in void*, char*, socklen_t);\n    int             inet_pton(int, in char*, void*);\n}\nelse version (CRuntime_Bionic)\n{\n    alias uint32_t in_addr_t;\n\n    struct in_addr\n    {\n        in_addr_t s_addr;\n    }\n\n    enum INET_ADDRSTRLEN = 16;\n\n    @safe pure extern (D)\n    {\n        private\n        {\n            uint32_t __swap32( uint32_t x )\n            {\n                uint32_t byte32_swap = (x & 0xff) << 24 | (x &0xff00) << 8 |\n                                     (x & 0xff0000) >> 8 | (x & 0xff000000) >> 24;\n                return byte32_swap;\n            }\n\n            uint16_t __swap16( uint16_t x )\n            {\n                uint16_t byte16_swap = (x & 0xff) << 8 | (x & 0xff00) >> 8;\n                return byte16_swap;\n            }\n        }\n\n        uint32_t htonl(uint32_t x) { return __swap32(x); }\n        uint16_t htons(uint16_t x) { return __swap16(x); }\n        uint32_t ntohl(uint32_t x) { return __swap32(x); }\n        uint16_t ntohs(uint16_t x) { return __swap16(x); }\n    }\n\n    in_addr_t       inet_addr(in char*);\n    char*           inet_ntoa(in_addr);\n    const(char)*    inet_ntop(int, in void*, char*, size_t);\n    int             inet_pton(int, in char*, void*);\n}\nelse version (CRuntime_Musl)\n{\n    alias uint16_t in_port_t;\n    alias uint32_t in_addr_t;\n\n    struct in_addr\n    {\n        in_addr_t s_addr;\n    }\n\n    enum INET_ADDRSTRLEN = 16;\n\n    @trusted pure\n    {\n    uint32_t htonl(uint32_t);\n    uint16_t htons(uint16_t);\n    uint32_t ntohl(uint32_t);\n    uint16_t ntohs(uint16_t);\n    }\n\n    in_addr_t       inet_addr(in char*);\n    char*           inet_ntoa(in_addr);\n    const(char)*    inet_ntop(int, in void*, char*, socklen_t);\n    int             inet_pton(int, in char*, void*);\n}\nelse version (CRuntime_UClibc)\n{\n    alias uint16_t in_port_t;\n    alias uint32_t in_addr_t;\n\n    struct in_addr\n    {\n        in_addr_t s_addr;\n    }\n\n    enum INET_ADDRSTRLEN = 16;\n\n    @trusted pure\n    {\n    uint32_t htonl(uint32_t);\n    uint16_t htons(uint16_t);\n    uint32_t ntohl(uint32_t);\n    uint16_t ntohs(uint16_t);\n    }\n\n    in_addr_t       inet_addr(in char*);\n    char*           inet_ntoa(in_addr);\n    const(char)*    inet_ntop(int, in void*, char*, socklen_t);\n    int             inet_pton(int, in char*, void*);\n}\n\n//\n// IPV6 (IP6)\n//\n/*\nNOTE: The following must must be defined in core.sys.posix.arpa.inet to break\n      a circular import: INET6_ADDRSTRLEN.\n\nINET6_ADDRSTRLEN // from core.sys.posix.netinet.in_\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum INET6_ADDRSTRLEN = 46;\n}\nelse version (Darwin)\n{\n    enum INET6_ADDRSTRLEN = 46;\n}\nelse version (FreeBSD)\n{\n    enum INET6_ADDRSTRLEN = 46;\n}\nelse version (NetBSD)\n{\n    enum INET6_ADDRSTRLEN = 46;\n}\nelse version (DragonFlyBSD)\n{\n    enum INET6_ADDRSTRLEN = 46;\n}\nelse version (Solaris)\n{\n    enum INET6_ADDRSTRLEN = 46;\n}\nelse version (CRuntime_Bionic)\n{\n    enum INET6_ADDRSTRLEN = 46;\n}\nelse version (CRuntime_UClibc)\n{\n    enum INET6_ADDRSTRLEN = 46;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/config.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly,\n              Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.config;\n\npublic import core.stdc.config;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\nenum _XOPEN_SOURCE     = 600;\nenum _POSIX_SOURCE     = true;\nenum _POSIX_C_SOURCE   = 200112L;\n\nversion (CRuntime_Glibc)\n{\n    // man 7 feature_test_macros\n    // http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html\n    enum _GNU_SOURCE         = false;\n    enum _DEFAULT_SOURCE     = false;\n    enum _ATFILE_SOURCE      = false;\n\n    // _BSD_SOURCE and _SVID_SOURCE are deprecated aliases for _DEFAULT_SOURCE.\n    deprecated(\"use _DEFAULT_SOURCE\")\n    {\n        enum _BSD_SOURCE = false;\n        enum _SVID_SOURCE = false;\n    }\n\n    enum _FILE_OFFSET_BITS   = 64;\n    // <sys/cdefs.h>\n    enum __REDIRECT          = false;\n\n    enum _REENTRANT          = true; // set by compiler when linking -pthread\n\n    // deduced <features.h>\n    enum __USE_FILE_OFFSET64 = _FILE_OFFSET_BITS == 64;\n    enum __USE_LARGEFILE     = __USE_FILE_OFFSET64 && !__REDIRECT;\n    enum __USE_LARGEFILE64   = __USE_FILE_OFFSET64 && !__REDIRECT;\n\n    enum __USE_XOPEN2K       = _XOPEN_SOURCE >= 600;\n    enum __USE_XOPEN2KXSI    = _XOPEN_SOURCE >= 600;\n    enum __USE_XOPEN2K8      = _XOPEN_SOURCE >= 700;\n    enum __USE_XOPEN2K8XSI   = _XOPEN_SOURCE >= 700;\n\n    enum __USE_MISC          = _DEFAULT_SOURCE;\n    enum __USE_ATFILE        = _ATFILE_SOURCE;\n    enum __USE_GNU           = _GNU_SOURCE;\n    enum __USE_REENTRANT     = _REENTRANT;\n\n    version (D_LP64)\n        enum __WORDSIZE=64;\n    else\n        enum __WORDSIZE=32;\n}\nelse version (CRuntime_Musl)\n{\n    enum _FILE_OFFSET_BITS   = 64;\n\n    enum __REDIRECT          = false;\n\n    enum __USE_FILE_OFFSET64 = _FILE_OFFSET_BITS == 64;\n    enum __USE_LARGEFILE     = __USE_FILE_OFFSET64 && !__REDIRECT;\n    enum __USE_LARGEFILE64   = __USE_FILE_OFFSET64 && !__REDIRECT;\n\n    enum __WORDSIZE=64;\n}\nelse version (CRuntime_UClibc)\n{\n    enum _GNU_SOURCE         = false;\n    enum _DEFAULT_SOURCE     = false;\n    enum _ATFILE_SOURCE      = false;\n\n    enum _FILE_OFFSET_BITS   = 64;\n    enum __REDIRECT          = false;\n\n    enum _REENTRANT          = true;\n\n    enum __USE_FILE_OFFSET64 = _FILE_OFFSET_BITS == 64;\n    enum __USE_LARGEFILE     = __USE_FILE_OFFSET64 && !__REDIRECT;\n    enum __USE_LARGEFILE64   = __USE_FILE_OFFSET64 && !__REDIRECT;\n\n    enum __USE_XOPEN2K       = _XOPEN_SOURCE >= 600;\n    enum __USE_XOPEN2KXSI    = _XOPEN_SOURCE >= 600;\n    enum __USE_XOPEN2K8      = _XOPEN_SOURCE >= 700;\n    enum __USE_XOPEN2K8XSI   = _XOPEN_SOURCE >= 700;\n\n    enum __USE_MISC          = _DEFAULT_SOURCE;\n    enum __USE_ATFILE        = _ATFILE_SOURCE;\n    enum __USE_GNU           = _GNU_SOURCE;\n    enum __USE_REENTRANT     = _REENTRANT;\n\n    version (D_LP64)\n        enum __WORDSIZE=64;\n    else\n        enum __WORDSIZE=32;\n}\nelse version (Solaris)\n{\n    enum _FILE_OFFSET_BITS = 64;\n    enum __REDIRECT = false;\n\n    enum __USE_FILE_OFFSET64 = _FILE_OFFSET_BITS == 64;\n    enum __USE_LARGEFILE = __USE_FILE_OFFSET64 && !__REDIRECT;\n    enum __USE_LARGEFILE64 = __USE_FILE_OFFSET64 && !__REDIRECT;\n\n    enum __USE_XOPEN2K = _XOPEN_SOURCE >= 600;\n    enum __USE_XOPEN2KXSI = _XOPEN_SOURCE >= 600;\n    enum __USE_XOPEN2K8 = _XOPEN_SOURCE >= 700;\n    enum __USE_XOPEN2K8XSI = _XOPEN_SOURCE >= 700;\n\n    version (D_LP64)\n        enum __WORDSIZE = 64;\n    else\n        enum __WORDSIZE = 32;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/dirent.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly,\n              Alex Rønne Petersn\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.dirent;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types; // for ino_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// Required\n//\n/*\nDIR\n\nstruct dirent\n{\n    char[] d_name;\n}\n\nint     closedir(DIR*);\nDIR*    opendir(in char*);\ndirent* readdir(DIR*);\nvoid    rewinddir(DIR*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    // NOTE: The following constants are non-standard Linux definitions\n    //       for dirent.d_type.\n    enum\n    {\n        DT_UNKNOWN  = 0,\n        DT_FIFO     = 1,\n        DT_CHR      = 2,\n        DT_DIR      = 4,\n        DT_BLK      = 6,\n        DT_REG      = 8,\n        DT_LNK      = 10,\n        DT_SOCK     = 12,\n        DT_WHT      = 14\n    }\n\n    struct dirent\n    {\n        ino_t       d_ino;\n        off_t       d_off;\n        ushort      d_reclen;\n        ubyte       d_type;\n        char[256]   d_name;\n    }\n\n    struct DIR\n    {\n        // Managed by OS\n    }\n\n    static if ( __USE_FILE_OFFSET64 )\n    {\n        dirent* readdir64(DIR*);\n        alias   readdir64 readdir;\n    }\n    else\n    {\n        dirent* readdir(DIR*);\n    }\n}\nelse version (Darwin)\n{\n    enum\n    {\n        DT_UNKNOWN  = 0,\n        DT_FIFO     = 1,\n        DT_CHR      = 2,\n        DT_DIR      = 4,\n        DT_BLK      = 6,\n        DT_REG      = 8,\n        DT_LNK      = 10,\n        DT_SOCK     = 12,\n        DT_WHT      = 14\n    }\n\n    // _DARWIN_FEATURE_64_BIT_INODE dirent is default for Mac OSX >10.5 and is\n    // only meaningful type for other OS X/Darwin variants (e.g. iOS).\n    // man dir(5) has some info, man stat(2) gives details.\n    struct dirent\n    {\n        ino_t       d_ino;\n        alias       d_fileno = d_ino;\n        ulong       d_seekoff;\n        ushort      d_reclen;\n        ushort      d_namlen;\n        ubyte       d_type;\n        char[1024]  d_name;\n    }\n\n    struct DIR\n    {\n        // Managed by OS\n    }\n\n    // OS X maintains backwards compatibility with older binaries using 32-bit\n    // inode functions by appending $INODE64 to newer 64-bit inode functions.\n    // Other Darwin variants (iOS, TVOS, WatchOS) only support 64-bit inodes,\n    // no suffix needed\n    version (OSX)\n        pragma(mangle, \"readdir$INODE64\") dirent* readdir(DIR*);\n    else\n        dirent* readdir(DIR*);\n}\nelse version (FreeBSD)\n{\n    // https://github.com/freebsd/freebsd/blob/master/sys/sys/dirent.h\n    enum\n    {\n        DT_UNKNOWN  = 0,\n        DT_FIFO     = 1,\n        DT_CHR      = 2,\n        DT_DIR      = 4,\n        DT_BLK      = 6,\n        DT_REG      = 8,\n        DT_LNK      = 10,\n        DT_SOCK     = 12,\n        DT_WHT      = 14\n    }\n\n    align(4)\n    struct dirent\n    {\n        uint      d_fileno;\n        ushort    d_reclen;\n        ubyte     d_type;\n        ubyte     d_namlen;\n        char[256] d_name;\n    }\n\n    alias void* DIR;\n\n    dirent* readdir(DIR*);\n}\nelse version (NetBSD)\n{\n    enum\n    {\n        DT_UNKNOWN  = 0,\n        DT_FIFO     = 1,\n        DT_CHR      = 2,\n        DT_DIR      = 4,\n        DT_BLK      = 6,\n        DT_REG      = 8,\n        DT_LNK      = 10,\n        DT_SOCK     = 12,\n        DT_WHT      = 14\n    }\n\n    struct dirent\n    {\n        ulong      d_fileno;\n        ushort    d_reclen;\n        ushort    d_namlen;\n        ubyte     d_type;\n        char[512] d_name;\n    }\n\n    alias void* DIR;\n\n    dirent* __readdir30(DIR*);\n    alias __readdir30 readdir;\n}\nelse version (OpenBSD)\n{\n    enum\n    {\n        DT_UNKNOWN  = 0,\n        DT_FIFO     = 1,\n        DT_CHR      = 2,\n        DT_DIR      = 4,\n        DT_BLK      = 6,\n        DT_REG      = 8,\n        DT_LNK      = 10,\n        DT_SOCK     = 12,\n    }\n\n    align(4)\n    struct dirent\n    {\n        ino_t     d_fileno;\n        off_t     d_off;\n        ushort    d_reclen;\n        ubyte     d_type;\n        ubyte     d_namlen;\n        ubyte[4]  __d_padding;\n        char[256] d_name;\n    }\n\n    alias void* DIR;\n\n    dirent* readdir(DIR*);\n}\nelse version (DragonFlyBSD)\n{\n    enum\n    {\n        DT_UNKNOWN  = 0,\n        DT_FIFO     = 1,\n        DT_CHR      = 2,\n        DT_DIR      = 4,\n        DT_BLK      = 6,\n        DT_REG      = 8,\n        DT_LNK      = 10,\n        DT_SOCK     = 12,\n        DT_WHT      = 14,\n        DT_DBF      = 15,         /* database record file */\n    }\n\n    struct dirent\n    {\n        ino_t     d_fileno;       /* file number of entry */\n        ushort    d_reclen;       /* strlen(d_name) */\n        ubyte     d_type;         /* file type, see blow */\n        ubyte     d_unused1;      /* padding, reserved */\n        uint      d_unused2;      /* reserved */\n        char[256] d_name;         /* name, NUL-terminated */\n    }\n\n    alias void* DIR;\n\n    dirent* readdir(DIR*);\n}\nelse version (Solaris)\n{\n    struct dirent\n    {\n        ino_t d_ino;\n        off_t d_off;\n        ushort d_reclen;\n        char[1] d_name;\n    }\n\n    struct DIR\n    {\n        int dd_fd;\n        int dd_loc;\n        int dd_size;\n        char* dd_buf;\n    }\n\n    version (D_LP64)\n    {\n        dirent* readdir(DIR*);\n        alias readdir64 = readdir;\n    }\n    else\n    {\n        static if (__USE_LARGEFILE64)\n        {\n            dirent* readdir64(DIR*);\n            alias readdir64 readdir;\n        }\n        else\n        {\n            dirent* readdir(DIR*);\n        }\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    enum\n    {\n        DT_UNKNOWN  = 0,\n        DT_FIFO     = 1,\n        DT_CHR      = 2,\n        DT_DIR      = 4,\n        DT_BLK      = 6,\n        DT_REG      = 8,\n        DT_LNK      = 10,\n        DT_SOCK     = 12,\n        DT_WHT      = 14\n    }\n\n    struct dirent\n    {\n        ulong       d_ino;\n        long        d_off;\n        ushort      d_reclen;\n        ubyte       d_type;\n        char[256]   d_name;\n    }\n\n    struct DIR\n    {\n    }\n\n    dirent* readdir(DIR*);\n}\nelse version (CRuntime_Musl)\n{\n    enum\n    {\n        DT_UNKNOWN  = 0,\n        DT_FIFO     = 1,\n        DT_CHR      = 2,\n        DT_DIR      = 4,\n        DT_BLK      = 6,\n        DT_REG      = 8,\n        DT_LNK      = 10,\n        DT_SOCK     = 12,\n        DT_WHT      = 14\n    }\n\n    struct dirent\n    {\n        ino_t       d_ino;\n        off_t       d_off;\n        ushort      d_reclen;\n        ubyte       d_type;\n        char[256]   d_name;\n    }\n\n    struct DIR\n    {\n    }\n\n    static if ( __USE_FILE_OFFSET64 )\n    {\n        dirent* readdir64(DIR*);\n        alias   readdir64 readdir;\n    }\n    else\n    {\n        dirent* readdir(DIR*);\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    // NOTE: The following constants are non-standard Linux definitions\n    //       for dirent.d_type.\n    enum\n    {\n        DT_UNKNOWN  = 0,\n        DT_FIFO     = 1,\n        DT_CHR      = 2,\n        DT_DIR      = 4,\n        DT_BLK      = 6,\n        DT_REG      = 8,\n        DT_LNK      = 10,\n        DT_SOCK     = 12,\n        DT_WHT      = 14\n    }\n\n    struct dirent\n    {\n        static if (__USE_FILE_OFFSET64)\n        {\n            ino64_t d_ino;\n            off64_t d_off;\n        }\n        else\n        {\n            ino_t d_ino;\n            off_t d_off;\n        }\n        ushort      d_reclen;\n        ubyte       d_type;\n        char[256]   d_name;\n    }\n\n    struct DIR\n    {\n        // Managed by OS\n    }\n\n    static if ( __USE_FILE_OFFSET64 )\n    {\n        dirent* readdir64(DIR*);\n        alias   readdir64 readdir;\n    }\n    else\n    {\n        dirent* readdir(DIR*);\n    }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n// Only OS X out of the Darwin family needs special treatment.  Other Darwins\n// (iOS, TVOS, WatchOS) are fine with normal symbol names for these functions\n// in else below.\nversion (OSX)\n{\n    version (D_LP64)\n    {\n        int closedir(DIR*);\n        pragma(mangle, \"opendir$INODE64\")   DIR* opendir(in char*);\n        pragma(mangle, \"rewinddir$INODE64\") void rewinddir(DIR*);\n    }\n    else\n    {\n        // 32-bit mangles __DARWIN_UNIX03 specific functions with $UNIX2003 to\n        // maintain backward compatibility with binaries build pre 10.5\n        pragma(mangle, \"closedir$UNIX2003\")          int closedir(DIR*);\n        pragma(mangle, \"opendir$INODE64$UNIX2003\")   DIR* opendir(in char*);\n        pragma(mangle, \"rewinddir$INODE64$UNIX2003\") void rewinddir(DIR*);\n    }\n}\nelse version (NetBSD)\n{\n    int     closedir(DIR*);\n    DIR*    __opendir30(in char*);\n    alias __opendir30 opendir;\n    void    rewinddir(DIR*);\n}\nelse\n{\n    int     closedir(DIR*);\n    DIR*    opendir(in char*);\n    //dirent* readdir(DIR*);\n    void    rewinddir(DIR*);\n}\n\n//\n// Thread-Safe Functions (TSF)\n//\n/*\nint readdir_r(DIR*, dirent*, dirent**);\n*/\n\nversion (CRuntime_Glibc)\n{\n  static if ( __USE_LARGEFILE64 )\n  {\n    int   readdir64_r(DIR*, dirent*, dirent**);\n    alias readdir64_r readdir_r;\n  }\n  else\n  {\n    int readdir_r(DIR*, dirent*, dirent**);\n  }\n}\nelse version (Darwin)\n{\n    version (OSX)\n        pragma(mangle, \"readdir_r$INODE64\") int readdir_r(DIR*, dirent*, dirent**);\n    else\n        int readdir_r(DIR*, dirent*, dirent**);\n}\nelse version (FreeBSD)\n{\n    int readdir_r(DIR*, dirent*, dirent**);\n}\nelse version (DragonFlyBSD)\n{\n    int readdir_r(DIR*, dirent*, dirent**);\n}\nelse version (NetBSD)\n{\n    int __readdir_r30(DIR*, dirent*, dirent**);\n    alias __readdir_r30 readdir_r;\n}\nelse version (OpenBSD)\n{\n    int readdir_r(DIR*, dirent*, dirent**);\n}\nelse version (Solaris)\n{\n    static if (__USE_LARGEFILE64)\n    {\n        int readdir64_r(DIR*, dirent*, dirent**);\n        alias readdir64_r readdir_r;\n    }\n    else\n    {\n        int readdir_r(DIR*, dirent*, dirent**);\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    int readdir_r(DIR*, dirent*, dirent**);\n}\nelse version (CRuntime_Musl)\n{\n\n}\nelse version (CRuntime_UClibc)\n{\n  static if ( __USE_LARGEFILE64 )\n  {\n    int   readdir64_r(DIR*, dirent*, dirent**);\n    alias readdir64_r readdir_r;\n  }\n  else\n  {\n    int readdir_r(DIR*, dirent*, dirent**);\n  }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// XOpen (XSI)\n//\n/*\nvoid   seekdir(DIR*, c_long);\nc_long telldir(DIR*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    void   seekdir(DIR*, c_long);\n    c_long telldir(DIR*);\n}\nelse version (FreeBSD)\n{\n    void   seekdir(DIR*, c_long);\n    c_long telldir(DIR*);\n}\nelse version (NetBSD)\n{\n    void   seekdir(DIR*, c_long);\n    c_long telldir(DIR*);\n}\nelse version (OpenBSD)\n{\n    void   seekdir(DIR*, c_long);\n    c_long telldir(DIR*);\n}\nelse version (DragonFlyBSD)\n{\n    void   seekdir(DIR*, c_long);\n    c_long telldir(DIR*);\n}\nelse version (Darwin)\n{\n    version (OSX)\n    {\n        version (D_LP64)\n        {\n            pragma(mangle, \"seekdir$INODE64\") void seekdir(DIR*, c_long);\n            pragma(mangle, \"telldir$INODE64\") c_long telldir(DIR*);\n        }\n        else\n        {\n            // 32-bit mangles __DARWIN_UNIX03 specific functions with $UNIX2003 to\n            // maintain backward compatibility with binaries build pre 10.5\n            pragma(mangle, \"seekdir$INODE64$UNIX2003\") void seekdir(DIR*, c_long);\n            pragma(mangle, \"telldir$INODE64$UNIX2003\") c_long telldir(DIR*);\n        }\n    }\n    else // other Darwins (e.g. iOS, TVOS, WatchOS)\n    {\n        void seekdir(DIR*, c_long);\n        c_long telldir(DIR*);\n    }\n}\nelse version (Solaris)\n{\n    c_long telldir(DIR*);\n    void seekdir(DIR*, c_long);\n}\nelse version (CRuntime_Bionic)\n{\n}\nelse version (CRuntime_Musl)\n{\n}\nelse version (CRuntime_UClibc)\n{\n    void   seekdir(DIR*, c_long);\n    c_long telldir(DIR*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/dlfcn.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.dlfcn;\n\nprivate import core.sys.posix.config;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// XOpen (XSI)\n//\n/*\nRTLD_LAZY\nRTLD_NOW\nRTLD_GLOBAL\nRTLD_LOCAL\n\nint   dlclose(void*);\nchar* dlerror();\nvoid* dlopen(in char*, int);\nvoid* dlsym(void*, in char*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    version (X86)\n    {\n        enum RTLD_LAZY      = 0x00001;\n        enum RTLD_NOW       = 0x00002;\n        enum RTLD_GLOBAL    = 0x00100;\n        enum RTLD_LOCAL     = 0x00000;\n    }\n    else version (X86_64)\n    {\n        enum RTLD_LAZY      = 0x00001;\n        enum RTLD_NOW       = 0x00002;\n        enum RTLD_GLOBAL    = 0x00100;\n        enum RTLD_LOCAL     = 0x00000;\n    }\n    else version (MIPS32)\n    {\n        enum RTLD_LAZY      = 0x0001;\n        enum RTLD_NOW       = 0x0002;\n        enum RTLD_GLOBAL    = 0x0004;\n        enum RTLD_LOCAL     = 0;\n    }\n    else version (MIPS64)\n    {\n        enum RTLD_LAZY      = 0x0001;\n        enum RTLD_NOW       = 0x0002;\n        enum RTLD_GLOBAL    = 0x0004;\n        enum RTLD_LOCAL     = 0;\n    }\n    else version (PPC)\n    {\n        enum RTLD_LAZY      = 0x00001;\n        enum RTLD_NOW       = 0x00002;\n        enum RTLD_GLOBAL    = 0x00100;\n        enum RTLD_LOCAL     = 0;\n    }\n    else version (PPC64)\n    {\n        enum RTLD_LAZY      = 0x00001;\n        enum RTLD_NOW       = 0x00002;\n        enum RTLD_GLOBAL    = 0x00100;\n        enum RTLD_LOCAL     = 0;\n    }\n    else version (ARM)\n    {\n        enum RTLD_LAZY      = 0x00001;\n        enum RTLD_NOW       = 0x00002;\n        enum RTLD_GLOBAL    = 0x00100;\n        enum RTLD_LOCAL     = 0;\n    }\n    else version (AArch64)\n    {\n        enum RTLD_LAZY      = 0x00001;\n        enum RTLD_NOW       = 0x00002;\n        enum RTLD_GLOBAL    = 0x00100;\n        enum RTLD_LOCAL     = 0;\n    }\n    else version (SPARC64)\n    {\n        enum RTLD_LAZY      = 0x00001;\n        enum RTLD_NOW       = 0x00002;\n        enum RTLD_GLOBAL    = 0x00100;\n        enum RTLD_LOCAL     = 0;\n    }\n    else version (SystemZ)\n    {\n        enum RTLD_LAZY      = 0x00001;\n        enum RTLD_NOW       = 0x00002;\n        enum RTLD_GLOBAL    = 0x00100;\n        enum RTLD_LOCAL     = 0;\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    int   dlclose(void*);\n    char* dlerror();\n    void* dlopen(in char*, int);\n    void* dlsym(void*, in char*);\n\n    deprecated(\"Please use core.sys.linux.dlfcn for non-POSIX extensions\")\n    {\n        int   dladdr(in void* addr, Dl_info* info);\n        void* dlvsym(void* handle, in char* symbol, in char* version_);\n\n        struct Dl_info\n        {\n            const(char)* dli_fname;\n            void*        dli_fbase;\n            const(char)* dli_sname;\n            void*        dli_saddr;\n        }\n    }\n}\nelse version (Darwin)\n{\n    enum RTLD_LAZY      = 0x00001;\n    enum RTLD_NOW       = 0x00002;\n    enum RTLD_GLOBAL    = 0x00100;\n    enum RTLD_LOCAL     = 0x00000;\n\n    int   dlclose(void*);\n    char* dlerror();\n    void* dlopen(in char*, int);\n    void* dlsym(void*, in char*);\n    int   dladdr(void* addr, Dl_info* info);\n\n    struct Dl_info\n    {\n        const(char)* dli_fname;\n        void*        dli_fbase;\n        const(char)* dli_sname;\n        void*        dli_saddr;\n    }\n}\nelse version (FreeBSD)\n{\n    enum RTLD_LAZY      = 1;\n    enum RTLD_NOW       = 2;\n    enum RTLD_GLOBAL    = 0x100;\n    enum RTLD_LOCAL     = 0;\n\n    int   dlclose(void*);\n    char* dlerror();\n    void* dlopen(in char*, int);\n    void* dlsym(void*, in char*);\n    int   dladdr(const(void)* addr, Dl_info* info);\n\n    struct Dl_info\n    {\n        const(char)* dli_fname;\n        void*        dli_fbase;\n        const(char)* dli_sname;\n        void*        dli_saddr;\n    }\n}\nelse version (NetBSD)\n{\n    enum RTLD_LAZY      = 1;\n    enum RTLD_NOW       = 2;\n    enum RTLD_GLOBAL    = 0x100;\n    enum RTLD_LOCAL     = 0x200;\n    enum RTLD_NODELETE  = 0x01000;         /* Do not remove members. */\n    enum RTLD_NOLOAD    = 0x02000;\n\n    int   dlclose(void*);\n    char* dlerror();\n    void* dlopen(in char*, int);\n    void* dlsym(void*, in char*);\n    int   dladdr(const(void)* addr, Dl_info* info);\n\n    struct Dl_info\n    {\n        const(char)* dli_fname;\n        void*        dli_fbase;\n        const(char)* dli_sname;\n        void*        dli_saddr;\n    }\n}\nelse version (OpenBSD)\n{\n    enum RTLD_LAZY      = 1;\n    enum RTLD_NOW       = 2;\n    enum RTLD_GLOBAL    = 0x100;\n    enum RTLD_LOCAL     = 0;\n\n    int   dlclose(void*);\n    char* dlerror();\n    void* dlopen(in char*, int);\n    void* dlsym(void*, in char*);\n    int   dladdr(const(void)* addr, Dl_info* info);\n\n    struct Dl_info\n    {\n        const(char)* dli_fname;\n        void*        dli_fbase;\n        const(char)* dli_sname;\n        void*        dli_saddr;\n    }\n}\nelse version (DragonFlyBSD)\n{\n    enum RTLD_LAZY      = 1;\n    enum RTLD_NOW       = 2;\n    enum RTLD_GLOBAL    = 0x100;\n    enum RTLD_LOCAL     = 0;\n\n    int   dlclose(void*);\n    char* dlerror();\n    void* dlopen(in char*, int);\n    void* dlsym(void*, in char*);\n    int   dladdr(const(void)* addr, Dl_info* info);\n\n    struct Dl_info\n    {\n        const(char)* dli_fname;\n        void*        dli_fbase;\n        const(char)* dli_sname;\n        void*        dli_saddr;\n    }\n}\nelse version (Solaris)\n{\n    enum RTLD_LAZY      = 1;\n    enum RTLD_NOW       = 2;\n    enum RTLD_GLOBAL    = 0x100;\n    enum RTLD_LOCAL     = 0;\n\n    int   dlclose(void*);\n    char* dlerror();\n    void* dlopen(in char*, int);\n    void* dlsym(void*, in char*);\n    int   dladdr(const(void)* addr, Dl_info* info);\n\n    struct Dl_info\n    {\n        const(char)* dli_fname;\n        void*        dli_fbase;\n        const(char)* dli_sname;\n        void*        dli_saddr;\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    enum\n    {\n        RTLD_NOW    = 0,\n        RTLD_LAZY   = 1,\n        RTLD_LOCAL  = 0,\n        RTLD_GLOBAL = 2\n    }\n\n    int          dladdr(in void*, Dl_info*);\n    int          dlclose(void*);\n    const(char)* dlerror();\n    void*        dlopen(in char*, int);\n    void*        dlsym(void*, in char*);\n\n    struct Dl_info\n    {\n        const(char)* dli_fname;\n        void*        dli_fbase;\n        const(char)* dli_sname;\n        void*        dli_saddr;\n    }\n}\nelse version (CRuntime_Musl)\n{\n    enum {\n        RTLD_LAZY     = 1,\n        RTLD_NOW      = 2,\n        RTLD_NOLOAD   = 4,\n        RTLD_NODELETE = 4096,\n        RTLD_GLOBAL   = 256,\n        RTLD_LOCAL    = 0,\n    }\n    int          dlclose(void*);\n    const(char)* dlerror();\n    void*        dlopen(in char*, int);\n    void*        dlsym(void*, in char*);\n}\nelse version (CRuntime_UClibc)\n{\n    version (X86_64)\n    {\n        enum RTLD_LAZY              = 0x0001;\n        enum RTLD_NOW               = 0x0002;\n        enum RTLD_BINDING_MASK      = 0x3;\n        enum RTLD_NOLOAD            = 0x00004;\n        enum RTLD_GLOBAL            = 0x00100;\n        enum RTLD_LOCAL             = 0;\n        enum RTLD_NODELETE          = 0x01000;\n    }\n    else version (MIPS32)\n    {\n        enum RTLD_LAZY              = 0x0001;\n        enum RTLD_NOW               = 0x0002;\n        enum RTLD_BINDING_MASK      = 0x3;\n        enum RTLD_NOLOAD            = 0x00008;\n        enum RTLD_GLOBAL            = 0x0004;\n        enum RTLD_LOCAL             = 0;\n        enum RTLD_NODELETE          = 0x01000;\n    }\n    else version (ARM)\n    {\n        enum RTLD_LAZY              = 0x0001;\n        enum RTLD_NOW               = 0x0002;\n        enum RTLD_BINDING_MASK      = 0x3;\n        enum RTLD_NOLOAD            = 0x00004;\n        enum RTLD_GLOBAL            = 0x00100;\n        enum RTLD_LOCAL             = 0;\n        enum RTLD_NODELETE          = 0x01000;\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    int   dlclose(void*);\n    char* dlerror();\n    void* dlopen(in char*, int);\n    void* dlsym(void*, in char*);\n}"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/fcntl.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.fcntl;\n\nprivate import core.sys.posix.config;\nprivate import core.stdc.stdint;\npublic import core.sys.posix.sys.types; // for off_t, mode_t\npublic import core.sys.posix.sys.stat;  // for S_IFMT, etc.\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\n\nnothrow:\n@nogc:\n\n//\n// Required\n//\n/*\nF_DUPFD\nF_GETFD\nF_SETFD\nF_GETFL\nF_SETFL\nF_GETLK\nF_SETLK\nF_SETLKW\nF_GETOWN\nF_SETOWN\n\nFD_CLOEXEC\n\nF_RDLCK\nF_UNLCK\nF_WRLCK\n\nO_CREAT\nO_EXCL\nO_NOCTTY\nO_TRUNC\n\nO_APPEND\nO_DSYNC\nO_NONBLOCK\nO_RSYNC\nO_SYNC\n\nO_ACCMODE\nO_RDONLY\nO_RDWR\nO_WRONLY\n\nstruct flock\n{\n    short   l_type;\n    short   l_whence;\n    off_t   l_start;\n    off_t   l_len;\n    pid_t   l_pid;\n}\n\nint creat(in char*, mode_t);\nint fcntl(int, int, ...);\nint open(in char*, int, ...);\n*/\nversion (CRuntime_Glibc)\n{\n    enum F_DUPFD        = 0;\n    enum F_GETFD        = 1;\n    enum F_SETFD        = 2;\n    enum F_GETFL        = 3;\n    enum F_SETFL        = 4;\n  version (X86_64)\n  {\n    static assert(off_t.sizeof == 8);\n    enum F_GETLK        = 5;\n    enum F_SETLK        = 6;\n    enum F_SETLKW       = 7;\n  }\n  else version (AArch64)\n  {\n    enum F_GETLK        = 5;\n    enum F_SETLK        = 6;\n    enum F_SETLKW       = 7;\n  }\n  else\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    enum F_GETLK        = 12;\n    enum F_SETLK        = 13;\n    enum F_SETLKW       = 14;\n  }\n  else\n  {\n    enum F_GETLK        = 5;\n    enum F_SETLK        = 6;\n    enum F_SETLKW       = 7;\n  }\n    enum F_GETOWN       = 9;\n    enum F_SETOWN       = 8;\n\n    enum FD_CLOEXEC     = 1;\n\n    enum F_RDLCK        = 0;\n    enum F_UNLCK        = 2;\n    enum F_WRLCK        = 1;\n\n    version (X86)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x101000; // octal 04010000\n        enum O_DSYNC        = 0x1000;   // octal   010000\n        enum O_RSYNC        = O_SYNC;\n    }\n    else version (X86_64)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x101000; // octal 04010000\n        enum O_DSYNC        = 0x1000;   // octal   010000\n        enum O_RSYNC        = O_SYNC;\n    }\n    else version (MIPS32)\n    {\n        enum O_CREAT        = 0x0100;\n        enum O_EXCL         = 0x0400;\n        enum O_NOCTTY       = 0x0800;\n        enum O_TRUNC        = 0x0200;\n\n        enum O_APPEND       = 0x0008;\n        enum O_DSYNC        = O_SYNC;\n        enum O_NONBLOCK     = 0x0080;\n        enum O_RSYNC        = O_SYNC;\n        enum O_SYNC         = 0x0010;\n    }\n    else version (MIPS64)\n    {\n        enum O_CREAT        = 0x0100;\n        enum O_EXCL         = 0x0400;\n        enum O_NOCTTY       = 0x0800;\n        enum O_TRUNC        = 0x0200;\n\n        enum O_APPEND       = 0x0008;\n        enum O_DSYNC        = 0x0010;\n        enum O_NONBLOCK     = 0x0080;\n        enum O_RSYNC        = O_SYNC;\n        enum O_SYNC         = 0x4010;\n    }\n    else version (PPC)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x101000; // octal 04010000\n        enum O_DSYNC        = 0x1000;   // octal   010000\n        enum O_RSYNC        = O_SYNC;\n    }\n    else version (PPC64)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x101000; // octal 04010000\n        enum O_DSYNC        = 0x1000;   // octal   010000\n        enum O_RSYNC        = O_SYNC;\n    }\n    else version (ARM)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x101000; // octal 04010000\n        enum O_DSYNC        = 0x1000;   // octal   010000\n        enum O_RSYNC        = O_SYNC;\n    }\n    else version (AArch64)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x101000; // octal 04010000\n        enum O_DSYNC        = 0x1000;   // octal   010000\n        enum O_RSYNC        = O_SYNC;\n    }\n    else version (SPARC64)\n    {\n        enum O_CREAT        = 0x200;\n        enum O_EXCL         = 0x800;\n        enum O_NOCTTY       = 0x8000;\n        enum O_TRUNC        = 0x400;\n\n        enum O_APPEND       = 0x8;\n        enum O_NONBLOCK     = 0x4000;\n        enum O_SYNC         = 0x802000;\n        enum O_DSYNC        = 0x2000;\n        enum O_RSYNC        = O_SYNC;\n    }\n    else version (SystemZ)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x101000; // octal 04010000\n        enum O_DSYNC        = 0x1000;   // octal   010000\n        enum O_RSYNC        = O_SYNC;\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    enum O_ACCMODE      = 0x3;\n    enum O_RDONLY       = 0x0;\n    enum O_WRONLY       = 0x1;\n    enum O_RDWR         = 0x2;\n\n    struct flock\n    {\n        short   l_type;\n        short   l_whence;\n        off_t   l_start;\n        off_t   l_len;\n        pid_t   l_pid;\n    }\n\n    static if ( __USE_FILE_OFFSET64 )\n    {\n        int   creat64(in char*, mode_t);\n        alias creat64 creat;\n\n        int   open64(in char*, int, ...);\n        alias open64 open;\n    }\n    else\n    {\n        int   creat(in char*, mode_t);\n        int   open(in char*, int, ...);\n    }\n\n    enum AT_SYMLINK_NOFOLLOW = 0x100;\n    enum AT_FDCWD = -100;\n}\nelse version (Darwin)\n{\n    enum F_DUPFD        = 0;\n    enum F_GETFD        = 1;\n    enum F_SETFD        = 2;\n    enum F_GETFL        = 3;\n    enum F_SETFL        = 4;\n    enum F_GETOWN       = 5;\n    enum F_SETOWN       = 6;\n    enum F_GETLK        = 7;\n    enum F_SETLK        = 8;\n    enum F_SETLKW       = 9;\n\n    enum FD_CLOEXEC     = 1;\n\n    enum F_RDLCK        = 1;\n    enum F_UNLCK        = 2;\n    enum F_WRLCK        = 3;\n\n    enum O_CREAT        = 0x0200;\n    enum O_EXCL         = 0x0800;\n    enum O_NOCTTY       = 0;\n    enum O_TRUNC        = 0x0400;\n\n    enum O_RDONLY       = 0x0000;\n    enum O_WRONLY       = 0x0001;\n    enum O_RDWR         = 0x0002;\n    enum O_ACCMODE      = 0x0003;\n\n    enum O_NONBLOCK     = 0x0004;\n    enum O_APPEND       = 0x0008;\n    enum O_SYNC         = 0x0080;\n    //enum O_DSYNC\n    //enum O_RSYNC\n\n    struct flock\n    {\n        off_t   l_start;\n        off_t   l_len;\n        pid_t   l_pid;\n        short   l_type;\n        short   l_whence;\n    }\n\n    int creat(in char*, mode_t);\n    int open(in char*, int, ...);\n}\nelse version (FreeBSD)\n{\n    enum F_DUPFD        = 0;\n    enum F_GETFD        = 1;\n    enum F_SETFD        = 2;\n    enum F_GETFL        = 3;\n    enum F_SETFL        = 4;\n    enum F_GETOWN       = 5;\n    enum F_SETOWN       = 6;\n    enum F_GETLK        = 11;\n    enum F_SETLK        = 12;\n    enum F_SETLKW       = 13;\n    enum F_OGETLK       = 7;\n    enum F_OSETLK       = 8;\n    enum F_OSETLKW      = 9;\n    enum F_DUP2FD       = 10;\n\n    enum FD_CLOEXEC     = 1;\n\n    enum F_RDLCK        = 1;\n    enum F_UNLCK        = 2;\n    enum F_WRLCK        = 3;\n\n    enum O_CREAT        = 0x0200;\n    enum O_EXCL         = 0x0800;\n    enum O_NOCTTY       = 0x8000;\n    enum O_TRUNC        = 0x0400;\n\n    enum O_RDONLY       = 0x0000;\n    enum O_WRONLY       = 0x0001;\n    enum O_RDWR         = 0x0002;\n    enum O_ACCMODE      = 0x0003;\n\n    enum O_NONBLOCK     = 0x0004;\n    enum O_APPEND       = 0x0008;\n    enum O_SYNC         = 0x0080;\n    //enum O_DSYNC\n    //enum O_RSYNC\n\n    struct flock\n    {\n        off_t   l_start;\n        off_t   l_len;\n        pid_t   l_pid;\n        short   l_type;\n        short   l_whence;\n        int     l_sysid;\n    }\n\n    struct oflock\n    {\n        off_t   l_start;\n        off_t   l_len;\n        pid_t   l_pid;\n        short   l_type;\n        short   l_whence;\n    }\n\n    int creat(in char*, mode_t);\n    int open(in char*, int, ...);\n\n    enum AT_SYMLINK_NOFOLLOW = 0x200;\n    enum AT_FDCWD = -100;\n}\nelse version (OpenBSD)\n{\n    enum F_DUPFD        = 0;\n    enum F_GETFD        = 1;\n    enum F_SETFD        = 2;\n    enum F_GETFL        = 3;\n    enum F_SETFL        = 4;\n    enum F_GETOWN       = 5;\n    enum F_SETOWN       = 6;\n    enum F_GETLK        = 7;\n    enum F_SETLK        = 8;\n    enum F_SETLKW       = 9;\n    enum F_DUPFD_CLOEXEC= 10;\n    enum F_ISATTY       = 11;\n\n    enum FD_CLOEXEC     = 1;\n\n    enum F_RDLCK        = 1;\n    enum F_UNLCK        = 2;\n    enum F_WRLCK        = 3;\n\n    enum O_CREAT        = 0x0200;\n    enum O_EXCL         = 0x0800;\n    enum O_NOCTTY       = 0x8000;\n    enum O_TRUNC        = 0x0400;\n\n    enum O_RDONLY       = 0x0000;\n    enum O_WRONLY       = 0x0001;\n    enum O_RDWR         = 0x0002;\n    enum O_ACCMODE      = 0x0003;\n    enum O_SHLOCK       = 0x0010;\n    enum O_EXLOCK       = 0x0020;\n    enum O_ASYNC        = 0x0040;\n    enum O_FSYNC        = 0x0080;\n    enum O_NOFOLLOW     = 0x0100;\n\n    enum O_NONBLOCK     = 0x0004;\n    enum O_APPEND       = 0x0008;\n    enum O_SYNC         = 0x0080;\n    enum O_DSYNC        = O_SYNC;\n    enum O_RSYNC        = O_SYNC;\n\n    enum O_CLOEXEC      = 0x10000;\n    enum O_DIRECTORY    = 0x20000;\n\n    enum LOCK_SH        = 0x01;\n    enum LOCK_EX        = 0x02;\n    enum LOCK_NB        = 0x04;\n    enum LOCK_UN        = 0x08;\n\n    struct flock\n    {\n        off_t   l_start;\n        off_t   l_len;\n        pid_t   l_pid;\n        short   l_type;\n        short   l_whence;\n    }\n\n    int creat(in char*, mode_t);\n    int open(in char*, int, ...);\n\n    enum AT_FDCWD            = -100;\n\n    enum AT_EACCESS          = 0x01;\n    enum AT_SYMLINK_NOFOLLOW = 0x02;\n    enum AT_SYMLINK_FOLLOW   = 0x04;\n    enum AT_REMOVEDIR        = 0x08;\n}\nelse version (NetBSD)\n{\n    enum F_DUPFD        = 0;\n    enum F_GETFD        = 1;\n    enum F_SETFD        = 2;\n    enum F_GETFL        = 3;\n    enum F_SETFL        = 4;\n    enum F_GETOWN       = 5;\n    enum F_SETOWN       = 6;\n    enum F_GETLK        = 7;\n    enum F_SETLK        = 8;\n    enum F_SETLKW       = 9;\n    enum F_CLOSEM       = 10;\n    enum F_MAXFD        = 11;\n    enum F_DUPFD_CLOEXEC= 12;\n    enum F_GETNOSIGPIPE = 13;\n    enum F_SETNOSIGPIPE = 14;\n\n    enum FD_CLOEXEC     = 1;\n\n    enum F_RDLCK        = 1;\n    enum F_UNLCK        = 2;\n    enum F_WRLCK        = 3;\n\n    enum O_CREAT        = 0x0200;\n    enum O_EXCL         = 0x0800;\n    enum O_NOCTTY       = 0x8000;\n    enum O_TRUNC        = 0x0400;\n\n    enum O_RDONLY       = 0x0000;\n    enum O_WRONLY       = 0x0001;\n    enum O_RDWR         = 0x0002;\n    enum O_ACCMODE      = 0x0003;\n\n    enum O_NONBLOCK     = 0x0004;\n    enum O_APPEND       = 0x0008;\n    enum O_SYNC         = 0x0080;\n    //enum O_DSYNC\n    //enum O_RSYNC\n\n    struct flock\n    {\n        off_t   l_start;\n        off_t   l_len;\n        pid_t   l_pid;\n        short   l_type;\n        short   l_whence;\n    }\n\n\n    int creat(in char*, mode_t);\n    int open(in char*, int, ...);\n}\nelse version (DragonFlyBSD)\n{\n    enum O_RDONLY       = 0x0000;\n    enum O_WRONLY       = 0x0001;\n    enum O_RDWR         = 0x0002;\n    enum O_ACCMODE      = 0x0003;\n\n    enum FREAD          = 0x0001;\n    enum FWRITE         = 0x0002;\n    enum O_NONBLOCK     = 0x0000004;\n    enum O_APPEND       = 0x0000008;\n    enum O_SHLOCK       = 0x0000010;\n    enum O_EXLOCK       = 0x0000020;\n    enum O_ASYNC        = 0x0000040;\n    enum O_FSYNC        = 0x0000080;\n    enum O_SYNC         = 0x0000080;\n    enum O_NOFOLLOW     = 0x0000100;\n    enum O_CREAT        = 0x0000200;\n    enum O_TRUNC        = 0x0000400;\n    enum O_EXCL         = 0x0000800;\n    enum O_NOCTTY       = 0x0008000;\n    enum O_DIRECT       = 0x0010000;\n    enum O_CLOEXEC      = 0x0020000;\n    enum O_FBLOCKING    = 0x0040000;\n    enum O_FNONBLOCKING = 0x0080000;\n    enum O_FAPPEND      = 0x0100000;\n    enum O_FOFFSET      = 0x0200000;\n    enum O_FSYNCWRITE   = 0x0400000;\n    enum O_FASYNCWRITE  = 0x0800000;\n    enum O_DIRECTORY    = 0x8000000;\n\n    enum FAPPEND        = O_APPEND;\n    enum FASYNC         = O_ASYNC;\n    enum FFSYNC         = O_FSYNC;\n    enum FNONBLOCK      = O_NONBLOCK;\n    enum FNDELAY        = O_NONBLOCK;\n    enum O_NDELAY       = O_NONBLOCK;\n    enum FPOSIXSHM      = O_NOFOLLOW;\n\n    enum FCNTLFLAGS = (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FPOSIXSHM|O_DIRECT);\n\n    enum F_DUPFD        = 0;\n    enum F_GETFD        = 1;\n    enum F_SETFD        = 2;\n    enum F_GETFL        = 3;\n    enum F_SETFL        = 4;\n    enum F_GETOWN       = 5;\n    enum F_SETOWN       = 6;\n    enum F_GETLK        = 7;\n//    enum F_SETLK        = 8;\n    enum F_SETLK        = 8;\n    enum F_SETLKW       = 9;\n    enum F_OGETLK       = F_GETLK;\n    enum F_OSETLK       = F_SETLK;\n    enum F_OSETLKW      = F_SETLKW;\n    enum F_DUP2FD       = 10;\n    //enum F_GETLK        = 11;\n    //enum F_SETLK        = 12;\n    //enum F_SETLKW       = 13;\n    enum F_DUPFD_CLOEXEC = 17;\n    enum F_DUP2FD_CLOEXEC = 18;\n\n    enum FD_CLOEXEC     = 1;\n\n    enum F_RDLCK        = 1;\n    enum F_UNLCK        = 2;\n    enum F_WRLCK        = 3;\n\n    enum LOCK_SH        = 0x01;\n    enum LOCK_EX        = 0x02;\n    enum LOCK_NB        = 0x04;\n    enum LOCK_UN        = 0x08;\n\n    struct flock\n    {\n        off_t   l_start;\n        off_t   l_len;\n        pid_t   l_pid;\n        short   l_type;\n        short   l_whence;\n    }\n\n    alias oflock = flock;\n\n    int creat(in char*, mode_t);\n    int open(in char*, int, ...);\n    //int fcntl(int, int, ...);  /*defined below*/\n    //int flock(int, int);\n}\nelse version (Solaris)\n{\n    enum F_DUPFD = 0;\n    enum F_GETFD = 1;\n    enum F_SETFD = 2;\n    enum F_GETFL = 3;\n    enum F_SETFL = 4;\n\n    version (D_LP64)\n    {\n        enum F_GETLK = 14;\n        enum F_SETLK = 6;\n        enum F_SETLKW = 7;\n    }\n    else\n    {\n        static if (__USE_FILE_OFFSET64)\n        {\n            enum F_GETLK = 14;\n            enum F_SETLK = 6;\n            enum F_SETLKW = 7;\n        }\n        else\n        {\n            enum F_GETLK = 33;\n            enum F_SETLK = 34;\n            enum F_SETLKW = 35;\n        }\n    }\n\n    enum F_GETOWN = 23;\n    enum F_SETOWN = 24;\n\n    enum FD_CLOEXEC = 1;\n\n    enum F_RDLCK = 1;\n    enum F_UNLCK = 3;\n    enum F_WRLCK = 2;\n    enum F_UNCKSYS = 4;\n\n    enum O_CREAT = 0x0100;\n    enum O_EXCL = 0x0400;\n    enum O_NOCTTY = 0x0800;\n    enum O_TRUNC = 0x0200;\n\n    enum O_APPEND = 0x0008;\n    enum O_NONBLOCK = 0x0080;\n    enum O_SYNC = 0x0010;\n    enum O_DSYNC = 0x0040;\n    enum O_RSYNC = 0x8000;\n\n    enum O_ACCMODE = (O_SEARCH | O_EXEC | 0x3);\n    enum O_RDONLY = 0;\n    enum O_WRONLY = 1;\n    enum O_RDWR = 2;\n    enum O_SEARCH = 0x200000;\n    enum O_EXEC = 0x400000;\n\n    struct flock\n    {\n        short l_type;\n        short l_whence;\n        off_t l_start;\n        off_t l_len;\n        int l_sysid;\n        pid_t l_pid;\n        c_long[4] l_pad;\n    }\n\n    static if (__USE_LARGEFILE64)\n    {\n        struct flock64\n        {\n            short       l_type;\n            short       l_whence;\n            off64_t     l_start;\n            off64_t     l_len;\n            int         l_sysid;\n            pid_t       l_pid;\n            c_long[4]   l_pad;\n        }\n    }\n\n    version (D_LP64)\n    {\n        int creat(in char*, mode_t);\n        int open(in char*, int, ...);\n\n        static if (__USE_LARGEFILE64)\n        {\n            alias creat creat64;\n            alias open open64;\n        }\n    }\n    else\n    {\n        static if (__USE_LARGEFILE64)\n        {\n            int creat64(in char*, mode_t);\n            alias creat64 creat;\n\n            int open64(in char*, int, ...);\n            alias open64 open;\n        }\n        else\n        {\n            int creat(in char*, mode_t);\n            int open(in char*, int, ...);\n        }\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    // All these except for the two functions open and creat really come from\n    // the linux kernel and can probably be merged.\n    enum F_DUPFD        = 0;\n    enum F_GETFD        = 1;\n    enum F_SETFD        = 2;\n    enum F_GETFL        = 3;\n    enum F_SETFL        = 4;\n    enum F_GETLK        = 5;\n    enum F_SETLK        = 6;\n    enum F_SETLKW       = 7;\n    enum F_SETOWN       = 8;\n    enum F_GETOWN       = 9;\n\n    enum FD_CLOEXEC     = 1;\n\n    enum F_RDLCK        = 0;\n    enum F_WRLCK        = 1;\n    enum F_UNLCK        = 2;\n\n    version (X86)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x1000;   // octal   010000\n    }\n    else version (ARM)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x1000;   // octal   010000\n    }\n    else version (AArch64)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x101000; // octal 04010000\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n\n    enum O_ACCMODE      = 0x3;\n    enum O_RDONLY       = 0x0;\n    enum O_WRONLY       = 0x1;\n    enum O_RDWR         = 0x2;\n\n    struct flock\n    {\n        short   l_type;\n        short   l_whence;\n        off_t   l_start;\n        off_t   l_len;\n        pid_t   l_pid;\n    }\n\n    int   creat(in char*, mode_t);\n    int   open(in char*, int, ...);\n\n    enum AT_FDCWD = -100;\n}\nelse version (CRuntime_Musl)\n{\n    enum {\n        O_CREAT         = 0x40,     // octal     0100\n        O_EXCL          = 0x80,     // octal     0200\n        O_NOCTTY        = 0x100,    // octal     0400\n        O_TRUNC         = 0x200,    // octal    01000\n\n        O_APPEND        = 0x400,    // octal    02000\n        O_NONBLOCK      = 0x800,    // octal    04000\n        O_DSYNC         = 0x1000,   // octal   010000\n        O_SYNC          = 0x101000, // octal 04010000\n        O_RSYNC         = O_SYNC,\n        O_DIRECTORY     = 0x10000,\n        O_NOFOLLOW      = 0x20000,\n        O_CLOEXEC       = 0x80000,\n\n        O_ASYNC         = 0x2000,\n        O_DIRECT        = 0x4000,\n        O_LARGEFILE     =      0,\n        O_NOATIME       = 0x40000,\n        O_PATH          = 0x200000,\n        O_TMPFILE       = 0x410000,\n        O_NDELAY        = O_NONBLOCK,\n        O_SEARCH        = O_PATH,\n        O_EXEC          = O_PATH,\n\n        O_ACCMODE       = (03|O_SEARCH),\n        O_RDONLY        = 00,\n        O_WRONLY        = 01,\n        O_RDWR          = 02,\n    }\n    enum {\n        F_DUPFD        = 0,\n        F_GETFD        = 1,\n        F_SETFD        = 2,\n        F_GETFL        = 3,\n        F_SETFL        = 4,\n        F_GETLK        = 5,\n        F_SETLK        = 6,\n        F_SETLKW       = 7,\n        F_SETOWN       = 8,\n        F_GETOWN       = 9,\n    }\n    enum {\n        F_RDLCK        = 0,\n        F_WRLCK        = 1,\n        F_UNLCK        = 2,\n    }\n    struct flock\n    {\n        short   l_type;\n        short   l_whence;\n        off_t   l_start;\n        off_t   l_len;\n        pid_t   l_pid;\n    }\n    enum FD_CLOEXEC     = 1;\n    int open(in char*, int, ...);\n\n    enum AT_FDCWD = -100;\n}\nelse version (CRuntime_UClibc)\n{\n    enum F_DUPFD        = 0;\n    enum F_GETFD        = 1;\n    enum F_SETFD        = 2;\n    enum F_GETFL        = 3;\n    enum F_SETFL        = 4;\n\n    version (X86_64)\n    {\n        enum F_GETLK        = 5;\n        enum F_SETLK        = 6;\n        enum F_SETLKW       = 7;\n    }\n    else static if (__USE_FILE_OFFSET64)\n    {\n        enum F_GETLK        = 5;\n        enum F_SETLK        = 6;\n        enum F_SETLKW       = 7;\n    }\n    else\n    {\n        enum F_GETLK        = 12;\n        enum F_SETLK        = 13;\n        enum F_SETLKW       = 14;\n    }\n\n    enum F_GETOWN       = 9;\n    enum F_SETOWN       = 8;\n\n    enum FD_CLOEXEC     = 1;\n\n    enum F_RDLCK        = 0;\n    enum F_UNLCK        = 2;\n    enum F_WRLCK        = 1;\n\n    version (X86_64)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x1000;   // octal    010000\n        enum O_NDELAY       = O_NONBLOCK;\n        enum O_FSYNC        = O_SYNC;\n        enum O_ASYNC        = 0x2000;   // octal    020000\n    }\n    else version (MIPS32)\n    {\n        enum O_CREAT        = 0x0100;\n        enum O_EXCL         = 0x0400;\n        enum O_NOCTTY       = 0x0800;\n        enum O_TRUNC        = 0x0200;\n\n        enum O_APPEND       = 0x0008;\n        enum O_SYNC         = 0x0010;\n        enum O_NONBLOCK     = 0x0080;\n        enum O_NDELAY       = O_NONBLOCK;\n        enum O_FSYNC        = O_SYNC;\n        enum O_ASYNC        = 0x1000;\n    }\n    else version (ARM)\n    {\n        enum O_CREAT        = 0x40;     // octal     0100\n        enum O_EXCL         = 0x80;     // octal     0200\n        enum O_NOCTTY       = 0x100;    // octal     0400\n        enum O_TRUNC        = 0x200;    // octal    01000\n\n        enum O_APPEND       = 0x400;    // octal    02000\n        enum O_NONBLOCK     = 0x800;    // octal    04000\n        enum O_SYNC         = 0x1000;   // octal    010000\n        enum O_NDELAY       = O_NONBLOCK;\n        enum O_FSYNC        = O_SYNC;\n        enum O_ASYNC        = 0x2000;     // octal 020000\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    enum O_ACCMODE      = 0x3;\n    enum O_RDONLY       = 0x0;\n    enum O_WRONLY       = 0x1;\n    enum O_RDWR         = 0x2;\n\n    struct flock\n    {\n        short   l_type;\n        short   l_whence;\n        static if (__USE_FILE_OFFSET64)\n        {\n            off64_t   l_start;\n            off64_t   l_len;\n        }\n        else\n        {\n            off_t   l_start;\n            off_t   l_len;\n        }\n        pid_t   l_pid;\n    }\n\n    static if ( __USE_FILE_OFFSET64 )\n    {\n        int   creat64(in char*, mode_t);\n        alias creat64 creat;\n\n        int   open64(in char*, int, ...);\n        alias open64 open;\n    }\n    else\n    {\n        int   creat(in char*, mode_t);\n        int   open(in char*, int, ...);\n    }\n\n    enum AT_SYMLINK_NOFOLLOW    = 0x100;\n    enum AT_FDCWD               = -100;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//int creat(in char*, mode_t);\nint fcntl(int, int, ...);\n//int open(in char*, int, ...);\n\n// Generic Posix fallocate\nint posix_fallocate(int, off_t, off_t);\n\n//\n// Advisory Information (ADV)\n//\n/*\nPOSIX_FADV_NORMAL\nPOSIX_FADV_SEQUENTIAL\nPOSIX_FADV_RANDOM\nPOSIX_FADV_WILLNEED\nPOSIX_FADV_DONTNEED\nPOSIX_FADV_NOREUSE\n\nint posix_fadvise(int, off_t, off_t, int);\n*/\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/grp.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009, Sönke Ludwig 2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen, Sönke Ludwig\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.grp;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types; // for gid_t, uid_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// Required\n//\n/*\nstruct group\n{\n    char*   gr_name;\n    char*   gr_passwd;\n    gid_t   gr_gid;\n    char**  gr_mem;\n}\n\ngroup* getgrnam(in char*);\ngroup* getgrgid(gid_t);\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct group\n    {\n        char*   gr_name;\n        char*   gr_passwd;\n        gid_t   gr_gid;\n        char**  gr_mem;\n    }\n}\nelse version (Darwin)\n{\n    struct group\n    {\n        char*   gr_name;\n        char*   gr_passwd;\n        gid_t   gr_gid;\n        char**  gr_mem;\n    }\n}\nelse version (FreeBSD)\n{\n    struct group\n    {\n        char*   gr_name;\n        char*   gr_passwd;\n        gid_t   gr_gid;\n        char**  gr_mem;\n    }\n}\nelse version (NetBSD)\n{\n    struct group\n    {\n        char*   gr_name;\n        char*   gr_passwd;\n        gid_t   gr_gid;\n        char**  gr_mem;\n    }\n}\nelse version (OpenBSD)\n{\n    struct group\n    {\n        char*   gr_name;\n        char*   gr_passwd;\n        gid_t   gr_gid;\n        char**  gr_mem;\n    }\n}\nelse version (DragonFlyBSD)\n{\n    struct group\n    {\n        char*   gr_name;\n        char*   gr_passwd;\n        gid_t   gr_gid;\n        char**  gr_mem;\n    }\n}\nelse version (Solaris)\n{\n    struct group\n    {\n        char*   gr_name;\n        char*   gr_passwd;\n        gid_t   gr_gid;\n        char**  gr_mem;\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    struct group\n    {\n        char*   gr_name;\n        char*   gr_passwd;\n        gid_t   gr_gid;\n        char**  gr_mem;\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    struct group\n    {\n        char*   gr_name;\n        char*   gr_passwd;\n        gid_t   gr_gid;\n        char**  gr_mem;\n    }\n}\nelse version (CRuntime_Musl)\n{\n    struct group\n    {\n        char*   gr_name;\n        char*   gr_passwd;\n        gid_t   gr_gid;\n        char**  gr_mem;\n    }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\ngroup* getgrnam(in char*);\ngroup* getgrgid(gid_t);\n\n//\n// Thread-Safe Functions (TSF)\n//\n/*\nint getgrnam_r(in char*, group*, char*, size_t, group**);\nint getgrgid_r(gid_t, group*, char*, size_t, group**);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int getgrnam_r(in char*, group*, char*, size_t, group**);\n    int getgrgid_r(gid_t, group*, char*, size_t, group**);\n}\nelse version (Darwin)\n{\n    int getgrnam_r(in char*, group*, char*, size_t, group**);\n    int getgrgid_r(gid_t, group*, char*, size_t, group**);\n}\nelse version (FreeBSD)\n{\n    int getgrnam_r(in char*, group*, char*, size_t, group**);\n    int getgrgid_r(gid_t, group*, char*, size_t, group**);\n}\nelse version (NetBSD)\n{\n    int getgrnam_r(in char*, group*, char*, size_t, group**);\n    int getgrgid_r(gid_t, group*, char*, size_t, group**);\n}\nelse version (OpenBSD)\n{\n    int getgrnam_r(in char*, group*, char*, size_t, group**);\n    int getgrgid_r(gid_t, group*, char*, size_t, group**);\n}\nelse version (DragonFlyBSD)\n{\n    int getgrnam_r(in char*, group*, char*, size_t, group**);\n    int getgrgid_r(gid_t, group*, char*, size_t, group**);\n}\nelse version (Solaris)\n{\n    int getgrnam_r(in char*, group*, char*, int, group**);\n    int getgrgid_r(gid_t, group*, char*, int, group**);\n}\nelse version (CRuntime_Bionic)\n{\n}\nelse version (CRuntime_UClibc)\n{\n    int getgrnam_r(in char*, group*, char*, size_t, group**);\n    int getgrgid_r(gid_t, group*, char*, size_t, group**);\n}\nelse version (CRuntime_Musl)\n{\n    int getgrnam_r(in char*, group*, char*, size_t, group**);\n    int getgrgid_r(gid_t, group*, char*, size_t, group**);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// XOpen (XSI)\n//\n/*\nstruct group  *getgrent(void);\nvoid           endgrent(void);\nvoid           setgrent(void);\n*/\n\nversion (CRuntime_Glibc)\n{\n    group* getgrent();\n    @trusted void endgrent();\n    @trusted void setgrent();\n}\nelse version (Darwin)\n{\n    group* getgrent();\n    @trusted void endgrent();\n    @trusted void setgrent();\n}\nelse version (FreeBSD)\n{\n    group* getgrent();\n    @trusted void endgrent();\n    @trusted void setgrent();\n}\nelse version (NetBSD)\n{\n    group* getgrent();\n    @trusted void endgrent();\n    @trusted void setgrent();\n}\nelse version (OpenBSD)\n{\n    group* getgrent();\n    @trusted void endgrent();\n    @trusted void setgrent();\n}\nelse version (DragonFlyBSD)\n{\n    group* getgrent();\n    @trusted void endgrent();\n    @trusted void setgrent();\n}\nelse version (Solaris)\n{\n    group* getgrent();\n    @trusted void endgrent();\n    @trusted void setgrent();\n}\nelse version (CRuntime_Bionic)\n{\n}\nelse version (CRuntime_UClibc)\n{\n    group* getgrent();\n    @trusted void endgrent();\n    @trusted void setgrent();\n}\nelse version (CRuntime_Musl)\n{\n    group* getgrent();\n    @trusted void endgrent();\n    @trusted void setgrent();\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/iconv.d",
    "content": "/*******************************************************************************\n\n    D binding for the POSIX iconv library.\n\n    Defines external functions required to use iconv codeset conversion\n    function.\n\n    iconv_open(3)   Allocates the descriptor for code conversion\n    iconv(3)        Performs the conversion\n    iconvctl(3)     Control iconv behavior\n    iconv_close(3)  Deallocates allocated resources\n\n    Copyright:  Copyright (c) 2016 Sociomantic Labs. All rights reserved.\n    License:    $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:    Nemanja Boric\n    Standards:  POSIX.1-2001, POSIX.1-2008\n    See_Also:\n       http://pubs.opengroup.org/onlinepubs/009695399/functions/iconv_open.html\n\n*******************************************************************************/\n\nmodule core.sys.posix.iconv;\n\nenum\n{\n    ICONV_TRIVIALP            = 0,  /* int *argument */\n    ICONV_GET_TRANSLITERATE   = 1,  /* int *argument */\n    ICONV_SET_TRANSLITERATE   = 2,  /* const int *argument */\n    ICONV_GET_DISCARD_ILSEQ   = 3,  /* int *argument */\n    ICONV_SET_DISCARD_ILSEQ   = 4,  /* const int *argument */\n}\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n\nalias void* iconv_t;\n\n/// Allocate descriptor for code conversion from codeset FROMCODE to\n/// codeset TOCODE.\niconv_t iconv_open (in char* tocode, in char* fromcode);\n\n/// Convert at most *INBYTESLEFT bytes from *INBUF according to the\n/// code conversion algorithm specified by CD and place up to\n/// *OUTBYTESLEFT bytes in buffer at *OUTBUF.\nsize_t iconv (iconv_t cd, in char** inbuf,\n         size_t* inbytesleft,\n         char** outbuf,\n         size_t* outbytesleft);\n\n/// iconvctl queries or adjusts the behavior of the iconv function,\n/// when invoked with the specified conversion descriptor,\n/// depending on the request value.\nint iconvctl (iconv_t cd, int request, void* argument);\n\n/// Free resources allocated for descriptor CD for code conversion.\nint iconv_close (iconv_t cd);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/inttypes.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.inttypes;\n\nprivate import core.sys.posix.config;\npublic import core.stdc.inttypes;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// Required\n//\n/*\nintmax_t  imaxabs(intmax_t);\nimaxdiv_t imaxdiv(intmax_t, intmax_t);\nintmax_t  strtoimax(in char*, char**, int);\nuintmax_t strtoumax(in char *, char**, int);\nintmax_t  wcstoimax(in wchar_t*, wchar_t**, int);\nuintmax_t wcstoumax(in wchar_t*, wchar_t**, int);\n*/\n\nintmax_t  imaxabs(intmax_t);\nimaxdiv_t imaxdiv(intmax_t, intmax_t);\nintmax_t  strtoimax(in char*, char**, int);\nuintmax_t strtoumax(in char *, char**, int);\nintmax_t  wcstoimax(in wchar_t*, wchar_t**, int);\nuintmax_t wcstoumax(in wchar_t*, wchar_t**, int);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/libgen.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: 2016 Sociomantic Labs GmbH\n * License:   <a href=\"http://www.boost.org/LICENSE_1_0.txt\">Boost License 1.0</a>.\n * Authors:   Leandro Lucarella\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sociomantic Labs GmbH 2016.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.libgen;\n\n@nogc nothrow:\nextern (C):\nversion (Posix):\n\nchar* basename(char*);\nchar* dirname(char*);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/mqueue.d",
    "content": "/**\n * D header file for Posix Message Queues\n *\n * Defines external functions required to manage Posix Message Queues\n *\n * mq_open(3)          open a message queue\n * mq_close(3)         close a message queue\n * mq_unlink(3)        remove a message queue\n * mq_send(3)          send a message\n * mq_receive(3)       receive a message\n * mq_timedsend(3)     send a message with a timeout (linux specific)\n * mq_timedreceive(3)  receive a message with a timeout (linux specific)\n * mq_getattr(3)       get message queue attributes\n * mq_setattr(3)       set message queue attributes\n * mq_notify(3)        register asynchronous notify\n *\n * Copyright: Copyright (c) 2016 sociomantic labs. All rights reserved\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Andreas Bok Andersen, Mathias Lang\n * Standards: POSIX.1-2001.\n * See_Also:  $(HTTP pubs.opengroup.org/onlinepubs/9699919799/basedefs/mqueue.h.html, Standard)\n */\nmodule core.sys.posix.mqueue;\n\nimport core.sys.posix.config;\nimport core.sys.posix.signal;\nimport core.sys.posix.time;\n\nversion (Posix):\nversion (CRuntime_Glibc):\nextern (C):\n@nogc nothrow:\n\n\n/// Message queue descriptor.\nalias int mqd_t;\n\n/**\n * Used in getting and setting the attributes of a message queue.\n */\nstruct mq_attr\n{\n    /// Message queue flags.\n    c_long mq_flags;\n    /// Maximum number of messages.\n    c_long mq_maxmsg;\n    /// Maximum message size.\n    c_long mq_msgsize;\n    /// Number of messages currently queued.\n    c_long mq_curmsgs;\n}\n\n\n/**\n * Establish connection between a process and a message queue `name`.\n *\n * Note:\n * Linux prototypes are:\n * mqd_t mq_open (const(char)* name, int oflag);\n * mqd_t mq_open(const(char)* name, int oflag, mode_t mode, mq_attr* attr);\n *\n * Params:\n *   name   = Name of the message queue to open.\n *   oflags = determines the type of access used.\n *            If `O_CREAT` is on `oflag`, the third argument is taken as a\n *            `mode_t`, the mode of the created message queue.\n *            If `O_CREAT` is on `oflag`, the fourth argument is taken as\n *            a pointer to a `mq_attr' (message queue attributes).\n *            If the fourth argument is `null`, default attributes are used.\n *\n * Returns:\n *  Message queue descriptor or (mqd_t) -1 on error.\n */\nmqd_t mq_open(const(char)* name, int oflag, ...);\n\n\n/**\n * Closes the message queue descriptor mqdes.\n *\n * Params:\n *   mqdes = Message queue descriptor to close.\n *\n * Returns:\n *   On success mq_close() returns 0; on error, -1 is returned, with errno\n *   set to indicate the error.\n */\nint mq_close (mqd_t mqdes);\n\n\n/**\n * Query status and attributes of message queue `mqdes`.\n *\n * Params:\n *   mqdes  = Message queue descriptor.\n *   mqstat = Buffer to fill with the message queue's attributes.\n *\n * Returns:\n *   On success mq_getattr() return 0; on error, -1 is returned, with errno\n *   set to indicate the error.\n */\nint mq_getattr (mqd_t mqdes, mq_attr* mqstat);\n\n\n/*\n * Set attributes associated with message queue `mqdes`\n *\n * Params:\n *   mqdes   = Message queue descriptor.\n *   newstat = non-null pointer to fill with attributes for `mqdes`.\n *   oldstat = if not `null` it is filled with the old attributes.\n *\n * Returns:\n *   On success mq_setattr() return 0; on error, -1 is returned, with errno\n *   set to indicate the error.\n */\nint mq_setattr (mqd_t mqdes, const(mq_attr)* newstat, mq_attr* oldstat);\n\n\n/**\n * Remove the specified message queue `name`.\n *\n * Params:\n *   name = Name of the queue to remove.\n *\n * Returns:\n *   On success mq_unlink() returns 0; on error, -1 is returned, with errno\n *   set to indicate the error.\n */\nint mq_unlink (const(char)* name);\n\n\n/**\n * Register for notification when a message is available\n *\n * Params:\n *   mqdes        = Message queue descriptor.\n *   notification = See `man 3 mq_notify` for details.\n *\n * Returns:\n *   On success mq_notify() returns 0; on error, -1 is returned, with errno\n *   set to indicate the error.\n */\nint mq_notify (mqd_t mqdes, const(sigevent)* notification);\n\n\n/**\n * Receive the oldest message with the highest priority the the message queue\n *\n * Params:\n *   mqdes      = Message queue descriptor.\n *   msg_ptr    = Buffer to write the message to\n *   msg_len    = Size of the buffer provided as `msg_ptr`. Must be greater\n *                than the mq_msgsize attribute of the queue.\n *   msg_prio   = If not `null`, set to the priority of this message.\n *\n * Returns:\n *   On success, mq_receive() returns the number of bytes in the received\n *   message; on error, -1 is returned, with errno set to indicate the error\n */\nssize_t mq_receive (mqd_t mqdes, char* msg_ptr, size_t msg_len, uint* msg_prio);\n\n\n/**\n * Receive the oldest message with the highest priority the the message queue,\n * wait up to a certain timeout.\n *\n * Params:\n *   mqdes       = Message queue descriptor.\n *   msg_ptr     = Buffer to write the message to\n *   msg_len     = Size of the buffer provided as `msg_ptr`. Must be greater\n *                 than the mq_msgsize attribute of the queue.\n *   msg_prio    = If not `null`, set to the priority of this message.\n *   abs_timeout = Specify a ceiling on the time to block if the queue is empty.\n *\n * Returns:\n *   On success, mq_receive() returns the number of bytes in the received\n *   message; on error, -1 is returned, with errno set to indicate the error\n */\nssize_t mq_timedreceive (mqd_t mqdes, char* msg_ptr, size_t msg_len,\n                         uint* msg_prio, const(timespec)* abs_timeout);\n\n\n/**\n * Add a message to a message queue.\n *\n * Params:\n *   mqdes      = Message queue descriptor.\n *   msg_ptr    = Buffer to read the message from\n *   msg_len    = Size of the message provided via `msg_ptr`. Must be lower\n *                or equal to the mq_msgsize attribute of the queue.\n *   msg_prio   = Priority of this message.\n *\n * Returns:\n *   On success, mq_send() return zero; on error, -1 is returned, with errno\n *   set to indicate the error.\n */\nint mq_send (mqd_t mqdes, const(char)* msg_ptr, size_t msg_len, uint msg_prio);\n\n\n/**\n * Add a message to a message queue, block up to a certain time if the queue\n * is full.\n *\n * Params:\n *   mqdes      = Message queue descriptor.\n *   msg_ptr    = Buffer to read the message from\n *   msg_len    = Size of the message provided via `msg_ptr`. Must be lower\n *                or equal to the mq_msgsize attribute of the queue.\n *   msg_prio   = Priority of this message.\n *   abs_timeout = Specify a ceiling on the time to block if the queue is empty.\n *\n * Returns:\n *   On success, mq_timedsend() return zero; on error, -1 is returned,\n *   with errno set to indicate the error.\n *\n */\nint mq_timedsend (mqd_t mqdes, const(char)* msg_ptr, size_t msg_len,\n                   uint msg_prio, const(timespec)* abs_timeout);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/net/if_.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.net.if_;\n\nprivate import core.sys.posix.config;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// Required\n//\n/*\nstruct if_nameindex // renamed to if_nameindex_t\n{\n    uint    if_index;\n    char*   if_name;\n}\n\nIF_NAMESIZE\n\nuint            if_nametoindex(in char*);\nchar*           if_indextoname(uint, char*);\nif_nameindex_t* if_nameindex();\nvoid            if_freenameindex(if_nameindex_t*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct if_nameindex_t\n    {\n        uint    if_index;\n        char*   if_name;\n    }\n\n    enum IF_NAMESIZE = 16;\n\n    uint            if_nametoindex(in char*);\n    char*           if_indextoname(uint, char*);\n    if_nameindex_t* if_nameindex();\n    void            if_freenameindex(if_nameindex_t*);\n}\nelse version (Darwin)\n{\n    struct if_nameindex_t\n    {\n        uint    if_index;\n        char*   if_name;\n    }\n\n    enum IF_NAMESIZE = 16;\n\n    uint            if_nametoindex(in char*);\n    char*           if_indextoname(uint, char*);\n    if_nameindex_t* if_nameindex();\n    void            if_freenameindex(if_nameindex_t*);\n}\nelse version (FreeBSD)\n{\n    struct if_nameindex_t\n    {\n        uint    if_index;\n        char*   if_name;\n    }\n\n    enum IF_NAMESIZE = 16;\n\n    uint            if_nametoindex(in char*);\n    char*           if_indextoname(uint, char*);\n    if_nameindex_t* if_nameindex();\n    void            if_freenameindex(if_nameindex_t*);\n}\nelse version (NetBSD)\n{\n    struct if_nameindex_t\n    {\n        uint    if_index;\n        char*   if_name;\n    }\n\n    enum IF_NAMESIZE = 16;\n\n    uint            if_nametoindex(in char*);\n    char*           if_indextoname(uint, char*);\n    if_nameindex_t* if_nameindex();\n    void            if_freenameindex(if_nameindex_t*);\n}\nelse version (DragonFlyBSD)\n{\n    struct if_nameindex_t\n    {\n        uint    if_index;\n        char*   if_name;\n    }\n\n    enum IF_NAMESIZE = 16;\n\n    uint            if_nametoindex(in char*);\n    char*           if_indextoname(uint, char*);\n    if_nameindex_t* if_nameindex();\n    void            if_freenameindex(if_nameindex_t*);\n}\nelse version (CRuntime_Bionic)\n{\n    enum IF_NAMESIZE = 16;\n\n    uint            if_nametoindex(in char*);\n    char*           if_indextoname(uint, char*);\n}\nelse version (CRuntime_UClibc)\n{\n    struct if_nameindex_t\n    {\n        uint    if_index;\n        char*   if_name;\n    }\n\n    enum IF_NAMESIZE = 16;\n\n    uint            if_nametoindex(in char*);\n    char*           if_indextoname(uint, char*);\n    if_nameindex_t* if_nameindex();\n    void            if_freenameindex(if_nameindex_t*);\n}"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/netdb.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright David Nadlinger 2011.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   David Nadlinger, Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright David Nadlinger 2011.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.netdb;\n\nprivate import core.sys.posix.config;\npublic import core.stdc.inttypes;         // for uint32_t\npublic import core.sys.posix.netinet.in_; // for in_port_t, in_addr_t\npublic import core.sys.posix.sys.types;   // for ino_t\npublic import core.sys.posix.sys.socket;  // for socklen_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// Required\n//\n/*\nstruct hostent\n{\n    char*   h_name;\n    char**  h_aliases;\n    int     h_addrtype;\n    int     h_length;\n    char**  h_addr_list;\n}\n\nstruct netent\n{\n    char*   n_name;\n    char**  n_aliase;\n    int     n_addrtype;\n    uint32_t n_net;\n}\n\nstruct protoent\n{\n    char*   p_name;\n    char**  p_aliases;\n    int     p_proto;\n}\n\nstruct servent\n{\n    char*   s_name;\n    char**  s_aliases;\n    int     s_port;\n    char*   s_proto;\n}\n\nIPPORT_RESERVED\n\nh_errno\n\nHOST_NOT_FOUND\nNO_DATA\nNO_RECOVERY\nTRY_AGAIN\n\nstruct addrinfo\n{\n    int         ai_flags;\n    int         ai_family;\n    int         ai_socktype;\n    int         ai_protocol;\n    socklen_t   ai_addrlen;\n    sockaddr*   ai_addr;\n    char*       ai_canonname;\n    addrinfo*   ai_next;\n}\n\nAI_PASSIVE\nAI_CANONNAME\nAI_NUMERICHOST\nAI_NUMERICSERV\nAI_V4MAPPED\nAI_ALL\nAI_ADDRCONFIG\n\nNI_NOFQDN\nNI_NUMERICHOST\nNI_NAMEREQD\nNI_NUMERICSERV\nNI_NUMERICSCOPE\nNI_DGRAM\n\nEAI_AGAIN\nEAI_BADFLAGS\nEAI_FAIL\nEAI_FAMILY\nEAI_MEMORY\nEAI_NONAME\n\nEAI_SERVICE\nEAI_SOCKTYPE\nEAI_SYSTEM\nEAI_OVERFLOW\n\nvoid         endhostent();\nvoid         endnetent();\nvoid         endprotoent();\nvoid         endservent();\nvoid         freeaddrinfo(addrinfo*);\nconst(char)* gai_strerror(int);\nint          getaddrinfo(const(char)*, const(char)*, const(addrinfo)*, addrinfo**);\nhostent*     gethostbyaddr(const(void)*, socklen_t, int);\nhostent*     gethostbyname(const(char)*);\nhostent*     gethostent();\nint          getnameinfo(const(sockaddr)*, socklen_t, char*, socklen_t, char*, socklen_t, int);\nnetent*      getnetbyaddr(uint32_t, int);\nnetent*      getnetbyname(const(char)*);\nnetent*      getnetent();\nprotoent*    getprotobyname(const(char)*);\nprotoent*    getprotobynumber(int);\nprotoent*    getprotoent();\nservent*     getservbyname(const(char)*, const(char)*);\nservent*     getservbyport(int, const(char)*);\nservent*     getservent();\nvoid         sethostent(int);\nvoid         setnetent(int);\nvoid         setprotoent(int);\nvoid         setservent(int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct hostent\n    {\n        char*   h_name;\n        char**  h_aliases;\n        int     h_addrtype;\n        int     h_length;\n        char**  h_addr_list;\n        char*   h_addr() @property { return h_addr_list[0]; } // non-standard\n    }\n\n    struct netent\n    {\n        char*   n_name;\n        char**  n_aliases;\n        int     n_addrtype;\n        uint32_t n_net;\n    }\n\n    struct protoent\n    {\n        char*   p_name;\n        char**  p_aliases;\n        int     p_proto;\n    }\n\n    struct servent\n    {\n        char*   s_name;\n        char**  s_aliases;\n        int     s_port;\n        char*   s_proto;\n    }\n\n    enum IPPORT_RESERVED = 1024;\n\n    //h_errno\n\n    enum HOST_NOT_FOUND = 1;\n    enum NO_DATA        = 4;\n    enum NO_RECOVERY    = 3;\n    enum TRY_AGAIN      = 2;\n\n    struct addrinfo\n    {\n        int         ai_flags;\n        int         ai_family;\n        int         ai_socktype;\n        int         ai_protocol;\n        socklen_t   ai_addrlen;\n        sockaddr*   ai_addr;\n        char*       ai_canonname;\n        addrinfo*   ai_next;\n    }\n\n    enum AI_PASSIVE         = 0x1;\n    enum AI_CANONNAME       = 0x2;\n    enum AI_NUMERICHOST     = 0x4;\n    enum AI_NUMERICSERV     = 0x400;\n    enum AI_V4MAPPED        = 0x8;\n    enum AI_ALL             = 0x10;\n    enum AI_ADDRCONFIG      = 0x20;\n\n    enum NI_NOFQDN          = 4;\n    enum NI_NUMERICHOST     = 1;\n    enum NI_NAMEREQD        = 8;\n    enum NI_NUMERICSERV     = 2;\n    //enum NI_NUMERICSCOPE    = ?;\n    enum NI_DGRAM           = 16;\n    enum NI_MAXHOST         = 1025; // non-standard\n    enum NI_MAXSERV         = 32;   // non-standard\n\n    enum EAI_AGAIN          = -3;\n    enum EAI_BADFLAGS       = -1;\n    enum EAI_FAIL           = -4;\n    enum EAI_FAMILY         = -6;\n    enum EAI_MEMORY         = -10;\n    enum EAI_NONAME         = -2;\n    enum EAI_SERVICE        = -8;\n    enum EAI_SOCKTYPE       = -7;\n    enum EAI_SYSTEM         = -11;\n    enum EAI_OVERFLOW       = -12;\n}\nelse version (Darwin)\n{\n    struct hostent\n    {\n        char*   h_name;\n        char**  h_aliases;\n        int     h_addrtype;\n        int     h_length;\n        char**  h_addr_list;\n        char*   h_addr() @property { return h_addr_list[0]; } // non-standard\n    }\n\n    struct netent\n    {\n        char*   n_name;\n        char**  n_aliases;\n        int     n_addrtype;\n        uint32_t n_net;\n    }\n\n    struct protoent\n    {\n        char*   p_name;\n        char**  p_aliases;\n        int     p_proto;\n    }\n\n    struct servent\n    {\n        char*   s_name;\n        char**  s_aliases;\n        int     s_port;\n        char*   s_proto;\n    }\n\n    enum IPPORT_RESERVED = 1024;\n\n    //h_errno\n\n    enum HOST_NOT_FOUND = 1;\n    enum NO_DATA        = 4;\n    enum NO_RECOVERY    = 3;\n    enum TRY_AGAIN      = 2;\n\n    struct addrinfo\n    {\n        int         ai_flags;\n        int         ai_family;\n        int         ai_socktype;\n        int         ai_protocol;\n        socklen_t   ai_addrlen;\n        char*       ai_canonname;\n        sockaddr*   ai_addr;\n        addrinfo*   ai_next;\n    }\n\n    enum AI_PASSIVE         = 0x1;\n    enum AI_CANONNAME       = 0x2;\n    enum AI_NUMERICHOST     = 0x4;\n    enum AI_NUMERICSERV     = 0x1000;\n    enum AI_V4MAPPED        = 0x800;\n    enum AI_ALL             = 0x100;\n    enum AI_ADDRCONFIG      = 0x400;\n\n    enum NI_NOFQDN          = 0x1;\n    enum NI_NUMERICHOST     = 0x2;\n    enum NI_NAMEREQD        = 0x4;\n    enum NI_NUMERICSERV     = 0x8;\n    //enum NI_NUMERICSCOPE    = ?;\n    enum NI_DGRAM           = 0x10;\n    enum NI_MAXHOST         = 1025; // non-standard\n    enum NI_MAXSERV         = 32;   // non-standard\n\n    enum EAI_AGAIN          = 2;\n    enum EAI_BADFLAGS       = 3;\n    enum EAI_FAIL           = 4;\n    enum EAI_FAMILY         = 5;\n    enum EAI_MEMORY         = 6;\n    enum EAI_NONAME         = 8;\n    enum EAI_SERVICE        = 9;\n    enum EAI_SOCKTYPE       = 10;\n    enum EAI_SYSTEM         = 11;\n    enum EAI_OVERFLOW       = 14;\n}\nelse version (FreeBSD)\n{\n    struct hostent\n    {\n        char*   h_name;\n        char**  h_aliases;\n        int     h_addrtype;\n        int     h_length;\n        char**  h_addr_list;\n        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard\n    }\n\n    struct netent\n    {\n        char*   n_name;\n        char**  n_aliases;\n        int     n_addrtype;\n        uint32_t n_net;\n    }\n\n    struct protoent\n    {\n        char*   p_name;\n        char**  p_aliases;\n        int     p_proto;\n    }\n\n    struct servent\n    {\n        char*   s_name;\n        char**  s_aliases;\n        int     s_port;\n        char*   s_proto;\n    }\n\n    enum IPPORT_RESERVED = 1024;\n\n    //h_errno\n\n    enum HOST_NOT_FOUND = 1;\n    enum NO_DATA        = 4;\n    enum NO_RECOVERY    = 3;\n    enum TRY_AGAIN      = 2;\n\n    struct addrinfo\n    {\n        int         ai_flags;\n        int         ai_family;\n        int         ai_socktype;\n        int         ai_protocol;\n        socklen_t   ai_addrlen;\n        char*       ai_canonname;\n        sockaddr*   ai_addr;\n        addrinfo*   ai_next;\n    }\n\n    enum AI_PASSIVE         = 0x1;\n    enum AI_CANONNAME       = 0x2;\n    enum AI_NUMERICHOST     = 0x4;\n    enum AI_NUMERICSERV     = 0x8;\n    enum AI_V4MAPPED        = 0x800;\n    enum AI_ALL             = 0x100;\n    enum AI_ADDRCONFIG      = 0x400;\n\n    enum NI_NOFQDN          = 0x1;\n    enum NI_NUMERICHOST     = 0x2;\n    enum NI_NAMEREQD        = 0x4;\n    enum NI_NUMERICSERV     = 0x8;\n    //enum NI_NUMERICSCOPE    = ?;\n    enum NI_DGRAM           = 0x10;\n    enum NI_MAXHOST         = 1025; // non-standard\n    enum NI_MAXSERV         = 32;   // non-standard\n\n    enum EAI_AGAIN          = 2;\n    enum EAI_BADFLAGS       = 3;\n    enum EAI_FAIL           = 4;\n    enum EAI_FAMILY         = 5;\n    enum EAI_MEMORY         = 6;\n    enum EAI_NONAME         = 8;\n    enum EAI_SERVICE        = 9;\n    enum EAI_SOCKTYPE       = 10;\n    enum EAI_SYSTEM         = 11;\n    enum EAI_OVERFLOW       = 14;\n}\nelse version (NetBSD)\n{\n    struct hostent\n    {\n        char*   h_name;\n        char**  h_aliases;\n        int     h_addrtype;\n        int     h_length;\n        char**  h_addr_list;\n        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard\n    }\n\n    struct netent\n    {\n        char*   n_name;\n        char**  n_aliases;\n        int     n_addrtype;\n        uint32_t n_net;\n/+ todo\n#if (defined(__sparc__) && defined(_LP64)) || \\\n    (defined(__sh__) && defined(_LP64) && (_BYTE_ORDER == _BIG_ENDIAN))\n        int             __n_pad0;       /* ABI compatibility */\n#endif\n        uint32_t        n_net;          /*%< network # */\n#if defined(__alpha__) || (defined(__i386__) && defined(_LP64)) || \\\n    (defined(__sh__) && defined(_LP64) && (_BYTE_ORDER == _LITTLE_ENDIAN))\n        int             __n_pad0;       /* ABI compatibility */\n#endif\n\n+/\n    }\n\n    struct protoent\n    {\n        char*   p_name;\n        char**  p_aliases;\n        int     p_proto;\n    }\n\n    struct servent\n    {\n        char*   s_name;\n        char**  s_aliases;\n        int     s_port;\n        char*   s_proto;\n    }\n\n    enum IPPORT_RESERVED = 1024;\n\n    //h_errno\n\n    enum HOST_NOT_FOUND = 1;\n    enum NO_DATA        = 4;\n    enum NO_RECOVERY    = 3;\n    enum TRY_AGAIN      = 2;\n\n    struct addrinfo\n    {\n        int         ai_flags;\n        int         ai_family;\n        int         ai_socktype;\n        int         ai_protocol;\n/+todo\n#if defined(__sparc__) && defined(_LP64)\n        int             __ai_pad0;      /* ABI compatibility */\n#endif\n+/\n        socklen_t   ai_addrlen;\n/+todo\n#if defined(__alpha__) || (defined(__i386__) && defined(_LP64))\n        int             __ai_pad0;      /* ABI compatibility */\n#endif\n+/\n        char*       ai_canonname;\n        sockaddr*   ai_addr;\n        addrinfo*   ai_next;\n    }\n\n    enum AI_PASSIVE         = 0x1;\n    enum AI_CANONNAME       = 0x2;\n    enum AI_NUMERICHOST     = 0x4;\n    enum AI_NUMERICSERV     = 0x8;\n    enum AI_V4MAPPED        = 0x800;\n    enum AI_ALL             = 0x100;\n    enum AI_ADDRCONFIG      = 0x400;\n\n    enum NI_NOFQDN          = 0x1;\n    enum NI_NUMERICHOST     = 0x2;\n    enum NI_NAMEREQD        = 0x4;\n    enum NI_NUMERICSERV     = 0x8;\n    enum NI_DGRAM           = 0x10;\n    enum NI_WITHSCOPEID     = 0x00000020;\n    enum NI_NUMERICSCOPE    = 0x00000040;\n    enum NI_MAXHOST         = 1025; // non-standard\n    enum NI_MAXSERV         = 32;   // non-standard\n\n    enum EAI_AGAIN          = 2;\n    enum EAI_BADFLAGS       = 3;\n    enum EAI_FAIL           = 4;\n    enum EAI_FAMILY         = 5;\n    enum EAI_MEMORY         = 6;\n    enum EAI_NONAME         = 8;\n    enum EAI_SERVICE        = 9;\n    enum EAI_SOCKTYPE       = 10;\n    enum EAI_SYSTEM         = 11;\n    enum EAI_OVERFLOW       = 14;\n}\nelse version (OpenBSD)\n{\n    struct hostent\n    {\n        char*     h_name;\n        char**    h_aliases;\n        int       h_addrtype;\n        int       h_length;\n        char**    h_addr_list;\n        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard\n    }\n\n    struct netent\n    {\n        char*     n_name;\n        char**    n_aliases;\n        int       n_addrtype;\n        in_addr_t n_net;\n    }\n\n    struct protoent\n    {\n        char*     p_name;\n        char**    p_aliases;\n        int       p_proto;\n    }\n\n    struct servent\n    {\n        char*     s_name;\n        char**    s_aliases;\n        int       s_port;\n        char*     s_proto;\n    }\n\n    enum IPPORT_RESERVED = 1024;\n\n    //h_errno\n\n    enum NETDB_INTERNAL = -1;\n    enum NETDB_SUCCESS  = 0;\n    enum HOST_NOT_FOUND = 1;\n    enum NO_DATA        = 4;\n    enum NO_RECOVERY    = 3;\n    enum TRY_AGAIN      = 2;\n\n    struct addrinfo\n    {\n        int         ai_flags;\n        int         ai_family;\n        int         ai_socktype;\n        int         ai_protocol;\n        socklen_t   ai_addrlen;\n        char*       ai_canonname;\n        sockaddr*   ai_addr;\n        addrinfo*   ai_next;\n    }\n\n    enum AI_PASSIVE         = 0x1;\n    enum AI_CANONNAME       = 0x2;\n    enum AI_NUMERICHOST     = 0x4;\n    enum AI_EXT             = 0x8;\n    enum AI_NUMERICSERV     = 0x10;\n    enum AI_FQDN            = 0x20;\n    enum AI_ADDRCONFIG      = 0x40;\n    enum AI_MASK            = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | AI_FQDN | AI_ADDRCONFIG;\n\n    enum NI_NUMERICHOST     = 1;\n    enum NI_NUMERICSERV     = 2;\n    enum NI_NOFQDN          = 4;\n    enum NI_NAMEREQD        = 8;\n    enum NI_DGRAM           = 16;\n    //enum NI_NUMERICSCOPE    = 32;\n    enum NI_MAXHOST         = 256; // non-standard\n    enum NI_MAXSERV         = 32;  // non-standard\n\n    enum EAI_NONAME         = -1;\n    enum EAI_BADFLAGS       = -2;\n    enum EAI_AGAIN          = -3;\n    enum EAI_FAIL           = -4;\n    enum EAI_NODATA         = -5;\n    enum EAI_FAMILY         = -6;\n    enum EAI_SOCKTYPE       = -7;\n    enum EAI_SERVICE        = -8;\n    enum EAI_ADDRFAMILY     = -9;\n    enum EAI_MEMORY         = -10;\n    enum EAI_SYSTEM         = -11;\n    enum EAI_BADHINTS       = -12;\n    enum EAI_PROTOCOL       = -13;\n    enum EAI_OVERFLOW       = -14;\n}\nelse version (DragonFlyBSD)\n{\n    /*\n     * Error return codes from gethostbyname() and gethostbyaddr()\n     * (left in h_errno).\n     */\n    struct hostent\n    {\n        char*   h_name;\n        char**  h_aliases;\n        int     h_addrtype;\n        int     h_length;\n        char**  h_addr_list;\n        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard\n    }\n\n    struct netent\n    {\n        char*   n_name;\n        char**  n_aliases;\n        int     n_addrtype;\n        uint32_t n_net;\n    }\n\n    struct protoent\n    {\n        char*   p_name;\n        char**  p_aliases;\n        int     p_proto;\n    }\n\n    struct servent\n    {\n        char*   s_name;\n        char**  s_aliases;\n        int     s_port;\n        char*   s_proto;\n    }\n\n    struct addrinfo\n    {\n        int         ai_flags;\n        int         ai_family;\n        int         ai_socktype = SOCK_STREAM;           /* socktype default value required to be able to perform getAddrInfo on DragonFlyBSD\n                                                          * without socktype set, you get 'servname not supported for ai_socktype'\n                                                          */\n        int         ai_protocol;\n        socklen_t   ai_addrlen;\n        char*       ai_canonname;\n        sockaddr*   ai_addr;\n        addrinfo*   ai_next;\n    }\n\n    enum IPPORT_RESERVED = 1024;\n\n    enum NETDB_INTERNAL = -1;\n    enum NETDB_SUCCESS  = 0;\n    enum HOST_NOT_FOUND = 1;\n    enum TRY_AGAIN      = 2;\n    enum NO_RECOVERY    = 3;\n    enum NO_DATA        = 4;\n    enum NO_ADDRESS     = NO_DATA;\n\n    //enum EAI_ADDRFAMILY     = 1; // deprecated\n    enum EAI_AGAIN          = 2;\n    enum EAI_BADFLAGS       = 3;\n    enum EAI_FAIL           = 4;\n    enum EAI_FAMILY         = 5;\n    enum EAI_MEMORY         = 6;\n    //enum EAI_NODATA         = 7; // deprecated\n    enum EAI_NONAME         = 8;\n    enum EAI_SERVICE        = 9;\n    enum EAI_SOCKTYPE       = 10;\n    enum EAI_SYSTEM         = 11;\n    enum EAI_BADHINTS       = 12;\n    enum EAI_PROTOCOL       = 13;\n    enum EAI_OVERFLOW       = 14;\n\n    enum AI_PASSIVE         = 0x001;\n    enum AI_CANONNAME       = 0x002;\n    enum AI_NUMERICHOST     = 0x004;\n    enum AI_NUMERICSERV     = 0x008;\n    enum AI_MASK            = (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG);   // valid flags for addrinfo (not a standard def, apps should not use it)\n    enum AI_ALL             = 0x100;\n    enum AI_V4MAPPED_CFG    = 0x200;\n    enum AI_ADDRCONFIG      = 0x400;\n    enum AI_V4MAPPED        = 0x800;\n    enum AI_DEFAULT         = (AI_V4MAPPED_CFG | AI_ADDRCONFIG);\n\n    enum NI_MAXHOST         = 1025; // non-standard\n    enum NI_MAXSERV         = 32;   // non-standard\n\n    enum NI_NOFQDN          = 0x01;\n    enum NI_NUMERICHOST     = 0x02;\n    enum NI_NAMEREQD        = 0x04;\n    enum NI_NUMERICSERV     = 0x08;\n    enum NI_DGRAM           = 0x10;\n    //enum NI_WITHSCOPEID     = 0x20; // deprecated\n    enum NI_NUMERICSCOPE    = 0x40;\n\n}\nelse version (Solaris)\n{\n    struct hostent\n    {\n        char* h_name;\n        char** h_aliases;\n        int h_addrtype;\n        int h_length;\n        char** h_addr_list;\n\n        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard\n    }\n\n    struct netent\n    {\n        char* n_name;\n        char** n_aliases;\n        int n_addrtype;\n        uint32_t n_net;\n    }\n\n    struct protoent\n    {\n        char* p_name;\n        char** p_aliases;\n        int p_proto;\n    }\n\n    struct servent\n    {\n        char* s_name;\n        char** s_aliases;\n        int s_port;\n        char* s_proto;\n    }\n\n    enum HOST_NOT_FOUND = 1;\n    enum TRY_AGAIN = 2;\n    enum NO_RECOVERY = 3;\n    enum NO_DATA = 4;\n\n    struct addrinfo\n    {\n        int ai_flags;\n        int ai_family;\n        int ai_socktype;\n        int ai_protocol;\n\n        version (SPARC)\n            int _ai_pad;\n        else version (SPARC64)\n            int _ai_pad;\n\n        socklen_t ai_addrlen;\n        char* ai_canonname;\n        sockaddr* ai_addr;\n        addrinfo* ai_next;\n    }\n\n    enum AI_PASSIVE = 0x0008;\n    enum AI_CANONNAME = 0x0010;\n    enum AI_NUMERICHOST = 0x0020;\n    enum AI_NUMERICSERV = 0x0040;\n    enum AI_V4MAPPED = 0x0001;\n    enum AI_ALL = 0x0002;\n    enum AI_ADDRCONFIG = 0x0004;\n\n    enum NI_NOFQDN = 0x0001;\n    enum NI_NUMERICHOST = 0x0002;\n    enum NI_NAMEREQD = 0x0004;\n    enum NI_NUMERICSERV = 0x0008;\n    enum NI_DGRAM = 0x0010;\n    enum NI_WITHSCOPEID = 0x0020;\n    enum NI_NUMERICSCOPE = 0x0040;\n    enum NI_MAXHOST = 1025;\n    enum NI_MAXSERV = 32;\n\n    enum EAI_AGAIN = 2;\n    enum EAI_BADFLAGS = 3;\n    enum EAI_FAIL = 4;\n    enum EAI_FAMILY = 5;\n    enum EAI_MEMORY = 6;\n    enum EAI_NONAME = 8;\n    enum EAI_SERVICE = 9;\n    enum EAI_SOCKTYPE = 10;\n    enum EAI_SYSTEM = 11;\n    enum EAI_OVERFLOW = 14;\n    enum EAI_PROTOCOL = 13;\n    enum EAI_MAX = 14;\n}\nelse version (CRuntime_Bionic)\n{\n    struct hostent\n    {\n        char*   h_name;\n        char**  h_aliases;\n        int     h_addrtype;\n        int     h_length;\n        char**  h_addr_list;\n        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard\n    }\n\n    struct netent\n    {\n        char*   n_name;\n        char**  n_aliases;\n        int     n_addrtype;\n        uint32_t n_net;\n    }\n\n    struct protoent\n    {\n        char*   p_name;\n        char**  p_aliases;\n        int     p_proto;\n    }\n\n    struct servent\n    {\n        char*   s_name;\n        char**  s_aliases;\n        int     s_port;\n        char*   s_proto;\n    }\n\n    enum IPPORT_RESERVED = 1024;\n\n    enum HOST_NOT_FOUND = 1;\n    enum NO_DATA        = 4;\n    enum NO_RECOVERY    = 3;\n    enum TRY_AGAIN      = 2;\n\n    struct addrinfo\n    {\n        int         ai_flags;\n        int         ai_family;\n        int         ai_socktype;\n        int         ai_protocol;\n        socklen_t   ai_addrlen;\n        char*       ai_canonname;\n        sockaddr*   ai_addr;\n        addrinfo*   ai_next;\n    }\n\n    enum AI_PASSIVE         = 0x1;\n    enum AI_CANONNAME       = 0x2;\n    enum AI_NUMERICHOST     = 0x4;\n    enum AI_NUMERICSERV     = 0x8;\n    enum AI_V4MAPPED        = 0x800;\n    enum AI_ALL             = 0x100;\n    enum AI_ADDRCONFIG      = 0x400;\n\n    enum NI_NOFQDN          = 0x1;\n    enum NI_NUMERICHOST     = 0x2;\n    enum NI_NAMEREQD        = 0x4;\n    enum NI_NUMERICSERV     = 0x8;\n    enum NI_DGRAM           = 0x10;\n    enum NI_MAXHOST         = 1025; // non-standard\n    enum NI_MAXSERV         = 32;   // non-standard\n\n    enum EAI_AGAIN          = 2;\n    enum EAI_BADFLAGS       = 3;\n    enum EAI_FAIL           = 4;\n    enum EAI_FAMILY         = 5;\n    enum EAI_MEMORY         = 6;\n    enum EAI_NONAME         = 8;\n    enum EAI_SERVICE        = 9;\n    enum EAI_SOCKTYPE       = 10;\n    enum EAI_SYSTEM         = 11;\n    enum EAI_OVERFLOW       = 14;\n}\nelse version (CRuntime_Musl)\n{\n    struct hostent\n    {\n        char*   h_name;\n        char**  h_aliases;\n        int     h_addrtype;\n        int     h_length;\n        char**  h_addr_list;\n        char*   h_addr() @property { return h_addr_list[0]; } // non-standard\n    }\n\n    struct netent\n    {\n        char*     n_name;\n        char**    n_aliases;\n        int       n_addrtype;\n        uint32_t n_net;\n    }\n\n    struct protoent\n    {\n        char*   p_name;\n        char**  p_aliases;\n        int     p_proto;\n    }\n\n    struct servent\n    {\n        char*     s_name;\n        char**    s_aliases;\n        int       s_port;\n        char*     s_proto;\n    }\n\n    struct addrinfo\n    {\n        int         ai_flags;\n        int         ai_family;\n        int         ai_socktype;\n        int         ai_protocol;\n        socklen_t   ai_addrlen;\n        sockaddr*   ai_addr;\n        char*       ai_canonname;\n        addrinfo*   ai_next;\n    }\n\n    enum {\n        AI_PASSIVE         = 0x1,\n        AI_CANONNAME       = 0x2,\n        AI_NUMERICHOST     = 0x4,\n        AI_NUMERICSERV     = 0x400,\n        AI_V4MAPPED        = 0x8,\n        AI_ALL             = 0x10,\n        AI_ADDRCONFIG      = 0x20,\n    }\n    enum {\n        NI_NUMERICHOST     = 1,\n        NI_NUMERICSERV     = 2,\n        NI_NOFQDN          = 4,\n        NI_NAMEREQD        = 8,\n        NI_DGRAM           = 16,\n        NI_MAXSERV         = 32,\n        NI_MAXHOST         = 255,\n    }\n    enum {\n        EAI_BADFLAGS       = -1,\n        EAI_NONAME         = -2,\n        EAI_AGAIN          = -3,\n        EAI_FAIL           = -4,\n        EAI_FAMILY         = -6,\n        EAI_SOCKTYPE       = -7,\n        EAI_SERVICE        = -8,\n        EAI_MEMORY         = -10,\n        EAI_SYSTEM         = -11,\n        EAI_OVERFLOW       = -12,\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    struct hostent\n    {\n        char*   h_name;\n        char**  h_aliases;\n        int     h_addrtype;\n        int     h_length;\n        char**  h_addr_list;\n        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard\n    }\n\n    struct netent\n    {\n        char*   n_name;\n        char**  n_aliases;\n        int     n_addrtype;\n        uint32_t n_net;\n    }\n\n    struct protoent\n    {\n        char*   p_name;\n        char**  p_aliases;\n        int     p_proto;\n    }\n\n    struct servent\n    {\n        char*   s_name;\n        char**  s_aliases;\n        int     s_port;\n        char*   s_proto;\n    }\n\n    enum IPPORT_RESERVED = 1024;\n\n    enum HOST_NOT_FOUND = 1;\n    enum NO_DATA        = 4;\n    enum NO_RECOVERY    = 3;\n    enum TRY_AGAIN      = 2;\n\n    struct addrinfo\n    {\n        int         ai_flags;\n        int         ai_family;\n        int         ai_socktype;\n        int         ai_protocol;\n        socklen_t   ai_addrlen;\n        sockaddr*   ai_addr;\n        char*       ai_canonname;\n        addrinfo*   ai_next;\n    }\n\n    enum AI_PASSIVE         = 0x1;\n    enum AI_CANONNAME       = 0x2;\n    enum AI_NUMERICHOST     = 0x4;\n    enum AI_NUMERICSERV     = 0x400;\n    enum AI_V4MAPPED        = 0x8;\n    enum AI_ALL             = 0x10;\n    enum AI_ADDRCONFIG      = 0x20;\n\n    enum NI_NOFQDN          = 4;\n    enum NI_NUMERICHOST     = 1;\n    enum NI_NAMEREQD        = 8;\n    enum NI_NUMERICSERV     = 2;\n    enum NI_DGRAM           = 16;\n    enum NI_MAXHOST         = 1025; // non-standard\n    enum NI_MAXSERV         = 32;   // non-standard\n\n    enum EAI_AGAIN          = -3;\n    enum EAI_BADFLAGS       = -1;\n    enum EAI_FAIL           = -4;\n    enum EAI_FAMILY         = -6;\n    enum EAI_MEMORY         = -10;\n    enum EAI_NONAME         = -2;\n    enum EAI_SERVICE        = -8;\n    enum EAI_SOCKTYPE       = -7;\n    enum EAI_SYSTEM         = -11;\n    enum EAI_OVERFLOW       = -12;\n\n    enum EAI_NODATA         = -5;\n    enum EAI_ADDRFAMILY     = -9;\n    enum EAI_INPROGRESS     = -100;\n    enum EAI_CANCELED       = -101;\n    enum EAI_NOTCANCELED    = -102;\n    enum EAI_ALLDONE        = -103;\n    enum EAI_INTR           = -104;\n    enum EAI_IDN_ENCODE     = -105;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\nvoid         endhostent();\nvoid         endnetent();\nvoid         endprotoent();\nvoid         endservent();\nvoid         freeaddrinfo(addrinfo*);\nconst(char)* gai_strerror(int);\nint          getaddrinfo(const(char)*, const(char)*, const(addrinfo)*, addrinfo**);\nhostent*     gethostbyaddr(const(void)*, socklen_t, int);\nhostent*     gethostbyname(const(char)*);\nhostent*     gethostent();\nint          getnameinfo(const(sockaddr)*, socklen_t, char*, socklen_t, char*, socklen_t, int);\nnetent*      getnetbyaddr(uint32_t, int);\nnetent*      getnetbyname(const(char)*);\nnetent*      getnetent();\nprotoent*    getprotobyname(const(char)*);\nprotoent*    getprotobynumber(int);\nprotoent*    getprotoent();\nservent*     getservbyname(const(char)*, const(char)*);\nservent*     getservbyport(int, const(char)*);\nservent*     getservent();\nvoid         sethostent(int);\nvoid         setnetent(int);\nvoid         setprotoent(int);\nvoid         setservent(int);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/netinet/in_.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.netinet.in_;\n\nprivate import core.sys.posix.config;\npublic import core.stdc.inttypes; // for uint32_t, uint16_t, uint8_t\npublic import core.sys.posix.arpa.inet;\npublic import core.sys.posix.sys.socket; // for sa_family_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// Required\n//\n/*\nNOTE: The following must must be defined in core.sys.posix.arpa.inet to break\n      a circular import: in_port_t, in_addr_t, struct in_addr, INET_ADDRSTRLEN.\n\nin_port_t\nin_addr_t\n\nsa_family_t // from core.sys.posix.sys.socket\nuint8_t     // from core.stdc.inttypes\nuint32_t    // from core.stdc.inttypes\n\nstruct in_addr\n{\n    in_addr_t   s_addr;\n}\n\nstruct sockaddr_in\n{\n    sa_family_t sin_family;\n    in_port_t   sin_port;\n    in_addr     sin_addr;\n}\n\nIPPROTO_IP\nIPPROTO_ICMP\nIPPROTO_TCP\nIPPROTO_UDP\n\nINADDR_ANY\nINADDR_BROADCAST\n\nINET_ADDRSTRLEN\n\nhtonl() // from core.sys.posix.arpa.inet\nhtons() // from core.sys.posix.arpa.inet\nntohl() // from core.sys.posix.arpa.inet\nntohs() // from core.sys.posix.arpa.inet\n*/\n\nversion (CRuntime_Glibc)\n{\n    // Some networking constants are subtly different for glibc, linux kernel\n    // constants are also provided below.\n\n    //alias uint16_t in_port_t;\n    //alias uint32_t in_addr_t;\n\n    //struct in_addr\n    //{\n    //    in_addr_t s_addr;\n    //}\n\n    private enum __SOCK_SIZE__ = 16;\n\n    struct sockaddr_in\n    {\n        sa_family_t sin_family;\n        in_port_t   sin_port;\n        in_addr     sin_addr;\n\n        /* Pad to size of `struct sockaddr'. */\n        ubyte[__SOCK_SIZE__ - sa_family_t.sizeof -\n              in_port_t.sizeof - in_addr.sizeof] __pad;\n    }\n\n    enum\n    {\n        IPPROTO_IP   = 0,\n        IPPROTO_ICMP = 1,\n        IPPROTO_IGMP = 2,\n        IPPROTO_GGP  = 3,\n        IPPROTO_TCP  = 6,\n        IPPROTO_PUP  = 12,\n        IPPROTO_UDP  = 17,\n        IPPROTO_IDP  = 22,\n        IPPROTO_ND   = 77,\n        IPPROTO_MAX  = 256\n    }\n\n    enum : uint\n    {\n        INADDR_ANY       = 0x00000000,\n        INADDR_BROADCAST = 0xffffffff,\n        INADDR_LOOPBACK  = 0x7F000001,\n        INADDR_NONE      = 0xFFFFFFFF\n    }\n\n    //enum INET_ADDRSTRLEN       = 16;\n}\nelse version (Darwin)\n{\n    //alias uint16_t in_port_t;\n    //alias uint32_t in_addr_t;\n\n    //struct in_addr\n    //{\n    //    in_addr_t s_addr;\n    //}\n\n    private enum __SOCK_SIZE__ = 16;\n\n    struct sockaddr_in\n    {\n        ubyte       sin_len;\n        sa_family_t sin_family;\n        in_port_t   sin_port;\n        in_addr     sin_addr;\n        ubyte[8]    sin_zero;\n    }\n\n    enum\n    {\n        IPPROTO_IP   = 0,\n        IPPROTO_ICMP = 1,\n        IPPROTO_IGMP = 2,\n        IPPROTO_GGP  = 3,\n        IPPROTO_TCP  = 6,\n        IPPROTO_PUP  = 12,\n        IPPROTO_UDP  = 17,\n        IPPROTO_IDP  = 22,\n        IPPROTO_ND   = 77,\n        IPPROTO_MAX  = 256\n    }\n\n    enum : uint\n    {\n        INADDR_ANY       = 0x00000000,\n        INADDR_BROADCAST = 0xffffffff,\n        INADDR_LOOPBACK  = 0x7F000001,\n        INADDR_NONE      = 0xFFFFFFFF\n    }\n\n    //enum INET_ADDRSTRLEN       = 16;\n}\nelse version (FreeBSD)\n{\n    //alias uint16_t in_port_t;\n    //alias uint32_t in_addr_t;\n\n    //struct in_addr\n    //{\n    //    in_addr_t s_addr;\n    //}\n\n    struct sockaddr_in\n    {\n        ubyte       sin_len;\n        sa_family_t sin_family;\n        in_port_t   sin_port;\n        in_addr     sin_addr;\n        ubyte[8]    sin_zero;\n    }\n\n    enum\n    {\n        IPPROTO_IP   = 0,\n        IPPROTO_ICMP = 1,\n        IPPROTO_IGMP = 2,\n        IPPROTO_GGP  = 3,\n        IPPROTO_TCP  = 6,\n        IPPROTO_PUP  = 12,\n        IPPROTO_UDP  = 17,\n        IPPROTO_IDP  = 22,\n        IPPROTO_ND   = 77,\n        IPPROTO_MAX  = 256\n    }\n\n    enum : uint\n    {\n        INADDR_ANY       = 0x00000000,\n        INADDR_BROADCAST = 0xffffffff,\n        INADDR_LOOPBACK  = 0x7f000001,\n        INADDR_NONE      = 0xffffffff\n    }\n\n    //enum INET_ADDRSTRLEN       = 16;\n}\nelse version (NetBSD)\n{\n    struct sockaddr_in\n    {\n        ubyte       sin_len;\n        sa_family_t sin_family;\n        in_port_t   sin_port;\n        in_addr     sin_addr;\n        ubyte[8]    sin_zero;\n    }\n\n    enum\n    {\n        IPPROTO_IP   = 0,\n        IPPROTO_ICMP = 1,\n        IPPROTO_IGMP = 2,\n        IPPROTO_GGP  = 3,\n        IPPROTO_TCP  = 6,\n        IPPROTO_PUP  = 12,\n        IPPROTO_UDP  = 17,\n        IPPROTO_IDP  = 22,\n        IPPROTO_ND   = 77,\n        IPPROTO_MAX  = 256\n    }\n\n    enum : uint\n    {\n        INADDR_ANY       = 0x00000000,\n        INADDR_BROADCAST = 0xffffffff,\n        INADDR_LOOPBACK  = 0x7f000001,\n        INADDR_NONE      = 0xffffffff\n    }\n\n    //enum INET_ADDRSTRLEN       = 16;\n}\nelse version (DragonFlyBSD)\n{\n    //alias uint16_t in_port_t;\n    //alias uint32_t in_addr_t;\n\n    //struct in_addr\n    //{\n    //    in_addr_t s_addr;\n    //}\n\n    struct sockaddr_in\n    {\n        ubyte       sin_len;\n        sa_family_t sin_family;\n        in_port_t   sin_port;\n        in_addr     sin_addr;\n        ubyte[8]    sin_zero;\n    }\n\n    enum\n    {\n        IPPROTO_IP   = 0,\n        IPPROTO_ICMP = 1,\n        IPPROTO_IGMP = 2,\n        IPPROTO_GGP  = 3,\n        IPPROTO_TCP  = 6,\n        IPPROTO_PUP  = 12,\n        IPPROTO_UDP  = 17,\n        IPPROTO_IDP  = 22,\n        IPPROTO_ND   = 77,\n        IPPROTO_MAX  = 256\n    }\n\n    enum : uint\n    {\n        INADDR_ANY       = 0x00000000,\n        INADDR_LOOPBACK  = 0x7f000001,\n        INADDR_BROADCAST = 0xffffffff,\n        INADDR_NONE      = 0xffffffff,\n    }\n\n    //enum INET_ADDRSTRLEN       = 16;\n}\nelse version (CRuntime_UClibc)\n{\n    private enum __SOCK_SIZE__ = 16;\n\n    struct sockaddr_in\n    {\n        sa_family_t sin_family;\n        in_port_t   sin_port;\n        in_addr     sin_addr;\n\n        ubyte[__SOCK_SIZE__ - short.sizeof -\n              ushort.sizeof - in_addr.sizeof] __pad;\n    }\n\n    enum\n    {\n        IPPROTO_IP      = 0,\n        IPPROTO_ICMP    = 1,\n        IPPROTO_IGMP    = 2,\n        IPPROTO_GGP     = 3,\n        IPPROTO_IPIP    = 4,\n        IPPROTO_TCP     = 6,\n        IPPROTO_EGP     = 8,\n        IPPROTO_PUP     = 12,\n        IPPROTO_UDP     = 17,\n        IPPROTO_IDP     = 22,\n        IPPROTO_TP      = 29,\n        IPPROTO_DCCP    = 33,\n        IPPROTO_RSVP    = 46,\n        IPPROTO_GRE     = 47,\n        IPPROTO_ESP     = 50,\n        IPPROTO_AH      = 51,\n        IPPROTO_MTP     = 92,\n        IPPROTO_BEETPH  = 94,\n        IPPROTO_ENCAP   = 98,\n        IPPROTO_PIM     = 103,\n        IPPROTO_COMP    = 108,\n        IPPROTO_SCTP    = 132,\n        IPPROTO_UDPLITE = 136,\n        IPPROTO_MPLS    = 137,\n        IPPROTO_MAX     = 256\n    }\n\n    enum : uint\n    {\n        INADDR_ANY       = 0x00000000,\n        INADDR_BROADCAST = 0xffffffff,\n        IN_LOOPBACKNET   = 127,\n        INADDR_LOOPBACK  = 0x7F000001,\n        INADDR_NONE      = 0xFFFFFFFF\n    }\n}\nelse version (Solaris)\n{\n    struct sockaddr_in\n    {\n        sa_family_t sin_family;\n        in_port_t   sin_port;\n        in_addr     sin_addr;\n        ubyte[8]    sin_zero;\n    }\n\n    enum\n    {\n        IPPROTO_IP   = 0,\n        IPPROTO_ICMP = 1,\n        IPPROTO_IGMP = 2,\n        IPPROTO_GGP  = 3,\n        IPPROTO_TCP  = 6,\n        IPPROTO_PUP  = 12,\n        IPPROTO_UDP  = 17,\n        IPPROTO_IDP  = 22,\n        IPPROTO_ND   = 77,\n        IPPROTO_MAX  = 256\n    }\n\n    enum : uint\n    {\n        INADDR_ANY       = 0x00000000,\n        INADDR_BROADCAST = 0xffffffff,\n        INADDR_LOOPBACK  = 0x7f000001,\n        INADDR_NONE      = 0xffffffff\n    }\n}\nelse version (linux)\n{\n    private enum __SOCK_SIZE__ = 16;\n\n    struct sockaddr_in\n    {\n        sa_family_t sin_family;\n        ushort      sin_port;\n        in_addr     sin_addr;\n\n        /* Pad to size of `struct sockaddr'. */\n        ubyte[__SOCK_SIZE__ - sa_family_t.sizeof -\n              ushort.sizeof - in_addr.sizeof] __pad;\n    }\n\n    enum\n    {\n        IPPROTO_IP   = 0,\n        IPPROTO_ICMP = 1,\n        IPPROTO_IGMP = 2,\n        IPPROTO_GGP  = 3,\n        IPPROTO_TCP  = 6,\n        IPPROTO_PUP  = 12,\n        IPPROTO_UDP  = 17,\n        IPPROTO_IDP  = 22\n    }\n\n    enum : c_ulong\n    {\n        INADDR_ANY       = 0x00000000,\n        INADDR_BROADCAST = 0xffffffff,\n        INADDR_LOOPBACK  = 0x7f000001,\n        INADDR_NONE      = 0xFFFFFFFF\n    }\n}\n\n\n//\n// IPV6 (IP6)\n//\n/*\nNOTE: The following must must be defined in core.sys.posix.arpa.inet to break\n      a circular import: INET6_ADDRSTRLEN.\n\nstruct in6_addr\n{\n    uint8_t[16] s6_addr;\n}\n\nstruct sockaddr_in6\n{\n    sa_family_t sin6_family;\n    in_port_t   sin6_port;\n    uint32_t    sin6_flowinfo;\n    in6_addr    sin6_addr;\n    uint32_t    sin6_scope_id;\n}\n\nextern in6_addr in6addr_any;\nextern in6_addr in6addr_loopback;\n\nstruct ipv6_mreq\n{\n    in6_addr    ipv6mr_multiaddr;\n    uint        ipv6mr_interface;\n}\n\nIPPROTO_IPV6\n\nINET6_ADDRSTRLEN\n\nIPV6_JOIN_GROUP\nIPV6_LEAVE_GROUP\nIPV6_MULTICAST_HOPS\nIPV6_MULTICAST_IF\nIPV6_MULTICAST_LOOP\nIPV6_UNICAST_HOPS\nIPV6_V6ONLY\n\n// macros\nint IN6_IS_ADDR_UNSPECIFIED(in6_addr*)\nint IN6_IS_ADDR_LOOPBACK(in6_addr*)\nint IN6_IS_ADDR_MULTICAST(in6_addr*)\nint IN6_IS_ADDR_LINKLOCAL(in6_addr*)\nint IN6_IS_ADDR_SITELOCAL(in6_addr*)\nint IN6_IS_ADDR_V4MAPPED(in6_addr*)\nint IN6_IS_ADDR_V4COMPAT(in6_addr*)\nint IN6_IS_ADDR_MC_NODELOCAL(in6_addr*)\nint IN6_IS_ADDR_MC_LINKLOCAL(in6_addr*)\nint IN6_IS_ADDR_MC_SITELOCAL(in6_addr*)\nint IN6_IS_ADDR_MC_ORGLOCAL(in6_addr*)\nint IN6_IS_ADDR_MC_GLOBAL(in6_addr*)\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct in6_addr\n    {\n        union\n        {\n            uint8_t[16] s6_addr;\n            uint16_t[8] s6_addr16;\n            uint32_t[4] s6_addr32;\n        }\n    }\n\n    struct sockaddr_in6\n    {\n        sa_family_t sin6_family;\n        in_port_t   sin6_port;\n        uint32_t    sin6_flowinfo;\n        in6_addr    sin6_addr;\n        uint32_t    sin6_scope_id;\n    }\n\n    extern __gshared immutable in6_addr in6addr_any;\n    extern __gshared immutable in6_addr in6addr_loopback;\n\n    struct ipv6_mreq\n    {\n        in6_addr    ipv6mr_multiaddr;\n        uint        ipv6mr_interface;\n    }\n\n    enum : uint\n    {\n        IPPROTO_IPV6        = 41,\n\n        //INET6_ADDRSTRLEN    = 46,\n\n        IPV6_JOIN_GROUP     = 20,\n        IPV6_LEAVE_GROUP    = 21,\n        IPV6_MULTICAST_HOPS = 18,\n        IPV6_MULTICAST_IF   = 17,\n        IPV6_MULTICAST_LOOP = 19,\n        IPV6_UNICAST_HOPS   = 16,\n        IPV6_V6ONLY         = 26\n    }\n\n    // macros\n    extern (D) int IN6_IS_ADDR_UNSPECIFIED( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0 &&\n               (cast(uint32_t*) addr)[1] == 0 &&\n               (cast(uint32_t*) addr)[2] == 0 &&\n               (cast(uint32_t*) addr)[3] == 0;\n    }\n\n    extern (D) int IN6_IS_ADDR_LOOPBACK( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0  &&\n               (cast(uint32_t*) addr)[1] == 0  &&\n               (cast(uint32_t*) addr)[2] == 0  &&\n               (cast(uint32_t*) addr)[3] == htonl( 1 );\n    }\n\n    extern (D) int IN6_IS_ADDR_MULTICAST( in6_addr* addr ) pure\n    {\n        return (cast(uint8_t*) addr)[0] == 0xff;\n    }\n\n    extern (D) int IN6_IS_ADDR_LINKLOCAL( in6_addr* addr ) pure\n    {\n        return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfe800000 );\n    }\n\n    extern (D) int IN6_IS_ADDR_SITELOCAL( in6_addr* addr ) pure\n    {\n        return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfec00000 );\n    }\n\n    extern (D) int IN6_IS_ADDR_V4MAPPED( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0 &&\n               (cast(uint32_t*) addr)[1] == 0 &&\n               (cast(uint32_t*) addr)[2] == htonl( 0xffff );\n    }\n\n    extern (D) int IN6_IS_ADDR_V4COMPAT( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0 &&\n               (cast(uint32_t*) addr)[1] == 0 &&\n               (cast(uint32_t*) addr)[2] == 0 &&\n               ntohl( (cast(uint32_t*) addr)[3] ) > 1;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr ) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x1;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr ) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x2;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(addr) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x5;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x8;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_GLOBAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr ) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0xe;\n    }\n}\nelse version (Darwin)\n{\n    struct in6_addr\n    {\n        union\n        {\n            uint8_t[16] s6_addr;\n            uint16_t[8] s6_addr16;\n            uint32_t[4] s6_addr32;\n        }\n    }\n\n    struct sockaddr_in6\n    {\n        uint8_t     sin6_len;\n        sa_family_t sin6_family;\n        in_port_t   sin6_port;\n        uint32_t    sin6_flowinfo;\n        in6_addr    sin6_addr;\n        uint32_t    sin6_scope_id;\n    }\n\n    extern __gshared immutable in6_addr in6addr_any;\n    extern __gshared immutable in6_addr in6addr_loopback;\n\n    struct ipv6_mreq\n    {\n        in6_addr    ipv6mr_multiaddr;\n        uint        ipv6mr_interface;\n    }\n\n    enum : uint\n    {\n        IPPROTO_IPV6        = 41,\n\n        //INET6_ADDRSTRLEN    = 46,\n\n        IPV6_JOIN_GROUP     = 12,\n        IPV6_LEAVE_GROUP    = 13,\n        IPV6_MULTICAST_HOPS = 10,\n        IPV6_MULTICAST_IF   = 9,\n        IPV6_MULTICAST_LOOP = 11,\n        IPV6_UNICAST_HOPS   = 4,\n        IPV6_V6ONLY         = 27\n    }\n\n    // macros\n    extern (D) int IN6_IS_ADDR_UNSPECIFIED( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0 &&\n               (cast(uint32_t*) addr)[1] == 0 &&\n               (cast(uint32_t*) addr)[2] == 0 &&\n               (cast(uint32_t*) addr)[3] == 0;\n    }\n\n    extern (D) int IN6_IS_ADDR_LOOPBACK( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0  &&\n               (cast(uint32_t*) addr)[1] == 0  &&\n               (cast(uint32_t*) addr)[2] == 0  &&\n               (cast(uint32_t*) addr)[3] == ntohl( 1 );\n    }\n\n    extern (D) int IN6_IS_ADDR_MULTICAST( in6_addr* addr ) pure\n    {\n        return addr.s6_addr[0] == 0xff;\n    }\n\n    extern (D) int IN6_IS_ADDR_LINKLOCAL( in6_addr* addr ) pure\n    {\n        return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0x80;\n    }\n\n    extern (D) int IN6_IS_ADDR_SITELOCAL( in6_addr* addr ) pure\n    {\n        return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0xc0;\n    }\n\n    extern (D) int IN6_IS_ADDR_V4MAPPED( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0 &&\n               (cast(uint32_t*) addr)[1] == 0 &&\n               (cast(uint32_t*) addr)[2] == ntohl( 0x0000ffff );\n    }\n\n    extern (D) int IN6_IS_ADDR_V4COMPAT( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0 &&\n               (cast(uint32_t*) addr)[1] == 0 &&\n               (cast(uint32_t*) addr)[2] == 0 &&\n               (cast(uint32_t*) addr)[3] != 0 &&\n               (cast(uint32_t*) addr)[3] != ntohl( 1 );\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr ) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x1;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr ) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x2;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(addr) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x5;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x8;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_GLOBAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr ) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0xe;\n    }\n}\nelse version (FreeBSD)\n{\n    struct in6_addr\n    {\n        union\n        {\n            uint8_t[16] s6_addr;\n            uint16_t[8] s6_addr16;\n            uint32_t[4] s6_addr32;\n        }\n    }\n\n    struct sockaddr_in6\n    {\n        uint8_t     sin6_len;\n        sa_family_t sin6_family;\n        in_port_t   sin6_port;\n        uint32_t    sin6_flowinfo;\n        in6_addr    sin6_addr;\n        uint32_t    sin6_scope_id;\n    }\n\n    extern __gshared immutable in6_addr in6addr_any;\n    extern __gshared immutable in6_addr in6addr_loopback;\n\n    struct ipv6_mreq\n    {\n        in6_addr    ipv6mr_multiaddr;\n        uint        ipv6mr_interface;\n    }\n\n    enum : uint\n    {\n        IPPROTO_IPV6        = 41,\n\n        //INET6_ADDRSTRLEN    = 46,\n\n        IPV6_JOIN_GROUP     = 12,\n        IPV6_LEAVE_GROUP    = 13,\n        IPV6_MULTICAST_HOPS = 10,\n        IPV6_MULTICAST_IF   = 9,\n        IPV6_MULTICAST_LOOP = 11,\n        IPV6_UNICAST_HOPS   = 4,\n        IPV6_V6ONLY         = 27,\n    }\n\n    private enum\n    {\n        __IPV6_ADDR_SCOPE_NODELOCAL     = 0x01,\n        __IPV6_ADDR_SCOPE_INTFACELOCAL  = 0x01,\n        __IPV6_ADDR_SCOPE_LINKLOCAL     = 0x02,\n        __IPV6_ADDR_SCOPE_SITELOCAL     = 0x05,\n        __IPV6_ADDR_SCOPE_ORGLOCAL      = 0x08,\n        __IPV6_ADDR_SCOPE_GLOBAL        = 0x0e,\n    }\n\n    // macros\n    extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);\n    }\n\n    extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));\n    }\n\n    extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));\n    }\n\n    extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));\n    }\n\n    extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;\n    }\n\n    extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;\n    }\n\n    extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure\n    {\n        return a.s6_addr[0] == 0xff;\n    }\n\n    extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( in in6_addr* a ) pure\n    {\n        return a.s6_addr[1] & 0x0f;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;\n    }\n}\nelse version (NetBSD)\n{\n    struct in6_addr\n    {\n        union\n        {\n            uint8_t[16] s6_addr;\n            uint16_t[8] s6_addr16;\n            uint32_t[4] s6_addr32;\n        }\n    }\n\n    struct sockaddr_in6\n    {\n        uint8_t     sin6_len;\n        sa_family_t sin6_family;\n        in_port_t   sin6_port;\n        uint32_t    sin6_flowinfo;\n        in6_addr    sin6_addr;\n        uint32_t    sin6_scope_id;\n    }\n\n    extern __gshared immutable in6_addr in6addr_any;\n    extern __gshared immutable in6_addr in6addr_loopback;\n\n    struct ipv6_mreq\n    {\n        in6_addr    ipv6mr_multiaddr;\n        uint        ipv6mr_interface;\n    }\n\n    enum : uint\n    {\n        IPPROTO_IPV6        = 41,\n\n        //INET6_ADDRSTRLEN    = 46,\n\n        IPV6_JOIN_GROUP     = 12,\n        IPV6_LEAVE_GROUP    = 13,\n        IPV6_MULTICAST_HOPS = 10,\n        IPV6_MULTICAST_IF   = 9,\n        IPV6_MULTICAST_LOOP = 11,\n        IPV6_UNICAST_HOPS   = 4,\n        IPV6_V6ONLY         = 27,\n    }\n\n    private enum\n    {\n        __IPV6_ADDR_SCOPE_NODELOCAL     = 0x01,\n        __IPV6_ADDR_SCOPE_INTFACELOCAL  = 0x01,\n        __IPV6_ADDR_SCOPE_LINKLOCAL     = 0x02,\n        __IPV6_ADDR_SCOPE_SITELOCAL     = 0x05,\n        __IPV6_ADDR_SCOPE_ORGLOCAL      = 0x08,\n        __IPV6_ADDR_SCOPE_GLOBAL        = 0x0e,\n    }\n\n    // macros\n    extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);\n    }\n\n    extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));\n    }\n\n    extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));\n    }\n\n    extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));\n    }\n\n    extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;\n    }\n\n    extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;\n    }\n\n    extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure\n    {\n        return a.s6_addr[0] == 0xff;\n    }\n\n    extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( in in6_addr* a ) pure\n    {\n        return a.s6_addr[1] & 0x0f;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;\n    }\n}\nelse version (DragonFlyBSD)\n{\n    struct in6_addr\n    {\n        union\n        {\n            uint8_t[16] s6_addr;\n            uint16_t[8] s6_addr16;\n            uint32_t[4] s6_addr32;\n        }\n    }\n\n    struct sockaddr_in6\n    {\n        uint8_t     sin6_len;\n        sa_family_t sin6_family;\n        in_port_t   sin6_port;\n        uint32_t    sin6_flowinfo;\n        in6_addr    sin6_addr;\n        uint32_t    sin6_scope_id;\n    }\n\n    extern __gshared immutable in6_addr in6addr_any;\n    extern __gshared immutable in6_addr in6addr_loopback;\n\n    struct ipv6_mreq\n    {\n        in6_addr    ipv6mr_multiaddr;\n        uint        ipv6mr_interface;\n    }\n\n    enum : uint\n    {\n        IPPROTO_IPV6        = 41,\n\n        //INET6_ADDRSTRLEN    = 46,\n\n        IPV6_JOIN_GROUP     = 12,\n        IPV6_LEAVE_GROUP    = 13,\n        IPV6_MULTICAST_HOPS = 10,\n        IPV6_MULTICAST_IF   = 9,\n        IPV6_MULTICAST_LOOP = 11,\n        IPV6_UNICAST_HOPS   = 4,\n        IPV6_V6ONLY         = 27,\n    }\n\n    private enum\n    {\n        __IPV6_ADDR_SCOPE_NODELOCAL     = 0x01,\n        __IPV6_ADDR_SCOPE_INTFACELOCAL  = 0x01,\n        __IPV6_ADDR_SCOPE_LINKLOCAL     = 0x02,\n        __IPV6_ADDR_SCOPE_SITELOCAL     = 0x05,\n        __IPV6_ADDR_SCOPE_ORGLOCAL      = 0x08,\n        __IPV6_ADDR_SCOPE_GLOBAL        = 0x0e,\n    }\n\n    // macros\n    extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);\n    }\n\n    extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));\n    }\n\n    extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));\n    }\n\n    extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure\n    {\n        return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n               (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));\n    }\n\n    extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;\n    }\n\n    extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;\n    }\n\n    extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure\n    {\n        return a.s6_addr[0] == 0xff;\n    }\n\n    extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( in in6_addr* a ) pure\n    {\n        return a.s6_addr[1] & 0x0f;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(a) &&\n               __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;\n    }\n}\nelse version (Solaris)\n{\n    struct in6_addr\n    {\n        union\n        {\n            uint8_t[16] s6_addr;\n            uint8_t[16] s6_addr8;\n            uint32_t[4] s6_addr32;\n        }\n    }\n\n    struct sockaddr_in6\n    {\n        sa_family_t sin6_family;\n        in_port_t   sin6_port;\n        uint32_t    sin6_flowinfo;\n        in6_addr    sin6_addr;\n        uint32_t    sin6_scope_id;\n        uint32_t    __sin6_src_id;\n    }\n\n    extern __gshared immutable in6_addr in6addr_any;\n    extern __gshared immutable in6_addr in6addr_loopback;\n\n    struct ipv6_mreq\n    {\n        in6_addr    ipv6mr_multiaddr;\n        uint        ipv6mr_interface;\n    }\n\n    enum : uint\n    {\n        IPPROTO_IPV6        = 41,\n\n        //INET6_ADDRSTRLEN    = 46,\n\n        IPV6_JOIN_GROUP     = 9,\n        IPV6_LEAVE_GROUP    = 10,\n        IPV6_MULTICAST_HOPS = 7,\n        IPV6_MULTICAST_IF   = 6,\n        IPV6_MULTICAST_LOOP = 8,\n        IPV6_UNICAST_HOPS   = 5,\n        IPV6_V6ONLY         = 39,\n    }\n\n    // macros\n    extern (D) int IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a ) pure\n    {\n        return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&\n               (a.s6_addr32[2] == 0) && (a.s6_addr32[3] == 0);\n    }\n\n    extern (D) int IN6_IS_ADDR_LOOPBACK( in in6_addr* a ) pure\n    {\n        return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&\n               (a.s6_addr32[2] == 0) && (a.s6_addr32[3] == ntohl(1));\n    }\n\n    extern (D) int IN6_IS_ADDR_V4COMPAT( in in6_addr* a ) pure\n    {\n        return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&\n               (a.s6_addr32[2] == 0) && (a.s6_addr32[3] != 0) &&\n               (a.s6_addr32[3] != ntohl(1));\n    }\n\n    extern (D) int IN6_IS_ADDR_V4MAPPED( in in6_addr* a ) pure\n    {\n        return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&\n               (a.s6_addr32[2] == ntohl(0x0000ffff));\n    }\n\n    extern (D) int IN6_IS_ADDR_LINKLOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr8[0] == 0xfe && (a.s6_addr8[1] & 0xc0) == 0x80;\n    }\n\n    extern (D) int IN6_IS_ADDR_SITELOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr8[0] == 0xfe && (a.s6_addr8[1] & 0xc0) == 0xc0;\n    }\n\n    extern (D) int IN6_IS_ADDR_MULTICAST( in in6_addr* a ) pure\n    {\n        return a.s6_addr8[0] == 0xff;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x01;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x02;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x05;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x08;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a ) pure\n    {\n        return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x0e;\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    struct in6_addr\n    {\n        union\n        {\n            uint8_t[16] s6_addr;\n            uint16_t[8] s6_addr16;\n            uint32_t[4] s6_addr32;\n        }\n    }\n\n    struct sockaddr_in6\n    {\n        ushort      sin6_family;\n        uint16_t    sin6_port;\n        uint32_t    sin6_flowinfo;\n        in6_addr    sin6_addr;\n        uint32_t    sin6_scope_id;\n    }\n\n    __gshared immutable in6_addr in6addr_any = {[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]};\n    __gshared immutable in6_addr in6addr_loopback = {[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]};\n\n    struct ipv6_mreq\n    {\n        in6_addr ipv6mr_multiaddr;\n        int      ipv6mr_ifindex;\n    }\n\n    enum : uint\n    {\n        IPPROTO_IPV6        = 41,\n\n        IPV6_JOIN_GROUP     = 20,\n        IPV6_LEAVE_GROUP    = 21,\n        IPV6_MULTICAST_HOPS = 18,\n        IPV6_MULTICAST_IF   = 17,\n        IPV6_MULTICAST_LOOP = 19,\n        IPV6_UNICAST_HOPS   = 16,\n        IPV6_V6ONLY         = 26\n    }\n\n    private enum\n    {\n        IPV6_ADDR_SCOPE_NODELOCAL     = 0x01,\n        IPV6_ADDR_SCOPE_INTFACELOCAL  = 0x01,\n        IPV6_ADDR_SCOPE_LINKLOCAL     = 0x02,\n        IPV6_ADDR_SCOPE_SITELOCAL     = 0x05,\n        IPV6_ADDR_SCOPE_ORGLOCAL      = 0x08,\n        IPV6_ADDR_SCOPE_GLOBAL        = 0x0e,\n    }\n\n    extern (D) pure\n    {\n        bool IN6_IS_ADDR_UNSPECIFIED( in in6_addr* a )\n        {\n            return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);\n        }\n\n        bool IN6_IS_ADDR_LOOPBACK( in in6_addr* a )\n        {\n            return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));\n        }\n\n        bool IN6_IS_ADDR_V4COMPAT( in in6_addr* a )\n        {\n            return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));\n        }\n\n        bool IN6_IS_ADDR_V4MAPPED( in in6_addr* a )\n        {\n            return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&\n                   (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));\n        }\n\n        bool IN6_IS_ADDR_LINKLOCAL( in in6_addr* a )\n        {\n            return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;\n        }\n\n        bool IN6_IS_ADDR_SITELOCAL( in in6_addr* a )\n        {\n            return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;\n        }\n\n        bool IN6_IS_ADDR_ULA( in in6_addr* a )\n        {\n            return (a.s6_addr[0] & 0xfe) == 0xfc;\n        }\n\n        bool IN6_IS_ADDR_MULTICAST( in in6_addr* a )\n        {\n            return a.s6_addr[0] == 0xff;\n        }\n\n        uint8_t IPV6_ADDR_MC_SCOPE( in in6_addr* a )\n        {\n            return a.s6_addr[1] & 0x0f;\n        }\n\n        bool IN6_IS_ADDR_MC_NODELOCAL( in in6_addr* a )\n        {\n            return IN6_IS_ADDR_MULTICAST(a) &&\n                   IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL;\n        }\n\n        bool IN6_IS_ADDR_MC_LINKLOCAL( in in6_addr* a )\n        {\n            return IN6_IS_ADDR_MULTICAST(a) &&\n                   IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL;\n        }\n\n        bool IN6_IS_ADDR_MC_SITELOCAL( in in6_addr* a )\n        {\n            return IN6_IS_ADDR_MULTICAST(a) &&\n                   IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL;\n        }\n\n        bool IN6_IS_ADDR_MC_ORGLOCAL( in in6_addr* a )\n        {\n            return IN6_IS_ADDR_MULTICAST(a) &&\n                   IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL;\n        }\n\n        bool IN6_IS_ADDR_MC_GLOBAL( in in6_addr* a )\n        {\n            return IN6_IS_ADDR_MULTICAST(a) &&\n                   IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL;\n        }\n    }\n}\nelse version (CRuntime_Musl)\n{\n\n    struct in6_addr {\n        union {\n            uint8_t[16] s6_addr;\n            uint16_t[8] s6_addr16;\n            uint32_t[4] s6_addr32;\n        }\n    }\n    struct sockaddr_in6 {\n        sa_family_t     sin6_family;\n        in_port_t       sin6_port;\n        uint32_t        sin6_flowinfo;\n        in6_addr        sin6_addr;\n        uint32_t        sin6_scope_id;\n    }\n\n    struct ipv6_mreq\n    {\n        in6_addr    ipv6mr_multiaddr;\n        uint        ipv6mr_interface;\n    }\n\n    enum : uint\n    {\n        IPPROTO_IPV6 = 41,\n\n        IPV6_UNICAST_HOPS   = 16,\n        IPV6_MULTICAST_IF   = 17,\n        IPV6_MULTICAST_HOPS = 18,\n        IPV6_MULTICAST_LOOP = 19,\n        IPV6_JOIN_GROUP     = 20,\n        IPV6_LEAVE_GROUP    = 21,\n        IPV6_V6ONLY         = 26\n    }\n    extern __gshared immutable in6_addr in6addr_any;\n    extern __gshared immutable in6_addr in6addr_loopback;\n}\nelse version (CRuntime_UClibc)\n{\n    struct in6_addr\n    {\n        union\n        {\n            uint8_t[16] s6_addr;\n            uint16_t[8] s6_addr16;\n            uint32_t[4] s6_addr32;\n        }\n    }\n\n    struct sockaddr_in6\n    {\n        sa_family_t sin6_family;\n        in_port_t   sin6_port;\n        uint32_t    sin6_flowinfo;\n        in6_addr    sin6_addr;\n        uint32_t    sin6_scope_id;\n    }\n\n    extern __gshared immutable in6_addr in6addr_any;\n    extern __gshared immutable in6_addr in6addr_loopback;\n\n    struct ipv6_mreq\n    {\n        in6_addr    ipv6mr_multiaddr;\n        uint        ipv6mr_interface;\n    }\n\n    enum : uint\n    {\n        IPPROTO_IPV6        = 41,\n        IPV6_JOIN_GROUP     = 20,\n        IPV6_LEAVE_GROUP    = 21,\n        IPV6_MULTICAST_HOPS = 18,\n        IPV6_MULTICAST_IF   = 17,\n        IPV6_MULTICAST_LOOP = 19,\n        IPV6_UNICAST_HOPS   = 16,\n        IPV6_V6ONLY         = 26\n    }\n\n    // macros\n    extern (D) int IN6_IS_ADDR_UNSPECIFIED( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0 &&\n               (cast(uint32_t*) addr)[1] == 0 &&\n               (cast(uint32_t*) addr)[2] == 0 &&\n               (cast(uint32_t*) addr)[3] == 0;\n    }\n\n    extern (D) int IN6_IS_ADDR_LOOPBACK( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0  &&\n               (cast(uint32_t*) addr)[1] == 0  &&\n               (cast(uint32_t*) addr)[2] == 0  &&\n               (cast(uint32_t*) addr)[3] == htonl( 1 );\n    }\n\n    extern (D) int IN6_IS_ADDR_MULTICAST( in6_addr* addr ) pure\n    {\n        return (cast(uint8_t*) addr)[0] == 0xff;\n    }\n\n    extern (D) int IN6_IS_ADDR_LINKLOCAL( in6_addr* addr ) pure\n    {\n        return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfe800000 );\n    }\n\n    extern (D) int IN6_IS_ADDR_SITELOCAL( in6_addr* addr ) pure\n    {\n        return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfec00000 );\n    }\n\n    extern (D) int IN6_IS_ADDR_V4MAPPED( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0 &&\n               (cast(uint32_t*) addr)[1] == 0 &&\n               (cast(uint32_t*) addr)[2] == htonl( 0xffff );\n    }\n\n    extern (D) int IN6_IS_ADDR_V4COMPAT( in6_addr* addr ) pure\n    {\n        return (cast(uint32_t*) addr)[0] == 0 &&\n               (cast(uint32_t*) addr)[1] == 0 &&\n               (cast(uint32_t*) addr)[2] == 0 &&\n               ntohl( (cast(uint32_t*) addr)[3] ) > 1;\n    }\n\n    extern (D) int IN6_ARE_ADDR_EQUAL( in6_addr* a, in6_addr* b ) pure\n    {\n        return (cast(uint32_t*) a)[0] == (cast(uint32_t*) b)[0] &&\n               (cast(uint32_t*) a)[1] == (cast(uint32_t*) b)[1] &&\n               (cast(uint32_t*) a)[2] == (cast(uint32_t*) b)[2] &&\n               (cast(uint32_t*) a)[3] == (cast(uint32_t*) b)[3];\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr ) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x1;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr ) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x2;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST(addr) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x5;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0x8;\n    }\n\n    extern (D) int IN6_IS_ADDR_MC_GLOBAL( in6_addr* addr ) pure\n    {\n        return IN6_IS_ADDR_MULTICAST( addr ) &&\n               ((cast(uint8_t*) addr)[1] & 0xf) == 0xe;\n    }\n}\n\n\n//\n// Raw Sockets (RS)\n//\n/*\nIPPROTO_RAW\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum uint IPPROTO_RAW = 255;\n}\nelse version (Darwin)\n{\n    enum uint IPPROTO_RAW = 255;\n}\nelse version (FreeBSD)\n{\n    enum uint IPPROTO_RAW = 255;\n}\nelse version (NetBSD)\n{\n    enum uint IPPROTO_RAW = 255;\n}\nelse version (DragonFlyBSD)\n{\n    enum uint IPPROTO_RAW = 255;\n}\nelse version (Solaris)\n{\n    enum uint IPPROTO_RAW = 255;\n}\nelse version (linux)\n{\n    enum uint IPPROTO_RAW = 255;\n}\nelse version (CRuntime_UClibc)\n{\n    enum uint IPPROTO_RAW = 255;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/netinet/tcp.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.netinet.tcp;\n\nprivate import core.sys.posix.config;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\n\n//\n// Required\n//\n/*\nTCP_NODELAY\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum TCP_NODELAY = 1;\n}\nelse version (Darwin)\n{\n    enum TCP_NODELAY = 1;\n}\nelse version (FreeBSD)\n{\n    enum TCP_NODELAY = 1;\n}\nelse version (NetBSD)\n{\n    enum TCP_NODELAY = 1;\n}\nelse version (DragonFlyBSD)\n{\n    enum TCP_NODELAY = 1;\n}\nelse version (Solaris)\n{\n    enum TCP_NODELAY = 1;\n}\nelse version (linux)\n{\n    enum TCP_NODELAY = 1;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/poll.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.poll;\n\nprivate import core.sys.posix.config;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// XOpen (XSI)\n//\n/*\nstruct pollfd\n{\n    int     fd;\n    short   events;\n    short   revents;\n}\n\nnfds_t\n\nPOLLIN\nPOLLRDNORM\nPOLLRDBAND\nPOLLPRI\nPOLLOUT\nPOLLWRNORM\nPOLLWRBAND\nPOLLERR\nPOLLHUP\nPOLLNVAL\n\nint poll(pollfd[], nfds_t, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct pollfd\n    {\n        int     fd;\n        short   events;\n        short   revents;\n    }\n\n    alias c_ulong nfds_t;\n\n    enum\n    {\n        POLLIN      = 0x001,\n        POLLRDNORM  = 0x040,\n        POLLRDBAND  = 0x080,\n        POLLPRI     = 0x002,\n        POLLOUT     = 0x004,\n        POLLWRNORM  = 0x100,\n        POLLWRBAND  = 0x200,\n        POLLERR     = 0x008,\n        POLLHUP     = 0x010,\n        POLLNVAL    = 0x020,\n    }\n\n    int poll(pollfd*, nfds_t, int);\n}\nelse version (Darwin)\n{\n    struct pollfd\n    {\n        int     fd;\n        short   events;\n        short   revents;\n    };\n\n    alias uint nfds_t;\n\n    enum\n    {\n        POLLIN      = 0x0001,\n        POLLPRI     = 0x0002,\n        POLLOUT     = 0x0004,\n        POLLRDNORM  = 0x0040,\n        POLLWRNORM  = POLLOUT,\n        POLLRDBAND  = 0x0080,\n        POLLWRBAND  = 0x0100,\n        POLLEXTEND  = 0x0200,\n        POLLATTRIB  = 0x0400,\n        POLLNLINK   = 0x0800,\n        POLLWRITE   = 0x1000,\n        POLLERR     = 0x0008,\n        POLLHUP     = 0x0010,\n        POLLNVAL    = 0x0020,\n\n        POLLSTANDARD = (POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLRDBAND|\n                        POLLWRBAND|POLLERR|POLLHUP|POLLNVAL)\n    }\n\n    int poll(pollfd*, nfds_t, int);\n}\nelse version (FreeBSD)\n{\n    alias uint nfds_t;\n\n    struct pollfd\n    {\n        int     fd;\n        short   events;\n        short   revents;\n    };\n\n    enum\n    {\n        POLLIN      = 0x0001,\n        POLLPRI     = 0x0002,\n        POLLOUT     = 0x0004,\n        POLLRDNORM  = 0x0040,\n        POLLWRNORM  = POLLOUT,\n        POLLRDBAND  = 0x0080,\n        POLLWRBAND  = 0x0100,\n        //POLLEXTEND  = 0x0200,\n        //POLLATTRIB  = 0x0400,\n        //POLLNLINK   = 0x0800,\n        //POLLWRITE   = 0x1000,\n        POLLERR     = 0x0008,\n        POLLHUP     = 0x0010,\n        POLLNVAL    = 0x0020,\n\n        POLLSTANDARD = (POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLRDBAND|\n        POLLWRBAND|POLLERR|POLLHUP|POLLNVAL)\n    }\n\n    int poll(pollfd*, nfds_t, int);\n}\nelse version (NetBSD)\n{\n    alias uint nfds_t;\n\n    struct pollfd\n    {\n        int     fd;\n        short   events;\n        short   revents;\n    };\n\n    enum\n    {\n        POLLIN      = 0x0001,\n        POLLPRI     = 0x0002,\n        POLLOUT     = 0x0004,\n        POLLRDNORM  = 0x0040,\n        POLLWRNORM  = POLLOUT,\n        POLLRDBAND  = 0x0080,\n        POLLWRBAND  = 0x0100,\n        //POLLEXTEND  = 0x0200,\n        //POLLATTRIB  = 0x0400,\n        //POLLNLINK   = 0x0800,\n        //POLLWRITE   = 0x1000,\n        POLLERR     = 0x0008,\n        POLLHUP     = 0x0010,\n        POLLNVAL    = 0x0020,\n\n        POLLSTANDARD = (POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLRDBAND|\n        POLLWRBAND|POLLERR|POLLHUP|POLLNVAL)\n    }\n\n    int poll(pollfd*, nfds_t, int);\n}\nelse version (OpenBSD)\n{\n    alias uint nfds_t;\n\n    struct pollfd\n    {\n        int     fd;\n        short   events;\n        short   revents;\n    };\n\n    enum\n    {\n        POLLIN      = 0x0001,\n        POLLPRI     = 0x0002,\n        POLLOUT     = 0x0004,\n        POLLRDNORM  = 0x0040,\n        POLLNORM    = POLLRDNORM,\n        POLLWRNORM  = POLLOUT,\n        POLLRDBAND  = 0x0080,\n        POLLWRBAND  = 0x0100,\n        POLLERR     = 0x0008,\n        POLLHUP     = 0x0010,\n        POLLNVAL    = 0x0020,\n\n        POLLSTANDARD = (POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLRDBAND|\n        POLLWRBAND|POLLERR|POLLHUP|POLLNVAL)\n    }\n\n    int poll(pollfd*, nfds_t, int);\n}\nelse version (DragonFlyBSD)\n{\n    alias uint nfds_t;\n\n    struct pollfd\n    {\n        int     fd;\n        short   events;\n        short   revents;\n    };\n\n    enum\n    {\n        POLLIN      = 0x0001,\n        POLLPRI     = 0x0002,\n        POLLOUT     = 0x0004,\n        POLLRDNORM  = 0x0040,\n        POLLWRNORM  = POLLOUT,\n        POLLRDBAND  = 0x0080,\n        POLLWRBAND  = 0x0100,\n        //POLLEXTEND  = 0x0200,\n        //POLLATTRIB  = 0x0400,\n        //POLLNLINK   = 0x0800,\n        //POLLWRITE   = 0x1000,\n        POLLERR     = 0x0008,\n        POLLHUP     = 0x0010,\n        POLLNVAL    = 0x0020,\n\n        POLLSTANDARD = (POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLRDBAND|\n        POLLWRBAND|POLLERR|POLLHUP|POLLNVAL)\n    }\n\n    int poll(pollfd*, nfds_t, int);\n}\nelse version (Solaris)\n{\n    alias c_ulong nfds_t;\n\n    struct pollfd\n    {\n        int     fd;\n        short   events;\n        short   revents;\n    }\n\n    enum\n    {\n        POLLIN      = 0x0001,\n        POLLPRI     = 0x0002,\n        POLLOUT     = 0x0004,\n        POLLRDNORM  = 0x0040,\n        POLLWRNORM  = POLLOUT,\n        POLLRDBAND  = 0x0080,\n        POLLWRBAND  = 0x0100,\n        POLLERR     = 0x0008,\n        POLLHUP     = 0x0010,\n        POLLNVAL    = 0x0020,\n    }\n\n    int poll(pollfd*, nfds_t, int);\n}\nelse version (CRuntime_Bionic)\n{\n    struct pollfd\n    {\n        int     fd;\n        short   events;\n        short   revents;\n    }\n\n    alias uint nfds_t;\n\n    enum\n    {\n        POLLIN      = 0x001,\n        POLLRDNORM  = 0x040,\n        POLLRDBAND  = 0x080,\n        POLLPRI     = 0x002,\n        POLLOUT     = 0x004,\n        POLLWRNORM  = 0x100,\n        POLLWRBAND  = 0x200,\n        POLLERR     = 0x008,\n        POLLHUP     = 0x010,\n        POLLNVAL    = 0x020,\n    }\n\n    int poll(pollfd*, nfds_t, c_long);\n}\nelse version (CRuntime_Musl)\n{\n    struct pollfd\n    {\n        int     fd;\n        short   events;\n        short   revents;\n    }\n\n    alias uint nfds_t;\n\n    enum\n    {\n        POLLIN      = 0x001,\n        POLLPRI     = 0x002,\n        POLLOUT     = 0x004,\n        POLLERR     = 0x008,\n        POLLHUP     = 0x010,\n        POLLNVAL    = 0x020,\n        POLLRDNORM  = 0x040,\n        POLLRDBAND  = 0x080,\n        POLLWRNORM  = 0x100,\n        POLLWRBAND  = 0x200,\n    }\n\n    int poll(pollfd*, nfds_t, c_long);\n}\nelse version (CRuntime_UClibc)\n{\n    struct pollfd\n    {\n        int     fd;\n        short   events;\n        short   revents;\n    }\n\n    alias c_ulong nfds_t;\n\n    enum\n    {\n        POLLIN      = 0x001,\n        POLLRDNORM  = 0x040,\n        POLLRDBAND  = 0x080,\n        POLLPRI     = 0x002,\n        POLLOUT     = 0x004,\n        POLLWRNORM  = 0x100,\n        POLLWRBAND  = 0x200,\n        POLLMSG     = 0x400,\n        POLLREMOVE  = 0x1000,\n        POLLRDHUP   = 0x2000,\n        POLLERR     = 0x008,\n        POLLHUP     = 0x010,\n        POLLNVAL    = 0x020,\n    }\n\n    int poll(pollfd*, nfds_t, int);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/pthread.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.pthread;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types;\npublic import core.sys.posix.sched;\npublic import core.sys.posix.time;\n\nimport core.stdc.stdint;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C)\nnothrow:\n\n//\n// Required\n//\n/*\nPTHREAD_CANCEL_ASYNCHRONOUS\nPTHREAD_CANCEL_ENABLE\nPTHREAD_CANCEL_DEFERRED\nPTHREAD_CANCEL_DISABLE\nPTHREAD_CANCELED\nPTHREAD_COND_INITIALIZER\nPTHREAD_CREATE_DETACHED\nPTHREAD_CREATE_JOINABLE\nPTHREAD_EXPLICIT_SCHED\nPTHREAD_INHERIT_SCHED\nPTHREAD_MUTEX_INITIALIZER\nPTHREAD_ONCE_INIT\nPTHREAD_PROCESS_SHARED\nPTHREAD_PROCESS_PRIVATE\n\nint pthread_atfork(void function(), void function(), void function());\nint pthread_attr_destroy(pthread_attr_t*);\nint pthread_attr_getdetachstate(in pthread_attr_t*, int*);\nint pthread_attr_getschedparam(in pthread_attr_t*, sched_param*);\nint pthread_attr_init(pthread_attr_t*);\nint pthread_attr_setdetachstate(pthread_attr_t*, int);\nint pthread_attr_setschedparam(in pthread_attr_t*, sched_param*);\nint pthread_cancel(pthread_t);\nvoid pthread_cleanup_push(void function(void*), void*);\nvoid pthread_cleanup_pop(int);\nint pthread_cond_broadcast(pthread_cond_t*);\nint pthread_cond_destroy(pthread_cond_t*);\nint pthread_cond_init(in pthread_cond_t*, pthread_condattr_t*);\nint pthread_cond_signal(pthread_cond_t*);\nint pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, in timespec*);\nint pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*);\nint pthread_condattr_destroy(pthread_condattr_t*);\nint pthread_condattr_init(pthread_condattr_t*);\nint pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*);\nint pthread_detach(pthread_t);\nint pthread_equal(pthread_t, pthread_t);\nvoid pthread_exit(void*);\nvoid* pthread_getspecific(pthread_key_t);\nint pthread_join(pthread_t, void**);\nint pthread_key_create(pthread_key_t*, void function(void*));\nint pthread_key_delete(pthread_key_t);\nint pthread_mutex_destroy(pthread_mutex_t*);\nint pthread_mutex_init(pthread_mutex_t*, pthread_mutexattr_t*);\nint pthread_mutex_lock(pthread_mutex_t*);\nint pthread_mutex_trylock(pthread_mutex_t*);\nint pthread_mutex_unlock(pthread_mutex_t*);\nint pthread_mutexattr_destroy(pthread_mutexattr_t*);\nint pthread_mutexattr_init(pthread_mutexattr_t*);\nint pthread_once(pthread_once_t*, void function());\nint pthread_rwlock_destroy(pthread_rwlock_t*);\nint pthread_rwlock_init(pthread_rwlock_t*, in pthread_rwlockattr_t*);\nint pthread_rwlock_rdlock(pthread_rwlock_t*);\nint pthread_rwlock_tryrdlock(pthread_rwlock_t*);\nint pthread_rwlock_trywrlock(pthread_rwlock_t*);\nint pthread_rwlock_unlock(pthread_rwlock_t*);\nint pthread_rwlock_wrlock(pthread_rwlock_t*);\nint pthread_rwlockattr_destroy(pthread_rwlockattr_t*);\nint pthread_rwlockattr_init(pthread_rwlockattr_t*);\npthread_t pthread_self();\nint pthread_setcancelstate(int, int*);\nint pthread_setcanceltype(int, int*);\nint pthread_setspecific(pthread_key_t, in void*);\nvoid pthread_testcancel();\n*/\nversion (CRuntime_Glibc)\n{\n    enum\n    {\n        PTHREAD_CANCEL_ENABLE,\n        PTHREAD_CANCEL_DISABLE\n    }\n\n    enum\n    {\n        PTHREAD_CANCEL_DEFERRED,\n        PTHREAD_CANCEL_ASYNCHRONOUS\n    }\n\n    enum PTHREAD_CANCELED = cast(void*) -1;\n\n    //enum pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, \"\", 0 };\n\n    enum\n    {\n        PTHREAD_CREATE_JOINABLE,\n        PTHREAD_CREATE_DETACHED\n    }\n\n    enum\n    {\n        PTHREAD_INHERIT_SCHED,\n        PTHREAD_EXPLICIT_SCHED\n    }\n\n    enum PTHREAD_MUTEX_INITIALIZER  = pthread_mutex_t.init;\n    enum PTHREAD_ONCE_INIT          = pthread_once_t.init;\n\n    enum\n    {\n        PTHREAD_PROCESS_PRIVATE,\n        PTHREAD_PROCESS_SHARED\n    }\n}\nelse version (Darwin)\n{\n    enum\n    {\n        PTHREAD_CANCEL_ENABLE   = 1,\n        PTHREAD_CANCEL_DISABLE  = 0\n    }\n\n    enum\n    {\n        PTHREAD_CANCEL_DEFERRED     = 2,\n        PTHREAD_CANCEL_ASYNCHRONOUS = 0\n    }\n\n    enum PTHREAD_CANCELED = cast(void*) -1;\n\n    //enum pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, \"\", 0 };\n\n    enum\n    {\n        PTHREAD_CREATE_JOINABLE = 1,\n        PTHREAD_CREATE_DETACHED = 2\n    }\n\n    enum\n    {\n        PTHREAD_INHERIT_SCHED   = 1,\n        PTHREAD_EXPLICIT_SCHED  = 2\n    }\n\n    enum PTHREAD_MUTEX_INITIALIZER  = pthread_mutex_t(0x32AAABA7);\n    enum PTHREAD_ONCE_INIT          = pthread_once_t(0x30b1bcba);\n\n    enum\n    {\n        PTHREAD_PROCESS_PRIVATE = 2,\n        PTHREAD_PROCESS_SHARED  = 1\n    }\n}\nelse version (FreeBSD)\n{\n    enum\n    {\n        PTHREAD_DETACHED            = 0x1,\n        PTHREAD_INHERIT_SCHED       = 0x4,\n        PTHREAD_NOFLOAT             = 0x8,\n\n        PTHREAD_CREATE_DETACHED     = PTHREAD_DETACHED,\n        PTHREAD_CREATE_JOINABLE     = 0,\n        PTHREAD_EXPLICIT_SCHED      = 0,\n    }\n\n    enum\n    {\n        PTHREAD_PROCESS_PRIVATE     = 0,\n        PTHREAD_PROCESS_SHARED      = 1,\n    }\n\n    enum\n    {\n        PTHREAD_CANCEL_ENABLE       = 0,\n        PTHREAD_CANCEL_DISABLE      = 1,\n        PTHREAD_CANCEL_DEFERRED     = 0,\n        PTHREAD_CANCEL_ASYNCHRONOUS = 2,\n    }\n\n    enum PTHREAD_CANCELED = cast(void*) -1;\n\n    enum PTHREAD_NEEDS_INIT = 0;\n    enum PTHREAD_DONE_INIT  = 1;\n\n    enum PTHREAD_MUTEX_INITIALIZER              = null;\n    enum PTHREAD_ONCE_INIT                      = null;\n    enum PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP  = null;\n    enum PTHREAD_COND_INITIALIZER               = null;\n    enum PTHREAD_RWLOCK_INITIALIZER             = null;\n}\nelse version (NetBSD)\n{\n    enum PRI_NONE = -1;\n    enum\n    {\n        PTHREAD_INHERIT_SCHED       = 0x0,\n\n        PTHREAD_CREATE_DETACHED     = 1,\n        PTHREAD_CREATE_JOINABLE     = 0,\n        PTHREAD_EXPLICIT_SCHED      = 1,\n    }\n\n    enum\n    {\n        PTHREAD_PROCESS_PRIVATE     = 0,\n        PTHREAD_PROCESS_SHARED      = 1,\n    }\n\n    enum\n    {\n        PTHREAD_CANCEL_ENABLE       = 0,\n        PTHREAD_CANCEL_DISABLE      = 1,\n        PTHREAD_CANCEL_DEFERRED     = 0,\n        PTHREAD_CANCEL_ASYNCHRONOUS = 1,\n    }\n\n    enum PTHREAD_CANCELED = cast(void*) 1;\n\n    enum PTHREAD_DONE_INIT  = 1;\n\n    enum PTHREAD_MUTEX_INITIALIZER              = pthread_mutex_t(0x33330003);\n\n    enum PTHREAD_ONCE_INIT                      = pthread_once_t(PTHREAD_MUTEX_INITIALIZER);\n    enum PTHREAD_COND_INITIALIZER               = pthread_cond_t(0x55550005);\n    enum PTHREAD_RWLOCK_INITIALIZER             = pthread_rwlock_t(0x99990009);\n}\nelse version (OpenBSD)\n{\n    enum\n    {\n        PTHREAD_DETACHED            = 0x1,\n        PTHREAD_INHERIT_SCHED       = 0x4,\n        PTHREAD_NOFLOAT             = 0x8,\n\n        PTHREAD_CREATE_DETACHED     = PTHREAD_DETACHED,\n        PTHREAD_CREATE_JOINABLE     = 0,\n        PTHREAD_EXPLICIT_SCHED      = 0,\n    }\n\n    enum\n    {\n        PTHREAD_PROCESS_PRIVATE     = 0,\n        PTHREAD_PROCESS_SHARED      = 1,\n    }\n\n    enum\n    {\n        PTHREAD_CANCEL_ENABLE       = 0,\n        PTHREAD_CANCEL_DISABLE      = 1,\n        PTHREAD_CANCEL_DEFERRED     = 0,\n        PTHREAD_CANCEL_ASYNCHRONOUS = 2,\n    }\n\n    enum PTHREAD_CANCELED = cast(void*) 1;\n\n    enum\n    {\n        PTHREAD_NEEDS_INIT = 0,\n        PTHREAD_DONE_INIT  = 1,\n    }\n\n    enum PTHREAD_MUTEX_INITIALIZER              = null;\n    //enum PTHREAD_ONCE_INIT                      = { PTHREAD_NEEDS_INIT, PTHREAD_MUTEX_INITIALIZER };\n    enum PTHREAD_COND_INITIALIZER               = null;\n    enum PTHREAD_RWLOCK_INITIALIZER             = null;\n}\nelse version (DragonFlyBSD)\n{\n    enum\n    {\n        PTHREAD_DETACHED            = 0x1,\n        //PTHREAD_SCOPE_SYSTEM        = 0x2,    // defined below\n        PTHREAD_INHERIT_SCHED       = 0x4,\n        PTHREAD_NOFLOAT             = 0x8,\n\n        PTHREAD_CREATE_DETACHED     = PTHREAD_DETACHED,\n        PTHREAD_CREATE_JOINABLE     = 0,\n        //PTHREAD_SCOPE_PROCESS       = 0,      // defined below\n        PTHREAD_EXPLICIT_SCHED      = 0,\n    }\n\n    enum\n    {\n        PTHREAD_PROCESS_PRIVATE     = 0,\n        PTHREAD_PROCESS_SHARED      = 1,\n    }\n\n    enum\n    {\n        PTHREAD_CANCEL_ENABLE       = 0,\n        PTHREAD_CANCEL_DISABLE      = 1,\n        PTHREAD_CANCEL_DEFERRED     = 0,\n        PTHREAD_CANCEL_ASYNCHRONOUS = 2,\n    }\n\n    enum PTHREAD_CANCELED = cast(void*) -1;\n\n    enum PTHREAD_NEEDS_INIT = 0;\n    enum PTHREAD_DONE_INIT  = 1;\n\n    enum PTHREAD_MUTEX_INITIALIZER              = null;\n    //enum PTHREAD_ONCE_INIT                      = { PTHREAD_NEEDS_INIT, NULL };\n    enum PTHREAD_ONCE_INIT                      = pthread_once_t.init;;\n    enum PTHREAD_COND_INITIALIZER               = null;\n    enum PTHREAD_RWLOCK_INITIALIZER             = null;\n}\nelse version (Solaris)\n{\n    enum\n    {\n        PTHREAD_INHERIT_SCHED = 0x01,\n        PTHREAD_NOFLOAT = 0x08,\n        PTHREAD_CREATE_DETACHED = 0x40,\n        PTHREAD_CREATE_JOINABLE = 0x00,\n        PTHREAD_EXPLICIT_SCHED = 0x00,\n    }\n\n    enum\n    {\n        PTHREAD_PROCESS_PRIVATE = 0,\n        PTHREAD_PROCESS_SHARED = 1,\n    }\n\n    enum\n    {\n        PTHREAD_CANCEL_ENABLE = 0,\n        PTHREAD_CANCEL_DISABLE = 1,\n        PTHREAD_CANCEL_DEFERRED = 0,\n        PTHREAD_CANCEL_ASYNCHRONOUS = 2,\n    }\n\n    enum PTHREAD_CANCELED = cast(void*)-19;\n\n    enum PTHREAD_MUTEX_INITIALIZER  = pthread_mutex_t.init;\n    enum PTHREAD_ONCE_INIT          = pthread_once_t.init;\n}\nelse version (CRuntime_Bionic)\n{\n    enum\n    {\n        PTHREAD_CREATE_JOINABLE,\n        PTHREAD_CREATE_DETACHED\n    }\n\n    enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;\n    enum PTHREAD_ONCE_INIT         = pthread_once_t.init;\n\n    enum\n    {\n        PTHREAD_PROCESS_PRIVATE,\n        PTHREAD_PROCESS_SHARED\n    }\n}\nelse version (CRuntime_Musl)\n{\n    enum\n    {\n        PTHREAD_CREATE_JOINABLE = 0,\n        PTHREAD_CREATE_DETACHED = 1\n    }\n\n    enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;\n    enum PTHREAD_ONCE_INIT = pthread_once_t.init;\n\n    enum\n    {\n        PTHREAD_PROCESS_PRIVATE = 0,\n        PTHREAD_PROCESS_SHARED = 1\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    enum\n    {\n        PTHREAD_CANCEL_ENABLE,\n        PTHREAD_CANCEL_DISABLE\n    }\n\n    enum\n    {\n        PTHREAD_CANCEL_DEFERRED,\n        PTHREAD_CANCEL_ASYNCHRONOUS\n    }\n\n    enum PTHREAD_CANCELED   = cast(void*) -1;\n\n    enum PTHREAD_MUTEX_INITIALIZER  = pthread_mutex_t.init;\n    enum PTHREAD_ONCE_INIT          = pthread_once_t.init;\n\n    enum\n    {\n        PTHREAD_CREATE_JOINABLE,\n        PTHREAD_CREATE_DETACHED\n    }\n\n    enum\n    {\n        PTHREAD_INHERIT_SCHED,\n        PTHREAD_EXPLICIT_SCHED\n    }\n\n    enum\n    {\n        PTHREAD_PROCESS_PRIVATE,\n        PTHREAD_PROCESS_SHARED\n    }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\nint pthread_atfork(void function(), void function(), void function());\n@nogc {\n    int pthread_atfork(void function() @nogc, void function() @nogc, void function() @nogc);\n    int pthread_attr_destroy(pthread_attr_t*);\n    int pthread_attr_getdetachstate(in pthread_attr_t*, int*);\n    int pthread_attr_getschedparam(in pthread_attr_t*, sched_param*);\n    int pthread_attr_init(pthread_attr_t*);\n    int pthread_attr_setdetachstate(pthread_attr_t*, int);\n    int pthread_attr_setschedparam(in pthread_attr_t*, sched_param*);\n    int pthread_cancel(pthread_t);\n}\n\nalias void function(void*) _pthread_cleanup_routine;\nalias void function(void*) @nogc _pthread_cleanup_routine_nogc;\nversion (CRuntime_Glibc)\n{\n    struct _pthread_cleanup_buffer\n    {\n        _pthread_cleanup_routine    __routine;\n        void*                       __arg;\n        int                         __canceltype;\n        _pthread_cleanup_buffer*    __prev;\n    }\n\n    void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine, void*);\n    void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine_nogc, void*) @nogc;\n    void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int);\n\n    struct pthread_cleanup\n    {\n        _pthread_cleanup_buffer buffer = void;\n\n        extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg )\n        {\n            _pthread_cleanup_push( &buffer, routine, arg );\n        }\n\n        extern (D) void pop()( int execute )\n        {\n            _pthread_cleanup_pop( &buffer, execute );\n        }\n    }\n}\nelse version (Darwin)\n{\n    struct _pthread_cleanup_buffer\n    {\n        _pthread_cleanup_routine    __routine;\n        void*                       __arg;\n        _pthread_cleanup_buffer*    __next;\n    }\n\n    struct pthread_cleanup\n    {\n        _pthread_cleanup_buffer buffer = void;\n\n        extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg )\n        {\n            pthread_t self       = pthread_self();\n            buffer.__routine     = routine;\n            buffer.__arg         = arg;\n            buffer.__next        = cast(_pthread_cleanup_buffer*) self.__cleanup_stack;\n            self.__cleanup_stack = cast(pthread_handler_rec*) &buffer;\n        }\n\n        extern (D) void pop()( int execute )\n        {\n            pthread_t self       = pthread_self();\n            self.__cleanup_stack = cast(pthread_handler_rec*) buffer.__next;\n            if ( execute )\n            {\n                buffer.__routine( buffer.__arg );\n            }\n        }\n    }\n}\nelse version (FreeBSD)\n{\n    struct _pthread_cleanup_info\n    {\n        uintptr_t[8]    pthread_cleanup_pad;\n    }\n\n    struct pthread_cleanup\n    {\n        _pthread_cleanup_info __cleanup_info__ = void;\n\n        extern (D) void push(F: _pthread_cleanup_routine)(F cleanup_routine, void* cleanup_arg )\n        {\n            __pthread_cleanup_push_imp( cleanup_routine, cleanup_arg, &__cleanup_info__ );\n        }\n\n        extern (D) void pop()( int execute )\n        {\n            __pthread_cleanup_pop_imp( execute );\n        }\n    }\n\n    void __pthread_cleanup_push_imp(_pthread_cleanup_routine, void*, _pthread_cleanup_info*);\n    void __pthread_cleanup_push_imp(_pthread_cleanup_routine_nogc, void*, _pthread_cleanup_info*) @nogc;\n    void __pthread_cleanup_pop_imp(int);\n}\nelse version (DragonFlyBSD)\n{\n    struct _pthread_cleanup_info\n    {\n        uintptr_t[8]    pthread_cleanup_pad;\n    }\n\n    struct pthread_cleanup\n    {\n        _pthread_cleanup_info __cleanup_info__ = void;\n\n        extern (D) void push()( _pthread_cleanup_routine cleanup_routine, void* cleanup_arg )\n        {\n            _pthread_cleanup_push( cleanup_routine, cleanup_arg, &__cleanup_info__ );\n        }\n\n        extern (D) void pop()( int execute )\n        {\n            _pthread_cleanup_pop( execute );\n        }\n    }\n\n    void _pthread_cleanup_push(_pthread_cleanup_routine, void*, _pthread_cleanup_info*);\n    void _pthread_cleanup_pop(int);\n}\nelse version (NetBSD)\n{\n    struct _pthread_cleanup_store\n    {\n        void*[4]    pthread_cleanup_pad;\n    }\n\n    struct pthread_cleanup\n    {\n        _pthread_cleanup_store __cleanup_info__ = void;\n\n        extern (D) void push()( _pthread_cleanup_routine cleanup_routine, void* cleanup_arg )\n        {\n            pthread__cleanup_push( cleanup_routine, cleanup_arg, &__cleanup_info__ );\n        }\n\n        extern (D) void pop()( int execute )\n        {\n            pthread__cleanup_pop( execute, &__cleanup_info__ );\n        }\n    }\n\n    void pthread__cleanup_push(_pthread_cleanup_routine, void*, void*);\n    void pthread__cleanup_pop(int, void *);\n}\nelse version (OpenBSD)\n{\n    void pthread_cleanup_push(void function(void*), void*);\n    void pthread_cleanup_pop(int);\n}\nelse version (Solaris)\n{\n    caddr_t _getfp();\n\n    struct _pthread_cleanup_info\n    {\n        uintptr_t[4] pthread_cleanup_pad;\n    }\n\n    struct pthread_cleanup\n    {\n        _pthread_cleanup_info __cleanup_info__ = void;\n\n        extern (D) void push(F: _pthread_cleanup_routine)(F cleanup_routine, void* cleanup_arg)\n        {\n            __pthread_cleanup_push(cleanup_routine, cleanup_arg, _getfp(), &__cleanup_info__);\n        }\n\n        extern (D) void pop()(int execute)\n        {\n            __pthread_cleanup_pop(execute, &__cleanup_info__);\n        }\n    }\n\n    void __pthread_cleanup_push(_pthread_cleanup_routine, void*, caddr_t, _pthread_cleanup_info*);\n    void __pthread_cleanup_push(_pthread_cleanup_routine_nogc, void*, caddr_t, _pthread_cleanup_info*) @nogc;\n    void __pthread_cleanup_pop(int, _pthread_cleanup_info*);\n}\nelse version (CRuntime_Bionic)\n{\n    struct __pthread_cleanup_t\n    {\n        __pthread_cleanup_t*     __cleanup_prev;\n        _pthread_cleanup_routine __cleanup_routine;\n        void*                    __cleanup_arg;\n    }\n\n    void __pthread_cleanup_push(__pthread_cleanup_t*, _pthread_cleanup_routine, void*);\n    void __pthread_cleanup_push(__pthread_cleanup_t*, _pthread_cleanup_routine_nogc, void*) @nogc;\n    void __pthread_cleanup_pop(__pthread_cleanup_t*, int);\n\n    struct pthread_cleanup\n    {\n        __pthread_cleanup_t __cleanup = void;\n\n        extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg )\n        {\n            __pthread_cleanup_push( &__cleanup, routine, arg );\n        }\n\n        extern (D) void pop()( int execute )\n        {\n            __pthread_cleanup_pop( &__cleanup, execute );\n        }\n    }\n}\nelse version (CRuntime_Musl)\n{\n    struct __ptcb {\n        _pthread_cleanup_routine f;\n        void* __x;\n        __ptcb* __next;\n    }\n    void _pthread_cleanup_push(__ptcb*, _pthread_cleanup_routine, void*);\n    void _pthread_cleanup_pop(__ptcb*, int);\n\n    struct pthread_cleanup\n    {\n        __ptcb __cleanup = void;\n\n        extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg )\n        {\n            _pthread_cleanup_push( &__cleanup, routine, arg );\n        }\n\n        extern (D) void pop()( int execute )\n        {\n            _pthread_cleanup_pop( &__cleanup, execute );\n        }\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    struct _pthread_cleanup_buffer\n    {\n        _pthread_cleanup_routine    __routine;\n        void*                       __arg;\n        int                         __canceltype;\n        _pthread_cleanup_buffer*    __prev;\n    }\n\n    void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine, void*);\n    void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine_nogc, void*) @nogc;\n    void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int);\n\n    struct pthread_cleanup\n    {\n        _pthread_cleanup_buffer buffer = void;\n\n        extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg )\n        {\n            _pthread_cleanup_push( &buffer, routine, arg );\n        }\n\n        extern (D) void pop()( int execute )\n        {\n            _pthread_cleanup_pop( &buffer, execute );\n        }\n    }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n@nogc:\n\nint pthread_cond_broadcast(pthread_cond_t*);\nint pthread_cond_destroy(pthread_cond_t*);\nint pthread_cond_init(in pthread_cond_t*, pthread_condattr_t*) @trusted;\nint pthread_cond_signal(pthread_cond_t*);\nint pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, in timespec*);\nint pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*);\nint pthread_condattr_destroy(pthread_condattr_t*);\nint pthread_condattr_init(pthread_condattr_t*);\nint pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*);\nint pthread_detach(pthread_t);\nint pthread_equal(pthread_t, pthread_t);\nvoid pthread_exit(void*);\nvoid* pthread_getspecific(pthread_key_t);\nint pthread_join(pthread_t, void**);\nint pthread_key_create(pthread_key_t*, void function(void*));\nint pthread_key_delete(pthread_key_t);\nint pthread_mutex_destroy(pthread_mutex_t*);\nint pthread_mutex_init(pthread_mutex_t*, pthread_mutexattr_t*) @trusted;\nint pthread_mutex_lock(pthread_mutex_t*);\nint pthread_mutex_lock(shared(pthread_mutex_t)*);\nint pthread_mutex_trylock(pthread_mutex_t*);\nint pthread_mutex_trylock(shared(pthread_mutex_t)*);\nint pthread_mutex_unlock(pthread_mutex_t*);\nint pthread_mutex_unlock(shared(pthread_mutex_t)*);\nint pthread_mutexattr_destroy(pthread_mutexattr_t*);\nint pthread_mutexattr_init(pthread_mutexattr_t*) @trusted;\nint pthread_once(pthread_once_t*, void function());\nint pthread_rwlock_destroy(pthread_rwlock_t*);\nint pthread_rwlock_init(pthread_rwlock_t*, in pthread_rwlockattr_t*);\nint pthread_rwlock_rdlock(pthread_rwlock_t*);\nint pthread_rwlock_tryrdlock(pthread_rwlock_t*);\nint pthread_rwlock_trywrlock(pthread_rwlock_t*);\nint pthread_rwlock_unlock(pthread_rwlock_t*);\nint pthread_rwlock_wrlock(pthread_rwlock_t*);\nint pthread_rwlockattr_destroy(pthread_rwlockattr_t*);\nint pthread_rwlockattr_init(pthread_rwlockattr_t*);\npthread_t pthread_self();\nint pthread_setcancelstate(int, int*);\nint pthread_setcanceltype(int, int*);\nint pthread_setspecific(pthread_key_t, in void*);\nvoid pthread_testcancel();\n\n//\n// Barrier (BAR)\n//\n/*\nPTHREAD_BARRIER_SERIAL_THREAD\n\nint pthread_barrier_destroy(pthread_barrier_t*);\nint pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);\nint pthread_barrier_wait(pthread_barrier_t*);\nint pthread_barrierattr_destroy(pthread_barrierattr_t*);\nint pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); (BAR|TSH)\nint pthread_barrierattr_init(pthread_barrierattr_t*);\nint pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); (BAR|TSH)\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum PTHREAD_BARRIER_SERIAL_THREAD = -1;\n\n    int pthread_barrier_destroy(pthread_barrier_t*);\n    int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);\n    int pthread_barrier_wait(pthread_barrier_t*);\n    int pthread_barrierattr_destroy(pthread_barrierattr_t*);\n    int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);\n    int pthread_barrierattr_init(pthread_barrierattr_t*);\n    int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);\n}\nelse version (FreeBSD)\n{\n    enum PTHREAD_BARRIER_SERIAL_THREAD = -1;\n\n    int pthread_barrier_destroy(pthread_barrier_t*);\n    int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);\n    int pthread_barrier_wait(pthread_barrier_t*);\n    int pthread_barrierattr_destroy(pthread_barrierattr_t*);\n    int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);\n    int pthread_barrierattr_init(pthread_barrierattr_t*);\n    int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);\n}\nelse version (DragonFlyBSD)\n{\n    enum PTHREAD_BARRIER_SERIAL_THREAD = -1;\n    enum PTHREAD_KEYS_MAX              = 256;\n    enum PTHREAD_STACK_MIN             = 16384;\n    enum PTHREAD_THREADS_MAX           = c_ulong.max;\n\n    int pthread_barrier_destroy(pthread_barrier_t*);\n    int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);\n    int pthread_barrier_wait(pthread_barrier_t*);\n    int pthread_barrierattr_destroy(pthread_barrierattr_t*);\n    int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);\n    int pthread_barrierattr_init(pthread_barrierattr_t*);\n    int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);\n}\nelse version (NetBSD)\n{\n    enum PTHREAD_BARRIER_SERIAL_THREAD = 1234567;\n\n    int pthread_barrier_destroy(pthread_barrier_t*);\n    int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);\n    int pthread_barrier_wait(pthread_barrier_t*);\n    int pthread_barrierattr_destroy(pthread_barrierattr_t*);\n    int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);\n    int pthread_barrierattr_init(pthread_barrierattr_t*);\n    int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);\n}\nelse version (OpenBSD)\n{\n    enum PTHREAD_BARRIER_SERIAL_THREAD = -1;\n\n    int pthread_barrier_destroy(pthread_barrier_t*);\n    int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);\n    int pthread_barrier_wait(pthread_barrier_t*);\n    int pthread_barrierattr_destroy(pthread_barrierattr_t*);\n    int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);\n    int pthread_barrierattr_init(pthread_barrierattr_t*);\n    int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);\n}\nelse version (Darwin)\n{\n}\nelse version (Solaris)\n{\n    enum PTHREAD_BARRIER_SERIAL_THREAD = -2;\n\n    int pthread_barrier_destroy(pthread_barrier_t*);\n    int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);\n    int pthread_barrier_wait(pthread_barrier_t*);\n    int pthread_barrierattr_destroy(pthread_barrierattr_t*);\n    int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);\n    int pthread_barrierattr_init(pthread_barrierattr_t*);\n    int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);\n}\nelse version (CRuntime_Bionic)\n{\n}\nelse version (CRuntime_Musl)\n{\n\n}\nelse version (CRuntime_UClibc)\n{\n    enum PTHREAD_BARRIER_SERIAL_THREAD = -1;\n\n    int pthread_barrier_destroy(pthread_barrier_t*);\n    int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);\n    int pthread_barrier_wait(pthread_barrier_t*);\n    int pthread_barrierattr_destroy(pthread_barrierattr_t*);\n    int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);\n    int pthread_barrierattr_init(pthread_barrierattr_t*);\n    int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Clock (CS)\n//\n/*\nint pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*);\nint pthread_condattr_setclock(pthread_condattr_t*, clockid_t);\n*/\n\n//\n// Spinlock (SPI)\n//\n/*\nint pthread_spin_destroy(pthread_spinlock_t*);\nint pthread_spin_init(pthread_spinlock_t*, int);\nint pthread_spin_lock(pthread_spinlock_t*);\nint pthread_spin_trylock(pthread_spinlock_t*);\nint pthread_spin_unlock(pthread_spinlock_t*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int pthread_spin_destroy(pthread_spinlock_t*);\n    int pthread_spin_init(pthread_spinlock_t*, int);\n    int pthread_spin_lock(pthread_spinlock_t*);\n    int pthread_spin_trylock(pthread_spinlock_t*);\n    int pthread_spin_unlock(pthread_spinlock_t*);\n}\nelse version (FreeBSD)\n{\n    int pthread_spin_init(pthread_spinlock_t*, int);\n    int pthread_spin_destroy(pthread_spinlock_t*);\n    int pthread_spin_lock(pthread_spinlock_t*);\n    int pthread_spin_trylock(pthread_spinlock_t*);\n    int pthread_spin_unlock(pthread_spinlock_t*);\n}\nelse version (DragonFlyBSD)\n{\n    int pthread_spin_init(pthread_spinlock_t*, int);\n    int pthread_spin_destroy(pthread_spinlock_t*);\n    int pthread_spin_lock(pthread_spinlock_t*);\n    int pthread_spin_trylock(pthread_spinlock_t*);\n    int pthread_spin_unlock(pthread_spinlock_t*);\n}\nelse version (NetBSD)\n{\n    int pthread_spin_init(pthread_spinlock_t*, int);\n    int pthread_spin_destroy(pthread_spinlock_t*);\n    int pthread_spin_lock(pthread_spinlock_t*);\n    int pthread_spin_trylock(pthread_spinlock_t*);\n    int pthread_spin_unlock(pthread_spinlock_t*);\n}\nelse version (OpenBSD)\n{\n    int pthread_spin_init(pthread_spinlock_t*, int);\n    int pthread_spin_destroy(pthread_spinlock_t*);\n    int pthread_spin_lock(pthread_spinlock_t*);\n    int pthread_spin_trylock(pthread_spinlock_t*);\n    int pthread_spin_unlock(pthread_spinlock_t*);\n}\nelse version (Darwin)\n{\n}\nelse version (Solaris)\n{\n    int pthread_spin_init(pthread_spinlock_t*, int);\n    int pthread_spin_destroy(pthread_spinlock_t*);\n    int pthread_spin_lock(pthread_spinlock_t*);\n    int pthread_spin_trylock(pthread_spinlock_t*);\n    int pthread_spin_unlock(pthread_spinlock_t*);\n}\nelse version (CRuntime_Bionic)\n{\n}\nelse version (CRuntime_Musl)\n{\n\n}\nelse version (CRuntime_UClibc)\n{\n    int pthread_spin_destroy(pthread_spinlock_t*);\n    int pthread_spin_init(pthread_spinlock_t*, int);\n    int pthread_spin_lock(pthread_spinlock_t*);\n    int pthread_spin_trylock(pthread_spinlock_t*);\n    int pthread_spin_unlock(pthread_spinlock_t*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// XOpen (XSI)\n//\n/*\nPTHREAD_MUTEX_DEFAULT\nPTHREAD_MUTEX_ERRORCHECK\nPTHREAD_MUTEX_NORMAL\nPTHREAD_MUTEX_RECURSIVE\n\nint pthread_attr_getguardsize(in pthread_attr_t*, size_t*);\nint pthread_attr_setguardsize(pthread_attr_t*, size_t);\nint pthread_getconcurrency();\nint pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);\nint pthread_mutexattr_settype(pthread_mutexattr_t*, int);\nint pthread_setconcurrency(int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum PTHREAD_MUTEX_NORMAL       = 0;\n    enum PTHREAD_MUTEX_RECURSIVE    = 1;\n    enum PTHREAD_MUTEX_ERRORCHECK   = 2;\n    enum PTHREAD_MUTEX_DEFAULT      = PTHREAD_MUTEX_NORMAL;\n\n    int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setguardsize(pthread_attr_t*, size_t);\n    int pthread_getconcurrency();\n    int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;\n    int pthread_setconcurrency(int);\n}\nelse version (Darwin)\n{\n    enum PTHREAD_MUTEX_NORMAL       = 0;\n    enum PTHREAD_MUTEX_ERRORCHECK   = 1;\n    enum PTHREAD_MUTEX_RECURSIVE    = 2;\n    enum PTHREAD_MUTEX_DEFAULT      = PTHREAD_MUTEX_NORMAL;\n\n    int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setguardsize(pthread_attr_t*, size_t);\n    int pthread_getconcurrency();\n    int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;\n    int pthread_setconcurrency(int);\n}\nelse version (FreeBSD)\n{\n    enum\n    {\n        PTHREAD_MUTEX_ERRORCHECK    = 1,\n        PTHREAD_MUTEX_RECURSIVE     = 2,\n        PTHREAD_MUTEX_NORMAL        = 3,\n        PTHREAD_MUTEX_ADAPTIVE_NP   = 4,\n        PTHREAD_MUTEX_TYPE_MAX\n    }\n    enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;\n\n    int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setguardsize(pthread_attr_t*, size_t);\n    int pthread_getconcurrency();\n    int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;\n    int pthread_setconcurrency(int);\n}\nelse version (NetBSD)\n{\n    enum\n    {\n        PTHREAD_MUTEX_NORMAL        = 0,\n        PTHREAD_MUTEX_ERRORCHECK    = 1,\n        PTHREAD_MUTEX_RECURSIVE     = 2,\n        PTHREAD_MUTEX_TYPE_MAX\n    }\n    enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;\n\n    int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setguardsize(pthread_attr_t*, size_t);\n    int pthread_getconcurrency();\n    int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;\n    int pthread_setconcurrency(int);\n}\nelse version (OpenBSD)\n{\n    enum\n    {\n        PTHREAD_MUTEX_ERRORCHECK    = 1,\n        PTHREAD_MUTEX_RECURSIVE     = 2,\n        PTHREAD_MUTEX_NORMAL        = 3,\n        PTHREAD_MUTEX_ADAPTIVE_NP   = 4,\n        PTHREAD_MUTEX_TYPE_MAX\n    }\n    enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;\n\n    int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setguardsize(pthread_attr_t*, size_t);\n    int pthread_getconcurrency();\n    int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;\n    int pthread_setconcurrency(int);\n}\nelse version (DragonFlyBSD)\n{\n    enum\n    {\n        PTHREAD_MUTEX_ERRORCHECK    = 1,\n        PTHREAD_MUTEX_RECURSIVE     = 2,\n        PTHREAD_MUTEX_NORMAL        = 3,\n        PTHREAD_MUTEX_TYPE_MAX\n    }\n    enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;\n\n    int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setguardsize(pthread_attr_t*, size_t);\n    int pthread_getconcurrency();\n    int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;\n    int pthread_setconcurrency(int);\n}\nelse version (Solaris)\n{\n    enum\n    {\n        PTHREAD_MUTEX_ERRORCHECK    = 2,\n        PTHREAD_MUTEX_RECURSIVE     = 4,\n        PTHREAD_MUTEX_NORMAL        = 0,\n    }\n\n    enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;\n\n    int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setguardsize(pthread_attr_t*, size_t);\n    int pthread_getconcurrency();\n    int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;\n    int pthread_setconcurrency(int);\n}\nelse version (CRuntime_Bionic)\n{\n    enum PTHREAD_MUTEX_NORMAL     = 0;\n    enum PTHREAD_MUTEX_RECURSIVE  = 1;\n    enum PTHREAD_MUTEX_ERRORCHECK = 2;\n    enum PTHREAD_MUTEX_DEFAULT    = PTHREAD_MUTEX_NORMAL;\n\n    int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setguardsize(pthread_attr_t*, size_t);\n    int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;\n}\nelse version (CRuntime_Musl)\n{\n    enum {\n        PTHREAD_MUTEX_NORMAL      = 0,\n        PTHREAD_MUTEX_RECURSIVE   = 1,\n        PTHREAD_MUTEX_ERRORCHECK  = 2,\n        PTHREAD_MUTEX_DEFAULT     = PTHREAD_MUTEX_NORMAL,\n    }\n    int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;\n}\nelse version (CRuntime_UClibc)\n{\n    enum\n    {\n      PTHREAD_MUTEX_TIMED_NP,\n      PTHREAD_MUTEX_RECURSIVE_NP,\n      PTHREAD_MUTEX_ERRORCHECK_NP,\n      PTHREAD_MUTEX_ADAPTIVE_NP,\n      PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,\n      PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,\n      PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,\n      PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL,\n      PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP\n    }\n\n    int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setguardsize(pthread_attr_t*, size_t);\n    int pthread_getconcurrency();\n    int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;\n    int pthread_setconcurrency(int);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// CPU Time (TCT)\n//\n/*\nint pthread_getcpuclockid(pthread_t, clockid_t*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int pthread_getcpuclockid(pthread_t, clockid_t*);\n}\nelse version (FreeBSD)\n{\n    int pthread_getcpuclockid(pthread_t, clockid_t*);\n}\nelse version (DragonFlyBSD)\n{\n    int pthread_getcpuclockid(pthread_t, clockid_t*);\n}\nelse version (NetBSD)\n{\n}\nelse version (OpenBSD)\n{\n    int pthread_getcpuclockid(pthread_t, clockid_t*);\n}\nelse version (Darwin)\n{\n}\nelse version (Solaris)\n{\n}\nelse version (CRuntime_Bionic)\n{\n    int pthread_getcpuclockid(pthread_t, clockid_t*);\n}\nelse version (CRuntime_Musl)\n{\n\n}\nelse version (CRuntime_UClibc)\n{\n    int pthread_getcpuclockid(pthread_t, clockid_t*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Timeouts (TMO)\n//\n/*\nint pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);\nint pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);\nint pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);\n    int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);\n    int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);\n}\nelse version (Darwin)\n{\n    int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);\n    int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);\n    int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);\n}\nelse version (FreeBSD)\n{\n    int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);\n    int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);\n    int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);\n}\nelse version (NetBSD)\n{\n    int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);\n    int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);\n    int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);\n}\nelse version (OpenBSD)\n{\n    int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);\n    int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);\n    int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);\n}\nelse version (DragonFlyBSD)\n{\n    int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);\n    int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);\n    int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);\n}\nelse version (Solaris)\n{\n    int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);\n    int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);\n    int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);\n}\nelse version (CRuntime_Bionic)\n{\n    int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);\n    int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);\n}\nelse version (CRuntime_Musl)\n{\n\n}\nelse version (CRuntime_UClibc)\n{\n    int pthread_mutex_timedlock(pthread_mutex_t*, in timespec*);\n    int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);\n    int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Priority (TPI|TPP)\n//\n/*\nPTHREAD_PRIO_INHERIT (TPI)\nPTHREAD_PRIO_NONE (TPP|TPI)\nPTHREAD_PRIO_PROTECT (TPI)\n\nint pthread_mutex_getprioceiling(in pthread_mutex_t*, int*); (TPP)\nint pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*); (TPP)\nint pthread_mutexattr_getprioceiling(pthread_mutexattr_t*, int*); (TPP)\nint pthread_mutexattr_getprotocol(in pthread_mutexattr_t*, int*); (TPI|TPP)\nint pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int); (TPP)\nint pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int); (TPI|TPP)\n*/\nversion (Darwin)\n{\n    enum\n    {\n        PTHREAD_PRIO_NONE,\n        PTHREAD_PRIO_INHERIT,\n        PTHREAD_PRIO_PROTECT\n    }\n\n    int pthread_mutex_getprioceiling(in pthread_mutex_t*, int*);\n    int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*);\n    int pthread_mutexattr_getprioceiling(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_getprotocol(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);\n    int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);\n}\nelse version (Solaris)\n{\n    enum\n    {\n        PTHREAD_PRIO_NONE    = 0x00,\n        PTHREAD_PRIO_INHERIT = 0x10,\n        PTHREAD_PRIO_PROTECT = 0x20,\n    }\n\n    int pthread_mutex_getprioceiling(in pthread_mutex_t*, int*);\n    int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*);\n    int pthread_mutexattr_getprioceiling(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_getprotocol(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);\n    int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);\n}\n\n//\n// Scheduling (TPS)\n//\n/*\nPTHREAD_SCOPE_PROCESS\nPTHREAD_SCOPE_SYSTEM\n\nint pthread_attr_getinheritsched(in pthread_attr_t*, int*);\nint pthread_attr_getschedpolicy(in pthread_attr_t*, int*);\nint pthread_attr_getscope(in pthread_attr_t*, int*);\nint pthread_attr_setinheritsched(pthread_attr_t*, int);\nint pthread_attr_setschedpolicy(pthread_attr_t*, int);\nint pthread_attr_setscope(pthread_attr_t*, int);\nint pthread_getschedparam(pthread_t, int*, sched_param*);\nint pthread_setschedparam(pthread_t, int, in sched_param*);\nint pthread_setschedprio(pthread_t, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum\n    {\n        PTHREAD_SCOPE_SYSTEM,\n        PTHREAD_SCOPE_PROCESS\n    }\n\n    int pthread_attr_getinheritsched(in pthread_attr_t*, int*);\n    int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);\n    int pthread_attr_getscope(in pthread_attr_t*, int*);\n    int pthread_attr_setinheritsched(pthread_attr_t*, int);\n    int pthread_attr_setschedpolicy(pthread_attr_t*, int);\n    int pthread_attr_setscope(pthread_attr_t*, int);\n    int pthread_getschedparam(pthread_t, int*, sched_param*);\n    int pthread_setschedparam(pthread_t, int, in sched_param*);\n    int pthread_setschedprio(pthread_t, int);\n}\nelse version (Darwin)\n{\n    enum\n    {\n        PTHREAD_SCOPE_SYSTEM    = 1,\n        PTHREAD_SCOPE_PROCESS   = 2\n    }\n\n    int pthread_attr_getinheritsched(in pthread_attr_t*, int*);\n    int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);\n    int pthread_attr_getscope(in pthread_attr_t*, int*);\n    int pthread_attr_setinheritsched(pthread_attr_t*, int);\n    int pthread_attr_setschedpolicy(pthread_attr_t*, int);\n    int pthread_attr_setscope(pthread_attr_t*, int);\n    int pthread_getschedparam(pthread_t, int*, sched_param*);\n    int pthread_setschedparam(pthread_t, int, in sched_param*);\n    // int pthread_setschedprio(pthread_t, int); // not implemented\n}\nelse version (FreeBSD)\n{\n    enum\n    {\n        PTHREAD_SCOPE_PROCESS   = 0,\n        PTHREAD_SCOPE_SYSTEM    = 0x2\n    }\n\n    int pthread_attr_getinheritsched(in pthread_attr_t*, int*);\n    int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);\n    int pthread_attr_getscope(in pthread_attr_t*, int*);\n    int pthread_attr_setinheritsched(pthread_attr_t*, int);\n    int pthread_attr_setschedpolicy(pthread_attr_t*, int);\n    int pthread_attr_setscope(in pthread_attr_t*, int);\n    int pthread_getschedparam(pthread_t, int*, sched_param*);\n    int pthread_setschedparam(pthread_t, int, sched_param*);\n    // int pthread_setschedprio(pthread_t, int); // not implemented\n}\nelse version (NetBSD)\n{\n    enum\n    {\n        PTHREAD_SCOPE_PROCESS   = 0,\n        PTHREAD_SCOPE_SYSTEM    = 0x1\n    }\n\n    int pthread_attr_getinheritsched(in pthread_attr_t*, int*);\n    int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);\n    int pthread_attr_getscope(in pthread_attr_t*, int*);\n    int pthread_attr_setinheritsched(pthread_attr_t*, int);\n    int pthread_attr_setschedpolicy(pthread_attr_t*, int);\n    int pthread_attr_setscope(in pthread_attr_t*, int);\n    int pthread_getschedparam(pthread_t, int*, sched_param*);\n    int pthread_setschedparam(pthread_t, int, sched_param*);\n    //int pthread_setschedprio(pthread_t, int);\n}\nelse version (OpenBSD)\n{\n    enum\n    {\n        PTHREAD_SCOPE_PROCESS   = 0,\n        PTHREAD_SCOPE_SYSTEM    = 0x2\n    }\n\n    int pthread_attr_getinheritsched(in pthread_attr_t*, int*);\n    int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);\n    int pthread_attr_getscope(in pthread_attr_t*, int*);\n    int pthread_attr_setinheritsched(pthread_attr_t*, int);\n    int pthread_attr_setschedpolicy(pthread_attr_t*, int);\n    int pthread_attr_setscope(in pthread_attr_t*, int);\n    int pthread_getschedparam(pthread_t, int*, sched_param*);\n    int pthread_setschedparam(pthread_t, int, sched_param*);\n    // int pthread_setschedprio(pthread_t, int); // not implemented\n}\nelse version (DragonFlyBSD)\n{\n    enum\n    {\n        PTHREAD_SCOPE_PROCESS   = 0,\n        PTHREAD_SCOPE_SYSTEM    = 0x2\n    }\n\n    int pthread_attr_getinheritsched(in pthread_attr_t*, int*);\n    int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);\n    int pthread_attr_getscope(in pthread_attr_t*, int*);\n    int pthread_attr_setinheritsched(pthread_attr_t*, int);\n    int pthread_attr_setschedpolicy(pthread_attr_t*, int);\n    int pthread_attr_setscope(in pthread_attr_t*, int);\n    int pthread_getschedparam(pthread_t, int*, sched_param*);\n    int pthread_setschedparam(pthread_t, int, sched_param*);\n}\nelse version (Solaris)\n{\n    enum\n    {\n        PTHREAD_SCOPE_PROCESS = 0,\n        PTHREAD_SCOPE_SYSTEM = 1,\n    }\n\n    int pthread_attr_getinheritsched(in pthread_attr_t*, int*);\n    int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);\n    int pthread_attr_getscope(in pthread_attr_t*, int*);\n    int pthread_attr_setinheritsched(pthread_attr_t*, int);\n    int pthread_attr_setschedpolicy(pthread_attr_t*, int);\n    int pthread_attr_setscope(in pthread_attr_t*, int);\n    int pthread_getschedparam(pthread_t, int*, sched_param*);\n    int pthread_setschedparam(pthread_t, int, sched_param*);\n    int pthread_setschedprio(pthread_t, int);\n}\nelse version (CRuntime_Bionic)\n{\n    enum\n    {\n        PTHREAD_SCOPE_SYSTEM,\n        PTHREAD_SCOPE_PROCESS\n    }\n\n    int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);\n    int pthread_attr_getscope(in pthread_attr_t*);\n    int pthread_attr_setschedpolicy(pthread_attr_t*, int);\n    int pthread_attr_setscope(pthread_attr_t*, int);\n    int pthread_getschedparam(pthread_t, int*, sched_param*);\n    int pthread_setschedparam(pthread_t, int, in sched_param*);\n}\nelse version (CRuntime_Musl)\n{\n    enum\n    {\n        PTHREAD_SCOPE_SYSTEM,\n        PTHREAD_SCOPE_PROCESS\n    }\n\n    int pthread_getschedparam(pthread_t, int*, sched_param*);\n    int pthread_setschedparam(pthread_t, int, in sched_param*);\n    int pthread_setschedprio(pthread_t, int);\n}\nelse version (CRuntime_UClibc)\n{\n    enum\n    {\n        PTHREAD_SCOPE_SYSTEM,\n        PTHREAD_SCOPE_PROCESS\n    }\n\n    int pthread_attr_getinheritsched(in pthread_attr_t*, int*);\n    int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);\n    int pthread_attr_getscope(in pthread_attr_t*, int*);\n    int pthread_attr_setinheritsched(pthread_attr_t*, int);\n    int pthread_attr_setschedpolicy(pthread_attr_t*, int);\n    int pthread_attr_setscope(pthread_attr_t*, int);\n    int pthread_getschedparam(pthread_t, int*, sched_param*);\n    int pthread_setschedparam(pthread_t, int, in sched_param*);\n    int pthread_setschedprio(pthread_t, int);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Stack (TSA|TSS)\n//\n/*\nint pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); (TSA|TSS)\nint pthread_attr_getstackaddr(in pthread_attr_t*, void**); (TSA)\nint pthread_attr_getstacksize(in pthread_attr_t*, size_t*); (TSS)\nint pthread_attr_setstack(pthread_attr_t*, void*, size_t); (TSA|TSS)\nint pthread_attr_setstackaddr(pthread_attr_t*, void*); (TSA)\nint pthread_attr_setstacksize(pthread_attr_t*, size_t); (TSS)\n*/\n\nversion (CRuntime_Glibc)\n{\n    int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);\n    int pthread_attr_getstackaddr(in pthread_attr_t*, void**);\n    int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setstack(pthread_attr_t*, void*, size_t);\n    int pthread_attr_setstackaddr(pthread_attr_t*, void*);\n    int pthread_attr_setstacksize(pthread_attr_t*, size_t);\n}\nelse version (Darwin)\n{\n    int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);\n    int pthread_attr_getstackaddr(in pthread_attr_t*, void**);\n    int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setstack(pthread_attr_t*, void*, size_t);\n    int pthread_attr_setstackaddr(pthread_attr_t*, void*);\n    int pthread_attr_setstacksize(pthread_attr_t*, size_t);\n}\nelse version (FreeBSD)\n{\n    int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);\n    int pthread_attr_getstackaddr(in pthread_attr_t*, void**);\n    int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setstack(pthread_attr_t*, void*, size_t);\n    int pthread_attr_setstackaddr(pthread_attr_t*, void*);\n    int pthread_attr_setstacksize(pthread_attr_t*, size_t);\n}\nelse version (NetBSD)\n{\n    int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);\n    int pthread_attr_getstackaddr(in pthread_attr_t*, void**);\n    int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setstack(pthread_attr_t*, void*, size_t);\n    int pthread_attr_setstackaddr(pthread_attr_t*, void*);\n    int pthread_attr_setstacksize(pthread_attr_t*, size_t);\n}\nelse version (OpenBSD)\n{\n    int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);\n    int pthread_attr_getstackaddr(in pthread_attr_t*, void**);\n    int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setstack(pthread_attr_t*, void*, size_t);\n    int pthread_attr_setstackaddr(pthread_attr_t*, void*);\n    int pthread_attr_setstacksize(pthread_attr_t*, size_t);\n}\nelse version (DragonFlyBSD)\n{\n    int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);\n    int pthread_attr_getstackaddr(in pthread_attr_t*, void**);\n    int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setstack(pthread_attr_t*, void*, size_t);\n    int pthread_attr_setstackaddr(pthread_attr_t*, void*);\n    int pthread_attr_setstacksize(pthread_attr_t*, size_t);\n}\nelse version (Solaris)\n{\n    int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);\n    int pthread_attr_getstackaddr(in pthread_attr_t*, void**);\n    int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setstack(pthread_attr_t*, void*, size_t);\n    int pthread_attr_setstackaddr(pthread_attr_t*, void*);\n    int pthread_attr_setstacksize(pthread_attr_t*, size_t);\n}\nelse version (CRuntime_Bionic)\n{\n    int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);\n    int pthread_attr_getstackaddr(in pthread_attr_t*, void**);\n    int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setstack(pthread_attr_t*, void*, size_t);\n    int pthread_attr_setstackaddr(pthread_attr_t*, void*);\n    int pthread_attr_setstacksize(pthread_attr_t*, size_t);\n}\nelse version (CRuntime_Musl)\n{\n    int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);\n    int pthread_attr_setstacksize(pthread_attr_t*, size_t);\n}\nelse version (CRuntime_UClibc)\n{\n    int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);\n    int pthread_attr_getstackaddr(in pthread_attr_t*, void**);\n    int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);\n    int pthread_attr_setstack(pthread_attr_t*, void*, size_t);\n    int pthread_attr_setstackaddr(pthread_attr_t*, void*);\n    int pthread_attr_setstacksize(pthread_attr_t*, size_t);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Shared Synchronization (TSH)\n//\n/*\nint pthread_condattr_getpshared(in pthread_condattr_t*, int*);\nint pthread_condattr_setpshared(pthread_condattr_t*, int);\nint pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);\nint pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);\nint pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);\nint pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int pthread_condattr_getpshared(in pthread_condattr_t*, int*);\n    int pthread_condattr_setpshared(pthread_condattr_t*, int);\n    int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);\n    int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);\n    int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);\n}\nelse version (FreeBSD)\n{\n    int pthread_condattr_getpshared(in pthread_condattr_t*, int*);\n    int pthread_condattr_setpshared(pthread_condattr_t*, int);\n    int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);\n    int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);\n    int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);\n}\nelse version (NetBSD)\n{\n    int pthread_condattr_getpshared(in pthread_condattr_t*, int*);\n    int pthread_condattr_setpshared(pthread_condattr_t*, int);\n    int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);\n    int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);\n    int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);\n}\nelse version (OpenBSD)\n{\n}\nelse version (DragonFlyBSD)\n{\n    int pthread_condattr_getpshared(in pthread_condattr_t*, int*);\n    int pthread_condattr_setpshared(pthread_condattr_t*, int);\n    int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);\n    int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);\n    int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);\n}\nelse version (Darwin)\n{\n    int pthread_condattr_getpshared(in pthread_condattr_t*, int*);\n    int pthread_condattr_setpshared(pthread_condattr_t*, int);\n    int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);\n    int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);\n    int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);\n}\nelse version (Solaris)\n{\n    int pthread_condattr_getpshared(in pthread_condattr_t*, int*);\n    int pthread_condattr_setpshared(pthread_condattr_t*, int);\n    int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);\n    int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);\n    int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);\n}\nelse version (CRuntime_Bionic)\n{\n    int pthread_condattr_getpshared(pthread_condattr_t*, int*);\n    int pthread_condattr_setpshared(pthread_condattr_t*, int);\n    int pthread_mutexattr_getpshared(pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);\n    int pthread_rwlockattr_getpshared(pthread_rwlockattr_t*, int*);\n    int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);\n}\nelse version (CRuntime_Musl)\n{\n\n}\nelse version (CRuntime_UClibc)\n{\n    int pthread_condattr_getpshared(in pthread_condattr_t*, int*);\n    int pthread_condattr_setpshared(pthread_condattr_t*, int);\n    int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);\n    int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);\n    int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);\n    int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/pwd.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.pwd;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types; // for gid_t, uid_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// Required\n//\n/*\nstruct passwd\n{\n    char*   pw_name;\n    uid_t   pw_uid;\n    gid_t   pw_gid;\n    char*   pw_dir;\n    char*   pw_shell;\n}\n\npasswd* getpwnam(in char*);\npasswd* getpwuid(uid_t);\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct passwd\n    {\n        char*   pw_name;\n        char*   pw_passwd;\n        uid_t   pw_uid;\n        gid_t   pw_gid;\n        char*   pw_gecos;\n        char*   pw_dir;\n        char*   pw_shell;\n    }\n}\nelse version (Darwin)\n{\n    struct passwd\n    {\n        char*   pw_name;\n        char*   pw_passwd;\n        uid_t   pw_uid;\n        gid_t   pw_gid;\n        time_t  pw_change;\n        char*   pw_class;\n        char*   pw_gecos;\n        char*   pw_dir;\n        char*   pw_shell;\n        time_t  pw_expire;\n    }\n}\nelse version (FreeBSD)\n{\n    struct passwd\n    {\n        char*   pw_name;        /* user name */\n        char*   pw_passwd;      /* encrypted password */\n        uid_t   pw_uid;         /* user uid */\n        gid_t   pw_gid;         /* user gid */\n        time_t  pw_change;      /* password change time */\n        char*   pw_class;       /* user access class */\n        char*   pw_gecos;       /* Honeywell login info */\n        char*   pw_dir;     /* home directory */\n        char*   pw_shell;       /* default shell */\n        time_t  pw_expire;      /* account expiration */\n        int pw_fields;      /* internal: fields filled in */\n    }\n}\nelse version (NetBSD)\n{\n    struct passwd\n    {\n        char*   pw_name;        /* user name */\n        char*   pw_passwd;      /* encrypted password */\n        uid_t   pw_uid;         /* user uid */\n        gid_t   pw_gid;         /* user gid */\n        time_t  pw_change;      /* password change time */\n        char*   pw_class;       /* user access class */\n        char*   pw_gecos;       /* Honeywell login info */\n        char*   pw_dir;     /* home directory */\n        char*   pw_shell;       /* default shell */\n        time_t  pw_expire;      /* account expiration */\n    }\n}\nelse version (OpenBSD)\n{\n    struct passwd\n    {\n        char*   pw_name;        /* user name */\n        char*   pw_passwd;      /* encrypted password */\n        uid_t   pw_uid;         /* user uid */\n        gid_t   pw_gid;         /* user gid */\n        time_t  pw_change;      /* password change time */\n        char*   pw_class;       /* user access class */\n        char*   pw_gecos;       /* Honeywell login info */\n        char*   pw_dir;     /* home directory */\n        char*   pw_shell;       /* default shell */\n        time_t  pw_expire;      /* account expiration */\n    }\n}\nelse version (DragonFlyBSD)\n{\n    struct passwd\n    {\n        char*   pw_name;        /* user name */\n        char*   pw_passwd;      /* encrypted password */\n        uid_t   pw_uid;         /* user uid */\n        gid_t   pw_gid;         /* user gid */\n        time_t  pw_change;      /* password change time */\n        char*   pw_class;       /* user access class */\n        char*   pw_gecos;       /* Honeywell login info */\n        char*   pw_dir;         /* home directory */\n        char*   pw_shell;       /* default shell */\n        time_t  pw_expire;      /* account expiration */\n        int pw_fields;          /* internal: fields filled in */\n    }\n}\nelse version (Solaris)\n{\n    struct passwd\n    {\n        char* pw_name;\n        char* pw_passwd;\n        uid_t pw_uid;\n        gid_t pw_gid;\n        char* pw_age;\n        char* pw_comment;\n        char* pw_gecos;\n        char* pw_dir;\n        char* pw_shell;\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    struct passwd\n    {\n        char*   pw_name;\n        char*   pw_passwd;\n        uid_t   pw_uid;\n        gid_t   pw_gid;\n        char*   pw_dir;\n        char*   pw_shell;\n    }\n}\nelse version (CRuntime_Musl)\n{\n    struct passwd {\n        char *pw_name;\n        char *pw_passwd;\n        uid_t pw_uid;\n        gid_t pw_gid;\n        char *pw_gecos;\n        char *pw_dir;\n        char *pw_shell;\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    struct passwd\n    {\n        char*   pw_name;\n        char*   pw_passwd;\n        uid_t   pw_uid;\n        gid_t   pw_gid;\n        char*   pw_gecos;\n        char*   pw_dir;\n        char*   pw_shell;\n    }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\npasswd* getpwnam(in char*);\npasswd* getpwuid(uid_t);\n\n//\n// Thread-Safe Functions (TSF)\n//\n/*\nint getpwnam_r(in char*, passwd*, char*, size_t, passwd**);\nint getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);\n    int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);\n}\nelse version (Darwin)\n{\n    int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);\n    int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);\n}\nelse version (FreeBSD)\n{\n    int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);\n    int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);\n}\nelse version (NetBSD)\n{\n    int __getpwnam_r50(in char*, passwd*, char*, size_t, passwd**);\n    alias __getpwnam_r50 getpwnam_r;\n    int __getpwuid_r50(uid_t, passwd*, char*, size_t, passwd**);\n    alias __getpwuid_r50 getpwuid_r;\n}\nelse version (OpenBSD)\n{\n    int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);\n    int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);\n}\nelse version (DragonFlyBSD)\n{\n    int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);\n    int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);\n}\nelse version (Solaris)\n{\n    alias getpwnam_r = __posix_getpwnam_r;\n    alias getpwuid_r = __posix_getpwuid_r;\n\n    // POSIX.1c standard version of the functions\n    int __posix_getpwnam_r(in char*, passwd*, char*, size_t, passwd**);\n    int __posix_getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);\n}\nelse version (CRuntime_Bionic)\n{\n}\nelse version (CRuntime_Musl)\n{\n}\nelse version (CRuntime_UClibc)\n{\n    int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);\n    int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// XOpen (XSI)\n//\n/*\nvoid    endpwent();\npasswd* getpwent();\nvoid    setpwent();\n*/\n\nversion (CRuntime_Glibc)\n{\n    void    endpwent();\n    passwd* getpwent();\n    void    setpwent();\n}\nelse version (Darwin)\n{\n    void    endpwent();\n    passwd* getpwent();\n    void    setpwent();\n}\nelse version (FreeBSD)\n{\n    void    endpwent();\n    passwd* getpwent();\n    void    setpwent();\n}\nelse version (NetBSD)\n{\n    void    endpwent();\n    passwd* getpwent();\n    void    setpwent();\n}\nelse version (OpenBSD)\n{\n    void    endpwent();\n    passwd* getpwent();\n    void    setpwent();\n}\nelse version (DragonFlyBSD)\n{\n    void    endpwent();\n    passwd* getpwent();\n    void    setpwent();\n}\nelse version (Solaris)\n{\n    void endpwent();\n    passwd* getpwent();\n    void setpwent();\n}\nelse version (CRuntime_Bionic)\n{\n    void    endpwent();\n}\nelse version (CRuntime_Musl)\n{\n    int getpwnam_r(in char*, passwd*, char*, size_t, passwd**);\n    int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);\n}\nelse version (CRuntime_UClibc)\n{\n    void    endpwent();\n    passwd* getpwent();\n    void    setpwent();\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sched.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly,\n              Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sched;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.time;\npublic import core.sys.posix.sys.types;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// Required\n//\n/*\nstruct sched_param\n{\n    int sched_priority (THR)\n    int sched_ss_low_priority (SS|TSP)\n    struct timespec sched_ss_repl_period (SS|TSP)\n    struct timespec sched_ss_init_budget (SS|TSP)\n    int sched_ss_max_repl (SS|TSP)\n}\n\nSCHED_FIFO\nSCHED_RR\nSCHED_SPORADIC (SS|TSP)\nSCHED_OTHER\n\nint sched_getparam(pid_t, sched_param*);\nint sched_getscheduler(pid_t);\nint sched_setparam(pid_t, in sched_param*);\nint sched_setscheduler(pid_t, int, in sched_param*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct sched_param\n    {\n        int sched_priority;\n    }\n\n    enum SCHED_OTHER    = 0;\n    enum SCHED_FIFO     = 1;\n    enum SCHED_RR       = 2;\n    //SCHED_SPORADIC (SS|TSP)\n}\nelse version (CRuntime_Musl)\n{\n    struct sched_param {\n        int sched_priority;\n        int sched_ss_low_priority;\n        timespec sched_ss_repl_period;\n        timespec sched_ss_init_budget;\n        int sched_ss_max_repl;\n    }\n}\nelse version (Darwin)\n{\n    enum SCHED_OTHER    = 1;\n    enum SCHED_FIFO     = 4;\n    enum SCHED_RR       = 2;\n    //SCHED_SPORADIC (SS|TSP)\n\n    private enum __SCHED_PARAM_SIZE__ = 4;\n\n    struct sched_param\n    {\n        int                             sched_priority;\n        byte[__PTHREAD_MUTEX_SIZE__]    __opaque;\n    }\n}\nelse version (FreeBSD)\n{\n    struct sched_param\n    {\n        int sched_priority;\n    }\n\n    enum SCHED_FIFO     = 1;\n    enum SCHED_OTHER    = 2;\n    enum SCHED_RR       = 3;\n}\nelse version (NetBSD)\n{\n    struct sched_param\n    {\n        int sched_priority;\n    }\n\n    enum SCHED_FIFO     = 1;\n    enum SCHED_OTHER    = 0;\n    enum SCHED_RR       = 2;\n}\nelse version (OpenBSD)\n{\n    struct sched_param\n    {\n        int sched_priority;\n    }\n\n    enum SCHED_FIFO     = 1;\n    enum SCHED_OTHER    = 2;\n    enum SCHED_RR       = 3;\n}\nelse version (DragonFlyBSD)\n{\n    struct sched_param\n    {\n        int sched_priority;\n    }\n\n    enum SCHED_FIFO     = 1;\n    enum SCHED_OTHER    = 2;\n    enum SCHED_RR       = 3;\n}\nelse version (Solaris)\n{\n    struct sched_param\n    {\n        int sched_priority;\n        int[8] sched_pad;\n    }\n\n    enum SCHED_OTHER = 0;\n    enum SCHED_FIFO = 1;\n    enum SCHED_RR = 2;\n    enum SCHED_SYS = 3;\n    enum SCHED_IA = 4;\n    enum SCHED_FSS = 5;\n    enum SCHED_FX = 6;\n    enum _SCHED_NEXT = 7;\n}\nelse version (CRuntime_Bionic)\n{\n    struct sched_param\n    {\n        int sched_priority;\n    }\n\n    enum SCHED_NORMAL   = 0;\n    enum SCHED_OTHER    = 0;\n    enum SCHED_FIFO     = 1;\n    enum SCHED_RR       = 2;\n}\nelse version (CRuntime_UClibc)\n{\n    struct sched_param\n    {\n        int sched_priority;\n    }\n\n    enum SCHED_OTHER    = 0;\n    enum SCHED_FIFO     = 1;\n    enum SCHED_RR       = 2;\n    enum SCHED_BATCH    = 3;\n    enum SCHED_IDLE     = 5;\n\n    enum SCHED_RESET_ON_FORK    = 0x40000000;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\nint sched_getparam(pid_t, sched_param*);\nint sched_getscheduler(pid_t);\nint sched_setparam(pid_t, in sched_param*);\nint sched_setscheduler(pid_t, int, in sched_param*);\n\n//\n// Thread (THR)\n//\n/*\nint sched_yield();\n*/\n\nversion (CRuntime_Glibc)\n{\n    int sched_yield();\n}\nelse version (Darwin)\n{\n    int sched_yield();\n}\nelse version (FreeBSD)\n{\n    int sched_yield();\n}\nelse version (NetBSD)\n{\n    int sched_yield();\n}\nelse version (OpenBSD)\n{\n    int sched_yield();\n}\nelse version (DragonFlyBSD)\n{\n    int sched_yield();\n}\nelse version (Solaris)\n{\n    int sched_yield();\n}\nelse version (CRuntime_Bionic)\n{\n    int sched_yield();\n}\nelse version (CRuntime_Musl)\n{\n    int sched_yield();\n}\nelse version (CRuntime_UClibc)\n{\n    int sched_yield();\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Scheduling (TPS)\n//\n/*\nint sched_get_priority_max(int);\nint sched_get_priority_min(int);\nint sched_rr_get_interval(pid_t, timespec*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int sched_get_priority_max(int);\n    int sched_get_priority_min(int);\n    int sched_rr_get_interval(pid_t, timespec*);\n}\nelse version (Darwin)\n{\n    int sched_get_priority_min(int);\n    int sched_get_priority_max(int);\n    //int sched_rr_get_interval(pid_t, timespec*); // FIXME: unavailable?\n}\nelse version (FreeBSD)\n{\n    int sched_get_priority_min(int);\n    int sched_get_priority_max(int);\n    int sched_rr_get_interval(pid_t, timespec*);\n}\nelse version (NetBSD)\n{\n    int sched_get_priority_min(int);\n    int sched_get_priority_max(int);\n    int sched_rr_get_interval(pid_t, timespec*);\n}\nelse version (OpenBSD)\n{\n    int sched_get_priority_min(int);\n    int sched_get_priority_max(int);\n    int sched_rr_get_interval(pid_t, timespec*);\n}\nelse version (DragonFlyBSD)\n{\n    int sched_get_priority_min(int);\n    int sched_get_priority_max(int);\n    int sched_rr_get_interval(pid_t, timespec*);\n}\nelse version (Solaris)\n{\n    int sched_get_priority_max(int);\n    int sched_get_priority_min(int);\n    int sched_rr_get_interval(pid_t, timespec*);\n}\nelse version (CRuntime_Bionic)\n{\n    int sched_get_priority_max(int);\n    int sched_get_priority_min(int);\n    int sched_rr_get_interval(pid_t, timespec*);\n}\nelse version (CRuntime_Musl)\n{\n    int sched_get_priority_max(int);\n    int sched_get_priority_min(int);\n    int sched_rr_get_interval(pid_t, timespec*);\n}\nelse version (CRuntime_UClibc)\n{\n    int sched_get_priority_max(int);\n    int sched_get_priority_min(int);\n    int sched_rr_get_interval(pid_t, timespec*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/semaphore.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.semaphore;\n\nprivate import core.sys.posix.config;\nprivate import core.sys.posix.time;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// Required\n//\n/*\nsem_t\nSEM_FAILED\n\nint sem_close(sem_t*);\nint sem_destroy(sem_t*);\nint sem_getvalue(sem_t*, int*);\nint sem_init(sem_t*, int, uint);\nsem_t* sem_open(in char*, int, ...);\nint sem_post(sem_t*);\nint sem_trywait(sem_t*);\nint sem_unlink(in char*);\nint sem_wait(sem_t*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    private alias int __atomic_lock_t;\n\n    private struct _pthread_fastlock\n    {\n      c_long            __status;\n      __atomic_lock_t   __spinlock;\n    }\n\n    struct sem_t\n    {\n      _pthread_fastlock __sem_lock;\n      int               __sem_value;\n      void*             __sem_waiting;\n    }\n\n    enum SEM_FAILED = cast(sem_t*) null;\n}\nelse version (Darwin)\n{\n    alias int sem_t;\n\n    enum SEM_FAILED = cast(sem_t*) null;\n}\nelse version (FreeBSD)\n{\n    // FBSD-9.0 definition\n    struct sem_t\n    {\n        uint _magic;\n        struct _usem\n        {\n            shared uint _has_waiters;\n            shared uint _count;\n            uint _flags;\n        } _usem _kern;\n    }\n\n    enum SEM_FAILED = cast(sem_t*) null;\n}\nelse version (NetBSD)\n{\n    alias size_t sem_t;\n\n    enum SEM_FAILED = cast(sem_t*) null;\n}\nelse version (OpenBSD)\n{\n    struct __sem { }\n    alias sem_t = __sem*;\n\n    enum SEM_FAILED = cast(sem_t*) null;\n}\nelse version (DragonFlyBSD)\n{\n    struct sem_t\n    {\n        uint _magic;\n        struct _usem\n        {\n            shared uint _has_waiters;\n            shared uint _count;\n            uint _flags;\n        } _usem _kern;\n    }\n\n    enum SEM_FAILED = cast(sem_t*) null;\n}\nelse version (Solaris)\n{\n    struct sem_t\n    {\n        uint sem_count;\n        ushort sem_type;\n        ushort sem_magic;\n        ulong[3] sem_pad1;\n        ulong[2] sem_pad2;\n    }\n\n    enum SEM_FAILED = cast(sem_t*)-1;\n}\nelse version (CRuntime_Bionic)\n{\n    struct sem_t\n    {\n        uint count; //volatile\n    }\n\n    enum SEM_FAILED = null;\n}\nelse version (CRuntime_Musl)\n{\n    struct sem_t {\n        int[4*long.sizeof/int.sizeof] __val;\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    enum __SIZEOF_SEM_T  = 16;\n\n    union sem_t\n    {\n        byte[__SIZEOF_SEM_T] __size;\n        c_long __align;\n    }\n\n    enum SEM_FAILED      = cast(sem_t*) null;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\nint sem_close(sem_t*);\nint sem_destroy(sem_t*);\nint sem_getvalue(sem_t*, int*);\nint sem_init(sem_t*, int, uint);\nsem_t* sem_open(in char*, int, ...);\nint sem_post(sem_t*);\nint sem_trywait(sem_t*);\nint sem_unlink(in char*);\nint sem_wait(sem_t*);\n\n//\n// Timeouts (TMO)\n//\n/*\nint sem_timedwait(sem_t*, in timespec*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int sem_timedwait(sem_t*, in timespec*);\n}\nelse version (Darwin)\n{\n    int sem_timedwait(sem_t*, in timespec*);\n}\nelse version (FreeBSD)\n{\n    int sem_timedwait(sem_t*, in timespec*);\n}\nelse version (NetBSD)\n{\n    int sem_timedwait(sem_t*, in timespec*);\n}\nelse version (OpenBSD)\n{\n    int sem_timedwait(sem_t*, in timespec*);\n}\nelse version (DragonFlyBSD)\n{\n    int sem_timedwait(sem_t*, in timespec*);\n}\nelse version (Solaris)\n{\n    int sem_timedwait(sem_t*, in timespec*);\n}\nelse version (CRuntime_Bionic)\n{\n    int sem_timedwait(sem_t*, in timespec*);\n}\nelse version (CRuntime_Musl)\n{\n    int sem_timedwait(sem_t*, in timespec*);\n}\nelse version (CRuntime_UClibc)\n{\n    int sem_timedwait(sem_t*, in timespec*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/setjmp.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.setjmp;\n\nprivate import core.sys.posix.config;\nprivate import core.sys.posix.signal; // for sigset_t\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// Required\n//\n/*\njmp_buf\n\nint  setjmp(ref jmp_buf);\nvoid longjmp(ref jmp_buf, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    version (X86_64)\n    {\n        //enum JB_BX      = 0;\n        //enum JB_BP      = 1;\n        //enum JB_12      = 2;\n        //enum JB_13      = 3;\n        //enum JB_14      = 4;\n        //enum JB_15      = 5;\n        //enum JB_SP      = 6;\n        //enum JB_PC      = 7;\n        //enum JB_SIZE    = 64;\n\n        alias long[8] __jmp_buf;\n    }\n    else version (X86)\n    {\n        //enum JB_BX      = 0;\n        //enum JB_SI      = 1;\n        //enum JB_DI      = 2;\n        //enum JB_BP      = 3;\n        //enum JB_SP      = 4;\n        //enum JB_PC      = 5;\n        //enum JB_SIZE    = 24;\n\n        alias int[6] __jmp_buf;\n    }\n    else version (SPARC)\n    {\n        alias int[3] __jmp_buf;\n    }\n    else version (SPARC64)\n    {\n        alias __jmp_buf = ulong[22];\n    }\n    else version (AArch64)\n    {\n        alias long[22] __jmp_buf;\n    }\n    else version (ARM)\n    {\n        alias int[64] __jmp_buf;\n    }\n    else version (PPC)\n    {\n        alias int[64 + (12*4)] __jmp_buf;\n    }\n    else version (PPC64)\n    {\n        alias long[64] __jmp_buf;\n    }\n    else version (MIPS32)\n    {\n        struct __jmp_buf\n        {\n            version (MIPS_O32)\n            {\n                void * __pc;\n                void * __sp;\n                int[8] __regs;\n                void * __fp;\n                void * __gp;\n            }\n            else\n            {\n                long __pc;\n                long __sp;\n                long[8] __regs;\n                long __fp;\n                long __gp;\n            }\n            int __fpc_csr;\n            version (MIPS_N64)\n                double[8] __fpregs;\n            else\n                double[6] __fpregs;\n        }\n    }\n    else version (MIPS64)\n    {\n        struct __jmp_buf\n        {\n            long __pc;\n            long __sp;\n            long[8] __regs;\n            long __fp;\n            long __gp;\n            int __fpc_csr;\n            version (MIPS_N64)\n                double[8] __fpregs;\n            else\n                double[6] __fpregs;\n        }\n    }\n    else version (SystemZ)\n    {\n        struct __s390_jmp_buf\n        {\n            c_long[10] __gregs;\n            c_long[8] __fpregs;\n        }\n        alias __jmp_buf = __s390_jmp_buf[1];\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    struct __jmp_buf_tag\n    {\n        __jmp_buf   __jmpbuf;\n        int         __mask_was_saved;\n        sigset_t    __saved_mask;\n    }\n\n    alias __jmp_buf_tag[1] jmp_buf;\n\n    alias _setjmp setjmp; // see XOpen block\n    void longjmp(ref jmp_buf, int);\n}\nelse version (FreeBSD)\n{\n    // <machine/setjmp.h>\n    version (X86)\n    {\n        enum _JBLEN = 11;\n        struct _jmp_buf { int[_JBLEN + 1] _jb; }\n    }\n    else version (X86_64)\n    {\n        enum _JBLEN = 12;\n        struct _jmp_buf { c_long[_JBLEN] _jb; }\n    }\n    else version (SPARC)\n    {\n        enum _JBLEN = 5;\n        struct _jmp_buf { c_long[_JBLEN + 1] _jb; }\n    }\n    else version (AArch64)\n    {\n        enum _JBLEN = 31;\n        // __int128_t\n        struct _jmp_buf { long[2][_JBLEN + 1] _jb; };\n    }\n    else\n        static assert(0);\n    alias _jmp_buf[1] jmp_buf;\n\n    int  setjmp(ref jmp_buf);\n    void longjmp(ref jmp_buf, int);\n}\nelse version (NetBSD)\n{\n    // <machine/setjmp.h>\n    version (X86)\n    {\n        enum _JBLEN = 13;\n        struct _jmp_buf { int[_JBLEN + 1] _jb; }\n    }\n    else version (X86_64)\n    {\n        enum _JBLEN = 11;\n        struct _jmp_buf { c_long[_JBLEN] _jb; }\n    }\n    else\n        static assert(0);\n    alias _jmp_buf[_JBLEN] jmp_buf;\n\n    int  setjmp(ref jmp_buf);\n    void longjmp(ref jmp_buf, int);\n}\nelse version (OpenBSD)\n{\n    // <machine/setjmp.h>\n    version (X86)\n    {\n        enum _JBLEN = 10;\n    }\n    else version (X86_64)\n    {\n        enum _JBLEN = 11;\n    }\n    else version (ARM)\n    {\n        enum _JBLEN = 64;\n    }\n    else version (PPC)\n    {\n        enum _JBLEN = 100;\n    }\n    else version (MIPS64)\n    {\n        enum _JBLEN = 83;\n    }\n    else version (SPARC)\n    {\n        enum _JBLEN = 10;\n    }\n    else version (SPARC64)\n    {\n        enum _JBLEN = 14;\n    }\n    else\n        static assert(0);\n\n    alias jmp_buf = c_long[_JBLEN];\n\n    int  setjmp(ref jmp_buf);\n    void longjmp(ref jmp_buf, int);\n}\nelse version (DragonFlyBSD)\n{\n    // <machine/setjmp.h>\n    version (X86_64)\n    {\n        enum _JBLEN = 12;\n        struct _jmp_buf { c_long[_JBLEN] _jb; }\n    }\n    else\n        static assert(0);\n    alias _jmp_buf[1] jmp_buf;\n\n    int  setjmp(ref jmp_buf);\n    void longjmp(ref jmp_buf, int);\n}\nelse version (CRuntime_Bionic)\n{\n    // <machine/setjmp.h>\n    version (X86)\n    {\n        enum _JBLEN = 10;\n    }\n    else version (ARM)\n    {\n        enum _JBLEN = 64;\n    }\n    else version (AArch64)\n    {\n        enum _JBLEN = 32;\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n\n    alias c_long[_JBLEN] jmp_buf;\n\n    int  setjmp(ref jmp_buf);\n    void longjmp(ref jmp_buf, int);\n}\nelse version (CRuntime_UClibc)\n{\n    version (X86_64)\n    {\n        alias long[8] __jmp_buf;\n    }\n    else version (ARM)\n    {\n        align(8) alias int[64] __jmp_buf;\n    }\n    else version (MIPS32)\n    {\n        struct __jmp_buf\n        {\n            version (MIPS_O32)\n            {\n                void * __pc;\n                void * __sp;\n                int[8] __regs;\n                void * __fp;\n                void * __gp;\n            }\n            else\n            {\n                long __pc;\n                long __sp;\n                long[8] __regs;\n                long __fp;\n                long __gp;\n            }\n            int __fpc_csr;\n            version (MIPS_N64)\n                double[8] __fpregs;\n            else\n                double[6] __fpregs;\n        };\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    struct __jmp_buf_tag\n    {\n        __jmp_buf   __jmpbuf;\n        int         __mask_was_saved;\n        sigset_t    __saved_mask;\n    }\n\n    alias __jmp_buf_tag[1] jmp_buf;\n\n    alias _setjmp setjmp;\n    void longjmp(ref jmp_buf, int);\n}\n\n//\n// C Extension (CX)\n//\n/*\nsigjmp_buf\n\nint  sigsetjmp(sigjmp_buf, int);\nvoid siglongjmp(sigjmp_buf, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    alias jmp_buf sigjmp_buf;\n\n    int __sigsetjmp(sigjmp_buf, int);\n    alias __sigsetjmp sigsetjmp;\n    void siglongjmp(sigjmp_buf, int);\n}\nelse version (FreeBSD)\n{\n    // <machine/setjmp.h>\n    version (X86)\n    {\n        struct _sigjmp_buf { int[_JBLEN + 1] _ssjb; }\n    }\n    else version (X86_64)\n    {\n        struct _sigjmp_buf { c_long[_JBLEN] _sjb; }\n    }\n    else version (SPARC)\n    {\n        enum _JBLEN         = 5;\n        enum _JB_FP         = 0;\n        enum _JB_PC         = 1;\n        enum _JB_SP         = 2;\n        enum _JB_SIGMASK    = 3;\n        enum _JB_SIGFLAG    = 5;\n        struct _sigjmp_buf { c_long[_JBLEN + 1] _sjb; }\n    }\n    else version (AArch64)\n    {\n        // __int128_t\n        struct _sigjmp_buf { long[2][_JBLEN + 1] _jb; };\n    }\n    else\n        static assert(0);\n    alias _sigjmp_buf[1] sigjmp_buf;\n\n    int  sigsetjmp(ref sigjmp_buf);\n    void siglongjmp(ref sigjmp_buf, int);\n}\nelse version (NetBSD)\n{\n    // <machine/setjmp.h>\n    version (X86)\n    {\n        struct _sigjmp_buf { int[_JBLEN + 1] _ssjb; }\n    }\n    else version (X86_64)\n    {\n        struct _sigjmp_buf { c_long[_JBLEN] _sjb; }\n    }\n    else\n        static assert(0);\n    alias _sigjmp_buf[_JBLEN + 1] sigjmp_buf;\n\n    int  sigsetjmp(ref sigjmp_buf);\n    void siglongjmp(ref sigjmp_buf, int);\n}\nelse version (OpenBSD)\n{\n    alias sigjmp_buf = c_long[_JBLEN + 1];\n\n    int  sigsetjmp(ref sigjmp_buf);\n    void siglongjmp(ref sigjmp_buf, int);\n}\nelse version (DragonFlyBSD)\n{\n    // <machine/setjmp.h>\n    version (X86_64)\n    {\n        struct _sigjmp_buf { c_long[_JBLEN] _sjb; }\n    }\n    else\n        static assert(0);\n    alias _sigjmp_buf[1] sigjmp_buf;\n\n    int  sigsetjmp(ref sigjmp_buf);\n    void siglongjmp(ref sigjmp_buf, int);\n}\nelse version (CRuntime_Bionic)\n{\n    alias c_long[_JBLEN + 1] sigjmp_buf;\n\n    int  sigsetjmp(ref sigjmp_buf, int);\n    void siglongjmp(ref sigjmp_buf, int);\n}\nelse version (CRuntime_UClibc)\n{\n    alias jmp_buf sigjmp_buf;\n\n    int __sigsetjmp(ref sigjmp_buf, int);\n    alias __sigsetjmp sigsetjmp;\n    void siglongjmp(ref sigjmp_buf, int);\n}\n\n//\n// XOpen (XSI)\n//\n/*\nint  _setjmp(jmp_buf);\nvoid _longjmp(jmp_buf, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int  _setjmp(ref jmp_buf);\n    void _longjmp(ref jmp_buf, int);\n}\nelse version (FreeBSD)\n{\n    int  _setjmp(ref jmp_buf);\n    void _longjmp(ref jmp_buf, int);\n}\nelse version (NetBSD)\n{\n    int  _setjmp(ref jmp_buf);\n    void _longjmp(ref jmp_buf, int);\n}\nelse version (OpenBSD)\n{\n    int  _setjmp(ref jmp_buf);\n    void _longjmp(ref jmp_buf, int);\n}\nelse version (DragonFlyBSD)\n{\n    int  _setjmp(ref jmp_buf);\n    void _longjmp(ref jmp_buf, int);\n}\nelse version (CRuntime_Bionic)\n{\n    int  _setjmp(ref jmp_buf);\n    void _longjmp(ref jmp_buf, int);\n}\nelse version (CRuntime_UClibc)\n{\n    int  _setjmp(ref jmp_buf);\n    void _longjmp(ref jmp_buf, int);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/signal.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Sean Kelly,\n              Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n * Source:    $(DRUNTIMESRC core/sys/posix/_signal.d)\n */\n\nmodule core.sys.posix.signal;\n\nprivate import core.sys.posix.config;\npublic import core.stdc.signal;\npublic import core.sys.posix.sys.types; // for pid_t\n//public import core.sys.posix.time;      // for timespec, now defined here\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\n//nothrow:  // this causes Issue 12738\n\n//\n// Required\n//\n/*\nSIG_DFL (defined in core.stdc.signal)\nSIG_ERR (defined in core.stdc.signal)\nSIG_IGN (defined in core.stdc.signal)\n\nsig_atomic_t (defined in core.stdc.signal)\n\nSIGEV_NONE\nSIGEV_SIGNAL\nSIGEV_THREAD\n\nunion sigval\n{\n    int   sival_int;\n    void* sival_ptr;\n}\n\nSIGRTMIN\nSIGRTMAX\n\nSIGABRT (defined in core.stdc.signal)\nSIGALRM\nSIGBUS\nSIGCHLD\nSIGCONT\nSIGFPE (defined in core.stdc.signal)\nSIGHUP\nSIGILL (defined in core.stdc.signal)\nSIGINT (defined in core.stdc.signal)\nSIGKILL\nSIGPIPE\nSIGQUIT\nSIGSEGV (defined in core.stdc.signal)\nSIGSTOP\nSIGTERM (defined in core.stdc.signal)\nSIGTSTP\nSIGTTIN\nSIGTTOU\nSIGUSR1\nSIGUSR2\nSIGURG\n\nstruct sigaction_t\n{\n    sigfn_t     sa_handler;\n    sigset_t    sa_mask;\n    sigactfn_t  sa_sigaction;\n}\n\nsigfn_t signal(int sig, sigfn_t func); (defined in core.stdc.signal)\nint raise(int sig);                    (defined in core.stdc.signal)\n*/\n\n//SIG_DFL (defined in core.stdc.signal)\n//SIG_ERR (defined in core.stdc.signal)\n//SIG_IGN (defined in core.stdc.signal)\n\n//sig_atomic_t (defined in core.stdc.signal)\n\nprivate alias void function(int) sigfn_t;\nprivate alias void function(int, siginfo_t*, void*) sigactfn_t;\n\n// nothrow versions\nnothrow @nogc\n{\n    private alias void function(int) sigfn_t2;\n    private alias void function(int, siginfo_t*, void*) sigactfn_t2;\n}\n\nenum\n{\n  SIGEV_SIGNAL,\n  SIGEV_NONE,\n  SIGEV_THREAD\n}\n\nunion sigval\n{\n    int     sival_int;\n    void*   sival_ptr;\n}\n\nversion (Solaris)\n{\n    import core.sys.posix.unistd;\n\n    @property int SIGRTMIN() nothrow @nogc {\n        __gshared static int sig = -1;\n        if (sig == -1) {\n            sig = cast(int)sysconf(_SC_SIGRT_MIN);\n        }\n        return sig;\n    }\n\n    @property int SIGRTMAX() nothrow @nogc {\n        __gshared static int sig = -1;\n        if (sig == -1) {\n            sig = cast(int)sysconf(_SC_SIGRT_MAX);\n        }\n        return sig;\n    }\n}\nelse version (CRuntime_Glibc)\n{\n    private extern (C) nothrow @nogc\n    {\n        int __libc_current_sigrtmin();\n        int __libc_current_sigrtmax();\n    }\n\n    @property int SIGRTMIN() nothrow @nogc {\n        __gshared static int sig = -1;\n        if (sig == -1) {\n            sig = __libc_current_sigrtmin();\n        }\n        return sig;\n    }\n\n    @property int SIGRTMAX() nothrow @nogc {\n        __gshared static int sig = -1;\n        if (sig == -1) {\n            sig = __libc_current_sigrtmax();\n        }\n        return sig;\n    }\n}\nelse version (FreeBSD) {\n    // Note: it appears that FreeBSD (prior to 7) and OSX do not support realtime signals\n    // https://github.com/freebsd/freebsd/blob/e79c62ff68fc74d88cb6f479859f6fae9baa5101/sys/sys/signal.h#L117\n    enum SIGRTMIN = 65;\n    enum SIGRTMAX = 126;\n}\nelse version (DragonFlyBSD) {\n    enum SIGRTMIN = 35;\n    enum SIGRTMAX = 126;\n}\nelse version (NetBSD)\n{\n    enum SIGRTMIN = 33;\n    enum SIGRTMAX = 63;\n}\nelse version (CRuntime_Bionic)\n{\n    // Switched to calling these functions since Lollipop\n    private extern (C) nothrow @nogc\n    {\n        int __libc_current_sigrtmin();\n        int __libc_current_sigrtmax();\n    }\n\n    @property int SIGRTMIN() nothrow @nogc {\n        __gshared static int sig = -1;\n        if (sig == -1) {\n            sig = __libc_current_sigrtmin();\n        }\n        return sig;\n    }\n\n    @property int SIGRTMAX() nothrow @nogc {\n        __gshared static int sig = -1;\n        if (sig == -1) {\n            sig = __libc_current_sigrtmax();\n        }\n        return sig;\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    private extern (C) nothrow @nogc\n    {\n        int __libc_current_sigrtmin();\n        int __libc_current_sigrtmax();\n    }\n\n    @property int SIGRTMIN() nothrow @nogc\n    {\n        return __libc_current_sigrtmin();\n    }\n\n    @property int SIGRTMAX() nothrow @nogc\n    {\n        return __libc_current_sigrtmax();\n    }\n}\n\nversion (linux)\n{\n    version (X86)\n    {\n        //SIGABRT (defined in core.stdc.signal)\n        enum SIGALRM    = 14;\n        enum SIGBUS     = 7;\n        enum SIGCHLD    = 17;\n        enum SIGCONT    = 18;\n        //SIGFPE (defined in core.stdc.signal)\n        enum SIGHUP     = 1;\n        //SIGILL (defined in core.stdc.signal)\n        //SIGINT (defined in core.stdc.signal)\n        enum SIGKILL    = 9;\n        enum SIGPIPE    = 13;\n        enum SIGQUIT    = 3;\n        //SIGSEGV (defined in core.stdc.signal)\n        enum SIGSTOP    = 19;\n        //SIGTERM (defined in core.stdc.signal)\n        enum SIGTSTP    = 20;\n        enum SIGTTIN    = 21;\n        enum SIGTTOU    = 22;\n        enum SIGUSR1    = 10;\n        enum SIGUSR2    = 12;\n        enum SIGURG     = 23;\n    }\n    else version (X86_64)\n    {\n        //SIGABRT (defined in core.stdc.signal)\n        enum SIGALRM    = 14;\n        enum SIGBUS     = 7;\n        enum SIGCHLD    = 17;\n        enum SIGCONT    = 18;\n        //SIGFPE (defined in core.stdc.signal)\n        enum SIGHUP     = 1;\n        //SIGILL (defined in core.stdc.signal)\n        //SIGINT (defined in core.stdc.signal)\n        enum SIGKILL    = 9;\n        enum SIGPIPE    = 13;\n        enum SIGQUIT    = 3;\n        //SIGSEGV (defined in core.stdc.signal)\n        enum SIGSTOP    = 19;\n        //SIGTERM (defined in core.stdc.signal)\n        enum SIGTSTP    = 20;\n        enum SIGTTIN    = 21;\n        enum SIGTTOU    = 22;\n        enum SIGUSR1    = 10;\n        enum SIGUSR2    = 12;\n        enum SIGURG     = 23;\n    }\n    else version (MIPS32)\n    {\n        //SIGABRT (defined in core.stdc.signal)\n        enum SIGALRM    = 14;\n        enum SIGBUS     = 10;\n        enum SIGCHLD    = 18;\n        enum SIGCONT    = 25;\n        //SIGFPE (defined in core.stdc.signal)\n        enum SIGHUP     = 1;\n        //SIGILL (defined in core.stdc.signal)\n        //SIGINT (defined in core.stdc.signal)\n        enum SIGKILL    = 9;\n        enum SIGPIPE    = 13;\n        enum SIGQUIT    = 3;\n        //SIGSEGV (defined in core.stdc.signal)\n        enum SIGSTOP    = 23;\n        //SIGTERM (defined in core.stdc.signal)\n        enum SIGTSTP    = 24;\n        enum SIGTTIN    = 26;\n        enum SIGTTOU    = 27;\n        enum SIGUSR1    = 16;\n        enum SIGUSR2    = 17;\n        enum SIGURG     = 21;\n    }\n    else version (MIPS64)\n    {\n        //SIGABRT (defined in core.stdc.signal)\n        enum SIGALRM    = 14;\n        enum SIGBUS     = 10;\n        enum SIGCHLD    = 18;\n        enum SIGCONT    = 25;\n        //SIGFPE (defined in core.stdc.signal)\n        enum SIGHUP     = 1;\n        //SIGILL (defined in core.stdc.signal)\n        //SIGINT (defined in core.stdc.signal)\n        enum SIGKILL    = 9;\n        enum SIGPIPE    = 13;\n        enum SIGQUIT    = 3;\n        //SIGSEGV (defined in core.stdc.signal)\n        enum SIGSTOP    = 23;\n        //SIGTERM (defined in core.stdc.signal)\n        enum SIGTSTP    = 24;\n        enum SIGTTIN    = 26;\n        enum SIGTTOU    = 27;\n        enum SIGUSR1    = 16;\n        enum SIGUSR2    = 17;\n        enum SIGURG     = 21;\n    }\n    else version (PPC)\n    {\n        //SIGABRT (defined in core.stdc.signal)\n        enum SIGALRM    = 14;\n        enum SIGBUS     = 7;\n        enum SIGCHLD    = 17;\n        enum SIGCONT    = 18;\n        //SIGFPE (defined in core.stdc.signal)\n        enum SIGHUP     = 1;\n        //SIGILL (defined in core.stdc.signal)\n        //SIGINT (defined in core.stdc.signal)\n        enum SIGKILL    = 9;\n        enum SIGPIPE    = 13;\n        enum SIGQUIT    = 3;\n        //SIGSEGV (defined in core.stdc.signal)\n        enum SIGSTOP    = 19;\n        //SIGTERM (defined in core.stdc.signal)\n        enum SIGTSTP    = 20;\n        enum SIGTTIN    = 21;\n        enum SIGTTOU    = 22;\n        enum SIGUSR1    = 10;\n        enum SIGUSR2    = 12;\n        enum SIGURG     = 23;\n    }\n    else version (PPC64)\n    {\n        //SIGABRT (defined in core.stdc.signal)\n        enum SIGALRM    = 14;\n        enum SIGBUS     = 7;\n        enum SIGCHLD    = 17;\n        enum SIGCONT    = 18;\n        //SIGFPE (defined in core.stdc.signal)\n        enum SIGHUP     = 1;\n        //SIGILL (defined in core.stdc.signal)\n        //SIGINT (defined in core.stdc.signal)\n        enum SIGKILL    = 9;\n        enum SIGPIPE    = 13;\n        enum SIGQUIT    = 3;\n        //SIGSEGV (defined in core.stdc.signal)\n        enum SIGSTOP    = 19;\n        //SIGTERM (defined in core.stdc.signal)\n        enum SIGTSTP    = 20;\n        enum SIGTTIN    = 21;\n        enum SIGTTOU    = 22;\n        enum SIGUSR1    = 10;\n        enum SIGUSR2    = 12;\n        enum SIGURG     = 23;\n    }\n    else version (ARM)\n    {\n        //SIGABRT (defined in core.stdc.signal)\n        enum SIGALRM    = 14;\n        enum SIGBUS     = 7;\n        enum SIGCHLD    = 17;\n        enum SIGCONT    = 18;\n        //SIGFPE (defined in core.stdc.signal)\n        enum SIGHUP     = 1;\n        //SIGILL (defined in core.stdc.signal)\n        //SIGINT (defined in core.stdc.signal)\n        enum SIGKILL    = 9;\n        enum SIGPIPE    = 13;\n        enum SIGQUIT    = 3;\n        //SIGSEGV (defined in core.stdc.signal)\n        enum SIGSTOP    = 19;\n        //SIGTERM (defined in core.stdc.signal)\n        enum SIGTSTP    = 20;\n        enum SIGTTIN    = 21;\n        enum SIGTTOU    = 22;\n        enum SIGUSR1    = 10;\n        enum SIGUSR2    = 12;\n        enum SIGURG     = 23;\n    }\n    else version (AArch64)\n    {\n        //SIGABRT (defined in core.stdc.signal)\n        enum SIGALRM    = 14;\n        enum SIGBUS     = 7;\n        enum SIGCHLD    = 17;\n        enum SIGCONT    = 18;\n        //SIGFPE (defined in core.stdc.signal)\n        enum SIGHUP     = 1;\n        //SIGILL (defined in core.stdc.signal)\n        //SIGINT (defined in core.stdc.signal)\n        enum SIGKILL    = 9;\n        enum SIGPIPE    = 13;\n        enum SIGQUIT    = 3;\n        //SIGSEGV (defined in core.stdc.signal)\n        enum SIGSTOP    = 19;\n        //SIGTERM (defined in core.stdc.signal)\n        enum SIGTSTP    = 20;\n        enum SIGTTIN    = 21;\n        enum SIGTTOU    = 22;\n        enum SIGUSR1    = 10;\n        enum SIGUSR2    = 12;\n        enum SIGURG     = 23;\n    }\n    else version (SPARC64)\n    {\n        //SIGABRT (defined in core.stdc.signal)\n        enum SIGALRM    = 14;\n        enum SIGBUS     = 10;\n        enum SIGCHLD    = 20;\n        enum SIGCONT    = 19;\n        //SIGFPE (defined in core.stdc.signal)\n        enum SIGHUP     = 1;\n        //SIGILL (defined in core.stdc.signal)\n        //SIGINT (defined in core.stdc.signal)\n        enum SIGKILL    = 9;\n        enum SIGPIPE    = 13;\n        enum SIGQUIT    = 3;\n        //SIGSEGV (defined in core.stdc.signal)\n        enum SIGSTOP    = 17;\n        //SIGTERM (defined in core.stdc.signal)\n        enum SIGTSTP    = 18;\n        enum SIGTTIN    = 21;\n        enum SIGTTOU    = 22;\n        enum SIGUSR1    = 30;\n        enum SIGUSR2    = 31;\n        enum SIGURG     = 16;\n    }\n    else version (SystemZ)\n    {\n        //SIGABRT (defined in core.stdc.signal)\n        enum SIGALRM    = 14;\n        enum SIGBUS     = 7;\n        enum SIGCHLD    = 17;\n        enum SIGCONT    = 18;\n        //SIGFPE (defined in core.stdc.signal)\n        enum SIGHUP     = 1;\n        //SIGILL (defined in core.stdc.signal)\n        //SIGINT (defined in core.stdc.signal)\n        enum SIGKILL    = 9;\n        enum SIGPIPE    = 13;\n        enum SIGQUIT    = 3;\n        //SIGSEGV (defined in core.stdc.signal)\n        enum SIGSTOP    = 19;\n        //SIGTERM (defined in core.stdc.signal)\n        enum SIGTSTP    = 20;\n        enum SIGTTIN    = 21;\n        enum SIGTTOU    = 22;\n        enum SIGUSR1    = 10;\n        enum SIGUSR2    = 12;\n        enum SIGURG     = 23;\n    }\n    else\n        static assert(0, \"unimplemented\");\n}\nelse version (Darwin)\n{\n    //SIGABRT (defined in core.stdc.signal)\n    enum SIGALRM    = 14;\n    enum SIGBUS     = 10;\n    enum SIGCHLD    = 20;\n    enum SIGCONT    = 19;\n    //SIGFPE (defined in core.stdc.signal)\n    enum SIGHUP     = 1;\n    //SIGILL (defined in core.stdc.signal)\n    //SIGINT (defined in core.stdc.signal)\n    enum SIGKILL    = 9;\n    enum SIGPIPE    = 13;\n    enum SIGQUIT    = 3;\n    //SIGSEGV (defined in core.stdc.signal)\n    enum SIGSTOP    = 17;\n    //SIGTERM (defined in core.stdc.signal)\n    enum SIGTSTP    = 18;\n    enum SIGTTIN    = 21;\n    enum SIGTTOU    = 22;\n    enum SIGUSR1    = 30;\n    enum SIGUSR2    = 31;\n    enum SIGURG     = 16;\n}\nelse version (FreeBSD)\n{\n    //SIGABRT (defined in core.stdc.signal)\n    enum SIGALRM    = 14;\n    enum SIGBUS     = 10;\n    enum SIGCHLD    = 20;\n    enum SIGCONT    = 19;\n    //SIGFPE (defined in core.stdc.signal)\n    enum SIGHUP     = 1;\n    //SIGILL (defined in core.stdc.signal)\n    //SIGINT (defined in core.stdc.signal)\n    enum SIGKILL    = 9;\n    enum SIGPIPE    = 13;\n    enum SIGQUIT    = 3;\n    //SIGSEGV (defined in core.stdc.signal)\n    enum SIGSTOP    = 17;\n    //SIGTERM (defined in core.stdc.signal)\n    enum SIGTSTP    = 18;\n    enum SIGTTIN    = 21;\n    enum SIGTTOU    = 22;\n    enum SIGUSR1    = 30;\n    enum SIGUSR2    = 31;\n    enum SIGURG     = 16;\n}\nelse version (NetBSD)\n{\n    //SIGABRT (defined in core.stdc.signal)\n    enum SIGALRM    = 14;\n    enum SIGBUS     = 10;\n    enum SIGCHLD    = 20;\n    enum SIGCONT    = 19;\n    //SIGFPE (defined in core.stdc.signal)\n    enum SIGHUP     = 1;\n    //SIGILL (defined in core.stdc.signal)\n    //SIGINT (defined in core.stdc.signal)\n    enum SIGKILL    = 9;\n    enum SIGPIPE    = 13;\n    enum SIGQUIT    = 3;\n    //SIGSEGV (defined in core.stdc.signal)\n    enum SIGSTOP    = 17;\n    //SIGTERM (defined in core.stdc.signal)\n    enum SIGTSTP    = 18;\n    enum SIGTTIN    = 21;\n    enum SIGTTOU    = 22;\n    enum SIGUSR1    = 30;\n    enum SIGUSR2    = 31;\n    enum SIGURG     = 16;\n}\nelse version (OpenBSD)\n{\n    //SIGABRT (defined in core.stdc.signal)\n    enum SIGALRM    = 14;\n    enum SIGBUS     = 10;\n    enum SIGCHLD    = 20;\n    enum SIGCONT    = 19;\n    //SIGFPE (defined in core.stdc.signal)\n    enum SIGHUP     = 1;\n    //SIGILL (defined in core.stdc.signal)\n    //SIGINT (defined in core.stdc.signal)\n    enum SIGKILL    = 9;\n    enum SIGPIPE    = 13;\n    enum SIGQUIT    = 3;\n    //SIGSEGV (defined in core.stdc.signal)\n    enum SIGSTOP    = 17;\n    //SIGTERM (defined in core.stdc.signal)\n    enum SIGTSTP    = 18;\n    enum SIGTTIN    = 21;\n    enum SIGTTOU    = 22;\n    enum SIGUSR1    = 30;\n    enum SIGUSR2    = 31;\n    enum SIGURG     = 16;\n}\nelse version (DragonFlyBSD)\n{\n    //SIGABRT (defined in core.stdc.signal)\n    enum SIGALRM    = 14;\n    enum SIGBUS     = 10;\n    enum SIGCHLD    = 20;\n    enum SIGCONT    = 19;\n    //SIGFPE (defined in core.stdc.signal)\n    enum SIGHUP     = 1;\n    //SIGILL (defined in core.stdc.signal)\n    //SIGINT (defined in core.stdc.signal)\n    enum SIGKILL    = 9;\n    enum SIGPIPE    = 13;\n    enum SIGQUIT    = 3;\n    //SIGSEGV (defined in core.stdc.signal)\n    enum SIGSTOP    = 17;\n    //SIGTERM (defined in core.stdc.signal)\n    enum SIGTSTP    = 18;\n    enum SIGTTIN    = 21;\n    enum SIGTTOU    = 22;\n    enum SIGUSR1    = 30;\n    enum SIGUSR2    = 31;\n    enum SIGURG     = 16;\n}\nelse version (Solaris)\n{\n    enum SIGALRM = 14;\n    enum SIGBUS = 10;\n    enum SIGCHLD = 18;\n    enum SIGCONT = 25;\n    enum SIGHUP = 1;\n    enum SIGKILL = 9;\n    enum SIGPIPE = 13;\n    enum SIGQUIT = 3;\n    enum SIGSTOP = 23;\n    enum SIGTSTP = 24;\n    enum SIGTTIN = 26;\n    enum SIGTTOU = 27;\n    enum SIGUSR1 = 16;\n    enum SIGUSR2 = 17;\n    enum SIGURG = 21;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\nversion (CRuntime_Glibc)\n{\n    struct sigaction_t\n    {\n        static if ( true /* __USE_POSIX199309 */ )\n        {\n            union\n            {\n                sigfn_t     sa_handler;\n                sigactfn_t  sa_sigaction;\n            }\n        }\n        else\n        {\n            sigfn_t     sa_handler;\n        }\n        sigset_t        sa_mask;\n        int             sa_flags;\n\n        void function() sa_restorer;\n    }\n}\nelse version (CRuntime_Musl)\n{\n    struct sigaction_t\n    {\n        static if ( true /* __USE_POSIX199309 */ )\n        {\n            union\n            {\n                sigfn_t     sa_handler;\n                sigactfn_t  sa_sigaction;\n            }\n        }\n        else\n        {\n            sigfn_t     sa_handler;\n        }\n        sigset_t        sa_mask;\n        int             sa_flags;\n\n        void function() sa_restorer;\n    }\n}\nelse version (FreeBSD)\n{\n    struct sigaction_t\n    {\n        union\n        {\n            sigfn_t     sa_handler;\n            sigactfn_t  sa_sigaction;\n        }\n        int      sa_flags;\n        sigset_t sa_mask;\n    }\n}\nelse version (NetBSD)\n{\n    struct sigaction_t\n    {\n        union\n        {\n            sigfn_t     sa_handler;\n            sigactfn_t  sa_sigaction;\n        }\n        sigset_t sa_mask;\n        int      sa_flags;\n    }\n}\nelse version (OpenBSD)\n{\n    struct sigaction_t\n    {\n        union\n        {\n            sigfn_t     __sa_handler;\n            alias sa_handler = __sa_handler;\n            sigactfn_t  __sa_sigaction;\n            alias sa_sigaction = __sa_sigaction;\n        }\n        sigset_t sa_mask;\n        int      sa_flags;\n    }\n}\nelse version (DragonFlyBSD)\n{\n    struct sigaction_t\n    {\n        union\n        {\n            sigfn_t     sa_handler;\n            sigactfn_t  sa_sigaction;\n        }\n        int      sa_flags;\n        sigset_t sa_mask;\n    }\n}\nelse version (Solaris)\n{\n    struct sigaction_t\n    {\n        int sa_flags;\n\n        union\n        {\n            sigfn_t sa_handler;\n            sigactfn_t sa_sigaction;\n        }\n\n        sigset_t sa_mask;\n        version (D_LP64) {}\n        else\n            int[2] sa_resv;\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    version (ARM)           version = sigaction_common;\n    else version (X86_64)   version = sigaction_common;\n\n    version (sigaction_common)\n    {\n        struct sigaction_t\n        {\n            static if ( true /* __USE_POSIX199309 */ )\n            {\n                union\n                {\n                    sigfn_t     sa_handler;\n                    sigactfn_t  sa_sigaction;\n                }\n            }\n            else\n            {\n                sigfn_t     sa_handler;\n            }\n            c_ulong     sa_flags;\n            void function() sa_restorer;\n            sigset_t    sa_mask;\n        }\n    }\n    else version (MIPS32)\n    {\n        struct sigaction_t\n        {\n            uint     sa_flags;\n            static if ( true /* __USE_POSIX199309 */ )\n            {\n                union\n                {\n                    sigfn_t     sa_handler;\n                    sigactfn_t  sa_sigaction;\n                }\n            }\n            else\n            {\n                sigfn_t     sa_handler;\n            }\n            sigset_t    sa_mask;\n            void function() sa_restorer;\n        }\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    version (X86)\n    {\n        struct sigaction_t\n        {\n            union\n            {\n                sigfn_t    sa_handler;\n                sigactfn_t sa_sigaction;\n            }\n\n            sigset_t        sa_mask;\n            int             sa_flags;\n            void function() sa_restorer;\n        }\n    }\n    else version (ARM)\n    {\n        struct sigaction_t\n        {\n            union\n            {\n                sigfn_t    sa_handler;\n                sigactfn_t sa_sigaction;\n            }\n\n            sigset_t        sa_mask;\n            int             sa_flags;\n            void function() sa_restorer;\n        }\n    }\n    else version (AArch64)\n    {\n        struct sigaction_t\n        {\n            int            sa_flags;\n            union\n            {\n                sigfn_t    sa_handler;\n                sigactfn_t sa_sigaction;\n            }\n\n            sigset_t        sa_mask;\n            void function() sa_restorer;\n        }\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n}\nelse version (Darwin)\n{\n    struct sigaction_t\n    {\n        static if ( true /* __USE_POSIX199309 */ )\n        {\n            union\n            {\n                sigfn_t     sa_handler;\n                sigactfn_t  sa_sigaction;\n            }\n        }\n        else\n        {\n            sigfn_t     sa_handler;\n        }\n        sigset_t        sa_mask;\n        int             sa_flags;\n    }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// C Extension (CX)\n//\n/*\nSIG_HOLD\n\nsigset_t\npid_t   (defined in core.sys.types)\n\nSIGABRT (defined in core.stdc.signal)\nSIGFPE  (defined in core.stdc.signal)\nSIGILL  (defined in core.stdc.signal)\nSIGINT  (defined in core.stdc.signal)\nSIGSEGV (defined in core.stdc.signal)\nSIGTERM (defined in core.stdc.signal)\n\nSA_NOCLDSTOP (CX|XSI)\nSIG_BLOCK\nSIG_UNBLOCK\nSIG_SETMASK\n\nstruct siginfo_t\n{\n    int     si_signo;\n    int     si_code;\n\n    version (XSI)\n    {\n        int     si_errno;\n        pid_t   si_pid;\n        uid_t   si_uid;\n        void*   si_addr;\n        int     si_status;\n        c_long  si_band;\n    }\n    version (RTS)\n    {\n        sigval  si_value;\n    }\n}\n\nSI_USER\nSI_QUEUE\nSI_TIMER\nSI_ASYNCIO\nSI_MESGQ\n\nint kill(pid_t, int);\nint sigaction(int, in sigaction_t*, sigaction_t*);\nint sigaddset(sigset_t*, int);\nint sigdelset(sigset_t*, int);\nint sigemptyset(sigset_t*);\nint sigfillset(sigset_t*);\nint sigismember(in sigset_t*, int);\nint sigpending(sigset_t*);\nint sigprocmask(int, in sigset_t*, sigset_t*);\nint sigsuspend(in sigset_t*);\nint sigwait(in sigset_t*, int*);\n*/\n\nnothrow @nogc\n{\n\nversion (CRuntime_Glibc)\n{\n    enum SIG_HOLD = cast(sigfn_t2) 1;\n\n    private enum _SIGSET_NWORDS = 1024 / (8 * c_ulong.sizeof);\n\n    struct sigset_t\n    {\n        c_ulong[_SIGSET_NWORDS] __val;\n    }\n\n    // pid_t  (defined in core.sys.types)\n\n    //SIGABRT (defined in core.stdc.signal)\n    //SIGFPE  (defined in core.stdc.signal)\n    //SIGILL  (defined in core.stdc.signal)\n    //SIGINT  (defined in core.stdc.signal)\n    //SIGSEGV (defined in core.stdc.signal)\n    //SIGTERM (defined in core.stdc.signal)\n\n    enum SA_NOCLDSTOP   = 1; // (CX|XSI)\n\n    enum SIG_BLOCK      = 0;\n    enum SIG_UNBLOCK    = 1;\n    enum SIG_SETMASK    = 2;\n\n    private enum __SI_MAX_SIZE = 128;\n\n    static if ( __WORDSIZE == 64 )\n    {\n        private enum __SI_PAD_SIZE = ((__SI_MAX_SIZE / int.sizeof) - 4);\n    }\n    else\n    {\n        private enum __SI_PAD_SIZE = ((__SI_MAX_SIZE / int.sizeof) - 3);\n    }\n\n    struct siginfo_t\n    {\n        int si_signo;       // Signal number\n        int si_errno;       // If non-zero, an errno value associated with\n                            // this signal, as defined in <errno.h>\n        int si_code;        // Signal code\n\n        union _sifields_t\n        {\n            int[__SI_PAD_SIZE] _pad;\n\n            // kill()\n            struct _kill_t\n            {\n                pid_t si_pid; // Sending process ID\n                uid_t si_uid; // Real user ID of sending process\n            } _kill_t _kill;\n\n            // POSIX.1b timers.\n            struct _timer_t\n            {\n                int    si_tid;     // Timer ID\n                int    si_overrun; // Overrun count\n                sigval si_sigval;  // Signal value\n            } _timer_t _timer;\n\n            // POSIX.1b signals\n            struct _rt_t\n            {\n                pid_t  si_pid;    // Sending process ID\n                uid_t  si_uid;    // Real user ID of sending process\n                sigval si_sigval; // Signal value\n            } _rt_t _rt;\n\n            // SIGCHLD\n            struct _sigchild_t\n            {\n                pid_t   si_pid;    // Which child\n                uid_t   si_uid;    // Real user ID of sending process\n                int     si_status; // Exit value or signal\n                clock_t si_utime;\n                clock_t si_stime;\n            } _sigchild_t _sigchld;\n\n            // SIGILL, SIGFPE, SIGSEGV, SIGBUS\n            struct _sigfault_t\n            {\n                void*     si_addr;  // Faulting insn/memory ref\n            } _sigfault_t _sigfault;\n\n            // SIGPOLL\n            struct _sigpoll_t\n            {\n                c_long   si_band;   // Band event for SIGPOLL\n                int      si_fd;\n            } _sigpoll_t _sigpoll;\n        } _sifields_t _sifields;\n\n    nothrow @nogc:\n        @property ref pid_t si_pid() return { return _sifields._kill.si_pid; }\n        @property ref uid_t si_uid() return { return _sifields._kill.si_uid; }\n        @property ref void* si_addr() return { return _sifields._sigfault.si_addr; }\n        @property ref int si_status() return { return _sifields._sigchld.si_status; }\n        @property ref c_long si_band() return { return _sifields._sigpoll.si_band; }\n        @property ref sigval si_value() return { return _sifields._rt.si_sigval; }\n    }\n\n    enum\n    {\n        SI_ASYNCNL = -60,\n        SI_TKILL   = -6,\n        SI_SIGIO,\n        SI_ASYNCIO,\n        SI_MESGQ,\n        SI_TIMER,\n        SI_QUEUE,\n        SI_USER,\n        SI_KERNEL  = 0x80\n    }\n\n    int kill(pid_t, int);\n    int sigaction(int, in sigaction_t*, sigaction_t*);\n    int sigaddset(sigset_t*, int);\n    int sigdelset(sigset_t*, int);\n    int sigemptyset(sigset_t*);\n    int sigfillset(sigset_t*);\n    int sigismember(in sigset_t*, int);\n    int sigpending(sigset_t*);\n    int sigprocmask(int, in sigset_t*, sigset_t*);\n    int sigsuspend(in sigset_t*);\n    int sigwait(in sigset_t*, int*);\n}\nelse version (Darwin)\n{\n    enum SIG_HOLD = cast(sigfn_t2) 5;\n\n    alias uint sigset_t;\n    // pid_t  (defined in core.sys.types)\n\n    //SIGABRT (defined in core.stdc.signal)\n    //SIGFPE  (defined in core.stdc.signal)\n    //SIGILL  (defined in core.stdc.signal)\n    //SIGINT  (defined in core.stdc.signal)\n    //SIGSEGV (defined in core.stdc.signal)\n    //SIGTERM (defined in core.stdc.signal)\n\n    enum SA_NOCLDSTOP = 8; // (CX|XSI)\n\n    enum SIG_BLOCK   = 1;\n    enum SIG_UNBLOCK = 2;\n    enum SIG_SETMASK = 3;\n\n    struct siginfo_t\n    {\n        int     si_signo;\n        int     si_errno;\n        int     si_code;\n        pid_t   si_pid;\n        uid_t   si_uid;\n        int     si_status;\n        void*   si_addr;\n        sigval  si_value;\n        int     si_band;\n        uint[7] pad;\n    }\n\n    enum SI_USER    = 0x10001;\n    enum SI_QUEUE   = 0x10002;\n    enum SI_TIMER   = 0x10003;\n    enum SI_ASYNCIO = 0x10004;\n    enum SI_MESGQ   = 0x10005;\n\n    int kill(pid_t, int);\n    int sigaction(int, in sigaction_t*, sigaction_t*);\n    int sigaddset(sigset_t*, int);\n    int sigdelset(sigset_t*, int);\n    int sigemptyset(sigset_t*);\n    int sigfillset(sigset_t*);\n    int sigismember(in sigset_t*, int);\n    int sigpending(sigset_t*);\n    int sigprocmask(int, in sigset_t*, sigset_t*);\n    int sigsuspend(in sigset_t*);\n    int sigwait(in sigset_t*, int*);\n}\nelse version (FreeBSD)\n{\n    enum SIG_HOLD = cast(sigfn_t2) 3;\n\n    struct sigset_t\n    {\n        uint[4] __bits;\n    }\n\n    enum SA_NOCLDSTOP = 8;\n\n    enum SIG_BLOCK = 1;\n    enum SIG_UNBLOCK = 2;\n    enum SIG_SETMASK = 3;\n\n    struct siginfo_t\n    {\n        int si_signo;\n        int si_errno;\n        int si_code;\n        pid_t si_pid;\n        uid_t si_uid;\n        int si_status;\n        void* si_addr;\n        sigval si_value;\n        union __reason\n        {\n            struct __fault\n            {\n                int _trapno;\n            }\n            __fault _fault;\n            struct __timer\n            {\n                int _timerid;\n                int _overrun;\n            }\n            __timer _timer;\n            struct __mesgq\n            {\n                int _mqd;\n            }\n            __mesgq _mesgq;\n            struct __poll\n            {\n                c_long _band;\n            }\n            __poll _poll;\n            struct ___spare___\n            {\n                c_long __spare1__;\n                int[7] __spare2__;\n            }\n            ___spare___ __spare__;\n        }\n        __reason _reason;\n\n        @property ref c_long si_band() return { return _reason._poll._band; }\n    }\n\n    enum SI_USER    = 0x10001;\n    enum SI_QUEUE   = 0x10002;\n    enum SI_TIMER   = 0x10003;\n    enum SI_ASYNCIO = 0x10004;\n    enum SI_MESGQ   = 0x10005;\n\n    int kill(pid_t, int);\n    int sigaction(int, in sigaction_t*, sigaction_t*);\n    int sigaddset(sigset_t*, int);\n    int sigdelset(sigset_t*, int);\n    int sigemptyset(sigset_t *);\n    int sigfillset(sigset_t *);\n    int sigismember(in sigset_t *, int);\n    int sigpending(sigset_t *);\n    int sigprocmask(int, in sigset_t*, sigset_t*);\n    int sigsuspend(in sigset_t *);\n    int sigwait(in sigset_t*, int*);\n}\nelse version (NetBSD)\n{\n    enum SIG_HOLD = cast(sigfn_t2) 3;\n\n    struct sigset_t\n    {\n        uint[4] __bits;\n    }\n\n    enum SA_NOCLDSTOP = 8;\n\n    enum SIG_BLOCK = 1;\n    enum SIG_UNBLOCK = 2;\n    enum SIG_SETMASK = 3;\n\n    union sigval_t {\n        int     sival_int;\n        void    *sival_ptr;\n    };\n    struct _rt{\n        pid_t   _pid;\n        uid_t   _uid;\n        sigval_t        _value;\n    };\n    struct _child{\n        pid_t   _pid;\n        uid_t   _uid;\n        int     _status;\n        clock_t _utime;\n        clock_t _stime;\n    };\n   struct _fault{\n        void   *_addr;\n        int     _trap;\n        int     _trap2;\n        int     _trap3;\n    };\n    struct _poll{\n        long    _band;\n        int     _fd;\n    };\n    union _reason{\n        _rt rt;\n        _child child;\n        _fault fault;\n        _poll poll;\n    };\n    struct _ksiginfo {\n        int     _signo;\n        int     _code;\n        int     _errno;\n/+#ifdef _LP64\n        /* In _LP64 the union starts on an 8-byte boundary. */\n        int     _pad;\n#endif+/\n        _reason reason;\n    };\n\n\n    union siginfo_t\n    {\n        ubyte[128] si_pad;/* Total size; for future expansion */\n        _ksiginfo _info;\n        @property ref c_long si_band() return { return _info.reason.poll._band; }\n    }\n\n    enum SI_USER    = 0;\n    enum SI_QUEUE   = -1;\n    enum SI_TIMER   = -2;\n    enum SI_ASYNCIO = -3;\n    enum SI_MESGQ   = -4;\n\n    int kill(pid_t, int);\n    int __sigaction14(int, in sigaction_t*, sigaction_t*);\n    int __sigaddset14(sigset_t*, int);\n    int __sigdelset14(sigset_t*, int);\n    int __sigemptyset14(sigset_t *);\n    int __sigfillset14(sigset_t *);\n    int __sigismember14(in sigset_t *, int);\n    int __sigpending14(sigset_t *);\n    int __sigprocmask14(int, in sigset_t*, sigset_t*);\n    int __sigsuspend14(in sigset_t *);\n    int sigwait(in sigset_t*, int*);\n\n    alias __sigaction14 sigaction;\n    alias __sigaddset14 sigaddset;\n    alias __sigdelset14 sigdelset;\n    alias __sigemptyset14 sigemptyset;\n    alias __sigfillset14 sigfillset;\n    alias __sigismember14 sigismember;\n    alias __sigpending14 sigpending;\n    alias __sigprocmask14 sigprocmask;\n    alias __sigsuspend14 sigsuspend;\n}\nelse version (OpenBSD)\n{\n    enum SIG_CATCH = cast(sigfn_t2) 2;\n    enum SIG_HOLD = cast(sigfn_t2) 3;\n\n    alias sigset_t = uint;\n\n    enum SA_NOCLDSTOP = 0x0008;\n\n    enum SIG_BLOCK = 1;\n    enum SIG_UNBLOCK = 2;\n    enum SIG_SETMASK = 3;\n\n    private enum SI_MAXSZ = 128;\n    private enum SI_PAD = (SI_MAXSZ / int.sizeof) - 3;\n\n    struct siginfo_t\n    {\n        int si_signo;\n        int si_errno;\n        int si_code;\n        union _data\n        {\n            int[SI_PAD] _pad;\n            struct _proc\n            {\n                pid_t _pid;\n                union _pdata\n                {\n                    struct _kill\n                    {\n                        uid_t _uid;\n                        sigval _value;\n                    }\n                    struct _cld\n                    {\n                        clock_t _utime;\n                        clock_t _stime;\n                        int _status;\n                    }\n                }\n            }\n            struct _fault\n            {\n                caddr_t _addr;\n                int _trapno;\n            }\n        }\n        alias si_pid     = _data._proc._pid;\n        alias si_status  = _data._proc._pdata._cld._status;\n        alias si_stime   = _data._proc._pdata._cld._stime;\n        alias si_utime   = _data._proc._pdata._cld._utime;\n        alias si_uid     = _data._proc._pdata._kill._uid;\n        alias si_value   = _data._proc._pdata._kill._value;\n        alias si_addr    = _data._fault._addr;\n        alias si_trapno  = _data._fault._trapno;\n    }\n\n    enum SI_NOINFO = 32767;\n    enum SI_USER   = 0;\n    enum SI_LWP    = -1;\n    enum SI_QUEUE  = -2;\n    enum SI_TIMER  = -3;\n\n    int kill(pid_t, int);\n    int sigaction(int, in sigaction_t*, sigaction_t*);\n    int sigaddset(sigset_t*, int);\n    int sigdelset(sigset_t*, int);\n    int sigemptyset(sigset_t *);\n    int sigfillset(sigset_t *);\n    int sigismember(in sigset_t *, int);\n    int sigpending(sigset_t *);\n    int sigprocmask(int, in sigset_t*, sigset_t*);\n    int sigsuspend(in sigset_t *);\n    int sigwait(in sigset_t*, int*);\n}\nelse version (DragonFlyBSD)\n{\n    enum SIG_CATCH = cast(sigfn_t2) 2;\n    enum SIG_HOLD = cast(sigfn_t2) 3;\n\n    struct sigset_t\n    {\n        uint[4] __bits;\n    }\n\n    enum SA_NOCLDSTOP = 8;\n\n    enum SIG_BLOCK = 1;\n    enum SIG_UNBLOCK = 2;\n    enum SIG_SETMASK = 3;\n\n    struct siginfo_t\n    {\n        int si_signo;\n        int si_errno;\n        int si_code;\n        int si_pid;\n        uint si_uid;\n        int si_status;\n        void* si_addr;\n        sigval si_value;\n        c_long si_band;\n        int[7]   __spare;\n    }\n\n    enum SI_UNDEFINED = 0x00000;\n    enum SI_USER      =  0;\n    enum SI_QUEUE     = -1;\n    enum SI_TIMER     = -2;\n    enum SI_ASYNCIO   = -3;\n    enum SI_MESGQ     = -4;\n\n    int kill(pid_t, int);\n    int sigaction(int, in sigaction_t*, sigaction_t*);\n    int sigaddset(sigset_t*, int);\n    int sigdelset(sigset_t*, int);\n    int sigemptyset(sigset_t *);\n    int sigfillset(sigset_t *);\n    int sigismember(in sigset_t *, int);\n    int sigpending(sigset_t *);\n    int sigprocmask(int, in sigset_t*, sigset_t*);\n    int sigsuspend(in sigset_t *);\n    int sigwait(in sigset_t*, int*);\n}\nelse version (Solaris)\n{\n    enum SIG_HOLD = cast(sigfn_t2)2;\n\n    struct sigset_t\n    {\n        uint[4] __bits;\n    }\n\n    struct siginfo_t\n    {\n        int si_signo;\n        int si_code;\n        int si_errno;\n\n        version (D_LP64)\n            int si_pad;\n\n        union ___data\n        {\n            version (D_LP64)\n                int[(256 / int.sizeof) - 4] si_pad;\n            else\n                int[(128 / int.sizeof) - 3] si_pad;\n\n            struct ___proc\n            {\n                pid_t __pid;\n\n                union ___pdata\n                {\n                    struct ___kill\n                    {\n                        uid_t __uid;\n                        sigval __value;\n                    }\n\n                    ___kill __kill;\n\n                    struct ___cld\n                    {\n                        clock_t __utime;\n                        int __status;\n                        clock_t __stime;\n                    }\n\n                    ___cld __cld;\n                }\n\n                ___pdata __pdata;\n                ctid_t __ctid;\n                zoneid_t __zoneid;\n            }\n\n            ___proc __proc;\n\n            struct ___fault\n            {\n                void* __addr;\n                int __trapno;\n                caddr_t __pc;\n            }\n\n            ___fault __fault;\n\n            struct ___file\n            {\n                int __fd;\n                c_long __band;\n            }\n\n            ___file __file;\n\n            struct ___prof\n            {\n                caddr_t __faddr;\n                timestruc_t __tstamp;\n                short __syscall;\n                char __nsysarg;\n                char __fault;\n                c_long[8] __sysarg;\n                int[10] __mstate;\n            }\n\n            ___prof __prof;\n\n            struct ___rctl\n            {\n                int __entity;\n            }\n\n            ___rctl __rctl;\n        }\n\n        ___data __data;\n    }\n\n    int kill(pid_t, int);\n    int sigaction(int, in sigaction_t*, sigaction_t*);\n    int sigaddset(sigset_t*, int);\n    int sigdelset(sigset_t*, int);\n    int sigemptyset(sigset_t*);\n    int sigfillset(sigset_t*);\n    int sigismember(in sigset_t*, int);\n    int sigpending(sigset_t*);\n    int sigprocmask(int, in sigset_t*, sigset_t*);\n    int sigsuspend(in sigset_t*);\n    int sigwait(in sigset_t*, int*);\n}\nelse version (CRuntime_Bionic)\n{\n    public import core.sys.posix.time: timer_t;\n    private import core.stdc.string : memset;\n\n    version (X86)\n    {\n        alias c_ulong sigset_t;\n        enum int LONG_BIT = 32;\n    }\n    else version (ARM)\n    {\n        alias c_ulong sigset_t;\n        enum int LONG_BIT = 32;\n    }\n    else version (AArch64)\n    {\n        struct sigset_t { ulong[1] sig; }\n        enum int LONG_BIT = 64;\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n\n    enum SIG_BLOCK   = 0;\n    enum SIG_UNBLOCK = 1;\n    enum SIG_SETMASK = 2;\n\n    private enum SI_MAX_SIZE = 128;\n    private enum SI_PAD_SIZE = ((SI_MAX_SIZE / int.sizeof) - 3);\n\n    struct siginfo_t\n    {\n        int si_signo;\n        int si_errno;\n        int si_code;\n\n        union _sifields_t\n        {\n            int[SI_PAD_SIZE] _pad;\n\n            struct _kill_t\n            {\n                pid_t _pid;\n                uid_t _uid;\n            } _kill_t _kill;\n\n            struct _timer_t\n            {\n                timer_t _tid;\n                int     _overrun;\n                sigval  _sigval;\n                int     _sys_private;\n            } _timer_t _timer;\n\n            struct _rt_t\n            {\n                pid_t  _pid;\n                uid_t  _uid;\n                sigval _sigval;\n            } _rt_t _rt;\n\n            struct _sigchild_t\n            {\n                pid_t   _pid;\n                uid_t   _uid;\n                int     _status;\n                clock_t _utime;\n                clock_t _stime;\n            } _sigchild_t _sigchld;\n\n            struct _sigfault_t\n            {\n                void*   _addr;\n            } _sigfault_t _sigfault;\n\n            struct _sigpoll_t\n            {\n                c_long _band;\n                int    _fd;\n            } _sigpoll_t _sigpoll;\n        } _sifields_t _sifields;\n    }\n\n    enum\n    {\n        SI_TKILL   = -6,\n        SI_SIGIO,\n        SI_ASYNCIO,\n        SI_MESGQ,\n        SI_TIMER,\n        SI_QUEUE,\n        SI_USER,\n        SI_KERNEL  = 0x80\n    }\n\n    int kill(pid_t, int);\n    int sigaction(int, in sigaction_t*, sigaction_t*);\n\n    // These functions are defined inline in bionic.\n    int sigaddset(sigset_t* set, int signum)\n    {\n        c_ulong* local_set = cast(c_ulong*) set;\n        signum--;\n        local_set[signum/LONG_BIT] |= 1UL << (signum%LONG_BIT);\n        return 0;\n    }\n\n    int sigdelset(sigset_t* set, int signum)\n    {\n        c_ulong* local_set = cast(c_ulong*) set;\n        signum--;\n        local_set[signum/LONG_BIT] &= ~(1UL << (signum%LONG_BIT));\n        return 0;\n    }\n\n    int sigemptyset(sigset_t* set) { memset(set, 0, (*set).sizeof); return 0; }\n\n    int sigfillset(sigset_t* set) { memset(set, ~0, (*set).sizeof); return 0; }\n\n    int sigismember(sigset_t* set, int signum)\n    {\n        c_ulong* local_set = cast(c_ulong*) set;\n        signum--;\n        return cast(int) ((local_set[signum/LONG_BIT] >> (signum%LONG_BIT)) & 1);\n    }\n\n    int sigpending(sigset_t*);\n    int sigprocmask(int, in sigset_t*, sigset_t*);\n    int sigsuspend(in sigset_t*);\n    int sigwait(in sigset_t*, int*);\n}\nelse version (CRuntime_Musl)\n{\n    struct sigset_t {\n        ulong[128/long.sizeof] __bits;\n    }\n\n    enum SIG_BLOCK      = 0;\n    enum SIG_UNBLOCK    = 1;\n    enum SIG_SETMASK    = 2;\n\n    struct siginfo_t {\n        int si_signo, si_errno, si_code;\n        union __si_fields_t {\n            char[128 - 2*int.sizeof - long.sizeof] __pad;\n            struct __si_common_t {\n                union __first_t {\n                    struct __piduid_t {\n                        pid_t si_pid;\n                        uid_t si_uid;\n                    }\n                    __piduid_t __piduid;\n\n                    struct __timer_t {\n                        int si_timerid;\n                        int si_overrun;\n                    }\n                    __timer_t __timer;\n                }\n                __first_t __first;\n\n                union __second_t {\n                    sigval si_value;\n                    struct __sigchld_t {\n                        int si_status;\n                        clock_t si_utime, si_stime;\n                    }\n                    __sigchld_t __sigchld;\n                }\n                __second_t __second;\n            }\n            __si_common_t __si_common;\n\n            struct __sigfault_t {\n                void *si_addr;\n                short si_addr_lsb;\n                union __first_t {\n                    struct __addr_bnd_t {\n                        void *si_lower;\n                        void *si_upper;\n                    }\n                    __addr_bnd_t __addr_bnd;\n                    uint si_pkey;\n                }\n                __first_t __first;\n            }\n            __sigfault_t __sigfault;\n\n            struct __sigpoll_t {\n                long si_band;\n                int si_fd;\n            }\n            __sigpoll_t __sigpoll;\n\n            struct __sigsys_t {\n                void *si_call_addr;\n                int si_syscall;\n                uint si_arch;\n            }\n            __sigsys_t __sigsys;\n        }\n        __si_fields_t __si_fields;\n    }\n\n    int kill(pid_t, int);\n    int sigaction(int, in sigaction_t*, sigaction_t*);\n    int sigaddset(sigset_t*, int);\n    int sigdelset(sigset_t*, int);\n    int sigemptyset(sigset_t*);\n    int sigfillset(sigset_t*);\n    int sigismember(in sigset_t*, int);\n    int sigpending(sigset_t*);\n    int sigprocmask(int, in sigset_t*, sigset_t*);\n    int sigsuspend(in sigset_t*);\n    int sigwait(in sigset_t*, int*);\n}\nelse version (CRuntime_UClibc)\n{\n    enum SIG_HOLD = cast(sigfn_t2) 2;\n\n    version (MIPS32)\n        private enum _SIGSET_NWORDS = 128 / (8 * c_ulong.sizeof);\n    else\n        private enum _SIGSET_NWORDS = 64 / (8 * c_ulong.sizeof);\n\n    struct sigset_t\n    {\n        c_ulong[_SIGSET_NWORDS] __val;\n    }\n\n    enum SA_NOCLDSTOP   = 1;\n\n    enum SIG_BLOCK      = 0;\n    enum SIG_UNBLOCK    = 1;\n    enum SIG_SETMASK    = 2;\n\n    private enum __SI_MAX_SIZE = 128;\n\n    static if ( __WORDSIZE == 64 )\n    {\n        private enum __SI_PAD_SIZE = ((__SI_MAX_SIZE / int.sizeof) - 4);\n    }\n    else\n    {\n        private enum __SI_PAD_SIZE = ((__SI_MAX_SIZE / int.sizeof) - 3);\n    }\n\n    version (ARM)           version = siginfo_common;\n    else version (X86_64)   version = siginfo_common;\n\n    version (siginfo_common)\n    {\n        struct siginfo_t\n        {\n            int si_signo;       // Signal number\n            int si_errno;       // If non-zero, an errno value associated with\n                                // this signal, as defined in <errno.h>\n            int si_code;        // Signal code\n\n            union _sifields_t\n            {\n                int[__SI_PAD_SIZE] _pad;\n\n                // kill()\n                struct _kill_t\n                {\n                    pid_t si_pid; // Sending process ID\n                    uid_t si_uid; // Real user ID of sending process\n                } _kill_t _kill;\n\n                // POSIX.1b timers.\n                struct _timer_t\n                {\n                    int    si_tid;     // Timer ID\n                    int    si_overrun; // Overrun count\n                    sigval si_sigval;  // Signal value\n                } _timer_t _timer;\n\n                // POSIX.1b signals\n                struct _rt_t\n                {\n                    pid_t  si_pid;    // Sending process ID\n                    uid_t  si_uid;    // Real user ID of sending process\n                    sigval si_sigval; // Signal value\n                } _rt_t _rt;\n\n                // SIGCHLD\n                struct _sigchild_t\n                {\n                    pid_t   si_pid;    // Which child\n                    uid_t   si_uid;    // Real user ID of sending process\n                    int     si_status; // Exit value or signal\n                    clock_t si_utime;\n                    clock_t si_stime;\n                } _sigchild_t _sigchld;\n\n                // SIGILL, SIGFPE, SIGSEGV, SIGBUS\n                struct _sigfault_t\n                {\n                    void*     si_addr;  // Faulting insn/memory ref\n                } _sigfault_t _sigfault;\n\n                // SIGPOLL\n                struct _sigpoll_t\n                {\n                    c_long si_band; // Band event for SIGPOLL;\n                    int      si_fd;\n                } _sigpoll_t _sigpoll;\n\n                // SIGSYS\n                struct _sigsys_t\n                {\n                    void*   _call_addr;   // Calling user insn.\n                    int     _syscall;     // Triggering system call number.\n                    uint    _arch;        // AUDIT_ARCH_* of syscall.\n                } _sigsys_t _sigsys;\n\n            } _sifields_t _sifields;\n\n        nothrow @nogc:\n            @property ref pid_t si_pid()() { return _sifields._kill.si_pid; }\n            @property ref uid_t si_uid()() { return _sifields._kill.si_uid; }\n            @property ref int si_timerid()() { return _sifields._timer.si_tid;}\n            @property ref int si_overrun()() { return _sifields._timer.si_overrun; }\n            @property ref int si_status()() { return _sifields._sigchld.si_status; }\n            @property ref clock_t si_utime()() { return _sifields._sigchld.si_utime; }\n            @property ref clock_t si_stime()() { return _sifields._sigchld.si_stime; }\n            @property ref sigval si_value()() { return _sifields._rt.si_sigval; }\n            @property ref int si_int()() { return _sifields._rt.si_sigval.sival_int; }\n            @property ref void* si_ptr()() { return _sifields._rt.si_sigval.sival_ptr; }\n            @property ref void* si_addr()() { return _sifields._sigfault.si_addr; }\n            @property ref c_long si_band()() { return _sifields._sigpoll.si_band; }\n            @property ref int  si_fd()() { return _sifields._sigpoll.si_fd; }\n            @property ref void*  si_call_addr()() { return _sifields._sigsys._call_addr; }\n            @property ref int  si_syscall()() { return _sifields._sigsys._syscall; }\n            @property ref uint  si_arch()() { return _sifields._sigsys._arch; }\n        }\n    }\n    else version (MIPS32)\n    {\n        struct siginfo_t\n        {\n            int si_signo;       // Signal number\n            int si_errno;       // If non-zero, an errno value associated with\n                                // this signal, as defined in <errno.h>\n            int si_code;        // Signal code\n\n            int[__SI_MAX_SIZE / int.sizeof - __SI_PAD_SIZE - 3] __pad0;\n\n            union _sifields_t\n            {\n                int[__SI_PAD_SIZE] _pad;\n\n                // kill()\n                struct _kill_t\n                {\n                    pid_t si_pid; // Sending process ID\n                    uid_t si_uid; // Real user ID of sending process\n                } _kill_t _kill;\n\n                // POSIX.1b timers.\n                struct _timer_t\n                {\n                    int    si_tid;     // Timer ID\n                    int    si_overrun; // Overrun count\n                    sigval si_sigval;  // Signal value\n                } _timer_t _timer;\n\n                // POSIX.1b signals\n                struct _rt_t\n                {\n                    pid_t  si_pid;    // Sending process ID\n                    uid_t  si_uid;    // Real user ID of sending process\n                    sigval si_sigval; // Signal value\n                } _rt_t _rt;\n\n                // SIGCHLD\n                struct _sigchild_t\n                {\n                    pid_t   si_pid;    // Which child\n                    uid_t   si_uid;    // Real user ID of sending process\n                    int     si_status; // Exit value or signal\n                    clock_t si_utime;\n                    clock_t si_stime;\n                } _sigchild_t _sigchld;\n\n                // SIGILL, SIGFPE, SIGSEGV, SIGBUS\n                struct _sigfault_t\n                {\n                    void*   si_addr;  // Faulting insn/memory ref\n                    short   si_addr_lsb;\n                } _sigfault_t _sigfault;\n\n                // SIGPOLL\n                struct _sigpoll_t\n                {\n                    c_long si_band; // Band event for SIGPOLL;\n                    int      si_fd;\n                } _sigpoll_t _sigpoll;\n\n                // SIGSYS\n                struct _sigsys_t\n                {\n                    void*   _call_addr;   // Calling user insn.\n                    int     _syscall;     // Triggering system call number.\n                    uint    _arch;        // AUDIT_ARCH_* of syscall.\n                } _sigsys_t _sigsys;\n\n            } _sifields_t _sifields;\n\n        nothrow @nogc:\n            @property ref pid_t si_pid()() { return _sifields._kill.si_pid; }\n            @property ref uid_t si_uid()() { return _sifields._kill.si_uid; }\n            @property ref int si_timerid()() { return _sifields._timer.si_tid;}\n            @property ref int si_overrun()() { return _sifields._timer.si_overrun; }\n            @property ref int si_status()() { return _sifields._sigchld.si_status; }\n            @property ref clock_t si_utime()() { return _sifields._sigchld.si_utime; }\n            @property ref clock_t si_stime()() { return _sifields._sigchld.si_stime; }\n            @property ref sigval si_value()() { return _sifields._rt.si_sigval; }\n            @property ref int si_int()() { return _sifields._rt.si_sigval.sival_int; }\n            @property ref void* si_ptr()() { return _sifields._rt.si_sigval.sival_ptr; }\n            @property ref void* si_addr()() { return _sifields._sigfault.si_addr; }\n            @property ref c_long si_band()() { return _sifields._sigpoll.si_band; }\n            @property ref int  si_fd()() { return _sifields._sigpoll.si_fd; }\n            @property ref void*  si_call_addr()() { return _sifields._sigsys._call_addr; }\n            @property ref int  si_syscall()() { return _sifields._sigsys._syscall; }\n            @property ref uint  si_arch()() { return _sifields._sigsys._arch; }\n        }\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n\n    enum\n    {\n        SI_ASYNCNL = -60,\n        SI_TKILL   = -6,\n        SI_SIGIO,\n        SI_ASYNCIO,\n        SI_MESGQ,\n        SI_TIMER,\n        SI_QUEUE,\n        SI_USER,\n        SI_KERNEL  = 0x80\n    }\n\n    int kill(pid_t, int);\n    int sigaction(int, in sigaction_t*, sigaction_t*);\n    int sigaddset(sigset_t*, int);\n    int sigdelset(sigset_t*, int);\n    int sigemptyset(sigset_t*);\n    int sigfillset(sigset_t*);\n    int sigismember(in sigset_t*, int);\n    int sigpending(sigset_t*);\n    int sigprocmask(int, in sigset_t*, sigset_t*);\n    int sigsuspend(in sigset_t*);\n    int sigwait(in sigset_t*, int*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n}\n\n//\n// XOpen (XSI)\n//\n/*\nSIGPOLL\nSIGPROF\nSIGSYS\nSIGTRAP\nSIGVTALRM\nSIGXCPU\nSIGXFSZ\n\nSA_ONSTACK\nSA_RESETHAND\nSA_RESTART\nSA_SIGINFO\nSA_NOCLDWAIT\nSA_NODEFER\nSS_ONSTACK\nSS_DISABLE\nMINSIGSTKSZ\nSIGSTKSZ\n\nucontext_t // from ucontext\nmcontext_t // from ucontext\n\nstruct stack_t\n{\n    void*   ss_sp;\n    size_t  ss_size;\n    int     ss_flags;\n}\n\nstruct sigstack\n{\n    int   ss_onstack;\n    void* ss_sp;\n}\n\nILL_ILLOPC\nILL_ILLOPN\nILL_ILLADR\nILL_ILLTRP\nILL_PRVOPC\nILL_PRVREG\nILL_COPROC\nILL_BADSTK\n\nFPE_INTDIV\nFPE_INTOVF\nFPE_FLTDIV\nFPE_FLTOVF\nFPE_FLTUND\nFPE_FLTRES\nFPE_FLTINV\nFPE_FLTSUB\n\nSEGV_MAPERR\nSEGV_ACCERR\n\nBUS_ADRALN\nBUS_ADRERR\nBUS_OBJERR\n\nTRAP_BRKPT\nTRAP_TRACE\n\nCLD_EXITED\nCLD_KILLED\nCLD_DUMPED\nCLD_TRAPPED\nCLD_STOPPED\nCLD_CONTINUED\n\nPOLL_IN\nPOLL_OUT\nPOLL_MSG\nPOLL_ERR\nPOLL_PRI\nPOLL_HUP\n\nsigfn_t bsd_signal(int sig, sigfn_t func);\nsigfn_t sigset(int sig, sigfn_t func);\n\nint killpg(pid_t, int);\nint sigaltstack(in stack_t*, stack_t*);\nint sighold(int);\nint sigignore(int);\nint siginterrupt(int, int);\nint sigpause(int);\nint sigrelse(int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    version (X86)\n    {\n        enum SIGPOLL        = 29;\n        enum SIGPROF        = 27;\n        enum SIGSYS         = 31;\n        enum SIGTRAP        = 5;\n        enum SIGVTALRM      = 26;\n        enum SIGXCPU        = 24;\n        enum SIGXFSZ        = 25;\n    }\n    else version (X86_64)\n    {\n        enum SIGPOLL        = 29;\n        enum SIGPROF        = 27;\n        enum SIGSYS         = 31;\n        enum SIGTRAP        = 5;\n        enum SIGVTALRM      = 26;\n        enum SIGXCPU        = 24;\n        enum SIGXFSZ        = 25;\n    }\n    else version (MIPS32)\n    {\n        enum SIGPOLL    = 22;\n        enum SIGPROF    = 29;\n        enum SIGSYS     = 12;\n        enum SIGTRAP    = 5;\n        enum SIGVTALRM  = 28;\n        enum SIGXCPU    = 30;\n        enum SIGXFSZ    = 31;\n    }\n    else version (MIPS64)\n    {\n        enum SIGPOLL    = 22;\n        enum SIGPROF    = 29;\n        enum SIGSYS     = 12;\n        enum SIGTRAP    = 5;\n        enum SIGVTALRM  = 28;\n        enum SIGXCPU    = 30;\n        enum SIGXFSZ    = 31;\n    }\n    else version (PPC)\n    {\n        enum SIGPOLL    = 29;\n        enum SIGPROF    = 27;\n        enum SIGSYS     = 31;\n        enum SIGTRAP    = 5;\n        enum SIGVTALRM  = 26;\n        enum SIGXCPU    = 24;\n        enum SIGXFSZ    = 25;\n    }\n    else version (PPC64)\n    {\n        enum SIGPOLL    = 29;\n        enum SIGPROF    = 27;\n        enum SIGSYS     = 31;\n        enum SIGTRAP    = 5;\n        enum SIGVTALRM  = 26;\n        enum SIGXCPU    = 24;\n        enum SIGXFSZ    = 25;\n    }\n    else version (ARM)\n    {\n        enum SIGPOLL    = 29;\n        enum SIGPROF    = 27;\n        enum SIGSYS     = 31;\n        enum SIGTRAP    = 5;\n        enum SIGVTALRM  = 26;\n        enum SIGXCPU    = 24;\n        enum SIGXFSZ    = 25;\n    }\n    else version (AArch64)\n    {\n        enum SIGPOLL    = 29;\n        enum SIGPROF    = 27;\n        enum SIGSYS     = 31;\n        enum SIGTRAP    = 5;\n        enum SIGVTALRM  = 26;\n        enum SIGXCPU    = 24;\n        enum SIGXFSZ    = 25;\n    }\n    else version (SPARC64)\n    {\n        enum SIGPOLL    = 23;\n        enum SIGPROF    = 27;\n        enum SIGSYS     = 12;\n        enum SIGTRAP    = 5;\n        enum SIGVTALRM  = 26;\n        enum SIGXCPU    = 24;\n        enum SIGXFSZ    = 25;\n    }\n    else version (SystemZ)\n    {\n        enum SIGPOLL    = 29;\n        enum SIGPROF    = 27;\n        enum SIGSYS     = 31;\n        enum SIGTRAP    = 5;\n        enum SIGVTALRM  = 26;\n        enum SIGXCPU    = 24;\n        enum SIGXFSZ    = 25;\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    enum SA_ONSTACK     = 0x08000000;\n    enum SA_RESETHAND   = 0x80000000;\n    enum SA_RESTART     = 0x10000000;\n    enum SA_SIGINFO     = 4;\n    enum SA_NOCLDWAIT   = 2;\n    enum SA_NODEFER     = 0x40000000;\n    enum SS_ONSTACK     = 1;\n    enum SS_DISABLE     = 2;\n    enum MINSIGSTKSZ    = 2048;\n    enum SIGSTKSZ       = 8192;\n\n    //ucontext_t (defined in core.sys.posix.ucontext)\n    //mcontext_t (defined in core.sys.posix.ucontext)\n\n    struct stack_t\n    {\n        void*   ss_sp;\n        int     ss_flags;\n        size_t  ss_size;\n    }\n\n    struct sigstack\n    {\n        void*   ss_sp;\n        int     ss_onstack;\n    }\n\n    enum\n    {\n        ILL_ILLOPC = 1,\n        ILL_ILLOPN,\n        ILL_ILLADR,\n        ILL_ILLTRP,\n        ILL_PRVOPC,\n        ILL_PRVREG,\n        ILL_COPROC,\n        ILL_BADSTK\n    }\n\n    enum\n    {\n        FPE_INTDIV = 1,\n        FPE_INTOVF,\n        FPE_FLTDIV,\n        FPE_FLTOVF,\n        FPE_FLTUND,\n        FPE_FLTRES,\n        FPE_FLTINV,\n        FPE_FLTSUB\n    }\n\n    enum\n    {\n        SEGV_MAPERR = 1,\n        SEGV_ACCERR\n    }\n\n    enum\n    {\n        BUS_ADRALN = 1,\n        BUS_ADRERR,\n        BUS_OBJERR\n    }\n\n    enum\n    {\n        TRAP_BRKPT = 1,\n        TRAP_TRACE\n    }\n\n    enum\n    {\n        CLD_EXITED = 1,\n        CLD_KILLED,\n        CLD_DUMPED,\n        CLD_TRAPPED,\n        CLD_STOPPED,\n        CLD_CONTINUED\n    }\n\n    enum\n    {\n        POLL_IN = 1,\n        POLL_OUT,\n        POLL_MSG,\n        POLL_ERR,\n        POLL_PRI,\n        POLL_HUP\n    }\n\n    sigfn_t bsd_signal(int sig, sigfn_t func);\n    sigfn_t sigset(int sig, sigfn_t func);\n\n  nothrow:\n  @nogc:\n    sigfn_t2 bsd_signal(int sig, sigfn_t2 func);\n    sigfn_t2 sigset(int sig, sigfn_t2 func);\n\n    int killpg(pid_t, int);\n    int sigaltstack(in stack_t*, stack_t*);\n    int sighold(int);\n    int sigignore(int);\n    int siginterrupt(int, int);\n    int sigpause(int);\n    int sigrelse(int);\n}\nelse version (Darwin)\n{\n    enum SIGPOLL        = 7;\n    enum SIGPROF        = 27;\n    enum SIGSYS         = 12;\n    enum SIGTRAP        = 5;\n    enum SIGVTALRM      = 26;\n    enum SIGXCPU        = 24;\n    enum SIGXFSZ        = 25;\n\n    enum SA_ONSTACK     = 0x0001;\n    enum SA_RESETHAND   = 0x0004;\n    enum SA_RESTART     = 0x0002;\n    enum SA_SIGINFO     = 0x0040;\n    enum SA_NOCLDWAIT   = 0x0020;\n    enum SA_NODEFER     = 0x0010;\n    enum SS_ONSTACK     = 0x0001;\n    enum SS_DISABLE     = 0x0004;\n    enum MINSIGSTKSZ    = 32768;\n    enum SIGSTKSZ       = 131072;\n\n    //ucontext_t (defined in core.sys.posix.ucontext)\n    //mcontext_t (defined in core.sys.posix.ucontext)\n\n    struct stack_t\n    {\n        void*   ss_sp;\n        size_t  ss_size;\n        int     ss_flags;\n    }\n\n    struct sigstack\n    {\n        void*   ss_sp;\n        int     ss_onstack;\n    }\n\n    enum ILL_ILLOPC = 1;\n    enum ILL_ILLOPN = 4;\n    enum ILL_ILLADR = 5;\n    enum ILL_ILLTRP = 2;\n    enum ILL_PRVOPC = 3;\n    enum ILL_PRVREG = 6;\n    enum ILL_COPROC = 7;\n    enum ILL_BADSTK = 8;\n\n    enum FPE_INTDIV = 7;\n    enum FPE_INTOVF = 8;\n    enum FPE_FLTDIV = 1;\n    enum FPE_FLTOVF = 2;\n    enum FPE_FLTUND = 3;\n    enum FPE_FLTRES = 4;\n    enum FPE_FLTINV = 5;\n    enum FPE_FLTSUB = 6;\n\n    enum\n    {\n        SEGV_MAPERR = 1,\n        SEGV_ACCERR\n    }\n\n    enum\n    {\n        BUS_ADRALN = 1,\n        BUS_ADRERR,\n        BUS_OBJERR\n    }\n\n    enum\n    {\n        TRAP_BRKPT = 1,\n        TRAP_TRACE\n    }\n\n    enum\n    {\n        CLD_EXITED = 1,\n        CLD_KILLED,\n        CLD_DUMPED,\n        CLD_TRAPPED,\n        CLD_STOPPED,\n        CLD_CONTINUED\n    }\n\n    enum\n    {\n        POLL_IN = 1,\n        POLL_OUT,\n        POLL_MSG,\n        POLL_ERR,\n        POLL_PRI,\n        POLL_HUP\n    }\n\n    sigfn_t bsd_signal(int sig, sigfn_t func);\n    sigfn_t sigset(int sig, sigfn_t func);\n\n  nothrow:\n  @nogc:\n    sigfn_t2 bsd_signal(int sig, sigfn_t2 func);\n    sigfn_t2 sigset(int sig, sigfn_t2 func);\n\n    int killpg(pid_t, int);\n    int sigaltstack(in stack_t*, stack_t*);\n    int sighold(int);\n    int sigignore(int);\n    int siginterrupt(int, int);\n    int sigpause(int);\n    int sigrelse(int);\n}\nelse version (FreeBSD)\n{\n    // No SIGPOLL on *BSD\n    enum SIGPROF        = 27;\n    enum SIGSYS         = 12;\n    enum SIGTRAP        = 5;\n    enum SIGVTALRM      = 26;\n    enum SIGXCPU        = 24;\n    enum SIGXFSZ        = 25;\n\n    enum\n    {\n        SA_ONSTACK      = 0x0001,\n        SA_RESTART      = 0x0002,\n        SA_RESETHAND    = 0x0004,\n        SA_NODEFER      = 0x0010,\n        SA_NOCLDWAIT    = 0x0020,\n        SA_SIGINFO      = 0x0040,\n    }\n\n    enum\n    {\n        SS_ONSTACK = 0x0001,\n        SS_DISABLE = 0x0004,\n    }\n\n    enum MINSIGSTKSZ = 512 * 4;\n    enum SIGSTKSZ    = (MINSIGSTKSZ + 32768);\n;\n    //ucontext_t (defined in core.sys.posix.ucontext)\n    //mcontext_t (defined in core.sys.posix.ucontext)\n\n    struct stack_t\n    {\n        void*   ss_sp;\n        size_t  ss_size;\n        int     ss_flags;\n    }\n\n    struct sigstack\n    {\n        void*   ss_sp;\n        int     ss_onstack;\n    }\n\n    enum\n    {\n        ILL_ILLOPC = 1,\n        ILL_ILLOPN,\n        ILL_ILLADR,\n        ILL_ILLTRP,\n        ILL_PRVOPC,\n        ILL_PRVREG,\n        ILL_COPROC,\n        ILL_BADSTK,\n    }\n\n    enum\n    {\n        BUS_ADRALN = 1,\n        BUS_ADRERR,\n        BUS_OBJERR,\n    }\n\n    enum\n    {\n        SEGV_MAPERR = 1,\n        SEGV_ACCERR,\n    }\n\n    enum\n    {\n        FPE_INTOVF = 1,\n        FPE_INTDIV,\n        FPE_FLTDIV,\n        FPE_FLTOVF,\n        FPE_FLTUND,\n        FPE_FLTRES,\n        FPE_FLTINV,\n        FPE_FLTSUB,\n    }\n\n    enum\n    {\n        TRAP_BRKPT = 1,\n        TRAP_TRACE,\n    }\n\n    enum\n    {\n        CLD_EXITED = 1,\n        CLD_KILLED,\n        CLD_DUMPED,\n        CLD_TRAPPED,\n        CLD_STOPPED,\n        CLD_CONTINUED,\n    }\n\n    enum\n    {\n        POLL_IN = 1,\n        POLL_OUT,\n        POLL_MSG,\n        POLL_ERR,\n        POLL_PRI,\n        POLL_HUP,\n    }\n\n    //sigfn_t bsd_signal(int sig, sigfn_t func);\n    sigfn_t sigset(int sig, sigfn_t func);\n\n  nothrow:\n  @nogc:\n    //sigfn_t2 bsd_signal(int sig, sigfn_t2 func);\n    sigfn_t2 sigset(int sig, sigfn_t2 func);\n\n    int killpg(pid_t, int);\n    int sigaltstack(in stack_t*, stack_t*);\n    int sighold(int);\n    int sigignore(int);\n    int siginterrupt(int, int);\n    int sigpause(int);\n    int sigrelse(int);\n}\nelse version (NetBSD)\n{\n    // No SIGPOLL on *BSD\n    enum SIGPROF        = 27;\n    enum SIGSYS         = 12;\n    enum SIGTRAP        = 5;\n    enum SIGVTALRM      = 26;\n    enum SIGXCPU        = 24;\n    enum SIGXFSZ        = 25;\n\n    enum\n    {\n        SA_ONSTACK      = 0x0001,\n        SA_RESTART      = 0x0002,\n        SA_RESETHAND    = 0x0004,\n        SA_NODEFER      = 0x0010,\n        SA_NOCLDWAIT    = 0x0020,\n        SA_SIGINFO      = 0x0040,\n    }\n\n    enum\n    {\n        SS_ONSTACK = 0x0001,\n        SS_DISABLE = 0x0004,\n    }\n\n    enum MINSIGSTKSZ = 8192;\n    enum SIGSTKSZ    = (MINSIGSTKSZ + 32768);\n;\n    //ucontext_t (defined in core.sys.posix.ucontext)\n    //mcontext_t (defined in core.sys.posix.ucontext)\n\n    struct stack_t\n    {\n        void*   ss_sp;\n        size_t  ss_size;\n        int     ss_flags;\n    }\n\n    struct sigstack\n    {\n        void*   ss_sp;\n        int     ss_onstack;\n    }\n\n    enum\n    {\n        ILL_ILLOPC = 1,\n        ILL_ILLOPN,\n        ILL_ILLADR,\n        ILL_ILLTRP,\n        ILL_PRVOPC,\n        ILL_PRVREG,\n        ILL_COPROC,\n        ILL_BADSTK,\n    }\n\n    enum\n    {\n        BUS_ADRALN = 1,\n        BUS_ADRERR,\n        BUS_OBJERR,\n    }\n\n    enum\n    {\n        SEGV_MAPERR = 1,\n        SEGV_ACCERR,\n    }\n\n    enum\n    {\n        FPE_INTOVF = 1,\n        FPE_INTDIV,\n        FPE_FLTDIV,\n        FPE_FLTOVF,\n        FPE_FLTUND,\n        FPE_FLTRES,\n        FPE_FLTINV,\n        FPE_FLTSUB,\n    }\n\n    enum\n    {\n        TRAP_BRKPT = 1,\n        TRAP_TRACE,\n    }\n\n    enum\n    {\n        CLD_EXITED = 1,\n        CLD_KILLED,\n        CLD_DUMPED,\n        CLD_TRAPPED,\n        CLD_STOPPED,\n        CLD_CONTINUED,\n    }\n\n    enum\n    {\n        POLL_IN = 1,\n        POLL_OUT,\n        POLL_MSG,\n        POLL_ERR,\n        POLL_PRI,\n        POLL_HUP,\n    }\n\n    //sigfn_t bsd_signal(int sig, sigfn_t func);\n    sigfn_t sigset(int sig, sigfn_t func);\n\n  nothrow:\n  @nogc:\n    //sigfn_t2 bsd_signal(int sig, sigfn_t2 func);\n    sigfn_t2 sigset(int sig, sigfn_t2 func);\n\n    int killpg(pid_t, int);\n    int sigaltstack(in stack_t*, stack_t*);\n    int sighold(int);\n    int sigignore(int);\n    int siginterrupt(int, int);\n    int sigpause(int);\n    int sigrelse(int);\n}\nelse version (OpenBSD)\n{\n    // No SIGPOLL on *BSD\n    enum SIGPROF        = 27;\n    enum SIGSYS         = 12;\n    enum SIGTRAP        = 5;\n    enum SIGVTALRM      = 26;\n    enum SIGXCPU        = 24;\n    enum SIGXFSZ        = 25;\n\n    enum\n    {\n        SA_ONSTACK      = 0x0001,\n        SA_RESTART      = 0x0002,\n        SA_RESETHAND    = 0x0004,\n        SA_NODEFER      = 0x0010,\n        SA_NOCLDWAIT    = 0x0020,\n        SA_SIGINFO      = 0x0040,\n    }\n\n    enum\n    {\n        SS_ONSTACK = 0x0001,\n        SS_DISABLE = 0x0004,\n    }\n\n    enum MINSIGSTKSZ = 8192;\n    enum SIGSTKSZ    = (MINSIGSTKSZ + 32768);\n\n    //ucontext_t (defined in core.sys.posix.ucontext)\n    //mcontext_t (defined in core.sys.posix.ucontext)\n\n    struct stack_t\n    {\n        void*   ss_sp;\n        size_t  ss_size;\n        int     ss_flags;\n    }\n\n    enum\n    {\n        ILL_ILLOPC = 1,\n        ILL_ILLOPN,\n        ILL_ILLADR,\n        ILL_ILLTRP,\n        ILL_PRVOPC,\n        ILL_PRVREG,\n        ILL_COPROC,\n        ILL_BADSTK,\n        NSIGILL = ILL_BADSTK,\n    }\n\n    enum\n    {\n        BUS_ADRALN = 1,\n        BUS_ADRERR,\n        BUS_OBJERR,\n        NSIGBUS = BUS_OBJERR,\n    }\n\n    enum\n    {\n        SEGV_MAPERR = 1,\n        SEGV_ACCERR,\n        NSIGSEGV = SEGV_ACCERR,\n    }\n\n    enum\n    {\n        FPE_INTDIV = 1,\n        FPE_INTOVF,\n        FPE_FLTDIV,\n        FPE_FLTOVF,\n        FPE_FLTUND,\n        FPE_FLTRES,\n        FPE_FLTINV,\n        FPE_FLTSUB,\n        NSIGFPE = FPE_FLTSUB,\n    }\n\n    enum\n    {\n        TRAP_BRKPT = 1,\n        TRAP_TRACE,\n        NSIGTRAP = TRAP_TRACE,\n    }\n\n    enum\n    {\n        CLD_EXITED = 1,\n        CLD_KILLED,\n        CLD_DUMPED,\n        CLD_TRAPPED,\n        CLD_STOPPED,\n        CLD_CONTINUED,\n        NSIGCLD = CLD_CONTINUED,\n    }\n\n    enum\n    {\n        POLL_IN = 1,\n        POLL_OUT,\n        POLL_MSG,\n        POLL_ERR,\n        POLL_PRI,\n        POLL_HUP,\n        NSIGPOLL = POLL_HUP,\n    }\n\n  nothrow:\n  @nogc:\n    int killpg(pid_t, int);\n    int sigaltstack(in stack_t*, stack_t*);\n    int siginterrupt(int, int);\n    int sigpause(int);\n}\nelse version (DragonFlyBSD)\n{\n    // No SIGPOLL on *BSD\n    enum SIGPROF        = 27;\n    enum SIGSYS         = 12;\n    enum SIGTRAP        = 5;\n    enum SIGVTALRM      = 26;\n    enum SIGXCPU        = 24;\n    enum SIGXFSZ        = 25;\n\n    enum\n    {\n        SA_ONSTACK      = 0x0001,\n        SA_RESTART      = 0x0002,\n        SA_RESETHAND    = 0x0004,\n        SA_NODEFER      = 0x0010,\n        SA_NOCLDWAIT    = 0x0020,\n        SA_SIGINFO      = 0x0040,\n    }\n\n    enum\n    {\n        SS_ONSTACK = 0x0001,\n        SS_DISABLE = 0x0004,\n    }\n\n    enum MINSIGSTKSZ = 8192;\n    enum SIGSTKSZ    = (MINSIGSTKSZ + 32768);\n;\n    //ucontext_t (defined in core.sys.posix.ucontext)\n    //mcontext_t (defined in core.sys.posix.ucontext)\n\n    struct stack_t\n    {\n        void*   ss_sp;\n        size_t  ss_size;\n        int     ss_flags;\n    }\n\n    struct sigstack\n    {\n        void*   ss_sp;\n        int     ss_onstack;\n    }\n\n    enum\n    {\n        ILL_ILLOPC = 1,\n        ILL_ILLOPN,\n        ILL_ILLADR,\n        ILL_ILLTRP,\n        ILL_PRVOPC,\n        ILL_PRVREG,\n        ILL_COPROC,\n        ILL_BADSTK,\n    }\n\n    enum\n    {\n        BUS_ADRALN = 1,\n        BUS_ADRERR,\n        BUS_OBJERR,\n    }\n\n    enum\n    {\n        SEGV_MAPERR = 1,\n        SEGV_ACCERR,\n    }\n\n    enum\n    {\n        FPE_INTOVF = 1,\n        FPE_INTDIV,\n        FPE_FLTDIV,\n        FPE_FLTOVF,\n        FPE_FLTUND,\n        FPE_FLTRES,\n        FPE_FLTINV,\n        FPE_FLTSUB,\n    }\n\n    enum\n    {\n        TRAP_BRKPT = 1,\n        TRAP_TRACE,\n    }\n\n    enum\n    {\n        CLD_EXITED = 1,\n        CLD_KILLED,\n        CLD_DUMPED,\n        CLD_TRAPPED,\n        CLD_STOPPED,\n        CLD_CONTINUED,\n    }\n\n    enum\n    {\n        POLL_IN = 1,\n        POLL_OUT,\n        POLL_MSG,\n        POLL_ERR,\n        POLL_PRI,\n        POLL_HUP,\n    }\n\n    //sigfn_t bsd_signal(int sig, sigfn_t func);\n    sigfn_t sigset(int sig, sigfn_t func);\n\n  nothrow:\n  @nogc:\n    //sigfn_t2 bsd_signal(int sig, sigfn_t2 func);\n    sigfn_t2 sigset(int sig, sigfn_t2 func);\n\n    int killpg(pid_t, int);\n    int sigaltstack(in stack_t*, stack_t*);\n    int sighold(int);\n    int sigignore(int);\n    int siginterrupt(int, int);\n    int sigpause(int);\n    int sigrelse(int);\n}\nelse version (Solaris)\n{\n    enum SIGPOLL = 22;\n    enum SIGPROF = 29;\n    enum SIGSYS = 12;\n    enum SIGTRAP = 5;\n    enum SIGVTALRM = 31;\n    enum SIGXCPU = 30;\n    enum SIGXFSZ = 25;\n\n    enum\n    {\n        SA_ONSTACK = 0x00001,\n        SA_RESTART = 0x00004,\n        SA_RESETHAND = 0x00002,\n        SA_NODEFER = 0x00010,\n        SA_NOCLDWAIT = 0x10000,\n        SA_SIGINFO = 0x00008,\n    }\n\n    enum\n    {\n        SS_ONSTACK = 0x0001,\n        SS_DISABLE = 0x0002,\n    }\n\n    enum MINSIGSTKSZ = 2048;\n    enum SIGSTKSZ = 8192;\n\n    struct stack_t\n    {\n        void* ss_sp;\n        size_t ss_size;\n        int ss_flags;\n    }\n\n    struct sigstack\n    {\n        void* ss_sp;\n        int ss_onstack;\n    }\n\n    enum\n    {\n        ILL_ILLOPC = 1,\n        ILL_ILLOPN,\n        ILL_ILLADR,\n        ILL_ILLTRP,\n        ILL_PRVOPC,\n        ILL_PRVREG,\n        ILL_COPROC,\n        ILL_BADSTK,\n    }\n\n    enum\n    {\n        BUS_ADRALN = 1,\n        BUS_ADRERR,\n        BUS_OBJERR,\n    }\n\n    enum\n    {\n        SEGV_MAPERR = 1,\n        SEGV_ACCERR,\n    }\n\n    enum\n    {\n        FPE_INTDIV = 1,\n        FPE_INTOVF,\n        FPE_FLTDIV,\n        FPE_FLTOVF,\n        FPE_FLTUND,\n        FPE_FLTRES,\n        FPE_FLTINV,\n        FPE_FLTSUB,\n        FPE_FLTDEN,\n    }\n\n    enum\n    {\n        TRAP_BRKPT = 1,\n        TRAP_TRACE,\n        TRAP_RWATCH,\n        TRAP_WWATCH,\n        TRAP_XWATCH,\n        TRAP_DTRACE,\n    }\n\n    enum\n    {\n        CLD_EXITED = 1,\n        CLD_KILLED,\n        CLD_DUMPED,\n        CLD_TRAPPED,\n        CLD_STOPPED,\n        CLD_CONTINUED,\n    }\n\n    enum\n    {\n        POLL_IN = 1,\n        POLL_OUT,\n        POLL_MSG,\n        POLL_ERR,\n        POLL_PRI,\n        POLL_HUP,\n    }\n\n    sigfn_t sigset(int sig, sigfn_t func);\n\n  nothrow:\n  @nogc:\n    sigfn_t2 sigset(int sig, sigfn_t2 func);\n\n    int killpg(pid_t, int);\n    int sigaltstack(in stack_t*, stack_t*);\n    int sighold(int);\n    int sigignore(int);\n    int siginterrupt(int, int);\n    int sigpause(int);\n    int sigrelse(int);\n}\nelse version (CRuntime_Bionic)\n{\n    version (X86)\n    {\n        enum SIGPOLL   = 29;\n        enum SIGPROF   = 27;\n        enum SIGSYS    = 31;\n        enum SIGTRAP   = 5;\n        enum SIGVTALRM = 26;\n        enum SIGXCPU   = 24;\n        enum SIGXFSZ   = 25;\n\n        enum SA_ONSTACK     = 0x08000000;\n        enum SA_RESETHAND   = 0x80000000;\n        enum SA_RESTART     = 0x10000000;\n        enum SA_SIGINFO     = 4;\n        enum SA_NOCLDWAIT   = 2;\n        enum SA_NODEFER     = 0x40000000;\n        enum SS_ONSTACK     = 1;\n        enum SS_DISABLE     = 2;\n        enum MINSIGSTKSZ    = 2048;\n        enum SIGSTKSZ       = 8192;\n\n        struct stack_t\n        {\n            void*   ss_sp;\n            int     ss_flags;\n            size_t  ss_size;\n        }\n    }\n    else version (ARM)\n    {\n        enum SIGPOLL   = 29;\n        enum SIGPROF   = 27;\n        enum SIGSYS    = 31;\n        enum SIGTRAP   = 5;\n        enum SIGVTALRM = 26;\n        enum SIGXCPU   = 24;\n        enum SIGXFSZ   = 25;\n\n        enum SA_ONSTACK     = 0x08000000;\n        enum SA_RESETHAND   = 0x80000000;\n        enum SA_RESTART     = 0x10000000;\n        enum SA_SIGINFO     = 4;\n        enum SA_NOCLDWAIT   = 2;\n        enum SA_NODEFER     = 0x40000000;\n        enum SS_ONSTACK     = 1;\n        enum SS_DISABLE     = 2;\n        enum MINSIGSTKSZ    = 2048;\n        enum SIGSTKSZ       = 8192;\n\n        struct stack_t\n        {\n            void*   ss_sp;\n            int     ss_flags;\n            size_t  ss_size;\n        }\n    }\n    else version (AArch64)\n    {\n        enum SIGPOLL   = 29;\n        enum SIGPROF   = 27;\n        enum SIGSYS    = 31;\n        enum SIGTRAP   = 5;\n        enum SIGVTALRM = 26;\n        enum SIGXCPU   = 24;\n        enum SIGXFSZ   = 25;\n\n        enum SA_ONSTACK     = 0x08000000;\n        enum SA_RESETHAND   = 0x80000000;\n        enum SA_RESTART     = 0x10000000;\n        enum SA_SIGINFO     = 4;\n        enum SA_NOCLDWAIT   = 2;\n        enum SA_NODEFER     = 0x40000000;\n        enum SS_ONSTACK     = 1;\n        enum SS_DISABLE     = 2;\n        enum MINSIGSTKSZ    = 2048;\n        enum SIGSTKSZ       = 8192;\n\n        struct stack_t\n        {\n            void*   ss_sp;\n            int     ss_flags;\n            size_t  ss_size;\n        }\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n\n    enum\n    {\n        ILL_ILLOPC = 1,\n        ILL_ILLOPN,\n        ILL_ILLADR,\n        ILL_ILLTRP,\n        ILL_PRVOPC,\n        ILL_PRVREG,\n        ILL_COPROC,\n        ILL_BADSTK\n    }\n\n    enum\n    {\n        FPE_INTDIV = 1,\n        FPE_INTOVF,\n        FPE_FLTDIV,\n        FPE_FLTOVF,\n        FPE_FLTUND,\n        FPE_FLTRES,\n        FPE_FLTINV,\n        FPE_FLTSUB\n    }\n\n    enum\n    {\n        SEGV_MAPERR = 1,\n        SEGV_ACCERR\n    }\n\n    enum\n    {\n        BUS_ADRALN = 1,\n        BUS_ADRERR,\n        BUS_OBJERR\n    }\n\n    enum\n    {\n        TRAP_BRKPT = 1,\n        TRAP_TRACE\n    }\n\n    enum\n    {\n        CLD_EXITED = 1,\n        CLD_KILLED,\n        CLD_DUMPED,\n        CLD_TRAPPED,\n        CLD_STOPPED,\n        CLD_CONTINUED\n    }\n\n    enum\n    {\n        POLL_IN = 1,\n        POLL_OUT,\n        POLL_MSG,\n        POLL_ERR,\n        POLL_PRI,\n        POLL_HUP\n    }\n\n    sigfn_t bsd_signal(int, sigfn_t);\n\n  nothrow:\n  @nogc:\n    sigfn_t2 bsd_signal(int, sigfn_t2);\n\n    int killpg(int, int);\n    int sigaltstack(in stack_t*, stack_t*);\n    int siginterrupt(int, int);\n}\nelse version (CRuntime_Musl)\n{\n    enum SA_RESTART     = 0x10000000;\n}\nelse version (CRuntime_UClibc)\n{\n    version (X86_64)\n    {\n        enum SIGTRAP         = 5;\n        enum SIGIOT          = 6;\n        enum SIGSTKFLT       = 16;\n        enum SIGCLD          = SIGCHLD;\n        enum SIGXCPU         = 24;\n        enum SIGXFSZ         = 25;\n        enum SIGVTALRM       = 26;\n        enum SIGPROF         = 27;\n        enum SIGWINCH        = 28;\n        enum SIGPOLL         = SIGIO;\n        enum SIGIO           = 29;\n        enum SIGPWR          = 30;\n        enum SIGSYS          = 31;\n        enum SIGUNUSED       = 31;\n    }\n    else version (MIPS32)\n    {\n        enum SIGTRAP = 5;\n        enum SIGIOT           = 6;\n        enum SIGEMT           = 7;\n        enum SIGFPE           = 8;\n        enum SIGSYS           = 12;\n        enum SIGCLD           = SIGCHLD;\n        enum SIGPWR           = 19;\n        enum SIGWINCH         = 20;\n        enum SIGIO            = 22;\n        enum SIGPOLL          = SIGIO;\n        enum SIGVTALRM        = 28;\n        enum SIGPROF          = 29;\n        enum SIGXCPU          = 30;\n        enum SIGXFSZ          = 31;\n    }\n    else version (ARM)\n    {\n        enum SIGTRAP = 5;\n        enum SIGIOT = 6;\n        enum SIGSTKFLT = 16;\n        enum SIGCLD = SIGCHLD;\n        enum SIGXCPU = 24;\n        enum SIGXFSZ = 25;\n        enum SIGVTALRM = 26;\n        enum SIGPROF = 27;\n        enum SIGWINCH = 28;\n        enum SIGPOLL = SIGIO;\n        enum SIGIO = 29;\n        enum SIGPWR = 30;\n        enum SIGSYS = 31;\n        enum SIGUNUSED = 31;\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    enum SA_ONSTACK     = 0x08000000;\n    enum SA_RESETHAND   = 0x80000000;\n    enum SA_RESTART     = 0x10000000;\n    enum SA_SIGINFO     = 4;\n    enum SA_NOCLDWAIT   = 2;\n    enum SA_NODEFER     = 0x40000000;\n    enum SS_ONSTACK     = 1;\n    enum SS_DISABLE     = 2;\n    enum MINSIGSTKSZ    = 2048;\n    enum SIGSTKSZ       = 8192;\n\n    enum SA_INTERRUPT   = 0x20000000;\n\n    enum SA_NOMASK      = SA_NODEFER;\n    enum SA_ONESHOT     = SA_RESETHAND;\n    enum SA_STACK       = SA_ONSTACK;\n\n    version (MIPS32)\n    {\n        struct stack_t\n        {\n            void *ss_sp;\n            size_t ss_size;\n            int ss_flags;\n        }\n    }\n    else\n    {\n        struct stack_t\n        {\n            void*   ss_sp;\n            int     ss_flags;\n            size_t  ss_size;\n        }\n     }\n\n    struct sigstack\n    {\n        void*   ss_sp;\n        int     ss_onstack;\n    }\n\n    // `si_code' values for SIGILL signal.\n    enum\n    {\n      ILL_ILLOPC = 1,       // Illegal opcode.\n      ILL_ILLOPN,           // Illegal operand.\n      ILL_ILLADR,           // Illegal addressing mode.\n      ILL_ILLTRP,           // Illegal trap.\n      ILL_PRVOPC,           // Privileged opcode.\n      ILL_PRVREG,           // Privileged register.\n      ILL_COPROC,           // Coprocessor error.\n      ILL_BADSTK            // Internal stack error.\n    }\n\n    // `si_code' values for SIGFPE signal.\n    enum\n    {\n      FPE_INTDIV = 1,       // Integer divide by zero.\n      FPE_INTOVF,           // Integer overflow.\n      FPE_FLTDIV,           // Floating point divide by zero.\n      FPE_FLTOVF,           // Floating point overflow.\n      FPE_FLTUND,           // Floating point underflow.\n      FPE_FLTRES,           // Floating point inexact result.\n      FPE_FLTINV,           // Floating point invalid operation.\n      FPE_FLTSUB            // Subscript out of range.\n    }\n\n    // `si_code' values for SIGSEGV signal.\n    enum\n    {\n      SEGV_MAPERR = 1,      // Address not mapped to object.\n      SEGV_ACCERR           // Invalid permissions for mapped object.\n    }\n\n    // `si_code' values for SIGBUS signal.\n    enum\n    {\n      BUS_ADRALN = 1,       // Invalid address alignment.\n      BUS_ADRERR,           // Non-existant physical address.\n      BUS_OBJERR            // Object specific hardware error.\n    }\n\n    // `si_code' values for SIGTRAP signal.\n    enum\n    {\n      TRAP_BRKPT = 1,       // Process breakpoint.\n      TRAP_TRACE            // Process trace trap.\n    }\n\n    // `si_code' values for SIGCHLD signal.\n    enum\n    {\n      CLD_EXITED = 1,       // Child has exited.\n      CLD_KILLED,           // Child was killed.\n      CLD_DUMPED,           // Child terminated abnormally.\n      CLD_TRAPPED,          // Traced child has trapped.\n      CLD_STOPPED,          // Child has stopped.\n      CLD_CONTINUED         // Stopped child has continued.\n    }\n\n    // `si_code' values for SIGPOLL signal.\n    enum\n    {\n      POLL_IN = 1,          // Data input available.\n      POLL_OUT,         // Output buffers available.\n      POLL_MSG,         // Input message available.\n      POLL_ERR,         // I/O error.\n      POLL_PRI,         // High priority input available.\n      POLL_HUP          // Device disconnected.\n    }\n\n    sigfn_t sigset(int sig, sigfn_t func);\n\n  nothrow:\n  @nogc:\n    sigfn_t2 sigset(int sig, sigfn_t2 func);\n\n    int killpg(pid_t, int);\n    int sigaltstack(in stack_t*, stack_t*);\n    int sighold(int);\n    int sigignore(int);\n    int siginterrupt(int, int);\n    int sigpause(int);\n    int sigrelse(int);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Timer (TMR)\n//\n/*\nNOTE: This should actually be defined in core.sys.posix.time.\n      It is defined here instead to break a circular import.\n\nstruct timespec\n{\n    time_t  tv_sec;\n    int     tv_nsec;\n}\n*/\n\nversion (linux)\n{\n    struct timespec\n    {\n        time_t  tv_sec;\n        c_long  tv_nsec;\n    }\n}\nelse version (Darwin)\n{\n    struct timespec\n    {\n        time_t  tv_sec;\n        c_long  tv_nsec;\n    }\n}\nelse version (FreeBSD)\n{\n    struct timespec\n    {\n        time_t  tv_sec;\n        c_long  tv_nsec;\n    }\n}\nelse version (NetBSD)\n{\n    struct timespec\n    {\n        time_t  tv_sec;\n        c_long  tv_nsec;\n    }\n}\nelse version (OpenBSD)\n{\n    struct timespec\n    {\n        time_t  tv_sec;\n        c_long  tv_nsec;\n    }\n}\nelse version (DragonFlyBSD)\n{\n    struct timespec\n    {\n        time_t  tv_sec;\n        c_long  tv_nsec;\n    }\n}\nelse version (Solaris)\n{\n    struct timespec\n    {\n        time_t tv_sec;\n        c_long tv_nsec;\n    }\n\n    alias timespec timestruc_t;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Realtime Signals (RTS)\n//\n/*\nstruct sigevent\n{\n    int             sigev_notify;\n    int             sigev_signo;\n    sigval          sigev_value;\n    void(*)(sigval) sigev_notify_function;\n    pthread_attr_t* sigev_notify_attributes;\n}\n\nint sigqueue(pid_t, int, in sigval);\nint sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);\nint sigwaitinfo(in sigset_t*, siginfo_t*);\n*/\n\nnothrow:\n@nogc:\n\nversion (CRuntime_Glibc)\n{\n    private enum __SIGEV_MAX_SIZE = 64;\n\n    static if ( __WORDSIZE == 64 )\n    {\n        private enum __SIGEV_PAD_SIZE = ((__SIGEV_MAX_SIZE / int.sizeof) - 4);\n    }\n    else\n    {\n        private enum __SIGEV_PAD_SIZE = ((__SIGEV_MAX_SIZE / int.sizeof) - 3);\n    }\n\n    struct sigevent\n    {\n        sigval      sigev_value;\n        int         sigev_signo;\n        int         sigev_notify;\n\n        union _sigev_un_t\n        {\n            int[__SIGEV_PAD_SIZE] _pad;\n            pid_t                 _tid;\n\n            struct _sigev_thread_t\n            {\n                void function(sigval)   _function;\n                void*                   _attribute;\n            } _sigev_thread_t _sigev_thread;\n        } _sigev_un_t _sigev_un;\n    }\n\n    int sigqueue(pid_t, int, in sigval);\n    int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);\n    int sigwaitinfo(in sigset_t*, siginfo_t*);\n}\nelse version (FreeBSD)\n{\n    struct sigevent\n    {\n        int             sigev_notify;\n        int             sigev_signo;\n        sigval          sigev_value;\n        union  _sigev_un\n        {\n            lwpid_t _threadid;\n            struct _sigev_thread\n            {\n                void function(sigval) _function;\n                void* _attribute;\n            }\n            c_long[8] __spare__;\n        }\n    }\n\n    int sigqueue(pid_t, int, in sigval);\n    int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);\n    int sigwaitinfo(in sigset_t*, siginfo_t*);\n}\nelse version (NetBSD)\n{\n    struct sigevent\n    {\n        int             sigev_notify;\n        int             sigev_signo;\n        sigval          sigev_value;\n        void function(sigval) sigev_notify_function;\n        void /* pthread_attr_t */*sigev_notify_attributes;\n    }\n\n    int sigqueue(pid_t, int, in sigval);\n    int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);\n    int sigwaitinfo(in sigset_t*, siginfo_t*);\n}\nelse version (OpenBSD)\n{\n}\nelse version (DragonFlyBSD)\n{\n    union  _sigev_un_t\n    {\n        int                       sigev_signo;\n        int                       sigev_notify_kqueue;\n        void /*pthread_attr_t*/ * sigev_notify_attributes;\n    };\n    union _sigval_t\n    {\n        int                       sival_int;\n        void                    * sival_ptr;\n        int                       sigval_int;\n        void                    * sigval_ptr;\n    };\n    struct sigevent\n    {\n        int                       sigev_notify;\n        _sigev_un_t               sigev_un;\n        _sigval_t                 sigev_value;\n        void function(_sigval_t)  sigev_notify_function;\n    }\n\n    int sigqueue(pid_t, int, in sigval);\n    int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);\n    int sigwaitinfo(in sigset_t*, siginfo_t*);\n}\nelse version (Darwin)\n{\n    struct sigevent\n    {\n        int sigev_notify;\n        int sigev_signo;\n        sigval sigev_value;\n        void function(sigval) sigev_notify_function;\n        pthread_attr_t* sigev_notify_attributes;\n    }\n}\nelse version (Solaris)\n{\n    struct sigevent\n    {\n        int sigev_notify;\n        int sigev_signo;\n        sigval sigev_value;\n        void function(sigval) sigev_notify_function;\n        pthread_attr_t* sigev_notify_attributes;\n        int __sigev_pad2;\n    }\n\n    int sigqueue(pid_t, int, in sigval);\n    int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);\n    int sigwaitinfo(in sigset_t*, siginfo_t*);\n}\nelse version (CRuntime_Bionic)\n{\n    private enum __ARCH_SIGEV_PREAMBLE_SIZE = (int.sizeof * 2) + sigval.sizeof;\n    private enum SIGEV_MAX_SIZE = 64;\n    private enum SIGEV_PAD_SIZE = (SIGEV_MAX_SIZE - __ARCH_SIGEV_PREAMBLE_SIZE)\n                                  / int.sizeof;\n\n    struct sigevent\n    {\n        sigval      sigev_value;\n        int         sigev_signo;\n        int         sigev_notify;\n\n        union _sigev_un_t\n        {\n            int[SIGEV_PAD_SIZE] _pad;\n            int                 _tid;\n\n            struct _sigev_thread_t\n            {\n                void function(sigval) _function;\n                void*                 _attribute;\n            } _sigev_thread_t _sigev_thread;\n        } _sigev_un_t _sigev_un;\n    }\n}\nelse version (CRuntime_Musl)\n{\n    struct sigevent\n    {\n        sigval sigev_value;\n        int sigev_signo;\n        int sigev_notify;\n        void function(sigval) sigev_notify_function;\n        pthread_attr_t *sigev_notify_attributes;\n        char[56 - 3 * long.sizeof] __pad;\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    private enum __SIGEV_MAX_SIZE = 64;\n\n    static if ( __WORDSIZE == 64 )\n    {\n        private enum __SIGEV_PAD_SIZE = ((__SIGEV_MAX_SIZE / int.sizeof) - 4);\n    }\n    else\n    {\n        private enum __SIGEV_PAD_SIZE = ((__SIGEV_MAX_SIZE / int.sizeof) - 3);\n    }\n\n    struct sigevent\n    {\n        sigval      sigev_value;\n        int         sigev_signo;\n        int         sigev_notify;\n\n        union _sigev_un_t\n        {\n            int[__SIGEV_PAD_SIZE] _pad;\n            pid_t                 _tid;\n\n            struct _sigev_thread_t\n            {\n                void function(sigval)   _function;\n                void*                   _attribute;\n            } _sigev_thread_t _sigev_thread;\n        } _sigev_un_t _sigev_un;\n    }\n\n    @property void function(sigval) sigev_notify_function(ref sigevent _sigevent) { return _sigevent._sigev_un._sigev_thread._function; }\n    @property void* sigev_notify_attributes(ref sigevent _sigevent) { return  _sigevent._sigev_un._sigev_thread._attribute; }\n\n    int sigqueue(pid_t, int, in sigval);\n    int sigtimedwait(in sigset_t*, siginfo_t*, in timespec*);\n    int sigwaitinfo(in sigset_t*, siginfo_t*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Threads (THR)\n//\n/*\nint pthread_kill(pthread_t, int);\nint pthread_sigmask(int, in sigset_t*, sigset_t*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int pthread_kill(pthread_t, int);\n    int pthread_sigmask(int, in sigset_t*, sigset_t*);\n}\nelse version (Darwin)\n{\n    int pthread_kill(pthread_t, int);\n    int pthread_sigmask(int, in sigset_t*, sigset_t*);\n}\nelse version (FreeBSD)\n{\n    int pthread_kill(pthread_t, int);\n    int pthread_sigmask(int, in sigset_t*, sigset_t*);\n}\nelse version (NetBSD)\n{\n    int pthread_kill(pthread_t, int);\n    int pthread_sigmask(int, in sigset_t*, sigset_t*);\n}\nelse version (OpenBSD)\n{\n    int pthread_kill(pthread_t, int);\n    int pthread_sigmask(int, in sigset_t*, sigset_t*);\n}\nelse version (DragonFlyBSD)\n{\n    int pthread_kill(pthread_t, int);\n    int pthread_sigmask(int, in sigset_t*, sigset_t*);\n}\nelse version (Solaris)\n{\n    int pthread_kill(pthread_t, int);\n    int pthread_sigmask(int, in sigset_t*, sigset_t*);\n}\nelse version (CRuntime_Bionic)\n{\n    int pthread_kill(pthread_t, int);\n    int pthread_sigmask(int, in sigset_t*, sigset_t*);\n}\nelse version (CRuntime_Musl)\n{\n    int pthread_kill(pthread_t, int);\n    int pthread_sigmask(int, in sigset_t*, sigset_t*);\n}\nelse version (CRuntime_UClibc)\n{\n    int pthread_kill(pthread_t, int);\n    int pthread_sigmask(int, in sigset_t*, sigset_t*);\n    int pthread_sigqueue(pthread_t, int, sigval);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/spawn.d",
    "content": "/**\n * D header file for spawn.h.\n *\n * Copyright: Copyright (C) 2018 by The D Language Foundation, All Rights Reserved\n * Authors:   Petar Kirov\n * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source:    $(LINK2 https://github.com/dlang/druntime/blob/master/src/core/sys/posix/spawn.d, _spawn.d)\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\nmodule core.sys.posix.spawn;\n\n/*\nBased on the following system headers:\n\nGlibc: https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/spawn.h;hb=HEAD\n\nBionic libc: https://android.googlesource.com/platform/bionic.git/+/master/libc/include/spawn.h\n\nMusl libc: https://git.musl-libc.org/cgit/musl/tree/include/spawn.h\n\nuClibc: https://git.uclibc.org/uClibc/tree/include/spawn.h\n\nDarwin XNU:\nhttps://opensource.apple.com/source/xnu/xnu-4570.71.2/libsyscall/wrappers/spawn/spawn.h.auto.html\nhttps://opensource.apple.com/source/xnu/xnu-4570.71.2/bsd/sys/spawn.h.auto.html\nhttps://github.com/opensource-apple/xnu (GitHub mirror)\n\nFreeBSD: https://github.com/freebsd/freebsd/blob/master/include/spawn.h\n\nNetBSD: https://github.com/NetBSD/src/blob/trunk/sys/sys/spawn.h\n\nOpenBSD: https://github.com/openbsd/src/blob/master/include/spawn.h\n\nDragonFlyBSD: https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/include/spawn.h\n\nSolaris: https://github.com/illumos/illumos-gate/blob/master/usr/src/head/spawn.h\n*/\n\nversion (OSX) // macOS and iOS only as this API is prohibited on WatchOS and TVOS\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\n\nversion (Posix):\npublic import core.sys.posix.sys.types : mode_t, pid_t;\npublic import core.sys.posix.signal : sigset_t;\npublic import core.sys.posix.sched : sched_param;\n\nextern(C):\n@nogc:\nnothrow:\n\nint posix_spawn_file_actions_addclose(posix_spawn_file_actions_t*, int);\nint posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t*, int, int);\nint posix_spawn_file_actions_addopen(posix_spawn_file_actions_t*, int, const char*, int, mode_t);\nint posix_spawn_file_actions_destroy(posix_spawn_file_actions_t*);\nint posix_spawn_file_actions_init(posix_spawn_file_actions_t*);\nint posix_spawnattr_destroy(posix_spawnattr_t*);\nint posix_spawnattr_getflags(const posix_spawnattr_t*, short*);\nint posix_spawnattr_getpgroup(const posix_spawnattr_t*, pid_t*);\n\nversion (Darwin)\n{ } // Not supported\nelse\n{\n    int posix_spawnattr_getschedparam(const posix_spawnattr_t*, sched_param*);\n    int posix_spawnattr_getschedpolicy(const posix_spawnattr_t*, int*);\n    int posix_spawnattr_setschedparam(posix_spawnattr_t*, const sched_param*);\n    int posix_spawnattr_setschedpolicy(posix_spawnattr_t*, int);\n}\n\nint posix_spawnattr_getsigdefault(const posix_spawnattr_t*, sigset_t*);\nint posix_spawnattr_getsigmask(const posix_spawnattr_t*, sigset_t*);\nint posix_spawnattr_init(posix_spawnattr_t*);\nint posix_spawnattr_setflags(posix_spawnattr_t*, short);\nint posix_spawnattr_setpgroup(posix_spawnattr_t*, pid_t);\nint posix_spawnattr_setsigdefault(posix_spawnattr_t*, const sigset_t*);\nint posix_spawnattr_setsigmask(posix_spawnattr_t*, const sigset_t*);\nint posix_spawn(pid_t*pid, const char* path,\n                const posix_spawn_file_actions_t* file_actions,\n                const posix_spawnattr_t* attrp,\n                const char** argv, const char** envp);\nint posix_spawnp(pid_t* pid, const char* file,\n                 const posix_spawn_file_actions_t* file_actions,\n                 const posix_spawnattr_t* attrp,\n                 const char** argv, const char** envp);\n\nversion (linux)\n{\n    version (CRuntime_Glibc)\n    {\n        // Source: https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/spawn.h;hb=HEAD\n        enum\n        {\n            POSIX_SPAWN_RESETIDS = 0x01,\n            POSIX_SPAWN_SETPGROUP = 0x02,\n            POSIX_SPAWN_SETSIGDEF = 0x04,\n            POSIX_SPAWN_SETSIGMASK = 0x08,\n            POSIX_SPAWN_SETSCHEDPARAM = 0x10,\n            POSIX_SPAWN_SETSCHEDULER = 0x20\n        }\n        import core.sys.posix.config : __USE_GNU;\n        static if (__USE_GNU)\n        {\n            enum\n            {\n                POSIX_SPAWN_USEVFORK = 0x40,\n                POSIX_SPAWN_SETSID = 0x80\n            }\n        }\n        struct posix_spawnattr_t\n        {\n            short __flags;\n            pid_t __pgrp;\n            sigset_t __sd;\n            sigset_t __ss;\n            sched_param __sp;\n            int __policy;\n            int[16] __pad;\n        }\n        struct __spawn_action;\n        struct posix_spawn_file_actions_t\n        {\n            int __allocated;\n            int __used;\n            __spawn_action* __actions;\n            int[16] __pad;\n        }\n    }\n    else version (CRuntime_Bionic)\n    {\n        // Source: https://android.googlesource.com/platform/bionic.git/+/master/libc/include/spawn.h\n        enum\n        {\n            POSIX_SPAWN_RESETIDS = 1,\n            POSIX_SPAWN_SETPGROUP = 2,\n            POSIX_SPAWN_SETSIGDEF = 4,\n            POSIX_SPAWN_SETSIGMASK = 8,\n            POSIX_SPAWN_SETSCHEDPARAM = 16,\n            POSIX_SPAWN_SETSCHEDULER = 32\n        }\n        import core.sys.posix.config : __USE_GNU;\n        static if (__USE_GNU)\n        {\n            enum\n            {\n                POSIX_SPAWN_USEVFORK = 64,\n                POSIX_SPAWN_SETSID = 128\n            }\n        }\n        alias posix_spawnattr_t = __posix_spawnattr*;\n        alias posix_spawn_file_actions_t = __posix_spawn_file_actions*;\n        struct __posix_spawnattr;\n        struct __posix_spawn_file_actions;\n    }\n    else version (CRuntime_Musl)\n    {\n        // Source: https://git.musl-libc.org/cgit/musl/tree/include/spawn.h\n        enum\n        {\n            POSIX_SPAWN_RESETIDS = 1,\n            POSIX_SPAWN_SETPGROUP = 2,\n            POSIX_SPAWN_SETSIGDEF = 4,\n            POSIX_SPAWN_SETSIGMASK = 8,\n            POSIX_SPAWN_SETSCHEDPARAM = 16,\n            POSIX_SPAWN_SETSCHEDULER = 32,\n            POSIX_SPAWN_USEVFORK = 64,\n            POSIX_SPAWN_SETSID = 128\n        }\n        struct posix_spawnattr_t\n        {\n            int __flags;\n            pid_t __pgrp;\n            sigset_t __def, __mask;\n            int __prio, __pol;\n            void* __fn;\n            char[64 - (void*).sizeof] __pad;\n        }\n        struct posix_spawn_file_actions_t\n        {\n            int[2] __pad0;\n            void* __actions;\n            int[16] __pad;\n        }\n    }\n    else version (CRuntime_UClibc)\n    {\n        // Source: https://git.uclibc.org/uClibc/tree/include/spawn.h\n        enum\n        {\n            POSIX_SPAWN_RESETIDS = 0x01,\n            POSIX_SPAWN_SETPGROUP = 0x02,\n            POSIX_SPAWN_SETSIGDEF = 0x04,\n            POSIX_SPAWN_SETSIGMASK = 0x08,\n            POSIX_SPAWN_SETSCHEDPARAM = 0x10,\n            POSIX_SPAWN_SETSCHEDULER = 0x20\n        }\n        import core.sys.posix.config : __USE_GNU;\n        static if (__USE_GNU)\n        {\n            enum\n            {\n                POSIX_SPAWN_USEVFORK = 0x40,\n            }\n        }\n        struct posix_spawnattr_t\n        {\n            short __flags;\n            pid_t __pgrp;\n            sigset_t __sd;\n            sigset_t __ss;\n            sched_param __sp;\n            int __policy;\n            int[16] __pad;\n        }\n        struct posix_spawn_file_actions_t\n        {\n            int __allocated;\n            int __used;\n            __spawn_action* __actions;\n            int[16] __pad;\n        }\n    }\n    else\n        static assert(0, \"Unsupported Linux libc\");\n}\nelse version (Darwin)\n{\n    // Sources:\n    // https://opensource.apple.com/source/xnu/xnu-4570.71.2/libsyscall/wrappers/spawn/spawn.h.auto.html\n    // https://opensource.apple.com/source/xnu/xnu-4570.71.2/bsd/sys/spawn.h.auto.html\n    enum\n    {\n        POSIX_SPAWN_RESETIDS = 0x01,\n        POSIX_SPAWN_SETPGROUP = 0x02,\n        POSIX_SPAWN_SETSIGDEF = 0x04,\n        POSIX_SPAWN_SETSIGMASK = 0x08,\n        // POSIX_SPAWN_SETSCHEDPARAM = 0x10,  // not supported\n        // POSIX_SPAWN_SETSCHEDULER = 0x20,   // ditto\n        POSIX_SPAWN_SETEXEC = 0x40,\n        POSIX_SPAWN_START_SUSPENDED = 0x80\n    }\n    alias posix_spawnattr_t = void*;\n    alias posix_spawn_file_actions_t = void*;\n}\nelse version (FreeBSD)\n{\n    // Source: https://github.com/freebsd/freebsd/blob/master/include/spawn.h\n    enum\n    {\n        POSIX_SPAWN_RESETIDS = 0x01,\n        POSIX_SPAWN_SETPGROUP = 0x02,\n        POSIX_SPAWN_SETSCHEDPARAM = 0x04,\n        POSIX_SPAWN_SETSCHEDULER = 0x08,\n        POSIX_SPAWN_SETSIGDEF = 0x10,\n        POSIX_SPAWN_SETSIGMASK = 0x20\n    }\n    alias posix_spawnattr_t =  void*;\n    alias posix_spawn_file_actions_t =  void*;\n}\nelse version (NetBSD)\n{\n    // Source: https://github.com/NetBSD/src/blob/trunk/sys/sys/spawn.h\n    enum\n    {\n        POSIX_SPAWN_RESETIDS = 0x01,\n        POSIX_SPAWN_SETPGROUP = 0x02,\n        POSIX_SPAWN_SETSCHEDPARAM = 0x04,\n        POSIX_SPAWN_SETSCHEDULER = 0x08,\n        POSIX_SPAWN_SETSIGDEF = 0x10,\n        POSIX_SPAWN_SETSIGMASK = 0x20,\n        POSIX_SPAWN_RETURNERROR = 0x40 // NetBSD specific\n    }\n    struct posix_spawnattr\n    {\n        short sa_flags;\n        pid_t sa_pgroup;\n        sched_param sa_schedparam;\n        int sa_schedpolicy;\n        sigset_t sa_sigdefault;\n        sigset_t sa_sigmask;\n    }\n    struct posix_spawn_file_actions_entry_t;\n    struct posix_spawn_file_actions\n    {\n        uint size;\n        uint len;\n        posix_spawn_file_actions_entry_t* fae;\n    }\n}\nelse version (OpenBSD)\n{\n    // Source: https://github.com/openbsd/src/blob/master/include/spawn.h\n    enum\n    {\n        POSIX_SPAWN_RESETIDS = 0x01,\n        POSIX_SPAWN_SETPGROUP = 0x02,\n        POSIX_SPAWN_SETSCHEDPARAM = 0x04,\n        POSIX_SPAWN_SETSCHEDULER = 0x08,\n        POSIX_SPAWN_SETSIGDEF = 0x10,\n        POSIX_SPAWN_SETSIGMASK = 0x20\n    }\n    alias posix_spawnattr_t = __posix_spawnattr*;\n    alias posix_spawn_file_actions_t = __posix_spawn_file_actions*;\n    struct __posix_spawnattr;\n    struct __posix_spawn_file_actions;\n}\nelse version (DragonFlyBSD)\n{\n    // Source: https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/include/spawn.h\n    enum\n    {\n        POSIX_SPAWN_RESETIDS = 0x01,\n        POSIX_SPAWN_SETPGROUP = 0x02,\n        POSIX_SPAWN_SETSCHEDPARAM = 0x04,\n        POSIX_SPAWN_SETSCHEDULER = 0x08,\n        POSIX_SPAWN_SETSIGDEF = 0x10,\n        POSIX_SPAWN_SETSIGMASK = 0x20\n    }\n    alias posix_spawnattr_t = __posix_spawnattr*;\n    alias posix_spawn_file_actions_t = __posix_spawn_file_actions*;\n    struct __posix_spawnattr;\n    struct __posix_spawn_file_actions;\n}\nelse version (Solaris)\n{\n    // Source: https://github.com/illumos/illumos-gate/blob/master/usr/src/head/spawn.h\n    enum\n    {\n        POSIX_SPAWN_RESETIDS = 0x01,\n        POSIX_SPAWN_SETPGROUP = 0x02,\n        POSIX_SPAWN_SETSIGDEF = 0x04,\n        POSIX_SPAWN_SETSIGMASK = 0x08,\n        POSIX_SPAWN_SETSCHEDPARAM = 0x10,\n        POSIX_SPAWN_SETSCHEDULER = 0x20,\n    }\n    version (none)\n    {\n        // Non-portable Solaris extensions.\n        enum\n        {\n            POSIX_SPAWN_SETSIGIGN_NP = 0x0800,\n            POSIX_SPAWN_NOSIGCHLD_NP = 0x1000,\n            POSIX_SPAWN_WAITPID_NP = 0x2000,\n            POSIX_SPAWN_NOEXECERR_NP = 0x4000,\n        }\n    }\n    struct posix_spawnattr_t\n    {\n        void* __spawn_attrp;\n    }\n    struct posix_spawn_file_actions_t\n    {\n        void* __file_attrp;\n    }\n    version (none)\n    {\n        // Non-portable Solaris extensions.\n        alias boolean_t = int;\n        int posix_spawn_file_actions_addclosefrom_np(posix_spawn_file_actions_t* file_actions,\n                                                     int lowfiledes);\n        int posix_spawn_pipe_np(pid_t* pidp, int* fdp, const char* cmd, boolean_t write,\n                                posix_spawn_file_actions_t* fact,\n                                posix_spawnattr_t* attr);\n        int posix_spawnattr_getsigignore_np(const posix_spawnattr_t* attr, sigset_t* sigignore);\n        int posix_spawnattr_setsigignore_np(posix_spawnattr_t* attr, const sigset_t* sigignore);\n    }\n}\nelse\n    static assert(0, \"Unsupported OS\");\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/stdio.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.stdio;\n\nprivate import core.sys.posix.config;\npublic import core.stdc.stdio;\npublic import core.sys.posix.sys.types; // for off_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\n\nnothrow:\n@nogc:\n\n//\n// Required (defined in core.stdc.stdio)\n//\n/*\nBUFSIZ\n_IOFBF\n_IOLBF\n_IONBF\nL_tmpnam\nSEEK_CUR\nSEEK_END\nSEEK_SET\nFILENAME_MAX\nFOPEN_MAX\nTMP_MAX\nEOF\nNULL\nstderr\nstdin\nstdout\nFILE\nfpos_t\nsize_t\n\nvoid   clearerr(FILE*);\nint    fclose(FILE*);\nint    feof(FILE*);\nint    ferror(FILE*);\nint    fflush(FILE*);\nint    fgetc(FILE*);\nint    fgetpos(FILE*, fpos_t *);\nchar*  fgets(char*, int, FILE*);\nFILE*  fopen(in char*, in char*);\nint    fprintf(FILE*, in char*, ...);\nint    fputc(int, FILE*);\nint    fputs(in char*, FILE*);\nsize_t fread(void *, size_t, size_t, FILE*);\nFILE*  freopen(in char*, in char*, FILE*);\nint    fscanf(FILE*, in char*, ...);\nint    fseek(FILE*, c_long, int);\nint    fsetpos(FILE*, in fpos_t*);\nc_long ftell(FILE*);\nsize_t fwrite(in void *, size_t, size_t, FILE*);\nint    getc(FILE*);\nint    getchar();\nchar*  gets(char*);\nvoid   perror(in char*);\nint    printf(in char*, ...);\nint    putc(int, FILE*);\nint    putchar(int);\nint    puts(in char*);\nint    remove(in char*);\nint    rename(in char*, in char*);\nvoid   rewind(FILE*);\nint    scanf(in char*, ...);\nvoid   setbuf(FILE*, char*);\nint    setvbuf(FILE*, char*, int, size_t);\nint    snprintf(char*, size_t, in char*, ...);\nint    sprintf(char*, in char*, ...);\nint    sscanf(in char*, in char*, int ...);\nFILE*  tmpfile();\nchar*  tmpnam(char*);\nint    ungetc(int, FILE*);\nint    vfprintf(FILE*, in char*, va_list);\nint    vfscanf(FILE*, in char*, va_list);\nint    vprintf(in char*, va_list);\nint    vscanf(in char*, va_list);\nint    vsnprintf(char*, size_t, in char*, va_list);\nint    vsprintf(char*, in char*, va_list);\nint    vsscanf(in char*, in char*, va_list arg);\n*/\n\nversion (CRuntime_Glibc)\n{\n    /*\n     * actually, if __USE_FILE_OFFSET64 && !_LARGEFILE64_SOURCE\n     * the *64 functions shouldn't be visible, but the aliases should\n     * still be supported\n     */\n    static if ( __USE_FILE_OFFSET64 )\n    {\n        int   fgetpos64(FILE*, fpos_t *);\n        alias fgetpos64 fgetpos;\n\n        FILE* fopen64(in char*, in char*);\n        alias fopen64 fopen;\n\n        FILE* freopen64(in char*, in char*, FILE*);\n        alias freopen64 freopen;\n\n        int   fseek(FILE*, c_long, int);\n\n        int   fsetpos64(FILE*, in fpos_t*);\n        alias fsetpos64 fsetpos;\n\n        FILE* tmpfile64();\n        alias tmpfile64 tmpfile;\n    }\n    else\n    {\n        int   fgetpos(FILE*, fpos_t *);\n        FILE* fopen(in char*, in char*);\n        FILE* freopen(in char*, in char*, FILE*);\n        int   fseek(FILE*, c_long, int);\n        int   fsetpos(FILE*, in fpos_t*);\n        FILE* tmpfile();\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    int   fgetpos(FILE*, fpos_t *);\n    FILE* fopen(in char*, in char*);\n    FILE* freopen(in char*, in char*, FILE*);\n    int   fseek(FILE*, c_long, int);\n    int   fsetpos(FILE*, in fpos_t*);\n}\nelse version (CRuntime_UClibc)\n{\n    static if ( __USE_FILE_OFFSET64 )\n    {\n        int   fgetpos64(FILE*, fpos_t *);\n        alias fgetpos64 fgetpos;\n\n        FILE* fopen64(in char*, in char*);\n        alias fopen64 fopen;\n\n        FILE* freopen64(in char*, in char*, FILE*);\n        alias freopen64 freopen;\n\n        int   fseek(FILE*, c_long, int);\n\n        int   fsetpos64(FILE*, in fpos_t*);\n        alias fsetpos64 fsetpos;\n\n        FILE* tmpfile64();\n        alias tmpfile64 tmpfile;\n    }\n    else\n    {\n        int   fgetpos(FILE*, fpos_t *);\n        FILE* fopen(in char*, in char*);\n        FILE* freopen(in char*, in char*, FILE*);\n        int   fseek(FILE*, c_long, int);\n        int   fsetpos(FILE*, in fpos_t*);\n        FILE* tmpfile();\n    }\n}\n\n//\n// C Extension (CX)\n//\n/*\nL_ctermid\n\nchar*  ctermid(char*);\nFILE*  fdopen(int, in char*);\nint    fileno(FILE*);\nint    fseeko(FILE*, off_t, int);\noff_t  ftello(FILE*);\nchar*  gets(char*);\nint    pclose(FILE*);\nFILE*  popen(in char*, in char*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum L_ctermid = 9;\n\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    int   fseeko64(FILE*, off_t, int);\n    alias fseeko64 fseeko;\n  }\n  else\n  {\n    int   fseeko(FILE*, off_t, int);\n  }\n\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    off_t ftello64(FILE*);\n    alias ftello64 ftello;\n  }\n  else\n  {\n    off_t ftello(FILE*);\n  }\n}\nelse version (CRuntime_UClibc)\n{\n    enum L_ctermid = 9;\n    enum L_cuserid = 9;\n\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    int   fseeko64(FILE*, off_t, int);\n    alias fseeko64 fseeko;\n  }\n  else\n  {\n    int   fseeko(FILE*, off_t, int);\n  }\n\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    off_t ftello64(FILE*);\n    alias ftello64 ftello;\n  }\n  else\n  {\n    off_t ftello(FILE*);\n  }\n}\nelse version (Posix)\n{\n    int   fseeko(FILE*, off_t, int);\n    off_t ftello(FILE*);\n}\n\nchar*  ctermid(char*);\nFILE*  fdopen(int, in char*);\nint    fileno(FILE*);\n//int    fseeko(FILE*, off_t, int);\n//off_t  ftello(FILE*);\nchar*  gets(char*);\nint    pclose(FILE*);\nFILE*  popen(in char*, in char*);\n\n\n// memstream functions are conforming to POSIX.1-2008.  These functions are\n// not specified in POSIX.1-2001 and are not widely available on other\n// systems.\nversion (CRuntime_Glibc)                     // as of glibc 1.0x\n    version = HaveMemstream;\nelse version (FreeBSD)                      // as of FreeBSD 9.2\n    version = HaveMemstream;\nelse version (DragonFlyBSD)                 // for DragonFlyBSD\n    version = HaveMemstream;\nelse version (OpenBSD)                      // as of OpenBSD 5.4\n    version = HaveMemstream;\nelse version (CRuntime_UClibc)\n    version = HaveMemstream;\n\nversion (HaveMemstream)\n{\n    FILE*  fmemopen(in void* buf, in size_t size, in char* mode);\n    FILE*  open_memstream(char** ptr, size_t* sizeloc);\n    version (CRuntime_UClibc) {} else\n    FILE*  open_wmemstream(wchar_t** ptr, size_t* sizeloc);\n}\n\n//\n// Thread-Safe Functions (TSF)\n//\n/*\nvoid   flockfile(FILE*);\nint    ftrylockfile(FILE*);\nvoid   funlockfile(FILE*);\nint    getc_unlocked(FILE*);\nint    getchar_unlocked();\nint    putc_unlocked(int, FILE*);\nint    putchar_unlocked(int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    void   flockfile(FILE*);\n    int    ftrylockfile(FILE*);\n    void   funlockfile(FILE*);\n    int    getc_unlocked(FILE*);\n    int    getchar_unlocked();\n    int    putc_unlocked(int, FILE*);\n    int    putchar_unlocked(int);\n}\nelse version (OpenBSD)\n{\n    void   flockfile(FILE*);\n    int    ftrylockfile(FILE*);\n    void   funlockfile(FILE*);\n    int    getc_unlocked(FILE*);\n    int    getchar_unlocked();\n    int    putc_unlocked(int, FILE*);\n    int    putchar_unlocked(int);\n}\nelse version (Solaris)\n{\n    void   flockfile(FILE*);\n    int    ftrylockfile(FILE*);\n    void   funlockfile(FILE*);\n    int    getc_unlocked(FILE*);\n    int    getchar_unlocked();\n    int    putc_unlocked(int, FILE*);\n    int    putchar_unlocked(int);\n}\nelse version (CRuntime_UClibc)\n{\n    void   flockfile(FILE*);\n    int    ftrylockfile(FILE*);\n    void   funlockfile(FILE*);\n    int    getc_unlocked(FILE*);\n    int    getchar_unlocked();\n    int    putc_unlocked(int, FILE*);\n    int    putchar_unlocked(int);\n}\n\n//\n// XOpen (XSI)\n//\n/*\nP_tmpdir\nva_list (defined in core.stdc.stdarg)\n\nchar*  tempnam(in char*, in char*);\n*/\n\nchar*  tempnam(in char*, in char*);\n\nversion (CRuntime_Glibc)\n{\n    enum P_tmpdir  = \"/tmp\";\n}\nversion (CRuntime_Musl)\n{\n    enum P_tmpdir  = \"/tmp\";\n}\nversion (Darwin)\n{\n    enum P_tmpdir  = \"/var/tmp\";\n}\nversion (FreeBSD)\n{\n    enum P_tmpdir  = \"/var/tmp/\";\n}\nversion (NetBSD)\n{\n    enum P_tmpdir  = \"/var/tmp/\";\n}\nversion (OpenBSD)\n{\n    enum P_tmpdir  = \"/tmp/\";\n}\nversion (DragonFlyBSD)\n{\n    enum P_tmpdir  = \"/var/tmp/\";\n}\nversion (Solaris)\n{\n    enum P_tmpdir  = \"/var/tmp/\";\n}\nversion (CRuntime_UClibc)\n{\n    enum P_tmpdir  = \"/tmp\";\n}\n\nversion (HaveMemstream)\nunittest\n{ /* fmemopen */\n    import core.stdc.string : memcmp;\n    byte[10] buf;\n    auto f = fmemopen(buf.ptr, 10, \"w\");\n    assert(f !is null);\n    assert(fprintf(f, \"hello\") == \"hello\".length);\n    assert(fflush(f) == 0);\n    assert(memcmp(buf.ptr, \"hello\".ptr, \"hello\".length) == 0);\n    //assert(buf\n    assert(fclose(f) == 0);\n}\n\nversion (HaveMemstream)\nunittest\n{ /* Note: open_memstream is only useful for writing */\n    import core.stdc.string : memcmp;\n    char* ptr = null;\n    char[6] testdata = ['h', 'e', 'l', 'l', 'o', 0];\n    size_t sz = 0;\n    auto f = open_memstream(&ptr, &sz);\n    assert(f !is null);\n    assert(fprintf(f, \"%s\", testdata.ptr) == 5);\n    assert(fflush(f) == 0);\n    assert(memcmp(ptr, testdata.ptr, testdata.length) == 0);\n    assert(fclose(f) == 0);\n}\n\nversion (CRuntime_UClibc) {} else\nversion (HaveMemstream)\nunittest\n{ /* Note: open_wmemstream is only useful for writing */\n    import core.stdc.string : memcmp;\n    import core.stdc.wchar_ : fwprintf;\n    wchar_t* ptr = null;\n    wchar_t[6] testdata = ['h', 'e', 'l', 'l', 'o', 0];\n    size_t sz = 0;\n    auto f = open_wmemstream(&ptr, &sz);\n    assert(f !is null);\n    assert(fwprintf(f, testdata.ptr) == 5);\n    assert(fflush(f) == 0);\n    assert(memcmp(ptr, testdata.ptr, testdata.length*wchar_t.sizeof) == 0);\n    assert(fclose(f) == 0);\n}\n\n\nssize_t getdelim (char** lineptr, size_t* n, int delimiter, FILE* stream);\nssize_t getline (char** lineptr, size_t* n, FILE* stream);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/stdlib.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.stdlib;\n\nprivate import core.sys.posix.config;\npublic import core.stdc.stdlib;\npublic import core.sys.posix.sys.wait;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// Required (defined in core.stdc.stdlib)\n//\n/*\nEXIT_FAILURE\nEXIT_SUCCESS\nNULL\nRAND_MAX\nMB_CUR_MAX\ndiv_t\nldiv_t\nlldiv_t\nsize_t\nwchar_t\n\nvoid    _Exit(int);\nvoid    abort();\nint     abs(int);\nint     atexit(void function());\ndouble  atof(in char*);\nint     atoi(in char*);\nc_long  atol(in char*);\nlong    atoll(in char*);\nvoid*   bsearch(in void*, in void*, size_t, size_t, int function(in void*, in void*));\nvoid*   calloc(size_t, size_t);\ndiv_t   div(int, int);\nvoid    exit(int);\nvoid    free(void*);\nchar*   getenv(in char*);\nc_long  labs(c_long);\nldiv_t  ldiv(c_long, c_long);\nlong    llabs(long);\nlldiv_t lldiv(long, long);\nvoid*   malloc(size_t);\nint     mblen(in char*, size_t);\nsize_t  mbstowcs(wchar_t*, in char*, size_t);\nint     mbtowc(wchar_t*, in char*, size_t);\nvoid    qsort(void*, size_t, size_t, int function(in void*, in void*));\nint     rand();\nvoid*   realloc(void*, size_t);\nvoid    srand(uint);\ndouble  strtod(in char*, char**);\nfloat   strtof(in char*, char**);\nc_long  strtol(in char*, char**, int);\nreal    strtold(in char*, char**);\nlong    strtoll(in char*, char**, int);\nc_ulong strtoul(in char*, char**, int);\nulong   strtoull(in char*, char**, int);\nint     system(in char*);\nsize_t  wcstombs(char*, in wchar_t*, size_t);\nint     wctomb(char*, wchar_t);\n*/\n\n//\n// Advisory Information (ADV)\n//\n/*\nint posix_memalign(void**, size_t, size_t);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int posix_memalign(void**, size_t, size_t);\n}\nelse version (FreeBSD)\n{\n    int posix_memalign(void**, size_t, size_t);\n}\nelse version (NetBSD)\n{\n    int posix_memalign(void**, size_t, size_t);\n}\nelse version (OpenBSD)\n{\n    int posix_memalign(void**, size_t, size_t);\n}\nelse version (DragonFlyBSD)\n{\n    int posix_memalign(void**, size_t, size_t);\n}\nelse version (Solaris)\n{\n    int posix_memalign(void**, size_t, size_t);\n}\nelse version (Darwin)\n{\n    int posix_memalign(void**, size_t, size_t);\n}\nelse version (CRuntime_Bionic)\n{\n    // Added since Lollipop\n    int posix_memalign(void**, size_t, size_t);\n}\nelse version (CRuntime_Musl)\n{\n    int posix_memalign(void**, size_t, size_t);\n}\nelse version (CRuntime_UClibc)\n{\n    int posix_memalign(void**, size_t, size_t);\n}\n\n//\n// C Extension (CX)\n//\n/*\nint setenv(in char*, in char*, int);\nint unsetenv(in char*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int setenv(in char*, in char*, int);\n    int unsetenv(in char*);\n\n    void* valloc(size_t); // LEGACY non-standard\n}\nelse version (Darwin)\n{\n    int setenv(in char*, in char*, int);\n    int unsetenv(in char*);\n\n    void* valloc(size_t); // LEGACY non-standard\n}\nelse version (FreeBSD)\n{\n    int setenv(in char*, in char*, int);\n    int unsetenv(in char*);\n\n    void* valloc(size_t); // LEGACY non-standard\n}\nelse version (NetBSD)\n{\n    int setenv(in char*, in char*, int);\n    int __unsetenv13(in char*);\n    alias __unsetenv13 unsetenv;\n    void* valloc(size_t); // LEGACY non-standard\n}\nelse version (OpenBSD)\n{\n    int setenv(in char*, in char*, int);\n    int unsetenv(in char*);\n\n    void* valloc(size_t); // LEGACY non-standard\n}\nelse version (DragonFlyBSD)\n{\n    int setenv(in char*, in char*, int);\n    int unsetenv(in char*);\n\n    void* valloc(size_t); // LEGACY non-standard\n}\nelse version (CRuntime_Bionic)\n{\n    int setenv(in char*, in char*, int);\n    int unsetenv(in char*);\n\n    void* valloc(size_t);\n}\nelse version (Solaris)\n{\n    int setenv(in char*, in char*, int);\n    int unsetenv(in char*);\n\n    void* valloc(size_t); // LEGACY non-standard\n}\nelse version (CRuntime_Musl)\n{\n    int setenv(in char*, in char*, int);\n    int unsetenv(in char*);\n}\nelse version (CRuntime_UClibc)\n{\n    int setenv(in char*, in char*, int);\n    int unsetenv(in char*);\n    void* valloc(size_t);\n}\n\n//\n// Thread-Safe Functions (TSF)\n//\n/*\nint rand_r(uint*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int rand_r(uint*);\n}\nelse version (Darwin)\n{\n    int rand_r(uint*);\n}\nelse version (FreeBSD)\n{\n    int rand_r(uint*);\n}\nelse version (NetBSD)\n{\n    int rand_r(uint*);\n}\nelse version (OpenBSD)\n{\n    int rand_r(uint*);\n}\nelse version (DragonFlyBSD)\n{\n    int rand_r(uint*);\n}\nelse version (Solaris)\n{\n    int rand_r(uint*);\n}\nelse version (CRuntime_UClibc)\n{\n    int rand_r(uint*);\n}\n\n//\n// XOpen (XSI)\n//\n/*\nWNOHANG     (defined in core.sys.posix.sys.wait)\nWUNTRACED   (defined in core.sys.posix.sys.wait)\nWEXITSTATUS (defined in core.sys.posix.sys.wait)\nWIFEXITED   (defined in core.sys.posix.sys.wait)\nWIFSIGNALED (defined in core.sys.posix.sys.wait)\nWIFSTOPPED  (defined in core.sys.posix.sys.wait)\nWSTOPSIG    (defined in core.sys.posix.sys.wait)\nWTERMSIG    (defined in core.sys.posix.sys.wait)\n\nc_long a64l(in char*);\ndouble drand48();\nchar*  ecvt(double, int, int *, int *); // LEGACY\ndouble erand48(ref ushort[3]);\nchar*  fcvt(double, int, int *, int *); // LEGACY\nchar*  gcvt(double, int, char*); // LEGACY\n// per spec: int getsubopt(char** char* const*, char**);\nint    getsubopt(char**, in char**, char**);\nint    grantpt(int);\nchar*  initstate(uint, char*, size_t);\nc_long jrand48(ref ushort[3]);\nchar*  l64a(c_long);\nvoid   lcong48(ref ushort[7]);\nc_long lrand48();\nchar*  mktemp(char*); // LEGACY\nint    mkstemp(char*);\nint    mkdtemp(char*); // Defined in IEEE 1003.1, 2008 Edition\nc_long mrand48();\nc_long nrand48(ref ushort[3]);\nint    posix_openpt(int);\nchar*  ptsname(int);\nint    putenv(char*);\nc_long random();\nchar*  realpath(in char*, char*);\nushort *seed48(ref ushort[3]);\nvoid   setkey(in char*);\nchar*  setstate(in char*);\nvoid   srand48(c_long);\nvoid   srandom(uint);\nint    unlockpt(int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    //WNOHANG     (defined in core.sys.posix.sys.wait)\n    //WUNTRACED   (defined in core.sys.posix.sys.wait)\n    //WEXITSTATUS (defined in core.sys.posix.sys.wait)\n    //WIFEXITED   (defined in core.sys.posix.sys.wait)\n    //WIFSIGNALED (defined in core.sys.posix.sys.wait)\n    //WIFSTOPPED  (defined in core.sys.posix.sys.wait)\n    //WSTOPSIG    (defined in core.sys.posix.sys.wait)\n    //WTERMSIG    (defined in core.sys.posix.sys.wait)\n\n    c_long a64l(in char*);\n    double drand48();\n    char*  ecvt(double, int, int *, int *); // LEGACY\n    double erand48(ref ushort[3]);\n    char*  fcvt(double, int, int *, int *); // LEGACY\n    char*  gcvt(double, int, char*); // LEGACY\n    int    getsubopt(char**, in char**, char**);\n    int    grantpt(int);\n    char*  initstate(uint, char*, size_t);\n    c_long jrand48(ref ushort[3]);\n    char*  l64a(c_long);\n    void   lcong48(ref ushort[7]);\n    c_long lrand48();\n    char*  mktemp(char*); // LEGACY\n    //int    mkstemp(char*);\n    char*  mkdtemp(char*); // Defined in IEEE 1003.1, 2008 Edition\n    c_long mrand48();\n    c_long nrand48(ref ushort[3]);\n    int    posix_openpt(int);\n    char*  ptsname(int);\n    int    putenv(char*);\n    c_long random();\n    char*  realpath(in char*, char*);\n    ushort *seed48(ref ushort[3]);\n    void   setkey(in char*);\n    char*  setstate(in char*);\n    void   srand48(c_long);\n    void   srandom(uint);\n    int    unlockpt(int);\n\n  static if ( __USE_LARGEFILE64 )\n  {\n    int    mkstemp64(char*);\n    alias  mkstemp64 mkstemp;\n  }\n  else\n  {\n    int    mkstemp(char*);\n  }\n}\nelse version (Darwin)\n{\n    //WNOHANG     (defined in core.sys.posix.sys.wait)\n    //WUNTRACED   (defined in core.sys.posix.sys.wait)\n    //WEXITSTATUS (defined in core.sys.posix.sys.wait)\n    //WIFEXITED   (defined in core.sys.posix.sys.wait)\n    //WIFSIGNALED (defined in core.sys.posix.sys.wait)\n    //WIFSTOPPED  (defined in core.sys.posix.sys.wait)\n    //WSTOPSIG    (defined in core.sys.posix.sys.wait)\n    //WTERMSIG    (defined in core.sys.posix.sys.wait)\n\n    c_long a64l(in char*);\n    double drand48();\n    char*  ecvt(double, int, int *, int *); // LEGACY\n    double erand48(ref ushort[3]);\n    char*  fcvt(double, int, int *, int *); // LEGACY\n    char*  gcvt(double, int, char*); // LEGACY\n    int    getsubopt(char**, in char**, char**);\n    int    grantpt(int);\n    char*  initstate(uint, char*, size_t);\n    c_long jrand48(ref ushort[3]);\n    char*  l64a(c_long);\n    void   lcong48(ref ushort[7]);\n    c_long lrand48();\n    char*  mktemp(char*); // LEGACY\n    int    mkstemp(char*);\n    char*  mkdtemp(char*); // Defined in IEEE 1003.1, 2008 Edition\n    c_long mrand48();\n    c_long nrand48(ref ushort[3]);\n    int    posix_openpt(int);\n    char*  ptsname(int);\n    int    putenv(char*);\n    c_long random();\n    char*  realpath(in char*, char*);\n    ushort *seed48(ref ushort[3]);\n    void   setkey(in char*);\n    char*  setstate(in char*);\n    void   srand48(c_long);\n    void   srandom(uint);\n    int    unlockpt(int);\n}\nelse version (FreeBSD)\n{\n    //WNOHANG     (defined in core.sys.posix.sys.wait)\n    //WUNTRACED   (defined in core.sys.posix.sys.wait)\n    //WEXITSTATUS (defined in core.sys.posix.sys.wait)\n    //WIFEXITED   (defined in core.sys.posix.sys.wait)\n    //WIFSIGNALED (defined in core.sys.posix.sys.wait)\n    //WIFSTOPPED  (defined in core.sys.posix.sys.wait)\n    //WSTOPSIG    (defined in core.sys.posix.sys.wait)\n    //WTERMSIG    (defined in core.sys.posix.sys.wait)\n\n    c_long a64l(in char*);\n    double drand48();\n    //char*  ecvt(double, int, int *, int *); // LEGACY\n    double erand48(ref ushort[3]);\n    //char*  fcvt(double, int, int *, int *); // LEGACY\n    //char*  gcvt(double, int, char*); // LEGACY\n    int    getsubopt(char**, in char**, char**);\n    int    grantpt(int);\n    char*  initstate(uint, char*, size_t);\n    c_long jrand48(ref ushort[3]);\n    char*  l64a(c_long);\n    void   lcong48(ref ushort[7]);\n    c_long lrand48();\n    char*  mktemp(char*); // LEGACY\n    int    mkstemp(char*);\n    char*  mkdtemp(char*); // Defined in IEEE 1003.1, 2008 Edition\n    c_long mrand48();\n    c_long nrand48(ref ushort[3]);\n    int    posix_openpt(int);\n    char*  ptsname(int);\n    int    putenv(char*);\n    c_long random();\n    char*  realpath(in char*, char*);\n    ushort *seed48(ref ushort[3]);\n    void   setkey(in char*);\n    char*  setstate(in char*);\n    void   srand48(c_long);\n    void   srandom(uint);\n    int    unlockpt(int);\n}\nelse version (NetBSD)\n{\n    //WNOHANG     (defined in core.sys.posix.sys.wait)\n    //WUNTRACED   (defined in core.sys.posix.sys.wait)\n    //WEXITSTATUS (defined in core.sys.posix.sys.wait)\n    //WIFEXITED   (defined in core.sys.posix.sys.wait)\n    //WIFSIGNALED (defined in core.sys.posix.sys.wait)\n    //WIFSTOPPED  (defined in core.sys.posix.sys.wait)\n    //WSTOPSIG    (defined in core.sys.posix.sys.wait)\n    //WTERMSIG    (defined in core.sys.posix.sys.wait)\n\n    c_long a64l(in char*);\n    double drand48();\n    //char*  ecvt(double, int, int *, int *); // LEGACY\n    double erand48(ref ushort[3]);\n    //char*  fcvt(double, int, int *, int *); // LEGACY\n    //char*  gcvt(double, int, char*); // LEGACY\n    int    getsubopt(char**, in char**, char**);\n    int    grantpt(int);\n    char*  initstate(uint, char*, size_t);\n    c_long jrand48(ref ushort[3]);\n    char*  l64a(c_long);\n    void   lcong48(ref ushort[7]);\n    c_long lrand48();\n    char*  mktemp(char*); // LEGACY\n    int    mkstemp(char*);\n    char*  mkdtemp(char*); // Defined in IEEE 1003.1, 2008 Edition\n    c_long mrand48();\n    c_long nrand48(ref ushort[3]);\n    int    posix_openpt(int);\n    char*  ptsname(int);\n    int    putenv(char*);\n    c_long random();\n    char*  realpath(in char*, char*);\n    ushort *seed48(ref ushort[3]);\n    void   setkey(in char*);\n    char*  setstate(in char*);\n    void   srand48(c_long);\n    void   srandom(uint);\n    int    unlockpt(int);\n}\nelse version (OpenBSD)\n{\n    //WNOHANG     (defined in core.sys.posix.sys.wait)\n    //WUNTRACED   (defined in core.sys.posix.sys.wait)\n    //WEXITSTATUS (defined in core.sys.posix.sys.wait)\n    //WIFEXITED   (defined in core.sys.posix.sys.wait)\n    //WIFSIGNALED (defined in core.sys.posix.sys.wait)\n    //WIFSTOPPED  (defined in core.sys.posix.sys.wait)\n    //WSTOPSIG    (defined in core.sys.posix.sys.wait)\n    //WTERMSIG    (defined in core.sys.posix.sys.wait)\n\n    c_long a64l(in char*);\n    double drand48();\n    //char*  ecvt(double, int, int *, int *); // LEGACY\n    double erand48(ref ushort[3]);\n    //char*  fcvt(double, int, int *, int *); // LEGACY\n    //char*  gcvt(double, int, char*); // LEGACY\n    int    getsubopt(char**, in char**, char**);\n    int    grantpt(int);\n    char*  initstate(uint, char*, size_t);\n    c_long jrand48(ref ushort[3]);\n    char*  l64a(c_long);\n    void   lcong48(ref ushort[7]);\n    c_long lrand48();\n    char*  mktemp(char*); // LEGACY\n    int    mkstemp(char*);\n    char*  mkdtemp(char*); // Defined in IEEE 1003.1, 2008 Edition\n    c_long mrand48();\n    c_long nrand48(ref ushort[3]);\n    int    posix_openpt(int);\n    char*  ptsname(int);\n    int    putenv(char*);\n    c_long random();\n    char*  realpath(in char*, char*);\n    ushort *seed48(ref ushort[3]);\n    // void   setkey(in char*); // not implemented\n    char*  setstate(in char*);\n    void   srand48(c_long);\n    void   srandom(uint);\n    int    unlockpt(int);\n}\nelse version (DragonFlyBSD)\n{\n    //WNOHANG     (defined in core.sys.posix.sys.wait)\n    //WUNTRACED   (defined in core.sys.posix.sys.wait)\n    //WEXITSTATUS (defined in core.sys.posix.sys.wait)\n    //WIFEXITED   (defined in core.sys.posix.sys.wait)\n    //WIFSIGNALED (defined in core.sys.posix.sys.wait)\n    //WIFSTOPPED  (defined in core.sys.posix.sys.wait)\n    //WSTOPSIG    (defined in core.sys.posix.sys.wait)\n    //WTERMSIG    (defined in core.sys.posix.sys.wait)\n\n    c_long a64l(in char*);\n    double drand48();\n    //char*  ecvt(double, int, int *, int *); // LEGACY\n    double erand48(ref ushort[3]);\n    //char*  fcvt(double, int, int *, int *); // LEGACY\n    //char*  gcvt(double, int, char*); // LEGACY\n    int    getsubopt(char**, in char**, char**);\n    int    grantpt(int);\n    char*  initstate(uint, char*, size_t);\n    c_long jrand48(ref ushort[3]);\n    char*  l64a(c_long);\n    void   lcong48(ref ushort[7]);\n    c_long lrand48();\n    char*  mktemp(char*); // LEGACY\n    int    mkstemp(char*);\n    char*  mkdtemp(char*); // Defined in IEEE 1003.1, 2008 Edition\n    c_long mrand48();\n    c_long nrand48(ref ushort[3]);\n    int    posix_openpt(int);\n    char*  ptsname(int);\n    int    putenv(char*);\n    c_long random();\n    char*  realpath(in char*, char*);\n    ushort *seed48(ref ushort[3]);\n    void   setkey(in char*);\n    char*  setstate(in char*);\n    void   srand48(c_long);\n    void   srandom(uint);\n    int    unlockpt(int);\n}\nelse version (CRuntime_Bionic)\n{\n    double  drand48();\n    double  erand48(ref ushort[3]);\n    //int   grantpt(int); defined inline, but seems to do nothing in bionic\n    c_long  jrand48(ref ushort[3]);\n    c_long  lrand48();\n    char*   mktemp(char*); // LEGACY\n    int     mkstemp(char*);\n    char*   mkdtemp(char*); // Defined in IEEE 1003.1, 2008 Edition\n    c_long  mrand48();\n    c_long  nrand48(ref ushort[3]);\n    char*   ptsname(int);\n    int     putenv(in char*);\n    c_long  random() { return lrand48(); }\n    char*   realpath(in char*, char*);\n    ushort* seed48(ref ushort[3]);\n    void    srand48(c_long);\n    void    srandom(uint s) { srand48(s); }\n    int     unlockpt(int);\n}\nelse version (CRuntime_Musl)\n{\n    char*  realpath(in char*, char*);\n    int    putenv(char*);\n    int    mkstemp(char*);\n\n}\nelse version (Solaris)\n{\n    //WNOHANG     (defined in core.sys.posix.sys.wait)\n    //WUNTRACED   (defined in core.sys.posix.sys.wait)\n    //WEXITSTATUS (defined in core.sys.posix.sys.wait)\n    //WIFEXITED   (defined in core.sys.posix.sys.wait)\n    //WIFSIGNALED (defined in core.sys.posix.sys.wait)\n    //WIFSTOPPED  (defined in core.sys.posix.sys.wait)\n    //WSTOPSIG    (defined in core.sys.posix.sys.wait)\n    //WTERMSIG    (defined in core.sys.posix.sys.wait)\n\n    c_long a64l(in char*);\n    double drand48();\n    char*  ecvt(double, int, int *, int *); // LEGACY\n    double erand48(ref ushort[3]);\n    char*  fcvt(double, int, int *, int *); // LEGACY\n    char*  gcvt(double, int, char*); // LEGACY\n    int    getsubopt(char**, in char**, char**);\n    int    grantpt(int);\n    char*  initstate(uint, char*, size_t);\n    c_long jrand48(ref ushort[3]);\n    char*  l64a(c_long);\n    void   lcong48(ref ushort[7]);\n    c_long lrand48();\n    char*  mktemp(char*); // LEGACY\n    //int    mkstemp(char*);\n    char*  mkdtemp(char*); // Defined in IEEE 1003.1, 2008 Edition\n    c_long mrand48();\n    c_long nrand48(ref ushort[3]);\n    int    posix_openpt(int);\n    char*  ptsname(int);\n    int    putenv(char*);\n    c_long random();\n    char*  realpath(in char*, char*);\n    ushort *seed48(ref ushort[3]);\n    void   setkey(in char*);\n    char*  setstate(in char*);\n    void   srand48(c_long);\n    void   srandom(uint);\n    int    unlockpt(int);\n\n    version (D_LP64)\n    {\n        int mkstemp(char*);\n\n        static if ( __USE_LARGEFILE64 )\n            alias mkstemp mkstemp64;\n    }\n    else\n    {\n        int mkstemp64(char*);\n\n        static if ( __USE_LARGEFILE64 )\n            alias mkstemp64 mkstemp;\n        else\n            int mkstemp(char*);\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    c_long a64l(in char*);\n    double drand48();\n    char*  ecvt(double, int, int *, int *);\n    double erand48(ref ushort[3]);\n    char*  fcvt(double, int, int *, int *);\n    char*  gcvt(double, int, char*);\n    int    getsubopt(char**, in char**, char**);\n    int    grantpt(int);\n    char*  initstate(uint, char*, size_t);\n    c_long jrand48(ref ushort[3]);\n    char*  l64a(c_long);\n    void   lcong48(ref ushort[7]);\n    c_long lrand48();\n    char*  mktemp(char*);\n    char*  mkdtemp(char*);\n    c_long mrand48();\n    c_long nrand48(ref ushort[3]);\n    int    posix_openpt(int);\n    char*  ptsname(int);\n    int    putenv(char*);\n    c_long random();\n    char*  realpath(in char*, char*);\n    ushort* seed48(ref ushort[3]);\n    void   setkey(in char*);\n    char*  setstate(in char*);\n    void   srand48(c_long);\n    void   srandom(uint);\n    int    unlockpt(int);\n\n  static if ( __USE_LARGEFILE64 )\n  {\n    int    mkstemp64(char*);\n    alias  mkstemp64 mkstemp;\n  }\n  else\n  {\n    int    mkstemp(char*);\n  }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/filio.d",
    "content": "/**\n * D header file for POSIX.\n *\n * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n */\n\nmodule core.sys.posix.sys.filio;\n\nimport core.sys.posix.sys.ioccom;\n\nversion (Posix):\n\nnothrow @nogc:\n\nversion (OSX)\n{\n    // File-descriptor ioctl's\n    enum uint FIOCLEX   = _IO('f', 1);         // set close on exec on fd\n    enum uint FIONCLEX  = _IO('f', 2);         // remove close on exec\n    enum uint FIONREAD  = _IOR!(int)('f', 127); // get # bytes to read\n    enum uint FIONBIO   = _IOW!(int)('f', 126); // set/clear non-blocking i/o\n    enum uint FIOASYNC  = _IOW!(int)('f', 125); // set/clear async i/o\n    enum uint FIOSETOWN = _IOW!(int)('f', 124); // set owner\n    enum uint FIOGETOWN = _IOR!(int)('f', 123); // get owner\n    enum uint FIODTYPE  = _IOR!(int)('f', 122); // get d_type\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/ioccom.d",
    "content": "/**\n * D header file for POSIX.\n *\n * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n */\n\nmodule core.sys.posix.sys.ioccom;\n\nversion (Posix):\n\nnothrow @nogc:\n\nversion (OSX)\n{\n    /* OSX ioctl's (based on FreeBSD) encode the command in the lower 16-bits\n     * and the size of any in/out parameters in the lower 13 bits of the upper\n     * 16-bits of a 32 bit unsigned integer. The high 3 bits of the upper\n     * 16-bits encode the in/out status of the parameter.\n     */\n    enum uint IOCPARM_MASK = 0x1fff; // parameter length, at most 13 bits\n    uint IOCPARM_LEN(uint x) // to extract the encoded parameter length\n    {\n        return ((x >> 16) & IOCPARM_MASK);\n    }\n    uint IOCBASECMD(uint x) // to extract the encoded command\n    {\n        return (x & ~(IOCPARM_MASK << 16));\n    }\n    uint IOCGROUP(uint x) // to extract the encoded group\n    {\n        return ((x >> 8) & 0xff);\n    }\n\n    enum uint IOCPARM_MAX = (IOCPARM_MASK + 1); // max size of ioctl args\n\n    enum uint IOC_VOID = 0x20000000; // no parameters\n    enum uint IOC_OUT = 0x40000000; // copy parameters back\n    enum uint IOC_IN = 0x80000000; // copy parameters into\n    enum uint IOC_INOUT = (IOC_IN | IOC_OUT); // copy parameter into and get back\n    enum uint IOC_DIRMASK = 0xe0000000; // mask to extract above direction parameters\n\n    // encode the ioctl info into 32 bits\n    uint _IOC(T=typeof(null))(uint inorout, uint group, uint num, size_t len)\n    {\n        return (inorout | ((len & IOCPARM_MASK) << 16) | (group << 8) | num);\n    }\n\n    // encode a command with no parameters\n    uint _IO(char g, int n)\n    {\n        return _IOC(IOC_VOID, cast(uint)g, cast(uint)n, cast(size_t)0);\n    }\n    // encode a command that returns info\n    uint _IOR(T)(char g, int n)\n    {\n        return _IOC!(T)(IOC_OUT, cast(uint)g, cast(uint)n, T.sizeof);\n    }\n    // encode a command that takes info\n    uint _IOW(T)(char g, int n)\n    {\n        return _IOC!(T)(IOC_IN, cast(uint)g, cast(uint)n, T.sizeof);\n    }\n    // encode a command that takes info and returns info\n    uint _IOWR(T)(char g, int n)\n    {\n        return _IOC!(T)(IOC_INOUT, cast(uint)g, cast(uint)n, T.sizeof);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/ioctl.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Alex Rønne Petersen 2011 - 2012.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Alex Rønne Petersen 2011 - 2012.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sys.ioctl;\n\nimport core.stdc.config;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\n\nextern (C) nothrow @nogc:\n\nversion (CRuntime_Glibc)\n{\n    import core.sys.posix.termios; // tcflag_t, speed_t, cc_t\n\n    enum _IOC_NRBITS = 8;\n    enum _IOC_TYPEBITS = 8;\n    enum _IOC_SIZEBITS = 14;\n    enum _IOC_DIRBITS = 2;\n\n    enum _IOC_NRMASK = (1 << _IOC_NRBITS) - 1;\n    enum _IOC_TYPEMASK = (1 << _IOC_TYPEBITS) - 1;\n    enum _IOC_SIZEMASK = (1 << _IOC_SIZEBITS) - 1;\n    enum _IOC_DIRMASK = (1 << _IOC_DIRBITS) - 1;\n\n    enum _IOC_NRSHIFT = 0;\n    enum _IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS;\n    enum _IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS;\n    enum _IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS;\n\n    enum _IOC_NONE = 0;\n    enum _IOC_WRITE = 1;\n    enum _IOC_READ = 2;\n\n    extern (D) int _IOC(T = typeof(null))(int dir, int type, int nr)\n    {\n        return (dir << _IOC_DIRSHIFT) |\n               (type << _IOC_TYPESHIFT) |\n               (nr << _IOC_NRSHIFT) |\n               (is(T == typeof(null)) ? 0 : T.sizeof << _IOC_SIZESHIFT);\n    }\n\n    extern (D) int _IO(int type, int nr)\n    {\n        return _IOC(_IOC_NONE, type, nr);\n    }\n\n    extern (D) int _IOR(T)(int type, int nr)\n    {\n        return _IOC!T(_IOC_READ, type, nr);\n    }\n\n    extern (D) int _IOW(T)(int type, int nr)\n    {\n        return _IOC!T(_IOC_WRITE, type, nr);\n    }\n\n    extern (D) int _IOWR(T)(int type, int nr)\n    {\n        return _IOC!T(_IOC_READ | _IOC_WRITE, type, nr);\n    }\n\n    extern (D) int _IOC_DIR(int nr)\n    {\n        return (nr >> _IOC_DIRSHIFT) & _IOC_DIRMASK;\n    }\n\n    extern (D) int _IOC_TYPE(int nr)\n    {\n        return (nr >> _IOC_TYPESHIFT) & _IOC_TYPEMASK;\n    }\n\n    extern (D) int _IOC_NR(int nr)\n    {\n        return (nr >> _IOC_NRSHIFT) & _IOC_NRMASK;\n    }\n\n    extern (D) int _IOC_SIZE(int nr)\n    {\n        return (nr >> _IOC_SIZESHIFT) & _IOC_SIZEMASK;\n    }\n\n    enum IOC_IN = _IOC_WRITE << _IOC_DIRSHIFT;\n    enum IOC_OUT = _IOC_READ << _IOC_DIRSHIFT;\n    enum IOC_INOUT = (_IOC_READ | _IOC_WRITE) << _IOC_DIRSHIFT;\n    enum IOCSIZE_MASK = _IOC_SIZEMASK << _IOC_DIRSHIFT;\n    enum IOCSIZE_SHIFT = _IOC_SIZESHIFT;\n\n    enum NCCS = 19;\n\n    struct termios2\n    {\n        tcflag_t c_iflag;\n        tcflag_t c_oflag;\n        tcflag_t c_cflag;\n        tcflag_t c_lflag;\n        cc_t c_line;\n        cc_t[NCCS] c_cc;\n        speed_t c_ispeed;\n        speed_t c_ospeed;\n    }\n\n    struct winsize\n    {\n        ushort ws_row;\n        ushort ws_col;\n        ushort ws_xpixel;\n        ushort ws_ypixel;\n    }\n\n    enum NCC = 8;\n\n    struct termio\n    {\n        ushort c_iflag;\n        ushort c_oflag;\n        ushort c_cflag;\n        ushort c_lflag;\n        ubyte c_line;\n        ubyte[NCC] c_cc;\n    }\n\n    enum TIOCM_LE = 0x001;\n    enum TIOCM_DTR = 0x002;\n    enum TIOCM_RTS = 0x004;\n    enum TIOCM_ST = 0x008;\n    enum TIOCM_SR = 0x010;\n    enum TIOCM_CTS = 0x020;\n    enum TIOCM_CAR = 0x040;\n    enum TIOCM_RNG = 0x080;\n    enum TIOCM_DSR = 0x100;\n    enum TIOCM_CD = TIOCM_CAR;\n    enum TIOCM_RI = TIOCM_RNG;\n\n    enum N_TTY = 0;\n    enum N_SLIP = 1;\n    enum N_MOUSE = 2;\n    enum N_PPP = 3;\n    enum N_STRIP = 4;\n    enum N_AX25 = 5;\n    enum N_X25 = 6;\n    enum N_6PACK = 7;\n    enum N_MASC = 8;\n    enum N_R3964 = 9;\n    enum N_PROFIBUS_FDL = 10;\n    enum N_IRDA = 11;\n    enum N_SMSBLOCK = 12;\n    enum N_HDLC = 13;\n    enum N_SYNC_PPP = 14;\n    enum N_HCI = 15;\n\n    enum TCGETS = 0x5401;\n    enum TCSETS = 0x5402;\n    enum TCSETSW = 0x5403;\n    enum TCSETSF = 0x5404;\n    enum TCGETA = 0x5405;\n    enum TCSETA = 0x5406;\n    enum TCSETAW = 0x5407;\n    enum TCSETAF = 0x5408;\n    enum TCSBRK = 0x5409;\n    enum TCXONC = 0x540A;\n    enum TCFLSH = 0x540B;\n    enum TIOCEXCL = 0x540C;\n    enum TIOCNXCL = 0x540D;\n    enum TIOCSCTTY = 0x540E;\n    enum TIOCGPGRP = 0x540F;\n    enum TIOCSPGRP = 0x5410;\n    enum TIOCOUTQ = 0x5411;\n    enum TIOCSTI = 0x5412;\n    enum TIOCGWINSZ = 0x5413;\n    enum TIOCSWINSZ = 0x5414;\n    enum TIOCMGET = 0x5415;\n    enum TIOCMBIS = 0x5416;\n    enum TIOCMBIC = 0x5417;\n    enum TIOCMSET = 0x5418;\n    enum TIOCGSOFTCAR = 0x5419;\n    enum TIOCSSOFTCAR = 0x541A;\n    enum FIONREAD = 0x541B;\n    enum TIOCINQ = FIONREAD;\n    enum TIOCLINUX = 0x541C;\n    enum TIOCCONS = 0x541D;\n    enum TIOCGSERIAL = 0x541E;\n    enum TIOCSSERIAL = 0x541F;\n    enum TIOCPKT = 0x5420;\n    enum FIONBIO = 0x5421;\n    enum TIOCNOTTY = 0x5422;\n    enum TIOCSETD = 0x5423;\n    enum TIOCGETD = 0x5424;\n    enum TCSBRKP = 0x5425;\n    enum TIOCSBRK = 0x5427;\n    enum TIOCCBRK = 0x5428;\n    enum TIOCGSID = 0x5429;\n\n    enum TCGETS2 = _IOR!termios2('T', 0x2A);\n    enum TCSETS2 = _IOR!termios2('T', 0x2B);\n    enum TCSETSW2 = _IOW!termios2('T', 0x2C);\n    enum TCSETSF2 = _IOW!termios2('T', 0x2D);\n\n    enum TIOCGRS485 = 0x542E;\n    enum TIOCSRS485 = 0x542F;\n\n    enum TIOCGPTN   = _IOR!uint('T', 0x30);\n    enum TIOCSPTLCK = _IOW!int('T', 0x31);\n    enum TIOCGDEV   = _IOR!uint('T', 0x32);\n\n    enum TCGETX = 0x5432;\n    enum TCSETX = 0x5433;\n    enum TCSETXF = 0x5434;\n    enum TCSETXW = 0x5435;\n\n    enum TIOCSIG = _IOW!int('T', 0x36);\n\n    enum TIOCVHANGUP = 0x5437;\n\n    enum FIONCLEX = 0x5450;\n    enum FIOCLEX = 0x5451;\n    enum FIOASYNC = 0x5452;\n    enum TIOCSERCONFIG = 0x5453;\n    enum TIOCSERGWILD = 0x5454;\n    enum TIOCSERSWILD = 0x5455;\n    enum TIOCGLCKTRMIOS = 0x5456;\n    enum TIOCSLCKTRMIOS = 0x5457;\n    enum TIOCSERGSTRUCT = 0x5458;\n    enum TIOCSERGETLSR = 0x5459;\n    enum TIOCSERGETMULTI = 0x545A;\n    enum TIOCSERSETMULTI = 0x545B;\n\n    enum TIOCMIWAIT = 0x545C;\n    enum TIOCGICOUNT = 0x545D;\n\n    enum FIOQSIZE = 0x5460;\n\n    enum TIOCPKT_DATA = 0;\n    enum TIOCPKT_FLUSHREAD = 1;\n    enum TIOCPKT_FLUSHWRITE = 2;\n    enum TIOCPKT_STOP = 4;\n    enum TIOCPKT_START = 8;\n    enum TIOCPKT_NOSTOP = 16;\n    enum TIOCPKT_DOSTOP = 32;\n    enum TIOCPKT_IOCTL = 64;\n\n    enum TIOCSER_TEMT = 0x01;\n\n    enum SIOCADDRT = 0x890B;\n    enum SIOCDELRT = 0x890C;\n    enum SIOCRTMSG = 0x890D;\n\n    enum SIOCGIFNAME = 0x8910;\n    enum SIOCSIFLINK = 0x8911;\n    enum SIOCGIFCONF = 0x8912;\n    enum SIOCGIFFLAGS = 0x8913;\n    enum SIOCSIFFLAGS = 0x8914;\n    enum SIOCGIFADDR = 0x8915;\n    enum SIOCSIFADDR = 0x8916;\n    enum SIOCGIFDSTADDR = 0x8917;\n    enum SIOCSIFDSTADDR = 0x8918;\n    enum SIOCGIFBRDADDR = 0x8919;\n    enum SIOCSIFBRDADDR = 0x891a;\n    enum SIOCGIFNETMASK = 0x891b;\n    enum SIOCSIFNETMASK = 0x891c;\n    enum SIOCGIFMETRIC = 0x891d;\n    enum SIOCSIFMETRIC = 0x891e;\n    enum SIOCGIFMEM = 0x891f;\n    enum SIOCSIFMEM = 0x8920;\n    enum SIOCGIFMTU = 0x8921;\n    enum SIOCSIFMTU = 0x8922;\n    enum SIOCSIFNAME = 0x8923;\n    enum SIOCSIFHWADDR = 0x8924;\n    enum SIOCGIFENCAP = 0x8925;\n    enum SIOCSIFENCAP = 0x8926;\n    enum SIOCGIFHWADDR = 0x8927;\n    enum SIOCGIFSLAVE = 0x8929;\n    enum SIOCSIFSLAVE = 0x8930;\n    enum SIOCADDMULTI = 0x8931;\n    enum SIOCDELMULTI = 0x8932;\n    enum SIOCGIFINDEX = 0x8933;\n    enum SIOGIFINDEX = SIOCGIFINDEX;\n    enum SIOCSIFPFLAGS = 0x8934;\n    enum SIOCGIFPFLAGS = 0x8935;\n    enum SIOCDIFADDR = 0x8936;\n    enum SIOCSIFHWBROADCAST = 0x8937;\n    enum SIOCGIFCOUNT = 0x8938;\n\n    enum SIOCGIFBR = 0x8940;\n    enum SIOCSIFBR = 0x8941;\n\n    enum SIOCGIFTXQLEN = 0x8942;\n    enum SIOCSIFTXQLEN = 0x8943;\n\n    enum SIOCDARP = 0x8953;\n    enum SIOCGARP = 0x8954;\n    enum SIOCSARP = 0x8955;\n\n    enum SIOCDRARP = 0x8960;\n    enum SIOCGRARP = 0x8961;\n    enum SIOCSRARP = 0x8962;\n\n    enum SIOCGIFMAP = 0x8970;\n    enum SIOCSIFMAP = 0x8971;\n\n    enum SIOCADDDLCI = 0x8980;\n    enum SIOCDELDLCI = 0x8981;\n\n    enum SIOCDEVPRIVATE = 0x89F0;\n\n    enum SIOCPROTOPRIVATE = 0x89E0;\n\n    int ioctl(int __fd, c_ulong __request, ...);\n}\nelse version (Darwin)\n{\n    import core.sys.posix.termios; // termios\n    import core.sys.posix.sys.time; // timeval\n\n    public import core.sys.posix.sys.ttycom; // Terminal related ioctls\n\n    struct ttysize\n    {\n        ushort ts_lines;\n        ushort ts_cols;\n        ushort ts_xxx;\n        ushort ts_yyy;\n    }\n\n    enum uint TIOCGSIZE = TIOCGWINSZ;\n    enum uint TIOCSSIZE = TIOCSWINSZ;\n\n    public import core.sys.posix.sys.filio; // File related ioctls\n\n    int ioctl(int fildes, c_ulong request, ...);\n}\nelse version (FreeBSD)\n{\n    struct fiodgname_arg\n    {\n        int len;\n        void* buf;\n    }\n\n    struct winsize\n    {\n        ushort ws_row;\n        ushort ws_col;\n        ushort ws_xpixel;\n        ushort ws_ypixel;\n    }\n\n    int ioctl(int, c_ulong, ...);\n}\nelse version (NetBSD)\n{\n    struct winsize\n    {\n        ushort ws_row;\n        ushort ws_col;\n        ushort ws_xpixel;\n        ushort ws_ypixel;\n    }\n\n    int ioctl(int, c_ulong, ...);\n}\nelse version (DragonFlyBSD)\n{\n    struct fiodgname_arg\n    {\n        int len;\n        void* buf;\n    }\n\n    struct winsize\n    {\n        ushort ws_row;\n        ushort ws_col;\n        ushort ws_xpixel;\n        ushort ws_ypixel;\n    }\n\n    int ioctl(int, c_ulong, ...);\n}\nelse version (Solaris)\n{\n    int ioctl(int fildes, int request, ...);\n}\nelse version (CRuntime_Bionic)\n{\n    int ioctl(int, int, ...);\n}\nelse version (CRuntime_Musl)\n{\n\n}\nelse version (CRuntime_UClibc)\n{\n    import core.sys.posix.termios;\n\n    enum _IOC_NRBITS = 8;\n    enum _IOC_TYPEBITS = 8;\n    enum _IOC_SIZEBITS = 14;\n    enum _IOC_DIRBITS = 2;\n\n    enum _IOC_NRMASK = (1 << _IOC_NRBITS) - 1;\n    enum _IOC_TYPEMASK = (1 << _IOC_TYPEBITS) - 1;\n    enum _IOC_SIZEMASK = (1 << _IOC_SIZEBITS) - 1;\n    enum _IOC_DIRMASK = (1 << _IOC_DIRBITS) - 1;\n\n    enum _IOC_NRSHIFT = 0;\n    enum _IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS;\n    enum _IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS;\n    enum _IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS;\n\n    enum _IOC_NONE = 0;\n    enum _IOC_WRITE = 1;\n    enum _IOC_READ = 2;\n\n    extern (D) int _IOC(T = typeof(null))(int dir, int type, int nr)\n    {\n        return (dir << _IOC_DIRSHIFT) |\n               (type << _IOC_TYPESHIFT) |\n               (nr << _IOC_NRSHIFT) |\n               (is(T == typeof(null)) ? 0 : T.sizeof << _IOC_SIZESHIFT);\n    }\n\n    extern (D) int _IO(int type, int nr)\n    {\n        return _IOC(_IOC_NONE, type, nr);\n    }\n\n    extern (D) int _IOR(T)(int type, int nr)\n    {\n        return _IOC!T(_IOC_READ, type, nr);\n    }\n\n    extern (D) int _IOW(T)(int type, int nr)\n    {\n        return _IOC!T(_IOC_WRITE, type, nr);\n    }\n\n    extern (D) int _IOWR(T)(int type, int nr)\n    {\n        return _IOC!T(_IOC_READ | _IOC_WRITE, type, nr);\n    }\n\n    extern (D) int _IOR_BAD(T)(int type, int nr)\n    {\n        return _IOC!T(_IOC_READ, type, nr);\n    }\n\n    extern (D) int _IOW_BAD(T)(int type, int nr)\n    {\n        return _IOC!T(_IOC_WRITE, type, nr);\n    }\n\n    extern (D) int _IORW_BAD(T)(int type, int nr)\n    {\n        return _IOC!T(_IOC_READ | _IOC_WRITE, type, nr);\n    }\n\n    extern (D) int _IOC_DIR(int nr)\n    {\n        return (nr >> _IOC_DIRSHIFT) & _IOC_DIRMASK;\n    }\n\n    extern (D) int _IOC_TYPE(int nr)\n    {\n        return (nr >> _IOC_TYPESHIFT) & _IOC_TYPEMASK;\n    }\n\n    extern (D) int _IOC_NR(int nr)\n    {\n        return (nr >> _IOC_NRSHIFT) & _IOC_NRMASK;\n    }\n\n    extern (D) int _IOC_SIZE(int nr)\n    {\n        return (nr >> _IOC_SIZESHIFT) & _IOC_SIZEMASK;\n    }\n\n    enum IOC_IN = _IOC_WRITE << _IOC_DIRSHIFT;\n    enum IOC_OUT = _IOC_READ << _IOC_DIRSHIFT;\n    enum IOC_INOUT = (_IOC_READ | _IOC_WRITE) << _IOC_DIRSHIFT;\n    enum IOCSIZE_MASK = _IOC_SIZEMASK << _IOC_DIRSHIFT;\n    enum IOCSIZE_SHIFT = _IOC_SIZESHIFT;\n\n    enum NCCS = 19;\n\n    struct termios\n    {\n        tcflag_t c_iflag;\n        tcflag_t c_oflag;\n        tcflag_t c_cflag;\n        tcflag_t c_lflag;\n        cc_t c_line;\n        cc_t[NCCS] c_cc;\n    }\n\n    struct termios2\n    {\n        tcflag_t c_iflag;\n        tcflag_t c_oflag;\n        tcflag_t c_cflag;\n        tcflag_t c_lflag;\n        cc_t c_line;\n        cc_t[NCCS] c_cc;\n        speed_t c_ispeed;\n        speed_t c_ospeed;\n    }\n\n    alias termios2 ktermios;\n\n    struct winsize\n    {\n        ushort ws_row;\n        ushort ws_col;\n        ushort ws_xpixel;\n        ushort ws_ypixel;\n    }\n\n    enum NCC = 8;\n\n    struct termio\n    {\n        ushort c_iflag;\n        ushort c_oflag;\n        ushort c_cflag;\n        ushort c_lflag;\n        ubyte c_line;\n        ubyte[NCC] c_cc;\n    }\n\n    enum TIOCM_LE = 0x001;\n    enum TIOCM_DTR = 0x002;\n    enum TIOCM_RTS = 0x004;\n    enum TIOCM_ST = 0x008;\n    enum TIOCM_SR = 0x010;\n    enum TIOCM_CTS = 0x020;\n    enum TIOCM_CAR = 0x040;\n    enum TIOCM_RNG = 0x080;\n    enum TIOCM_DSR = 0x100;\n    enum TIOCM_CD = TIOCM_CAR;\n    enum TIOCM_RI = TIOCM_RNG;\n\n    enum N_TTY = 0;\n    enum N_SLIP = 1;\n    enum N_MOUSE = 2;\n    enum N_PPP = 3;\n    enum N_STRIP = 4;\n    enum N_AX25 = 5;\n    enum N_X25 = 6;\n    enum N_6PACK = 7;\n    enum N_MASC = 8;\n    enum N_R3964 = 9;\n    enum N_PROFIBUS_FDL = 10;\n    enum N_IRDA = 11;\n    enum N_SMSBLOCK = 12;\n    enum N_HDLC = 13;\n    enum N_SYNC_PPP = 14;\n    enum N_HCI = 15;\n\n    enum TCGETS = 0x5401;\n    enum TCSETS = 0x5402;\n    enum TCSETSW = 0x5403;\n    enum TCSETSF = 0x5404;\n    enum TCGETA = 0x5405;\n    enum TCSETA = 0x5406;\n    enum TCSETAW = 0x5407;\n    enum TCSETAF = 0x5408;\n    enum TCSBRK = 0x5409;\n    enum TCXONC = 0x540A;\n    enum TCFLSH = 0x540B;\n    enum TIOCEXCL = 0x540C;\n    enum TIOCNXCL = 0x540D;\n    enum TIOCSCTTY = 0x540E;\n    enum TIOCGPGRP = 0x540F;\n    enum TIOCSPGRP = 0x5410;\n    enum TIOCOUTQ = 0x5411;\n    enum TIOCSTI = 0x5412;\n    enum TIOCGWINSZ = 0x5413;\n    enum TIOCSWINSZ = 0x5414;\n    enum TIOCMGET = 0x5415;\n    enum TIOCMBIS = 0x5416;\n    enum TIOCMBIC = 0x5417;\n    enum TIOCMSET = 0x5418;\n    enum TIOCGSOFTCAR = 0x5419;\n    enum TIOCSSOFTCAR = 0x541A;\n    enum FIONREAD = 0x541B;\n    enum TIOCINQ = FIONREAD;\n    enum TIOCLINUX = 0x541C;\n    enum TIOCCONS = 0x541D;\n    enum TIOCGSERIAL = 0x541E;\n    enum TIOCSSERIAL = 0x541F;\n    enum TIOCPKT = 0x5420;\n    enum FIONBIO = 0x5421;\n    enum TIOCNOTTY = 0x5422;\n    enum TIOCSETD = 0x5423;\n    enum TIOCGETD = 0x5424;\n    enum TCSBRKP = 0x5425;\n    enum TIOCSBRK = 0x5427;\n    enum TIOCCBRK = 0x5428;\n    enum TIOCGSID = 0x5429;\n\n    enum TCGETS2 = _IOR!termios2('T', 0x2A);\n    enum TCSETS2 = _IOR!termios2('T', 0x2B);\n    enum TCSETSW2 = _IOW!termios2('T', 0x2C);\n    enum TCSETSF2 = _IOW!termios2('T', 0x2D);\n\n    enum TIOCGRS485 = 0x542E;\n    enum TIOCSRS485 = 0x542F;\n\n    enum TIOCGPTN   = _IOR!uint('T', 0x30);\n    enum TIOCSPTLCK = _IOW!int('T', 0x31);\n    enum TIOCGDEV   = _IOR!uint('T', 0x32);\n\n    enum TCGETX = 0x5432;\n    enum TCSETX = 0x5433;\n    enum TCSETXF = 0x5434;\n    enum TCSETXW = 0x5435;\n\n    enum TIOCSIG = _IOW!int('T', 0x36);\n\n    enum TIOCVHANGUP = 0x5437;\n\n    enum FIONCLEX = 0x5450;\n    enum FIOCLEX = 0x5451;\n    enum FIOASYNC = 0x5452;\n    enum TIOCSERCONFIG = 0x5453;\n    enum TIOCSERGWILD = 0x5454;\n    enum TIOCSERSWILD = 0x5455;\n    enum TIOCGLCKTRMIOS = 0x5456;\n    enum TIOCSLCKTRMIOS = 0x5457;\n    enum TIOCSERGSTRUCT = 0x5458;\n    enum TIOCSERGETLSR = 0x5459;\n    enum TIOCSERGETMULTI = 0x545A;\n    enum TIOCSERSETMULTI = 0x545B;\n\n    enum TIOCMIWAIT = 0x545C;\n    enum TIOCGICOUNT = 0x545D;\n\n    enum FIOQSIZE = 0x5460;\n\n    enum TIOCPKT_DATA = 0;\n    enum TIOCPKT_FLUSHREAD = 1;\n    enum TIOCPKT_FLUSHWRITE = 2;\n    enum TIOCPKT_STOP = 4;\n    enum TIOCPKT_START = 8;\n    enum TIOCPKT_NOSTOP = 16;\n    enum TIOCPKT_DOSTOP = 32;\n    enum TIOCPKT_IOCTL = 64;\n\n    enum TIOCSER_TEMT = 0x01;\n\n    enum SIOCADDRT = 0x890B;\n    enum SIOCDELRT = 0x890C;\n    enum SIOCRTMSG = 0x890D;\n\n    enum SIOCGIFNAME = 0x8910;\n    enum SIOCSIFLINK = 0x8911;\n    enum SIOCGIFCONF = 0x8912;\n    enum SIOCGIFFLAGS = 0x8913;\n    enum SIOCSIFFLAGS = 0x8914;\n    enum SIOCGIFADDR = 0x8915;\n    enum SIOCSIFADDR = 0x8916;\n    enum SIOCGIFDSTADDR = 0x8917;\n    enum SIOCSIFDSTADDR = 0x8918;\n    enum SIOCGIFBRDADDR = 0x8919;\n    enum SIOCSIFBRDADDR = 0x891a;\n    enum SIOCGIFNETMASK = 0x891b;\n    enum SIOCSIFNETMASK = 0x891c;\n    enum SIOCGIFMETRIC = 0x891d;\n    enum SIOCSIFMETRIC = 0x891e;\n    enum SIOCGIFMEM = 0x891f;\n    enum SIOCSIFMEM = 0x8920;\n    enum SIOCGIFMTU = 0x8921;\n    enum SIOCSIFMTU = 0x8922;\n    enum SIOCSIFNAME = 0x8923;\n    enum SIOCSIFHWADDR = 0x8924;\n    enum SIOCGIFENCAP = 0x8925;\n    enum SIOCSIFENCAP = 0x8926;\n    enum SIOCGIFHWADDR = 0x8927;\n    enum SIOCGIFSLAVE = 0x8929;\n    enum SIOCSIFSLAVE = 0x8930;\n    enum SIOCADDMULTI = 0x8931;\n    enum SIOCDELMULTI = 0x8932;\n    enum SIOCGIFINDEX = 0x8933;\n    enum SIOGIFINDEX = SIOCGIFINDEX;\n    enum SIOCSIFPFLAGS = 0x8934;\n    enum SIOCGIFPFLAGS = 0x8935;\n    enum SIOCDIFADDR = 0x8936;\n    enum SIOCSIFHWBROADCAST = 0x8937;\n    enum SIOCGIFCOUNT = 0x8938;\n\n    enum SIOCGIFBR = 0x8940;\n    enum SIOCSIFBR = 0x8941;\n\n    enum SIOCGIFTXQLEN = 0x8942;\n    enum SIOCSIFTXQLEN = 0x8943;\n\n    enum SIOCDARP = 0x8953;\n    enum SIOCGARP = 0x8954;\n    enum SIOCSARP = 0x8955;\n\n    enum SIOCDRARP = 0x8960;\n    enum SIOCGRARP = 0x8961;\n    enum SIOCSRARP = 0x8962;\n\n    enum SIOCGIFMAP = 0x8970;\n    enum SIOCSIFMAP = 0x8971;\n\n    enum SIOCADDDLCI = 0x8980;\n    enum SIOCDELDLCI = 0x8981;\n\n    enum SIOCDEVPRIVATE = 0x89F0;\n\n    enum SIOCPROTOPRIVATE = 0x89E0;\n\n    int ioctl(int __fd, c_ulong __request, ...);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/ipc.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sys.ipc;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types; // for uid_t, gid_t, mode_t, key_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// XOpen (XSI)\n//\n/*\nstruct ipc_perm\n{\n    uid_t    uid;\n    gid_t    gid;\n    uid_t    cuid;\n    gid_t    cgid;\n    mode_t   mode;\n}\n\nIPC_CREAT\nIPC_EXCL\nIPC_NOWAIT\n\nIPC_PRIVATE\n\nIPC_RMID\nIPC_SET\nIPC_STAT\n\nkey_t ftok(in char*, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct ipc_perm\n    {\n        key_t   __key;\n        uid_t   uid;\n        gid_t   gid;\n        uid_t   cuid;\n        gid_t   cgid;\n        ushort  mode;\n        ushort  __pad1;\n        ushort  __seq;\n        ushort  __pad2;\n        c_ulong __unused1;\n        c_ulong __unused2;\n    }\n\n    enum IPC_CREAT      = 0x0200; // 01000\n    enum IPC_EXCL       = 0x0400; // 02000\n    enum IPC_NOWAIT     = 0x0800; // 04000\n\n    enum key_t IPC_PRIVATE = 0;\n\n    enum IPC_RMID       = 0;\n    enum IPC_SET        = 1;\n    enum IPC_STAT       = 2;\n\n    key_t ftok(in char*, int);\n}\nelse version (Darwin)\n{\n\n}\nelse version (FreeBSD)\n{\n    struct ipc_perm_old // <= FreeBSD7\n    {\n        ushort cuid;\n        ushort cguid;\n        ushort uid;\n        ushort gid;\n        ushort mode;\n        ushort seq;\n        key_t key;\n    }\n\n    struct ipc_perm\n    {\n        uid_t   cuid;\n        gid_t   cgid;\n        uid_t   uid;\n        gid_t   gid;\n        mode_t  mode;\n        ushort  seq;\n        key_t   key;\n    }\n\n    enum IPC_CREAT      = 0x0200; // 01000\n    enum IPC_EXCL       = 0x0400; // 02000\n    enum IPC_NOWAIT     = 0x0800; // 04000\n\n    enum key_t IPC_PRIVATE = 0;\n\n    enum IPC_RMID       = 0;\n    enum IPC_SET        = 1;\n    enum IPC_STAT       = 2;\n\n    key_t ftok(in char*, int);\n}\nelse version (NetBSD)\n{\n    struct ipc_perm\n    {\n        uid_t   cuid;\n        gid_t   cgid;\n        uid_t   uid;\n        gid_t   gid;\n        mode_t  mode;\n        ushort  seq;\n        key_t   key;\n    }\n\n    enum IPC_CREAT      = 0x0100; // 01000\n    enum IPC_EXCL       = 0x0200; // 02000\n    enum IPC_NOWAIT     = 0x0400; // 04000\n\n    enum key_t IPC_PRIVATE = 0;\n\n    enum IPC_RMID       = 0;\n    enum IPC_SET        = 1;\n    enum IPC_STAT       = 2;\n\n    key_t ftok(in char*, int);\n}\nelse version (DragonFlyBSD)\n{\n    struct ipc_perm\n    {\n        uid_t   cuid;\n        gid_t   cgid;\n        uid_t   uid;\n        gid_t   gid;\n        mode_t  mode;\n        ushort  seq;\n        key_t   key;\n    }\n\n    enum IPC_CREAT      = 0x0200; // 01000\n    enum IPC_EXCL       = 0x0400; // 02000\n    enum IPC_NOWAIT     = 0x0800; // 04000\n\n    enum key_t IPC_PRIVATE = 0;\n\n    enum IPC_RMID       = 0;\n    enum IPC_SET        = 1;\n    enum IPC_STAT       = 2;\n\n    key_t ftok(in char*, int);\n}\nelse version (CRuntime_Bionic)\n{\n    // All except ftok are from the linux kernel headers.\n    version (X86)\n    {\n        struct ipc_perm\n        {\n            key_t   key;\n            ushort  uid;\n            ushort  gid;\n            ushort  cuid;\n            ushort  cgid;\n            mode_t  mode;\n            ushort  seq;\n        }\n    }\n    else version (ARM)\n    {\n        struct ipc_perm\n        {\n            key_t   key;\n            ushort  uid;\n            ushort  gid;\n            ushort  cuid;\n            ushort  cgid;\n            mode_t  mode;\n            ushort  seq;\n        }\n    }\n    else version (AArch64)\n    {\n        struct ipc_perm\n        {\n            key_t   key;\n            uint    uid;\n            uint    gid;\n            uint    cuid;\n            uint    cgid;\n            mode_t  mode;\n            ushort  seq;\n        }\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n\n    enum IPC_CREAT      = 0x0200; // 01000\n    enum IPC_EXCL       = 0x0400; // 02000\n    enum IPC_NOWAIT     = 0x0800; // 04000\n\n    enum key_t IPC_PRIVATE = 0;\n\n    enum IPC_RMID       = 0;\n    enum IPC_SET        = 1;\n    enum IPC_STAT       = 2;\n\n    key_t ftok(in char*, int);\n}\nelse version (CRuntime_UClibc)\n{\n    struct ipc_perm\n    {\n        key_t   __key;\n        uid_t   uid;\n        gid_t   gid;\n        uid_t   cuid;\n        gid_t   cgid;\n        ushort  mode;\n        ushort  __pad1;\n        ushort  __seq;\n        ushort  __pad2;\n        c_ulong __unused1;\n        c_ulong __unused2;\n    }\n\n    enum IPC_CREAT      = 0x0200; // 01000\n    enum IPC_EXCL       = 0x0400; // 02000\n    enum IPC_NOWAIT     = 0x0800; // 04000\n\n    enum key_t IPC_PRIVATE = 0;\n\n    enum IPC_RMID       = 0;\n    enum IPC_SET        = 1;\n    enum IPC_STAT       = 2;\n    enum IPC_INFO       = 3;\n\n    key_t ftok(in char*, int);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/mman.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sys.mman;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types; // for off_t, mode_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// Advisory Information (ADV)\n//\n/*\nint posix_madvise(void*, size_t, int);\n*/\n\n//\n// Advisory Information and either Memory Mapped Files or Shared Memory Objects (MC1)\n//\n/*\nPOSIX_MADV_NORMAL\nPOSIX_MADV_SEQUENTIAL\nPOSIX_MADV_RANDOM\nPOSIX_MADV_WILLNEED\nPOSIX_MADV_DONTNEED\n*/\n\nversion (CRuntime_Glibc)\n{\n    version (Alpha)\n        private enum __POSIX_MADV_DONTNEED = 6;\n    else\n        private enum __POSIX_MADV_DONTNEED = 4;\n\n    static if (__USE_XOPEN2K)\n    {\n        enum\n        {\n            POSIX_MADV_NORMAL = 0,\n            POSIX_MADV_RANDOM = 1,\n            POSIX_MADV_SEQUENTIAL = 2,\n            POSIX_MADV_WILLNEED = 3,\n            POSIX_MADV_DONTNEED = __POSIX_MADV_DONTNEED,\n        }\n        int posix_madvise(void *__addr, size_t __len, int __advice);\n    }\n}\nelse version (Darwin)\n{\n    enum POSIX_MADV_NORMAL      = 0;\n    enum POSIX_MADV_RANDOM      = 1;\n    enum POSIX_MADV_SEQUENTIAL  = 2;\n    enum POSIX_MADV_WILLNEED    = 3;\n    enum POSIX_MADV_DONTNEED    = 4;\n    int posix_madvise(void *addr, size_t len, int advice);\n}\nelse version (FreeBSD)\n{\n    enum POSIX_MADV_NORMAL      = 0;\n    enum POSIX_MADV_RANDOM      = 1;\n    enum POSIX_MADV_SEQUENTIAL  = 2;\n    enum POSIX_MADV_WILLNEED    = 3;\n    enum POSIX_MADV_DONTNEED    = 4;\n    int posix_madvise(void *addr, size_t len, int advice);\n}\nelse version (NetBSD)\n{\n    enum POSIX_MADV_NORMAL      = 0;\n    enum POSIX_MADV_RANDOM      = 1;\n    enum POSIX_MADV_SEQUENTIAL  = 2;\n    enum POSIX_MADV_WILLNEED    = 3;\n    enum POSIX_MADV_DONTNEED    = 4;\n    int posix_madvise(void *addr, size_t len, int advice);\n}\nelse version (DragonFlyBSD)\n{\n    enum POSIX_MADV_NORMAL      = 0;\n    enum POSIX_MADV_RANDOM      = 1;\n    enum POSIX_MADV_SEQUENTIAL  = 2;\n    enum POSIX_MADV_WILLNEED    = 3;\n    enum POSIX_MADV_DONTNEED    = 4;\n    int posix_madvise(void *addr, size_t len, int advice);\n}\nelse version (Solaris)\n{\n}\nelse version (CRuntime_Bionic)\n{\n}\nelse version (CRuntime_Musl)\n{\n}\nelse version (CRuntime_UClibc)\n{\n    enum\n    {\n        POSIX_MADV_NORMAL = 0,\n        POSIX_MADV_RANDOM = 1,\n        POSIX_MADV_SEQUENTIAL = 2,\n        POSIX_MADV_WILLNEED = 3,\n        POSIX_MADV_DONTNEED = 4,\n    }\n    int posix_madvise(void *__addr, size_t __len, int __advice);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Memory Mapped Files, Shared Memory Objects, or Memory Protection (MC2)\n//\n/*\nPROT_READ\nPROT_WRITE\nPROT_EXEC\nPROT_NONE\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum PROT_NONE      = 0x0;\n    enum PROT_READ      = 0x1;\n    enum PROT_WRITE     = 0x2;\n    enum PROT_EXEC      = 0x4;\n}\nelse version (Darwin)\n{\n    enum PROT_NONE      = 0x00;\n    enum PROT_READ      = 0x01;\n    enum PROT_WRITE     = 0x02;\n    enum PROT_EXEC      = 0x04;\n}\nelse version (FreeBSD)\n{\n    enum PROT_NONE      = 0x00;\n    enum PROT_READ      = 0x01;\n    enum PROT_WRITE     = 0x02;\n    enum PROT_EXEC      = 0x04;\n}\nelse version (NetBSD)\n{\n    enum PROT_NONE      = 0x00;\n    enum PROT_READ      = 0x01;\n    enum PROT_WRITE     = 0x02;\n    enum PROT_EXEC      = 0x04;\n}\nelse version (DragonFlyBSD)\n{\n    enum PROT_NONE      = 0x00;\n    enum PROT_READ      = 0x01;\n    enum PROT_WRITE     = 0x02;\n    enum PROT_EXEC      = 0x04;\n}\nelse version (Solaris)\n{\n    enum PROT_NONE = 0x00;\n    enum PROT_READ = 0x01;\n    enum PROT_WRITE = 0x02;\n    enum PROT_EXEC = 0x04;\n}\nelse version (CRuntime_Bionic)\n{\n    enum PROT_NONE = 0x00;\n    enum PROT_READ = 0x01;\n    enum PROT_WRITE = 0x02;\n    enum PROT_EXEC = 0x04;\n}\nelse version (CRuntime_Musl)\n{\n    enum PROT_NONE      = 0x0;\n    enum PROT_READ      = 0x1;\n    enum PROT_WRITE     = 0x2;\n    enum PROT_EXEC      = 0x4;\n}\nelse version (CRuntime_UClibc)\n{\n    enum PROT_NONE      = 0x0;\n    enum PROT_READ      = 0x1;\n    enum PROT_WRITE     = 0x2;\n    enum PROT_EXEC      = 0x4;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Memory Mapped Files, Shared Memory Objects, or Typed Memory Objects (MC3)\n//\n/*\nvoid* mmap(void*, size_t, int, int, int, off_t);\nint munmap(void*, size_t);\n*/\n\nversion (CRuntime_Glibc)\n{\n    static if (__USE_LARGEFILE64) void* mmap64(void*, size_t, int, int, int, off_t);\n    static if (__USE_FILE_OFFSET64)\n        alias mmap = mmap64;\n    else\n        void* mmap(void*, size_t, int, int, int, off_t);\n    int munmap(void*, size_t);\n}\nelse version (Darwin)\n{\n    void* mmap(void*, size_t, int, int, int, off_t);\n    int   munmap(void*, size_t);\n}\nelse version (FreeBSD)\n{\n    void* mmap(void*, size_t, int, int, int, off_t);\n    int   munmap(void*, size_t);\n}\nelse version (NetBSD)\n{\n    void* mmap(void*, size_t, int, int, int, off_t);\n    int   munmap(void*, size_t);\n}\nelse version (DragonFlyBSD)\n{\n    void* mmap(void*, size_t, int, int, int, off_t);\n    int   munmap(void*, size_t);\n}\nelse version (Solaris)\n{\n    void* mmap(void*, size_t, int, int, int, off_t);\n    int   munmap(void*, size_t);\n}\nelse version (CRuntime_Bionic)\n{\n    void* mmap(void*, size_t, int, int, int, off_t);\n    int   munmap(void*, size_t);\n}\nelse version (CRuntime_Musl)\n{\n    static if (__USE_LARGEFILE64) void* mmap64(void*, size_t, int, int, int, off_t);\n    static if (__USE_FILE_OFFSET64)\n        alias mmap = mmap64;\n    else\n        void* mmap(void*, size_t, int, int, int, off_t);\n    int munmap(void*, size_t);\n}\nelse version (CRuntime_UClibc)\n{\n    static if (__USE_LARGEFILE64) void* mmap64(void*, size_t, int, int, int, off64_t);\n    static if (__USE_FILE_OFFSET64)\n        alias mmap = mmap64;\n    else\n        void* mmap(void*, size_t, int, int, int, off_t);\n    int munmap(void*, size_t);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Memory Mapped Files (MF)\n//\n/*\nMAP_SHARED (MF|SHM)\nMAP_PRIVATE (MF|SHM)\nMAP_FIXED  (MF|SHM)\nMAP_FAILED (MF|SHM)\n\nMS_ASYNC (MF|SIO)\nMS_SYNC (MF|SIO)\nMS_INVALIDATE (MF|SIO)\n\nint msync(void*, size_t, int); (MF|SIO)\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum MAP_SHARED     = 0x01;\n    enum MAP_PRIVATE    = 0x02;\n    enum MAP_FIXED      = 0x10;\n\n    enum MAP_FAILED     = cast(void*) -1;\n\n    version (MICROBLAZE)\n        private enum DEFAULTS = true;\n    else version (Alpha)\n    {\n        private enum DEFAULTS = false;\n        enum MAP_ANON = 0x10;\n        enum MS_ASYNC = 1;\n        enum MS_SYNC = 2;\n        enum MS_INVALIDATE = 4;\n    }\n    else version (SH)\n        private enum DEFAULTS = true;\n    else version (AArch64)\n        private enum DEFAULTS = true;\n    else version (ARM)\n        private enum DEFAULTS = true;\n    else version (S390)\n        private enum DEFAULTS = true;\n    else version (SystemZ)\n        private enum DEFAULTS = true;\n    else version (IA64)\n        private enum DEFAULTS = true;\n    else version (HPPA)\n    {\n        private enum DEFAULTS = false;\n        enum MAP_ANON = 0x10;\n        enum MS_SYNC = 1;\n        enum MS_ASYNC = 2;\n        enum MS_INVALIDATE = 4;\n    }\n    else version (HPPA64)\n    {\n        private enum DEFAULTS = false;\n        enum MAP_ANON = 0x10;\n        enum MS_SYNC = 1;\n        enum MS_ASYNC = 2;\n        enum MS_INVALIDATE = 4;\n    }\n    else version (M68K)\n        private enum DEFAULTS = true;\n    else version (TILE)\n        private enum DEFAULTS = true;\n    else version (X86)\n        private enum DEFAULTS = true;\n    else version (X86_64)\n        private enum DEFAULTS = true;\n    else version (MIPS32)\n    {\n        private enum DEFAULTS = false;\n        enum MAP_ANON = 0x0800;\n        enum MS_ASYNC = 1;\n        enum MS_INVALIDATE = 2;\n        enum MS_SYNC = 4;\n    }\n    else version (MIPS64)\n    {\n        private enum DEFAULTS = false;\n        enum MAP_ANON = 0x0800;\n        enum MS_ASYNC = 1;\n        enum MS_INVALIDATE = 2;\n        enum MS_SYNC = 4;\n    }\n    else version (SPARC)\n        private enum DEFAULTS = true;\n    else version (SPARC64)\n        private enum DEFAULTS = true;\n    else version (PPC)\n        private enum DEFAULTS = true;\n    else version (PPC64)\n        private enum DEFAULTS = true;\n    else\n        static assert(0, \"unimplemented\");\n\n    static if (DEFAULTS)\n    {\n        enum MAP_ANON = 0x20;\n        enum MS_ASYNC = 1;\n        enum MS_INVALIDATE = 2;\n        enum MS_SYNC = 4;\n    }\n\n    int msync(void*, size_t, int);\n}\nelse version (Darwin)\n{\n    enum MAP_SHARED     = 0x0001;\n    enum MAP_PRIVATE    = 0x0002;\n    enum MAP_FIXED      = 0x0010;\n    enum MAP_ANON       = 0x1000;\n\n    enum MAP_FAILED     = cast(void*)-1;\n\n    enum MS_ASYNC       = 0x0001;\n    enum MS_INVALIDATE  = 0x0002;\n    enum MS_SYNC        = 0x0010;\n\n    int msync(void*, size_t, int);\n}\nelse version (FreeBSD)\n{\n    enum MAP_SHARED     = 0x0001;\n    enum MAP_PRIVATE    = 0x0002;\n    enum MAP_FIXED      = 0x0010;\n    enum MAP_ANON       = 0x1000;\n\n    enum MAP_FAILED     = cast(void*)-1;\n\n    enum MS_SYNC        = 0x0000;\n    enum MS_ASYNC       = 0x0001;\n    enum MS_INVALIDATE  = 0x0002;\n\n    int msync(void*, size_t, int);\n}\nelse version (NetBSD)\n{\n    enum MAP_SHARED     = 0x0001;\n    enum MAP_PRIVATE    = 0x0002;\n    enum MAP_FIXED      = 0x0010;\n    enum MAP_ANON       = 0x1000;\n\n    enum MAP_FAILED     = cast(void*)-1;\n\n    enum MS_SYNC        = 0x0004;\n    enum MS_ASYNC       = 0x0001;\n    enum MS_INVALIDATE  = 0x0002;\n\n    int __msync13(void*, size_t, int);\n    alias msync = __msync13;\n}\nelse version (DragonFlyBSD)\n{\n    enum MAP_SHARED     = 0x0001;\n    enum MAP_PRIVATE    = 0x0002;\n    enum MAP_FIXED      = 0x0010;\n    enum MAP_ANON       = 0x1000;\n\n    enum MAP_FAILED     = cast(void*)-1;\n\n    enum MS_SYNC        = 0x0000;\n    enum MS_ASYNC       = 0x0001;\n    enum MS_INVALIDATE  = 0x0002;\n\n    int msync(void*, size_t, int);\n}\nelse version (Solaris)\n{\n    enum MAP_SHARED = 0x0001;\n    enum MAP_PRIVATE = 0x0002;\n    enum MAP_FIXED = 0x0010;\n    enum MAP_ANON = 0x0100;\n\n    enum MAP_FAILED = cast(void*)-1;\n\n    enum MS_SYNC = 0x0004;\n    enum MS_ASYNC = 0x0001;\n    enum MS_INVALIDATE  = 0x0002;\n\n    int msync(void*, size_t, int);\n}\nelse version (CRuntime_Bionic)\n{\n    enum MAP_SHARED     = 0x0001;\n    enum MAP_PRIVATE    = 0x0002;\n    enum MAP_FIXED      = 0x0010;\n\n    version (X86)\n    {\n        enum MAP_ANON       = 0x0020;\n    }\n    else version (ARM)\n    {\n        enum MAP_ANON       = 0x0020;\n    }\n    else version (AArch64)\n    {\n        enum MAP_ANON       = 0x0020;\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n\n    enum MAP_FAILED     = cast(void*)-1;\n\n    enum MS_SYNC        = 4;\n    enum MS_ASYNC       = 1;\n    enum MS_INVALIDATE  = 2;\n\n    int msync(in void*, size_t, int);\n}\nelse version (CRuntime_Musl)\n{\n    enum MAP_SHARED     = 0x01;\n    enum MAP_PRIVATE    = 0x02;\n    enum MAP_FIXED      = 0x10;\n\n    enum MAP_FAILED     = cast(void*) -1;\n    enum MAP_ANON = 0x20;\n    enum MS_ASYNC = 1;\n    enum MS_INVALIDATE = 2;\n    enum MS_SYNC = 4;\n    int msync(void*, size_t, int);\n}\nelse version (CRuntime_UClibc)\n{\n    enum MAP_SHARED     = 0x01;\n    enum MAP_PRIVATE    = 0x02;\n    enum MAP_FIXED      = 0x10;\n\n    enum MAP_FAILED     = cast(void*) -1;\n\n    version (X86_64)\n    {\n        enum MAP_ANON       = 0x20;\n        enum MS_ASYNC       = 1;\n        enum MS_INVALIDATE  = 2;\n        enum MS_SYNC        = 4;\n    }\n    else version (MIPS32)\n    {\n        enum MAP_ANON       = 0x0800;\n        enum MS_ASYNC       = 1;\n        enum MS_INVALIDATE  = 2;\n        enum MS_SYNC        = 4;\n    }\n    else version (ARM)\n    {\n        enum MAP_ANON       = 0x020;\n        enum MS_ASYNC       = 1;\n        enum MS_INVALIDATE  = 2;\n        enum MS_SYNC        = 4;\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n\n\n    int msync(void*, size_t, int);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Process Memory Locking (ML)\n//\n/*\nMCL_CURRENT\nMCL_FUTURE\n\nint mlockall(int);\nint munlockall();\n*/\n\nversion (CRuntime_Glibc)\n{\n    version (SPARC) enum\n    {\n        MCL_CURRENT = 0x2000,\n        MCL_FUTURE = 0x4000,\n    }\n    else version (SPARC64) enum\n    {\n        MCL_CURRENT = 0x2000,\n        MCL_FUTURE = 0x4000,\n    }\n    else version (PPC) enum\n    {\n        MCL_CURRENT = 0x2000,\n        MCL_FUTURE = 0x4000,\n    }\n    else version (PPC64) enum\n    {\n        MCL_CURRENT = 0x2000,\n        MCL_FUTURE = 0x4000,\n    }\n    else version (Alpha) enum\n    {\n        MCL_CURRENT = 8192,\n        MCL_FUTURE = 16384,\n    }\n    else enum\n    {\n        MCL_CURRENT = 1,\n        MCL_FUTURE = 2,\n    }\n\n    int mlockall(int);\n    int munlockall();\n\n}\nelse version (Darwin)\n{\n    enum MCL_CURRENT    = 0x0001;\n    enum MCL_FUTURE     = 0x0002;\n\n    int mlockall(int);\n    int munlockall();\n}\nelse version (FreeBSD)\n{\n    enum MCL_CURRENT    = 0x0001;\n    enum MCL_FUTURE     = 0x0002;\n\n    int mlockall(int);\n    int munlockall();\n}\nelse version (NetBSD)\n{\n    enum MCL_CURRENT    = 0x0001;\n    enum MCL_FUTURE     = 0x0002;\n\n    int mlockall(int);\n    int munlockall();\n}\nelse version (DragonFlyBSD)\n{\n    enum MCL_CURRENT    = 0x0001;\n    enum MCL_FUTURE     = 0x0002;\n\n    int mlockall(int);\n    int munlockall();\n}\nelse version (Solaris)\n{\n    enum MCL_CURRENT = 0x0001;\n    enum MCL_FUTURE = 0x0002;\n\n    int mlockall(int);\n    int munlockall();\n}\nelse version (CRuntime_Bionic)\n{\n    enum MCL_CURRENT = 1;\n    enum MCL_FUTURE  = 2;\n\n    int mlockall(int);\n    int munlockall();\n}\nelse version (CRuntime_Musl)\n{\n}\nelse version (CRuntime_UClibc)\n{\n    enum\n    {\n        MCL_CURRENT = 1,\n        MCL_FUTURE = 2,\n    }\n\n    int mlockall(int);\n    int munlockall();\n\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Range Memory Locking (MLR)\n//\n/*\nint mlock(in void*, size_t);\nint munlock(in void*, size_t);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int mlock(in void*, size_t);\n    int munlock(in void*, size_t);\n}\nelse version (Darwin)\n{\n    int mlock(in void*, size_t);\n    int munlock(in void*, size_t);\n}\nelse version (FreeBSD)\n{\n    int mlock(in void*, size_t);\n    int munlock(in void*, size_t);\n}\nelse version (NetBSD)\n{\n    int mlock(in void*, size_t);\n    int munlock(in void*, size_t);\n}\nelse version (DragonFlyBSD)\n{\n    int mlock(in void*, size_t);\n    int munlock(in void*, size_t);\n}\nelse version (Solaris)\n{\n    int mlock(in void*, size_t);\n    int munlock(in void*, size_t);\n}\nelse version (CRuntime_Bionic)\n{\n    int mlock(in void*, size_t);\n    int munlock(in void*, size_t);\n}\nelse version (CRuntime_Musl)\n{\n}\nelse version (CRuntime_UClibc)\n{\n    int mlock(in void*, size_t);\n    int munlock(in void*, size_t);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Memory Protection (MPR)\n//\n/*\nint mprotect(void*, size_t, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int mprotect(void*, size_t, int);\n}\nelse version (Darwin)\n{\n    int mprotect(void*, size_t, int);\n}\nelse version (FreeBSD)\n{\n    int mprotect(void*, size_t, int);\n}\nelse version (NetBSD)\n{\n    int mprotect(void*, size_t, int);\n}\nelse version (DragonFlyBSD)\n{\n    int mprotect(void*, size_t, int);\n}\nelse version (Solaris)\n{\n    int mprotect(void*, size_t, int);\n}\nelse version (CRuntime_Bionic)\n{\n    int mprotect(in void*, size_t, int);\n}\nelse version (CRuntime_Musl)\n{\n    int mprotect(void*, size_t, int);\n}\nelse version (CRuntime_UClibc)\n{\n    int mprotect(void*, size_t, int);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Shared Memory Objects (SHM)\n//\n/*\nint shm_open(in char*, int, mode_t);\nint shm_unlink(in char*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int shm_open(in char*, int, mode_t);\n    int shm_unlink(in char*);\n}\nelse version (Darwin)\n{\n    int shm_open(in char*, int, mode_t);\n    int shm_unlink(in char*);\n}\nelse version (FreeBSD)\n{\n    int shm_open(in char*, int, mode_t);\n    int shm_unlink(in char*);\n}\nelse version (NetBSD)\n{\n    int shm_open(in char*, int, mode_t);\n    int shm_unlink(in char*);\n}\nelse version (DragonFlyBSD)\n{\n    int shm_open(in char*, int, mode_t);\n    int shm_unlink(in char*);\n}\nelse version (Solaris)\n{\n    int shm_open(in char*, int, mode_t);\n    int shm_unlink(in char*);\n}\nelse version (CRuntime_Bionic)\n{\n}\nelse version (CRuntime_Musl)\n{\n}\nelse version (CRuntime_UClibc)\n{\n    int shm_open(in char*, int, mode_t);\n    int shm_unlink(in char*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Typed Memory Objects (TYM)\n//\n/*\nPOSIX_TYPED_MEM_ALLOCATE\nPOSIX_TYPED_MEM_ALLOCATE_CONTIG\nPOSIX_TYPED_MEM_MAP_ALLOCATABLE\n\nstruct posix_typed_mem_info\n{\n    size_t posix_tmi_length;\n}\n\nint posix_mem_offset(in void*, size_t, off_t *, size_t *, int *);\nint posix_typed_mem_get_info(int, struct posix_typed_mem_info *);\nint posix_typed_mem_open(in char*, int, int);\n*/\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/msg.d",
    "content": "/**\n* D header file for POSIX.\n*\n* Authors: Neven Miculinić\n*/\n\nmodule core.sys.posix.sys.msg;\n\nimport core.sys.posix.sys.ipc;\npublic import core.sys.posix.sys.types;\npublic import core.stdc.config;\n\nversion (CRuntime_Glibc):\n// Some of these may be from linux kernel headers.\nextern (C):\n\npublic enum MSG_STAT = 11;\npublic enum MSG_INFO = 12;\n\npublic enum MSG_NOERROR = 1 << 12; // octal!10000\npublic enum  MSG_EXCEPT = 2 << 12; // octal!20000\npublic enum    MSG_COPY = 4 << 12; // octal!40000\n\nstruct msgbuf\n{\n    c_long mtype;\n    char[1] mtext;\n}\n\nstruct msginfo\n{\n    int msgpool;\n    int msgmap;\n    int msgmax;\n    int msgmnb;\n    int msgmni;\n    int msgssz;\n    int msgtql;\n    ushort msgseg;\n}\n\nversion (Alpha)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/alpha/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    struct msqid_ds\n    {\n        ipc_perm msg_perm;\n        time_t msg_stime;\n        time_t msg_rtime;\n        time_t msg_ctime;\n        c_ulong __msg_cbytes;\n        msgqnum_t msg_qnum;\n        msglen_t msg_qbytes;\n        pid_t msg_lspid;\n        pid_t msg_lrpid;\n        c_ulong __glibc_reserved1;\n        c_ulong __glibc_reserved2;\n    }\n}\nelse version (HPPA)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/hppa/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    // Assuming word size is 32\n    struct msqid_ds\n    {\n        ipc_perm msg_perm;\n        c_ulong __pad1;\n        time_t          msg_stime;\n        c_ulong __pad2;\n        time_t          msg_rtime;\n        c_ulong __pad3;\n        time_t          msg_ctime;\n        c_ulong         __msg_cbytes;\n        msgqnum_t       msg_qnum;\n        msglen_t        msg_qbytes;\n        pid_t           msg_lspid;\n        pid_t           msg_lrpid;\n        c_ulong __glibc_reserved1;\n        c_ulong __glibc_reserved2;\n    }\n\n}\nelse version (MIPS32)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/mips/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    struct msqid_ds\n    {\n        ipc_perm  msg_perm;\n        version (BigEndian) c_ulong __glibc_reserved1;\n        time_t    msg_stime;\n        version (LittleEndian) c_ulong __glibc_reserved1;\n        version (BigEndian) c_ulong __glibc_reserved2;\n        time_t    msg_rtime;\n        version (LittleEndian) c_ulong __glibc_reserved2;\n        version (BigEndian) c_ulong __glibc_reserved3;\n        time_t    msg_ctime;\n        version (LittleEndian) c_ulong __glibc_reserved3;\n        c_ulong   __msg_cbytes;\n        msgqnum_t msg_qnum;\n        msglen_t  msg_qbytes;\n        pid_t     msg_lspid;\n        pid_t     msg_lrpid;\n        c_ulong   __glibc_reserved4;\n        c_ulong   __glibc_reserved5;\n    }\n}\nelse version (MIPS64)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/mips/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    struct msqid_ds\n    {\n        ipc_perm  msg_perm;\n        time_t    msg_stime;\n        time_t    msg_rtime;\n        time_t    msg_ctime;\n        c_ulong   __msg_cbytes;\n        msgqnum_t msg_qnum;\n        msglen_t  msg_qbytes;\n        pid_t     msg_lspid;\n        pid_t     msg_lrpid;\n        c_ulong   __glibc_reserved4;\n        c_ulong   __glibc_reserved5;\n    }\n}\nelse version (PPC)\n{\n\n    //  https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/powerpc/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    struct msqid_ds\n    {\n        ipc_perm msg_perm;\n        c_ulong __glibc_reserved1;\n        time_t          msg_stime;\n        c_ulong __glibc_reserved2;\n        time_t          msg_rtime;\n        c_ulong __glibc_reserved3;\n        time_t          msg_ctime;\n        c_ulong         __msg_cbytes;\n        msgqnum_t       msg_qnum;\n        msglen_t        msg_qbytes;\n        pid_t           msg_lspid;\n        pid_t           msg_lrpid;\n        c_ulong __glibc_reserved4;\n        c_ulong __glibc_reserved5;\n    }\n}\nelse version (PPC64)\n{\n    //  https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/powerpc/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    struct msqid_ds\n    {\n        ipc_perm  msg_perm;\n        time_t    msg_stime;\n        time_t    msg_rtime;\n        time_t    msg_ctime;\n        c_ulong   __msg_cbytes;\n        msgqnum_t msg_qnum;\n        msglen_t  msg_qbytes;\n        pid_t     msg_lspid;\n        pid_t     msg_lrpid;\n        c_ulong   __glibc_reserved4;\n        c_ulong   __glibc_reserved5;\n    }\n}\nelse version (S390)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/s390/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    // Assuming wordsize != 64\n    struct msqid_ds\n    {\n        ipc_perm msg_perm;\n        c_ulong __glibc_reserved1;\n        time_t          msg_stime;\n        c_ulong __glibc_reserved2;\n        time_t          msg_rtime;\n        c_ulong __glibc_reserved3;\n        time_t          msg_ctime;\n        c_ulong         __msg_cbytes;\n        msgqnum_t       msg_qnum;\n        msglen_t        msg_qbytes;\n        pid_t           msg_lspid;\n        pid_t           msg_lrpid;\n        c_ulong __glibc_reserved4;\n        c_ulong __glibc_reserved5;\n    }\n}\nelse version (SystemZ)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/s390/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    // Assuming wordsize == 64\n    struct msqid_ds\n    {\n        ipc_perm msg_perm;\n        time_t          msg_stime;\n        time_t          msg_rtime;\n        time_t          msg_ctime;\n        c_ulong         __msg_cbytes;\n        msgqnum_t       msg_qnum;\n        msglen_t        msg_qbytes;\n        pid_t           msg_lspid;\n        pid_t           msg_lrpid;\n        c_ulong __glibc_reserved4;\n        c_ulong __glibc_reserved5;\n    }\n}\nelse version (SPARC)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sparc/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    // Assuming word size is 32\n    struct msqid_ds\n    {\n        ipc_perm msg_perm;\n        c_ulong __pad1;\n        time_t          msg_stime;\n        c_ulong __pad2;\n        time_t          msg_rtime;\n        c_ulong __pad3;\n        time_t          msg_ctime;\n        c_ulong         __msg_cbytes;\n        msgqnum_t       msg_qnum;\n        msglen_t        msg_qbytes;\n        pid_t           msg_lspid;\n        pid_t           msg_lrpid;\n        c_ulong __glibc_reserved1;\n        c_ulong __glibc_reserved2;\n    }\n}\nelse version (SPARC64)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sparc/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    // Assuming word size is 32\n    struct msqid_ds\n    {\n        ipc_perm msg_perm;\n        c_ulong __pad1;\n        time_t          msg_stime;\n        c_ulong __pad2;\n        time_t          msg_rtime;\n        c_ulong __pad3;\n        time_t          msg_ctime;\n        c_ulong         __msg_cbytes;\n        msgqnum_t       msg_qnum;\n        msglen_t        msg_qbytes;\n        pid_t           msg_lspid;\n        pid_t           msg_lrpid;\n        c_ulong __glibc_reserved1;\n        c_ulong __glibc_reserved2;\n    }\n}\nelse version (X86)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    struct msqid_ds\n    {\n        ipc_perm msg_perm;\n        time_t          msg_stime;\n        time_t          msg_rtime;\n        time_t          msg_ctime;\n        c_ulong         __msg_cbytes;\n        msgqnum_t       msg_qnum;\n        msglen_t        msg_qbytes;\n        pid_t           msg_lspid;\n        pid_t           msg_lrpid;\n        c_ulong __glibc_reserved4;\n        c_ulong __glibc_reserved5;\n    }\n}\nelse version (X86_64)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    struct msqid_ds\n    {\n        ipc_perm msg_perm;\n        c_ulong __glibc_reserved1;\n        time_t          msg_stime;\n        c_ulong __glibc_reserved2;\n        time_t          msg_rtime;\n        c_ulong __glibc_reserved3;\n        time_t          msg_ctime;\n        c_ulong         __msg_cbytes;\n        msgqnum_t       msg_qnum;\n        msglen_t        msg_qbytes;\n        pid_t           msg_lspid;\n        pid_t           msg_lrpid;\n        c_ulong __glibc_reserved4;\n        c_ulong __glibc_reserved5;\n    }\n}\nelse version (AArch64)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/generic/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    struct msqid_ds\n    {\n        ipc_perm msg_perm;\n        time_t          msg_stime;\n        time_t          msg_rtime;\n        time_t          msg_ctime;\n        c_ulong         __msg_cbytes;\n        msgqnum_t       msg_qnum;\n        msglen_t        msg_qbytes;\n        pid_t           msg_lspid;\n        pid_t           msg_lrpid;\n        c_ulong __glibc_reserved4;\n        c_ulong __glibc_reserved5;\n    }\n}\nelse version (ARM)\n{\n    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/generic/bits/msq.h\n    alias c_ulong msgqnum_t;\n    alias c_ulong msglen_t;\n\n    struct msqid_ds\n    {\n        ipc_perm msg_perm;\n        c_ulong __glibc_reserved1;\n        time_t          msg_stime;\n        c_ulong __glibc_reserved2;\n        time_t          msg_rtime;\n        c_ulong __glibc_reserved3;\n        time_t          msg_ctime;\n        c_ulong         __msg_cbytes;\n        msgqnum_t       msg_qnum;\n        msglen_t        msg_qbytes;\n        pid_t           msg_lspid;\n        pid_t           msg_lrpid;\n        c_ulong __glibc_reserved4;\n        c_ulong __glibc_reserved5;\n    }\n} else\n    static assert(0, \"unimplemented\");\n\n\npublic enum MSG_MEM_SCALE =  32;\npublic enum MSGMNI =     16;\npublic enum MSGMAX =   8192;\npublic enum MSGMNB =  16384;\n\nint msgctl (int msqid, int cmd, msqid_ds *__buf);\nint msgget ( key_t key, int msgflg );\nssize_t msgrcv(int msqid, void *msgp, size_t msgsz, c_long msgtyp, int msgflg);\nint msgsnd ( int msqid, msgbuf *msgp, int msgsz, int msgflg );\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/resource.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright (c) 2013 Lars Tandle Kyllingstad.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Lars Tandle Kyllingstad\n * Standards: The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008\n */\nmodule core.sys.posix.sys.resource;\nversion (Posix):\n\npublic import core.sys.posix.sys.time;\npublic import core.sys.posix.sys.types: id_t;\nimport core.sys.posix.config;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nnothrow @nogc extern(C):\n\n//\n// XOpen (XSI)\n//\n// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_resource.h.html\n/*\nenum\n{\n    PRIO_PROCESS,\n    PRIO_PGRP,\n    PRIO_USER,\n}\n\nalias ulong rlim_t;\n\nenum\n{\n    RLIM_INFINITY,\n    RLIM_SAVED_MAX,\n    RLIM_SAVED_CUR,\n}\n\nenum\n{\n    RUSAGE_SELF,\n    RUSAGE_CHILDREN,\n}\n\nstruct rlimit\n{\n    rlim_t rlim_cur;\n    rlim_t rlim_max;\n}\n\nstruct rusage\n{\n    timeval ru_utime;\n    timeval ru_stime;\n}\n\nenum\n{\n    RLIMIT_CORE,\n    RLIMIT_CPU,\n    RLIMIT_DATA,\n    RLIMIT_FSIZE,\n    RLIMIT_NOFILE,\n    RLIMIT_STACK,\n    RLIMIT_AS,\n}\n\nint getpriority(int, id_t);\nint getrlimit(int, rlimit*);\nint getrusage(int, rusage*);\nint setpriority(int, id_t, int);\nint setrlimit(int, const rlimit*);\n*/\n\n\nversion (CRuntime_Glibc)\n{\n    // rusage and some other constants in the Bionic section below really\n    // come from the linux kernel headers, but they're all mixed right now.\n    enum\n    {\n        PRIO_PROCESS = 0,\n        PRIO_PGRP    = 1,\n        PRIO_USER    = 2,\n    }\n\n    static if (__USE_FILE_OFFSET64)\n         alias ulong rlim_t;\n    else\n         alias c_ulong rlim_t;\n\n    static if (__USE_FILE_OFFSET64)\n        enum RLIM_INFINITY = 0xffffffffffffffffUL;\n    else\n        enum RLIM_INFINITY = cast(c_ulong)(~0UL);\n\n    enum RLIM_SAVED_MAX = RLIM_INFINITY;\n    enum RLIM_SAVED_CUR = RLIM_INFINITY;\n\n    enum\n    {\n        RUSAGE_SELF     =  0,\n        RUSAGE_CHILDREN = -1,\n    }\n\n    struct rusage\n    {\n        timeval ru_utime;\n        timeval ru_stime;\n        c_long ru_maxrss;\n        c_long ru_ixrss;\n        c_long ru_idrss;\n        c_long ru_isrss;\n        c_long ru_minflt;\n        c_long ru_majflt;\n        c_long ru_nswap;\n        c_long ru_inblock;\n        c_long ru_oublock;\n        c_long ru_msgsnd;\n        c_long ru_msgrcv;\n        c_long ru_nsignals;\n        c_long ru_nvcsw;\n        c_long ru_nivcsw;\n    }\n\n    enum\n    {\n        RLIMIT_CORE   = 4,\n        RLIMIT_CPU    = 0,\n        RLIMIT_DATA   = 2,\n        RLIMIT_FSIZE  = 1,\n        RLIMIT_NOFILE = 7,\n        RLIMIT_STACK  = 3,\n        RLIMIT_AS     = 9,\n    }\n}\nelse version (Darwin)\n{\n    enum\n    {\n        PRIO_PROCESS = 0,\n        PRIO_PGRP    = 1,\n        PRIO_USER    = 2,\n    }\n\n    alias ulong rlim_t;\n\n    enum\n    {\n        RLIM_INFINITY  = ((cast(ulong) 1 << 63) - 1),\n        RLIM_SAVED_MAX = RLIM_INFINITY,\n        RLIM_SAVED_CUR = RLIM_INFINITY,\n    }\n\n    enum\n    {\n        RUSAGE_SELF     =  0,\n        RUSAGE_CHILDREN = -1,\n    }\n\n    struct rusage\n    {\n        timeval ru_utime;\n        timeval ru_stime;\n        c_long[14] ru_opaque;\n    }\n\n    enum\n    {\n        RLIMIT_CORE   = 4,\n        RLIMIT_CPU    = 0,\n        RLIMIT_DATA   = 2,\n        RLIMIT_FSIZE  = 1,\n        RLIMIT_NOFILE = 8,\n        RLIMIT_STACK  = 3,\n        RLIMIT_AS     = 5,\n    }\n}\nelse version (FreeBSD)\n{\n    enum\n    {\n        PRIO_PROCESS = 0,\n        PRIO_PGRP    = 1,\n        PRIO_USER    = 2,\n    }\n\n    alias long rlim_t;\n\n    enum\n    {\n        RLIM_INFINITY   = (cast(rlim_t)((cast(ulong) 1 << 63) - 1)),\n        // FreeBSD explicitly does not define the following:\n        //RLIM_SAVED_MAX,\n        //RLIM_SAVED_CUR,\n    }\n\n    enum\n    {\n        RUSAGE_SELF     =  0,\n        RUSAGE_CHILDREN = -1,\n    }\n\n    struct rusage\n    {\n        timeval ru_utime;\n        timeval ru_stime;\n        c_long ru_maxrss;\n        alias ru_ixrss ru_first;\n        c_long ru_ixrss;\n        c_long ru_idrss;\n        c_long ru_isrss;\n        c_long ru_minflt;\n        c_long ru_majflt;\n        c_long ru_nswap;\n        c_long ru_inblock;\n        c_long ru_oublock;\n        c_long ru_msgsnd;\n        c_long ru_msgrcv;\n        c_long ru_nsignals;\n        c_long ru_nvcsw;\n        c_long ru_nivcsw;\n        alias ru_nivcsw ru_last;\n    }\n\n    enum\n    {\n        RLIMIT_CORE   =  4,\n        RLIMIT_CPU    =  0,\n        RLIMIT_DATA   =  2,\n        RLIMIT_FSIZE  =  1,\n        RLIMIT_NOFILE =  8,\n        RLIMIT_STACK  =  3,\n        RLIMIT_AS     = 10,\n    }\n}\nelse version (NetBSD)\n{\n    enum\n    {\n        PRIO_PROCESS = 0,\n        PRIO_PGRP    = 1,\n        PRIO_USER    = 2,\n    }\n\n    alias long rlim_t;\n\n    enum\n    {\n        RLIM_INFINITY   = (cast(rlim_t)((cast(ulong) 1 << 63) - 1)),\n        // FreeBSD explicitly does not define the following:\n        //RLIM_SAVED_MAX,\n        //RLIM_SAVED_CUR,\n    }\n\n    enum\n    {\n        RUSAGE_SELF     =  0,\n        RUSAGE_CHILDREN = -1,\n    }\n\n    struct rusage\n    {\n        timeval ru_utime;\n        timeval ru_stime;\n        c_long ru_maxrss;\n        alias ru_ixrss ru_first;\n        c_long ru_ixrss;\n        c_long ru_idrss;\n        c_long ru_isrss;\n        c_long ru_minflt;\n        c_long ru_majflt;\n        c_long ru_nswap;\n        c_long ru_inblock;\n        c_long ru_oublock;\n        c_long ru_msgsnd;\n        c_long ru_msgrcv;\n        c_long ru_nsignals;\n        c_long ru_nvcsw;\n        c_long ru_nivcsw;\n        alias ru_nivcsw ru_last;\n    }\n\n    enum\n    {\n        RLIMIT_CORE   =  4,\n        RLIMIT_CPU    =  0,\n        RLIMIT_DATA   =  2,\n        RLIMIT_FSIZE  =  1,\n        RLIMIT_NOFILE =  8,\n        RLIMIT_STACK  =  3,\n        RLIMIT_AS     = 10,\n    }\n}\nelse version (DragonFlyBSD)\n{\n    enum\n    {\n        PRIO_PROCESS = 0,\n        PRIO_PGRP    = 1,\n        PRIO_USER    = 2,\n    }\n\n    alias long rlim_t;\n\n    enum\n    {\n        RLIM_INFINITY   = (cast(rlim_t)((cast(ulong) 1 << 63) - 1)),\n        // DragonFlyBSD explicitly does not define the following:\n        //RLIM_SAVED_MAX,\n        //RLIM_SAVED_CUR,\n    }\n\n    enum\n    {\n        RUSAGE_SELF     =  0,\n        RUSAGE_CHILDREN = -1,\n    }\n\n    struct rusage\n    {\n        timeval ru_utime;\n        timeval ru_stime;\n        c_long ru_maxrss;\n        alias ru_ixrss ru_first;\n        c_long ru_ixrss;\n        c_long ru_idrss;\n        c_long ru_isrss;\n        c_long ru_minflt;\n        c_long ru_majflt;\n        c_long ru_nswap;\n        c_long ru_inblock;\n        c_long ru_oublock;\n        c_long ru_msgsnd;\n        c_long ru_msgrcv;\n        c_long ru_nsignals;\n        c_long ru_nvcsw;\n        c_long ru_nivcsw;\n        alias ru_nivcsw ru_last;\n    }\n\n    enum\n    {\n        RLIMIT_CORE   =  4,\n        RLIMIT_CPU    =  0,\n        RLIMIT_DATA   =  2,\n        RLIMIT_FSIZE  =  1,\n        RLIMIT_NOFILE =  8,\n        RLIMIT_STACK  =  3,\n        RLIMIT_AS     = 10,\n    }\n}\nelse version (Solaris)\n{\n    enum\n    {\n        PRIO_PROCESS = 0,\n        PRIO_PGRP    = 1,\n        PRIO_USER    = 2,\n    }\n\n    alias c_ulong rlim_t;\n\n    enum : c_long\n    {\n        RLIM_INFINITY   = -3,\n        RLIM_SAVED_MAX  = -2,\n        RLIM_SAVED_CUR  = -1,\n    }\n\n    enum\n    {\n        RUSAGE_SELF     =  0,\n        RUSAGE_CHILDREN = -1,\n    }\n\n    struct rusage\n    {\n        timeval ru_utime;\n        timeval ru_stime;\n        c_long ru_maxrss;\n        c_long ru_ixrss;\n        c_long ru_idrss;\n        c_long ru_isrss;\n        c_long ru_minflt;\n        c_long ru_majflt;\n        c_long ru_nswap;\n        c_long ru_inblock;\n        c_long ru_oublock;\n        c_long ru_msgsnd;\n        c_long ru_msgrcv;\n        c_long ru_nsignals;\n        c_long ru_nvcsw;\n        c_long ru_nivcsw;\n    }\n\n    enum\n    {\n        RLIMIT_CORE   = 4,\n        RLIMIT_CPU    = 0,\n        RLIMIT_DATA   = 2,\n        RLIMIT_FSIZE  = 1,\n        RLIMIT_NOFILE = 5,\n        RLIMIT_STACK  = 3,\n        RLIMIT_AS     = 6,\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    enum\n    {\n        PRIO_PROCESS = 0,\n        PRIO_PGRP    = 1,\n        PRIO_USER    = 2,\n    }\n\n    alias c_ulong rlim_t;\n    enum RLIM_INFINITY = cast(c_ulong)(~0UL);\n\n    enum\n    {\n        RUSAGE_SELF     =  0,\n        RUSAGE_CHILDREN = -1,\n    }\n\n    struct rusage\n    {\n        timeval ru_utime;\n        timeval ru_stime;\n        c_long ru_maxrss;\n        c_long ru_ixrss;\n        c_long ru_idrss;\n        c_long ru_isrss;\n        c_long ru_minflt;\n        c_long ru_majflt;\n        c_long ru_nswap;\n        c_long ru_inblock;\n        c_long ru_oublock;\n        c_long ru_msgsnd;\n        c_long ru_msgrcv;\n        c_long ru_nsignals;\n        c_long ru_nvcsw;\n        c_long ru_nivcsw;\n    }\n\n    enum\n    {\n        RLIMIT_CORE   = 4,\n        RLIMIT_CPU    = 0,\n        RLIMIT_DATA   = 2,\n        RLIMIT_FSIZE  = 1,\n        RLIMIT_NOFILE = 7,\n        RLIMIT_STACK  = 3,\n        RLIMIT_AS     = 9,\n    }\n}\nelse version (CRuntime_Musl)\n{\n    alias ulong rlim_t;\n    enum\n    {\n        RLIMIT_CPU    = 0,\n        RLIMIT_FSIZE  = 1,\n        RLIMIT_DATA   = 2,\n        RLIMIT_STACK  = 3,\n        RLIMIT_CORE   = 4,\n        RLIMIT_NOFILE = 7,\n        RLIMIT_AS     = 9,\n    }\n    int getrlimit(int, rlimit*);\n    int setrlimit(int, in rlimit*);\n    alias getrlimit getrlimit64;\n    alias setrlimit setrlimit64;\n}\nelse version (CRuntime_UClibc)\n{\n    enum\n    {\n        PRIO_PROCESS = 0,\n        PRIO_PGRP    = 1,\n        PRIO_USER    = 2,\n    }\n\n    static if (__USE_FILE_OFFSET64)\n         alias ulong rlim_t;\n    else\n         alias c_ulong rlim_t;\n\n    static if (__USE_FILE_OFFSET64)\n        enum RLIM_INFINITY = 0xffffffffffffffffUL;\n    else\n        enum RLIM_INFINITY = cast(c_ulong)(~0UL);\n\n    enum RLIM_SAVED_MAX = RLIM_INFINITY;\n    enum RLIM_SAVED_CUR = RLIM_INFINITY;\n\n    enum\n    {\n        RUSAGE_SELF     =  0,\n        RUSAGE_CHILDREN = -1,\n    }\n\n    struct rusage\n    {\n        timeval ru_utime;\n        timeval ru_stime;\n        c_long ru_maxrss;\n        c_long ru_ixrss;\n        c_long ru_idrss;\n        c_long ru_isrss;\n        c_long ru_minflt;\n        c_long ru_majflt;\n        c_long ru_nswap;\n        c_long ru_inblock;\n        c_long ru_oublock;\n        c_long ru_msgsnd;\n        c_long ru_msgrcv;\n        c_long ru_nsignals;\n        c_long ru_nvcsw;\n        c_long ru_nivcsw;\n    }\n\n    enum\n    {\n        RLIMIT_CORE   = 4,\n        RLIMIT_CPU    = 0,\n        RLIMIT_DATA   = 2,\n        RLIMIT_FSIZE  = 1,\n        RLIMIT_NOFILE = 7,\n        RLIMIT_STACK  = 3,\n        RLIMIT_AS     = 9,\n    }\n}\nelse static assert (false, \"Unsupported platform\");\n\nstruct rlimit\n{\n    rlim_t rlim_cur;\n    rlim_t rlim_max;\n}\n\nversion (CRuntime_Glibc)\n{\n    int getpriority(int, id_t);\n    int setpriority(int, id_t, int);\n}\nelse version (FreeBSD)\n{\n    int getpriority(int, int);\n    int setpriority(int, int, int);\n}\nelse version (DragonFlyBSD)\n{\n    int getpriority(int, int);\n    int setpriority(int, int, int);\n}\nelse version (CRuntime_Bionic)\n{\n    int getpriority(int, int);\n    int setpriority(int, int, int);\n}\nelse version (Solaris)\n{\n    int getpriority(int, id_t);\n    int setpriority(int, id_t, int);\n}\nelse version (Darwin)\n{\n    int getpriority(int, id_t);\n    int setpriority(int, id_t, int);\n}\nelse version (CRuntime_UClibc)\n{\n    int getpriority(int, id_t);\n    int setpriority(int, id_t, int);\n}\n\nversion (CRuntime_Glibc)\n{\n    static if (__USE_FILE_OFFSET64)\n    {\n        int getrlimit64(int, rlimit*);\n        int setrlimit64(int, in rlimit*);\n        alias getrlimit = getrlimit64;\n        alias setrlimit = setrlimit64;\n    }\n    else\n    {\n        int getrlimit(int, rlimit*);\n        int setrlimit(int, in rlimit*);\n    }\n    int getrusage(int, rusage*);\n}\nelse version (CRuntime_Bionic)\n{\n    int getrlimit(int, rlimit*);\n    int getrusage(int, rusage*);\n    int setrlimit(int, in rlimit*);\n}\nelse version (Darwin)\n{\n    int getrlimit(int, rlimit*);\n    int getrusage(int, rusage*);\n    int setrlimit(int, in rlimit*);\n}\nelse version (FreeBSD)\n{\n    int getrlimit(int, rlimit*);\n    int getrusage(int, rusage*);\n    int setrlimit(int, in rlimit*);\n}\nelse version (NetBSD)\n{\n    int getrlimit(int, rlimit*);\n    int getrusage(int, rusage*);\n    int setrlimit(int, in rlimit*);\n}\nelse version (DragonFlyBSD)\n{\n    int getrlimit(int, rlimit*);\n    int getrusage(int, rusage*);\n    int setrlimit(int, in rlimit*);\n}\nelse version (Solaris)\n{\n    int getrlimit(int, rlimit*);\n    int getrusage(int, rusage*);\n    int setrlimit(int, in rlimit*);\n}\nelse version (CRuntime_UClibc)\n{\n    static if (__USE_FILE_OFFSET64)\n    {\n        int getrlimit64(int, rlimit*);\n        int setrlimit64(int, in rlimit*);\n        alias getrlimit = getrlimit64;\n        alias setrlimit = setrlimit64;\n    }\n    else\n    {\n        int getrlimit(int, rlimit*);\n        int setrlimit(int, in rlimit*);\n    }\n    int getrusage(int, rusage*);\n}"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/select.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2016.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\nmodule core.sys.posix.sys.select;\n\nprivate import core.sys.posix.config;\npublic import core.stdc.time;           // for timespec\npublic import core.sys.posix.sys.time;  // for timeval\npublic import core.sys.posix.sys.types; // for time_t\npublic import core.sys.posix.signal;    // for sigset_t\n\n//debug=select;  // uncomment to turn on debugging printf's\nversion (unittest) import core.stdc.stdio: printf;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// Required\n//\n/*\nNOTE: This module requires timeval from core.sys.posix.sys.time, but timeval\n      is supposedly an XOpen extension.  As a result, this header will not\n      compile on platforms that are not XSI-compliant.  This must be resolved\n      on a per-platform basis.\n\nfd_set\n\nvoid FD_CLR(int fd, fd_set* fdset);\nint FD_ISSET(int fd, const(fd_set)* fdset);\nvoid FD_SET(int fd, fd_set* fdset);\nvoid FD_ZERO(fd_set* fdset);\n\nFD_SETSIZE\n\nint  pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);\nint  select(int, fd_set*, fd_set*, fd_set*, timeval*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    private\n    {\n        alias c_long __fd_mask;\n        enum uint __NFDBITS = 8 * __fd_mask.sizeof;\n\n        extern (D) auto __FDELT( int d ) pure\n        {\n            return d / __NFDBITS;\n        }\n\n        extern (D) auto __FDMASK( int d ) pure\n        {\n            return cast(__fd_mask) 1 << ( d % __NFDBITS );\n        }\n    }\n\n    enum FD_SETSIZE = 1024;\n\n    struct fd_set\n    {\n        __fd_mask[FD_SETSIZE / __NFDBITS] fds_bits;\n    }\n\n    extern (D) void FD_CLR( int fd, fd_set* fdset ) pure\n    {\n        fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );\n    }\n\n    extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure\n    {\n        return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;\n    }\n\n    extern (D) void FD_SET( int fd, fd_set* fdset ) pure\n    {\n        fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );\n    }\n\n    extern (D) void FD_ZERO( fd_set* fdset ) pure\n    {\n        fdset.fds_bits[0 .. $] = 0;\n    }\n\n    /+\n     + GNU ASM Implementation\n     +\n    # define __FD_ZERO(fdsp)                                \\\n      do {                                                  \\\n        int __d0, __d1;                                     \\\n        __asm__ __volatile__ (\"cld; rep; stosl\"             \\\n                  : \"=c\" (__d0), \"=D\" (__d1)                \\\n                  : \"a\" (0), \"0\" (sizeof (fd_set)           \\\n                          / sizeof (__fd_mask)),            \\\n                    \"1\" (&__FDS_BITS (fdsp)[0])             \\\n                  : \"memory\");                              \\\n      } while (0)\n\n    # define __FD_SET(fd, fdsp)                             \\\n      __asm__ __volatile__ (\"btsl %1,%0\"                    \\\n                : \"=m\" (__FDS_BITS (fdsp)[__FDELT (fd)])    \\\n                : \"r\" (((int) (fd)) % __NFDBITS)            \\\n                : \"cc\",\"memory\")\n    # define __FD_CLR(fd, fdsp)                             \\\n      __asm__ __volatile__ (\"btrl %1,%0\"                    \\\n                : \"=m\" (__FDS_BITS (fdsp)[__FDELT (fd)])    \\\n                : \"r\" (((int) (fd)) % __NFDBITS)            \\\n                : \"cc\",\"memory\")\n    # define __FD_ISSET(fd, fdsp)                           \\\n      (__extension__                                        \\\n       ({register char __result;                            \\\n         __asm__ __volatile__ (\"btl %1,%2 ; setcb %b0\"      \\\n                   : \"=q\" (__result)                        \\\n                   : \"r\" (((int) (fd)) % __NFDBITS),        \\\n                     \"m\" (__FDS_BITS (fdsp)[__FDELT (fd)])  \\\n                   : \"cc\");                                 \\\n         __result; }))\n     +/\n\n    int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);\n    int select(int, fd_set*, fd_set*, fd_set*, timeval*);\n}\nelse version (Darwin)\n{\n    private\n    {\n        enum uint __DARWIN_NBBY    = 8;                            /* bits in a byte */\n        enum uint __DARWIN_NFDBITS = (int.sizeof * __DARWIN_NBBY); /* bits per mask */\n    }\n\n    enum FD_SETSIZE = 1024;\n\n    struct fd_set\n    {\n        int[(FD_SETSIZE + (__DARWIN_NFDBITS - 1)) / __DARWIN_NFDBITS] fds_bits;\n    }\n\n    extern (D) void FD_CLR( int fd, fd_set* fdset ) pure\n    {\n        fdset.fds_bits[fd / __DARWIN_NFDBITS] &= ~(1 << (fd % __DARWIN_NFDBITS));\n    }\n\n    extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure\n    {\n        return (fdset.fds_bits[fd / __DARWIN_NFDBITS] & (1 << (fd % __DARWIN_NFDBITS))) != 0;\n    }\n\n    extern (D) void FD_SET( int fd, fd_set* fdset ) pure\n    {\n        fdset.fds_bits[fd / __DARWIN_NFDBITS] |= 1 << (fd % __DARWIN_NFDBITS);\n    }\n\n    extern (D) void FD_ZERO( fd_set* fdset ) pure\n    {\n        fdset.fds_bits[0 .. $] = 0;\n    }\n\n    int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);\n    int select(int, fd_set*, fd_set*, fd_set*, timeval*);\n}\nelse version (FreeBSD)\n{\n    private\n    {\n        alias c_ulong __fd_mask;\n        enum _NFDBITS = __fd_mask.sizeof * 8;\n    }\n\n    enum uint FD_SETSIZE = 1024;\n\n    struct fd_set\n    {\n        __fd_mask[(FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS] __fds_bits;\n    }\n\n    extern (D) __fd_mask __fdset_mask(uint n) pure\n    {\n        return cast(__fd_mask) 1 << (n % _NFDBITS);\n    }\n\n    extern (D) void FD_CLR( int n, fd_set* p ) pure\n    {\n        p.__fds_bits[n / _NFDBITS] &= ~__fdset_mask(n);\n    }\n\n    extern (D) bool FD_ISSET( int n, const(fd_set)* p ) pure\n    {\n        return (p.__fds_bits[n / _NFDBITS] & __fdset_mask(n)) != 0;\n    }\n\n    extern (D) void FD_SET( int n, fd_set* p ) pure\n    {\n        p.__fds_bits[n / _NFDBITS] |= __fdset_mask(n);\n    }\n\n    extern (D) void FD_ZERO( fd_set* p ) pure\n    {\n        fd_set *_p;\n        size_t _n;\n\n        _p = p;\n        _n = (FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS;\n        while (_n > 0)\n            _p.__fds_bits[--_n] = 0;\n    }\n\n    int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);\n    int select(int, fd_set*, fd_set*, fd_set*, timeval*);\n}\nelse version (NetBSD)\n{\n    private\n    {\n        alias c_ulong __fd_mask;\n        enum _NFDBITS = __fd_mask.sizeof * 8;\n    }\n\n    enum uint FD_SETSIZE = 256;\n\n    struct fd_set\n    {\n        __fd_mask[(FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS] __fds_bits;\n    }\n\n    extern (D) __fd_mask __fdset_mask(uint n) pure\n    {\n        return cast(__fd_mask) 1 << (n % _NFDBITS);\n    }\n\n    extern (D) void FD_CLR( int n, fd_set* p ) pure\n    {\n        p.__fds_bits[n / _NFDBITS] &= ~__fdset_mask(n);\n    }\n\n    extern (D) bool FD_ISSET( int n, const(fd_set)* p ) pure\n    {\n        return (p.__fds_bits[n / _NFDBITS] & __fdset_mask(n)) != 0;\n    }\n\n    extern (D) void FD_SET( int n, fd_set* p ) pure\n    {\n        p.__fds_bits[n / _NFDBITS] |= __fdset_mask(n);\n    }\n\n    extern (D) void FD_ZERO( fd_set* p ) pure\n    {\n        fd_set *_p;\n        size_t _n;\n\n        _p = p;\n        _n = (FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS;\n        while (_n > 0)\n            _p.__fds_bits[--_n] = 0;\n    }\n\n    int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);\n    int select(int, fd_set*, fd_set*, fd_set*, timeval*);\n}\nelse version (DragonFlyBSD)\n{\n    private\n    {\n        alias c_ulong __fd_mask;\n        enum _NFDBITS = __fd_mask.sizeof * 8;\n    }\n\n    enum uint FD_SETSIZE = 1024;\n\n    struct fd_set\n    {\n        __fd_mask[(FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS] __fds_bits;\n    }\n\n    extern (D) __fd_mask __fdset_mask(uint n) pure\n    {\n        return cast(__fd_mask) 1 << (n % _NFDBITS);\n    }\n\n    extern (D) void FD_CLR( int n, fd_set* p ) pure\n    {\n        p.__fds_bits[n / _NFDBITS] &= ~__fdset_mask(n);\n    }\n\n    extern (D) bool FD_ISSET( int n, const(fd_set)* p ) pure\n    {\n        return (p.__fds_bits[n / _NFDBITS] & __fdset_mask(n)) != 0;\n    }\n\n    extern (D) void FD_SET( int n, fd_set* p ) pure\n    {\n        p.__fds_bits[n / _NFDBITS] |= __fdset_mask(n);\n    }\n\n    extern (D) void FD_ZERO( fd_set* p ) pure\n    {\n        fd_set *_p;\n        size_t _n;\n\n        _p = p;\n        _n = (FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS;\n        while (_n > 0)\n            _p.__fds_bits[--_n] = 0;\n    }\n\n    int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);\n    int select(int, fd_set*, fd_set*, fd_set*, timeval*);\n}\nelse version (Solaris)\n{\n    private\n    {\n        alias c_long fds_mask;\n\n        enum _NBBY = 8;\n        enum FD_NFDBITS = fds_mask.sizeof * _NBBY;\n    }\n\n    version (D_LP64)\n        enum uint FD_SETSIZE = 65536;\n    else\n        enum uint FD_SETSIZE = 1024;\n\n    struct fd_set\n    {\n        c_long[(FD_SETSIZE + (FD_NFDBITS - 1)) / FD_NFDBITS] fds_bits;\n    }\n\n    extern (D) void FD_SET(int __n, fd_set* __p) pure\n    {\n        __p.fds_bits[__n / FD_NFDBITS] |= 1UL << (__n % FD_NFDBITS);\n    }\n\n    extern (D) void FD_CLR(int __n, fd_set* __p) pure\n    {\n        __p.fds_bits[__n / FD_NFDBITS] &= ~(1UL << (__n % FD_NFDBITS));\n    }\n\n    extern (D) bool FD_ISSET(int __n, const(fd_set)* __p) pure\n    {\n        return (__p.fds_bits[__n / FD_NFDBITS] & (1UL << (__n % FD_NFDBITS))) != 0;\n    }\n\n    extern (D) void FD_ZERO(fd_set* __p) pure\n    {\n        __p.fds_bits[0 .. $] = 0;\n    }\n\n    int select(int, fd_set*, fd_set*, fd_set*, timeval*);\n    int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);\n}\nelse version (CRuntime_Bionic)\n{\n    private\n    {\n        alias c_ulong __fd_mask;\n        enum uint __NFDBITS = 8 * __fd_mask.sizeof;\n\n        extern (D) auto __FDELT( int d ) pure\n        {\n            return d / __NFDBITS;\n        }\n\n        extern (D) auto __FDMASK( int d ) pure\n        {\n            return cast(__fd_mask) 1 << ( d % __NFDBITS );\n        }\n    }\n\n    enum FD_SETSIZE = 1024;\n\n    struct fd_set\n    {\n        __fd_mask[FD_SETSIZE / __NFDBITS] fds_bits;\n    }\n\n    // These functions are generated in assembly in bionic.\n    extern (D) void FD_CLR( int fd, fd_set* fdset ) pure\n    {\n        fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );\n    }\n\n    extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure\n    {\n        return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;\n    }\n\n    extern (D) void FD_SET( int fd, fd_set* fdset ) pure\n    {\n        fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );\n    }\n\n    extern (D) void FD_ZERO( fd_set* fdset ) pure\n    {\n        fdset.fds_bits[0 .. $] = 0;\n    }\n\n    int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);\n    int select(int, fd_set*, fd_set*, fd_set*, timeval*);\n}\nelse version (CRuntime_Musl)\n{\n    enum FD_SETSIZE = 1024;\n\n    alias ulong fd_mask;\n\n    private\n    {\n        enum uint __NFDBITS = 8 * fd_mask.sizeof;\n\n        extern (D) auto __FDELT( int d ) pure\n        {\n            return d / __NFDBITS;\n        }\n\n        extern (D) auto __FDMASK( int d ) pure\n        {\n            return cast(fd_mask) 1 << ( d % __NFDBITS );\n        }\n    }\n\n    struct fd_set {\n        ulong[FD_SETSIZE / 8 / long.sizeof] fds_bits;\n    }\n\n    extern (D) void FD_CLR( int fd, fd_set* fdset ) pure\n    {\n        fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );\n    }\n\n    extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure\n    {\n        return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;\n    }\n\n    extern (D) void FD_SET( int fd, fd_set* fdset ) pure\n    {\n        fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );\n    }\n\n    extern (D) void FD_ZERO( fd_set* fdset ) pure\n    {\n        fdset.fds_bits[0 .. $] = 0;\n    }\n    int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);\n    int select(int, fd_set*, fd_set*, fd_set*, timeval*);\n}\nelse version (CRuntime_UClibc)\n{\n    private\n    {\n        alias c_long __fd_mask;\n        enum uint __NFDBITS = 8 * __fd_mask.sizeof;\n\n        extern (D) auto __FDELT( int d ) pure\n        {\n            return d / __NFDBITS;\n        }\n\n        extern (D) auto __FDMASK( int d ) pure\n        {\n            return cast(__fd_mask) 1 << ( d % __NFDBITS );\n        }\n    }\n\n    enum FD_SETSIZE = 1024;\n\n    struct fd_set\n    {\n        __fd_mask[FD_SETSIZE / __NFDBITS] fds_bits;\n    }\n\n    extern (D) void FD_CLR( int fd, fd_set* fdset ) pure\n    {\n        fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );\n    }\n\n    extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure\n    {\n        return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;\n    }\n\n    extern (D) void FD_SET( int fd, fd_set* fdset ) pure\n    {\n        fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );\n    }\n\n    extern (D) void FD_ZERO( fd_set* fdset ) pure\n    {\n        fdset.fds_bits[0 .. $] = 0;\n    }\n\n    int pselect(int, fd_set*, fd_set*, fd_set*, in timespec*, in sigset_t*);\n    int select(int, fd_set*, fd_set*, fd_set*, timeval*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\npure unittest\n{\n    debug(select) printf(\"core.sys.posix.sys.select unittest\\n\");\n\n    fd_set fd;\n\n    for (auto i = 0; i < FD_SETSIZE; i++)\n    {\n        assert(!FD_ISSET(i, &fd));\n    }\n\n    for (auto i = 0; i < FD_SETSIZE; i++)\n    {\n        if ((i & -i) == i)\n            FD_SET(i, &fd);\n    }\n\n    for (auto i = 0; i < FD_SETSIZE; i++)\n    {\n        if ((i & -i) == i)\n            assert(FD_ISSET(i, &fd));\n        else\n            assert(!FD_ISSET(i, &fd));\n    }\n\n    for (auto i = 0; i < FD_SETSIZE; i++)\n    {\n        if ((i & -i) == i)\n            FD_CLR(i, &fd);\n        else\n            FD_SET(i, &fd);\n    }\n\n    for (auto i = 0; i < FD_SETSIZE; i++)\n    {\n        if ((i & -i) == i)\n            assert(!FD_ISSET(i, &fd));\n        else\n            assert(FD_ISSET(i, &fd));\n    }\n\n    FD_ZERO(&fd);\n\n    for (auto i = 0; i < FD_SETSIZE; i++)\n    {\n        assert(!FD_ISSET(i, &fd));\n    }\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/shm.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sys.shm;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types; // for pid_t, time_t, key_t\npublic import core.sys.posix.sys.ipc;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// XOpen (XSI)\n//\n/*\nSHM_RDONLY\nSHM_RND\n\nSHMLBA\n\nshmatt_t\n\nstruct shmid_ds\n{\n    ipc_perm    shm_perm;\n    size_t      shm_segsz;\n    pid_t       shm_lpid;\n    pid_t       shm_cpid;\n    shmatt_t    shm_nattch;\n    time_t      shm_atime;\n    time_t      shm_dtime;\n    time_t      shm_ctime;\n}\n\nvoid* shmat(int, in void*, int);\nint   shmctl(int, int, shmid_ds*);\nint   shmdt(in void*);\nint   shmget(key_t, size_t, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum SHM_RDONLY     = 0x01000; // 010000\n    enum SHM_RND        = 0x02000; // 020000\n\n    int   __getpagesize();\n    alias __getpagesize SHMLBA;\n\n    alias c_ulong   shmatt_t;\n\n    /* For any changes, please check /usr/include/bits/shm.h */\n    struct shmid_ds\n    {\n        ipc_perm    shm_perm;\n        size_t      shm_segsz;\n        time_t      shm_atime;\n        version (X86_64) {} else c_ulong     __unused1;\n        time_t      shm_dtime;\n        version (X86_64) {} else c_ulong     __unused2;\n        time_t      shm_ctime;\n        version (X86_64) {} else c_ulong     __unused3;\n        pid_t       shm_cpid;\n        pid_t       shm_lpid;\n        shmatt_t    shm_nattch;\n        c_ulong     __unused4;\n        c_ulong     __unused5;\n    }\n\n    void* shmat(int, in void*, int);\n    int   shmctl(int, int, shmid_ds*);\n    int   shmdt(in void*);\n    int   shmget(key_t, size_t, int);\n}\nelse version (FreeBSD)\n{\n    enum SHM_RDONLY     = 0x01000; // 010000\n    enum SHM_RND        = 0x02000; // 020000\n    enum SHMLBA         = 1 << 12; // PAGE_SIZE = (1<<PAGE_SHIFT)\n\n    alias c_ulong   shmatt_t;\n\n    struct shmid_ds_old // <= FreeBSD7\n    {\n        ipc_perm_old    shm_perm;\n        int             shm_segsz;\n        pid_t           shm_lpid;\n        pid_t           shm_cpid;\n        short           shm_nattch;\n        time_t          shm_atime;\n        time_t          shm_dtime;\n        time_t          shm_ctime;\n        void*           shm_internal;\n    }\n\n    struct shmid_ds\n    {\n         ipc_perm    shm_perm;\n         int         shm_segsz;\n         pid_t       shm_lpid;\n         pid_t       shm_cpid;\n         short       shm_nattch;\n         time_t      shm_atime;\n         time_t      shm_dtime;\n         time_t      shm_ctime;\n    }\n\n    void* shmat(int, in void*, int);\n    int   shmctl(int, int, shmid_ds*);\n    int   shmdt(in void*);\n    int   shmget(key_t, size_t, int);\n}\nelse version (NetBSD)\n{\n    enum SHM_RDONLY     = 0x01000; // 010000\n    enum SHM_RND        = 0x02000; // 020000\n    enum SHMLBA         = 1 << 12; // PAGE_SIZE = (1<<PAGE_SHIFT)\n\n    alias c_ulong   shmatt_t;\n\n    struct shmid_ds\n    {\n        ipc_perm        shm_perm;\n        size_t             shm_segsz;\n        pid_t           shm_lpid;\n        pid_t           shm_cpid;\n        short           shm_nattch;\n        time_t          shm_atime;\n        time_t          shm_dtime;\n        time_t          shm_ctime;\n        void*           shm_internal;\n    }\n\n    void* shmat(int, in void*, int);\n    int   shmctl(int, int, shmid_ds*);\n    int   shmdt(in void*);\n    int   shmget(key_t, size_t, int);\n}\nelse version (DragonFlyBSD)\n{\n    enum SHM_RDONLY     = 0x01000; // 010000\n    enum SHM_RND        = 0x02000; // 020000\n    enum SHMLBA         = 1 << 12; // PAGE_SIZE = (1<<PAGE_SHIFT)\n\n    alias c_ulong   shmatt_t;\n\n    struct shmid_ds\n    {\n         ipc_perm       shm_perm;\n         int            shm_segsz;\n         pid_t          shm_lpid;\n         pid_t          shm_cpid;\n         short          shm_nattch;\n         time_t         shm_atime;\n         time_t         shm_dtime;\n         time_t         shm_ctime;\n         private void*  shm_internal;\n    }\n\n    void* shmat(int, in void*, int);\n    int   shmctl(int, int, shmid_ds*);\n    int   shmdt(in void*);\n    int   shmget(key_t, size_t, int);\n}\nelse version (Darwin)\n{\n\n}\nelse version (CRuntime_UClibc)\n{\n    enum SHM_RDONLY     = 0x1000; // 010000\n    enum SHM_RND        = 0x2000; // 020000\n    enum SHM_REMAP      = 0x4000; // 040000\n\n    int   __getpagesize();\n    alias __getpagesize SHMLBA;\n\n    alias c_ulong   shmatt_t;\n\n    version (X86_64)\n        enum includeUnused  = false;\n    else version (MIPS32)\n        enum includeUnused  = false;\n    else\n        enum includeUnused  = true;\n\n    struct shmid_ds\n    {\n        ipc_perm    shm_perm;\n        size_t      shm_segsz;\n        time_t      shm_atime;\n        static if (includeUnused) c_ulong     __unused1;\n        time_t      shm_dtime;\n        static if (includeUnused) c_ulong     __unused2;\n        time_t      shm_ctime;\n        static if (includeUnused) c_ulong     __unused3;\n        pid_t       shm_cpid;\n        pid_t       shm_lpid;\n        shmatt_t    shm_nattch;\n        c_ulong     __unused4;\n        c_ulong     __unused5;\n    }\n\n    struct shminfo\n    {\n        c_ulong shmmax;\n        c_ulong shmmin;\n        c_ulong shmmni;\n        c_ulong shmseg;\n        c_ulong shmall;\n        c_ulong __unused1;\n        c_ulong __unused2;\n        c_ulong __unused3;\n        c_ulong __unused4;\n    }\n\n    struct shm_info\n    {\n        int used_ids;\n        c_ulong shm_tot;\n        c_ulong shm_rss;\n        c_ulong shm_swp;\n        c_ulong swap_attempts;\n        c_ulong swap_successes;\n    }\n\n    void* shmat(int, in void*, int);\n    int   shmctl(int, int, shmid_ds*);\n    int   shmdt(in void*);\n    int   shmget(key_t, size_t, int);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/socket.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sys.socket;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types; // for ssize_t\npublic import core.sys.posix.sys.uio;   // for iovec\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// Required\n//\n/*\nsocklen_t\nsa_family_t\n\nstruct sockaddr\n{\n    sa_family_t sa_family;\n    char        sa_data[];\n}\n\nstruct sockaddr_storage\n{\n    sa_family_t ss_family;\n}\n\nstruct msghdr\n{\n    void*         msg_name;\n    socklen_t     msg_namelen;\n    struct iovec* msg_iov;\n    int           msg_iovlen;\n    void*         msg_control;\n    socklen_t     msg_controllen;\n    int           msg_flags;\n}\n\nstruct iovec {} // from core.sys.posix.sys.uio\n\nstruct cmsghdr\n{\n    socklen_t cmsg_len;\n    int       cmsg_level;\n    int       cmsg_type;\n}\n\nSCM_RIGHTS\n\nCMSG_DATA(cmsg)\nCMSG_NXTHDR(mhdr,cmsg)\nCMSG_FIRSTHDR(mhdr)\n\nstruct linger\n{\n    int l_onoff;\n    int l_linger;\n}\n\nSOCK_DGRAM\nSOCK_SEQPACKET\nSOCK_STREAM\n\nSOL_SOCKET\n\nSO_ACCEPTCONN\nSO_BROADCAST\nSO_DEBUG\nSO_DONTROUTE\nSO_ERROR\nSO_KEEPALIVE\nSO_LINGER\nSO_OOBINLINE\nSO_RCVBUF\nSO_RCVLOWAT\nSO_RCVTIMEO\nSO_REUSEADDR\nSO_SNDBUF\nSO_SNDLOWAT\nSO_SNDTIMEO\nSO_TYPE\n\nSOMAXCONN\n\nMSG_CTRUNC\nMSG_DONTROUTE\nMSG_EOR\nMSG_OOB\nMSG_PEEK\nMSG_TRUNC\nMSG_WAITALL\n\nAF_INET\nAF_UNIX\nAF_UNSPEC\n\nSHUT_RD\nSHUT_RDWR\nSHUT_WR\n\nint     accept(int, sockaddr*, socklen_t*);\nint     bind(int, in sockaddr*, socklen_t);\nint     connect(int, in sockaddr*, socklen_t);\nint     getpeername(int, sockaddr*, socklen_t*);\nint     getsockname(int, sockaddr*, socklen_t*);\nint     getsockopt(int, int, int, void*, socklen_t*);\nint     listen(int, int);\nssize_t recv(int, void*, size_t, int);\nssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);\nssize_t recvmsg(int, msghdr*, int);\nssize_t send(int, in void*, size_t, int);\nssize_t sendmsg(int, in msghdr*, int);\nssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);\nint     setsockopt(int, int, int, in void*, socklen_t);\nint     shutdown(int, int);\nint     socket(int, int, int);\nint     sockatmark(int);\nint     socketpair(int, int, int, ref int[2]);\n*/\n\nversion (CRuntime_Glibc)\n{\n    // Some of the constants below and from the Bionic section are really from\n    // the linux kernel headers.\n    alias uint   socklen_t;\n    alias ushort sa_family_t;\n\n    struct sockaddr\n    {\n        sa_family_t sa_family;\n        byte[14]    sa_data;\n    }\n\n    private enum : size_t\n    {\n        _SS_SIZE    = 128,\n        _SS_PADSIZE = _SS_SIZE - (c_ulong.sizeof * 2)\n    }\n\n    struct sockaddr_storage\n    {\n        sa_family_t ss_family;\n        c_ulong     __ss_align;\n        byte[_SS_PADSIZE] __ss_padding;\n    }\n\n    struct msghdr\n    {\n        void*     msg_name;\n        socklen_t msg_namelen;\n        iovec*    msg_iov;\n        size_t    msg_iovlen;\n        void*     msg_control;\n        size_t    msg_controllen;\n        int       msg_flags;\n    }\n\n    struct cmsghdr\n    {\n        size_t cmsg_len;\n        int    cmsg_level;\n        int    cmsg_type;\n        static if ( false /* (!is( __STRICT_ANSI__ ) && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L */ )\n        {\n            ubyte[1] __cmsg_data;\n        }\n    }\n\n    enum : uint\n    {\n        SCM_RIGHTS = 0x01\n    }\n\n    static if ( false /* (!is( __STRICT_ANSI__ ) && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L */ )\n    {\n        extern (D) ubyte[1] CMSG_DATA( cmsghdr* cmsg ) pure nothrow @nogc { return cmsg.__cmsg_data; }\n    }\n    else\n    {\n        extern (D) inout(ubyte)*   CMSG_DATA( inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }\n    }\n\n    private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc;\n    extern (D)  inout(cmsghdr)* CMSG_NXTHDR(inout(msghdr)* msg, inout(cmsghdr)* cmsg) pure nothrow @nogc\n    {\n        return __cmsg_nxthdr(msg, cmsg);\n    }\n\n    extern (D) inout(cmsghdr)* CMSG_FIRSTHDR( inout(msghdr)* mhdr ) pure nothrow @nogc\n    {\n        return ( cast(size_t)mhdr.msg_controllen >= cmsghdr.sizeof\n                             ? cast(inout(cmsghdr)*) mhdr.msg_control\n                             : cast(inout(cmsghdr)*) null );\n    }\n\n    extern (D)\n    {\n        size_t CMSG_ALIGN( size_t len ) pure nothrow @nogc\n        {\n            return (len + size_t.sizeof - 1) & cast(size_t) (~(size_t.sizeof - 1));\n        }\n\n        size_t CMSG_LEN( size_t len ) pure nothrow @nogc\n        {\n            return CMSG_ALIGN(cmsghdr.sizeof) + len;\n        }\n    }\n\n    extern (D) size_t CMSG_SPACE(size_t len) pure nothrow @nogc\n    {\n        return CMSG_ALIGN(len) + CMSG_ALIGN(cmsghdr.sizeof);\n    }\n\n    struct linger\n    {\n        int l_onoff;\n        int l_linger;\n    }\n\n    version (X86)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 1\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 30,\n            SO_BROADCAST    = 6,\n            SO_DEBUG        = 1,\n            SO_DONTROUTE    = 5,\n            SO_ERROR        = 4,\n            SO_KEEPALIVE    = 9,\n            SO_LINGER       = 13,\n            SO_OOBINLINE    = 10,\n            SO_RCVBUF       = 8,\n            SO_RCVLOWAT     = 18,\n            SO_RCVTIMEO     = 20,\n            SO_REUSEADDR    = 2,\n            SO_REUSEPORT    = 15,\n            SO_SNDBUF       = 7,\n            SO_SNDLOWAT     = 19,\n            SO_SNDTIMEO     = 21,\n            SO_TYPE         = 3\n        }\n    }\n    else version (X86_64)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 1\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 30,\n            SO_BROADCAST    = 6,\n            SO_DEBUG        = 1,\n            SO_DONTROUTE    = 5,\n            SO_ERROR        = 4,\n            SO_KEEPALIVE    = 9,\n            SO_LINGER       = 13,\n            SO_OOBINLINE    = 10,\n            SO_RCVBUF       = 8,\n            SO_RCVLOWAT     = 18,\n            SO_RCVTIMEO     = 20,\n            SO_REUSEADDR    = 2,\n            SO_REUSEPORT    = 15,\n            SO_SNDBUF       = 7,\n            SO_SNDLOWAT     = 19,\n            SO_SNDTIMEO     = 21,\n            SO_TYPE         = 3\n        }\n    }\n    else version (MIPS32)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 1,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 2,\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 0xffff\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 0x1009,\n            SO_BROADCAST    = 0x0020,\n            SO_DEBUG        = 0x0001,\n            SO_DONTROUTE    = 0x0010,\n            SO_ERROR        = 0x1007,\n            SO_KEEPALIVE    = 0x0008,\n            SO_LINGER       = 0x0080,\n            SO_OOBINLINE    = 0x0100,\n            SO_RCVBUF       = 0x1002,\n            SO_RCVLOWAT     = 0x1004,\n            SO_RCVTIMEO     = 0x1006,\n            SO_REUSEADDR    = 0x0004,\n            SO_SNDBUF       = 0x1001,\n            SO_SNDLOWAT     = 0x1003,\n            SO_SNDTIMEO     = 0x1005,\n            SO_TYPE         = 0x1008,\n        }\n    }\n    else version (MIPS64)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 1,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 2,\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 0xffff\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 0x1009,\n            SO_BROADCAST    = 0x0020,\n            SO_DEBUG        = 0x0001,\n            SO_DONTROUTE    = 0x0010,\n            SO_ERROR        = 0x1007,\n            SO_KEEPALIVE    = 0x0008,\n            SO_LINGER       = 0x0080,\n            SO_OOBINLINE    = 0x0100,\n            SO_RCVBUF       = 0x1002,\n            SO_RCVLOWAT     = 0x1004,\n            SO_RCVTIMEO     = 0x1006,\n            SO_REUSEADDR    = 0x0004,\n            SO_SNDBUF       = 0x1001,\n            SO_SNDLOWAT     = 0x1003,\n            SO_SNDTIMEO     = 0x1005,\n            SO_TYPE         = 0x1008,\n        }\n    }\n    else version (PPC)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 1\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 30,\n            SO_BROADCAST    = 6,\n            SO_DEBUG        = 1,\n            SO_DONTROUTE    = 5,\n            SO_ERROR        = 4,\n            SO_KEEPALIVE    = 9,\n            SO_LINGER       = 13,\n            SO_OOBINLINE    = 10,\n            SO_RCVBUF       = 8,\n            SO_RCVLOWAT     = 16,\n            SO_RCVTIMEO     = 18,\n            SO_REUSEADDR    = 2,\n            SO_SNDBUF       = 7,\n            SO_SNDLOWAT     = 17,\n            SO_SNDTIMEO     = 19,\n            SO_TYPE         = 3\n        }\n    }\n    else version (PPC64)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 1\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 30,\n            SO_BROADCAST    = 6,\n            SO_DEBUG        = 1,\n            SO_DONTROUTE    = 5,\n            SO_ERROR        = 4,\n            SO_KEEPALIVE    = 9,\n            SO_LINGER       = 13,\n            SO_OOBINLINE    = 10,\n            SO_RCVBUF       = 8,\n            SO_RCVLOWAT     = 16,\n            SO_RCVTIMEO     = 18,\n            SO_REUSEADDR    = 2,\n            SO_SNDBUF       = 7,\n            SO_SNDLOWAT     = 17,\n            SO_SNDTIMEO     = 19,\n            SO_TYPE         = 3\n        }\n    }\n    else version (AArch64)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 1\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 30,\n            SO_BROADCAST    = 6,\n            SO_DEBUG        = 1,\n            SO_DONTROUTE    = 5,\n            SO_ERROR        = 4,\n            SO_KEEPALIVE    = 9,\n            SO_LINGER       = 13,\n            SO_OOBINLINE    = 10,\n            SO_RCVBUF       = 8,\n            SO_RCVLOWAT     = 18,\n            SO_RCVTIMEO     = 20,\n            SO_REUSEADDR    = 2,\n            SO_REUSEPORT    = 15,\n            SO_SNDBUF       = 7,\n            SO_SNDLOWAT     = 19,\n            SO_SNDTIMEO     = 21,\n            SO_TYPE         = 3\n        }\n    }\n    else version (ARM)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 1\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 30,\n            SO_BROADCAST    = 6,\n            SO_DEBUG        = 1,\n            SO_DONTROUTE    = 5,\n            SO_ERROR        = 4,\n            SO_KEEPALIVE    = 9,\n            SO_LINGER       = 13,\n            SO_OOBINLINE    = 10,\n            SO_RCVBUF       = 8,\n            SO_RCVLOWAT     = 18,\n            SO_RCVTIMEO     = 20,\n            SO_REUSEADDR    = 2,\n            SO_REUSEPORT    = 15,\n            SO_SNDBUF       = 7,\n            SO_SNDLOWAT     = 19,\n            SO_SNDTIMEO     = 21,\n            SO_TYPE         = 3\n        }\n    }\n    else version (SPARC64)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 1\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 30,\n            SO_BROADCAST    = 6,\n            SO_DEBUG        = 1,\n            SO_DONTROUTE    = 5,\n            SO_ERROR        = 4,\n            SO_KEEPALIVE    = 9,\n            SO_LINGER       = 13,\n            SO_OOBINLINE    = 10,\n            SO_RCVBUF       = 8,\n            SO_RCVLOWAT     = 18,\n            SO_RCVTIMEO     = 20,\n            SO_REUSEADDR    = 2,\n            SO_SNDBUF       = 7,\n            SO_SNDLOWAT     = 19,\n            SO_SNDTIMEO     = 21,\n            SO_TYPE         = 3\n        }\n    }\n    else version (SystemZ)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 1\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 30,\n            SO_BROADCAST    = 6,\n            SO_DEBUG        = 1,\n            SO_DONTROUTE    = 5,\n            SO_ERROR        = 4,\n            SO_KEEPALIVE    = 9,\n            SO_LINGER       = 13,\n            SO_OOBINLINE    = 10,\n            SO_RCVBUF       = 8,\n            SO_RCVLOWAT     = 18,\n            SO_RCVTIMEO     = 20,\n            SO_REUSEADDR    = 2,\n            SO_SNDBUF       = 7,\n            SO_SNDLOWAT     = 19,\n            SO_SNDTIMEO     = 21,\n            SO_TYPE         = 3\n        }\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    enum\n    {\n        SOMAXCONN       = 128\n    }\n\n    enum : uint\n    {\n        MSG_CTRUNC      = 0x08,\n        MSG_DONTROUTE   = 0x04,\n        MSG_EOR         = 0x80,\n        MSG_OOB         = 0x01,\n        MSG_PEEK        = 0x02,\n        MSG_TRUNC       = 0x20,\n        MSG_WAITALL     = 0x100,\n        MSG_NOSIGNAL    = 0x4000\n    }\n\n    enum\n    {\n        AF_APPLETALK    = 5,\n        AF_INET         = 2,\n        AF_IPX          = 4,\n        AF_UNIX         = 1,\n        AF_UNSPEC       = 0,\n        PF_APPLETALK    = AF_APPLETALK,\n        PF_IPX          = AF_IPX\n    }\n\n    enum int SOCK_RDM   = 4;\n\n    enum\n    {\n        SHUT_RD,\n        SHUT_WR,\n        SHUT_RDWR\n    }\n\n    int     accept(int, scope sockaddr*, scope socklen_t*);\n    int     bind(int, const scope sockaddr*, socklen_t);\n    int     connect(int, const scope sockaddr*, socklen_t);\n    int     getpeername(int, scope sockaddr*, scope socklen_t*);\n    int     getsockname(int, scope sockaddr*, scope socklen_t*);\n    int     getsockopt(int, int, int, scope void*, scope socklen_t*);\n    int     listen(int, int) @safe;\n    ssize_t recv(int, scope void*, size_t, int);\n    ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);\n    ssize_t recvmsg(int, scope msghdr*, int);\n    ssize_t send(int, const scope void*, size_t, int);\n    ssize_t sendmsg(int, const scope msghdr*, int);\n    ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);\n    int     setsockopt(int, int, int, const scope void*, socklen_t);\n    int     shutdown(int, int) @safe;\n    int     socket(int, int, int) @safe;\n    int     sockatmark(int) @safe;\n    int     socketpair(int, int, int, ref int[2]) @safe;\n}\nelse version (Darwin)\n{\n    alias uint   socklen_t;\n    alias ubyte  sa_family_t;\n\n    struct sockaddr\n    {\n        ubyte       sa_len;\n        sa_family_t sa_family;\n        byte[14]    sa_data;\n    }\n\n    private enum : size_t\n    {\n        _SS_PAD1    = long.sizeof - ubyte.sizeof - sa_family_t.sizeof,\n        _SS_PAD2    = 128 - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1 - long.sizeof\n    }\n\n    struct sockaddr_storage\n    {\n         ubyte          ss_len;\n         sa_family_t    ss_family;\n         byte[_SS_PAD1] __ss_pad1;\n         long           __ss_align;\n         byte[_SS_PAD2] __ss_pad2;\n    }\n\n    struct msghdr\n    {\n        void*     msg_name;\n        socklen_t msg_namelen;\n        iovec*    msg_iov;\n        int       msg_iovlen;\n        void*     msg_control;\n        socklen_t msg_controllen;\n        int       msg_flags;\n    }\n\n    struct cmsghdr\n    {\n         socklen_t cmsg_len;\n         int       cmsg_level;\n         int       cmsg_type;\n    }\n\n    enum : uint\n    {\n        SCM_RIGHTS = 0x01\n    }\n\n    /+\n    CMSG_DATA(cmsg)     ((unsigned char *)(cmsg) + \\\n                         ALIGN(sizeof(struct cmsghdr)))\n    CMSG_NXTHDR(mhdr, cmsg) \\\n                        (((unsigned char *)(cmsg) + ALIGN((cmsg)->cmsg_len) + \\\n                         ALIGN(sizeof(struct cmsghdr)) > \\\n                         (unsigned char *)(mhdr)->msg_control +(mhdr)->msg_controllen) ? \\\n                         (struct cmsghdr *)0 /* NULL */ : \\\n                         (struct cmsghdr *)((unsigned char *)(cmsg) + ALIGN((cmsg)->cmsg_len)))\n    CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)\n    +/\n\n    struct linger\n    {\n        int l_onoff;\n        int l_linger;\n    }\n\n    enum\n    {\n        SOCK_DGRAM      = 2,\n        SOCK_RDM        = 4,\n        SOCK_SEQPACKET  = 5,\n        SOCK_STREAM     = 1\n    }\n\n    enum : uint\n    {\n        SOL_SOCKET      = 0xffff\n    }\n\n    enum : uint\n    {\n        SO_ACCEPTCONN   = 0x0002,\n        SO_BROADCAST    = 0x0020,\n        SO_DEBUG        = 0x0001,\n        SO_DONTROUTE    = 0x0010,\n        SO_ERROR        = 0x1007,\n        SO_KEEPALIVE    = 0x0008,\n        SO_LINGER       = 0x1080,\n        SO_NOSIGPIPE    = 0x1022, // non-standard\n        SO_OOBINLINE    = 0x0100,\n        SO_RCVBUF       = 0x1002,\n        SO_RCVLOWAT     = 0x1004,\n        SO_RCVTIMEO     = 0x1006,\n        SO_REUSEADDR    = 0x0004,\n        SO_REUSEPORT    = 0x0200,\n        SO_SNDBUF       = 0x1001,\n        SO_SNDLOWAT     = 0x1003,\n        SO_SNDTIMEO     = 0x1005,\n        SO_TYPE         = 0x1008\n    }\n\n    enum\n    {\n        SOMAXCONN       = 128\n    }\n\n    enum : uint\n    {\n        MSG_CTRUNC      = 0x20,\n        MSG_DONTROUTE   = 0x4,\n        MSG_EOR         = 0x8,\n        MSG_OOB         = 0x1,\n        MSG_PEEK        = 0x2,\n        MSG_TRUNC       = 0x10,\n        MSG_WAITALL     = 0x40\n    }\n\n    enum\n    {\n        AF_APPLETALK    = 16,\n        AF_INET         = 2,\n        AF_IPX          = 23,\n        AF_UNIX         = 1,\n        AF_UNSPEC       = 0,\n        PF_APPLETALK    = AF_APPLETALK,\n        PF_IPX          = AF_IPX\n    }\n\n    enum\n    {\n        SHUT_RD,\n        SHUT_WR,\n        SHUT_RDWR\n    }\n\n    int     accept(int, scope sockaddr*, scope socklen_t*);\n    int     bind(int, const scope sockaddr*, socklen_t);\n    int     connect(int, const scope sockaddr*, socklen_t);\n    int     getpeername(int, scope sockaddr*, scope socklen_t*);\n    int     getsockname(int, scope sockaddr*, scope socklen_t*);\n    int     getsockopt(int, int, int, scope void*, scope socklen_t*);\n    int     listen(int, int) @safe;\n    ssize_t recv(int, scope void*, size_t, int);\n    ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);\n    ssize_t recvmsg(int, scope msghdr*, int);\n    ssize_t send(int, const scope void*, size_t, int);\n    ssize_t sendmsg(int, const scope msghdr*, int);\n    ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);\n    int     setsockopt(int, int, int, const scope void*, socklen_t);\n    int     shutdown(int, int) @safe;\n    int     socket(int, int, int) @safe;\n    int     sockatmark(int) @safe;\n    int     socketpair(int, int, int, ref int[2]) @safe;\n}\nelse version (FreeBSD)\n{\n    alias uint   socklen_t;\n    alias ubyte  sa_family_t;\n\n    struct sockaddr\n    {\n        ubyte       sa_len;\n        sa_family_t sa_family;\n        byte[14]    sa_data;\n    }\n\n    private\n    {\n        enum _SS_ALIGNSIZE  = long.sizeof;\n        enum _SS_MAXSIZE    = 128;\n        enum _SS_PAD1SIZE   = _SS_ALIGNSIZE - ubyte.sizeof - sa_family_t.sizeof;\n        enum _SS_PAD2SIZE   = _SS_MAXSIZE - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1SIZE - _SS_ALIGNSIZE;\n    }\n\n    struct sockaddr_storage\n    {\n         ubyte              ss_len;\n         sa_family_t        ss_family;\n         byte[_SS_PAD1SIZE] __ss_pad1;\n         long               __ss_align;\n         byte[_SS_PAD2SIZE] __ss_pad2;\n    }\n\n    struct msghdr\n    {\n        void*     msg_name;\n        socklen_t msg_namelen;\n        iovec*    msg_iov;\n        int       msg_iovlen;\n        void*     msg_control;\n        socklen_t msg_controllen;\n        int       msg_flags;\n    }\n\n    struct cmsghdr\n    {\n         socklen_t cmsg_len;\n         int       cmsg_level;\n         int       cmsg_type;\n    }\n\n    enum : uint\n    {\n        SCM_RIGHTS = 0x01\n    }\n\n    private // <machine/param.h>\n    {\n        enum _ALIGNBYTES = /+c_int+/ int.sizeof - 1;\n        extern (D) size_t _ALIGN( size_t p ) { return (p + _ALIGNBYTES) & ~_ALIGNBYTES; }\n    }\n\n    extern (D) ubyte* CMSG_DATA( cmsghdr* cmsg )\n    {\n        return cast(ubyte*) cmsg + _ALIGN( cmsghdr.sizeof );\n    }\n\n    extern (D) cmsghdr* CMSG_NXTHDR( msghdr* mhdr, cmsghdr* cmsg )\n    {\n        if ( cmsg == null )\n        {\n           return CMSG_FIRSTHDR( mhdr );\n        }\n        else\n        {\n            if ( cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ) + _ALIGN( cmsghdr.sizeof ) >\n                    cast(ubyte*) mhdr.msg_control + mhdr.msg_controllen )\n                return null;\n            else\n                return cast(cmsghdr*) (cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ));\n        }\n    }\n\n    extern (D) cmsghdr* CMSG_FIRSTHDR( msghdr* mhdr )\n    {\n        return mhdr.msg_controllen >= cmsghdr.sizeof ? cast(cmsghdr*) mhdr.msg_control : null;\n    }\n\n    struct linger\n    {\n        int l_onoff;\n        int l_linger;\n    }\n\n    enum\n    {\n        SOCK_DGRAM      = 2,\n        SOCK_RDM        = 4,\n        SOCK_SEQPACKET  = 5,\n        SOCK_STREAM     = 1\n    }\n\n    enum : uint\n    {\n        SOL_SOCKET      = 0xffff\n    }\n\n    enum : uint\n    {\n        SO_ACCEPTCONN   = 0x0002,\n        SO_BROADCAST    = 0x0020,\n        SO_DEBUG        = 0x0001,\n        SO_DONTROUTE    = 0x0010,\n        SO_ERROR        = 0x1007,\n        SO_KEEPALIVE    = 0x0008,\n        SO_LINGER       = 0x0080,\n        SO_NOSIGPIPE    = 0x0800, // non-standard\n        SO_OOBINLINE    = 0x0100,\n        SO_RCVBUF       = 0x1002,\n        SO_RCVLOWAT     = 0x1004,\n        SO_RCVTIMEO     = 0x1006,\n        SO_REUSEADDR    = 0x0004,\n        SO_REUSEPORT    = 0x0200,\n        SO_SNDBUF       = 0x1001,\n        SO_SNDLOWAT     = 0x1003,\n        SO_SNDTIMEO     = 0x1005,\n        SO_TYPE         = 0x1008\n    }\n\n    enum\n    {\n        SOMAXCONN       = 128\n    }\n\n    enum : uint\n    {\n        MSG_CTRUNC      = 0x20,\n        MSG_DONTROUTE   = 0x4,\n        MSG_EOR         = 0x8,\n        MSG_OOB         = 0x1,\n        MSG_PEEK        = 0x2,\n        MSG_TRUNC       = 0x10,\n        MSG_WAITALL     = 0x40,\n        MSG_NOSIGNAL    = 0x20000\n    }\n\n    enum\n    {\n        AF_APPLETALK    = 16,\n        AF_INET         = 2,\n        AF_IPX          = 23,\n        AF_UNIX         = 1,\n        AF_UNSPEC       = 0\n    }\n\n    enum\n    {\n        SHUT_RD = 0,\n        SHUT_WR = 1,\n        SHUT_RDWR = 2\n    }\n\n    int     accept(int, scope sockaddr*, scope socklen_t*);\n    int     bind(int, const scope sockaddr*, socklen_t);\n    int     connect(int, const scope sockaddr*, socklen_t);\n    int     getpeername(int, scope sockaddr*, scope socklen_t*);\n    int     getsockname(int, scope sockaddr*, scope socklen_t*);\n    int     getsockopt(int, int, int, scope void*, scope socklen_t*);\n    int     listen(int, int) @safe;\n    ssize_t recv(int, scope void*, size_t, int);\n    ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);\n    ssize_t recvmsg(int, scope msghdr*, int);\n    ssize_t send(int, const scope void*, size_t, int);\n    ssize_t sendmsg(int, const scope msghdr*, int);\n    ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);\n    int     setsockopt(int, int, int, const scope void*, socklen_t);\n    int     shutdown(int, int) @safe;\n    int     socket(int, int, int) @safe;\n    int     sockatmark(int) @safe;\n    int     socketpair(int, int, int, ref int[2]) @safe;\n}\nelse version (NetBSD)\n{\n    alias uint   socklen_t;\n    alias ubyte  sa_family_t;\n\n    struct sockaddr\n    {\n        ubyte       sa_len;\n        sa_family_t sa_family;\n        byte[14]    sa_data;\n    }\n\n    private\n    {\n        enum _SS_ALIGNSIZE  = long.sizeof;\n        enum _SS_MAXSIZE    = 128;\n        enum _SS_PAD1SIZE   = _SS_ALIGNSIZE - ubyte.sizeof - sa_family_t.sizeof;\n        enum _SS_PAD2SIZE   = _SS_MAXSIZE - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1SIZE - _SS_ALIGNSIZE;\n    }\n\n    struct sockaddr_storage\n    {\n         ubyte              ss_len;\n         sa_family_t        ss_family;\n         byte[_SS_PAD1SIZE] __ss_pad1;\n         long               __ss_align;\n         byte[_SS_PAD2SIZE] __ss_pad2;\n    }\n\n    struct msghdr\n    {\n        void*     msg_name;\n        socklen_t msg_namelen;\n        iovec*    msg_iov;\n        int       msg_iovlen;\n        void*     msg_control;\n        socklen_t msg_controllen;\n        int       msg_flags;\n    }\n\n    struct cmsghdr\n    {\n         socklen_t cmsg_len;\n         int       cmsg_level;\n         int       cmsg_type;\n    }\n\n    enum : uint\n    {\n        SCM_RIGHTS = 0x01\n    }\n\n    private // <machine/param.h>\n    {\n        enum _ALIGNBYTES = /+c_int+/ int.sizeof - 1;\n        extern (D) size_t _ALIGN( size_t p ) { return (p + _ALIGNBYTES) & ~_ALIGNBYTES; }\n    }\n\n    extern (D) ubyte* CMSG_DATA( cmsghdr* cmsg )\n    {\n        return cast(ubyte*) cmsg + _ALIGN( cmsghdr.sizeof );\n    }\n\n    extern (D) cmsghdr* CMSG_NXTHDR( msghdr* mhdr, cmsghdr* cmsg )\n    {\n        if ( cmsg == null )\n        {\n           return CMSG_FIRSTHDR( mhdr );\n        }\n        else\n        {\n            if ( cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ) + _ALIGN( cmsghdr.sizeof ) >\n                    cast(ubyte*) mhdr.msg_control + mhdr.msg_controllen )\n                return null;\n            else\n                return cast(cmsghdr*) (cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ));\n        }\n    }\n\n    extern (D) cmsghdr* CMSG_FIRSTHDR( msghdr* mhdr )\n    {\n        return mhdr.msg_controllen >= cmsghdr.sizeof ? cast(cmsghdr*) mhdr.msg_control : null;\n    }\n\n    struct linger\n    {\n        int l_onoff;\n        int l_linger;\n    }\n\n    enum\n    {\n        SOCK_DGRAM      = 2,\n        SOCK_RDM        = 4,\n        SOCK_SEQPACKET  = 5,\n        SOCK_STREAM     = 1\n    }\n\n    enum : uint\n    {\n        SOL_SOCKET      = 0xffff\n    }\n\n    enum : uint\n    {\n         SO_DEBUG        = 0x0001,          /* turn on debugging info recording */\n         SO_ACCEPTCONN   = 0x0002,          /* socket has had listen() */\n         SO_REUSEADDR    = 0x0004,          /* allow local address reuse */\n         SO_KEEPALIVE    = 0x0008,          /* keep connections alive */\n         SO_DONTROUTE    = 0x0010,          /* just use interface addresses */\n         SO_BROADCAST    = 0x0020,          /* permit sending of broadcast msgs */\n         SO_USELOOPBACK  = 0x0040,          /* bypass hardware when possible */\n         SO_LINGER       = 0x0080,          /* linger on close if data present */\n         SO_OOBINLINE    = 0x0100,          /* leave received OOB data in line */\n         SO_REUSEPORT    = 0x0200,          /* allow local address & port reuse */\n        /*      SO_OTIMESTAMP   0x0400          */\n         SO_NOSIGPIPE    = 0x0800,          /* no SIGPIPE from EPIPE */\n         SO_ACCEPTFILTER = 0x1000,          /* there is an accept filter */\n         SO_TIMESTAMP    = 0x2000,          /* timestamp received dgram traffic */\n\n        /*\n         * Additional options, not kept in so_options.\n         */\n         SO_SNDBUF       = 0x1001,          /* send buffer size */\n         SO_RCVBUF       = 0x1002,          /* receive buffer size */\n         SO_SNDLOWAT     = 0x1003,          /* send low-water mark */\n         SO_RCVLOWAT     = 0x1004,          /* receive low-water mark */\n        /* SO_OSNDTIMEO         0x1005 */\n        /* SO_ORCVTIMEO         0x1006 */\n         SO_ERROR        = 0x1007,          /* get error status and clear */\n         SO_TYPE         = 0x1008,          /* get socket type */\n         SO_OVERFLOWED   = 0x1009,          /* datagrams: return packets dropped */\n\n         SO_NOHEADER     = 0x100a,          /* user supplies no header to kernel;\n                                                 * kernel removes header and supplies\n                                                 * payload\n                                                 */\n         SO_SNDTIMEO     = 0x100b,          /* send timeout */\n         SO_RCVTIMEO     = 0x100c          /* receive timeout */\n\n    }\n\n    enum\n    {\n        SOMAXCONN       = 128\n    }\n\n    enum : uint\n    {\n         MSG_OOB         = 0x0001,          /* process out-of-band data */\n         MSG_PEEK        = 0x0002,          /* peek at incoming message */\n         MSG_DONTROUTE   = 0x0004,          /* send without using routing tables */\n         MSG_EOR         = 0x0008,          /* data completes record */\n         MSG_TRUNC       = 0x0010,          /* data discarded before delivery */\n         MSG_CTRUNC      = 0x0020,          /* control data lost before delivery */\n         MSG_WAITALL     = 0x0040,          /* wait for full request or error */\n         MSG_DONTWAIT    = 0x0080,          /* this message should be nonblocking */\n         MSG_BCAST       = 0x0100,          /* this message was rcvd using link-level brdcst */\n         MSG_MCAST       = 0x0200,          /* this message was rcvd using link-level mcast */\n         MSG_NOSIGNAL    = 0x0400          /* do not generate SIGPIPE on EOF */\n    }\n\n    enum\n    {\n        AF_APPLETALK    = 16,\n        AF_INET         = 2,\n        AF_IPX          = 23,\n        AF_UNIX         = 1,\n        AF_UNSPEC       = 0\n    }\n\n    enum\n    {\n        SHUT_RD = 0,\n        SHUT_WR = 1,\n        SHUT_RDWR = 2\n    }\n\n    int     accept(int, scope sockaddr*, scope socklen_t*);\n    int     bind(int, const scope sockaddr*, socklen_t);\n    int     connect(int, const scope sockaddr*, socklen_t);\n    int     getpeername(int, scope sockaddr*, scope socklen_t*);\n    int     getsockname(int, scope sockaddr*, scope socklen_t*);\n    int     getsockopt(int, int, int, scope void*, scope socklen_t*);\n    int     listen(int, int) @safe;\n    ssize_t recv(int, scope void*, size_t, int);\n    ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);\n    ssize_t recvmsg(int, scope msghdr*, int);\n    ssize_t send(int, const scope void*, size_t, int);\n    ssize_t sendmsg(int, const scope msghdr*, int);\n    ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);\n    int     setsockopt(int, int, int, const scope void*, socklen_t);\n    int     shutdown(int, int) @safe;\n    int     socket(int, int, int) @safe;\n    int     sockatmark(int) @safe;\n    int     socketpair(int, int, int, ref int[2]) @safe;\n}\nelse version (DragonFlyBSD)\n{\n    alias uint   socklen_t;\n    alias ubyte  sa_family_t;\n\n    enum\n    {\n        SOCK_STREAM         = 1,\n        SOCK_DGRAM          = 2,\n        //SOCK_RAW          = 3,      // defined below\n        SOCK_RDM            = 4,\n        SOCK_SEQPACKET      = 5,\n    }\n\n    enum SOCK_CLOEXEC       = 0x10000000;\n    enum SOCK_NONBLOCK      = 0x20000000;\n\n    enum : uint\n    {\n        SO_DEBUG            = 0x0001,\n        SO_ACCEPTCONN       = 0x0002,\n        SO_REUSEADDR        = 0x0004,\n        SO_KEEPALIVE        = 0x0008,\n        SO_DONTROUTE        = 0x0010,\n        SO_BROADCAST        = 0x0020,\n        SO_USELOOPBACK      = 0x0040,\n        SO_LINGER           = 0x0080,\n        SO_OOBINLINE        = 0x0100,\n        SO_REUSEPORT        = 0x0200,\n        SO_TIMESTAMP        = 0x0400,\n        SO_NOSIGPIPE        = 0x0800, // non-standard\n        SO_ACCEPTFILTER     = 0x1000,\n\n        SO_SNDBUF           = 0x1001,\n        SO_RCVBUF           = 0x1002,\n        SO_SNDLOWAT         = 0x1003,\n        SO_RCVLOWAT         = 0x1004,\n        SO_SNDTIMEO         = 0x1005,\n        SO_RCVTIMEO         = 0x1006,\n        SO_ERROR            = 0x1007,\n        SO_TYPE             = 0x1008,\n        SO_SNDSPACE         = 0x100a, // get appr. send buffer free space\n        SO_CPUHINT          = 0x1030, // get socket's owner cpuid hint\n    }\n\n    struct linger\n    {\n        int l_onoff;\n        int l_linger;\n    }\n\n    struct  accept_filter_arg {\n        byte[16] af_name;\n        byte[256-16] af_arg;\n    }\n\n    enum : uint\n    {\n        SOL_SOCKET          = 0xffff\n    }\n\n    enum\n    {\n        AF_UNSPEC           = 0,\n        AF_LOCAL            = 1,\n        AF_UNIX             = AF_LOCAL,\n        AF_INET             = 2,\n        AF_IMPLINK          = 3,\n        AF_PUP              = 4,\n        AF_CHAOS            = 5,\n        AF_NETBIOS          = 6,\n        AF_ISO              = 7,\n        AF_OSI              = AF_ISO,\n        AF_ECMA             = 8,\n        AF_DATAKIT          = 9,\n        AF_CCITT            = 10,\n        AF_SNA              = 11,\n        AF_DECnet           = 12,\n        AF_DLI              = 13,\n        AF_LAT              = 14,\n        AF_HYLINK           = 15,\n        AF_APPLETALK        = 16,\n        AF_ROUTE            = 17,\n        AF_LINK             = 18,\n        pseudo_AF_XTP       = 19,\n        AF_COIP             = 20,\n        AF_CNT              = 21,\n        pseudo_AF_RTIP      = 22,\n        AF_IPX              = 23,\n        AF_SIP              = 24,\n        pseudo_AF_PIP       = 25,\n        AF_ISDN             = 26,\n        AF_E164             = AF_ISDN,\n        pseudo_AF_KEY       = 27,\n        //AF_INET6            = 28,   // defined below\n        AF_NATM             = 29,\n        AF_ATM              = 30,\n        pseudo_AF_HDRCMPLT  = 31,\n        AF_NETGRAPH         = 32,\n        AF_BLUETOOTH        = 33,\n        AF_MPLS             = 34,\n        AF_IEEE80211        = 35,\n    }\n\n    struct sockaddr\n    {\n        ubyte               sa_len;\n        sa_family_t         sa_family;\n        byte[14]            sa_data;\n    }\n\n    enum SOCK_MAXADDRLEN = 255;\n\n    struct sockproto {\n        ushort              sp_family;\n        ushort              sp_protocol;\n    }\n\n    private\n    {\n        enum _SS_ALIGNSIZE  = long.sizeof;\n        enum _SS_MAXSIZE    = 128;\n        enum _SS_PAD1SIZE   = _SS_ALIGNSIZE - ubyte.sizeof - sa_family_t.sizeof;\n        enum _SS_PAD2SIZE   = _SS_MAXSIZE - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1SIZE - _SS_ALIGNSIZE;\n    }\n\n    struct sockaddr_storage\n    {\n        ubyte              ss_len;\n        sa_family_t        ss_family;\n        byte[_SS_PAD1SIZE] __ss_pad1;\n        long               __ss_align;\n        byte[_SS_PAD2SIZE] __ss_pad2;\n    }\n\n    /* protocol families */\n    enum PF_UNSPEC          = AF_UNSPEC;\n    enum PF_LOCAL           = AF_LOCAL;\n    enum PF_UNIX            = PF_LOCAL;\n    enum PF_INET            = AF_INET;\n    enum PF_IMPLINK         = AF_IMPLINK;\n    enum PF_PUP             = AF_PUP;\n    enum PF_CHAOS           = AF_CHAOS;\n    enum PF_NETBIOS         = AF_NETBIOS;\n    enum PF_ISO             = AF_ISO;\n    enum PF_OSI             = AF_ISO;\n    enum PF_ECMA            = AF_ECMA;\n    enum PF_DATAKIT         = AF_DATAKIT;\n    enum PF_CCITT           = AF_CCITT;\n    enum PF_SNA             = AF_SNA;\n    enum PF_DECnet          = AF_DECnet;\n    enum PF_DLI             = AF_DLI;\n    enum PF_LAT             = AF_LAT;\n    enum PF_HYLINK          = AF_HYLINK;\n    enum PF_APPLETALK       = AF_APPLETALK;\n    enum PF_ROUTE           = AF_ROUTE;\n    enum PF_LINK            = AF_LINK;\n    enum PF_XTP             = pseudo_AF_XTP;\n    enum PF_COIP            = AF_COIP;\n    enum PF_CNT             = AF_CNT;\n    enum PF_SIP             = AF_SIP;\n    enum PF_IPX             = AF_IPX;\n    enum PF_RTIP            = pseudo_AF_RTIP;\n    enum PF_PIP             = pseudo_AF_PIP;\n    enum PF_ISDN            = AF_ISDN;\n    enum PF_KEY             = pseudo_AF_KEY;\n    enum PF_INET6           = AF_INET6;\n    enum PF_NATM            = AF_NATM;\n    enum PF_ATM             = AF_ATM;\n    enum PF_NETGRAPH        = AF_NETGRAPH;\n    enum PF_BLUETOOTH       = AF_BLUETOOTH;\n\n    struct msghdr\n    {\n        void*               msg_name;\n        socklen_t           msg_namelen;\n        iovec*              msg_iov;\n        int                 msg_iovlen;\n        void*               msg_control;\n        socklen_t           msg_controllen;\n        int                 msg_flags;\n    }\n\n    enum SOMAXCONN          = 128;\n    enum SOMAXOPT_SIZE      = 65536;\n    enum SOMAXOPT_SIZE0     = (32 * 1024 * 1024);\n\n    enum : uint\n    {\n        MSG_OOB             = 0x00000001,\n        MSG_PEEK            = 0x00000002,\n        MSG_DONTROUTE       = 0x00000004,\n        MSG_EOR             = 0x00000008,\n        MSG_TRUNC           = 0x00000010,\n        MSG_CTRUNC          = 0x00000020,\n        MSG_WAITALL         = 0x00000040,\n        MSG_DONTWAIT        = 0x00000080,\n        MSG_EOF             = 0x00000100,\n        MSG_UNUSED09        = 0x00000200,\n        MSG_NOSIGNAL        = 0x00000400,\n        MSG_SYNC            = 0x00000800,\n        MSG_CMSG_CLOEXEC    = 0x00001000,\n        /* These override FIONBIO.  MSG_FNONBLOCKING is functionally equivalent to MSG_DONTWAIT.*/\n        MSG_FBLOCKING       = 0x00010000,\n        MSG_FNONBLOCKING    = 0x00020000,\n        MSG_FMASK           = 0xFFFF0000,\n    }\n\n    struct cmsghdr\n    {\n         socklen_t          cmsg_len;\n         int                cmsg_level;\n         int                cmsg_type;\n    }\n\n    enum CMGROUP_MAX        = 16;\n\n    struct cmsgcred {\n            pid_t           cmcred_pid;\n            uid_t           cmcred_uid;\n            uid_t           cmcred_euid;\n            gid_t           cmcred_gid;\n            short           cmcred_ngroups;\n            gid_t[CMGROUP_MAX] cmcred_groups;\n    };\n\n    enum : uint\n    {\n        SCM_RIGHTS = 0x01\n    }\n\n    private // <machine/param.h>\n    {\n        enum _ALIGNBYTES = /+c_int+/ int.sizeof - 1;\n        extern (D) size_t _ALIGN( size_t p ) { return (p + _ALIGNBYTES) & ~_ALIGNBYTES; }\n    }\n\n    extern (D) ubyte* CMSG_DATA( cmsghdr* cmsg )\n    {\n        return cast(ubyte*) cmsg + _ALIGN( cmsghdr.sizeof );\n    }\n\n    extern (D) cmsghdr* CMSG_NXTHDR( msghdr* mhdr, cmsghdr* cmsg )\n    {\n        if ( cmsg == null )\n        {\n           return CMSG_FIRSTHDR( mhdr );\n        }\n        else\n        {\n            if ( cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ) + _ALIGN( cmsghdr.sizeof ) >\n                    cast(ubyte*) mhdr.msg_control + mhdr.msg_controllen )\n                return null;\n            else\n                return cast(cmsghdr*) (cast(ubyte*) cmsg + _ALIGN( cmsg.cmsg_len ));\n        }\n    }\n\n    extern (D) cmsghdr* CMSG_FIRSTHDR( msghdr* mhdr )\n    {\n        return mhdr.msg_controllen >= cmsghdr.sizeof ? cast(cmsghdr*) mhdr.msg_control : null;\n    }\n\n    enum\n    {\n        SHUT_RD             = 0,\n        SHUT_WR             = 1,\n        SHUT_RDWR           = 2\n    }\n\n/*\n    /+ sendfile(2) header/trailer struct +/\n    struct sf_hdtr {\n        iovec *             headers;\n        int                 hdr_cnt;\n        iovec *             trailers;\n        int                 trl_cnt;\n    };\n*/\n\n    int     accept(int, sockaddr*, socklen_t*);\n//    int     accept4(int, sockaddr*, socklen_t*, int);\n    int     bind(int, in sockaddr*, socklen_t);\n    int     connect(int, in sockaddr*, socklen_t);\n//    int     extconnect(int, int, sockaddr*, socklen_t);\n    int     getpeername(int, sockaddr*, socklen_t*);\n    int     getsockname(int, sockaddr*, socklen_t*);\n    int     getsockopt(int, int, int, void*, socklen_t*);\n    int     listen(int, int);\n    ssize_t recv(int, void*, size_t, int);\n    ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);\n    ssize_t recvmsg(int, msghdr*, int);\n    ssize_t send(int, in void*, size_t, int);\n    ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);\n    ssize_t sendmsg(int, in msghdr*, int);\n//    int     sendfile(int, int, off_t, size_t, sf_hdtr *, off_t *, int);\n    int     setsockopt(int, int, int, in void*, socklen_t);\n    int     shutdown(int, int);\n    int     sockatmark(int);\n    int     socket(int, int, int);\n    int     socketpair(int, int, int, ref int[2]);\n//  void    pfctlinput(int, struct sockaddr *);\n}\nelse version (Solaris)\n{\n    alias uint socklen_t;\n    alias ushort sa_family_t;\n\n    struct sockaddr\n    {\n        sa_family_t sa_family;\n        char[14] sa_data;\n    }\n\n    alias double sockaddr_maxalign_t;\n\n    private\n    {\n        enum _SS_ALIGNSIZE  = sockaddr_maxalign_t.sizeof;\n        enum _SS_MAXSIZE    = 256;\n        enum _SS_PAD1SIZE   = _SS_ALIGNSIZE - sa_family_t.sizeof;\n        enum _SS_PAD2SIZE   = _SS_MAXSIZE - sa_family_t.sizeof + _SS_PAD1SIZE + _SS_ALIGNSIZE;\n    }\n\n    struct sockaddr_storage\n    {\n         sa_family_t ss_family;\n         char[_SS_PAD1SIZE] _ss_pad1;\n         sockaddr_maxalign_t _ss_align;\n         char[_SS_PAD2SIZE] _ss_pad2;\n    }\n\n    struct msghdr\n    {\n        void* msg_name;\n        socklen_t msg_namelen;\n        iovec* msg_iov;\n        int msg_iovlen;\n        void* msg_control;\n        socklen_t msg_controllen;\n        int msg_flags;\n    }\n\n    struct cmsghdr\n    {\n         socklen_t cmsg_len;\n         int cmsg_level;\n         int cmsg_type;\n    }\n\n    enum : uint\n    {\n        SCM_RIGHTS = 0x1010\n    }\n\n    // FIXME: CMSG_DATA, CMSG_NXTHDR, CMSG_FIRSTHDR missing\n\n    struct linger\n    {\n        int l_onoff;\n        int l_linger;\n    }\n\n    enum\n    {\n        SOCK_STREAM = 2,\n        SOCK_DGRAM = 1,\n        SOCK_RDM = 5,\n        SOCK_SEQPACKET = 6,\n    }\n\n    enum : uint\n    {\n        SOL_SOCKET      = 0xffff\n    }\n\n    enum : uint\n    {\n        SO_ACCEPTCONN   = 0x0002,\n        SO_BROADCAST    = 0x0020,\n        SO_DEBUG        = 0x0001,\n        SO_DONTROUTE    = 0x0010,\n        SO_ERROR        = 0x1007,\n        SO_KEEPALIVE    = 0x0008,\n        SO_LINGER       = 0x0080,\n        SO_OOBINLINE    = 0x0100,\n        SO_RCVBUF       = 0x1002,\n        SO_RCVLOWAT     = 0x1004,\n        SO_RCVTIMEO     = 0x1006,\n        SO_REUSEADDR    = 0x0004,\n        SO_SNDBUF       = 0x1001,\n        SO_SNDLOWAT     = 0x1003,\n        SO_SNDTIMEO     = 0x1005,\n        SO_TYPE         = 0x1008,\n\n        SO_USELOOPBACK  = 0x0040, // non-standard\n        SO_DGRAM_ERRIND = 0x0200, // non-standard\n        SO_RECVUCRED    = 0x0400, // non-standard\n    }\n\n    enum\n    {\n        SOMAXCONN = 128\n    }\n\n    enum : uint\n    {\n        MSG_CTRUNC      = 0x10,\n        MSG_DONTROUTE   = 0x4,\n        MSG_EOR         = 0x8,\n        MSG_OOB         = 0x1,\n        MSG_PEEK        = 0x2,\n        MSG_TRUNC       = 0x20,\n        MSG_WAITALL     = 0x40\n    }\n\n    enum\n    {\n        AF_IPX          = 23,\n        AF_APPLETALK    = 16,\n        AF_INET         = 2,\n        AF_UNIX         = 1,\n        AF_UNSPEC       = 0\n    }\n\n    enum\n    {\n        SHUT_RD,\n        SHUT_WR,\n        SHUT_RDWR\n    }\n\n    int     accept(int, scope sockaddr*, scope socklen_t*);\n    int     bind(int, const scope sockaddr*, socklen_t);\n    int     connect(int, const scope sockaddr*, socklen_t);\n    int     getpeername(int, scope sockaddr*, scope socklen_t*);\n    int     getsockname(int, scope sockaddr*, scope socklen_t*);\n    int     getsockopt(int, int, int, scope void*, scope socklen_t*);\n    int     listen(int, int) @safe;\n    ssize_t recv(int, scope void*, size_t, int);\n    ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);\n    ssize_t recvmsg(int, scope msghdr*, int);\n    ssize_t send(int, const scope void*, size_t, int);\n    ssize_t sendmsg(int, const scope msghdr*, int);\n    ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);\n    int     setsockopt(int, int, int, const scope void*, socklen_t);\n    int     shutdown(int, int) @safe;\n    int     socket(int, int, int) @safe;\n    int     sockatmark(int) @safe;\n    int     socketpair(int, int, int, ref int[2]) @safe;\n}\nelse version (CRuntime_Bionic)\n{\n    alias int    socklen_t;\n    alias ushort sa_family_t;\n\n    struct sockaddr\n    {\n        sa_family_t sa_family;\n        byte[14]    sa_data;\n    }\n\n    private enum size_t _K_SS_MAXSIZE  = 128;\n\n    struct sockaddr_storage\n    {\n        ushort ss_family;\n        byte[_K_SS_MAXSIZE - ushort.sizeof] __data;\n    }\n\n    enum : uint\n    {\n        SCM_RIGHTS = 0x01\n    }\n\n    private enum _ALIGNBYTES = c_long.sizeof - 1;\n\n    extern (D)\n    {\n        size_t CMSG_ALIGN( size_t len )\n        {\n            return (len + _ALIGNBYTES) & ~_ALIGNBYTES;\n        }\n\n        void* CMSG_DATA( cmsghdr* cmsg )\n        {\n            return cast(void*) (cast(char*) cmsg + CMSG_ALIGN( cmsghdr.sizeof ));\n        }\n\n        cmsghdr* CMSG_NXTHDR( msghdr* mhdr, cmsghdr* cmsg )\n        {\n            cmsghdr* __ptr = cast(cmsghdr*) ((cast(ubyte*) cmsg) + CMSG_ALIGN(cmsg.cmsg_len));\n            return cast(c_ulong)( cast(char*)(__ptr+1) - cast(char*) mhdr.msg_control) > mhdr.msg_controllen ? null : __ptr;\n        }\n\n        cmsghdr* CMSG_FIRSTHDR( msghdr* mhdr )\n        {\n            return mhdr.msg_controllen >= cmsghdr.sizeof ? cast(cmsghdr*) mhdr.msg_control : null;\n        }\n    }\n\n    struct linger\n    {\n        int l_onoff;\n        int l_linger;\n    }\n\n    struct msghdr\n    {\n        void*           msg_name;\n        int             msg_namelen;\n        iovec*          msg_iov;\n        __kernel_size_t msg_iovlen;\n        void*           msg_control;\n        __kernel_size_t msg_controllen;\n        uint            msg_flags;\n    }\n\n    struct cmsghdr\n    {\n        __kernel_size_t cmsg_len;\n        int             cmsg_level;\n        int             cmsg_type;\n    }\n\n    version (X86)\n    {\n        alias uint __kernel_size_t;\n\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 1\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 30,\n            SO_BROADCAST    = 6,\n            SO_DEBUG        = 1,\n            SO_DONTROUTE    = 5,\n            SO_ERROR        = 4,\n            SO_KEEPALIVE    = 9,\n            SO_LINGER       = 13,\n            SO_OOBINLINE    = 10,\n            SO_RCVBUF       = 8,\n            SO_RCVLOWAT     = 18,\n            SO_RCVTIMEO     = 20,\n            SO_REUSEADDR    = 2,\n            SO_SNDBUF       = 7,\n            SO_SNDLOWAT     = 19,\n            SO_SNDTIMEO     = 21,\n            SO_TYPE         = 3\n        }\n    }\n    else version (ARM)\n    {\n        alias uint __kernel_size_t;\n\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 1\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 30,\n            SO_BROADCAST    = 6,\n            SO_DEBUG        = 1,\n            SO_DONTROUTE    = 5,\n            SO_ERROR        = 4,\n            SO_KEEPALIVE    = 9,\n            SO_LINGER       = 13,\n            SO_OOBINLINE    = 10,\n            SO_RCVBUF       = 8,\n            SO_RCVLOWAT     = 18,\n            SO_RCVTIMEO     = 20,\n            SO_REUSEADDR    = 2,\n            SO_SNDBUF       = 7,\n            SO_SNDLOWAT     = 19,\n            SO_SNDTIMEO     = 21,\n            SO_TYPE         = 3\n        }\n    }\n    else version (AArch64)\n    {\n        alias ulong __kernel_size_t;\n\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n\n        enum\n        {\n            SOL_SOCKET      = 1\n        }\n\n        enum\n        {\n            SO_ACCEPTCONN   = 30,\n            SO_BROADCAST    = 6,\n            SO_DEBUG        = 1,\n            SO_DONTROUTE    = 5,\n            SO_ERROR        = 4,\n            SO_KEEPALIVE    = 9,\n            SO_LINGER       = 13,\n            SO_OOBINLINE    = 10,\n            SO_RCVBUF       = 8,\n            SO_RCVLOWAT     = 18,\n            SO_RCVTIMEO     = 20,\n            SO_REUSEADDR    = 2,\n            SO_SNDBUF       = 7,\n            SO_SNDLOWAT     = 19,\n            SO_SNDTIMEO     = 21,\n            SO_TYPE         = 3\n        }\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n\n    enum\n    {\n        SOMAXCONN       = 128\n    }\n\n    enum : uint\n    {\n        MSG_CTRUNC      = 0x08,\n        MSG_DONTROUTE   = 0x04,\n        MSG_EOR         = 0x80,\n        MSG_OOB         = 0x01,\n        MSG_PEEK        = 0x02,\n        MSG_TRUNC       = 0x20,\n        MSG_WAITALL     = 0x100\n    }\n\n    enum\n    {\n        AF_APPLETALK    = 5,\n        AF_INET         = 2,\n        AF_IPX          = 4,\n        AF_UNIX         = 1,\n        AF_UNSPEC       = 0\n    }\n\n    enum\n    {\n        SHUT_RD,\n        SHUT_WR,\n        SHUT_RDWR\n    }\n\n    enum SOCK_RDM = 4;\n\n    int     accept(int, scope sockaddr*, scope socklen_t*);\n    int     bind(int, const scope sockaddr*, socklen_t);\n    int     connect(int, const scope sockaddr*, socklen_t);\n    int     getpeername(int, scope sockaddr*, scope socklen_t*);\n    int     getsockname(int, scope sockaddr*, scope socklen_t*);\n    int     getsockopt(int, int, int, scope void*, scope socklen_t*);\n    int     listen(int, int) @safe;\n    ssize_t recv(int, scope void*, size_t, int);\n    ssize_t recvfrom(int, scope void*, size_t, int, scope sockaddr*, scope socklen_t*);\n    int     recvmsg(int, scope msghdr*, int);\n    ssize_t send(int, const scope void*, size_t, int);\n    int     sendmsg(int, const scope msghdr*, int);\n    ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);\n    int     setsockopt(int, int, int, const scope void*, socklen_t);\n    int     shutdown(int, int) @safe;\n    int     socket(int, int, int) @safe;\n    int     sockatmark(int) @safe;\n    int     socketpair(int, int, int, ref int[2]) @safe;\n}\nelse version (CRuntime_Musl)\n{\n    alias uint socklen_t;\n    alias ushort sa_family_t;\n\n    struct sockaddr\n    {\n        sa_family_t sa_family;\n        byte[14]    sa_data;\n    }\n\n    private enum : size_t\n    {\n        _SS_SIZE    = 128,\n        _SS_PADSIZE = _SS_SIZE - c_ulong.sizeof - sa_family_t.sizeof\n    }\n\n    struct sockaddr_storage\n    {\n        sa_family_t ss_family;\n        byte[_SS_PADSIZE] __ss_padding;\n        c_ulong     __ss_align;\n    }\n\n    enum {\n        SOCK_STREAM = 1,\n        SOCK_DGRAM = 2,\n        SOCK_RAW = 3,\n        SOCK_RDM = 4,\n        SOCK_SEQPACKET = 5,\n        SOCK_DCCP = 6,\n        SOCK_PACKET = 10\n    }\n    enum\n    {\n        AF_UNSPEC       = 0,\n        AF_LOCAL        = 1,\n        AF_UNIX         = AF_LOCAL,\n        AF_FILE         = AF_LOCAL,\n        AF_INET         = 2,\n        AF_AX25         = 3,\n        AF_IPX          = 4,\n        AF_APPLETALK    = 5,\n        PF_APPLETALK    = AF_APPLETALK,\n        PF_IPX          = AF_IPX\n    }\n\n    enum\n    {\n        SHUT_RD,\n        SHUT_WR,\n        SHUT_RDWR\n    }\n\n    enum\n    {\n        SOL_SOCKET      = 1\n    }\n\n    enum\n    {\n        SO_DEBUG        = 1,\n        SO_REUSEADDR    = 2,\n        SO_TYPE         = 3,\n        SO_ERROR        = 4,\n        SO_DONTROUTE    = 5,\n        SO_BROADCAST    = 6,\n        SO_SNDBUF       = 7,\n        SO_RCVBUF       = 8,\n        SO_KEEPALIVE    = 9,\n        SO_OOBINLINE    = 10,\n        SO_LINGER       = 13,\n        SO_RCVLOWAT     = 18,\n        SO_SNDLOWAT     = 19,\n        SO_RCVTIMEO     = 20,\n        SO_SNDTIMEO     = 21,\n        SO_ACCEPTCONN   = 30\n    }\n\n    enum : uint\n    {\n        MSG_OOB         = 0x01,\n        MSG_PEEK        = 0x02,\n        MSG_DONTROUTE   = 0x04,\n        MSG_CTRUNC      = 0x08,\n        MSG_TRUNC       = 0x20,\n        MSG_EOR         = 0x80,\n        MSG_WAITALL     = 0x100,\n        MSG_NOSIGNAL    = 0x4000\n    }\n\n    struct linger\n    {\n        int l_onoff;\n        int l_linger;\n    }\n    struct msghdr {\n        void *msg_name;\n        socklen_t msg_namelen;\n        iovec *msg_iov;\n        int msg_iovlen, __pad1;\n        void *msg_control;\n        socklen_t msg_controllen, __pad2;\n        int msg_flags;\n    }\n    int     accept(int, sockaddr*, socklen_t*);\n    int     bind(int, in sockaddr*, socklen_t);\n    int     connect(int, in sockaddr*, socklen_t);\n    int     getpeername(int, sockaddr*, socklen_t*);\n    int     getsockname(int, sockaddr*, socklen_t*);\n    int     getsockopt(int, int, int, void*, socklen_t*);\n    int     listen(int, int);\n    ssize_t recv(int, void*, size_t, int);\n    ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);\n    ssize_t recvmsg(int, msghdr*, int);\n    ssize_t send(int, in void*, size_t, int);\n    ssize_t sendmsg(int, in msghdr*, int);\n    ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);\n    int     setsockopt(int, int, int, in void*, socklen_t);\n    int     shutdown(int, int);\n    int     socket(int, int, int);\n    int     sockatmark(int);\n    int     socketpair(int, int, int, ref int[2]);\n}\nelse version (CRuntime_UClibc)\n{\n    alias uint   socklen_t;\n    alias ushort sa_family_t;\n\n    struct sockaddr\n    {\n        sa_family_t sa_family;\n        byte[14]    sa_data;\n    }\n\n    private enum : size_t\n    {\n        _SS_SIZE    = 128,\n        _SS_PADSIZE = _SS_SIZE - (c_ulong.sizeof * 2)\n    }\n\n    struct sockaddr_storage\n    {\n        sa_family_t ss_family;\n        c_ulong     __ss_align;\n        byte[_SS_PADSIZE] __ss_padding;\n    }\n\n    struct msghdr\n    {\n        void*     msg_name;\n        socklen_t msg_namelen;\n        iovec*    msg_iov;\n        size_t    msg_iovlen;\n        void*     msg_control;\n        size_t    msg_controllen;\n        int       msg_flags;\n    }\n\n    struct cmsghdr\n    {\n        size_t cmsg_len;\n        int    cmsg_level;\n        int    cmsg_type;\n    }\n\n    enum : uint\n    {\n        SCM_RIGHTS = 0x01\n    }\n\n    extern (D) inout(ubyte)*   CMSG_DATA( inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }\n\n    private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc;\n    extern (D)  inout(cmsghdr)* CMSG_NXTHDR(inout(msghdr)* msg, inout(cmsghdr)* cmsg) pure nothrow @nogc\n    {\n        return __cmsg_nxthdr(msg, cmsg);\n    }\n\n    extern (D) inout(cmsghdr)* CMSG_FIRSTHDR( inout(msghdr)* mhdr ) pure nothrow @nogc\n    {\n        return ( cast(size_t)mhdr.msg_controllen >= cmsghdr.sizeof\n                             ? cast(inout(cmsghdr)*) mhdr.msg_control\n                             : cast(inout(cmsghdr)*) null );\n    }\n\n    extern (D)\n    {\n        size_t CMSG_ALIGN( size_t len ) pure nothrow @nogc\n        {\n            return (len + size_t.sizeof - 1) & cast(size_t) (~(size_t.sizeof - 1));\n        }\n\n        size_t CMSG_LEN( size_t len ) pure nothrow @nogc\n        {\n            return CMSG_ALIGN(cmsghdr.sizeof) + len;\n        }\n    }\n\n    extern (D) size_t CMSG_SPACE(size_t len) pure nothrow @nogc\n    {\n        return CMSG_ALIGN(len) + CMSG_ALIGN(cmsghdr.sizeof);\n    }\n\n    struct linger\n    {\n        int l_onoff;\n        int l_linger;\n    }\n\n    version (X86_64)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n    }\n    else version (MIPS32)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 1,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 2,\n        }\n    }\n    else version (ARM)\n    {\n        enum\n        {\n            SOCK_DGRAM      = 2,\n            SOCK_SEQPACKET  = 5,\n            SOCK_STREAM     = 1\n        }\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    enum\n    {\n        SO_ACCEPTCONN   = 30,\n        SO_BROADCAST    = 6,\n        SO_DEBUG        = 1,\n        SO_DONTROUTE    = 5,\n        SO_ERROR        = 4,\n        SO_KEEPALIVE    = 9,\n        SO_LINGER       = 13,\n        SO_OOBINLINE    = 10,\n        SO_RCVBUF       = 8,\n        SO_RCVLOWAT     = 18,\n        SO_RCVTIMEO     = 20,\n        SO_REUSEADDR    = 2,\n        SO_SNDBUF       = 7,\n        SO_SNDLOWAT     = 19,\n        SO_SNDTIMEO     = 21,\n        SO_TYPE         = 3,\n\n        SOL_SOCKET      = 1,\n        SOMAXCONN       = 128\n    }\n\n    enum : uint\n    {\n        MSG_CTRUNC      = 0x08,\n        MSG_DONTROUTE   = 0x04,\n        MSG_EOR         = 0x80,\n        MSG_OOB         = 0x01,\n        MSG_PEEK        = 0x02,\n        MSG_TRUNC       = 0x20,\n        MSG_WAITALL     = 0x100,\n        MSG_NOSIGNAL    = 0x4000\n    }\n\n    enum\n    {\n        AF_APPLETALK    = 5,\n        AF_INET         = 2,\n        AF_IPX          = 4,\n        AF_UNIX         = 1,\n        AF_UNSPEC       = 0,\n        PF_APPLETALK    = AF_APPLETALK,\n        PF_IPX          = AF_IPX\n    }\n\n    enum int SOCK_RDM   = 4;\n\n    enum\n    {\n        SHUT_RD,\n        SHUT_WR,\n        SHUT_RDWR\n    }\n\n    int     accept(int, sockaddr*, socklen_t*);\n    int     bind(int, in sockaddr*, socklen_t);\n    int     connect(int, in sockaddr*, socklen_t);\n    int     getpeername(int, sockaddr*, socklen_t*);\n    int     getsockname(int, sockaddr*, socklen_t*);\n    int     getsockopt(int, int, int, void*, socklen_t*);\n    int     listen(int, int);\n    ssize_t recv(int, void*, size_t, int);\n    ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*);\n    ssize_t recvmsg(int, msghdr*, int);\n    ssize_t send(int, in void*, size_t, int);\n    ssize_t sendmsg(int, in msghdr*, int);\n    ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t);\n    int     setsockopt(int, int, int, in void*, socklen_t);\n    int     shutdown(int, int);\n    int     socket(int, int, int);\n    int     sockatmark(int);\n    int     socketpair(int, int, int, ref int[2]);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// IPV6 (IP6)\n//\n/*\nAF_INET6\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum\n    {\n        AF_INET6    = 10\n    }\n}\nelse version (Darwin)\n{\n    enum\n    {\n        AF_INET6    = 30\n    }\n}\nelse version (FreeBSD)\n{\n    enum\n    {\n        AF_INET6    = 28\n    }\n}\nelse version (NetBSD)\n{\n    enum\n    {\n        AF_INET6    = 24\n    }\n}\nelse version (DragonFlyBSD)\n{\n    enum\n    {\n        AF_INET6    = 28\n    }\n}\nelse version (Solaris)\n{\n    enum\n    {\n        AF_INET6 = 26,\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    enum\n    {\n        AF_INET6    = 10\n    }\n}\nelse version (CRuntime_Musl)\n{\n    enum AF_INET6 = 10;\n}\nelse version (CRuntime_UClibc)\n{\n    enum\n    {\n        AF_INET6    = 10\n    }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Raw Sockets (RS)\n//\n/*\nSOCK_RAW\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum\n    {\n        SOCK_RAW    = 3\n    }\n}\nelse version (Darwin)\n{\n    enum\n    {\n        SOCK_RAW    = 3\n    }\n}\nelse version (FreeBSD)\n{\n    enum\n    {\n        SOCK_RAW    = 3\n    }\n}\nelse version (NetBSD)\n{\n    enum\n    {\n        SOCK_RAW    = 3\n    }\n}\nelse version (DragonFlyBSD)\n{\n    enum\n    {\n        SOCK_RAW    = 3\n    }\n}\nelse version (Solaris)\n{\n    enum\n    {\n        SOCK_RAW = 4,\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    enum\n    {\n        SOCK_RAW    = 3\n    }\n}\nelse version (CRuntime_Musl)\n{\n}\nelse version (CRuntime_UClibc)\n{\n    enum\n    {\n        SOCK_RAW    = 3\n    }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/stat.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sys.stat;\n\nprivate import core.sys.posix.config;\nprivate import core.stdc.stdint;\nprivate import core.sys.posix.time;     // for timespec\npublic import core.sys.posix.sys.types; // for off_t, mode_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// Required\n//\n/*\nstruct stat\n{\n    dev_t   st_dev;\n    ino_t   st_ino;\n    mode_t  st_mode;\n    nlink_t st_nlink;\n    uid_t   st_uid;\n    gid_t   st_gid;\n    off_t   st_size;\n    time_t  st_atime;\n    time_t  st_mtime;\n    time_t  st_ctime;\n}\n\nS_IRWXU\n    S_IRUSR\n    S_IWUSR\n    S_IXUSR\nS_IRWXG\n    S_IRGRP\n    S_IWGRP\n    S_IXGRP\nS_IRWXO\n    S_IROTH\n    S_IWOTH\n    S_IXOTH\nS_ISUID\nS_ISGID\nS_ISVTX\n\nS_ISBLK(m)\nS_ISCHR(m)\nS_ISDIR(m)\nS_ISFIFO(m)\nS_ISREG(m)\nS_ISLNK(m)\nS_ISSOCK(m)\n\nS_TYPEISMQ(buf)\nS_TYPEISSEM(buf)\nS_TYPEISSHM(buf)\n\nint    chmod(in char*, mode_t);\nint    fchmod(int, mode_t);\nint    fstat(int, stat*);\nint    lstat(in char*, stat*);\nint    mkdir(in char*, mode_t);\nint    mkfifo(in char*, mode_t);\nint    stat(in char*, stat*);\nmode_t umask(mode_t);\n */\n\nversion (CRuntime_Glibc)\n{\n    version (X86)\n    {\n        struct stat_t\n        {\n            dev_t       st_dev;\n            ushort      __pad1;\n            static if (!__USE_FILE_OFFSET64)\n            {\n                ino_t       st_ino;\n            }\n            else\n            {\n                uint        __st_ino;\n            }\n            mode_t      st_mode;\n            nlink_t     st_nlink;\n            uid_t       st_uid;\n            gid_t       st_gid;\n            dev_t       st_rdev;\n            ushort      __pad2;\n            off_t       st_size;\n            blksize_t   st_blksize;\n            blkcnt_t    st_blocks;\n            static if (__USE_MISC || __USE_XOPEN2K8)\n            {\n                timespec    st_atim;\n                timespec    st_mtim;\n                timespec    st_ctim;\n                extern(D)\n                {\n                    @property ref time_t st_atime() { return st_atim.tv_sec; }\n                    @property ref time_t st_mtime() { return st_mtim.tv_sec; }\n                    @property ref time_t st_ctime() { return st_ctim.tv_sec; }\n                }\n            }\n            else\n            {\n                time_t      st_atime;\n                ulong_t     st_atimensec;\n                time_t      st_mtime;\n                ulong_t     st_mtimensec;\n                time_t      st_ctime;\n                ulong_t     st_ctimensec;\n            }\n            static if (__USE_FILE_OFFSET64)\n            {\n                ino_t       st_ino;\n            }\n            else\n            {\n                c_ulong     __unused4;\n                c_ulong     __unused5;\n            }\n        }\n    }\n    else version (X86_64)\n    {\n        struct stat_t\n        {\n            dev_t       st_dev;\n            ino_t       st_ino;\n            nlink_t     st_nlink;\n            mode_t      st_mode;\n            uid_t       st_uid;\n            gid_t       st_gid;\n            uint        __pad0;\n            dev_t       st_rdev;\n            off_t       st_size;\n            blksize_t   st_blksize;\n            blkcnt_t    st_blocks;\n            static if (__USE_MISC || __USE_XOPEN2K8)\n            {\n                timespec    st_atim;\n                timespec    st_mtim;\n                timespec    st_ctim;\n                extern(D)\n                {\n                    @property ref time_t st_atime() { return st_atim.tv_sec; }\n                    @property ref time_t st_mtime() { return st_mtim.tv_sec; }\n                    @property ref time_t st_ctime() { return st_ctim.tv_sec; }\n                }\n            }\n            else\n            {\n                time_t      st_atime;\n                ulong_t     st_atimensec;\n                time_t      st_mtime;\n                ulong_t     st_mtimensec;\n                time_t      st_ctime;\n                ulong_t     st_ctimensec;\n            }\n            slong_t[3]     __unused;\n        }\n    }\n    else version (MIPS_O32)\n    {\n        struct stat_t\n        {\n            c_ulong     st_dev;\n            c_long[3]   st_pad1;\n            ino_t       st_ino;\n            mode_t      st_mode;\n            nlink_t     st_nlink;\n            uid_t       st_uid;\n            gid_t       st_gid;\n            c_ulong     st_rdev;\n            static if (!__USE_FILE_OFFSET64)\n            {\n                c_long[2]   st_pad2;\n                off_t       st_size;\n                c_long      st_pad3;\n            }\n            else\n            {\n                c_long[3]   st_pad2;\n                off_t       st_size;\n            }\n            static if (__USE_MISC || __USE_XOPEN2K8)\n            {\n                timespec    st_atim;\n                timespec    st_mtim;\n                timespec    st_ctim;\n                extern(D)\n                {\n                    @property ref time_t st_atime() { return st_atim.tv_sec; }\n                    @property ref time_t st_mtime() { return st_mtim.tv_sec; }\n                    @property ref time_t st_ctime() { return st_ctim.tv_sec; }\n                }\n            }\n            else\n            {\n                time_t      st_atime;\n                c_ulong     st_atimensec;\n                time_t      st_mtime;\n                c_ulong     st_mtimensec;\n                time_t      st_ctime;\n                c_ulong     st_ctimensec;\n            }\n            blksize_t   st_blksize;\n            static if (!__USE_FILE_OFFSET64)\n            {\n                blkcnt_t    st_blocks;\n            }\n            else\n            {\n                c_long      st_pad4;\n                blkcnt_t    st_blocks;\n            }\n            c_long[14]  st_pad5;\n        }\n    }\n    else version (MIPS64)\n    {\n        struct stat_t\n        {\n            c_ulong     st_dev;\n            int[3]      st_pad1;\n            static if (!__USE_FILE_OFFSET64)\n            {\n                ino_t       st_ino;\n            }\n            else\n            {\n                c_ulong     st_ino;\n            }\n            mode_t      st_mode;\n            nlink_t     st_nlink;\n            uid_t       st_uid;\n            gid_t       st_gid;\n            c_ulong     st_rdev;\n            static if (!__USE_FILE_OFFSET64)\n            {\n                uint[2]     st_pad2;\n                off_t       st_size;\n                int         st_pad3;\n            }\n            else\n            {\n                c_long[3]   st_pad2;\n                c_long      st_size;\n            }\n            static if (__USE_MISC || __USE_XOPEN2K8)\n            {\n                timespec    st_atim;\n                timespec    st_mtim;\n                timespec    st_ctim;\n                extern(D)\n                {\n                    @property ref time_t st_atime() { return st_atim.tv_sec; }\n                    @property ref time_t st_mtime() { return st_mtim.tv_sec; }\n                    @property ref time_t st_ctime() { return st_ctim.tv_sec; }\n                }\n            }\n            else\n            {\n                time_t      st_atime;\n                c_ulong     st_atimensec;\n                time_t      st_mtime;\n                c_ulong     st_mtimensec;\n                time_t      st_ctime;\n                c_ulong     st_ctimensec;\n            }\n            blksize_t   st_blksize;\n            uint        st_pad4;\n            static if (!__USE_FILE_OFFSET64)\n            {\n                blkcnt_t    st_blocks;\n            }\n            else\n            {\n                c_long  st_blocks;\n            }\n            c_long[14]  st_pad5;\n        }\n    }\n    else version (PPC)\n    {\n        struct stat_t\n        {\n            c_ulong     st_dev;\n            ino_t       st_ino;\n            mode_t      st_mode;\n            nlink_t     st_nlink;\n            uid_t       st_uid;\n            gid_t       st_gid;\n            c_ulong     st_rdev;\n            off_t       st_size;\n            c_ulong     st_blksize;\n            c_ulong     st_blocks;\n            c_ulong     st_atime;\n            c_ulong     st_atime_nsec;\n            c_ulong     st_mtime;\n            c_ulong     st_mtime_nsec;\n            c_ulong     st_ctime;\n            c_ulong     st_ctime_nsec;\n            c_ulong     __unused4;\n            c_ulong     __unused5;\n        }\n    }\n    else version (PPC64)\n    {\n        struct stat_t\n        {\n            c_ulong     st_dev;\n            ino_t       st_ino;\n            nlink_t     st_nlink;\n            mode_t      st_mode;\n            uid_t       st_uid;\n            gid_t       st_gid;\n            c_ulong     st_rdev;\n            off_t       st_size;\n            c_ulong     st_blksize;\n            c_ulong     st_blocks;\n            c_ulong     st_atime;\n            c_ulong     st_atime_nsec;\n            c_ulong     st_mtime;\n            c_ulong     st_mtime_nsec;\n            c_ulong     st_ctime;\n            c_ulong     st_ctime_nsec;\n            c_ulong     __unused4;\n            c_ulong     __unused5;\n            c_ulong     __unused6;\n        }\n    }\n    else version (ARM)\n    {\n        private\n        {\n            alias __dev_t = ulong;\n            alias __ino_t = c_ulong;\n            alias __ino64_t = ulong;\n            alias __mode_t = uint;\n            alias __nlink_t = size_t;\n            alias __uid_t = uint;\n            alias __gid_t = uint;\n            alias __off_t = c_long;\n            alias __off64_t = long;\n            alias __blksize_t = c_long;\n            alias __blkcnt_t = c_long;\n            alias __blkcnt64_t = long;\n            alias __timespec = timespec;\n            alias __time_t = time_t;\n        }\n        struct stat_t\n        {\n            __dev_t st_dev;\n            ushort __pad1;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                __ino_t st_ino;\n            }\n            else\n            {\n                __ino_t __st_ino;\n            }\n            __mode_t st_mode;\n            __nlink_t st_nlink;\n            __uid_t st_uid;\n            __gid_t st_gid;\n            __dev_t st_rdev;\n            ushort __pad2;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                __off_t st_size;\n            }\n            else\n            {\n                __off64_t st_size;\n            }\n            __blksize_t st_blksize;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                __blkcnt_t st_blocks;\n            }\n            else\n            {\n                __blkcnt64_t st_blocks;\n            }\n\n            static if ( __USE_MISC || __USE_XOPEN2K8)\n            {\n                __timespec st_atim;\n                __timespec st_mtim;\n                __timespec st_ctim;\n                extern(D)\n                {\n                    @property ref time_t st_atime() { return st_atim.tv_sec; }\n                    @property ref time_t st_mtime() { return st_mtim.tv_sec; }\n                    @property ref time_t st_ctime() { return st_ctim.tv_sec; }\n                }\n            }\n            else\n            {\n                __time_t st_atime;\n                c_ulong st_atimensec;\n                __time_t st_mtime;\n                c_ulong st_mtimensec;\n                __time_t st_ctime;\n                c_ulong st_ctimensec;\n            }\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                c_ulong __unused4;\n                c_ulong __unused5;\n            }\n            else\n            {\n                __ino64_t st_ino;\n            }\n        }\n        static if (__USE_FILE_OFFSET64)\n            static assert(stat_t.sizeof == 104);\n        else\n            static assert(stat_t.sizeof == 88);\n    }\n    else version (AArch64)\n    {\n        private\n        {\n            alias __dev_t = ulong;\n            alias __ino_t = c_ulong;\n            alias __ino64_t = ulong;\n            alias __mode_t = uint;\n            alias __nlink_t = uint;\n            alias __uid_t = uint;\n            alias __gid_t = uint;\n            alias __off_t = c_long;\n            alias __off64_t = long;\n            alias __blksize_t = int;\n            alias __blkcnt_t = c_long;\n            alias __blkcnt64_t = long;\n            alias __timespec = timespec;\n            alias __time_t = time_t;\n        }\n        struct stat_t\n        {\n            __dev_t st_dev;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                __ino_t st_ino;\n            }\n            else\n            {\n                __ino64_t st_ino;\n            }\n            __mode_t st_mode;\n            __nlink_t st_nlink;\n            __uid_t st_uid;\n            __gid_t st_gid;\n            __dev_t st_rdev;\n            __dev_t __pad1;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                __off_t st_size;\n            }\n            else\n            {\n                __off64_t st_size;\n            }\n            __blksize_t st_blksize;\n            int __pad2;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                __blkcnt_t st_blocks;\n            }\n            else\n            {\n                __blkcnt64_t st_blocks;\n            }\n\n            static if (__USE_MISC)\n            {\n                __timespec st_atim;\n                __timespec st_mtim;\n                __timespec st_ctim;\n                extern(D)\n                {\n                    @property ref time_t st_atime() { return st_atim.tv_sec; }\n                    @property ref time_t st_mtime() { return st_mtim.tv_sec; }\n                    @property ref time_t st_ctime() { return st_ctim.tv_sec; }\n                }\n            }\n            else\n            {\n                __time_t st_atime;\n                c_ulong st_atimensec;\n                __time_t st_mtime;\n                c_ulong st_mtimensec;\n                __time_t st_ctime;\n                c_ulong st_ctimensec;\n            }\n            int[2] __unused;\n        }\n        static if (__USE_FILE_OFFSET64)\n            static assert(stat_t.sizeof == 128);\n        else\n            static assert(stat_t.sizeof == 128);\n    }\n    else version (SPARC64)\n    {\n        private\n        {\n            alias __dev_t = ulong;\n            alias __ino_t = c_ulong;\n            alias __ino64_t = ulong;\n            alias __mode_t = uint;\n            alias __nlink_t = uint;\n            alias __uid_t = uint;\n            alias __gid_t = uint;\n            alias __off_t = c_long;\n            alias __off64_t = long;\n            alias __blksize_t = c_long;\n            alias __blkcnt_t = c_long;\n            alias __blkcnt64_t = long;\n            alias __timespec = timespec;\n            alias __time_t = time_t;\n        }\n        struct stat_t\n        {\n            __dev_t st_dev;\n            ushort __pad1;\n            __ino_t st_ino;\n            __mode_t st_mode;\n            __nlink_t st_nlink;\n            __uid_t st_uid;\n            __gid_t st_gid;\n            __dev_t st_rdev;\n            ushort __pad2;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                __off_t st_size;\n            }\n            else\n            {\n                __off64_t st_size;\n            }\n            __blksize_t st_blksize;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                __blkcnt_t st_blocks;\n            }\n            else\n            {\n                __blkcnt64_t st_blocks;\n            }\n\n            static if (__USE_XOPEN2K8)\n            {\n                __timespec st_atim;\n                __timespec st_mtim;\n                __timespec st_ctim;\n                extern(D)\n                {\n                    @property ref time_t st_atime() { return st_atim.tv_sec; }\n                    @property ref time_t st_mtime() { return st_mtim.tv_sec; }\n                    @property ref time_t st_ctime() { return st_ctim.tv_sec; }\n                }\n            }\n            else\n            {\n                __time_t st_atime;\n                c_ulong st_atimensec;\n                __time_t st_mtime;\n                c_ulong st_mtimensec;\n                __time_t st_ctime;\n                c_ulong st_ctimensec;\n            }\n\n            c_ulong __unused4;\n            c_ulong __unused5;\n        }\n        static assert(stat_t.sizeof == 144);\n    }\n    else version (SystemZ)\n    {\n        private\n        {\n            alias __dev_t = ulong;\n            alias __ino_t = c_ulong;\n            alias __ino64_t = ulong;\n            alias __mode_t = uint;\n            alias __nlink_t = uint;\n            alias __uid_t = uint;\n            alias __gid_t = uint;\n            alias __off_t = c_long;\n            alias __off64_t = long;\n            alias __blksize_t = int;\n            alias __blkcnt_t = c_long;\n            alias __blkcnt64_t = long;\n            alias __timespec = timespec;\n            alias __time_t = time_t;\n        }\n        struct stat_t\n        {\n            __dev_t st_dev;\n            __ino_t st_ino;\n            __nlink_t st_nlink;\n            __mode_t st_mode;\n            __uid_t st_uid;\n            __gid_t st_gid;\n            int __glibc_reserved0;\n            __dev_t st_rdev;\n            __off_t st_size;\n            static if (__USE_XOPEN2K8)\n            {\n                __timespec st_atim;\n                __timespec st_mtim;\n                __timespec st_ctim;\n                extern(D)\n                {\n                    @property ref time_t st_atime() { return st_atim.tv_sec; }\n                    @property ref time_t st_mtime() { return st_mtim.tv_sec; }\n                    @property ref time_t st_ctime() { return st_ctim.tv_sec; }\n                }\n            }\n            else\n            {\n                __time_t st_atime;\n                c_ulong st_atimensec;\n                __time_t st_mtime;\n                c_ulong st_mtimensec;\n                __time_t st_ctime;\n                c_ulong st_ctimensec;\n            }\n            __blksize_t st_blksize;\n            __blkcnt_t st_blocks;\n            c_long[3] __glibc_reserved;\n        }\n        static if (__USE_XOPEN2K8)\n            static assert(stat_t.sizeof == 144);\n        else\n            static assert(stat_t.sizeof == 144);\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    enum S_IRUSR    = 0x100; // octal 0400\n    enum S_IWUSR    = 0x080; // octal 0200\n    enum S_IXUSR    = 0x040; // octal 0100\n    enum S_IRWXU    = S_IRUSR | S_IWUSR | S_IXUSR;\n\n    enum S_IRGRP    = S_IRUSR >> 3;\n    enum S_IWGRP    = S_IWUSR >> 3;\n    enum S_IXGRP    = S_IXUSR >> 3;\n    enum S_IRWXG    = S_IRWXU >> 3;\n\n    enum S_IROTH    = S_IRGRP >> 3;\n    enum S_IWOTH    = S_IWGRP >> 3;\n    enum S_IXOTH    = S_IXGRP >> 3;\n    enum S_IRWXO    = S_IRWXG >> 3;\n\n    enum S_ISUID    = 0x800; // octal 04000\n    enum S_ISGID    = 0x400; // octal 02000\n    enum S_ISVTX    = 0x200; // octal 01000\n\n    private\n    {\n        extern (D) bool S_ISTYPE( mode_t mode, uint mask )\n        {\n            return ( mode & S_IFMT ) == mask;\n        }\n    }\n\n    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }\n    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }\n    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }\n    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }\n    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }\n    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }\n    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }\n\n    static if ( true /*__USE_POSIX199309*/ )\n    {\n        extern bool S_TYPEISMQ( stat_t* buf )  { return false; }\n        extern bool S_TYPEISSEM( stat_t* buf ) { return false; }\n        extern bool S_TYPEISSHM( stat_t* buf ) { return false; }\n    }\n\n    enum UTIME_NOW = 0x3fffffff;\n    enum UTIME_OMIT = 0x3ffffffe;\n\n    int utimensat(int dirfd, const char *pathname,\n        ref const(timespec)[2] times, int flags);\n    int futimens(int fd, ref const(timespec)[2] times);\n}\nelse version (Darwin)\n{\n    // _DARWIN_FEATURE_64_BIT_INODE stat is default for Mac OSX >10.5 and is\n    // only meaningful type for other OS X/Darwin variants (e.g. iOS).\n    // man stat(2) gives details.\n    struct stat_t\n    {\n        dev_t       st_dev;\n        mode_t      st_mode;\n        nlink_t     st_nlink;\n        ino_t       st_ino;\n        uid_t       st_uid;\n        gid_t       st_gid;\n        dev_t       st_rdev;\n        union\n        {\n            struct\n            {\n                timespec  st_atimespec;\n                timespec  st_mtimespec;\n                timespec  st_ctimespec;\n                timespec  st_birthtimespec;\n            }\n            struct\n            {\n                time_t      st_atime;\n                c_long      st_atimensec;\n                time_t      st_mtime;\n                c_long      st_mtimensec;\n                time_t      st_ctime;\n                c_long      st_ctimensec;\n                time_t      st_birthtime;\n                c_long      st_birthtimensec;\n            }\n        }\n        off_t       st_size;\n        blkcnt_t    st_blocks;\n        blksize_t   st_blksize;\n        uint        st_flags;\n        uint        st_gen;\n        int         st_lspare;\n        long[2]     st_qspare;\n    }\n\n    enum S_IRUSR    = 0x100;  // octal 0400\n    enum S_IWUSR    = 0x080;  // octal 0200\n    enum S_IXUSR    = 0x040;  // octal 0100\n    enum S_IRWXU    = S_IRUSR | S_IWUSR | S_IXUSR;\n\n    enum S_IRGRP    = S_IRUSR >> 3;\n    enum S_IWGRP    = S_IWUSR >> 3;\n    enum S_IXGRP    = S_IXUSR >> 3;\n    enum S_IRWXG    = S_IRWXU >> 3;\n\n    enum S_IROTH    = S_IRGRP >> 3;\n    enum S_IWOTH    = S_IWGRP >> 3;\n    enum S_IXOTH    = S_IXGRP >> 3;\n    enum S_IRWXO    = S_IRWXG >> 3;\n\n    enum S_ISUID    = 0x800; // octal 04000\n    enum S_ISGID    = 0x400; // octal 02000\n    enum S_ISVTX    = 0x200; // octal 01000\n\n    private\n    {\n        extern (D) bool S_ISTYPE( mode_t mode, uint mask )\n        {\n            return ( mode & S_IFMT ) == mask;\n        }\n    }\n\n    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }\n    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }\n    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }\n    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }\n    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }\n    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }\n    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }\n}\nelse version (FreeBSD)\n{\n    // https://github.com/freebsd/freebsd/blob/master/sys/sys/stat.h\n\n    struct stat_t\n    {\n        dev_t       st_dev;\n        ino_t       st_ino;\n        mode_t      st_mode;\n        nlink_t     st_nlink;\n        uid_t       st_uid;\n        gid_t       st_gid;\n        dev_t       st_rdev;\n\n        time_t      st_atime;\n        c_long      __st_atimensec;\n        time_t      st_mtime;\n        c_long      __st_mtimensec;\n        time_t      st_ctime;\n        c_long      __st_ctimensec;\n\n        off_t       st_size;\n        blkcnt_t    st_blocks;\n        blksize_t   st_blksize;\n        fflags_t    st_flags;\n        uint        st_gen;\n        int         st_lspare;\n\n        time_t      st_birthtime;\n        c_long      st_birthtimensec;\n\n        ubyte[16 - timespec.sizeof] padding;\n    }\n\n    enum S_IRUSR    = 0x100; // octal 0000400\n    enum S_IWUSR    = 0x080; // octal 0000200\n    enum S_IXUSR    = 0x040; // octal 0000100\n    enum S_IRWXU    = 0x1C0; // octal 0000700\n\n    enum S_IRGRP    = 0x020;  // octal 0000040\n    enum S_IWGRP    = 0x010;  // octal 0000020\n    enum S_IXGRP    = 0x008;  // octal 0000010\n    enum S_IRWXG    = 0x038;  // octal 0000070\n\n    enum S_IROTH    = 0x4; // 0000004\n    enum S_IWOTH    = 0x2; // 0000002\n    enum S_IXOTH    = 0x1; // 0000001\n    enum S_IRWXO    = 0x7; // 0000007\n\n    enum S_ISUID    = 0x800; // octal 0004000\n    enum S_ISGID    = 0x400; // octal 0002000\n    enum S_ISVTX    = 0x200; // octal 0001000\n\n    private\n    {\n        extern (D) bool S_ISTYPE( mode_t mode, uint mask )\n        {\n            return ( mode & S_IFMT ) == mask;\n        }\n    }\n\n    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }\n    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }\n    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }\n    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }\n    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }\n    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }\n    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }\n\n    enum UTIME_NOW = -1;\n    enum UTIME_OMIT = -2;\n\n    // Since FreeBSD 11:\n    version (none)\n    {\n        int utimensat(int dirfd, const char *pathname,\n            ref const(timespec)[2] times, int flags);\n        int futimens(int fd, ref const(timespec)[2] times);\n    }\n}\nelse version (NetBSD)\n{\n    struct stat_t\n    {\n        dev_t     st_dev;               /* inode's device */\n        mode_t    st_mode;              /* inode protection mode */\n        ino_t     st_ino;               /* inode's number */\n        nlink_t   st_nlink;             /* number of hard links */\n        uid_t     st_uid;               /* user ID of the file's owner */\n        gid_t     st_gid;               /* group ID of the file's group */\n        dev_t     st_rdev;              /* device type */\n        time_t    st_atime;             /* time of last access */\n        long      st_atimensec;         /* nsec of last access */\n        time_t    st_mtime;             /* time of last data modification */\n        long      st_mtimensec;         /* nsec of last data modification */\n        time_t    st_ctime;             /* time of last file status change */\n        long      st_ctimensec;         /* nsec of last file status change */\n        time_t    st_birthtime;         /* time of creation */\n        long      st_birthtimensec;     /* nsec of time of creation */\n        off_t     st_size;              /* file size, in bytes */\n        blkcnt_t  st_blocks;            /* blocks allocated for file */\n        blksize_t st_blksize;           /* optimal blocksize for I/O */\n        uint32_t  st_flags;             /* user defined flags for file */\n        uint32_t  st_gen;               /* file generation number */\n        uint32_t[2]  st_spare;\n    }\n\n    enum S_IRUSR    = 0x100; // octal 0000400\n    enum S_IWUSR    = 0x080; // octal 0000200\n    enum S_IXUSR    = 0x040; // octal 0000100\n    enum S_IRWXU    = 0x1C0; // octal 0000700\n\n    enum S_IRGRP    = 0x020;  // octal 0000040\n    enum S_IWGRP    = 0x010;  // octal 0000020\n    enum S_IXGRP    = 0x008;  // octal 0000010\n    enum S_IRWXG    = 0x038;  // octal 0000070\n\n    enum S_IROTH    = 0x4; // 0000004\n    enum S_IWOTH    = 0x2; // 0000002\n    enum S_IXOTH    = 0x1; // 0000001\n    enum S_IRWXO    = 0x7; // 0000007\n\n    enum S_ISUID    = 0x800; // octal 0004000\n    enum S_ISGID    = 0x400; // octal 0002000\n    enum S_ISVTX    = 0x200; // octal 0001000\n\n    private\n    {\n        extern (D) bool S_ISTYPE( mode_t mode, uint mask )\n        {\n            return ( mode & S_IFMT ) == mask;\n        }\n    }\n\n    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }\n    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }\n    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }\n    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }\n    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }\n    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }\n    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }\n}\nelse version (DragonFlyBSD)\n{\n    struct stat_t {\n            ino_t     st_ino;               /* inode's number */\n            nlink_t   st_nlink;             /* number of hard links */\n            dev_t     st_dev;               /* inode's device */\n            mode_t    st_mode;              /* inode protection mode */\n            uint16_t  st_padding1;\n            uid_t     st_uid;               /* user ID of the file's owner */\n            gid_t     st_gid;               /* group ID of the file's group */\n            dev_t     st_rdev;              /* device type */\n            time_t      st_atime;\n            c_long      __st_atimensec;\n            time_t      st_mtime;\n            c_long      __st_mtimensec;\n            time_t      st_ctime;\n            c_long      __st_ctimensec;\n            off_t     st_size;              /* file size, in bytes */\n            int64_t   st_blocks;            /* blocks allocated for file */\n            uint32_t  st_blksize;           /* optimal blocksize for I/O */\n            uint32_t  st_flags;             /* user defined flags for file */\n            uint32_t  st_gen;               /* file generation number */\n            int32_t   st_lspare;\n            int64_t   st_qspare1;           /* was recursive change detect */\n            int64_t   st_qspare2;\n    };\n\n    enum S_IRUSR    = 0x100; // octal 0000400\n    enum S_IWUSR    = 0x080; // octal 0000200\n    enum S_IXUSR    = 0x040; // octal 0000100\n    enum S_IRWXU    = 0x1C0; // octal 0000700\n\n    enum S_IRGRP    = 0x020;  // octal 0000040\n    enum S_IWGRP    = 0x010;  // octal 0000020\n    enum S_IXGRP    = 0x008;  // octal 0000010\n    enum S_IRWXG    = 0x038;  // octal 0000070\n\n    enum S_IROTH    = 0x4; // 0000004\n    enum S_IWOTH    = 0x2; // 0000002\n    enum S_IXOTH    = 0x1; // 0000001\n    enum S_IRWXO    = 0x7; // 0000007\n\n    enum S_ISUID    = 0x800; // octal 0004000\n    enum S_ISGID    = 0x400; // octal 0002000\n    enum S_ISVTX    = 0x200; // octal 0001000\n\n    private\n    {\n        extern (D) bool S_ISTYPE( mode_t mode, uint mask )\n        {\n            return ( mode & S_IFMT ) == mask;\n        }\n    }\n\n    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }\n    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }\n    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }\n    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }\n    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }\n    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }\n    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }\n}\nelse version (Solaris)\n{\n    private enum _ST_FSTYPSZ = 16;\n\n    version (D_LP64)\n    {\n        struct stat_t\n        {\n            dev_t st_dev;\n            ino_t st_ino;\n            mode_t st_mode;\n            nlink_t st_nlink;\n            uid_t st_uid;\n            gid_t st_gid;\n            dev_t st_rdev;\n            off_t st_size;\n            union\n            {\n                timestruc_t st_atim;\n                time_t      st_atime;\n            }\n            union\n            {\n                timestruc_t st_mtim;\n                time_t      st_mtime;\n            }\n            union\n            {\n                timestruc_t st_ctim;\n                time_t      st_ctime;\n            }\n            blksize_t st_blksize;\n            blkcnt_t st_blocks;\n            char[_ST_FSTYPSZ] st_fstype;\n        }\n\n        static if (__USE_LARGEFILE64) alias stat_t stat64_t;\n    }\n    else\n    {\n        struct stat32_t\n        {\n            dev_t st_dev;\n            c_long[3] st_pad1;\n            ino_t st_ino;\n            mode_t st_mode;\n            nlink_t st_nlink;\n            uid_t st_uid;\n            gid_t st_gid;\n            dev_t st_rdev;\n            c_long[2] st_pad2;\n            off_t st_size;\n            c_long st_pad3;\n            union\n            {\n                timestruc_t st_atim;\n                time_t      st_atime;\n            }\n            union\n            {\n                timestruc_t st_mtim;\n                time_t      st_mtime;\n            }\n            union\n            {\n                timestruc_t st_ctim;\n                time_t      st_ctime;\n            }\n            blksize_t st_blksize;\n            blkcnt_t st_blocks;\n            char[_ST_FSTYPSZ] st_fstype;\n            c_long[8] st_pad4;\n        }\n\n        struct stat64_t\n        {\n            dev_t st_dev;\n            c_long[3] st_pad1;\n            ino64_t st_ino;\n            mode_t st_mode;\n            nlink_t st_nlink;\n            uid_t st_uid;\n            gid_t st_gid;\n            dev_t st_rdev;\n            c_long[2] st_pad2;\n            off64_t st_size;\n            c_long st_pad3;\n            union\n            {\n                timestruc_t st_atim;\n                time_t      st_atime;\n            }\n            union\n            {\n                timestruc_t st_mtim;\n                time_t      st_mtime;\n            }\n            union\n            {\n                timestruc_t st_ctim;\n                time_t      st_ctime;\n            }\n            blksize_t st_blksize;\n            blkcnt64_t st_blocks;\n            char[_ST_FSTYPSZ] st_fstype;\n            c_long[8] st_pad4;\n        }\n\n        static if (__USE_FILE_OFFSET64)\n            alias stat64_t stat_t;\n        else\n            alias stat32_t stat_t;\n\n    }\n\n    enum S_IRUSR = 0x100;\n    enum S_IWUSR = 0x080;\n    enum S_IXUSR = 0x040;\n    enum S_IRWXU = 0x1C0;\n\n    enum S_IRGRP = 0x020;\n    enum S_IWGRP = 0x010;\n    enum S_IXGRP = 0x008;\n    enum S_IRWXG = 0x038;\n\n    enum S_IROTH = 0x4; // 0000004\n    enum S_IWOTH = 0x2; // 0000002\n    enum S_IXOTH = 0x1; // 0000001\n    enum S_IRWXO = 0x7; // 0000007\n\n    enum S_ISUID = 0x800;\n    enum S_ISGID = 0x400;\n    enum S_ISVTX = 0x200;\n\n    private\n    {\n        extern (D) bool S_ISTYPE(mode_t mode, uint mask)\n        {\n            return (mode & S_IFMT) == mask;\n        }\n    }\n\n    extern (D) bool S_ISBLK(mode_t mode) { return S_ISTYPE(mode, S_IFBLK); }\n    extern (D) bool S_ISCHR(mode_t mode) { return S_ISTYPE(mode, S_IFCHR); }\n    extern (D) bool S_ISDIR(mode_t mode) { return S_ISTYPE(mode, S_IFDIR); }\n    extern (D) bool S_ISFIFO(mode_t mode) { return S_ISTYPE(mode, S_IFIFO); }\n    extern (D) bool S_ISREG(mode_t mode) { return S_ISTYPE(mode, S_IFREG); }\n    extern (D) bool S_ISLNK(mode_t mode) { return S_ISTYPE(mode, S_IFLNK); }\n    extern (D) bool S_ISSOCK(mode_t mode) { return S_ISTYPE(mode, S_IFSOCK); }\n    extern (D) bool S_ISDOOR(mode_t mode) { return S_ISTYPE(mode, S_IFDOOR); }\n    extern (D) bool S_ISPORT(mode_t mode) { return S_ISTYPE(mode, S_IFPORT); }\n}\nelse version (CRuntime_Bionic)\n{\n    version (X86)\n    {\n        struct stat_t\n        {\n            ulong       st_dev;\n            ubyte[4]    __pad0;\n            c_ulong     __st_ino;\n            uint        st_mode;\n            uint        st_nlink;\n            c_ulong     st_uid;\n            c_ulong     st_gid;\n            ulong       st_rdev;\n            ubyte[4]    __pad3;\n\n            long        st_size;\n            c_ulong     st_blksize;\n            ulong       st_blocks;\n            c_ulong     st_atime;\n            c_ulong     st_atime_nsec;\n            c_ulong     st_mtime;\n            c_ulong     st_mtime_nsec;\n            c_ulong     st_ctime;\n            c_ulong     st_ctime_nsec;\n            ulong       st_ino;\n        }\n    }\n    else version (ARM)\n    {\n        struct stat_t\n        {\n            ulong       st_dev;\n            ubyte[4]    __pad0;\n            c_ulong     __st_ino;\n            uint        st_mode;\n            uint        st_nlink;\n            c_ulong     st_uid;\n            c_ulong     st_gid;\n            ulong       st_rdev;\n            ubyte[4]    __pad3;\n\n            long        st_size;\n            c_ulong     st_blksize;\n            ulong       st_blocks;\n            c_ulong     st_atime;\n            c_ulong     st_atime_nsec;\n            c_ulong     st_mtime;\n            c_ulong     st_mtime_nsec;\n            c_ulong     st_ctime;\n            c_ulong     st_ctime_nsec;\n            ulong       st_ino;\n        }\n    }\n    else version (AArch64)\n    {\n        struct stat_t\n        {\n            ulong       st_dev;\n            ulong       st_ino;\n            uint        st_mode;\n            uint        st_nlink;\n            uid_t       st_uid;\n            gid_t       st_gid;\n            ulong       st_rdev;\n            ulong       __pad1;\n\n            long        st_size;\n            int         st_blksize;\n            int         __pad2;\n            long        st_blocks;\n            long        st_atime;\n            ulong       st_atime_nsec;\n            long        st_mtime;\n            ulong       st_mtime_nsec;\n            long        st_ctime;\n            ulong       st_ctime_nsec;\n            uint        __unused4;\n            uint        __unused5;\n        }\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n\n    enum S_IRUSR    = 0x100; // octal 0000400\n    enum S_IWUSR    = 0x080; // octal 0000200\n    enum S_IXUSR    = 0x040; // octal 0000100\n    enum S_IRWXU    = 0x1C0; // octal 0000700\n\n    enum S_IRGRP    = 0x020;  // octal 0000040\n    enum S_IWGRP    = 0x010;  // octal 0000020\n    enum S_IXGRP    = 0x008;  // octal 0000010\n    enum S_IRWXG    = 0x038;  // octal 0000070\n\n    enum S_IROTH    = 0x4; // 0000004\n    enum S_IWOTH    = 0x2; // 0000002\n    enum S_IXOTH    = 0x1; // 0000001\n    enum S_IRWXO    = 0x7; // 0000007\n\n    enum S_ISUID    = 0x800; // octal 0004000\n    enum S_ISGID    = 0x400; // octal 0002000\n    enum S_ISVTX    = 0x200; // octal 0001000\n\n    private\n    {\n        extern (D) bool S_ISTYPE( uint mode, uint mask )\n        {\n            return ( mode & S_IFMT ) == mask;\n        }\n    }\n\n    extern (D) bool S_ISBLK( uint mode )  { return S_ISTYPE( mode, S_IFBLK );  }\n    extern (D) bool S_ISCHR( uint mode )  { return S_ISTYPE( mode, S_IFCHR );  }\n    extern (D) bool S_ISDIR( uint mode )  { return S_ISTYPE( mode, S_IFDIR );  }\n    extern (D) bool S_ISFIFO( uint mode ) { return S_ISTYPE( mode, S_IFIFO );  }\n    extern (D) bool S_ISREG( uint mode )  { return S_ISTYPE( mode, S_IFREG );  }\n    extern (D) bool S_ISLNK( uint mode )  { return S_ISTYPE( mode, S_IFLNK );  }\n    extern (D) bool S_ISSOCK( uint mode ) { return S_ISTYPE( mode, S_IFSOCK ); }\n\n    // Added since Lollipop\n    int utimensat(int dirfd, const char *pathname,\n        ref const(timespec)[2] times, int flags);\n}\nelse version (CRuntime_Musl)\n{\n    alias __mode_t = uint;\n    enum {\n        S_IRUSR    = 0x100, // octal 0400\n        S_IWUSR    = 0x080, // octal 0200\n        S_IXUSR    = 0x040, // octal 0100\n        S_IRWXU    = S_IRUSR | S_IWUSR | S_IXUSR,\n\n        S_IRGRP    = S_IRUSR >> 3,\n        S_IWGRP    = S_IWUSR >> 3,\n        S_IXGRP    = S_IXUSR >> 3,\n        S_IRWXG    = S_IRWXU >> 3,\n\n        S_IROTH    = S_IRGRP >> 3,\n        S_IWOTH    = S_IWGRP >> 3,\n        S_IXOTH    = S_IXGRP >> 3,\n        S_IRWXO    = S_IRWXG >> 3,\n\n        S_ISUID    = 0x800, // octal 04000\n        S_ISGID    = 0x400, // octal 02000\n        S_ISVTX    = 0x200, // octal 01000\n    }\n    struct stat_t {\n        dev_t st_dev;\n        ino_t st_ino;\n        nlink_t st_nlink;\n\n        mode_t st_mode;\n        uid_t st_uid;\n        gid_t st_gid;\n        uint    __pad0;\n        dev_t st_rdev;\n        off_t st_size;\n        blksize_t st_blksize;\n        blkcnt_t st_blocks;\n\n        timespec st_atim;\n        timespec st_mtim;\n        timespec st_ctim;\n        extern(D) @safe @property\n        {\n            ref time_t st_atime() return { return st_atim.tv_sec; }\n            ref time_t st_mtime() return { return st_mtim.tv_sec; }\n            ref time_t st_ctime() return { return st_ctim.tv_sec; }\n        }\n        long[3] __unused;\n    }\n    private\n    {\n        extern (D) bool S_ISTYPE( mode_t mode, uint mask )\n        {\n            return ( mode & S_IFMT ) == mask;\n        }\n    }\n\n    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }\n    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }\n    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }\n    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }\n    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }\n    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }\n    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }\n\n    int utimensat(int dirfd, const char *pathname,\n        ref const(timespec)[2] times, int flags);\n}\nelse version (CRuntime_UClibc)\n{\n    version (X86_64)\n    {\n        struct stat_t\n        {\n            dev_t       st_dev;\n            ino_t       st_ino;\n            nlink_t     st_nlink;\n            mode_t      st_mode;\n            uid_t       st_uid;\n            gid_t       st_gid;\n            uint        __pad0;\n            dev_t       st_rdev;\n            off_t       st_size;\n            blksize_t   st_blksize;\n            blkcnt_t    st_blocks;\n            time_t      st_atime;\n            ulong_t     st_atimensec;\n            time_t      st_mtime;\n            ulong_t     st_mtimensec;\n            time_t      st_ctime;\n            ulong_t     st_ctimensec;\n            slong_t[3]     __unused;\n        }\n    }\n    else version (MIPS_O32)\n    {\n        struct stat_t\n        {\n            c_ulong     st_dev;\n            c_long[3]   st_pad1;\n            ino_t       st_ino;\n            mode_t      st_mode;\n            nlink_t     st_nlink;\n            uid_t       st_uid;\n            gid_t       st_gid;\n            c_ulong     st_rdev;\n            static if (!__USE_FILE_OFFSET64)\n            {\n                c_long[2]   st_pad2;\n                off_t       st_size;\n                c_long      st_pad3;\n            }\n            else\n            {\n                c_long[3]   st_pad2;\n                off_t       st_size;\n            }\n            static if (__USE_MISC || __USE_XOPEN2K8)\n            {\n                timespec    st_atim;\n                timespec    st_mtim;\n                timespec    st_ctim;\n                extern(D)\n                {\n                    @property ref time_t st_atime() { return st_atim.tv_sec; }\n                    @property ref time_t st_mtime() { return st_mtim.tv_sec; }\n                    @property ref time_t st_ctime() { return st_ctim.tv_sec; }\n                }\n            }\n            else\n            {\n                time_t      st_atime;\n                c_ulong     st_atimensec;\n                time_t      st_mtime;\n                c_ulong     st_mtimensec;\n                time_t      st_ctime;\n                c_ulong     st_ctimensec;\n            }\n            blksize_t   st_blksize;\n            static if (!__USE_FILE_OFFSET64)\n            {\n                blkcnt_t    st_blocks;\n            }\n            else\n            {\n                c_long      st_pad4;\n                blkcnt_t    st_blocks;\n            }\n            c_long[14]  st_pad5;\n        }\n    }\n    else version (ARM)\n    {\n        private\n        {\n            alias __dev_t = ulong;\n            alias __ino_t = c_ulong;\n            alias __ino64_t = ulong;\n            alias __mode_t = uint;\n            alias __nlink_t = size_t;\n            alias __uid_t = uint;\n            alias __gid_t = uint;\n            alias __off_t = c_long;\n            alias __off64_t = long;\n            alias __blksize_t = c_long;\n            alias __blkcnt_t = c_long;\n            alias __blkcnt64_t = long;\n            alias __timespec = timespec;\n            alias __time_t = time_t;\n        }\n        struct stat_t\n        {\n            __dev_t st_dev;\n            ushort __pad1;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                __ino_t st_ino;\n            }\n            else\n            {\n                __ino_t __st_ino;\n            }\n            __mode_t st_mode;\n            __nlink_t st_nlink;\n            __uid_t st_uid;\n            __gid_t st_gid;\n            __dev_t st_rdev;\n            ushort __pad2;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                __off_t st_size;\n            }\n            else\n            {\n                __off64_t st_size;\n            }\n            __blksize_t st_blksize;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                __blkcnt_t st_blocks;\n            }\n            else\n            {\n                __blkcnt64_t st_blocks;\n            }\n\n            __time_t st_atime;\n            c_ulong st_atimensec;\n            __time_t st_mtime;\n            c_ulong st_mtimensec;\n            __time_t st_ctime;\n            c_ulong st_ctimensec;\n\n            static if (!__USE_FILE_OFFSET64)\n            {\n                c_ulong __unused4;\n                c_ulong __unused5;\n            }\n            else\n            {\n                __ino64_t st_ino;\n            }\n        }\n        static if (__USE_FILE_OFFSET64)\n            static assert(stat_t.sizeof == 104);\n        else\n            static assert(stat_t.sizeof == 88);\n    }\n    else\n        static assert(0, \"unimplemented\");\n\n    enum S_IRUSR    = 0x100; // octal 0400\n    enum S_IWUSR    = 0x080; // octal 0200\n    enum S_IXUSR    = 0x040; // octal 0100\n    enum S_IRWXU    = S_IRUSR | S_IWUSR | S_IXUSR;\n\n    enum S_IRGRP    = S_IRUSR >> 3;\n    enum S_IWGRP    = S_IWUSR >> 3;\n    enum S_IXGRP    = S_IXUSR >> 3;\n    enum S_IRWXG    = S_IRWXU >> 3;\n\n    enum S_IROTH    = S_IRGRP >> 3;\n    enum S_IWOTH    = S_IWGRP >> 3;\n    enum S_IXOTH    = S_IXGRP >> 3;\n    enum S_IRWXO    = S_IRWXG >> 3;\n\n    enum S_ISUID    = 0x800; // octal 04000\n    enum S_ISGID    = 0x400; // octal 02000\n    enum S_ISVTX    = 0x200; // octal 01000\n\n    private\n    {\n        extern (D) bool S_ISTYPE( mode_t mode, uint mask )\n        {\n            return ( mode & S_IFMT ) == mask;\n        }\n    }\n\n    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }\n    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }\n    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }\n    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }\n    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }\n    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }\n    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }\n\n    static if ( true /*__USE_POSIX199309*/ )\n    {\n        extern bool S_TYPEISMQ( stat_t* buf )  { return false; }\n        extern bool S_TYPEISSEM( stat_t* buf ) { return false; }\n        extern bool S_TYPEISSHM( stat_t* buf ) { return false; }\n    }\n\n    enum UTIME_NOW = 0x3fffffff;\n    enum UTIME_OMIT = 0x3ffffffe;\n\n    int utimensat(int dirfd, const char *pathname,\n    ref const(timespec)[2] times, int flags);\n    int futimens(int fd, ref const(timespec)[2] times);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\nint    chmod(in char*, mode_t);\nint    fchmod(int, mode_t);\n//int    fstat(int, stat_t*);\n//int    lstat(in char*, stat_t*);\nint    mkdir(in char*, mode_t);\nint    mkfifo(in char*, mode_t);\n//int    stat(in char*, stat_t*);\nmode_t umask(mode_t);\n\nversion (CRuntime_Glibc)\n{\n  static if ( __USE_LARGEFILE64 )\n  {\n    int   fstat64(int, stat_t*) @trusted;\n    alias fstat64 fstat;\n\n    int   lstat64(in char*, stat_t*);\n    alias lstat64 lstat;\n\n    int   stat64(in char*, stat_t*);\n    alias stat64 stat;\n  }\n  else\n  {\n    int   fstat(int, stat_t*) @trusted;\n    int   lstat(in char*, stat_t*);\n    int   stat(in char*, stat_t*);\n  }\n}\nelse version (Solaris)\n{\n    version (D_LP64)\n    {\n        int fstat(int, stat_t*) @trusted;\n        int lstat(in char*, stat_t*);\n        int stat(in char*, stat_t*);\n\n        static if (__USE_LARGEFILE64)\n        {\n            alias fstat fstat64;\n            alias lstat lstat64;\n            alias stat stat64;\n        }\n    }\n    else\n    {\n        static if (__USE_LARGEFILE64)\n        {\n            int   fstat64(int, stat_t*) @trusted;\n            alias fstat64 fstat;\n\n            int   lstat64(in char*, stat_t*);\n            alias lstat64 lstat;\n\n            int   stat64(in char*, stat_t*);\n            alias stat64 stat;\n        }\n        else\n        {\n            int fstat(int, stat_t*) @trusted;\n            int lstat(in char*, stat_t*);\n            int stat(in char*, stat_t*);\n        }\n    }\n}\nelse version (Darwin)\n{\n    // OS X maintains backwards compatibility with older binaries using 32-bit\n    // inode functions by appending $INODE64 to newer 64-bit inode functions.\n    version (OSX)\n    {\n        pragma(mangle, \"fstat$INODE64\") int fstat(int, stat_t*);\n        pragma(mangle, \"lstat$INODE64\") int lstat(in char*, stat_t*);\n        pragma(mangle, \"stat$INODE64\")  int stat(in char*, stat_t*);\n    }\n    else\n    {\n        int fstat(int, stat_t*);\n        int lstat(in char*, stat_t*);\n        int stat(in char*, stat_t*);\n    }\n}\nelse version (FreeBSD)\n{\n    int   fstat(int, stat_t*);\n    int   lstat(in char*, stat_t*);\n    int   stat(in char*, stat_t*);\n}\nelse version (NetBSD)\n{\n    int   __fstat50(int, stat_t*);\n    int   __lstat50(in char*, stat_t*);\n    int   __stat50(in char*, stat_t*);\n    alias __fstat50 fstat;\n    alias __lstat50 lstat;\n    alias __stat50 stat;\n}\nelse version (DragonFlyBSD)\n{\n    int   fstat(int, stat_t*);\n    int   lstat(in char*, stat_t*);\n    int   stat(in char*, stat_t*);\n}\nelse version (CRuntime_Bionic)\n{\n    int   fstat(int, stat_t*) @trusted;\n    int   lstat(in char*, stat_t*);\n    int   stat(in char*, stat_t*);\n}\nelse version (CRuntime_Musl)\n{\n    int stat(in char*, stat_t*);\n    int fstat(int, stat_t*);\n    int lstat(in char*, stat_t*);\n\n    alias fstat fstat64;\n    alias lstat lstat64;\n    alias stat stat64;\n}\nelse version (CRuntime_UClibc)\n{\n  static if ( __USE_LARGEFILE64 )\n  {\n    int   fstat64(int, stat_t*) @trusted;\n    alias fstat64 fstat;\n\n    int   lstat64(in char*, stat_t*);\n    alias lstat64 lstat;\n\n    int   stat64(in char*, stat_t*);\n    alias stat64 stat;\n  }\n  else\n  {\n    int   fstat(int, stat_t*) @trusted;\n    int   lstat(in char*, stat_t*);\n    int   stat(in char*, stat_t*);\n  }\n}\n\n//\n// Typed Memory Objects (TYM)\n//\n/*\nS_TYPEISTMO(buf)\n*/\n\n//\n// XOpen (XSI)\n//\n/*\nS_IFMT\nS_IFBLK\nS_IFCHR\nS_IFIFO\nS_IFREG\nS_IFDIR\nS_IFLNK\nS_IFSOCK\n\nint mknod(in 3char*, mode_t, dev_t);\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum S_IFMT     = 0xF000; // octal 0170000\n    enum S_IFBLK    = 0x6000; // octal 0060000\n    enum S_IFCHR    = 0x2000; // octal 0020000\n    enum S_IFIFO    = 0x1000; // octal 0010000\n    enum S_IFREG    = 0x8000; // octal 0100000\n    enum S_IFDIR    = 0x4000; // octal 0040000\n    enum S_IFLNK    = 0xA000; // octal 0120000\n    enum S_IFSOCK   = 0xC000; // octal 0140000\n\n    int mknod(in char*, mode_t, dev_t);\n}\nelse version (Darwin)\n{\n    enum S_IFMT     = 0xF000; // octal 0170000\n    enum S_IFBLK    = 0x6000; // octal 0060000\n    enum S_IFCHR    = 0x2000; // octal 0020000\n    enum S_IFIFO    = 0x1000; // octal 0010000\n    enum S_IFREG    = 0x8000; // octal 0100000\n    enum S_IFDIR    = 0x4000; // octal 0040000\n    enum S_IFLNK    = 0xA000; // octal 0120000\n    enum S_IFSOCK   = 0xC000; // octal 0140000\n\n    int mknod(in char*, mode_t, dev_t);\n}\nelse version (FreeBSD)\n{\n    enum S_IFMT     = 0xF000; // octal 0170000\n    enum S_IFBLK    = 0x6000; // octal 0060000\n    enum S_IFCHR    = 0x2000; // octal 0020000\n    enum S_IFIFO    = 0x1000; // octal 0010000\n    enum S_IFREG    = 0x8000; // octal 0100000\n    enum S_IFDIR    = 0x4000; // octal 0040000\n    enum S_IFLNK    = 0xA000; // octal 0120000\n    enum S_IFSOCK   = 0xC000; // octal 0140000\n\n    int mknod(in char*, mode_t, dev_t);\n}\nelse version (NetBSD)\n{\n    enum S_IFMT     = 0xF000; // octal 0170000\n    enum S_IFBLK    = 0x6000; // octal 0060000\n    enum S_IFCHR    = 0x2000; // octal 0020000\n    enum S_IFIFO    = 0x1000; // octal 0010000\n    enum S_IFREG    = 0x8000; // octal 0100000\n    enum S_IFDIR    = 0x4000; // octal 0040000\n    enum S_IFLNK    = 0xA000; // octal 0120000\n    enum S_IFSOCK   = 0xC000; // octal 0140000\n\n    int mknod(in char*, mode_t, dev_t);\n}\nelse version (DragonFlyBSD)\n{\n    enum S_IFMT     = 0xF000; // octal 0170000\n    enum S_IFBLK    = 0x6000; // octal 0060000\n    enum S_IFCHR    = 0x2000; // octal 0020000\n    enum S_IFIFO    = 0x1000; // octal 0010000\n    enum S_IFREG    = 0x8000; // octal 0100000\n    enum S_IFDIR    = 0x4000; // octal 0040000\n    enum S_IFLNK    = 0xA000; // octal 0120000\n    enum S_IFSOCK   = 0xC000; // octal 0140000\n\n    int mknod(in char*, mode_t, dev_t);\n}\nelse version (Solaris)\n{\n    enum S_IFMT = 0xF000;\n    enum S_IFBLK = 0x6000;\n    enum S_IFCHR = 0x2000;\n    enum S_IFIFO = 0x1000;\n    enum S_IFREG = 0x8000;\n    enum S_IFDIR = 0x4000;\n    enum S_IFLNK = 0xA000;\n    enum S_IFSOCK = 0xC000;\n    enum S_IFDOOR = 0xD000;\n    enum S_IFPORT = 0xE000;\n\n    int mknod(in char*, mode_t, dev_t);\n}\nelse version (CRuntime_Bionic)\n{\n    enum S_IFMT     = 0xF000; // octal 0170000\n    enum S_IFBLK    = 0x6000; // octal 0060000\n    enum S_IFCHR    = 0x2000; // octal 0020000\n    enum S_IFIFO    = 0x1000; // octal 0010000\n    enum S_IFREG    = 0x8000; // octal 0100000\n    enum S_IFDIR    = 0x4000; // octal 0040000\n    enum S_IFLNK    = 0xA000; // octal 0120000\n    enum S_IFSOCK   = 0xC000; // octal 0140000\n\n    int mknod(in char*, mode_t, dev_t);\n}\nelse version (CRuntime_Musl)\n{\n    enum {\n        S_IFMT     = 0xF000, // octal 0170000\n        S_IFBLK    = 0x6000, // octal 0060000\n        S_IFCHR    = 0x2000, // octal 0020000\n        S_IFIFO    = 0x1000, // octal 0010000\n        S_IFREG    = 0x8000, // octal 0100000\n        S_IFDIR    = 0x4000, // octal 0040000\n        S_IFLNK    = 0xA000, // octal 0120000\n        S_IFSOCK   = 0xC000, // octal 0140000\n    }\n\n    int mknod(in char*, mode_t, dev_t);\n}\nelse version (CRuntime_UClibc)\n{\n    enum S_IFMT     = 0xF000; // octal 0170000\n    enum S_IFBLK    = 0x6000; // octal 0060000\n    enum S_IFCHR    = 0x2000; // octal 0020000\n    enum S_IFIFO    = 0x1000; // octal 0010000\n    enum S_IFREG    = 0x8000; // octal 0100000\n    enum S_IFDIR    = 0x4000; // octal 0040000\n    enum S_IFLNK    = 0xA000; // octal 0120000\n    enum S_IFSOCK   = 0xC000; // octal 0140000\n\n    int mknod(in char*, mode_t, dev_t);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/statvfs.d",
    "content": "/++\n    D header file correspoding to sys/statvfs.h.\n\n    Copyright: Copyright 2012 -\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   Robert Klotzner and $(HTTP jmdavisprog.com, Jonathan M Davis)\n    Standards: $(HTTP http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_statvfs.h.html,\n                      The Open Group Base Specifications Issue 7 IEEE Std 1003.1, 2018 Edition)\n +/\nmodule core.sys.posix.sys.statvfs;\nprivate import core.stdc.config;\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types;\n\nversion (Posix):\nextern (C) :\nnothrow:\n@nogc:\n\nversion (CRuntime_Glibc) {\n    static if (__WORDSIZE == 32)\n    {\n        version=_STATVFSBUF_F_UNUSED;\n    }\n    struct statvfs_t\n    {\n        c_ulong f_bsize;\n        c_ulong f_frsize;\n        fsblkcnt_t f_blocks;\n        fsblkcnt_t f_bfree;\n        fsblkcnt_t f_bavail;\n        fsfilcnt_t f_files;\n        fsfilcnt_t f_ffree;\n        fsfilcnt_t f_favail;\n        c_ulong f_fsid;\n        version (_STATVFSBUF_F_UNUSED)\n        {\n            int __f_unused;\n        }\n        c_ulong f_flag;\n        c_ulong f_namemax;\n        int[6] __f_spare;\n    }\n    /* Definitions for the flag in `f_flag'.  These definitions should be\n      kept in sync with the definitions in <sys/mount.h>.  */\n    static if (__USE_GNU)\n    {\n        enum FFlag\n        {\n            ST_RDONLY = 1,        /* Mount read-only.  */\n            ST_NOSUID = 2,\n            ST_NODEV = 4,         /* Disallow access to device special files.  */\n            ST_NOEXEC = 8,        /* Disallow program execution.  */\n            ST_SYNCHRONOUS = 16,      /* Writes are synced at once.  */\n            ST_MANDLOCK = 64,     /* Allow mandatory locks on an FS.  */\n            ST_WRITE = 128,       /* Write on file/directory/symlink.  */\n            ST_APPEND = 256,      /* Append-only file.  */\n            ST_IMMUTABLE = 512,       /* Immutable file.  */\n            ST_NOATIME = 1024,        /* Do not update access times.  */\n            ST_NODIRATIME = 2048,     /* Do not update directory access times.  */\n            ST_RELATIME = 4096        /* Update atime relative to mtime/ctime.  */\n\n        }\n    }  /* Use GNU.  */\n    else\n    { // Posix defined:\n        enum FFlag\n        {\n            ST_RDONLY = 1,        /* Mount read-only.  */\n            ST_NOSUID = 2\n        }\n    }\n\n    static if ( __USE_FILE_OFFSET64 )\n    {\n        int statvfs64 (const char * file, statvfs_t* buf);\n        alias statvfs64 statvfs;\n\n        int fstatvfs64 (int fildes, statvfs_t *buf) @trusted;\n        alias fstatvfs64 fstatvfs;\n    }\n    else\n    {\n        int statvfs (const char * file, statvfs_t* buf);\n        int fstatvfs (int fildes, statvfs_t *buf);\n    }\n\n}\nelse version (NetBSD)\n{\n    enum  _VFS_MNAMELEN = 1024;\n    enum  _VFS_NAMELEN = 32;\n\n    struct fsid_t\n    {\n       int[2] __fsid_val;\n    }\n\n    struct statvfs_t\n    {\n        c_ulong f_flag;\n        c_ulong f_bsize;\n        c_ulong f_frsize;\n        c_ulong f_iosize;\n        fsblkcnt_t f_blocks;\n        fsblkcnt_t f_bfree;\n        fsblkcnt_t f_bavail;\n        fsblkcnt_t f_bresvd;\n        fsfilcnt_t f_files;\n        fsfilcnt_t f_ffree;\n        fsfilcnt_t f_favail;\n        fsfilcnt_t f_fresvd;\n        ulong f_syncreads;\n        ulong f_syncwrites;\n        ulong f_asyncreads;\n        ulong f_asyncwrites;\n        fsid_t f_fsidx;\n        c_ulong f_fsid;\n        c_ulong f_namemax;\n        int f_owner;\n        int[4] f_spare;\n        char[_VFS_NAMELEN] f_fstypename;\n        char[_VFS_MNAMELEN] f_mntonname;\n        char[_VFS_MNAMELEN] f_mntfromname;\n    }\n\n    enum FFlag\n    {\n        ST_RDONLY = 1,        /* Mount read-only.  */\n        ST_NOSUID = 2\n    }\n\n    int statvfs (const char * file, statvfs_t* buf);\n    int fstatvfs (int fildes, statvfs_t *buf) @trusted;\n}\nelse version (FreeBSD)\n{\n    import core.sys.freebsd.sys.mount;\n\n    // @@@DEPRECATED_2.091@@@\n    deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n    alias MFSNAMELEN = core.sys.freebsd.sys.mount.MFSNAMELEN;\n\n    // @@@DEPRECATED_2.091@@@\n    deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n    alias MNAMELEN = core.sys.freebsd.sys.mount.MNAMELEN;\n\n    // @@@DEPRECATED_2.091@@@\n    deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n    alias fsid_t = core.sys.freebsd.sys.mount.fsid_t;\n\n    // @@@DEPRECATED_2.091@@@\n    deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n    alias statfs_t = core.sys.freebsd.sys.mount.statfs_t;\n\n    // @@@DEPRECATED_2.091@@@\n    deprecated(\"Values moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n    enum FFlag\n    {\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_RDONLY = 1,          /* read only filesystem */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_SYNCHRONOUS = 2,     /* fs written synchronously */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_NOEXEC = 4,          /* can't exec from filesystem */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_NOSUID  = 8,         /* don't honor setuid fs bits */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_NFS4ACLS = 16,       /* enable NFS version 4 ACLs */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_UNION = 32,          /* union with underlying fs */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_ASYNC = 64,          /* fs written asynchronously */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_SUIDDIR = 128,       /* special SUID dir handling */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_SOFTDEP = 256,       /* using soft updates */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_NOSYMFOLLOW = 512,   /* do not follow symlinks */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_GJOURNAL = 1024,     /* GEOM journal support enabled */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_MULTILABEL = 2048,   /* MAC support for objects */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_ACLS = 4096,         /* ACL support enabled */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_NOATIME = 8192,      /* dont update file access time */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_NOCLUSTERR = 16384,  /* disable cluster read */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_NOCLUSTERW = 32768,  /* disable cluster write */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_SUJ = 65536,         /* using journaled soft updates */\n\n        // @@@DEPRECATED_2.091@@@\n        deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n        MNT_AUTOMOUNTED = 131072 /* mounted by automountd(8) */\n    }\n\n    deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n    alias statfs = core.sys.freebsd.sys.mount.statfs;\n\n    deprecated(\"Moved to core.sys.freebsd.sys.mount to correspond to C header file sys/mount.h\")\n    alias fstatfs = core.sys.freebsd.sys.mount.fstatfs;\n\n    struct statvfs_t\n    {\n        fsblkcnt_t f_bavail;\n        fsblkcnt_t f_bfree;\n        fsblkcnt_t f_blocks;\n        fsfilcnt_t f_favail;\n        fsfilcnt_t f_ffree;\n        fsfilcnt_t f_files;\n        ulong f_bsize;\n        ulong f_flag;\n        ulong f_frsize;\n        ulong f_fsid;\n        ulong f_namemax;\n    }\n\n    enum uint ST_RDONLY = 0x1;\n    enum uint ST_NOSUID = 0x2;\n\n    int fstatvfs(int, statvfs_t*);\n    int statvfs(const char*, statvfs_t*);\n}\nelse\n{\n    struct statvfs_t\n    {\n        c_ulong f_bsize;\n        c_ulong f_frsize;\n        fsblkcnt_t f_blocks;\n        fsblkcnt_t f_bfree;\n        fsblkcnt_t f_bavail;\n        fsfilcnt_t f_files;\n        fsfilcnt_t f_ffree;\n        fsfilcnt_t f_favail;\n        c_ulong f_fsid;\n        c_ulong f_flag;\n        c_ulong f_namemax;\n    }\n\n    enum FFlag\n    {\n        ST_RDONLY = 1,        /* Mount read-only.  */\n        ST_NOSUID = 2\n    }\n\n    int statvfs (const char * file, statvfs_t* buf);\n    int fstatvfs (int fildes, statvfs_t *buf) @trusted;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/time.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sys.time;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types;  // for time_t, suseconds_t\npublic import core.sys.posix.sys.select; // for fd_set, FD_CLR() FD_ISSET() FD_SET() FD_ZERO() FD_SETSIZE, select()\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (linux) public import core.sys.linux.sys.time;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// XOpen (XSI)\n//\n/*\nstruct timeval\n{\n    time_t      tv_sec;\n    suseconds_t tv_usec;\n}\n\nstruct itimerval\n{\n    timeval it_interval;\n    timeval it_value;\n}\n\nITIMER_REAL\nITIMER_VIRTUAL\nITIMER_PROF\n\nint getitimer(int, itimerval*);\nint gettimeofday(timeval*, void*);\nint select(int, fd_set*, fd_set*, fd_set*, timeval*); (defined in core.sys.posix.sys.signal)\nint setitimer(int, in itimerval*, itimerval*);\nint utimes(in char*, ref const(timeval)[2]); // LEGACY\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct timeval\n    {\n        time_t      tv_sec;\n        suseconds_t tv_usec;\n    }\n\n    struct itimerval\n    {\n        timeval it_interval;\n        timeval it_value;\n    }\n\n    enum ITIMER_REAL    = 0;\n    enum ITIMER_VIRTUAL = 1;\n    enum ITIMER_PROF    = 2;\n\n    int getitimer(int, itimerval*);\n    int gettimeofday(timeval*, void*);\n    int setitimer(int, in itimerval*, itimerval*);\n    int utimes(in char*, ref const(timeval)[2]); // LEGACY\n}\nelse version (CRuntime_Musl)\n{\n    struct timeval\n    {\n        time_t      tv_sec;\n        suseconds_t tv_usec;\n    }\n    int gettimeofday(timeval*, void*);\n    int utimes(in char*, ref const(timeval)[2]);\n}\nelse version (Darwin)\n{\n    struct timeval\n    {\n        time_t      tv_sec;\n        suseconds_t tv_usec;\n    }\n\n    struct itimerval\n    {\n        timeval it_interval;\n        timeval it_value;\n    }\n\n    // non-standard\n    struct timezone_t\n    {\n        int tz_minuteswest;\n        int tz_dsttime;\n    }\n\n    int getitimer(int, itimerval*);\n    int gettimeofday(timeval*, timezone_t*); // timezone_t* is normally void*\n    int setitimer(int, in itimerval*, itimerval*);\n    int utimes(in char*, ref const(timeval)[2]);\n}\nelse version (FreeBSD)\n{\n    struct timeval\n    {\n        time_t      tv_sec;\n        suseconds_t tv_usec;\n    }\n\n    struct itimerval\n    {\n        timeval it_interval;\n        timeval it_value;\n    }\n\n    // non-standard\n    struct timezone_t\n    {\n        int tz_minuteswest;\n        int tz_dsttime;\n    }\n\n    int getitimer(int, itimerval*);\n    int gettimeofday(timeval*, timezone_t*); // timezone_t* is normally void*\n    int setitimer(int, in itimerval*, itimerval*);\n    int utimes(in char*, ref const(timeval)[2]);\n}\nelse version (NetBSD)\n{\n    struct timeval\n    {\n        time_t      tv_sec;\n        suseconds_t tv_usec;\n    }\n\n    struct itimerval\n    {\n        timeval it_interval;\n        timeval it_value;\n    }\n\n    int getitimer(int, itimerval*);\n    int gettimeofday(timeval*, void*); // timezone_t* is normally void*\n    int setitimer(int, in itimerval*, itimerval*);\n    int utimes(in char*, ref const(timeval)[2]);\n}\nelse version (DragonFlyBSD)\n{\n    struct timeval\n    {\n        time_t      tv_sec;\n        suseconds_t tv_usec;\n    }\n\n    struct itimerval\n    {\n        timeval it_interval;\n        timeval it_value;\n    }\n\n    // non-standard\n    struct timezone_t\n    {\n        int tz_minuteswest;\n        int tz_dsttime;\n    }\n\n    int getitimer(int, itimerval*);\n    int gettimeofday(timeval*, timezone_t*); // timezone_t* is normally void*\n    int setitimer(int, in itimerval*, itimerval*);\n    int utimes(in char*, ref const(timeval)[2]);\n}\nelse version (Solaris)\n{\n    struct timeval\n    {\n        time_t tv_sec;\n        suseconds_t tv_usec;\n    }\n\n    struct itimerval\n    {\n        timeval it_interval;\n        timeval it_value;\n    }\n\n    int getitimer(int, itimerval*);\n    int gettimeofday(timeval*, void*);\n    int setitimer(int, in itimerval*, itimerval*);\n    int utimes(in char*, ref const(timeval)[2]);\n}\nelse version (CRuntime_Bionic)\n{\n    struct timeval\n    {\n        time_t      tv_sec;\n        suseconds_t tv_usec;\n    }\n\n    struct itimerval\n    {\n        timeval it_interval;\n        timeval it_value;\n    }\n\n    struct timezone_t\n    {\n        int tz_minuteswest;\n        int tz_dsttime;\n    }\n\n    enum ITIMER_REAL    = 0;\n    enum ITIMER_VIRTUAL = 1;\n    enum ITIMER_PROF    = 2;\n\n    int getitimer(int, itimerval*);\n    int gettimeofday(timeval*, timezone_t*);\n    int setitimer(int, in itimerval*, itimerval*);\n    int utimes(in char*, ref const(timeval)[2]);\n}\nelse version (CRuntime_UClibc)\n{\n    struct timeval\n    {\n        time_t      tv_sec;\n        suseconds_t tv_usec;\n    }\n\n    struct itimerval\n    {\n        timeval it_interval;\n        timeval it_value;\n    }\n\n    enum ITIMER_REAL    = 0;\n    enum ITIMER_VIRTUAL = 1;\n    enum ITIMER_PROF    = 2;\n\n    int getitimer(int, itimerval*);\n    int gettimeofday(timeval*, void*);\n    int setitimer(int, in itimerval*, itimerval*);\n    int utimes(in char*, ref const(timeval)[2]);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/ttycom.d",
    "content": "/**\n * D header file for POSIX.\n *\n * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n */\n\nmodule core.sys.posix.sys.ttycom;\n\nimport core.sys.posix.sys.ioccom;\nimport core.sys.posix.termios;\nimport core.sys.posix.sys.time;\n\nversion (Posix):\n\nnothrow @nogc:\n\nversion (OSX)\n{\n    struct winsize {\n        ushort  ws_row;     // rows, in characters\n        ushort  ws_col;     // columns, in characters\n        ushort  ws_xpixel;  // horizontal size, pixels\n        ushort  ws_ypixel;  // vertical size, pixels\n    }\n\n    // Serial/TTY ioctl's\n    enum uint TIOCMODG =  _IOR!(int)('t', 3);  // get modem control state\n    enum uint TIOCMODS =  _IOW!(int)('t', 4);  // set modem control state\n    enum uint       TIOCM_LE  = 0x001;          // line enable\n    enum uint       TIOCM_DTR = 0x002;          // data terminal ready\n    enum uint       TIOCM_RTS = 0x004;          // request to send\n    enum uint       TIOCM_ST  = 0x008;          // secondary transmit\n    enum uint       TIOCM_SR  = 0x010;          // secondary receive\n    enum uint       TIOCM_CTS = 0x020;          // clear to send\n    enum uint       TIOCM_CAR = 0x040;          // carrier detect\n    enum uint       TIOCM_CD  = TIOCM_CAR;\n    enum uint       TIOCM_RNG = 0x080;          // ring\n    enum uint       TIOCM_RI  = TIOCM_RNG;\n    enum uint       TIOCM_DSR = 0x100;          // data set ready\n                            // 8-10 compat\n    enum uint TIOCEXCL  = _IO('t', 13);        // set exclusive use of tty\n    enum uint TIOCNXCL  = _IO('t', 14);        // reset exclusive use of tty\n                            // 15 unused\n    enum uint TIOCFLUSH = _IOW!(int)('t', 16); // flush buffers\n                            // 17-18 compat\n    enum uint TIOCGETA  = _IOR!(termios)('t', 19); // get termios struct\n    enum uint TIOCSETA  = _IOW!(termios)('t', 20); // set termios struct\n    enum uint TIOCSETAW = _IOW!(termios)('t', 21); // drain output, set\n    enum uint TIOCSETAF = _IOW!(termios)('t', 22); // drn out, fls in, set\n    enum uint TIOCGETD  = _IOR!(int)('t', 26); // get line discipline\n    enum uint TIOCSETD  = _IOW!(int)('t', 27); // set line discipline\n    enum uint TIOCIXON  = _IO('t', 129);       // internal input VSTART\n    enum uint TIOCIXOFF = _IO('t', 128);       // internal input VSTOP\n                            // 127-124 compat\n    enum uint TIOCSBRK  = _IO('t', 123);       // set break bit\n    enum uint TIOCCBRK  = _IO('t', 122);       // clear break bit\n    enum uint TIOCSDTR  = _IO('t', 121);       // set data terminal ready\n    enum uint TIOCCDTR  = _IO('t', 120);       // clear data terminal ready\n    enum uint TIOCGPGRP = _IOR!(int)('t', 119); // get pgrp of tty\n    enum uint TIOCSPGRP = _IOW!(int)('t', 118); // set pgrp of tty\n                            // 117-116 compat\n    enum uint TIOCOUTQ  = _IOR!(int)('t', 115); // output queue size\n    enum uint TIOCSTI   = _IOW!(char)('t', 114);// simulate terminal input\n    enum uint TIOCNOTTY = _IO('t', 113);        // void tty association\n    enum uint TIOCPKT   = _IOW!(int)('t', 112); // pty: set/clear packet mode\n    enum uint   TIOCPKT_DATA       = 0x00;     // data packet\n    enum uint   TIOCPKT_FLUSHREAD  = 0x01;     // flush packet\n    enum uint   TIOCPKT_FLUSHWRITE = 0x02;     // flush packet\n    enum uint   TIOCPKT_STOP       = 0x04;     // stop output\n    enum uint   TIOCPKT_START      = 0x08;     // start output\n    enum uint   TIOCPKT_NOSTOP     = 0x10;     // no more ^S, ^Q\n    enum uint   TIOCPKT_DOSTOP     = 0x20;     // now do ^S ^Q\n    enum uint   TIOCPKT_IOCTL      = 0x40;     // state change of pty driver\n    enum uint TIOCSTOP   = _IO('t', 111);      // stop output, like ^S\n    enum uint TIOCSTART  = _IO('t', 110);      // start output, like ^Q\n    enum uint TIOCMSET   = _IOW!(int)('t', 109); // set all modem bits\n    enum uint TIOCMBIS   = _IOW!(int)('t', 108); // bis modem bits\n    enum uint TIOCMBIC   = _IOW!(int)('t', 107); // bic modem bits\n    enum uint TIOCMGET   = _IOR!(int)('t', 106); // get all modem bits\n    enum uint TIOCREMOTE = _IOW!(int)('t', 105); // remote input editing\n    enum uint TIOCGWINSZ = _IOR!(winsize)('t', 104);  // get window size\n    enum uint TIOCSWINSZ = _IOW!(winsize)('t', 103);  // set window size\n    enum uint TIOCUCNTL  = _IOW!(int)('t', 102); // pty: set/clr usr cntl mode\n    enum uint TIOCSTAT   = _IO('t', 101);      // simulate ^T status message\n    enum uint   UIOCCMD(n) = _IO('u', n);      // usr cntl op \"n\"\n    enum uint TIOCSCONS = _IO('t', 99);        // 4.2 compatibility\n    enum uint TIOCCONS  = _IOW!(int)('t', 98); // become virtual console\n    enum uint TIOCSCTTY = _IO('t', 97);        // become controlling tty\n    enum uint TIOCEXT   = _IOW!(int)('t', 96); // pty: external processing\n    enum uint TIOCSIG   =   _IO('t', 95);      // pty: generate signal\n    enum uint TIOCDRAIN =   _IO('t', 94);      // wait till output drained\n    enum uint TIOCMSDTRWAIT =  _IOW!(int)('t', 91);  // modem: set wait on close\n    enum uint TIOCMGDTRWAIT =  _IOR!(int)('t', 90);  // modem: get wait on close\n    enum uint TIOCTIMESTAMP =  _IOR!(timeval)('t', 89);   // enable/get timestamp\n                                                          // of last input event\n    enum uint TIOCDCDTIMESTAMP = _IOR!(timeval)('t', 88); // enable/get timestamp\n                                                          // of last DCd rise\n    enum uint TIOCSDRAINWAIT   = _IOW!(int)('t', 87); // set ttywait timeout\n    enum uint TIOCGDRAINWAIT   = _IOR!(int)('t', 86); // get ttywait timeout\n    enum uint TIOCDSIMICROCODE = _IO('t', 85);        // download microcode to\n                                                      // DSI Softmodem\n    enum uint TIOCPTYGRANT  =  _IO('t', 84);   // grantpt(3)\n    enum uint TIOCPTYGNAME  =  _IOC(IOC_OUT, 't', 83, 128); // ptsname(3)\n    enum uint TIOCPTYUNLK   =  _IO('t', 82);   // unlockpt(3)\n\n    enum uint TTYDISC  = 0;       // termios tty line discipline\n    enum uint TABLDISC = 3;       // tablet discipline\n    enum uint SLIPDISC = 4;       // serial IP discipline\n    enum uint PPPDISC  = 5;       // PPP discipline\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/types.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly,\n              Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sys.types;\n\nprivate import core.sys.posix.config;\nprivate import core.stdc.stdint;\npublic import core.stdc.stddef;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\n\n//\n// bits/typesizes.h -- underlying types for *_t.\n//\n/*\n__syscall_slong_t\n__syscall_ulong_t\n*/\nversion (CRuntime_Glibc)\n{\n    version (X86_64)\n    {\n        version (D_X32)\n        {\n            // X32 kernel interface is 64-bit.\n            alias long slong_t;\n            alias ulong ulong_t;\n        }\n        else\n        {\n            alias c_long slong_t;\n            alias c_ulong ulong_t;\n        }\n    }\n    else\n    {\n        alias c_long slong_t;\n        alias c_ulong ulong_t;\n    }\n}\nelse\n{\n    alias c_long slong_t;\n    alias c_ulong ulong_t;\n}\n\n//\n// Required\n//\n/*\nblkcnt_t\nblksize_t\ndev_t\ngid_t\nino_t\nmode_t\nnlink_t\noff_t\npid_t\nsize_t\nssize_t\ntime_t\nuid_t\n*/\n\nversion (CRuntime_Glibc)\n{\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    alias long      blkcnt_t;\n    alias ulong     ino_t;\n    alias long      off_t;\n  }\n  else\n  {\n    alias slong_t   blkcnt_t;\n    alias ulong_t   ino_t;\n    alias slong_t   off_t;\n  }\n    alias slong_t   blksize_t;\n    alias ulong     dev_t;\n    alias uint      gid_t;\n    alias uint      mode_t;\n    alias ulong_t   nlink_t;\n    alias int       pid_t;\n    //size_t (defined in core.stdc.stddef)\n    alias c_long    ssize_t;\n    alias slong_t   time_t;\n    alias uint      uid_t;\n}\nelse version (CRuntime_Musl)\n{\n    alias long      blksize_t;\n    alias ulong     nlink_t;\n    alias long      dev_t;\n    alias long      blkcnt_t;\n    alias ulong     ino_t;\n    alias long      off_t;\n    alias long      _Addr;\n    alias int       pid_t;\n    alias uint      uid_t;\n    alias uint      gid_t;\n    alias long      time_t;\n    alias long      clock_t;\n    alias ulong     pthread_t;\n    alias _Addr     ssize_t;\n}\nelse version (Darwin)\n{\n    alias long      blkcnt_t;\n    alias int       blksize_t;\n    alias int       dev_t;\n    alias uint      gid_t;\n    alias ulong     ino_t;\n    alias ushort    mode_t;\n    alias ushort    nlink_t;\n    alias long      off_t;\n    alias int       pid_t;\n    //size_t (defined in core.stdc.stddef)\n    alias c_long    ssize_t;\n    alias c_long    time_t;\n    alias uint      uid_t;\n}\nelse version (FreeBSD)\n{\n    // https://github.com/freebsd/freebsd/blob/master/sys/sys/_types.h\n    alias long      blkcnt_t;\n    alias uint      blksize_t;\n    alias uint      dev_t;\n    alias uint      gid_t;\n    alias uint      ino_t;\n    alias ushort    mode_t;\n    alias ushort    nlink_t;\n    alias long      off_t;\n    alias int       pid_t;\n    //size_t (defined in core.stdc.stddef)\n    alias c_long    ssize_t;\n    alias c_long    time_t;\n    alias uint      uid_t;\n    alias uint      fflags_t;\n}\nelse version (NetBSD)\n{\n    alias long      blkcnt_t;\n    alias int       blksize_t;\n    alias ulong     dev_t;\n    alias uint      gid_t;\n    alias ulong     ino_t;\n    alias uint      mode_t;\n    alias uint      nlink_t;\n    alias ulong     off_t;\n    alias int       pid_t;\n    //size_t (defined in core.stdc.stddef)\n    alias c_long      ssize_t;\n    alias c_long      time_t;\n    alias uint        uid_t;\n}\nelse version (DragonFlyBSD)\n{\n    alias long      blkcnt_t;\n    alias long      blksize_t;\n    alias uint      dev_t;\n    alias uint      gid_t;\n    alias long      ino_t;\n    alias ushort    mode_t;\n    alias uint      nlink_t;\n    alias long      off_t;      //__off_t (defined in /usr/include/sys/stdint.h -> core.stdc.stddef)\n    alias int       pid_t;      // size_t (defined in /usr/include/sys/stdint.h -> core.stdc.stddef)\n    alias c_long    ssize_t;\n    alias long      time_t;\n    alias uint      uid_t;\n}\nelse version (Solaris)\n{\n    alias char* caddr_t;\n    alias c_long daddr_t;\n    alias short cnt_t;\n\n    static if (__USE_FILE_OFFSET64)\n    {\n        alias long blkcnt_t;\n        alias ulong ino_t;\n        alias long off_t;\n    }\n    else\n    {\n        alias c_long blkcnt_t;\n        alias c_ulong ino_t;\n        alias c_long off_t;\n    }\n\n    version (D_LP64)\n    {\n        alias blkcnt_t blkcnt64_t;\n        alias ino_t ino64_t;\n        alias off_t off64_t;\n    }\n    else\n    {\n        alias long blkcnt64_t;\n        alias ulong ino64_t;\n        alias long off64_t;\n    }\n\n    alias uint blksize_t;\n    alias c_ulong dev_t;\n    alias uid_t gid_t;\n    alias uint mode_t;\n    alias uint nlink_t;\n    alias int pid_t;\n    alias c_long ssize_t;\n    alias c_long time_t;\n    alias uint uid_t;\n}\nelse version (CRuntime_Bionic)\n{\n    alias c_ulong   blkcnt_t;\n    alias c_ulong   blksize_t;\n    alias size_t    dev_t;\n    alias uint      gid_t;\n    alias c_ulong   ino_t;\n    alias c_long    off_t;\n    alias int       pid_t;\n    alias c_long    ssize_t;\n    alias c_long    time_t;\n    alias uint      uid_t;\n\n    version (X86)\n    {\n        alias ushort    mode_t;\n        alias ushort    nlink_t;\n    }\n    else version (X86_64)\n    {\n        alias ushort    mode_t;\n        alias uint      nlink_t;\n    }\n    else version (ARM)\n    {\n        alias ushort    mode_t;\n        alias ushort    nlink_t;\n    }\n    else version (AArch64)\n    {\n        alias uint      mode_t;\n        alias uint      nlink_t;\n    }\n    else version (MIPS32)\n    {\n        alias uint      mode_t;\n        alias uint      nlink_t;\n    }\n    else\n    {\n        static assert(false, \"Architecture not supported.\");\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    static if ( __USE_FILE_OFFSET64 )\n    {\n        alias long      blkcnt_t;\n        alias ulong     ino_t;\n        alias long      off_t;\n    }\n    else\n    {\n        alias slong_t   blkcnt_t;\n        alias ulong_t   ino_t;\n        alias slong_t   off_t;\n    }\n\n    version (D_LP64)\n    {\n        alias ino_t ino64_t;\n        alias off_t off64_t;\n    }\n    else\n    {\n        alias ulong ino64_t;\n        alias long off64_t;\n    }\n\n    alias slong_t   blksize_t;\n    alias c_ulong   dev_t;\n    alias uint      gid_t;\n    alias uint      mode_t;\n    alias uint      nlink_t;\n    alias int       pid_t;\n    //size_t (defined in core.stdc.stddef)\n    alias c_long    ssize_t;\n    alias slong_t   time_t;\n    alias uint      uid_t;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// XOpen (XSI)\n//\n/*\nclock_t\nfsblkcnt_t\nfsfilcnt_t\nid_t\nkey_t\nsuseconds_t\nuseconds_t\n*/\n\nversion (CRuntime_Glibc)\n{\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    alias ulong     fsblkcnt_t;\n    alias ulong     fsfilcnt_t;\n  }\n  else\n  {\n    alias ulong_t   fsblkcnt_t;\n    alias ulong_t   fsfilcnt_t;\n  }\n    alias slong_t   clock_t;\n    alias uint      id_t;\n    alias int       key_t;\n    alias slong_t   suseconds_t;\n    alias uint      useconds_t;\n}\nelse version (Darwin)\n{\n    alias uint   fsblkcnt_t;\n    alias uint   fsfilcnt_t;\n    alias c_long clock_t;\n    alias uint   id_t;\n    // key_t\n    alias int    suseconds_t;\n    alias uint   useconds_t;\n}\nelse version (FreeBSD)\n{\n    alias ulong     fsblkcnt_t;\n    alias ulong     fsfilcnt_t;\n    alias c_long    clock_t;\n    alias long      id_t;\n    alias c_long    key_t;\n    alias c_long    suseconds_t;\n    alias uint      useconds_t;\n}\nelse version (NetBSD)\n{\n    alias ulong     fsblkcnt_t;\n    alias ulong     fsfilcnt_t;\n    alias c_long    clock_t;\n    alias long      id_t;\n    alias c_long    key_t;\n    alias c_long    suseconds_t;\n    alias uint      useconds_t;\n}\nelse version (DragonFlyBSD)\n{\n    alias ulong     fsblkcnt_t;\n    alias ulong     fsfilcnt_t;\n    alias c_long    clock_t;\n    alias long      id_t;\n    alias c_long    key_t;\n    alias c_long    suseconds_t;\n    alias uint      useconds_t;\n}\nelse version (Solaris)\n{\n    static if (__USE_FILE_OFFSET64)\n    {\n        alias ulong fsblkcnt_t;\n        alias ulong fsfilcnt_t;\n    }\n    else\n    {\n        alias c_ulong fsblkcnt_t;\n        alias c_ulong fsfilcnt_t;\n    }\n\n    alias c_long clock_t;\n    alias int id_t;\n    alias int key_t;\n    alias c_long suseconds_t;\n    alias uint useconds_t;\n\n    alias id_t taskid_t;\n    alias id_t projid_t;\n    alias id_t poolid_t;\n    alias id_t zoneid_t;\n    alias id_t ctid_t;\n}\nelse version (CRuntime_Bionic)\n{\n    alias c_ulong  fsblkcnt_t;\n    alias c_ulong  fsfilcnt_t;\n    alias c_long   clock_t;\n    alias uint     id_t;\n    alias int      key_t;\n    alias c_long   suseconds_t;\n    alias uint     useconds_t; // Updated in Lollipop\n}\nelse version (CRuntime_Musl)\n{\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    alias ulong     fsblkcnt_t;\n    alias ulong     fsfilcnt_t;\n  }\n  else\n  {\n    alias ulong_t   fsblkcnt_t;\n    alias ulong_t   fsfilcnt_t;\n  }\n    alias uint mode_t;\n    alias uint id_t;\n    alias long suseconds_t;\n}\nelse version (CRuntime_UClibc)\n{\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    alias ulong     fsblkcnt_t;\n    alias ulong     fsfilcnt_t;\n  }\n  else\n  {\n    alias ulong_t   fsblkcnt_t;\n    alias ulong_t   fsfilcnt_t;\n  }\n    alias slong_t   clock_t;\n    alias uint      id_t;\n    alias int       key_t;\n    alias slong_t   suseconds_t;\n    alias uint      useconds_t;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Thread (THR)\n//\n/*\npthread_attr_t\npthread_cond_t\npthread_condattr_t\npthread_key_t\npthread_mutex_t\npthread_mutexattr_t\npthread_once_t\npthread_rwlock_t\npthread_rwlockattr_t\npthread_t\n*/\n\nversion (CRuntime_Glibc)\n{\n    version (X86)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 36;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 24;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 32;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 20;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else version (X86_64)\n    {\n        static if (__WORDSIZE == 64)\n        {\n            enum __SIZEOF_PTHREAD_ATTR_T = 56;\n            enum __SIZEOF_PTHREAD_MUTEX_T = 40;\n            enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n            enum __SIZEOF_PTHREAD_COND_T = 48;\n            enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n            enum __SIZEOF_PTHREAD_RWLOCK_T = 56;\n            enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n            enum __SIZEOF_PTHREAD_BARRIER_T = 32;\n            enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n        }\n        else\n        {\n            enum __SIZEOF_PTHREAD_ATTR_T = 32;\n            enum __SIZEOF_PTHREAD_MUTEX_T = 32;\n            enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n            enum __SIZEOF_PTHREAD_COND_T = 48;\n            enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n            enum __SIZEOF_PTHREAD_RWLOCK_T = 44;\n            enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n            enum __SIZEOF_PTHREAD_BARRIER_T = 20;\n            enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n        }\n    }\n    else version (AArch64)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 64;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 48;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 8;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 8;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 56;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 32;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 8;\n    }\n    else version (ARM)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 36;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 24;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 32;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 20;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else version (IA64)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 56;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 40;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 56;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 32;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else version (MIPS32)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 36;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 24;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 32;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 20;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else version (MIPS64)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 56;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 40;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 56;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 32;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else version (PPC)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 36;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 24;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 32;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 20;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else version (PPC64)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 56;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 40;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 56;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 32;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else version (RISCV32)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 36;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 24;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 32;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 20;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else version (RISCV64)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 56;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 40;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 56;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 32;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else version (SPARC64)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 56;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 40;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 56;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 32;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else version (S390)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 36;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 24;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 32;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 20;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else version (SystemZ)\n    {\n        enum __SIZEOF_PTHREAD_ATTR_T = 56;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 40;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 56;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 32;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n    }\n    else\n    {\n        static assert (false, \"Unsupported platform\");\n    }\n\n    union pthread_attr_t\n    {\n        byte[__SIZEOF_PTHREAD_ATTR_T] __size;\n        c_long __align;\n    }\n\n    private alias int __atomic_lock_t;\n\n    private struct _pthread_fastlock\n    {\n        c_long          __status;\n        __atomic_lock_t __spinlock;\n    }\n\n    private alias void* _pthread_descr;\n\n    union pthread_cond_t\n    {\n        byte[__SIZEOF_PTHREAD_COND_T] __size;\n        long  __align;\n    }\n\n    union pthread_condattr_t\n    {\n        byte[__SIZEOF_PTHREAD_CONDATTR_T] __size;\n        int __align;\n    }\n\n    alias uint pthread_key_t;\n\n    union pthread_mutex_t\n    {\n        byte[__SIZEOF_PTHREAD_MUTEX_T] __size;\n        c_long __align;\n    }\n\n    union pthread_mutexattr_t\n    {\n        byte[__SIZEOF_PTHREAD_MUTEXATTR_T] __size;\n        int __align;\n    }\n\n    alias int pthread_once_t;\n\n    struct pthread_rwlock_t\n    {\n        byte[__SIZEOF_PTHREAD_RWLOCK_T] __size;\n        c_long __align;\n    }\n\n    struct pthread_rwlockattr_t\n    {\n        byte[__SIZEOF_PTHREAD_RWLOCKATTR_T] __size;\n        c_long __align;\n    }\n\n    alias c_ulong pthread_t;\n}\nelse version (CRuntime_Musl)\n{\n    version (X86_64) {\n        union pthread_attr_t\n        {\n            int[14] __i;\n            ulong[7] __s;\n        }\n        union pthread_cond_t\n        {\n            int[12] __i;\n            void*[6] __p;\n        }\n        union pthread_mutex_t\n        {\n            int[10] __i;\n            void*[5] __p;\n        }\n        union pthread_rwlock_t\n        {\n            int[14] __i;\n            void*[7] __p;\n        }\n        struct pthread_rwlockattr_t\n        {\n            uint[2] __attr;\n        }\n        alias uint pthread_key_t;\n        alias uint pthread_condattr_t;\n        alias uint pthread_mutexattr_t;\n        alias int pthread_once_t;\n    }\n    else\n    {\n        static assert (false, \"Architecture unsupported\");\n    }\n}\nelse version (Darwin)\n{\n    version (D_LP64)\n    {\n        enum __PTHREAD_SIZE__               = 1168;\n        enum __PTHREAD_ATTR_SIZE__          = 56;\n        enum __PTHREAD_MUTEXATTR_SIZE__     = 8;\n        enum __PTHREAD_MUTEX_SIZE__         = 56;\n        enum __PTHREAD_CONDATTR_SIZE__      = 8;\n        enum __PTHREAD_COND_SIZE__          = 40;\n        enum __PTHREAD_ONCE_SIZE__          = 8;\n        enum __PTHREAD_RWLOCK_SIZE__        = 192;\n        enum __PTHREAD_RWLOCKATTR_SIZE__    = 16;\n    }\n    else\n    {\n        enum __PTHREAD_SIZE__               = 596;\n        enum __PTHREAD_ATTR_SIZE__          = 36;\n        enum __PTHREAD_MUTEXATTR_SIZE__     = 8;\n        enum __PTHREAD_MUTEX_SIZE__         = 40;\n        enum __PTHREAD_CONDATTR_SIZE__      = 4;\n        enum __PTHREAD_COND_SIZE__          = 24;\n        enum __PTHREAD_ONCE_SIZE__          = 4;\n        enum __PTHREAD_RWLOCK_SIZE__        = 124;\n        enum __PTHREAD_RWLOCKATTR_SIZE__    = 12;\n    }\n\n    struct pthread_handler_rec\n    {\n      void function(void*)  __routine;\n      void*                 __arg;\n      pthread_handler_rec*  __next;\n    }\n\n    struct pthread_attr_t\n    {\n        c_long                              __sig;\n        byte[__PTHREAD_ATTR_SIZE__]         __opaque;\n    }\n\n    struct pthread_cond_t\n    {\n        c_long                              __sig;\n        byte[__PTHREAD_COND_SIZE__]         __opaque;\n    }\n\n    struct pthread_condattr_t\n    {\n        c_long                              __sig;\n        byte[__PTHREAD_CONDATTR_SIZE__]     __opaque;\n    }\n\n    alias c_ulong pthread_key_t;\n\n    struct pthread_mutex_t\n    {\n        c_long                              __sig;\n        byte[__PTHREAD_MUTEX_SIZE__]        __opaque;\n    }\n\n    struct pthread_mutexattr_t\n    {\n        c_long                              __sig;\n        byte[__PTHREAD_MUTEXATTR_SIZE__]    __opaque;\n    }\n\n    struct pthread_once_t\n    {\n        c_long                              __sig;\n        byte[__PTHREAD_ONCE_SIZE__]         __opaque;\n    }\n\n    struct pthread_rwlock_t\n    {\n        c_long                              __sig;\n        byte[__PTHREAD_RWLOCK_SIZE__]       __opaque;\n    }\n\n    struct pthread_rwlockattr_t\n    {\n        c_long                              __sig;\n        byte[__PTHREAD_RWLOCKATTR_SIZE__]   __opaque;\n    }\n\n    private struct _opaque_pthread_t\n    {\n        c_long                  __sig;\n        pthread_handler_rec*    __cleanup_stack;\n        byte[__PTHREAD_SIZE__]  __opaque;\n    }\n\n    alias _opaque_pthread_t* pthread_t;\n}\nelse version (FreeBSD)\n{\n    alias int lwpid_t;\n\n    alias void* pthread_attr_t;\n    alias void* pthread_cond_t;\n    alias void* pthread_condattr_t;\n    alias void* pthread_key_t;\n    alias void* pthread_mutex_t;\n    alias void* pthread_mutexattr_t;\n    alias void* pthread_once_t;\n    alias void* pthread_rwlock_t;\n    alias void* pthread_rwlockattr_t;\n    alias void* pthread_t;\n}\nelse version (NetBSD)\n{\n   struct pthread_queue_t {\n         void*  ptqh_first;\n         void** ptqh_last;\n   }\n\n    alias lwpid_t = int;\n    alias pthread_spin_t = ubyte;\n    struct pthread_attr_t {\n        uint    pta_magic;\n        int     pta_flags;\n        void*   pta_private;\n    }\n    struct  pthread_spinlock_t {\n        uint    pts_magic;\n        pthread_spin_t  pts_spin;\n        int             pts_flags;\n    }\n    struct pthread_cond_t {\n        uint    ptc_magic;\n        pthread_spin_t  ptc_lock;\n        pthread_queue_t ptc_waiters;\n        pthread_mutex_t *ptc_mutex;\n        void*   ptc_private;\n    }\n    struct pthread_condattr_t {\n        uint    ptca_magic;\n        void    *ptca_private;\n    }\n    struct pthread_mutex_t {\n        uint ptm_magic;\n        pthread_spin_t  ptm_errorcheck;\n        ubyte[3]         ptm_pad1;\n        pthread_spin_t  ptm_interlock;\n        ubyte[3] ptm_pad2;\n        pthread_t ptm_owner;\n        void* ptm_waiters;\n        uint  ptm_recursed;\n        void* ptm_spare2;\n    }\n    struct pthread_mutexattr_t{\n        uint    ptma_magic;\n        void*   ptma_private;\n    }\n    struct pthread_once_t{\n        pthread_mutex_t pto_mutex;\n        int     pto_done;\n    }\n    struct pthread_rwlock_t{\n        uint    ptr_magic;\n\n        pthread_spin_t  ptr_interlock;\n\n        pthread_queue_t ptr_rblocked;\n        pthread_queue_t ptr_wblocked;\n        uint    ptr_nreaders;\n        pthread_t ptr_owner;\n        void    *ptr_private;\n    }\n    struct pthread_rwlockattr_t{\n        uint    ptra_magic;\n        void*   ptra_private;\n    }\n\n    alias uint pthread_key_t;\n    alias void* pthread_t;\n}\nelse version (DragonFlyBSD)\n{\n    alias int lwpid_t;\n\n    alias void* pthread_attr_t;\n    alias void* pthread_cond_t;\n    alias void* pthread_condattr_t;\n    alias void* pthread_key_t;\n    alias void* pthread_mutex_t;\n    alias void* pthread_mutexattr_t;\n    alias void* pthread_once_t;\n    alias void* pthread_rwlock_t;\n    alias void* pthread_rwlockattr_t;\n    alias void* pthread_t;\n}\nelse version (Solaris)\n{\n    alias uint pthread_t;\n\n    struct pthread_attr_t\n    {\n        void* __pthread_attrp;\n    }\n\n    struct pthread_cond_t\n    {\n        struct ___pthread_cond_flags\n        {\n            ubyte[4] __pthread_cond_flags;\n            ushort __pthread_cond_type;\n            ushort __pthread_cond_magic;\n        }\n\n        ___pthread_cond_flags __pthread_cond_flags;\n        ulong __pthread_cond_data;\n    }\n\n    struct pthread_condattr_t\n    {\n        void* __pthread_condattrp;\n    }\n\n    struct pthread_rwlock_t\n    {\n        int __pthread_rwlock_readers;\n        ushort __pthread_rwlock_type;\n        ushort __pthread_rwlock_magic;\n        pthread_mutex_t __pthread_rwlock_mutex;\n        pthread_cond_t __pthread_rwlock_readercv;\n        pthread_cond_t __pthread_rwlock_writercv;\n    }\n\n    struct pthread_rwlockattr_t\n    {\n        void* __pthread_rwlockattrp;\n    }\n\n    struct pthread_mutex_t\n    {\n        struct ___pthread_mutex_flags\n        {\n            ushort __pthread_mutex_flag1;\n            ubyte __pthread_mutex_flag2;\n            ubyte __pthread_mutex_ceiling;\n            ushort __pthread_mutex_type;\n            ushort __pthread_mutex_magic;\n        }\n\n        ___pthread_mutex_flags __pthread_mutex_flags;\n\n        union ___pthread_mutex_lock\n        {\n            struct ___pthread_mutex_lock64\n            {\n                ubyte[8] __pthread_mutex_pad;\n            }\n\n            ___pthread_mutex_lock64 __pthread_mutex_lock64;\n\n            struct ___pthread_mutex_lock32\n            {\n                uint __pthread_ownerpid;\n                uint __pthread_lockword;\n            }\n\n            ___pthread_mutex_lock32 __pthread_mutex_lock32;\n            ulong __pthread_mutex_owner64;\n        }\n\n        ___pthread_mutex_lock __pthread_mutex_lock;\n        ulong __pthread_mutex_data;\n    }\n\n    struct pthread_mutexattr_t\n    {\n        void* __pthread_mutexattrp;\n    }\n\n    struct pthread_once_t\n    {\n        ulong[4] __pthread_once_pad;\n    }\n\n    alias uint pthread_key_t;\n}\nelse version (CRuntime_Bionic)\n{\n    struct pthread_attr_t\n    {\n        uint    flags;\n        void*   stack_base;\n        size_t  stack_size;\n        size_t  guard_size;\n        int     sched_policy;\n        int     sched_priority;\n        version (D_LP64) char[16] __reserved;\n    }\n\n    struct pthread_cond_t\n    {\n        version (D_LP64)\n            int[12] __private;\n        else\n            int[1] __private;\n    }\n\n    alias c_long pthread_condattr_t;\n    alias int    pthread_key_t;\n\n    struct pthread_mutex_t\n    {\n        version (D_LP64)\n            int[10] __private;\n        else\n            int[1] __private;\n    }\n\n    alias c_long pthread_mutexattr_t;\n    alias int    pthread_once_t;\n\n    struct pthread_rwlock_t\n    {\n        version (D_LP64)\n            int[14] __private;\n        else\n            int[10] __private;\n    }\n\n    alias c_long pthread_rwlockattr_t;\n    alias c_long pthread_t;\n}\nelse version (CRuntime_UClibc)\n{\n     version (X86_64)\n     {\n        enum __SIZEOF_PTHREAD_ATTR_T        = 56;\n        enum __SIZEOF_PTHREAD_MUTEX_T       = 40;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T   = 4;\n        enum __SIZEOF_PTHREAD_COND_T        = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T    = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T      = 56;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T  = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T     = 32;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n     }\n     else version (MIPS32)\n     {\n        enum __SIZEOF_PTHREAD_ATTR_T        = 36;\n        enum __SIZEOF_PTHREAD_MUTEX_T       = 24;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T   = 4;\n        enum __SIZEOF_PTHREAD_COND_T        = 48;\n        enum __SIZEOF_PTHREAD_CONDATTR_T    = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T      = 32;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T  = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T     = 20;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n     }\n     else version (ARM)\n     {\n        enum __SIZEOF_PTHREAD_ATTR_T = 36;\n        enum __SIZEOF_PTHREAD_MUTEX_T = 24;\n        enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;\n        enum __SIZEOF_PTHREAD_COND_T = 48;\n        enum __SIZEOF_PTHREAD_COND_COMPAT_T = 12;\n        enum __SIZEOF_PTHREAD_CONDATTR_T = 4;\n        enum __SIZEOF_PTHREAD_RWLOCK_T = 32;\n        enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;\n        enum __SIZEOF_PTHREAD_BARRIER_T = 20;\n        enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;\n     }\n     else\n     {\n        static assert (false, \"Architecture unsupported\");\n     }\n\n    union pthread_attr_t\n    {\n        byte[__SIZEOF_PTHREAD_ATTR_T] __size;\n        c_long __align;\n    }\n\n    union pthread_cond_t\n    {\n        struct data\n        {\n            int __lock;\n            uint __futex;\n            ulong __total_seq;\n            ulong __wakeup_seq;\n            ulong __woken_seq;\n            void *__mutex;\n            uint __nwaiters;\n            uint __broadcast_seq;\n        } data __data;\n        byte[__SIZEOF_PTHREAD_COND_T] __size;\n        long  __align;\n    }\n\n    union pthread_condattr_t\n    {\n        byte[__SIZEOF_PTHREAD_CONDATTR_T] __size;\n        c_long __align;\n    }\n\n    alias uint pthread_key_t;\n\n    struct __pthread_slist_t\n    {\n      __pthread_slist_t* __next;\n    }\n\n    union pthread_mutex_t\n    {\n      struct __pthread_mutex_s\n      {\n        int __lock;\n        uint __count;\n        int __owner;\n        /* KIND must stay at this position in the structure to maintain\n           binary compatibility.  */\n        int __kind;\n        uint __nusers;\n        union\n        {\n          int __spins;\n          __pthread_slist_t __list;\n        }\n      }\n      __pthread_mutex_s __data;\n        byte[__SIZEOF_PTHREAD_MUTEX_T] __size;\n        c_long __align;\n    }\n\n    union pthread_mutexattr_t\n    {\n        byte[__SIZEOF_PTHREAD_MUTEXATTR_T] __size;\n        c_long __align;\n    }\n\n    alias int pthread_once_t;\n\n    struct pthread_rwlock_t\n    {\n        struct data\n        {\n            int __lock;\n            uint __nr_readers;\n            uint __readers_wakeup;\n            uint __writer_wakeup;\n            uint __nr_readers_queued;\n            uint __nr_writers_queued;\n            version (BigEndian)\n            {\n                ubyte __pad1;\n                ubyte __pad2;\n                ubyte __shared;\n                ubyte __flags;\n            }\n            else\n            {\n                ubyte __flags;\n                ubyte __shared;\n                ubyte __pad1;\n                ubyte __pad2;\n            }\n            int __writer;\n        } data __data;\n        byte[__SIZEOF_PTHREAD_RWLOCK_T] __size;\n        c_long __align;\n    }\n\n    struct pthread_rwlockattr_t\n    {\n        byte[__SIZEOF_PTHREAD_RWLOCKATTR_T] __size;\n        c_long __align;\n    }\n\n    alias c_ulong pthread_t;\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Barrier (BAR)\n//\n/*\npthread_barrier_t\npthread_barrierattr_t\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct pthread_barrier_t\n    {\n        byte[__SIZEOF_PTHREAD_BARRIER_T] __size;\n        c_long __align;\n    }\n\n    struct pthread_barrierattr_t\n    {\n        byte[__SIZEOF_PTHREAD_BARRIERATTR_T] __size;\n        int __align;\n    }\n}\nelse version (FreeBSD)\n{\n    alias void* pthread_barrier_t;\n    alias void* pthread_barrierattr_t;\n}\nelse version (NetBSD)\n{\n    alias void* pthread_barrier_t;\n    alias void* pthread_barrierattr_t;\n}\nelse version (DragonFlyBSD)\n{\n    alias void* pthread_barrier_t;\n    alias void* pthread_barrierattr_t;\n}\nelse version (Darwin)\n{\n}\nelse version (Solaris)\n{\n    struct pthread_barrier_t\n    {\n        uint __pthread_barrier_count;\n        uint __pthread_barrier_current;\n        ulong __pthread_barrier_cycle;\n        ulong __pthread_barrier_reserved;\n        pthread_mutex_t __pthread_barrier_lock;\n        pthread_cond_t __pthread_barrier_cond;\n    }\n\n    struct pthread_barrierattr_t\n    {\n        void* __pthread_barrierattrp;\n    }\n}\nelse version (CRuntime_Bionic)\n{\n}\nelse version (CRuntime_Musl)\n{\n}\nelse version (CRuntime_UClibc)\n{\n    struct pthread_barrier_t\n    {\n        byte[__SIZEOF_PTHREAD_BARRIER_T] __size;\n        c_long __align;\n    }\n\n    struct pthread_barrierattr_t\n    {\n        byte[__SIZEOF_PTHREAD_BARRIERATTR_T] __size;\n        int __align;\n    }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Spin (SPN)\n//\n/*\npthread_spinlock_t\n*/\n\nversion (CRuntime_Glibc)\n{\n    alias int pthread_spinlock_t; // volatile\n}\nelse version (FreeBSD)\n{\n    alias void* pthread_spinlock_t;\n}\nelse version (NetBSD)\n{\n    //already defined\n}\nelse version (DragonFlyBSD)\n{\n    alias void* pthread_spinlock_t;\n}\nelse version (Solaris)\n{\n    alias pthread_mutex_t pthread_spinlock_t;\n}\nelse version (CRuntime_UClibc)\n{\n    alias int pthread_spinlock_t; // volatile\n}\n\n//\n// Timer (TMR)\n//\n/*\nclockid_t\ntimer_t\n*/\n\n//\n// Trace (TRC)\n//\n/*\ntrace_attr_t\ntrace_event_id_t\ntrace_event_set_t\ntrace_id_t\n*/\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/uio.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sys.uio;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types; // for ssize_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// Required\n//\n/*\nstruct iovec\n{\n    void*  iov_base;\n    size_t iov_len;\n}\n\nssize_t // from core.sys.posix.sys.types\nsize_t  // from core.sys.posix.sys.types\n\nssize_t readv(int, in iovec*, int);\nssize_t writev(int, in iovec*, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct iovec\n    {\n        void*  iov_base;\n        size_t iov_len;\n    }\n\n    ssize_t readv(int, in iovec*, int);\n    ssize_t writev(int, in iovec*, int);\n}\nelse version (Darwin)\n{\n    struct iovec\n    {\n        void*  iov_base;\n        size_t iov_len;\n    }\n\n    ssize_t readv(int, in iovec*, int);\n    ssize_t writev(int, in iovec*, int);\n}\nelse version (FreeBSD)\n{\n    struct iovec\n    {\n        void*  iov_base;\n        size_t iov_len;\n    }\n\n    ssize_t readv(int, in iovec*, int);\n    ssize_t writev(int, in iovec*, int);\n}\nelse version (NetBSD)\n{\n    struct iovec\n    {\n        void*  iov_base;\n        size_t iov_len;\n    }\n\n    ssize_t readv(int, in iovec*, int);\n    ssize_t writev(int, in iovec*, int);\n}\nelse version (DragonFlyBSD)\n{\n    struct iovec\n    {\n        void*  iov_base;\n        size_t iov_len;\n    }\n\n    ssize_t readv(int, in iovec*, int);\n    ssize_t writev(int, in iovec*, int);\n}\nelse version (Solaris)\n{\n    struct iovec\n    {\n        void* iov_base;\n        size_t iov_len;\n    }\n\n    ssize_t readv(int, in iovec*, int);\n    ssize_t writev(int, in iovec*, int);\n}\nelse version (CRuntime_Bionic)\n{\n    struct iovec\n    {\n        void*  iov_base;\n        size_t iov_len;\n    }\n\n    int readv(int, in iovec*, int);\n    int writev(int, in iovec*, int);\n}\nelse version (CRuntime_Musl)\n{\n    struct iovec\n    {\n        void* iov_base;\n        uint  iov_len;\n    }\n\n    ssize_t readv(int, in iovec*, int);\n    ssize_t writev(int, in iovec*, int);\n}\nelse version (CRuntime_UClibc)\n{\n    struct iovec\n    {\n        void*  iov_base;\n        size_t iov_len;\n    }\n\n    ssize_t readv(int, in iovec*, int);\n    ssize_t writev(int, in iovec*, int);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/un.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sys.un;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern(C):\n\npublic import core.sys.posix.sys.socket: sa_family_t;\n\n//\n// Required\n//\n/*\nstruct sockaddr_un\n{\n    sa_family_t sun_family;\n    char        sa_data[];\n}\n\nsa_family_t    // From core.sys.posix.sys.socket\n*/\n\nversion (linux)\n{\n    enum UNIX_PATH_MAX = 108;\n\n    struct sockaddr_un\n    {\n        sa_family_t         sun_family;\n        byte[UNIX_PATH_MAX] sun_path;\n    }\n}\nelse version (Darwin)\n{\n    struct sockaddr_un\n    {\n        ubyte       sun_len;\n        sa_family_t sun_family;\n        byte[104]   sun_path;\n    }\n}\nelse version (FreeBSD)\n{\n    struct sockaddr_un\n    {\n        ubyte       sun_len;\n        sa_family_t sun_family;\n        byte[104]   sun_path;\n    }\n}\nelse version (NetBSD)\n{\n    struct sockaddr_un\n    {\n        ubyte       sun_len;\n        sa_family_t sun_family;\n        byte[104]   sun_path;\n    }\n}\nelse version (DragonFlyBSD)\n{\n    struct sockaddr_un\n    {\n        ubyte       sun_len;\n        sa_family_t sun_family;\n        byte[104]   sun_path;\n    }\n}\nelse version (Solaris)\n{\n    struct sockaddr_un\n    {\n        sa_family_t  sun_family;\n        byte[108]    sun_path;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/utsname.d",
    "content": "\n// Interface to <sys/utsname.h>\n\nmodule core.sys.posix.sys.utsname;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern(C):\nnothrow:\n@nogc:\n\nversion (CRuntime_Glibc)\n{\n    private enum utsNameLength = 65;\n\n    struct utsname\n    {\n        char[utsNameLength] sysname;\n        char[utsNameLength] nodename;\n        char[utsNameLength] release;\n        char[utsNameLength] version_;\n        // TODO Deprecate after version_ has been in an official release.\n        alias update = version_;\n        char[utsNameLength] machine;\n\n        char[utsNameLength] __domainname;\n    }\n\n    int uname(utsname* __name);\n}\nelse version (Darwin)\n{\n    private enum utsNameLength = 256;\n\n    struct utsname\n    {\n        char[utsNameLength] sysname;\n        char[utsNameLength] nodename;\n        char[utsNameLength] release;\n        char[utsNameLength] version_;\n        // TODO Deprecate after version_ has been in an official release.\n        alias update = version_;\n        char[utsNameLength] machine;\n    }\n\n    int uname(utsname* __name);\n}\nelse version (FreeBSD)\n{\n    //private enum SYS_NMLN = 32;       // old FreeBSD 1.1 ABI\n    private enum SYS_NMLN = 256;\n\n    struct utsname\n    {\n        char[SYS_NMLN] sysname;\n        char[SYS_NMLN] nodename;\n        char[SYS_NMLN] release;\n        char[SYS_NMLN] version_;\n        // TODO Deprecate after version_ has been in an official release.\n        alias update = version_;\n        char[SYS_NMLN] machine;\n    }\n\n    int __xuname(int, void*);\n    int uname()(utsname* __name) { return __xuname(SYS_NMLN, cast(void*) __name); }\n}\nelse version (NetBSD)\n{\n    private enum utsNameLength = 256;\n\n    struct utsname\n    {\n        char[utsNameLength] sysname;\n        char[utsNameLength] nodename;\n        char[utsNameLength] release;\n        char[utsNameLength] version_;\n        // TODO Deprecate after version_ has been in an official release.\n        alias update = version_;\n        char[utsNameLength] machine;\n    }\n\n    int uname(utsname* __name);\n}\nelse version (DragonFlyBSD)\n{\n    private enum utsNameLength = 32;\n\n    struct utsname\n    {\n        char[utsNameLength] sysname;\n        char[utsNameLength] nodename;\n        char[utsNameLength] release;\n        char[utsNameLength] version_;\n        // TODO Deprecate after version_ has been in an official release.\n        alias update = version_;\n        char[utsNameLength] machine;\n    }\n\n    int uname(utsname* __name);\n}\nelse version (Solaris)\n{\n    private enum SYS_NMLN = 257;\n\n    struct utsname\n    {\n        char[SYS_NMLN] sysname;\n        char[SYS_NMLN] nodename;\n        char[SYS_NMLN] release;\n        // The field name is version but version is a keyword in D.\n        char[SYS_NMLN] _version;\n        char[SYS_NMLN] machine;\n    }\n\n    int uname(utsname* __name);\n}\nelse version (CRuntime_Bionic)\n{\n    private enum SYS_NMLN = 65;\n\n    struct utsname\n    {\n        char[SYS_NMLN] sysname;\n        char[SYS_NMLN] nodename;\n        char[SYS_NMLN] release;\n        // The field name is version but version is a keyword in D.\n        char[SYS_NMLN] _version;\n        char[SYS_NMLN] machine;\n        char[SYS_NMLN] domainname;\n    }\n\n    int uname(utsname*);\n}\nelse version (CRuntime_Musl)\n{\n    private enum SYS_NMLN = 65;\n\n    struct utsname\n    {\n        char[SYS_NMLN] sysname;\n        char[SYS_NMLN] nodename;\n        char[SYS_NMLN] release;\n        char[SYS_NMLN] _version;\n        char[SYS_NMLN] machine;\n        char[SYS_NMLN] domainname;\n    }\n\n    int uname(utsname*);\n}\nelse version (CRuntime_UClibc)\n{\n    private enum utsNameLength = 65;\n\n    struct utsname\n    {\n        char[utsNameLength] sysname;\n        char[utsNameLength] nodename;\n        char[utsNameLength] release;\n        char[utsNameLength] version_;\n        char[utsNameLength] machine;\n        char[utsNameLength] domainname;\n    }\n\n    int uname(utsname*);\n}\nelse\n{\n    static assert(false, \"unsupported system\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/sys/wait.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.sys.wait;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types; // for id_t, pid_t\npublic import core.sys.posix.signal;    // for siginfo_t (XSI)\n//public import core.sys.posix.resource; // for rusage (XSI)\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C) nothrow @nogc:\n\n//\n// Required\n//\n/*\nWNOHANG\nWUNTRACED\n\nWEXITSTATUS\nWIFCONTINUED\nWIFEXITED\nWIFSIGNALED\nWIFSTOPPED\nWSTOPSIG\nWTERMSIG\n\npid_t wait(int*);\npid_t waitpid(pid_t, int*, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum WNOHANG        = 1;\n    enum WUNTRACED      = 2;\n\n    private\n    {\n        enum __W_CONTINUED = 0xFFFF;\n\n        extern (D) int __WTERMSIG( int status ) { return status & 0x7F; }\n    }\n\n    //\n    // NOTE: These macros assume __USE_MISC is not defined in the relevant\n    //       C headers as the parameter definition there is different and\n    //       much more complicated.\n    //\n    extern (D) int  WEXITSTATUS( int status )  { return ( status & 0xFF00 ) >> 8;   }\n    extern (D) int  WIFCONTINUED( int status ) { return status == __W_CONTINUED;    }\n    extern (D) bool WIFEXITED( int status )    { return __WTERMSIG( status ) == 0;  }\n    extern (D) bool WIFSIGNALED( int status )\n    {\n        return ( cast(byte) ( ( status & 0x7F ) + 1 ) >> 1 ) > 0;\n    }\n    extern (D) bool WIFSTOPPED( int status )   { return ( status & 0xFF ) == 0x7F;  }\n    extern (D) int  WSTOPSIG( int status )     { return WEXITSTATUS( status );      }\n    extern (D) int  WTERMSIG( int status )     { return status & 0x7F;              }\n}\nelse version (Darwin)\n{\n    enum WNOHANG        = 1;\n    enum WUNTRACED      = 2;\n\n    private\n    {\n        enum _WSTOPPED = 0x7F; // octal 0177\n    }\n\n    extern (D) int _WSTATUS(int status)         { return (status & 0x7F);           }\n    extern (D) int  WEXITSTATUS( int status )   { return (status >> 8);             }\n    extern (D) int  WIFCONTINUED( int status )  { return status == 0x13;            }\n    extern (D) bool WIFEXITED( int status )     { return _WSTATUS(status) == 0;     }\n    extern (D) bool WIFSIGNALED( int status )\n    {\n        return _WSTATUS( status ) != _WSTOPPED && _WSTATUS( status ) != 0;\n    }\n    extern (D) bool WIFSTOPPED( int status )   { return _WSTATUS( status ) == _WSTOPPED; }\n    extern (D) int  WSTOPSIG( int status )     { return status >> 8;                     }\n    extern (D) int  WTERMSIG( int status )     { return _WSTATUS( status );              }\n}\nelse version (FreeBSD)\n{\n    enum WNOHANG        = 1;\n    enum WUNTRACED      = 2;\n\n    private\n    {\n        enum _WSTOPPED = 0x7F; // octal 0177\n    }\n\n    extern (D) int _WSTATUS(int status)         { return (status & 0x7F);           }\n    extern (D) int  WEXITSTATUS( int status )   { return (status >> 8);             }\n    extern (D) int  WIFCONTINUED( int status )  { return status == 0x13;            }\n    extern (D) bool WIFEXITED( int status )     { return _WSTATUS(status) == 0;     }\n    extern (D) bool WIFSIGNALED( int status )\n    {\n        return _WSTATUS( status ) != _WSTOPPED && _WSTATUS( status ) != 0;\n    }\n    extern (D) bool WIFSTOPPED( int status )   { return _WSTATUS( status ) == _WSTOPPED; }\n    extern (D) int  WSTOPSIG( int status )     { return status >> 8;                     }\n    extern (D) int  WTERMSIG( int status )     { return _WSTATUS( status );              }\n}\nelse version (NetBSD)\n{\n    enum WNOHANG        = 1;\n    enum WUNTRACED      = 2;\n\n    private\n    {\n        enum _WSTOPPED = 0x7F; // octal 0177\n    }\n\n    extern (D) int _WSTATUS(int status)         { return (status & 0x7F);           }\n    extern (D) int  WEXITSTATUS( int status )   { return (status >> 8);             }\n    extern (D) int  WIFCONTINUED( int status )  { return status == 0x13;            }\n    extern (D) bool WIFEXITED( int status )     { return _WSTATUS(status) == 0;     }\n    extern (D) bool WIFSIGNALED( int status )\n    {\n        return _WSTATUS( status ) != _WSTOPPED && _WSTATUS( status ) != 0;\n    }\n    extern (D) bool WIFSTOPPED( int status )   { return _WSTATUS( status ) == _WSTOPPED; }\n    extern (D) int  WSTOPSIG( int status )     { return status >> 8;                     }\n    extern (D) int  WTERMSIG( int status )     { return _WSTATUS( status );              }\n}\nelse version (DragonFlyBSD)\n{\n    enum WNOHANG        = 1;\n    enum WUNTRACED      = 2;\n\n    private\n    {\n        enum _WSTOPPED = 0x7F; // octal 0177\n    }\n\n    extern (D) int _WSTATUS(int status)         { return (status & 0x7F);           }\n    extern (D) int  WEXITSTATUS( int status )   { return (status >> 8);             }\n    extern (D) int  WIFCONTINUED( int status )  { return status == 0x13;            }\n    extern (D) bool WIFEXITED( int status )     { return _WSTATUS(status) == 0;     }\n    extern (D) bool WIFSIGNALED( int status )\n    {\n        return _WSTATUS( status ) != _WSTOPPED && _WSTATUS( status ) != 0;\n    }\n    extern (D) bool WIFSTOPPED( int status )   { return _WSTATUS( status ) == _WSTOPPED; }\n    extern (D) int  WSTOPSIG( int status )     { return status >> 8;                     }\n    extern (D) int  WTERMSIG( int status )     { return _WSTATUS( status );              }\n}\nelse version (Solaris)\n{\n    enum WNOHANG        = 64;\n    enum WUNTRACED      = 4;\n\n    extern (D) int WEXITSTATUS(int status) { return (status >> 8) & 0xff; }\n    extern (D) int WIFCONTINUED(int status) { return (status & 0xffff) == 0xffff; }\n    extern (D) bool WIFEXITED(int status) { return (status & 0xff) == 0;     }\n    extern (D) bool WIFSIGNALED(int status) { return (status & 0xff) > 0 && (status & 0xff00) == 0; }\n    extern (D) bool WIFSTOPPED(int status) { return (status & 0xff) == 0x7f && (status & 0xff00) != 0; }\n    extern (D) int WSTOPSIG(int status) { return (status >> 8) & 0x7f; }\n    extern (D) int WTERMSIG(int status) { return (status & 0x7f); }\n}\nelse version (CRuntime_Bionic)\n{\n    enum WNOHANG   = 1;\n    enum WUNTRACED = 2;\n\n    extern (D) int  WEXITSTATUS( int status ) { return ( status & 0xFF00 ) >> 8; }\n    extern (D) bool WIFEXITED( int status ) { return WTERMSIG(status) == 0; }\n    extern (D) bool WIFSIGNALED( int status ) { return WTERMSIG(status + 1) >= 2; }\n    extern (D) bool WIFSTOPPED( int status ) { return WTERMSIG(status) == 0x7F; }\n    extern (D) int  WSTOPSIG( int status ) { return WEXITSTATUS(status); }\n    extern (D) int  WTERMSIG( int status ) { return status & 0x7F; }\n}\nelse version (CRuntime_Musl)\n{\n    enum WNOHANG        = 1;\n    enum WUNTRACED      = 2;\n\n    extern (D) int  WEXITSTATUS( int status ) { return ( status & 0xFF00 ) >> 8; }\n    extern (D) int  WIFCONTINUED( int status ) { return status == 0xffff; }\n    extern (D) bool WIFEXITED( int status ) { return WTERMSIG( status ) == 0; }\n    extern (D) bool WIFSIGNALED( int status ) { return (status&0xffff)-1U < 0xffU; }\n    extern (D) bool WIFSTOPPED( int status ) { return cast(short)(((status&0xffff)*0x10001)>>8) > 0x7f00; }\n    extern (D) int  WTERMSIG( int status ) { return status & 0x7F; }\n    alias WEXITSTATUS WSTOPSIG;\n}\nelse version (CRuntime_UClibc)\n{\n    enum WNOHANG        = 1;\n    enum WUNTRACED      = 2;\n\n    private\n    {\n        enum __W_CONTINUED = 0xFFFF;\n\n        extern (D) int __WTERMSIG( int status ) { return status & 0x7F; }\n    }\n\n    //\n    // NOTE: These macros assume __USE_BSD is not defined in the relevant\n    //       C headers as the parameter definition there is different and\n    //       much more complicated.\n    //\n    extern (D) int  WEXITSTATUS( int status )  { return ( status & 0xFF00 ) >> 8;   }\n    extern (D) int  WIFCONTINUED( int status ) { return status == __W_CONTINUED;    }\n    extern (D) bool WIFEXITED( int status )    { return __WTERMSIG( status ) == 0;  }\n    extern (D) bool WIFSIGNALED( int status )\n    {\n        return ( cast(ulong) ( ( status & 0xffff ) - 1U ) >> 1 ) < 0xffU;\n    }\n    version (MIPS32)\n    {\n        extern (D) bool WIFSTOPPED( int status )   { return ( status & 0xFF ) == 0x7F;  }\n    }\n    else\n    {\n        extern (D) bool WIFSTOPPED( int status )   { return ( status & 0xFF ) == 0x7F && ( status & 0xFF00 );  }\n    }\n    extern (D) int  WSTOPSIG( int status )     { return WEXITSTATUS( status );      }\n    extern (D) int  WTERMSIG( int status )     { return status & 0x7F;              }\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\npid_t wait(int*);\npid_t waitpid(pid_t, int*, int);\n\n//\n// XOpen (XSI)\n//\n/*\nWEXITED\nWSTOPPED\nWCONTINUED\nWNOWAIT\n\nenum idtype_t\n{\n    P_ALL,\n    P_PID,\n    P_PGID\n}\n\nint waitid(idtype_t, id_t, siginfo_t*, int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum WEXITED    = 4;\n    enum WSTOPPED   = 2;\n    enum WCONTINUED = 8;\n    enum WNOWAIT    = 0x01000000;\n\n    enum idtype_t\n    {\n        P_ALL,\n        P_PID,\n        P_PGID\n    }\n\n    int waitid(idtype_t, id_t, siginfo_t*, int);\n}\nelse version (Darwin)\n{\n    enum WEXITED    = 0x00000004;\n    enum WSTOPPED   = 0x00000008;\n    enum WCONTINUED = 0x00000010;\n    enum WNOWAIT    = 0x00000020;\n\n    enum idtype_t\n    {\n        P_ALL,\n        P_PID,\n        P_PGID\n    }\n\n    int waitid(idtype_t, id_t, siginfo_t*, int);\n}\nelse version (FreeBSD)\n{\n    enum WSTOPPED       = WUNTRACED;\n    enum WCONTINUED     = 4;\n    enum WNOWAIT        = 8;\n\n    // http://www.freebsd.org/projects/c99/\n}\nelse version (NetBSD)\n{\n    enum WSTOPPED       = WUNTRACED;\n    //enum WCONTINUED     = 4;\n    enum WNOWAIT        = 0x00010000;\n}\nelse version (DragonFlyBSD)\n{\n    enum WSTOPPED       = WUNTRACED;\n    enum WCONTINUED     = 4;\n    enum WNOWAIT        = 8;\n}\nelse version (Solaris)\n{\n    enum WEXITED = 1;\n    enum WTRAPPED = 2;\n    enum WSTOPPED = WUNTRACED;\n    enum WCONTINUED = 8;\n    enum WNOWAIT = 128;\n\n    enum idtype_t\n    {\n        P_PID,          /* A process identifier.                */\n        P_PPID,         /* A parent process identifier.         */\n        P_PGID,         /* A process group (job control group)  */\n                        /* identifier.                          */\n        P_SID,          /* A session identifier.                */\n        P_CID,          /* A scheduling class identifier.       */\n        P_UID,          /* A user identifier.                   */\n        P_GID,          /* A group identifier.                  */\n        P_ALL,          /* All processes.                       */\n        P_LWPID,        /* An LWP identifier.                   */\n        P_TASKID,       /* A task identifier.                   */\n        P_PROJID,       /* A project identifier.                */\n        P_POOLID,       /* A pool identifier.                   */\n        P_ZONEID,       /* A zone identifier.                   */\n        P_CTID,         /* A (process) contract identifier.     */\n        P_CPUID,        /* CPU identifier.                      */\n        P_PSETID,       /* Processor set identifier             */\n    }\n\n    int waitid(idtype_t, id_t, siginfo_t*, int);\n}\nelse version (CRuntime_Bionic)\n{\n    enum WEXITED    = 4;\n    enum WSTOPPED   = 2;\n    enum WCONTINUED = 8;\n    enum WNOWAIT    = 0x01000000;\n\n    alias int idtype_t;\n\n    int waitid(idtype_t, id_t, siginfo_t*, int);\n}\nelse version (CRuntime_Musl)\n{\n}\nelse version (CRuntime_UClibc)\n{\n    enum WEXITED    = 4;\n    enum WSTOPPED   = 2;\n    enum WCONTINUED = 8;\n    enum WNOWAIT    = 0x01000000;\n\n    enum idtype_t\n    {\n        P_ALL,\n        P_PID,\n        P_PGID\n    }\n\n    int waitid(idtype_t, id_t, siginfo_t*, int);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/syslog.d",
    "content": "/**\n * D header file for POSIX system logger API.\n * (http://pubs.opengroup.org/onlinepubs/007904875/basedefs/syslog.h.html)\n *\n * Copyright: Copyright Adil Baig 2013.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Adil Baig\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Adil Baig 2013.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.syslog;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\n\nextern (C) nothrow @nogc:\n\nversion (CRuntime_Glibc)\n{\n    //PRIORITY\n    enum {\n        LOG_EMERG = 0,     /* system is unusable */\n        LOG_ALERT = 1,     /* action must be taken immediately */\n        LOG_CRIT  = 2,     /* critical conditions */\n        LOG_ERR   = 3,     /* error conditions */\n        LOG_WARNING = 4,   /* warning conditions */\n        LOG_NOTICE  = 5,   /* normal but significant condition */\n        LOG_INFO    = 6,   /* informational */\n        LOG_DEBUG   = 7,   /* debug-level messages */\n    };\n\n    //OPTIONS\n    enum {\n        LOG_PID    = 0x01,  /* log the pid with each message */\n        LOG_CONS   = 0x02,  /* log on the console if errors in sending */\n        LOG_ODELAY = 0x04,  /* delay open until first syslog() (default) */\n        LOG_NDELAY = 0x08,  /* don't delay open */\n        LOG_NOWAIT = 0x10,  /* don't wait for console forks: DEPRECATED */\n        LOG_PERROR = 0x20,  /* log to stderr as well */\n    };\n\n    //FACILITY\n    enum {\n        LOG_KERN   = (0<<3),  /* kernel messages */\n        LOG_USER   = (1<<3),  /* random user-level messages */\n        LOG_MAIL   = (2<<3),  /* mail system */\n        LOG_DAEMON = (3<<3),  /* system daemons */\n        LOG_AUTH   = (4<<3),  /* security/authorization messages */\n        LOG_SYSLOG = (5<<3),  /* messages generated internally by syslogd */\n        LOG_LPR    = (6<<3),  /* line printer subsystem */\n        LOG_NEWS   = (7<<3),  /* network news subsystem */\n        LOG_UUCP   = (8<<3),  /* UUCP subsystem */\n        LOG_CRON   = (9<<3),  /* clock daemon */\n        LOG_AUTHPRIV = (10<<3), /* security/authorization messages (private), */\n        LOG_FTP    =  (11<<3), /* ftp daemon */\n\n        /* other codes through 15 reserved for system use */\n        LOG_LOCAL0 = (16<<3), /* reserved for local use */\n        LOG_LOCAL1 = (17<<3), /* reserved for local use */\n        LOG_LOCAL2 = (18<<3), /* reserved for local use */\n        LOG_LOCAL3 = (19<<3), /* reserved for local use */\n        LOG_LOCAL4 = (20<<3), /* reserved for local use */\n        LOG_LOCAL5 = (21<<3), /* reserved for local use */\n        LOG_LOCAL6 = (22<<3), /* reserved for local use */\n        LOG_LOCAL7 = (23<<3), /* reserved for local use */\n\n        LOG_NFACILITIES = 24,  /* current number of facilities */\n    };\n\n    int LOG_MASK(int pri) { return 1 << pri; }        /* mask for one priority */\n    int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; }  /* all priorities through pri */\n\n    void openlog (const char *, int __option, int __facility);\n    int  setlogmask (int __mask);\n    void syslog (int __pri, const char *__fmt, ...);\n    void closelog();\n}\nelse version (Darwin)\n{\n    //http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/osfmk/sys/syslog.h\n\n    //PRIORITY\n    enum {\n        LOG_EMERG = 0,     /* system is unusable */\n        LOG_ALERT = 1,     /* action must be taken immediately */\n        LOG_CRIT  = 2,     /* critical conditions */\n        LOG_ERR   = 3,     /* error conditions */\n        LOG_WARNING = 4,   /* warning conditions */\n        LOG_NOTICE  = 5,   /* normal but significant condition */\n        LOG_INFO    = 6,   /* informational */\n        LOG_DEBUG   = 7,   /* debug-level messages */\n    };\n\n    //OPTIONS\n    enum {\n        LOG_PID    = 0x01,     /* log the pid with each message */\n        LOG_CONS   = 0x02,  /* log on the console if errors in sending */\n        LOG_ODELAY = 0x04,  /* delay open until first syslog() (default) */\n        LOG_NDELAY = 0x08,  /* don't delay open */\n        LOG_NOWAIT = 0x10,  /* don't wait for console forks: DEPRECATED */\n    };\n\n    //FACILITY\n    enum {\n        LOG_KERN   = (0<<3),  /* kernel messages */\n        LOG_USER   = (1<<3),  /* random user-level messages */\n        LOG_MAIL   = (2<<3),  /* mail system */\n        LOG_DAEMON = (3<<3),  /* system daemons */\n        LOG_AUTH   = (4<<3),  /* security/authorization messages */\n        LOG_SYSLOG = (5<<3),  /* messages generated internally by syslogd */\n        LOG_LPR    = (6<<3),  /* line printer subsystem */\n        LOG_NEWS   = (7<<3),  /* network news subsystem */\n        LOG_UUCP   = (8<<3),  /* UUCP subsystem */\n\n        /* other codes through 15 reserved for system use */\n        LOG_LOCAL0 = (16<<3), /* reserved for local use */\n        LOG_LOCAL1 = (17<<3), /* reserved for local use */\n        LOG_LOCAL2 = (18<<3), /* reserved for local use */\n        LOG_LOCAL3 = (19<<3), /* reserved for local use */\n        LOG_LOCAL4 = (20<<3), /* reserved for local use */\n        LOG_LOCAL5 = (21<<3), /* reserved for local use */\n        LOG_LOCAL6 = (22<<3), /* reserved for local use */\n        LOG_LOCAL7 = (23<<3), /* reserved for local use */\n\n        LOG_NFACILITIES = 24,  /* current number of facilities */\n    };\n\n    int LOG_MASK(int pri) { return 1 << pri; }        /* mask for one priority */\n    int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; }  /* all priorities through pri */\n\n    void openlog (const char *, int __option, int __facility);\n    int  setlogmask (int __mask);\n    void syslog (int __pri, const char *__fmt, ...);\n    void closelog();\n}\nelse version (FreeBSD)\n{\n    //http://fxr.watson.org/fxr/source/sys/syslog.h\n\n    //PRIORITY\n    enum {\n        LOG_EMERG = 0,     /* system is unusable */\n        LOG_ALERT = 1,     /* action must be taken immediately */\n        LOG_CRIT  = 2,     /* critical conditions */\n        LOG_ERR   = 3,     /* error conditions */\n        LOG_WARNING = 4,   /* warning conditions */\n        LOG_NOTICE  = 5,   /* normal but significant condition */\n        LOG_INFO    = 6,   /* informational */\n        LOG_DEBUG   = 7,   /* debug-level messages */\n    };\n\n    //OPTIONS\n    enum {\n        LOG_PID    = 0x01,    /* log the pid with each message */\n        LOG_CONS   = 0x02,    /* log on the console if errors in sending */\n        LOG_ODELAY = 0x04,    /* delay open until first syslog() (default) */\n        LOG_NDELAY = 0x08,    /* don't delay open */\n        LOG_NOWAIT = 0x10,    /* don't wait for console forks: DEPRECATED */\n        LOG_PERROR = 0x20,    /* log to stderr as well */\n    };\n\n    //FACILITY\n    enum {\n        LOG_KERN   = (0<<3),  /* kernel messages */\n        LOG_USER   = (1<<3),  /* random user-level messages */\n        LOG_MAIL   = (2<<3),  /* mail system */\n        LOG_DAEMON = (3<<3),  /* system daemons */\n        LOG_AUTH   = (4<<3),  /* security/authorization messages */\n        LOG_SYSLOG = (5<<3),  /* messages generated internally by syslogd */\n        LOG_LPR    = (6<<3),  /* line printer subsystem */\n        LOG_NEWS   = (7<<3),  /* network news subsystem */\n        LOG_UUCP   = (8<<3),  /* UUCP subsystem */\n        LOG_CRON   = (9<<3),  /* clock daemon */\n        LOG_AUTHPRIV = (10<<3), /* security/authorization messages (private), */\n        LOG_FTP    =  (11<<3), /* ftp daemon */\n        LOG_NTP    = (12<<3), /* NTP subsystem */\n        LOG_SECURITY = (13<<3), /* security subsystems (firewalling, etc.) */\n        LOG_CONSOLE  = (14<<3), /* /dev/console output */\n\n        /* other codes through 15 reserved for system use */\n        LOG_LOCAL0 = (16<<3), /* reserved for local use */\n        LOG_LOCAL1 = (17<<3), /* reserved for local use */\n        LOG_LOCAL2 = (18<<3), /* reserved for local use */\n        LOG_LOCAL3 = (19<<3), /* reserved for local use */\n        LOG_LOCAL4 = (20<<3), /* reserved for local use */\n        LOG_LOCAL5 = (21<<3), /* reserved for local use */\n        LOG_LOCAL6 = (22<<3), /* reserved for local use */\n        LOG_LOCAL7 = (23<<3), /* reserved for local use */\n\n        LOG_NFACILITIES = 24,  /* current number of facilities */\n    };\n\n    int LOG_MASK(int pri) { return 1 << pri; }        /* mask for one priority */\n    int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; }  /* all priorities through pri */\n\n    void openlog (const char *, int __option, int __facility);\n    int  setlogmask (int __mask);\n    void syslog (int __pri, const char *__fmt, ...);\n    void closelog();\n}\nelse version (NetBSD)\n{\n    //http://fxr.watson.org/fxr/source/sys/syslog.h\n\n    //PRIORITY\n    enum {\n        LOG_EMERG = 0,     /* system is unusable */\n        LOG_ALERT = 1,     /* action must be taken immediately */\n        LOG_CRIT  = 2,     /* critical conditions */\n        LOG_ERR   = 3,     /* error conditions */\n        LOG_WARNING = 4,   /* warning conditions */\n        LOG_NOTICE  = 5,   /* normal but significant condition */\n        LOG_INFO    = 6,   /* informational */\n        LOG_DEBUG   = 7,   /* debug-level messages */\n    };\n\n    //OPTIONS\n    enum {\n        LOG_PID    = 0x01,    /* log the pid with each message */\n        LOG_CONS   = 0x02,    /* log on the console if errors in sending */\n        LOG_ODELAY = 0x04,    /* delay open until first syslog() (default) */\n        LOG_NDELAY = 0x08,    /* don't delay open */\n        LOG_NOWAIT = 0x10,    /* don't wait for console forks: DEPRECATED */\n        LOG_PERROR = 0x20,    /* log to stderr as well */\n    };\n\n    //FACILITY\n    enum {\n        LOG_KERN   = (0<<3),  /* kernel messages */\n        LOG_USER   = (1<<3),  /* random user-level messages */\n        LOG_MAIL   = (2<<3),  /* mail system */\n        LOG_DAEMON = (3<<3),  /* system daemons */\n        LOG_AUTH   = (4<<3),  /* security/authorization messages */\n        LOG_SYSLOG = (5<<3),  /* messages generated internally by syslogd */\n        LOG_LPR    = (6<<3),  /* line printer subsystem */\n        LOG_NEWS   = (7<<3),  /* network news subsystem */\n        LOG_UUCP   = (8<<3),  /* UUCP subsystem */\n        LOG_CRON   = (9<<3),  /* clock daemon */\n        LOG_AUTHPRIV = (10<<3), /* security/authorization messages (private), */\n        LOG_FTP    =  (11<<3), /* ftp daemon */\n        LOG_NTP    = (12<<3), /* NTP subsystem */\n        LOG_SECURITY = (13<<3), /* security subsystems (firewalling, etc.) */\n        LOG_CONSOLE  = (14<<3), /* /dev/console output */\n\n        /* other codes through 15 reserved for system use */\n        LOG_LOCAL0 = (16<<3), /* reserved for local use */\n        LOG_LOCAL1 = (17<<3), /* reserved for local use */\n        LOG_LOCAL2 = (18<<3), /* reserved for local use */\n        LOG_LOCAL3 = (19<<3), /* reserved for local use */\n        LOG_LOCAL4 = (20<<3), /* reserved for local use */\n        LOG_LOCAL5 = (21<<3), /* reserved for local use */\n        LOG_LOCAL6 = (22<<3), /* reserved for local use */\n        LOG_LOCAL7 = (23<<3), /* reserved for local use */\n\n        LOG_NFACILITIES = 24,  /* current number of facilities */\n    };\n\n    int LOG_MASK(int pri) { return 1 << pri; }        /* mask for one priority */\n    int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; }  /* all priorities through pri */\n\n    void openlog (const char *, int __option, int __facility);\n    int  setlogmask (int __mask);\n    void syslog (int __pri, const char *__fmt, ...);\n    void closelog();\n}\nelse version (DragonFlyBSD)\n{\n    //PRIORITY\n    enum {\n        LOG_EMERG = 0,     /* system is unusable */\n        LOG_ALERT = 1,     /* action must be taken immediately */\n        LOG_CRIT  = 2,     /* critical conditions */\n        LOG_ERR   = 3,     /* error conditions */\n        LOG_WARNING = 4,   /* warning conditions */\n        LOG_NOTICE  = 5,   /* normal but significant condition */\n        LOG_INFO    = 6,   /* informational */\n        LOG_DEBUG   = 7,   /* debug-level messages */\n    };\n\n    //OPTIONS\n    enum {\n        LOG_PID    = 0x01,    /* log the pid with each message */\n        LOG_CONS   = 0x02,    /* log on the console if errors in sending */\n        LOG_ODELAY = 0x04,    /* delay open until first syslog() (default) */\n        LOG_NDELAY = 0x08,    /* don't delay open */\n        LOG_NOWAIT = 0x10,    /* don't wait for console forks: DEPRECATED */\n        LOG_PERROR = 0x20,    /* log to stderr as well */\n    };\n\n    //FACILITY\n    enum {\n        LOG_KERN   = (0<<3),  /* kernel messages */\n        LOG_USER   = (1<<3),  /* random user-level messages */\n        LOG_MAIL   = (2<<3),  /* mail system */\n        LOG_DAEMON = (3<<3),  /* system daemons */\n        LOG_AUTH   = (4<<3),  /* security/authorization messages */\n        LOG_SYSLOG = (5<<3),  /* messages generated internally by syslogd */\n        LOG_LPR    = (6<<3),  /* line printer subsystem */\n        LOG_NEWS   = (7<<3),  /* network news subsystem */\n        LOG_UUCP   = (8<<3),  /* UUCP subsystem */\n        LOG_CRON   = (9<<3),  /* clock daemon */\n        LOG_AUTHPRIV = (10<<3), /* security/authorization messages (private), */\n        LOG_FTP    =  (11<<3), /* ftp daemon */\n        LOG_NTP    = (12<<3), /* NTP subsystem */\n        LOG_SECURITY = (13<<3), /* security subsystems (firewalling, etc.) */\n        LOG_CONSOLE  = (14<<3), /* /dev/console output */\n\n        /* other codes through 15 reserved for system use */\n        LOG_LOCAL0 = (16<<3), /* reserved for local use */\n        LOG_LOCAL1 = (17<<3), /* reserved for local use */\n        LOG_LOCAL2 = (18<<3), /* reserved for local use */\n        LOG_LOCAL3 = (19<<3), /* reserved for local use */\n        LOG_LOCAL4 = (20<<3), /* reserved for local use */\n        LOG_LOCAL5 = (21<<3), /* reserved for local use */\n        LOG_LOCAL6 = (22<<3), /* reserved for local use */\n        LOG_LOCAL7 = (23<<3), /* reserved for local use */\n\n        LOG_NFACILITIES = 24,  /* current number of facilities */\n    };\n\n    int LOG_MASK(int pri) { return 1 << pri; }        /* mask for one priority */\n    int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; }  /* all priorities through pri */\n\n    void openlog (const char *, int __option, int __facility);\n    int  setlogmask (int __mask);\n    void syslog (int __pri, const char *__fmt, ...);\n    void closelog();\n}\nelse version (Solaris)\n{\n    //http://pubs.opengroup.org/onlinepubs/007904875/basedefs/syslog.h.html\n\n    //PRIORITY\n    enum {\n        LOG_EMERG = 0,     /* system is unusable */\n        LOG_ALERT = 1,     /* action must be taken immediately */\n        LOG_CRIT  = 2,     /* critical conditions */\n        LOG_ERR   = 3,     /* error conditions */\n        LOG_WARNING = 4,   /* warning conditions */\n        LOG_NOTICE  = 5,   /* normal but significant condition */\n        LOG_INFO    = 6,   /* informational */\n        LOG_DEBUG   = 7,   /* debug-level messages */\n    };\n\n    //OPTIONS\n    enum {\n        LOG_PID = 0x01,     /* log the pid with each message */\n        LOG_CONS   = 0x02,  /* log on the console if errors in sending */\n        LOG_NDELAY = 0x08,  /* don't delay open */\n        LOG_NOWAIT = 0x10,  /* don't wait for console forks: DEPRECATED */\n    };\n\n    //FACILITY\n    enum {\n        LOG_KERN   = (0<<3),  /* kernel messages */\n        LOG_USER   = (1<<3),  /* random user-level messages */\n        LOG_MAIL   = (2<<3),  /* mail system */\n        LOG_DAEMON = (3<<3),  /* system daemons */\n        LOG_AUTH   = (4<<3),  /* security/authorization messages */\n        LOG_SYSLOG = (5<<3),  /* messages generated internally by syslogd */\n        LOG_LPR    = (6<<3),  /* line printer subsystem */\n        LOG_NEWS   = (7<<3),  /* network news subsystem */\n        LOG_UUCP   = (8<<3),  /* UUCP subsystem */\n        LOG_CRON   = (9<<3),  /* clock daemon */\n        LOG_AUTHPRIV = (10<<3), /* security/authorization messages (private), */\n        LOG_FTP    =  (11<<3), /* ftp daemon */\n\n        /* other codes through 15 reserved for system use */\n        LOG_LOCAL0 = (16<<3), /* reserved for local use */\n        LOG_LOCAL1 = (17<<3), /* reserved for local use */\n        LOG_LOCAL2 = (18<<3), /* reserved for local use */\n        LOG_LOCAL3 = (19<<3), /* reserved for local use */\n        LOG_LOCAL4 = (20<<3), /* reserved for local use */\n        LOG_LOCAL5 = (21<<3), /* reserved for local use */\n        LOG_LOCAL6 = (22<<3), /* reserved for local use */\n        LOG_LOCAL7 = (23<<3), /* reserved for local use */\n\n        LOG_NFACILITIES = 24,  /* current number of facilities */\n    };\n\n    int LOG_MASK(int pri) { return 1 << pri; }        /* mask for one priority */\n    int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; }  /* all priorities through pri */\n\n    void openlog (const char *, int __option, int __facility);\n    int  setlogmask (int __mask);\n    void syslog (int __pri, const char *__fmt, ...);\n    void closelog();\n}\nelse version (CRuntime_UClibc)\n{\n    //PRIORITY\n    enum {\n        LOG_EMERG = 0,     /* system is unusable */\n        LOG_ALERT = 1,     /* action must be taken immediately */\n        LOG_CRIT  = 2,     /* critical conditions */\n        LOG_ERR   = 3,     /* error conditions */\n        LOG_WARNING = 4,   /* warning conditions */\n        LOG_NOTICE  = 5,   /* normal but significant condition */\n        LOG_INFO    = 6,   /* informational */\n        LOG_DEBUG   = 7,   /* debug-level messages */\n    };\n\n    //OPTIONS\n    enum {\n        LOG_PID    = 0x01,  /* log the pid with each message */\n        LOG_CONS   = 0x02,  /* log on the console if errors in sending */\n        LOG_ODELAY = 0x04,  /* delay open until first syslog() (default) */\n        LOG_NDELAY = 0x08,  /* don't delay open */\n        LOG_NOWAIT = 0x10,  /* don't wait for console forks: DEPRECATED */\n        LOG_PERROR = 0x20,  /* log to stderr as well */\n    };\n\n    //FACILITY\n    enum {\n        LOG_KERN   = (0<<3),  /* kernel messages */\n        LOG_USER   = (1<<3),  /* random user-level messages */\n        LOG_MAIL   = (2<<3),  /* mail system */\n        LOG_DAEMON = (3<<3),  /* system daemons */\n        LOG_AUTH   = (4<<3),  /* security/authorization messages */\n        LOG_SYSLOG = (5<<3),  /* messages generated internally by syslogd */\n        LOG_LPR    = (6<<3),  /* line printer subsystem */\n        LOG_NEWS   = (7<<3),  /* network news subsystem */\n        LOG_UUCP   = (8<<3),  /* UUCP subsystem */\n        LOG_CRON   = (9<<3),  /* clock daemon */\n        LOG_AUTHPRIV = (10<<3), /* security/authorization messages (private), */\n        LOG_FTP    =  (11<<3), /* ftp daemon */\n\n        /* other codes through 15 reserved for system use */\n        LOG_LOCAL0 = (16<<3), /* reserved for local use */\n        LOG_LOCAL1 = (17<<3), /* reserved for local use */\n        LOG_LOCAL2 = (18<<3), /* reserved for local use */\n        LOG_LOCAL3 = (19<<3), /* reserved for local use */\n        LOG_LOCAL4 = (20<<3), /* reserved for local use */\n        LOG_LOCAL5 = (21<<3), /* reserved for local use */\n        LOG_LOCAL6 = (22<<3), /* reserved for local use */\n        LOG_LOCAL7 = (23<<3), /* reserved for local use */\n\n        LOG_NFACILITIES = 24,  /* current number of facilities */\n    };\n\n    int LOG_MASK(int pri) { return 1 << pri; }        /* mask for one priority */\n    int LOG_UPTO(int pri) { return (1 << (pri+1)) - 1; }  /* all priorities through pri */\n\n    void openlog (const char *, int __option, int __facility);\n    int  setlogmask (int __mask);\n    void syslog (int __pri, const char *__fmt, ...);\n    void closelog();\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/termios.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly, Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.termios;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types; // for pid_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\n\nnothrow:\n@nogc:\n\n//\n// Required\n//\n/*\ncc_t\nspeed_t\ntcflag_t\n\nNCCS\n\nstruct termios\n{\n    tcflag_t   c_iflag;\n    tcflag_t   c_oflag;\n    tcflag_t   c_cflag;\n    tcflag_t   c_lflag;\n    cc_t[NCCS] c_cc;\n}\n\nVEOF\nVEOL\nVERASE\nVINTR\nVKILL\nVMIN\nVQUIT\nVSTART\nVSTOP\nVSUSP\nVTIME\n\nBRKINT\nICRNL\nIGNBRK\nIGNCR\nIGNPAR\nINLCR\nINPCK\nISTRIP\nIXOFF\nIXON\nPARMRK\n\nOPOST\n\nB0\nB50\nB75\nB110\nB134\nB150\nB200\nB300\nB600\nB1200\nB1800\nB2400\nB4800\nB9600\nB19200\nB38400\n\nCSIZE\n    CS5\n    CS6\n    CS7\n    CS8\nCSTOPB\nCREAD\nPARENB\nPARODD\nHUPCL\nCLOCAL\n\nECHO\nECHOE\nECHOK\nECHONL\nICANON\nIEXTEN\nISIG\nNOFLSH\nTOSTOP\n\nTCSANOW\nTCSADRAIN\nTCSAFLUSH\n\nTCIFLUSH\nTCIOFLUSH\nTCOFLUSH\n\nTCIOFF\nTCION\nTCOOFF\nTCOON\n\nspeed_t cfgetispeed(in termios*);\nspeed_t cfgetospeed(in termios*);\nint     cfsetispeed(termios*, speed_t);\nint     cfsetospeed(termios*, speed_t);\nint     tcdrain(int);\nint     tcflow(int, int);\nint     tcflush(int, int);\nint     tcgetattr(int, termios*);\nint     tcsendbreak(int, int);\nint     tcsetattr(int, int, in termios*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    alias ubyte cc_t;\n    alias uint  speed_t;\n    alias uint  tcflag_t;\n\n    enum NCCS   = 32;\n\n    struct termios\n    {\n        tcflag_t   c_iflag;\n        tcflag_t   c_oflag;\n        tcflag_t   c_cflag;\n        tcflag_t   c_lflag;\n        cc_t       c_line;\n        cc_t[NCCS] c_cc;\n        speed_t    c_ispeed;\n        speed_t    c_ospeed;\n    }\n\n    enum VEOF       = 4;\n    enum VEOL       = 11;\n    enum VERASE     = 2;\n    enum VINTR      = 0;\n    enum VKILL      = 3;\n    enum VMIN       = 6;\n    enum VQUIT      = 1;\n    enum VSTART     = 8;\n    enum VSTOP      = 9;\n    enum VSUSP      = 10;\n    enum VTIME      = 5;\n\n    enum BRKINT     = 0x0000002; // 0000002\n    enum ICRNL      = 0x0000100; // 0000400\n    enum IGNBRK     = 0x0000001; // 0000001\n    enum IGNCR      = 0x0000080; // 0000200\n    enum IGNPAR     = 0x0000004; // 0000004\n    enum INLCR      = 0x0000040; // 0000100\n    enum INPCK      = 0x0000010; // 0000020\n    enum ISTRIP     = 0x0000020; // 0000040\n    enum IXOFF      = 0x0001000; // 0010000\n    enum IXON       = 0x0000400; // 0002000\n    enum PARMRK     = 0x0000008; // 0000010\n\n    enum OPOST      = 0x0000001; // 0000001\n\n    enum B0         = 0x0000000; // 0000000\n    enum B50        = 0x0000001; // 0000001\n    enum B75        = 0x0000002; // 0000002\n    enum B110       = 0x0000003; // 0000003\n    enum B134       = 0x0000004; // 0000004\n    enum B150       = 0x0000005; // 0000005\n    enum B200       = 0x0000006; // 0000006\n    enum B300       = 0x0000007; // 0000007\n    enum B600       = 0x0000008; // 0000010\n    enum B1200      = 0x0000009; // 0000011\n    enum B1800      = 0x000000A; // 0000012\n    enum B2400      = 0x000000B; // 0000013\n    enum B4800      = 0x000000C; // 0000014\n    enum B9600      = 0x000000D; // 0000015\n    enum B19200     = 0x000000E; // 0000016\n    enum B38400     = 0x000000F; // 0000017\n\n    enum CSIZE      = 0x0000030; // 0000060\n    enum   CS5      = 0x0000000; // 0000000\n    enum   CS6      = 0x0000010; // 0000020\n    enum   CS7      = 0x0000020; // 0000040\n    enum   CS8      = 0x0000030; // 0000060\n    enum CSTOPB     = 0x0000040; // 0000100\n    enum CREAD      = 0x0000080; // 0000200\n    enum PARENB     = 0x0000100; // 0000400\n    enum PARODD     = 0x0000200; // 0001000\n    enum HUPCL      = 0x0000400; // 0002000\n    enum CLOCAL     = 0x0000800; // 0004000\n\n    enum ECHO       = 0x0000008; // 0000010\n    enum ECHOE      = 0x0000010; // 0000020\n    enum ECHOK      = 0x0000020; // 0000040\n    enum ECHONL     = 0x0000040; // 0000100\n    enum ICANON     = 0x0000002; // 0000002\n    enum IEXTEN     = 0x0008000; // 0100000\n    enum ISIG       = 0x0000001; // 0000001\n    enum NOFLSH     = 0x0000080; // 0000200\n    enum TOSTOP     = 0x0000100; // 0000400\n\n    enum TCSANOW    = 0;\n    enum TCSADRAIN  = 1;\n    enum TCSAFLUSH  = 2;\n\n    enum TCIFLUSH   = 0;\n    enum TCOFLUSH   = 1;\n    enum TCIOFLUSH  = 2;\n\n    enum TCIOFF     = 2;\n    enum TCION      = 3;\n    enum TCOOFF     = 0;\n    enum TCOON      = 1;\n\n    speed_t cfgetispeed(in termios*);\n    speed_t cfgetospeed(in termios*);\n    int     cfsetispeed(termios*, speed_t);\n    int     cfsetospeed(termios*, speed_t);\n    int     tcdrain(int);\n    int     tcflow(int, int);\n    int     tcflush(int, int);\n    int     tcgetattr(int, termios*);\n    int     tcsendbreak(int, int);\n    int     tcsetattr(int, int, in termios*);\n}\nelse version (Darwin)\n{\n    alias ubyte cc_t;\n    alias c_ulong  speed_t;\n    alias c_ulong  tcflag_t;\n\n    enum NCCS   = 20;\n\n    struct termios\n    {\n        tcflag_t   c_iflag;\n        tcflag_t   c_oflag;\n        tcflag_t   c_cflag;\n        tcflag_t   c_lflag;\n        cc_t[NCCS] c_cc;\n        speed_t    c_ispeed;\n        speed_t    c_ospeed;\n    }\n\n    enum VEOF       = 0;\n    enum VEOL       = 1;\n    enum VERASE     = 3;\n    enum VINTR      = 8;\n    enum VKILL      = 5;\n    enum VMIN       = 16;\n    enum VQUIT      = 9;\n    enum VSTART     = 12;\n    enum VSTOP      = 13;\n    enum VSUSP      = 10;\n    enum VTIME      = 17;\n\n    enum BRKINT     = 0x0000002;\n    enum ICRNL      = 0x0000100;\n    enum IGNBRK     = 0x0000001;\n    enum IGNCR      = 0x0000080;\n    enum IGNPAR     = 0x0000004;\n    enum INLCR      = 0x0000040;\n    enum INPCK      = 0x0000010;\n    enum ISTRIP     = 0x0000020;\n    enum IXOFF      = 0x0000400;\n    enum IXON       = 0x0000200;\n    enum PARMRK     = 0x0000008;\n\n    enum OPOST      = 0x0000001;\n\n    enum B0         = 0;\n    enum B50        = 50;\n    enum B75        = 75;\n    enum B110       = 110;\n    enum B134       = 134;\n    enum B150       = 150;\n    enum B200       = 200;\n    enum B300       = 300;\n    enum B600       = 600;\n    enum B1200      = 1200;\n    enum B1800      = 1800;\n    enum B2400      = 2400;\n    enum B4800      = 4800;\n    enum B9600      = 9600;\n    enum B19200     = 19200;\n    enum B38400     = 38400;\n\n    enum CSIZE      = 0x0000300;\n    enum   CS5      = 0x0000000;\n    enum   CS6      = 0x0000100;\n    enum   CS7      = 0x0000200;\n    enum   CS8      = 0x0000300;\n    enum CSTOPB     = 0x0000400;\n    enum CREAD      = 0x0000800;\n    enum PARENB     = 0x0001000;\n    enum PARODD     = 0x0002000;\n    enum HUPCL      = 0x0004000;\n    enum CLOCAL     = 0x0008000;\n\n    enum ECHO       = 0x00000008;\n    enum ECHOE      = 0x00000002;\n    enum ECHOK      = 0x00000004;\n    enum ECHONL     = 0x00000010;\n    enum ICANON     = 0x00000100;\n    enum IEXTEN     = 0x00000400;\n    enum ISIG       = 0x00000080;\n    enum NOFLSH     = 0x80000000;\n    enum TOSTOP     = 0x00400000;\n\n    enum TCSANOW    = 0;\n    enum TCSADRAIN  = 1;\n    enum TCSAFLUSH  = 2;\n\n    enum TCIFLUSH   = 1;\n    enum TCOFLUSH   = 2;\n    enum TCIOFLUSH  = 3;\n\n    enum TCIOFF     = 3;\n    enum TCION      = 4;\n    enum TCOOFF     = 1;\n    enum TCOON      = 2;\n\n    speed_t cfgetispeed(in termios*);\n    speed_t cfgetospeed(in termios*);\n    int     cfsetispeed(termios*, speed_t);\n    int     cfsetospeed(termios*, speed_t);\n    int     tcdrain(int);\n    int     tcflow(int, int);\n    int     tcflush(int, int);\n    int     tcgetattr(int, termios*);\n    int     tcsendbreak(int, int);\n    int     tcsetattr(int, int, in termios*);\n\n}\nelse version (FreeBSD)\n{\n    alias ubyte cc_t;\n    alias uint  speed_t;\n    alias uint  tcflag_t;\n\n    enum NCCS   = 20;\n\n    struct termios\n    {\n        tcflag_t   c_iflag;\n        tcflag_t   c_oflag;\n        tcflag_t   c_cflag;\n        tcflag_t   c_lflag;\n        cc_t[NCCS] c_cc;\n        speed_t    c_ispeed;\n        speed_t    c_ospeed;\n    }\n\n    enum VEOF       = 0;\n    enum VEOL       = 1;\n    enum VERASE     = 3;\n    enum VINTR      = 8;\n    enum VKILL      = 5;\n    enum VMIN       = 16;\n    enum VQUIT      = 9;\n    enum VSTART     = 12;\n    enum VSTOP      = 13;\n    enum VSUSP      = 10;\n    enum VTIME      = 17;\n\n    enum BRKINT     = 0x0000002;\n    enum ICRNL      = 0x0000100;\n    enum IGNBRK     = 0x0000001;\n    enum IGNCR      = 0x0000080;\n    enum IGNPAR     = 0x0000004;\n    enum INLCR      = 0x0000040;\n    enum INPCK      = 0x0000010;\n    enum ISTRIP     = 0x0000020;\n    enum IXOFF      = 0x0000400;\n    enum IXON       = 0x0000200;\n    enum PARMRK     = 0x0000008;\n\n    enum OPOST      = 0x0000001;\n\n    enum B0         = 0;\n    enum B50        = 50;\n    enum B75        = 75;\n    enum B110       = 110;\n    enum B134       = 134;\n    enum B150       = 150;\n    enum B200       = 200;\n    enum B300       = 300;\n    enum B600       = 600;\n    enum B1200      = 1200;\n    enum B1800      = 1800;\n    enum B2400      = 2400;\n    enum B4800      = 4800;\n    enum B9600      = 9600;\n    enum B19200     = 19200;\n    enum B38400     = 38400;\n\n    enum CSIZE      = 0x0000300;\n    enum   CS5      = 0x0000000;\n    enum   CS6      = 0x0000100;\n    enum   CS7      = 0x0000200;\n    enum   CS8      = 0x0000300;\n    enum CSTOPB     = 0x0000400;\n    enum CREAD      = 0x0000800;\n    enum PARENB     = 0x0001000;\n    enum PARODD     = 0x0002000;\n    enum HUPCL      = 0x0004000;\n    enum CLOCAL     = 0x0008000;\n\n    enum ECHO       = 0x00000008;\n    enum ECHOE      = 0x00000002;\n    enum ECHOK      = 0x00000004;\n    enum ECHONL     = 0x00000010;\n    enum ICANON     = 0x00000100;\n    enum IEXTEN     = 0x00000400;\n    enum ISIG       = 0x00000080;\n    enum NOFLSH     = 0x80000000;\n    enum TOSTOP     = 0x00400000;\n\n    enum TCSANOW    = 0;\n    enum TCSADRAIN  = 1;\n    enum TCSAFLUSH  = 2;\n\n    enum TCIFLUSH   = 1;\n    enum TCOFLUSH   = 2;\n    enum TCIOFLUSH  = 3;\n\n    enum TCIOFF     = 3;\n    enum TCION      = 4;\n    enum TCOOFF     = 1;\n    enum TCOON      = 2;\n\n    speed_t cfgetispeed(in termios*);\n    speed_t cfgetospeed(in termios*);\n    int     cfsetispeed(termios*, speed_t);\n    int     cfsetospeed(termios*, speed_t);\n    int     tcdrain(int);\n    int     tcflow(int, int);\n    int     tcflush(int, int);\n    int     tcgetattr(int, termios*);\n    int     tcsendbreak(int, int);\n    int     tcsetattr(int, int, in termios*);\n}\nelse version (DragonFlyBSD)\n{\n    alias ubyte cc_t;\n    alias uint  speed_t;\n    alias uint  tcflag_t;\n\n    enum NCCS   = 20;\n\n    struct termios\n    {\n        tcflag_t   c_iflag;\n        tcflag_t   c_oflag;\n        tcflag_t   c_cflag;\n        tcflag_t   c_lflag;\n        cc_t[NCCS] c_cc;\n        speed_t    c_ispeed;\n        speed_t    c_ospeed;\n    }\n\n    enum VEOF       = 0;\n    enum VEOL       = 1;\n    enum VERASE     = 3;\n    enum VINTR      = 8;\n    enum VKILL      = 5;\n    enum VMIN       = 16;\n    enum VQUIT      = 9;\n    enum VSTART     = 12;\n    enum VSTOP      = 13;\n    enum VSUSP      = 10;\n    enum VTIME      = 17;\n\n    enum BRKINT     = 0x0000002;\n    enum ICRNL      = 0x0000100;\n    enum IGNBRK     = 0x0000001;\n    enum IGNCR      = 0x0000080;\n    enum IGNPAR     = 0x0000004;\n    enum INLCR      = 0x0000040;\n    enum INPCK      = 0x0000010;\n    enum ISTRIP     = 0x0000020;\n    enum IXOFF      = 0x0000400;\n    enum IXON       = 0x0000200;\n    enum PARMRK     = 0x0000008;\n\n    enum OPOST      = 0x0000001;\n\n    enum B0         = 0;\n    enum B50        = 50;\n    enum B75        = 75;\n    enum B110       = 110;\n    enum B134       = 134;\n    enum B150       = 150;\n    enum B200       = 200;\n    enum B300       = 300;\n    enum B600       = 600;\n    enum B1200      = 1200;\n    enum B1800      = 1800;\n    enum B2400      = 2400;\n    enum B4800      = 4800;\n    enum B9600      = 9600;\n    enum B19200     = 19200;\n    enum B38400     = 38400;\n\n    enum CSIZE      = 0x0000300;\n    enum   CS5      = 0x0000000;\n    enum   CS6      = 0x0000100;\n    enum   CS7      = 0x0000200;\n    enum   CS8      = 0x0000300;\n    enum CSTOPB     = 0x0000400;\n    enum CREAD      = 0x0000800;\n    enum PARENB     = 0x0001000;\n    enum PARODD     = 0x0002000;\n    enum HUPCL      = 0x0004000;\n    enum CLOCAL     = 0x0008000;\n\n    enum ECHO       = 0x00000008;\n    enum ECHOE      = 0x00000002;\n    enum ECHOK      = 0x00000004;\n    enum ECHONL     = 0x00000010;\n    enum ICANON     = 0x00000100;\n    enum IEXTEN     = 0x00000400;\n    enum ISIG       = 0x00000080;\n    enum NOFLSH     = 0x80000000;\n    enum TOSTOP     = 0x00400000;\n\n    enum TCSANOW    = 0;\n    enum TCSADRAIN  = 1;\n    enum TCSAFLUSH  = 2;\n\n    enum TCIFLUSH   = 1;\n    enum TCOFLUSH   = 2;\n    enum TCIOFLUSH  = 3;\n\n    enum TCIOFF     = 3;\n    enum TCION      = 4;\n    enum TCOOFF     = 1;\n    enum TCOON      = 2;\n\n    speed_t cfgetispeed(in termios*);\n    speed_t cfgetospeed(in termios*);\n    int     cfsetispeed(termios*, speed_t);\n    int     cfsetospeed(termios*, speed_t);\n    int     tcdrain(int);\n    int     tcflow(int, int);\n    int     tcflush(int, int);\n    int     tcgetattr(int, termios*);\n    int     tcsendbreak(int, int);\n    int     tcsetattr(int, int, in termios*);\n}\nelse version (NetBSD)\n{\n    alias ubyte cc_t;\n    alias uint  speed_t;\n    alias uint  tcflag_t;\n\n    enum NCCS   = 20;\n\n    struct termios\n    {\n        tcflag_t   c_iflag;\n        tcflag_t   c_oflag;\n        tcflag_t   c_cflag;\n        tcflag_t   c_lflag;\n        cc_t[NCCS] c_cc;\n        speed_t    c_ispeed;\n        speed_t    c_ospeed;\n    }\n\n    enum VEOF       = 0;\n    enum VEOL       = 1;\n    enum VERASE     = 3;\n    enum VINTR      = 8;\n    enum VKILL      = 5;\n    enum VMIN       = 16;\n    enum VQUIT      = 9;\n    enum VSTART     = 12;\n    enum VSTOP      = 13;\n    enum VSUSP      = 10;\n    enum VTIME      = 17;\n\n    enum BRKINT     = 0x0000002;\n    enum ICRNL      = 0x0000100;\n    enum IGNBRK     = 0x0000001;\n    enum IGNCR      = 0x0000080;\n    enum IGNPAR     = 0x0000004;\n    enum INLCR      = 0x0000040;\n    enum INPCK      = 0x0000010;\n    enum ISTRIP     = 0x0000020;\n    enum IXOFF      = 0x0000400;\n    enum IXON       = 0x0000200;\n    enum PARMRK     = 0x0000008;\n\n    enum OPOST      = 0x0000001;\n\n    enum B0         = 0;\n    enum B50        = 50;\n    enum B75        = 75;\n    enum B110       = 110;\n    enum B134       = 134;\n    enum B150       = 150;\n    enum B200       = 200;\n    enum B300       = 300;\n    enum B600       = 600;\n    enum B1200      = 1200;\n    enum B1800      = 1800;\n    enum B2400      = 2400;\n    enum B4800      = 4800;\n    enum B9600      = 9600;\n    enum B19200     = 19200;\n    enum B38400     = 38400;\n\n    enum CSIZE      = 0x0000300;\n    enum   CS5      = 0x0000000;\n    enum   CS6      = 0x0000100;\n    enum   CS7      = 0x0000200;\n    enum   CS8      = 0x0000300;\n    enum CSTOPB     = 0x0000400;\n    enum CREAD      = 0x0000800;\n    enum PARENB     = 0x0001000;\n    enum PARODD     = 0x0002000;\n    enum HUPCL      = 0x0004000;\n    enum CLOCAL     = 0x0008000;\n\n    enum ECHO       = 0x00000008;\n    enum ECHOE      = 0x00000002;\n    enum ECHOK      = 0x00000004;\n    enum ECHONL     = 0x00000010;\n    enum ICANON     = 0x00000100;\n    enum IEXTEN     = 0x00000400;\n    enum ISIG       = 0x00000080;\n    enum NOFLSH     = 0x80000000;\n    enum TOSTOP     = 0x00400000;\n\n    enum TCSANOW    = 0;\n    enum TCSADRAIN  = 1;\n    enum TCSAFLUSH  = 2;\n\n    enum TCIFLUSH   = 1;\n    enum TCOFLUSH   = 2;\n    enum TCIOFLUSH  = 3;\n\n    enum TCIOFF     = 3;\n    enum TCION      = 4;\n    enum TCOOFF     = 1;\n    enum TCOON      = 2;\n\n    speed_t cfgetispeed(in termios*);\n    speed_t cfgetospeed(in termios*);\n    int     cfsetispeed(termios*, speed_t);\n    int     cfsetospeed(termios*, speed_t);\n    int     tcdrain(int);\n    int     tcflow(int, int);\n    int     tcflush(int, int);\n    int     tcgetattr(int, termios*);\n    int     tcsendbreak(int, int);\n    int     tcsetattr(int, int, in termios*);\n}\nelse version (Solaris)\n{\n    alias tcflag_t = uint;\n    alias cc_t = ubyte;\n    alias speed_t = uint;\n\n    enum NCCS   = 19;\n\n    struct termios\n    {\n        tcflag_t   c_iflag;    /* input modes */\n        tcflag_t   c_oflag;    /* output modes */\n        tcflag_t   c_cflag;    /* control modes */\n        tcflag_t   c_lflag;    /* line discipline modes */\n        cc_t[NCCS] c_cc;       /* control chars */\n    }\n\n    /* control characters */\n    enum VINTR  = 0;\n    enum VQUIT  = 1;\n    enum VERASE = 2;\n    enum VKILL  = 3;\n    enum VEOF   = 4;\n    enum VEOL   = 5;\n    enum VMIN   = 4;\n    enum VTIME  = 5;\n    enum VSTART = 8;\n    enum VSTOP  = 9;\n    enum VSUSP  = 10;\n\n    /* input modes */\n    enum IGNBRK = 0x000001;\n    enum BRKINT = 0x000002;\n    enum IGNPAR = 0x000004;\n    enum PARMRK = 0x000008;\n    enum INPCK  = 0x000010;\n    enum ISTRIP = 0x000020;\n    enum INLCR  = 0x000040;\n    enum IGNCR  = 0x000080;\n    enum ICRNL  = 0x000100;\n    enum IXON   = 0x000400;\n    enum IXOFF  = 0x001000;\n\n    /* output modes */\n    enum OPOST  = 0x000001;\n\n    /* control modes */\n    enum CSIZE  = 0x000030;\n    enum CS5    = 0x000000;\n    enum CS6    = 0x000010;\n    enum CS7    = 0x000020;\n    enum CS8    = 0x000030;\n    enum CSTOPB = 0x000040;\n    enum CREAD  = 0x000080;\n    enum PARENB = 0x000100;\n    enum PARODD = 0x000200;\n    enum HUPCL  = 0x000400;\n    enum CLOCAL = 0x000800;\n\n    enum CRTSCTS = 0x10000000;\n\n    /* line discipline 0 modes */\n    enum ISIG   = 0x000001;\n    enum ICANON = 0x000002;\n    enum ECHO   = 0x000008;\n    enum ECHOE  = 0x000010;\n    enum ECHOK  = 0x000020;\n    enum ECHONL = 0x000040;\n    enum NOFLSH = 0x000080;\n    enum TOSTOP = 0x000100;\n\n    enum ECHOCTL = 0x000200;\n    enum ECHOPRT = 0x000400;\n    enum ECHOKE  = 0x000800;\n\n    enum IEXTEN = 0x008000;  /* POSIX flag - enable POSIX extensions */\n\n    enum _TIOC      = ('T'<<8);\n    enum TCSANOW    = (_TIOC|14);\n    enum TCSADRAIN  = (_TIOC|15);\n    enum TCSAFLUSH  = (_TIOC|16);\n\n    /* termios option flags */\n    enum TCIFLUSH   = 0;  /* flush data received but not read */\n    enum TCOFLUSH   = 1;  /* flush data written but not transmitted */\n    enum TCIOFLUSH  = 2;  /* flush both data both input and output queues */\n\n    enum TCOOFF     = 0;  /* suspend output */\n    enum TCOON      = 1;  /* restart suspended output */\n    enum TCIOFF     = 2;  /* suspend input */\n    enum TCION      = 3;  /* restart suspended input */\n\n    /* Speeds */\n    enum B0      = 0;\n    enum B50     = 1;\n    enum B75     = 2;\n    enum B110    = 3;\n    enum B134    = 4;\n    enum B150    = 5;\n    enum B200    = 6;\n    enum B300    = 7;\n    enum B600    = 8;\n    enum B1200   = 9;\n    enum B1800   = 10;\n    enum B2400   = 11;\n    enum B4800   = 12;\n    enum B9600   = 13;\n    enum B19200  = 14;\n    enum B38400  = 15;\n    enum B57600  = 16;\n    enum B76800  = 17;\n    enum B115200 = 18;\n    enum B153600 = 19;\n    enum B230400 = 20;\n    enum B307200 = 21;\n    enum B460800 = 22;\n    enum B921600 = 23;\n\n    /*\n     * POSIX termios functions\n     * These functions get mapped into ioctls.\n     */\n    speed_t cfgetospeed(in termios*);\n    int     cfsetospeed(termios*, speed_t);\n    speed_t cfgetispeed(in termios*);\n    int     cfsetispeed(termios*, speed_t);\n    int     tcgetattr(int, termios*);\n    int     tcsetattr(int, int, in termios*);\n    int     tcsendbreak(int, int);\n    int     tcdrain(int);\n    int     tcflush(int, int);\n    int     tcflow(int, int);\n}\nelse version (CRuntime_UClibc)\n{\n    alias ubyte cc_t;\n    alias uint  speed_t;\n    alias uint  tcflag_t;\n\n    enum NCCS   = 32;\n\n    struct termios\n    {\n        tcflag_t   c_iflag;\n        tcflag_t   c_oflag;\n        tcflag_t   c_cflag;\n        tcflag_t   c_lflag;\n        cc_t       c_line;\n        cc_t[NCCS] c_cc;\n        speed_t    c_ispeed;\n        speed_t    c_ospeed;\n    }\n\n    enum VINTR      = 0;\n    enum VQUIT      = 1;\n    enum VERASE     = 2;\n    enum VKILL      = 3;\n    enum VEOF       = 4;\n    enum VTIME      = 5;\n    enum VMIN       = 6;\n    enum VSWTC      = 7;\n    enum VSTART     = 8;\n    enum VSTOP      = 9;\n    enum VSUSP      = 10;\n    enum VEOL       = 11;\n    enum VREPRINT   = 12;\n    enum VDISCARD   = 13;\n    enum VWERASE    = 14;\n    enum VLNEXT     = 15;\n    enum VEOL2      = 16;\n\n    enum BRKINT     = 0x0000002; // 0000002\n    enum ICRNL      = 0x0000100; // 0000400\n    enum IGNBRK     = 0x0000001; // 0000001\n    enum IGNCR      = 0x0000080; // 0000200\n    enum IGNPAR     = 0x0000004; // 0000004\n    enum INLCR      = 0x0000040; // 0000100\n    enum INPCK      = 0x0000010; // 0000020\n    enum ISTRIP     = 0x0000020; // 0000040\n    enum IXOFF      = 0x0001000; // 0010000\n    enum IXON       = 0x0000400; // 0002000\n    enum PARMRK     = 0x0000008; // 0000010\n\n    enum OPOST      = 0x0000001; // 0000001\n\n    enum B0         = 0x0000000; // 0000000\n    enum B50        = 0x0000001; // 0000001\n    enum B75        = 0x0000002; // 0000002\n    enum B110       = 0x0000003; // 0000003\n    enum B134       = 0x0000004; // 0000004\n    enum B150       = 0x0000005; // 0000005\n    enum B200       = 0x0000006; // 0000006\n    enum B300       = 0x0000007; // 0000007\n    enum B600       = 0x0000008; // 0000010\n    enum B1200      = 0x0000009; // 0000011\n    enum B1800      = 0x000000A; // 0000012\n    enum B2400      = 0x000000B; // 0000013\n    enum B4800      = 0x000000C; // 0000014\n    enum B9600      = 0x000000D; // 0000015\n    enum B19200     = 0x000000E; // 0000016\n    enum B38400     = 0x000000F; // 0000017\n\n    enum CSIZE      = 0x0000030; // 0000060\n    enum   CS5      = 0x0000000; // 0000000\n    enum   CS6      = 0x0000010; // 0000020\n    enum   CS7      = 0x0000020; // 0000040\n    enum   CS8      = 0x0000030; // 0000060\n    enum CSTOPB     = 0x0000040; // 0000100\n    enum CREAD      = 0x0000080; // 0000200\n    enum PARENB     = 0x0000100; // 0000400\n    enum PARODD     = 0x0000200; // 0001000\n    enum HUPCL      = 0x0000400; // 0002000\n    enum CLOCAL     = 0x0000800; // 0004000\n\n    enum ECHO       = 0x0000008; // 0000010\n    enum ECHOE      = 0x0000010; // 0000020\n    enum ECHOK      = 0x0000020; // 0000040\n    enum ECHONL     = 0x0000040; // 0000100\n    enum ICANON     = 0x0000002; // 0000002\n    enum IEXTEN     = 0x0008000; // 0100000\n    enum ISIG       = 0x0000001; // 0000001\n    enum NOFLSH     = 0x0000080; // 0000200\n    enum TOSTOP     = 0x0000100; // 0000400\n\n    enum TCSANOW    = 0;\n    enum TCSADRAIN  = 1;\n    enum TCSAFLUSH  = 2;\n\n    enum TCIFLUSH   = 0;\n    enum TCOFLUSH   = 1;\n    enum TCIOFLUSH  = 2;\n\n    enum TCIOFF     = 2;\n    enum TCION      = 3;\n    enum TCOOFF     = 0;\n    enum TCOON      = 1;\n\n    speed_t cfgetispeed(in termios*);\n    speed_t cfgetospeed(in termios*);\n    int     cfsetispeed(termios*, speed_t);\n    int     cfsetospeed(termios*, speed_t);\n    int     tcdrain(int);\n    int     tcflow(int, int);\n    int     tcflush(int, int);\n    int     tcgetattr(int, termios*);\n    int     tcsendbreak(int, int);\n    int     tcsetattr(int, int, in termios*);\n}\n\n//\n// XOpen (XSI)\n//\n/*\nIXANY\n\nONLCR\nOCRNL\nONOCR\nONLRET\nOFILL\nNLDLY\n    NL0\n    NL1\nCRDLY\n    CR0\n    CR1\n    CR2\n    CR3\nTABDLY\n    TAB0\n    TAB1\n    TAB2\n    TAB3\nBSDLY\n    BS0\n    BS1\nVTDLY\n    VT0\n    VT1\nFFDLY\n    FF0\n    FF1\n\npid_t   tcgetsid(int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum IXANY      = 0x0000800; // 0004000\n\n    enum ONLCR      = 0x0000004; // 0000004\n    enum OCRNL      = 0x0000008; // 0000010\n    enum ONOCR      = 0x0000010; // 0000020\n    enum ONLRET     = 0x0000020; // 0000040\n    enum OFILL      = 0x0000040; // 0000100\n    enum NLDLY      = 0x0000100; // 0000400\n    enum   NL0      = 0x0000000; // 0000000\n    enum   NL1      = 0x0000100; // 0000400\n    enum CRDLY      = 0x0000600; // 0003000\n    enum   CR0      = 0x0000000; // 0000000\n    enum   CR1      = 0x0000200; // 0001000\n    enum   CR2      = 0x0000400; // 0002000\n    enum   CR3      = 0x0000600; // 0003000\n    enum TABDLY     = 0x0001800; // 0014000\n    enum   TAB0     = 0x0000000; // 0000000\n    enum   TAB1     = 0x0000800; // 0004000\n    enum   TAB2     = 0x0001000; // 0010000\n    enum   TAB3     = 0x0001800; // 0014000\n    enum BSDLY      = 0x0002000; // 0020000\n    enum   BS0      = 0x0000000; // 0000000\n    enum   BS1      = 0x0002000; // 0020000\n    enum VTDLY      = 0x0004000; // 0040000\n    enum   VT0      = 0x0000000; // 0000000\n    enum   VT1      = 0x0004000; // 0040000\n    enum FFDLY      = 0x0008000; // 0100000\n    enum   FF0      = 0x0000000; // 0000000\n    enum   FF1      = 0x0008000; // 0100000\n\n    pid_t   tcgetsid(int);\n}\n\nelse version (Darwin)\n{\n    enum IXANY      = 0x00000800;\n\n    enum ONLCR      = 0x00000002;\n    enum OCRNL      = 0x00000010;\n    enum ONOCR      = 0x00000020;\n    enum ONLRET     = 0x00000040;\n    enum OFILL      = 0x00000080;\n    enum NLDLY      = 0x00000300;\n    enum   NL0      = 0x00000000;\n    enum   NL1      = 0x00000100;\n    enum CRDLY      = 0x00003000;\n    enum   CR0      = 0x00000000;\n    enum   CR1      = 0x00001000;\n    enum   CR2      = 0x00002000;\n    enum   CR3      = 0x00003000;\n    enum TABDLY     = 0x00000c04;\n    enum   TAB0     = 0x00000000;\n    enum   TAB1     = 0x00000400;\n    enum   TAB2     = 0x00000800;\n    enum   TAB3     = 0x00000004;\n    enum BSDLY      = 0x00008000;\n    enum   BS0      = 0x00000000;\n    enum   BS1      = 0x00008000;\n    enum VTDLY      = 0x00010000;\n    enum   VT0      = 0x00000000;\n    enum   VT1      = 0x00010000;\n    enum FFDLY      = 0x00004000;\n    enum   FF0      = 0x00000000;\n    enum   FF1      = 0x00004000;\n\n    pid_t tcgetsid (int);\n}\n\nelse version (FreeBSD)\n{\n    enum IXANY      = 0x00000800;\n\n    enum ONLCR      = 0x00000002;\n    enum OCRNL      = 0x00000010;\n    enum ONOCR      = 0x00000020;\n    enum ONLRET     = 0x00000040;\n    //enum OFILL\n    //enum NLDLY\n    //enum     NL0\n    //enum     NL1\n    //enum CRDLY\n    //enum     CR0\n    //enum     CR1\n    //enum     CR2\n    //enum     CR3\n    enum TABDLY     = 0x00000004;\n    enum     TAB0   = 0x00000000;\n    //enum     TAB1\n    //enum     TAB2\n    enum     TAB3   = 0x00000004;\n    //enum BSDLY\n    //enum     BS0\n    //enum     BS1\n    //enum VTDLY\n    //enum     VT0\n    //enum     VT1\n    //enum FFDLY\n    //enum     FF0\n    //enum     FF1\n\n    pid_t   tcgetsid(int);\n}\nelse version (DragonFlyBSD)\n{\n    enum IXANY      = 0x00000800;\n\n    enum ONLCR      = 0x00000002;\n    enum OCRNL      = 0x00000010;\n    enum ONOCR      = 0x00000020;\n    enum ONLRET     = 0x00000040;\n    //enum OFILL\n    //enum NLDLY\n    //enum     NL0\n    //enum     NL1\n    //enum CRDLY\n    //enum     CR0\n    //enum     CR1\n    //enum     CR2\n    //enum     CR3\n    enum TABDLY     = 0x00000004;\n    enum     TAB0   = 0x00000000;\n    //enum     TAB1\n    //enum     TAB2\n    enum     TAB3   = 0x00000004;\n    //enum BSDLY\n    //enum     BS0\n    //enum     BS1\n    //enum VTDLY\n    //enum     VT0\n    //enum     VT1\n    //enum FFDLY\n    //enum     FF0\n    //enum     FF1\n\n    pid_t   tcgetsid(int);\n}\nelse version (NetBSD)\n{\n    enum IXANY      = 0x00000800;\n\n    enum ONLCR      = 0x00000002;\n    enum OCRNL      = 0x00000010;\n    enum ONOCR      = 0x00000020;\n    enum ONLRET     = 0x00000040;\n    //enum OFILL\n    //enum NLDLY\n    //enum     NL0\n    //enum     NL1\n    //enum CRDLY\n    //enum     CR0\n    //enum     CR1\n    //enum     CR2\n    //enum     CR3\n    enum TABDLY     = 0x00000004;\n    enum     TAB0   = 0x00000000;\n    //enum     TAB1\n    //enum     TAB2\n    enum     TAB3   = 0x00000004;\n    //enum BSDLY\n    //enum     BS0\n    //enum     BS1\n    //enum VTDLY\n    //enum     VT0\n    //enum     VT1\n    //enum FFDLY\n    //enum     FF0\n    //enum     FF1\n\n    pid_t   tcgetsid(int);\n}\nelse version (Solaris)\n{\n    enum IXANY      = 0x0000800;\n\n    enum ONLCR      = 0x0000004;\n    enum OCRNL      = 0x0000008;\n    enum ONOCR      = 0x0000010;\n    enum ONLRET     = 0x0000020;\n    enum OFILL      = 0x0000040;\n    enum OFDEL      = 0x0000080;\n    enum NLDLY      = 0x0000100;\n    enum NL0        = 0x0000000;\n    enum NL1        = 0x0000100;\n    enum CRDLY      = 0x0000600;\n    enum CR0        = 0x0000000;\n    enum CR1        = 0x0000200;\n    enum CR2        = 0x0000400;\n    enum CR3        = 0x0000600;\n    enum TABDLY     = 0x0001800;\n    enum TAB0       = 0x0000000;\n    enum TAB1       = 0x0000800;\n    enum TAB2       = 0x0001000;\n    enum TAB3       = 0x0001800;\n    enum BSDLY      = 0x0002000;\n    enum BS0        = 0x0000000;\n    enum BS1        = 0x0002000;\n    enum VTDLY      = 0x0004000;\n    enum VT0        = 0x0000000;\n    enum VT1        = 0x0004000;\n    enum FFDLY      = 0x0008000;\n    enum FF0        = 0x0000000;\n    enum FF1        = 0x0008000;\n    enum XCASE      = 0x0000004;\n\n    pid_t   tcgetsid(int);\n}\nelse version (CRuntime_UClibc)\n{\n    enum IXANY      = 0x0000800; // 0004000\n\n    enum ONLCR      = 0x0000004; // 0000004\n    enum OCRNL      = 0x0000008; // 0000010\n    enum ONOCR      = 0x0000010; // 0000020\n    enum ONLRET     = 0x0000020; // 0000040\n    enum OFILL      = 0x0000040; // 0000100\n    enum NLDLY      = 0x0000100; // 0000400\n    enum   NL0      = 0x0000000; // 0000000\n    enum   NL1      = 0x0000100; // 0000400\n    enum CRDLY      = 0x0000600; // 0003000\n    enum   CR0      = 0x0000000; // 0000000\n    enum   CR1      = 0x0000200; // 0001000\n    enum   CR2      = 0x0000400; // 0002000\n    enum   CR3      = 0x0000600; // 0003000\n    enum TABDLY     = 0x0001800; // 0014000\n    enum   TAB0     = 0x0000000; // 0000000\n    enum   TAB1     = 0x0000800; // 0004000\n    enum   TAB2     = 0x0001000; // 0010000\n    enum   TAB3     = 0x0001800; // 0014000\n    enum BSDLY      = 0x0002000; // 0020000\n    enum   BS0      = 0x0000000; // 0000000\n    enum   BS1      = 0x0002000; // 0020000\n    enum VTDLY      = 0x0004000; // 0040000\n    enum   VT0      = 0x0000000; // 0000000\n    enum   VT1      = 0x0004000; // 0040000\n    enum FFDLY      = 0x0008000; // 0100000\n    enum   FF0      = 0x0000000; // 0000000\n    enum   FF1      = 0x0008000; // 0100000\n\n    pid_t   tcgetsid(int);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/time.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly,\n              Alex Rønne Petersen\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.time;\n\nprivate import core.sys.posix.config;\npublic import core.stdc.time;\npublic import core.sys.posix.sys.types;\npublic import core.sys.posix.signal; // for sigevent\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// Required (defined in core.stdc.time)\n//\n/*\nchar* asctime(in tm*);\nclock_t clock();\nchar* ctime(in time_t*);\ndouble difftime(time_t, time_t);\ntm* gmtime(in time_t*);\ntm* localtime(in time_t*);\ntime_t mktime(tm*);\nsize_t strftime(char*, size_t, in char*, in tm*);\ntime_t time(time_t*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    time_t timegm(tm*); // non-standard\n}\nelse version (Darwin)\n{\n    time_t timegm(tm*); // non-standard\n}\nelse version (FreeBSD)\n{\n    time_t timegm(tm*); // non-standard\n}\nelse version (NetBSD)\n{\n    time_t timegm(tm*); // non-standard\n}\nelse version (DragonFlyBSD)\n{\n    time_t timegm(tm*); // non-standard\n}\nelse version (Solaris)\n{\n    time_t timegm(tm*); // non-standard\n}\nelse version (CRuntime_Bionic)\n{\n    // Not supported.\n}\nelse version (CRuntime_Musl)\n{\n    time_t timegm(tm*);\n}\nelse version (CRuntime_UClibc)\n{\n    time_t timegm(tm*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// C Extension (CX)\n// (defined in core.stdc.time)\n//\n/*\nchar* tzname[];\nvoid tzset();\n*/\n\n//\n// Process CPU-Time Clocks (CPT)\n//\n/*\nint clock_getcpuclockid(pid_t, clockid_t*);\n*/\n\n//\n// Clock Selection (CS)\n//\n/*\nint clock_nanosleep(clockid_t, int, in timespec*, timespec*);\n*/\n\n//\n// Monotonic Clock (MON)\n//\n/*\nCLOCK_MONOTONIC\n*/\n\nversion (linux)\n{\n    enum CLOCK_MONOTONIC          = 1;\n    // To be removed in December 2015.\n    static import core.sys.linux.time;\n    deprecated(\"Please import it from core.sys.linux.time instead.\")\n        alias CLOCK_MONOTONIC_RAW = core.sys.linux.time.CLOCK_MONOTONIC_RAW; // non-standard\n    deprecated(\"Please import it from core.sys.linux.time instead.\")\n        alias CLOCK_MONOTONIC_COARSE = core.sys.linux.time.CLOCK_MONOTONIC_COARSE; // non-standard\n}\nelse version (FreeBSD)\n{   // time.h\n    enum CLOCK_MONOTONIC         = 4;\n    // To be removed in December 2015.\n    static import core.sys.freebsd.time;\n    deprecated(\"Please import it from core.sys.freebsd.time instead.\")\n        alias CLOCK_MONOTONIC_PRECISE = core.sys.freebsd.time.CLOCK_MONOTONIC_PRECISE;\n    deprecated(\"Please import it from core.sys.freebsd.time instead.\")\n        alias CLOCK_MONOTONIC_FAST = core.sys.freebsd.time.CLOCK_MONOTONIC_FAST;\n}\nelse version (NetBSD)\n{\n    // time.h\n    enum CLOCK_MONOTONIC         = 3;\n}\nelse version (DragonFlyBSD)\n{   // time.h\n    enum CLOCK_MONOTONIC         = 4;\n    // To be removed in December 2015.\n    static import core.sys.dragonflybsd.time;\n    deprecated(\"Please import it from core.sys.dragonflybsd.time instead.\")\n        alias CLOCK_MONOTONIC_PRECISE = core.sys.dragonflybsd.time.CLOCK_MONOTONIC_PRECISE;\n    deprecated(\"Please import it from core.sys.dragonflybsd.time instead.\")\n        alias CLOCK_MONOTONIC_FAST = core.sys.dragonflybsd.time.CLOCK_MONOTONIC_FAST;\n}\nelse version (Darwin)\n{\n    // No CLOCK_MONOTONIC defined\n}\nelse version (Solaris)\n{\n    enum CLOCK_MONOTONIC = 4;\n}\nelse\n{\n    static assert(0);\n}\n\n//\n// Timer (TMR)\n//\n/*\nCLOCK_PROCESS_CPUTIME_ID (TMR|CPT)\nCLOCK_THREAD_CPUTIME_ID (TMR|TCT)\n\nNOTE: timespec must be defined in core.sys.posix.signal to break\n      a circular import.\n\nstruct timespec\n{\n    time_t  tv_sec;\n    int     tv_nsec;\n}\n\nstruct itimerspec\n{\n    timespec it_interval;\n    timespec it_value;\n}\n\nCLOCK_REALTIME\nTIMER_ABSTIME\n\nclockid_t\ntimer_t\n\nint clock_getres(clockid_t, timespec*);\nint clock_gettime(clockid_t, timespec*);\nint clock_settime(clockid_t, in timespec*);\nint nanosleep(in timespec*, timespec*);\nint timer_create(clockid_t, sigevent*, timer_t*);\nint timer_delete(timer_t);\nint timer_gettime(timer_t, itimerspec*);\nint timer_getoverrun(timer_t);\nint timer_settime(timer_t, int, in itimerspec*, itimerspec*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    enum CLOCK_PROCESS_CPUTIME_ID = 2;\n    enum CLOCK_THREAD_CPUTIME_ID  = 3;\n\n    // NOTE: See above for why this is commented out.\n    //\n    //struct timespec\n    //{\n    //    time_t  tv_sec;\n    //    c_long  tv_nsec;\n    //}\n\n    struct itimerspec\n    {\n        timespec it_interval;\n        timespec it_value;\n    }\n\n    enum CLOCK_REALTIME         = 0;\n    // To be removed in December 2015.\n    static import core.sys.linux.time;\n    deprecated(\"Please import it from core.sys.linux.time instead.\")\n        alias CLOCK_REALTIME_COARSE = core.sys.linux.time.CLOCK_REALTIME_COARSE; // non-standard\n    enum TIMER_ABSTIME          = 0x01;\n\n    alias int clockid_t;\n    alias void* timer_t;\n\n    int clock_getres(clockid_t, timespec*);\n    int clock_gettime(clockid_t, timespec*);\n    int clock_settime(clockid_t, in timespec*);\n    int nanosleep(in timespec*, timespec*);\n    int timer_create(clockid_t, sigevent*, timer_t*);\n    int timer_delete(timer_t);\n    int timer_gettime(timer_t, itimerspec*);\n    int timer_getoverrun(timer_t);\n    int timer_settime(timer_t, int, in itimerspec*, itimerspec*);\n}\nelse version (Darwin)\n{\n    int nanosleep(in timespec*, timespec*);\n}\nelse version (FreeBSD)\n{\n    //enum CLOCK_PROCESS_CPUTIME_ID = ??;\n    enum CLOCK_THREAD_CPUTIME_ID  = 15;\n\n    // NOTE: See above for why this is commented out.\n    //\n    //struct timespec\n    //{\n    //    time_t  tv_sec;\n    //    c_long  tv_nsec;\n    //}\n\n    struct itimerspec\n    {\n        timespec it_interval;\n        timespec it_value;\n    }\n\n    enum CLOCK_REALTIME      = 0;\n    enum TIMER_ABSTIME       = 0x01;\n\n    alias int clockid_t; // <sys/_types.h>\n    alias int timer_t;\n\n    int clock_getres(clockid_t, timespec*);\n    int clock_gettime(clockid_t, timespec*);\n    int clock_settime(clockid_t, in timespec*);\n    int nanosleep(in timespec*, timespec*);\n    int timer_create(clockid_t, sigevent*, timer_t*);\n    int timer_delete(timer_t);\n    int timer_gettime(timer_t, itimerspec*);\n    int timer_getoverrun(timer_t);\n    int timer_settime(timer_t, int, in itimerspec*, itimerspec*);\n}\nelse version (DragonFlyBSD)\n{\n    enum CLOCK_THREAD_CPUTIME_ID  = 15;\n\n    struct itimerspec\n    {\n        timespec it_interval;\n        timespec it_value;\n    }\n\n    enum CLOCK_REALTIME      = 0;\n    enum TIMER_ABSTIME       = 0x01;\n\n    alias int clockid_t; // <sys/_types.h>\n    alias int timer_t;\n\n    int clock_getres(clockid_t, timespec*);\n    int clock_gettime(clockid_t, timespec*);\n    int clock_settime(clockid_t, in timespec*);\n    int nanosleep(in timespec*, timespec*);\n    int timer_create(clockid_t, sigevent*, timer_t*);\n    int timer_delete(timer_t);\n    int timer_gettime(timer_t, itimerspec*);\n    int timer_getoverrun(timer_t);\n    int timer_settime(timer_t, int, in itimerspec*, itimerspec*);\n}\nelse version (NetBSD)\n{\n    struct itimerspec\n    {\n        timespec it_interval;\n        timespec it_value;\n    }\n\n    enum CLOCK_REALTIME      = 0;\n    enum TIMER_ABSTIME       = 0x01;\n\n    alias int clockid_t; // <sys/_types.h>\n    alias int timer_t;\n\n    int clock_getres(clockid_t, timespec*);\n    int clock_gettime(clockid_t, timespec*);\n    int clock_settime(clockid_t, in timespec*);\n    int nanosleep(in timespec*, timespec*);\n    int timer_create(clockid_t, sigevent*, timer_t*);\n    int timer_delete(timer_t);\n    int timer_gettime(timer_t, itimerspec*);\n    int timer_getoverrun(timer_t);\n    int timer_settime(timer_t, int, in itimerspec*, itimerspec*);\n}\nelse version (Solaris)\n{\n    enum CLOCK_PROCESS_CPUTIME_ID = 5; // <sys/time_impl.h>\n    enum CLOCK_THREAD_CPUTIME_ID  = 2; // <sys/time_impl.h>\n\n    struct itimerspec\n    {\n        timespec it_interval;\n        timespec it_value;\n    }\n\n    enum CLOCK_REALTIME = 3; // <sys/time_impl.h>\n    enum TIMER_ABSOLUTE = 0x1;\n\n    alias int clockid_t;\n    alias int timer_t;\n\n    int clock_getres(clockid_t, timespec*);\n    int clock_gettime(clockid_t, timespec*);\n    int clock_settime(clockid_t, in timespec*);\n    int clock_nanosleep(clockid_t, int, in timespec*, timespec*);\n\n    int nanosleep(in timespec*, timespec*);\n\n    int timer_create(clockid_t, sigevent*, timer_t*);\n    int timer_delete(timer_t);\n    int timer_getoverrun(timer_t);\n    int timer_gettime(timer_t, itimerspec*);\n    int timer_settime(timer_t, int, in itimerspec*, itimerspec*);\n}\nelse version (CRuntime_Bionic)\n{\n    enum CLOCK_PROCESS_CPUTIME_ID = 2;\n    enum CLOCK_THREAD_CPUTIME_ID  = 3;\n\n    struct itimerspec\n    {\n        timespec it_interval;\n        timespec it_value;\n    }\n\n    enum CLOCK_REALTIME    = 0;\n    enum CLOCK_REALTIME_HR = 4;\n    enum TIMER_ABSTIME     = 0x01;\n\n    alias int   clockid_t;\n    alias void* timer_t; // Updated since Lollipop\n\n    int clock_getres(int, timespec*);\n    int clock_gettime(int, timespec*);\n    int nanosleep(in timespec*, timespec*);\n    int timer_create(int, sigevent*, timer_t*);\n    int timer_delete(timer_t);\n    int timer_gettime(timer_t, itimerspec*);\n    int timer_getoverrun(timer_t);\n    int timer_settime(timer_t, int, in itimerspec*, itimerspec*);\n}\nelse version (CRuntime_Musl)\n{\n    alias int clockid_t;\n    alias void* timer_t;\n\n    struct itimerspec\n    {\n        timespec it_interval;\n        timespec it_value;\n    }\n\n    enum TIMER_ABSTIME = 1;\n\n    enum CLOCK_REALTIME = 0;\n    enum CLOCK_PROCESS_CPUTIME_ID = 2;\n    enum CLOCK_THREAD_CPUTIME_ID = 3;\n    enum CLOCK_REALTIME_COARSE = 5;\n    enum CLOCK_BOOTTIME = 7;\n    enum CLOCK_REALTIME_ALARM = 8;\n    enum CLOCK_BOOTTIME_ALARM = 9;\n    enum CLOCK_SGI_CYCLE = 10;\n    enum CLOCK_TAI = 11;\n\n    int nanosleep(in timespec*, timespec*);\n\n    int clock_getres(clockid_t, timespec*);\n    int clock_gettime(clockid_t, timespec*);\n    int clock_settime(clockid_t, in timespec*);\n    int clock_nanosleep(clockid_t, int, in timespec*, timespec*);\n    int clock_getcpuclockid(pid_t, clockid_t *);\n\n    int timer_create(clockid_t, sigevent*, timer_t*);\n    int timer_delete(timer_t);\n    int timer_gettime(timer_t, itimerspec*);\n    int timer_settime(timer_t, int, in itimerspec*, itimerspec*);\n    int timer_getoverrun(timer_t);\n}\nelse version (CRuntime_UClibc)\n{\n    enum CLOCK_REALTIME             = 0;\n    enum CLOCK_PROCESS_CPUTIME_ID   = 2;\n    enum CLOCK_THREAD_CPUTIME_ID    = 3;\n\n    struct itimerspec\n    {\n        timespec it_interval;\n        timespec it_value;\n    }\n\n    enum TIMER_ABSTIME          = 0x01;\n\n    alias int clockid_t;\n    alias void* timer_t;\n\n    int clock_getres(clockid_t, timespec*);\n    int clock_gettime(clockid_t, timespec*);\n    int clock_settime(clockid_t, in timespec*);\n    int nanosleep(in timespec*, timespec*);\n    int timer_create(clockid_t, sigevent*, timer_t*);\n    int timer_delete(timer_t);\n    int timer_gettime(timer_t, itimerspec*);\n    int timer_getoverrun(timer_t);\n    int timer_settime(timer_t, int, in itimerspec*, itimerspec*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// Thread-Safe Functions (TSF)\n//\n/*\nchar* asctime_r(in tm*, char*);\nchar* ctime_r(in time_t*, char*);\ntm*   gmtime_r(in time_t*, tm*);\ntm*   localtime_r(in time_t*, tm*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    char* asctime_r(in tm*, char*);\n    char* ctime_r(in time_t*, char*);\n    tm*   gmtime_r(in time_t*, tm*);\n    tm*   localtime_r(in time_t*, tm*);\n}\nelse version (Darwin)\n{\n    char* asctime_r(in tm*, char*);\n    char* ctime_r(in time_t*, char*);\n    tm*   gmtime_r(in time_t*, tm*);\n    tm*   localtime_r(in time_t*, tm*);\n}\nelse version (FreeBSD)\n{\n    char* asctime_r(in tm*, char*);\n    char* ctime_r(in time_t*, char*);\n    tm*   gmtime_r(in time_t*, tm*);\n    tm*   localtime_r(in time_t*, tm*);\n}\nelse version (NetBSD)\n{\n    char* asctime_r(in tm*, char*);\n    char* ctime_r(in time_t*, char*);\n    tm*   gmtime_r(in time_t*, tm*);\n    tm*   localtime_r(in time_t*, tm*);\n}\nelse version (DragonFlyBSD)\n{\n    char* asctime_r(in tm*, char*);\n    char* ctime_r(in time_t*, char*);\n    tm*   gmtime_r(in time_t*, tm*);\n    tm*   localtime_r(in time_t*, tm*);\n}\nelse version (Solaris)\n{\n    char* asctime_r(in tm*, char*);\n    char* ctime_r(in time_t*, char*);\n    tm* gmtime_r(in time_t*, tm*);\n    tm* localtime_r(in time_t*, tm*);\n}\nelse version (CRuntime_Bionic)\n{\n    char* asctime_r(in tm*, char*);\n    char* ctime_r(in time_t*, char*);\n    tm* gmtime_r(in time_t*, tm*);\n    tm* localtime_r(in time_t*, tm*);\n}\nelse version (CRuntime_Musl)\n{\n    char* asctime_r(in tm*, char*);\n    char* ctime_r(in time_t*, char*);\n    tm*   gmtime_r(in time_t*, tm*);\n    tm*   localtime_r(in time_t*, tm*);\n}\nelse version (CRuntime_UClibc)\n{\n    char* asctime_r(in tm*, char*);\n    char* ctime_r(in time_t*, char*);\n    tm*   gmtime_r(in time_t*, tm*);\n    tm*   localtime_r(in time_t*, tm*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n\n//\n// XOpen (XSI)\n//\n/*\ngetdate_err\n\nint daylight;\nint timezone;\n\ntm* getdate(in char*);\nchar* strptime(in char*, in char*, tm*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    extern __gshared int    daylight;\n    extern __gshared c_long timezone;\n\n    tm*   getdate(in char*);\n    char* strptime(in char*, in char*, tm*);\n}\nelse version (Darwin)\n{\n    extern __gshared c_long timezone;\n    extern __gshared int    daylight;\n\n    tm*   getdate(in char*);\n    char* strptime(in char*, in char*, tm*);\n}\nelse version (FreeBSD)\n{\n    //tm*   getdate(in char*);\n    char* strptime(in char*, in char*, tm*);\n}\nelse version (NetBSD)\n{\n    tm*   getdate(in char*);\n    char* strptime(in char*, in char*, tm*);\n}\nelse version (DragonFlyBSD)\n{\n    //tm*   getdate(in char*);\n    char* strptime(in char*, in char*, tm*);\n}\nelse version (Solaris)\n{\n    extern __gshared c_long timezone, altzone;\n    extern __gshared int daylight;\n\n    tm* getdate(in char*);\n    char* __strptime_dontzero(in char*, in char*, tm*);\n    alias __strptime_dontzero strptime;\n}\nelse version (CRuntime_Bionic)\n{\n    extern __gshared int    daylight;\n    extern __gshared c_long timezone;\n\n    char* strptime(in char*, in char*, tm*);\n}\nelse version (CRuntime_Musl)\n{\n    tm*   getdate(in char*);\n    char* strptime(in char*, in char*, tm*);\n}\nelse version (CRuntime_UClibc)\n{\n    extern __gshared int    daylight;\n    extern __gshared c_long timezone;\n\n    tm*   getdate(in char*);\n    char* strptime(in char*, in char*, tm*);\n}\nelse\n{\n    static assert(false, \"Unsupported platform\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/ucontext.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.ucontext;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.signal; // for sigset_t, stack_t\nprivate import core.stdc.stdint : uintptr_t;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// XOpen (XSI)\n//\n/*\nmcontext_t\n\nstruct ucontext_t\n{\n    ucontext_t* uc_link;\n    sigset_t    uc_sigmask;\n    stack_t     uc_stack;\n    mcontext_t  uc_mcontext;\n}\n*/\n\nversion (CRuntime_Glibc)\n{\n\n    version (X86_64)\n    {\n        enum\n        {\n            REG_R8 = 0,\n            REG_R9,\n            REG_R10,\n            REG_R11,\n            REG_R12,\n            REG_R13,\n            REG_R14,\n            REG_R15,\n            REG_RDI,\n            REG_RSI,\n            REG_RBP,\n            REG_RBX,\n            REG_RDX,\n            REG_RAX,\n            REG_RCX,\n            REG_RSP,\n            REG_RIP,\n            REG_EFL,\n            REG_CSGSFS,     /* Actually short cs, gs, fs, __pad0.  */\n            REG_ERR,\n            REG_TRAPNO,\n            REG_OLDMASK,\n            REG_CR2\n        }\n\n        private\n        {\n            struct _libc_fpxreg\n            {\n                ushort[4] significand;\n                ushort    exponent;\n                ushort[3] padding;\n            }\n\n            struct _libc_xmmreg\n            {\n                uint[4] element;\n            }\n\n            struct _libc_fpstate\n            {\n                ushort           cwd;\n                ushort           swd;\n                ushort           ftw;\n                ushort           fop;\n                ulong            rip;\n                ulong            rdp;\n                uint             mxcsr;\n                uint             mxcr_mask;\n                _libc_fpxreg[8]  _st;\n                _libc_xmmreg[16] _xmm;\n                uint[24]         padding;\n            }\n\n            enum NGREG = 23;\n\n            alias c_long            greg_t;\n            alias greg_t[NGREG]     gregset_t;\n            alias _libc_fpstate*    fpregset_t;\n        }\n\n        struct mcontext_t\n        {\n            gregset_t   gregs;\n            fpregset_t  fpregs;\n            c_ulong[8]  __reserved1;\n        }\n\n        struct ucontext_t\n        {\n            c_ulong         uc_flags;\n            ucontext_t*     uc_link;\n            stack_t         uc_stack;\n            mcontext_t      uc_mcontext;\n            sigset_t        uc_sigmask;\n            _libc_fpstate   __fpregs_mem;\n        }\n    }\n    else version (X86)\n    {\n        enum\n        {\n            REG_GS = 0,\n            REG_FS,\n            REG_ES,\n            REG_DS,\n            REG_EDI,\n            REG_ESI,\n            REG_EBP,\n            REG_ESP,\n            REG_EBX,\n            REG_EDX,\n            REG_ECX,\n            REG_EAX,\n            REG_TRAPNO,\n            REG_ERR,\n            REG_EIP,\n            REG_CS,\n            REG_EFL,\n            REG_UESP,\n            REG_SS\n        }\n\n        private\n        {\n            struct _libc_fpreg\n            {\n              ushort[4] significand;\n              ushort    exponent;\n            }\n\n            struct _libc_fpstate\n            {\n              c_ulong           cw;\n              c_ulong           sw;\n              c_ulong           tag;\n              c_ulong           ipoff;\n              c_ulong           cssel;\n              c_ulong           dataoff;\n              c_ulong           datasel;\n              _libc_fpreg[8]    _st;\n              c_ulong           status;\n            }\n\n            enum NGREG = 19;\n\n            alias int               greg_t;\n            alias greg_t[NGREG]     gregset_t;\n            alias _libc_fpstate*    fpregset_t;\n        }\n\n        struct mcontext_t\n        {\n            gregset_t   gregs;\n            fpregset_t  fpregs;\n            c_ulong     oldmask;\n            c_ulong     cr2;\n        }\n\n        struct ucontext_t\n        {\n            c_ulong         uc_flags;\n            ucontext_t*     uc_link;\n            stack_t         uc_stack;\n            mcontext_t      uc_mcontext;\n            sigset_t        uc_sigmask;\n            _libc_fpstate   __fpregs_mem;\n        }\n    }\n    else version (MIPS32)\n    {\n        private\n        {\n            enum NGREG  = 32;\n            enum NFPREG = 32;\n\n            alias ulong         greg_t;\n            alias greg_t[NGREG] gregset_t;\n\n            struct fpregset_t\n            {\n                union fp_r_t\n                {\n                    double[NFPREG]  fp_dregs;\n                    static struct fp_fregs_t\n                    {\n                        float   _fp_fregs;\n                        uint    _fp_pad;\n                    } fp_fregs_t[NFPREG] fp_fregs;\n                } fp_r_t fp_r;\n            }\n        }\n\n        version (MIPS_O32)\n        {\n            struct mcontext_t\n            {\n                uint regmask;\n                uint status;\n                greg_t pc;\n                gregset_t gregs;\n                fpregset_t fpregs;\n                uint fp_owned;\n                uint fpc_csr;\n                uint fpc_eir;\n                uint used_math;\n                uint dsp;\n                greg_t mdhi;\n                greg_t mdlo;\n                c_ulong hi1;\n                c_ulong lo1;\n                c_ulong hi2;\n                c_ulong lo2;\n                c_ulong hi3;\n                c_ulong lo3;\n            }\n        }\n        else\n        {\n            struct mcontext_t\n            {\n                gregset_t gregs;\n                fpregset_t fpregs;\n                greg_t mdhi;\n                greg_t hi1;\n                greg_t hi2;\n                greg_t hi3;\n                greg_t mdlo;\n                greg_t lo1;\n                greg_t lo2;\n                greg_t lo3;\n                greg_t pc;\n                uint fpc_csr;\n                uint used_math;\n                uint dsp;\n                uint reserved;\n            }\n        }\n\n        struct ucontext_t\n        {\n            c_ulong     uc_flags;\n            ucontext_t* uc_link;\n            stack_t     uc_stack;\n            mcontext_t  uc_mcontext;\n            sigset_t    uc_sigmask;\n        }\n    }\n    else version (MIPS64)\n    {\n        private\n        {\n            enum NGREG  = 32;\n            enum NFPREG = 32;\n\n            alias ulong         greg_t;\n            alias greg_t[NGREG] gregset_t;\n\n            struct fpregset_t\n            {\n                union fp_r_t\n                {\n                    double[NFPREG]  fp_dregs;\n                    static struct fp_fregs_t\n                    {\n                        float   _fp_fregs;\n                        uint    _fp_pad;\n                    } fp_fregs_t[NFPREG] fp_fregs;\n                } fp_r_t fp_r;\n            }\n        }\n\n        struct mcontext_t\n        {\n            gregset_t gregs;\n            fpregset_t fpregs;\n            greg_t mdhi;\n            greg_t hi1;\n            greg_t hi2;\n            greg_t hi3;\n            greg_t mdlo;\n            greg_t lo1;\n            greg_t lo2;\n            greg_t lo3;\n            greg_t pc;\n            uint fpc_csr;\n            uint used_math;\n            uint dsp;\n            uint reserved;\n        }\n\n        struct ucontext_t\n        {\n            c_ulong     uc_flags;\n            ucontext_t* uc_link;\n            stack_t     uc_stack;\n            mcontext_t  uc_mcontext;\n            sigset_t    uc_sigmask;\n        }\n    }\n    else version (PPC)\n    {\n        private\n        {\n            enum NGREG  = 48;\n\n            alias c_ulong        greg_t;\n            alias greg_t[NGREG]  gregset_t;\n\n            struct fpregset_t\n            {\n                double[32] fpregs;\n                double fpscr;\n                uint[2] _pad;\n            }\n\n            struct vrregset_t\n            {\n                uint[32][4] vrregs;\n                uint        vrsave;\n                uint[2]     __pad;\n                uint vscr;\n            }\n\n            struct pt_regs\n            {\n                c_ulong[32] gpr;\n                c_ulong     nip;\n                c_ulong     msr;\n                c_ulong     orig_gpr3;\n                c_ulong     ctr;\n                c_ulong     link;\n                c_ulong     xer;\n                c_ulong     ccr;\n                c_ulong     mq;\n                c_ulong     trap;\n                c_ulong     dar;\n                c_ulong     dsisr;\n                c_ulong     result;\n            }\n        }\n\n        struct mcontext_t\n        {\n            gregset_t gregs;\n            fpregset_t fpregs;\n            align(16) vrregset_t vrregs;\n        }\n\n        struct ucontext_t\n        {\n            c_ulong     uc_flags;\n            ucontext_t* uc_link;\n            stack_t     uc_stack;\n            int[7]      uc_pad;\n            union uc_mcontext\n            {\n                pt_regs*     regs;\n                mcontext_t*  uc_regs;\n            }\n            sigset_t    uc_sigmask;\n            char[mcontext_t.sizeof + 12] uc_reg_space;\n        }\n    }\n    else version (PPC64)\n    {\n        private\n        {\n            enum NGREG  = 48;\n            enum NFPREG = 33;\n            enum NVRREG = 34;\n\n            alias c_ulong        greg_t;\n            alias greg_t[NGREG]  gregset_t;\n            alias double[NFPREG] fpregset_t;\n\n            struct vscr_t\n            {\n                uint[3] __pad;\n                uint    vscr_word;\n            }\n\n            struct vrregset_t\n            {\n                uint[32][4] vrregs;\n                vscr_t      vscr;\n                uint        vrsave;\n                uint[3]     __pad;\n            }\n\n            struct pt_regs\n            {\n                c_ulong[32] gpr;\n                c_ulong     nip;\n                c_ulong     msr;\n                c_ulong     orig_gpr3;\n                c_ulong     ctr;\n                c_ulong     link;\n                c_ulong     xer;\n                c_ulong     ccr;\n                c_ulong     softe;\n                c_ulong     trap;\n                c_ulong     dar;\n                c_ulong     dsisr;\n                c_ulong     result;\n            }\n        }\n\n        struct mcontext_t\n        {\n            c_ulong[4] __unused;\n            int signal;\n            int __pad0;\n            c_ulong handler;\n            c_ulong oldmask;\n            pt_regs* regs;\n            gregset_t gp_regs;\n            fpregset_t fp_regs;\n            vrregset_t *v_regs;\n            c_long[NVRREG+NVRREG+1] vmx_reserve;\n        }\n\n        struct ucontext_t\n        {\n            c_ulong     uc_flags;\n            ucontext_t* uc_link;\n            stack_t     uc_stack;\n            sigset_t    uc_sigmask;\n            mcontext_t  uc_mcontext;\n        }\n    }\n    else version (ARM)\n    {\n        enum\n        {\n            R0 = 0,\n            R1 = 1,\n            R2 = 2,\n            R3 = 3,\n            R4 = 4,\n            R5 = 5,\n            R6 = 6,\n            R7 = 7,\n            R8 = 8,\n            R9 = 9,\n            R10 = 10,\n            R11 = 11,\n            R12 = 12,\n            R13 = 13,\n            R14 = 14,\n            R15 = 15\n        }\n\n        struct sigcontext\n        {\n            c_ulong trap_no;\n            c_ulong error_code;\n            c_ulong oldmask;\n            c_ulong arm_r0;\n            c_ulong arm_r1;\n            c_ulong arm_r2;\n            c_ulong arm_r3;\n            c_ulong arm_r4;\n            c_ulong arm_r5;\n            c_ulong arm_r6;\n            c_ulong arm_r7;\n            c_ulong arm_r8;\n            c_ulong arm_r9;\n            c_ulong arm_r10;\n            c_ulong arm_fp;\n            c_ulong arm_ip;\n            c_ulong arm_sp;\n            c_ulong arm_lr;\n            c_ulong arm_pc;\n            c_ulong arm_cpsr;\n            c_ulong fault_address;\n        }\n\n        //alias elf_fpregset_t fpregset_t;\n        alias sigcontext mcontext_t;\n\n        struct ucontext_t\n        {\n            c_ulong uc_flags;\n            ucontext_t* uc_link;\n            stack_t uc_stack;\n            mcontext_t uc_mcontext;\n            sigset_t uc_sigmask;\n            align(8) c_ulong[128] uc_regspace;\n        }\n    }\n    else version (AArch64)\n    {\n        alias int greg_t;\n\n        struct sigcontext {\n            ulong           fault_address;\n            /* AArch64 registers */\n            ulong[31]       regs;\n            ulong           sp;\n            ulong           pc;\n            ulong           pstate;\n            /* 4K reserved for FP/SIMD state and future expansion */\n            align(16) ubyte[4096] __reserved;\n        }\n\n        alias sigcontext mcontext_t;\n\n        struct ucontext_t\n        {\n            c_ulong     uc_flags;\n            ucontext_t* uc_link;\n            stack_t     uc_stack;\n            sigset_t    uc_sigmask;\n            mcontext_t  uc_mcontext;\n        }\n    }\n    else version (SPARC64)\n    {\n        enum MC_NGREG = 19;\n        alias mc_greg_t = c_ulong;\n        alias mc_gregset_t = mc_greg_t[MC_NGREG];\n\n        struct mc_fq\n        {\n            c_ulong* mcfq_addr;\n            uint     mcfq_insn;\n        }\n\n        struct mc_fpu_t\n        {\n            union mcfpu_fregs_t\n            {\n                uint[32]    sregs;\n                c_ulong[32] dregs;\n                real[16]    qregs;\n            }\n            mcfpu_fregs_t mcfpu_fregs;\n            c_ulong       mcfpu_fsr;\n            c_ulong       mcfpu_fprs;\n            c_ulong       mcfpu_gsr;\n            mc_fq*        mcfpu_fq;\n            ubyte         mcfpu_qcnt;\n            ubyte         mcfpu_qentsz;\n            ubyte         mcfpu_enab;\n        }\n\n        struct mcontext_t\n        {\n            mc_gregset_t mc_gregs;\n            mc_greg_t    mc_fp;\n            mc_greg_t    mc_i7;\n            mc_fpu_t     mc_fpregs;\n        }\n\n        struct ucontext_t\n        {\n            ucontext_t* uc_link;\n            c_ulong     uc_flags;\n            c_ulong     __uc_sigmask;\n            mcontext_t  uc_mcontext;\n            stack_t     uc_stack;\n            sigset_t    uc_sigmask;\n        }\n\n        /* Location of the users' stored registers relative to R0.\n         * Usage is as an index into a gregset_t array. */\n        enum\n        {\n            REG_PSR = 0,\n            REG_PC  = 1,\n            REG_nPC = 2,\n            REG_Y   = 3,\n            REG_G1  = 4,\n            REG_G2  = 5,\n            REG_G3  = 6,\n            REG_G4  = 7,\n            REG_G5  = 8,\n            REG_G6  = 9,\n            REG_G7  = 10,\n            REG_O0  = 11,\n            REG_O1  = 12,\n            REG_O2  = 13,\n            REG_O3  = 14,\n            REG_O4  = 15,\n            REG_O5  = 16,\n            REG_O6  = 17,\n            REG_O7  = 18,\n            REG_ASI = 19,\n            REG_FPRS = 20,\n        }\n\n        enum NGREG = 21;\n        alias greg_t = c_ulong;\n        alias gregset_t = greg_t[NGREG];\n    }\n    else version (SystemZ)\n    {\n        public import core.sys.posix.signal : sigset_t;\n\n        enum NGREG = 27;\n\n        alias greg_t = c_ulong;\n        alias gregset_t = align(8) greg_t[NGREG];\n\n        align(8) struct __psw_t\n        {\n            c_ulong mask;\n            c_ulong addr;\n        }\n\n        union fpreg_t\n        {\n            double d;\n            float  f;\n        }\n\n        struct fpregset_t\n        {\n            uint        fpc;\n            fpreg_t[16] fprs;\n        }\n\n        struct  mcontext_t\n        {\n            __psw_t     psw;\n            c_ulong[16] gregs;\n            uint[16]    aregs;\n            fpregset_t  fpregs;\n        }\n\n        struct ucontext\n        {\n            c_ulong    uc_flags;\n            ucontext*  uc_link;\n            stack_t    uc_stack;\n            mcontext_t uc_mcontext;\n            sigset_t   uc_sigmask;\n        }\n\n        alias ucontext_t = ucontext;\n    }\n    else\n        static assert(0, \"unimplemented\");\n}\nelse version (FreeBSD)\n{\n    // <machine/ucontext.h>\n    version (X86_64)\n    {\n      alias long __register_t;\n      alias uint __uint32_t;\n      alias ushort __uint16_t;\n\n      struct mcontext_t {\n       __register_t    mc_onstack;\n       __register_t    mc_rdi;\n       __register_t    mc_rsi;\n       __register_t    mc_rdx;\n       __register_t    mc_rcx;\n       __register_t    mc_r8;\n       __register_t    mc_r9;\n       __register_t    mc_rax;\n       __register_t    mc_rbx;\n       __register_t    mc_rbp;\n       __register_t    mc_r10;\n       __register_t    mc_r11;\n       __register_t    mc_r12;\n       __register_t    mc_r13;\n       __register_t    mc_r14;\n       __register_t    mc_r15;\n       __uint32_t      mc_trapno;\n       __uint16_t      mc_fs;\n       __uint16_t      mc_gs;\n       __register_t    mc_addr;\n       __uint32_t      mc_flags;\n       __uint16_t      mc_es;\n       __uint16_t      mc_ds;\n       __register_t    mc_err;\n       __register_t    mc_rip;\n       __register_t    mc_cs;\n       __register_t    mc_rflags;\n       __register_t    mc_rsp;\n       __register_t    mc_ss;\n\n       long    mc_len;                 /* sizeof(mcontext_t) */\n\n       long    mc_fpformat;\n       long    mc_ownedfp;\n\n       align(16)\n       long[64]    mc_fpstate;\n\n       __register_t    mc_fsbase;\n       __register_t    mc_gsbase;\n\n       long[6]    mc_spare;\n      }\n    }\n    else version (X86)\n    {\n        alias int __register_t;\n\n        struct mcontext_t\n        {\n            __register_t    mc_onstack;\n            __register_t    mc_gs;\n            __register_t    mc_fs;\n            __register_t    mc_es;\n            __register_t    mc_ds;\n            __register_t    mc_edi;\n            __register_t    mc_esi;\n            __register_t    mc_ebp;\n            __register_t    mc_isp;\n            __register_t    mc_ebx;\n            __register_t    mc_edx;\n            __register_t    mc_ecx;\n            __register_t    mc_eax;\n            __register_t    mc_trapno;\n            __register_t    mc_err;\n            __register_t    mc_eip;\n            __register_t    mc_cs;\n            __register_t    mc_eflags;\n            __register_t    mc_esp;\n            __register_t    mc_ss;\n\n            int             mc_len;\n            int             mc_fpformat;\n            int             mc_ownedfp;\n            int[1]          mc_spare1;\n\n            align(16)\n            int[128]        mc_fpstate;\n\n            __register_t    mc_fsbase;\n            __register_t    mc_gsbase;\n\n            int[6]          mc_spare2;\n        }\n    }\n    else version (AArch64)\n    {\n        alias __register_t = long;\n\n        struct gpregs\n        {\n            __register_t[30] gp_x;\n            __register_t     gp_lr;\n            __register_t     gp_sp;\n            __register_t     gp_elr;\n            uint             gp_spsr;\n            int              gp_pad;\n        }\n\n        struct fpregs\n        {\n            ulong[2][32]    fp_q; // __uint128_t\n            uint            fp_sr;\n            uint            fp_cr;\n            int             fp_flags;\n            int             fp_pad;\n        }\n\n        struct mcontext_t\n        {\n            gpregs          mc_gpregs;\n            fpregs          mc_fpregs;\n            int             mc_flags;\n            int             mc_pad;\n            ulong[8]        mc_spare;\n        }\n    }\n\n    // <ucontext.h>\n    enum UCF_SWAPPED = 0x00000001;\n\n    struct ucontext_t\n    {\n        sigset_t        uc_sigmask;\n        mcontext_t      uc_mcontext;\n\n        ucontext_t*     uc_link;\n        stack_t         uc_stack;\n        int             uc_flags;\n        int[4]          __spare__;\n    }\n}\nelse version (NetBSD)\n{\n\n    version (X86_64)\n    {\n      enum { NGREG = 26 };\n      alias __greg_t = ulong;\n      alias __gregset_t = __greg_t[NGREG];\n      alias __fpregset_t = align(8)ubyte[512];\n\n      struct mcontext_t {\n        __gregset_t     __gregs;\n        __greg_t        _mc_tlsbase;\n        __fpregset_t    __fpregs;\n      }\n    }\n    else version (X86)\n    {\n      enum { NGREG = 19 };\n      alias __greg_t = ulong;\n      alias __gregset_t = __greg_t[_NGREG];\n      struct __fpregset_t{\n        union __fp_reg_set{\n                struct __fpchip_state{\n                        int[27]     __fp_state; /* Environment and registers */\n                } ;       /* x87 regs in fsave format */\n                struct __fp_xmm_state{\n                        ubyte[512]    __fp_xmm;\n                } ;       /* x87 and xmm regs in fxsave format */\n                int[128]     __fp_fpregs;\n        };\n        __fpregset_t __fp_reg_set;\n        int[33]     __fp_pad;                   /* Historic padding */\n      };\n\n      struct mcontext_t {\n        __gregset_t     __gregs;\n        __fpregset_t    __fpregs;\n        __greg_t        _mc_tlsbase;\n      }\n    }\n\n    struct ucontext_t\n    {\n        uint    uc_flags;       /* properties */\n        ucontext_t *    uc_link;        /* context to resume */\n        sigset_t        uc_sigmask;     /* signals blocked in this context */\n        stack_t         uc_stack;       /* the stack used by this context */\n        mcontext_t      uc_mcontext;    /* machine state */\n        /+ todo #if defined(_UC_MACHINE_PAD)\n                long            __uc_pad[_UC_MACHINE_PAD];\n        #endif\n        +/\n\n    }\n}\nelse version (DragonFlyBSD)\n{\n    // <machine/ucontext.h>\n    version (X86_64)\n    {\n      alias long __register_t;\n      alias uint __uint32_t;\n      alias ushort __uint16_t;\n\n      struct mcontext_t {\n        __register_t    mc_onstack;\n        __register_t    mc_rdi;\n        __register_t    mc_rsi;\n        __register_t    mc_rdx;\n        __register_t    mc_rcx;\n        __register_t    mc_r8;\n        __register_t    mc_r9;\n        __register_t    mc_rax;\n        __register_t    mc_rbx;\n        __register_t    mc_rbp;\n        __register_t    mc_r10;\n        __register_t    mc_r11;\n        __register_t    mc_r12;\n        __register_t    mc_r13;\n        __register_t    mc_r14;\n        __register_t    mc_r15;\n        __register_t    mc_xflags;\n        __register_t    mc_trapno;\n        __register_t    mc_addr;\n        __register_t    mc_flags;\n        __register_t    mc_err;\n        __register_t    mc_rip;\n        __register_t    mc_cs;\n        __register_t    mc_rflags;\n        __register_t    mc_rsp;\n        __register_t    mc_ss;\n\n        uint            mc_len;\n        uint            mc_fpformat;\n        uint            mc_ownedfp;\n        uint            mc_reserved;\n        uint[8]         mc_unused;\n        int[256]        mc_fpregs;\n      };  // __attribute__((aligned(64)));\n    }\n    else\n    {\n        static assert(0, \"Only X86_64 support on DragonFlyBSD\");\n    }\n\n    // <ucontext.h>\n    enum UCF_SWAPPED = 0x00000001;\n\n    struct ucontext_t\n    {\n        sigset_t        uc_sigmask;\n        mcontext_t      uc_mcontext;\n\n        ucontext_t*     uc_link;\n        stack_t         uc_stack;\n        void            function(ucontext_t *, void *) uc_cofunc;\n        void*           uc_arg;\n        int[4]          __spare__;\n    }\n}\nelse version (Solaris)\n{\n    alias uint[4] upad128_t;\n\n    version (X86_64)\n    {\n        enum _NGREG = 28;\n        alias long greg_t;\n    }\n    else version (X86)\n    {\n        enum _NGREG = 19;\n        alias int greg_t;\n    }\n\n    alias greg_t[_NGREG] gregset_t;\n\n    version (X86_64)\n    {\n        union _u_st\n        {\n            ushort[5]   fpr_16;\n            upad128_t   __fpr_pad;\n        }\n\n        struct fpregset_t\n        {\n            union fp_reg_set\n            {\n                struct fpchip_state\n                {\n                    ushort          cw;\n                    ushort          sw;\n                    ubyte           fctw;\n                    ubyte           __fx_rsvd;\n                    ushort          fop;\n                    ulong           rip;\n                    ulong           rdp;\n                    uint            mxcsr;\n                    uint            mxcsr_mask;\n                    _u_st[8]        st;\n                    upad128_t[16]   xmm;\n                    upad128_t[6]    __fx_ign2;\n                    uint            status;\n                    uint            xstatus;\n                }\n                uint[130]   f_fpregs;\n            }\n        }\n    }\n    else version (X86)\n    {\n        struct fpregset_t\n        {\n            union u_fp_reg_set\n            {\n                struct s_fpchip_state\n                {\n                    uint[27]        state;\n                    uint            status;\n                    uint            mxcsr;\n                    uint            xstatus;\n                    uint[2]         __pad;\n                    upad128_t[8]    xmm;\n                }\n                s_fpchip_state    fpchip_state;\n\n                struct s_fp_emul_space\n                {\n                    ubyte[246]  fp_emul;\n                    ubyte[2]    fp_epad;\n                }\n                s_fp_emul_space   fp_emul_space;\n                uint[95]        f_fpregs;\n            }\n        u_fp_reg_set fp_reg_set;\n        }\n    }\n    struct mcontext_t\n    {\n        gregset_t   gregs;\n        fpregset_t  fpregs;\n    }\n\n    struct ucontext_t\n    {\n        c_ulong      uc_flags;\n        ucontext_t  *uc_link;\n        sigset_t    uc_sigmask;\n        stack_t     uc_stack;\n        mcontext_t  uc_mcontext;\n        c_long[5]   uc_filler;\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    version (X86_64)\n    {\n        enum\n        {\n            REG_R8 = 0,\n            REG_R9,\n            REG_R10,\n            REG_R11,\n            REG_R12,\n            REG_R13,\n            REG_R14,\n            REG_R15,\n            REG_RDI,\n            REG_RSI,\n            REG_RBP,\n            REG_RBX,\n            REG_RDX,\n            REG_RAX,\n            REG_RCX,\n            REG_RSP,\n            REG_RIP,\n            REG_EFL,\n            REG_CSGSFS,     /* Actually short cs, gs, fs, __pad0.  */\n            REG_ERR,\n            REG_TRAPNO,\n            REG_OLDMASK,\n            REG_CR2\n        }\n\n        alias sigcontext mcontext_t;\n\n        struct ucontext_t\n        {\n            c_ulong         uc_flags;\n            ucontext_t*     uc_link;\n            stack_t         uc_stack;\n            mcontext_t      uc_mcontext;\n            sigset_t        uc_sigmask;\n        }\n    }\n    else version (MIPS32)\n    {\n        alias greg_t    = ulong;\n        enum NGREG      = 32;\n        enum NFPREG     = 32;\n        alias gregset_t = greg_t[NGREG];\n\n        struct fpregset_t\n        {\n            union fp_r\n            {\n                double[NFPREG]  fp_dregs;\n                struct _fp_fregs\n                {\n                    float   _fp_fregs;\n                    uint    _fp_pad;\n                }\n                _fp_fregs[NFPREG] fp_fregs;\n            }\n        }\n\n        version (MIPS_O32)\n        {\n            struct mcontext_t\n            {\n                uint regmask;\n                uint status;\n                greg_t pc;\n                gregset_t gregs;\n                fpregset_t fpregs;\n                uint fp_owned;\n                uint fpc_csr;\n                uint fpc_eir;\n                uint used_math;\n                uint dsp;\n                greg_t mdhi;\n                greg_t mdlo;\n                c_ulong hi1;\n                c_ulong lo1;\n                c_ulong hi2;\n                c_ulong lo2;\n                c_ulong hi3;\n                c_ulong lo3;\n            }\n        }\n        else\n        {\n            struct mcontext_t\n            {\n                gregset_t gregs;\n                fpregset_t fpregs;\n                greg_t mdhi;\n                greg_t hi1;\n                greg_t hi2;\n                greg_t hi3;\n                greg_t mdlo;\n                greg_t lo1;\n                greg_t lo2;\n                greg_t lo3;\n                greg_t pc;\n                uint fpc_csr;\n                uint used_math;\n                uint dsp;\n                uint reserved;\n            }\n        }\n\n        struct ucontext_t\n        {\n            c_ulong uc_flags;\n            ucontext_t* uc_link;\n            stack_t uc_stack;\n            mcontext_t uc_mcontext;\n            sigset_t uc_sigmask;\n        }\n    }\n    else version (ARM)\n    {\n        enum\n        {\n            R0 = 0,\n            R1 = 1,\n            R2 = 2,\n            R3 = 3,\n            R4 = 4,\n            R5 = 5,\n            R6 = 6,\n            R7 = 7,\n            R8 = 8,\n            R9 = 9,\n            R10 = 10,\n            R11 = 11,\n            R12 = 12,\n            R13 = 13,\n            R14 = 14,\n            R15 = 15\n        }\n\n        struct sigcontext\n        {\n            c_ulong trap_no;\n            c_ulong error_code;\n            c_ulong oldmask;\n            c_ulong arm_r0;\n            c_ulong arm_r1;\n            c_ulong arm_r2;\n            c_ulong arm_r3;\n            c_ulong arm_r4;\n            c_ulong arm_r5;\n            c_ulong arm_r6;\n            c_ulong arm_r7;\n            c_ulong arm_r8;\n            c_ulong arm_r9;\n            c_ulong arm_r10;\n            c_ulong arm_fp;\n            c_ulong arm_ip;\n            c_ulong arm_sp;\n            c_ulong arm_lr;\n            c_ulong arm_pc;\n            c_ulong arm_cpsr;\n            c_ulong fault_address;\n        }\n\n        alias sigcontext mcontext_t;\n\n        struct ucontext_t\n        {\n            c_ulong uc_flags;\n            ucontext_t* uc_link;\n            stack_t uc_stack;\n            mcontext_t uc_mcontext;\n            sigset_t uc_sigmask;\n            align(8) c_ulong[128] uc_regspace;\n        }\n    }\n    else\n        static assert(0, \"unimplemented\");\n}\n\n//\n// Obsolescent (OB)\n//\n/*\nint  getcontext(ucontext_t*);\nvoid makecontext(ucontext_t*, void function(), int, ...);\nint  setcontext(in ucontext_t*);\nint  swapcontext(ucontext_t*, in ucontext_t*);\n*/\n\nstatic if ( is( ucontext_t ) )\n{\n    int  getcontext(ucontext_t*);\n    void makecontext(ucontext_t*, void function(), int, ...);\n    int  setcontext(in ucontext_t*);\n    int  swapcontext(ucontext_t*, in ucontext_t*);\n}\n\nversion (Solaris)\n{\n    int walkcontext(in ucontext_t*, int function(uintptr_t, int, void*), void*);\n    int addrtosymstr(uintptr_t, char*, int);\n    int printstack(int);\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/unistd.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.unistd;\n\nprivate import core.sys.posix.config;\nprivate import core.stdc.stddef;\npublic import core.sys.posix.inttypes;  // for intptr_t\npublic import core.sys.posix.sys.types; // for ssize_t, uid_t, gid_t, off_t, pid_t, useconds_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\nenum STDIN_FILENO  = 0;\nenum STDOUT_FILENO = 1;\nenum STDERR_FILENO = 2;\n\nextern __gshared char*   optarg;\nextern __gshared int     optind;\nextern __gshared int     opterr;\nextern __gshared int     optopt;\n\nint     access(in char*, int);\nuint    alarm(uint) @trusted;\nint     chdir(in char*);\nint     chown(in char*, uid_t, gid_t);\nint     close(int) @trusted;\nsize_t  confstr(int, char*, size_t);\nint     dup(int) @trusted;\nint     dup2(int, int) @trusted;\nint     execl(in char*, in char*, ...);\nint     execle(in char*, in char*, ...);\nint     execlp(in char*, in char*, ...);\nint     execv(in char*, in char**);\nint     execve(in char*, in char**, in char**);\nint     execvp(in char*, in char**);\nvoid    _exit(int) @trusted;\nint     fchown(int, uid_t, gid_t) @trusted;\npid_t   fork() @trusted;\nc_long  fpathconf(int, int) @trusted;\n//int     ftruncate(int, off_t);\nchar*   getcwd(char*, size_t);\ngid_t   getegid() @trusted;\nuid_t   geteuid() @trusted;\ngid_t   getgid() @trusted;\nint     getgroups(int, gid_t *);\nint     gethostname(char*, size_t);\nchar*   getlogin() @trusted;\nint     getlogin_r(char*, size_t);\nint     getopt(int, in char**, in char*);\npid_t   getpgrp() @trusted;\npid_t   getpid() @trusted;\npid_t   getppid() @trusted;\nuid_t   getuid() @trusted;\nint     isatty(int) @trusted;\nint     link(in char*, in char*);\n//off_t   lseek(int, off_t, int);\nc_long  pathconf(in char*, int);\nint     pause() @trusted;\nint     pipe(ref int[2]) @trusted;\nssize_t read(int, void*, size_t);\nssize_t readlink(in char*, char*, size_t);\nint     rmdir(in char*);\nint     setegid(gid_t) @trusted;\nint     seteuid(uid_t) @trusted;\nint     setgid(gid_t) @trusted;\nint     setgroups(size_t, in gid_t*) @trusted;\nint     setpgid(pid_t, pid_t) @trusted;\npid_t   setsid() @trusted;\nint     setuid(uid_t) @trusted;\nuint    sleep(uint) @trusted;\nint     symlink(in char*, in char*);\nc_long  sysconf(int) @trusted;\npid_t   tcgetpgrp(int) @trusted;\nint     tcsetpgrp(int, pid_t) @trusted;\nchar*   ttyname(int) @trusted;\nint     ttyname_r(int, char*, size_t);\nint     unlink(in char*);\nssize_t write(int, in void*, size_t);\n\nversion (CRuntime_Glibc)\n{\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    off_t lseek64(int, off_t, int) @trusted;\n    alias lseek64 lseek;\n  }\n  else\n  {\n    off_t lseek(int, off_t, int) @trusted;\n  }\n  static if ( __USE_LARGEFILE64 )\n  {\n    int   ftruncate64(int, off_t) @trusted;\n    alias ftruncate64 ftruncate;\n  }\n  else\n  {\n    int   ftruncate(int, off_t) @trusted;\n  }\n}\nelse version (FreeBSD)\n{\n    off_t lseek(int, off_t, int) @trusted;\n    int   ftruncate(int, off_t) @trusted;\n}\nelse version (NetBSD)\n{\n    off_t lseek(int, off_t, int) @trusted;\n    int   ftruncate(int, off_t) @trusted;\n}\nelse version (DragonFlyBSD)\n{\n    off_t lseek(int, off_t, int) @trusted;\n    int   ftruncate(int, off_t) @trusted;\n}\nelse version (Solaris)\n{\n    version (D_LP64)\n    {\n        off_t   lseek(int, off_t, int) @trusted;\n        alias   lseek lseek64;\n\n        int     ftruncate(int, off_t) @trusted;\n        alias   ftruncate ftruncate64;\n    }\n    else\n    {\n        static if ( __USE_LARGEFILE64 )\n        {\n            off64_t lseek64(int, off64_t, int) @trusted;\n            alias   lseek64 lseek;\n\n            int     ftruncate64(int, off64_t) @trusted;\n            alias   ftruncate64 ftruncate;\n        }\n        else\n        {\n            off_t   lseek(int, off_t, int) @trusted;\n            int     ftruncate(int, off_t) @trusted;\n        }\n    }\n}\nelse version (Darwin)\n{\n    off_t lseek(int, off_t, int) @trusted;\n    int   ftruncate(int, off_t) @trusted;\n}\nelse version (CRuntime_Bionic)\n{\n    off_t lseek(int, off_t, int) @trusted;\n    int   ftruncate(int, off_t) @trusted;\n}\nelse version (CRuntime_Musl)\n{\n    int ftruncate(int, off_t) @trusted;\n    off_t lseek(int, off_t, int) @trusted;\n    alias ftruncate ftruncate64;\n    alias lseek lseek64;\n}\nelse version (CRuntime_UClibc)\n{\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    off_t lseek64(int, off_t, int) @trusted;\n    alias lseek64 lseek;\n  }\n  else\n  {\n    off_t lseek(int, off_t, int) @trusted;\n  }\n  static if ( __USE_LARGEFILE64 )\n  {\n    int   ftruncate64(int, off_t) @trusted;\n    alias ftruncate64 ftruncate;\n  }\n  else\n  {\n    int   ftruncate(int, off_t) @trusted;\n  }\n}\n\nversion (CRuntime_Glibc)\n{\n    enum F_OK       = 0;\n    enum R_OK       = 4;\n    enum W_OK       = 2;\n    enum X_OK       = 1;\n\n    enum F_ULOCK    = 0;\n    enum F_LOCK     = 1;\n    enum F_TLOCK    = 2;\n    enum F_TEST     = 3;\n\n    enum\n    {\n        _CS_PATH,\n\n        _CS_V6_WIDTH_RESTRICTED_ENVS,\n\n        _CS_GNU_LIBC_VERSION,\n        _CS_GNU_LIBPTHREAD_VERSION,\n\n        _CS_LFS_CFLAGS = 1000,\n        _CS_LFS_LDFLAGS,\n        _CS_LFS_LIBS,\n        _CS_LFS_LINTFLAGS,\n        _CS_LFS64_CFLAGS,\n        _CS_LFS64_LDFLAGS,\n        _CS_LFS64_LIBS,\n        _CS_LFS64_LINTFLAGS,\n\n        _CS_XBS5_ILP32_OFF32_CFLAGS = 1100,\n        _CS_XBS5_ILP32_OFF32_LDFLAGS,\n        _CS_XBS5_ILP32_OFF32_LIBS,\n        _CS_XBS5_ILP32_OFF32_LINTFLAGS,\n        _CS_XBS5_ILP32_OFFBIG_CFLAGS,\n        _CS_XBS5_ILP32_OFFBIG_LDFLAGS,\n        _CS_XBS5_ILP32_OFFBIG_LIBS,\n        _CS_XBS5_ILP32_OFFBIG_LINTFLAGS,\n        _CS_XBS5_LP64_OFF64_CFLAGS,\n        _CS_XBS5_LP64_OFF64_LDFLAGS,\n        _CS_XBS5_LP64_OFF64_LIBS,\n        _CS_XBS5_LP64_OFF64_LINTFLAGS,\n        _CS_XBS5_LPBIG_OFFBIG_CFLAGS,\n        _CS_XBS5_LPBIG_OFFBIG_LDFLAGS,\n        _CS_XBS5_LPBIG_OFFBIG_LIBS,\n        _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS,\n\n        _CS_POSIX_V6_ILP32_OFF32_CFLAGS,\n        _CS_POSIX_V6_ILP32_OFF32_LDFLAGS,\n        _CS_POSIX_V6_ILP32_OFF32_LIBS,\n        _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS,\n        _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS,\n        _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS,\n        _CS_POSIX_V6_ILP32_OFFBIG_LIBS,\n        _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS,\n        _CS_POSIX_V6_LP64_OFF64_CFLAGS,\n        _CS_POSIX_V6_LP64_OFF64_LDFLAGS,\n        _CS_POSIX_V6_LP64_OFF64_LIBS,\n        _CS_POSIX_V6_LP64_OFF64_LINTFLAGS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LIBS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS\n    }\n\n    enum\n    {\n        _PC_LINK_MAX,\n        _PC_MAX_CANON,\n        _PC_MAX_INPUT,\n        _PC_NAME_MAX,\n        _PC_PATH_MAX,\n        _PC_PIPE_BUF,\n        _PC_CHOWN_RESTRICTED,\n        _PC_NO_TRUNC,\n        _PC_VDISABLE,\n        _PC_SYNC_IO,\n        _PC_ASYNC_IO,\n        _PC_PRIO_IO,\n        _PC_SOCK_MAXBUF,\n        _PC_FILESIZEBITS,\n        _PC_REC_INCR_XFER_SIZE,\n        _PC_REC_MAX_XFER_SIZE,\n        _PC_REC_MIN_XFER_SIZE,\n        _PC_REC_XFER_ALIGN,\n        _PC_ALLOC_SIZE_MIN,\n        _PC_SYMLINK_MAX,\n        _PC_2_SYMLINKS\n    }\n\n    enum\n    {\n        _SC_ARG_MAX,\n        _SC_CHILD_MAX,\n        _SC_CLK_TCK,\n        _SC_NGROUPS_MAX,\n        _SC_OPEN_MAX,\n        _SC_STREAM_MAX,\n        _SC_TZNAME_MAX,\n        _SC_JOB_CONTROL,\n        _SC_SAVED_IDS,\n        _SC_REALTIME_SIGNALS,\n        _SC_PRIORITY_SCHEDULING,\n        _SC_TIMERS,\n        _SC_ASYNCHRONOUS_IO,\n        _SC_PRIORITIZED_IO,\n        _SC_SYNCHRONIZED_IO,\n        _SC_FSYNC,\n        _SC_MAPPED_FILES,\n        _SC_MEMLOCK,\n        _SC_MEMLOCK_RANGE,\n        _SC_MEMORY_PROTECTION,\n        _SC_MESSAGE_PASSING,\n        _SC_SEMAPHORES,\n        _SC_SHARED_MEMORY_OBJECTS,\n        _SC_AIO_LISTIO_MAX,\n        _SC_AIO_MAX,\n        _SC_AIO_PRIO_DELTA_MAX,\n        _SC_DELAYTIMER_MAX,\n        _SC_MQ_OPEN_MAX,\n        _SC_MQ_PRIO_MAX,\n        _SC_VERSION,\n        _SC_PAGESIZE,\n        _SC_PAGE_SIZE = _SC_PAGESIZE,\n        _SC_RTSIG_MAX,\n        _SC_SEM_NSEMS_MAX,\n        _SC_SEM_VALUE_MAX,\n        _SC_SIGQUEUE_MAX,\n        _SC_TIMER_MAX,\n\n        _SC_BC_BASE_MAX,\n        _SC_BC_DIM_MAX,\n        _SC_BC_SCALE_MAX,\n        _SC_BC_STRING_MAX,\n        _SC_COLL_WEIGHTS_MAX,\n        _SC_EQUIV_CLASS_MAX,\n        _SC_EXPR_NEST_MAX,\n        _SC_LINE_MAX,\n        _SC_RE_DUP_MAX,\n        _SC_CHARCLASS_NAME_MAX,\n\n        _SC_2_VERSION,\n        _SC_2_C_BIND,\n        _SC_2_C_DEV,\n        _SC_2_FORT_DEV,\n        _SC_2_FORT_RUN,\n        _SC_2_SW_DEV,\n        _SC_2_LOCALEDEF,\n\n        _SC_PII,\n        _SC_PII_XTI,\n        _SC_PII_SOCKET,\n        _SC_PII_INTERNET,\n        _SC_PII_OSI,\n        _SC_POLL,\n        _SC_SELECT,\n        _SC_UIO_MAXIOV,\n        _SC_IOV_MAX = _SC_UIO_MAXIOV,\n        _SC_PII_INTERNET_STREAM,\n        _SC_PII_INTERNET_DGRAM,\n        _SC_PII_OSI_COTS,\n        _SC_PII_OSI_CLTS,\n        _SC_PII_OSI_M,\n        _SC_T_IOV_MAX,\n\n        _SC_THREADS,\n        _SC_THREAD_SAFE_FUNCTIONS,\n        _SC_GETGR_R_SIZE_MAX,\n        _SC_GETPW_R_SIZE_MAX,\n        _SC_LOGIN_NAME_MAX,\n        _SC_TTY_NAME_MAX,\n        _SC_THREAD_DESTRUCTOR_ITERATIONS,\n        _SC_THREAD_KEYS_MAX,\n        _SC_THREAD_STACK_MIN,\n        _SC_THREAD_THREADS_MAX,\n        _SC_THREAD_ATTR_STACKADDR,\n        _SC_THREAD_ATTR_STACKSIZE,\n        _SC_THREAD_PRIORITY_SCHEDULING,\n        _SC_THREAD_PRIO_INHERIT,\n        _SC_THREAD_PRIO_PROTECT,\n        _SC_THREAD_PROCESS_SHARED,\n\n        _SC_NPROCESSORS_CONF,\n        _SC_NPROCESSORS_ONLN,\n        _SC_PHYS_PAGES,\n        _SC_AVPHYS_PAGES,\n        _SC_ATEXIT_MAX,\n        _SC_PASS_MAX,\n\n        _SC_XOPEN_VERSION,\n        _SC_XOPEN_XCU_VERSION,\n        _SC_XOPEN_UNIX,\n        _SC_XOPEN_CRYPT,\n        _SC_XOPEN_ENH_I18N,\n        _SC_XOPEN_SHM,\n\n        _SC_2_CHAR_TERM,\n        _SC_2_C_VERSION,\n        _SC_2_UPE,\n\n        _SC_XOPEN_XPG2,\n        _SC_XOPEN_XPG3,\n        _SC_XOPEN_XPG4,\n\n        _SC_CHAR_BIT,\n        _SC_CHAR_MAX,\n        _SC_CHAR_MIN,\n        _SC_INT_MAX,\n        _SC_INT_MIN,\n        _SC_LONG_BIT,\n        _SC_WORD_BIT,\n        _SC_MB_LEN_MAX,\n        _SC_NZERO,\n        _SC_SSIZE_MAX,\n        _SC_SCHAR_MAX,\n        _SC_SCHAR_MIN,\n        _SC_SHRT_MAX,\n        _SC_SHRT_MIN,\n        _SC_UCHAR_MAX,\n        _SC_UINT_MAX,\n        _SC_ULONG_MAX,\n        _SC_USHRT_MAX,\n\n        _SC_NL_ARGMAX,\n        _SC_NL_LANGMAX,\n        _SC_NL_MSGMAX,\n        _SC_NL_NMAX,\n        _SC_NL_SETMAX,\n        _SC_NL_TEXTMAX,\n\n        _SC_XBS5_ILP32_OFF32,\n        _SC_XBS5_ILP32_OFFBIG,\n        _SC_XBS5_LP64_OFF64,\n        _SC_XBS5_LPBIG_OFFBIG,\n\n        _SC_XOPEN_LEGACY,\n        _SC_XOPEN_REALTIME,\n        _SC_XOPEN_REALTIME_THREADS,\n\n        _SC_ADVISORY_INFO,\n        _SC_BARRIERS,\n        _SC_BASE,\n        _SC_C_LANG_SUPPORT,\n        _SC_C_LANG_SUPPORT_R,\n        _SC_CLOCK_SELECTION,\n        _SC_CPUTIME,\n        _SC_THREAD_CPUTIME,\n        _SC_DEVICE_IO,\n        _SC_DEVICE_SPECIFIC,\n        _SC_DEVICE_SPECIFIC_R,\n        _SC_FD_MGMT,\n        _SC_FIFO,\n        _SC_PIPE,\n        _SC_FILE_ATTRIBUTES,\n        _SC_FILE_LOCKING,\n        _SC_FILE_SYSTEM,\n        _SC_MONOTONIC_CLOCK,\n        _SC_MULTI_PROCESS,\n        _SC_SINGLE_PROCESS,\n        _SC_NETWORKING,\n        _SC_READER_WRITER_LOCKS,\n        _SC_SPIN_LOCKS,\n        _SC_REGEXP,\n        _SC_REGEX_VERSION,\n        _SC_SHELL,\n        _SC_SIGNALS,\n        _SC_SPAWN,\n        _SC_SPORADIC_SERVER,\n        _SC_THREAD_SPORADIC_SERVER,\n        _SC_SYSTEM_DATABASE,\n        _SC_SYSTEM_DATABASE_R,\n        _SC_TIMEOUTS,\n        _SC_TYPED_MEMORY_OBJECTS,\n        _SC_USER_GROUPS,\n        _SC_USER_GROUPS_R,\n        _SC_2_PBS,\n        _SC_2_PBS_ACCOUNTING,\n        _SC_2_PBS_LOCATE,\n        _SC_2_PBS_MESSAGE,\n        _SC_2_PBS_TRACK,\n        _SC_SYMLOOP_MAX,\n        _SC_STREAMS,\n        _SC_2_PBS_CHECKPOINT,\n\n        _SC_V6_ILP32_OFF32,\n        _SC_V6_ILP32_OFFBIG,\n        _SC_V6_LP64_OFF64,\n        _SC_V6_LPBIG_OFFBIG,\n\n        _SC_HOST_NAME_MAX,\n        _SC_TRACE,\n        _SC_TRACE_EVENT_FILTER,\n        _SC_TRACE_INHERIT,\n        _SC_TRACE_LOG,\n\n        _SC_LEVEL1_ICACHE_SIZE,\n        _SC_LEVEL1_ICACHE_ASSOC,\n        _SC_LEVEL1_ICACHE_LINESIZE,\n        _SC_LEVEL1_DCACHE_SIZE,\n        _SC_LEVEL1_DCACHE_ASSOC,\n        _SC_LEVEL1_DCACHE_LINESIZE,\n        _SC_LEVEL2_CACHE_SIZE,\n        _SC_LEVEL2_CACHE_ASSOC,\n        _SC_LEVEL2_CACHE_LINESIZE,\n        _SC_LEVEL3_CACHE_SIZE,\n        _SC_LEVEL3_CACHE_ASSOC,\n        _SC_LEVEL3_CACHE_LINESIZE,\n        _SC_LEVEL4_CACHE_SIZE,\n        _SC_LEVEL4_CACHE_ASSOC,\n        _SC_LEVEL4_CACHE_LINESIZE,\n\n        _SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50,\n        _SC_RAW_SOCKETS\n    }\n}\nelse version (Darwin)\n{\n    enum F_OK       = 0;\n    enum R_OK       = 4;\n    enum W_OK       = 2;\n    enum X_OK       = 1;\n\n    enum F_ULOCK    = 0;\n    enum F_LOCK     = 1;\n    enum F_TLOCK    = 2;\n    enum F_TEST     = 3;\n\n    enum\n    {\n        _SC_ARG_MAX                      =   1,\n        _SC_CHILD_MAX                    =   2,\n        _SC_CLK_TCK                      =   3,\n        _SC_NGROUPS_MAX                  =   4,\n        _SC_OPEN_MAX                     =   5,\n        _SC_JOB_CONTROL                  =   6,\n        _SC_SAVED_IDS                    =   7,\n        _SC_VERSION                      =   8,\n        _SC_BC_BASE_MAX                  =   9,\n        _SC_BC_DIM_MAX                   =  10,\n        _SC_BC_SCALE_MAX                 =  11,\n        _SC_BC_STRING_MAX                =  12,\n        _SC_COLL_WEIGHTS_MAX             =  13,\n        _SC_EXPR_NEST_MAX                =  14,\n        _SC_LINE_MAX                     =  15,\n        _SC_RE_DUP_MAX                   =  16,\n        _SC_2_VERSION                    =  17,\n        _SC_2_C_BIND                     =  18,\n        _SC_2_C_DEV                      =  19,\n        _SC_2_CHAR_TERM                  =  20,\n        _SC_2_FORT_DEV                   =  21,\n        _SC_2_FORT_RUN                   =  22,\n        _SC_2_LOCALEDEF                  =  23,\n        _SC_2_SW_DEV                     =  24,\n        _SC_2_UPE                        =  25,\n        _SC_STREAM_MAX                   =  26,\n        _SC_TZNAME_MAX                   =  27,\n        _SC_ASYNCHRONOUS_IO              =  28,\n        _SC_PAGESIZE                     =  29,\n        _SC_MEMLOCK                      =  30,\n        _SC_MEMLOCK_RANGE                =  31,\n        _SC_MEMORY_PROTECTION            =  32,\n        _SC_MESSAGE_PASSING              =  33,\n        _SC_PRIORITIZED_IO               =  34,\n        _SC_PRIORITY_SCHEDULING          =  35,\n        _SC_REALTIME_SIGNALS             =  36,\n        _SC_SEMAPHORES                   =  37,\n        _SC_FSYNC                        =  38,\n        _SC_SHARED_MEMORY_OBJECTS        =  39,\n        _SC_SYNCHRONIZED_IO              =  40,\n        _SC_TIMERS                       =  41,\n        _SC_AIO_LISTIO_MAX               =  42,\n        _SC_AIO_MAX                      =  43,\n        _SC_AIO_PRIO_DELTA_MAX           =  44,\n        _SC_DELAYTIMER_MAX               =  45,\n        _SC_MQ_OPEN_MAX                  =  46,\n        _SC_MAPPED_FILES                 =  47,\n        _SC_RTSIG_MAX                    =  48,\n        _SC_SEM_NSEMS_MAX                =  49,\n        _SC_SEM_VALUE_MAX                =  50,\n        _SC_SIGQUEUE_MAX                 =  51,\n        _SC_TIMER_MAX                    =  52,\n        _SC_IOV_MAX                      =  56,\n        _SC_NPROCESSORS_CONF             =  57,\n        _SC_NPROCESSORS_ONLN             =  58,\n        _SC_2_PBS                        =  59,\n        _SC_2_PBS_ACCOUNTING             =  60,\n        _SC_2_PBS_CHECKPOINT             =  61,\n        _SC_2_PBS_LOCATE                 =  62,\n        _SC_2_PBS_MESSAGE                =  63,\n        _SC_2_PBS_TRACK                  =  64,\n        _SC_ADVISORY_INFO                =  65,\n        _SC_BARRIERS                     =  66,\n        _SC_CLOCK_SELECTION              =  67,\n        _SC_CPUTIME                      =  68,\n        _SC_FILE_LOCKING                 =  69,\n        _SC_GETGR_R_SIZE_MAX             =  70,\n        _SC_GETPW_R_SIZE_MAX             =  71,\n        _SC_HOST_NAME_MAX                =  72,\n        _SC_LOGIN_NAME_MAX               =  73,\n        _SC_MONOTONIC_CLOCK              =  74,\n        _SC_MQ_PRIO_MAX                  =  75,\n        _SC_READER_WRITER_LOCKS          =  76,\n        _SC_REGEXP                       =  77,\n        _SC_SHELL                        =  78,\n        _SC_SPAWN                        =  79,\n        _SC_SPIN_LOCKS                   =  80,\n        _SC_SPORADIC_SERVER              =  81,\n        _SC_THREAD_ATTR_STACKADDR        =  82,\n        _SC_THREAD_ATTR_STACKSIZE        =  83,\n        _SC_THREAD_CPUTIME               =  84,\n        _SC_THREAD_DESTRUCTOR_ITERATIONS =  85,\n        _SC_THREAD_KEYS_MAX              =  86,\n        _SC_THREAD_PRIO_INHERIT          =  87,\n        _SC_THREAD_PRIO_PROTECT          =  88,\n        _SC_THREAD_PRIORITY_SCHEDULING   =  89,\n        _SC_THREAD_PROCESS_SHARED        =  90,\n        _SC_THREAD_SAFE_FUNCTIONS        =  91,\n        _SC_THREAD_SPORADIC_SERVER       =  92,\n        _SC_THREAD_STACK_MIN             =  93,\n        _SC_THREAD_THREADS_MAX           =  94,\n        _SC_TIMEOUTS                     =  95,\n        _SC_THREADS                      =  96,\n        _SC_TRACE                        =  97,\n        _SC_TRACE_EVENT_FILTER           =  98,\n        _SC_TRACE_INHERIT                =  99,\n        _SC_TRACE_LOG                    = 100,\n        _SC_TTY_NAME_MAX                 = 101,\n        _SC_TYPED_MEMORY_OBJECTS         = 102,\n        _SC_V6_ILP32_OFF32               = 103,\n        _SC_V6_ILP32_OFFBIG              = 104,\n        _SC_V6_LP64_OFF64                = 105,\n        _SC_V6_LPBIG_OFFBIG              = 106,\n        _SC_ATEXIT_MAX                   = 107,\n        _SC_XOPEN_CRYPT                  = 108,\n        _SC_XOPEN_ENH_I18N               = 109,\n        _SC_XOPEN_LEGACY                 = 110,\n        _SC_XOPEN_REALTIME               = 111,\n        _SC_XOPEN_REALTIME_THREADS       = 112,\n        _SC_XOPEN_SHM                    = 113,\n        _SC_XOPEN_STREAMS                = 114,\n        _SC_XOPEN_UNIX                   = 115,\n        _SC_XOPEN_VERSION                = 116,\n        _SC_IPV6                         = 118,\n        _SC_RAW_SOCKETS                  = 119,\n        _SC_SYMLOOP_MAX                  = 120,\n        _SC_XOPEN_XCU_VERSION            = 121,\n        _SC_XBS5_ILP32_OFF32             = 122,\n        _SC_XBS5_ILP32_OFFBIG            = 123,\n        _SC_XBS5_LP64_OFF64              = 124,\n        _SC_XBS5_LPBIG_OFFBIG            = 125,\n        _SC_SS_REPL_MAX                  = 126,\n        _SC_TRACE_EVENT_NAME_MAX         = 127,\n        _SC_TRACE_NAME_MAX               = 128,\n        _SC_TRACE_SYS_MAX                = 129,\n        _SC_TRACE_USER_EVENT_MAX         = 130,\n        _SC_PASS_MAX                     = 131,\n    }\n\n    enum _SC_PAGE_SIZE = _SC_PAGESIZE;\n\n    enum\n    {\n        _CS_PATH                                =     1,\n        _CS_POSIX_V6_ILP32_OFF32_CFLAGS         =     2,\n        _CS_POSIX_V6_ILP32_OFF32_LDFLAGS        =     3,\n        _CS_POSIX_V6_ILP32_OFF32_LIBS           =     4,\n        _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS        =     5,\n        _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS       =     6,\n        _CS_POSIX_V6_ILP32_OFFBIG_LIBS          =     7,\n        _CS_POSIX_V6_LP64_OFF64_CFLAGS          =     8,\n        _CS_POSIX_V6_LP64_OFF64_LDFLAGS         =     9,\n        _CS_POSIX_V6_LP64_OFF64_LIBS            =    10,\n        _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS        =    11,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS       =    12,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LIBS          =    13,\n        _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS      =    14,\n\n        _CS_XBS5_ILP32_OFF32_CFLAGS             =    20,\n        _CS_XBS5_ILP32_OFF32_LDFLAGS            =    21,\n        _CS_XBS5_ILP32_OFF32_LIBS               =    22,\n        _CS_XBS5_ILP32_OFF32_LINTFLAGS          =    23,\n        _CS_XBS5_ILP32_OFFBIG_CFLAGS            =    24,\n        _CS_XBS5_ILP32_OFFBIG_LDFLAGS           =    25,\n        _CS_XBS5_ILP32_OFFBIG_LIBS              =    26,\n        _CS_XBS5_ILP32_OFFBIG_LINTFLAGS         =    27,\n        _CS_XBS5_LP64_OFF64_CFLAGS              =    28,\n        _CS_XBS5_LP64_OFF64_LDFLAGS             =    29,\n        _CS_XBS5_LP64_OFF64_LIBS                =    30,\n        _CS_XBS5_LP64_OFF64_LINTFLAGS           =    31,\n        _CS_XBS5_LPBIG_OFFBIG_CFLAGS            =    32,\n        _CS_XBS5_LPBIG_OFFBIG_LDFLAGS           =    33,\n        _CS_XBS5_LPBIG_OFFBIG_LIBS              =    34,\n        _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS         =    35,\n\n        _CS_DARWIN_USER_DIR                     = 65536,\n        _CS_DARWIN_USER_TEMP_DIR                = 65537,\n        _CS_DARWIN_USER_CACHE_DIR               = 65538,\n    }\n}\nelse version (FreeBSD)\n{\n    enum F_OK       = 0;\n    enum R_OK       = 0x04;\n    enum W_OK       = 0x02;\n    enum X_OK       = 0x01;\n\n    enum F_ULOCK    = 0;\n    enum F_LOCK     = 1;\n    enum F_TLOCK    = 2;\n    enum F_TEST     = 3;\n\n    enum\n    {\n        _SC_ARG_MAX                        =   1,\n        _SC_CHILD_MAX                      =   2,\n        _SC_CLK_TCK                        =   3,\n        _SC_NGROUPS_MAX                    =   4,\n        _SC_OPEN_MAX                       =   5,\n        _SC_JOB_CONTROL                    =   6,\n        _SC_SAVED_IDS                      =   7,\n        _SC_VERSION                        =   8,\n        _SC_BC_BASE_MAX                    =   9,\n        _SC_BC_DIM_MAX                     =  10,\n        _SC_BC_SCALE_MAX                   =  11,\n        _SC_BC_STRING_MAX                  =  12,\n        _SC_COLL_WEIGHTS_MAX               =  13,\n        _SC_EXPR_NEST_MAX                  =  14,\n        _SC_LINE_MAX                       =  15,\n        _SC_RE_DUP_MAX                     =  16,\n        _SC_2_VERSION                      =  17,\n        _SC_2_C_BIND                       =  18,\n        _SC_2_C_DEV                        =  19,\n        _SC_2_CHAR_TERM                    =  20,\n        _SC_2_FORT_DEV                     =  21,\n        _SC_2_FORT_RUN                     =  22,\n        _SC_2_LOCALEDEF                    =  23,\n        _SC_2_SW_DEV                       =  24,\n        _SC_2_UPE                          =  25,\n        _SC_STREAM_MAX                     =  26,\n        _SC_TZNAME_MAX                     =  27,\n        _SC_ASYNCHRONOUS_IO                =  28,\n        _SC_MAPPED_FILES                   =  29,\n        _SC_MEMLOCK                        =  30,\n        _SC_MEMLOCK_RANGE                  =  31,\n        _SC_MEMORY_PROTECTION              =  32,\n        _SC_MESSAGE_PASSING                =  33,\n        _SC_PRIORITIZED_IO                 =  34,\n        _SC_PRIORITY_SCHEDULING            =  35,\n        _SC_REALTIME_SIGNALS               =  36,\n        _SC_SEMAPHORES                     =  37,\n        _SC_FSYNC                          =  38,\n        _SC_SHARED_MEMORY_OBJECTS          =  39,\n        _SC_SYNCHRONIZED_IO                =  40,\n        _SC_TIMERS                         =  41,\n        _SC_AIO_LISTIO_MAX                 =  42,\n        _SC_AIO_MAX                        =  43,\n        _SC_AIO_PRIO_DELTA_MAX             =  44,\n        _SC_DELAYTIMER_MAX                 =  45,\n        _SC_MQ_OPEN_MAX                    =  46,\n        _SC_PAGESIZE                       =  47,\n        _SC_RTSIG_MAX                      =  48,\n        _SC_SEM_NSEMS_MAX                  =  49,\n        _SC_SEM_VALUE_MAX                  =  50,\n        _SC_SIGQUEUE_MAX                   =  51,\n        _SC_TIMER_MAX                      =  52,\n        _SC_IOV_MAX                        =  56,\n        _SC_NPROCESSORS_CONF               =  57,\n        _SC_NPROCESSORS_ONLN               =  58,\n        _SC_2_PBS                          =  59,\n        _SC_2_PBS_ACCOUNTING               =  60,\n        _SC_2_PBS_CHECKPOINT               =  61,\n        _SC_2_PBS_LOCATE                   =  62,\n        _SC_2_PBS_MESSAGE                  =  63,\n        _SC_2_PBS_TRACK                    =  64,\n        _SC_ADVISORY_INFO                  =  65,\n        _SC_BARRIERS                       =  66,\n        _SC_CLOCK_SELECTION                =  67,\n        _SC_CPUTIME                        =  68,\n        _SC_FILE_LOCKING                   =  69,\n        _SC_GETGR_R_SIZE_MAX               =  70,\n        _SC_GETPW_R_SIZE_MAX               =  71,\n        _SC_HOST_NAME_MAX                  =  72,\n        _SC_LOGIN_NAME_MAX                 =  73,\n        _SC_MONOTONIC_CLOCK                =  74,\n        _SC_MQ_PRIO_MAX                    =  75,\n        _SC_READER_WRITER_LOCKS            =  76,\n        _SC_REGEXP                         =  77,\n        _SC_SHELL                          =  78,\n        _SC_SPAWN                          =  79,\n        _SC_SPIN_LOCKS                     =  80,\n        _SC_SPORADIC_SERVER                =  81,\n        _SC_THREAD_ATTR_STACKADDR          =  82,\n        _SC_THREAD_ATTR_STACKSIZE          =  83,\n        _SC_THREAD_CPUTIME                 =  84,\n        _SC_THREAD_DESTRUCTOR_ITERATIONS   =  85,\n        _SC_THREAD_KEYS_MAX                =  86,\n        _SC_THREAD_PRIO_INHERIT            =  87,\n        _SC_THREAD_PRIO_PROTECT            =  88,\n        _SC_THREAD_PRIORITY_SCHEDULING     =  89,\n        _SC_THREAD_PROCESS_SHARED          =  90,\n        _SC_THREAD_SAFE_FUNCTIONS          =  91,\n        _SC_THREAD_SPORADIC_SERVER         =  92,\n        _SC_THREAD_STACK_MIN               =  93,\n        _SC_THREAD_THREADS_MAX             =  94,\n        _SC_TIMEOUTS                       =  95,\n        _SC_THREADS                        =  96,\n        _SC_TRACE                          =  97,\n        _SC_TRACE_EVENT_FILTER             =  98,\n        _SC_TRACE_INHERIT                  =  99,\n        _SC_TRACE_LOG                      = 100,\n        _SC_TTY_NAME_MAX                   = 101,\n        _SC_TYPED_MEMORY_OBJECTS           = 102,\n        _SC_V6_ILP32_OFF32                 = 103,\n        _SC_V6_ILP32_OFFBIG                = 104,\n        _SC_V6_LP64_OFF64                  = 105,\n        _SC_V6_LPBIG_OFFBIG                = 106,\n        _SC_IPV6                           = 118,\n        _SC_RAW_SOCKETS                    = 119,\n        _SC_SYMLOOP_MAX                    = 120,\n        _SC_ATEXIT_MAX                     = 107,\n        _SC_XOPEN_CRYPT                    = 108,\n        _SC_XOPEN_ENH_I18N                 = 109,\n        _SC_XOPEN_LEGACY                   = 110,\n        _SC_XOPEN_REALTIME                 = 111,\n        _SC_XOPEN_REALTIME_THREADS         = 112,\n        _SC_XOPEN_SHM                      = 113,\n        _SC_XOPEN_STREAMS                  = 114,\n        _SC_XOPEN_UNIX                     = 115,\n        _SC_XOPEN_VERSION                  = 116,\n        _SC_XOPEN_XCU_VERSION              = 117,\n        _SC_CPUSET_SIZE                    = 122,\n        _SC_PHYS_PAGES                     = 121,\n    }\n\n    enum _SC_PAGE_SIZE = _SC_PAGESIZE;\n\n    enum\n    {\n        _CS_PATH                           =   1,\n        _CS_POSIX_V6_ILP32_OFF32_CFLAGS    =   2,\n        _CS_POSIX_V6_ILP32_OFF32_LDFLAGS   =   3,\n        _CS_POSIX_V6_ILP32_OFF32_LIBS      =   4,\n        _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS   =   5,\n        _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS  =   6,\n        _CS_POSIX_V6_ILP32_OFFBIG_LIBS     =   7,\n        _CS_POSIX_V6_LP64_OFF64_CFLAGS     =   8,\n        _CS_POSIX_V6_LP64_OFF64_LDFLAGS    =   9,\n        _CS_POSIX_V6_LP64_OFF64_LIBS       =  10,\n        _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS   =  11,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS  =  12,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LIBS     =  13,\n        _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS =  14,\n    }\n}\nelse version (NetBSD)\n{\n    enum F_OK       = 0;\n    enum R_OK       = 0x04;\n    enum W_OK       = 0x02;\n    enum X_OK       = 0x01;\n\n    enum F_ULOCK    = 0;\n    enum F_LOCK     = 1;\n    enum F_TLOCK    = 2;\n    enum F_TEST     = 3;\n\n    enum\n    {\n        _SC_ARG_MAX                        =   1,\n        _SC_CHILD_MAX                      =   2,\n        _O_SC_CLK_TCK                      =   3,\n        _SC_NGROUPS_MAX                    =   4,\n        _SC_OPEN_MAX                       =   5,\n        _SC_JOB_CONTROL                    =   6,\n        _SC_SAVED_IDS                      =   7,\n        _SC_VERSION                        =   8,\n        _SC_BC_BASE_MAX                    =   9,\n        _SC_BC_DIM_MAX                     =  10,\n        _SC_BC_SCALE_MAX                   =  11,\n        _SC_BC_STRING_MAX                  =  12,\n        _SC_COLL_WEIGHTS_MAX               =  13,\n        _SC_EXPR_NEST_MAX                  =  14,\n        _SC_LINE_MAX                       =  15,\n        _SC_RE_DUP_MAX                     =  16,\n        _SC_2_VERSION                      =  17,\n        _SC_2_C_BIND                       =  18,\n        _SC_2_C_DEV                        =  19,\n        _SC_2_CHAR_TERM                    =  20,\n        _SC_2_FORT_DEV                     =  21,\n        _SC_2_FORT_RUN                     =  22,\n        _SC_2_LOCALEDEF                    =  23,\n        _SC_2_SW_DEV                       =  24,\n        _SC_2_UPE                          =  25,\n        _SC_STREAM_MAX                     =  26,\n        _SC_TZNAME_MAX                     =  27,\n        _SC_PAGESIZE                       =  28,\n        _SC_FSYNC                          =  29,\n        _SC_XOPEN_SHM                      =  30,\n        _SC_SYNCHRONIZED_IO                =  31,\n        _SC_IOV_MAX                        =  32,\n        _SC_MAPPED_FILES                   =  33,\n        _SC_MEMLOCK                        =  34,\n        _SC_MEMLOCK_RANGE                  =  35,\n        _SC_MEMORY_PROTECTION              =  36,\n        _SC_LOGIN_NAME_MAX                 =  37,\n        _SC_MONOTONIC_CLOCK                =  38,\n        _SC_CLK_TCK                        =  39,\n        _SC_ATEXIT_MAX                     =  40,\n        _SC_THREADS                        =  41,\n        _SC_SEMAPHORES                     =  42,\n        _SC_BARRIERS                       =  43,\n        _SC_TIMERS                         =  44,\n        _SC_SPIN_LOCKS                     =  45,\n        _SC_READER_WRITER_LOCKS            =  46,\n        _SC_GETGR_R_SIZE_MAX               =  47,\n        _SC_GETPW_R_SIZE_MAX               =  48,\n        _SC_CLOCK_SELECTION                =  49,\n        _SC_ASYNCHRONOUS_IO                =  50,\n        _SC_AIO_LISTIO_MAX                 =  51,\n        _SC_AIO_MAX                        =  52,\n        _SC_MESSAGE_PASSING     = 53,\n        _SC_MQ_OPEN_MAX         = 54,\n        _SC_MQ_PRIO_MAX         = 55,\n        _SC_PRIORITY_SCHEDULING = 56,\n        _SC_THREAD_DESTRUCTOR_ITERATIONS = 57,\n        _SC_THREAD_KEYS_MAX             = 58,\n        _SC_THREAD_STACK_MIN            = 59,\n        _SC_THREAD_THREADS_MAX          = 60,\n        _SC_THREAD_ATTR_STACKADDR       = 61,\n        _SC_THREAD_ATTR_STACKSIZE       = 62,\n        _SC_THREAD_PRIORITY_SCHEDULING  = 63,\n        _SC_THREAD_PRIO_INHERIT         = 64,\n        _SC_THREAD_PRIO_PROTECT         = 65,\n        _SC_THREAD_PROCESS_SHARED       = 66,\n        _SC_THREAD_SAFE_FUNCTIONS       = 67,\n        _SC_TTY_NAME_MAX                = 68,\n        _SC_HOST_NAME_MAX               = 69,\n        _SC_PASS_MAX                    = 70,\n        _SC_REGEXP                      = 71,\n        _SC_SHELL                       = 72,\n        _SC_SYMLOOP_MAX                 = 73,\n\n        /* Actually, they are not supported or implemented yet */\n        _SC_V6_ILP32_OFF32              = 74,\n        _SC_V6_ILP32_OFFBIG             = 75,\n        _SC_V6_LP64_OFF64               = 76,\n        _SC_V6_LPBIG_OFFBIG             = 77,\n        _SC_2_PBS                       = 80,\n        _SC_2_PBS_ACCOUNTING            = 81,\n        _SC_2_PBS_CHECKPOINT            = 82,\n        _SC_2_PBS_LOCATE                = 83,\n        _SC_2_PBS_MESSAGE               = 84,\n        _SC_2_PBS_TRACK                 = 85,\n\n        /* These are implemented */\n        _SC_SPAWN                       = 86,\n        _SC_SHARED_MEMORY_OBJECTS       = 87,\n\n        /* Extensions found in Solaris and Linux. */\n        _SC_PHYS_PAGES          = 121,\n\n        /* Commonly provided sysconf() extensions */\n        _SC_NPROCESSORS_CONF    = 1001,\n        _SC_NPROCESSORS_ONLN    = 1002,\n        /* Native variables */\n        _SC_SCHED_RT_TS         = 2001,\n        _SC_SCHED_PRI_MIN       = 2002,\n        _SC_SCHED_PRI_MAX       = 2003\n\n    }\n\n    enum _SC_PAGE_SIZE = _SC_PAGESIZE;\n\n    enum\n    {\n        _CS_PATH                           =   1,\n        _CS_POSIX_V6_ILP32_OFF32_CFLAGS    =   2,\n        _CS_POSIX_V6_ILP32_OFF32_LDFLAGS   =   3,\n        _CS_POSIX_V6_ILP32_OFF32_LIBS      =   4,\n        _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS   =   5,\n        _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS  =   6,\n        _CS_POSIX_V6_ILP32_OFFBIG_LIBS     =   7,\n        _CS_POSIX_V6_LP64_OFF64_CFLAGS     =   8,\n        _CS_POSIX_V6_LP64_OFF64_LDFLAGS    =   9,\n        _CS_POSIX_V6_LP64_OFF64_LIBS       =  10,\n        _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS   =  11,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS  =  12,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LIBS     =  13,\n        _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS =  14,\n    }\n}\nelse version (DragonFlyBSD)\n{\n    enum F_OK       = 0;\n    enum R_OK       = 0x04;\n    enum W_OK       = 0x02;\n    enum X_OK       = 0x01;\n\n    enum F_ULOCK    = 0;\n    enum F_LOCK     = 1;\n    enum F_TLOCK    = 2;\n    enum F_TEST     = 3;\n\n    enum\n    {\n        _SC_ARG_MAX                        =   1,\n        _SC_CHILD_MAX                      =   2,\n        _SC_CLK_TCK                        =   3,\n        _SC_NGROUPS_MAX                    =   4,\n        _SC_OPEN_MAX                       =   5,\n        _SC_JOB_CONTROL                    =   6,\n        _SC_SAVED_IDS                      =   7,\n        _SC_VERSION                        =   8,\n        _SC_BC_BASE_MAX                    =   9,\n        _SC_BC_DIM_MAX                     =  10,\n        _SC_BC_SCALE_MAX                   =  11,\n        _SC_BC_STRING_MAX                  =  12,\n        _SC_COLL_WEIGHTS_MAX               =  13,\n        _SC_EXPR_NEST_MAX                  =  14,\n        _SC_LINE_MAX                       =  15,\n        _SC_RE_DUP_MAX                     =  16,\n        _SC_2_VERSION                      =  17,\n        _SC_2_C_BIND                       =  18,\n        _SC_2_C_DEV                        =  19,\n        _SC_2_CHAR_TERM                    =  20,\n        _SC_2_FORT_DEV                     =  21,\n        _SC_2_FORT_RUN                     =  22,\n        _SC_2_LOCALEDEF                    =  23,\n        _SC_2_SW_DEV                       =  24,\n        _SC_2_UPE                          =  25,\n        _SC_STREAM_MAX                     =  26,\n        _SC_TZNAME_MAX                     =  27,\n        _SC_ASYNCHRONOUS_IO                =  28,\n        _SC_MAPPED_FILES                   =  29,\n        _SC_MEMLOCK                        =  30,\n        _SC_MEMLOCK_RANGE                  =  31,\n        _SC_MEMORY_PROTECTION              =  32,\n        _SC_MESSAGE_PASSING                =  33,\n        _SC_PRIORITIZED_IO                 =  34,\n        _SC_PRIORITY_SCHEDULING            =  35,\n        _SC_REALTIME_SIGNALS               =  36,\n        _SC_SEMAPHORES                     =  37,\n        _SC_FSYNC                          =  38,\n        _SC_SHARED_MEMORY_OBJECTS          =  39,\n        _SC_SYNCHRONIZED_IO                =  40,\n        _SC_TIMERS                         =  41,\n        _SC_AIO_LISTIO_MAX                 =  42,\n        _SC_AIO_MAX                        =  43,\n        _SC_AIO_PRIO_DELTA_MAX             =  44,\n        _SC_DELAYTIMER_MAX                 =  45,\n        _SC_MQ_OPEN_MAX                    =  46,\n        _SC_PAGESIZE                       =  47,\n        _SC_RTSIG_MAX                      =  48,\n        _SC_SEM_NSEMS_MAX                  =  49,\n        _SC_SEM_VALUE_MAX                  =  50,\n        _SC_SIGQUEUE_MAX                   =  51,\n        _SC_TIMER_MAX                      =  52,\n        _SC_IOV_MAX                        =  56,\n        _SC_NPROCESSORS_CONF               =  57,\n        _SC_NPROCESSORS_ONLN               =  58,\n        _SC_2_PBS                          =  59,\n        _SC_2_PBS_ACCOUNTING               =  60,\n        _SC_2_PBS_CHECKPOINT               =  61,\n        _SC_2_PBS_LOCATE                   =  62,\n        _SC_2_PBS_MESSAGE                  =  63,\n        _SC_2_PBS_TRACK                    =  64,\n        _SC_ADVISORY_INFO                  =  65,\n        _SC_BARRIERS                       =  66,\n        _SC_CLOCK_SELECTION                =  67,\n        _SC_CPUTIME                        =  68,\n        _SC_FILE_LOCKING                   =  69,\n        _SC_GETGR_R_SIZE_MAX               =  70,\n        _SC_GETPW_R_SIZE_MAX               =  71,\n        _SC_HOST_NAME_MAX                  =  72,\n        _SC_LOGIN_NAME_MAX                 =  73,\n        _SC_MONOTONIC_CLOCK                =  74,\n        _SC_MQ_PRIO_MAX                    =  75,\n        _SC_READER_WRITER_LOCKS            =  76,\n        _SC_REGEXP                         =  77,\n        _SC_SHELL                          =  78,\n        _SC_SPAWN                          =  79,\n        _SC_SPIN_LOCKS                     =  80,\n        _SC_SPORADIC_SERVER                =  81,\n        _SC_THREAD_ATTR_STACKADDR          =  82,\n        _SC_THREAD_ATTR_STACKSIZE          =  83,\n        _SC_THREAD_CPUTIME                 =  84,\n        _SC_THREAD_DESTRUCTOR_ITERATIONS   =  85,\n        _SC_THREAD_KEYS_MAX                =  86,\n        _SC_THREAD_PRIO_INHERIT            =  87,\n        _SC_THREAD_PRIO_PROTECT            =  88,\n        _SC_THREAD_PRIORITY_SCHEDULING     =  89,\n        _SC_THREAD_PROCESS_SHARED          =  90,\n        _SC_THREAD_SAFE_FUNCTIONS          =  91,\n        _SC_THREAD_SPORADIC_SERVER         =  92,\n        _SC_THREAD_STACK_MIN               =  93,\n        _SC_THREAD_THREADS_MAX             =  94,\n        _SC_TIMEOUTS                       =  95,\n        _SC_THREADS                        =  96,\n        _SC_TRACE                          =  97,\n        _SC_TRACE_EVENT_FILTER             =  98,\n        _SC_TRACE_INHERIT                  =  99,\n        _SC_TRACE_LOG                      = 100,\n        _SC_TTY_NAME_MAX                   = 101,\n        _SC_TYPED_MEMORY_OBJECTS           = 102,\n        _SC_V6_ILP32_OFF32                 = 103,\n        _SC_V6_ILP32_OFFBIG                = 104,\n        _SC_V6_LP64_OFF64                  = 105,\n        _SC_V6_LPBIG_OFFBIG                = 106,\n        _SC_IPV6                           = 118,\n        _SC_RAW_SOCKETS                    = 119,\n        _SC_SYMLOOP_MAX                    = 120,\n        _SC_ATEXIT_MAX                     = 107,\n        _SC_XOPEN_CRYPT                    = 108,\n        _SC_XOPEN_ENH_I18N                 = 109,\n        _SC_XOPEN_LEGACY                   = 110,\n        _SC_XOPEN_REALTIME                 = 111,\n        _SC_XOPEN_REALTIME_THREADS         = 112,\n        _SC_XOPEN_SHM                      = 113,\n        _SC_XOPEN_STREAMS                  = 114,\n        _SC_XOPEN_UNIX                     = 115,\n        _SC_XOPEN_VERSION                  = 116,\n        _SC_XOPEN_XCU_VERSION              = 117,\n        _SC_CPUSET_SIZE                    = 122,\n        _SC_PHYS_PAGES                     = 121,\n    }\n\n    enum _SC_PAGE_SIZE = _SC_PAGESIZE;\n\n    enum\n    {\n        _CS_PATH                           =   1,\n        _CS_POSIX_V6_ILP32_OFF32_CFLAGS    =   2,\n        _CS_POSIX_V6_ILP32_OFF32_LDFLAGS   =   3,\n        _CS_POSIX_V6_ILP32_OFF32_LIBS      =   4,\n        _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS   =   5,\n        _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS  =   6,\n        _CS_POSIX_V6_ILP32_OFFBIG_LIBS     =   7,\n        _CS_POSIX_V6_LP64_OFF64_CFLAGS     =   8,\n        _CS_POSIX_V6_LP64_OFF64_LDFLAGS    =   9,\n        _CS_POSIX_V6_LP64_OFF64_LIBS       =  10,\n        _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS   =  11,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS  =  12,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LIBS     =  13,\n        _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS =  14,\n    }\n}\nelse version (CRuntime_Bionic)\n{\n    enum F_OK       = 0;\n    enum R_OK       = 4;\n    enum W_OK       = 2;\n    enum X_OK       = 1;\n\n    enum _SC_PAGESIZE         = 0x0027;\n    enum _SC_NPROCESSORS_ONLN = 0x0061;\n    enum _SC_THREAD_STACK_MIN = 0x004c;\n}\nelse version (Solaris)\n{\n    enum F_OK       = 0;\n    enum R_OK       = 4;\n    enum W_OK       = 2;\n    enum X_OK       = 1;\n\n    enum F_ULOCK    = 0;\n    enum F_LOCK     = 1;\n    enum F_TLOCK    = 2;\n    enum F_TEST     = 3;\n\n    enum\n    {\n        // large file compilation environment configuration\n        _CS_LFS_CFLAGS                  = 68,\n        _CS_LFS_LDFLAGS                 = 69,\n        _CS_LFS_LIBS                    = 70,\n        _CS_LFS_LINTFLAGS               = 71,\n        // transitional large file interface configuration\n        _CS_LFS64_CFLAGS                = 72,\n        _CS_LFS64_LDFLAGS               = 73,\n        _CS_LFS64_LIBS                  = 74,\n        _CS_LFS64_LINTFLAGS             = 75,\n\n        // UNIX 98\n        _CS_XBS5_ILP32_OFF32_CFLAGS     = 700,\n        _CS_XBS5_ILP32_OFF32_LDFLAGS    = 701,\n        _CS_XBS5_ILP32_OFF32_LIBS       = 702,\n        _CS_XBS5_ILP32_OFF32_LINTFLAGS  = 703,\n        _CS_XBS5_ILP32_OFFBIG_CFLAGS    = 705,\n        _CS_XBS5_ILP32_OFFBIG_LDFLAGS   = 706,\n        _CS_XBS5_ILP32_OFFBIG_LIBS      = 707,\n        _CS_XBS5_ILP32_OFFBIG_LINTFLAGS = 708,\n        _CS_XBS5_LP64_OFF64_CFLAGS      = 709,\n        _CS_XBS5_LP64_OFF64_LDFLAGS     = 710,\n        _CS_XBS5_LP64_OFF64_LIBS        = 711,\n        _CS_XBS5_LP64_OFF64_LINTFLAGS   = 712,\n        _CS_XBS5_LPBIG_OFFBIG_CFLAGS    = 713,\n        _CS_XBS5_LPBIG_OFFBIG_LDFLAGS   = 714,\n        _CS_XBS5_LPBIG_OFFBIG_LIBS      = 715,\n        _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS = 716,\n\n        // UNIX 03\n        _CS_POSIX_V6_ILP32_OFF32_CFLAGS         = 800,\n        _CS_POSIX_V6_ILP32_OFF32_LDFLAGS        = 801,\n        _CS_POSIX_V6_ILP32_OFF32_LIBS           = 802,\n        _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS      = 803,\n        _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS        = 804,\n        _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS       = 805,\n        _CS_POSIX_V6_ILP32_OFFBIG_LIBS          = 806,\n        _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS     = 807,\n        _CS_POSIX_V6_LP64_OFF64_CFLAGS          = 808,\n        _CS_POSIX_V6_LP64_OFF64_LDFLAGS         = 809,\n        _CS_POSIX_V6_LP64_OFF64_LIBS            = 810,\n        _CS_POSIX_V6_LP64_OFF64_LINTFLAGS       = 811,\n        _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS        = 812,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS       = 813,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LIBS          = 814,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS     = 815,\n        _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS      = 816\n    }\n\n    enum {\n        _SC_ARG_MAX                     = 1,\n        _SC_CHILD_MAX                   = 2,\n        _SC_CLK_TCK                     = 3,\n        _SC_NGROUPS_MAX                 = 4,\n        _SC_OPEN_MAX                    = 5,\n        _SC_JOB_CONTROL                 = 6,\n        _SC_SAVED_IDS                   = 7,\n        _SC_VERSION                     = 8,\n\n        _SC_PASS_MAX                    = 9,\n        _SC_LOGNAME_MAX                 = 10,\n        _SC_PAGESIZE                    = 11,\n        _SC_XOPEN_VERSION               = 12,\n        // 13 reserved for SVr4-ES/MP _SC_NACLS_MAX\n        _SC_NPROCESSORS_CONF            = 14,\n        _SC_NPROCESSORS_ONLN            = 15,\n        _SC_STREAM_MAX                  = 16,\n        _SC_TZNAME_MAX                  = 17,\n\n        _SC_AIO_LISTIO_MAX              = 18,\n        _SC_AIO_MAX                     = 19,\n        _SC_AIO_PRIO_DELTA_MAX          = 20,\n        _SC_ASYNCHRONOUS_IO             = 21,\n        _SC_DELAYTIMER_MAX              = 22,\n        _SC_FSYNC                       = 23,\n        _SC_MAPPED_FILES                = 24,\n        _SC_MEMLOCK                     = 25,\n        _SC_MEMLOCK_RANGE               = 26,\n        _SC_MEMORY_PROTECTION           = 27,\n        _SC_MESSAGE_PASSING             = 28,\n        _SC_MQ_OPEN_MAX                 = 29,\n        _SC_MQ_PRIO_MAX                 = 30,\n        _SC_PRIORITIZED_IO              = 31,\n        _SC_PRIORITY_SCHEDULING         = 32,\n        _SC_REALTIME_SIGNALS            = 33,\n        _SC_RTSIG_MAX                   = 34,\n        _SC_SEMAPHORES                  = 35,\n        _SC_SEM_NSEMS_MAX               = 36,\n        _SC_SEM_VALUE_MAX               = 37,\n        _SC_SHARED_MEMORY_OBJECTS       = 38,\n        _SC_SIGQUEUE_MAX                = 39,\n        _SC_SIGRT_MIN                   = 40,\n        _SC_SIGRT_MAX                   = 41,\n        _SC_SYNCHRONIZED_IO             = 42,\n        _SC_TIMERS                      = 43,\n        _SC_TIMER_MAX                   = 44,\n\n        _SC_2_C_BIND                    = 45,\n        _SC_2_C_DEV                     = 46,\n        _SC_2_C_VERSION                 = 47,\n        _SC_2_FORT_DEV                  = 48,\n        _SC_2_FORT_RUN                  = 49,\n        _SC_2_LOCALEDEF                 = 50,\n        _SC_2_SW_DEV                    = 51,\n        _SC_2_UPE                       = 52,\n        _SC_2_VERSION                   = 53,\n        _SC_BC_BASE_MAX                 = 54,\n        _SC_BC_DIM_MAX                  = 55,\n        _SC_BC_SCALE_MAX                = 56,\n        _SC_BC_STRING_MAX               = 57,\n        _SC_COLL_WEIGHTS_MAX            = 58,\n        _SC_EXPR_NEST_MAX               = 59,\n        _SC_LINE_MAX                    = 60,\n        _SC_RE_DUP_MAX                  = 61,\n        _SC_XOPEN_CRYPT                 = 62,\n        _SC_XOPEN_ENH_I18N              = 63,\n        _SC_XOPEN_SHM                   = 64,\n        _SC_2_CHAR_TERM                 = 66,\n        _SC_XOPEN_XCU_VERSION           = 67,\n\n        _SC_ATEXIT_MAX                  = 76,\n        _SC_IOV_MAX                     = 77,\n        _SC_XOPEN_UNIX                  = 78,\n\n        _SC_T_IOV_MAX                   = 79,\n\n        _SC_PHYS_PAGES                  = 500,\n        _SC_AVPHYS_PAGES                = 501,\n\n        _SC_COHER_BLKSZ         = 503,\n        _SC_SPLIT_CACHE         = 504,\n        _SC_ICACHE_SZ           = 505,\n        _SC_DCACHE_SZ           = 506,\n        _SC_ICACHE_LINESZ       = 507,\n        _SC_DCACHE_LINESZ       = 508,\n        _SC_ICACHE_BLKSZ        = 509,\n        _SC_DCACHE_BLKSZ        = 510,\n        _SC_DCACHE_TBLKSZ       = 511,\n        _SC_ICACHE_ASSOC        = 512,\n        _SC_DCACHE_ASSOC        = 513,\n\n        _SC_MAXPID              = 514,\n        _SC_STACK_PROT          = 515,\n        _SC_NPROCESSORS_MAX     = 516,\n        _SC_CPUID_MAX           = 517,\n        _SC_EPHID_MAX           = 518,\n\n        _SC_THREAD_DESTRUCTOR_ITERATIONS = 568,\n        _SC_GETGR_R_SIZE_MAX            = 569,\n        _SC_GETPW_R_SIZE_MAX            = 570,\n        _SC_LOGIN_NAME_MAX              = 571,\n        _SC_THREAD_KEYS_MAX             = 572,\n        _SC_THREAD_STACK_MIN            = 573,\n        _SC_THREAD_THREADS_MAX          = 574,\n        _SC_TTY_NAME_MAX                = 575,\n        _SC_THREADS                     = 576,\n        _SC_THREAD_ATTR_STACKADDR       = 577,\n        _SC_THREAD_ATTR_STACKSIZE       = 578,\n        _SC_THREAD_PRIORITY_SCHEDULING  = 579,\n        _SC_THREAD_PRIO_INHERIT         = 580,\n        _SC_THREAD_PRIO_PROTECT         = 581,\n        _SC_THREAD_PROCESS_SHARED       = 582,\n        _SC_THREAD_SAFE_FUNCTIONS       = 583,\n\n        _SC_XOPEN_LEGACY                = 717,\n        _SC_XOPEN_REALTIME              = 718,\n        _SC_XOPEN_REALTIME_THREADS      = 719,\n        _SC_XBS5_ILP32_OFF32            = 720,\n        _SC_XBS5_ILP32_OFFBIG           = 721,\n        _SC_XBS5_LP64_OFF64             = 722,\n        _SC_XBS5_LPBIG_OFFBIG           = 723,\n\n        _SC_2_PBS                       = 724,\n        _SC_2_PBS_ACCOUNTING            = 725,\n        _SC_2_PBS_CHECKPOINT            = 726,\n        _SC_2_PBS_LOCATE                = 728,\n        _SC_2_PBS_MESSAGE               = 729,\n        _SC_2_PBS_TRACK                 = 730,\n        _SC_ADVISORY_INFO               = 731,\n        _SC_BARRIERS                    = 732,\n        _SC_CLOCK_SELECTION             = 733,\n        _SC_CPUTIME                     = 734,\n        _SC_HOST_NAME_MAX               = 735,\n        _SC_MONOTONIC_CLOCK             = 736,\n        _SC_READER_WRITER_LOCKS         = 737,\n        _SC_REGEXP                      = 738,\n        _SC_SHELL                       = 739,\n        _SC_SPAWN                       = 740,\n        _SC_SPIN_LOCKS                  = 741,\n        _SC_SPORADIC_SERVER             = 742,\n        _SC_SS_REPL_MAX                 = 743,\n        _SC_SYMLOOP_MAX                 = 744,\n        _SC_THREAD_CPUTIME              = 745,\n        _SC_THREAD_SPORADIC_SERVER      = 746,\n        _SC_TIMEOUTS                    = 747,\n        _SC_TRACE                       = 748,\n        _SC_TRACE_EVENT_FILTER          = 749,\n        _SC_TRACE_EVENT_NAME_MAX        = 750,\n        _SC_TRACE_INHERIT               = 751,\n        _SC_TRACE_LOG                   = 752,\n        _SC_TRACE_NAME_MAX              = 753,\n        _SC_TRACE_SYS_MAX               = 754,\n        _SC_TRACE_USER_EVENT_MAX        = 755,\n        _SC_TYPED_MEMORY_OBJECTS        = 756,\n        _SC_V6_ILP32_OFF32              = 757,\n        _SC_V6_ILP32_OFFBIG             = 758,\n        _SC_V6_LP64_OFF64               = 759,\n        _SC_V6_LPBIG_OFFBIG             = 760,\n        _SC_XOPEN_STREAMS               = 761,\n        _SC_IPV6                        = 762,\n        _SC_RAW_SOCKETS                 = 763,\n    }\n    enum _SC_PAGE_SIZE = _SC_PAGESIZE;\n\n    enum {\n        _PC_LINK_MAX            = 1,\n        _PC_MAX_CANON           = 2,\n        _PC_MAX_INPUT           = 3,\n        _PC_NAME_MAX            = 4,\n        _PC_PATH_MAX            = 5,\n        _PC_PIPE_BUF            = 6,\n        _PC_NO_TRUNC            = 7,\n        _PC_VDISABLE            = 8,\n        _PC_CHOWN_RESTRICTED    = 9,\n\n        _PC_ASYNC_IO            = 10,\n        _PC_PRIO_IO             = 11,\n        _PC_SYNC_IO             = 12,\n\n        _PC_ALLOC_SIZE_MIN      = 13,\n        _PC_REC_INCR_XFER_SIZE  = 14,\n        _PC_REC_MAX_XFER_SIZE   = 15,\n        _PC_REC_MIN_XFER_SIZE   = 16,\n        _PC_REC_XFER_ALIGN      = 17,\n        _PC_SYMLINK_MAX         = 18,\n        _PC_2_SYMLINKS          = 19,\n        _PC_ACL_ENABLED         = 20,\n        _PC_MIN_HOLE_SIZE       = 21,\n        _PC_CASE_BEHAVIOR       = 22,\n        _PC_SATTR_ENABLED       = 23,\n        _PC_SATTR_EXISTS        = 24,\n        _PC_ACCESS_FILTERING    = 25,\n\n        _PC_TIMESTAMP_RESOLUTION = 26,\n\n        _PC_FILESIZEBITS        = 67,\n\n        _PC_XATTR_ENABLED       = 100,\n        _PC_XATTR_EXISTS        = 101\n    }\n\n    enum _PC_LAST = 101;\n}\nelse version (CRuntime_Musl)\n{\n    enum F_OK       = 0;\n    enum R_OK       = 4;\n    enum W_OK       = 2;\n    enum X_OK       = 1;\n\n    enum F_ULOCK    = 0;\n    enum F_LOCK     = 1;\n    enum F_TLOCK    = 2;\n    enum F_TEST     = 3;\n\n    enum\n    {\n        _CS_PATH,\n        _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS,\n        _CS_GNU_LIBC_VERSION,\n        _CS_GNU_LIBPTHREAD_VERSION,\n        _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS,\n        _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS,\n\n        _CS_POSIX_V6_ILP32_OFF32_CFLAGS = 1116,\n        _CS_POSIX_V6_ILP32_OFF32_LDFLAGS,\n        _CS_POSIX_V6_ILP32_OFF32_LIBS,\n        _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS,\n        _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS,\n        _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS,\n        _CS_POSIX_V6_ILP32_OFFBIG_LIBS,\n        _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS,\n        _CS_POSIX_V6_LP64_OFF64_CFLAGS,\n        _CS_POSIX_V6_LP64_OFF64_LDFLAGS,\n        _CS_POSIX_V6_LP64_OFF64_LIBS,\n        _CS_POSIX_V6_LP64_OFF64_LINTFLAGS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LIBS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS,\n        _CS_POSIX_V7_ILP32_OFF32_CFLAGS,\n        _CS_POSIX_V7_ILP32_OFF32_LDFLAGS,\n        _CS_POSIX_V7_ILP32_OFF32_LIBS,\n        _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS,\n        _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS,\n        _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS,\n        _CS_POSIX_V7_ILP32_OFFBIG_LIBS,\n        _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS,\n        _CS_POSIX_V7_LP64_OFF64_CFLAGS,\n        _CS_POSIX_V7_LP64_OFF64_LDFLAGS,\n        _CS_POSIX_V7_LP64_OFF64_LIBS,\n        _CS_POSIX_V7_LP64_OFF64_LINTFLAGS,\n        _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS,\n        _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS,\n        _CS_POSIX_V7_LPBIG_OFFBIG_LIBS,\n        _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS,\n        _CS_V6_ENV,\n        _CS_V7_ENV\n    }\n\n    enum\n    {\n        _PC_LINK_MAX,\n        _PC_MAX_CANON,\n        _PC_MAX_INPUT,\n        _PC_NAME_MAX,\n        _PC_PATH_MAX,\n        _PC_PIPE_BUF,\n        _PC_CHOWN_RESTRICTED,\n        _PC_NO_TRUNC,\n        _PC_VDISABLE,\n        _PC_SYNC_IO,\n        _PC_ASYNC_IO,\n        _PC_PRIO_IO,\n        _PC_SOCK_MAXBUF,\n        _PC_FILESIZEBITS,\n        _PC_REC_INCR_XFER_SIZE,\n        _PC_REC_MAX_XFER_SIZE,\n        _PC_REC_MIN_XFER_SIZE,\n        _PC_REC_XFER_ALIGN,\n        _PC_ALLOC_SIZE_MIN,\n        _PC_SYMLINK_MAX,\n        _PC_2_SYMLINKS\n    }\n\n    enum\n    {\n        _SC_ARG_MAX,\n        _SC_CHILD_MAX,\n        _SC_CLK_TCK,\n        _SC_NGROUPS_MAX,\n        _SC_OPEN_MAX,\n        _SC_STREAM_MAX,\n        _SC_TZNAME_MAX,\n        _SC_JOB_CONTROL,\n        _SC_SAVED_IDS,\n        _SC_REALTIME_SIGNALS,\n        _SC_PRIORITY_SCHEDULING,\n        _SC_TIMERS,\n        _SC_ASYNCHRONOUS_IO,\n        _SC_PRIORITIZED_IO,\n        _SC_SYNCHRONIZED_IO,\n        _SC_FSYNC,\n        _SC_MAPPED_FILES,\n        _SC_MEMLOCK,\n        _SC_MEMLOCK_RANGE,\n        _SC_MEMORY_PROTECTION,\n        _SC_MESSAGE_PASSING,\n        _SC_SEMAPHORES,\n        _SC_SHARED_MEMORY_OBJECTS,\n        _SC_AIO_LISTIO_MAX,\n        _SC_AIO_MAX,\n        _SC_AIO_PRIO_DELTA_MAX,\n        _SC_DELAYTIMER_MAX,\n        _SC_MQ_OPEN_MAX,\n        _SC_MQ_PRIO_MAX,\n        _SC_VERSION,\n        _SC_PAGE_SIZE,\n        _SC_PAGESIZE = _SC_PAGE_SIZE,\n        _SC_RTSIG_MAX,\n        _SC_SEM_NSEMS_MAX,\n        _SC_SEM_VALUE_MAX,\n        _SC_SIGQUEUE_MAX,\n        _SC_TIMER_MAX,\n        _SC_BC_BASE_MAX,\n        _SC_BC_DIM_MAX,\n        _SC_BC_SCALE_MAX,\n        _SC_BC_STRING_MAX,\n        _SC_COLL_WEIGHTS_MAX,\n\n        _SC_EXPR_NEST_MAX = 42,\n        _SC_LINE_MAX,\n        _SC_RE_DUP_MAX,\n\n        _SC_2_VERSION = 46,\n        _SC_2_C_BIND,\n        _SC_2_C_DEV,\n        _SC_2_FORT_DEV,\n        _SC_2_FORT_RUN,\n        _SC_2_SW_DEV,\n        _SC_2_LOCALEDEF,\n\n        _SC_UIO_MAXIOV = 60,\n        _SC_IOV_MAX = _SC_UIO_MAXIOV,\n\n        _SC_THREADS = 67,\n        _SC_THREAD_SAFE_FUNCTIONS,\n        _SC_GETGR_R_SIZE_MAX,\n        _SC_GETPW_R_SIZE_MAX,\n        _SC_LOGIN_NAME_MAX,\n        _SC_TTY_NAME_MAX,\n        _SC_THREAD_DESTRUCTOR_ITERATIONS,\n        _SC_THREAD_KEYS_MAX,\n        _SC_THREAD_STACK_MIN,\n        _SC_THREAD_THREADS_MAX,\n        _SC_THREAD_ATTR_STACKADDR,\n        _SC_THREAD_ATTR_STACKSIZE,\n        _SC_THREAD_PRIORITY_SCHEDULING,\n        _SC_THREAD_PRIO_INHERIT,\n        _SC_THREAD_PRIO_PROTECT,\n        _SC_THREAD_PROCESS_SHARED,\n\n        _SC_NPROCESSORS_CONF,\n        _SC_NPROCESSORS_ONLN,\n        _SC_PHYS_PAGES,\n        _SC_AVPHYS_PAGES,\n        _SC_ATEXIT_MAX,\n        _SC_PASS_MAX,\n\n        _SC_XOPEN_VERSION,\n        _SC_XOPEN_XCU_VERSION,\n        _SC_XOPEN_UNIX,\n        _SC_XOPEN_CRYPT,\n        _SC_XOPEN_ENH_I18N,\n        _SC_XOPEN_SHM,\n\n        _SC_2_CHAR_TERM,\n        _SC_2_UPE = 97,\n\n        _SC_XOPEN_XPG2,\n        _SC_XOPEN_XPG3,\n        _SC_XOPEN_XPG4,\n\n        _SC_NZERO = 109,\n\n        _SC_XBS5_ILP32_OFF32 = 125,\n        _SC_XBS5_ILP32_OFFBIG,\n        _SC_XBS5_LP64_OFF64,\n        _SC_XBS5_LPBIG_OFFBIG,\n\n        _SC_XOPEN_LEGACY,\n        _SC_XOPEN_REALTIME,\n        _SC_XOPEN_REALTIME_THREADS,\n\n        _SC_ADVISORY_INFO,\n        _SC_BARRIERS,\n        _SC_CLOCK_SELECTION = 137,\n        _SC_CPUTIME,\n        _SC_THREAD_CPUTIME,\n        _SC_MONOTONIC_CLOCK = 149,\n        _SC_READER_WRITER_LOCKS = 153,\n        _SC_SPIN_LOCKS,\n        _SC_REGEXP,\n        _SC_SHELL = 157,\n        _SC_SPAWN = 159,\n        _SC_SPORADIC_SERVER,\n        _SC_THREAD_SPORADIC_SERVER,\n        _SC_TIMEOUTS = 164,\n        _SC_TYPED_MEMORY_OBJECTS,\n        _SC_2_PBS = 168,\n        _SC_2_PBS_ACCOUNTING,\n        _SC_2_PBS_LOCATE,\n        _SC_2_PBS_MESSAGE,\n        _SC_2_PBS_TRACK,\n        _SC_SYMLOOP_MAX,\n        _SC_STREAMS,\n        _SC_2_PBS_CHECKPOINT,\n\n        _SC_V6_ILP32_OFF32,\n        _SC_V6_ILP32_OFFBIG,\n        _SC_V6_LP64_OFF64,\n        _SC_V6_LPBIG_OFFBIG,\n\n        _SC_HOST_NAME_MAX,\n        _SC_TRACE,\n        _SC_TRACE_EVENT_FILTER,\n        _SC_TRACE_INHERIT,\n        _SC_TRACE_LOG,\n\n        _SC_IPV6 = 235,\n        _SC_RAW_SOCKETS,\n        _SC_V7_ILP32_OFF32,\n        _SC_V7_ILP32_OFFBIG,\n        _SC_V7_LP64_OFF64,\n        _SC_V7_LPBIG_OFFBIG,\n        _SC_SS_REPL_MAX,\n        _SC_TRACE_EVENT_NAME_MAX,\n        _SC_TRACE_NAME_MAX,\n        _SC_TRACE_SYS_MAX,\n        _SC_TRACE_USER_EVENT_MAX,\n        _SC_XOPEN_STREAMS,\n        _SC_THREAD_ROBUST_PRIO_INHERIT,\n        _SC_THREAD_ROBUST_PRIO_PROTECT\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    enum F_OK       = 0;\n    enum R_OK       = 4;\n    enum W_OK       = 2;\n    enum X_OK       = 1;\n\n    enum F_ULOCK    = 0;\n    enum F_LOCK     = 1;\n    enum F_TLOCK    = 2;\n    enum F_TEST     = 3;\n\n    enum\n    {\n        _CS_PATH,\n\n        _CS_V6_WIDTH_RESTRICTED_ENVS,\n\n        _CS_GNU_LIBC_VERSION,\n        _CS_GNU_LIBPTHREAD_VERSION,\n\n        _CS_LFS_CFLAGS = 1000,\n        _CS_LFS_LDFLAGS,\n        _CS_LFS_LIBS,\n        _CS_LFS_LINTFLAGS,\n        _CS_LFS64_CFLAGS,\n        _CS_LFS64_LDFLAGS,\n        _CS_LFS64_LIBS,\n        _CS_LFS64_LINTFLAGS,\n\n        _CS_XBS5_ILP32_OFF32_CFLAGS = 1100,\n        _CS_XBS5_ILP32_OFF32_LDFLAGS,\n        _CS_XBS5_ILP32_OFF32_LIBS,\n        _CS_XBS5_ILP32_OFF32_LINTFLAGS,\n        _CS_XBS5_ILP32_OFFBIG_CFLAGS,\n        _CS_XBS5_ILP32_OFFBIG_LDFLAGS,\n        _CS_XBS5_ILP32_OFFBIG_LIBS,\n        _CS_XBS5_ILP32_OFFBIG_LINTFLAGS,\n        _CS_XBS5_LP64_OFF64_CFLAGS,\n        _CS_XBS5_LP64_OFF64_LDFLAGS,\n        _CS_XBS5_LP64_OFF64_LIBS,\n        _CS_XBS5_LP64_OFF64_LINTFLAGS,\n        _CS_XBS5_LPBIG_OFFBIG_CFLAGS,\n        _CS_XBS5_LPBIG_OFFBIG_LDFLAGS,\n        _CS_XBS5_LPBIG_OFFBIG_LIBS,\n        _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS,\n\n        _CS_POSIX_V6_ILP32_OFF32_CFLAGS,\n        _CS_POSIX_V6_ILP32_OFF32_LDFLAGS,\n        _CS_POSIX_V6_ILP32_OFF32_LIBS,\n        _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS,\n        _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS,\n        _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS,\n        _CS_POSIX_V6_ILP32_OFFBIG_LIBS,\n        _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS,\n        _CS_POSIX_V6_LP64_OFF64_CFLAGS,\n        _CS_POSIX_V6_LP64_OFF64_LDFLAGS,\n        _CS_POSIX_V6_LP64_OFF64_LIBS,\n        _CS_POSIX_V6_LP64_OFF64_LINTFLAGS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LIBS,\n        _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS\n    }\n\n    enum\n    {\n        _PC_LINK_MAX,\n        _PC_MAX_CANON,\n        _PC_MAX_INPUT,\n        _PC_NAME_MAX,\n        _PC_PATH_MAX,\n        _PC_PIPE_BUF,\n        _PC_CHOWN_RESTRICTED,\n        _PC_NO_TRUNC,\n        _PC_VDISABLE,\n        _PC_SYNC_IO,\n        _PC_ASYNC_IO,\n        _PC_PRIO_IO,\n        _PC_SOCK_MAXBUF,\n        _PC_FILESIZEBITS,\n        _PC_REC_INCR_XFER_SIZE,\n        _PC_REC_MAX_XFER_SIZE,\n        _PC_REC_MIN_XFER_SIZE,\n        _PC_REC_XFER_ALIGN,\n        _PC_ALLOC_SIZE_MIN,\n        _PC_SYMLINK_MAX,\n        _PC_2_SYMLINKS\n    }\n\n    enum\n    {\n        _SC_ARG_MAX,\n        _SC_CHILD_MAX,\n        _SC_CLK_TCK,\n        _SC_NGROUPS_MAX,\n        _SC_OPEN_MAX,\n        _SC_STREAM_MAX,\n        _SC_TZNAME_MAX,\n        _SC_JOB_CONTROL,\n        _SC_SAVED_IDS,\n        _SC_REALTIME_SIGNALS,\n        _SC_PRIORITY_SCHEDULING,\n        _SC_TIMERS,\n        _SC_ASYNCHRONOUS_IO,\n        _SC_PRIORITIZED_IO,\n        _SC_SYNCHRONIZED_IO,\n        _SC_FSYNC,\n        _SC_MAPPED_FILES,\n        _SC_MEMLOCK,\n        _SC_MEMLOCK_RANGE,\n        _SC_MEMORY_PROTECTION,\n        _SC_MESSAGE_PASSING,\n        _SC_SEMAPHORES,\n        _SC_SHARED_MEMORY_OBJECTS,\n        _SC_AIO_LISTIO_MAX,\n        _SC_AIO_MAX,\n        _SC_AIO_PRIO_DELTA_MAX,\n        _SC_DELAYTIMER_MAX,\n        _SC_MQ_OPEN_MAX,\n        _SC_MQ_PRIO_MAX,\n        _SC_VERSION,\n        _SC_PAGESIZE,\n        _SC_PAGE_SIZE = _SC_PAGESIZE,\n        _SC_RTSIG_MAX,\n        _SC_SEM_NSEMS_MAX,\n        _SC_SEM_VALUE_MAX,\n        _SC_SIGQUEUE_MAX,\n        _SC_TIMER_MAX,\n\n        _SC_BC_BASE_MAX,\n        _SC_BC_DIM_MAX,\n        _SC_BC_SCALE_MAX,\n        _SC_BC_STRING_MAX,\n        _SC_COLL_WEIGHTS_MAX,\n        _SC_EQUIV_CLASS_MAX,\n        _SC_EXPR_NEST_MAX,\n        _SC_LINE_MAX,\n        _SC_RE_DUP_MAX,\n        _SC_CHARCLASS_NAME_MAX,\n\n        _SC_2_VERSION,\n        _SC_2_C_BIND,\n        _SC_2_C_DEV,\n        _SC_2_FORT_DEV,\n        _SC_2_FORT_RUN,\n        _SC_2_SW_DEV,\n        _SC_2_LOCALEDEF,\n\n        _SC_PII,\n        _SC_PII_XTI,\n        _SC_PII_SOCKET,\n        _SC_PII_INTERNET,\n        _SC_PII_OSI,\n        _SC_POLL,\n        _SC_SELECT,\n        _SC_UIO_MAXIOV,\n        _SC_IOV_MAX = _SC_UIO_MAXIOV,\n        _SC_PII_INTERNET_STREAM,\n        _SC_PII_INTERNET_DGRAM,\n        _SC_PII_OSI_COTS,\n        _SC_PII_OSI_CLTS,\n        _SC_PII_OSI_M,\n        _SC_T_IOV_MAX,\n\n        _SC_THREADS,\n        _SC_THREAD_SAFE_FUNCTIONS,\n        _SC_GETGR_R_SIZE_MAX,\n        _SC_GETPW_R_SIZE_MAX,\n        _SC_LOGIN_NAME_MAX,\n        _SC_TTY_NAME_MAX,\n        _SC_THREAD_DESTRUCTOR_ITERATIONS,\n        _SC_THREAD_KEYS_MAX,\n        _SC_THREAD_STACK_MIN,\n        _SC_THREAD_THREADS_MAX,\n        _SC_THREAD_ATTR_STACKADDR,\n        _SC_THREAD_ATTR_STACKSIZE,\n        _SC_THREAD_PRIORITY_SCHEDULING,\n        _SC_THREAD_PRIO_INHERIT,\n        _SC_THREAD_PRIO_PROTECT,\n        _SC_THREAD_PROCESS_SHARED,\n\n        _SC_NPROCESSORS_CONF,\n        _SC_NPROCESSORS_ONLN,\n        _SC_PHYS_PAGES,\n        _SC_AVPHYS_PAGES,\n        _SC_ATEXIT_MAX,\n        _SC_PASS_MAX,\n\n        _SC_XOPEN_VERSION,\n        _SC_XOPEN_XCU_VERSION,\n        _SC_XOPEN_UNIX,\n        _SC_XOPEN_CRYPT,\n        _SC_XOPEN_ENH_I18N,\n        _SC_XOPEN_SHM,\n\n        _SC_2_CHAR_TERM,\n        _SC_2_C_VERSION,\n        _SC_2_UPE,\n\n        _SC_XOPEN_XPG2,\n        _SC_XOPEN_XPG3,\n        _SC_XOPEN_XPG4,\n\n        _SC_CHAR_BIT,\n        _SC_CHAR_MAX,\n        _SC_CHAR_MIN,\n        _SC_INT_MAX,\n        _SC_INT_MIN,\n        _SC_LONG_BIT,\n        _SC_WORD_BIT,\n        _SC_MB_LEN_MAX,\n        _SC_NZERO,\n        _SC_SSIZE_MAX,\n        _SC_SCHAR_MAX,\n        _SC_SCHAR_MIN,\n        _SC_SHRT_MAX,\n        _SC_SHRT_MIN,\n        _SC_UCHAR_MAX,\n        _SC_UINT_MAX,\n        _SC_ULONG_MAX,\n        _SC_USHRT_MAX,\n\n        _SC_NL_ARGMAX,\n        _SC_NL_LANGMAX,\n        _SC_NL_MSGMAX,\n        _SC_NL_NMAX,\n        _SC_NL_SETMAX,\n        _SC_NL_TEXTMAX,\n\n        _SC_XBS5_ILP32_OFF32,\n        _SC_XBS5_ILP32_OFFBIG,\n        _SC_XBS5_LP64_OFF64,\n        _SC_XBS5_LPBIG_OFFBIG,\n\n        _SC_XOPEN_LEGACY,\n        _SC_XOPEN_REALTIME,\n        _SC_XOPEN_REALTIME_THREADS,\n\n        _SC_ADVISORY_INFO,\n        _SC_BARRIERS,\n        _SC_BASE,\n        _SC_C_LANG_SUPPORT,\n        _SC_C_LANG_SUPPORT_R,\n        _SC_CLOCK_SELECTION,\n        _SC_CPUTIME,\n        _SC_THREAD_CPUTIME,\n        _SC_DEVICE_IO,\n        _SC_DEVICE_SPECIFIC,\n        _SC_DEVICE_SPECIFIC_R,\n        _SC_FD_MGMT,\n        _SC_FIFO,\n        _SC_PIPE,\n        _SC_FILE_ATTRIBUTES,\n        _SC_FILE_LOCKING,\n        _SC_FILE_SYSTEM,\n        _SC_MONOTONIC_CLOCK,\n        _SC_MULTI_PROCESS,\n        _SC_SINGLE_PROCESS,\n        _SC_NETWORKING,\n        _SC_READER_WRITER_LOCKS,\n        _SC_SPIN_LOCKS,\n        _SC_REGEXP,\n        _SC_REGEX_VERSION,\n        _SC_SHELL,\n        _SC_SIGNALS,\n        _SC_SPAWN,\n        _SC_SPORADIC_SERVER,\n        _SC_THREAD_SPORADIC_SERVER,\n        _SC_SYSTEM_DATABASE,\n        _SC_SYSTEM_DATABASE_R,\n        _SC_TIMEOUTS,\n        _SC_TYPED_MEMORY_OBJECTS,\n        _SC_USER_GROUPS,\n        _SC_USER_GROUPS_R,\n        _SC_2_PBS,\n        _SC_2_PBS_ACCOUNTING,\n        _SC_2_PBS_LOCATE,\n        _SC_2_PBS_MESSAGE,\n        _SC_2_PBS_TRACK,\n        _SC_SYMLOOP_MAX,\n        _SC_STREAMS,\n        _SC_2_PBS_CHECKPOINT,\n\n        _SC_V6_ILP32_OFF32,\n        _SC_V6_ILP32_OFFBIG,\n        _SC_V6_LP64_OFF64,\n        _SC_V6_LPBIG_OFFBIG,\n\n        _SC_HOST_NAME_MAX,\n        _SC_TRACE,\n        _SC_TRACE_EVENT_FILTER,\n        _SC_TRACE_INHERIT,\n        _SC_TRACE_LOG,\n\n        _SC_LEVEL1_ICACHE_SIZE,\n        _SC_LEVEL1_ICACHE_ASSOC,\n        _SC_LEVEL1_ICACHE_LINESIZE,\n        _SC_LEVEL1_DCACHE_SIZE,\n        _SC_LEVEL1_DCACHE_ASSOC,\n        _SC_LEVEL1_DCACHE_LINESIZE,\n        _SC_LEVEL2_CACHE_SIZE,\n        _SC_LEVEL2_CACHE_ASSOC,\n        _SC_LEVEL2_CACHE_LINESIZE,\n        _SC_LEVEL3_CACHE_SIZE,\n        _SC_LEVEL3_CACHE_ASSOC,\n        _SC_LEVEL3_CACHE_LINESIZE,\n        _SC_LEVEL4_CACHE_SIZE,\n        _SC_LEVEL4_CACHE_ASSOC,\n        _SC_LEVEL4_CACHE_LINESIZE,\n\n        _SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50,\n        _SC_RAW_SOCKETS\n    }\n}\n\n//\n// File Synchronization (FSC)\n//\n/*\nint fsync(int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int fsync(int) @trusted;\n}\nelse version (Darwin)\n{\n    int fsync(int) @trusted;\n}\nelse version (FreeBSD)\n{\n    int fsync(int) @trusted;\n}\nelse version (NetBSD)\n{\n    int fsync(int) @trusted;\n}\nelse version (DragonFlyBSD)\n{\n    int fsync(int) @trusted;\n}\nelse version (CRuntime_Bionic)\n{\n    int fsync(int) @trusted;\n}\nelse version (CRuntime_Musl)\n{\n    int fsync(int) @trusted;\n}\nelse version (Solaris)\n{\n    int fsync(int) @trusted;\n}\nelse version (CRuntime_UClibc)\n{\n    int fsync(int) @trusted;\n}\n\n//\n// Synchronized I/O (SIO)\n//\n/*\nint fdatasync(int);\n*/\n\nversion (CRuntime_Glibc)\n{\n    int fdatasync(int) @trusted;\n}\nelse version (Solaris)\n{\n    int fdatasync(int) @trusted;\n}\nelse version (CRuntime_Bionic)\n{\n    int fdatasync(int) @trusted;\n}\nelse version (CRuntime_UClibc)\n{\n    int fdatasync(int) @trusted;\n}\n\n//\n// XOpen (XSI)\n//\n/*\nchar*      crypt(in char*, in char*);\nchar*      ctermid(char*);\nvoid       encrypt(ref char[64], int);\nint        fchdir(int);\nc_long     gethostid();\npid_t      getpgid(pid_t);\npid_t      getsid(pid_t);\nchar*      getwd(char*); // LEGACY\nint        lchown(in char*, uid_t, gid_t);\nint        lockf(int, int, off_t);\nint        nice(int);\nssize_t    pread(int, void*, size_t, off_t);\nssize_t    pwrite(int, in void*, size_t, off_t);\npid_t      setpgrp();\nint        setregid(gid_t, gid_t);\nint        setreuid(uid_t, uid_t);\nvoid       swab(in void*, void*, ssize_t);\nvoid       sync();\nint        truncate(in char*, off_t);\nuseconds_t ualarm(useconds_t, useconds_t);\nint        usleep(useconds_t);\npid_t      vfork();\n*/\n\nversion (CRuntime_Glibc)\n{\n    char*      crypt(in char*, in char*);\n    char*      ctermid(char*);\n    void       encrypt(ref char[64], int) @trusted;\n    int        fchdir(int) @trusted;\n    c_long     gethostid() @trusted;\n    pid_t      getpgid(pid_t) @trusted;\n    pid_t      getsid(pid_t) @trusted;\n    char*      getwd(char*); // LEGACY\n    int        lchown(in char*, uid_t, gid_t);\n    //int        lockf(int, int, off_t);\n    int        nice(int) @trusted;\n    //ssize_t    pread(int, void*, size_t, off_t);\n    //ssize_t    pwrite(int, in void*, size_t, off_t);\n    pid_t      setpgrp() @trusted;\n    int        setregid(gid_t, gid_t) @trusted;\n    int        setreuid(uid_t, uid_t) @trusted;\n    void       swab(in void*, void*, ssize_t);\n    void       sync() @trusted;\n    //int        truncate(in char*, off_t);\n    useconds_t ualarm(useconds_t, useconds_t) @trusted;\n    int        usleep(useconds_t) @trusted;\n    pid_t      vfork();\n\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    int        lockf64(int, int, off_t) @trusted;\n    alias      lockf64 lockf;\n\n    ssize_t    pread64(int, void*, size_t, off_t);\n    alias      pread64 pread;\n\n    ssize_t    pwrite64(int, in void*, size_t, off_t);\n    alias      pwrite64 pwrite;\n\n    int        truncate64(in char*, off_t);\n    alias      truncate64 truncate;\n  }\n  else\n  {\n    int        lockf(int, int, off_t) @trusted;\n    ssize_t    pread(int, void*, size_t, off_t);\n    ssize_t    pwrite(int, in void*, size_t, off_t);\n    int        truncate(in char*, off_t);\n  }\n}\nelse version (CRuntime_Musl)\n{\n    int fchdir(int) @trusted;\n    int lockf(int, int, off_t);\n    alias lockf lockf64;\n}\nelse version (Darwin)\n{\n    char*      crypt(in char*, in char*);\n    char*      ctermid(char*);\n    void       encrypt(ref char[64], int) @trusted;\n    int        fchdir(int) @trusted;\n    c_long     gethostid() @trusted;\n    pid_t      getpgid(pid_t) @trusted;\n    pid_t      getsid(pid_t) @trusted;\n    char*      getwd(char*); // LEGACY\n    int        lchown(in char*, uid_t, gid_t);\n    int        lockf(int, int, off_t) @trusted;\n    int        nice(int) @trusted;\n    ssize_t    pread(int, void*, size_t, off_t);\n    ssize_t    pwrite(int, in void*, size_t, off_t);\n    pid_t      setpgrp() @trusted;\n    int        setregid(gid_t, gid_t) @trusted;\n    int        setreuid(uid_t, uid_t) @trusted;\n    void       swab(in void*, void*, ssize_t);\n    void       sync() @trusted;\n    int        truncate(in char*, off_t);\n    useconds_t ualarm(useconds_t, useconds_t) @trusted;\n    int        usleep(useconds_t) @trusted;\n    pid_t      vfork();\n}\nelse version (FreeBSD)\n{\n    char*      crypt(in char*, in char*);\n    //char*      ctermid(char*);\n    void       encrypt(ref char[64], int) @trusted;\n    int        fchdir(int) @trusted;\n    c_long     gethostid() @trusted;\n    int        getpgid(pid_t) @trusted;\n    int        getsid(pid_t) @trusted;\n    char*      getwd(char*); // LEGACY\n    int        lchown(in char*, uid_t, gid_t);\n    int        lockf(int, int, off_t) @trusted;\n    int        nice(int) @trusted;\n    ssize_t    pread(int, void*, size_t, off_t);\n    ssize_t    pwrite(int, in void*, size_t, off_t);\n    int        setpgrp(pid_t, pid_t) @trusted;\n    int        setregid(gid_t, gid_t) @trusted;\n    int        setreuid(uid_t, uid_t) @trusted;\n    void       swab(in void*, void*, ssize_t);\n    void       sync() @trusted;\n    int        truncate(in char*, off_t);\n    useconds_t ualarm(useconds_t, useconds_t) @trusted;\n    int        usleep(useconds_t) @trusted;\n    pid_t      vfork();\n}\nelse version (NetBSD)\n{\n    char*      crypt(in char*, in char*);\n    //char*      ctermid(char*);\n    void       encrypt(ref char[64], int) @trusted;\n    int        fchdir(int) @trusted;\n    c_long     gethostid() @trusted;\n    int        getpgid(pid_t) @trusted;\n    int        getsid(pid_t) @trusted;\n    char*      getwd(char*); // LEGACY\n    int        lchown(in char*, uid_t, gid_t);\n    int        lockf(int, int, off_t) @trusted;\n    int        nice(int) @trusted;\n    ssize_t    pread(int, void*, size_t, off_t);\n    ssize_t    pwrite(int, in void*, size_t, off_t);\n    int        setpgrp(pid_t, pid_t) @trusted;\n    int        setregid(gid_t, gid_t) @trusted;\n    int        setreuid(uid_t, uid_t) @trusted;\n    void       swab(in void*, void*, ssize_t);\n    void       sync() @trusted;\n    int        truncate(in char*, off_t);\n    useconds_t ualarm(useconds_t, useconds_t) @trusted;\n    int        usleep(useconds_t) @trusted;\n    pid_t      vfork();\n}\nelse version (DragonFlyBSD)\n{\n    char*      crypt(in char*, in char*);\n    //char*      ctermid(char*);\n    void       encrypt(ref char[64], int) @trusted;\n    int        fchdir(int) @trusted;\n    c_long     gethostid() @trusted;\n    int        getpgid(pid_t) @trusted;\n    int        getsid(pid_t) @trusted;\n    char*      getwd(char*); // LEGACY\n    int        lchown(in char*, uid_t, gid_t);\n    int        lockf(int, int, off_t) @trusted;\n    int        nice(int) @trusted;\n    ssize_t    pread(int, void*, size_t, off_t);\n    ssize_t    pwrite(int, in void*, size_t, off_t);\n    int        setpgrp(pid_t, pid_t) @trusted;\n    int        setregid(gid_t, gid_t) @trusted;\n    int        setreuid(uid_t, uid_t) @trusted;\n    void       swab(in void*, void*, ssize_t);\n    void       sync() @trusted;\n    int        truncate(in char*, off_t);\n    useconds_t ualarm(useconds_t, useconds_t) @trusted;\n    int        usleep(useconds_t) @trusted;\n    pid_t      vfork();\n}\nelse version (CRuntime_Bionic)\n{\n    int        fchdir(int) @trusted;\n    pid_t      getpgid(pid_t) @trusted;\n    int        lchown(in char*, uid_t, gid_t);\n    int        nice(int) @trusted;\n    ssize_t    pread(int, void*, size_t, off_t);\n    ssize_t    pwrite(int, in void*, size_t, off_t);\n    int        setpgrp() @trusted;\n    int        setregid(gid_t, gid_t) @trusted;\n    int        setreuid(uid_t, uid_t) @trusted;\n    int        sync() @trusted;\n    int        truncate(in char*, off_t);\n    int        usleep(c_ulong) @trusted;\n    pid_t      vfork();\n}\nelse version (Solaris)\n{\n    char*      crypt(in char*, in char*);\n    char*      ctermid(char*);\n    void       encrypt(ref char[64], int);\n    int        fchdir(int);\n    c_long     gethostid();\n    pid_t      getpgid(pid_t);\n    pid_t      getsid(pid_t);\n    char*      getwd(char*); // LEGACY\n    int        lchown(in char*, uid_t, gid_t);\n    int        nice(int);\n    pid_t      setpgrp();\n    int        setregid(gid_t, gid_t);\n    int        setreuid(uid_t, uid_t);\n    void       swab(in void*, void*, ssize_t);\n    void       sync();\n    useconds_t ualarm(useconds_t, useconds_t);\n    int        usleep(useconds_t);\n    pid_t      vfork();\n\n    version (D_LP64)\n    {\n        int         lockf(int, int, off_t);\n        alias       lockf lockf64;\n\n        ssize_t     pread(int, void*, size_t, off_t);\n        alias       pread pread64;\n\n        ssize_t     pwrite(int, in void*, size_t, off_t);\n        alias       pwrite pwrite64;\n\n        int         truncate(in char*, off_t);\n        alias       truncate truncate64;\n    }\n    else\n    {\n        static if ( __USE_FILE_OFFSET64 )\n        {\n            int        lockf64(int, int, off64_t);\n            alias      lockf64 lockf;\n\n            ssize_t    pread64(int, void*, size_t, off64_t);\n            alias      pread64 pread;\n\n            ssize_t    pwrite64(int, in void*, size_t, off_t);\n            alias      pwrite64 pwrite;\n\n            int        truncate64(in char*, off_t);\n            alias      truncate64 truncate;\n        }\n        else\n        {\n            int        lockf(int, int, off_t);\n            ssize_t    pread(int, void*, size_t, off_t);\n            ssize_t    pwrite(int, in void*, size_t, off_t);\n            int        truncate(in char*, off_t);\n        }\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    char*      crypt(in char*, in char*);\n    char*      ctermid(char*);\n    void       encrypt(ref char[64], int) @trusted;\n    int        fchdir(int) @trusted;\n    c_long     gethostid() @trusted;\n    pid_t      getpgid(pid_t) @trusted;\n    pid_t      getsid(pid_t) @trusted;\n    char*      getwd(char*); // LEGACY\n    int        lchown(in char*, uid_t, gid_t);\n    int        nice(int) @trusted;\n    pid_t      setpgrp() @trusted;\n    int        setregid(gid_t, gid_t) @trusted;\n    int        setreuid(uid_t, uid_t) @trusted;\n    void       swab(in void*, void*, ssize_t);\n    void       sync() @trusted;\n    useconds_t ualarm(useconds_t, useconds_t) @trusted;\n    int        usleep(useconds_t) @trusted;\n    pid_t      vfork();\n\n  static if ( __USE_FILE_OFFSET64 )\n  {\n    int        lockf64(int, int, off_t) @trusted;\n    alias      lockf64 lockf;\n\n    ssize_t    pread64(int, void*, size_t, off_t);\n    alias      pread64 pread;\n\n    ssize_t    pwrite64(int, in void*, size_t, off_t);\n    alias      pwrite64 pwrite;\n\n    int        truncate64(in char*, off_t);\n    alias      truncate64 truncate;\n  }\n  else\n  {\n    int        lockf(int, int, off_t) @trusted;\n    ssize_t    pread(int, void*, size_t, off_t);\n    ssize_t    pwrite(int, in void*, size_t, off_t);\n    int        truncate(in char*, off_t);\n  }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/posix/utime.d",
    "content": "/**\n * D header file for POSIX.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition\n */\n\n/*          Copyright Sean Kelly 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.sys.posix.utime;\n\nprivate import core.sys.posix.config;\npublic import core.sys.posix.sys.types; // for time_t\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Posix):\nextern (C):\nnothrow:\n@nogc:\n\n//\n// Required\n//\n/*\nstruct utimbuf\n{\n    time_t  actime;\n    time_t  modtime;\n}\n\nint utime(in char*, in utimbuf*);\n*/\n\nversion (CRuntime_Glibc)\n{\n    struct utimbuf\n    {\n        time_t  actime;\n        time_t  modtime;\n    }\n\n    int utime(in char*, in utimbuf*);\n}\nelse version (CRuntime_Musl)\n{\n    struct utimbuf\n    {\n        time_t  actime;\n        time_t  modtime;\n    }\n\n    int utime(in char*, in utimbuf*);\n}\nelse version (Darwin)\n{\n    struct utimbuf\n    {\n        time_t  actime;\n        time_t  modtime;\n    }\n\n    int utime(in char*, in utimbuf*);\n}\nelse version (FreeBSD)\n{\n    struct utimbuf\n    {\n        time_t  actime;\n        time_t  modtime;\n    }\n\n    int utime(in char*, in utimbuf*);\n}\nelse version (NetBSD)\n{\n    struct utimbuf\n    {\n        time_t  actime;\n        time_t  modtime;\n    }\n\n    int utime(in char*, in utimbuf*);\n}\nelse version (DragonFlyBSD)\n{\n    struct utimbuf\n    {\n        time_t  actime;\n        time_t  modtime;\n    }\n\n    int utime(in char*, in utimbuf*);\n}\nelse version (Solaris)\n{\n    struct utimbuf\n    {\n        time_t  actime;\n        time_t  modtime;\n    }\n\n    int utime(in char*, in utimbuf*);\n}\nelse version (CRuntime_Bionic)\n{\n    struct utimbuf\n    {\n        time_t  actime;\n        time_t  modtime;\n    }\n\n    int utime(in char*, in utimbuf*);\n}\nelse version (CRuntime_UClibc)\n{\n    struct utimbuf\n    {\n        time_t  actime;\n        time_t  modtime;\n    }\n\n    int utime(in char*, in utimbuf*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/dlfcn.d",
    "content": "/**\n * D header file for Solaris\n *\n * $(LINK2 http://src.illumos.org/source/xref/illumos-gate/usr/src/head/dlfcn.h, illumos dlfcn.h)\n */\n\nmodule core.sys.solaris.dlfcn;\n\nversion (Solaris):\nextern (C):\nnothrow:\n\npublic import core.sys.posix.dlfcn;\nimport core.stdc.config;\n\n// enum RTLD_LAZY = 0x00001; // POSIX\n// enum RTLD_NOW = 0x00002; // POSIX\nenum RTLD_NOLOAD = 0x00004;\nenum RTLD_DEEPBIND = 0x00008;\n\n// enum RTLD_GLOBAL = 0x00100; // POSIX\n// enum RTLD_LOCAL = 0; // POSIX\nenum RTLD_PARENT   = 0x00200;\nenum RTLD_GROUP    = 0x00400;\nenum RTLD_WORLD    = 0x00800;\nenum RTLD_NODELETE = 0x01000;\nenum RTLD_FIRST    = 0x02000;\nenum RTLD_CONFGEN  = 0x10000;\n\n\nenum\n{\n    RTLD_NEXT    = cast(void *)-1,\n    RTLD_DEFAULT = cast(void *)-2,\n    RTLD_SELF    = cast(void *)-3,\n    RTLD_PROBE   = cast(void *)-4,\n}\n\nalias c_ulong Lmid_t;\n\nvoid* dlmopen(Lmid_t, in char*, int);\n\nenum\n{\n    RTLD_REL_RELATIVE = 0x00001,\n    RTLD_REL_EXEC     = 0x00002,\n    RTLD_REL_DEPENDS  = 0x00004,\n    RTLD_REL_PRELOAD  = 0x00008,\n    RTLD_REL_SELF     = 0x00010,\n    RTLD_REL_WEAK     = 0x00020,\n    RTLD_REL_ALL      = 0x00fff,\n    RTLD_MEMORY       = 0x01000,\n    RTLD_STRIP        = 0x02000,\n    RTLD_NOHEAP       = 0x04000,\n    RTLD_CONFSET      = 0x10000,\n}\n\nint dldump(in char*, in char*, int);\n\nstruct Dl_info\n{\n    const(char)* dli_fname;\n    void*        dli_fbase;\n    const(char)* dli_sname;\n    void*        dli_saddr;\n}\n\nenum\n{\n    RTLD_DL_SYMENT = 1,\n    RTLD_DL_LINKMAP = 2,\n}\n\nint dladdr(const(void)*, Dl_info*);\nint dladdr1(void*, Dl_info*, void**, int);\n\nenum\n{\n    RTLD_DI_LMID         = 1,\n    RTLD_DI_LINKMAP      = 2,\n    RTLD_DI_CONFIGADDR   = 3,\n    RTLD_DI_SERINFO      = 4,\n    RTLD_DI_SERINFOSIZE  = 5,\n    RTLD_DI_ORIGIN       = 6,\n    RTLD_DI_PROFILENAME  = 7,\n    RTLD_DI_PROFILEOUT   = 8,\n    RTLD_DI_GETSIGNAL    = 9,\n    RTLD_DI_SETSIGNAL    = 10,\n    RTLD_DI_ARGSINFO     = 11,\n    RTLD_DI_MMAPS        = 12,\n    RTLD_DI_MMAPCNT      = 13,\n    RTLD_DI_DEFERRED     = 14,\n    RTLD_DI_DEFERRED_SYM = 15,\n    RTLD_DI_MAX          = 15,\n}\n\nint dlinfo(void*, int, void*);\n\nstruct Dl_serpath\n{\n    char*  dls_name;\n    uint   dls_flags;\n}\n\nstruct Dl_serinfo\n{\n    size_t         dls_size;\n    uint           dls_cnt;\n    Dl_serpath[1]  dls_serpath;\n}\n\n// FIXME: Dl_argsinfo, Dl_mapinfo, Dl_amd64_unwindinfo are missing"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/elf.d",
    "content": "/**\n * D header file for Solaris.\n *\n * $(LINK2 http://src.illumos.org/source/xref/illumos-gate/usr/src/head/elf.h, illumos elf.h)\n */\nmodule core.sys.solaris.elf;\n\nversion (Solaris):\nextern (C):\nnothrow:\n\npublic import core.sys.solaris.sys.elf;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/execinfo.d",
    "content": "/**\n * D header file for Solaris.\n *\n * Copyright: Copyright Martin Nowak 2012.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Martin Nowak\n */\nmodule core.sys.solaris.execinfo;\n\n// The interface is exactly the same as linux, so copied from linux's execinfo.d\n\nversion (Solaris):\nextern (C):\nnothrow:\n\nint backtrace(void** buffer, int size);\nchar** backtrace_symbols(const(void*)* buffer, int size);\nvoid backtrace_symbols_fd(const(void*)* buffer, int size, int fd);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/libelf.d",
    "content": "/**\n * D header file for Solaris.\n *\n * $(LINK2 http://src.illumos.org/source/xref/illumos-gate/usr/src/head/libelf.h, illumos libelf.h)\n */\nmodule core.sys.solaris.libelf;\n\nversion (Solaris):\nextern (C):\nnothrow:\n\nimport core.stdc.config;\nimport core.sys.posix.sys.types;\nimport core.sys.solaris.sys.elf;\n\nenum Elf_Cmd\n{\n    ELF_C_NULL = 0,\n    ELF_C_READ,\n    ELF_C_WRITE,\n    ELF_C_CLR,\n    ELF_C_SET,\n    ELF_C_FDDONE,\n    ELF_C_FDREAD,\n    ELF_C_RDWR,\n    ELF_C_WRIMAGE,\n    ELF_C_IMAGE,\n    ELF_C_NUM\n}\n\nenum ELF_F_DIRTY  = 0x1;\nenum ELF_F_LAYOUT = 0x4;\n\nenum Elf_Kind\n{\n    ELF_K_NONE = 0,\n    ELF_K_AR,\n    ELF_K_COFF,\n    ELF_K_ELF,\n    ELF_K_NUM\n}\n\nenum Elf_Type\n{\n    ELF_T_BYTE = 0,\n    ELF_T_ADDR,\n    ELF_T_DYN,\n    ELF_T_EHDR,\n    ELF_T_HALF,\n    ELF_T_OFF,\n    ELF_T_PHDR,\n    ELF_T_RELA,\n    ELF_T_REL,\n    ELF_T_SHDR,\n    ELF_T_SWORD,\n    ELF_T_SYM,\n    ELF_T_WORD,\n    ELF_T_VDEF,\n    ELF_T_VNEED,\n    ELF_T_SXWORD,\n    ELF_T_XWORD,\n    ELF_T_SYMINFO,\n    ELF_T_NOTE,\n    ELF_T_MOVE,\n    ELF_T_MOVEP,\n    ELF_T_CAP,\n    ELF_T_NUM\n}\n\nstruct Elf\n{\n}\n\nstruct Elf_Scn\n{\n}\n\nstruct Elf_Arhdr\n{\n    char*   ar_name;\n    time_t  ar_date;\n    uid_t   ar_uid;\n    gid_t   ar_gid;\n    mode_t  ar_mode;\n    off_t   ar_size;\n    char*   ar_rawname;\n}\n\nstruct Elf_Arsym\n{\n    char*    as_name;\n    size_t   as_off;\n    c_ulong  as_hash;\n}\n\nstruct Elf_Data\n{\n  void*     d_buf;\n  Elf_Type  d_type;\n  size_t    d_size;\n  off_t     d_off;\n  size_t    d_align;\n  uint      d_version;\n}\n\nElf* elf_begin(int, Elf_Cmd, Elf*);\nint elf_cntl(Elf*, Elf_Cmd);\nint elf_end(Elf*);\nconst(char)* elf_errmsg(int);\nint elf_errno();\nvoid elf_fill(int);\nuint elf_flagdata(Elf_Data*, Elf_Cmd, uint);\nuint elf_flagehdr(Elf*, Elf_Cmd,  uint);\nuint elf_flagelf(Elf*, Elf_Cmd, uint);\nuint elf_flagphdr(Elf*, Elf_Cmd, uint);\nuint elf_flagscn(Elf_Scn*, Elf_Cmd, uint);\nuint elf_flagshdr(Elf_Scn*, Elf_Cmd, uint);\nsize_t elf32_fsize(Elf_Type, size_t, uint);\nElf_Arhdr* elf_getarhdr(Elf*);\nElf_Arsym* elf_getarsym(Elf*, size_t*);\noff_t elf_getbase(Elf*);\nElf_Data* elf_getdata(Elf_Scn*, Elf_Data*);\nElf32_Ehdr* elf32_getehdr(Elf*);\nchar* elf_getident(Elf*, size_t*);\nElf32_Phdr* elf32_getphdr(Elf*);\nElf_Scn* elf_getscn(Elf*, size_t);\nElf32_Shdr* elf32_getshdr(Elf_Scn*);\nint elf_getphnum(Elf*, size_t*);\nint elf_getphdrnum(Elf*, size_t*);\nint elf_getshnum(Elf*, size_t*);\nint elf_getshdrnum(Elf*, size_t*);\nint elf_getshstrndx(Elf*, size_t*);\nint elf_getshdrstrndx(Elf*, size_t*);\nc_ulong elf_hash(in char*);\nuint elf_sys_encoding();\nlong elf32_checksum(Elf*);\nElf_Kind elf_kind(Elf*);\nElf* elf_memory(char*, size_t);\nsize_t elf_ndxscn(Elf_Scn*);\nElf_Data* elf_newdata(Elf_Scn*);\nElf32_Ehdr* elf32_newehdr(Elf*);\nElf32_Phdr* elf32_newphdr(Elf*, size_t);\nElf_Scn* elf_newscn(Elf*);\nElf_Scn* elf_nextscn(Elf*, Elf_Scn*);\nElf_Cmd elf_next(Elf*);\nsize_t elf_rand(Elf*, size_t);\nElf_Data* elf_rawdata(Elf_Scn*, Elf_Data*);\nchar* elf_rawfile(Elf*, size_t*);\nchar* elf_strptr(Elf*, size_t, size_t);\noff_t elf_update(Elf*, Elf_Cmd);\nuint elf_version(uint);\nElf_Data* elf32_xlatetof(Elf_Data*, in Elf_Data*, uint);\nElf_Data* elf32_xlatetom(Elf_Data*, in Elf_Data*, uint);\n\nversion (D_LP64)\n{\nsize_t elf64_fsize(Elf_Type, size_t, uint);\nElf64_Ehdr* elf64_getehdr(Elf*);\nElf64_Phdr* elf64_getphdr(Elf*);\nElf64_Shdr* elf64_getshdr(Elf_Scn*);\nlong elf64_checksum(Elf*);\nElf64_Ehdr* elf64_newehdr(Elf*);\nElf64_Phdr* elf64_newphdr(Elf*, size_t);\nElf_Data* elf64_xlatetof(Elf_Data*, in Elf_Data*, uint);\nElf_Data* elf64_xlatetom(Elf_Data*, in Elf_Data*, uint);\n}"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/link.d",
    "content": "﻿/**\n * D header file for Solaris.\n *\n * $(LINK2 http://src.illumos.org/source/xref/illumos-gate/usr/src/head/link.h, illumos link.h)\n */\nmodule core.sys.solaris.link;\n\nversion (Solaris):\nextern (C):\nnothrow:\n\nimport core.stdc.stdint;\nimport core.sys.solaris.dlfcn;\nimport core.sys.solaris.libelf;\nimport core.sys.solaris.sys.elf;\nimport core.sys.solaris.sys.link;\n\nuint ld_version(uint);\nvoid ld_input_done(uint*);\n\nvoid ld_start(in char*, in Elf32_Half, in char*);\nvoid ld_atexit(int);\nvoid ld_open(in char**, in char**, int*, int, Elf**, Elf*, size_t, in Elf_Kind);\nvoid ld_file(in char*, in Elf_Kind, int, Elf*);\nvoid ld_input_section(in char*, Elf32_Shdr**, Elf32_Word, Elf_Data*, Elf*, uint*);\nvoid ld_section(in char*, Elf32_Shdr*, Elf32_Word, Elf_Data*, Elf*);\n\nversion (D_LP64)\n{\nvoid ld_start64(in char*, in Elf64_Half, in char*);\nvoid ld_atexit64(int);\nvoid ld_open64(in char**, in char**, int*, int, Elf**, Elf*, size_t, in Elf_Kind);\nvoid ld_file64(in char*, in Elf_Kind, int, Elf*);\nvoid ld_input_section64(in char*, Elf64_Shdr**, Elf64_Word, Elf_Data*, Elf*, uint*);\nvoid ld_section64(in char*, Elf64_Shdr*, Elf64_Word, Elf_Data*, Elf*);\n}\n\nenum LD_SUP_VNONE    = 0;\nenum LD_SUP_VERSION1 = 1;\nenum LD_SUP_VERSION2 = 2;\nenum LD_SUP_VERSION3 = 3;\nenum LD_SUP_VCURRENT = LD_SUP_VERSION3;\n\nenum LD_SUP_DERIVED   = 0x1;\nenum LD_SUP_INHERITED = 0x2;\nenum LD_SUP_EXTRACTED = 0x4;\n\nenum LM_ID_BASE = 0x00;\nenum LM_ID_LDSO = 0x01;\nenum LM_ID_NUM  = 2;\n\nenum LM_ID_BRAND = 0xfd;\nenum LM_ID_NONE  = 0xfe;\nenum LM_ID_NEWLM = 0xff;\n\nenum LAV_NONE     = 0;\nenum LAV_VERSION1 = 1;\nenum LAV_VERSION2 = 2;\nenum LAV_VERSION3 = 3;\nenum LAV_VERSION4 = 4;\nenum LAV_VERSION5 = 5;\nenum LAV_CURRENT  = LAV_VERSION5;\nenum LAV_NUM      = 6;\n\nenum LA_FLG_BINDTO   = 0x0001;\nenum LA_FLG_BINDFROM = 0x0002;\n\nenum LA_SYMB_NOPLTENTER = 0x0001;\nenum LA_SYMB_NOPLTEXIT  = 0x0002;\nenum LA_SYMB_STRUCTCALL = 0x0004;\nenum LA_SYMB_DLSYM      = 0x0008;\nenum LA_SYMB_ALTVALUE   = 0x0010;\n\nenum LA_SER_ORIG    = 0x001;\nenum LA_SER_LIBPATH = 0x002;\nenum LA_SER_RUNPATH = 0x004;\nenum LA_SER_CONFIG  = 0x008;\nenum LA_SER_DEFAULT = 0x040;\nenum LA_SER_SECURE  = 0x080;\n\nenum LA_SER_MASK    = 0xfff;\n\nenum LA_ACT_CONSISTENT = 0x00;\nenum LA_ACT_ADD        = 0x01;\nenum LA_ACT_DELETE     = 0x02;\nenum LA_ACT_MAX        = 3;\n\nversion (D_LP64)\n    alias long lagreg_t;\nelse\n    alias int lagreg_t;\n\nstruct _la_sparc_regs\n{\n    lagreg_t  lr_rego0;\n    lagreg_t  lr_rego1;\n    lagreg_t  lr_rego2;\n    lagreg_t  lr_rego3;\n    lagreg_t  lr_rego4;\n    lagreg_t  lr_rego5;\n    lagreg_t  lr_rego6;\n    lagreg_t  lr_rego7;\n}\n\nversion (D_LP64)\n{\n    alias _la_sparc_regs La_sparcv9_regs;\n    struct La_amd64_regs\n    {\n        lagreg_t  lr_rsp;\n        lagreg_t  lr_rbp;\n        lagreg_t  lr_rdi;\n        lagreg_t  lr_rsi;\n        lagreg_t  lr_rdx;\n        lagreg_t  lr_rcx;\n        lagreg_t  lr_r8;\n        lagreg_t  lr_r9;\n    }\n}\nelse\n{\n    alias _la_sparc_regs La_sparcv8_regs;\n    struct La_i86_regs\n    {\n        lagreg_t  lr_esp;\n        lagreg_t  lr_ebp;\n    }\n}\n\nuint la_version(uint);\nvoid la_activity(uintptr_t*, uint);\nvoid la_preinit(uintptr_t*);\nchar* la_objsearch(in char*, uintptr_t*, uint);\nuint la_objopen(Link_map*, Lmid_t, uintptr_t*);\nuint la_objclose(uintptr_t*);\nint la_objfilter(uintptr_t*, in char*, uintptr_t*, uint);\n\nversion (D_LP64)\n{\nuintptr_t la_amd64_pltenter(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, La_amd64_regs*, uint*, in char*);\nuintptr_t la_symbind64(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, uint*, in char*);\nuintptr_t la_sparcv9_pltenter(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, La_sparcv9_regs*, uint*, in char*);\nuintptr_t la_pltexit64(Elf64_Sym*, uint, uintptr_t*, uintptr_t*, uintptr_t, in char*);\n}\nelse\n{\nuintptr_t la_symbind32(Elf32_Sym*, uint, uintptr_t*, uintptr_t*, uint*);\nuintptr_t la_sparcv8_pltenter(Elf32_Sym*, uint, uintptr_t*, uintptr_t*, La_sparcv8_regs*, uint*);\nuintptr_t la_i86_pltenter(Elf32_Sym*, uint, uintptr_t*, uintptr_t*, La_i86_regs*, uint*);\nuintptr_t la_pltexit(Elf32_Sym*, uint, uintptr_t*, uintptr_t*, uintptr_t);\n}\n\ntemplate ElfW(string type)\n{\n    version (D_LP64)\n        mixin(\"alias Elf64_\"~type~\" ElfW;\");\n    else\n        mixin(\"alias Elf32_\"~type~\" ElfW;\");\n}\n\nstruct dl_phdr_info {\n    ElfW!\"Addr\"        dlpi_addr;\n    char*              dlpi_name;\n    ElfW!\"Phdr\"*       dlpi_phdr;\n    ElfW!\"Half\"        dlpi_phnum;\n    uint64_t           dlpi_adds;\n    uint64_t           dlpi_subs;\n};\n\nprivate alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;\nprivate alias extern(C) int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_cb_ngc;\nextern int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data);\nextern int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/sys/elf.d",
    "content": "/**\n * D header file for Solaris.\n *\n * $(LINK2 http://src.illumos.org/source/xref/illumos-gate/usr/src/uts/common/sys/elf_386.h, illumos sys/elf_386.h)\n */\nmodule core.sys.solaris.sys.elf;\n\nversion (Solaris):\nextern (C):\nnothrow:\n\npublic import core.sys.solaris.sys.elftypes;\n\nenum ELF32_FSZ_ADDR  = 4;\nenum ELF32_FSZ_HALF  = 2;\nenum ELF32_FSZ_OFF   = 4;\nenum ELF32_FSZ_SWORD = 4;\nenum ELF32_FSZ_WORD  = 4;\n\nenum ELF64_FSZ_ADDR   = 8;\nenum ELF64_FSZ_HALF   = 2;\nenum ELF64_FSZ_OFF    = 8;\nenum ELF64_FSZ_SWORD  = 4;\nenum ELF64_FSZ_WORD   = 4;\nenum ELF64_FSZ_SXWORD = 8;\nenum ELF64_FSZ_XWORD  = 8;\n\nenum EI_NIDENT = 16;\n\nstruct Elf32_Ehdr\n{\n    char[EI_NIDENT] e_ident;\n    Elf32_Half    e_type;\n    Elf32_Half    e_machine;\n    Elf32_Word    e_version;\n    Elf32_Addr    e_entry;\n    Elf32_Off     e_phoff;\n    Elf32_Off     e_shoff;\n    Elf32_Word    e_flags;\n    Elf32_Half    e_ehsize;\n    Elf32_Half    e_phentsize;\n    Elf32_Half    e_phnum;\n    Elf32_Half    e_shentsize;\n    Elf32_Half    e_shnum;\n    Elf32_Half    e_shstrndx;\n}\n\nstruct Elf64_Ehdr\n{\n    char[EI_NIDENT] e_ident;\n    Elf64_Half    e_type;\n    Elf64_Half    e_machine;\n    Elf64_Word    e_version;\n    Elf64_Addr    e_entry;\n    Elf64_Off     e_phoff;\n    Elf64_Off     e_shoff;\n    Elf64_Word    e_flags;\n    Elf64_Half    e_ehsize;\n    Elf64_Half    e_phentsize;\n    Elf64_Half    e_phnum;\n    Elf64_Half    e_shentsize;\n    Elf64_Half    e_shnum;\n    Elf64_Half    e_shstrndx;\n}\n\nenum EI_MAG0       = 0;\nenum EI_MAG1       = 1;\nenum EI_MAG2       = 2;\nenum EI_MAG3       = 3;\nenum EI_CLASS      = 4;\nenum EI_DATA       = 5;\nenum EI_VERSION    = 6;\nenum EI_OSABI      = 7;\nenum EI_ABIVERSION = 8;\nenum EI_PAD        = 9;\n\nenum ELFMAG0 = 0x7f;\nenum ELFMAG1 = 'E';\nenum ELFMAG2 = 'L';\nenum ELFMAG3 = 'F';\nenum ELFMAG  = \"\\177ELF\";\nenum SELFMAG = 4;\n\nenum ELFCLASSNONE = 0;\nenum ELFCLASS32   = 1;\nenum ELFCLASS64   = 2;\nenum ELFCLASSNUM  = 3;\n\nenum ELFDATANONE = 0;\nenum ELFDATA2LSB = 1;\nenum ELFDATA2MSB = 2;\nenum ELFDATANUM  = 3;\n\nenum ET_NONE       = 0;\nenum ET_REL        = 1;\nenum ET_EXEC       = 2;\nenum ET_DYN        = 3;\nenum ET_CORE       = 4;\nenum ET_NUM        = 5;\nenum ET_LOOS       = 0xfe00;\nenum ET_LOSUNW     = 0xfeff;\nenum ET_SUNWPSEUDO = 0xfeff;\nenum ET_HISUNW     = 0xfeff;\nenum ET_HIOS       = 0xfeff;\nenum ET_LOPROC     = 0xff00;\nenum ET_HIPROC     = 0xffff;\n\nenum EM_NONE        = 0;\nenum EM_M32         = 1;\nenum EM_SPARC       = 2;\nenum EM_386         = 3;\nenum EM_68K         = 4;\nenum EM_88K         = 5;\nenum EM_486         = 6;\nenum EM_860         = 7;\nenum EM_MIPS        = 8;\nenum EM_S370        = 9;\nenum EM_MIPS_RS3_LE = 10;\nenum EM_RS6000      = 11;\nenum EM_UNKNOWN12   = 12;\nenum EM_UNKNOWN13   = 13;\nenum EM_UNKNOWN14   = 14;\nenum EM_PA_RISC     = 15;\nenum EM_PARISC      = EM_PA_RISC;\nenum EM_nCUBE       = 16;\nenum EM_VPP500      = 17;\nenum EM_SPARC32PLUS = 18;\nenum EM_960         = 19;\nenum EM_PPC         = 20;\nenum EM_PPC64       = 21;\nenum EM_S390        = 22;\nenum EM_UNKNOWN22   = EM_S390;\nenum EM_UNKNOWN23   = 23;\nenum EM_UNKNOWN24   = 24;\nenum EM_UNKNOWN25   = 25;\nenum EM_UNKNOWN26   = 26;\nenum EM_UNKNOWN27   = 27;\nenum EM_UNKNOWN28   = 28;\nenum EM_UNKNOWN29   = 29;\nenum EM_UNKNOWN30   = 30;\nenum EM_UNKNOWN31   = 31;\nenum EM_UNKNOWN32   = 32;\nenum EM_UNKNOWN33   = 33;\nenum EM_UNKNOWN34   = 34;\nenum EM_UNKNOWN35   = 35;\nenum EM_V800        = 36;\nenum EM_FR20        = 37;\nenum EM_RH32        = 38;\nenum EM_RCE         = 39;\nenum EM_ARM         = 40;\nenum EM_ALPHA       = 41;\nenum EM_SH          = 42;\nenum EM_SPARCV9     = 43;\nenum EM_TRICORE     = 44;\nenum EM_ARC         = 45;\nenum EM_H8_300      = 46;\nenum EM_H8_300H     = 47;\nenum EM_H8S         = 48;\nenum EM_H8_500      = 49;\nenum EM_IA_64       = 50;\nenum EM_MIPS_X      = 51;\nenum EM_COLDFIRE    = 52;\nenum EM_68HC12      = 53;\nenum EM_MMA         = 54;\nenum EM_PCP         = 55;\nenum EM_NCPU        = 56;\nenum EM_NDR1        = 57;\nenum EM_STARCORE    = 58;\nenum EM_ME16        = 59;\nenum EM_ST100       = 60;\nenum EM_TINYJ       = 61;\nenum EM_AMD64       = 62;\nenum EM_X86_64      = EM_AMD64;\nenum EM_PDSP        = 63;\nenum EM_UNKNOWN64   = 64;\nenum EM_UNKNOWN65   = 65;\nenum EM_FX66        = 66;\nenum EM_ST9PLUS     = 67;\nenum EM_ST7         = 68;\nenum EM_68HC16      = 69;\nenum EM_68HC11      = 70;\nenum EM_68HC08      = 71;\nenum EM_68HC05      = 72;\nenum EM_SVX         = 73;\nenum EM_ST19        = 74;\nenum EM_VAX         = 75;\nenum EM_CRIS        = 76;\nenum EM_JAVELIN     = 77;\nenum EM_FIREPATH    = 78;\nenum EM_ZSP         = 79;\nenum EM_MMIX        = 80;\nenum EM_HUANY       = 81;\nenum EM_PRISM       = 82;\nenum EM_AVR         = 83;\nenum EM_FR30        = 84;\nenum EM_D10V        = 85;\nenum EM_D30V        = 86;\nenum EM_V850        = 87;\nenum EM_M32R        = 88;\nenum EM_MN10300     = 89;\nenum EM_MN10200     = 90;\nenum EM_PJ          = 91;\nenum EM_OPENRISC    = 92;\nenum EM_ARC_A5      = 93;\nenum EM_XTENSA      = 94;\nenum EM_NUM         = 95;\n\nenum EV_NONE    = 0;\nenum EV_CURRENT = 1;\nenum EV_NUM     = 2;\n\n\nenum ELFOSABI_NONE        = 0;\nenum ELFOSABI_SYSV        = ELFOSABI_NONE;\nenum ELFOSABI_HPUX        = 1;\nenum ELFOSABI_NETBSD      = 2;\nenum ELFOSABI_LINUX       = 3;\nenum ELFOSABI_UNKNOWN4    = 4;\nenum ELFOSABI_UNKNOWN5    = 5;\nenum ELFOSABI_SOLARIS     = 6;\nenum ELFOSABI_AIX         = 7;\nenum ELFOSABI_IRIX        = 8;\nenum ELFOSABI_FREEBSD     = 9;\nenum ELFOSABI_TRU64       = 10;\nenum ELFOSABI_MODESTO     = 11;\nenum ELFOSABI_OPENBSD     = 12;\nenum ELFOSABI_OPENVMS     = 13;\nenum ELFOSABI_NSK         = 14;\nenum ELFOSABI_AROS        = 15;\nenum ELFOSABI_ARM         = 97;\nenum ELFOSABI_STANDALONE  = 255;\nenum ELFOSABI_DRAGONFLYBSD= ELFOSABI_NONE;\n\nenum EAV_SUNW_NONE    = 0;\nenum EAV_SUNW_CURRENT = 1;\nenum EAV_SUNW_NUM     = 2;\n\nstruct Elf32_Phdr\n{\n    Elf32_Word    p_type;\n    Elf32_Off     p_offset;\n    Elf32_Addr    p_vaddr;\n    Elf32_Addr    p_paddr;\n    Elf32_Word    p_filesz;\n    Elf32_Word    p_memsz;\n    Elf32_Word    p_flags;\n    Elf32_Word    p_align;\n}\n\nstruct Elf64_Phdr\n{\n    Elf64_Word    p_type;\n    Elf64_Word    p_flags;\n    Elf64_Off     p_offset;\n    Elf64_Addr    p_vaddr;\n    Elf64_Addr    p_paddr;\n    Elf64_Xword   p_filesz;\n    Elf64_Xword   p_memsz;\n    Elf64_Xword   p_align;\n}\n\nenum PT_NULL    = 0;\nenum PT_LOAD    = 1;\nenum PT_DYNAMIC = 2;\nenum PT_INTERP  = 3;\nenum PT_NOTE    = 4;\nenum PT_SHLIB   = 5;\nenum PT_PHDR    = 6;\nenum PT_TLS     = 7;\nenum PT_NUM     = 8;\n\nenum PT_LOOS    = 0x60000000;\n\nenum PT_SUNW_UNWIND   = 0x6464e550;\nenum PT_SUNW_EH_FRAME = 0x6474e550;\nenum PT_GNU_EH_FRAME  = PT_SUNW_EH_FRAME;\n\nenum PT_GNU_STACK = 0x6474e551;\nenum PT_GNU_RELRO = 0x6474e552;\n\nenum PT_LOSUNW     = 0x6ffffffa;\nenum PT_SUNWBSS    = 0x6ffffffa;\nenum PT_SUNWSTACK  = 0x6ffffffb;\nenum PT_SUNWDTRACE = 0x6ffffffc;\nenum PT_SUNWCAP    = 0x6ffffffd;\nenum PT_HISUNW     = 0x6fffffff;\nenum PT_HIOS       = 0x6fffffff;\nenum PT_LOPROC     = 0x70000000;\nenum PT_HIPROC     = 0x7fffffff;\n\nenum PF_R = 0x4;\nenum PF_W = 0x2;\nenum PF_X = 0x1;\n\nenum PF_MASKOS   = 0x0ff00000;\nenum PF_MASKPROC = 0xf0000000;\n\nenum PF_SUNW_FAILURE = 0x00100000;\nenum PF_SUNW_KILLED  = 0x00200000;\nenum PF_SUNW_SIGINFO = 0x00400000;\n\nenum PN_XNUM = 0xffff;\n\nstruct Elf32_Shdr\n{\n    Elf32_Word    sh_name;\n    Elf32_Word    sh_type;\n    Elf32_Word    sh_flags;\n    Elf32_Addr    sh_addr;\n    Elf32_Off     sh_offset;\n    Elf32_Word    sh_size;\n    Elf32_Word    sh_link;\n    Elf32_Word    sh_info;\n    Elf32_Word    sh_addralign;\n    Elf32_Word    sh_entsize;\n}\n\nstruct Elf64_Shdr\n{\n    Elf64_Word    sh_name;\n    Elf64_Word    sh_type;\n    Elf64_Xword   sh_flags;\n    Elf64_Addr    sh_addr;\n    Elf64_Off     sh_offset;\n    Elf64_Xword   sh_size;\n    Elf64_Word    sh_link;\n    Elf64_Word    sh_info;\n    Elf64_Xword   sh_addralign;\n    Elf64_Xword   sh_entsize;\n}\n\nenum SHT_NULL          = 0;\nenum SHT_PROGBITS      = 1;\nenum SHT_SYMTAB        = 2;\nenum SHT_STRTAB        = 3;\nenum SHT_RELA          = 4;\nenum SHT_HASH          = 5;\nenum SHT_DYNAMIC       = 6;\nenum SHT_NOTE          = 7;\nenum SHT_NOBITS        = 8;\nenum SHT_REL           = 9;\nenum SHT_SHLIB         = 10;\nenum SHT_DYNSYM        = 11;\nenum SHT_UNKNOWN12     = 12;\nenum SHT_UNKNOWN13     = 13;\nenum SHT_INIT_ARRAY    = 14;\nenum SHT_FINI_ARRAY    = 15;\nenum SHT_PREINIT_ARRAY = 16;\nenum SHT_GROUP         = 17;\nenum SHT_SYMTAB_SHNDX  = 18;\nenum SHT_NUM           = 19;\n\nenum SHT_LOOS           = 0x60000000;\nenum SHT_LOSUNW         = 0x6fffffef;\nenum SHT_SUNW_capchain  = 0x6fffffef;\nenum SHT_SUNW_capinfo   = 0x6ffffff0;\nenum SHT_SUNW_symsort   = 0x6ffffff1;\nenum SHT_SUNW_tlssort   = 0x6ffffff2;\nenum SHT_SUNW_LDYNSYM   = 0x6ffffff3;\nenum SHT_SUNW_dof       = 0x6ffffff4;\nenum SHT_SUNW_cap       = 0x6ffffff5;\nenum SHT_SUNW_SIGNATURE = 0x6ffffff6;\nenum SHT_SUNW_ANNOTATE  = 0x6ffffff7;\nenum SHT_SUNW_DEBUGSTR  = 0x6ffffff8;\nenum SHT_SUNW_DEBUG     = 0x6ffffff9;\nenum SHT_SUNW_move      = 0x6ffffffa;\nenum SHT_SUNW_COMDAT    = 0x6ffffffb;\nenum SHT_SUNW_syminfo   = 0x6ffffffc;\nenum SHT_SUNW_verdef    = 0x6ffffffd;\nenum SHT_GNU_verdef     = SHT_SUNW_verdef;\nenum SHT_SUNW_verneed   = 0x6ffffffe;\nenum SHT_GNU_verneed    = SHT_SUNW_verneed;\nenum SHT_SUNW_versym    = 0x6fffffff;\nenum SHT_GNU_versym     = SHT_SUNW_versym;\nenum SHT_HISUNW         = 0x6fffffff;\nenum SHT_HIOS           = 0x6fffffff;\nenum SHT_GNU_ATTRIBUTES = 0x6ffffff5;\nenum SHT_GNU_HASH       = 0x6ffffff6;\nenum SHT_GNU_LIBLIST    = 0x6ffffff7;\nenum SHT_CHECKSUM       = 0x6ffffff8;\nenum SHT_LOPROC         = 0x70000000;\nenum SHT_HIPROC         = 0x7fffffff;\nenum SHT_LOUSER         = 0x80000000;\nenum SHT_HIUSER         = 0xffffffff;\n\nenum SHF_WRITE            = 0x01;\nenum SHF_ALLOC            = 0x02;\nenum SHF_EXECINSTR        = 0x04;\nenum SHF_MERGE            = 0x10;\nenum SHF_STRINGS          = 0x20;\nenum SHF_INFO_LINK        = 0x40;\nenum SHF_LINK_ORDER       = 0x80;\nenum SHF_OS_NONCONFORMING = 0x100;\nenum SHF_GROUP            = 0x200;\nenum SHF_TLS              = 0x400;\n\nenum SHF_MASKOS = 0x0ff00000;\n\nenum SHF_MASKPROC = 0xf0000000;\n\nenum SHN_UNDEF       = 0;\nenum SHN_LORESERVE   = 0xff00;\nenum SHN_LOPROC      = 0xff00;\nenum SHN_HIPROC      = 0xff1f;\nenum SHN_LOOS        = 0xff20;\nenum SHN_LOSUNW      = 0xff3f;\nenum SHN_SUNW_IGNORE = 0xff3f;\nenum SHN_HISUNW      = 0xff3f;\nenum SHN_HIOS        = 0xff3f;\nenum SHN_ABS         = 0xfff1;\nenum SHN_COMMON      = 0xfff2;\nenum SHN_XINDEX      = 0xffff;\nenum SHN_HIRESERVE   = 0xffff;\n\nstruct Elf32_Sym\n{\n    Elf32_Word    st_name;\n    Elf32_Addr    st_value;\n    Elf32_Word    st_size;\n    ubyte         st_info;\n    ubyte         st_other;\n    Elf32_Half    st_shndx;\n}\n\nstruct Elf64_Sym\n{\n    Elf64_Word    st_name;\n    ubyte         st_info;\n    ubyte         st_other;\n    Elf64_Half    st_shndx;\n    Elf64_Addr    st_value;\n    Elf64_Xword   st_size;\n}\n\nenum STN_UNDEF  = 0;\n\nextern (D)\n{\n    auto ELF32_ST_BIND(T)(T val) { return cast(ubyte)val >> 4; }\n    auto ELF32_ST_TYPE(T)(T val) { return val & 0xf; }\n    auto ELF32_ST_INFO(B, T)(B bind, T type) { return (bind << 4) + (type & 0xf); }\n    alias ELF32_ST_BIND ELF64_ST_BIND;\n    alias ELF32_ST_TYPE ELF64_ST_TYPE;\n    alias ELF32_ST_INFO ELF64_ST_INFO;\n}\n\nenum STB_LOCAL  = 0;\nenum STB_GLOBAL = 1;\nenum STB_WEAK   = 2;\nenum STB_NUM    = 3;\nenum STB_LOPROC = 13;\nenum STB_HIPROC = 15;\n\nenum STT_NOTYPE  = 0;\nenum STT_OBJECT  = 1;\nenum STT_FUNC    = 2;\nenum STT_SECTION = 3;\nenum STT_FILE    = 4;\nenum STT_COMMON  = 5;\nenum STT_TLS     = 6;\nenum STT_NUM     = 7;\nenum STT_LOOS    = 10;\nenum STT_HIOS    = 12;\nenum STT_LOPROC  = 13;\nenum STT_HIPROC  = 15;\n\nextern (D)\n{\n    auto ELF32_ST_VISIBILITY(O)(O o) { return o & 0x07; }\n    alias ELF32_ST_VISIBILITY ELF64_ST_VISIBILITY;\n}\n\nenum STV_DEFAULT   = 0;\nenum STV_INTERNAL  = 1;\nenum STV_HIDDEN    = 2;\nenum STV_PROTECTED = 3;\nenum STV_EXPORTED  = 4;\nenum STV_SINGLETON = 5;\nenum STV_ELIMINATE = 6;\nenum STV_NUM       = 7;\n\nstruct Elf32_Rel\n{\n    Elf32_Addr    r_offset;\n    Elf32_Word    r_info;\n}\n\nstruct Elf32_Rela\n{\n    Elf32_Addr    r_offset;\n    Elf32_Word    r_info;\n    Elf32_Sword   r_addend;\n}\n\nstruct Elf64_Rel\n{\n    Elf64_Addr    r_offset;\n    Elf64_Xword   r_info;\n}\n\nstruct Elf64_Rela\n{\n    Elf64_Addr    r_offset;\n    Elf64_Xword   r_info;\n    Elf64_Sxword  r_addend;\n}\n\nextern (D)\n{\n    auto ELF32_R_SYM(V)(V val) { return val >> 8; }\n    auto ELF32_R_TYPE(V)(V val) { return val & 0xff; }\n    auto ELF32_R_INFO(S, T)(S sym, T type) { return (sym << 8) + (type & 0xff); }\n\n    auto ELF64_R_SYM(I)(I i) { return i >> 32; }\n    auto ELF64_R_TYPE(I)(I i) { return i & 0xffffffff; }\n    auto ELF64_R_INFO(S, T)(S sym, T type) { return (sym << 32) + (type); }\n\n    auto ELF64_R_TYPE_DATA(I)(I i) { return (i << 32) >> 40; }\n    auto ELF64_R_TYPE_ID(I)(I i) { return (i << 56) >> 56; }\n    auto ELF64_R_TYPE_INFO(S, T)(S sym, T type) { return (sym <<8) + (type); }\n}\n\nenum GRP_COMDAT = 0x01;\n\nstruct Elf32_Nhdr\n{\n    Elf32_Word n_namesz;\n    Elf32_Word n_descsz;\n    Elf32_Word n_type;\n}\n\nstruct Elf64_Nhdr\n{\n    Elf64_Word n_namesz;\n    Elf64_Word n_descsz;\n    Elf64_Word n_type;\n}\n\nstruct Elf32_Move\n{\n    Elf32_Lword m_value;\n    Elf32_Word  m_info;\n    Elf32_Word  m_poffset;\n    Elf32_Half  m_repeat;\n    Elf32_Half  m_stride;\n}\n\nextern (D)\n{\n    auto ELF32_M_SYM(I)(I info) { return info >> 8; }\n    auto ELF32_M_SIZE(I)(I info) { return cast(ubyte)info; }\n    auto ELF32_M_INFO(S, SZ)(S sym, SZ size) { return (sym << 8) + cast(ubyte)size; }\n}\n\nstruct Elf64_Move\n{\n    Elf64_Lword m_value;\n    Elf64_Xword m_info;\n    Elf64_Xword m_poffset;\n    Elf64_Half  m_repeat;\n    Elf64_Half  m_stride;\n}\n\nalias ELF32_M_SYM ELF64_M_SYM;\nalias ELF32_M_SIZE ELF64_M_SIZE;\nalias ELF32_M_INFO ELF64_M_INFO;\n\nstruct Elf32_Cap\n{\n    Elf32_Word  c_tag;\n    union c_un\n    {\n        Elf32_Word  c_val;\n        Elf32_Addr  c_ptr;\n    }\n}\n\nalias Elf32_Word Elf32_Capinfo;\nalias Elf32_Word Elf32_Capchain;\n\n\nalias ELF32_M_SYM ELF32_C_SYM;\nalias ELF32_M_SIZE ELF32_C_GROUP;\nalias ELF32_M_INFO ELF32_C_INFO;\n\nstruct Elf64_Cap\n{\n    Elf64_Xword c_tag;\n    union c_un\n    {\n        Elf64_Xword c_val;\n        Elf64_Addr  c_ptr;\n    }\n}\n\nalias Elf64_Xword Elf64_Capinfo;\nalias Elf64_Word  Elf64_Capchain;\n\n/*\n *  Macros to compose and decompose values for capabilities info.\n *\n *  sym = ELF64_C_SYM(info)\n *  grp = ELF64_C_GROUP(info)\n *  info = ELF64_C_INFO(sym, grp)\n */\nextern (D)\n{\n    auto ELF64_C_SYM(I)(I info) { return info >> 32; }\n    auto ELF64_C_GROUP(I)(I info) { return cast(Elf64_Word)info; }\n    auto ELF64_C_INFO(S, G)(S sym, G grp) { return (sym << 32) + grp; }\n}\n\nenum CAPINFO_NONE    = 0;\nenum CAPINFO_CURRENT = 1;\nenum CAPINFO_NUM     = 2;\n\nenum CAPCHAIN_NONE    = 0;\nenum CAPCHAIN_CURRENT = 1;\nenum CAPCHAIN_NUM     = 2;\n\nenum CAPINFO_SUNW_GLOB = 0xff;\n\nenum CA_SUNW_NULL = 0;\nenum CA_SUNW_HW_1 = 1;\nenum CA_SUNW_SF_1 = 2;\nenum CA_SUNW_HW_2 = 3;\nenum CA_SUNW_PLAT = 4;\nenum CA_SUNW_MACH = 5;\nenum CA_SUNW_ID   = 6;\nenum CA_SUNW_NUM  = 7;\n\nenum SF1_SUNW_FPKNWN = 0x001;\nenum SF1_SUNW_FPUSED = 0x002;\nenum SF1_SUNW_ADDR32 = 0x004;\nenum SF1_SUNW_MASK   = 0x007;\n\nenum NT_PRSTATUS   = 1;\nenum NT_PRFPREG    = 2;\nenum NT_PRPSINFO   = 3;\nenum NT_PRXREG     = 4;\nenum NT_PLATFORM   = 5;\nenum NT_AUXV       = 6;\nenum NT_GWINDOWS   = 7;\nenum NT_ASRS       = 8;\nenum NT_LDT        = 9;\nenum NT_PSTATUS    = 10;\nenum NT_PSINFO     = 13;\nenum NT_PRCRED     = 14;\nenum NT_UTSNAME    = 15;\nenum NT_LWPSTATUS  = 16;\nenum NT_LWPSINFO   = 17;\nenum NT_PRPRIV     = 18;\nenum NT_PRPRIVINFO = 19;\nenum NT_CONTENT    = 20;\nenum NT_ZONENAME   = 21;\nenum NT_FDINFO     = 22;\nenum NT_SPYMASTER  = 23;\nenum NT_NUM        = 23;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/sys/elf_386.d",
    "content": "/**\n * D header file for Solaris.\n *\n * $(LINK2 http://src.illumos.org/source/xref/illumos-gate/usr/src/uts/common/sys/elf_386.h, illumos sys/elf_386.h)\n */\nmodule core.sys.solaris.sys.elf_386;\n\nversion (Solaris):\nextern (C):\nnothrow:\n\nenum R_386_NONE         = 0;\nenum R_386_32           = 1;\nenum R_386_PC32         = 2;\nenum R_386_GOT32        = 3;\nenum R_386_PLT32        = 4;\nenum R_386_COPY         = 5;\nenum R_386_GLOB_DAT     = 6;\nenum R_386_JMP_SLOT     = 7;\nenum R_386_RELATIVE     = 8;\nenum R_386_GOTOFF       = 9;\nenum R_386_GOTPC        = 10;\nenum R_386_32PLT        = 11;\nenum R_386_TLS_GD_PLT   = 12;\nenum R_386_TLS_LDM_PLT  = 13;\nenum R_386_TLS_TPOFF    = 14;\nenum R_386_TLS_IE       = 15;\nenum R_386_TLS_GOTIE    = 16;\nenum R_386_TLS_LE       = 17;\nenum R_386_TLS_GD       = 18;\nenum R_386_TLS_LDM      = 19;\nenum R_386_16           = 20;\nenum R_386_PC16         = 21;\nenum R_386_8            = 22;\nenum R_386_PC8          = 23;\nenum R_386_UNKNOWN24    = 24;\nenum R_386_UNKNOWN25    = 25;\nenum R_386_UNKNOWN26    = 26;\nenum R_386_UNKNOWN27    = 27;\nenum R_386_UNKNOWN28    = 28;\nenum R_386_UNKNOWN29    = 29;\nenum R_386_UNKNOWN30    = 30;\nenum R_386_UNKNOWN31    = 31;\nenum R_386_TLS_LDO_32   = 32;\nenum R_386_UNKNOWN33    = 33;\nenum R_386_UNKNOWN34    = 34;\nenum R_386_TLS_DTPMOD32 = 35;\nenum R_386_TLS_DTPOFF32 = 36;\nenum R_386_UNKNOWN37    = 37;\nenum R_386_SIZE32       = 38;\nenum R_386_NUM          = 39;\n\nenum ELF_386_MAXPGSZ = 0x10000;\n\nenum SHF_ORDERED = 0x40000000;\nenum SHF_EXCLUDE = 0x80000000;\n\nenum SHN_BEFORE = 0xff00;\nenum SHN_AFTER  = 0xff01;\n\nenum M_PLT_INSSIZE  = 6;\nenum M_PLT_XNumber  = 1;\nenum M_GOT_XDYNAMIC = 0;\nenum M_GOT_XLINKMAP = 1;\nenum M_GOT_XRTLD    = 2;\nenum M_GOT_XNumber  = 3;\n\nenum M32_WORD_ALIGN   = 4;\nenum M32_PLT_ENTSIZE  = 16;\nenum M32_PLT_ALIGN    = M32_WORD_ALIGN;\nenum M32_GOT_ENTSIZE  = 4;\nenum M32_PLT_RESERVSZ = (M_PLT_XNumber * M32_PLT_ENTSIZE);\n\nversion (_ELF64) {}\nelse\n{\n    enum M_WORD_ALIGN   = M32_WORD_ALIGN;\n    enum M_PLT_ENTSIZE  = M32_PLT_ENTSIZE;\n    enum M_PLT_ALIGN    = M32_PLT_ALIGN;\n    enum M_PLT_RESERVSZ = M32_PLT_RESERVSZ;\n    enum M_GOT_ENTSIZE  = M32_GOT_ENTSIZE;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d",
    "content": "/**\n * D header file for Solaris.\n *\n * $(LINK2 http://src.illumos.org/source/xref/illumos-gate/usr/src/uts/common/sys/elf_SPARC.h, illumos sys/elf_SPARC.h)\n */\nmodule core.sys.solaris.sys.elf_SPARC;\n\nversion (Solaris):\nextern (C):\nnothrow:\n\nenum EF_SPARC_32PLUS_MASK = 0xffff00;\nenum EF_SPARC_32PLUS      = 0x000100;\nenum EF_SPARC_EXT_MASK    = 0xffff00;\nenum EF_SPARC_SUN_US1     = 0x000200;\nenum EF_SPARC_HAL_R1      = 0x000400;\nenum EF_SPARC_SUN_US3     = 0x000800;\n\nenum EF_SPARCV9_MM  = 0x3;\nenum EF_SPARCV9_TSO = 0x0;\nenum EF_SPARCV9_PSO = 0x1;\nenum EF_SPARCV9_RMO = 0x2;\n\nenum R_SPARC_NONE             = 0;\nenum R_SPARC_8                = 1;\nenum R_SPARC_16               = 2;\nenum R_SPARC_32               = 3;\nenum R_SPARC_DISP8            = 4;\nenum R_SPARC_DISP16           = 5;\nenum R_SPARC_DISP32           = 6;\nenum R_SPARC_WDISP30          = 7;\nenum R_SPARC_WDISP22          = 8;\nenum R_SPARC_HI22             = 9;\nenum R_SPARC_22               = 10;\nenum R_SPARC_13               = 11;\nenum R_SPARC_LO10             = 12;\nenum R_SPARC_GOT10            = 13;\nenum R_SPARC_GOT13            = 14;\nenum R_SPARC_GOT22            = 15;\nenum R_SPARC_PC10             = 16;\nenum R_SPARC_PC22             = 17;\nenum R_SPARC_WPLT30           = 18;\nenum R_SPARC_COPY             = 19;\nenum R_SPARC_GLOB_DAT         = 20;\nenum R_SPARC_JMP_SLOT         = 21;\nenum R_SPARC_RELATIVE         = 22;\nenum R_SPARC_UA32             = 23;\nenum R_SPARC_PLT32            = 24;\nenum R_SPARC_HIPLT22          = 25;\nenum R_SPARC_LOPLT10          = 26;\nenum R_SPARC_PCPLT32          = 27;\nenum R_SPARC_PCPLT22          = 28;\nenum R_SPARC_PCPLT10          = 29;\nenum R_SPARC_10               = 30;\nenum R_SPARC_11               = 31;\nenum R_SPARC_64               = 32;\nenum R_SPARC_OLO10            = 33;\nenum R_SPARC_HH22             = 34;\nenum R_SPARC_HM10             = 35;\nenum R_SPARC_LM22             = 36;\nenum R_SPARC_PC_HH22          = 37;\nenum R_SPARC_PC_HM10          = 38;\nenum R_SPARC_PC_LM22          = 39;\nenum R_SPARC_WDISP16          = 40;\nenum R_SPARC_WDISP19          = 41;\nenum R_SPARC_GLOB_JMP         = 42;\nenum R_SPARC_7                = 43;\nenum R_SPARC_5                = 44;\nenum R_SPARC_6                = 45;\nenum R_SPARC_DISP64           = 46;\nenum R_SPARC_PLT64            = 47;\nenum R_SPARC_HIX22            = 48;\nenum R_SPARC_LOX10            = 49;\nenum R_SPARC_H44              = 50;\nenum R_SPARC_M44              = 51;\nenum R_SPARC_L44              = 52;\nenum R_SPARC_REGISTER         = 53;\nenum R_SPARC_UA64             = 54;\nenum R_SPARC_UA16             = 55;\nenum R_SPARC_TLS_GD_HI22      = 56;\nenum R_SPARC_TLS_GD_LO10      = 57;\nenum R_SPARC_TLS_GD_ADD       = 58;\nenum R_SPARC_TLS_GD_CALL      = 59;\nenum R_SPARC_TLS_LDM_HI22     = 60;\nenum R_SPARC_TLS_LDM_LO10     = 61;\nenum R_SPARC_TLS_LDM_ADD      = 62;\nenum R_SPARC_TLS_LDM_CALL     = 63;\nenum R_SPARC_TLS_LDO_HIX22    = 64;\nenum R_SPARC_TLS_LDO_LOX10    = 65;\nenum R_SPARC_TLS_LDO_ADD      = 66;\nenum R_SPARC_TLS_IE_HI22      = 67;\nenum R_SPARC_TLS_IE_LO10      = 68;\nenum R_SPARC_TLS_IE_LD        = 69;\nenum R_SPARC_TLS_IE_LDX       = 70;\nenum R_SPARC_TLS_IE_ADD       = 71;\nenum R_SPARC_TLS_LE_HIX22     = 72;\nenum R_SPARC_TLS_LE_LOX10     = 73;\nenum R_SPARC_TLS_DTPMOD32     = 74;\nenum R_SPARC_TLS_DTPMOD64     = 75;\nenum R_SPARC_TLS_DTPOFF32     = 76;\nenum R_SPARC_TLS_DTPOFF64     = 77;\nenum R_SPARC_TLS_TPOFF32      = 78;\nenum R_SPARC_TLS_TPOFF64      = 79;\nenum R_SPARC_GOTDATA_HIX22    = 80;\nenum R_SPARC_GOTDATA_LOX10    = 81;\nenum R_SPARC_GOTDATA_OP_HIX22 = 82;\nenum R_SPARC_GOTDATA_OP_LOX10 = 83;\nenum R_SPARC_GOTDATA_OP       = 84;\nenum R_SPARC_H34              = 85;\nenum R_SPARC_SIZE32           = 86;\nenum R_SPARC_SIZE64           = 87;\nenum R_SPARC_NUM              = 88;\n\nenum R_SPARC_L34 = R_SPARC_L44;\n\nenum ELF_SPARC_MAXPGSZ   = 0x10000;\nenum ELF_SPARCV9_MAXPGSZ = 0x100000;\n\nenum SHT_SPARC_GOTDATA = 0x70000000;\n\nenum SHF_ORDERED = 0x40000000;\nenum SHF_EXCLUDE = 0x80000000;\n\nenum SHN_BEFORE = 0xff00;\nenum SHN_AFTER  =  0xff01;\n\nenum STT_SPARC_REGISTER = 13;\n\nenum DT_SPARC_REGISTER = 0x70000001;\n\nenum STO_SPARC_REGISTER_G1 = 0x1;\nenum STO_SPARC_REGISTER_G2 = 0x2;\nenum STO_SPARC_REGISTER_G3 = 0x3;\nenum STO_SPARC_REGISTER_G4 = 0x4;\nenum STO_SPARC_REGISTER_G5 = 0x5;\nenum STO_SPARC_REGISTER_G6 = 0x6;\nenum STO_SPARC_REGISTER_G7 = 0x7;\n\nenum M_PLT_INSSIZE  = 4;\nenum M_PLT_XNumber  = 4;\nenum M_GOT_XDYNAMIC = 0;\nenum M_GOT_XNumber  = 1;\n\nenum M32_WORD_ALIGN   = 4;\nenum M32_PLT_ENTSIZE  = 12;\nenum M32_PLT_ALIGN    = M_WORD_ALIGN;\nenum M32_GOT_ENTSIZE  = 4;\nenum M32_GOT_MAXSMALL = 2048;\nenum M32_PLT_RESERVSZ = (M_PLT_XNumber * M32_PLT_ENTSIZE);\n\nenum M64_WORD_ALIGN   = 8;\nenum M64_PLT_ENTSIZE  = 32;\nenum M64_PLT_ALIGN    = 256;\nenum M64_GOT_ENTSIZE  = 8;\nenum M64_GOT_MAXSMALL = 1024;\nenum M64_PLT_RESERVSZ = (M_PLT_XNumber * M64_PLT_ENTSIZE);\n\nenum M64_PLT_NEARPLTS = 0x8000;\nenum M64_PLT_FENTSIZE = 24;\nenum M64_PLT_PSIZE    = 8;\nenum M64_PLT_FBLKCNTS = 160;\nenum M64_PLT_FBLOCKSZ = (M64_PLT_FBLKCNTS * M64_PLT_ENTSIZE);\n\nversion (_ELF64)\n{\n    enum M_WORD_ALIGN   = M64_WORD_ALIGN;\n    enum M_PLT_ENTSIZE  = M64_PLT_ENTSIZE;\n    enum M_PLT_ALIGN    = M64_PLT_ALIGN;\n    enum M_PLT_RESERVSZ = M64_PLT_RESERVSZ;\n    enum M_GOT_ENTSIZE  = M64_GOT_ENTSIZE;\n    enum M_GOT_MAXSMALL = M64_GOT_MAXSMALL;\n}\nelse\n{\n    enum M_WORD_ALIGN   = M32_WORD_ALIGN;\n    enum M_PLT_ENTSIZE  = M32_PLT_ENTSIZE;\n    enum M_PLT_ALIGN    = M32_PLT_ALIGN;\n    enum M_PLT_RESERVSZ = M32_PLT_RESERVSZ;\n    enum M_GOT_ENTSIZE  = M32_GOT_ENTSIZE;\n    enum M_GOT_MAXSMALL = M32_GOT_MAXSMALL;\n}"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/sys/elf_amd64.d",
    "content": "/**\n * D header file for Solaris.\n *\n * $(LINK2 http://src.illumos.org/source/xref/illumos-gate/usr/src/uts/common/sys/elf_amd64.h, illumos sys/elf_amd64.h)\n */\nmodule core.sys.solaris.sys.elf_amd64;\n\nversion (Solaris):\nextern (C):\nnothrow:\n\npublic import core.sys.solaris.sys.elf_386;\n\nenum R_AMD64_NONE       = 0;\nenum R_AMD64_64         = 1;\nenum R_AMD64_PC32       = 2;\nenum R_AMD64_GOT32      = 3;\nenum R_AMD64_PLT32      = 4;\nenum R_AMD64_COPY       = 5;\nenum R_AMD64_GLOB_DAT   = 6;\nenum R_AMD64_JUMP_SLOT  = 7;\nenum R_AMD64_RELATIVE   = 8;\nenum R_AMD64_GOTPCREL   = 9;\nenum R_AMD64_32         = 10;\nenum R_AMD64_32S        = 11;\nenum R_AMD64_16         = 12;\nenum R_AMD64_PC16       = 13;\nenum R_AMD64_8          = 14;\nenum R_AMD64_PC8        = 15;\nenum R_AMD64_DTPMOD64   = 16;\nenum R_AMD64_DTPOFF64   = 17;\nenum R_AMD64_TPOFF64    = 18;\nenum R_AMD64_TLSGD      = 19;\nenum R_AMD64_TLSLD      = 20;\nenum R_AMD64_DTPOFF32   = 21;\nenum R_AMD64_GOTTPOFF   = 22;\nenum R_AMD64_TPOFF32    = 23;\nenum R_AMD64_PC64       = 24;\nenum R_AMD64_GOTOFF64   = 25;\nenum R_AMD64_GOTPC32    = 26;\nenum R_AMD64_GOT64      = 27;\nenum R_AMD64_GOTPCREL64 = 28;\nenum R_AMD64_GOTPC64    = 29;\nenum R_AMD64_GOTPLT64   = 30;\nenum R_AMD64_PLTOFF64   = 31;\nenum R_AMD64_SIZE32     = 32;\nenum R_AMD64_SIZE64     = 33;\nenum R_AMD64_NUM        = 34;\n\n\nenum R_X86_64_NONE       = R_AMD64_NONE;\nenum R_X86_64_64         = R_AMD64_64;\nenum R_X86_64_PC32       = R_AMD64_PC32;\nenum R_X86_64_GOT32      = R_AMD64_GOT32;\nenum R_X86_64_PLT32      = R_AMD64_PLT32;\nenum R_X86_64_COPY       = R_AMD64_COPY;\nenum R_X86_64_GLOB_DAT   = R_AMD64_GLOB_DAT;\nenum R_X86_64_JUMP_SLOT  = R_AMD64_JUMP_SLOT;\nenum R_X86_64_RELATIVE   = R_AMD64_RELATIVE;\nenum R_X86_64_GOTPCREL   = R_AMD64_GOTPCREL;\nenum R_X86_64_32         = R_AMD64_32;\nenum R_X86_64_32S        = R_AMD64_32S;\nenum R_X86_64_16         = R_AMD64_16;\nenum R_X86_64_PC16       = R_AMD64_PC16;\nenum R_X86_64_8          = R_AMD64_8;\nenum R_X86_64_PC8        = R_AMD64_PC8;\nenum R_X86_64_DTPMOD64   = R_AMD64_DTPMOD64;\nenum R_X86_64_DTPOFF64   = R_AMD64_DTPOFF64;\nenum R_X86_64_TPOFF64    = R_AMD64_TPOFF64;\nenum R_X86_64_TLSGD      = R_AMD64_TLSGD;\nenum R_X86_64_TLSLD      = R_AMD64_TLSLD;\nenum R_X86_64_DTPOFF32   = R_AMD64_DTPOFF32;\nenum R_X86_64_GOTTPOFF   = R_AMD64_GOTTPOFF;\nenum R_X86_64_TPOFF32    = R_AMD64_TPOFF32;\nenum R_X86_64_PC64       = R_AMD64_PC64;\nenum R_X86_64_GOTPC32    = R_AMD64_GOTPC32;\nenum R_X86_64_GOTOFF64   = R_AMD64_GOTOFF64;\nenum R_X86_64_GOT64      = R_AMD64_GOT64;\nenum R_X86_64_GOTPCREL64 = R_AMD64_GOTPCREL64;\nenum R_X86_64_GOTPC64    = R_AMD64_GOTPC64;\nenum R_X86_64_GOTPLT64   = R_AMD64_GOTPLT64;\nenum R_X86_64_PLTOFF64   = R_AMD64_PLTOFF64;\nenum R_X86_64_SIZE32     = R_AMD64_SIZE32;\nenum R_X86_64_SIZE64     = R_AMD64_SIZE64;\nenum R_X86_64_NUM        = R_AMD64_NUM;\n\nenum ELF_AMD64_MAXPGSZ = 0x100000;\n\nenum SHT_AMD64_UNWIND   = 0x70000001;\nenum SHT_X86_64_UNWIND  = SHT_AMD64_UNWIND;\n\nenum SHF_AMD64_LARGE  = 0x10000000;\nenum SHF_X86_64_LARGE = SHF_AMD64_LARGE;\n\nenum SHN_AMD64_LCOMMON  = 0xff02;\nenum SHN_X86_64_LCOMMON = SHN_AMD64_LCOMMON;\n\nenum M64_WORD_ALIGN   = 8;\nenum M64_PLT_ENTSIZE  = M32_PLT_ENTSIZE;\nenum M64_PLT_ALIGN    = M64_WORD_ALIGN;\nenum M64_GOT_ENTSIZE  = 8;\nenum M64_PLT_RESERVSZ = M32_PLT_RESERVSZ;\n\nversion (_ELF64)\n{\n    enum M_WORD_ALIGN   = M64_WORD_ALIGN;\n    enum M_PLT_ENTSIZE  = M64_PLT_ENTSIZE;\n    enum M_PLT_ALIGN    = M64_PLT_ALIGN;\n    enum M_PLT_RESERVSZ = M64_PLT_RESERVSZ;\n    enum M_GOT_ENTSIZE  = M64_GOT_ENTSIZE;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/sys/elf_notes.d",
    "content": "/**\n * D header file for Solaris.\n *\n * $(LINK2 http://src.illumos.org/source/xref/illumos-gate/usr/src/uts/common/sys/elf_notes.h, illumos sys/elf_notes.h)\n */\nmodule core.sys.solaris.sys.elf_notes;\n\nversion (Solaris):\nextern (C):\nnothrow:\n\nenum ELF_NOTE_SOLARIS = \"SUNW Solaris\";\n\nenum ELF_NOTE_PAGESIZE_HINT = 1;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/sys/elftypes.d",
    "content": "/**\n * D header file for Solaris.\n *\n * $(LINK2 http://src.illumos.org/source/xref/illumos-gate/usr/src/uts/common/sys/elftypes.h, illumos sys/elftypes.h)\n */\nmodule core.sys.solaris.sys.elftypes;\n\nversion (Solaris):\nextern (C):\nnothrow:\n\nimport core.stdc.stdint;\n\nalias uint32_t Elf32_Addr;\nalias uint16_t Elf32_Half;\nalias uint32_t Elf32_Off;\nalias int32_t  Elf32_Sword;\nalias uint32_t Elf32_Word;\n\nalias uint64_t Elf64_Addr;\nalias uint16_t Elf64_Half;\nalias uint64_t Elf64_Off;\nalias int32_t  Elf64_Sword;\nalias int64_t  Elf64_Sxword;\nalias uint32_t Elf64_Word;\nalias uint64_t Elf64_Xword;\nalias uint64_t Elf64_Lword;\nalias uint64_t Elf32_Lword;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/sys/link.d",
    "content": "/**\n * D header file for Solaris.\n *\n * $(LINK2 http://src.illumos.org/source/xref/illumos-gate/usr/src/uts/common/sys/link.h, illumos sys/link.h)\n */\nmodule core.sys.solaris.sys.link;\n\nversion (Solaris):\nextern (C):\nnothrow:\n\npublic import core.sys.solaris.sys.elftypes;\nimport core.stdc.config;\n\nstruct Elf32_Dyn\n{\n    Elf32_Sword d_tag;\n    union d_un\n    {\n        Elf32_Word d_val;\n        Elf32_Addr d_ptr;\n        Elf32_Off  d_off;\n    }\n}\n\nstruct Elf64_Dyn\n{\n    Elf64_Xword d_tag;\n    union d_un\n    {\n        Elf64_Xword d_val;\n        Elf64_Addr  d_ptr;\n    }\n}\n\nenum DT_NULL         = 0;\nenum DT_NEEDED       = 1;\nenum DT_PLTRELSZ     = 2;\nenum DT_PLTGOT       = 3;\nenum DT_HASH         = 4;\nenum DT_STRTAB       = 5;\nenum DT_SYMTAB       = 6;\nenum DT_RELA         = 7;\nenum DT_RELASZ       = 8;\nenum DT_RELAENT      = 9;\nenum DT_STRSZ        = 10;\nenum DT_SYMENT       = 11;\nenum DT_INIT         = 12;\nenum DT_FINI         = 13;\nenum DT_SONAME       = 14;\nenum DT_RPATH        = 15;\nenum DT_SYMBOLIC     = 16;\nenum DT_REL          = 17;\nenum DT_RELSZ        = 18;\nenum DT_RELENT       = 19;\nenum DT_PLTREL       = 20;\nenum DT_DEBUG        = 21;\nenum DT_TEXTREL      = 22;\nenum DT_JMPREL       = 23;\nenum DT_BIND_NOW     = 24;\nenum DT_INIT_ARRAY   = 25;\nenum DT_FINI_ARRAY   = 26;\nenum DT_INIT_ARRAYSZ = 27;\nenum DT_FINI_ARRAYSZ = 28;\nenum DT_RUNPATH      = 29;\nenum DT_FLAGS        = 30;\n\nenum DT_ENCODING        = 32;\nenum DT_PREINIT_ARRAY   = 32;\nenum DT_PREINIT_ARRAYSZ = 33;\n\nenum DT_MAXPOSTAGS = 34;\n\nenum DT_LOOS           = 0x6000000d;\nenum DT_SUNW_AUXILIARY = 0x6000000d;\nenum DT_SUNW_RTLDINF   = 0x6000000e;\nenum DT_SUNW_FILTER    = 0x6000000f;\nenum DT_SUNW_CAP       = 0x60000010;\nenum DT_SUNW_SYMTAB    = 0x60000011;\nenum DT_SUNW_SYMSZ     = 0x60000012;\n\nenum DT_SUNW_ENCODING    = 0x60000013;\nenum DT_SUNW_SORTENT     = 0x60000013;\nenum DT_SUNW_SYMSORT     = 0x60000014;\nenum DT_SUNW_SYMSORTSZ   = 0x60000015;\nenum DT_SUNW_TLSSORT     = 0x60000016;\nenum DT_SUNW_TLSSORTSZ   = 0x60000017;\nenum DT_SUNW_CAPINFO     = 0x60000018;\nenum DT_SUNW_STRPAD      = 0x60000019;\nenum DT_SUNW_CAPCHAIN    = 0x6000001a;\nenum DT_SUNW_LDMACH      = 0x6000001b;\nenum DT_SUNW_CAPCHAINENT = 0x6000001d;\nenum DT_SUNW_CAPCHAINSZ  = 0x6000001f;\n\nenum DT_HIOS = 0x6ffff000;\n\nenum DT_DEPRECATED_SPARC_REGISTER = 0x7000001;\n\nenum DT_VALRNGLO = 0x6ffffd00;\n\nenum DT_GNU_PRELINKED  = 0x6ffffdf5;\nenum DT_GNU_CONFLICTSZ = 0x6ffffdf6;\nenum DT_GNU_LIBLISTSZ  = 0x6ffffdf7;\nenum DT_CHECKSUM       = 0x6ffffdf8;\nenum DT_PLTPADSZ       = 0x6ffffdf9;\nenum DT_MOVEENT        = 0x6ffffdfa;\nenum DT_MOVESZ         = 0x6ffffdfb;\nenum DT_FEATURE_1      = 0x6ffffdfc;\nenum DT_POSFLAG_1      = 0x6ffffdfd;\nenum DT_SYMINSZ        = 0x6ffffdfe;\nenum DT_SYMINENT       = 0x6ffffdff;\nenum DT_VALRNGHI       = 0x6ffffdff;\n\nenum DT_ADDRRNGLO = 0x6ffffe00;\n\nenum DT_GNU_HASH     = 0x6ffffef5;\nenum DT_TLSDESC_PLT  = 0x6ffffef6;\nenum DT_TLSDESC_GOT  = 0x6ffffef7;\nenum DT_GNU_CONFLICT = 0x6ffffef8;\nenum DT_GNU_LIBLIST  = 0x6ffffef9;\n\nenum DT_CONFIG    = 0x6ffffefa;\nenum DT_DEPAUDIT  = 0x6ffffefb;\nenum DT_AUDIT     = 0x6ffffefc;\nenum DT_PLTPAD    = 0x6ffffefd;\nenum DT_MOVETAB   = 0x6ffffefe;\nenum DT_SYMINFO   = 0x6ffffeff;\nenum DT_ADDRRNGHI = 0x6ffffeff;\n\nenum DT_VERSYM = 0x6ffffff0;\n\nenum DT_RELACOUNT  = 0x6ffffff9;\nenum DT_RELCOUNT   = 0x6ffffffa;\nenum DT_FLAGS_1    = 0x6ffffffb;\nenum DT_VERDEF     = 0x6ffffffc;\nenum DT_VERDEFNUM  = 0x6ffffffd;\nenum DT_VERNEED    = 0x6ffffffe;\nenum DT_VERNEEDNUM = 0x6fffffff;\n\nenum DT_LOPROC    = 0x70000000;\nenum DT_AUXILIARY = 0x7ffffffd;\nenum DT_USED      = 0x7ffffffe;\nenum DT_FILTER    = 0x7fffffff;\nenum DT_HIPROC    = 0x7fffffff;\n\nenum DF_ORIGIN     = 0x00000001;\nenum DF_SYMBOLIC   = 0x00000002;\nenum DF_TEXTREL    = 0x00000004;\nenum DF_BIND_NOW   = 0x00000008;\nenum DF_STATIC_TLS = 0x00000010;\n\nenum DF_P1_LAZYLOAD  = 0x00000001;\nenum DF_P1_GROUPPERM = 0x00000002;\nenum DF_P1_DEFERRED  = 0x00000004;\n\nenum DF_1_NOW        = 0x00000001;\nenum DF_1_GLOBAL     = 0x00000002;\nenum DF_1_GROUP      = 0x00000004;\nenum DF_1_NODELETE   = 0x00000008;\nenum DF_1_LOADFLTR   = 0x00000010;\nenum DF_1_INITFIRST  = 0x00000020;\nenum DF_1_NOOPEN     = 0x00000040;\nenum DF_1_ORIGIN     = 0x00000080;\nenum DF_1_DIRECT     = 0x00000100;\nenum DF_1_TRANS      = 0x00000200;\nenum DF_1_INTERPOSE  = 0x00000400;\nenum DF_1_NODEFLIB   = 0x00000800;\nenum DF_1_NODUMP     = 0x00001000;\nenum DF_1_CONFALT    = 0x00002000;\nenum DF_1_ENDFILTEE  = 0x00004000;\nenum DF_1_DISPRELDNE = 0x00008000;\nenum DF_1_DISPRELPND = 0x00010000;\nenum DF_1_NODIRECT   = 0x00020000;\nenum DF_1_IGNMULDEF  = 0x00040000;\nenum DF_1_NOKSYMS    = 0x00080000;\nenum DF_1_NOHDR      = 0x00100000;\nenum DF_1_EDITED     = 0x00200000;\nenum DF_1_NORELOC    = 0x00400000;\nenum DF_1_SYMINTPOSE = 0x00800000;\nenum DF_1_GLOBAUDIT  = 0x01000000;\nenum DF_1_SINGLETON  = 0x02000000;\n\nenum DTF_1_PARINIT = 0x00000001;\nenum DTF_1_CONFEXP = 0x00000002;\n\nstruct Elf32_Verdef\n{\n    Elf32_Half  vd_version;\n    Elf32_Half  vd_flags;\n    Elf32_Half  vd_ndx;\n    Elf32_Half  vd_cnt;\n    Elf32_Word  vd_hash;\n    Elf32_Word  vd_aux;\n    Elf32_Word  vd_next;\n}\n\nstruct Elf32_Verdaux\n{\n    Elf32_Word  vda_name;\n    Elf32_Word  vda_next;\n}\n\nstruct Elf32_Verneed\n{\n    Elf32_Half  vn_version;\n    Elf32_Half  vn_cnt;\n    Elf32_Word  vn_file;\n    Elf32_Word  vn_aux;\n    Elf32_Word  vn_next;\n}\n\nstruct Elf32_Vernaux\n{\n    Elf32_Word  vna_hash;\n    Elf32_Half  vna_flags;\n    Elf32_Half  vna_other;\n    Elf32_Word  vna_name;\n    Elf32_Word  vna_next;\n}\n\nalias Elf32_Half  Elf32_Versym;\n\nstruct Elf32_Syminfo\n{\n    Elf32_Half  si_boundto;\n    Elf32_Half  si_flags;\n}\n\nstruct Elf64_Verdef\n{\n    Elf64_Half  vd_version;\n    Elf64_Half  vd_flags;\n    Elf64_Half  vd_ndx;\n    Elf64_Half  vd_cnt;\n    Elf64_Word  vd_hash;\n    Elf64_Word  vd_aux;\n    Elf64_Word  vd_next;\n}\n\nstruct Elf64_Verdaux\n{\n    Elf64_Word  vda_name;\n    Elf64_Word  vda_next;\n}\n\nstruct Elf64_Verneed\n{\n    Elf64_Half  vn_version;\n    Elf64_Half  vn_cnt;\n    Elf64_Word  vn_file;\n    Elf64_Word  vn_aux;\n    Elf64_Word  vn_next;\n}\n\nstruct Elf64_Vernaux\n{\n    Elf64_Word  vna_hash;\n    Elf64_Half  vna_flags;\n    Elf64_Half  vna_other;\n    Elf64_Word  vna_name;\n    Elf64_Word  vna_next;\n}\n\nalias Elf64_Half  Elf64_Versym;\n\nstruct Elf64_Syminfo\n{\n    Elf64_Half  si_boundto;\n    Elf64_Half  si_flags;\n}\n\nenum VER_NDX_LOCAL     = 0;\nenum VER_NDX_GLOBAL    = 1;\nenum VER_NDX_LORESERVE = 0xff00;\nenum VER_NDX_ELIMINATE = 0xff01;\n\nenum VER_FLG_BASE = 0x1;\nenum VER_FLG_WEAK = 0x2;\nenum VER_FLG_INFO = 0x4;\n\nenum VER_DEF_NONE    = 0;\nenum VER_DEF_CURRENT = 1;\nenum VER_DEF_NUM     = 2;\n\nenum VER_NEED_NONE    = 0;\nenum VER_NEED_CURRENT = 1;\nenum VER_NEED_NUM     = 2;\n\nenum SYMINFO_FLG_DIRECT      = 0x0001;\nenum SYMINFO_FLG_FILTER      = 0x0002;\nenum SYMINFO_FLG_PASSTHRU    = SYMINFO_FLG_FILTER;\nenum SYMINFO_FLG_COPY        = 0x0004;\nenum SYMINFO_FLG_LAZYLOAD    = 0x0008;\nenum SYMINFO_FLG_DIRECTBIND  = 0x0010;\nenum SYMINFO_FLG_NOEXTDIRECT = 0x0020;\nenum SYMINFO_FLG_AUXILIARY   = 0x0040;\nenum SYMINFO_FLG_INTERPOSE   = 0x0080;\nenum SYMINFO_FLG_CAP         = 0x0100;\nenum SYMINFO_FLG_DEFERRED    = 0x0200;\n\nenum SYMINFO_BT_SELF       = 0xffff;\nenum SYMINFO_BT_PARENT     = 0xfffe;\nenum SYMINFO_BT_NONE       = 0xfffd;\nenum SYMINFO_BT_EXTERN     = 0xfffc;\nenum SYMINFO_BT_LOWRESERVE = 0xff00;\n\nenum SYMINFO_NONE    = 0;\nenum SYMINFO_CURRENT = 1;\nenum SYMINFO_NUM     = 2;\n\nalias link_map Link_map;\n\nstruct link_map\n{\n    c_ulong  l_addr;\n    char*    l_name;\n    version (D_LP64)\n        Elf64_Dyn*  l_ld;\n    else\n        Elf32_Dyn*  l_ld;\n    Link_map*  l_next;\n    Link_map*  l_prev;\n    char*      l_refname;\n}\n\nversion (_SYSCALL32)\n{\nalias link_map32 Link_map32;\n\nstruct link_map32\n{\n    Elf32_Word  l_addr;\n    Elf32_Addr  l_name;\n    Elf32_Addr  l_ld;\n    Elf32_Addr  l_next;\n    Elf32_Addr  l_prev;\n    Elf32_Addr  l_refname;\n}\n}\n\nenum r_state_e\n{\n    RT_CONSISTENT,\n    RT_ADD,\n    RT_DELETE\n}\n\nenum rd_flags_e\n{\n    RD_FL_NONE = 0,\n    RD_FL_ODBG = (1<<0),\n    RD_FL_DBG  = (1<<1)\n}\n\nenum rd_event_e\n{\n    RD_NONE = 0,\n    RD_PREINIT,\n    RD_POSTINIT,\n    RD_DLACTIVITY\n}\n\nstruct r_debug\n{\n    int         r_version;\n    Link_map*   r_map;\n    c_ulong     r_brk;\n    r_state_e   r_state;\n    c_ulong     r_ldbase;\n    Link_map*   r_ldsomap;\n    rd_event_e  r_rdevent;\n    rd_flags_e  r_flags;\n}\n\nversion (_SYSCALL32)\n{\nstruct r_debug32\n{\n    Elf32_Word  r_version;\n    Elf32_Addr  r_map;\n    Elf32_Word  r_brk;\n    r_state_e   r_state;\n    Elf32_Word  r_ldbase;\n    Elf32_Addr  r_ldsomap;\n    rd_event_e  r_rdevent;\n    rd_flags_e  r_flags;\n}\n}\n\nenum R_DEBUG_VERSION = 2;\n\nstruct Elf32_Boot\n{\n    Elf32_Sword eb_tag;\n    union eb_un\n    {\n        Elf32_Word eb_val;\n        Elf32_Addr eb_ptr;\n        Elf32_Off  eb_off;\n    }\n}\n\nstruct Elf64_Boot\n{\n    Elf64_Xword eb_tag;\n    union eb_un\n    {\n        Elf64_Xword eb_val;\n        Elf64_Addr eb_ptr;\n        Elf64_Off eb_off;\n    }\n}\n\nenum EB_NULL       = 0;\nenum EB_DYNAMIC    = 1;\nenum EB_LDSO_BASE  = 2;\nenum EB_ARGV       = 3;\nenum EB_ENVP       = 4;\nenum EB_AUXV       = 5;\nenum EB_DEVZERO    = 6;\nenum EB_PAGESIZE   = 7;\nenum EB_MAX        = 8;\nenum EB_MAX_SIZE32 = 64;\nenum EB_MAX_SIZE64 = 128;\n\nvoid _ld_libc(void *);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/sys/priocntl.d",
    "content": "/**\n * D header file for the Solaris priocntl(2) and priocntlset(2) functions.\n *\n * Copyright:   Copyright 2014 Jason King.\n * License:     $(HTTP www.boost.org/LICENSE_1.0.txt, Boost License 1.0).\n * Authors:     Jason King\n */\n\n/*\n * Copyright 2014 Jason King.\n * Distributed under the Boost Software License, Version 1.0.\n * See accompanying file LICENSE or copy at\n *  http://www.boost.org/LICENSE_1_0.txt\n */\nmodule core.sys.solaris.sys.priocntl;\n\nversion (Solaris):\nnothrow:\n@nogc:\nextern (C):\n\nimport core.sys.posix.sys.types : caddr_t, id_t;\nimport core.sys.posix.sys.wait : idtype_t;\nimport core.stdc.config : c_long;\nimport core.sys.solaris.sys.procset;\nimport core.sys.solaris.sys.types : pri_t;\n\nc_long priocntl(idtype_t, id_t, int, ...);\nc_long priocntlset(procset_t*, int, ...);\n\n\nenum PC_GETCID       = 0;       /* Get class ID */\nenum PC_GETCLINFO    = 1;       /* Get info about a configured class */\nenum PC_SETPARMS     = 2;       /* Set scheduling parameters */\nenum PC_GETPARMS     = 3;       /* Get scheduling parameters */\nenum PC_ADMIN        = 4;       /* Scheduler administration (used by */\n                                /* dispadmin(1M), not for general use) */\nenum PC_GETPRIRANGE  = 5;       /* Get priority range for a class */\n                                /* posix.4; scheduling, not for general use */\nenum PC_DONICE       = 6;       /* Set or get nice value */\nenum PC_SETXPARMS    = 7;       /* Set extended scheduling parameters */\nenum PC_GETXPARMS    = 8;       /* Get extended scheduling parameters */\nenum PC_SETDFLCL     = 9;       /* Set default class, not for general use */\nenum PC_GETDFLCL     = 10;      /* Get default class, not for general use */\nenum PC_DOPRIO       = 11;      /* Set or get priority, not for general use */\n\nenum PC_CLNULL       = -1;\n\nenum PC_CLNMSZ       = 16;\nenum PC_CLINFOSZ     = (32 / int.sizeof);\nenum PC_CLPARMSZ     = (32 / int.sizeof);\n\nenum PC_GETNICE = 0;\nenum PC_SETNICE = 1;\n\nenum PC_GETPRIO      = 0;\nenum PC_SETPRIO      = 1;\n\nstruct pcinfo_t\n{\n    id_t                pc_cid;     // class id\n    char[PC_CLNMSZ]     pc_clname;  // class name\n    int[PC_CLINFOSZ]    pc_clinfo;  // class information\n}\n\nstruct pcparms_t\n{\n    id_t                pc_cid;     // process class\n    int[PC_CLPARMSZ]    pc_clparms; //class specific parameters\n}\n\nstruct pcnice_t\n{\n    int pc_val; // nice value\n    int pc_op;  // type of operation, set or get\n}\n\nstruct pcprio_t\n{\n    int     pc_op;  // type of operation, set or get\n    id_t    pc_cid; // class id\n    int     pc_val; // priority value\n}\n\n// Used by the priocntl varargs interface\n// PC_SETXPARMS and PC_GETXPARMS\nenum PC_VAPARMCNT = 8;  // max # of kv pairs\nenum PC_KY_NULL   = 0;  // kv chain terminator\nenum PC_KY_CLNAME = 1;  // get the class name of a process or LWP\n\nstruct pc_vaparm_t\n{\n    int     pc_key;\n    ulong   pc_parm;\n}\n\nstruct pc_vaparms_t\n{\n    int                         pc_vaparmscnt; // # of kv pairs\n    pc_vaparm_t[PC_VAPARMCNT]   pc_parm;\n}\n\n// Not for general use\nstruct pcpri_t\n{\n    id_t    pc_cid;\n    pri_t   pc_clpmax;\n    pri_t   pc_clpmin;\n}\n\nstruct pcadmin_t\n{\n    id_t    pc_cid;\n    caddr_t pc_cladmin;\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/sys/procset.d",
    "content": "/**\n * D header file defining a process set.\n *\n * Copyright:   Copyright 2014 Jason King.\n * License:     $(HTTP www.boost.org/LICENSE_1.0.txt, Boost License 1.0).\n * Authors:     Jason King\n */\n\n/*\n * Copyright 2014 Jason King.\n * Distributed under the Boost Software License, Version 1.0.\n * See accompanying file LICENSE or copy at\n *  http://www.boost.org/LICENSE_1_0.txt\n */\nmodule core.sys.solaris.sys.procset;\n\nversion (Solaris):\nnothrow:\n@nogc:\n\nimport core.sys.posix.sys.types : id_t;\nimport core.sys.posix.sys.wait : idtype_t;\n\nenum P_INITPID  = 1;\nenum P_INITUID  = 0;\nenum P_INITPGID = 0;\n\nenum idop_t\n{\n    POP_DIFF,\n    POP_AND,\n    POP_OR,\n    POP_XOR\n}\n\nstruct procset_t\n{\n    idop_t      p_op;\n    idtype_t    p_lidtype;\n    id_t        p_lid;\n    idtype_t    p_ridtype;\n    id_t        p_rid;\n}\n\nvoid setprocset(ref procset_t psp, idop_t op, idtype_t ltype, id_t lid, idtype_t rtype, id_t rid)\n{\n    psp.p_op = op;\n    psp.p_lidtype = ltype;\n    psp.p_lid = lid;\n    psp.p_ridtype = rtype;\n    psp.p_rid = rid;\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/sys/types.d",
    "content": "/**\n * D header file that defines Solaris-specific types.\n *\n * Copyright:   Copyright 2014 Jason King.\n * License:     $(HTTP www.boost.org/LICENSE_1.0.txt, Boost License 1.0).\n * Authors:     Jason King\n */\n\n/*\n * Copyright 2014 Jason King.\n * Distributed under the Boost Software License, Version 1.0.\n * See accompanying file LICENSE or copy at\n *  http://www.boost.org/LICENSE_1_0.txt\n */\n\nmodule core.sys.solaris.sys.types;\n\nversion (Solaris):\nnothrow:\n@nogc:\n\nalias short pri_t;\n\nenum P_MYID = -1;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/solaris/time.d",
    "content": "//Written in the D programming language\n\n/++\n    D header file for Solaris's extensions to POSIX's time.h.\n\n    Copyright: Copyright 2014\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   Kai Nacke\n +/\nmodule core.sys.solaris.time;\n\npublic import core.sys.posix.time;\n\nversion (Solaris):\n\nenum CLOCK_VIRTUAL           = 1;\nenum CLOCK_HIGHRES           = CLOCK_MONOTONIC;\nenum CLOCK_PROF              = CLOCK_THREAD_CPUTIME_ID;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/accctrl.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_accctrl.d)\n */\nmodule core.sys.windows.accctrl;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;\n\n// FIXME: check types and grouping of constants\n// FIXME: check Windows version support\n\nalias LocalFree AccFree;\n\nenum uint\n    ACTRL_RESERVED            = 0x00000000,\n    ACTRL_ACCESS_PROTECTED    = 0x00000001,\n    ACTRL_ACCESS_ALLOWED      = 0x00000001,\n    ACTRL_ACCESS_DENIED       = 0x00000002,\n    ACTRL_AUDIT_SUCCESS       = 0x00000004,\n    ACTRL_AUDIT_FAILURE       = 0x00000008,\n    ACTRL_SYSTEM_ACCESS       = 0x04000000,\n    ACTRL_DELETE              = 0x08000000,\n    ACTRL_READ_CONTROL        = 0x10000000,\n    ACTRL_CHANGE_ACCESS       = 0x20000000,\n    ACTRL_CHANGE_OWNER        = 0x40000000,\n    ACTRL_SYNCHRONIZE         = 0x80000000,\n    ACTRL_STD_RIGHTS_ALL      = 0xf8000000;\n\nenum uint\n    ACTRL_FILE_READ           = 0x00000001,\n    ACTRL_FILE_WRITE          = 0x00000002,\n    ACTRL_FILE_APPEND         = 0x00000004,\n    ACTRL_FILE_READ_PROP      = 0x00000008,\n    ACTRL_FILE_WRITE_PROP     = 0x00000010,\n    ACTRL_FILE_EXECUTE        = 0x00000020,\n    ACTRL_FILE_READ_ATTRIB    = 0x00000080,\n    ACTRL_FILE_WRITE_ATTRIB   = 0x00000100,\n    ACTRL_FILE_CREATE_PIPE    = 0x00000200;\n\nenum uint\n    ACTRL_DIR_LIST            = 0x00000001,\n    ACTRL_DIR_CREATE_OBJECT   = 0x00000002,\n    ACTRL_DIR_CREATE_CHILD    = 0x00000004,\n    ACTRL_DIR_DELETE_CHILD    = 0x00000040,\n    ACTRL_DIR_TRAVERSE        = 0x00000020;\n\nenum uint\n    ACTRL_KERNEL_TERMINATE    = 0x00000001,\n    ACTRL_KERNEL_THREAD       = 0x00000002,\n    ACTRL_KERNEL_VM           = 0x00000004,\n    ACTRL_KERNEL_VM_READ      = 0x00000008,\n    ACTRL_KERNEL_VM_WRITE     = 0x00000010,\n    ACTRL_KERNEL_DUP_HANDLE   = 0x00000020,\n    ACTRL_KERNEL_PROCESS      = 0x00000040,\n    ACTRL_KERNEL_SET_INFO     = 0x00000080,\n    ACTRL_KERNEL_GET_INFO     = 0x00000100,\n    ACTRL_KERNEL_CONTROL      = 0x00000200,\n    ACTRL_KERNEL_ALERT        = 0x00000400,\n    ACTRL_KERNEL_GET_CONTEXT  = 0x00000800,\n    ACTRL_KERNEL_SET_CONTEXT  = 0x00001000,\n    ACTRL_KERNEL_TOKEN        = 0x00002000,\n    ACTRL_KERNEL_IMPERSONATE  = 0x00004000,\n    ACTRL_KERNEL_DIMPERSONATE = 0x00008000;\n\nenum uint\n    ACTRL_PRINT_SADMIN        = 0x00000001,\n    ACTRL_PRINT_SLIST         = 0x00000002,\n    ACTRL_PRINT_PADMIN        = 0x00000004,\n    ACTRL_PRINT_PUSE          = 0x00000008,\n    ACTRL_PRINT_JADMIN        = 0x00000010;\n\nenum uint\n    ACTRL_SVC_GET_INFO        = 0x00000001,\n    ACTRL_SVC_SET_INFO        = 0x00000002,\n    ACTRL_SVC_STATUS          = 0x00000004,\n    ACTRL_SVC_LIST            = 0x00000008,\n    ACTRL_SVC_START           = 0x00000010,\n    ACTRL_SVC_STOP            = 0x00000020,\n    ACTRL_SVC_PAUSE           = 0x00000040,\n    ACTRL_SVC_INTERROGATE     = 0x00000080,\n    ACTRL_SVC_UCONTROL        = 0x00000100;\n\nenum uint\n    ACTRL_REG_QUERY           = 0x00000001,\n    ACTRL_REG_SET             = 0x00000002,\n    ACTRL_REG_CREATE_CHILD    = 0x00000004,\n    ACTRL_REG_LIST            = 0x00000008,\n    ACTRL_REG_NOTIFY          = 0x00000010,\n    ACTRL_REG_LINK            = 0x00000020;\n\nenum uint\n    ACTRL_WIN_CLIPBRD         = 0x00000001,\n    ACTRL_WIN_GLOBAL_ATOMS    = 0x00000002,\n    ACTRL_WIN_CREATE          = 0x00000004,\n    ACTRL_WIN_LIST_DESK       = 0x00000008,\n    ACTRL_WIN_LIST            = 0x00000010,\n    ACTRL_WIN_READ_ATTRIBS    = 0x00000020,\n    ACTRL_WIN_WRITE_ATTRIBS   = 0x00000040,\n    ACTRL_WIN_SCREEN          = 0x00000080,\n    ACTRL_WIN_EXIT            = 0x00000100;\n\nenum : uint {\n    ACTRL_ACCESS_NO_OPTIONS              = 0x00000000,\n    ACTRL_ACCESS_SUPPORTS_OBJECT_ENTRIES = 0x00000001\n}\n\nconst TCHAR[] ACCCTRL_DEFAULT_PROVIDER = \"Windows NT Access Provider\";\n\nenum uint\n    TRUSTEE_ACCESS_ALLOWED    = 0x00000001,\n    TRUSTEE_ACCESS_READ       = 0x00000002,\n    TRUSTEE_ACCESS_WRITE      = 0x00000004,\n    TRUSTEE_ACCESS_EXPLICIT   = 0x00000001,\n    TRUSTEE_ACCESS_READ_WRITE = 0x00000006,\n    TRUSTEE_ACCESS_ALL        = 0xFFFFFFFF;\n\nenum uint\n    NO_INHERITANCE                     = 0x0,\n    SUB_OBJECTS_ONLY_INHERIT           = 0x1,\n    SUB_CONTAINERS_ONLY_INHERIT        = 0x2,\n    SUB_CONTAINERS_AND_OBJECTS_INHERIT = 0x3,\n    INHERIT_NO_PROPAGATE               = 0x4,\n    INHERIT_ONLY                       = 0x8,\n    INHERITED_ACCESS_ENTRY             = 0x10,\n    INHERITED_PARENT                   = 0x10000000,\n    INHERITED_GRANDPARENT              = 0x20000000;\n\nalias ULONG INHERIT_FLAGS, ACCESS_RIGHTS;\nalias ULONG* PINHERIT_FLAGS, PACCESS_RIGHTS;\n\nenum ACCESS_MODE {\n    NOT_USED_ACCESS,\n    GRANT_ACCESS,\n    SET_ACCESS,\n    DENY_ACCESS,\n    REVOKE_ACCESS,\n    SET_AUDIT_SUCCESS,\n    SET_AUDIT_FAILURE\n}\n\nenum SE_OBJECT_TYPE {\n    SE_UNKNOWN_OBJECT_TYPE,\n    SE_FILE_OBJECT,\n    SE_SERVICE,\n    SE_PRINTER,\n    SE_REGISTRY_KEY,\n    SE_LMSHARE,\n    SE_KERNEL_OBJECT,\n    SE_WINDOW_OBJECT,\n    SE_DS_OBJECT,\n    SE_DS_OBJECT_ALL,\n    SE_PROVIDER_DEFINED_OBJECT,\n    SE_WMIGUID_OBJECT,\n    SE_REGISTRY_WOW64_32KEY\n}\n\nenum TRUSTEE_TYPE {\n    TRUSTEE_IS_UNKNOWN,\n    TRUSTEE_IS_USER,\n    TRUSTEE_IS_GROUP,\n    TRUSTEE_IS_DOMAIN,\n    TRUSTEE_IS_ALIAS,\n    TRUSTEE_IS_WELL_KNOWN_GROUP,\n    TRUSTEE_IS_DELETED,\n    TRUSTEE_IS_INVALID,\n    TRUSTEE_IS_COMPUTER\n}\n\nenum TRUSTEE_FORM {\n    TRUSTEE_IS_SID,\n    TRUSTEE_IS_NAME,\n    TRUSTEE_BAD_FORM,\n    TRUSTEE_IS_OBJECTS_AND_SID,\n    TRUSTEE_IS_OBJECTS_AND_NAME\n}\n\nenum MULTIPLE_TRUSTEE_OPERATION {\n    NO_MULTIPLE_TRUSTEE,\n    TRUSTEE_IS_IMPERSONATE\n}\n\nstruct TRUSTEE_A {\n    TRUSTEE_A*                 pMultipleTrustee;\n    MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation;\n    TRUSTEE_FORM               TrusteeForm;\n    TRUSTEE_TYPE               TrusteeType;\n    LPSTR                      ptstrName;\n}\nalias TRUSTEE_A TRUSTEEA;\nalias TRUSTEE_A* PTRUSTEE_A, PTRUSTEEA;\n\nstruct TRUSTEE_W {\n    TRUSTEE_W*                 pMultipleTrustee;\n    MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation;\n    TRUSTEE_FORM               TrusteeForm;\n    TRUSTEE_TYPE               TrusteeType;\n    LPWSTR                     ptstrName;\n}\nalias TRUSTEE_W TRUSTEEW;\nalias TRUSTEEW* PTRUSTEE_W, PTRUSTEEW;\n\nstruct ACTRL_ACCESS_ENTRYA {\n    TRUSTEE_A     Trustee;\n    ULONG         fAccessFlags;\n    ACCESS_RIGHTS Access;\n    ACCESS_RIGHTS ProvSpecificAccess;\n    INHERIT_FLAGS Inheritance;\n    LPCSTR        lpInheritProperty;\n}\nalias ACTRL_ACCESS_ENTRYA* PACTRL_ACCESS_ENTRYA;\n\nstruct ACTRL_ACCESS_ENTRYW {\n    TRUSTEE_W     Trustee;\n    ULONG         fAccessFlags;\n    ACCESS_RIGHTS Access;\n    ACCESS_RIGHTS ProvSpecificAccess;\n    INHERIT_FLAGS Inheritance;\n    LPCWSTR       lpInheritProperty;\n}\nalias ACTRL_ACCESS_ENTRYW* PACTRL_ACCESS_ENTRYW;\n\nstruct ACTRL_ACCESS_ENTRY_LISTA {\n    ULONG                cEntries;\n    ACTRL_ACCESS_ENTRYA* pAccessList;\n}\nalias ACTRL_ACCESS_ENTRY_LISTA* PACTRL_ACCESS_ENTRY_LISTA;\n\nstruct ACTRL_ACCESS_ENTRY_LISTW {\n    ULONG                cEntries;\n    ACTRL_ACCESS_ENTRYW* pAccessList;\n}\nalias ACTRL_ACCESS_ENTRY_LISTW* PACTRL_ACCESS_ENTRY_LISTW;\n\nstruct ACTRL_PROPERTY_ENTRYA {\n    LPCSTR                    lpProperty;\n    PACTRL_ACCESS_ENTRY_LISTA pAccessEntryList;\n    ULONG                     fListFlags;\n}\nalias ACTRL_PROPERTY_ENTRYA* PACTRL_PROPERTY_ENTRYA;\n\nstruct ACTRL_PROPERTY_ENTRYW {\n    LPCWSTR                   lpProperty;\n    PACTRL_ACCESS_ENTRY_LISTW pAccessEntryList;\n    ULONG                     fListFlags;\n}\nalias ACTRL_PROPERTY_ENTRYW* PACTRL_PROPERTY_ENTRYW;\n\nstruct ACTRL_ACCESSA {\n    ULONG                  cEntries;\n    PACTRL_PROPERTY_ENTRYA pPropertyAccessList;\n}\nalias ACTRL_ACCESSA ACTRL_AUDITA;\nalias ACTRL_ACCESSA* PACTRL_ACCESSA, PACTRL_AUDITA;\n\nstruct ACTRL_ACCESSW {\n    ULONG                  cEntries;\n    PACTRL_PROPERTY_ENTRYW pPropertyAccessList;\n}\nalias ACTRL_ACCESSW ACTRL_AUDITW;\nalias ACTRL_ACCESSW* PACTRL_ACCESSW, PACTRL_AUDITW;\n\nstruct TRUSTEE_ACCESSA {\n    LPSTR         lpProperty;\n    ACCESS_RIGHTS Access;\n    ULONG         fAccessFlags;\n    ULONG         fReturnedAccess;\n}\nalias TRUSTEE_ACCESSA* PTRUSTEE_ACCESSA;\n\nstruct TRUSTEE_ACCESSW {\n    LPWSTR        lpProperty;\n    ACCESS_RIGHTS Access;\n    ULONG         fAccessFlags;\n    ULONG         fReturnedAccess;\n}\nalias TRUSTEE_ACCESSW* PTRUSTEE_ACCESSW;\n\nstruct ACTRL_OVERLAPPED {\n    union {\n        PVOID Provider;\n        ULONG Reserved1;\n    }\n    ULONG     Reserved2;\n    HANDLE    hEvent;\n}\nalias ACTRL_OVERLAPPED* PACTRL_OVERLAPPED;\n\nstruct ACTRL_ACCESS_INFOA {\n    ULONG fAccessPermission;\n    LPSTR lpAccessPermissionName;\n}\nalias ACTRL_ACCESS_INFOA* PACTRL_ACCESS_INFOA;\n\nstruct ACTRL_ACCESS_INFOW {\n    ULONG  fAccessPermission;\n    LPWSTR lpAccessPermissionName;\n}\nalias ACTRL_ACCESS_INFOW* PACTRL_ACCESS_INFOW;\n\nstruct ACTRL_CONTROL_INFOA {\n    LPSTR lpControlId;\n    LPSTR lpControlName;\n}\nalias ACTRL_CONTROL_INFOA* PACTRL_CONTROL_INFOA;\n\nstruct ACTRL_CONTROL_INFOW {\n    LPWSTR lpControlId;\n    LPWSTR lpControlName;\n}\nalias ACTRL_CONTROL_INFOW* PACTRL_CONTROL_INFOW;\n\nstruct EXPLICIT_ACCESS_A {\n    DWORD       grfAccessPermissions;\n    ACCESS_MODE grfAccessMode;\n    DWORD       grfInheritance;\n    TRUSTEE_A   Trustee;\n}\nalias EXPLICIT_ACCESS_A EXPLICIT_ACCESSA;\nalias EXPLICIT_ACCESS_A* PEXPLICIT_ACCESS_A, PEXPLICIT_ACCESSA;\n\nstruct EXPLICIT_ACCESS_W {\n    DWORD       grfAccessPermissions;\n    ACCESS_MODE grfAccessMode;\n    DWORD       grfInheritance;\n    TRUSTEE_W   Trustee;\n}\nalias EXPLICIT_ACCESS_W EXPLICIT_ACCESSW;\nalias EXPLICIT_ACCESS_W* PEXPLICIT_ACCESS_W, PEXPLICIT_ACCESSW;\n\nstruct OBJECTS_AND_SID {\n    DWORD ObjectsPresent;\n    GUID  ObjectTypeGuid;\n    GUID  InheritedObjectTypeGuid;\n    SID*  pSid;\n}\nalias OBJECTS_AND_SID* POBJECTS_AND_SID;\n\nstruct OBJECTS_AND_NAME_A {\n    DWORD          ObjectsPresent;\n    SE_OBJECT_TYPE ObjectType;\n    LPSTR          ObjectTypeName;\n    LPSTR          InheritedObjectTypeName;\n    LPSTR          ptstrName;\n}\nalias OBJECTS_AND_NAME_A* POBJECTS_AND_NAME_A;\n\nstruct OBJECTS_AND_NAME_W {\n    DWORD          ObjectsPresent;\n    SE_OBJECT_TYPE ObjectType;\n    LPWSTR         ObjectTypeName;\n    LPWSTR         InheritedObjectTypeName;\n    LPWSTR         ptstrName;\n}\nalias OBJECTS_AND_NAME_W* POBJECTS_AND_NAME_W;\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    struct INHERITED_FROMA {\n        LONG  GenerationGap;\n        LPSTR AncestorName;\n    }\n    alias INHERITED_FROMA* PINHERITED_FROMA;\n\n    struct INHERITED_FROMW {\n        LONG   GenerationGap;\n        LPWSTR AncestorName;\n    }\n    alias INHERITED_FROMW* PINHERITED_FROMW;\n}\n\nversion (Unicode) {\n    alias TRUSTEEW TRUSTEE;\n    alias ACTRL_ACCESSW ACTRL_ACCESS;\n    alias ACTRL_ACCESS_ENTRY_LISTW ACTRL_ACCESS_ENTRY_LIST;\n    alias ACTRL_ACCESS_INFOW ACTRL_ACCESS_INFO;\n    alias ACTRL_ACCESS_ENTRYW ACTRL_ACCESS_ENTRY;\n    alias ACTRL_AUDITW ACTRL_AUDIT;\n    alias ACTRL_CONTROL_INFOW ACTRL_CONTROL_INFO;\n    alias EXPLICIT_ACCESSW EXPLICIT_ACCESS;\n    alias TRUSTEE_ACCESSW TRUSTEE_ACCESS;\n    alias OBJECTS_AND_NAME_W OBJECTS_AND_NAME_;\n    static if (_WIN32_WINNT >= 0x501) {\n        alias INHERITED_FROMW INHERITED_FROM;\n    }\n} else {\n    alias TRUSTEEA TRUSTEE;\n    alias ACTRL_ACCESSA ACTRL_ACCESS;\n    alias ACTRL_ACCESS_ENTRY_LISTA ACTRL_ACCESS_ENTRY_LIST;\n    alias ACTRL_ACCESS_INFOA ACTRL_ACCESS_INFO;\n    alias ACTRL_ACCESS_ENTRYA ACTRL_ACCESS_ENTRY;\n    alias ACTRL_AUDITA ACTRL_AUDIT;\n    alias ACTRL_CONTROL_INFOA ACTRL_CONTROL_INFO;\n    alias EXPLICIT_ACCESSA EXPLICIT_ACCESS;\n    alias TRUSTEE_ACCESSA TRUSTEE_ACCESS;\n    alias OBJECTS_AND_NAME_A OBJECTS_AND_NAME_;\n    static if (_WIN32_WINNT >= 0x501) {\n        alias INHERITED_FROMA INHERITED_FROM;\n    }\n}\n\nalias TRUSTEE TRUSTEE_;\nalias TRUSTEE* PTRUSTEE, PTRUSTEE_;\nalias ACTRL_ACCESS* PACTRL_ACCESS;\nalias ACTRL_ACCESS_ENTRY_LIST* PACTRL_ACCESS_ENTRY_LIST;\nalias ACTRL_ACCESS_INFO* PACTRL_ACCESS_INFO;\nalias ACTRL_ACCESS_ENTRY* PACTRL_ACCESS_ENTRY;\nalias ACTRL_AUDIT* PACTRL_AUDIT;\nalias ACTRL_CONTROL_INFO* PACTRL_CONTROL_INFO;\nalias EXPLICIT_ACCESS EXPLICIT_ACCESS_;\nalias EXPLICIT_ACCESS* PEXPLICIT_ACCESS, PEXPLICIT_ACCESS_;\nalias TRUSTEE_ACCESS* PTRUSTEE_ACCESS;\nalias OBJECTS_AND_NAME_* POBJECTS_AND_NAME_;\nstatic if (_WIN32_WINNT >= 0x501) {\n    alias INHERITED_FROM* PINHERITED_FROM;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/aclapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_aclapi.d)\n */\nmodule core.sys.windows.aclapi;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"advapi32\");\n\nimport core.sys.windows.windows, core.sys.windows.accctrl;\n\nextern (Windows) {\n    VOID BuildExplicitAccessWithNameA(PEXPLICIT_ACCESS_A, LPSTR, DWORD,\n      ACCESS_MODE, DWORD);\n    VOID BuildExplicitAccessWithNameW(PEXPLICIT_ACCESS_W, LPWSTR, DWORD,\n      ACCESS_MODE, DWORD);\n    DWORD BuildSecurityDescriptorA(PTRUSTEE_A, PTRUSTEE_A , ULONG,\n      PEXPLICIT_ACCESS_A, ULONG, PEXPLICIT_ACCESS_A, PSECURITY_DESCRIPTOR,\n      PULONG, PSECURITY_DESCRIPTOR*);\n    DWORD BuildSecurityDescriptorW(PTRUSTEE_W, PTRUSTEE_W , ULONG,\n      PEXPLICIT_ACCESS_W, ULONG, PEXPLICIT_ACCESS_W, PSECURITY_DESCRIPTOR,\n      PULONG, PSECURITY_DESCRIPTOR*);\n    VOID BuildTrusteeWithNameA(PTRUSTEE_A, LPSTR);\n    VOID BuildTrusteeWithNameW(PTRUSTEE_W, LPWSTR);\n    VOID BuildTrusteeWithObjectsAndNameA(PTRUSTEE_A, POBJECTS_AND_NAME_A,\n      SE_OBJECT_TYPE, LPSTR, LPSTR, LPSTR);\n    VOID BuildTrusteeWithObjectsAndNameW(PTRUSTEE_W, POBJECTS_AND_NAME_W,\n      SE_OBJECT_TYPE, LPWSTR, LPWSTR, LPWSTR);\n    VOID BuildTrusteeWithObjectsAndSidA(PTRUSTEE_A, POBJECTS_AND_SID,\n      GUID*, GUID*, PSID);\n    VOID BuildTrusteeWithObjectsAndSidW(PTRUSTEE_W, POBJECTS_AND_SID,\n      GUID*, GUID*, PSID);\n    VOID BuildTrusteeWithSidA(PTRUSTEE_A, PSID);\n    VOID BuildTrusteeWithSidW(PTRUSTEE_W, PSID);\n    DWORD GetAuditedPermissionsFromAclA(PACL, PTRUSTEE_A, PACCESS_MASK,\n      PACCESS_MASK);\n    DWORD GetAuditedPermissionsFromAclW(PACL, PTRUSTEE_W, PACCESS_MASK,\n      PACCESS_MASK);\n    DWORD GetEffectiveRightsFromAclA(PACL, PTRUSTEE_A, PACCESS_MASK);\n    DWORD GetEffectiveRightsFromAclW(PACL, PTRUSTEE_W, PACCESS_MASK);\n    DWORD GetExplicitEntriesFromAclA(PACL, PULONG, PEXPLICIT_ACCESS_A*);\n    DWORD GetExplicitEntriesFromAclW(PACL, PULONG, PEXPLICIT_ACCESS_W*);\n    static if (_WIN32_WINNT >= 0x501) {\n        DWORD GetInheritanceSourceA(LPSTR, SE_OBJECT_TYPE,\n          SECURITY_INFORMATION, BOOL, GUID**, DWORD, PACL, void*,\n          PGENERIC_MAPPING, PINHERITED_FROMA);\n        DWORD GetInheritanceSourceW(LPWSTR, SE_OBJECT_TYPE,\n          SECURITY_INFORMATION, BOOL, GUID**, DWORD, PACL, void*,\n          PGENERIC_MAPPING, PINHERITED_FROMW);\n    }\n    DWORD GetNamedSecurityInfoA(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,\n      PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*);\n    DWORD GetNamedSecurityInfoW(LPWSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,\n      PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*);\n    DWORD GetSecurityInfo(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,\n      PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*);\n    TRUSTEE_FORM GetTrusteeFormA(PTRUSTEE_A);\n    TRUSTEE_FORM GetTrusteeFormW(PTRUSTEE_W);\n    LPSTR GetTrusteeNameA(PTRUSTEE_A);\n    LPWSTR GetTrusteeNameW(PTRUSTEE_W);\n    TRUSTEE_TYPE GetTrusteeTypeA(PTRUSTEE_A);\n    TRUSTEE_TYPE GetTrusteeTypeW(PTRUSTEE_W);\n    DWORD LookupSecurityDescriptorPartsA(PTRUSTEE_A*, PTRUSTEE_A*, PULONG,\n      PEXPLICIT_ACCESS_A*, PULONG, PEXPLICIT_ACCESS_A*,\n      PSECURITY_DESCRIPTOR);\n    DWORD LookupSecurityDescriptorPartsW(PTRUSTEE_W*, PTRUSTEE_W*, PULONG,\n      PEXPLICIT_ACCESS_W*, PULONG, PEXPLICIT_ACCESS_W*,\n      PSECURITY_DESCRIPTOR);\n    DWORD SetEntriesInAclA(ULONG, PEXPLICIT_ACCESS_A, PACL, PACL*);\n    DWORD SetEntriesInAclW(ULONG, PEXPLICIT_ACCESS_W, PACL, PACL*);\n    DWORD SetNamedSecurityInfoA(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,\n      PSID, PSID, PACL, PACL);\n    DWORD SetNamedSecurityInfoW(LPWSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,\n      PSID, PSID, PACL, PACL);\n    DWORD SetSecurityInfo(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, PSID,\n      PSID, PACL, PACL);\n    VOID BuildImpersonateExplicitAccessWithNameA(PEXPLICIT_ACCESS_A, LPSTR,\n      PTRUSTEE_A, DWORD, ACCESS_MODE, DWORD);\n    VOID BuildImpersonateExplicitAccessWithNameW(PEXPLICIT_ACCESS_W, LPWSTR,\n      PTRUSTEE_W, DWORD, ACCESS_MODE, DWORD);\n    VOID BuildImpersonateTrusteeA(PTRUSTEE_A, PTRUSTEE_A);\n    VOID BuildImpersonateTrusteeW(PTRUSTEE_W, PTRUSTEE_W);\n    PTRUSTEE_A GetMultipleTrusteeA(PTRUSTEE_A);\n    PTRUSTEE_W GetMultipleTrusteeW(PTRUSTEE_W);\n    MULTIPLE_TRUSTEE_OPERATION GetMultipleTrusteeOperationA(PTRUSTEE_A);\n    MULTIPLE_TRUSTEE_OPERATION GetMultipleTrusteeOperationW(PTRUSTEE_W);\n}\n\nversion (Unicode) {\n    alias BuildExplicitAccessWithNameW BuildExplicitAccessWithName;\n    alias BuildSecurityDescriptorW BuildSecurityDescriptor;\n    alias BuildTrusteeWithNameW BuildTrusteeWithName;\n    alias BuildTrusteeWithObjectsAndNameW BuildTrusteeWithObjectsAndName;\n    alias BuildTrusteeWithObjectsAndSidW BuildTrusteeWithObjectsAndSid;\n    alias BuildTrusteeWithSidW BuildTrusteeWithSid;\n    alias GetAuditedPermissionsFromAclW GetAuditedPermissionsFromAcl;\n    alias GetEffectiveRightsFromAclW GetEffectiveRightsFromAcl;\n    alias GetExplicitEntriesFromAclW GetExplicitEntriesFromAcl;\n    alias GetNamedSecurityInfoW GetNamedSecurityInfo;\n    alias GetTrusteeFormW GetTrusteeForm;\n    alias GetTrusteeNameW GetTrusteeName;\n    alias GetTrusteeTypeW GetTrusteeType;\n    alias LookupSecurityDescriptorPartsW LookupSecurityDescriptorParts;\n    alias SetEntriesInAclW SetEntriesInAcl;\n    alias SetNamedSecurityInfoW SetNamedSecurityInfo;\n    alias BuildImpersonateExplicitAccessWithNameW\n      BuildImpersonateExplicitAccessWithName;\n    alias BuildImpersonateTrusteeW BuildImpersonateTrustee;\n    alias GetMultipleTrusteeW GetMultipleTrustee;\n    alias GetMultipleTrusteeOperationW GetMultipleTrusteeOperation;\n} else {\n    alias BuildExplicitAccessWithNameA BuildExplicitAccessWithName;\n    alias BuildSecurityDescriptorA BuildSecurityDescriptor;\n    alias BuildTrusteeWithNameA BuildTrusteeWithName;\n    alias BuildTrusteeWithObjectsAndNameA BuildTrusteeWithObjectsAndName;\n    alias BuildTrusteeWithObjectsAndSidA BuildTrusteeWithObjectsAndSid;\n    alias BuildTrusteeWithSidA BuildTrusteeWithSid;\n    alias GetAuditedPermissionsFromAclA GetAuditedPermissionsFromAcl;\n    alias GetEffectiveRightsFromAclA GetEffectiveRightsFromAcl;\n    alias GetExplicitEntriesFromAclA GetExplicitEntriesFromAcl;\n    alias GetNamedSecurityInfoA GetNamedSecurityInfo;\n    alias GetTrusteeFormA GetTrusteeForm;\n    alias GetTrusteeNameA GetTrusteeName;\n    alias GetTrusteeTypeA GetTrusteeType;\n    alias LookupSecurityDescriptorPartsA LookupSecurityDescriptorParts;\n    alias SetEntriesInAclA SetEntriesInAcl;\n    alias SetNamedSecurityInfoA SetNamedSecurityInfo;\n    alias BuildImpersonateExplicitAccessWithNameA\n      BuildImpersonateExplicitAccessWithName;\n    alias BuildImpersonateTrusteeA BuildImpersonateTrustee;\n    alias GetMultipleTrusteeA GetMultipleTrustee;\n    alias GetMultipleTrusteeOperationA GetMultipleTrusteeOperation;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/aclui.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.10\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_aclui.d)\n */\nmodule core.sys.windows.aclui;\nversion (Windows):\npragma(lib, \"aclui\");\n\nprivate import core.sys.windows.w32api;\n/*\nstatic assert (_WIN32_WINNT >= 0x500,\n    \"core.sys.windows.aclui is available only if version Windows2000, WindowsXP, Windows2003 \"\n    \"or WindowsVista is set\");\n*/\nimport core.sys.windows.accctrl, core.sys.windows.commctrl, core.sys.windows.objbase;\nprivate import core.sys.windows.basetyps, core.sys.windows.prsht, core.sys.windows.unknwn, core.sys.windows.windef,\n  core.sys.windows.winuser;\n\n\nstruct SI_OBJECT_INFO {\n    DWORD     dwFlags;\n    HINSTANCE hInstance;\n    LPWSTR    pszServerName;\n    LPWSTR    pszObjectName;\n    LPWSTR    pszPageTitle;\n    GUID      guidObjectType;\n}\nalias SI_OBJECT_INFO* PSI_OBJECT_INFO;\n\n// values for SI_OBJECT_INFO.dwFlags\nenum DWORD\n    SI_EDIT_PERMS               = 0x00000000,\n    SI_EDIT_OWNER               = 0x00000001,\n    SI_EDIT_AUDITS              = 0x00000002,\n    SI_CONTAINER                = 0x00000004,\n    SI_READONLY                 = 0x00000008,\n    SI_ADVANCED                 = 0x00000010,\n    SI_RESET                    = 0x00000020,\n    SI_OWNER_READONLY           = 0x00000040,\n    SI_EDIT_PROPERTIES          = 0x00000080,\n    SI_OWNER_RECURSE            = 0x00000100,\n    SI_NO_ACL_PROTECT           = 0x00000200,\n    SI_NO_TREE_APPLY            = 0x00000400,\n    SI_PAGE_TITLE               = 0x00000800,\n    SI_SERVER_IS_DC             = 0x00001000,\n    SI_RESET_DACL_TREE          = 0x00004000,\n    SI_RESET_SACL_TREE          = 0x00008000,\n    SI_OBJECT_GUID              = 0x00010000,\n    SI_EDIT_EFFECTIVE           = 0x00020000,\n    SI_RESET_DACL               = 0x00040000,\n    SI_RESET_SACL               = 0x00080000,\n    SI_RESET_OWNER              = 0x00100000,\n    SI_NO_ADDITIONAL_PERMISSION = 0x00200000,\n    SI_MAY_WRITE                = 0x10000000,\n    SI_EDIT_ALL                 = SI_EDIT_PERMS | SI_EDIT_OWNER\n                                  | SI_EDIT_AUDITS;\n\nstruct SI_ACCESS {\nconst(GUID)* pguid;\n    ACCESS_MASK  mask;\n    LPCWSTR      pszName;\n    DWORD        dwFlags;\n}\nalias SI_ACCESS* PSI_ACCESS;\n\n// values for SI_ACCESS.dwFlags\nenum DWORD\n    SI_ACCESS_SPECIFIC  = 0x00010000,\n    SI_ACCESS_GENERAL   = 0x00020000,\n    SI_ACCESS_CONTAINER = 0x00040000,\n    SI_ACCESS_PROPERTY  = 0x00080000;\n\n\nstruct SI_INHERIT_TYPE {\nconst(GUID)* pguid;\n    ULONG        dwFlags;\n    LPCWSTR      pszName;\n}\nalias SI_INHERIT_TYPE* PSI_INHERIT_TYPE;\n\n/* values for SI_INHERIT_TYPE.dwFlags\n   INHERIT_ONLY_ACE, CONTAINER_INHERIT_ACE, OBJECT_INHERIT_ACE\n   defined elsewhere */\n\nenum SI_PAGE_TYPE {\n    SI_PAGE_PERM,\n    SI_PAGE_ADVPERM,\n    SI_PAGE_AUDIT,\n    SI_PAGE_OWNER\n}\n\nenum uint PSPCB_SI_INITDIALOG = WM_USER + 1;\n\ninterface ISecurityInformation : IUnknown {\n    HRESULT GetObjectInformation(PSI_OBJECT_INFO);\n    HRESULT GetSecurity(SECURITY_INFORMATION, PSECURITY_DESCRIPTOR*, BOOL);\n    HRESULT SetSecurity(SECURITY_INFORMATION, PSECURITY_DESCRIPTOR);\n    HRESULT GetAccessRights(const(GUID)*, DWORD, PSI_ACCESS*, ULONG*, ULONG*);\n    HRESULT MapGeneric(const(GUID)*, UCHAR*, ACCESS_MASK*);\n    HRESULT GetInheritTypes(PSI_INHERIT_TYPE*, ULONG*);\n    HRESULT PropertySheetPageCallback(HWND, UINT, SI_PAGE_TYPE);\n}\nalias ISecurityInformation LPSECURITYINFO;\n\n/* Comment from MinGW\n * TODO: ISecurityInformation2, IEffectivePermission, ISecurityObjectTypeInfo\n */\n\n// FIXME: linkage attribute?\nextern (C) /+DECLSPEC_IMPORT+/ extern const IID IID_ISecurityInformation;\n\nextern (Windows) {\n    HPROPSHEETPAGE CreateSecurityPage(LPSECURITYINFO psi);\n    BOOL EditSecurity(HWND hwndOwner, LPSECURITYINFO psi);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/basetsd.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.12\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_basetsd.d)\n */\nmodule core.sys.windows.basetsd;\nversion (Windows):\n\n/*  This template is used in these modules to declare constant pointer types,\n *  in order to support both D 1.x and 2.x.\n *  Since removed - now supporting only D2\n */\n/*template CPtr(T) {\n    version (D_Version2) {\n        // must use mixin so that it doesn't cause a syntax error under D1\n        mixin(\"alias const(T)* CPtr;\");\n    } else {\n        alias T* CPtr;\n    }\n}*/\n\n/*  [CyberShadow VP 2011.12.22] typedef is now deprecated in D2.\n */\ntemplate TypeDef(T) {\n    version (D_Version2) {\n        alias T TypeDef;\n    } else {\n        // must use mixin so that it doesn't cause a deprecation error under D2\n        mixin(\"typedef T TypeDef;\");\n    }\n}\n\n// [SnakE 2009-02-23] Moved HANDLE definition here from winnt.d to avoid\n// 'forwatd template reference' to CPtr from winnt.d caused by a circular\n// import.\n\nalias TypeDef!(void*) HANDLE;\n/+struct HANDLE {\nconst(void)* h;\n    alias h this;\n}+/\n\npackage template DECLARE_HANDLE(string name, base = HANDLE) {\n    mixin (\"alias \" ~ base.stringof ~ \" \" ~ name ~ \";\");\n}\nalias HANDLE* PHANDLE, LPHANDLE;\n\n// helper for aligned structs\n// alignVal 0 means the default align.\n// _alignSpec as parameter does not pollute namespace.\npackage mixin template AlignedStr(int alignVal, string name, string memberlist,\n                                    string _alignSpec = !alignVal ? \"align\" : \"align(\"~alignVal.stringof~\")\" )\n{\n    mixin( _alignSpec ~ \" struct \" ~ name ~\" { \" ~ _alignSpec ~\":\"~ memberlist~\" }\" );\n}\n\nversion (unittest) {\n    private mixin AlignedStr!(16, \"_Test_Aligned_Str\", q{char a; char b;});\n    private mixin AlignedStr!(0, \"_Test_NoAligned_Str\", q{char a; char b;});\n}\n\nversion (Win64) {\n    alias long __int3264;\nenum ulong ADDRESS_TAG_BIT = 0x40000000000;\n\n    alias long INT_PTR, LONG_PTR;\n    alias long* PINT_PTR, PLONG_PTR;\n    alias ulong UINT_PTR, ULONG_PTR, HANDLE_PTR;\n    alias ulong* PUINT_PTR, PULONG_PTR;\n    alias int HALF_PTR;\n    alias int* PHALF_PTR;\n    alias uint UHALF_PTR;\n    alias uint* PUHALF_PTR;\n\n    uint HandleToULong(void* h) { return(cast(uint) cast(ULONG_PTR) h); }\n    int HandleToLong(void* h)   { return(cast(int) cast(LONG_PTR) h); }\n    void* ULongToHandle(uint h) { return(cast(void*) cast(UINT_PTR) h); }\n    void* LongToHandle(int h)   { return(cast(void*) cast(INT_PTR) h); }\n    uint PtrToUlong(void* p)    { return(cast(uint) cast(ULONG_PTR) p); }\n    uint PtrToUint(void* p)     { return(cast(uint) cast(UINT_PTR) p); }\n    ushort PtrToUshort(void* p) { return(cast(ushort) cast(uint) cast(ULONG_PTR) p); }\n    int PtrToLong(void* p)      { return(cast(int) cast(LONG_PTR) p); }\n    int PtrToInt(void* p)       { return(cast(int) cast(INT_PTR) p); }\n    short PtrToShort(void* p)   { return(cast(short) cast(int) cast(LONG_PTR) p); }\n    void* IntToPtr(int i)       { return(cast(void*) cast(INT_PTR) i); }\n    void* UIntToPtr(uint ui)    { return(cast(void*) cast(UINT_PTR) ui); }\n    void* LongToPtr(int l)      { return(cast(void*) cast(LONG_PTR) l); }\n    void* ULongToPtr(uint ul)   { return(cast(void*) cast(ULONG_PTR) ul); }\n\n} else {\n    alias int __int3264;\nenum uint ADDRESS_TAG_BIT = 0x80000000;\n\n    alias int INT_PTR, LONG_PTR;\n    alias int* PINT_PTR, PLONG_PTR;\n    alias uint UINT_PTR, ULONG_PTR, HANDLE_PTR;\n    alias uint* PUINT_PTR, PULONG_PTR;\n    alias short HALF_PTR;\n    alias short* PHALF_PTR;\n    alias ushort UHALF_PTR;\n    alias ushort* PUHALF_PTR;\n\n    uint HandleToUlong(HANDLE h)      { return cast(uint) h; }\n    int HandleToLong(HANDLE h)        { return cast(int) h; }\n    HANDLE LongToHandle(LONG_PTR h)   { return cast(HANDLE)h; }\n    uint PtrToUlong(const(void)* p)    { return cast(uint) p; }\n    uint PtrToUint(const(void)* p)     { return cast(uint) p; }\n    int PtrToInt(const(void)* p)       { return cast(int) p; }\n    ushort PtrToUshort(const(void)* p) { return cast(ushort) p; }\n    short PtrToShort(const(void)* p)   { return cast(short) p; }\n    void* IntToPtr(int i)             { return cast(void*) i; }\n    void* UIntToPtr(uint ui)          { return cast(void*) ui; }\n    alias IntToPtr LongToPtr;\n    alias UIntToPtr ULongToPtr;\n}\n\nalias UIntToPtr UintToPtr, UlongToPtr;\n\nenum : UINT_PTR {\n    MAXUINT_PTR = UINT_PTR.max\n}\n\nenum : INT_PTR {\n    MAXINT_PTR = INT_PTR.max,\n    MININT_PTR = INT_PTR.min\n}\n\nenum : ULONG_PTR {\n    MAXULONG_PTR = ULONG_PTR.max\n}\n\nenum : LONG_PTR {\n    MAXLONG_PTR = LONG_PTR.max,\n    MINLONG_PTR = LONG_PTR.min\n}\n\nenum : UHALF_PTR {\n    MAXUHALF_PTR = UHALF_PTR.max\n}\n\nenum : HALF_PTR {\n    MAXHALF_PTR = HALF_PTR.max,\n    MINHALF_PTR = HALF_PTR.min\n}\n\nalias byte INT8;\nalias byte* PINT8;\nalias ubyte UINT8;\nalias ubyte* PUINT8;\n\nalias short INT16;\nalias short* PINT16;\nalias ushort UINT16;\nalias ushort* PUINT16;\n\nalias int LONG32, INT32;\nalias int* PLONG32, PINT32;\nalias uint ULONG32, DWORD32, UINT32;\nalias uint* PULONG32, PDWORD32, PUINT32;\n\nalias ULONG_PTR SIZE_T, DWORD_PTR;\nalias ULONG_PTR* PSIZE_T, PDWORD_PTR;\nalias LONG_PTR SSIZE_T;\nalias LONG_PTR* PSSIZE_T;\n\nalias long LONG64, INT64;\nalias long* PLONG64, PINT64;\nalias ulong ULONG64, DWORD64, UINT64;\nalias ulong* PULONG64, PDWORD64, PUINT64;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/basetyps.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.10\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_basetyps.d)\n */\nmodule core.sys.windows.basetyps;\nversion (Windows):\n\nprivate import core.sys.windows.windef, core.sys.windows.basetsd;\n\nalign(1) struct GUID {  // size is 16\n    align(1):\n    DWORD   Data1;\n    WORD    Data2;\n    WORD    Data3;\n    BYTE[8] Data4;\n}\nalias GUID UUID, /*IID, CLSID, */FMTID, uuid_t;\nalias IID = const(GUID);\nalias CLSID = const(GUID);\n\nalias GUID* LPGUID, LPCLSID, LPIID;\nalias const(GUID)* LPCGUID, REFGUID, REFIID, REFCLSID, REFFMTID;\nalias uint error_status_t, PROPID;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/cderr.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_cderr.d)\n */\nmodule core.sys.windows.cderr;\nversion (Windows):\n\nenum {\n    CDERR_DIALOGFAILURE    = 0xFFFF,\n    CDERR_GENERALCODES     = 0x0000,\n    CDERR_STRUCTSIZE,\n    CDERR_INITIALIZATION,\n    CDERR_NOTEMPLATE,\n    CDERR_NOHINSTANCE,\n    CDERR_LOADSTRFAILURE,\n    CDERR_FINDRESFAILURE,\n    CDERR_LOADRESFAILURE,\n    CDERR_LOCKRESFAILURE,\n    CDERR_MEMALLOCFAILURE,\n    CDERR_MEMLOCKFAILURE,\n    CDERR_NOHOOK,\n    CDERR_REGISTERMSGFAIL,\n    PDERR_PRINTERCODES     = 0x1000,\n    PDERR_SETUPFAILURE,\n    PDERR_PARSEFAILURE,\n    PDERR_RETDEFFAILURE,\n    PDERR_LOADDRVFAILURE,\n    PDERR_GETDEVMODEFAIL,\n    PDERR_INITFAILURE,\n    PDERR_NODEVICES,\n    PDERR_NODEFAULTPRN,\n    PDERR_DNDMMISMATCH,\n    PDERR_CREATEICFAILURE,\n    PDERR_PRINTERNOTFOUND,\n    PDERR_DEFAULTDIFFERENT,\n    CFERR_CHOOSEFONTCODES  = 0x2000,\n    CFERR_NOFONTS,\n    CFERR_MAXLESSTHANMIN,\n    FNERR_FILENAMECODES    = 0x3000,\n    FNERR_SUBCLASSFAILURE,\n    FNERR_INVALIDFILENAME,\n    FNERR_BUFFERTOOSMALL,\n    FRERR_FINDREPLACECODES = 0x4000,\n    FRERR_BUFFERLENGTHZERO,\n    CCERR_CHOOSECOLORCODES = 0x5000\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/cguid.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_cguid.d)\n */\nmodule core.sys.windows.cguid;\nversion (Windows):\n\nprivate import core.sys.windows.basetyps;\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/com.d",
    "content": "module core.sys.windows.com;\nversion (Windows):\n\npragma(lib,\"uuid\");\n\nimport core.atomic;\nimport core.sys.windows.windows;\n//import std.string;\n\npublic import core.sys.windows.basetyps : GUID, IID, CLSID;\n\npublic import core.sys.windows.objbase :\n    CLSCTX_INPROC, CLSCTX_ALL, CLSCTX_SERVER,\n    COINIT,\n    CoBuildVersion, StringFromGUID2,\n    CoInitialize, CoInitializeEx, CoUninitialize, CoGetCurrentProcess,\n    CoCreateInstance,\n    CoFreeLibrary, CoFreeAllLibraries, CoFreeUnusedLibraries;\n\npublic import core.sys.windows.ole2ver : rmm, rup;\n\npublic import core.sys.windows.unknwn : IUnknown, IClassFactory;\n\npublic import core.sys.windows.winerror :\n    S_OK,\n    S_FALSE,\n    NOERROR,\n    E_NOTIMPL,\n    E_NOINTERFACE,\n    E_POINTER,\n    E_ABORT,\n    E_FAIL,\n    E_HANDLE,\n    CLASS_E_NOAGGREGATION,\n    E_OUTOFMEMORY,\n    E_INVALIDARG,\n    E_UNEXPECTED,\n    RPC_E_CHANGED_MODE;\n\npublic import core.sys.windows.wtypes :\n    OLECHAR, LPOLESTR, LPCOLESTR;\n\nalias CLSCTX_INPROC_SERVER     = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_SERVER    ;\nalias CLSCTX_INPROC_HANDLER    = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_HANDLER   ;\nalias CLSCTX_LOCAL_SERVER      = core.sys.windows.wtypes.CLSCTX.CLSCTX_LOCAL_SERVER     ;\nalias CLSCTX_INPROC_SERVER16   = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_SERVER16  ;\nalias CLSCTX_REMOTE_SERVER     = core.sys.windows.wtypes.CLSCTX.CLSCTX_REMOTE_SERVER    ;\nalias CLSCTX_INPROC_HANDLER16  = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_HANDLER16 ;\nalias CLSCTX_INPROC_SERVERX86  = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_SERVERX86 ;\nalias CLSCTX_INPROC_HANDLERX86 = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_HANDLERX86;\n\nalias COINIT_APARTMENTTHREADED   = COINIT.COINIT_APARTMENTTHREADED;\nalias COINIT_MULTITHREADED       = COINIT.COINIT_MULTITHREADED    ;\nalias COINIT_DISABLE_OLE1DDE     = COINIT.COINIT_DISABLE_OLE1DDE  ;\nalias COINIT_SPEED_OVER_MEMORY   = COINIT.COINIT_SPEED_OVER_MEMORY;\n\npublic import core.sys.windows.uuid;\n\nextern (System)\n{\n\nclass ComObject : IUnknown\n{\nextern (System):\n    HRESULT QueryInterface(const(IID)* riid, void** ppv)\n    {\n        if (*riid == IID_IUnknown)\n        {\n            *ppv = cast(void*)cast(IUnknown)this;\n            AddRef();\n            return S_OK;\n        }\n        else\n        {   *ppv = null;\n            return E_NOINTERFACE;\n        }\n    }\n\n    ULONG AddRef()\n    {\n        return atomicOp!\"+=\"(*cast(shared)&count, 1);\n    }\n\n    ULONG Release()\n    {\n        LONG lRef = atomicOp!\"-=\"(*cast(shared)&count, 1);\n        if (lRef == 0)\n        {\n            // free object\n\n            // If we delete this object, then the postinvariant called upon\n            // return from Release() will fail.\n            // Just let the GC reap it.\n            //delete this;\n\n            return 0;\n        }\n        return cast(ULONG)lRef;\n    }\n\n    LONG count = 0;             // object reference count\n}\n\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/comcat.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_comcat.d)\n */\nmodule core.sys.windows.comcat;\nversion (Windows):\n\nimport core.sys.windows.windows, core.sys.windows.ole2;\nprivate import core.sys.windows.basetyps, core.sys.windows.cguid, core.sys.windows.objbase, core.sys.windows.unknwn,\n  core.sys.windows.windef, core.sys.windows.wtypes;\n\nalias IEnumGUID LPENUMGUID;\n\ninterface IEnumGUID : IUnknown {\n    HRESULT Next(ULONG, GUID*, ULONG*);\n    HRESULT Skip(ULONG);\n    HRESULT Reset();\n    HRESULT Clone(LPENUMGUID*);\n}\n\nalias GUID CATID;\nalias REFGUID REFCATID;\nalias GUID_NULL CATID_NULL;\nalias IsEqualGUID IsEqualCATID;\n\nstruct CATEGORYINFO {\n    CATID        catid;\n    LCID         lcid;\n    OLECHAR[128] szDescription;\n}\nalias CATEGORYINFO* LPCATEGORYINFO;\n\nalias IEnumGUID IEnumCATID;\nalias LPENUMGUID LPENUMCATID;\nalias IID_IEnumGUID IID_IEnumCATID;\n\nalias IEnumGUID IEnumCLSID;\nalias LPENUMGUID LPENUMCLSID;\nalias IID_IEnumGUID IID_IEnumCLSID;\n\ninterface ICatInformation : IUnknown {\n    HRESULT EnumCategories(LCID, LPENUMCATEGORYINFO*);\n    HRESULT GetCategoryDesc(REFCATID, LCID, PWCHAR*);\n    HRESULT EnumClassesOfCategories(ULONG, CATID*, ULONG, CATID*,\n      LPENUMCLSID*);\n    HRESULT IsClassOfCategories(REFCLSID, ULONG, CATID*, ULONG, CATID*);\n    HRESULT EnumImplCategoriesOfClass(REFCLSID, LPENUMCATID*);\n    HRESULT EnumReqCategoriesOfClass(REFCLSID, LPENUMCATID*);\n}\nalias ICatInformation LPCATINFORMATION;\n\ninterface ICatRegister : IUnknown {\n    HRESULT RegisterCategories(ULONG, CATEGORYINFO*);\n    HRESULT UnRegisterCategories(ULONG, CATID*);\n    HRESULT RegisterClassImplCategories(REFCLSID, ULONG, CATID*);\n    HRESULT UnRegisterClassImplCategories(REFCLSID, ULONG, CATID*);\n    HRESULT RegisterClassReqCategories(REFCLSID, ULONG, CATID*);\n    HRESULT UnRegisterClassReqCategories(REFCLSID, ULONG, CATID*);\n}\nalias ICatRegister LPCATREGISTER;\n\ninterface IEnumCATEGORYINFO : IUnknown {\n    HRESULT Next(ULONG, CATEGORYINFO*, ULONG*);\n    HRESULT Skip(ULONG);\n    HRESULT Reset();\n    HRESULT Clone(LPENUMCATEGORYINFO*);\n}\nalias IEnumCATEGORYINFO LPENUMCATEGORYINFO;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/commctrl.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.12\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_commctrl.d)\n */\nmodule core.sys.windows.commctrl;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"comctl32\");\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winuser;\nprivate import core.sys.windows.winbase; // for SYSTEMTIME\nprivate import core.sys.windows.objfwd;  // for LPSTREAM\n\nimport core.sys.windows.prsht;\n\nenum COMCTL32_VERSION = 6;\n\nconst TCHAR[]\n    DRAGLISTMSGSTRING  = \"commctrl_DragListMsg\",\n    HOTKEY_CLASS       = \"msctls_hotkey32\",\n    PROGRESS_CLASS     = \"msctls_progress32\",\n    STATUSCLASSNAME    = \"msctls_statusbar32\",\n    TOOLBARCLASSNAME   = \"ToolbarWindow32\",\n    TOOLTIPS_CLASS     = \"tooltips_class32\",\n    TRACKBAR_CLASS     = \"msctls_trackbar32\",\n    UPDOWN_CLASS       = \"msctls_updown32\",\n    ANIMATE_CLASS      = \"SysAnimate32\",\n    DATETIMEPICK_CLASS = \"SysDateTimePick32\",\n    MONTHCAL_CLASS     = \"SysMonthCal32\",\n    REBARCLASSNAME     = \"ReBarWindow32\",\n    WC_COMBOBOXEX      = \"ComboBoxEx32\",\n    WC_IPADDRESS       = \"SysIPAddress32\",\n    WC_LISTVIEW        = \"SysListView32\",\n    WC_TABCONTROL      = \"SysTabControl32\",\n    WC_TREEVIEW        = \"SysTreeView32\",\n    WC_HEADER          = \"SysHeader32\",\n    WC_PAGESCROLLER    = \"SysPager\",\n    WC_NATIVEFONTCTL   = \"NativeFontCtl\",\n    WC_BUTTON          = \"Button\",\n    WC_STATIC          = \"Static\",\n    WC_EDIT            = \"Edit\",\n    WC_LISTBOX         = \"ListBox\",\n    WC_COMBOBOX        = \"ComboBox\",\n    WC_SCROLLBAR       = \"ScrollBar\",\n    WC_LINKA           = \"SysLink\";\n\nenum {\n    LVM_FIRST = 0x1000,\n    TV_FIRST  = 0x1100,\n    HDM_FIRST = 0x1200\n}\n\nenum {\n    ACM_OPENA = WM_USER + 100,\n    ACM_PLAY  = WM_USER + 101,\n    ACM_STOP  = WM_USER + 102,\n    ACM_OPENW = WM_USER + 103,\n    ACM_ISPLAYING = WM_USER + 104\n}\n\nenum {\n    ACN_START = 1,\n    ACN_STOP\n}\n\nenum {\n    CBEIF_TEXT          = 0x00000001,\n    CBEIF_IMAGE         = 0x00000002,\n    CBEIF_SELECTEDIMAGE = 0x00000004,\n    CBEIF_OVERLAY       = 0x00000008,\n    CBEIF_INDENT        = 0x00000010,\n    CBEIF_LPARAM        = 0x00000020,\n    CBEIF_DI_SETITEM    = 0x10000000\n}\n\nenum {\n    RBN_FIRST  = -831U,\n    RBN_LAST   = -859U,\n    MCN_FIRST  = -750U,\n    MCN_LAST   = -759U,\n    DTN_FIRST  = -760U,\n    DTN_LAST   = -799U,\n    CBEN_FIRST = -800U,\n    CBEN_LAST  = -830U\n}\n\nenum {\n    CBEN_INSERTITEM = CBEN_FIRST - 1,\n    CBEN_DELETEITEM = CBEN_FIRST - 2,\n    CBEN_BEGINEDIT  = CBEN_FIRST - 4,\n    CBEN_ENDEDITA   = CBEN_FIRST - 5,\n    CBEN_ENDEDITW   = CBEN_FIRST - 6\n}\n\nenum {\n    CBENF_KILLFOCUS = 1,\n    CBENF_RETURN,\n    CBENF_ESCAPE,\n    CBENF_DROPDOWN // = 4\n}\n\nenum CBEMAXSTRLEN = 260;\n\nenum {\n    DL_BEGINDRAG  = 1157,\n    DL_CANCELDRAG = 1160,\n    DL_DRAGGING   = 1158,\n    DL_DROPPED    = 1159,\n    DL_CURSORSET  = 0,\n    DL_STOPCURSOR = 1,\n    DL_COPYCURSOR = 2,\n    DL_MOVECURSOR = 3\n}\n\nenum {\n    CCS_TOP           = 1,\n    CCS_NOMOVEY       = 2,\n    CCS_BOTTOM        = 3,\n    CCS_NORESIZE      = 4,\n    CCS_NOPARENTALIGN = 8,\n    CCS_ADJUSTABLE    = 32,\n    CCS_NODIVIDER     = 64\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        CCS_VERT    = 128,\n        CCS_LEFT    = 129,\n        CCS_NOMOVEX = 130,\n        CCS_RIGHT   = 131\n    }\n}\n\nenum {\n    ACS_CENTER      = 0x0001,\n    ACS_TRANSPARENT = 0x0002,\n    ACS_AUTOPLAY    = 0x0004,\n    ACS_TIMER       = 0x0008\n}\n\nenum {\n    PGS_VERT       = 0x00000000,\n    PGS_HORZ       = 0x00000001,\n    PGS_AUTOSCROLL = 0x00000002,\n    PGS_DRAGNDROP  = 0x00000004\n}\n\nenum CMB_MASKED = 2;\n\nenum MINSYSCOMMAND = SC_SIZE;\n\nenum {\n    SBT_OWNERDRAW  = 0x1000,\n    SBT_NOBORDERS  = 256,\n    SBT_POPOUT     = 512,\n    SBT_RTLREADING = 1024\n}\n\nenum {\n    SB_SETTEXTA       = WM_USER + 1,\n    SB_SETTEXTW       = WM_USER + 11,\n    SB_GETTEXTA       = WM_USER + 2,\n    SB_GETTEXTW       = WM_USER + 13,\n    SB_GETTEXTLENGTHA = WM_USER + 3,\n    SB_GETTEXTLENGTHW = WM_USER + 12,\n    SB_SETPARTS       = WM_USER + 4,\n    SB_GETPARTS       = WM_USER + 6,\n    SB_GETBORDERS     = WM_USER + 7,\n    SB_SETMINHEIGHT   = WM_USER + 8,\n    SB_SIMPLE         = WM_USER + 9,\n    SB_GETRECT        = WM_USER + 10\n}\n\nenum {\n    MSGF_COMMCTRL_BEGINDRAG   = 0x4200,\n    MSGF_COMMCTRL_SIZEHEADER  = 0x4201,\n    MSGF_COMMCTRL_DRAGSELECT  = 0x4202,\n    MSGF_COMMCTRL_TOOLBARCUST = 0x4203\n}\n\nenum {\n    ILC_COLOR    = 0,\n    ILC_COLOR4   = 4,\n    ILC_COLOR8   = 8,\n    ILC_COLOR16  = 16,\n    ILC_COLOR24  = 24,\n    ILC_COLOR32  = 32,\n    ILC_COLORDDB = 254,\n    ILC_MASK     = 1,\n    ILC_PALETTE  = 2048\n}\n\nenum {\n    ILCF_MOVE,\n    ILCF_SWAP\n}\n\nenum {\n    ILS_NORMAL        = 0,\n    ILS_GLOW          = 1,\n    ILS_SHADOW        = 2,\n    ILS_SATURATE      = 4,\n    ILS_ALPHA         = 8,\n    ILD_BLEND25       = 2,\n    ILD_BLEND50       = 4,\n    ILD_SELECTED      = 4,\n    ILD_BLEND         = 4,\n    ILD_FOCUS         = 2,\n    ILD_MASK          = 16,\n    ILD_NORMAL        = 0,\n    ILD_TRANSPARENT   = 1,\n    ILD_IMAGE         = 0x0020,\n    ILD_ROP           = 0x0040,\n    ILD_OVERLAYMASK   = 0x0F00,\n    ILD_PRESERVEALPHA = 0x1000,\n    ILD_SCALE         = 0x2000,\n    ILD_DPISCALE      = 0x4000\n}\n\nenum {\n    HDS_HORZ    = 0,\n    HDS_BUTTONS = 2,\n    HDS_HIDDEN  = 8\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        HDS_HOTTRACK = 4,\n        HDS_DRAGDROP = 0x0040,\n        HDS_FULLDRAG = 0x0080\n    }\n}\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        HDS_FILTERBAR = 0x0100\n    }\n}\n\nenum {\n    NM_FIRST  = 0,\n    NM_LAST   = -99U,\n    LVN_FIRST = -100U,\n    LVN_LAST  = -199U,\n    HDN_FIRST = -300U,\n    HDN_LAST  = -399U,\n    TVN_FIRST = -400U,\n    TVN_LAST  = -499U,\n    TTN_FIRST = -520U,\n    TTN_LAST  = -549U,\n    TCN_FIRST = -550U,\n    TCN_LAST  = -580U,\n    CDN_FIRST = -601U, /* also in commdlg.h */\n    CDN_LAST  = -699U,\n    TBN_FIRST = -700U,\n    TBN_LAST  = -720U,\n    UDN_FIRST = -721U,\n    UDN_LAST  = -740U\n}\n/*static if (_WIN32_IE >= 0x300) {\n    enum {\n        RBN_FIRST  = -831U,\n        RBN_LAST   = -859U,\n        MCN_FIRST  = -750U,\n        MCN_LAST   = -759U,\n        DTN_FIRST  = -760U,\n        DTN_LAST   = -799U,\n        CBEN_FIRST = -800U,\n        CBEN_LAST  = -830U\n    }\n}*/\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        IPN_FIRST        = -860U,\n        IPN_LAST         = -879U,\n        IPN_FIELDCHANGED = IPN_FIRST,\n        SBN_FIRST        = -880U,\n        SBN_LAST         = -899U,\n        PGN_FIRST        = -900U,\n        PGN_LAST         = -950U,\n        PGN_SCROLL       = PGN_FIRST-1,\n        PGN_CALCSIZE     = PGN_FIRST-2\n    }\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        WMN_FIRST = -1000U,\n        WMN_LAST = -1200U,\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x501)\n{\n    enum {\n        BCN_FIRST = -1250U,\n        BCN_LAST = -1350U,\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x600)\n{\n    enum {\n        TRBN_FIRST = -1501U,\n        TRBN_LAST = -1519U,\n    }\n}\n\nenum {\n    HDI_WIDTH  = 1,\n    HDI_HEIGHT = 1,\n    HDI_TEXT   = 2,\n    HDI_FORMAT = 4,\n    HDI_LPARAM = 8,\n    HDI_BITMAP = 16\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        HDI_IMAGE      = 32,\n        HDI_DI_SETITEM = 64,\n        HDI_ORDER      = 128\n    }\n}\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        HDI_FILTER = 256\n    }\n}\n\nenum {\n    CBES_EX_NOEDITIMAGE       = 0x00000001,\n    CBES_EX_NOEDITIMAGEINDENT = 0x00000002,\n    CBES_EX_PATHWORDBREAKPROC = 0x00000004\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        CBES_EX_NOSIZELIMIT   = 0x00000008,\n        CBES_EX_CASESENSITIVE = 0x00000010,\n        CBEN_GETDISPINFOA     = CBEN_FIRST - 0,\n        CBEN_GETDISPINFOW     = CBEN_FIRST - 7,\n        CBEN_DRAGBEGINA       = CBEN_FIRST - 8,\n        CBEN_DRAGBEGINW       = CBEN_FIRST - 9\n    }\n}\n\nenum {\n    HDF_LEFT,\n    HDF_RIGHT,\n    HDF_CENTER,\n    HDF_JUSTIFYMASK,\n    HDF_RTLREADING, // = 4\n    HDF_OWNERDRAW = 0x8000,\n    HDF_STRING    = 0x4000,\n    HDF_BITMAP    = 0x2000\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        HDF_BITMAP_ON_RIGHT = 0x1000,\n        HDF_IMAGE           = 0x0800\n    }\n}\n\nenum {\n    CCM_FIRST            = 0x2000,\n    CCM_LAST             = CCM_FIRST + 0x200,\n    CCM_SETBKCOLOR       = 8193,\n    CCM_SETCOLORSCHEME   = 8194,\n    CCM_GETCOLORSCHEME   = 8195,\n    CCM_GETDROPTARGET    = 8196,\n    CCM_SETUNICODEFORMAT = 8197,\n    CCM_GETUNICODEFORMAT = 8198,\n    CCM_SETVERSION       = 0x2007,\n    CCM_GETVERSION       = 0x2008,\n    CCM_SETNOTIFYWINDOW  = 0x2009\n}\n\nenum {\n    HDM_GETITEMCOUNT = HDM_FIRST,\n    HDM_INSERTITEMA  = HDM_FIRST + 1,\n    HDM_INSERTITEMW  = HDM_FIRST + 10,\n    HDM_DELETEITEM   = HDM_FIRST + 2,\n    HDM_GETITEMA     = HDM_FIRST + 3,\n    HDM_GETITEMW     = HDM_FIRST + 11,\n    HDM_SETITEMA     = HDM_FIRST + 4,\n    HDM_SETITEMW     = HDM_FIRST + 12,\n    HDM_LAYOUT       = HDM_FIRST + 5\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        HDM_GETITEMRECT     = HDM_FIRST + 7,\n        HDM_SETIMAGELIST    = HDM_FIRST + 8,\n        HDM_GETIMAGELIST    = HDM_FIRST + 9,\n        HDM_ORDERTOINDEX    = HDM_FIRST + 15,\n        HDM_CREATEDRAGIMAGE = HDM_FIRST + 16,\n        HDM_GETORDERARRAY   = HDM_FIRST + 17,\n        HDM_SETORDERARRAY   = HDM_FIRST + 18,\n        HDM_SETHOTDIVIDER   = HDM_FIRST + 19\n    }\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        HDM_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT,\n        HDM_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT\n    }\n}\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        HDM_SETBITMAPMARGIN = HDM_FIRST + 20,\n        HDM_GETBITMAPMARGIN = HDM_FIRST + 21,\n        HDM_SETFILTERCHANGETIMEOUT = HDM_FIRST + 22,\n        HDM_EDITFILTER = HDM_FIRST + 23,\n        HDM_CLEARFILTER = HDM_FIRST + 24,\n    }\n}\nstatic if (_WIN32_IE >= 0x600) {\n    enum {\n        HDM_GETITEMDROPDOWNRECT = HDM_FIRST + 25,\n        HDM_GETOVERFLOWRECT = HDM_FIRST + 26,\n        HDM_GETFOCUSEDITEM = HDM_FIRST + 27,\n        HDM_SETFOCUSEDITEM = HDM_FIRST + 28,\n    }\n}\n\nenum {\n    HHT_NOWHERE   = 1,\n    HHT_ONHEADER  = 2,\n    HHT_ONDIVIDER = 4,\n    HHT_ONDIVOPEN = 8,\n    HHT_ABOVE     = 256,\n    HHT_BELOW     = 512,\n    HHT_TORIGHT   = 1024,\n    HHT_TOLEFT    = 2048\n}\n\nenum {\n    HDM_HITTEST = HDM_FIRST + 6\n}\n\nenum {\n    HDN_ITEMCHANGINGA    = HDN_FIRST -0,\n    HDN_ITEMCHANGINGW    = HDN_FIRST -20,\n    HDN_ITEMCHANGEDA     = HDN_FIRST -1,\n    HDN_ITEMCHANGEDW     = HDN_FIRST -21,\n    HDN_ITEMCLICKA       = HDN_FIRST -2,\n    HDN_ITEMCLICKW       = HDN_FIRST -22,\n    HDN_ITEMDBLCLICKA    = HDN_FIRST -3,\n    HDN_ITEMDBLCLICKW    = HDN_FIRST -23,\n    HDN_DIVIDERDBLCLICKA = HDN_FIRST -5,\n    HDN_DIVIDERDBLCLICKW = HDN_FIRST -25,\n    HDN_BEGINTRACKA      = HDN_FIRST -6,\n    HDN_BEGINTRACKW      = HDN_FIRST -26,\n    HDN_ENDTRACKA        = HDN_FIRST -7,\n    HDN_ENDTRACKW        = HDN_FIRST -27,\n    HDN_TRACKA           = HDN_FIRST -8,\n    HDN_TRACKW           = HDN_FIRST -28\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        HDN_ENDDRAG      = (HDN_FIRST-11),\n        HDN_BEGINDRAG    = (HDN_FIRST-10),\n        HDN_GETDISPINFOA = (HDN_FIRST-9),\n        HDN_GETDISPINFOW = (HDN_FIRST-29)\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        HICF_OTHER          = 0x00,\n        HICF_MOUSE          = 0x01,\n        HICF_ARROWKEYS      = 0x02,\n        HICF_ACCELERATOR    = 0x04,\n        HICF_DUPACCEL       = 0x08,\n        HICF_ENTERING       = 0x10,\n        HICF_LEAVING        = 0x20,\n        HICF_RESELECT       = 0x40,\n        HICF_LMOUSE         = 0x80,\n        HICF_TOGGLEDROPDOWN = 0x100\n    }\n}\n\nenum {\n    IPM_CLEARADDRESS = WM_USER + 100,\n    IPM_SETADDRESS   = WM_USER + 101,\n    IPM_GETADDRESS   = WM_USER + 102,\n    IPM_SETRANGE     = WM_USER + 103,\n    IPM_SETFOCUS     = WM_USER + 104,\n    IPM_ISBLANK      = WM_USER + 105\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        I_INDENTCALLBACK = -1,\n        I_IMAGENONE      = -2\n    }\n}\n\nenum {\n    TBSTATE_CHECKED       = 1,\n    TBSTATE_PRESSED       = 2,\n    TBSTATE_ENABLED       = 4,\n    TBSTATE_HIDDEN        = 8,\n    TBSTATE_INDETERMINATE = 16,\n    TBSTATE_WRAP          = 32\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TBSTATE_ELLIPSES = 0x40\n    }\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TBSTATE_MARKED = 0x0080\n    }\n}\n\nenum {\n    TBSTYLE_BUTTON     = 0,\n    TBSTYLE_SEP        = 1,\n    TBSTYLE_CHECK      = 2,\n    TBSTYLE_GROUP      = 4,\n    TBSTYLE_CHECKGROUP = TBSTYLE_GROUP | TBSTYLE_CHECK\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TBSTYLE_DROPDOWN = 8\n    }\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TBSTYLE_AUTOSIZE = 16,\n        TBSTYLE_NOPREFIX = 32\n    }\n}\nenum {\n    TBSTYLE_TOOLTIPS = 256,\n    TBSTYLE_WRAPABLE = 512,\n    TBSTYLE_ALTDRAG  = 1024\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TBSTYLE_FLAT        = 2048,\n        TBSTYLE_LIST        = 4096,\n        TBSTYLE_CUSTOMERASE = 8192\n    }\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TBSTYLE_REGISTERDROP    = 0x4000,\n        TBSTYLE_TRANSPARENT     = 0x8000,\n        TBSTYLE_EX_DRAWDDARROWS = 0x00000001\n    }\n}\nstatic if (_WIN32_IE >= 0x501) {\n    enum {\n        TBSTYLE_EX_MIXEDBUTTONS       = 8,\n        TBSTYLE_EX_HIDECLIPPEDBUTTONS = 16\n    }\n}\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        TBSTYLE_EX_DOUBLEBUFFER = 0x80\n    }\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        BTNS_BUTTON        = TBSTYLE_BUTTON,\n        BTNS_SEP           = TBSTYLE_SEP,\n        BTNS_CHECK         = TBSTYLE_CHECK,\n        BTNS_GROUP         = TBSTYLE_GROUP,\n        BTNS_CHECKGROUP    = TBSTYLE_CHECKGROUP,\n        BTNS_DROPDOWN      = TBSTYLE_DROPDOWN,\n        BTNS_AUTOSIZE      = TBSTYLE_AUTOSIZE,\n        BTNS_NOPREFIX      = TBSTYLE_NOPREFIX,\n        BTNS_WHOLEDROPDOWN = 0x0080\n    }\n}\nstatic if (_WIN32_IE >= 0x501) {\n    enum {\n        BTNS_SHOWTEXT = 0x0040\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TBCDRF_NOEDGES        = 0x10000,\n        TBCDRF_HILITEHOTTRACK = 0x20000,\n        TBCDRF_NOOFFSET       = 0x40000,\n        TBCDRF_NOMARK         = 0x80000,\n        TBCDRF_NOETCHEDEFFECT = 0x100000\n    }\n}\n\nenum HINST_COMMCTRL = cast(HINSTANCE) (-1);\n\nenum {\n    IDB_STD_SMALL_COLOR,\n    IDB_STD_LARGE_COLOR,\n    IDB_VIEW_SMALL_COLOR = 4,\n    IDB_VIEW_LARGE_COLOR = 5\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        IDB_HIST_SMALL_COLOR = 8,\n        IDB_HIST_LARGE_COLOR = 9\n    }\n}\n\nenum {\n    STD_CUT,\n    STD_COPY,\n    STD_PASTE,\n    STD_UNDO,\n    STD_REDOW,\n    STD_DELETE,\n    STD_FILENEW,\n    STD_FILEOPEN,\n    STD_FILESAVE,\n    STD_PRINTPRE,\n    STD_PROPERTIES,\n    STD_HELP,\n    STD_FIND,\n    STD_REPLACE,\n    STD_PRINT // = 14\n}\n\nenum {\n    VIEW_LARGEICONS,\n    VIEW_SMALLICONS,\n    VIEW_LIST,\n    VIEW_DETAILS,\n    VIEW_SORTNAME,\n    VIEW_SORTSIZE,\n    VIEW_SORTDATE,\n    VIEW_SORTTYPE,\n    VIEW_PARENTFOLDER,\n    VIEW_NETCONNECT,\n    VIEW_NETDISCONNECT,\n    VIEW_NEWFOLDER // = 11\n}\n\nenum {\n    TB_ENABLEBUTTON          = WM_USER + 1,\n    TB_CHECKBUTTON,\n    TB_PRESSBUTTON,\n    TB_HIDEBUTTON,\n    TB_INDETERMINATE, //     = WM_USER + 5,\n    TB_ISBUTTONENABLED       = WM_USER + 9,\n    TB_ISBUTTONCHECKED,\n    TB_ISBUTTONPRESSED,\n    TB_ISBUTTONHIDDEN,\n    TB_ISBUTTONINDETERMINATE, // = WM_USER + 13,\n    TB_SETSTATE              = WM_USER + 17,\n    TB_GETSTATE              = WM_USER + 18,\n    TB_ADDBITMAP             = WM_USER + 19,\n    TB_DELETEBUTTON          = WM_USER + 22,\n    TB_GETBUTTON,\n    TB_BUTTONCOUNT,\n    TB_COMMANDTOINDEX,\n    TB_SAVERESTOREA,\n    TB_CUSTOMIZE,\n    TB_ADDSTRINGA,\n    TB_GETITEMRECT,\n    TB_BUTTONSTRUCTSIZE,\n    TB_SETBUTTONSIZE,\n    TB_SETBITMAPSIZE,\n    TB_AUTOSIZE, //          = WM_USER + 33,\n    TB_GETTOOLTIPS           = WM_USER + 35,\n    TB_SETTOOLTIPS           = WM_USER + 36,\n    TB_SETPARENT             = WM_USER + 37,\n    TB_SETROWS               = WM_USER + 39,\n    TB_GETROWS,\n    TB_GETBITMAPFLAGS,\n    TB_SETCMDID,\n    TB_CHANGEBITMAP,\n    TB_GETBITMAP,\n    TB_GETBUTTONTEXTA,\n    TB_REPLACEBITMAP, //     = WM_USER + 46,\n    TB_GETBUTTONSIZE         = WM_USER + 58,\n    TB_SETBUTTONWIDTH        = WM_USER + 59,\n    TB_GETBUTTONTEXTW        = WM_USER + 75,\n    TB_SAVERESTOREW          = WM_USER + 76,\n    TB_ADDSTRINGW            = WM_USER + 77,\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TB_MARKBUTTON = WM_USER + 6\n    }\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TB_ISBUTTONHIGHLIGHTED = WM_USER + 14\n    }\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TB_ADDBUTTONSA   = WM_USER + 20,\n        TB_INSERTBUTTONA = WM_USER + 21\n    }\n} else {\n    enum {\n        TB_ADDBUTTONS   = WM_USER + 20,\n        TB_INSERTBUTTON = WM_USER + 21\n    }\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TB_SETINDENT = WM_USER + 47,\n        TB_SETIMAGELIST,\n        TB_GETIMAGELIST,\n        TB_LOADIMAGES,\n        TB_GETRECT,\n        TB_SETHOTIMAGELIST,\n        TB_GETHOTIMAGELIST,\n        TB_SETDISABLEDIMAGELIST,\n        TB_GETDISABLEDIMAGELIST,\n        TB_SETSTYLE,\n        TB_GETSTYLE,\n        //TB_GETBUTTONSIZE,\n        //TB_SETBUTTONWIDTH,\n        TB_SETMAXTEXTROWS,\n        TB_GETTEXTROWS // = WM_USER + 61\n    }\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TB_GETOBJECT            = WM_USER + 62,\n        TB_GETBUTTONINFOW,\n        TB_SETBUTTONINFOW,\n        TB_GETBUTTONINFOA,\n        TB_SETBUTTONINFOA,\n        TB_INSERTBUTTONW,\n        TB_ADDBUTTONSW,\n        TB_HITTEST, //          = WM_USER + 69\n        TB_SETEXTENDEDSTYLE     = WM_USER + 84,\n        TB_GETEXTENDEDSTYLE     = WM_USER + 85,\n        TB_SETDRAWTEXTFLAGS     = WM_USER + 70,\n        TB_GETHOTITEM,\n        TB_SETHOTITEM,\n        TB_SETANCHORHIGHLIGHT,\n        TB_GETANCHORHIGHLIGHT, // = WM_USER + 74\n        TB_MAPACCELERATORA      = WM_USER + 78,\n        TB_GETINSERTMARK,\n        TB_SETINSERTMARK,\n        TB_INSERTMARKHITTEST,\n        TB_MOVEBUTTON,\n        TB_GETMAXSIZE,\n        //TB_SETEXTENDEDSTYLE,\n        //TB_GETEXTENDEDSTYLE,\n        TB_GETPADDING,\n        TB_SETPADDING,\n        TB_SETINSERTMARKCOLOR,\n        TB_GETINSERTMARKCOLOR,\n        TB_MAPACCELERATORW,\n        TB_GETSTRINGW,\n        TB_GETSTRINGA, //       = WM_USER + 92\n        TB_SETHOTITEM2          = WM_USER + 94,\n        TB_SETLISTGAP           = WM_USER + 96,\n        TB_GETIMAGELISTCOUNT    = WM_USER + 98,\n        TB_GETIDEALSIZE         = WM_USER + 99,\n        //TB_TRANSLATEACCELERATOR = CCM_TRANSLATEACCELERATOR,\n        TB_SETCOLORSCHEME       = CCM_SETCOLORSCHEME,\n        TB_GETCOLORSCHEME       = CCM_GETCOLORSCHEME,\n        TB_SETUNICODEFORMAT     = CCM_SETUNICODEFORMAT,\n        TB_GETUNICODEFORMAT     = CCM_GETUNICODEFORMAT\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        TB_GETMETRICS = WM_USER + 101,\n        TB_SETMETRICS = WM_USER + 102,\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum {\n        TB_GETITEMDROPDOWNRECT = WM_USER + 103,\n        TB_SETPRESSEDIMAGELIST = WM_USER + 104,\n        TB_GETPRESSEDIMAGELIST = WM_USER + 105,\n    }\n}\n\nenum TBBF_LARGE = 1;\n\nenum {\n    TBN_GETBUTTONINFOA = TBN_FIRST -0,\n    TBN_BEGINDRAG      = TBN_FIRST -1,\n    TBN_ENDDRAG        = TBN_FIRST -2,\n    TBN_BEGINADJUST    = TBN_FIRST -3,\n    TBN_ENDADJUST      = TBN_FIRST -4,\n    TBN_RESET          = TBN_FIRST -5,\n    TBN_QUERYINSERT    = TBN_FIRST -6,\n    TBN_QUERYDELETE    = TBN_FIRST -7,\n    TBN_TOOLBARCHANGE  = TBN_FIRST -8,\n    TBN_CUSTHELP       = TBN_FIRST -9\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TBN_DROPDOWN = TBN_FIRST - 10\n    }\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TBN_HOTITEMCHANGE  = TBN_FIRST - 13,\n        TBN_DRAGOUT        = TBN_FIRST - 14,\n        TBN_DELETINGBUTTON = TBN_FIRST - 15,\n        TBN_GETDISPINFOA   = TBN_FIRST - 16,\n        TBN_GETDISPINFOW   = TBN_FIRST - 17,\n        TBN_GETINFOTIPA    = TBN_FIRST - 18,\n        TBN_GETINFOTIPW    = TBN_FIRST - 19,\n        TBN_GETBUTTONINFOW = TBN_FIRST - 20\n    }\n}\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        TBN_RESTORE       = TBN_FIRST - 21,\n        TBN_SAVE          = TBN_FIRST - 22,\n        TBN_INITCUSTOMIZE = TBN_FIRST - 23\n    }\n\n    enum {\n        TBNRF_HIDEHELP = 1,\n        TBNRF_ENDCUSTOMIZE\n    }\n\n    enum {\n        TBNF_IMAGE      = 1,\n        TBNF_TEXT       = 2,\n        TBNF_DI_SETITEM = 0x10000000\n    }\n}\n\nenum {\n    TTS_ALWAYSTIP = 1,\n    TTS_NOPREFIX\n}\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        TTS_NOANIMATE = 0x10,\n        TTS_NOFADE    = 0x20,\n        TTS_BALLOON   = 0x40,\n        TTS_CLOSE     = 0x80\n    }\n}\n\nenum {\n    TTF_IDISHWND   = 1,\n    TTF_CENTERTIP  = 2,\n    TTF_RTLREADING = 4,\n    TTF_SUBCLASS   = 16\n}\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TTF_TRACK       = 0x0020,\n        TTF_ABSOLUTE    = 0x0080,\n        TTF_TRANSPARENT = 0x0100,\n        TTF_DI_SETITEM  = 0x8000\n    }\n\n    static if (_WIN32_IE >= 0x501) {\n        enum {\n            TTF_PARSELINKS = 0x1000\n        }\n    }\n\n    enum {\n        TBCD_TICS = 1,\n        TBCD_THUMB,\n        TBCD_CHANNEL // = 3\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TBDDRET_DEFAULT,\n        TBDDRET_NODEFAULT,\n        TBDDRET_TREATPRESSED\n    }\n\n    enum {\n        TBIMHT_AFTER = 1,\n        TBIMHT_BACKGROUND\n    }\n}\n\nenum {\n    TTDT_AUTOMATIC,\n    TTDT_RESHOW,\n    TTDT_AUTOPOP,\n    TTDT_INITIAL\n}\n\nenum {\n    TTM_ACTIVATE        = WM_USER + 1,\n    TTM_SETDELAYTIME    = WM_USER + 3,\n    TTM_ADDTOOLA,\n    TTM_DELTOOLA,\n    TTM_NEWTOOLRECTA,\n    TTM_RELAYEVENT,\n    TTM_GETTOOLINFOA,\n    TTM_SETTOOLINFOA,\n    TTM_HITTESTA,\n    TTM_GETTEXTA,\n    TTM_UPDATETIPTEXTA,\n    TTM_GETTOOLCOUNT,\n    TTM_ENUMTOOLSA,\n    TTM_GETCURRENTTOOLA,\n    TTM_WINDOWFROMPOINT, // = WM_USER + 16\n    TTM_ADDTOOLW        = WM_USER + 50,\n    TTM_DELTOOLW,\n    TTM_NEWTOOLRECTW,\n    TTM_GETTOOLINFOW,\n    TTM_SETTOOLINFOW,\n    TTM_HITTESTW,\n    TTM_GETTEXTW,\n    TTM_UPDATETIPTEXTW,\n    TTM_ENUMTOOLSW,\n    TTM_GETCURRENTTOOLW // = WM_USER + 59\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TTM_TRACKACTIVATE = WM_USER + 17,\n        TTM_TRACKPOSITION,\n        TTM_SETTIPBKCOLOR,\n        TTM_SETTIPTEXTCOLOR,\n        TTM_GETDELAYTIME,\n        TTM_GETTIPBKCOLOR,\n        TTM_GETTIPTEXTCOLOR,\n        TTM_SETMAXTIPWIDTH,\n        TTM_GETMAXTIPWIDTH,\n        TTM_SETMARGIN,\n        TTM_GETMARGIN,\n        TTM_POP // = WM_USER + 28\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {  // IE4.0 ???\n    enum {\n        TTM_UPDATE = WM_USER + 29,\n        TTM_GETBUBBLESIZE,\n        TTM_ADJUSTRECT,\n        TTM_SETTITLEA,\n        TTM_SETTITLEW // = WM_USER + 33\n    }\n    static if (_WIN32_IE >= 0x500) {\n        alias TTM_SETTITLEW TTM_SETTITLE;\n    } else {\n        alias TTM_SETTITLEA TTM_SETTITLE;\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        TTM_POPUP = (WM_USER + 34),\n        TTM_GETTITLE = (WM_USER + 35),\n    }\n}\n\nenum {\n    TTN_GETDISPINFOA = TTN_FIRST - 0,\n    TTN_GETDISPINFOW = TTN_FIRST - 10,\n    TTN_NEEDTEXTA    = TTN_GETDISPINFOA,\n    TTN_NEEDTEXTW    = TTN_GETDISPINFOW,\n    TTN_SHOW         = TTN_FIRST-1,\n    TTN_POP          = TTN_FIRST-2\n}\n\nenum UD_MAXVAL = 0x7fff;\nenum UD_MINVAL = -UD_MAXVAL;\n\nenum {\n    UDN_DELTAPOS    = UDN_FIRST-1,\n    UDS_WRAP        = 1,\n    UDS_SETBUDDYINT = 2,\n    UDS_ALIGNRIGHT  = 4,\n    UDS_ALIGNLEFT   = 8,\n    UDS_AUTOBUDDY   = 16,\n    UDS_ARROWKEYS   = 32,\n    UDS_HORZ        = 64,\n    UDS_NOTHOUSANDS = 128\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        UDS_HOTTRACK = 0x0100\n    }\n}\n\nenum {\n    UDM_SETRANGE = WM_USER + 101,\n    UDM_GETRANGE,\n    UDM_SETPOS,\n    UDM_GETPOS,\n    UDM_SETBUDDY,\n    UDM_GETBUDDY,\n    UDM_SETACCEL,\n    UDM_GETACCEL,\n    UDM_SETBASE,\n    UDM_GETBASE // = WM_USER + 110\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        UDM_SETRANGE32 = WM_USER + 111,\n        UDM_GETRANGE32,\n        UDM_SETPOS32,\n        UDM_GETPOS32 // = WM_USER + 114\n    }\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        UDM_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT,\n        UDM_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT\n    }\n}\n\n/*enum {\n    SB_SETTEXTA       = WM_USER + 1,\n    SB_GETTEXTA,\n    SB_GETTEXTLENGTHA,\n    SB_SETPARTS,   // = WM_USER + 4\n    SB_GETPARTS       = WM_USER + 6,\n    SB_GETBORDERS,\n    SB_SETMINHEIGHT,\n    SB_SIMPLE,\n    SB_GETRECT,\n    SB_SETTEXTW,\n    SB_GETTEXTLENGTHW,\n    SB_GETTEXTW    // = WM_USER + 13\n}*/\n\n/*enum {\n    SBT_OWNERDRAW  = 0x1000,\n    SBT_NOBORDERS  = 256,\n    SBT_POPOUT     = 512,\n    SBT_RTLREADING = 1024\n}*/\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        SBT_TOOLTIPS         = 0x0800,\n        SBN_SIMPLEMODECHANGE = SBN_FIRST\n    }\n}\n\nenum {\n    TBS_AUTOTICKS      = 1,\n    TBS_VERT           = 2,\n    TBS_HORZ           = 0,\n    TBS_TOP            = 4,\n    TBS_BOTTOM         = 0,\n    TBS_LEFT           = 4,\n    TBS_RIGHT          = 0,\n    TBS_BOTH           = 8,\n    TBS_NOTICKS        = 16,\n    TBS_ENABLESELRANGE = 32,\n    TBS_FIXEDLENGTH    = 64,\n    TBS_NOTHUMB        = 128\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TBS_TOOLTIPS = 0x0100,\n        TBTS_TOP     = 0,\n        TBTS_LEFT,\n        TBTS_BOTTOM,\n        TBTS_RIGHT // = 3\n    }\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        TBS_REVERSED = 0x0200\n    }\n}\n\nstatic if (_WIN32_IE >= 0x501) {\n    enum {\n        TBS_DOWNISLEFT = 0x0400\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TBIF_BYINDEX = 0x80000000,\n        TBIF_COMMAND = 32,\n        TBIF_IMAGE   = 1,\n        TBIF_LPARAM  = 16,\n        TBIF_SIZE    = 64,\n        TBIF_STATE   = 4,\n        TBIF_STYLE   = 8,\n        TBIF_TEXT    = 2\n    }\n}\n\nenum {\n    TBM_GETPOS           = WM_USER,\n    TBM_GETRANGEMIN,\n    TBM_GETRANGEMAX,\n    TBM_GETTIC,\n    TBM_SETTIC,\n    TBM_SETPOS,\n    TBM_SETRANGE,\n    TBM_SETRANGEMIN,\n    TBM_SETRANGEMAX,\n    TBM_CLEARTICS,\n    TBM_SETSEL,\n    TBM_SETSELSTART,\n    TBM_SETSELEND,    // = WM_USER+12,\n    TBM_GETPTICS         = WM_USER+14,\n    TBM_GETTICPOS,\n    TBM_GETNUMTICS,\n    TBM_GETSELSTART,\n    TBM_GETSELEND,\n    TBM_CLEARSEL,\n    TBM_SETTICFREQ,\n    TBM_SETPAGESIZE,\n    TBM_GETPAGESIZE,\n    TBM_SETLINESIZE,\n    TBM_GETLINESIZE,\n    TBM_GETTHUMBRECT,\n    TBM_GETCHANNELRECT,\n    TBM_SETTHUMBLENGTH,\n    TBM_GETTHUMBLENGTH,\n    TBM_SETTOOLTIPS,\n    TBM_GETTOOLTIPS,\n    TBM_SETTIPSIDE,\n    TBM_SETBUDDY,\n    TBM_GETBUDDY, //     = WM_USER+33,\n    TBM_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT,\n    TBM_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT\n}\n\nenum {\n    TB_LINEUP,\n    TB_LINEDOWN,\n    TB_PAGEUP,\n    TB_PAGEDOWN,\n    TB_THUMBPOSITION,\n    TB_THUMBTRACK,\n    TB_TOP,\n    TB_BOTTOM,\n    TB_ENDTRACK // = 8\n}\n\nenum {\n    HOTKEYF_SHIFT   = 1,\n    HOTKEYF_CONTROL = 2,\n    HOTKEYF_ALT     = 4,\n    HOTKEYF_EXT     = 8\n}\n\nenum {\n    HKCOMB_NONE = 1,\n    HKCOMB_S    = 2,\n    HKCOMB_C    = 4,\n    HKCOMB_A    = 8,\n    HKCOMB_SC   = 16,\n    HKCOMB_SA   = 32,\n    HKCOMB_CA   = 64,\n    HKCOMB_SCA  = 128\n}\n\nenum {\n    HKM_SETHOTKEY = WM_USER + 1,\n    HKM_GETHOTKEY = WM_USER + 2,\n    HKM_SETRULES  = WM_USER + 3\n}\n\nenum {\n    PBM_SETRANGE     = WM_USER + 1,\n    PBM_SETPOS,\n    PBM_DELTAPOS,\n    PBM_SETSTEP,\n    PBM_STEPIT,   // = WM_USER + 5\n    PBM_SETRANGE32   = 1030,\n    PBM_GETRANGE,\n    PBM_GETPOS,\n    PBM_SETBARCOLOR, // = 1033\n    PBM_SETBKCOLOR   = CCM_SETBKCOLOR\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        PBM_SETMARQUEE = WM_USER + 10,\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum {\n        PBM_GETSTEP = WM_USER + 13,\n        PBM_GETBKCOLOR,\n        PBM_GETBARCOLOR,\n        PBM_SETSTATE,\n        PBM_GETSTATE,\n    }\n}\n\nenum {\n    PBS_SMOOTH   = 1,\n    PBS_VERTICAL = 4\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        PBS_MARQUEE = 8,\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum {\n        PBS_SMOOTHREVERSE = 16,\n    }\n}\n\nenum {\n    LVS_ICON,\n    LVS_REPORT,\n    LVS_SMALLICON,\n    LVS_LIST,        // = 3\n    LVS_TYPEMASK        = 3,\n    LVS_SINGLESEL       = 4,\n    LVS_SHOWSELALWAYS   = 8,\n    LVS_SORTASCENDING   = 16,\n    LVS_SORTDESCENDING  = 32,\n    LVS_SHAREIMAGELISTS = 64,\n    LVS_NOLABELWRAP     = 128,\n    LVS_AUTOARRANGE     = 256,\n    LVS_EDITLABELS      = 512,\n    LVS_NOSCROLL        = 0x2000,\n    LVS_TYPESTYLEMASK   = 0xFC00,\n    LVS_ALIGNTOP        = 0,\n    LVS_ALIGNLEFT       = 0x800,\n    LVS_ALIGNMASK       = 0xC00,\n    LVS_OWNERDRAWFIXED  = 0x400,\n    LVS_NOCOLUMNHEADER  = 0x4000,\n    LVS_NOSORTHEADER    = 0x8000\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        CDIS_CHECKED       = 8,\n        CDIS_DEFAULT       = 32,\n        CDIS_DISABLED      = 4,\n        CDIS_FOCUS         = 16,\n        CDIS_GRAYED        = 2,\n        CDIS_HOT           = 64,\n        CDIS_SELECTED      = 1,\n        CDIS_MARKED        = 128,\n        CDIS_INDETERMINATE = 256\n    }\n\n    static if (_WIN32_WINNT >= 0x501) {\n        enum {\n            CDIS_SHOWKEYBOARDCUES = 512\n        }\n    }\n\n    enum {\n        CDDS_POSTERASE     = 4,\n        CDDS_POSTPAINT     = 2,\n        CDDS_PREERASE      = 3,\n        CDDS_PREPAINT      = 1,\n        CDDS_ITEM          = 65536,\n        CDDS_ITEMPOSTERASE = 65540,\n        CDDS_ITEMPOSTPAINT = 65538,\n        CDDS_ITEMPREERASE  = 65539,\n        CDDS_ITEMPREPAINT  = 65537\n    }\n\n    static if (_WIN32_IE >= 0x400) {\n        enum {\n            CDDS_SUBITEM = 0x20000\n        }\n    }\n\n    enum {\n        CDRF_DODEFAULT         = 0x00,\n        CDRF_NOTIFYITEMDRAW    = 0x20,\n        CDRF_NOTIFYSUBITEMDRAW = 0x20,\n        CDRF_NOTIFYITEMERASE   = 0x80,\n        CDRF_NOTIFYPOSTERASE   = 0x40,\n        CDRF_NOTIFYPOSTPAINT   = 0x10,\n        CDRF_NEWFONT           = 0x02,\n        CDRF_SKIPDEFAULT       = 0x04\n    }\n\n    static if (_WIN32_IE >= 0x400) {\n        enum {\n            LVBKIF_SOURCE_NONE    = 0x00000000,\n            LVBKIF_SOURCE_HBITMAP = 0x00000001,\n            LVBKIF_SOURCE_URL     = 0x00000002,\n            LVBKIF_SOURCE_MASK    = 0x00000003,\n            LVBKIF_STYLE_NORMAL   = 0x00000000,\n            LVBKIF_STYLE_TILE     = 0x00000010,\n            LVBKIF_STYLE_MASK     = 0x00000010\n        }\n    }\n\n    static if (_WIN32_WINNT >= 0x501) {\n        enum {\n            LVBKIF_FLAG_TILEOFFSET = 0x00000100,\n            LVBKIF_TYPE_WATERMARK  = 0x10000000\n        }\n    }\n\n    enum {\n        LVS_OWNERDATA = 4096\n    }\n\n    enum {\n        LVS_EX_CHECKBOXES       = 4,\n        LVS_EX_FULLROWSELECT    = 32,\n        LVS_EX_GRIDLINES        = 1,\n        LVS_EX_HEADERDRAGDROP   = 16,\n        LVS_EX_ONECLICKACTIVATE = 64,\n        LVS_EX_SUBITEMIMAGES    = 2,\n        LVS_EX_TRACKSELECT      = 8,\n        LVS_EX_TWOCLICKACTIVATE = 128\n    }\n\n    enum {\n        LVSICF_NOINVALIDATEALL = 0x00000001,\n        LVSICF_NOSCROLL        = 0x00000002\n    }\n\n    static if (_WIN32_IE >= 0x400) {\n        enum {\n            LVS_EX_FLATSB         = 0x00000100,\n            LVS_EX_REGIONAL       = 0x00000200,\n            LVS_EX_INFOTIP        = 0x00000400,\n            LVS_EX_UNDERLINEHOT   = 0x00000800,\n            LVS_EX_UNDERLINECOLD  = 0x00001000,\n            LVS_EX_MULTIWORKAREAS = 0x00002000\n        }\n    }\n\n    static if (_WIN32_IE >= 0x500) {\n        enum {\n            LVS_EX_LABELTIP     = 0x00004000,\n            LVS_EX_BORDERSELECT = 0x00008000\n        }\n    }\n}\n\nenum {\n    LVSIL_NORMAL,\n    LVSIL_SMALL,\n    LVSIL_STATE\n}\n\nenum {\n    LVM_GETBKCOLOR             = LVM_FIRST,\n    LVM_SETBKCOLOR,\n    LVM_GETIMAGELIST,\n    LVM_SETIMAGELIST,\n    LVM_GETITEMCOUNT,       // = LVM_FIRST +   4\n    LVM_SORTITEMSEX            = LVM_FIRST +  81,\n    LVM_GETGROUPSTATE          = LVM_FIRST + 92,\n    LVM_GETFOCUSEDGROUP,\n    LVM_GETGROUPRECT           = LVM_FIRST + 98,\n    LVM_SETVIEW                = LVM_FIRST + 142,\n    LVM_GETVIEW,            // = LVM_FIRST + 143\n    LVM_INSERTGROUP            = LVM_FIRST + 145,\n    LVM_SETGROUPINFO           = LVM_FIRST + 147,\n    LVM_GETGROUPINFO           = LVM_FIRST + 149,\n    LVM_REMOVEGROUP,\n    LVM_MOVEGROUP,          // = LVM_FIRST + 151\n    LVM_GETGROUPCOUNT,\n    LVM_GETGROUPINFOBYINDEX,\n    LVM_MOVEITEMTOGROUP,\n    LVM_SETGROUPMETRICS        = LVM_FIRST + 155,\n    LVM_GETGROUPMETRICS,\n    LVM_ENABLEGROUPVIEW,\n    LVM_SORTGROUPS,\n    LVM_INSERTGROUPSORTED,\n    LVM_REMOVEALLGROUPS,\n    LVM_HASGROUP,\n    LVM_SETTILEVIEWINFO,\n    LVM_GETTILEVIEWINFO,\n    LVM_SETTILEINFO,\n    LVM_GETTILEINFO,\n    LVM_SETINSERTMARK,\n    LVM_GETINSERTMARK,\n    LVM_INSERTMARKHITTEST,\n    LVM_GETINSERTMARKRECT,\n    LVM_SETINSERTMARKCOLOR,\n    LVM_GETINSERTMARKCOLOR, // = LVM_FIRST + 171\n    LVM_SETINFOTIP             = LVM_FIRST + 173,\n    LVM_GETSELECTEDCOLUMN,\n    LVM_ISGROUPVIEWENABLED,\n    LVM_GETOUTLINECOLOR,\n    LVM_SETOUTLINECOLOR,    // = LVM_FIRST + 177\n    LVM_CANCELEDITLABEL        = LVM_FIRST + 179,\n    LVM_MAPINDEXTOID           = LVM_FIRST + 180,\n    LVM_MAPIDTOINDEX           = LVM_FIRST + 181,\n    LVM_ISITEMVISIBLE          = LVM_FIRST + 182,\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        LVM_SETSELECTEDCOLUMN  = LVM_FIRST + 140\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum {\n        LVM_GETEMPTYTEXT = LVM_FIRST + 204,\n        LVM_GETFOOTERRECT = LVM_FIRST + 205,\n        LVM_GETFOOTERINFO = LVM_FIRST + 206,\n        LVM_GETFOOTERITEMRECT = LVM_FIRST + 207,\n        LVM_GETFOOTERITEM = (LVM_FIRST + 208),\n        LVM_GETITEMINDEXRECT = (LVM_FIRST + 209),\n        LVM_SETITEMINDEXSTATE = (LVM_FIRST + 210),\n        LVM_GETNEXTITEMINDEX = (LVM_FIRST + 211),\n    }\n}\n\nenum {\n    LVIF_TEXT  = 1,\n    LVIF_IMAGE = 2,\n    LVIF_PARAM = 4,\n    LVIF_STATE = 8\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        LVIF_INDENT      = 16,\n        LVIF_NORECOMPUTE = 2048\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        LVIF_GROUPID = 128,\n        LVIF_COLUMNS = 256\n    }\n}\n\nenum {\n    LVIS_FOCUSED        = 1,\n    LVIS_SELECTED       = 2,\n    LVIS_CUT            = 4,\n    LVIS_DROPHILITED    = 8,\n    LVIS_OVERLAYMASK    = 0xF00,\n    LVIS_STATEIMAGEMASK = 0xF000\n}\n\nenum LPWSTR LPSTR_TEXTCALLBACKW = cast(LPWSTR) -1;\nenum LPSTR  LPSTR_TEXTCALLBACKA = cast(LPSTR) -1;\n\nenum I_IMAGECALLBACK = -1;\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        LVM_SETBKIMAGEA          = LVM_FIRST + 68,\n        LVM_SETBKIMAGEW          = LVM_FIRST + 138,\n        LVM_GETBKIMAGEA          = LVM_FIRST + 69,\n        LVM_GETBKIMAGEW          = LVM_FIRST + 139,\n        LV_MAX_WORKAREAS         = 16,\n        LVM_SETWORKAREAS         = LVM_FIRST + 65,\n        LVM_GETWORKAREAS         = LVM_FIRST + 70,\n        LVM_GETNUMBEROFWORKAREAS = LVM_FIRST + 73,\n        LVM_GETSELECTIONMARK     = LVM_FIRST + 66,\n        LVM_SETSELECTIONMARK     = LVM_FIRST + 67,\n        LVM_SETHOVERTIME         = LVM_FIRST + 71,\n        LVM_GETHOVERTIME         = LVM_FIRST + 72,\n        LVM_SETTOOLTIPS          = LVM_FIRST + 74,\n        LVM_GETTOOLTIPS          = LVM_FIRST + 78,\n        LVM_SETUNICODEFORMAT     = CCM_SETUNICODEFORMAT,\n        LVM_GETUNICODEFORMAT     = CCM_GETUNICODEFORMAT\n    }\n}\n\nenum {\n    LVNI_ALL,\n    LVNI_FOCUSED     = 1,\n    LVNI_SELECTED    = 2,\n    LVNI_CUT         = 4,\n    LVNI_DROPHILITED = 8,\n    LVNI_ABOVE       = 256,\n    LVNI_BELOW       = 512,\n    LVNI_TOLEFT      = 1024,\n    LVNI_TORIGHT     = 2048\n}\n\nenum {\n    LVM_GETITEMA          = LVM_FIRST + 5,\n    LVM_SETITEMA,\n    LVM_INSERTITEMA,\n    LVM_DELETEITEM,\n    LVM_DELETEALLITEMS,\n    LVM_GETCALLBACKMASK,\n    LVM_SETCALLBACKMASK,\n    LVM_GETNEXTITEM,\n    LVM_FINDITEMA,\n    LVM_GETITEMRECT,\n    LVM_SETITEMPOSITION,\n    LVM_GETITEMPOSITION,\n    LVM_GETSTRINGWIDTHA,\n    LVM_HITTEST,\n    LVM_ENSUREVISIBLE,\n    LVM_SCROLL,\n    LVM_REDRAWITEMS,\n    LVM_ARRANGE,\n    LVM_EDITLABELA,\n    LVM_GETEDITCONTROL,\n    LVM_GETCOLUMNA,\n    LVM_SETCOLUMNA,\n    LVM_INSERTCOLUMNA,\n    LVM_DELETECOLUMN,\n    LVM_GETCOLUMNWIDTH,\n    LVM_SETCOLUMNWIDTH, // = LVM_FIRST + 30,\n    LVM_CREATEDRAGIMAGE   = LVM_FIRST + 33,\n    LVM_GETVIEWRECT,\n    LVM_GETTEXTCOLOR,\n    LVM_SETTEXTCOLOR,\n    LVM_GETTEXTBKCOLOR,\n    LVM_SETTEXTBKCOLOR,\n    LVM_GETTOPINDEX,\n    LVM_GETCOUNTPERPAGE,\n    LVM_GETORIGIN,\n    LVM_UPDATE,\n    LVM_SETITEMSTATE,\n    LVM_GETITEMSTATE,\n    LVM_GETITEMTEXTA,\n    LVM_SETITEMTEXTA,\n    LVM_SETITEMCOUNT,\n    LVM_SORTITEMS,\n    LVM_SETITEMPOSITION32,\n    LVM_GETSELECTEDCOUNT,\n    LVM_GETITEMSPACING,\n    LVM_GETISEARCHSTRINGA, // = LVM_FIRST + 52,\n    LVM_GETITEMW          = LVM_FIRST + 75,\n    LVM_SETITEMW          = LVM_FIRST + 76,\n    LVM_INSERTITEMW       = LVM_FIRST + 77,\n    LVM_FINDITEMW         = LVM_FIRST + 83,\n    LVM_GETSTRINGWIDTHW   = LVM_FIRST + 87,\n    LVM_GETCOLUMNW        = LVM_FIRST + 95,\n    LVM_SETCOLUMNW        = LVM_FIRST + 96,\n    LVM_INSERTCOLUMNW     = LVM_FIRST + 97,\n    LVM_GETITEMTEXTW      = LVM_FIRST + 115,\n    LVM_SETITEMTEXTW,\n    LVM_GETISEARCHSTRINGW,\n    LVM_EDITLABELW     // = LVM_FIRST + 118,\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        LVM_GETHEADER                = LVM_FIRST + 31,\n        LVM_SETICONSPACING           = LVM_FIRST + 53,\n        LVM_SETEXTENDEDLISTVIEWSTYLE,\n        LVM_GETEXTENDEDLISTVIEWSTYLE,\n        LVM_GETSUBITEMRECT,\n        LVM_SUBITEMHITTEST,\n        LVM_SETCOLUMNORDERARRAY,\n        LVM_GETCOLUMNORDERARRAY,\n        LVM_SETHOTITEM,\n        LVM_GETHOTITEM,\n        LVM_SETHOTCURSOR,\n        LVM_GETHOTCURSOR,\n        LVM_APPROXIMATEVIEWRECT   // = LVM_FIRST + 64,\n    }\n}\n\nenum {\n    LVFI_PARAM     = 1,\n    LVFI_STRING    = 2,\n    LVFI_PARTIAL   = 8,\n    LVFI_WRAP      = 32,\n    LVFI_NEARESTXY = 64\n}\n\nenum {\n    LVIF_DI_SETITEM = 0x1000\n}\n\nenum {\n    LVIR_BOUNDS,\n    LVIR_ICON,\n    LVIR_LABEL,\n    LVIR_SELECTBOUNDS // = 3\n}\n\nenum {\n    LVHT_NOWHERE         = 1,\n    LVHT_ONITEMICON      = 2,\n    LVHT_ONITEMLABEL     = 4,\n    LVHT_ONITEMSTATEICON = 8,\n    LVHT_ONITEM          = LVHT_ONITEMICON | LVHT_ONITEMLABEL\n                           | LVHT_ONITEMSTATEICON,\n    LVHT_ABOVE           = 8,\n    LVHT_BELOW           = 16,\n    LVHT_TORIGHT         = 32,\n    LVHT_TOLEFT          = 64\n}\n\nenum {\n    LVA_DEFAULT    = 0,\n    LVA_ALIGNLEFT  = 1,\n    LVA_ALIGNTOP   = 2,\n    LVA_SNAPTOGRID = 5\n}\n\nenum {\n    LVCF_FMT     = 1,\n    LVCF_WIDTH   = 2,\n    LVCF_TEXT    = 4,\n    LVCF_SUBITEM = 8\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        LVCF_IMAGE = 16,\n        LVCF_ORDER = 32\n    }\n}\n\nenum {\n    LVCFMT_LEFT,\n    LVCFMT_RIGHT,\n    LVCFMT_CENTER,\n    LVCFMT_JUSTIFYMASK // = 3\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        LVCFMT_IMAGE           = 2048,\n        LVCFMT_BITMAP_ON_RIGHT = 4096,\n        LVCFMT_COL_HAS_IMAGES  = 32768\n    }\n}\n\nenum {\n    LVSCW_AUTOSIZE           = -1,\n    LVSCW_AUTOSIZE_USEHEADER = -2\n}\n\nenum {\n    LVN_ITEMCHANGING    = LVN_FIRST,\n    LVN_ITEMCHANGED     = LVN_FIRST - 1,\n    LVN_INSERTITEM      = LVN_FIRST - 2,\n    LVN_DELETEITEM      = LVN_FIRST - 3,\n    LVN_DELETEALLITEMS  = LVN_FIRST - 4,\n    LVN_BEGINLABELEDITA = LVN_FIRST - 5,\n    LVN_ENDLABELEDITA   = LVN_FIRST - 6,\n    LVN_COLUMNCLICK     = LVN_FIRST - 8,\n    LVN_BEGINDRAG       = LVN_FIRST - 9,\n    LVN_BEGINRDRAG      = LVN_FIRST - 11,\n    LVN_GETDISPINFOA    = LVN_FIRST - 50,\n    LVN_SETDISPINFOA    = LVN_FIRST - 51,\n    LVN_KEYDOWN         = LVN_FIRST - 55,\n    LVN_BEGINLABELEDITW = LVN_FIRST - 75,\n    LVN_ENDLABELEDITW   = LVN_FIRST - 76,\n    LVN_GETDISPINFOW    = LVN_FIRST - 77,\n    LVN_SETDISPINFOW    = LVN_FIRST - 78\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        LVN_MARQUEEBEGIN = LVN_FIRST - 56,\n        LVN_GETINFOTIPA  = LVN_FIRST - 57,\n        LVN_GETINFOTIPW  = LVN_FIRST - 58,\n        LVKF_ALT         = 1,\n        LVKF_CONTROL     = 2,\n        LVKF_SHIFT       = 4,\n        LVGIT_UNFOLDED   = 1\n    }\n}\n\nenum {\n    TVS_HASBUTTONS      = 1,\n    TVS_HASLINES        = 2,\n    TVS_LINESATROOT     = 4,\n    TVS_EDITLABELS      = 8,\n    TVS_DISABLEDRAGDROP = 16,\n    TVS_SHOWSELALWAYS   = 32\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TVS_RTLREADING  = 64,\n        TVS_NOTOOLTIPS  = 128,\n        TVS_CHECKBOXES  = 256,\n        TVS_TRACKSELECT = 512\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TVS_SINGLEEXPAND  = 1024,\n        TVS_INFOTIP       = 2048,\n        TVS_FULLROWSELECT = 4096,\n        TVS_NOSCROLL      = 8192,\n        TVS_NONEVENHEIGHT = 16384\n    }\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        TVS_NOHSCROLL = 0x8000\n    }\n}\n\nenum {\n    TVIF_TEXT          = 1,\n    TVIF_IMAGE         = 2,\n    TVIF_PARAM         = 4,\n    TVIF_STATE         = 8,\n    TVIF_HANDLE        = 16,\n    TVIF_SELECTEDIMAGE = 32,\n    TVIF_CHILDREN      = 64\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TVIF_INTEGRAL = 0x0080\n    }\n}\n\nenum {\n    TVIS_FOCUSED        = 1,\n    TVIS_SELECTED       = 2,\n    TVIS_CUT            = 4,\n    TVIS_DROPHILITED    = 8,\n    TVIS_BOLD           = 16,\n    TVIS_EXPANDED       = 32,\n    TVIS_EXPANDEDONCE   = 64,\n    TVIS_OVERLAYMASK    = 0xF00,\n    TVIS_STATEIMAGEMASK = 0xF000,\n    TVIS_USERMASK       = 0xF000\n}\n\nenum {\n    I_CHILDRENCALLBACK = -1\n}\n\nmixin DECLARE_HANDLE!(\"HTREEITEM\");\nmixin DECLARE_HANDLE!(\"HIMAGELIST\");\n\nversion (Win64)\n{\nenum HTREEITEM\n    TVI_ROOT  = cast(HTREEITEM) cast(ULONG_PTR)-0x10000,\n    TVI_FIRST = cast(HTREEITEM) cast(ULONG_PTR)-0xffff,\n    TVI_LAST  = cast(HTREEITEM) cast(ULONG_PTR)-0xfffe,\n    TVI_SORT  = cast(HTREEITEM) cast(ULONG_PTR)-0xfffd;\n} else {\nenum HTREEITEM\n    TVI_ROOT  = cast(HTREEITEM) 0xFFFF0000,\n    TVI_FIRST = cast(HTREEITEM) 0xFFFF0001,\n    TVI_LAST  = cast(HTREEITEM) 0xFFFF0002,\n    TVI_SORT  = cast(HTREEITEM) 0xFFFF0003;\n}\n\nenum {\n    TVSIL_NORMAL = 0,\n    TVSIL_STATE  = 2\n}\n\nenum {\n    TVM_INSERTITEMA       = TV_FIRST,\n    TVM_DELETEITEM        = TV_FIRST + 1,\n    TVM_EXPAND            = TV_FIRST + 2,\n    TVM_GETITEMRECT       = TV_FIRST + 4,\n    TVM_GETCOUNT,\n    TVM_GETINDENT,\n    TVM_SETINDENT,\n    TVM_GETIMAGELIST,\n    TVM_SETIMAGELIST,\n    TVM_GETNEXTITEM,\n    TVM_SELECTITEM,\n    TVM_GETITEMA,\n    TVM_SETITEMA,\n    TVM_EDITLABELA,\n    TVM_GETEDITCONTROL,\n    TVM_GETVISIBLECOUNT,\n    TVM_HITTEST,\n    TVM_CREATEDRAGIMAGE,\n    TVM_SORTCHILDREN,\n    TVM_ENSUREVISIBLE,\n    TVM_SORTCHILDRENCB,\n    TVM_ENDEDITLABELNOW,\n    TVM_GETISEARCHSTRINGA, // = TV_FIRST + 23\n    TVM_INSERTITEMW       = TV_FIRST + 50,\n    TVM_GETITEMW          = TV_FIRST + 62,\n    TVM_SETITEMW          = TV_FIRST + 63,\n    TVM_GETISEARCHSTRINGW = TV_FIRST + 64,\n    TVM_EDITLABELW        = TV_FIRST + 65\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TVM_GETTOOLTIPS = TV_FIRST + 25,\n        TVM_SETTOOLTIPS = TV_FIRST + 24\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TVM_SETINSERTMARK      = TV_FIRST + 26,\n        TVM_SETITEMHEIGHT,\n        TVM_GETITEMHEIGHT,\n        TVM_SETBKCOLOR,\n        TVM_SETTEXTCOLOR,\n        TVM_GETBKCOLOR,\n        TVM_GETTEXTCOLOR,\n        TVM_SETSCROLLTIME,\n        TVM_GETSCROLLTIME,  // = TV_FIRST + 34\n        TVM_SETINSERTMARKCOLOR = TV_FIRST + 37,\n        TVM_GETINSERTMARKCOLOR = TV_FIRST + 38,\n        TVM_SETUNICODEFORMAT   = CCM_SETUNICODEFORMAT,\n        TVM_GETUNICODEFORMAT   = CCM_GETUNICODEFORMAT\n    }\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        TVM_GETITEMSTATE = TV_FIRST + 39,\n        TVM_SETLINECOLOR = TV_FIRST + 40,\n        TVM_GETLINECOLOR = TV_FIRST + 41\n    }\n}\n\nstatic if (_WIN32_IE >= 0x501) {\n    enum {\n        TVM_MAPACCIDTOHTREEITEM = TV_FIRST + 42,\n        TVM_MAPHTREEITEMTOACCID = TV_FIRST + 43,\n        TVM_SETEXTENDEDSTYLE = TV_FIRST + 44,\n        TVM_GETEXTENDEDSTYLE = TV_FIRST + 45,\n        TVM_SETAUTOSCROLLINFO = TV_FIRST + 59\n    }\n}\n\nstatic if (_WIN32_IE >= 0x600) {\n    enum {\n        TVM_GETSELECTEDCOUNT = TV_FIRST + 70,\n        TVM_SHOWINFOTIP = TV_FIRST + 71,\n        TVM_GETITEMPARTRECT = TV_FIRST + 72,\n    }\n}\n\nenum {\n    TVE_COLLAPSE      = 1,\n    TVE_EXPAND        = 2,\n    TVE_TOGGLE        = 3,\n    TVE_COLLAPSERESET = 0x8000\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TVE_EXPANDPARTIAL = 0x4000\n    }\n}\n\nenum {\n    TVC_UNKNOWN,\n    TVC_BYMOUSE,\n    TVC_BYKEYBOARD // = 2\n}\n\nenum {\n    TVGN_ROOT,\n    TVGN_NEXT,\n    TVGN_PREVIOUS,\n    TVGN_PARENT,\n    TVGN_CHILD,\n    TVGN_FIRSTVISIBLE,\n    TVGN_NEXTVISIBLE,\n    TVGN_PREVIOUSVISIBLE,\n    TVGN_DROPHILITE,\n    TVGN_CARET // = 9\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TVGN_LASTVISIBLE = 10\n    }\n}\n\nstatic if (_WIN32_IE >= 0x600) {\n    enum {\n        TVGN_NEXTSELECTED = 11\n    }\n}\n\nenum {\n    TVN_SELCHANGINGA    = TVN_FIRST - 1,\n    TVN_SELCHANGEDA     = TVN_FIRST - 2,\n    TVN_GETDISPINFOA    = TVN_FIRST - 3,\n    TVN_SETDISPINFOA    = TVN_FIRST - 4,\n    TVN_ITEMEXPANDINGA  = TVN_FIRST - 5,\n    TVN_ITEMEXPANDEDA   = TVN_FIRST - 6,\n    TVN_BEGINDRAGA      = TVN_FIRST - 7,\n    TVN_BEGINRDRAGA     = TVN_FIRST - 8,\n    TVN_DELETEITEMA     = TVN_FIRST - 9,\n    TVN_BEGINLABELEDITA = TVN_FIRST - 10,\n    TVN_ENDLABELEDITA   = TVN_FIRST - 11,\n    TVN_KEYDOWN         = TVN_FIRST - 12,\n    TVN_SELCHANGINGW    = TVN_FIRST - 50,\n    TVN_SELCHANGEDW     = TVN_FIRST - 51,\n    TVN_GETDISPINFOW    = TVN_FIRST - 52,\n    TVN_SETDISPINFOW    = TVN_FIRST - 53,\n    TVN_ITEMEXPANDINGW  = TVN_FIRST - 54,\n    TVN_ITEMEXPANDEDW   = TVN_FIRST - 55,\n    TVN_BEGINDRAGW      = TVN_FIRST - 56,\n    TVN_BEGINRDRAGW     = TVN_FIRST - 57,\n    TVN_DELETEITEMW     = TVN_FIRST - 58,\n    TVN_BEGINLABELEDITW = TVN_FIRST - 59,\n    TVN_ENDLABELEDITW   = TVN_FIRST - 60\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TVNRET_DEFAULT   = 0,\n        TVNRET_SKIPOLD   = 1,\n        TVNRET_SKIPNEW   = 2,\n        TVN_GETINFOTIPA  = TVN_FIRST - 13,\n        TVN_GETINFOTIPW  = TVN_FIRST - 14,\n        TVN_SINGLEEXPAND = TVN_FIRST - 15\n    }\n}\n\nenum {\n    TVIF_DI_SETITEM = 0x1000\n}\n\nenum {\n    TVHT_NOWHERE         = 1,\n    TVHT_ONITEMICON      = 2,\n    TVHT_ONITEMLABEL     = 4,\n    TVHT_ONITEMINDENT    = 8,\n    TVHT_ONITEMBUTTON    = 16,\n    TVHT_ONITEMRIGHT     = 32,\n    TVHT_ONITEMSTATEICON = 64,\n    TVHT_ABOVE           = 256,\n    TVHT_BELOW           = 512,\n    TVHT_TORIGHT         = 1024,\n    TVHT_TOLEFT          = 2048,\n    TCHT_NOWHERE         = 1,\n    TCHT_ONITEMICON      = 2,\n    TCHT_ONITEMLABEL     = 4,\n    TVHT_ONITEM          = TVHT_ONITEMICON | TVHT_ONITEMLABEL\n                           | TVHT_ONITEMSTATEICON,\n    TCHT_ONITEM          = TCHT_ONITEMICON | TCHT_ONITEMLABEL\n}\n\nenum {\n    TCS_TABS              = 0,\n    TCS_RIGHTJUSTIFY      = 0,\n    TCS_SINGLELINE        = 0,\n    TCS_FORCEICONLEFT     = 16,\n    TCS_FORCELABELLEFT    = 32,\n    TCS_BUTTONS           = 256,\n    TCS_MULTILINE         = 512,\n    TCS_FIXEDWIDTH        = 1024,\n    TCS_RAGGEDRIGHT       = 2048,\n    TCS_FOCUSONBUTTONDOWN = 0x1000,\n    TCS_OWNERDRAWFIXED    = 0x2000,\n    TCS_TOOLTIPS          = 0x4000,\n    TCS_FOCUSNEVER        = 0x8000\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        TCS_BOTTOM         = 2,\n        TCS_RIGHT          = 2,\n        TCS_VERTICAL       = 128,\n        TCS_SCROLLOPPOSITE = 0x0001,\n        TCS_HOTTRACK       = 0x0040,\n        TCS_MULTISELECT    = 0x0004\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TCS_FLATBUTTONS       = 0x0008,\n        TCS_EX_FLATSEPARATORS = 0x00000001,\n        TCS_EX_REGISTERDROP   = 0x00000002\n    }\n}\n\nenum {\n    TCIF_TEXT       = 1,\n    TCIF_IMAGE      = 2,\n    TCIF_RTLREADING = 4,\n    TCIF_PARAM      = 8\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TCIF_STATE = 16\n    }\n}\n\nenum {\n    TCIS_BUTTONPRESSED = 1\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        TCIS_HIGHLIGHTED = 2\n    }\n}\n\nenum {\n    TCM_FIRST          = 0x1300,\n    TCM_GETIMAGELIST   = TCM_FIRST + 2,\n    TCM_SETIMAGELIST,\n    TCM_GETITEMCOUNT,\n    TCM_GETITEMA,\n    TCM_SETITEMA,\n    TCM_INSERTITEMA,\n    TCM_DELETEITEM,\n    TCM_DELETEALLITEMS,\n    TCM_GETITEMRECT,\n    TCM_GETCURSEL,\n    TCM_SETCURSEL,\n    TCM_HITTEST,\n    TCM_SETITEMEXTRA, // = TCM_FIRST + 14\n    TCM_ADJUSTRECT     = TCM_FIRST + 40,\n    TCM_SETITEMSIZE,\n    TCM_REMOVEIMAGE,\n    TCM_SETPADDING,\n    TCM_GETROWCOUNT,\n    TCM_GETTOOLTIPS,\n    TCM_SETTOOLTIPS,\n    TCM_GETCURFOCUS,\n    TCM_SETCURFOCUS,\n    TCM_SETMINTABWIDTH,\n    TCM_DESELECTALL, // = TCM_FIRST + 50\n    TCM_GETITEMW       = TCM_FIRST + 60,\n    TCM_SETITEMW       = TCM_FIRST + 61,\n    TCM_INSERTITEMW    = TCM_FIRST + 62\n}\n\nstatic if (_WIN32_IE >=0x0400) {\n    enum {\n        TCM_HIGHLIGHTITEM    = TCM_FIRST + 51,\n        TCM_SETEXTENDEDSTYLE = TCM_FIRST + 52,\n        TCM_GETEXTENDEDSTYLE = TCM_FIRST + 53,\n        TCM_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT,\n        TCM_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT\n    }\n}\n\nenum {\n    TCN_KEYDOWN     = TCN_FIRST,\n    TCN_SELCHANGE   = TCN_FIRST - 1,\n    TCN_SELCHANGING = TCN_FIRST - 2\n}\n\nenum {\n    NM_OUTOFMEMORY     = NM_FIRST - 1,\n    NM_CLICK           = NM_FIRST - 2,\n    NM_DBLCLK          = NM_FIRST - 3,\n    NM_RETURN          = NM_FIRST - 4,\n    NM_RCLICK          = NM_FIRST - 5,\n    NM_RDBLCLK         = NM_FIRST - 6,\n    NM_SETFOCUS        = NM_FIRST - 7,\n    NM_KILLFOCUS       = NM_FIRST - 8,\n    NM_CUSTOMDRAW      = NM_FIRST - 12,\n    NM_HOVER           = NM_FIRST - 13,\n    NM_NCHITTEST       = NM_FIRST - 14,\n    NM_KEYDOWN         = NM_FIRST - 15,\n    NM_RELEASEDCAPTURE = NM_FIRST - 16,\n    NM_SETCURSOR       = NM_FIRST - 17,\n    NM_CHAR            = NM_FIRST - 18,\n    NM_TOOLTIPSCREATED = NM_FIRST - 19\n}\n\nenum {\n    SBARS_SIZEGRIP = 256\n}\n\n/*enum {\n    CCM_FIRST            = 0x2000,\n    CCM_LAST             = CCM_FIRST + 0x200,\n    CCM_SETBKCOLOR       = 8193,\n    CCM_SETCOLORSCHEME   = 8194,\n    CCM_GETCOLORSCHEME   = 8195,\n    CCM_GETDROPTARGET    = 8196,\n    CCM_SETUNICODEFORMAT = 8197,\n    CCM_GETUNICODEFORMAT = 8198,\n    CCM_SETVERSION       = 0x2007,\n    CCM_GETVERSION       = 0x2008,\n    CCM_SETNOTIFYWINDOW  = 0x2009\n}*/\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        CCM_SETWINDOWTHEME = 0x200b,\n        CCM_DPISCALE       = 0x200c,\n\n        RB_GETBANDMARGINS = WM_USER + 40,\n        RB_SETWINDOWTHEME = CCM_SETWINDOWTHEME,\n        TB_SETWINDOWTHEME  = CCM_SETWINDOWTHEME,\n        TTM_SETWINDOWTHEME = CCM_SETWINDOWTHEME,\n    }\n}\n\nenum {\n    ICC_LISTVIEW_CLASSES = 1,\n    ICC_TREEVIEW_CLASSES = 2,\n    ICC_BAR_CLASSES      = 4,\n    ICC_TAB_CLASSES      = 8,\n    ICC_UPDOWN_CLASS     = 16,\n    ICC_PROGRESS_CLASS   = 32,\n    ICC_HOTKEY_CLASS     = 64,\n    ICC_ANIMATE_CLASS    = 128,\n    ICC_WIN95_CLASSES    = 255,\n    ICC_DATE_CLASSES     = 256,\n    ICC_USEREX_CLASSES   = 512,\n    ICC_COOL_CLASSES     = 1024\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        INFOTIPSIZE            = 1024,\n        ICC_INTERNET_CLASSES   = 2048,\n        ICC_PAGESCROLLER_CLASS = 4096,\n        ICC_NATIVEFNTCTL_CLASS = 8192\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        ICC_STANDARD_CLASSES = 0x00004000,\n        ICC_LINK_CLASS       = 0x00008000\n    }\n}\n\nenum {\n    GDTR_MIN = 1,\n    GDTR_MAX = 2\n}\n\nenum {\n    GMR_VISIBLE,\n    GMR_DAYSTATE\n}\n\nenum {\n    GDT_ERROR = -1,\n    GDT_VALID = 0,\n    GDT_NONE  = 1\n}\n\nenum {\n    DTS_SHORTDATEFORMAT = 0,\n    DTS_UPDOWN          = 1,\n    DTS_SHOWNONE        = 2,\n    DTS_LONGDATEFORMAT  = 4,\n    DTS_TIMEFORMAT      = 9,\n    DTS_APPCANPARSE     = 16,\n    DTS_RIGHTALIGN      = 32\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        DTS_SHORTDATECENTURYFORMAT = 0x000C\n    }\n}\n\nenum {\n    MCS_DAYSTATE    = 1,\n    MCS_MULTISELECT = 2,\n    MCS_WEEKNUMBERS = 4\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        MCS_NOTODAYCIRCLE = 0x0008,\n        MCS_NOTODAY       = 0x0010\n    }\n} else {\n    enum {\n        MCS_NOTODAY = 0x0008\n    }\n}\n\nenum {\n    DTM_FIRST         = 0x10000,\n    DTM_GETSYSTEMTIME = 0x1001,\n    DTM_SETSYSTEMTIME = 0x1002,\n    DTM_GETRANGE      = 0x1003,\n    DTM_SETRANGE      = 0x1004,\n    DTM_SETFORMATA    = 0x1005,\n    DTM_SETMCCOLOR    = 0x1006,\n    DTM_GETMCCOLOR    = 0x1007,\n    DTM_GETMONTHCAL   = 0x1008,\n    DTM_SETMCFONT     = 0x1009,\n    DTM_GETMCFONT     = 0x100a,\n    DTM_SETFORMATW    = 0x1050\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum {\n        DTM_SETMCSTYLE = DTM_FIRST + 11,\n        DTM_GETMCSTYLE,\n        DTM_CLOSEMONTHCAL,\n        DTM_GETDATETIMEPICKERINFO,\n        DTM_GETIDEALSIZE,\n    }\n}\n\nenum {\n    DTN_USERSTRINGA    = -758U,\n    DTN_USERSTRINGW    = -745U,\n    DTN_WMKEYDOWNA     = -757U,\n    DTN_WMKEYDOWNW     = -744U,\n    DTN_FORMATA        = -756U,\n    DTN_FORMATW        = -743U,\n    DTN_FORMATQUERYA   = -755U,\n    DTN_FORMATQUERYW   = -742U,\n    DTN_DROPDOWN       = -754U,\n    DTN_CLOSEUP        = -753U,\n    DTN_DATETIMECHANGE = -759U,\n}\n\nenum {\n    MCM_FIRST             = 0x1000,\n    MCM_GETCURSEL         = 0x1001,\n    MCM_SETCURSEL         = 0x1002,\n    MCM_GETMAXSELCOUNT    = 0x1003,\n    MCM_SETMAXSELCOUNT    = 0x1004,\n    MCM_GETSELRANGE       = 0x1005,\n    MCM_SETSELRANGE       = 0x1006,\n    MCM_GETMONTHRANGE     = 0x1007,\n    MCM_SETDAYSTATE       = 0x1008,\n    MCM_GETMINREQRECT     = 0x1009,\n    MCM_SETCOLOR          = 0x100a,\n    MCM_GETCOLOR          = 0x100b,\n    MCM_SETTODAY          = 0x100c,\n    MCM_GETTODAY          = 0x100d,\n    MCM_HITTEST           = 0x100e,\n    MCM_SETFIRSTDAYOFWEEK = 0x100f,\n    MCM_GETFIRSTDAYOFWEEK = 0x1010,\n    MCM_GETRANGE          = 0x1011,\n    MCM_SETRANGE          = 0x1012,\n    MCM_GETMONTHDELTA     = 0x1013,\n    MCM_SETMONTHDELTA     = 0x1014,\n    MCM_GETMAXTODAYWIDTH  = 0x1015,\n    MCM_GETUNICODEFORMAT  = CCM_GETUNICODEFORMAT,\n    MCM_SETUNICODEFORMAT  = CCM_SETUNICODEFORMAT\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum {\n        MCM_GETCURRENTVIEW = MCM_FIRST + 22,\n        MCM_GETCALENDARCOUNT,\n        MCM_GETCALENDARGRIDINFO,\n        MCM_GETCALID = MCM_FIRST + 27,\n        MCM_SETCALID,\n        MCM_SIZERECTTOMIN,\n        MCM_SETCALENDARBORDER,\n        MCM_GETCALENDARBORDER,\n        MCM_SETCURRENTVIEW,\n    }\n}\n\nenum {\n    MCN_SELCHANGE   = -749U,\n    MCN_GETDAYSTATE = -747U,\n    MCN_SELECT      = -746U\n}\n\nenum {\n    ODT_HEADER = 100,\n    ODT_TAB,\n    ODT_LISTVIEW // = 102\n}\n\nenum {\n    SB_SETBKCOLOR = 0x2001\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        SB_ISSIMPLE = 1038\n    }\n\n    enum {\n        MCSC_BACKGROUND,\n        MCSC_TEXT,\n        MCSC_TITLEBK,\n        MCSC_TITLETEXT,\n        MCSC_MONTHBK,\n        MCSC_TRAILINGTEXT // = 5\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        MCHT_TITLE            = 0x10000,\n        MCHT_CALENDAR         = 0x20000,\n        MCHT_TODAYLINK        = 0x30000,\n        MCHT_NEXT             = 0x1000000,\n        MCHT_PREV             = 0x2000000,\n        MCHT_NOWHERE          = 0x00,\n        MCHT_TITLEBK          = MCHT_TITLE,\n        MCHT_TITLEMONTH       = MCHT_TITLE | 0x0001,\n        MCHT_TITLEYEAR        = MCHT_TITLE | 0x0002,\n        MCHT_TITLEBTNNEXT     = MCHT_TITLE | MCHT_NEXT | 0x0003,\n        MCHT_TITLEBTNPREV     = MCHT_TITLE | MCHT_PREV | 0x0003,\n        MCHT_CALENDARBK       = MCHT_CALENDAR,\n        MCHT_CALENDARDATE     = MCHT_CALENDAR | 0x0001,\n        MCHT_CALENDARDATENEXT = MCHT_CALENDARDATE | MCHT_NEXT,\n        MCHT_CALENDARDATEPREV = MCHT_CALENDARDATE | MCHT_PREV,\n        MCHT_CALENDARDAY      = MCHT_CALENDAR | 0x0002,\n        MCHT_CALENDARWEEKNUM  = MCHT_CALENDAR | 0x0003\n    }\n}\n\nenum {\n    RBS_TOOLTIPS    = 256,\n    RBS_VARHEIGHT   = 512,\n    RBS_BANDBORDERS = 1024,\n    RBS_FIXEDORDER  = 2048\n}\n\nenum {\n    RBIM_IMAGELIST = 1\n}\n\nenum {\n    RB_SETCOLORSCHEME = CCM_SETCOLORSCHEME,\n    RB_GETCOLORSCHEME = CCM_GETCOLORSCHEME\n}\n\nenum {\n    RBBS_BREAK          = 0x0001,\n    RBBS_FIXEDSIZE      = 0x0002,\n    RBBS_CHILDEDGE      = 0x0004,\n    RBBS_HIDDEN         = 0x0008,\n    RBBS_NOVERT         = 0x0010,\n    RBBS_FIXEDBMP       = 0x0020,\n    RBBS_VARIABLEHEIGHT = 0x0040,\n    RBBS_GRIPPERALWAYS  = 0x0080,\n    RBBS_NOGRIPPER      = 0x0100\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        RBBS_USECHEVRON = 0x0200\n    }\n}\n\nstatic if (_WIN32_IE >= 0x501) {\n    enum {\n        RBBS_HIDETITLE = 0x0400,\n        RBBS_TOPALIGN  = 0x0800\n    }\n}\n\nenum {\n    RBBIM_STYLE      = 1,\n    RBBIM_COLORS     = 2,\n    RBBIM_TEXT       = 4,\n    RBBIM_IMAGE      = 8,\n    RBBIM_CHILD      = 16,\n    RBBIM_CHILDSIZE  = 32,\n    RBBIM_SIZE       = 64,\n    RBBIM_BACKGROUND = 128,\n    RBBIM_ID         = 256\n}\n\nenum {\n    RB_INSERTBANDA  = WM_USER + 1,\n    RB_DELETEBAND,\n    RB_GETBARINFO,\n    RB_SETBARINFO, // = WM_USER + 4\n    RB_SETBANDINFOA = WM_USER + 6,\n    RB_SETPARENT    = WM_USER + 7,\n    RB_INSERTBANDW  = WM_USER + 10,\n    RB_SETBANDINFOW,\n    RB_GETBANDCOUNT,\n    RB_GETROWCOUNT,\n    RB_GETROWHEIGHT // = WM_USER + 14,\n}\n\nenum {\n    RBN_HEIGHTCHANGE = RBN_FIRST\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    enum {\n        LVN_ODCACHEHINT    = LVN_FIRST - 13,\n        LVN_ODFINDITEMA    = LVN_FIRST - 52,\n        LVN_ODFINDITEMW    = LVN_FIRST - 79,\n        LVN_ITEMACTIVATE   = LVN_FIRST - 14,\n        LVN_ODSTATECHANGED = LVN_FIRST - 15\n    }\n\n    version (Unicode) {\n        enum {\n            LVN_ODFINDITEM = LVN_ODFINDITEMW\n        }\n    } else {\n        enum {\n            LVN_ODFINDITEM = LVN_ODFINDITEMA\n        }\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        SB_SETICON          = 1039,\n        SB_SETTIPTEXTA,\n        SB_SETTIPTEXTW,\n        SB_GETTIPTEXTA,\n        SB_GETTIPTEXTW,\n        SB_GETICON,      // = 1044\n        SB_SETUNICODEFORMAT = 0x2005,\n        SB_GETUNICODEFORMAT = 0x2006\n    }\n\n    enum {\n        PGF_INVISIBLE = 0,\n        PGF_NORMAL    = 1,\n        PGF_GRAYED    = 2,\n        PGF_DEPRESSED = 4,\n        PGF_HOT       = 8\n    }\n\n    enum {\n        PGB_TOPORLEFT,\n        PGB_BOTTOMORRIGHT\n    }\n\n    enum {\n        PGF_SCROLLUP    = 1,\n        PGF_SCROLLDOWN  = 2,\n        PGF_SCROLLLEFT  = 4,\n        PGF_SCROLLRIGHT = 8\n    }\n\n    enum {\n        PGK_SHIFT   = 1,\n        PGK_CONTROL = 2,\n        PGK_MENU    = 4\n    }\n\n    enum {\n        PGF_CALCWIDTH  = 1,\n        PGF_CALCHEIGHT = 2\n    }\n\n    enum {\n        PGM_FIRST    = 0x1400,\n        PGM_SETCHILD = PGM_FIRST + 1,\n        PGM_RECALCSIZE,\n        PGM_FORWARDMOUSE,\n        PGM_SETBKCOLOR,\n        PGM_GETBKCOLOR,\n        PGM_SETBORDER,\n        PGM_GETBORDER,\n        PGM_SETPOS,\n        PGM_GETPOS,\n        PGM_SETBUTTONSIZE,\n        PGM_GETBUTTONSIZE,\n        PGM_GETBUTTONSTATE, // = PGM_FIRST + 12\n        PGM_GETDROPTARGET = CCM_GETDROPTARGET\n    }\n\n    enum {\n        RBS_REGISTERDROP    = 4096,\n        RBS_AUTOSIZE        = 8192,\n        RBS_VERTICALGRIPPER = 16384,\n        RBS_DBLCLKTOGGLE    = 32768\n    }\n\n    enum {\n        RBBIM_IDEALSIZE  = 512,\n        RBBIM_LPARAM     = 1024,\n        RBBIM_HEADERSIZE = 2048\n    }\n\n    enum {\n        RB_HITTEST          = WM_USER + 8,\n        RB_GETRECT          = WM_USER + 9,\n        RB_IDTOINDEX        = WM_USER + 16,\n        RB_GETTOOLTIPS,\n        RB_SETTOOLTIPS,\n        RB_SETBKCOLOR,\n        RB_GETBKCOLOR,\n        RB_SETTEXTCOLOR,\n        RB_GETTEXTCOLOR,\n        RB_SIZETORECT,\n        RB_BEGINDRAG,\n        RB_ENDDRAG,\n        RB_DRAGMOVE,\n        RB_GETBARHEIGHT,\n        RB_GETBANDINFOW,\n        RB_GETBANDINFOA,\n        RB_MINIMIZEBAND,\n        RB_MAXIMIZEBAND, // = WM_USER + 31\n        RB_GETDROPTARGET    = CCM_GETDROPTARGET,\n        RB_GETBANDBORDERS   = WM_USER + 34,\n        RB_SHOWBAND         = WM_USER + 35,\n        RB_SETPALETTE       = WM_USER + 37,\n        RB_GETPALETTE       = WM_USER + 38,\n        RB_MOVEBAND         = WM_USER + 39,\n        RB_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT,\n        RB_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT\n    }\n\n    enum {\n        RBN_GETOBJECT     = RBN_FIRST - 1,\n        RBN_LAYOUTCHANGED = RBN_FIRST - 2,\n        RBN_AUTOSIZE      = RBN_FIRST - 3,\n        RBN_BEGINDRAG     = RBN_FIRST - 4,\n        RBN_ENDDRAG       = RBN_FIRST - 5,\n        RBN_DELETINGBAND  = RBN_FIRST - 6,\n        RBN_DELETEDBAND   = RBN_FIRST - 7,\n        RBN_CHILDSIZE     = RBN_FIRST - 8\n    }\n\n    enum {\n        RBNM_ID     = 1,\n        RBNM_STYLE  = 2,\n        RBNM_LPARAM = 4\n    }\n\n    enum {\n        RBHT_NOWHERE = 1,\n        RBHT_CAPTION,\n        RBHT_CLIENT,\n        RBHT_GRABBER\n    }\n\n    version (Unicode) {\n        alias SB_SETTIPTEXTW SB_SETTIPTEXT;\n        alias SB_GETTIPTEXTW SB_GETTIPTEXT;\n        alias RB_GETBANDINFOW RB_GETBANDINFO;\n    } else {\n        alias SB_SETTIPTEXTA SB_SETTIPTEXT;\n        alias SB_GETTIPTEXTA SB_GETTIPTEXT;\n        alias RB_GETBANDINFOA RB_GETBANDINFO;\n    }\n} else {\n    enum {\n        RB_GETBANDINFO = WM_USER + 5\n    }\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        RB_PUSHCHEVRON = WM_USER + 43,\n    }\n}\n\nstatic if (_WIN32_IE >= 0x600) {\n    enum {\n        RB_SETEXTENDEDSTYLE = WM_USER + 41,\n        RB_GETEXTENDEDSTYLE = WM_USER + 42,\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    enum {\n        RB_SETBANDWIDTH = WM_USER + 44,\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        ECM_FIRST = 0x1500,\n        BCM_FIRST = 0x1600,\n\n        BCM_GETIDEALSIZE = BCM_FIRST + 0x0001,\n        BCM_SETIMAGELIST = BCM_FIRST + 0x0002,\n        BCM_GETIMAGELIST = BCM_FIRST + 0x0003,\n        BCM_SETTEXTMARGIN = BCM_FIRST + 0x0004,\n        BCM_GETTEXTMARGIN = BCM_FIRST + 0x0005,\n\n        BCN_HOTITEMCHANGE = BCN_FIRST + 0x0001,\n    }\n\n    struct NMBCHOTITEM {\n        NMHDR hdr;\n        DWORD dwFlags;\n    }\n    alias NMBCHOTITEM* LPNMBCHOTITEM;\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum {\n        BST_DROPDOWNPUSHED      = 0x0400,\n\n        BS_SPLITBUTTON          = 0x0000_000C,\n        BS_DEFSPLITBUTTON       = 0x0000_000D,\n        BS_COMMANDLINK          = 0x0000_000E,\n        BS_DEFCOMMANDLINK       = 0x0000_000F,\n\n        BCSIF_GLYPH             = 0x0001,\n        BCSIF_IMAGE             = 0x0002,\n        BCSIF_STYLE             = 0x0004,\n        BCSIF_SIZE              = 0x0008,\n\n        BCSS_NOSPLIT            = 0x0001,\n        BCSS_STRETCH            = 0x0002,\n        BCSS_ALIGNLEFT          = 0x0004,\n        BCSS_IMAGE              = 0x0008,\n\n        BCM_SETDROPDOWNSTATE = BCM_FIRST + 0x0006,\n        BCM_SETSPLITINFO = BCM_FIRST + 0x0007,\n        BCM_GETSPLITINFO = BCM_FIRST + 0x0008,\n        BCM_SETNOTE = BCM_FIRST + 0x0009,\n        BCM_GETNOTE = BCM_FIRST + 0x000A,\n        BCM_GETNOTELENGTH = BCM_FIRST + 0x000B,\n        BCM_SETSHIELD = BCM_FIRST + 0x000C,\n\n        BCN_DROPDOWN = BCN_FIRST + 0x0002,\n    }\n\nenum HIMAGELIST BCCL_NOGLYPH = cast(HIMAGELIST)-1;\n\n    struct BUTTON_SPLITINFO\n    {\n        UINT mask;\n        HIMAGELIST himlGlyph;\n        UINT uSplitStyle;\n        SIZE size;\n    }\n    alias BUTTON_SPLITINFO* PBUTTON_SPLITINFO;\n}\n\nenum {\n    CBEM_INSERTITEMA = WM_USER + 1,\n    CBEM_SETIMAGELIST,\n    CBEM_GETIMAGELIST,\n    CBEM_GETITEMA,\n    CBEM_SETITEMA,\n    CBEM_GETCOMBOCONTROL,\n    CBEM_GETEDITCONTROL,\n    CBEM_SETEXSTYLE,\n    CBEM_GETEXSTYLE, // = WM_USER + 9)\n    CBEM_DELETEITEM  = CB_DELETESTRING\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        CBEM_SETEXTENDEDSTYLE = WM_USER + 14,\n        CBEM_GETEXTENDEDSTYLE = WM_USER + 9,\n        CBEM_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT,\n        CBEM_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT\n    }\n}\n\nenum {\n    CBEM_HASEDITCHANGED = WM_USER + 10,\n    CBEM_INSERTITEMW    = WM_USER + 11,\n    CBEM_SETITEMW       = WM_USER + 12,\n    CBEM_GETITEMW       = WM_USER + 13\n}\n\nstatic if (_WIN32_WINNT >= 0x501)\n{\n    enum {\n        CBEM_SETWINDOWTHEME = CCM_SETWINDOWTHEME\n    }\n}\n\nenum {\n    DA_LAST = 0x7fffffff\n}\n\nenum {\n    DPA_APPEND = 0x7fffffff,\n    DPA_ERR    = -1\n}\n\nenum {\n    DSA_APPEND = 0x7fffffff,\n    DSA_ERR    = -1\n}\n\nenum {\n    DPAS_SORTED       = 1,\n    DPAS_INSERTBEFORE = 2,\n    DPAS_INSERTAFTER  = 4\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        WSB_PROP_CYVSCROLL = 1,\n        WSB_PROP_CXHSCROLL = 2,\n        WSB_PROP_CYHSCROLL = 4,\n        WSB_PROP_CXVSCROLL = 8,\n        WSB_PROP_CXHTHUMB  = 16,\n        WSB_PROP_CYVTHUMB  = 32,\n        WSB_PROP_VBKGCOLOR = 64,\n        WSB_PROP_HBKGCOLOR = 128,\n        WSB_PROP_VSTYLE    = 256,\n        WSB_PROP_HSTYLE    = 512,\n        WSB_PROP_WINSTYLE  = 1024,\n        WSB_PROP_PALETTE   = 2048,\n        WSB_PROP_MASK      = 0xfff,\n        FSB_FLAT_MODE      = 2,\n        FSB_ENCARTA_MODE   = 1,\n        FSB_REGULAR_MODE   = 0\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        LIF_ITEMINDEX = 1,\n        LIF_STATE     = 2,\n        LIF_ITEMID    = 4,\n        LIF_URL       = 8\n    }\n\n    enum {\n        LIS_FOCUSED = 1,\n        LIS_ENABLED = 2,\n        LIS_VISITED = 4\n    }\n\n    enum {\n        LM_HITTEST        = WM_USER + 768,\n        LM_GETIDEALHEIGHT,\n        LM_SETITEM,\n        LM_GETITEM,     // = WM_USER + 771\n        LM_GETIDEALSIZE = LM_GETIDEALHEIGHT,\n    }\n\nenum size_t MAX_LINKID_TEXT  =   48;\nenum size_t L_MAX_URL_LENGTH = 2084;\n}\n\n\nstruct TBMETRICS {\n    UINT  cbSize = TBMETRICS.sizeof;\n    DWORD dwMask;\n    int   cxPad;\n    int   cyPad;\n    int   cxBarPad;\n    int   cyBarPad;\n    int   cxButtonSpacing;\n    int   cyButtonSpacing;\n}\nalias TBMETRICS* LPTBMETRICS;\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    struct TTGETTITLE {\n        DWORD dwSize = TTGETTITLE.sizeof;\n        UINT  uTitleBitmap;\n        UINT  cch;\n        WCHAR* pszTitle;\n    }\n    alias TTGETTITLE* PTTGETTITLE;\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    struct MCGRIDINFO {\n        UINT cbSize;\n        DWORD dwPart;\n        DWORD dwFlags;\n        int iCalendar;\n        int iRow;\n        int iCol;\n        BOOL bSelected;\n        SYSTEMTIME stStart;\n        SYSTEMTIME stEnd;\n        RECT rc;\n        PWSTR pszName;\n        size_t cchName;\n    }\n    alias MCGRIDINFO* PMCGRIDINFO;\n\n    struct DATETIMEPICKERINFO\n    {\n        DWORD cbSize;\n        RECT rcCheck;\n        DWORD stateCheck;\n        RECT rcButton;\n        DWORD stateButton;\n        HWND hwndEdit;\n        HWND hwndUD;\n        HWND hwndDropDown;\n    }\n    alias DATETIMEPICKERINFO* LPDATETIMEPICKERINFO;\n}\n\nstruct COMBOBOXEXITEMA {\n    UINT   mask;\n    INT_PTR iItem;\n    LPSTR  pszText;\n    int    cchTextMax;\n    int    iImage;\n    int    iSelectedImage;\n    int    iOverlay;\n    int    iIndent;\n    LPARAM lParam;\n}\nalias COMBOBOXEXITEMA*        PCOMBOBOXEXITEMA;\nalias const(COMBOBOXEXITEMA)* PCCOMBOEXITEMA;\n\nstruct COMBOBOXEXITEMW {\n    UINT   mask;\n    INT_PTR iItem;\n    LPWSTR pszText;\n    int    cchTextMax;\n    int    iImage;\n    int    iSelectedImage;\n    int    iOverlay;\n    int    iIndent;\n    LPARAM lParam;\n}\nalias COMBOBOXEXITEMW*        PCOMBOBOXEXITEMW;\nalias const(COMBOBOXEXITEMW)* PCCOMBOEXITEMW;\n\nstatic if (_WIN32_IE >= 0x400) {\n    struct NMCOMBOBOXEXA {\n        NMHDR           hdr;\n        COMBOBOXEXITEMA ceItem;\n    }\n    alias NMCOMBOBOXEXA* PNMCOMBOBOXEXA;\n\n    struct NMCOMBOBOXEXW {\n        NMHDR           hdr;\n        COMBOBOXEXITEMW ceItem;\n    }\n    alias NMCOMBOBOXEXW* PNMCOMBOBOXEXW;\n\n    struct NMCBEDRAGBEGINW {\n        NMHDR hdr;\n        int   iItemid;\n        WCHAR[CBEMAXSTRLEN] szText;\n    }\n    alias NMCBEDRAGBEGINW* LPNMCBEDRAGBEGINW, PNMCBEDRAGBEGINW;\n\n    struct NMCBEDRAGBEGINA {\n        NMHDR hdr;\n        int   iItemid;\n        char[CBEMAXSTRLEN] szText;\n    }\n    alias NMCBEDRAGBEGINA* LPNMCBEDRAGBEGINA, PNMCBEDRAGBEGINA;\n\n    struct NMIPADDRESS {\n        NMHDR hdr;\n        int   iField;\n        int   iValue;\n    }\n    alias NMIPADDRESS* LPNMIPADDRESS;\n\n    align (1)\n    struct NMLVKEYDOWN {\n    align (1):\n        NMHDR hdr;\n        WORD  wVKey;\n        UINT  flags;\n    }\n    alias NMLVKEYDOWN* LPNMLVKEYDOWN;\n\n    struct NMPGCALCSIZE {\n        NMHDR hdr;\n        DWORD dwFlag;\n        int   iWidth;\n        int   iHeight;\n    }\n    alias NMPGCALCSIZE* LPNMPGCALCSIZE;\n\n    align (1)\n    struct NMPGSCROLL {\n    align (1):\n        NMHDR hdr;\n        WORD  fwKeys;   // Note: this should be WORD if MSDN document says wrong\n        RECT  rcParent;\n        int   iDir;\n        int   iXpos;\n        int   iYpos;\n        int   iScroll;\n    }\n    alias NMPGSCROLL* LPNMPGSCROLL;\n\n    struct NMSELCHANGE {\n        NMHDR      nmhdr;\n        SYSTEMTIME stSelStart;\n        SYSTEMTIME stSelEnd;\n    }\n    alias NMSELCHANGE* LPNMSELCHANGE;\n\n    struct NMTBHOTITEM {\n        NMHDR hdr;\n        int   idOld;\n        int   idNew;\n        DWORD dwFlags;\n    }\n    alias NMTBHOTITEM* LPNMTBHOTITEM;\n\n    struct NMTBDISPINFOA {\n        NMHDR     hdr;\n        DWORD     dwMask;\n        int       idCommand;\n        DWORD_PTR lParam;\n        int       iImage;\n        LPSTR     pszText;\n        int       cchText;\n    }\n    alias NMTBDISPINFOA* LPNMTBDISPINFOA;\n\n    struct NMTBDISPINFOW {\n        NMHDR     hdr;\n        DWORD     dwMask;\n        int       idCommand;\n        DWORD_PTR lParam;\n        int       iImage;\n        LPWSTR    pszText;\n        int       cchText;\n    }\n    alias NMTBDISPINFOW* LPNMTBDISPINFOW;\n\n    struct NMTBGETINFOTIPA {\n        NMHDR  hdr;\n        LPSTR  pszText;\n        int    cchTextMax;\n        int    iItem;\n        LPARAM lParam;\n    }\n    alias NMTBGETINFOTIPA* LPNMTBGETINFOTIPA;\n\n    struct NMTBGETINFOTIPW {\n        NMHDR  hdr;\n        LPWSTR pszText;\n        int    cchTextMax;\n        int    iItem;\n        LPARAM lParam;\n    }\n    alias NMTBGETINFOTIPW* LPNMTBGETINFOTIPW;\n\n    struct NMMOUSE {\n        NMHDR     hdr;\n        DWORD_PTR dwItemSpec;\n        DWORD_PTR dwItemData;\n        POINT     pt;\n        LPARAM    dwHitInfo;\n    }\n    alias NMMOUSE* LPNMMOUSE;\n}\n\nstatic if (_WIN32_IE >= 0x401) {\n    struct NMTOOLTIPSCREATED {\n        NMHDR hdr;\n        HWND  hwndToolTips;\n    }\n    alias NMTOOLTIPSCREATED* LPNMTOOLTIPSCREATED;\n}\n\nstruct NMDATETIMECHANGE {\n    NMHDR      nmhdr;\n    DWORD      dwFlags;\n    SYSTEMTIME st;\n}\nalias NMDATETIMECHANGE* LPNMDATETIMECHANGE;\n\nstruct NMCBEENDEDITW {\n    NMHDR hdr;\n    BOOL  fChanged;\n    int   iNewSelection;\n    WCHAR[CBEMAXSTRLEN] szText;\n    int   iWhy;\n}\nalias NMCBEENDEDITW* LPNMCBEENDEDITW, PNMCBEENDEDITW;\n\nstruct NMCBEENDEDITA {\n    NMHDR hdr;\n    BOOL  fChanged;\n    int   iNewSelection;\n    char[CBEMAXSTRLEN] szText;\n    int   iWhy;\n}\nalias NMCBEENDEDITA* LPNMCBEENDEDITA, PNMCBEENDEDITA;\n\nstruct COLORMAP {\n    COLORREF from;\n    COLORREF to;\n}\nalias COLORMAP* LPCOLORMAP;\n\nstruct DRAGLISTINFO {\n    UINT  uNotification;\n    HWND  hWnd;\n    POINT ptCursor;\n}\nalias DRAGLISTINFO* LPDRAGLISTINFO;\n\nstruct TBBUTTON {\n    int   iBitmap;\n    int   idCommand;\n    BYTE  fsState;\n    BYTE  fsStyle;\n    version (Win64){\n        BYTE[6] bReserved;\n    } else {\n        BYTE[2] bReserved;\n    }\n    DWORD_PTR dwData;\n    INT_PTR iString;\n}\nalias TBBUTTON*        PTBBUTTON, LPTBBUTTON;\nalias const(TBBUTTON)* LPCTBBUTTON;\n\nstatic if (_WIN32_IE >= 0x400) {\n    struct TBBUTTONINFOA {\n        UINT  cbSize = TBBUTTONINFOA.sizeof;\n        DWORD dwMask;\n        int   idCommand;\n        int   iImage;\n        BYTE  fsState;\n        BYTE  fsStyle;\n        WORD  cx;\n        DWORD_PTR lParam;\n        LPSTR pszText;\n        int   cchText;\n    }\n    alias TBBUTTONINFOA* LPTBBUTTONINFOA;\n\n    struct TBBUTTONINFOW {\n        UINT   cbSize = TBBUTTONINFOW.sizeof;\n        DWORD  dwMask;\n        int    idCommand;\n        int    iImage;\n        BYTE   fsState;\n        BYTE   fsStyle;\n        WORD   cx;\n        DWORD_PTR lParam;\n        LPWSTR pszText;\n        int    cchText;\n    }\n    alias TBBUTTONINFOW* LPTBBUTTONINFOW;\n\n    struct TBINSERTMARK {\n        int   iButton;\n        DWORD dwFlags;\n    }\n    alias TBINSERTMARK* LPTBINSERTMARK;\n\n    struct LVBKIMAGEA {\n        ULONG   ulFlags;\n        HBITMAP hbm;\n        LPSTR   pszImage;\n        UINT    cchImageMax;\n        int     xOffsetPercent;\n        int     yOffsetPercent;\n    }\n    alias LVBKIMAGEA* LPLVBKIMAGEA;\n\n    struct LVBKIMAGEW {\n        ULONG   ulFlags;\n        HBITMAP hbm;\n        LPWSTR  pszImage;\n        UINT    cchImageMax;\n        int     xOffsetPercent;\n        int     yOffsetPercent;\n    }\n    alias LVBKIMAGEW* LPLVBKIMAGEW;\n}\n\n/*struct TBNOTIFY {\n    NMHDR    hdr;\n    int      iItem;\n    TBBUTTON tbButton;\n    int      cchText;\n    LPTSTR   pszText;\n}\nalias TBNOTIFY* LPTBNOTIFY;\n*/\n\n/*struct TBSAVEPARAMS {\n    HKEY    hkr;\n    LPCTSTR pszSubKey;\n    LPCTSTR pszValueName;\n}*/\n\nstruct IMAGEINFO {\n    HBITMAP hbmImage;\n    HBITMAP hbmMask;\n    int     Unused1;\n    int     Unused2;\n    RECT    rcImage;\n}\nalias IMAGEINFO* LPIMAGEINFO;\n\nstatic if (_WIN32_IE >= 0x500) {\n    struct HDITEMA {\n        UINT    mask;\n        int     cxy;\n        LPSTR   pszText;\n        HBITMAP hbm;\n        int     cchTextMax;\n        int     fmt;\n        LPARAM  lParam;\n        int     iImage;\n        int     iOrder;\n        UINT    type;\n        LPVOID  pvFilter;\n    }\n\n    struct HDITEMW {\n        UINT    mask;\n        int     cxy;\n        LPWSTR  pszText;\n        HBITMAP hbm;\n        int     cchTextMax;\n        int     fmt;\n        LPARAM  lParam;\n        int     iImage;\n        int     iOrder;\n        UINT    type;\n        LPVOID  pvFilter;\n    }\n} else static if (_WIN32_IE >= 0x300) {\n    struct HDITEMA {\n        UINT    mask;\n        int     cxy;\n        LPSTR   pszText;\n        HBITMAP hbm;\n        int     cchTextMax;\n        int     fmt;\n        LPARAM  lParam;\n        int     iImage;\n        int     iOrder;\n    }\n\n    struct HDITEMW {\n        UINT    mask;\n        int     cxy;\n        LPWSTR  pszText;\n        HBITMAP hbm;\n        int     cchTextMax;\n        int     fmt;\n        LPARAM  lParam;\n        int     iImage;\n        int     iOrder;\n    }\n} else {\n    struct HDITEMA {\n        UINT    mask;\n        int     cxy;\n        LPSTR   pszText;\n        HBITMAP hbm;\n        int     cchTextMax;\n        int     fmt;\n        LPARAM  lParam;\n    }\n\n    struct HDITEMW {\n        UINT    mask;\n        int     cxy;\n        LPWSTR  pszText;\n        HBITMAP hbm;\n        int     cchTextMax;\n        int     fmt;\n        LPARAM  lParam;\n    }\n}\nalias HDITEMA* LPHDITEMA;\nalias HDITEMW* LPHDITEMW;\n\ndeprecated {\n    alias HDITEMA HD_ITEMA;\n    alias HDITEMW HD_ITEMW;\n    //alias HDITEM HD_ITEM; fixme\n}\n\nstruct HD_LAYOUT {\n    RECT*      prc;\n    WINDOWPOS* pwpos;\n}\nalias HD_LAYOUT* LPHDLAYOUT;\ndeprecated alias HD_LAYOUT HDLAYOUT;\n\nstruct HD_HITTESTINFO {\n    POINT pt;\n    UINT  flags;\n    int   iItem;\n}\nalias HD_HITTESTINFO* LPHDHITTESTINFO;\n\nstruct HD_NOTIFYA {\n    NMHDR    hdr;\n    int      iItem;\n    int      iButton;\n    HDITEMA* pitem;\n}\n\nstruct HD_NOTIFYW {\n    NMHDR    hdr;\n    int      iItem;\n    int      iButton;\n    HDITEMW* pitem;\n}\n\n/* FIXME: NMHEADER structure (base for all events of the comctl controls)\n   is the same as HD_NOTIFY depending on the value of _WIN32_IE macro.\n   I'm defining both for now. */\nstruct NMHEADERA {\n    NMHDR    hdr;\n    int      iItem;\n    int      iButton;\n    HDITEMA* pitem;\n}\nalias NMHEADERA* LPNMHEADERA;\n\nstruct NMHEADERW {\n    NMHDR    hdr;\n    int      iItem;\n    int      iButton;\n    HDITEMW* pitem;\n}\nalias NMHEADERW* LPNMHEADERW;\n\nversion (Unicode) {\n    alias NMHEADERW NMHEADER;\n    alias LPNMHEADERW LPNMHEADER;\n} else {\n    alias NMHEADERA NMHEADER;\n    alias LPNMHEADERA LPNMHEADER;\n}\n// End FIXME\n\nstruct NMHDDISPINFOA {\n    NMHDR  hdr;\n    int    iItem;\n    UINT   mask;\n    LPSTR  pszText;\n    int    cchTextMax;\n    int    iImage;\n    LPARAM lParam;\n}\nalias NMHDDISPINFOA* LPNMHDDISPINFOA;\n\nstruct NMHDDISPINFOW {\n    NMHDR  hdr;\n    int    iItem;\n    UINT   mask;\n    LPWSTR pszText;\n    int    cchTextMax;\n    int    iImage;\n    LPARAM lParam;\n}\nalias NMHDDISPINFOW* LPNMHDDISPINFOW;\n\nstruct NMCUSTOMDRAW {\n    NMHDR  hdr;\n    DWORD  dwDrawStage;\n    HDC    hdc;\n    RECT   rc;\n    DWORD_PTR dwItemSpec;\n    UINT   uItemState;\n    LPARAM lItemlParam;\n}\nalias NMCUSTOMDRAW* LPNMCUSTOMDRAW;\n\nstatic if (_WIN32_IE >= 0x400) {\n    struct NMLVCUSTOMDRAW {\n        NMCUSTOMDRAW nmcd;\n        COLORREF     clrText;\n        COLORREF     clrTextBk;\n        int          iSubItem;\n    }\n} else {\n    struct NMLVCUSTOMDRAW {\n        NMCUSTOMDRAW nmcd;\n        COLORREF     clrText;\n        COLORREF     clrTextBk;\n    }\n}\nalias NMLVCUSTOMDRAW* LPNMLVCUSTOMDRAW;\n\nstatic if (_WIN32_IE >= 0x400) {\n    struct NMLVGETINFOTIPA {\n        NMHDR  hdr;\n        DWORD  dwFlags;\n        LPSTR  pszText;\n        int    cchTextMax;\n        int    iItem;\n        int    iSubItem;\n        LPARAM lParam;\n    }\n    alias NMLVGETINFOTIPA* LPNMLVGETINFOTIPA;\n\n    struct NMLVGETINFOTIPW {\n        NMHDR  hdr;\n        DWORD  dwFlags;\n        LPWSTR pszText;\n        int    cchTextMax;\n        int    iItem;\n        int    iSubItem;\n        LPARAM lParam;\n    }\n    alias NMLVGETINFOTIPW* LPNMLVGETINFOTIPW;\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    struct NMTVCUSTOMDRAW {\n        NMCUSTOMDRAW nmcd;\n        COLORREF     clrText;\n        COLORREF     clrTextBk;\n        int          iLevel;\n    }\n} else {\n    struct NMTVCUSTOMDRAW {\n        NMCUSTOMDRAW nmcd;\n        COLORREF     clrText;\n        COLORREF     clrTextBk;\n    }\n}\nalias NMTVCUSTOMDRAW* LPNMTVCUSTOMDRAW;\n\nstatic if (_WIN32_IE >= 0x400) {\n    static if (_WIN32_WINNT >= 0x501) {\n        struct NMTBCUSTOMDRAW {\n            NMCUSTOMDRAW nmcd;\n            HBRUSH       hbrMonoDither;\n            HBRUSH       hbrLines;\n            HPEN         hpenLines;\n            COLORREF     clrText;\n            COLORREF     clrMark;\n            COLORREF     clrTextHighlight;\n            COLORREF     clrBtnFace;\n            COLORREF     clrBtnHighlight;\n            COLORREF     clrHighlightHotTrack;\n            RECT         rcText;\n            int          nStringBkMode;\n            int          nHLStringBkMode;\n            int          iListGap;\n        }\n    } else {\n        struct NMTBCUSTOMDRAW {\n            NMCUSTOMDRAW nmcd;\n            HBRUSH       hbrMonoDither;\n            HBRUSH       hbrLines;\n            HPEN         hpenLines;\n            COLORREF     clrText;\n            COLORREF     clrMark;\n            COLORREF     clrTextHighlight;\n            COLORREF     clrBtnFace;\n            COLORREF     clrBtnHighlight;\n            COLORREF     clrHighlightHotTrack;\n            RECT         rcText;\n            int          nStringBkMode;\n            int          nHLStringBkMode;\n        }\n    }\n    alias NMTBCUSTOMDRAW* LPNMTBCUSTOMDRAW;\n\n    struct NMITEMACTIVATE {\n        NMHDR  hdr;\n        int    iItem;\n        int    iSubItem;\n        UINT   uNewState;\n        UINT   uOldState;\n        UINT   uChanged;\n        POINT  ptAction;\n        LPARAM lParam;\n        UINT   uKeyFlags;\n    }\n    alias NMITEMACTIVATE* LPNMITEMACTIVATE;\n}\n\nstruct TBADDBITMAP {\n    HINSTANCE hInst;\n    UINT_PTR  nID;\n}\nalias TBADDBITMAP* LPTBADDBITMAP;\n\nstruct TBSAVEPARAMSA {\n    HKEY   hkr;\n    LPCSTR pszSubKey;\n    LPCSTR pszValueName;\n}\n\nstruct TBSAVEPARAMSW {\n    HKEY    hkr;\n    LPCWSTR pszSubKey;\n    LPCWSTR pszValueName;\n}\n\nstruct TBREPLACEBITMAP {\n    HINSTANCE hInstOld;\n    UINT_PTR  nIDOld;\n    HINSTANCE hInstNew;\n    UINT_PTR  nIDNew;\n    int       nButtons;\n}\nalias TBREPLACEBITMAP* LPTBREPLACEBITMAP;\n\nstatic if (_WIN32_IE >= 0x500) {\n    struct NMTOOLBARA {\n        NMHDR    hdr;\n        int      iItem;\n        TBBUTTON tbButton;\n        int      cchText;\n        LPSTR    pszText;\n        RECT     rcButton;\n    }\n\n    struct NMTOOLBARW {\n        NMHDR    hdr;\n        int      iItem;\n        TBBUTTON tbButton;\n        int      cchText;\n        LPWSTR   pszText;\n        RECT     rcButton;\n    }\n} else {\n    struct NMTOOLBARA {\n        NMHDR    hdr;\n        int      iItem;\n        TBBUTTON tbButton;\n        int      cchText;\n        LPSTR    pszText;\n    }\n\n    struct NMTOOLBARW {\n        NMHDR    hdr;\n        int      iItem;\n        TBBUTTON tbButton;\n        int      cchText;\n        LPWSTR   pszText;\n    }\n}\nalias NMTOOLBARA* LPNMTOOLBARA;\nalias NMTOOLBARW* LPNMTOOLBARW;\n\nalias NMTOOLBARA TBNOTIFYA;\nalias LPNMTOOLBARA LPTBNOTIFYA;\n\nalias NMTOOLBARW TBNOTIFYW;\nalias LPNMTOOLBARW LPTBNOTIFYW;\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    struct TOOLINFOA {\n        UINT      cbSize = TOOLINFOA.sizeof;\n        UINT      uFlags;\n        HWND      hwnd;\n        UINT_PTR  uId;\n        RECT      rect;\n        HINSTANCE hinst;\n        LPSTR     lpszText;\n        LPARAM    lParam;\n        void*     lpReserved;\n    }\n\n    struct TOOLINFOW {\n        UINT      cbSize = TOOLINFOW.sizeof;\n        UINT      uFlags;\n        HWND      hwnd;\n        UINT_PTR  uId;\n        RECT      rect;\n        HINSTANCE hinst;\n        LPWSTR    lpszText;\n        LPARAM    lParam;\n        void*     lpReserved;\n    }\n\nenum size_t\n        TTTOOLINFOA_V1_SIZE = TOOLINFOA.lParam.offsetof,\n        TTTOOLINFOW_V1_SIZE = TOOLINFOW.lParam.offsetof,\n        TTTOOLINFOA_V2_SIZE = TOOLINFOA.lpReserved.offsetof,\n        TTTOOLINFOW_V2_SIZE = TOOLINFOW.lpReserved.offsetof,\n        TTTOOLINFOA_V3_SIZE = TOOLINFOA.sizeof,\n        TTTOOLINFOW_V3_SIZE = TOOLINFOW.sizeof;\n} else static if (_WIN32_IE >= 0x300) {\n    struct TOOLINFOA {\n        UINT      cbSize = TOOLINFOA.sizeof;\n        UINT      uFlags;\n        HWND      hwnd;\n        UINT      uId;\n        RECT      rect;\n        HINSTANCE hinst;\n        LPSTR     lpszText;\n        LPARAM    lParam;\n    }\n\n    struct TOOLINFOW {\n        UINT      cbSize = TOOLINFOW.sizeof;\n        UINT      uFlags;\n        HWND      hwnd;\n        UINT      uId;\n        RECT      rect;\n        HINSTANCE hinst;\n        LPWSTR    lpszText;\n        LPARAM    lParam;\n    }\n\nenum size_t\n        TTTOOLINFOA_V1_SIZE = TOOLINFOA.lParam.offsetof,\n        TTTOOLINFOW_V1_SIZE = TOOLINFOW.lParam.offsetof,\n        TTTOOLINFOA_V2_SIZE = TOOLINFOA.sizeof,\n        TTTOOLINFOW_V2_SIZE = TOOLINFOW.sizeof;\n} else {\n    struct TOOLINFOA {\n        UINT      cbSize = TOOLINFOA.sizeof;\n        UINT      uFlags;\n        HWND      hwnd;\n        UINT      uId;\n        RECT      rect;\n        HINSTANCE hinst;\n        LPSTR     lpszText;\n    }\n\n    struct TOOLINFOW {\n        UINT      cbSize = TOOLINFOW.sizeof;\n        UINT      uFlags;\n        HWND      hwnd;\n        UINT      uId;\n        RECT      rect;\n        HINSTANCE hinst;\n        LPWSTR    lpszText;\n    }\n\nenum size_t\n        TTTOOLINFOA_V1_SIZE = TOOLINFOA.sizeof,\n        TTTOOLINFOW_V1_SIZE = TOOLINFOW.sizeof;\n}\nalias TOOLINFOA TTTOOLINFOA;\nalias TOOLINFOW TTTOOLINFOW;\nalias TTTOOLINFOA* LPTTTOOLINFOA, PTOOLINFOA, LPTOOLINFOA;\nalias TTTOOLINFOW* LPTTTOOLINFOW, PTOOLINFOW, LPTOOLINFOW;\n\nstruct TTHITTESTINFOA {\n    HWND      hwnd;\n    POINT     pt;\n    TOOLINFOA ti;\n}\nalias TTHITTESTINFOA* LPTTHITTESTINFOA, LPHITTESTINFOA;\n\nstruct TTHITTESTINFOW {\n    HWND      hwnd;\n    POINT     pt;\n    TOOLINFOW ti;\n}\nalias TTHITTESTINFOW* LPTTHITTESTINFOW, LPHITTESTINFOW;\n\nstatic if (_WIN32_IE >= 0x300) {\n    struct NMTTDISPINFOA {\n        NMHDR     hdr;\n        LPSTR     lpszText;\n        char[80]  szText;\n        HINSTANCE hinst;\n        UINT      uFlags;\n        LPARAM    lParam;\n    }\n\n    struct NMTTDISPINFOW {\n        NMHDR     hdr;\n        LPWSTR    lpszText;\n        WCHAR[80] szText;\n        HINSTANCE hinst;\n        UINT      uFlags;\n        LPARAM    lParam;\n    }\n} else {\n    struct NMTTDISPINFOA {\n        NMHDR     hdr;\n        LPSTR     lpszText;\n        char[80]  szText;\n        HINSTANCE hinst;\n        UINT      uFlags;\n    }\n\n    struct NMTTDISPINFOW {\n        NMHDR     hdr;\n        LPWSTR    lpszText;\n        WCHAR[80] szText;\n        HINSTANCE hinst;\n        UINT      uFlags;\n    }\n}\nalias NMTTDISPINFOA* LPNMTTDISPINFOA;\nalias NMTTDISPINFOW* LPNMTTDISPINFOW;\nalias NMTTDISPINFOA TOOLTIPTEXTA;\nalias LPNMTTDISPINFOA LPTOOLTIPTEXTA;\nalias NMTTDISPINFOW TOOLTIPTEXTW;\nalias LPNMTTDISPINFOW LPTOOLTIPTEXTW;\n\nstruct UDACCEL {\n    UINT nSec;\n    UINT nInc;\n}\nalias UDACCEL* LPUDACCEL;\n\nstruct NMUPDOWN {\n    NMHDR hdr;\n    int   iPos;\n    int   iDelta;\n}\nalias NMUPDOWN* LPNMUPDOWN;\n\ndeprecated {\n    alias NMUPDOWN NM_UPDOWN;\n    alias LPNMUPDOWN LPNM_UPDOWN;\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    struct LVITEMA {\n        UINT   mask;\n        int    iItem;\n        int    iSubItem;\n        UINT   state;\n        UINT   stateMask;\n        LPSTR  pszText;\n        int    cchTextMax;\n        int    iImage;\n        LPARAM lParam;\n        int    iIndent;\n        int    iGroupId;\n        UINT   cColumns;\n        PUINT  puColumns;\n    }\n\n    struct LVITEMW {\n        UINT   mask;\n        int    iItem;\n        int    iSubItem;\n        UINT   state;\n        UINT   stateMask;\n        LPWSTR pszText;\n        int    cchTextMax;\n        int    iImage;\n        LPARAM lParam;\n        int    iIndent;\n        int    iGroupId;\n        UINT   cColumns;\n        PUINT  puColumns;\n    }\n} else static if (_WIN32_IE >= 0x300) {\n    struct LVITEMA {\n        UINT   mask;\n        int    iItem;\n        int    iSubItem;\n        UINT   state;\n        UINT   stateMask;\n        LPSTR  pszText;\n        int    cchTextMax;\n        int    iImage;\n        LPARAM lParam;\n        int    iIndent;\n    }\n\n    struct LVITEMW {\n        UINT   mask;\n        int    iItem;\n        int    iSubItem;\n        UINT   state;\n        UINT   stateMask;\n        LPWSTR pszText;\n        int    cchTextMax;\n        int    iImage;\n        LPARAM lParam;\n        int    iIndent;\n    }\n} else {\n    struct LVITEMA {\n        UINT   mask;\n        int    iItem;\n        int    iSubItem;\n        UINT   state;\n        UINT   stateMask;\n        LPSTR  pszText;\n        int    cchTextMax;\n        int    iImage;\n        LPARAM lParam;\n    }\n\n    struct LVITEMW {\n        UINT   mask;\n        int    iItem;\n        int    iSubItem;\n        UINT   state;\n        UINT   stateMask;\n        LPWSTR pszText;\n        int    cchTextMax;\n        int    iImage;\n        LPARAM lParam;\n    }\n}\nalias LVITEMA* LPLVITEMA;\nalias LVITEMW* LPLVITEMW;\nalias LVITEMA LV_ITEMA;\nalias LVITEMW LV_ITEMW;\n\nstruct LVFINDINFOA {\n    UINT   flags;\n    LPCSTR psz;\n    LPARAM lParam;\n    POINT  pt;\n    UINT   vkDirection;\n}\n\nstruct LVFINDINFOW {\n    UINT    flags;\n    LPCWSTR psz;\n    LPARAM  lParam;\n    POINT   pt;\n    UINT    vkDirection;\n}\n\nalias LVFINDINFOA* LPFINDINFOA;\nalias LVFINDINFOA LV_FINDINFOA;\nalias LVFINDINFOW* LPFINDINFOW;\nalias LVFINDINFOW LV_FINDINFOW;\n\nstruct NMLVFINDITEMA {\n    NMHDR       hdr;\n    int         iStart;\n    LVFINDINFOA lvfi;\n}\n\nstruct NMLVFINDITEMW {\n    NMHDR       hdr;\n    int         iStart;\n    LVFINDINFOW lvfi;\n}\n\nalias NMLVFINDITEMA* PNMLVFINDITEMA, LPNMLVFINDITEMA;\nalias NMLVFINDITEMW* PNMLVFINDITEMW, LPNMLVFINDITEMW;\n\nstatic if (_WIN32_IE >= 0x300) {\n    struct LVHITTESTINFO {\n        POINT pt;\n        UINT  flags;\n        int   iItem;\n        int   iSubItem;\n    }\n} else {\n    struct LVHITTESTINFO {\n        POINT pt;\n        UINT  flags;\n        int   iItem;\n    }\n}\nalias LVHITTESTINFO* LPLVHITTESTINFO;\nalias LVHITTESTINFO LV_HITTESTINFO;\n\nstatic if (_WIN32_IE >= 0x300) {\n    struct LVCOLUMNA {\n        UINT  mask;\n        int   fmt;\n        int   cx;\n        LPSTR pszText;\n        int   cchTextMax;\n        int   iSubItem;\n        int   iImage;\n        int   iOrder;\n    }\n    struct LVCOLUMNW {\n        UINT   mask;\n        int    fmt;\n        int    cx;\n        LPWSTR pszText;\n        int    cchTextMax;\n        int    iSubItem;\n        int    iImage;\n        int    iOrder;\n    }\n} else {\n    struct LVCOLUMNA {\n        UINT  mask;\n        int   fmt;\n        int   cx;\n        LPSTR pszText;\n        int   cchTextMax;\n        int   iSubItem;\n    }\n    struct LVCOLUMNW {\n        UINT   mask;\n        int    fmt;\n        int    cx;\n        LPWSTR pszText;\n        int    cchTextMax;\n        int    iSubItem;\n    }\n}\nalias LVCOLUMNA* LPLVCOLUMNA;\nalias LVCOLUMNW* LPLVCOLUMNW;\nalias LVCOLUMNA LV_COLUMNA;\nalias LVCOLUMNW LV_COLUMNW;\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    /*  SG: The definitions in this static if block are from the MSDN docs.\n     *  They are not in MinGW, but nonetheless required for macros that are.\n     */\n    struct LVGROUP {\n        UINT    cbSize = LVGROUP.sizeof;\n        UINT    mask;\n        LPWSTR  pszHeader;\n        int     cchHeader;\n        LPWSTR  pszFooter;\n        int     cchFooter;\n        int     iGroupId;\n        UINT    stateMask;\n        UINT    state;\n        UINT    uAlign;\n        static if (_WIN32_WINNT >= 0x600) {\n            LPWSTR  pszSubtitle;\n            UINT    cchSubtitle;\n            LPWSTR  pszTask;\n            UINT    cchTask;\n            LPWSTR  pszDescriptionTop;\n            UINT    cchDescriptionTop;\n            LPWSTR  pszDescriptionBottom;\n            UINT    cchDescriptionBottom;\n            int     iTitleImage;\n            int     iExtendedImage;\n            int     iFirstItem;         // Read only\n            UINT    cItems;             // Read only\n            LPWSTR  pszSubsetTitle;     // NULL if group is not subset\n            UINT    cchSubsetTitle;\n        }\n    }\n    alias LVGROUP* PLVGROUP;\n\n    struct LVGROUPMETRICS {\n        UINT     cbSize = LVGROUPMETRICS.sizeof;\n        UINT     mask;\n        UINT     Left;\n        UINT     Top;\n        UINT     Right;\n        UINT     Bottom;\n        COLORREF crLeft;\n        COLORREF crTop;\n        COLORREF crRight;\n        COLORREF crBottom;\n        COLORREF crHeader;\n        COLORREF crFooter;\n    }\n    alias LVGROUPMETRICS* PLVGROUPMETRICS;\n\n    struct LVINSERTMARK {\n        UINT  cbSize = LVINSERTMARK.sizeof;\n        DWORD dwFlags;\n        int   iItem;\n        DWORD dwReserved;\n    }\n    alias LVINSERTMARK* PLVINSERTMARK;\n    alias LVINSERTMARK* LPLVINSERTMARK;\n\n    struct LVTILEINFO {\n        UINT     cbSize = LVTILEINFO.sizeof;\n        int      iItem;\n        UINT     cColumns;\n        PUINT    puColumns;\n        static if (_WIN32_WINNT >= 0x600) {\n            int* piColFmt;\n        }\n    }\n    alias LVTILEINFO* PLVTILEINFO;\n\n    struct LVTILEVIEWINFO {\n        UINT  cbSize = LVTILEVIEWINFO.sizeof;\n        DWORD dwMask;\n        DWORD dwFlags;\n        SIZE  sizeTile;\n        int   cLines;\n        RECT  rcLabelMargin;\n    }\n    alias LVTILEVIEWINFO* PLVTILEVIEWINFO;\n\n    struct LVINSERTGROUPSORTED {\n        PFNLVGROUPCOMPARE pfnGroupCompare;\n        LPVOID* pvData;\n        LVGROUP lvGroup;\n    }\n    alias LVINSERTGROUPSORTED* PLVINSERTGROUPSORTED;\n\n    extern (Windows) alias int function(INT, INT, VOID*) PFNLVGROUPCOMPARE;\n\n    struct LVSETINFOTIP {\n        UINT    cbSize = LVSETINFOTIP.sizeof;\n        DWORD   dwFlags;\n        LPWSTR  pszText;\n        int     iItem;\n        int     iSubItem;\n        HBITMAP hbmp;\n    }\n    alias LVSETINFOTIP* PLVSETINFOTIP;\n\n    struct BUTTON_IMAGELIST {\n        HIMAGELIST himl;\n        RECT margin;\n        UINT uAlign;\n    }\n    alias BUTTON_IMAGELIST* PBUTTON_IMAGELIST;\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    struct LVITEMINDEX\n    {\n        int iItem;\n        int iGroup;\n    };\n    alias LVITEMINDEX* PLVITEMINDEX;\n\n    struct LVFOOTERINFO\n    {\n        UINT mask;\n        LPWSTR pszText;\n        int cchTextMax;\n        UINT cItems;\n    }\n    alias LVFOOTERINFO* LPLVFOOTERINFO;\n\n    struct LVFOOTERITEM\n    {\n        UINT mask;\n        int iItem;\n        LPWSTR pszText;\n        int cchTextMax;\n        UINT state;\n        UINT stateMask;\n    }\n    alias LVFOOTERITEM *LPLVFOOTERITEM;\n\n    alias UINT TVITEMPART;\n    enum {\n        TVGIPR_BUTTON  = 0x0001,\n    }\n}\n\nextern (Windows) alias int function(LPARAM, LPARAM, LPARAM) PFNLVCOMPARE;\n\nstruct NMLISTVIEW {\n    NMHDR  hdr;\n    int    iItem;\n    int    iSubItem;\n    UINT   uNewState;\n    UINT   uOldState;\n    UINT   uChanged;\n    POINT  ptAction;\n    LPARAM lParam;\n}\nalias NMLISTVIEW* LPNMLISTVIEW;\n\ndeprecated {\n    alias NMLISTVIEW NM_LISTVIEW;\n    alias LPNMLISTVIEW LPNM_LISTVIEW;\n}\n\nstruct NMLVDISPINFOA {\n    NMHDR    hdr;\n    LV_ITEMA item;\n}\nalias NMLVDISPINFOA* LPNMLVDISPINFOA;\nalias NMLVDISPINFOA LV_DISPINFOA;\n\nstruct NMLVDISPINFOW {\n    NMHDR    hdr;\n    LV_ITEMW item;\n}\nalias NMLVDISPINFOW* LPNMLVDISPINFOW;\nalias NMLVDISPINFOW LV_DISPINFOW;\n\nalign (1)\nstruct LV_KEYDOWN {\nalign (1):\n    NMHDR hdr;\n    WORD  wVKey;\n    UINT  flags;\n}\n\nstruct NMLVCACHEHINT {\n    NMHDR hdr;\n    int   iFrom;\n    int   iTo;\n}\nalias NMLVCACHEHINT* LPNMLVCACHEHINT, PNM_CACHEHINT, LPNM_CACHEHINT;\nalias NMLVCACHEHINT NM_CACHEHINT;\n\nstruct TVITEMA {\n    UINT      mask;\n    HTREEITEM hItem;\n    UINT      state;\n    UINT      stateMask;\n    LPSTR     pszText;\n    int       cchTextMax;\n    int       iImage;\n    int       iSelectedImage;\n    int       cChildren;\n    LPARAM    lParam;\n}\nalias TVITEMA* LPTVITEMA, LPTV_ITEMA;\nalias TVITEMA TV_ITEMA;\n\nstruct TVITEMW {\n    UINT      mask;\n    HTREEITEM hItem;\n    UINT      state;\n    UINT      stateMask;\n    LPWSTR    pszText;\n    int       cchTextMax;\n    int       iImage;\n    int       iSelectedImage;\n    int       cChildren;\n    LPARAM    lParam;\n}\nalias TVITEMW* LPTVITEMW, LPTV_ITEMW;\nalias TVITEMW TV_ITEMW;\n\nstatic if (_WIN32_IE >= 0x400) {\n    struct TVITEMEXA {\n        UINT      mask;\n        HTREEITEM hItem;\n        UINT      state;\n        UINT      stateMask;\n        LPSTR     pszText;\n        int       cchTextMax;\n        int       iImage;\n        int       iSelectedImage;\n        int       cChildren;\n        LPARAM    lParam;\n        int       iIntegral;\n    }\n    alias TVITEMEXA* LPTVITEMEXA;\n\n    struct TVITEMEXW {\n        UINT      mask;\n        HTREEITEM hItem;\n        UINT      state;\n        UINT      stateMask;\n        LPWSTR    pszText;\n        int       cchTextMax;\n        int       iImage;\n        int       iSelectedImage;\n        int       cChildren;\n        LPARAM    lParam;\n        int       iIntegral;\n    }\n    alias TVITEMEXW* LPTVITEMEXW;\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    struct TVINSERTSTRUCTA {\n        HTREEITEM hParent;\n        HTREEITEM hInsertAfter;\n        union {\n            TVITEMEXA itemex;\n            TV_ITEMA  item;\n        }\n    }\n\n    struct TVINSERTSTRUCTW {\n        HTREEITEM hParent;\n        HTREEITEM hInsertAfter;\n        union {\n            TVITEMEXW itemex;\n            TV_ITEMW  item;\n        }\n    }\n} else {\n    struct TVINSERTSTRUCTA {\n        HTREEITEM hParent;\n        HTREEITEM hInsertAfter;\n        TV_ITEMA  item;\n    }\n\n    struct TVINSERTSTRUCTW {\n        HTREEITEM hParent;\n        HTREEITEM hInsertAfter;\n        TV_ITEMW  item;\n    }\n}\nalias TVINSERTSTRUCTA* LPTVINSERTSTRUCTA, LPTV_INSERTSTRUCTA;\nalias TVINSERTSTRUCTA TV_INSERTSTRUCTA;\nalias TVINSERTSTRUCTW* LPTVINSERTSTRUCTW, LPTV_INSERTSTRUCTW;\nalias TVINSERTSTRUCTW TV_INSERTSTRUCTW;\n\nstruct TVHITTESTINFO {\n    POINT     pt;\n    UINT      flags;\n    HTREEITEM hItem;\n}\nalias TVHITTESTINFO* LPTVHITTESTINFO, LPTV_HITTESTINFO;\nalias TVHITTESTINFO TV_HITTESTINFO;\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    struct TVGETITEMPARTRECTINFO {\n        HTREEITEM hti;\n        RECT*     prc;\n        TVITEMPART partID;\n    }\n}\n\nextern (Windows) alias int function(LPARAM, LPARAM, LPARAM) PFNTVCOMPARE;\nstruct TVSORTCB {\n    HTREEITEM    hParent;\n    PFNTVCOMPARE lpfnCompare;\n    LPARAM       lParam;\n}\nalias TVSORTCB* LPTVSORTCB, LPTV_SORTCB;\nalias TVSORTCB TV_SORTCB;\n\nstruct NMTREEVIEWA {\n    NMHDR    hdr;\n    UINT     action;\n    TV_ITEMA itemOld;\n    TV_ITEMA itemNew;\n    POINT    ptDrag;\n}\nalias NMTREEVIEWA* LPNMTREEVIEWA, LPNM_TREEVIEWA;\nalias NMTREEVIEWA NM_TREEVIEWA;\n\nstruct NMTREEVIEWW {\n    NMHDR    hdr;\n    UINT     action;\n    TV_ITEMW itemOld;\n    TV_ITEMW itemNew;\n    POINT    ptDrag;\n}\nalias NMTREEVIEWW* LPNMTREEVIEWW, LPNM_TREEVIEWW;\nalias NMTREEVIEWW NM_TREEVIEWW;\n\nstruct NMTVDISPINFOA {\n    NMHDR   hdr;\n    TVITEMA item;\n}\nalias NMTVDISPINFOA* LPNMTVDISPINFOA;\nalias NMTVDISPINFOA TV_DISPINFOA;\n\nstruct NMTVDISPINFOW {\n    NMHDR   hdr;\n    TVITEMW item;\n}\nalias NMTVDISPINFOW* LPNMTVDISPINFOW;\nalias NMTVDISPINFOW TV_DISPINFOW;\n\nstatic if (_WIN32_IE >= 0x400) {\n    struct NMTVGETINFOTIPA {\n        NMHDR     hdr;\n        LPSTR     pszText;\n        int       cchTextMax;\n        HTREEITEM hItem;\n        LPARAM    lParam;\n    }\n    alias NMTVGETINFOTIPA* LPNMTVGETINFOTIPA;\n\n    struct NMTVGETINFOTIPW {\n        NMHDR     hdr;\n        LPWSTR    pszText;\n        int       cchTextMax;\n        HTREEITEM hItem;\n        LPARAM    lParam;\n    }\n    alias NMTVGETINFOTIPW* LPNMTVGETINFOTIPW;\n}\n\nalign (1)\nstruct TV_KEYDOWN {\nalign (1):\n    NMHDR hdr;\n    WORD  wVKey;\n    UINT  flags;\n}\n\nstruct TC_ITEMHEADERA {\n    UINT  mask;\n    UINT  lpReserved1;\n    UINT  lpReserved2;\n    LPSTR pszText;\n    int   cchTextMax;\n    int   iImage;\n}\n\nstruct TC_ITEMHEADERW {\n    UINT   mask;\n    UINT   lpReserved1;\n    UINT   lpReserved2;\n    LPWSTR pszText;\n    int    cchTextMax;\n    int    iImage;\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    struct TCITEMA {\n        UINT   mask;\n        DWORD  dwState;\n        DWORD  dwStateMask;\n        LPSTR  pszText;\n        int    cchTextMax;\n        int    iImage;\n        LPARAM lParam;\n    }\n\n    struct TCITEMW {\n        UINT   mask;\n        DWORD  dwState;\n        DWORD  dwStateMask;\n        LPWSTR pszText;\n        int    cchTextMax;\n        int    iImage;\n        LPARAM lParam;\n    }\n} else {\n    struct TCITEMA {\n        UINT   mask;\n        UINT   lpReserved1;\n        UINT   lpReserved2;\n        LPSTR  pszText;\n        int    cchTextMax;\n        int    iImage;\n        LPARAM lParam;\n    }\n\n    struct TCITEMW {\n        UINT   mask;\n        UINT   lpReserved1;\n        UINT   lpReserved2;\n        LPWSTR pszText;\n        int    cchTextMax;\n        int    iImage;\n        LPARAM lParam;\n    }\n}\nalias TCITEMA* LPTCITEMA;\nalias TCITEMA TC_ITEMA;\nalias TCITEMW* LPTCITEMW;\nalias TCITEMW TC_ITEMW;\n\nstruct TCHITTESTINFO {\n    POINT pt;\n    UINT  flags;\n}\nalias TCHITTESTINFO* LPTCHITTESTINFO, LPTC_HITTESTINFO;\nalias TCHITTESTINFO TC_HITTESTINFO;\n\nalign (1)\nstruct TC_KEYDOWN {\nalign (1):\n    NMHDR hdr;\n    WORD wVKey;\n    UINT flags;\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    struct INITCOMMONCONTROLSEX {\n        DWORD dwSize = INITCOMMONCONTROLSEX.sizeof;\n        DWORD dwICC;\n    }\n    alias INITCOMMONCONTROLSEX* LPINITCOMMONCONTROLSEX;\n}\n\nstruct PBRANGE {\n    int iLow;\n    int iHigh;\n}\nalias PBRANGE* PPBRANGE;\n\nstruct COLORSCHEME {\n    DWORD    dwSize = COLORSCHEME.sizeof;\n    COLORREF clrBtnHighlight;\n    COLORREF clrBtnShadow;\n}\nalias COLORSCHEME* LPCOLORSCHEME;\n\nstruct MCHITTESTINFO {\n    UINT       cbSize = MCHITTESTINFO.sizeof;\n    POINT      pt;\n    UINT       uHit;\n    SYSTEMTIME st;\n}\nalias MCHITTESTINFO* PMCHITTESTINFO;\n\nalias DWORD MONTHDAYSTATE;\nalias MONTHDAYSTATE* LPMONTHDAYSTATE;\n\nstruct NMDAYSTATE {\n    NMHDR           nmhdr;\n    SYSTEMTIME      stStart;\n    int             cDayState;\n    LPMONTHDAYSTATE prgDayState;\n}\nalias NMDAYSTATE* LPNMDAYSTATE;\n\nstruct REBARINFO {\n    UINT       cbSize = REBARINFO.sizeof;\n    UINT       fMask;\n    HIMAGELIST himl;\n}\nalias REBARINFO* LPREBARINFO;\n\nstatic if (_WIN32_IE >= 0x400) {\n    struct REBARBANDINFOA {\n        UINT     cbSize = REBARBANDINFOA.sizeof;\n        UINT     fMask;\n        UINT     fStyle;\n        COLORREF clrFore;\n        COLORREF clrBack;\n        LPSTR    lpText;\n        UINT     cch;\n        int      iImage;\n        HWND     hwndChild;\n        UINT     cxMinChild;\n        UINT     cyMinChild;\n        UINT     cx;\n        HBITMAP  hbmBack;\n        UINT     wID;\n        UINT     cyChild;\n        UINT     cyMaxChild;\n        UINT     cyIntegral;\n        UINT     cxIdeal;\n        LPARAM   lParam;\n        UINT     cxHeader;\n    }\n\n    struct REBARBANDINFOW {\n        UINT     cbSize = REBARBANDINFOW.sizeof;\n        UINT     fMask;\n        UINT     fStyle;\n        COLORREF clrFore;\n        COLORREF clrBack;\n        LPWSTR   lpText;\n        UINT     cch;\n        int      iImage;\n        HWND     hwndChild;\n        UINT     cxMinChild;\n        UINT     cyMinChild;\n        UINT     cx;\n        HBITMAP  hbmBack;\n        UINT     wID;\n        UINT     cyChild;\n        UINT     cyMaxChild;\n        UINT     cyIntegral;\n        UINT     cxIdeal;\n        LPARAM   lParam;\n        UINT     cxHeader;\n    }\n\n    enum : size_t {\n        REBARBANDINFOA_V3_SIZE = REBARBANDINFOA.cyChild.offsetof,\n        REBARBANDINFOW_V3_SIZE = REBARBANDINFOW.cyChild.offsetof\n    }\n} else {\n    struct REBARBANDINFOA {\n        UINT     cbSize = REBARBANDINFOA.sizeof;\n        UINT     fMask;\n        UINT     fStyle;\n        COLORREF clrFore;\n        COLORREF clrBack;\n        LPSTR    lpText;\n        UINT     cch;\n        int      iImage;\n        HWND     hwndChild;\n        UINT     cxMinChild;\n        UINT     cyMinChild;\n        UINT     cx;\n        HBITMAP  hbmBack;\n        UINT     wID;\n    }\n\n    struct REBARBANDINFOW {\n        UINT     cbSize = REBARBANDINFOW.sizeof;\n        UINT     fMask;\n        UINT     fStyle;\n        COLORREF clrFore;\n        COLORREF clrBack;\n        LPWSTR   lpText;\n        UINT     cch;\n        int      iImage;\n        HWND     hwndChild;\n        UINT     cxMinChild;\n        UINT     cyMinChild;\n        UINT     cx;\n        HBITMAP  hbmBack;\n        UINT     wID;\n    }\n\n    enum : size_t {\n        REBARBANDINFOA_V3_SIZE = REBARBANDINFOA.sizeof,\n        REBARBANDINFOW_V3_SIZE = REBARBANDINFOW.sizeof\n    }\n}\nalias REBARBANDINFOA*        LPREBARBANDINFOA;\nalias const(REBARBANDINFOA)* LPCREBARBANDINFOA;\nalias REBARBANDINFOW*        LPREBARBANDINFOW;\nalias const(REBARBANDINFOW)* LPCREBARBANDINFOW;\n\nstatic if (_WIN32_IE >= 0x300) {\n    struct NMLVODSTATECHANGE {\n        NMHDR hdr;\n        int iFrom;\n        int iTo;\n        UINT uNewState;\n        UINT uOldState;\n    }\n    alias NMLVODSTATECHANGE* LPNMLVODSTATECHANGE;\n\n    static if (_WIN32_WINNT >= 0x501) {\n        struct IMAGELISTDRAWPARAMS {\n            DWORD      cbSize = IMAGELISTDRAWPARAMS.sizeof;\n            HIMAGELIST himl;\n            int        i;\n            HDC        hdcDst;\n            int        x;\n            int        y;\n            int        cx;\n            int        cy;\n            int        xBitmap;\n            int        yBitmap;\n            COLORREF   rgbBk;\n            COLORREF   rgbFg;\n            UINT       fStyle;\n            DWORD      dwRop;\n            DWORD      fState;\n            DWORD      Frame;\n            COLORREF   crEffect;\n        }\n    } else {\n        struct IMAGELISTDRAWPARAMS {\n            DWORD      cbSize = IMAGELISTDRAWPARAMS.sizeof;\n            HIMAGELIST himl;\n            int        i;\n            HDC        hdcDst;\n            int        x;\n            int        y;\n            int        cx;\n            int        cy;\n            int        xBitmap;\n            int        yBitmap;\n            COLORREF   rgbBk;\n            COLORREF   rgbFg;\n            UINT       fStyle;\n            DWORD      dwRop;\n        }\n    }\n    alias IMAGELISTDRAWPARAMS* LPIMAGELISTDRAWPARAMS;\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    struct NMREBARCHILDSIZE {\n        NMHDR hdr;\n        UINT  uBand;\n        UINT  wID;\n        RECT  rcChild;\n        RECT  rcBand;\n    }\n    alias NMREBARCHILDSIZE* LPNMREBARCHILDSIZE;\n\n    struct NMREBAR {\n        NMHDR  hdr;\n        DWORD  dwMask;\n        UINT   uBand;\n        UINT   fStyle;\n        UINT   wID;\n        LPARAM lParam;\n    }\n    alias NMREBAR* LPNMREBAR;\n\n    struct NMRBAUTOSIZE {\n        NMHDR hdr;\n        BOOL  fChanged;\n        RECT  rcTarget;\n        RECT  rcActual;\n    }\n    alias NMRBAUTOSIZE* LPNMRBAUTOSIZE;\n\n    static if (_WIN32_IE >= 0x500) {\n        struct NMREBARCHEVRON {\n            NMHDR  hdr;\n            UINT   uBand;\n            UINT   wID;\n            LPARAM lParam;\n            RECT   rc;\n            LPARAM lParamNM;\n        }\n        alias NMREBARCHEVRON* LPNMREBARCHEVRON;\n    }\n\n    struct RBHITTESTINFO {\n        POINT pt;\n        UINT  flags;\n        int   iBand;\n    }\n    alias RBHITTESTINFO* LPRBHITTESTINFO;\n}\n\nmixin DECLARE_HANDLE!(\"HDSA\");\nmixin DECLARE_HANDLE!(\"HDPA\");\n\nversion (Unicode) {\n    alias HDITEMW HDITEM;\n    alias LPHDITEMW LPHDITEM;\n    alias TOOLINFOW TOOLINFO;\n    alias TOOLINFOW* PTOOLINFO, LPTOOLINFO;\n    alias TTHITTESTINFOW TTHITTESTINFO;\n    alias TTHITTESTINFOW* LPHITTESTINFO, LPTTHITTESTINFO;\n    alias TOOLTIPTEXTW TOOLTIPTEXT;\n    alias TOOLTIPTEXTW* LPTOOLTIPTEXT;\n    alias NMTTDISPINFOW NMTTDISPINFO;\n    alias NMTTDISPINFOW* LPNMTTDISPINFO;\n    alias TV_ITEMW TV_ITEM;\n    alias TV_ITEMW* LPTV_ITEM;\n    alias TVITEMW TVITEM;\n    alias TVITEMW* LPTVITEM;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias TVITEMEXW TVITEMEX;\n        alias TVITEMEXW* LPTVITEMEX;\n    }\n\n    alias TV_INSERTSTRUCTW TV_INSERTSTRUCT;\n    alias TV_INSERTSTRUCTW* LPTV_INSERTSTRUCT;\n    alias TVINSERTSTRUCTW TVINSERTSTRUCT;\n    alias TVINSERTSTRUCTW* LPTVINSERTSTRUCT;\n    alias NM_TREEVIEWW NM_TREEVIEW;\n    alias NM_TREEVIEWW* LPNM_TREEVIEW;\n    alias NMTREEVIEWW NMTREEVIEW;\n    alias NMTREEVIEWW* LPNMTREEVIEW;\n    alias NMHDDISPINFOW NMHDDISPINFO;\n    alias NMHDDISPINFOW* LPNMHDDISPINFO;\n\n    alias ACM_OPENW ACM_OPEN;\n    alias COMBOBOXEXITEMW COMBOBOXEXITEM;\n    alias PCOMBOBOXEXITEMW PCOMBOBOXEXITEM;\n    //alias PCCOMBOBOXEXITEMW PCCOMBOBOXEXITEM; fixme\n    alias CBEM_INSERTITEMW CBEM_INSERTITEM;\n    alias CBEM_SETITEMW CBEM_SETITEM;\n    alias CBEM_GETITEMW CBEM_GETITEM;\n    alias CBEN_ENDEDITW CBEN_ENDEDIT;\n    alias NMCBEENDEDITW NMCBEENDEDIT;\n    alias LPNMCBEENDEDITW LPNMCBEENDEDIT;\n    alias PNMCBEENDEDITW PNMCBEENDEDIT;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias NMCOMBOBOXEXW NMCOMBOBOXEX;\n        alias PNMCOMBOBOXEXW PNMCOMBOBOXEX;\n        alias CBEN_GETDISPINFOW CBEN_GETDISPINFO;\n        alias CBEN_DRAGBEGINW CBEN_DRAGBEGIN;\n        alias NMCBEDRAGBEGINW NMCBEDRAGBEGIN;\n        alias LPNMCBEDRAGBEGINW LPNMCBEDRAGBEGIN;\n        alias PNMCBEDRAGBEGINW PNMCBEDRAGBEGIN;\n    }\n\n    alias SB_GETTEXTW SB_GETTEXT;\n    alias SB_SETTEXTW SB_SETTEXT;\n    alias SB_GETTEXTLENGTHW SB_GETTEXTLENGTH;\n    alias HDM_INSERTITEMW HDM_INSERTITEM;\n    alias HDM_GETITEMW HDM_GETITEM;\n    alias HDM_SETITEMW HDM_SETITEM;\n    alias HDN_ITEMCHANGINGW HDN_ITEMCHANGING;\n    alias HDN_ITEMCHANGEDW HDN_ITEMCHANGED;\n    alias HDN_ITEMCLICKW HDN_ITEMCLICK;\n    alias HDN_ITEMDBLCLICKW HDN_ITEMDBLCLICK;\n    alias HDN_DIVIDERDBLCLICKW HDN_DIVIDERDBLCLICK;\n    alias HDN_BEGINTRACKW HDN_BEGINTRACK;\n    alias HDN_ENDTRACKW HDN_ENDTRACK;\n    alias HDN_TRACKW HDN_TRACK;\n\n    static if (_WIN32_IE >= 0x300) {\n        alias HDN_GETDISPINFOW HDN_GETDISPINFO;\n    }\n\n    alias HD_NOTIFYW HD_NOTIFY;\n    alias TBSAVEPARAMSW TBSAVEPARAMS;\n    alias TB_GETBUTTONTEXTW TB_GETBUTTONTEXT;\n    alias TB_SAVERESTOREW TB_SAVERESTORE;\n    alias TB_ADDSTRINGW TB_ADDSTRING;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias TBN_GETBUTTONINFOW TBN_GETBUTTONINFO;  // fixme\n        alias TB_GETBUTTONINFOW TB_GETBUTTONINFO;\n        alias TB_SETBUTTONINFOW TB_SETBUTTONINFO;\n        alias TB_INSERTBUTTONW TB_INSERTBUTTON;\n        alias TB_ADDBUTTONSW TB_ADDBUTTONS;\n        alias TB_MAPACCELERATORW TB_MAPACCELERATOR;\n        alias TB_GETSTRINGW TB_GETSTRING;\n        alias TBBUTTONINFOW TBBUTTONINFO;\n        alias LPTBBUTTONINFOW LPTBBUTTONINFO;\n        alias TBN_GETDISPINFOW TBN_GETDISPINFO;\n        alias NMTBDISPINFOW NMTBDISPINFO;\n        alias LPNMTBDISPINFOW LPNMTBDISPINFO;\n        alias NMTBGETINFOTIPW NMTBGETINFOTIP;\n        alias LPNMTBGETINFOTIPW LPNMTBGETINFOTIP;\n    }\n\n    alias TBNOTIFYW TBNOTIFY;\n    alias LPTBNOTIFYW LPTBNOTIFY;\n    alias NMTOOLBARW NMTOOLBAR;\n    alias LPNMTOOLBARW LPNMTOOLBAR;\n    alias TTM_ADDTOOLW TTM_ADDTOOL;\n    alias TTM_DELTOOLW TTM_DELTOOL;\n    alias TTM_NEWTOOLRECTW TTM_NEWTOOLRECT;\n    alias TTM_GETTOOLINFOW TTM_GETTOOLINFO;\n    alias TTM_SETTOOLINFOW TTM_SETTOOLINFO;\n    alias TTM_HITTESTW TTM_HITTEST;\n    alias TTM_GETTEXTW TTM_GETTEXT;\n    alias TTM_UPDATETIPTEXTW TTM_UPDATETIPTEXT;\n    alias TTM_ENUMTOOLSW TTM_ENUMTOOLS;\n    alias TTM_GETCURRENTTOOLW TTM_GETCURRENTTOOL;\n    alias TTN_NEEDTEXTW TTN_NEEDTEXT;\n    alias TTN_GETDISPINFOW TTN_GETDISPINFO;\n    //alias SB_GETTEXTW SB_GETTEXT;\n    //alias SB_SETTEXTW SB_SETTEXT;\n    //alias SB_GETTEXTLENGTHW SB_GETTEXTLENGTH;\n    alias LV_ITEMW LV_ITEM;\n    alias LVITEMW LVITEM;\n    alias LVITEM* LPLVITEM;\n    alias LPSTR_TEXTCALLBACKW LPSTR_TEXTCALLBACK;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias LVBKIMAGEW LVBKIMAGE;\n        alias LPLVBKIMAGEW LPLVBKIMAGE;\n        alias LVM_SETBKIMAGEW LVM_SETBKIMAGE;\n        alias LVM_GETBKIMAGEW LVM_GETBKIMAGE;\n    }\n\n    alias LVM_GETITEMW LVM_GETITEM;\n    alias LVM_SETITEMW LVM_SETITEM;\n    alias LVM_INSERTITEMW LVM_INSERTITEM;\n    alias LV_FINDINFOW LV_FINDINFO;\n    alias LVFINDINFOW LVFINDINFO;\n    alias LPFINDINFOW LPFINDINFO;\n    alias NMLVFINDITEMW NMLVFINDITEM;\n    alias PNMLVFINDITEMW PNMLVFINDITEM;\n    alias LPNMLVFINDITEMW LPNMLVFINDITEM;\n    alias LVM_FINDITEMW LVM_FINDITEM;\n    alias LVM_GETSTRINGWIDTHW LVM_GETSTRINGWIDTH;\n    alias LVM_EDITLABELW LVM_EDITLABEL;\n    alias LV_COLUMNW LV_COLUMN;\n    alias LVCOLUMNW LVCOLUMN;\n    alias LVCOLUMNW* LPLVCOLUMN;\n    alias LVM_GETCOLUMNW LVM_GETCOLUMN;\n    alias LVM_SETCOLUMNW LVM_SETCOLUMN;\n    alias LVM_INSERTCOLUMNW LVM_INSERTCOLUMN;\n    alias LVM_GETITEMTEXTW LVM_GETITEMTEXT;\n    alias LVM_SETITEMTEXTW LVM_SETITEMTEXT;\n    alias LVM_GETISEARCHSTRINGW LVM_GETISEARCHSTRING;\n    alias LVN_BEGINLABELEDITW LVN_BEGINLABELEDIT;\n    alias LVN_ENDLABELEDITW LVN_ENDLABELEDIT;\n    alias LVN_GETDISPINFOW LVN_GETDISPINFO;\n    alias LVN_SETDISPINFOW LVN_SETDISPINFO;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias LVN_GETINFOTIPW LVN_GETINFOTIP;\n        alias NMLVGETINFOTIPW NMLVGETINFOTIP;\n        alias LPNMLVGETINFOTIPW LPNMLVGETINFOTIP;\n    }\n\n    alias LV_DISPINFOW LV_DISPINFO;\n    alias NMLVDISPINFOW NMLVDISPINFO;\n    alias LPNMLVDISPINFOW LPNMLVDISPINFO;\n    alias TVM_INSERTITEMW TVM_INSERTITEM;\n    alias TVM_GETITEMW TVM_GETITEM;\n    alias TVM_SETITEMW TVM_SETITEM;\n    alias TVM_EDITLABELW TVM_EDITLABEL;\n    alias TVM_GETISEARCHSTRINGW TVM_GETISEARCHSTRING;\n    alias NMTVDISPINFOW TV_DISPINFO;\n    alias NMTVDISPINFOW NMTVDISPINFO;\n    alias LPNMTVDISPINFOW LPNMTVDISPINFO;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias NMTVGETINFOTIPW NMTVGETINFOTIP;\n        alias LPNMTVGETINFOTIPW LPNMTVGETINFOTIP;\n        alias TVN_GETINFOTIPW TVN_GETINFOTIP;\n    }\n\n    alias TVN_SELCHANGINGW TVN_SELCHANGING;\n    alias TVN_SELCHANGEDW TVN_SELCHANGED;\n    alias TVN_GETDISPINFOW TVN_GETDISPINFO;\n    alias TVN_SETDISPINFOW TVN_SETDISPINFO;\n    alias TVN_ITEMEXPANDINGW TVN_ITEMEXPANDING;\n    alias TVN_ITEMEXPANDEDW TVN_ITEMEXPANDED;\n    alias TVN_BEGINDRAGW TVN_BEGINDRAG;\n    alias TVN_BEGINRDRAGW TVN_BEGINRDRAG;\n    alias TVN_DELETEITEMW TVN_DELETEITEM;\n    alias TVN_BEGINLABELEDITW TVN_BEGINLABELEDIT;\n    alias TVN_ENDLABELEDITW TVN_ENDLABELEDIT;\n    alias TC_ITEMHEADERW TC_ITEMHEADER;\n    alias TC_ITEMW TC_ITEM;\n    alias TCITEMW TCITEM;\n    alias LPTCITEMW LPTCITEM;\n    alias TCM_GETITEMW TCM_GETITEM;\n    alias TCM_SETITEMW TCM_SETITEM;\n    alias TCM_INSERTITEMW TCM_INSERTITEM;\n    alias CreateStatusWindowW CreateStatusWindow;\n    alias DrawStatusTextW DrawStatusText;\n    alias ImageList_LoadImageW ImageList_LoadImage;\n    alias DTM_SETFORMATW DTM_SETFORMAT;\n    alias DTN_USERSTRINGW DTN_USERSTRING;\n    alias DTN_WMKEYDOWNW DTN_WMKEYDOWN;\n    alias DTN_FORMATW DTN_FORMAT;\n    alias DTN_FORMATQUERYW DTN_FORMATQUERY;\n    alias REBARBANDINFOW REBARBANDINFO;\n    alias REBARBANDINFO* LPREBARBANDINFO;\n    alias LPCREBARBANDINFOW LPCREBARBANDINFO;\n    alias REBARBANDINFOW_V3_SIZE REBARBANDINFO_V3_SIZE;\n    alias RB_INSERTBANDW RB_INSERTBAND;\n    alias RB_SETBANDINFOW RB_SETBANDINFO;\n} else {\n    alias HDITEMA HDITEM;\n    alias LPHDITEMA LPHDITEM;\n    alias TOOLINFOA TOOLINFO;\n    alias TOOLINFOA* PTOOLINFO, LPTOOLINFO;\n    alias TTHITTESTINFOA TTHITTESTINFO;\n    alias TTHITTESTINFOA* LPHITTESTINFO, LPTTHITTESTINFO;\n    alias TOOLTIPTEXTA TOOLTIPTEXT;\n    alias TOOLTIPTEXTA* LPTOOLTIPTEXT;\n    alias NMTTDISPINFOA NMTTDISPINFO;\n    alias NMTTDISPINFOA* LPNMTTDISPINFO;\n    alias TV_ITEMA TV_ITEM;\n    alias TV_ITEMA* LPTV_ITEM;\n    alias TVITEMA TVITEM;\n    alias TVITEMA* LPTVITEM;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias TVITEMEXA TVITEMEX;\n        alias TVITEMEXA* LPTVITEMEX;\n    }\n\n    alias TV_INSERTSTRUCTA TV_INSERTSTRUCT;\n    alias TV_INSERTSTRUCTA* LPTV_INSERTSTRUCT;\n    alias TVINSERTSTRUCTA TVINSERTSTRUCT;\n    alias TVINSERTSTRUCTA* LPTVINSERTSTRUCT;\n    alias NM_TREEVIEWA NM_TREEVIEW;\n    alias NM_TREEVIEWA* LPNM_TREEVIEW;\n    alias NMTREEVIEWA NMTREEVIEW;\n    alias NMTREEVIEWA* LPNMTREEVIEW;\n    alias NMHDDISPINFOW NMHDDISPINFO;\n    alias NMHDDISPINFOW* LPNMHDDISPINFO;\n\n    alias ACM_OPENA ACM_OPEN;\n    alias COMBOBOXEXITEMA COMBOBOXEXITEM;\n    alias PCOMBOBOXEXITEMA PCOMBOBOXEXITEM;\n    //alias PCCOMBOBOXEXITEMA PCCOMBOBOXEXITEM; fixme\n    alias CBEM_INSERTITEMA CBEM_INSERTITEM;\n    alias CBEM_SETITEMA CBEM_SETITEM;\n    alias CBEM_GETITEMA CBEM_GETITEM;\n    alias CBEN_ENDEDITA CBEN_ENDEDIT;\n    alias NMCBEENDEDITA NMCBEENDEDIT;\n    alias LPNMCBEENDEDITA LPNMCBEENDEDIT;\n    alias PNMCBEENDEDITA PNMCBEENDEDIT;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias TB_GETBUTTONINFOA TB_GETBUTTONINFO;\n        alias TB_SETBUTTONINFOA TB_SETBUTTONINFO;\n        alias TB_INSERTBUTTONA TB_INSERTBUTTON;\n        alias TB_ADDBUTTONSA TB_ADDBUTTONS;\n        alias TB_MAPACCELERATORA TB_MAPACCELERATOR;\n        alias TB_GETSTRINGA TB_GETSTRING;\n        alias NMCOMBOBOXEXA NMCOMBOBOXEX;\n        alias PNMCOMBOBOXEXA PNMCOMBOBOXEX;\n        alias CBEN_DRAGBEGINA CBEN_DRAGBEGIN;\n        alias CBEN_GETDISPINFOA CBEN_GETDISPINFO;\n        alias NMCBEDRAGBEGINA NMCBEDRAGBEGIN;\n        alias LPNMCBEDRAGBEGINA LPNMCBEDRAGBEGIN;\n        alias PNMCBEDRAGBEGINA PNMCBEDRAGBEGIN;\n        alias TBN_GETDISPINFOA TBN_GETDISPINFO;\n        alias NMTBDISPINFOA NMTBDISPINFO;\n        alias LPNMTBDISPINFOA LPNMTBDISPINFO;\n        alias NMTBGETINFOTIPA NMTBGETINFOTIP;\n        alias LPNMTBGETINFOTIPA LPNMTBGETINFOTIP;\n    }\n\n    alias SB_GETTEXTA SB_GETTEXT;\n    alias SB_SETTEXTA SB_SETTEXT;\n    alias SB_GETTEXTLENGTHA SB_GETTEXTLENGTH;\n    alias HDM_INSERTITEMA HDM_INSERTITEM;\n    alias HDM_GETITEMA HDM_GETITEM;\n    alias HDM_SETITEMA HDM_SETITEM;\n    alias HDN_ITEMCHANGINGA HDN_ITEMCHANGING;\n    alias HDN_ITEMCHANGEDA HDN_ITEMCHANGED;\n    alias HDN_ITEMCLICKA HDN_ITEMCLICK;\n    alias HDN_ITEMDBLCLICKA HDN_ITEMDBLCLICK;\n    alias HDN_DIVIDERDBLCLICKA HDN_DIVIDERDBLCLICK;\n    alias HDN_BEGINTRACKA HDN_BEGINTRACK;\n    alias HDN_ENDTRACKA HDN_ENDTRACK;\n    alias HDN_TRACKA HDN_TRACK;\n\n    static if (_WIN32_IE >= 0x300) {\n        alias HDN_GETDISPINFOA HDN_GETDISPINFO;\n    }\n\n    alias HD_NOTIFYA HD_NOTIFY;\n    alias TBSAVEPARAMSA TBSAVEPARAMS;\n    alias TB_GETBUTTONTEXTA TB_GETBUTTONTEXT;\n    alias TB_SAVERESTOREA TB_SAVERESTORE;\n    alias TB_ADDSTRINGA TB_ADDSTRING;\n    alias TBN_GETBUTTONINFOA TBN_GETBUTTONINFO;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias TBBUTTONINFOA TBBUTTONINFO;\n        alias LPTBBUTTONINFOA LPTBBUTTONINFO;\n    }\n\n    alias TBNOTIFYA TBNOTIFY;\n    alias LPTBNOTIFYA LPTBNOTIFY;\n    alias NMTOOLBARA NMTOOLBAR;\n    alias LPNMTOOLBARA LPNMTOOLBAR;\n    alias TTM_ADDTOOLA TTM_ADDTOOL;\n    alias TTM_DELTOOLA TTM_DELTOOL;\n    alias TTM_NEWTOOLRECTA TTM_NEWTOOLRECT;\n    alias TTM_GETTOOLINFOA TTM_GETTOOLINFO;\n    alias TTM_SETTOOLINFOA TTM_SETTOOLINFO;\n    alias TTM_HITTESTA TTM_HITTEST;\n    alias TTM_GETTEXTA TTM_GETTEXT;\n    alias TTM_UPDATETIPTEXTA TTM_UPDATETIPTEXT;\n    alias TTM_ENUMTOOLSA TTM_ENUMTOOLS;\n    alias TTM_GETCURRENTTOOLA TTM_GETCURRENTTOOL;\n    alias TTN_NEEDTEXTA TTN_NEEDTEXT;\n    alias TTN_GETDISPINFOA TTN_GETDISPINFO;\n    alias LV_ITEMA LV_ITEM;\n    alias LVITEMA LVITEM;\n    alias LVITEM* LPLVITEM;\n    alias LPSTR_TEXTCALLBACKA LPSTR_TEXTCALLBACK;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias LVBKIMAGEA LVBKIMAGE;\n        alias LPLVBKIMAGEA LPLVBKIMAGE;\n        alias LVM_SETBKIMAGEA LVM_SETBKIMAGE;\n        alias LVM_GETBKIMAGEA LVM_GETBKIMAGE;\n    }\n\n    alias LVM_GETITEMA LVM_GETITEM;\n    alias LVM_SETITEMA LVM_SETITEM;\n    alias LVM_INSERTITEMA LVM_INSERTITEM;\n    alias LV_FINDINFOA LV_FINDINFO;\n    alias LVFINDINFOA LVFINDINFO;\n    alias LPFINDINFOA LPFINDINFO;\n    alias NMLVFINDITEMA NMLVFINDITEM;\n    alias PNMLVFINDITEMA PNMLVFINDITEM;\n    alias LPNMLVFINDITEMA LPNMLVFINDITEM;\n    alias LVM_FINDITEMA LVM_FINDITEM;\n    alias LVM_GETSTRINGWIDTHA LVM_GETSTRINGWIDTH;\n    alias LVM_EDITLABELA LVM_EDITLABEL;\n    alias LV_COLUMNA LV_COLUMN;\n    alias LVCOLUMNA LVCOLUMN;\n    alias LVCOLUMNA* LPLVCOLUMN;\n    alias LVM_GETCOLUMNA LVM_GETCOLUMN;\n    alias LVM_SETCOLUMNA LVM_SETCOLUMN;\n    alias LVM_INSERTCOLUMNA LVM_INSERTCOLUMN;\n    alias LVM_GETITEMTEXTA LVM_GETITEMTEXT;\n    alias LVM_SETITEMTEXTA LVM_SETITEMTEXT;\n    alias LVM_GETISEARCHSTRINGA LVM_GETISEARCHSTRING;\n    alias LVN_BEGINLABELEDITA LVN_BEGINLABELEDIT;\n    alias LVN_ENDLABELEDITA LVN_ENDLABELEDIT;\n    alias LVN_GETDISPINFOA LVN_GETDISPINFO;\n    alias LVN_SETDISPINFOA LVN_SETDISPINFO;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias LVN_GETINFOTIPA LVN_GETINFOTIP;\n        alias NMLVGETINFOTIPA NMLVGETINFOTIP;\n        alias LPNMLVGETINFOTIPA LPNMLVGETINFOTIP;\n    }\n\n    alias LV_DISPINFOA LV_DISPINFO;\n    alias NMLVDISPINFOA NMLVDISPINFO;\n    alias LPNMLVDISPINFOA LPNMLVDISPINFO;\n    alias TVM_INSERTITEMA TVM_INSERTITEM;\n    alias TVM_GETITEMA TVM_GETITEM;\n    alias TVM_SETITEMA TVM_SETITEM;\n    alias TVM_EDITLABELA TVM_EDITLABEL;\n    alias TVM_GETISEARCHSTRINGA TVM_GETISEARCHSTRING;\n    alias NMTVDISPINFOA TV_DISPINFO;\n    alias NMTVDISPINFOA NMTVDISPINFO;\n    alias LPNMTVDISPINFOA LPNMTVDISPINFO;\n\n    static if (_WIN32_IE >= 0x400) {\n        alias NMTVGETINFOTIPA NMTVGETINFOTIP;\n        alias LPNMTVGETINFOTIPA LPNMTVGETINFOTIP;\n        alias TVN_GETINFOTIPA TVN_GETINFOTIP;\n    }\n\n    alias TVN_SELCHANGINGA TVN_SELCHANGING;\n    alias TVN_SELCHANGEDA TVN_SELCHANGED;\n    alias TVN_GETDISPINFOA TVN_GETDISPINFO;\n    alias TVN_SETDISPINFOA TVN_SETDISPINFO;\n    alias TVN_ITEMEXPANDINGA TVN_ITEMEXPANDING;\n    alias TVN_ITEMEXPANDEDA TVN_ITEMEXPANDED;\n    alias TVN_BEGINDRAGA TVN_BEGINDRAG;\n    alias TVN_BEGINRDRAGA TVN_BEGINRDRAG;\n    alias TVN_DELETEITEMA TVN_DELETEITEM;\n    alias TVN_BEGINLABELEDITA TVN_BEGINLABELEDIT;\n    alias TVN_ENDLABELEDITA TVN_ENDLABELEDIT;\n    alias TC_ITEMHEADERA TC_ITEMHEADER;\n    alias TC_ITEMA TC_ITEM;\n    alias TCITEMA TCITEM;\n    alias LPTCITEMA LPTCITEM;\n    alias TCM_GETITEMA TCM_GETITEM;\n    alias TCM_SETITEMA TCM_SETITEM;\n    alias TCM_INSERTITEMA TCM_INSERTITEM;\n    alias CreateStatusWindowA CreateStatusWindow;\n    alias DrawStatusTextA DrawStatusText;\n    alias ImageList_LoadImageA ImageList_LoadImage;\n    alias DTM_SETFORMATA DTM_SETFORMAT;\n    alias DTN_USERSTRINGA DTN_USERSTRING;\n    alias DTN_WMKEYDOWNA DTN_WMKEYDOWN;\n    alias DTN_FORMATA DTN_FORMAT;\n    alias DTN_FORMATQUERYA DTN_FORMATQUERY;\n    alias REBARBANDINFOA REBARBANDINFO;\n    alias REBARBANDINFOA* LPREBARBANDINFO;\n    alias LPCREBARBANDINFOA LPCREBARBANDINFO;\n    alias REBARBANDINFOA_V3_SIZE REBARBANDINFO_V3_SIZE;\n    alias RB_INSERTBANDA RB_INSERTBAND;\n    alias RB_SETBANDINFOA RB_SETBANDINFO;\n}\n\n\nextern (Windows) {\nalias INT function(PVOID, PVOID) PFNDPAENUMCALLBACK;\nalias INT function(PVOID, PVOID) PFNDSAENUMCALLBACK;\nalias INT function(PVOID, PVOID, LPARAM) PFNDPACOMPARE;\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    extern (Windows)\n    alias LRESULT function(HWND, UINT, WPARAM, LPARAM, UINT_PTR, DWORD_PTR)\n      SUBCLASSPROC;\n\n    struct LITEM {\n        UINT mask;\n        int  iLink;\n        UINT state;\n        UINT stateMask;\n        WCHAR[MAX_LINKID_TEXT]  szID;\n        WCHAR[L_MAX_URL_LENGTH] szUrl;\n    }\n    alias LITEM* PLITEM;\n\n    struct LHITTESTINFO {\n        POINT pt;\n        LITEM item;\n    }\n    alias LHITTESTINFO* PLHITTESTINFO;\n\n    struct NMLINK {\n        NMHDR hdr;\n        LITEM item;\n    }\n    alias NMLINK* PNMLINK;\n}\n\nuint INDEXTOOVERLAYMASK(uint i) { return i << 8; }\nuint INDEXTOSTATEIMAGEMASK(uint i) { return i << 12; }\n\ntemplate HANDLE_WM_NOTIFY(R) {\n    private alias _prm_HANDLE_WM_NOTIFY = extern (Windows)\n        R function(HWND, int, NMHDR*); // to inject linkage type\n    R HANDLE_WM_NOTIFY(HWND hwnd, WPARAM wParam, LPARAM lParam, _prm_HANDLE_WM_NOTIFY fn) {\n        return fn(hwnd, wParam, cast(NMHDR*) lParam);\n    }\n}\nprivate alias _prm_FORWARD_WM_NOTIFY = extern (Windows)\n    LRESULT function(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); // to inject linkage type\nLRESULT FORWARD_WM_NOTIFY(HWND hwnd, int idFrom, NMHDR* pnmhdr, _prm_FORWARD_WM_NOTIFY fn) {\n    return fn(hwnd, WM_NOTIFY, idFrom, cast(LPARAM) pnmhdr);\n}\n\n//#define CCSIZEOF_STRUCT(s, m) (((int)((PBYTE)(&((s*)0)->m)-((PBYTE)((s*)0))))+sizeof(((s*)0)->m))\n\nLPARAM MAKEIPADDRESS(ubyte b1, ubyte b2, ubyte b3, ubyte b4) {\n    return (cast(DWORD) b1 << 24)\n         | (cast(DWORD) b2 << 16)\n         | (cast(DWORD) b3 << 8)\n         | (cast(DWORD) b4);\n}\n\nLPARAM MAKEIPRANGE(ubyte low, ubyte high) {\n    return (cast(int) high << 8) | low;\n}\n\nubyte FIRST_IPADDRESS(LPARAM x) {\n    return cast(ubyte) (x >> 24);\n}\n\nubyte SECOND_IPADDRESS(LPARAM x) {\n    return cast(ubyte) (x >> 16);\n}\n\nubyte THIRD_IPADDRESS(LPARAM x) {\n    return cast(ubyte) (x >> 8);\n}\n\nubyte FOURTH_IPADDRESS(LPARAM x) {\n    return cast(ubyte) x;\n}\n\nHWND Animate_Create(HWND hwndP, UINT id, DWORD dwStyle,\n      HINSTANCE hInstance) {\n    return CreateWindow(cast(TCHAR*)ANIMATE_CLASS.ptr, null, dwStyle, 0, 0, 0, 0, hwndP,\n      cast(HMENU) id, hInstance, null);\n}\n\nBOOL Animate_Open(HWND hwnd, LPTSTR szName) {\n    return cast(BOOL) SendMessage(hwnd, ACM_OPEN, 0, cast(LPARAM) szName);\n}\n\nBOOL Animate_OpenEx(HWND hwnd, HINSTANCE hInst, LPTSTR szName) {\n    return cast(BOOL) SendMessage(hwnd, ACM_OPEN, cast(WPARAM) hInst,\n      cast(LPARAM) szName);\n}\n\nBOOL Animate_Play(HWND hwnd, int from, int to, int rep) {\n    return cast(BOOL) SendMessage(hwnd, ACM_PLAY, rep,\n      MAKELONG(cast(ushort) from, cast(ushort) to));\n}\n\nBOOL Animate_Stop(HWND hwnd) {\n    return cast(BOOL) SendMessage(hwnd, ACM_STOP, 0, 0);\n}\n\nBOOL Animate_Close(HWND hwnd) {\n    return Animate_Open(hwnd, null);\n}\n\nBOOL Animate_Seek(HWND hwnd, int frame) {\n    return Animate_Play(hwnd, frame, frame, 1);\n}\n\nextern (Windows) {\n    HBITMAP CreateMappedBitmap(HINSTANCE, INT_PTR, UINT, LPCOLORMAP, int);\n    HWND CreateStatusWindowA(LONG, LPCSTR, HWND, UINT);\n    HWND CreateStatusWindowW(LONG, LPCWSTR, HWND, UINT);\n    HWND CreateToolbarEx(HWND, DWORD, UINT, int, HINSTANCE, UINT_PTR,\n      LPCTBBUTTON, int, int, int, int, int, UINT);\n    HWND CreateUpDownControl(DWORD, int, int, int, int, HWND, int, HINSTANCE,\n      HWND, int, int, int);\n}\n\nHWND DateTime_GetMonthCal(HWND hwnd) {\n    return cast(HWND) SendMessage(hwnd, DTM_GETMONTHCAL, 0, 0);\n}\n\nCOLORREF DateTime_GetMonthCalColor(HWND hwnd, int iColor) {\n    return cast(COLORREF) SendMessage(hwnd, DTM_GETMCCOLOR, iColor, 0);\n}\n\nHFONT DateTime_GetMonthCalFont(HWND hwnd) {\n    return cast(HFONT) SendMessage(hwnd, DTM_GETMCFONT, 0, 0);\n}\n\nDWORD DateTime_GetRange(HWND hwnd, LPSYSTEMTIME lpSysTimeArray) {\n    return cast(DWORD) SendMessage(hwnd, DTM_GETRANGE, 0, cast(LPARAM) lpSysTimeArray);\n}\n\nDWORD DateTime_GetSystemtime(HWND hwnd, LPSYSTEMTIME lpSysTime) {\n    return cast(DWORD) SendMessage(hwnd, DTM_GETSYSTEMTIME, 0, cast(LPARAM) lpSysTime);\n}\n\nBOOL DateTime_SetFormat(HWND hwnd, LPCTSTR lpszFormat) {\n    return cast(BOOL) SendMessage(hwnd, DTM_SETFORMAT, 0,\n      cast(LPARAM) lpszFormat);\n}\n\nLRESULT DateTime_SetMonthCalColor(HWND hwnd, int iColor, COLORREF clr) {\n    return SendMessage(hwnd, DTM_SETMCCOLOR, cast(WPARAM) iColor,\n      cast(LPARAM) clr);\n}\n\nvoid DateTime_SetMonthCalFont(HWND hwnd, HFONT hfont, BOOL fRedraw) {\n    SendMessage(hwnd, DTM_SETMCFONT, cast(WPARAM) hfont, fRedraw);\n}\n\nBOOL DateTime_SetRange(HWND hwnd, WPARAM flags, LPSYSTEMTIME lpSysTimeArray) {\n    return cast(BOOL) SendMessage(hwnd, DTM_SETRANGE, flags,\n      cast(LPARAM) lpSysTimeArray);\n}\n\nBOOL DateTime_SetSystemtime(HWND hwnd, WPARAM flag, LPSYSTEMTIME lpSysTime) {\n    return cast(BOOL) SendMessage(hwnd, DTM_SETSYSTEMTIME, flag,\n      cast(LPARAM) lpSysTime);\n}\n\nextern (Windows) {\n    void DrawInsert(HWND, HWND, int);\n    void DrawStatusTextA(HDC, LPRECT, LPCSTR, UINT);\n    void DrawStatusTextW(HDC, LPRECT, LPCWSTR, UINT);\n    void GetEffectiveClientRect(HWND, LPRECT, LPINT);\n}\n\nint Header_GetItemCount(HWND w) {\n    return cast(int) SendMessage(w, HDM_GETITEMCOUNT, 0, 0);\n}\n\nint Header_InsertItem(HWND w, int i, const(HDITEM)* phdi) {\n    return cast(int) SendMessage(w, HDM_INSERTITEM, i, cast(LPARAM) phdi);\n}\n\nBOOL Header_DeleteItem(HWND w, int i) {\n    return cast(BOOL) SendMessage(w, HDM_DELETEITEM, i, 0);\n}\n\nBOOL Header_GetItem(HWND w, int i, LPHDITEM phdi) {\n    return cast(BOOL) SendMessage(w, HDM_GETITEM, i, cast(LPARAM) phdi);\n}\n\nBOOL Header_SetItem(HWND w, int i, const(HDITEM)* phdi) {\n    return cast(BOOL) SendMessage(w, HDM_SETITEM, i, cast(LPARAM) phdi);\n}\n\nBOOL Header_Layout(HWND w, LPHDLAYOUT playout) {\n    return cast(BOOL) SendMessage(w, HDM_LAYOUT, 0, cast(LPARAM) playout);\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    int Header_OrderToIndex(HWND w, int i) {\n        return cast(int) SendMessage(w, HDM_ORDERTOINDEX, i, 0);\n    }\n\n    BOOL Header_GetItemRect(HWND w, int i, RECT* r) {\n        return cast(BOOL) SendMessage(w, HDM_GETITEMRECT, i, cast(LPARAM) r);\n    }\n\n    BOOL Header_GetOrderArray(HWND w, int iSize, LPINT lpiArray) {\n        return cast(BOOL) SendMessage(w, HDM_GETORDERARRAY, iSize,\n          cast(LPARAM) lpiArray);\n    }\n\n    BOOL Header_SetOrderArray(HWND w, int iSize, LPINT lpiArray) {\n        return cast(BOOL) SendMessage(w, HDM_SETORDERARRAY, iSize,\n          cast(LPARAM) lpiArray);\n    }\n\n    HIMAGELIST Header_CreateDragImage(HWND w, int i) {\n        return cast(HIMAGELIST) SendMessage(w, HDM_CREATEDRAGIMAGE, i, 0);\n    }\n\n    HIMAGELIST Header_SetImageList(HWND w, HIMAGELIST himl) {\n        return cast(HIMAGELIST) SendMessage(w, HDM_SETIMAGELIST, 0,\n          cast(LPARAM) himl);\n    }\n\n    HIMAGELIST Header_GetImageList(HWND w) {\n        return cast(HIMAGELIST) SendMessage(w, HDM_GETIMAGELIST, 0, 0);\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    BOOL Header_GetUnicodeFormat(HWND w) {\n        return cast(BOOL) SendMessage(w, HDM_GETUNICODEFORMAT, 0, 0);\n    }\n\n    BOOL Header_SetUnicodeFormat(HWND w, BOOL fUnicode) {\n        return cast(BOOL) SendMessage(w, HDM_SETUNICODEFORMAT, fUnicode, 0);\n    }\n}\n\nextern (Windows) {\n    HDSA DSA_Create(INT, INT);\n    BOOL DSA_Destroy(HDSA);\n    VOID DSA_DestroyCallback(HDSA, PFNDSAENUMCALLBACK, PVOID);\n    PVOID DSA_GetItemPtr(HDSA, INT);\n    INT DSA_InsertItem(HDSA, INT, PVOID);\n    HDPA DPA_Create(INT);\n    BOOL DPA_Destroy(HDPA);\n    PVOID DPA_DeletePtr(HDPA, INT);\n    BOOL DPA_DeleteAllPtrs(HDPA);\n    VOID DPA_EnumCallback(HDPA, PFNDPAENUMCALLBACK, PVOID);\n    VOID DPA_DestroyCallback(HDPA, PFNDPAENUMCALLBACK, PVOID);\n    BOOL DPA_SetPtr(HDPA, INT, PVOID);\n    INT DPA_InsertPtr(HDPA, INT, PVOID);\n    PVOID DPA_GetPtr(HDPA, INT_PTR);\n    BOOL DPA_Sort(HDPA, PFNDPACOMPARE, LPARAM);\n    INT DPA_Search(HDPA, PVOID, INT, PFNDPACOMPARE, LPARAM, UINT);\n    BOOL Str_SetPtrW(LPWSTR*, LPCWSTR);\n\n    static if (_WIN32_IE >= 0x400) {\n        BOOL FlatSB_EnableScrollBar(HWND, INT, UINT);\n        BOOL FlatSB_ShowScrollBar(HWND, INT, BOOL);\n        BOOL FlatSB_GetScrollRange(HWND, INT, LPINT, LPINT);\n        BOOL FlatSB_GetScrollInfo(HWND, INT, LPSCROLLINFO);\n        INT FlatSB_GetScrollPos(HWND, INT);\n        BOOL FlatSB_GetScrollProp(HWND, INT, LPINT);\n        version (Win64) {\n            BOOL FlatSB_GetScrollPropPtr(HWND, INT, PINT_PTR);\n        } else {\n            alias FlatSB_GetScrollProp FlatSB_GetScrollPropPtr;\n        }\n        INT FlatSB_SetScrollPos(HWND, INT, INT, BOOL);\n        INT FlatSB_SetScrollInfo(HWND, INT, LPSCROLLINFO, BOOL);\n        INT FlatSB_SetScrollRange(HWND, INT, INT, INT, BOOL);\n        BOOL FlatSB_SetScrollProp(HWND, UINT, INT_PTR, BOOL);\n        alias FlatSB_SetScrollProp FlatSB_SetScrollPropPtr;\n        BOOL InitializeFlatSB(HWND);\n        HRESULT UninitializeFlatSB(HWND);\n    }\n\n    static if (_WIN32_WINNT >= 0x501) {\n        BOOL SetWindowSubclass(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);\n        BOOL GetWindowSubclass(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR*);\n        BOOL RemoveWindowSubclass(HWND, SUBCLASSPROC, UINT_PTR);\n        LRESULT DefSubclassProc(HWND, UINT, WPARAM, LPARAM);\n        INT DrawShadowText(HDC, LPCWSTR, UINT, RECT*, DWORD, COLORREF,\n          COLORREF, INT, INT);\n    }\n\n    int ImageList_Add(HIMAGELIST, HBITMAP, HBITMAP);\n    int ImageList_AddMasked(HIMAGELIST, HBITMAP, COLORREF);\n    BOOL ImageList_BeginDrag(HIMAGELIST, int, int, int);\n    HIMAGELIST ImageList_Create(int, int, UINT, int, int);\n    BOOL ImageList_Destroy(HIMAGELIST);\n    BOOL ImageList_DragEnter(HWND, int, int);\n    BOOL ImageList_DragLeave(HWND);\n    BOOL ImageList_DragMove(int, int);\n    BOOL ImageList_DragShowNolock(BOOL);\n    BOOL ImageList_Draw(HIMAGELIST, int, HDC, int, int, UINT);\n    BOOL ImageList_DrawEx(HIMAGELIST, int, HDC, int, int, int, int, COLORREF,\n      COLORREF, UINT);\n    void ImageList_EndDrag();\n    COLORREF ImageList_GetBkColor(HIMAGELIST);\n    HIMAGELIST ImageList_GetDragImage(LPPOINT, LPPOINT);\n    HICON ImageList_GetIcon(HIMAGELIST, int, UINT);\n    BOOL ImageList_GetIconSize(HIMAGELIST, int*, int*);\n    int ImageList_GetImageCount(HIMAGELIST);\n    BOOL ImageList_GetImageInfo(HIMAGELIST, int, IMAGEINFO*);\n    HIMAGELIST ImageList_LoadImageA(HINSTANCE, LPCSTR, int, int, COLORREF,\n      UINT, UINT);\n    HIMAGELIST ImageList_LoadImageW(HINSTANCE, LPCWSTR, int, int, COLORREF,\n      UINT, UINT);\n    HIMAGELIST ImageList_Merge(HIMAGELIST, int, HIMAGELIST, int, int, int);\n    BOOL ImageList_Remove(HIMAGELIST, int);\n    BOOL ImageList_Replace(HIMAGELIST, int, HBITMAP, HBITMAP);\n    int ImageList_ReplaceIcon(HIMAGELIST, int, HICON);\n    COLORREF ImageList_SetBkColor(HIMAGELIST, COLORREF);\n    BOOL ImageList_SetDragCursorImage(HIMAGELIST, int, int, int);\n    BOOL ImageList_SetIconSize(HIMAGELIST, int, int);\n    BOOL ImageList_SetOverlayImage(HIMAGELIST, int, int);\n\n    //#ifdef _OBJIDL_H\n    HIMAGELIST ImageList_Read(LPSTREAM);\n    BOOL ImageList_Write(HIMAGELIST, LPSTREAM);\n    //#endif\n\n    static if (_WIN32_IE >= 0x400) {\n        HIMAGELIST ImageList_Duplicate(HIMAGELIST himl);\n    }\n\n    void InitCommonControls();\n\n    static if (_WIN32_IE >= 0x300) {\n        BOOL InitCommonControlsEx(LPINITCOMMONCONTROLSEX);\n    }\n\n    int LBItemFromPt(HWND, POINT, BOOL);\n}\n\nint ImageList_AddIcon(HIMAGELIST himl, HICON hicon) {\n    return ImageList_ReplaceIcon(himl, -1, hicon);\n}\n\nHICON ImageList_ExtractIcon(HINSTANCE hi, HIMAGELIST himl, int i) {\n    return ImageList_GetIcon(himl, i, 0);\n}\n\nHIMAGELIST ImageList_LoadBitmap(HINSTANCE hi, LPCTSTR lpbmp, int cx,\n      int cGrow, COLORREF crMask) {\n    return ImageList_LoadImage(hi, lpbmp, cx, cGrow, crMask, IMAGE_BITMAP, 0);\n}\n\nBOOL ImageList_RemoveAll(HIMAGELIST himl) {\n    return ImageList_Remove(himl, -1);\n}\n\nCOLORREF ListView_GetBkColor(HWND w) {\n    return cast(COLORREF) SendMessage(w, LVM_GETBKCOLOR, 0, 0);\n}\n\nHIMAGELIST ListView_GetImageList(HWND w, int i) {\n    return cast(HIMAGELIST) SendMessage(w, LVM_GETIMAGELIST, i, 0);\n}\n\nint ListView_GetItemCount(HWND w) {\n    return cast(int) SendMessage(w, LVM_GETITEMCOUNT, 0, 0);\n}\n\nBOOL ListView_GetItem(HWND w, LPLVITEM pitem) {\n    return cast(BOOL) SendMessage(w, LVM_GETITEM, 0, cast(LPARAM) pitem);\n}\n\nBOOL ListView_SetBkColor(HWND w, COLORREF c) {\n    return cast(BOOL) SendMessage(w, LVM_SETBKCOLOR, 0, cast(LPARAM) c);\n}\n\nHIMAGELIST ListView_SetImageList(HWND w, HIMAGELIST h, int i) {\n    return cast(HIMAGELIST) SendMessage(w, LVM_SETIMAGELIST, i,\n      cast(LPARAM) h);\n}\n\nBOOL ListView_SetItem(HWND w, const(LV_ITEM)* i) {\n    return cast(BOOL) SendMessage(w, LVM_SETITEM, 0, cast(LPARAM) i);\n}\n\nint ListView_InsertItem(HWND w, const(LV_ITEM)* i) {\n    return cast(int) SendMessage(w, LVM_INSERTITEM, 0, cast(LPARAM) i);\n}\n\nBOOL ListView_DeleteItem(HWND w, int i) {\n    return cast(BOOL) SendMessage(w, LVM_DELETEITEM, i, 0);\n}\n\nBOOL ListView_DeleteAllItems(HWND w) {\n    return cast(BOOL) SendMessage(w, LVM_DELETEALLITEMS, 0, 0);\n}\n\nUINT ListView_GetCallbackMask(HWND w) {\n    return cast(UINT) SendMessage(w, LVM_GETCALLBACKMASK, 0, 0);\n}\n\nBOOL ListView_SetCallbackMask(HWND w, UINT m) {\n    return cast(BOOL) SendMessage(w, LVM_SETCALLBACKMASK, m, 0);\n}\n\nint ListView_GetNextItem(HWND w, int i, UINT f) {\n    return cast(int) SendMessage(w, LVM_GETNEXTITEM, i, MAKELPARAM(cast(ushort)f, 0));\n}\n\nint ListView_FindItem(HWND w, int i, const(LV_FINDINFO)* p) {\n    return cast(int) SendMessage(w, LVM_FINDITEM, i, cast(LPARAM) p);\n}\n\nBOOL ListView_GetItemRect(HWND w, int i, LPRECT p, int c) {\n    if (p)\n        p.left = c;\n    return cast(BOOL) SendMessage(w, LVM_GETITEMRECT, i, cast(LPARAM) p);\n}\n\nBOOL ListView_SetItemPosition(HWND w, int i, int x, int y) {\n    return cast(BOOL) SendMessage(w, LVM_SETITEMPOSITION, i, MAKELPARAM(cast(ushort)x, cast(ushort)y));\n}\n\nBOOL ListView_GetItemPosition(HWND w, int i, POINT* p) {\n    return cast(BOOL) SendMessage(w, LVM_GETITEMPOSITION, i, cast(LPARAM) p);\n}\n\nDWORD ListView_GetItemSpacing(HWND w, BOOL f) {\n    return cast(DWORD) SendMessage(w, LVM_GETITEMSPACING, f, 0);\n}\n\nint ListView_GetStringWidth(HWND w, LPCSTR s) {\n    return cast(int) SendMessage(w, LVM_GETSTRINGWIDTH, 0, cast(LPARAM) s);\n}\n\nint ListView_HitTest(HWND w, LPLVHITTESTINFO p) {\n    return cast(int) SendMessage(w, LVM_HITTEST, 0, cast(LPARAM) p);\n}\n\nBOOL ListView_EnsureVisible(HWND w, int i, BOOL f) {\n    return cast(BOOL) SendMessage(w, LVM_ENSUREVISIBLE, i, MAKELPARAM(cast(ushort)f, 0));\n}\n\nBOOL ListView_Scroll(HWND w, int dx, int dy) {\n    return cast(BOOL) SendMessage(w, LVM_SCROLL, dx, dy);\n}\n\nBOOL ListView_RedrawItems(HWND w, int f, int l) {\n    return cast(BOOL) SendMessage(w, LVM_REDRAWITEMS, f, l);\n}\n\nBOOL ListView_Arrange(HWND w, UINT c) {\n    return cast(BOOL) SendMessage(w, LVM_ARRANGE, c, 0);\n}\n\nHWND ListView_EditLabel(HWND w, int i) {\n    return cast(HWND) SendMessage(w, LVM_EDITLABEL, i, 0);\n}\n\nHWND ListView_GetEditControl(HWND w) {\n    return cast(HWND) SendMessage(w, LVM_GETEDITCONTROL, 0, 0);\n}\n\nBOOL ListView_GetColumn(HWND w, int i, LPLVCOLUMN p) {\n    return cast(BOOL) SendMessage(w, LVM_GETCOLUMN, i, cast(LPARAM) p);\n}\n\nBOOL ListView_SetColumn(HWND w, int i, const(LV_COLUMN)* p) {\n    return cast(BOOL) SendMessage(w, LVM_SETCOLUMN, i, cast(LPARAM) p);\n}\n\nint ListView_InsertColumn(HWND w, int i, const(LV_COLUMN)* p) {\n    return cast(int) SendMessage(w, LVM_INSERTCOLUMN, i, cast(LPARAM) p);\n}\n\nBOOL ListView_DeleteColumn(HWND w, int i) {\n    return cast(BOOL) SendMessage(w, LVM_DELETECOLUMN, i, 0);\n}\n\nint ListView_GetColumnWidth(HWND w, int i) {\n    return cast(int) SendMessage(w, LVM_GETCOLUMNWIDTH, i, 0);\n}\n\nBOOL ListView_SetColumnWidth(HWND w, int i, int x) {\n    return cast(BOOL) SendMessage(w, LVM_SETCOLUMNWIDTH, i, MAKELPARAM(cast(ushort)x, 0));\n}\n\nHIMAGELIST ListView_CreateDragImage(HWND w, int i, LPPOINT p) {\n    return cast(HIMAGELIST) SendMessage(w, LVM_CREATEDRAGIMAGE, i,\n      cast(LPARAM) p);\n}\n\nBOOL ListView_GetViewRect(HWND w, RECT* p) {\n    return cast(BOOL) SendMessage(w, LVM_GETVIEWRECT, 0, cast(LPARAM) p);\n}\n\nCOLORREF ListView_GetTextColor(HWND w) {\n    return cast(COLORREF) SendMessage(w, LVM_GETTEXTCOLOR, 0, 0);\n}\n\nBOOL ListView_SetTextColor(HWND w, COLORREF c) {\n    return cast(BOOL) SendMessage(w, LVM_SETTEXTCOLOR, 0, cast(LPARAM) c);\n}\n\nCOLORREF ListView_GetTextBkColor(HWND w) {\n    return cast(COLORREF) SendMessage(w, LVM_GETTEXTBKCOLOR, 0, 0);\n}\n\nBOOL ListView_SetTextBkColor(HWND w, COLORREF c) {\n    return cast(BOOL) SendMessage(w, LVM_SETTEXTBKCOLOR, 0, cast(LPARAM) c);\n}\n\nint ListView_GetTopIndex(HWND w) {\n    return cast(int) SendMessage(w, LVM_GETTOPINDEX, 0, 0);\n}\n\nint ListView_GetCountPerPage(HWND w) {\n    return cast(int) SendMessage(w, LVM_GETCOUNTPERPAGE, 0, 0);\n}\n\nBOOL ListView_GetOrigin(HWND w, LPPOINT p) {\n    return cast(BOOL) SendMessage(w, LVM_GETORIGIN, 0, cast(LPARAM) p);\n}\n\nBOOL ListView_Update(HWND w, WPARAM i) {\n    return cast(BOOL) SendMessage(w, LVM_UPDATE, i, 0);\n}\n\nvoid ListView_SetItemState(HWND w, int i, UINT d, UINT m) {\n    LV_ITEM _lvi;\n    _lvi.stateMask = m;\n    _lvi.state = d;\n    SendMessage(w, LVM_SETITEMSTATE, i, cast(LPARAM) &_lvi);\n}\n\nUINT ListView_GetItemState(HWND w, int i, UINT m) {\n    return cast(UINT) SendMessage(w, LVM_GETITEMSTATE, i, m);\n}\n\nvoid ListView_GetItemText(HWND w, int i, int iS, LPTSTR s, int n) {\n    LV_ITEM _lvi;\n    _lvi.iSubItem = iS;\n    _lvi.cchTextMax = n;\n    _lvi.pszText = s;\n    SendMessage(w, LVM_GETITEMTEXT, i, cast(LPARAM) &_lvi);\n}\n\nvoid ListView_SetItemText(HWND w, int i, int iS, LPTSTR s) {\n    LV_ITEM _lvi;\n    _lvi.iSubItem = iS;\n    _lvi.pszText = s;\n    SendMessage(w, LVM_SETITEMTEXT, i, cast(LPARAM) &_lvi);\n}\n\nvoid ListView_SetItemCount(HWND w, int n) {\n    SendMessage(w, LVM_SETITEMCOUNT, n, 0);\n}\n\nBOOL ListView_SortItems(HWND w, PFNLVCOMPARE f, LPARAM l) {\n    return cast(BOOL) SendMessage(w, LVM_SORTITEMS, l, cast(LPARAM) f);\n}\n\nvoid ListView_SetItemPosition32(HWND w, int i, int x, int y) {\n    POINT p;\n    p.x = x;\n    p.y = y;\n    SendMessage(w, LVM_SETITEMPOSITION32, i, cast(LPARAM) &p);\n}\n\nUINT ListView_GetSelectedCount(HWND w) {\n    return cast(UINT) SendMessage(w, LVM_GETSELECTEDCOUNT, 0, 0);\n}\n\nUINT ListView_GetCheckState(HWND w, UINT i) {\n    return ((cast(UINT) SendMessage(w, LVM_GETITEMSTATE, i, LVIS_STATEIMAGEMASK)) >> 12) - 1;\n}\n\nvoid ListView_SetCheckState(HWND w, UINT i, BOOL f) {\n    ListView_SetItemState(w, i, INDEXTOSTATEIMAGEMASK(f ? 2 : 1),\n      LVIS_STATEIMAGEMASK);\n}\n\nBOOL ListView_GetISearchString(HWND w, LPSTR lpsz) {\n    return cast(BOOL) SendMessage(w, LVM_GETISEARCHSTRING, 0,\n      cast(LPARAM) lpsz);\n}\n\nvoid ListView_CancelEditLabel(HWND w) {\n    SendMessage(w, LVM_CANCELEDITLABEL, 0, 0);\n}\n\nint ListView_EnableGroupView(HWND w, BOOL i) {\n    return cast(int) SendMessage(w, LVM_ENABLEGROUPVIEW, i, 0);\n}\n\n//static if (_WIN32_WINNT >= 0x500 || _WIN32_IE >= 0x500) {\n    BOOL ListView_SortItemsEx(HWND w, PFNLVCOMPARE c, LPARAM p) {\n        return cast(BOOL) SendMessage(w, LVM_SORTITEMSEX, cast(WPARAM) p, cast(LPARAM)c);\n    }\n//}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    int ListView_GetGroupInfo(HWND w, int i, PLVGROUP p) {\n        return cast(int) SendMessage(w, LVM_GETGROUPINFO, i, cast(LPARAM) p);\n    }\n\n    void ListView_GetGroupMetrics(HWND w, PLVGROUPMETRICS p) {\n        SendMessage(w, LVM_GETGROUPMETRICS, 0, cast(LPARAM) p);\n    }\n\n    BOOL ListView_GetInsertMark(HWND w, PLVINSERTMARK p) {\n        return cast(BOOL) SendMessage(w, LVM_GETINSERTMARK, 0, cast(LPARAM) p);\n    }\n\n    COLORREF ListView_GetInsertMarkColor(HWND w) {\n        return cast(COLORREF) SendMessage(w, LVM_GETINSERTMARKCOLOR, 0, 0);\n    }\n\n    int ListView_GetInsertMarkRect(HWND w, LPRECT p) {\n        return cast(int) SendMessage(w, LVM_GETINSERTMARKRECT, 0, cast(LPARAM) p);\n    }\n\n    COLORREF ListView_GetOutlineColor(HWND w) {\n        return cast(COLORREF) SendMessage(w, LVM_GETOUTLINECOLOR, 0, 0);\n    }\n\n    UINT ListView_GetSelectedColumn(HWND w) {\n        return cast(UINT) SendMessage(w, LVM_GETSELECTEDCOLUMN, 0, 0);\n    }\n\n    void ListView_GetTileInfo(HWND w, PLVTILEINFO p) {\n        SendMessage(w, LVM_GETTILEINFO, 0, cast(LPARAM) p);\n    }\n\n    void ListView_GetTileViewInfo(HWND w, PLVTILEVIEWINFO p) {\n        SendMessage(w, LVM_GETTILEVIEWINFO, 0, cast(LPARAM) p);\n    }\n\n    DWORD ListView_GetView(HWND w) {\n        return cast(DWORD) SendMessage(w, LVM_GETVIEW, 0, 0);\n    }\n\n    BOOL ListView_HasGroup(HWND w, int i) {\n        return cast(BOOL) SendMessage(w, LVM_HASGROUP, i, 0);\n    }\n\n    int ListView_InsertGroup(HWND w, int i, PLVGROUP p) {\n        return cast(int) SendMessage(w, LVM_INSERTGROUP, i, cast(LPARAM) p);\n    }\n\n    void ListView_InsertGroupSorted(HWND w, PLVINSERTGROUPSORTED p) {\n        SendMessage(w, LVM_INSERTGROUPSORTED, cast(WPARAM) p, 0);\n    }\n\n    BOOL ListView_InsertMarkHitTest(HWND w, LPPOINT p, PLVINSERTMARK t) {\n        return cast(BOOL) SendMessage(w, LVM_INSERTMARKHITTEST, cast(WPARAM) p, cast(LPARAM) t);\n    }\n\n    BOOL ListView_IsGroupViewEnabled(HWND w) {\n        return cast(BOOL) SendMessage(w, LVM_ISGROUPVIEWENABLED, 0, 0);\n    }\n\n    UINT ListView_MapIDToIndex(HWND w, UINT i) {\n        return cast(UINT) SendMessage(w, LVM_MAPIDTOINDEX, i, 0);\n    }\n\n    /*  ??? MSDN documents this as \"Not implemented\", except in relation to\n     *  Windows CE/Mobile.\n     */\n    void ListView_MoveGroup(HWND w, int i, int t) {\n        SendMessage(w, LVM_MOVEGROUP, i, t);\n    }\n\n    void ListView_RemoveAllGroups(HWND w) {\n        SendMessage(w, LVM_REMOVEALLGROUPS, 0, 0);\n    }\n\n    int ListView_RemoveGroup(HWND w, int i) {\n        return cast(int) SendMessage(w, LVM_REMOVEGROUP, i, 0);\n    }\n\n    int ListView_SetGroupInfo(HWND w, int i, PLVGROUP p) {\n        return cast(int) SendMessage(w, LVM_SETGROUPINFO, i, cast(LPARAM) p);\n    }\n\n    void ListView_SetGroupMetrics(HWND w, PLVGROUPMETRICS p) {\n        SendMessage(w, LVM_SETGROUPMETRICS, 0, cast(LPARAM) p);\n    }\n\n    BOOL ListView_SetInfoTip(HWND w, PLVSETINFOTIP p) {\n        return cast(BOOL) SendMessage(w, LVM_SETINFOTIP, 0, cast(LPARAM) p);\n    }\n\n    BOOL ListView_SetInsertMark(HWND w, PLVINSERTMARK p) {\n        return cast(BOOL) SendMessage(w, LVM_SETINSERTMARK, 0, cast(LPARAM) p);\n    }\n\n    COLORREF ListView_SetInsertMarkColor(HWND w, COLORREF c) {\n        return cast(COLORREF) SendMessage(w, LVM_SETINSERTMARKCOLOR, 0, c);\n    }\n\n    COLORREF ListView_SetOutlineColor(HWND w, COLORREF c) {\n        return cast(COLORREF) SendMessage(w, LVM_SETOUTLINECOLOR, 0, c);\n    }\n\n    void ListView_SetSelectedColumn(HWND w, int i) {\n        SendMessage(w, LVM_SETSELECTEDCOLUMN, i, 0);\n    }\n\n    BOOL ListView_SetTileInfo(HWND w, PLVTILEINFO p) {\n        return cast(BOOL) SendMessage(w, LVM_SETTILEINFO, 0, cast(LPARAM) p);\n    }\n\n    BOOL ListView_SetTileViewInfo(HWND w, PLVTILEVIEWINFO p) {\n        return cast(BOOL) SendMessage(w, LVM_SETTILEVIEWINFO, 0, cast(LPARAM) p);\n    }\n\n    int ListView_SetView(HWND w, DWORD i) {\n        return cast(int) SendMessage(w, LVM_SETVIEW, i, 0);\n    }\n\n    int ListView_SortGroups(HWND w, PFNLVGROUPCOMPARE c, LPVOID p) {\n        return cast(int) SendMessage(w, LVM_SORTGROUPS, cast(WPARAM) c, cast(LPARAM) p);\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        CBM_FIRST        = 0x1700,\n        CB_SETMINVISIBLE = CBM_FIRST + 1,\n        CB_GETMINVISIBLE = CBM_FIRST + 2,\n        CB_SETCUEBANNER = CBM_FIRST + 3,\n        CB_GETCUEBANNER = CBM_FIRST + 4,\n    }\n\n    BOOL ComboBox_SetMinVisible(HWND w, INT i) {\n        return cast(BOOL) SendMessage(w, CB_SETMINVISIBLE, cast(WPARAM) i, 0);\n    }\n\n    int ComboBox_GetMinVisible(HWND w) {\n        return cast(int) SendMessage(w, CB_GETMINVISIBLE, 0, 0);\n    }\n}\n\nextern (Windows) BOOL MakeDragList(HWND);\nextern (Windows) void MenuHelp(UINT, WPARAM, LPARAM, HMENU, HINSTANCE, HWND,\n  PUINT);\n\nCOLORREF MonthCal_GetColor(HWND hwnd, INT icolor) {\n    return cast(COLORREF) SendMessage(hwnd, MCM_GETCOLOR,\n      cast(WPARAM) icolor, 0);\n}\n\nBOOL MonthCal_GetCurSel(HWND hwnd, LPSYSTEMTIME lpsystime) {\n    return cast(BOOL) SendMessage(hwnd, MCM_GETCURSEL, 0,\n      cast(LPARAM) lpsystime);\n}\n\nDWORD MonthCal_GetFirstDayOfWeek(HWND hwnd) {\n    return cast(DWORD) SendMessage(hwnd, MCM_GETFIRSTDAYOFWEEK, 0, 0);\n}\n\nDWORD MonthCal_GetMaxSelCount(HWND hwnd) {\n    return cast(DWORD) SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0);\n}\n\nDWORD MonthCal_GetMaxTodayWidth(HWND hwnd) {\n    return cast(DWORD) SendMessage(hwnd, MCM_GETMAXTODAYWIDTH, 0, 0);\n}\n\nBOOL MonthCal_GetMinReqRect(HWND hwnd, LPRECT lpRectInfo) {\n    return cast(BOOL) SendMessage(hwnd, MCM_GETMINREQRECT, 0,\n      cast(LPARAM) lpRectInfo);\n}\n\nINT MonthCal_GetMonthDelta(HWND hwnd) {\n    return cast(INT) SendMessage(hwnd, MCM_GETMONTHDELTA, 0, 0);\n}\n\nINT MonthCal_GetMonthRange(HWND hwnd, DWORD flag, LPSYSTEMTIME systimearray) {\n    return cast(INT) SendMessage(hwnd, MCM_GETMONTHRANGE, cast(WPARAM) flag,\n      cast(LPARAM) systimearray);\n}\n\nDWORD MonthCal_GetRange(HWND hwnd, LPSYSTEMTIME systimearray) {\n    return cast(DWORD) SendMessage(hwnd, MCM_GETRANGE, 0,\n      cast(LPARAM) systimearray);\n}\n\nBOOL MonthCal_GetSelRange(HWND hwnd, LPSYSTEMTIME systimearray) {\n    return cast(BOOL) SendMessage(hwnd, MCM_GETSELRANGE, 0,\n      cast(LPARAM) systimearray);\n}\n\nBOOL MonthCal_GetToday(HWND hwnd, LPSYSTEMTIME systime) {\n    return cast(BOOL) SendMessage(hwnd, MCM_GETTODAY, 0,\n      cast(LPARAM) systime);\n}\n\nBOOL MonthCal_GetUnicodeFormat(HWND hwnd) {\n    return cast(BOOL) SendMessage(hwnd, MCM_GETUNICODEFORMAT, 0, 0);\n}\n\nDWORD MonthCal_HitTest(HWND hwnd, PMCHITTESTINFO pmchittest) {\n    return cast(DWORD) SendMessage(hwnd, MCM_HITTEST, 0,\n      cast(LPARAM) pmchittest);\n}\n\nCOLORREF MonthCal_SetColor(HWND hwnd, INT icolor, COLORREF clr) {\n    return cast(COLORREF) SendMessage(hwnd, MCM_SETCOLOR, cast(WPARAM) icolor,\n      cast(LPARAM) clr);\n}\n\nBOOL MonthCal_SetCurSel(HWND hwnd, LPSYSTEMTIME lpsystime) {\n    return cast(BOOL) SendMessage(hwnd, MCM_SETCURSEL, 0,\n      cast(LPARAM) lpsystime);\n}\n\nBOOL MonthCal_SetDayState(HWND hwnd, INT imonths, LPMONTHDAYSTATE lpdatestatearray) {\n    return cast(BOOL) SendMessage(hwnd, MCM_SETDAYSTATE, cast(WPARAM) imonths,\n      cast(LPARAM) lpdatestatearray);\n}\n\nDWORD MonthCal_SetFirstDayOfWeek(HWND hwnd, INT iday) {\n    return cast(DWORD) SendMessage(hwnd, MCM_SETFIRSTDAYOFWEEK, 0,\n      cast(LPARAM) iday);\n}\n\nBOOL MonthCal_SetMaxSelCount(HWND hwnd, UINT imax) {\n    return cast(BOOL) SendMessage(hwnd, MCM_SETMAXSELCOUNT,\n      cast(WPARAM) imax, 0);\n}\n\nINT MonthCal_SetMonthDelta(HWND hwnd, INT idelta) {\n    return cast(INT) SendMessage(hwnd, MCM_SETMONTHDELTA, cast(WPARAM) idelta, 0);\n}\n\nBOOL MonthCal_SetSelRange(HWND hwnd, LPSYSTEMTIME systimearray) {\n    return cast(BOOL) SendMessage(hwnd, MCM_SETSELRANGE, 0,\n      cast(LPARAM) systimearray);\n}\n\nvoid MonthCal_SetToday(HWND hwnd, LPSYSTEMTIME systime) {\n    SendMessage(hwnd, MCM_SETTODAY, 0, cast(LPARAM) systime);\n}\n\nBOOL MonthCal_SetUnicodeFormat(HWND hwnd, BOOL unicode) {\n    return cast(BOOL) SendMessage(hwnd, MCM_SETUNICODEFORMAT,\n      cast(WPARAM) unicode, 0);\n}\n\nBOOL MonthCal_SetRange(HWND w, DWORD f, LPSYSTEMTIME st) {\n    return cast(BOOL) SendMessage(w, MCM_SETRANGE, cast(WPARAM) f,\n      cast(LPARAM) st);\n}\n\nextern (Windows) BOOL ShowHideMenuCtl(HWND, UINT_PTR, PINT);\n\nBOOL TabCtrl_GetItem(HWND w, int i, LPTCITEM p) {\n    return cast(BOOL) SendMessage(w, TCM_GETITEM, i, cast(LPARAM) p);\n}\n\nBOOL TabCtrl_SetItem(HWND w, int i, LPTCITEM p) {\n    return cast(BOOL) SendMessage(w, TCM_SETITEM, i, cast(LPARAM) p);\n}\n\nint TabCtrl_InsertItem(HWND w, int i, const(TC_ITEM)* p) {\n    return cast(int) SendMessage(w, TCM_INSERTITEM, i, cast(LPARAM) p);\n}\n\nBOOL TabCtrl_DeleteItem(HWND w, int i) {\n    return cast(BOOL) SendMessage(w, TCM_DELETEITEM, i, 0);\n}\n\nBOOL TabCtrl_DeleteAllItems(HWND w) {\n    return cast(BOOL) SendMessage(w, TCM_DELETEALLITEMS, 0, 0);\n}\n\nBOOL TabCtrl_GetItemRect(HWND w, int i, LPRECT p) {\n    return cast(BOOL) SendMessage(w, TCM_GETITEMRECT, i, cast(LPARAM) p);\n}\n\nint TabCtrl_GetCurSel(HWND w) {\n    return cast(int) SendMessage(w, TCM_GETCURSEL, 0, 0);\n}\n\nint TabCtrl_SetCurSel(HWND w, int i) {\n    return cast(int) SendMessage(w, TCM_SETCURSEL, i, 0);\n}\n\nint TabCtrl_HitTest(HWND w, LPTCHITTESTINFO p) {\n    return cast(int) SendMessage(w, TCM_HITTEST, 0, cast(LPARAM) p);\n}\n\nBOOL TabCtrl_SetItemExtra(HWND w, int c) {\n    return cast(BOOL) SendMessage(w, TCM_SETITEMEXTRA, c, 0);\n}\n\nint TabCtrl_AdjustRect(HWND w, BOOL b, LPRECT p) {\n    return cast(int) SendMessage(w, TCM_ADJUSTRECT, b, cast(LPARAM) p);\n}\n\nDWORD TabCtrl_SetItemSize(HWND w, int x, int y) {\n    return cast(DWORD) SendMessage(w, TCM_SETITEMSIZE, 0, MAKELPARAM(cast(ushort)x, cast(ushort)y));\n}\n\nvoid TabCtrl_RemoveImage(HWND w, int i) {\n    SendMessage(w, TCM_REMOVEIMAGE, i, 0);\n}\n\nvoid TabCtrl_SetPadding(HWND w, int x, int y) {\n    SendMessage(w, TCM_SETPADDING, 0, MAKELPARAM(cast(ushort)x, cast(ushort)y));\n}\n\nint TabCtrl_GetRowCount(HWND w) {\n    return cast(int) SendMessage(w, TCM_GETROWCOUNT, 0, 0);\n}\n\nHWND TabCtrl_GetToolTips(HWND w) {\n    return cast(HWND) SendMessage(w, TCM_GETTOOLTIPS, 0, 0);\n}\n\nvoid TabCtrl_SetToolTips(HWND w, HWND t) {\n    SendMessage(w, TCM_SETTOOLTIPS, cast(WPARAM) t, 0);\n}\n\nint TabCtrl_GetCurFocus(HWND w) {\n    return cast(int) SendMessage(w, TCM_GETCURFOCUS, 0, 0);\n}\n\nvoid TabCtrl_SetCurFocus(HWND w, int i) {\n    SendMessage(w, TCM_SETCURFOCUS, i, 0);\n}\n\nHIMAGELIST TabCtrl_GetImageList(HWND w) {\n    return cast(HIMAGELIST) SendMessage(w, TCM_GETIMAGELIST, 0, 0);\n}\n\nHIMAGELIST TabCtrl_SetImageList(HWND w, HIMAGELIST h) {\n    return cast(HIMAGELIST) SendMessage(w, TCM_SETIMAGELIST, 0,\n      cast(LPARAM) h);\n}\n\nint TabCtrl_GetItemCount(HWND w) {\n    return cast(int) SendMessage(w, TCM_GETITEMCOUNT, 0, 0);\n}\n\nextern (Windows) BOOL _TrackMouseEvent(LPTRACKMOUSEEVENT);\n\nHTREEITEM TreeView_InsertItem(HWND w, LPTVINSERTSTRUCT i) {\n    return cast(HTREEITEM) SendMessage(w, TVM_INSERTITEM, 0, cast(LPARAM) i);\n}\n\nBOOL TreeView_DeleteItem(HWND w, HTREEITEM i) {\n    return cast(BOOL) SendMessage(w, TVM_DELETEITEM, 0, cast(LPARAM) i);\n}\n\nBOOL TreeView_DeleteAllItems(HWND w) {\n    return cast(BOOL) SendMessage(w, TVM_DELETEITEM, 0, cast(LPARAM) TVI_ROOT);\n}\n\nBOOL TreeView_Expand(HWND w, HTREEITEM i, UINT c) {\n    return cast(BOOL) SendMessage(w, TVM_EXPAND, c, cast(LPARAM) i);\n}\n\nBOOL TreeView_GetItemRect(HWND w, HTREEITEM i, LPRECT p, BOOL c) {\n    *cast(HTREEITEM*) p = i;\n    return cast(BOOL) SendMessage(w, TVM_GETITEMRECT, c, cast(LPARAM) p);\n}\n\nUINT TreeView_GetCount(HWND w) {\n    return cast(UINT) SendMessage(w, TVM_GETCOUNT, 0, 0);\n}\n\nUINT TreeView_GetIndent(HWND w) {\n    return cast(UINT) SendMessage(w, TVM_GETINDENT, 0, 0);\n}\n\nBOOL TreeView_SetIndent(HWND w, INT i) {\n    return cast(BOOL) SendMessage(w, TVM_SETINDENT, i, 0);\n}\n\nHIMAGELIST TreeView_GetImageList(HWND w, INT i) {\n    return cast(HIMAGELIST) SendMessage(w, TVM_GETIMAGELIST, i, 0);\n}\n\nHIMAGELIST TreeView_SetImageList(HWND w, HIMAGELIST h, INT i) {\n    return cast(HIMAGELIST) SendMessage(w, TVM_SETIMAGELIST, i,\n      cast(LPARAM) h);\n}\n\nHTREEITEM TreeView_GetNextItem(HWND w, HTREEITEM i, UINT c) {\n    return cast(HTREEITEM) SendMessage(w, TVM_GETNEXTITEM, c, cast(LPARAM) i);\n}\n\nHTREEITEM TreeView_GetChild(HWND w, HTREEITEM i) {\n    return TreeView_GetNextItem(w, i, TVGN_CHILD);\n}\n\nHTREEITEM TreeView_GetNextSibling(HWND w, HTREEITEM i) {\n    return TreeView_GetNextItem(w, i, TVGN_NEXT);\n}\n\nHTREEITEM TreeView_GetPrevSibling(HWND w, HTREEITEM i) {\n    return TreeView_GetNextItem(w, i, TVGN_PREVIOUS);\n}\n\nHTREEITEM TreeView_GetParent(HWND w, HTREEITEM i) {\n    return TreeView_GetNextItem(w, i, TVGN_PARENT);\n}\n\nHTREEITEM TreeView_GetFirstVisible(HWND w) {\n    return TreeView_GetNextItem(w, null, TVGN_FIRSTVISIBLE);\n}\n\nHTREEITEM TreeView_GetNextVisible(HWND w, HTREEITEM i) {\n    return TreeView_GetNextItem(w, i, TVGN_NEXTVISIBLE);\n}\n\nHTREEITEM TreeView_GetPrevVisible(HWND w, HTREEITEM i) {\n    return TreeView_GetNextItem(w, i, TVGN_PREVIOUSVISIBLE);\n}\n\nHTREEITEM TreeView_GetSelection(HWND w) {\n    return TreeView_GetNextItem(w, null, TVGN_CARET);\n}\n\nHTREEITEM TreeView_GetDropHilight(HTREEITEM w) {\n    return TreeView_GetNextItem(w, null, TVGN_DROPHILITE);\n}\n\nHTREEITEM TreeView_GetRoot(HWND w) {\n    return TreeView_GetNextItem(w, null, TVGN_ROOT);\n}\n\nBOOL TreeView_Select(HWND w, HTREEITEM i, UINT c) {\n    return cast(BOOL) SendMessage(w, TVM_SELECTITEM, c, cast(LPARAM) i);\n}\n\nBOOL TreeView_SelectItem(HWND w, HTREEITEM i) {\n    return TreeView_Select(w, i, TVGN_CARET);\n}\n\nBOOL TreeView_SelectDropTarget(HWND w, HTREEITEM i) {\n    return TreeView_Select(w, i, TVGN_DROPHILITE);\n}\n\nBOOL TreeView_SelectSetFirstVisible(HWND w, HTREEITEM i) {\n    return TreeView_Select(w, i, TVGN_FIRSTVISIBLE);\n}\n\nBOOL TreeView_GetItem(HWND w, LPTVITEM i) {\n return cast(BOOL) SendMessage(w, TVM_GETITEM, 0, cast(LPARAM) i);\n}\n\nBOOL TreeView_SetItem(HWND w, const(TV_ITEM)* i) {\n    return cast(BOOL) SendMessage(w, TVM_SETITEM, 0, cast(LPARAM) i);\n}\n\nHWND TreeView_EditLabel(HWND w, HTREEITEM i) {\n    return cast(HWND) SendMessage(w, TVM_EDITLABEL, 0, cast(LPARAM) i);\n}\n\nHWND TreeView_GetEditControl(HWND w) {\n    return cast(HWND) SendMessage(w, TVM_GETEDITCONTROL, 0, 0);\n}\n\nUINT TreeView_GetVisibleCount(HWND w) {\n    return cast(UINT) SendMessage(w, TVM_GETVISIBLECOUNT, 0, 0);\n}\n\nHTREEITEM TreeView_HitTest(HWND w, LPTVHITTESTINFO p) {\n    return cast(HTREEITEM) SendMessage(w, TVM_HITTEST, 0, cast(LPARAM) p);\n}\n\nHIMAGELIST TreeView_CreateDragImage(HWND w, HTREEITEM i) {\n    return cast(HIMAGELIST) SendMessage(w, TVM_CREATEDRAGIMAGE, 0,\n      cast(LPARAM) i);\n}\n\nBOOL TreeView_SortChildren(HWND w, HTREEITEM i, BOOL r) {\n    return cast(BOOL) SendMessage(w, TVM_SORTCHILDREN, r, cast(LPARAM) i);\n}\n\nBOOL TreeView_EnsureVisible(HWND w, HTREEITEM i) {\n    return cast(BOOL) SendMessage(w, TVM_ENSUREVISIBLE, 0, cast(LPARAM) i);\n}\n\nBOOL TreeView_SortChildrenCB(HWND w, LPTVSORTCB s, BOOL r) {\n    return cast(BOOL) SendMessage(w, TVM_SORTCHILDRENCB, r, cast(LPARAM) s);\n}\n\nBOOL TreeView_EndEditLabelNow(HWND w, BOOL f) {\n    return cast(BOOL) SendMessage(w, TVM_ENDEDITLABELNOW, f, 0);\n}\n\nBOOL TreeView_GetISearchString(HWND w, LPTSTR s) {\n    return cast(BOOL) SendMessage(w, TVM_GETISEARCHSTRING, 0, cast(LPARAM) s);\n}\n\nstatic if (_WIN32_IE >= 0x300) {\n    DWORD ListView_ApproximateViewRect(HWND w, int iw, int ih, int i) {\n        return cast(DWORD) SendMessage(w, LVM_APPROXIMATEVIEWRECT, i,\n          MAKELPARAM(cast(ushort)iw, cast(ushort)ih));\n    }\n\n    DWORD ListView_SetExtendedListViewStyle(HWND w, DWORD s) {\n        return cast(DWORD) SendMessage(w, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, s);\n    }\n\n    DWORD ListView_GetExtendedListViewStyle(HWND w) {\n        return cast(DWORD) SendMessage(w, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);\n    }\n\n    BOOL ListView_SetColumnOrderArray(HWND w, int i, int* a) {\n        return cast(BOOL) SendMessage(w, LVM_SETCOLUMNORDERARRAY,\n          cast(WPARAM) i, cast(LPARAM) a);\n    }\n\n    BOOL ListView_GetColumnOrderArray(HWND w, int i, int* a) {\n        return cast(BOOL) SendMessage(w, LVM_GETCOLUMNORDERARRAY,\n          cast(WPARAM) i, cast(LPARAM) a);\n    }\n\n    HWND ListView_GetHeader(HWND w) {\n        return cast(HWND) SendMessage(w, LVM_GETHEADER, 0, 0);\n    }\n\n    HCURSOR ListView_GetHotCursor(HWND w) {\n        return cast(HCURSOR) SendMessage(w, LVM_GETHOTCURSOR, 0, 0);\n    }\n\n    INT ListView_GetHotItem(HWND w) {\n        return cast(INT) SendMessage(w, LVM_GETHOTITEM, 0, 0);\n    }\n\n    BOOL ListView_GetSubItemRect(HWND w, int i, int isi, int c, LPRECT p) {\n        if (p)\n        {\n            p.left = c;\n            p.top = isi;\n        }\n        return cast(BOOL) SendMessage(w, LVM_GETSUBITEMRECT, i, cast(LPARAM) p);\n    }\n\n    HCURSOR ListView_SetHotCursor(HWND w, HCURSOR c) {\n        return cast(HCURSOR) SendMessage(w, LVM_SETHOTCURSOR, 0,\n          cast(LPARAM) c);\n    }\n\n    INT ListView_SetHotItem(HWND w, INT i) {\n        return cast(INT) SendMessage(w, LVM_SETHOTITEM, cast(WPARAM) i, 0);\n    }\n\n    DWORD ListView_SetIconSpacing(HWND w, int x, int y) {\n        return cast(DWORD) SendMessage(w, LVM_SETICONSPACING, 0,\n          MAKELONG(cast(ushort)x, cast(ushort)y));\n    }\n\n    INT ListView_SubItemHitTest(HWND w, LPLVHITTESTINFO p) {\n        return cast(INT) SendMessage(w, LVM_SUBITEMHITTEST, 0, cast(LPARAM) p);\n    }\n\n    BOOL ListView_SetItemCountEx(HWND w, int i, DWORD f) {\n        return cast(BOOL) SendMessage(w, LVM_SETITEMCOUNT, i, cast(LPARAM) f);\n    }\n\n    extern (Windows) {\n        WINBOOL ImageList_SetImageCount(HIMAGELIST, UINT);\n        WINBOOL ImageList_Copy(HIMAGELIST, int, HIMAGELIST, int, UINT);\n        WINBOOL ImageList_DrawIndirect(IMAGELISTDRAWPARAMS*);\n    }\n\n    int TabCtrl_SetMinTabWidth(HWND hwnd, int x) {\n        return cast(int) SendMessage(hwnd, TCM_SETMINTABWIDTH, 0, x);\n    }\n\n    VOID TabCtrl_DeselectAll(HWND hwnd, UINT fExcludeFocus) {\n        SendMessage(hwnd, TCM_DESELECTALL, fExcludeFocus, 0);\n    }\n\n    HWND TreeView_GetToolTips(HWND w) {\n        return cast(HWND) SendMessage(w, TVM_GETTOOLTIPS, 0, 0);\n    }\n\n    HWND TreeView_SetToolTips(HWND w, HWND wt) {\n        return cast(HWND) SendMessage(w, TVM_SETTOOLTIPS, cast(WPARAM) wt, 0);\n    }\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    BOOL ListView_GetBkImage(HWND h, LPLVBKIMAGE plvbki) {\n        return cast(BOOL) SendMessage(h, LVM_GETBKIMAGE, 0,\n          cast(LPARAM) plvbki);\n    }\n\n    BOOL ListView_SetBkImage(HWND h, LPLVBKIMAGE plvbki) {\n        return cast(BOOL) SendMessage(h, LVM_SETBKIMAGE, 0,\n          cast(LPARAM) plvbki);\n    }\n\n    DWORD ListView_SetExtendedListViewStyleEx(HWND w, DWORD m, DWORD s) {\n        return cast(DWORD) SendMessage(w, LVM_SETEXTENDEDLISTVIEWSTYLE, m, s);\n    }\n\n    VOID ListView_SetWorkAreas(HWND w, INT n, LPRECT r) {\n        SendMessage(w, LVM_SETWORKAREAS, cast(WPARAM) n, cast(LPARAM) r);\n    }\n\n    VOID ListView_GetWorkAreas(HWND w, INT n, LPRECT r) {\n        SendMessage(w, LVM_GETWORKAREAS, cast(WPARAM) n, cast(LPARAM) r);\n    }\n\n    BOOL ListView_GetNumberOfWorkAreas(HWND w, LPUINT n) {\n        return cast(BOOL) SendMessage(w, LVM_GETNUMBEROFWORKAREAS, 0,\n          cast(LPARAM) n);\n    }\n\n    DWORD ListView_SetHoverTime(HWND w, DWORD t) {\n        return cast(DWORD) SendMessage(w, LVM_SETHOVERTIME, 0,\n          cast(LPARAM) t);\n    }\n\n    DWORD ListView_GetHoverTime(HWND w) {\n        return cast(DWORD) SendMessage(w, LVM_GETHOVERTIME, 0, 0);\n    }\n\n    INT ListView_GetSelectionMark(HWND w) {\n        return cast(INT) SendMessage(w, LVM_GETSELECTIONMARK, 0, 0);\n    }\n\n    INT ListView_SetSelectionMark(HWND w, INT i) {\n        return cast(INT) SendMessage(w, LVM_SETSELECTIONMARK, 0, cast(LPARAM) i);\n    }\n\n    HWND ListView_SetToolTips(HWND w, HWND n) {\n        return cast(HWND) SendMessage(w, LVM_SETTOOLTIPS, cast(WPARAM) n, 0);\n    }\n\n    HWND ListView_GetToolTips(HWND w) {\n        return cast(HWND) SendMessage(w, LVM_GETTOOLTIPS, 0, 0);\n    }\n\n    BOOL ListView_SetUnicodeFormat(HWND w, BOOL f) {\n        return cast(BOOL) SendMessage(w, LVM_SETUNICODEFORMAT,\n          cast(WPARAM) f, 0);\n    }\n\n    BOOL ListView_GetUnicodeFormat(HWND w) {\n        return cast(BOOL) SendMessage(w, LVM_GETUNICODEFORMAT, 0, 0);\n    }\n\n    BOOL TabCtrl_HighlightItem(HWND hwnd, INT i, WORD fHighlight) {\n        return cast(BOOL) SendMessage(hwnd, TCM_HIGHLIGHTITEM,\n          cast(WPARAM) i, cast(LPARAM) MAKELONG(fHighlight, 0));\n    }\n\n    DWORD TabCtrl_SetExtendedStyle(HWND hwnd, DWORD dw) {\n        return cast(DWORD) SendMessage(hwnd, TCM_SETEXTENDEDSTYLE, 0, dw);\n    }\n\n    DWORD TabCtrl_GetExtendedStyle(HWND hwnd) {\n        return cast(DWORD) SendMessage(hwnd, TCM_GETEXTENDEDSTYLE, 0, 0);\n    }\n\n    BOOL TabCtrl_SetUnicodeFormat(HWND hwnd, HWND fUnicode) {\n        return cast(BOOL) SendMessage(hwnd, TCM_SETUNICODEFORMAT,\n          cast(WPARAM) fUnicode, 0);\n    }\n\n    BOOL TabCtrl_GetUnicodeFormat(HWND hwnd) {\n        return cast(BOOL) SendMessage(hwnd, TCM_GETUNICODEFORMAT, 0, 0);\n    }\n\n    COLORREF TreeView_GetBkColor(HWND w) {\n        return cast(COLORREF) SendMessage(w, TVM_GETBKCOLOR, 0, 0);\n    }\n\n    COLORREF TreeView_GetInsertMarkColor(HWND w) {\n        return cast(COLORREF) SendMessage(w, TVM_GETINSERTMARKCOLOR, 0, 0);\n    }\n\n    int TreeView_GetItemHeight(HWND w) {\n        return cast(int) SendMessage(w, TVM_GETITEMHEIGHT, 0, 0);\n    }\n\n    UINT TreeView_GetScrollTime(HWND w) {\n        return cast(UINT) SendMessage(w, TVM_GETSCROLLTIME, 0, 0);\n    }\n\n    COLORREF TreeView_GetTextColor(HWND w) {\n        return cast(COLORREF) SendMessage(w, TVM_GETTEXTCOLOR, 0, 0);\n    }\n\n    COLORREF TreeView_SetBkColor(HWND w, COLORREF c) {\n        return cast(COLORREF) SendMessage(w, TVM_SETBKCOLOR, 0,\n          cast(LPARAM) c);\n    }\n\n    COLORREF TreeView_SetInsertMarkColor(HWND w, COLORREF c) {\n        return cast(COLORREF) SendMessage(w, TVM_SETINSERTMARKCOLOR, 0,\n          cast(LPARAM) c);\n    }\n\n    int TreeView_SetItemHeight(HWND w, SHORT h) {\n        return cast(int) SendMessage(w, TVM_SETITEMHEIGHT, cast(WPARAM) h, 0);\n    }\n\n    UINT TreeView_SetScrollTime(HWND w, UINT t) {\n        return cast(UINT) SendMessage(w, TVM_SETSCROLLTIME, cast(WPARAM) t, 0);\n    }\n\n    COLORREF TreeView_SetTextColor(HWND w, COLORREF c) {\n        return cast(COLORREF) SendMessage(w, TVM_SETTEXTCOLOR, 0,\n          cast(LPARAM) c);\n    }\n\n    BOOL TreeView_SetInsertMark(HWND w, HTREEITEM i, BOOL a) {\n        return cast(BOOL) SendMessage(w, TVM_SETINSERTMARK, cast(WPARAM) a,\n          cast(LPARAM) i);\n    }\n\n    BOOL TreeView_SetUnicodeFormat(HWND w, BOOL u) {\n        return cast(BOOL) SendMessage(w, TVM_SETUNICODEFORMAT,\n          cast(WPARAM) u, 0);\n    }\n\n    BOOL TreeView_GetUnicodeFormat(HWND w) {\n        return cast(BOOL) SendMessage(w, TVM_GETUNICODEFORMAT, 0, 0);\n    }\n\n    HTREEITEM TreeView_GetLastVisible(HWND w) {\n        return TreeView_GetNextItem(w, null, TVGN_LASTVISIBLE);\n    }\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    UINT TreeView_GetItemState(HWND w, HTREEITEM i, UINT m) {\n        return cast(UINT) SendMessage(w, TVM_GETITEMSTATE, cast(WPARAM) i,\n          cast(LPARAM) m);\n    }\n\n    BOOL TreeView_SetItemState(HWND w, HTREEITEM i, UINT d, UINT m) {\n        TVITEM _tvi;\n        _tvi.mask = TVIF_STATE;\n        _tvi.hItem = i;\n        _tvi.stateMask = m;\n        _tvi.state = d;\n        return cast(BOOL) SendMessage(w, TVM_SETITEM, 0, cast(LPARAM) &_tvi);\n    }\n}\n\n\n//#ifdef _WIN32_WCE               // these are PPC only\n/+\nextern (Windows) {\n    HWND  CommandBar_Create(HINSTANCE, HWND, int);\n    BOOL  CommandBar_Show(HWND, BOOL);\n    int   CommandBar_AddBitmap(HWND, HINSTANCE, int, int, int, int);\n    HWND  CommandBar_InsertComboBox(HWND, HINSTANCE, int, UINT, WORD, WORD);\n    BOOL  CommandBar_InsertMenubar(HWND, HINSTANCE, WORD, WORD );\n    BOOL  CommandBar_InsertMenubarEx(HWND, HINSTANCE, LPTSTR, WORD);\n    BOOL  CommandBar_DrawMenuBar(HWND, WORD);\n    HMENU CommandBar_GetMenu(HWND, WORD);\n    BOOL  CommandBar_AddAdornments(HWND, DWORD, DWORD);\n    int   CommandBar_Height(HWND hwndCB);\n}\n\n// MinGW: These two are not in the DLL\nvoid CommandBar_InsertButton(HWND hwnd, int i, LPTBBUTTON lptbbutton) {\n    SendMessage(hwnd, TB_INSERTBUTTON, i, lptbbutton);\n}\nalias DestroyWindow CommandBar_Destroy;\n+/\n//#endif // _WIN32_WCE\n\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    struct EDITBALLOONTIP\n    {\n        DWORD cbStruct;\n        LPCWSTR pszTitle;\n        LPCWSTR pszText;\n        INT ttiIcon;\n    }\n    alias EDITBALLOONTIP* PEDITBALLOONTIP;\n\nenum EM_SETCUEBANNER = ECM_FIRST + 1;\nenum EM_GETCUEBANNER = ECM_FIRST + 2;\nenum EM_SHOWBALLOONTIP = ECM_FIRST + 3;\nenum EM_HIDEBALLOONTIP = ECM_FIRST + 4;\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\nenum EM_SETHILITE = ECM_FIRST + 5;\nenum EM_GETHILITE = ECM_FIRST + 6;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/commdlg.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.12\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_commdlg.d)\n */\nmodule core.sys.windows.commdlg;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"comdlg32\");\n\nprivate import core.sys.windows.w32api;\nimport core.sys.windows.windef, core.sys.windows.winuser;\nimport core.sys.windows.wingdi; // for LPLOGFONTA\n\nconst TCHAR[]\n    LBSELCHSTRING = \"commdlg_LBSelChangedNotify\",\n    SHAREVISTRING = \"commdlg_ShareViolation\",\n    FILEOKSTRING  = \"commdlg_FileNameOK\",\n    COLOROKSTRING = \"commdlg_ColorOK\",\n    SETRGBSTRING  = \"commdlg_SetRGBColor\",\n    HELPMSGSTRING = \"commdlg_help\",\n    FINDMSGSTRING = \"commdlg_FindReplace\";\n\nenum : UINT {\n    CDN_FIRST          = -601, // also in commctrl.h\n    CDN_LAST           = -699,\n    CDN_INITDONE       = CDN_FIRST,\n    CDN_SELCHANGE      = CDN_FIRST - 1,\n    CDN_FOLDERCHANGE   = CDN_FIRST - 2,\n    CDN_SHAREVIOLATION = CDN_FIRST - 3,\n    CDN_HELP           = CDN_FIRST - 4,\n    CDN_FILEOK         = CDN_FIRST - 5,\n    CDN_TYPECHANGE     = CDN_FIRST - 6,\n}\n\n//static if (_WIN32_WINNT >= 0x500) {\n    enum : UINT {\n        CDN_INCLUDEITEM    = CDN_FIRST - 7,\n    }\n//}\n\nenum : UINT {\n    CDM_FIRST           = WM_USER + 100,\n    CDM_LAST            = WM_USER + 200,\n    CDM_GETSPEC         = CDM_FIRST,\n    CDM_GETFILEPATH,\n    CDM_GETFOLDERPATH,\n    CDM_GETFOLDERIDLIST,\n    CDM_SETCONTROLTEXT,\n    CDM_HIDECONTROL,\n    CDM_SETDEFEXT    // = CDM_FIRST + 6\n}\n\n// flags for ChooseColor\nenum : DWORD {\n    CC_RGBINIT              = 0x0001,\n    CC_FULLOPEN             = 0x0002,\n    CC_PREVENTFULLOPEN      = 0x0004,\n    CC_SHOWHELP             = 0x0008,\n    CC_ENABLEHOOK           = 0x0010,\n    CC_ENABLETEMPLATE       = 0x0020,\n    CC_ENABLETEMPLATEHANDLE = 0x0040,\n    CC_SOLIDCOLOR           = 0x0080,\n    CC_ANYCOLOR             = 0x0100\n}\n\n// flags for ChooseFont\nenum : DWORD {\n    CF_SCREENFONTS          = 0x00000001,\n    CF_PRINTERFONTS         = 0x00000002,\n    CF_BOTH                 = 0x00000003,\n    CF_SHOWHELP             = 0x00000004,\n    CF_ENABLEHOOK           = 0x00000008,\n    CF_ENABLETEMPLATE       = 0x00000010,\n    CF_ENABLETEMPLATEHANDLE = 0x00000020,\n    CF_INITTOLOGFONTSTRUCT  = 0x00000040,\n    CF_USESTYLE             = 0x00000080,\n    CF_EFFECTS              = 0x00000100,\n    CF_APPLY                = 0x00000200,\n    CF_ANSIONLY             = 0x00000400,\n    CF_SCRIPTSONLY          = CF_ANSIONLY,\n    CF_NOVECTORFONTS        = 0x00000800,\n    CF_NOOEMFONTS           = 0x00000800,\n    CF_NOSIMULATIONS        = 0x00001000,\n    CF_LIMITSIZE            = 0x00002000,\n    CF_FIXEDPITCHONLY       = 0x00004000,\n    CF_WYSIWYG              = 0x00008000,\n    CF_FORCEFONTEXIST       = 0x00010000,\n    CF_SCALABLEONLY         = 0x00020000,\n    CF_TTONLY               = 0x00040000,\n    CF_NOFACESEL            = 0x00080000,\n    CF_NOSTYLESEL           = 0x00100000,\n    CF_NOSIZESEL            = 0x00200000,\n    CF_SELECTSCRIPT         = 0x00400000,\n    CF_NOSCRIPTSEL          = 0x00800000,\n    CF_NOVERTFONTS          = 0x01000000\n}\n\n// Font type for ChooseFont\nenum : WORD {\n    BOLD_FONTTYPE      = 0x0100,\n    ITALIC_FONTTYPE    = 0x0200,\n    REGULAR_FONTTYPE   = 0x0400,\n    SCREEN_FONTTYPE    = 0x2000,\n    PRINTER_FONTTYPE   = 0x4000,\n    SIMULATED_FONTTYPE = 0x8000\n}\n\nenum : UINT {\n    WM_CHOOSEFONT_GETLOGFONT = WM_USER +   1,\n    WM_CHOOSEFONT_SETLOGFONT = WM_USER + 101,\n    WM_CHOOSEFONT_SETFLAGS   = WM_USER + 102\n}\n\n// flags for OpenFileName\nenum : DWORD {\n    OFN_SHAREWARN            = 0,\n    OFN_SHARENOWARN          = 0x000001,\n    OFN_READONLY             = 0x000001,\n    OFN_SHAREFALLTHROUGH     = 0x000002,\n    OFN_OVERWRITEPROMPT      = 0x000002,\n    OFN_HIDEREADONLY         = 0x000004,\n    OFN_NOCHANGEDIR          = 0x000008,\n    OFN_SHOWHELP             = 0x000010,\n    OFN_ENABLEHOOK           = 0x000020,\n    OFN_ENABLETEMPLATE       = 0x000040,\n    OFN_ENABLETEMPLATEHANDLE = 0x000080,\n    OFN_NOVALIDATE           = 0x000100,\n    OFN_ALLOWMULTISELECT     = 0x000200,\n    OFN_EXTENSIONDIFFERENT   = 0x000400,\n    OFN_PATHMUSTEXIST        = 0x000800,\n    OFN_FILEMUSTEXIST        = 0x001000,\n    OFN_CREATEPROMPT         = 0x002000,\n    OFN_SHAREAWARE           = 0x004000,\n    OFN_NOREADONLYRETURN     = 0x008000,\n    OFN_NOTESTFILECREATE     = 0x010000,\n    OFN_NONETWORKBUTTON      = 0x020000,\n    OFN_NOLONGNAMES          = 0x040000,\n    OFN_EXPLORER             = 0x080000,\n    OFN_NODEREFERENCELINKS   = 0x100000,\n    OFN_LONGNAMES            = 0x200000,\n    OFN_ENABLESIZING         = 0x800000\n}\n\nenum : DWORD {\n    FR_DOWN                 = 0x00000001,\n    FR_WHOLEWORD            = 0x00000002,\n    FR_MATCHCASE            = 0x00000004,\n    FR_FINDNEXT             = 0x00000008,\n    FR_REPLACE              = 0x00000010,\n    FR_REPLACEALL           = 0x00000020,\n    FR_DIALOGTERM           = 0x00000040,\n    FR_SHOWHELP             = 0x00000080,\n    FR_ENABLEHOOK           = 0x00000100,\n    FR_ENABLETEMPLATE       = 0x00000200,\n    FR_NOUPDOWN             = 0x00000400,\n    FR_NOMATCHCASE          = 0x00000800,\n    FR_NOWHOLEWORD          = 0x00001000,\n    FR_ENABLETEMPLATEHANDLE = 0x00002000,\n    FR_HIDEUPDOWN           = 0x00004000,\n    FR_HIDEMATCHCASE        = 0x00008000,\n    FR_HIDEWHOLEWORD        = 0x00010000,\n    FR_MATCHDIAC            = 0x20000000,\n    FR_MATCHKASHIDA         = 0x40000000,\n    FR_MATCHALEFHAMZA       = 0x80000000\n}\n\nenum : DWORD {\n    PD_ALLPAGES                   = 0,\n    PD_SELECTION                  = 0x000001,\n    PD_PAGENUMS                   = 0x000002,\n    PD_NOSELECTION                = 0x000004,\n    PD_NOPAGENUMS                 = 0x000008,\n    PD_COLLATE                    = 0x000010,\n    PD_PRINTTOFILE                = 0x000020,\n    PD_PRINTSETUP                 = 0x000040,\n    PD_NOWARNING                  = 0x000080,\n    PD_RETURNDC                   = 0x000100,\n    PD_RETURNIC                   = 0x000200,\n    PD_RETURNDEFAULT              = 0x000400,\n    PD_SHOWHELP                   = 0x000800,\n    PD_ENABLEPRINTHOOK            = 0x001000,\n    PD_ENABLESETUPHOOK            = 0x002000,\n    PD_ENABLEPRINTTEMPLATE        = 0x004000,\n    PD_ENABLESETUPTEMPLATE        = 0x008000,\n    PD_ENABLEPRINTTEMPLATEHANDLE  = 0x010000,\n    PD_ENABLESETUPTEMPLATEHANDLE  = 0x020000,\n    PD_USEDEVMODECOPIES           = 0x040000,\n    PD_USEDEVMODECOPIESANDCOLLATE = 0x040000,\n    PD_DISABLEPRINTTOFILE         = 0x080000,\n    PD_HIDEPRINTTOFILE            = 0x100000,\n    PD_NONETWORKBUTTON            = 0x200000\n}\n\n//static if (_WIN32_WINNT >= 0x500) {\n    enum : DWORD {\n        PD_CURRENTPAGE      = 0x00400000,\n        PD_NOCURRENTPAGE    = 0x00800000,\n        PD_EXCLUSIONFLAGS   = 0x01000000,\n        PD_USELARGETEMPLATE = 0x10000000,\n    }\n\n    enum : HRESULT {\n        PD_RESULT_CANCEL,\n        PD_RESULT_PRINT,\n        PD_RESULT_APPLY\n    }\n\nenum DWORD START_PAGE_GENERAL = 0xFFFFFFFF;\n//}\n\nenum {\n    PSD_DEFAULTMINMARGINS             = 0,\n    PSD_INWININIINTLMEASURE           = 0,\n    PSD_MINMARGINS                    = 0x000001,\n    PSD_MARGINS                       = 0x000002,\n    PSD_INTHOUSANDTHSOFINCHES         = 0x000004,\n    PSD_INHUNDREDTHSOFMILLIMETERS     = 0x000008,\n    PSD_DISABLEMARGINS                = 0x000010,\n    PSD_DISABLEPRINTER                = 0x000020,\n    PSD_NOWARNING                     = 0x000080,\n    PSD_DISABLEORIENTATION            = 0x000100,\n    PSD_DISABLEPAPER                  = 0x000200,\n    PSD_RETURNDEFAULT                 = 0x000400,\n    PSD_SHOWHELP                      = 0x000800,\n    PSD_ENABLEPAGESETUPHOOK           = 0x002000,\n    PSD_ENABLEPAGESETUPTEMPLATE       = 0x008000,\n    PSD_ENABLEPAGESETUPTEMPLATEHANDLE = 0x020000,\n    PSD_ENABLEPAGEPAINTHOOK           = 0x040000,\n    PSD_DISABLEPAGEPAINTING           = 0x080000\n}\n\nenum : UINT {\n    WM_PSD_PAGESETUPDLG = WM_USER,\n    WM_PSD_FULLPAGERECT,\n    WM_PSD_MINMARGINRECT,\n    WM_PSD_MARGINRECT,\n    WM_PSD_GREEKTEXTRECT,\n    WM_PSD_ENVSTAMPRECT,\n    WM_PSD_YAFULLPAGERECT // = WM_USER + 6\n}\n\nenum : int {\n    CD_LBSELNOITEMS = -1,\n    CD_LBSELCHANGE,\n    CD_LBSELSUB,\n    CD_LBSELADD\n}\n\nenum WORD DN_DEFAULTPRN = 1;\n\n/+\n// Both MinGW and the windows docs indicate that there are macros for the send messages\n// the controls. These seem to be totally unnecessary -- and at least one of MinGW or\n// Windows Docs is buggy!\n\nint CommDlg_OpenSave_GetSpec(HWND hWndControl, LPARAM lparam, WPARAM wParam) {\n    return SendMessage(hWndControl, CDM_GETSPEC, wParam, lParam);\n}\n\nint CommDlg_OpenSave_GetFilePath(HWND hWndControl, LPARAM lparam, WPARAM wParam) {\n    return SendMessage(hWndControl, CDM_GETFILEPATH, wParam, lParam);\n}\n\nint CommDlg_OpenSave_GetFolderPath(HWND hWndControl, LPARAM lparam, WPARAM wParam) {\n    return SendMessage(hWndControl, CDM_GETFOLDERPATH, wParam, lParam);\n}\n\nint CommDlg_OpenSave_GetFolderIDList(HWND hWndControl, LPARAM lparam, WPARAM wParam) {\n    return SendMessage(hWndControl, CDM_GETFOLDERIDLIST, wParam, lParam);\n}\n\nvoid CommDlg_OpenSave_SetControlText(HWND hWndControl, LPARAM lparam, WPARAM wParam) {\n    return SendMessage(hWndControl, CDM_SETCONTROLTEXT, wParam, lParam);\n}\n\nvoid CommDlg_OpenSave_HideControl(HWND hWndControl, WPARAM wParam) {\n    return SendMessage(hWndControl, CDM_HIDECONTROL, wParam, 0);\n}\n\nvoid CommDlg_OpenSave_SetDefExt(HWND hWndControl, TCHAR* lparam) {\n    return SendMessage(hWndControl, CDM_SETCONTROLTEXT, 0, cast(LPARAM)lParam);\n}\n\n// These aliases seem even more unnecessary\nalias CommDlg_OpenSave_GetSpec\n    CommDlg_OpenSave_GetSpecA, CommDlg_OpenSave_GetSpecW;\nalias CommDlg_OpenSave_GetFilePath\n    CommDlg_OpenSave_GetFilePathA, CommDlg_OpenSave_GetFilePathW;\nalias CommDlg_OpenSave_GetFolderPath\n    CommDlg_OpenSave_GetFolderPathA, CommDlg_OpenSave_GetFolderPathW;\n+/\n\n// Callbacks.\nextern(Windows) {\nalias UINT_PTR function (HWND, UINT, WPARAM, LPARAM) nothrow\n    LPCCHOOKPROC, LPCFHOOKPROC, LPFRHOOKPROC, LPOFNHOOKPROC,\n    LPPAGEPAINTHOOK, LPPAGESETUPHOOK, LPSETUPHOOKPROC, LPPRINTHOOKPROC;\n}\n\n//align (1): // 1 in Win32, default in Win64\n\nstruct CHOOSECOLORA {\n    DWORD        lStructSize = CHOOSECOLORA.sizeof;\n    HWND         hwndOwner;\n    HWND         hInstance;\n    COLORREF     rgbResult;\n    COLORREF*    lpCustColors;\n    DWORD        Flags;\n    LPARAM       lCustData;\n    LPCCHOOKPROC lpfnHook;\n    LPCSTR       lpTemplateName;\n}\nalias CHOOSECOLORA* LPCHOOSECOLORA;\n\nstruct CHOOSECOLORW {\n    DWORD        lStructSize = CHOOSECOLORW.sizeof;\n    HWND         hwndOwner;\n    HWND         hInstance;\n    COLORREF     rgbResult;\n    COLORREF*    lpCustColors;\n    DWORD        Flags;\n    LPARAM       lCustData;\n    LPCCHOOKPROC lpfnHook;\n    LPCWSTR      lpTemplateName;\n}\nalias CHOOSECOLORW* LPCHOOSECOLORW;\n\nstruct CHOOSEFONTA {\n    DWORD        lStructSize = CHOOSEFONTA.sizeof;\n    HWND         hwndOwner;\n    HDC          hDC;\n    LPLOGFONTA   lpLogFont;\n    INT          iPointSize;\n    DWORD        Flags;\n    DWORD        rgbColors;\n    LPARAM       lCustData;\n    LPCFHOOKPROC lpfnHook;\n    LPCSTR       lpTemplateName;\n    HINSTANCE    hInstance;\n    LPSTR        lpszStyle;\n    WORD         nFontType;\n    WORD         ___MISSING_ALIGNMENT__;\n    INT          nSizeMin;\n    INT          nSizeMax;\n}\nalias CHOOSEFONTA* LPCHOOSEFONTA;\n\nstruct CHOOSEFONTW {\n    DWORD        lStructSize = CHOOSEFONTW.sizeof;\n    HWND         hwndOwner;\n    HDC          hDC;\n    LPLOGFONTW   lpLogFont;\n    INT          iPointSize;\n    DWORD        Flags;\n    DWORD        rgbColors;\n    LPARAM       lCustData;\n    LPCFHOOKPROC lpfnHook;\n    LPCWSTR      lpTemplateName;\n    HINSTANCE    hInstance;\n    LPWSTR       lpszStyle;\n    WORD         nFontType;\n    WORD         ___MISSING_ALIGNMENT__;\n    INT          nSizeMin;\n    INT          nSizeMax;\n}\nalias CHOOSEFONTW* LPCHOOSEFONTW;\n\nstruct DEVNAMES {\n    WORD wDriverOffset;\n    WORD wDeviceOffset;\n    WORD wOutputOffset;\n    WORD wDefault;\n}\nalias DEVNAMES* LPDEVNAMES;\n\nstruct FINDREPLACEA {\n    DWORD        lStructSize = FINDREPLACEA.sizeof;\n    HWND         hwndOwner;\n    HINSTANCE    hInstance;\n    DWORD        Flags;\n    LPSTR        lpstrFindWhat;\n    LPSTR        lpstrReplaceWith;\n    WORD         wFindWhatLen;\n    WORD         wReplaceWithLen;\n    LPARAM       lCustData;\n    LPFRHOOKPROC lpfnHook;\n    LPCSTR       lpTemplateName;\n}\nalias FINDREPLACEA* LPFINDREPLACEA;\n\nstruct FINDREPLACEW {\n    DWORD        lStructSize = FINDREPLACEW.sizeof;\n    HWND         hwndOwner;\n    HINSTANCE    hInstance;\n    DWORD        Flags;\n    LPWSTR       lpstrFindWhat;\n    LPWSTR       lpstrReplaceWith;\n    WORD         wFindWhatLen;\n    WORD         wReplaceWithLen;\n    LPARAM       lCustData;\n    LPFRHOOKPROC lpfnHook;\n    LPCWSTR      lpTemplateName;\n}\nalias FINDREPLACEW* LPFINDREPLACEW;\n\nstruct OPENFILENAMEA {\n    DWORD         lStructSize = OPENFILENAMEA.sizeof;\n    HWND          hwndOwner;\n    HINSTANCE     hInstance;\n    LPCSTR        lpstrFilter;\n    LPSTR         lpstrCustomFilter;\n    DWORD         nMaxCustFilter;\n    DWORD         nFilterIndex;\n    LPSTR         lpstrFile;\n    DWORD         nMaxFile;\n    LPSTR         lpstrFileTitle;\n    DWORD         nMaxFileTitle;\n    LPCSTR        lpstrInitialDir;\n    LPCSTR        lpstrTitle;\n    DWORD         Flags;\n    WORD          nFileOffset;\n    WORD          nFileExtension;\n    LPCSTR        lpstrDefExt;\n    LPARAM        lCustData;\n    LPOFNHOOKPROC lpfnHook;\n    LPCSTR        lpTemplateName;\n\n    //static if (_WIN32_WINNT >= 0x500) {\n        void          *pvReserved;\n        DWORD         dwReserved;\n        DWORD         FlagsEx;\n    //}\n}\nalias OPENFILENAMEA* LPOPENFILENAMEA;\n\nstruct OPENFILENAMEW {\n    DWORD         lStructSize = OPENFILENAMEW.sizeof;\n    HWND          hwndOwner;\n    HINSTANCE     hInstance;\n    LPCWSTR       lpstrFilter;\n    LPWSTR        lpstrCustomFilter;\n    DWORD         nMaxCustFilter;\n    DWORD         nFilterIndex;\n    LPWSTR        lpstrFile;\n    DWORD         nMaxFile;\n    LPWSTR        lpstrFileTitle;\n    DWORD         nMaxFileTitle;\n    LPCWSTR       lpstrInitialDir;\n    LPCWSTR       lpstrTitle;\n    DWORD         Flags;\n    WORD          nFileOffset;\n    WORD          nFileExtension;\n    LPCWSTR       lpstrDefExt;\n    LPARAM        lCustData;\n    LPOFNHOOKPROC lpfnHook;\n    LPCWSTR       lpTemplateName;\n\n    //static if (_WIN32_WINNT >= 0x500) {\n        void          *pvReserved;\n        DWORD         dwReserved;\n        DWORD         FlagsEx;\n    //}\n}\nalias OPENFILENAMEW* LPOPENFILENAMEW;\n\nenum size_t OPENFILENAME_SIZE_VERSION_400 = 76;\n\nstruct OFNOTIFYA {\n    NMHDR           hdr;\n    LPOPENFILENAMEA lpOFN;\n    LPSTR           pszFile;\n}\nalias OFNOTIFYA* LPOFNOTIFYA;\n\nstruct OFNOTIFYW {\n    NMHDR           hdr;\n    LPOPENFILENAMEW lpOFN;\n    LPWSTR          pszFile;\n}\nalias OFNOTIFYW* LPOFNOTIFYW;\n\nstruct PAGESETUPDLGA {\n    DWORD           lStructSize = PAGESETUPDLGA.sizeof;\n    HWND            hwndOwner;\n    HGLOBAL         hDevMode;\n    HGLOBAL         hDevNames;\n    DWORD           Flags;\n    POINT           ptPaperSize;\n    RECT            rtMinMargin;\n    RECT            rtMargin;\n    HINSTANCE       hInstance;\n    LPARAM          lCustData;\n    LPPAGESETUPHOOK lpfnPageSetupHook;\n    LPPAGEPAINTHOOK lpfnPagePaintHook;\n    LPCSTR          lpPageSetupTemplateName;\n    HGLOBAL         hPageSetupTemplate;\n}\nalias PAGESETUPDLGA* LPPAGESETUPDLGA;\n\nstruct PAGESETUPDLGW {\n    DWORD           lStructSize = PAGESETUPDLGW.sizeof;\n    HWND            hwndOwner;\n    HGLOBAL         hDevMode;\n    HGLOBAL         hDevNames;\n    DWORD           Flags;\n    POINT           ptPaperSize;\n    RECT            rtMinMargin;\n    RECT            rtMargin;\n    HINSTANCE       hInstance;\n    LPARAM          lCustData;\n    LPPAGESETUPHOOK lpfnPageSetupHook;\n    LPPAGEPAINTHOOK lpfnPagePaintHook;\n    LPCWSTR         lpPageSetupTemplateName;\n    HGLOBAL         hPageSetupTemplate;\n}\nalias PAGESETUPDLGW* LPPAGESETUPDLGW;\n\nalign (1) struct PRINTDLGA {\nalign(1):\n    DWORD           lStructSize = PRINTDLGA.sizeof;\n    version (Win64)\n        DWORD       padding1;\n    HWND            hwndOwner;\n    HANDLE          hDevMode;\n    HANDLE          hDevNames;\n    HDC             hDC;\n    DWORD           Flags;\n    WORD            nFromPage;\n    WORD            nToPage;\n    WORD            nMinPage;\n    WORD            nMaxPage;\n    WORD            nCopies;\n    version (Win64)\n        WORD        padding2;\n    HINSTANCE       hInstance;\n    LPARAM          lCustData;\n    LPPRINTHOOKPROC lpfnPrintHook;\n    LPSETUPHOOKPROC lpfnSetupHook;\n    LPCSTR          lpPrintTemplateName;\n    LPCSTR          lpSetupTemplateName;\n    HANDLE          hPrintTemplate;\n    HANDLE          hSetupTemplate;\n}\nalias PRINTDLGA* LPPRINTDLGA;\n\nalign (1) struct PRINTDLGW {\nalign(1):\n    DWORD           lStructSize = PRINTDLGW.sizeof;\n    version (Win64)\n        DWORD       padding1;\n    HWND            hwndOwner;\n    HANDLE          hDevMode;\n    HANDLE          hDevNames;\n    HDC             hDC;\n    DWORD           Flags;\n    WORD            nFromPage;\n    WORD            nToPage;\n    WORD            nMinPage;\n    WORD            nMaxPage;\n    WORD            nCopies;\n    version (Win64)\n        WORD        padding2;\n    HINSTANCE       hInstance;\n    LPARAM          lCustData;\n    LPPRINTHOOKPROC lpfnPrintHook;\n    LPSETUPHOOKPROC lpfnSetupHook;\n    LPCWSTR         lpPrintTemplateName;\n    LPCWSTR         lpSetupTemplateName;\n    HANDLE          hPrintTemplate;\n    HANDLE          hSetupTemplate;\n}\nalias PRINTDLGW* LPPRINTDLGW;\n\n//static if (_WIN32_WINNT >= 0x500) {\n    import core.sys.windows.unknwn; // for LPUNKNOWN\n    import core.sys.windows.prsht;  // for HPROPSHEETPAGE\n\n    struct PRINTPAGERANGE {\n        DWORD  nFromPage;\n        DWORD  nToPage;\n    }\n    alias PRINTPAGERANGE* LPPRINTPAGERANGE;\n\n    struct PRINTDLGEXA {\n        DWORD            lStructSize = PRINTDLGEXA.sizeof;\n        HWND             hwndOwner;\n        HGLOBAL          hDevMode;\n        HGLOBAL          hDevNames;\n        HDC              hDC;\n        DWORD            Flags;\n        DWORD            Flags2;\n        DWORD            ExclusionFlags;\n        DWORD            nPageRanges;\n        DWORD            nMaxPageRanges;\n        LPPRINTPAGERANGE lpPageRanges;\n        DWORD            nMinPage;\n        DWORD            nMaxPage;\n        DWORD            nCopies;\n        HINSTANCE        hInstance;\n        LPCSTR           lpPrintTemplateName;\n        LPUNKNOWN        lpCallback;\n        DWORD            nPropertyPages;\n        HPROPSHEETPAGE*  lphPropertyPages;\n        DWORD            nStartPage;\n        DWORD            dwResultAction;\n    }\n    alias PRINTDLGEXA* LPPRINTDLGEXA;\n\n    struct PRINTDLGEXW {\n        DWORD            lStructSize = PRINTDLGEXW.sizeof;\n        HWND             hwndOwner;\n        HGLOBAL          hDevMode;\n        HGLOBAL          hDevNames;\n        HDC              hDC;\n        DWORD            Flags;\n        DWORD            Flags2;\n        DWORD            ExclusionFlags;\n        DWORD            nPageRanges;\n        DWORD            nMaxPageRanges;\n        LPPRINTPAGERANGE lpPageRanges;\n        DWORD            nMinPage;\n        DWORD            nMaxPage;\n        DWORD            nCopies;\n        HINSTANCE        hInstance;\n        LPCWSTR          lpPrintTemplateName;\n        LPUNKNOWN        lpCallback;\n        DWORD            nPropertyPages;\n        HPROPSHEETPAGE*  lphPropertyPages;\n        DWORD            nStartPage;\n        DWORD            dwResultAction;\n    }\n    alias PRINTDLGEXW* LPPRINTDLGEXW;\n\n//} // _WIN32_WINNT >= 0x500\n\nextern (Windows) nothrow @nogc {\n    BOOL ChooseColorA(LPCHOOSECOLORA);\n    BOOL ChooseColorW(LPCHOOSECOLORW);\n    BOOL ChooseFontA(LPCHOOSEFONTA);\n    BOOL ChooseFontW(LPCHOOSEFONTW);\n    DWORD CommDlgExtendedError();\n    HWND FindTextA(LPFINDREPLACEA);\n    HWND FindTextW(LPFINDREPLACEW);\n    short GetFileTitleA(LPCSTR, LPSTR, WORD);\n    short GetFileTitleW(LPCWSTR, LPWSTR, WORD);\n    BOOL GetOpenFileNameA(LPOPENFILENAMEA);\n    BOOL GetOpenFileNameW(LPOPENFILENAMEW);\n    BOOL GetSaveFileNameA(LPOPENFILENAMEA);\n    BOOL GetSaveFileNameW(LPOPENFILENAMEW);\n    BOOL PageSetupDlgA(LPPAGESETUPDLGA);\n    BOOL PageSetupDlgW(LPPAGESETUPDLGW);\n    BOOL PrintDlgA(LPPRINTDLGA);\n    BOOL PrintDlgW(LPPRINTDLGW);\n    HWND ReplaceTextA(LPFINDREPLACEA);\n    HWND ReplaceTextW(LPFINDREPLACEW);\n\n    //static if (_WIN32_WINNT >= 0x500) {\n        HRESULT PrintDlgExA(LPPRINTDLGEXA);\n        HRESULT PrintDlgExW(LPPRINTDLGEXW);\n    //}\n}\n\nversion (Unicode) {\n    alias CHOOSECOLORW CHOOSECOLOR;\n    alias CHOOSEFONTW CHOOSEFONT;\n    alias FINDREPLACEW FINDREPLACE;\n    alias OPENFILENAMEW OPENFILENAME;\n    alias OFNOTIFYW OFNOTIFY;\n    alias PAGESETUPDLGW PAGESETUPDLG;\n    alias PRINTDLGW PRINTDLG;\n\n    alias ChooseColorW ChooseColor;\n    alias ChooseFontW ChooseFont;\n    alias FindTextW FindText;\n    alias GetFileTitleW GetFileTitle;\n    alias GetOpenFileNameW GetOpenFileName;\n    alias GetSaveFileNameW GetSaveFileName;\n    alias PageSetupDlgW PageSetupDlg;\n    alias PrintDlgW PrintDlg;\n    alias ReplaceTextW ReplaceText;\n\n    //static if (_WIN32_WINNT >= 0x500) {\n        alias PRINTDLGEXW PRINTDLGEX;\n        alias PrintDlgExW PrintDlgEx;\n    //}\n\n} else { // UNICODE\n\n    alias CHOOSECOLORA CHOOSECOLOR;\n    alias CHOOSEFONTA CHOOSEFONT;\n    alias FINDREPLACEA FINDREPLACE;\n    alias OPENFILENAMEA OPENFILENAME;\n    alias OFNOTIFYA OFNOTIFY;\n    alias PAGESETUPDLGA PAGESETUPDLG;\n    alias PRINTDLGA PRINTDLG;\n\n    alias ChooseColorA ChooseColor;\n    alias ChooseFontA ChooseFont;\n    alias FindTextA FindText;\n    alias GetFileTitleA GetFileTitle;\n    alias GetOpenFileNameA GetOpenFileName;\n    alias GetSaveFileNameA GetSaveFileName;\n    alias PageSetupDlgA PageSetupDlg;\n    alias PrintDlgA PrintDlg;\n    alias ReplaceTextA ReplaceText;\n\n    //static if (_WIN32_WINNT >= 0x500) {\n        alias PRINTDLGEXA PRINTDLGEX;\n        alias PrintDlgExA PrintDlgEx;\n    //}\n\n} // UNICODE\n\nalias CHOOSECOLOR* LPCHOOSECOLOR;\nalias CHOOSEFONT* LPCHOOSEFONT;\nalias FINDREPLACE* LPFINDREPLACE;\nalias OPENFILENAME* LPOPENFILENAME;\nalias OFNOTIFY* LPOFNOTIFY;\nalias PAGESETUPDLG* LPPAGESETUPDLG;\nalias PRINTDLG* LPPRINTDLG;\n//static if (_WIN32_WINNT >= 0x500) {\n    alias PRINTDLGEX* LPPRINTDLGEX;\n//}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/core.d",
    "content": "/**\n * Helper module for the Windows API\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_core.d)\n */\nmodule core.sys.windows.core;\nversion (Windows):\n\n/**\n The core Windows API functions.\n\n Importing this file is equivalent to the C code:\n ---\n #define WIN32_LEAN_AND_MEAN\n #include \"windows.h\"\n ---\n\n*/\n\npublic import core.sys.windows.windef;\npublic import core.sys.windows.winnt;\npublic import core.sys.windows.wincon;\npublic import core.sys.windows.winbase;\npublic import core.sys.windows.wingdi;\npublic import core.sys.windows.winuser;\npublic import core.sys.windows.winnls;\npublic import core.sys.windows.winver;\npublic import core.sys.windows.winnetwk;\npublic import core.sys.windows.winsvc;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/cpl.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_cpl.d)\n */\nmodule core.sys.windows.cpl;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.windef, core.sys.windows.winuser;\n\nenum : uint {\n    WM_CPL_LAUNCH = WM_USER + 1000,\n    WM_CPL_LAUNCHED\n}\n\nenum : uint {\n    CPL_DYNAMIC_RES,\n    CPL_INIT,\n    CPL_GETCOUNT,\n    CPL_INQUIRE,\n    CPL_SELECT,\n    CPL_DBLCLK,\n    CPL_STOP,\n    CPL_EXIT,\n    CPL_NEWINQUIRE,\n    CPL_STARTWPARMSA,\n    CPL_STARTWPARMSW, // = 10\n    CPL_SETUP = 200\n}\n\nextern (Windows) alias LONG function(HWND, UINT, LONG, LONG) APPLET_PROC;\n\nalign(1)\nstruct CPLINFO {\nalign(1):\n    int  idIcon;\n    int  idName;\n    int  idInfo;\n    LONG_PTR  lData;\n}\nalias CPLINFO* LPCPLINFO;\n\nalign(1)\nstruct NEWCPLINFOA {\nalign(1):\n    DWORD     dwSize = NEWCPLINFOA.sizeof;\n    DWORD     dwFlags;\n    DWORD     dwHelpContext;\n    LONG_PTR  lData;\n    HICON     hIcon;\n    CHAR[32]  szName;\n    CHAR[64]  szInfo;\n    CHAR[128] szHelpFile;\n}\nalias NEWCPLINFOA* LPNEWCPLINFOA;\n\nalign(1)\nstruct NEWCPLINFOW {\nalign(1):\n    DWORD      dwSize = NEWCPLINFOW.sizeof;\n    DWORD      dwFlags;\n    DWORD      dwHelpContext;\n    LONG_PTR   lData;\n    HICON      hIcon;\n    WCHAR[32]  szName;\n    WCHAR[64]  szInfo;\n    WCHAR[128] szHelpFile;\n}\nalias NEWCPLINFOW* LPNEWCPLINFOW;\n\nversion (Unicode) {\n    alias CPL_STARTWPARMSW CPL_STARTWPARMS;\n    alias NEWCPLINFOW NEWCPLINFO;\n} else {\n    alias CPL_STARTWPARMSA CPL_STARTWPARMS;\n    alias NEWCPLINFOA NEWCPLINFO;\n}\n\nalias NEWCPLINFO* LPNEWCPLINFO;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/cplext.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.10\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_cplext.d)\n */\nmodule core.sys.windows.cplext;\nversion (Windows):\n\nenum : uint {\n    CPLPAGE_MOUSE_BUTTONS      = 1,\n    CPLPAGE_MOUSE_PTRMOTION    = 2,\n    CPLPAGE_MOUSE_WHEEL        = 3,\n    CPLPAGE_KEYBOARD_SPEED     = 1,\n    CPLPAGE_DISPLAY_BACKGROUND = 1\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/custcntl.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_custcntl.d)\n */\nmodule core.sys.windows.custcntl;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.windef;\n\n// FIXME: check type\nenum CCF_NOTEXT = 1;\n\nenum size_t\n    CCHCCCLASS =  32,\n    CCHCCDESC  =  32,\n    CCHCCTEXT  = 256;\n\nstruct CCSTYLEA {\n    DWORD           flStyle;\n    DWORD           flExtStyle;\n    CHAR[CCHCCTEXT] szText;\n    LANGID          lgid;\n    WORD            wReserved1;\n}\nalias CCSTYLEA* LPCCSTYLEA;\n\nstruct CCSTYLEW {\n    DWORD            flStyle;\n    DWORD            flExtStyle;\n    WCHAR[CCHCCTEXT] szText;\n    LANGID           lgid;\n    WORD             wReserved1;\n}\nalias CCSTYLEW* LPCCSTYLEW;\n\nstruct CCSTYLEFLAGA {\n    DWORD flStyle;\n    DWORD flStyleMask;\n    LPSTR pszStyle;\n}\nalias CCSTYLEFLAGA* LPCCSTYLEFLAGA;\n\nstruct CCSTYLEFLAGW {\n    DWORD  flStyle;\n    DWORD  flStyleMask;\n    LPWSTR pszStyle;\n}\nalias CCSTYLEFLAGW* LPCCSTYLEFLAGW;\n\nstruct CCINFOA {\n    CHAR[CCHCCCLASS]  szClass;\n    DWORD             flOptions;\n    CHAR[CCHCCDESC]   szDesc;\n    UINT              cxDefault;\n    UINT              cyDefault;\n    DWORD             flStyleDefault;\n    DWORD             flExtStyleDefault;\n    DWORD             flCtrlTypeMask;\n    CHAR[CCHCCTEXT]   szTextDefault;\n    INT               cStyleFlags;\n    LPCCSTYLEFLAGA    aStyleFlags;\n    LPFNCCSTYLEA      lpfnStyle;\n    LPFNCCSIZETOTEXTA lpfnSizeToText;\n    DWORD             dwReserved1;\n    DWORD             dwReserved2;\n}\nalias CCINFOA* LPCCINFOA;\n\nstruct CCINFOW {\n    WCHAR[CCHCCCLASS] szClass;\n    DWORD             flOptions;\n    WCHAR[CCHCCDESC]  szDesc;\n    UINT              cxDefault;\n    UINT              cyDefault;\n    DWORD             flStyleDefault;\n    DWORD             flExtStyleDefault;\n    DWORD             flCtrlTypeMask;\n    WCHAR[CCHCCTEXT]  szTextDefault;\n    INT               cStyleFlags;\n    LPCCSTYLEFLAGW    aStyleFlags;\n    LPFNCCSTYLEW      lpfnStyle;\n    LPFNCCSIZETOTEXTW lpfnSizeToText;\n    DWORD             dwReserved1;\n    DWORD             dwReserved2;\n}\nalias CCINFOW* LPCCINFOW;\n\nextern (Windows) {\n    alias BOOL function(HWND, LPCCSTYLEA) LPFNCCSTYLEA;\n    alias BOOL function(HWND, LPCCSTYLEW) LPFNCCSTYLEW;\n    alias INT function(DWORD, DWORD, HFONT, LPSTR) LPFNCCSIZETOTEXTA;\n    alias INT function(DWORD, DWORD, HFONT, LPWSTR) LPFNCCSIZETOTEXTW;\n    alias UINT function(LPCCINFOA) LPFNCCINFOA;\n    alias UINT function(LPCCINFOW) LPFNCCINFOW;\n    UINT CustomControlInfoA(LPCCINFOA acci);\n    UINT CustomControlInfoW(LPCCINFOW acci);\n}\n\nversion (Unicode) {\n    alias CCSTYLEW CCSTYLE;\n    alias CCSTYLEFLAGW CCSTYLEFLAG;\n    alias CCINFOW CCINFO;\n    alias LPFNCCSTYLEW LPFNCCSTYLE;\n    alias LPFNCCSIZETOTEXTW LPFNCCSIZETOTEXT;\n    alias LPFNCCINFOW LPFNCCINFO;\n} else {\n    alias CCSTYLEA CCSTYLE;\n    alias CCSTYLEFLAGA CCSTYLEFLAG;\n    alias CCINFOA CCINFO;\n    alias LPFNCCSTYLEA LPFNCCSTYLE;\n    alias LPFNCCSIZETOTEXTA LPFNCCSIZETOTEXT;\n    alias LPFNCCINFOA LPFNCCINFO;\n}\n\nalias CCSTYLE* LPCCSTYLE;\nalias CCSTYLEFLAG* LPCCSTYLEFLAG;\nalias CCINFO* LPCCINFO;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/dbghelp.d",
    "content": "/**\n * ...\n *\n * Copyright: Copyright Benjamin Thaut 2010 - 2011.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Benjamin Thaut, Sean Kelly\n * Source:    $(DRUNTIMESRC core/sys/windows/_stacktrace.d)\n */\n\nmodule core.sys.windows.dbghelp;\nversion (Windows):\n\nimport core.sys.windows.windows;\n\npublic import core.sys.windows.dbghelp_types;\n\nextern(System)\n{\n    alias BOOL         function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;\n    alias PVOID        function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;\n    alias DWORD64      function(HANDLE hProcess, DWORD64 Address) GetModuleBaseProc64;\n    alias DWORD64      function(HANDLE hProcess, HANDLE hThread, ADDRESS64 *lpaddr) TranslateAddressProc64;\n\n    alias BOOL         function(HANDLE hProcess, PCSTR UserSearchPath, bool fInvadeProcess) SymInitializeFunc;\n    alias BOOL         function(HANDLE hProcess) SymCleanupFunc;\n    alias DWORD        function(DWORD SymOptions) SymSetOptionsFunc;\n    alias DWORD        function() SymGetOptionsFunc;\n    alias PVOID        function(HANDLE hProcess, DWORD64 AddrBase) SymFunctionTableAccess64Func;\n    alias BOOL         function(DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, PVOID ContextRecord,\n                                ReadProcessMemoryProc64 ReadMemoryRoutine, FunctionTableAccessProc64 FunctoinTableAccess,\n                                GetModuleBaseProc64 GetModuleBaseRoutine, TranslateAddressProc64 TranslateAddress) StackWalk64Func;\n    alias BOOL         function(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, IMAGEHLP_LINEA64 *line) SymGetLineFromAddr64Func;\n    alias DWORD64      function(HANDLE hProcess, DWORD64 dwAddr) SymGetModuleBase64Func;\n    alias BOOL         function(HANDLE hProcess, DWORD64 dwAddr, IMAGEHLP_MODULEA64 *ModuleInfo) SymGetModuleInfo64Func;\n    alias BOOL         function(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, IMAGEHLP_SYMBOLA64 *Symbol) SymGetSymFromAddr64Func;\n    alias DWORD        function(PCTSTR DecoratedName, PTSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) UnDecorateSymbolNameFunc;\n    alias DWORD64      function(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll) SymLoadModule64Func;\n    alias BOOL         function(HANDLE HProcess, PTSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc;\n    alias BOOL         function(HANDLE hProcess, DWORD64 Address) SymUnloadModule64Func;\n    alias BOOL         function(HANDLE hProcess, ULONG ActionCode, ulong CallbackContext, ulong UserContext) PSYMBOL_REGISTERED_CALLBACK64;\n    alias BOOL         function(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, ulong UserContext) SymRegisterCallback64Func;\n    alias API_VERSION* function() ImagehlpApiVersionFunc;\n}\n\nstruct DbgHelp\n{\n    SymInitializeFunc        SymInitialize;\n    SymCleanupFunc           SymCleanup;\n    StackWalk64Func          StackWalk64;\n    SymGetOptionsFunc        SymGetOptions;\n    SymSetOptionsFunc        SymSetOptions;\n    SymFunctionTableAccess64Func SymFunctionTableAccess64;\n    SymGetLineFromAddr64Func SymGetLineFromAddr64;\n    SymGetModuleBase64Func   SymGetModuleBase64;\n    SymGetModuleInfo64Func   SymGetModuleInfo64;\n    SymGetSymFromAddr64Func  SymGetSymFromAddr64;\n    UnDecorateSymbolNameFunc UnDecorateSymbolName;\n    SymLoadModule64Func      SymLoadModule64;\n    SymGetSearchPathFunc     SymGetSearchPath;\n    SymUnloadModule64Func    SymUnloadModule64;\n    SymRegisterCallback64Func SymRegisterCallback64;\n    ImagehlpApiVersionFunc   ImagehlpApiVersion;\n\n    static DbgHelp* get()\n    {\n        if ( sm_hndl != sm_hndl.init )\n            return &sm_inst;\n        if ( (sm_hndl = LoadLibraryA( \"dbghelp.dll\" )) != sm_hndl.init )\n        {\n            sm_inst.SymInitialize            = cast(SymInitializeFunc) GetProcAddress(sm_hndl,\"SymInitialize\");\n            sm_inst.SymCleanup               = cast(SymCleanupFunc) GetProcAddress(sm_hndl,\"SymCleanup\");\n            sm_inst.StackWalk64              = cast(StackWalk64Func) GetProcAddress(sm_hndl,\"StackWalk64\");\n            sm_inst.SymGetOptions            = cast(SymGetOptionsFunc) GetProcAddress(sm_hndl,\"SymGetOptions\");\n            sm_inst.SymSetOptions            = cast(SymSetOptionsFunc) GetProcAddress(sm_hndl,\"SymSetOptions\");\n            sm_inst.SymFunctionTableAccess64 = cast(SymFunctionTableAccess64Func) GetProcAddress(sm_hndl,\"SymFunctionTableAccess64\");\n            sm_inst.SymGetLineFromAddr64     = cast(SymGetLineFromAddr64Func) GetProcAddress(sm_hndl,\"SymGetLineFromAddr64\");\n            sm_inst.SymGetModuleBase64       = cast(SymGetModuleBase64Func) GetProcAddress(sm_hndl,\"SymGetModuleBase64\");\n            sm_inst.SymGetModuleInfo64       = cast(SymGetModuleInfo64Func) GetProcAddress(sm_hndl,\"SymGetModuleInfo64\");\n            sm_inst.SymGetSymFromAddr64      = cast(SymGetSymFromAddr64Func) GetProcAddress(sm_hndl,\"SymGetSymFromAddr64\");\n            sm_inst.SymLoadModule64          = cast(SymLoadModule64Func) GetProcAddress(sm_hndl,\"SymLoadModule64\");\n            sm_inst.SymGetSearchPath         = cast(SymGetSearchPathFunc) GetProcAddress(sm_hndl,\"SymGetSearchPath\");\n            sm_inst.SymUnloadModule64        = cast(SymUnloadModule64Func) GetProcAddress(sm_hndl,\"SymUnloadModule64\");\n            sm_inst.SymRegisterCallback64    = cast(SymRegisterCallback64Func) GetProcAddress(sm_hndl, \"SymRegisterCallback64\");\n            sm_inst.ImagehlpApiVersion       = cast(ImagehlpApiVersionFunc) GetProcAddress(sm_hndl, \"ImagehlpApiVersion\");\n            assert( sm_inst.SymInitialize && sm_inst.SymCleanup && sm_inst.StackWalk64 && sm_inst.SymGetOptions &&\n                    sm_inst.SymSetOptions && sm_inst.SymFunctionTableAccess64 && sm_inst.SymGetLineFromAddr64 &&\n                    sm_inst.SymGetModuleBase64 && sm_inst.SymGetModuleInfo64 && sm_inst.SymGetSymFromAddr64 &&\n                    sm_inst.SymLoadModule64 && sm_inst.SymGetSearchPath && sm_inst.SymUnloadModule64 &&\n                    sm_inst.SymRegisterCallback64 && sm_inst.ImagehlpApiVersion);\n\n            return &sm_inst;\n        }\n        return null;\n    }\n\n    shared static ~this()\n    {\n        if ( sm_hndl != sm_hndl.init )\n            FreeLibrary( sm_hndl );\n    }\n\nprivate:\n    __gshared DbgHelp sm_inst;\n    __gshared HANDLE  sm_hndl;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/dbghelp_types.d",
    "content": "/**\n * ...\n *\n * Copyright: Copyright Benjamin Thaut 2010 - 2011.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Benjamin Thaut, Sean Kelly\n * Source:    $(DRUNTIMESRC core/sys/windows/_dbghelp_types.d)\n */\n\nmodule core.sys.windows.dbghelp_types;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nimport core.sys.windows.windows;\n\npublic import core.sys.windows.winnt : TCHAR;\n\n/*\nenum ADDRESS_MODE : DWORD\n{\n    AddrMode1616 = 0,\n    AddrMode1632 = 1,\n    AddrModeReal = 2,\n    AddrModeFlat = 3,\n}\n*/\nenum : DWORD\n{\n    SYMOPT_DEFERRED_LOAD        = 0x00000004,\n    SYMOPT_FAIL_CRITICAL_ERRORS = 0x00000200,\n    SYMOPT_LOAD_LINES           = 0x00000010,\n    SYMOPT_DEBUG                = 0x80000000,\n}\n\nenum : ULONG\n{\n    CBA_READ_MEMORY             = 0x00000006,\n    CBA_DEBUG_INFO              = 0x10000000,\n}\n\npublic import core.sys.windows.basetyps : GUID;\n\nstruct ADDRESS64\n{\n    DWORD64      Offset;\n    WORD         Segment;\n    ADDRESS_MODE Mode;\n}\n\nstruct KDHELP64\n{\n    DWORD64 Thread;\n    DWORD   ThCallbackStack;\n    DWORD   ThCallbackBStore;\n    DWORD   NextCallback;\n    DWORD   FramePointer;\n    DWORD64 KiCallUserMode;\n    DWORD64 KeUserCallbackDispatcher;\n    DWORD64 SystemRangeStart;\n    DWORD64 KiUserExceptionDispatcher;\n    DWORD64 StackBase;\n    DWORD64 StackLimit;\n    DWORD64[5] Reserved;\n}\n\nstruct STACKFRAME64\n{\n    ADDRESS64  AddrPC;\n    ADDRESS64  AddrReturn;\n    ADDRESS64  AddrFrame;\n    ADDRESS64  AddrStack;\n    ADDRESS64  AddrBStore;\n    PVOID      FuncTableEntry;\n    DWORD64[4] Params;\n    BOOL       Far;\n    BOOL       Virtual;\n    DWORD64[3] Reserved;\n    KDHELP64   KdHelp;\n}\n\npublic import core.sys.windows.winnt : IMAGE_FILE_MACHINE_I386, IMAGE_FILE_MACHINE_IA64, IMAGE_FILE_MACHINE_AMD64;\n\nstruct IMAGEHLP_LINEA64\n{\n    DWORD   SizeOfStruct;\n    PVOID   Key;\n    DWORD   LineNumber;\n    PCSTR   FileName;\n    DWORD64 Address;\n}\nstruct IMAGEHLP_LINEW64\n{\n    DWORD   SizeOfStruct;\n    PVOID   Key;\n    DWORD   LineNumber;\n    PWSTR FileName;\n    DWORD64 Address;\n}\n\nenum SYM_TYPE : int\n{\n    SymNone = 0,\n    SymCoff,\n    SymCv,\n    SymPdb,\n    SymExport,\n    SymDeferred,\n    SymSym,\n    SymDia,\n    SymVirtual,\n    NumSymTypes,\n}\n\nstruct IMAGEHLP_MODULEA64\n{\n    DWORD      SizeOfStruct;\n    DWORD64    BaseOfImage;\n    DWORD      ImageSize;\n    DWORD      TimeDateStamp;\n    DWORD      CheckSum;\n    DWORD      NumSyms;\n    SYM_TYPE   SymType;\n    CHAR[32]   ModuleName;\n    CHAR[256]  ImageName;\n    CHAR[256]  LoadedImageName;\n    // new elements: 07-Jun-2002\n    version (none)\n    {\n        CHAR[256]  LoadedPdbName;\n        DWORD      CVSig;\n        CHAR[MAX_PATH*3] CVData;\n        DWORD      PdbSig;\n        GUID       PdbSig70;\n        DWORD      PdbAge;\n        BOOL       PdbUnmatched;\n        BOOL       DbgUnmachted;\n        BOOL       LineNumbers;\n        BOOL       GlobalSymbols;\n        BOOL       TypeInfo;\n    }\n    // new elements: 17-Dec-2003\n    version (none)\n    {\n        BOOL       SourceIndexed;\n        BOOL       Publics;\n    }\n}\nstruct IMAGEHLP_MODULEW64\n{\n    DWORD      SizeOfStruct;\n    DWORD64    BaseOfImage;\n    DWORD      ImageSize;\n    DWORD      TimeDateStamp;\n    DWORD      CheckSum;\n    DWORD      NumSyms;\n    SYM_TYPE   SymType;\n    WCHAR[32]  ModuleName;\n    WCHAR[256] ImageName;\n    WCHAR[256] LoadedImageName;\n    // new elements: 07-Jun-2002\n    version (none)\n    {\n        WCHAR[256] LoadedPdbName;\n        DWORD      CVSig;\n        WCHAR[MAX_PATH*3] CVData;\n        DWORD      PdbSig;\n        GUID       PdbSig70;\n        DWORD      PdbAge;\n        BOOL       PdbUnmatched;\n        BOOL       DbgUnmachted;\n        BOOL       LineNumbers;\n        BOOL       GlobalSymbols;\n        BOOL       TypeInfo;\n    }\n    // new elements: 17-Dec-2003\n    version (none)\n    {\n        BOOL       SourceIndexed;\n        BOOL       Publics;\n    }\n}\n\nstruct IMAGEHLP_SYMBOLA64\n{\n    DWORD    SizeOfStruct;\n    DWORD64  Address;\n    DWORD    Size;\n    DWORD    Flags;\n    DWORD    MaxNameLength;\n    CHAR[1] Name;\n}\nstruct IMAGEHLP_SYMBOLW64\n{\n    DWORD    SizeOfStruct;\n    DWORD64  Address;\n    DWORD    Size;\n    DWORD    Flags;\n    DWORD    MaxNameLength;\n    WCHAR[1] Name;\n}\n\n\nstruct IMAGEHLP_CBA_READ_MEMORY\n{\n    DWORD64 addr;\n    PVOID   buf;\n    DWORD   bytes;\n    DWORD   *bytesread;\n}\n\nstruct API_VERSION\n{\n    USHORT MajorVersion;\n    USHORT MinorVersion;\n    USHORT Revision;\n    USHORT Reserved;\n}\n\nversion (Unicode)\n{\n    alias IMAGEHLP_LINEW64 IMAGEHLP_LINE64;\n    alias IMAGEHLP_MODULEW64 IMAGEHLP_MODULE64;\n    alias IMAGEHLP_SYMBOLW64 IMAGEHLP_SYMBOL64;\n}\nelse\n{\n    alias IMAGEHLP_LINEA64 IMAGEHLP_LINE64;\n    alias IMAGEHLP_MODULEA64 IMAGEHLP_MODULE64;\n    alias IMAGEHLP_SYMBOLA64 IMAGEHLP_SYMBOL64;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/dbt.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Vladimir Vlasov\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_dbt.d)\n */\nmodule core.sys.windows.dbt;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nimport core.sys.windows.w32api, core.sys.windows.windef;\nimport core.sys.windows.basetyps; // for GUID\n\n// FIXME: clean up Windows version support\n\nenum : DWORD {\n    DBT_NO_DISK_SPACE           = 0x47,\n    DBT_CONFIGMGPRIVATE         = 0x7FFF,\n    DBT_DEVICEARRIVAL           = 0x8000,\n    DBT_DEVICEQUERYREMOVE       = 0x8001,\n    DBT_DEVICEQUERYREMOVEFAILED = 0x8002,\n    DBT_DEVICEREMOVEPENDING     = 0x8003,\n    DBT_DEVICEREMOVECOMPLETE    = 0x8004,\n    DBT_DEVICETYPESPECIFIC      = 0x8005,\n    DBT_DEVTYP_OEM              = 0,\n    DBT_DEVTYP_DEVNODE,\n    DBT_DEVTYP_VOLUME,\n    DBT_DEVTYP_PORT,\n    DBT_DEVTYP_NET,\n    DBT_DEVTYP_DEVICEINTERFACE,\n    DBT_DEVTYP_HANDLE        // = 6\n}\n\nenum : DWORD {\n    DBT_APPYBEGIN,\n    DBT_APPYEND,\n    DBT_DEVNODES_CHANGED     = 7,\n    DBT_QUERYCHANGECONFIG    = 0x17,\n    DBT_CONFIGCHANGED        = 0x18,\n    DBT_CONFIGCHANGECANCELED = 0x19,\n    DBT_MONITORCHANGE        = 0x1B,\n    DBT_SHELLLOGGEDON        = 32,\n    DBT_CONFIGMGAPI32        = 34,\n    DBT_VXDINITCOMPLETE      = 35,\n    DBT_VOLLOCKQUERYLOCK     = 0x8041,\n    DBT_VOLLOCKLOCKTAKEN     = 0x8042,\n    DBT_VOLLOCKLOCKFAILED    = 0x8043,\n    DBT_VOLLOCKQUERYUNLOCK   = 0x8044,\n    DBT_VOLLOCKLOCKRELEASED  = 0x8045,\n    DBT_VOLLOCKUNLOCKFAILED  = 0x8046,\n    DBT_USERDEFINED          = 0xFFFF\n}\n\nenum : WORD {\n    DBTF_MEDIA = 1,\n    DBTF_NET   = 2\n}\n\nenum : DWORD {\n    BSM_ALLCOMPONENTS      = 0,\n    BSM_APPLICATIONS       = 8,\n    BSM_ALLDESKTOPS        = 16,\n    BSM_INSTALLABLEDRIVERS = 4,\n    BSM_NETDRIVER          = 2,\n    BSM_VXDS               = 1,\n    BSF_FLUSHDISK          = 0x00000004,\n    BSF_FORCEIFHUNG        = 0x00000020,\n    BSF_IGNORECURRENTTASK  = 0x00000002,\n    BSF_NOHANG             = 0x00000008,\n    BSF_NOTIMEOUTIFNOTHUNG = 0x00000040,\n    BSF_POSTMESSAGE        = 0x00000010,\n    BSF_QUERY              = 0x00000001,\n    BSF_MSGSRV32ISOK_BIT   = 31,\n    BSF_MSGSRV32ISOK       = 0x80000000\n}\n\n//static if (_WIN32_WINNT >= 0x500) {\n    enum : DWORD {\n        BSF_ALLOWSFW          = 0x00000080,\n        BSF_SENDNOTIFYMESSAGE = 0x00000100\n    }\n//}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum : DWORD {\n        BSF_LUID        = 0x00000400,\n        BSF_RETURNHDESK = 0x00000200\n    }\n}\n\nstruct DEV_BROADCAST_HDR {\n    DWORD dbch_size = DEV_BROADCAST_HDR.sizeof;\n    DWORD dbch_devicetype;\n    DWORD dbch_reserved;\n}\nalias DEV_BROADCAST_HDR* PDEV_BROADCAST_HDR;\n\nstruct DEV_BROADCAST_OEM {\n    DWORD dbco_size = DEV_BROADCAST_OEM.sizeof;\n    DWORD dbco_devicetype;\n    DWORD dbco_reserved;\n    DWORD dbco_identifier;\n    DWORD dbco_suppfunc;\n}\nalias DEV_BROADCAST_OEM* PDEV_BROADCAST_OEM;\n\nstruct DEV_BROADCAST_PORT_A {\n    DWORD dbcp_size = DEV_BROADCAST_PORT_A.sizeof;\n    DWORD dbcp_devicetype;\n    DWORD dbcp_reserved;\n    char  _dbcp_name;\n    char* dbcp_name() return { return &_dbcp_name; }\n}\nalias DEV_BROADCAST_PORT_A* PDEV_BROADCAST_PORT_A;\n\nstruct DEV_BROADCAST_PORT_W {\n    DWORD  dbcp_size = DEV_BROADCAST_PORT_W.sizeof;\n    DWORD  dbcp_devicetype;\n    DWORD  dbcp_reserved;\n    WCHAR  _dbcp_name;\n    WCHAR* dbcp_name() return { return &_dbcp_name; }\n}\nalias DEV_BROADCAST_PORT_W* PDEV_BROADCAST_PORT_W;\n\nstruct DEV_BROADCAST_USERDEFINED {\n    DEV_BROADCAST_HDR dbud_dbh;\n    char  _dbud_szName;\n    char* dbud_szName() return { return &_dbud_szName; }\n}\n\nstruct DEV_BROADCAST_VOLUME {\n    DWORD dbcv_size = DEV_BROADCAST_VOLUME.sizeof;\n    DWORD dbcv_devicetype;\n    DWORD dbcv_reserved;\n    DWORD dbcv_unitmask;\n    WORD  dbcv_flags;\n}\nalias DEV_BROADCAST_VOLUME* PDEV_BROADCAST_VOLUME;\n\nversion (Unicode) {\n    alias DEV_BROADCAST_PORT_W DEV_BROADCAST_PORT;\n} else {\n    alias DEV_BROADCAST_PORT_A DEV_BROADCAST_PORT;\n}\nalias DEV_BROADCAST_PORT* PDEV_BROADCAST_PORT;\n\n//static if (_WIN32_WINNT >= 0x500) {\n    struct DEV_BROADCAST_DEVICEINTERFACE_A {\n        DWORD dbcc_size = DEV_BROADCAST_DEVICEINTERFACE_A.sizeof;\n        DWORD dbcc_devicetype;\n        DWORD dbcc_reserved;\n        GUID  dbcc_classguid;\n        char  _dbcc_name;\n        char* dbcc_name() return { return &_dbcc_name; }\n    }\n    alias DEV_BROADCAST_DEVICEINTERFACE_A* PDEV_BROADCAST_DEVICEINTERFACE_A;\n\n    struct DEV_BROADCAST_DEVICEINTERFACE_W {\n        DWORD  dbcc_size = DEV_BROADCAST_DEVICEINTERFACE_W.sizeof;\n        DWORD  dbcc_devicetype;\n        DWORD  dbcc_reserved;\n        GUID   dbcc_classguid;\n        WCHAR  _dbcc_name;\n        WCHAR* dbcc_name() return { return &_dbcc_name; }\n    }\n    alias DEV_BROADCAST_DEVICEINTERFACE_W* PDEV_BROADCAST_DEVICEINTERFACE_W;\n\n    version (Unicode) {\n        alias DEV_BROADCAST_DEVICEINTERFACE_W DEV_BROADCAST_DEVICEINTERFACE;\n    } else {\n        alias DEV_BROADCAST_DEVICEINTERFACE_A DEV_BROADCAST_DEVICEINTERFACE;\n    }\n    alias DEV_BROADCAST_DEVICEINTERFACE* PDEV_BROADCAST_DEVICEINTERFACE;\n\n    struct DEV_BROADCAST_HANDLE {\n        DWORD  dbch_size = DEV_BROADCAST_HANDLE.sizeof;\n        DWORD  dbch_devicetype;\n        DWORD  dbch_reserved;\n        HANDLE dbch_handle;\n        DWORD  dbch_hdevnotify;\n        GUID   dbch_eventguid;\n        LONG   dbch_nameoffset;\n        BYTE   _dbch_data;\n        BYTE*  dbch_data() return { return &_dbch_data; }\n    }\n    alias DEV_BROADCAST_HANDLE* PDEV_BROADCAST_HANDLE;\n//}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/dde.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_dde.d)\n */\nmodule core.sys.windows.dde;\nversion (Windows):\npragma(lib, \"user32\");\n\nprivate import core.sys.windows.windef;\n\nenum : uint {\n    WM_DDE_FIRST     = 0x03E0,\n    WM_DDE_INITIATE  = WM_DDE_FIRST,\n    WM_DDE_TERMINATE,\n    WM_DDE_ADVISE,\n    WM_DDE_UNADVISE,\n    WM_DDE_ACK,\n    WM_DDE_DATA,\n    WM_DDE_REQUEST,\n    WM_DDE_POKE,\n    WM_DDE_EXECUTE,\n    WM_DDE_LAST      = WM_DDE_EXECUTE\n}\n\nstruct DDEACK {\n    ubyte bAppReturnCode;\n    ubyte _bf;\n\n    @property ubyte reserved() { return cast(ubyte) (_bf & 0x3F); }\n    @property bool  fBusy()    { return cast(bool)  (_bf & 0x40); }\n    @property bool  fAck()     { return cast(bool)  (_bf & 0x80); }\n\n    @property ubyte reserved(ubyte r) {\n        _bf = cast(ubyte) ((_bf & ~0x3F) | (r & 0x3F));\n        return cast(ubyte)(r & 0x3F);\n    }\n\n    @property bool fBusy(bool f) { _bf = cast(ubyte) ((_bf & ~0x40) | (f << 6)); return f; }\n    @property bool fAck(bool f)  { _bf = cast(ubyte) ((_bf & ~0x80) | (f << 7)); return f; }\n}\n\nstruct DDEADVISE {\n    ushort _bf;\n    short  cfFormat;\n\n    @property ushort reserved()  { return cast(ushort) (_bf & 0x3FFF); }\n    @property bool   fDeferUpd() { return cast(bool)   (_bf & 0x4000); }\n    @property bool   fAckReq()   { return cast(bool)   (_bf & 0x8000); }\n\n    @property ushort reserved(ushort r) {\n        _bf = cast(ushort) ((_bf & ~0x3FFF) | (r & 0x3FFF));\n        return cast(ushort)(r & 0x3FFF);\n    }\n\n    @property bool   fDeferUpd(bool f) { _bf = cast(ushort) ((_bf & ~0x4000) | (f << 14)); return f; }\n    @property bool   fAckReq(bool f)   { _bf = cast(ushort) ((_bf & ~0x8000) | (f << 15)); return f; }\n}\n\nstruct DDEDATA {\n    ushort _bf;\n    short  cfFormat;\n    byte   _Value;\n\n    @property ushort unused()    { return cast(ushort) (_bf & 0x0FFF); }\n    @property bool   fResponse() { return cast(bool)   (_bf & 0x1000); }\n    @property bool   fRelease()  { return cast(bool)   (_bf & 0x2000); }\n    @property bool   reserved()  { return cast(bool)   (_bf & 0x4000); }\n    @property bool   fAckReq()   { return cast(bool)   (_bf & 0x8000); }\n\n    @property byte*  Value() return { return &_Value; }\n\n    @property ushort unused(ushort r) {\n        _bf = cast(ushort) ((_bf & ~0x0FFF) | (r & 0x0FFF));\n        return cast(ushort)(r & 0x0FFF);\n    }\n\n    @property bool   fResponse(bool f) { _bf = cast(ushort) ((_bf & ~0x1000) | (f << 12)); return f; }\n    @property bool   fRelease(bool f)  { _bf = cast(ushort) ((_bf & ~0x2000) | (f << 13)); return f; }\n    @property bool   reserved(bool f)  { _bf = cast(ushort) ((_bf & ~0x4000) | (f << 14)); return f; }\n    @property bool   fAckReq(bool f)   { _bf = cast(ushort) ((_bf & ~0x8000) | (f << 15)); return f; }\n}\n\nstruct DDEPOKE {\n    ushort _bf;\n    short  cfFormat;\n    byte   _Value;\n\n    @property ushort unused()    { return cast(ushort) (_bf & 0x1FFF); }\n    @property bool   fRelease()  { return cast(bool)   (_bf & 0x2000); }\n    @property ubyte  fReserved() { return cast(ubyte)  ((_bf & 0xC000) >>> 14); }\n\n    @property byte*  Value() return { return &_Value; }\n\n    @property ushort unused(ushort u) {\n        _bf = cast(ushort) ((_bf & ~0x1FFF) | (u & 0x1FFF));\n        return cast(ushort)(u & 0x1FFF);\n    }\n\n    @property bool   fRelease(bool f)   { _bf = cast(ushort) ((_bf & ~0x2000) | (f << 13)); return f; }\n    @property ubyte  fReserved(ubyte r) { _bf = cast(ushort) ((_bf & ~0xC000) | (r << 14)); return r; }\n}\n\ndeprecated struct DDELN {\n    ushort _bf;\n    short  cfFormat;\n\n    @property ushort unused()    { return cast(ushort) (_bf & 0x1FFF); }\n    @property bool   fRelease()  { return cast(bool)   (_bf & 0x2000); }\n    @property bool   fDeferUpd() { return cast(bool)   (_bf & 0x4000); }\n    @property bool   fAckReq()   { return cast(bool)   (_bf & 0x8000); }\n\n    @property ushort unused(ushort u) {\n        _bf = cast(ushort)((_bf & ~0x1FFF) | (u & 0x1FFF));\n        return cast(ushort)(u & 0x1FFF);\n    }\n\n    @property bool   fRelease(bool f)  { _bf = cast(ushort) ((_bf & ~0x2000) | (f << 13)); return f; }\n    @property bool   fDeferUpd(bool f) { _bf = cast(ushort) ((_bf & ~0x4000) | (f << 14)); return f; }\n    @property bool   fAckReq(bool f)   { _bf = cast(ushort) ((_bf & ~0x8000) | (f << 15)); return f; }\n}\n\ndeprecated struct DDEUP {\n    ushort _bf;\n    short  cfFormat;\n    byte   _rgb;\n\n    @property ushort unused()    { return cast(ushort) (_bf & 0x0FFF); }\n    @property bool   fAck()      { return cast(bool)   (_bf & 0x1000); }\n    @property bool   fRelease()  { return cast(bool)   (_bf & 0x2000); }\n    @property bool   fReserved() { return cast(bool)   (_bf & 0x4000); }\n    @property bool   fAckReq()   { return cast(bool)   (_bf & 0x8000); }\n\n    @property byte*  rgb() return { return &_rgb; }\n\n    @property ushort unused(ushort r) {\n        _bf = cast(ushort) ((_bf & ~0x0FFF) | (r & 0x0FFF));\n        return cast(ushort)(r & 0x0FFF);\n    }\n\n    @property bool   fAck(bool f)      { _bf = cast(ushort) ((_bf & ~0x1000) | (f << 12)); return f; }\n    @property bool   fRelease(bool f)  { _bf = cast(ushort) ((_bf & ~0x2000) | (f << 13)); return f; }\n    @property bool   fReserved(bool f) { _bf = cast(ushort) ((_bf & ~0x4000) | (f << 14)); return f; }\n    @property bool   fAckReq(bool f)   { _bf = cast(ushort) ((_bf & ~0x8000) | (f << 15)); return f; }\n}\n\nextern (Windows) {\n    BOOL DdeSetQualityOfService(HWND, const(SECURITY_QUALITY_OF_SERVICE)*,\n      PSECURITY_QUALITY_OF_SERVICE);\n    BOOL ImpersonateDdeClientWindow(HWND, HWND);\n    LPARAM PackDDElParam(UINT, UINT_PTR, UINT_PTR);\n    BOOL UnpackDDElParam(UINT, LPARAM, PUINT_PTR, PUINT_PTR);\n    BOOL FreeDDElParam(UINT, LPARAM);\n    LPARAM ReuseDDElParam(LPARAM, UINT, UINT, UINT_PTR, UINT_PTR);\n}\n\ndebug (WindowsUnitTest) {\n    unittest {\n        DDEACK ddeack;\n\n        with (ddeack) {\n            reserved = 10;\n            assert (_bf == 0x0A);\n            fBusy = true;\n            assert (_bf == 0x4A);\n            fAck = true;\n            assert (_bf == 0xCA);\n\n            assert (reserved == 10);\n            assert (fBusy == true);\n            assert (fAck == true);\n\n            reserved = 43;\n            assert (_bf == 0xEB);\n            fBusy = false;\n            assert (_bf == 0xAB);\n            fAck = false;\n            assert (_bf == 0x2B);\n\n            assert (reserved == 43);\n            assert (fBusy == false);\n            assert (fAck == false);\n        }\n\n        DDEPOKE ddepoke;\n\n        with (ddepoke) {\n            unused = 3456;\n            assert (_bf == 0x0D80);\n            fRelease = true;\n            assert (_bf == 0x2D80);\n            fReserved = 2;\n            assert (_bf == 0xAD80);\n\n            assert (unused == 3456);\n            assert (fRelease == true);\n            assert (fReserved == 2);\n\n            unused = 2109;\n            assert (_bf == 0xa83d);\n            fRelease = false;\n            assert (_bf == 0x883d);\n            fReserved = 1;\n            assert (_bf == 0x483d);\n\n            assert (unused == 2109);\n            assert (fRelease == false);\n            assert (fReserved == 1);\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ddeml.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ddeml.d)\n */\nmodule core.sys.windows.ddeml;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"user32\");\n\nprivate import core.sys.windows.basetsd, core.sys.windows.windef, core.sys.windows.winnt;\n\nenum : int {\n    CP_WINANSI    = 1004,\n    CP_WINUNICODE = 1200\n}\n\nenum : UINT {\n    XTYPF_NOBLOCK = 2,\n    XTYPF_NODATA  = 4,\n    XTYPF_ACKREQ  = 8\n}\n\nenum : UINT {\n    XCLASS_MASK         = 0xFC00,\n    XCLASS_BOOL         = 0x1000,\n    XCLASS_DATA         = 0x2000,\n    XCLASS_FLAGS        = 0x4000,\n    XCLASS_NOTIFICATION = 0x8000\n}\n\nenum : UINT {\n    XST_NULL,\n    XST_INCOMPLETE,\n    XST_CONNECTED,\n    XST_INIT1,\n    XST_INIT2,\n    XST_REQSENT,\n    XST_DATARCVD,\n    XST_POKESENT,\n    XST_POKEACKRCVD,\n    XST_EXECSENT,\n    XST_EXECACKRCVD,\n    XST_ADVSENT,\n    XST_UNADVSENT,\n    XST_ADVACKRCVD,\n    XST_UNADVACKRCVD,\n    XST_ADVDATASENT,\n    XST_ADVDATAACKRCVD // = 16\n}\n\nenum : UINT {\n    XTYP_ERROR           = XCLASS_NOTIFICATION | XTYPF_NOBLOCK,\n    XTYP_ADVDATA         = 0x0010 | XCLASS_FLAGS,\n    XTYP_ADVREQ          = 0x0020 | XCLASS_DATA | XTYPF_NOBLOCK,\n    XTYP_ADVSTART        = 0x0030 | XCLASS_BOOL,\n    XTYP_ADVSTOP         = 0x0040 | XCLASS_NOTIFICATION,\n    XTYP_EXECUTE         = 0x0050 | XCLASS_FLAGS,\n    XTYP_CONNECT         = 0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK,\n    XTYP_CONNECT_CONFIRM = 0x0070 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK,\n    XTYP_XACT_COMPLETE   = 0x0080 | XCLASS_NOTIFICATION,\n    XTYP_POKE            = 0x0090 | XCLASS_FLAGS,\n    XTYP_REGISTER        = 0x00A0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK,\n    XTYP_REQUEST         = 0x00B0 | XCLASS_DATA,\n    XTYP_DISCONNECT      = 0x00C0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK,\n    XTYP_UNREGISTER      = 0x00D0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK,\n    XTYP_WILDCONNECT     = 0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK,\n    XTYP_MONITOR         = 0X00F0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK,\n    XTYP_MASK            = 0x00F0,\n    XTYP_SHIFT           = 4\n}\n\n/+\n#define TIMEOUT_ASYNC  0xFFFFFFFF\n#define QID_SYNC       0xFFFFFFFF\n+/\n\nenum : UINT {\n    ST_CONNECTED  =   1,\n    ST_ADVISE     =   2,\n    ST_ISLOCAL    =   4,\n    ST_BLOCKED    =   8,\n    ST_CLIENT     =  16,\n    ST_TERMINATED =  32,\n    ST_INLIST     =  64,\n    ST_BLOCKNEXT  = 128,\n    ST_ISSELF     = 256\n}\n\n/+\n#define CADV_LATEACK 0xFFFF\n+/\n\nenum : UINT {\n    DMLERR_NO_ERROR      = 0,\n    DMLERR_FIRST         = 0x4000,\n    DMLERR_ADVACKTIMEOUT = DMLERR_FIRST,\n    DMLERR_BUSY,\n    DMLERR_DATAACKTIMEOUT,\n    DMLERR_DLL_NOT_INITIALIZED,\n    DMLERR_DLL_USAGE,\n    DMLERR_EXECACKTIMEOUT,\n    DMLERR_INVALIDPARAMETER,\n    DMLERR_LOW_MEMORY,\n    DMLERR_MEMORY_ERROR,\n    DMLERR_NOTPROCESSED,\n    DMLERR_NO_CONV_ESTABLISHED,\n    DMLERR_POKEACKTIMEOUT,\n    DMLERR_POSTMSG_FAILED,\n    DMLERR_REENTRANCY,\n    DMLERR_SERVER_DIED,\n    DMLERR_SYS_ERROR,\n    DMLERR_UNADVACKTIMEOUT,\n    DMLERR_UNFOUND_QUEUE_ID, // = 0x4011\n    DMLERR_LAST          = DMLERR_UNFOUND_QUEUE_ID\n}\n\n/+\n#define DDE_FACK    0x8000\n#define DDE_FBUSY   0x4000\n#define DDE_FDEFERUPD   0x4000\n#define DDE_FACKREQ 0x8000\n#define DDE_FRELEASE    0x2000\n#define DDE_FREQUESTED  0x1000\n#define DDE_FAPPSTATUS  0x00ff\n#define DDE_FNOTPROCESSED   0\n#define DDE_FACKRESERVED    (~(DDE_FACK|DDE_FBUSY|DDE_FAPPSTATUS))\n#define DDE_FADVRESERVED    (~(DDE_FACKREQ|DDE_FDEFERUPD))\n#define DDE_FDATRESERVED    (~(DDE_FACKREQ|DDE_FRELEASE|DDE_FREQUESTED))\n#define DDE_FPOKRESERVED    (~DDE_FRELEASE)\n#define MSGF_DDEMGR 0x8001\n#define CBR_BLOCK   ((HDDEDATA)0xffffffff)\n+/\n\nenum DWORD\n    APPCLASS_STANDARD         = 0,\n    APPCLASS_MONITOR          = 0x00000001,\n    APPCLASS_MASK             = 0x0000000F,\n    APPCMD_CLIENTONLY         = 0x00000010,\n    APPCMD_FILTERINITS        = 0x00000020,\n    APPCMD_MASK               = 0x00000FF0,\n    CBF_FAIL_SELFCONNECTIONS  = 0x00001000,\n    CBF_FAIL_CONNECTIONS      = 0x00002000,\n    CBF_FAIL_ADVISES          = 0x00004000,\n    CBF_FAIL_EXECUTES         = 0x00008000,\n    CBF_FAIL_POKES            = 0x00010000,\n    CBF_FAIL_REQUESTS         = 0x00020000,\n    CBF_FAIL_ALLSVRXACTIONS   = 0x0003f000,\n    CBF_SKIP_CONNECT_CONFIRMS = 0x00040000,\n    CBF_SKIP_REGISTRATIONS    = 0x00080000,\n    CBF_SKIP_UNREGISTRATIONS  = 0x00100000,\n    CBF_SKIP_DISCONNECTS      = 0x00200000,\n    CBF_SKIP_ALLNOTIFICATIONS = 0x003c0000,\n    MF_HSZ_INFO               = 0x01000000,\n    MF_SENDMSGS               = 0x02000000,\n    MF_POSTMSGS               = 0x04000000,\n    MF_CALLBACKS              = 0x08000000,\n    MF_ERRORS                 = 0x10000000,\n    MF_LINKS                  = 0x20000000,\n    MF_CONV                   = 0x40000000,\n    MF_MASK                   = 0xFF000000;\n\nenum : UINT {\n    EC_ENABLEALL    = 0,\n    EC_ENABLEONE    = ST_BLOCKNEXT,\n    EC_DISABLE      = ST_BLOCKED,\n    EC_QUERYWAITING = 2\n}\n\nenum : UINT {\n    DNS_REGISTER   = 1,\n    DNS_UNREGISTER = 2,\n    DNS_FILTERON   = 4,\n    DNS_FILTEROFF  = 8\n}\n\n/+\n#define HDATA_APPOWNED  1\n#define MAX_MONITORS    4\n+/\n\nenum : int {\n    MH_CREATE  = 1,\n    MH_KEEP    = 2,\n    MH_DELETE  = 3,\n    MH_CLEANUP = 4\n}\n\nmixin DECLARE_HANDLE!(\"HCONVLIST\");\nmixin DECLARE_HANDLE!(\"HCONV\");\nmixin DECLARE_HANDLE!(\"HSZ\");\nmixin DECLARE_HANDLE!(\"HDDEDATA\");\n\nextern (Windows) alias HDDEDATA\n  function(UINT, UINT, HCONV, HSZ, HSZ, HDDEDATA, ULONG_PTR, ULONG_PTR) PFNCALLBACK;\n\nstruct HSZPAIR {\n    HSZ hszSvc;\n    HSZ hszTopic;\n}\nalias HSZPAIR* PHSZPAIR;\n\nstruct CONVCONTEXT {\n    UINT                        cb = CONVCONTEXT.sizeof;\n    UINT                        wFlags;\n    UINT                        wCountryID;\n    int                         iCodePage;\n    DWORD                       dwLangID;\n    DWORD                       dwSecurity;\n    SECURITY_QUALITY_OF_SERVICE qos;\n}\nalias CONVCONTEXT* PCONVCONTEXT;\n\nstruct CONVINFO {\n    DWORD       cb = CONVINFO.sizeof;\n    DWORD_PTR   hUser;\n    HCONV       hConvPartner;\n    HSZ         hszSvcPartner;\n    HSZ         hszServiceReq;\n    HSZ         hszTopic;\n    HSZ         hszItem;\n    UINT        wFmt;\n    UINT        wType;\n    UINT        wStatus;\n    UINT        wConvst;\n    UINT        wLastError;\n    HCONVLIST   hConvList;\n    CONVCONTEXT ConvCtxt;\n    HWND        hwnd;\n    HWND        hwndPartner;\n}\nalias CONVINFO* PCONVINFO;\n\nstruct DDEML_MSG_HOOK_DATA {\n    UINT_PTR uiLo;\n    UINT_PTR uiHi;\n    DWORD    cbData;\n    DWORD[8] Data;\n}\n\nstruct MONHSZSTRUCT {\n    UINT     cb = MONHSZSTRUCT.sizeof;\n    int      fsAction;\n    DWORD    dwTime;\n    HSZ      hsz;\n    HANDLE   hTask;\n    TCHAR[1] _str;\n\n    TCHAR* str() return { return _str.ptr; }\n}\nalias MONHSZSTRUCT* PMONHSZSTRUCT;\n\nstruct MONLINKSTRUCT {\n    UINT   cb = MONLINKSTRUCT.sizeof;\n    DWORD  dwTime;\n    HANDLE hTask;\n    BOOL   fEstablished;\n    BOOL   fNoData;\n    HSZ    hszSvc;\n    HSZ    hszTopic;\n    HSZ    hszItem;\n    UINT   wFmt;\n    BOOL   fServer;\n    HCONV  hConvServer;\n    HCONV  hConvClient;\n}\nalias MONLINKSTRUCT* PMONLINKSTRUCT;\n\nstruct MONCONVSTRUCT {\n    UINT   cb = MONCONVSTRUCT.sizeof;\n    BOOL   fConnect;\n    DWORD  dwTime;\n    HANDLE hTask;\n    HSZ    hszSvc;\n    HSZ    hszTopic;\n    HCONV  hConvClient;\n    HCONV  hConvServer;\n}\nalias MONCONVSTRUCT* PMONCONVSTRUCT;\n\nstruct MONCBSTRUCT {\n    UINT        cb = MONCBSTRUCT.sizeof;\n    DWORD       dwTime;\n    HANDLE      hTask;\n    DWORD       dwRet;\n    UINT        wType;\n    UINT        wFmt;\n    HCONV       hConv;\n    HSZ         hsz1;\n    HSZ         hsz2;\n    HDDEDATA    hData;\n    ULONG_PTR   dwData1;\n    ULONG_PTR   dwData2;\n    CONVCONTEXT cc;\n    DWORD       cbData;\n    DWORD[8]    Data;\n}\nalias MONCBSTRUCT* PMONCBSTRUCT;\n\nstruct MONERRSTRUCT {\n    UINT   cb = MONERRSTRUCT.sizeof;\n    UINT   wLastError;\n    DWORD  dwTime;\n    HANDLE hTask;\n}\nalias MONERRSTRUCT* PMONERRSTRUCT;\n\nstruct MONMSGSTRUCT {\n    UINT   cb = MONMSGSTRUCT.sizeof;\n    HWND   hwndTo;\n    DWORD  dwTime;\n    HANDLE hTask;\n    UINT   wMsg;\n    WPARAM wParam;\n    LPARAM lParam;\n    DDEML_MSG_HOOK_DATA dmhd;\n}\nalias MONMSGSTRUCT* PMONMSGSTRUCT;\n\nextern (Windows) {\n    BOOL DdeAbandonTransaction(DWORD, HCONV, DWORD);\n    PBYTE DdeAccessData(HDDEDATA, PDWORD);\n    HDDEDATA DdeAddData(HDDEDATA, PBYTE, DWORD, DWORD);\n    HDDEDATA DdeClientTransaction(PBYTE, DWORD, HCONV, HSZ, UINT, UINT,\n      DWORD, PDWORD);\n    int DdeCmpStringHandles(HSZ, HSZ);\n    HCONV DdeConnect(DWORD, HSZ, HSZ, PCONVCONTEXT);\n    HCONVLIST DdeConnectList(DWORD, HSZ, HSZ, HCONVLIST, PCONVCONTEXT);\n    HDDEDATA DdeCreateDataHandle(DWORD, PBYTE, DWORD, DWORD, HSZ, UINT,\n      UINT);\n    HSZ DdeCreateStringHandleA(DWORD, LPSTR, int);\n    HSZ DdeCreateStringHandleW(DWORD, LPWSTR, int);\n    BOOL DdeDisconnect(HCONV);\n    BOOL DdeDisconnectList(HCONVLIST);\n    BOOL DdeEnableCallback(DWORD, HCONV, UINT);\n    BOOL DdeFreeDataHandle(HDDEDATA);\n    BOOL DdeFreeStringHandle(DWORD, HSZ);\n    DWORD DdeGetData(HDDEDATA, PBYTE, DWORD, DWORD);\n    UINT DdeGetLastError(DWORD);\n    BOOL DdeImpersonateClient(HCONV);\n    UINT DdeInitializeA(PDWORD, PFNCALLBACK, DWORD, DWORD);\n    UINT DdeInitializeW(PDWORD, PFNCALLBACK, DWORD, DWORD);\n    BOOL DdeKeepStringHandle(DWORD, HSZ);\n    HDDEDATA DdeNameService(DWORD, HSZ, HSZ, UINT);\n    BOOL DdePostAdvise(DWORD, HSZ, HSZ);\n    UINT DdeQueryConvInfo(HCONV, DWORD, PCONVINFO);\n    HCONV DdeQueryNextServer(HCONVLIST, HCONV);\n    DWORD DdeQueryStringA(DWORD, HSZ, LPSTR, DWORD, int);\n    DWORD DdeQueryStringW(DWORD, HSZ, LPWSTR, DWORD, int);\n    HCONV DdeReconnect(HCONV);\n    BOOL DdeSetUserHandle(HCONV, DWORD, DWORD_PTR);\n    BOOL DdeUnaccessData(HDDEDATA);\n    BOOL DdeUninitialize(DWORD);\n}\n\nconst TCHAR[]\n    SZDDESYS_TOPIC         = \"System\",\n    SZDDESYS_ITEM_TOPICS   = \"Topics\",\n    SZDDESYS_ITEM_SYSITEMS = \"SysItems\",\n    SZDDESYS_ITEM_RTNMSG   = \"ReturnMessage\",\n    SZDDESYS_ITEM_STATUS   = \"Status\",\n    SZDDESYS_ITEM_FORMATS  = \"Formats\",\n    SZDDESYS_ITEM_HELP     = \"Help\",\n    SZDDE_ITEM_ITEMLIST    = \"TopicItemList\";\n\nversion (Unicode) {\n    alias DdeCreateStringHandleW DdeCreateStringHandle;\n    alias DdeInitializeW DdeInitialize;\n    alias DdeQueryStringW DdeQueryString;\n} else {\n    alias DdeCreateStringHandleA DdeCreateStringHandle;\n    alias DdeInitializeA DdeInitialize;\n    alias DdeQueryStringA DdeQueryString;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/dhcpcsdk.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_dhcpcsdk.d)\n */\nmodule core.sys.windows.dhcpcsdk;\nversion (Windows):\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef;\n\n/*static assert (_WIN32_WINNT >= 0x500,\n\"core.sys.windows.dhcpcsdk is available only if version Windows2000, WindowsXP, Windows2003\nor WindowsVista is set\");*/\n\n//#if (_WIN32_WINNT >= 0x500)\n\n// FIXME: check type\nenum DHCPCAPI_REGISTER_HANDLE_EVENT = 1;\nenum DHCPCAPI_REQUEST_PERSISTENT    = 1;\nenum DHCPCAPI_REQUEST_SYNCHRONOUS   = 2;\n\nstruct DHCPCAPI_CLASSID {\n    ULONG  Flags;\n    LPBYTE Data;\n    ULONG  nBytesData;\n}\nalias DHCPCAPI_CLASSID* PDHCPCAPI_CLASSID, LPDHCPCAPI_CLASSID;\n\nstruct DHCPAPI_PARAMS {\n    ULONG  Flags;\n    ULONG  OptionId;\n    BOOL   IsVendor;\n    LPBYTE Data;\n    DWORD  nBytesData;\n}\nalias DHCPAPI_PARAMS* PDHCPAPI_PARAMS, LPDHCPAPI_PARAMS;\n\nstruct DHCPCAPI_PARAMS_ARRAY {\n    ULONG            nParams;\n    LPDHCPAPI_PARAMS Params;\n}\nalias DHCPCAPI_PARAMS_ARRAY* PDHCPCAPI_PARAMS_ARRAY, LPDHCPCAPI_PARAMS_ARRAY;\n\nextern (Windows) {\n    void DhcpCApiCleanup();\n    DWORD DhcpCApiInitialize(LPDWORD);\n    DWORD DhcpDeRegisterParamChange(DWORD, LPVOID, LPVOID);\n    DWORD DhcpRegisterParamChange(DWORD, LPVOID, PWSTR, LPDHCPCAPI_CLASSID,\n      DHCPCAPI_PARAMS_ARRAY, LPVOID);\n    DWORD DhcpRemoveDNSRegistrations();\n    DWORD DhcpUndoRequestParams(DWORD, LPVOID, LPWSTR, LPWSTR);\n}\n\n//#endif // (_WIN32_WINNT >= 0x500)\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/dlgs.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_dlgs.d)\n */\nmodule core.sys.windows.dlgs;\nversion (Windows):\n\nprivate import core.sys.windows.windef;\n\nenum : ushort {\n    FILEOPENORD      = 1536,\n    MULTIFILEOPENORD = 1537,\n    PRINTDLGORD      = 1538,\n    PRNSETUPDLGORD   = 1539,\n    FINDDLGORD       = 1540,\n    REPLACEDLGORD    = 1541,\n    FONTDLGORD       = 1542,\n    FORMATDLGORD31   = 1543,\n    FORMATDLGORD30   = 1544,\n    PAGESETUPDLGORD  = 1546\n}\n\nenum : int {\n    ctlFirst = 0x400,\n    ctlLast  = 0x4ff,\n    chx1     = 0x410,\n    chx2     = 0x411,\n    chx3     = 0x412,\n    chx4     = 0x413,\n    chx5     = 0x414,\n    chx6     = 0x415,\n    chx7     = 0x416,\n    chx8     = 0x417,\n    chx9     = 0x418,\n    chx10    = 0x419,\n    chx11    = 0x41a,\n    chx12    = 0x41b,\n    chx13    = 0x41c,\n    chx14    = 0x41d,\n    chx15    = 0x41e,\n    chx16    = 0x41f,\n    cmb1     = 0x470,\n    cmb2     = 0x471,\n    cmb3     = 0x472,\n    cmb4     = 0x473,\n    cmb5     = 0x474,\n    cmb6     = 0x475,\n    cmb7     = 0x476,\n    cmb8     = 0x477,\n    cmb9     = 0x478,\n    cmb10    = 0x479,\n    cmb11    = 0x47a,\n    cmb12    = 0x47b,\n    cmb13    = 0x47c,\n    cmb14    = 0x47d,\n    cmb15    = 0x47e,\n    cmb16    = 0x47f,\n    edt1     = 0x480,\n    edt2     = 0x481,\n    edt3     = 0x482,\n    edt4     = 0x483,\n    edt5     = 0x484,\n    edt6     = 0x485,\n    edt7     = 0x486,\n    edt8     = 0x487,\n    edt9     = 0x488,\n    edt10    = 0x489,\n    edt11    = 0x48a,\n    edt12    = 0x48b,\n    edt13    = 0x48c,\n    edt14    = 0x48d,\n    edt15    = 0x48e,\n    edt16    = 0x48f,\n    frm1     = 0x434,\n    frm2     = 0x435,\n    frm3     = 0x436,\n    frm4     = 0x437,\n    grp1     = 0x430,\n    grp2     = 0x431,\n    grp3     = 0x432,\n    grp4     = 0x433,\n    ico1     = 0x43c,\n    ico2     = 0x43d,\n    ico3     = 0x43e,\n    ico4     = 0x43f,\n    lst1     = 0x460,\n    lst2     = 0x461,\n    lst3     = 0x462,\n    lst4     = 0x463,\n    lst5     = 0x464,\n    lst6     = 0x465,\n    lst7     = 0x466,\n    lst8     = 0x467,\n    lst9     = 0x468,\n    lst10    = 0x469,\n    lst11    = 0x46a,\n    lst12    = 0x46b,\n    lst13    = 0x46c,\n    lst14    = 0x46d,\n    lst15    = 0x46e,\n    lst16    = 0x46f,\n    psh1     = 0x400,\n    psh2     = 0x401,\n    psh3     = 0x402,\n    psh4     = 0x403,\n    psh5     = 0x404,\n    psh6     = 0x405,\n    psh7     = 0x406,\n    psh8     = 0x407,\n    psh9     = 0x408,\n    psh10    = 0x409,\n    psh11    = 0x40a,\n    psh12    = 0x40b,\n    psh13    = 0x40c,\n    psh14    = 0x40d,\n    psh15    = 0x40e,\n    pshHelp  = 0x40e,\n    psh16    = 0x40f,\n    rad1     = 0x420,\n    rad2     = 0x421,\n    rad3     = 0x422,\n    rad4     = 0x423,\n    rad5     = 0x424,\n    rad6     = 0x425,\n    rad7     = 0x426,\n    rad8     = 0x427,\n    rad9     = 0x428,\n    rad10    = 0x429,\n    rad11    = 0x42a,\n    rad12    = 0x42b,\n    rad13    = 0x42c,\n    rad14    = 0x42d,\n    rad15    = 0x42e,\n    rad16    = 0x42f,\n    rct1     = 0x438,\n    rct2     = 0x439,\n    rct3     = 0x43a,\n    rct4     = 0x43b,\n    scr1     = 0x490,\n    scr2     = 0x491,\n    scr3     = 0x492,\n    scr4     = 0x493,\n    scr5     = 0x494,\n    scr6     = 0x495,\n    scr7     = 0x496,\n    scr8     = 0x497,\n    stc1     = 0x440,\n    stc2     = 0x441,\n    stc3     = 0x442,\n    stc4     = 0x443,\n    stc5     = 0x444,\n    stc6     = 0x445,\n    stc7     = 0x446,\n    stc8     = 0x447,\n    stc9     = 0x448,\n    stc10    = 0x449,\n    stc11    = 0x44a,\n    stc12    = 0x44b,\n    stc13    = 0x44c,\n    stc14    = 0x44d,\n    stc15    = 0x44e,\n    stc16    = 0x44f,\n    stc17    = 0x450,\n    stc18    = 0x451,\n    stc19    = 0x452,\n    stc20    = 0x453,\n    stc21    = 0x454,\n    stc22    = 0x455,\n    stc23    = 0x456,\n    stc24    = 0x457,\n    stc25    = 0x458,\n    stc26    = 0x459,\n    stc27    = 0x45a,\n    stc28    = 0x45b,\n    stc29    = 0x45c,\n    stc30    = 0x45d,\n    stc31    = 0x45e,\n    stc32    = 0x45f\n}\n\nstruct CRGB {\n    ubyte bRed;\n    ubyte bGreen;\n    ubyte bBlue;\n    ubyte bExtra;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/dll.d",
    "content": "/**\n * This module provides OS specific helper function for DLL support\n *\n * Copyright: Copyright Digital Mars 2010 - 2012.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Rainer Schuetze\n * Source: $(DRUNTIMESRC src/core/sys/windows/_dll.d)\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule core.sys.windows.dll;\nversion (Windows):\n\nimport core.sys.windows.windows;\nimport core.stdc.string;\nimport core.runtime;\n\npublic import core.sys.windows.threadaux;\n\n///////////////////////////////////////////////////////////////////\n// support fixing implicit TLS for dynamically loaded DLLs on Windows XP\n\n// in this special case, we have to treat _tlsstart and _tlsend as non-TLS variables\n//  as they are used to simulate TLS when it is not set up under XP. In this case we must\n//  not access tls_array[tls_index] as needed for thread local _tlsstart and _tlsend\nextern (C)\n{\n        version (MinGW)\n        {\n            extern __gshared void* _tls_start;\n            extern __gshared void* _tls_end;\n            extern __gshared void* __xl_a;\n\n            alias _tls_start _tlsstart;\n            alias _tls_end   _tlsend;\n            alias __xl_a     _tls_callbacks_a;\n        }\n        else version (Win32)\n    {\n        version (CRuntime_DigitalMars)\n        {\n            extern __gshared byte  _tlsstart;\n            extern __gshared byte  _tlsend;\n            extern __gshared void* _tls_callbacks_a;\n        }\n        else version (CRuntime_Microsoft)\n        {\n            extern __gshared byte  _tls_start;\n            extern __gshared byte  _tls_end;\n            extern __gshared void*  __xl_a;\n            alias _tls_start _tlsstart;\n            alias _tls_end   _tlsend;\n            alias __xl_a     _tls_callbacks_a;\n        }\n        extern __gshared int   _tls_index;\n    }\n}\n\nextern (C) // rt.minfo\n{\n    void rt_moduleTlsCtor();\n    void rt_moduleTlsDtor();\n}\n\nprivate:\nversion (Win32)\n{\nstruct dll_aux\n{\n    // don't let symbols leak into other modules\n    struct LdrpTlsListEntry\n    {\n        LdrpTlsListEntry* next;\n        LdrpTlsListEntry* prev;\n        void* tlsstart;\n        void* tlsend;\n        void* ptr_tlsindex;\n        void* callbacks;\n        void* zerofill;\n        int   tlsindex;\n    }\n\n    alias fnRtlAllocateHeap = extern(Windows)\n    void* function(void* HeapHandle, uint Flags, size_t Size) nothrow;\n\n    // find a code sequence and return the address after the sequence\n    static void* findCodeSequence( void* adr, int len, ref ubyte[] pattern ) nothrow\n    {\n        if ( !adr )\n            return null;\n\n        ubyte* code = cast(ubyte*) adr;\n        for ( int p = 0; p < len; p++ )\n        {\n            if ( code[ p .. p + pattern.length ] == pattern[ 0 .. $ ] )\n            {\n                ubyte* padr = code + p + pattern.length;\n                return padr;\n            }\n        }\n        return null;\n    }\n\n    // find a code sequence and return the (relative) address that follows\n    static void* findCodeReference( void* adr, int len, ref ubyte[] pattern, bool relative ) nothrow\n    {\n        if ( !adr )\n            return null;\n\n        ubyte* padr = cast(ubyte*) findCodeSequence( adr, len, pattern );\n        if ( padr )\n        {\n            if ( relative )\n                return padr + 4 + *cast(int*) padr;\n            return *cast(void**) padr;\n        }\n        return null;\n    }\n\n    // crawl through ntdll to find function _LdrpAllocateTls@0 and references\n    //  to _LdrpNumberOfTlsEntries, _NtdllBaseTag and _LdrpTlsList\n    // LdrInitializeThunk\n    // -> _LdrpInitialize@12\n    // -> _LdrpInitializeThread@4\n    // -> _LdrpAllocateTls@0\n    // -> je chunk\n    //     _LdrpNumberOfTlsEntries - number of entries in TlsList\n    //     _NtdllBaseTag           - tag used for RtlAllocateHeap\n    //     _LdrpTlsList            - root of the double linked list with TlsList entries\n\n    static __gshared int* pNtdllBaseTag; // remembered for reusage in addTlsData\n\n    static __gshared ubyte[] jmp_LdrpInitialize = [ 0x33, 0xED, 0xE9 ]; // xor ebp,ebp; jmp _LdrpInitialize\n    static __gshared ubyte[] jmp__LdrpInitialize = [ 0x5D, 0xE9 ]; // pop ebp; jmp __LdrpInitialize\n    static __gshared ubyte[] jmp__LdrpInitialize_xp64 = [ 0x5D, 0x90, 0x90, 0x90, 0x90, 0x90 ]; // pop ebp; nop; nop; nop; nop; nop;\n    static __gshared ubyte[] call_LdrpInitializeThread = [ 0xFF, 0x75, 0x08, 0xE8 ]; // push [ebp+8]; call _LdrpInitializeThread\n    static __gshared ubyte[] call_LdrpAllocateTls = [ 0x00, 0x00, 0xE8 ]; // jne 0xc3; call _LdrpAllocateTls\n    static __gshared ubyte[] call_LdrpAllocateTls_svr03 = [ 0x65, 0xfc, 0x00, 0xE8 ]; // and [ebp+fc], 0; call _LdrpAllocateTls\n    static __gshared ubyte[] jne_LdrpAllocateTls = [ 0x0f, 0x85 ]; // jne body_LdrpAllocateTls\n    static __gshared ubyte[] mov_LdrpNumberOfTlsEntries = [ 0x8B, 0x0D ]; // mov ecx, _LdrpNumberOfTlsEntries\n    static __gshared ubyte[] mov_NtdllBaseTag = [ 0x51, 0x8B, 0x0D ]; // push ecx; mov ecx, _NtdllBaseTag\n    static __gshared ubyte[] mov_NtdllBaseTag_srv03 = [ 0x50, 0xA1 ]; // push eax; mov eax, _NtdllBaseTag\n    static __gshared ubyte[] mov_LdrpTlsList = [ 0x8B, 0x3D ]; // mov edi, _LdrpTlsList\n\n    static LdrpTlsListEntry* addTlsListEntry( void** peb, void* tlsstart, void* tlsend, void* tls_callbacks_a, int* tlsindex ) nothrow\n    {\n        HANDLE hnd = GetModuleHandleA( \"NTDLL\" );\n        assert( hnd, \"cannot get module handle for ntdll\" );\n        ubyte* fn = cast(ubyte*) GetProcAddress( hnd, \"LdrInitializeThunk\" );\n        assert( fn, \"cannot find LdrInitializeThunk in ntdll\" );\n\n        void* pLdrpInitialize = findCodeReference( fn, 20, jmp_LdrpInitialize, true );\n        void* p_LdrpInitialize = findCodeReference( pLdrpInitialize, 40, jmp__LdrpInitialize, true );\n        if ( !p_LdrpInitialize )\n            p_LdrpInitialize = findCodeSequence( pLdrpInitialize, 40, jmp__LdrpInitialize_xp64 );\n        void* pLdrpInitializeThread = findCodeReference( p_LdrpInitialize, 200, call_LdrpInitializeThread, true );\n        void* pLdrpAllocateTls = findCodeReference( pLdrpInitializeThread, 40, call_LdrpAllocateTls, true );\n        if (!pLdrpAllocateTls)\n            pLdrpAllocateTls = findCodeReference( pLdrpInitializeThread, 100, call_LdrpAllocateTls_svr03, true );\n        void* pBodyAllocateTls = findCodeReference( pLdrpAllocateTls, 40, jne_LdrpAllocateTls, true );\n\n        int* pLdrpNumberOfTlsEntries = cast(int*) findCodeReference( pBodyAllocateTls, 60, mov_LdrpNumberOfTlsEntries, false );\n        pNtdllBaseTag = cast(int*) findCodeReference( pBodyAllocateTls, 30, mov_NtdllBaseTag, false );\n        if (!pNtdllBaseTag)\n            pNtdllBaseTag = cast(int*) findCodeReference( pBodyAllocateTls, 30, mov_NtdllBaseTag_srv03, false );\n        LdrpTlsListEntry* pLdrpTlsList = cast(LdrpTlsListEntry*)findCodeReference( pBodyAllocateTls, 80, mov_LdrpTlsList, false );\n\n        if ( !pLdrpNumberOfTlsEntries || !pNtdllBaseTag || !pLdrpTlsList )\n            return null;\n\n        fnRtlAllocateHeap fnAlloc = cast(fnRtlAllocateHeap) GetProcAddress( hnd, \"RtlAllocateHeap\" );\n        if ( !fnAlloc )\n            return null;\n\n        // allocate new TlsList entry (adding 0xC0000 to the tag is obviously a flag also usesd by\n        //  the nt-loader, could be the result of HEAP_MAKE_TAG_FLAGS(0,HEAP_NO_SERIALIZE|HEAP_GROWABLE)\n        //  but this is not documented in the msdn entry for RtlAlloateHeap\n        void* heap = peb[6];\n        LdrpTlsListEntry* entry = cast(LdrpTlsListEntry*) (*fnAlloc)( heap, *pNtdllBaseTag | 0xc0000, LdrpTlsListEntry.sizeof );\n        if ( !entry )\n            return null;\n\n        // fill entry\n        entry.tlsstart = tlsstart;\n        entry.tlsend = tlsend;\n        entry.ptr_tlsindex = tlsindex;\n        entry.callbacks = tls_callbacks_a;\n        entry.zerofill = null;\n        entry.tlsindex = *pLdrpNumberOfTlsEntries;\n\n        // and add it to the end of TlsList\n        *tlsindex = *pLdrpNumberOfTlsEntries;\n        entry.next = pLdrpTlsList;\n        entry.prev = pLdrpTlsList.prev;\n        pLdrpTlsList.prev.next = entry;\n        pLdrpTlsList.prev = entry;\n        (*pLdrpNumberOfTlsEntries)++;\n\n        return entry;\n    }\n\n    // reallocate TLS array and create a copy of the TLS data section\n    static bool addTlsData( void** teb, void* tlsstart, void* tlsend, int tlsindex ) nothrow\n    {\n        HANDLE hnd = GetModuleHandleA( \"NTDLL\" );\n        assert( hnd, \"cannot get module handle for ntdll\" );\n\n        fnRtlAllocateHeap fnAlloc = cast(fnRtlAllocateHeap) GetProcAddress( hnd, \"RtlAllocateHeap\" );\n        if ( !fnAlloc || !pNtdllBaseTag )\n            return false;\n\n        void** peb = cast(void**) teb[12];\n        void* heap = peb[6];\n\n        auto sz = tlsend - tlsstart;\n        void* tlsdata = cast(void*) (*fnAlloc)( heap, *pNtdllBaseTag | 0xc0000, sz );\n        if ( !tlsdata )\n            return false;\n\n        // no relocations! not even self-relocations. Windows does not do them.\n        core.stdc.string.memcpy( tlsdata, tlsstart, sz );\n\n        // create copy of tls pointer array\n        void** array = cast(void**) (*fnAlloc)( heap, *pNtdllBaseTag | 0xc0000, (tlsindex + 1) * (void*).sizeof );\n        if ( !array )\n            return false;\n\n        if ( tlsindex > 0 && teb[11] )\n            core.stdc.string.memcpy( array, teb[11], tlsindex * (void*).sizeof);\n        array[tlsindex] = tlsdata;\n        teb[11] = cast(void*) array;\n\n        // let the old array leak, in case a oncurrent thread is still relying on it\n        return true;\n    }\n\n    alias bool BOOLEAN;\n\n    struct UNICODE_STRING\n    {\n        short Length;\n        short MaximumLength;\n        wchar* Buffer;\n    }\n\n    struct LIST_ENTRY\n    {\n        LIST_ENTRY* next;\n        LIST_ENTRY* prev;\n    }\n\n    // the following structures can be found here: http://undocumented.ntinternals.net/\n    // perhaps this should be same as LDR_DATA_TABLE_ENTRY, which is introduced with PEB_LDR_DATA\n    struct LDR_MODULE\n    {\n        LIST_ENTRY      InLoadOrderModuleList;\n        LIST_ENTRY      InMemoryOrderModuleList;\n        LIST_ENTRY      InInitializationOrderModuleList;\n        PVOID           BaseAddress;\n        PVOID           EntryPoint;\n        SIZE_T          SizeOfImage;\n        UNICODE_STRING  FullDllName;\n        UNICODE_STRING  BaseDllName;\n        ULONG           Flags;\n        SHORT           LoadCount;\n        SHORT           TlsIndex;\n        LIST_ENTRY      HashTableEntry;\n        ULONG           TimeDateStamp;\n    }\n\n    struct PEB_LDR_DATA\n    {\n        ULONG           Length;\n        BOOLEAN         Initialized;\n        PVOID           SsHandle;\n        LIST_ENTRY      InLoadOrderModuleList;\n        LIST_ENTRY      InMemoryOrderModuleList;\n        LIST_ENTRY      InInitializationOrderModuleList;\n    }\n\n    static LDR_MODULE* findLdrModule( HINSTANCE hInstance, void** peb ) nothrow\n    {\n        PEB_LDR_DATA* ldrData = cast(PEB_LDR_DATA*) peb[3];\n        LIST_ENTRY* root = &ldrData.InLoadOrderModuleList;\n        for (LIST_ENTRY* entry = root.next; entry != root; entry = entry.next)\n        {\n            LDR_MODULE *ldrMod = cast(LDR_MODULE*) entry;\n            if (ldrMod.BaseAddress == hInstance)\n                return ldrMod;\n        }\n        return null;\n    }\n\n    static bool setDllTlsUsage( HINSTANCE hInstance, void** peb ) nothrow\n    {\n        LDR_MODULE *thisMod = findLdrModule( hInstance, peb );\n        if ( !thisMod )\n            return false;\n\n        thisMod.TlsIndex = -1;  // uses TLS (not the index itself)\n        thisMod.LoadCount = -1; // never unload\n        return true;\n    }\n}\n}\n\npublic:\n/* *****************************************************\n * Fix implicit thread local storage for the case when a DLL is loaded\n * dynamically after process initialization.\n * The link time variables are passed to allow placing this function into\n * an RTL DLL itself.\n * The problem is described in Bugzilla 3342 and\n * http://www.nynaeve.net/?p=187, to quote from the latter:\n *\n * \"When a DLL using implicit TLS is loaded, because the loader doesn't process the TLS\n *  directory, the _tls_index value is not initialized by the loader, nor is there space\n *  allocated for module's TLS data in the ThreadLocalStoragePointer arrays of running\n *  threads. The DLL continues to load, however, and things will appear to work... until the\n *  first access to a __declspec(thread) variable occurs, that is.\"\n *\n * _tls_index is initialized by the compiler to 0, so we can use this as a test.\n */\nbool dll_fixTLS( HINSTANCE hInstance, void* tlsstart, void* tlsend, void* tls_callbacks_a, int* tlsindex ) nothrow\n{\n    version (Win64)\n        return true;                // fixed\n    else version (Win32)\n    {\n    /* If the OS has allocated a TLS slot for us, we don't have to do anything\n     * tls_index 0 means: the OS has not done anything, or it has allocated slot 0\n     * Vista and later Windows systems should do this correctly and not need\n     * this function.\n     */\n    if ( *tlsindex != 0 )\n        return true;\n\n    void** peb;\n    asm pure nothrow @nogc\n    {\n        mov EAX,FS:[0x30];\n        mov peb, EAX;\n    }\n    dll_aux.LDR_MODULE *ldrMod = dll_aux.findLdrModule( hInstance, peb );\n    if ( !ldrMod )\n        return false; // not in module list, bail out\n    if ( ldrMod.TlsIndex != 0 )\n        return true;  // the OS has already setup TLS\n\n    dll_aux.LdrpTlsListEntry* entry = dll_aux.addTlsListEntry( peb, tlsstart, tlsend, tls_callbacks_a, tlsindex );\n    if ( !entry )\n        return false;\n\n    scope (failure) assert(0); // enforce nothrow, Bugzilla 13561\n\n    if ( !enumProcessThreads(\n        function (uint id, void* context) nothrow {\n            dll_aux.LdrpTlsListEntry* entry = cast(dll_aux.LdrpTlsListEntry*) context;\n            return dll_aux.addTlsData( getTEB( id ), entry.tlsstart, entry.tlsend, entry.tlsindex );\n        }, entry ) )\n        return false;\n\n    ldrMod.TlsIndex = -1;  // flag TLS usage (not the index itself)\n    ldrMod.LoadCount = -1; // prevent unloading of the DLL,\n                           // since XP does not keep track of used TLS entries\n    return true;\n    }\n}\n\n// fixup TLS storage, initialize runtime and attach to threads\n// to be called from DllMain with reason DLL_PROCESS_ATTACH\nbool dll_process_attach( HINSTANCE hInstance, bool attach_threads,\n                         void* tlsstart, void* tlsend, void* tls_callbacks_a, int* tlsindex )\n{\n    version (Win32)\n    {\n        if ( !dll_fixTLS( hInstance, tlsstart, tlsend, tls_callbacks_a, tlsindex ) )\n            return false;\n    }\n\n    Runtime.initialize();\n\n    if ( !attach_threads )\n        return true;\n\n    // attach to all other threads\n    return enumProcessThreads(\n        function (uint id, void* context) {\n            if ( !thread_findByAddr( id ) )\n            {\n                // if the OS has not prepared TLS for us, don't attach to the thread\n                if ( GetTlsDataAddress( id ) )\n                {\n                    thread_attachByAddr( id );\n                    thread_moduleTlsCtor( id );\n                }\n            }\n            return true;\n        }, null );\n}\n\n// same as above, but only usable if druntime is linked statically\nbool dll_process_attach( HINSTANCE hInstance, bool attach_threads = true )\n{\n    version (Win64)\n    {\n        return dll_process_attach( hInstance, attach_threads,\n                                   null, null, null, null );\n    }\n    else version (Win32)\n    {\n        return dll_process_attach( hInstance, attach_threads,\n                                   &_tlsstart, &_tlsend, &_tls_callbacks_a, &_tls_index );\n    }\n}\n\n// to be called from DllMain with reason DLL_PROCESS_DETACH\nvoid dll_process_detach( HINSTANCE hInstance, bool detach_threads = true )\n{\n    // detach from all other threads\n    if ( detach_threads )\n        enumProcessThreads(\n            function (uint id, void* context) {\n                if ( id != GetCurrentThreadId() && thread_findByAddr( id ) )\n                {\n                    thread_moduleTlsDtor( id );\n                    thread_detachByAddr( id );\n                }\n                return true;\n            }, null );\n\n    Runtime.terminate();\n}\n\n/* Make sure that tlsCtorRun is itself a tls variable\n */\nstatic bool tlsCtorRun;\nstatic this() { tlsCtorRun = true; }\nstatic ~this() { tlsCtorRun = false; }\n\n// to be called from DllMain with reason DLL_THREAD_ATTACH\nbool dll_thread_attach( bool attach_thread = true, bool initTls = true )\n{\n    // if the OS has not prepared TLS for us, don't attach to the thread\n    //  (happened when running under x64 OS)\n    if ( !GetTlsDataAddress( GetCurrentThreadId() ) )\n        return false;\n    if ( !thread_findByAddr( GetCurrentThreadId() ) )\n    {\n        // only attach to thread and initalize it if it is not in the thread list (so it's not created by \"new Thread\")\n        if ( attach_thread )\n            thread_attachThis();\n        if ( initTls && !tlsCtorRun ) // avoid duplicate calls\n            rt_moduleTlsCtor();\n    }\n    return true;\n}\n\n// to be called from DllMain with reason DLL_THREAD_DETACH\nbool dll_thread_detach( bool detach_thread = true, bool exitTls = true )\n{\n    // if the OS has not prepared TLS for us, we did not attach to the thread\n    if ( !GetTlsDataAddress( GetCurrentThreadId() ) )\n         return false;\n    if ( thread_findByAddr( GetCurrentThreadId() ) )\n    {\n        if ( exitTls && tlsCtorRun ) // avoid dtors to be run twice\n            rt_moduleTlsDtor();\n        if ( detach_thread )\n            thread_detachThis();\n    }\n    return true;\n}\n\n/// A simple mixin to provide a $(D DllMain) which calls the necessary\n/// runtime initialization and termination functions automatically.\n///\n/// Instead of writing a custom $(D DllMain), simply write:\n///\n/// ---\n/// mixin SimpleDllMain;\n/// ---\nmixin template SimpleDllMain()\n{\n    import core.sys.windows.windows : HINSTANCE;\n\n    extern(Windows)\n    bool DllMain(HINSTANCE hInstance, uint ulReason, void* reserved)\n    {\n        import core.sys.windows.windows;\n        import core.sys.windows.dll :\n            dll_process_attach, dll_process_detach,\n            dll_thread_attach, dll_thread_detach;\n        switch (ulReason)\n        {\n            default: assert(0);\n            case DLL_PROCESS_ATTACH:\n                return dll_process_attach( hInstance, true );\n\n            case DLL_PROCESS_DETACH:\n                dll_process_detach( hInstance, true );\n                return true;\n\n            case DLL_THREAD_ATTACH:\n                return dll_thread_attach( true, true );\n\n            case DLL_THREAD_DETACH:\n                return dll_thread_detach( true, true );\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/docobj.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_docobj.d)\n */\nmodule core.sys.windows.docobj;\nversion (Windows):\n\nprivate import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.objidl, core.sys.windows.oleidl,\n  core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;\n\n// FIXME: remove inherited methods from interface definitions\n\nenum {\n    OLECMDERR_E_UNKNOWNGROUP = -2147221244,\n    OLECMDERR_E_CANCELED     = -2147221245,\n    OLECMDERR_E_NOHELP       = -2147221246,\n    OLECMDERR_E_DISABLED     = -2147221247,\n    OLECMDERR_E_NOTSUPPORTED = -2147221248\n}\n\nenum OLECMDID {\n    OLECMDID_OPEN = 1,\n    OLECMDID_NEW = 2,\n    OLECMDID_SAVE = 3,\n    OLECMDID_SAVEAS = 4,\n    OLECMDID_SAVECOPYAS = 5,\n    OLECMDID_PRINT = 6,\n    OLECMDID_PRINTPREVIEW = 7,\n    OLECMDID_PAGESETUP = 8,\n    OLECMDID_SPELL = 9,\n    OLECMDID_PROPERTIES = 10,\n    OLECMDID_CUT = 11,\n    OLECMDID_COPY = 12,\n    OLECMDID_PASTE = 13,\n    OLECMDID_PASTESPECIAL = 14,\n    OLECMDID_UNDO = 15,\n    OLECMDID_REDO = 16,\n    OLECMDID_SELECTALL = 17,\n    OLECMDID_CLEARSELECTION = 18,\n    OLECMDID_ZOOM = 19,\n    OLECMDID_GETZOOMRANGE = 20,\n    OLECMDID_UPDATECOMMANDS = 21,\n    OLECMDID_REFRESH = 22,\n    OLECMDID_STOP = 23,\n    OLECMDID_HIDETOOLBARS = 24,\n    OLECMDID_SETPROGRESSMAX = 25,\n    OLECMDID_SETPROGRESSPOS = 26,\n    OLECMDID_SETPROGRESSTEXT = 27,\n    OLECMDID_SETTITLE = 28,\n    OLECMDID_SETDOWNLOADSTATE = 29,\n    OLECMDID_STOPDOWNLOAD = 30\n}\n\nenum OLECMDF {\n    OLECMDF_SUPPORTED = 1,\n    OLECMDF_ENABLED = 2,\n    OLECMDF_LATCHED = 4,\n    OLECMDF_NINCHED = 8\n}\n\nenum OLECMDEXECOPT {\n    OLECMDEXECOPT_DODEFAULT = 0,\n    OLECMDEXECOPT_PROMPTUSER = 1,\n    OLECMDEXECOPT_DONTPROMPTUSER = 2,\n    OLECMDEXECOPT_SHOWHELP = 3\n}\n\nstruct OLECMDTEXT {\n    DWORD cmdtextf;\n    ULONG cwActual;\n    ULONG cwBuf;\n    wchar[1] rgwz;\n}\n\nstruct OLECMD {\n    ULONG cmdID;\n    DWORD cmdf;\n}\n\nalias IOleInPlaceSite LPOLEINPLACESITE;\nalias IEnumOleDocumentViews LPENUMOLEDOCUMENTVIEWS;\n\nextern (C) extern const IID\n    IID_IContinueCallback,\n    IID_IEnumOleDocumentViews,\n    IID_IPrint,\n    IID_IOleDocumentView,\n    IID_IOleDocument,\n    IID_IOleCommandTarget,\n    IID_IOleDocumentSite;\n\n\ninterface IOleDocumentView : IUnknown {\n    HRESULT SetInPlaceSite(LPOLEINPLACESITE);\n    HRESULT GetInPlaceSite(LPOLEINPLACESITE*);\n    HRESULT GetDocument(IUnknown*);\n    HRESULT SetRect(LPRECT);\n    HRESULT GetRect(LPRECT);\n    HRESULT SetRectComplex(LPRECT, LPRECT, LPRECT, LPRECT);\n    HRESULT Show(BOOL);\n    HRESULT UIActivate(BOOL);\n    HRESULT Open();\n    HRESULT Close(DWORD);\n    HRESULT SaveViewState(IStream);\n    HRESULT ApplyViewState(IStream);\n    HRESULT Clone(LPOLEINPLACESITE, IOleDocumentView*);\n}\n\ninterface IEnumOleDocumentViews : IUnknown {\n      HRESULT Next(ULONG, IOleDocumentView, ULONG*);\n      HRESULT Skip(ULONG);\n      HRESULT Reset();\n      HRESULT Clone(IEnumOleDocumentViews*);\n}\n\ninterface IOleDocument : IUnknown {\n    HRESULT CreateView(LPOLEINPLACESITE, IStream, DWORD, IOleDocumentView*);\n    HRESULT GetDocMiscStatus(DWORD*);\n    HRESULT EnumViews(LPENUMOLEDOCUMENTVIEWS*, IOleDocumentView*);\n}\n\ninterface IOleCommandTarget : IUnknown {\n    HRESULT QueryStatus(const(GUID)*, ULONG, OLECMD*, OLECMDTEXT*);\n    HRESULT Exec(const(GUID)*, DWORD, DWORD, VARIANTARG*, VARIANTARG*);\n}\n\ninterface IOleDocumentSite : IUnknown {\n    HRESULT ActivateMe(IOleDocumentView);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/errorrep.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_errorrep.d)\n */\nmodule core.sys.windows.errorrep;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef;\n\nstatic assert (_WIN32_WINNT >= 0x501,\n    \"core.sys.windows.errorrep is available only if version WindowsXP, Windows2003 \"\n    ~ \"or WindowsVista is set\");\n\nenum EFaultRepRetVal {\n    frrvOk,\n    frrvOkManifest,\n    frrvOkQueued,\n    frrvErr,\n    frrvErrNoDW,\n    frrvErrTimeout,\n    frrvLaunchDebugger,\n    frrvOkHeadless // = 7\n}\n\nextern (Windows) {\n    BOOL AddERExcludedApplicationA(LPCSTR);\n    BOOL AddERExcludedApplicationW(LPCWSTR);\n    EFaultRepRetVal ReportFault(LPEXCEPTION_POINTERS, DWORD);\n}\n\nversion (Unicode) {\n    alias AddERExcludedApplicationW AddERExcludedApplication;\n} else {\n    alias AddERExcludedApplicationA AddERExcludedApplication;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/exdisp.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_exdisp.d)\n */\nmodule core.sys.windows.exdisp;\nversion (Windows):\n\nimport core.sys.windows.docobj, core.sys.windows.oaidl, core.sys.windows.ocidl;\nprivate import core.sys.windows.basetyps, core.sys.windows.windef, core.sys.windows.wtypes;\n\n\nenum BrowserNavConstants {\n    navOpenInNewWindow = 0x01,\n    navNoHistory       = 0x02,\n    navNoReadFromCache = 0x04,\n    navNoWriteTocache  = 0x08,\n    navAllowAutosearch = 0x10,\n    navBrowserBar      = 0x20,\n    navHyperLink       = 0x40\n}\n\ninterface IWebBrowser : IDispatch {\n    HRESULT GoBack();\n    HRESULT GoForward();\n    HRESULT GoHome();\n    HRESULT GoSearch();\n    HRESULT Navigate(BSTR, VARIANT*, VARIANT*, VARIANT*, VARIANT*);\n    HRESULT Refresh();\n    HRESULT Refresh2(VARIANT*);\n    HRESULT Stop();\n    HRESULT get_Application(IDispatch* ppDisp);\n    HRESULT get_Parent(IDispatch* ppDisp);\n    HRESULT get_Container(IDispatch* ppDisp);\n    HRESULT get_Document(IDispatch* ppDisp);\n    HRESULT get_TopLevelContainer(VARIANT_BOOL*);\n    HRESULT get_Type(BSTR*);\n    HRESULT get_Left(LONG*);\n    HRESULT put_Left(LONG);\n    HRESULT get_Top(LONG*);\n    HRESULT put_Top(LONG);\n    HRESULT get_Width(LONG*);\n    HRESULT put_Width(LONG);\n    HRESULT get_Height(LONG*);\n    HRESULT put_Height(LONG);\n    HRESULT get_LocationName(BSTR*);\n    HRESULT get_LocationURL(BSTR*);\n    HRESULT get_Busy(VARIANT_BOOL*);\n}\n\ninterface IWebBrowserApp : IWebBrowser {\n    HRESULT Quit();\n    HRESULT ClientToWindow(int*, int*);\n    HRESULT PutProperty(BSTR, VARIANT);\n    HRESULT GetProperty(BSTR, VARIANT*);\n    HRESULT get_Name(BSTR*);\n    HRESULT get_HWND(LONG*);\n    HRESULT get_FullName(BSTR*);\n    HRESULT get_Path(BSTR*);\n    HRESULT get_Visible(VARIANT_BOOL*);\n    HRESULT put_Visible(VARIANT_BOOL);\n    HRESULT get_StatusBar(VARIANT_BOOL*);\n    HRESULT put_StatusBar(VARIANT_BOOL);\n    HRESULT get_StatusText(BSTR*);\n    HRESULT put_StatusText(BSTR);\n    HRESULT get_ToolBar(int*);\n    HRESULT put_ToolBar(int);\n    HRESULT get_MenuBar(VARIANT_BOOL*);\n    HRESULT put_MenuBar(VARIANT_BOOL);\n    HRESULT get_FullScreen(VARIANT_BOOL*);\n    HRESULT put_FullScreen(VARIANT_BOOL);\n}\n\ninterface IWebBrowser2 : IWebBrowserApp {\n    HRESULT Navigate2(VARIANT*, VARIANT*, VARIANT*, VARIANT*, VARIANT*);\n    HRESULT QueryStatusWB(OLECMDID, OLECMDF*);\n    HRESULT ExecWB(OLECMDID, OLECMDEXECOPT, VARIANT*, VARIANT*);\n    HRESULT ShowBrowserBar(VARIANT*, VARIANT*, VARIANT*);\n    HRESULT get_ReadyState(READYSTATE*);\n    HRESULT get_Offline(VARIANT_BOOL*);\n    HRESULT put_Offline(VARIANT_BOOL);\n    HRESULT get_Silent(VARIANT_BOOL*);\n    HRESULT put_Silent(VARIANT_BOOL);\n    HRESULT get_RegistaerAsBrowser(VARIANT_BOOL*);\n    HRESULT put_RegisterAsBrowser(VARIANT_BOOL);\n    HRESULT get_RegistaerAsDropTarget(VARIANT_BOOL*);\n    HRESULT put_RegisterAsDropTarget(VARIANT_BOOL);\n    HRESULT get_TheaterMode(VARIANT_BOOL*);\n    HRESULT put_TheaterMode(VARIANT_BOOL);\n    HRESULT get_AddressBar(VARIANT_BOOL*);\n    HRESULT put_AddressBar(VARIANT_BOOL);\n    HRESULT get_Resizable(VARIANT_BOOL*);\n    HRESULT put_Resizable(VARIANT_BOOL);\n}\n\ninterface DWebBrowserEvents2 : IDispatch {\n    void StatusTextChange(BSTR);\n    void ProgressChange(LONG, LONG);\n    void CommandStateChange(LONG, VARIANT_BOOL);\n    void DownloadBegin();\n    void DownloadComplete();\n    void TitleChange(BSTR);\n    void PropertyChange(BSTR);\n    void BeforeNavigate2(IDispatch pDisp, VARIANT*, VARIANT*, VARIANT*, VARIANT*, VARIANT*, VARIANT_BOOL*);\n    void NewWindow2(IDispatch* ppDisp, VARIANT_BOOL*);\n    void NavigateComplete(IDispatch pDisp, VARIANT*);\n    void DocumentComplete(IDispatch pDisp, VARIANT*);\n    void OnQuit();\n    void OnVisible(VARIANT_BOOL);\n    void OnToolBar(VARIANT_BOOL);\n    void OnMenuBar(VARIANT_BOOL);\n    void OnStatusBar(VARIANT_BOOL);\n    void OnFullScreen(VARIANT_BOOL);\n    void OnTheaterMode(VARIANT_BOOL);\n    void WindowSetResizable(VARIANT_BOOL);\n    void WindowSetLeft(LONG);\n    void WindowSetTop(LONG);\n    void WindowSetWidth(LONG);\n    void WindowSetHeight(LONG);\n    void WindowClosing(VARIANT_BOOL, VARIANT_BOOL*);\n    void ClientToHostWindow(LONG*, LONG*);\n    void SetSecureLockIcon(LONG);\n    void FileDownload(VARIANT_BOOL*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/exdispid.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.10\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_exdispid.d)\n */\nmodule core.sys.windows.exdispid;\nversion (Windows):\n\nenum : int {\n    DISPID_STATUSTEXTCHANGE = 102,\n    DISPID_PROGRESSCHANGE   = 108,\n    DISPID_TITLECHANGE      = 113,\n    DISPID_BEFORENAVIGATE2  = 250,\n    DISPID_NEWWINDOW2       = 251,\n    DISPID_DOCUMENTCOMPLETE = 259\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/httpext.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_httpext.d)\n */\nmodule core.sys.windows.httpext;\nversion (Windows):\n\n/* Comment from MinGW\n       httpext.h - Header for ISAPI extensions.\n\n       This file is part of a free library for the Win32 API.\n\n       This library is distributed in the hope that it will be useful,\n       but WITHOUT ANY WARRANTY; without even the implied warranty of\n       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n*/\n\nprivate import core.sys.windows.windows;\n\nenum {\n    HSE_VERSION_MAJOR               = 2,\n    HSE_VERSION_MINOR               = 0,\n    HSE_LOG_BUFFER_LEN              = 80,\n    HSE_MAX_EXT_DLL_NAME_LEN        = 256,\n    HSE_STATUS_SUCCESS              = 1,\n    HSE_STATUS_SUCCESS_AND_KEEP_CONN,\n    HSE_STATUS_PENDING,\n    HSE_STATUS_ERROR,\n    HSE_REQ_BASE                    = 0,\n    HSE_REQ_SEND_URL_REDIRECT_RESP,\n    HSE_REQ_SEND_URL,\n    HSE_REQ_SEND_RESPONSE_HEADER,\n    HSE_REQ_DONE_WITH_SESSION,\n    HSE_REQ_SEND_RESPONSE_HEADER_EX = 1016,\n    HSE_REQ_END_RESERVED            = 1000,\n    HSE_TERM_ADVISORY_UNLOAD        = 0x00000001,\n    HSE_TERM_MUST_UNLOAD,\n    HSE_IO_SYNC                     = 0x00000001,\n    HSE_IO_ASYNC,\n    HSE_IO_DISCONNECT_AFTER_SEND    = 0x00000004,\n    HSE_IO_SEND_HEADERS             = 0x00000008\n}\n\nmixin DECLARE_HANDLE!(\"HCONN\");\n\nstruct HSE_VERSION_INFO {\n    DWORD dwExtensionVersion;\n    CHAR[HSE_MAX_EXT_DLL_NAME_LEN] lpszExtensionDesc;\n}\nalias HSE_VERSION_INFO* LPHSE_VERSION_INFO;\n\nstruct EXTENSION_CONTROL_BLOCK {\n    DWORD  cbSize = EXTENSION_CONTROL_BLOCK.sizeof;\n    DWORD  dwVersion;\n    HCONN  ConnID;\n    DWORD  dwHttpStatusCode;\n    CHAR[HSE_LOG_BUFFER_LEN] lpszLogData;\n    LPSTR  lpszMethod;\n    LPSTR  lpszQueryString;\n    LPSTR  lpszPathInfo;\n    LPSTR  lpszPathTranslated;\n    DWORD  cbTotalBytes;\n    DWORD  cbAvailable;\n    LPBYTE lpbData;\n    LPSTR  lpszContentType;\n    extern(Pascal) BOOL function(HCONN, LPSTR, LPVOID, LPDWORD)\n      GetServerVariable;\n    extern(Pascal) BOOL function(HCONN, LPVOID, LPDWORD, DWORD) WriteClient;\n    extern(Pascal) BOOL function(HCONN, LPVOID, LPDWORD) ReadClient;\n    extern(Pascal) BOOL function(HCONN, DWORD, LPVOID, LPDWORD, LPDWORD)\n      ServerSupportFunction;\n}\nalias EXTENSION_CONTROL_BLOCK* LPEXTENSION_CONTROL_BLOCK;\n\nextern (Pascal) {\n    alias BOOL function(HSE_VERSION_INFO*) PFN_GETEXTENSIONVERSION;\n    alias DWORD function(EXTENSION_CONTROL_BLOCK*) PFN_HTTPEXTENSIONPROC;\n    alias BOOL function(DWORD) PFN_TERMINATEEXTENSION;\n    alias VOID function(EXTENSION_CONTROL_BLOCK*, PVOID, DWORD, DWORD) PFN_HSE_IO_COMPLETION;\n}\n\nstruct HSE_TF_INFO {\n    PFN_HSE_IO_COMPLETION pfnHseIO;\n    PVOID  pContext;\n    HANDLE hFile;\n    LPCSTR pszStatusCode;\n    DWORD  BytesToWrite;\n    DWORD  Offset;\n    PVOID  pHead;\n    DWORD  HeadLength;\n    PVOID  pTail;\n    DWORD  TailLength;\n    DWORD  dwFlags;\n}\nalias HSE_TF_INFO* LPHSE_TF_INFO;\n\nstruct HSE_SEND_HEADER_EX_INFO {\n    LPCSTR pszStatus;\n    LPCSTR pszHeader;\n    DWORD  cchStatus;\n    DWORD  cchHeader;\n    BOOL   fKeepConn;\n}\nalias HSE_SEND_HEADER_EX_INFO* LPHSE_SEND_HEADER_EX_INF;\n\nextern (Pascal) {\n    BOOL GetExtensionVersion(HSE_VERSION_INFO*);\n    DWORD HttpExtensionProc(EXTENSION_CONTROL_BLOCK*);\n    BOOL TerminateExtension(DWORD);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/idispids.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.10\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_idispids.d)\n */\nmodule core.sys.windows.idispids;\nversion (Windows):\n\nenum : int {\n    DISPID_AMBIENT_OFFLINEIFNOTCONNECTED = -5501,\n    DISPID_AMBIENT_SILENT                = -5502\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/imagehlp.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_imagehlp.d)\n */\nmodule core.sys.windows.imagehlp;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\n/* Comment from MinGW\n    NOTE: This strictly does not belong in the Win32 API since it's\n    really part of Platform SDK. However, GDB needs it and we might\n    as well provide it here.\n*/\n\nprivate import core.sys.windows.winbase, core.sys.windows.windef;\n\n// FIXME: check types of constants\n\nenum API_VERSION_NUMBER = 7;\n\nenum BIND_NO_BOUND_IMPORTS  = 1;\nenum BIND_NO_UPDATE         = 2;\nenum BIND_ALL_IMAGES        = 4;\nenum BIND_CACHE_IMPORT_DLLS = 8;\n\nenum {\n    CBA_DEFERRED_SYMBOL_LOAD_START = 1,\n    CBA_DEFERRED_SYMBOL_LOAD_COMPLETE,\n    CBA_DEFERRED_SYMBOL_LOAD_FAILURE,\n    CBA_SYMBOLS_UNLOADED,\n    CBA_DUPLICATE_SYMBOL\n}\n\nenum CERT_PE_IMAGE_DIGEST_DEBUG_INFO      = 1;\nenum CERT_PE_IMAGE_DIGEST_RESOURCES       = 2;\nenum CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO = 4;\nenum CERT_PE_IMAGE_DIGEST_NON_PE_INFO     = 8;\n\nenum CERT_SECTION_TYPE_ANY = 255;\n\nenum {\n    CHECKSUM_SUCCESS = 0,\n    CHECKSUM_OPEN_FAILURE,\n    CHECKSUM_MAP_FAILURE,\n    CHECKSUM_MAPVIEW_FAILURE,\n    CHECKSUM_UNICODE_FAILURE\n}\n\nenum IMAGE_SEPARATION = 65536;\n\nenum SPLITSYM_REMOVE_PRIVATE    = 1;\nenum SPLITSYM_EXTRACT_ALL       = 2;\nenum SPLITSYM_SYMBOLPATH_IS_SRC = 4;\n\nenum SYMF_OMAP_GENERATED = 1;\nenum SYMF_OMAP_MODIFIED  = 2;\n\nenum SYMOPT_CASE_INSENSITIVE  =  1;\nenum SYMOPT_UNDNAME           =  2;\nenum SYMOPT_DEFERRED_LOADS    =  4;\nenum SYMOPT_NO_CPP            =  8;\n//const SYMOPT_LOAD_LINES        = 16;\n//const SYMOPT_OMAP_FIND_NEAREST = 32;\npublic import core.sys.windows.dbghelp_types :\n    SYMOPT_DEFERRED_LOAD,\n    SYMOPT_FAIL_CRITICAL_ERRORS,\n    SYMOPT_LOAD_LINES,\n    SYMOPT_DEBUG;\n\nenum UNDNAME_COMPLETE               =     0;\nenum UNDNAME_NO_LEADING_UNDERSCORES =     1;\nenum UNDNAME_NO_MS_KEYWORDS         =     2;\nenum UNDNAME_NO_FUNCTION_RETURNS    =     4;\nenum UNDNAME_NO_ALLOCATION_MODEL    =     8;\nenum UNDNAME_NO_ALLOCATION_LANGUAGE =    16;\nenum UNDNAME_NO_MS_THISTYPE         =    32;\nenum UNDNAME_NO_CV_THISTYPE         =    64;\nenum UNDNAME_NO_THISTYPE            =    96;\nenum UNDNAME_NO_ACCESS_SPECIFIERS   =   128;\nenum UNDNAME_NO_THROW_SIGNATURES    =   256;\nenum UNDNAME_NO_MEMBER_TYPE         =   512;\nenum UNDNAME_NO_RETURN_UDT_MODEL    =  1024;\nenum UNDNAME_32_BIT_DECODE          =  2048;\nenum UNDNAME_NAME_ONLY              =  4096;\nenum UNDNAME_NO_ARGUMENTS           =  8192;\nenum UNDNAME_NO_SPECIAL_SYMS        = 16384;\n\nenum IMAGEHLP_STATUS_REASON {\n    BindOutOfMemory,\n    BindRvaToVaFailed,\n    BindNoRoomInImage,\n    BindImportModuleFailed,\n    BindImportProcedureFailed,\n    BindImportModule,\n    BindImportProcedure,\n    BindForwarder,\n    BindForwarderNOT,\n    BindImageModified,\n    BindExpandFileHeaders,\n    BindImageComplete,\n    BindMismatchedSymbols,\n    BindSymbolsNotUpdated\n}\n\nstruct LOADED_IMAGE {\n    LPSTR                 ModuleName;\n    HANDLE                hFile;\n    PUCHAR                MappedAddress;\n    PIMAGE_NT_HEADERS     FileHeader;\n    PIMAGE_SECTION_HEADER LastRvaSection;\n    ULONG                 NumberOfSections;\n    PIMAGE_SECTION_HEADER Sections;\n    ULONG                 Characteristics;\n    BOOLEAN               fSystemImage;\n    BOOLEAN               fDOSImage;\n    LIST_ENTRY            Links;\n    ULONG                 SizeOfImage;\n}\nalias LOADED_IMAGE* PLOADED_IMAGE;\n\nstruct IMAGE_DEBUG_INFORMATION {\n    LIST_ENTRY                 List;\n    DWORD                      Size;\n    PVOID                      MappedBase;\n    USHORT                     Machine;\n    USHORT                     Characteristics;\n    DWORD                      CheckSum;\n    DWORD                      ImageBase;\n    DWORD                      SizeOfImage;\n    DWORD                      NumberOfSections;\n    PIMAGE_SECTION_HEADER      Sections;\n    DWORD                      ExportedNamesSize;\n    LPSTR                      ExportedNames;\n    DWORD                      NumberOfFunctionTableEntries;\n    PIMAGE_FUNCTION_ENTRY      FunctionTableEntries;\n    DWORD                      LowestFunctionStartingAddress;\n    DWORD                      HighestFunctionEndingAddress;\n    DWORD                      NumberOfFpoTableEntries;\n    PFPO_DATA                  FpoTableEntries;\n    DWORD                      SizeOfCoffSymbols;\n    PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols;\n    DWORD                      SizeOfCodeViewSymbols;\n    PVOID                      CodeViewSymbols;\n    LPSTR                      ImageFilePath;\n    LPSTR                      ImageFileName;\n    LPSTR                      DebugFilePath;\n    DWORD                      TimeDateStamp;\n    BOOL                       RomImage;\n    PIMAGE_DEBUG_DIRECTORY     DebugDirectory;\n    DWORD                      NumberOfDebugDirectories;\n    DWORD[3]                   Reserved;\n}\nalias IMAGE_DEBUG_INFORMATION* PIMAGE_DEBUG_INFORMATION;\n\nenum ADDRESS_MODE {\n    AddrMode1616,\n    AddrMode1632,\n    AddrModeReal,\n    AddrModeFlat\n}\n\nstruct ADDRESS {\n    DWORD        Offset;\n    WORD         Segment;\n    ADDRESS_MODE Mode;\n}\nalias ADDRESS* LPADDRESS;\n\nstruct KDHELP {\n    DWORD Thread;\n    DWORD ThCallbackStack;\n    DWORD NextCallback;\n    DWORD FramePointer;\n    DWORD KiCallUserMode;\n    DWORD KeUserCallbackDispatcher;\n    DWORD SystemRangeStart;\n    DWORD ThCallbackBStore;\n    DWORD KiUserExceptionDispatcher;\n    DWORD StackBase;\n    DWORD StackLimit;\n    DWORD[5] Reserved;\n}\nalias KDHELP* PKDHELP;\n\nstruct STACKFRAME {\n    ADDRESS  AddrPC;\n    ADDRESS  AddrReturn;\n    ADDRESS  AddrFrame;\n    ADDRESS  AddrStack;\n    LPVOID   FuncTableEntry;\n    DWORD[4] Params;\n    BOOL     Far;\n    BOOL     Virtual;\n    DWORD[3] Reserved;\n    KDHELP   KdHelp;\n    ADDRESS  AddrBStore;\n}\nalias STACKFRAME* LPSTACKFRAME;\n\n/*\nstruct API_VERSION {\n    USHORT MajorVersion;\n    USHORT MinorVersion;\n    USHORT Revision;\n    USHORT Reserved;\n}\n*/\npublic import core.sys.windows.dbghelp_types : API_VERSION;\nalias API_VERSION* LPAPI_VERSION;\n\nenum SYM_TYPE {\n    SymNone,\n    SymCoff,\n    SymCv,\n    SymPdb,\n    SymExport,\n    SymDeferred,\n    SymSym\n}\n\nstruct IMAGEHLP_SYMBOL {\n    DWORD   SizeOfStruct;\n    DWORD   Address;\n    DWORD   Size;\n    DWORD   Flags;\n    DWORD   MaxNameLength;\n    CHAR[1] Name;\n}\nalias IMAGEHLP_SYMBOL* PIMAGEHLP_SYMBOL;\n\nstruct IMAGEHLP_MODULE {\n    DWORD     SizeOfStruct;\n    DWORD     BaseOfImage;\n    DWORD     ImageSize;\n    DWORD     TimeDateStamp;\n    DWORD     CheckSum;\n    DWORD     NumSyms;\n    SYM_TYPE  SymType;\n    CHAR[32]  ModuleName;\n    CHAR[256] ImageName;\n    CHAR[256] LoadedImageName;\n}\nalias IMAGEHLP_MODULE* PIMAGEHLP_MODULE;\n\nstruct IMAGEHLP_LINE {\n    DWORD SizeOfStruct;\n    DWORD Key;\n    DWORD LineNumber;\n    PCHAR FileName;\n    DWORD Address;\n}\nalias IMAGEHLP_LINE* PIMAGEHLP_LINE;\n\nstruct IMAGEHLP_DEFERRED_SYMBOL_LOAD {\n    DWORD          SizeOfStruct;\n    DWORD          BaseOfImage;\n    DWORD          CheckSum;\n    DWORD          TimeDateStamp;\n    CHAR[MAX_PATH] FileName;\n    BOOLEAN        Reparse;\n}\nalias IMAGEHLP_DEFERRED_SYMBOL_LOAD* PIMAGEHLP_DEFERRED_SYMBOL_LOAD;\n\nstruct IMAGEHLP_DUPLICATE_SYMBOL {\n    DWORD            SizeOfStruct;\n    DWORD            NumberOfDups;\n    PIMAGEHLP_SYMBOL Symbol;\n    ULONG            SelectedSymbol;\n}\nalias IMAGEHLP_DUPLICATE_SYMBOL* PIMAGEHLP_DUPLICATE_SYMBOL;\n\nmixin DECLARE_HANDLE!(\"DIGEST_HANDLE\");\n\nextern (Windows) {\n    alias BOOL function(IMAGEHLP_STATUS_REASON, LPSTR, LPSTR, ULONG_PTR, ULONG_PTR)\n      PIMAGEHLP_STATUS_ROUTINE;\n    alias BOOL function(HANDLE , LPCVOID, LPVOID, DWORD, LPDWORD)\n      PREAD_PROCESS_MEMORY_ROUTINE;\n    alias LPVOID function(HANDLE, DWORD) PFUNCTION_TABLE_ACCESS_ROUTINE;\n    alias DWORD function(HANDLE, DWORD) PGET_MODULE_BASE_ROUTINE;\n    alias DWORD function(HANDLE, HANDLE, LPADDRESS)\n      PTRANSLATE_ADDRESS_ROUTINE;\n    alias BOOL function(LPSTR, ULONG, PVOID) PSYM_ENUMMODULES_CALLBACK;\n    alias BOOL function(LPSTR, ULONG, ULONG, PVOID) PSYM_ENUMSYMBOLS_CALLBACK;\n    alias BOOL function(LPSTR, ULONG, ULONG, PVOID)\n      PENUMLOADED_MODULES_CALLBACK;\n    alias BOOL function(HANDLE, ULONG, PVOID, PVOID)\n      PSYMBOL_REGISTERED_CALLBACK;\n    alias BOOL function(DIGEST_HANDLE refdata, PBYTE pData, DWORD dwLength)\n      DIGEST_FUNCTION;\n\n    PIMAGE_NT_HEADERS CheckSumMappedFile(LPVOID, DWORD, LPDWORD, LPDWORD);\n    DWORD MapFileAndCheckSumA(LPSTR, LPDWORD, LPDWORD);\n    DWORD MapFileAndCheckSumW(PWSTR, LPDWORD, LPDWORD);\n    BOOL TouchFileTimes(HANDLE, LPSYSTEMTIME);\n    BOOL SplitSymbols(LPSTR, LPSTR, LPSTR, DWORD);\n    HANDLE FindDebugInfoFile(LPSTR, LPSTR, LPSTR);\n    HANDLE FindExecutableImage(LPSTR, LPSTR, LPSTR);\n    BOOL UpdateDebugInfoFile(LPSTR, LPSTR, LPSTR, PIMAGE_NT_HEADERS);\n    BOOL UpdateDebugInfoFileEx(LPSTR, LPSTR, LPSTR, PIMAGE_NT_HEADERS, DWORD);\n    BOOL BindImage(LPSTR, LPSTR, LPSTR);\n    BOOL BindImageEx(DWORD, LPSTR, LPSTR, LPSTR, PIMAGEHLP_STATUS_ROUTINE);\n    BOOL ReBaseImage(LPSTR, LPSTR, BOOL, BOOL, BOOL, ULONG, ULONG*, ULONG_PTR*,\n      ULONG*, ULONG_PTR*, ULONG);\n    PLOADED_IMAGE ImageLoad(LPSTR, LPSTR);\n    BOOL ImageUnload(PLOADED_IMAGE);\n    PIMAGE_NT_HEADERS ImageNtHeader(PVOID);\n    PVOID ImageDirectoryEntryToData(PVOID, BOOLEAN, USHORT, PULONG);\n    PIMAGE_SECTION_HEADER ImageRvaToSection(PIMAGE_NT_HEADERS, PVOID, ULONG);\n    PVOID ImageRvaToVa(PIMAGE_NT_HEADERS, PVOID, ULONG,\n      PIMAGE_SECTION_HEADER*);\n    BOOL MapAndLoad(LPSTR, LPSTR, PLOADED_IMAGE, BOOL, BOOL);\n    BOOL GetImageConfigInformation(PLOADED_IMAGE,\n      PIMAGE_LOAD_CONFIG_DIRECTORY);\n    DWORD GetImageUnusedHeaderBytes(PLOADED_IMAGE, LPDWORD);\n    BOOL SetImageConfigInformation(PLOADED_IMAGE,\n      PIMAGE_LOAD_CONFIG_DIRECTORY);\n    BOOL UnMapAndLoad(PLOADED_IMAGE);\n    PIMAGE_DEBUG_INFORMATION MapDebugInformation(HANDLE, LPSTR, LPSTR, DWORD);\n    BOOL UnmapDebugInformation(PIMAGE_DEBUG_INFORMATION);\n    HANDLE FindExecutableImage(LPSTR, LPSTR, LPSTR);\n    BOOL SearchTreeForFile(LPSTR, LPSTR, LPSTR);\n    BOOL MakeSureDirectoryPathExists(LPCSTR);\n    DWORD UnDecorateSymbolName(LPCSTR, LPSTR, DWORD, DWORD);\n    BOOL StackWalk(DWORD, HANDLE, HANDLE, LPSTACKFRAME, LPVOID,\n      PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE,\n      PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE);\n    LPAPI_VERSION ImagehlpApiVersion();\n    LPAPI_VERSION ImagehlpApiVersionEx(LPAPI_VERSION);\n    DWORD GetTimestampForLoadedLibrary(HMODULE);\n    BOOL RemovePrivateCvSymbolic(PCHAR, PCHAR*, ULONG*);\n    VOID RemoveRelocations(PCHAR);\n    DWORD SymSetOptions(DWORD);\n    DWORD SymGetOptions();\n    BOOL SymCleanup(HANDLE);\n    BOOL SymEnumerateModules(HANDLE, PSYM_ENUMMODULES_CALLBACK, PVOID);\n    BOOL SymEnumerateSymbols(HANDLE, DWORD, PSYM_ENUMSYMBOLS_CALLBACK, PVOID);\n    BOOL EnumerateLoadedModules(HANDLE, PENUMLOADED_MODULES_CALLBACK, PVOID);\n    LPVOID SymFunctionTableAccess(HANDLE, DWORD);\n    BOOL SymGetModuleInfo(HANDLE, DWORD, PIMAGEHLP_MODULE);\n    DWORD SymGetModuleBase(HANDLE, DWORD);\n    BOOL SymGetSymFromAddr(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL);\n    BOOL SymGetSymFromName(HANDLE, LPSTR, PIMAGEHLP_SYMBOL);\n    BOOL SymGetSymNext(HANDLE, PIMAGEHLP_SYMBOL);\n    BOOL SymGetSymPrev(HANDLE, PIMAGEHLP_SYMBOL);\n    BOOL SymGetLineFromAddr(HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE);\n    BOOL SymGetLineFromName(HANDLE, LPSTR, LPSTR, DWORD, PLONG,\n      PIMAGEHLP_LINE);\n    BOOL SymGetLineNext(HANDLE, PIMAGEHLP_LINE);\n    BOOL SymGetLinePrev(HANDLE, PIMAGEHLP_LINE);\n    BOOL SymMatchFileName(LPSTR, LPSTR, LPSTR*, LPSTR*);\n    BOOL SymInitialize(HANDLE, LPSTR, BOOL);\n    BOOL SymGetSearchPath(HANDLE, LPSTR, DWORD);\n    BOOL SymSetSearchPath(HANDLE, LPSTR);\n    BOOL SymLoadModule(HANDLE, HANDLE, PSTR, PSTR, DWORD, DWORD);\n    BOOL SymUnloadModule(HANDLE, DWORD);\n    BOOL SymUnDName(PIMAGEHLP_SYMBOL, LPSTR, DWORD);\n    BOOL SymRegisterCallback(HANDLE, PSYMBOL_REGISTERED_CALLBACK, PVOID);\n    BOOL ImageGetDigestStream(HANDLE, DWORD, DIGEST_FUNCTION, DIGEST_HANDLE);\n    BOOL ImageAddCertificate(HANDLE, LPWIN_CERTIFICATE, PDWORD);\n    BOOL ImageRemoveCertificate(HANDLE, DWORD);\n    BOOL ImageEnumerateCertificates(HANDLE, WORD, PDWORD, PDWORD, DWORD);\n    BOOL ImageGetCertificateData(HANDLE, DWORD, LPWIN_CERTIFICATE, PDWORD);\n    BOOL ImageGetCertificateHeader(HANDLE, DWORD, LPWIN_CERTIFICATE);\n    BOOL CopyPdb(CHAR*, CHAR*, BOOL);\n    BOOL RemovePrivateCvSymbolicEx(PCHAR, ULONG, PCHAR*, ULONG*);\n}\n\nversion (Unicode) {\n    alias MapFileAndCheckSumW MapFileAndCheckSum;\n} else {\n    alias MapFileAndCheckSumA MapFileAndCheckSum;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/imm.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_imm.d)\n */\nmodule core.sys.windows.imm;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"imm32\");\n\nimport core.sys.windows.windef, core.sys.windows.wingdi;\nimport core.sys.windows.winuser; // for the MFS_xxx enums.\nprivate import core.sys.windows.w32api;\n\nenum WM_CONVERTREQUESTEX     = 0x108;\nenum WM_IME_STARTCOMPOSITION = 0x10D;\nenum WM_IME_ENDCOMPOSITION   = 0x10E;\nenum WM_IME_COMPOSITION      = 0x10F;\nenum WM_IME_KEYLAST          = 0x10F;\nenum WM_IME_SETCONTEXT       = 0x281;\nenum WM_IME_NOTIFY           = 0x282;\nenum WM_IME_CONTROL          = 0x283;\nenum WM_IME_COMPOSITIONFULL  = 0x284;\nenum WM_IME_SELECT           = 0x285;\nenum WM_IME_CHAR             = 0x286;\n//static if (_WIN32_WINNT >= 0x500) {\nenum WM_IME_REQUEST      = 0x288;\n//}\nenum WM_IME_KEYDOWN          = 0x290;\nenum WM_IME_KEYUP            = 0x291;\n\n\nenum IMC_GETCANDIDATEPOS=7;\nenum IMC_SETCANDIDATEPOS=8;\nenum IMC_GETCOMPOSITIONFONT=9;\nenum IMC_SETCOMPOSITIONFONT=10;\nenum IMC_GETCOMPOSITIONWINDOW=11;\nenum IMC_SETCOMPOSITIONWINDOW=12;\nenum IMC_GETSTATUSWINDOWPOS=15;\nenum IMC_SETSTATUSWINDOWPOS=16;\nenum IMC_CLOSESTATUSWINDOW=0x21;\nenum IMC_OPENSTATUSWINDOW=0x22;\nenum IMN_CLOSESTATUSWINDOW=1;\nenum IMN_OPENSTATUSWINDOW=2;\nenum IMN_CHANGECANDIDATE=3;\nenum IMN_CLOSECANDIDATE=4;\nenum IMN_OPENCANDIDATE=5;\nenum IMN_SETCONVERSIONMODE=6;\nenum IMN_SETSENTENCEMODE=7;\nenum IMN_SETOPENSTATUS=8;\nenum IMN_SETCANDIDATEPOS=9;\nenum IMN_SETCOMPOSITIONFONT=10;\nenum IMN_SETCOMPOSITIONWINDOW=11;\nenum IMN_SETSTATUSWINDOWPOS=12;\nenum IMN_GUIDELINE=13;\nenum IMN_PRIVATE=14;\n\nenum NI_OPENCANDIDATE=16;\nenum NI_CLOSECANDIDATE=17;\nenum NI_SELECTCANDIDATESTR=18;\nenum NI_CHANGECANDIDATELIST=19;\nenum NI_FINALIZECONVERSIONRESULT=20;\nenum NI_COMPOSITIONSTR=21;\nenum NI_SETCANDIDATE_PAGESTART=22;\nenum NI_SETCANDIDATE_PAGESIZE=23;\nenum NI_IMEMENUSELECTED=24;\n\nenum ISC_SHOWUICANDIDATEWINDOW=1;\nenum ISC_SHOWUICOMPOSITIONWINDOW=0x80000000;\nenum ISC_SHOWUIGUIDELINE=0x40000000;\nenum ISC_SHOWUIALLCANDIDATEWINDOW=15;\nenum ISC_SHOWUIALL=0xC000000F;\n\nenum CPS_COMPLETE=1;\nenum CPS_CONVERT=2;\nenum CPS_REVERT=3;\nenum CPS_CANCEL=4;\n\nenum IME_CHOTKEY_IME_NONIME_TOGGLE=16;\nenum IME_CHOTKEY_SHAPE_TOGGLE=17;\nenum IME_CHOTKEY_SYMBOL_TOGGLE=18;\nenum IME_JHOTKEY_CLOSE_OPEN=0x30;\nenum IME_KHOTKEY_SHAPE_TOGGLE=0x50;\nenum IME_KHOTKEY_HANJACONVERT=0x51;\nenum IME_KHOTKEY_ENGLISH=0x52;\nenum IME_THOTKEY_IME_NONIME_TOGGLE=0x70;\nenum IME_THOTKEY_SHAPE_TOGGLE=0x71;\nenum IME_THOTKEY_SYMBOL_TOGGLE=0x72;\nenum IME_HOTKEY_DSWITCH_FIRST=256;\nenum IME_HOTKEY_DSWITCH_LAST=0x11F;\nenum IME_ITHOTKEY_RESEND_RESULTSTR=512;\nenum IME_ITHOTKEY_PREVIOUS_COMPOSITION=513;\nenum IME_ITHOTKEY_UISTYLE_TOGGLE=514;\n\nenum GCS_COMPREADSTR=1;\nenum GCS_COMPREADATTR=2;\nenum GCS_COMPREADCLAUSE=4;\nenum GCS_COMPSTR=8;\nenum GCS_COMPATTR=16;\nenum GCS_COMPCLAUSE=32;\nenum GCS_CURSORPOS=128;\nenum GCS_DELTASTART=256;\nenum GCS_RESULTREADSTR=512;\nenum GCS_RESULTREADCLAUSE=1024;\nenum GCS_RESULTSTR=2048;\nenum GCS_RESULTCLAUSE=4096;\n\nenum CS_INSERTCHAR=0x2000;\nenum CS_NOMOVECARET=0x4000;\n\nenum IMEVER_0310=0x3000A;\nenum IMEVER_0400=0x40000;\n\nenum IME_PROP_AT_CARET=0x10000;\nenum IME_PROP_SPECIAL_UI=0x20000;\nenum IME_PROP_CANDLIST_START_FROM_1=0x40000;\nenum IME_PROP_UNICODE=0x80000;\n\nenum UI_CAP_2700=1;\nenum UI_CAP_ROT90=2;\nenum UI_CAP_ROTANY=4;\n\nenum SCS_CAP_COMPSTR=1;\nenum SCS_CAP_MAKEREAD=2;\nenum SELECT_CAP_CONVERSION=1;\nenum SELECT_CAP_SENTENCE=2;\nenum GGL_LEVEL=1;\nenum GGL_INDEX=2;\nenum GGL_STRING=3;\nenum GGL_PRIVATE=4;\nenum GL_LEVEL_NOGUIDELINE=0;\nenum GL_LEVEL_FATAL=1;\nenum GL_LEVEL_ERROR=2;\nenum GL_LEVEL_WARNING=3;\nenum GL_LEVEL_INFORMATION=4;\nenum GL_ID_UNKNOWN=0;\nenum GL_ID_NOMODULE=1;\nenum GL_ID_NODICTIONARY=16;\nenum GL_ID_CANNOTSAVE=17;\nenum GL_ID_NOCONVERT=32;\nenum GL_ID_TYPINGERROR=33;\nenum GL_ID_TOOMANYSTROKE=34;\nenum GL_ID_READINGCONFLICT=35;\nenum GL_ID_INPUTREADING=36;\nenum GL_ID_INPUTRADICAL=37;\nenum GL_ID_INPUTCODE=38;\nenum GL_ID_INPUTSYMBOL=39;\nenum GL_ID_CHOOSECANDIDATE=40;\nenum GL_ID_REVERSECONVERSION=41;\nenum GL_ID_PRIVATE_FIRST=0x8000;\nenum GL_ID_PRIVATE_LAST=0xFFFF;\n\nenum DWORD IGP_GETIMEVERSION = -4;\nenum IGP_PROPERTY=4;\nenum IGP_CONVERSION=8;\nenum IGP_SENTENCE=12;\nenum IGP_UI=16;\nenum IGP_SETCOMPSTR=0x14;\nenum IGP_SELECT=0x18;\n\nenum SCS_SETSTR       = GCS_COMPREADSTR|GCS_COMPSTR;\nenum SCS_CHANGEATTR   = GCS_COMPREADATTR|GCS_COMPATTR;\nenum SCS_CHANGECLAUSE = GCS_COMPREADCLAUSE|GCS_COMPCLAUSE;\n\nenum ATTR_INPUT=0;\nenum ATTR_TARGET_CONVERTED=1;\nenum ATTR_CONVERTED=2;\nenum ATTR_TARGET_NOTCONVERTED=3;\nenum ATTR_INPUT_ERROR=4;\nenum ATTR_FIXEDCONVERTED=5;\nenum CFS_DEFAULT=0;\nenum CFS_RECT=1;\nenum CFS_POINT=2;\nenum CFS_SCREEN=4;\nenum CFS_FORCE_POSITION=32;\nenum CFS_CANDIDATEPOS=64;\nenum CFS_EXCLUDE=128;\nenum GCL_CONVERSION=1;\nenum GCL_REVERSECONVERSION=2;\nenum GCL_REVERSE_LENGTH=3;\n\nenum IME_CMODE_ALPHANUMERIC=0;\nenum IME_CMODE_NATIVE=1;\nenum IME_CMODE_CHINESE=IME_CMODE_NATIVE;\nenum IME_CMODE_HANGEUL=IME_CMODE_NATIVE;\nenum IME_CMODE_HANGUL=IME_CMODE_NATIVE;\nenum IME_CMODE_JAPANESE=IME_CMODE_NATIVE;\nenum IME_CMODE_KATAKANA=2;\nenum IME_CMODE_LANGUAGE=3;\nenum IME_CMODE_FULLSHAPE=8;\nenum IME_CMODE_ROMAN=16;\nenum IME_CMODE_CHARCODE=32;\nenum IME_CMODE_HANJACONVERT=64;\nenum IME_CMODE_SOFTKBD=128;\nenum IME_CMODE_NOCONVERSION=256;\nenum IME_CMODE_EUDC=512;\nenum IME_CMODE_SYMBOL=1024;\nenum IME_CMODE_FIXED=2048;\nenum IME_SMODE_NONE=0;\nenum IME_SMODE_PLAURALCLAUSE=1;\nenum IME_SMODE_SINGLECONVERT=2;\nenum IME_SMODE_AUTOMATIC=4;\nenum IME_SMODE_PHRASEPREDICT=8;\nenum IME_CAND_UNKNOWN=0;\nenum IME_CAND_READ=1;\nenum IME_CAND_CODE=2;\nenum IME_CAND_MEANING=3;\nenum IME_CAND_RADICAL=4;\nenum IME_CAND_STROKE=5;\nenum IMM_ERROR_NODATA=(-1);\nenum IMM_ERROR_GENERAL=(-2);\nenum IME_CONFIG_GENERAL=1;\nenum IME_CONFIG_REGISTERWORD=2;\nenum IME_CONFIG_SELECTDICTIONARY=3;\nenum IME_ESC_QUERY_SUPPORT=3;\nenum IME_ESC_RESERVED_FIRST=4;\nenum IME_ESC_RESERVED_LAST=0x7FF;\nenum IME_ESC_PRIVATE_FIRST=0x800;\nenum IME_ESC_PRIVATE_LAST=0xFFF;\nenum IME_ESC_SEQUENCE_TO_INTERNAL=0x1001;\nenum IME_ESC_GET_EUDC_DICTIONARY=0x1003;\nenum IME_ESC_SET_EUDC_DICTIONARY=0x1004;\nenum IME_ESC_MAX_KEY=0x1005;\nenum IME_ESC_IME_NAME=0x1006;\nenum IME_ESC_SYNC_HOTKEY=0x1007;\nenum IME_ESC_HANJA_MODE=0x1008;\nenum IME_ESC_AUTOMATA=0x1009;\nenum IME_REGWORD_STYLE_EUDC=1;\nenum IME_REGWORD_STYLE_USER_FIRST=0x80000000;\nenum IME_REGWORD_STYLE_USER_LAST=0xFFFFFFFF;\n\nenum SOFTKEYBOARD_TYPE_T1=1;\nenum SOFTKEYBOARD_TYPE_C1=2;\n\nenum IMEMENUITEM_STRING_SIZE=80;\n\nenum MOD_ALT=1;\nenum MOD_CONTROL=2;\nenum MOD_SHIFT=4;\nenum MOD_WIN=8;\nenum MOD_IGNORE_ALL_MODIFIER=1024;\nenum MOD_ON_KEYUP=2048;\nenum MOD_RIGHT=16384;\nenum MOD_LEFT=32768;\n\nenum IACE_CHILDREN=1;\nenum IACE_DEFAULT=16;\nenum IACE_IGNORENOCONTEXT=32;\n\nenum IGIMIF_RIGHTMENU=1;\n\nenum IGIMII_CMODE=1;\nenum IGIMII_SMODE=2;\nenum IGIMII_CONFIGURE=4;\nenum IGIMII_TOOLS=8;\nenum IGIMII_HELP=16;\nenum IGIMII_OTHER=32;\nenum IGIMII_INPUTTOOLS=64;\n\nenum IMFT_RADIOCHECK=1;\nenum IMFT_SEPARATOR=2;\nenum IMFT_SUBMENU=4;\n\nenum IMFS_GRAYED=MFS_GRAYED;\nenum IMFS_DISABLED=MFS_DISABLED;\nenum IMFS_CHECKED=MFS_CHECKED;\nenum IMFS_HILITE=MFS_HILITE;\nenum IMFS_ENABLED=MFS_ENABLED;\nenum IMFS_UNCHECKED=MFS_UNCHECKED;\nenum IMFS_UNHILITE=MFS_UNHILITE;\nenum IMFS_DEFAULT=MFS_DEFAULT;\n\nenum STYLE_DESCRIPTION_SIZE=32;\n\nalias DWORD HIMC;\nalias DWORD HIMCC;\nalias HKL* LPHKL;\n\nstruct COMPOSITIONFORM{\n    DWORD dwStyle;\n    POINT ptCurrentPos;\n    RECT rcArea;\n}\nalias COMPOSITIONFORM* PCOMPOSITIONFORM, LPCOMPOSITIONFORM;\n\nstruct CANDIDATEFORM{\n    DWORD dwIndex;\n    DWORD dwStyle;\n    POINT ptCurrentPos;\n    RECT rcArea;\n}\nalias CANDIDATEFORM* PCANDIDATEFORM, LPCANDIDATEFORM;\n\nstruct CANDIDATELIST{\n    DWORD dwSize;\n    DWORD dwStyle;\n    DWORD dwCount;\n    DWORD dwSelection;\n    DWORD dwPageStart;\n    DWORD dwPageSize;\n    DWORD[1] dwOffset;\n}\nalias CANDIDATELIST* PCANDIDATELIST, LPCANDIDATELIST;\n\nstruct REGISTERWORDA{\n    LPSTR lpReading;\n    LPSTR lpWord;\n}\nalias REGISTERWORDA* PREGISTERWORDA, LPREGISTERWORDA;\n\nstruct REGISTERWORDW{\n    LPWSTR lpReading;\n    LPWSTR lpWord;\n}\nalias REGISTERWORDW* PREGISTERWORDW, LPREGISTERWORDW;\n\nstruct STYLEBUFA{\n    DWORD dwStyle;\n    CHAR[STYLE_DESCRIPTION_SIZE] szDescription;\n}\nalias STYLEBUFA* PSTYLEBUFA, LPSTYLEBUFA;\n\nstruct STYLEBUFW{\n    DWORD dwStyle;\n    WCHAR[STYLE_DESCRIPTION_SIZE] szDescription;\n}\nalias STYLEBUFW* PSTYLEBUFW, LPSTYLEBUFW;\n\nstruct IMEMENUITEMINFOA{\n    UINT cbSize = this.sizeof;\n    UINT fType;\n    UINT fState;\n    UINT wID;\n    HBITMAP hbmpChecked;\n    HBITMAP hbmpUnchecked;\n    DWORD dwItemData;\n    CHAR[IMEMENUITEM_STRING_SIZE] szString;\n    HBITMAP hbmpItem;\n}\nalias IMEMENUITEMINFOA* PIMEMENUITEMINFOA, LPIMEMENUITEMINFOA;\n\nstruct IMEMENUITEMINFOW{\n    UINT cbSize = this.sizeof;\n    UINT fType;\n    UINT fState;\n    UINT wID;\n    HBITMAP hbmpChecked;\n    HBITMAP hbmpUnchecked;\n    DWORD dwItemData;\n    WCHAR[IMEMENUITEM_STRING_SIZE] szString;\n    HBITMAP hbmpItem;\n}\nalias IMEMENUITEMINFOW* PIMEMENUITEMINFOW, LPIMEMENUITEMINFOW;\n\nextern (Windows) {\nalias int function (LPCSTR, DWORD, LPCSTR, LPVOID)  REGISTERWORDENUMPROCA;\nalias int function (LPCWSTR, DWORD, LPCWSTR, LPVOID) REGISTERWORDENUMPROCW;\n}\n\nversion (Unicode) {\n    alias REGISTERWORDENUMPROCW REGISTERWORDENUMPROC;\n    alias REGISTERWORDW REGISTERWORD;\n    alias IMEMENUITEMINFOW IMEMENUITEMINFO;\n    alias STYLEBUFW STYLEBUF;\n} else {\n    alias REGISTERWORDENUMPROCA REGISTERWORDENUMPROC;\n    alias REGISTERWORDA REGISTERWORD;\n    alias IMEMENUITEMINFOA IMEMENUITEMINFO;\n    alias STYLEBUFA STYLEBUF;\n}\n\nalias STYLEBUF* PSTYLEBUF, LPSTYLEBUF;\nalias REGISTERWORD* PREGISTERWORD, LPREGISTERWORD;\nalias IMEMENUITEMINFO* PIMEMENUITEMINFO, LPIMEMENUITEMINFO;\n\n\nextern (Windows):\nHKL ImmInstallIMEA(LPCSTR, LPCSTR);\nHKL ImmInstallIMEW(LPCWSTR, LPCWSTR);\nHWND ImmGetDefaultIMEWnd(HWND);\nUINT ImmGetDescriptionA(HKL, LPSTR, UINT);\nUINT ImmGetDescriptionW(HKL, LPWSTR, UINT);\nUINT ImmGetIMEFileNameA(HKL, LPSTR, UINT);\nUINT ImmGetIMEFileNameW(HKL, LPWSTR, UINT);\nDWORD ImmGetProperty(HKL, DWORD);\nBOOL ImmIsIME(HKL);\nBOOL ImmSimulateHotKey(HWND, DWORD);\nHIMC ImmCreateContext();\nBOOL ImmDestroyContext(HIMC);\nHIMC ImmGetContext(HWND);\nBOOL ImmReleaseContext(HWND, HIMC);\nHIMC ImmAssociateContext(HWND, HIMC);\nLONG ImmGetCompositionStringA(HIMC, DWORD, PVOID, DWORD);\nLONG ImmGetCompositionStringW(HIMC, DWORD, PVOID, DWORD);\nBOOL ImmSetCompositionStringA(HIMC, DWORD, PCVOID, DWORD, PCVOID, DWORD);\nBOOL ImmSetCompositionStringW(HIMC, DWORD, PCVOID, DWORD, PCVOID, DWORD);\nDWORD ImmGetCandidateListCountA(HIMC, PDWORD);\nDWORD ImmGetCandidateListCountW(HIMC, PDWORD);\nDWORD ImmGetCandidateListA(HIMC, DWORD, PCANDIDATELIST, DWORD);\nDWORD ImmGetCandidateListW(HIMC, DWORD, PCANDIDATELIST, DWORD);\nDWORD ImmGetGuideLineA(HIMC, DWORD, LPSTR, DWORD);\nDWORD ImmGetGuideLineW(HIMC, DWORD, LPWSTR, DWORD);\nBOOL ImmGetConversionStatus(HIMC, LPDWORD, PDWORD);\nBOOL ImmSetConversionStatus(HIMC, DWORD, DWORD);\nBOOL ImmGetOpenStatus(HIMC);\nBOOL ImmSetOpenStatus(HIMC, BOOL);\n\nBOOL ImmGetCompositionFontA(HIMC, LPLOGFONTA);\nBOOL ImmGetCompositionFontW(HIMC, LPLOGFONTW);\nBOOL ImmSetCompositionFontA(HIMC, LPLOGFONTA);\nBOOL ImmSetCompositionFontW(HIMC, LPLOGFONTW);\n\nBOOL ImmConfigureIMEA(HKL, HWND, DWORD, PVOID);\nBOOL ImmConfigureIMEW(HKL, HWND, DWORD, PVOID);\nLRESULT ImmEscapeA(HKL, HIMC, UINT, PVOID);\nLRESULT ImmEscapeW(HKL, HIMC, UINT, PVOID);\nDWORD ImmGetConversionListA(HKL, HIMC, LPCSTR, PCANDIDATELIST, DWORD, UINT);\nDWORD ImmGetConversionListW(HKL, HIMC, LPCWSTR, PCANDIDATELIST, DWORD, UINT);\nBOOL ImmNotifyIME(HIMC, DWORD, DWORD, DWORD);\nBOOL ImmGetStatusWindowPos(HIMC, LPPOINT);\nBOOL ImmSetStatusWindowPos(HIMC, LPPOINT);\nBOOL ImmGetCompositionWindow(HIMC, PCOMPOSITIONFORM);\nBOOL ImmSetCompositionWindow(HIMC, PCOMPOSITIONFORM);\nBOOL ImmGetCandidateWindow(HIMC, DWORD, PCANDIDATEFORM);\nBOOL ImmSetCandidateWindow(HIMC, PCANDIDATEFORM);\nBOOL ImmIsUIMessageA(HWND, UINT, WPARAM, LPARAM);\nBOOL ImmIsUIMessageW(HWND, UINT, WPARAM, LPARAM);\nUINT ImmGetVirtualKey(HWND);\nBOOL ImmRegisterWordA(HKL, LPCSTR, DWORD, LPCSTR);\nBOOL ImmRegisterWordW(HKL, LPCWSTR, DWORD, LPCWSTR);\nBOOL ImmUnregisterWordA(HKL, LPCSTR, DWORD, LPCSTR);\nBOOL ImmUnregisterWordW(HKL, LPCWSTR, DWORD, LPCWSTR);\nUINT ImmGetRegisterWordStyleA(HKL, UINT, PSTYLEBUFA);\nUINT ImmGetRegisterWordStyleW(HKL, UINT, PSTYLEBUFW);\nUINT ImmEnumRegisterWordA(HKL, REGISTERWORDENUMPROCA, LPCSTR, DWORD, LPCSTR, PVOID);\nUINT ImmEnumRegisterWordW(HKL, REGISTERWORDENUMPROCW, LPCWSTR, DWORD, LPCWSTR, PVOID);\nBOOL EnableEUDC(BOOL);\nBOOL ImmDisableIME(DWORD);\nDWORD ImmGetImeMenuItemsA(HIMC, DWORD, DWORD, LPIMEMENUITEMINFOA, LPIMEMENUITEMINFOA, DWORD);\nDWORD ImmGetImeMenuItemsW(HIMC, DWORD, DWORD, LPIMEMENUITEMINFOW, LPIMEMENUITEMINFOW, DWORD);\n\nversion (Unicode) {\n    alias ImmEnumRegisterWordW ImmEnumRegisterWord;\n    alias ImmGetRegisterWordStyleW ImmGetRegisterWordStyle;\n    alias ImmUnregisterWordW ImmUnregisterWord;\n    alias ImmRegisterWordW ImmRegisterWord;\n    alias ImmInstallIMEW ImmInstallIME;\n    alias ImmIsUIMessageW ImmIsUIMessage;\n    alias ImmGetConversionListW ImmGetConversionList;\n    alias ImmEscapeW ImmEscape;\n    alias ImmConfigureIMEW ImmConfigureIME;\n    alias ImmSetCompositionFontW ImmSetCompositionFont;\n    alias ImmGetCompositionFontW ImmGetCompositionFont;\n    alias ImmGetGuideLineW ImmGetGuideLine;\n    alias ImmGetCandidateListW ImmGetCandidateList;\n    alias ImmGetCandidateListCountW ImmGetCandidateListCount;\n    alias ImmSetCompositionStringW ImmSetCompositionString;\n    alias ImmGetCompositionStringW ImmGetCompositionString;\n    alias ImmGetDescriptionW ImmGetDescription;\n    alias ImmGetIMEFileNameW ImmGetIMEFileName;\n    alias ImmGetImeMenuItemsW ImmGetImeMenuItems;\n} else {\n    alias ImmEnumRegisterWordA ImmEnumRegisterWord;\n    alias ImmGetRegisterWordStyleA ImmGetRegisterWordStyle;\n    alias ImmUnregisterWordA ImmUnregisterWord;\n    alias ImmRegisterWordA ImmRegisterWord;\n    alias ImmInstallIMEA ImmInstallIME;\n    alias ImmIsUIMessageA ImmIsUIMessage;\n    alias ImmGetConversionListA ImmGetConversionList;\n    alias ImmEscapeA ImmEscape;\n    alias ImmConfigureIMEA ImmConfigureIME;\n    alias ImmSetCompositionFontA ImmSetCompositionFont;\n    alias ImmGetCompositionFontA ImmGetCompositionFont;\n    alias ImmGetGuideLineA ImmGetGuideLine;\n    alias ImmGetCandidateListA ImmGetCandidateList;\n    alias ImmGetCandidateListCountA ImmGetCandidateListCount;\n    alias ImmSetCompositionStringA ImmSetCompositionString;\n    alias ImmGetCompositionStringA ImmGetCompositionString;\n    alias ImmGetDescriptionA ImmGetDescription;\n    alias ImmGetIMEFileNameA ImmGetIMEFileName;\n    alias ImmGetImeMenuItemsW ImmGetImeMenuItems;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/intshcut.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_intshcut.d)\n */\nmodule core.sys.windows.intshcut;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.unknwn, core.sys.windows.windef;\n\nenum : SCODE {\n    E_FLAGS                     = 0x80041000,\n      // = MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, 0x1000)\n    URL_E_INVALID_SYNTAX        = 0x80041001,\n      // = MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, 0x1001)\n    URL_E_UNREGISTERED_PROTOCOL = 0x80041002, // etc.\n    IS_E_EXEC_FAILED            = 0x80042002\n}\n\nenum IURL_SETURL_FLAGS {\n    IURL_SETURL_FL_GUESS_PROTOCOL = 1,\n    IURL_SETURL_FL_USE_DEFAULT_PROTOCOL,\n    ALL_IURL_SETURL_FLAGS\n}\n\nenum IURL_INVOKECOMMAND_FLAGS {\n    IURL_INVOKECOMMAND_FL_ALLOW_UI = 1,\n    IURL_INVOKECOMMAND_FL_USE_DEFAULT_VERB,\n    ALL_IURL_INVOKECOMMAND_FLAGS\n}\n\nenum TRANSLATEURL_IN_FLAGS {\n    TRANSLATEURL_FL_GUESS_PROTOCOL = 1,\n    TRANSLATEURL_FL_USE_DEFAULT_PROTOCOL,\n    ALL_TRANSLATEURL_FLAGS\n}\n\nenum URLASSOCIATIONDIALOG_IN_FLAGS {\n    URLASSOCDLG_FL_USE_DEFAULT_NAME = 1,\n    URLASSOCDLG_FL_REGISTER_ASSOC,\n    ALL_URLASSOCDLG_FLAGS\n}\n\nenum MIMEASSOCIATIONDIALOG_IN_FLAGS {\n    MIMEASSOCDLG_FL_REGISTER_ASSOC = 1,\n    ALL_MIMEASSOCDLG_FLAGS         = MIMEASSOCDLG_FL_REGISTER_ASSOC\n}\n\nstruct URLINVOKECOMMANDINFO {\n    DWORD dwcbSize = URLINVOKECOMMANDINFO.sizeof;\n    DWORD dwFlags;\n    HWND  hwndParent;\n    PCSTR pcszVerb;\n}\nalias URLINVOKECOMMANDINFO CURLINVOKECOMMANDINFO;\nalias URLINVOKECOMMANDINFO* PURLINVOKECOMMANDINFO, PCURLINVOKECOMMANDINFO;\n\ninterface IUniformResourceLocator : IUnknown {\n    HRESULT SetURL(PCSTR, DWORD);\n    HRESULT GetURL(PSTR*);\n    HRESULT InvokeCommand(PURLINVOKECOMMANDINFO);\n}\n//alias typeof(*(IUniformResourceLocator.init)) CIUniformResourceLocator; // value-type of interface not representable in D\nalias IUniformResourceLocator PIUniformResourceLocator,\n  PCIUniformResourceLocator;\n\nextern (Windows) {\n    BOOL InetIsOffline(DWORD);\n    HRESULT MIMEAssociationDialogA(HWND, DWORD, PCSTR, PCSTR, PSTR, UINT);\n    HRESULT MIMEAssociationDialogW(HWND, DWORD, PCWSTR, PCWSTR, PWSTR, UINT);\n    HRESULT TranslateURLA(PCSTR, DWORD, PSTR*);\n    HRESULT TranslateURLW(PCWSTR, DWORD, PWSTR*);\n    HRESULT URLAssociationDialogA(HWND, DWORD, PCSTR, PCSTR, PSTR, UINT);\n    HRESULT URLAssociationDialogW(HWND, DWORD, PCWSTR, PCWSTR, PWSTR, UINT);\n}\n\nversion (Unicode) {\n    alias TranslateURLW TranslateURL;\n    alias MIMEAssociationDialogW MIMEAssociationDialog;\n    alias URLAssociationDialogW URLAssociationDialog;\n} else {\n    alias TranslateURLA TranslateURL;\n    alias MIMEAssociationDialogA MIMEAssociationDialog;\n    alias URLAssociationDialogA URLAssociationDialog;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ipexport.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ipexport.d)\n */\nmodule core.sys.windows.ipexport;\nversion (Windows):\n\nprivate import core.sys.windows.windef;\n\nenum size_t MAX_ADAPTER_NAME = 128;\n\n// IP STATUS flags\nenum : IP_STATUS {\n    IP_SUCCESS         =     0,\n    IP_STATUS_BASE     = 11000,\n    IP_BUF_TOO_SMALL,\n    IP_DEST_NET_UNREACHABLE,\n    IP_DEST_HOST_UNREACHABLE,\n    IP_DEST_PROT_UNREACHABLE,\n    IP_DEST_PORT_UNREACHABLE,\n    IP_NO_RESOURCES,\n    IP_BAD_OPTION,\n    IP_HW_ERROR,\n    IP_PACKET_TOO_BIG,\n    IP_REQ_TIMED_OUT,\n    IP_BAD_REQ,\n    IP_BAD_ROUTE,\n    IP_TTL_EXPIRED_TRANSIT,\n    IP_TTL_EXPIRED_REASSEM,\n    IP_PARAM_PROBLEM,\n    IP_SOURCE_QUENCH,\n    IP_OPTION_TOO_BIG,\n    IP_BAD_DESTINATION,\n    IP_ADDR_DELETED,\n    IP_SPEC_MTU_CHANGE,\n    IP_MTU_CHANGE,\n    IP_UNLOAD,      // = IP_STATUS_BASE + 22\n    IP_GENERAL_FAILURE = IP_STATUS_BASE + 50,\n    MAX_IP_STATUS      = IP_GENERAL_FAILURE,\n    IP_PENDING         = IP_STATUS_BASE + 255\n}\n\n// IP header Flags values\nenum byte IP_FLAG_DF = 2;\n\n// IP Option types\nenum : ubyte {\n    IP_OPT_EOL          = 0,\n    IP_OPT_NOP          = 0x01,\n    IP_OPT_RR           = 0x07,\n    IP_OPT_SECURITY     = 0x82,\n    IP_OPT_LSRR         = 0x83,\n    IP_OPT_SSRR         = 0x89,\n    IP_OPT_TS           = 0x44,\n    IP_OPT_SID          = 0x88,\n    IP_OPT_ROUTER_ALERT = 0x94\n}\n\nenum ubyte MAX_OPT_SIZE = 40;\n\nalias uint IPAddr, IPMask, IP_STATUS;\n\nstruct IP_OPTION_INFORMATION {\n    ubyte  Ttl;\n    ubyte  Tos;\n    ubyte  Flags;\n    ubyte  OptionsSize;\n    ubyte* OptionsData;\n}\nalias IP_OPTION_INFORMATION* PIP_OPTION_INFORMATION;\n\nstruct ICMP_ECHO_REPLY {\n  IPAddr Address;\n  uint   Status;\n  uint   RoundTripTime;\n  ushort DataSize;\n  ushort Reserved;\n  void*  Data;\n  IP_OPTION_INFORMATION Options;\n}\nalias ICMP_ECHO_REPLY* PICMP_ECHO_REPLY;\n\nstruct IP_ADAPTER_INDEX_MAP {\n    ULONG                   Index;\n    WCHAR[MAX_ADAPTER_NAME] Name;\n}\nalias IP_ADAPTER_INDEX_MAP* PIP_ADAPTER_INDEX_MAP;\n\nstruct IP_INTERFACE_INFO {\n    LONG                    NumAdapters;\n    IP_ADAPTER_INDEX_MAP[1] _Adapter;\n\n    IP_ADAPTER_INDEX_MAP* Adapter() return { return _Adapter.ptr; }\n}\nalias IP_INTERFACE_INFO* PIP_INTERFACE_INFO;\n\nstruct IP_UNIDIRECTIONAL_ADAPTER_ADDRESS {\n    ULONG     NumAdapters;\n    IPAddr[1] _Address;\n\n    IPAddr* Address() return { return _Address.ptr; }\n}\nalias IP_UNIDIRECTIONAL_ADAPTER_ADDRESS* PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/iphlpapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_iphlpapi.d)\n */\nmodule core.sys.windows.iphlpapi;\nversion (Windows):\n\nimport core.sys.windows.ipexport, core.sys.windows.iprtrmib, core.sys.windows.iptypes;\nprivate import core.sys.windows.winbase, core.sys.windows.windef;\n\nextern (Windows) {\n    DWORD AddIPAddress(IPAddr, IPMask, DWORD, PULONG, PULONG);\n    DWORD CreateIpForwardEntry(PMIB_IPFORWARDROW);\n    DWORD CreateIpNetEntry(PMIB_IPNETROW);\n    DWORD CreateProxyArpEntry(DWORD, DWORD, DWORD);\n    DWORD DeleteIPAddress(ULONG);\n    DWORD DeleteIpForwardEntry(PMIB_IPFORWARDROW);\n    DWORD DeleteIpNetEntry(PMIB_IPNETROW);\n    DWORD DeleteProxyArpEntry(DWORD, DWORD, DWORD);\n    DWORD EnableRouter(HANDLE*, OVERLAPPED*);\n    DWORD FlushIpNetTable(DWORD);\n    DWORD GetAdapterIndex(LPWSTR, PULONG);\n    DWORD GetAdaptersInfo(PIP_ADAPTER_INFO, PULONG);\n    DWORD GetBestInterface(IPAddr, PDWORD);\n    DWORD GetBestRoute(DWORD, DWORD, PMIB_IPFORWARDROW);\n    DWORD GetFriendlyIfIndex(DWORD);\n    DWORD GetIcmpStatistics(PMIB_ICMP);\n    DWORD GetIfEntry(PMIB_IFROW);\n    DWORD GetIfTable(PMIB_IFTABLE, PULONG, BOOL);\n    DWORD GetInterfaceInfo(PIP_INTERFACE_INFO, PULONG);\n    DWORD GetIpAddrTable(PMIB_IPADDRTABLE, PULONG, BOOL);\n    DWORD GetIpForwardTable(PMIB_IPFORWARDTABLE, PULONG, BOOL);\n    DWORD GetIpNetTable(PMIB_IPNETTABLE, PULONG, BOOL);\n    DWORD GetIpStatistics(PMIB_IPSTATS);\n    DWORD GetNetworkParams(PFIXED_INFO, PULONG);\n    DWORD GetNumberOfInterfaces(PDWORD);\n    DWORD GetPerAdapterInfo(ULONG, PIP_PER_ADAPTER_INFO, PULONG);\n    BOOL GetRTTAndHopCount(IPAddr, PULONG, ULONG, PULONG);\n    DWORD GetTcpStatistics(PMIB_TCPSTATS);\n    DWORD GetTcpTable(PMIB_TCPTABLE, PDWORD, BOOL);\n    DWORD GetUniDirectionalAdapterInfo(PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS,\n      PULONG);\n    DWORD GetUdpStatistics(PMIB_UDPSTATS);\n    DWORD GetUdpTable(PMIB_UDPTABLE, PDWORD, BOOL);\n    DWORD IpReleaseAddress(PIP_ADAPTER_INDEX_MAP);\n    DWORD IpRenewAddress(PIP_ADAPTER_INDEX_MAP);\n    DWORD NotifyAddrChange(PHANDLE, LPOVERLAPPED);\n    DWORD NotifyRouteChange(PHANDLE, LPOVERLAPPED);\n    DWORD SendARP(IPAddr, IPAddr, PULONG, PULONG);\n    DWORD SetIfEntry(PMIB_IFROW);\n    DWORD SetIpForwardEntry(PMIB_IPFORWARDROW);\n    DWORD SetIpNetEntry(PMIB_IPNETROW);\n    DWORD SetIpStatistics(PMIB_IPSTATS);\n    DWORD SetIpTTL(UINT);\n    DWORD SetTcpEntry(PMIB_TCPROW);\n    DWORD UnenableRouter(OVERLAPPED*, LPDWORD);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ipifcons.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ipifcons.d)\n */\nmodule core.sys.windows.ipifcons;\nversion (Windows):\n\n// FIXME: check types of constants\n\nenum {\n    MIB_IF_ADMIN_STATUS_UP = 1,\n    MIB_IF_ADMIN_STATUS_DOWN,\n    MIB_IF_ADMIN_STATUS_TESTING,\n}\n\nenum {\n    MIB_IF_OPER_STATUS_NON_OPERATIONAL,\n    MIB_IF_OPER_STATUS_UNREACHABLE,\n    MIB_IF_OPER_STATUS_DISCONNECTED,\n    MIB_IF_OPER_STATUS_CONNECTING,\n    MIB_IF_OPER_STATUS_CONNECTED,\n    MIB_IF_OPER_STATUS_OPERATIONAL // = 5\n}\n\nenum {\n    MIB_IF_TYPE_OTHER     =  1,\n    MIB_IF_TYPE_ETHERNET  =  6,\n    MIB_IF_TYPE_TOKENRING =  9,\n    MIB_IF_TYPE_FDDI      = 15,\n    MIB_IF_TYPE_PPP       = 23,\n    MIB_IF_TYPE_LOOPBACK  = 24,\n    MIB_IF_TYPE_SLIP      = 28\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/iprtrmib.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_iprtrmib.d)\n */\nmodule core.sys.windows.iprtrmib;\nversion (Windows):\n\nimport core.sys.windows.ipifcons;\nprivate import core.sys.windows.windef;\n\n// FIXME: check types of constants\n\nenum size_t\n    MAXLEN_PHYSADDR        =   8,\n    MAXLEN_IFDESCR         = 256,\n    MAX_INTERFACE_NAME_LEN = 256;\n\nenum {\n    MIB_IPNET_TYPE_OTHER = 1,\n    MIB_IPNET_TYPE_INVALID,\n    MIB_IPNET_TYPE_DYNAMIC,\n    MIB_IPNET_TYPE_STATIC\n}\n\nenum {\n    MIB_TCP_RTO_OTHER = 1,\n    MIB_TCP_RTO_CONSTANT,\n    MIB_TCP_RTO_RSRE,\n    MIB_TCP_RTO_VANJ\n}\n\nenum {\n    MIB_TCP_STATE_CLOSED = 1,\n    MIB_TCP_STATE_LISTEN,\n    MIB_TCP_STATE_SYN_SENT,\n    MIB_TCP_STATE_SYN_RCVD,\n    MIB_TCP_STATE_ESTAB,\n    MIB_TCP_STATE_FIN_WAIT1,\n    MIB_TCP_STATE_FIN_WAIT2,\n    MIB_TCP_STATE_CLOSE_WAIT,\n    MIB_TCP_STATE_CLOSING,\n    MIB_TCP_STATE_LAST_ACK,\n    MIB_TCP_STATE_TIME_WAIT,\n    MIB_TCP_STATE_DELETE_TCB // = 12\n}\n\nenum DWORD\n    MIB_USE_CURRENT_TTL        = -1,\n    MIB_USE_CURRENT_FORWARDING = -1,\n    MIB_TCP_MAXCONN_DYNAMIC    = -1;\n\nstruct MIB_IPADDRROW {\n    DWORD  dwAddr;\n    DWORD  dwIndex;\n    DWORD  dwMask;\n    DWORD  dwBCastAddr;\n    DWORD  dwReasmSize;\n    ushort unused1;\n    ushort unused2;\n}\nalias MIB_IPADDRROW* PMIB_IPADDRROW;\n\nstruct MIB_IPADDRTABLE {\n    DWORD            dwNumEntries;\n    MIB_IPADDRROW[1] _table;\n\n    MIB_IPADDRROW* table() return { return _table.ptr; }\n}\nalias MIB_IPADDRTABLE* PMIB_IPADDRTABLE;\n\nstruct MIB_IPFORWARDROW {\n    DWORD dwForwardDest;\n    DWORD dwForwardMask;\n    DWORD dwForwardPolicy;\n    DWORD dwForwardNextHop;\n    DWORD dwForwardIfIndex;\n    DWORD dwForwardType;\n    DWORD dwForwardProto;\n    DWORD dwForwardAge;\n    DWORD dwForwardNextHopAS;\n    DWORD dwForwardMetric1;\n    DWORD dwForwardMetric2;\n    DWORD dwForwardMetric3;\n    DWORD dwForwardMetric4;\n    DWORD dwForwardMetric5;\n}\nalias MIB_IPFORWARDROW* PMIB_IPFORWARDROW;\n\nstruct MIB_IPFORWARDTABLE {\n    DWORD               dwNumEntries;\n    MIB_IPFORWARDROW[1] _table;\n\n    MIB_IPFORWARDROW* table() return { return _table.ptr; }\n}\nalias MIB_IPFORWARDTABLE* PMIB_IPFORWARDTABLE;\n\nstruct MIB_IPNETROW {\n    DWORD dwIndex;\n    DWORD dwPhysAddrLen;\n    BYTE[MAXLEN_PHYSADDR] bPhysAddr;\n    DWORD dwAddr;\n    DWORD dwType;\n}\nalias MIB_IPNETROW* PMIB_IPNETROW;\n\nstruct MIB_IPNETTABLE {\n    DWORD           dwNumEntries;\n    MIB_IPNETROW[1] _table;\n\n    MIB_IPNETROW* table() return { return _table.ptr; }\n}\nalias MIB_IPNETTABLE* PMIB_IPNETTABLE;\n\nstruct MIBICMPSTATS {\n    DWORD dwMsgs;\n    DWORD dwErrors;\n    DWORD dwDestUnreachs;\n    DWORD dwTimeExcds;\n    DWORD dwParmProbs;\n    DWORD dwSrcQuenchs;\n    DWORD dwRedirects;\n    DWORD dwEchos;\n    DWORD dwEchoReps;\n    DWORD dwTimestamps;\n    DWORD dwTimestampReps;\n    DWORD dwAddrMasks;\n    DWORD dwAddrMaskReps;\n}\nalias MIBICMPSTATS* PMIBICMPSTATS;\n\nstruct MIBICMPINFO {\n    MIBICMPSTATS icmpInStats;\n    MIBICMPSTATS icmpOutStats;\n}\nalias MIBICMPINFO* PMIBICMPINFO;\n\nstruct MIB_ICMP {\n    MIBICMPINFO stats;\n}\nalias MIB_ICMP* PMIB_ICMP;\n\nstruct MIB_IFROW {\n    WCHAR[MAX_INTERFACE_NAME_LEN] wszName;\n    DWORD dwIndex;\n    DWORD dwType;\n    DWORD dwMtu;\n    DWORD dwSpeed;\n    DWORD dwPhysAddrLen;\n    BYTE[MAXLEN_PHYSADDR] bPhysAddr;\n    DWORD dwAdminStatus;\n    DWORD dwOperStatus;\n    DWORD dwLastChange;\n    DWORD dwInOctets;\n    DWORD dwInUcastPkts;\n    DWORD dwInNUcastPkts;\n    DWORD dwInDiscards;\n    DWORD dwInErrors;\n    DWORD dwInUnknownProtos;\n    DWORD dwOutOctets;\n    DWORD dwOutUcastPkts;\n    DWORD dwOutNUcastPkts;\n    DWORD dwOutDiscards;\n    DWORD dwOutErrors;\n    DWORD dwOutQLen;\n    DWORD dwDescrLen;\n    BYTE[MAXLEN_IFDESCR] bDescr;\n}\nalias MIB_IFROW* PMIB_IFROW;\n\nstruct MIB_IFTABLE {\n    DWORD        dwNumEntries;\n    MIB_IFROW[1] _table;\n\n    MIB_IFROW* table() return { return _table.ptr; }\n}\nalias MIB_IFTABLE* PMIB_IFTABLE;\n\nstruct MIB_IPSTATS {\n    DWORD dwForwarding;\n    DWORD dwDefaultTTL;\n    DWORD dwInReceives;\n    DWORD dwInHdrErrors;\n    DWORD dwInAddrErrors;\n    DWORD dwForwDatagrams;\n    DWORD dwInUnknownProtos;\n    DWORD dwInDiscards;\n    DWORD dwInDelivers;\n    DWORD dwOutRequests;\n    DWORD dwRoutingDiscards;\n    DWORD dwOutDiscards;\n    DWORD dwOutNoRoutes;\n    DWORD dwReasmTimeout;\n    DWORD dwReasmReqds;\n    DWORD dwReasmOks;\n    DWORD dwReasmFails;\n    DWORD dwFragOks;\n    DWORD dwFragFails;\n    DWORD dwFragCreates;\n    DWORD dwNumIf;\n    DWORD dwNumAddr;\n    DWORD dwNumRoutes;\n}\nalias MIB_IPSTATS* PMIB_IPSTATS;\n\nstruct MIB_TCPSTATS {\n    DWORD dwRtoAlgorithm;\n    DWORD dwRtoMin;\n    DWORD dwRtoMax;\n    DWORD dwMaxConn;\n    DWORD dwActiveOpens;\n    DWORD dwPassiveOpens;\n    DWORD dwAttemptFails;\n    DWORD dwEstabResets;\n    DWORD dwCurrEstab;\n    DWORD dwInSegs;\n    DWORD dwOutSegs;\n    DWORD dwRetransSegs;\n    DWORD dwInErrs;\n    DWORD dwOutRsts;\n    DWORD dwNumConns;\n}\nalias MIB_TCPSTATS* PMIB_TCPSTATS;\n\nstruct MIB_TCPROW {\n    DWORD dwState;\n    DWORD dwLocalAddr;\n    DWORD dwLocalPort;\n    DWORD dwRemoteAddr;\n    DWORD dwRemotePort;\n}\nalias MIB_TCPROW* PMIB_TCPROW;\n\nstruct MIB_TCPTABLE {\n    DWORD         dwNumEntries;\n    MIB_TCPROW[1] _table;\n\n    MIB_TCPROW* table() return { return _table.ptr; }\n}\nalias MIB_TCPTABLE* PMIB_TCPTABLE;\n\nstruct MIB_UDPSTATS {\n    DWORD dwInDatagrams;\n    DWORD dwNoPorts;\n    DWORD dwInErrors;\n    DWORD dwOutDatagrams;\n    DWORD dwNumAddrs;\n}\nalias MIB_UDPSTATS* PMIB_UDPSTATS;\n\nstruct MIB_UDPROW {\n    DWORD dwLocalAddr;\n    DWORD dwLocalPort;\n}\nalias MIB_UDPROW* PMIB_UDPROW;\n\nstruct MIB_UDPTABLE {\n    DWORD         dwNumEntries;\n    MIB_UDPROW[1] _table;\n\n    MIB_UDPROW* table() return { return _table.ptr; }\n}\nalias MIB_UDPTABLE* PMIB_UDPTABLE;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/iptypes.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_iptypes.d)\n */\nmodule core.sys.windows.iptypes;\nversion (Windows):\n\nimport core.sys.windows.windef;\nimport core.stdc.time;\n//#include <sys/types.h>\n\nenum size_t\n    DEFAULT_MINIMUM_ENTITIES       =  32,\n    MAX_ADAPTER_ADDRESS_LENGTH     =   8,\n    MAX_ADAPTER_DESCRIPTION_LENGTH = 128,\n    MAX_ADAPTER_NAME_LENGTH        = 256,\n    MAX_DOMAIN_NAME_LEN            = 128,\n    MAX_HOSTNAME_LEN               = 128,\n    MAX_SCOPE_ID_LEN               = 256;\n\nenum UINT\n    BROADCAST_NODETYPE    = 1,\n    PEER_TO_PEER_NODETYPE = 2,\n    MIXED_NODETYPE        = 4,\n    HYBRID_NODETYPE       = 8;\n\nenum : UINT {\n    IF_OTHER_ADAPTERTYPE,\n    IF_ETHERNET_ADAPTERTYPE,\n    IF_TOKEN_RING_ADAPTERTYPE,\n    IF_FDDI_ADAPTERTYPE,\n    IF_PPP_ADAPTERTYPE,\n    IF_LOOPBACK_ADAPTERTYPE // = 5\n}\n\nstruct IP_ADDRESS_STRING {\n    char[16] String;\n}\nalias IP_ADDRESS_STRING IP_MASK_STRING;\nalias IP_ADDRESS_STRING* PIP_ADDRESS_STRING, PIP_MASK_STRING;\n\nstruct IP_ADDR_STRING {\n    IP_ADDR_STRING*   Next;\n    IP_ADDRESS_STRING IpAddress;\n    IP_MASK_STRING    IpMask;\n    DWORD             Context;\n}\nalias IP_ADDR_STRING* PIP_ADDR_STRING;\n\nstruct IP_ADAPTER_INFO {\n    IP_ADAPTER_INFO* Next;\n    DWORD ComboIndex;\n    char[MAX_ADAPTER_NAME_LENGTH+4]        AdapterName;\n    char[MAX_ADAPTER_DESCRIPTION_LENGTH+4] Description;\n    UINT             AddressLength;\n    BYTE[MAX_ADAPTER_ADDRESS_LENGTH]       Address;\n    DWORD            Index;\n    UINT             Type;\n    UINT             DhcpEnabled;\n    PIP_ADDR_STRING  CurrentIpAddress;\n    IP_ADDR_STRING   IpAddressList;\n    IP_ADDR_STRING   GatewayList;\n    IP_ADDR_STRING   DhcpServer;\n    BOOL             HaveWins;\n    IP_ADDR_STRING   PrimaryWinsServer;\n    IP_ADDR_STRING   SecondaryWinsServer;\n    time_t           LeaseObtained;\n    time_t           LeaseExpires;\n}\nalias IP_ADAPTER_INFO* PIP_ADAPTER_INFO;\n\nstruct IP_PER_ADAPTER_INFO {\n    UINT AutoconfigEnabled;\n    UINT AutoconfigActive;\n    PIP_ADDR_STRING CurrentDnsServer;\n    IP_ADDR_STRING DnsServerList;\n}\nalias IP_PER_ADAPTER_INFO* PIP_PER_ADAPTER_INFO;\n\nstruct FIXED_INFO {\n    char[MAX_HOSTNAME_LEN+4]    HostName;\n    char[MAX_DOMAIN_NAME_LEN+4] DomainName;\n    PIP_ADDR_STRING             CurrentDnsServer;\n    IP_ADDR_STRING              DnsServerList;\n    UINT                        NodeType;\n    char[MAX_SCOPE_ID_LEN+4]    ScopeId;\n    UINT                        EnableRouting;\n    UINT                        EnableProxy;\n    UINT                        EnableDns;\n}\nalias FIXED_INFO* PFIXED_INFO;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/isguids.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.10\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_isguids.d)\n */\nmodule core.sys.windows.isguids;\nversion (Windows):\n\nprivate import core.sys.windows.basetyps;\n\nextern (C) extern const GUID\n    CLSID_InternetShortcut,\n    IID_IUniformResourceLocator;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lm.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lm.d)\n */\nmodule core.sys.windows.lm;\nversion (Windows):\n/* removed - now supporting only Win2k up\nversion (WindowsVista) {\n    version = WIN32_WINNT_ONLY;\n} else version (Windows2003) {\n    version = WIN32_WINNT_ONLY;\n} else version (WindowsXP) {\n    version = WIN32_WINNT_ONLY;\n} else version (WindowsNTonly) {\n    version = WIN32_WINNT_ONLY;\n}\n*/\npublic import core.sys.windows.lmcons;\npublic import core.sys.windows.lmaccess;\npublic import core.sys.windows.lmalert;\npublic import core.sys.windows.lmat;\npublic import core.sys.windows.lmerr;\npublic import core.sys.windows.lmshare;\npublic import core.sys.windows.lmapibuf;\npublic import core.sys.windows.lmremutl;\npublic import core.sys.windows.lmrepl;\npublic import core.sys.windows.lmuse;\npublic import core.sys.windows.lmstats;\npublic import core.sys.windows.lmwksta;\npublic import core.sys.windows.lmserver;\n\nversion (Windows2000) {\n} else {\n    public import core.sys.windows.lmmsg;\n}\n\n// FIXME: Everything in these next files seems to be deprecated!\nimport core.sys.windows.lmaudit;\nimport core.sys.windows.lmchdev; // can't find many docs for functions from this file.\nimport core.sys.windows.lmconfig;\nimport core.sys.windows.lmerrlog;\nimport core.sys.windows.lmsvc;\nimport core.sys.windows.lmsname; // in MinGW, this was publicly included by lm.lmsvc\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmaccess.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmaccess.d)\n */\nmodule core.sys.windows.lmaccess;\nversion (Windows):\npragma(lib, \"netapi32\");\n\n/**\n Changes relative to MinGW:\n    USER_POSIX_ID_PARMNUM and GROUP_POSIX_ID_PARMNUM aren't in MinGW or in\n    the Platform SDK docs, so they have been dropped from this file.\n*/\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nconst wchar[]\n    GROUP_SPECIALGRP_USERS  = \"USERS\",\n    GROUP_SPECIALGRP_ADMINS = \"ADMINS\",\n    GROUP_SPECIALGRP_GUESTS = \"GUESTS\",\n    GROUP_SPECIALGRP_LOCAL  = \"LOCAL\";\n\nenum ACCESS_LETTERS = \"RWCXDAP \";\n\nenum NETLOGON_CONTROL_QUERY=1;\nenum NETLOGON_CONTROL_REPLICATE=2;\nenum NETLOGON_CONTROL_SYNCHRONIZE=3;\nenum NETLOGON_CONTROL_PDC_REPLICATE=4;\nenum NETLOGON_CONTROL_REDISCOVER=5;\nenum NETLOGON_CONTROL_TC_QUERY=6;\nenum NETLOGON_CONTROL_BACKUP_CHANGE_LOG=65532;\nenum NETLOGON_CONTROL_TRUNCATE_LOG=65533;\nenum NETLOGON_CONTROL_SET_DBFLAG=65534;\nenum NETLOGON_CONTROL_BREAKPOINT=65535;\n\nenum UF_SCRIPT=1;\nenum UF_ACCOUNTDISABLE=2;\nenum UF_HOMEDIR_REQUIRED=8;\nenum UF_LOCKOUT=16;\nenum UF_PASSWD_NOTREQD=32;\nenum UF_PASSWD_CANT_CHANGE=64;\nenum UF_TEMP_DUPLICATE_ACCOUNT=256;\nenum UF_NORMAL_ACCOUNT=512;\nenum UF_INTERDOMAIN_TRUST_ACCOUNT=2048;\nenum UF_WORKSTATION_TRUST_ACCOUNT=4096;\nenum UF_SERVER_TRUST_ACCOUNT=8192;\nenum UF_MNS_LOGON_ACCOUNT=131072;\nenum UF_MACHINE_ACCOUNT_MASK=UF_INTERDOMAIN_TRUST_ACCOUNT|UF_WORKSTATION_TRUST_ACCOUNT|UF_SERVER_TRUST_ACCOUNT;\nenum UF_ACCOUNT_TYPE_MASK=UF_TEMP_DUPLICATE_ACCOUNT|UF_NORMAL_ACCOUNT|UF_INTERDOMAIN_TRUST_ACCOUNT|UF_WORKSTATION_TRUST_ACCOUNT|UF_SERVER_TRUST_ACCOUNT;\nenum UF_DONT_EXPIRE_PASSWD=65536;\nenum UF_SETTABLE_BITS=UF_SCRIPT|UF_ACCOUNTDISABLE|UF_LOCKOUT|UF_HOMEDIR_REQUIRED|UF_PASSWD_NOTREQD|UF_PASSWD_CANT_CHANGE|UF_ACCOUNT_TYPE_MASK|UF_DONT_EXPIRE_PASSWD;\n\nenum FILTER_TEMP_DUPLICATE_ACCOUNT=1;\nenum FILTER_NORMAL_ACCOUNT=2;\nenum FILTER_INTERDOMAIN_TRUST_ACCOUNT=8;\nenum FILTER_WORKSTATION_TRUST_ACCOUNT=16;\nenum FILTER_SERVER_TRUST_ACCOUNT=32;\n\nenum LG_INCLUDE_INDIRECT=1;\n\nenum AF_OP_PRINT=1;\nenum AF_OP_COMM=2;\nenum AF_OP_SERVER=4;\nenum AF_OP_ACCOUNTS=8;\nenum AF_SETTABLE_BITS=(AF_OP_PRINT|AF_OP_COMM|AF_OP_SERVER|AF_OP_ACCOUNTS);\n\nenum UAS_ROLE_STANDALONE=0;\nenum UAS_ROLE_MEMBER=1;\nenum UAS_ROLE_BACKUP=2;\nenum UAS_ROLE_PRIMARY=3;\n\nenum USER_NAME_PARMNUM=1;\nenum USER_PASSWORD_PARMNUM=3;\nenum USER_PASSWORD_AGE_PARMNUM=4;\nenum USER_PRIV_PARMNUM=5;\nenum USER_HOME_DIR_PARMNUM=6;\nenum USER_COMMENT_PARMNUM=7;\nenum USER_FLAGS_PARMNUM=8;\nenum USER_SCRIPT_PATH_PARMNUM=9;\nenum USER_AUTH_FLAGS_PARMNUM=10;\nenum USER_FULL_NAME_PARMNUM=11;\nenum USER_USR_COMMENT_PARMNUM=12;\nenum USER_PARMS_PARMNUM=13;\nenum USER_WORKSTATIONS_PARMNUM=14;\nenum USER_LAST_LOGON_PARMNUM=15;\nenum USER_LAST_LOGOFF_PARMNUM=16;\nenum USER_ACCT_EXPIRES_PARMNUM=17;\nenum USER_MAX_STORAGE_PARMNUM=18;\nenum USER_UNITS_PER_WEEK_PARMNUM=19;\nenum USER_LOGON_HOURS_PARMNUM=20;\nenum USER_PAD_PW_COUNT_PARMNUM=21;\nenum USER_NUM_LOGONS_PARMNUM=22;\nenum USER_LOGON_SERVER_PARMNUM=23;\nenum USER_COUNTRY_CODE_PARMNUM=24;\nenum USER_CODE_PAGE_PARMNUM=25;\nenum USER_PRIMARY_GROUP_PARMNUM=51;\nenum USER_PROFILE=52;\nenum USER_PROFILE_PARMNUM=52;\nenum USER_HOME_DIR_DRIVE_PARMNUM=53;\n\nenum USER_NAME_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_NAME_PARMNUM;\nenum USER_PASSWORD_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_PASSWORD_PARMNUM;\nenum USER_PASSWORD_AGE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_PASSWORD_AGE_PARMNUM;\nenum USER_PRIV_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_PRIV_PARMNUM;\nenum USER_HOME_DIR_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_HOME_DIR_PARMNUM;\nenum USER_COMMENT_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_COMMENT_PARMNUM;\nenum USER_FLAGS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_FLAGS_PARMNUM;\nenum USER_SCRIPT_PATH_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_SCRIPT_PATH_PARMNUM;\nenum USER_AUTH_FLAGS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_AUTH_FLAGS_PARMNUM;\nenum USER_FULL_NAME_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_FULL_NAME_PARMNUM;\nenum USER_USR_COMMENT_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_USR_COMMENT_PARMNUM;\nenum USER_PARMS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_PARMS_PARMNUM;\nenum USER_WORKSTATIONS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_WORKSTATIONS_PARMNUM;\nenum USER_LAST_LOGON_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_LAST_LOGON_PARMNUM;\nenum USER_LAST_LOGOFF_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_LAST_LOGOFF_PARMNUM;\nenum USER_ACCT_EXPIRES_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_ACCT_EXPIRES_PARMNUM;\nenum USER_MAX_STORAGE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_MAX_STORAGE_PARMNUM;\nenum USER_UNITS_PER_WEEK_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_UNITS_PER_WEEK_PARMNUM;\nenum USER_LOGON_HOURS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_LOGON_HOURS_PARMNUM;\nenum USER_PAD_PW_COUNT_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_PAD_PW_COUNT_PARMNUM;\nenum USER_NUM_LOGONS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_NUM_LOGONS_PARMNUM;\nenum USER_LOGON_SERVER_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_LOGON_SERVER_PARMNUM;\nenum USER_COUNTRY_CODE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_COUNTRY_CODE_PARMNUM;\nenum USER_CODE_PAGE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_CODE_PAGE_PARMNUM;\nenum USER_PRIMARY_GROUP_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_PRIMARY_GROUP_PARMNUM;\n// USER_POSIX_ID_PARMNUM isn't in MinGW or in the Platform SDK docs.\n//const USER_POSIX_ID_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_POSIX_ID_PARMNUM;\nenum USER_HOME_DIR_DRIVE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+USER_HOME_DIR_DRIVE_PARMNUM;\n\nenum NULL_USERSETINFO_PASSWD=\" \";\nenum ULONG TIMEQ_FOREVER=-1;\nenum ULONG USER_MAXSTORAGE_UNLIMITED=-1;\nenum ULONG USER_NO_LOGOFF=-1;\nenum UNITS_PER_DAY=24;\nenum UNITS_PER_WEEK=168;\nenum USER_PRIV_MASK=3;\nenum USER_PRIV_GUEST=0;\nenum USER_PRIV_USER=1;\nenum USER_PRIV_ADMIN=2;\nenum MAX_PASSWD_LEN=PWLEN;\nenum DEF_MIN_PWLEN=6;\nenum DEF_PWUNIQUENESS=5;\nenum DEF_MAX_PWHIST=8;\nenum DEF_MAX_PWAGE=TIMEQ_FOREVER;\nenum DEF_MIN_PWAGE=0;\nenum ULONG DEF_FORCE_LOGOFF=0xffffffff;\nenum DEF_MAX_BADPW=0;\nenum ONE_DAY=86400;\nenum VALIDATED_LOGON=0;\nenum PASSWORD_EXPIRED=2;\nenum NON_VALIDATED_LOGON=3;\nenum VALID_LOGOFF=1;\n\nenum MODALS_MIN_PASSWD_LEN_PARMNUM=1;\nenum MODALS_MAX_PASSWD_AGE_PARMNUM=2;\nenum MODALS_MIN_PASSWD_AGE_PARMNUM=3;\nenum MODALS_FORCE_LOGOFF_PARMNUM=4;\nenum MODALS_PASSWD_HIST_LEN_PARMNUM=5;\nenum MODALS_ROLE_PARMNUM=6;\nenum MODALS_PRIMARY_PARMNUM=7;\nenum MODALS_DOMAIN_NAME_PARMNUM=8;\nenum MODALS_DOMAIN_ID_PARMNUM=9;\nenum MODALS_LOCKOUT_DURATION_PARMNUM=10;\nenum MODALS_LOCKOUT_OBSERVATION_WINDOW_PARMNUM=11;\nenum MODALS_LOCKOUT_THRESHOLD_PARMNUM=12;\n\nenum MODALS_MIN_PASSWD_LEN_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+MODALS_MIN_PASSWD_LEN_PARMNUM);\nenum MODALS_MAX_PASSWD_AGE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+MODALS_MAX_PASSWD_AGE_PARMNUM);\nenum MODALS_MIN_PASSWD_AGE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+MODALS_MIN_PASSWD_AGE_PARMNUM);\nenum MODALS_FORCE_LOGOFF_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+MODALS_FORCE_LOGOFF_PARMNUM);\nenum MODALS_PASSWD_HIST_LEN_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+MODALS_PASSWD_HIST_LEN_PARMNUM);\nenum MODALS_ROLE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+MODALS_ROLE_PARMNUM);\nenum MODALS_PRIMARY_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+MODALS_PRIMARY_PARMNUM);\nenum MODALS_DOMAIN_NAME_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+MODALS_DOMAIN_NAME_PARMNUM);\nenum MODALS_DOMAIN_ID_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+MODALS_DOMAIN_ID_PARMNUM);\n\nenum GROUPIDMASK=0x8000;\nenum GROUP_ALL_PARMNUM=0;\nenum GROUP_NAME_PARMNUM=1;\nenum GROUP_COMMENT_PARMNUM=2;\nenum GROUP_ATTRIBUTES_PARMNUM=3;\n\nenum GROUP_ALL_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + GROUP_ALL_PARMNUM;\nenum GROUP_NAME_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + GROUP_NAME_PARMNUM;\nenum GROUP_COMMENT_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + GROUP_COMMENT_PARMNUM;\nenum GROUP_ATTRIBUTES_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + GROUP_ATTRIBUTES_PARMNUM;\n// GROUP_POSIX_ID_PARMNUM isn't in MinGW or in the Platform SDK docs.\n//const GROUP_POSIX_ID_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + GROUP_POSIX_ID_PARMNUM;\n\nenum LOCALGROUP_NAME_PARMNUM=1;\nenum LOCALGROUP_COMMENT_PARMNUM=2;\nenum MAXPERMENTRIES=64;\nenum ACCESS_NONE=0;\nenum ACCESS_READ=1;\nenum ACCESS_WRITE=2;\nenum ACCESS_CREATE=4;\nenum ACCESS_EXEC=8;\nenum ACCESS_DELETE=16;\nenum ACCESS_ATRIB=32;\nenum ACCESS_PERM=64;\nenum ACCESS_ALL = ACCESS_READ|ACCESS_WRITE|ACCESS_CREATE|ACCESS_EXEC|ACCESS_DELETE|ACCESS_ATRIB|ACCESS_PERM;\nenum ACCESS_GROUP=0x8000;\nenum ACCESS_AUDIT=1;\nenum ACCESS_SUCCESS_OPEN=16;\nenum ACCESS_SUCCESS_WRITE=32;\nenum ACCESS_SUCCESS_DELETE=64;\nenum ACCESS_SUCCESS_ACL=128;\nenum ACCESS_SUCCESS_MASK=240;\nenum ACCESS_FAIL_OPEN=256;\nenum ACCESS_FAIL_WRITE=512;\nenum ACCESS_FAIL_DELETE=1024;\nenum ACCESS_FAIL_ACL=2048;\nenum ACCESS_FAIL_MASK=3840;\nenum ACCESS_FAIL_SHIFT=4;\nenum ACCESS_RESOURCE_NAME_PARMNUM=1;\nenum ACCESS_ATTR_PARMNUM=2;\nenum ACCESS_COUNT_PARMNUM=3;\nenum ACCESS_ACCESS_LIST_PARMNUM=4;\n\nenum ACCESS_RESOURCE_NAME_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+ACCESS_RESOURCE_NAME_PARMNUM);\nenum ACCESS_ATTR_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+ACCESS_ATTR_PARMNUM);\nenum ACCESS_COUNT_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+ACCESS_COUNT_PARMNUM);\nenum ACCESS_ACCESS_LIST_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+ACCESS_ACCESS_LIST_PARMNUM);\n\nenum NETLOGON_REPLICATION_NEEDED=1;\nenum NETLOGON_REPLICATION_IN_PROGRESS=2;\nenum NETLOGON_FULL_SYNC_REPLICATION=4;\nenum NETLOGON_REDO_NEEDED=8;\n\nstruct USER_INFO_0 {\n    LPWSTR usri0_name;\n}\nalias USER_INFO_0* PUSER_INFO_0, LPUSER_INFO_0;\n\nstruct USER_INFO_1{\n    LPWSTR usri1_name;\n    LPWSTR usri1_password;\n    DWORD usri1_password_age;\n    DWORD usri1_priv;\n    LPWSTR usri1_home_dir;\n    LPWSTR usri1_comment;\n    DWORD usri1_flags;\n    LPWSTR usri1_script_path;\n}\nalias USER_INFO_1* PUSER_INFO_1, LPUSER_INFO_1;\n\nstruct USER_INFO_2{\n    LPWSTR usri2_name;\n    LPWSTR usri2_password;\n    DWORD usri2_password_age;\n    DWORD usri2_priv;\n    LPWSTR usri2_home_dir;\n    LPWSTR usri2_comment;\n    DWORD usri2_flags;\n    LPWSTR usri2_script_path;\n    DWORD usri2_auth_flags;\n    LPWSTR usri2_full_name;\n    LPWSTR usri2_usr_comment;\n    LPWSTR usri2_parms;\n    LPWSTR usri2_workstations;\n    DWORD usri2_last_logon;\n    DWORD usri2_last_logoff;\n    DWORD usri2_acct_expires;\n    DWORD usri2_max_storage;\n    DWORD usri2_units_per_week;\n    PBYTE usri2_logon_hours;\n    DWORD usri2_bad_pw_count;\n    DWORD usri2_num_logons;\n    LPWSTR usri2_logon_server;\n    DWORD usri2_country_code;\n    DWORD usri2_code_page;\n}\nalias USER_INFO_2* PUSER_INFO_2, LPUSER_INFO_2;\n\nstruct USER_INFO_3{\n    LPWSTR usri3_name;\n    LPWSTR usri3_password;\n    DWORD usri3_password_age;\n    DWORD usri3_priv;\n    LPWSTR usri3_home_dir;\n    LPWSTR usri3_comment;\n    DWORD usri3_flags;\n    LPWSTR usri3_script_path;\n    DWORD usri3_auth_flags;\n    LPWSTR usri3_full_name;\n    LPWSTR usri3_usr_comment;\n    LPWSTR usri3_parms;\n    LPWSTR usri3_workstations;\n    DWORD usri3_last_logon;\n    DWORD usri3_last_logoff;\n    DWORD usri3_acct_expires;\n    DWORD usri3_max_storage;\n    DWORD usri3_units_per_week;\n    PBYTE usri3_logon_hours;\n    DWORD usri3_bad_pw_count;\n    DWORD usri3_num_logons;\n    LPWSTR usri3_logon_server;\n    DWORD usri3_country_code;\n    DWORD usri3_code_page;\n    DWORD usri3_user_id;\n    DWORD usri3_primary_group_id;\n    LPWSTR usri3_profile;\n    LPWSTR usri3_home_dir_drive;\n    DWORD usri3_password_expired;\n}\nalias USER_INFO_3* PUSER_INFO_3, LPUSER_INFO_3;\n\nstruct USER_INFO_10{\n    LPWSTR usri10_name;\n    LPWSTR usri10_comment;\n    LPWSTR usri10_usr_comment;\n    LPWSTR usri10_full_name;\n}\nalias USER_INFO_10* PUSER_INFO_10, LPUSER_INFO_10;\n\nstruct USER_INFO_11{\n    LPWSTR usri11_name;\n    LPWSTR usri11_comment;\n    LPWSTR usri11_usr_comment;\n    LPWSTR usri11_full_name;\n    DWORD usri11_priv;\n    DWORD usri11_auth_flags;\n    DWORD usri11_password_age;\n    LPWSTR usri11_home_dir;\n    LPWSTR usri11_parms;\n    DWORD usri11_last_logon;\n    DWORD usri11_last_logoff;\n    DWORD usri11_bad_pw_count;\n    DWORD usri11_num_logons;\n    LPWSTR usri11_logon_server;\n    DWORD usri11_country_code;\n    LPWSTR usri11_workstations;\n    DWORD usri11_max_storage;\n    DWORD usri11_units_per_week;\n    PBYTE usri11_logon_hours;\n    DWORD usri11_code_page;\n}\nalias USER_INFO_11* PUSER_INFO_11, LPUSER_INFO_11;\n\nstruct USER_INFO_20 {\n    LPWSTR usri20_name;\n    LPWSTR usri20_full_name;\n    LPWSTR usri20_comment;\n    DWORD usri20_flags;\n    DWORD usri20_user_id;\n}\nalias USER_INFO_20* PUSER_INFO_20, LPUSER_INFO_20;\n\nstruct USER_INFO_21 {\n    BYTE[ENCRYPTED_PWLEN] usri21_password;\n}\nalias USER_INFO_21* PUSER_INFO_21, LPUSER_INFO_21;\n\nstruct USER_INFO_22{\n    LPWSTR usri22_name;\n    BYTE[ENCRYPTED_PWLEN] usri22_password;\n    DWORD usri22_password_age;\n    DWORD usri22_priv;\n    LPWSTR usri22_home_dir;\n    LPWSTR usri22_comment;\n    DWORD usri22_flags;\n    LPWSTR usri22_script_path;\n    DWORD usri22_auth_flags;\n    LPWSTR usri22_full_name;\n    LPWSTR usri22_usr_comment;\n    LPWSTR usri22_parms;\n    LPWSTR usri22_workstations;\n    DWORD usri22_last_logon;\n    DWORD usri22_last_logoff;\n    DWORD usri22_acct_expires;\n    DWORD usri22_max_storage;\n    DWORD usri22_units_per_week;\n    PBYTE usri22_logon_hours;\n    DWORD usri22_bad_pw_count;\n    DWORD usri22_num_logons;\n    LPWSTR usri22_logon_server;\n    DWORD usri22_country_code;\n    DWORD usri22_code_page;\n}\nalias USER_INFO_22* PUSER_INFO_22, LPUSER_INFO_22;\n\nstruct USER_INFO_1003{\n    LPWSTR usri1003_password;\n}\nalias USER_INFO_1003* PUSER_INFO_1003, LPUSER_INFO_1003;\n\nstruct USER_INFO_1005{\n    DWORD usri1005_priv;\n}\nalias USER_INFO_1005* PUSER_INFO_1005, LPUSER_INFO_1005;\n\nstruct USER_INFO_1006{\n    LPWSTR usri1006_home_dir;\n}\nalias USER_INFO_1006* PUSER_INFO_1006, LPUSER_INFO_1006;\n\nstruct USER_INFO_1007{\n    LPWSTR usri1007_comment;\n}\nalias USER_INFO_1007* PUSER_INFO_1007, LPUSER_INFO_1007;\n\nstruct USER_INFO_1008{\n    DWORD usri1008_flags;\n}\nalias USER_INFO_1008* PUSER_INFO_1008, LPUSER_INFO_1008;\n\nstruct USER_INFO_1009{\n    LPWSTR usri1009_script_path;\n}\nalias USER_INFO_1009* PUSER_INFO_1009, LPUSER_INFO_1009;\n\nstruct USER_INFO_1010{\n    DWORD usri1010_auth_flags;\n}\nalias USER_INFO_1010* PUSER_INFO_1010, LPUSER_INFO_1010;\n\nstruct USER_INFO_1011{\n    LPWSTR usri1011_full_name;\n}\nalias USER_INFO_1011* PUSER_INFO_1011, LPUSER_INFO_1011;\n\nstruct USER_INFO_1012{\n    LPWSTR usri1012_usr_comment;\n}\nalias USER_INFO_1012* PUSER_INFO_1012, LPUSER_INFO_1012;\n\nstruct USER_INFO_1013{\n    LPWSTR usri1013_parms;\n}\nalias USER_INFO_1013* PUSER_INFO_1013, LPUSER_INFO_1013;\n\nstruct USER_INFO_1014{\n    LPWSTR usri1014_workstations;\n}\nalias USER_INFO_1014* PUSER_INFO_1014, LPUSER_INFO_1014;\n\nstruct USER_INFO_1017{\n    DWORD usri1017_acct_expires;\n}\nalias USER_INFO_1017* PUSER_INFO_1017, LPUSER_INFO_1017;\n\nstruct USER_INFO_1018{\n    DWORD usri1018_max_storage;\n}\nalias USER_INFO_1018* PUSER_INFO_1018, LPUSER_INFO_1018;\n\nstruct USER_INFO_1020{\n    DWORD usri1020_units_per_week;\n    PBYTE usri1020_logon_hours;\n}\nalias USER_INFO_1020* PUSER_INFO_1020, LPUSER_INFO_1020;\n\nstruct USER_INFO_1023{\n    LPWSTR usri1023_logon_server;\n}\nalias USER_INFO_1023* PUSER_INFO_1023, LPUSER_INFO_1023;\n\nstruct USER_INFO_1024{\n    DWORD usri1024_country_code;\n}\nalias USER_INFO_1024* PUSER_INFO_1024, LPUSER_INFO_1024;\n\nstruct USER_INFO_1025{\n    DWORD usri1025_code_page;\n}\nalias USER_INFO_1025* PUSER_INFO_1025, LPUSER_INFO_1025;\n\nstruct USER_INFO_1051{\n    DWORD usri1051_primary_group_id;\n}\nalias USER_INFO_1051* PUSER_INFO_1051, LPUSER_INFO_1051;\n\nstruct USER_INFO_1052{\n    LPWSTR usri1052_profile;\n}\nalias USER_INFO_1052* PUSER_INFO_1052, LPUSER_INFO_1052;\n\nstruct USER_INFO_1053{\n    LPWSTR usri1053_home_dir_drive;\n}\nalias USER_INFO_1053* PUSER_INFO_1053, LPUSER_INFO_1053;\n\nstruct USER_MODALS_INFO_0{\n    DWORD usrmod0_min_passwd_len;\n    DWORD usrmod0_max_passwd_age;\n    DWORD usrmod0_min_passwd_age;\n    DWORD usrmod0_force_logoff;\n    DWORD usrmod0_password_hist_len;\n}\nalias USER_MODALS_INFO_0* PUSER_MODALS_INFO_0, LPUSER_MODALS_INFO_0;\n\nstruct USER_MODALS_INFO_1{\n    DWORD usrmod1_role;\n    LPWSTR usrmod1_primary;\n}\nalias USER_MODALS_INFO_1* PUSER_MODALS_INFO_1, LPUSER_MODALS_INFO_1;\n\nstruct USER_MODALS_INFO_2{\n    LPWSTR usrmod2_domain_name;\n    PSID usrmod2_domain_id;\n}\nalias USER_MODALS_INFO_2* PUSER_MODALS_INFO_2, LPUSER_MODALS_INFO_2;\n\nstruct USER_MODALS_INFO_3{\n    DWORD usrmod3_lockout_duration;\n    DWORD usrmod3_lockout_observation_window;\n    DWORD usrmod3_lockout_threshold;\n}\nalias USER_MODALS_INFO_3* PUSER_MODALS_INFO_3, LPUSER_MODALS_INFO_3;\n\nstruct USER_MODALS_INFO_1001{\n    DWORD usrmod1001_min_passwd_len;\n}\nalias USER_MODALS_INFO_1001* PUSER_MODALS_INFO_1001, LPUSER_MODALS_INFO_1001;\n\nstruct USER_MODALS_INFO_1002{\n    DWORD usrmod1002_max_passwd_age;\n}\nalias USER_MODALS_INFO_1002* PUSER_MODALS_INFO_1002, LPUSER_MODALS_INFO_1002;\n\nstruct USER_MODALS_INFO_1003{\n    DWORD usrmod1003_min_passwd_age;\n}\nalias USER_MODALS_INFO_1003* PUSER_MODALS_INFO_1003, LPUSER_MODALS_INFO_1003;\n\nstruct USER_MODALS_INFO_1004{\n    DWORD usrmod1004_force_logoff;\n}\nalias USER_MODALS_INFO_1004* PUSER_MODALS_INFO_1004, LPUSER_MODALS_INFO_1004;\n\nstruct USER_MODALS_INFO_1005{\n    DWORD usrmod1005_password_hist_len;\n}\nalias USER_MODALS_INFO_1005* PUSER_MODALS_INFO_1005, LPUSER_MODALS_INFO_1005;\n\nstruct USER_MODALS_INFO_1006{\n    DWORD usrmod1006_role;\n}\nalias USER_MODALS_INFO_1006* PUSER_MODALS_INFO_1006, LPUSER_MODALS_INFO_1006;\n\nstruct USER_MODALS_INFO_1007{\n    LPWSTR usrmod1007_primary;\n}\nalias USER_MODALS_INFO_1007* PUSER_MODALS_INFO_1007, LPUSER_MODALS_INFO_1007;\n\nstruct GROUP_INFO_0{\n    LPWSTR grpi0_name;\n}\nalias GROUP_INFO_0* PGROUP_INFO_0, LPGROUP_INFO_0;\n\nstruct GROUP_INFO_1{\n    LPWSTR grpi1_name;\n    LPWSTR grpi1_comment;\n}\nalias GROUP_INFO_1* PGROUP_INFO_1, LPGROUP_INFO_1;\n\nstruct GROUP_INFO_2{\n    LPWSTR grpi2_name;\n    LPWSTR grpi2_comment;\n    DWORD grpi2_group_id;\n    DWORD grpi2_attributes;\n}\nalias GROUP_INFO_2* PGROUP_INFO_2;\n\nstruct GROUP_INFO_1002{\n    LPWSTR grpi1002_comment;\n}\nalias GROUP_INFO_1002* PGROUP_INFO_1002, LPGROUP_INFO_1002;\n\nstruct GROUP_INFO_1005{\n    DWORD grpi1005_attributes;\n}\nalias GROUP_INFO_1005* PGROUP_INFO_1005, LPGROUP_INFO_1005;\n\nstruct GROUP_USERS_INFO_0{\n    LPWSTR grui0_name;\n}\nalias GROUP_USERS_INFO_0* PGROUP_USERS_INFO_0, LPGROUP_USERS_INFO_0;\n\nstruct GROUP_USERS_INFO_1{\n    LPWSTR grui1_name;\n    DWORD grui1_attributes;\n}\nalias GROUP_USERS_INFO_1* PGROUP_USERS_INFO_1, LPGROUP_USERS_INFO_1;\n\nstruct LOCALGROUP_INFO_0{\n    LPWSTR lgrpi0_name;\n}\nalias LOCALGROUP_INFO_0* PLOCALGROUP_INFO_0, LPLOCALGROUP_INFO_0;\n\nstruct LOCALGROUP_INFO_1{\n    LPWSTR lgrpi1_name;\n    LPWSTR lgrpi1_comment;\n}\nalias LOCALGROUP_INFO_1* PLOCALGROUP_INFO_1, LPLOCALGROUP_INFO_1;\n\nstruct LOCALGROUP_INFO_1002{\n    LPWSTR lgrpi1002_comment;\n}\nalias LOCALGROUP_INFO_1002* PLOCALGROUP_INFO_1002, LPLOCALGROUP_INFO_1002;\n\nstruct LOCALGROUP_MEMBERS_INFO_0{\n    PSID lgrmi0_sid;\n}\nalias LOCALGROUP_MEMBERS_INFO_0* PLOCALGROUP_MEMBERS_INFO_0, LPLOCALGROUP_MEMBERS_INFO_0;\n\nstruct LOCALGROUP_MEMBERS_INFO_1{\n    PSID lgrmi1_sid;\n    SID_NAME_USE lgrmi1_sidusage;\n    LPWSTR lgrmi1_name;\n}\nalias LOCALGROUP_MEMBERS_INFO_1* PLOCALGROUP_MEMBERS_INFO_1, LPLOCALGROUP_MEMBERS_INFO_1;\n\nstruct LOCALGROUP_MEMBERS_INFO_2{\n    PSID lgrmi2_sid;\n    SID_NAME_USE lgrmi2_sidusage;\n    LPWSTR lgrmi2_domainandname;\n}\nalias LOCALGROUP_MEMBERS_INFO_2* PLOCALGROUP_MEMBERS_INFO_2, LPLOCALGROUP_MEMBERS_INFO_2;\n\nstruct LOCALGROUP_MEMBERS_INFO_3{\n    LPWSTR lgrmi3_domainandname;\n}\nalias LOCALGROUP_MEMBERS_INFO_3* PLOCALGROUP_MEMBERS_INFO_3, LPLOCALGROUP_MEMBERS_INFO_3;\n\nstruct LOCALGROUP_USERS_INFO_0{\n    LPWSTR lgrui0_name;\n}\nalias LOCALGROUP_USERS_INFO_0* PLOCALGROUP_USERS_INFO_0, LPLOCALGROUP_USERS_INFO_0;\n\nstruct NET_DISPLAY_USER{\n    LPWSTR usri1_name;\n    LPWSTR usri1_comment;\n    DWORD usri1_flags;\n    LPWSTR usri1_full_name;\n    DWORD usri1_user_id;\n    DWORD usri1_next_index;\n}\nalias NET_DISPLAY_USER* PNET_DISPLAY_USER;\n\nstruct NET_DISPLAY_MACHINE{\n    LPWSTR usri2_name;\n    LPWSTR usri2_comment;\n    DWORD usri2_flags;\n    DWORD usri2_user_id;\n    DWORD usri2_next_index;\n}\nalias NET_DISPLAY_MACHINE* PNET_DISPLAY_MACHINE;\n\nstruct NET_DISPLAY_GROUP{\n    LPWSTR grpi3_name;\n    LPWSTR grpi3_comment;\n    DWORD grpi3_group_id;\n    DWORD grpi3_attributes;\n    DWORD grpi3_next_index;\n}\nalias NET_DISPLAY_GROUP* PNET_DISPLAY_GROUP;\n\nstruct ACCESS_INFO_0{\n    LPTSTR acc0_resource_name;\n}\nalias ACCESS_INFO_0* PACCESS_INFO_0, LPACCESS_INFO_0;\n\nstruct ACCESS_INFO_1{\n    LPTSTR acc1_resource_name;\n    DWORD acc1_attr;\n    DWORD acc1_count;\n}\nalias ACCESS_INFO_1* PACCESS_INFO_1, LPACCESS_INFO_1;\n\nstruct ACCESS_INFO_1002{\n    DWORD acc1002_attr;\n}\nalias ACCESS_INFO_1002* PACCESS_INFO_1002, LPACCESS_INFO_1002;\n\nstruct ACCESS_LIST{\n    LPTSTR acl_ugname;\n    DWORD acl_access;\n}\nalias ACCESS_LIST* PACCESS_LIST, LPACCESS_LIST;\n\nstruct NETLOGON_INFO_1{\n    DWORD netlog1_flags;\n    NET_API_STATUS netlog1_pdc_connection_status;\n}\nalias NETLOGON_INFO_1* PNETLOGON_INFO_1;\n\nstruct NETLOGON_INFO_2{\n    DWORD netlog2_flags;\n    NET_API_STATUS netlog2_pdc_connection_status;\n    LPWSTR netlog2_trusted_dc_name;\n    NET_API_STATUS netlog2_tc_connection_status;\n}\nalias NETLOGON_INFO_2* PNETLOGON_INFO_2;\n\nstruct NETLOGON_INFO_3{\n    DWORD netlog3_flags;\n    DWORD netlog3_logon_attempts;\n    DWORD netlog3_reserved1;\n    DWORD netlog3_reserved2;\n    DWORD netlog3_reserved3;\n    DWORD netlog3_reserved4;\n    DWORD netlog3_reserved5;\n}\nalias NETLOGON_INFO_3* PNETLOGON_INFO_3;\n\nextern (Windows) {\ndeprecated {\n    /* These are obsolete */\n    NET_API_STATUS NetAccessAdd(LPCWSTR,DWORD,PBYTE,PDWORD);\n    NET_API_STATUS NetAccessEnum(LPCWSTR,LPCWSTR,DWORD,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\n    NET_API_STATUS NetAccessGetInfo(LPCWSTR,LPCWSTR,DWORD,PBYTE*);\n    NET_API_STATUS NetAccessSetInfo(LPCWSTR,LPCWSTR,DWORD,PBYTE,PDWORD);\n    NET_API_STATUS NetAccessDel(LPCWSTR,LPCWSTR);\n    NET_API_STATUS NetAccessGetUserPerms(LPCWSTR,LPCWSTR,LPCWSTR,PDWORD);\n}\nNET_API_STATUS NetUserAdd(LPCWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetUserEnum(LPCWSTR,DWORD,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetUserGetInfo(LPCWSTR,LPCWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetUserSetInfo(LPCWSTR,LPCWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetUserDel(LPCWSTR,LPCWSTR);\nNET_API_STATUS NetUserGetGroups(LPCWSTR,LPCWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD);\nNET_API_STATUS NetUserSetGroups(LPCWSTR,LPCWSTR,DWORD,PBYTE,DWORD);\nNET_API_STATUS NetUserGetLocalGroups(LPCWSTR,LPCWSTR,DWORD,DWORD,PBYTE*,DWORD,PDWORD,PDWORD);\nNET_API_STATUS NetUserModalsGet(LPCWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetUserModalsSet(LPCWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetUserChangePassword(LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR);\nNET_API_STATUS NetGroupAdd(LPCWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetGroupAddUser(LPCWSTR,LPCWSTR,LPCWSTR);\nNET_API_STATUS NetGroupEnum(LPCWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetGroupGetInfo(LPCWSTR,LPCWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetGroupSetInfo(LPCWSTR,LPCWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetGroupDel(LPCWSTR,LPCWSTR);\nNET_API_STATUS NetGroupDelUser(LPCWSTR,LPCWSTR,LPCWSTR);\nNET_API_STATUS NetGroupGetUsers(LPCWSTR,LPCWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetGroupSetUsers(LPCWSTR,LPCWSTR,DWORD,PBYTE,DWORD);\nNET_API_STATUS NetLocalGroupAdd(LPCWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetLocalGroupAddMember(LPCWSTR,LPCWSTR,PSID);\nNET_API_STATUS NetLocalGroupEnum(LPCWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetLocalGroupGetInfo(LPCWSTR,LPCWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetLocalGroupSetInfo(LPCWSTR,LPCWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetLocalGroupDel(LPCWSTR,LPCWSTR);\nNET_API_STATUS NetLocalGroupDelMember(LPCWSTR,LPCWSTR,PSID);\nNET_API_STATUS NetLocalGroupGetMembers(LPCWSTR,LPCWSTR,DWORD,PBYTE*,DWORD,\nPDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetLocalGroupSetMembers(LPCWSTR,LPCWSTR,DWORD,PBYTE,DWORD);\nNET_API_STATUS NetLocalGroupAddMembers(LPCWSTR,LPCWSTR,DWORD,PBYTE,DWORD);\nNET_API_STATUS NetLocalGroupDelMembers(LPCWSTR,LPCWSTR,DWORD,PBYTE,DWORD);\nNET_API_STATUS NetQueryDisplayInformation(LPCWSTR,DWORD,DWORD,DWORD,DWORD,PDWORD,PVOID*);\nNET_API_STATUS NetGetDisplayInformationIndex(LPCWSTR,DWORD,LPCWSTR,PDWORD);\nNET_API_STATUS NetGetDCName(LPCWSTR,LPCWSTR,PBYTE*);\nNET_API_STATUS NetGetAnyDCName(LPCWSTR,LPCWSTR,PBYTE*);\nNET_API_STATUS I_NetLogonControl(LPCWSTR,DWORD,DWORD,PBYTE*);\nNET_API_STATUS I_NetLogonControl2(LPCWSTR,DWORD,DWORD,PBYTE,PBYTE*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmalert.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmalert.d)\n */\nmodule core.sys.windows.lmalert;\nversion (Windows):\npragma(lib, \"netapi32\");\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nconst TCHAR[]\n    ALERTER_MAILSLOT     = `\\\\.\\MAILSLOT\\Alerter`,\n    ALERT_PRINT_EVENT    = \"PRINTING\",\n    ALERT_MESSAGE_EVENT  = \"MESSAGE\",\n    ALERT_ERRORLOG_EVENT = \"ERRORLOG\",\n    ALERT_ADMIN_EVENT    = \"ADMIN\",\n    ALERT_USER_EVENT     = \"USER\";\n//MACRO #define ALERT_OTHER_INFO(x) ((PBYTE)(x)+sizeof(STD_ALERT))\n\n//MACRO #define ALERT_VAR_DATA(p) ((PBYTE)(p)+sizeof(*p))\n\nenum PRJOB_QSTATUS     = 3;\nenum PRJOB_DEVSTATUS   = 508;\nenum PRJOB_COMPLETE    = 4;\nenum PRJOB_INTERV      = 8;\nenum PRJOB_            = 16;\nenum PRJOB_DESTOFFLINE = 32;\nenum PRJOB_DESTPAUSED  = 64;\nenum PRJOB_NOTIFY      = 128;\nenum PRJOB_DESTNOPAPER = 256;\nenum PRJOB_DELETED     = 32768;\nenum PRJOB_QS_QUEUED   = 0;\nenum PRJOB_QS_PAUSED   = 1;\nenum PRJOB_QS_SPOOLING = 2;\nenum PRJOB_QS_PRINTING = 3;\n\nstruct ADMIN_OTHER_INFO{\n    DWORD alrtad_errcode;\n    DWORD alrtad_numstrings;\n}\nalias ADMIN_OTHER_INFO* PADMIN_OTHER_INFO, LPADMIN_OTHER_INFO;\n\nstruct STD_ALERT{\n    DWORD alrt_timestamp;\n    TCHAR[EVLEN+1] alrt_eventname;\n    TCHAR[SNLEN+1] alrt_servicename;\n}\nalias STD_ALERT* PSTD_ALERT, LPSTD_ALERT;\n\nstruct ERRLOG_OTHER_INFO{\n    DWORD alrter_errcode;\n    DWORD alrter_offset;\n}\nalias ERRLOG_OTHER_INFO* PERRLOG_OTHER_INFO, LPERRLOG_OTHER_INFO;\n\nstruct PRINT_OTHER_INFO{\n    DWORD alrtpr_jobid;\n    DWORD alrtpr_status;\n    DWORD alrtpr_submitted;\n    DWORD alrtpr_size;\n}\nalias PRINT_OTHER_INFO* PPRINT_OTHER_INFO, LPPRINT_OTHER_INFO;\n\nstruct USER_OTHER_INFO{\n    DWORD alrtus_errcode;\n    DWORD alrtus_numstrings;\n}\nalias USER_OTHER_INFO* PUSER_OTHER_INFO, LPUSER_OTHER_INFO;\n\nextern (Windows) {\nNET_API_STATUS NetAlertRaise(LPCWSTR,PVOID,DWORD);\nNET_API_STATUS NetAlertRaiseEx(LPCWSTR,PVOID,DWORD,LPCWSTR);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmapibuf.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmapibuf.d)\n */\nmodule core.sys.windows.lmapibuf;\nversion (Windows):\npragma(lib, \"netapi32\");\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nextern (Windows) {\n    NET_API_STATUS NetApiBufferAllocate(DWORD, PVOID*);\n    NET_API_STATUS NetApiBufferFree(PVOID);\n    NET_API_STATUS NetApiBufferReallocate(PVOID, DWORD, PVOID*);\n    NET_API_STATUS NetApiBufferSize(PVOID, PDWORD);\n    NET_API_STATUS NetapipBufferAllocate(DWORD, PVOID*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmat.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmat.d)\n */\nmodule core.sys.windows.lmat;\nversion (Windows):\npragma(lib, \"netapi32\");\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nenum JOB_RUN_PERIODICALLY = 1;\nenum JOB_EXEC_ERROR       = 2;\nenum JOB_RUNS_TODAY       = 4;\nenum JOB_ADD_CURRENT_DATE = 8;\nenum JOB_NONINTERACTIVE   = 16;\nenum JOB_INPUT_FLAGS      = JOB_RUN_PERIODICALLY | JOB_ADD_CURRENT_DATE\n                             | JOB_NONINTERACTIVE;\nenum JOB_OUTPUT_FLAGS     = JOB_RUN_PERIODICALLY | JOB_EXEC_ERROR\n                             | JOB_RUNS_TODAY | JOB_NONINTERACTIVE;\n\nstruct AT_ENUM {\n    DWORD JobId;\n    DWORD_PTR JobTime;\n    DWORD DaysOfMonth;\n    UCHAR DaysOfWeek;\n    UCHAR Flags;\n    LPWSTR Command;\n}\nalias AT_ENUM* PAT_ENUM, LPAT_ENUM;\n\nstruct AT_INFO {\n    DWORD_PTR JobTime;\n    DWORD DaysOfMonth;\n    UCHAR DaysOfWeek;\n    UCHAR Flags;\n    LPWSTR Command;\n}\nalias AT_INFO* PAT_INFO, LPAT_INFO;\n\nextern (Windows) {\n    NET_API_STATUS NetScheduleJobAdd(LPWSTR, PBYTE, LPDWORD);\n    NET_API_STATUS NetScheduleJobDel(LPWSTR, DWORD, DWORD);\n    NET_API_STATUS NetScheduleJobEnum(LPWSTR, PBYTE*, DWORD, PDWORD, PDWORD,\n      PDWORD);\n    NET_API_STATUS NetScheduleJobGetInfo(LPWSTR, DWORD, PBYTE*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmaudit.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmaudit.d)\n */\n// COMMENT: This file may be deprecated.\nmodule core.sys.windows.lmaudit;\nversion (Windows):\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nenum LOGFLAGS_FORWARD  = 0;\nenum LOGFLAGS_BACKWARD = 1;\nenum LOGFLAGS_SEEK     = 2;\n\nenum ACTION_LOCKOUT     = 0;\nenum ACTION_ADMINUNLOCK = 1;\n\nenum AE_GUEST=0;\nenum AE_USER=1;\nenum AE_ADMIN=2;\nenum AE_NORMAL=0;\nenum AE_USERLIMIT=0;\nenum AE_GENERAL=0;\nenum AE_ERROR=1;\nenum AE_SESSDIS=1;\nenum AE_BADPW=1;\nenum AE_AUTODIS=2;\nenum AE_UNSHARE=2;\nenum AE_ADMINPRIVREQD=2;\nenum AE_ADMINDIS=3;\nenum AE_NOACCESSPERM=3;\nenum AE_ACCRESTRICT=4;\nenum AE_NORMAL_CLOSE=0;\nenum AE_SES_CLOSE=1;\nenum AE_ADMIN_CLOSE=2;\nenum AE_LIM_UNKNOWN=0;\nenum AE_LIM_LOGONHOURS=1;\nenum AE_LIM_EXPIRED=2;\nenum AE_LIM_INVAL_WKSTA=3;\nenum AE_LIM_DISABLED=4;\nenum AE_LIM_DELETED=5;\nenum AE_MOD=0;\nenum AE_DELETE=1;\nenum AE_ADD=2;\n\nenum AE_UAS_USER   = 0;\nenum AE_UAS_GROUP  = 1;\nenum AE_UAS_MODALS = 2;\n\nenum SVAUD_SERVICE       = 1;\nenum SVAUD_GOODSESSLOGON = 6;\nenum SVAUD_BADSESSLOGON  = 24;\nenum SVAUD_SESSLOGON     = SVAUD_GOODSESSLOGON|SVAUD_BADSESSLOGON;\nenum SVAUD_GOODNETLOGON  = 96;\nenum SVAUD_BADNETLOGON   = 384;\nenum SVAUD_NETLOGON      = SVAUD_GOODNETLOGON|SVAUD_BADNETLOGON;\nenum SVAUD_LOGON         = SVAUD_NETLOGON|SVAUD_SESSLOGON;\nenum SVAUD_GOODUSE       = 0x600;\nenum SVAUD_BADUSE        = 0x1800;\nenum SVAUD_USE           = SVAUD_GOODUSE|SVAUD_BADUSE;\nenum SVAUD_USERLIST      = 8192;\nenum SVAUD_PERMISSIONS   = 16384;\nenum SVAUD_RESOURCE      = 32768;\nenum SVAUD_LOGONLIM      = 65536;\n\nenum AA_AUDIT_ALL=1;\nenum AA_A_OWNER=4;\nenum AA_CLOSE=8;\nenum AA_S_OPEN=16;\nenum AA_S_WRITE=32;\nenum AA_S_CREATE=32;\nenum AA_S_DELETE=64;\nenum AA_S_ACL=128;\nenum AA_S_ALL=253;\nenum AA_F_OPEN=256;\nenum AA_F_WRITE=512;\nenum AA_F_CREATE=512;\nenum AA_F_DELETE=1024;\nenum AA_F_ACL=2048;\nenum AA_F_ALL = AA_F_OPEN|AA_F_WRITE|AA_F_DELETE|AA_F_ACL;\nenum AA_A_OPEN=2048;\nenum AA_A_WRITE=4096;\nenum AA_A_CREATE=8192;\nenum AA_A_DELETE=16384;\nenum AA_A_ACL=32768;\nenum AA_A_ALL = AA_F_OPEN|AA_F_WRITE|AA_F_DELETE|AA_F_ACL;\n\nstruct AUDIT_ENTRY{\n    DWORD ae_len;\n    DWORD ae_reserved;\n    DWORD ae_time;\n    DWORD ae_type;\n    DWORD ae_data_offset;\n    DWORD ae_data_size;\n}\nalias AUDIT_ENTRY* PAUDIT_ENTRY, LPAUDIT_ENTRY;\n\nstruct HLOG{\n    DWORD time;\n    DWORD last_flags;\n    DWORD offset;\n    DWORD rec_offset;\n}\nalias HLOG* PHLOG, LPHLOG;\n\nstruct AE_SRVSTATUS{\n    DWORD ae_sv_status;\n}\nalias AE_SRVSTATUS* PAE_SRVSTATUS, LPAE_SRVSTATUS;\n\nstruct AE_SESSLOGON{\n    DWORD ae_so_compname;\n    DWORD ae_so_username;\n    DWORD ae_so_privilege;\n}\nalias AE_SESSLOGON* PAE_SESSLOGON, LPAE_SESSLOGON;\n\nstruct AE_SESSLOGOFF{\n    DWORD ae_sf_compname;\n    DWORD ae_sf_username;\n    DWORD ae_sf_reason;\n}\nalias AE_SESSLOGOFF* PAE_SESSLOGOFF, LPAE_SESSLOGOFF;\n\nstruct AE_SESSPWERR{\n    DWORD ae_sp_compname;\n    DWORD ae_sp_username;\n}\nalias AE_SESSPWERR* PAE_SESSPWERR, LPAE_SESSPWERR;\n\nstruct AE_CONNSTART{\n    DWORD ae_ct_compname;\n    DWORD ae_ct_username;\n    DWORD ae_ct_netname;\n    DWORD ae_ct_connid;\n}\nalias AE_CONNSTART* PAE_CONNSTART, LPAE_CONNSTART;\n\nstruct AE_CONNSTOP{\n    DWORD ae_cp_compname;\n    DWORD ae_cp_username;\n    DWORD ae_cp_netname;\n    DWORD ae_cp_connid;\n    DWORD ae_cp_reason;\n}\nalias AE_CONNSTOP* PAE_CONNSTOP, LPAE_CONNSTOP;\n\nstruct AE_CONNREJ{\n    DWORD ae_cr_compname;\n    DWORD ae_cr_username;\n    DWORD ae_cr_netname;\n    DWORD ae_cr_reason;\n}\nalias AE_CONNREJ* PAE_CONNREJ, LPAE_CONNREJ;\n\nstruct AE_RESACCESS{\n    DWORD ae_ra_compname;\n    DWORD ae_ra_username;\n    DWORD ae_ra_resname;\n    DWORD ae_ra_operation;\n    DWORD ae_ra_returncode;\n    DWORD ae_ra_restype;\n    DWORD ae_ra_fileid;\n}\nalias AE_RESACCESS* PAE_RESACCESS, LPAE_RESACCESS;\n\nstruct AE_RESACCESSREJ{\n    DWORD ae_rr_compname;\n    DWORD ae_rr_username;\n    DWORD ae_rr_resname;\n    DWORD ae_rr_operation;\n}\nalias AE_RESACCESSREJ* PAE_RESACCESSREJ, LPAE_RESACCESSREJ;\n\nstruct AE_CLOSEFILE{\n    DWORD ae_cf_compname;\n    DWORD ae_cf_username;\n    DWORD ae_cf_resname;\n    DWORD ae_cf_fileid;\n    DWORD ae_cf_duration;\n    DWORD ae_cf_reason;\n}\nalias AE_CLOSEFILE* PAE_CLOSEFILE, LPAE_CLOSEFILE;\n\nstruct AE_SERVICESTAT{\n    DWORD ae_ss_compname;\n    DWORD ae_ss_username;\n    DWORD ae_ss_svcname;\n    DWORD ae_ss_status;\n    DWORD ae_ss_code;\n    DWORD ae_ss_text;\n    DWORD ae_ss_returnval;\n}\nalias AE_SERVICESTAT* PAE_SERVICESTAT, LPAE_SERVICESTAT;\n\nstruct AE_ACLMOD{\n    DWORD ae_am_compname;\n    DWORD ae_am_username;\n    DWORD ae_am_resname;\n    DWORD ae_am_action;\n    DWORD ae_am_datalen;\n}\nalias AE_ACLMOD* PAE_ACLMOD, LPAE_ACLMOD;\n\nstruct AE_UASMOD{\n    DWORD ae_um_compname;\n    DWORD ae_um_username;\n    DWORD ae_um_resname;\n    DWORD ae_um_rectype;\n    DWORD ae_um_action;\n    DWORD ae_um_datalen;\n}\nalias AE_UASMOD* PAE_UASMOD, LPAE_UASMOD;\n\nstruct AE_NETLOGON{\n    DWORD ae_no_compname;\n    DWORD ae_no_username;\n    DWORD ae_no_privilege;\n    DWORD ae_no_authflags;\n}\nalias AE_NETLOGON* PAE_NETLOGON, LPAE_NETLOGON;\n\nstruct AE_NETLOGOFF{\n    DWORD ae_nf_compname;\n    DWORD ae_nf_username;\n    DWORD ae_nf_reserved1;\n    DWORD ae_nf_reserved2;\n}\nalias AE_NETLOGOFF* PAE_NETLOGOFF, LPAE_NETLOGOFF;\n\nstruct AE_ACCLIM{\n    DWORD ae_al_compname;\n    DWORD ae_al_username;\n    DWORD ae_al_resname;\n    DWORD ae_al_limit;\n}\nalias AE_ACCLIM* PAE_ACCLIM, LPAE_ACCLIM;\n\nstruct AE_LOCKOUT{\n    DWORD ae_lk_compname;\n    DWORD ae_lk_username;\n    DWORD ae_lk_action;\n    DWORD ae_lk_bad_pw_count;\n}\nalias AE_LOCKOUT* PAE_LOCKOUT, LPAE_LOCKOUT;\n\nstruct AE_GENERIC{\n    DWORD ae_ge_msgfile;\n    DWORD ae_ge_msgnum;\n    DWORD ae_ge_params;\n    DWORD ae_ge_param1;\n    DWORD ae_ge_param2;\n    DWORD ae_ge_param3;\n    DWORD ae_ge_param4;\n    DWORD ae_ge_param5;\n    DWORD ae_ge_param6;\n    DWORD ae_ge_param7;\n    DWORD ae_ge_param8;\n    DWORD ae_ge_param9;\n}\nalias AE_GENERIC* PAE_GENERIC, LPAE_GENERIC;\n\nextern (Windows) {\ndeprecated {\nNET_API_STATUS NetAuditClear(LPCWSTR,LPCWSTR,LPCWSTR);\nNET_API_STATUS NetAuditRead(LPTSTR,LPTSTR,LPHLOG,DWORD,PDWORD,DWORD,DWORD,PBYTE*,DWORD,PDWORD,PDWORD);\nNET_API_STATUS NetAuditWrite(DWORD,PBYTE,DWORD,LPTSTR,PBYTE);\n}\n}\n\n/+\n/* MinGW: These conflict with struct typedefs, why? */\nenum AE_SRVSTATUS=0;\nenum AE_SESSLOGON=1;\nenum AE_SESSLOGOFF=2;\nenum AE_SESSPWERR=3;\nenum AE_CONNSTART=4;\nenum AE_CONNSTOP=5;\nenum AE_CONNREJ=6;\nenum AE_RESACCESS=7;\nenum AE_RESACCESSREJ=8;\nenum AE_CLOSEFILE=9;\nenum AE_SERVICESTAT=11;\nenum AE_ACLMOD=12;\nenum AE_UASMOD=13;\nenum AE_NETLOGON=14;\nenum AE_NETLOGOFF=15;\nenum AE_NETLOGDENIED=16;\nenum AE_ACCLIMITEXCD=17;\nenum AE_RESACCESS2=18;\nenum AE_ACLMODFAIL=19;\nenum AE_LOCKOUT=20;\nenum AE_GENERIC_TYPE=21;\nenum AE_SRVSTART=0;\nenum AE_SRVPAUSED=1;\nenum AE_SRVCONT=2;\nenum AE_SRVSTOP=3;\n+/\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmbrowsr.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmbrowsr.d)\n */\nmodule core.sys.windows.lmbrowsr;\nversion (Windows):\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nenum BROWSER_ROLE_PDC = 1;\nenum BROWSER_ROLE_BDC = 2;\n\nstruct BROWSER_STATISTICS {\n    LARGE_INTEGER StatisticsStartTime;\n    LARGE_INTEGER NumberOfServerAnnouncements;\n    LARGE_INTEGER NumberOfDomainAnnouncements;\n    ULONG NumberOfElectionPackets;\n    ULONG NumberOfMailslotWrites;\n    ULONG NumberOfGetBrowserServerListRequests;\n    ULONG NumberOfServerEnumerations;\n    ULONG NumberOfDomainEnumerations;\n    ULONG NumberOfOtherEnumerations;\n    ULONG NumberOfMissedServerAnnouncements;\n    ULONG NumberOfMissedMailslotDatagrams;\n    ULONG NumberOfMissedGetBrowserServerListRequests;\n    ULONG NumberOfFailedServerAnnounceAllocations;\n    ULONG NumberOfFailedMailslotAllocations;\n    ULONG NumberOfFailedMailslotReceives;\n    ULONG NumberOfFailedMailslotWrites;\n    ULONG NumberOfFailedMailslotOpens;\n    ULONG NumberOfDuplicateMasterAnnouncements;\n    LARGE_INTEGER NumberOfIllegalDatagrams;\n}\nalias BROWSER_STATISTICS* PBROWSER_STATISTICS, LPBROWSER_STATISTICS;\n\nstruct BROWSER_STATISTICS_100 {\n    LARGE_INTEGER StartTime;\n    LARGE_INTEGER NumberOfServerAnnouncements;\n    LARGE_INTEGER NumberOfDomainAnnouncements;\n    ULONG NumberOfElectionPackets;\n    ULONG NumberOfMailslotWrites;\n    ULONG NumberOfGetBrowserServerListRequests;\n    LARGE_INTEGER NumberOfIllegalDatagrams;\n}\nalias BROWSER_STATISTICS_100* PBROWSER_STATISTICS_100;\n\nstruct BROWSER_STATISTICS_101 {\n    LARGE_INTEGER StartTime;\n    LARGE_INTEGER NumberOfServerAnnouncements;\n    LARGE_INTEGER NumberOfDomainAnnouncements;\n    ULONG NumberOfElectionPackets;\n    ULONG NumberOfMailslotWrites;\n    ULONG NumberOfGetBrowserServerListRequests;\n    LARGE_INTEGER NumberOfIllegalDatagrams;\n    ULONG NumberOfMissedServerAnnouncements;\n    ULONG NumberOfMissedMailslotDatagrams;\n    ULONG NumberOfMissedGetBrowserServerListRequests;\n    ULONG NumberOfFailedServerAnnounceAllocations;\n    ULONG NumberOfFailedMailslotAllocations;\n    ULONG NumberOfFailedMailslotReceives;\n    ULONG NumberOfFailedMailslotWrites;\n    ULONG NumberOfFailedMailslotOpens;\n    ULONG NumberOfDuplicateMasterAnnouncements;\n}\nalias BROWSER_STATISTICS_101* PBROWSER_STATISTICS_101;\n\nextern (Windows) {\n    NET_API_STATUS I_BrowserServerEnum(LPCWSTR, LPCWSTR, LPCWSTR, DWORD,\n      PBYTE*, DWORD, PDWORD, PDWORD, DWORD, LPCWSTR, PDWORD);\n    NET_API_STATUS I_BrowserServerEnumEx(LPCWSTR, LPCWSTR, LPCWSTR, DWORD,\n      PBYTE*, DWORD, PDWORD, PDWORD, DWORD, LPCWSTR, LPCWSTR);\n    NET_API_STATUS I_BrowserQueryEmulatedDomains(LPWSTR, PBYTE*, PDWORD);\n    NET_API_STATUS I_BrowserQueryOtherDomains(LPCWSTR, PBYTE*, PDWORD, PDWORD);\n    NET_API_STATUS I_BrowserResetNetlogonState(LPCWSTR);\n    NET_API_STATUS I_BrowserSetNetlogonState(LPWSTR, LPWSTR, LPWSTR, DWORD);\n    NET_API_STATUS I_BrowserQueryStatistics(LPCWSTR, LPBROWSER_STATISTICS*);\n    NET_API_STATUS I_BrowserResetStatistics(LPCWSTR);\n    WORD I_BrowserServerEnumForXactsrv(LPCWSTR, LPCWSTR, ULONG, USHORT, PVOID,\n      WORD, DWORD, PDWORD, PDWORD, DWORD, LPCWSTR, LPCWSTR, PWORD);\n    NET_API_STATUS I_BrowserDebugTrace(PWCHAR, PCHAR);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmchdev.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmchdev.d)\n */\nmodule core.sys.windows.lmchdev;\nversion (Windows):\n\n// COMMENT: This file might be deprecated.\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nenum CHARDEVQ_NO_REQUESTS  = -1;\nenum CHARDEV_CLOSE         = 0;\nenum CHARDEVQ_MAX_PRIORITY = 1;\nenum CHARDEVQ_DEV_PARMNUM  = 1;\n\nenum HANDLE_INFO_LEVEL_1 = 1;\nenum HANDLE_CHARTIME_PARMNUM = 1;\nenum HANDLE_CHARCOUNT_PARMNUM = 2;\n\nenum CHARDEV_STAT_OPENED = 2;\nenum CHARDEVQ_PRIORITY_PARMNUM = 2;\nenum CHARDEVQ_DEVS_PARMNUM = 3;\nenum CHARDEV_STAT_ERROR = 4;\nenum CHARDEVQ_NUMUSERS_PARMNUM = 4;\nenum CHARDEVQ_NUMAHEAD_PARMNUM = 5;\nenum CHARDEVQ_DEF_PRIORITY = 5;\nenum CHARDEVQ_PRIORITY_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+CHARDEVQ_PRIORITY_PARMNUM;\nenum CHARDEVQ_DEVS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+CHARDEVQ_DEVS_PARMNUM;\nenum CHARDEVQ_MIN_PRIORITY = 9;\n\nstruct CHARDEV_INFO_0 {\n LPWSTR ch0_dev;\n}\nalias CHARDEV_INFO_0* PCHARDEV_INFO_0, LPCHARDEV_INFO_0;\n\nstruct CHARDEV_INFO_1{\n    LPWSTR ch1_dev;\n    DWORD ch1_status;\n    LPWSTR ch1_username;\n    DWORD ch1_time;\n}\nalias CHARDEV_INFO_1* PCHARDEV_INFO_1, LPCHARDEV_INFO_1;\n\nstruct CHARDEVQ_INFO_0 {\n LPWSTR cq0_dev;\n}\nalias CHARDEVQ_INFO_0* PCHARDEVQ_INFO_0, LPCHARDEVQ_INFO_0;\n\nstruct CHARDEVQ_INFO_1{\n    LPWSTR cq1_dev;\n    DWORD cq1_priority;\n    LPWSTR cq1_devs;\n    DWORD cq1_numusers;\n    DWORD cq1_numahead;\n}\nalias CHARDEVQ_INFO_1* PCHARDEVQ_INFO_1, LPCHARDEVQ_INFO_1;\n\nstruct CHARDEVQ_INFO_1002 {\n    DWORD cq1002_priority;\n}\nalias CHARDEVQ_INFO_1002* PCHARDEVQ_INFO_1002, LPCHARDEVQ_INFO_1002;\n\nstruct CHARDEVQ_INFO_1003 {\n    LPWSTR cq1003_devs;\n}\nalias CHARDEVQ_INFO_1003* PCHARDEVQ_INFO_1003, LPCHARDEVQ_INFO_1003;\n\nstruct HANDLE_INFO_1{\n    DWORD hdli1_chartime;\n    DWORD hdli1_charcount;\n}\nalias HANDLE_INFO_1* PHANDLE_INFO_1, LPHANDLE_INFO_1;\n\nextern (Windows) {\n    NET_API_STATUS NetCharDevEnum(LPCWSTR, DWORD, PBYTE*, DWORD, PDWORD, PDWORD, PDWORD);\n    NET_API_STATUS NetCharDevGetInfo(LPCWSTR, LPCWSTR, DWORD, PBYTE*);\n    NET_API_STATUS NetCharDevControl(LPCWSTR, LPCWSTR, DWORD);\n    NET_API_STATUS NetCharDevQEnum(LPCWSTR, LPCWSTR, DWORD, PBYTE*, DWORD, PDWORD, PDWORD, PDWORD);\n    NET_API_STATUS NetCharDevQGetInfo(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, PBYTE*);\n    NET_API_STATUS NetCharDevQSetInfo(LPCWSTR, LPCWSTR, DWORD, PBYTE, PDWORD);\n    NET_API_STATUS NetCharDevQPurge(LPCWSTR, LPCWSTR);\n    NET_API_STATUS NetCharDevQPurgeSelf(LPCWSTR, LPCWSTR, LPCWSTR);\n    NET_API_STATUS NetHandleGetInfo(HANDLE, DWORD, PBYTE*);\n    NET_API_STATUS NetHandleSetInfo(HANDLE, DWORD, PBYTE, DWORD, PDWORD);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmconfig.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmconfig.d)\n */\nmodule core.sys.windows.lmconfig;\nversion (Windows):\n\n// All functions in this file are deprecated!\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\ndeprecated {\n    struct CONFIG_INFO_0 {\n        LPWSTR cfgi0_key;\n        LPWSTR cfgi0_data;\n    }\n\n    alias CONFIG_INFO_0* PCONFIG_INFO_0, LPCONFIG_INFO_0;\n\n    extern (Windows) {\n        NET_API_STATUS NetConfigGet(LPCWSTR, LPCWSTR, LPCWSTR, PBYTE*);\n        NET_API_STATUS NetConfigGetAll(LPCWSTR, LPCWSTR, PBYTE*);\n        NET_API_STATUS NetConfigSet(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, DWORD,\n          PBYTE, DWORD);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmcons.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmcons.d)\n */\nmodule core.sys.windows.lmcons;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.windef;\nprivate import core.sys.windows.lmerr; // for NERR_BASE\n\nconst TCHAR[]\n    MESSAGE_FILENAME = \"NETMSG\",\n    OS2MSG_FILENAME = \"BASE\",\n    HELP_MSG_FILENAME = \"NETH\";\n\nalias DWORD NET_API_STATUS, API_RET_TYPE;\n\nenum MIN_LANMAN_MESSAGE_ID = NERR_BASE;\nenum MAX_LANMAN_MESSAGE_ID = 5799;\n\nenum CNLEN        = 15; /* also in nddeapi.h */\nenum UNCLEN       = CNLEN + 2;\n\nenum DNLEN        = 15;\nenum LM20_CNLEN   = 15;\nenum LM20_DNLEN   = 15;\nenum LM20_SNLEN   = 15;\nenum LM20_STXTLEN = 63;\nenum LM20_UNCLEN  = LM20_CNLEN + 2;\nenum LM20_NNLEN   = 12;\nenum LM20_RMLEN   = LM20_UNCLEN + 1 + LM20_NNLEN;\nenum NNLEN        = 80;\nenum RMLEN        = UNCLEN + 1 + NNLEN;\nenum SNLEN        = 80;\nenum STXTLEN      = 256;\nenum PATHLEN      = 256;\nenum LM20_PATHLEN = 256;\nenum DEVLEN       = 80;\nenum LM20_DEVLEN  = 8;\nenum EVLEN        = 16;\nenum UNLEN        = 256;\nenum LM20_UNLEN   = 20;\nenum GNLEN        = UNLEN;\nenum LM20_GNLEN   = LM20_UNLEN;\nenum PWLEN        = 256;\nenum LM20_PWLEN   = 14;\nenum SHPWLEN      = 8;\nenum CLTYPE_LEN   = 12;\nenum QNLEN        = NNLEN;\nenum LM20_QNLEN   = LM20_NNLEN;\n\nenum MAXCOMMENTSZ = 256;\nenum LM20_MAXCOMMENTSZ = 48;\nenum ALERTSZ      = 128;\nenum MAXDEVENTRIES = 32;// (sizeof(int)*8);\nenum NETBIOS_NAME_LEN = 16;\nenum DWORD MAX_PREFERRED_LENGTH = -1;\nenum CRYPT_KEY_LEN = 7;\nenum CRYPT_TXT_LEN = 8;\nenum ENCRYPTED_PWLEN = 16;\nenum SESSION_PWLEN = 24;\nenum SESSION_CRYPT_KLEN = 21;\n\nenum PARMNUM_ALL = 0;\nenum DWORD PARM_ERROR_UNKNOWN = -1;\nenum PARM_ERROR_NONE = 0;\nenum PARMNUM_BASE_INFOLEVEL = 1000;\n\nenum PLATFORM_ID_DOS = 300;\nenum PLATFORM_ID_OS2 = 400;\nenum PLATFORM_ID_NT  = 500;\nenum PLATFORM_ID_OSF = 600;\nenum PLATFORM_ID_VMS = 700;\n\n// this is a new typedef in W2K, but it should be harmless for earlier Windows versions.\nversion (Unicode) {\n    alias LPWSTR LMSTR;\n    alias LPCWSTR LMCSTR;\n} else {\n    alias LPSTR LMSTR;\n    alias LPCSTR LMCSTR;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmerr.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmerr.d)\n */\nmodule core.sys.windows.lmerr;\nversion (Windows):\n\nimport core.sys.windows.winerror;\n\nenum {\n    NERR_Success                      = 0,\n    NERR_BASE                         = 2100,\n    NERR_NetNotStarted                = NERR_BASE + 2,\n    NERR_UnknownServer,\n    NERR_ShareMem,\n    NERR_NoNetworkResource,\n    NERR_RemoteOnly,\n    NERR_DevNotRedirected,\n    NERR_ServerNotStarted             = NERR_BASE + 14,\n    NERR_ItemNotFound,\n    NERR_UnknownDevDir,\n    NERR_RedirectedPath,\n    NERR_DuplicateShare,\n    NERR_NoRoom,\n    NERR_TooManyItems                 = NERR_BASE + 21,\n    NERR_InvalidMaxUsers,\n    NERR_BufTooSmall,\n    NERR_RemoteErr                    = NERR_BASE + 27,\n    NERR_LanmanIniError               = NERR_BASE + 31,\n    NERR_NetworkError                 = NERR_BASE + 36,\n    NERR_WkstaInconsistentState,\n    NERR_WkstaNotStarted,\n    NERR_BrowserNotStarted,\n    NERR_InternalError,\n    NERR_BadTransactConfig,\n    NERR_InvalidAPI,\n    NERR_BadEventName,\n    NERR_DupNameReboot,\n    NERR_CfgCompNotFound              = NERR_BASE + 46,\n    NERR_CfgParamNotFound,\n    NERR_LineTooLong                  = NERR_BASE + 49,\n    NERR_QNotFound,\n    NERR_JobNotFound,\n    NERR_DestNotFound,\n    NERR_DestExists,\n    NERR_QExists,\n    NERR_QNoRoom,\n    NERR_JobNoRoom,\n    NERR_DestNoRoom,\n    NERR_DestIdle,\n    NERR_DestInvalidOp,\n    NERR_ProcNoRespond,\n    NERR_SpoolerNotLoaded,\n    NERR_DestInvalidState,\n    NERR_QInvalidState,\n    NERR_JobInvalidState,\n    NERR_SpoolNoMemory,\n    NERR_DriverNotFound,\n    NERR_DataTypeInvalid,\n    NERR_ProcNotFound,\n    NERR_ServiceTableLocked           = NERR_BASE + 80,\n    NERR_ServiceTableFull,\n    NERR_ServiceInstalled,\n    NERR_ServiceEntryLocked,\n    NERR_ServiceNotInstalled,\n    NERR_BadServiceName,\n    NERR_ServiceCtlTimeout,\n    NERR_ServiceCtlBusy,\n    NERR_BadServiceProgName,\n    NERR_ServiceNotCtrl,\n    NERR_ServiceKillProc,\n    NERR_ServiceCtlNotValid,\n    NERR_NotInDispatchTbl,\n    NERR_BadControlRecv,\n    NERR_ServiceNotStarting,\n    NERR_AlreadyLoggedOn              = NERR_BASE + 100,\n    NERR_NotLoggedOn,\n    NERR_BadUsername,\n    NERR_BadPassword,\n    NERR_UnableToAddName_W,\n    NERR_UnableToAddName_F,\n    NERR_UnableToDelName_W,\n    NERR_UnableToDelName_F,\n    NERR_LogonsPaused                 = NERR_BASE + 109,\n    NERR_LogonServerConflict,\n    NERR_LogonNoUserPath,\n    NERR_LogonScriptError,\n    NERR_StandaloneLogon              = NERR_BASE + 114,\n    NERR_LogonServerNotFound,\n    NERR_LogonDomainExists,\n    NERR_NonValidatedLogon,\n    NERR_ACFNotFound                  = NERR_BASE + 119,\n    NERR_GroupNotFound,\n    NERR_UserNotFound,\n    NERR_ResourceNotFound,\n    NERR_GroupExists,\n    NERR_UserExists,\n    NERR_ResourceExists,\n    NERR_NotPrimary,\n    NERR_ACFNotLoaded,\n    NERR_ACFNoRoom,\n    NERR_ACFFileIOFail,\n    NERR_ACFTooManyLists,\n    NERR_UserLogon,\n    NERR_ACFNoParent,\n    NERR_CanNotGrowSegment,\n    NERR_SpeGroupOp,\n    NERR_NotInCache,\n    NERR_UserInGroup,\n    NERR_UserNotInGroup,\n    NERR_AccountUndefined,\n    NERR_AccountExpired,\n    NERR_InvalidWorkstation,\n    NERR_InvalidLogonHours,\n    NERR_PasswordExpired,\n    NERR_PasswordCantChange,\n    NERR_PasswordHistConflict,\n    NERR_PasswordTooShort,\n    NERR_PasswordTooRecent,\n    NERR_InvalidDatabase,\n    NERR_DatabaseUpToDate,\n    NERR_SyncRequired,\n    NERR_UseNotFound,\n    NERR_BadAsgType,\n    NERR_DeviceIsShared,\n    NERR_NoComputerName               = NERR_BASE + 170,\n    NERR_MsgAlreadyStarted,\n    NERR_MsgInitFailed,\n    NERR_NameNotFound,\n    NERR_AlreadyForwarded,\n    NERR_AddForwarded,\n    NERR_AlreadyExists,\n    NERR_TooManyNames,\n    NERR_DelComputerName,\n    NERR_LocalForward,\n    NERR_GrpMsgProcessor,\n    NERR_PausedRemote,\n    NERR_BadReceive,\n    NERR_NameInUse,\n    NERR_MsgNotStarted,\n    NERR_NotLocalName,\n    NERR_NoForwardName,\n    NERR_RemoteFull,\n    NERR_NameNotForwarded,\n    NERR_TruncatedBroadcast,\n    NERR_InvalidDevice                = NERR_BASE + 194,\n    NERR_WriteFault,\n    NERR_DuplicateName                = NERR_BASE + 197,\n    NERR_DeleteLater,\n    NERR_IncompleteDel,\n    NERR_MultipleNets,\n    NERR_NetNameNotFound              = NERR_BASE + 210,\n    NERR_DeviceNotShared,\n    NERR_ClientNameNotFound,\n    NERR_FileIdNotFound               = NERR_BASE + 214,\n    NERR_ExecFailure,\n    NERR_TmpFile,\n    NERR_TooMuchData,\n    NERR_DeviceShareConflict,\n    NERR_BrowserTableIncomplete,\n    NERR_NotLocalDomain,\n    NERR_DevInvalidOpCode             = NERR_BASE + 231,\n    NERR_DevNotFound,\n    NERR_DevNotOpen,\n    NERR_BadQueueDevString,\n    NERR_BadQueuePriority,\n    NERR_NoCommDevs                   = NERR_BASE + 237,\n    NERR_QueueNotFound,\n    NERR_BadDevString                 = NERR_BASE + 240,\n    NERR_BadDev,\n    NERR_InUseBySpooler,\n    NERR_CommDevInUse,\n    NERR_InvalidComputer              = NERR_BASE + 251,\n    NERR_MaxLenExceeded               = NERR_BASE + 254,\n    NERR_BadComponent                 = NERR_BASE + 256,\n    NERR_CantType,\n    NERR_TooManyEntries               = NERR_BASE + 262,\n    NERR_ProfileFileTooBig            = NERR_BASE + 270,\n    NERR_ProfileOffset,\n    NERR_ProfileCleanup,\n    NERR_ProfileUnknownCmd,\n    NERR_ProfileLoadErr,\n    NERR_ProfileSaveErr,\n    NERR_LogOverflow                  = NERR_BASE + 277,\n    NERR_LogFileChanged,\n    NERR_LogFileCorrupt,\n    NERR_SourceIsDir,\n    NERR_BadSource,\n    NERR_BadDest,\n    NERR_DifferentServers,\n    NERR_RunSrvPaused                 = NERR_BASE + 285,\n    NERR_ErrCommRunSrv                = NERR_BASE + 289,\n    NERR_ErrorExecingGhost            = NERR_BASE + 291,\n    NERR_ShareNotFound,\n    NERR_InvalidLana                  = NERR_BASE + 300,\n    NERR_OpenFiles,\n    NERR_ActiveConns,\n    NERR_BadPasswordCore,\n    NERR_DevInUse,\n    NERR_LocalDrive,\n    NERR_AlertExists                  = NERR_BASE + 330,\n    NERR_TooManyAlerts,\n    NERR_NoSuchAlert,\n    NERR_BadRecipient,\n    NERR_AcctLimitExceeded,\n    NERR_InvalidLogSeek               = NERR_BASE + 340,\n    NERR_BadUasConfig                 = NERR_BASE + 350,\n    NERR_InvalidUASOp,\n    NERR_LastAdmin,\n    NERR_DCNotFound,\n    NERR_LogonTrackingError,\n    NERR_NetlogonNotStarted,\n    NERR_CanNotGrowUASFile,\n    NERR_TimeDiffAtDC,\n    NERR_PasswordMismatch,\n    NERR_NoSuchServer                 = NERR_BASE + 360,\n    NERR_NoSuchSession,\n    NERR_NoSuchConnection,\n    NERR_TooManyServers,\n    NERR_TooManySessions,\n    NERR_TooManyConnections,\n    NERR_TooManyFiles,\n    NERR_NoAlternateServers,\n    NERR_TryDownLevel                 = NERR_BASE + 370,\n    NERR_UPSDriverNotStarted          = NERR_BASE + 380,\n    NERR_UPSInvalidConfig,\n    NERR_UPSInvalidCommPort,\n    NERR_UPSSignalAsserted,\n    NERR_UPSShutdownFailed,\n    NERR_BadDosRetCode                = NERR_BASE + 400,\n    NERR_ProgNeedsExtraMem,\n    NERR_BadDosFunction,\n    NERR_RemoteBootFailed,\n    NERR_BadFileCheckSum,\n    NERR_NoRplBootSystem,\n    NERR_RplLoadrNetBiosErr,\n    NERR_RplLoadrDiskErr,\n    NERR_ImageParamErr,\n    NERR_TooManyImageParams,\n    NERR_NonDosFloppyUsed,\n    NERR_RplBootRestart,\n    NERR_RplSrvrCallFailed,\n    NERR_CantConnectRplSrvr,\n    NERR_CantOpenImageFile,\n    NERR_CallingRplSrvr,\n    NERR_StartingRplBoot,\n    NERR_RplBootServiceTerm,\n    NERR_RplBootStartFailed,\n    NERR_RPL_CONNECTED,\n    NERR_BrowserConfiguredToNotRun    = NERR_BASE + 450,\n    NERR_RplNoAdaptersStarted         = NERR_BASE + 510,\n    NERR_RplBadRegistry,\n    NERR_RplBadDatabase,\n    NERR_RplRplfilesShare,\n    NERR_RplNotRplServer,\n    NERR_RplCannotEnum,\n    NERR_RplWkstaInfoCorrupted,\n    NERR_RplWkstaNotFound,\n    NERR_RplWkstaNameUnavailable,\n    NERR_RplProfileInfoCorrupted,\n    NERR_RplProfileNotFound,\n    NERR_RplProfileNameUnavailable,\n    NERR_RplProfileNotEmpty,\n    NERR_RplConfigInfoCorrupted,\n    NERR_RplConfigNotFound,\n    NERR_RplAdapterInfoCorrupted,\n    NERR_RplInternal,\n    NERR_RplVendorInfoCorrupted,\n    NERR_RplBootInfoCorrupted,\n    NERR_RplWkstaNeedsUserAcct,\n    NERR_RplNeedsRPLUSERAcct,\n    NERR_RplBootNotFound,\n    NERR_RplIncompatibleProfile,\n    NERR_RplAdapterNameUnavailable,\n    NERR_RplConfigNotEmpty,\n    NERR_RplBootInUse,\n    NERR_RplBackupDatabase,\n    NERR_RplAdapterNotFound,\n    NERR_RplVendorNotFound,\n    NERR_RplVendorNameUnavailable,\n    NERR_RplBootNameUnavailable,\n    NERR_RplConfigNameUnavailable,\n    NERR_DfsInternalCorruption        = NERR_BASE + 560,\n    NERR_DfsVolumeDataCorrupt,\n    NERR_DfsNoSuchVolume,\n    NERR_DfsVolumeAlreadyExists,\n    NERR_DfsAlreadyShared,\n    NERR_DfsNoSuchShare,\n    NERR_DfsNotALeafVolume,\n    NERR_DfsLeafVolume,\n    NERR_DfsVolumeHasMultipleServers,\n    NERR_DfsCantCreateJunctionPoint,\n    NERR_DfsServerNotDfsAware,\n    NERR_DfsBadRenamePath,\n    NERR_DfsVolumeIsOffline,\n    NERR_DfsNoSuchServer,\n    NERR_DfsCyclicalName,\n    NERR_DfsNotSupportedInServerDfs,\n    NERR_DfsDuplicateService,\n    NERR_DfsCantRemoveLastServerShare,\n    NERR_DfsVolumeIsInterDfs,\n    NERR_DfsInconsistent,\n    NERR_DfsServerUpgraded,\n    NERR_DfsDataIsIdentical,\n    NERR_DfsCantRemoveDfsRoot,\n    NERR_DfsChildOrParentInDfs,\n    NERR_DfsInternalError             = NERR_BASE + 590,\n    MAX_NERR                          = NERR_BASE + 899\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmerrlog.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmerrlog.d)\n */\nmodule core.sys.windows.lmerrlog;\nversion (Windows):\n\n// COMMENT: This appears to be only for Win16. All functions are deprecated.\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\nprivate import core.sys.windows.lmaudit; // for LPHLOG\n\nenum ERRLOG_BASE=3100;\nenum ERRLOG2_BASE=5700;\nenum LOGFLAGS_FORWARD=0;\nenum LOGFLAGS_BACKWARD=1;\nenum LOGFLAGS_SEEK=2;\nenum NELOG_Internal_Error=ERRLOG_BASE;\nenum NELOG_Resource_Shortage=(ERRLOG_BASE+1);\nenum NELOG_Unable_To_Lock_Segment=(ERRLOG_BASE+2);\nenum NELOG_Unable_To_Unlock_Segment=(ERRLOG_BASE+3);\nenum NELOG_Uninstall_Service=(ERRLOG_BASE+4);\nenum NELOG_Init_Exec_Fail=(ERRLOG_BASE+5);\nenum NELOG_Ncb_Error=(ERRLOG_BASE+6);\nenum NELOG_Net_Not_Started=(ERRLOG_BASE+7);\nenum NELOG_Ioctl_Error=(ERRLOG_BASE+8);\nenum NELOG_System_Semaphore=(ERRLOG_BASE+9);\nenum NELOG_Init_OpenCreate_Err=(ERRLOG_BASE+10);\nenum NELOG_NetBios=(ERRLOG_BASE+11);\nenum NELOG_SMB_Illegal=(ERRLOG_BASE+12);\nenum NELOG_Service_Fail=(ERRLOG_BASE+13);\nenum NELOG_Entries_Lost=(ERRLOG_BASE+14);\nenum NELOG_Init_Seg_Overflow=(ERRLOG_BASE+20);\nenum NELOG_Srv_No_Mem_Grow=(ERRLOG_BASE+21);\nenum NELOG_Access_File_Bad=(ERRLOG_BASE+22);\nenum NELOG_Srvnet_Not_Started=(ERRLOG_BASE+23);\nenum NELOG_Init_Chardev_Err=(ERRLOG_BASE+24);\nenum NELOG_Remote_API=(ERRLOG_BASE+25);\nenum NELOG_Ncb_TooManyErr=(ERRLOG_BASE+26);\nenum NELOG_Mailslot_err=(ERRLOG_BASE+27);\nenum NELOG_ReleaseMem_Alert=(ERRLOG_BASE+28);\nenum NELOG_AT_cannot_write=(ERRLOG_BASE+29);\nenum NELOG_Cant_Make_Msg_File=(ERRLOG_BASE+30);\nenum NELOG_Exec_Netservr_NoMem=(ERRLOG_BASE+31);\nenum NELOG_Server_Lock_Failure=(ERRLOG_BASE+32);\nenum NELOG_Msg_Shutdown=(ERRLOG_BASE+40);\nenum NELOG_Msg_Sem_Shutdown=(ERRLOG_BASE+41);\nenum NELOG_Msg_Log_Err=(ERRLOG_BASE+50);\nenum NELOG_VIO_POPUP_ERR=(ERRLOG_BASE+51);\nenum NELOG_Msg_Unexpected_SMB_Type=(ERRLOG_BASE+52);\nenum NELOG_Wksta_Infoseg=(ERRLOG_BASE+60);\nenum NELOG_Wksta_Compname=(ERRLOG_BASE+61);\nenum NELOG_Wksta_BiosThreadFailure=(ERRLOG_BASE+62);\nenum NELOG_Wksta_IniSeg=(ERRLOG_BASE+63);\nenum NELOG_Wksta_HostTab_Full=(ERRLOG_BASE+64);\nenum NELOG_Wksta_Bad_Mailslot_SMB=(ERRLOG_BASE+65);\nenum NELOG_Wksta_UASInit=(ERRLOG_BASE+66);\nenum NELOG_Wksta_SSIRelogon=(ERRLOG_BASE+67);\nenum NELOG_Build_Name=(ERRLOG_BASE+70);\nenum NELOG_Name_Expansion=(ERRLOG_BASE+71);\nenum NELOG_Message_Send=(ERRLOG_BASE+72);\nenum NELOG_Mail_Slt_Err=(ERRLOG_BASE+73);\nenum NELOG_AT_cannot_read=(ERRLOG_BASE+74);\nenum NELOG_AT_sched_err=(ERRLOG_BASE+75);\nenum NELOG_AT_schedule_file_created=(ERRLOG_BASE+76);\nenum NELOG_Srvnet_NB_Open=(ERRLOG_BASE+77);\nenum NELOG_AT_Exec_Err=(ERRLOG_BASE+78);\nenum NELOG_Lazy_Write_Err=(ERRLOG_BASE+80);\nenum NELOG_HotFix=(ERRLOG_BASE+81);\nenum NELOG_HardErr_From_Server=(ERRLOG_BASE+82);\nenum NELOG_LocalSecFail1=(ERRLOG_BASE+83);\nenum NELOG_LocalSecFail2=(ERRLOG_BASE+84);\nenum NELOG_LocalSecFail3=(ERRLOG_BASE+85);\nenum NELOG_LocalSecGeneralFail=(ERRLOG_BASE+86);\nenum NELOG_NetWkSta_Internal_Error=(ERRLOG_BASE+90);\nenum NELOG_NetWkSta_No_Resource=(ERRLOG_BASE+91);\nenum NELOG_NetWkSta_SMB_Err=(ERRLOG_BASE+92);\nenum NELOG_NetWkSta_VC_Err=(ERRLOG_BASE+93);\nenum NELOG_NetWkSta_Stuck_VC_Err=(ERRLOG_BASE+94);\nenum NELOG_NetWkSta_NCB_Err=(ERRLOG_BASE+95);\nenum NELOG_NetWkSta_Write_Behind_Err=(ERRLOG_BASE+96);\nenum NELOG_NetWkSta_Reset_Err=(ERRLOG_BASE+97);\nenum NELOG_NetWkSta_Too_Many=(ERRLOG_BASE+98);\nenum NELOG_Srv_Thread_Failure=(ERRLOG_BASE+104);\nenum NELOG_Srv_Close_Failure=(ERRLOG_BASE+105);\nenum NELOG_ReplUserCurDir=(ERRLOG_BASE+106);\nenum NELOG_ReplCannotMasterDir=(ERRLOG_BASE+107);\nenum NELOG_ReplUpdateError=(ERRLOG_BASE+108);\nenum NELOG_ReplLostMaster=(ERRLOG_BASE+109);\nenum NELOG_NetlogonAuthDCFail=(ERRLOG_BASE+110);\nenum NELOG_ReplLogonFailed=(ERRLOG_BASE+111);\nenum NELOG_ReplNetErr=(ERRLOG_BASE+112);\nenum NELOG_ReplMaxFiles=(ERRLOG_BASE+113);\nenum NELOG_ReplMaxTreeDepth=(ERRLOG_BASE+114);\nenum NELOG_ReplBadMsg=(ERRLOG_BASE+115);\nenum NELOG_ReplSysErr=(ERRLOG_BASE+116);\nenum NELOG_ReplUserLoged=(ERRLOG_BASE+117);\nenum NELOG_ReplBadImport=(ERRLOG_BASE+118);\nenum NELOG_ReplBadExport=(ERRLOG_BASE+119);\nenum NELOG_ReplSignalFileErr=(ERRLOG_BASE+120);\nenum NELOG_DiskFT=(ERRLOG_BASE+121);\nenum NELOG_ReplAccessDenied=(ERRLOG_BASE+122);\nenum NELOG_NetlogonFailedPrimary=(ERRLOG_BASE+123);\nenum NELOG_NetlogonPasswdSetFailed=(ERRLOG_BASE+124);\nenum NELOG_NetlogonTrackingError=(ERRLOG_BASE+125);\nenum NELOG_NetlogonSyncError=(ERRLOG_BASE+126);\nenum NELOG_UPS_PowerOut=(ERRLOG_BASE+130);\nenum NELOG_UPS_Shutdown=(ERRLOG_BASE+131);\nenum NELOG_UPS_CmdFileError=(ERRLOG_BASE+132);\nenum NELOG_UPS_CannotOpenDriver=(ERRLOG_BASE+133);\nenum NELOG_UPS_PowerBack=(ERRLOG_BASE+134);\nenum NELOG_UPS_CmdFileConfig=(ERRLOG_BASE+135);\nenum NELOG_UPS_CmdFileExec=(ERRLOG_BASE+136);\nenum NELOG_Missing_Parameter=(ERRLOG_BASE+150);\nenum NELOG_Invalid_Config_Line=(ERRLOG_BASE+151);\nenum NELOG_Invalid_Config_File=(ERRLOG_BASE+152);\nenum NELOG_File_Changed=(ERRLOG_BASE+153);\nenum NELOG_Files_Dont_Fit=(ERRLOG_BASE+154);\nenum NELOG_Wrong_DLL_Version=(ERRLOG_BASE+155);\nenum NELOG_Error_in_DLL=(ERRLOG_BASE+156);\nenum NELOG_System_Error=(ERRLOG_BASE+157);\nenum NELOG_FT_ErrLog_Too_Large=(ERRLOG_BASE+158);\nenum NELOG_FT_Update_In_Progress=(ERRLOG_BASE+159);\nenum NELOG_OEM_Code=(ERRLOG_BASE+199);\nenum NELOG_NetlogonSSIInitError=ERRLOG2_BASE;\nenum NELOG_NetlogonFailedToUpdateTrustList=(ERRLOG2_BASE+1);\nenum NELOG_NetlogonFailedToAddRpcInterface=(ERRLOG2_BASE+2);\nenum NELOG_NetlogonFailedToReadMailslot=(ERRLOG2_BASE+3);\nenum NELOG_NetlogonFailedToRegisterSC=(ERRLOG2_BASE+4);\nenum NELOG_NetlogonChangeLogCorrupt=(ERRLOG2_BASE+5);\nenum NELOG_NetlogonFailedToCreateShare=(ERRLOG2_BASE+6);\nenum NELOG_NetlogonDownLevelLogonFailed=(ERRLOG2_BASE+7);\nenum NELOG_NetlogonDownLevelLogoffFailed=(ERRLOG2_BASE+8);\nenum NELOG_NetlogonNTLogonFailed=(ERRLOG2_BASE+9);\nenum NELOG_NetlogonNTLogoffFailed=(ERRLOG2_BASE+10);\nenum NELOG_NetlogonPartialSyncCallSuccess=(ERRLOG2_BASE+11);\nenum NELOG_NetlogonPartialSyncCallFailed=(ERRLOG2_BASE+12);\nenum NELOG_NetlogonFullSyncCallSuccess=(ERRLOG2_BASE+13);\nenum NELOG_NetlogonFullSyncCallFailed=(ERRLOG2_BASE+14);\nenum NELOG_NetlogonPartialSyncSuccess=(ERRLOG2_BASE+15);\nenum NELOG_NetlogonPartialSyncFailed=(ERRLOG2_BASE+16);\nenum NELOG_NetlogonFullSyncSuccess=(ERRLOG2_BASE+17);\nenum NELOG_NetlogonFullSyncFailed=(ERRLOG2_BASE+18);\nenum NELOG_NetlogonAuthNoDomainController=(ERRLOG2_BASE+19);\nenum NELOG_NetlogonAuthNoTrustLsaSecret=(ERRLOG2_BASE+20);\nenum NELOG_NetlogonAuthNoTrustSamAccount=(ERRLOG2_BASE+21);\nenum NELOG_NetlogonServerAuthFailed=(ERRLOG2_BASE+22);\nenum NELOG_NetlogonServerAuthNoTrustSamAccount=(ERRLOG2_BASE+23);\nenum NELOG_FailedToRegisterSC=(ERRLOG2_BASE+24);\nenum NELOG_FailedToSetServiceStatus=(ERRLOG2_BASE+25);\nenum NELOG_FailedToGetComputerName=(ERRLOG2_BASE+26);\nenum NELOG_DriverNotLoaded=(ERRLOG2_BASE+27);\nenum NELOG_NoTranportLoaded=(ERRLOG2_BASE+28);\nenum NELOG_NetlogonFailedDomainDelta=(ERRLOG2_BASE+29);\nenum NELOG_NetlogonFailedGlobalGroupDelta=(ERRLOG2_BASE+30);\nenum NELOG_NetlogonFailedLocalGroupDelta=(ERRLOG2_BASE+31);\nenum NELOG_NetlogonFailedUserDelta=(ERRLOG2_BASE+32);\nenum NELOG_NetlogonFailedPolicyDelta=(ERRLOG2_BASE+33);\nenum NELOG_NetlogonFailedTrustedDomainDelta=(ERRLOG2_BASE+34);\nenum NELOG_NetlogonFailedAccountDelta=(ERRLOG2_BASE+35);\nenum NELOG_NetlogonFailedSecretDelta=(ERRLOG2_BASE+36);\nenum NELOG_NetlogonSystemError=(ERRLOG2_BASE+37);\nenum NELOG_NetlogonDuplicateMachineAccounts=(ERRLOG2_BASE+38);\nenum NELOG_NetlogonTooManyGlobalGroups=(ERRLOG2_BASE+39);\nenum NELOG_NetlogonBrowserDriver=(ERRLOG2_BASE+40);\nenum NELOG_NetlogonAddNameFailure=(ERRLOG2_BASE+41);\nenum NELOG_RplMessages=(ERRLOG2_BASE+42);\nenum NELOG_RplXnsBoot=(ERRLOG2_BASE+43);\nenum NELOG_RplSystem=(ERRLOG2_BASE+44);\nenum NELOG_RplWkstaTimeout=(ERRLOG2_BASE+45);\nenum NELOG_RplWkstaFileOpen=(ERRLOG2_BASE+46);\nenum NELOG_RplWkstaFileRead=(ERRLOG2_BASE+47);\nenum NELOG_RplWkstaMemory=(ERRLOG2_BASE+48);\nenum NELOG_RplWkstaFileChecksum=(ERRLOG2_BASE+49);\nenum NELOG_RplWkstaFileLineCount=(ERRLOG2_BASE+50);\nenum NELOG_RplWkstaBbcFile=(ERRLOG2_BASE+51);\nenum NELOG_RplWkstaFileSize=(ERRLOG2_BASE+52);\nenum NELOG_RplWkstaInternal=(ERRLOG2_BASE+53);\nenum NELOG_RplWkstaWrongVersion=(ERRLOG2_BASE+54);\nenum NELOG_RplWkstaNetwork=(ERRLOG2_BASE+55);\nenum NELOG_RplAdapterResource=(ERRLOG2_BASE+56);\nenum NELOG_RplFileCopy=(ERRLOG2_BASE+57);\nenum NELOG_RplFileDelete=(ERRLOG2_BASE+58);\nenum NELOG_RplFilePerms=(ERRLOG2_BASE+59);\nenum NELOG_RplCheckConfigs=(ERRLOG2_BASE+60);\nenum NELOG_RplCreateProfiles=(ERRLOG2_BASE+61);\nenum NELOG_RplRegistry=(ERRLOG2_BASE+62);\nenum NELOG_RplReplaceRPLDISK=(ERRLOG2_BASE+63);\nenum NELOG_RplCheckSecurity=(ERRLOG2_BASE+64);\nenum NELOG_RplBackupDatabase=(ERRLOG2_BASE+65);\nenum NELOG_RplInitDatabase=(ERRLOG2_BASE+66);\nenum NELOG_RplRestoreDatabaseFailure=(ERRLOG2_BASE+67);\nenum NELOG_RplRestoreDatabaseSuccess=(ERRLOG2_BASE+68);\nenum NELOG_RplInitRestoredDatabase=(ERRLOG2_BASE+69);\nenum NELOG_NetlogonSessionTypeWrong=(ERRLOG2_BASE+70);\n\nstruct ERROR_LOG {\n    DWORD el_len;\n    DWORD el_reserved;\n    DWORD el_time;\n    DWORD el_error;\n    LPWSTR el_name;\n    LPWSTR el_text;\n    LPBYTE el_data;\n    DWORD el_data_size;\n    DWORD el_nstrings;\n}\nalias ERROR_LOG* PERROR_LOG, LPERROR_LOG;\n\nextern (Windows) {\n    deprecated {\n        NET_API_STATUS NetErrorLogClear(LPCWSTR, LPCWSTR, LPBYTE);\n        NET_API_STATUS NetErrorLogRead(LPCWSTR, LPWSTR, LPHLOG, DWORD,\n          LPDWORD, DWORD, DWORD, LPBYTE*, DWORD, LPDWORD, LPDWORD);\n        NET_API_STATUS NetErrorLogWrite(LPBYTE, DWORD, LPCWSTR, LPBYTE,\n          DWORD, LPBYTE, DWORD, LPBYTE);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmmsg.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmmsg.d)\n */\nmodule core.sys.windows.lmmsg;\nversion (Windows):\npragma(lib, \"netapi32\");\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef, core.sys.windows.w32api;\n\nstatic assert (_WIN32_WINNT >= 0x501,\n    \"core.sys.windows.lmmsg is available only if version WindowsXP, Windows2003 \"\n    ~ \"or WindowsVista is set\");\n\nenum MSGNAME_NOT_FORWARDED  = 0;\nenum MSGNAME_FORWARDED_TO   = 4;\nenum MSGNAME_FORWARDED_FROM = 16;\n\nstruct MSG_INFO_0 {\n    LPWSTR msgi0_name;\n}\nalias MSG_INFO_0* PMSG_INFO_0, LPMSG_INFO_0;\n\nstruct MSG_INFO_1 {\n    LPWSTR msgi1_name;\n    DWORD msgi1_forward_flag;\n    LPWSTR msgi1_forward;\n}\nalias MSG_INFO_1* PMSG_INFO_1, LPMSG_INFO_1;\n\nextern (Windows) {\n    NET_API_STATUS NetMessageBufferSend(LPCWSTR, LPCWSTR, LPCWSTR, PBYTE,\n      DWORD);\n    NET_API_STATUS NetMessageNameAdd(LPCWSTR, LPCWSTR);\n    NET_API_STATUS NetMessageNameDel(LPCWSTR, LPCWSTR);\n    NET_API_STATUS NetMessageNameEnum(LPCWSTR, DWORD, PBYTE*, DWORD, PDWORD,\n      PDWORD, PDWORD);\n    NET_API_STATUS NetMessageNameGetInfo(LPCWSTR, LPCWSTR, DWORD, PBYTE*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmremutl.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmremutl.d)\n */\nmodule core.sys.windows.lmremutl;\nversion (Windows):\npragma(lib, \"netapi32\");\n\n// D Conversion Note: DESC_CHAR is defined as TCHAR.\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nenum SUPPORTS_REMOTE_ADMIN_PROTOCOL =  2;\nenum SUPPORTS_RPC                   =  4;\nenum SUPPORTS_SAM_PROTOCOL          =  8;\nenum SUPPORTS_UNICODE               = 16;\nenum SUPPORTS_LOCAL                 = 32;\nenum SUPPORTS_ANY                   = 0xFFFFFFFF;\n\nenum NO_PERMISSION_REQUIRED = 1;\nenum ALLOCATE_RESPONSE      = 2;\nenum USE_SPECIFIC_TRANSPORT = 0x80000000;\n\n//[Yes] #ifndef DESC_CHAR_UNICODE\n//alias CHAR DESC_CHAR;\n//} else {\n//[No] #else\n//[No] typedef WCHAR DESC_CHAR;\n//[No] #endif\n// FIXME (D): Is this OK?\nalias TCHAR DESC_CHAR;\n\nalias DESC_CHAR* LPDESC;\n\nstruct TIME_OF_DAY_INFO {\n    DWORD tod_elapsedt;\n    DWORD tod_msecs;\n    DWORD tod_hours;\n    DWORD tod_mins;\n    DWORD tod_secs;\n    DWORD tod_hunds;\n    LONG  tod_timezone;\n    DWORD tod_tinterval;\n    DWORD tod_day;\n    DWORD tod_month;\n    DWORD tod_year;\n    DWORD tod_weekday;\n}\nalias TIME_OF_DAY_INFO* PTIME_OF_DAY_INFO, LPTIME_OF_DAY_INFO;\n\nextern (Windows) {\n    NET_API_STATUS NetRemoteTOD(LPCWSTR, PBYTE*);\n    NET_API_STATUS NetRemoteComputerSupports(LPCWSTR, DWORD, PDWORD);\n    NET_API_STATUS RxRemoteApi(DWORD, LPCWSTR, LPDESC, LPDESC, LPDESC,\n      LPDESC, LPDESC, LPDESC, LPDESC, DWORD, ...);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmrepl.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmrepl.d)\n */\nmodule core.sys.windows.lmrepl;\nversion (Windows):\npragma(lib, \"netapi32\");\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nenum REPL_ROLE_EXPORT=1;\nenum REPL_ROLE_IMPORT=2;\nenum REPL_ROLE_BOTH=3;\n\nenum REPL_INTERVAL_INFOLEVEL  = PARMNUM_BASE_INFOLEVEL+0;\nenum REPL_PULSE_INFOLEVEL     = PARMNUM_BASE_INFOLEVEL+1;\nenum REPL_GUARDTIME_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+2;\nenum REPL_RANDOM_INFOLEVEL    = PARMNUM_BASE_INFOLEVEL+3;\n\nenum REPL_UNLOCK_NOFORCE=0;\nenum REPL_UNLOCK_FORCE=1;\nenum REPL_STATE_OK=0;\nenum REPL_STATE_NO_MASTER=1;\nenum REPL_STATE_NO_SYNC=2;\nenum REPL_STATE_NEVER_REPLICATED=3;\nenum REPL_INTEGRITY_FILE=1;\nenum REPL_INTEGRITY_TREE=2;\nenum REPL_EXTENT_FILE=1;\nenum REPL_EXTENT_TREE=2;\n\nenum REPL_EXPORT_INTEGRITY_INFOLEVEL = PARMNUM_BASE_INFOLEVEL+0;\nenum REPL_EXPORT_EXTENT_INFOLEVEL    = PARMNUM_BASE_INFOLEVEL+1;\n\nstruct REPL_INFO_0 {\n    DWORD rp0_role;\n    LPWSTR rp0_exportpath;\n    LPWSTR rp0_exportlist;\n    LPWSTR rp0_importpath;\n    LPWSTR rp0_importlist;\n    LPWSTR rp0_logonusername;\n    DWORD rp0_interval;\n    DWORD rp0_pulse;\n    DWORD rp0_guardtime;\n    DWORD rp0_random;\n}\nalias REPL_INFO_0* PREPL_INFO_0, LPREPL_INFO_0;\n\nstruct REPL_INFO_1000 {\n    DWORD rp1000_interval;\n}\nalias REPL_INFO_1000* PREPL_INFO_1000, LPREPL_INFO_1000;\n\nstruct REPL_INFO_1001 {\n    DWORD rp1001_pulse;\n}\nalias REPL_INFO_1001* PREPL_INFO_1001, LPREPL_INFO_1001;\n\nstruct REPL_INFO_1002 {\n    DWORD rp1002_guardtime;\n}\nalias REPL_INFO_1002* PREPL_INFO_1002, LPREPL_INFO_1002;\n\nstruct REPL_INFO_1003 {\n    DWORD rp1003_random;\n}\nalias REPL_INFO_1003* PREPL_INFO_1003, LPREPL_INFO_1003;\n\nstruct REPL_EDIR_INFO_0 {\n    LPWSTR rped0_dirname;\n}\nalias REPL_EDIR_INFO_0* PREPL_EDIR_INFO_0, LPREPL_EDIR_INFO_0;\n\nstruct REPL_EDIR_INFO_1 {\n    LPWSTR rped1_dirname;\n    DWORD rped1_integrity;\n    DWORD rped1_extent;\n}\nalias REPL_EDIR_INFO_1* PREPL_EDIR_INFO_1, LPREPL_EDIR_INFO_1;\n\nstruct REPL_EDIR_INFO_2 {\n    LPWSTR rped2_dirname;\n    DWORD rped2_integrity;\n    DWORD rped2_extent;\n    DWORD rped2_lockcount;\n    DWORD rped2_locktime;\n}\nalias REPL_EDIR_INFO_2* PREPL_EDIR_INFO_2, LPREPL_EDIR_INFO_2;\n\nstruct REPL_EDIR_INFO_1000 {\n    DWORD rped1000_integrity;\n}\nalias REPL_EDIR_INFO_1000* PREPL_EDIR_INFO_1000, LPREPL_EDIR_INFO_1000;\n\nstruct REPL_EDIR_INFO_1001 {\n    DWORD rped1001_extent;\n}\nalias REPL_EDIR_INFO_1001* PREPL_EDIR_INFO_1001, LPREPL_EDIR_INFO_1001;\n\nstruct REPL_IDIR_INFO_0 {\n    LPWSTR rpid0_dirname;\n}\nalias REPL_IDIR_INFO_0* PREPL_IDIR_INFO_0, LPREPL_IDIR_INFO_0;\n\nstruct REPL_IDIR_INFO_1 {\n    LPWSTR rpid1_dirname;\n    DWORD rpid1_state;\n    LPWSTR rpid1_mastername;\n    DWORD rpid1_last_update_time;\n    DWORD rpid1_lockcount;\n    DWORD rpid1_locktime;\n}\nalias REPL_IDIR_INFO_1* PREPL_IDIR_INFO_1, LPREPL_IDIR_INFO_1;\n\nextern (Windows) {\nNET_API_STATUS NetReplGetInfo(LPCWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetReplSetInfo(LPCWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetReplExportDirAdd(LPCWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetReplExportDirDel(LPCWSTR,LPCWSTR);\nNET_API_STATUS NetReplExportDirEnum(LPCWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetReplExportDirGetInfo(LPCWSTR,LPCWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetReplExportDirSetInfo(LPCWSTR,LPCWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetReplExportDirLock(LPCWSTR,LPCWSTR);\nNET_API_STATUS NetReplExportDirUnlock(LPCWSTR,LPCWSTR,DWORD);\nNET_API_STATUS NetReplImportDirAdd(LPCWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetReplImportDirDel(LPCWSTR,LPCWSTR);\nNET_API_STATUS NetReplImportDirEnum(LPCWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetReplImportDirGetInfo(LPCWSTR,LPCWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetReplImportDirLock(LPCWSTR,LPCWSTR);\nNET_API_STATUS NetReplImportDirUnlock(LPCWSTR,LPCWSTR,DWORD);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmserver.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmserver.d)\n */\nmodule core.sys.windows.lmserver;\nversion (Windows):\n\nimport core.sys.windows.winsvc;\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nstruct SERVER_INFO_100 {\n    DWORD  sv100_platform_id;\n    LPWSTR sv100_name;\n}\nalias SERVER_INFO_100* PSERVER_INFO_100, LPSERVER_INFO_100;\n\nstruct SERVER_INFO_101 {\n    DWORD  sv101_platform_id;\n    LPWSTR sv101_name;\n    DWORD  sv101_version_major;\n    DWORD  sv101_version_minor;\n    DWORD  sv101_type;\n    LPWSTR sv101_comment;\n}\nalias SERVER_INFO_101* PSERVER_INFO_101, LPSERVER_INFO_101;\n\nstruct SERVER_INFO_102 {\n    DWORD  sv102_platform_id;\n    LPWSTR sv102_name;\n    DWORD  sv102_version_major;\n    DWORD  sv102_version_minor;\n    DWORD  sv102_type;\n    LPWSTR sv102_comment;\n    DWORD  sv102_users;\n    LONG   sv102_disc;\n    BOOL   sv102_hidden;\n    DWORD  sv102_announce;\n    DWORD  sv102_anndelta;\n    DWORD  sv102_licenses;\n    LPWSTR sv102_userpath;\n}\nalias SERVER_INFO_102* PSERVER_INFO_102, LPSERVER_INFO_102;\n\nstruct SERVER_INFO_402 {\n    DWORD  sv402_ulist_mtime;\n    DWORD  sv402_glist_mtime;\n    DWORD  sv402_alist_mtime;\n    LPWSTR sv402_alerts;\n    DWORD  sv402_security;\n    DWORD  sv402_numadmin;\n    DWORD  sv402_lanmask;\n    LPWSTR sv402_guestacct;\n    DWORD  sv402_chdevs;\n    DWORD  sv402_chdevq;\n    DWORD  sv402_chdevjobs;\n    DWORD  sv402_connections;\n    DWORD  sv402_shares;\n    DWORD  sv402_openfiles;\n    DWORD  sv402_sessopens;\n    DWORD  sv402_sessvcs;\n    DWORD  sv402_sessreqs;\n    DWORD  sv402_opensearch;\n    DWORD  sv402_activelocks;\n    DWORD  sv402_numreqbuf;\n    DWORD  sv402_sizreqbuf;\n    DWORD  sv402_numbigbuf;\n    DWORD  sv402_numfiletasks;\n    DWORD  sv402_alertsched;\n    DWORD  sv402_erroralert;\n    DWORD  sv402_logonalert;\n    DWORD  sv402_accessalert;\n    DWORD  sv402_diskalert;\n    DWORD  sv402_netioalert;\n    DWORD  sv402_maxauditsz;\n    LPWSTR sv402_srvheuristics;\n}\nalias SERVER_INFO_402* PSERVER_INFO_402, LPSERVER_INFO_402;\n\nstruct SERVER_INFO_403 {\n    DWORD  sv403_ulist_mtime;\n    DWORD  sv403_glist_mtime;\n    DWORD  sv403_alist_mtime;\n    LPWSTR sv403_alerts;\n    DWORD  sv403_security;\n    DWORD  sv403_numadmin;\n    DWORD  sv403_lanmask;\n    LPWSTR sv403_guestacct;\n    DWORD  sv403_chdevs;\n    DWORD  sv403_chdevq;\n    DWORD  sv403_chdevjobs;\n    DWORD  sv403_connections;\n    DWORD  sv403_shares;\n    DWORD  sv403_openfiles;\n    DWORD  sv403_sessopens;\n    DWORD  sv403_sessvcs;\n    DWORD  sv403_sessreqs;\n    DWORD  sv403_opensearch;\n    DWORD  sv403_activelocks;\n    DWORD  sv403_numreqbuf;\n    DWORD  sv403_sizreqbuf;\n    DWORD  sv403_numbigbuf;\n    DWORD  sv403_numfiletasks;\n    DWORD  sv403_alertsched;\n    DWORD  sv403_erroralert;\n    DWORD  sv403_logonalert;\n    DWORD  sv403_accessalert;\n    DWORD  sv403_diskalert;\n    DWORD  sv403_netioalert;\n    DWORD  sv403_maxauditsz;\n    LPWSTR sv403_srvheuristics;\n    DWORD  sv403_auditedevents;\n    DWORD  sv403_autoprofile;\n    LPWSTR sv403_autopath;\n}\nalias SERVER_INFO_403* PSERVER_INFO_403, LPSERVER_INFO_403;\n\nstruct SERVER_INFO_502 {\n    DWORD sv502_sessopens;\n    DWORD sv502_sessvcs;\n    DWORD sv502_opensearch;\n    DWORD sv502_sizreqbuf;\n    DWORD sv502_initworkitems;\n    DWORD sv502_maxworkitems;\n    DWORD sv502_rawworkitems;\n    DWORD sv502_irpstacksize;\n    DWORD sv502_maxrawbuflen;\n    DWORD sv502_sessusers;\n    DWORD sv502_sessconns;\n    DWORD sv502_maxpagedmemoryusage;\n    DWORD sv502_maxnonpagedmemoryusage;\n    BOOL  sv502_enablesoftcompat;\n    BOOL  sv502_enableforcedlogoff;\n    BOOL  sv502_timesource;\n    BOOL  sv502_acceptdownlevelapis;\n    BOOL  sv502_lmannounce;\n}\nalias SERVER_INFO_502* PSERVER_INFO_502, LPSERVER_INFO_502;\n\nstruct SERVER_INFO_503 {\n    DWORD  sv503_sessopens;\n    DWORD  sv503_sessvcs;\n    DWORD  sv503_opensearch;\n    DWORD  sv503_sizreqbuf;\n    DWORD  sv503_initworkitems;\n    DWORD  sv503_maxworkitems;\n    DWORD  sv503_rawworkitems;\n    DWORD  sv503_irpstacksize;\n    DWORD  sv503_maxrawbuflen;\n    DWORD  sv503_sessusers;\n    DWORD  sv503_sessconns;\n    DWORD  sv503_maxpagedmemoryusage;\n    DWORD  sv503_maxnonpagedmemoryusage;\n    BOOL   sv503_enablesoftcompat;\n    BOOL   sv503_enableforcedlogoff;\n    BOOL   sv503_timesource;\n    BOOL   sv503_acceptdownlevelapis;\n    BOOL   sv503_lmannounce;\n    LPWSTR sv503_domain;\n    DWORD  sv503_maxcopyreadlen;\n    DWORD  sv503_maxcopywritelen;\n    DWORD  sv503_minkeepsearch;\n    DWORD  sv503_maxkeepsearch;\n    DWORD  sv503_minkeepcomplsearch;\n    DWORD  sv503_maxkeepcomplsearch;\n    DWORD  sv503_threadcountadd;\n    DWORD  sv503_numblockthreads;\n    DWORD  sv503_scavtimeout;\n    DWORD  sv503_minrcvqueue;\n    DWORD  sv503_minfreeworkitems;\n    DWORD  sv503_xactmemsize;\n    DWORD  sv503_threadpriority;\n    DWORD  sv503_maxmpxct;\n    DWORD  sv503_oplockbreakwait;\n    DWORD  sv503_oplockbreakresponsewait;\n    BOOL   sv503_enableoplocks;\n    BOOL   sv503_enableoplockforceclose;\n    BOOL   sv503_enablefcbopens;\n    BOOL   sv503_enableraw;\n    BOOL   sv503_enablesharednetdrives;\n    DWORD  sv503_minfreeconnections;\n    DWORD  sv503_maxfreeconnections;\n}\nalias SERVER_INFO_503* PSERVER_INFO_503, LPSERVER_INFO_503;\n\nstruct SERVER_INFO_599 {\n    DWORD  sv599_sessopens;\n    DWORD  sv599_sessvcs;\n    DWORD  sv599_opensearch;\n    DWORD  sv599_sizreqbuf;\n    DWORD  sv599_initworkitems;\n    DWORD  sv599_maxworkitems;\n    DWORD  sv599_rawworkitems;\n    DWORD  sv599_irpstacksize;\n    DWORD  sv599_maxrawbuflen;\n    DWORD  sv599_sessusers;\n    DWORD  sv599_sessconns;\n    DWORD  sv599_maxpagedmemoryusage;\n    DWORD  sv599_maxnonpagedmemoryusage;\n    BOOL   sv599_enablesoftcompat;\n    BOOL   sv599_enableforcedlogoff;\n    BOOL   sv599_timesource;\n    BOOL   sv599_acceptdownlevelapis;\n    BOOL   sv599_lmannounce;\n    LPWSTR sv599_domain;\n    DWORD  sv599_maxcopyreadlen;\n    DWORD  sv599_maxcopywritelen;\n    DWORD  sv599_minkeepsearch;\n    DWORD  sv599_maxkeepsearch;\n    DWORD  sv599_minkeepcomplsearch;\n    DWORD  sv599_maxkeepcomplsearch;\n    DWORD  sv599_threadcountadd;\n    DWORD  sv599_numblockthreads;\n    DWORD  sv599_scavtimeout;\n    DWORD  sv599_minrcvqueue;\n    DWORD  sv599_minfreeworkitems;\n    DWORD  sv599_xactmemsize;\n    DWORD  sv599_threadpriority;\n    DWORD  sv599_maxmpxct;\n    DWORD  sv599_oplockbreakwait;\n    DWORD  sv599_oplockbreakresponsewait;\n    BOOL   sv599_enableoplocks;\n    BOOL   sv599_enableoplockforceclose;\n    BOOL   sv599_enablefcbopens;\n    BOOL   sv599_enableraw;\n    BOOL   sv599_enablesharednetdrives;\n    DWORD  sv599_minfreeconnections;\n    DWORD  sv599_maxfreeconnections;\n    DWORD  sv599_initsesstable;\n    DWORD  sv599_initconntable;\n    DWORD  sv599_initfiletable;\n    DWORD  sv599_initsearchtable;\n    DWORD  sv599_alertschedule;\n    DWORD  sv599_errorthreshold;\n    DWORD  sv599_networkerrorthreshold;\n    DWORD  sv599_diskspacethreshold;\n    DWORD  sv599_reserved;\n    DWORD  sv599_maxlinkdelay;\n    DWORD  sv599_minlinkthroughput;\n    DWORD  sv599_linkinfovalidtime;\n    DWORD  sv599_scavqosinfoupdatetime;\n    DWORD  sv599_maxworkitemidletime;\n}\nalias SERVER_INFO_599* PSERVER_INFO_599, LPSERVER_INFO_599;\n\nstruct SERVER_INFO_598 {\n    DWORD sv598_maxrawworkitems;\n    DWORD sv598_maxthreadsperqueue;\n    DWORD sv598_producttype;\n    DWORD sv598_serversize;\n    DWORD sv598_connectionlessautodisc;\n    DWORD sv598_sharingviolationretries;\n    DWORD sv598_sharingviolationdelay;\n    DWORD sv598_maxglobalopensearch;\n    DWORD sv598_removeduplicatesearches;\n    DWORD sv598_lockviolationoffset;\n    DWORD sv598_lockviolationdelay;\n    DWORD sv598_mdlreadswitchover;\n    DWORD sv598_cachedopenlimit;\n    DWORD sv598_otherqueueaffinity;\n    BOOL  sv598_restrictnullsessaccess;\n    BOOL  sv598_enablewfw311directipx;\n    DWORD sv598_queuesamplesecs;\n    DWORD sv598_balancecount;\n    DWORD sv598_preferredaffinity;\n    DWORD sv598_maxfreerfcbs;\n    DWORD sv598_maxfreemfcbs;\n    DWORD sv598_maxfreelfcbs;\n    DWORD sv598_maxfreepagedpoolchunks;\n    DWORD sv598_minpagedpoolchunksize;\n    DWORD sv598_maxpagedpoolchunksize;\n    BOOL  sv598_sendsfrompreferredprocessor;\n}\nalias SERVER_INFO_598* PSERVER_INFO_598, LPSERVER_INFO_598;\n\nstruct SERVER_INFO_1005 {\n    LPWSTR sv1005_comment;\n}\nalias SERVER_INFO_1005* PSERVER_INFO_1005, LPSERVER_INFO_1005;\n\nstruct SERVER_INFO_1107 {\n    DWORD sv1107_users;\n}\nalias SERVER_INFO_1107* PSERVER_INFO_1107, LPSERVER_INFO_1107;\n\nstruct SERVER_INFO_1010 {\n    LONG sv1010_disc;\n}\nalias SERVER_INFO_1010* PSERVER_INFO_1010, LPSERVER_INFO_1010;\n\nstruct SERVER_INFO_1016 {\n    BOOL sv1016_hidden;\n}\nalias SERVER_INFO_1016* PSERVER_INFO_1016, LPSERVER_INFO_1016;\n\nstruct SERVER_INFO_1017 {\n    DWORD sv1017_announce;\n}\nalias SERVER_INFO_1017* PSERVER_INFO_1017, LPSERVER_INFO_1017;\n\nstruct SERVER_INFO_1018 {\n    DWORD sv1018_anndelta;\n}\nalias SERVER_INFO_1018* PSERVER_INFO_1018, LPSERVER_INFO_1018;\n\nstruct SERVER_INFO_1501 {\n    DWORD sv1501_sessopens;\n}\nalias SERVER_INFO_1501* PSERVER_INFO_1501, LPSERVER_INFO_1501;\n\nstruct SERVER_INFO_1502 {\n    DWORD sv1502_sessvcs;\n}\nalias SERVER_INFO_1502* PSERVER_INFO_1502, LPSERVER_INFO_1502;\n\nstruct SERVER_INFO_1503 {\n    DWORD sv1503_opensearch;\n}\nalias SERVER_INFO_1503* PSERVER_INFO_1503, LPSERVER_INFO_1503;\n\nstruct SERVER_INFO_1506 {\n    DWORD sv1506_maxworkitems;\n}\nalias SERVER_INFO_1506* PSERVER_INFO_1506, LPSERVER_INFO_1506;\n\nstruct SERVER_INFO_1509 {\n    DWORD sv1509_maxrawbuflen;\n}\nalias SERVER_INFO_1509* PSERVER_INFO_1509, LPSERVER_INFO_1509;\n\nstruct SERVER_INFO_1510 {\n    DWORD sv1510_sessusers;\n}\nalias SERVER_INFO_1510* PSERVER_INFO_1510, LPSERVER_INFO_1510;\n\nstruct SERVER_INFO_1511 {\n    DWORD sv1511_sessconns;\n} alias SERVER_INFO_1511* PSERVER_INFO_1511, LPSERVER_INFO_1511;\n\nstruct SERVER_INFO_1512 {\n    DWORD sv1512_maxnonpagedmemoryusage;\n}\nalias SERVER_INFO_1512* PSERVER_INFO_1512, LPSERVER_INFO_1512;\n\nstruct SERVER_INFO_1513 {\n    DWORD sv1513_maxpagedmemoryusage;\n}\nalias SERVER_INFO_1513* PSERVER_INFO_1513, LPSERVER_INFO_1513;\n\nstruct SERVER_INFO_1514 {\n    BOOL sv1514_enablesoftcompat;\n}\nalias SERVER_INFO_1514* PSERVER_INFO_1514, LPSERVER_INFO_1514;\n\nstruct SERVER_INFO_1515 {\n    BOOL sv1515_enableforcedlogoff;\n}\nalias SERVER_INFO_1515* PSERVER_INFO_1515, LPSERVER_INFO_1515;\n\nstruct SERVER_INFO_1516 {\n    BOOL sv1516_timesource;\n}\nalias SERVER_INFO_1516* PSERVER_INFO_1516, LPSERVER_INFO_1516;\n\nstruct SERVER_INFO_1518 {\n    BOOL sv1518_lmannounce;\n}\nalias SERVER_INFO_1518* PSERVER_INFO_1518, LPSERVER_INFO_1518;\n\nstruct SERVER_INFO_1520 {\n    DWORD sv1520_maxcopyreadlen;\n}\nalias SERVER_INFO_1520* PSERVER_INFO_1520, LPSERVER_INFO_1520;\n\nstruct SERVER_INFO_1521 {\n    DWORD sv1521_maxcopywritelen;\n}\nalias SERVER_INFO_1521* PSERVER_INFO_1521, LPSERVER_INFO_1521;\n\nstruct SERVER_INFO_1522 {\n    DWORD sv1522_minkeepsearch;\n}\nalias SERVER_INFO_1522* PSERVER_INFO_1522, LPSERVER_INFO_1522;\n\nstruct SERVER_INFO_1523 {\n    DWORD sv1523_maxkeepsearch;\n}\nalias SERVER_INFO_1523* PSERVER_INFO_1523, LPSERVER_INFO_1523;\n\nstruct SERVER_INFO_1524 {\n    DWORD sv1524_minkeepcomplsearch;\n}\nalias SERVER_INFO_1524* PSERVER_INFO_1524, LPSERVER_INFO_1524;\n\nstruct SERVER_INFO_1525 {\n    DWORD sv1525_maxkeepcomplsearch;\n}\nalias SERVER_INFO_1525* PSERVER_INFO_1525, LPSERVER_INFO_1525;\n\nstruct SERVER_INFO_1528 {\n    DWORD sv1528_scavtimeout;\n}\nalias SERVER_INFO_1528* PSERVER_INFO_1528, LPSERVER_INFO_1528;\n\nstruct SERVER_INFO_1529 {\n    DWORD sv1529_minrcvqueue;\n}\nalias SERVER_INFO_1529* PSERVER_INFO_1529, LPSERVER_INFO_1529;\n\nstruct SERVER_INFO_1530 {\n    DWORD sv1530_minfreeworkitems;\n}\nalias SERVER_INFO_1530* PSERVER_INFO_1530, LPSERVER_INFO_1530;\n\nstruct SERVER_INFO_1533 {\n    DWORD sv1533_maxmpxct;\n}\nalias SERVER_INFO_1533* PSERVER_INFO_1533, LPSERVER_INFO_1533;\n\nstruct SERVER_INFO_1534 {\n    DWORD sv1534_oplockbreakwait;\n}\nalias SERVER_INFO_1534* PSERVER_INFO_1534, LPSERVER_INFO_1534;\n\nstruct SERVER_INFO_1535 {\n    DWORD sv1535_oplockbreakresponsewait;\n}\nalias SERVER_INFO_1535* PSERVER_INFO_1535, LPSERVER_INFO_1535;\n\nstruct SERVER_INFO_1536 {\n    BOOL sv1536_enableoplocks;\n}\nalias SERVER_INFO_1536* PSERVER_INFO_1536, LPSERVER_INFO_1536;\n\nstruct SERVER_INFO_1537 {\n    BOOL sv1537_enableoplockforceclose;\n}\nalias SERVER_INFO_1537* PSERVER_INFO_1537, LPSERVER_INFO_1537;\n\nstruct SERVER_INFO_1538 {\n    BOOL sv1538_enablefcbopens;\n}\nalias SERVER_INFO_1538* PSERVER_INFO_1538, LPSERVER_INFO_1538;\n\nstruct SERVER_INFO_1539 {\n    BOOL sv1539_enableraw;\n}\nalias SERVER_INFO_1539* PSERVER_INFO_1539, LPSERVER_INFO_1539;\n\nstruct SERVER_INFO_1540 {\n    BOOL sv1540_enablesharednetdrives;\n}\nalias SERVER_INFO_1540* PSERVER_INFO_1540, LPSERVER_INFO_1540;\n\nstruct SERVER_INFO_1541 {\n    BOOL sv1541_minfreeconnections;\n}\nalias SERVER_INFO_1541* PSERVER_INFO_1541, LPSERVER_INFO_1541;\n\nstruct SERVER_INFO_1542 {\n    BOOL sv1542_maxfreeconnections;\n}\nalias SERVER_INFO_1542* PSERVER_INFO_1542, LPSERVER_INFO_1542;\n\nstruct SERVER_INFO_1543 {\n    DWORD sv1543_initsesstable;\n}\nalias SERVER_INFO_1543* PSERVER_INFO_1543, LPSERVER_INFO_1543;\n\nstruct SERVER_INFO_1544 {\n    DWORD sv1544_initconntable;\n}\nalias SERVER_INFO_1544* PSERVER_INFO_1544, LPSERVER_INFO_1544;\n\nstruct SERVER_INFO_1545 {\n    DWORD sv1545_initfiletable;\n}\nalias SERVER_INFO_1545* PSERVER_INFO_1545, LPSERVER_INFO_1545;\n\nstruct SERVER_INFO_1546 {\n    DWORD sv1546_initsearchtable;\n}\nalias SERVER_INFO_1546* PSERVER_INFO_1546, LPSERVER_INFO_1546;\n\nstruct SERVER_INFO_1547 {\n    DWORD sv1547_alertschedule;\n}\nalias SERVER_INFO_1547* PSERVER_INFO_1547, LPSERVER_INFO_1547;\n\nstruct SERVER_INFO_1548 {\n    DWORD sv1548_errorthreshold;\n}\nalias SERVER_INFO_1548* PSERVER_INFO_1548, LPSERVER_INFO_1548;\n\nstruct SERVER_INFO_1549 {\n    DWORD sv1549_networkerrorthreshold;\n}\nalias SERVER_INFO_1549* PSERVER_INFO_1549, LPSERVER_INFO_1549;\n\nstruct SERVER_INFO_1550 {\n    DWORD sv1550_diskspacethreshold;\n}\nalias SERVER_INFO_1550* PSERVER_INFO_1550, LPSERVER_INFO_1550;\n\nstruct SERVER_INFO_1552 {\n    DWORD sv1552_maxlinkdelay;\n}\nalias SERVER_INFO_1552* PSERVER_INFO_1552, LPSERVER_INFO_1552;\n\nstruct SERVER_INFO_1553 {\n    DWORD sv1553_minlinkthroughput;\n}\nalias SERVER_INFO_1553* PSERVER_INFO_1553, LPSERVER_INFO_1553;\n\nstruct SERVER_INFO_1554 {\n    DWORD sv1554_linkinfovalidtime;\n}\nalias SERVER_INFO_1554* PSERVER_INFO_1554, LPSERVER_INFO_1554;\n\nstruct SERVER_INFO_1555 {\n    DWORD sv1555_scavqosinfoupdatetime;\n}\nalias SERVER_INFO_1555* PSERVER_INFO_1555, LPSERVER_INFO_1555;\n\nstruct SERVER_INFO_1556 {\n    DWORD sv1556_maxworkitemidletime;\n}\nalias SERVER_INFO_1556* PSERVER_INFO_1556, LPSERVER_INFO_1556;\n\nstruct SERVER_INFO_1557 {\n    DWORD sv1557_maxrawworkitems;\n}\nalias SERVER_INFO_1557* PSERVER_INFO_1557, LPSERVER_INFO_1557;\n\nstruct SERVER_INFO_1560 {\n    DWORD sv1560_producttype;\n}\nalias SERVER_INFO_1560* PSERVER_INFO_1560, LPSERVER_INFO_1560;\n\nstruct SERVER_INFO_1561 {\n    DWORD sv1561_serversize;\n}\nalias SERVER_INFO_1561* PSERVER_INFO_1561, LPSERVER_INFO_1561;\n\nstruct SERVER_INFO_1562 {\n    DWORD sv1562_connectionlessautodisc;\n}\nalias SERVER_INFO_1562* PSERVER_INFO_1562, LPSERVER_INFO_1562;\n\nstruct SERVER_INFO_1563 {\n    DWORD sv1563_sharingviolationretries;\n}\nalias SERVER_INFO_1563* PSERVER_INFO_1563, LPSERVER_INFO_1563;\n\nstruct SERVER_INFO_1564 {\n    DWORD sv1564_sharingviolationdelay;\n}\nalias SERVER_INFO_1564* PSERVER_INFO_1564, LPSERVER_INFO_1564;\n\nstruct SERVER_INFO_1565 {\n    DWORD sv1565_maxglobalopensearch;\n}\nalias SERVER_INFO_1565* PSERVER_INFO_1565, LPSERVER_INFO_1565;\n\nstruct SERVER_INFO_1566 {\n    BOOL sv1566_removeduplicatesearches;\n}\nalias SERVER_INFO_1566* PSERVER_INFO_1566, LPSERVER_INFO_1566;\n\nstruct SERVER_INFO_1567 {\n    DWORD sv1567_lockviolationretries;\n}\nalias SERVER_INFO_1567* PSERVER_INFO_1567, LPSERVER_INFO_1567;\n\nstruct SERVER_INFO_1568 {\n    DWORD sv1568_lockviolationoffset;\n}\nalias SERVER_INFO_1568* PSERVER_INFO_1568, LPSERVER_INFO_1568;\n\nstruct SERVER_INFO_1569 {\n    DWORD sv1569_lockviolationdelay;\n}\nalias SERVER_INFO_1569* PSERVER_INFO_1569, LPSERVER_INFO_1569;\n\nstruct SERVER_INFO_1570 {\n    DWORD sv1570_mdlreadswitchover;\n}\nalias SERVER_INFO_1570* PSERVER_INFO_1570, LPSERVER_INFO_1570;\n\nstruct SERVER_INFO_1571 {\n    DWORD sv1571_cachedopenlimit;\n}\nalias SERVER_INFO_1571* PSERVER_INFO_1571, LPSERVER_INFO_1571;\n\nstruct SERVER_INFO_1572 {\n    DWORD sv1572_criticalthreads;\n}\nalias SERVER_INFO_1572* PSERVER_INFO_1572, LPSERVER_INFO_1572;\n\nstruct SERVER_INFO_1573 {\n    DWORD sv1573_restrictnullsessaccess;\n}\nalias SERVER_INFO_1573* PSERVER_INFO_1573, LPSERVER_INFO_1573;\n\nstruct SERVER_INFO_1574 {\n    DWORD sv1574_enablewfw311directipx;\n}\nalias SERVER_INFO_1574* PSERVER_INFO_1574, LPSERVER_INFO_1574;\n\nstruct SERVER_INFO_1575 {\n    DWORD sv1575_otherqueueaffinity;\n}\nalias SERVER_INFO_1575* PSERVER_INFO_1575, LPSERVER_INFO_1575;\n\nstruct SERVER_INFO_1576 {\n    DWORD sv1576_queuesamplesecs;\n}\nalias SERVER_INFO_1576* PSERVER_INFO_1576, LPSERVER_INFO_1576;\n\nstruct SERVER_INFO_1577 {\n    DWORD sv1577_balancecount;\n}\nalias SERVER_INFO_1577* PSERVER_INFO_1577, LPSERVER_INFO_1577;\n\nstruct SERVER_INFO_1578 {\n    DWORD sv1578_preferredaffinity;\n}\nalias SERVER_INFO_1578* PSERVER_INFO_1578, LPSERVER_INFO_1578;\n\nstruct SERVER_INFO_1579 {\n    DWORD sv1579_maxfreerfcbs;\n}\nalias SERVER_INFO_1579* PSERVER_INFO_1579, LPSERVER_INFO_1579;\n\nstruct SERVER_INFO_1580 {\n    DWORD sv1580_maxfreemfcbs;\n}\nalias SERVER_INFO_1580* PSERVER_INFO_1580, LPSERVER_INFO_1580;\n\nstruct SERVER_INFO_1581 {\n    DWORD sv1581_maxfreemlcbs;\n}\nalias SERVER_INFO_1581* PSERVER_INFO_1581, LPSERVER_INFO_1581;\n\nstruct SERVER_INFO_1582 {\n    DWORD sv1582_maxfreepagedpoolchunks;\n}\nalias SERVER_INFO_1582* PSERVER_INFO_1582, LPSERVER_INFO_1582;\n\nstruct SERVER_INFO_1583 {\n    DWORD sv1583_minpagedpoolchunksize;\n}\nalias SERVER_INFO_1583* PSERVER_INFO_1583, LPSERVER_INFO_1583;\n\nstruct SERVER_INFO_1584 {\n    DWORD sv1584_maxpagedpoolchunksize;\n}\nalias SERVER_INFO_1584* PSERVER_INFO_1584, LPSERVER_INFO_1584;\n\nstruct SERVER_INFO_1585 {\n    BOOL sv1585_sendsfrompreferredprocessor;\n}\nalias SERVER_INFO_1585* PSERVER_INFO_1585, LPSERVER_INFO_1585;\n\nstruct SERVER_INFO_1586 {\n    BOOL sv1586_maxthreadsperqueue;\n}\nalias SERVER_INFO_1586* PSERVER_INFO_1586, LPSERVER_INFO_1586;\n\nstruct SERVER_TRANSPORT_INFO_0 {\n    DWORD  svti0_numberofvcs;\n    LPWSTR svti0_transportname;\n    PBYTE  svti0_transportaddress;\n    DWORD  svti0_transportaddresslength;\n    LPWSTR svti0_networkaddress;\n}\nalias SERVER_TRANSPORT_INFO_0* PSERVER_TRANSPORT_INFO_0,\n  LPSERVER_TRANSPORT_INFO_0;\n\nextern (Windows):\nNET_API_STATUS NetServerEnum(LPCWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,DWORD,LPCWSTR,PDWORD);\nNET_API_STATUS NetServerEnumEx(LPCWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,DWORD,LPCWSTR,LPCWSTR);\nNET_API_STATUS NetServerGetInfo(LPWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetServerSetInfo(LPWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetServerSetInfoCommandLine(WORD,LPWSTR*);\nNET_API_STATUS NetServerDiskEnum(LPWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetServerComputerNameAdd(LPWSTR,LPWSTR,LPWSTR);\nNET_API_STATUS NetServerComputerNameDel(LPWSTR,LPWSTR);\nNET_API_STATUS NetServerTransportAdd(LPWSTR,DWORD,PBYTE);\nNET_API_STATUS NetServerTransportAddEx(LPWSTR,DWORD,PBYTE);\nNET_API_STATUS NetServerTransportDel(LPWSTR,DWORD,PBYTE);\nNET_API_STATUS NetServerTransportEnum(LPWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nBOOL SetServiceBits(SERVICE_STATUS_HANDLE,DWORD,BOOL,BOOL);\n\nenum SVI1_NUM_ELEMENTS=5;\nenum SVI2_NUM_ELEMENTS=40;\nenum SVI3_NUM_ELEMENTS=44;\nenum SV_MAX_CMD_LEN=PATHLEN;\nenum SW_AUTOPROF_LOAD_MASK=1;\nenum SW_AUTOPROF_SAVE_MASK=2;\nenum SV_MAX_SRV_HEUR_LEN=32;\nenum SV_USERS_PER_LICENSE=5;\nenum SV_PLATFORM_ID_OS2=400;\nenum SV_PLATFORM_ID_NT=500;\nenum MAJOR_VERSION_MASK=15;\nenum SV_TYPE_WORKSTATION=1;\nenum SV_TYPE_SERVER=2;\nenum SV_TYPE_SQLSERVER=4;\nenum SV_TYPE_DOMAIN_CTRL=8;\nenum SV_TYPE_DOMAIN_BAKCTRL=16;\nenum SV_TYPE_TIME_SOURCE=32;\nenum SV_TYPE_AFP=64;\nenum SV_TYPE_NOVELL=128;\nenum SV_TYPE_DOMAIN_MEMBER=256;\nenum SV_TYPE_PRINTQ_SERVER=512;\nenum SV_TYPE_DIALIN_SERVER=1024;\nenum SV_TYPE_XENIX_SERVER=2048;\nenum SV_TYPE_SERVER_UNIX=SV_TYPE_XENIX_SERVER;\nenum SV_TYPE_NT=4096;\nenum SV_TYPE_WFW=8192;\nenum SV_TYPE_SERVER_MFPN=16384;\nenum SV_TYPE_SERVER_NT=32768;\nenum SV_TYPE_POTENTIAL_BROWSER=65536;\nenum SV_TYPE_BACKUP_BROWSER=0x20000;\nenum SV_TYPE_MASTER_BROWSER=0x40000;\nenum SV_TYPE_DOMAIN_MASTER=0x80000;\nenum SV_TYPE_SERVER_OSF=0x100000;\nenum SV_TYPE_SERVER_VMS=0x200000;\nenum SV_TYPE_WINDOWS=0x400000;\nenum SV_TYPE_ALTERNATE_XPORT=0x20000000;\nenum SV_TYPE_LOCAL_LIST_ONLY=0x40000000;\nenum SV_TYPE_DOMAIN_ENUM=0x80000000;\nenum SV_TYPE_ALL=0xFFFFFFFF;\nenum SV_NODISC=(-1);\nenum SV_USERSECURITY=1;\nenum SV_SHARESECURITY=0;\nenum SV_HIDDEN=1;\nenum SV_VISIBLE=0;\nenum SV_PLATFORM_ID_PARMNUM=101;\nenum SV_NAME_PARMNUM=102;\nenum SV_VERSION_MAJOR_PARMNUM=103;\nenum SV_VERSION_MINOR_PARMNUM=104;\nenum SV_TYPE_PARMNUM=105;\nenum SV_COMMENT_PARMNUM=5;\nenum SV_USERS_PARMNUM=107;\nenum SV_DISC_PARMNUM=10;\nenum SV_HIDDEN_PARMNUM=16;\nenum SV_ANNOUNCE_PARMNUM=17;\nenum SV_ANNDELTA_PARMNUM=18;\nenum SV_USERPATH_PARMNUM=112;\nenum SV_ULIST_MTIME_PARMNUM=401;\nenum SV_GLIST_MTIME_PARMNUM=402;\nenum SV_ALIST_MTIME_PARMNUM=403;\nenum SV_ALERTS_PARMNUM=11;\nenum SV_SECURITY_PARMNUM=405;\nenum SV_NUMADMIN_PARMNUM=406;\nenum SV_LANMASK_PARMNUM=407;\nenum SV_GUESTACC_PARMNUM=408;\nenum SV_CHDEVQ_PARMNUM=410;\nenum SV_CHDEVJOBS_PARMNUM=411;\nenum SV_CONNECTIONS_PARMNUM=412;\nenum SV_SHARES_PARMNUM=413;\nenum SV_OPENFILES_PARMNUM=414;\nenum SV_SESSREQS_PARMNUM=417;\nenum SV_ACTIVELOCKS_PARMNUM=419;\nenum SV_NUMREQBUF_PARMNUM=420;\nenum SV_NUMBIGBUF_PARMNUM=422;\nenum SV_NUMFILETASKS_PARMNUM=423;\nenum SV_ALERTSCHED_PARMNUM=37;\nenum SV_ERRORALERT_PARMNUM=38;\nenum SV_LOGONALERT_PARMNUM=39;\nenum SV_ACCESSALERT_PARMNUM=40;\nenum SV_DISKALERT_PARMNUM=41;\nenum SV_NETIOALERT_PARMNUM=42;\nenum SV_MAXAUDITSZ_PARMNUM=43;\nenum SV_SRVHEURISTICS_PARMNUM=431;\nenum SV_SESSOPENS_PARMNUM=501;\nenum SV_SESSVCS_PARMNUM=502;\nenum SV_OPENSEARCH_PARMNUM=503;\nenum SV_SIZREQBUF_PARMNUM=504;\nenum SV_INITWORKITEMS_PARMNUM=505;\nenum SV_MAXWORKITEMS_PARMNUM=506;\nenum SV_RAWWORKITEMS_PARMNUM=507;\nenum SV_IRPSTACKSIZE_PARMNUM=508;\nenum SV_MAXRAWBUFLEN_PARMNUM=509;\nenum SV_SESSUSERS_PARMNUM=510;\nenum SV_SESSCONNS_PARMNUM=511;\nenum SV_MAXNONPAGEDMEMORYUSAGE_PARMNUM=512;\nenum SV_MAXPAGEDMEMORYUSAGE_PARMNUM=513;\nenum SV_ENABLESOFTCOMPAT_PARMNUM=514;\nenum SV_ENABLEFORCEDLOGOFF_PARMNUM=515;\nenum SV_TIMESOURCE_PARMNUM=516;\nenum SV_ACCEPTDOWNLEVELAPIS_PARMNUM=517;\nenum SV_LMANNOUNCE_PARMNUM=518;\nenum SV_DOMAIN_PARMNUM=519;\nenum SV_MAXCOPYREADLEN_PARMNUM=520;\nenum SV_MAXCOPYWRITELEN_PARMNUM=521;\nenum SV_MINKEEPSEARCH_PARMNUM=522;\nenum SV_MAXKEEPSEARCH_PARMNUM=523;\nenum SV_MINKEEPCOMPLSEARCH_PARMNUM=524;\nenum SV_MAXKEEPCOMPLSEARCH_PARMNUM=525;\nenum SV_THREADCOUNTADD_PARMNUM=526;\nenum SV_NUMBLOCKTHREADS_PARMNUM=527;\nenum SV_SCAVTIMEOUT_PARMNUM=528;\nenum SV_MINRCVQUEUE_PARMNUM=529;\nenum SV_MINFREEWORKITEMS_PARMNUM=530;\nenum SV_XACTMEMSIZE_PARMNUM=531;\nenum SV_THREADPRIORITY_PARMNUM=532;\nenum SV_MAXMPXCT_PARMNUM=533;\nenum SV_OPLOCKBREAKWAIT_PARMNUM=534;\nenum SV_OPLOCKBREAKRESPONSEWAIT_PARMNUM=535;\nenum SV_ENABLEOPLOCKS_PARMNUM=536;\nenum SV_ENABLEOPLOCKFORCECLOSE_PARMNUM=537;\nenum SV_ENABLEFCBOPENS_PARMNUM=538;\nenum SV_ENABLERAW_PARMNUM=539;\nenum SV_ENABLESHAREDNETDRIVES_PARMNUM=540;\nenum SV_MINFREECONNECTIONS_PARMNUM=541;\nenum SV_MAXFREECONNECTIONS_PARMNUM=542;\nenum SV_INITSESSTABLE_PARMNUM=543;\nenum SV_INITCONNTABLE_PARMNUM=544;\nenum SV_INITFILETABLE_PARMNUM=545;\nenum SV_INITSEARCHTABLE_PARMNUM=546;\nenum SV_ALERTSCHEDULE_PARMNUM=547;\nenum SV_ERRORTHRESHOLD_PARMNUM=548;\nenum SV_NETWORKERRORTHRESHOLD_PARMNUM=549;\nenum SV_DISKSPACETHRESHOLD_PARMNUM=550;\nenum SV_MAXLINKDELAY_PARMNUM=552;\nenum SV_MINLINKTHROUGHPUT_PARMNUM=553;\nenum SV_LINKINFOVALIDTIME_PARMNUM=554;\nenum SV_SCAVQOSINFOUPDATETIME_PARMNUM=555;\nenum SV_MAXWORKITEMIDLETIME_PARMNUM=556;\nenum SV_MAXRAWWORKITEMS_PARMNUM=557;\nenum SV_PRODUCTTYPE_PARMNUM=560;\nenum SV_SERVERSIZE_PARMNUM=561;\nenum SV_CONNECTIONLESSAUTODISC_PARMNUM=562;\nenum SV_SHARINGVIOLATIONRETRIES_PARMNUM=563;\nenum SV_SHARINGVIOLATIONDELAY_PARMNUM=564;\nenum SV_MAXGLOBALOPENSEARCH_PARMNUM=565;\nenum SV_REMOVEDUPLICATESEARCHES_PARMNUM=566;\nenum SV_LOCKVIOLATIONRETRIES_PARMNUM=567;\nenum SV_LOCKVIOLATIONOFFSET_PARMNUM=568;\nenum SV_LOCKVIOLATIONDELAY_PARMNUM=569;\nenum SV_MDLREADSWITCHOVER_PARMNUM=570;\nenum SV_CACHEDOPENLIMIT_PARMNUM=571;\nenum SV_CRITICALTHREADS_PARMNUM=572;\nenum SV_RESTRICTNULLSESSACCESS_PARMNUM=573;\nenum SV_ENABLEWFW311DIRECTIPX_PARMNUM=574;\nenum SV_OTHERQUEUEAFFINITY_PARMNUM=575;\nenum SV_QUEUESAMPLESECS_PARMNUM=576;\nenum SV_BALANCECOUNT_PARMNUM=577;\nenum SV_PREFERREDAFFINITY_PARMNUM=578;\nenum SV_MAXFREERFCBS_PARMNUM=579;\nenum SV_MAXFREEMFCBS_PARMNUM=580;\nenum SV_MAXFREELFCBS_PARMNUM=581;\nenum SV_MAXFREEPAGEDPOOLCHUNKS_PARMNUM=582;\nenum SV_MINPAGEDPOOLCHUNKSIZE_PARMNUM=583;\nenum SV_MAXPAGEDPOOLCHUNKSIZE_PARMNUM=584;\nenum SV_SENDSFROMPREFERREDPROCESSOR_PARMNUM=585;\nenum SV_MAXTHREADSPERQUEUE_PARMNUM=586;\nenum SV_COMMENT_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_COMMENT_PARMNUM);\nenum SV_USERS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_USERS_PARMNUM);\nenum SV_DISC_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_DISC_PARMNUM);\nenum SV_HIDDEN_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_HIDDEN_PARMNUM);\nenum SV_ANNOUNCE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ANNOUNCE_PARMNUM);\nenum SV_ANNDELTA_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ANNDELTA_PARMNUM);\nenum SV_SESSOPENS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_SESSOPENS_PARMNUM);\nenum SV_SESSVCS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_SESSVCS_PARMNUM);\nenum SV_OPENSEARCH_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_OPENSEARCH_PARMNUM);\nenum SV_MAXWORKITEMS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXWORKITEMS_PARMNUM);\nenum SV_MAXRAWBUFLEN_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXRAWBUFLEN_PARMNUM);\nenum SV_SESSUSERS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_SESSUSERS_PARMNUM);\nenum SV_SESSCONNS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_SESSCONNS_PARMNUM);\nenum SV_MAXNONPAGEDMEMORYUSAGE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXNONPAGEDMEMORYUSAGE_PARMNUM);\nenum SV_MAXPAGEDMEMORYUSAGE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXPAGEDMEMORYUSAGE_PARMNUM);\nenum SV_ENABLESOFTCOMPAT_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ENABLESOFTCOMPAT_PARMNUM);\nenum SV_ENABLEFORCEDLOGOFF_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ENABLEFORCEDLOGOFF_PARMNUM);\nenum SV_TIMESOURCE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_TIMESOURCE_PARMNUM);\nenum SV_LMANNOUNCE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_LMANNOUNCE_PARMNUM);\nenum SV_MAXCOPYREADLEN_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXCOPYREADLEN_PARMNUM);\nenum SV_MAXCOPYWRITELEN_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXCOPYWRITELEN_PARMNUM);\nenum SV_MINKEEPSEARCH_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MINKEEPSEARCH_PARMNUM);\nenum SV_MAXKEEPSEARCH_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXKEEPSEARCH_PARMNUM);\nenum SV_MINKEEPCOMPLSEARCH_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MINKEEPCOMPLSEARCH_PARMNUM);\nenum SV_MAXKEEPCOMPLSEARCH_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXKEEPCOMPLSEARCH_PARMNUM);\nenum SV_SCAVTIMEOUT_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_SCAVTIMEOUT_PARMNUM);\nenum SV_MINRCVQUEUE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MINRCVQUEUE_PARMNUM);\nenum SV_MINFREEWORKITEMS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MINFREEWORKITEMS_PARMNUM);\nenum SV_MAXMPXCT_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXMPXCT_PARMNUM);\nenum SV_OPLOCKBREAKWAIT_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_OPLOCKBREAKWAIT_PARMNUM);\nenum SV_OPLOCKBREAKRESPONSEWAIT_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_OPLOCKBREAKRESPONSEWAIT_PARMNUM);\nenum SV_ENABLEOPLOCKS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ENABLEOPLOCKS_PARMNUM);\nenum SV_ENABLEOPLOCKFORCECLOSE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ENABLEOPLOCKFORCECLOSE_PARMNUM);\nenum SV_ENABLEFCBOPENS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ENABLEFCBOPENS_PARMNUM);\nenum SV_ENABLERAW_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ENABLERAW_PARMNUM);\nenum SV_ENABLESHAREDNETDRIVES_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ENABLESHAREDNETDRIVES_PARMNUM);\nenum SV_MINFREECONNECTIONS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MINFREECONNECTIONS_PARMNUM);\nenum SV_MAXFREECONNECTIONS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXFREECONNECTIONS_PARMNUM);\nenum SV_INITSESSTABLE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_INITSESSTABLE_PARMNUM);\nenum SV_INITCONNTABLE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_INITCONNTABLE_PARMNUM);\nenum SV_INITFILETABLE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_INITFILETABLE_PARMNUM);\nenum SV_INITSEARCHTABLE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_INITSEARCHTABLE_PARMNUM);\nenum SV_ALERTSCHEDULE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ALERTSCHEDULE_PARMNUM);\nenum SV_ERRORTHRESHOLD_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ERRORTHRESHOLD_PARMNUM);\nenum SV_NETWORKERRORTHRESHOLD_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_NETWORKERRORTHRESHOLD_PARMNUM);\nenum SV_DISKSPACETHRESHOLD_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_DISKSPACETHRESHOLD_PARMNUM);\nenum SV_MAXLINKDELAY_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXLINKDELAY_PARMNUM);\nenum SV_MINLINKTHROUGHPUT_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MINLINKTHROUGHPUT_PARMNUM);\nenum SV_LINKINFOVALIDTIME_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_LINKINFOVALIDTIME_PARMNUM);\nenum SV_SCAVQOSINFOUPDATETIME_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_SCAVQOSINFOUPDATETIME_PARMNUM);\nenum SV_MAXWORKITEMIDLETIME_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXWORKITEMIDLETIME_PARMNUM);\nenum SV_MAXRAWWORKITEMS_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXRAWWORKITEMS_PARMNUM);\nenum SV_PRODUCTTYPE_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_PRODUCTTYPE_PARMNUM);\nenum SV_SERVERSIZE_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_SERVERSIZE_PARMNUM);\nenum SV_CONNECTIONLESSAUTODISC_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_CONNECTIONLESSAUTODISC_PARMNUM);\nenum SV_SHARINGVIOLATIONRETRIES_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_SHARINGVIOLATIONRETRIES_PARMNUM);\nenum SV_SHARINGVIOLATIONDELAY_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_SHARINGVIOLATIONDELAY_PARMNUM);\nenum SV_MAXGLOBALOPENSEARCH_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXGLOBALOPENSEARCH_PARMNUM);\nenum SV_REMOVEDUPLICATESEARCHES_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_REMOVEDUPLICATESEARCHES_PARMNUM);\nenum SV_LOCKVIOLATIONRETRIES_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_LOCKVIOLATIONRETRIES_PARMNUM);\nenum SV_LOCKVIOLATIONOFFSET_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_LOCKVIOLATIONOFFSET_PARMNUM);\nenum SV_LOCKVIOLATIONDELAY_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_LOCKVIOLATIONDELAY_PARMNUM);\nenum SV_MDLREADSWITCHOVER_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MDLREADSWITCHOVER_PARMNUM);\nenum SV_CACHEDOPENLIMIT_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_CACHEDOPENLIMIT_PARMNUM);\nenum SV_CRITICALTHREADS_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_CRITICALTHREADS_PARMNUM);\nenum SV_RESTRICTNULLSESSACCESS_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_RESTRICTNULLSESSACCESS_PARMNUM);\nenum SV_ENABLEWFW311DIRECTIPX_INFOLOEVEL=(PARMNUM_BASE_INFOLEVEL+SV_ENABLEWFW311DIRECTIPX_PARMNUM);\nenum SV_OTHERQUEUEAFFINITY_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_OTHERQUEUEAFFINITY_PARMNUM);\nenum SV_QUEUESAMPLESECS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_QUEUESAMPLESECS_PARMNUM);\nenum SV_BALANCECOUNT_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_BALANCECOUNT_PARMNUM);\nenum SV_PREFERREDAFFINITY_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_PREFERREDAFFINITY_PARMNUM);\nenum SV_MAXFREERFCBS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXFREERFCBS_PARMNUM);\nenum SV_MAXFREEMFCBS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXFREEMFCBS_PARMNUM);\nenum SV_MAXFREELFCBS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXFREELFCBS_PARMNUM);\nenum SV_MAXFREEPAGEDPOOLCHUNKS_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXFREEPAGEDPOOLCHUNKS_PARMNUM);\nenum SV_MINPAGEDPOOLCHUNKSIZE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MINPAGEDPOOLCHUNKSIZE_PARMNUM);\nenum SV_MAXPAGEDPOOLCHUNKSIZE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXPAGEDPOOLCHUNKSIZE_PARMNUM);\nenum SV_SENDSFROMPREFERREDPROCESSOR_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_SENDSFROMPREFERREDPROCESSOR_PARMNUM);\nenum SV_MAXTHREADSPERQUEUE_INFOLEVEL=(PARMNUM_BASE_INFOLEVEL+SV_MAXTHREADSPERQUEUE_PARMNUM);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmshare.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmshare.d)\n */\nmodule core.sys.windows.lmshare;\nversion (Windows):\npragma(lib, \"netapi32\");\n\nimport core.sys.windows.lmcons;\nprivate import core.sys.windows.w32api, core.sys.windows.windef;\n\n\nenum SHARE_NETNAME_PARMNUM      = 1;\nenum SHARE_TYPE_PARMNUM         = 3;\nenum SHARE_REMARK_PARMNUM       = 4;\nenum SHARE_PERMISSIONS_PARMNUM  = 5;\nenum SHARE_MAX_USES_PARMNUM     = 6;\nenum SHARE_CURRENT_USES_PARMNUM = 7;\nenum SHARE_PATH_PARMNUM         = 8;\nenum SHARE_PASSWD_PARMNUM       = 9;\nenum SHARE_FILE_SD_PARMNUM      = 501;\nenum SHARE_REMARK_INFOLEVEL   = PARMNUM_BASE_INFOLEVEL + SHARE_REMARK_PARMNUM;\nenum SHARE_MAX_USES_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + SHARE_MAX_USES_PARMNUM;\nenum SHARE_FILE_SD_INFOLEVEL  = PARMNUM_BASE_INFOLEVEL + SHARE_FILE_SD_PARMNUM;\n\nenum SHI1_NUM_ELEMENTS = 4;\nenum SHI2_NUM_ELEMENTS = 10;\n\nenum STYPE_DISKTREE = 0;\nenum STYPE_PRINTQ   = 1;\nenum STYPE_DEVICE   = 2;\nenum STYPE_IPC      = 3;\nenum STYPE_DFS      = 100;\nenum STYPE_SPECIAL  = 0x80000000;\n\nenum DWORD SHI_USES_UNLIMITED = -1;\n\nenum SESS_GUEST = 1;\nenum SESS_NOENCRYPTION = 2;\nenum SESI1_NUM_ELEMENTS = 8;\nenum SESI2_NUM_ELEMENTS = 9;\n\nenum PERM_FILE_READ   = 1;\nenum PERM_FILE_WRITE  = 2;\nenum PERM_FILE_CREATE = 4;\n\nstruct FILE_INFO_2 {\n    DWORD fi2_id;\n}\nalias FILE_INFO_2* PFILE_INFO_2, LPFILE_INFO_2;\n\nstruct FILE_INFO_3 {\n    DWORD fi3_id;\n    DWORD fi3_permissions;\n    DWORD fi3_num_locks;\n    LPTSTR fi3_pathname;\n    LPTSTR fi3_username;\n}\nalias FILE_INFO_3* PFILE_INFO_3, LPFILE_INFO_3;\n\nstruct SHARE_INFO_0 {\n    LPTSTR shi0_netname;\n}\nalias SHARE_INFO_0* PSHARE_INFO_0, LPSHARE_INFO_0;\n\nstruct SHARE_INFO_1 {\n    LPTSTR shi1_netname;\n    DWORD shi1_type;\n    LPTSTR shi1_remark;\n}\nalias SHARE_INFO_1* PSHARE_INFO_1, LPSHARE_INFO_1;\n\nstruct SHARE_INFO_2 {\n    LPTSTR shi2_netname;\n    DWORD shi2_type;\n    LPTSTR shi2_remark;\n    DWORD shi2_permissions;\n    DWORD shi2_max_uses;\n    DWORD shi2_current_uses;\n    LPTSTR shi2_path;\n    LPTSTR shi2_passwd;\n}\nalias SHARE_INFO_2* PSHARE_INFO_2, LPSHARE_INFO_2;\n\nstruct SHARE_INFO_502 {\n    LPTSTR shi502_netname;\n    DWORD shi502_type;\n    LPTSTR shi502_remark;\n    DWORD shi502_permissions;\n    DWORD shi502_max_uses;\n    DWORD shi502_current_uses;\n    LPTSTR shi502_path;\n    LPTSTR shi502_passwd;\n    DWORD shi502_reserved;\n    PSECURITY_DESCRIPTOR shi502_security_descriptor;\n}\nalias SHARE_INFO_502* PSHARE_INFO_502, LPSHARE_INFO_502;\n\nstruct SHARE_INFO_1004 {\n    LPTSTR shi1004_remark;\n}\nalias SHARE_INFO_1004* PSHARE_INFO_1004, LPSHARE_INFO_1004;\n\nstruct SHARE_INFO_1006 {\n    DWORD shi1006_max_uses;\n}\nalias SHARE_INFO_1006* PSHARE_INFO_1006, LPSHARE_INFO_1006;\n\nstruct SHARE_INFO_1501 {\n    DWORD shi1501_reserved;\n    PSECURITY_DESCRIPTOR shi1501_security_descriptor;\n}\nalias SHARE_INFO_1501* PSHARE_INFO_1501, LPSHARE_INFO_1501;\n\nstruct SESSION_INFO_0 {\n    LPWSTR sesi0_cname;\n}\nalias SESSION_INFO_0* PSESSION_INFO_0, LPSESSION_INFO_0;\n\nstruct SESSION_INFO_1 {\n    LPTSTR sesi1_cname;\n    LPTSTR sesi1_username;\n    DWORD sesi1_num_opens;\n    DWORD sesi1_time;\n    DWORD sesi1_idle_time;\n    DWORD sesi1_user_flags;\n}\nalias SESSION_INFO_1* PSESSION_INFO_1, LPSESSION_INFO_1;\n\nstruct SESSION_INFO_2 {\n    LPTSTR sesi2_cname;\n    LPTSTR sesi2_username;\n    DWORD sesi2_num_opens;\n    DWORD sesi2_time;\n    DWORD sesi2_idle_time;\n    DWORD sesi2_user_flags;\n    LPWSTR sesi2_cltype_name;\n}\nalias SESSION_INFO_2* PSESSION_INFO_2, LPSESSION_INFO_2;\n\nstruct SESSION_INFO_10 {\n    LPWSTR sesi10_cname;\n    LPWSTR sesi10_username;\n    DWORD sesi10_time;\n    DWORD sesi10_idle_time;\n}\nalias SESSION_INFO_10* PSESSION_INFO_10, LPSESSION_INFO_10;\n\nstruct SESSION_INFO_502 {\n    LPWSTR sesi502_cname;\n    LPWSTR sesi502_username;\n    DWORD sesi502_num_opens;\n    DWORD sesi502_time;\n    DWORD sesi502_idle_time;\n    DWORD sesi502_user_flags;\n    LPWSTR sesi502_cltype_name;\n    LPWSTR sesi502_transport;\n}\nalias SESSION_INFO_502* PSESSION_INFO_502, LPSESSION_INFO_502;\n\nstruct CONNECTION_INFO_0 {\n    DWORD coni0_id;\n}\nalias CONNECTION_INFO_0* PCONNECTION_INFO_0, LPCONNECTION_INFO_0;\n\nstruct CONNECTION_INFO_1 {\n    DWORD coni1_id;\n    DWORD coni1_type;\n    DWORD coni1_num_opens;\n    DWORD coni1_num_users;\n    DWORD coni1_time;\n    LPWSTR coni1_username;\n    LPWSTR coni1_netname;\n}\nalias CONNECTION_INFO_1* PCONNECTION_INFO_1, LPCONNECTION_INFO_1;\n\nextern (Windows) {\nNET_API_STATUS NetShareAdd(LPWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetShareEnum(LPWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetShareEnumSticky(LPWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD resume_handle);\nNET_API_STATUS NetShareGetInfo(LPWSTR,LPWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetShareSetInfo(LPWSTR,LPWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetShareDel(LPWSTR,LPWSTR,DWORD);\nNET_API_STATUS NetShareDelSticky(LPWSTR,LPWSTR,DWORD);\nNET_API_STATUS NetShareCheck(LPWSTR,LPWSTR,PDWORD);\nNET_API_STATUS NetSessionEnum(LPWSTR,LPWSTR,LPWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetSessionDel(LPWSTR,LPWSTR,LPWSTR);\nNET_API_STATUS NetSessionGetInfo(LPWSTR,LPWSTR,LPWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetConnectionEnum(LPWSTR,LPWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetFileClose(LPWSTR,DWORD);\nNET_API_STATUS NetFileEnum(LPWSTR,LPWSTR,LPWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetFileGetInfo(LPWSTR,DWORD,DWORD,PBYTE*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmsname.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmsname.d)\n */\nmodule core.sys.windows.lmsname;\nversion (Windows):\n\nprivate import core.sys.windows.windef;\n\nconst TCHAR[]\n    SERVICE_WORKSTATION      = \"LanmanWorkstation\",\n    SERVICE_LM20_WORKSTATION = \"WORKSTATION\",\n    WORKSTATION_DISPLAY_NAME = \"Workstation\",\n    SERVICE_SERVER           = \"LanmanServer\",\n    SERVICE_LM20_SERVER      = \"SERVER\",\n    SERVER_DISPLAY_NAME      = \"Server\",\n    SERVICE_BROWSER          = \"BROWSER\",\n    SERVICE_LM20_BROWSER     = SERVICE_BROWSER,\n    SERVICE_MESSENGER        = \"MESSENGER\",\n    SERVICE_LM20_MESSENGER   = SERVICE_MESSENGER,\n    SERVICE_NETRUN           = \"NETRUN\",\n    SERVICE_LM20_NETRUN      = SERVICE_NETRUN,\n    SERVICE_SPOOLER          = \"SPOOLER\",\n    SERVICE_LM20_SPOOLER     = SERVICE_SPOOLER,\n    SERVICE_ALERTER          = \"ALERTER\",\n    SERVICE_LM20_ALERTER     = SERVICE_ALERTER,\n    SERVICE_NETLOGON         = \"NETLOGON\",\n    SERVICE_LM20_NETLOGON    = SERVICE_NETLOGON,\n    SERVICE_NETPOPUP         = \"NETPOPUP\",\n    SERVICE_LM20_NETPOPUP    = SERVICE_NETPOPUP,\n    SERVICE_SQLSERVER        = \"SQLSERVER\",\n    SERVICE_LM20_SQLSERVER   = SERVICE_SQLSERVER,\n    SERVICE_REPL             = \"REPLICATOR\",\n    SERVICE_LM20_REPL        = SERVICE_REPL,\n    SERVICE_RIPL             = \"REMOTEBOOT\",\n    SERVICE_LM20_RIPL        = SERVICE_RIPL,\n    SERVICE_TIMESOURCE       = \"TIMESOURCE\",\n    SERVICE_LM20_TIMESOURCE  = SERVICE_TIMESOURCE,\n    SERVICE_AFP              = \"AFP\",\n    SERVICE_LM20_AFP         = SERVICE_AFP,\n    SERVICE_UPS              = \"UPS\",\n    SERVICE_LM20_UPS         = SERVICE_UPS,\n    SERVICE_XACTSRV          = \"XACTSRV\",\n    SERVICE_LM20_XACTSRV     = SERVICE_XACTSRV,\n    SERVICE_TCPIP            = \"TCPIP\",\n    SERVICE_LM20_TCPIP       = SERVICE_TCPIP,\n    SERVICE_NBT              = \"NBT\",\n    SERVICE_LM20_NBT         = SERVICE_NBT,\n    SERVICE_LMHOSTS          = \"LMHOSTS\",\n    SERVICE_LM20_LMHOSTS     = SERVICE_LMHOSTS,\n    SERVICE_TELNET           = \"Telnet\",\n    SERVICE_LM20_TELNET      = SERVICE_TELNET,\n    SERVICE_SCHEDULE         = \"Schedule\",\n    SERVICE_LM20_SCHEDULE    = SERVICE_SCHEDULE,\n    SERVICE_NTLMSSP          = \"NtLmSsp\",\n    SERVICE_DHCP             = \"DHCP\",\n    SERVICE_LM20_DHCP        = SERVICE_DHCP,\n    SERVICE_NWSAP            = \"NwSapAgent\",\n    SERVICE_LM20_NWSAP       = SERVICE_NWSAP,\n    NWSAP_DISPLAY_NAME       = \"NW Sap Agent\",\n    SERVICE_NWCS             = \"NWCWorkstation\";\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmstats.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmstats.d)\n */\nmodule core.sys.windows.lmstats;\nversion (Windows):\npragma(lib, \"netapi32\");\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nenum ULONG\n    STATSOPT_CLR   = 1,\n    STATS_NO_VALUE = -1,\n    STATS_OVERFLOW = -2;\n\nstruct STAT_SERVER_0{\n    DWORD sts0_start;\n    DWORD sts0_fopens;\n    DWORD sts0_devopens;\n    DWORD sts0_jobsqueued;\n    DWORD sts0_sopens;\n    DWORD sts0_stimedout;\n    DWORD sts0_serrorout;\n    DWORD sts0_pwerrors;\n    DWORD sts0_permerrors;\n    DWORD sts0_syserrors;\n    DWORD sts0_bytessent_low;\n    DWORD sts0_bytessent_high;\n    DWORD sts0_bytesrcvd_low;\n    DWORD sts0_bytesrcvd_high;\n    DWORD sts0_avresponse;\n    DWORD sts0_reqbufneed;\n    DWORD sts0_bigbufneed;\n}\nalias STAT_SERVER_0* PSTAT_SERVER_0, LPSTAT_SERVER_0;\n\n// #ifdef LM20_WORKSTATION_STATISTICS\n// typedef struct _STAT_WORKSTATION_0 {\n//  DWORD stw0_start;\n//  DWORD stw0_numNCB_r;\n//  DWORD stw0_numNCB_s;\n//  DWORD stw0_numNCB_a;\n//  DWORD stw0_fiNCB_r;\n//  DWORD stw0_fiNCB_s;\n//  DWORD stw0_fiNCB_a;\n//  DWORD stw0_fcNCB_r;\n//  DWORD stw0_fcNCB_s;\n//  DWORD stw0_fcNCB_a;\n//  DWORD stw0_sesstart;\n//  DWORD stw0_sessfailcon;\n//  DWORD stw0_sessbroke;\n//  DWORD stw0_uses;\n//  DWORD stw0_usefail;\n//  DWORD stw0_autorec;\n//  DWORD stw0_bytessent_r_lo;\n//  DWORD stw0_bytessent_r_hi;\n//  DWORD stw0_bytesrcvd_r_lo;\n//  DWORD stw0_bytesrcvd_r_hi;\n//  DWORD stw0_bytessent_s_lo;\n//  DWORD stw0_bytessent_s_hi;\n//  DWORD stw0_bytesrcvd_s_lo;\n//  DWORD stw0_bytesrcvd_s_hi;\n//  DWORD stw0_bytessent_a_lo;\n//  DWORD stw0_bytessent_a_hi;\n//  DWORD stw0_bytesrcvd_a_lo;\n//  DWORD stw0_bytesrcvd_a_hi;\n//  DWORD stw0_reqbufneed;\n//  DWORD stw0_bigbufneed;\n// } STAT_WORKSTATION_0,*PSTAT_WORKSTATION_0,*LPSTAT_WORKSTATION_0;\n// #else\n\nstruct STAT_WORKSTATION_0{\n    LARGE_INTEGER StatisticsStartTime;\n    LARGE_INTEGER BytesReceived;\n    LARGE_INTEGER SmbsReceived;\n    LARGE_INTEGER PagingReadBytesRequested;\n    LARGE_INTEGER NonPagingReadBytesRequested;\n    LARGE_INTEGER CacheReadBytesRequested;\n    LARGE_INTEGER NetworkReadBytesRequested;\n    LARGE_INTEGER BytesTransmitted;\n    LARGE_INTEGER SmbsTransmitted;\n    LARGE_INTEGER PagingWriteBytesRequested;\n    LARGE_INTEGER NonPagingWriteBytesRequested;\n    LARGE_INTEGER CacheWriteBytesRequested;\n    LARGE_INTEGER NetworkWriteBytesRequested;\n    DWORD InitiallyFailedOperations;\n    DWORD FailedCompletionOperations;\n    DWORD ReadOperations;\n    DWORD RandomReadOperations;\n    DWORD ReadSmbs;\n    DWORD LargeReadSmbs;\n    DWORD SmallReadSmbs;\n    DWORD WriteOperations;\n    DWORD RandomWriteOperations;\n    DWORD WriteSmbs;\n    DWORD LargeWriteSmbs;\n    DWORD SmallWriteSmbs;\n    DWORD RawReadsDenied;\n    DWORD RawWritesDenied;\n    DWORD NetworkErrors;\n    DWORD Sessions;\n    DWORD FailedSessions;\n    DWORD Reconnects;\n    DWORD CoreConnects;\n    DWORD Lanman20Connects;\n    DWORD Lanman21Connects;\n    DWORD LanmanNtConnects;\n    DWORD ServerDisconnects;\n    DWORD HungSessions;\n    DWORD UseCount;\n    DWORD FailedUseCount;\n    DWORD CurrentCommands;\n}\nalias STAT_WORKSTATION_0* PSTAT_WORKSTATION_0, LPSTAT_WORKSTATION_0;\n\nextern (Windows):\nNET_API_STATUS NetStatisticsGet(LPWSTR,LPWSTR,DWORD,DWORD,PBYTE*);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmsvc.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmsvc.d)\n */\nmodule core.sys.windows.lmsvc;\nversion (Windows):\n\n// FIXME: Is this file deprecated? All of the functions are only for Win16.\n/**\n  Changes relative to MinGW:\n  lmsname is not imported publicly (instead, core.sys.windows.lm imports it directly).\n*/\n// TODO: 5 macros\n\nprivate import core.sys.windows.lmcons, core.sys.windows.lmsname, core.sys.windows.windef;\n\nconst TCHAR[] SERVICE_DOS_ENCRYPTION = \"ENCRYPT\";\n\nenum SERVICE_UNINSTALLED=0;\nenum SERVICE_INSTALL_PENDING=1;\nenum SERVICE_UNINSTALL_PENDING=2;\nenum SERVICE_INSTALLED=3;\nenum SERVICE_INSTALL_STATE=3;\nenum SERVICE_PAUSE_STATE=18;\nenum LM20_SERVICE_ACTIVE=0;\nenum LM20_SERVICE_CONTINUE_PENDING=4;\nenum LM20_SERVICE_PAUSE_PENDING=8;\nenum LM20_SERVICE_PAUSED=18;\nenum SERVICE_NOT_UNINSTALLABLE=0;\nenum SERVICE_UNINSTALLABLE=16;\nenum SERVICE_NOT_PAUSABLE=0;\nenum SERVICE_PAUSABLE=32;\nenum SERVICE_REDIR_PAUSED=0x700;\nenum SERVICE_REDIR_DISK_PAUSED=256;\nenum SERVICE_REDIR_PRINT_PAUSED=512;\nenum SERVICE_REDIR_COMM_PAUSED=1024;\nenum SERVICE_CTRL_INTERROGATE=0;\nenum SERVICE_CTRL_PAUSE=1;\nenum SERVICE_CTRL_CONTINUE=2;\nenum SERVICE_CTRL_UNINSTALL=3;\nenum SERVICE_CTRL_REDIR_DISK=1;\nenum SERVICE_CTRL_REDIR_PRINT=2;\nenum SERVICE_CTRL_REDIR_COMM=4;\nenum SERVICE_IP_NO_HINT=0;\nenum SERVICE_CCP_NO_HINT=0;\nenum SERVICE_IP_QUERY_HINT=0x10000;\nenum SERVICE_CCP_QUERY_HINT=0x10000;\nenum SERVICE_IP_CHKPT_NUM=255;\nenum SERVICE_CCP_CHKPT_NUM=255;\nenum SERVICE_IP_WAIT_TIME=0xFF00;\nenum SERVICE_CCP_WAIT_TIME=0xFF00;\nenum SERVICE_IP_WAITTIME_SHIFT=8;\nenum SERVICE_NTIP_WAITTIME_SHIFT=12;\nenum UPPER_HINT_MASK=0xFF00;\nenum LOWER_HINT_MASK=255;\nenum UPPER_GET_HINT_MASK=0xFF00000;\nenum LOWER_GET_HINT_MASK=0xFF00;\nenum SERVICE_NT_MAXTIME=0xFFFF;\nenum SERVICE_RESRV_MASK=0x1FFFF;\nenum SERVICE_MAXTIME=255;\nenum SERVICE_BASE=3050;\nenum SERVICE_UIC_NORMAL=0;\n\nenum SERVICE_UIC_BADPARMVAL = SERVICE_BASE+1;\nenum SERVICE_UIC_MISSPARM = SERVICE_BASE+2;\nenum SERVICE_UIC_UNKPARM = SERVICE_BASE+3;\nenum SERVICE_UIC_RESOURCE = SERVICE_BASE+4;\nenum SERVICE_UIC_CONFIG = SERVICE_BASE+5;\nenum SERVICE_UIC_SYSTEM = SERVICE_BASE+6;\nenum SERVICE_UIC_INTERNAL = SERVICE_BASE+7;\nenum SERVICE_UIC_AMBIGPARM = SERVICE_BASE+8;\nenum SERVICE_UIC_DUPPARM = SERVICE_BASE+9;\nenum SERVICE_UIC_KILL = SERVICE_BASE+10;\nenum SERVICE_UIC_EXEC = SERVICE_BASE+11;\nenum SERVICE_UIC_SUBSERV = SERVICE_BASE+12;\nenum SERVICE_UIC_CONFLPARM = SERVICE_BASE+13;\nenum SERVICE_UIC_FILE = SERVICE_BASE+14;\nenum SERVICE_UIC_M_NULL=0;\nenum SERVICE_UIC_M_MEMORY = SERVICE_BASE+20;\nenum SERVICE_UIC_M_DISK = SERVICE_BASE+21;\nenum SERVICE_UIC_M_THREADS = SERVICE_BASE+22;\nenum SERVICE_UIC_M_PROCESSES = SERVICE_BASE+23;\nenum SERVICE_UIC_M_SECURITY = SERVICE_BASE+24;\nenum SERVICE_UIC_M_LANROOT = SERVICE_BASE+25;\nenum SERVICE_UIC_M_REDIR = SERVICE_BASE+26;\nenum SERVICE_UIC_M_SERVER = SERVICE_BASE+27;\nenum SERVICE_UIC_M_SEC_FILE_ERR = SERVICE_BASE+28;\nenum SERVICE_UIC_M_FILES = SERVICE_BASE+29;\nenum SERVICE_UIC_M_LOGS = SERVICE_BASE+30;\nenum SERVICE_UIC_M_LANGROUP = SERVICE_BASE+31;\nenum SERVICE_UIC_M_MSGNAME = SERVICE_BASE+32;\nenum SERVICE_UIC_M_ANNOUNCE = SERVICE_BASE+33;\nenum SERVICE_UIC_M_UAS = SERVICE_BASE+34;\nenum SERVICE_UIC_M_SERVER_SEC_ERR = SERVICE_BASE+35;\nenum SERVICE_UIC_M_WKSTA = SERVICE_BASE+37;\nenum SERVICE_UIC_M_ERRLOG = SERVICE_BASE+38;\nenum SERVICE_UIC_M_FILE_UW = SERVICE_BASE+39;\nenum SERVICE_UIC_M_ADDPAK = SERVICE_BASE+40;\nenum SERVICE_UIC_M_LAZY = SERVICE_BASE+41;\nenum SERVICE_UIC_M_UAS_MACHINE_ACCT = SERVICE_BASE+42;\nenum SERVICE_UIC_M_UAS_SERVERS_NMEMB = SERVICE_BASE+43;\nenum SERVICE_UIC_M_UAS_SERVERS_NOGRP = SERVICE_BASE+44;\nenum SERVICE_UIC_M_UAS_INVALID_ROLE = SERVICE_BASE+45;\nenum SERVICE_UIC_M_NETLOGON_NO_DC = SERVICE_BASE+46;\nenum SERVICE_UIC_M_NETLOGON_DC_CFLCT = SERVICE_BASE+47;\nenum SERVICE_UIC_M_NETLOGON_AUTH = SERVICE_BASE+48;\nenum SERVICE_UIC_M_UAS_PROLOG = SERVICE_BASE+49;\nenum SERVICE2_BASE=5600;\nenum SERVICE_UIC_M_NETLOGON_MPATH = SERVICE2_BASE+0;\nenum SERVICE_UIC_M_LSA_MACHINE_ACCT = SERVICE2_BASE+1;\nenum SERVICE_UIC_M_DATABASE_ERROR = SERVICE2_BASE+2;\n\nstruct SERVICE_INFO_0 {\n    LPWSTR svci0_name;\n}\nalias SERVICE_INFO_0* PSERVICE_INFO_0, LPSERVICE_INFO_0;\n\nstruct SERVICE_INFO_1 {\n    LPWSTR svci1_name;\n    DWORD svci1_status;\n    DWORD svci1_code;\n    DWORD svci1_pid;\n}\nalias SERVICE_INFO_1* PSERVICE_INFO_1, LPSERVICE_INFO_1;\n\nstruct SERVICE_INFO_2 {\n    LPWSTR svci2_name;\n    DWORD svci2_status;\n    DWORD svci2_code;\n    DWORD svci2_pid;\n    LPWSTR svci2_text;\n    DWORD svci2_specific_error;\n    LPWSTR svci2_display_name;\n}\nalias SERVICE_INFO_2* PSERVICE_INFO_2, LPSERVICE_INFO_2;\n\nextern (Windows) {\n    deprecated {\n        NET_API_STATUS NetServiceControl(LPCWSTR, LPCWSTR, DWORD, DWORD,\n          PBYTE*);\n        NET_API_STATUS NetServiceEnum(LPCWSTR, DWORD, PBYTE*, DWORD, PDWORD,\n          PDWORD, PDWORD);\n        NET_API_STATUS NetServiceGetInfo(LPCWSTR, LPCWSTR, DWORD, PBYTE*);\n        NET_API_STATUS NetServiceInstall(LPCWSTR, LPCWSTR, DWORD, LPCWSTR*,\n          PBYTE*);\n    }\n}\n//MACRO #define SERVICE_IP_CODE(t, n) ((long)SERVICE_IP_QUERY_HINT|(long)(n|(t<<SERVICE_IP_WAITTIME_SHIFT)))\n//MACRO #define SERVICE_CCP_CODE(t, n) ((long)SERVICE_CCP_QUERY_HINT|(long)(n|(t<<SERVICE_IP_WAITTIME_SHIFT)))\n//MACRO #define SERVICE_UIC_CODE(c, m) ((long)(((long)c<<16)|(long)(USHORT)m))\n//MACRO #define SERVICE_NT_CCP_CODE(t, n) (((long)SERVICE_CCP_QUERY_HINT)|((long)(n))|(((t)&LOWER_HINT_MASK)<<SERVICE_IP_WAITTIME_SHIFT)|(((t)&UPPER_HINT_MASK)<<SERVICE_NTIP_WAITTIME_SHIFT))\n//MACRO #define SERVICE_NT_WAIT_GET(c) ((((c)&UPPER_GET_HINT_MASK)>>SERVICE_NTIP_WAITTIME_SHIFT)|(((c)&LOWER_GET_HINT_MASK)>>SERVICE_IP_WAITTIME_SHIFT))\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmuse.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmuse.d)\n */\nmodule core.sys.windows.lmuse;\nversion (Windows):\npragma(lib, \"netapi32\");\n\nimport core.sys.windows.lmuseflg;\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nenum {\n    USE_LOCAL_PARMNUM = 1,\n    USE_REMOTE_PARMNUM,\n    USE_PASSWORD_PARMNUM,\n    USE_ASGTYPE_PARMNUM,\n    USE_USERNAME_PARMNUM,\n    USE_DOMAINNAME_PARMNUM\n}\n\nenum {\n    USE_OK,\n    USE_PAUSED,\n    USE_SESSLOST,\n    USE_DISCONN = USE_SESSLOST,\n    USE_NETERR,\n    USE_CONN,\n    USE_RECONN\n}\n\nenum DWORD USE_WILDCARD = -1;\n\nenum {\n    USE_DISKDEV,\n    USE_SPOOLDEV,\n    USE_CHARDEV,\n    USE_IPC\n}\n\nstruct USE_INFO_0 {\n    LPWSTR ui0_local;\n    LPWSTR ui0_remote;\n}\nalias USE_INFO_0* PUSE_INFO_0, LPUSE_INFO_0;\n\nstruct USE_INFO_1 {\n    LPWSTR ui1_local;\n    LPWSTR ui1_remote;\n    LPWSTR ui1_password;\n    DWORD ui1_status;\n    DWORD ui1_asg_type;\n    DWORD ui1_refcount;\n    DWORD ui1_usecount;\n}\nalias USE_INFO_1* PUSE_INFO_1, LPUSE_INFO_1;\n\nstruct USE_INFO_2 {\n    LPWSTR ui2_local;\n    LPWSTR ui2_remote;\n    LPWSTR ui2_password;\n    DWORD ui2_status;\n    DWORD ui2_asg_type;\n    DWORD ui2_refcount;\n    DWORD ui2_usecount;\n    LPWSTR ui2_username;\n    LPWSTR ui2_domainname;\n}\nalias USE_INFO_2* PUSE_INFO_2, LPUSE_INFO_2;\n\nextern (Windows) {\n    NET_API_STATUS NetUseAdd(LPWSTR, DWORD, PBYTE, PDWORD);\n    NET_API_STATUS NetUseDel(LPWSTR, LPWSTR, DWORD);\n    NET_API_STATUS NetUseEnum(LPWSTR, DWORD, PBYTE*, DWORD, PDWORD, PDWORD,\n      PDWORD);\n    NET_API_STATUS NetUseGetInfo(LPWSTR, LPWSTR, DWORD, PBYTE*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmuseflg.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.10\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmuseflg.d)\n */\nmodule core.sys.windows.lmuseflg;\nversion (Windows):\n\nenum : uint {\n    USE_NOFORCE = 0,\n    USE_FORCE,\n    USE_LOTS_OF_FORCE // = 2\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lmwksta.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lmwksta.d)\n */\nmodule core.sys.windows.lmwksta;\nversion (Windows):\npragma(lib, \"netapi32\");\n\nimport core.sys.windows.lmuseflg;\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\npragma(lib, \"Netapi32\");\n\nenum {\n    WKSTA_COMPUTERNAME_PARMNUM     = 1,\n    WKSTA_LANGROUP_PARMNUM,     // = 2\n    WKSTA_VER_MAJOR_PARMNUM        = 4,\n    WKSTA_VER_MINOR_PARMNUM,\n    WKSTA_LOGGED_ON_USERS_PARMNUM,\n    WKSTA_LANROOT_PARMNUM,\n    WKSTA_LOGON_DOMAIN_PARMNUM,\n    WKSTA_LOGON_SERVER_PARMNUM,\n    WKSTA_CHARWAIT_PARMNUM,\n    WKSTA_CHARTIME_PARMNUM,\n    WKSTA_CHARCOUNT_PARMNUM,\n    WKSTA_KEEPCONN_PARMNUM,\n    WKSTA_KEEPSEARCH_PARMNUM,\n    WKSTA_MAXCMDS_PARMNUM,\n    WKSTA_NUMWORKBUF_PARMNUM,\n    WKSTA_MAXWRKCACHE_PARMNUM,\n    WKSTA_SESSTIMEOUT_PARMNUM,\n    WKSTA_SIZERROR_PARMNUM,\n    WKSTA_NUMALERTS_PARMNUM,\n    WKSTA_NUMSERVICES_PARMNUM,\n    WKSTA_NUMCHARBUF_PARMNUM,\n    WKSTA_SIZCHARBUF_PARMNUM,     // = 23\n    WKSTA_ERRLOGSZ_PARMNUM           = 27,\n    WKSTA_PRINTBUFTIME_PARMNUM,\n    WKSTA_SIZWORKBUF_PARMNUM,\n    WKSTA_MAILSLOTS_PARMNUM,\n    WKSTA_NUMDGRAMBUF_PARMNUM,\n    WKSTA_WRKHEURISTICS_PARMNUM,\n    WKSTA_MAXTHREADS_PARMNUM,     // = 33\n    WKSTA_LOCKQUOTA_PARMNUM          = 41,\n    WKSTA_LOCKINCREMENT_PARMNUM,\n    WKSTA_LOCKMAXIMUM_PARMNUM,\n    WKSTA_PIPEINCREMENT_PARMNUM,\n    WKSTA_PIPEMAXIMUM_PARMNUM,\n    WKSTA_DORMANTFILELIMIT_PARMNUM,\n    WKSTA_CACHEFILETIMEOUT_PARMNUM,\n    WKSTA_USEOPPORTUNISTICLOCKING_PARMNUM,\n    WKSTA_USEUNLOCKBEHIND_PARMNUM,\n    WKSTA_USECLOSEBEHIND_PARMNUM,\n    WKSTA_BUFFERNAMEDPIPES_PARMNUM,\n    WKSTA_USELOCKANDREADANDUNLOCK_PARMNUM,\n    WKSTA_UTILIZENTCACHING_PARMNUM,\n    WKSTA_USERAWREAD_PARMNUM,\n    WKSTA_USERAWWRITE_PARMNUM,\n    WKSTA_USEWRITERAWWITHDATA_PARMNUM,\n    WKSTA_USEENCRYPTION_PARMNUM,\n    WKSTA_BUFFILESWITHDENYWRITE_PARMNUM,\n    WKSTA_BUFFERREADONLYFILES_PARMNUM,\n    WKSTA_FORCECORECREATEMODE_PARMNUM,\n    WKSTA_USE512BYTESMAXTRANSFER_PARMNUM,\n    WKSTA_READAHEADTHRUPUT_PARMNUM,    // = 62\n    WKSTA_PLATFORM_ID_PARMNUM             = 100,\n    WKSTA_OTH_DOMAINS_PARMNUM             = 101,\n    TRANSPORT_QUALITYOFSERVICE_PARMNUM    = 201,\n    TRANSPORT_NAME_PARMNUM                = 202\n}\n\nstruct WKSTA_INFO_100{\n    DWORD wki100_platform_id;\n    LPWSTR wki100_computername;\n    LPWSTR wki100_langroup;\n    DWORD wki100_ver_major;\n    DWORD wki100_ver_minor;\n}\nalias WKSTA_INFO_100* PWKSTA_INFO_100, LPWKSTA_INFO_100;\n\nstruct WKSTA_INFO_101{\n    DWORD wki101_platform_id;\n    LPWSTR wki101_computername;\n    LPWSTR wki101_langroup;\n    DWORD wki101_ver_major;\n    DWORD wki101_ver_minor;\n    LPWSTR wki101_lanroot;\n}\nalias WKSTA_INFO_101* PWKSTA_INFO_101, LPWKSTA_INFO_101;\n\nstruct WKSTA_INFO_102{\n    DWORD wki102_platform_id;\n    LPWSTR wki102_computername;\n    LPWSTR wki102_langroup;\n    DWORD wki102_ver_major;\n    DWORD wki102_ver_minor;\n    LPWSTR wki102_lanroot;\n    DWORD wki102_logged_on_users;\n}\nalias WKSTA_INFO_102* PWKSTA_INFO_102, LPWKSTA_INFO_102;\n\nstruct WKSTA_INFO_302{\n    DWORD wki302_char_wait;\n    DWORD wki302_collection_time;\n    DWORD wki302_maximum_collection_count;\n    DWORD wki302_keep_conn;\n    DWORD wki302_keep_search;\n    DWORD wki302_max_cmds;\n    DWORD wki302_num_work_buf;\n    DWORD wki302_siz_work_buf;\n    DWORD wki302_max_wrk_cache;\n    DWORD wki302_sess_timeout;\n    DWORD wki302_siz_error;\n    DWORD wki302_num_alerts;\n    DWORD wki302_num_services;\n    DWORD wki302_errlog_sz;\n    DWORD wki302_print_buf_time;\n    DWORD wki302_num_char_buf;\n    DWORD wki302_siz_char_buf;\n    LPWSTR wki302_wrk_heuristics;\n    DWORD wki302_mailslots;\n    DWORD wki302_num_dgram_buf;\n}\nalias WKSTA_INFO_302* PWKSTA_INFO_302, LPWKSTA_INFO_302;\n\nstruct WKSTA_INFO_402{\n    DWORD wki402_char_wait;\n    DWORD wki402_collection_time;\n    DWORD wki402_maximum_collection_count;\n    DWORD wki402_keep_conn;\n    DWORD wki402_keep_search;\n    DWORD wki402_max_cmds;\n    DWORD wki402_num_work_buf;\n    DWORD wki402_siz_work_buf;\n    DWORD wki402_max_wrk_cache;\n    DWORD wki402_sess_timeout;\n    DWORD wki402_siz_error;\n    DWORD wki402_num_alerts;\n    DWORD wki402_num_services;\n    DWORD wki402_errlog_sz;\n    DWORD wki402_print_buf_time;\n    DWORD wki402_num_char_buf;\n    DWORD wki402_siz_char_buf;\n    LPWSTR wki402_wrk_heuristics;\n    DWORD wki402_mailslots;\n    DWORD wki402_num_dgram_buf;\n    DWORD wki402_max_threads;\n}\nalias WKSTA_INFO_402* PWKSTA_INFO_402, LPWKSTA_INFO_402;\n\nstruct WKSTA_INFO_502{\n    DWORD wki502_char_wait;\n    DWORD wki502_collection_time;\n    DWORD wki502_maximum_collection_count;\n    DWORD wki502_keep_conn;\n    DWORD wki502_max_cmds;\n    DWORD wki502_sess_timeout;\n    DWORD wki502_siz_char_buf;\n    DWORD wki502_max_threads;\n    DWORD wki502_lock_quota;\n    DWORD wki502_lock_increment;\n    DWORD wki502_lock_maximum;\n    DWORD wki502_pipe_increment;\n    DWORD wki502_pipe_maximum;\n    DWORD wki502_cache_file_timeout;\n    DWORD wki502_dormant_file_limit;\n    DWORD wki502_read_ahead_throughput;\n    DWORD wki502_num_mailslot_buffers;\n    DWORD wki502_num_srv_announce_buffers;\n    DWORD wki502_max_illegal_datagram_events;\n    DWORD wki502_illegal_datagram_event_reset_frequency;\n    BOOL wki502_log_election_packets;\n    BOOL wki502_use_opportunistic_locking;\n    BOOL wki502_use_unlock_behind;\n    BOOL wki502_use_close_behind;\n    BOOL wki502_buf_named_pipes;\n    BOOL wki502_use_lock_read_unlock;\n    BOOL wki502_utilize_nt_caching;\n    BOOL wki502_use_raw_read;\n    BOOL wki502_use_raw_write;\n    BOOL wki502_use_write_raw_data;\n    BOOL wki502_use_encryption;\n    BOOL wki502_buf_files_deny_write;\n    BOOL wki502_buf_read_only_files;\n    BOOL wki502_force_core_create_mode;\n    BOOL wki502_use_512_byte_max_transfer;\n}\nalias WKSTA_INFO_502* PWKSTA_INFO_502, LPWKSTA_INFO_502;\n\nstruct WKSTA_INFO_1010 {\n    DWORD wki1010_char_wait;\n}\nalias WKSTA_INFO_1010* PWKSTA_INFO_1010, LPWKSTA_INFO_1010;\n\nstruct WKSTA_INFO_1011 {\n    DWORD wki1011_collection_time;\n}\nalias WKSTA_INFO_1011* PWKSTA_INFO_1011, LPWKSTA_INFO_1011;\n\nstruct WKSTA_INFO_1012 {\n    DWORD wki1012_maximum_collection_count;\n}\nalias WKSTA_INFO_1012* PWKSTA_INFO_1012, LPWKSTA_INFO_1012;\n\nstruct WKSTA_INFO_1027 {\n    DWORD wki1027_errlog_sz;\n}\nalias WKSTA_INFO_1027* PWKSTA_INFO_1027, LPWKSTA_INFO_1027;\n\nstruct WKSTA_INFO_1028 {\n    DWORD wki1028_print_buf_time;\n}\nalias WKSTA_INFO_1028* PWKSTA_INFO_1028, LPWKSTA_INFO_1028;\n\nstruct WKSTA_INFO_1032 {\n    DWORD wki1032_wrk_heuristics;\n}\nalias WKSTA_INFO_1032* PWKSTA_INFO_1032, LPWKSTA_INFO_1032;\n\nstruct WKSTA_INFO_1013 {\n    DWORD wki1013_keep_conn;\n}\nalias WKSTA_INFO_1013* PWKSTA_INFO_1013, LPWKSTA_INFO_1013;\n\nstruct WKSTA_INFO_1018 {\n    DWORD wki1018_sess_timeout;\n}\nalias WKSTA_INFO_1018* PWKSTA_INFO_1018, LPWKSTA_INFO_1018;\n\nstruct WKSTA_INFO_1023 {\n    DWORD wki1023_siz_char_buf;\n}\nalias WKSTA_INFO_1023* PWKSTA_INFO_1023, LPWKSTA_INFO_1023;\n\nstruct WKSTA_INFO_1033 {\n    DWORD wki1033_max_threads;\n}\nalias WKSTA_INFO_1033* PWKSTA_INFO_1033, LPWKSTA_INFO_1033;\n\nstruct WKSTA_INFO_1041 {\n    DWORD wki1041_lock_quota;\n}\nalias WKSTA_INFO_1041* PWKSTA_INFO_1041, LPWKSTA_INFO_1041;\n\nstruct WKSTA_INFO_1042 {\n    DWORD wki1042_lock_increment;\n}\nalias WKSTA_INFO_1042* PWKSTA_INFO_1042, LPWKSTA_INFO_1042;\n\nstruct WKSTA_INFO_1043 {\n    DWORD wki1043_lock_maximum;\n}\nalias WKSTA_INFO_1043* PWKSTA_INFO_1043, LPWKSTA_INFO_1043;\n\nstruct WKSTA_INFO_1044 {\n    DWORD wki1044_pipe_increment;\n}\nalias WKSTA_INFO_1044* PWKSTA_INFO_1044, LPWKSTA_INFO_1044;\n\nstruct WKSTA_INFO_1045 {\n    DWORD wki1045_pipe_maximum;\n}\nalias WKSTA_INFO_1045* PWKSTA_INFO_1045, LPWKSTA_INFO_1045;\n\nstruct WKSTA_INFO_1046 {\n    DWORD wki1046_dormant_file_limit;\n}\nalias WKSTA_INFO_1046* PWKSTA_INFO_1046, LPWKSTA_INFO_1046;\n\nstruct WKSTA_INFO_1047 {\n    DWORD wki1047_cache_file_timeout;\n}\nalias WKSTA_INFO_1047* PWKSTA_INFO_1047, LPWKSTA_INFO_1047;\n\nstruct WKSTA_INFO_1048 {\n    BOOL wki1048_use_opportunistic_locking;\n}\nalias WKSTA_INFO_1048* PWKSTA_INFO_1048, LPWKSTA_INFO_1048;\n\nstruct WKSTA_INFO_1049 {\n    BOOL wki1049_use_unlock_behind;\n}\nalias WKSTA_INFO_1049* PWKSTA_INFO_1049, LPWKSTA_INFO_1049;\n\nstruct WKSTA_INFO_1050 {\n    BOOL wki1050_use_close_behind;\n}\nalias WKSTA_INFO_1050* PWKSTA_INFO_1050, LPWKSTA_INFO_1050;\n\nstruct WKSTA_INFO_1051 {\n    BOOL wki1051_buf_named_pipes;\n}\nalias WKSTA_INFO_1051* PWKSTA_INFO_1051, LPWKSTA_INFO_1051;\n\nstruct WKSTA_INFO_1052 {\n    BOOL wki1052_use_lock_read_unlock;\n}\nalias WKSTA_INFO_1052* PWKSTA_INFO_1052, LPWKSTA_INFO_1052;\n\nstruct WKSTA_INFO_1053 {\n    BOOL wki1053_utilize_nt_caching;\n}\nalias WKSTA_INFO_1053* PWKSTA_INFO_1053, LPWKSTA_INFO_1053;\n\nstruct WKSTA_INFO_1054 {\n    BOOL wki1054_use_raw_read;\n}\nalias WKSTA_INFO_1054* PWKSTA_INFO_1054, LPWKSTA_INFO_1054;\n\nstruct WKSTA_INFO_1055 {\n    BOOL wki1055_use_raw_write;\n}\nalias WKSTA_INFO_1055* PWKSTA_INFO_1055, LPWKSTA_INFO_1055;\n\nstruct WKSTA_INFO_1056 {\n    BOOL wki1056_use_write_raw_data;\n}\nalias WKSTA_INFO_1056* PWKSTA_INFO_1056, LPWKSTA_INFO_1056;\n\nstruct WKSTA_INFO_1057 {\n    BOOL wki1057_use_encryption;\n}\nalias WKSTA_INFO_1057* PWKSTA_INFO_1057, LPWKSTA_INFO_1057;\n\nstruct WKSTA_INFO_1058 {\n    BOOL wki1058_buf_files_deny_write;\n}\nalias WKSTA_INFO_1058* PWKSTA_INFO_1058, LPWKSTA_INFO_1058;\n\nstruct WKSTA_INFO_1059 {\n    BOOL wki1059_buf_read_only_files;\n}\nalias WKSTA_INFO_1059* PWKSTA_INFO_1059, LPWKSTA_INFO_1059;\n\nstruct WKSTA_INFO_1060 {\n    BOOL wki1060_force_core_create_mode;\n}\nalias WKSTA_INFO_1060* PWKSTA_INFO_1060, LPWKSTA_INFO_1060;\n\nstruct WKSTA_INFO_1061 {\n    BOOL wki1061_use_512_byte_max_transfer;\n}\nalias WKSTA_INFO_1061* PWKSTA_INFO_1061, LPWKSTA_INFO_1061;\n\nstruct WKSTA_INFO_1062 {\n    DWORD wki1062_read_ahead_throughput;\n}\nalias WKSTA_INFO_1062* PWKSTA_INFO_1062, LPWKSTA_INFO_1062;\n\nstruct WKSTA_USER_INFO_0 {\n    LPWSTR wkui0_username;\n}\nalias WKSTA_USER_INFO_0* PWKSTA_USER_INFO_0, LPWKSTA_USER_INFO_0;\n\nstruct WKSTA_USER_INFO_1{\n    LPWSTR wkui1_username;\n    LPWSTR wkui1_logon_domain;\n    LPWSTR wkui1_oth_domains;\n    LPWSTR wkui1_logon_server;\n}\nalias WKSTA_USER_INFO_1* PWKSTA_USER_INFO_1, LPWKSTA_USER_INFO_1;\n\nstruct WKSTA_USER_INFO_1101 {\n    LPWSTR wkui1101_oth_domains;\n}\nalias WKSTA_USER_INFO_1101* PWKSTA_USER_INFO_1101, LPWKSTA_USER_INFO_1101;\n\nstruct WKSTA_TRANSPORT_INFO_0{\n    DWORD wkti0_quality_of_service;\n    DWORD wkti0_number_of_vcs;\n    LPWSTR wkti0_transport_name;\n    LPWSTR wkti0_transport_address;\n    BOOL wkti0_wan_ish;\n}\nalias WKSTA_TRANSPORT_INFO_0* PWKSTA_TRANSPORT_INFO_0, LPWKSTA_TRANSPORT_INFO_0;\n\nextern (Windows) {\nNET_API_STATUS NetWkstaGetInfo(LPWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetWkstaSetInfo(LPWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetWkstaUserGetInfo(LPWSTR,DWORD,PBYTE*);\nNET_API_STATUS NetWkstaUserSetInfo(LPWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetWkstaUserEnum(LPWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\nNET_API_STATUS NetWkstaTransportAdd(LPWSTR,DWORD,PBYTE,PDWORD);\nNET_API_STATUS NetWkstaTransportDel(LPWSTR,LPWSTR,DWORD);\nNET_API_STATUS NetWkstaTransportEnum(LPWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/lzexpand.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_lzexpand.d)\n */\nmodule core.sys.windows.lzexpand;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"lz32\");\n\nprivate import core.sys.windows.winbase, core.sys.windows.windef;\n\nenum : LONG {\n    LZERROR_BADINHANDLE  = -1,\n    LZERROR_BADOUTHANDLE = -2,\n    LZERROR_READ         = -3,\n    LZERROR_WRITE        = -4,\n    LZERROR_GLOBALLOC    = -5,\n    LZERROR_GLOBLOCK     = -6,\n    LZERROR_BADVALUE     = -7,\n    LZERROR_UNKNOWNALG   = -8\n}\n\nextern (Windows):\ndeprecated {\n    LONG CopyLZFile(INT, INT);\n    void LZDone();\n    INT LZStart();\n}\nINT GetExpandedNameA(LPSTR, LPSTR);\nINT GetExpandedNameW(LPWSTR, LPWSTR);\nvoid LZClose(INT);\nLONG LZCopy(INT, INT);\nINT LZInit(INT);\nINT LZOpenFileA(LPSTR, LPOFSTRUCT, WORD);\nINT LZOpenFileW(LPWSTR, LPOFSTRUCT, WORD);\nINT LZRead(INT, LPSTR, INT);\nLONG LZSeek(INT, LONG, INT);\n\nversion (Unicode) {\n    alias GetExpandedNameW GetExpandedName;\n    alias LZOpenFileW LZOpenFile;\n} else {\n    alias GetExpandedNameA GetExpandedName;\n    alias LZOpenFileA LZOpenFile;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/mapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_mapi.d)\n */\nmodule core.sys.windows.mapi;\nversion (Windows):\n\nprivate import core.sys.windows.windef;\n\n// FIXME: check types and grouping of constants\n\nenum {\n    SUCCESS_SUCCESS,\n    MAPI_USER_ABORT,\n    MAPI_E_USER_ABORT        = MAPI_USER_ABORT,\n    MAPI_E_FAILURE,\n    MAPI_E_LOGIN_FAILURE,\n    MAPI_E_LOGON_FAILURE     = MAPI_E_LOGIN_FAILURE,\n    MAPI_E_DISK_FULL         = 4,\n    MAPI_E_INSUFFICIENT_MEMORY,\n    MAPI_E_ACCESS_DENIED,\n    MAPI_E_BLK_TOO_SMALL     = MAPI_E_ACCESS_DENIED, // = 6\n    MAPI_E_TOO_MANY_SESSIONS = 8,\n    MAPI_E_TOO_MANY_FILES,\n    MAPI_E_TOO_MANY_RECIPIENTS,\n    MAPI_E_ATTACHMENT_NOT_FOUND,\n    MAPI_E_ATTACHMENT_OPEN_FAILURE,\n    MAPI_E_ATTACHMENT_WRITE_FAILURE,\n    MAPI_E_UNKNOWN_RECIPIENT,\n    MAPI_E_BAD_RECIPTYPE,\n    MAPI_E_NO_MESSAGES,\n    MAPI_E_INVALID_MESSAGE,\n    MAPI_E_TEXT_TOO_LARGE,\n    MAPI_E_INVALID_SESSION,\n    MAPI_E_TYPE_NOT_SUPPORTED,\n    MAPI_E_AMBIGUOUS_RECIPIENT,\n    MAPI_E_AMBIGUOUS_RECIP   = MAPI_E_AMBIGUOUS_RECIPIENT,\n    MAPI_E_MESSAGE_IN_USE,\n    MAPI_E_NETWORK_FAILURE,\n    MAPI_E_INVALID_EDITFIELDS,\n    MAPI_E_INVALID_RECIPS,\n    MAPI_E_NOT_SUPPORTED  // = 26\n}\n\nenum {\n    MAPI_ORIG,\n    MAPI_TO,\n    MAPI_CC,\n    MAPI_BCC\n}\n\nenum MAPI_LOGON_UI          = 0x0001;\nenum MAPI_NEW_SESSION       = 0x0002;\nenum MAPI_FORCE_DOWNLOAD    = 0x1000;\nenum MAPI_LOGOFF_SHARED     = 0x0001;\nenum MAPI_LOGOFF_UI         = 0x0002;\nenum MAPI_DIALOG            = 0x0008;\nenum MAPI_UNREAD_ONLY       = 0x0020;\nenum MAPI_LONG_MSGID        = 0x4000;\nenum MAPI_GUARANTEE_FIFO    = 0x0100;\nenum MAPI_ENVELOPE_ONLY     = 0x0040;\nenum MAPI_PEEK              = 0x0080;\nenum MAPI_BODY_AS_FILE      = 0x0200;\nenum MAPI_SUPPRESS_ATTACH   = 0x0800;\nenum MAPI_AB_NOMODIFY       = 0x0400;\nenum MAPI_OLE               = 0x0001;\nenum MAPI_OLE_STATIC        = 0x0002;\nenum MAPI_UNREAD            = 0x0001;\nenum MAPI_RECEIPT_REQUESTED = 0x0002;\nenum MAPI_SENT              = 0x0004;\n\nalias uint FLAGS;\nalias uint* LPULONG;\nalias ULONG_PTR LHANDLE;\nalias ULONG_PTR* LPLHANDLE;\n\nstruct MapiRecipDesc {\n    ULONG  ulReserved;\n    ULONG  ulRecipClass;\n    LPSTR  lpszName;\n    LPSTR  lpszAddress;\n    ULONG  ulEIDSize;\n    LPVOID lpEntryID;\n}\nalias MapiRecipDesc* lpMapiRecipDesc;\n\nstruct MapiFileDesc {\n    ULONG  ulReserved;\n    ULONG  flFlags;\n    ULONG  nPosition;\n    LPSTR  lpszPathName;\n    LPSTR  lpszFileName;\n    LPVOID lpFileType;\n}\nalias MapiFileDesc* lpMapiFileDesc;\n\nstruct MapiFileTagExt {\n    ULONG  ulReserved;\n    ULONG  cbTag;\n    LPBYTE lpTag;\n    ULONG  cbEncoding;\n    LPBYTE lpEncoding;\n}\nalias MapiFileTagExt* lpMapiFileTagExt;\n\nstruct MapiMessage {\n    ULONG           ulReserved;\n    LPSTR           lpszSubject;\n    LPSTR           lpszNoteText;\n    LPSTR           lpszMessageType;\n    LPSTR           lpszDateReceived;\n    LPSTR           lpszConversationID;\n    FLAGS           flFlags;\n    lpMapiRecipDesc lpOriginator;\n    ULONG           nRecipCount;\n    lpMapiRecipDesc lpRecips;\n    ULONG           nFileCount;\n    lpMapiFileDesc  lpFiles;\n}\nalias MapiMessage* lpMapiMessage;\n\nextern (Pascal) {\n    ULONG MAPILogon(ULONG_PTR, LPSTR, LPSTR, FLAGS, ULONG, LPLHANDLE);\n    ULONG MAPISendMail(LHANDLE, ULONG_PTR, lpMapiMessage, FLAGS, ULONG);\n    ULONG MAPISendDocuments(ULONG_PTR, LPSTR, LPSTR, LPSTR, ULONG);\n    ULONG MAPIReadMail(LHANDLE, ULONG_PTR, LPSTR, FLAGS, ULONG, lpMapiMessage*);\n    ULONG MAPIFindNext(LHANDLE, ULONG_PTR, LPSTR, LPSTR, FLAGS, ULONG, LPSTR);\n    ULONG MAPIResolveName(LHANDLE, ULONG_PTR, LPSTR, FLAGS, ULONG,\n      lpMapiRecipDesc*);\n    ULONG MAPIAddress(LHANDLE, ULONG_PTR, LPSTR, ULONG, LPSTR, ULONG,\n      lpMapiRecipDesc, FLAGS, ULONG, LPULONG, lpMapiRecipDesc*);\n    ULONG MAPIFreeBuffer(LPVOID);\n    ULONG MAPIDetails(LHANDLE, ULONG_PTR, lpMapiRecipDesc, FLAGS, ULONG);\n    ULONG MAPISaveMail(LHANDLE, ULONG_PTR, lpMapiMessage lpszMessage, FLAGS,\n      ULONG, LPSTR);\n    ULONG MAPIDeleteMail(LHANDLE, ULONG_PTR, LPSTR, FLAGS, ULONG);\n    ULONG MAPILogoff(LHANDLE, ULONG_PTR, FLAGS, ULONG);\n    // Netscape extensions\n    ULONG MAPIGetNetscapeVersion();\n    ULONG MAPI_NSCP_SynchronizeClient(LHANDLE, ULONG);\n\n    // Handles for use with GetProcAddress\n    alias ULONG function(ULONG_PTR, LPSTR, LPSTR, FLAGS, ULONG, LPLHANDLE)\n      LPMAPILOGON;\n    alias ULONG function(LHANDLE, ULONG_PTR, lpMapiMessage, FLAGS, ULONG)\n      LPMAPISENDMAIL;\n    alias ULONG function(ULONG_PTR, LPSTR, LPSTR, LPSTR, ULONG)\n      LPMAPISENDDOCUMENTS;\n    alias ULONG function(LHANDLE, ULONG_PTR, LPSTR, FLAGS, ULONG, lpMapiMessage*)\n      LPMAPIREADMAIL;\n    alias ULONG function(LHANDLE, ULONG_PTR, LPSTR, LPSTR, FLAGS, ULONG, LPSTR)\n      LPMAPIFINDNEXT;\n    alias ULONG function(LHANDLE, ULONG_PTR, LPSTR, FLAGS, ULONG,\n      lpMapiRecipDesc*) LPMAPIRESOLVENAME;\n    alias ULONG function(LHANDLE, ULONG_PTR, LPSTR, ULONG, LPSTR, ULONG,\n      lpMapiRecipDesc, FLAGS, ULONG, LPULONG, lpMapiRecipDesc*) LPMAPIADDRESS;\n    alias ULONG function(LPVOID lpv) LPMAPIFREEBUFFER;\n    alias ULONG function(LHANDLE, ULONG_PTR, lpMapiRecipDesc, FLAGS, ULONG)\n      LPMAPIDETAILS;\n    alias ULONG function(LHANDLE, ULONG_PTR, lpMapiMessage, FLAGS, ULONG, LPSTR)\n      LPMAPISAVEMAIL;\n    alias ULONG function(LHANDLE, ULONG_PTR, LPSTR, FLAGS, ULONG)\n      LPMAPIDELETEMAIL;\n    alias ULONG function(LHANDLE, ULONG_PTR, FLAGS, ULONG) LPMAPILOGOFF;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/mciavi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_mciavi.d)\n */\nmodule core.sys.windows.mciavi;\nversion (Windows):\n\nprivate import core.sys.windows.mmsystem;\n\n// FIXME: check types and grouping of constants\n\nenum MCI_MCIAVI_PLAY_WINDOW     = 0x01000000;\nenum MCI_MCIAVI_PLAY_FULLSCREEN = 0x02000000;\nenum MCI_MCIAVI_PLAY_FULLBY2    = 0x04000000;\n\nenum {\n    MCI_AVI_STATUS_FRAMES_SKIPPED     = 0x00008001,\n    MCI_AVI_STATUS_LAST_PLAY_SPEED    = 0x00008002,\n    MCI_AVI_STATUS_AUDIO_BREAKS       = 0x00008003,\n    MCI_AVI_SETVIDEO_DRAW_PROCEDURE   = 0x00008000,\n    MCI_AVI_SETVIDEO_PALETTE_COLOR    = 0x00008100,\n    MCI_AVI_SETVIDEO_PALETTE_HALFTONE = 0x0000FFFF\n}\n\nenum {\n    MCIERR_AVI_OLDAVIFORMAT  = MCIERR_CUSTOM_DRIVER_BASE + 100,\n    MCIERR_AVI_NOTINTERLEAVED,\n    MCIERR_AVI_NODISPDIB,\n    MCIERR_AVI_CANTPLAYFULLSCREEN,\n    MCIERR_AVI_TOOBIGFORVGA,\n    MCIERR_AVI_NOCOMPRESSOR,\n    MCIERR_AVI_DISPLAYERROR,\n    MCIERR_AVI_AUDIOERROR,\n    MCIERR_AVI_BADPALETTE // = MCIERR_CUSTOM_DRIVER_BASE + 108\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/mcx.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_mcx.d)\n */\nmodule core.sys.windows.mcx;\nversion (Windows):\n\nprivate import core.sys.windows.windef;\n\nenum DWORD\n    DIALOPTION_BILLING  =  64,\n    DIALOPTION_QUIET    = 128,\n    DIALOPTION_DIALTONE = 256;\n\nenum DWORD\n    MDMVOLFLAG_LOW    = 1,\n    MDMVOLFLAG_MEDIUM = 2,\n    MDMVOLFLAG_HIGH   = 4;\n\nenum : DWORD {\n    MDMVOL_LOW    = 0,\n    MDMVOL_MEDIUM = 1,\n    MDMVOL_HIGH   = 2\n}\n\nenum DWORD\n    MDMSPKRFLAG_OFF       = 1,\n    MDMSPKRFLAG_DIAL      = 2,\n    MDMSPKRFLAG_ON        = 4,\n    MDMSPKRFLAG_CALLSETUP = 8;\n\nenum : DWORD {\n    MDMSPKR_OFF,\n    MDMSPKR_DIAL,\n    MDMSPKR_ON,\n    MDMSPKR_CALLSETUP\n}\n\nenum DWORD\n    MDM_COMPRESSION      = 0x0001,\n    MDM_ERROR_CONTROL    = 0x0002,\n    MDM_FORCED_EC        = 0x0004,\n    MDM_CELLULAR         = 0x0008,\n    MDM_FLOWCONTROL_HARD = 0x0010,\n    MDM_FLOWCONTROL_SOFT = 0x0020,\n    MDM_CCITT_OVERRIDE   = 0x0040,\n    MDM_SPEED_ADJUST     = 0x0080,\n    MDM_TONE_DIAL        = 0x0100,\n    MDM_BLIND_DIAL       = 0x0200,\n    MDM_V23_OVERRIDE     = 0x0400;\n\nstruct MODEMDEVCAPS {\n    DWORD dwActualSize;\n    DWORD dwRequiredSize;\n    DWORD dwDevSpecificOffset;\n    DWORD dwDevSpecificSize;\n    DWORD dwModemProviderVersion;\n    DWORD dwModemManufacturerOffset;\n    DWORD dwModemManufacturerSize;\n    DWORD dwModemModelOffset;\n    DWORD dwModemModelSize;\n    DWORD dwModemVersionOffset;\n    DWORD dwModemVersionSize;\n    DWORD dwDialOptions;\n    DWORD dwCallSetupFailTimer;\n    DWORD dwInactivityTimeout;\n    DWORD dwSpeakerVolume;\n    DWORD dwSpeakerMode;\n    DWORD dwModemOptions;\n    DWORD dwMaxDTERate;\n    DWORD dwMaxDCERate;\n    BYTE  _abVariablePortion;\n\n    BYTE* abVariablePortion() return { return &_abVariablePortion; }\n}\nalias MODEMDEVCAPS* PMODEMDEVCAPS, LPMODEMDEVCAPS;\n\nstruct MODEMSETTINGS {\n    DWORD dwActualSize;\n    DWORD dwRequiredSize;\n    DWORD dwDevSpecificOffset;\n    DWORD dwDevSpecificSize;\n    DWORD dwCallSetupFailTimer;\n    DWORD dwInactivityTimeout;\n    DWORD dwSpeakerVolume;\n    DWORD dwSpeakerMode;\n    DWORD dwPreferredModemOptions;\n    DWORD dwNegotiatedModemOptions;\n    DWORD dwNegotiatedDCERate;\n    BYTE  _abVariablePortion;\n\n    BYTE* abVariablePortion() return { return &_abVariablePortion; }\n}\nalias MODEMSETTINGS* PMODEMSETTINGS, LPMODEMSETTINGS;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/mgmtapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_mgmtapi.d)\n */\nmodule core.sys.windows.mgmtapi;\nversion (Windows):\n\nimport core.sys.windows.snmp;\nprivate import core.sys.windows.windef;\n\nenum {\n    SNMP_MGMTAPI_TIMEOUT = 40,\n    SNMP_MGMTAPI_SELECT_FDERRORS,\n    SNMP_MGMTAPI_TRAP_ERRORS,\n    SNMP_MGMTAPI_TRAP_DUPINIT,\n    SNMP_MGMTAPI_NOTRAPS,\n    SNMP_MGMTAPI_AGAIN,\n    SNMP_MGMTAPI_INVALID_CTL,\n    SNMP_MGMTAPI_INVALID_SESSION,\n    SNMP_MGMTAPI_INVALID_BUFFER // = 48\n}\n\nenum MGMCTL_SETAGENTPORT = 1;\n\nalias PVOID LPSNMP_MGR_SESSION;\n\nextern (Windows) {\n    BOOL SnmpMgrClose(LPSNMP_MGR_SESSION);\n    BOOL SnmpMgrCtl(LPSNMP_MGR_SESSION, DWORD, LPVOID, DWORD, LPVOID, DWORD,\n      LPDWORD);\n    BOOL SnmpMgrGetTrap(AsnObjectIdentifier*, AsnNetworkAddress*,\n      AsnInteger*, AsnInteger*, AsnTimeticks*, SnmpVarBindList*);\n    BOOL SnmpMgrGetTrapEx(AsnObjectIdentifier*, AsnNetworkAddress*,\n      AsnNetworkAddress*, AsnInteger*, AsnInteger*, AsnOctetString*,\n      AsnTimeticks*, SnmpVarBindList*);\n    BOOL SnmpMgrOidToStr(AsnObjectIdentifier*, LPSTR*);\n    LPSNMP_MGR_SESSION SnmpMgrOpen(LPSTR, LPSTR, INT, INT);\n    INT SnmpMgrRequest(LPSNMP_MGR_SESSION, BYTE, SnmpVarBindList*,\n      AsnInteger*, AsnInteger*);\n    BOOL SnmpMgrStrToOid(LPSTR, AsnObjectIdentifier*);\n    BOOL SnmpMgrTrapListen(HANDLE*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/mmsystem.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_mmsystem.d)\n */\nmodule core.sys.windows.mmsystem;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"winmm\");\n\n/*  The #defines MAKEFOURCC, mmioFOURCC, sndAlias are used to define\n *  compile-time constants, so they are implemented as templates.\n */\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winver;\n\nalign(1):\n\nenum MAXPNAMELEN = 32;\nenum MAXERRORLENGTH = 256;\nenum MAX_JOYSTICKOEMVXDNAME = 260;\n\nenum TIME_MS      = 1;\nenum TIME_SAMPLES = 2;\nenum TIME_BYTES   = 4;\nenum TIME_SMPTE   = 8;\nenum TIME_MIDI    = 16;\nenum TIME_TICKS   = 32;\n\ntemplate MAKEFOURCC(char c0, char c1, char c2, char c3)\n{\nenum DWORD MAKEFOURCC = c0 | (c1<<8) | (c2<<16) | (cast(DWORD)c3 <<24);\n}\n\ntemplate mmioFOURCC(char c0, char c1, char c2, char c3)\n{\nenum DWORD mmioFOURCC = c0 | (c1<<8) | (c2<<16) | (cast(DWORD)c3 <<24);\n}\n\nenum {\n    MM_JOY1MOVE            = 0x3A0,\n    MM_JOY2MOVE,\n    MM_JOY1ZMOVE,\n    MM_JOY2ZMOVE,       // = 0x3A3\n    MM_JOY1BUTTONDOWN      = 0x3B5,\n    MM_JOY2BUTTONDOWN,\n    MM_JOY1BUTTONUP,\n    MM_JOY2BUTTONUP,\n    MM_MCINOTIFY,       // = 0x3B9\n    MM_WOM_OPEN            = 0x3BB,\n    MM_WOM_CLOSE,\n    MM_WOM_DONE,\n    MM_WIM_OPEN,\n    MM_WIM_CLOSE,\n    MM_WIM_DATA,\n    MM_MIM_OPEN,\n    MM_MIM_CLOSE,\n    MM_MIM_DATA,\n    MM_MIM_LONGDATA,\n    MM_MIM_ERROR,\n    MM_MIM_LONGERROR,\n    MM_MOM_OPEN,\n    MM_MOM_CLOSE,\n    MM_MOM_DONE,        // = 0x3C9\n    MM_DRVM_OPEN           = 0x3D0,\n    MM_DRVM_CLOSE,\n    MM_DRVM_DATA,\n    MM_DRVM_ERROR,\n    MM_STREAM_OPEN,\n    MM_STREAM_CLOSE,\n    MM_STREAM_DONE,\n    MM_STREAM_ERROR,    // = 0x3D7\n    MM_MOM_POSITIONCB      = 0x3CA,\n    MM_MCISIGNAL,\n    MM_MIM_MOREDATA,    // = 0x3CC\n    MM_MIXM_LINE_CHANGE    = 0x3D0,\n    MM_MIXM_CONTROL_CHANGE = 0x3D1\n}\n\nenum MMSYSERR_BASE     =    0;\nenum WAVERR_BASE       =   32;\nenum MIDIERR_BASE      =   64;\nenum TIMERR_BASE       =   96;\nenum JOYERR_BASE       =  160;\nenum MCIERR_BASE       =  256;\nenum MIXERR_BASE       = 1024;\nenum MCI_STRING_OFFSET =  512;\nenum MCI_VD_OFFSET     = 1024;\nenum MCI_CD_OFFSET     = 1088;\nenum MCI_WAVE_OFFSET   = 1152;\nenum MCI_SEQ_OFFSET    = 1216;\n\nenum {\n    MMSYSERR_NOERROR        = 0,\n    MMSYSERR_ERROR          = MMSYSERR_BASE+1,\n    MMSYSERR_BADDEVICEID,\n    MMSYSERR_NOTENABLED,\n    MMSYSERR_ALLOCATED,\n    MMSYSERR_INVALHANDLE,\n    MMSYSERR_NODRIVER,\n    MMSYSERR_NOMEM,\n    MMSYSERR_NOTSUPPORTED,\n    MMSYSERR_BADERRNUM,\n    MMSYSERR_INVALFLAG,\n    MMSYSERR_INVALPARAM,\n    MMSYSERR_HANDLEBUSY,\n    MMSYSERR_INVALIDALIAS,\n    MMSYSERR_BADDB,\n    MMSYSERR_KEYNOTFOUND,\n    MMSYSERR_READERROR,\n    MMSYSERR_WRITEERROR,\n    MMSYSERR_DELETEERROR,\n    MMSYSERR_VALNOTFOUND,\n    MMSYSERR_NODRIVERCB, // = MMSYSERR_BASE+20\n    MMSYSERR_LASTERROR      = MMSYSERR_NODRIVERCB\n}\n\nenum {\n    DRV_LOAD = 1,\n    DRV_ENABLE,\n    DRV_OPEN,\n    DRV_CLOSE,\n    DRV_DISABLE,\n    DRV_FREE,\n    DRV_CONFIGURE,\n    DRV_QUERYCONFIGURE,\n    DRV_INSTALL,\n    DRV_REMOVE,\n    DRV_EXITSESSION,\n    DRV_POWER\n}\n\nenum DRV_RESERVED = 0x800;\nenum DRV_USER = 0x4000;\n\nenum DRVCNF_CANCEL = 0;\nenum DRVCNF_OK = 1;\nenum DRVCNF_RESTART = 2;\nenum DRV_CANCEL = DRVCNF_CANCEL;\nenum DRV_OK = DRVCNF_OK;\nenum DRV_RESTART = DRVCNF_RESTART;\nenum DRV_MCI_FIRST = DRV_RESERVED;\nenum DRV_MCI_LAST  = DRV_RESERVED + 0xFFF;\n\nenum CALLBACK_TYPEMASK = 0x70000;\nenum CALLBACK_NULL     = 0;\nenum CALLBACK_WINDOW   = 0x10000;\nenum CALLBACK_TASK     = 0x20000;\nenum CALLBACK_FUNCTION = 0x30000;\nenum CALLBACK_THREAD   = CALLBACK_TASK;\nenum CALLBACK_EVENT    = 0x50000;\n\nenum SND_SYNC=0;\nenum SND_ASYNC=1;\nenum SND_NODEFAULT=2;\nenum SND_MEMORY=4;\nenum SND_LOOP=8;\nenum SND_NOSTOP=16;\nenum SND_NOWAIT=0x2000;\nenum SND_ALIAS=0x10000;\nenum SND_ALIAS_ID=0x110000;\nenum SND_FILENAME=0x20000;\nenum SND_RESOURCE=0x40004;\nenum SND_PURGE=0x40;\nenum SND_APPLICATION=0x80;\nenum SND_ALIAS_START=0;\n\ntemplate sndAlias(char c0, char c1)\n{\nenum DWORD sndAlias = SND_ALIAS_START + c0 | (c1<<8);\n}\n\nenum SND_ALIAS_SYSTEMASTERISK    = sndAlias!('S', '*');\nenum SND_ALIAS_SYSTEMQUESTION    = sndAlias!('S', '?');\nenum SND_ALIAS_SYSTEMHAND        = sndAlias!('S', 'H');\nenum SND_ALIAS_SYSTEMEXIT        = sndAlias!('S', 'E');\nenum SND_ALIAS_SYSTEMSTART       = sndAlias!('S', 'S');\nenum SND_ALIAS_SYSTEMWELCOME     = sndAlias!('S', 'W');\nenum SND_ALIAS_SYSTEMEXCLAMATION = sndAlias!('S', '!');\nenum SND_ALIAS_SYSTEMDEFAULT     = sndAlias!('S', 'D');\n\nenum {\n    WAVERR_BADFORMAT  = (WAVERR_BASE + 0),\n    WAVERR_STILLPLAYING,\n    WAVERR_UNPREPARED,\n    WAVERR_SYNC,  // = WAVERR_BASE + 3;\n    WAVERR_LASTERROR = WAVERR_SYNC\n}\n\nenum WOM_OPEN  = MM_WOM_OPEN;\nenum WOM_CLOSE = MM_WOM_CLOSE;\nenum WOM_DONE  = MM_WOM_DONE;\nenum WIM_OPEN  = MM_WIM_OPEN;\nenum WIM_CLOSE = MM_WIM_CLOSE;\nenum WIM_DATA  = MM_WIM_DATA;\n\nenum UINT WAVE_MAPPER= -1;  // FIXME: This doesn't make sense!\nenum WAVE_FORMAT_QUERY=1;\nenum WAVE_ALLOWSYNC=2;\nenum WAVE_MAPPED=4;\nenum WAVE_FORMAT_DIRECT=8;\nenum WAVE_FORMAT_DIRECT_QUERY=(WAVE_FORMAT_QUERY|WAVE_FORMAT_DIRECT);\nenum WHDR_DONE=1;\nenum WHDR_PREPARED=2;\nenum WHDR_BEGINLOOP=4;\nenum WHDR_ENDLOOP=8;\nenum WHDR_INQUEUE=16;\n\nenum WAVECAPS_PITCH=1;\nenum WAVECAPS_PLAYBACKRATE=2;\nenum WAVECAPS_VOLUME=4;\nenum WAVECAPS_LRVOLUME=8;\nenum WAVECAPS_SYNC=16;\nenum WAVECAPS_SAMPLEACCURATE=32;\nenum WAVECAPS_DIRECTSOUND=64;\n\nenum WAVE_INVALIDFORMAT=0;\nenum WAVE_FORMAT_1M08=1;\nenum WAVE_FORMAT_1S08=2;\nenum WAVE_FORMAT_1M16=4;\nenum WAVE_FORMAT_1S16=8;\nenum WAVE_FORMAT_2M08=16;\nenum WAVE_FORMAT_2S08=32;\nenum WAVE_FORMAT_2M16=64;\nenum WAVE_FORMAT_2S16=128;\nenum WAVE_FORMAT_4M08=256;\nenum WAVE_FORMAT_4S08=512;\nenum WAVE_FORMAT_4M16=1024;\nenum WAVE_FORMAT_4S16=2048;\nenum WAVE_FORMAT_PCM=1;\n\nenum {\n    MIDIERR_UNPREPARED = MIDIERR_BASE,\n    MIDIERR_STILLPLAYING,\n    MIDIERR_NOMAP,\n    MIDIERR_NOTREADY,\n    MIDIERR_NODEVICE,\n    MIDIERR_INVALIDSETUP,\n    MIDIERR_BADOPENMODE,\n    MIDIERR_DONT_CONTINUE, // = MIDIERR_BASE+7\n    MIDIERR_LASTERROR = MIDIERR_DONT_CONTINUE\n}\n\nenum MIDIPATCHSIZE=128;\n\nenum MIM_OPEN=MM_MIM_OPEN;\nenum MIM_CLOSE=MM_MIM_CLOSE;\nenum MIM_DATA=MM_MIM_DATA;\nenum MIM_LONGDATA=MM_MIM_LONGDATA;\nenum MIM_ERROR=MM_MIM_ERROR;\nenum MIM_LONGERROR=MM_MIM_LONGERROR;\nenum MOM_OPEN=MM_MOM_OPEN;\nenum MOM_CLOSE=MM_MOM_CLOSE;\nenum MOM_DONE=MM_MOM_DONE;\nenum MIM_MOREDATA=MM_MIM_MOREDATA;\nenum MOM_POSITIONCB=MM_MOM_POSITIONCB;\n\nenum UINT MIDIMAPPER= -1; // FIXME: uint is nonsense for this!\nenum UINT MIDI_MAPPER= -1; // FIXME: uint is nonsense for this!\nenum MIDI_IO_STATUS=32;\nenum MIDI_CACHE_ALL=1;\nenum MIDI_CACHE_BESTFIT=2;\nenum MIDI_CACHE_QUERY=3;\nenum MIDI_UNCACHE=4;\nenum MOD_MIDIPORT=1;\nenum MOD_SYNTH=2;\nenum MOD_SQSYNTH=3;\nenum MOD_FMSYNTH=4;\nenum MOD_MAPPER=5;\nenum MIDICAPS_VOLUME=1;\nenum MIDICAPS_LRVOLUME=2;\nenum MIDICAPS_CACHE=4;\nenum MIDICAPS_STREAM=8;\nenum MHDR_DONE=1;\nenum MHDR_PREPARED=2;\nenum MHDR_INQUEUE=4;\nenum MHDR_ISSTRM=8;\nenum MEVT_F_SHORT=0;\nenum MEVT_F_LONG=0x80000000;\nenum MEVT_F_CALLBACK=0x40000000;\n\nBYTE MEVT_EVENTTYPE(DWORD x) { return cast(BYTE)((x>>24) &0xFF); }\nDWORD MEVT_EVENTPARM(DWORD x) { return x & 0xFFFFFF; }\n\nenum MEVT_SHORTMSG=0;\nenum MEVT_TEMPO=1;\nenum MEVT_NOP=2;\n\nenum BYTE MEVT_LONGMSG = 0x80;\nenum BYTE MEVT_COMMENT = 0x82;\nenum BYTE MEVT_VERSION = 0x84;\n\nenum MIDISTRM_ERROR = -2;\n\nenum MIDIPROP_SET = 0x80000000;\nenum MIDIPROP_GET = 0x40000000;\nenum MIDIPROP_TIMEDIV = 1;\nenum MIDIPROP_TEMPO = 2;\n\nenum UINT AUX_MAPPER = -1;\n\nenum AUXCAPS_CDAUDIO=1;\nenum AUXCAPS_AUXIN=2;\nenum AUXCAPS_VOLUME=1;\nenum AUXCAPS_LRVOLUME=2;\nenum MIXER_SHORT_NAME_CHARS=16;\nenum MIXER_LONG_NAME_CHARS=64;\nenum MIXERR_INVALLINE=MIXERR_BASE;\nenum MIXERR_INVALCONTROL=(MIXERR_BASE+1);\nenum MIXERR_INVALVALUE=(MIXERR_BASE+2);\nenum MIXERR_LASTERROR=(MIXERR_BASE+2);\n\nenum MIXER_OBJECTF_HANDLE=0x80000000;\nenum MIXER_OBJECTF_MIXER=0;\nenum MIXER_OBJECTF_HMIXER=(MIXER_OBJECTF_HANDLE|MIXER_OBJECTF_MIXER);\nenum MIXER_OBJECTF_WAVEOUT=0x10000000;\nenum MIXER_OBJECTF_HWAVEOUT=(MIXER_OBJECTF_HANDLE|MIXER_OBJECTF_WAVEOUT);\nenum MIXER_OBJECTF_WAVEIN=0x20000000;\nenum MIXER_OBJECTF_HWAVEIN=(MIXER_OBJECTF_HANDLE|MIXER_OBJECTF_WAVEIN);\nenum MIXER_OBJECTF_MIDIOUT=0x30000000;\nenum MIXER_OBJECTF_HMIDIOUT=(MIXER_OBJECTF_HANDLE|MIXER_OBJECTF_MIDIOUT);\nenum MIXER_OBJECTF_MIDIIN=0x40000000;\nenum MIXER_OBJECTF_HMIDIIN=(MIXER_OBJECTF_HANDLE|MIXER_OBJECTF_MIDIIN);\nenum MIXER_OBJECTF_AUX=0x50000000;\n\nenum MIXERLINE_LINEF_ACTIVE=1;\nenum MIXERLINE_LINEF_DISCONNECTED=0x8000;\nenum MIXERLINE_LINEF_SOURCE=0x80000000;\n\nenum MIXERLINE_COMPONENTTYPE_DST_FIRST=0;\nenum MIXERLINE_COMPONENTTYPE_DST_UNDEFINED=MIXERLINE_COMPONENTTYPE_DST_FIRST;\nenum MIXERLINE_COMPONENTTYPE_DST_DIGITAL=(MIXERLINE_COMPONENTTYPE_DST_FIRST+1);\nenum MIXERLINE_COMPONENTTYPE_DST_LINE=(MIXERLINE_COMPONENTTYPE_DST_FIRST+2);\nenum MIXERLINE_COMPONENTTYPE_DST_MONITOR=(MIXERLINE_COMPONENTTYPE_DST_FIRST+3);\nenum MIXERLINE_COMPONENTTYPE_DST_SPEAKERS=(MIXERLINE_COMPONENTTYPE_DST_FIRST+4);\nenum MIXERLINE_COMPONENTTYPE_DST_HEADPHONES=(MIXERLINE_COMPONENTTYPE_DST_FIRST+5);\nenum MIXERLINE_COMPONENTTYPE_DST_TELEPHONE=(MIXERLINE_COMPONENTTYPE_DST_FIRST+6);\nenum MIXERLINE_COMPONENTTYPE_DST_WAVEIN=(MIXERLINE_COMPONENTTYPE_DST_FIRST+7);\nenum MIXERLINE_COMPONENTTYPE_DST_VOICEIN=(MIXERLINE_COMPONENTTYPE_DST_FIRST+8);\nenum MIXERLINE_COMPONENTTYPE_DST_LAST=(MIXERLINE_COMPONENTTYPE_DST_FIRST+8);\nenum MIXERLINE_COMPONENTTYPE_SRC_FIRST=0x1000;\nenum MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED=MIXERLINE_COMPONENTTYPE_SRC_FIRST;\nenum MIXERLINE_COMPONENTTYPE_SRC_DIGITAL=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+1);\nenum MIXERLINE_COMPONENTTYPE_SRC_LINE=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+2);\nenum MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+3);\nenum MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+4);\nenum MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+5);\nenum MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+6);\nenum MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+7);\nenum MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+8);\nenum MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+9);\nenum MIXERLINE_COMPONENTTYPE_SRC_ANALOG=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+10);\nenum MIXERLINE_COMPONENTTYPE_SRC_LAST=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+10);\n\nenum {\n    MIXERLINE_TARGETTYPE_UNDEFINED = 0,\n    MIXERLINE_TARGETTYPE_WAVEOUT,\n    MIXERLINE_TARGETTYPE_WAVEIN,\n    MIXERLINE_TARGETTYPE_MIDIOUT,\n    MIXERLINE_TARGETTYPE_MIDIIN,\n    MIXERLINE_TARGETTYPE_AUX // =5\n}\n\nenum MIXER_GETLINEINFOF_DESTINATION=0;\nenum MIXER_GETLINEINFOF_SOURCE=1;\nenum MIXER_GETLINEINFOF_LINEID=2;\nenum MIXER_GETLINEINFOF_COMPONENTTYPE=3;\nenum MIXER_GETLINEINFOF_TARGETTYPE=4;\nenum MIXER_GETLINEINFOF_QUERYMASK=15;\n\nenum MIXERCONTROL_CONTROLF_UNIFORM=1;\nenum MIXERCONTROL_CONTROLF_MULTIPLE=2;\nenum MIXERCONTROL_CONTROLF_DISABLED=0x80000000;\nenum MIXERCONTROL_CT_CLASS_MASK=0xF0000000;\nenum MIXERCONTROL_CT_CLASS_CUSTOM=0;\nenum MIXERCONTROL_CT_CLASS_METER=0x10000000;\nenum MIXERCONTROL_CT_CLASS_SWITCH=0x20000000;\nenum MIXERCONTROL_CT_CLASS_NUMBER=0x30000000;\nenum MIXERCONTROL_CT_CLASS_SLIDER=0x40000000;\nenum MIXERCONTROL_CT_CLASS_FADER=0x50000000;\nenum MIXERCONTROL_CT_CLASS_TIME=0x60000000;\nenum MIXERCONTROL_CT_CLASS_LIST=0x70000000;\nenum MIXERCONTROL_CT_SUBCLASS_MASK=0xF000000;\nenum MIXERCONTROL_CT_SC_SWITCH_BOOLEAN=0;\nenum MIXERCONTROL_CT_SC_SWITCH_BUTTON=0x1000000;\nenum MIXERCONTROL_CT_SC_METER_POLLED=0;\nenum MIXERCONTROL_CT_SC_TIME_MICROSECS=0;\nenum MIXERCONTROL_CT_SC_TIME_MILLISECS=0x1000000;\nenum MIXERCONTROL_CT_SC_LIST_SINGLE=0;\nenum MIXERCONTROL_CT_SC_LIST_MULTIPLE=0x1000000;\nenum MIXERCONTROL_CT_UNITS_MASK=0xFF0000;\nenum MIXERCONTROL_CT_UNITS_CUSTOM=0;\nenum MIXERCONTROL_CT_UNITS_BOOLEAN=0x10000;\nenum MIXERCONTROL_CT_UNITS_SIGNED=0x20000;\nenum MIXERCONTROL_CT_UNITS_UNSIGNED=0x30000;\nenum MIXERCONTROL_CT_UNITS_DECIBELS=0x40000;\nenum MIXERCONTROL_CT_UNITS_PERCENT=0x50000;\n\nenum MIXERCONTROL_CONTROLTYPE_CUSTOM=(MIXERCONTROL_CT_CLASS_CUSTOM|MIXERCONTROL_CT_UNITS_CUSTOM);\nenum MIXERCONTROL_CONTROLTYPE_BOOLEANMETER=(MIXERCONTROL_CT_CLASS_METER|MIXERCONTROL_CT_SC_METER_POLLED|MIXERCONTROL_CT_UNITS_BOOLEAN);\nenum MIXERCONTROL_CONTROLTYPE_SIGNEDMETER=(MIXERCONTROL_CT_CLASS_METER|MIXERCONTROL_CT_SC_METER_POLLED|MIXERCONTROL_CT_UNITS_SIGNED);\nenum MIXERCONTROL_CONTROLTYPE_PEAKMETER=(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER+1);\nenum MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER=(MIXERCONTROL_CT_CLASS_METER|MIXERCONTROL_CT_SC_METER_POLLED|MIXERCONTROL_CT_UNITS_UNSIGNED);\nenum MIXERCONTROL_CONTROLTYPE_BOOLEAN=(MIXERCONTROL_CT_CLASS_SWITCH|MIXERCONTROL_CT_SC_SWITCH_BOOLEAN|MIXERCONTROL_CT_UNITS_BOOLEAN);\nenum MIXERCONTROL_CONTROLTYPE_ONOFF=(MIXERCONTROL_CONTROLTYPE_BOOLEAN+1);\nenum MIXERCONTROL_CONTROLTYPE_MUTE=(MIXERCONTROL_CONTROLTYPE_BOOLEAN+2);\nenum MIXERCONTROL_CONTROLTYPE_MONO=(MIXERCONTROL_CONTROLTYPE_BOOLEAN+3);\nenum MIXERCONTROL_CONTROLTYPE_LOUDNESS=(MIXERCONTROL_CONTROLTYPE_BOOLEAN+4);\nenum MIXERCONTROL_CONTROLTYPE_STEREOENH=(MIXERCONTROL_CONTROLTYPE_BOOLEAN+5);\nenum MIXERCONTROL_CONTROLTYPE_BUTTON=(MIXERCONTROL_CT_CLASS_SWITCH|MIXERCONTROL_CT_SC_SWITCH_BUTTON|MIXERCONTROL_CT_UNITS_BOOLEAN);\nenum MIXERCONTROL_CONTROLTYPE_DECIBELS=(MIXERCONTROL_CT_CLASS_NUMBER|MIXERCONTROL_CT_UNITS_DECIBELS);\nenum MIXERCONTROL_CONTROLTYPE_SIGNED=(MIXERCONTROL_CT_CLASS_NUMBER|MIXERCONTROL_CT_UNITS_SIGNED);\nenum MIXERCONTROL_CONTROLTYPE_UNSIGNED=(MIXERCONTROL_CT_CLASS_NUMBER|MIXERCONTROL_CT_UNITS_UNSIGNED);\nenum MIXERCONTROL_CONTROLTYPE_PERCENT=(MIXERCONTROL_CT_CLASS_NUMBER|MIXERCONTROL_CT_UNITS_PERCENT);\nenum MIXERCONTROL_CONTROLTYPE_SLIDER=(MIXERCONTROL_CT_CLASS_SLIDER|MIXERCONTROL_CT_UNITS_SIGNED);\nenum MIXERCONTROL_CONTROLTYPE_PAN=(MIXERCONTROL_CONTROLTYPE_SLIDER+1);\nenum MIXERCONTROL_CONTROLTYPE_QSOUNDPAN=(MIXERCONTROL_CONTROLTYPE_SLIDER+2);\nenum MIXERCONTROL_CONTROLTYPE_FADER=(MIXERCONTROL_CT_CLASS_FADER|MIXERCONTROL_CT_UNITS_UNSIGNED);\nenum MIXERCONTROL_CONTROLTYPE_VOLUME=(MIXERCONTROL_CONTROLTYPE_FADER+1);\nenum MIXERCONTROL_CONTROLTYPE_BASS=(MIXERCONTROL_CONTROLTYPE_FADER+2);\nenum MIXERCONTROL_CONTROLTYPE_TREBLE=(MIXERCONTROL_CONTROLTYPE_FADER+3);\nenum MIXERCONTROL_CONTROLTYPE_EQUALIZER=(MIXERCONTROL_CONTROLTYPE_FADER+4);\nenum MIXERCONTROL_CONTROLTYPE_SINGLESELECT=(MIXERCONTROL_CT_CLASS_LIST|MIXERCONTROL_CT_SC_LIST_SINGLE|MIXERCONTROL_CT_UNITS_BOOLEAN);\nenum MIXERCONTROL_CONTROLTYPE_MUX=(MIXERCONTROL_CONTROLTYPE_SINGLESELECT+1);\nenum MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT=(MIXERCONTROL_CT_CLASS_LIST|MIXERCONTROL_CT_SC_LIST_MULTIPLE|MIXERCONTROL_CT_UNITS_BOOLEAN);\nenum MIXERCONTROL_CONTROLTYPE_MIXER=(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT+1);\nenum MIXERCONTROL_CONTROLTYPE_MICROTIME=(MIXERCONTROL_CT_CLASS_TIME|MIXERCONTROL_CT_SC_TIME_MICROSECS|MIXERCONTROL_CT_UNITS_UNSIGNED);\nenum MIXERCONTROL_CONTROLTYPE_MILLITIME=(MIXERCONTROL_CT_CLASS_TIME|MIXERCONTROL_CT_SC_TIME_MILLISECS|MIXERCONTROL_CT_UNITS_UNSIGNED);\n\nenum MIXER_GETLINECONTROLSF_ALL=0;\nenum MIXER_GETLINECONTROLSF_ONEBYID=1;\nenum MIXER_GETLINECONTROLSF_ONEBYTYPE=2;\nenum MIXER_GETLINECONTROLSF_QUERYMASK=15;\nenum MIXER_GETCONTROLDETAILSF_VALUE=0;\nenum MIXER_GETCONTROLDETAILSF_LISTTEXT=1;\nenum MIXER_GETCONTROLDETAILSF_QUERYMASK=15;\nenum MIXER_SETCONTROLDETAILSF_VALUE=0;\nenum MIXER_SETCONTROLDETAILSF_CUSTOM=1;\nenum MIXER_SETCONTROLDETAILSF_QUERYMASK=15;\n\nenum TIMERR_NOERROR=0;\nenum TIMERR_NOCANDO=(TIMERR_BASE+1);\nenum TIMERR_STRUCT=(TIMERR_BASE+33);\nenum TIME_ONESHOT=0;\nenum TIME_PERIODIC=1;\nenum TIME_CALLBACK_FUNCTION=0;\nenum TIME_CALLBACK_EVENT_SET=16;\nenum TIME_CALLBACK_EVENT_PULSE=32;\n\nstatic if (_WIN32_WINNT >= 0x501) {\n\nenum TIME_KILL_SYNCHRONOUS=0x0100;\n\n}\n\nenum JOYERR_NOERROR = 0;\nenum JOYERR_PARMS=(JOYERR_BASE+5);\nenum JOYERR_NOCANDO=(JOYERR_BASE+6);\nenum JOYERR_UNPLUGGED=(JOYERR_BASE+7);\n\nenum JOY_BUTTON1=1;\nenum JOY_BUTTON2=2;\nenum JOY_BUTTON3=4;\nenum JOY_BUTTON4=8;\nenum JOY_BUTTON1CHG=256;\nenum JOY_BUTTON2CHG=512;\nenum JOY_BUTTON3CHG=1024;\nenum JOY_BUTTON4CHG=2048;\nenum JOY_BUTTON5=257;\nenum JOY_BUTTON6=513;\nenum JOY_BUTTON7=1025;\nenum JOY_BUTTON8=2049;\nenum JOY_BUTTON9=256;\nenum JOY_BUTTON10=512;\nenum JOY_BUTTON11=1024;\nenum JOY_BUTTON12=2048;\nenum JOY_BUTTON13=4096;\nenum JOY_BUTTON14=8192;\nenum JOY_BUTTON15=16384;\nenum JOY_BUTTON16=32768;\nenum JOY_BUTTON17=65536;\nenum JOY_BUTTON18=0x20000;\nenum JOY_BUTTON19=0x40000;\nenum JOY_BUTTON20=0x80000;\nenum JOY_BUTTON21=0x100000;\nenum JOY_BUTTON22=0x200000;\nenum JOY_BUTTON23=0x400000;\nenum JOY_BUTTON24=0x800000;\nenum JOY_BUTTON25=0x1000000;\nenum JOY_BUTTON26=0x2000000;\nenum JOY_BUTTON27=0x4000000;\nenum JOY_BUTTON28=0x8000000;\nenum JOY_BUTTON29=0x10000000;\nenum JOY_BUTTON30=0x20000000;\nenum JOY_BUTTON31=0x40000000;\nenum JOY_BUTTON32=0x80000000;\n\nenum  : DWORD {\n    JOY_POVCENTERED = -1,\n    JOY_POVFORWARD  = 0,\n    JOY_POVBACKWARD = 18000,\n    JOY_POVLEFT     = 27000,\n    JOY_POVRIGHT    = 9000\n}\n\nenum DWORD\n    JOY_RETURNX        = 0x00000001,\n    JOY_RETURNY        = 0x00000002,\n    JOY_RETURNZ        = 0x00000004,\n    JOY_RETURNR        = 0x00000008,\n    JOY_RETURNU        = 0x00000010,\n    JOY_RETURNV        = 0x00000020,\n    JOY_RETURNPOV      = 0x00000040,\n    JOY_RETURNBUTTONS  = 0x00000080,\n    JOY_RETURNRAWDATA  = 0x00000100,\n    JOY_RETURNPOVCTS   = 0x00000200,\n    JOY_RETURNCENTERED = 0x00000400,\n    JOY_USEDEADZONE    = 0x00000800,\n    JOY_RETURNALL      = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNR\n                         | JOY_RETURNU | JOY_RETURNV | JOY_RETURNPOV\n                         | JOY_RETURNBUTTONS,\n    JOY_CAL_READALWAYS = 0x00010000,\n    JOY_CAL_READXYONLY = 0x00020000,\n    JOY_CAL_READ3      = 0x00040000,\n    JOY_CAL_READ4      = 0x00080000,\n    JOY_CAL_READXONLY  = 0x00100000,\n    JOY_CAL_READYONLY  = 0x00200000,\n    JOY_CAL_READ5      = 0x00400000,\n    JOY_CAL_READ6      = 0x00800000,\n    JOY_CAL_READZONLY  = 0x01000000,\n    JOY_CAL_READRONLY  = 0x02000000,\n    JOY_CAL_READUONLY  = 0x04000000,\n    JOY_CAL_READVONLY  = 0x08000000;\n\nenum JOYSTICKID1=0;\nenum JOYSTICKID2=1;\n\nenum JOYCAPS_HASZ=1;\nenum JOYCAPS_HASR=2;\nenum JOYCAPS_HASU=4;\nenum JOYCAPS_HASV=8;\nenum JOYCAPS_HASPOV=16;\nenum JOYCAPS_POV4DIR=32;\nenum JOYCAPS_POVCTS=64;\n\nenum MMIOERR_BASE=256;\nenum MMIOERR_FILENOTFOUND=(MMIOERR_BASE+1);\nenum MMIOERR_OUTOFMEMORY=(MMIOERR_BASE+2);\nenum MMIOERR_CANNOTOPEN=(MMIOERR_BASE+3);\nenum MMIOERR_CANNOTCLOSE=(MMIOERR_BASE+4);\nenum MMIOERR_CANNOTREAD=(MMIOERR_BASE+5);\nenum MMIOERR_CANNOTWRITE=(MMIOERR_BASE+6);\nenum MMIOERR_CANNOTSEEK=(MMIOERR_BASE+7);\nenum MMIOERR_CANNOTEXPAND=(MMIOERR_BASE+8);\nenum MMIOERR_CHUNKNOTFOUND=(MMIOERR_BASE+9);\nenum MMIOERR_UNBUFFERED=(MMIOERR_BASE+10);\nenum MMIOERR_PATHNOTFOUND=(MMIOERR_BASE+11);\nenum MMIOERR_ACCESSDENIED=(MMIOERR_BASE+12);\nenum MMIOERR_SHARINGVIOLATION=(MMIOERR_BASE+13);\nenum MMIOERR_NETWORKERROR=(MMIOERR_BASE+14);\nenum MMIOERR_TOOMANYOPENFILES=(MMIOERR_BASE+15);\nenum MMIOERR_INVALIDFILE=(MMIOERR_BASE+16);\n\nenum CFSEPCHAR='+';\n\nenum MMIO_RWMODE=3;\nenum MMIO_SHAREMODE=0x70;\nenum MMIO_CREATE=0x1000;\nenum MMIO_PARSE=256;\nenum MMIO_DELETE=512;\nenum MMIO_EXIST=0x4000;\nenum MMIO_ALLOCBUF=0x10000;\nenum MMIO_GETTEMP=0x20000;\nenum MMIO_DIRTY=0x10000000;\nenum MMIO_READ=0;\nenum MMIO_WRITE=1;\nenum MMIO_READWRITE=2;\nenum MMIO_COMPAT=0;\nenum MMIO_EXCLUSIVE=16;\nenum MMIO_DENYWRITE=32;\nenum MMIO_DENYREAD=0x30;\nenum MMIO_DENYNONE=64;\nenum MMIO_FHOPEN=16;\nenum MMIO_EMPTYBUF=16;\nenum MMIO_TOUPPER=16;\nenum MMIO_INSTALLPROC=0x10000;\nenum MMIO_GLOBALPROC=0x10000000;\nenum MMIO_REMOVEPROC=0x20000;\nenum MMIO_UNICODEPROC=0x1000000;\nenum MMIO_FINDPROC=0x40000;\nenum MMIO_FINDCHUNK=16;\nenum MMIO_FINDRIFF=32;\nenum MMIO_FINDLIST=64;\nenum MMIO_CREATERIFF=32;\nenum MMIO_CREATELIST=64;\nenum MMIOM_READ=MMIO_READ;\nenum MMIOM_WRITE=MMIO_WRITE;\nenum MMIOM_SEEK=2;\nenum MMIOM_OPEN=3;\nenum MMIOM_CLOSE=4;\nenum MMIOM_WRITEFLUSH=5;\nenum MMIOM_RENAME=6;\nenum MMIOM_USER=0x8000;\n\nenum FOURCC_RIFF = mmioFOURCC!('R', 'I', 'F', 'F');\nenum FOURCC_LIST = mmioFOURCC!('L', 'I', 'S', 'T');\nenum FOURCC_DOS  = mmioFOURCC!('D', 'O', 'S', ' ');\nenum FOURCC_MEM  = mmioFOURCC!('M', 'E', 'M', ' ');\n\nenum MMIO_DEFAULTBUFFER=8192;\n\nenum {\n    MCIERR_INVALID_DEVICE_ID = MCIERR_BASE + 1,\n    MCIERR_UNRECOGNIZED_KEYWORD = MCIERR_BASE + 3,\n    MCIERR_UNRECOGNIZED_COMMAND = MCIERR_BASE + 5,\n    MCIERR_HARDWARE,\n    MCIERR_INVALID_DEVICE_NAME,\n    MCIERR_OUT_OF_MEMORY,\n    MCIERR_DEVICE_OPEN,\n    MCIERR_CANNOT_LOAD_DRIVER,\n    MCIERR_MISSING_COMMAND_STRING,\n    MCIERR_PARAM_OVERFLOW,\n    MCIERR_MISSING_STRING_ARGUMENT,\n    MCIERR_BAD_INTEGER,\n    MCIERR_PARSER_INTERNAL,\n    MCIERR_DRIVER_INTERNAL,\n    MCIERR_MISSING_PARAMETER,\n    MCIERR_UNSUPPORTED_FUNCTION,\n    MCIERR_FILE_NOT_FOUND,\n    MCIERR_DEVICE_NOT_READY,\n    MCIERR_INTERNAL,\n    MCIERR_DRIVER,\n    MCIERR_CANNOT_USE_ALL,\n    MCIERR_MULTIPLE,\n    MCIERR_EXTENSION_NOT_FOUND,\n    MCIERR_OUTOFRANGE, // = MCIERR_BASE+26\n    MCIERR_FLAGS_NOT_COMPATIBLE = MCIERR_BASE + 28,\n    MCIERR_FILE_NOT_SAVED = MCIERR_BASE + 30,\n    MCIERR_DEVICE_TYPE_REQUIRED,\n    MCIERR_DEVICE_LOCKED,\n    MCIERR_DUPLICATE_ALIAS,\n    MCIERR_BAD_CONSTANT,\n    MCIERR_MUST_USE_SHAREABLE,\n    MCIERR_MISSING_DEVICE_NAME,\n    MCIERR_BAD_TIME_FORMAT,\n    MCIERR_NO_CLOSING_QUOTE,\n    MCIERR_DUPLICATE_FLAGS,\n    MCIERR_INVALID_FILE,\n    MCIERR_NULL_PARAMETER_BLOCK,\n    MCIERR_UNNAMED_RESOURCE,\n    MCIERR_NEW_REQUIRES_ALIAS,\n    MCIERR_NOTIFY_ON_AUTO_OPEN,\n    MCIERR_NO_ELEMENT_ALLOWED,\n    MCIERR_NONAPPLICABLE_FUNCTION,\n    MCIERR_ILLEGAL_FOR_AUTO_OPEN,\n    MCIERR_FILENAME_REQUIRED,\n    MCIERR_EXTRA_CHARACTERS,\n    MCIERR_DEVICE_NOT_INSTALLED,\n    MCIERR_GET_CD,\n    MCIERR_SET_CD,\n    MCIERR_SET_DRIVE,\n    MCIERR_DEVICE_LENGTH,\n    MCIERR_DEVICE_ORD_LENGTH,\n    MCIERR_NO_INTEGER, // = MCIERR_BASE + 56\n    MCIERR_WAVE_OUTPUTSINUSE = MCIERR_BASE + 64,\n    MCIERR_WAVE_SETOUTPUTINUSE,\n    MCIERR_WAVE_INPUTSINUSE,\n    MCIERR_WAVE_SETINPUTINUSE,\n    MCIERR_WAVE_OUTPUTUNSPECIFIED,\n    MCIERR_WAVE_INPUTUNSPECIFIED,\n    MCIERR_WAVE_OUTPUTSUNSUITABLE,\n    MCIERR_WAVE_SETOUTPUTUNSUITABLE,\n    MCIERR_WAVE_INPUTSUNSUITABLE,\n    MCIERR_WAVE_SETINPUTUNSUITABLE, // = MCIERR_BASE + 73\n    MCIERR_SEQ_DIV_INCOMPATIBLE = MCIERR_BASE + 80,\n    MCIERR_SEQ_PORT_INUSE,\n    MCIERR_SEQ_PORT_NONEXISTENT,\n    MCIERR_SEQ_PORT_MAPNODEVICE,\n    MCIERR_SEQ_PORT_MISCERROR,\n    MCIERR_SEQ_TIMER,\n    MCIERR_SEQ_PORTUNSPECIFIED,\n    MCIERR_SEQ_NOMIDIPRESENT, // = MCIERR_BASE + 87\n    MCIERR_NO_WINDOW = MCIERR_BASE + 90,\n    MCIERR_CREATEWINDOW,\n    MCIERR_FILE_READ,\n    MCIERR_FILE_WRITE,\n    MCIERR_NO_IDENTITY // = MCIERR_BASE + 94\n}\nenum MCIERR_CUSTOM_DRIVER_BASE = MCIERR_BASE + 256;\n\nenum MCI_FIRST=DRV_MCI_FIRST;\nenum MCI_OPEN=0x803;\nenum MCI_CLOSE=0x804;\nenum MCI_ESCAPE=0x805;\nenum MCI_PLAY=0x806;\nenum MCI_SEEK=0x807;\nenum MCI_STOP=0x808;\nenum MCI_PAUSE=0x809;\nenum MCI_INFO=0x80A;\nenum MCI_GETDEVCAPS=0x80B;\nenum MCI_SPIN=0x80C;\nenum MCI_SET=0x80D;\nenum MCI_STEP=0x80E;\nenum MCI_RECORD=0x80F;\nenum MCI_SYSINFO=0x810;\nenum MCI_BREAK=0x811;\nenum MCI_SAVE=0x813;\nenum MCI_STATUS=0x814;\nenum MCI_CUE=0x830;\nenum MCI_REALIZE=0x840;\nenum MCI_WINDOW=0x841;\nenum MCI_PUT=0x842;\nenum MCI_WHERE=0x843;\nenum MCI_FREEZE=0x844;\nenum MCI_UNFREEZE=0x845;\nenum MCI_LOAD=0x850;\nenum MCI_CUT=0x851;\nenum MCI_COPY=0x852;\nenum MCI_PASTE=0x853;\nenum MCI_UPDATE=0x854;\nenum MCI_RESUME=0x855;\nenum MCI_DELETE=0x856;\nenum MCI_USER_MESSAGES=(DRV_MCI_FIRST+0x400);\nenum MCI_LAST=0xFFF;\n\nenum MCIDEVICEID MCI_ALL_DEVICE_ID = -1;\n\nenum MCI_DEVTYPE_VCR=513;\nenum MCI_DEVTYPE_VIDEODISC=514;\nenum MCI_DEVTYPE_OVERLAY=515;\nenum MCI_DEVTYPE_CD_AUDIO=516;\nenum MCI_DEVTYPE_DAT=517;\nenum MCI_DEVTYPE_SCANNER=518;\nenum MCI_DEVTYPE_ANIMATION=519;\nenum MCI_DEVTYPE_DIGITAL_VIDEO=520;\nenum MCI_DEVTYPE_OTHER=521;\nenum MCI_DEVTYPE_WAVEFORM_AUDIO=522;\nenum MCI_DEVTYPE_SEQUENCER=523;\nenum MCI_DEVTYPE_FIRST=MCI_DEVTYPE_VCR;\nenum MCI_DEVTYPE_LAST=MCI_DEVTYPE_SEQUENCER;\nenum MCI_DEVTYPE_FIRST_USER=0x1000;\nenum MCI_MODE_NOT_READY=(MCI_STRING_OFFSET+12);\nenum MCI_MODE_STOP=(MCI_STRING_OFFSET+13);\nenum MCI_MODE_PLAY=(MCI_STRING_OFFSET+14);\nenum MCI_MODE_RECORD=(MCI_STRING_OFFSET+15);\nenum MCI_MODE_SEEK=(MCI_STRING_OFFSET+16);\nenum MCI_MODE_PAUSE=(MCI_STRING_OFFSET+17);\nenum MCI_MODE_OPEN=(MCI_STRING_OFFSET+18);\nenum MCI_FORMAT_MILLISECONDS=0;\nenum MCI_FORMAT_HMS=1;\nenum MCI_FORMAT_MSF=2;\nenum MCI_FORMAT_FRAMES=3;\nenum MCI_FORMAT_SMPTE_24=4;\nenum MCI_FORMAT_SMPTE_25=5;\nenum MCI_FORMAT_SMPTE_30=6;\nenum MCI_FORMAT_SMPTE_30DROP=7;\nenum MCI_FORMAT_BYTES=8;\nenum MCI_FORMAT_SAMPLES=9;\nenum MCI_FORMAT_TMSF=10;\n\n\n\n\n// Macros\nBYTE MCI_HMS_HOUR(DWORD t) { return cast(BYTE)(t); }\nBYTE MCI_HMS_MINUTE(DWORD t) { return cast(BYTE)(t>>>8); }\nBYTE MCI_HMS_SECOND(DWORD t) { return cast(BYTE)( t>>>16); }\nDWORD MCI_MAKE_HMS(BYTE h, BYTE m, BYTE s) { return h |(m<<8)|(cast(DWORD)(s)<<16); }\nDWORD MCI_MAKE_MSF(BYTE m, BYTE s, BYTE f) { return m |(s<<8)|(cast(DWORD)(f)<<16); }\nDWORD MCI_MAKE_TMSF(BYTE t, BYTE m, BYTE s, BYTE f) {\n return t |(m<<8)|(s<<16)|(cast(DWORD)(f)<< 24); }\n\nBYTE MCI_MSF_MINUTE(DWORD t) { return cast(BYTE)(t); }\nBYTE MCI_MSF_SECOND(DWORD t) { return cast(BYTE)(t >>> 8); }\nBYTE MCI_MSF_FRAME(DWORD t)  {  return cast(BYTE)(t >>> 16); }\n\nBYTE MCI_TMSF_TRACK(DWORD t)  { return cast(BYTE)(t); }\nBYTE MCI_TMSF_MINUTE(DWORD t) { return cast(BYTE)(t>>8); }\nBYTE MCI_TMSF_SECOND(DWORD t) { return cast(BYTE)(t>>16); }\nBYTE MCI_TMSF_FRAME(DWORD t)  { return cast(BYTE)(t>>24); }\n\n\nenum MCI_NOTIFY_SUCCESSFUL=1;\nenum MCI_NOTIFY_SUPERSEDED=2;\nenum MCI_NOTIFY_ABORTED=4;\nenum MCI_NOTIFY_FAILURE=8;\nenum MCI_NOTIFY=1;\nenum MCI_WAIT=2;\nenum MCI_FROM=4;\nenum MCI_TO=8;\nenum MCI_TRACK=16;\nenum MCI_OPEN_SHAREABLE=256;\nenum MCI_OPEN_ELEMENT=512;\nenum MCI_OPEN_ALIAS=1024;\nenum MCI_OPEN_ELEMENT_ID=2048;\nenum MCI_OPEN_TYPE_ID=0x1000;\nenum MCI_OPEN_TYPE=0x2000;\nenum MCI_SEEK_TO_START=256;\nenum MCI_SEEK_TO_END=512;\nenum MCI_STATUS_ITEM=256;\nenum MCI_STATUS_START=512;\nenum MCI_STATUS_LENGTH=1;\nenum MCI_STATUS_POSITION=2;\nenum MCI_STATUS_NUMBER_OF_TRACKS=3;\nenum MCI_STATUS_MODE=4;\nenum MCI_STATUS_MEDIA_PRESENT=5;\nenum MCI_STATUS_TIME_FORMAT=6;\nenum MCI_STATUS_READY=7;\nenum MCI_STATUS_CURRENT_TRACK=8;\nenum MCI_INFO_PRODUCT=256;\nenum MCI_INFO_FILE=512;\nenum MCI_INFO_MEDIA_UPC=1024;\nenum MCI_INFO_MEDIA_IDENTITY=2048;\nenum MCI_INFO_NAME=0x1000;\nenum MCI_INFO_COPYRIGHT=0x2000;\n\nenum MCI_GETDEVCAPS_ITEM=256;\nenum MCI_GETDEVCAPS_CAN_RECORD=1;\nenum MCI_GETDEVCAPS_HAS_AUDIO=2;\nenum MCI_GETDEVCAPS_HAS_VIDEO=3;\nenum MCI_GETDEVCAPS_DEVICE_TYPE=4;\nenum MCI_GETDEVCAPS_USES_FILES=5;\nenum MCI_GETDEVCAPS_COMPOUND_DEVICE=6;\nenum MCI_GETDEVCAPS_CAN_EJECT=7;\nenum MCI_GETDEVCAPS_CAN_PLAY=8;\nenum MCI_GETDEVCAPS_CAN_SAVE=9;\n\nenum MCI_SYSINFO_QUANTITY=256;\nenum MCI_SYSINFO_OPEN=512;\nenum MCI_SYSINFO_NAME=1024;\nenum MCI_SYSINFO_INSTALLNAME=2048;\nenum MCI_SET_DOOR_OPEN=256;\nenum MCI_SET_DOOR_CLOSED=512;\nenum MCI_SET_TIME_FORMAT=1024;\nenum MCI_SET_AUDIO=2048;\nenum MCI_SET_VIDEO=0x1000;\nenum MCI_SET_ON=0x2000;\nenum MCI_SET_OFF=0x4000;\n\nenum MCI_SET_AUDIO_ALL=0;\nenum MCI_SET_AUDIO_LEFT=1;\nenum MCI_SET_AUDIO_RIGHT=2;\n\nenum MCI_BREAK_KEY=256;\nenum MCI_BREAK_HWND=512;\nenum MCI_BREAK_OFF=1024;\n\nenum MCI_RECORD_INSERT=256;\nenum MCI_RECORD_OVERWRITE=512;\nenum MCI_SAVE_FILE=256;\nenum MCI_LOAD_FILE=256;\n\nenum MCI_VD_MODE_PARK=(MCI_VD_OFFSET+1);\nenum MCI_VD_MEDIA_CLV=(MCI_VD_OFFSET+2);\nenum MCI_VD_MEDIA_CAV=(MCI_VD_OFFSET+3);\nenum MCI_VD_MEDIA_OTHER=(MCI_VD_OFFSET+4);\n\nenum MCI_VD_FORMAT_TRACK=0x4001;\nenum MCI_VD_PLAY_REVERSE=0x10000;\nenum MCI_VD_PLAY_FAST=0x20000;\nenum MCI_VD_PLAY_SPEED=0x40000;\nenum MCI_VD_PLAY_SCAN=0x80000;\nenum MCI_VD_PLAY_SLOW=0x100000;\nenum MCI_VD_SEEK_REVERSE=0x10000;\nenum MCI_VD_STATUS_SPEED=0x4002;\nenum MCI_VD_STATUS_FORWARD=0x4003;\nenum MCI_VD_STATUS_MEDIA_TYPE=0x4004;\nenum MCI_VD_STATUS_SIDE=0x4005;\nenum MCI_VD_STATUS_DISC_SIZE=0x4006;\nenum MCI_VD_GETDEVCAPS_CLV=0x10000;\nenum MCI_VD_GETDEVCAPS_CAV=0x20000;\nenum MCI_VD_SPIN_UP=0x10000;\nenum MCI_VD_SPIN_DOWN=0x20000;\nenum MCI_VD_GETDEVCAPS_CAN_REVERSE=0x4002;\nenum MCI_VD_GETDEVCAPS_FAST_RATE=0x4003;\nenum MCI_VD_GETDEVCAPS_SLOW_RATE=0x4004;\nenum MCI_VD_GETDEVCAPS_NORMAL_RATE=0x4005;\nenum MCI_VD_STEP_FRAMES=0x10000;\nenum MCI_VD_STEP_REVERSE=0x20000;\nenum MCI_VD_ESCAPE_STRING=256;\n\nenum MCI_CDA_STATUS_TYPE_TRACK=0x4001;\nenum MCI_CDA_TRACK_AUDIO=MCI_CD_OFFSET;\nenum MCI_CDA_TRACK_OTHER=(MCI_CD_OFFSET+1);\n\nenum MCI_WAVE_PCM=MCI_WAVE_OFFSET;\nenum MCI_WAVE_MAPPER=(MCI_WAVE_OFFSET+1);\nenum MCI_WAVE_OPEN_BUFFER=0x10000;\nenum MCI_WAVE_SET_FORMATTAG=0x10000;\nenum MCI_WAVE_SET_CHANNELS=0x20000;\nenum MCI_WAVE_SET_SAMPLESPERSEC=0x40000;\nenum MCI_WAVE_SET_AVGBYTESPERSEC=0x80000;\nenum MCI_WAVE_SET_BLOCKALIGN=0x100000;\nenum MCI_WAVE_SET_BITSPERSAMPLE=0x200000;\nenum MCI_WAVE_INPUT=0x400000;\nenum MCI_WAVE_OUTPUT=0x800000;\nenum MCI_WAVE_STATUS_FORMATTAG=0x4001;\nenum MCI_WAVE_STATUS_CHANNELS=0x4002;\nenum MCI_WAVE_STATUS_SAMPLESPERSEC=0x4003;\nenum MCI_WAVE_STATUS_AVGBYTESPERSEC=0x4004;\nenum MCI_WAVE_STATUS_BLOCKALIGN=0x4005;\nenum MCI_WAVE_STATUS_BITSPERSAMPLE=0x4006;\nenum MCI_WAVE_STATUS_LEVEL=0x4007;\nenum MCI_WAVE_SET_ANYINPUT=0x4000000;\nenum MCI_WAVE_SET_ANYOUTPUT=0x8000000;\nenum MCI_WAVE_GETDEVCAPS_INPUTS=0x4001;\nenum MCI_WAVE_GETDEVCAPS_OUTPUTS=0x4002;\n\nenum MCI_SEQ_DIV_PPQN=MCI_SEQ_OFFSET;\nenum MCI_SEQ_DIV_SMPTE_24=(MCI_SEQ_OFFSET+1);\nenum MCI_SEQ_DIV_SMPTE_25=(MCI_SEQ_OFFSET+2);\nenum MCI_SEQ_DIV_SMPTE_30DROP=(MCI_SEQ_OFFSET+3);\nenum MCI_SEQ_DIV_SMPTE_30=(MCI_SEQ_OFFSET+4);\nenum MCI_SEQ_FORMAT_SONGPTR=0x4001;\nenum MCI_SEQ_FILE=0x4002;\nenum MCI_SEQ_MIDI=0x4003;\nenum MCI_SEQ_SMPTE=0x4004;\nenum MCI_SEQ_NONE=65533;\nenum MCI_SEQ_MAPPER=65535;\n\nenum MCI_SEQ_STATUS_TEMPO=0x4002;\nenum MCI_SEQ_STATUS_PORT=0x4003;\nenum MCI_SEQ_STATUS_SLAVE=0x4007;\nenum MCI_SEQ_STATUS_MASTER=0x4008;\nenum MCI_SEQ_STATUS_OFFSET=0x4009;\nenum MCI_SEQ_STATUS_DIVTYPE=0x400A;\nenum MCI_SEQ_STATUS_NAME=0x400B;\nenum MCI_SEQ_STATUS_COPYRIGHT=0x400C;\n\nenum MCI_SEQ_SET_TEMPO=0x10000;\nenum MCI_SEQ_SET_PORT=0x20000;\nenum MCI_SEQ_SET_SLAVE=0x40000;\nenum MCI_SEQ_SET_MASTER=0x80000;\nenum MCI_SEQ_SET_OFFSET=0x1000000;\n\nenum MCI_ANIM_OPEN_WS=0x10000;\nenum MCI_ANIM_OPEN_PARENT=0x20000;\nenum MCI_ANIM_OPEN_NOSTATIC=0x40000;\nenum MCI_ANIM_PLAY_SPEED=0x10000;\nenum MCI_ANIM_PLAY_REVERSE=0x20000;\nenum MCI_ANIM_PLAY_FAST=0x40000;\nenum MCI_ANIM_PLAY_SLOW=0x80000;\nenum MCI_ANIM_PLAY_SCAN=0x100000;\nenum MCI_ANIM_STEP_REVERSE=0x10000;\nenum MCI_ANIM_STEP_FRAMES=0x20000;\nenum MCI_ANIM_STATUS_SPEED=0x4001;\nenum MCI_ANIM_STATUS_FORWARD=0x4002;\nenum MCI_ANIM_STATUS_HWND=0x4003;\nenum MCI_ANIM_STATUS_HPAL=0x4004;\nenum MCI_ANIM_STATUS_STRETCH=0x4005;\nenum MCI_ANIM_INFO_TEXT=0x10000;\n\nenum MCI_ANIM_GETDEVCAPS_CAN_REVERSE=0x4001;\nenum MCI_ANIM_GETDEVCAPS_FAST_RATE=0x4002;\nenum MCI_ANIM_GETDEVCAPS_SLOW_RATE=0x4003;\nenum MCI_ANIM_GETDEVCAPS_NORMAL_RATE=0x4004;\nenum MCI_ANIM_GETDEVCAPS_PALETTES=0x4006;\nenum MCI_ANIM_GETDEVCAPS_CAN_STRETCH=0x4007;\nenum MCI_ANIM_GETDEVCAPS_MAX_WINDOWS=0x4008;\n\nenum MCI_ANIM_REALIZE_NORM=0x10000;\nenum MCI_ANIM_REALIZE_BKGD=0x20000;\n\nenum MCI_ANIM_WINDOW_HWND=0x10000;\nenum MCI_ANIM_WINDOW_STATE=0x40000;\nenum MCI_ANIM_WINDOW_TEXT=0x80000;\nenum MCI_ANIM_WINDOW_ENABLE_STRETCH=0x100000;\nenum MCI_ANIM_WINDOW_DISABLE_STRETCH=0x200000;\nenum MCI_ANIM_WINDOW_DEFAULT=0x0;\n\nenum MCI_ANIM_RECT=0x10000;\nenum MCI_ANIM_PUT_SOURCE=0x20000;\nenum MCI_ANIM_PUT_DESTINATION=0x40000;\nenum MCI_ANIM_WHERE_SOURCE=0x20000;\nenum MCI_ANIM_WHERE_DESTINATION=0x40000;\nenum MCI_ANIM_UPDATE_HDC=0x20000;\n\nenum MCI_OVLY_OPEN_WS=0x10000;\nenum MCI_OVLY_OPEN_PARENT=0x20000;\nenum MCI_OVLY_STATUS_HWND=0x4001;\nenum MCI_OVLY_STATUS_STRETCH=0x4002;\nenum MCI_OVLY_INFO_TEXT=0x10000;\nenum MCI_OVLY_GETDEVCAPS_CAN_STRETCH=0x4001;\nenum MCI_OVLY_GETDEVCAPS_CAN_FREEZE=0x4002;\nenum MCI_OVLY_GETDEVCAPS_MAX_WINDOWS=0x4003;\nenum MCI_OVLY_WINDOW_HWND=0x10000;\nenum MCI_OVLY_WINDOW_STATE=0x40000;\nenum MCI_OVLY_WINDOW_TEXT=0x80000;\nenum MCI_OVLY_WINDOW_ENABLE_STRETCH=0x100000;\nenum MCI_OVLY_WINDOW_DISABLE_STRETCH=0x200000;\nenum MCI_OVLY_WINDOW_DEFAULT=0x0;\nenum MCI_OVLY_RECT=0x10000;\nenum MCI_OVLY_PUT_SOURCE=0x20000;\nenum MCI_OVLY_PUT_DESTINATION=0x40000;\nenum MCI_OVLY_PUT_FRAME=0x80000;\nenum MCI_OVLY_PUT_VIDEO=0x100000;\nenum MCI_OVLY_WHERE_SOURCE=0x20000;\nenum MCI_OVLY_WHERE_DESTINATION=0x40000;\nenum MCI_OVLY_WHERE_FRAME=0x80000;\nenum MCI_OVLY_WHERE_VIDEO=0x100000;\n\nenum NEWTRANSPARENT=3;\nenum QUERYROPSUPPORT=40;\nenum SELECTDIB=41;\n\nLONG DIBINDEX(WORD n) {\n    return MAKELONG(n, 0x10FF);\n}\nenum CAPS1=94;\nenum C1_TRANSPARENT=1;\n\n//const SEEK_SET=0;\n//const SEEK_CUR=1;\n//const SEEK_END=2;\npublic import core.stdc.stdio : SEEK_SET, SEEK_CUR, SEEK_END;\n\nalias DWORD MCIERROR;\nalias UINT MCIDEVICEID;\nextern(Windows) alias UINT function (MCIDEVICEID, DWORD) YIELDPROC;\nalias UINT MMVERSION;\nalias UINT MMRESULT;\n\nstruct MMTIME {\n    UINT wType;\n    union {\n        DWORD ms;\n        DWORD sample;\n        DWORD cb;\n        DWORD ticks;\n        struct _smpte {\n            BYTE hour;\n            BYTE min;\n            BYTE sec;\n            BYTE frame;\n            BYTE fps;\n            BYTE dummy;\n            BYTE[2] pad;\n        };\n        _smpte smpte;\n        struct _midi {\n            DWORD songptrpos;\n        }\n        _midi midi;\n    }\n}\nalias MMTIME* PMMTIME, LPMMTIME;\n\nalias TypeDef!(HANDLE) HDRVR;\n\nstruct DRVCONFIGINFO {\nalign(1):\n    DWORD dwDCISize;\n    LPCWSTR lpszDCISectionName;\n    LPCWSTR lpszDCIAliasName;\n}\nalias DRVCONFIGINFO * PDRVCONFIGINFO, LPDRVCONFIGINFO;\n\nstruct DRVCONFIGINFOEX {\nalign(1):\n    DWORD dwDCISize;\n    LPCWSTR lpszDCISectionName;\n    LPCWSTR lpszDCIAliasName;\n    DWORD dnDevNode;\n}\nalias DRVCONFIGINFOEX* PDRVCONFIGINFOEX, LPDRVCONFIGINFOEX;\n\nextern(Windows):\n\n/+FIXME: I couldn't find these in MSDN.\nalias void function (HDRVR, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR) DRVCALLBACK;\nLRESULT DRIVERPROC (DWORD_PTR, HDRVR, UINT, LPARAM, LPARAM);\nalias DRVCALLBACK* LPDRVCALLBACK, PDRVCALLBACK;\n\nalias DRVCALLBACK WAVECALLBACK;\nalias WAVECALLBACK* LPWAVECALLBACK;\n\nalias DRVCALLBACK MIDICALLBACK;\nalias MIDICALLBACK* LPMIDICALLBACK;\n\n+/\n\nalias TypeDef!(HANDLE) HWAVE;\nalias TypeDef!(HANDLE) HWAVEIN;\nalias TypeDef!(HANDLE) HWAVEOUT;\n\nalias HWAVEIN* LPHWAVEIN;\nalias HWAVEOUT* LPHWAVEOUT;\n\nstruct WAVEHDR {\n    LPSTR lpData;\n    DWORD dwBufferLength;\n    DWORD dwBytesRecorded;\n    DWORD_PTR dwUser;\n    DWORD dwFlags;\n    DWORD dwLoops;\n    WAVEHDR *lpNext;\n    DWORD_PTR reserved;\n}\nalias WAVEHDR* PWAVEHDR, LPWAVEHDR;\n\nstruct WAVEOUTCAPSA {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    CHAR[MAXPNAMELEN] szPname;\n    DWORD dwFormats;\n    WORD wChannels;\n    WORD wReserved1;\n    DWORD dwSupport;\n}\nalias WAVEOUTCAPSA* PWAVEOUTCAPSA, LPWAVEOUTCAPSA;\n\nstruct WAVEOUTCAPSW {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    WCHAR[MAXPNAMELEN] szPname;\n    DWORD dwFormats;\n    WORD wChannels;\n    WORD wReserved1;\n    DWORD dwSupport;\n}\nalias WAVEOUTCAPSW* PWAVEOUTCAPSW, LPWAVEOUTCAPSW;\n\nstruct WAVEINCAPSA {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    CHAR[MAXPNAMELEN] szPname;\n    DWORD dwFormats;\n    WORD wChannels;\n    WORD wReserved1;\n}\nalias WAVEINCAPSA* PWAVEINCAPSA, LPWAVEINCAPSA;\n\nstruct WAVEINCAPSW {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    WCHAR[MAXPNAMELEN] szPname;\n    DWORD dwFormats;\n    WORD wChannels;\n    WORD wReserved1;\n}\nalias WAVEINCAPSW* PWAVEINCAPSW, LPWAVEINCAPSW;\n\nstruct WAVEFORMAT {\n    WORD wFormatTag;\n    WORD nChannels;\n    DWORD nSamplesPerSec;\n    DWORD nAvgBytesPerSec;\n    WORD nBlockAlign;\n}\nalias WAVEFORMAT* PWAVEFORMAT, LPWAVEFORMAT;\n\nstruct PCMWAVEFORMAT {\n    WAVEFORMAT wf;\n    WORD wBitsPerSample;\n}\nalias PCMWAVEFORMAT* PPCMWAVEFORMAT, LPPCMWAVEFORMAT;\n\nstruct WAVEFORMATEX {\n    WORD wFormatTag;\n    WORD nChannels;\n    DWORD nSamplesPerSec;\n    DWORD nAvgBytesPerSec;\n    WORD nBlockAlign;\n    WORD wBitsPerSample;\n    WORD cbSize;\n}\nalias WAVEFORMATEX* PWAVEFORMATEX, LPWAVEFORMATEX;\nalias const(WAVEFORMATEX)* LPCWAVEFORMATEX;\n\nalias TypeDef!(HANDLE) HMIDI;\nalias TypeDef!(HANDLE) HMIDIIN;\nalias TypeDef!(HANDLE) HMIDIOUT;\nalias TypeDef!(HANDLE) HMIDISTRM;\n\nalias HMIDI* LPHMIDI;\nalias HMIDIIN* LPHMIDIIN;\nalias HMIDIOUT* LPHMIDIOUT;\nalias HMIDISTRM* LPHMIDISTRM;\n\nalias WORD[MIDIPATCHSIZE] PATCHARRAY;\nalias WORD* LPPATCHARRAY;\nalias WORD[MIDIPATCHSIZE] KEYARRAY;\nalias WORD* LPKEYARRAY;\n\nstruct MIDIOUTCAPSA {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    CHAR[MAXPNAMELEN] szPname;\n    WORD wTechnology;\n    WORD wVoices;\n    WORD wNotes;\n    WORD wChannelMask;\n    DWORD dwSupport;\n}\nalias MIDIOUTCAPSA* PMIDIOUTCAPSA, LPMIDIOUTCAPSA;\n\nstruct MIDIOUTCAPSW {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    WCHAR[MAXPNAMELEN] szPname;\n    WORD wTechnology;\n    WORD wVoices;\n    WORD wNotes;\n    WORD wChannelMask;\n    DWORD dwSupport;\n}\nalias MIDIOUTCAPSW* PMIDIOUTCAPSW, LPMIDIOUTCAPSW;\n\nstruct MIDIINCAPSA {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    CHAR[MAXPNAMELEN] szPname;\n    DWORD dwSupport;\n}\nalias MIDIINCAPSA* PMIDIINCAPSA, LPMIDIINCAPSA;\n\nstruct MIDIINCAPSW {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    WCHAR[MAXPNAMELEN] szPname;\n    DWORD dwSupport;\n}\nalias MIDIINCAPSW* PMIDIINCAPSW, LPMIDIINCAPSW;\n\nstruct MIDIHDR {\nalign(1):\n    LPSTR lpData;\n    DWORD dwBufferLength;\n    DWORD dwBytesRecorded;\n    DWORD_PTR dwUser;\n    DWORD dwFlags;\n    MIDIHDR *lpNext;\n    DWORD_PTR reserved;\n    DWORD dwOffset;\n    DWORD_PTR[8] dwReserved;\n}\nalias MIDIHDR* PMIDIHDR, LPMIDIHDR;\n\nstruct MIDIEVENT {\n    DWORD dwDeltaTime;\n    DWORD dwStreamID;\n    DWORD dwEvent;\n    DWORD[1] dwParms;\n}\n\nstruct MIDISTRMBUFFVER {\n    DWORD dwVersion;\n    DWORD dwMid;\n    DWORD dwOEMVersion;\n}\n\nstruct MIDIPROPTIMEDIV {\n    DWORD cbStruct;\n    DWORD dwTimeDiv;\n}\nalias MIDIPROPTIMEDIV* LPMIDIPROPTIMEDIV;\n\nstruct MIDIPROPTEMPO {\n    DWORD cbStruct;\n    DWORD dwTempo;\n}\nalias MIDIPROPTEMPO* LPMIDIPROPTEMPO;\n\nstruct AUXCAPSA {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    CHAR[MAXPNAMELEN] szPname;\n    WORD wTechnology;\n    WORD wReserved1;\n    DWORD dwSupport;\n}\nalias AUXCAPSA* PAUXCAPSA, LPAUXCAPSA;\n\nstruct AUXCAPSW {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    WCHAR[MAXPNAMELEN] szPname;\n    WORD wTechnology;\n    WORD wReserved1;\n    DWORD dwSupport;\n}\nalias AUXCAPSW* PAUXCAPSW, LPAUXCAPSW;\n\nalias TypeDef!(HANDLE) HMIXEROBJ;\nalias HMIXEROBJ* LPHMIXEROBJ;\n\nalias TypeDef!(HANDLE) HMIXER;\nalias HMIXER* LPHMIXER;\n\nstruct MIXERCAPSA {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    CHAR[MAXPNAMELEN] szPname;\n    DWORD fdwSupport;\n    DWORD cDestinations;\n}\nalias MIXERCAPSA* PMIXERCAPSA, LPMIXERCAPSA;\n\nstruct MIXERCAPSW {\n    WORD wMid;\n    WORD wPid;\n    MMVERSION vDriverVersion;\n    WCHAR[MAXPNAMELEN] szPname;\n    DWORD fdwSupport;\n    DWORD cDestinations;\n}\nalias MIXERCAPSW* PMIXERCAPSW, LPMIXERCAPSW;\n\nstruct MIXERLINEA {\nalign(1):\n    DWORD cbStruct;\n    DWORD dwDestination;\n    DWORD dwSource;\n    DWORD dwLineID;\n    DWORD fdwLine;\n    DWORD_PTR dwUser;\n    DWORD dwComponentType;\n    DWORD cChannels;\n    DWORD cConnections;\n    DWORD cControls;\n    CHAR[MIXER_SHORT_NAME_CHARS] szShortName;\n    CHAR[MIXER_LONG_NAME_CHARS] szName;\n    struct _Target {\n        DWORD dwType;\n        DWORD dwDeviceID;\n        WORD wMid;\n        WORD wPid;\n        MMVERSION vDriverVersion;\n        CHAR[MAXPNAMELEN] szPname;\n    }\n    _Target Target;\n}\nalias MIXERLINEA* PMIXERLINEA, LPMIXERLINEA;\n\nstruct MIXERLINEW {\nalign(1):\n    DWORD cbStruct;\n    DWORD dwDestination;\n    DWORD dwSource;\n    DWORD dwLineID;\n    DWORD fdwLine;\n    DWORD_PTR dwUser;\n    DWORD dwComponentType;\n    DWORD cChannels;\n    DWORD cConnections;\n    DWORD cControls;\n    WCHAR[MIXER_SHORT_NAME_CHARS] szShortName;\n    WCHAR[MIXER_LONG_NAME_CHARS] szName;\n    struct _Target {\n        DWORD dwType;\n        DWORD dwDeviceID;\n        WORD wMid;\n        WORD wPid;\n        MMVERSION vDriverVersion;\n        WCHAR[MAXPNAMELEN] szPname;\n    }\n    _Target Target;\n}\nalias MIXERLINEW* PMIXERLINEW, LPMIXERLINEW;\n\nstruct MIXERCONTROLA {\n    DWORD cbStruct;\n    DWORD dwControlID;\n    DWORD dwControlType;\n    DWORD fdwControl;\n    DWORD cMultipleItems;\n    CHAR[MIXER_SHORT_NAME_CHARS] szShortName;\n    CHAR[MIXER_LONG_NAME_CHARS] szName;\n    union _Bounds {\n        struct {\n            LONG lMinimum;\n            LONG lMaximum;\n        }\n        struct {\n            DWORD dwMinimum;\n            DWORD dwMaximum;\n        }\n        DWORD[6] dwReserved;\n    }\n    _Bounds Bounds;\n    union _Metrics {\n        DWORD cSteps;\n        DWORD cbCustomData;\n        DWORD[6] dwReserved;\n    }\n    _Metrics Metrics;\n}\nalias MIXERCONTROLA* PMIXERCONTROLA, LPMIXERCONTROLA;\n\nstruct MIXERCONTROLW {\n    DWORD cbStruct;\n    DWORD dwControlID;\n    DWORD dwControlType;\n    DWORD fdwControl;\n    DWORD cMultipleItems;\n    WCHAR[MIXER_SHORT_NAME_CHARS] szShortName;\n    WCHAR[MIXER_LONG_NAME_CHARS] szName;\n    union _Bounds {\n        struct {\n            LONG lMinimum;\n            LONG lMaximum;\n        }\n        struct {\n            DWORD dwMinimum;\n            DWORD dwMaximum;\n        }\n        DWORD[6] dwReserved;\n    }\n    _Bounds Bounds;\n    union _Metrics {\n        DWORD cSteps;\n        DWORD cbCustomData;\n        DWORD[6] dwReserved;\n    }\n    _Metrics Metrics;\n}\n\nalias MIXERCONTROLW* PMIXERCONTROLW, LPMIXERCONTROLW;\n\nstruct MIXERLINECONTROLSA {\nalign(1):\n    DWORD cbStruct;\n    DWORD dwLineID;\n    union {\n        DWORD dwControlID;\n        DWORD dwControlType;\n    }\n    DWORD cControls;\n    DWORD cbmxctrl;\n    LPMIXERCONTROLA pamxctrl;\n}\nalias MIXERLINECONTROLSA* PMIXERLINECONTROLSA, LPMIXERLINECONTROLSA;\n\nstruct MIXERLINECONTROLSW {\nalign(1):\n    DWORD cbStruct;\n    DWORD dwLineID;\n    union {\n        DWORD dwControlID;\n        DWORD dwControlType;\n    }\n    DWORD cControls;\n    DWORD cbmxctrl;\n    LPMIXERCONTROLW pamxctrl;\n}\nalias MIXERLINECONTROLSW* PMIXERLINECONTROLSW, LPMIXERLINECONTROLSW;\n\nstruct MIXERCONTROLDETAILS {\nalign(1):\n    DWORD cbStruct;\n    DWORD dwControlID;\n    DWORD cChannels;\n    union {\n        HWND hwndOwner;\n        DWORD cMultipleItems;\n    }\n    DWORD cbDetails;\n    PVOID paDetails;\n}\nalias MIXERCONTROLDETAILS* PMIXERCONTROLDETAILS, LPMIXERCONTROLDETAILS;\n\nstruct MIXERCONTROLDETAILS_LISTTEXTA {\n    DWORD dwParam1;\n    DWORD dwParam2;\n    CHAR[MIXER_LONG_NAME_CHARS] szName;\n}\nalias MIXERCONTROLDETAILS_LISTTEXTA* PMIXERCONTROLDETAILS_LISTTEXTA, LPMIXERCONTROLDETAILS_LISTTEXTA;\n\nstruct MIXERCONTROLDETAILS_LISTTEXTW {\n    DWORD dwParam1;\n    DWORD dwParam2;\n    WCHAR[MIXER_LONG_NAME_CHARS] szName;\n}\nalias MIXERCONTROLDETAILS_LISTTEXTW* PMIXERCONTROLDETAILS_LISTTEXTW, LPMIXERCONTROLDETAILS_LISTTEXTW;\n\nstruct MIXERCONTROLDETAILS_BOOLEAN {\n    LONG fValue;\n}\nalias MIXERCONTROLDETAILS_BOOLEAN* PMIXERCONTROLDETAILS_BOOLEAN, LPMIXERCONTROLDETAILS_BOOLEAN;\n\nstruct MIXERCONTROLDETAILS_SIGNED {\n    LONG lValue;\n}\nalias MIXERCONTROLDETAILS_SIGNED* PMIXERCONTROLDETAILS_SIGNED, LPMIXERCONTROLDETAILS_SIGNED;\n\nstruct MIXERCONTROLDETAILS_UNSIGNED {\n    DWORD dwValue;\n}\nalias MIXERCONTROLDETAILS_UNSIGNED* PMIXERCONTROLDETAILS_UNSIGNED, LPMIXERCONTROLDETAILS_UNSIGNED;\n\nalias void function (UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR) LPTIMECALLBACK;\n\nstruct TIMECAPS {\n    UINT wPeriodMin;\n    UINT wPeriodMax;\n}\nalias TIMECAPS* PTIMECAPS, LPTIMECAPS;\n\nstruct JOYCAPSA {\n    WORD wMid;\n    WORD wPid;\n    CHAR[MAXPNAMELEN] szPname;\n    UINT wXmin;\n    UINT wXmax;\n    UINT wYmin;\n    UINT wYmax;\n    UINT wZmin;\n    UINT wZmax;\n    UINT wNumButtons;\n    UINT wPeriodMin;\n    UINT wPeriodMax;\n    UINT wRmin;\n    UINT wRmax;\n    UINT wUmin;\n    UINT wUmax;\n    UINT wVmin;\n    UINT wVmax;\n    UINT wCaps;\n    UINT wMaxAxes;\n    UINT wNumAxes;\n    UINT wMaxButtons;\n    CHAR[MAXPNAMELEN] szRegKey;\n    CHAR[MAX_JOYSTICKOEMVXDNAME] szOEMVxD;\n}\nalias JOYCAPSA* PJOYCAPSA, LPJOYCAPSA;\n\nstruct JOYCAPSW {\n    WORD wMid;\n    WORD wPid;\n    WCHAR[MAXPNAMELEN] szPname;\n    UINT wXmin;\n    UINT wXmax;\n    UINT wYmin;\n    UINT wYmax;\n    UINT wZmin;\n    UINT wZmax;\n    UINT wNumButtons;\n    UINT wPeriodMin;\n    UINT wPeriodMax;\n    UINT wRmin;\n    UINT wRmax;\n    UINT wUmin;\n    UINT wUmax;\n    UINT wVmin;\n    UINT wVmax;\n    UINT wCaps;\n    UINT wMaxAxes;\n    UINT wNumAxes;\n    UINT wMaxButtons;\n    WCHAR[MAXPNAMELEN] szRegKey;\n    WCHAR[MAX_JOYSTICKOEMVXDNAME] szOEMVxD;\n}\nalias JOYCAPSW* PJOYCAPSW, LPJOYCAPSW;\n\nstruct JOYINFO {\n    UINT wXpos;\n    UINT wYpos;\n    UINT wZpos;\n    UINT wButtons;\n}\nalias JOYINFO* PJOYINFO, LPJOYINFO;\n\nstruct JOYINFOEX {\n    DWORD dwSize;\n    DWORD dwFlags;\n    DWORD dwXpos;\n    DWORD dwYpos;\n    DWORD dwZpos;\n    DWORD dwRpos;\n    DWORD dwUpos;\n    DWORD dwVpos;\n    DWORD dwButtons;\n    DWORD dwButtonNumber;\n    DWORD dwPOV;\n    DWORD dwReserved1;\n    DWORD dwReserved2;\n}\nalias JOYINFOEX* PJOYINFOEX, LPJOYINFOEX;\n\nalias DWORD FOURCC;\nalias char* HPSTR;\n\nalias TypeDef!(HANDLE) HMMIO;\n\nalias LRESULT function (LPSTR, UINT, LPARAM, LPARAM) LPMMIOPROC;\n\nstruct MMIOINFO {\nalign(1):\n    DWORD dwFlags;\n    FOURCC fccIOProc;\n    LPMMIOPROC pIOProc;\n    UINT wErrorRet;\n    HTASK htask;\n    LONG cchBuffer;\n    HPSTR pchBuffer;\n    HPSTR pchNext;\n    HPSTR pchEndRead;\n    HPSTR pchEndWrite;\n    LONG lBufOffset;\n    LONG lDiskOffset;\n    DWORD[3] adwInfo;\n    DWORD dwReserved1;\n    DWORD dwReserved2;\n    HMMIO hmmio;\n}\nalias MMIOINFO* PMMIOINFO, LPMMIOINFO;\nalias const(MMIOINFO)* LPCMMIOINFO;\n\nstruct MMCKINFO {\n    FOURCC ckid;\n    DWORD cksize;\n    FOURCC fccType;\n    DWORD dwDataOffset;\n    DWORD dwFlags;\n}\nalias MMCKINFO* PMMCKINFO, LPMMCKINFO;\nalias const(MMCKINFO)* LPCMMCKINFO;\n\nstruct MCI_GENERIC_PARMS {\n    DWORD_PTR dwCallback;\n}\nalias MCI_GENERIC_PARMS* PMCI_GENERIC_PARMS, LPMCI_GENERIC_PARMS;\n\nstruct MCI_OPEN_PARMSA {\nalign(1):\n    DWORD_PTR dwCallback;\n    MCIDEVICEID wDeviceID;\n    LPCSTR lpstrDeviceType;\n    LPCSTR lpstrElementName;\n    LPCSTR lpstrAlias;\n}\nalias MCI_OPEN_PARMSA* PMCI_OPEN_PARMSA, LPMCI_OPEN_PARMSA;\n\nstruct MCI_OPEN_PARMSW {\nalign(1):\n    DWORD_PTR dwCallback;\n    MCIDEVICEID wDeviceID;\n    LPCWSTR lpstrDeviceType;\n    LPCWSTR lpstrElementName;\n    LPCWSTR lpstrAlias;\n}\nalias MCI_OPEN_PARMSW* PMCI_OPEN_PARMSW, LPMCI_OPEN_PARMSW;\n\nstruct MCI_PLAY_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwFrom;\n    DWORD dwTo;\n}\nalias MCI_PLAY_PARMS* PMCI_PLAY_PARMS, LPMCI_PLAY_PARMS;\n\nstruct MCI_SEEK_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwTo;\n}\nalias MCI_SEEK_PARMS* PMCI_SEEK_PARMS, LPMCI_SEEK_PARMS;\n\nstruct MCI_STATUS_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD_PTR dwReturn;\n    DWORD dwItem;\n    DWORD dwTrack;\n}\nalias MCI_STATUS_PARMS* PMCI_STATUS_PARMS, LPMCI_STATUS_PARMS;\n\nstruct MCI_INFO_PARMSA {\n    DWORD_PTR dwCallback;\n    LPSTR lpstrReturn;\n    DWORD dwRetSize;\n}\nalias MCI_INFO_PARMSA* LPMCI_INFO_PARMSA;\n\nstruct MCI_INFO_PARMSW {\n    DWORD_PTR dwCallback;\n    LPWSTR lpstrReturn;\n    DWORD dwRetSize;\n}\nalias MCI_INFO_PARMSW* LPMCI_INFO_PARMSW;\n\nstruct MCI_GETDEVCAPS_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwReturn;\n    DWORD dwItem;\n}\nalias MCI_GETDEVCAPS_PARMS* PMCI_GETDEVCAPS_PARMS, LPMCI_GETDEVCAPS_PARMS;\n\nstruct MCI_SYSINFO_PARMSA {\n    DWORD_PTR dwCallback;\n    LPSTR lpstrReturn;\n    DWORD dwRetSize;\n    DWORD dwNumber;\n    UINT wDeviceType;\n}\nalias MCI_SYSINFO_PARMSA* PMCI_SYSINFO_PARMSA, LPMCI_SYSINFO_PARMSA;\n\nstruct MCI_SYSINFO_PARMSW {\n    DWORD_PTR dwCallback;\n    LPWSTR lpstrReturn;\n    DWORD dwRetSize;\n    DWORD dwNumber;\n    UINT wDeviceType;\n}\nalias MCI_SYSINFO_PARMSW* PMCI_SYSINFO_PARMSW, LPMCI_SYSINFO_PARMSW;\n\nstruct MCI_SET_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwTimeFormat;\n    DWORD dwAudio;\n}\nalias MCI_SET_PARMS* PMCI_SET_PARMS, LPMCI_SET_PARMS;\n\nstruct MCI_BREAK_PARMS {\nalign(1):\n    DWORD_PTR dwCallback;\n    int nVirtKey;\n    HWND hwndBreak;\n}\nalias MCI_BREAK_PARMS* PMCI_BREAK_PARMS, LPMCI_BREAK_PARMS;\n\nstruct MCI_SAVE_PARMSA {\n    DWORD_PTR dwCallback;\n    LPCSTR lpfilename;\n}\nalias MCI_SAVE_PARMSA* PMCI_SAVE_PARMSA, LPMCI_SAVE_PARMSA;\n\nstruct MCI_SAVE_PARMSW {\n    DWORD_PTR dwCallback;\n    LPCWSTR lpfilename;\n}\nalias MCI_SAVE_PARMSW* PMCI_SAVE_PARMSW, LPMCI_SAVE_PARMSW;\n\nstruct MCI_LOAD_PARMSA {\n    DWORD_PTR dwCallback;\n    LPCSTR lpfilename;\n}\nalias MCI_LOAD_PARMSA* PMCI_LOAD_PARMSA, LPMCI_LOAD_PARMSA;\n\nstruct MCI_LOAD_PARMSW {\n    DWORD_PTR dwCallback;\n    LPCWSTR lpfilename;\n}\nalias MCI_LOAD_PARMSW* PMCI_LOAD_PARMSW, LPMCI_LOAD_PARMSW;\n\nstruct MCI_RECORD_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwFrom;\n    DWORD dwTo;\n}\nalias MCI_RECORD_PARMS* LPMCI_RECORD_PARMS;\n\nstruct MCI_VD_PLAY_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwFrom;\n    DWORD dwTo;\n    DWORD dwSpeed;\n}\nalias MCI_VD_PLAY_PARMS* PMCI_VD_PLAY_PARMS, LPMCI_VD_PLAY_PARMS;\n\nstruct MCI_VD_STEP_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwFrames;\n}\nalias MCI_VD_STEP_PARMS* PMCI_VD_STEP_PARMS, LPMCI_VD_STEP_PARMS;\n\nstruct MCI_VD_ESCAPE_PARMSA {\n    DWORD_PTR dwCallback;\n    LPCSTR lpstrCommand;\n}\nalias MCI_VD_ESCAPE_PARMSA* PMCI_VD_ESCAPE_PARMSA, LPMCI_VD_ESCAPE_PARMSA;\n\nstruct MCI_VD_ESCAPE_PARMSW {\n    DWORD_PTR dwCallback;\n    LPCWSTR lpstrCommand;\n}\nalias MCI_VD_ESCAPE_PARMSW* PMCI_VD_ESCAPE_PARMSW, LPMCI_VD_ESCAPE_PARMSW;\n\nstruct MCI_WAVE_OPEN_PARMSA {\nalign(1):\n    DWORD_PTR dwCallback;\n    MCIDEVICEID wDeviceID;\n    LPCSTR lpstrDeviceType;\n    LPCSTR lpstrElementName;\n    LPCSTR lpstrAlias;\n    DWORD dwBufferSeconds;\n}\nalias MCI_WAVE_OPEN_PARMSA* PMCI_WAVE_OPEN_PARMSA, LPMCI_WAVE_OPEN_PARMSA;\n\nstruct MCI_WAVE_OPEN_PARMSW {\nalign(1):\n    DWORD_PTR dwCallback;\n    MCIDEVICEID wDeviceID;\n    LPCWSTR lpstrDeviceType;\n    LPCWSTR lpstrElementName;\n    LPCWSTR lpstrAlias;\n    DWORD dwBufferSeconds;\n}\nalias MCI_WAVE_OPEN_PARMSW* PMCI_WAVE_OPEN_PARMSW, LPMCI_WAVE_OPEN_PARMSW;\n\nstruct MCI_WAVE_DELETE_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwFrom;\n    DWORD dwTo;\n}\nalias MCI_WAVE_DELETE_PARMS* PMCI_WAVE_DELETE_PARMS, LPMCI_WAVE_DELETE_PARMS;\n\nstruct MCI_WAVE_SET_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwTimeFormat;\n    DWORD dwAudio;\n    UINT wInput;\n    UINT wOutput;\n    WORD wFormatTag;\n    WORD wReserved2;\n    WORD nChannels;\n    WORD wReserved3;\n    DWORD nSamplesPerSec;\n    DWORD nAvgBytesPerSec;\n    WORD nBlockAlign;\n    WORD wReserved4;\n    WORD wBitsPerSample;\n    WORD wReserved5;\n}\nalias MCI_WAVE_SET_PARMS* PMCI_WAVE_SET_PARMS, LPMCI_WAVE_SET_PARMS;\n\nextern (Windows) nothrow @nogc:\nLRESULT CloseDriver(HDRVR, LONG, LONG);\nHDRVR OpenDriver(LPCWSTR, LPCWSTR, LONG);\nLRESULT SendDriverMessage(HDRVR, UINT, LONG, LONG);\nHMODULE DrvGetModuleHandle(HDRVR);\nHMODULE GetDriverModuleHandle(HDRVR);\nLRESULT DefDriverProc(DWORD_PTR, HDRVR, UINT, LPARAM, LPARAM);\nUINT mmsystemGetVersion();\n// FIXME: I believe this next line is a mistake\n//alias OutputDebugString OutputDebugStr;\nBOOL sndPlaySoundA(LPCSTR, UINT);\nBOOL sndPlaySoundW(LPCWSTR, UINT);\nBOOL PlaySoundA(LPCSTR, HMODULE, DWORD);\nBOOL PlaySoundW(LPCWSTR, HMODULE, DWORD);\nUINT waveOutGetNumDevs();\nMMRESULT waveOutGetDevCapsA(UINT_PTR, LPWAVEOUTCAPSA, UINT);\nMMRESULT waveOutGetDevCapsW(UINT_PTR, LPWAVEOUTCAPSW, UINT);\nMMRESULT waveOutGetVolume(HWAVEOUT, PDWORD);\nMMRESULT waveOutSetVolume(HWAVEOUT, DWORD);\nMMRESULT waveOutGetErrorTextA(MMRESULT, LPSTR, UINT);\nMMRESULT waveOutGetErrorTextW(MMRESULT, LPWSTR, UINT);\nMMRESULT waveOutOpen(LPHWAVEOUT, UINT, LPCWAVEFORMATEX, DWORD_PTR, DWORD_PTR, DWORD);\nMMRESULT waveOutClose(HWAVEOUT);\nMMRESULT waveOutPrepareHeader(HWAVEOUT, LPWAVEHDR, UINT);\nMMRESULT waveOutUnprepareHeader(HWAVEOUT, LPWAVEHDR, UINT);\nMMRESULT waveOutWrite(HWAVEOUT, LPWAVEHDR, UINT);\nMMRESULT waveOutPause(HWAVEOUT);\nMMRESULT waveOutRestart(HWAVEOUT);\nMMRESULT waveOutReset(HWAVEOUT);\nMMRESULT waveOutBreakLoop(HWAVEOUT);\nMMRESULT waveOutGetPosition(HWAVEOUT, LPMMTIME, UINT);\nMMRESULT waveOutGetPitch(HWAVEOUT, PDWORD);\nMMRESULT waveOutSetPitch(HWAVEOUT, DWORD);\nMMRESULT waveOutGetPlaybackRate(HWAVEOUT, PDWORD);\nMMRESULT waveOutSetPlaybackRate(HWAVEOUT, DWORD);\nMMRESULT waveOutGetID(HWAVEOUT, LPUINT);\nMMRESULT waveOutMessage(HWAVEOUT, UINT, DWORD_PTR, DWORD_PTR);\nUINT waveInGetNumDevs();\nMMRESULT waveInGetDevCapsA(UINT_PTR, LPWAVEINCAPSA, UINT);\nMMRESULT waveInGetDevCapsW(UINT_PTR, LPWAVEINCAPSW, UINT);\nMMRESULT waveInGetErrorTextA(MMRESULT, LPSTR, UINT);\nMMRESULT waveInGetErrorTextW(MMRESULT, LPWSTR, UINT);\nMMRESULT waveInOpen(LPHWAVEIN, UINT, LPCWAVEFORMATEX, DWORD_PTR, DWORD_PTR, DWORD);\nMMRESULT waveInClose(HWAVEIN);\nMMRESULT waveInPrepareHeader(HWAVEIN, LPWAVEHDR, UINT);\nMMRESULT waveInUnprepareHeader(HWAVEIN, LPWAVEHDR, UINT);\nMMRESULT waveInAddBuffer(HWAVEIN, LPWAVEHDR, UINT);\nMMRESULT waveInStart(HWAVEIN);\nMMRESULT waveInStop(HWAVEIN);\nMMRESULT waveInReset(HWAVEIN);\nMMRESULT waveInGetPosition(HWAVEIN, LPMMTIME, UINT);\nMMRESULT waveInGetID(HWAVEIN, LPUINT);\nMMRESULT waveInMessage(HWAVEIN, UINT, DWORD_PTR, DWORD_PTR);\nUINT midiOutGetNumDevs();\nMMRESULT midiStreamOpen(LPHMIDISTRM, LPUINT, DWORD, DWORD_PTR, DWORD_PTR, DWORD);\nMMRESULT midiStreamClose(HMIDISTRM);\nMMRESULT midiStreamProperty(HMIDISTRM, LPBYTE, DWORD);\nMMRESULT midiStreamPosition(HMIDISTRM, LPMMTIME, UINT);\nMMRESULT midiStreamOut(HMIDISTRM, LPMIDIHDR, UINT);\nMMRESULT midiStreamPause(HMIDISTRM);\nMMRESULT midiStreamRestart(HMIDISTRM);\nMMRESULT midiStreamStop(HMIDISTRM);\nMMRESULT midiConnect(HMIDI, HMIDIOUT, PVOID);\nMMRESULT midiDisconnect(HMIDI, HMIDIOUT, PVOID);\nMMRESULT midiOutGetDevCapsA(UINT_PTR, LPMIDIOUTCAPSA, UINT);\nMMRESULT midiOutGetDevCapsW(UINT_PTR, LPMIDIOUTCAPSW, UINT);\nMMRESULT midiOutGetVolume(HMIDIOUT, PDWORD);\nMMRESULT midiOutSetVolume(HMIDIOUT, DWORD);\nMMRESULT midiOutGetErrorTextA(MMRESULT, LPSTR, UINT);\nMMRESULT midiOutGetErrorTextW(MMRESULT, LPWSTR, UINT);\nMMRESULT midiOutOpen(LPHMIDIOUT, UINT, DWORD_PTR, DWORD_PTR, DWORD);\nMMRESULT midiOutClose(HMIDIOUT);\nMMRESULT midiOutPrepareHeader(HMIDIOUT, LPMIDIHDR, UINT);\nMMRESULT midiOutUnprepareHeader(HMIDIOUT, LPMIDIHDR, UINT);\nMMRESULT midiOutShortMsg(HMIDIOUT, DWORD);\nMMRESULT midiOutLongMsg(HMIDIOUT, LPMIDIHDR, UINT);\nMMRESULT midiOutReset(HMIDIOUT);\nMMRESULT midiOutCachePatches(HMIDIOUT, UINT, LPWORD, UINT);\nMMRESULT midiOutCacheDrumPatches(HMIDIOUT, UINT, LPWORD, UINT);\nMMRESULT midiOutGetID(HMIDIOUT, LPUINT);\nMMRESULT midiOutMessage(HMIDIOUT, UINT, DWORD_PTR, DWORD_PTR);\nUINT midiInGetNumDevs();\nMMRESULT midiInGetDevCapsA(UINT_PTR, LPMIDIINCAPSA, UINT);\nMMRESULT midiInGetDevCapsW(UINT_PTR, LPMIDIINCAPSW, UINT);\nMMRESULT midiInGetErrorTextA(MMRESULT, LPSTR, UINT);\nMMRESULT midiInGetErrorTextW(MMRESULT, LPWSTR, UINT);\nMMRESULT midiInOpen(LPHMIDIIN, UINT, DWORD_PTR, DWORD_PTR, DWORD);\nMMRESULT midiInClose(HMIDIIN);\nMMRESULT midiInPrepareHeader(HMIDIIN, LPMIDIHDR, UINT);\nMMRESULT midiInUnprepareHeader(HMIDIIN, LPMIDIHDR, UINT);\nMMRESULT midiInAddBuffer(HMIDIIN, LPMIDIHDR, UINT);\nMMRESULT midiInStart(HMIDIIN);\nMMRESULT midiInStop(HMIDIIN);\nMMRESULT midiInReset(HMIDIIN);\nMMRESULT midiInGetID(HMIDIIN, LPUINT);\nMMRESULT midiInMessage(HMIDIIN, UINT, DWORD_PTR, DWORD_PTR);\nUINT auxGetNumDevs();\nMMRESULT auxGetDevCapsA(UINT_PTR, LPAUXCAPSA, UINT);\nMMRESULT auxGetDevCapsW(UINT_PTR, LPAUXCAPSW, UINT);\nMMRESULT auxSetVolume(UINT, DWORD);\nMMRESULT auxGetVolume(UINT, PDWORD);\nMMRESULT auxOutMessage(UINT, UINT, DWORD_PTR, DWORD_PTR);\nUINT mixerGetNumDevs();\nMMRESULT mixerGetDevCapsA(UINT_PTR, LPMIXERCAPSA, UINT);\nMMRESULT mixerGetDevCapsW(UINT_PTR, LPMIXERCAPSW, UINT);\nMMRESULT mixerOpen(LPHMIXER, UINT, DWORD_PTR, DWORD_PTR, DWORD);\nMMRESULT mixerClose(HMIXER);\nDWORD mixerMessage(HMIXER, UINT, DWORD_PTR, DWORD_PTR);\nMMRESULT mixerGetLineInfoA(HMIXEROBJ, LPMIXERLINEA, DWORD);\nMMRESULT mixerGetLineInfoW(HMIXEROBJ, LPMIXERLINEW, DWORD);\nMMRESULT mixerGetID(HMIXEROBJ, PUINT, DWORD);\nMMRESULT mixerGetLineControlsA(HMIXEROBJ, LPMIXERLINECONTROLSA, DWORD);\nMMRESULT mixerGetLineControlsW(HMIXEROBJ, LPMIXERLINECONTROLSW, DWORD);\nMMRESULT mixerGetControlDetailsA(HMIXEROBJ, LPMIXERCONTROLDETAILS, DWORD);\nMMRESULT mixerGetControlDetailsW(HMIXEROBJ, LPMIXERCONTROLDETAILS, DWORD);\nMMRESULT mixerSetControlDetails(HMIXEROBJ, LPMIXERCONTROLDETAILS, DWORD);\nMMRESULT timeGetSystemTime(LPMMTIME, UINT);\nDWORD timeGetTime();\nMMRESULT timeSetEvent(UINT, UINT, LPTIMECALLBACK, DWORD_PTR, UINT);\nMMRESULT timeKillEvent(UINT);\nMMRESULT timeGetDevCaps(LPTIMECAPS, UINT);\nMMRESULT timeBeginPeriod(UINT);\nMMRESULT timeEndPeriod(UINT);\nUINT joyGetNumDevs();\nMMRESULT joyGetDevCapsA(UINT_PTR, LPJOYCAPSA, UINT);\nMMRESULT joyGetDevCapsW(UINT_PTR, LPJOYCAPSW, UINT);\nMMRESULT joyGetPos(UINT, LPJOYINFO);\nMMRESULT joyGetPosEx(UINT, LPJOYINFOEX);\nMMRESULT joyGetThreshold(UINT, LPUINT);\nMMRESULT joyReleaseCapture(UINT);\nMMRESULT joySetCapture(HWND, UINT, UINT, BOOL);\nMMRESULT joySetThreshold(UINT, UINT);\nFOURCC mmioStringToFOURCCA(LPCSTR, UINT);\nFOURCC mmioStringToFOURCCW(LPCWSTR, UINT);\nLPMMIOPROC mmioInstallIOProcA(FOURCC, LPMMIOPROC, DWORD);\nLPMMIOPROC mmioInstallIOProcW(FOURCC, LPMMIOPROC, DWORD);\nHMMIO mmioOpenA(LPSTR, LPMMIOINFO, DWORD);\nHMMIO mmioOpenW(LPWSTR, LPMMIOINFO, DWORD);\nMMRESULT mmioRenameA(LPCSTR, LPCSTR, LPCMMIOINFO, DWORD);\nMMRESULT mmioRenameW(LPCWSTR, LPCWSTR, LPCMMIOINFO, DWORD);\nMMRESULT mmioClose(HMMIO, UINT);\nLONG mmioRead(HMMIO, HPSTR, LONG);\nLONG mmioWrite(HMMIO, LPCSTR, LONG);\nLONG mmioSeek(HMMIO, LONG, int);\nMMRESULT mmioGetInfo(HMMIO, LPMMIOINFO, UINT);\nMMRESULT mmioSetInfo(HMMIO, LPCMMIOINFO, UINT);\nMMRESULT mmioSetBuffer(HMMIO, LPSTR, LONG, UINT);\nMMRESULT mmioFlush(HMMIO, UINT);\nMMRESULT mmioAdvance(HMMIO, LPMMIOINFO, UINT);\nLRESULT mmioSendMessage(HMMIO, UINT, LPARAM, LPARAM);\nMMRESULT mmioDescend(HMMIO, LPMMCKINFO, const(MMCKINFO)*, UINT);\nMMRESULT mmioAscend(HMMIO, LPMMCKINFO, UINT);\nMMRESULT mmioCreateChunk(HMMIO, LPMMCKINFO, UINT);\nMCIERROR mciSendCommandA(MCIDEVICEID, UINT, DWORD_PTR, DWORD_PTR);\nMCIERROR mciSendCommandW(MCIDEVICEID, UINT, DWORD_PTR, DWORD_PTR);\nMCIERROR mciSendStringA(LPCSTR, LPSTR, UINT, HWND);\nMCIERROR mciSendStringW(LPCWSTR, LPWSTR, UINT, HWND);\nMCIDEVICEID mciGetDeviceIDA(LPCSTR);\nMCIDEVICEID mciGetDeviceIDW(LPCWSTR);\nMCIDEVICEID mciGetDeviceIDFromElementIDA(DWORD, LPCSTR);\nMCIDEVICEID mciGetDeviceIDFromElementIDW(DWORD, LPCWSTR);\nBOOL mciGetErrorStringA(MCIERROR, LPSTR, UINT);\nBOOL mciGetErrorStringW(MCIERROR, LPWSTR, UINT);\nBOOL mciSetYieldProc(MCIDEVICEID, YIELDPROC, DWORD);\nHTASK mciGetCreatorTask(MCIDEVICEID);\nYIELDPROC mciGetYieldProc(MCIDEVICEID, PDWORD);\n\nstruct MCI_SEQ_SET_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwTimeFormat;\n    DWORD dwAudio;\n    DWORD dwTempo;\n    DWORD dwPort;\n    DWORD dwSlave;\n    DWORD dwMaster;\n    DWORD dwOffset;\n}\nalias MCI_SEQ_SET_PARMS* PMCI_SEQ_SET_PARMS, LPMCI_SEQ_SET_PARMS;\n\nstruct MCI_ANIM_OPEN_PARMSA {\nalign(1):\n    DWORD_PTR dwCallback;\n    MCIDEVICEID wDeviceID;\n    LPCSTR lpstrDeviceType;\n    LPCSTR lpstrElementName;\n    LPCSTR lpstrAlias;\n    DWORD dwStyle;\n    HWND hWndParent;\n}\nalias MCI_ANIM_OPEN_PARMSA* PMCI_ANIM_OPEN_PARMSA, LPMCI_ANIM_OPEN_PARMSA;\n\nstruct MCI_ANIM_OPEN_PARMSW {\nalign(1):\n    DWORD_PTR dwCallback;\n    MCIDEVICEID wDeviceID;\n    LPCWSTR lpstrDeviceType;\n    LPCWSTR lpstrElementName;\n    LPCWSTR lpstrAlias;\n    DWORD dwStyle;\n    HWND hWndParent;\n}\nalias MCI_ANIM_OPEN_PARMSW* PMCI_ANIM_OPEN_PARMSW, LPMCI_ANIM_OPEN_PARMSW;\n\nstruct MCI_ANIM_PLAY_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwFrom;\n    DWORD dwTo;\n    DWORD dwSpeed;\n}\nalias MCI_ANIM_PLAY_PARMS* PMCI_ANIM_PLAY_PARMS, LPMCI_ANIM_PLAY_PARMS;\n\nstruct MCI_ANIM_STEP_PARMS {\n    DWORD_PTR dwCallback;\n    DWORD dwFrames;\n}\nalias MCI_ANIM_STEP_PARMS* PMCI_ANIM_STEP_PARMS, LPMCI_ANIM_STEP_PARMS;\n\nstruct MCI_ANIM_WINDOW_PARMSA {\nalign(1):\n    DWORD_PTR dwCallback;\n    HWND hWnd;\n    UINT nCmdShow;\n    LPCSTR lpstrText;\n}\nalias MCI_ANIM_WINDOW_PARMSA* PMCI_ANIM_WINDOW_PARMSA, LPMCI_ANIM_WINDOW_PARMSA;\n\nstruct MCI_ANIM_WINDOW_PARMSW {\nalign(1):\n    DWORD_PTR dwCallback;\n    HWND hWnd;\n    UINT nCmdShow;\n    LPCWSTR lpstrText;\n}\nalias MCI_ANIM_WINDOW_PARMSW* PMCI_ANIM_WINDOW_PARMSW, LPMCI_ANIM_WINDOW_PARMSW;\n\nstruct MCI_ANIM_RECT_PARMS {\n    DWORD_PTR dwCallback;\n    //#ifdef MCI_USE_OFFEXT\n    //  POINT ptOffset;\n    //  POINT ptExtent;\n    //#else\n    RECT rc;\n    //#endif\n}\nalias MCI_ANIM_RECT_PARMS* PMCI_ANIM_RECT_PARMS, LPMCI_ANIM_RECT_PARMS;\n\nstruct MCI_ANIM_UPDATE_PARMS {\n    DWORD_PTR dwCallback;\n    RECT rc;\n    HDC hDC;\n}\nalias MCI_ANIM_UPDATE_PARMS* PMCI_ANIM_UPDATE_PARMS, LPMCI_ANIM_UPDATE_PARMS;\n\nstruct MCI_OVLY_OPEN_PARMSA {\nalign(1):\n    DWORD_PTR dwCallback;\n    MCIDEVICEID wDeviceID;\n    LPCSTR lpstrDeviceType;\n    LPCSTR lpstrElementName;\n    LPCSTR lpstrAlias;\n    DWORD dwStyle;\n    HWND hWndParent;\n}\nalias MCI_OVLY_OPEN_PARMSA* PMCI_OVLY_OPEN_PARMSA, LPMCI_OVLY_OPEN_PARMSA;\n\nstruct MCI_OVLY_OPEN_PARMSW {\nalign(1):\n    DWORD_PTR dwCallback;\n    MCIDEVICEID wDeviceID;\n    LPCWSTR lpstrDeviceType;\n    LPCWSTR lpstrElementName;\n    LPCWSTR lpstrAlias;\n    DWORD dwStyle;\n    HWND hWndParent;\n}\nalias MCI_OVLY_OPEN_PARMSW* PMCI_OVLY_OPEN_PARMSW, LPMCI_OVLY_OPEN_PARMSW;\n\nstruct MCI_OVLY_WINDOW_PARMSA {\nalign(1):\n    DWORD_PTR dwCallback;\n    HWND hWnd;\n    UINT nCmdShow;\n    LPCSTR lpstrText;\n}\nalias MCI_OVLY_WINDOW_PARMSA* PMCI_OVLY_WINDOW_PARMSA, LPMCI_OVLY_WINDOW_PARMSA;\n\nstruct MCI_OVLY_WINDOW_PARMSW {\nalign(1):\n    DWORD_PTR dwCallback;\n    HWND hWnd;\n    UINT nCmdShow;\n    LPCWSTR lpstrText;\n}\nalias MCI_OVLY_WINDOW_PARMSW* PMCI_OVLY_WINDOW_PARMSW, LPMCI_OVLY_WINDOW_PARMSW;\n\nstruct MCI_OVLY_RECT_PARMS {\n    DWORD_PTR dwCallback;\n    //#ifdef MCI_USE_OFFEXT\n    //  POINT ptOffset;\n    //  POINT ptExtent;\n    //#else\n    RECT rc;\n    //#endif\n}\nalias MCI_OVLY_RECT_PARMS* PMCI_OVLY_RECT_PARMS, LPMCI_OVLY_RECT_PARMS;\n\nstruct MCI_OVLY_SAVE_PARMSA {\n    DWORD_PTR dwCallback;\n    LPCSTR lpfilename;\n    RECT rc;\n}\nalias MCI_OVLY_SAVE_PARMSA* PMCI_OVLY_SAVE_PARMSA, LPMCI_OVLY_SAVE_PARMSA;\n\nstruct MCI_OVLY_SAVE_PARMSW {\n    DWORD_PTR dwCallback;\n    LPCWSTR lpfilename;\n    RECT rc;\n}\nalias MCI_OVLY_SAVE_PARMSW* PMCI_OVLY_SAVE_PARMSW, LPMCI_OVLY_SAVE_PARMSW;\n\nstruct MCI_OVLY_LOAD_PARMSA {\n    DWORD_PTR dwCallback;\n    LPCSTR lpfilename;\n    RECT rc;\n}\nalias MCI_OVLY_LOAD_PARMSA* PMCI_OVLY_LOAD_PARMSA, LPMCI_OVLY_LOAD_PARMSA;\n\nstruct MCI_OVLY_LOAD_PARMSW {\n    DWORD_PTR dwCallback;\n    LPCWSTR lpfilename;\n    RECT rc;\n}\nalias MCI_OVLY_LOAD_PARMSW* PMCI_OVLY_LOAD_PARMSW, LPMCI_OVLY_LOAD_PARMSW;\n\nversion (Unicode) {\n    alias WAVEOUTCAPSW WAVEOUTCAPS;\n    alias WAVEINCAPSW WAVEINCAPS;\n    alias MIDIOUTCAPSW MIDIOUTCAPS;\n    alias MIDIINCAPSW MIDIINCAPS;\n    alias AUXCAPSW AUXCAPS;\n    alias MIXERCAPSW MIXERCAPS;\n    alias MIXERLINEW MIXERLINE;\n    alias MIXERCONTROLA MIXERCONTROL;\n    alias MIXERLINECONTROLSW MIXERLINECONTROLS;\n    alias MIXERCONTROLDETAILS_LISTTEXTW MIXERCONTROLDETAILS_LISTTEXT;\n    alias JOYCAPSW JOYCAPS;\n    alias MCI_OPEN_PARMSW MCI_OPEN_PARMS;\n    alias MCI_INFO_PARMSW MCI_INFO_PARMS;\n    alias MCI_SYSINFO_PARMSW MCI_SYSINFO_PARMS;\n    alias MCI_SAVE_PARMSW MCI_SAVE_PARMS;\n    alias MCI_LOAD_PARMSW MCI_LOAD_PARMS;\n    alias MCI_VD_ESCAPE_PARMSW MCI_VD_ESCAPE_PARMS;\n    alias MCI_WAVE_OPEN_PARMSW MCI_WAVE_OPEN_PARMS;\n    alias MCI_ANIM_OPEN_PARMSW MCI_ANIM_OPEN_PARMS;\n    alias MCI_ANIM_WINDOW_PARMSW MCI_ANIM_WINDOW_PARMS;\n    alias MCI_OVLY_OPEN_PARMSW MCI_OVLY_OPEN_PARMS;\n    alias MCI_OVLY_WINDOW_PARMSW MCI_OVLY_WINDOW_PARMS;\n    alias MCI_OVLY_SAVE_PARMSW MCI_OVLY_SAVE_PARMS;\n\n    alias sndPlaySoundW sndPlaySound;\n    alias PlaySoundW PlaySound;\n    alias waveOutGetDevCapsW waveOutGetDevCaps;\n    alias waveOutGetErrorTextW waveOutGetErrorText;\n    alias waveInGetDevCapsW waveInGetDevCaps;\n    alias waveInGetErrorTextW waveInGetErrorText;\n    alias midiOutGetDevCapsW midiOutGetDevCaps;\n    alias midiOutGetErrorTextW midiOutGetErrorText;\n    alias midiInGetDevCapsW midiInGetDevCaps;\n    alias midiInGetErrorTextW midiInGetErrorText;\n    alias auxGetDevCapsW auxGetDevCaps;\n    alias mixerGetDevCapsW mixerGetDevCaps;\n    alias mixerGetLineInfoW mixerGetLineInfo;\n    alias mixerGetLineControlsW mixerGetLineControls;\n    alias mixerGetControlDetailsW mixerGetControlDetails;\n    alias joyGetDevCapsW joyGetDevCaps;\n    alias mmioInstallIOProcW mmioInstallIOProc;\n    alias mmioStringToFOURCCW mmioStringToFOURCC;\n    alias mmioOpenW mmioOpen;\n    alias mmioRenameW mmioRename;\n    alias mciSendCommandW mciSendCommand;\n    alias mciSendStringW mciSendString;\n    alias mciGetDeviceIDW mciGetDeviceID;\n    alias mciGetDeviceIDFromElementIDW mciGetDeviceIDFromElementID;\n    alias mciGetErrorStringW mciGetErrorString;\n\n} else {\n    alias WAVEOUTCAPSA WAVEOUTCAPS;\n    alias WAVEINCAPSA WAVEINCAPS;\n    alias MIDIOUTCAPSA MIDIOUTCAPS;\n    alias MIDIINCAPSA MIDIINCAPS;\n    alias AUXCAPSA AUXCAPS;\n    alias MIXERCAPSA MIXERCAPS;\n    alias MIXERLINEA MIXERLINE;\n    alias MIXERCONTROLA MIXERCONTROL;\n    alias MIXERLINECONTROLSA MIXERLINECONTROLS;\n    alias MIXERCONTROLDETAILS_LISTTEXTA MIXERCONTROLDETAILS_LISTTEXT;\n    alias JOYCAPSA JOYCAPS;\n    alias MCI_OPEN_PARMSA MCI_OPEN_PARMS;\n    alias MCI_INFO_PARMSA MCI_INFO_PARMS;\n    alias MCI_SYSINFO_PARMSA MCI_SYSINFO_PARMS;\n    alias MCI_SAVE_PARMSA MCI_SAVE_PARMS;\n    alias MCI_LOAD_PARMSA MCI_LOAD_PARMS;\n    alias MCI_VD_ESCAPE_PARMSA MCI_VD_ESCAPE_PARMS;\n    alias MCI_WAVE_OPEN_PARMSA MCI_WAVE_OPEN_PARMS;\n    alias MCI_ANIM_OPEN_PARMSA MCI_ANIM_OPEN_PARMS;\n    alias MCI_ANIM_WINDOW_PARMSA MCI_ANIM_WINDOW_PARMS;\n    alias MCI_OVLY_OPEN_PARMSA MCI_OVLY_OPEN_PARMS;\n    alias MCI_OVLY_WINDOW_PARMSA MCI_OVLY_WINDOW_PARMS;\n    alias MCI_OVLY_SAVE_PARMSA MCI_OVLY_SAVE_PARMS;\n\n    alias sndPlaySoundA sndPlaySound;\n    alias PlaySoundA PlaySound;\n    alias waveOutGetDevCapsA waveOutGetDevCaps;\n    alias waveOutGetErrorTextA waveOutGetErrorText;\n    alias waveInGetDevCapsA waveInGetDevCaps;\n    alias waveInGetErrorTextA waveInGetErrorText;\n    alias midiOutGetDevCapsA midiOutGetDevCaps;\n    alias midiOutGetErrorTextA midiOutGetErrorText;\n    alias midiInGetDevCapsA midiInGetDevCaps;\n    alias midiInGetErrorTextA midiInGetErrorText;\n    alias auxGetDevCapsA auxGetDevCaps;\n    alias mixerGetDevCapsA mixerGetDevCaps;\n    alias mixerGetLineInfoA mixerGetLineInfo;\n    alias mixerGetLineControlsA mixerGetLineControls;\n    alias mixerGetControlDetailsA mixerGetControlDetails;\n    alias joyGetDevCapsA joyGetDevCaps;\n    alias mmioInstallIOProcA mmioInstallIOProc;\n    alias mmioStringToFOURCCA mmioStringToFOURCC;\n    alias mmioOpenA mmioOpen;\n    alias mmioRenameA mmioRename;\n    alias mciSendCommandA mciSendCommand;\n    alias mciSendStringA mciSendString;\n    alias mciGetDeviceIDA mciGetDeviceID;\n    alias mciGetDeviceIDFromElementIDA mciGetDeviceIDFromElementID;\n    alias mciGetErrorStringA mciGetErrorString;\n}\n\nalias WAVEOUTCAPS* PWAVEOUTCAPS, LPWAVEOUTCAPS;\nalias WAVEINCAPS* PWAVEINCAPS, LPWAVEINCAPS;\nalias MIDIOUTCAPS* PMIDIOUTCAPS, LPMIDIOUTCAPS;\nalias MIDIINCAPS* PMIDIINCAPS, LPMIDIINCAPS;\nalias AUXCAPS* PAUXCAPS, LPAUXCAPS;\nalias MIXERCAPS* PMIXERCAPS, LPMIXERCAPS;\nalias MIXERLINE* PMIXERLINE, LPMIXERLINE;\nalias MIXERCONTROL* PMIXERCONTROL, LPMIXERCONTROL;\nalias MIXERLINECONTROLS* PMIXERLINECONTROLS, LPMIXERLINECONTROLS;\nalias MIXERCONTROLDETAILS_LISTTEXT* PMIXERCONTROLDETAILS_LISTTEXT, LPMIXERCONTROLDETAILS_LISTTEXT;\nalias JOYCAPS* PJOYCAPS, LPJOYCAPS;\nalias MCI_OPEN_PARMS* PMCI_OPEN_PARMS, LPMCI_OPEN_PARMS;\nalias MCI_INFO_PARMS* LPMCI_INFO_PARMS;\nalias MCI_SYSINFO_PARMS* PMCI_SYSINFO_PARMS, LPMCI_SYSINFO_PARMS;\nalias MCI_SAVE_PARMS* PMCI_SAVE_PARMS, LPMCI_SAVE_PARMS;\nalias MCI_LOAD_PARMS* PMCI_LOAD_PARMS, LPMCI_LOAD_PARMS;\nalias MCI_VD_ESCAPE_PARMS* PMCI_VD_ESCAPE_PARMS, LPMCI_VD_ESCAPE_PARMS;\nalias MCI_WAVE_OPEN_PARMS* PMCI_WAVE_OPEN_PARMS, LPMCI_WAVE_OPEN_PARMS;\nalias MCI_ANIM_OPEN_PARMS* PMCI_ANIM_OPEN_PARMS, LPMCI_ANIM_OPEN_PARMS;\nalias MCI_ANIM_WINDOW_PARMS* PMCI_ANIM_WINDOW_PARMS, LPMCI_ANIM_WINDOW_PARMS;\nalias MCI_OVLY_OPEN_PARMS* PMCI_OVLY_OPEN_PARMS, LPMCI_OVLY_OPEN_PARMS;\nalias MCI_OVLY_WINDOW_PARMS* PMCI_OVLY_WINDOW_PARMS, LPMCI_OVLY_WINDOW_PARMS;\nalias MCI_OVLY_SAVE_PARMS* PMCI_OVLY_SAVE_PARMS, LPMCI_OVLY_SAVE_PARMS;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/msacm.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_msacm.d)\n */\nmodule core.sys.windows.msacm;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.basetsd, core.sys.windows.mmsystem, core.sys.windows.windef;\n\nmixin DECLARE_HANDLE!(\"HACMDRIVERID\");\nmixin DECLARE_HANDLE!(\"HACMDRIVER\");\nalias HACMDRIVER* LPHACMDRIVER;\n\nenum size_t\n    ACMDRIVERDETAILS_SHORTNAME_CHARS =  32,\n    ACMDRIVERDETAILS_LONGNAME_CHARS  = 128,\n    ACMDRIVERDETAILS_COPYRIGHT_CHARS =  80,\n    ACMDRIVERDETAILS_LICENSING_CHARS = 128,\n    ACMDRIVERDETAILS_FEATURES_CHARS  = 512;\n\nenum size_t\n    ACMFORMATDETAILS_FORMAT_CHARS       = 128,\n    ACMFORMATTAGDETAILS_FORMATTAG_CHARS = 48;\n\nalign(1):\n\nstruct ACMFORMATDETAILSA {\n    DWORD          cbStruct = ACMFORMATDETAILSA.sizeof;\n    DWORD          dwFormatIndex;\n    DWORD          dwFormatTag;\n    DWORD          fdwSupport;\n    LPWAVEFORMATEX pwfx;\n    DWORD          cbwfx;\n    char[ACMFORMATDETAILS_FORMAT_CHARS] szFormat;\n}\nalias ACMFORMATDETAILSA* LPACMFORMATDETAILSA;\n\nstruct ACMFORMATDETAILSW {\n    DWORD          cbStruct = ACMFORMATDETAILSW.sizeof;\n    DWORD          dwFormatIndex;\n    DWORD          dwFormatTag;\n    DWORD          fdwSupport;\n    LPWAVEFORMATEX pwfx;\n    DWORD          cbwfx;\n    WCHAR[ACMFORMATDETAILS_FORMAT_CHARS] szFormat;\n}\nalias ACMFORMATDETAILSW* LPACMFORMATDETAILSW;\n\nstruct ACMFORMATTAGDETAILSA {\n    DWORD cbStruct = ACMFORMATTAGDETAILSA.sizeof;\n    DWORD dwFormatTagIndex;\n    DWORD dwFormatTag;\n    DWORD cbFormatSize;\n    DWORD fdwSupport;\n    DWORD cStandardFormats;\n    char[ACMFORMATTAGDETAILS_FORMATTAG_CHARS] szFormatTag;\n}\nalias ACMFORMATTAGDETAILSA* LPACMFORMATTAGDETAILSA;\n\nstruct ACMFORMATTAGDETAILSW {\n    DWORD cbStruct = ACMFORMATTAGDETAILSW.sizeof;\n    DWORD dwFormatTagIndex;\n    DWORD dwFormatTag;\n    DWORD cbFormatSize;\n    DWORD fdwSupport;\n    DWORD cStandardFormats;\n    WCHAR[ACMFORMATTAGDETAILS_FORMATTAG_CHARS] szFormatTag;\n}\nalias ACMFORMATTAGDETAILSW* LPACMFORMATTAGDETAILSW;\n\nstruct ACMDRIVERDETAILSA {\nalign(1):\n    DWORD  cbStruct = ACMDRIVERDETAILSA.sizeof;\n    FOURCC fccType;\n    FOURCC fccComp;\n    WORD   wMid;\n    WORD   wPid;\n    DWORD  vdwACM;\n    DWORD  vdwDriver;\n    DWORD  fdwSupport;\n    DWORD  cFormatTags;\n    DWORD  cFilterTags;\n    HICON  hicon;\n    char[ACMDRIVERDETAILS_SHORTNAME_CHARS] szShortName;\n    char[ACMDRIVERDETAILS_LONGNAME_CHARS]  szLongName;\n    char[ACMDRIVERDETAILS_COPYRIGHT_CHARS] szCopyright;\n    char[ACMDRIVERDETAILS_LICENSING_CHARS] szLicensing;\n    char[ACMDRIVERDETAILS_FEATURES_CHARS]  szFeatures;\n}\nalias ACMDRIVERDETAILSA* LPACMDRIVERDETAILSA;\n\nstruct ACMDRIVERDETAILSW {\nalign(1):\n    DWORD  cbStruct = ACMDRIVERDETAILSW.sizeof;\n    FOURCC fccType;\n    FOURCC fccComp;\n    WORD   wMid;\n    WORD   wPid;\n    DWORD  vdwACM;\n    DWORD  vdwDriver;\n    DWORD  fdwSupport;\n    DWORD  cFormatTags;\n    DWORD  cFilterTags;\n    HICON  hicon;\n    WCHAR[ACMDRIVERDETAILS_SHORTNAME_CHARS] szShortName;\n    WCHAR[ACMDRIVERDETAILS_LONGNAME_CHARS]  szLongName;\n    WCHAR[ACMDRIVERDETAILS_COPYRIGHT_CHARS] szCopyright;\n    WCHAR[ACMDRIVERDETAILS_LICENSING_CHARS] szLicensing;\n    WCHAR[ACMDRIVERDETAILS_FEATURES_CHARS]  szFeatures;\n}\nalias ACMDRIVERDETAILSW* LPACMDRIVERDETAILSW;\n\nextern (Windows) {\n    alias BOOL function(HACMDRIVERID hadid, LPACMFORMATDETAILSA pafd,\n      DWORD_PTR dwInstance, DWORD fdwSupport) ACMFORMATENUMCBA;\n    alias BOOL function(HACMDRIVERID hadid, LPACMFORMATDETAILSW pafd,\n      DWORD_PTR dwInstance, DWORD fdwSupport) ACMFORMATENUMCBW;\n    alias BOOL function(HACMDRIVERID hadid, LPACMFORMATTAGDETAILSA paftd,\n      DWORD_PTR dwInstance, DWORD fdwSupport) ACMFORMATTAGENUMCBA;\n    alias BOOL function(HACMDRIVERID hadid, LPACMFORMATTAGDETAILSW paftd,\n      DWORD_PTR dwInstance, DWORD fdwSupport) ACMFORMATTAGENUMCBW;\n    alias BOOL function(HACMDRIVERID hadid, DWORD_PTR dwInstance,\n      DWORD fdwSupport) ACMDRIVERENUMCB;\n\n    MMRESULT acmDriverOpen(LPHACMDRIVER phad, HACMDRIVERID hadid,\n      DWORD fdwOpen);\n    MMRESULT acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD_PTR dwInstance,\n      DWORD fdwEnum);\n    MMRESULT acmFormatEnumA(HACMDRIVER had, LPACMFORMATDETAILSA pafd,\n      ACMFORMATENUMCBA fnCallback, DWORD_PTR dwInstance, DWORD fdwEnum);\n    MMRESULT acmFormatEnumW(HACMDRIVER had, LPACMFORMATDETAILSW pafd,\n      ACMFORMATENUMCBW fnCallback, DWORD_PTR dwInstance, DWORD fdwEnum);\n    MMRESULT acmDriverClose(HACMDRIVER had, DWORD fdwClose);\n    MMRESULT acmDriverDetailsA(HACMDRIVERID hadid, LPACMDRIVERDETAILSA padd,\n      DWORD fdwDetails);\n    MMRESULT acmDriverDetailsW(HACMDRIVERID hadid, LPACMDRIVERDETAILSW padd,\n      DWORD fdwDetails);\n    MMRESULT acmFormatTagEnumA(HACMDRIVER had, LPACMFORMATTAGDETAILSA paftd,\n      ACMFORMATTAGENUMCBA fnCallback, DWORD_PTR dwInstance, DWORD fdwEnum);\n    MMRESULT acmFormatTagEnumW(HACMDRIVER had, LPACMFORMATTAGDETAILSW paftd,\n      ACMFORMATTAGENUMCBW fnCallback, DWORD_PTR dwInstance, DWORD fdwEnum);\n}\n\nversion (Unicode) {\n    alias ACMFORMATDETAILSW ACMFORMATDETAILS;\n    alias ACMFORMATTAGDETAILSW ACMFORMATTAGDETAILS;\n    alias ACMDRIVERDETAILSW ACMDRIVERDETAILS;\n    alias ACMFORMATENUMCBW ACMFORMATENUMCB;\n    alias ACMFORMATTAGENUMCBW ACMFORMATTAGENUMCB;\n    alias acmFormatEnumW acmFormatEnum;\n    alias acmDriverDetailsW acmDriverDetails;\n    alias acmFormatTagEnumW acmFormatTagEnum;\n} else {\n    alias ACMFORMATDETAILSA ACMFORMATDETAILS;\n    alias ACMFORMATTAGDETAILSA ACMFORMATTAGDETAILS;\n    alias ACMDRIVERDETAILSA ACMDRIVERDETAILS;\n    alias ACMFORMATENUMCBA ACMFORMATENUMCB;\n    alias ACMFORMATTAGENUMCBA ACMFORMATTAGENUMCB;\n    alias acmFormatEnumA acmFormatEnum;\n    alias acmDriverDetailsA acmDriverDetails;\n    alias acmFormatTagEnumA acmFormatTagEnum;\n}\n\nalias ACMFORMATDETAILS* LPACMFORMATDETAILS;\nalias ACMFORMATTAGDETAILS* LPACMFORMATTAGDETAILS;\nalias ACMDRIVERDETAILS* LPACMDRIVERDETAILS;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/mshtml.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_mshtml.d)\n */\nmodule core.sys.windows.mshtml;\nversion (Windows):\n\nprivate import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.unknwn,\n  core.sys.windows.windef, core.sys.windows.wtypes;\n\n// These are used in this file, but not defined in MinGW.\ninterface IHTMLStyleSheet {};\nalias IHTMLStyle LPHTMLSTYLE;\nalias IHTMLStyleSheet LPHTMLSTYLESHEET;\ninterface IHTMLLocation {};\nalias IHTMLLocation LPHTMLLOCATION;\ninterface IHTMLFramesCollection {};\nalias IHTMLFramesCollection LPHTMLFRAMESCOLLECTION;\ninterface IHTMLStyleSheetsCollection {};\nalias IHTMLStyleSheetsCollection LPHTMLSTYLESHEETSCOLLECTION;\ninterface IHTMLStyle {};\ninterface IHTMLFiltersCollection {};\nalias IHTMLFiltersCollection LPHTMLFILTERSCOLLECTION;\ninterface IOmHistory : IDispatch {\n    HRESULT get_length(short* p);\n    HRESULT back(VARIANT*);\n    HRESULT forward(VARIANT*);\n    HRESULT go(VARIANT*);\n};\nalias IOmHistory LPOMHISTORY;\ninterface IOmNavigator {};\nalias IOmNavigator LPOMNAVIGATOR;\ninterface IHTMLImageElementFactory {};\nalias IHTMLImageElementFactory LPHTMLIMAGEELEMENTFACTORY;\ninterface IHTMLEventObj {};\nalias IHTMLEventObj LPHTMLEVENTOBJ;\ninterface IHTMLScreen {};\nalias IHTMLScreen LPHTMLSCREEN;\ninterface IHTMLOptionElementFactory {};\nalias IHTMLOptionElementFactory LPHTMLOPTIONELEMENTFACTORY;\n\ninterface IHTMLLinkElement : IDispatch {\n    HRESULT put_href(BSTR);\n    HRESULT get_href(BSTR*);\n    HRESULT put_rel(BSTR);\n    HRESULT get_rel(BSTR*);\n    HRESULT put_rev(BSTR);\n    HRESULT get_rev(BSTR*);\n    HRESULT put_type(BSTR);\n    HRESULT get_type(BSTR*);\n    HRESULT get_readyState(BSTR*);\n    HRESULT put_onreadystatechange(VARIANT);\n    HRESULT get_onreadystatechange(VARIANT*);\n    HRESULT put_onload(VARIANT);\n    HRESULT get_onload(VARIANT*);\n    HRESULT put_onerror(VARIANT);\n    HRESULT get_onerror(VARIANT*);\n    HRESULT get_styleSheet(LPHTMLSTYLESHEET*);\n    HRESULT put_disabled(VARIANT_BOOL);\n    HRESULT get_disabled(VARIANT_BOOL*);\n    HRESULT put_media(BSTR);\n    HRESULT get_media(BSTR*);\n}\nalias IHTMLLinkElement LPHTMLLINKELEMENT;\n\ninterface IHTMLImgElement : IDispatch {\n    HRESULT put_isMap(VARIANT_BOOL);\n    HRESULT get_isMap(VARIANT_BOOL*);\n    HRESULT put_useMap(BSTR);\n    HRESULT get_useMap(BSTR*);\n    HRESULT get_mimeType(BSTR*);\n    HRESULT get_fileSize(BSTR*);\n    HRESULT get_fileCreatedDate(BSTR*);\n    HRESULT get_fileModifiedDate(BSTR*);\n    HRESULT get_fileUpdatedDate(BSTR*);\n    HRESULT get_protocol(BSTR*);\n    HRESULT get_href(BSTR*);\n    HRESULT get_nameProp(BSTR*);\n    HRESULT put_border(VARIANT);\n    HRESULT get_border(VARIANT*);\n    HRESULT put_vspace(LONG);\n    HRESULT get_vspace(LONG*);\n    HRESULT put_hspace(LONG);\n    HRESULT get_hspace(LONG*);\n    HRESULT put_alt(BSTR);\n    HRESULT get_alt(BSTR*);\n    HRESULT put_src(BSTR);\n    HRESULT get_src(BSTR*);\n    HRESULT put_lowsrc(BSTR);\n    HRESULT get_lowsrc(BSTR*);\n    HRESULT put_vrml(BSTR);\n    HRESULT get_vrml(BSTR*);\n    HRESULT put_dynsrc(BSTR);\n    HRESULT get_dynsrc(BSTR*);\n    HRESULT get_readyState(BSTR*);\n    HRESULT get_complete(VARIANT_BOOL*);\n    HRESULT put_loop(VARIANT);\n    HRESULT get_loop(VARIANT*);\n    HRESULT put_align(BSTR);\n    HRESULT get_align(BSTR*);\n    HRESULT put_onload(VARIANT);\n    HRESULT get_onload(VARIANT*);\n    HRESULT put_onerror(VARIANT);\n    HRESULT get_onerror(VARIANT*);\n    HRESULT put_onabort(VARIANT);\n    HRESULT get_onabort(VARIANT*);\n    HRESULT put_name(BSTR);\n    HRESULT get_name(BSTR*);\n    HRESULT put_width(LONG);\n    HRESULT get_width(LONG*);\n    HRESULT put_height(LONG);\n    HRESULT get_height(LONG*);\n    HRESULT put_start(BSTR);\n    HRESULT get_start(BSTR*);\n}\nalias IHTMLImgElement LPHTMLIMGELEMENT;\n\ninterface IHTMLElementCollection : IDispatch {\n    HRESULT toString(BSTR*);\n    HRESULT put_length(LONG);\n    HRESULT get_length(LONG*);\n    HRESULT get__newEnum(IUnknown*);\n    HRESULT item(VARIANT,VARIANT,IDispatch* pDisp);\n    HRESULT tags(VARIANT,IDispatch* pdisp);\n}\nalias IHTMLElementCollection LPHTMLELEMENTCOLLECTION;\n\ninterface IHTMLDocument : IDispatch {\n    HRESULT get_Script(IDispatch*);\n}\n\ninterface IHTMLDocument2 : IHTMLDocument {\n    HRESULT get_all(LPHTMLELEMENTCOLLECTION*);\n    HRESULT get_body(LPHTMLELEMENT*);\n    HRESULT get_activeElement(LPHTMLELEMENT*);\n    HRESULT get_images(LPHTMLELEMENTCOLLECTION*);\n    HRESULT get_applets(LPHTMLELEMENTCOLLECTION*);\n    HRESULT get_links(LPHTMLELEMENTCOLLECTION*);\n    HRESULT get_forms(LPHTMLELEMENTCOLLECTION*);\n    HRESULT get_anchors(LPHTMLELEMENTCOLLECTION*);\n    HRESULT put_title(BSTR);\n    HRESULT get_title(BSTR*);\n    HRESULT get_scripts(LPHTMLELEMENTCOLLECTION*);\n    HRESULT put_designMode(BSTR);\n    HRESULT get_designMode(BSTR*);\n    HRESULT get_selection(LPHTMLSELECTIONOBJECT*);\n    HRESULT get_readyState(BSTR*);\n    HRESULT get_frames(IHTMLFramesCollection2*);\n    HRESULT get_embeds(LPHTMLELEMENTCOLLECTION*);\n    HRESULT get_plugins(LPHTMLELEMENTCOLLECTION*);\n    HRESULT put_alinkColor(VARIANT);\n    HRESULT get_alinkColor(VARIANT*);\n    HRESULT put_bgColor(VARIANT);\n    HRESULT get_bgColor(VARIANT*);\n    HRESULT put_fgColor(VARIANT);\n    HRESULT get_fgColor(VARIANT*);\n    HRESULT put_linkColor(VARIANT);\n    HRESULT get_linkColor(VARIANT*);\n    HRESULT put_vlinkColor(VARIANT);\n    HRESULT get_vlinkColor(VARIANT*);\n    HRESULT get_referrer(BSTR*);\n    HRESULT get_location(LPHTMLLOCATION*);\n    HRESULT get_lastModified(BSTR*);\n    HRESULT put_url(BSTR);\n    HRESULT get_url(BSTR*);\n    HRESULT put_domain(BSTR);\n    HRESULT get_domain(BSTR*);\n    HRESULT put_cookie(BSTR);\n    HRESULT get_cookie(BSTR*);\n    HRESULT put_expands(VARIANT_BOOL);\n    HRESULT get_expands(VARIANT_BOOL*);\n    HRESULT put_charset(BSTR);\n    HRESULT get_charset(BSTR*);\n    HRESULT put_defaultCharset(BSTR);\n    HRESULT get_defaultCharset(BSTR*);\n    HRESULT get_mimeType(BSTR*);\n    HRESULT get_fileSize(BSTR*);\n    HRESULT get_fileCreatedDate(BSTR*);\n    HRESULT get_fileModifiedDate(BSTR*);\n    HRESULT get_fileUpdatedDate(BSTR*);\n    HRESULT get_security(BSTR*);\n    HRESULT get_protocol(BSTR*);\n    HRESULT get_nameProp(BSTR*);\n    HRESULT write(SAFEARRAY*);\n    HRESULT writeln(SAFEARRAY*);\n    HRESULT open(BSTR,VARIANT,VARIANT,VARIANT,IDispatch*);\n    HRESULT close();\n    HRESULT clear();\n    HRESULT queryCommandSupported(BSTR,VARIANT_BOOL*);\n    HRESULT queryCommandEnabled(BSTR,VARIANT_BOOL*);\n    HRESULT queryCommandState(BSTR,VARIANT_BOOL*);\n    HRESULT queryCommandIndeterm(BSTR,VARIANT_BOOL*);\n    HRESULT queryCommandText(BSTR,BSTR*);\n    HRESULT queryCommandValue(BSTR,VARIANT*);\n    HRESULT execCommand(BSTR,VARIANT_BOOL,VARIANT,VARIANT_BOOL*);\n    HRESULT execCommandShowHelp(BSTR,VARIANT_BOOL*);\n    HRESULT createElement(BSTR,LPHTMLELEMENT*);\n    HRESULT put_onhelp(VARIANT);\n    HRESULT get_onhelp(VARIANT*);\n    HRESULT put_onclick(VARIANT);\n    HRESULT get_onclick(VARIANT*);\n    HRESULT put_ondblclick(VARIANT);\n    HRESULT get_ondblclick(VARIANT*);\n    HRESULT put_onkeyup(VARIANT);\n    HRESULT get_onkeyup(VARIANT*);\n    HRESULT put_onkeydown(VARIANT);\n    HRESULT get_onkeydown(VARIANT*);\n    HRESULT put_onkeypress(VARIANT);\n    HRESULT get_onkeypress(VARIANT*);\n    HRESULT put_onmouseup(VARIANT);\n    HRESULT get_onmouseup(VARIANT*);\n    HRESULT put_onmousedown(VARIANT);\n    HRESULT get_onmousedown(VARIANT*);\n    HRESULT put_onmousemove(VARIANT);\n    HRESULT get_onmousemove(VARIANT*);\n    HRESULT put_onmouseout(VARIANT);\n    HRESULT get_onmouseout(VARIANT*);\n    HRESULT put_onmouseover(VARIANT);\n    HRESULT get_onmouseover(VARIANT*);\n    HRESULT put_onreadystatechange(VARIANT);\n    HRESULT get_onreadystatechange(VARIANT*);\n    HRESULT put_onafterupdate(VARIANT);\n    HRESULT get_onafterupdate(VARIANT*);\n    HRESULT put_onrowexit(VARIANT);\n    HRESULT get_onrowexit(VARIANT*);\n    HRESULT put_onrowenter(VARIANT);\n    HRESULT get_onrowenter(VARIANT*);\n    HRESULT put_ondragstart(VARIANT);\n    HRESULT get_ondragstart(VARIANT*);\n    HRESULT put_onselectstart(VARIANT);\n    HRESULT get_onselectstart(VARIANT*);\n    HRESULT elementFromPoint(LONG,LONG,LPHTMLELEMENT*);\n    HRESULT get_parentWindow(LPHTMLWINDOW2*);\n    HRESULT get_styleSheets(LPHTMLSTYLESHEETSCOLLECTION*);\n    HRESULT put_onbeforeupdate(VARIANT);\n    HRESULT get_onbeforeupdate(VARIANT*);\n    HRESULT put_onerrorupdate(VARIANT);\n    HRESULT get_onerrorupdate(VARIANT*);\n    HRESULT toString(BSTR*);\n    HRESULT createStyleSheet(BSTR,LONG,LPHTMLSTYLESHEET*);\n}\n\ninterface IHTMLSelectionObject : IDispatch {\n    HRESULT createRange(IDispatch*);\n    HRESULT empty();\n    HRESULT clear();\n    HRESULT get_type(BSTR*);\n}\nalias IHTMLSelectionObject LPHTMLSELECTIONOBJECT;\n\ninterface IHTMLTxtRange : IDispatch {\n    HRESULT get_htmlText(BSTR*);\n    HRESULT put_text(BSTR);\n    HRESULT get_text(BSTR*);\n    HRESULT parentElement(LPHTMLELEMENT*);\n    HRESULT duplicate(IHTMLTxtRange*);\n    HRESULT inRange(IHTMLTxtRange,VARIANT_BOOL*);\n    HRESULT isEqual(IHTMLTxtRange,VARIANT_BOOL*);\n    HRESULT scrollIntoView(VARIANT_BOOL);\n    HRESULT collapse(VARIANT_BOOL);\n    HRESULT expand(BSTR,VARIANT_BOOL*);\n    HRESULT move(BSTR,LONG,LONG*);\n    HRESULT moveStart(BSTR,LONG,LONG*);\n    HRESULT moveEnd(BSTR,LONG,LONG*);\n    HRESULT select();\n    HRESULT pasteHTML(BSTR);\n    HRESULT moveToElementText(LPHTMLELEMENT);\n    HRESULT setEndPoint(BSTR,IHTMLTxtRange);\n    HRESULT compareEndPoints(BSTR,IHTMLTxtRange,LONG*);\n    HRESULT findText(BSTR,LONG,LONG,VARIANT_BOOL*);\n    HRESULT moveToPoint(LONG,LONG);\n    HRESULT getBookmark(BSTR*);\n    HRESULT moveToBookbark(BSTR,VARIANT_BOOL*);\n    HRESULT queryCommandSupported(BSTR,VARIANT_BOOL*);\n    HRESULT queryCommandEnabled(BSTR,VARIANT_BOOL*);\n    HRESULT queryCommandState(BSTR,VARIANT_BOOL*);\n    HRESULT queryCommandIndeterm(BSTR,VARIANT_BOOL*);\n    HRESULT queryCommandText(BSTR,BSTR*);\n    HRESULT queryCommandValue(BSTR,VARIANT*);\n    HRESULT execCommand(BSTR,VARIANT_BOOL,VARIANT,VARIANT_BOOL*);\n    HRESULT execCommandShowHelp(BSTR,VARIANT_BOOL*);\n}\n\ninterface IHTMLElement : IDispatch {\n    HRESULT setAttribute(BSTR,VARIANT,LONG);\n    HRESULT getAttribute(BSTR,LONG,VARIANT*);\n    HRESULT removeAttribute(BSTR,LONG,VARIANT_BOOL*);\n    HRESULT put_className(BSTR);\n    HRESULT get_className(BSTR*);\n    HRESULT put_id(BSTR);\n    HRESULT get_id(BSTR*);\n    HRESULT get_tagName(BSTR*);\n    HRESULT get_parentElement(LPHTMLELEMENT*);\n    HRESULT get_style(LPHTMLSTYLE*);\n    HRESULT put_onhelp(VARIANT);\n    HRESULT get_onhelp(VARIANT*);\n    HRESULT put_onclick(VARIANT);\n    HRESULT get_onclick(VARIANT*);\n    HRESULT put_ondblclick(VARIANT);\n    HRESULT get_ondblclick(VARIANT*);\n    HRESULT put_onkeydown(VARIANT);\n    HRESULT get_onkeydown(VARIANT*);\n    HRESULT put_onkeyup(VARIANT);\n    HRESULT get_onkeyup(VARIANT*);\n    HRESULT put_onkeypress(VARIANT);\n    HRESULT get_onkeypress(VARIANT*);\n    HRESULT put_onmouseout(VARIANT);\n    HRESULT get_onmouseout(VARIANT*);\n    HRESULT put_onmouseover(VARIANT);\n    HRESULT get_onmouseover(VARIANT*);\n    HRESULT put_onmousemove(VARIANT);\n    HRESULT get_onmousemove(VARIANT*);\n    HRESULT put_onmousedown(VARIANT);\n    HRESULT get_onmousedown(VARIANT*);\n    HRESULT put_onmouseup(VARIANT);\n    HRESULT get_onmouseup(VARIANT*);\n    HRESULT get_document(IDispatch*);\n    HRESULT put_title(BSTR);\n    HRESULT get_title(BSTR*);\n    HRESULT put_language(BSTR);\n    HRESULT get_language(BSTR*);\n    HRESULT put_onselectstart(VARIANT);\n    HRESULT get_onselectstart(VARIANT*);\n    HRESULT scrollIntoView(VARIANT);\n    HRESULT contains(LPHTMLELEMENT,VARIANT_BOOL*);\n    HRESULT get_source3Index(LONG*);\n    HRESULT get_recordNumber(VARIANT*);\n    HRESULT put_lang(BSTR);\n    HRESULT get_lang(BSTR*);\n    HRESULT get_offsetLeft(LONG*);\n    HRESULT get_offsetTop(LONG*);\n    HRESULT get_offsetWidth(LONG*);\n    HRESULT get_offsetHeight(LONG*);\n    HRESULT get_offsetParent(LPHTMLELEMENT*);\n    HRESULT put_innerHTML(BSTR);\n    HRESULT get_innerHTML(BSTR*);\n    HRESULT put_innerText(BSTR);\n    HRESULT get_innerText(BSTR*);\n    HRESULT put_outerHTML(BSTR);\n    HRESULT get_outerHTML(BSTR*);\n    HRESULT put_outerText(BSTR);\n    HRESULT get_outerText(BSTR*);\n    HRESULT insertAdjacentHTML(BSTR,BSTR);\n    HRESULT insertAdjacentText(BSTR,BSTR);\n    HRESULT get_parentTextEdit(LPHTMLELEMENT*);\n    HRESULT isTextEdit(VARIANT_BOOL*);\n    HRESULT click();\n    HRESULT get_filters(LPHTMLFILTERSCOLLECTION*);\n    HRESULT put_ondragstart(VARIANT);\n    HRESULT get_ondragstart(VARIANT*);\n    HRESULT toString(BSTR*);\n    HRESULT put_onbeforeupdate(VARIANT);\n    HRESULT get_onbeforeupdate(VARIANT*);\n    HRESULT put_onafterupdate(VARIANT);\n    HRESULT get_onafterupdate(VARIANT*);\n    HRESULT put_onerrorupdate(VARIANT);\n    HRESULT get_onerrorupdate(VARIANT*);\n    HRESULT put_onrowexit(VARIANT);\n    HRESULT get_onrowexit(VARIANT*);\n    HRESULT put_onrowenter(VARIANT);\n    HRESULT get_onrowenter(VARIANT*);\n    HRESULT put_ondatasetchanged(VARIANT);\n    HRESULT get_ondatasetchanged(VARIANT*);\n    HRESULT put_ondataavailable(VARIANT);\n    HRESULT get_ondataavailable(VARIANT*);\n    HRESULT put_ondatasetcomplete(VARIANT);\n    HRESULT get_ondatasetcomplete(VARIANT*);\n    HRESULT put_onfilterchange(VARIANT);\n    HRESULT get_onfilterchange(VARIANT*);\n    HRESULT get_children(IDispatch*);\n    HRESULT get_all(IDispatch*);\n}\nalias IHTMLElement LPHTMLELEMENT;\n\ninterface IHTMLFramesCollection2 : IDispatch {\n    HRESULT item(VARIANT*,VARIANT*);\n    HRESULT get_length(LONG*);\n}\n\ninterface IHTMLWindow2 : IHTMLFramesCollection2 {\n    HRESULT get_frames(IHTMLFramesCollection2*);\n    HRESULT put_defaultStatus(BSTR);\n    HRESULT get_defaultStatus(BSTR*);\n    HRESULT put_status(BSTR);\n    HRESULT get_status(BSTR*);\n    HRESULT setTimeout(BSTR,LONG,VARIANT*,LONG*);\n    HRESULT clearTimeout(LONG);\n    HRESULT alert(BSTR);\n    HRESULT confirm(BSTR,VARIANT_BOOL*);\n    HRESULT prompt(BSTR,BSTR,VARIANT*);\n    HRESULT get_Image(LPHTMLIMAGEELEMENTFACTORY*);\n    HRESULT get_location(LPHTMLLOCATION*);\n    HRESULT get_history(LPOMHISTORY*);\n    HRESULT close();\n    HRESULT put_opener(VARIANT);\n    HRESULT get_opener(VARIANT*);\n    HRESULT get_navigator(LPOMNAVIGATOR*);\n    HRESULT put_name(BSTR);\n    HRESULT get_name(BSTR*);\n    HRESULT get_parent(LPHTMLWINDOW2*);\n    HRESULT open(BSTR,BSTR,BSTR,VARIANT_BOOL,LPHTMLWINDOW2*);\n    HRESULT get_self(LPHTMLWINDOW2*);\n    HRESULT get_top(LPHTMLWINDOW2*);\n    HRESULT get_window(LPHTMLWINDOW2*);\n    HRESULT navigate(BSTR);\n    HRESULT put_onfocus(VARIANT);\n    HRESULT get_onfocus(VARIANT*);\n    HRESULT put_onblur(VARIANT);\n    HRESULT get_onblur(VARIANT*);\n    HRESULT put_onload(VARIANT);\n    HRESULT get_onload(VARIANT*);\n    HRESULT put_onbeforeunload(VARIANT);\n    HRESULT get_onbeforeunload(VARIANT*);\n    HRESULT put_onunload(VARIANT);\n    HRESULT get_onunload(VARIANT*);\n    HRESULT put_onhelp(VARIANT);\n    HRESULT get_onhelp(VARIANT*);\n    HRESULT put_onerror(VARIANT);\n    HRESULT get_onerror(VARIANT*);\n    HRESULT put_onresize(VARIANT);\n    HRESULT get_onresize(VARIANT*);\n    HRESULT put_onscroll(VARIANT);\n    HRESULT get_onscroll(VARIANT*);\n    HRESULT get_document(IHTMLDocument2*);\n    HRESULT get_event(LPHTMLEVENTOBJ*);\n    HRESULT get__newEnum(IUnknown*);\n    HRESULT showModalDialog(BSTR,VARIANT*,VARIANT*,VARIANT*);\n    HRESULT showHelp(BSTR,VARIANT,BSTR);\n    HRESULT get_screen(LPHTMLSCREEN*);\n    HRESULT get_Option(LPHTMLOPTIONELEMENTFACTORY*);\n    HRESULT focus();\n    HRESULT get_closed(VARIANT_BOOL*);\n    HRESULT blur();\n    HRESULT scroll(long,long);\n    HRESULT get_clientInformation(LPOMNAVIGATOR*);\n    HRESULT setInterval(BSTR,long,VARIANT*,long*);\n    HRESULT clearInterval(long);\n    HRESULT put_offscreenBuffering(VARIANT);\n    HRESULT get_offscreenBuffering(VARIANT*);\n    HRESULT execScript(BSTR,BSTR,VARIANT*);\n    HRESULT toString(BSTR*);\n    HRESULT scrollBy(LONG,LONG);\n    HRESULT scrollTo(LONG,LONG);\n    HRESULT moveTo(LONG,LONG);\n    HRESULT moveBy(LONG,LONG);\n    HRESULT resizeTo(LONG,LONG);\n    HRESULT resizeBy(LONG,LONG);\n    HRESULT get_external(IDispatch*);\n}\nalias IHTMLWindow2 LPHTMLWINDOW2;\n\ninterface IHTMLFrameBase : IDispatch {\n    HRESULT put_src(BSTR);\n    HRESULT get_src(BSTR*);\n    HRESULT put_name(BSTR);\n    HRESULT get_name(BSTR*);\n    HRESULT put_border(VARIANT);\n    HRESULT get_border(VARIANT*);\n    HRESULT put_frameBorder(BSTR);\n    HRESULT get_frameBorder(BSTR*);\n    HRESULT put_frameSpacing(VARIANT);\n    HRESULT get_frameSpacing(VARIANT*);\n    HRESULT put_marginWidth(VARIANT);\n    HRESULT get_marginWidth(VARIANT*);\n    HRESULT put_marginHeight(VARIANT);\n    HRESULT get_marginHeight(VARIANT*);\n    HRESULT put_noResize(VARIANT_BOOL);\n    HRESULT get_noResize(VARIANT_BOOL*);\n    HRESULT put_scrolling(BSTR);\n    HRESULT get_scrolling(BSTR*);\n}\n\ninterface IHTMLFrameBase2 : IDispatch {\n    HRESULT get_contentWindow(IHTMLWindow2*);\n    HRESULT put_onload(VARIANT);\n    HRESULT get_onload(VARIANT*);\n    HRESULT put_onreadystatechange(VARIANT);\n    HRESULT get_onreadystatechange(VARIANT*);\n    HRESULT get_readyState(BSTR*);\n    HRESULT put_allowTransparency(VARIANT_BOOL);\n    HRESULT get_allowTransparency(VARIANT_BOOL*);\n}\n\ninterface IHTMLFrameBase3 : IDispatch {\n    HRESULT put_longDesc(BSTR);\n    HRESULT get_longDesc(BSTR*);\n}\n\ninterface IHTMLBodyElement : IDispatch {\n    HRESULT put_background(BSTR);\n    HRESULT get_background(BSTR*);\n    HRESULT put_bgProperties(BSTR);\n    HRESULT get_bgProperties(BSTR*);\n    HRESULT put_leftMargin(VARIANT);\n    HRESULT get_leftMargin(VARIANT*);\n    HRESULT put_topMargin(VARIANT);\n    HRESULT get_topMargin(VARIANT*);\n    HRESULT put_rightMargin(VARIANT);\n    HRESULT get_rightMargin(VARIANT*);\n    HRESULT put_bottomMargin(VARIANT);\n    HRESULT get_bottomMargin(VARIANT*);\n    HRESULT put_noWrap(VARIANT_BOOL);\n    HRESULT get_noWrap(VARIANT_BOOL*);\n    HRESULT put_bgColor(VARIANT);\n    HRESULT get_bgColor(VARIANT*);\n    HRESULT put_text(VARIANT);\n    HRESULT get_text(VARIANT*);\n    HRESULT put_link(VARIANT);\n    HRESULT get_link(VARIANT*);\n    HRESULT put_vLink(VARIANT);\n    HRESULT get_vLink(VARIANT*);\n    HRESULT put_aLink(VARIANT);\n    HRESULT get_aLink(VARIANT*);\n    HRESULT put_onload(VARIANT);\n    HRESULT get_onload(VARIANT*);\n    HRESULT put_onunload(VARIANT);\n    HRESULT get_onunload(VARIANT*);\n    HRESULT put_scroll(BSTR);\n    HRESULT get_scroll(BSTR*);\n    HRESULT put_onselect(VARIANT);\n    HRESULT get_onselect(VARIANT*);\n    HRESULT put_onbeforeunload(VARIANT);\n    HRESULT get_onbeforeunload(VARIANT*);\n    HRESULT createTextRange(IHTMLTxtRange*);\n}\n\ninterface IHTMLBodyElement2 : IDispatch {\n    HRESULT put_onbeforeprint(VARIANT);\n    HRESULT get_onbeforeprint(VARIANT*);\n    HRESULT put_onafterprint(VARIANT);\n    HRESULT get_onafterprint(VARIANT*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/mswsock.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Daniel Keep\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_mswsock.d)\n */\nmodule core.sys.windows.mswsock;\nversion (Windows):\n\nimport core.sys.windows.winbase, core.sys.windows.windef;\nprivate import core.sys.windows.basetyps, core.sys.windows.w32api;\n\nimport core.sys.windows.winsock2;\n\n//static if (_WIN32_WINNT >= 0x500) {\n    enum {\n        /* WinNT5+:\n           ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/socket_options.htm */\n        SO_MAXDG             = 0x7009,\n        SO_MAXPATHDG         = 0x700A,\n    }\n//}\n\nenum {\n    /* WinNT4+:\n       ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/socket_options_for_windows_nt_4_0_2.htm */\n    SO_CONNDATA              = 0x7000,\n    SO_CONNOPT               = 0x7001,\n    SO_DISCDATA              = 0x7002,\n    SO_DISCOPT               = 0x7003,\n    SO_CONNDATALEN           = 0x7004,\n    SO_CONNOPTLEN            = 0x7005,\n    SO_DISCDATALEN           = 0x7006,\n    SO_DISCOPTLEN            = 0x7007,\n\n    /* WinNT4:\n       ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/socket_options.htm */\n    SO_UPDATE_ACCEPT_CONTENT = 0x700B,\n}\n\nenum {\n    /* Win95+, WinNT4+ but apparently shouldn't used: mark as deprecated?\n       ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/socket_options.htm */\n    SO_OPENTYPE                  = 0x7008,\n\n    /* Win95+; these two are passed to the SO_OPENTYPE option as arguments,\n       so would they be deprecated as well?\n       ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/socket_options.htm */\n    SO_SYNCHRONOUS_ALERT         = 0x0010,\n    SO_SYNCHRONOUS_NONALERT      = 0x0020,\n\n    /* Win95:\n       ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/socket_options.htm */\n    SO_CONNECT_TIME              = 0x700C,\n}\n\n\nenum {\n    TCP_BSDURGENT = 0x7000,\n}\n\n/* These *appear* to be constants for passing to the TransmitFile /\n   TransmitPackets functions, which are available in WinNT3.51+\n   ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/transmitfile_2.htm */\nenum {\n    TF_DISCONNECT         = 1,\n    TF_REUSE_SOCKET       = 2,\n    TF_WRITE_BEHIND       = 4,\n    TF_USE_DEFAULT_WORKER = 0,\n    TF_USE_SYSTEM_THREAD  = 16,\n    TF_USE_KERNEL_APC     = 32\n}\n\n/* Win95+, WinNT3.51+\n   ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/transmit_file_buffers_2.htm */\nstruct TRANSMIT_FILE_BUFFERS {\n    PVOID Head;\n    DWORD HeadLength;\n    PVOID Tail;\n    DWORD TailLength;\n}\nalias TRANSMIT_FILE_BUFFERS* PTRANSMIT_FILE_BUFFERS, LPTRANSMIT_FILE_BUFFERS;\n\nextern(Windows) {\n    /* Win95+, WinNT3.51+\n       ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/wsarecvex_2.htm */\n    int WSARecvEx(SOCKET, char*, int, int*);\n\n    /* Win95+, WinNT3.51+\n       ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/getacceptexSOCKADDRs_2.htm */\n    VOID GetAcceptExSockaddrs(PVOID, DWORD, DWORD, DWORD, SOCKADDR**, LPINT, SOCKADDR**, LPINT);\n\n    /* WinNT3.51+\n       ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/transmitfile_2.htm */\n    BOOL TransmitFile(SOCKET, HANDLE, DWORD, DWORD, LPOVERLAPPED, LPTRANSMIT_FILE_BUFFERS, DWORD);\n\n    /* WinNT3.51+\n       ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/acceptex_2.htm */\n    alias BOOL function(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED) LPFN_ACCEPTEX;\n    const GUID WSAID_ACCEPTEX = {0xb5367df1,0xcbac,0x11cf,[0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92]};\n\n    alias BOOL function(SOCKET, SOCKADDR*, int, PVOID, DWORD, LPDWORD, LPOVERLAPPED) LPFN_CONNECTEX;\n    const GUID WSAID_CONNECTEX = {0x25a207b9,0xddf3,0x4660,[0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e]};\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    /*  These appear to be constants for the TRANSMIT_PACKETS_ELEMENT\n     *  structure below, so I've given them the same minimum version\n     */\n    enum {\n        TP_ELEMENT_FILE   = 1,\n        TP_ELEMENT_MEMORY = 2,\n        TP_ELEMENT_EOP    = 4\n    }\n\n    /*  WinXP+, Srv2k3+\n     *  ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/transmit_packets_element_2.htm\n     */\n    struct TRANSMIT_PACKETS_ELEMENT {\n        ULONG dwElFlags;\n        ULONG cLength;\n        union {\n            struct {\n                LARGE_INTEGER nFileOffset;\n                HANDLE        hFile;\n            }\n            PVOID pBuffer;\n        }\n    }\n\n    struct WSABUF {\n        ULONG len;\n        CHAR* buf;\n    }\n\n    alias WSABUF* LPWSABUF;\n\n    /*  WinXP+, Server2003+:\n     *  ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/wsamsg_2.htm\n     */\n    struct WSAMSG {\n        LPSOCKADDR name;\n        INT        namelen;\n        LPWSABUF   lpBuffers;\n        DWORD      dwBufferCount;\n        WSABUF     Control;\n        DWORD      dwFlags;\n    }\n\n    alias WSAMSG* PWSAMSG, LPWSAMSG;\n\n    /* According to MSDN docs, the WSAMSG.Control buffer starts with a\n       cmsghdr header of the following form.  See also RFC 2292. */\n    /* DK: Confirmed.  So I suppose these should get the same version as\n       WSAMSG... */\n    struct WSACMSGHDR {\n        SIZE_T cmsg_len;\n        INT  cmsg_level;\n        INT  cmsg_type;\n        // followed by UCHAR cmsg_data[];\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    /* TODO: Standard Posix.1g macros as per RFC 2292, with WSA_uglification. */\n    /* DK: MinGW doesn't define these, and neither does the MSDN docs.  Might have\n       to actually look up RFC 2292... */\n    /+\n    #if 0\n    #define WSA_CMSG_FIRSTHDR(mhdr)\n    #define WSA_CMSG_NXTHDR(mhdr, cmsg)\n    #define WSA_CMSG_SPACE(length)\n    #define WSA_CMSG_LEN(length)\n    #endif\n    +/\n\n    /*  Win Vista+, Srv2k3+\n     *  ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/disconnectex_2.htm\n     */\n    extern(Windows) BOOL DisconnectEx(SOCKET, LPOVERLAPPED, DWORD, DWORD);\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    /*  WinXP+, Srv2k3+\n     *  ms-help://MS.MSDNQTR.2003FEB.1033/winsock/winsock/wsarecvmsg_2.htm\n     */\n    extern(Windows) int WSARecvMsg(SOCKET, LPWSAMSG, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/nb30.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_nb30.d)\n */\nmodule core.sys.windows.nb30;\nversion (Windows):\n\nprivate import core.sys.windows.windef;\n\nenum size_t\n    NCBNAMSZ =  16,\n    MAX_LANA = 254;\n\n// FIXME: are these really two sets of constants?\nenum : UCHAR {\n    REGISTERING     = 0,\n    REGISTERED      = 4,\n    DEREGISTERED,\n    DUPLICATE,\n    DUPLICATE_DEREG, // = 7\n    UNIQUE_NAME     = 0,\n    GROUP_NAME      = 0x80,\n    NAME_FLAGS_MASK = 0x87\n}\n\nenum : UCHAR {\n    LISTEN_OUTSTANDING = 1,\n    CALL_PENDING,\n    SESSION_ESTABLISHED,\n    HANGUP_PENDING,\n    HANGUP_COMPLETE,\n    SESSION_ABORTED // = 6\n}\n\nenum char[4]\n    ALL_TRANSPORTS = \"M\\0\\0\\0\",\n    MS_NBF         = \"MNBF\";\n\nenum : UCHAR {\n    NCBCALL        = 0x10,\n    NCBLISTEN,\n    NCBHANGUP,  // = 0x12\n    NCBSEND        = 0x14,\n    NCBRECV,\n    NCBRECVANY,\n    NCBCHAINSEND, // = 0x17\n    NCBDGSEND      = 0x20,\n    NCBDGRECV,\n    NCBDGSENDBC,\n    NCBDGRECVBC, // = 0x23,\n    NCBADDNAME     = 0x30,\n    NCBDELNAME,\n    NCBRESET,\n    NCBASTAT,\n    NCBSSTAT,\n    NCBCANCEL,\n    NCBADDGRNAME,\n    NCBENUM,    // = 0x37\n    NCBUNLINK      = 0x70,\n    NCBSENDNA,\n    NCBCHAINSENDNA,\n    NCBLANSTALERT, // = 0x73\n    NCBACTION      = 0x77,\n    NCBFINDNAME,\n    NCBTRACE    // = 0x79\n}\n\nenum UCHAR ASYNCH = 0x80;\n\nenum : UCHAR {\n    NRC_GOODRET     = 0x00,\n    NRC_BUFLEN      = 0x01,\n    NRC_ILLCMD      = 0x03,\n    NRC_CMDTMO      = 0x05,\n    NRC_INCOMP,\n    NRC_BADDR,\n    NRC_SNUMOUT,\n    NRC_NORES,\n    NRC_SCLOSED,\n    NRC_CMDCAN,  // = 0x0b\n    NRC_DUPNAME     = 0x0d,\n    NRC_NAMTFUL,\n    NRC_ACTSES,  // = 0x0f,\n    NRC_LOCTFUL     = 0x11,\n    NRC_REMTFUL,\n    NRC_ILLNN,\n    NRC_NOCALL,\n    NRC_NOWILD,\n    NRC_INUSE,\n    NRC_NAMERR,\n    NRC_SABORT,\n    NRC_NAMCONF, // = 0x19\n    NRC_IFBUSY      = 0x21,\n    NRC_TOOMANY,\n    NRC_BRIDGE,\n    NRC_CANOCCR, // = 0x24\n    NRC_CANCEL      = 0x26,\n    NRC_DUPENV      = 0x30,\n    NRC_ENVNOTDEF   = 0x34,\n    NRC_OSRESNOTAV,\n    NRC_MAXAPPS,\n    NRC_NOSAPS,\n    NRC_NORESOURCES,\n    NRC_INVADDRESS, // = 0x39\n    NRC_INVDDID     = 0x3B,\n    NRC_LOCKFAIL    = 0x3C,\n    NRC_OPENERR     = 0x3f,\n    NRC_SYSTEM      = 0x40,\n    NRC_PENDING     = 0xff\n}\n\nstruct ACTION_HEADER {\n    union {\n        /*  transport_id is defined as a ULONG, but both the above constants\n         *  and the documented description suggest it should be a char[4]\n         */\n        ULONG   transport_id;\n        char[4] c_transport_id;\n    }\n    USHORT action_code;\n    USHORT reserved;\n}\nalias ACTION_HEADER* PACTION_HEADER;\n\nstruct ADAPTER_STATUS {\n    UCHAR[6] adapter_address;\n    UCHAR    rev_major;\n    UCHAR    reserved0;\n    UCHAR    adapter_type;\n    UCHAR    rev_minor;\n    WORD     duration;\n    WORD     frmr_recv;\n    WORD     frmr_xmit;\n    WORD     iframe_recv_err;\n    WORD     xmit_aborts;\n    DWORD    xmit_success;\n    DWORD    recv_success;\n    WORD     iframe_xmit_err;\n    WORD     recv_buff_unavail;\n    WORD     t1_timeouts;\n    WORD     ti_timeouts;\n    DWORD    reserved1;\n    WORD     free_ncbs;\n    WORD     max_cfg_ncbs;\n    WORD     max_ncbs;\n    WORD     xmit_buf_unavail;\n    WORD     max_dgram_size;\n    WORD     pending_sess;\n    WORD     max_cfg_sess;\n    WORD     max_sess;\n    WORD     max_sess_pkt_size;\n    WORD     name_count;\n}\nalias ADAPTER_STATUS* PADAPTER_STATUS;\n\nstruct FIND_NAME_BUFFER {\n    /*  From Win32 API docs\n     *\n     *  length\n     *      Specifies the length, in bytes, of the FIND_NAME_BUFFER\n     *      structure. Although this structure always occupies 33 bytes,\n     *      not all of the structure is necessarily valid.\n     *\n     *  On this basis, should length be initialised?\n     */\n    UCHAR     length;\n    UCHAR     access_control;\n    UCHAR     frame_control;\n    UCHAR[6]  destination_addr;\n    UCHAR[6]  source_addr;\n    UCHAR[18] routing_info;\n}\nalias FIND_NAME_BUFFER* PFIND_NAME_BUFFER;\n\nstruct FIND_NAME_HEADER {\n    WORD  node_count;\n    UCHAR reserved;\n    UCHAR unique_group;\n}\nalias FIND_NAME_HEADER* PFIND_NAME_HEADER;\n\nstruct LANA_ENUM {\n    UCHAR             length;\n    UCHAR[MAX_LANA+1] lana;\n}\nalias LANA_ENUM* PLANA_ENUM;\n\nstruct NAME_BUFFER {\n    UCHAR[NCBNAMSZ] name;\n    UCHAR           name_num;\n    UCHAR           name_flags;\n}\nalias NAME_BUFFER* PNAME_BUFFER;\n\nstruct NCB {\n    UCHAR           ncb_command;\n    UCHAR           ncb_retcode;\n    UCHAR           ncb_lsn;\n    UCHAR           ncb_num;\n    PUCHAR          ncb_buffer;\n    WORD            ncb_length;\n    UCHAR[NCBNAMSZ] ncb_callname;\n    UCHAR[NCBNAMSZ] ncb_name;\n    UCHAR           ncb_rto;\n    UCHAR           ncb_sto;\n    extern (Windows) void function(NCB*) ncb_post;\n    UCHAR           ncb_lana_num;\n    UCHAR           ncb_cmd_cplt;\n    version (Win64)\n        UCHAR[18]   ncb_reserve;\n    else\n        UCHAR[10]   ncb_reserve;\n    HANDLE          ncb_event;\n}\nalias NCB* PNCB;\n\nstruct SESSION_BUFFER {\n    UCHAR           lsn;\n    UCHAR           state;\n    UCHAR[NCBNAMSZ] local_name;\n    UCHAR[NCBNAMSZ] remote_name;\n    UCHAR           rcvs_outstanding;\n    UCHAR           sends_outstanding;\n}\nalias SESSION_BUFFER* PSESSION_BUFFER;\n\nstruct SESSION_HEADER {\n    UCHAR sess_name;\n    UCHAR num_sess;\n    UCHAR rcv_dg_outstanding;\n    UCHAR rcv_any_outstanding;\n}\nalias SESSION_HEADER* PSESSION_HEADER;\n\nextern (Windows) UCHAR Netbios(PNCB);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/nddeapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_nddeapi.d)\n */\nmodule core.sys.windows.nddeapi;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.windef;\n\n// FIXME: check types and grouping of constants\n\n/+\n#ifndef CNLEN /* also in lmcons.h */\n#define CNLEN 15\n#define UNCLEN (CNLEN + 2)\n#endif\n+/\n\nenum char    SEP_CHAR  = ',';\nconst char[]  BAR_CHAR  = \"|\";\nenum wchar   SEP_WCHAR = ',';\nconst wchar[] BAR_WCHAR = \"|\";\n\nenum {\n    NDDE_NO_ERROR,\n    NDDE_ACCESS_DENIED,\n    NDDE_BUF_TOO_SMALL,\n    NDDE_ERROR_MORE_DATA,\n    NDDE_INVALID_SERVER,\n    NDDE_INVALID_SHARE,\n    NDDE_INVALID_PARAMETER,\n    NDDE_INVALID_LEVEL,\n    NDDE_INVALID_PASSWORD,\n    NDDE_INVALID_ITEMNAME,\n    NDDE_INVALID_TOPIC,\n    NDDE_INTERNAL_ERROR,\n    NDDE_OUT_OF_MEMORY,\n    NDDE_INVALID_APPNAME,\n    NDDE_NOT_IMPLEMENTED,\n    NDDE_SHARE_ALREADY_EXIST,\n    NDDE_SHARE_NOT_EXIST,\n    NDDE_INVALID_FILENAME,\n    NDDE_NOT_RUNNING,\n    NDDE_INVALID_WINDOW,\n    NDDE_INVALID_SESSION,\n    NDDE_INVALID_ITEM_LIST,\n    NDDE_SHARE_DATA_CORRUPTED,\n    NDDE_REGISTRY_ERROR,\n    NDDE_CANT_ACCESS_SERVER,\n    NDDE_INVALID_SPECIAL_COMMAND,\n    NDDE_INVALID_SECURITY_DESC,\n    NDDE_TRUST_SHARE_FAIL\n}\n\nenum size_t\n    MAX_NDDESHARENAME = 256,\n    MAX_DOMAINNAME = 15,\n    MAX_USERNAME = 15,\n    MAX_APPNAME = 255,\n    MAX_TOPICNAME = 255,\n    MAX_ITEMNAME = 255;\n\nenum NDDEF_NOPASSWORDPROMPT = 1;\nenum NDDEF_NOCACHELOOKUP    = 2;\nenum NDDEF_STRIP_NDDE       = 4;\n\nenum SHARE_TYPE_OLD         = 1;\nenum SHARE_TYPE_NEW         = 2;\nenum SHARE_TYPE_STATIC      = 4;\n\nenum uint\n    NDDE_CMD_SHOW_MASK     = 0x0000FFFF,\n    NDDE_TRUST_CMD_SHOW    = 0x10000000,\n    NDDE_TRUST_SHARE_DEL   = 0x20000000,\n    NDDE_TRUST_SHARE_INIT  = 0x40000000,\n    NDDE_TRUST_SHARE_START = 0x80000000;\n\nstruct NDdeShareInfo_tag {\n    LONG    lRevision;\n    LPTSTR  lpszShareName;\n    LONG    lShareType;\n    LPTSTR  lpszAppTopicList;\n    LONG    fSharedFlag;\n    LONG    fService;\n    LONG    fStartAppFlag;\n    LONG    nCmdShow;\n    LONG[2] qModifyId;\n    LONG    cNumItems;\n    LPTSTR  lpszItemList;\n}\nextern (C) {    // huh?\n    NDdeShareInfo_tag  NDDESHAREINFO;\n    NDdeShareInfo_tag* PNDDESHAREINFO;\n}\n\nextern (Windows) {\n    UINT NDdeGetErrorStringA(UINT, LPSTR, DWORD);\n    UINT NDdeGetErrorStringW(UINT, LPWSTR, DWORD);\n    UINT NDdeGetShareSecurityA(LPSTR, LPSTR, SECURITY_INFORMATION,\n      PSECURITY_DESCRIPTOR, DWORD, PDWORD);\n    UINT NDdeGetShareSecurityW(LPWSTR, LPWSTR, SECURITY_INFORMATION,\n      PSECURITY_DESCRIPTOR, DWORD, PDWORD);\n    UINT NDdeGetTrustedShareA(LPSTR, LPSTR, PDWORD, PDWORD, PDWORD);\n    UINT NDdeGetTrustedShareW(LPWSTR, LPWSTR, PDWORD, PDWORD, PDWORD);\n    BOOL NDdeIsValidShareNameA(LPSTR);\n    BOOL NDdeIsValidShareNameW(LPWSTR);\n    BOOL NDdeIsValidAppTopicListA(LPSTR);\n    BOOL NDdeIsValidAppTopicListW(LPWSTR);\n    UINT NDdeSetShareSecurityA(LPSTR, LPSTR, SECURITY_INFORMATION,\n      PSECURITY_DESCRIPTOR);\n    UINT NDdeSetShareSecurityW(LPWSTR, LPWSTR, SECURITY_INFORMATION,\n      PSECURITY_DESCRIPTOR);\n    UINT NDdeSetTrustedShareA(LPSTR, LPSTR, DWORD);\n    UINT NDdeSetTrustedShareW(LPWSTR, LPWSTR, DWORD);\n    UINT NDdeShareAddA(LPSTR, UINT, PSECURITY_DESCRIPTOR, PBYTE, DWORD);\n    UINT NDdeShareAddW(LPWSTR, UINT, PSECURITY_DESCRIPTOR, PBYTE, DWORD);\n    UINT NDdeShareDelA(LPSTR, LPSTR, UINT);\n    UINT NDdeShareDelW(LPWSTR, LPWSTR, UINT);\n    UINT NDdeShareEnumA(LPSTR, UINT, PBYTE, DWORD, PDWORD, PDWORD);\n    UINT NDdeShareEnumW(LPWSTR, UINT, PBYTE, DWORD, PDWORD, PDWORD);\n    UINT NDdeShareGetInfoA(LPSTR, LPSTR, UINT, PBYTE, DWORD, PDWORD, PWORD);\n    UINT NDdeShareGetInfoW(LPWSTR, LPWSTR, UINT, PBYTE, DWORD, PDWORD, PWORD);\n    UINT NDdeShareSetInfoA(LPSTR, LPSTR, UINT, PBYTE, DWORD, WORD);\n    UINT NDdeShareSetInfoW(LPWSTR, LPWSTR, UINT, PBYTE, DWORD, WORD);\n    UINT NDdeTrustedShareEnumA(LPSTR, UINT, PBYTE, DWORD, PDWORD, PDWORD);\n    UINT NDdeTrustedShareEnumW(LPWSTR, UINT, PBYTE, DWORD, PDWORD, PDWORD);\n}\n\nversion (Unicode) {\n    alias NDdeShareAddW NDdeShareAdd;\n    alias NDdeShareDelW NDdeShareDel;\n    alias NDdeSetShareSecurityW NDdeSetShareSecurity;\n    alias NDdeGetShareSecurityW NDdeGetShareSecurity;\n    alias NDdeShareEnumW NDdeShareEnum;\n    alias NDdeShareGetInfoW NDdeShareGetInfo;\n    alias NDdeShareSetInfoW NDdeShareSetInfo;\n    alias NDdeGetErrorStringW NDdeGetErrorString;\n    alias NDdeIsValidShareNameW NDdeIsValidShareName;\n    alias NDdeIsValidAppTopicListW NDdeIsValidAppTopicList;\n    alias NDdeSetTrustedShareW NDdeSetTrustedShare;\n    alias NDdeGetTrustedShareW NDdeGetTrustedShare;\n    alias NDdeTrustedShareEnumW NDdeTrustedShareEnum;\n} else {\n    alias NDdeShareAddA NDdeShareAdd;\n    alias NDdeShareDelA NDdeShareDel;\n    alias NDdeSetShareSecurityA NDdeSetShareSecurity;\n    alias NDdeGetShareSecurityA NDdeGetShareSecurity;\n    alias NDdeShareEnumA NDdeShareEnum;\n    alias NDdeShareGetInfoA NDdeShareGetInfo;\n    alias NDdeShareSetInfoA NDdeShareSetInfo;\n    alias NDdeGetErrorStringA NDdeGetErrorString;\n    alias NDdeIsValidShareNameA NDdeIsValidShareName;\n    alias NDdeIsValidAppTopicListA NDdeIsValidAppTopicList;\n    alias NDdeSetTrustedShareA NDdeSetTrustedShare;\n    alias NDdeGetTrustedShareA NDdeGetTrustedShare;\n    alias NDdeTrustedShareEnumA NDdeTrustedShareEnum;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/nspapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_nspapi.d)\n */\nmodule core.sys.windows.nspapi;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.basetyps, core.sys.windows.windef;\n\n// FIXME: check types of constants\n\nenum {\n    NS_ALL         =  0,\n\n    NS_SAP,\n    NS_NDS,\n    NS_PEER_BROWSE,\n\n    NS_TCPIP_LOCAL = 10,\n    NS_TCPIP_HOSTS,\n    NS_DNS,\n    NS_NETBT,\n    NS_WINS,\n\n    NS_NBP         = 20,\n\n    NS_MS          = 30,\n    NS_STDA,\n    NS_NTDS,\n\n    NS_X500        = 40,\n    NS_NIS,\n    NS_NISPLUS,\n\n    NS_WRQ         = 50\n}\n\nenum {\n    SERVICE_REGISTER   = 1,\n    SERVICE_DEREGISTER = 2,\n    SERVICE_FLUSH      = 3,\n    SERVICE_FLAG_HARD  = 2\n}\n\nimport core.sys.windows.winsock2;\n\nstruct SOCKET_ADDRESS {\n    LPSOCKADDR lpSockaddr;\n    INT        iSockaddrLength;\n}\nalias SOCKET_ADDRESS* PSOCKET_ADDRESS, LPSOCKET_ADDRESS;\n\nstruct CSADDR_INFO {\n    SOCKET_ADDRESS LocalAddr;\n    SOCKET_ADDRESS RemoteAddr;\n    INT            iSocketType;\n    INT            iProtocol;\n}\nalias CSADDR_INFO* PCSADDR_INFO, LPCSADDR_INFO;\n\nstruct BLOB {\n    ULONG cbSize;\n    BYTE* pBlobData;\n}\nalias BLOB* PBLOB, LPBLOB;\n\nstruct SERVICE_ADDRESS {\n    DWORD dwAddressType;\n    DWORD dwAddressFlags;\n    DWORD dwAddressLength;\n    DWORD dwPrincipalLength;\n    BYTE* lpAddress;\n    BYTE* lpPrincipal;\n}\n\nstruct SERVICE_ADDRESSES {\n    DWORD           dwAddressCount;\n    SERVICE_ADDRESS _Addresses;\n\n    SERVICE_ADDRESS* Addresses() return { return &_Addresses; }\n}\nalias SERVICE_ADDRESSES* PSERVICE_ADDRESSES, LPSERVICE_ADDRESSES;\n\nstruct SERVICE_INFOA {\n    LPGUID lpServiceType;\n    LPSTR  lpServiceName;\n    LPSTR  lpComment;\n    LPSTR  lpLocale;\n    DWORD  dwDisplayHint;\n    DWORD  dwVersion;\n    DWORD  dwTime;\n    LPSTR  lpMachineName;\n    LPSERVICE_ADDRESSES lpServiceAddress;\n    BLOB   ServiceSpecificInfo;\n}\nalias SERVICE_INFOA* LPSERVICE_INFOA;\n\nstruct SERVICE_INFOW {\n    LPGUID lpServiceType;\n    LPWSTR lpServiceName;\n    LPWSTR lpComment;\n    LPWSTR lpLocale;\n    DWORD  dwDisplayHint;\n    DWORD  dwVersion;\n    DWORD  dwTime;\n    LPWSTR lpMachineName;\n    LPSERVICE_ADDRESSES lpServiceAddress;\n    BLOB   ServiceSpecificInfo;\n}\nalias SERVICE_INFOW* LPSERVICE_INFOW;\n\nalias void* LPSERVICE_ASYNC_INFO;\n\nextern (Windows) {\n    INT SetServiceA(DWORD, DWORD, DWORD, LPSERVICE_INFOA,\n      LPSERVICE_ASYNC_INFO, LPDWORD);\n    INT SetServiceW(DWORD, DWORD, DWORD, LPSERVICE_INFOW,\n      LPSERVICE_ASYNC_INFO, LPDWORD);\n    INT GetAddressByNameA(DWORD, LPGUID, LPSTR, LPINT, DWORD,\n      LPSERVICE_ASYNC_INFO, LPVOID, LPDWORD, LPSTR, LPDWORD);\n    INT GetAddressByNameW(DWORD, LPGUID, LPWSTR, LPINT, DWORD,\n      LPSERVICE_ASYNC_INFO, LPVOID, LPDWORD, LPWSTR, LPDWORD);\n}\n\nversion (Unicode) {\n    alias SERVICE_INFOW SERVICE_INFO;\n    alias SetServiceW SetService;\n    alias GetAddressByNameW GetAddressByName;\n} else {\n    alias SERVICE_INFOA SERVICE_INFO;\n    alias SetServiceA SetService;\n    alias GetAddressByNameA GetAddressByName;\n}\n\nalias SERVICE_INFO _SERVICE_INFO;\nalias SERVICE_INFO* LPSERVICE_INFO;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ntdef.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ntdef.d)\n */\nmodule core.sys.windows.ntdef;\nversion (Windows):\n\nprivate import core.sys.windows.basetsd, core.sys.windows.subauth, core.sys.windows.windef, core.sys.windows.winnt;\n\nenum uint\n    OBJ_INHERIT          = 0x0002,\n    OBJ_PERMANENT        = 0x0010,\n    OBJ_EXCLUSIVE        = 0x0020,\n    OBJ_CASE_INSENSITIVE = 0x0040,\n    OBJ_OPENIF           = 0x0080,\n    OBJ_OPENLINK         = 0x0100,\n    OBJ_VALID_ATTRIBUTES = 0x01F2;\n\nvoid InitializeObjectAttributes(OBJECT_ATTRIBUTES* p, UNICODE_STRING* n,\n      uint a, HANDLE r, void* s) {\n    with (*p) {\n        Length = OBJECT_ATTRIBUTES.sizeof;\n        RootDirectory = r;\n        Attributes = a;\n        ObjectName = n;\n        SecurityDescriptor = s;\n        SecurityQualityOfService = null;\n    }\n}\n\nbool NT_SUCCESS(int x) { return x >= 0; }\n\n/*  In MinGW, NTSTATUS, UNICODE_STRING, STRING and their associated pointer\n *  type aliases are defined in ntdef.h, ntsecapi.h and subauth.h, each of\n *  which checks that none of the others is already included.\n */\nalias int  NTSTATUS;\nalias int* PNTSTATUS;\n\nstruct UNICODE_STRING {\n    USHORT Length;\n    USHORT MaximumLength;\n    PWSTR  Buffer;\n}\nalias UNICODE_STRING*        PUNICODE_STRING;\nalias const(UNICODE_STRING)* PCUNICODE_STRING;\n\nstruct STRING {\n    USHORT Length;\n    USHORT MaximumLength;\n    PCHAR  Buffer;\n}\nalias STRING  ANSI_STRING, OEM_STRING;\nalias STRING* PSTRING, PANSI_STRING, POEM_STRING;\n\nalias LARGE_INTEGER  PHYSICAL_ADDRESS;\nalias LARGE_INTEGER* PPHYSICAL_ADDRESS;\n\nenum SECTION_INHERIT {\n    ViewShare = 1,\n    ViewUnmap\n}\n\n/*  In MinGW, this is defined in ntdef.h and ntsecapi.h, each of which checks\n *  that the other isn't already included.\n */\nstruct OBJECT_ATTRIBUTES {\n    ULONG           Length = OBJECT_ATTRIBUTES.sizeof;\n    HANDLE          RootDirectory;\n    PUNICODE_STRING ObjectName;\n    ULONG           Attributes;\n    PVOID           SecurityDescriptor;\n    PVOID           SecurityQualityOfService;\n}\nalias OBJECT_ATTRIBUTES* POBJECT_ATTRIBUTES;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ntdll.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.10\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ntdll.d)\n */\nmodule core.sys.windows.ntdll;\nversion (Windows):\n\nprivate import core.sys.windows.w32api;\n\n\nenum SHUTDOWN_ACTION {\n    ShutdownNoReboot,\n    ShutdownReboot,\n    ShutdownPowerOff\n}\n\nextern (Windows) uint NtShutdownSystem(SHUTDOWN_ACTION Action);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ntldap.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ntldap.d)\n */\nmodule core.sys.windows.ntldap;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\n/*  TOTHINKABOUT: These constants don't have ANSI/Unicode versioned\n *  aliases.  Should we merge them anyway?\n */\n\nconst char[]\n    LDAP_SERVER_ASQ_OID                    = \"1.2.840.113556.1.4.1504\",\n    LDAP_SERVER_DIRSYNC_OID                = \"1.2.840.113556.1.4.841\",\n    LDAP_SERVER_SD_FLAGS_OID               = \"1.2.840.113556.1.4.801\",\n    LDAP_SERVER_FAST_BIND_OID              = \"1.2.840.113556.1.4.1781\",\n    LDAP_MATCHING_RULE_BIT_OR              = \"1.2.840.113556.1.4.804\",\n    LDAP_MATCHING_RULE_BIT_AND             = \"1.2.840.113556.1.4.803\",\n    LDAP_SERVER_EXTENDED_DN_OID            = \"1.2.840.113556.1.4.529\",\n    LDAP_SERVER_LAZY_COMMIT_OID            = \"1.2.840.113556.1.4.619\",\n    LDAP_SERVER_TREE_DELETE_OID            = \"1.2.840.113556.1.4.805\",\n    LDAP_SERVER_VERIFY_NAME_OID            = \"1.2.840.113556.1.4.1338\",\n    LDAP_SERVER_SHOW_DELETED_OID           = \"1.2.840.113556.1.4.417\",\n    LDAP_SERVER_NOTIFICATION_OID           = \"1.2.840.113556.1.4.528\",\n    LDAP_SERVER_DOMAIN_SCOPE_OID           = \"1.2.840.113556.1.4.1339\",\n    LDAP_CAP_ACTIVE_DIRECTORY_OID          = \"1.2.840.113556.1.4.800\",\n    LDAP_SERVER_SEARCH_OPTIONS_OID         = \"1.2.840.113556.1.4.1340\",\n    LDAP_CAP_ACTIVE_DIRECTORY_V51_OID      = \"1.2.840.113556.1.4.1670\",\n    LDAP_SERVER_PERMISSIVE_MODIFY_OID      = \"1.2.840.113556.1.4.1413\",\n    LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID   = \"1.2.840.113556.1.4.521\";\n\nconst wchar[]\n    LDAP_SERVER_ASQ_OID_W                  = \"1.2.840.113556.1.4.1504\",\n    LDAP_SERVER_DIRSYNC_OID_W              = \"1.2.840.113556.1.4.841\",\n    LDAP_SERVER_SD_FLAGS_OID_W             = \"1.2.840.113556.1.4.801\",\n    LDAP_SERVER_FAST_BIND_OID_W            = \"1.2.840.113556.1.4.1781\",\n    LDAP_MATCHING_RULE_BIT_OR_W            = \"1.2.840.113556.1.4.804\",\n    LDAP_MATCHING_RULE_BIT_AND_W           = \"1.2.840.113556.1.4.803\",\n    LDAP_SERVER_EXTENDED_DN_OID_W          = \"1.2.840.113556.1.4.529\",\n    LDAP_SERVER_LAZY_COMMIT_OID_W          = \"1.2.840.113556.1.4.619\",\n    LDAP_SERVER_TREE_DELETE_OID_W          = \"1.2.840.113556.1.4.805\",\n    LDAP_SERVER_VERIFY_NAME_OID_W          = \"1.2.840.113556.1.4.1338\",\n    LDAP_SERVER_SHOW_DELETED_OID_W         = \"1.2.840.113556.1.4.417\",\n    LDAP_SERVER_NOTIFICATION_OID_W         = \"1.2.840.113556.1.4.528\",\n    LDAP_SERVER_DOMAIN_SCOPE_OID_W         = \"1.2.840.113556.1.4.1339\",\n    LDAP_CAP_ACTIVE_DIRECTORY_OID_W        = \"1.2.840.113556.1.4.800\",\n    LDAP_SERVER_SEARCH_OPTIONS_OID_W       = \"1.2.840.113556.1.4.1340\",\n    LDAP_CAP_ACTIVE_DIRECTORY_V51_OID_W    = \"1.2.840.113556.1.4.1670\",\n    LDAP_SERVER_PERMISSIVE_MODIFY_OID_W    = \"1.2.840.113556.1.4.1413\",\n    LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID_W = \"1.2.840.113556.1.4.521\";\n\nenum SERVER_SEARCH_FLAG_DOMAIN_SCOPE = 1;\nenum SERVER_SEARCH_FLAG_PHANTOM_ROOT = 2;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ntsecapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ntsecapi.d)\n */\nmodule core.sys.windows.ntsecapi;\nversion (Windows):\npragma(lib, \"advapi32\");\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import\n  core.sys.windows.basetyps, core.sys.windows.ntdef, core.sys.windows.windef, core.sys.windows.winnt, core.sys.windows.w32api;\n\n// FIXME: check types and grouping of constants\n// FIXME: check Windows version support\n\nenum KERB_WRAP_NO_ENCRYPT        = 0x80000001;\n\nenum LOGON_GUEST                 = 0x00000001;\nenum LOGON_NOENCRYPTION          = 0x00000002;\nenum LOGON_CACHED_ACCOUNT        = 0x00000004;\nenum LOGON_USED_LM_PASSWORD      = 0x00000008;\nenum LOGON_EXTRA_SIDS            = 0x00000020;\nenum LOGON_SUBAUTH_SESSION_KEY   = 0x00000040;\nenum LOGON_SERVER_TRUST_ACCOUNT  = 0x00000080;\nenum LOGON_NTLMV2_ENABLED        = 0x00000100;\nenum LOGON_RESOURCE_GROUPS       = 0x00000200;\nenum LOGON_PROFILE_PATH_RETURNED = 0x00000400;\nenum LOGON_GRACE_LOGON           = 0x01000000;\n\nenum {\n    LSA_MODE_PASSWORD_PROTECTED = 1,\n    LSA_MODE_INDIVIDUAL_ACCOUNTS,\n    LSA_MODE_MANDATORY_ACCESS,\n    LSA_MODE_LOG_FULL\n}\n\nbool LSA_SUCCESS(int x) { return x >= 0; }\n\n/*  TOTHINKABOUT: These constants don't have ANSI/Unicode versioned\n *  aliases.  Should we merge them anyway?\n */\nconst char[]  MICROSOFT_KERBEROS_NAME_A = \"Kerberos\";\nconst wchar[] MICROSOFT_KERBEROS_NAME_W = \"Kerberos\";\nconst char[]  MSV1_0_PACKAGE_NAME  = \"MICROSOFT_AUTHENTICATION_PACKAGE_V1_0\";\nconst wchar[] MSV1_0_PACKAGE_NAMEW = \"MICROSOFT_AUTHENTICATION_PACKAGE_V1_0\";\n\nenum MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT      =       32;\nenum MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT =     2048;\nenum MSV1_0_CLEARTEXT_PASSWORD_ALLOWED      =        2;\nenum MSV1_0_CRED_LM_PRESENT                 =        1;\nenum MSV1_0_CRED_NT_PRESENT                 =        2;\nenum MSV1_0_CRED_VERSION                    =        0;\nenum MSV1_0_DONT_TRY_GUEST_ACCOUNT          =       16;\nenum MSV1_0_MAX_NTLM3_LIFE                  =     1800;\nenum MSV1_0_MAX_AVL_SIZE                    =    64000;\nenum MSV1_0_MNS_LOGON                       = 16777216;\n\nenum size_t\n    MSV1_0_CHALLENGE_LENGTH          = 8,\n    MSV1_0_LANMAN_SESSION_KEY_LENGTH = 8,\n    MSV1_0_NTLM3_RESPONSE_LENGTH     = 16,\n    MSV1_0_NTLM3_OWF_LENGTH          = 16,\n    MSV1_0_NTLM3_INPUT_LENGTH        = MSV1_0_NTLM3_RESPONSE.sizeof\n                                       - MSV1_0_NTLM3_RESPONSE_LENGTH,\n    MSV1_0_OWF_PASSWORD_LENGTH       = 16,\n    MSV1_0_PACKAGE_NAMEW_LENGTH      = MSV1_0_PACKAGE_NAMEW.sizeof\n                                       - WCHAR.sizeof;\n\nenum MSV1_0_RETURN_USER_PARAMETERS      =          8;\nenum MSV1_0_RETURN_PASSWORD_EXPIRY      =         64;\nenum MSV1_0_RETURN_PROFILE_PATH         =        512;\nenum MSV1_0_SUBAUTHENTICATION_DLL_EX    =    1048576;\nenum MSV1_0_SUBAUTHENTICATION_DLL       = 0xff000000;\nenum MSV1_0_SUBAUTHENTICATION_DLL_SHIFT =         24;\nenum MSV1_0_SUBAUTHENTICATION_DLL_RAS   =          2;\nenum MSV1_0_SUBAUTHENTICATION_DLL_IIS   =        132;\nenum MSV1_0_SUBAUTHENTICATION_FLAGS     = 0xff000000;\nenum MSV1_0_TRY_GUEST_ACCOUNT_ONLY      =        256;\nenum MSV1_0_TRY_SPECIFIED_DOMAIN_ONLY   =       1024;\nenum MSV1_0_UPDATE_LOGON_STATISTICS     =          4;\nenum MSV1_0_USE_CLIENT_CHALLENGE        =        128;\nenum MSV1_0_USER_SESSION_KEY_LENGTH     =         16;\n\nconst char[]\n    MSV1_0_SUBAUTHENTICATION_KEY\n      = `System\\CurrentControlSet\\Control\\Lsa\\MSV1_0`,\n    MSV1_0_SUBAUTHENTICATION_VALUE = \"Auth\";\n\nenum ACCESS_MASK\n    POLICY_VIEW_LOCAL_INFORMATION   = 0x0001,\n    POLICY_VIEW_AUDIT_INFORMATION   = 0x0002,\n    POLICY_GET_PRIVATE_INFORMATION  = 0x0004,\n    POLICY_TRUST_ADMIN              = 0x0008,\n    POLICY_CREATE_ACCOUNT           = 0x0010,\n    POLICY_CREATE_SECRET            = 0x0020,\n    POLICY_CREATE_PRIVILEGE         = 0x0040,\n    POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x0080,\n    POLICY_SET_AUDIT_REQUIREMENTS   = 0x0100,\n    POLICY_AUDIT_LOG_ADMIN          = 0x0200,\n    POLICY_SERVER_ADMIN             = 0x0400,\n    POLICY_LOOKUP_NAMES             = 0x0800,\n\n    POLICY_READ                     = STANDARD_RIGHTS_READ     | 0x0006,\n    POLICY_WRITE                    = STANDARD_RIGHTS_WRITE    | 0x07F8,\n    POLICY_EXECUTE                  = STANDARD_RIGHTS_EXECUTE  | 0x0801,\n    POLICY_ALL_ACCESS               = STANDARD_RIGHTS_REQUIRED | 0x0FFF;\n\nenum POLICY_AUDIT_EVENT_UNCHANGED = 0;\nenum POLICY_AUDIT_EVENT_SUCCESS   = 1;\nenum POLICY_AUDIT_EVENT_FAILURE   = 2;\nenum POLICY_AUDIT_EVENT_NONE      = 4;\nenum POLICY_AUDIT_EVENT_MASK      = 7;\n\nenum {\n    POLICY_LOCATION_LOCAL = 1,\n    POLICY_LOCATION_DS\n}\n\nenum : uint {\n    POLICY_MACHINE_POLICY_LOCAL     =          0,\n    POLICY_MACHINE_POLICY_DEFAULTED,\n    POLICY_MACHINE_POLICY_EXPLICIT,\n    POLICY_MACHINE_POLICY_UNKNOWN   = 0xFFFFFFFF\n}\n\n\nenum POLICY_QOS_SCHANEL_REQUIRED            = 0x0001;\nenum POLICY_QOS_OUTBOUND_INTEGRITY          = 0x0002;\nenum POLICY_QOS_OUTBOUND_CONFIDENTIALITY    = 0x0004;\nenum POLICY_QOS_INBOUND_INTEGREITY          = 0x0008;\nenum POLICY_QOS_INBOUND_CONFIDENTIALITY     = 0x0010;\nenum POLICY_QOS_ALLOW_LOCAL_ROOT_CERT_STORE = 0x0020;\nenum POLICY_QOS_RAS_SERVER_ALLOWED          = 0x0040;\nenum POLICY_QOS_DHCP_SERVER_ALLOWD          = 0x0080;\n\nenum POLICY_KERBEROS_FORWARDABLE  = 1;\nenum POLICY_KERBEROS_PROXYABLE    = 2;\nenum POLICY_KERBEROS_RENEWABLE    = 4;\nenum POLICY_KERBEROS_POSTDATEABLE = 8;\n\nconst char[]\n    SAM_PASSWORD_CHANGE_NOTIFY_ROUTINE = \"PasswordChangeNotify\",\n    SAM_INIT_NOTIFICATION_ROUTINE      = \"InitializeChangeNotify\",\n    SAM_PASSWORD_FILTER_ROUTINE        = \"PasswordFilter\";\n\nconst TCHAR[]\n    SE_INTERACTIVE_LOGON_NAME          = \"SeInteractiveLogonRight\",\n    SE_NETWORK_LOGON_NAME              = \"SeNetworkLogonRight\",\n    SE_BATCH_LOGON_NAME                = \"SeBatchLogonRight\",\n    SE_SERVICE_LOGON_NAME              = \"SeServiceLogonRight\";\n\nenum {\n    TRUST_ATTRIBUTE_NON_TRANSITIVE =         1,\n    TRUST_ATTRIBUTE_UPLEVEL_ONLY   =         2,\n    TRUST_ATTRIBUTE_TREE_PARENT    =   4194304,\n    TRUST_ATTRIBUTES_VALID         = -16580609\n}\n\nenum {\n    TRUST_AUTH_TYPE_NONE,\n    TRUST_AUTH_TYPE_NT4OWF,\n    TRUST_AUTH_TYPE_CLEAR\n}\n\nenum {\n    TRUST_DIRECTION_DISABLED,\n    TRUST_DIRECTION_INBOUND,\n    TRUST_DIRECTION_OUTBOUND,\n    TRUST_DIRECTION_BIDIRECTIONAL\n}\n\nenum {\n    TRUST_TYPE_DOWNLEVEL = 1,\n    TRUST_TYPE_UPLEVEL,\n    TRUST_TYPE_MIT,\n    TRUST_TYPE_DCE\n}\n\nalias UNICODE_STRING LSA_UNICODE_STRING;\nalias UNICODE_STRING* PLSA_UNICODE_STRING;\nalias STRING LSA_STRING;\nalias STRING* PLSA_STRING;\n\nenum MSV1_0_LOGON_SUBMIT_TYPE {\n    MsV1_0InteractiveLogon       = 2,\n    MsV1_0Lm20Logon,\n    MsV1_0NetworkLogon,\n    MsV1_0SubAuthLogon,\n    MsV1_0WorkstationUnlockLogon = 7\n}\nalias MSV1_0_LOGON_SUBMIT_TYPE* PMSV1_0_LOGON_SUBMIT_TYPE;\n\nenum MSV1_0_PROFILE_BUFFER_TYPE {\n    MsV1_0InteractiveProfile = 2,\n    MsV1_0Lm20LogonProfile,\n    MsV1_0SmartCardProfile\n}\nalias MSV1_0_PROFILE_BUFFER_TYPE* PMSV1_0_PROFILE_BUFFER_TYPE;\n\n\nenum MSV1_0_AVID {\n    MsvAvEOL,\n    MsvAvNbComputerName,\n    MsvAvNbDomainName,\n    MsvAvDnsComputerName,\n    MsvAvDnsDomainName\n}\n\nenum MSV1_0_PROTOCOL_MESSAGE_TYPE {\n    MsV1_0Lm20ChallengeRequest = 0,\n    MsV1_0Lm20GetChallengeResponse,\n    MsV1_0EnumerateUsers,\n    MsV1_0GetUserInfo,\n    MsV1_0ReLogonUsers,\n    MsV1_0ChangePassword,\n    MsV1_0ChangeCachedPassword,\n    MsV1_0GenericPassthrough,\n    MsV1_0CacheLogon,\n    MsV1_0SubAuth,\n    MsV1_0DeriveCredential,\n    MsV1_0CacheLookup\n}\nalias MSV1_0_PROTOCOL_MESSAGE_TYPE* PMSV1_0_PROTOCOL_MESSAGE_TYPE;\n\nenum POLICY_LSA_SERVER_ROLE {\n    PolicyServerRoleBackup = 2,\n    PolicyServerRolePrimary\n}\nalias POLICY_LSA_SERVER_ROLE* PPOLICY_LSA_SERVER_ROLE;\n\nenum POLICY_SERVER_ENABLE_STATE {\n    PolicyServerEnabled = 2,\n    PolicyServerDisabled\n}\nalias POLICY_SERVER_ENABLE_STATE* PPOLICY_SERVER_ENABLE_STATE;\n\nenum POLICY_INFORMATION_CLASS {\n    PolicyAuditLogInformation = 1,\n    PolicyAuditEventsInformation,\n    PolicyPrimaryDomainInformation,\n    PolicyPdAccountInformation,\n    PolicyAccountDomainInformation,\n    PolicyLsaServerRoleInformation,\n    PolicyReplicaSourceInformation,\n    PolicyDefaultQuotaInformation,\n    PolicyModificationInformation,\n    PolicyAuditFullSetInformation,\n    PolicyAuditFullQueryInformation,\n    PolicyDnsDomainInformation,\n    PolicyEfsInformation\n}\nalias POLICY_INFORMATION_CLASS* PPOLICY_INFORMATION_CLASS;\n\nenum POLICY_AUDIT_EVENT_TYPE {\n    AuditCategorySystem,\n    AuditCategoryLogon,\n    AuditCategoryObjectAccess,\n    AuditCategoryPrivilegeUse,\n    AuditCategoryDetailedTracking,\n    AuditCategoryPolicyChange,\n    AuditCategoryAccountManagement,\n    AuditCategoryDirectoryServiceAccess,\n    AuditCategoryAccountLogon\n}\nalias POLICY_AUDIT_EVENT_TYPE* PPOLICY_AUDIT_EVENT_TYPE;\n\nenum POLICY_LOCAL_INFORMATION_CLASS {\n    PolicyLocalAuditEventsInformation = 1,\n    PolicyLocalPdAccountInformation,\n    PolicyLocalAccountDomainInformation,\n    PolicyLocalLsaServerRoleInformation,\n    PolicyLocalReplicaSourceInformation,\n    PolicyLocalModificationInformation,\n    PolicyLocalAuditFullSetInformation,\n    PolicyLocalAuditFullQueryInformation,\n    PolicyLocalDnsDomainInformation,\n    PolicyLocalIPSecReferenceInformation,\n    PolicyLocalMachinePasswordInformation,\n    PolicyLocalQualityOfServiceInformation,\n    PolicyLocalPolicyLocationInformation\n}\nalias POLICY_LOCAL_INFORMATION_CLASS* PPOLICY_LOCAL_INFORMATION_CLASS;\n\nenum POLICY_DOMAIN_INFORMATION_CLASS {\n    PolicyDomainIPSecReferenceInformation = 1,\n    PolicyDomainQualityOfServiceInformation,\n    PolicyDomainEfsInformation,\n    PolicyDomainPublicKeyInformation,\n    PolicyDomainPasswordPolicyInformation,\n    PolicyDomainLockoutInformation,\n    PolicyDomainKerberosTicketInformation\n}\nalias POLICY_DOMAIN_INFORMATION_CLASS* PPOLICY_DOMAIN_INFORMATION_CLASS;\n\nenum SECURITY_LOGON_TYPE {\n    Interactive = 2,\n    Network,\n    Batch,\n    Service,\n    Proxy,\n    Unlock\n}\nalias SECURITY_LOGON_TYPE* PSECURITY_LOGON_TYPE;\n\nenum TRUSTED_INFORMATION_CLASS {\n    TrustedDomainNameInformation = 1,\n    TrustedControllersInformation,\n    TrustedPosixOffsetInformation,\n    TrustedPasswordInformation,\n    TrustedDomainInformationBasic,\n    TrustedDomainInformationEx,\n    TrustedDomainAuthInformation,\n    TrustedDomainFullInformation\n}\nalias TRUSTED_INFORMATION_CLASS* PTRUSTED_INFORMATION_CLASS;\n\nstruct DOMAIN_PASSWORD_INFORMATION {\n    USHORT        MinPasswordLength;\n    USHORT        PasswordHistoryLength;\n    ULONG         PasswordProperties;\n    LARGE_INTEGER MaxPasswordAge;\n    LARGE_INTEGER MinPasswordAge;\n}\nalias DOMAIN_PASSWORD_INFORMATION* PDOMAIN_PASSWORD_INFORMATION;\n\nstruct LSA_ENUMERATION_INFORMATION {\n    PSID Sid;\n}\nalias LSA_ENUMERATION_INFORMATION* PLSA_ENUMERATION_INFORMATION;\n\nalias OBJECT_ATTRIBUTES LSA_OBJECT_ATTRIBUTES;\nalias OBJECT_ATTRIBUTES* PLSA_OBJECT_ATTRIBUTES;\n\nstruct LSA_TRUST_INFORMATION {\n    LSA_UNICODE_STRING Name;\n    PSID               Sid;\n}\nalias LSA_TRUST_INFORMATION TRUSTED_DOMAIN_INFORMATION_BASIC;\nalias LSA_TRUST_INFORMATION* PLSA_TRUST_INFORMATION;\n/*  in MinGW (further down the code):\n *      typedef PLSA_TRUST_INFORMATION *PTRUSTED_DOMAIN_INFORMATION_BASIC;\n *  but it doesn't look right....\n */\nalias LSA_TRUST_INFORMATION** PTRUSTED_DOMAIN_INFORMATION_BASIC;\n\nstruct LSA_REFERENCED_DOMAIN_LIST {\n    ULONG                  Entries;\n    PLSA_TRUST_INFORMATION Domains;\n}\nalias LSA_REFERENCED_DOMAIN_LIST* PLSA_REFERENCED_DOMAIN_LIST;\n\nstruct LSA_TRANSLATED_SID {\n    SID_NAME_USE Use;\n    ULONG        RelativeId;\n    LONG         DomainIndex;\n}\nalias LSA_TRANSLATED_SID* PLSA_TRANSLATED_SID;\n\nstruct LSA_TRANSLATED_NAME {\n    SID_NAME_USE       Use;\n    LSA_UNICODE_STRING Name;\n    LONG               DomainIndex;\n}\nalias LSA_TRANSLATED_NAME* PLSA_TRANSLATED_NAME;\n\nstruct MSV1_0_INTERACTIVE_LOGON {\n    MSV1_0_LOGON_SUBMIT_TYPE MessageType;\n    UNICODE_STRING           LogonDomainName;\n    UNICODE_STRING           UserName;\n    UNICODE_STRING           Password;\n}\nalias MSV1_0_INTERACTIVE_LOGON* PMSV1_0_INTERACTIVE_LOGON;\n\nstruct MSV1_0_INTERACTIVE_PROFILE {\n    MSV1_0_PROFILE_BUFFER_TYPE MessageType;\n    USHORT                     LogonCount;\n    USHORT                     BadPasswordCount;\n    LARGE_INTEGER              LogonTime;\n    LARGE_INTEGER              LogoffTime;\n    LARGE_INTEGER              KickOffTime;\n    LARGE_INTEGER              PasswordLastSet;\n    LARGE_INTEGER              PasswordCanChange;\n    LARGE_INTEGER              PasswordMustChange;\n    UNICODE_STRING             LogonScript;\n    UNICODE_STRING             HomeDirectory;\n    UNICODE_STRING             FullName;\n    UNICODE_STRING             ProfilePath;\n    UNICODE_STRING             HomeDirectoryDrive;\n    UNICODE_STRING             LogonServer;\n    ULONG                      UserFlags;\n}\nalias MSV1_0_INTERACTIVE_PROFILE* PMSV1_0_INTERACTIVE_PROFILE;\n\nstruct MSV1_0_LM20_LOGON {\n    MSV1_0_LOGON_SUBMIT_TYPE       MessageType;\n    UNICODE_STRING                 LogonDomainName;\n    UNICODE_STRING                 UserName;\n    UNICODE_STRING                 Workstation;\n    UCHAR[MSV1_0_CHALLENGE_LENGTH] ChallengeToClient;\n    STRING                         CaseSensitiveChallengeResponse;\n    STRING                         CaseInsensitiveChallengeResponse;\n    ULONG                          ParameterControl;\n}\nalias MSV1_0_LM20_LOGON* PMSV1_0_LM20_LOGON;\n\n//static if (_WIN32_WINNT >= 0x500) {\n    struct MSV1_0_SUBAUTH_LOGON {\n        MSV1_0_LOGON_SUBMIT_TYPE       MessageType;\n        UNICODE_STRING                 LogonDomainName;\n        UNICODE_STRING                 UserName;\n        UNICODE_STRING                 Workstation;\n        UCHAR[MSV1_0_CHALLENGE_LENGTH] ChallengeToClient;\n        STRING                         AuthenticationInfo1;\n        STRING                         AuthenticationInfo2;\n        ULONG                          ParameterControl;\n        ULONG                          SubAuthPackageId;\n    }\n    alias MSV1_0_SUBAUTH_LOGON* PMSV1_0_SUBAUTH_LOGON;\n//}\n\nstruct MSV1_0_LM20_LOGON_PROFILE {\n    MSV1_0_PROFILE_BUFFER_TYPE              MessageType;\n    LARGE_INTEGER                           KickOffTime;\n    LARGE_INTEGER                           LogoffTime;\n    ULONG                                   UserFlags;\n    UCHAR[MSV1_0_USER_SESSION_KEY_LENGTH]   UserSessionKey;\n    UNICODE_STRING                          LogonDomainName;\n    UCHAR[MSV1_0_LANMAN_SESSION_KEY_LENGTH] LanmanSessionKey;\n    UNICODE_STRING                          LogonServer;\n    UNICODE_STRING                          UserParameters;\n}\nalias MSV1_0_LM20_LOGON_PROFILE* PMSV1_0_LM20_LOGON_PROFILE;\n\nstruct MSV1_0_SUPPLEMENTAL_CREDENTIAL {\n    ULONG Version;\n    ULONG Flags;\n    UCHAR[MSV1_0_OWF_PASSWORD_LENGTH] LmPassword;\n    UCHAR[MSV1_0_OWF_PASSWORD_LENGTH] NtPassword;\n}\nalias MSV1_0_SUPPLEMENTAL_CREDENTIAL* PMSV1_0_SUPPLEMENTAL_CREDENTIAL;\n\nstruct MSV1_0_NTLM3_RESPONSE {\n    UCHAR[MSV1_0_NTLM3_RESPONSE_LENGTH] Response;\n    UCHAR     RespType;\n    UCHAR     HiRespType;\n    USHORT    Flags;\n    ULONG     MsgWord;\n    ULONGLONG TimeStamp;\n    UCHAR[MSV1_0_CHALLENGE_LENGTH]      ChallengeFromClient;\n    ULONG     AvPairsOff;\n    UCHAR     _Buffer;\n    UCHAR*    Buffer() return { return &_Buffer; }\n}\nalias MSV1_0_NTLM3_RESPONSE* PMSV1_0_NTLM3_RESPONSE;\n\nstruct  MSV1_0_AV_PAIR {\n    USHORT AvId;\n    USHORT AvLen;\n}\nalias MSV1_0_AV_PAIR* PMSV1_0_AV_PAIR;\n\nstruct MSV1_0_CHANGEPASSWORD_REQUEST {\n    MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;\n    UNICODE_STRING DomainName;\n    UNICODE_STRING AccountName;\n    UNICODE_STRING OldPassword;\n    UNICODE_STRING NewPassword;\n    BOOLEAN        Impersonating;\n}\nalias MSV1_0_CHANGEPASSWORD_REQUEST* PMSV1_0_CHANGEPASSWORD_REQUEST;\n\nstruct MSV1_0_CHANGEPASSWORD_RESPONSE {\n    MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;\n    BOOLEAN                      PasswordInfoValid;\n    DOMAIN_PASSWORD_INFORMATION  DomainPasswordInfo;\n}\nalias MSV1_0_CHANGEPASSWORD_RESPONSE* PMSV1_0_CHANGEPASSWORD_RESPONSE;\n\nstruct MSV1_0_SUBAUTH_REQUEST {\n    MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;\n    ULONG  SubAuthPackageId;\n    ULONG  SubAuthInfoLength;\n    PUCHAR SubAuthSubmitBuffer;\n}\nalias MSV1_0_SUBAUTH_REQUEST* PMSV1_0_SUBAUTH_REQUEST;\n\nstruct MSV1_0_SUBAUTH_RESPONSE {\n    MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;\n    ULONG  SubAuthInfoLength;\n    PUCHAR SubAuthReturnBuffer;\n}\nalias MSV1_0_SUBAUTH_RESPONSE* PMSV1_0_SUBAUTH_RESPONSE;\n\nenum MSV1_0_DERIVECRED_TYPE_SHA1 = 0;\n\nstruct MSV1_0_DERIVECRED_REQUEST {\n    MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;\n    LUID   LogonId;\n    ULONG  DeriveCredType;\n    ULONG  DeriveCredInfoLength;\n    UCHAR  _DeriveCredSubmitBuffer;\n    UCHAR* DeriveCredSubmitBuffer() return { return &_DeriveCredSubmitBuffer; }\n}\nalias MSV1_0_DERIVECRED_REQUEST* PMSV1_0_DERIVECRED_REQUEST;\n\nstruct MSV1_0_DERIVECRED_RESPONSE {\n    MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;\n    ULONG  DeriveCredInfoLength;\n    UCHAR  _DeriveCredReturnBuffer;\n    UCHAR* DeriveCredReturnBuffer() return { return &_DeriveCredReturnBuffer; }\n}\nalias MSV1_0_DERIVECRED_RESPONSE* PMSV1_0_DERIVECRED_RESPONSE;\n\nalias uint LSA_ENUMERATION_HANDLE, LSA_OPERATIONAL_MODE,\n  POLICY_AUDIT_EVENT_OPTIONS;\nalias uint* PLSA_ENUMERATION_HANDLE, PLSA_OPERATIONAL_MODE,\n  PPOLICY_AUDIT_EVENT_OPTIONS;\n\nstruct POLICY_PRIVILEGE_DEFINITION {\n    LSA_UNICODE_STRING Name;\n    LUID LocalValue;\n}\nalias POLICY_PRIVILEGE_DEFINITION* PPOLICY_PRIVILEGE_DEFINITION;\n\nstruct POLICY_AUDIT_LOG_INFO {\n    ULONG         AuditLogPercentFull;\n    ULONG         MaximumLogSize;\n    LARGE_INTEGER AuditRetentionPeriod;\n    BOOLEAN       AuditLogFullShutdownInProgress;\n    LARGE_INTEGER TimeToShutdown;\n    ULONG         NextAuditRecordId;\n}\nalias POLICY_AUDIT_LOG_INFO* PPOLICY_AUDIT_LOG_INFO;\n\nstruct POLICY_AUDIT_EVENTS_INFO {\n    BOOLEAN                     AuditingMode;\n    PPOLICY_AUDIT_EVENT_OPTIONS EventAuditingOptions;\n    ULONG                       MaximumAuditEventCount;\n}\nalias POLICY_AUDIT_EVENTS_INFO* PPOLICY_AUDIT_EVENTS_INFO;\n\nstruct POLICY_ACCOUNT_DOMAIN_INFO {\n    LSA_UNICODE_STRING DomainName;\n    PSID               DomainSid;\n}\nalias POLICY_ACCOUNT_DOMAIN_INFO* PPOLICY_ACCOUNT_DOMAIN_INFO;\n\nstruct POLICY_PRIMARY_DOMAIN_INFO {\n    LSA_UNICODE_STRING Name;\n    PSID               Sid;\n}\nalias POLICY_PRIMARY_DOMAIN_INFO* PPOLICY_PRIMARY_DOMAIN_INFO;\n\nstruct POLICY_DNS_DOMAIN_INFO {\n    LSA_UNICODE_STRING Name;\n    LSA_UNICODE_STRING DnsDomainName;\n    LSA_UNICODE_STRING DnsTreeName;\n    GUID               DomainGuid;\n    PSID               Sid;\n}\nalias POLICY_DNS_DOMAIN_INFO* PPOLICY_DNS_DOMAIN_INFO;\n\nstruct POLICY_PD_ACCOUNT_INFO {\n    LSA_UNICODE_STRING Name;\n}\nalias POLICY_PD_ACCOUNT_INFO* PPOLICY_PD_ACCOUNT_INFO;\n\nstruct POLICY_LSA_SERVER_ROLE_INFO {\n    POLICY_LSA_SERVER_ROLE LsaServerRole;\n}\nalias POLICY_LSA_SERVER_ROLE_INFO* PPOLICY_LSA_SERVER_ROLE_INFO;\n\nstruct POLICY_REPLICA_SOURCE_INFO {\n    LSA_UNICODE_STRING ReplicaSource;\n    LSA_UNICODE_STRING ReplicaAccountName;\n}\nalias POLICY_REPLICA_SOURCE_INFO* PPOLICY_REPLICA_SOURCE_INFO;\n\nstruct POLICY_DEFAULT_QUOTA_INFO {\n    QUOTA_LIMITS QuotaLimits;\n}\nalias POLICY_DEFAULT_QUOTA_INFO* PPOLICY_DEFAULT_QUOTA_INFO;\n\nstruct POLICY_MODIFICATION_INFO {\n    LARGE_INTEGER ModifiedId;\n    LARGE_INTEGER DatabaseCreationTime;\n}\nalias POLICY_MODIFICATION_INFO* PPOLICY_MODIFICATION_INFO;\n\nstruct POLICY_AUDIT_FULL_SET_INFO {\n    BOOLEAN ShutDownOnFull;\n}\nalias POLICY_AUDIT_FULL_SET_INFO* PPOLICY_AUDIT_FULL_SET_INFO;\n\nstruct POLICY_AUDIT_FULL_QUERY_INFO {\n    BOOLEAN ShutDownOnFull;\n    BOOLEAN LogIsFull;\n}\nalias POLICY_AUDIT_FULL_QUERY_INFO* PPOLICY_AUDIT_FULL_QUERY_INFO;\n\nstruct POLICY_EFS_INFO {\n    ULONG InfoLength;\n    PUCHAR EfsBlob;\n}\nalias POLICY_EFS_INFO* PPOLICY_EFS_INFO;\n\nstruct POLICY_LOCAL_IPSEC_REFERENCE_INFO {\n    LSA_UNICODE_STRING ObjectPath;\n}\nalias POLICY_LOCAL_IPSEC_REFERENCE_INFO* PPOLICY_LOCAL_IPSEC_REFERENCE_INFO;\n\nstruct POLICY_LOCAL_MACHINE_PASSWORD_INFO {\n    LARGE_INTEGER PasswordChangeInterval;\n}\nalias POLICY_LOCAL_MACHINE_PASSWORD_INFO* PPOLICY_LOCAL_MACHINE_PASSWORD_INFO;\n\nstruct POLICY_LOCAL_POLICY_LOCATION_INFO {\n    ULONG PolicyLocation;\n}\nalias POLICY_LOCAL_POLICY_LOCATION_INFO* PPOLICY_LOCAL_POLICY_LOCATION_INFO;\n\nstruct POLICY_LOCAL_QUALITY_OF_SERVICE_INFO{\n    ULONG QualityOfService;\n}\nalias POLICY_LOCAL_QUALITY_OF_SERVICE_INFO\n  POLICY_DOMAIN_QUALITY_OF_SERVICE_INFO;\nalias POLICY_LOCAL_QUALITY_OF_SERVICE_INFO*\n  PPOLICY_LOCAL_QUALITY_OF_SERVICE_INFO,\n  PPOLICY_DOMAIN_QUALITY_OF_SERVICE_INFO;\n\nstruct POLICY_DOMAIN_PUBLIC_KEY_INFO {\n    ULONG  InfoLength;\n    PUCHAR PublicKeyInfo;\n}\nalias POLICY_DOMAIN_PUBLIC_KEY_INFO* PPOLICY_DOMAIN_PUBLIC_KEY_INFO;\n\nstruct POLICY_DOMAIN_LOCKOUT_INFO {\n    LARGE_INTEGER LockoutDuration;\n    LARGE_INTEGER LockoutObservationWindow;\n    USHORT        LockoutThreshold;\n}\nalias POLICY_DOMAIN_LOCKOUT_INFO* PPOLICY_DOMAIN_LOCKOUT_INFO;\n\nstruct POLICY_DOMAIN_PASSWORD_INFO {\n    USHORT        MinPasswordLength;\n    USHORT        PasswordHistoryLength;\n    ULONG         PasswordProperties;\n    LARGE_INTEGER MaxPasswordAge;\n    LARGE_INTEGER MinPasswordAge;\n}\nalias POLICY_DOMAIN_PASSWORD_INFO* PPOLICY_DOMAIN_PASSWORD_INFO;\n\nstruct POLICY_DOMAIN_KERBEROS_TICKET_INFO {\n    ULONG         AuthenticationOptions;\n    LARGE_INTEGER MinTicketAge;\n    LARGE_INTEGER MaxTicketAge;\n    LARGE_INTEGER MaxRenewAge;\n    LARGE_INTEGER ProxyLifetime;\n    LARGE_INTEGER ForceLogoff;\n}\nalias POLICY_DOMAIN_KERBEROS_TICKET_INFO* PPOLICY_DOMAIN_KERBEROS_TICKET_INFO;\n\nmixin DECLARE_HANDLE!(\"LSA_HANDLE\");\nalias LSA_HANDLE* PLSA_HANDLE;\n\nstruct TRUSTED_DOMAIN_NAME_INFO {\n    LSA_UNICODE_STRING Name;\n}\nalias TRUSTED_DOMAIN_NAME_INFO* PTRUSTED_DOMAIN_NAME_INFO;\n\nstruct TRUSTED_CONTROLLERS_INFO {\n    ULONG               Entries;\n    PLSA_UNICODE_STRING Names;\n}\nalias TRUSTED_CONTROLLERS_INFO* PTRUSTED_CONTROLLERS_INFO;\n\nstruct TRUSTED_POSIX_OFFSET_INFO {\n    ULONG Offset;\n}\nalias TRUSTED_POSIX_OFFSET_INFO* PTRUSTED_POSIX_OFFSET_INFO;\n\nstruct TRUSTED_PASSWORD_INFO {\n    LSA_UNICODE_STRING Password;\n    LSA_UNICODE_STRING OldPassword;\n}\nalias TRUSTED_PASSWORD_INFO* PTRUSTED_PASSWORD_INFO;\n\nstruct TRUSTED_DOMAIN_INFORMATION_EX {\n    LSA_UNICODE_STRING Name;\n    LSA_UNICODE_STRING FlatName;\n    PSID               Sid;\n    ULONG              TrustDirection;\n    ULONG              TrustType;\n    ULONG              TrustAttributes;\n}\nalias TRUSTED_DOMAIN_INFORMATION_EX* PTRUSTED_DOMAIN_INFORMATION_EX;\n\nstruct LSA_AUTH_INFORMATION {\n    LARGE_INTEGER LastUpdateTime;\n    ULONG         AuthType;\n    ULONG         AuthInfoLength;\n    PUCHAR        AuthInfo;\n}\nalias LSA_AUTH_INFORMATION* PLSA_AUTH_INFORMATION;\n\nstruct TRUSTED_DOMAIN_AUTH_INFORMATION {\n    ULONG                 IncomingAuthInfos;\n    PLSA_AUTH_INFORMATION IncomingAuthenticationInformation;\n    PLSA_AUTH_INFORMATION IncomingPreviousAuthenticationInformation;\n    ULONG                 OutgoingAuthInfos;\n    PLSA_AUTH_INFORMATION OutgoingAuthenticationInformation;\n    PLSA_AUTH_INFORMATION OutgoingPreviousAuthenticationInformation;\n}\nalias TRUSTED_DOMAIN_AUTH_INFORMATION* PTRUSTED_DOMAIN_AUTH_INFORMATION;\n\nstruct TRUSTED_DOMAIN_FULL_INFORMATION {\n    TRUSTED_DOMAIN_INFORMATION_EX   Information;\n    TRUSTED_POSIX_OFFSET_INFO       PosixOffset;\n    TRUSTED_DOMAIN_AUTH_INFORMATION AuthInformation;\n}\nalias TRUSTED_DOMAIN_FULL_INFORMATION* PTRUSTED_DOMAIN_FULL_INFORMATION;\n\nextern (Windows) {\n    NTSTATUS LsaAddAccountRights(LSA_HANDLE, PSID, PLSA_UNICODE_STRING,\n      ULONG);\n    NTSTATUS LsaCallAuthenticationPackage(HANDLE, ULONG, PVOID, ULONG,\n      PVOID*, PULONG, PNTSTATUS);\n    NTSTATUS LsaClose(LSA_HANDLE);\n    NTSTATUS LsaConnectUntrusted(PHANDLE);\n    NTSTATUS LsaCreateTrustedDomainEx(LSA_HANDLE,\n      PTRUSTED_DOMAIN_INFORMATION_EX, PTRUSTED_DOMAIN_AUTH_INFORMATION,\n      ACCESS_MASK, PLSA_HANDLE);\n    NTSTATUS LsaDeleteTrustedDomain(LSA_HANDLE, PSID);\n    NTSTATUS LsaDeregisterLogonProcess(HANDLE);\n    NTSTATUS LsaEnumerateAccountRights(LSA_HANDLE, PSID, PLSA_UNICODE_STRING*,\n      PULONG);\n    NTSTATUS LsaEnumerateAccountsWithUserRight(LSA_HANDLE,\n      PLSA_UNICODE_STRING, PVOID*, PULONG);\n    NTSTATUS LsaEnumerateTrustedDomains(LSA_HANDLE, PLSA_ENUMERATION_HANDLE,\n      PVOID*, ULONG, PULONG);\n    NTSTATUS LsaEnumerateTrustedDomainsEx(LSA_HANDLE, PLSA_ENUMERATION_HANDLE,\n      TRUSTED_INFORMATION_CLASS, PVOID*, ULONG, PULONG);\n    NTSTATUS LsaFreeMemory(PVOID);\n    NTSTATUS LsaFreeReturnBuffer(PVOID);\n    NTSTATUS LsaLogonUser(HANDLE, PLSA_STRING, SECURITY_LOGON_TYPE, ULONG,\n      PVOID, ULONG, PTOKEN_GROUPS, PTOKEN_SOURCE, PVOID*, PULONG, PLUID,\n      PHANDLE, PQUOTA_LIMITS, PNTSTATUS);\n    NTSTATUS LsaLookupAuthenticationPackage(HANDLE, PLSA_STRING, PULONG);\n    NTSTATUS LsaLookupNames(LSA_HANDLE, ULONG, PLSA_UNICODE_STRING,\n      PLSA_REFERENCED_DOMAIN_LIST*, PLSA_TRANSLATED_SID*);\n    NTSTATUS LsaLookupSids(LSA_HANDLE, ULONG, PSID*,\n      PLSA_REFERENCED_DOMAIN_LIST*, PLSA_TRANSLATED_NAME*);\n    ULONG LsaNtStatusToWinError(NTSTATUS);\n    NTSTATUS LsaOpenPolicy(PLSA_UNICODE_STRING, PLSA_OBJECT_ATTRIBUTES,\n      ACCESS_MASK, PLSA_HANDLE);\n    NTSTATUS LsaQueryDomainInformationPolicy(LSA_HANDLE,\n      POLICY_DOMAIN_INFORMATION_CLASS, PVOID*);\n    NTSTATUS LsaQueryInformationPolicy(LSA_HANDLE, POLICY_INFORMATION_CLASS,\n      PVOID*);\n    NTSTATUS LsaQueryLocalInformationPolicy(LSA_HANDLE,\n      POLICY_LOCAL_INFORMATION_CLASS, PVOID*);\n    NTSTATUS LsaQueryTrustedDomainInfo(LSA_HANDLE, PSID,\n      TRUSTED_INFORMATION_CLASS, PVOID*);\n    NTSTATUS LsaQueryTrustedDomainInfoByName(LSA_HANDLE, PLSA_UNICODE_STRING,\n      TRUSTED_INFORMATION_CLASS, PVOID*);\n    NTSTATUS LsaRegisterLogonProcess(PLSA_STRING, PHANDLE,\n      PLSA_OPERATIONAL_MODE);\n    NTSTATUS LsaRemoveAccountRights(LSA_HANDLE, PSID, BOOLEAN,\n      PLSA_UNICODE_STRING, ULONG);\n    NTSTATUS LsaRetrievePrivateData(LSA_HANDLE, PLSA_UNICODE_STRING,\n      PLSA_UNICODE_STRING*);\n    NTSTATUS LsaSetDomainInformationPolicy(LSA_HANDLE,\n      POLICY_DOMAIN_INFORMATION_CLASS, PVOID);\n    NTSTATUS LsaSetInformationPolicy(LSA_HANDLE, POLICY_INFORMATION_CLASS,\n      PVOID);\n    NTSTATUS LsaSetLocalInformationPolicy(LSA_HANDLE,\n      POLICY_LOCAL_INFORMATION_CLASS, PVOID);\n    NTSTATUS LsaSetTrustedDomainInformation(LSA_HANDLE, PSID,\n      TRUSTED_INFORMATION_CLASS, PVOID);\n    NTSTATUS LsaSetTrustedDomainInfoByName(LSA_HANDLE, PLSA_UNICODE_STRING,\n      TRUSTED_INFORMATION_CLASS, PVOID);\n    NTSTATUS LsaStorePrivateData(LSA_HANDLE, PLSA_UNICODE_STRING,\n      PLSA_UNICODE_STRING);\n}\n\nalias NTSTATUS function(PUNICODE_STRING, ULONG, PUNICODE_STRING)\n  PSAM_PASSWORD_NOTIFICATION_ROUTINE;\nalias BOOLEAN function() PSAM_INIT_NOTIFICATION_ROUTINE;\nalias BOOLEAN function(PUNICODE_STRING, PUNICODE_STRING,\n  PUNICODE_STRING, BOOLEAN) PSAM_PASSWORD_FILTER_ROUTINE;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ntsecpkg.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Ellery Newcomer\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ntsecpkg.d)\n */\nmodule core.sys.windows.ntsecpkg;\nversion (Windows):\n\nimport core.sys.windows.windef, core.sys.windows.ntsecapi, core.sys.windows.security, core.sys.windows.ntdef, core.sys.windows.sspi;\nimport core.sys.windows.basetyps : GUID;\nimport core.sys.windows.winbase;\n\nextern(Windows):\n\nenum :ULONG{\n    ISC_REQ_DELEGATE = 1,\n    ISC_REQ_MUTUAL_AUTH = 2,\n    ISC_REQ_REPLAY_DETECT = 4,\n    ISC_REQ_SEQUENCE_DETECT = 8,\n    ISC_REQ_CONFIDENTIALITY  = 16,\n    ISC_REQ_USE_SESSION_KEY = 32,\n    ISC_REQ_PROMPT_FOR_CREDS = 64,\n    ISC_REQ_USE_SUPPLIED_CREDS  = 128,\n    ISC_REQ_ALLOCATE_MEMORY = 256,\n    ISC_REQ_USE_DCE_STYLE = 512,\n    ISC_REQ_DATAGRAM = 1024,\n    ISC_REQ_CONNECTION = 2048,\n    ISC_REQ_EXTENDED_ERROR = 16384,\n    ISC_REQ_STREAM = 32768,\n    ISC_REQ_INTEGRITY = 65536,\n    ISC_REQ_MANUAL_CRED_VALIDATION = 524288,\n    ISC_REQ_HTTP  = 268435456,\n}\n\nenum ISC_RET_EXTENDED_ERROR = 16384;\n\nenum :ULONG{\n    ASC_REQ_DELEGATE = 1,\n    ASC_REQ_MUTUAL_AUTH = 2,\n    ASC_REQ_REPLAY_DETECT = 4,\n    ASC_REQ_SEQUENCE_DETECT = 8,\n    ASC_REQ_CONFIDENTIALITY = 16,\n    ASC_REQ_USE_SESSION_KEY = 32,\n    ASC_REQ_ALLOCATE_MEMORY = 256,\n    ASC_REQ_USE_DCE_STYLE = 512,\n    ASC_REQ_DATAGRAM = 1024,\n    ASC_REQ_CONNECTION = 2048,\n    ASC_REQ_EXTENDED_ERROR = 32768,\n    ASC_REQ_STREAM = 65536,\n    ASC_REQ_INTEGRITY = 131072,\n}\n\nenum SECURITY_NATIVE_DREP  = 16;\nenum SECURITY_NETWORK_DREP = 0;\n\nenum :ULONG{\n    SECPKG_STATE_ENCRYPTION_PERMITTED               = 0x01,\n    SECPKG_STATE_STRONG_ENCRYPTION_PERMITTED        = 0x02,\n    SECPKG_STATE_DOMAIN_CONTROLLER                  = 0x04,\n    SECPKG_STATE_WORKSTATION                        = 0x08,\n    SECPKG_STATE_STANDALONE                         = 0x10,\n}\n\n/* enum definitions for Secure Service Provider/Authentication Packages */\nenum LSA_TOKEN_INFORMATION_TYPE {\n    LsaTokenInformationNull,\n    LsaTokenInformationV1\n}\nalias LSA_TOKEN_INFORMATION_TYPE* PLSA_TOKEN_INFORMATION_TYPE;\nenum SECPKG_EXTENDED_INFORMATION_CLASS\n{\n    SecpkgGssInfo = 1,\n    SecpkgContextThunks,\n    SecpkgMutualAuthLevel,\n    SecpkgMaxInfo\n}\nenum SECPKG_NAME_TYPE {\n    SecNameSamCompatible,\n    SecNameAlternateId,\n    SecNameFlat,\n    SecNameDN\n}\n\n/* struct definitions for SSP/AP */\nstruct SECPKG_PRIMARY_CRED {\n    LUID LogonId;\n    UNICODE_STRING DownlevelName;\n    UNICODE_STRING DomainName;\n    UNICODE_STRING Password;\n    UNICODE_STRING OldPassword;\n    PSID UserSid;\n    ULONG Flags;\n    UNICODE_STRING DnsDomainName;\n    UNICODE_STRING Upn;\n    UNICODE_STRING LogonServer;\n    UNICODE_STRING Spare1;\n    UNICODE_STRING Spare2;\n    UNICODE_STRING Spare3;\n    UNICODE_STRING Spare4;\n}\nalias SECPKG_PRIMARY_CRED* PSECPKG_PRIMARY_CRED;\nstruct SECPKG_SUPPLEMENTAL_CRED {\n    UNICODE_STRING PackageName;\n    ULONG CredentialSize;\n    PUCHAR Credentials;\n}\nalias SECPKG_SUPPLEMENTAL_CRED* PSECPKG_SUPPLEMENTAL_CRED;\nstruct SECPKG_SUPPLEMENTAL_CRED_ARRAY {\n    ULONG CredentialCount;\n    SECPKG_SUPPLEMENTAL_CRED[1] Credentials;\n}\nalias SECPKG_SUPPLEMENTAL_CRED_ARRAY* PSECPKG_SUPPLEMENTAL_CRED_ARRAY;\nstruct SECPKG_PARAMETERS {\n    ULONG Version;\n    ULONG MachineState;\n    ULONG SetupMode;\n    PSID DomainSid;\n    UNICODE_STRING DomainName;\n    UNICODE_STRING DnsDomainName;\n    GUID DomainGuid;\n}\nalias SECPKG_PARAMETERS* PSECPKG_PARAMETERS,PSECPKG_EVENT_DOMAIN_CHANGE;\nalias SECPKG_PARAMETERS SECPKG_EVENT_DOMAIN_CHANGE;\nstruct SECPKG_CLIENT_INFO {\n  LUID LogonId;\n  ULONG ProcessID;\n  ULONG ThreadID;\n  BOOLEAN HasTcbPrivilege;\n  BOOLEAN Impersonating;\n  BOOLEAN Restricted;\n}\nalias SECPKG_CLIENT_INFO* PSECPKG_CLIENT_INFO;\nstruct SECURITY_USER_DATA {\n    SECURITY_STRING UserName;\n    SECURITY_STRING LogonDomainName;\n    SECURITY_STRING LogonServer;\n    PSID pSid;\n}\nalias SECURITY_USER_DATA* PSECURITY_USER_DATA,PSecurityUserData;\nalias SECURITY_USER_DATA SecurityUserData;\nstruct SECPKG_GSS_INFO {\n    ULONG EncodedIdLength;\n    UCHAR[4] EncodedId;\n}\nalias SECPKG_GSS_INFO* PSECPKG_GSS_INFO;\nstruct SECPKG_CONTEXT_THUNKS {\n    ULONG InfoLevelCount;\n    ULONG[1] Levels;\n}\nalias SECPKG_CONTEXT_THUNKS* PSECPKG_CONTEXT_THUNKS;\nstruct SECPKG_MUTUAL_AUTH_LEVEL {\n    ULONG MutualAuthLevel;\n}\nalias SECPKG_MUTUAL_AUTH_LEVEL* PSECPKG_MUTUAL_AUTH_LEVEL;\nstruct SECPKG_CALL_INFO {\n    ULONG ProcessId;\n    ULONG ThreadId;\n    ULONG Attributes;\n    ULONG CallCount;\n}\nalias SECPKG_CALL_INFO* PSECPKG_CALL_INFO;\nstruct SECPKG_EXTENDED_INFORMATION {\n    SECPKG_EXTENDED_INFORMATION_CLASS Class;\n    union _Info{\n        SECPKG_GSS_INFO GssInfo;\n        SECPKG_CONTEXT_THUNKS ContextThunks;\n        SECPKG_MUTUAL_AUTH_LEVEL MutualAuthLevel;\n    }\n    _Info Info;\n}\nalias SECPKG_EXTENDED_INFORMATION* PSECPKG_EXTENDED_INFORMATION;\n\n/* callbacks implemented by SSP/AP dlls and called by the LSA */\nalias void function(ULONG_PTR, ULONG_PTR, PSecBuffer,\n PSecBuffer) PLSA_CALLBACK_FUNCTION;\n\n/* misc typedefs used in the below prototypes */\nalias PVOID* PLSA_CLIENT_REQUEST;\nalias ULONG_PTR LSA_SEC_HANDLE;\nalias LSA_SEC_HANDLE* PLSA_SEC_HANDLE;\nalias LPTHREAD_START_ROUTINE SEC_THREAD_START;\nalias PSECURITY_ATTRIBUTES SEC_ATTRS;\n\n/* functions used by SSP/AP obtainable by dispatch tables */\nalias NTSTATUS function(ULONG, PLSA_CALLBACK_FUNCTION) PLSA_REGISTER_CALLBACK;\nalias NTSTATUS function(PLUID) PLSA_CREATE_LOGON_SESSION;\nalias NTSTATUS function(PLUID) PLSA_DELETE_LOGON_SESSION;\nalias NTSTATUS function(PLUID, ULONG, PLSA_STRING,\n PLSA_STRING) PLSA_ADD_CREDENTIAL;\nalias NTSTATUS function(PLUID, ULONG, PULONG, BOOLEAN,\n PLSA_STRING, PULONG, PLSA_STRING) PLSA_GET_CREDENTIALS;\nalias NTSTATUS function(PLUID, ULONG, PLSA_STRING) PLSA_DELETE_CREDENTIAL;\nalias PVOID function(ULONG) PLSA_ALLOCATE_LSA_HEAP;\nalias void function(PVOID) PLSA_FREE_LSA_HEAP;\nalias NTSTATUS function(PLSA_CLIENT_REQUEST,\n ULONG, PVOID*) PLSA_ALLOCATE_CLIENT_BUFFER;\nalias NTSTATUS function(PLSA_CLIENT_REQUEST, PVOID) PLSA_FREE_CLIENT_BUFFER;\nalias NTSTATUS function(PLSA_CLIENT_REQUEST, ULONG,\n PVOID, PVOID) PLSA_COPY_TO_CLIENT_BUFFER;\nalias NTSTATUS function(PLSA_CLIENT_REQUEST,\n ULONG, PVOID, PVOID) PLSA_COPY_FROM_CLIENT_BUFFER;\nalias NTSTATUS function() PLSA_IMPERSONATE_CLIENT;\nalias NTSTATUS function() PLSA_UNLOAD_PACKAGE;\nalias NTSTATUS function(HANDLE, PHANDLE) PLSA_DUPLICATE_HANDLE;\nalias NTSTATUS function(PLUID, ULONG,\n PVOID, BOOLEAN) PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS;\nalias HANDLE function(SEC_ATTRS, ULONG, SEC_THREAD_START,\n PVOID, ULONG, PULONG) PLSA_CREATE_THREAD;\nalias NTSTATUS function(PSECPKG_CLIENT_INFO) PLSA_GET_CLIENT_INFO;\nalias HANDLE function(SEC_THREAD_START, PVOID,\n ULONG, ULONG, ULONG, ULONG, HANDLE) PLSA_REGISTER_NOTIFICATION;\nalias NTSTATUS function(HANDLE) PLSA_CANCEL_NOTIFICATION;\nalias NTSTATUS function(PSecBuffer, PSecBuffer) PLSA_MAP_BUFFER;\nalias NTSTATUS function(PLUID, PTOKEN_SOURCE,\n SECURITY_LOGON_TYPE, SECURITY_IMPERSONATION_LEVEL, LSA_TOKEN_INFORMATION_TYPE,\n PVOID, PTOKEN_GROUPS, PUNICODE_STRING, PUNICODE_STRING, PUNICODE_STRING,\n PUNICODE_STRING, PHANDLE, PNTSTATUS) PLSA_CREATE_TOKEN;\nalias void function(NTSTATUS, NTSTATUS, PUNICODE_STRING,\n PUNICODE_STRING, PUNICODE_STRING, PSID, SECURITY_LOGON_TYPE,\n PTOKEN_SOURCE, PLUID) PLSA_AUDIT_LOGON;\nalias NTSTATUS function(PUNICODE_STRING, PVOID, ULONG,\n PVOID*, PULONG, PNTSTATUS) PLSA_CALL_PACKAGE;\nalias BOOLEAN function(PSECPKG_CALL_INFO) PLSA_GET_CALL_INFO;\nalias NTSTATUS function(PUNICODE_STRING, PVOID, PVOID,\n ULONG, PVOID*, PULONG, PNTSTATUS) PLSA_CALL_PACKAGEEX;\nalias PVOID function(ULONG, ULONG) PLSA_CREATE_SHARED_MEMORY;\nalias PVOID function(PVOID, ULONG) PLSA_ALLOCATE_SHARED_MEMORY;\nalias void function(PVOID, PVOID) PLSA_FREE_SHARED_MEMORY;\nalias BOOLEAN function(PVOID) PLSA_DELETE_SHARED_MEMORY;\nalias NTSTATUS function(PSECURITY_STRING, SECPKG_NAME_TYPE,\n PSECURITY_STRING, BOOLEAN, ULONG, PVOID*) PLSA_OPEN_SAM_USER;\nalias NTSTATUS function(PVOID, PVOID *, PULONG,\n PVOID *, PULONG) PLSA_GET_USER_CREDENTIALS;\nalias NTSTATUS function(PVOID, PUCHAR *, PULONG) PLSA_GET_USER_AUTH_DATA;\nalias NTSTATUS function(PVOID) PLSA_CLOSE_SAM_USER;\nalias NTSTATUS function(PVOID, ULONG,\n SECURITY_IMPERSONATION_LEVEL, PTOKEN_SOURCE, SECURITY_LOGON_TYPE,\n PUNICODE_STRING, PHANDLE, PLUID, PUNICODE_STRING, PNTSTATUS) PLSA_CONVERT_AUTH_DATA_TO_TOKEN;\nalias NTSTATUS function(PCHAR, ULONG_PTR, ULONG_PTR,\n PSecBuffer, PSecBuffer) PLSA_CLIENT_CALLBACK;\nalias NTSTATUS function(PSECPKG_PRIMARY_CRED, PSECPKG_SUPPLEMENTAL_CRED_ARRAY) PLSA_UPDATE_PRIMARY_CREDENTIALS;\nalias NTSTATUS function(PSECURITY_STRING,\n SECPKG_NAME_TYPE, PSECURITY_STRING, PUCHAR *, PULONG, PUNICODE_STRING) PLSA_GET_AUTH_DATA_FOR_USER;\nalias NTSTATUS function(ULONG, BOOLEAN,\n PUNICODE_STRING, PUNICODE_STRING, ULONG, PUNICODE_STRING, PUNICODE_STRING,\n PULONG) PLSA_CRACK_SINGLE_NAME;\nalias NTSTATUS function(ULONG, BOOLEAN,\n PUNICODE_STRING, PUNICODE_STRING, PUNICODE_STRING, NTSTATUS) PLSA_AUDIT_ACCOUNT_LOGON;\nalias NTSTATUS function(PUNICODE_STRING, PVOID,\n PVOID, ULONG, PVOID*, PULONG, PNTSTATUS) PLSA_CALL_PACKAGE_PASSTHROUGH;\n\n/* Dispatch tables of functions used by SSP/AP */\nstruct SECPKG_DLL_FUNCTIONS {\n    PLSA_ALLOCATE_LSA_HEAP AllocateHeap;\n    PLSA_FREE_LSA_HEAP FreeHeap;\n    PLSA_REGISTER_CALLBACK RegisterCallback;\n}\nalias SECPKG_DLL_FUNCTIONS* PSECPKG_DLL_FUNCTIONS;\nstruct LSA_DISPATCH_TABLE {\n    PLSA_CREATE_LOGON_SESSION CreateLogonSession;\n    PLSA_DELETE_LOGON_SESSION DeleteLogonSession;\n    PLSA_ADD_CREDENTIAL AddCredential;\n    PLSA_GET_CREDENTIALS GetCredentials;\n    PLSA_DELETE_CREDENTIAL DeleteCredential;\n    PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap;\n    PLSA_FREE_LSA_HEAP FreeLsaHeap;\n    PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;\n    PLSA_FREE_CLIENT_BUFFER FreeClientBuffer;\n    PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer;\n    PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer;\n}\nalias LSA_DISPATCH_TABLE* PLSA_DISPATCH_TABLE;\nstruct LSA_SECPKG_FUNCTION_TABLE {\n    PLSA_CREATE_LOGON_SESSION CreateLogonSession;\n    PLSA_DELETE_LOGON_SESSION DeleteLogonSession;\n    PLSA_ADD_CREDENTIAL AddCredential;\n    PLSA_GET_CREDENTIALS GetCredentials;\n    PLSA_DELETE_CREDENTIAL DeleteCredential;\n    PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap;\n    PLSA_FREE_LSA_HEAP FreeLsaHeap;\n    PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;\n    PLSA_FREE_CLIENT_BUFFER FreeClientBuffer;\n    PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer;\n    PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer;\n    PLSA_IMPERSONATE_CLIENT ImpersonateClient;\n    PLSA_UNLOAD_PACKAGE UnloadPackage;\n    PLSA_DUPLICATE_HANDLE DuplicateHandle;\n    PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS SaveSupplementalCredentials;\n    PLSA_CREATE_THREAD CreateThread;\n    PLSA_GET_CLIENT_INFO GetClientInfo;\n    PLSA_REGISTER_NOTIFICATION RegisterNotification;\n    PLSA_CANCEL_NOTIFICATION CancelNotification;\n    PLSA_MAP_BUFFER MapBuffer;\n    PLSA_CREATE_TOKEN CreateToken;\n    PLSA_AUDIT_LOGON AuditLogon;\n    PLSA_CALL_PACKAGE CallPackage;\n    PLSA_FREE_LSA_HEAP FreeReturnBuffer;\n    PLSA_GET_CALL_INFO GetCallInfo;\n    PLSA_CALL_PACKAGEEX CallPackageEx;\n    PLSA_CREATE_SHARED_MEMORY CreateSharedMemory;\n    PLSA_ALLOCATE_SHARED_MEMORY AllocateSharedMemory;\n    PLSA_FREE_SHARED_MEMORY FreeSharedMemory;\n    PLSA_DELETE_SHARED_MEMORY DeleteSharedMemory;\n    PLSA_OPEN_SAM_USER OpenSamUser;\n    PLSA_GET_USER_CREDENTIALS GetUserCredentials;\n    PLSA_GET_USER_AUTH_DATA GetUserAuthData;\n    PLSA_CLOSE_SAM_USER CloseSamUser;\n    PLSA_CONVERT_AUTH_DATA_TO_TOKEN ConvertAuthDataToToken;\n    PLSA_CLIENT_CALLBACK ClientCallback;\n    PLSA_UPDATE_PRIMARY_CREDENTIALS UpdateCredentials;\n    PLSA_GET_AUTH_DATA_FOR_USER GetAuthDataForUser;\n    PLSA_CRACK_SINGLE_NAME CrackSingleName;\n    PLSA_AUDIT_ACCOUNT_LOGON AuditAccountLogon;\n    PLSA_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough;\n}\nalias LSA_SECPKG_FUNCTION_TABLE* PLSA_SECPKG_FUNCTION_TABLE;\n\n/* functions implemented by SSP/AP obtainable by dispatch tables */\nalias NTSTATUS function(ULONG, PLSA_DISPATCH_TABLE,\n PLSA_STRING, PLSA_STRING, PLSA_STRING *) PLSA_AP_INITIALIZE_PACKAGE;\nalias NTSTATUS function(LPWSTR, LPWSTR, LPWSTR, LPWSTR,\n DWORD, DWORD, PHANDLE) PLSA_AP_LOGON_USER;\nalias NTSTATUS function(PUNICODE_STRING, PVOID, ULONG,\n PVOID *, PULONG, PNTSTATUS) PLSA_AP_CALL_PACKAGE;\nalias void function(PLUID) PLSA_AP_LOGON_TERMINATED;\nalias NTSTATUS function(PLSA_CLIENT_REQUEST,\n PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS) PLSA_AP_CALL_PACKAGE_UNTRUSTED;\nalias NTSTATUS function(PUNICODE_STRING,\n PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS) PLSA_AP_CALL_PACKAGE_PASSTHROUGH;\nalias NTSTATUS function(PLSA_CLIENT_REQUEST,\n SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,\n PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,\n PUNICODE_STRING *) PLSA_AP_LOGON_USER_EX;\nalias NTSTATUS function(PLSA_CLIENT_REQUEST,\n SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,\n PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,\n PUNICODE_STRING *, PSECPKG_PRIMARY_CRED, PSECPKG_SUPPLEMENTAL_CRED_ARRAY *) PLSA_AP_LOGON_USER_EX2;\nalias NTSTATUS function(ULONG_PTR, PSECPKG_PARAMETERS,\n PLSA_SECPKG_FUNCTION_TABLE) SpInitializeFn;\nalias NTSTATUS function() SpShutDownFn;\nalias NTSTATUS function(PSecPkgInfoW) SpGetInfoFn;\nalias NTSTATUS function(SECURITY_LOGON_TYPE,\n PUNICODE_STRING, PSECPKG_PRIMARY_CRED, PSECPKG_SUPPLEMENTAL_CRED) SpAcceptCredentialsFn;\nalias NTSTATUS function(PUNICODE_STRING, ULONG,\n PLUID, PVOID, PVOID, PVOID, PLSA_SEC_HANDLE, PTimeStamp) SpAcquireCredentialsHandleFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, ULONG, PVOID) SpQueryCredentialsAttributesFn;\nalias NTSTATUS function(LSA_SEC_HANDLE) SpFreeCredentialsHandleFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, PSecBuffer) SpSaveCredentialsFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, PSecBuffer) SpGetCredentialsFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, PSecBuffer) SpDeleteCredentialsFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, LSA_SEC_HANDLE,\n PUNICODE_STRING, ULONG, ULONG, PSecBufferDesc, PLSA_SEC_HANDLE, PSecBufferDesc,\n PULONG, PTimeStamp, PBOOLEAN, PSecBuffer) SpInitLsaModeContextFn;\nalias NTSTATUS function(LSA_SEC_HANDLE,\n LSA_SEC_HANDLE, PSecBufferDesc, ULONG, ULONG, PLSA_SEC_HANDLE, PSecBufferDesc,\n PULONG, PTimeStamp, PBOOLEAN, PSecBuffer) SpAcceptLsaModeContextFn;\nalias NTSTATUS function(LSA_SEC_HANDLE) SpDeleteContextFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, PSecBufferDesc) SpApplyControlTokenFn;\nalias NTSTATUS function(PLUID, ULONG, PSecurityUserData *) SpGetUserInfoFn;\nalias NTSTATUS function(SECPKG_EXTENDED_INFORMATION_CLASS, PSECPKG_EXTENDED_INFORMATION *) SpGetExtendedInformationFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, ULONG, PVOID) SpQueryContextAttributesFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, PUNICODE_STRING,\n PUNICODE_STRING, ULONG, PVOID, PVOID, PVOID, PTimeStamp) SpAddCredentialsFn;\nalias NTSTATUS function(\n SECPKG_EXTENDED_INFORMATION_CLASS, PSECPKG_EXTENDED_INFORMATION) SpSetExtendedInformationFn;\nalias NTSTATUS function(ULONG, PSECPKG_DLL_FUNCTIONS,\n PVOID *) SpInstanceInitFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, PSecBuffer) SpInitUserModeContextFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, ULONG,\n PSecBufferDesc, ULONG) SpMakeSignatureFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, PSecBufferDesc,\n ULONG, PULONG) SpVerifySignatureFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, ULONG, PSecBufferDesc,\n ULONG) SpSealMessageFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, PSecBufferDesc,\n ULONG, PULONG) SpUnsealMessageFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, PHANDLE) SpGetContextTokenFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, PSecBufferDesc) SpCompleteAuthTokenFn;\nalias NTSTATUS function(PSecBuffer, PSecBuffer) SpFormatCredentialsFn;\nalias NTSTATUS function(ULONG, PUCHAR, PULONG,\n PVOID *) SpMarshallSupplementalCredsFn;\nalias NTSTATUS function(LSA_SEC_HANDLE, ULONG,\n PSecBuffer, PHANDLE) SpExportSecurityContextFn;\nalias NTSTATUS function(PSecBuffer, HANDLE,\n PLSA_SEC_HANDLE) SpImportSecurityContextFn;\n\n/* Dispatch tables of functions implemented by SSP/AP */\nstruct SECPKG_FUNCTION_TABLE {\n    PLSA_AP_INITIALIZE_PACKAGE InitializePackage;\n    PLSA_AP_LOGON_USER LogonUser;\n    PLSA_AP_CALL_PACKAGE CallPackage;\n    PLSA_AP_LOGON_TERMINATED LogonTerminated;\n    PLSA_AP_CALL_PACKAGE_UNTRUSTED CallPackageUntrusted;\n    PLSA_AP_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough;\n    PLSA_AP_LOGON_USER_EX LogonUserEx;\n    PLSA_AP_LOGON_USER_EX2 LogonUserEx2;\n    SpInitializeFn *Initialize;\n    SpShutDownFn *Shutdown;\n    SpGetInfoFn *GetInfo;\n    SpAcceptCredentialsFn *AcceptCredentials;\n    SpAcquireCredentialsHandleFn *AcquireCredentialsHandle;\n    SpQueryCredentialsAttributesFn *QueryCredentialsAttributes;\n    SpFreeCredentialsHandleFn *FreeCredentialsHandle;\n    SpSaveCredentialsFn *SaveCredentials;\n    SpGetCredentialsFn *GetCredentials;\n    SpDeleteCredentialsFn *DeleteCredentials;\n    SpInitLsaModeContextFn *InitLsaModeContext;\n    SpAcceptLsaModeContextFn *AcceptLsaModeContext;\n    SpDeleteContextFn *DeleteContext;\n    SpApplyControlTokenFn *ApplyControlToken;\n    SpGetUserInfoFn *GetUserInfo;\n    SpGetExtendedInformationFn *GetExtendedInformation;\n    SpQueryContextAttributesFn *QueryContextAttributes;\n    SpAddCredentialsFn *AddCredentials;\n    SpSetExtendedInformationFn *SetExtendedInformation;\n}\nalias SECPKG_FUNCTION_TABLE* PSECPKG_FUNCTION_TABLE;\n\nstruct SECPKG_USER_FUNCTION_TABLE {\n    SpInstanceInitFn *InstanceInit;\n    SpInitUserModeContextFn *InitUserModeContext;\n    SpMakeSignatureFn *MakeSignature;\n    SpVerifySignatureFn *VerifySignature;\n    SpSealMessageFn *SealMessage;\n    SpUnsealMessageFn *UnsealMessage;\n    SpGetContextTokenFn *GetContextToken;\n    SpQueryContextAttributesFn *QueryContextAttributes;\n    SpCompleteAuthTokenFn *CompleteAuthToken;\n    SpDeleteContextFn *DeleteUserModeContext;\n    SpFormatCredentialsFn *FormatCredentials;\n    SpMarshallSupplementalCredsFn *MarshallSupplementalCreds;\n    SpExportSecurityContextFn *ExportContext;\n    SpImportSecurityContextFn *ImportContext;\n}\nalias SECPKG_USER_FUNCTION_TABLE* PSECPKG_USER_FUNCTION_TABLE;\n\n/* Entry points to SSP/AP */\nalias NTSTATUS function(ULONG, PULONG,\n PSECPKG_FUNCTION_TABLE *, PULONG) SpLsaModeInitializeFn;\nalias NTSTATUS function(ULONG, PULONG,\n PSECPKG_USER_FUNCTION_TABLE *, PULONG) SpUserModeInitializeFn;\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/oaidl.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_oaidl.d)\n */\nmodule core.sys.windows.oaidl;\nversion (Windows):\n\nprivate import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;\n\nenum DISPID_UNKNOWN = -1;\nenum DISPID_VALUE = 0;\nenum DISPID_PROPERTYPUT = -3;\nenum DISPID_NEWENUM = -4;\nenum DISPID_EVALUATE = -5;\nenum DISPID_CONSTRUCTOR = -6;\nenum DISPID_DESTRUCTOR = -7;\nenum DISPID_COLLECT = -8;\n\nenum FADF_AUTO = 1;\nenum FADF_STATIC = 2;\nenum FADF_EMBEDDED = 4;\nenum FADF_FIXEDSIZE = 16;\nenum FADF_RECORD = 32;\nenum FADF_HAVEIID = 64;\nenum FADF_HAVEVARTYPE = 128;\nenum FADF_BSTR = 256;\nenum FADF_UNKNOWN = 512;\nenum FADF_DISPATCH = 1024;\nenum FADF_VARIANT = 2048;\nenum FADF_RESERVED = 0xf0e8;\nenum FADF_DATADELETED = 0x1000;\nenum FADF_CREATEVECTOR = 0x2000;\n\nenum PARAMFLAG_NONE = 0;\nenum PARAMFLAG_FIN = 1;\nenum PARAMFLAG_FOUT = 2;\nenum PARAMFLAG_FLCID = 4;\nenum PARAMFLAG_FRETVAL = 8;\nenum PARAMFLAG_FOPT = 16;\nenum PARAMFLAG_FHASDEFAULT = 32;\nenum PARAMFLAG_FHASCUSTDATA = 64;\n\nenum IDLFLAG_NONE = PARAMFLAG_NONE;\nenum IDLFLAG_FIN = PARAMFLAG_FIN;\nenum IDLFLAG_FOUT = PARAMFLAG_FOUT;\nenum IDLFLAG_FLCID = PARAMFLAG_FLCID;\nenum IDLFLAG_FRETVAL = PARAMFLAG_FRETVAL;\n\nenum IMPLTYPEFLAG_FDEFAULT       = 1;\nenum IMPLTYPEFLAG_FSOURCE        = 2;\nenum IMPLTYPEFLAG_FRESTRICTED    = 4;\nenum IMPLTYPEFLAG_FDEFAULTVTABLE = 8;\n\n\nenum SYSKIND {\n    SYS_WIN16,\n    SYS_WIN32,\n    SYS_MAC\n}\n\nenum LIBFLAGS {\n    LIBFLAG_FRESTRICTED   = 1,\n    LIBFLAG_FCONTROL      = 2,\n    LIBFLAG_FHIDDEN       = 4,\n    LIBFLAG_FHASDISKIMAGE = 8\n}\n\nstruct TLIBATTR {\n    GUID guid;\n    LCID lcid;\n    SYSKIND syskind;\n    WORD wMajorVerNum;\n    WORD wMinorVerNum;\n    WORD wLibFlags;\n}\nalias TLIBATTR* LPTLIBATTR;\n\nalias CY CURRENCY;\n\nstruct SAFEARRAYBOUND {\n    ULONG cElements;\n    LONG lLbound;\n}\nalias SAFEARRAYBOUND* LPSAFEARRAYBOUND;\n\nstruct SAFEARR_BSTR {\n    ULONG Size;\n    wireBSTR* aBstr;\n}\n\nstruct SAFEARR_UNKNOWN {\n    ULONG Size;\n    IUnknown* apUnknown;\n}\n\nstruct SAFEARR_DISPATCH {\n    ULONG Size;\n    LPDISPATCH* apDispatch;\n}\n\nstruct SAFEARR_VARIANT {\n    ULONG Size;\n    _wireVARIANT* aVariant;\n}\n\nenum SF_TYPE {\n    SF_ERROR=VARENUM.VT_ERROR,\n    SF_I1=VARENUM.VT_I1,\n    SF_I2=VARENUM.VT_I2,\n    SF_I4=VARENUM.VT_I4,\n    SF_I8=VARENUM.VT_I8,\n    SF_BSTR=VARENUM.VT_BSTR,\n    SF_UNKNOWN=VARENUM.VT_UNKNOWN,\n    SF_DISPATCH=VARENUM.VT_DISPATCH,\n    SF_VARIANT=VARENUM.VT_VARIANT\n}\n\nstruct _wireBRECORD {\n    ULONG fFlags;\n    ULONG clSize;\n    LPRECORDINFO* pRecInfo;\n    byte* pRecord;\n}\nalias _wireBRECORD* wireBRECORD;\n\nstruct SAFEARR_BRECORD {\n    ULONG Size;\n    wireBRECORD* aRecord;\n}\n\nstruct SAFEARR_HAVEIID {\n    ULONG Size;\n    IUnknown* apUnknown;\n    IID iid;\n}\n\nstruct SAFEARRAYUNION {\n    ULONG sfType;\n    union _u {\n        SAFEARR_BSTR BstrStr;\n        SAFEARR_UNKNOWN UnknownStr;\n        SAFEARR_DISPATCH DispatchStr;\n        SAFEARR_VARIANT VariantStr;\n        SAFEARR_BRECORD RecordStr;\n        SAFEARR_HAVEIID HaveIidStr;\n        BYTE_SIZEDARR ByteStr;\n        WORD_SIZEDARR WordStr;\n        DWORD_SIZEDARR LongStr;\n        HYPER_SIZEDARR HyperStr;\n    }\n    _u u;\n}\n\nstruct _wireSAFEARRAY {\n    USHORT cDims;\n    USHORT fFeatures;\n    ULONG cbElements;\n    ULONG cLocks;\n    SAFEARRAYUNION uArrayStructs;\n    SAFEARRAYBOUND[1] rgsabound;\n}\nalias _wireSAFEARRAY* wireSAFEARRAY;\n\nalias wireSAFEARRAY* wirePSAFEARRAY;\n\nstruct SAFEARRAY {\n    USHORT cDims;\n    USHORT fFeatures;\n    ULONG cbElements;\n    ULONG cLocks;\n    PVOID pvData;\n    SAFEARRAYBOUND[1] rgsabound;\n}\nalias SAFEARRAY* LPSAFEARRAY;\n\nstruct VARIANT {\n    union {\n        struct {\n            VARTYPE vt;\n            WORD wReserved1;\n            WORD wReserved2;\n            WORD wReserved3;\n            union {\n                int lVal;\n                LONGLONG llVal;\n                ubyte bVal;\n                short iVal;\n                float fltVal;\n                double dblVal;\n                VARIANT_BOOL  boolVal;\n                SCODE scode;\n                CY cyVal;\n                DATE date;\n                BSTR bstrVal;\n                IUnknown punkVal;\n                IDispatch pdispVal;\n                SAFEARRAY* parray;\n                ubyte* pbVal;\n                short* piVal;\n                int* plVal;\n                LONGLONG* pllVal;\n                float* pfltVal;\n                double* pdblVal;\n                VARIANT_BOOL* pboolVal;\n                _VARIANT_BOOL*  pbool;\n                SCODE* pscode;\n                CY* pcyVal;\n                DATE* pdate;\n                BSTR* pbstrVal;\n                IUnknown* ppunkVal;\n                IDispatch* ppdispVal;\n                SAFEARRAY** pparray;\n                VARIANT* pvarVal;\n                void* byref;\n                CHAR cVal;\n                USHORT uiVal;\n                ULONG ulVal;\n                ULONGLONG ullVal;\n                INT intVal;\n                UINT uintVal;\n                DECIMAL* pdecVal;\n                CHAR*  pcVal;\n                USHORT*  puiVal;\n                ULONG*  pulVal;\n                ULONGLONG* pullVal;\n                INT*  pintVal;\n                UINT*  puintVal;\n                struct {\n                    PVOID pvRecord;\n                    IRecordInfo pRecInfo;\n                }\n            }\n        }\n        DECIMAL decVal;\n    }\n}\nalias VARIANT* LPVARIANT;\n\nalias VARIANT VARIANTARG;\nalias VARIANT* LPVARIANTARG;\n\nstruct _wireVARIANT {\n    DWORD clSize;\n    DWORD rpcReserved;\n    USHORT vt;\n    USHORT wReserved1;\n    USHORT wReserved2;\n    USHORT wReserved3;\n    union {\n        LONG lVal;\n        LONGLONG llVal;\n        BYTE bVal;\n        SHORT iVal;\n        FLOAT fltVal;\n        DOUBLE dblVal;\n        VARIANT_BOOL boolVal;\n        SCODE scode;\n        CY cyVal;\n        DATE date;\n        wireBSTR bstrVal;\n        IUnknown punkVal;\n        LPDISPATCH pdispVal;\n        wirePSAFEARRAY parray;\n        wireBRECORD brecVal;\n        BYTE* pbVal;\n        SHORT* piVal;\n        LONG* plVal;\n        LONGLONG* pllVal;\n        FLOAT* pfltVal;\n        DOUBLE* pdblVal;\n        VARIANT_BOOL* pboolVal;\n        SCODE* pscode;\n        CY* pcyVal;\n        DATE* pdate;\n        wireBSTR* pbstrVal;\n        IUnknown* ppunkVal;\n        LPDISPATCH* ppdispVal;\n        wirePSAFEARRAY* pparray;\n        wireVARIANT* pvarVal;\n        CHAR cVal;\n        USHORT uiVal;\n        ULONG ulVal;\n        ULONGLONG ullVal;\n        INT intVal;\n        UINT uintVal;\n        DECIMAL decVal;\n        DECIMAL* pdecVal;\n        CHAR* pcVal;\n        USHORT* puiVal;\n        ULONG* pulVal;\n        ULONGLONG* pullVal;\n        INT* pintVal;\n        UINT* puintVal;\n    }\n}\nalias _wireVARIANT* wireVARIANT;\n\nalias LONG DISPID;\nalias DISPID MEMBERID;\nalias DWORD HREFTYPE;\n\nenum TYPEKIND {\n    TKIND_ENUM, TKIND_RECORD, TKIND_MODULE, TKIND_INTERFACE, TKIND_DISPATCH,\n    TKIND_COCLASS, TKIND_ALIAS, TKIND_UNION, TKIND_MAX\n}\n\nstruct TYPEDESC {\n    union {\n        TYPEDESC* lptdesc;\n        ARRAYDESC* lpadesc;\n        HREFTYPE hreftype;\n    }\n    VARTYPE vt;\n}\n\nstruct ARRAYDESC {\n    TYPEDESC tdescElem;\n    USHORT cDims;\n    SAFEARRAYBOUND[1] rgbounds;\n}\n\nstruct PARAMDESCEX {\n    ULONG cBytes;\n    VARIANTARG varDefaultValue;\n}\nalias PARAMDESCEX* LPPARAMDESCEX;\n\nstruct PARAMDESC {\n    LPPARAMDESCEX pparamdescex;\n    USHORT wParamFlags;\n}\nalias PARAMDESC* LPPARAMDESC;\n\nstruct IDLDESC {\n    ULONG_PTR dwReserved;\n    USHORT wIDLFlags;\n}\nalias IDLDESC* LPIDLDESC;\n\nstruct ELEMDESC {\n    TYPEDESC tdesc;\n    union {\n        IDLDESC idldesc;\n        PARAMDESC paramdesc;\n    }\n}\nalias ELEMDESC* LPELEMDESC;\n\nstruct TYPEATTR {\n    GUID guid;\n    LCID lcid;\n    DWORD dwReserved;\n    MEMBERID memidConstructor;\n    MEMBERID memidDestructor;\n    LPOLESTR lpstrSchema;\n    ULONG cbSizeInstance;\n    TYPEKIND typekind;\n    WORD cFuncs;\n    WORD cVars;\n    WORD cImplTypes;\n    WORD cbSizeVft;\n    WORD cbAlignment;\n    WORD wTypeFlags;\n    WORD wMajorVerNum;\n    WORD wMinorVerNum;\n    TYPEDESC tdescAlias;\n    IDLDESC idldescType;\n}\nalias TYPEATTR* LPTYPEATTR;\n\nstruct DISPPARAMS {\n    VARIANTARG* rgvarg;\n    DISPID* rgdispidNamedArgs;\n    UINT cArgs;\n    UINT cNamedArgs;\n}\n\nstruct EXCEPINFO {\n    WORD wCode;\n    WORD wReserved;\n    BSTR bstrSource;\n    BSTR bstrDescription;\n    BSTR bstrHelpFile;\n    DWORD dwHelpContext;\n    PVOID pvReserved;\n    extern (Windows) {\n    HRESULT function (EXCEPINFO* ) pfnDeferredFillIn;\n    }\n    SCODE scode;\n}\nalias EXCEPINFO* LPEXCEPINFO;\n\nenum CALLCONV {\n    CC_FASTCALL,\n    CC_CDECL,\n    CC_MSCPASCAL,\n    CC_PASCAL=CC_MSCPASCAL,\n    CC_MACPASCAL,\n    CC_STDCALL,\n    CC_FPFASTCALL,\n    CC_SYSCALL,\n    CC_MPWCDECL,\n    CC_MPWPASCAL,\n    CC_MAX=CC_MPWPASCAL\n}\n\nenum FUNCKIND {\n    FUNC_VIRTUAL,\n    FUNC_PUREVIRTUAL,\n    FUNC_NONVIRTUAL,\n    FUNC_STATIC,\n    FUNC_DISPATCH\n}\n\nenum INVOKEKIND {\n    INVOKE_FUNC           = 1,\n    INVOKE_PROPERTYGET    = 2,\n    INVOKE_PROPERTYPUT    = 4,\n    INVOKE_PROPERTYPUTREF = 8\n}\n\nstruct FUNCDESC {\n    MEMBERID memid;\n    SCODE* lprgscode;\n    ELEMDESC* lprgelemdescParam;\n    FUNCKIND funckind;\n    INVOKEKIND invkind;\n    CALLCONV callconv;\n    SHORT cParams;\n    SHORT cParamsOpt;\n    SHORT oVft;\n    SHORT cScodes;\n    ELEMDESC elemdescFunc;\n    WORD wFuncFlags;\n}\nalias FUNCDESC* LPFUNCDESC;\n\nenum VARKIND {\n    VAR_PERINSTANCE, VAR_STATIC, VAR_CONST, VAR_DISPATCH\n}\n\nstruct VARDESC {\n    MEMBERID memid;\n    LPOLESTR lpstrSchema;\n    union {\n        ULONG oInst;\n        VARIANT* lpvarValue;\n    }\n    ELEMDESC elemdescVar;\n    WORD wVarFlags;\n    VARKIND varkind;\n}\nalias VARDESC* LPVARDESC;\n\nenum TYPEFLAGS {\n    TYPEFLAG_FAPPOBJECT     = 1,\n    TYPEFLAG_FCANCREATE     = 2,\n    TYPEFLAG_FLICENSED      = 4,\n    TYPEFLAG_FPREDECLID     = 8,\n    TYPEFLAG_FHIDDEN        = 16,\n    TYPEFLAG_FCONTROL       = 32,\n    TYPEFLAG_FDUAL          = 64,\n    TYPEFLAG_FNONEXTENSIBLE = 128,\n    TYPEFLAG_FOLEAUTOMATION = 256,\n    TYPEFLAG_FRESTRICTED    = 512,\n    TYPEFLAG_FAGGREGATABLE  = 1024,\n    TYPEFLAG_FREPLACEABLE   = 2048,\n    TYPEFLAG_FDISPATCHABLE  = 4096,\n    TYPEFLAG_FREVERSEBIND   = 8192\n}\n\nenum FUNCFLAGS {\n    FUNCFLAG_FRESTRICTED = 1,\n    FUNCFLAG_FSOURCE = 2,\n    FUNCFLAG_FBINDABLE = 4,\n    FUNCFLAG_FREQUESTEDIT = 8,\n    FUNCFLAG_FDISPLAYBIND = 16,\n    FUNCFLAG_FDEFAULTBIND = 32,\n    FUNCFLAG_FHIDDEN = 64,\n    FUNCFLAG_FUSESGETLASTERROR = 128,\n    FUNCFLAG_FDEFAULTCOLLELEM = 256,\n    FUNCFLAG_FUIDEFAULT = 512,\n    FUNCFLAG_FNONBROWSABLE = 1024,\n    FUNCFLAG_FREPLACEABLE = 2048,\n    FUNCFLAG_FIMMEDIATEBIND = 4096\n}\n\nenum VARFLAGS {\n    VARFLAG_FREADONLY = 1,\n    VARFLAG_FSOURCE = 2,\n    VARFLAG_FBINDABLE = 4,\n    VARFLAG_FREQUESTEDIT = 8,\n    VARFLAG_FDISPLAYBIND = 16,\n    VARFLAG_FDEFAULTBIND = 32,\n    VARFLAG_FHIDDEN = 64,\n    VARFLAG_FRESTRICTED = 128,\n    VARFLAG_FDEFAULTCOLLELEM = 256,\n    VARFLAG_FUIDEFAULT = 512,\n    VARFLAG_FNONBROWSABLE = 1024,\n    VARFLAG_FREPLACEABLE = 2048,\n    VARFLAG_FIMMEDIATEBIND = 4096\n}\n\nstruct CLEANLOCALSTORAGE {\n    IUnknown pInterface;\n    PVOID pStorage;\n    DWORD flags;\n}\n\nstruct CUSTDATAITEM {\n    GUID guid;\n    VARIANTARG varValue;\n}\nalias CUSTDATAITEM* LPCUSTDATAITEM;\n\nstruct CUSTDATA {\n    DWORD cCustData;\n    LPCUSTDATAITEM prgCustData;\n}\nalias CUSTDATA* LPCUSTDATA;\n\nenum DESCKIND {\n    DESCKIND_NONE = 0,\n    DESCKIND_FUNCDESC = DESCKIND_NONE+1,\n    DESCKIND_VARDESC = DESCKIND_FUNCDESC+1,\n    DESCKIND_TYPECOMP = DESCKIND_VARDESC+1,\n    DESCKIND_IMPLICITAPPOBJ = DESCKIND_TYPECOMP+1,\n    DESCKIND_MAX = DESCKIND_IMPLICITAPPOBJ+1\n}\n\nunion BINDPTR {\n    LPFUNCDESC lpfuncdesc;\n    LPVARDESC lpvardesc;\n    LPTYPECOMP lptcomp;\n}\nalias BINDPTR* LPBINDPTR;\n\ninterface IDispatch : IUnknown {\n    HRESULT GetTypeInfoCount(UINT*);\n    HRESULT GetTypeInfo(UINT, LCID, LPTYPEINFO*);\n    HRESULT GetIDsOfNames(REFIID, LPOLESTR*, UINT, LCID, DISPID*);\n    HRESULT Invoke(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);\n}\nalias IDispatch LPDISPATCH;\n\ninterface IEnumVARIANT : IUnknown {\n    HRESULT Next(ULONG, VARIANT*, ULONG*);\n    HRESULT Skip(ULONG);\n    HRESULT Reset();\n    HRESULT Clone(IEnumVARIANT*);\n}\nalias IEnumVARIANT LPENUMVARIANT;\n\ninterface ITypeComp : IUnknown {\n    HRESULT Bind(LPOLESTR, ULONG, WORD, LPTYPEINFO*, DESCKIND*, LPBINDPTR);\n    HRESULT BindType(LPOLESTR, ULONG, LPTYPEINFO*, LPTYPECOMP*);\n}\nalias ITypeComp LPTYPECOMP;\n\ninterface ITypeInfo : IUnknown {\n    HRESULT GetTypeAttr(LPTYPEATTR*);\n    HRESULT GetTypeComp(LPTYPECOMP*);\n    HRESULT GetFuncDesc(UINT, LPFUNCDESC*);\n    HRESULT GetVarDesc(UINT, LPVARDESC*);\n    HRESULT GetNames(MEMBERID, BSTR*, UINT, UINT*);\n    HRESULT GetRefTypeOfImplType(UINT, HREFTYPE*);\n    HRESULT GetImplTypeFlags(UINT, INT*);\n    HRESULT GetIDsOfNames(LPOLESTR*, UINT, MEMBERID*);\n    HRESULT Invoke(PVOID, MEMBERID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*,\n      UINT*);\n    HRESULT GetDocumentation(MEMBERID, BSTR*, BSTR*, DWORD*, BSTR*);\n    HRESULT GetDllEntry(MEMBERID, INVOKEKIND, BSTR*, BSTR*, WORD*);\n    HRESULT GetRefTypeInfo(HREFTYPE, LPTYPEINFO*);\n    HRESULT AddressOfMember(MEMBERID, INVOKEKIND, PVOID*);\n    HRESULT CreateInstance(LPUNKNOWN, REFIID, PVOID*);\n    HRESULT GetMops(MEMBERID, BSTR*);\n    HRESULT GetContainingTypeLib(LPTYPELIB*, UINT*);\n    void ReleaseTypeAttr(LPTYPEATTR);\n    void ReleaseFuncDesc(LPFUNCDESC);\n    void ReleaseVarDesc(LPVARDESC);\n}\nalias ITypeInfo LPTYPEINFO;\n\ninterface ITypeInfo2 : ITypeInfo {\n    HRESULT GetTypeKind(TYPEKIND*);\n    HRESULT GetTypeFlags(ULONG*);\n    HRESULT GetFuncIndexOfMemId(MEMBERID, INVOKEKIND, UINT*);\n    HRESULT GetVarIndexOfMemId(MEMBERID, UINT*);\n    HRESULT GetCustData(REFGUID, VARIANT*);\n    HRESULT GetFuncCustData(UINT, REFGUID, VARIANT*);\n    HRESULT GetParamCustData(UINT, UINT, REFGUID, VARIANT*);\n    HRESULT GetVarCustData(UINT, REFGUID, VARIANT*);\n    HRESULT GetImplTypeCustData(UINT, REFGUID, VARIANT*);\n    HRESULT GetDocumentation2(MEMBERID, LCID, BSTR*, DWORD*, BSTR*);\n    HRESULT GetAllCustData(CUSTDATA*);\n    HRESULT GetAllFuncCustData(UINT, CUSTDATA*);\n    HRESULT GetAllParamCustData(UINT, UINT, CUSTDATA*);\n    HRESULT GetAllVarCustData(UINT, CUSTDATA*);\n    HRESULT GetAllImplTypeCustData(UINT, CUSTDATA*);\n}\nalias ITypeInfo2 LPTYPEINFO2;\n\ninterface ITypeLib : IUnknown {\n    UINT GetTypeInfoCount();\n    HRESULT GetTypeInfo(UINT, ITypeInfo*);\n    HRESULT GetTypeInfoType(UINT, TYPEKIND*);\n    HRESULT GetTypeInfoOfGuid(REFGUID, ITypeInfo*);\n    HRESULT GetLibAttr(TLIBATTR**);\n    HRESULT GetTypeComp(ITypeComp);\n    HRESULT GetDocumentation(INT, BSTR*, BSTR*, DWORD*, BSTR*);\n    HRESULT IsName(LPOLESTR, ULONG, BOOL*);\n    HRESULT FindName(LPOLESTR, ULONG, ITypeInfo*, MEMBERID*, USHORT*);\n    void ReleaseTLibAttr(TLIBATTR*);\n}\nalias ITypeLib LPTYPELIB;\n\ninterface ITypeLib2 : ITypeLib {\n    HRESULT GetCustData(REFGUID, VARIANT*);\n    HRESULT GetLibStatistics(ULONG*, ULONG*);\n    HRESULT GetDocumentation2(INT, LCID, BSTR*, DWORD*, BSTR*);\n    HRESULT GetAllCustData(CUSTDATA*);\n}\nalias ITypeLib2 LPTYPELIB2;\n\ninterface IErrorInfo : IUnknown {\n    HRESULT GetGUID(GUID*);\n    HRESULT GetSource(BSTR*);\n    HRESULT GetDescription(BSTR*);\n    HRESULT GetHelpFile(BSTR*);\n    HRESULT GetHelpContext(DWORD*);\n}\nalias IErrorInfo LPERRORINFO;\n\ninterface ICreateErrorInfo : IUnknown {\n    HRESULT SetGUID(REFGUID);\n    HRESULT SetSource(LPOLESTR);\n    HRESULT SetDescription(LPOLESTR);\n    HRESULT SetHelpFile(LPOLESTR);\n    HRESULT SetHelpContext(DWORD);\n}\nalias ICreateErrorInfo LPCREATEERRORINFO;\n\ninterface ISupportErrorInfo : IUnknown {\n    HRESULT InterfaceSupportsErrorInfo(REFIID);\n}\nalias ISupportErrorInfo LPSUPPORTERRORINFO;\n\ninterface IRecordInfo : IUnknown {\n    HRESULT RecordInit(PVOID);\n    HRESULT RecordClear(PVOID);\n    HRESULT RecordCopy(PVOID, PVOID);\n    HRESULT GetGuid(GUID*);\n    HRESULT GetName(BSTR*);\n    HRESULT GetSize(ULONG*);\n    HRESULT GetTypeInfo(ITypeInfo*);\n    HRESULT GetField(PVOID, LPCOLESTR, VARIANT*);\n    HRESULT GetFieldNoCopy(PVOID, LPCOLESTR, VARIANT*, PVOID*);\n    HRESULT PutField (ULONG, PVOID, LPCOLESTR, VARIANT*);\n    HRESULT PutFieldNoCopy(ULONG, PVOID, LPCOLESTR, VARIANT*);\n    HRESULT GetFieldNames(ULONG*, BSTR*);\n    BOOL IsMatchingType();\n    PVOID RecordCreate();\n    HRESULT RecordCreateCopy(PVOID, PVOID*);\n    HRESULT RecordDestroy (PVOID);\n}\nalias IRecordInfo LPRECORDINFO;\n\ninterface ITypeMarshal : IUnknown {\n    HRESULT Size(PVOID, DWORD, PVOID, ULONG*);\n    HRESULT Marshal(PVOID, DWORD, PVOID, ULONG, BYTE*, ULONG*);\n    HRESULT Unmarshal(PVOID, DWORD, ULONG, BYTE*, ULONG*);\n    HRESULT Free(PVOID);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/objbase.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_objbase.d)\n */\nmodule core.sys.windows.objbase;\nversion (Windows):\npragma(lib, \"ole32\");\n\nimport core.sys.windows.cguid, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.wtypes;\nprivate import core.sys.windows.basetyps, core.sys.windows.objfwd, core.sys.windows.rpcdce, core.sys.windows.winbase,\n  core.sys.windows.windef;\n\n// DAC: Not needed for D?\n//MACRO #define LISet32(li, v) ((li).HighPart=(v)<0?-1:0, (li).LowPart=(v))\n//MACRO #define ULISet32(li, v) ((li).HighPart=0, (li).LowPart=(v))\n\nenum CLSCTX_ALL    = CLSCTX.CLSCTX_INPROC_SERVER|CLSCTX.CLSCTX_INPROC_HANDLER|CLSCTX.CLSCTX_LOCAL_SERVER;\nenum CLSCTX_INPROC = CLSCTX.CLSCTX_INPROC_SERVER|CLSCTX.CLSCTX_INPROC_HANDLER;\nenum CLSCTX_SERVER = CLSCTX.CLSCTX_INPROC_SERVER|CLSCTX.CLSCTX_LOCAL_SERVER|CLSCTX.CLSCTX_REMOTE_SERVER;\nenum MARSHALINTERFACE_MIN=500;\nenum CWCSTORAGENAME=32;\n\nenum STGM_DIRECT           = 0;\nenum STGM_TRANSACTED       = 0x10000L;\nenum STGM_SIMPLE           = 0x8000000L;\nenum STGM_READ             = 0;\nenum STGM_WRITE            = 1;\nenum STGM_READWRITE        = 2;\nenum STGM_SHARE_DENY_NONE  = 0x40;\nenum STGM_SHARE_DENY_READ  = 0x30;\nenum STGM_SHARE_DENY_WRITE = 0x20;\nenum STGM_SHARE_EXCLUSIVE  = 0x10;\nenum STGM_PRIORITY         = 0x40000L;\nenum STGM_DELETEONRELEASE  = 0x4000000;\nenum STGM_NOSCRATCH        = 0x100000;\nenum STGM_CREATE           = 0x1000;\nenum STGM_CONVERT          = 0x20000;\nenum STGM_NOSNAPSHOT       = 0x200000;\nenum STGM_FAILIFTHERE      = 0;\n\nenum ASYNC_MODE_COMPATIBILITY = 1;\nenum ASYNC_MODE_DEFAULT       = 0;\n\nenum STGTY_REPEAT = 256;\nenum STG_TOEND = 0xFFFFFFFF;\nenum STG_LAYOUT_SEQUENTIAL  = 0;\nenum STG_LAYOUT_INTERLEAVED = 1;\n\nenum COM_RIGHTS_EXECUTE            = 1;\nenum COM_RIGHTS_SAFE_FOR_SCRIPTING = 2;\n\nenum STGOPTIONS_VERSION = 2;\n\nenum STGFMT {\n    STGFMT_STORAGE = 0,\n    STGFMT_FILE = 3,\n    STGFMT_ANY = 4,\n    STGFMT_DOCFILE = 5\n}\n\nstruct STGOPTIONS {\n    USHORT usVersion;\n    USHORT reserved;\n    ULONG ulSectorSize;\nconst(WCHAR)* pwcsTemplateFile;\n}\n\nenum REGCLS {\n    REGCLS_SINGLEUSE = 0,\n    REGCLS_MULTIPLEUSE = 1,\n    REGCLS_MULTI_SEPARATE = 2\n}\n\n/*\nBOOL IsEqualGUID(GUID rguid1, GUID rguid2) {\n    return rguid1 == rguid2;\n}\n*/\n\nextern (Windows) BOOL IsEqualGUID(\n  REFGUID rguid1,\n  REFGUID rguid2\n);\n\nalias IsEqualGUID IsEqualIID;\nalias IsEqualGUID IsEqualCLSID;\n\nenum COINIT {\n    COINIT_APARTMENTTHREADED = 2,\n    COINIT_MULTITHREADED     = 0,\n    COINIT_DISABLE_OLE1DDE   = 4,\n    COINIT_SPEED_OVER_MEMORY = 8\n}\n\nenum STDMSHLFLAGS {\n    SMEXF_SERVER  = 1,\n    SMEXF_HANDLER\n}\n\nextern(Windows) {\n    alias HRESULT function(REFCLSID, REFIID, PVOID*) LPFNGETCLASSOBJECT;\n    alias HRESULT function() LPFNCANUNLOADNOW;\n\n    DWORD CoBuildVersion();\n    HRESULT CoInitialize(PVOID);\n    HRESULT CoInitializeEx(LPVOID, DWORD);\n    void CoUninitialize();\n    HRESULT CoGetMalloc(DWORD, LPMALLOC*);\n    DWORD CoGetCurrentProcess();\n    HRESULT CoRegisterMallocSpy(LPMALLOCSPY);\n    HRESULT CoRevokeMallocSpy();\n    HRESULT CoCreateStandardMalloc(DWORD, IMalloc*);\n    //#ifdef DBG\n    ULONG DebugCoGetRpcFault();\n    void DebugCoSetRpcFault(ULONG);\n    //#endif\n    HRESULT CoGetClassObject(REFCLSID, DWORD, COSERVERINFO*, REFIID, PVOID*);\n    HRESULT CoRegisterClassObject(REFCLSID, LPUNKNOWN, DWORD, DWORD, PDWORD);\n    HRESULT CoRevokeClassObject(DWORD);\n    HRESULT CoGetMarshalSizeMax(ULONG*, REFIID, LPUNKNOWN, DWORD, PVOID, DWORD);\n    HRESULT CoMarshalInterface(LPSTREAM, REFIID, LPUNKNOWN, DWORD, PVOID, DWORD);\n    HRESULT CoUnmarshalInterface(LPSTREAM, REFIID, PVOID*);\n    HRESULT CoMarshalHresult(LPSTREAM, HRESULT);\n    HRESULT CoUnmarshalHresult(LPSTREAM, HRESULT*);\n    HRESULT CoReleaseMarshalData(LPSTREAM);\n    HRESULT CoDisconnectObject(LPUNKNOWN, DWORD);\n    HRESULT CoLockObjectExternal(LPUNKNOWN, BOOL, BOOL);\n    HRESULT CoGetStandardMarshal(REFIID, LPUNKNOWN, DWORD, PVOID, DWORD, LPMARSHAL*);\n    HRESULT CoGetStdMarshalEx(LPUNKNOWN, DWORD, LPUNKNOWN*);\n    BOOL CoIsHandlerConnected(LPUNKNOWN);\n    BOOL CoHasStrongExternalConnections(LPUNKNOWN);\n    HRESULT CoMarshalInterThreadInterfaceInStream(REFIID, LPUNKNOWN, LPSTREAM*);\n    HRESULT CoGetInterfaceAndReleaseStream(LPSTREAM, REFIID, PVOID*);\n    HRESULT CoCreateFreeThreadedMarshaler(LPUNKNOWN, LPUNKNOWN*);\n    HINSTANCE CoLoadLibrary(LPOLESTR, BOOL);\n    void CoFreeLibrary(HINSTANCE);\n    void CoFreeAllLibraries();\n    void CoFreeUnusedLibraries();\n    HRESULT CoCreateInstance(REFCLSID, LPUNKNOWN, DWORD, REFIID, PVOID*);\n    HRESULT CoCreateInstanceEx(REFCLSID, IUnknown, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);\n    HRESULT StringFromCLSID(REFCLSID, LPOLESTR*);\n    HRESULT CLSIDFromString(LPOLESTR, LPCLSID);\n    HRESULT StringFromIID(REFIID, LPOLESTR*);\n    HRESULT IIDFromString(LPOLESTR, LPIID);\n    BOOL CoIsOle1Class(REFCLSID);\n    HRESULT ProgIDFromCLSID(REFCLSID, LPOLESTR*);\n    HRESULT CLSIDFromProgID(LPCOLESTR, LPCLSID);\n    int StringFromGUID2(REFGUID, LPOLESTR, int);\n    HRESULT CoCreateGuid(GUID*);\n    BOOL CoFileTimeToDosDateTime(FILETIME*, LPWORD, LPWORD);\n    BOOL CoDosDateTimeToFileTime(WORD, WORD, FILETIME*);\n    HRESULT CoFileTimeNow(FILETIME*);\n    HRESULT CoRegisterMessageFilter(LPMESSAGEFILTER, LPMESSAGEFILTER*);\n    HRESULT CoGetTreatAsClass(REFCLSID, LPCLSID);\n    HRESULT CoTreatAsClass(REFCLSID, REFCLSID);\n    HRESULT DllGetClassObject(REFCLSID, REFIID, PVOID*);\n    HRESULT DllCanUnloadNow();\n    PVOID CoTaskMemAlloc(SIZE_T);\n    PVOID CoTaskMemRealloc(PVOID, SIZE_T);\n    void CoTaskMemFree(PVOID);\n    HRESULT CreateDataAdviseHolder(LPDATAADVISEHOLDER*);\n    HRESULT CreateDataCache(LPUNKNOWN, REFCLSID, REFIID, PVOID*);\n    HRESULT StgCreateDocfile(const(OLECHAR)*, DWORD, DWORD, IStorage*);\n    HRESULT StgCreateDocfileOnILockBytes(ILockBytes, DWORD, DWORD, IStorage*);\n    HRESULT StgOpenStorage(const(OLECHAR)*, IStorage, DWORD, SNB, DWORD, IStorage*);\n    HRESULT StgOpenStorageOnILockBytes(ILockBytes, IStorage, DWORD, SNB, DWORD, IStorage*);\n    HRESULT StgIsStorageFile(const(OLECHAR)*);\n    HRESULT StgIsStorageILockBytes(ILockBytes);\n    HRESULT StgSetTimes(OLECHAR *, FILETIME *, FILETIME *, FILETIME *);\n    HRESULT StgCreateStorageEx(const(WCHAR)*, DWORD, DWORD, DWORD, STGOPTIONS*, void*, REFIID, void**);\n    HRESULT StgOpenStorageEx(const(WCHAR)*, DWORD, DWORD, DWORD, STGOPTIONS*, void*, REFIID, void**);\n    HRESULT BindMoniker(LPMONIKER, DWORD, REFIID, PVOID*);\n    HRESULT CoGetObject(LPCWSTR, BIND_OPTS*, REFIID, void**);\n    HRESULT MkParseDisplayName(LPBC, LPCOLESTR, ULONG*, LPMONIKER*);\n    HRESULT MonikerRelativePathTo(LPMONIKER, LPMONIKER, LPMONIKER*, BOOL);\n    HRESULT MonikerCommonPrefixWith(LPMONIKER, LPMONIKER, LPMONIKER*);\n    HRESULT CreateBindCtx(DWORD, LPBC*);\n    HRESULT CreateGenericComposite(LPMONIKER, LPMONIKER, LPMONIKER*);\n    HRESULT GetClassFile (LPCOLESTR, CLSID*);\n    HRESULT CreateFileMoniker(LPCOLESTR, LPMONIKER*);\n    HRESULT CreateItemMoniker(LPCOLESTR, LPCOLESTR, LPMONIKER*);\n    HRESULT CreateAntiMoniker(LPMONIKER*);\n    HRESULT CreatePointerMoniker(LPUNKNOWN, LPMONIKER*);\n    HRESULT GetRunningObjectTable(DWORD, LPRUNNINGOBJECTTABLE*);\n    HRESULT CoInitializeSecurity(PSECURITY_DESCRIPTOR, LONG, SOLE_AUTHENTICATION_SERVICE*, void*, DWORD, DWORD, void*, DWORD, void*);\n    HRESULT CoGetCallContext(REFIID, void**);\n    HRESULT CoQueryProxyBlanket(IUnknown*, DWORD*, DWORD*, OLECHAR**, DWORD*, DWORD*, RPC_AUTH_IDENTITY_HANDLE*, DWORD*);\n    HRESULT CoSetProxyBlanket(IUnknown*, DWORD, DWORD, OLECHAR*, DWORD, DWORD, RPC_AUTH_IDENTITY_HANDLE, DWORD);\n    HRESULT CoCopyProxy(IUnknown*, IUnknown**);\n    HRESULT CoQueryClientBlanket(DWORD*, DWORD*, OLECHAR**, DWORD*, DWORD*, RPC_AUTHZ_HANDLE*, DWORD*);\n    HRESULT CoImpersonateClient();\n    HRESULT CoRevertToSelf();\n    HRESULT CoQueryAuthenticationServices(DWORD*, SOLE_AUTHENTICATION_SERVICE**);\n    HRESULT CoSwitchCallContext(IUnknown*, IUnknown**);\n    HRESULT CoGetInstanceFromFile(COSERVERINFO*, CLSID*, IUnknown*, DWORD, DWORD, OLECHAR*, DWORD, MULTI_QI*);\n    HRESULT CoGetInstanceFromIStorage(COSERVERINFO*, CLSID*, IUnknown*, DWORD, IStorage*, DWORD, MULTI_QI*);\n    ULONG CoAddRefServerProcess();\n    ULONG CoReleaseServerProcess();\n    HRESULT CoResumeClassObjects();\n    HRESULT CoSuspendClassObjects();\n    HRESULT CoGetPSClsid(REFIID, CLSID*);\n    HRESULT CoRegisterPSClsid(REFIID, REFCLSID);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/objfwd.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_objfwd.d)\n */\nmodule core.sys.windows.objfwd;\nversion (Windows):\n\nprivate import core.sys.windows.objidl;\n\n/+\n// Forward declararions are not necessary in D.\nextern(Windows) {\n    interface IMoniker;\n    interface IStream;\n    interface IMarshal;\n    interface IMalloc;\n    interface IMallocSpy;\n    interface IMessageFilter;\n    interface IPersist;\n    interface IPersistStream;\n    interface IRunningObjectTable;\n    interface IBindCtx;\n    interface IAdviseSink;\n    interface IAdviseSink2;\n    interface IDataObject;\n    interface IDataAdviseHolder;\n\n    interface IEnumMoniker;\n    interface IEnumFORMATETC;\n    interface IEnumSTATDATA;\n    interface IEnumSTATSTG;\n    interface IEnumSTATPROPSTG;\n    interface IEnumString;\n    interface IEnumUnknown;\n    interface IStorage;\n    interface IPersistStorage;\n    interface ILockBytes;\n    interface IStdMarshalInfo;\n    interface IExternalConnection;\n    interface IRunnableObject;\n    interface IROTData;\n    interface IPersistFile;\n    interface IRootStorage;\n    interface IPropertyStorage;\n    interface IEnumSTATPROPSETSTG;\n    interface IPropertySetStorage;\n    interface IClientSecurity;\n    interface IServerSecurity;\n    interface IClassActivator;\n    interface IFillLockBytes;\n    interface IProgressNotify;\n    interface ILayoutStorage;\n    interface IRpcProxyBuffer;\n    interface IRpcChannelBuffer;\n    interface IRpcStubBuffer;\n}\n+/\nalias IMoniker LPMONIKER;\nalias IStream LPSTREAM;\nalias IMarshal LPMARSHAL;\nalias IMalloc LPMALLOC;\nalias IMallocSpy LPMALLOCSPY;\nalias IMessageFilter LPMESSAGEFILTER;\nalias IPersist LPPERSIST;\nalias IPersistStream LPPERSISTSTREAM;\nalias IRunningObjectTable LPRUNNINGOBJECTTABLE;\nalias IBindCtx LPBINDCTX, LPBC;\nalias IAdviseSink LPADVISESINK;\nalias IAdviseSink2 LPADVISESINK2;\nalias IDataObject LPDATAOBJECT;\nalias IDataAdviseHolder LPDATAADVISEHOLDER;\nalias IEnumMoniker LPENUMMONIKER;\nalias IEnumFORMATETC LPENUMFORMATETC;\nalias IEnumSTATDATA LPENUMSTATDATA;\nalias IEnumSTATSTG LPENUMSTATSTG;\nalias IEnumSTATPROPSTG LPENUMSTATPROPSTG;\nalias IEnumString LPENUMSTRING;\nalias IEnumUnknown LPENUMUNKNOWN;\nalias IStorage LPSTORAGE;\nalias IPersistStorage LPPERSISTSTORAGE;\nalias ILockBytes LPLOCKBYTES;\nalias IStdMarshalInfo LPSTDMARSHALINFO;\nalias IExternalConnection LPEXTERNALCONNECTION;\nalias IRunnableObject LPRUNNABLEOBJECT;\nalias IROTData LPROTDATA;\nalias IPersistFile LPPERSISTFILE;\nalias IRootStorage LPROOTSTORAGE;\nalias IRpcChannelBuffer LPRPCCHANNELBUFFER;\nalias IRpcProxyBuffer LPRPCPROXYBUFFER;\nalias IRpcStubBuffer LPRPCSTUBBUFFER;\nalias IPropertyStorage LPPROPERTYSTORAGE;\nalias IEnumSTATPROPSETSTG LPENUMSTATPROPSETSTG;\nalias IPropertySetStorage LPPROPERTYSETSTORAGE;\nalias IClientSecurity LPCLIENTSECURITY;\nalias IServerSecurity LPSERVERSECURITY;\nalias IClassActivator LPCLASSACTIVATOR;\nalias IFillLockBytes LPFILLLOCKBYTES;\nalias IProgressNotify LPPROGRESSNOTIFY;\nalias ILayoutStorage LPLAYOUTSTORAGE;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/objidl.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_objidl.d)\n */\n// TODO (Don):\n// # why is \"alias IPSFactoryBuffer* LPPSFACTORYBUFFER;\" in this file,\n// rather than in objfwd ?\n// # do we need the proxies that are defined in this file?\nmodule core.sys.windows.objidl;\nversion (Windows):\n\nimport core.sys.windows.unknwn;\nimport core.sys.windows.objfwd;\nprivate import core.sys.windows.windef;\nprivate import core.sys.windows.basetyps;\nprivate import core.sys.windows.oleidl;\nprivate import core.sys.windows.wtypes;\nprivate import core.sys.windows.winbase; // for FILETIME\nprivate import core.sys.windows.rpcdce;\n\nstruct  STATSTG {\n    LPOLESTR pwcsName;\n    DWORD type;\n    ULARGE_INTEGER cbSize;\n    FILETIME mtime;\n    FILETIME ctime;\n    FILETIME atime;\n    DWORD grfMode;\n    DWORD grfLocksSupported;\n    CLSID clsid;\n    DWORD grfStateBits;\n    DWORD reserved;\n}\n\nenum STGTY {\n    STGTY_STORAGE = 1,\n    STGTY_STREAM,\n    STGTY_LOCKBYTES,\n    STGTY_PROPERTY\n}\n\nenum STREAM_SEEK {\n    STREAM_SEEK_SET,\n    STREAM_SEEK_CUR,\n    STREAM_SEEK_END\n}\n\nstruct INTERFACEINFO {\n    LPUNKNOWN pUnk;\n    IID iid;\n    WORD wMethod;\n}\nalias INTERFACEINFO* LPINTERFACEINFO;\n\nenum CALLTYPE {\n    CALLTYPE_TOPLEVEL = 1,\n    CALLTYPE_NESTED,\n    CALLTYPE_ASYNC,\n    CALLTYPE_TOPLEVEL_CALLPENDING,\n    CALLTYPE_ASYNC_CALLPENDING\n}\n\nenum PENDINGTYPE {\n    PENDINGTYPE_TOPLEVEL = 1,\n    PENDINGTYPE_NESTED\n}\n\nenum PENDINGMSG {\n    PENDINGMSG_CANCELCALL = 0,\n    PENDINGMSG_WAITNOPROCESS,\n    PENDINGMSG_WAITDEFPROCESS\n}\n\nalias OLECHAR** SNB;\n\nenum DATADIR {\n    DATADIR_GET = 1,\n    DATADIR_SET\n}\nalias WORD CLIPFORMAT;\nalias CLIPFORMAT* LPCLIPFORMAT;\n\nstruct DVTARGETDEVICE {\n    DWORD tdSize;\n    WORD tdDriverNameOffset;\n    WORD tdDeviceNameOffset;\n    WORD tdPortNameOffset;\n    WORD tdExtDevmodeOffset;\n    BYTE[1] tdData;\n}\n\nstruct FORMATETC {\n    CLIPFORMAT cfFormat;\n    DVTARGETDEVICE* ptd;\n    DWORD dwAspect;\n    LONG lindex;\n    DWORD tymed;\n}\nalias FORMATETC* LPFORMATETC;\n\nstruct RemSTGMEDIUM {\n    DWORD tymed;\n    DWORD dwHandleType;\n    ULONG pData;\n    uint pUnkForRelease;\n    uint cbData;\n    BYTE[1] data;\n}\n\nstruct HLITEM {\n    ULONG uHLID;\n    LPWSTR pwzFriendlyName;\n}\n\nstruct STATDATA {\n    FORMATETC formatetc;\n    DWORD grfAdvf;\n    IAdviseSink pAdvSink;\n    DWORD dwConnection;\n}\n\nstruct STATPROPSETSTG {\n    FMTID fmtid;\n    CLSID clsid;\n    DWORD grfFlags;\n    FILETIME mtime;\n    FILETIME ctime;\n    FILETIME atime;\n}\n\nenum EXTCONN {\n    EXTCONN_STRONG   = 1,\n    EXTCONN_WEAK     = 2,\n    EXTCONN_CALLABLE = 4\n}\n\nstruct MULTI_QI {\nconst(IID)* pIID;\n    IUnknown    pItf;\n    HRESULT     hr;\n}\n\nstruct AUTH_IDENTITY {\n    USHORT* User;\n    ULONG UserLength;\n    USHORT* Domain;\n    ULONG DomainLength;\n    USHORT* Password;\n    ULONG PasswordLength;\n    ULONG Flags;\n}\n\nstruct COAUTHINFO {\n    DWORD dwAuthnSvc;\n    DWORD dwAuthzSvc;\n    LPWSTR pwszServerPrincName;\n    DWORD dwAuthnLevel;\n    DWORD dwImpersonationLevel;\n    AUTH_IDENTITY* pAuthIdentityData;\n    DWORD dwCapabilities;\n}\n\nstruct  COSERVERINFO {\n    DWORD dwReserved1;\n    LPWSTR pwszName;\n    COAUTHINFO* pAuthInfo;\n    DWORD dwReserved2;\n}\n\nstruct BIND_OPTS {\n    DWORD cbStruct;\n    DWORD grfFlags;\n    DWORD grfMode;\n    DWORD dwTickCountDeadline;\n}\nalias BIND_OPTS* LPBIND_OPTS;\n\nstruct BIND_OPTS2 {\n    DWORD cbStruct;\n    DWORD grfFlags;\n    DWORD grfMode;\n    DWORD dwTickCountDeadline;\n    DWORD dwTrackFlags;\n    DWORD dwClassContext;\n    LCID locale;\n    COSERVERINFO* pServerInfo;\n}\nalias BIND_OPTS2* LPBIND_OPTS2;\n\nenum BIND_FLAGS {\n    BIND_MAYBOTHERUSER = 1,\n    BIND_JUSTTESTEXISTENCE\n}\n\nstruct STGMEDIUM {\n    DWORD tymed;\n    union {\n        HBITMAP hBitmap;\n        PVOID hMetaFilePict;\n        HENHMETAFILE hEnhMetaFile;\n        HGLOBAL hGlobal;\n        LPWSTR lpszFileName;\n        LPSTREAM pstm;\n        LPSTORAGE pstg;\n    }\n    LPUNKNOWN pUnkForRelease;\n}\nalias STGMEDIUM* LPSTGMEDIUM;\n\nenum LOCKTYPE {\n    LOCK_WRITE     = 1,\n    LOCK_EXCLUSIVE = 2,\n    LOCK_ONLYONCE  = 4\n}\n\nalias uint RPCOLEDATAREP;\n\nstruct  RPCOLEMESSAGE {\n    PVOID reserved1;\n    RPCOLEDATAREP dataRepresentation;\n    PVOID Buffer;\n    ULONG cbBuffer;\n    ULONG iMethod;\n    PVOID[5] reserved2;\n    ULONG rpcFlags;\n}\nalias RPCOLEMESSAGE* PRPCOLEMESSAGE;\n\nenum MKSYS {\n    MKSYS_NONE,\n    MKSYS_GENERICCOMPOSITE,\n    MKSYS_FILEMONIKER,\n    MKSYS_ANTIMONIKER,\n    MKSYS_ITEMMONIKER,\n    MKSYS_POINTERMONIKER\n}\n\nenum MKREDUCE {\n    MKRREDUCE_ALL,\n    MKRREDUCE_ONE         = 196608,\n    MKRREDUCE_TOUSER      = 131072,\n    MKRREDUCE_THROUGHUSER = 65536\n}\n\nstruct RemSNB {\n    uint ulCntStr;\n    uint ulCntChar;\n    OLECHAR[1] rgString;\n}\n\nenum ADVF {\n    ADVF_NODATA            = 1,\n    ADVF_PRIMEFIRST        = 2,\n    ADVF_ONLYONCE          = 4,\n    ADVFCACHE_NOHANDLER    = 8,\n    ADVFCACHE_FORCEBUILTIN = 16,\n    ADVFCACHE_ONSAVE       = 32,\n    ADVF_DATAONSTOP        = 64\n}\n\nenum TYMED {\n    TYMED_HGLOBAL  = 1,\n    TYMED_FILE     = 2,\n    TYMED_ISTREAM  = 4,\n    TYMED_ISTORAGE = 8,\n    TYMED_GDI      = 16,\n    TYMED_MFPICT   = 32,\n    TYMED_ENHMF    = 64,\n    TYMED_NULL     = 0\n}\n\nenum SERVERCALL {\n    SERVERCALL_ISHANDLED,\n    SERVERCALL_REJECTED,\n    SERVERCALL_RETRYLATER\n}\n\nstruct CAUB {\n    ULONG cElems;\n    ubyte* pElems;\n}\n\nstruct CAI {\n    ULONG cElems;\n    short* pElems;\n}\n\nstruct CAUI {\n    ULONG cElems;\n    USHORT* pElems;\n}\n\nstruct CAL {\n    ULONG cElems;\n    int* pElems;\n}\n\nstruct CAUL {\n    ULONG cElems;\n    ULONG* pElems;\n}\n\nstruct CAFLT {\n    ULONG cElems;\n    float* pElems;\n}\n\nstruct CADBL {\n    ULONG cElems;\n    double* pElems;\n}\n\nstruct CACY {\n    ULONG cElems;\n    CY* pElems;\n}\n\nstruct CADATE {\n    ULONG cElems;\n    DATE* pElems;\n}\n\nstruct CABSTR {\n    ULONG cElems;\n    BSTR*  pElems;\n}\n\nstruct CABSTRBLOB {\n    ULONG cElems;\n    BSTRBLOB* pElems;\n}\n\nstruct CABOOL {\n    ULONG cElems;\n    VARIANT_BOOL* pElems;\n}\n\nstruct CASCODE {\n    ULONG cElems;\n    SCODE* pElems;\n}\n\nstruct CAH {\n    ULONG cElems;\n    LARGE_INTEGER* pElems;\n}\n\nstruct CAUH {\n    ULONG cElems;\n    ULARGE_INTEGER* pElems;\n}\n\nstruct CALPSTR {\n    ULONG cElems;\n    LPSTR* pElems;\n}\n\nstruct CALPWSTR {\n    ULONG cElems;\n    LPWSTR* pElems;\n}\n\nstruct CAFILETIME {\n    ULONG cElems;\n    FILETIME* pElems;\n}\n\nstruct CACLIPDATA {\n    ULONG cElems;\n    CLIPDATA* pElems;\n}\n\nstruct CACLSID {\n    ULONG cElems;\n    CLSID* pElems;\n}\nalias PROPVARIANT* LPPROPVARIANT;\n\nstruct CAPROPVARIANT {\n    ULONG cElems;\n    LPPROPVARIANT pElems;\n}\n\nstruct PROPVARIANT {\n    VARTYPE vt;\n    WORD wReserved1;\n    WORD wReserved2;\n    WORD wReserved3;\n    union {\n        CHAR cVal;\n        UCHAR bVal;\n        short iVal;\n        USHORT uiVal;\n        VARIANT_BOOL boolVal;\n        int lVal;\n        ULONG ulVal;\n        float fltVal;\n        SCODE scode;\n        LARGE_INTEGER hVal;\n        ULARGE_INTEGER uhVal;\n        double dblVal;\n        CY cyVal;\n        DATE date;\n        FILETIME filetime;\n        CLSID* puuid;\n        BLOB blob;\n        CLIPDATA* pclipdata;\n        LPSTREAM pStream;\n        LPSTORAGE pStorage;\n        BSTR bstrVal;\n        BSTRBLOB bstrblobVal;\n        LPSTR pszVal;\n        LPWSTR pwszVal;\n        CAUB caub;\n        CAI cai;\n        CAUI caui;\n        CABOOL cabool;\n        CAL cal;\n        CAUL caul;\n        CAFLT caflt;\n        CASCODE cascode;\n        CAH cah;\n        CAUH cauh;\n        CADBL cadbl;\n        CACY cacy;\n        CADATE cadate;\n        CAFILETIME cafiletime;\n        CACLSID cauuid;\n        CACLIPDATA caclipdata;\n        CABSTR cabstr;\n        CABSTRBLOB cabstrblob;\n        CALPSTR calpstr;\n        CALPWSTR calpwstr;\n        CAPROPVARIANT capropvar;\n    }\n}\n\nstruct PROPSPEC {\n    ULONG ulKind;\n    union {\n        PROPID propid;\n        LPOLESTR lpwstr;\n    }\n}\n\nstruct  STATPROPSTG {\n    LPOLESTR lpwstrName;\n    PROPID propid;\n    VARTYPE vt;\n}\n\nenum PROPSETFLAG {\n    PROPSETFLAG_DEFAULT,\n    PROPSETFLAG_NONSIMPLE,\n    PROPSETFLAG_ANSI,\n    PROPSETFLAG_UNBUFFERED = 4\n}\n\nstruct STORAGELAYOUT {\n    DWORD LayoutType;\n    OLECHAR* pwcsElementName;\n    LARGE_INTEGER cOffset;\n    LARGE_INTEGER cBytes;\n}\n\nstruct SOLE_AUTHENTICATION_SERVICE {\n    DWORD dwAuthnSvc;\n    DWORD dwAuthzSvc;\n    OLECHAR* pPrincipalName;\n    HRESULT hr;\n}\n\nenum OLECHAR* COLE_DEFAULT_PRINCIPAL = cast ( OLECHAR* )(-1);\n\nenum EOLE_AUTHENTICATION_CAPABILITIES {\n    EOAC_NONE              = 0,\n    EOAC_MUTUAL_AUTH       = 0x1,\n    EOAC_SECURE_REFS       = 0x2,\n    EOAC_ACCESS_CONTROL    = 0x4,\n    EOAC_APPID             = 0x8,\n    EOAC_DYNAMIC           = 0x10,\n    EOAC_STATIC_CLOAKING   = 0x20,\n    EOAC_DYNAMIC_CLOAKING  = 0x40,\n    EOAC_ANY_AUTHORITY     = 0x80,\n    EOAC_MAKE_FULLSIC      = 0x100,\n    EOAC_REQUIRE_FULLSIC   = 0x200,\n    EOAC_AUTO_IMPERSONATE  = 0x400,\n    EOAC_DEFAULT           = 0x800,\n    EOAC_DISABLE_AAA       = 0x1000,\n    EOAC_NO_CUSTOM_MARSHAL = 0x2000\n}\n\nstruct SOLE_AUTHENTICATION_INFO {\n    DWORD dwAuthnSvc;\n    DWORD dwAuthzSvc;\n    void* pAuthInfo;\n}\n\nenum void* COLE_DEFAULT_AUTHINFO = cast( void* )(-1 );\n\nstruct SOLE_AUTHENTICATION_LIST {\n    DWORD cAuthInfo;\n    SOLE_AUTHENTICATION_INFO* aAuthInfo;\n}\n\ninterface IEnumFORMATETC : IUnknown {\n      HRESULT Next(ULONG, FORMATETC*, ULONG*);\n      HRESULT Skip(ULONG);\n      HRESULT Reset();\n      HRESULT Clone(IEnumFORMATETC*);\n}\n\ninterface IEnumHLITEM : IUnknown {\n      HRESULT Next(ULONG, HLITEM*, ULONG*);\n      HRESULT Skip(ULONG);\n      HRESULT Reset();\n      HRESULT Clone(IEnumHLITEM*);\n}\n\ninterface IEnumSTATDATA : IUnknown {\n      HRESULT Next(ULONG, STATDATA*, ULONG*);\n      HRESULT Skip(ULONG);\n      HRESULT Reset();\n      HRESULT Clone(IEnumSTATDATA*);\n}\n\ninterface IEnumSTATPROPSETSTG : IUnknown {\n      HRESULT Next(ULONG, STATPROPSETSTG*, ULONG*);\n      HRESULT Skip(ULONG);\n      HRESULT Reset();\n      HRESULT Clone(IEnumSTATPROPSETSTG*);\n}\n\ninterface IEnumSTATPROPSTG : IUnknown {\n      HRESULT Next(ULONG, STATPROPSTG*, ULONG*);\n      HRESULT Skip(ULONG);\n      HRESULT Reset();\n      HRESULT Clone(IEnumSTATPROPSTG*);\n}\n\ninterface IEnumSTATSTG : IUnknown {\n      HRESULT Next(ULONG, STATSTG*, ULONG*);\n      HRESULT Skip(ULONG);\n      HRESULT Reset();\n      HRESULT Clone(IEnumSTATSTG*);\n}\n\ninterface IEnumString : IUnknown {\n      HRESULT Next(ULONG, LPOLESTR*, ULONG*);\n      HRESULT Skip(ULONG);\n      HRESULT Reset();\n      HRESULT Clone(IEnumString*);\n}\n\ninterface IEnumMoniker : IUnknown {\n      HRESULT Next(ULONG, IMoniker*, ULONG*);\n      HRESULT Skip(ULONG);\n      HRESULT Reset();\n      HRESULT Clone(IEnumMoniker*);\n}\n\n\ninterface IEnumUnknown : IUnknown {\n      HRESULT Next(ULONG, IUnknown*, ULONG*);\n      HRESULT Skip(ULONG);\n      HRESULT Reset();\n      HRESULT Clone(IEnumUnknown*);\n}\n\ninterface ISequentialStream : IUnknown {\n    HRESULT Read(void*, ULONG, ULONG*);\n    HRESULT Write(void* , ULONG, ULONG*);\n}\n\ninterface IStream : ISequentialStream {\n    HRESULT Seek(LARGE_INTEGER, DWORD, ULARGE_INTEGER*);\n    HRESULT SetSize(ULARGE_INTEGER);\n    HRESULT CopyTo(IStream, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*);\n    HRESULT Commit(DWORD);\n    HRESULT Revert();\n    HRESULT LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD);\n    HRESULT UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD);\n    HRESULT Stat(STATSTG*, DWORD);\n    HRESULT Clone(LPSTREAM*);\n}\n\ninterface IMarshal : IUnknown {\n    HRESULT GetUnmarshalClass(REFIID, PVOID, DWORD, PVOID, DWORD, CLSID*);\n    HRESULT GetMarshalSizeMax(REFIID, PVOID, DWORD, PVOID, DWORD, ULONG*);\n    HRESULT MarshalInterface(IStream, REFIID, PVOID, DWORD, PVOID, DWORD);\n    HRESULT UnmarshalInterface(IStream, REFIID, void**);\n    HRESULT ReleaseMarshalData(IStream);\n    HRESULT DisconnectObject(DWORD);\n}\n\ninterface IStdMarshalInfo : IUnknown {\n    HRESULT GetClassForHandler(DWORD, PVOID, CLSID*);\n}\n\ninterface IMalloc : IUnknown {\n    void* Alloc(SIZE_T);\n    void* Realloc(void*, SIZE_T);\n    void Free(void*);\n    SIZE_T GetSize(void*);\n    int DidAlloc(void*);\n    void HeapMinimize();\n}\n\ninterface IMallocSpy : IUnknown {\n    SIZE_T PreAlloc(SIZE_T);\n    void* PostAlloc(void*);\n    void* PreFree(void*, BOOL);\n    void PostFree(BOOL);\n    SIZE_T PreRealloc(void*, SIZE_T, void**, BOOL);\n    void* PostRealloc(void*, BOOL);\n    void* PreGetSize(void*, BOOL);\n    SIZE_T PostGetSize(SIZE_T, BOOL);\n    void* PreDidAlloc(void*, BOOL);\n    int PostDidAlloc(void*, BOOL, int);\n    void PreHeapMinimize();\n    void PostHeapMinimize();\n}\n\ninterface IMessageFilter : IUnknown {\n    DWORD HandleInComingCall(DWORD, HTASK, DWORD, LPINTERFACEINFO);\n    DWORD RetryRejectedCall(HTASK, DWORD, DWORD);\n    DWORD MessagePending(HTASK, DWORD, DWORD);\n}\n\n\ninterface IPersist : IUnknown {\n    HRESULT GetClassID(CLSID*);\n}\n\ninterface IPersistStream : IPersist {\n    HRESULT IsDirty();\n    HRESULT Load(IStream);\n    HRESULT Save(IStream, BOOL);\n    HRESULT GetSizeMax(PULARGE_INTEGER);\n}\n\ninterface IRunningObjectTable : IUnknown {\n    HRESULT Register(DWORD, LPUNKNOWN, LPMONIKER, PDWORD);\n    HRESULT Revoke(DWORD);\n    HRESULT IsRunning(LPMONIKER);\n    HRESULT GetObject(LPMONIKER, LPUNKNOWN*);\n    HRESULT NoteChangeTime(DWORD, LPFILETIME);\n    HRESULT GetTimeOfLastChange(LPMONIKER, LPFILETIME);\n    HRESULT EnumRunning(IEnumMoniker*);\n}\n\ninterface IBindCtx : IUnknown {\n    HRESULT RegisterObjectBound(LPUNKNOWN);\n    HRESULT RevokeObjectBound(LPUNKNOWN);\n    HRESULT ReleaseBoundObjects();\n    HRESULT SetBindOptions(LPBIND_OPTS);\n    HRESULT GetBindOptions(LPBIND_OPTS);\n    HRESULT GetRunningObjectTable(IRunningObjectTable*);\n    HRESULT RegisterObjectParam(LPOLESTR, IUnknown);\n    HRESULT GetObjectParam(LPOLESTR, IUnknown*);\n    HRESULT EnumObjectParam(IEnumString*);\n    HRESULT RevokeObjectParam(LPOLESTR);\n}\n\ninterface IMoniker: IPersistStream {\n    HRESULT BindToObject(IBindCtx, IMoniker, REFIID, PVOID*);\n    HRESULT BindToStorage(IBindCtx, IMoniker, REFIID, PVOID*);\n    HRESULT Reduce(IBindCtx, DWORD, IMoniker*, IMoniker*);\n    HRESULT ComposeWith(IMoniker, BOOL, IMoniker*);\n    HRESULT Enum(BOOL, IEnumMoniker*);\n    HRESULT IsEqual(IMoniker);\n    HRESULT Hash(PDWORD);\n    HRESULT IsRunning(IBindCtx, IMoniker, IMoniker);\n    HRESULT GetTimeOfLastChange(IBindCtx, IMoniker, LPFILETIME);\n    HRESULT Inverse(IMoniker*);\n    HRESULT CommonPrefixWith(IMoniker, IMoniker*);\n    HRESULT RelativePathTo(IMoniker, IMoniker*);\n    HRESULT GetDisplayName(IBindCtx, IMoniker, LPOLESTR*);\n    HRESULT ParseDisplayName(IBindCtx, IMoniker, LPOLESTR, ULONG*, IMoniker*);\n    HRESULT IsSystemMoniker(PDWORD);\n}\n\ninterface IPersistStorage : IPersist\n{\n    HRESULT IsDirty();\n    HRESULT InitNew(LPSTORAGE);\n    HRESULT Load(LPSTORAGE);\n    HRESULT Save(LPSTORAGE, BOOL);\n    HRESULT SaveCompleted(LPSTORAGE);\n    HRESULT HandsOffStorage();\n}\n\ninterface IPersistFile : IPersist\n{\n    HRESULT IsDirty();\n    HRESULT Load(LPCOLESTR, DWORD);\n    HRESULT Save(LPCOLESTR, BOOL);\n    HRESULT SaveCompleted(LPCOLESTR);\n    HRESULT GetCurFile(LPOLESTR*);\n}\n\ninterface IAdviseSink : IUnknown {\n    HRESULT QueryInterface(REFIID, PVOID*);\n    ULONG AddRef();\n    ULONG Release();\n    void OnDataChange(FORMATETC*, STGMEDIUM*);\n    void OnViewChange(DWORD, LONG);\n    void OnRename(IMoniker);\n    void OnSave();\n    void OnClose();\n}\n\ninterface IAdviseSink2 : IAdviseSink\n{\n    void OnLinkSrcChange(IMoniker);\n}\n\ninterface IDataObject : IUnknown {\n    HRESULT GetData(FORMATETC*, STGMEDIUM*);\n    HRESULT GetDataHere(FORMATETC*, STGMEDIUM*);\n    HRESULT QueryGetData(FORMATETC*);\n    HRESULT GetCanonicalFormatEtc(FORMATETC*, FORMATETC*);\n    HRESULT SetData(FORMATETC*, STGMEDIUM*, BOOL);\n    HRESULT EnumFormatEtc(DWORD, IEnumFORMATETC*);\n    HRESULT DAdvise(FORMATETC*, DWORD, IAdviseSink, PDWORD);\n    HRESULT DUnadvise(DWORD);\n    HRESULT EnumDAdvise(IEnumSTATDATA*);\n}\n\ninterface IDataAdviseHolder : IUnknown {\n    HRESULT Advise(IDataObject, FORMATETC*, DWORD, IAdviseSink, PDWORD);\n    HRESULT Unadvise(DWORD);\n    HRESULT EnumAdvise(IEnumSTATDATA*);\n    HRESULT SendOnDataChange(IDataObject, DWORD, DWORD);\n}\n\ninterface IStorage : IUnknown {\n    HRESULT CreateStream(LPCWSTR, DWORD, DWORD, DWORD, IStream);\n    HRESULT OpenStream(LPCWSTR, PVOID, DWORD, DWORD, IStream);\n    HRESULT CreateStorage(LPCWSTR, DWORD, DWORD, DWORD, IStorage);\n    HRESULT OpenStorage(LPCWSTR, IStorage, DWORD, SNB, DWORD, IStorage);\n    HRESULT CopyTo(DWORD, IID* , SNB, IStorage);\n    HRESULT MoveElementTo(LPCWSTR, IStorage, LPCWSTR, DWORD);\n    HRESULT Commit(DWORD);\n    HRESULT Revert();\n    HRESULT EnumElements(DWORD, PVOID, DWORD, IEnumSTATSTG);\n    HRESULT DestroyElement(LPCWSTR);\n    HRESULT RenameElement(LPCWSTR, LPCWSTR);\n    HRESULT SetElementTimes(LPCWSTR, FILETIME* , FILETIME* , FILETIME* );\n    HRESULT SetClass(REFCLSID);\n    HRESULT SetStateBits(DWORD, DWORD);\n    HRESULT Stat(STATSTG*, DWORD);\n}\n\n// FIXME: GetClassID from IPersist not there - what to do about it?\ninterface IRootStorage : IPersist {\n    HRESULT QueryInterface(REFIID, PVOID*);\n    ULONG AddRef();\n    ULONG Release();\n    HRESULT SwitchToFile(LPOLESTR);\n}\n\ninterface IRpcChannelBuffer : IUnknown {\n    HRESULT GetBuffer(RPCOLEMESSAGE*, REFIID);\n    HRESULT SendReceive(RPCOLEMESSAGE*, PULONG);\n    HRESULT FreeBuffer(RPCOLEMESSAGE*);\n    HRESULT GetDestCtx(PDWORD, PVOID*);\n    HRESULT IsConnected();\n}\n\ninterface IRpcProxyBuffer : IUnknown {\n    HRESULT Connect(IRpcChannelBuffer);\n    void Disconnect();\n}\n\ninterface IRpcStubBuffer : IUnknown {\n    HRESULT Connect(LPUNKNOWN);\n    void Disconnect();\n    HRESULT Invoke(RPCOLEMESSAGE*, LPRPCSTUBBUFFER);\n    LPRPCSTUBBUFFER IsIIDSupported(REFIID);\n    ULONG CountRefs();\n    HRESULT DebugServerQueryInterface(PVOID*);\n    HRESULT DebugServerRelease(PVOID);\n}\n\ninterface IPSFactoryBuffer : IUnknown {\n    HRESULT CreateProxy(LPUNKNOWN, REFIID, LPRPCPROXYBUFFER*, PVOID*);\n    HRESULT CreateStub(REFIID, LPUNKNOWN, LPRPCSTUBBUFFER*);\n}\nalias IPSFactoryBuffer LPPSFACTORYBUFFER;\n\ninterface ILockBytes : IUnknown {\n    HRESULT ReadAt(ULARGE_INTEGER, PVOID, ULONG, ULONG*);\n    HRESULT WriteAt(ULARGE_INTEGER, PCVOID, ULONG, ULONG*);\n    HRESULT Flush();\n    HRESULT SetSize(ULARGE_INTEGER);\n    HRESULT LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD);\n    HRESULT UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD);\n    HRESULT Stat(STATSTG*, DWORD);\n}\n\ninterface IExternalConnection : IUnknown {\n    HRESULT AddConnection(DWORD, DWORD);\n    HRESULT ReleaseConnection(DWORD, DWORD, BOOL);\n}\n\ninterface IRunnableObject : IUnknown {\n    HRESULT GetRunningClass(LPCLSID);\n    HRESULT Run(LPBC);\n    BOOL IsRunning();\n    HRESULT LockRunning(BOOL, BOOL);\n    HRESULT SetContainedObject(BOOL);\n}\n\ninterface IROTData : IUnknown {\n    HRESULT GetComparisonData(PVOID, ULONG, PULONG);\n}\n\ninterface IChannelHook : IUnknown {\n    void ClientGetSize(REFGUID, REFIID, PULONG);\n    void ClientFillBuffer(REFGUID, REFIID, PULONG, PVOID);\n    void ClientNotify(REFGUID, REFIID, ULONG, PVOID, DWORD, HRESULT);\n    void ServerNotify(REFGUID, REFIID, ULONG, PVOID, DWORD);\n    void ServerGetSize(REFGUID, REFIID, HRESULT, PULONG);\n    void ServerFillBuffer(REFGUID, REFIID, PULONG, PVOID, HRESULT);\n}\n\ninterface IPropertyStorage : IUnknown {\n    HRESULT ReadMultiple(ULONG, PROPSPEC* , PROPVARIANT*);\n    HRESULT WriteMultiple(ULONG, PROPSPEC* , PROPVARIANT*, PROPID);\n    HRESULT DeleteMultiple(ULONG, PROPSPEC* );\n    HRESULT ReadPropertyNames(ULONG, PROPID* , LPWSTR*);\n    HRESULT WritePropertyNames(ULONG, PROPID* , LPWSTR* );\n    HRESULT DeletePropertyNames(ULONG, PROPID* );\n    HRESULT SetClass(REFCLSID);\n    HRESULT Commit(DWORD);\n    HRESULT Revert();\n    HRESULT Enum(IEnumSTATPROPSTG*);\n    HRESULT Stat(STATPROPSTG*);\n    HRESULT SetTimes(FILETIME* , FILETIME* , FILETIME* );\n}\n\ninterface IPropertySetStorage : IUnknown {\n    HRESULT Create(REFFMTID, CLSID*, DWORD, DWORD, LPPROPERTYSTORAGE*);\n    HRESULT Open(REFFMTID, DWORD, LPPROPERTYSTORAGE*);\n    HRESULT Delete(REFFMTID);\n    HRESULT Enum(IEnumSTATPROPSETSTG*);\n}\n\ninterface IClientSecurity : IUnknown {\n    HRESULT QueryBlanket(PVOID, PDWORD, PDWORD, OLECHAR**, PDWORD, PDWORD, RPC_AUTH_IDENTITY_HANDLE**, PDWORD*);\n    HRESULT SetBlanket(PVOID, DWORD, DWORD, LPWSTR, DWORD, DWORD, RPC_AUTH_IDENTITY_HANDLE*, DWORD);\n    HRESULT CopyProxy(LPUNKNOWN, LPUNKNOWN*);\n}\n\ninterface IServerSecurity : IUnknown {\n    HRESULT QueryBlanket(PDWORD, PDWORD, OLECHAR**, PDWORD, PDWORD, RPC_AUTHZ_HANDLE*, PDWORD*);\n    HRESULT ImpersonateClient();\n    HRESULT RevertToSelf();\n    HRESULT IsImpersonating();\n}\n\ninterface IClassActivator : IUnknown {\n    HRESULT GetClassObject(REFCLSID, DWORD, LCID, REFIID, PVOID*);\n}\n\ninterface IFillLockBytes : IUnknown {\n    HRESULT FillAppend(void* , ULONG, PULONG);\n    HRESULT FillAt(ULARGE_INTEGER, void* , ULONG, PULONG);\n    HRESULT SetFillSize(ULARGE_INTEGER);\n    HRESULT Terminate(BOOL);\n}\n\ninterface IProgressNotify : IUnknown {\n    HRESULT OnProgress(DWORD, DWORD, BOOL, BOOL);\n}\n\ninterface ILayoutStorage : IUnknown {\n    HRESULT LayoutScript(STORAGELAYOUT*, DWORD, DWORD);\n    HRESULT BeginMonitor();\n    HRESULT EndMonitor();\n    HRESULT ReLayoutDocfile(OLECHAR*);\n}\n\ninterface IGlobalInterfaceTable : IUnknown {\n    HRESULT RegisterInterfaceInGlobal(IUnknown, REFIID, DWORD*);\n    HRESULT RevokeInterfaceFromGlobal(DWORD);\n    HRESULT GetInterfaceFromGlobal(DWORD, REFIID, void**);\n}\n\n/+\n// These are probably unnecessary for D.\nextern (Windows) {\nHRESULT IMarshal_GetUnmarshalClass_Proxy(IMarshal, REFIID, void*, DWORD, void*, DWORD, CLSID*);\nvoid IMarshal_GetUnmarshalClass_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMarshal_GetMarshalSizeMax_Proxy(IMarshal, REFIID, void*, DWORD, void*, DWORD, DWORD*);\nvoid IMarshal_GetMarshalSizeMax_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMarshal_MarshalInterface_Proxy(IMarshal, IStream, REFIID, void*, DWORD, void*, DWORD);\nvoid IMarshal_MarshalInterface_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMarshal_UnmarshalInterface_Proxy(IMarshal, IStream, REFIID, void**);\nvoid IMarshal_UnmarshalInterface_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMarshal_ReleaseMarshalData_Proxy(IMarshal, IStream);\nvoid IMarshal_ReleaseMarshalData_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMarshal_DisconnectObject_Proxy(IMarshal, DWORD);\nvoid IMarshal_DisconnectObject_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid* IMalloc_Alloc_Proxy(IMalloc, ULONG);\nvoid IMalloc_Alloc_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid* IMalloc_Realloc_Proxy(IMalloc, void*, ULONG);\nvoid IMalloc_Realloc_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IMalloc_Free_Proxy(IMalloc, void*);\nvoid IMalloc_Free_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nULONG IMalloc_GetSize_Proxy(IMalloc, void*);\nvoid IMalloc_GetSize_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nint IMalloc_DidAlloc_Proxy(IMalloc, void*);\nvoid IMalloc_DidAlloc_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IMalloc_HeapMinimize_Proxy(IMalloc);\nvoid IMalloc_HeapMinimize_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nULONG IMallocSpy_PreAlloc_Proxy(IMallocSpy, ULONG cbRequest);\nvoid IMallocSpy_PreAlloc_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid* IMallocSpy_PostAlloc_Proxy(IMallocSpy, void*);\nvoid IMallocSpy_PostAlloc_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid* IMallocSpy_PreFree_Proxy(IMallocSpy, void*, BOOL);\nvoid IMallocSpy_PreFree_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IMallocSpy_PostFree_Proxy(IMallocSpy, BOOL);\nvoid IMallocSpy_PostFree_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nULONG IMallocSpy_PreRealloc_Proxy(IMallocSpy, void*, ULONG, void**, BOOL);\nvoid IMallocSpy_PreRealloc_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid* IMallocSpy_PostRealloc_Proxy(IMallocSpy, void*, BOOL);\nvoid IMallocSpy_PostRealloc_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid* IMallocSpy_PreGetSize_Proxy(IMallocSpy, void*, BOOL);\nvoid IMallocSpy_PreGetSize_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nULONG IMallocSpy_PostGetSize_Proxy(IMallocSpy, ULONG, BOOL);\nvoid IMallocSpy_PostGetSize_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid* IMallocSpy_PreDidAlloc_Proxy(IMallocSpy, void*, BOOL);\nvoid IMallocSpy_PreDidAlloc_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nint IMallocSpy_PostDidAlloc_Proxy(IMallocSpy, void*, BOOL, int);\nvoid IMallocSpy_PostDidAlloc_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IMallocSpy_PreHeapMinimize_Proxy(IMallocSpy );\nvoid IMallocSpy_PreHeapMinimize_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IMallocSpy_PostHeapMinimize_Proxy(IMallocSpy);\nvoid IMallocSpy_PostHeapMinimize_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStdMarshalInfo_GetClassForHandler_Proxy(IStdMarshalInfo, DWORD, void*, CLSID*);\nvoid IStdMarshalInfo_GetClassForHandler_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nDWORD IExternalConnection_AddConnection_Proxy(IExternalConnection, DWORD, DWORD);\nvoid IExternalConnection_AddConnection_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nDWORD IExternalConnection_ReleaseConnection_Proxy(IExternalConnection, DWORD, DWORD, BOOL);\nvoid IExternalConnection_ReleaseConnection_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumUnknown_RemoteNext_Proxy(IEnumUnknown, ULONG, IUnknown*, ULONG*);\nvoid IEnumUnknown_RemoteNext_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumUnknown_Skip_Proxy(IEnumUnknown, ULONG);\nvoid IEnumUnknown_Skip_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumUnknown_Reset_Proxy(IEnumUnknown );\nvoid IEnumUnknown_Reset_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumUnknown_Clone_Proxy(IEnumUnknown, IEnumUnknown*);\nvoid IEnumUnknown_Clone_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IBindCtx_RegisterObjectBound_Proxy(IBindCtx, IUnknownpunk);\nvoid IBindCtx_RegisterObjectBound_Stub(IRpcStubBuffer, IRpcChannelBuffer_pRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IBindCtx_RevokeObjectBound_Proxy(IBindCtx, IUnknownpunk);\nvoid IBindCtx_RevokeObjectBound_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IBindCtx_ReleaseBoundObjects_Proxy(IBindCtx);\nvoid IBindCtx_ReleaseBoundObjects_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IBindCtx_SetBindOptions_Proxy(IBindCtx, BIND_OPTS*);\nvoid IBindCtx_SetBindOptions_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IBindCtx_GetBindOptions_Proxy(IBindCtx, BIND_OPTS*pbindopts);\nvoid IBindCtx_GetBindOptions_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IBindCtx_GetRunningObjectTable_Proxy(IBindCtx, IRunningObjectTable*);\nvoid IBindCtx_GetRunningObjectTable_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IBindCtx_RegisterObjectParam_Proxy(IBindCtx, LPCSTR, IUnknown);\nvoid IBindCtx_RegisterObjectParam_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IBindCtx_GetObjectParam_Proxy(IBindCtx, LPCSTR, IUnknown*);\nvoid IBindCtx_GetObjectParam_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IBindCtx_EnumObjectParam_Proxy(IBindCtx, IEnumString*);\nvoid IBindCtx_EnumObjectParam_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IBindCtx_RevokeObjectParam_Proxy(IBindCtx, LPCSTR);\nvoid IBindCtx_RevokeObjectParam_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumMoniker_RemoteNext_Proxy(IEnumMoniker, ULONG, IMoniker*, ULONG*);\nvoid IEnumMoniker_RemoteNext_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumMoniker_Skip_Proxy(IEnumMoniker, ULONG);\nvoid IEnumMoniker_Skip_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumMoniker_Reset_Proxy(IEnumMoniker);\nvoid IEnumMoniker_Reset_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumMoniker_Clone_Proxy(IEnumMoniker, IEnumMoniker*);\nvoid IEnumMoniker_Clone_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRunnableObject_GetRunningClass_Proxy(IRunnableObject, LPCLSID);\nvoid IRunnableObject_GetRunningClass_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRunnableObject_Run_Proxy(IRunnableObject, LPBINDCTX);\nvoid IRunnableObject_Run_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nBOOL IRunnableObject_IsRunning_Proxy(IRunnableObject);\nvoid IRunnableObject_IsRunning_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRunnableObject_LockRunning_Proxy(IRunnableObject, BOOL, BOOL);\nvoid IRunnableObject_LockRunning_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRunnableObject_SetContainedObject_Proxy(IRunnableObject, BOOL);\nvoid IRunnableObject_SetContainedObject_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRunningObjectTable_Register_Proxy(IRunningObjectTable, DWORD, IUnknown, IMoniker, DWORD*);\nvoid IRunningObjectTable_Register_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRunningObjectTable_Revoke_Proxy(IRunningObjectTable, DWORD);\nvoid IRunningObjectTable_Revoke_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRunningObjectTable_IsRunning_Proxy(IRunningObjectTable, IMoniker);\nvoid IRunningObjectTable_IsRunning_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRunningObjectTable_GetObject_Proxy(IRunningObjectTable, IMoniker, IUnknown*);\nvoid IRunningObjectTable_GetObject_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRunningObjectTable_NoteChangeTime_Proxy(IRunningObjectTable, DWORD, FILETIME*);\nvoid IRunningObjectTable_NoteChangeTime_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRunningObjectTable_GetTimeOfLastChange_Proxy(IRunningObjectTable, IMoniker, FILETIME*);\nvoid IRunningObjectTable_GetTimeOfLastChange_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRunningObjectTable_EnumRunning_Proxy(IRunningObjectTable, IEnumMoniker*);\nvoid IRunningObjectTable_EnumRunning_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersist_GetClassID_Proxy(IPersist, CLSID*);\nvoid IPersist_GetClassID_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistStream_IsDirty_Proxy(IPersistStream);\nvoid IPersistStream_IsDirty_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistStream_Load_Proxy(IPersistStream, IStream);\nvoid IPersistStream_Load_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistStream_Save_Proxy(IPersistStream, IStream, BOOL);\nvoid IPersistStream_Save_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistStream_GetSizeMax_Proxy(IPersistStream, ULARGE_INTEGER*);\nvoid IPersistStream_GetSizeMax_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_RemoteBindToObject_Proxy(IMoniker, IBindCtx, IMoniker, REFIID, IUnknown*);\nvoid IMoniker_RemoteBindToObject_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_RemoteBindToStorage_Proxy(IMoniker, IBindCtx, IMoniker, REFIID, IUnknown*);\nvoid IMoniker_RemoteBindToStorage_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_Reduce_Proxy(IMoniker, IBindCtx, DWORD, IMoniker*, IMoniker*);\nvoid IMoniker_Reduce_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_ComposeWith_Proxy(IMoniker, IMoniker, BOOL, IMoniker*);\nvoid IMoniker_ComposeWith_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_Enum_Proxy(IMoniker, BOOL, IEnumMoniker*);\nvoid IMoniker_Enum_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_IsEqual_Proxy(IMoniker, IMoniker);\nvoid IMoniker_IsEqual_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_Hash_Proxy(IMoniker, DWORD*);\nvoid IMoniker_Hash_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_IsRunning_Proxy(IMoniker, IBindCtx, IMoniker, IMoniker);\nvoid IMoniker_IsRunning_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_GetTimeOfLastChange_Proxy(IMoniker, IBindCtx, IMoniker, FILETIME*);\nvoid IMoniker_GetTimeOfLastChange_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_Inverse_Proxy(IMoniker, IMoniker*);\nvoid IMoniker_Inverse_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_CommonPrefixWith_Proxy(IMoniker, IMoniker, IMoniker*);\nvoid IMoniker_CommonPrefixWith_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_RelativePathTo_Proxy(IMoniker, IMoniker, IMoniker*);\nvoid IMoniker_RelativePathTo_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_GetDisplayName_Proxy(IMoniker, IBindCtx, IMoniker, LPCSTR*);\nvoid IMoniker_GetDisplayName_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_ParseDisplayName_Proxy(IMoniker, IBindCtx, IMoniker, LPCSTR, ULONG*, IMoniker*);\nvoid IMoniker_ParseDisplayName_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IMoniker_IsSystemMoniker_Proxy(IMoniker, DWORD*);\nvoid IMoniker_IsSystemMoniker_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IROTData_GetComparisonData_Proxy(IROTData, BYTE*, ULONG cbMax, ULONG*);\nvoid IROTData_GetComparisonData_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumString_RemoteNext_Proxy(IEnumString, ULONG, LPCSTR*rgelt, ULONG*);\nvoid IEnumString_RemoteNext_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumString_Skip_Proxy(IEnumString, ULONG);\nvoid IEnumString_Skip_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumString_Reset_Proxy(IEnumString);\nvoid IEnumString_Reset_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumString_Clone_Proxy(IEnumString, IEnumString*);\nvoid IEnumString_Clone_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStream_RemoteRead_Proxy(IStream, BYTE*, ULONG, ULONG*);\nvoid IStream_RemoteRead_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStream_RemoteWrite_Proxy(IStream, BYTE*pv, ULONG, ULONG*);\nvoid IStream_RemoteWrite_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStream_RemoteSeek_Proxy(IStream, LARGE_INTEGER, DWORD, ULARGE_INTEGER*);\nvoid IStream_RemoteSeek_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStream_SetSize_Proxy(IStream, ULARGE_INTEGER);\nvoid IStream_SetSize_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStream_RemoteCopyTo_Proxy(IStream, IStream, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*);\nvoid IStream_RemoteCopyTo_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStream_Commit_Proxy(IStream, DWORD);\nvoid IStream_Commit_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStream_Revert_Proxy(IStream);\nvoid IStream_Revert_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStream_LockRegion_Proxy(IStream, ULARGE_INTEGER, ULARGE_INTEGER, DWORD);\nvoid IStream_LockRegion_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStream_UnlockRegion_Proxy(IStream, ULARGE_INTEGER, ULARGE_INTEGER, DWORD);\nvoid IStream_UnlockRegion_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStream_Stat_Proxy(IStream, STATSTG*, DWORD);\nvoid IStream_Stat_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStream_Clone_Proxy(IStream, IStream*);\nvoid IStream_Clone_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumSTATSTG_RemoteNext_Proxy(IEnumSTATSTG, ULONG, STATSTG*, ULONG*);\nvoid IEnumSTATSTG_RemoteNext_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumSTATSTG_Skip_Proxy(IEnumSTATSTG, ULONG celt);\nvoid IEnumSTATSTG_Skip_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumSTATSTG_Reset_Proxy(IEnumSTATSTG);\nvoid IEnumSTATSTG_Reset_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumSTATSTG_Clone_Proxy(IEnumSTATSTG, IEnumSTATSTG*);\nvoid IEnumSTATSTG_Clone_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_CreateStream_Proxy(IStorage, OLECHAR*, DWORD, DWORD, DWORD, IStream*);\nvoid IStorage_CreateStream_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_RemoteOpenStream_Proxy(IStorage, const(OLECHAR)*, uint, BYTE*, DWORD, DWORD, IStream*);\nvoid IStorage_RemoteOpenStream_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_CreateStorage_Proxy(IStorage, OLECHAR*, DWORD, DWORD, DWORD, IStorage*);\nvoid IStorage_CreateStorage_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_OpenStorage_Proxy(IStorage, OLECHAR*, IStorage, DWORD, SNB, DWORD, IStorage*);\nvoid IStorage_OpenStorage_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_CopyTo_Proxy(IStorage, DWORD, const(IID)*, SNB, IStorage);\nvoid IStorage_CopyTo_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_MoveElementTo_Proxy(IStorage, const(OLECHAR)*, IStorage, const(OLECHAR)*, DWORD);\nvoid IStorage_MoveElementTo_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_Commit_Proxy(IStorage, DWORD);\nvoid IStorage_Commit_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_Revert_Proxy(IStorage);\nvoid IStorage_Revert_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_RemoteEnumElements_Proxy(IStorage, DWORD, uint, BYTE*, DWORD, IEnumSTATSTG*);\nvoid IStorage_RemoteEnumElements_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_DestroyElement_Proxy(IStorage, OLECHAR*);\nvoid IStorage_DestroyElement_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_RenameElement_Proxy(IStorage, const(OLECHAR)*, const(OLECHAR)*);\nvoid IStorage_RenameElement_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_SetElementTimes_Proxy(IStorage, const(OLECHAR)*, const(FILETIME)*, const(FILETIME)*, const(FILETIME)*);\nvoid IStorage_SetElementTimes_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_SetClass_Proxy(IStorage, REFCLSID);\nvoid IStorage_SetClass_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_SetStateBits_Proxy(IStorage, DWORD, DWORD);\nvoid IStorage_SetStateBits_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IStorage_Stat_Proxy(IStorage, STATSTG*, DWORD);\nvoid IStorage_Stat_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistFile_IsDirty_Proxy(IPersistFile);\nvoid IPersistFile_IsDirty_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistFile_Load_Proxy(IPersistFile, LPCOLESTR, DWORD);\nvoid IPersistFile_Load_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistFile_Save_Proxy(IPersistFile, LPCOLESTR pszFileName, BOOL);\nvoid IPersistFile_Save_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistFile_SaveCompleted_Proxy(IPersistFile, LPCOLESTR);\nvoid IPersistFile_SaveCompleted_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistFile_GetCurFile_Proxy(IPersistFile, LPCSTR*);\nvoid IPersistFile_GetCurFile_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistStorage_IsDirty_Proxy(IPersistStorage);\nvoid IPersistStorage_IsDirty_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistStorage_InitNew_Proxy(IPersistStorage, IStorage);\nvoid IPersistStorage_InitNew_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistStorage_Load_Proxy(IPersistStorage, IStorage);\nvoid IPersistStorage_Load_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistStorage_Save_Proxy(IPersistStorage, IStorage, BOOL);\nvoid IPersistStorage_Save_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistStorage_SaveCompleted_Proxy(IPersistStorage, IStorage);\nvoid IPersistStorage_SaveCompleted_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPersistStorage_HandsOffStorage_Proxy(IPersistStorage);\nvoid IPersistStorage_HandsOffStorage_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT ILockBytes_RemoteReadAt_Proxy(ILockBytes, ULARGE_INTEGER, BYTE*, ULONG, ULONG*);\nvoid ILockBytes_RemoteReadAt_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT ILockBytes_RemoteWriteAt_Proxy(ILockBytes, ULARGE_INTEGER, BYTE*pv, ULONG, ULONG*);\nvoid ILockBytes_RemoteWriteAt_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT ILockBytes_Flush_Proxy(ILockBytes);\nvoid ILockBytes_Flush_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT ILockBytes_SetSize_Proxy(ILockBytes, ULARGE_INTEGER);\nvoid ILockBytes_SetSize_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT ILockBytes_LockRegion_Proxy(ILockBytes, ULARGE_INTEGER, ULARGE_INTEGER, DWORD);\nvoid ILockBytes_LockRegion_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT ILockBytes_UnlockRegion_Proxy(ILockBytes, ULARGE_INTEGER, ULARGE_INTEGER, DWORD);\nvoid ILockBytes_UnlockRegion_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT ILockBytes_Stat_Proxy(ILockBytes, STATSTG*, DWORD);\nvoid ILockBytes_Stat_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumFORMATETC_RemoteNext_Proxy(IEnumFORMATETC, ULONG, FORMATETC*, ULONG*);\nvoid IEnumFORMATETC_RemoteNext_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumFORMATETC_Skip_Proxy(IEnumFORMATETC, ULONG);\nvoid IEnumFORMATETC_Skip_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumFORMATETC_Reset_Proxy(IEnumFORMATETC);\nvoid IEnumFORMATETC_Reset_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumFORMATETC_Clone_Proxy(IEnumFORMATETC, IEnumFORMATETC*);\nvoid IEnumFORMATETC_Clone_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumFORMATETC_Next_Proxy(IEnumFORMATETC, ULONG, FORMATETC*, ULONG*);\nHRESULT IEnumFORMATETC_Next_Stub(IEnumFORMATETC, ULONG, FORMATETC*, ULONG*);\nHRESULT IEnumSTATDATA_RemoteNext_Proxy(IEnumSTATDATA, ULONG, STATDATA*, ULONG*);\nvoid IEnumSTATDATA_RemoteNext_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumSTATDATA_Skip_Proxy(IEnumSTATDATA, ULONG);\nvoid IEnumSTATDATA_Skip_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumSTATDATA_Reset_Proxy(IEnumSTATDATA);\nvoid IEnumSTATDATA_Reset_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumSTATDATA_Clone_Proxy(IEnumSTATDATA, IEnumSTATDATA*);\nvoid IEnumSTATDATA_Clone_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IEnumSTATDATA_Next_Proxy(IEnumSTATDATA, ULONG, STATDATA*, ULONG*);\nHRESULT IEnumSTATDATA_Next_Stub(IEnumSTATDATA, ULONG, STATDATA*, ULONG*);\nHRESULT IRootStorage_SwitchToFile_Proxy(IRootStorage, LPCSTR);\nvoid IRootStorage_SwitchToFile_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IAdviseSink_RemoteOnDataChange_Proxy(IAdviseSink, FORMATETC*, RemSTGMEDIUM*);\nvoid IAdviseSink_RemoteOnDataChange_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IAdviseSink_RemoteOnViewChange_Proxy(IAdviseSink, DWORD, LONG);\nvoid IAdviseSink_RemoteOnViewChange_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IAdviseSink_RemoteOnRename_Proxy(IAdviseSink, IMoniker);\nvoid IAdviseSink_RemoteOnRename_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IAdviseSink_RemoteOnSave_Proxy(IAdviseSink);\nvoid IAdviseSink_RemoteOnSave_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IAdviseSink_RemoteOnClose_Proxy(IAdviseSink);\nvoid IAdviseSink_RemoteOnClose_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IAdviseSink_OnDataChange_Proxy(IAdviseSink, FORMATETC*, STGMEDIUM*);\nvoid IAdviseSink_OnDataChange_Stub(IAdviseSink, FORMATETC*, RemSTGMEDIUM*);\nvoid IAdviseSink_OnViewChange_Proxy(IAdviseSink, DWORD, LONG);\nvoid IAdviseSink_OnViewChange_Stub(IAdviseSink, DWORD, LONG);\nvoid IAdviseSink_OnRename_Proxy(IAdviseSink, IMoniker);\nvoid IAdviseSink_OnRename_Stub(IAdviseSink, IMoniker);\nvoid IAdviseSink_OnSave_Proxy(IAdviseSink);\nvoid IAdviseSink_OnSave_Stub(IAdviseSink);\nvoid IAdviseSink_OnClose_Proxy(IAdviseSink);\nHRESULT IAdviseSink_OnClose_Stub(IAdviseSink);\nvoid IAdviseSink2_RemoteOnLinkSrcChange_Proxy(IAdviseSink2, IMoniker);\nvoid IAdviseSink2_RemoteOnLinkSrcChange_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IAdviseSink2_OnLinkSrcChange_Proxy(IAdviseSink2, IMoniker);\nvoid IAdviseSink2_OnLinkSrcChange_Stub(IAdviseSink2, IMoniker);\nHRESULT IDataObject_RemoteGetData_Proxy(IDataObject, FORMATETC*, RemSTGMEDIUM**);\nvoid IDataObject_RemoteGetData_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataObject_RemoteGetDataHere_Proxy(IDataObject, FORMATETC*, RemSTGMEDIUM**);\nvoid IDataObject_RemoteGetDataHere_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataObject_QueryGetData_Proxy(IDataObject, FORMATETC*);\nvoid IDataObject_QueryGetData_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataObject_GetCanonicalFormatEtc_Proxy(IDataObject, FORMATETC*, FORMATETC*);\nvoid IDataObject_GetCanonicalFormatEtc_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataObject_RemoteSetData_Proxy(IDataObject, FORMATETC*, RemSTGMEDIUM*, BOOL);\nvoid IDataObject_RemoteSetData_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataObject_EnumFormatEtc_Proxy(IDataObject, DWORD, IEnumFORMATETC*);\nvoid IDataObject_EnumFormatEtc_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataObject_DAdvise_Proxy(IDataObject, FORMATETC*, DWORD, IAdviseSink, DWORD*);\nvoid IDataObject_DAdvise_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataObject_DUnadvise_Proxy(IDataObject, DWORD);\nvoid IDataObject_DUnadvise_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataObject_EnumDAdvise_Proxy(IDataObject, IEnumSTATDATA*);\nvoid IDataObject_EnumDAdvise_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataObject_GetData_Proxy(IDataObject, FORMATETC*, STGMEDIUM*);\nHRESULT IDataObject_GetData_Stub(IDataObject, FORMATETC*, RemSTGMEDIUM**);\nHRESULT IDataObject_GetDataHere_Proxy(IDataObject, FORMATETC*, STGMEDIUM*);\nHRESULT IDataObject_GetDataHere_Stub(IDataObject, FORMATETC*, RemSTGMEDIUM**);\nHRESULT IDataObject_SetData_Proxy(IDataObject, FORMATETC*, STGMEDIUM*, BOOL);\nHRESULT IDataObject_SetData_Stub(IDataObject, FORMATETC*, RemSTGMEDIUM*, BOOL);\nHRESULT IDataAdviseHolder_Advise_Proxy(IDataAdviseHolder, IDataObject, FORMATETC*, DWORD, IAdviseSink, DWORD*);\nvoid IDataAdviseHolder_Advise_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataAdviseHolder_Unadvise_Proxy(IDataAdviseHolder, DWORD);\nvoid IDataAdviseHolder_Unadvise_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataAdviseHolder_EnumAdvise_Proxy(IDataAdviseHolder, IEnumSTATDATA*);\nvoid IDataAdviseHolder_EnumAdvise_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IDataAdviseHolder_SendOnDataChange_Proxy(IDataAdviseHolder, IDataObject, DWORD, DWORD);\nvoid IDataAdviseHolder_SendOnDataChange_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nDWORD IMessageFilter_HandleInComingCall_Proxy(IMessageFilter, DWORD, HTASK, DWORD, LPINTERFACEINFO);\nvoid IMessageFilter_HandleInComingCall_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nDWORD IMessageFilter_RetryRejectedCall_Proxy(IMessageFilter, HTASK, DWORD, DWORD);\nvoid IMessageFilter_RetryRejectedCall_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nDWORD IMessageFilter_MessagePending_Proxy(IMessageFilter, HTASK, DWORD, DWORD);\nvoid IMessageFilter_MessagePending_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRpcChannelBuffer_GetBuffer_Proxy(IRpcChannelBuffer, RPCOLEMESSAGE*, REFIID);\nvoid IRpcChannelBuffer_GetBuffer_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRpcChannelBuffer_SendReceive_Proxy(IRpcChannelBuffer, RPCOLEMESSAGE*, ULONG*);\nvoid IRpcChannelBuffer_SendReceive_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRpcChannelBuffer_FreeBuffer_Proxy(IRpcChannelBuffer, RPCOLEMESSAGE*);\nvoid IRpcChannelBuffer_FreeBuffer_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRpcChannelBuffer_GetDestCtx_Proxy(IRpcChannelBuffer, DWORD*, void**);\nvoid IRpcChannelBuffer_GetDestCtx_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRpcChannelBuffer_IsConnected_Proxy(IRpcChannelBuffer);\nvoid IRpcChannelBuffer_IsConnected_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRpcProxyBuffer_Connect_Proxy(IRpcProxyBuffer, IRpcChannelBufferpRpcChannelBuffer);\nvoid IRpcProxyBuffer_Connect_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IRpcProxyBuffer_Disconnect_Proxy(IRpcProxyBuffer);\nvoid IRpcProxyBuffer_Disconnect_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRpcStubBuffer_Connect_Proxy(IRpcStubBuffer, IUnknown);\nvoid IRpcStubBuffer_Connect_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IRpcStubBuffer_Disconnect_Proxy(IRpcStubBuffer);\nvoid IRpcStubBuffer_Disconnect_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRpcStubBuffer_Invoke_Proxy(IRpcStubBuffer, RPCOLEMESSAGE*, IRpcChannelBuffer);\nvoid IRpcStubBuffer_Invoke_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nIRpcStubBufferIRpcStubBuffer_IsIIDSupported_Proxy(IRpcStubBuffer, REFIID);\nvoid IRpcStubBuffer_IsIIDSupported_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nULONG IRpcStubBuffer_CountRefs_Proxy(IRpcStubBuffer);\nvoid IRpcStubBuffer_CountRefs_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IRpcStubBuffer_DebugServerQueryInterface_Proxy(IRpcStubBuffer, void**);\nvoid IRpcStubBuffer_DebugServerQueryInterface_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid IRpcStubBuffer_DebugServerRelease_Proxy(IRpcStubBuffer, void*);\nvoid IRpcStubBuffer_DebugServerRelease_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPSFactoryBuffer_CreateProxy_Proxy(IPSFactoryBuffer, IUnknown, REFIID, IRpcProxyBuffer*, void**);\nvoid IPSFactoryBuffer_CreateProxy_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nHRESULT IPSFactoryBuffer_CreateStub_Proxy(IPSFactoryBuffer, REFIID, IUnknown, IRpcStubBuffer*);\nvoid IPSFactoryBuffer_CreateStub_Stub(IRpcStubBuffer, IRpcChannelBuffer, PRPC_MESSAGE, PDWORD);\nvoid SNB_to_xmit(SNB*, RemSNB**);\nvoid SNB_from_xmit(RemSNB*, SNB*);\nvoid SNB_free_inst(SNB*);\nvoid SNB_free_xmit(RemSNB*);\nHRESULT IEnumUnknown_Next_Proxy(IEnumUnknown, ULONG, IUnknown*, ULONG*);\nHRESULT IEnumUnknown_Next_Stub(IEnumUnknown, ULONG, IUnknown*, ULONG*);\nHRESULT IEnumMoniker_Next_Proxy(IEnumMoniker, ULONG, IMoniker*, ULONG*);\nHRESULT IEnumMoniker_Next_Stub(IEnumMoniker, ULONG, IMoniker*, ULONG*);\nHRESULT IMoniker_BindToObject_Proxy(IMoniker, IBindCtx, IMoniker, REFIID, void**);\nHRESULT IMoniker_BindToObject_Stub(IMoniker, IBindCtx, IMoniker, REFIID, IUnknown*);\nHRESULT IMoniker_BindToStorage_Proxy(IMoniker, IBindCtx, IMoniker, REFIID, void**);\nHRESULT IMoniker_BindToStorage_Stub(IMoniker, IBindCtx, IMoniker, REFIID, IUnknown*);\nHRESULT IEnumString_Next_Proxy(IEnumString, ULONG, LPCSTR*, ULONG*);\nHRESULT IEnumString_Next_Stub(IEnumString, ULONG, LPCSTR*, ULONG*);\nHRESULT IStream_Read_Proxy(IStream, void*, ULONG, ULONG*);\nHRESULT IStream_Read_Stub(IStream, BYTE*, ULONG, ULONG*);\nHRESULT IStream_Write_Proxy(IStream, void*, ULONG, ULONG*);\nHRESULT IStream_Write_Stub(IStream, BYTE*, ULONG, ULONG*);\nHRESULT IStream_Seek_Proxy(IStream, LARGE_INTEGER, DWORD, ULARGE_INTEGER*);\nHRESULT IStream_Seek_Stub(IStream, LARGE_INTEGER, DWORD, ULARGE_INTEGER*);\nHRESULT IStream_CopyTo_Proxy(IStream, IStream, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*);\nHRESULT IStream_CopyTo_Stub(IStream, IStream, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*);\nHRESULT IEnumSTATSTG_Next_Proxy(IEnumSTATSTG, ULONG, STATSTG*, ULONG*);\nHRESULT IEnumSTATSTG_Next_Stub(IEnumSTATSTG, ULONG, STATSTG*, ULONG*);\nHRESULT IStorage_OpenStream_Proxy(IStorage, OLECHAR*, void*, DWORD, DWORD, IStream*);\nHRESULT IStorage_OpenStream_Stub(IStorage, OLECHAR*, uint, BYTE*, DWORD, DWORD, IStream* );\nHRESULT IStorage_EnumElements_Proxy(IStorage, DWORD, void*, DWORD, IEnumSTATSTG*);\nHRESULT IStorage_EnumElements_Stub(IStorage, DWORD, uint, BYTE*, DWORD, IEnumSTATSTG*);\nHRESULT ILockBytes_ReadAt_Proxy(ILockBytes, ULARGE_INTEGER, void*, ULONG, ULONG*);\nHRESULT ILockBytes_ReadAt_Stub(ILockBytes, ULARGE_INTEGER, BYTE*, ULONG, ULONG*);\nHRESULT ILockBytes_WriteAt_Proxy(ILockBytes, ULARGE_INTEGER, const(void)*, ULONG, ULONG*);\nHRESULT ILockBytes_WriteAt_Stub(ILockBytes, ULARGE_INTEGER, BYTE*, ULONG, ULONG*);\n}\n+/\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/objsafe.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_objsafe.d)\n */\nmodule core.sys.windows.objsafe;\nversion (Windows):\n\nprivate import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef;\n\nenum {\n    INTERFACESAFE_FOR_UNTRUSTED_CALLER = 1,\n    INTERFACESAFE_FOR_UNTRUSTED_DATA\n}\n\ninterface IObjectSafety : IUnknown {\n    HRESULT GetInterfaceSafetyOptions(REFIID, DWORD*, DWORD*);\n    HRESULT SetInterfaceSafetyOptions(REFIID, DWORD, DWORD);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ocidl.d",
    "content": "/**\n * Windows API header module\n *\n * Part of the Internet Development SDK\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ocidl.d)\n */\nmodule core.sys.windows.ocidl;\nversion (Windows):\n\nprivate import core.sys.windows.ole2, core.sys.windows.oleidl, core.sys.windows.oaidl, core.sys.windows.objfwd,\n  core.sys.windows.windef, core.sys.windows.wtypes;\nprivate import core.sys.windows.objidl;  // for CLIPFORMAT\nprivate import core.sys.windows.wingdi;  // for TEXTMETRICW\nprivate import core.sys.windows.winuser; // for LPMSG\n\ninterface IBindHost : IUnknown {}\n\ninterface IServiceProvider : IUnknown{\n    HRESULT QueryService(REFGUID,REFIID,void**);\n}\n\n/*\n// TODO:\n//private import core.sys.windows.servprov; // for IServiceProvider\n// private import core.sys.windows.urlmon; // for IBindHost. This is not included in MinGW.\n\n// core.sys.windows.urlmon should contain:\ninterface IBindHost : IUnknown\n{\n    HRESULT CreateMoniker(LPOLESTR szName, IBindCtx pBC, IMoniker* ppmk, DWORD);\n    HRESULT MonikerBindToObject(IMoniker pMk, IBindCtx pBC, IBindStatusCallback pBSC, REFIID, void** );\n    HRESULT MonikerBindToStorage(IMoniker pMk, IBindCtx pBC, IBindStatusCallback pBSC, REFIID, void** );\n}\n*/\n\n\n\n\n//[Yes] #ifndef OLE2ANSI\nalias TEXTMETRICW TEXTMETRICOLE;\n//} else {\n//alias TEXTMETRIC TEXTMETRICOLE;\n//}\nalias TEXTMETRICOLE* LPTEXTMETRICOLE;\n\nalias DWORD OLE_COLOR;\nalias UINT OLE_HANDLE;\nalias int OLE_XPOS_HIMETRIC;\nalias int OLE_YPOS_HIMETRIC;\nalias int OLE_XSIZE_HIMETRIC;\nalias int OLE_YSIZE_HIMETRIC;\n\nenum READYSTATE {\n    READYSTATE_UNINITIALIZED = 0,\n    READYSTATE_LOADING = 1,\n    READYSTATE_LOADED = 2,\n    READYSTATE_INTERACTIVE = 3,\n    READYSTATE_COMPLETE = 4\n}\n\nenum PROPBAG2_TYPE {\n    PROPBAG2_TYPE_UNDEFINED,\n    PROPBAG2_TYPE_DATA,\n    PROPBAG2_TYPE_URL,\n    PROPBAG2_TYPE_OBJECT,\n    PROPBAG2_TYPE_STREAM,\n    PROPBAG2_TYPE_STORAGE,\n    PROPBAG2_TYPE_MONIKER // = 6\n}\n\nstruct PROPBAG2 {\n    DWORD dwType;\n    VARTYPE vt;\n    CLIPFORMAT cfType;\n    DWORD dwHint;\n    LPOLESTR pstrName;\n    CLSID clsid;\n}\n\nenum QACONTAINERFLAGS {\n    QACONTAINER_SHOWHATCHING = 1,\n    QACONTAINER_SHOWGRABHANDLES = 2,\n    QACONTAINER_USERMODE = 4,\n    QACONTAINER_DISPLAYASDEFAULT = 8,\n    QACONTAINER_UIDEAD = 16,\n    QACONTAINER_AUTOCLIP = 32,\n    QACONTAINER_MESSAGEREFLECT = 64,\n    QACONTAINER_SUPPORTSMNEMONICS = 128\n}\n\nstruct QACONTAINER {\n    ULONG cbSize = this.sizeof;\n    IOleClientSite pClientSite;\n    IAdviseSinkEx pAdviseSink;\n    IPropertyNotifySink pPropertyNotifySink;\n    IUnknown pUnkEventSink;\n    DWORD dwAmbientFlags;\n    OLE_COLOR colorFore;\n    OLE_COLOR colorBack;\n    IFont pFont;\n    IOleUndoManager pUndoMgr;\n    DWORD dwAppearance;\n    LONG lcid;\n    HPALETTE hpal;\n    IBindHost pBindHost;\n    IOleControlSite pOleControlSite;\n    IServiceProvider pServiceProvider;\n}\n\nstruct QACONTROL {\n    ULONG cbSize = this.sizeof;\n    DWORD dwMiscStatus;\n    DWORD dwViewStatus;\n    DWORD dwEventCookie;\n    DWORD dwPropNotifyCookie;\n    DWORD dwPointerActivationPolicy;\n}\n\nstruct POINTF {\n    float x;\n    float y;\n}\nalias POINTF* LPPOINTF;\n\nstruct CONTROLINFO {\n    ULONG cb;\n    HACCEL hAccel;\n    USHORT cAccel;\n    DWORD dwFlags;\n}\nalias CONTROLINFO* LPCONTROLINFO;\n\nstruct CONNECTDATA {\n    LPUNKNOWN pUnk;\n    DWORD dwCookie;\n}\nalias CONNECTDATA* LPCONNECTDATA;\n\nstruct LICINFO {\n    int cbLicInfo;\n    BOOL fRuntimeKeyAvail;\n    BOOL fLicVerified;\n}\nalias LICINFO* LPLICINFO;\n\nstruct CAUUID {\n    ULONG cElems;\n    GUID* pElems;\n}\nalias CAUUID* LPCAUUID;\n\nstruct CALPOLESTR {\n    ULONG cElems;\n    LPOLESTR* pElems;\n}\nalias CALPOLESTR* LPCALPOLESTR;\n\nstruct CADWORD {\n    ULONG cElems;\n    DWORD* pElems;\n}\nalias CADWORD* LPCADWORD;\n\nstruct PROPPAGEINFO {\n    ULONG cb;\n    LPOLESTR pszTitle;\n    SIZE size;\n    LPOLESTR pszDocString;\n    LPOLESTR pszHelpFile;\n    DWORD dwHelpContext;\n}\nalias PROPPAGEINFO* LPPROPPAGEINFO;\n\ninterface IOleControl : IUnknown {\n    HRESULT GetControlInfo(LPCONTROLINFO);\n    HRESULT OnMnemonic(LPMSG);\n    HRESULT OnAmbientPropertyChange(DISPID);\n    HRESULT FreezeEvents(BOOL);\n}\n\ninterface IOleControlSite : IUnknown {\n    HRESULT OnControlInfoChanged();\n    HRESULT LockInPlaceActive(BOOL);\n    HRESULT GetExtendedControl(LPDISPATCH*);\n    HRESULT TransformCoords(POINTL*, POINTF*, DWORD);\n    HRESULT TranslateAccelerator(LPMSG, DWORD);\n    HRESULT OnFocus(BOOL);\n    HRESULT ShowPropertyFrame();\n}\n\ninterface ISimpleFrameSite : IUnknown {\n    HRESULT PreMessageFilter(HWND, UINT, WPARAM, LPARAM, LRESULT*, PDWORD);\n    HRESULT PostMessageFilter(HWND, UINT, WPARAM, LPARAM, LRESULT*, DWORD);\n}\n\ninterface IErrorLog : IUnknown {\n    HRESULT AddError(LPCOLESTR, LPEXCEPINFO);\n}\nalias IErrorLog LPERRORLOG;\n\ninterface IPropertyBag : IUnknown {\n    HRESULT Read(LPCOLESTR, LPVARIANT, LPERRORLOG);\n    HRESULT Write(LPCOLESTR, LPVARIANT);\n}\nalias IPropertyBag LPPROPERTYBAG;\n\ninterface IPropertyBag2 : IUnknown {\n    HRESULT Read(ULONG, PROPBAG2*, LPERRORLOG, VARIANT*, HRESULT*);\n    HRESULT Write(ULONG, PROPBAG2*, VARIANT*);\n    HRESULT CountProperties(ULONG*);\n    HRESULT GetPropertyInfo(ULONG, ULONG, PROPBAG2*, ULONG*);\n    HRESULT LoadObject(LPCOLESTR, DWORD, IUnknown, LPERRORLOG);\n}\nalias IPropertyBag2 LPPROPERTYBAG2;\n\ninterface IPersistPropertyBag : IPersist {\n    HRESULT InitNew();\n    HRESULT Load(LPPROPERTYBAG, LPERRORLOG);\n    HRESULT Save(LPPROPERTYBAG, BOOL, BOOL);\n}\n\ninterface IPersistPropertyBag2 : IPersist {\n    HRESULT InitNew();\n    HRESULT Load(LPPROPERTYBAG2, LPERRORLOG);\n    HRESULT Save(LPPROPERTYBAG2, BOOL, BOOL);\n    HRESULT IsDirty();\n}\n\ninterface IPersistStreamInit : IPersist {\n    HRESULT IsDirty();\n    HRESULT Load(LPSTREAM);\n    HRESULT Save(LPSTREAM, BOOL);\n    HRESULT GetSizeMax(PULARGE_INTEGER);\n    HRESULT InitNew();\n}\n\ninterface IPersistMemory : IPersist {\n    HRESULT IsDirty();\n    HRESULT Load(PVOID, ULONG);\n    HRESULT Save(PVOID, BOOL, ULONG);\n    HRESULT GetSizeMax(PULONG);\n    HRESULT InitNew();\n}\n\ninterface IPropertyNotifySink : IUnknown {\n    HRESULT OnChanged(DISPID);\n    HRESULT OnRequestEdit(DISPID);\n}\n\ninterface IProvideClassInfo : IUnknown {\n    HRESULT GetClassInfo(LPTYPEINFO*);\n}\n\ninterface IProvideClassInfo2 : IProvideClassInfo {\n    HRESULT GetGUID(DWORD, GUID*);\n}\n\ninterface IConnectionPointContainer : IUnknown {\n    HRESULT EnumConnectionPoints(LPENUMCONNECTIONPOINTS*);\n    HRESULT FindConnectionPoint(REFIID, LPCONNECTIONPOINT*);\n}\n\ninterface IEnumConnectionPoints : IUnknown {\n    HRESULT Next(ULONG, LPCONNECTIONPOINT*, ULONG*);\n    HRESULT Skip(ULONG);\n    HRESULT Reset();\n    HRESULT Clone(LPENUMCONNECTIONPOINTS*);\n}\nalias IEnumConnectionPoints LPENUMCONNECTIONPOINTS;\n\ninterface IConnectionPoint : IUnknown {\n    HRESULT GetConnectionInterface(IID*);\n    HRESULT GetConnectionPointContainer(IConnectionPointContainer*);\n    HRESULT Advise(LPUNKNOWN, PDWORD);\n    HRESULT Unadvise(DWORD);\n    HRESULT EnumConnections(LPENUMCONNECTIONS*);\n}\nalias IConnectionPoint LPCONNECTIONPOINT;\n\ninterface IEnumConnections : IUnknown {\n    HRESULT Next(ULONG, LPCONNECTDATA, PULONG);\n    HRESULT Skip(ULONG);\n    HRESULT Reset();\n    HRESULT Clone(LPENUMCONNECTIONS*);\n}\nalias IEnumConnections LPENUMCONNECTIONS;\n\ninterface IClassFactory2 : IClassFactory {\n    HRESULT GetLicInfo(LPLICINFO);\n    HRESULT RequestLicKey(DWORD, BSTR*);\n    HRESULT CreateInstanceLic(LPUNKNOWN, LPUNKNOWN, REFIID, BSTR, PVOID*);\n}\n\ninterface ISpecifyPropertyPages : IUnknown {\n    HRESULT GetPages(CAUUID*);\n}\n\ninterface IPerPropertyBrowsing : IUnknown {\n    HRESULT GetDisplayString(DISPID, BSTR*);\n    HRESULT MapPropertyToPage(DISPID, LPCLSID);\n    HRESULT GetPredefinedStrings(DISPID, CALPOLESTR*, CADWORD*);\n    HRESULT GetPredefinedValue(DISPID, DWORD, VARIANT*);\n}\n\ninterface IPropertyPageSite : IUnknown {\n    HRESULT OnStatusChange(DWORD);\n    HRESULT GetLocaleID(LCID*);\n    HRESULT GetPageContainer(LPUNKNOWN*);\n    HRESULT TranslateAccelerator(LPMSG);\n}\nalias IPropertyPageSite LPPROPERTYPAGESITE;\n\ninterface IPropertyPage : IUnknown {\n    HRESULT SetPageSite(LPPROPERTYPAGESITE);\n    HRESULT Activate(HWND, LPCRECT, BOOL);\n    HRESULT Deactivate();\n    HRESULT GetPageInfo(LPPROPPAGEINFO);\n    HRESULT SetObjects(ULONG, LPUNKNOWN*);\n    HRESULT Show(UINT);\n    HRESULT Move(LPCRECT);\n    HRESULT IsPageDirty();\n    HRESULT Apply();\n    HRESULT Help(LPCOLESTR);\n    HRESULT TranslateAccelerator(LPMSG);\n}\n\n\ninterface IPropertyPage2 : IPropertyPage\n{ HRESULT EditProperty(DISPID);\n}\n\ninterface IFont : IUnknown {\n    HRESULT get_Name(BSTR*);\n    HRESULT put_Name(BSTR);\n    HRESULT get_Size(CY*);\n    HRESULT put_Size(CY);\n    HRESULT get_Bold(BOOL*);\n    HRESULT put_Bold(BOOL);\n    HRESULT get_Italic(BOOL*);\n    HRESULT put_Italic(BOOL);\n    HRESULT get_Underline(BOOL*);\n    HRESULT put_Underline(BOOL);\n    HRESULT get_Strikethrough(BOOL*);\n    HRESULT put_Strikethrough(BOOL);\n    HRESULT get_Weight(short*);\n    HRESULT put_Weight(short);\n    HRESULT get_Charset(short*);\n    HRESULT put_Charset(short);\n    HRESULT get_hFont(HFONT*);\n    HRESULT Clone(IFont*);\n    HRESULT IsEqual(IFont);\n    HRESULT SetRatio(int, int);\n    HRESULT QueryTextMetrics(LPTEXTMETRICOLE);\n    HRESULT AddRefHfont(HFONT);\n    HRESULT ReleaseHfont(HFONT);\n    HRESULT SetHdc(HDC);\n}\nalias IFont LPFONT;\n\ninterface IFontDisp : IDispatch {\n}\nalias IFontDisp LPFONTDISP;\n\ninterface IPicture : IUnknown {\n    HRESULT get_Handle(OLE_HANDLE*);\n    HRESULT get_hPal(OLE_HANDLE*);\n    HRESULT get_Type(short*);\n    HRESULT get_Width(OLE_XSIZE_HIMETRIC*);\n    HRESULT get_Height(OLE_YSIZE_HIMETRIC*);\n    HRESULT Render(HDC, int, int, int, int, OLE_XPOS_HIMETRIC,\n      OLE_YPOS_HIMETRIC, OLE_XSIZE_HIMETRIC, OLE_YSIZE_HIMETRIC, LPCRECT);\n    HRESULT set_hPal(OLE_HANDLE);\n    HRESULT get_CurDC(HDC*);\n    HRESULT SelectPicture(HDC, HDC*, OLE_HANDLE*);\n    HRESULT get_KeepOriginalFormat(BOOL*);\n    HRESULT put_KeepOriginalFormat(BOOL);\n    HRESULT PictureChanged();\n    HRESULT SaveAsFile(LPSTREAM, BOOL, LONG*);\n    HRESULT get_Attributes(PDWORD);\n}\n\ninterface IPictureDisp : IDispatch {\n}\n\ninterface IOleInPlaceSiteEx : IOleInPlaceSite {\n    HRESULT OnInPlaceActivateEx(BOOL*, DWORD);\n    HRESULT OnInPlaceDeactivateEx(BOOL);\n    HRESULT RequestUIActivate();\n}\n\ninterface IObjectWithSite : IUnknown {\n    HRESULT SetSite(IUnknown);\n    HRESULT GetSite(REFIID, void**);\n}\n\ninterface IOleInPlaceSiteWindowless : IOleInPlaceSiteEx {\n    HRESULT CanWindowlessActivate();\n    HRESULT GetCapture();\n    HRESULT SetCapture(BOOL);\n    HRESULT GetFocus();\n    HRESULT SetFocus(BOOL);\n    HRESULT GetDC(LPCRECT, DWORD, HDC*);\n    HRESULT ReleaseDC(HDC);\n    HRESULT InvalidateRect(LPCRECT, BOOL);\n    HRESULT InvalidateRgn(HRGN, BOOL);\n    HRESULT ScrollRect(INT, INT, LPCRECT, LPCRECT);\n    HRESULT AdjustRect(LPCRECT);\n    HRESULT OnDefWindowMessage(UINT, WPARAM, LPARAM, LRESULT*);\n}\n\ninterface IAdviseSinkEx : IUnknown {\n    void OnDataChange(FORMATETC*, STGMEDIUM*);\n    void OnViewChange(DWORD, LONG);\n    void OnRename(IMoniker);\n    void OnSave();\n    void OnClose();\n    HRESULT OnViewStatusChange(DWORD);\n}\n\ninterface IPointerInactive : IUnknown {\n    HRESULT GetActivationPolicy(DWORD*);\n    HRESULT OnInactiveMouseMove(LPCRECT, LONG, LONG, DWORD);\n    HRESULT OnInactiveSetCursor(LPCRECT, LONG, LONG, DWORD, BOOL);\n}\n\ninterface IOleUndoUnit : IUnknown {\n    HRESULT Do(LPOLEUNDOMANAGER);\n    HRESULT GetDescription(BSTR*);\n    HRESULT GetUnitType(CLSID*, LONG*);\n    HRESULT OnNextAdd();\n}\n\ninterface IOleParentUndoUnit : IOleUndoUnit {\n    HRESULT Open(IOleParentUndoUnit);\n    HRESULT Close(IOleParentUndoUnit, BOOL);\n    HRESULT Add(IOleUndoUnit);\n    HRESULT FindUnit(IOleUndoUnit);\n    HRESULT GetParentState(DWORD*);\n}\n\ninterface IEnumOleUndoUnits : IUnknown {\n    HRESULT Next(ULONG, IOleUndoUnit*, ULONG*);\n    HRESULT Skip(ULONG);\n    HRESULT Reset();\n    HRESULT Clone(IEnumOleUndoUnits*);\n}\n\ninterface IOleUndoManager : IUnknown {\n    HRESULT Open(IOleParentUndoUnit);\n    HRESULT Close(IOleParentUndoUnit, BOOL);\n    HRESULT Add(IOleUndoUnit);\n    HRESULT GetOpenParentState(DWORD*);\n    HRESULT DiscardFrom(IOleUndoUnit);\n    HRESULT UndoTo(IOleUndoUnit);\n    HRESULT RedoTo(IOleUndoUnit);\n    HRESULT EnumUndoable(IEnumOleUndoUnits*);\n    HRESULT EnumRedoable(IEnumOleUndoUnits*);\n    HRESULT GetLastUndoDescription(BSTR*);\n    HRESULT GetLastRedoDescription(BSTR*);\n    HRESULT Enable(BOOL);\n}\nalias IOleUndoManager LPOLEUNDOMANAGER;\n\ninterface IQuickActivate : IUnknown {\n    HRESULT QuickActivate(QACONTAINER*, QACONTROL*);\n    HRESULT SetContentExtent(LPSIZEL);\n    HRESULT GetContentExtent(LPSIZEL);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/odbcinst.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_odbcinst.d)\n */\nmodule core.sys.windows.odbcinst;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nimport core.sys.windows.sql;\nprivate import core.sys.windows.windef;\n\n/*  FIXME: The Unicode/Ansi functions situation is a mess. How do the xxxA\n *  versions of these functions fit into the scheme?\n */\n\n// SQLConfigDataSource()\nenum : WORD {\n    ODBC_ADD_DSN            = 1,\n    ODBC_CONFIG_DSN         = 2,\n    ODBC_REMOVE_DSN         = 3,\n    ODBC_ADD_SYS_DSN        = 4,\n    ODBC_CONFIG_SYS_DSN     = 5,\n    ODBC_REMOVE_SYS_DSN     = 6,\n    ODBC_REMOVE_DEFAULT_DSN = 7\n}\n\n// ODBC 3.0+\nenum : WORD {\n    ODBC_INSTALL_INQUIRY  = 1,\n    ODBC_INSTALL_COMPLETE = 2\n}\n\n// ODBC 2.5+\nenum : WORD {\n    ODBC_INSTALL_DRIVER    = 1,\n    ODBC_REMOVE_DRIVER     = 2,\n    ODBC_CONFIG_DRIVER     = 3,\n    ODBC_CONFIG_DRIVER_MAX = 100\n}\n\n// ODBC 3.0+\n// SQLSetConfigMode()\nenum : UWORD {\n    ODBC_BOTH_DSN   = 0,\n    ODBC_USER_DSN   = 1,\n    ODBC_SYSTEM_DSN = 2\n}\n\nenum : DWORD {\n    ODBC_ERROR_GENERAL_ERR             = 1,\n    ODBC_ERROR_INVALID_BUFF_LEN        = 2,\n    ODBC_ERROR_INVALID_HWND            = 3,\n    ODBC_ERROR_INVALID_STR             = 4,\n    ODBC_ERROR_INVALID_REQUEST_TYPE    = 5,\n    ODBC_ERROR_COMPONENT_NOT_FOUND     = 6,\n    ODBC_ERROR_INVALID_NAME            = 7,\n    ODBC_ERROR_INVALID_KEYWORD_VALUE   = 8,\n    ODBC_ERROR_INVALID_DSN             = 9,\n    ODBC_ERROR_INVALID_INF             = 10,\n    ODBC_ERROR_REQUEST_FAILED          = 11,\n    ODBC_ERROR_INVALID_PATH            = 12,\n    ODBC_ERROR_LOAD_LIB_FAILED         = 13,\n    ODBC_ERROR_INVALID_PARAM_SEQUENCE  = 14,\n    ODBC_ERROR_INVALID_LOG_FILE        = 15,\n    ODBC_ERROR_USER_CANCELED           = 16,\n    ODBC_ERROR_USAGE_UPDATE_FAILED     = 17,\n    ODBC_ERROR_CREATE_DSN_FAILED       = 18,\n    ODBC_ERROR_WRITING_SYSINFO_FAILED  = 19,\n    ODBC_ERROR_REMOVE_DSN_FAILED       = 20,\n    ODBC_ERROR_OUT_OF_MEM              = 21,\n    ODBC_ERROR_OUTPUT_STRING_TRUNCATED = 22\n}\n\nextern (Windows):\nBOOL  ConfigDSN(HWND,WORD,LPCSTR,LPCSTR);\nBOOL  ConfigDSNW(HWND,WORD,LPCWSTR,LPCWSTR);\nBOOL  ConfigTranslator(HWND,DWORD*);\nBOOL  SQLConfigDataSource(HWND,WORD,LPCSTR,LPCSTR);\nBOOL  SQLConfigDataSourceW(HWND,WORD,LPCWSTR,LPCWSTR);\nBOOL  SQLCreateDataSource(HWND,LPCSTR);\nBOOL  SQLCreateDataSourceW(HWND,LPCWSTR);\nBOOL  SQLGetAvailableDrivers(LPCSTR,LPSTR,WORD,WORD*);\nBOOL  SQLGetAvailableDriversW(LPCWSTR,LPWSTR,WORD,WORD*);\nBOOL  SQLGetInstalledDrivers(LPSTR,WORD,WORD*);\nBOOL  SQLGetInstalledDriversW(LPWSTR,WORD,WORD*);\nint  SQLGetPrivateProfileString(LPCSTR,LPCSTR,LPCSTR,LPSTR,int,LPCSTR);\nint  SQLGetPrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,int,LPCWSTR);\nBOOL  SQLGetTranslator(HWND,LPSTR,WORD,WORD*,LPSTR,WORD,WORD*,DWORD*);\nBOOL  SQLGetTranslatorW(HWND,LPWSTR,WORD,WORD*,LPWSTR,WORD,WORD*,DWORD*);\nBOOL  SQLInstallDriver(LPCSTR,LPCSTR,LPSTR,WORD,WORD*);\nBOOL  SQLInstallDriverManager(LPSTR,WORD,WORD*);\nBOOL  SQLInstallDriverManagerW(LPWSTR,WORD,WORD*);\nBOOL  SQLInstallDriverW(LPCWSTR,LPCWSTR,LPWSTR,WORD,WORD*);\nBOOL  SQLInstallODBC(HWND,LPCSTR,LPCSTR,LPCSTR);\nBOOL  SQLInstallODBCW(HWND,LPCWSTR,LPCWSTR,LPCWSTR);\nBOOL  SQLManageDataSources(HWND);\nBOOL  SQLRemoveDefaultDataSource();\nBOOL  SQLRemoveDSNFromIni(LPCSTR);\nBOOL  SQLRemoveDSNFromIniW(LPCWSTR);\nBOOL  SQLValidDSN(LPCSTR);\nBOOL  SQLValidDSNW(LPCWSTR);\nBOOL  SQLWriteDSNToIni(LPCSTR,LPCSTR);\nBOOL  SQLWriteDSNToIniW(LPCWSTR,LPCWSTR);\nBOOL  SQLWritePrivateProfileString(LPCSTR,LPCSTR,LPCSTR,LPCSTR);\nBOOL  SQLWritePrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR);\n\nstatic if (ODBCVER >= 0x0250) {\n    BOOL  ConfigDriver(HWND,WORD,LPCSTR,LPCSTR,LPSTR,WORD,WORD*);\n    BOOL  ConfigDriverW(HWND,WORD,LPCWSTR,LPCWSTR,LPWSTR,WORD,WORD*);\n    BOOL  SQLConfigDriver(HWND,WORD,LPCSTR,LPCSTR,LPSTR,WORD,WORD*);\n    BOOL  SQLConfigDriverW(HWND,WORD,LPCWSTR,LPCWSTR,LPWSTR,WORD,WORD*);\n    deprecated (\"Use SQLInstallTranslatorExW instead\") {\n        BOOL  SQLInstallTranslator(LPCSTR,LPCSTR,LPCSTR,LPSTR,WORD,WORD*,WORD,LPDWORD);\n        BOOL  SQLInstallTranslatorW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,WORD,WORD*,WORD,LPDWORD);\n    }\n    BOOL  SQLRemoveDriver(LPCSTR,BOOL,LPDWORD);\n    BOOL  SQLRemoveDriverManager(LPDWORD);\n    BOOL  SQLRemoveDriverW(LPCWSTR,BOOL,LPDWORD);\n    BOOL  SQLRemoveTranslator(LPCSTR,LPDWORD);\n    BOOL  SQLRemoveTranslatorW(LPCWSTR,LPDWORD);\n}\nstatic if (ODBCVER >= 0x0300) {\n    BOOL  SQLGetConfigMode(UWORD*);\n    BOOL  SQLInstallDriverEx(LPCSTR,LPCSTR,LPSTR,WORD,WORD*,WORD,LPDWORD);\n    BOOL  SQLInstallDriverExW(LPCWSTR,LPCWSTR,LPWSTR,WORD,WORD*,WORD,LPDWORD);\n    SQLRETURN  SQLInstallerError(WORD,DWORD*,LPSTR,WORD,WORD*);\n    SQLRETURN  SQLInstallerErrorW(WORD,DWORD*,LPWSTR,WORD,WORD*);\n    BOOL  SQLInstallTranslatorEx(LPCSTR,LPCSTR,LPSTR,WORD,WORD*,WORD,LPDWORD);\n    BOOL  SQLInstallTranslatorExW(LPCWSTR,LPCWSTR,LPWSTR,WORD,WORD*,WORD,LPDWORD);\n    SQLRETURN  SQLPostInstallerError(DWORD,LPCSTR);\n    SQLRETURN  SQLPostInstallerErrorW(DWORD,LPCWSTR);\n    BOOL  SQLReadFileDSN(LPCSTR,LPCSTR,LPCSTR,LPSTR,WORD,WORD*);\n    BOOL  SQLReadFileDSNW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,WORD,WORD*);\n    BOOL  SQLSetConfigMode(UWORD);\n    BOOL  SQLWriteFileDSN(LPCSTR,LPCSTR,LPCSTR,LPCSTR);\n    BOOL  SQLWriteFileDSNW(LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR);\n}\n\nversion (Unicode) {\n    alias SQLConfigDataSourceW SQLConfigDataSource;\n    alias SQLConfigDriverW SQLConfigDriver;\n    alias SQLCreateDataSourceW SQLCreateDataSource;\n    alias SQLGetAvailableDriversW SQLGetAvailableDrivers;\n    alias SQLGetInstalledDriversW SQLGetInstalledDrivers;\n    alias SQLGetPrivateProfileStringW SQLGetPrivateProfileString;\n    alias SQLGetTranslatorW SQLGetTranslator;\n    alias SQLInstallDriverW SQLInstallDriver;\n    alias SQLInstallDriverExW SQLInstallDriverEx;\n    alias SQLInstallDriverManagerW SQLInstallDriverManager;\n    alias SQLInstallerErrorW SQLInstallerError;\n    alias SQLInstallODBCW SQLInstallODBC;\n    deprecated alias SQLInstallTranslatorW SQLInstallTranslator;\n    alias SQLInstallTranslatorExW SQLInstallTranslatorEx;\n    alias SQLPostInstallerErrorW SQLPostInstallerError;\n    alias SQLReadFileDSNW SQLReadFileDSN;\n    alias SQLRemoveDriverW SQLRemoveDriver;\n    alias SQLRemoveDSNFromIniW SQLRemoveDSNFromIni;\n    alias SQLRemoveTranslatorW SQLRemoveTranslator;\n    alias SQLValidDSNW SQLValidDSN;\n    alias SQLWriteDSNToIniW SQLWriteDSNToIni;\n    alias SQLWriteFileDSNW SQLWriteFileDSN;\n    alias SQLWritePrivateProfileStringW SQLWritePrivateProfileString;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ole.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ole.d)\n */\nmodule core.sys.windows.ole;\nversion (Windows):\npragma(lib, \"ole32\");\n\nprivate import core.sys.windows.windef, core.sys.windows.wingdi, core.sys.windows.uuid;\n\nalias LPCSTR OLE_LPCSTR;\n\n/+#define LRESULT LONG\n#define HGLOBAL HANDLE+/\n\nenum {\n    OT_LINK = 1,\n    OT_EMBEDDED,\n    OT_STATIC\n}\n\nenum OLEVERB_PRIMARY = 0;\nenum OF_SET          = 1;\nenum OF_GET          = 2;\nenum OF_HANDLER      = 4;\n\nstruct OLETARGETDEVICE {\n    USHORT otdDeviceNameOffset;\n    USHORT otdDriverNameOffset;\n    USHORT otdPortNameOffset;\n    USHORT otdExtDevmodeOffset;\n    USHORT otdExtDevmodeSize;\n    USHORT otdEnvironmentOffset;\n    USHORT otdEnvironmentSize;\n    BYTE   _otdData;\n    BYTE*  otdData() return { return &_otdData; }\n}\nalias OLETARGETDEVICE* LPOLETARGETDEVICE;\n\nenum OLESTATUS {\n    OLE_OK,\n    OLE_WAIT_FOR_RELEASE,\n    OLE_BUSY,\n    OLE_ERROR_PROTECT_ONLY,\n    OLE_ERROR_MEMORY,\n    OLE_ERROR_STREAM,\n    OLE_ERROR_STATIC,\n    OLE_ERROR_BLANK,\n    OLE_ERROR_DRAW,\n    OLE_ERROR_METAFILE,\n    OLE_ERROR_ABORT,\n    OLE_ERROR_CLIPBOARD,\n    OLE_ERROR_FORMAT,\n    OLE_ERROR_OBJECT,\n    OLE_ERROR_OPTION,\n    OLE_ERROR_PROTOCOL,\n    OLE_ERROR_ADDRESS,\n    OLE_ERROR_NOT_EQUAL,\n    OLE_ERROR_HANDLE,\n    OLE_ERROR_GENERIC,\n    OLE_ERROR_CLASS,\n    OLE_ERROR_SYNTAX,\n    OLE_ERROR_DATATYPE,\n    OLE_ERROR_PALETTE,\n    OLE_ERROR_NOT_LINK,\n    OLE_ERROR_NOT_EMPTY,\n    OLE_ERROR_SIZE,\n    OLE_ERROR_DRIVE,\n    OLE_ERROR_NETWORK,\n    OLE_ERROR_NAME,\n    OLE_ERROR_TEMPLATE,\n    OLE_ERROR_NEW,\n    OLE_ERROR_EDIT,\n    OLE_ERROR_OPEN,\n    OLE_ERROR_NOT_OPEN,\n    OLE_ERROR_LAUNCH,\n    OLE_ERROR_COMM,\n    OLE_ERROR_TERMINATE,\n    OLE_ERROR_COMMAND,\n    OLE_ERROR_SHOW,\n    OLE_ERROR_DOVERB,\n    OLE_ERROR_ADVISE_NATIVE,\n    OLE_ERROR_ADVISE_PICT,\n    OLE_ERROR_ADVISE_RENAME,\n    OLE_ERROR_POKE_NATIVE,\n    OLE_ERROR_REQUEST_NATIVE,\n    OLE_ERROR_REQUEST_PICT,\n    OLE_ERROR_SERVER_BLOCKED,\n    OLE_ERROR_REGISTRATION,\n    OLE_ERROR_ALREADY_REGISTERED,\n    OLE_ERROR_TASK,\n    OLE_ERROR_OUTOFDATE,\n    OLE_ERROR_CANT_UPDATE_CLIENT,\n    OLE_ERROR_UPDATE,\n    OLE_ERROR_SETDATA_FORMAT,\n    OLE_ERROR_STATIC_FROM_OTHER_OS,\n    OLE_ERROR_FILE_VER,\n    OLE_WARN_DELETE_DATA = 1000\n}\n\nenum OLE_NOTIFICATION {\n    OLE_CHANGED,\n    OLE_SAVED,\n    OLE_CLOSED,\n    OLE_RENAMED,\n    OLE_QUERY_PAINT,\n    OLE_RELEASE,\n    OLE_QUERY_RETRY\n}\n\nenum OLE_RELEASE_METHOD {\n    OLE_NONE,\n    OLE_DELETE,\n    OLE_LNKPASTE,\n    OLE_EMBPASTE,\n    OLE_SHOW,\n    OLE_RUN,\n    OLE_ACTIVATE,\n    OLE_UPDATE,\n    OLE_CLOSE,\n    OLE_RECONNECT,\n    OLE_SETUPDATEOPTIONS,\n    OLE_SERVERUNLAUNCH,\n    OLE_LOADFROMSTREAM,\n    OLE_SETDATA,\n    OLE_REQUESTDATA,\n    OLE_OTHER,\n    OLE_CREATE,\n    OLE_CREATEFROMTEMPLATE,\n    OLE_CREATELINKFROMFILE,\n    OLE_COPYFROMLNK,\n    OLE_CREATEFROMFILE,\n    OLE_CREATEINVISIBLE\n}\n\nenum OLEOPT_RENDER {\n    olerender_none,\n    olerender_draw,\n    olerender_format\n}\n\nalias WORD OLECLIPFORMAT;\n\nenum OLEOPT_UPDATE {\n    oleupdate_always,\n    oleupdate_onsave,\n    oleupdate_oncall,\n// #ifdef OLE_INTERNAL\n    oleupdate_onclose\n// #endif\n}\n\nmixin DECLARE_HANDLE!(\"HOBJECT\");\nalias LONG_PTR LHSERVER, LHCLIENTDOC, LHSERVERDOC;\n\nstruct OLEOBJECTVTBL {\n    extern (Windows) {\n        void* function(LPOLEOBJECT, OLE_LPCSTR) QueryProtocol;\n        OLESTATUS function(LPOLEOBJECT) Release;\n        OLESTATUS function(LPOLEOBJECT, BOOL) Show;\n        OLESTATUS function(LPOLEOBJECT, UINT, BOOL, BOOL) DoVerb;\n        OLESTATUS function(LPOLEOBJECT, OLECLIPFORMAT, HANDLE*) GetData;\n        OLESTATUS function(LPOLEOBJECT, OLECLIPFORMAT, HANDLE) SetData;\n        OLESTATUS function(LPOLEOBJECT, HGLOBAL) SetTargetDevice;\n        OLESTATUS function(LPOLEOBJECT, RECT*) SetBounds;\n        OLECLIPFORMAT function(LPOLEOBJECT, OLECLIPFORMAT) EnumFormats;\n        OLESTATUS function(LPOLEOBJECT, LOGPALETTE*) SetColorScheme;\n//#ifndef SERVERONLY\n        OLESTATUS function(LPOLEOBJECT) Delete;\n        OLESTATUS function(LPOLEOBJECT, OLE_LPCSTR, OLE_LPCSTR) SetHostNames;\n        OLESTATUS function(LPOLEOBJECT, LPOLESTREAM) SaveToStream;\n        OLESTATUS function(LPOLEOBJECT, LPOLECLIENT, LHCLIENTDOC, OLE_LPCSTR,\n          LPOLEOBJECT*) Clone;\n        OLESTATUS function(LPOLEOBJECT, LPOLECLIENT, LHCLIENTDOC, OLE_LPCSTR,\n          LPOLEOBJECT*) CopyFromLink;\n        OLESTATUS function(LPOLEOBJECT, LPOLEOBJECT) Equal;\n        OLESTATUS function(LPOLEOBJECT) CopyToClipboard;\n        OLESTATUS function(LPOLEOBJECT, HDC, RECT*, RECT*, HDC) Draw;\n        OLESTATUS function(LPOLEOBJECT, UINT, BOOL, BOOL, HWND, RECT*)\n          Activate;\n        OLESTATUS function(LPOLEOBJECT, HGLOBAL, UINT) Execute;\n        OLESTATUS function(LPOLEOBJECT) Close;\n        OLESTATUS function(LPOLEOBJECT) Update;\n        OLESTATUS function(LPOLEOBJECT) Reconnect;\n        OLESTATUS function(LPOLEOBJECT, OLE_LPCSTR, LPOLECLIENT, LHCLIENTDOC,\n          OLE_LPCSTR, LPOLEOBJECT*) ObjectConvert;\n        OLESTATUS function(LPOLEOBJECT, OLEOPT_UPDATE*) GetLinkUpdateOptions;\n        OLESTATUS function(LPOLEOBJECT, OLEOPT_UPDATE) SetLinkUpdateOptions;\n        OLESTATUS function(LPOLEOBJECT, OLE_LPCSTR) Rename;\n        OLESTATUS function(LPOLEOBJECT, LPSTR, UINT*) QueryName;\n        OLESTATUS function(LPOLEOBJECT, LONG*) QueryType;\n        OLESTATUS function(LPOLEOBJECT, RECT*) QueryBounds;\n        OLESTATUS function(LPOLEOBJECT, DWORD*) QuerySize;\n        OLESTATUS function(LPOLEOBJECT) QueryOpen;\n        OLESTATUS function(LPOLEOBJECT) QueryOutOfDate;\n        OLESTATUS function(LPOLEOBJECT) QueryReleaseStatus;\n        OLESTATUS function(LPOLEOBJECT) QueryReleaseError;\n        OLE_RELEASE_METHOD function(LPOLEOBJECT) QueryReleaseMethod;\n        OLESTATUS function(LPOLEOBJECT, OLECLIPFORMAT) RequestData;\n        OLESTATUS function(LPOLEOBJECT, UINT, LONG*) ObjectLong;\n        OLESTATUS function(LPOLEOBJECT, HANDLE, LPOLECLIENT, BOOL) ChangeData;\n//#endif\n    }\n}\nalias OLEOBJECTVTBL* LPOLEOBJECTVTBL;\n\n//#ifndef OLE_INTERNAL\nstruct OLEOBJECT {\n    LPOLEOBJECTVTBL lpvtbl;\n}\nalias OLEOBJECT* LPOLEOBJECT;\n//#endif\n\nstruct OLECLIENTVTBL {\n    extern (Windows) int function(LPOLECLIENT, OLE_NOTIFICATION, LPOLEOBJECT) CallBack;\n}\nalias OLECLIENTVTBL* LPOLECLIENTVTBL;\n\nstruct OLECLIENT {\n    LPOLECLIENTVTBL lpvtbl;\n}\nalias OLECLIENT* LPOLECLIENT;\n\nstruct OLESTREAMVTBL {\n    extern (Windows):\n    DWORD function(LPOLESTREAM, void*, DWORD) Get;\n    DWORD function(LPOLESTREAM, void*, DWORD) Put;\n}\nalias OLESTREAMVTBL* LPOLESTREAMVTBL;\n\nstruct OLESTREAM {\n    LPOLESTREAMVTBL lpstbl;\n}\nalias OLESTREAM* LPOLESTREAM;\n\nenum OLE_SERVER_USE {\n    OLE_SERVER_MULTI,\n    OLE_SERVER_SINGLE\n}\n\nstruct OLESERVERVTBL {\n    extern (Windows):\n    OLESTATUS function(LPOLESERVER, LHSERVERDOC, OLE_LPCSTR, LPOLESERVERDOC*)\n      Open;\n    OLESTATUS function(LPOLESERVER, LHSERVERDOC, OLE_LPCSTR, OLE_LPCSTR,\n      LPOLESERVERDOC*) Create;\n    OLESTATUS function(LPOLESERVER, LHSERVERDOC, OLE_LPCSTR, OLE_LPCSTR,\n      OLE_LPCSTR, LPOLESERVERDOC*) CreateFromTemplate;\n    OLESTATUS function(LPOLESERVER, LHSERVERDOC, OLE_LPCSTR, OLE_LPCSTR,\n      LPOLESERVERDOC*) Edit;\n    OLESTATUS function(LPOLESERVER) Exit;\n    OLESTATUS function(LPOLESERVER) Release;\n    OLESTATUS function(LPOLESERVER, HGLOBAL) Execute;\n}\nalias TypeDef!(OLESERVERVTBL*) LPOLESERVERVTBL;\n\nstruct OLESERVER {\n    LPOLESERVERVTBL lpvtbl;\n}\nalias OLESERVER* LPOLESERVER;\n\nstruct OLESERVERDOCVTBL {\nextern (Windows):\n    OLESTATUS function(LPOLESERVERDOC) Save;\n    OLESTATUS function(LPOLESERVERDOC) Close;\n    OLESTATUS function(LPOLESERVERDOC, OLE_LPCSTR, OLE_LPCSTR) SetHostNames;\n    OLESTATUS function(LPOLESERVERDOC, RECT*) SetDocDimensions;\n    OLESTATUS function(LPOLESERVERDOC, OLE_LPCSTR, LPOLEOBJECT*, LPOLECLIENT)\n      GetObject;\n    OLESTATUS function(LPOLESERVERDOC) Release;\n    OLESTATUS function(LPOLESERVERDOC, LOGPALETTE*) SetColorScheme;\n    OLESTATUS function(LPOLESERVERDOC, HGLOBAL) Execute;\n}\nalias OLESERVERDOCVTBL* LPOLESERVERDOCVTBL;\n\nstruct OLESERVERDOC {\n    LPOLESERVERDOCVTBL lpvtbl;\n}\nalias OLESERVERDOC* LPOLESERVERDOC;\n\nextern (Windows) {\n    OLESTATUS OleDelete(LPOLEOBJECT);\n    OLESTATUS OleRelease(LPOLEOBJECT);\n    OLESTATUS OleSaveToStream(LPOLEOBJECT, LPOLESTREAM);\n    OLESTATUS OleEqual(LPOLEOBJECT, LPOLEOBJECT);\n    OLESTATUS OleCopyToClipboard(LPOLEOBJECT);\n    OLESTATUS OleSetHostNames(LPOLEOBJECT, LPCSTR, LPCSTR);\n    OLESTATUS OleSetTargetDevice(LPOLEOBJECT, HGLOBAL);\n    OLESTATUS OleSetBounds(LPOLEOBJECT, LPCRECT);\n    OLESTATUS OleSetColorScheme(LPOLEOBJECT, const(LOGPALETTE)*);\n    OLESTATUS OleQueryBounds(LPOLEOBJECT, RECT*);\n    OLESTATUS OleQuerySize(LPOLEOBJECT, DWORD*);\n    OLESTATUS OleDraw(LPOLEOBJECT, HDC, LPCRECT, LPCRECT, HDC);\n    OLESTATUS OleQueryOpen(LPOLEOBJECT);\n    OLESTATUS OleActivate(LPOLEOBJECT, UINT, BOOL, BOOL, HWND, LPCRECT);\n    OLESTATUS OleExecute(LPOLEOBJECT, HGLOBAL, UINT);\n    OLESTATUS OleClose(LPOLEOBJECT);\n    OLESTATUS OleUpdate(LPOLEOBJECT);\n    OLESTATUS OleReconnect(LPOLEOBJECT);\n    OLESTATUS OleGetLinkUpdateOptions(LPOLEOBJECT, OLEOPT_UPDATE*);\n    OLESTATUS OleSetLinkUpdateOptions(LPOLEOBJECT, OLEOPT_UPDATE);\n    void* OleQueryProtocol(LPOLEOBJECT, LPCSTR);\n    OLESTATUS OleQueryReleaseStatus(LPOLEOBJECT);\n    OLESTATUS OleQueryReleaseError(LPOLEOBJECT);\n    OLE_RELEASE_METHOD OleQueryReleaseMethod(LPOLEOBJECT);\n    OLESTATUS OleQueryType(LPOLEOBJECT, LONG*);\n    DWORD OleQueryClientVersion();\n    DWORD OleQueryServerVersion();\n    OLECLIPFORMAT OleEnumFormats(LPOLEOBJECT, OLECLIPFORMAT);\n    OLESTATUS OleGetData(LPOLEOBJECT, OLECLIPFORMAT, HANDLE*);\n    OLESTATUS OleSetData(LPOLEOBJECT, OLECLIPFORMAT, HANDLE);\n    OLESTATUS OleQueryOutOfDate(LPOLEOBJECT);\n    OLESTATUS OleRequestData(LPOLEOBJECT, OLECLIPFORMAT);\n    OLESTATUS OleQueryLinkFromClip(LPCSTR, OLEOPT_RENDER, OLECLIPFORMAT);\n    OLESTATUS OleQueryCreateFromClip(LPCSTR, OLEOPT_RENDER, OLECLIPFORMAT);\n    OLESTATUS OleCreateFromClip(LPCSTR, LPOLECLIENT, LHCLIENTDOC, LPCSTR,\n      LPOLEOBJECT*, OLEOPT_RENDER, OLECLIPFORMAT);\n    OLESTATUS OleCreateLinkFromClip(LPCSTR, LPOLECLIENT, LHCLIENTDOC, LPCSTR,\n      LPOLEOBJECT*, OLEOPT_RENDER, OLECLIPFORMAT);\n    OLESTATUS OleCreateFromFile(LPCSTR, LPOLECLIENT, LPCSTR, LPCSTR,\n      LHCLIENTDOC, LPCSTR, LPOLEOBJECT*, OLEOPT_RENDER, OLECLIPFORMAT);\n    OLESTATUS OleCreateLinkFromFile(LPCSTR, LPOLECLIENT, LPCSTR, LPCSTR,\n      LPCSTR, LHCLIENTDOC, LPCSTR, LPOLEOBJECT*, OLEOPT_RENDER, OLECLIPFORMAT);\n    OLESTATUS OleLoadFromStream(LPOLESTREAM, LPCSTR, LPOLECLIENT, LHCLIENTDOC,\n      LPCSTR, LPOLEOBJECT*);\n    OLESTATUS OleCreate(LPCSTR, LPOLECLIENT, LPCSTR, LHCLIENTDOC, LPCSTR,\n      LPOLEOBJECT*, OLEOPT_RENDER, OLECLIPFORMAT);\n    OLESTATUS OleCreateInvisible(LPCSTR, LPOLECLIENT, LPCSTR, LHCLIENTDOC,\n      LPCSTR, LPOLEOBJECT*, OLEOPT_RENDER, OLECLIPFORMAT, BOOL);\n    OLESTATUS OleCreateFromTemplate(LPCSTR, LPOLECLIENT, LPCSTR, LHCLIENTDOC,\n      LPCSTR, LPOLEOBJECT*, OLEOPT_RENDER, OLECLIPFORMAT);\n    OLESTATUS OleClone(LPOLEOBJECT, LPOLECLIENT, LHCLIENTDOC, LPCSTR,\n      LPOLEOBJECT*);\n    OLESTATUS OleCopyFromLink(LPOLEOBJECT, LPCSTR, LPOLECLIENT, LHCLIENTDOC,\n      LPCSTR, LPOLEOBJECT*);\n    OLESTATUS OleObjectConvert(LPOLEOBJECT, LPCSTR, LPOLECLIENT, LHCLIENTDOC,\n      LPCSTR, LPOLEOBJECT*);\n    OLESTATUS OleRename(LPOLEOBJECT, LPCSTR);\n    OLESTATUS OleQueryName(LPOLEOBJECT, LPSTR, UINT*);\n    OLESTATUS OleRevokeObject(LPOLECLIENT);\n    BOOL OleIsDcMeta(HDC);\n    OLESTATUS OleRegisterClientDoc(LPCSTR, LPCSTR, LONG, LHCLIENTDOC*);\n    OLESTATUS OleRevokeClientDoc(LHCLIENTDOC);\n    OLESTATUS OleRenameClientDoc(LHCLIENTDOC, LPCSTR);\n    OLESTATUS OleRevertClientDoc(LHCLIENTDOC);\n    OLESTATUS OleSavedClientDoc(LHCLIENTDOC);\n    OLESTATUS OleEnumObjects(LHCLIENTDOC, LPOLEOBJECT*);\n    OLESTATUS OleRegisterServer(LPCSTR, LPOLESERVER, LHSERVER*, HINSTANCE,\n      OLE_SERVER_USE);\n    OLESTATUS OleRevokeServer(LHSERVER);\n    OLESTATUS OleBlockServer(LHSERVER);\n    OLESTATUS OleUnblockServer(LHSERVER, BOOL*);\n    OLESTATUS OleLockServer(LPOLEOBJECT, LHSERVER*);\n    OLESTATUS OleUnlockServer(LHSERVER);\n    OLESTATUS OleRegisterServerDoc(LHSERVER, LPCSTR, LPOLESERVERDOC,\n      LHSERVERDOC*);\n    OLESTATUS OleRevokeServerDoc(LHSERVERDOC);\n    OLESTATUS OleRenameServerDoc(LHSERVERDOC, LPCSTR);\n    OLESTATUS OleRevertServerDoc(LHSERVERDOC);\n    OLESTATUS OleSavedServerDoc(LHSERVERDOC);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ole2.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ole2.d)\n */\nmodule core.sys.windows.ole2;\nversion (Windows):\npragma(lib, \"ole32\");\n\npublic import core.sys.windows.basetyps, core.sys.windows.objbase, core.sys.windows.oleauto, core.sys.windows.olectlid,\n  core.sys.windows.oleidl, core.sys.windows.unknwn, core.sys.windows.winerror, core.sys.windows.uuid;\nprivate import core.sys.windows.objfwd, core.sys.windows.objidl, core.sys.windows.windef, core.sys.windows.wtypes;\nprivate import core.sys.windows.winuser; // for LPMSG\n\nenum E_DRAW = VIEW_E_DRAW;\n\nenum DATA_E_FORMATETC = DV_E_FORMATETC;\n\nenum {\n    OLEIVERB_PRIMARY = 0,\n    OLEIVERB_SHOW = -1,\n    OLEIVERB_OPEN = -2,\n    OLEIVERB_HIDE = -3,\n    OLEIVERB_UIACTIVATE = -4,\n    OLEIVERB_INPLACEACTIVATE = -5,\n    OLEIVERB_DISCARDUNDOSTATE = -6\n}\n\nenum EMBDHLP_INPROC_HANDLER = 0x0000L;\nenum EMBDHLP_INPROC_SERVER  = 0x0001L;\nenum EMBDHLP_CREATENOW      = 0x00000000L;\nenum EMBDHLP_DELAYCREATE    = 0x00010000L;\n\nalign(8):\nstruct OLESTREAM {\n    LPOLESTREAMVTBL lpstbl;\n}\nalias OLESTREAM* LPOLESTREAM;\n\nextern (Windows) {\n    struct OLESTREAMVTBL {\n        DWORD function (LPOLESTREAM, void*, DWORD) Get;\n        DWORD function (LPOLESTREAM, const(void)*, DWORD) Put;\n    }\n}\nalias OLESTREAMVTBL* LPOLESTREAMVTBL;\n\nextern (Windows) {\n    HRESULT CreateDataAdviseHolder(LPDATAADVISEHOLDER*);\n    DWORD OleBuildVersion();\n    HRESULT ReadClassStg(LPSTORAGE, CLSID*);\n    HRESULT WriteClassStg(LPSTORAGE, REFCLSID);\n    HRESULT ReadClassStm(LPSTREAM, CLSID*);\n    HRESULT WriteClassStm(LPSTREAM, REFCLSID);\n    HRESULT WriteFmtUserTypeStg(LPSTORAGE, CLIPFORMAT, LPOLESTR);\n    HRESULT ReadFmtUserTypeStg(LPSTORAGE, CLIPFORMAT*, LPOLESTR*);\n    HRESULT OleInitialize(PVOID);\n    void OleUninitialize();\n    HRESULT OleQueryLinkFromData(LPDATAOBJECT);\n    HRESULT OleQueryCreateFromData(LPDATAOBJECT);\n    HRESULT OleCreate(REFCLSID, REFIID, DWORD, LPFORMATETC, LPOLECLIENTSITE, LPSTORAGE, PVOID*);\n    HRESULT OleCreateFromData(LPDATAOBJECT, REFIID, DWORD, LPFORMATETC, LPOLECLIENTSITE, LPSTORAGE, PVOID*);\n    HRESULT OleCreateLinkFromData(LPDATAOBJECT, REFIID, DWORD, LPFORMATETC, LPOLECLIENTSITE, LPSTORAGE, PVOID*);\n    HRESULT OleCreateStaticFromData(LPDATAOBJECT, REFIID, DWORD, LPFORMATETC, LPOLECLIENTSITE, LPSTORAGE, PVOID*);\n    HRESULT OleCreateLink(LPMONIKER, REFIID, DWORD, LPFORMATETC, LPOLECLIENTSITE, LPSTORAGE, PVOID*);\n    HRESULT OleCreateLinkToFile(LPCOLESTR, REFIID, DWORD, LPFORMATETC, LPOLECLIENTSITE, LPSTORAGE, PVOID*);\n    HRESULT OleCreateFromFile(REFCLSID, LPCOLESTR, REFIID, DWORD, LPFORMATETC, LPOLECLIENTSITE, LPSTORAGE, PVOID*);\n    HRESULT OleLoad(LPSTORAGE, REFIID, LPOLECLIENTSITE, PVOID*);\n    HRESULT OleSave(LPPERSISTSTORAGE, LPSTORAGE, BOOL);\n    HRESULT OleLoadFromStream(LPSTREAM, REFIID, PVOID*);\n    HRESULT OleSaveToStream(LPPERSISTSTREAM, LPSTREAM);\n    HRESULT OleSetContainedObject(LPUNKNOWN, BOOL);\n    HRESULT OleNoteObjectVisible(LPUNKNOWN, BOOL);\n    HRESULT RegisterDragDrop(HWND, LPDROPTARGET);\n    HRESULT RevokeDragDrop(HWND);\n    HRESULT DoDragDrop(LPDATAOBJECT, LPDROPSOURCE, DWORD, PDWORD);\n    HRESULT OleSetClipboard(LPDATAOBJECT);\n    HRESULT OleGetClipboard(LPDATAOBJECT*);\n    HRESULT OleFlushClipboard();\n    HRESULT OleIsCurrentClipboard(LPDATAOBJECT);\n    HOLEMENU OleCreateMenuDescriptor(HMENU, LPOLEMENUGROUPWIDTHS);\n    HRESULT OleSetMenuDescriptor(HOLEMENU, HWND, HWND, LPOLEINPLACEFRAME, LPOLEINPLACEACTIVEOBJECT);\n    HRESULT OleDestroyMenuDescriptor(HOLEMENU);\n    HRESULT OleTranslateAccelerator(LPOLEINPLACEFRAME, LPOLEINPLACEFRAMEINFO, LPMSG);\n    HANDLE OleDuplicateData(HANDLE, CLIPFORMAT, UINT);\n    HRESULT OleDraw(LPUNKNOWN, DWORD, HDC, LPCRECT);\n    HRESULT OleRun(LPUNKNOWN);\n    BOOL OleIsRunning(LPOLEOBJECT);\n    HRESULT OleLockRunning(LPUNKNOWN, BOOL, BOOL);\n    void ReleaseStgMedium(LPSTGMEDIUM);\n    HRESULT CreateOleAdviseHolder(LPOLEADVISEHOLDER*);\n    HRESULT OleCreateDefaultHandler(REFCLSID, LPUNKNOWN, REFIID, PVOID*);\n    HRESULT OleCreateEmbeddingHelper(REFCLSID, LPUNKNOWN, DWORD, LPCLASSFACTORY, REFIID, PVOID*);\n    BOOL IsAccelerator(HACCEL, int, LPMSG, WORD*);\n    HGLOBAL OleGetIconOfFile(LPOLESTR, BOOL);\n    HGLOBAL OleGetIconOfClass(REFCLSID, LPOLESTR, BOOL);\n    HGLOBAL OleMetafilePictFromIconAndLabel(HICON, LPOLESTR, LPOLESTR, UINT);\n    HRESULT OleRegGetUserType(REFCLSID, DWORD, LPOLESTR*);\n    HRESULT OleRegGetMiscStatus(REFCLSID, DWORD, DWORD*);\n    HRESULT OleRegEnumFormatEtc (REFCLSID, DWORD, LPENUMFORMATETC*);\n    HRESULT OleRegEnumVerbs (REFCLSID, LPENUMOLEVERB*);\n    HRESULT OleConvertOLESTREAMToIStorage(LPOLESTREAM, LPSTORAGE, const(DVTARGETDEVICE)*);\n    HRESULT OleConvertIStorageToOLESTREAM(LPSTORAGE, LPOLESTREAM);\n    HRESULT GetHGlobalFromILockBytes(LPLOCKBYTES, HGLOBAL*);\n    HRESULT CreateILockBytesOnHGlobal(HGLOBAL, BOOL, LPLOCKBYTES*);\n    HRESULT GetHGlobalFromStream(LPSTREAM, HGLOBAL*);\n    HRESULT CreateStreamOnHGlobal(HGLOBAL, BOOL, LPSTREAM*);\n    HRESULT OleDoAutoConvert(LPSTORAGE, LPCLSID);\n    HRESULT OleGetAutoConvert(REFCLSID, LPCLSID);\n    HRESULT OleSetAutoConvert(REFCLSID, REFCLSID);\n    HRESULT GetConvertStg(LPSTORAGE);\n    HRESULT SetConvertStg(LPSTORAGE, BOOL);\n    HRESULT OleConvertIStorageToOLESTREAMEx(LPSTORAGE, CLIPFORMAT, LONG, LONG, DWORD, LPSTGMEDIUM, LPOLESTREAM);\n    HRESULT OleConvertOLESTREAMToIStorageEx(LPOLESTREAM, LPSTORAGE, CLIPFORMAT*, LONG*, LONG*, DWORD*, LPSTGMEDIUM);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ole2ver.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.10\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ole2ver.d)\n */\nmodule core.sys.windows.ole2ver;\nversion (Windows):\n\n// These are apparently not documented on the MSDN site\nenum rmm = 23;\nenum rup = 639;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/oleacc.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_oleacc.d)\n */\nmodule core.sys.windows.oleacc;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"oleacc\");\n\nprivate import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.unknwn, core.sys.windows.wtypes,\n  core.sys.windows.windef;\n\nenum {\n    DISPID_ACC_PARENT           = -5000,\n    DISPID_ACC_CHILDCOUNT       = -5001,\n    DISPID_ACC_CHILD            = -5002,\n    DISPID_ACC_NAME             = -5003,\n    DISPID_ACC_VALUE            = -5004,\n    DISPID_ACC_DESCRIPTION      = -5005,\n    DISPID_ACC_ROLE             = -5006,\n    DISPID_ACC_STATE            = -5007,\n    DISPID_ACC_HELP             = -5008,\n    DISPID_ACC_HELPTOPIC        = -5009,\n    DISPID_ACC_KEYBOARDSHORTCUT = -5010,\n    DISPID_ACC_FOCUS            = -5011,\n    DISPID_ACC_SELECTION        = -5012,\n    DISPID_ACC_DEFAULTACTION    = -5013,\n    DISPID_ACC_SELECT           = -5014,\n    DISPID_ACC_LOCATION         = -5015,\n    DISPID_ACC_NAVIGATE         = -5016,\n    DISPID_ACC_HITTEST          = -5017,\n    DISPID_ACC_DODEFAULTACTION  = -5018\n}\n\nenum {\n    NAVDIR_UP = 1,\n    NAVDIR_DOWN,\n    NAVDIR_LEFT,\n    NAVDIR_RIGHT,\n    NAVDIR_NEXT,\n    NAVDIR_PREVIOUS,\n    NAVDIR_FIRSTCHILD,\n    NAVDIR_LASTCHILD // = 8\n}\n\nenum {\n    ROLE_SYSTEM_TITLEBAR = 1,\n    ROLE_SYSTEM_MENUBAR,\n    ROLE_SYSTEM_SCROLLBAR,\n    ROLE_SYSTEM_GRIP,\n    ROLE_SYSTEM_SOUND,\n    ROLE_SYSTEM_CURSOR,\n    ROLE_SYSTEM_CARET,\n    ROLE_SYSTEM_ALERT,\n    ROLE_SYSTEM_WINDOW,\n    ROLE_SYSTEM_CLIENT,\n    ROLE_SYSTEM_MENUPOPUP,\n    ROLE_SYSTEM_MENUITEM,\n    ROLE_SYSTEM_TOOLTIP,\n    ROLE_SYSTEM_APPLICATION,\n    ROLE_SYSTEM_DOCUMENT,\n    ROLE_SYSTEM_PANE,\n    ROLE_SYSTEM_CHART,\n    ROLE_SYSTEM_DIALOG,\n    ROLE_SYSTEM_BORDER,\n    ROLE_SYSTEM_GROUPING,\n    ROLE_SYSTEM_SEPARATOR,\n    ROLE_SYSTEM_TOOLBAR,\n    ROLE_SYSTEM_STATUSBAR,\n    ROLE_SYSTEM_TABLE,\n    ROLE_SYSTEM_COLUMNHEADER,\n    ROLE_SYSTEM_ROWHEADER,\n    ROLE_SYSTEM_COLUMN,\n    ROLE_SYSTEM_ROW,\n    ROLE_SYSTEM_CELL,\n    ROLE_SYSTEM_LINK,\n    ROLE_SYSTEM_HELPBALLOON,\n    ROLE_SYSTEM_CHARACTER,\n    ROLE_SYSTEM_LIST,\n    ROLE_SYSTEM_LISTITEM,\n    ROLE_SYSTEM_OUTLINE,\n    ROLE_SYSTEM_OUTLINEITEM,\n    ROLE_SYSTEM_PAGETAB,\n    ROLE_SYSTEM_PROPERTYPAGE,\n    ROLE_SYSTEM_INDICATOR,\n    ROLE_SYSTEM_GRAPHIC,\n    ROLE_SYSTEM_STATICTEXT,\n    ROLE_SYSTEM_TEXT,\n    ROLE_SYSTEM_PUSHBUTTON,\n    ROLE_SYSTEM_CHECKBUTTON,\n    ROLE_SYSTEM_RADIOBUTTON,\n    ROLE_SYSTEM_COMBOBOX,\n    ROLE_SYSTEM_DROPLIST,\n    ROLE_SYSTEM_PROGRESSBAR,\n    ROLE_SYSTEM_DIAL,\n    ROLE_SYSTEM_HOTKEYFIELD,\n    ROLE_SYSTEM_SLIDER,\n    ROLE_SYSTEM_SPINBUTTON,\n    ROLE_SYSTEM_DIAGRAM,\n    ROLE_SYSTEM_ANIMATION,\n    ROLE_SYSTEM_EQUATION,\n    ROLE_SYSTEM_BUTTONDROPDOWN,\n    ROLE_SYSTEM_BUTTONMENU,\n    ROLE_SYSTEM_BUTTONDROPDOWNGRID,\n    ROLE_SYSTEM_WHITESPACE,\n    ROLE_SYSTEM_PAGETABLIST,\n    ROLE_SYSTEM_CLOCK // = 61\n}\n\nenum {\n    STATE_SYSTEM_UNAVAILABLE     = 0x00000001,\n    STATE_SYSTEM_SELECTED        = 0x00000002,\n    STATE_SYSTEM_FOCUSED         = 0x00000004,\n    STATE_SYSTEM_PRESSED         = 0x00000008,\n    STATE_SYSTEM_CHECKED         = 0x00000010,\n    STATE_SYSTEM_MIXED           = 0x00000020,\n    STATE_SYSTEM_READONLY        = 0x00000040,\n    STATE_SYSTEM_HOTTRACKED      = 0x00000080,\n    STATE_SYSTEM_DEFAULT         = 0x00000100,\n    STATE_SYSTEM_EXPANDED        = 0x00000200,\n    STATE_SYSTEM_COLLAPSED       = 0x00000400,\n    STATE_SYSTEM_BUSY            = 0x00000800,\n    STATE_SYSTEM_FLOATING        = 0x00001000,\n    STATE_SYSTEM_MARQUEED        = 0x00002000,\n    STATE_SYSTEM_ANIMATED        = 0x00004000,\n    STATE_SYSTEM_INVISIBLE       = 0x00008000,\n    STATE_SYSTEM_OFFSCREEN       = 0x00010000,\n    STATE_SYSTEM_SIZEABLE        = 0x00020000,\n    STATE_SYSTEM_MOVEABLE        = 0x00040000,\n    STATE_SYSTEM_SELFVOICING     = 0x00080000,\n    STATE_SYSTEM_FOCUSABLE       = 0x00100000,\n    STATE_SYSTEM_SELECTABLE      = 0x00200000,\n    STATE_SYSTEM_LINKED          = 0x00400000,\n    STATE_SYSTEM_TRAVERSED       = 0x00800000,\n    STATE_SYSTEM_MULTISELECTABLE = 0x01000000,\n    STATE_SYSTEM_EXTSELECTABLE   = 0x02000000,\n    STATE_SYSTEM_ALERT_LOW       = 0x04000000,\n    STATE_SYSTEM_ALERT_MEDIUM    = 0x08000000,\n    STATE_SYSTEM_ALERT_HIGH      = 0x10000000,\n    STATE_SYSTEM_VALID           = 0x1fffffff\n}\n\nenum SELFLAG\n{\n    SELFLAG_NONE            = 0,\n    SELFLAG_TAKEFOCUS       = 1,\n    SELFLAG_TAKESELECTION   = 2,\n    SELFLAG_EXTENDSELECTION = 4,\n    SELFLAG_ADDSELECTION    = 8,\n    SELFLAG_REMOVESELECTION = 16\n}\n\nenum SELFLAG_VALID = 0x0000001F;\n\n\ninterface IAccessible : IDispatch {\n    HRESULT get_accParent(IDispatch*);\n    HRESULT get_accChildCount(int*);\n    HRESULT get_accChild(VARIANT, IDispatch*);\n    HRESULT get_accName(VARIANT, BSTR*);\n    HRESULT get_accValue(VARIANT, BSTR*);\n    HRESULT get_accDescription(VARIANT, BSTR*);\n    HRESULT get_accRole(VARIANT, VARIANT*);\n    HRESULT get_accState(VARIANT, VARIANT*);\n    HRESULT get_accHelp(VARIANT, BSTR*);\n    HRESULT get_accHelpTopic(BSTR*, VARIANT, int*);\n    HRESULT get_accKeyboardShortcut(VARIANT, BSTR*);\n    HRESULT get_accFocus(VARIANT*);\n    HRESULT get_accSelection(VARIANT*);\n    HRESULT get_accDefaultAction(VARIANT, BSTR*);\n\n    HRESULT accSelect(int, VARIANT);\n    HRESULT accLocation(int*, int*, int*, int*, VARIANT);\n    HRESULT accNavigate(int, VARIANT, VARIANT*);\n    HRESULT accHitTest(int, int, VARIANT*);\n    HRESULT accDoDefaultAction(VARIANT);\n\n    HRESULT put_accName(VARIANT, BSTR);\n    HRESULT put_accValue(VARIANT, BSTR);\n}\n\nalias IAccessible LPACCESSIBLE;\n\nextern (Windows) {\n    HRESULT AccessibleChildren(IAccessible, LONG, LONG, VARIANT*, LONG*);\n    HRESULT AccessibleObjectFromEvent(HWND, DWORD, DWORD, IAccessible, VARIANT*);\n    HRESULT AccessibleObjectFromPoint(POINT, IAccessible*, VARIANT*);\n    HRESULT AccessibleObjectFromWindow(HWND, DWORD, REFIID, void**);\n    HRESULT CreateStdAccessibleObject(HWND, LONG, REFIID, void**);\n    HRESULT CreateStdAccessibleProxyA(HWND, LPCSTR, LONG, REFIID, void**);\n    HRESULT CreateStdAccessibleProxyW(HWND, LPCWSTR, LONG, REFIID, void**);\n\n    void GetOleaccVersionInfo(DWORD*, DWORD*);\n    UINT GetRoleTextA(DWORD, LPSTR, UINT);\n    UINT GetRoleTextW(DWORD, LPWSTR, UINT);\n    UINT GetStateTextA(DWORD, LPSTR, UINT);\n    UINT GetStateTextW(DWORD, LPWSTR, UINT);\n    LRESULT LresultFromObject(REFIID, WPARAM, LPUNKNOWN);\n    HRESULT ObjectFromLresult(LRESULT, REFIID, WPARAM, void**);\n    HRESULT WindowFromAccessibleObject(IAccessible, HWND*);\n}\n\nversion (Unicode) {\n    alias CreateStdAccessibleProxyW CreateStdAccessibleProxy;\n    alias GetRoleTextW GetRoleText;\n    alias GetStateTextW GetStateText;\n} else {\n    alias CreateStdAccessibleProxyA CreateStdAccessibleProxy;\n    alias GetRoleTextA GetRoleText;\n    alias GetStateTextA GetStateText;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/oleauto.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_oleauto.d)\n */\nmodule core.sys.windows.oleauto;\nversion (Windows):\npragma(lib, \"oleaut32\");\n\nimport core.sys.windows.oaidl;\nprivate import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;\nprivate import core.sys.windows.winbase; // for SYSTEMTIME\n\nalign(8):\nenum STDOLE_MAJORVERNUM = 1;\nenum STDOLE_MINORVERNUM = 0;\nenum STDOLE_LCID = 0;\n\nenum VARIANT_NOVALUEPROP = 0x01;\nenum VARIANT_ALPHABOOL = 0x02;\nenum VARIANT_NOUSEOVERRIDE = 0x04;\nenum VARIANT_LOCALBOOL = 0x08;\n\nenum VAR_TIMEVALUEONLY = 0x0001;\nenum VAR_DATEVALUEONLY = 0x0002;\nenum VAR_VALIDDATE = 0x0004;\nenum VAR_CALENDAR_HIJRI = 0x0008;\nenum VAR_LOCALBOOL = 0x0010;\nenum VAR_FORMAT_NOSUBSTITUTE = 0x0020;\nenum VAR_FOURDIGITYEARS = 0x0040;\nenum VAR_CALENDAR_THAI = 0x0080;\nenum VAR_CALENDAR_GREGORIAN = 0x0100;\n\nenum MEMBERID_NIL = DISPID_UNKNOWN;\nenum ID_DEFAULTINST =  -2;\nenum DISPATCH_METHOD = 1;\nenum DISPATCH_PROPERTYGET = 2;\nenum DISPATCH_PROPERTYPUT = 4;\nenum DISPATCH_PROPERTYPUTREF = 8;\n\n//ULONG LHashValOfName(LCID l, OLECHAR* n) { return LHashValOfNameSys(SYSKIND.SYS_WIN32, l, n); }\n\n// DAC: These aren't in the 2003 SDK.\n//MACRO #define WHashValOfLHashVal(h) ((unsigned short)(0x0000ffff&(h)))\n//MACRO #define IsHashValCompatible(h1, h2) ((BOOL)((0x00ff0000&(h1))==(0x00ff0000&(h2))))\n\nenum {\n    ACTIVEOBJECT_STRONG = 0,\n    ACTIVEOBJECT_WEAK   = 1\n}\n\n// DAC: These seem to be irrelevant for D.\n//#define V_UNION(X, Y) ((X)->Y)\n//#define V_VT(X) ((X)->vt)\n//#define V_BOOL(X) V_UNION(X, boolVal)\n//#define V_ISBYREF(X) (V_VT(X)&VT_BYREF)\n//#define V_ISARRAY(X) (V_VT(X)&VT_ARRAY)\n//#define V_ISVECTOR(X) (V_VT(X)&VT_VECTOR)\n//#define V_NONE(X) V_I2(X)\n//#define V_UI1(X) V_UNION(X, bVal)\n//#define V_UI1REF(X) V_UNION(X, pbVal)\n//#define V_I2(X) V_UNION(X, iVal)\n//#define V_UI2(X) V_UNION(X, uiVal)\n//#define V_I2REF(X) V_UNION(X, piVal)\n//#define V_I4(X) V_UNION(X, lVal)\n//#define V_UI4(X) V_UNION(X, ulVal)\n//#define V_I4REF(X) V_UNION(X, plVal)\n//#define V_UI4REF(X) V_UNION(X, pulVal)\n//#define V_I8(X) V_UNION(X, llVal)\n//#define V_UI8(X) V_UNION(X, ullVal)\n//#define V_I8REF(X) V_UNION(X, pllVal)\n//#define V_UI8REF(X) V_UNION(X, pullVal)\n//#define V_R4(X) V_UNION(X, fltVal)\n//#define V_R4REF(X) V_UNION(X, pfltVal)\n//#define V_R8(X) V_UNION(X, dblVal)\n//#define V_R8REF(X) V_UNION(X, pdblVal)\n//#define V_CY(X) V_UNION(X, cyVal)\n//#define V_CYREF(X) V_UNION(X, pcyVal)\n//#define V_DATE(X) V_UNION(X, date)\n//#define V_DATEREF(X) V_UNION(X, pdate)\n//#define V_BSTR(X) V_UNION(X, bstrVal)\n//#define V_BSTRREF(X) V_UNION(X, pbstrVal)\n//#define V_DISPATCH(X) V_UNION(X, pdispVal)\n//#define V_DISPATCHREF(X) V_UNION(X, ppdispVal)\n//#define V_ERROR(X) V_UNION(X, scode)\n//#define V_ERRORREF(X) V_UNION(X, pscode)\n//#define V_BOOLREF(X) V_UNION(X, pboolVal)\n//#define V_UNKNOWN(X) V_UNION(X, punkVal)\n//#define V_UNKNOWNREF(X) V_UNION(X, ppunkVal)\n//#define V_VARIANTREF(X) V_UNION(X, pvarVal)\n//#define V_LPSTR(X) V_UNION(X, pszVal)\n//#define V_LPSTRREF(X) V_UNION(X, ppszVal)\n//#define V_LPWSTR(X) V_UNION(X, pwszVal)\n//#define V_LPWSTRREF(X) V_UNION(X, ppwszVal)\n//#define V_FILETIME(X) V_UNION(X, filetime)\n//#define V_FILETIMEREF(X) V_UNION(X, pfiletime)\n//#define V_BLOB(X) V_UNION(X, blob)\n//#define V_UUID(X) V_UNION(X, puuid)\n//#define V_CLSID(X) V_UNION(X, puuid)\n//#define V_ARRAY(X) V_UNION(X, parray)\n//#define V_ARRAYREF(X) V_UNION(X, pparray)\n//#define V_BYREF(X) V_UNION(X, byref)\n//#define V_DECIMAL(X) ((X)->decVal)\n//#define V_DECIMALREF(X) V_UNION(X, pdecVal)\n//#define V_I1(X) V_UNION(X, cVal)\n\n//#ifdef _WIN64\n//#define V_INT_PTR(X) V_I8(X)\n//#define V_UINT_PTR(X) V_UI8(X)\n//#define V_INT_PTRREF(X) V_I8REF(X)\n//#define V_UINT_PTRREF(X) V_UI8REF(X)\n//#else\n//#define V_INT_PTR(X) V_I4(X)\n//#define V_UINT_PTR(X) V_UI4(X)\n//#define V_INT_PTRREF(X) V_I4REF(X)\n//#define V_UINT_PTRREF(X) V_UI4REF(X)\n//#endif\n\nenum {\n    VARCMP_LT = 0,\n    VARCMP_EQ,\n    VARCMP_GT,\n    VARCMP_NULL // = 3\n}\n\nenum LOCALE_USE_NLS = 0x10000000;\n\nenum VARIANT_NOUSEROVERRIDE     = 0x04;\nenum VARIANT_CALENDAR_HIJRI     = 0x08;\nenum VARIANT_CALENDAR_THAI      = 0x20;\nenum VARIANT_CALENDAR_GREGORIAN = 0x40;\nenum VARIANT_USE_NLS            = 0x80;\n\nenum NUMPRS_LEADING_WHITE  = 0x00001;\nenum NUMPRS_TRAILING_WHITE = 0x00002;\nenum NUMPRS_LEADING_PLUS   = 0x00004;\nenum NUMPRS_TRAILING_PLUS  = 0x00008;\nenum NUMPRS_LEADING_MINUS  = 0x00010;\nenum NUMPRS_TRAILING_MINUS = 0x00020;\nenum NUMPRS_HEX_OCT        = 0x00040;\nenum NUMPRS_PARENS         = 0x00080;\nenum NUMPRS_DECIMAL        = 0x00100;\nenum NUMPRS_THOUSANDS      = 0x00200;\nenum NUMPRS_CURRENCY       = 0x00400;\nenum NUMPRS_EXPONENT       = 0x00800;\nenum NUMPRS_USE_ALL        = 0x01000;\nenum NUMPRS_STD            = 0x01FFF;\nenum NUMPRS_NEG            = 0x10000;\nenum NUMPRS_INEXACT        = 0x20000;\n\nenum VTBIT_I1 = 1 << VARENUM.VT_I1;\nenum VTBIT_UI1 = 1 << VARENUM.VT_UI1;\nenum VTBIT_I2 = 1 << VARENUM.VT_I2;\nenum VTBIT_UI2 = 1 << VARENUM.VT_UI2;\nenum VTBIT_I4 = 1 << VARENUM.VT_I4;\nenum VTBIT_UI4 = 1 << VARENUM.VT_UI4;\nenum VTBIT_I8 = 1 << VARENUM.VT_I8;\nenum VTBIT_UI8 = 1 << VARENUM.VT_UI8;\nenum VTBIT_R4 = 1 << VARENUM.VT_R4;\nenum VTBIT_R8 = 1 << VARENUM.VT_R8;\nenum VTBIT_CY = 1 << VARENUM.VT_CY;\nenum VTBIT_DECIMAL = 1 << VARENUM.VT_DECIMAL;\n\n\nenum REGKIND{\n    REGKIND_DEFAULT,\n    REGKIND_REGISTER,\n    REGKIND_NONE\n}\n\nstruct PARAMDATA{\n    OLECHAR* szName;\n    VARTYPE vt;\n}\nalias PARAMDATA* LPPARAMDATA;\n\nstruct METHODDATA{\n    OLECHAR* szName;\n    PARAMDATA* ppdata;\n    DISPID dispid;\n    UINT iMeth;\n    CALLCONV cc;\n    UINT cArgs;\n    WORD wFlags;\n    VARTYPE vtReturn;\n}\nalias METHODDATA* LPMETHODDATA;\n\nstruct INTERFACEDATA{\n    METHODDATA* pmethdata;\n    UINT cMembers;\n}\nalias INTERFACEDATA* LPINTERFACEDATA;\n\nstruct UDATE {\n    SYSTEMTIME st;\n    USHORT wDayOfYear;\n}\n\nstruct NUMPARSE {\n    int cDig;\n    uint dwInFlags;\n    uint dwOutFlags;\n    int cchUsed;\n    int nBaseShift;\n    int nPwr10;\n}\n\n\n// DAC: In MinGW, these were declared but not defined in oaidl.\n// The SDK docs suggest they belong in this file instead.\n\ndeprecated {  // not actually deprecated, but they aren't converted yet.\n              // (will need to reinstate CreateTypeLib as well)\n    interface ICreateTypeInfo {};\n    interface ICreateTypeInfo2 {};\n    interface ICreateTypeLib {};\n    interface ICreateTypeLib2 {};\n\n    alias ICreateTypeInfo LPCREATETYPEINFO;\n    alias ICreateTypeInfo2 LPCREATETYPEINFO2;\n    alias ICreateTypeLib LPCREATETYPELIB;\n    alias ICreateTypeLib2 LPCREATETYPELIB2;\n}\n\nextern (Windows) {\n    BSTR SysAllocString(const(OLECHAR)*);\n    int SysReAllocString(BSTR*, const(OLECHAR)*);\n    BSTR SysAllocStringLen(const(OLECHAR)*, uint);\n    int SysReAllocStringLen(BSTR*, const(OLECHAR)*, uint);\n    void SysFreeString(BSTR);\n    uint SysStringLen(BSTR);\n    uint SysStringByteLen(BSTR);\n    BSTR SysAllocStringByteLen(const(char)*, uint);\n    int DosDateTimeToVariantTime(ushort, ushort, double*);\n    int VariantTimeToDosDateTime(double, ushort*, ushort*);\n    int VariantTimeToSystemTime(double, LPSYSTEMTIME);\n    int SystemTimeToVariantTime(LPSYSTEMTIME, double*);\n    HRESULT VarDateFromUdate(UDATE*, ULONG, DATE*);\n    HRESULT VarDateFromUdateEx(UDATE*, LCID, ULONG, DATE*);\n    HRESULT VarUdateFromDate(DATE, ULONG, UDATE*);\n    HRESULT SafeArrayAllocDescriptor(uint, SAFEARRAY**);\n    HRESULT SafeArrayAllocData(SAFEARRAY*);\n    SAFEARRAY* SafeArrayCreate(VARTYPE, uint, SAFEARRAYBOUND*);\n    HRESULT SafeArrayDestroyDescriptor(SAFEARRAY*);\n    HRESULT SafeArrayDestroyData(SAFEARRAY*);\n    HRESULT SafeArrayDestroy(SAFEARRAY*);\n    HRESULT SafeArrayRedim(SAFEARRAY*, SAFEARRAYBOUND*);\n    uint SafeArrayGetDim(SAFEARRAY*);\n    uint SafeArrayGetElemsize(SAFEARRAY*);\n    HRESULT SafeArrayGetUBound(SAFEARRAY*, uint, int*);\n    HRESULT SafeArrayGetLBound(SAFEARRAY*, uint, int*);\n    HRESULT SafeArrayLock(SAFEARRAY*);\n    HRESULT SafeArrayUnlock(SAFEARRAY*);\n    HRESULT SafeArrayAccessData(SAFEARRAY*, void**);\n    HRESULT SafeArrayUnaccessData(SAFEARRAY*);\n    HRESULT SafeArrayGetElement(SAFEARRAY*, int*, void*);\n    HRESULT SafeArrayPutElement(SAFEARRAY*, int*, void*);\n    HRESULT SafeArrayCopy(SAFEARRAY*, SAFEARRAY**);\n    HRESULT SafeArrayPtrOfIndex(SAFEARRAY*, int*, void**);\n    SAFEARRAY* SafeArrayCreateVector(VARTYPE, LONG, ULONG);\n    SAFEARRAY* SafeArrayCreateVectorEx(VARTYPE, LONG, ULONG, LPVOID);\n    HRESULT SafeArrayAllocDescriptorEx(VARTYPE, UINT, SAFEARRAY**);\n    HRESULT SafeArrayGetVartype(SAFEARRAY*, VARTYPE*);\n    HRESULT SafeArraySetRecordInfo(SAFEARRAY*, IRecordInfo);\n    HRESULT SafeArrayGetRecordInfo(SAFEARRAY*, IRecordInfo*);\n    HRESULT SafeArraySetIID(SAFEARRAY*, REFGUID);\n    HRESULT SafeArrayGetIID(SAFEARRAY*, GUID*);\n    void VariantInit(VARIANTARG*);\n    HRESULT VariantClear(VARIANTARG*);\n    HRESULT VariantCopy(VARIANTARG*, VARIANTARG*);\n    HRESULT VariantCopyInd(VARIANT*, VARIANTARG*);\n    HRESULT VariantChangeType(VARIANTARG*, VARIANTARG*, ushort, VARTYPE);\n    HRESULT VariantChangeTypeEx(VARIANTARG*, VARIANTARG*, LCID, ushort, VARTYPE);\n    HRESULT VarUI1FromI2(short, ubyte*);\n    HRESULT VarUI1FromI4(int, ubyte*);\n    HRESULT VarUI1FromR4(float, ubyte*);\n    HRESULT VarUI1FromR8(double, ubyte*);\n    HRESULT VarUI1FromCy(CY, ubyte*);\n    HRESULT VarUI1FromDate(DATE, ubyte*);\n    HRESULT VarUI1FromStr(OLECHAR*, LCID, uint, ubyte*);\n    HRESULT VarUI1FromDisp(LPDISPATCH, LCID, ubyte*);\n    HRESULT VarUI1FromBool(VARIANT_BOOL, ubyte*);\n    HRESULT VarI2FromUI1(ubyte, short*);\n    HRESULT VarI2FromI4(int, short*);\n    HRESULT VarI2FromR4(float, short*);\n    HRESULT VarI2FromR8(double, short*);\n    HRESULT VarI2FromCy(CY cyIn, short*);\n    HRESULT VarI2FromDate(DATE, short*);\n    HRESULT VarI2FromStr(OLECHAR*, LCID, uint, short*);\n    HRESULT VarI2FromDisp(LPDISPATCH, LCID, short*);\n    HRESULT VarI2FromBool(VARIANT_BOOL, short*);\n    HRESULT VarI4FromUI1(ubyte, int*);\n    HRESULT VarI4FromI2(short, int*);\n    HRESULT VarI4FromR4(float, int*);\n    HRESULT VarI4FromR8(double, int*);\n    HRESULT VarI4FromCy(CY, int*);\n    HRESULT VarI4FromDate(DATE, int*);\n    HRESULT VarI4FromStr(OLECHAR*, LCID, uint, int*);\n    HRESULT VarI4FromDisp(LPDISPATCH, LCID, int*);\n    HRESULT VarI4FromBool(VARIANT_BOOL, int*);\n    HRESULT VarR4FromUI1(ubyte, float*);\n    HRESULT VarR4FromI2(short, float*);\n    HRESULT VarR4FromI4(int, float*);\n    HRESULT VarR4FromR8(double, float*);\n    HRESULT VarR4FromCy(CY, float*);\n    HRESULT VarR4FromDate(DATE, float*);\n    HRESULT VarR4FromStr(OLECHAR*, LCID, uint, float*);\n    HRESULT VarR4FromDisp(LPDISPATCH, LCID, float*);\n    HRESULT VarR4FromBool(VARIANT_BOOL, float*);\n    HRESULT VarR8FromUI1(ubyte, double*);\n    HRESULT VarR8FromI2(short, double*);\n    HRESULT VarR8FromI4(int, double*);\n    HRESULT VarR8FromR4(float, double*);\n    HRESULT VarR8FromCy(CY, double*);\n    HRESULT VarR8FromDate(DATE, double*);\n    HRESULT VarR8FromStr(OLECHAR*, LCID, uint, double*);\n    HRESULT VarR8FromDisp(LPDISPATCH, LCID, double*);\n    HRESULT VarR8FromBool(VARIANT_BOOL, double*);\n    HRESULT VarR8FromDec(DECIMAL*, double*);\n    HRESULT VarDateFromUI1(ubyte, DATE*);\n    HRESULT VarDateFromI2(short, DATE*);\n    HRESULT VarDateFromI4(int, DATE*);\n    HRESULT VarDateFromR4(float, DATE*);\n    HRESULT VarDateFromR8(double, DATE*);\n    HRESULT VarDateFromCy(CY, DATE*);\n    HRESULT VarDateFromStr(OLECHAR*, LCID, uint, DATE*);\n    HRESULT VarDateFromDisp(LPDISPATCH, LCID, DATE*);\n    HRESULT VarDateFromBool(VARIANT_BOOL, DATE*);\n    HRESULT VarCyFromUI1(ubyte, CY*);\n    HRESULT VarCyFromI2(short, CY*);\n    HRESULT VarCyFromI4(int, CY*);\n    HRESULT VarCyFromR4(float, CY*);\n    HRESULT VarCyFromR8(double, CY*);\n    HRESULT VarCyFromDate(DATE, CY*);\n    HRESULT VarCyFromStr(OLECHAR*, LCID, uint, CY*);\n    HRESULT VarCyFromDisp(LPDISPATCH, LCID, CY*);\n    HRESULT VarCyFromBool(VARIANT_BOOL, CY*);\n    HRESULT VarBstrFromUI1(ubyte, LCID, uint, BSTR*);\n    HRESULT VarBstrFromI2(short, LCID, uint, BSTR*);\n    HRESULT VarBstrFromI4(int, LCID, uint, BSTR*);\n    HRESULT VarBstrFromR4(float, LCID, uint, BSTR*);\n    HRESULT VarBstrFromR8(double, LCID, uint, BSTR*);\n    HRESULT VarBstrFromCy(CY, LCID, uint, BSTR*);\n    HRESULT VarBstrFromDate(DATE, LCID, uint, BSTR*);\n    HRESULT VarBstrFromDisp(LPDISPATCH, LCID, uint, BSTR*);\n    HRESULT VarBstrFromBool(VARIANT_BOOL, LCID, uint, BSTR*);\n    HRESULT VarBoolFromUI1(ubyte, VARIANT_BOOL*);\n    HRESULT VarBoolFromI2(short, VARIANT_BOOL*);\n    HRESULT VarBoolFromI4(int, VARIANT_BOOL*);\n    HRESULT VarBoolFromR4(float, VARIANT_BOOL*);\n    HRESULT VarBoolFromR8(double, VARIANT_BOOL*);\n    HRESULT VarBoolFromDate(DATE, VARIANT_BOOL*);\n    HRESULT VarBoolFromCy(CY, VARIANT_BOOL*);\n    HRESULT VarBoolFromStr(OLECHAR*, LCID, uint, VARIANT_BOOL*);\n    HRESULT VarBoolFromDisp(LPDISPATCH, LCID, VARIANT_BOOL*);\n    HRESULT VarDecFromR8(double, DECIMAL*);\n    ULONG LHashValOfNameSysA(SYSKIND, LCID, const(char)*);\n    ULONG LHashValOfNameSys(SYSKIND, LCID, const(OLECHAR)*);\n    HRESULT LoadTypeLib(const(OLECHAR)*, LPTYPELIB*);\n    HRESULT LoadTypeLibEx(LPCOLESTR, REGKIND, LPTYPELIB*);\n    HRESULT LoadRegTypeLib(REFGUID, WORD, WORD, LCID, LPTYPELIB*);\n    HRESULT QueryPathOfRegTypeLib(REFGUID, ushort, ushort, LCID, LPBSTR);\n    HRESULT RegisterTypeLib(LPTYPELIB, OLECHAR*, OLECHAR*);\n    HRESULT UnRegisterTypeLib(REFGUID, WORD, WORD, LCID, SYSKIND);\n    // not actually deprecated, but depends on unconverted ICreateTypeLib\n    deprecated HRESULT CreateTypeLib(SYSKIND, const(OLECHAR)*, LPCREATETYPELIB*);\n    HRESULT DispGetParam(DISPPARAMS*, UINT, VARTYPE, VARIANT*, UINT*);\n    HRESULT DispGetIDsOfNames(LPTYPEINFO, OLECHAR**, UINT, DISPID*);\n    HRESULT DispInvoke(void*, LPTYPEINFO, DISPID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);\n    HRESULT CreateDispTypeInfo(INTERFACEDATA*, LCID, LPTYPEINFO*);\n    HRESULT CreateStdDispatch(IUnknown, void*, LPTYPEINFO, IUnknown*);\n    HRESULT RegisterActiveObject(IUnknown, REFCLSID, DWORD, DWORD*);\n    HRESULT RevokeActiveObject(DWORD, void*);\n    HRESULT GetActiveObject(REFCLSID, void*, IUnknown*);\n    HRESULT SetErrorInfo(uint, LPERRORINFO);\n    HRESULT GetErrorInfo(uint, LPERRORINFO*);\n    HRESULT CreateErrorInfo(LPCREATEERRORINFO*);\n    uint OaBuildVersion();\n    HRESULT VectorFromBstr (BSTR, SAFEARRAY**);\n    HRESULT BstrFromVector (SAFEARRAY*, BSTR*);\n    HRESULT VarParseNumFromStr(OLECHAR*, LCID, ULONG, NUMPARSE*, BYTE*);\n    HRESULT VarNumFromParseNum(NUMPARSE*, BYTE*, ULONG, VARIANT*);\n\n    HRESULT VarAdd(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarSub(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarMul(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarDiv(LPVARIANT, LPVARIANT, LPVARIANT);\n\n    HRESULT VarUI1FromI2(SHORT, BYTE*);\n    HRESULT VarUI1FromI4(LONG, BYTE*);\n    HRESULT VarUI1FromI8(LONG64, BYTE*);\n    HRESULT VarUI1FromR4(FLOAT, BYTE*);\n    HRESULT VarUI1FromR8(DOUBLE, BYTE*);\n    HRESULT VarUI1FromDate(DATE, BYTE*);\n    HRESULT VarUI1FromBool(VARIANT_BOOL, BYTE*);\n    HRESULT VarUI1FromI1(byte, BYTE*);\n    HRESULT VarUI1FromUI2(USHORT, BYTE*);\n    HRESULT VarUI1FromUI4(ULONG, BYTE*);\n    HRESULT VarUI1FromUI8(ULONG64, BYTE*);\n    HRESULT VarUI1FromStr(OLECHAR*, LCID, ULONG, BYTE*);\n    HRESULT VarUI1FromCy(CY, BYTE*);\n    HRESULT VarUI1FromDec(DECIMAL*, BYTE*);\n    HRESULT VarUI1FromDisp(IDispatch, LCID, BYTE*);\n\n    HRESULT VarI2FromUI1(BYTE, SHORT*);\n    HRESULT VarI2FromI4(LONG, SHORT*);\n    HRESULT VarI2FromI8(LONG64, SHORT*);\n    HRESULT VarI2FromR4(FLOAT, SHORT*);\n    HRESULT VarI2FromR8(DOUBLE, SHORT*);\n    HRESULT VarI2FromDate(DATE, SHORT*);\n    HRESULT VarI2FromBool(VARIANT_BOOL, SHORT*);\n    HRESULT VarI2FromI1(byte, SHORT*);\n    HRESULT VarI2FromUI2(USHORT, SHORT*);\n    HRESULT VarI2FromUI4(ULONG, SHORT*);\n    HRESULT VarI2FromUI8(ULONG64, SHORT*);\n    HRESULT VarI2FromStr(OLECHAR*, LCID, ULONG, SHORT*);\n    HRESULT VarI2FromCy(CY, SHORT*);\n    HRESULT VarI2FromDec(DECIMAL*, SHORT*);\n    HRESULT VarI2FromDisp(IDispatch, LCID, SHORT*);\n\n    HRESULT VarI4FromUI1(BYTE, LONG*);\n    HRESULT VarI4FromI2(SHORT, LONG*);\n    HRESULT VarI4FromI8(LONG64, LONG*);\n    HRESULT VarI4FromR4(FLOAT, LONG*);\n    HRESULT VarI4FromR8(DOUBLE, LONG*);\n    HRESULT VarI4FromDate(DATE, LONG*);\n    HRESULT VarI4FromBool(VARIANT_BOOL, LONG*);\n    HRESULT VarI4FromI1(byte, LONG*);\n    HRESULT VarI4FromUI2(USHORT, LONG*);\n    HRESULT VarI4FromUI4(ULONG, LONG*);\n    HRESULT VarI4FromUI8(ULONG64, LONG*);\n    HRESULT VarI4FromStr(OLECHAR*, LCID, ULONG, LONG*);\n    HRESULT VarI4FromCy(CY, LONG*);\n    HRESULT VarI4FromDec(DECIMAL*, LONG*);\n    HRESULT VarI4FromDisp(IDispatch, LCID, LONG*);\n\n    HRESULT VarI8FromUI1(BYTE, LONG64*);\n    HRESULT VarI8FromI2(SHORT, LONG64*);\n    HRESULT VarI8FromI4(LONG, LONG64*);\n    HRESULT VarI8FromR4(FLOAT, LONG64*);\n    HRESULT VarI8FromR8(DOUBLE, LONG64*);\n    HRESULT VarI8FromDate(DATE, LONG64*);\n    HRESULT VarI8FromStr(OLECHAR*, LCID, ULONG, LONG64*);\n    HRESULT VarI8FromBool(VARIANT_BOOL, LONG64*);\n    HRESULT VarI8FromI1(byte, LONG64*);\n    HRESULT VarI8FromUI2(USHORT, LONG64*);\n    HRESULT VarI8FromUI4(ULONG, LONG64*);\n    HRESULT VarI8FromUI8(ULONG64, LONG64*);\n    HRESULT VarI8FromDec(DECIMAL* pdecIn, LONG64*);\n    HRESULT VarI8FromInt(INT intIn, LONG64*);\n    HRESULT VarI8FromCy(CY, LONG64*);\n    HRESULT VarI8FromDisp(IDispatch, LCID, LONG64*);\n\n    HRESULT VarR4FromUI1(BYTE, FLOAT*);\n    HRESULT VarR4FromI2(SHORT, FLOAT*);\n    HRESULT VarR4FromI4(LONG, FLOAT*);\n    HRESULT VarR4FromI8(LONG64, FLOAT*);\n    HRESULT VarR4FromR8(DOUBLE, FLOAT*);\n    HRESULT VarR4FromDate(DATE, FLOAT*);\n    HRESULT VarR4FromBool(VARIANT_BOOL, FLOAT*);\n    HRESULT VarR4FromI1(byte, FLOAT*);\n    HRESULT VarR4FromUI2(USHORT, FLOAT*);\n    HRESULT VarR4FromUI4(ULONG, FLOAT*);\n    HRESULT VarR4FromUI8(ULONG64, FLOAT*);\n    HRESULT VarR4FromStr(OLECHAR*, LCID, ULONG, FLOAT*);\n    HRESULT VarR4FromCy(CY, FLOAT*);\n    HRESULT VarR4FromDec(DECIMAL*, FLOAT*);\n    HRESULT VarR4FromDisp(IDispatch, LCID, FLOAT*);\n\n    HRESULT VarR8FromUI1(BYTE, double*);\n    HRESULT VarR8FromI2(SHORT, double*);\n    HRESULT VarR8FromI4(LONG, double*);\n    HRESULT VarR8FromI8(LONG64, double*);\n    HRESULT VarR8FromR4(FLOAT, double*);\n    HRESULT VarR8FromDate(DATE, double*);\n    HRESULT VarR8FromBool(VARIANT_BOOL, double*);\n    HRESULT VarR8FromI1(byte, double*);\n    HRESULT VarR8FromUI2(USHORT, double*);\n    HRESULT VarR8FromUI4(ULONG, double*);\n    HRESULT VarR8FromUI8(ULONG64, double*);\n    HRESULT VarR8FromStr(OLECHAR*, LCID, ULONG, double*);\n    HRESULT VarR8FromCy(CY, double*);\n    HRESULT VarR8FromDec(DECIMAL*, double*);\n    HRESULT VarR8FromDisp(IDispatch, LCID, double*);\n\n    HRESULT VarDateFromUI1(BYTE, DATE*);\n    HRESULT VarDateFromI2(SHORT, DATE*);\n    HRESULT VarDateFromI4(LONG, DATE*);\n    HRESULT VarDateFromI8(LONG64, DATE*);\n    HRESULT VarDateFromR4(FLOAT, DATE*);\n    HRESULT VarDateFromR8(DOUBLE, DATE*);\n    HRESULT VarDateFromStr(OLECHAR*, LCID, ULONG, DATE*);\n    HRESULT VarDateFromI1(byte, DATE*);\n    HRESULT VarDateFromUI2(USHORT, DATE*);\n    HRESULT VarDateFromUI4(ULONG, DATE*);\n    HRESULT VarDateFromUI8(ULONG64, DATE*);\n    HRESULT VarDateFromBool(VARIANT_BOOL, DATE*);\n    HRESULT VarDateFromCy(CY, DATE*);\n    HRESULT VarDateFromDec(DECIMAL*, DATE*);\n    HRESULT VarDateFromDisp(IDispatch, LCID, DATE*);\n\n    HRESULT VarCyFromUI1(BYTE, CY*);\n    HRESULT VarCyFromI2(SHORT sIn, CY*);\n    HRESULT VarCyFromI4(LONG, CY*);\n    HRESULT VarCyFromI8(LONG64, CY*);\n    HRESULT VarCyFromR4(FLOAT, CY*);\n    HRESULT VarCyFromR8(DOUBLE, CY*);\n    HRESULT VarCyFromDate(DATE, CY*);\n    HRESULT VarCyFromStr(OLECHAR*, LCID, ULONG, CY*);\n    HRESULT VarCyFromBool(VARIANT_BOOL, CY*);\n    HRESULT VarCyFromI1(byte, CY*);\n    HRESULT VarCyFromUI2(USHORT, CY*);\n    HRESULT VarCyFromUI4(ULONG, CY*);\n    HRESULT VarCyFromUI8(ULONG64, CY*);\n    HRESULT VarCyFromDec(DECIMAL*, CY*);\n    HRESULT VarCyFromStr(OLECHAR*, LCID, ULONG, CY*);\n    HRESULT VarCyFromDisp(IDispatch, LCID, CY*);\n\n    HRESULT VarBstrFromUI1(BYTE, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromI2(SHORT, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromI4(LONG, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromI8(LONG64, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromR4(FLOAT, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromR8(DOUBLE, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromDate(DATE, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromBool(VARIANT_BOOL, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromI1(byte, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromUI2(USHORT, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromUI8(ULONG64, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromUI4(ULONG, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromCy(CY, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromDec(DECIMAL*, LCID, ULONG, BSTR*);\n    HRESULT VarBstrFromDisp(IDispatch, LCID, ULONG, BSTR*);\n\n    HRESULT VarBoolFromUI1(BYTE, VARIANT_BOOL*);\n    HRESULT VarBoolFromI2(SHORT, VARIANT_BOOL*);\n    HRESULT VarBoolFromI4(LONG, VARIANT_BOOL*);\n    HRESULT VarBoolFromI8(LONG64, VARIANT_BOOL*);\n    HRESULT VarBoolFromR4(FLOAT, VARIANT_BOOL*);\n    HRESULT VarBoolFromR8(DOUBLE, VARIANT_BOOL*);\n    HRESULT VarBoolFromDate(DATE, VARIANT_BOOL*);\n    HRESULT VarBoolFromStr(OLECHAR*, LCID, ULONG, VARIANT_BOOL*);\n    HRESULT VarBoolFromI1(byte, VARIANT_BOOL*);\n    HRESULT VarBoolFromUI2(USHORT, VARIANT_BOOL*);\n    HRESULT VarBoolFromUI4(ULONG, VARIANT_BOOL*);\n    HRESULT VarBoolFromUI8(ULONG64, VARIANT_BOOL*);\n    HRESULT VarBoolFromCy(CY, VARIANT_BOOL*);\n    HRESULT VarBoolFromDec(DECIMAL*, VARIANT_BOOL*);\n    HRESULT VarBoolFromDisp(IDispatch, LCID, VARIANT_BOOL*);\n\n    HRESULT VarI1FromUI1(BYTE, byte*);\n    HRESULT VarI1FromI2(SHORT, byte*);\n    HRESULT VarI1FromI4(LONG, byte*);\n    HRESULT VarI1FromI8(LONG64, byte*);\n    HRESULT VarI1FromR4(FLOAT, byte*);\n    HRESULT VarI1FromR8(DOUBLE, byte*);\n    HRESULT VarI1FromDate(DATE, byte*);\n    HRESULT VarI1FromStr(OLECHAR*, LCID, ULONG, byte*);\n    HRESULT VarI1FromBool(VARIANT_BOOL, byte*);\n    HRESULT VarI1FromUI2(USHORT, byte*);\n    HRESULT VarI1FromUI4(ULONG, byte*);\n    HRESULT VarI1FromUI8(ULONG64, byte*);\n    HRESULT VarI1FromCy(CY, byte*);\n    HRESULT VarI1FromDec(DECIMAL*, byte*);\n    HRESULT VarI1FromDisp(IDispatch, LCID, byte*);\n\n    HRESULT VarUI2FromUI1(BYTE, USHORT*);\n    HRESULT VarUI2FromI2(SHORT, USHORT*);\n    HRESULT VarUI2FromI4(LONG, USHORT*);\n    HRESULT VarUI2FromI8(LONG64, USHORT*);\n    HRESULT VarUI2FromR4(FLOAT, USHORT*);\n    HRESULT VarUI2FromR8(DOUBLE, USHORT*);\n    HRESULT VarUI2FromDate(DATE, USHORT*);\n    HRESULT VarUI2FromStr(OLECHAR*, LCID, ULONG, USHORT*);\n    HRESULT VarUI2FromBool(VARIANT_BOOL, USHORT*);\n    HRESULT VarUI2FromI1(byte, USHORT*);\n    HRESULT VarUI2FromUI4(ULONG, USHORT*);\n    HRESULT VarUI2FromUI8(ULONG64, USHORT*);\n    HRESULT VarUI2FromCy(CY, USHORT*);\n    HRESULT VarUI2FromDec(DECIMAL*, USHORT*);\n    HRESULT VarUI2FromDisp(IDispatch, LCID, USHORT*);\n\n    HRESULT VarUI4FromStr(OLECHAR*, LCID, ULONG, ULONG*);\n    HRESULT VarUI4FromUI1(BYTE, ULONG*);\n    HRESULT VarUI4FromI2(SHORT, ULONG*);\n    HRESULT VarUI4FromI4(LONG, ULONG*);\n    HRESULT VarUI4FromI8(LONG64, ULONG*);\n    HRESULT VarUI4FromR4(FLOAT, ULONG*);\n    HRESULT VarUI4FromR8(DOUBLE, ULONG*);\n    HRESULT VarUI4FromDate(DATE, ULONG*);\n    HRESULT VarUI4FromBool(VARIANT_BOOL, ULONG*);\n    HRESULT VarUI4FromI1(byte, ULONG*);\n    HRESULT VarUI4FromUI2(USHORT, ULONG*);\n    HRESULT VarUI4FromUI8(ULONG64, ULONG*);\n    HRESULT VarUI4FromCy(CY, ULONG*);\n    HRESULT VarUI4FromDec(DECIMAL*, ULONG*);\n    HRESULT VarUI4FromDisp(IDispatch, LCID, ULONG*);\n\n    HRESULT VarUI8FromUI1(BYTE, ULONG64*);\n    HRESULT VarUI8FromI2(SHORT, ULONG64*);\n    HRESULT VarUI8FromI4(LONG, ULONG64*);\n    HRESULT VarUI8FromI8(LONG64, ULONG64*);\n    HRESULT VarUI8FromR4(FLOAT, ULONG64*);\n    HRESULT VarUI8FromR8(DOUBLE, ULONG64*);\n    HRESULT VarUI8FromDate(DATE, ULONG64*);\n    HRESULT VarUI8FromStr(OLECHAR*, LCID, ULONG, ULONG64*);\n    HRESULT VarUI8FromBool(VARIANT_BOOL, ULONG64*);\n    HRESULT VarUI8FromI1(byte, ULONG64*);\n    HRESULT VarUI8FromUI2(USHORT, ULONG64*);\n    HRESULT VarUI8FromUI4(ULONG, ULONG64*);\n    HRESULT VarUI8FromDec(DECIMAL*, ULONG64*);\n    HRESULT VarUI8FromInt(INT, ULONG64*);\n    HRESULT VarUI8FromCy(CY, ULONG64*);\n    HRESULT VarUI8FromDisp(IDispatch, LCID, ULONG64*);\n\n    HRESULT VarDecFromUI1(BYTE, DECIMAL*);\n    HRESULT VarDecFromI2(SHORT, DECIMAL*);\n    HRESULT VarDecFromI4(LONG, DECIMAL*);\n    HRESULT VarDecFromI8(LONG64, DECIMAL*);\n    HRESULT VarDecFromR4(FLOAT, DECIMAL*);\n    HRESULT VarDecFromR8(DOUBLE, DECIMAL*);\n    HRESULT VarDecFromDate(DATE, DECIMAL*);\n    HRESULT VarDecFromStr(OLECHAR*, LCID, ULONG, DECIMAL*);\n    HRESULT VarDecFromBool(VARIANT_BOOL, DECIMAL*);\n    HRESULT VarDecFromI1(byte, DECIMAL*);\n    HRESULT VarDecFromUI2(USHORT, DECIMAL*);\n    HRESULT VarDecFromUI4(ULONG, DECIMAL*);\n    HRESULT VarDecFromUI8(ULONG64, DECIMAL*);\n    HRESULT VarDecFromCy(CY, DECIMAL*);\n    HRESULT VarDecFromDisp(IDispatch, LCID, DECIMAL*);\n\n    HRESULT VarDecNeg(const(DECIMAL)*, DECIMAL*);\n    HRESULT VarR4CmpR8(float, double);\n    HRESULT VarR8Pow(double, double, double*);\n    HRESULT VarR8Round(double, int, double*);\n    HRESULT VarDecAbs(const(DECIMAL)*, DECIMAL*);\n    HRESULT VarDecAdd(const(DECIMAL)*, const(DECIMAL)*, DECIMAL*);\n    HRESULT VarDecCmp(const(DECIMAL)*, const(DECIMAL)*);\n    HRESULT VarDecCmpR8(const(DECIMAL)*, DOUBLE);\n    HRESULT VarDecDiv(const(DECIMAL)*, const(DECIMAL)*, DECIMAL*);\n    HRESULT VarDecFix(const(DECIMAL)*, DECIMAL*);\n    HRESULT VarDecInt(const(DECIMAL)*, DECIMAL*);\n    HRESULT VarDecMul(const(DECIMAL)*, const(DECIMAL)*, DECIMAL*);\n    HRESULT VarDecRound(const(DECIMAL)*, int, DECIMAL*);\n    HRESULT VarDecSub(const(DECIMAL)*, const(DECIMAL)*, DECIMAL*);\n    HRESULT VarCyAbs(CY, CY*);\n    HRESULT VarCyAdd(CY, CY, CY*);\n    HRESULT VarCyCmp(CY, CY);\n    HRESULT VarCyCmpR8(CY, DOUBLE);\n    HRESULT VarCyFix(CY, CY*);\n    HRESULT VarCyInt(CY, CY*);\n    HRESULT VarCyMul(CY, CY, CY*);\n    HRESULT VarCyMulI4(CY, LONG, CY*);\n    HRESULT VarCyMulI8(CY, LONG64, CY*);\n    HRESULT VarCyNeg(CY, CY*);\n    HRESULT VarCyRound(CY, INT, CY*);\n    HRESULT VarCySub(CY, CY, CY*);\n    HRESULT VarAdd(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarAnd(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarCat(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarDiv(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarEqv(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarIdiv(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarImp(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarMod(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarMul(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarOr(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarPow(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarSub(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarXor(LPVARIANT, LPVARIANT, LPVARIANT);\n    HRESULT VarAbs(LPVARIANT, LPVARIANT);\n    HRESULT VarFix(LPVARIANT, LPVARIANT);\n    HRESULT VarInt(LPVARIANT, LPVARIANT);\n    HRESULT VarNeg(LPVARIANT, LPVARIANT);\n    HRESULT VarNot(LPVARIANT, LPVARIANT);\n    HRESULT VarRound(LPVARIANT, int, LPVARIANT);\n    HRESULT VarCmp(LPVARIANT, LPVARIANT, LCID, ULONG);\n    HRESULT VarBstrCmp(BSTR, BSTR, LCID, ULONG);\n    HRESULT VarBstrCat(BSTR, BSTR, BSTR*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/olectl.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_olectl.d)\n */\nmodule core.sys.windows.olectl;\nversion (Windows):\n\n// In conversion from MinGW, the following was deleted:\n//#define FONTSIZE(n) {n##0000, 0}\n\nimport core.sys.windows.ocidl, core.sys.windows.olectlid;\nprivate import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.oleauto, core.sys.windows.unknwn,\n  core.sys.windows.windef, core.sys.windows.wingdi, core.sys.windows.winuser, core.sys.windows.wtypes;\nprivate import core.sys.windows.ntdef;     // for NTSTATUS\nprivate import core.sys.windows.objfwd;    // for LPSTREAM\nprivate import core.sys.windows.winerror;  // for SCODE\n\n\nprivate {\n    // These replace C macros.\n    template ITF_ERROR_SCODE_FOR_D(int c)\n    {\nenum SCODE ITF_ERROR_SCODE_FOR_D\n          = (SEVERITY_ERROR << 31) | (FACILITY_ITF << 16) | c;\n    }\n\n    template ITF_SUCCESS_SCODE_FOR_D(int c)\n    {\nenum SCODE ITF_SUCCESS_SCODE_FOR_D\n          = (SEVERITY_SUCCESS << 31) | (FACILITY_ITF << 16) | c;\n    }\n\n    template STD_CTL_SCODE(int c)\n    {\nenum SCODE STD_CTL_SCODE\n          = (SEVERITY_ERROR << 31) | (FACILITY_CONTROL << 16) | c;\n    }\n}\n\nenum : SCODE {\n    CTL_E_ILLEGALFUNCTIONCALL       = STD_CTL_SCODE!(5),\n    CTL_E_OVERFLOW                  = STD_CTL_SCODE!(6),\n    CTL_E_OUTOFMEMORY               = STD_CTL_SCODE!(7),\n    CTL_E_DIVISIONBYZERO            = STD_CTL_SCODE!(11),\n    CTL_E_OUTOFSTRINGSPACE          = STD_CTL_SCODE!(14),\n    CTL_E_OUTOFSTACKSPACE           = STD_CTL_SCODE!(28),\n    CTL_E_BADFILENAMEORNUMBER       = STD_CTL_SCODE!(52),\n    CTL_E_FILENOTFOUND              = STD_CTL_SCODE!(53),\n    CTL_E_BADFILEMODE               = STD_CTL_SCODE!(54),\n    CTL_E_FILEALREADYOPEN           = STD_CTL_SCODE!(55),\n    CTL_E_DEVICEIOERROR             = STD_CTL_SCODE!(57),\n    CTL_E_FILEALREADYEXISTS         = STD_CTL_SCODE!(58),\n    CTL_E_BADRECORDLENGTH           = STD_CTL_SCODE!(59),\n    CTL_E_DISKFULL                  = STD_CTL_SCODE!(61),\n    CTL_E_BADRECORDNUMBER           = STD_CTL_SCODE!(63),\n    CTL_E_BADFILENAME               = STD_CTL_SCODE!(64),\n    CTL_E_TOOMANYFILES              = STD_CTL_SCODE!(67),\n    CTL_E_DEVICEUNAVAILABLE         = STD_CTL_SCODE!(68),\n    CTL_E_PERMISSIONDENIED          = STD_CTL_SCODE!(70),\n    CTL_E_DISKNOTREADY              = STD_CTL_SCODE!(71),\n    CTL_E_PATHFILEACCESSERROR       = STD_CTL_SCODE!(75),\n    CTL_E_PATHNOTFOUND              = STD_CTL_SCODE!(76),\n    CTL_E_INVALIDPATTERNSTRING      = STD_CTL_SCODE!(93),\n    CTL_E_INVALIDUSEOFNULL          = STD_CTL_SCODE!(94),\n    CTL_E_INVALIDFILEFORMAT         = STD_CTL_SCODE!(321),\n    CTL_E_INVALIDPROPERTYVALUE      = STD_CTL_SCODE!(380),\n    CTL_E_INVALIDPROPERTYARRAYINDEX = STD_CTL_SCODE!(381),\n    CTL_E_SETNOTSUPPORTEDATRUNTIME  = STD_CTL_SCODE!(382),\n    CTL_E_SETNOTSUPPORTED           = STD_CTL_SCODE!(383),\n    CTL_E_NEEDPROPERTYARRAYINDEX    = STD_CTL_SCODE!(385),\n    CTL_E_SETNOTPERMITTED           = STD_CTL_SCODE!(387),\n    CTL_E_GETNOTSUPPORTEDATRUNTIME  = STD_CTL_SCODE!(393),\n    CTL_E_GETNOTSUPPORTED           = STD_CTL_SCODE!(394),\n    CTL_E_PROPERTYNOTFOUND          = STD_CTL_SCODE!(422),\n    CTL_E_INVALIDCLIPBOARDFORMAT    = STD_CTL_SCODE!(460),\n    CTL_E_INVALIDPICTURE            = STD_CTL_SCODE!(481),\n    CTL_E_PRINTERERROR              = STD_CTL_SCODE!(482),\n    CTL_E_CANTSAVEFILETOTEMP        = STD_CTL_SCODE!(735),\n    CTL_E_SEARCHTEXTNOTFOUND        = STD_CTL_SCODE!(744),\n    CTL_E_REPLACEMENTSTOOLONG       = STD_CTL_SCODE!(746),\n    CTL_E_CUSTOM_FIRST              = STD_CTL_SCODE!(600)\n}\n\nenum SCODE CLASS_E_NOTLICENSED = CLASSFACTORY_E_FIRST+2;\n\nenum : SCODE {\n    CONNECT_E_FIRST           = ITF_ERROR_SCODE_FOR_D!(0x200),\n    CONNECT_E_LAST            = ITF_ERROR_SCODE_FOR_D!(0x20F),\n    CONNECT_S_FIRST           = ITF_SUCCESS_SCODE_FOR_D!(0x200),\n    CONNECT_S_LAST            = ITF_SUCCESS_SCODE_FOR_D!(0x20F),\n    CONNECT_E_NOCONNECTION    = CONNECT_E_FIRST + 0,\n    CONNECT_E_ADVISELIMIT     = CONNECT_E_FIRST + 1,\n    CONNECT_E_CANNOTCONNECT   = CONNECT_E_FIRST + 2,\n    CONNECT_E_OVERRIDDEN      = CONNECT_E_FIRST + 3,\n\n    SELFREG_E_FIRST           = ITF_ERROR_SCODE_FOR_D!(0x200),\n    SELFREG_E_LAST            = ITF_ERROR_SCODE_FOR_D!(0x20F),\n    SELFREG_S_FIRST           = ITF_SUCCESS_SCODE_FOR_D!(0x200),\n    SELFREG_S_LAST            = ITF_SUCCESS_SCODE_FOR_D!(0x20F),\n    SELFREG_E_TYPELIB         = SELFREG_E_FIRST + 0,\n    SELFREG_E_CLASS           = SELFREG_E_FIRST + 1,\n\n    PERPROP_E_FIRST           = ITF_ERROR_SCODE_FOR_D!(0x200),\n    PERPROP_E_LAST            = ITF_ERROR_SCODE_FOR_D!(0x20F),\n    PERPROP_S_FIRST           = ITF_SUCCESS_SCODE_FOR_D!(0x200),\n    PERPROP_S_LAST            = ITF_SUCCESS_SCODE_FOR_D!(0x20F),\n    PERPROP_E_NOPAGEAVAILABLE = PERPROP_E_FIRST\n}\n\nenum {\n    OLEMISC_RECOMPOSEONRESIZE            = 0x1,\n    OLEMISC_ONLYICONIC                   = 0x2,\n    OLEMISC_INSERTNOTREPLACE             = 0x4,\n    OLEMISC_STATIC                       = 0x8,\n    OLEMISC_CANTLINKINSIDE               = 0x10,\n    OLEMISC_CANLINKBYOLE1                = 0x20,\n    OLEMISC_ISLINKOBJECT                 = 0x40,\n    OLEMISC_INSIDEOUT                    = 0x80,\n    OLEMISC_ACTIVATEWHENVISIBLE          = 0x100,\n    OLEMISC_RENDERINGISDEVICEINDEPENDENT = 0x200,\n    OLEMISC_INVISIBLEATRUNTIME           = 0x400,\n    OLEMISC_ALWAYSRUN                    = 0x800,\n    OLEMISC_ACTSLIKEBUTTON               = 0x1000,\n    OLEMISC_ACTSLIKELABEL                = 0x2000,\n    OLEMISC_NOUIACTIVATE                 = 0x4000,\n    OLEMISC_ALIGNABLE                    = 0x8000,\n    OLEMISC_SIMPLEFRAME                  = 0x10000,\n    OLEMISC_SETCLIENTSITEFIRST           = 0x20000,\n    OLEMISC_IMEMODE                      = 0x40000,\n    OLEMISC_IGNOREACTIVATEWHENVISIBLE    = 0x80000,\n    OLEMISC_WANTSTOMENUMERGE             = 0x100000,\n    OLEMISC_SUPPORTSMULTILEVELUNDO       = 0x200000\n}\nenum OLEIVERB_PROPERTIES = -7;\n\nenum VT_STREAMED_PROPSET = 73;\nenum VT_STORED_PROPSET = 74;\nenum VT_BLOB_PROPSET = 75;\nenum VT_VERBOSE_ENUM = 76;\nenum VT_COLOR = VARENUM.VT_I4;\nenum VT_XPOS_PIXELS = VARENUM.VT_I4;\nenum VT_YPOS_PIXELS = VARENUM.VT_I4;\nenum VT_XSIZE_PIXELS = VARENUM.VT_I4;\nenum VT_YSIZE_PIXELS = VARENUM.VT_I4;\nenum VT_XPOS_HIMETRIC = VARENUM.VT_I4;\nenum VT_YPOS_HIMETRIC = VARENUM.VT_I4;\nenum VT_XSIZE_HIMETRIC = VARENUM.VT_I4;\nenum VT_YSIZE_HIMETRIC = VARENUM.VT_I4;\nenum VT_TRISTATE = VARENUM.VT_I2;\nenum VT_OPTEXCLUSIVE = VARENUM.VT_BOOL;\nenum VT_FONT = VARENUM.VT_DISPATCH;\nenum VT_PICTURE = VARENUM.VT_DISPATCH;\nenum VT_HANDLE = VARENUM.VT_I4;\n\nenum {\n    OCM__BASE = WM_USER + 0x1c00,\n    OCM_COMMAND = OCM__BASE + WM_COMMAND,\n    OCM_CTLCOLORBTN = OCM__BASE + WM_CTLCOLORBTN,\n    OCM_CTLCOLOREDIT = OCM__BASE + WM_CTLCOLOREDIT,\n    OCM_CTLCOLORDLG = OCM__BASE + WM_CTLCOLORDLG,\n    OCM_CTLCOLORLISTBOX = OCM__BASE + WM_CTLCOLORLISTBOX,\n    OCM_CTLCOLORMSGBOX = OCM__BASE + WM_CTLCOLORMSGBOX,\n    OCM_CTLCOLORSCROLLBAR = OCM__BASE + WM_CTLCOLORSCROLLBAR,\n    OCM_CTLCOLORSTATIC = OCM__BASE + WM_CTLCOLORSTATIC,\n    OCM_DRAWITEM = OCM__BASE + WM_DRAWITEM,\n    OCM_MEASUREITEM = OCM__BASE + WM_MEASUREITEM,\n    OCM_DELETEITEM = OCM__BASE + WM_DELETEITEM,\n    OCM_VKEYTOITEM = OCM__BASE + WM_VKEYTOITEM,\n    OCM_CHARTOITEM = OCM__BASE + WM_CHARTOITEM,\n    OCM_COMPAREITEM = OCM__BASE + WM_COMPAREITEM,\n    OCM_HSCROLL = OCM__BASE + WM_HSCROLL,\n    OCM_VSCROLL = OCM__BASE + WM_VSCROLL,\n    OCM_PARENTNOTIFY = OCM__BASE + WM_PARENTNOTIFY,\n    OCM_NOTIFY = OCM__BASE + WM_NOTIFY\n}\n\nenum {\n    CTRLINFO_EATS_RETURN = 1,\n    CTRLINFO_EATS_ESCAPE\n}\n\nenum {\n    XFORMCOORDS_POSITION            = 1,\n    XFORMCOORDS_SIZE                = 2,\n    XFORMCOORDS_HIMETRICTOCONTAINER = 4,\n    XFORMCOORDS_CONTAINERTOHIMETRIC = 8\n}\n\nenum GUIDKIND_DEFAULT_SOURCE_DISP_IID = 1;\n\nenum {\n    PROPPAGESTATUS_DIRTY = 1,\n    PROPPAGESTATUS_VALIDATE = 2\n}\n\nenum {\n    PICTURE_SCALABLE = 1,\n    PICTURE_TRANSPARENT = 2\n}\n\nenum {\n    PICTYPE_UNINITIALIZED  =  -1,\n    PICTYPE_NONE,       // = 0\n    PICTYPE_BITMAP,\n    PICTYPE_METAFILE,\n    PICTYPE_ICON,\n    PICTYPE_ENHMETAFILE // = 4\n}\n\nenum {\n    DISPID_AUTOSIZE = -500,\n    DISPID_BACKCOLOR = -501,\n    DISPID_BACKSTYLE = -502,\n    DISPID_BORDERCOLOR = -503,\n    DISPID_BORDERSTYLE = -504,\n    DISPID_BORDERWIDTH = -505,\n    DISPID_DRAWMODE = -507,\n    DISPID_DRAWSTYLE = -508,\n    DISPID_DRAWWIDTH = -509,\n    DISPID_FILLCOLOR = -510,\n    DISPID_FILLSTYLE = -511,\n    DISPID_FONT = -512,\n    DISPID_FORECOLOR = -513,\n    DISPID_ENABLED = -514,\n    DISPID_HWND = -515,\n    DISPID_TABSTOP = -516,\n    DISPID_TEXT = -517,\n    DISPID_CAPTION = -518,\n    DISPID_BORDERVISIBLE = -519,\n    DISPID_APPEARANCE = -520,\n    DISPID_MOUSEPOINTER = -521,\n    DISPID_MOUSEICON = -522,\n    DISPID_PICTURE = -523,\n    DISPID_VALID = -524,\n    DISPID_REFRESH = -550,\n    DISPID_DOCLICK = -551,\n    DISPID_ABOUTBOX = -552,\n    DISPID_CLICK = -600,\n    DISPID_DBLCLICK = -601,\n    DISPID_KEYDOWN = -602,\n    DISPID_KEYPRESS = -603,\n    DISPID_KEYUP = -604,\n    DISPID_MOUSEDOWN = -605,\n    DISPID_MOUSEMOVE = -606,\n    DISPID_MOUSEUP = -607,\n    DISPID_ERROREVENT = -608,\n    DISPID_AMBIENT_BACKCOLOR = -701,\n    DISPID_AMBIENT_DISPLAYNAME = -702,\n    DISPID_AMBIENT_FONT = -703,\n    DISPID_AMBIENT_FORECOLOR = -704,\n    DISPID_AMBIENT_LOCALEID = -705,\n    DISPID_AMBIENT_MESSAGEREFLECT = -706,\n    DISPID_AMBIENT_SCALEUNITS = -707,\n    DISPID_AMBIENT_TEXTALIGN = -708,\n    DISPID_AMBIENT_USERMODE = -709,\n    DISPID_AMBIENT_UIDEAD = -710,\n    DISPID_AMBIENT_SHOWGRABHANDLES = -711,\n    DISPID_AMBIENT_SHOWHATCHING = -712,\n    DISPID_AMBIENT_DISPLAYASDEFAULT = -713,\n    DISPID_AMBIENT_SUPPORTSMNEMONICS = -714,\n    DISPID_AMBIENT_AUTOCLIP = -715,\n    DISPID_AMBIENT_APPEARANCE = -716,\n    DISPID_AMBIENT_CODEPAGE = -725,\n    DISPID_AMBIENT_PALETTE = -726,\n    DISPID_AMBIENT_CHARSET = -727,\n    DISPID_AMBIENT_RIGHTTOLEFT = -732,\n    DISPID_AMBIENT_TOPTOBOTTOM = -733\n}\n\nenum {\n    DISPID_FONT_NAME = 0,\n    DISPID_FONT_SIZE = 2,\n    DISPID_FONT_BOLD,\n    DISPID_FONT_ITALIC,\n    DISPID_FONT_UNDER,\n    DISPID_FONT_STRIKE,\n    DISPID_FONT_WEIGHT,\n    DISPID_FONT_CHARSET // = 8\n}\n\nenum {\n    DISPID_PICT_HANDLE = 0,\n    DISPID_PICT_HPAL   = 2,\n    DISPID_PICT_TYPE,\n    DISPID_PICT_WIDTH,\n    DISPID_PICT_HEIGHT,\n    DISPID_PICT_RENDER // = 6\n}\n\nalias IOleControl LPOLECONTROL;\nalias IOleControlSite LPOLECONTROLSITE;\nalias ISimpleFrameSite LPSIMPLEFRAMESITE;\nalias IPersistPropertyBag LPPERSISTPROPERTYBAG;\nalias IPersistStreamInit LPPERSISTSTREAMINIT;\nalias IPersistMemory LPPERSISTMEMORY;\nalias IPropertyNotifySink LPPROPERTYNOTIFYSINK;\nalias IProvideClassInfo LPPROVIDECLASSINFO;\nalias IProvideClassInfo2 LPPROVIDECLASSINFO2;\nalias IConnectionPointContainer LPCONNECTIONPOINTCONTAINER;\nalias IClassFactory2 LPCLASSFACTORY2;\nalias ISpecifyPropertyPages LPSPECIFYPROPERTYPAGES;\nalias IPerPropertyBrowsing LPPERPROPERTYBROWSING;\nalias IPropertyPage LPPROPERTYPAGE;\nalias IPropertyPage2 LPPROPERTYPAGE2;\n\nalias IPicture LPPICTURE;\nalias IPictureDisp LPPICTUREDISP;\nalias int OLE_XPOS_PIXELS;\nalias int OLE_YPOS_PIXELS;\nalias int OLE_XSIZE_PIXELS;\nalias int OLE_YSIZE_PIXELS;\nalias float OLE_XPOS_CONTAINER;\nalias float OLE_YPOS_CONTAINER;\nalias float OLE_XSIZE_CONTAINER;\n\nalias VARIANT_BOOL OLE_OPTEXCLUSIVE;\nalias VARIANT_BOOL OLE_CANCELBOOL;\nalias VARIANT_BOOL OLE_ENABLEDEFAULTBOOL;\n\nalign(8):\n\nenum OLE_TRISTATE {\n    triUnchecked,\n    triChecked1,\n    triGray\n}\n\nstruct OCPFIPARAMS {\n    ULONG cbStructSize;\n    HWND hWndOwner;\n    int x;\n    int y;\n    LPCOLESTR lpszCaption;\n    ULONG cObjects;\n    LPUNKNOWN *lplpUnk;\n    ULONG cPages;\n    CLSID *lpPages;\n    LCID lcid;\n    DISPID dispidInitialProperty;\n}\nalias OCPFIPARAMS* LPOCPFIPARAMS;\n\nstruct FONTDESC {\n    UINT cbSizeofstruct;\n    LPOLESTR lpstrName;\n    CY cySize;\n    SHORT sWeight;\n    SHORT sCharset;\n    BOOL fItalic;\n    BOOL fUnderline;\n    BOOL fStrikethrough;\n}\nalias FONTDESC* LPFONTDESC;\n\nstruct PICTDESC\n{\n    UINT cbSizeofstruct;\n    UINT picType;\n    union {\n        struct _bmp {\n            HBITMAP hbitmap;\n            HPALETTE hpal;\n        }\n        _bmp bmp;\n        struct _wmf {\n            HMETAFILE hmeta;\n            int xExt;\n            int yExt;\n        }\n        _wmf wmf;\n        struct _icon {\n            HICON hicon;\n        }\n        _icon icon;\n        struct _emf {\n            HENHMETAFILE hemf;\n        }\n        _emf emf;\n    }\n}\nalias PICTDESC* LPPICTDESC;\n\nextern(Windows) {\n    HRESULT DllRegisterServer();\n    HRESULT DllUnregisterServer();\n    HRESULT OleCreateFontIndirect(LPFONTDESC, REFIID, PVOID*);\n    HRESULT OleCreatePictureIndirect(LPPICTDESC, REFIID, BOOL, PVOID*);\n    HRESULT OleCreatePropertyFrame(HWND, UINT, UINT, LPCOLESTR, ULONG, LPUNKNOWN*, ULONG, LPCLSID, LCID, DWORD, PVOID);\n    HRESULT OleCreatePropertyFrameIndirect(LPOCPFIPARAMS);\n    HCURSOR OleIconToCursor(HINSTANCE, HICON);\n    HRESULT OleLoadPicture(LPSTREAM, LONG, BOOL, REFIID, PVOID*);\n    HRESULT OleLoadPictureEx(LPSTREAM, LONG, BOOL, REFIID, DWORD, DWORD, DWORD, LPVOID*);\n    HRESULT OleLoadPicturePath(LPOLESTR, LPUNKNOWN, DWORD, OLE_COLOR, REFIID, LPVOID*);\n    HRESULT OleLoadPictureFile(VARIANT, LPDISPATCH*);\n    HRESULT OleLoadPictureFileEx(VARIANT, DWORD, DWORD, DWORD, LPDISPATCH*);\n    HRESULT OleSavePictureFile(LPDISPATCH, BSTR);\n    HRESULT OleTranslateColor(OLE_COLOR, HPALETTE, COLORREF*);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/olectlid.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_olectlid.d)\n */\nmodule core.sys.windows.olectlid;\nversion (Windows):\n\nprivate import core.sys.windows.basetyps;\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/oledlg.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_oledlg.d)\n */\nmodule core.sys.windows.oledlg;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nimport core.sys.windows.commdlg, core.sys.windows.dlgs, core.sys.windows.ole2, core.sys.windows.prsht, core.sys.windows.shellapi,\n  core.sys.windows.windows;\nprivate import core.sys.windows.winbase, core.sys.windows.objidl, core.sys.windows.objfwd, core.sys.windows.winnt;\n\n// FIXME: remove inherited methods from interface definitions\n\nenum PS_MAXLINKTYPES=8;\n\nconst TCHAR[] OLESTDDELIM = \"\\\\\";\nconst TCHAR[] SZOLEUI_MSG_HELP = \"OLEUI_MSG_HELP\";\nconst TCHAR[] SZOLEUI_MSG_ENDDIALOG = \"OLEUI_MSG_ENDDIALOG\";\nconst TCHAR[] SZOLEUI_MSG_BROWSE = \"OLEUI_MSG_BROWSE\";\nconst TCHAR[] SZOLEUI_MSG_CHANGEICON = \"OLEUI_MSG_CHANGEICON\";\nconst TCHAR[] SZOLEUI_MSG_CLOSEBUSYDIALOG = \"OLEUI_MSG_CLOSEBUSYDIALOG\";\nconst TCHAR[] SZOLEUI_MSG_CONVERT = \"OLEUI_MSG_CONVERT\";\nconst TCHAR[] SZOLEUI_MSG_CHANGESOURCE = \"OLEUI_MSG_CHANGESOURCE\";\nconst TCHAR[] SZOLEUI_MSG_ADDCONTROL = \"OLEUI_MSG_ADDCONTROL\";\nconst TCHAR[] SZOLEUI_MSG_BROWSE_OFN = \"OLEUI_MSG_BROWSE_OFN\";\n\nconst TCHAR[] PROP_HWND_CHGICONDLG = \"HWND_CIDLG\";\n\nenum IDC_OLEUIHELP=99;\n\nenum {\n    IDC_IO_CREATENEW = 2100,\n    IDC_IO_CREATEFROMFILE,\n    IDC_IO_LINKFILE,\n    IDC_IO_OBJECTTYPELIST,\n    IDC_IO_DISPLAYASICON,\n    IDC_IO_CHANGEICON,\n    IDC_IO_FILE,\n    IDC_IO_FILEDISPLAY,\n    IDC_IO_RESULTIMAGE,\n    IDC_IO_RESULTTEXT,\n    IDC_IO_ICONDISPLAY,\n    IDC_IO_OBJECTTYPETEXT,\n    IDC_IO_FILETEXT,\n    IDC_IO_FILETYPE,\n    IDC_IO_INSERTCONTROL,\n    IDC_IO_ADDCONTROL,\n    IDC_IO_CONTROLTYPELIST // = 2116\n}\n\nenum IDC_PS_PASTE=500;\nenum IDC_PS_PASTELINK=501;\nenum IDC_PS_SOURCETEXT=502;\nenum IDC_PS_PASTELIST=503;\nenum IDC_PS_PASTELINKLIST=504;\nenum IDC_PS_DISPLAYLIST=505;\nenum IDC_PS_DISPLAYASICON=506;\nenum IDC_PS_ICONDISPLAY=507;\nenum IDC_PS_CHANGEICON=508;\nenum IDC_PS_RESULTIMAGE=509;\nenum IDC_PS_RESULTTEXT=510;\n\nenum IDC_CI_GROUP=120;\nenum IDC_CI_CURRENT=121;\nenum IDC_CI_CURRENTICON=122;\nenum IDC_CI_DEFAULT=123;\nenum IDC_CI_DEFAULTICON=124;\nenum IDC_CI_FROMFILE=125;\nenum IDC_CI_FROMFILEEDIT=126;\nenum IDC_CI_ICONLIST=127;\nenum IDC_CI_LABEL=128;\nenum IDC_CI_LABELEDIT=129;\nenum IDC_CI_BROWSE=130;\nenum IDC_CI_ICONDISPLAY=131;\n\nenum IDC_CV_OBJECTTYPE=150;\nenum IDC_CV_DISPLAYASICON=152;\nenum IDC_CV_CHANGEICON=153;\nenum IDC_CV_ACTIVATELIST=154;\nenum IDC_CV_CONVERTTO=155;\nenum IDC_CV_ACTIVATEAS=156;\nenum IDC_CV_RESULTTEXT=157;\nenum IDC_CV_CONVERTLIST=158;\nenum IDC_CV_ICONDISPLAY=165;\n\nenum IDC_EL_CHANGESOURCE=201;\nenum IDC_EL_AUTOMATIC=202;\nenum IDC_EL_CANCELLINK=209;\nenum IDC_EL_UPDATENOW=210;\nenum IDC_EL_OPENSOURCE=211;\nenum IDC_EL_MANUAL=212;\nenum IDC_EL_LINKSOURCE=216;\nenum IDC_EL_LINKTYPE=217;\nenum IDC_EL_LINKSLISTBOX=206;\nenum IDC_EL_COL1=220;\nenum IDC_EL_COL2=221;\nenum IDC_EL_COL3=222;\n\nenum IDC_BZ_RETRY=600;\nenum IDC_BZ_ICON=601;\nenum IDC_BZ_MESSAGE1=602;\nenum IDC_BZ_SWITCHTO=604;\n\nenum IDC_UL_METER=1029;\nenum IDC_UL_STOP=1030;\nenum IDC_UL_PERCENT=1031;\nenum IDC_UL_PROGRESS=1032;\n\nenum IDC_PU_LINKS=900;\nenum IDC_PU_TEXT=901;\nenum IDC_PU_CONVERT=902;\nenum IDC_PU_ICON=908;\n\nenum IDC_GP_OBJECTNAME=1009;\nenum IDC_GP_OBJECTTYPE=1010;\nenum IDC_GP_OBJECTSIZE=1011;\nenum IDC_GP_CONVERT=1013;\nenum IDC_GP_OBJECTICON=1014;\nenum IDC_GP_OBJECTLOCATION=1022;\n\nenum IDC_VP_PERCENT=1000;\nenum IDC_VP_CHANGEICON=1001;\nenum IDC_VP_EDITABLE=1002;\nenum IDC_VP_ASICON=1003;\nenum IDC_VP_RELATIVE=1005;\nenum IDC_VP_SPIN=1006;\nenum IDC_VP_SCALETXT=1034;\nenum IDC_VP_ICONDISPLAY=1021;\nenum IDC_VP_RESULTIMAGE=1033;\n\nenum IDC_LP_OPENSOURCE=1006;\nenum IDC_LP_UPDATENOW=1007;\nenum IDC_LP_BREAKLINK=1008;\nenum IDC_LP_LINKSOURCE=1012;\nenum IDC_LP_CHANGESOURCE=1015;\nenum IDC_LP_AUTOMATIC=1016;\nenum IDC_LP_MANUAL=1017;\nenum IDC_LP_DATE=1018;\nenum IDC_LP_TIME=1019;\n\nenum IDD_INSERTOBJECT=1000;\nenum IDD_CHANGEICON=1001;\nenum IDD_CONVERT=1002;\nenum IDD_PASTESPECIAL=1003;\nenum IDD_EDITLINKS=1004;\nenum IDD_BUSY=1006;\nenum IDD_UPDATELINKS=1007;\nenum IDD_CHANGESOURCE=1009;\nenum IDD_INSERTFILEBROWSE=1010;\nenum IDD_CHANGEICONBROWSE=1011;\nenum IDD_CONVERTONLY=1012;\nenum IDD_CHANGESOURCE4=1013;\nenum IDD_GNRLPROPS=1100;\nenum IDD_VIEWPROPS=1101;\nenum IDD_LINKPROPS=1102;\nenum IDD_CANNOTUPDATELINK=1008;\nenum IDD_LINKSOURCEUNAVAILABLE=1020;\nenum IDD_SERVERNOTFOUND=1023;\nenum IDD_OUTOFMEMORY=1024;\nenum IDD_SERVERNOTREGW=1021;\nenum IDD_LINKTYPECHANGEDW=1022;\nenum IDD_SERVERNOTREGA=1025;\nenum IDD_LINKTYPECHANGEDA=1026;\n\nenum ID_BROWSE_CHANGEICON=1;\nenum ID_BROWSE_INSERTFILE=2;\nenum ID_BROWSE_ADDCONTROL=3;\nenum ID_BROWSE_CHANGESOURCE=4;\n\nenum OLEUI_FALSE=0;\nenum OLEUI_SUCCESS=1;\nenum OLEUI_OK=1;\nenum OLEUI_CANCEL=2;\n\nenum OLEUI_ERR_STANDARDMIN=100;\nenum OLEUI_ERR_STRUCTURENULL=101;\nenum OLEUI_ERR_STRUCTUREINVALID=102;\nenum OLEUI_ERR_CBSTRUCTINCORRECT=103;\nenum OLEUI_ERR_HWNDOWNERINVALID=104;\nenum OLEUI_ERR_LPSZCAPTIONINVALID=105;\nenum OLEUI_ERR_LPFNHOOKINVALID=106;\nenum OLEUI_ERR_HINSTANCEINVALID=107;\nenum OLEUI_ERR_LPSZTEMPLATEINVALID=108;\nenum OLEUI_ERR_HRESOURCEINVALID=109;\nenum OLEUI_ERR_FINDTEMPLATEFAILURE=110;\nenum OLEUI_ERR_LOADTEMPLATEFAILURE=111;\nenum OLEUI_ERR_DIALOGFAILURE=112;\nenum OLEUI_ERR_LOCALMEMALLOC=113;\nenum OLEUI_ERR_GLOBALMEMALLOC=114;\nenum OLEUI_ERR_LOADSTRING=115;\nenum OLEUI_ERR_OLEMEMALLOC=116;\nenum OLEUI_ERR_STANDARDMAX=116;\n\nenum OPF_OBJECTISLINK=1;\nenum OPF_NOFILLDEFAULT=2;\nenum OPF_SHOWHELP=4;\nenum OPF_DISABLECONVERT=8;\n\nenum OLEUI_OPERR_SUBPROPNULL=OLEUI_ERR_STANDARDMAX;\nenum OLEUI_OPERR_SUBPROPINVALID=(OLEUI_ERR_STANDARDMAX+1);\nenum OLEUI_OPERR_PROPSHEETNULL=(OLEUI_ERR_STANDARDMAX+2);\nenum OLEUI_OPERR_PROPSHEETINVALID=(OLEUI_ERR_STANDARDMAX+3);\nenum OLEUI_OPERR_SUPPROP=(OLEUI_ERR_STANDARDMAX+4);\nenum OLEUI_OPERR_PROPSINVALID=(OLEUI_ERR_STANDARDMAX+5);\nenum OLEUI_OPERR_PAGESINCORRECT=(OLEUI_ERR_STANDARDMAX+6);\nenum OLEUI_OPERR_INVALIDPAGES=(OLEUI_ERR_STANDARDMAX+7);\nenum OLEUI_OPERR_NOTSUPPORTED=(OLEUI_ERR_STANDARDMAX+8);\nenum OLEUI_OPERR_DLGPROCNOTNULL=(OLEUI_ERR_STANDARDMAX+9);\nenum OLEUI_OPERR_LPARAMNOTZERO=(OLEUI_ERR_STANDARDMAX+10);\nenum OLEUI_GPERR_STRINGINVALID=(OLEUI_ERR_STANDARDMAX+11);\nenum OLEUI_GPERR_CLASSIDINVALID=(OLEUI_ERR_STANDARDMAX+12);\nenum OLEUI_GPERR_LPCLSIDEXCLUDEINVALID=(OLEUI_ERR_STANDARDMAX+13);\nenum OLEUI_GPERR_CBFORMATINVALID=(OLEUI_ERR_STANDARDMAX+14);\nenum OLEUI_VPERR_METAPICTINVALID=(OLEUI_ERR_STANDARDMAX+15);\nenum OLEUI_VPERR_DVASPECTINVALID=(OLEUI_ERR_STANDARDMAX+16);\nenum OLEUI_LPERR_LINKCNTRNULL=(OLEUI_ERR_STANDARDMAX+17);\nenum OLEUI_LPERR_LINKCNTRINVALID=(OLEUI_ERR_STANDARDMAX+18);\nenum OLEUI_OPERR_PROPERTYSHEET=(OLEUI_ERR_STANDARDMAX+19);\nenum OLEUI_OPERR_OBJINFOINVALID=(OLEUI_ERR_STANDARDMAX+20);\nenum OLEUI_OPERR_LINKINFOINVALID=(OLEUI_ERR_STANDARDMAX+21);\n\nenum OLEUI_QUERY_GETCLASSID=65280;\nenum OLEUI_QUERY_LINKBROKEN=65281;\n\nenum IOF_SHOWHELP=1;\nenum IOF_SELECTCREATENEW=2;\nenum IOF_SELECTCREATEFROMFILE=4;\nenum IOF_CHECKLINK=8;\nenum IOF_CHECKDISPLAYASICON=16;\nenum IOF_CREATENEWOBJECT=32;\nenum IOF_CREATEFILEOBJECT=64;\nenum IOF_CREATELINKOBJECT=128;\nenum IOF_DISABLELINK=256;\nenum IOF_VERIFYSERVERSEXIST=512;\nenum IOF_DISABLEDISPLAYASICON=1024;\nenum IOF_HIDECHANGEICON=2048;\nenum IOF_SHOWINSERTCONTROL=4096;\nenum IOF_SELECTCREATECONTROL=8192;\n\nenum OLEUI_IOERR_LPSZFILEINVALID=OLEUI_ERR_STANDARDMAX;\nenum OLEUI_IOERR_LPSZLABELINVALID=(OLEUI_ERR_STANDARDMAX+1);\nenum OLEUI_IOERR_HICONINVALID=(OLEUI_ERR_STANDARDMAX+2);\nenum OLEUI_IOERR_LPFORMATETCINVALID=(OLEUI_ERR_STANDARDMAX+3);\nenum OLEUI_IOERR_PPVOBJINVALID=(OLEUI_ERR_STANDARDMAX+4);\nenum OLEUI_IOERR_LPIOLECLIENTSITEINVALID=(OLEUI_ERR_STANDARDMAX+5);\nenum OLEUI_IOERR_LPISTORAGEINVALID=(OLEUI_ERR_STANDARDMAX+6);\nenum OLEUI_IOERR_SCODEHASERROR=(OLEUI_ERR_STANDARDMAX+7);\nenum OLEUI_IOERR_LPCLSIDEXCLUDEINVALID=(OLEUI_ERR_STANDARDMAX+8);\nenum OLEUI_IOERR_CCHFILEINVALID=(OLEUI_ERR_STANDARDMAX+9);\n\nenum PSF_SHOWHELP=1;\nenum PSF_SELECTPASTE=2;\nenum PSF_SELECTPASTELINK=4;\nenum PSF_CHECKDISPLAYASICON=8;\nenum PSF_DISABLEDISPLAYASICON=16;\nenum PSF_HIDECHANGEICON=32;\nenum PSF_STAYONCLIPBOARDCHANGE=64;\nenum PSF_NOREFRESHDATAOBJECT=128;\n\nenum OLEUI_IOERR_SRCDATAOBJECTINVALID=OLEUI_ERR_STANDARDMAX;\nenum OLEUI_IOERR_ARRPASTEENTRIESINVALID=(OLEUI_ERR_STANDARDMAX+1);\nenum OLEUI_IOERR_ARRLINKTYPESINVALID=(OLEUI_ERR_STANDARDMAX+2);\nenum OLEUI_PSERR_CLIPBOARDCHANGED=(OLEUI_ERR_STANDARDMAX+3);\nenum OLEUI_PSERR_GETCLIPBOARDFAILED=(OLEUI_ERR_STANDARDMAX+4);\nenum OLEUI_ELERR_LINKCNTRNULL=OLEUI_ERR_STANDARDMAX;\nenum OLEUI_ELERR_LINKCNTRINVALID=(OLEUI_ERR_STANDARDMAX+1);\n\nenum ELF_SHOWHELP=1;\nenum ELF_DISABLEUPDATENOW=2;\nenum ELF_DISABLEOPENSOURCE=4;\nenum ELF_DISABLECHANGESOURCE=8;\nenum ELF_DISABLECANCELLINK=16;\n\nenum CIF_SHOWHELP=1;\nenum CIF_SELECTCURRENT=2;\nenum CIF_SELECTDEFAULT=4;\nenum CIF_SELECTFROMFILE=8;\nenum CIF_USEICONEXE=16;\n\nenum OLEUI_CIERR_MUSTHAVECLSID=OLEUI_ERR_STANDARDMAX;\nenum OLEUI_CIERR_MUSTHAVECURRENTMETAFILE=OLEUI_ERR_STANDARDMAX+1;\nenum OLEUI_CIERR_SZICONEXEINVALID=OLEUI_ERR_STANDARDMAX+2;\n\nenum CF_SHOWHELPBUTTON=1;\nenum CF_SETCONVERTDEFAULT=2;\nenum CF_SETACTIVATEDEFAULT=4;\nenum CF_SELECTCONVERTTO=8;\nenum CF_SELECTACTIVATEAS=16;\nenum CF_DISABLEDISPLAYASICON=32;\nenum CF_DISABLEACTIVATEAS=64;\nenum CF_HIDECHANGEICON=128;\nenum CF_CONVERTONLY=256;\n\nenum OLEUI_CTERR_CLASSIDINVALID = OLEUI_ERR_STANDARDMAX+1;\nenum OLEUI_CTERR_DVASPECTINVALID = OLEUI_ERR_STANDARDMAX+2;\nenum OLEUI_CTERR_CBFORMATINVALID = OLEUI_ERR_STANDARDMAX+3;\nenum OLEUI_CTERR_HMETAPICTINVALID = OLEUI_ERR_STANDARDMAX+4;\nenum OLEUI_CTERR_STRINGINVALID = OLEUI_ERR_STANDARDMAX+5;\n\nenum BZ_DISABLECANCELBUTTON = 1;\nenum BZ_DISABLESWITCHTOBUTTON = 2;\nenum BZ_DISABLERETRYBUTTON = 4;\nenum BZ_NOTRESPONDINGDIALOG = 8;\n\nenum OLEUI_BZERR_HTASKINVALID = OLEUI_ERR_STANDARDMAX;\nenum OLEUI_BZ_SWITCHTOSELECTED = OLEUI_ERR_STANDARDMAX+1;\nenum OLEUI_BZ_RETRYSELECTED = OLEUI_ERR_STANDARDMAX+2;\nenum OLEUI_BZ_CALLUNBLOCKED = OLEUI_ERR_STANDARDMAX+3;\n\nenum CSF_SHOWHELP = 1;\nenum CSF_VALIDSOURCE = 2;\nenum CSF_ONLYGETSOURCE = 4;\nenum CSF_EXPLORER = 8;\n\nenum OLEUI_CSERR_LINKCNTRNULL = OLEUI_ERR_STANDARDMAX;\nenum OLEUI_CSERR_LINKCNTRINVALID = OLEUI_ERR_STANDARDMAX+1;\nenum OLEUI_CSERR_FROMNOTNULL = OLEUI_ERR_STANDARDMAX+2;\nenum OLEUI_CSERR_TONOTNULL = OLEUI_ERR_STANDARDMAX+3;\nenum OLEUI_CSERR_SOURCENULL = OLEUI_ERR_STANDARDMAX+4;\nenum OLEUI_CSERR_SOURCEINVALID = OLEUI_ERR_STANDARDMAX+5;\nenum OLEUI_CSERR_SOURCEPARSERROR = OLEUI_ERR_STANDARDMAX+6;\nenum OLEUI_CSERR_SOURCEPARSEERROR = OLEUI_ERR_STANDARDMAX+7;\n\nenum VPF_SELECTRELATIVE=1;\nenum VPF_DISABLERELATIVE=2;\nenum VPF_DISABLESCALE=4;\n\nalign(8):\nextern (Windows) {\n    alias UINT function(HWND, UINT, WPARAM, LPARAM) LPFNOLEUIHOOK;\n}\n\nstruct OLEUIINSERTOBJECTW {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCWSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCWSTR lpszTemplate;\n    HRSRC hResource;\n    CLSID clsid;\n    LPWSTR lpszFile;\n    UINT cchFile;\n    UINT cClsidExclude;\n    LPCLSID lpClsidExclude;\n    IID iid;\n    DWORD oleRender;\n    LPFORMATETC lpFormatEtc;\n    LPOLECLIENTSITE lpIOleClientSite;\n    LPSTORAGE lpIStorage;\n    PVOID *ppvObj;\n    SCODE sc;\n    HGLOBAL hMetaPict;\n}\nalias OLEUIINSERTOBJECTW* POLEUIINSERTOBJECTW, LPOLEUIINSERTOBJECTW;\n\nstruct OLEUIINSERTOBJECTA {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCSTR lpszTemplate;\n    HRSRC hResource;\n    CLSID clsid;\n    LPSTR lpszFile;\n    UINT cchFile;\n    UINT cClsidExclude;\n    LPCLSID lpClsidExclude;\n    IID iid;\n    DWORD oleRender;\n    LPFORMATETC lpFormatEtc;\n    LPOLECLIENTSITE lpIOleClientSite;\n    LPSTORAGE lpIStorage;\n    PVOID *ppvObj;\n    SCODE sc;\n    HGLOBAL hMetaPict;\n}\nalias OLEUIINSERTOBJECTA* POLEUIINSERTOBJECTA, LPOLEUIINSERTOBJECTA;\n\nextern (Windows) {\n    UINT OleUIInsertObjectW(LPOLEUIINSERTOBJECTW);\n    UINT OleUIInsertObjectA(LPOLEUIINSERTOBJECTA);\n}\n\nenum OLEUIPASTEFLAG {\n    OLEUIPASTE_PASTEONLY,\n    OLEUIPASTE_LINKTYPE1,\n    OLEUIPASTE_LINKTYPE2,\n    OLEUIPASTE_LINKTYPE3 = 4,\n    OLEUIPASTE_LINKTYPE4 = 8,\n    OLEUIPASTE_LINKTYPE5 = 16,\n    OLEUIPASTE_LINKTYPE6 = 32,\n    OLEUIPASTE_LINKTYPE7 = 64,\n    OLEUIPASTE_LINKTYPE8 = 128,\n    OLEUIPASTE_PASTE = 512,\n    OLEUIPASTE_LINKANYTYPE = 1024,\n    OLEUIPASTE_ENABLEICON = 2048\n}\n\nstruct OLEUIPASTEENTRYW {\n    FORMATETC fmtetc;\n    LPCWSTR lpstrFormatName;\n    LPCWSTR lpstrResultText;\n    DWORD dwFlags;\n    DWORD dwScratchSpace;\n}\nalias OLEUIPASTEENTRYW* POLEUIPASTEENTRYW, LPOLEUIPASTEENTRYW;\n\nstruct OLEUIPASTEENTRYA {\n    FORMATETC fmtetc;\n    LPCSTR lpstrFormatName;\n    LPCSTR lpstrResultText;\n    DWORD dwFlags;\n    DWORD dwScratchSpace;\n}\nalias OLEUIPASTEENTRYA* POLEUIPASTEENTRYA, LPOLEUIPASTEENTRYA;\n\nstruct OLEUIPASTESPECIALW {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCWSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCWSTR lpszTemplate;\n    HRSRC hResource;\n    LPDATAOBJECT lpSrcDataObj;\n    LPOLEUIPASTEENTRYW arrPasteEntries;\n    int cPasteEntries;\n    UINT *arrLinkTypes;\n    int cLinkTypes;\n    UINT cClsidExclude;\n    LPCLSID lpClsidExclude;\n    int nSelectedIndex;\n    BOOL fLink;\n    HGLOBAL hMetaPict;\n    SIZEL sizel;\n}\nalias OLEUIPASTESPECIALW* POLEUIPASTESPECIALW, LPOLEUIPASTESPECIALW;\n\nstruct OLEUIPASTESPECIALA {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCSTR lpszTemplate;\n    HRSRC hResource;\n    LPDATAOBJECT lpSrcDataObj;\n    LPOLEUIPASTEENTRYA arrPasteEntries;\n    int cPasteEntries;\n    UINT* arrLinkTypes;\n    int cLinkTypes;\n    UINT cClsidExclude;\n    LPCLSID lpClsidExclude;\n    int nSelectedIndex;\n    BOOL fLink;\n    HGLOBAL hMetaPict;\n    SIZEL sizel;\n}\nalias OLEUIPASTESPECIALA* POLEUIPASTESPECIALA, LPOLEUIPASTESPECIALA;\n\ninterface IOleUILinkContainerW : IUnknown\n{\n    HRESULT QueryInterface(REFIID, PVOID*);\n    ULONG AddRef();\n    ULONG Release();\n    DWORD GetNextLink(DWORD dwLink);\n    HRESULT SetLinkUpdateOptions(DWORD, DWORD);\n    HRESULT GetLinkUpdateOptions(DWORD, PDWORD);\n    HRESULT SetLinkSource(DWORD, LPWSTR, ULONG, PULONG, BOOL);\n    HRESULT GetLinkSource(DWORD, LPWSTR*, PULONG, LPWSTR*, LPWSTR*, BOOL*, BOOL*);\n    HRESULT OpenLinkSource(DWORD);\n    HRESULT UpdateLink(DWORD, BOOL, BOOL);\n    HRESULT CancelLink(DWORD);\n}\nalias IOleUILinkContainerW LPOLEUILINKCONTAINERW;\n\ninterface IOleUILinkContainerA : IUnknown\n{\n    HRESULT QueryInterface(REFIID, PVOID*);\n    ULONG AddRef();\n    ULONG Release();\n    DWORD GetNextLink(DWORD);\n    HRESULT SetLinkUpdateOptions(DWORD, DWORD);\n    HRESULT GetLinkUpdateOptions(DWORD, PDWORD);\n    HRESULT SetLinkSource(DWORD, LPSTR, ULONG, PULONG, BOOL);\n    HRESULT GetLinkSource(DWORD, LPSTR*, PULONG, LPSTR*, LPSTR*, BOOL*, BOOL*);\n    HRESULT OpenLinkSource(DWORD);\n    HRESULT UpdateLink(DWORD, BOOL, BOOL);\n    HRESULT CancelLink(DWORD);\n}\nalias IOleUILinkContainerA LPOLEUILINKCONTAINERA;\n\nstruct OLEUIEDITLINKSW {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCWSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCWSTR lpszTemplate;\n    HRSRC hResource;\n    LPOLEUILINKCONTAINERW lpOleUILinkContainer;\n}\nalias OLEUIEDITLINKSW* POLEUIEDITLINKSW, LPOLEUIEDITLINKSW;\n\nstruct OLEUIEDITLINKSA {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCSTR lpszTemplate;\n    HRSRC hResource;\n    LPOLEUILINKCONTAINERA lpOleUILinkContainer;\n}\nalias OLEUIEDITLINKSA* POLEUIEDITLINKSA, LPOLEUIEDITLINKSA;\n\nstruct OLEUICHANGEICONW {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCWSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCWSTR lpszTemplate;\n    HRSRC hResource;\n    HGLOBAL hMetaPict;\n    CLSID clsid;\n    WCHAR[MAX_PATH] szIconExe;\n    int cchIconExe;\n}\nalias OLEUICHANGEICONW* POLEUICHANGEICONW, LPOLEUICHANGEICONW;\n\nstruct OLEUICHANGEICONA {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCSTR lpszTemplate;\n    HRSRC hResource;\n    HGLOBAL hMetaPict;\n    CLSID clsid;\n    CHAR[MAX_PATH] szIconExe;\n    int cchIconExe;\n}\nalias OLEUICHANGEICONA* POLEUICHANGEICONA, LPOLEUICHANGEICONA;\n\nstruct OLEUICONVERTW {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCWSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCWSTR lpszTemplate;\n    HRSRC hResource;\n    CLSID clsid;\n    CLSID clsidConvertDefault;\n    CLSID clsidActivateDefault;\n    CLSID clsidNew;\n    DWORD dvAspect;\n    WORD wFormat;\n    BOOL fIsLinkedObject;\n    HGLOBAL hMetaPict;\n    LPWSTR lpszUserType;\n    BOOL fObjectsIconChanged;\n    LPWSTR lpszDefLabel;\n    UINT cClsidExclude;\n    LPCLSID lpClsidExclude;\n}\nalias OLEUICONVERTW* POLEUICONVERTW, LPOLEUICONVERTW;\n\nstruct OLEUICONVERTA {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCSTR lpszTemplate;\n    HRSRC hResource;\n    CLSID clsid;\n    CLSID clsidConvertDefault;\n    CLSID clsidActivateDefault;\n    CLSID clsidNew;\n    DWORD dvAspect;\n    WORD wFormat;\n    BOOL fIsLinkedObject;\n    HGLOBAL hMetaPict;\n    LPSTR lpszUserType;\n    BOOL fObjectsIconChanged;\n    LPSTR lpszDefLabel;\n    UINT cClsidExclude;\n    LPCLSID lpClsidExclude;\n}\nalias OLEUICONVERTA* POLEUICONVERTA, LPOLEUICONVERTA;\n\nstruct OLEUIBUSYW {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCWSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCWSTR lpszTemplate;\n    HRSRC hResource;\n    HTASK hTask;\n    HWND *lphWndDialog;\n}\nalias OLEUIBUSYW* POLEUIBUSYW, LPOLEUIBUSYW;\n\nstruct OLEUIBUSYA {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCSTR lpszTemplate;\n    HRSRC hResource;\n    HTASK hTask;\n    HWND *lphWndDialog;\n}\nalias OLEUIBUSYA* POLEUIBUSYA, LPOLEUIBUSYA;\n\nstruct OLEUICHANGESOURCEW {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCWSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCWSTR lpszTemplate;\n    HRSRC hResource;\n    OPENFILENAMEW* lpOFN;\n    DWORD[4] dwReserved1;\n    LPOLEUILINKCONTAINERW lpOleUILinkContainer;\n    DWORD dwLink;\n    LPWSTR lpszDisplayName;\n    ULONG nFileLength;\n    LPWSTR lpszFrom;\n    LPWSTR lpszTo;\n}\nalias OLEUICHANGESOURCEW* POLEUICHANGESOURCEW, LPOLEUICHANGESOURCEW;\n\nstruct OLEUICHANGESOURCEA {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    HWND hWndOwner;\n    LPCSTR lpszCaption;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    HINSTANCE hInstance;\n    LPCSTR lpszTemplate;\n    HRSRC hResource;\n    OPENFILENAMEA *lpOFN;\n    DWORD[4] dwReserved1;\n    LPOLEUILINKCONTAINERA lpOleUILinkContainer;\n    DWORD dwLink;\n    LPSTR lpszDisplayName;\n    ULONG nFileLength;\n    LPSTR lpszFrom;\n    LPSTR lpszTo;\n}\nalias OLEUICHANGESOURCEA* POLEUICHANGESOURCEA, LPOLEUICHANGESOURCEA;\n\ninterface IOleUIObjInfoW : IUnknown\n{\n    HRESULT QueryInterface(REFIID, PVOID*);\n    ULONG AddRef();\n    ULONG Release();\n    HRESULT GetObjectInfo(DWORD, PDWORD, LPWSTR*, LPWSTR*, LPWSTR*, LPWSTR*);\n    HRESULT GetConvertInfo(DWORD, CLSID*, PWORD, CLSID*, LPCLSID*, UINT*);\n    HRESULT ConvertObject(DWORD, REFCLSID);\n    HRESULT GetViewInfo(DWORD, HGLOBAL*, PDWORD, int*);\n    HRESULT SetViewInfo(DWORD, HGLOBAL, DWORD, int, BOOL);\n}\nalias IOleUIObjInfoW LPOLEUIOBJINFOW;\n\ninterface IOleUIObjInfoA : IUnknown\n{\n    HRESULT QueryInterface(REFIID, PVOID*);\n    ULONG AddRef();\n    ULONG Release();\n    HRESULT GetObjectInfo(DWORD, PDWORD, LPSTR*, LPSTR*, LPSTR*, LPSTR*);\n    HRESULT GetConvertInfo(DWORD, CLSID*, PWORD, CLSID*, LPCLSID*, UINT*);\n    HRESULT ConvertObject(DWORD, REFCLSID);\n    HRESULT GetViewInfo(DWORD, HGLOBAL*, PDWORD, int*);\n    HRESULT SetViewInfo(DWORD, HGLOBAL, DWORD, int, BOOL);\n}\nalias IOleUIObjInfoA LPOLEUIOBJINFOA;\n\ninterface IOleUILinkInfoW : IOleUILinkContainerW\n{\n    HRESULT QueryInterface(REFIID, PVOID*);\n    ULONG AddRef();\n    ULONG Release();\n    DWORD GetNextLink(DWORD);\n    HRESULT SetLinkUpdateOptions(DWORD, DWORD);\n    HRESULT GetLinkUpdateOptions(DWORD, DWORD*);\n    HRESULT SetLinkSource(DWORD, LPWSTR, ULONG, PULONG, BOOL);\n    HRESULT GetLinkSource(DWORD, LPWSTR*, PULONG, LPWSTR*, LPWSTR*, BOOL*, BOOL*);\n    HRESULT OpenLinkSource(DWORD);\n    HRESULT UpdateLink(DWORD, BOOL, BOOL);\n    HRESULT CancelLink(DWORD);\n    HRESULT GetLastUpdate(DWORD, FILETIME*);\n}\nalias IOleUILinkInfoW LPOLEUILINKINFOW;\n\ninterface IOleUILinkInfoA : IOleUILinkContainerA\n{\n    HRESULT QueryInterface(REFIID, PVOID*);\n    ULONG AddRef();\n    ULONG Release();\n    DWORD GetNextLink(DWORD);\n    HRESULT SetLinkUpdateOptions(DWORD, DWORD);\n    HRESULT GetLinkUpdateOptions(DWORD, DWORD*);\n    HRESULT SetLinkSource(DWORD, LPSTR, ULONG, PULONG, BOOL);\n    HRESULT GetLinkSource(DWORD, LPSTR*, PULONG, LPSTR*, LPSTR*, BOOL*, BOOL*);\n    HRESULT OpenLinkSource(DWORD);\n    HRESULT UpdateLink(DWORD, BOOL, BOOL);\n    HRESULT CancelLink(DWORD);\n    HRESULT GetLastUpdate(DWORD, FILETIME*);\n}\nalias IOleUILinkInfoA LPOLEUILINKINFOA;\n\nstruct OLEUIGNRLPROPSW {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    DWORD[2] dwReserved1;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    DWORD[3] dwReserved2;\n    OLEUIOBJECTPROPSW* lpOP;\n}\nalias OLEUIGNRLPROPSW* POLEUIGNRLPROPSW, LPOLEUIGNRLPROPSW;\n\nstruct OLEUIGNRLPROPSA {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    DWORD[2] dwReserved1;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    DWORD[3] dwReserved2;\n    OLEUIOBJECTPROPSA* lpOP;\n}\nalias OLEUIGNRLPROPSA* POLEUIGNRLPROPSA, LPOLEUIGNRLPROPSA;\n\nstruct OLEUIVIEWPROPSW {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    DWORD[2] dwReserved1;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    DWORD[3] dwReserved2;\n    OLEUIOBJECTPROPSW* lpOP;\n    int nScaleMin;\n    int nScaleMax;\n}\nalias OLEUIVIEWPROPSW* POLEUIVIEWPROPSW, LPOLEUIVIEWPROPSW;\n\nstruct OLEUIVIEWPROPSA {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    DWORD[2] dwReserved1;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    DWORD[3] dwReserved2;\n    OLEUIOBJECTPROPSA *lpOP;\n    int nScaleMin;\n    int nScaleMax;\n}\nalias OLEUIVIEWPROPSA* POLEUIVIEWPROPSA, LPOLEUIVIEWPROPSA;\n\nstruct OLEUILINKPROPSW {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    DWORD[2] dwReserved1;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    DWORD[3] dwReserved2;\n    OLEUIOBJECTPROPSW *lpOP;\n}\nalias OLEUILINKPROPSW* POLEUILINKPROPSW, LPOLEUILINKPROPSW;\n\nstruct OLEUILINKPROPSA {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    DWORD[2] dwReserved1;\n    LPFNOLEUIHOOK lpfnHook;\n    LPARAM lCustData;\n    DWORD[3] dwReserved2;\n    OLEUIOBJECTPROPSA* lpOP;\n}\nalias OLEUILINKPROPSA*  POLEUILINKPROPSA, LPOLEUILINKPROPSA;\n\nstruct OLEUIOBJECTPROPSW {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    LPPROPSHEETHEADERW lpPS;\n    DWORD dwObject;\n    LPOLEUIOBJINFOW lpObjInfo;\n    DWORD dwLink;\n    LPOLEUILINKINFOW lpLinkInfo;\n    LPOLEUIGNRLPROPSW lpGP;\n    LPOLEUIVIEWPROPSW lpVP;\n    LPOLEUILINKPROPSW lpLP;\n}\nalias OLEUIOBJECTPROPSW* POLEUIOBJECTPROPSW, LPOLEUIOBJECTPROPSW;\n\nstruct OLEUIOBJECTPROPSA {\n    DWORD cbStruct;\n    DWORD dwFlags;\n    LPPROPSHEETHEADERA lpPS;\n    DWORD dwObject;\n    LPOLEUIOBJINFOA lpObjInfo;\n    DWORD dwLink;\n    LPOLEUILINKINFOA lpLinkInfo;\n    LPOLEUIGNRLPROPSA lpGP;\n    LPOLEUIVIEWPROPSA lpVP;\n    LPOLEUILINKPROPSA lpLP;\n}\nalias OLEUIOBJECTPROPSA* POLEUIOBJECTPROPSA, LPOLEUIOBJECTPROPSA;\n\nextern (Windows) {\n    BOOL OleUIAddVerbMenuW(LPOLEOBJECT, LPCWSTR, HMENU, UINT, UINT, UINT, BOOL, UINT, HMENU*);\n    BOOL OleUIAddVerbMenuA(LPOLEOBJECT, LPCSTR, HMENU, UINT, UINT, UINT, BOOL, UINT, HMENU*);\n    UINT OleUIBusyW(LPOLEUIBUSYW);\n    UINT OleUIBusyA(LPOLEUIBUSYA);\n    BOOL OleUICanConvertOrActivateAs(REFCLSID, BOOL, WORD);\n    UINT OleUIChangeIconW(LPOLEUICHANGEICONW);\n    UINT OleUIChangeIconA(LPOLEUICHANGEICONA);\n    UINT OleUIChangeSourceW(LPOLEUICHANGESOURCEW);\n    UINT OleUIChangeSourceA(LPOLEUICHANGESOURCEA);\n    UINT OleUIConvertW(LPOLEUICONVERTW);\n    UINT OleUIConvertA(LPOLEUICONVERTA);\n    UINT OleUIEditLinksW(LPOLEUIEDITLINKSW);\n    UINT OleUIEditLinksA(LPOLEUIEDITLINKSA);\n    UINT OleUIObjectPropertiesW(LPOLEUIOBJECTPROPSW);\n    UINT OleUIObjectPropertiesA(LPOLEUIOBJECTPROPSA);\n    UINT OleUIPasteSpecialW(LPOLEUIPASTESPECIALW);\n    UINT OleUIPasteSpecialA(LPOLEUIPASTESPECIALA);\n    BOOL OleUIUpdateLinksW(LPOLEUILINKCONTAINERW, HWND, LPWSTR, int);\n    BOOL OleUIUpdateLinksA(LPOLEUILINKCONTAINERA, HWND, LPSTR, int);\n}\n\nextern (C) {\n    int OleUIPromptUserW(int, HWND, ...);\n    int OleUIPromptUserA(int, HWND, ...);\n}\n\nversion (Unicode) {\n    alias IDD_SERVERNOTREGW IDD_SERVERNOTREG;\n    alias IDD_LINKTYPECHANGEDW IDD_LINKTYPECHANGED;\n    alias OleUIUpdateLinksW OleUIUpdateLinks;\n    alias OleUIAddVerbMenuW OleUIAddVerbMenu;\n    alias OLEUIOBJECTPROPSW OLEUIOBJECTPROPS;\n    alias POLEUIOBJECTPROPSW POLEUIOBJECTPROPS;\n    alias LPOLEUIOBJECTPROPSW LPOLEUIOBJECTPROPS;\n    alias OleUIObjectPropertiesW OleUIObjectProperties;\n    alias OLEUIINSERTOBJECTW OLEUIINSERTOBJECT;\n    alias POLEUIINSERTOBJECTW POLEUIINSERTOBJECT;\n    alias LPOLEUIINSERTOBJECTW LPOLEUIINSERTOBJECT;\n    alias OleUIInsertObjectW OleUIInsertObject;\n    alias OleUIPromptUserW OleUIPromptUser;\n    alias OLEUIPASTEENTRYW OLEUIPASTEENTRY;\n    alias POLEUIPASTEENTRYW POLEUIPASTEENTRY;\n    alias LPOLEUIPASTEENTRYW LPOLEUIPASTEENTRY;\n    alias OLEUIPASTESPECIALW OLEUIPASTESPECIAL;\n    alias POLEUIPASTESPECIALW POLEUIPASTESPECIAL;\n    alias LPOLEUIPASTESPECIALW LPOLEUIPASTESPECIAL;\n    alias OleUIPasteSpecialW OleUIPasteSpecial;\n    alias IOleUILinkContainerW IOleUILinkContainer;\n    alias LPOLEUILINKCONTAINERW LPOLEUILINKCONTAINER;\n    alias OLEUIEDITLINKSW OLEUIEDITLINKS;\n    alias POLEUIEDITLINKSW POLEUIEDITLINKS;\n    alias LPOLEUIEDITLINKSW LPOLEUIEDITLINKS;\n    alias OleUIEditLinksW OleUIEditLinks;\n    alias OLEUICHANGEICONW OLEUICHANGEICON;\n    alias POLEUICHANGEICONW POLEUICHANGEICON;\n    alias LPOLEUICHANGEICONW LPOLEUICHANGEICON;\n    alias OleUIChangeIconW OleUIChangeIcon;\n    alias OLEUICONVERTW OLEUICONVERT;\n    alias POLEUICONVERTW POLEUICONVERT;\n    alias LPOLEUICONVERTW LPOLEUICONVERT;\n    alias OleUIConvertW OleUIConvert;\n    alias OLEUIBUSYW OLEUIBUSY;\n    alias POLEUIBUSYW POLEUIBUSY;\n    alias LPOLEUIBUSYW LPOLEUIBUSY;\n    alias OleUIBusyW OleUIBusy;\n    alias OLEUICHANGESOURCEW OLEUICHANGESOURCE;\n    alias POLEUICHANGESOURCEW POLEUICHANGESOURCE;\n    alias LPOLEUICHANGESOURCEW LPOLEUICHANGESOURCE;\n    alias OleUIChangeSourceW OleUIChangeSource;\n    alias IOleUIObjInfoW IOleUIObjInfo;\n    alias LPOLEUIOBJINFOW LPOLEUIOBJINFO;\n    alias IOleUILinkInfoW IOleUILinkInfo;\n    //alias IOleUILinkInfoWVtbl IOleUILinkInfoVtbl;\n    alias LPOLEUILINKINFOW LPOLEUILINKINFO;\n    alias OLEUIGNRLPROPSW OLEUIGNRLPROPS;\n    alias POLEUIGNRLPROPSW POLEUIGNRLPROPS;\n    alias LPOLEUIGNRLPROPSW LPOLEUIGNRLPROPS;\n    alias OLEUIVIEWPROPSW OLEUIVIEWPROPS;\n    alias POLEUIVIEWPROPSW POLEUIVIEWPROPS;\n    alias LPOLEUIVIEWPROPSW LPOLEUIVIEWPROPS;\n    alias OLEUILINKPROPSW OLEUILINKPROPS;\n    alias POLEUILINKPROPSW POLEUILINKPROPS;\n    alias LPOLEUILINKPROPSW LPOLEUILINKPROPS;\n} else {\n    alias IDD_SERVERNOTREGA IDD_SERVERNOTREG;\n    alias IDD_LINKTYPECHANGEDA IDD_LINKTYPECHANGED;\n    alias OleUIUpdateLinksA OleUIUpdateLinks;\n    alias OleUIAddVerbMenuA OleUIAddVerbMenu;\n    alias OLEUIOBJECTPROPSA OLEUIOBJECTPROPS;\n    alias POLEUIOBJECTPROPSA POLEUIOBJECTPROPS;\n    alias LPOLEUIOBJECTPROPSA LPOLEUIOBJECTPROPS;\n    alias OleUIObjectPropertiesA OleUIObjectProperties;\n    alias OLEUIINSERTOBJECTA OLEUIINSERTOBJECT;\n    alias POLEUIINSERTOBJECTA POLEUIINSERTOBJECT;\n    alias LPOLEUIINSERTOBJECTA LPOLEUIINSERTOBJECT;\n    alias OleUIInsertObjectA OleUIInsertObject;\n    alias OleUIPromptUserA OleUIPromptUser;\n    alias OLEUIPASTEENTRYA OLEUIPASTEENTRY;\n    alias POLEUIPASTEENTRYA POLEUIPASTEENTRY;\n    alias LPOLEUIPASTEENTRYA LPOLEUIPASTEENTRY;\n    alias OLEUIPASTESPECIALA OLEUIPASTESPECIAL;\n    alias POLEUIPASTESPECIALA POLEUIPASTESPECIAL;\n    alias LPOLEUIPASTESPECIALA LPOLEUIPASTESPECIAL;\n    alias OleUIPasteSpecialA OleUIPasteSpecial;\n    alias IOleUILinkContainerA IOleUILinkContainer;\n    alias LPOLEUILINKCONTAINERA LPOLEUILINKCONTAINER;\n    alias OLEUIEDITLINKSA OLEUIEDITLINKS;\n    alias POLEUIEDITLINKSA POLEUIEDITLINKS;\n    alias LPOLEUIEDITLINKSA LPOLEUIEDITLINKS;\n    alias OleUIEditLinksA OleUIEditLinks;\n    alias OLEUICHANGEICONA OLEUICHANGEICON;\n    alias POLEUICHANGEICONA POLEUICHANGEICON;\n    alias LPOLEUICHANGEICONA LPOLEUICHANGEICON;\n    alias OleUIChangeIconA OleUIChangeIcon;\n    alias OLEUICONVERTA OLEUICONVERT;\n    alias POLEUICONVERTA POLEUICONVERT;\n    alias LPOLEUICONVERTA LPOLEUICONVERT;\n    alias OleUIConvertA OleUIConvert;\n    alias OLEUIBUSYA OLEUIBUSY;\n    alias POLEUIBUSYA POLEUIBUSY;\n    alias LPOLEUIBUSYA LPOLEUIBUSY;\n    alias OleUIBusyA OleUIBusy;\n    alias OLEUICHANGESOURCEA OLEUICHANGESOURCE;\n    alias POLEUICHANGESOURCEA POLEUICHANGESOURCE;\n    alias LPOLEUICHANGESOURCEA LPOLEUICHANGESOURCE;\n    alias OleUIChangeSourceA OleUIChangeSource;\n    alias IOleUIObjInfoA IOleUIObjInfo;\n    alias LPOLEUIOBJINFOA LPOLEUIOBJINFO;\n    alias IOleUILinkInfoA IOleUILinkInfo;\n    //alias IOleUILinkInfoAVtbl IOleUILinkInfoVtbl;\n    alias LPOLEUILINKINFOA LPOLEUILINKINFO;\n    alias OLEUIGNRLPROPSA OLEUIGNRLPROPS;\n    alias POLEUIGNRLPROPSA POLEUIGNRLPROPS;\n    alias LPOLEUIGNRLPROPSA LPOLEUIGNRLPROPS;\n    alias OLEUIVIEWPROPSA OLEUIVIEWPROPS;\n    alias POLEUIVIEWPROPSA POLEUIVIEWPROPS;\n    alias LPOLEUIVIEWPROPSA LPOLEUIVIEWPROPS;\n    alias OLEUILINKPROPSA OLEUILINKPROPS;\n    alias POLEUILINKPROPSA POLEUILINKPROPS;\n    alias LPOLEUILINKPROPSA LPOLEUILINKPROPS;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/oleidl.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_oleidl.d)\n */\nmodule core.sys.windows.oleidl;\nversion (Windows):\n\n// DAC: This is defined in ocidl !!\n// what is it doing in here?\n//alias IEnumOleUndoUnits LPENUMOLEUNDOUNITS;\n\nprivate import core.sys.windows.basetyps, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.windef,\n  core.sys.windows.winuser, core.sys.windows.wtypes;\nprivate import core.sys.windows.objfwd; // for LPMONIKER\nprivate import core.sys.windows.wingdi; // for LPLOGPALETTE\n\nenum MK_ALT = 32;\n\nenum BINDSPEED {\n    BINDSPEED_INDEFINITE = 1,\n    BINDSPEED_MODERATE,\n    BINDSPEED_IMMEDIATE\n}\n\nenum OLEWHICHMK {\n    OLEWHICHMK_CONTAINER = 1,\n    OLEWHICHMK_OBJREL,\n    OLEWHICHMK_OBJFULL\n}\n\nenum OLEGETMONIKER {\n    OLEGETMONIKER_ONLYIFTHERE = 1,\n    OLEGETMONIKER_FORCEASSIGN,\n    OLEGETMONIKER_UNASSIGN,\n    OLEGETMONIKER_TEMPFORUSER\n}\n\nenum USERCLASSTYPE {\n    USERCLASSTYPE_FULL = 1,\n    USERCLASSTYPE_SHORT,\n    USERCLASSTYPE_APPNAME\n}\n\nenum DROPEFFECT {\n    DROPEFFECT_NONE   = 0,\n    DROPEFFECT_COPY   = 1,\n    DROPEFFECT_MOVE   = 2,\n    DROPEFFECT_LINK   = 4,\n    DROPEFFECT_SCROLL = 0x80000000\n}\n\nstruct OLEMENUGROUPWIDTHS {\n    LONG[6] width;\n}\nalias OLEMENUGROUPWIDTHS* LPOLEMENUGROUPWIDTHS;\n\nalias HGLOBAL HOLEMENU;\n\nenum OLECLOSE {\n    OLECLOSE_SAVEIFDIRTY,\n    OLECLOSE_NOSAVE,\n    OLECLOSE_PROMPTSAVE\n}\n\nstruct OLEVERB {\n    LONG lVerb;\n    LPWSTR lpszVerbName;\n    DWORD fuFlags;\n    DWORD grfAttribs;\n}\nalias OLEVERB* LPOLEVERB;\n\nalias RECT BORDERWIDTHS;\nalias LPRECT LPBORDERWIDTHS;\nalias LPCRECT LPCBORDERWIDTHS;\n\nstruct OLEINPLACEFRAMEINFO {\n    UINT cb;\n    BOOL fMDIApp;\n    HWND hwndFrame;\n    HACCEL haccel;\n    UINT cAccelEntries;\n}\nalias OLEINPLACEFRAMEINFO* LPOLEINPLACEFRAMEINFO;\n\ninterface IEnumOLEVERB : IUnknown\n{\n      HRESULT Next(ULONG,OLEVERB*,ULONG*);\n      HRESULT Skip(ULONG);\n      HRESULT Reset();\n      HRESULT Clone(IEnumOLEVERB*);\n}\n//alias IEnumOLEVERB IEnumOleVerb;\nalias IEnumOLEVERB LPENUMOLEVERB;\n\n\ninterface IParseDisplayName : IUnknown {\n    HRESULT ParseDisplayName(IBindCtx,LPOLESTR,ULONG*,IMoniker*);\n}\nalias IParseDisplayName LPPARSEDISPLAYNAME;\n\ninterface IOleContainer : IParseDisplayName {\n    HRESULT EnumObjects(DWORD,IEnumUnknown*);\n    HRESULT LockContainer(BOOL);\n}\nalias IOleContainer LPOLECONTAINER;\n\ninterface IOleItemContainer : IOleContainer {\n    HRESULT GetObject(LPOLESTR,DWORD,IBindCtx,REFIID,void**);\n    HRESULT GetObjectStorage(LPOLESTR,IBindCtx,REFIID,void**);\n    HRESULT IsRunning(LPOLESTR);\n}\n\n\ninterface IOleClientSite : IUnknown {\n    HRESULT SaveObject();\n    HRESULT GetMoniker(DWORD,DWORD,LPMONIKER*);\n    HRESULT GetContainer(LPOLECONTAINER*);\n    HRESULT ShowObject();\n    HRESULT OnShowWindow(BOOL);\n    HRESULT RequestNewObjectLayout();\n}\nalias IOleClientSite LPOLECLIENTSITE;\n\ninterface IOleObject : IUnknown {\n    HRESULT SetClientSite(LPOLECLIENTSITE);\n    HRESULT GetClientSite(LPOLECLIENTSITE*);\n    HRESULT SetHostNames(LPCOLESTR,LPCOLESTR);\n    HRESULT Close(DWORD);\n    HRESULT SetMoniker(DWORD,LPMONIKER);\n    HRESULT GetMoniker(DWORD,DWORD,LPMONIKER*);\n    HRESULT InitFromData(LPDATAOBJECT,BOOL,DWORD);\n    HRESULT GetClipboardData(DWORD,LPDATAOBJECT*);\n    HRESULT DoVerb(LONG,LPMSG,LPOLECLIENTSITE,LONG,HWND,LPCRECT);\n    HRESULT EnumVerbs(LPENUMOLEVERB*);\n    HRESULT Update();\n    HRESULT IsUpToDate();\n    HRESULT GetUserClassID(LPCLSID);\n    HRESULT GetUserType(DWORD,LPOLESTR*);\n    HRESULT SetExtent(DWORD,SIZEL*);\n    HRESULT GetExtent(DWORD,SIZEL*);\n    HRESULT Advise(LPADVISESINK,PDWORD);\n    HRESULT Unadvise(DWORD);\n    HRESULT EnumAdvise(LPENUMSTATDATA*);\n    HRESULT GetMiscStatus(DWORD,PDWORD);\n    HRESULT SetColorScheme(LPLOGPALETTE);\n}\nalias IOleObject LPOLEOBJECT;\n\ninterface IOleWindow : IUnknown {\n    HRESULT GetWindow(HWND*);\n    HRESULT ContextSensitiveHelp(BOOL);\n}\nalias IOleWindow LPOLEWINDOW;\n\ninterface IOleInPlaceUIWindow : IOleWindow {\n    HRESULT GetBorder(LPRECT);\n    HRESULT RequestBorderSpace(LPCBORDERWIDTHS);\n    HRESULT SetBorderSpace(LPCBORDERWIDTHS);\n    HRESULT SetActiveObject(LPOLEINPLACEACTIVEOBJECT,LPCOLESTR);\n}\nalias IOleInPlaceUIWindow LPOLEINPLACEUIWINDOW;\n\ninterface IOleInPlaceObject : IOleWindow {\n    HRESULT InPlaceDeactivate();\n    HRESULT UIDeactivate();\n    HRESULT SetObjectRects(LPCRECT,LPCRECT);\n    HRESULT ReactivateAndUndo();\n}\n\n\ninterface IOleInPlaceActiveObject : IOleWindow {\n    HRESULT TranslateAccelerator(LPMSG);\n    HRESULT OnFrameWindowActivate(BOOL);\n    HRESULT OnDocWindowActivate(BOOL);\n    HRESULT ResizeBorder(LPCRECT,LPOLEINPLACEUIWINDOW,BOOL);\n    HRESULT EnableModeless(BOOL);\n}\nalias IOleInPlaceActiveObject LPOLEINPLACEACTIVEOBJECT;\n\ninterface IOleInPlaceFrame : IOleInPlaceUIWindow {\n    HRESULT InsertMenus(HMENU,LPOLEMENUGROUPWIDTHS);\n    HRESULT SetMenu(HMENU,HOLEMENU,HWND);\n    HRESULT RemoveMenus(HMENU);\n    HRESULT SetStatusText(LPCOLESTR);\n    HRESULT EnableModeless(BOOL);\n    HRESULT TranslateAccelerator(LPMSG,WORD);\n}\nalias IOleInPlaceFrame LPOLEINPLACEFRAME;\n\ninterface IOleInPlaceSite  : IOleWindow {\n    HRESULT CanInPlaceActivate();\n    HRESULT OnInPlaceActivate();\n    HRESULT OnUIActivate();\n    HRESULT GetWindowContext(IOleInPlaceFrame,IOleInPlaceUIWindow,LPRECT,LPRECT,LPOLEINPLACEFRAMEINFO);\n    HRESULT Scroll(SIZE);\n    HRESULT OnUIDeactivate(BOOL);\n    HRESULT OnInPlaceDeactivate();\n    HRESULT DiscardUndoState();\n    HRESULT DeactivateAndUndo();\n    HRESULT OnPosRectChange(LPCRECT);\n}\n\ninterface IOleAdviseHolder : IUnknown {\n    HRESULT Advise(LPADVISESINK,PDWORD);\n    HRESULT Unadvise(DWORD);\n    HRESULT EnumAdvise(LPENUMSTATDATA*);\n    HRESULT SendOnRename(LPMONIKER);\n    HRESULT SendOnSave();\n    HRESULT SendOnClose();\n}\nalias IOleAdviseHolder LPOLEADVISEHOLDER;\n\ninterface IDropSource : IUnknown {\n    HRESULT QueryContinueDrag(BOOL,DWORD);\n    HRESULT GiveFeedback(DWORD);\n}\nalias IDropSource LPDROPSOURCE;\n\ninterface IDropTarget : IUnknown {\n    HRESULT DragEnter(LPDATAOBJECT,DWORD,POINTL,PDWORD);\n    HRESULT DragOver(DWORD,POINTL,PDWORD);\n    HRESULT DragLeave();\n    HRESULT Drop(LPDATAOBJECT,DWORD,POINTL,PDWORD);\n}\nalias IDropTarget LPDROPTARGET;\n\nextern (Windows) {\n    alias BOOL function(ULONG_PTR) __IView_pfncont;\n}\n\ninterface IViewObject : IUnknown {\n    HRESULT Draw(DWORD,LONG,PVOID,DVTARGETDEVICE*,HDC,HDC,LPCRECTL,LPCRECTL,__IView_pfncont pfnContinue,ULONG_PTR);\n    HRESULT GetColorSet(DWORD,LONG,PVOID,DVTARGETDEVICE*,HDC,LPLOGPALETTE*);\n    HRESULT Freeze(DWORD,LONG,PVOID,PDWORD);\n    HRESULT Unfreeze(DWORD);\n    HRESULT SetAdvise(DWORD,DWORD,IAdviseSink);\n    HRESULT GetAdvise(PDWORD,PDWORD,IAdviseSink*);\n}\nalias IViewObject LPVIEWOBJECT;\n\ninterface IViewObject2 : IViewObject {\n    HRESULT GetExtent(DWORD,LONG,DVTARGETDEVICE*,LPSIZEL);\n}\nalias IViewObject2 LPVIEWOBJECT2;\n\ninterface IOleCache : IUnknown {\n    HRESULT Cache(FORMATETC*,DWORD,DWORD*);\n    HRESULT Uncache(DWORD);\n    HRESULT EnumCache(IEnumSTATDATA*);\n    HRESULT InitCache(LPDATAOBJECT);\n    HRESULT SetData(FORMATETC*,STGMEDIUM*,BOOL);\n}\nalias IOleCache LPOLECACHE;\n\ninterface IOleCache2 : IOleCache {\n    HRESULT UpdateCache(LPDATAOBJECT,DWORD,LPVOID);\n    HRESULT DiscardCache(DWORD);\n}\nalias IOleCache2 LPOLECACHE2;\n\ninterface IOleCacheControl : IUnknown {\n    HRESULT OnRun(LPDATAOBJECT);\n    HRESULT OnStop();\n}\nalias IOleCacheControl LPOLECACHECONTROL;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/pbt.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_pbt.d)\n */\nmodule core.sys.windows.pbt;\nversion (Windows):\n\nprivate import core.sys.windows.windef;\n\nenum : WPARAM {\n    PBT_APMQUERYSUSPEND,\n    PBT_APMQUERYSTANDBY,\n    PBT_APMQUERYSUSPENDFAILED,\n    PBT_APMQUERYSTANDBYFAILED,\n    PBT_APMSUSPEND,\n    PBT_APMSTANDBY,\n    PBT_APMRESUMECRITICAL,\n    PBT_APMRESUMESUSPEND,\n    PBT_APMRESUMESTANDBY,\n    PBT_APMBATTERYLOW,\n    PBT_APMPOWERSTATUSCHANGE,\n    PBT_APMOEMEVENT // = 11\n}\n\nenum LPARAM PBTF_APMRESUMEFROMFAILURE = 1;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/powrprof.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_powrprof.d)\n */\nmodule core.sys.windows.powrprof;\nversion (Windows):\npragma(lib, \"powrprof\");\n\nprivate import core.sys.windows.windef;\nprivate import core.sys.windows.ntdef;\n\n// FIXME: look up Windows version support\n\nenum ULONG\n    EnableSysTrayBatteryMeter =  1,\n    EnableMultiBatteryDisplay =  2,\n    EnablePasswordLogon       =  4,\n    EnableWakeOnRing          =  8,\n    EnableVideoDimDisplay     = 16;\n\nenum UINT NEWSCHEME = -1;\n\nstruct GLOBAL_MACHINE_POWER_POLICY {\n    ULONG              Revision;\n    SYSTEM_POWER_STATE LidOpenWakeAc;\n    SYSTEM_POWER_STATE LidOpenWakeDc;\n    ULONG              BroadcastCapacityResolution;\n}\nalias GLOBAL_MACHINE_POWER_POLICY* PGLOBAL_MACHINE_POWER_POLICY;\n\nstruct GLOBAL_USER_POWER_POLICY {\n    ULONG               Revision;\n    POWER_ACTION_POLICY PowerButtonAc;\n    POWER_ACTION_POLICY PowerButtonDc;\n    POWER_ACTION_POLICY SleepButtonAc;\n    POWER_ACTION_POLICY SleepButtonDc;\n    POWER_ACTION_POLICY LidCloseAc;\n    POWER_ACTION_POLICY LidCloseDc;\n    SYSTEM_POWER_LEVEL[NUM_DISCHARGE_POLICIES] DischargePolicy;\n    ULONG GlobalFlags;\n}\nalias GLOBAL_USER_POWER_POLICY* PGLOBAL_USER_POWER_POLICY;\n\nstruct GLOBAL_POWER_POLICY {\n    GLOBAL_USER_POWER_POLICY    user;\n    GLOBAL_MACHINE_POWER_POLICY mach;\n}\nalias GLOBAL_POWER_POLICY* PGLOBAL_POWER_POLICY;\n\nstruct MACHINE_POWER_POLICY {\n    ULONG               Revision;\n    SYSTEM_POWER_STATE  MinSleepAc;\n    SYSTEM_POWER_STATE  MinSleepDc;\n    SYSTEM_POWER_STATE  ReducedLatencySleepAc;\n    SYSTEM_POWER_STATE  ReducedLatencySleepDc;\n    ULONG               DozeTimeoutAc;\n    ULONG               DozeTimeoutDc;\n    ULONG               DozeS4TimeoutAc;\n    ULONG               DozeS4TimeoutDc;\n    UCHAR               MinThrottleAc;\n    UCHAR               MinThrottleDc;\n    UCHAR[2]            pad1;\n    POWER_ACTION_POLICY OverThrottledAc;\n    POWER_ACTION_POLICY OverThrottledDc;\n}\nalias MACHINE_POWER_POLICY* PMACHINE_POWER_POLICY;\n\nstruct MACHINE_PROCESSOR_POWER_POLICY {\n    ULONG Revision;\n    PROCESSOR_POWER_POLICY ProcessorPolicyAc;\n    PROCESSOR_POWER_POLICY ProcessorPolicyDc;\n}\nalias MACHINE_PROCESSOR_POWER_POLICY* PMACHINE_PROCESSOR_POWER_POLICY;\n\nstruct USER_POWER_POLICY {\n   ULONG               Revision;\n   POWER_ACTION_POLICY IdleAc;\n   POWER_ACTION_POLICY IdleDc;\n   ULONG               IdleTimeoutAc;\n   ULONG               IdleTimeoutDc;\n   UCHAR               IdleSensitivityAc;\n   UCHAR               IdleSensitivityDc;\n   UCHAR               ThrottlePolicyAc;\n   UCHAR               ThrottlePolicyDc;\n   SYSTEM_POWER_STATE  MaxSleepAc;\n   SYSTEM_POWER_STATE  MaxSleepDc;\n   ULONG[2]            Reserved;\n   ULONG               VideoTimeoutAc;\n   ULONG               VideoTimeoutDc;\n   ULONG               SpindownTimeoutAc;\n   ULONG               SpindownTimeoutDc;\n   BOOLEAN             OptimizeForPowerAc;\n   BOOLEAN             OptimizeForPowerDc;\n   UCHAR               FanThrottleToleranceAc;\n   UCHAR               FanThrottleToleranceDc;\n   UCHAR               ForcedThrottleAc;\n   UCHAR               ForcedThrottleDc;\n}\nalias USER_POWER_POLICY* PUSER_POWER_POLICY;\n\nstruct POWER_POLICY {\n    USER_POWER_POLICY    user;\n    MACHINE_POWER_POLICY mach;\n}\nalias POWER_POLICY* PPOWER_POLICY;\n\nextern (Windows) {\n    alias BOOLEAN function(UINT, DWORD, LPTSTR, DWORD, LPTSTR, PPOWER_POLICY,\n      LPARAM) PWRSCHEMESENUMPROC;\n    alias BOOLEAN function(POWER_ACTION, SYSTEM_POWER_STATE, ULONG, BOOLEAN)\n      PFNNTINITIATEPWRACTION;\n\n    NTSTATUS CallNtPowerInformation(POWER_INFORMATION_LEVEL, PVOID, ULONG,\n      PVOID, ULONG);\n    BOOLEAN CanUserWritePwrScheme();\n    BOOLEAN DeletePwrScheme(UINT);\n    BOOLEAN EnumPwrSchemes(PWRSCHEMESENUMPROC, LPARAM);\n    BOOLEAN GetActivePwrScheme(PUINT);\n    BOOLEAN GetCurrentPowerPolicies(PGLOBAL_POWER_POLICY, PPOWER_POLICY);\n    BOOLEAN GetPwrCapabilities(PSYSTEM_POWER_CAPABILITIES);\n    BOOLEAN GetPwrDiskSpindownRange(PUINT, PUINT);\n    BOOLEAN IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY);\n    BOOLEAN IsPwrHibernateAllowed();\n    BOOLEAN IsPwrShutdownAllowed();\n    BOOLEAN IsPwrSuspendAllowed();\n    BOOLEAN ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY);\n    BOOLEAN ReadProcessorPwrScheme(UINT, PMACHINE_PROCESSOR_POWER_POLICY);\n    BOOLEAN ReadPwrScheme(UINT, PPOWER_POLICY);\n    BOOLEAN SetActivePwrScheme(UINT, PGLOBAL_POWER_POLICY, PPOWER_POLICY);\n    BOOLEAN SetSuspendState(BOOLEAN, BOOLEAN, BOOLEAN);\n    BOOLEAN WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY);\n    BOOLEAN WriteProcessorPwrScheme(UINT, PMACHINE_PROCESSOR_POWER_POLICY);\n    BOOLEAN ValidatePowerPolicies(PGLOBAL_POWER_POLICY, PPOWER_POLICY);\n    BOOLEAN WritePwrScheme(PUINT, LPTSTR, LPTSTR, PPOWER_POLICY);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/prsht.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Vladimir Vlasov\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_prsht.d)\n */\nmodule core.sys.windows.prsht;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"comctl32\");\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winuser;\n\nenum MAXPROPPAGES = 100;\n\nenum {\n    PSP_DEFAULT      = 0x00000000,\n    PSP_DLGINDIRECT  = 0x00000001,\n    PSP_USEHICON     = 0x00000002,\n    PSP_USEICONID    = 0x00000004,\n    PSP_USETITLE     = 0x00000008,\n    PSP_RTLREADING   = 0x00000010,\n    PSP_HASHELP      = 0x00000020,\n    PSP_USEREFPARENT = 0x00000040,\n    PSP_USECALLBACK  = 0x00000080,\n    PSP_PREMATURE    = 0x00000400\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        PSP_HIDEHEADER        = 0x00000800,\n        PSP_USEHEADERTITLE    = 0x00001000,\n        PSP_USEHEADERSUBTITLE = 0x00002000\n    }\n}\n\nenum {\n    PSPCB_RELEASE = 1,\n    PSPCB_CREATE\n}\n\nenum {\n    PSH_DEFAULT           = 0x00000000,\n    PSH_PROPTITLE         = 0x00000001,\n    PSH_USEHICON          = 0x00000002,\n    PSH_USEICONID         = 0x00000004,\n    PSH_PROPSHEETPAGE     = 0x00000008,\n    PSH_WIZARDHASFINISH   = 0x00000010,\n    PSH_WIZARD            = 0x00000020,\n    PSH_USEPSTARTPAGE     = 0x00000040,\n    PSH_NOAPPLYNOW        = 0x00000080,\n    PSH_USECALLBACK       = 0x00000100,\n    PSH_HASHELP           = 0x00000200,\n    PSH_MODELESS          = 0x00000400,\n    PSH_RTLREADING        = 0x00000800,\n    PSH_WIZARDCONTEXTHELP = 0x00001000\n}\n\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        PSH_WATERMARK        = 0x00008000,\n        PSH_USEHBMWATERMARK  = 0x00010000,\n        PSH_USEHPLWATERMARK  = 0x00020000,\n        PSH_STRETCHWATERMARK = 0x00040000,\n        PSH_HEADER           = 0x00080000,\n        PSH_USEHBMHEADER     = 0x00100000,\n        PSH_USEPAGELANG      = 0x00200000\n    }\n    static if (_WIN32_IE < 0x0500) {\n        enum {\n            PSH_WIZARD97 = 0x00002000\n        }\n    } else {\n        enum {\n            PSH_WIZARD97 = 0x01000000\n        }\n    }\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        PSH_WIZARD_LITE   = 0x00400000,\n        PSH_NOCONTEXTHELP = 0x02000000\n    }\n}\n\nenum {\n    PSCB_INITIALIZED = 1,\n    PSCB_PRECREATE\n}\n\nenum {\n    PSN_FIRST       = (-200),\n    PSN_LAST        = (-299),\n    PSN_SETACTIVE   = (-200),\n    PSN_KILLACTIVE  = (-201),\n    PSN_APPLY       = (-202),\n    PSN_RESET       = (-203),\n    PSN_HELP        = (-205),\n    PSN_WIZBACK     = (-206),\n    PSN_WIZNEXT     = (-207),\n    PSN_WIZFINISH   = (-208),\n    PSN_QUERYCANCEL = (-209)\n}\nstatic if (_WIN32_IE >= 0x400) {\n    enum {\n        PSN_GETOBJECT = (-210)\n    }\n}\nstatic if (_WIN32_IE >= 0x500) {\n    enum {\n        PSN_TRANSLATEACCELERATOR = (-212),\n        PSN_QUERYINITIALFOCUS    = (-213)\n    }\n}\n\nenum {\n    PSNRET_NOERROR,\n    PSNRET_INVALID,\n    PSNRET_INVALID_NOCHANGEPAGE,\n    PSNRET_MESSAGEHANDLED\n}\n\nenum {\n    ID_PSRESTARTWINDOWS = 0x2,\n    ID_PSREBOOTSYSTEM   = ID_PSRESTARTWINDOWS | 0x1\n}\n\nenum {\n    WIZ_CXDLG  = 276,\n    WIZ_CYDLG  = 140,\n    WIZ_CXBMP  = 80,\n    WIZ_BODYX  = 92,\n    WIZ_BODYCX = 184\n}\n\nenum {\n    PROP_SM_CXDLG  = 212,\n    PROP_SM_CYDLG  = 188,\n    PROP_MED_CXDLG = 227,\n    PROP_MED_CYDLG = 215,\n    PROP_LG_CXDLG  = 252,\n    PROP_LG_CYDLG  = 218\n}\n\nenum {\n    PSBTN_BACK,\n    PSBTN_NEXT,\n    PSBTN_FINISH,\n    PSBTN_OK,\n    PSBTN_APPLYNOW,\n    PSBTN_CANCEL,\n    PSBTN_HELP,\n    PSBTN_MAX = 6\n}\n\nenum {\n    PSWIZB_BACK           = 1,\n    PSWIZB_NEXT           = 2,\n    PSWIZB_FINISH         = 4,\n    PSWIZB_DISABLEDFINISH = 8\n}\n\nenum {\n    PSM_SETCURSEL = WM_USER + 101,\n    PSM_REMOVEPAGE,\n    PSM_ADDPAGE,\n    PSM_CHANGED,\n    PSM_RESTARTWINDOWS,\n    PSM_REBOOTSYSTEM,\n    PSM_CANCELTOCLOSE,\n    PSM_QUERYSIBLINGS,\n    PSM_UNCHANGED,\n    PSM_APPLY,\n    PSM_SETTITLEA,\n    PSM_SETWIZBUTTONS,\n    PSM_PRESSBUTTON,\n    PSM_SETCURSELID,\n    PSM_SETFINISHTEXTA,\n    PSM_GETTABCONTROL,\n    PSM_ISDIALOGMESSAGE,\n    PSM_GETCURRENTPAGEHWND,\n    PSM_INSERTPAGE,\n    PSM_SETTITLEW,\n    PSM_SETFINISHTEXTW // = WM_USER + 121,\n}\n\nextern (Windows) {\n    alias UINT function(HWND, UINT, LPPROPSHEETPAGEA) LPFNPSPCALLBACKA;\n    alias UINT function(HWND, UINT, LPPROPSHEETPAGEW) LPFNPSPCALLBACKW;\n    alias int function(HWND, UINT, LPARAM) PFNPROPSHEETCALLBACK;\n}\n\nalign(4):\n\nstruct PROPSHEETPAGEA {\n    DWORD dwSize = PROPSHEETPAGEA.sizeof;\n    DWORD dwFlags;\n    HINSTANCE hInstance;\n    union {\n        LPCSTR         pszTemplate;\n        LPCDLGTEMPLATE pResource;\n    }\n    union {\n        HICON  hIcon;\n        LPCSTR pszIcon;\n    }\n    LPCSTR  pszTitle;\n    DLGPROC pfnDlgProc;\n    LPARAM  lParam;\n    LPFNPSPCALLBACKA pfnCallback;\n    UINT*     pcRefParent;\n    static if (_WIN32_IE >= 0x400) {\n        LPCSTR pszHeaderTitle;\n        LPCSTR pszHeaderSubTitle;\n    }\n}\nalias PROPSHEETPAGEA*        LPPROPSHEETPAGEA;\nalias const(PROPSHEETPAGEA)* LPCPROPSHEETPAGEA;\n\nstruct PROPSHEETPAGEW {\n    DWORD     dwSize = PROPSHEETPAGEW.sizeof;\n    DWORD     dwFlags;\n    HINSTANCE hInstance;\n    union {\n        LPCWSTR        pszTemplate;\n        LPCDLGTEMPLATE pResource;\n    }\n    union {\n        HICON   hIcon;\n        LPCWSTR pszIcon;\n    }\n    LPCWSTR   pszTitle;\n    DLGPROC   pfnDlgProc;\n    LPARAM    lParam;\n    LPFNPSPCALLBACKW pfnCallback;\n    UINT*     pcRefParent;\n    static if (_WIN32_IE >= 0x400) {\n        LPCWSTR pszHeaderTitle;\n        LPCWSTR pszHeaderSubTitle;\n    }\n}\nalias PROPSHEETPAGEW*        LPPROPSHEETPAGEW;\nalias const(PROPSHEETPAGEW)* LPCPROPSHEETPAGEW;\n\nmixin DECLARE_HANDLE!(\"HPROPSHEETPAGE\");\n\nstruct PROPSHEETHEADERA {\n    DWORD dwSize = PROPSHEETHEADERA.sizeof;\n    DWORD dwFlags;\n    HWND  hwndParent;\n    HINSTANCE hInstance;\n    union {\n        HICON   hIcon;\n        LPCSTR  pszIcon;\n    }\n    LPCSTR pszCaption;\n    UINT   nPages;\n    union {\n        UINT   nStartPage;\n        LPCSTR pStartPage;\n    }\n    union {\n        LPCPROPSHEETPAGEA ppsp;\n        HPROPSHEETPAGE*   phpage;\n    }\n    PFNPROPSHEETCALLBACK pfnCallback;\n    static if (_WIN32_IE >= 0x400) {\n        union {\n            HBITMAP hbmWatermark;\n            LPCSTR  pszbmWatermark;\n        }\n        HPALETTE hplWatermark;\n        union {\n            HBITMAP hbmHeader;\n            LPCSTR  pszbmHeader;\n        }\n    }\n}\nalias PROPSHEETHEADERA*        LPPROPSHEETHEADERA;\nalias const(PROPSHEETHEADERA)* LPCPROPSHEETHEADERA;\n\nstruct PROPSHEETHEADERW {\n    DWORD     dwSize = PROPSHEETHEADERW.sizeof;\n    DWORD     dwFlags;\n    HWND      hwndParent;\n    HINSTANCE hInstance;\n    union {\n        HICON   hIcon;\n        LPCWSTR pszIcon;\n    }\n    LPCWSTR   pszCaption;\n    UINT      nPages;\n    union {\n        UINT    nStartPage;\n        LPCWSTR pStartPage;\n    }\n    union {\n        LPCPROPSHEETPAGEW ppsp;\n        HPROPSHEETPAGE*   phpage;\n    }\n    PFNPROPSHEETCALLBACK pfnCallback;\n    static if (_WIN32_IE >= 0x400) {\n        union {\n            HBITMAP hbmWatermark;\n            LPCWSTR pszbmWatermark;\n        }\n        HPALETTE hplWatermark;\n        union {\n            HBITMAP hbmHeader;\n            LPCWSTR pszbmHeader;\n        }\n    }\n}\nalias PROPSHEETHEADERW*        LPPROPSHEETHEADERW;\nalias const(PROPSHEETHEADERW)* LPCPROPSHEETHEADERW;\n\nextern (Windows) {\n    alias BOOL function(HPROPSHEETPAGE, LPARAM) LPFNADDPROPSHEETPAGE;\n    alias BOOL function(LPVOID, LPFNADDPROPSHEETPAGE, LPARAM)\n      LPFNADDPROPSHEETPAGES;\n}\n\nstruct PSHNOTIFY {\n    NMHDR  hdr;\n    LPARAM lParam;\n}\nalias PSHNOTIFY* LPPSHNOTIFY;\n\nextern (Windows) {\n    HPROPSHEETPAGE CreatePropertySheetPageA(LPCPROPSHEETPAGEA);\n    HPROPSHEETPAGE CreatePropertySheetPageW(LPCPROPSHEETPAGEW);\n    BOOL DestroyPropertySheetPage(HPROPSHEETPAGE);\n    INT_PTR PropertySheetA(LPCPROPSHEETHEADERA);\n    INT_PTR PropertySheetW(LPCPROPSHEETHEADERW);\n}\n\nversion (Unicode) {\n    alias LPFNPSPCALLBACKW         LPFNPSPCALLBACK;\n    alias PROPSHEETPAGEW           PROPSHEETPAGE;\n    alias LPPROPSHEETPAGEW         LPPROPSHEETPAGE;\n    alias LPCPROPSHEETPAGEW        LPCPROPSHEETPAGE;\n    alias PROPSHEETHEADERW         PROPSHEETHEADER;\n    alias LPPROPSHEETHEADERW       LPPROPSHEETHEADER;\n    alias LPCPROPSHEETHEADERW      LPCPROPSHEETHEADER;\n    alias PSM_SETTITLEW            PSM_SETTITLE;\n    alias PSM_SETFINISHTEXTW       PSM_SETFINISHTEXT;\n    alias CreatePropertySheetPageW CreatePropertySheetPage;\n    alias PropertySheetW           PropertySheet;\n} else {\n    alias LPFNPSPCALLBACKA         LPFNPSPCALLBACK;\n    alias PROPSHEETPAGEA           PROPSHEETPAGE;\n    alias LPPROPSHEETPAGEA         LPPROPSHEETPAGE;\n    alias LPCPROPSHEETPAGEA        LPCPROPSHEETPAGE;\n    alias PROPSHEETHEADERA         PROPSHEETHEADER;\n    alias LPPROPSHEETHEADERA       LPPROPSHEETHEADER;\n    alias LPCPROPSHEETHEADERA      LPCPROPSHEETHEADER;\n    alias PSM_SETTITLEA            PSM_SETTITLE;\n    alias PSM_SETFINISHTEXTA       PSM_SETFINISHTEXT;\n    alias CreatePropertySheetPageA CreatePropertySheetPage;\n    alias PropertySheetA           PropertySheet;\n}\n\nBOOL PropSheet_SetCurSel(HWND hPropSheetDlg, HPROPSHEETPAGE hpage,\n      HPROPSHEETPAGE index) {\n    return cast(BOOL) SendMessage(hPropSheetDlg, PSM_SETCURSEL,\n      cast(WPARAM) index, cast(LPARAM) hpage);\n}\n\nVOID PropSheet_RemovePage(HWND hPropSheetDlg, int index, HPROPSHEETPAGE hpage) {\n    SendMessage(hPropSheetDlg, PSM_REMOVEPAGE, index, cast(LPARAM) hpage);\n}\n\nBOOL PropSheet_AddPage(HWND hPropSheetDlg, HPROPSHEETPAGE hpage) {\n        return cast(BOOL) SendMessage(hPropSheetDlg, PSM_ADDPAGE,\n          0, cast(LPARAM) hpage);\n}\n\nVOID PropSheet_Changed(HWND hPropSheetDlg, HWND hwndPage) {\n    SendMessage(hPropSheetDlg, PSM_CHANGED, cast(WPARAM) hwndPage, 0);\n}\n\nVOID PropSheet_RestartWindows(HWND hPropSheetDlg) {\n    SendMessage(hPropSheetDlg, PSM_RESTARTWINDOWS, 0, 0);\n}\n\nVOID PropSheet_RebootSystem(HWND hPropSheetDlg) {\n    SendMessage(hPropSheetDlg, PSM_REBOOTSYSTEM, 0, 0);\n}\n\nVOID PropSheet_CancelToClose(HWND hPropSheetDlg) {\n    SendMessage(hPropSheetDlg, PSM_CANCELTOCLOSE, 0, 0);\n}\n\nint PropSheet_QuerySiblings(HWND hPropSheetDlg, WPARAM param1, LPARAM param2) {\n    return cast(int) SendMessage(hPropSheetDlg, PSM_QUERYSIBLINGS, param1, param2);\n}\n\nVOID PropSheet_UnChanged(HWND hPropSheetDlg, HWND hwndPage) {\n    SendMessage(hPropSheetDlg, PSM_UNCHANGED, cast(WPARAM) hwndPage, 0);\n}\n\nBOOL PropSheet_Apply(HWND hPropSheetDlg) {\n    return cast(BOOL) SendMessage(hPropSheetDlg, PSM_APPLY, 0, 0);\n}\n\nVOID PropSheet_SetTitle(HWND hPropSheetDlg, DWORD wStyle, LPTSTR lpszText) {\n    SendMessage(hPropSheetDlg, PSM_SETTITLE, wStyle, cast(LPARAM) lpszText);\n}\n\nVOID PropSheet_SetWizButtons(HWND hPropSheetDlg, DWORD dwFlags) {\n    PostMessage(hPropSheetDlg, PSM_SETWIZBUTTONS, 0, cast(LPARAM) dwFlags);\n}\n\nBOOL PropSheet_PressButton(HWND hPropSheetDlg, int iButton) {\n    return cast(BOOL) SendMessage(hPropSheetDlg, PSM_PRESSBUTTON, iButton, 0);\n}\n\nBOOL PropSheet_SetCurSelByID(HWND hPropSheetDlg, int id) {\n    return cast(BOOL) SendMessage(hPropSheetDlg, PSM_SETCURSELID, 0, id);\n}\n\nVOID PropSheet_SetFinishText(HWND hPropSheetDlg, LPTSTR lpszText) {\n    SendMessage(hPropSheetDlg, PSM_SETFINISHTEXT, 0, cast(LPARAM) lpszText);\n}\n\nHWND PropSheet_GetTabControl(HWND hPropSheetDlg) {\n    return cast(HWND) SendMessage(hPropSheetDlg, PSM_GETTABCONTROL, 0, 0);\n}\n\nBOOL PropSheet_IsDialogMessage(HWND hDlg, LPMSG pMsg) {\n    return cast(BOOL) SendMessage(hDlg, PSM_ISDIALOGMESSAGE,\n      0, cast(LPARAM) pMsg);\n}\n\nHWND PropSheet_GetCurrentPageHwnd(HWND hDlg) {\n    return cast(HWND) SendMessage(hDlg, PSM_GETCURRENTPAGEHWND, 0, 0);\n}\n\nBOOL PropSheet_InsertPage(HWND hPropSheetDlg, WPARAM wInsertAfter,\n      HPROPSHEETPAGE hpage) {\n    return cast(BOOL) SendMessage(hPropSheetDlg, PSM_INSERTPAGE,\n      wInsertAfter, cast(LPARAM) hpage);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/psapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_psapi.d)\n */\n/* Comment from MinGW\n *   Process status API (PSAPI)\n *   http://windowssdk.msdn.microsoft.com/library/ms684884.aspx\n */\n\nmodule core.sys.windows.psapi;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.w32api;\nprivate import core.sys.windows.winbase;\nprivate import core.sys.windows.windef;\n\nstruct MODULEINFO {\n    LPVOID lpBaseOfDll;\n    DWORD SizeOfImage;\n    LPVOID EntryPoint;\n}\nalias MODULEINFO* LPMODULEINFO;\n\nstruct PSAPI_WS_WATCH_INFORMATION {\n    LPVOID FaultingPc;\n    LPVOID FaultingVa;\n}\nalias PSAPI_WS_WATCH_INFORMATION* PPSAPI_WS_WATCH_INFORMATION;\n\nstruct PSAPI_WS_WATCH_INFORMATION_EX {\n    PSAPI_WS_WATCH_INFORMATION BasicInfo;\n    ULONG_PTR FaultingThreadId;\n    ULONG_PTR Flags;\n}\nalias PSAPI_WS_WATCH_INFORMATION_EX* PPSAPI_WS_WATCH_INFORMATION_EX;\n\nstruct PROCESS_MEMORY_COUNTERS {\n    DWORD cb;\n    DWORD PageFaultCount;\n    SIZE_T PeakWorkingSetSize;\n    SIZE_T WorkingSetSize;\n    SIZE_T QuotaPeakPagedPoolUsage;\n    SIZE_T QuotaPagedPoolUsage;\n    SIZE_T QuotaPeakNonPagedPoolUsage;\n    SIZE_T QuotaNonPagedPoolUsage;\n    SIZE_T PagefileUsage;\n    SIZE_T PeakPagefileUsage;\n}\nalias PROCESS_MEMORY_COUNTERS* PPROCESS_MEMORY_COUNTERS;\n\nstruct PERFORMANCE_INFORMATION {\n    DWORD cb;\n    SIZE_T CommitTotal;\n    SIZE_T CommitLimit;\n    SIZE_T CommitPeak;\n    SIZE_T PhysicalTotal;\n    SIZE_T PhysicalAvailable;\n    SIZE_T SystemCache;\n    SIZE_T KernelTotal;\n    SIZE_T KernelPaged;\n    SIZE_T KernelNonpaged;\n    SIZE_T PageSize;\n    DWORD HandleCount;\n    DWORD ProcessCount;\n    DWORD ThreadCount;\n}\nalias PERFORMANCE_INFORMATION* PPERFORMANCE_INFORMATION;\n\nstruct ENUM_PAGE_FILE_INFORMATION {\n    DWORD cb;\n    DWORD Reserved;\n    SIZE_T TotalSize;\n    SIZE_T TotalInUse;\n    SIZE_T PeakUsage;\n}\nalias ENUM_PAGE_FILE_INFORMATION* PENUM_PAGE_FILE_INFORMATION;\n\n/* application-defined callback function used with the EnumPageFiles()\n * http://windowssdk.msdn.microsoft.com/library/ms682627.aspx */\nversion (Unicode) {\n    alias BOOL function(LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCWSTR)\n      PENUM_PAGE_FILE_CALLBACK;\n} else {\n    alias BOOL function(LPVOID, PENUM_PAGE_FILE_INFORMATION, LPCSTR)\n      PENUM_PAGE_FILE_CALLBACK;\n}\n\n// Grouped by application, not in alphabetical order.\nextern (Windows) {\n    /* Process Information\n     * http://windowssdk.msdn.microsoft.com/library/ms684870.aspx */\n    BOOL EnumProcesses(DWORD*, DWORD, DWORD*); /* NT/2000/XP/Server2003/Vista/Longhorn */\n    DWORD GetProcessImageFileNameA(HANDLE, LPSTR, DWORD); /* XP/Server2003/Vista/Longhorn */\n    DWORD GetProcessImageFileNameW(HANDLE, LPWSTR, DWORD); /* XP/Server2003/Vista/Longhorn */\n\n    /* Module Information\n     * http://windowssdk.msdn.microsoft.com/library/ms684232.aspx */\n    BOOL EnumProcessModules(HANDLE, HMODULE*, DWORD, LPDWORD);\n    BOOL EnumProcessModulesEx(HANDLE, HMODULE*, DWORD, LPDWORD, DWORD); /* Vista/Longhorn */\n    DWORD GetModuleBaseNameA(HANDLE, HMODULE, LPSTR, DWORD);\n    DWORD GetModuleBaseNameW(HANDLE, HMODULE, LPWSTR, DWORD);\n    DWORD GetModuleFileNameExA(HANDLE, HMODULE, LPSTR, DWORD);\n    DWORD GetModuleFileNameExW(HANDLE, HMODULE, LPWSTR, DWORD);\n    BOOL GetModuleInformation(HANDLE, HMODULE, LPMODULEINFO, DWORD);\n\n    /* Device Driver Information\n     * http://windowssdk.msdn.microsoft.com/library/ms682578.aspx */\n    BOOL EnumDeviceDrivers(LPVOID*, DWORD, LPDWORD);\n    DWORD GetDeviceDriverBaseNameA(LPVOID, LPSTR, DWORD);\n    DWORD GetDeviceDriverBaseNameW(LPVOID, LPWSTR, DWORD);\n    DWORD GetDeviceDriverFileNameA(LPVOID, LPSTR, DWORD);\n    DWORD GetDeviceDriverFileNameW(LPVOID, LPWSTR, DWORD);\n\n    /* Process Memory Usage Information\n     * http://windowssdk.msdn.microsoft.com/library/ms684879.aspx */\n    BOOL GetProcessMemoryInfo(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);\n\n    /* Working Set Information\n     * http://windowssdk.msdn.microsoft.com/library/ms687398.aspx */\n    BOOL EmptyWorkingSet(HANDLE);\n    BOOL GetWsChanges(HANDLE, PPSAPI_WS_WATCH_INFORMATION, DWORD);\n    BOOL GetWsChangesEx(HANDLE, PPSAPI_WS_WATCH_INFORMATION_EX, DWORD); /* Vista/Longhorn */\n    BOOL InitializeProcessForWsWatch(HANDLE);\n    BOOL QueryWorkingSet(HANDLE, PVOID, DWORD);\n    BOOL QueryWorkingSetEx(HANDLE, PVOID, DWORD);\n\n    /* Memory-Mapped File Information\n     * http://windowssdk.msdn.microsoft.com/library/ms684212.aspx */\n    DWORD GetMappedFileNameW(HANDLE, LPVOID, LPWSTR, DWORD);\n    DWORD GetMappedFileNameA(HANDLE, LPVOID, LPSTR, DWORD);\n\n    /* Resources Information */\n    BOOL GetPerformanceInfo(PPERFORMANCE_INFORMATION, DWORD); /* XP/Server2003/Vista/Longhorn */\n    BOOL EnumPageFilesW(PENUM_PAGE_FILE_CALLBACK, LPVOID); /* 2000/XP/Server2003/Vista/Longhorn */\n    BOOL EnumPageFilesA(PENUM_PAGE_FILE_CALLBACK, LPVOID); /* 2000/XP/Server2003/Vista/Longhorn */\n}\n\nversion (Unicode) {\n    alias GetModuleBaseNameW GetModuleBaseName;\n    alias GetModuleFileNameExW GetModuleFileNameEx;\n    alias GetMappedFileNameW GetMappedFileName;\n    alias GetDeviceDriverBaseNameW GetDeviceDriverBaseName;\n    alias GetDeviceDriverFileNameW GetDeviceDriverFileName;\n    alias EnumPageFilesW EnumPageFiles;\n    alias GetProcessImageFileNameW GetProcessImageFileName;\n} else {\n    alias GetModuleBaseNameA GetModuleBaseName;\n    alias GetModuleFileNameExA GetModuleFileNameEx;\n    alias GetMappedFileNameA GetMappedFileName;\n    alias GetDeviceDriverBaseNameA GetDeviceDriverBaseName;\n    alias GetDeviceDriverFileNameA GetDeviceDriverFileName;\n    alias EnumPageFilesA EnumPageFiles;\n    alias GetProcessImageFileNameA GetProcessImageFileName;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/rapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_rapi.d)\n */\nmodule core.sys.windows.rapi;\nversion (Windows):\n\n/* Comment from MinGW\n   NOTE: This strictly does not belong in the Win32 API since it's\n   really part of Platform SDK.\n */\n\nprivate import core.sys.windows.winbase, core.sys.windows.windef;\n\nextern (Windows):\n\nenum RAPISTREAMFLAG\n{\n    STREAM_TIMEOUT_READ\n}\n\ninterface IRAPIStream\n{\n    HRESULT SetRapiStat(RAPISTREAMFLAG, DWORD);\n    HRESULT GetRapiStat(RAPISTREAMFLAG, DWORD*);\n}\n\nalias HRESULT function(DWORD, BYTE, DWORD, BYTE, IRAPIStream) RAPIEXT;\n\nstruct RAPIINIT\n{\n    DWORD   cbSize = this.sizeof;\n    HANDLE  heRapiInit;\n    HRESULT hrRapiInit;\n}\n\nHRESULT CeRapiInit();\nHRESULT CeRapiInitEx(RAPIINIT*);\nBOOL CeCreateProcess(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES,\n  LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPWSTR, LPSTARTUPINFO,\n  LPPROCESS_INFORMATION);\nHRESULT CeRapiUninit();\nBOOL CeWriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);\nHANDLE CeCreateFile(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD,\n  DWORD, HANDLE);\nBOOL CeCreateDirectory(LPCWSTR, LPSECURITY_ATTRIBUTES);\nDWORD CeGetLastError();\nBOOL CeGetFileTime(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME);\nBOOL CeCloseHandle(HANDLE);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/ras.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_ras.d)\n */\nmodule core.sys.windows.ras;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"rasapi32\");\n\nprivate import core.sys.windows.basetyps, core.sys.windows.lmcons, core.sys.windows.w32api, core.sys.windows.windef;\n\nalign(4):\n\nenum RAS_MaxDeviceType = 16;\nenum RAS_MaxPhoneNumber = 128;\nenum RAS_MaxIpAddress = 15;\nenum RAS_MaxIpxAddress = 21;\nenum RAS_MaxEntryName = 256;\nenum RAS_MaxDeviceName = 128;\nenum RAS_MaxCallbackNumber = RAS_MaxPhoneNumber;\nenum RAS_MaxAreaCode = 10;\nenum RAS_MaxPadType = 32;\nenum RAS_MaxX25Address = 200;\nenum RAS_MaxFacilities = 200;\nenum RAS_MaxUserData = 200;\nenum RAS_MaxReplyMessage = 1024;\n\nenum RDEOPT_UsePrefixSuffix           = 0x00000001;\nenum RDEOPT_PausedStates              = 0x00000002;\nenum RDEOPT_IgnoreModemSpeaker        = 0x00000004;\nenum RDEOPT_SetModemSpeaker           = 0x00000008;\nenum RDEOPT_IgnoreSoftwareCompression = 0x00000010;\nenum RDEOPT_SetSoftwareCompression    = 0x00000020;\nenum RDEOPT_DisableConnectedUI        = 0x00000040;\nenum RDEOPT_DisableReconnectUI        = 0x00000080;\nenum RDEOPT_DisableReconnect          = 0x00000100;\nenum RDEOPT_NoUser                    = 0x00000200;\nenum RDEOPT_PauseOnScript             = 0x00000400;\nenum RDEOPT_Router                    = 0x00000800;\n\nenum REN_User = 0x00000000;\nenum REN_AllUsers = 0x00000001;\nenum VS_Default = 0;\nenum VS_PptpOnly = 1;\nenum VS_PptpFirst = 2;\nenum VS_L2tpOnly = 3;\nenum VS_L2tpFirst = 4;\n\nenum RASDIALEVENT = \"RasDialEvent\";\nenum WM_RASDIALEVENT = 0xCCCD;\n\nenum RASEO_UseCountryAndAreaCodes = 0x00000001;\nenum RASEO_SpecificIpAddr = 0x00000002;\nenum RASEO_SpecificNameServers = 0x00000004;\nenum RASEO_IpHeaderCompression = 0x00000008;\nenum RASEO_RemoteDefaultGateway = 0x00000010;\nenum RASEO_DisableLcpExtensions = 0x00000020;\nenum RASEO_TerminalBeforeDial = 0x00000040;\nenum RASEO_TerminalAfterDial = 0x00000080;\nenum RASEO_ModemLights = 0x00000100;\nenum RASEO_SwCompression = 0x00000200;\nenum RASEO_RequireEncryptedPw = 0x00000400;\nenum RASEO_RequireMsEncryptedPw = 0x00000800;\nenum RASEO_RequireDataEncryption = 0x00001000;\nenum RASEO_NetworkLogon = 0x00002000;\nenum RASEO_UseLogonCredentials = 0x00004000;\nenum RASEO_PromoteAlternates = 0x00008000;\nenum RASNP_NetBEUI = 0x00000001;\nenum RASNP_Ipx = 0x00000002;\nenum RASNP_Ip = 0x00000004;\nenum RASFP_Ppp = 0x00000001;\nenum RASFP_Slip = 0x00000002;\nenum RASFP_Ras = 0x00000004;\n\nconst TCHAR[]\n    RASDT_Modem = \"modem\",\n    RASDT_Isdn = \"isdn\",\n    RASDT_X25 = \"x25\",\n    RASDT_Vpn = \"vpn\",\n    RASDT_Pad = \"pad\",\n    RASDT_Generic = \"GENERIC\",\n    RASDT_Serial = \"SERIAL\",\n    RASDT_FrameRelay = \"FRAMERELAY\",\n    RASDT_Atm = \"ATM\",\n    RASDT_Sonet = \"SONET\",\n    RASDT_SW56 = \"SW56\",\n    RASDT_Irda = \"IRDA\",\n    RASDT_Parallel = \"PARALLEL\";\n\nenum RASET_Phone = 1;\nenum RASET_Vpn = 2;\nenum RASET_Direct = 3;\nenum RASET_Internet = 4;\n\nstatic if (_WIN32_WINNT >= 0x401) {\nenum RASEO_SecureLocalFiles = 0x00010000;\nenum RASCN_Connection = 0x00000001;\nenum RASCN_Disconnection = 0x00000002;\nenum RASCN_BandwidthAdded = 0x00000004;\nenum RASCN_BandwidthRemoved = 0x00000008;\nenum RASEDM_DialAll = 1;\nenum RASEDM_DialAsNeeded = 2;\nenum RASIDS_Disabled = 0xffffffff;\nenum RASIDS_UseGlobalValue = 0;\nenum RASADFLG_PositionDlg = 0x00000001;\nenum RASCM_UserName = 0x00000001;\nenum RASCM_Password = 0x00000002;\nenum RASCM_Domain = 0x00000004;\nenum RASADP_DisableConnectionQuery = 0;\nenum RASADP_LoginSessionDisable = 1;\nenum RASADP_SavedAddressesLimit = 2;\nenum RASADP_FailedConnectionTimeout = 3;\nenum RASADP_ConnectionQueryTimeout = 4;\n}\n//static if (_WIN32_WINNT >= 0x500) {\nenum RDEOPT_CustomDial = 0x00001000;\nenum RASLCPAP_PAP = 0xC023;\nenum RASLCPAP_SPAP = 0xC027;\nenum RASLCPAP_CHAP = 0xC223;\nenum RASLCPAP_EAP = 0xC227;\nenum RASLCPAD_CHAP_MD5 = 0x05;\nenum RASLCPAD_CHAP_MS = 0x80;\nenum RASLCPAD_CHAP_MSV2 = 0x81;\nenum RASLCPO_PFC    = 0x00000001;\nenum RASLCPO_ACFC   = 0x00000002;\nenum RASLCPO_SSHF   = 0x00000004;\nenum RASLCPO_DES_56 = 0x00000008;\nenum RASLCPO_3_DES  = 0x00000010;\n\nenum RASCCPCA_MPPC = 0x00000006;\nenum RASCCPCA_STAC = 0x00000005;\n\nenum RASCCPO_Compression      = 0x00000001;\nenum RASCCPO_HistoryLess      = 0x00000002;\nenum RASCCPO_Encryption56bit  = 0x00000010;\nenum RASCCPO_Encryption40bit  = 0x00000020;\nenum RASCCPO_Encryption128bit = 0x00000040;\n\nenum RASEO_RequireEAP          = 0x00020000;\nenum RASEO_RequirePAP          = 0x00040000;\nenum RASEO_RequireSPAP         = 0x00080000;\nenum RASEO_Custom              = 0x00100000;\nenum RASEO_PreviewPhoneNumber  = 0x00200000;\nenum RASEO_SharedPhoneNumbers  = 0x00800000;\nenum RASEO_PreviewUserPw       = 0x01000000;\nenum RASEO_PreviewDomain       = 0x02000000;\nenum RASEO_ShowDialingProgress = 0x04000000;\nenum RASEO_RequireCHAP         = 0x08000000;\nenum RASEO_RequireMsCHAP       = 0x10000000;\nenum RASEO_RequireMsCHAP2      = 0x20000000;\nenum RASEO_RequireW95MSCHAP    = 0x40000000;\nenum RASEO_CustomScript        = 0x80000000;\n\nenum RASIPO_VJ = 0x00000001;\nenum RCD_SingleUser = 0;\nenum RCD_AllUsers = 0x00000001;\nenum RCD_Eap = 0x00000002;\nenum RASEAPF_NonInteractive = 0x00000002;\nenum RASEAPF_Logon = 0x00000004;\nenum RASEAPF_Preview = 0x00000008;\nenum ET_40Bit = 1;\nenum ET_128Bit = 2;\nenum ET_None = 0;\nenum ET_Require = 1;\nenum ET_RequireMax = 2;\nenum ET_Optional = 3;\n//}\n\nenum RASCS_PAUSED = 0x1000;\nenum RASCS_DONE = 0x2000;\nenum RASCONNSTATE {\n    RASCS_OpenPort = 0,\n    RASCS_PortOpened,\n    RASCS_ConnectDevice,\n    RASCS_DeviceConnected,\n    RASCS_AllDevicesConnected,\n    RASCS_Authenticate,\n    RASCS_AuthNotify,\n    RASCS_AuthRetry,\n    RASCS_AuthCallback,\n    RASCS_AuthChangePassword,\n    RASCS_AuthProject,\n    RASCS_AuthLinkSpeed,\n    RASCS_AuthAck,\n    RASCS_ReAuthenticate,\n    RASCS_Authenticated,\n    RASCS_PrepareForCallback,\n    RASCS_WaitForModemReset,\n    RASCS_WaitForCallback,\n    RASCS_Projected,\n    RASCS_StartAuthentication,\n    RASCS_CallbackComplete,\n    RASCS_LogonNetwork,\n    RASCS_SubEntryConnected,\n    RASCS_SubEntryDisconnected,\n    RASCS_Interactive = RASCS_PAUSED,\n    RASCS_RetryAuthentication,\n    RASCS_CallbackSetByCaller,\n    RASCS_PasswordExpired,\n//  static if (_WIN32_WINNT >= 0x500) {\n        RASCS_InvokeEapUI,\n//  }\n    RASCS_Connected = RASCS_DONE,\n    RASCS_Disconnected\n}\nalias RASCONNSTATE* LPRASCONNSTATE;\n\nenum RASPROJECTION {\n    RASP_Amb =      0x10000,\n    RASP_PppNbf =   0x803F,\n    RASP_PppIpx =   0x802B,\n    RASP_PppIp =    0x8021,\n//  static if (_WIN32_WINNT >= 0x500) {\n        RASP_PppCcp =   0x80FD,\n//  }\n    RASP_PppLcp =   0xC021,\n    RASP_Slip =     0x20000\n}\nalias RASPROJECTION* LPRASPROJECTION;\n\nalias TypeDef!(HANDLE) HRASCONN;\nalias HRASCONN* LPHRASCONN;\n\nstruct RASCONNW {\nalign(4):\n    DWORD dwSize;\n    HRASCONN hrasconn;\n    align {\n    WCHAR[RAS_MaxEntryName + 1] szEntryName;\n    WCHAR[RAS_MaxDeviceType + 1] szDeviceType;\n    WCHAR[RAS_MaxDeviceName + 1] szDeviceName;\n    }\n    //static if (_WIN32_WINNT >= 0x401) {\n        WCHAR[MAX_PATH] szPhonebook;\n        DWORD dwSubEntry;\n    //}\n    //static if (_WIN32_WINNT >= 0x500) {\n        GUID guidEntry;\n    //}\n    static if (_WIN32_WINNT >= 0x501) {\n        DWORD dwFlags;\n        LUID luid;\n    }\n}\nalias RASCONNW* LPRASCONNW;\n\nstruct RASCONNA {\nalign(4):\n    DWORD dwSize;\n    HRASCONN hrasconn;\n    align {\n    CHAR[RAS_MaxEntryName + 1] szEntryName;\n    CHAR[RAS_MaxDeviceType + 1] szDeviceType;\n    CHAR[RAS_MaxDeviceName + 1] szDeviceName;\n    }\n    //static if (_WIN32_WINNT >= 0x401) {\n        CHAR[MAX_PATH] szPhonebook;\n        DWORD dwSubEntry;\n    //}\n    //static if (_WIN32_WINNT >= 0x500) {\n        GUID guidEntry;\n    //}\n    static if (_WIN32_WINNT >= 0x501) {\n        DWORD dwFlags;\n        LUID luid;\n    }\n}\nalias RASCONNA* LPRASCONNA;\n\nstruct RASCONNSTATUSW {\n    DWORD dwSize;\n    RASCONNSTATE rasconnstate;\n    DWORD dwError;\n    WCHAR[RAS_MaxDeviceType + 1] szDeviceType;\n    WCHAR[RAS_MaxDeviceName + 1] szDeviceName;\n    static if (_WIN32_WINNT >= 0x401) {\n        WCHAR[RAS_MaxPhoneNumber + 1] szPhoneNumber;\n    }\n}\nalias RASCONNSTATUSW* LPRASCONNSTATUSW;\n\nstruct RASCONNSTATUSA {\n    DWORD dwSize;\n    RASCONNSTATE rasconnstate;\n    DWORD dwError;\n    CHAR[RAS_MaxDeviceType + 1] szDeviceType;\n    CHAR[RAS_MaxDeviceName + 1] szDeviceName;\n    static if (_WIN32_WINNT >= 0x401) {\n        CHAR[RAS_MaxPhoneNumber + 1] szPhoneNumber;\n    }\n}\nalias RASCONNSTATUSA* LPRASCONNSTATUSA;\n\nstruct RASDIALPARAMSW {\nalign(4):\n    DWORD dwSize;\nalign {\n    WCHAR[RAS_MaxEntryName + 1] szEntryName;\n    WCHAR[RAS_MaxPhoneNumber + 1] szPhoneNumber;\n    WCHAR[RAS_MaxCallbackNumber + 1] szCallbackNumber;\n    WCHAR[UNLEN + 1] szUserName;\n    WCHAR[PWLEN + 1] szPassword;\n    WCHAR[DNLEN + 1] szDomain;\n}\n    static if (_WIN32_WINNT >= 0x401) {\n        DWORD dwSubEntry;\n        ULONG_PTR dwCallbackId;\n    }\n}\nalias RASDIALPARAMSW* LPRASDIALPARAMSW;\n\nstruct RASDIALPARAMSA{\nalign(4):\n    DWORD dwSize;\nalign {\n    CHAR[RAS_MaxEntryName + 1] szEntryName;\n    CHAR[RAS_MaxPhoneNumber + 1] szPhoneNumber;\n    CHAR[RAS_MaxCallbackNumber + 1] szCallbackNumber;\n    CHAR[UNLEN + 1] szUserName;\n    CHAR[PWLEN + 1] szPassword;\n    CHAR[DNLEN + 1] szDomain;\n}\n    static if (_WIN32_WINNT >= 0x401) {\n        DWORD dwSubEntry;\n        ULONG_PTR dwCallbackId;\n    }\n}\nalias RASDIALPARAMSA* LPRASDIALPARAMSA;\n\n//static if (_WIN32_WINNT >= 0x500) {\n    struct RASEAPINFO {\n    align(4):\n        DWORD dwSizeofEapInfo;\n        BYTE *pbEapInfo;\n    }\n//}\n\nstruct RASDIALEXTENSIONS {\nalign(4):\n    DWORD dwSize;\n    DWORD dwfOptions;\n    HWND hwndParent;\n    ULONG_PTR reserved;\n    //static if (_WIN32_WINNT >= 0x500) {\n        ULONG_PTR reserved1;\n        RASEAPINFO RasEapInfo;\n    //}\n}\nalias RASDIALEXTENSIONS* LPRASDIALEXTENSIONS;\n\nstruct RASENTRYNAMEW {\n    DWORD dwSize;\n    WCHAR[RAS_MaxEntryName + 1] szEntryName;\n    //static if (_WIN32_WINNT >= 0x500) {\n        DWORD dwFlags;\n        WCHAR[MAX_PATH + 1] szPhonebookPath;\n    //}\n}\nalias RASENTRYNAMEW* LPRASENTRYNAMEW;\n\nstruct RASENTRYNAMEA{\n    DWORD dwSize;\n    CHAR[RAS_MaxEntryName + 1] szEntryName;\n    //static if (_WIN32_WINNT >= 0x500) {\n        DWORD dwFlags;\n        CHAR[MAX_PATH + 1] szPhonebookPath;\n    //}\n}\nalias RASENTRYNAMEA* LPRASENTRYNAMEA;\n\nstruct RASAMBW{\n    DWORD dwSize;\n    DWORD dwError;\n    WCHAR[NETBIOS_NAME_LEN + 1] szNetBiosError;\n    BYTE bLana;\n}\nalias RASAMBW* LPRASAMBW;\n\nstruct RASAMBA{\n    DWORD dwSize;\n    DWORD dwError;\n    CHAR[NETBIOS_NAME_LEN + 1] szNetBiosError;\n    BYTE bLana;\n}\nalias RASAMBA* LPRASAMBA;\n\nstruct RASPPPNBFW{\n    DWORD dwSize;\n    DWORD dwError;\n    DWORD dwNetBiosError;\n    WCHAR[NETBIOS_NAME_LEN + 1] szNetBiosError;\n    WCHAR[NETBIOS_NAME_LEN + 1] szWorkstationName;\n    BYTE bLana;\n}\nalias RASPPPNBFW* LPRASPPPNBFW;\n\nstruct RASPPPNBFA{\n    DWORD dwSize;\n    DWORD dwError;\n    DWORD dwNetBiosError;\n    CHAR[NETBIOS_NAME_LEN + 1] szNetBiosError;\n    CHAR[NETBIOS_NAME_LEN + 1] szWorkstationName;\n    BYTE bLana;\n}\nalias RASPPPNBFA* LPRASPPPNBFA;\n\nstruct RASPPPIPXW {\n    DWORD dwSize;\n    DWORD dwError;\n    WCHAR[RAS_MaxIpxAddress + 1] szIpxAddress;\n}\nalias RASPPPIPXW* LPRASPPPIPXW;\n\nstruct RASPPPIPXA {\n    DWORD dwSize;\n    DWORD dwError;\n    CHAR[RAS_MaxIpxAddress + 1] szIpxAddress;\n}\nalias RASPPPIPXA* LPRASPPPIPXA;\n\nstruct RASPPPIPW{\n    DWORD dwSize;\n    DWORD dwError;\n    WCHAR[RAS_MaxIpAddress + 1] szIpAddress;\n    //#ifndef WINNT35COMPATIBLE\n    WCHAR[RAS_MaxIpAddress + 1] szServerIpAddress;\n    //#endif\n    //static if (_WIN32_WINNT >= 0x500) {\n        DWORD dwOptions;\n        DWORD dwServerOptions;\n    //}\n}\nalias RASPPPIPW* LPRASPPPIPW;\n\nstruct RASPPPIPA{\n    DWORD dwSize;\n    DWORD dwError;\n    CHAR[RAS_MaxIpAddress + 1] szIpAddress;\n    //#ifndef WINNT35COMPATIBLE\n    CHAR[RAS_MaxIpAddress + 1] szServerIpAddress;\n    //#endif\n    //static if (_WIN32_WINNT >= 0x500) {\n        DWORD dwOptions;\n        DWORD dwServerOptions;\n    //}\n}\nalias RASPPPIPA* LPRASPPPIPA;\n\nstruct RASPPPLCPW{\n    DWORD dwSize;\n    BOOL fBundled;\n    //static if (_WIN32_WINNT >= 0x500) {\n        DWORD dwError;\n        DWORD dwAuthenticationProtocol;\n        DWORD dwAuthenticationData;\n        DWORD dwEapTypeId;\n        DWORD dwServerAuthenticationProtocol;\n        DWORD dwServerAuthenticationData;\n        DWORD dwServerEapTypeId;\n        BOOL fMultilink;\n        DWORD dwTerminateReason;\n        DWORD dwServerTerminateReason;\n        WCHAR[RAS_MaxReplyMessage] szReplyMessage;\n        DWORD dwOptions;\n        DWORD dwServerOptions;\n    //}\n}\nalias RASPPPLCPW* LPRASPPPLCPW;\n\nstruct RASPPPLCPA{\n    DWORD dwSize;\n    BOOL fBundled;\n    //static if (_WIN32_WINNT >= 0x500) {\n        DWORD dwError;\n        DWORD dwAuthenticationProtocol;\n        DWORD dwAuthenticationData;\n        DWORD dwEapTypeId;\n        DWORD dwServerAuthenticationProtocol;\n        DWORD dwServerAuthenticationData;\n        DWORD dwServerEapTypeId;\n        BOOL fMultilink;\n        DWORD dwTerminateReason;\n        DWORD dwServerTerminateReason;\n        CHAR[RAS_MaxReplyMessage] szReplyMessage;\n        DWORD dwOptions;\n        DWORD dwServerOptions;\n    //}\n}\nalias RASPPPLCPA* LPRASPPPLCPA;\n\nstruct RASSLIPW{\n    DWORD dwSize;\n    DWORD dwError;\n    WCHAR[RAS_MaxIpAddress + 1] szIpAddress;\n}\nalias RASSLIPW* LPRASSLIPW;\n\nstruct RASSLIPA{\n    DWORD dwSize;\n    DWORD dwError;\n    CHAR[RAS_MaxIpAddress + 1] szIpAddress;\n}\nalias RASSLIPA* LPRASSLIPA;\n\nstruct RASDEVINFOW{\n    DWORD dwSize;\n    WCHAR[RAS_MaxDeviceType + 1] szDeviceType;\n    WCHAR[RAS_MaxDeviceName + 1] szDeviceName;\n}\nalias RASDEVINFOW* LPRASDEVINFOW;\n\nstruct RASDEVINFOA{\n    DWORD dwSize;\n    CHAR[RAS_MaxDeviceType + 1] szDeviceType;\n    CHAR[RAS_MaxDeviceName + 1] szDeviceName;\n}\nalias RASDEVINFOA* LPRASDEVINFOA;\n\nstruct RASCTRYINFO {\n    DWORD dwSize;\n    DWORD dwCountryID;\n    DWORD dwNextCountryID;\n    DWORD dwCountryCode;\n    DWORD dwCountryNameOffset;\n}\nalias RASCTRYINFO* LPRASCTRYINFO;\nalias RASCTRYINFO  RASCTRYINFOW, RASCTRYINFOA;\nalias RASCTRYINFOW* LPRASCTRYINFOW;\nalias RASCTRYINFOA* LPRASCTRYINFOA;\n\nstruct RASIPADDR {\n    BYTE a;\n    BYTE b;\n    BYTE c;\n    BYTE d;\n}\n\nstruct RASENTRYW {\n    DWORD dwSize;\n    DWORD dwfOptions;\n    DWORD dwCountryID;\n    DWORD dwCountryCode;\n    WCHAR[RAS_MaxAreaCode + 1] szAreaCode;\n    WCHAR[RAS_MaxPhoneNumber + 1] szLocalPhoneNumber;\n    DWORD dwAlternateOffset;\n    RASIPADDR ipaddr;\n    RASIPADDR ipaddrDns;\n    RASIPADDR ipaddrDnsAlt;\n    RASIPADDR ipaddrWins;\n    RASIPADDR ipaddrWinsAlt;\n    DWORD dwFrameSize;\n    DWORD dwfNetProtocols;\n    DWORD dwFramingProtocol;\n    WCHAR[MAX_PATH] szScript;\n    WCHAR[MAX_PATH] szAutodialDll;\n    WCHAR[MAX_PATH] szAutodialFunc;\n    WCHAR[RAS_MaxDeviceType + 1] szDeviceType;\n    WCHAR[RAS_MaxDeviceName + 1] szDeviceName;\n    WCHAR[RAS_MaxPadType + 1] szX25PadType;\n    WCHAR[RAS_MaxX25Address + 1] szX25Address;\n    WCHAR[RAS_MaxFacilities + 1] szX25Facilities;\n    WCHAR[RAS_MaxUserData + 1] szX25UserData;\n    DWORD dwChannels;\n    DWORD dwReserved1;\n    DWORD dwReserved2;\n    //static if (_WIN32_WINNT >= 0x401) {\n        DWORD dwSubEntries;\n        DWORD dwDialMode;\n        DWORD dwDialExtraPercent;\n        DWORD dwDialExtraSampleSeconds;\n        DWORD dwHangUpExtraPercent;\n        DWORD dwHangUpExtraSampleSeconds;\n        DWORD dwIdleDisconnectSeconds;\n    //}\n    //static if (_WIN32_WINNT >= 0x500) {\n        DWORD dwType;\n        DWORD dwEncryptionType;\n        DWORD dwCustomAuthKey;\n        GUID guidId;\n        WCHAR[MAX_PATH] szCustomDialDll;\n        DWORD dwVpnStrategy;\n    //}\n}\nalias RASENTRYW* LPRASENTRYW;\n\nstruct RASENTRYA {\n    DWORD dwSize;\n    DWORD dwfOptions;\n    DWORD dwCountryID;\n    DWORD dwCountryCode;\n    CHAR[RAS_MaxAreaCode + 1] szAreaCode;\n    CHAR[RAS_MaxPhoneNumber + 1] szLocalPhoneNumber;\n    DWORD dwAlternateOffset;\n    RASIPADDR ipaddr;\n    RASIPADDR ipaddrDns;\n    RASIPADDR ipaddrDnsAlt;\n    RASIPADDR ipaddrWins;\n    RASIPADDR ipaddrWinsAlt;\n    DWORD dwFrameSize;\n    DWORD dwfNetProtocols;\n    DWORD dwFramingProtocol;\n    CHAR[MAX_PATH] szScript;\n    CHAR[MAX_PATH] szAutodialDll;\n    CHAR[MAX_PATH] szAutodialFunc;\n    CHAR[RAS_MaxDeviceType + 1] szDeviceType;\n    CHAR[RAS_MaxDeviceName + 1] szDeviceName;\n    CHAR[RAS_MaxPadType + 1] szX25PadType;\n    CHAR[RAS_MaxX25Address + 1] szX25Address;\n    CHAR[RAS_MaxFacilities + 1] szX25Facilities;\n    CHAR[RAS_MaxUserData + 1] szX25UserData;\n    DWORD dwChannels;\n    DWORD dwReserved1;\n    DWORD dwReserved2;\n    //static if (_WIN32_WINNT >= 0x401) {\n        DWORD dwSubEntries;\n        DWORD dwDialMode;\n        DWORD dwDialExtraPercent;\n        DWORD dwDialExtraSampleSeconds;\n        DWORD dwHangUpExtraPercent;\n        DWORD dwHangUpExtraSampleSeconds;\n        DWORD dwIdleDisconnectSeconds;\n    //}\n    //static if (_WIN32_WINNT >= 0x500) {\n        DWORD dwType;\n        DWORD dwEncryptionType;\n        DWORD dwCustomAuthKey;\n        GUID guidId;\n        CHAR[MAX_PATH] szCustomDialDll;\n        DWORD dwVpnStrategy;\n    //}\n}\nalias RASENTRYA* LPRASENTRYA;\n\n\n//static if (_WIN32_WINNT >= 0x401) {\n    struct RASADPARAMS {\n    align(4):\n        DWORD dwSize;\n        HWND hwndOwner;\n        DWORD dwFlags;\n        LONG xDlg;\n        LONG yDlg;\n    }\n    alias RASADPARAMS* LPRASADPARAMS;\n\n    struct RASSUBENTRYW{\n        DWORD dwSize;\n        DWORD dwfFlags;\n        WCHAR[RAS_MaxDeviceType + 1] szDeviceType;\n        WCHAR[RAS_MaxDeviceName + 1] szDeviceName;\n        WCHAR[RAS_MaxPhoneNumber + 1] szLocalPhoneNumber;\n        DWORD dwAlternateOffset;\n    }\n    alias RASSUBENTRYW* LPRASSUBENTRYW;\n\n    struct RASSUBENTRYA{\n        DWORD dwSize;\n        DWORD dwfFlags;\n        CHAR[RAS_MaxDeviceType + 1] szDeviceType;\n        CHAR[RAS_MaxDeviceName + 1] szDeviceName;\n        CHAR[RAS_MaxPhoneNumber + 1] szLocalPhoneNumber;\n        DWORD dwAlternateOffset;\n    }\n    alias RASSUBENTRYA* LPRASSUBENTRYA;\n\n    struct RASCREDENTIALSW{\n        DWORD dwSize;\n        DWORD dwMask;\n        WCHAR[UNLEN + 1] szUserName;\n        WCHAR[PWLEN + 1] szPassword;\n        WCHAR[DNLEN + 1] szDomain;\n    }\n    alias RASCREDENTIALSW* LPRASCREDENTIALSW;\n\n    struct RASCREDENTIALSA{\n        DWORD dwSize;\n        DWORD dwMask;\n        CHAR[UNLEN + 1] szUserName;\n        CHAR[PWLEN + 1] szPassword;\n        CHAR[DNLEN + 1] szDomain;\n    }\n    alias RASCREDENTIALSA* LPRASCREDENTIALSA;\n\n    struct RASAUTODIALENTRYW{\n        DWORD dwSize;\n        DWORD dwFlags;\n        DWORD dwDialingLocation;\n        WCHAR[RAS_MaxEntryName + 1] szEntry;\n    }\n    alias RASAUTODIALENTRYW* LPRASAUTODIALENTRYW;\n\n    struct RASAUTODIALENTRYA{\n        DWORD dwSize;\n        DWORD dwFlags;\n        DWORD dwDialingLocation;\n        CHAR[RAS_MaxEntryName + 1] szEntry;\n    }\n    alias RASAUTODIALENTRYA* LPRASAUTODIALENTRYA;\n//}\n\n//static if (_WIN32_WINNT >= 0x500) {\n    struct RASPPPCCP{\n        DWORD dwSize;\n        DWORD dwError;\n        DWORD dwCompressionAlgorithm;\n        DWORD dwOptions;\n        DWORD dwServerCompressionAlgorithm;\n        DWORD dwServerOptions;\n    }\n    alias RASPPPCCP* LPRASPPPCCP;\n\n    struct RASEAPUSERIDENTITYW{\n        WCHAR[UNLEN + 1] szUserName;\n        DWORD dwSizeofEapInfo;\n        BYTE[1] pbEapInfo;\n    }\n    alias RASEAPUSERIDENTITYW* LPRASEAPUSERIDENTITYW;\n\n    struct RASEAPUSERIDENTITYA{\n        CHAR[UNLEN + 1] szUserName;\n        DWORD dwSizeofEapInfo;\n        BYTE[1] pbEapInfo;\n    }\n    alias RASEAPUSERIDENTITYA* LPRASEAPUSERIDENTITYA;\n\n    struct RAS_STATS{\n        DWORD dwSize;\n        DWORD dwBytesXmited;\n        DWORD dwBytesRcved;\n        DWORD dwFramesXmited;\n        DWORD dwFramesRcved;\n        DWORD dwCrcErr;\n        DWORD dwTimeoutErr;\n        DWORD dwAlignmentErr;\n        DWORD dwHardwareOverrunErr;\n        DWORD dwFramingErr;\n        DWORD dwBufferOverrunErr;\n        DWORD dwCompressionRatioIn;\n        DWORD dwCompressionRatioOut;\n        DWORD dwBps;\n        DWORD dwConnectDuration;\n    }\n    alias RAS_STATS* PRAS_STATS;\n//}\n\n\n/* UNICODE typedefs for structures*/\nversion (Unicode) {\n    alias RASCONNW RASCONN;\n    alias RASENTRYW RASENTRY;\n    alias RASCONNSTATUSW RASCONNSTATUS;\n    alias RASDIALPARAMSW RASDIALPARAMS;\n    alias RASAMBW RASAMB;\n    alias RASPPPNBFW RASPPPNBF;\n    alias RASPPPIPXW RASPPPIPX;\n    alias RASPPPIPW RASPPPIP;\n    alias RASPPPLCPW RASPPPLCP;\n    alias RASSLIPW RASSLIP;\n    alias RASDEVINFOW RASDEVINFO;\n    alias RASENTRYNAMEW RASENTRYNAME;\n\n    //static if (_WIN32_WINNT >= 0x401) {\n        alias RASSUBENTRYW RASSUBENTRY;\n        alias RASCREDENTIALSW RASCREDENTIALS;\n        alias RASAUTODIALENTRYW RASAUTODIALENTRY;\n    //}\n\n    //static if (_WIN32_WINNT >= 0x500) {\n        alias RASEAPUSERIDENTITYW RASEAPUSERIDENTITY;\n    //}\n\n} else { // ! defined UNICODE\n\n    alias RASCONNA RASCONN;\n    alias RASENTRYA  RASENTRY;\n    alias RASCONNSTATUSA RASCONNSTATUS;\n    alias RASDIALPARAMSA RASDIALPARAMS;\n    alias RASAMBA RASAMB;\n    alias RASPPPNBFA RASPPPNBF;\n    alias RASPPPIPXA RASPPPIPX;\n    alias RASPPPIPA RASPPPIP;\n    alias RASPPPLCPA RASPPPLCP;\n    alias RASSLIPA RASSLIP;\n    alias RASDEVINFOA  RASDEVINFO;\n    alias RASENTRYNAMEA RASENTRYNAME;\n\n    //static if (_WIN32_WINNT >= 0x401) {\n        alias RASSUBENTRYA RASSUBENTRY;\n        alias RASCREDENTIALSA RASCREDENTIALS;\n        alias RASAUTODIALENTRYA RASAUTODIALENTRY;\n    //}\n    //static if (_WIN32_WINNT >= 0x500) {\n        alias RASEAPUSERIDENTITYA RASEAPUSERIDENTITY;\n    //}\n}// ! UNICODE\n\n\nalias RASCONN* LPRASCONN;\nalias RASENTRY* LPRASENTRY;\nalias RASCONNSTATUS* LPRASCONNSTATUS;\nalias RASDIALPARAMS* LPRASDIALPARAMS;\nalias RASAMB* LPRASAM;\nalias RASPPPNBF* LPRASPPPNBF;\nalias RASPPPIPX* LPRASPPPIPX;\nalias RASPPPIP* LPRASPPPIP;\nalias RASPPPLCP* LPRASPPPLCP;\nalias RASSLIP* LPRASSLIP;\nalias RASDEVINFO* LPRASDEVINFO;\nalias RASENTRYNAME* LPRASENTRYNAME;\n\n//static if (_WIN32_WINNT >= 0x401) {\n    alias RASSUBENTRY* LPRASSUBENTRY;\n    alias RASCREDENTIALS* LPRASCREDENTIALS;\n    alias RASAUTODIALENTRY* LPRASAUTODIALENTRY;\n//}\n//static if (_WIN32_WINNT >= 0x500) {\n    alias RASEAPUSERIDENTITY* LPRASEAPUSERIDENTITY;\n//}\n\n/* Callback prototypes */\nextern (Windows) { /* WINAPI */\n    deprecated {\n        alias BOOL function (HWND, LPSTR, DWORD, LPDWORD) ORASADFUNC;\n    }\n\n    alias void function (UINT, RASCONNSTATE, DWORD) RASDIALFUNC;\n    alias void function(HRASCONN, UINT, RASCONNSTATE, DWORD, DWORD) RASDIALFUNC1;\n    alias DWORD function (ULONG_PTR, DWORD, HRASCONN, UINT,\n    RASCONNSTATE, DWORD, DWORD) RASDIALFUNC2;\n\n    /* External functions */\n    DWORD RasDialA(LPRASDIALEXTENSIONS, LPCSTR, LPRASDIALPARAMSA, DWORD, LPVOID, LPHRASCONN);\n    DWORD RasDialW(LPRASDIALEXTENSIONS, LPCWSTR, LPRASDIALPARAMSW, DWORD, LPVOID, LPHRASCONN);\n    DWORD RasEnumConnectionsA(LPRASCONNA, LPDWORD, LPDWORD);\n    DWORD RasEnumConnectionsW(LPRASCONNW, LPDWORD, LPDWORD);\n    DWORD RasEnumEntriesA(LPCSTR, LPCSTR, LPRASENTRYNAMEA, LPDWORD, LPDWORD);\n    DWORD RasEnumEntriesW(LPCWSTR, LPCWSTR, LPRASENTRYNAMEW, LPDWORD, LPDWORD);\n    DWORD RasGetConnectStatusA(HRASCONN, LPRASCONNSTATUSA);\n    DWORD RasGetConnectStatusW(HRASCONN, LPRASCONNSTATUSW);\n    DWORD RasGetErrorStringA(UINT, LPSTR, DWORD);\n    DWORD RasGetErrorStringW(UINT, LPWSTR, DWORD);\n    DWORD RasHangUpA(HRASCONN);\n    DWORD RasHangUpW(HRASCONN);\n    DWORD RasGetProjectionInfoA(HRASCONN, RASPROJECTION, LPVOID, LPDWORD);\n    DWORD RasGetProjectionInfoW(HRASCONN, RASPROJECTION, LPVOID, LPDWORD);\n    DWORD RasCreatePhonebookEntryA(HWND, LPCSTR);\n    DWORD RasCreatePhonebookEntryW(HWND, LPCWSTR);\n    DWORD RasEditPhonebookEntryA(HWND, LPCSTR, LPCSTR);\n    DWORD RasEditPhonebookEntryW(HWND, LPCWSTR, LPCWSTR);\n    DWORD RasSetEntryDialParamsA(LPCSTR, LPRASDIALPARAMSA, BOOL);\n    DWORD RasSetEntryDialParamsW(LPCWSTR, LPRASDIALPARAMSW, BOOL);\n    DWORD RasGetEntryDialParamsA(LPCSTR, LPRASDIALPARAMSA, LPBOOL);\n    DWORD RasGetEntryDialParamsW(LPCWSTR, LPRASDIALPARAMSW, LPBOOL);\n    DWORD RasEnumDevicesA(LPRASDEVINFOA, LPDWORD, LPDWORD);\n    DWORD RasEnumDevicesW(LPRASDEVINFOW, LPDWORD, LPDWORD);\n    DWORD RasGetCountryInfoA(LPRASCTRYINFOA, LPDWORD);\n    DWORD RasGetCountryInfoW(LPRASCTRYINFOW, LPDWORD);\n    DWORD RasGetEntryPropertiesA(LPCSTR, LPCSTR, LPRASENTRYA, LPDWORD, LPBYTE, LPDWORD);\n    DWORD RasGetEntryPropertiesW(LPCWSTR, LPCWSTR, LPRASENTRYW, LPDWORD, LPBYTE, LPDWORD);\n    DWORD RasSetEntryPropertiesA(LPCSTR, LPCSTR, LPRASENTRYA, DWORD, LPBYTE, DWORD);\n    DWORD RasSetEntryPropertiesW(LPCWSTR, LPCWSTR, LPRASENTRYW, DWORD, LPBYTE, DWORD);\n    DWORD RasRenameEntryA(LPCSTR, LPCSTR, LPCSTR);\n    DWORD RasRenameEntryW(LPCWSTR, LPCWSTR, LPCWSTR);\n    DWORD RasDeleteEntryA(LPCSTR, LPCSTR);\n    DWORD RasDeleteEntryW(LPCWSTR, LPCWSTR);\n    DWORD RasValidateEntryNameA(LPCSTR, LPCSTR);\n    DWORD RasValidateEntryNameW(LPCWSTR, LPCWSTR);\n\n//static if (_WIN32_WINNT >= 0x401) {\n    alias BOOL function(LPSTR, LPSTR, LPRASADPARAMS, LPDWORD) RASADFUNCA;\n    alias BOOL function(LPWSTR, LPWSTR, LPRASADPARAMS, LPDWORD) RASADFUNCW;\n\n    DWORD RasGetSubEntryHandleA(HRASCONN, DWORD, LPHRASCONN);\n    DWORD RasGetSubEntryHandleW(HRASCONN, DWORD, LPHRASCONN);\n    DWORD RasGetCredentialsA(LPCSTR, LPCSTR, LPRASCREDENTIALSA);\n    DWORD RasGetCredentialsW(LPCWSTR, LPCWSTR, LPRASCREDENTIALSW);\n    DWORD RasSetCredentialsA(LPCSTR, LPCSTR, LPRASCREDENTIALSA, BOOL);\n    DWORD RasSetCredentialsW(LPCWSTR, LPCWSTR, LPRASCREDENTIALSW, BOOL);\n    DWORD RasConnectionNotificationA(HRASCONN, HANDLE, DWORD);\n    DWORD RasConnectionNotificationW(HRASCONN, HANDLE, DWORD);\n    DWORD RasGetSubEntryPropertiesA(LPCSTR, LPCSTR, DWORD, LPRASSUBENTRYA, LPDWORD, LPBYTE, LPDWORD);\n    DWORD RasGetSubEntryPropertiesW(LPCWSTR, LPCWSTR, DWORD, LPRASSUBENTRYW, LPDWORD, LPBYTE, LPDWORD);\n    DWORD RasSetSubEntryPropertiesA(LPCSTR, LPCSTR, DWORD, LPRASSUBENTRYA, DWORD, LPBYTE, DWORD);\n    DWORD RasSetSubEntryPropertiesW(LPCWSTR, LPCWSTR, DWORD, LPRASSUBENTRYW, DWORD, LPBYTE, DWORD);\n    DWORD RasGetAutodialAddressA(LPCSTR, LPDWORD, LPRASAUTODIALENTRYA, LPDWORD, LPDWORD);\n    DWORD RasGetAutodialAddressW(LPCWSTR, LPDWORD, LPRASAUTODIALENTRYW, LPDWORD, LPDWORD);\n    DWORD RasSetAutodialAddressA(LPCSTR, DWORD, LPRASAUTODIALENTRYA, DWORD, DWORD);\n    DWORD RasSetAutodialAddressW(LPCWSTR, DWORD, LPRASAUTODIALENTRYW, DWORD, DWORD);\n    DWORD RasEnumAutodialAddressesA(LPSTR*, LPDWORD, LPDWORD);\n    DWORD RasEnumAutodialAddressesW(LPWSTR*, LPDWORD, LPDWORD);\n    DWORD RasGetAutodialEnableA(DWORD, LPBOOL);\n    DWORD RasGetAutodialEnableW(DWORD, LPBOOL);\n    DWORD RasSetAutodialEnableA(DWORD, BOOL);\n    DWORD RasSetAutodialEnableW(DWORD, BOOL);\n    DWORD RasGetAutodialParamA(DWORD, LPVOID, LPDWORD);\n    DWORD RasGetAutodialParamW(DWORD, LPVOID, LPDWORD);\n    DWORD RasSetAutodialParamA(DWORD, LPVOID, DWORD);\n    DWORD RasSetAutodialParamW(DWORD, LPVOID, DWORD);\n//}\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    alias DWORD function(HRASCONN) RasCustomHangUpFn;\n    alias DWORD function(LPCTSTR, LPCTSTR, DWORD) RasCustomDeleteEntryNotifyFn;\n    alias DWORD function(HINSTANCE, LPRASDIALEXTENSIONS, LPCTSTR, LPRASDIALPARAMS, DWORD, LPVOID,\n                         LPHRASCONN, DWORD) RasCustomDialFn;\n\n    DWORD RasInvokeEapUI(HRASCONN, DWORD, LPRASDIALEXTENSIONS, HWND);\n    DWORD RasGetLinkStatistics(HRASCONN, DWORD, RAS_STATS*);\n    DWORD RasGetConnectionStatistics(HRASCONN, RAS_STATS*);\n    DWORD RasClearLinkStatistics(HRASCONN, DWORD);\n    DWORD RasClearConnectionStatistics(HRASCONN);\n    DWORD RasGetEapUserDataA(HANDLE, LPCSTR, LPCSTR, BYTE*, DWORD*);\n    DWORD RasGetEapUserDataW(HANDLE, LPCWSTR, LPCWSTR, BYTE*, DWORD*);\n    DWORD RasSetEapUserDataA(HANDLE, LPCSTR, LPCSTR, BYTE*, DWORD);\n    DWORD RasSetEapUserDataW(HANDLE, LPCWSTR, LPCWSTR, BYTE*, DWORD);\n    DWORD RasGetCustomAuthDataA(LPCSTR, LPCSTR, BYTE*, DWORD*);\n    DWORD RasGetCustomAuthDataW(LPCWSTR, LPCWSTR, BYTE*, DWORD*);\n    DWORD RasSetCustomAuthDataA(LPCSTR, LPCSTR, BYTE*, DWORD);\n    DWORD RasSetCustomAuthDataW(LPCWSTR, LPCWSTR, BYTE*, DWORD);\n    DWORD RasGetEapUserIdentityW(LPCWSTR, LPCWSTR, DWORD, HWND, LPRASEAPUSERIDENTITYW*);\n    DWORD RasGetEapUserIdentityA(LPCSTR, LPCSTR, DWORD, HWND, LPRASEAPUSERIDENTITYA*);\n    void RasFreeEapUserIdentityW(LPRASEAPUSERIDENTITYW);\n    void RasFreeEapUserIdentityA(LPRASEAPUSERIDENTITYA);\n}\n} // extern (Windows)\n\n\n/* UNICODE defines for functions */\nversion (Unicode) {\n    alias RasDialW RasDial;\n    alias RasEnumConnectionsW RasEnumConnections;\n    alias RasEnumEntriesW RasEnumEntries;\n    alias RasGetConnectStatusW RasGetConnectStatus;\n    alias RasGetErrorStringW RasGetErrorString;\n    alias RasHangUpW RasHangUp;\n    alias RasGetProjectionInfoW RasGetProjectionInfo;\n    alias RasCreatePhonebookEntryW RasCreatePhonebookEntry;\n    alias RasEditPhonebookEntryW RasEditPhonebookEntry;\n    alias RasSetEntryDialParamsW RasSetEntryDialParams;\n    alias RasGetEntryDialParamsW RasGetEntryDialParams;\n    alias RasEnumDevicesW RasEnumDevices;\n    alias RasGetCountryInfoW RasGetCountryInfo;\n    alias RasGetEntryPropertiesW RasGetEntryProperties;\n    alias RasSetEntryPropertiesW RasSetEntryProperties;\n    alias RasRenameEntryW RasRenameEntry;\n    alias RasDeleteEntryW RasDeleteEntry;\n    alias RasValidateEntryNameW RasValidateEntryName;\n\n    //static if (_WIN32_WINNT >= 0x401) {\n        alias RASADFUNCW RASADFUNC;\n        alias RasGetSubEntryHandleW RasGetSubEntryHandle;\n        alias RasConnectionNotificationW RasConnectionNotification;\n        alias RasGetSubEntryPropertiesW RasGetSubEntryProperties;\n        alias RasSetSubEntryPropertiesW RasSetSubEntryProperties;\n        alias RasGetCredentialsW RasGetCredentials;\n        alias RasSetCredentialsW RasSetCredentials;\n        alias RasGetAutodialAddressW RasGetAutodialAddress;\n        alias RasSetAutodialAddressW RasSetAutodialAddress;\n        alias RasEnumAutodialAddressesW RasEnumAutodialAddresses;\n        alias RasGetAutodialEnableW RasGetAutodialEnable;\n        alias RasSetAutodialEnableW RasSetAutodialEnable;\n        alias RasGetAutodialParamW RasGetAutodialParam;\n        alias RasSetAutodialParamW RasSetAutodialParam;\n    //}\n\n    //static if (_WIN32_WINNT >= 0x500) {\n        alias RasGetEapUserDataW RasGetEapUserData;\n        alias RasSetEapUserDataW RasSetEapUserData;\n        alias RasGetCustomAuthDataW RasGetCustomAuthData;\n        alias RasSetCustomAuthDataW RasSetCustomAuthData;\n        alias RasGetEapUserIdentityW RasGetEapUserIdentity;\n        alias RasFreeEapUserIdentityW RasFreeEapUserIdentity;\n    //}\n\n} else { // !Unicode\n    alias RasDialA RasDial;\n    alias RasEnumConnectionsA RasEnumConnections;\n    alias RasEnumEntriesA RasEnumEntries;\n    alias RasGetConnectStatusA RasGetConnectStatus;\n    alias RasGetErrorStringA RasGetErrorString;\n    alias RasHangUpA RasHangUp;\n    alias RasGetProjectionInfoA RasGetProjectionInfo;\n    alias RasCreatePhonebookEntryA RasCreatePhonebookEntry;\n    alias RasEditPhonebookEntryA RasEditPhonebookEntry;\n    alias RasSetEntryDialParamsA RasSetEntryDialParams;\n    alias RasGetEntryDialParamsA RasGetEntryDialParams;\n    alias RasEnumDevicesA RasEnumDevices;\n    alias RasGetCountryInfoA RasGetCountryInfo;\n    alias RasGetEntryPropertiesA RasGetEntryProperties;\n    alias RasSetEntryPropertiesA RasSetEntryProperties;\n    alias RasRenameEntryA RasRenameEntry;\n    alias RasDeleteEntryA RasDeleteEntry;\n    alias RasValidateEntryNameA RasValidateEntryName;\n\n    //static if (_WIN32_WINNT >= 0x401) {\n        alias RASADFUNCA RASADFUNC;\n        alias RasGetSubEntryHandleA RasGetSubEntryHandle;\n        alias RasConnectionNotificationA RasConnectionNotification;\n        alias RasGetSubEntryPropertiesA RasGetSubEntryProperties;\n        alias RasSetSubEntryPropertiesA RasSetSubEntryProperties;\n        alias RasGetCredentialsA RasGetCredentials;\n        alias RasSetCredentialsA RasSetCredentials;\n        alias RasGetAutodialAddressA RasGetAutodialAddress;\n        alias RasSetAutodialAddressA RasSetAutodialAddress;\n        alias RasEnumAutodialAddressesA RasEnumAutodialAddresses;\n        alias RasGetAutodialEnableA RasGetAutodialEnable;\n        alias RasSetAutodialEnableA RasSetAutodialEnable;\n        alias RasGetAutodialParamA RasGetAutodialParam;\n        alias RasSetAutodialParamA RasSetAutodialParam;\n    //}\n\n    //static if (_WIN32_WINNT >= 0x500) {\n        alias RasGetEapUserDataA RasGetEapUserData;\n        alias RasSetEapUserDataA RasSetEapUserData;\n        alias RasGetCustomAuthDataA RasGetCustomAuthData;\n        alias RasSetCustomAuthDataA RasSetCustomAuthData;\n        alias RasGetEapUserIdentityA RasGetEapUserIdentity;\n        alias RasFreeEapUserIdentityA RasFreeEapUserIdentity;\n    //}\n} //#endif // !Unicode\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/rasdlg.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_rasdlg.d)\n */\nmodule core.sys.windows.rasdlg;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nimport core.sys.windows.ras;\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\nenum {\n    RASPBDEVENT_AddEntry = 1,\n    RASPBDEVENT_EditEntry,\n    RASPBDEVENT_RemoveEntry,\n    RASPBDEVENT_DialEntry,\n    RASPBDEVENT_EditGlobals,\n    RASPBDEVENT_NoUser,\n    RASPBDEVENT_NoUserEdit\n}\n\nenum RASPBDFLAG_PositionDlg      =  1;\nenum RASPBDFLAG_ForceCloseOnDial =  2;\nenum RASPBDFLAG_NoUser           = 16;\n\nenum RASEDFLAG_PositionDlg = 1;\nenum RASEDFLAG_NewEntry    = 2;\nenum RASEDFLAG_CloneEntry  = 4;\n\nenum RASDDFLAG_PositionDlg = 1;\n\nalign(4):\n\nstruct RASENTRYDLGA {\nalign(4):\n    DWORD     dwSize = RASENTRYDLGA.sizeof;\n    HWND      hwndOwner;\n    DWORD     dwFlags;\n    LONG      xDlg;\n    LONG      yDlg;\n    CHAR[RAS_MaxEntryName + 1] szEntry;\n    DWORD     dwError;\n    ULONG_PTR reserved;\n    ULONG_PTR reserved2;\n}\nalias RASENTRYDLGA* LPRASENTRYDLGA;\n\nstruct RASENTRYDLGW {\nalign(4):\n    DWORD     dwSize = RASENTRYDLGW.sizeof;\n    HWND      hwndOwner;\n    DWORD     dwFlags;\n    LONG      xDlg;\n    LONG      yDlg;\n    WCHAR[RAS_MaxEntryName + 1] szEntry;\n    DWORD     dwError;\n    ULONG_PTR reserved;\n    ULONG_PTR reserved2;\n}\nalias RASENTRYDLGW* LPRASENTRYDLGW;\n\nstruct RASDIALDLG {\nalign(4):\n    DWORD     dwSize;\n    HWND      hwndOwner;\n    DWORD     dwFlags;\n    LONG      xDlg;\n    LONG      yDlg;\n    DWORD     dwSubEntry;\n    DWORD     dwError;\n    ULONG_PTR reserved;\n    ULONG_PTR reserved2;\n}\nalias RASDIALDLG* LPRASDIALDLG;\n\n// Application-defined callback functions\nextern (Windows) {\n    alias VOID function(ULONG_PTR, DWORD, LPWSTR, LPVOID) RASPBDLGFUNCW;\n    alias VOID function(ULONG_PTR, DWORD, LPSTR, LPVOID) RASPBDLGFUNCA;\n}\n\nstruct RASPBDLGA {\nalign(4):\n    DWORD         dwSize = RASPBDLGA.sizeof;\n    HWND          hwndOwner;\n    DWORD         dwFlags;\n    LONG          xDlg;\n    LONG          yDlg;\n    ULONG_PTR     dwCallbackId;\n    RASPBDLGFUNCA pCallback;\n    DWORD         dwError;\n    ULONG_PTR     reserved;\n    ULONG_PTR     reserved2;\n}\nalias RASPBDLGA* LPRASPBDLGA;\n\nstruct RASPBDLGW {\nalign(4):\n    DWORD         dwSize = RASPBDLGW.sizeof;\n    HWND          hwndOwner;\n    DWORD         dwFlags;\n    LONG          xDlg;\n    LONG          yDlg;\n    ULONG_PTR     dwCallbackId;\n    RASPBDLGFUNCW pCallback;\n    DWORD         dwError;\n    ULONG_PTR     reserved;\n    ULONG_PTR     reserved2;\n}\nalias RASPBDLGW* LPRASPBDLGW;\n\nstruct RASNOUSERA\n{\n    DWORD           dwSize = RASNOUSERA.sizeof;\n    DWORD           dwFlags;\n    DWORD           dwTimeoutMs;\n    CHAR[UNLEN + 1] szUserName;\n    CHAR[PWLEN + 1] szPassword;\n    CHAR[DNLEN + 1] szDomain;\n}\nalias RASNOUSERA* LPRASNOUSERA;\n\nstruct RASNOUSERW {\n    DWORD            dwSize = RASNOUSERW.sizeof;\n    DWORD            dwFlags;\n    DWORD            dwTimeoutMs;\n    WCHAR[UNLEN + 1] szUserName;\n    WCHAR[PWLEN + 1] szPassword;\n    WCHAR[DNLEN + 1] szDomain;\n}\nalias RASNOUSERW* LPRASNOUSERW;\n\nextern (Windows) {\n    BOOL RasDialDlgA(LPSTR, LPSTR, LPSTR, LPRASDIALDLG);\n    BOOL RasDialDlgW(LPWSTR, LPWSTR, LPWSTR, LPRASDIALDLG);\n    BOOL RasEntryDlgA(LPSTR, LPSTR, LPRASENTRYDLGA);\n    BOOL RasEntryDlgW(LPWSTR, LPWSTR, LPRASENTRYDLGW);\n    BOOL RasPhonebookDlgA(LPSTR, LPSTR, LPRASPBDLGA);\n    BOOL RasPhonebookDlgW(LPWSTR, LPWSTR, LPRASPBDLGW);\n}\n\nversion (Unicode) {\n    alias RASENTRYDLGW RASENTRYDLG;\n    alias RASPBDLGW RASPBDLG;\n    alias RASNOUSERW RASNOUSER;\n    alias RasDialDlgW RasDialDlg;\n    alias RasEntryDlgW RasEntryDlg;\n    alias RasPhonebookDlgW RasPhonebookDlg;\n} else {\n    alias RASENTRYDLGA RASENTRYDLG;\n    alias RASPBDLGA RASPBDLG;\n    alias RASNOUSERA RASNOUSER;\n    alias RasDialDlgA RasDialDlg;\n    alias RasEntryDlgA RasEntryDlg;\n    alias RasPhonebookDlgA RasPhonebookDlg;\n}\n\nalias RASENTRYDLG* LPRASENTRYDLG;\nalias RASPBDLG* LPRASPBDLG;\nalias RASNOUSER* LPRASNOUSER;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/raserror.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_raserror.d)\n */\nmodule core.sys.windows.raserror;\nversion (Windows):\n\nenum {\n    SUCCESS = 0,\n    RASBASE = 600,\n    PENDING = RASBASE,\n    ERROR_INVALID_PORT_HANDLE,\n    ERROR_PORT_ALREADY_OPEN,\n    ERROR_BUFFER_TOO_SMALL,\n    ERROR_WRONG_INFO_SPECIFIED,\n    ERROR_CANNOT_SET_PORT_INFO,\n    ERROR_PORT_NOT_CONNECTED,\n    ERROR_EVENT_INVALID,\n    ERROR_DEVICE_DOES_NOT_EXIST,\n    ERROR_DEVICETYPE_DOES_NOT_EXIST,\n    ERROR_BUFFER_INVALID,\n    ERROR_ROUTE_NOT_AVAILABLE,\n    ERROR_ROUTE_NOT_ALLOCATED,\n    ERROR_INVALID_COMPRESSION_SPECIFIED,\n    ERROR_OUT_OF_BUFFERS,\n    ERROR_PORT_NOT_FOUND,\n    ERROR_ASYNC_REQUEST_PENDING,\n    ERROR_ALREADY_DISCONNECTING,\n    ERROR_PORT_NOT_OPEN,\n    ERROR_PORT_DISCONNECTED,\n    ERROR_NO_ENDPOINTS,\n    ERROR_CANNOT_OPEN_PHONEBOOK,\n    ERROR_CANNOT_LOAD_PHONEBOOK,\n    ERROR_CANNOT_FIND_PHONEBOOK_ENTRY,\n    ERROR_CANNOT_WRITE_PHONEBOOK,\n    ERROR_CORRUPT_PHONEBOOK,\n    ERROR_CANNOT_LOAD_STRING,\n    ERROR_KEY_NOT_FOUND,\n    ERROR_DISCONNECTION,\n    ERROR_REMOTE_DISCONNECTION,\n    ERROR_HARDWARE_FAILURE,\n    ERROR_USER_DISCONNECTION,\n    ERROR_INVALID_SIZE,\n    ERROR_PORT_NOT_AVAILABLE,\n    ERROR_CANNOT_PROJECT_CLIENT,\n    ERROR_UNKNOWN,\n    ERROR_WRONG_DEVICE_ATTACHED,\n    ERROR_BAD_STRING,\n    ERROR_REQUEST_TIMEOUT,\n    ERROR_CANNOT_GET_LANA,\n    ERROR_NETBIOS_ERROR,\n    ERROR_SERVER_OUT_OF_RESOURCES,\n    ERROR_NAME_EXISTS_ON_NET,\n    ERROR_SERVER_GENERAL_NET_FAILURE,\n    WARNING_MSG_ALIAS_NOT_ADDED,\n    ERROR_AUTH_INTERNAL,\n    ERROR_RESTRICTED_LOGON_HOURS,\n    ERROR_ACCT_DISABLED,\n    ERROR_PASSWD_EXPIRED,\n    ERROR_NO_DIALIN_PERMISSION,\n    ERROR_SERVER_NOT_RESPONDING,\n    ERROR_FROM_DEVICE,\n    ERROR_UNRECOGNIZED_RESPONSE,\n    ERROR_MACRO_NOT_FOUND,\n    ERROR_MACRO_NOT_DEFINED,\n    ERROR_MESSAGE_MACRO_NOT_FOUND,\n    ERROR_DEFAULTOFF_MACRO_NOT_FOUND,\n    ERROR_FILE_COULD_NOT_BE_OPENED,\n    ERROR_DEVICENAME_TOO_LONG,\n    ERROR_DEVICENAME_NOT_FOUND,\n    ERROR_NO_RESPONSES,\n    ERROR_NO_COMMAND_FOUND,\n    ERROR_WRONG_KEY_SPECIFIED,\n    ERROR_UNKNOWN_DEVICE_TYPE,\n    ERROR_ALLOCATING_MEMORY,\n    ERROR_PORT_NOT_CONFIGURED,\n    ERROR_DEVICE_NOT_READY,\n    ERROR_READING_INI_FILE,\n    ERROR_NO_CONNECTION,\n    ERROR_BAD_USAGE_IN_INI_FILE,\n    ERROR_READING_SECTIONNAME,\n    ERROR_READING_DEVICETYPE,\n    ERROR_READING_DEVICENAME,\n    ERROR_READING_USAGE,\n    ERROR_READING_MAXCONNECTBPS,\n    ERROR_READING_MAXCARRIERBPS,\n    ERROR_LINE_BUSY,\n    ERROR_VOICE_ANSWER,\n    ERROR_NO_ANSWER,\n    ERROR_NO_CARRIER,\n    ERROR_NO_DIALTONE,\n    ERROR_IN_COMMAND,\n    ERROR_WRITING_SECTIONNAME,\n    ERROR_WRITING_DEVICETYPE,\n    ERROR_WRITING_DEVICENAME,\n    ERROR_WRITING_MAXCONNECTBPS,\n    ERROR_WRITING_MAXCARRIERBPS,\n    ERROR_WRITING_USAGE,\n    ERROR_WRITING_DEFAULTOFF,\n    ERROR_READING_DEFAULTOFF,\n    ERROR_EMPTY_INI_FILE,\n    ERROR_AUTHENTICATION_FAILURE,\n    ERROR_PORT_OR_DEVICE,\n    ERROR_NOT_BINARY_MACRO,\n    ERROR_DCB_NOT_FOUND,\n    ERROR_STATE_MACHINES_NOT_STARTED,\n    ERROR_STATE_MACHINES_ALREADY_STARTED,\n    ERROR_PARTIAL_RESPONSE_LOOPING,\n    ERROR_UNKNOWN_RESPONSE_KEY,\n    ERROR_RECV_BUF_FULL,\n    ERROR_CMD_TOO_LONG,\n    ERROR_UNSUPPORTED_BPS,\n    ERROR_UNEXPECTED_RESPONSE,\n    ERROR_INTERACTIVE_MODE,\n    ERROR_BAD_CALLBACK_NUMBER,\n    ERROR_INVALID_AUTH_STATE,\n    ERROR_WRITING_INITBPS,\n    ERROR_X25_DIAGNOSTIC,\n    ERROR_ACCT_EXPIRED,\n    ERROR_CHANGING_PASSWORD,\n    ERROR_OVERRUN,\n    ERROR_RASMAN_CANNOT_INITIALIZE,\n    ERROR_BIPLEX_PORT_NOT_AVAILABLE,\n    ERROR_NO_ACTIVE_ISDN_LINES,\n    ERROR_NO_ISDN_CHANNELS_AVAILABLE,\n    ERROR_TOO_MANY_LINE_ERRORS,\n    ERROR_IP_CONFIGURATION,\n    ERROR_NO_IP_ADDRESSES,\n    ERROR_PPP_TIMEOUT,\n    ERROR_PPP_REMOTE_TERMINATED,\n    ERROR_PPP_NO_PROTOCOLS_CONFIGURED,\n    ERROR_PPP_NO_RESPONSE,\n    ERROR_PPP_INVALID_PACKET,\n    ERROR_PHONE_NUMBER_TOO_LONG,\n    ERROR_IPXCP_NO_DIALOUT_CONFIGURED,\n    ERROR_IPXCP_NO_DIALIN_CONFIGURED,\n    ERROR_IPXCP_DIALOUT_ALREADY_ACTIVE,\n    ERROR_ACCESSING_TCPCFGDLL,\n    ERROR_NO_IP_RAS_ADAPTER,\n    ERROR_SLIP_REQUIRES_IP,\n    ERROR_PROJECTION_NOT_COMPLETE,\n    ERROR_PROTOCOL_NOT_CONFIGURED,\n    ERROR_PPP_NOT_CONVERGING,\n    ERROR_PPP_CP_REJECTED,\n    ERROR_PPP_LCP_TERMINATED,\n    ERROR_PPP_REQUIRED_ADDRESS_REJECTED,\n    ERROR_PPP_NCP_TERMINATED,\n    ERROR_PPP_LOOPBACK_DETECTED,\n    ERROR_PPP_NO_ADDRESS_ASSIGNED,\n    ERROR_CANNOT_USE_LOGON_CREDENTIALS,\n    ERROR_TAPI_CONFIGURATION,\n    ERROR_NO_LOCAL_ENCRYPTION,\n    ERROR_NO_REMOTE_ENCRYPTION,\n    ERROR_REMOTE_REQUIRES_ENCRYPTION,\n    ERROR_IPXCP_NET_NUMBER_CONFLICT,\n    ERROR_INVALID_SMM,\n    ERROR_SMM_UNINITIALIZED,\n    ERROR_NO_MAC_FOR_PORT,\n    ERROR_SMM_TIMEOUT,\n    ERROR_BAD_PHONE_NUMBER,\n    ERROR_WRONG_MODULE,\n    ERROR_INVALID_CALLBACK_NUMBER,\n    ERROR_SCRIPT_SYNTAX,\n    ERROR_HANGUP_FAILED,\n    ERROR_BUNDLE_NOT_FOUND,\n    ERROR_CANNOT_DO_CUSTOMDIAL,\n    ERROR_DIAL_ALREADY_IN_PROGRESS,\n    ERROR_RASAUTO_CANNOT_INITIALIZE,\n    ERROR_CONNECTION_ALREADY_SHARED,\n    ERROR_SHARING_CHANGE_FAILED,\n    ERROR_SHARING_ROUTER_INSTALL,\n    ERROR_SHARE_CONNECTION_FAILED,\n    ERROR_SHARING_PRIVATE_INSTALL,\n    ERROR_CANNOT_SHARE_CONNECTION,\n    ERROR_NO_SMART_CARD_READER,\n    ERROR_SHARING_ADDRESS_EXISTS,\n    ERROR_NO_CERTIFICATE,\n    ERROR_SHARING_MULTIPLE_ADDRESSES,\n    ERROR_FAILED_TO_ENCRYPT,\n    ERROR_BAD_ADDRESS_SPECIFIED,\n    ERROR_CONNECTION_REJECT,\n    ERROR_CONGESTION,\n    ERROR_INCOMPATIBLE,\n    ERROR_NUMBERCHANGED,\n    ERROR_TEMPFAILURE,\n    ERROR_BLOCKED,\n    ERROR_DONOTDISTURB,\n    ERROR_OUTOFORDER,\n    ERROR_UNABLE_TO_AUTHENTICATE_SERVER,\n    ERROR_SMART_CARD_REQUIRED,\n    ERROR_INVALID_FUNCTION_FOR_ENTRY,\n    ERROR_CERT_FOR_ENCRYPTION_NOT_FOUND,\n    ERROR_SHARING_RRAS_CONFLICT,\n    ERROR_SHARING_NO_PRIVATE_LAN,\n    ERROR_NO_DIFF_USER_AT_LOGON,\n    ERROR_NO_REG_CERT_AT_LOGON,\n    ERROR_OAKLEY_NO_CERT,\n    ERROR_OAKLEY_AUTH_FAIL,\n    ERROR_OAKLEY_ATTRIB_FAIL,\n    ERROR_OAKLEY_GENERAL_PROCESSING,\n    ERROR_OAKLEY_NO_PEER_CERT,\n    ERROR_OAKLEY_NO_POLICY,\n    ERROR_OAKLEY_TIMED_OUT,\n    ERROR_OAKLEY_ERROR,\n    ERROR_UNKNOWN_FRAMED_PROTOCOL,\n    ERROR_WRONG_TUNNEL_TYPE,\n    ERROR_UNKNOWN_SERVICE_TYPE,\n    ERROR_CONNECTING_DEVICE_NOT_FOUND,\n    ERROR_NO_EAPTLS_CERTIFICATE, // = RASBASE+198\n    RASBASEEND = ERROR_NO_EAPTLS_CERTIFICATE\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/rassapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_rassapi.d)\n */\nmodule core.sys.windows.rassapi;\nversion (Windows):\n\nprivate import core.sys.windows.lmcons, core.sys.windows.windef;\n\n// FIXME: check types of constants\n\nenum size_t\n    RASSAPI_MAX_PHONENUMBER_SIZE = 128,\n    RASSAPI_MAX_MEDIA_NAME       =  16,\n    RASSAPI_MAX_PORT_NAME        =  16,\n    RASSAPI_MAX_DEVICE_NAME      = 128,\n    RASSAPI_MAX_DEVICETYPE_NAME  =  16,\n    RASSAPI_MAX_PARAM_KEY_SIZE   =  32;\n\nenum RASPRIV_NoCallback        = 0x01;\nenum RASPRIV_AdminSetCallback  = 0x02;\nenum RASPRIV_CallerSetCallback = 0x04;\nenum RASPRIV_DialinPrivilege   = 0x08;\nenum RASPRIV_CallbackType      = 0x07;\n\nenum {\n    RAS_MODEM_OPERATIONAL = 1,\n    RAS_MODEM_NOT_RESPONDING,\n    RAS_MODEM_HARDWARE_FAILURE,\n    RAS_MODEM_INCORRECT_RESPONSE,\n    RAS_MODEM_UNKNOWN  // = 5\n}\n\nenum {\n    RAS_PORT_NON_OPERATIONAL = 1,\n    RAS_PORT_DISCONNECTED,\n    RAS_PORT_CALLING_BACK,\n    RAS_PORT_LISTENING,\n    RAS_PORT_AUTHENTICATING,\n    RAS_PORT_AUTHENTICATED,\n    RAS_PORT_INITIALIZING // = 7\n}\n\nenum {\n    MEDIA_UNKNOWN,\n    MEDIA_SERIAL,\n    MEDIA_RAS10_SERIAL,\n    MEDIA_X25,\n    MEDIA_ISDN\n}\n\nenum USER_AUTHENTICATED = 0x0001;\nenum MESSENGER_PRESENT  = 0x0002;\nenum PPP_CLIENT         = 0x0004;\nenum GATEWAY_ACTIVE     = 0x0008;\nenum REMOTE_LISTEN      = 0x0010;\nenum PORT_MULTILINKED   = 0x0020;\n\nenum size_t\n    RAS_IPADDRESSLEN  = 15,\n    RAS_IPXADDRESSLEN = 22,\n    RAS_ATADDRESSLEN  = 32;\n\n// FIXME: should these be grouped together?\nenum {\n    RASDOWNLEVEL     = 10,\n    RASADMIN_35      = 35,\n    RASADMIN_CURRENT = 40\n}\n\nalias ULONG IPADDR;\n\nenum RAS_PARAMS_FORMAT {\n    ParamNumber = 0,\n    ParamString\n}\n\nunion RAS_PARAMS_VALUE {\n    DWORD Number;\n    struct _String {\n        DWORD Length;\n        PCHAR Data;\n    }\n    _String String;\n}\n\nstruct RAS_PARAMETERS {\n    CHAR[RASSAPI_MAX_PARAM_KEY_SIZE] P_Key;\n    RAS_PARAMS_FORMAT                P_Type;\n    BYTE                             P_Attributes;\n    RAS_PARAMS_VALUE                 P_Value;\n}\n\nstruct RAS_USER_0 {\n    BYTE                                    bfPrivilege;\n    WCHAR[RASSAPI_MAX_PHONENUMBER_SIZE + 1] szPhoneNumber;\n}\nalias RAS_USER_0* PRAS_USER_0;\n\nstruct RAS_PORT_0 {\n    WCHAR[RASSAPI_MAX_PORT_NAME]       wszPortName;\n    WCHAR[RASSAPI_MAX_DEVICETYPE_NAME] wszDeviceType;\n    WCHAR[RASSAPI_MAX_DEVICE_NAME]     wszDeviceName;\n    WCHAR[RASSAPI_MAX_MEDIA_NAME]      wszMediaName;\n    DWORD                              reserved;\n    DWORD                              Flags;\n    WCHAR[UNLEN + 1]                   wszUserName;\n    WCHAR[NETBIOS_NAME_LEN]            wszComputer;\n    DWORD                              dwStartSessionTime; // seconds from 1/1/1970\n    WCHAR[DNLEN + 1]                   wszLogonDomain;\n    BOOL                               fAdvancedServer;\n}\nalias RAS_PORT_0* PRAS_PORT_0;\n\nstruct RAS_PPP_NBFCP_RESULT {\n    DWORD dwError;\n    DWORD dwNetBiosError;\n    CHAR[NETBIOS_NAME_LEN + 1]  szName;\n    WCHAR[NETBIOS_NAME_LEN + 1] wszWksta;\n}\n\nstruct RAS_PPP_IPCP_RESULT {\n    DWORD dwError;\n    WCHAR[RAS_IPADDRESSLEN + 1] wszAddress;\n}\n\nstruct RAS_PPP_IPXCP_RESULT {\n    DWORD dwError;\n    WCHAR[RAS_IPXADDRESSLEN + 1] wszAddress;\n}\n\nstruct RAS_PPP_ATCP_RESULT {\n    DWORD dwError;\n    WCHAR[RAS_ATADDRESSLEN + 1] wszAddress;\n}\n\nstruct RAS_PPP_PROJECTION_RESULT {\n    RAS_PPP_NBFCP_RESULT nbf;\n    RAS_PPP_IPCP_RESULT  ip;\n    RAS_PPP_IPXCP_RESULT ipx;\n    RAS_PPP_ATCP_RESULT  at;\n}\n\nstruct RAS_PORT_1 {\n    RAS_PORT_0 rasport0;\n    DWORD      LineCondition;\n    DWORD      HardwareCondition;\n    DWORD      LineSpeed;\n    WORD       NumStatistics;\n    WORD       NumMediaParms;\n    DWORD      SizeMediaParms;\n    RAS_PPP_PROJECTION_RESULT ProjResult;\n}\nalias RAS_PORT_1* PRAS_PORT_1;\n\nstruct RAS_PORT_STATISTICS {\n    DWORD dwBytesXmited;\n    DWORD dwBytesRcved;\n    DWORD dwFramesXmited;\n    DWORD dwFramesRcved;\n    DWORD dwCrcErr;\n    DWORD dwTimeoutErr;\n    DWORD dwAlignmentErr;\n    DWORD dwHardwareOverrunErr;\n    DWORD dwFramingErr;\n    DWORD dwBufferOverrunErr;\n    DWORD dwBytesXmitedUncompressed;\n    DWORD dwBytesRcvedUncompressed;\n    DWORD dwBytesXmitedCompressed;\n    DWORD dwBytesRcvedCompressed;\n    DWORD dwPortBytesXmited;\n    DWORD dwPortBytesRcved;\n    DWORD dwPortFramesXmited;\n    DWORD dwPortFramesRcved;\n    DWORD dwPortCrcErr;\n    DWORD dwPortTimeoutErr;\n    DWORD dwPortAlignmentErr;\n    DWORD dwPortHardwareOverrunErr;\n    DWORD dwPortFramingErr;\n    DWORD dwPortBufferOverrunErr;\n    DWORD dwPortBytesXmitedUncompressed;\n    DWORD dwPortBytesRcvedUncompressed;\n    DWORD dwPortBytesXmitedCompressed;\n    DWORD dwPortBytesRcvedCompressed;\n}\nalias RAS_PORT_STATISTICS* PRAS_PORT_STATISTICS;\n\nstruct RAS_SERVER_0 {\n    WORD TotalPorts;\n    WORD PortsInUse;\n    DWORD RasVersion;\n}\nalias RAS_SERVER_0* PRAS_SERVER_0;\n\nextern (Windows) {\n    DWORD RasAdminServerGetInfo(const(WCHAR)*, PRAS_SERVER_0);\n    DWORD RasAdminGetUserAccountServer(const(WCHAR)*, const(WCHAR)*, LPWSTR);\n    DWORD RasAdminUserGetInfo(const(WCHAR)*, const(WCHAR)*, PRAS_USER_0);\n    DWORD RasAdminUserSetInfo(const(WCHAR)*, const(WCHAR)*, PRAS_USER_0);\n    DWORD RasAdminPortEnum(WCHAR*, PRAS_PORT_0*, WORD*);\n    DWORD RasAdminPortGetInfo(const(WCHAR)*, const(WCHAR)*, RAS_PORT_1*,\n     RAS_PORT_STATISTICS*, RAS_PARAMETERS**);\n    DWORD RasAdminPortClearStatistics(const(WCHAR)*, const(WCHAR)*);\n    DWORD RasAdminPortDisconnect(const(WCHAR)*, const(WCHAR)*);\n    DWORD RasAdminFreeBuffer(PVOID);\n    DWORD RasAdminGetErrorString(UINT, WCHAR*, DWORD);\n    BOOL RasAdminAcceptNewConnection(RAS_PORT_1*, RAS_PORT_STATISTICS*,\n     RAS_PARAMETERS*);\n    VOID RasAdminConnectionHangupNotification(RAS_PORT_1*,\n      RAS_PORT_STATISTICS*, RAS_PARAMETERS*);\n    DWORD RasAdminGetIpAddressForUser (WCHAR*, WCHAR*, IPADDR*, BOOL*);\n    VOID RasAdminReleaseIpAddress (WCHAR*, WCHAR*,IPADDR*);\n    DWORD RasAdminGetUserParms(WCHAR*, PRAS_USER_0);\n    DWORD RasAdminSetUserParms(WCHAR*, DWORD, PRAS_USER_0);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/reason.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_reason.d)\n */\nmodule core.sys.windows.reason;\nversion (Windows):\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef;\n\nstatic assert (_WIN32_WINNT >= 0x501,\n  \"core.sys.windows.reason is only available on WindowsXP and later\");\n\n\nenum : DWORD {\n    SHTDN_REASON_MAJOR_OTHER           = 0x00000000,\n    SHTDN_REASON_MAJOR_HARDWARE        = 0x00010000,\n    SHTDN_REASON_MAJOR_OPERATINGSYSTEM = 0x00020000,\n    SHTDN_REASON_MAJOR_SOFTWARE        = 0x00030000,\n    SHTDN_REASON_MAJOR_APPLICATION     = 0x00040000,\n    SHTDN_REASON_MAJOR_SYSTEM          = 0x00050000,\n    SHTDN_REASON_MAJOR_POWER           = 0x00060000,\n    SHTDN_REASON_MAJOR_LEGACY_API      = 0x00070000\n}\n\nenum : DWORD {\n    SHTDN_REASON_MINOR_OTHER,\n    SHTDN_REASON_MINOR_MAINTENANCE,\n    SHTDN_REASON_MINOR_INSTALLATION,\n    SHTDN_REASON_MINOR_UPGRADE,\n    SHTDN_REASON_MINOR_RECONFIG,\n    SHTDN_REASON_MINOR_HUNG,\n    SHTDN_REASON_MINOR_UNSTABLE,\n    SHTDN_REASON_MINOR_DISK,\n    SHTDN_REASON_MINOR_PROCESSOR,\n    SHTDN_REASON_MINOR_NETWORKCARD,\n    SHTDN_REASON_MINOR_POWER_SUPPLY,\n    SHTDN_REASON_MINOR_CORDUNPLUGGED,\n    SHTDN_REASON_MINOR_ENVIRONMENT,\n    SHTDN_REASON_MINOR_HARDWARE_DRIVER,\n    SHTDN_REASON_MINOR_OTHERDRIVER,\n    SHTDN_REASON_MINOR_BLUESCREEN,\n    SHTDN_REASON_MINOR_SERVICEPACK,\n    SHTDN_REASON_MINOR_HOTFIX,\n    SHTDN_REASON_MINOR_SECURITYFIX,\n    SHTDN_REASON_MINOR_SECURITY,\n    SHTDN_REASON_MINOR_NETWORK_CONNECTIVITY,\n    SHTDN_REASON_MINOR_WMI,\n    SHTDN_REASON_MINOR_SERVICEPACK_UNINSTALL,\n    SHTDN_REASON_MINOR_HOTFIX_UNINSTALL,\n    SHTDN_REASON_MINOR_SECURITYFIX_UNINSTALL,\n    SHTDN_REASON_MINOR_MMC,         // = 0x00000019\n    SHTDN_REASON_MINOR_TERMSRV         = 0x00000020\n}\n\nenum : DWORD {\n    SHTDN_REASON_FLAG_USER_DEFINED     = 0x40000000,\n    SHTDN_REASON_FLAG_PLANNED          = 0x80000000\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/regstr.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_regstr.d)\n */\nmodule core.sys.windows.regstr;\nversion (Windows):\n\n// TODO: fix possible conflict with shloj. Sort out NEC_98 issue.\n\nprivate import core.sys.windows.windef;\n\nenum REGSTR_MAX_VALUE_LENGTH = 256;\n\nenum {\n    IT_COMPACT = 0,\n    IT_TYPICAL,\n    IT_PORTABLE,\n    IT_CUSTOM // = 3\n}\n\nenum DOSOPTGF_DEFCLEAN = 1;\n\nenum DOSOPTF_DEFAULT     = 0x01;\nenum DOSOPTF_SUPPORTED   = 0x02;\nenum DOSOPTF_ALWAYSUSE   = 0x04;\nenum DOSOPTF_USESPMODE   = 0x08;\nenum DOSOPTF_PROVIDESUMB = 0x10;\nenum DOSOPTF_NEEDSETUP   = 0x20;\nenum DOSOPTF_INDOSSTART  = 0x40;\nenum DOSOPTF_MULTIPLE    = 0x80;\n\nenum SUF_FIRSTTIME  = 0x0001;\nenum SUF_EXPRESS    = 0x0002;\nenum SUF_BATCHINF   = 0x0004;\nenum SUF_CLEAN      = 0x0008;\nenum SUF_INSETUP    = 0x0010;\nenum SUF_NETSETUP   = 0x0020;\nenum SUF_NETHDBOOT  = 0x0040;\nenum SUF_NETRPLBOOT = 0x0080;\nenum SUF_SBSCOPYOK  = 0x0100;\n\nenum VPDF_DISABLEPWRMGMT       = 1;\nenum VPDF_FORCEAPM10MODE       = 2;\nenum VPDF_SKIPINTELSLCHECK     = 4;\nenum VPDF_DISABLEPWRSTATUSPOLL = 8;\n\nenum PCMCIA_OPT_HAVE_SOCKET  = 0x01;\nenum PCMCIA_OPT_AUTOMEM      = 0x04;\nenum PCMCIA_OPT_NO_SOUND     = 0x08;\nenum PCMCIA_OPT_NO_AUDIO     = 0x10;\nenum PCMCIA_OPT_NO_APMREMOVE = 0x20;\n\nenum PCMCIA_DEF_MEMBEGIN   = 0x0C0000;\nenum PCMCIA_DEF_MEMEND     = 0xFFFFFF;\nenum PCMCIA_DEF_MEMLEN     = 0x001000;\nenum PCMCIA_DEF_MIN_REGION = 0x010000;\n\nenum {\n    PCI_OPTIONS_USE_BIOS         = 1,\n    PCI_OPTIONS_USE_IRQ_STEERING = 2\n}\n\nenum PCI_FLAG_NO_VIDEO_IRQ      = 0x0001;\nenum PCI_FLAG_PCMCIA_WANT_IRQ   = 0x0002;\nenum PCI_FLAG_DUAL_IDE          = 0x0004;\nenum PCI_FLAG_NO_ENUM_AT_ALL    = 0x0008;\nenum PCI_FLAG_ENUM_NO_RESOURCE  = 0x0010;\nenum PCI_FLAG_NEED_DWORD_ACCESS = 0x0020;\nenum PCI_FLAG_SINGLE_FUNCTION   = 0x0040;\nenum PCI_FLAG_ALWAYS_ENABLED    = 0x0080;\nenum PCI_FLAG_IS_IDE            = 0x0100;\nenum PCI_FLAG_IS_VIDEO          = 0x0200;\nenum PCI_FLAG_FAIL_START        = 0x0400;\n\nenum size_t REGSTR_VAL_MAX_HCID_LEN = 1024;\n\nenum REGDF_NOTDETIO        = 0x00000001;\nenum REGDF_NOTDETMEM       = 0x00000002;\nenum REGDF_NOTDETIRQ       = 0x00000004;\nenum REGDF_NOTDETDMA       = 0x00000008;\nenum REGDF_NOTDETALL       = REGDF_NOTDETIO | REGDF_NOTDETMEM | REGDF_NOTDETIRQ | REGDF_NOTDETDMA;\nenum REGDF_NEEDFULLCONFIG  = 0x00000010;\nenum REGDF_GENFORCEDCONFIG = 0x00000020;\nenum REGDF_NODETCONFIG     = 0x00008000;\nenum REGDF_CONFLICTIO      = 0x00010000;\nenum REGDF_CONFLICTMEM     = 0x00020000;\nenum REGDF_CONFLICTIRQ     = 0x00040000;\nenum REGDF_CONFLICTDMA     = 0x00080000;\nenum REGDF_CONFLICTALL     = REGDF_CONFLICTIO | REGDF_CONFLICTMEM | REGDF_CONFLICTIRQ | REGDF_CONFLICTDMA;\nenum REGDF_MAPIRQ2TO9      = 0x00100000;\nenum REGDF_NOTVERIFIED     = 0x80000000;\n\nenum CONFIGFLAG_DISABLED       = 0x0001;\nenum CONFIGFLAG_REMOVED        = 0x0002;\nenum CONFIGFLAG_MANUAL_INSTALL = 0x0004;\nenum CONFIGFLAG_IGNORE_BOOT_LC = 0x0008;\nenum CONFIGFLAG_NET_BOOT       = 0x0010;\nenum CONFIGFLAG_REINSTALL      = 0x0020;\nenum CONFIGFLAG_FAILEDINSTALL  = 0x0040;\nenum CONFIGFLAG_CANTSTOPACHILD = 0x0080;\nenum CONFIGFLAG_OKREMOVEROM    = 0x0100;\nenum CONFIGFLAG_NOREMOVEEXIT   = 0x0200;\n\nenum CSCONFIGFLAG_DISABLED      = 1;\nenum CSCONFIGFLAG_DO_NOT_CREATE = 2;\nenum CSCONFIGFLAG_DO_NOT_START  = 4;\nenum CSCONFIGFLAG_BITS          = 7;\n\nenum DMSTATEFLAG_APPLYTOALL = 1;\n\nenum NUM_RESOURCE_MAP = 256;\n\nenum MF_FLAGS_EVEN_IF_NO_RESOURCE         = 1;\nenum MF_FLAGS_NO_CREATE_IF_NO_RESOURCE    = 2;\nenum MF_FLAGS_FILL_IN_UNKNOWN_RESOURCE    = 4;\nenum MF_FLAGS_CREATE_BUT_NO_SHOW_DISABLED = 8;\n\nenum EISAFLAG_NO_IO_MERGE   = 1;\nenum EISAFLAG_SLOT_IO_FIRST = 2;\n\nenum EISA_NO_MAX_FUNCTION   = 0xFF;\n\nenum NUM_EISA_RANGES = 4;\n\nenum APMMENUSUSPEND_DISABLED = 0;\nenum APMMENUSUSPEND_ENABLED  = 1;\nenum APMMENUSUSPEND_UNDOCKED = 2;\nenum APMMENUSUSPEND_NOCHANGE = 128;\n\n//#ifndef NEC_98\nconst TCHAR[]\n    REGSTR_KEY_ISAENUM             = \"ISAPnP\",\n    REGSTR_KEY_EISAENUM            = \"EISA\",\n    REGSTR_VAL_EISA_RANGES         = \"EISARanges\",\n    REGSTR_VAL_EISA_FUNCTIONS      = \"EISAFunctions\",\n    REGSTR_VAL_EISA_FUNCTIONS_MASK = \"EISAFunctionsMask\",\n    REGSTR_VAL_EISA_FLAGS          = \"EISAFlags\",\n    REGSTR_VAL_EISA_SIMULATE_INT15 = \"EISASimulateInt15\";\n// #else\n// #define REGSTR_KEY_ISAENUM   TEXT(\"C98PnP\")\n// #define REGSTR_KEY_EISAENUM  TEXT(\"NESA\")\n// #define  REGSTR_VAL_EISA_RANGES  TEXT(\"NESARanges\")\n// #define  REGSTR_VAL_EISA_FUNCTIONS   TEXT(\"NESAFunctions\")\n// #define  REGSTR_VAL_EISA_FUNCTIONS_MASK  TEXT(\"NESAFunctionsMask\")\n// #define  REGSTR_VAL_EISA_FLAGS   TEXT(\"NESAFlags\")\n// #define  REGSTR_VAL_EISA_SIMULATE_INT15  TEXT(\"NESASimulateInt15\")\n// #endif\n\nconst TCHAR[]\n    REGSTR_KEY_CLASS                     = `Class`,\n    REGSTR_KEY_CONFIG                    = `Config`,\n    REGSTR_KEY_ENUM                      = `Enum`,\n    REGSTR_KEY_ROOTENUM                  = `Root`,\n    REGSTR_KEY_BIOSENUM                  = `BIOS`,\n    REGSTR_KEY_PCMCIAENUM                = `PCMCIA`,\n    REGSTR_KEY_PCIENUM                   = `PCI`,\n    REGSTR_KEY_LOGCONFIG                 = `LogConfig`,\n    REGSTR_KEY_SYSTEMBOARD               = `*PNP0C01`,\n    REGSTR_KEY_APM                       = `*PNP0C05`,\n    REGSTR_KEY_INIUPDATE                 = `IniUpdate`,\n    REG_KEY_INSTDEV                      = `Installed`,\n    REGSTR_KEY_DOSOPTCDROM               = `CD-ROM`,\n    REGSTR_KEY_DOSOPTMOUSE               = `MOUSE`,\n    REGSTR_DEFAULT_INSTANCE              = `0000`,\n    REGSTR_PATH_MOTHERBOARD              = REGSTR_KEY_SYSTEMBOARD ~ `\\` ~ REGSTR_DEFAULT_INSTANCE,\n    REGSTR_PATH_SETUP                    = `Software\\Microsoft\\Windows\\CurrentVersion`,\n    REGSTR_PATH_PIFCONVERT               = `Software\\Microsoft\\Windows\\CurrentVersion\\PIFConvert`,\n    REGSTR_PATH_MSDOSOPTS                = `Software\\Microsoft\\Windows\\CurrentVersion\\MS-DOSOptions`,\n    REGSTR_PATH_MSDOSEMU                 = `Software\\Microsoft\\Windows\\CurrentVersion\\MS-DOS Emulation`,\n    REGSTR_PATH_NEWDOSBOX                = `Software\\Microsoft\\Windows\\CurrentVersion\\MS-DOS Emulation\\AppCompat`,\n    REGSTR_PATH_RUNONCE                  = `Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce`,\n    REGSTR_PATH_RUN                      = `Software\\Microsoft\\Windows\\CurrentVersion\\Run`,\n    REGSTR_PATH_RUNSERVICESONCE          = `Software\\Microsoft\\Windows\\CurrentVersion\\RunServicesOnce`,\n    REGSTR_PATH_RUNSERVICES              = `Software\\Microsoft\\Windows\\CurrentVersion\\RunServices`,\n\n//#ifndef REGSTR_PATH_EXPLORER /* also in shlobj.h */\n    REGSTR_PATH_EXPLORER                 = `Software\\Microsoft\\Windows\\CurrentVersion\\Explorer`,\n//#endif\n\n    REGSTR_PATH_DETECT                   = `Software\\Microsoft\\Windows\\CurrentVersion\\Detect`,\n    REGSTR_PATH_APPPATHS                 = `Software\\Microsoft\\Windows\\CurrentVersion\\App Paths`,\n    REGSTR_PATH_UNINSTALL                = `Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall`,\n    REGSTR_PATH_REALMODENET              = `Software\\Microsoft\\Windows\\CurrentVersion\\Network\\Real Mode Net`,\n    REGSTR_PATH_NETEQUIV                 = `Software\\Microsoft\\Windows\\CurrentVersion\\Network\\Equivalent`,\n    REGSTR_PATH_CVNETWORK                = `Software\\Microsoft\\Windows\\CurrentVersion\\Network`,\n    REGSTR_PATH_IDCONFIGDB               = `System\\CurrentControlSet\\Control\\IDConfigDB`,\n    REGSTR_PATH_CLASS                    = `System\\CurrentControlSet\\Services\\Class`,\n    REGSTR_PATH_DISPLAYSETTINGS          = `Display\\Settings`,\n    REGSTR_PATH_FONTS                    = `Display\\Fonts`,\n    REGSTR_PATH_ENUM                     = `Enum`,\n    REGSTR_PATH_ROOT                     = `Enum\\Root`,\n    REGSTR_PATH_SERVICES                 = `System\\CurrentControlSet\\Services`,\n    REGSTR_PATH_VXD                      = `System\\CurrentControlSet\\Services\\VxD`,\n    REGSTR_PATH_IOS                      = `System\\CurrentControlSet\\Services\\VxD\\IOS`,\n    REGSTR_PATH_VMM                      = `System\\CurrentControlSet\\Services\\VxD\\VMM`,\n    REGSTR_PATH_VPOWERD                  = `System\\CurrentControlSet\\Services\\VxD\\VPOWERD`,\n    REGSTR_PATH_VNETSUP                  = `System\\CurrentControlSet\\Services\\VxD\\VNETSUP`,\n    REGSTR_PATH_NWREDIR                  = `System\\CurrentControlSet\\Services\\VxD\\NWREDIR`,\n    REGSTR_PATH_NCPSERVER                = `System\\CurrentControlSet\\Services\\NcpServer\\Parameters`,\n    REGSTR_PATH_IOARB                    = `System\\CurrentControlSet\\Services\\Arbitrators\\IOArb`,\n    REGSTR_PATH_ADDRARB                  = `System\\CurrentControlSet\\Services\\Arbitrators\\AddrArb`,\n    REGSTR_PATH_DMAARB                   = `System\\CurrentControlSet\\Services\\Arbitrators\\DMAArb`,\n    REGSTR_PATH_IRQARB                   = `System\\CurrentControlSet\\Services\\Arbitrators\\IRQArb`,\n    REGSTR_PATH_CODEPAGE                 = `System\\CurrentControlSet\\Control\\Nls\\Codepage`,\n    REGSTR_PATH_FILESYSTEM               = `System\\CurrentControlSet\\Control\\FileSystem`,\n    REGSTR_PATH_FILESYSTEM_NOVOLTRACK    = `System\\CurrentControlSet\\Control\\FileSystem\\NoVolTrack`,\n    REGSTR_PATH_CDFS                     = `System\\CurrentControlSet\\Control\\FileSystem\\CDFS`,\n    REGSTR_PATH_WINBOOT                  = `System\\CurrentControlSet\\Control\\WinBoot`,\n    REGSTR_PATH_INSTALLEDFILES           = `System\\CurrentControlSet\\Control\\InstalledFiles`,\n    REGSTR_PATH_VMM32FILES               = `System\\CurrentControlSet\\Control\\VMM32Files`,\n\n    REGSTR_VAL_BITSPERPIXEL              = `BitsPerPixel`,\n    REGSTR_VAL_RESOLUTION                = `Resolution`,\n    REGSTR_VAL_DPILOGICALX               = `DPILogicalX`,\n    REGSTR_VAL_DPILOGICALY               = `DPILogicalY`,\n    REGSTR_VAL_DPIPHYSICALX              = `DPIPhysicalX`,\n    REGSTR_VAL_DPIPHYSICALY              = `DPIPhysicalY`,\n    REGSTR_VAL_REFRESHRATE               = `RefreshRate`,\n    REGSTR_VAL_DISPLAYFLAGS              = `DisplayFlags`,\n    REGSTR_PATH_CONTROLPANEL             = `Control Panel`,\n    REGSTR_PATH_CONTROLSFOLDER           = `Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder`,\n    REGSTR_VAL_DOSCP                     = `OEMCP`,\n    REGSTR_VAL_WINCP                     = `ACP`,\n    REGSTR_PATH_DYNA_ENUM                = `Config Manager\\Enum`,\n    REGSTR_VAL_HARDWARE_KEY              = `HardWareKey`,\n    REGSTR_VAL_ALLOCATION                = `Allocation`,\n    REGSTR_VAL_PROBLEM                   = `Problem`,\n    REGSTR_VAL_STATUS                    = `Status`,\n    REGSTR_VAL_DONTUSEMEM                = `DontAllocLastMem`,\n    REGSTR_VAL_SYSTEMROOT                = `SystemRoot`,\n    REGSTR_VAL_BOOTCOUNT                 = `BootCount`,\n    REGSTR_VAL_REALNETSTART              = `RealNetStart`,\n    REGSTR_VAL_MEDIA                     = `MediaPath`,\n    REGSTR_VAL_CONFIG                    = `ConfigPath`,\n    REGSTR_VAL_DEVICEPATH                = `DevicePath`,\n    REGSTR_VAL_SRCPATH                   = `SourcePath`,\n    REGSTR_VAL_OLDWINDIR                 = `OldWinDir`,\n    REGSTR_VAL_SETUPFLAGS                = `SetupFlags`,\n    REGSTR_VAL_REGOWNER                  = `RegisteredOwner`,\n    REGSTR_VAL_REGORGANIZATION           = `RegisteredOrganization`,\n    REGSTR_VAL_LICENSINGINFO             = `LicensingInfo`,\n    REGSTR_VAL_OLDMSDOSVER               = `OldMSDOSVer`,\n    REGSTR_VAL_FIRSTINSTALLDATETIME      = `FirstInstallDateTime`,\n    REGSTR_VAL_INSTALLTYPE               = `InstallType`,\n    REGSTR_VAL_WRAPPER                   = `Wrapper`,\n\n    REGSTR_KEY_SETUP                     = `\\Setup`,\n    REGSTR_VAL_BOOTDIR                   = `BootDir`,\n    REGSTR_VAL_WINBOOTDIR                = `WinbootDir`,\n    REGSTR_VAL_WINDIR                    = `WinDir`,\n    REGSTR_VAL_APPINSTPATH               = `AppInstallPath`,\n    REGSTR_PATH_EBD                      = REGSTR_PATH_SETUP ~ REGSTR_KEY_SETUP ~ `\\EBD`,\n    REGSTR_KEY_EBDFILESLOCAL             = `EBDFilesLocale`,\n    REGSTR_KEY_EBDFILESKEYBOARD          = `EBDFilesKeyboard`,\n    REGSTR_KEY_EBDAUTOEXECBATLOCAL       = `EBDAutoexecBatLocale`,\n    REGSTR_KEY_EBDAUTOEXECBATKEYBOARD    = `EBDAutoexecBatKeyboard`,\n    REGSTR_KEY_EBDCONFIGSYSLOCAL         = `EBDConfigSysLocale`,\n    REGSTR_KEY_EBDCONFIGSYSKEYBOARD      = `EBDConfigSysKeyboard`,\n    REGSTR_VAL_MSDOSMODE                 = `MSDOSMode`,\n    REGSTR_VAL_MSDOSMODEDISCARD          = `Discard`,\n    REGSTR_VAL_DOSOPTGLOBALFLAGS         = `GlobalFlags`,\n    REGSTR_VAL_DOSOPTFLAGS               = `Flags`,\n    REGSTR_VAL_OPTORDER                  = `Order`,\n    REGSTR_VAL_CONFIGSYS                 = `Config.Sys`,\n    REGSTR_VAL_AUTOEXEC                  = `Autoexec.Bat`,\n    REGSTR_VAL_STDDOSOPTION              = `StdOption`,\n    REGSTR_VAL_DOSOPTTIP                 = `TipText`,\n\n    REGSTR_VAL_DOSPAGER                  = `DOSPager`,\n    REGSTR_VAL_VXDGROUPS                 = `VXDGroups`,\n    REGSTR_VAL_VPOWERDFLAGS              = `Flags`,\n\n    REGSTR_VAL_WORKGROUP                 = `Workgroup`,\n    REGSTR_VAL_DIRECTHOST                = `DirectHost`,\n    REGSTR_VAL_FILESHARING               = `FileSharing`,\n    REGSTR_VAL_PRINTSHARING              = `PrintSharing`,\n    REGSTR_VAL_FIRSTNETDRIVE             = `FirstNetworkDrive`,\n    REGSTR_VAL_MAXCONNECTIONS            = `MaxConnections`,\n    REGSTR_VAL_APISUPPORT                = `APISupport`,\n    REGSTR_VAL_MAXRETRY                  = `MaxRetry`,\n    REGSTR_VAL_MINRETRY                  = `MinRetry`,\n    REGSTR_VAL_SUPPORTLFN                = `SupportLFN`,\n    REGSTR_VAL_SUPPORTBURST              = `SupportBurst`,\n    REGSTR_VAL_SUPPORTTUNNELLING         = `SupportTunnelling`,\n    REGSTR_VAL_FULLTRACE                 = `FullTrace`,\n    REGSTR_VAL_READCACHING               = `ReadCaching`,\n    REGSTR_VAL_SHOWDOTS                  = `ShowDots`,\n    REGSTR_VAL_GAPTIME                   = `GapTime`,\n    REGSTR_VAL_SEARCHMODE                = `SearchMode`,\n    REGSTR_VAL_SHELLVERSION              = `ShellVersion`,\n    REGSTR_VAL_MAXLIP                    = `MaxLIP`,\n    REGSTR_VAL_PRESERVECASE              = `PreserveCase`,\n    REGSTR_VAL_OPTIMIZESFN               = `OptimizeSFN`,\n    REGSTR_VAL_NCP_BROWSEMASTER          = `BrowseMaster`,\n    REGSTR_VAL_NCP_USEPEERBROWSING       = `Use_PeerBrowsing`,\n    REGSTR_VAL_NCP_USESAP                = `Use_Sap`,\n    REGSTR_VAL_WIN31FILESYSTEM           = `Win31FileSystem`,\n    REGSTR_VAL_PRESERVELONGNAMES         = `PreserveLongNames`,\n    REGSTR_VAL_DRIVEWRITEBEHIND          = `DriveWriteBehind`,\n    REGSTR_VAL_ASYNCFILECOMMIT           = `AsyncFileCommit`,\n    REGSTR_VAL_PATHCACHECOUNT            = `PathCache`,\n    REGSTR_VAL_NAMECACHECOUNT            = `NameCache`,\n    REGSTR_VAL_CONTIGFILEALLOC           = `ContigFileAllocSize`,\n    REGSTR_VAL_VOLIDLETIMEOUT            = `VolumeIdleTimeout`,\n    REGSTR_VAL_BUFFIDLETIMEOUT           = `BufferIdleTimeout`,\n    REGSTR_VAL_BUFFAGETIMEOUT            = `BufferAgeTimeout`,\n    REGSTR_VAL_NAMENUMERICTAIL           = `NameNumericTail`,\n    REGSTR_VAL_READAHEADTHRESHOLD        = `ReadAheadThreshold`,\n    REGSTR_VAL_DOUBLEBUFFER              = `DoubleBuffer`,\n    REGSTR_VAL_SOFTCOMPATMODE            = `SoftCompatMode`,\n    REGSTR_VAL_DRIVESPINDOWN             = `DriveSpinDown`,\n    REGSTR_VAL_FORCEPMIO                 = `ForcePMIO`,\n    REGSTR_VAL_FORCERMIO                 = `ForceRMIO`,\n    REGSTR_VAL_LASTBOOTPMDRVS            = `LastBootPMDrvs`,\n    REGSTR_VAL_VIRTUALHDIRQ              = `VirtualHDIRQ`,\n    REGSTR_VAL_SRVNAMECACHECOUNT         = `ServerNameCacheMax`,\n    REGSTR_VAL_SRVNAMECACHE              = `ServerNameCache`,\n    REGSTR_VAL_SRVNAMECACHENETPROV       = `ServerNameCacheNumNets`,\n    REGSTR_VAL_AUTOMOUNT                 = `AutoMountDrives`,\n    REGSTR_VAL_COMPRESSIONMETHOD         = `CompressionAlgorithm`,\n    REGSTR_VAL_COMPRESSIONTHRESHOLD      = `CompressionThreshold`,\n    REGSTR_VAL_CDCACHESIZE               = `CacheSize`,\n    REGSTR_VAL_CDPREFETCH                = `Prefetch`,\n    REGSTR_VAL_CDPREFETCHTAIL            = `PrefetchTail`,\n    REGSTR_VAL_CDRAWCACHE                = `RawCache`,\n    REGSTR_VAL_CDEXTERRORS               = `ExtendedErrors`,\n    REGSTR_VAL_CDSVDSENSE                = `SVDSense`,\n    REGSTR_VAL_CDSHOWVERSIONS            = `ShowVersions`,\n    REGSTR_VAL_CDCOMPATNAMES             = `MSCDEXCompatNames`,\n    REGSTR_VAL_CDNOREADAHEAD             = `NoReadAhead`,\n    REGSTR_VAL_SCSI                      = `SCSI\\`,\n    REGSTR_VAL_ESDI                      = `ESDI\\`,\n    REGSTR_VAL_FLOP                      = `FLOP\\`,\n    REGSTR_VAL_DISK                      = `GenDisk`,\n    REGSTR_VAL_CDROM                     = `GenCD`,\n    REGSTR_VAL_TAPE                      = `TAPE`,\n    REGSTR_VAL_SCANNER                   = `SCANNER`,\n    REGSTR_VAL_FLOPPY                    = `FLOPPY`,\n    REGSTR_VAL_SCSITID                   = `SCSITargetID`,\n    REGSTR_VAL_SCSILUN                   = `SCSILUN`,\n    REGSTR_VAL_REVLEVEL                  = `RevisionLevel`,\n    REGSTR_VAL_PRODUCTID                 = `ProductId`,\n    REGSTR_VAL_PRODUCTTYPE               = `ProductType`,\n    REGSTR_VAL_DEVTYPE                   = `DeviceType`,\n    REGSTR_VAL_REMOVABLE                 = `Removable`,\n    REGSTR_VAL_CURDRVLET                 = `CurrentDriveLetterAssignment`,\n    REGSTR_VAL_USRDRVLET                 = `UserDriveLetterAssignment`,\n    REGSTR_VAL_SYNCDATAXFER              = `SyncDataXfer`,\n    REGSTR_VAL_AUTOINSNOTE               = `AutoInsertNotification`,\n    REGSTR_VAL_DISCONNECT                = `Disconnect`,\n    REGSTR_VAL_INT13                     = `Int13`,\n    REGSTR_VAL_PMODE_INT13               = `PModeInt13`,\n    REGSTR_VAL_USERSETTINGS              = `AdapterSettings`,\n    REGSTR_VAL_NOIDE                     = `NoIDE`,\n    REGSTR_VAL_DISKCLASSNAME             = `DiskDrive`,\n    REGSTR_VAL_CDROMCLASSNAME            = `CDROM`,\n    REGSTR_VAL_FORCELOAD                 = `ForceLoadPD`,\n    REGSTR_VAL_FORCEFIFO                 = `ForceFIFO`,\n    REGSTR_VAL_FORCECL                   = `ForceChangeLine`,\n    REGSTR_VAL_NOUSECLASS                = `NoUseClass`,\n    REGSTR_VAL_NOINSTALLCLASS            = `NoInstallClass`,\n    REGSTR_VAL_NODISPLAYCLASS            = `NoDisplayClass`,\n    REGSTR_VAL_SILENTINSTALL             = `SilentInstall`,\n    REGSTR_KEY_PCMCIA_CLASS              = `PCMCIA`,\n    REGSTR_KEY_SCSI_CLASS                = `SCSIAdapter`,\n    REGSTR_KEY_PORTS_CLASS               = `ports`,\n    REGSTR_KEY_MEDIA_CLASS               = `MEDIA`,\n    REGSTR_KEY_DISPLAY_CLASS             = `Display`,\n    REGSTR_KEY_KEYBOARD_CLASS            = `Keyboard`,\n    REGSTR_KEY_MOUSE_CLASS               = `Mouse`,\n    REGSTR_KEY_MONITOR_CLASS             = `Monitor`,\n    REGSTR_VAL_PCMCIA_OPT                = `Options`,\n    REGSTR_VAL_PCMCIA_MEM                = `Memory`,\n    REGSTR_VAL_PCMCIA_ALLOC              = `AllocMemWin`,\n    REGSTR_VAL_PCMCIA_ATAD               = `ATADelay`,\n    REGSTR_VAL_PCMCIA_SIZ                = `MinRegionSize`,\n    REGSTR_VAL_P1284MDL                  = `Model`,\n    REGSTR_VAL_P1284MFG                  = `Manufacturer`,\n    REGSTR_VAL_ISAPNP                    = `ISAPNP`,\n    REGSTR_VAL_ISAPNP_RDP_OVERRIDE       = `RDPOverRide`,\n    REGSTR_VAL_PCI                       = `PCI`,\n    REGSTR_PCI_OPTIONS                   = `Options`,\n    REGSTR_PCI_DUAL_IDE                  = `PCIDualIDE`,\n\n    REGSTR_KEY_CRASHES                   = `Crashes`,\n    REGSTR_KEY_DANGERS                   = `Dangers`,\n    REGSTR_KEY_DETMODVARS                = `DetModVars`,\n    REGSTR_KEY_NDISINFO                  = `NDISInfo`,\n    REGSTR_VAL_PROTINIPATH               = `ProtIniPath`,\n    REGSTR_VAL_RESOURCES                 = `Resources`,\n    REGSTR_VAL_CRASHFUNCS                = `CrashFuncs`,\n    REGSTR_VAL_CLASS                     = `Class`,\n    REGSTR_VAL_DEVDESC                   = `DeviceDesc`,\n    REGSTR_VAL_BOOTCONFIG                = `BootConfig`,\n    REGSTR_VAL_DETFUNC                   = `DetFunc`,\n    REGSTR_VAL_DETFLAGS                  = `DetFlags`,\n    REGSTR_VAL_COMPATIBLEIDS             = `CompatibleIDs`,\n    REGSTR_VAL_DETCONFIG                 = `DetConfig`,\n    REGSTR_VAL_VERIFYKEY                 = `VerifyKey`,\n    REGSTR_VAL_COMINFO                   = `ComInfo`,\n    REGSTR_VAL_INFNAME                   = `InfName`,\n    REGSTR_VAL_CARDSPECIFIC              = `CardSpecific`,\n    REGSTR_VAL_NETOSTYPE                 = `NetOSType`,\n    REGSTR_DATA_NETOS_NDIS               = `NDIS`,\n    REGSTR_DATA_NETOS_ODI                = `ODI`,\n    REGSTR_DATA_NETOS_IPX                = `IPX`,\n    REGSTR_VAL_MFG                       = `Mfg`,\n    REGSTR_VAL_SCAN_ONLY_FIRST           = `ScanOnlyFirstDrive`,\n    REGSTR_VAL_SHARE_IRQ                 = `ForceIRQSharing`,\n    REGSTR_VAL_NONSTANDARD_ATAPI         = `NonStandardATAPI`,\n    REGSTR_VAL_IDE_FORCE_SERIALIZE       = `ForceSerialization`,\n    REGSTR_VAL_HWREV                     = `HWRevision`,\n    REGSTR_VAL_ENABLEINTS                = `EnableInts`,\n\n    REGSTR_VAL_APMBIOSVER                = `APMBiosVer`,\n    REGSTR_VAL_APMFLAGS                  = `APMFlags`,\n    REGSTR_VAL_SLSUPPORT                 = `SLSupport`,\n    REGSTR_VAL_MACHINETYPE               = `MachineType`,\n    REGSTR_VAL_SETUPMACHINETYPE          = `SetupMachineType`,\n    REGSTR_MACHTYPE_UNKNOWN              = `Unknown`,\n    REGSTR_MACHTYPE_IBMPC                = `IBM PC`,\n    REGSTR_MACHTYPE_IBMPCJR              = `IBM PCjr`,\n    REGSTR_MACHTYPE_IBMPCCONV            = `IBM PC Convertible`,\n    REGSTR_MACHTYPE_IBMPCXT              = `IBM PC/XT`,\n    REGSTR_MACHTYPE_IBMPCXT_286          = `IBM PC/XT 286`,\n    REGSTR_MACHTYPE_IBMPCAT              = `IBM PC/AT`,\n    REGSTR_MACHTYPE_IBMPS2_25            = `IBM PS/2-25`,\n    REGSTR_MACHTYPE_IBMPS2_30_286        = `IBM PS/2-30 286`,\n    REGSTR_MACHTYPE_IBMPS2_30            = `IBM PS/2-30`,\n    REGSTR_MACHTYPE_IBMPS2_50            = `IBM PS/2-50`,\n    REGSTR_MACHTYPE_IBMPS2_50Z           = `IBM PS/2-50Z`,\n    REGSTR_MACHTYPE_IBMPS2_55SX          = `IBM PS/2-55SX`,\n    REGSTR_MACHTYPE_IBMPS2_60            = `IBM PS/2-60`,\n    REGSTR_MACHTYPE_IBMPS2_65SX          = `IBM PS/2-65SX`,\n    REGSTR_MACHTYPE_IBMPS2_70            = `IBM PS/2-70`,\n    REGSTR_MACHTYPE_IBMPS2_P70           = `IBM PS/2-P70`,\n    REGSTR_MACHTYPE_IBMPS2_70_80         = `IBM PS/2-70/80`,\n    REGSTR_MACHTYPE_IBMPS2_80            = `IBM PS/2-80`,\n    REGSTR_MACHTYPE_IBMPS2_90            = `IBM PS/2-90`,\n    REGSTR_MACHTYPE_IBMPS1               = `IBM PS/1`,\n    REGSTR_MACHTYPE_PHOENIX_PCAT         = `Phoenix PC/AT Compatible`,\n    REGSTR_MACHTYPE_HP_VECTRA            = `HP Vectra`,\n    REGSTR_MACHTYPE_ATT_PC               = `AT&T PC`,\n    REGSTR_MACHTYPE_ZENITH_PC            = `Zenith PC`,\n    REGSTR_VAL_APMMENUSUSPEND            = `APMMenuSuspend`,\n\n    REGSTR_VAL_BUSTYPE                   = `BusType`,\n    REGSTR_VAL_CPU                       = `CPU`,\n    REGSTR_VAL_NDP                       = `NDP`,\n    REGSTR_VAL_PNPBIOSVER                = `PnPBIOSVer`,\n    REGSTR_VAL_PNPSTRUCOFFSET            = `PnPStrucOffset`,\n    REGSTR_VAL_PCIBIOSVER                = `PCIBIOSVer`,\n    REGSTR_VAL_HWMECHANISM               = `HWMechanism`,\n    REGSTR_VAL_LASTPCIBUSNUM             = `LastPCIBusNum`,\n    REGSTR_VAL_CONVMEM                   = `ConvMem`,\n    REGSTR_VAL_EXTMEM                    = `ExtMem`,\n    REGSTR_VAL_COMPUTERNAME              = `ComputerName`,\n    REGSTR_VAL_BIOSNAME                  = `BIOSName`,\n    REGSTR_VAL_BIOSVERSION               = `BIOSVersion`,\n    REGSTR_VAL_BIOSDATE                  = `BIOSDate`,\n    REGSTR_VAL_MODEL                     = `Model`,\n    REGSTR_VAL_SUBMODEL                  = `Submodel`,\n    REGSTR_VAL_REVISION                  = `Revision`,\n    REGSTR_VAL_FIFODEPTH                 = `FIFODepth`,\n    REGSTR_VAL_RDINTTHRESHOLD            = `RDIntThreshold`,\n    REGSTR_VAL_WRINTTHRESHOLD            = `WRIntThreshold`,\n    REGSTR_VAL_PRIORITY                  = `Priority`,\n    REGSTR_VAL_DRIVER                    = `Driver`,\n    REGSTR_VAL_FUNCDESC                  = `FunctionDesc`,\n    REGSTR_VAL_FORCEDCONFIG              = `ForcedConfig`,\n    REGSTR_VAL_CONFIGFLAGS               = `ConfigFlags`,\n    REGSTR_VAL_CSCONFIGFLAGS             = `CSConfigFlags`,\n\n    REGSTR_VAL_ROOT_DEVNODE              = `HTREE\\ROOT\\0`,\n    REGSTR_VAL_RESERVED_DEVNODE          = `HTREE\\RESERVED\\0`,\n    REGSTR_PATH_READDATAPORT             = REGSTR_KEY_ISAENUM ~ `\\ReadDataPort\\0`,\n    REGSTR_PATH_MULTI_FUNCTION           = `MF`,\n    REGSTR_VAL_RESOURCE_MAP              = `ResourceMap`,\n    REGSTR_PATH_CHILD_PREFIX             = `Child`,\n    REGSTR_VAL_MF_FLAGS                  = `MFFlags`,\n    REGSTR_VAL_DRVDESC                   = `DriverDesc`,\n    REGSTR_VAL_DEVLOADER                 = `DevLoader`,\n    REGSTR_VAL_STATICVXD                 = `StaticVxD`,\n    REGSTR_VAL_PROPERTIES                = `Properties`,\n    REGSTR_VAL_MANUFACTURER              = `Manufacturer`,\n    REGSTR_VAL_EXISTS                    = `Exists`,\n    REGSTR_VAL_CMENUMFLAGS               = `CMEnumFlags`,\n    REGSTR_VAL_CMDRIVFLAGS               = `CMDrivFlags`,\n    REGSTR_VAL_ENUMERATOR                = `Enumerator`,\n    REGSTR_VAL_DEVICEDRIVER              = `DeviceDriver`,\n    REGSTR_VAL_PORTNAME                  = `PortName`,\n    REGSTR_VAL_INFPATH                   = `InfPath`,\n    REGSTR_VAL_INFSECTION                = `InfSection`,\n    REGSTR_VAL_POLLING                   = `Polling`,\n    REGSTR_VAL_DONTLOADIFCONFLICT        = `DontLoadIfConflict`,\n    REGSTR_VAL_PORTSUBCLASS              = `PortSubClass`,\n    REGSTR_VAL_NETCLEAN                  = `NetClean`,\n    REGSTR_VAL_IDE_NO_SERIALIZE          = `IDENoSerialize`,\n    REGSTR_VAL_NOCMOSORFDPT              = `NoCMOSorFDPT`,\n    REGSTR_VAL_COMVERIFYBASE             = `COMVerifyBase`,\n    REGSTR_KEY_OVERRIDE                  = `Override`,\n    REGSTR_VAL_CONFIGMG                  = `CONFIGMG`,\n    REGSTR_VAL_SYSDM                     = `SysDM`,\n    REGSTR_VAL_SYSDMFUNC                 = `SysDMFunc`,\n    REGSTR_VAL_PRIVATE                   = `Private`,\n    REGSTR_VAL_PRIVATEFUNC               = `PrivateFunc`,\n    REGSTR_VAL_DETECT                    = `Detect`,\n    REGSTR_VAL_DETECTFUNC                = `DetectFunc`,\n    REGSTR_VAL_ASKFORCONFIG              = `AskForConfig`,\n    REGSTR_VAL_ASKFORCONFIGFUNC          = `AskForConfigFunc`,\n    REGSTR_VAL_WAITFORUNDOCK             = `WaitForUndock`,\n    REGSTR_VAL_WAITFORUNDOCKFUNC         = `WaitForUndockFunc`,\n    REGSTR_VAL_REMOVEROMOKAY             = `RemoveRomOkay`,\n    REGSTR_VAL_REMOVEROMOKAYFUNC         = `RemoveRomOkayFunc`,\n    REGSTR_VAL_CURCONFIG                 = `CurrentConfig`,\n    REGSTR_VAL_FRIENDLYNAME              = `FriendlyName`,\n    REGSTR_VAL_CURRENTCONFIG             = `CurrentConfig`,\n    REGSTR_VAL_MAP                       = `Map`,\n    REGSTR_VAL_ID                        = `CurrentID`,\n    REGSTR_VAL_DOCKED                    = `CurrentDockedState`,\n    REGSTR_VAL_CHECKSUM                  = `CurrentChecksum`,\n    REGSTR_VAL_HWDETECT                  = `HardwareDetect`,\n    REGSTR_VAL_INHIBITRESULTS            = `InhibitResults`,\n    REGSTR_VAL_PROFILEFLAGS              = `ProfileFlags`,\n    REGSTR_KEY_PCMCIA                    = `PCMCIA\\`,\n    REGSTR_KEY_PCUNKNOWN                 = `UNKNOWN_MANUFACTURER`,\n    REGSTR_VAL_PCSSDRIVER                = `Driver`,\n    REGSTR_KEY_PCMTD                     = `MTD-`,\n    REGSTR_VAL_PCMTDRIVER                = `MTD`,\n    REGSTR_VAL_HARDWAREID                = `HardwareID`,\n    REGSTR_VAL_INSTALLER                 = `Installer`,\n    REGSTR_VAL_INSICON                   = `Icon`,\n    REGSTR_VAL_ENUMPROPPAGES             = `EnumPropPages`,\n    REGSTR_VAL_BASICPROPERTIES           = `BasicProperties`,\n    REGSTR_VAL_PRIVATEPROBLEM            = `PrivateProblem`,\n    REGSTR_KEY_CURRENT                   = `Current`,\n    REGSTR_KEY_DEFAULT                   = `Default`,\n    REGSTR_KEY_MODES                     = `Modes`,\n    REGSTR_VAL_MODE                      = `Mode`,\n    REGSTR_VAL_BPP                       = `BPP`,\n    REGSTR_VAL_HRES                      = `HRes`,\n    REGSTR_VAL_VRES                      = `VRes`,\n    REGSTR_VAL_FONTSIZE                  = `FontSize`,\n    REGSTR_VAL_DRV                       = `drv`,\n    REGSTR_VAL_GRB                       = `grb`,\n    REGSTR_VAL_VDD                       = `vdd`,\n    REGSTR_VAL_VER                       = `Ver`,\n    REGSTR_VAL_MAXRES                    = `MaxResolution`,\n    REGSTR_VAL_DPMS                      = `DPMS`,\n    REGSTR_VAL_RESUMERESET               = `ResumeReset`,\n    REGSTR_VAL_DESCRIPTION               = `Description`,\n    REGSTR_KEY_SYSTEM                    = `System`,\n    REGSTR_KEY_USER                      = `User`,\n    REGSTR_VAL_DPI                       = `dpi`,\n    REGSTR_VAL_PCICOPTIONS               = `PCICOptions`,\n\n    REGSTR_VAL_PCICIRQMAP                = `PCICIRQMap`,\n    REGSTR_PATH_APPEARANCE               = `Control Panel\\Appearance`,\n    REGSTR_PATH_LOOKSCHEMES              = `Control Panel\\Appearance\\Schemes`,\n    REGSTR_VAL_CUSTOMCOLORS              = `CustomColors`,\n    REGSTR_PATH_SCREENSAVE               = `Control Panel\\Desktop`,\n    REGSTR_VALUE_USESCRPASSWORD          = `ScreenSaveUsePassword`,\n    REGSTR_VALUE_SCRPASSWORD             = `ScreenSave_Data`,\n    REGSTR_VALUE_LOWPOWERTIMEOUT         = `ScreenSaveLowPowerTimeout`,\n    REGSTR_VALUE_POWEROFFTIMEOUT         = `ScreenSavePowerOffTimeout`,\n    REGSTR_VALUE_LOWPOWERACTIVE          = `ScreenSaveLowPowerActive`,\n    REGSTR_VALUE_POWEROFFACTIVE          = `ScreenSavePowerOffActive`,\n    REGSTR_PATH_WINDOWSAPPLETS           = `Software\\Microsoft\\Windows\\CurrentVersion\\Applets`,\n    REGSTR_PATH_SYSTRAY                  = `Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\SysTray`,\n    REGSTR_VAL_SYSTRAYSVCS               = `Services`,\n    REGSTR_VAL_SYSTRAYBATFLAGS           = `PowerFlags`,\n    REGSTR_VAL_SYSTRAYPCCARDFLAGS        = `PCMCIAFlags`,\n    REGSTR_PATH_NETWORK_USERSETTINGS     = `Network`,\n    REGSTR_KEY_NETWORK_PERSISTENT        = `\\Persistent`,\n    REGSTR_KEY_NETWORK_RECENT            = `\\Recent`,\n    REGSTR_VAL_REMOTE_PATH               = `RemotePath`,\n    REGSTR_VAL_USER_NAME                 = `UserName`,\n    REGSTR_VAL_PROVIDER_NAME             = `ProviderName`,\n    REGSTR_VAL_CONNECTION_TYPE           = `ConnectionType`,\n    REGSTR_VAL_UPGRADE                   = `Upgrade`,\n    REGSTR_KEY_LOGON                     = `\\Logon`,\n    REGSTR_VAL_MUSTBEVALIDATED           = `MustBeValidated`,\n    REGSTR_VAL_RUNLOGINSCRIPT            = `ProcessLoginScript`,\n    REGSTR_KEY_NETWORKPROVIDER           = `\\NetworkProvider`,\n    REGSTR_PATH_NW32NETPROVIDER          =REGSTR_PATH_SERVICES ~ `\\NWNP32` ~ REGSTR_KEY_NETWORKPROVIDER,\n    REGSTR_PATH_MS32NETPROVIDER          =REGSTR_PATH_SERVICES ~ `\\MSNP32` ~ REGSTR_KEY_NETWORKPROVIDER,\n    REGSTR_VAL_AUTHENT_AGENT             = `AuthenticatingAgent`,\n    REGSTR_VAL_PREFREDIR                 = `PreferredRedir`,\n    REGSTR_VAL_AUTOSTART                 = `AutoStart`,\n    REGSTR_VAL_AUTOLOGON                 = `AutoLogon`,\n    REGSTR_VAL_NETCARD                   = `Netcard`,\n    REGSTR_VAL_TRANSPORT                 = `Transport`,\n    REGSTR_VAL_DYNAMIC                   = `Dynamic`,\n    REGSTR_VAL_TRANSITION                = `Transition`,\n    REGSTR_VAL_STATICDRIVE               = `StaticDrive`,\n    REGSTR_VAL_LOADHI                    = `LoadHi`,\n    REGSTR_VAL_LOADRMDRIVERS             = `LoadRMDrivers`,\n    REGSTR_VAL_SETUPN                    = `SetupN`,\n    REGSTR_VAL_SETUPNPATH                = `SetupNPath`,\n    REGSTR_VAL_WRKGRP_FORCEMAPPING       = `WrkgrpForceMapping`,\n    REGSTR_VAL_WRKGRP_REQUIRED           = `WrkgrpRequired`,\n    REGSTR_PATH_CURRENT_CONTROL_SET      = `System\\CurrentControlSet\\Control`,\n    REGSTR_VAL_CURRENT_USER              = `Current User`,\n    REGSTR_PATH_PWDPROVIDER              = `System\\CurrentControlSet\\Control\\PwdProvider`,\n    REGSTR_VAL_PWDPROVIDER_PATH          = `ProviderPath`,\n    REGSTR_VAL_PWDPROVIDER_DESC          = `Description`,\n    REGSTR_VAL_PWDPROVIDER_CHANGEPWD     = `ChangePassword`,\n    REGSTR_VAL_PWDPROVIDER_CHANGEPWDHWND = `ChangePasswordHwnd`,\n    REGSTR_VAL_PWDPROVIDER_GETPWDSTATUS  = `GetPasswordStatus`,\n    REGSTR_VAL_PWDPROVIDER_ISNP          = `NetworkProvider`,\n    REGSTR_VAL_PWDPROVIDER_CHANGEORDER   = `ChangeOrder`,\n    REGSTR_PATH_POLICIES                 = `Software\\Microsoft\\Windows\\CurrentVersion\\Policies`,\n    REGSTR_PATH_UPDATE                   = `System\\CurrentControlSet\\Control\\Update`,\n    REGSTR_VALUE_ENABLE                  = `Enable`,\n    REGSTR_VALUE_VERBOSE                 = `Verbose`,\n    REGSTR_VALUE_NETPATH                 = `NetworkPath`,\n    REGSTR_VALUE_DEFAULTLOC              = `UseDefaultNetLocation`,\n    REGSTR_KEY_NETWORK                   = `Network`,\n// [Redefined] REGSTR_KEY_SYSTEM         = `System`)\n    REGSTR_KEY_PRINTERS                  = `Printers`,\n    REGSTR_KEY_WINOLDAPP                 = `WinOldApp`,\n    REGSTR_VAL_NOFILESHARING             = `NoFileSharing`,\n    REGSTR_VAL_NOPRINTSHARING            = `NoPrintSharing`,\n    REGSTR_VAL_NOFILESHARINGCTRL         = `NoFileSharingControl`,\n    REGSTR_VAL_NOPRINTSHARINGCTRL        = `NoPrintSharingControl`,\n    REGSTR_VAL_HIDESHAREPWDS             = `HideSharePwds`,\n    REGSTR_VAL_DISABLEPWDCACHING         = `DisablePwdCaching`,\n    REGSTR_VAL_ALPHANUMPWDS              = `AlphanumPwds`,\n    REGSTR_VAL_NETSETUP_DISABLE          = `NoNetSetup`,\n    REGSTR_VAL_NETSETUP_NOCONFIGPAGE     = `NoNetSetupConfigPage`,\n    REGSTR_VAL_NETSETUP_NOIDPAGE         = `NoNetSetupIDPage`,\n    REGSTR_VAL_NETSETUP_NOSECURITYPAGE   = `NoNetSetupSecurityPage`,\n    REGSTR_VAL_SYSTEMCPL_NOVIRTMEMPAGE   = `NoVirtMemPage`,\n    REGSTR_VAL_SYSTEMCPL_NODEVMGRPAGE    = `NoDevMgrPage`,\n    REGSTR_VAL_SYSTEMCPL_NOCONFIGPAGE    = `NoConfigPage`,\n    REGSTR_VAL_SYSTEMCPL_NOFILESYSPAGE   = `NoFileSysPage`,\n    REGSTR_VAL_DISPCPL_NODISPCPL         = `NoDispCPL`,\n    REGSTR_VAL_DISPCPL_NOBACKGROUNDPAGE  = `NoDispBackgroundPage`,\n    REGSTR_VAL_DISPCPL_NOSCRSAVPAGE      = `NoDispScrSavPage`,\n    REGSTR_VAL_DISPCPL_NOAPPEARANCEPAGE  = `NoDispAppearancePage`,\n    REGSTR_VAL_DISPCPL_NOSETTINGSPAGE    = `NoDispSettingsPage`,\n    REGSTR_VAL_SECCPL_NOSECCPL           = `NoSecCPL`,\n    REGSTR_VAL_SECCPL_NOPWDPAGE          = `NoPwdPage`,\n    REGSTR_VAL_SECCPL_NOADMINPAGE        = `NoAdminPage`,\n    REGSTR_VAL_SECCPL_NOPROFILEPAGE      = `NoProfilePage`,\n    REGSTR_VAL_PRINTERS_HIDETABS         = `NoPrinterTabs`,\n    REGSTR_VAL_PRINTERS_NODELETE         = `NoDeletePrinter`,\n    REGSTR_VAL_PRINTERS_NOADD            = `NoAddPrinter`,\n    REGSTR_VAL_WINOLDAPP_DISABLED        = `Disabled`,\n    REGSTR_VAL_WINOLDAPP_NOREALMODE      = `NoRealMode`,\n    REGSTR_VAL_NOENTIRENETWORK           = `NoEntireNetwork`,\n    REGSTR_VAL_NOWORKGROUPCONTENTS       = `NoWorkgroupContents`,\n    REGSTR_VAL_MINPWDLEN                 = `MinPwdLen`,\n    REGSTR_VAL_PWDEXPIRATION             = `PwdExpiration`,\n    REGSTR_VAL_WIN31PROVIDER             = `Win31Provider`,\n    REGSTR_VAL_DISABLEREGTOOLS           = `DisableRegistryTools`,\n    REGSTR_PATH_WINLOGON                 = `Software\\Microsoft\\Windows\\CurrentVersion\\Winlogon`,\n    REGSTR_VAL_LEGALNOTICECAPTION        = `LegalNoticeCaption`,\n    REGSTR_VAL_LEGALNOTICETEXT           = `LegalNoticeText`,\n    REGSTR_VAL_RESTRICTRUN               = `RestrictRun`,\n    REGSTR_KEY_POL_USERS                 = `Users`,\n    REGSTR_KEY_POL_COMPUTERS             = `Computers`,\n    REGSTR_KEY_POL_USERGROUPS            = `UserGroups`,\n    REGSTR_KEY_POL_DEFAULT               = `.default`,\n    REGSTR_KEY_POL_USERGROUPDATA         = `GroupData\\UserGroups\\Priority`,\n    REGSTR_PATH_TIMEZONE                 = `System\\CurrentControlSet\\Control\\TimeZoneInformation`,\n    REGSTR_VAL_TZBIAS                    = `Bias`,\n    REGSTR_VAL_TZDLTBIAS                 = `DaylightBias`,\n    REGSTR_VAL_TZSTDBIAS                 = `StandardBias`,\n    REGSTR_VAL_TZACTBIAS                 = `ActiveTimeBias`,\n    REGSTR_VAL_TZDLTFLAG                 = `DaylightFlag`,\n    REGSTR_VAL_TZSTDSTART                = `StandardStart`,\n    REGSTR_VAL_TZDLTSTART                = `DaylightStart`,\n    REGSTR_VAL_TZDLTNAME                 = `DaylightName`,\n    REGSTR_VAL_TZSTDNAME                 = `StandardName`,\n    REGSTR_VAL_TZNOCHANGESTART           = `NoChangeStart`,\n    REGSTR_VAL_TZNOCHANGEEND             = `NoChangeEnd`,\n    REGSTR_VAL_TZNOAUTOTIME              = `DisableAutoDaylightTimeSet`,\n    REGSTR_PATH_FLOATINGPOINTPROCESSOR   = `HARDWARE\\DESCRIPTION\\System\\FloatingPointProcessor`,\n    REGSTR_PATH_FLOATINGPOINTPROCESSOR0  = `HARDWARE\\DESCRIPTION\\System\\FloatingPointProcessor\\0`,\n    REGSTR_PATH_COMPUTRNAME              = `System\\CurrentControlSet\\Control\\ComputerName\\ComputerName`,\n    REGSTR_VAL_COMPUTRNAME               = `ComputerName`,\n    REGSTR_PATH_SHUTDOWN                 = `System\\CurrentControlSet\\Control\\Shutdown`,\n    REGSTR_VAL_FORCEREBOOT               = `ForceReboot`,\n    REGSTR_VAL_SETUPPROGRAMRAN           = `SetupProgramRan`,\n    REGSTR_VAL_DOES_POLLING              = `PollingSupportNeeded`,\n    REGSTR_PATH_KNOWNDLLS                = `System\\CurrentControlSet\\Control\\SessionManager\\KnownDLLs`,\n    REGSTR_PATH_KNOWN16DLLS              = `System\\CurrentControlSet\\Control\\SessionManager\\Known16DLLs`,\n    REGSTR_PATH_CHECKVERDLLS             = `System\\CurrentControlSet\\Control\\SessionManager\\CheckVerDLLs`,\n    REGSTR_PATH_WARNVERDLLS              = `System\\CurrentControlSet\\Control\\SessionManager\\WarnVerDLLs`,\n    REGSTR_PATH_HACKINIFILE              = `System\\CurrentControlSet\\Control\\SessionManager\\HackIniFiles`,\n    REGSTR_PATH_CHECKBADAPPS             = `System\\CurrentControlSet\\Control\\SessionManager\\CheckBadApps`,\n    REGSTR_PATH_APPPATCH                 = `System\\CurrentControlSet\\Control\\SessionManager\\AppPatches`,\n    REGSTR_PATH_KNOWNVXDS                = `System\\CurrentControlSet\\Control\\SessionManager\\KnownVxDs`,\n    REGSTR_VAL_UNINSTALLER_DISPLAYNAME   = `DisplayName`,\n    REGSTR_VAL_UNINSTALLER_COMMANDLINE   = `UninstallString`,\n    REGSTR_PATH_DESKTOP                  = REGSTR_PATH_SCREENSAVE,\n    REGSTR_PATH_MOUSE                    = `Control Panel\\Mouse`,\n    REGSTR_PATH_KEYBOARD                 = `Control Panel\\Keyboard`,\n    REGSTR_PATH_COLORS                   = `Control Panel\\Colors`,\n    REGSTR_PATH_SOUND                    = `Control Panel\\Sound`,\n    REGSTR_PATH_METRICS                  = `Control Panel\\Desktop\\WindowMetrics`,\n    REGSTR_PATH_ICONS                    = `Control Panel\\Icons`,\n    REGSTR_PATH_CURSORS                  = `Control Panel\\Cursors`,\n    REGSTR_PATH_CHECKDISK                = `Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Check Drive`,\n    REGSTR_PATH_CHECKDISKSET             = `Settings`,\n    REGSTR_PATH_CHECKDISKUDRVS           = `NoUnknownDDErrDrvs`,\n    REGSTR_PATH_FAULT                    = `Software\\Microsoft\\Windows\\CurrentVersion\\Fault`,\n    REGSTR_VAL_FAULT_LOGFILE             = `LogFile`,\n    REGSTR_PATH_AEDEBUG                  = `Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug`,\n    REGSTR_VAL_AEDEBUG_DEBUGGER          = `Debugger`,\n    REGSTR_VAL_AEDEBUG_AUTO              = `Auto`,\n    REGSTR_PATH_GRPCONV                  = `Software\\Microsoft\\Windows\\CurrentVersion\\GrpConv`,\n    REGSTR_VAL_REGITEMDELETEMESSAGE      = `Removal Message`,\n    REGSTR_PATH_LASTCHECK                = `Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\LastCheck`,\n    REGSTR_PATH_LASTOPTIMIZE             = `Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\LastOptimize`,\n    REGSTR_PATH_LASTBACKUP               = `Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\LastBackup`,\n    REGSTR_PATH_CHKLASTCHECK             = `Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Check Drive\\LastCheck`,\n    REGSTR_PATH_CHKLASTSURFAN            = `Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Check Drive\\LastSurfaceAnalysis`,\n    REGSTR_KEY_SHARES                    = `Software\\Microsoft\\Windows\\CurrentVersion\\Network\\LanMan`,\n    REGSTR_VAL_SHARES_FLAGS              = `Flags`,\n    REGSTR_VAL_SHARES_TYPE               = `Type`,\n    REGSTR_VAL_SHARES_PATH               = `Path`,\n    REGSTR_VAL_SHARES_REMARK             = `Remark`,\n    REGSTR_VAL_SHARES_RW_PASS            = `Parm1`,\n    REGSTR_VAL_SHARES_RO_PASS            = `Parm2`,\n    REGSTR_PATH_PRINT                    = `System\\CurrentControlSet\\Control\\Print`,\n    REGSTR_PATH_PRINTERS                 = `System\\CurrentControlSet\\Control\\Print\\Printers`,\n    REGSTR_PATH_PROVIDERS                = `System\\CurrentControlSet\\Control\\Print\\Providers`,\n    REGSTR_PATH_MONITORS                 = `System\\CurrentControlSet\\Control\\Print\\Monitors`,\n    REGSTR_PATH_ENVIRONMENTS             = `System\\CurrentControlSet\\Control\\Print\\Environments`,\n    REGSTR_VAL_START_ON_BOOT             = `StartOnBoot`,\n    REGSTR_VAL_PRINTERS_MASK             = `PrintersMask`,\n    REGSTR_VAL_DOS_SPOOL_MASK            = `DOSSpoolMask`,\n    REGSTR_KEY_CURRENT_ENV               = `\\Windows 4.0`,\n    REGSTR_KEY_DRIVERS                   = `\\Drivers`,\n    REGSTR_KEY_PRINT_PROC                = `\\Print Processors`,\n    REGSTR_PATH_EVENTLABELS              = `AppEvents\\EventLabels`,\n    REGSTR_PATH_SCHEMES                  = `AppEvents\\Schemes`,\n    REGSTR_PATH_APPS                     = REGSTR_PATH_SCHEMES ~ `\\Apps`,\n    REGSTR_PATH_APPS_DEFAULT             = REGSTR_PATH_SCHEMES ~ `\\Apps\\.Default`,\n    REGSTR_PATH_NAMES                    = REGSTR_PATH_SCHEMES ~ `\\Names`,\n    REGSTR_PATH_MULTIMEDIA               = REGSTR_PATH_SETUP ~ `\\Multimedia`,\n    REGSTR_PATH_MULTIMEDIA_AUDIO         = `Software\\Microsoft\\Multimedia\\Audio`,\n    REGSTR_PATH_MEDIARESOURCES           = REGSTR_PATH_CURRENT_CONTROL_SET ~ `\\MediaResources`,\n    REGSTR_PATH_MEDIAPROPERTIES          = REGSTR_PATH_CURRENT_CONTROL_SET ~ `\\MediaProperties`,\n    REGSTR_PATH_PRIVATEPROPERTIES        = REGSTR_PATH_MEDIAPROPERTIES ~ `\\PrivateProperties`,\n    REGSTR_PATH_PUBLICPROPERTIES         = REGSTR_PATH_MEDIAPROPERTIES ~ `\\PublicProperties`,\n    REGSTR_PATH_JOYOEM                   = REGSTR_PATH_PRIVATEPROPERTIES ~ `\\Joystick\\OEM`,\n    REGSTR_PATH_JOYCONFIG                = REGSTR_PATH_MEDIARESOURCES ~ `\\Joystick`,\n    REGSTR_KEY_JOYCURR                   = `CurrentJoystickSettings`,\n    REGSTR_KEY_JOYSETTINGS               = `JoystickSettings`,\n    REGSTR_VAL_JOYUSERVALUES             = `JoystickUserValues`,\n    REGSTR_VAL_JOYCALLOUT                = `JoystickCallout`,\n    REGSTR_VAL_JOYNCONFIG                = `Joystick%dConfiguration`,\n    REGSTR_VAL_JOYNOEMNAME               = `Joystick%dOEMName`,\n    REGSTR_VAL_JOYNOEMCALLOUT            = `Joystick%dOEMCallout`,\n    REGSTR_VAL_JOYOEMCALLOUT             = `OEMCallout`,\n    REGSTR_VAL_JOYOEMNAME                = `OEMName`,\n    REGSTR_VAL_JOYOEMDATA                = `OEMData`,\n    REGSTR_VAL_JOYOEMXYLABEL             = `OEMXYLabel`,\n    REGSTR_VAL_JOYOEMZLABEL              = `OEMZLabel`,\n    REGSTR_VAL_JOYOEMRLABEL              = `OEMRLabel`,\n    REGSTR_VAL_JOYOEMPOVLABEL            = `OEMPOVLabel`,\n    REGSTR_VAL_JOYOEMULABEL              = `OEMULabel`,\n    REGSTR_VAL_JOYOEMVLABEL              = `OEMVLabel`,\n    REGSTR_VAL_JOYOEMTESTMOVEDESC        = `OEMTestMoveDesc`,\n    REGSTR_VAL_JOYOEMTESTBUTTONDESC      = `OEMTestButtonDesc`,\n    REGSTR_VAL_JOYOEMTESTMOVECAP         = `OEMTestMoveCap`,\n    REGSTR_VAL_JOYOEMTESTBUTTONCAP       = `OEMTestButtonCap`,\n    REGSTR_VAL_JOYOEMTESTWINCAP          = `OEMTestWinCap`,\n    REGSTR_VAL_JOYOEMCALCAP              = `OEMCalCap`,\n    REGSTR_VAL_JOYOEMCALWINCAP           = `OEMCalWinCap`,\n    REGSTR_VAL_JOYOEMCAL1                = `OEMCal1`,\n    REGSTR_VAL_JOYOEMCAL2                = `OEMCal2`,\n    REGSTR_VAL_JOYOEMCAL3                = `OEMCal3`,\n    REGSTR_VAL_JOYOEMCAL4                = `OEMCal4`,\n    REGSTR_VAL_JOYOEMCAL5                = `OEMCal5`,\n    REGSTR_VAL_JOYOEMCAL6                = `OEMCal6`,\n    REGSTR_VAL_JOYOEMCAL7                = `OEMCal7`,\n    REGSTR_VAL_JOYOEMCAL8                = `OEMCal8`,\n    REGSTR_VAL_JOYOEMCAL9                = `OEMCal9`,\n    REGSTR_VAL_JOYOEMCAL10               = `OEMCal10`,\n    REGSTR_VAL_JOYOEMCAL11               = `OEMCal11`,\n    REGSTR_VAL_JOYOEMCAL12               = `OEMCal12`;\n\nenum {\n    DTRESULTOK,\n    DTRESULTFIX,\n    DTRESULTPROB,\n    DTRESULTPART\n}\n\n//#ifndef NEC_98\nenum PCIC_DEFAULT_IRQMASK = 0x4EB8;\n//#else\n//#define PCIC_DEFAULT_IRQMASK  0x1468\n//#endif\nenum PCIC_DEFAULT_NUMSOCKETS = 0;\n\nstruct DSKTLSYSTEMTIME {\n    WORD wYear;\n    WORD wMonth;\n    WORD wDayOfWeek;\n    WORD wDay;\n    WORD wHour;\n    WORD wMinute;\n    WORD wSecond;\n    WORD wMilliseconds;\n    WORD wResult;\n}\nalias DSKTLSYSTEMTIME* PDSKTLSYSTEMTIME, LPDSKTLSYSTEMTIME;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/richedit.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_richedit.d)\n */\nmodule core.sys.windows.richedit;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.windef, core.sys.windows.winuser;\nprivate import core.sys.windows.wingdi; // for LF_FACESIZE\n\nalign(4):\n\nversion (Unicode) {\nconst wchar[] RICHEDIT_CLASS = \"RichEdit20W\";\n} else {\nconst char[] RICHEDIT_CLASS  = \"RichEdit20A\";\n}\n\nenum RICHEDIT_CLASS10A = \"RICHEDIT\";\n\nconst TCHAR[]\n    CF_RTF       = \"Rich Text Format\",\n    CF_RTFNOOBJS = \"Rich Text Format Without Objects\",\n    CF_RETEXTOBJ = \"RichEdit Text and Objects\";\n\nenum DWORD\n    CFM_BOLD        = 1,\n    CFM_ITALIC      = 2,\n    CFM_UNDERLINE   = 4,\n    CFM_STRIKEOUT   = 8,\n    CFM_PROTECTED   = 16,\n    CFM_LINK        = 32,\n    CFM_SIZE        = 0x80000000,\n    CFM_COLOR       = 0x40000000,\n    CFM_FACE        = 0x20000000,\n    CFM_OFFSET      = 0x10000000,\n    CFM_CHARSET     = 0x08000000,\n    CFM_SUBSCRIPT   = 0x00030000,\n    CFM_SUPERSCRIPT = 0x00030000;\n\nenum DWORD\n    CFE_BOLD        = 1,\n    CFE_ITALIC      = 2,\n    CFE_UNDERLINE   = 4,\n    CFE_STRIKEOUT   = 8,\n    CFE_PROTECTED   = 16,\n    CFE_SUBSCRIPT   = 0x00010000,\n    CFE_SUPERSCRIPT = 0x00020000,\n    CFE_AUTOCOLOR   = 0x40000000;\n\nenum CFM_EFFECTS = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_COLOR\n  | CFM_STRIKEOUT | CFE_PROTECTED | CFM_LINK;\n\n// flags for EM_SETIMEOPTIONS\nenum LPARAM\n    IMF_FORCENONE         = 1,\n    IMF_FORCEENABLE       = 2,\n    IMF_FORCEDISABLE      = 4,\n    IMF_CLOSESTATUSWINDOW = 8,\n    IMF_VERTICAL          = 32,\n    IMF_FORCEACTIVE       = 64,\n    IMF_FORCEINACTIVE     = 128,\n    IMF_FORCEREMEMBER     = 256;\n\nenum SEL_EMPTY=0;\nenum SEL_TEXT=1;\nenum SEL_OBJECT=2;\nenum SEL_MULTICHAR=4;\nenum SEL_MULTIOBJECT=8;\n\nenum MAX_TAB_STOPS=32;\n\nenum PFM_ALIGNMENT=8;\nenum PFM_NUMBERING=32;\nenum PFM_OFFSET=4;\nenum PFM_OFFSETINDENT=0x80000000;\nenum PFM_RIGHTINDENT=2;\nenum PFM_STARTINDENT=1;\nenum PFM_TABSTOPS=16;\nenum PFM_BORDER=2048;\nenum PFM_LINESPACING=256;\nenum PFM_NUMBERINGSTART=32768;\nenum PFM_NUMBERINGSTYLE=8192;\nenum PFM_NUMBERINGTAB=16384;\nenum PFM_SHADING=4096;\nenum PFM_SPACEAFTER=128;\nenum PFM_SPACEBEFORE=64;\nenum PFM_STYLE=1024;\nenum PFM_DONOTHYPHEN=4194304;\nenum PFM_KEEP=131072;\nenum PFM_KEEPNEXT=262144;\nenum PFM_NOLINENUMBER=1048576;\nenum PFM_NOWIDOWCONTROL=2097152;\nenum PFM_PAGEBREAKBEFORE=524288;\nenum PFM_RTLPARA=65536;\nenum PFM_SIDEBYSIDE=8388608;\nenum PFM_TABLE=1073741824;\nenum PFN_BULLET=1;\n\nenum PFE_DONOTHYPHEN=64;\nenum PFE_KEEP=2;\nenum PFE_KEEPNEXT=4;\nenum PFE_NOLINENUMBER=16;\nenum PFE_NOWIDOWCONTROL=32;\nenum PFE_PAGEBREAKBEFORE=8;\nenum PFE_RTLPARA=1;\nenum PFE_SIDEBYSIDE=128;\nenum PFE_TABLE=16384;\nenum PFA_LEFT=1;\nenum PFA_RIGHT=2;\nenum PFA_CENTER=3;\nenum PFA_JUSTIFY=4;\nenum PFA_FULL_INTERWORD=4;\n\nenum SF_TEXT=1;\nenum SF_RTF=2;\nenum SF_RTFNOOBJS=3;\nenum SF_TEXTIZED=4;\nenum SF_UNICODE=16;\nenum SF_USECODEPAGE=32;\nenum SF_NCRFORNONASCII=64;\nenum SF_RTFVAL=0x0700;\n\nenum SFF_PWD=0x0800;\nenum SFF_KEEPDOCINFO=0x1000;\nenum SFF_PERSISTVIEWSCALE=0x2000;\nenum SFF_PLAINRTF=0x4000;\nenum SFF_SELECTION=0x8000;\n\nenum WB_CLASSIFY      = 3;\nenum WB_MOVEWORDLEFT  = 4;\nenum WB_MOVEWORDRIGHT = 5;\nenum WB_LEFTBREAK     = 6;\nenum WB_RIGHTBREAK    = 7;\nenum WB_MOVEWORDPREV  = 4;\nenum WB_MOVEWORDNEXT  = 5;\nenum WB_PREVBREAK     = 6;\nenum WB_NEXTBREAK     = 7;\n\nenum WBF_WORDWRAP  = 16;\nenum WBF_WORDBREAK = 32;\nenum WBF_OVERFLOW  = 64;\nenum WBF_LEVEL1    = 128;\nenum WBF_LEVEL2    = 256;\nenum WBF_CUSTOM    = 512;\n\nenum ES_DISABLENOSCROLL  = 8192;\nenum ES_SUNKEN           = 16384;\nenum ES_SAVESEL          = 32768;\nenum ES_EX_NOCALLOLEINIT = 16777216;\nenum ES_NOIME            = 524288;\nenum ES_NOOLEDRAGDROP    = 8;\nenum ES_SELECTIONBAR     = 16777216;\nenum ES_SELFIME          = 262144;\nenum ES_VERTICAL         = 4194304;\n\nenum EM_CANPASTE = WM_USER+50;\nenum EM_DISPLAYBAND = WM_USER+51;\nenum EM_EXGETSEL = WM_USER+52;\nenum EM_EXLIMITTEXT = WM_USER+53;\nenum EM_EXLINEFROMCHAR = WM_USER+54;\nenum EM_EXSETSEL = WM_USER+55;\nenum EM_FINDTEXT = WM_USER+56;\nenum EM_FORMATRANGE = WM_USER+57;\nenum EM_GETCHARFORMAT = WM_USER+58;\nenum EM_GETEVENTMASK = WM_USER+59;\nenum EM_GETOLEINTERFACE = WM_USER+60;\nenum EM_GETPARAFORMAT = WM_USER+61;\nenum EM_GETSELTEXT = WM_USER+62;\nenum EM_HIDESELECTION = WM_USER+63;\nenum EM_PASTESPECIAL = WM_USER+64;\nenum EM_REQUESTRESIZE = WM_USER+65;\nenum EM_SELECTIONTYPE = WM_USER+66;\nenum EM_SETBKGNDCOLOR = WM_USER+67;\nenum EM_SETCHARFORMAT = WM_USER+68;\nenum EM_SETEVENTMASK = WM_USER+69;\nenum EM_SETOLECALLBACK = WM_USER+70;\nenum EM_SETPARAFORMAT = WM_USER+71;\nenum EM_SETTARGETDEVICE = WM_USER+72;\nenum EM_STREAMIN = WM_USER+73;\nenum EM_STREAMOUT = WM_USER+74;\nenum EM_GETTEXTRANGE = WM_USER+75;\nenum EM_FINDWORDBREAK = WM_USER+76;\nenum EM_SETOPTIONS = WM_USER+77;\nenum EM_GETOPTIONS = WM_USER+78;\nenum EM_FINDTEXTEX = WM_USER+79;\nenum EM_GETWORDBREAKPROCEX = WM_USER+80;\nenum EM_SETWORDBREAKPROCEX = WM_USER+81;\n/* RichEdit 2.0 messages */\nenum EM_SETUNDOLIMIT = WM_USER+82;\nenum EM_REDO = WM_USER+84;\nenum EM_CANREDO = WM_USER+85;\nenum EM_GETUNDONAME = WM_USER+86;\nenum EM_GETREDONAME = WM_USER+87;\nenum EM_STOPGROUPTYPING = WM_USER+88;\nenum EM_SETTEXTMODE = WM_USER+89;\nenum EM_GETTEXTMODE = WM_USER+90;\nenum EM_AUTOURLDETECT = WM_USER+91;\nenum EM_GETAUTOURLDETECT = WM_USER + 92;\nenum EM_SETPALETTE = WM_USER + 93;\nenum EM_GETTEXTEX = WM_USER+94;\nenum EM_GETTEXTLENGTHEX = WM_USER+95;\nenum EM_SHOWSCROLLBAR = WM_USER+96;\nenum EM_SETTEXTEX = WM_USER + 97;\nenum EM_SETPUNCTUATION = WM_USER + 100;\nenum EM_GETPUNCTUATION = WM_USER + 101;\nenum EM_SETWORDWRAPMODE = WM_USER + 102;\nenum EM_GETWORDWRAPMODE = WM_USER + 103;\nenum EM_SETIMECOLOR = WM_USER + 104;\nenum EM_GETIMECOLOR = WM_USER + 105;\nenum EM_SETIMEOPTIONS = WM_USER + 106;\nenum EM_GETIMEOPTIONS = WM_USER + 107;\nenum EM_SETLANGOPTIONS = WM_USER+120;\nenum EM_GETLANGOPTIONS = WM_USER+121;\nenum EM_GETIMECOMPMODE = WM_USER+122;\nenum EM_FINDTEXTW = WM_USER + 123;\nenum EM_FINDTEXTEXW = WM_USER + 124;\nenum EM_RECONVERSION = WM_USER + 125;\nenum EM_SETBIDIOPTIONS = WM_USER + 200;\nenum EM_GETBIDIOPTIONS = WM_USER + 201;\nenum EM_SETTYPOGRAPHYOPTIONS = WM_USER+202;\nenum EM_GETTYPOGRAPHYOPTIONS = WM_USER+203;\nenum EM_SETEDITSTYLE = WM_USER + 204;\nenum EM_GETEDITSTYLE = WM_USER + 205;\nenum EM_GETSCROLLPOS = WM_USER+221;\nenum EM_SETSCROLLPOS = WM_USER+222;\nenum EM_SETFONTSIZE = WM_USER+223;\nenum EM_GETZOOM = WM_USER+224;\nenum EM_SETZOOM = WM_USER+225;\n\nenum EN_MSGFILTER     = 1792;\nenum EN_REQUESTRESIZE = 1793;\nenum EN_SELCHANGE     = 1794;\nenum EN_DROPFILES     = 1795;\nenum EN_PROTECTED     = 1796;\nenum EN_CORRECTTEXT   = 1797;\nenum EN_STOPNOUNDO    = 1798;\nenum EN_IMECHANGE     = 1799;\nenum EN_SAVECLIPBOARD = 1800;\nenum EN_OLEOPFAILED   = 1801;\nenum EN_LINK          = 1803;\n\nenum ENM_NONE            = 0;\nenum ENM_CHANGE          = 1;\nenum ENM_UPDATE          = 2;\nenum ENM_SCROLL          = 4;\nenum ENM_SCROLLEVENTS    = 8;\nenum ENM_DRAGDROPDONE    = 16;\nenum ENM_KEYEVENTS       = 65536;\nenum ENM_MOUSEEVENTS     = 131072;\nenum ENM_REQUESTRESIZE   = 262144;\nenum ENM_SELCHANGE       = 524288;\nenum ENM_DROPFILES       = 1048576;\nenum ENM_PROTECTED       = 2097152;\nenum ENM_CORRECTTEXT     = 4194304;\nenum ENM_IMECHANGE       = 8388608;\nenum ENM_LANGCHANGE      = 16777216;\nenum ENM_OBJECTPOSITIONS = 33554432;\nenum ENM_LINK            = 67108864;\n\nenum ECO_AUTOWORDSELECTION=1;\nenum ECO_AUTOVSCROLL=64;\nenum ECO_AUTOHSCROLL=128;\nenum ECO_NOHIDESEL=256;\nenum ECO_READONLY=2048;\nenum ECO_WANTRETURN=4096;\nenum ECO_SAVESEL=0x8000;\nenum ECO_SELECTIONBAR=0x1000000;\nenum ECO_VERTICAL=0x400000;\n\nenum {\n    ECOOP_SET = 1,\n    ECOOP_OR,\n    ECOOP_AND,\n    ECOOP_XOR\n}\n\nenum SCF_DEFAULT    = 0;\nenum SCF_SELECTION  = 1;\nenum SCF_WORD       = 2;\nenum SCF_ALL        = 4;\nenum SCF_USEUIRULES = 8;\n\nalias DWORD TEXTMODE;\nenum TM_PLAINTEXT=1;\nenum TM_RICHTEXT=2;\nenum TM_SINGLELEVELUNDO=4;\nenum TM_MULTILEVELUNDO=8;\nenum TM_SINGLECODEPAGE=16;\nenum TM_MULTICODEPAGE=32;\n\nenum GT_DEFAULT=0;\nenum GT_USECRLF=1;\n\nenum yHeightCharPtsMost=1638;\nenum lDefaultTab=720;\n\nalias DWORD UNDONAMEID;\nenum UID_UNKNOWN    = 0;\nenum UID_TYPING     = 1;\nenum UID_DELETE     = 2;\nenum UID_DRAGDROP   = 3;\nenum UID_CUT        = 4;\nenum UID_PASTE      = 5;\n\nstruct CHARFORMATA {\n    UINT cbSize = this.sizeof;\n    DWORD dwMask;\n    DWORD dwEffects;\n    LONG yHeight;\n    LONG yOffset;\n    COLORREF crTextColor;\n    BYTE bCharSet;\n    BYTE bPitchAndFamily;\n    char[LF_FACESIZE] szFaceName;\n}\nstruct CHARFORMATW {\n    UINT cbSize = this.sizeof;\n    DWORD dwMask;\n    DWORD dwEffects;\n    LONG yHeight;\n    LONG yOffset;\n    COLORREF crTextColor;\n    BYTE bCharSet;\n    BYTE bPitchAndFamily;\n    WCHAR[LF_FACESIZE] szFaceName;\n}\n\nstruct CHARFORMAT2A {\n    UINT cbSize = this.sizeof;\n    DWORD dwMask;\n    DWORD dwEffects;\n    LONG yHeight;\n    LONG yOffset;\n    COLORREF crTextColor;\n    BYTE bCharSet;\n    BYTE bPitchAndFamily;\n    char[LF_FACESIZE] szFaceName;\n    WORD wWeight;\n    SHORT sSpacing;\n    COLORREF crBackColor;\n    LCID lcid;\n    DWORD dwReserved;\n    SHORT sStyle;\n    WORD wKerning;\n    BYTE bUnderlineType;\n    BYTE bAnimation;\n    BYTE bRevAuthor;\n}\n\nstruct CHARFORMAT2W {\n    UINT cbSize = this.sizeof;\n    DWORD dwMask;\n    DWORD dwEffects;\n    LONG yHeight;\n    LONG yOffset;\n    COLORREF crTextColor;\n    BYTE bCharSet;\n    BYTE bPitchAndFamily;\n    WCHAR[LF_FACESIZE] szFaceName;\n    WORD wWeight;\n    SHORT sSpacing;\n    COLORREF crBackColor;\n    LCID lcid;\n    DWORD dwReserved;\n    SHORT sStyle;\n    WORD wKerning;\n    BYTE bUnderlineType;\n    BYTE bAnimation;\n    BYTE bRevAuthor;\n}\n\nstruct CHARRANGE {\n    LONG cpMin;\n    LONG cpMax;\n}\n\nstruct COMPCOLOR {\n    COLORREF crText;\n    COLORREF crBackground;\n    DWORD dwEffects;\n}\n\nextern (Windows) {\n    alias DWORD function(DWORD_PTR,PBYTE,LONG,LONG*) EDITSTREAMCALLBACK;\n}\n\nstruct EDITSTREAM {\nalign(4):\n    DWORD_PTR dwCookie;\n    DWORD dwError;\n    EDITSTREAMCALLBACK pfnCallback;\n}\n\nstruct ENCORRECTTEXT {\nalign(4):\n    NMHDR nmhdr;\n    CHARRANGE chrg;\n    WORD seltyp;\n}\n\nstruct ENDROPFILES {\nalign(4):\n    NMHDR nmhdr;\n    HANDLE hDrop;\n    LONG cp;\n    BOOL fProtected;\n}\n\nstruct ENLINK {\nalign(4):\n    NMHDR nmhdr;\n    UINT msg;\n    WPARAM wParam;\n    LPARAM lParam;\n    CHARRANGE chrg;\n}\n\nstruct ENOLEOPFAILED {\nalign(4):\n    NMHDR nmhdr;\n    LONG iob;\n    LONG lOper;\n    HRESULT hr;\n}\n\nstruct ENPROTECTED {\nalign(4):\n    NMHDR nmhdr;\n    UINT msg;\n    WPARAM wParam;\n    LPARAM lParam;\n    CHARRANGE chrg;\n}\nalias ENPROTECTED* LPENPROTECTED;\n\nstruct ENSAVECLIPBOARD {\nalign(4):\n    NMHDR nmhdr;\n    LONG cObjectCount;\n    LONG cch;\n}\n\nstruct FINDTEXTA {\n    CHARRANGE chrg;\n    LPSTR lpstrText;\n}\n\nstruct FINDTEXTW {\n    CHARRANGE chrg;\n    LPWSTR lpstrText;\n}\n\nstruct FINDTEXTEXA {\n    CHARRANGE chrg;\n    LPSTR lpstrText;\n    CHARRANGE chrgText;\n}\n\nstruct FINDTEXTEXW {\n    CHARRANGE chrg;\n    LPWSTR lpstrText;\n    CHARRANGE chrgText;\n}\n\nstruct FORMATRANGE {\n    HDC hdc;\n    HDC hdcTarget;\n    RECT rc;\n    RECT rcPage;\n    CHARRANGE chrg;\n}\n\nstruct MSGFILTER {\nalign(4):\n    NMHDR nmhdr;\n    UINT msg;\n    WPARAM wParam;\n    LPARAM lParam;\n}\n\nstruct PARAFORMAT {\n    UINT cbSize = this.sizeof;\n    DWORD dwMask;\n    WORD wNumbering;\n    WORD wReserved;\n    LONG dxStartIndent;\n    LONG dxRightIndent;\n    LONG dxOffset;\n    WORD wAlignment;\n    SHORT cTabCount;\n    LONG[MAX_TAB_STOPS] rgxTabs;\n}\n\nstruct PARAFORMAT2 {\n    UINT cbSize = this.sizeof;\n    DWORD dwMask;\n    WORD wNumbering;\n    WORD wEffects;\n    LONG dxStartIndent;\n    LONG dxRightIndent;\n    LONG dxOffset;\n    WORD wAlignment;\n    SHORT cTabCount;\n    LONG[MAX_TAB_STOPS] rgxTabs;\n    LONG dySpaceBefore;\n    LONG dySpaceAfter;\n    LONG dyLineSpacing;\n    SHORT sStype;\n    BYTE bLineSpacingRule;\n    BYTE bOutlineLevel;\n    WORD wShadingWeight;\n    WORD wShadingStyle;\n    WORD wNumberingStart;\n    WORD wNumberingStyle;\n    WORD wNumberingTab;\n    WORD wBorderSpace;\n    WORD wBorderWidth;\n    WORD wBorders;\n}\n\nstruct SELCHANGE {\n    NMHDR nmhdr;\n    CHARRANGE chrg;\n    WORD seltyp;\n}\n\nstruct TEXTRANGEA {\n    CHARRANGE chrg;\n    LPSTR lpstrText;\n}\n\nstruct TEXTRANGEW {\n    CHARRANGE chrg;\n    LPWSTR lpstrText;\n}\n\nstruct REQRESIZE {\n    NMHDR nmhdr;\n    RECT rc;\n}\n\nstruct REPASTESPECIAL {\nalign(4):\n    DWORD dwAspect;\n    DWORD_PTR dwParam;\n}\n\nstruct PUNCTUATION {\nalign(4):\n    UINT iSize;\n    LPSTR szPunctuation;\n}\n\nstruct GETTEXTEX {\nalign(4):\n    DWORD cb;\n    DWORD flags;\n    UINT codepage;\n    LPCSTR lpDefaultChar;\n    LPBOOL lpUsedDefChar;\n}\n\nextern (Windows) {\nalias LONG function(char*,LONG,BYTE,INT) EDITWORDBREAKPROCEX;\n}\n\n/* Defines for EM_SETTYPOGRAPHYOPTIONS */\nenum TO_ADVANCEDTYPOGRAPHY = 1;\nenum TO_SIMPLELINEBREAK    = 2;\n\n/* Defines for GETTEXTLENGTHEX */\nenum GTL_DEFAULT  = 0;\nenum GTL_USECRLF  = 1;\nenum GTL_PRECISE  = 2;\nenum GTL_CLOSE    = 4;\nenum GTL_NUMCHARS = 8;\nenum GTL_NUMBYTES = 16;\n\nstruct GETTEXTLENGTHEX {\nalign(4):\n    DWORD flags;\n    UINT codepage;\n}\n\nversion (Unicode) {\n    alias CHARFORMATW CHARFORMAT;\n    alias CHARFORMAT2W CHARFORMAT2;\n    alias FINDTEXTW FINDTEXT;\n    alias FINDTEXTEXW FINDTEXTEX;\n    alias TEXTRANGEW TEXTRANGE;\n} else {\n    alias CHARFORMATA CHARFORMAT;\n    alias CHARFORMAT2A CHARFORMAT2;\n    alias FINDTEXTA FINDTEXT;\n    alias FINDTEXTEXA FINDTEXTEX;\n    alias TEXTRANGEA TEXTRANGE;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/richole.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_richole.d)\n */\nmodule core.sys.windows.richole;\nversion (Windows):\n\nprivate import core.sys.windows.objfwd, core.sys.windows.objidl, core.sys.windows.ole2, core.sys.windows.unknwn,\n  core.sys.windows.windef;\nprivate import core.sys.windows.richedit; // for CHARRANGE\n\n//align(4):\n\nenum ULONG\n    REO_GETOBJ_NO_INTERFACES = 0,\n    REO_GETOBJ_POLEOBJ = 1,\n    REO_GETOBJ_PSTG = 2,\n    REO_GETOBJ_POLESITE = 4,\n    REO_GETOBJ_ALL_INTERFACES = 7,\n    REO_CP_SELECTION = -1,\n    REO_IOB_SELECTION = -1,\n    REO_IOB_USE_CP = -2,\n    REO_NULL = 0,\n    REO_READWRITEMASK = 0x3F,\n    REO_DONTNEEDPALETTE = 32,\n    REO_BLANK = 16,\n    REO_DYNAMICSIZE = 8,\n    REO_INVERTEDSELECT = 4,\n    REO_BELOWBASELINE = 2,\n    REO_RESIZABLE = 1,\n    REO_LINK = 0x80000000,\n    REO_STATIC = 0x40000000,\n    REO_SELECTED = 0x08000000,\n    REO_OPEN = 0x4000000,\n    REO_INPLACEACTIVE = 0x2000000,\n    REO_HILITED = 0x1000000,\n    REO_LINKAVAILABLE = 0x800000,\n    REO_GETMETAFILE = 0x400000;\n\nenum {\n    RECO_PASTE = 0,\n    RECO_DROP,\n    RECO_COPY,\n    RECO_CUT,\n    RECO_DRAG // = 4\n}\n\nextern (C) extern const GUID\n    IID_IRichEditOle,\n    IID_IRichEditOleCallback;\n\nstruct REOBJECT {\n    DWORD           cbStruct = REOBJECT.sizeof;\n    LONG            cp;\n    CLSID           clsid;\n    LPOLEOBJECT     poleobj;\n    LPSTORAGE       pstg;\n    LPOLECLIENTSITE polesite;\n    SIZEL           sizel;\n    DWORD           dvaspect;\n    DWORD           dwFlags;\n    DWORD           dwUser;\n}\n\ninterface IRichEditOle : IUnknown {\n    HRESULT GetClientSite(LPOLECLIENTSITE*);\n    LONG GetObjectCount();\n    LONG GetLinkCount();\n    HRESULT GetObject(LONG, REOBJECT*, DWORD);\n    HRESULT InsertObject(REOBJECT*);\n    HRESULT ConvertObject(LONG, REFCLSID, LPCSTR);\n    HRESULT ActivateAs(REFCLSID, REFCLSID);\n    HRESULT SetHostNames(LPCSTR, LPCSTR);\n    HRESULT SetLinkAvailable(LONG, BOOL);\n    HRESULT SetDvaspect(LONG, DWORD);\n    HRESULT HandsOffStorage(LONG);\n    HRESULT SaveCompleted(LONG, LPSTORAGE);\n    HRESULT InPlaceDeactivate();\n    HRESULT ContextSensitiveHelp(BOOL);\n    HRESULT GetClipboardData(CHARRANGE*, DWORD, LPDATAOBJECT*);\n    HRESULT ImportDataObject(LPDATAOBJECT, CLIPFORMAT, HGLOBAL);\n};\nalias IRichEditOle LPRICHEDITOLE;\n\ninterface IRichEditOleCallback : IUnknown {\n    HRESULT GetNewStorage(LPSTORAGE*);\n    HRESULT GetInPlaceContext(LPOLEINPLACEFRAME*, LPOLEINPLACEUIWINDOW*, LPOLEINPLACEFRAMEINFO);\n    HRESULT ShowContainerUI(BOOL);\n    HRESULT QueryInsertObject(LPCLSID, LPSTORAGE, LONG);\n    HRESULT DeleteObject(LPOLEOBJECT);\n    HRESULT QueryAcceptData(LPDATAOBJECT, CLIPFORMAT*, DWORD, BOOL, HGLOBAL);\n    HRESULT ContextSensitiveHelp(BOOL);\n    HRESULT GetClipboardData(CHARRANGE*, DWORD, LPDATAOBJECT*);\n    HRESULT GetDragDropEffect(BOOL, DWORD, PDWORD);\n    HRESULT GetContextMenu(WORD, LPOLEOBJECT, CHARRANGE*, HMENU*);\n};\nalias IRichEditOleCallback LPRICHEDITOLECALLBACK;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/rpc.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_rpc.d)\n */\nmodule core.sys.windows.rpc;\nversion (Windows):\n\n/* Moved to rpcdecp (duplicate definition).\n    typedef void *I_RPC_HANDLE;\n    alias long RPC_STATUS;\n    // Moved to rpcdce:\n    RpcImpersonateClient\n    RpcRevertToSelf\n*/\n\npublic import core.sys.windows.unknwn;\npublic import core.sys.windows.rpcdce;  // also pulls in rpcdcep\npublic import core.sys.windows.rpcnsi;\npublic import core.sys.windows.rpcnterr;\npublic import core.sys.windows.winerror;\n\nalias MIDL_user_allocate midl_user_allocate;\nalias MIDL_user_free midl_user_free;\n\nextern (Windows) {\n    int I_RpcMapWin32Status(RPC_STATUS);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/rpcdce.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_rpcdce.d)\n */\nmodule core.sys.windows.rpcdce;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"Rpcrt4\");\n\n// TODO: I think MinGW got this wrong. RPC_UNICODE_SUPPORTED should be\n// replaced aliases for version (Unicode)\n\npublic import core.sys.windows.rpcdcep;\nprivate import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.windef;\n\n// FIXME: clean up Windows version support\n\nalias UUID uuid_t;\nalias UUID_VECTOR uuid_vector_t;\nalias void RPC_MGR_EPV;\n\n// for RpcMgmtSetComTimeout()\nenum : uint {\n    RPC_C_BINDING_MIN_TIMEOUT      = 0,\n    RPC_C_BINDING_DEFAULT_TIMEOUT  = 5,\n    RPC_C_BINDING_MAX_TIMEOUT      = 9,\n    RPC_C_BINDING_INFINITE_TIMEOUT = 10\n}\n\nenum RPC_C_CANCEL_INFINITE_TIMEOUT= -1;\nenum RPC_C_LISTEN_MAX_CALLS_DEFAULT=1234;\nenum RPC_C_PROTSEQ_MAX_REQS_DEFAULT=10;\nenum RPC_C_BIND_TO_ALL_NICS=1;\nenum RPC_C_USE_INTERNET_PORT=1;\nenum RPC_C_USE_INTRANET_PORT=2;\n\n// for RPC_STATS_VECTOR, used by RpcMgmyInqStats\nenum : uint {\n    RPC_C_STATS_CALLS_IN  = 0,\n    RPC_C_STATS_CALLS_OUT,\n    RPC_C_STATS_PKTS_IN,\n    RPC_C_STATS_PKTS_OUT\n}\n\nenum RPC_IF_AUTOLISTEN=0x0001;\nenum RPC_IF_OLE=2;\nenum RPC_C_MGMT_INQ_IF_IDS=0;\nenum RPC_C_MGMT_INQ_PRINC_NAME=1;\nenum RPC_C_MGMT_INQ_STATS=2;\nenum RPC_C_MGMT_IS_SERVER_LISTEN=3;\nenum RPC_C_MGMT_STOP_SERVER_LISTEN=4;\n\n// Inquiry Type for RpcMgmtEpEltInqBegin()\nenum : uint {\n    RPC_C_EP_ALL_ELTS = 0,\n    RPC_C_EP_MATCH_BY_IF,\n    RPC_C_EP_MATCH_BY_OBJ,\n    RPC_C_EP_MATCH_BY_BOTH\n}\n\n// for RpcMgmtEpEltInqNext()\nenum : uint {\n    RPC_C_VERS_ALL = 1,\n    RPC_C_VERS_COMPATIBLE,\n    RPC_C_VERS_EXACT,\n    RPC_C_VERS_MAJOR_ONLY,\n    RPC_C_VERS_UPTO\n}\n\nenum DCE_C_ERROR_STRING_LEN=256;\nenum RPC_C_PARM_MAX_PACKET_LENGTH=1;\nenum RPC_C_PARM_BUFFER_LENGTH=2;\nenum RPC_C_AUTHN_LEVEL_DEFAULT=0;\nenum RPC_C_AUTHN_LEVEL_NONE=1;\nenum RPC_C_AUTHN_LEVEL_CONNECT=2;\nenum RPC_C_AUTHN_LEVEL_CALL=3;\nenum RPC_C_AUTHN_LEVEL_PKT=4;\nenum RPC_C_AUTHN_LEVEL_PKT_INTEGRITY=5;\nenum RPC_C_AUTHN_LEVEL_PKT_PRIVACY=6;\nenum RPC_C_IMP_LEVEL_ANONYMOUS=1;\nenum RPC_C_IMP_LEVEL_IDENTIFY=2;\nenum RPC_C_IMP_LEVEL_IMPERSONATE=3;\nenum RPC_C_IMP_LEVEL_DELEGATE=4;\nenum RPC_C_QOS_IDENTITY_STATIC=0;\nenum RPC_C_QOS_IDENTITY_DYNAMIC=1;\nenum RPC_C_QOS_CAPABILITIES_DEFAULT=0;\nenum RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH=1;\n\n// These enums were buggy in MinGW !\nenum RPC_C_PROTECT_LEVEL_DEFAULT = RPC_C_AUTHN_LEVEL_DEFAULT;\nenum RPC_C_PROTECT_LEVEL_NONE = RPC_C_AUTHN_LEVEL_NONE;\nenum RPC_C_PROTECT_LEVEL_CONNECT = RPC_C_AUTHN_LEVEL_CONNECT;\nenum RPC_C_PROTECT_LEVEL_CALL = RPC_C_AUTHN_LEVEL_CALL;\nenum RPC_C_PROTECT_LEVEL_PKT = RPC_C_AUTHN_LEVEL_PKT;\nenum RPC_C_PROTECT_LEVEL_PKT_INTEGRITY = RPC_C_AUTHN_LEVEL_PKT_INTEGRITY;\nenum RPC_C_PROTECT_LEVEL_PKT_PRIVACY = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;\n\nenum RPC_C_AUTHN_NONE=0;\nenum RPC_C_AUTHN_DCE_PRIVATE=1;\nenum RPC_C_AUTHN_DCE_PUBLIC=2;\nenum RPC_C_AUTHN_DEC_PUBLIC=4;\nenum RPC_C_AUTHN_WINNT=10;\nenum RPC_C_AUTHN_DEFAULT=0xFFFFFFFF;\n//const RPC_C_SECURITY_QOS_VERSION=L; // FIXME(MinGW): This is nonsense!\nenum SEC_WINNT_AUTH_IDENTITY_ANSI=0x1;\nenum SEC_WINNT_AUTH_IDENTITY_UNICODE=0x2;\nenum RPC_C_AUTHZ_NONE=0;\nenum RPC_C_AUTHZ_NAME=1;\nenum RPC_C_AUTHZ_DCE=2;\nenum RPC_C_AUTHZ_DEFAULT=0xFFFFFFFF;\n\nalias I_RPC_HANDLE RPC_BINDING_HANDLE;\nalias RPC_BINDING_HANDLE handle_t;\n\nstruct RPC_BINDING_VECTOR {\n    uint Count;\n    RPC_BINDING_HANDLE[1] BindingH;\n}\n\nalias RPC_BINDING_HANDLE rpc_binding_handle_t;\nalias RPC_BINDING_VECTOR rpc_binding_vector_t;\n\n\nstruct UUID_VECTOR {\n    uint Count;\n    UUID*[1] Uuid;\n}\n\nalias void* RPC_IF_HANDLE;\n\nstruct RPC_IF_ID {\n    UUID Uuid;\n    ushort VersMajor;\n    ushort VersMinor;\n}\n\nstruct RPC_POLICY {\n    uint Length;\n    uint EndpointFlags;\n    uint NICFlags;\n}\nalias RPC_POLICY* PRPC_POLICY;\n\nextern (Windows) {\n    alias void function(UUID*, UUID*, RPC_STATUS*) RPC_OBJECT_INQ_FN;\n    alias RPC_STATUS function(RPC_IF_HANDLE, void*) RPC_IF_CALLBACK_FN;\n}\n\nstruct RPC_STATS_VECTOR {\n    uint    Count;\n    uint[1] Stats;\n}\n\nstruct RPC_IF_ID_VECTOR {\n    uint          Count;\n    RPC_IF_ID*[1] IfId;\n}\nmixin DECLARE_HANDLE!(\"RPC_AUTH_IDENTITY_HANDLE\");\nmixin DECLARE_HANDLE!(\"RPC_AUTHZ_HANDLE\");\n\nstruct RPC_SECURITY_QOS {\n    uint Version;\n    uint Capabilities;\n    uint IdentityTracking;\n    uint ImpersonationType;\n}\nalias RPC_SECURITY_QOS* PRPC_SECURITY_QOS;\n\nstruct SEC_WINNT_AUTH_IDENTITY_W {\n    ushort* User;\n    uint UserLength;\n    ushort* Domain;\n    uint DomainLength;\n    ushort* Password;\n    uint PasswordLength;\n    uint Flags;\n}\nalias SEC_WINNT_AUTH_IDENTITY_W* PSEC_WINNT_AUTH_IDENTITY_W;\n\nstruct SEC_WINNT_AUTH_IDENTITY_A {\n    ubyte* User;\n    uint UserLength;\n    ubyte* Domain;\n    uint DomainLength;\n    ubyte* Password;\n    uint PasswordLength;\n    uint Flags;\n}\nalias SEC_WINNT_AUTH_IDENTITY_A* PSEC_WINNT_AUTH_IDENTITY_A;\n\nstruct RPC_CLIENT_INFORMATION1 {\n    ubyte* UserName;\n    ubyte* ComputerName;\n    ushort Privilege;\n    uint AuthFlags;\n}\nalias RPC_CLIENT_INFORMATION1* PRPC_CLIENT_INFORMATION1;\nalias I_RPC_HANDLE* RPC_EP_INQ_HANDLE;\nextern (Windows) {\n    alias int function(RPC_BINDING_HANDLE, uint, RPC_STATUS*) RPC_MGMT_AUTHORIZATION_FN;\n}\n\nstruct RPC_PROTSEQ_VECTORA {\n    uint Count;\n    ubyte*[1] Protseq;\n}\n\nstruct RPC_PROTSEQ_VECTORW {\n    uint Count;\n    ushort*[1] Protseq;\n}\n\nextern (Windows) {\n    RPC_STATUS RpcBindingFromStringBindingA(char*, RPC_BINDING_HANDLE*);\n    RPC_STATUS RpcBindingFromStringBindingW(wchar*, RPC_BINDING_HANDLE*);\n    RPC_STATUS RpcBindingToStringBindingA(RPC_BINDING_HANDLE, char**);\n    RPC_STATUS RpcBindingToStringBindingW(RPC_BINDING_HANDLE, wchar**);\n    RPC_STATUS RpcStringBindingComposeA(char*, char*, char*, char*, char*, char**);\n    RPC_STATUS RpcStringBindingComposeW(wchar*, wchar*, wchar*, wchar*, wchar*, wchar**);\n    RPC_STATUS RpcStringBindingParseA(char*, char**, char**, char**, char**, char**);\n    RPC_STATUS RpcStringBindingParseW(wchar*, wchar**, wchar**, wchar**, wchar**, wchar**);\n    RPC_STATUS RpcStringFreeA(char**);\n    RPC_STATUS RpcStringFreeW(wchar**);\n    RPC_STATUS RpcNetworkIsProtseqValidA(char*);\n    RPC_STATUS RpcNetworkIsProtseqValidW(wchar*);\n    RPC_STATUS RpcNetworkInqProtseqsA(RPC_PROTSEQ_VECTORA**);\n    RPC_STATUS RpcNetworkInqProtseqsW(RPC_PROTSEQ_VECTORW**);\n    RPC_STATUS RpcProtseqVectorFreeA(RPC_PROTSEQ_VECTORA**);\n    RPC_STATUS RpcProtseqVectorFreeW(RPC_PROTSEQ_VECTORW**);\n    RPC_STATUS RpcServerUseProtseqA(char*, uint, void*);\n    RPC_STATUS RpcServerUseProtseqW(wchar*, uint, void*);\n    RPC_STATUS RpcServerUseProtseqExA(char*, uint MaxCalls, void*, PRPC_POLICY);\n    RPC_STATUS RpcServerUseProtseqExW(wchar*, uint, void*, PRPC_POLICY);\n    RPC_STATUS RpcServerUseProtseqEpA(char*, uint, char*, void*);\n    RPC_STATUS RpcServerUseProtseqEpExA(char*, uint, char*, void*, PRPC_POLICY);\n    RPC_STATUS RpcServerUseProtseqEpW(wchar*, uint, wchar*, void*);\n    RPC_STATUS RpcServerUseProtseqEpExW(wchar*, uint, wchar*, void*, PRPC_POLICY);\n    RPC_STATUS RpcServerUseProtseqIfA(char*, uint, RPC_IF_HANDLE, void*);\n    RPC_STATUS RpcServerUseProtseqIfExA(char*, uint, RPC_IF_HANDLE, void*, PRPC_POLICY);\n    RPC_STATUS RpcServerUseProtseqIfW(wchar*, uint, RPC_IF_HANDLE, void*);\n    RPC_STATUS RpcServerUseProtseqIfExW(wchar*, uint, RPC_IF_HANDLE, void*, PRPC_POLICY);\n    RPC_STATUS RpcMgmtInqServerPrincNameA(RPC_BINDING_HANDLE, uint, char**);\n    RPC_STATUS RpcMgmtInqServerPrincNameW(RPC_BINDING_HANDLE, uint, wchar**);\n    RPC_STATUS RpcServerInqDefaultPrincNameA(uint, char**);\n    RPC_STATUS RpcServerInqDefaultPrincNameW(uint, wchar**);\n    RPC_STATUS RpcNsBindingInqEntryNameA(RPC_BINDING_HANDLE, uint, char**);\n    RPC_STATUS RpcNsBindingInqEntryNameW(RPC_BINDING_HANDLE, uint, wchar**);\n    RPC_STATUS RpcBindingInqAuthClientA(RPC_BINDING_HANDLE, RPC_AUTHZ_HANDLE*, char**, uint*, uint*, uint*);\n    RPC_STATUS RpcBindingInqAuthClientW(RPC_BINDING_HANDLE, RPC_AUTHZ_HANDLE*, wchar**, uint*, uint*, uint*);\n    RPC_STATUS RpcBindingInqAuthInfoA(RPC_BINDING_HANDLE, char**, uint*, uint*, RPC_AUTH_IDENTITY_HANDLE*, uint*);\n    RPC_STATUS RpcBindingInqAuthInfoW(RPC_BINDING_HANDLE, wchar**, uint*, uint*, RPC_AUTH_IDENTITY_HANDLE*, uint*);\n    RPC_STATUS RpcBindingSetAuthInfoA(RPC_BINDING_HANDLE, char*, uint, uint, RPC_AUTH_IDENTITY_HANDLE, uint);\n    RPC_STATUS RpcBindingSetAuthInfoExA(RPC_BINDING_HANDLE, char*, uint, uint, RPC_AUTH_IDENTITY_HANDLE, uint, RPC_SECURITY_QOS*);\n    RPC_STATUS RpcBindingSetAuthInfoW(RPC_BINDING_HANDLE, wchar*, uint, uint, RPC_AUTH_IDENTITY_HANDLE, uint);\n    RPC_STATUS RpcBindingSetAuthInfoExW(RPC_BINDING_HANDLE, wchar*, uint, uint, RPC_AUTH_IDENTITY_HANDLE, uint, RPC_SECURITY_QOS*);\n    RPC_STATUS RpcBindingInqAuthInfoExA(RPC_BINDING_HANDLE, char**, uint*, uint*, RPC_AUTH_IDENTITY_HANDLE*, uint*, uint, RPC_SECURITY_QOS*);\n    RPC_STATUS RpcBindingInqAuthInfoExW(RPC_BINDING_HANDLE, wchar**, uint*, uint*, RPC_AUTH_IDENTITY_HANDLE*, uint*, uint, RPC_SECURITY_QOS*);\n    alias void function(void*, wchar*, uint, void**, RPC_STATUS*) RPC_AUTH_KEY_RETRIEVAL_FN;\n    RPC_STATUS RpcServerRegisterAuthInfoA(char*, uint, RPC_AUTH_KEY_RETRIEVAL_FN, void*);\n    RPC_STATUS RpcServerRegisterAuthInfoW(wchar*, uint, RPC_AUTH_KEY_RETRIEVAL_FN, void*);\n    RPC_STATUS UuidToStringA(UUID*, char**);\n    RPC_STATUS UuidFromStringA(char*, UUID*);\n    RPC_STATUS UuidToStringW(UUID*, wchar**);\n    RPC_STATUS UuidFromStringW(wchar*, UUID*);\n    RPC_STATUS RpcEpRegisterNoReplaceA(RPC_IF_HANDLE, RPC_BINDING_VECTOR*, UUID_VECTOR*, char*);\n    RPC_STATUS RpcEpRegisterNoReplaceW(RPC_IF_HANDLE, RPC_BINDING_VECTOR*, UUID_VECTOR*, wchar*);\n    RPC_STATUS RpcEpRegisterA(RPC_IF_HANDLE, RPC_BINDING_VECTOR*, UUID_VECTOR*, char*);\n    RPC_STATUS RpcEpRegisterW(RPC_IF_HANDLE, RPC_BINDING_VECTOR*, UUID_VECTOR*, wchar*);\n    RPC_STATUS DceErrorInqTextA(RPC_STATUS, char*);\n    RPC_STATUS DceErrorInqTextW(RPC_STATUS, wchar*);\n    RPC_STATUS RpcMgmtEpEltInqNextA(RPC_EP_INQ_HANDLE, RPC_IF_ID*, RPC_BINDING_HANDLE*, UUID*, char**);\n    RPC_STATUS RpcMgmtEpEltInqNextW(RPC_EP_INQ_HANDLE, RPC_IF_ID*, RPC_BINDING_HANDLE*, UUID*, wchar**);\n\n    // MinGW erroneously had these in rpc.h\n    RPC_STATUS RpcImpersonateClient(RPC_BINDING_HANDLE);\n    RPC_STATUS RpcRevertToSelf();\n}\n\nversion (Unicode) {\n    alias RPC_PROTSEQ_VECTORW RPC_PROTSEQ_VECTOR;\n    alias SEC_WINNT_AUTH_IDENTITY_W SEC_WINNT_AUTH_IDENTITY;\n    alias PSEC_WINNT_AUTH_IDENTITY_W PSEC_WINNT_AUTH_IDENTITY;\n    alias RpcMgmtEpEltInqNextW RpcMgmtEpEltInqNext;\n    alias RpcBindingFromStringBindingW RpcBindingFromStringBinding;\n    alias RpcBindingToStringBindingW RpcBindingToStringBinding;\n    alias RpcStringBindingComposeW RpcStringBindingCompose;\n    alias RpcStringBindingParseW RpcStringBindingParse;\n    alias RpcStringFreeW RpcStringFree;\n    alias RpcNetworkIsProtseqValidW RpcNetworkIsProtseqValid;\n    alias RpcNetworkInqProtseqsW RpcNetworkInqProtseqs;\n    alias RpcProtseqVectorFreeW RpcProtseqVectorFree;\n    alias RpcServerUseProtseqW RpcServerUseProtseq;\n    alias RpcServerUseProtseqExW RpcServerUseProtseqEx;\n    alias RpcServerUseProtseqEpW RpcServerUseProtseqEp;\n    alias RpcServerUseProtseqEpExW RpcServerUseProtseqEpEx;\n    alias RpcServerUseProtseqIfW RpcServerUseProtseqIf;\n    alias RpcServerUseProtseqIfExW RpcServerUseProtseqIfEx;\n    alias RpcMgmtInqServerPrincNameW RpcMgmtInqServerPrincName;\n    alias RpcServerInqDefaultPrincNameW RpcServerInqDefaultPrincName;\n    alias RpcNsBindingInqEntryNameW RpcNsBindingInqEntryName;\n    alias RpcBindingInqAuthClientW RpcBindingInqAuthClient;\n    alias RpcBindingInqAuthInfoW RpcBindingInqAuthInfo;\n    alias RpcBindingSetAuthInfoW RpcBindingSetAuthInfo;\n    alias RpcServerRegisterAuthInfoW RpcServerRegisterAuthInfo;\n    alias RpcBindingInqAuthInfoExW RpcBindingInqAuthInfoEx;\n    alias RpcBindingSetAuthInfoExW RpcBindingSetAuthInfoEx;\n    alias UuidFromStringW UuidFromString;\n    alias UuidToStringW UuidToString;\n    alias RpcEpRegisterNoReplaceW RpcEpRegisterNoReplace;\n    alias RpcEpRegisterW RpcEpRegister;\n    alias DceErrorInqTextW DceErrorInqText;\n} else { // Ansi\n    alias RPC_PROTSEQ_VECTORA RPC_PROTSEQ_VECTOR;\n    alias SEC_WINNT_AUTH_IDENTITY_A SEC_WINNT_AUTH_IDENTITY;\n    alias PSEC_WINNT_AUTH_IDENTITY_A PSEC_WINNT_AUTH_IDENTITY;\n    alias RpcMgmtEpEltInqNextA RpcMgmtEpEltInqNext;\n    alias RpcBindingFromStringBindingA RpcBindingFromStringBinding;\n    alias RpcBindingToStringBindingA RpcBindingToStringBinding;\n    alias RpcStringBindingComposeA RpcStringBindingCompose;\n    alias RpcStringBindingParseA RpcStringBindingParse;\n    alias RpcStringFreeA RpcStringFree;\n    alias RpcNetworkIsProtseqValidA RpcNetworkIsProtseqValid;\n    alias RpcNetworkInqProtseqsA RpcNetworkInqProtseqs;\n    alias RpcProtseqVectorFreeA RpcProtseqVectorFree;\n    alias RpcServerUseProtseqA RpcServerUseProtseq;\n    alias RpcServerUseProtseqExA RpcServerUseProtseqEx;\n    alias RpcServerUseProtseqEpA RpcServerUseProtseqEp;\n    alias RpcServerUseProtseqEpExA RpcServerUseProtseqEpEx;\n    alias RpcServerUseProtseqIfA RpcServerUseProtseqIf;\n    alias RpcServerUseProtseqIfExA RpcServerUseProtseqIfEx;\n    alias RpcMgmtInqServerPrincNameA RpcMgmtInqServerPrincName;\n    alias RpcServerInqDefaultPrincNameA RpcServerInqDefaultPrincName;\n    alias RpcNsBindingInqEntryNameA RpcNsBindingInqEntryName;\n    alias RpcBindingInqAuthClientA RpcBindingInqAuthClient;\n    alias RpcBindingInqAuthInfoA RpcBindingInqAuthInfo;\n    alias RpcBindingSetAuthInfoA RpcBindingSetAuthInfo;\n    alias RpcServerRegisterAuthInfoA RpcServerRegisterAuthInfo;\n    alias RpcBindingInqAuthInfoExA RpcBindingInqAuthInfoEx;\n    alias RpcBindingSetAuthInfoExA RpcBindingSetAuthInfoEx;\n    alias UuidFromStringA UuidFromString;\n    alias UuidToStringA UuidToString;\n    alias RpcEpRegisterNoReplaceA RpcEpRegisterNoReplace;\n    alias RpcEpRegisterA RpcEpRegister;\n    alias DceErrorInqTextA DceErrorInqText;\n} //#endif // UNICODE\n\nextern (Windows) {\n    RPC_STATUS RpcBindingCopy(RPC_BINDING_HANDLE, RPC_BINDING_HANDLE*);\n    RPC_STATUS RpcBindingFree(RPC_BINDING_HANDLE*);\n    RPC_STATUS RpcBindingInqObject(RPC_BINDING_HANDLE, UUID*);\n    RPC_STATUS RpcBindingReset(RPC_BINDING_HANDLE);\n    RPC_STATUS RpcBindingSetObject(RPC_BINDING_HANDLE, UUID*);\n    RPC_STATUS RpcMgmtInqDefaultProtectLevel(uint, uint*);\n    RPC_STATUS RpcBindingVectorFree(RPC_BINDING_VECTOR**);\n    RPC_STATUS RpcIfInqId(RPC_IF_HANDLE, RPC_IF_ID*);\n    RPC_STATUS RpcMgmtInqComTimeout(RPC_BINDING_HANDLE, uint*);\n    RPC_STATUS RpcMgmtSetComTimeout(RPC_BINDING_HANDLE, uint);\n    RPC_STATUS RpcMgmtSetCancelTimeout(int Timeout);\n    RPC_STATUS RpcObjectInqType(UUID*, UUID*);\n    RPC_STATUS RpcObjectSetInqFn(RPC_OBJECT_INQ_FN*);\n    RPC_STATUS RpcObjectSetType(UUID*, UUID*);\n    RPC_STATUS RpcProtseqVectorFree(RPC_PROTSEQ_VECTOR**);\n    RPC_STATUS RpcServerInqIf(RPC_IF_HANDLE, UUID*, RPC_MGR_EPV**);\n    RPC_STATUS RpcServerListen(uint, uint, uint);\n    RPC_STATUS RpcServerRegisterIf(RPC_IF_HANDLE, UUID*, RPC_MGR_EPV*);\n    RPC_STATUS RpcServerRegisterIfEx(RPC_IF_HANDLE, UUID*, RPC_MGR_EPV*, uint, uint, RPC_IF_CALLBACK_FN*);\n    RPC_STATUS RpcServerRegisterIf2(RPC_IF_HANDLE, UUID*, RPC_MGR_EPV*, uint, uint, uint, RPC_IF_CALLBACK_FN*);\n    RPC_STATUS RpcServerUnregisterIf(RPC_IF_HANDLE, UUID*, uint);\n    RPC_STATUS RpcServerUseAllProtseqs(uint, void*);\n    RPC_STATUS RpcServerUseAllProtseqsEx(uint, void*, PRPC_POLICY);\n    RPC_STATUS RpcServerUseAllProtseqsIf(uint, RPC_IF_HANDLE, void*);\n    RPC_STATUS RpcServerUseAllProtseqsIfEx(uint, RPC_IF_HANDLE, void*, PRPC_POLICY);\n    RPC_STATUS RpcMgmtStatsVectorFree(RPC_STATS_VECTOR**);\n    RPC_STATUS RpcMgmtInqStats(RPC_BINDING_HANDLE, RPC_STATS_VECTOR**);\n    RPC_STATUS RpcMgmtIsServerListening(RPC_BINDING_HANDLE);\n    RPC_STATUS RpcMgmtStopServerListening(RPC_BINDING_HANDLE);\n    RPC_STATUS RpcMgmtWaitServerListen();\n    RPC_STATUS RpcMgmtSetServerStackSize(uint);\n    void RpcSsDontSerializeContext();\n    RPC_STATUS RpcMgmtEnableIdleCleanup();\n    RPC_STATUS RpcMgmtInqIfIds(RPC_BINDING_HANDLE, RPC_IF_ID_VECTOR**);\n    RPC_STATUS RpcIfIdVectorFree(RPC_IF_ID_VECTOR**);\n    RPC_STATUS RpcEpResolveBinding(RPC_BINDING_HANDLE, RPC_IF_HANDLE);\n    RPC_STATUS RpcBindingServerFromClient(RPC_BINDING_HANDLE, RPC_BINDING_HANDLE*);\n\n    // never returns\n    void RpcRaiseException(RPC_STATUS);\n    RPC_STATUS RpcTestCancel();\n    RPC_STATUS RpcCancelThread(void*);\n    RPC_STATUS UuidCreate(UUID*);\n    int UuidCompare(UUID*, UUID*, RPC_STATUS*);\n    RPC_STATUS UuidCreateNil(UUID*);\n    int UuidEqual(UUID*, UUID*, RPC_STATUS*);\n    ushort UuidHash(UUID*, RPC_STATUS*);\n    int UuidIsNil(UUID*, RPC_STATUS*);\n    RPC_STATUS RpcEpUnregister(RPC_IF_HANDLE, RPC_BINDING_VECTOR*, UUID_VECTOR*);\n    RPC_STATUS RpcMgmtEpEltInqBegin(RPC_BINDING_HANDLE, uint, RPC_IF_ID*, uint, UUID*, RPC_EP_INQ_HANDLE*);\n    RPC_STATUS RpcMgmtEpEltInqDone(RPC_EP_INQ_HANDLE*);\n    RPC_STATUS RpcMgmtEpUnregister(RPC_BINDING_HANDLE, RPC_IF_ID*, RPC_BINDING_HANDLE, UUID*);\n    RPC_STATUS RpcMgmtSetAuthorizationFn(RPC_MGMT_AUTHORIZATION_FN);\n    RPC_STATUS RpcMgmtInqParameter(uint, uint*);\n    RPC_STATUS RpcMgmtSetParameter(uint, uint);\n    RPC_STATUS RpcMgmtBindingInqParameter(RPC_BINDING_HANDLE, uint, uint*);\n    RPC_STATUS RpcMgmtBindingSetParameter(RPC_BINDING_HANDLE, uint, uint);\n\n//static if (_WIN32_WINNT >= 0x500) {\n    RPC_STATUS UuidCreateSequential(UUID*);\n//}\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/rpcdce2.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_rpcdce2.d)\n */\nmodule core.sys.windows.rpcdce2;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nimport core.sys.windows.rpcdce;\nprivate import core.sys.windows.basetyps;\n\n// FIXME: deal with RPC_UNICODE_SUPPORTED\n// FIXME: check types of constants\n\nenum {\n    RPC_C_EP_ALL_ELTS,\n    RPC_C_EP_MATCH_BY_IF,\n    RPC_C_EP_MATCH_BY_OBJ,\n    RPC_C_EP_MATCH_BY_BOTH\n}\n\nenum {\n    RPC_C_VERS_ALL = 1,\n    RPC_C_VERS_COMPATIBLE,\n    RPC_C_VERS_EXACT,\n    RPC_C_VERS_MAJOR_ONLY,\n    RPC_C_VERS_UPTO\n}\n\nenum size_t DCE_C_ERROR_STRING_LEN = 256;\n\nenum {\n    RPC_C_MGMT_INQ_IF_IDS,\n    RPC_C_MGMT_INQ_PRINC_NAME,\n    RPC_C_MGMT_INQ_STATS,\n    RPC_C_MGMT_IS_SERVER_LISTEN,\n    RPC_C_MGMT_STOP_SERVER_LISTEN\n}\n\nextern (Windows) {\n    int UuidCompare(UUID*, UUID*, RPC_STATUS*);\n    RPC_STATUS UuidCreateNil(UUID*);\n    int UuidEqual(UUID*, UUID*, RPC_STATUS*);\n    ushort UuidHash(UUID*, RPC_STATUS*);\n    int UuidIsNil(UUID*, RPC_STATUS*);\n\n    RPC_STATUS RpcMgmtEpEltInqBegin(RPC_BINDING_HANDLE, uint, RPC_IF_ID*,\n      uint, UUID*, RPC_EP_INQ_HANDLE*);\n    RPC_STATUS RpcMgmtEpEltInqDone(RPC_EP_INQ_HANDLE*);\n    RPC_STATUS RpcMgmtEpUnregister(RPC_BINDING_HANDLE, RPC_IF_ID*,\n      RPC_BINDING_HANDLE, UUID*);\n    RPC_STATUS RpcMgmtSetAuthorizationFn(RPC_MGMT_AUTHORIZATION_FN);\n}\n\n\n//#ifdef RPC_UNICODE_SUPPORTED\nextern (Windows) {\n    RPC_STATUS DceErrorInqTextA(RPC_STATUS, char*);\n    RPC_STATUS DceErrorInqTextW(RPC_STATUS, wchar*);\n    RPC_STATUS RpcMgmtEpEltInqNextA(RPC_EP_INQ_HANDLE, RPC_IF_ID*,\n      RPC_BINDING_HANDLE*, UUID*, char**);\n    RPC_STATUS RpcMgmtEpEltInqNextW(RPC_EP_INQ_HANDLE, RPC_IF_ID*,\n      RPC_BINDING_HANDLE*, UUID*, wchar**);\n}\n\nversion (Unicode) {\n    alias RpcMgmtEpEltInqNextW RpcMgmtEpEltInqNext;\n    alias DceErrorInqTextW DceErrorInqText;\n} else {\n    alias RpcMgmtEpEltInqNextA RpcMgmtEpEltInqNext;\n    alias DceErrorInqTextA DceErrorInqText;\n}\n/+\n#else /* RPC_UNICODE_SUPPORTED */\n    RPC_STATUS RPC_ENTRY DceErrorInqText(RPC_STATUS,unsigned char*);\n    RPC_STATUS RPC_ENTRY RpcMgmtEpEltInqNext(RPC_EP_INQ_HANDLE,RPC_IF_ID*,RPC_BINDING_HANDLE*,UUID*,unsigned char**);\n#endif\n+/\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/rpcdcep.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_rpcdcep.d)\n */\nmodule core.sys.windows.rpcdcep;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.basetyps;\nprivate import core.sys.windows.w32api;\nprivate import core.sys.windows.windef;\n\nmixin DECLARE_HANDLE!(\"I_RPC_HANDLE\");\nalias long RPC_STATUS;\n\nenum RPC_NCA_FLAGS_DEFAULT=0;\nenum RPC_NCA_FLAGS_IDEMPOTENT=1;\nenum RPC_NCA_FLAGS_BROADCAST=2;\nenum RPC_NCA_FLAGS_MAYBE=4;\nenum RPCFLG_ASYNCHRONOUS=0x40000000;\nenum RPCFLG_INPUT_SYNCHRONOUS=0x20000000;\nenum RPC_FLAGS_VALID_BIT=0x8000;\n\nenum TRANSPORT_TYPE_CN=1;\nenum TRANSPORT_TYPE_DG=2;\nenum TRANSPORT_TYPE_LPC=4;\nenum TRANSPORT_TYPE_WMSG=8;\n\nstruct RPC_VERSION {\n    ushort MajorVersion;\n    ushort MinorVersion;\n}\nstruct RPC_SYNTAX_IDENTIFIER {\n    GUID        SyntaxGUID;\n    RPC_VERSION SyntaxVersion;\n}\nalias RPC_SYNTAX_IDENTIFIER* PRPC_SYNTAX_IDENTIFIER;\n\nstruct RPC_MESSAGE {\n    HANDLE Handle;\n    uint  DataRepresentation;\n    void* Buffer;\n    uint  BufferLength;\n    uint  ProcNum;\n    PRPC_SYNTAX_IDENTIFIER TransferSyntax;\n    void* RpcInterfaceInformation;\n    void* ReservedForRuntime;\n    void* ManagerEpv;\n    void* ImportContext;\n    uint  RpcFlags;\n}\nalias RPC_MESSAGE* PRPC_MESSAGE;\n\nextern (Windows) {\nalias void function (PRPC_MESSAGE Message) RPC_DISPATCH_FUNCTION;\n}\n\nstruct RPC_DISPATCH_TABLE {\n    uint DispatchTableCount;\n    RPC_DISPATCH_FUNCTION* DispatchTable;\n    LONG_PTR Reserved;\n}\nalias RPC_DISPATCH_TABLE* PRPC_DISPATCH_TABLE;\n\nstruct RPC_PROTSEQ_ENDPOINT {\n    ubyte* RpcProtocolSequence;\n    ubyte* Endpoint;\n}\nalias RPC_PROTSEQ_ENDPOINT* PRPC_PROTSEQ_ENDPOINT;\n\nstruct RPC_SERVER_INTERFACE {\n    uint                  Length;\n    RPC_SYNTAX_IDENTIFIER InterfaceId;\n    RPC_SYNTAX_IDENTIFIER TransferSyntax;\n    PRPC_DISPATCH_TABLE   DispatchTable;\n    uint                  RpcProtseqEndpointCount;\n    PRPC_PROTSEQ_ENDPOINT RpcProtseqEndpoint;\n    void*                 DefaultManagerEpv;\nconst(void)*          InterpreterInfo;\n}\nalias RPC_SERVER_INTERFACE* PRPC_SERVER_INTERFACE;\n\nstruct RPC_CLIENT_INTERFACE {\n    uint                  Length;\n    RPC_SYNTAX_IDENTIFIER InterfaceId;\n    RPC_SYNTAX_IDENTIFIER TransferSyntax;\n    PRPC_DISPATCH_TABLE   DispatchTable;\n    uint                  RpcProtseqEndpointCount;\n    PRPC_PROTSEQ_ENDPOINT RpcProtseqEndpoint;\n    ULONG_PTR             Reserved;\nconst(void)*          InterpreterInfo;\n}\nalias RPC_CLIENT_INTERFACE* PRPC_CLIENT_INTERFACE;\n\nalias TypeDef!(void*) I_RPC_MUTEX;\n\nstruct RPC_TRANSFER_SYNTAX {\n    GUID   Uuid;\n    ushort VersMajor;\n    ushort VersMinor;\n}\nalias RPC_STATUS function(void*, void*, void*) RPC_BLOCKING_FN;\n\nextern (Windows) {\n    alias void function(void*) PRPC_RUNDOWN;\n\n    int    I_RpcGetBuffer(RPC_MESSAGE*);\n    int    I_RpcSendReceive(RPC_MESSAGE*);\n    int    I_RpcSend(RPC_MESSAGE*);\n    int    I_RpcFreeBuffer(RPC_MESSAGE*);\n    void   I_RpcRequestMutex(I_RPC_MUTEX*);\n    void   I_RpcClearMutex(I_RPC_MUTEX);\n    void   I_RpcDeleteMutex(I_RPC_MUTEX);\n    void*  I_RpcAllocate(uint);\n    void   I_RpcFree(void*);\n    void   I_RpcPauseExecution(uint);\n    int    I_RpcMonitorAssociation(HANDLE, PRPC_RUNDOWN, void*);\n    int    I_RpcStopMonitorAssociation(HANDLE);\n    HANDLE I_RpcGetCurrentCallHandle();\n    int    I_RpcGetAssociationContext(void**);\n    int    I_RpcSetAssociationContext(void*);\n    int    I_RpcNsBindingSetEntryName(HANDLE, uint, wchar*);\n    int    I_RpcBindingInqDynamicEndpoint(HANDLE, wchar**);\n    int    I_RpcBindingInqTransportType(HANDLE, uint*);\n    int    I_RpcIfInqTransferSyntaxes(HANDLE, RPC_TRANSFER_SYNTAX*, uint,\n             uint*);\n    int    I_UuidCreate(GUID*);\n    int    I_RpcBindingCopy(HANDLE, HANDLE*);\n    int    I_RpcBindingIsClientLocal(HANDLE, uint*);\n    void   I_RpcSsDontSerializeContext();\n    int    I_RpcServerRegisterForwardFunction(int function (GUID*,\n             RPC_VERSION*, GUID*, ubyte*, void**));\n    int    I_RpcConnectionInqSockBuffSize(uint*, uint*);\n    int    I_RpcConnectionSetSockBuffSize(uint, uint);\n    int    I_RpcBindingSetAsync(HANDLE, RPC_BLOCKING_FN);\n    int    I_RpcAsyncSendReceive(RPC_MESSAGE*, void*);\n    int    I_RpcGetThreadWindowHandle(void**);\n    int    I_RpcServerThreadPauseListening();\n    int    I_RpcServerThreadContinueListening();\n    int    I_RpcServerUnregisterEndpointA(ubyte*, ubyte*);\n    int    I_RpcServerUnregisterEndpointW(ushort*, ushort*);\n}\n\nversion (Unicode) {\n    alias I_RpcServerUnregisterEndpointW I_RpcServerUnregisterEndpoint;\n} else {\n    alias I_RpcServerUnregisterEndpointA I_RpcServerUnregisterEndpoint;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/rpcndr.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_rpcndr.d)\n */\nmodule core.sys.windows.rpcndr;\nversion (Windows):\npragma(lib, \"rpcrt4\");\n\n/* Translation notes:\n RPC_CLIENT_ALLOC*, RPC_CLIENT_FREE* were replaced with PRPC_CLIENT_ALLOC, PRPC_CLIENT_FREE\n*/\n\n// TODO: Bitfields in MIDL_STUB_MESSAGE.\n//       Macros need to be converted.\nenum __RPCNDR_H_VERSION__= 450;\n\nimport core.sys.windows.rpcnsip;\nprivate import core.sys.windows.rpc, core.sys.windows.rpcdce, core.sys.windows.unknwn, core.sys.windows.windef;\nprivate import core.sys.windows.objidl; // for IRpcChannelBuffer, IRpcStubBuffer\nprivate import core.sys.windows.basetyps;\n\nextern (Windows):\n\nenum uint NDR_CHAR_REP_MASK      = 0xF,\n    NDR_INT_REP_MASK              = 0xF0,\n    NDR_FLOAT_REP_MASK            = 0xFF00,\n    NDR_LITTLE_ENDIAN             = 0x10,\n    NDR_BIG_ENDIAN                = 0,\n    NDR_IEEE_FLOAT                = 0,\n    NDR_VAX_FLOAT                 = 0x100,\n    NDR_ASCII_CHAR                = 0,\n    NDR_EBCDIC_CHAR               = 1,\n    NDR_LOCAL_DATA_REPRESENTATION = 0x10,\n    NDR_LOCAL_ENDIAN              = NDR_LITTLE_ENDIAN;\n\nalias MIDL_user_allocate midl_user_allocate;\nalias MIDL_user_free midl_user_free;\n\nalias long hyper;\nalias ulong MIDL_uhyper;\nalias char small;\n\nenum cbNDRContext=20;\n//MACRO #define NDRSContextValue(hContext) (&(hContext)->userContext)\n//MACRO #define byte_from_ndr(source, target) { *(target) = *(*(char**)&(source)->Buffer)++; }\n\n//MACRO #define byte_array_from_ndr(Source, LowerIndex, UpperIndex, Target) { NDRcopy ((((char *)(Target))+(LowerIndex)), (Source)->Buffer, (unsigned int)((UpperIndex)-(LowerIndex))); *(unsigned long *)&(Source)->Buffer += ((UpperIndex)-(LowerIndex)); }\n\n//MACRO #define boolean_from_ndr(source, target) { *(target) = *(*(char**)&(source)->Buffer)++; }\n\n//MACRO #define boolean_array_from_ndr(Source, LowerIndex, UpperIndex, Target) { NDRcopy ((((char *)(Target))+(LowerIndex)), (Source)->Buffer, (unsigned int)((UpperIndex)-(LowerIndex))); *(unsigned long *)&(Source)->Buffer += ((UpperIndex)-(LowerIndex)); }\n\n//MACRO #define small_from_ndr(source, target) { *(target) = *(*(char**)&(source)->Buffer)++; }\n\n//MACRO #define small_from_ndr_temp(source, target, format) { *(target) = *(*(char**)(source))++; }\n\n//MACRO #define small_array_from_ndr(Source, LowerIndex, UpperIndex, Target) { NDRcopy ((((char *)(Target))+(LowerIndex)), (Source)->Buffer, (unsigned int)((UpperIndex)-(LowerIndex))); *(unsigned long *)&(Source)->Buffer += ((UpperIndex)-(LowerIndex)); }\n\n//MACRO #define MIDL_ascii_strlen(string) strlen(string)\n\n//MACRO #define MIDL_ascii_strcpy(target,source) strcpy(target,source)\n\n//MACRO #define MIDL_memset(s,c,n) memset(s,c,n)\n\n//MACRO #define _midl_ma1( p, cast ) *(*( cast **)&p)++\n//MACRO #define _midl_ma2( p, cast ) *(*( cast **)&p)++\n//MACRO #define _midl_ma4( p, cast ) *(*( cast **)&p)++\n//MACRO #define _midl_ma8( p, cast ) *(*( cast **)&p)++\n//MACRO #define _midl_unma1( p, cast ) *(( cast *)p)++\n//MACRO #define _midl_unma2( p, cast ) *(( cast *)p)++\n//MACRO #define _midl_unma3( p, cast ) *(( cast *)p)++\n//MACRO #define _midl_unma4( p, cast ) *(( cast *)p)++\n//MACRO #define _midl_fa2( p ) (p = (RPC_BUFPTR )((LONG_PTR)(p+1) & 0xffffffff_fffffffe))\n//MACRO #define _midl_fa4( p ) (p = (RPC_BUFPTR )((LONG_PTR)(p+3) & 0xffffffff_fffffffc))\n//MACRO #define _midl_fa8( p ) (p = (RPC_BUFPTR )((LONG_PTR)(p+7) & 0xffffffff_fffffff8))\n//MACRO #define _midl_addp( p, n ) (p += n)\n//MACRO #define _midl_marsh_lhs( p, cast ) *(*( cast **)&p)++\n//MACRO #define _midl_marsh_up( mp, p ) *(*(unsigned long **)&mp)++ = (unsigned long)p\n//MACRO #define _midl_advmp( mp ) *(*(unsigned long **)&mp)++\n//MACRO #define _midl_unmarsh_up( p ) (*(*(unsigned long **)&p)++)\n\n//MACRO #define NdrMarshConfStringHdr( p, s, l ) (_midl_ma4( p, unsigned long) = s, _midl_ma4( p, unsigned long) = 0, _midl_ma4( p, unsigned long) = l)\n\n//MACRO #define NdrUnMarshConfStringHdr(p, s, l) ((s=_midl_unma4(p,unsigned long), (_midl_addp(p,4)), (l=_midl_unma4(p,unsigned long))\n\n//MACRO #define NdrMarshCCtxtHdl(pc,p) (NDRCContextMarshall( (NDR_CCONTEXT)pc, p ),p+20)\n//MACRO #define NdrUnMarshCCtxtHdl(pc,p,h,drep) (NDRCContextUnmarshall((NDR_CONTEXT)pc,h,p,drep), p+20)\n//MACRO #define NdrUnMarshSCtxtHdl(pc, p,drep) (pc = NdrSContextUnMarshall(p,drep ))\n//MACRO #define NdrMarshSCtxtHdl(pc,p,rd) (NdrSContextMarshall((NDR_SCONTEXT)pc,p, (NDR_RUNDOWN)rd)\n\n//MACRO #define NdrFieldOffset(s,f) (LONG_PTR)(& (((s *)0)->f))\n//MACRO #define NdrFieldPad(s,f,p,t) (NdrFieldOffset(s,f) - NdrFieldOffset(s,p) - sizeof(t))\n//MACRO #define NdrFcShort(s) (unsigned char)(s & 0xff), (unsigned char)(s >> 8)\n//MACRO #define NdrFcLong(s) (unsigned char)(s & 0xff), (unsigned char)((s & 0x0000ff00) >> 8), (unsigned char)((s & 0x00ff0000) >> 16), (unsigned char)(s >> 24)\n\nalias void * NDR_CCONTEXT;\nstruct tagNDR_SCONTEXT {\n    void*[2] pad;\n    void *userContext;\n}\nalias tagNDR_SCONTEXT * NDR_SCONTEXT;\n\nstruct SCONTEXT_QUEUE {\n    uint NumberOfObjects;\n    NDR_SCONTEXT *ArrayOfObjects;\n}\nalias SCONTEXT_QUEUE * PSCONTEXT_QUEUE;\n\nstruct _MIDL_STUB_MESSAGE;\nstruct _MIDL_STUB_DESC;\nstruct _FULL_PTR_XLAT_TABLES;\n\nalias ubyte *RPC_BUFPTR;\nalias uint RPC_LENGTH;\n\nalias const(char)* PFORMAT_STRING;\n\nstruct ARRAY_INFO {\n    int Dimension;\n    uint *BufferConformanceMark;\n    uint *BufferVarianceMark;\n    uint *MaxCountArray;\n    uint *OffsetArray;\n    uint *ActualCountArray;\n}\nalias ARRAY_INFO * PARRAY_INFO;\n\nRPC_BINDING_HANDLE  NDRCContextBinding(NDR_CCONTEXT);\nvoid  NDRCContextMarshall(NDR_CCONTEXT,void*);\nvoid  NDRCContextUnmarshall(NDR_CCONTEXT*,RPC_BINDING_HANDLE,void*,uint);\nvoid  NDRSContextMarshall(NDR_SCONTEXT,void*,NDR_RUNDOWN);\nNDR_SCONTEXT  NDRSContextUnmarshall(void*pBuff,uint);\nvoid  RpcSsDestroyClientContext(void**);\nvoid  NDRcopy(void*,void*,uint);\nuint  MIDL_wchar_strlen(wchar *);\nvoid  MIDL_wchar_strcpy(void*,wchar *);\nvoid  char_from_ndr(PRPC_MESSAGE,ubyte*);\nvoid  char_array_from_ndr(PRPC_MESSAGE,uint,uint,ubyte*);\nvoid  short_from_ndr(PRPC_MESSAGE,ushort*);\nvoid  short_array_from_ndr(PRPC_MESSAGE,uint,uint,ushort*);\nvoid  short_from_ndr_temp(ubyte**,ushort*,uint);\nvoid  int_from_ndr(PRPC_MESSAGE,uint*);\nvoid  int_array_from_ndr(PRPC_MESSAGE,uint,uint,uint*);\nvoid  int_from_ndr_temp(ubyte**,uint*,uint);\nvoid  enum_from_ndr(PRPC_MESSAGE,uint*);\nvoid  float_from_ndr(PRPC_MESSAGE,void*);\nvoid  float_array_from_ndr(PRPC_MESSAGE,uint,uint,void*);\nvoid  double_from_ndr(PRPC_MESSAGE,void*);\nvoid  double_array_from_ndr(PRPC_MESSAGE,uint,uint,void*);\nvoid  hyper_from_ndr(PRPC_MESSAGE,hyper*);\nvoid  hyper_array_from_ndr(PRPC_MESSAGE,uint,uint,hyper*);\nvoid  hyper_from_ndr_temp(ubyte**,hyper*,uint);\nvoid  data_from_ndr(PRPC_MESSAGE,void*,char*,ubyte);\nvoid  data_into_ndr(void*,PRPC_MESSAGE,char*,ubyte);\nvoid  tree_into_ndr(void*,PRPC_MESSAGE,char*,ubyte);\nvoid  data_size_ndr(void*,PRPC_MESSAGE,char*,ubyte);\nvoid  tree_size_ndr(void*,PRPC_MESSAGE,char*,ubyte);\nvoid  tree_peek_ndr(PRPC_MESSAGE,ubyte**,char*,ubyte);\nvoid * midl_allocate(int);\n\nalign(4):\nstruct MIDL_STUB_MESSAGE {\n    PRPC_MESSAGE RpcMsg;\n    ubyte *Buffer;\n    ubyte *BufferStart;\n    ubyte *BufferEnd;\n    ubyte *BufferMark;\n    uint BufferLength;\n    uint MemorySize;\n    ubyte *Memory;\n    int IsClient;\n    int ReuseBuffer;\n    ubyte *AllocAllNodesMemory;\n    ubyte *AllocAllNodesMemoryEnd;\n    int IgnoreEmbeddedPointers;\n    ubyte *PointerBufferMark;\n    ubyte fBufferValid;\n    ubyte Unused;\n    ULONG_PTR MaxCount;\n    uint Offset;\n    uint ActualCount;\n    void* function (uint) pfnAllocate;\n    void function (void*) pfnFree;\n    ubyte * StackTop;\n    ubyte * pPresentedType;\n    ubyte * pTransmitType;\n    handle_t SavedHandle;\nconst(_MIDL_STUB_DESC)* StubDesc;\n    _FULL_PTR_XLAT_TABLES *FullPtrXlatTables;\n    uint FullPtrRefId;\n    int fCheckBounds;\n    // FIXME:\n    byte bit_fields_for_D; // FIXME: Bitfields\n//  int fInDontFree :1;\n//  int fDontCallFreeInst :1;\n//  int fInOnlyParam :1;\n//  int fHasReturn :1;\n    uint dwDestContext;\n    void* pvDestContext;\n    NDR_SCONTEXT * SavedContextHandles;\n    int ParamNumber;\n    IRpcChannelBuffer  pRpcChannelBuffer;\n    PARRAY_INFO pArrayInfo;\n    uint * SizePtrCountArray;\n    uint * SizePtrOffsetArray;\n    uint * SizePtrLengthArray;\n    void* pArgQueue;\n    uint dwStubPhase;\n    INT_PTR[5] w2kReserved;\n}\nalias MIDL_STUB_MESSAGE * PMIDL_STUB_MESSAGE;\n\nextern (Windows) {\n    alias void* function (void*) GENERIC_BINDING_ROUTINE;\n    alias void function (void*,ubyte*) GENERIC_UNBIND_ROUTINE;\n    alias uint function (uint *,uint,void *) USER_MARSHAL_SIZING_ROUTINE;\n    alias ubyte * function (uint *,ubyte *,void *) USER_MARSHAL_MARSHALLING_ROUTINE;\n    alias ubyte * function (uint *,ubyte *,void *) USER_MARSHAL_UNMARSHALLING_ROUTINE;\n    alias void function (uint *,void *) USER_MARSHAL_FREEING_ROUTINE;\n    alias void function () NDR_NOTIFY_ROUTINE;\n}\n\nalign:\nstruct GENERIC_BINDING_ROUTINE_PAIR {\n    GENERIC_BINDING_ROUTINE pfnBind;\n    GENERIC_UNBIND_ROUTINE pfnUnbind;\n}\nalias GENERIC_BINDING_ROUTINE_PAIR * PGENERIC_BINDING_ROUTINE_PAIR;\n\nstruct GENERIC_BINDING_INFO {\n    void *pObj;\n    uint Size;\n    GENERIC_BINDING_ROUTINE pfnBind;\n    GENERIC_UNBIND_ROUTINE pfnUnbind;\n}\nalias GENERIC_BINDING_INFO * PGENERIC_BINDING_INFO;\n\n\nstruct XMIT_ROUTINE_QUINTUPLE {\n    XMIT_HELPER_ROUTINE pfnTranslateToXmit;\n    XMIT_HELPER_ROUTINE pfnTranslateFromXmit;\n    XMIT_HELPER_ROUTINE pfnFreeXmit;\n    XMIT_HELPER_ROUTINE pfnFreeInst;\n}\nalias XMIT_ROUTINE_QUINTUPLE * PXMIT_ROUTINE_QUINTUPLE;\n\nstruct MALLOC_FREE_STRUCT {\n    void* function (uint) pfnAllocate;\n    void function (void*) pfnFree;\n}\n\nstruct COMM_FAULT_OFFSETS {\n    short CommOffset;\n    short FaultOffset;\n}\n\nstruct USER_MARSHAL_ROUTINE_QUADRUPLE {\n    USER_MARSHAL_SIZING_ROUTINE pfnBufferSize;\n    USER_MARSHAL_MARSHALLING_ROUTINE pfnMarshall;\n    USER_MARSHAL_UNMARSHALLING_ROUTINE pfnUnmarshall;\n    USER_MARSHAL_FREEING_ROUTINE pfnFree;\n}\n\nenum IDL_CS_CONVERT {\n    IDL_CS_NO_CONVERT,\n    IDL_CS_IN_PLACE_CONVERT,\n    IDL_CS_NEW_BUFFER_CONVERT\n}\n\nstruct NDR_CS_SIZE_CONVERT_ROUTINES {\n    CS_TYPE_NET_SIZE_ROUTINE pfnNetSize;\n    CS_TYPE_TO_NETCS_ROUTINE pfnToNetCs;\n    CS_TYPE_LOCAL_SIZE_ROUTINE pfnLocalSize;\n    CS_TYPE_FROM_NETCS_ROUTINE pfnFromNetCs;\n}\n\nstruct NDR_CS_ROUTINES {\n    NDR_CS_SIZE_CONVERT_ROUTINES *pSizeConvertRoutines;\n    CS_TAG_GETTING_ROUTINE *pTagGettingRoutines;\n}\n\nstruct MIDL_STUB_DESC {\n    void* RpcInterfaceInformation;\n    void* function(uint) pfnAllocate;\n    void function (void*) pfnFree;\n    union _IMPLICIT_HANDLE_INFO {\n        handle_t *pAutoHandle;\n        handle_t *pPrimitiveHandle;\n        PGENERIC_BINDING_INFO pGenericBindingInfo;\n    }\n    _IMPLICIT_HANDLE_INFO IMPLICIT_HANDLE_INFO;\nconst(NDR_RUNDOWN)* apfnNdrRundownRoutines;\nconst(GENERIC_BINDING_ROUTINE_PAIR)* aGenericBindingRoutinePairs;\nconst(EXPR_EVAL)* apfnExprEval;\nconst(XMIT_ROUTINE_QUINTUPLE)* aXmitQuintuple;\nconst(char)* *pFormatTypes;\n    int fCheckBounds;\n    uint Version;\n    MALLOC_FREE_STRUCT *pMallocFreeStruct;\n    int MIDLVersion;\nconst(COMM_FAULT_OFFSETS)* CommFaultOffsets;\nconst(USER_MARSHAL_ROUTINE_QUADRUPLE)* aUserMarshalQuadruple;\nconst(NDR_NOTIFY_ROUTINE)* NotifyRoutineTable;\n    ULONG_PTR mFlags;\nconst(NDR_CS_ROUTINES)* CsRoutineTables;\n    void *Reserved4;\n    ULONG_PTR Reserved5;\n}\nalias const(MIDL_STUB_DESC)* PMIDL_STUB_DESC;\n\nalias void * PMIDL_XMIT_TYPE;\n\nstruct MIDL_FORMAT_STRING {\n    short Pad;\n    ubyte[1] Format;\n}\n\nstruct MIDL_SERVER_INFO {\n    PMIDL_STUB_DESC pStubDesc;\nconst(SERVER_ROUTINE)* DispatchTable;\n    PFORMAT_STRING ProcString;\nconst(ushort)* FmtStringOffset;\nconst(STUB_THUNK)* ThunkTable;\n}\nalias MIDL_SERVER_INFO * PMIDL_SERVER_INFO;\n\nstruct MIDL_STUBLESS_PROXY_INFO {\n    PMIDL_STUB_DESC pStubDesc;\n    PFORMAT_STRING ProcFormatString;\nconst(ushort)* FormatStringOffset;\n}\nalias MIDL_STUBLESS_PROXY_INFO *PMIDL_STUBLESS_PROXY_INFO;\n\nunion CLIENT_CALL_RETURN {\n    void *Pointer;\n    LONG_PTR Simple;\n}\n\nenum XLAT_SIDE {\n    XLAT_SERVER = 1,\n    XLAT_CLIENT\n}\nstruct FULL_PTR_TO_REFID_ELEMENT {\n    FULL_PTR_TO_REFID_ELEMENT * Next;\n    void* Pointer;\n    uint RefId;\n    ubyte State;\n}\nalias FULL_PTR_TO_REFID_ELEMENT * PFULL_PTR_TO_REFID_ELEMENT;\n\nstruct FULL_PTR_XLAT_TABLES {\n    struct _RefIdToPointer {\n        void **XlatTable;\n        ubyte *StateTable;\n        uint NumberOfEntries;\n    }\n    void* RefIdToPointer;\n    struct _PointerToRefId {\n        PFULL_PTR_TO_REFID_ELEMENT *XlatTable;\n        uint NumberOfBuckets;\n        uint HashMask;\n    }\n    void* PointerToRefId;\n\n    uint NextRefId;\n    XLAT_SIDE XlatSide;\n}\nalias FULL_PTR_XLAT_TABLES * PFULL_PTR_XLAT_TABLES;\n\n\nenum STUB_PHASE {\n    STUB_UNMARSHAL,\n    STUB_CALL_SERVER,\n    STUB_MARSHAL,\n    STUB_CALL_SERVER_NO_HRESULT\n}\n\nenum PROXY_PHASE {\n    PROXY_CALCSIZE,\n    PROXY_GETBUFFER,\n    PROXY_MARSHAL,\n    PROXY_SENDRECEIVE,\n    PROXY_UNMARSHAL\n}\n\nalias TypeDef!(void *) RPC_SS_THREAD_HANDLE;\n\nextern (Windows) {\nalias void function (void*) NDR_RUNDOWN;\nalias void function (_MIDL_STUB_MESSAGE*) EXPR_EVAL;\nalias void function(PMIDL_STUB_MESSAGE) XMIT_HELPER_ROUTINE;\nalias void function (RPC_BINDING_HANDLE,uint,uint,IDL_CS_CONVERT*,uint*,error_status_t*) CS_TYPE_NET_SIZE_ROUTINE;\nalias void function (RPC_BINDING_HANDLE,uint,uint,IDL_CS_CONVERT*,uint*,error_status_t*) CS_TYPE_LOCAL_SIZE_ROUTINE;\nalias void function (RPC_BINDING_HANDLE,uint,void*,uint,byte*,uint*,error_status_t*) CS_TYPE_TO_NETCS_ROUTINE;\nalias void function (RPC_BINDING_HANDLE,uint,byte*,uint,uint,void*,uint*,error_status_t*) CS_TYPE_FROM_NETCS_ROUTINE;\nalias void function (RPC_BINDING_HANDLE,int,uint*,uint*,uint*,error_status_t*) CS_TAG_GETTING_ROUTINE;\n\n//alias void* RPC_CLIENT_ALLOC(uint);\n//alias void RPC_CLIENT_FREE(void*);\nalias void* function(uint) PRPC_CLIENT_ALLOC;\nalias void function(void*) PRPC_CLIENT_FREE;\n\n    alias void function (PMIDL_STUB_MESSAGE) STUB_THUNK;\n    alias int function() SERVER_ROUTINE;\n}\n\nvoid  NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE,ubyte*,ubyte);\nubyte * NdrPointerMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING pFormat);\nubyte * NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrConformantStructMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrHardStructMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrComplexStructMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrConformantVaryingArrayMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrConformantStringMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte * NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrClientContextMarshall(PMIDL_STUB_MESSAGE,NDR_CCONTEXT,int);\nvoid  NdrServerContextMarshall(PMIDL_STUB_MESSAGE,NDR_SCONTEXT,NDR_RUNDOWN);\nvoid  NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE,ubyte*,ubyte);\nubyte * NdrPointerUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrHardStructUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrConformantVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrConformantStringUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nubyte * NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nvoid  NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE,NDR_CCONTEXT*,RPC_BINDING_HANDLE);\nNDR_SCONTEXT  NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE);\nvoid  NdrPointerBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrHardStructBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrContextHandleSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nuint  NdrPointerMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrHardStructMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrConformantVaryingArrayMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrConformantStringMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nuint  NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nvoid  NdrPointerFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrSimpleStructFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrConformantStructFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrHardStructFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrComplexStructFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrFixedArrayFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrConformantArrayFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrConformantVaryingArrayFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrVaryingArrayFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrComplexArrayFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrByteCountPointerFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrInterfacePointerFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nvoid  NdrConvert(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nvoid  NdrClientInitializeNew(PRPC_MESSAGE,PMIDL_STUB_MESSAGE,PMIDL_STUB_DESC,uint);\nubyte * NdrServerInitializeNew(PRPC_MESSAGE,PMIDL_STUB_MESSAGE,PMIDL_STUB_DESC);\nvoid  NdrClientInitialize(PRPC_MESSAGE,PMIDL_STUB_MESSAGE,PMIDL_STUB_DESC,uint);\nubyte * NdrServerInitialize(PRPC_MESSAGE,PMIDL_STUB_MESSAGE,PMIDL_STUB_DESC);\nubyte * NdrServerInitializeUnmarshall(PMIDL_STUB_MESSAGE,PMIDL_STUB_DESC,PRPC_MESSAGE);\nvoid  NdrServerInitializeMarshall(PRPC_MESSAGE,PMIDL_STUB_MESSAGE);\nubyte * NdrGetBuffer(PMIDL_STUB_MESSAGE,uint,RPC_BINDING_HANDLE);\nubyte * NdrNsGetBuffer(PMIDL_STUB_MESSAGE,uint,RPC_BINDING_HANDLE);\nubyte * NdrSendReceive(PMIDL_STUB_MESSAGE,ubyte*);\nubyte * NdrNsSendReceive(PMIDL_STUB_MESSAGE,ubyte*,RPC_BINDING_HANDLE*);\nvoid  NdrFreeBuffer(PMIDL_STUB_MESSAGE);\n\nCLIENT_CALL_RETURN  NdrClientCall(PMIDL_STUB_DESC,PFORMAT_STRING,...);\n\nint  NdrStubCall(IRpcStubBuffer, IRpcChannelBuffer,PRPC_MESSAGE,uint*);\nvoid  NdrServerCall(PRPC_MESSAGE);\nint  NdrServerUnmarshall(IRpcChannelBuffer, PRPC_MESSAGE,PMIDL_STUB_MESSAGE,PMIDL_STUB_DESC,PFORMAT_STRING,void*);\nvoid  NdrServerMarshall(IRpcStubBuffer, IRpcChannelBuffer,PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nRPC_STATUS  NdrMapCommAndFaultStatus(PMIDL_STUB_MESSAGE,uint*,uint*,RPC_STATUS);\nint  NdrSH_UPDecision(PMIDL_STUB_MESSAGE,ubyte**,RPC_BUFPTR);\nint  NdrSH_TLUPDecision(PMIDL_STUB_MESSAGE,ubyte**);\nint  NdrSH_TLUPDecisionBuffer(PMIDL_STUB_MESSAGE,ubyte**);\nint  NdrSH_IfAlloc(PMIDL_STUB_MESSAGE,ubyte**,uint);\nint  NdrSH_IfAllocRef(PMIDL_STUB_MESSAGE,ubyte**,uint);\nint  NdrSH_IfAllocSet(PMIDL_STUB_MESSAGE,ubyte**,uint);\nRPC_BUFPTR  NdrSH_IfCopy(PMIDL_STUB_MESSAGE,ubyte**,uint);\nRPC_BUFPTR  NdrSH_IfAllocCopy(PMIDL_STUB_MESSAGE,ubyte**,uint);\nuint  NdrSH_Copy(ubyte*,ubyte*,uint);\nvoid  NdrSH_IfFree(PMIDL_STUB_MESSAGE,ubyte*);\nRPC_BUFPTR  NdrSH_StringMarshall(PMIDL_STUB_MESSAGE,ubyte*,uint,int);\nRPC_BUFPTR  NdrSH_StringUnMarshall(PMIDL_STUB_MESSAGE,ubyte**,int);\nvoid* RpcSsAllocate(uint);\nvoid  RpcSsDisableAllocate();\nvoid  RpcSsEnableAllocate();\nvoid  RpcSsFree(void*);\nRPC_SS_THREAD_HANDLE  RpcSsGetThreadHandle();\nvoid  RpcSsSetClientAllocFree(PRPC_CLIENT_ALLOC,PRPC_CLIENT_FREE);\nvoid  RpcSsSetThreadHandle(RPC_SS_THREAD_HANDLE);\nvoid  RpcSsSwapClientAllocFree(PRPC_CLIENT_ALLOC,PRPC_CLIENT_FREE,PRPC_CLIENT_ALLOC*,PRPC_CLIENT_FREE*);\nvoid* RpcSmAllocate(uint,RPC_STATUS*);\nRPC_STATUS  RpcSmClientFree(void*);\nRPC_STATUS  RpcSmDestroyClientContext(void**);\nRPC_STATUS  RpcSmDisableAllocate();\nRPC_STATUS  RpcSmEnableAllocate();\nRPC_STATUS  RpcSmFree(void*);\nRPC_SS_THREAD_HANDLE  RpcSmGetThreadHandle(RPC_STATUS*);\nRPC_STATUS  RpcSmSetClientAllocFree(PRPC_CLIENT_ALLOC,PRPC_CLIENT_FREE);\nRPC_STATUS  RpcSmSetThreadHandle(RPC_SS_THREAD_HANDLE);\nRPC_STATUS  RpcSmSwapClientAllocFree(PRPC_CLIENT_ALLOC,PRPC_CLIENT_FREE,PRPC_CLIENT_ALLOC*,PRPC_CLIENT_FREE*);\nvoid  NdrRpcSsEnableAllocate(PMIDL_STUB_MESSAGE);\nvoid  NdrRpcSsDisableAllocate(PMIDL_STUB_MESSAGE);\nvoid  NdrRpcSmSetClientToOsf(PMIDL_STUB_MESSAGE);\nvoid* NdrRpcSmClientAllocate(uint);\nvoid  NdrRpcSmClientFree(void*);\nvoid* NdrRpcSsDefaultAllocate(uint);\nvoid  NdrRpcSsDefaultFree(void*);\nPFULL_PTR_XLAT_TABLES  NdrFullPointerXlatInit(uint,XLAT_SIDE);\nvoid  NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES);\nint  NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES,void*,ubyte,uint*);\nint  NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES,uint,ubyte,void**);\nvoid  NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES,uint,void*);\nint  NdrFullPointerFree(PFULL_PTR_XLAT_TABLES,void*);\nvoid* NdrAllocate(PMIDL_STUB_MESSAGE,uint);\nvoid  NdrClearOutParameters(PMIDL_STUB_MESSAGE,PFORMAT_STRING,void*);\nvoid* NdrOleAllocate(uint);\nvoid  NdrOleFree(void*);\nubyte* NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nubyte* NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE,ubyte**,PFORMAT_STRING,ubyte);\nvoid  NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\nuint  NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE,PFORMAT_STRING);\nvoid  NdrUserMarshalFree(PMIDL_STUB_MESSAGE,ubyte*,PFORMAT_STRING);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/rpcnsi.d",
    "content": "/**\n * Windows API header module\n *\n * RPC Name Service (RpcNs APIs)\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_rpcnsi.d)\n */\nmodule core.sys.windows.rpcnsi;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"rpcns4\");\n\nprivate import core.sys.windows.basetyps, core.sys.windows.rpcdcep, core.sys.windows.rpcnsi, core.sys.windows.rpcdce,\n  core.sys.windows.w32api;\nprivate import core.sys.windows.windef;  // for HANDLE\n\nmixin DECLARE_HANDLE!(\"RPC_NS_HANDLE\");\n\nenum RPC_C_NS_SYNTAX_DEFAULT=0;\nenum RPC_C_NS_SYNTAX_DCE=3;\nenum RPC_C_PROFILE_DEFAULT_ELT=0;\nenum RPC_C_PROFILE_ALL_ELT=1;\nenum RPC_C_PROFILE_MATCH_BY_IF=2;\nenum RPC_C_PROFILE_MATCH_BY_MBR=3;\nenum RPC_C_PROFILE_MATCH_BY_BOTH=4;\nenum RPC_C_NS_DEFAULT_EXP_AGE=-1;\n\nextern (Windows) {\n    RPC_STATUS RpcNsBindingExportA(uint, ubyte*, RPC_IF_HANDLE,\n      RPC_BINDING_VECTOR*, UUID_VECTOR*);\n    RPC_STATUS RpcNsBindingUnexportA(uint, ubyte*, RPC_IF_HANDLE,\n      UUID_VECTOR*);\n    RPC_STATUS RpcNsBindingLookupBeginA(uint, ubyte*, RPC_IF_HANDLE, UUID*,\n      uint, RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsBindingLookupNext(RPC_NS_HANDLE, RPC_BINDING_VECTOR**);\n    RPC_STATUS RpcNsBindingLookupDone(RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsGroupDeleteA(uint, ubyte*);\n    RPC_STATUS RpcNsGroupMbrAddA(uint, ubyte*, uint, ubyte*);\n    RPC_STATUS RpcNsGroupMbrRemoveA(uint, ubyte*, uint, ubyte*);\n    RPC_STATUS RpcNsGroupMbrInqBeginA(uint, ubyte*, uint, RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsGroupMbrInqNextA(RPC_NS_HANDLE, ubyte**);\n    RPC_STATUS RpcNsGroupMbrInqDone(RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsProfileDeleteA(uint, ubyte*);\n    RPC_STATUS RpcNsProfileEltAddA(uint, ubyte*, RPC_IF_ID*, uint, ubyte*,\n      uint, ubyte*);\n    RPC_STATUS RpcNsProfileEltRemoveA(uint, ubyte*, RPC_IF_ID*, uint, ubyte*);\n    RPC_STATUS RpcNsProfileEltInqBeginA(uint, ubyte*, uint, RPC_IF_ID*, uint,\n      uint, ubyte*, RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsProfileEltInqNextA(RPC_NS_HANDLE, RPC_IF_ID*, ubyte**,\n      uint*, ubyte**);\n    RPC_STATUS RpcNsProfileEltInqDone(RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsEntryObjectInqNext(RPC_NS_HANDLE, UUID*);\n    RPC_STATUS RpcNsEntryObjectInqDone(RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsEntryExpandNameA(uint, ubyte*, ubyte**);\n    RPC_STATUS RpcNsMgmtBindingUnexportA(uint, ubyte*, RPC_IF_ID*, uint,\n      UUID_VECTOR*);\n    RPC_STATUS RpcNsMgmtEntryCreateA(uint, ubyte*);\n    RPC_STATUS RpcNsMgmtEntryDeleteA(uint, ubyte*);\n    RPC_STATUS RpcNsMgmtEntryInqIfIdsA(uint, ubyte*, RPC_IF_ID_VECTOR**);\n    RPC_STATUS RpcNsMgmtHandleSetExpAge(RPC_NS_HANDLE, uint);\n    RPC_STATUS RpcNsMgmtInqExpAge(uint*);\n    RPC_STATUS RpcNsMgmtSetExpAge(uint);\n    RPC_STATUS RpcNsBindingImportNext(RPC_NS_HANDLE, RPC_BINDING_HANDLE*);\n    RPC_STATUS RpcNsBindingImportDone(RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsBindingSelect(RPC_BINDING_VECTOR*, RPC_BINDING_HANDLE*);\n\nversion (Unicode) {\n} else {\n    RPC_STATUS RpcNsEntryObjectInqBeginA(uint, ubyte*, RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsBindingImportBeginA(uint, ubyte*, RPC_IF_HANDLE, UUID*,\n      RPC_NS_HANDLE*);\n}\n\n    RPC_STATUS RpcNsBindingExportW(uint, ushort*, RPC_IF_HANDLE,\n      RPC_BINDING_VECTOR*, UUID_VECTOR*);\n    RPC_STATUS RpcNsBindingUnexportW(uint, ushort*, RPC_IF_HANDLE,\n      UUID_VECTOR*);\n    RPC_STATUS RpcNsBindingLookupBeginW(uint, ushort*, RPC_IF_HANDLE, UUID*,\n      uint, RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsGroupDeleteW(uint, ushort*);\n    RPC_STATUS RpcNsGroupMbrAddW(uint, ushort*, uint, ushort*);\n    RPC_STATUS RpcNsGroupMbrRemoveW(uint, ushort*, uint, ushort*);\n    RPC_STATUS RpcNsGroupMbrInqBeginW(uint, ushort*, uint, RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsGroupMbrInqNextW(RPC_NS_HANDLE, ushort**);\n    RPC_STATUS RpcNsProfileDeleteW(uint, ushort*);\n    RPC_STATUS RpcNsProfileEltAddW(uint, ushort*, RPC_IF_ID*, uint, ushort*,\n      uint, ushort*);\n    RPC_STATUS RpcNsProfileEltRemoveW(uint, ushort*, RPC_IF_ID*, uint,\n      ushort*);\n    RPC_STATUS RpcNsProfileEltInqBeginW(uint, ushort*, uint, RPC_IF_ID*,\n      uint, uint, ushort*, RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsProfileEltInqNextW(RPC_NS_HANDLE, RPC_IF_ID*, ushort**,\n      uint*, ushort**);\n    RPC_STATUS RpcNsEntryObjectInqBeginW(uint, ushort*, RPC_NS_HANDLE*);\n    RPC_STATUS RpcNsEntryExpandNameW(uint, ushort*, ushort**);\n    RPC_STATUS RpcNsMgmtBindingUnexportW(uint, ushort*, RPC_IF_ID*, uint,\n      UUID_VECTOR*);\n    RPC_STATUS RpcNsMgmtEntryCreateW(uint, ushort*);\n    RPC_STATUS RpcNsMgmtEntryDeleteW(uint, ushort*);\n    RPC_STATUS RpcNsMgmtEntryInqIfIdsW(uint, ushort , RPC_IF_ID_VECTOR**);\n    RPC_STATUS RpcNsBindingImportBeginW(uint, ushort*, RPC_IF_HANDLE, UUID*,\n      RPC_NS_HANDLE*);\n}\n\nversion (Unicode) {\n    alias RpcNsBindingLookupBeginW RpcNsBindingLookupBegin;\n    alias RpcNsBindingImportBeginW RpcNsBindingImportBegin;\n    alias RpcNsBindingExportW RpcNsBindingExport;\n    alias RpcNsBindingUnexportW RpcNsBindingUnexport;\n    alias RpcNsGroupDeleteW RpcNsGroupDelete;\n    alias RpcNsGroupMbrAddW RpcNsGroupMbrAdd;\n    alias RpcNsGroupMbrRemoveW RpcNsGroupMbrRemove;\n    alias RpcNsGroupMbrInqBeginW RpcNsGroupMbrInqBegin;\n    alias RpcNsGroupMbrInqNextW RpcNsGroupMbrInqNext;\n    alias RpcNsEntryExpandNameW RpcNsEntryExpandName;\n    alias RpcNsEntryObjectInqBeginW RpcNsEntryObjectInqBegin;\n    alias RpcNsMgmtBindingUnexportW RpcNsMgmtBindingUnexport;\n    alias RpcNsMgmtEntryCreateW RpcNsMgmtEntryCreate;\n    alias RpcNsMgmtEntryDeleteW RpcNsMgmtEntryDelete;\n    alias RpcNsMgmtEntryInqIfIdsW RpcNsMgmtEntryInqIfIds;\n    alias RpcNsProfileDeleteW RpcNsProfileDelete;\n    alias RpcNsProfileEltAddW RpcNsProfileEltAdd;\n    alias RpcNsProfileEltRemoveW RpcNsProfileEltRemove;\n    alias RpcNsProfileEltInqBeginW RpcNsProfileEltInqBegin;\n    alias RpcNsProfileEltInqNextW RpcNsProfileEltInqNext;\n} else {\n    alias RpcNsBindingLookupBeginA RpcNsBindingLookupBegin;\n    alias RpcNsBindingImportBeginA RpcNsBindingImportBegin;\n    alias RpcNsBindingExportA RpcNsBindingExport;\n    alias RpcNsBindingUnexportA RpcNsBindingUnexport;\n    alias RpcNsGroupDeleteA RpcNsGroupDelete;\n    alias RpcNsGroupMbrAddA RpcNsGroupMbrAdd;\n    alias RpcNsGroupMbrRemoveA RpcNsGroupMbrRemove;\n    alias RpcNsGroupMbrInqBeginA RpcNsGroupMbrInqBegin;\n    alias RpcNsGroupMbrInqNextA RpcNsGroupMbrInqNext;\n    alias RpcNsEntryExpandNameA RpcNsEntryExpandName;\n    alias RpcNsEntryObjectInqBeginA RpcNsEntryObjectInqBegin;\n    alias RpcNsMgmtBindingUnexportA RpcNsMgmtBindingUnexport;\n    alias RpcNsMgmtEntryCreateA RpcNsMgmtEntryCreate;\n    alias RpcNsMgmtEntryDeleteA RpcNsMgmtEntryDelete;\n    alias RpcNsMgmtEntryInqIfIdsA RpcNsMgmtEntryInqIfIds;\n    alias RpcNsProfileDeleteA RpcNsProfileDelete;\n    alias RpcNsProfileEltAddA RpcNsProfileEltAdd;\n    alias RpcNsProfileEltRemoveA RpcNsProfileEltRemove;\n    alias RpcNsProfileEltInqBeginA RpcNsProfileEltInqBegin;\n    alias RpcNsProfileEltInqNextA RpcNsProfileEltInqNext;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/rpcnsip.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_rpcnsip.d)\n */\nmodule core.sys.windows.rpcnsip;\nversion (Windows):\n\nprivate import core.sys.windows.rpcdce, core.sys.windows.rpcdcep, core.sys.windows.rpcnsi;\n\nstruct RPC_IMPORT_CONTEXT_P {\n    RPC_NS_HANDLE       LookupContext;\n    RPC_BINDING_HANDLE  ProposedHandle;\n    RPC_BINDING_VECTOR* Bindings;\n}\nalias RPC_IMPORT_CONTEXT_P* PRPC_IMPORT_CONTEXT_P;\n\nextern(Windows) {\n    RPC_STATUS I_RpcNsGetBuffer(PRPC_MESSAGE);\n    RPC_STATUS I_RpcNsSendReceive(PRPC_MESSAGE, RPC_BINDING_HANDLE*);\n    void I_RpcNsRaiseException(PRPC_MESSAGE, RPC_STATUS);\n    RPC_STATUS I_RpcReBindBuffer(PRPC_MESSAGE);\n    RPC_STATUS I_NsServerBindSearch();\n    RPC_STATUS I_NsClientBindSearch();\n    void I_NsClientBindDone();\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/rpcnterr.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_rpcnterr.d)\n */\nmodule core.sys.windows.rpcnterr;\nversion (Windows):\n\nimport core.sys.windows.winerror;\n\nenum : uint {\n    RPC_S_OK                     = ERROR_SUCCESS,\n    RPC_S_INVALID_ARG            = ERROR_INVALID_PARAMETER,\n    RPC_S_OUT_OF_MEMORY          = ERROR_OUTOFMEMORY,\n    RPC_S_OUT_OF_THREADS         = ERROR_MAX_THRDS_REACHED,\n    RPC_S_INVALID_LEVEL          = ERROR_INVALID_PARAMETER,\n    RPC_S_BUFFER_TOO_SMALL       = ERROR_INSUFFICIENT_BUFFER,\n    RPC_S_INVALID_SECURITY_DESC  = ERROR_INVALID_SECURITY_DESCR,\n    RPC_S_ACCESS_DENIED          = ERROR_ACCESS_DENIED,\n    RPC_S_SERVER_OUT_OF_MEMORY   = ERROR_NOT_ENOUGH_SERVER_MEMORY,\n    RPC_X_NO_MEMORY              = RPC_S_OUT_OF_MEMORY,\n    RPC_X_INVALID_BOUND          = RPC_S_INVALID_BOUND,\n    RPC_X_INVALID_TAG            = RPC_S_INVALID_TAG,\n    RPC_X_ENUM_VALUE_TOO_LARGE   = RPC_X_ENUM_VALUE_OUT_OF_RANGE,\n    RPC_X_SS_CONTEXT_MISMATCH    = ERROR_INVALID_HANDLE,\n    RPC_X_INVALID_BUFFER         = ERROR_INVALID_USER_BUFFER,\n    RPC_X_INVALID_PIPE_OPERATION = RPC_X_WRONG_PIPE_ORDER\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/schannel.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_schannel.d)\n */\nmodule core.sys.windows.schannel;\nversion (Windows):\n\nimport core.sys.windows.wincrypt;\nprivate import core.sys.windows.windef;\n\nenum DWORD SCHANNEL_CRED_VERSION = 4;\nenum SCHANNEL_SHUTDOWN           = 1;\n/* Comment from MinGW\n    ? Do these belong here or in wincrypt.h\n */\nenum : DWORD {\n    AUTHTYPE_CLIENT = 1,\n    AUTHTYPE_SERVER = 2\n}\n\nenum DWORD\n    SP_PROT_PCT1_SERVER = 0x01,\n    SP_PROT_PCT1_CLIENT = 0x02,\n    SP_PROT_SSL2_SERVER = 0x04,\n    SP_PROT_SSL2_CLIENT = 0x08,\n    SP_PROT_SSL3_SERVER = 0x10,\n    SP_PROT_SSL3_CLIENT = 0x20,\n    SP_PROT_TLS1_SERVER = 0x40,\n    SP_PROT_TLS1_CLIENT = 0x80,\n    SP_PROT_PCT1        = SP_PROT_PCT1_CLIENT | SP_PROT_PCT1_SERVER,\n    SP_PROT_TLS1        = SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_SERVER,\n    SP_PROT_SSL2        = SP_PROT_SSL2_CLIENT | SP_PROT_SSL2_SERVER,\n    SP_PROT_SSL3        = SP_PROT_SSL3_CLIENT | SP_PROT_SSL3_SERVER;\n\nenum DWORD\n    SCH_CRED_NO_SYSTEM_MAPPER                    = 0x0002,\n    SCH_CRED_NO_SERVERNAME_CHECK                 = 0x0004,\n    SCH_CRED_MANUAL_CRED_VALIDATION              = 0x0008,\n    SCH_CRED_NO_DEFAULT_CREDS                    = 0x0010,\n    SCH_CRED_AUTO_CRED_VALIDATION                = 0x0020,\n    SCH_CRED_USE_DEFAULT_CREDS                   = 0x0040,\n    SCH_CRED_REVOCATION_CHECK_END_CERT           = 0x0100,\n    SCH_CRED_REVOCATION_CHECK_CHAIN              = 0x0200,\n    SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x0400,\n    SCH_CRED_IGNORE_NO_REVOCATION_CHECK          = 0x0800,\n    SCH_CRED_IGNORE_REVOCATION_OFFLINE           = 0x1000;\n\n// No definition - presumably an opaque structure\nstruct _HMAPPER;\n\nstruct SCHANNEL_CRED {\n    DWORD           dwVersion = SCHANNEL_CRED_VERSION;\n    DWORD           cCreds;\n    PCCERT_CONTEXT* paCred;\n    HCERTSTORE      hRootStore;\n    DWORD           cMappers;\n    _HMAPPER**      aphMappers;\n    DWORD           cSupportedAlgs;\n    ALG_ID*         palgSupportedAlgs;\n    DWORD           grbitEnabledProtocols;\n    DWORD           dwMinimumCypherStrength;\n    DWORD           dwMaximumCypherStrength;\n    DWORD           dwSessionLifespan;\n    DWORD           dwFlags;\n    DWORD           reserved;\n}\nalias SCHANNEL_CRED* PSCHANNEL_CRED;\n\nstruct SecPkgCred_SupportedAlgs {\n    DWORD   cSupportedAlgs;\n    ALG_ID* palgSupportedAlgs;\n}\nalias SecPkgCred_SupportedAlgs* PSecPkgCred_SupportedAlgs;\n\nstruct SecPkgCred_CypherStrengths {\n    DWORD dwMinimumCypherStrength;\n    DWORD dwMaximumCypherStrength;\n}\nalias SecPkgCred_CypherStrengths* PSecPkgCred_CypherStrengths;\n\nstruct SecPkgCred_SupportedProtocols {\n    DWORD grbitProtocol;\n}\nalias SecPkgCred_SupportedProtocols* PSecPkgCred_SupportedProtocols;\n\nstruct SecPkgContext_IssuerListInfoEx {\n    PCERT_NAME_BLOB aIssuers;\n    DWORD           cIssuers;\n}\nalias SecPkgContext_IssuerListInfoEx* PSecPkgContext_IssuerListInfoEx;\n\nstruct SecPkgContext_ConnectionInfo {\n    DWORD  dwProtocol;\n    ALG_ID aiCipher;\n    DWORD  dwCipherStrength;\n    ALG_ID aiHash;\n    DWORD  dwHashStrength;\n    ALG_ID aiExch;\n    DWORD  dwExchStrength;\n}\nalias SecPkgContext_ConnectionInfo* PSecPkgContext_ConnectionInfo;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/secext.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_secext.d)\n */\n// Don't include this file directly, use core.sys.windows.security instead.\nmodule core.sys.windows.secext;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"secur32\");\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef;\n\nstatic assert (_WIN32_WINNT >= 0x501,\n  \"SecExt is only available on WindowsXP and later\");\n\nenum EXTENDED_NAME_FORMAT {\n    NameUnknown,\n    NameFullyQualifiedDN,\n    NameSamCompatible,\n    NameDisplay,          // =  3\n    NameUniqueId             =  6,\n    NameCanonical,\n    NameUserPrincipal,\n    NameCanonicalEx,\n    NameServicePrincipal, // = 10\n    NameDnsDomain            = 12\n}\nalias EXTENDED_NAME_FORMAT* PEXTENDED_NAME_FORMAT;\n\nextern (Windows) {\n    BOOLEAN GetComputerObjectNameA(EXTENDED_NAME_FORMAT, LPSTR, PULONG);\n    BOOLEAN GetComputerObjectNameW(EXTENDED_NAME_FORMAT, LPWSTR, PULONG);\n    BOOLEAN GetUserNameExA(EXTENDED_NAME_FORMAT, LPSTR, PULONG);\n    BOOLEAN GetUserNameExW(EXTENDED_NAME_FORMAT, LPWSTR, PULONG);\n    BOOLEAN TranslateNameA(LPCSTR, EXTENDED_NAME_FORMAT,\n      EXTENDED_NAME_FORMAT, LPSTR, PULONG);\n    BOOLEAN TranslateNameW(LPCWSTR, EXTENDED_NAME_FORMAT,\n      EXTENDED_NAME_FORMAT, LPWSTR, PULONG);\n}\n\nversion (Unicode) {\n    alias GetComputerObjectNameW GetComputerObjectName;\n    alias GetUserNameExW GetUserNameEx;\n    alias TranslateNameW TranslateName;\n} else {\n    alias GetComputerObjectNameA GetComputerObjectName;\n    alias GetUserNameExA GetUserNameEx;\n    alias TranslateNameA TranslateName;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/security.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Ellery Newcomer\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_security.d)\n */\nmodule core.sys.windows.security;\nversion (Windows):\n\nenum :SECURITY_STATUS{\n    SEC_E_OK = 0,\n    SEC_E_CERT_EXPIRED = (-2146893016),\n    SEC_E_INCOMPLETE_MESSAGE = (-2146893032),\n    SEC_E_INSUFFICIENT_MEMORY = (-2146893056),\n    SEC_E_INTERNAL_ERROR = (-2146893052),\n    SEC_E_INVALID_HANDLE = (-2146893055),\n    SEC_E_INVALID_TOKEN = (-2146893048),\n    SEC_E_LOGON_DENIED = (-2146893044),\n    SEC_E_NO_AUTHENTICATING_AUTHORITY = (-2146893039),\n    SEC_E_NO_CREDENTIALS = (-2146893042),\n    SEC_E_TARGET_UNKNOWN = (-2146893053),\n    SEC_E_UNSUPPORTED_FUNCTION = (-2146893054),\n    SEC_E_UNTRUSTED_ROOT = (-2146893019),\n    SEC_E_WRONG_PRINCIPAL = (-2146893022),\n    SEC_E_SECPKG_NOT_FOUND = (-2146893051),\n    SEC_E_QOP_NOT_SUPPORTED = (-2146893046),\n    SEC_E_UNKNOWN_CREDENTIALS = (-2146893043),\n    SEC_E_NOT_OWNER = (-2146893050),\n}\nenum :SECURITY_STATUS {\n    SEC_I_RENEGOTIATE = 590625,\n    SEC_I_COMPLETE_AND_CONTINUE = 590612,\n    SEC_I_COMPLETE_NEEDED = 590611,\n    SEC_I_CONTINUE_NEEDED = 590610,\n    SEC_I_INCOMPLETE_CREDENTIALS = 590624,\n}\n\n/* always a char */\nalias char SEC_CHAR;\nalias wchar SEC_WCHAR;\n\nalias int SECURITY_STATUS;\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/servprov.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.10\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_servprov.d)\n */\nmodule core.sys.windows.servprov;\nversion (Windows):\n\nprivate import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;\n\ninterface IServiceProvider : IUnknown {\n    HRESULT QueryService(REFGUID, REFIID, void**);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/setupapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Vladimir Vlasov\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_setupapi.d)\n */\nmodule core.sys.windows.setupapi;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"setupapi\");\n\nprivate import core.sys.windows.basetyps, core.sys.windows.commctrl, core.sys.windows.prsht, core.sys.windows.w32api,\n  core.sys.windows.winreg, core.sys.windows.windef;\nprivate import core.sys.windows.winbase; // for SYSTEMTIME\n\n/*static if (_WIN32_WINNT < _WIN32_WINDOWS) {\nenum UINT _SETUPAPI_VER = _WIN32_WINNT; // SetupAPI version follows Windows NT version\n} else static if (_WIN32_WINDOWS) {\n    static if (_WIN32_WINDOWS >= 0x0490) {\nenum UINT _SETUPAPI_VER = 0x0500;     // WinME uses same version of SetupAPI as Win2k\n    } else static if (_WIN32_WINDOWS >= 0x0410) {\nenum UINT _SETUPAPI_VER = 0x0410;     // Indicates version of SetupAPI shipped with Win98\n    } else {\nenum UINT _SETUPAPI_VER = 0x0400;     // Earliest SetupAPI version\n    }\n} else {\nenum UINT _SETUPAPI_VER = 0x0501;\n}\n\nversion (WindowsNTonly) {\n    static if (_WIN32_WINNT >= 0x500) {\nenum UINT USE_SP_DRVINFO_DATA_V1 = 0;\n    } else {\nenum UINT USE_SP_DRVINFO_DATA_V1 = 1;\n    }\n} else {\nenum UINT USE_SP_DRVINFO_DATA_V1 = 1;\n}*/\n/+\nenum UINT _SETUPAPI_VER = 0x0400;     // Earliest SetupAPI version\nenum UINT USE_SP_DRVINFO_DATA_V1 = 1;\n+/\nenum UINT _SETUPAPI_VER          = _WIN32_WINNT;\nenum bool USE_SP_DRVINFO_DATA_V1 = _WIN32_WINNT < 0x500;\n\nenum : uint {\n    LINE_LEN                  = 256,\n    MAX_INF_STRING_LENGTH     = 4096,\n    MAX_TITLE_LEN             = 60,\n    MAX_INSTRUCTION_LEN       = 256,\n    MAX_LABEL_LEN             = 30,\n    MAX_SERVICE_NAME_LEN      = 256,\n    MAX_SUBTITLE_LEN          = 256,\n    SP_MAX_MACHINENAME_LENGTH = MAX_PATH + 3\n}\n\nenum : DWORD {\n    COPYFLG_WARN_IF_SKIP         = 0x00000001,\n    COPYFLG_NOSKIP               = 0x00000002,\n    COPYFLG_NOVERSIONCHECK       = 0x00000004,\n    COPYFLG_FORCE_FILE_IN_USE    = 0x00000008,\n    COPYFLG_NO_OVERWRITE         = 0x00000010,\n    COPYFLG_NO_VERSION_DIALOG    = 0x00000020,\n    COPYFLG_OVERWRITE_OLDER_ONLY = 0x00000040,\n    COPYFLG_REPLACEONLY          = 0x00000400,\n    COPYFLG_NODECOMP             = 0x00000800,\n    COPYFLG_REPLACE_BOOT_FILE    = 0x00001000,\n    COPYFLG_NOPRUNE              = 0x00002000\n}\n\nenum : DWORD {\n    DELFLG_IN_USE  = 0x00000001,\n    DELFLG_IN_USE1 = 0x00010000\n}\n\nenum : DWORD {\n    DI_REMOVEDEVICE_GLOBAL              = 0x00000001,\n    DI_REMOVEDEVICE_CONFIGSPECIFIC      = 0x00000002,\n    DI_UNREMOVEDEVICE_CONFIGSPECIFIC    = 0x00000002,\n    DI_SHOWOEM                          = 0x00000001,\n    DI_SHOWCOMPAT                       = 0x00000002,\n    DI_SHOWCLASS                        = 0x00000004,\n    DI_SHOWALL                          = 0x00000007,\n    DI_NOVCP                            = 0x00000008,\n    DI_DIDCOMPAT                        = 0x00000010,\n    DI_DIDCLASS                         = 0x00000020,\n    DI_AUTOASSIGNRES                    = 0x00000040,\n    DI_NEEDRESTART                      = 0x00000080,\n    DI_NEEDREBOOT                       = 0x00000100,\n    DI_NOBROWSE                         = 0x00000200,\n    DI_MULTMFGS                         = 0x00000400,\n    DI_DISABLED                         = 0x00000800,\n    DI_GENERALPAGE_ADDED                = 0x00001000,\n    DI_RESOURCEPAGE_ADDED               = 0x00002000,\n    DI_PROPERTIES_CHANGE                = 0x00004000,\n    DI_INF_IS_SORTED                    = 0x00008000,\n    DI_ENUMSINGLEINF                    = 0x00010000,\n    DI_DONOTCALLCONFIGMG                = 0x00020000,\n    DI_INSTALLDISABLED                  = 0x00040000,\n    DI_COMPAT_FROM_CLASS                = 0x00080000,\n    DI_CLASSINSTALLPARAMS               = 0x00100000,\n    DI_NODI_DEFAULTACTION               = 0x00200000,\n    DI_QUIETINSTALL                     = 0x00800000,\n    DI_NOFILECOPY                       = 0x01000000,\n    DI_FORCECOPY                        = 0x02000000,\n    DI_DRIVERPAGE_ADDED                 = 0x04000000,\n    DI_USECI_SELECTSTRINGS              = 0x08000000,\n    DI_OVERRIDE_INFFLAGS                = 0x10000000,\n    DI_PROPS_NOCHANGEUSAGE              = 0x20000000,\n    DI_NOSELECTICONS                    = 0x40000000,\n    DI_NOWRITE_IDS                      = 0x80000000,\n    DI_FLAGSEX_USEOLDINFSEARCH          = 0x00000001,\n    DI_FLAGSEX_AUTOSELECTRANK0          = 0x00000002,\n    DI_FLAGSEX_CI_FAILED                = 0x00000004,\n    DI_FLAGSEX_DIDINFOLIST              = 0x00000010,\n    DI_FLAGSEX_DIDCOMPATINFO            = 0x00000020,\n    DI_FLAGSEX_FILTERCLASSES            = 0x00000040,\n    DI_FLAGSEX_SETFAILEDINSTALL         = 0x00000080,\n    DI_FLAGSEX_DEVICECHANGE             = 0x00000100,\n    DI_FLAGSEX_ALWAYSWRITEIDS           = 0x00000200,\n    DI_FLAGSEX_PROPCHANGE_PENDING       = 0x00000400,\n    DI_FLAGSEX_ALLOWEXCLUDEDDRVS        = 0x00000800,\n    DI_FLAGSEX_NOUIONQUERYREMOVE        = 0x00001000,\n    DI_FLAGSEX_USECLASSFORCOMPAT        = 0x00002000,\n    DI_FLAGSEX_OLDINF_IN_CLASSLIST      = 0x00004000,\n    DI_FLAGSEX_NO_DRVREG_MODIFY         = 0x00008000,\n    DI_FLAGSEX_IN_SYSTEM_SETUP          = 0x00010000,\n    DI_FLAGSEX_INET_DRIVER              = 0x00020000,\n    DI_FLAGSEX_APPENDDRIVERLIST         = 0x00040000,\n    DI_FLAGSEX_PREINSTALLBACKUP         = 0x00080000,\n    DI_FLAGSEX_BACKUPONREPLACE          = 0x00100000,\n    DI_FLAGSEX_DRIVERLIST_FROM_URL      = 0x00200000,\n    DI_FLAGSEX_RESERVED1                = 0x00400000,\n    DI_FLAGSEX_EXCLUDE_OLD_INET_DRIVERS = 0x00800000,\n    DI_FLAGSEX_POWERPAGE_ADDED          = 0x01000000\n}\n\nenum : DWORD {\n    DIBCI_NOINSTALLCLASS = 0x00000001,\n    DIBCI_NODISPLAYCLASS = 0x00000002\n}\n\nenum : DWORD {\n    DICD_GENERATE_ID       = 0x00000001,\n    DICD_INHERIT_CLASSDRVS = 0x00000002\n}\n\nenum : DWORD {\n    DICS_ENABLE = 1,\n    DICS_DISABLE,\n    DICS_PROPCHANGE,\n    DICS_START,\n    DICS_STOP // = 5\n}\n\nenum : DWORD {\n    DICS_FLAG_GLOBAL         = 1,\n    DICS_FLAG_CONFIGSPECIFIC = 2,\n    DICS_FLAG_CONFIGGENERAL  = 4\n}\n\nalias UINT DI_FUNCTION;\n\nenum : DI_FUNCTION {\n    DIF_SELECTDEVICE = 1,\n    DIF_INSTALLDEVICE,\n    DIF_ASSIGNRESOURCES,\n    DIF_PROPERTIES,\n    DIF_REMOVE,\n    DIF_FIRSTTIMESETUP,\n    DIF_FOUNDDEVICE,\n    DIF_SELECTCLASSDRIVERS,\n    DIF_VALIDATECLASSDRIVERS,\n    DIF_INSTALLCLASSDRIVERS,\n    DIF_CALCDISKSPACE,\n    DIF_DESTROYPRIVATEDATA,\n    DIF_VALIDATEDRIVER,\n    DIF_MOVEDEVICE,\n    DIF_DETECT,\n    DIF_INSTALLWIZARD,\n    DIF_DESTROYWIZARDDATA,\n    DIF_PROPERTYCHANGE,\n    DIF_ENABLECLASS,\n    DIF_DETECTVERIFY,\n    DIF_INSTALLDEVICEFILES,\n    DIF_UNREMOVE,\n    DIF_SELECTBESTCOMPATDRV,\n    DIF_ALLOW_INSTALL,\n    DIF_REGISTERDEVICE,\n    DIF_NEWDEVICEWIZARD_PRESELECT,\n    DIF_NEWDEVICEWIZARD_SELECT,\n    DIF_NEWDEVICEWIZARD_PREANALYZE,\n    DIF_NEWDEVICEWIZARD_POSTANALYZE,\n    DIF_NEWDEVICEWIZARD_FINISHINSTALL,\n    DIF_UNUSED1,\n    DIF_INSTALLINTERFACES,\n    DIF_DETECTCANCEL,\n    DIF_REGISTER_COINSTALLERS,\n    DIF_ADDPROPERTYPAGE_ADVANCED,\n    DIF_ADDPROPERTYPAGE_BASIC,\n    DIF_RESERVED1,\n    DIF_TROUBLESHOOTER,\n    DIF_POWERMESSAGEWAKE // = 39\n}\n\nenum : DWORD {\n    DIGCF_DEFAULT         = 0x00000001,\n    DIGCF_PRESENT         = 0x00000002,\n    DIGCF_ALLCLASSES      = 0x00000004,\n    DIGCF_PROFILE         = 0x00000008,\n    DIGCF_DEVICEINTERFACE = 0x00000010\n}\n\ndeprecated enum : DWORD {\n    DIGCF_INTERFACEDEVICE = DIGCF_DEVICEINTERFACE\n}\n\nenum : DWORD {\n    DIGCDP_FLAG_BASIC    = 0x00000001,\n    DIGCDP_FLAG_ADVANCED = 0x00000002\n}\n\nenum : DWORD {\n    DIOCR_INSTALLER = 0x00000001,\n    DIOCR_INTERFACE = 0x00000002\n}\n\nenum : DWORD {\n    DIODI_NO_ADD = 0x00000001\n}\n\nenum : DWORD {\n    DIOD_INHERIT_CLASSDRVS = 0x00000002,\n    DIOD_CANCEL_REMOVE     = 0x00000004\n}\n\nenum : DWORD {\n    DIREG_DEV  = 0x00000001,\n    DIREG_DRV  = 0x00000002,\n    DIREG_BOTH = 0x00000004\n}\n\nenum : int {\n    DIRID_ABSOLUTE       = -1,\n    DIRID_NULL           = 0,\n    DIRID_SRCPATH        = 1,\n    DIRID_WINDOWS        = 10,\n    DIRID_SYSTEM         = 11,\n    DIRID_DRIVERS        = 12,\n    DIRID_IOSUBSYS       = DIRID_DRIVERS,\n    DIRID_INF            = 17,\n    DIRID_HELP           = 18,\n    DIRID_FONTS          = 20,\n    DIRID_VIEWERS        = 21,\n    DIRID_COLOR          = 23,\n    DIRID_APPS           = 24,\n    DIRID_SHARED         = 25,\n    DIRID_BOOT           = 30,\n    DIRID_SYSTEM16       = 50,\n    DIRID_SPOOL          = 51,\n    DIRID_SPOOLDRIVERS   = 52,\n    DIRID_USERPROFILE    = 53,\n    DIRID_LOADER         = 54,\n    DIRID_PRINTPROCESSOR = 55,\n    DIRID_DEFAULT        = DIRID_SYSTEM\n}\n\nenum : int {\n    DIRID_COMMON_STARTMENU        = 16406,\n    DIRID_COMMON_PROGRAMS         = 16407,\n    DIRID_COMMON_STARTUP          = 16408,\n    DIRID_COMMON_DESKTOPDIRECTORY = 16409,\n    DIRID_COMMON_FAVORITES        = 16415,\n    DIRID_COMMON_APPDATA          = 16419,\n    DIRID_PROGRAM_FILES           = 16422,\n    DIRID_SYSTEM_X86              = 16425,\n    DIRID_PROGRAM_FILES_X86       = 16426,\n    DIRID_PROGRAM_FILES_COMMON    = 16427,\n    DIRID_PROGRAM_FILES_COMMONX86 = 16428,\n    DIRID_COMMON_TEMPLATES        = 16429,\n    DIRID_COMMON_DOCUMENTS        = 16430,\n    DIRID_USER                    = 0x8000,\n    DIRID_ABSOLUTE_16BIT          = 0xffff\n}\n\nenum : DWORD {\n    DMI_MASK    = 0x00000001,\n    DMI_BKCOLOR = 0x00000002,\n    DMI_USERECT = 0x00000004\n}\n\nenum : DWORD {\n    DNF_DUPDESC           = 0x00000001,\n    DNF_OLDDRIVER         = 0x00000002,\n    DNF_EXCLUDEFROMLIST   = 0x00000004,\n    DNF_NODRIVER          = 0x00000008,\n    DNF_LEGACYINF         = 0x00000010,\n    DNF_CLASS_DRIVER      = 0x00000020,\n    DNF_COMPATIBLE_DRIVER = 0x00000040,\n    DNF_INET_DRIVER       = 0x00000080,\n    DNF_UNUSED1           = 0x00000100,\n    DNF_INDEXED_DRIVER    = 0x00000200,\n    DNF_OLD_INET_DRIVER   = 0x00000400,\n    DNF_BAD_DRIVER        = 0x00000800,\n    DNF_DUPPROVIDER       = 0x00001000\n}\n\nenum : UINT {\n    DPROMPT_SUCCESS,\n    DPROMPT_CANCEL,\n    DPROMPT_SKIPFILE,\n    DPROMPT_BUFFERTOOSMALL,\n    DPROMPT_OUTOFMEMORY // = 4\n}\n\nenum : DWORD {\n    DRIVER_HARDWAREID_RANK             = 0x00000FFF,\n    DRIVER_COMPATID_RANK               = 0x00003FFF,\n    DRIVER_UNTRUSTED_RANK              = 0x00008000,\n    DRIVER_UNTRUSTED_HARDWAREID_RANK   = 0x00008FFF,\n    DRIVER_UNTRUSTED_COMPATID_RANK     = 0x0000BFFF,\n    DRIVER_W9X_SUSPECT_RANK            = 0x0000C000,\n    DRIVER_W9X_SUSPECT_HARDWAREID_RANK = 0x0000CFFF,\n    DRIVER_W9X_SUSPECT_COMPATID_RANK   = 0x0000FFFF\n}\n\nenum : DWORD {\n    DYNAWIZ_FLAG_PAGESADDED             = 0x00000001,\n    DYNAWIZ_FLAG_INSTALLDET_NEXT        = 0x00000002,\n    DYNAWIZ_FLAG_INSTALLDET_PREV        = 0x00000004,\n    DYNAWIZ_FLAG_ANALYZE_HANDLECONFLICT = 0x00000008\n}\n\nenum : WORD {\n    ENABLECLASS_QUERY,\n    ENABLECLASS_SUCCESS,\n    ENABLECLASS_FAILURE // = 2\n}\n\nenum : DWORD {\n    ERROR_EXPECTED_SECTION_NAME       = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0,\n    ERROR_BAD_SECTION_NAME_LINE       = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 1,\n    ERROR_SECTION_NAME_TOO_LONG       = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 2,\n    ERROR_GENERAL_SYNTAX              = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 3,\n    ERROR_WRONG_INF_STYLE             = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x100,\n    ERROR_NOT_INSTALLED               = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x1000,\n    ERROR_SECTION_NOT_FOUND           = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x101,\n    ERROR_LINE_NOT_FOUND              = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x102,\n    ERROR_NO_BACKUP                   = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x103,\n    ERROR_NO_ASSOCIATED_CLASS         = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x200,\n    ERROR_CLASS_MISMATCH              = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x201,\n    ERROR_DUPLICATE_FOUND             = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x202,\n    ERROR_NO_DRIVER_SELECTED          = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x203,\n    ERROR_KEY_DOES_NOT_EXIST          = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x204,\n    ERROR_INVALID_DEVINST_NAME        = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x205,\n    ERROR_INVALID_CLASS               = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x206,\n    ERROR_DEVINST_ALREADY_EXISTS      = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x207,\n    ERROR_DEVINFO_NOT_REGISTERED      = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x208,\n    ERROR_INVALID_REG_PROPERTY        = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x209,\n    ERROR_NO_INF                      = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x20A,\n    ERROR_NO_SUCH_DEVINST             = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x20B,\n    ERROR_CANT_LOAD_CLASS_ICON        = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x20C,\n    ERROR_INVALID_CLASS_INSTALLER     = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x20D,\n    ERROR_DI_DO_DEFAULT               = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x20E,\n    ERROR_DI_NOFILECOPY               = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x20F,\n    ERROR_INVALID_HWPROFILE           = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x210,\n    ERROR_NO_DEVICE_SELECTED          = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x211,\n    ERROR_DEVINFO_LIST_LOCKED         = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x212,\n    ERROR_DEVINFO_DATA_LOCKED         = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x213,\n    ERROR_DI_BAD_PATH                 = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x214,\n    ERROR_NO_CLASSINSTALL_PARAMS      = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x215,\n    ERROR_FILEQUEUE_LOCKED            = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x216,\n    ERROR_BAD_SERVICE_INSTALLSECT     = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x217,\n    ERROR_NO_CLASS_DRIVER_LIST        = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x218,\n    ERROR_NO_ASSOCIATED_SERVICE       = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x219,\n    ERROR_NO_DEFAULT_DEVICE_INTERFACE = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x21A,\n    ERROR_DEVICE_INTERFACE_ACTIVE     = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x21B,\n    ERROR_DEVICE_INTERFACE_REMOVED    = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x21C,\n    ERROR_BAD_INTERFACE_INSTALLSECT   = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x21D,\n    ERROR_NO_SUCH_INTERFACE_CLASS     = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x21E,\n    ERROR_INVALID_REFERENCE_STRING    = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x21F,\n    ERROR_INVALID_MACHINENAME         = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x220,\n    ERROR_REMOTE_COMM_FAILURE         = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x221,\n    ERROR_MACHINE_UNAVAILABLE         = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x222,\n    ERROR_NO_CONFIGMGR_SERVICES       = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x223,\n    ERROR_INVALID_PROPPAGE_PROVIDER   = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x224,\n    ERROR_NO_SUCH_DEVICE_INTERFACE    = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x225,\n    ERROR_DI_POSTPROCESSING_REQUIRED  = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x226,\n    ERROR_INVALID_COINSTALLER         = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x227,\n    ERROR_NO_COMPAT_DRIVERS           = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x228,\n    ERROR_NO_DEVICE_ICON              = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x229,\n    ERROR_INVALID_INF_LOGCONFIG       = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x22A,\n    ERROR_DI_DONT_INSTALL             = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x22B,\n    ERROR_INVALID_FILTER_DRIVER       = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x22C,\n    ERROR_NON_WINDOWS_NT_DRIVER       = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x22D,\n    ERROR_NON_WINDOWS_DRIVER          = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x22E,\n    ERROR_NO_CATALOG_FOR_OEM_INF      = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x22F,\n    ERROR_DEVINSTALL_QUEUE_NONNATIVE  = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x230,\n    ERROR_NOT_DISABLEABLE             = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x231,\n    ERROR_CANT_REMOVE_DEVINST         = APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR | 0x232\n}\n\ndeprecated enum : DWORD {\n    ERROR_NO_DEFAULT_INTERFACE_DEVICE = ERROR_NO_DEFAULT_DEVICE_INTERFACE,\n    ERROR_INTERFACE_DEVICE_ACTIVE     = ERROR_DEVICE_INTERFACE_ACTIVE,\n    ERROR_INTERFACE_DEVICE_REMOVED    = ERROR_DEVICE_INTERFACE_REMOVED,\n    ERROR_NO_SUCH_INTERFACE_DEVICE    = ERROR_NO_SUCH_DEVICE_INTERFACE,\n}\n\nenum : UINT {\n    FILEOP_COPY,\n    FILEOP_RENAME,\n    FILEOP_DELETE,\n    FILEOP_BACKUP,\n    FILEOP_NEWPATH, // = 4\n    FILEOP_ABORT = 0,\n    FILEOP_DOIT,\n    FILEOP_SKIP, // = 2\n    FILEOP_RETRY = FILEOP_DOIT\n}\n\nenum : UINT {\n    FILE_COMPRESSION_NONE,\n    FILE_COMPRESSION_WINLZA,\n    FILE_COMPRESSION_MSZIP,\n    FILE_COMPRESSION_NTCAB // = 3\n}\n\nenum : DWORD {\n    FLG_ADDREG_TYPE_SZ        = 0x00000000,\n    FLG_ADDREG_BINVALUETYPE   = 0x00000001,\n    FLG_ADDREG_NOCLOBBER      = 0x00000002,\n    FLG_ADDREG_DELVAL         = 0x00000004,\n    FLG_ADDREG_APPEND         = 0x00000008,\n    FLG_ADDREG_KEYONLY        = 0x00000010,\n    FLG_ADDREG_OVERWRITEONLY  = 0x00000020,\n    FLG_ADDREG_TYPE_MULTI_SZ  = 0x00010000,\n    FLG_ADDREG_TYPE_EXPAND_SZ = 0x00020000,\n    FLG_ADDREG_TYPE_BINARY    = 0x00000000 | FLG_ADDREG_BINVALUETYPE,\n    FLG_ADDREG_TYPE_DWORD     = 0x00010000 | FLG_ADDREG_BINVALUETYPE,\n    FLG_ADDREG_TYPE_NONE      = 0x00020000 | FLG_ADDREG_BINVALUETYPE,\n    FLG_ADDREG_TYPE_MASK      = 0xFFFF0000 | FLG_ADDREG_BINVALUETYPE\n}\n\nstatic if (_SETUPAPI_VER >= 0x0501) {\n    enum : DWORD {\n        FLG_ADDREG_64BITKEY       = 0x00001000,\n        FLG_ADDREG_KEYONLY_COMMON = 0x00002000,\n        FLG_ADDREG_32BITKEY       = 0x00004000,\n        FLG_ADDREG_DELREG_BIT     = 0x00008000\n    }\n}\n\nenum : DWORD {\n    FLG_DELREG_VALUE = 0x00000000\n}\n\nstatic if (_SETUPAPI_VER >= 0x0501) {\n    enum : DWORD {\n        FLG_DELREG_TYPE_MASK          = FLG_ADDREG_TYPE_MASK,\n        FLG_DELREG_TYPE_SZ            = FLG_ADDREG_TYPE_SZ,\n        FLG_DELREG_TYPE_MULTI_SZ      = FLG_ADDREG_TYPE_MULTI_SZ,\n        FLG_DELREG_TYPE_EXPAND_SZ     = FLG_ADDREG_TYPE_EXPAND_SZ,\n        FLG_DELREG_TYPE_BINARY        = FLG_ADDREG_TYPE_BINARY,\n        FLG_DELREG_TYPE_DWORD         = FLG_ADDREG_TYPE_DWORD,\n        FLG_DELREG_TYPE_NONE          = FLG_ADDREG_TYPE_NONE,\n        FLG_DELREG_64BITKEY           = FLG_ADDREG_64BITKEY,\n        FLG_DELREG_KEYONLY_COMMON     = FLG_ADDREG_KEYONLY_COMMON,\n        FLG_DELREG_32BITKEY           = FLG_ADDREG_32BITKEY,\n        FLG_DELREG_OPERATION_MASK     = 0x000000FE,\n        FLG_DELREG_MULTI_SZ_DELSTRING = 0x00000002 | FLG_DELREG_TYPE_MULTI_SZ | FLG_ADDREG_DELREG_BIT\n    }\n}\n\nenum : DWORD {\n    FLG_BITREG_CLEARBITS = 0x00000000,\n    FLG_BITREG_SETBITS   = 0x00000001\n}\n\nstatic if (_SETUPAPI_VER >= 0x0501) {\n    enum : DWORD {\n        FLG_BITREG_64BITKEY = 0x00001000,\n        FLG_BITREG_32BITKEY = 0x00004000\n    }\n}\n\nenum : DWORD {\n    FLG_PROFITEM_CURRENTUSER = 0x00000001,\n    FLG_PROFITEM_DELETE      = 0x00000002,\n    FLG_PROFITEM_GROUP       = 0x00000004,\n    FLG_PROFITEM_CSIDL       = 0x00000008\n}\n\nenum : DWORD {\n    FLG_REGSVR_DLLREGISTER = 0x00000001,\n    FLG_REGSVR_DLLINSTALL  = 0x00000002\n}\n\nenum {\n    IDD_DYNAWIZ_FIRSTPAGE = 10000,\n    IDD_DYNAWIZ_SELECT_PREVPAGE,\n    IDD_DYNAWIZ_SELECT_NEXTPAGE,\n    IDD_DYNAWIZ_ANALYZE_PREVPAGE,\n    IDD_DYNAWIZ_ANALYZE_NEXTPAGE, // = 1004\n    IDD_DYNAWIZ_INSTALLDETECTED_PREVPAGE = 10006,\n    IDD_DYNAWIZ_INSTALLDETECTED_NEXTPAGE,\n    IDD_DYNAWIZ_INSTALLDETECTED_NODEVS,\n    IDD_DYNAWIZ_SELECTDEV_PAGE,\n    IDD_DYNAWIZ_ANALYZEDEV_PAGE,\n    IDD_DYNAWIZ_INSTALLDETECTEDDEVS_PAGE,\n    IDD_DYNAWIZ_SELECTCLASS_PAGE, // = 10012\n    MIN_IDD_DYNAWIZ_RESOURCE_ID = 10000,\n    MAX_IDD_DYNAWIZ_RESOURCE_ID = 11000\n}\n\nenum : DWORD {\n    IDF_NOBROWSE     = 0x00000001,\n    IDF_NOSKIP       = 0x00000002,\n    IDF_NODETAILS    = 0x00000004,\n    IDF_NOCOMPRESSED = 0x00000008,\n    IDF_CHECKFIRST   = 0x00000100,\n    IDF_NOBEEP       = 0x00000200,\n    IDF_NOFOREGROUND = 0x00000400,\n    IDF_WARNIFSKIP   = 0x00000800\n}\n\nstatic if (_SETUPAPI_VER >= 0x0501) {\n    enum : DWORD {\n        IDF_NOREMOVABLEMEDIAPROMPT = 0x00001000,\n        IDF_USEDISKNAMEASPROMPT    = 0x00002000,\n        IDF_OEMDISK                = 0x80000000\n    }\n}\n\nenum {\n    IDI_RESOURCEFIRST          = 159,\n    IDI_RESOURCE               = 159,\n    IDI_RESOURCELAST           = 161,\n    IDI_RESOURCEOVERLAYFIRST   = 161,\n    IDI_RESOURCEOVERLAYLAST    = 161,\n    IDI_CONFLICT               = 161,\n    IDI_PROBLEM_OVL            = 500,\n    IDI_DISABLED_OVL           = 501,\n    IDI_FORCED_OVL             = 502,\n    IDI_CLASSICON_OVERLAYFIRST = 500,\n    IDI_CLASSICON_OVERLAYLAST  = 502\n}\n\nenum : DWORD {\n    INF_STYLE_NONE          = 0x00000000,\n    INF_STYLE_OLDNT         = 0x00000001,\n    INF_STYLE_WIN4          = 0x00000002,\n    INF_STYLE_CACHE_ENABLE  = 0x00000010,\n    INF_STYLE_CACHE_DISABLE = 0x00000020\n}\n\nenum : DWORD {\n    INFINFO_INF_SPEC_IS_HINF = 1,\n    INFINFO_INF_NAME_IS_ABSOLUTE,\n    INFINFO_DEFAULT_SEARCH,\n    INFINFO_REVERSE_DEFAULT_SEARCH,\n    INFINFO_INF_PATH_LIST_SEARCH // = 5\n}\n\nalias DWORD LogSeverity;\nenum : LogSeverity {\n    LogSevInformation,\n    LogSevWarning,\n    LogSevError,\n    LogSevFatalError,\n    LogSevMaximum // = 4\n}\n\nenum MAX_INSTALLWIZARD_DYNAPAGES = 20;\n\nenum : DWORD {\n    NDW_INSTALLFLAG_DIDFACTDEFS        = 0x00000001,\n    NDW_INSTALLFLAG_HARDWAREALLREADYIN = 0x00000002,\n    NDW_INSTALLFLAG_NEEDSHUTDOWN       = 0x00000200,\n    NDW_INSTALLFLAG_EXPRESSINTRO       = 0x00000400,\n    NDW_INSTALLFLAG_SKIPISDEVINSTALLED = 0x00000800,\n    NDW_INSTALLFLAG_NODETECTEDDEVS     = 0x00001000,\n    NDW_INSTALLFLAG_INSTALLSPECIFIC    = 0x00002000,\n    NDW_INSTALLFLAG_SKIPCLASSLIST      = 0x00004000,\n    NDW_INSTALLFLAG_CI_PICKED_OEM      = 0x00008000,\n    NDW_INSTALLFLAG_PCMCIAMODE         = 0x00010000,\n    NDW_INSTALLFLAG_PCMCIADEVICE       = 0x00020000,\n    NDW_INSTALLFLAG_USERCANCEL         = 0x00040000,\n    NDW_INSTALLFLAG_KNOWNCLASS         = 0x00080000,\n    NDW_INSTALLFLAG_NEEDRESTART        = 0x00000080,\n    NDW_INSTALLFLAG_NEEDREBOOT         = 0x00000100\n}\n\nenum : DWORD {\n    SETDIRID_NOT_FULL_PATH = 0x00000001\n}\n\nenum : DWORD {\n    SP_COPY_DELETESOURCE        = 0x0000001,\n    SP_COPY_REPLACEONLY         = 0x0000002,\n    SP_COPY_NEWER               = 0x0000004,\n    SP_COPY_NEWER_OR_SAME       = 0x0000004,\n    SP_COPY_NOOVERWRITE         = 0x0000008,\n    SP_COPY_NODECOMP            = 0x0000010,\n    SP_COPY_LANGUAGEAWARE       = 0x0000020,\n    SP_COPY_SOURCE_ABSOLUTE     = 0x0000040,\n    SP_COPY_SOURCEPATH_ABSOLUTE = 0x0000080,\n    SP_COPY_IN_USE_NEEDS_REBOOT = 0x0000100,\n    SP_COPY_FORCE_IN_USE        = 0x0000200,\n    SP_COPY_NOSKIP              = 0x0000400,\n    SP_FLAG_CABINETCONTINUATION = 0x0000800,\n    SP_COPY_FORCE_NOOVERWRITE   = 0x0001000,\n    SP_COPY_FORCE_NEWER         = 0x0002000,\n    SP_COPY_WARNIFSKIP          = 0x0004000,\n    SP_COPY_NOBROWSE            = 0x0008000,\n    SP_COPY_NEWER_ONLY          = 0x0010000,\n    SP_COPY_SOURCE_SIS_MASTER   = 0x0020000,\n    SP_COPY_OEMINF_CATALOG_ONLY = 0x0040000,\n    SP_COPY_REPLACE_BOOT_FILE   = 0x0080000,\n    SP_COPY_NOPRUNE             = 0x0100000\n}\n\nstatic if (_SETUPAPI_VER >= 0x0501) {\n    enum : DWORD {\n        SP_COPY_OEM_F6_INF = 0x0200000\n    }\n}\n\nenum : DWORD {\n    SPCRP_SECURITY = 23,\n    SPCRP_SECURITY_SDS,\n    SPCRP_DEVTYPE,\n    SPCRP_EXCLUSIVE,\n    SPCRP_CHARACTERISTICS,\n    SPCRP_MAXIMUM_PROPERTY // = 28\n}\n\nenum : DWORD {\n    SPDIT_NODRIVER,\n    SPDIT_CLASSDRIVER,\n    SPDIT_COMPATDRIVER // = 2\n}\n\nenum : DWORD {\n    SPDRP_DEVICEDESC,\n    SPDRP_HARDWAREID,\n    SPDRP_COMPATIBLEIDS,\n    SPDRP_UNUSED0,\n    SPDRP_SERVICE,\n    SPDRP_UNUSED1,\n    SPDRP_UNUSED2,\n    SPDRP_CLASS,\n    SPDRP_CLASSGUID,\n    SPDRP_DRIVER,\n    SPDRP_CONFIGFLAGS,\n    SPDRP_MFG,\n    SPDRP_FRIENDLYNAME,\n    SPDRP_LOCATION_INFORMATION,\n    SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,\n    SPDRP_CAPABILITIES,\n    SPDRP_UI_NUMBER,\n    SPDRP_UPPERFILTERS,\n    SPDRP_LOWERFILTERS,\n    SPDRP_BUSTYPEGUID,\n    SPDRP_LEGACYBUSTYPE,\n    SPDRP_BUSNUMBER,\n    SPDRP_ENUMERATOR_NAME,\n    SPDRP_SECURITY,\n    SPDRP_SECURITY_SDS,\n    SPDRP_DEVTYPE,\n    SPDRP_EXCLUSIVE,\n    SPDRP_CHARACTERISTICS,\n    SPDRP_ADDRESS, // = 28\n    SPDRP_UI_NUMBER_DESC_FORMAT = 30,\n    SPDRP_MAXIMUM_PROPERTY      = 31\n}\n\nenum : UINT {\n    SPDSL_IGNORE_DISK = 1,\n    SPDSL_DISALLOW_NEGATIVE_ADJUST\n}\n\nenum : UINT {\n    SPFILENOTIFY_STARTQUEUE = 1,\n    SPFILENOTIFY_ENDQUEUE,\n    SPFILENOTIFY_STARTSUBQUEUE,\n    SPFILENOTIFY_ENDSUBQUEUE,\n    SPFILENOTIFY_STARTDELETE,\n    SPFILENOTIFY_ENDDELETE,\n    SPFILENOTIFY_DELETEERROR,\n    SPFILENOTIFY_STARTRENAME,\n    SPFILENOTIFY_ENDRENAME,\n    SPFILENOTIFY_RENAMEERROR,\n    SPFILENOTIFY_STARTCOPY,\n    SPFILENOTIFY_ENDCOPY,\n    SPFILENOTIFY_COPYERROR,\n    SPFILENOTIFY_NEEDMEDIA,\n    SPFILENOTIFY_QUEUESCAN,\n    SPFILENOTIFY_CABINETINFO,\n    SPFILENOTIFY_FILEINCABINET,\n    SPFILENOTIFY_NEEDNEWCABINET,\n    SPFILENOTIFY_FILEEXTRACTED,\n    SPFILENOTIFY_FILEOPDELAYED,\n    SPFILENOTIFY_STARTBACKUP,\n    SPFILENOTIFY_BACKUPERROR,\n    SPFILENOTIFY_ENDBACKUP,\n    SPFILENOTIFY_QUEUESCAN_EX,\n    SPFILENOTIFY_STARTREGISTRATION, // = 25\n    SPFILENOTIFY_ENDREGISTRATION = 32,\n    SPFILENOTIFY_LANGMISMATCH    = 0x00010000,\n    SPFILENOTIFY_TARGETEXISTS    = 0x00020000,\n    SPFILENOTIFY_TARGETNEWER     = 0x00040000\n}\n\nstatic if (_SETUPAPI_VER >= 0x0501) {\n    enum : UINT {\n        SPFILENOTIFY_QUEUESCAN_SIGNERINFO = 0x00000040\n    }\n}\n\nenum : DWORD {\n    SPFILELOG_SYSTEMLOG = 0x00000001,\n    SPFILELOG_OEMFILE   = 0x00000001,\n    SPFILELOG_FORCENEW  = 0x00000002,\n    SPFILELOG_QUERYONLY = 0x00000004\n}\n\nenum : INT {\n    SPFILEQ_FILE_IN_USE        = 0x00000001,\n    SPFILEQ_REBOOT_RECOMMENDED = 0x00000002,\n    SPFILEQ_REBOOT_IN_PROGRESS = 0x00000004\n}\n\nenum : DWORD {\n    SPINT_ACTIVE  = 0x00000001,\n    SPINT_DEFAULT = 0x00000002,\n    SPINT_REMOVED = 0x00000004\n}\n\ndeprecated enum : DWORD {\n    SPID_ACTIVE  = SPINT_ACTIVE,\n    SPID_DEFAULT = SPINT_DEFAULT,\n    SPID_REMOVED = SPINT_REMOVED\n}\n\nenum : UINT {\n    SPINST_LOGCONFIG                = 0x00000001,\n    SPINST_INIFILES                 = 0x00000002,\n    SPINST_REGISTRY                 = 0x00000004,\n    SPINST_INI2REG                  = 0x00000008,\n    SPINST_FILES                    = 0x00000010,\n    SPINST_BITREG                   = 0x00000020,\n    SPINST_REGSVR                   = 0x00000040,\n    SPINST_UNREGSVR                 = 0x00000080,\n    SPINST_PROFILEITEMS             = 0x00000100,\n    SPINST_SINGLESECTION            = 0x00010000,\n    SPINST_LOGCONFIG_IS_FORCED      = 0x00020000,\n    SPINST_LOGCONFIGS_ARE_OVERRIDES = 0x00040000\n}\n\nstatic if (_SETUPAPI_VER >= 0x0501) {\n    enum : UINT {\n        SPINST_COPYINF               = 0x00000200,\n        SPINST_ALL                   = 0x000003ff,\n        SPINST_REGISTERCALLBACKAWARE = 0x00080000\n    }\n} else {\n    enum : UINT {\n        SPINST_ALL = 0x000001ff\n    }\n}\n\nenum : DWORD {\n    SPOST_NONE,\n    SPOST_PATH,\n    SPOST_URL,\n    SPOST_MAX // = 3\n}\n\nenum : DWORD {\n    SPPSR_SELECT_DEVICE_RESOURCES = 1,\n    SPPSR_ENUM_BASIC_DEVICE_PROPERTIES,\n    SPPSR_ENUM_ADV_DEVICE_PROPERTIES\n}\n\nenum : DWORD {\n    SPQ_SCAN_FILE_PRESENCE    = 0x00000001,\n    SPQ_SCAN_FILE_VALIDITY    = 0x00000002,\n    SPQ_SCAN_USE_CALLBACK     = 0x00000004,\n    SPQ_SCAN_USE_CALLBACKEX   = 0x00000008,\n    SPQ_SCAN_INFORM_USER      = 0x00000010,\n    SPQ_SCAN_PRUNE_COPY_QUEUE = 0x00000020\n}\n\nstatic if (_SETUPAPI_VER >= 0x0501) {\n    enum : DWORD {\n        SPQ_SCAN_USE_CALLBACK_SIGNERINFO = 0x00000040,\n        SPQ_SCAN_PRUNE_DELREN            = 0x00000080\n    }\n}\n\nenum : UINT_PTR {\n    SPQ_DELAYED_COPY = 0x00000001\n}\n\nenum : DWORD {\n    SPRDI_FIND_DUPS = 0x00000001,\n}\n\nenum : DWORD {\n    SPSVCINST_TAGTOFRONT               = 0x00000001,\n    SPSVCINST_ASSOCSERVICE             = 0x00000002,\n    SPSVCINST_DELETEEVENTLOGENTRY      = 0x00000004,\n    SPSVCINST_NOCLOBBER_DISPLAYNAME    = 0x00000008,\n    SPSVCINST_NOCLOBBER_STARTTYPE      = 0x00000010,\n    SPSVCINST_NOCLOBBER_ERRORCONTROL   = 0x00000020,\n    SPSVCINST_NOCLOBBER_LOADORDERGROUP = 0x00000040,\n    SPSVCINST_NOCLOBBER_DEPENDENCIES   = 0x00000080,\n    SPSVCINST_NOCLOBBER_DESCRIPTION    = 0x00000100,\n    SPSVCINST_STOPSERVICE              = 0x00000200\n}\n\nstatic if (_SETUPAPI_VER >= 0x0501) {\n    enum : DWORD {\n        SPSVCINST_CLOBBER_SECURITY = 0x00000400\n    }\n}\n\nenum : DWORD {\n    SPWPT_SELECTDEVICE = 0x00000001\n}\n\nenum : DWORD {\n    SPWP_USE_DEVINFO_DATA = 0x00000001\n}\n\nenum : UINT {\n    SRCINFO_PATH = 1,\n    SRCINFO_TAGFILE,\n    SRCINFO_DESCRIPTION,\n    SRCINFO_FLAGS // = 4\n}\n\nenum : DWORD {\n    SRCLIST_TEMPORARY       = 0x00000001,\n    SRCLIST_NOBROWSE        = 0x00000002,\n    SRCLIST_SYSTEM          = 0x00000010,\n    SRCLIST_USER            = 0x00000020,\n    SRCLIST_SYSIFADMIN      = 0x00000040,\n    SRCLIST_SUBDIRS         = 0x00000100,\n    SRCLIST_APPEND          = 0x00000200,\n    SRCLIST_NOSTRIPPLATFORM = 0x00000400\n}\n\nalias PVOID HINF;\nalias PVOID HDSKSPC;\nmixin DECLARE_HANDLE!(\"HDEVINFO\");\nalias PVOID HSPFILEQ;\nalias PVOID HSPFILELOG;\n\nenum SetupFileLogInfo {\n    SetupFileLogSourceFilename,\n    SetupFileLogChecksum,\n    SetupFileLogDiskTagfile,\n    SetupFileLogDiskDescription,\n    SetupFileLogOtherInfo,\n    SetupFileLogMax\n}\n\nversion (Win64)\n    private enum _alignVal = 0;\nelse\n    private enum _alignVal = 1;\n\nstruct INFCONTEXT {\n    PVOID Inf;\n    PVOID CurrentInf;\n    UINT  Section;\n    UINT  Line;\n}\nalias INFCONTEXT* PINFCONTEXT;\n\nmixin AlignedStr!(_alignVal, \"SP_INF_INFORMATION\", q{\n    DWORD InfStyle;\n    DWORD InfCount;\n    BYTE[1] _VersionData;\n    BYTE* VersionData() return { return _VersionData.ptr; }\n});\nalias SP_INF_INFORMATION* PSP_INF_INFORMATION;\n\nstruct SP_ALTPLATFORM_INFO {\n    DWORD cbSize = SP_ALTPLATFORM_INFO.sizeof;\n    DWORD Platform;\n    DWORD MajorVersion;\n    DWORD MinorVersion;\n    WORD  ProcessorArchitecture;\n    WORD  Reserved;\n}\nalias SP_ALTPLATFORM_INFO* PSP_ALTPLATFORM_INFO;\n\nstruct SP_ORIGINAL_FILE_INFO_A {\n    DWORD cbSize = SP_ORIGINAL_FILE_INFO_A.sizeof;\n    CHAR[MAX_PATH] OriginalInfName;\n    CHAR[MAX_PATH] OriginalCatalogName;\n}\nalias SP_ORIGINAL_FILE_INFO_A* PSP_ORIGINAL_FILE_INFO_A;\n\nstruct SP_ORIGINAL_FILE_INFO_W {\n    DWORD cbSize = SP_ORIGINAL_FILE_INFO_W.sizeof;\n    WCHAR[MAX_PATH] OriginalInfName;\n    WCHAR[MAX_PATH] OriginalCatalogName;\n}\nalias SP_ORIGINAL_FILE_INFO_W* PSP_ORIGINAL_FILE_INFO_W;\n\nstruct FILEPATHS_A {\n    PCSTR Target;\n    PCSTR Source;\n    UINT  Win32Error;\n    DWORD Flags;\n}\nalias FILEPATHS_A* PFILEPATHS_A;\n\nstruct FILEPATHS_W {\n    PCWSTR Target;\n    PCWSTR Source;\n    UINT   Win32Error;\n    DWORD  Flags;\n}\nalias FILEPATHS_W* PFILEPATHS_W;\n\nstruct SOURCE_MEDIA_A {\n    PCSTR Reserved;\n    PCSTR Tagfile;\n    PCSTR Description;\n    PCSTR SourcePath;\n    PCSTR SourceFile;\n    DWORD Flags;\n}\nalias SOURCE_MEDIA_A* PSOURCE_MEDIA_A;\n\nstruct SOURCE_MEDIA_W {\n    PCWSTR Reserved;\n    PCWSTR Tagfile;\n    PCWSTR Description;\n    PCWSTR SourcePath;\n    PCWSTR SourceFile;\n    DWORD  Flags;\n}\nalias SOURCE_MEDIA_W* PSOURCE_MEDIA_W;\n\nstruct CABINET_INFO_A {\n    PCSTR  CabinetPath;\n    PCSTR  CabinetFile;\n    PCSTR  DiskName;\n    USHORT SetId;\n    USHORT CabinetNumber;\n}\nalias CABINET_INFO_A* PCABINET_INFO_A;\n\nstruct CABINET_INFO_W {\n    PCWSTR CabinetPath;\n    PCWSTR CabinetFile;\n    PCWSTR DiskName;\n    USHORT SetId;\n    USHORT CabinetNumber;\n}\nalias CABINET_INFO_W* PCABINET_INFO_W;\n\nmixin AlignedStr!(_alignVal, \"FILE_IN_CABINET_INFO_A\", q{\n    PCSTR NameInCabinet;\n    DWORD FileSize;\n    DWORD Win32Error;\n    WORD  DosDate;\n    WORD  DosTime;\n    WORD  DosAttribs;\n    CHAR[MAX_PATH] FullTargetName;\n});\nalias FILE_IN_CABINET_INFO_A* PFILE_IN_CABINET_INFO_A;\n\nmixin AlignedStr!(_alignVal, \"FILE_IN_CABINET_INFO_W\", q{\n    PCWSTR NameInCabinet;\n    DWORD  FileSize;\n    DWORD  Win32Error;\n    WORD   DosDate;\n    WORD   DosTime;\n    WORD   DosAttribs;\n    WCHAR[MAX_PATH] FullTargetName;\n});\nalias FILE_IN_CABINET_INFO_W* PFILE_IN_CABINET_INFO_W;\n\nstruct SP_FILE_COPY_PARAMS_A {\n    DWORD    cbSize = SP_FILE_COPY_PARAMS_A.sizeof;\n    HSPFILEQ QueueHandle;\n    PCSTR    SourceRootPath;\n    PCSTR    SourcePath;\n    PCSTR    SourceFilename;\n    PCSTR    SourceDescription;\n    PCSTR    SourceTagfile;\n    PCSTR    TargetDirectory;\n    PCSTR    TargetFilename;\n    DWORD    CopyStyle;\n    HINF     LayoutInf;\n    PCSTR    SecurityDescriptor;\n}\nalias SP_FILE_COPY_PARAMS_A* PSP_FILE_COPY_PARAMS_A;\n\nstruct SP_FILE_COPY_PARAMS_W {\n    DWORD    cbSize = SP_FILE_COPY_PARAMS_W.sizeof;\n    HSPFILEQ QueueHandle;\n    PCWSTR   SourceRootPath;\n    PCWSTR   SourcePath;\n    PCWSTR   SourceFilename;\n    PCWSTR   SourceDescription;\n    PCWSTR   SourceTagfile;\n    PCWSTR   TargetDirectory;\n    PCWSTR   TargetFilename;\n    DWORD    CopyStyle;\n    HINF     LayoutInf;\n    PCWSTR   SecurityDescriptor;\n}\nalias SP_FILE_COPY_PARAMS_W* PSP_FILE_COPY_PARAMS_W;\n\nstruct SP_DEVINFO_DATA {\n    DWORD     cbSize = SP_DEVINFO_DATA.sizeof;\n    GUID      ClassGuid;\n    DWORD     DevInst;\n    ULONG_PTR Reserved;\n}\nalias SP_DEVINFO_DATA* PSP_DEVINFO_DATA;\n\nmixin AlignedStr!(_alignVal, \"SP_DEVICE_INTERFACE_DATA\", q{\n    DWORD     cbSize = SP_DEVICE_INTERFACE_DATA.sizeof;\n    GUID      InterfaceClassGuid;\n    DWORD     Flags;\n    ULONG_PTR Reserved;\n});\nalias SP_DEVICE_INTERFACE_DATA* PSP_DEVICE_INTERFACE_DATA;\ndeprecated alias SP_DEVICE_INTERFACE_DATA SP_INTERFACE_DEVICE_DATA;\ndeprecated alias SP_DEVICE_INTERFACE_DATA* PSP_INTERFACE_DEVICE_DATA;\n\nmixin AlignedStr!(_alignVal, \"SP_DEVICE_INTERFACE_DETAIL_DATA_A\", q{\n    DWORD cbSize = SP_DEVICE_INTERFACE_DETAIL_DATA_A.sizeof;\n    CHAR[1] _DevicePath;\n    CHAR* DevicePath() return { return _DevicePath.ptr; }\n});\nalias SP_DEVICE_INTERFACE_DETAIL_DATA_A* PSP_DEVICE_INTERFACE_DETAIL_DATA_A;\n\nmixin AlignedStr!(_alignVal, \"SP_DEVICE_INTERFACE_DETAIL_DATA_W\", q{\n    DWORD  cbSize = SP_DEVICE_INTERFACE_DETAIL_DATA_W.sizeof;\n    WCHAR[1] _DevicePath;\n    WCHAR* DevicePath() return { return _DevicePath.ptr; }\n});\nalias SP_DEVICE_INTERFACE_DETAIL_DATA_W* PSP_DEVICE_INTERFACE_DETAIL_DATA_W;\n\ndeprecated alias SP_DEVICE_INTERFACE_DETAIL_DATA_A SP_INTERFACE_DEVICE_DETAIL_DATA_A;\ndeprecated alias SP_DEVICE_INTERFACE_DETAIL_DATA_A* PSP_INTERFACE_DEVICE_DETAIL_DATA_A;\ndeprecated alias SP_DEVICE_INTERFACE_DETAIL_DATA_W SP_INTERFACE_DEVICE_DETAIL_DATA_W;\ndeprecated alias SP_DEVICE_INTERFACE_DETAIL_DATA_W* PSP_INTERFACE_DEVICE_DETAIL_DATA_W;\n\nmixin AlignedStr!(_alignVal, \"SP_DEVINFO_LIST_DETAIL_DATA_A\", q{\n    DWORD  cbSize = SP_DEVINFO_LIST_DETAIL_DATA_A.sizeof;\n    GUID   ClassGuid;\n    HANDLE RemoteMachineHandle;\n    CHAR[SP_MAX_MACHINENAME_LENGTH] RemoteMachineName;\n});\nalias SP_DEVINFO_LIST_DETAIL_DATA_A* PSP_DEVINFO_LIST_DETAIL_DATA_A;\n\nmixin AlignedStr!(_alignVal, \"SP_DEVINFO_LIST_DETAIL_DATA_W\", q{\n    DWORD  cbSize = SP_DEVINFO_LIST_DETAIL_DATA_W.sizeof;\n    GUID   ClassGuid;\n    HANDLE RemoteMachineHandle;\n    WCHAR[SP_MAX_MACHINENAME_LENGTH] RemoteMachineName;\n});\nalias SP_DEVINFO_LIST_DETAIL_DATA_W* PSP_DEVINFO_LIST_DETAIL_DATA_W;\n\nextern(Windows) alias UINT function(PVOID, UINT, UINT_PTR, UINT_PTR) PSP_FILE_CALLBACK_A;\nextern(Windows) alias UINT function(PVOID, UINT, UINT_PTR, UINT_PTR) PSP_FILE_CALLBACK_W;\n\nstruct SP_DEVINSTALL_PARAMS_A {\n    DWORD               cbSize = SP_DEVINSTALL_PARAMS_A.sizeof;\n    DWORD               Flags;\n    DWORD               FlagsEx;\n    HWND                hwndParent;\n    PSP_FILE_CALLBACK_A InstallMsgHandler;\n    PVOID               InstallMsgHandlerContext;\n    HSPFILEQ            FileQueue;\n    ULONG_PTR           ClassInstallReserved;\n    DWORD               Reserved;\n    CHAR[MAX_PATH]      DriverPath;\n}\nalias SP_DEVINSTALL_PARAMS_A* PSP_DEVINSTALL_PARAMS_A;\n\nstruct SP_DEVINSTALL_PARAMS_W {\n    DWORD               cbSize = SP_DEVINSTALL_PARAMS_W.sizeof;\n    DWORD               Flags;\n    DWORD               FlagsEx;\n    HWND                hwndParent;\n    PSP_FILE_CALLBACK_W InstallMsgHandler;\n    PVOID               InstallMsgHandlerContext;\n    HSPFILEQ            FileQueue;\n    ULONG_PTR           ClassInstallReserved;\n    DWORD               Reserved;\n    WCHAR[MAX_PATH]     DriverPath;\n}\nalias SP_DEVINSTALL_PARAMS_W* PSP_DEVINSTALL_PARAMS_W;\n\nstruct SP_CLASSINSTALL_HEADER {\n    DWORD       cbSize = SP_CLASSINSTALL_HEADER.sizeof;\n    DI_FUNCTION InstallFunction;\n}\nalias SP_CLASSINSTALL_HEADER* PSP_CLASSINSTALL_HEADER;\n\nstruct SP_ENABLECLASS_PARAMS {\n    SP_CLASSINSTALL_HEADER ClassInstallHeader;\n    GUID                   ClassGuid;\n    DWORD                  EnableMessage;\n}\nalias SP_ENABLECLASS_PARAMS* PSP_ENABLECLASS_PARAMS;\n\nstruct SP_MOVEDEV_PARAMS {\n    SP_CLASSINSTALL_HEADER ClassInstallHeader;\n    SP_DEVINFO_DATA        SourceDeviceInfoData;\n}\nalias SP_MOVEDEV_PARAMS* PSP_MOVEDEV_PARAMS;\n\nstruct SP_PROPCHANGE_PARAMS {\n    SP_CLASSINSTALL_HEADER ClassInstallHeader;\n    DWORD                  StateChange;\n    DWORD                  Scope;\n    DWORD                  HwProfile;\n}\nalias SP_PROPCHANGE_PARAMS* PSP_PROPCHANGE_PARAMS;\n\nstruct SP_REMOVEDEVICE_PARAMS {\n    SP_CLASSINSTALL_HEADER ClassInstallHeader;\n    DWORD                  Scope;\n    DWORD                  HwProfile;\n}\nalias SP_REMOVEDEVICE_PARAMS* PSP_REMOVEDEVICE_PARAMS;\n\nstruct SP_UNREMOVEDEVICE_PARAMS {\n    SP_CLASSINSTALL_HEADER ClassInstallHeader;\n    DWORD                  Scope;\n    DWORD                  HwProfile;\n}\nalias SP_UNREMOVEDEVICE_PARAMS* PSP_UNREMOVEDEVICE_PARAMS;\n\nstruct SP_SELECTDEVICE_PARAMS_A {\n    SP_CLASSINSTALL_HEADER    ClassInstallHeader;\n    CHAR[MAX_TITLE_LEN]       Title;\n    CHAR[MAX_INSTRUCTION_LEN] Instructions;\n    CHAR[MAX_LABEL_LEN]       ListLabel;\n    CHAR[MAX_SUBTITLE_LEN]    SubTitle;\n    BYTE[2]                   Reserved;\n}\nalias SP_SELECTDEVICE_PARAMS_A* PSP_SELECTDEVICE_PARAMS_A;\n\nstruct SP_SELECTDEVICE_PARAMS_W {\n    SP_CLASSINSTALL_HEADER     ClassInstallHeader;\n    WCHAR[MAX_TITLE_LEN]       Title;\n    WCHAR[MAX_INSTRUCTION_LEN] Instructions;\n    WCHAR[MAX_LABEL_LEN]       ListLabel;\n    WCHAR[MAX_SUBTITLE_LEN]    SubTitle;\n}\nalias SP_SELECTDEVICE_PARAMS_W* PSP_SELECTDEVICE_PARAMS_W;\n\nextern(Windows) alias BOOL function(PVOID, DWORD) PDETECT_PROGRESS_NOTIFY;\n\nstruct SP_DETECTDEVICE_PARAMS {\n    SP_CLASSINSTALL_HEADER  ClassInstallHeader;\n    PDETECT_PROGRESS_NOTIFY DetectProgressNotify;\n    PVOID                   ProgressNotifyParam;\n}\nalias SP_DETECTDEVICE_PARAMS* PSP_DETECTDEVICE_PARAMS;\n\nstruct SP_INSTALLWIZARD_DATA {\n    SP_CLASSINSTALL_HEADER ClassInstallHeader;\n    DWORD                  Flags;\n    HPROPSHEETPAGE[MAX_INSTALLWIZARD_DYNAPAGES] DynamicPages;\n    DWORD                  NumDynamicPages;\n    DWORD                  DynamicPageFlags;\n    DWORD                  PrivateFlags;\n    LPARAM                 PrivateData;\n    HWND                   hwndWizardDlg;\n}\nalias SP_INSTALLWIZARD_DATA* PSP_INSTALLWIZARD_DATA;\n\nstruct SP_NEWDEVICEWIZARD_DATA {\n    SP_CLASSINSTALL_HEADER ClassInstallHeader;\n    DWORD                  Flags;\n    HPROPSHEETPAGE[MAX_INSTALLWIZARD_DYNAPAGES]  DynamicPages;\n    DWORD                  NumDynamicPages;\n    HWND                   hwndWizardDlg;\n}\nalias SP_NEWDEVICEWIZARD_DATA* PSP_NEWDEVICEWIZARD_DATA;\nalias SP_NEWDEVICEWIZARD_DATA SP_ADDPROPERTYPAGE_DATA;\nalias SP_NEWDEVICEWIZARD_DATA* PSP_ADDPROPERTYPAGE_DATA;\n\nstruct SP_TROUBLESHOOTER_PARAMS_A {\n    SP_CLASSINSTALL_HEADER ClassInstallHeader;\n    CHAR[MAX_PATH]         ChmFile;\n    CHAR[MAX_PATH]         HtmlTroubleShooter;\n}\nalias SP_TROUBLESHOOTER_PARAMS_A* PSP_TROUBLESHOOTER_PARAMS_A;\n\nstruct SP_TROUBLESHOOTER_PARAMS_W {\n    SP_CLASSINSTALL_HEADER ClassInstallHeader;\n    WCHAR[MAX_PATH]        ChmFile;\n    WCHAR[MAX_PATH]        HtmlTroubleShooter;\n}\nalias SP_TROUBLESHOOTER_PARAMS_W* PSP_TROUBLESHOOTER_PARAMS_W;\n\nstruct SP_POWERMESSAGEWAKE_PARAMS_A {\n    SP_CLASSINSTALL_HEADER ClassInstallHeader;\n    CHAR[LINE_LEN*2]       PowerMessageWake;\n}\nalias SP_POWERMESSAGEWAKE_PARAMS_A* PSP_POWERMESSAGEWAKE_PARAMS_A;\n\nstruct SP_POWERMESSAGEWAKE_PARAMS_W {\n    SP_CLASSINSTALL_HEADER ClassInstallHeader;\n    WCHAR[LINE_LEN*2]      PowerMessageWake;\n}\nalias SP_POWERMESSAGEWAKE_PARAMS_W* PSP_POWERMESSAGEWAKE_PARAMS_W;\n\nmixin AlignedStr!(_alignVal, \"SP_DRVINFO_DATA_V2_A\", q{\n    DWORD          cbSize = SP_DRVINFO_DATA_V2_A.sizeof;\n    DWORD          DriverType;\n    ULONG_PTR      Reserved;\n    CHAR[LINE_LEN] Description;\n    CHAR[LINE_LEN] MfgName;\n    CHAR[LINE_LEN] ProviderName;\n    FILETIME       DriverDate;\n    DWORDLONG      DriverVersion;\n});\nalias SP_DRVINFO_DATA_V2_A* PSP_DRVINFO_DATA_V2_A;\n\nmixin AlignedStr!(_alignVal, \"SP_DRVINFO_DATA_V2_W\", q{\n    DWORD           cbSize = SP_DRVINFO_DATA_V2_A.sizeof;\n    DWORD           DriverType;\n    ULONG_PTR       Reserved;\n    WCHAR[LINE_LEN] Description;\n    WCHAR[LINE_LEN] MfgName;\n    WCHAR[LINE_LEN] ProviderName;\n    FILETIME        DriverDate;\n    DWORDLONG       DriverVersion;\n});\nalias SP_DRVINFO_DATA_V2_W* PSP_DRVINFO_DATA_V2_W;\n\nstruct SP_DRVINFO_DATA_V1_A {\n    DWORD          cbSize = SP_DRVINFO_DATA_V1_A.sizeof;\n    DWORD          DriverType;\n    ULONG_PTR      Reserved;\n    CHAR[LINE_LEN] Description;\n    CHAR[LINE_LEN] MfgName;\n    CHAR[LINE_LEN] ProviderName;\n}\nalias SP_DRVINFO_DATA_V1_A* PSP_DRVINFO_DATA_V1_A;\n\nstruct SP_DRVINFO_DATA_V1_W {\n    DWORD           cbSize = SP_DRVINFO_DATA_V1_W.sizeof;\n    DWORD           DriverType;\n    ULONG_PTR       Reserved;\n    WCHAR[LINE_LEN] Description;\n    WCHAR[LINE_LEN] MfgName;\n    WCHAR[LINE_LEN] ProviderName;\n}\nalias SP_DRVINFO_DATA_V1_W* PSP_DRVINFO_DATA_V1_W;\n\nversion (Unicode) {\n    alias SP_DRVINFO_DATA_V1_W SP_DRVINFO_DATA_V1;\n    alias SP_DRVINFO_DATA_V2_W SP_DRVINFO_DATA_V2;\n} else {\n    alias SP_DRVINFO_DATA_V1_A SP_DRVINFO_DATA_V1;\n    alias SP_DRVINFO_DATA_V2_A SP_DRVINFO_DATA_V2;\n}\nalias SP_DRVINFO_DATA_V1* PSP_DRVINFO_DATA_V1;\nalias SP_DRVINFO_DATA_V2* PSP_DRVINFO_DATA_V2;\n\nstatic if (USE_SP_DRVINFO_DATA_V1) {\n    alias SP_DRVINFO_DATA_V1_A SP_DRVINFO_DATA_A;\n    alias SP_DRVINFO_DATA_V1_A* PSP_DRVINFO_DATA_A;\n    alias SP_DRVINFO_DATA_V1_W SP_DRVINFO_DATA_W;\n    alias SP_DRVINFO_DATA_V1_W* PSP_DRVINFO_DATA_W;\n    alias SP_DRVINFO_DATA_V1 SP_DRVINFO_DATA;\n    alias SP_DRVINFO_DATA_V1* PSP_DRVINFO_DATA;\n} else {\n    alias SP_DRVINFO_DATA_V2_A SP_DRVINFO_DATA_A;\n    alias SP_DRVINFO_DATA_V2_A* PSP_DRVINFO_DATA_A;\n    alias SP_DRVINFO_DATA_V2_W SP_DRVINFO_DATA_W;\n    alias SP_DRVINFO_DATA_V2_W* PSP_DRVINFO_DATA_W;\n    alias SP_DRVINFO_DATA_V2 SP_DRVINFO_DATA;\n    alias SP_DRVINFO_DATA_V2* PSP_DRVINFO_DATA;\n}\n\nextern(Windows) alias DWORD function(HDEVINFO, PSP_DEVINFO_DATA, PSP_DEVINFO_DATA, PVOID) PSP_DETSIG_CMPPROC;\n\nmixin AlignedStr!(_alignVal, \"SP_DRVINFO_DETAIL_DATA_A\", q{\n    DWORD          cbSize = SP_DRVINFO_DETAIL_DATA_A.sizeof;\n    FILETIME       InfDate;\n    DWORD          CompatIDsOffset;\n    DWORD          CompatIDsLength;\n    ULONG_PTR      Reserved;\n    CHAR[LINE_LEN] SectionName;\n    CHAR[MAX_PATH] InfFileName;\n    CHAR[LINE_LEN] DrvDescription;\n    CHAR[1]        _HardwareID;\n    CHAR*          HardwareID() return { return _HardwareID.ptr; }\n});\nalias SP_DRVINFO_DETAIL_DATA_A* PSP_DRVINFO_DETAIL_DATA_A;\n\nmixin AlignedStr!(_alignVal, \"SP_DRVINFO_DETAIL_DATA_W\", q{\n    DWORD           cbSize = SP_DRVINFO_DETAIL_DATA_W.sizeof;\n    FILETIME        InfDate;\n    DWORD           CompatIDsOffset;\n    DWORD           CompatIDsLength;\n    ULONG_PTR       Reserved;\n    WCHAR[LINE_LEN] SectionName;\n    WCHAR[MAX_PATH] InfFileName;\n    WCHAR[LINE_LEN] DrvDescription;\n    WCHAR[1]        _HardwareID;\n    WCHAR*          HardwareID() return { return _HardwareID.ptr; }\n});\nalias SP_DRVINFO_DETAIL_DATA_W* PSP_DRVINFO_DETAIL_DATA_W;\n\nstruct SP_DRVINSTALL_PARAMS {\n    DWORD cbSize = SP_DRVINSTALL_PARAMS.sizeof;\n    DWORD Rank;\n    DWORD Flags;\n    DWORD_PTR PrivateData;\n    DWORD Reserved;\n}\nalias SP_DRVINSTALL_PARAMS* PSP_DRVINSTALL_PARAMS;\n\nstruct COINSTALLER_CONTEXT_DATA {\n    BOOL  PostProcessing;\n    DWORD InstallResult;\n    PVOID PrivateData;\n}\nalias COINSTALLER_CONTEXT_DATA* PCOINSTALLER_CONTEXT_DATA;\n\nstruct SP_CLASSIMAGELIST_DATA {\n    DWORD      cbSize = SP_CLASSIMAGELIST_DATA.sizeof;\n    HIMAGELIST ImageList;\n    ULONG_PTR  Reserved;\n}\nalias SP_CLASSIMAGELIST_DATA* PSP_CLASSIMAGELIST_DATA;\n\nstruct SP_PROPSHEETPAGE_REQUEST {\n    DWORD            cbSize = SP_PROPSHEETPAGE_REQUEST.sizeof;\n    DWORD            PageRequested;\n    HDEVINFO         DeviceInfoSet;\n    PSP_DEVINFO_DATA DeviceInfoData;\n}\nalias SP_PROPSHEETPAGE_REQUEST* PSP_PROPSHEETPAGE_REQUEST;\n\nstruct SP_BACKUP_QUEUE_PARAMS_A {\n    DWORD cbSize = SP_BACKUP_QUEUE_PARAMS_A.sizeof;\n    CHAR[MAX_PATH] FullInfPath;\n    INT FilenameOffset;\n}\nalias SP_BACKUP_QUEUE_PARAMS_A* PSP_BACKUP_QUEUE_PARAMS_A;\n\nstruct SP_BACKUP_QUEUE_PARAMS_W {\n    DWORD cbSize = SP_BACKUP_QUEUE_PARAMS_W.sizeof;\n    WCHAR[MAX_PATH] FullInfPath;\n    INT FilenameOffset;\n}\nalias SP_BACKUP_QUEUE_PARAMS_W* PSP_BACKUP_QUEUE_PARAMS_W;\n\nversion (Unicode) {\n    alias SP_ORIGINAL_FILE_INFO_W SP_ORIGINAL_FILE_INFO;\n    alias SP_ORIGINAL_FILE_INFO_W* PSP_ORIGINAL_FILE_INFO;\n    alias FILEPATHS_W FILEPATHS;\n    alias FILEPATHS_W* PFILEPATHS;\n    alias SOURCE_MEDIA_W SOURCE_MEDIA;\n    alias SOURCE_MEDIA_W* PSOURCE_MEDIA;\n    alias CABINET_INFO_W CABINET_INFO;\n    alias CABINET_INFO_W* PCABINET_INFO;\n    alias FILE_IN_CABINET_INFO_W FILE_IN_CABINET_INFO;\n    alias FILE_IN_CABINET_INFO_W* PFILE_IN_CABINET_INFO;\n    alias SP_FILE_COPY_PARAMS_W SP_FILE_COPY_PARAMS;\n    alias SP_FILE_COPY_PARAMS_W* PSP_FILE_COPY_PARAMS;\n    alias SP_DEVICE_INTERFACE_DETAIL_DATA_W SP_DEVICE_INTERFACE_DETAIL_DATA;\n    alias SP_DEVICE_INTERFACE_DETAIL_DATA_W* PSP_DEVICE_INTERFACE_DETAIL_DATA;\n    deprecated {\n        alias SP_DEVICE_INTERFACE_DETAIL_DATA_W SP_INTERFACE_DEVICE_DETAIL_DATA;\n        alias SP_DEVICE_INTERFACE_DETAIL_DATA_W* PSP_INTERFACE_DEVICE_DETAIL_DATA;\n    }\n    alias SP_DEVINFO_LIST_DETAIL_DATA_W SP_DEVINFO_LIST_DETAIL_DATA;\n    alias SP_DEVINFO_LIST_DETAIL_DATA_W *PSP_DEVINFO_LIST_DETAIL_DATA;\n    alias SP_DEVINSTALL_PARAMS_W SP_DEVINSTALL_PARAMS;\n    alias SP_DEVINSTALL_PARAMS_W* PSP_DEVINSTALL_PARAMS;\n    alias SP_SELECTDEVICE_PARAMS_W SP_SELECTDEVICE_PARAMS;\n    alias SP_SELECTDEVICE_PARAMS_W* PSP_SELECTDEVICE_PARAMS;\n    alias SP_TROUBLESHOOTER_PARAMS_W SP_TROUBLESHOOTER_PARAMS;\n    alias SP_TROUBLESHOOTER_PARAMS_W* PSP_TROUBLESHOOTER_PARAMS;\n    alias SP_POWERMESSAGEWAKE_PARAMS_W SP_POWERMESSAGEWAKE_PARAMS;\n    alias SP_POWERMESSAGEWAKE_PARAMS_W* PSP_POWERMESSAGEWAKE_PARAMS;\n    alias SP_DRVINFO_DETAIL_DATA_W SP_DRVINFO_DETAIL_DATA;\n    alias SP_DRVINFO_DETAIL_DATA_W* PSP_DRVINFO_DETAIL_DATA;\n    alias SP_BACKUP_QUEUE_PARAMS_W SP_BACKUP_QUEUE_PARAMS;\n    alias SP_BACKUP_QUEUE_PARAMS_W* PSP_BACKUP_QUEUE_PARAMS;\n} else {\n    alias SP_ORIGINAL_FILE_INFO_A SP_ORIGINAL_FILE_INFO;\n    alias SP_ORIGINAL_FILE_INFO_A* PSP_ORIGINAL_FILE_INFO;\n    alias FILEPATHS_A FILEPATHS;\n    alias FILEPATHS_A* PFILEPATHS;\n    alias SOURCE_MEDIA_A SOURCE_MEDIA;\n    alias SOURCE_MEDIA_A* PSOURCE_MEDIA;\n    alias CABINET_INFO_A CABINET_INFO;\n    alias CABINET_INFO_A* PCABINET_INFO;\n    alias FILE_IN_CABINET_INFO_A FILE_IN_CABINET_INFO;\n    alias FILE_IN_CABINET_INFO_A* PFILE_IN_CABINET_INFO;\n    alias SP_FILE_COPY_PARAMS_A SP_FILE_COPY_PARAMS;\n    alias SP_FILE_COPY_PARAMS_A* PSP_FILE_COPY_PARAMS;\n    alias SP_DEVICE_INTERFACE_DETAIL_DATA_A SP_DEVICE_INTERFACE_DETAIL_DATA;\n    alias SP_DEVICE_INTERFACE_DETAIL_DATA_A* PSP_DEVICE_INTERFACE_DETAIL_DATA;\n    deprecated {\n        alias SP_DEVICE_INTERFACE_DETAIL_DATA_A SP_INTERFACE_DEVICE_DETAIL_DATA;\n        alias SP_DEVICE_INTERFACE_DETAIL_DATA_A* PSP_INTERFACE_DEVICE_DETAIL_DATA;\n    }\n    alias SP_DEVINFO_LIST_DETAIL_DATA_A SP_DEVINFO_LIST_DETAIL_DATA;\n    alias SP_DEVINFO_LIST_DETAIL_DATA_A* PSP_DEVINFO_LIST_DETAIL_DATA;\n    alias SP_DEVINSTALL_PARAMS_A SP_DEVINSTALL_PARAMS;\n    alias SP_DEVINSTALL_PARAMS_A* PSP_DEVINSTALL_PARAMS;\n    alias SP_SELECTDEVICE_PARAMS_A SP_SELECTDEVICE_PARAMS;\n    alias SP_SELECTDEVICE_PARAMS_A* PSP_SELECTDEVICE_PARAMS;\n    alias SP_TROUBLESHOOTER_PARAMS_A SP_TROUBLESHOOTER_PARAMS;\n    alias SP_TROUBLESHOOTER_PARAMS_A* PSP_TROUBLESHOOTER_PARAMS;\n    alias SP_POWERMESSAGEWAKE_PARAMS_A SP_POWERMESSAGEWAKE_PARAMS;\n    alias SP_POWERMESSAGEWAKE_PARAMS_A* PSP_POWERMESSAGEWAKE_PARAMS;\n    alias SP_DRVINFO_DETAIL_DATA_A SP_DRVINFO_DETAIL_DATA;\n    alias SP_DRVINFO_DETAIL_DATA_A* PSP_DRVINFO_DETAIL_DATA;\n    alias SP_BACKUP_QUEUE_PARAMS_A SP_BACKUP_QUEUE_PARAMS;\n    alias SP_BACKUP_QUEUE_PARAMS_A* PSP_BACKUP_QUEUE_PARAMS;\n}\n\nextern (Windows) {\n    BOOL SetupAddInstallSectionToDiskSpaceListA(HDSKSPC, HINF, HINF, PCSTR, PVOID, UINT);\n    BOOL SetupAddInstallSectionToDiskSpaceListW(HDSKSPC, HINF, HINF, PCWSTR, PVOID, UINT);\n    BOOL SetupAddSectionToDiskSpaceListA(HDSKSPC, HINF, HINF, PCSTR, UINT, PVOID, UINT);\n    BOOL SetupAddSectionToDiskSpaceListW(HDSKSPC, HINF, HINF, PCWSTR, UINT, PVOID, UINT);\n    BOOL SetupAddToDiskSpaceListA(HDSKSPC, PCSTR, LONGLONG, UINT, PVOID, UINT);\n    BOOL SetupAddToDiskSpaceListW(HDSKSPC, PCWSTR, LONGLONG, UINT, PVOID, UINT);\n    BOOL SetupAddToSourceListA(DWORD, PCSTR);\n    BOOL SetupAddToSourceListW(DWORD, PCWSTR);\n    BOOL SetupQuerySourceListA(DWORD, PCSTR**List, PUINT);\n    BOOL SetupQuerySourceListW(DWORD, PCWSTR**List, PUINT);\n    BOOL SetupFreeSourceListA(PCSTR**List, UINT);\n    BOOL SetupFreeSourceListW(PCWSTR**List, UINT);\n    BOOL SetupAdjustDiskSpaceListA(HDSKSPC, LPCSTR, LONGLONG, PVOID, UINT);\n    BOOL SetupAdjustDiskSpaceListW(HDSKSPC, LPCWSTR, LONGLONG, PVOID, UINT);\n    UINT SetupBackupErrorA(HWND, PCSTR, PCSTR, PCSTR, UINT, DWORD);\n    UINT SetupBackupErrorW(HWND, PCWSTR, PCWSTR, PCWSTR, UINT, DWORD);\n    BOOL SetupCancelTemporary();\n    BOOL SetupCloseFileQueue(HSPFILEQ);\n    VOID SetupCloseInfFile(HINF);\n    VOID SetupCloseLog();\n    BOOL SetupCommitFileQueueA(HWND, HSPFILEQ, PSP_FILE_CALLBACK_A, PVOID);\n    BOOL SetupCommitFileQueueW(HWND, HSPFILEQ, PSP_FILE_CALLBACK_W, PVOID);\n    UINT SetupCopyErrorA(HWND, PCSTR, PCSTR, PCSTR, PCSTR, PCSTR, UINT, DWORD, PSTR, DWORD, PDWORD);\n    UINT SetupCopyErrorW(HWND, PCWSTR, PCWSTR, PCWSTR, PCWSTR, PCWSTR, UINT, DWORD, PWSTR, DWORD, PDWORD);\n    BOOL SetupCopyOEMInfA(PCSTR, PCSTR, DWORD, DWORD, PSTR, DWORD, PDWORD, PSTR*);\n    BOOL SetupCopyOEMInfW(PCWSTR, PCWSTR, DWORD, DWORD, PWSTR, DWORD, PDWORD, PWSTR*);\n    HDSKSPC SetupCreateDiskSpaceListA(PVOID, DWORD, UINT);\n    HDSKSPC SetupCreateDiskSpaceListW(PVOID, DWORD, UINT);\n    DWORD SetupDecompressOrCopyFileA(PCSTR, PCSTR, PUINT);\n    DWORD SetupDecompressOrCopyFileW(PCWSTR, PCWSTR, PUINT);\n    UINT SetupDefaultQueueCallbackA(PVOID, UINT, UINT_PTR, UINT_PTR);\n    UINT SetupDefaultQueueCallbackW(PVOID, UINT, UINT_PTR, UINT_PTR);\n    UINT SetupDeleteErrorA(HWND, PCSTR, PCSTR, UINT, DWORD);\n    UINT SetupDeleteErrorW(HWND, PCWSTR, PCWSTR, UINT, DWORD);\n    BOOL SetupDestroyDiskSpaceList(HDSKSPC);\n    BOOL SetupDiAskForOEMDisk(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiBuildClassInfoList(DWORD, LPGUID, DWORD, PDWORD);\n    BOOL SetupDiBuildClassInfoListExA(DWORD, LPGUID, DWORD, PDWORD, PCSTR, PVOID);\n    BOOL SetupDiBuildClassInfoListExW(DWORD, LPGUID, DWORD, PDWORD, PCWSTR, PVOID);\n    BOOL SetupDiBuildDriverInfoList(HDEVINFO, PSP_DEVINFO_DATA, DWORD);\n    BOOL SetupDiCallClassInstaller(DI_FUNCTION, HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiCancelDriverInfoSearch(HDEVINFO);\n    BOOL SetupDiChangeState(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiClassGuidsFromNameA(PCSTR, LPGUID, DWORD, PDWORD);\n    BOOL SetupDiClassGuidsFromNameW(PCWSTR, LPGUID, DWORD, PDWORD);\n    BOOL SetupDiClassGuidsFromNameExA(PCSTR, LPGUID, DWORD, PDWORD, PCSTR, PVOID);\n    BOOL SetupDiClassGuidsFromNameExW(PCWSTR, LPGUID, DWORD, PDWORD, PCWSTR, PVOID);\n    BOOL SetupDiClassNameFromGuidA(const(GUID)*, PSTR, DWORD, PDWORD);\n    BOOL SetupDiClassNameFromGuidW(const(GUID)*, PWSTR, DWORD, PDWORD);\n    BOOL SetupDiClassNameFromGuidExA(const(GUID)*, PSTR, DWORD, PDWORD, PCSTR, PVOID);\n    BOOL SetupDiClassNameFromGuidExW(const(GUID)*, PWSTR, DWORD, PDWORD, PCWSTR, PVOID);\n    BOOL SetupDiCreateDeviceInfoA(HDEVINFO, PCSTR, const(GUID)*, PCSTR, HWND, DWORD, PSP_DEVINFO_DATA);\n    BOOL SetupDiCreateDeviceInfoW(HDEVINFO, PCWSTR, const(GUID)*, PCWSTR, HWND, DWORD, PSP_DEVINFO_DATA);\n    HDEVINFO SetupDiCreateDeviceInfoList(const(GUID)*, HWND);\n    HDEVINFO SetupDiCreateDeviceInfoListExA(const(GUID)*, HWND, PCSTR, PVOID);\n    HDEVINFO SetupDiCreateDeviceInfoListExW(const(GUID)*, HWND, PCWSTR, PVOID);\n    BOOL SetupDiCreateDeviceInterfaceA(HDEVINFO, PSP_DEVINFO_DATA, const(GUID)*, PCSTR, DWORD, PSP_DEVICE_INTERFACE_DATA);\n    BOOL SetupDiCreateDeviceInterfaceW(HDEVINFO, PSP_DEVINFO_DATA, const(GUID)*, PCWSTR, DWORD, PSP_DEVICE_INTERFACE_DATA);\n    HKEY SetupDiCreateDeviceInterfaceRegKeyA(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, REGSAM, HINF, PCSTR);\n    HKEY SetupDiCreateDeviceInterfaceRegKeyW(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, REGSAM, HINF, PCWSTR);\n    HKEY SetupDiCreateDevRegKeyA(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, HINF, PCSTR);\n    HKEY SetupDiCreateDevRegKeyW(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, HINF, PCWSTR);\n    BOOL SetupDiDeleteDeviceInfo(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiDeleteDeviceInterfaceData(HDEVINFO, PSP_DEVICE_INTERFACE_DATA);\n    BOOL SetupDiDeleteDeviceInterfaceRegKey(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD);\n    BOOL SetupDiDeleteDevRegKey(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD);\n    BOOL SetupDiDestroyClassImageList(PSP_CLASSIMAGELIST_DATA);\n    BOOL SetupDiDestroyDeviceInfoList(HDEVINFO);\n    BOOL SetupDiDestroyDriverInfoList(HDEVINFO, PSP_DEVINFO_DATA, DWORD);\n    INT SetupDiDrawMiniIcon(HDC, RECT, INT, DWORD);\n    BOOL SetupDiEnumDeviceInfo(HDEVINFO, DWORD, PSP_DEVINFO_DATA);\n    BOOL SetupDiEnumDeviceInterfaces(HDEVINFO, PSP_DEVINFO_DATA, const(GUID)*, DWORD, PSP_DEVICE_INTERFACE_DATA);\n    BOOL SetupDiEnumDriverInfoA(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, PSP_DRVINFO_DATA_A);\n    BOOL SetupDiEnumDriverInfoW(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, PSP_DRVINFO_DATA_W);\n    BOOL SetupDiGetActualSectionToInstallA(HINF, PCSTR, PSTR, DWORD, PDWORD, PSTR*);\n    BOOL SetupDiGetActualSectionToInstallW(HINF, PCWSTR, PWSTR, DWORD, PDWORD, PWSTR*);\n    BOOL SetupDiGetClassBitmapIndex(const(GUID)*, PINT);\n    BOOL SetupDiGetClassDescriptionA(const(GUID)*, PSTR, DWORD, PDWORD);\n    BOOL SetupDiGetClassDescriptionW(const(GUID)*, PWSTR, DWORD, PDWORD);\n    BOOL SetupDiGetClassDescriptionExA(const(GUID)*, PSTR, DWORD, PDWORD, PCSTR, PVOID);\n    BOOL SetupDiGetClassDescriptionExW(const(GUID)*, PWSTR, DWORD, PDWORD, PCWSTR, PVOID);\n    BOOL SetupDiGetClassDevPropertySheetsA(HDEVINFO, PSP_DEVINFO_DATA, LPPROPSHEETHEADERA, DWORD, PDWORD, DWORD);\n    BOOL SetupDiGetClassDevPropertySheetsW(HDEVINFO, PSP_DEVINFO_DATA, LPPROPSHEETHEADERW, DWORD, PDWORD, DWORD);\n    HDEVINFO SetupDiGetClassDevsA(const(GUID)*, PCSTR, HWND, DWORD);\n    HDEVINFO SetupDiGetClassDevsW(const(GUID)*, PCWSTR, HWND, DWORD);\n    HDEVINFO SetupDiGetClassDevsExA(const(GUID)*, PCSTR, HWND, DWORD, HDEVINFO, PCSTR, PVOID);\n    HDEVINFO SetupDiGetClassDevsExW(const(GUID)*, PCWSTR, HWND, DWORD, HDEVINFO, PCWSTR, PVOID);\n    BOOL SetupDiGetClassImageIndex(PSP_CLASSIMAGELIST_DATA, const(GUID)*, PINT);\n    BOOL SetupDiGetClassImageList(PSP_CLASSIMAGELIST_DATA);\n    BOOL SetupDiGetClassImageListExA(PSP_CLASSIMAGELIST_DATA, PCSTR, PVOID);\n    BOOL SetupDiGetClassImageListExW(PSP_CLASSIMAGELIST_DATA, PCWSTR, PVOID);\n    BOOL SetupDiGetClassInstallParamsA(HDEVINFO, PSP_DEVINFO_DATA, PSP_CLASSINSTALL_HEADER, DWORD, PDWORD);\n    BOOL SetupDiGetClassInstallParamsW(HDEVINFO, PSP_DEVINFO_DATA, PSP_CLASSINSTALL_HEADER, DWORD, PDWORD);\n    BOOL SetupDiGetClassRegistryPropertyA(LPGUID, DWORD, PDWORD, PBYTE, DWORD, PDWORD, PCSTR, PVOID);\n    BOOL SetupDiGetClassRegistryPropertyW(LPGUID, DWORD, PDWORD, PBYTE, DWORD, PDWORD, PCWSTR, PVOID);\n    BOOL SetupDiGetDeviceInfoListClass(HDEVINFO, LPGUID);\n    BOOL SetupDiGetDeviceInfoListDetailA(HDEVINFO, PSP_DEVINFO_LIST_DETAIL_DATA_A);\n    BOOL SetupDiGetDeviceInfoListDetailW(HDEVINFO, PSP_DEVINFO_LIST_DETAIL_DATA_W);\n    BOOL SetupDiGetDeviceInstallParamsA(HDEVINFO, PSP_DEVINFO_DATA, PSP_DEVINSTALL_PARAMS_A);\n    BOOL SetupDiGetDeviceInstallParamsW(HDEVINFO, PSP_DEVINFO_DATA, PSP_DEVINSTALL_PARAMS_W);\n    BOOL SetupDiGetDeviceInstanceIdA(HDEVINFO, PSP_DEVINFO_DATA, PSTR, DWORD, PDWORD);\n    BOOL SetupDiGetDeviceInstanceIdW(HDEVINFO, PSP_DEVINFO_DATA, PWSTR, DWORD, PDWORD);\n    BOOL SetupDiGetDeviceInterfaceAlias(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, const(GUID)*, PSP_DEVICE_INTERFACE_DATA);\n    BOOL SetupDiGetDeviceInterfaceDetailA(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA);\n    BOOL SetupDiGetDeviceInterfaceDetailW(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA_W, DWORD, PDWORD, PSP_DEVINFO_DATA);\n    BOOL SetupDiGetDeviceRegistryPropertyA(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD);\n    BOOL SetupDiGetDeviceRegistryPropertyW(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD);\n    BOOL SetupDiGetDriverInfoDetailA(HDEVINFO, PSP_DEVINFO_DATA, PSP_DRVINFO_DATA_A, PSP_DRVINFO_DETAIL_DATA_A, DWORD, PDWORD);\n    BOOL SetupDiGetDriverInfoDetailW(HDEVINFO, PSP_DEVINFO_DATA, PSP_DRVINFO_DATA_W, PSP_DRVINFO_DETAIL_DATA_W, DWORD, PDWORD);\n    BOOL SetupDiGetDriverInstallParamsA(HDEVINFO, PSP_DEVINFO_DATA, PSP_DRVINFO_DATA_A, PSP_DRVINSTALL_PARAMS);\n    BOOL SetupDiGetDriverInstallParamsW(HDEVINFO, PSP_DEVINFO_DATA, PSP_DRVINFO_DATA_W, PSP_DRVINSTALL_PARAMS);\n    BOOL SetupDiGetHwProfileFriendlyNameA(DWORD, PSTR, DWORD, PDWORD);\n    BOOL SetupDiGetHwProfileFriendlyNameExA(DWORD, PSTR, DWORD, PDWORD, PCSTR, PVOID);\n    BOOL SetupDiGetHwProfileFriendlyNameExW(DWORD, PWSTR, DWORD, PDWORD, PCWSTR, PVOID);\n    BOOL SetupDiGetHwProfileFriendlyNameW(DWORD, PWSTR, DWORD, PDWORD);\n    BOOL SetupDiGetHwProfileList(PDWORD, DWORD, PDWORD, PDWORD);\n    BOOL SetupDiGetHwProfileListExA(PDWORD, DWORD, PDWORD, PDWORD, PCSTR, PVOID);\n    BOOL SetupDiGetHwProfileListExW(PDWORD, DWORD, PDWORD, PDWORD, PCWSTR, PVOID);\n    BOOL SetupDiGetINFClassA(PCSTR, LPGUID, PSTR, DWORD, PDWORD);\n    BOOL SetupDiGetINFClassW(PCWSTR, LPGUID, PWSTR, DWORD, PDWORD);\n    BOOL SetupDiGetSelectedDevice(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiGetSelectedDriverA(HDEVINFO, PSP_DEVINFO_DATA, PSP_DRVINFO_DATA_A);\n    BOOL SetupDiGetSelectedDriverW(HDEVINFO, PSP_DEVINFO_DATA, PSP_DRVINFO_DATA_W);\n    HPROPSHEETPAGE SetupDiGetWizardage(HDEVINFO, PSP_DEVINFO_DATA, PSP_INSTALLWIZARD_DATA, DWORD, DWORD);\n    BOOL SetupDiInstallClassA(HWND, PCSTR, DWORD, HSPFILEQ);\n    BOOL SetupDiInstallClassW(HWND, PCWSTR, DWORD, HSPFILEQ);\n    BOOL SetupDiInstallClassExA(HWND, PCSTR, DWORD, HSPFILEQ, const(GUID)*, PVOID, PVOID);\n    BOOL SetupDiInstallClassExW(HWND, PCWSTR, DWORD, HSPFILEQ, const(GUID)*, PVOID, PVOID);\n    BOOL SetupDiInstallDevice(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiInstallDeviceInterfaces(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiInstallDriverFiles(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiLoadClassIcon(const(GUID)*, HICON*, PINT);\n    BOOL SetupDiMoveDuplicateDevice(HDEVINFO, PSP_DEVINFO_DATA);\n    HKEY SetupDiOpenClassRegKey(const(GUID)*, REGSAM);\n    HKEY SetupDiOpenClassRegKeyExA(const(GUID)*, REGSAM, DWORD, PCSTR, PVOID);\n    HKEY SetupDiOpenClassRegKeyExW(const(GUID)*, REGSAM, DWORD, PCWSTR, PVOID);\n    BOOL SetupDiOpenDeviceInfoA(HDEVINFO, PCSTR, HWND, DWORD, PSP_DEVINFO_DATA);\n    BOOL SetupDiOpenDeviceInfoW(HDEVINFO, PCWSTR, HWND, DWORD, PSP_DEVINFO_DATA);\n    BOOL SetupDiOpenDeviceInterfaceA(HDEVINFO, PCSTR, DWORD, PSP_DEVICE_INTERFACE_DATA);\n    BOOL SetupDiOpenDeviceInterfaceW(HDEVINFO, PCWSTR, DWORD, PSP_DEVICE_INTERFACE_DATA);\n    HKEY SetupDiOpenDeviceInterfaceRegKey(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, REGSAM);\n    HKEY SetupDiOpenDevRegKey(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM);\n    BOOL SetupDiRegisterCoDeviceInstallers(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiRegisterDeviceInfo(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PSP_DETSIG_CMPPROC, PVOID, PSP_DEVINFO_DATA);\n    BOOL SetupDiRemoveDevice(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiRemoveDeviceInterface(HDEVINFO, PSP_DEVICE_INTERFACE_DATA);\n    BOOL SetupDiSelectBestCompatDrv(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiSelectDevice(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiSelectOEMDrv(HWND, HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiSetClassInstallParamsA(HDEVINFO, PSP_DEVINFO_DATA, PSP_CLASSINSTALL_HEADER, DWORD);\n    BOOL SetupDiSetClassInstallParamsW(HDEVINFO, PSP_DEVINFO_DATA, PSP_CLASSINSTALL_HEADER, DWORD);\n    BOOL SetupDiSetClassRegistryPropertyA(LPGUID, DWORD, const(BYTE)*, DWORD, PCSTR, PVOID);\n    BOOL SetupDiSetClassRegistryPropertyW(LPGUID, DWORD, const(BYTE)*, DWORD, PCWSTR, PVOID);\n    BOOL SetupDiSetDeviceInstallParamsA(HDEVINFO, PSP_DEVINFO_DATA, PSP_DEVINSTALL_PARAMS_A);\n    BOOL SetupDiSetDeviceInstallParamsW(HDEVINFO, PSP_DEVINFO_DATA, PSP_DEVINSTALL_PARAMS_W);\n    BOOL SetupDiSetDeviceRegistryPropertyA(HDEVINFO, PSP_DEVINFO_DATA, DWORD, const(BYTE)*, DWORD);\n    BOOL SetupDiSetDeviceRegistryPropertyW(HDEVINFO, PSP_DEVINFO_DATA, DWORD, const(BYTE)*, DWORD);\n    BOOL SetupDiSetDriverInstallParamsA(HDEVINFO, PSP_DEVINFO_DATA, PSP_DRVINFO_DATA_A, PSP_DRVINSTALL_PARAMS);\n    BOOL SetupDiSetDriverInstallParamsW(HDEVINFO, PSP_DEVINFO_DATA, PSP_DRVINFO_DATA_W, PSP_DRVINSTALL_PARAMS);\n    BOOL SetupDiSetSelectedDevice(HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupDiSetSelectedDriverA(HDEVINFO, PSP_DEVINFO_DATA, PSP_DRVINFO_DATA_A);\n    BOOL SetupDiSetSelectedDriverW(HDEVINFO, PSP_DEVINFO_DATA, PSP_DRVINFO_DATA_W);\n    BOOL SetupDiUnremoveDevice(HDEVINFO, PSP_DEVINFO_DATA);\n    HDSKSPC SetupDuplicateDiskSpaceListA(HDSKSPC, PVOID, DWORD, UINT);\n    HDSKSPC SetupDuplicateDiskSpaceListW(HDSKSPC, PVOID, DWORD, UINT);\n    BOOL SetupFindFirstLineA(HINF, PCSTR, PCSTR, PINFCONTEXT);\n    BOOL SetupFindFirstLineW(HINF, PCWSTR, PCWSTR, PINFCONTEXT);\n    BOOL SetupFindNextLine(PINFCONTEXT, PINFCONTEXT);\n    BOOL SetupFindNextMatchLineA(PINFCONTEXT, PCSTR, PINFCONTEXT);\n    BOOL SetupFindNextMatchLineW(PINFCONTEXT, PCWSTR, PINFCONTEXT);\n    BOOL SetupFreeA(PCSTR**, UINT);\n    BOOL SetupFreeW(PCWSTR**, UINT);\n    BOOL SetupGetBackupInformationA(HSPFILEQ, PSP_BACKUP_QUEUE_PARAMS_A);\n    BOOL SetupGetBackupInformationW(HSPFILEQ, PSP_BACKUP_QUEUE_PARAMS_W);\n    BOOL SetupGetBinaryField(PINFCONTEXT, DWORD, PBYTE, DWORD, LPDWORD);\n    DWORD SetupGetFieldCount(PINFCONTEXT);\n    DWORD SetupGetFileCompressionInfoA(PCSTR, PSTR*, PDWORD, PDWORD, PUINT);\n    DWORD SetupGetFileCompressionInfoW(PCWSTR, PWSTR*, PDWORD, PDWORD, PUINT);\n    BOOL SetupGetInfFileListA(PCSTR, DWORD, PSTR, DWORD, PDWORD);\n    BOOL SetupGetInfFileListW(PCWSTR, DWORD, PWSTR, DWORD, PDWORD);\n    BOOL SetupGetInfInformationA(LPCVOID, DWORD, PSP_INF_INFORMATION, DWORD, PDWORD);\n    BOOL SetupGetInfInformationW(LPCVOID, DWORD, PSP_INF_INFORMATION, DWORD, PDWORD);\n    BOOL SetupGetIntField(PINFCONTEXT, DWORD, PINT);\n    BOOL SetupGetLineByIndexA(HINF, PCSTR, DWORD, PINFCONTEXT);\n    BOOL SetupGetLineByIndexW(HINF, PCWSTR, DWORD, PINFCONTEXT);\n    LONG SetupGetLineCountA(HINF, PCSTR);\n    LONG SetupGetLineCountW(HINF, PCWSTR);\n    BOOL SetupGetLineTextA(PINFCONTEXT, HINF, PCSTR, PCSTR, PSTR, DWORD, PDWORD);\n    BOOL SetupGetLineTextW(PINFCONTEXT, HINF, PCWSTR, PCWSTR, PWSTR, DWORD, PDWORD);\n    BOOL SetupGetMultiSzFieldA(PINFCONTEXT, DWORD, PSTR, DWORD, LPDWORD);\n    BOOL SetupGetMultiSzFieldW(PINFCONTEXT, DWORD, PWSTR, DWORD, LPDWORD);\n    BOOL SetupGetSourceFileLocationA(HINF, PINFCONTEXT, PCSTR, PUINT, PSTR, DWORD, PDWORD);\n    BOOL SetupGetSourceFileLocationW(HINF, PINFCONTEXT, PCWSTR, PUINT, PWSTR, DWORD, PDWORD);\n    BOOL SetupGetSourceFileSizeA(HINF, PINFCONTEXT, PCSTR, PCSTR, PDWORD, UINT);\n    BOOL SetupGetSourceFileSizeW(HINF, PINFCONTEXT, PCWSTR, PCWSTR, PDWORD, UINT);\n    BOOL SetupGetSourceInfoA(HINF, UINT, UINT, PSTR, DWORD, PDWORD);\n    BOOL SetupGetSourceInfoW(HINF, UINT, UINT, PWSTR, DWORD, PDWORD);\n    BOOL SetupGetStringFieldA(PINFCONTEXT, DWORD, PSTR, DWORD, PDWORD);\n    BOOL SetupGetStringFieldW(PINFCONTEXT, DWORD, PWSTR, DWORD, PDWORD);\n    BOOL SetupGetTargetPathA(HINF, PINFCONTEXT, PCSTR, PSTR, DWORD, PDWORD);\n    BOOL SetupGetTargetPathW(HINF, PINFCONTEXT, PCWSTR, PWSTR, DWORD, PDWORD);\n    PVOID SetupInitDefaultQueueCallback(HWND);\n    PVOID SetupInitDefaultQueueCallbackEx(HWND, HWND, UINT, DWORD, PVOID);\n    HSPFILELOG SetupInitializeFileLogA(PCSTR, DWORD);\n    HSPFILELOG SetupInitializeFileLogW(PCWSTR, DWORD);\n    BOOL SetupInstallFileA(HINF, PINFCONTEXT, PCSTR, PCSTR, PCSTR, DWORD, PSP_FILE_CALLBACK_A, PVOID);\n    BOOL SetupInstallFileW(HINF, PINFCONTEXT, PCWSTR, PCWSTR, PCWSTR, DWORD, PSP_FILE_CALLBACK_W, PVOID);\n    BOOL SetupInstallFileExA(HINF, PINFCONTEXT, PCSTR, PCSTR, PCSTR, DWORD, PSP_FILE_CALLBACK_A, PVOID, PBOOL);\n    BOOL SetupInstallFileExW(HINF, PINFCONTEXT, PCWSTR, PCWSTR, PCWSTR, DWORD, PSP_FILE_CALLBACK_W, PVOID, PBOOL);\n    BOOL SetupInstallFilesFromInfSectionA(HINF, HINF, HSPFILEQ, PCSTR, PCSTR, UINT);\n    BOOL SetupInstallFilesFromInfSectionW(HINF, HINF, HSPFILEQ, PCWSTR, PCWSTR, UINT);\n    BOOL SetupInstallFromInfSectionA(HWND, HINF, PCSTR, UINT, HKEY, PCSTR, UINT, PSP_FILE_CALLBACK_A, PVOID, HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupInstallFromInfSectionW(HWND, HINF, PCWSTR, UINT, HKEY, PCWSTR, UINT, PSP_FILE_CALLBACK_W, PVOID, HDEVINFO, PSP_DEVINFO_DATA);\n    BOOL SetupInstallServicesFromInfSectionA(HINF, PCSTR, DWORD);\n    BOOL SetupInstallServicesFromInfSectionW(HINF, PCWSTR, DWORD);\n    BOOL SetupInstallServicesFromInfSectionExA(HINF, PCSTR, DWORD, HDEVINFO, PSP_DEVINFO_DATA, PVOID, PVOID);\n    BOOL SetupInstallServicesFromInfSectionExW(HINF, PCWSTR, DWORD, HDEVINFO, PSP_DEVINFO_DATA, PVOID, PVOID);\n    BOOL SetupIterateCabinetA(PCSTR, DWORD, PSP_FILE_CALLBACK_A, PVOID);\n    BOOL SetupIterateCabinetW(PCWSTR, DWORD, PSP_FILE_CALLBACK_W, PVOID);\n    BOOL SetupLogErrorA(LPCSTR, LogSeverity);\n    BOOL SetupLogErrorW(LPCWSTR, LogSeverity);\n    BOOL SetupLogFileA(HSPFILELOG, PCSTR, PCSTR, PCSTR, DWORD, PCSTR, PCSTR, PCSTR, DWORD);\n    BOOL SetupLogFileW(HSPFILELOG, PCWSTR, PCWSTR, PCWSTR, DWORD, PCWSTR, PCWSTR, PCWSTR, DWORD);\n    BOOL SetupOpenAppendInfFileA(PCSTR, HINF, PUINT);\n    BOOL SetupOpenAppendInfFileW(PCWSTR, HINF, PUINT);\n    HSPFILEQ SetupOpenFileQueue();\n    HINF SetupOpenInfFileA(PCSTR, PCSTR, DWORD, PUINT);\n    HINF SetupOpenInfFileW(PCWSTR, PCWSTR, DWORD, PUINT);\n    BOOL SetupOpenLog(BOOL);\n    HINF SetupOpenMasterInf();\n    UINT SetupPromptForDiskA(HWND, PCSTR, PCSTR, PCSTR, PCSTR, PCSTR, DWORD, PSTR, DWORD, PDWORD);\n    UINT SetupPromptForDiskW(HWND, PCWSTR, PCWSTR, PCWSTR, PCWSTR, PCWSTR, DWORD, PWSTR, DWORD, PDWORD);\n    INT SetupPromptReboot(HSPFILEQ, HWND, BOOL);\n    BOOL SetupQueryA(DWORD, PCSTR**, PUINT);\n    BOOL SetupQueryW(DWORD, PCWSTR**, PUINT);\n    BOOL SetupQueryDrivesInDiskSpaceListA(HDSKSPC, PSTR, DWORD, PDWORD);\n    BOOL SetupQueryDrivesInDiskSpaceListW(HDSKSPC, PWSTR, DWORD, PDWORD);\n    BOOL SetupQueryFileLogA(HSPFILELOG, PCSTR, PCSTR, SetupFileLogInfo, PSTR, DWORD, PDWORD);\n    BOOL SetupQueryFileLogW(HSPFILELOG, PCWSTR, PCWSTR, SetupFileLogInfo, PWSTR, DWORD, PDWORD);\n    BOOL SetupQueryInfFileInformationA(PSP_INF_INFORMATION, UINT, PSTR, DWORD, PDWORD);\n    BOOL SetupQueryInfFileInformationW(PSP_INF_INFORMATION, UINT, PWSTR, DWORD, PDWORD);\n    BOOL SetupQueryInfOriginalFileInformationA(PSP_INF_INFORMATION, UINT, PSP_ALTPLATFORM_INFO, PSP_ORIGINAL_FILE_INFO_A);\n    BOOL SetupQueryInfOriginalFileInformationW(PSP_INF_INFORMATION, UINT, PSP_ALTPLATFORM_INFO, PSP_ORIGINAL_FILE_INFO_W);\n    BOOL SetupQueryInfVersionInformationA(PSP_INF_INFORMATION, UINT, PSTR, PSTR, DWORD, PDWORD);\n    BOOL SetupQueryInfVersionInformationW(PSP_INF_INFORMATION, UINT, PCWSTR, PWSTR, DWORD, PDWORD);\n    BOOL SetupQuerySpaceRequiredOnDriveA(HDSKSPC, PCSTR, LONGLONG*, PVOID, UINT);\n    BOOL SetupQuerySpaceRequiredOnDriveW(HDSKSPC, PCWSTR, LONGLONG*, PVOID, UINT);\n    BOOL SetupQueueCopyA(HSPFILEQ, PCSTR, PCSTR, PCSTR, PCSTR, PCSTR, PCSTR, PCSTR, DWORD);\n    BOOL SetupQueueCopyW(HSPFILEQ, PCWSTR, PCWSTR, PCWSTR, PCWSTR, PCWSTR, PCWSTR, PCWSTR, DWORD);\n    BOOL SetupQueueCopyIndirectA(PSP_FILE_COPY_PARAMS_A);\n    BOOL SetupQueueCopyIndirectW(PSP_FILE_COPY_PARAMS_W);\n    BOOL SetupQueueCopySectionA(HSPFILEQ, PCSTR, HINF, HINF, PCSTR, DWORD);\n    BOOL SetupQueueCopySectionW(HSPFILEQ, PCWSTR, HINF, HINF, PCWSTR, DWORD);\n    BOOL SetupQueueDefaultCopyA(HSPFILEQ, HINF, PCSTR, PCSTR, PCSTR, DWORD);\n    BOOL SetupQueueDefaultCopyW(HSPFILEQ, HINF, PCWSTR, PCWSTR, PCWSTR, DWORD);\n    BOOL SetupQueueDeleteA(HSPFILEQ, PCSTR, PCSTR);\n    BOOL SetupQueueDeleteW(HSPFILEQ, PCWSTR, PCWSTR);\n    BOOL SetupQueueDeleteSectionA(HSPFILEQ, HINF, HINF, PCSTR);\n    BOOL SetupQueueDeleteSectionW(HSPFILEQ, HINF, HINF, PCWSTR);\n    BOOL SetupQueueRenameA(HSPFILEQ, PCSTR, PCSTR, PCSTR, PCSTR);\n    BOOL SetupQueueRenameW(HSPFILEQ, PCWSTR, PCWSTR, PCWSTR, PCWSTR);\n    BOOL SetupQueueRenameSectionA(HSPFILEQ, HINF, HINF, PCSTR);\n    BOOL SetupQueueRenameSectionW(HSPFILEQ, HINF, HINF, PCWSTR);\n    BOOL SetupRemoveFileLogEntryA(HSPFILELOG, PCSTR, PCSTR);\n    BOOL SetupRemoveFileLogEntryW(HSPFILELOG, PCWSTR, PCWSTR);\n    BOOL SetupRemoveFromDiskSpaceListA(HDSKSPC, PCSTR, UINT, PVOID, UINT);\n    BOOL SetupRemoveFromDiskSpaceListW(HDSKSPC, PCWSTR, UINT, PVOID, UINT);\n    BOOL SetupRemoveFromSourceListA(DWORD, PCSTR);\n    BOOL SetupRemoveFromSourceListW(DWORD, PCWSTR);\n    BOOL SetupRemoveInstallSectionFromDiskSpaceListA(HDSKSPC, HINF, HINF, PCSTR, PVOID, UINT);\n    BOOL SetupRemoveInstallSectionFromDiskSpaceListW(HDSKSPC, HINF, HINF, PCWSTR, PVOID, UINT);\n    BOOL SetupRemoveSectionFromDiskSpaceListA(HDSKSPC, HINF, HINF, PCSTR, UINT, PVOID, UINT);\n    BOOL SetupRemoveSectionFromDiskSpaceListW(HDSKSPC, HINF, HINF, PCWSTR, UINT, PVOID, UINT);\n    UINT SetupRenameErrorA(HWND, PCSTR, PCSTR, PCSTR, UINT, DWORD);\n    UINT SetupRenameErrorW(HWND, PCWSTR, PCWSTR, PCWSTR, UINT, DWORD);\n    BOOL SetupScanFileQueueA(HSPFILEQ, DWORD, HWND, PSP_FILE_CALLBACK_A, PVOID, PDWORD);\n    BOOL SetupScanFileQueueW(HSPFILEQ, DWORD, HWND, PSP_FILE_CALLBACK_W, PVOID, PDWORD);\n    BOOL SetupSetDirectoryIdA(HINF, DWORD, PCSTR);\n    BOOL SetupSetDirectoryIdW(HINF, DWORD, PCWSTR);\n    BOOL SetupSetDirectoryIdExA(HINF, DWORD, PCSTR, DWORD, DWORD, PVOID);\n    BOOL SetupSetDirectoryIdExW(HINF, DWORD, PCWSTR, DWORD, DWORD, PVOID);\n    BOOL SetupSetFileQueueAlternatePlatformA(HSPFILEQ, PSP_ALTPLATFORM_INFO, PCSTR);\n    BOOL SetupSetFileQueueAlternatePlatformW(HSPFILEQ, PSP_ALTPLATFORM_INFO, PCWSTR);\n    BOOL SetupSetPlatformPathOverrideA(PCSTR);\n    BOOL SetupSetPlatformPathOverrideW(PCWSTR);\n    BOOL SetupSetSourceListA(DWORD, PCSTR*, UINT);\n    BOOL SetupSetSourceListW(DWORD, PCWSTR*, UINT);\n    VOID SetupTermDefaultQueueCallback(PVOID);\n    BOOL SetupTerminateFileLog(HSPFILELOG);\n}\n\ndeprecated {\n    alias SetupDiCreateDeviceInterfaceW SetupDiCreateInterfaceDeviceW;\n    alias SetupDiCreateDeviceInterfaceRegKeyW SetupDiCreateInterfaceDeviceRegKeyW;\n    alias SetupDiOpenDeviceInterfaceW SetupDiOpenInterfaceDeviceW;\n    alias SetupDiGetDeviceInterfaceDetailW SetupDiGetInterfaceDeviceDetailW;\n    alias SetupDiCreateDeviceInterfaceA SetupDiCreateInterfaceDeviceA;\n    alias SetupDiCreateDeviceInterfaceRegKeyA SetupDiCreateInterfaceDeviceRegKeyA;\n    alias SetupDiOpenDeviceInterfaceA SetupDiOpenInterfaceDeviceA;\n    alias SetupDiGetDeviceInterfaceDetailA SetupDiGetInterfaceDeviceDetailA;\n}\n\nversion (Unicode) {\n    alias PSP_FILE_CALLBACK_W PSP_FILE_CALLBACK;\n    alias SetupAddInstallSectionToDiskSpaceListW SetupAddInstallSectionToDiskSpaceList;\n    alias SetupAddSectionToDiskSpaceListW SetupAddSectionToDiskSpaceList;\n    alias SetupAddToDiskSpaceListW SetupAddToDiskSpaceList;\n    alias SetupAddToSourceListW SetupAddToSourceList;\n    alias SetupAdjustDiskSpaceListW SetupAdjustDiskSpaceList;\n    alias SetupBackupErrorW SetupBackupError;\n    alias SetupCommitFileQueueW SetupCommitFileQueue;\n    alias SetupCopyErrorW SetupCopyError;\n    alias SetupCopyOEMInfW SetupCopyOEMInf;\n    alias SetupCreateDiskSpaceListW SetupCreateDiskSpaceList;\n    alias SetupDecompressOrCopyFileW SetupDecompressOrCopyFile;\n    alias SetupDefaultQueueCallbackW SetupDefaultQueueCallback;\n    alias SetupDeleteErrorW SetupDeleteError;\n    alias SetupDiBuildClassInfoListExW SetupDiBuildClassInfoListEx;\n    alias SetupDiClassGuidsFromNameExW SetupDiClassGuidsFromNameEx;\n    alias SetupDiClassGuidsFromNameW SetupDiClassGuidsFromName;\n    alias SetupDiClassNameFromGuidExW SetupDiClassNameFromGuidEx;\n    alias SetupDiClassNameFromGuidW SetupDiClassNameFromGuid;\n    alias SetupDiCreateDeviceInfoListExW SetupDiCreateDeviceInfoListEx;\n    alias SetupDiCreateDeviceInfoW SetupDiCreateDeviceInfo;\n    alias SetupDiCreateDeviceInterfaceRegKeyW SetupDiCreateDeviceInterfaceRegKey;\n    deprecated alias SetupDiCreateDeviceInterfaceRegKeyW SetupDiCreateInterfaceDeviceRegKey;\n    alias SetupDiCreateDeviceInterfaceW SetupDiCreateDeviceInterface;\n    deprecated alias SetupDiCreateDeviceInterfaceW SetupDiCreateInterfaceDevice;\n    alias SetupDiCreateDevRegKeyW SetupDiCreateDevRegKey;\n    alias SetupDiEnumDriverInfoW SetupDiEnumDriverInfo;\n    alias SetupDiGetActualSectionToInstallW SetupDiGetActualSectionToInstall;\n    alias SetupDiGetClassDescriptionExW SetupDiGetClassDescriptionEx;\n    alias SetupDiGetClassDescriptionW SetupDiGetClassDescription;\n    alias SetupDiGetClassDevPropertySheetsW SetupDiGetClassDevPropertySheets;\n    alias SetupDiGetClassDevsExW SetupDiGetClassDevsEx;\n    alias SetupDiGetClassDevsW SetupDiGetClassDevs;\n    alias SetupDiGetClassImageListExW SetupDiGetClassImageListEx;\n    alias SetupDiGetClassInstallParamsW SetupDiGetClassInstallParams;\n    alias SetupDiGetClassRegistryPropertyW SetupDiGetClassRegistryProperty;\n    alias SetupDiGetDeviceInfoListDetailW SetupDiGetDeviceInfoListDetail;\n    alias SetupDiGetDeviceInstallParamsW SetupDiGetDeviceInstallParams;\n    alias SetupDiGetDeviceInstanceIdW SetupDiGetDeviceInstanceId;\n    alias SetupDiGetDeviceInterfaceDetailW SetupDiGetDeviceInterfaceDetail;\n    deprecated alias SetupDiGetDeviceInterfaceDetailW SetupDiGetInterfaceDeviceDetail;\n    alias SetupDiGetDeviceRegistryPropertyW SetupDiGetDeviceRegistryProperty;\n    alias SetupDiGetDriverInfoDetailW SetupDiGetDriverInfoDetail;\n    alias SetupDiGetDriverInstallParamsW SetupDiGetDriverInstallParams;\n    alias SetupDiGetHwProfileFriendlyNameExW SetupDiGetHwProfileFriendlyNameEx;\n    alias SetupDiGetHwProfileFriendlyNameW SetupDiGetHwProfileFriendlyName;\n    alias SetupDiGetHwProfileListExW SetupDiGetHwProfileListEx;\n    alias SetupDiGetINFClassW SetupDiGetINFClass;\n    alias SetupDiGetSelectedDriverW SetupDiGetSelectedDriver;\n    alias SetupDiInstallClassExW SetupDiInstallClassEx;\n    alias SetupDiInstallClassW SetupDiInstallClass;\n    alias SetupDiOpenClassRegKeyExW SetupDiOpenClassRegKeyEx;\n    alias SetupDiOpenDeviceInfoW SetupDiOpenDeviceInfo;\n    alias SetupDiOpenDeviceInterfaceW SetupDiOpenDeviceInterface;\n    deprecated alias SetupDiOpenDeviceInterfaceW SetupDiOpenInterfaceDevice;\n    alias SetupDiSetClassInstallParamsW SetupDiSetClassInstallParams;\n    alias SetupDiSetClassRegistryPropertyW SetupDiSetClassRegistryProperty;\n    alias SetupDiSetDeviceInstallParamsW SetupDiSetDeviceInstallParams;\n    alias SetupDiSetDeviceRegistryPropertyW SetupDiSetDeviceRegistryProperty;\n    alias SetupDiSetDriverInstallParamsW SetupDiSetDriverInstallParams;\n    alias SetupDiSetSelectedDriverW SetupDiSetSelectedDriver;\n    alias SetupDuplicateDiskSpaceListW SetupDuplicateDiskSpaceList;\n    alias SetupFindFirstLineW SetupFindFirstLine;\n    alias SetupFindNextMatchLineW SetupFindNextMatchLine;\n    alias SetupFreeSourceListW SetupFreeSourceList;\n    alias SetupGetBackupInformationW SetupGetBackupInformation;\n    alias SetupGetFileCompressionInfoW SetupGetFileCompressionInfo;\n    alias SetupGetInfFileListW SetupGetInfFileList;\n    alias SetupGetInfInformationW SetupGetInfInformation;\n    alias SetupGetLineByIndexW SetupGetLineByIndex;\n    alias SetupGetLineCountW SetupGetLineCount;\n    alias SetupGetLineTextW SetupGetLineText;\n    alias SetupGetMultiSzFieldW SetupGetMultiSzField;\n    alias SetupGetSourceFileLocationW SetupGetSourceFileLocation;\n    alias SetupGetSourceFileSizeW SetupGetSourceFileSize;\n    alias SetupGetSourceInfoW SetupGetSourceInfo;\n    alias SetupGetStringFieldW SetupGetStringField;\n    alias SetupGetTargetPathW SetupGetTargetPath;\n    alias SetupInitializeFileLogW SetupInitializeFileLog;\n    alias SetupInstallFileExW SetupInstallFileEx;\n    alias SetupInstallFilesFromInfSectionW SetupInstallFilesFromInfSection;\n    alias SetupInstallFileW SetupInstallFile;\n    alias SetupInstallFromInfSectionW SetupInstallFromInfSection;\n    alias SetupInstallServicesFromInfSectionExW SetupInstallServicesFromInfSectionEx;\n    alias SetupInstallServicesFromInfSectionW SetupInstallServicesFromInfSection;\n    alias SetupIterateCabinetW SetupIterateCabinet;\n    alias SetupLogErrorW SetupLogError;\n    alias SetupLogFileW SetupLogFile;\n    alias SetupOpenAppendInfFileW SetupOpenAppendInfFile;\n    alias SetupOpenInfFileW SetupOpenInfFile;\n    alias SetupPromptForDiskW SetupPromptForDisk;\n    alias SetupQueryDrivesInDiskSpaceListW SetupQueryDrivesInDiskSpaceList;\n    alias SetupQueryFileLogW SetupQueryFileLog;\n    alias SetupQueryInfFileInformationW SetupQueryInfFileInformation;\n    alias SetupQueryInfOriginalFileInformationW SetupQueryInfOriginalFileInformation;\n    alias SetupQueryInfVersionInformationW SetupQueryInfVersionInformation;\n    alias SetupQuerySourceListW SetupQuerySourceList;\n    alias SetupQuerySpaceRequiredOnDriveW SetupQuerySpaceRequiredOnDrive;\n    alias SetupQueueCopyIndirectW SetupQueueCopyIndirect;\n    alias SetupQueueCopySectionW SetupQueueCopySection;\n    alias SetupQueueCopyW SetupQueueCopy;\n    alias SetupQueueDefaultCopyW SetupQueueDefaultCopy;\n    alias SetupQueueDeleteSectionW SetupQueueDeleteSection;\n    alias SetupQueueDeleteW SetupQueueDelete;\n    alias SetupQueueRenameSectionW SetupQueueRenameSection;\n    alias SetupQueueRenameW SetupQueueRename;\n    alias SetupRemoveFileLogEntryW SetupRemoveFileLogEntry;\n    alias SetupRemoveFromDiskSpaceListW SetupRemoveFromDiskSpaceList;\n    alias SetupRemoveFromSourceListW SetupRemoveFromSourceList;\n    alias SetupRemoveInstallSectionFromDiskSpaceListW SetupRemoveInstallSectionFromDiskSpaceList;\n    alias SetupRemoveSectionFromDiskSpaceListW SetupRemoveSectionFromDiskSpaceList;\n    alias SetupRenameErrorW SetupRenameError;\n    alias SetupScanFileQueueW SetupScanFileQueue;\n    alias SetupSetDirectoryIdExW SetupSetDirectoryIdEx;\n    alias SetupSetDirectoryIdW SetupSetDirectoryId;\n    alias SetupSetFileQueueAlternatePlatformW SetupSetFileQueueAlternatePlatform;\n    alias SetupSetPlatformPathOverrideW SetupSetPlatformPathOverride;\n    alias SetupSetSourceListW SetupSetSourceList;\n} else {\n    alias PSP_FILE_CALLBACK_A PSP_FILE_CALLBACK;\n    alias SetupAddInstallSectionToDiskSpaceListA SetupAddInstallSectionToDiskSpaceList;\n    alias SetupAddSectionToDiskSpaceListA SetupAddSectionToDiskSpaceList;\n    alias SetupAddToDiskSpaceListA SetupAddToDiskSpaceList;\n    alias SetupAddToSourceListA SetupAddToSourceList;\n    alias SetupAdjustDiskSpaceListA SetupAdjustDiskSpaceList;\n    alias SetupBackupErrorA SetupBackupError;\n    alias SetupCommitFileQueueA SetupCommitFileQueue;\n    alias SetupCopyErrorA SetupCopyError;\n    alias SetupCopyOEMInfA SetupCopyOEMInf;\n    alias SetupCreateDiskSpaceListA SetupCreateDiskSpaceList;\n    alias SetupDecompressOrCopyFileA SetupDecompressOrCopyFile;\n    alias SetupDefaultQueueCallbackA SetupDefaultQueueCallback;\n    alias SetupDeleteErrorA SetupDeleteError;\n    alias SetupDiBuildClassInfoListExA SetupDiBuildClassInfoListEx;\n    alias SetupDiClassGuidsFromNameA SetupDiClassGuidsFromName;\n    alias SetupDiClassGuidsFromNameExA SetupDiClassGuidsFromNameEx;\n    alias SetupDiClassNameFromGuidA SetupDiClassNameFromGuid;\n    alias SetupDiClassNameFromGuidExA SetupDiClassNameFromGuidEx;\n    alias SetupDiCreateDeviceInfoA SetupDiCreateDeviceInfo;\n    alias SetupDiCreateDeviceInfoListExA SetupDiCreateDeviceInfoListEx;\n    alias SetupDiCreateDeviceInterfaceA SetupDiCreateDeviceInterface;\n    deprecated alias SetupDiCreateDeviceInterfaceA SetupDiCreateInterfaceDevice;\n    alias SetupDiCreateDeviceInterfaceRegKeyA SetupDiCreateDeviceInterfaceRegKey;\n    deprecated alias SetupDiCreateDeviceInterfaceRegKeyA SetupDiCreateInterfaceDeviceRegKey;\n    alias SetupDiCreateDevRegKeyA SetupDiCreateDevRegKey;\n    alias SetupDiDeleteDeviceInterfaceData SetupDiDeleteInterfaceDeviceData;\n    alias SetupDiEnumDriverInfoA SetupDiEnumDriverInfo;\n    alias SetupDiGetActualSectionToInstallA SetupDiGetActualSectionToInstall;\n    alias SetupDiGetClassDescriptionA SetupDiGetClassDescription;\n    alias SetupDiGetClassDescriptionExA SetupDiGetClassDescriptionEx;\n    alias SetupDiGetClassDevPropertySheetsA SetupDiGetClassDevPropertySheets;\n    alias SetupDiGetClassDevsA SetupDiGetClassDevs;\n    alias SetupDiGetClassDevsExA SetupDiGetClassDevsEx;\n    alias SetupDiGetClassImageListExA SetupDiGetClassImageListEx;\n    alias SetupDiGetClassInstallParamsA SetupDiGetClassInstallParams;\n    alias SetupDiGetClassRegistryPropertyA SetupDiGetClassRegistryProperty;\n    alias SetupDiGetDeviceInfoListDetailA SetupDiGetDeviceInfoListDetail;\n    alias SetupDiGetDeviceInstallParamsA SetupDiGetDeviceInstallParams;\n    alias SetupDiGetDeviceInstanceIdA SetupDiGetDeviceInstanceId;\n    alias SetupDiGetDeviceInterfaceDetailA SetupDiGetDeviceInterfaceDetail;\n    deprecated alias SetupDiGetDeviceInterfaceDetailA SetupDiGetInterfaceDeviceDetail;\n    alias SetupDiGetDeviceRegistryPropertyA SetupDiGetDeviceRegistryProperty;\n    alias SetupDiGetDriverInfoDetailA SetupDiGetDriverInfoDetail;\n    alias SetupDiGetDriverInstallParamsA SetupDiGetDriverInstallParams;\n    alias SetupDiGetHwProfileFriendlyNameA SetupDiGetHwProfileFriendlyName;\n    alias SetupDiGetHwProfileFriendlyNameExA SetupDiGetHwProfileFriendlyNameEx;\n    alias SetupDiGetHwProfileListExA SetupDiGetHwProfileListEx;\n    alias SetupDiGetINFClassA SetupDiGetINFClass;\n    alias SetupDiGetSelectedDriverA SetupDiGetSelectedDriver;\n    alias SetupDiInstallClassA SetupDiInstallClass;\n    alias SetupDiInstallClassExA SetupDiInstallClassEx;\n    alias SetupDiOpenClassRegKeyExA SetupDiOpenClassRegKeyEx;\n    alias SetupDiOpenDeviceInfoA SetupDiOpenDeviceInfo;\n    alias SetupDiOpenDeviceInterfaceA SetupDiOpenDeviceInterface;\n    deprecated alias SetupDiOpenDeviceInterfaceA SetupDiOpenInterfaceDevice;\n    alias SetupDiSetClassInstallParamsA SetupDiSetClassInstallParams;\n    alias SetupDiSetClassRegistryPropertyA SetupDiSetClassRegistryProperty;\n    alias SetupDiSetDeviceInstallParamsA SetupDiSetDeviceInstallParams;\n    alias SetupDiSetDeviceRegistryPropertyA SetupDiSetDeviceRegistryProperty;\n    alias SetupDiSetDriverInstallParamsA SetupDiSetDriverInstallParams;\n    alias SetupDiSetSelectedDriverA SetupDiSetSelectedDriver;\n    alias SetupDuplicateDiskSpaceListA SetupDuplicateDiskSpaceList;\n    alias SetupFindFirstLineA SetupFindFirstLine;\n    alias SetupFindNextMatchLineA SetupFindNextMatchLine;\n    alias SetupFreeSourceListA SetupFreeSourceList;\n    alias SetupGetBackupInformationA SetupGetBackupInformation;\n    alias SetupGetFileCompressionInfoA SetupGetFileCompressionInfo;\n    alias SetupGetInfFileListA SetupGetInfFileList;\n    alias SetupGetInfInformationA SetupGetInfInformation;\n    alias SetupGetLineByIndexA SetupGetLineByIndex;\n    alias SetupGetLineCountA SetupGetLineCount;\n    alias SetupGetLineTextA SetupGetLineText;\n    alias SetupGetMultiSzFieldA SetupGetMultiSzField;\n    alias SetupGetSourceFileLocationA SetupGetSourceFileLocation;\n    alias SetupGetSourceFileSizeA SetupGetSourceFileSize;\n    alias SetupGetSourceInfoA SetupGetSourceInfo;\n    alias SetupGetStringFieldA SetupGetStringField;\n    alias SetupGetTargetPathA SetupGetTargetPath;\n    alias SetupInitializeFileLogA SetupInitializeFileLog;\n    alias SetupInstallFileA SetupInstallFile;\n    alias SetupInstallFileExA SetupInstallFileEx;\n    alias SetupInstallFilesFromInfSectionA SetupInstallFilesFromInfSection;\n    alias SetupInstallFromInfSectionA SetupInstallFromInfSection;\n    alias SetupInstallServicesFromInfSectionA SetupInstallServicesFromInfSection;\n    alias SetupInstallServicesFromInfSectionExA SetupInstallServicesFromInfSectionEx;\n    alias SetupIterateCabinetA SetupIterateCabinet;\n    alias SetupLogErrorA SetupLogError;\n    alias SetupLogFileA SetupLogFile;\n    alias SetupOpenAppendInfFileA SetupOpenAppendInfFile;\n    alias SetupOpenInfFileA SetupOpenInfFile;\n    alias SetupPromptForDiskA SetupPromptForDisk;\n    alias SetupQueryDrivesInDiskSpaceListA SetupQueryDrivesInDiskSpaceList;\n    alias SetupQueryFileLogA SetupQueryFileLog;\n    alias SetupQueryInfFileInformationA SetupQueryInfFileInformation;\n    alias SetupQueryInfOriginalFileInformationA SetupQueryInfOriginalFileInformation;\n    alias SetupQueryInfVersionInformationA SetupQueryInfVersionInformation;\n    alias SetupQuerySourceListA SetupQuerySourceList;\n    alias SetupQuerySpaceRequiredOnDriveA SetupQuerySpaceRequiredOnDrive;\n    alias SetupQueueCopyA SetupQueueCopy;\n    alias SetupQueueCopyIndirectA SetupQueueCopyIndirect;\n    alias SetupQueueCopySectionA SetupQueueCopySection;\n    alias SetupQueueDefaultCopyA SetupQueueDefaultCopy;\n    alias SetupQueueDeleteA SetupQueueDelete;\n    alias SetupQueueDeleteSectionA SetupQueueDeleteSection;\n    alias SetupQueueRenameA SetupQueueRename;\n    alias SetupQueueRenameSectionA SetupQueueRenameSection;\n    alias SetupRemoveFileLogEntryA SetupRemoveFileLogEntry;\n    alias SetupRemoveFromDiskSpaceListA SetupRemoveFromDiskSpaceList;\n    alias SetupRemoveFromSourceListA SetupRemoveFromSourceList;\n    alias SetupRemoveInstallSectionFromDiskSpaceListA SetupRemoveInstallSectionFromDiskSpaceList;\n    alias SetupRemoveSectionFromDiskSpaceListA SetupRemoveSectionFromDiskSpaceList;\n    alias SetupRenameErrorA SetupRenameError;\n    alias SetupScanFileQueueA SetupScanFileQueue;\n    alias SetupSetDirectoryIdA SetupSetDirectoryId;\n    alias SetupSetDirectoryIdExA SetupSetDirectoryIdEx;\n    alias SetupSetFileQueueAlternatePlatformA SetupSetFileQueueAlternatePlatform;\n    alias SetupSetPlatformPathOverrideA SetupSetPlatformPathOverride;\n    alias SetupSetSourceListA SetupSetSourceList;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/shellapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_shellapi.d)\n */\nmodule core.sys.windows.shellapi;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"shell32\");\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.basetyps;\n\nenum : UINT {\n    ABE_LEFT,\n    ABE_TOP,\n    ABE_RIGHT,\n    ABE_BOTTOM // = 3\n}\n\nenum : UINT {\n    ABS_AUTOHIDE    = 1,\n    ABS_ALWAYSONTOP\n}\n\nenum ULONG\n    SEE_MASK_CLASSNAME      =        1,\n    SEE_MASK_CLASSKEY       =        3,\n    SEE_MASK_IDLIST         =        4,\n    SEE_MASK_INVOKEIDLIST   =       12,\n    SEE_MASK_ICON           = 0x000010,\n    SEE_MASK_HOTKEY         = 0x000020,\n    SEE_MASK_NOCLOSEPROCESS = 0x000040,\n    SEE_MASK_CONNECTNETDRV  = 0x000080,\n    SEE_MASK_FLAG_DDEWAIT   = 0x000100,\n    SEE_MASK_DOENVSUBST     = 0x000200,\n    SEE_MASK_FLAG_NO_UI     = 0x000400,\n    SEE_MASK_NO_CONSOLE     = 0x008000,\n    SEE_MASK_UNICODE        = 0x010000,\n    SEE_MASK_ASYNCOK        = 0x100000,\n    SEE_MASK_HMONITOR       = 0x200000;\n\nenum : DWORD {\n    ABM_NEW,\n    ABM_REMOVE,\n    ABM_QUERYPOS,\n    ABM_SETPOS,\n    ABM_GETSTATE,\n    ABM_GETTASKBARPOS,\n    ABM_ACTIVATE,\n    ABM_GETAUTOHIDEBAR,\n    ABM_SETAUTOHIDEBAR,\n    ABM_WINDOWPOSCHANGED // = 9\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\nenum DWORD ABM_SETSTATE = 10;\n}\n\nenum : UINT {\n    ABN_STATECHANGE,\n    ABN_POSCHANGED,\n    ABN_FULLSCREENAPP,\n    ABN_WINDOWARRANGE\n}\n\nenum : DWORD {\n    NIM_ADD,\n    NIM_MODIFY,\n    NIM_DELETE\n}\n\nstatic if (_WIN32_IE >= 0x500) {\nenum NOTIFYICON_VERSION = 3;\n\n    enum : DWORD {\n        NIM_SETFOCUS = 3,\n        NIM_SETVERSION\n    }\n}\n\nenum UINT\n    NIF_MESSAGE = 1,\n    NIF_ICON    = 2,\n    NIF_TIP     = 4,\n    NIF_STATE   = 8;\n\nstatic if (_WIN32_IE >= 0x500) {\nenum UINT NIF_INFO = 0x00000010;\n}\n\nstatic if (_WIN32_IE >= 0x600) {\nenum UINT NIF_GUID = 0x00000020;\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    enum : DWORD {\n        NIIF_NONE,\n        NIIF_INFO,\n        NIIF_WARNING,\n        NIIF_ERROR\n    }\n}\n\nstatic if (_WIN32_IE >= 0x600) {\n    enum : DWORD {\n        NIIF_ICON_MASK = 15,\n        NIIF_NOSOUND\n    }\n}\n\nenum DWORD\n    NIS_HIDDEN     = 1,\n    NIS_SHAREDICON = 2;\n\nenum HINSTANCE\n    SE_ERR_FNF             = cast(HINSTANCE)  2,\n    SE_ERR_PNF             = cast(HINSTANCE)  3,\n    SE_ERR_ACCESSDENIED    = cast(HINSTANCE)  5,\n    SE_ERR_OOM             = cast(HINSTANCE)  8,\n    SE_ERR_DLLNOTFOUND     = cast(HINSTANCE) 32,\n    SE_ERR_SHARE           = cast(HINSTANCE) 26,\n    SE_ERR_ASSOCINCOMPLETE = cast(HINSTANCE) 27,\n    SE_ERR_DDETIMEOUT      = cast(HINSTANCE) 28,\n    SE_ERR_DDEFAIL         = cast(HINSTANCE) 29,\n    SE_ERR_DDEBUSY         = cast(HINSTANCE) 30,\n    SE_ERR_NOASSOC         = cast(HINSTANCE) 31;\n\nenum : UINT {\n    FO_MOVE = 1,\n    FO_COPY,\n    FO_DELETE,\n    FO_RENAME\n}\n\nenum FILEOP_FLAGS\n    FOF_MULTIDESTFILES        = 0x0001,\n    FOF_CONFIRMMOUSE          = 0x0002,\n    FOF_SILENT                = 0x0004,\n    FOF_RENAMEONCOLLISION     = 0x0008,\n    FOF_NOCONFIRMATION        = 0x0010,\n    FOF_WANTMAPPINGHANDLE     = 0x0020,\n    FOF_ALLOWUNDO             = 0x0040,\n    FOF_FILESONLY             = 0x0080,\n    FOF_SIMPLEPROGRESS        = 0x0100,\n    FOF_NOCONFIRMMKDIR        = 0x0200,\n    FOF_NOERRORUI             = 0x0400,\n    FOF_NOCOPYSECURITYATTRIBS = 0x0800;\n\n// these are not documented on the MSDN site\nenum {\n    PO_DELETE     = 19,\n    PO_RENAME     = 20,\n    PO_PORTCHANGE = 32,\n    PO_REN_PORT   = 52\n}\n\nenum UINT\n    SHGFI_LARGEICON         = 0x000000,\n    SHGFI_SMALLICON         = 0x000001,\n    SHGFI_OPENICON          = 0x000002,\n    SHGFI_SHELLICONSIZE     = 0x000004,\n    SHGFI_PIDL              = 0x000008,\n    SHGFI_USEFILEATTRIBUTES = 0x000010,\n    SHGFI_ICON              = 0x000100,\n    SHGFI_DISPLAYNAME       = 0x000200,\n    SHGFI_TYPENAME          = 0x000400,\n    SHGFI_ATTRIBUTES        = 0x000800,\n    SHGFI_ICONLOCATION      = 0x001000,\n    SHGFI_EXETYPE           = 0x002000,\n    SHGFI_SYSICONINDEX      = 0x004000,\n    SHGFI_LINKOVERLAY       = 0x008000,\n    SHGFI_SELECTED          = 0x010000,\n    SHGFI_ATTR_SPECIFIED    = 0x020000;\n\nstatic if (_WIN32_IE >= 0x500) {\nenum uint\n        SHGFI_ADDOVERLAYS   = 0x000020,\n        SHGFI_OVERLAYINDEX  = 0x000040;\n}\n\nenum SHERB_NOCONFIRMATION = 1;\nenum SHERB_NOPROGRESSUI   = 2;\nenum SHERB_NOSOUND        = 4;\n\nalias WORD FILEOP_FLAGS, PRINTEROP_FLAGS;\nmixin DECLARE_HANDLE!(\"HDROP\");\n\n//align(2): // 1 in Win32, default in Win64\n\nstruct APPBARDATA {\n    DWORD  cbSize = APPBARDATA.sizeof;\n    HWND   hWnd;\n    UINT   uCallbackMessage;\n    UINT   uEdge;\n    RECT   rc;\n    LPARAM lParam;\n}\nalias APPBARDATA* PAPPBARDATA;\n\nstruct NOTIFYICONDATAA {\n    DWORD cbSize = NOTIFYICONDATAA.sizeof;\n    HWND  hWnd;\n    UINT  uID;\n    UINT  uFlags;\n    UINT  uCallbackMessage;\n    HICON hIcon;\n    static if (_WIN32_IE >= 0x500) {\n        CHAR[128] szTip;\n        DWORD     dwState;\n        DWORD     dwStateMask;\n        CHAR[256] szInfo;\n        union {\n            UINT  uTimeout;\n            UINT  uVersion;\n        }\n        CHAR[64]  szInfoTitle;\n        DWORD     dwInfoFlags;\n    } else {\n        CHAR[64]  szTip;\n    }\n    static if (_WIN32_IE >= 0x600) {\n        GUID      guidItem;\n    }\n}\nalias NOTIFYICONDATAA* PNOTIFYICONDATAA;\n\nstruct NOTIFYICONDATAW {\n    DWORD cbSize = NOTIFYICONDATAW.sizeof;\n    HWND  hWnd;\n    UINT  uID;\n    UINT  uFlags;\n    UINT  uCallbackMessage;\n    HICON hIcon;\n    static if (_WIN32_IE >= 0x500) {\n        WCHAR[128] szTip;\n        DWORD      dwState;\n        DWORD      dwStateMask;\n        WCHAR[256] szInfo;\n        union {\n            UINT   uTimeout;\n            UINT   uVersion;\n        }\n        WCHAR[64]  szInfoTitle;\n        DWORD      dwInfoFlags;\n    } else {\n        WCHAR[64]  szTip;\n    }\n    static if (_WIN32_IE >= 0x600) {\n        GUID guidItem;\n    }\n}\nalias NOTIFYICONDATAW* PNOTIFYICONDATAW;\n\nstruct SHELLEXECUTEINFOA {\n    DWORD     cbSize = SHELLEXECUTEINFOA.sizeof;\n    ULONG     fMask;\n    HWND      hwnd;\n    LPCSTR    lpVerb;\n    LPCSTR    lpFile;\n    LPCSTR    lpParameters;\n    LPCSTR    lpDirectory;\n    int       nShow;\n    HINSTANCE hInstApp;\n    PVOID     lpIDList;\n    LPCSTR    lpClass;\n    HKEY      hkeyClass;\n    DWORD     dwHotKey;\n    HANDLE    hIcon;\n    HANDLE    hProcess;\n}\nalias SHELLEXECUTEINFOA* LPSHELLEXECUTEINFOA;\n\nstruct SHELLEXECUTEINFOW {\n    DWORD     cbSize = SHELLEXECUTEINFOW.sizeof;\n    ULONG     fMask;\n    HWND      hwnd;\n    LPCWSTR   lpVerb;\n    LPCWSTR   lpFile;\n    LPCWSTR   lpParameters;\n    LPCWSTR   lpDirectory;\n    int       nShow;\n    HINSTANCE hInstApp;\n    PVOID     lpIDList;\n    LPCWSTR   lpClass;\n    HKEY      hkeyClass;\n    DWORD     dwHotKey;\n    HANDLE    hIcon;\n    HANDLE    hProcess;\n}\nalias SHELLEXECUTEINFOW* LPSHELLEXECUTEINFOW;\n\nalign(1) struct SHFILEOPSTRUCTA {\nalign(1):\n    HWND         hwnd;\n    UINT         wFunc;\n    version (Win64)\n        WORD     _padding1;\n    LPCSTR       pFrom;\n    LPCSTR       pTo;\n    FILEOP_FLAGS fFlags;\n    version (Win64)\n        DWORD     _padding2;\n    BOOL         fAnyOperationsAborted;\n    PVOID        hNameMappings;\n    LPCSTR       lpszProgressTitle;\n}\nalias SHFILEOPSTRUCTA* LPSHFILEOPSTRUCTA;\n\nalign(1) struct SHFILEOPSTRUCTW {\nalign(1):\n    HWND         hwnd;\n    UINT         wFunc;\n    version (Win64)\n        DWORD     _padding1;\n    LPCWSTR      pFrom;\n    LPCWSTR      pTo;\n    FILEOP_FLAGS fFlags;\n    version (Win64)\n        WORD     _padding2;\n    BOOL         fAnyOperationsAborted;\n    PVOID        hNameMappings;\n    LPCWSTR      lpszProgressTitle;\n}\nalias SHFILEOPSTRUCTW* LPSHFILEOPSTRUCTW;\n\nstruct SHFILEINFOA {\n    HICON          hIcon;\n    int            iIcon;\n    DWORD          dwAttributes;\n    CHAR[MAX_PATH] szDisplayName;\n    CHAR[80]       szTypeName;\n}\n\nstruct SHFILEINFOW {\n    HICON           hIcon;\n    int             iIcon;\n    DWORD           dwAttributes;\n    WCHAR[MAX_PATH] szDisplayName;\n    WCHAR[80]       szTypeName;\n}\n\nalign(1) struct SHQUERYRBINFO {\nalign(1):\n    DWORD cbSize = SHQUERYRBINFO.sizeof;\n    version (Win64)\n        DWORD _padding;\n    long  i64Size;\n    long  i64NumItems;\n}\nalias SHQUERYRBINFO* LPSHQUERYRBINFO;\n\nextern (Windows) nothrow @nogc {\n    LPWSTR* CommandLineToArgvW(LPCWSTR, int*);\n    void DragAcceptFiles(HWND, BOOL);\n    void DragFinish(HDROP);\n    UINT DragQueryFileA(HDROP, UINT, LPSTR, UINT);\n    UINT DragQueryFileW(HDROP, UINT, LPWSTR, UINT);\n    BOOL DragQueryPoint(HDROP, LPPOINT);\n    HICON DuplicateIcon(HINSTANCE, HICON);\n    HICON ExtractAssociatedIconA(HINSTANCE, LPCSTR, PWORD);\n    HICON ExtractAssociatedIconW(HINSTANCE, LPCWSTR, PWORD);\n    HICON ExtractIconA(HINSTANCE, LPCSTR, UINT);\n    HICON ExtractIconW(HINSTANCE, LPCWSTR, UINT);\n    UINT ExtractIconExA(LPCSTR, int, HICON*, HICON*, UINT);\n    UINT ExtractIconExW(LPCWSTR, int, HICON*, HICON*, UINT);\n    HINSTANCE FindExecutableA(LPCSTR, LPCSTR, LPSTR);\n    HINSTANCE FindExecutableW(LPCWSTR, LPCWSTR, LPWSTR);\n    UINT_PTR SHAppBarMessage(DWORD, PAPPBARDATA);\n    BOOL Shell_NotifyIconA(DWORD, PNOTIFYICONDATAA);\n    BOOL Shell_NotifyIconW(DWORD, PNOTIFYICONDATAW);\n    int ShellAboutA(HWND, LPCSTR, LPCSTR, HICON);\n    int ShellAboutW(HWND, LPCWSTR, LPCWSTR, HICON);\n    HINSTANCE ShellExecuteA(HWND, LPCSTR, LPCSTR, LPCSTR, LPCSTR, INT);\n    HINSTANCE ShellExecuteW(HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT);\n    BOOL ShellExecuteExA(LPSHELLEXECUTEINFOA);\n    BOOL ShellExecuteExW(LPSHELLEXECUTEINFOW);\n    int SHFileOperationA(LPSHFILEOPSTRUCTA);\n    int SHFileOperationW(LPSHFILEOPSTRUCTW);\n    void SHFreeNameMappings(HANDLE);\n    DWORD_PTR SHGetFileInfoA(LPCSTR, DWORD, SHFILEINFOA*, UINT, UINT);\n    DWORD_PTR SHGetFileInfoW(LPCWSTR, DWORD, SHFILEINFOW*, UINT, UINT);\n    HRESULT SHQueryRecycleBinA(LPCSTR,  LPSHQUERYRBINFO);\n    HRESULT SHQueryRecycleBinW(LPCWSTR,  LPSHQUERYRBINFO);\n    HRESULT SHEmptyRecycleBinA(HWND, LPCSTR, DWORD);\n    HRESULT SHEmptyRecycleBinW(HWND, LPCWSTR, DWORD);\n}\n\nversion (Unicode) {\n    alias NOTIFYICONDATAW NOTIFYICONDATA;\n    alias SHELLEXECUTEINFOW SHELLEXECUTEINFO;\n    alias SHFILEOPSTRUCTW SHFILEOPSTRUCT;\n    alias SHFILEINFOW SHFILEINFO;\n    alias DragQueryFileW DragQueryFile;\n    alias ExtractAssociatedIconW ExtractAssociatedIcon;\n    alias ExtractIconW ExtractIcon;\n    alias ExtractIconExW ExtractIconEx;\n    alias FindExecutableW FindExecutable;\n    alias Shell_NotifyIconW Shell_NotifyIcon;\n    alias ShellAboutW ShellAbout;\n    alias ShellExecuteW ShellExecute;\n    alias ShellExecuteExW ShellExecuteEx;\n    alias SHFileOperationW SHFileOperation;\n    alias SHGetFileInfoW SHGetFileInfo;\n    alias SHQueryRecycleBinW SHQueryRecycleBin;\n    alias SHEmptyRecycleBinW SHEmptyRecycleBin;\n} else {\n    alias NOTIFYICONDATAA NOTIFYICONDATA;\n    alias SHELLEXECUTEINFOA SHELLEXECUTEINFO;\n    alias SHFILEOPSTRUCTA SHFILEOPSTRUCT;\n    alias SHFILEINFOA SHFILEINFO;\n    alias DragQueryFileA DragQueryFile;\n    alias ExtractAssociatedIconA ExtractAssociatedIcon;\n    alias ExtractIconA ExtractIcon;\n    alias ExtractIconExA ExtractIconEx;\n    alias FindExecutableA FindExecutable;\n    alias Shell_NotifyIconA Shell_NotifyIcon;\n    alias ShellAboutA ShellAbout;\n    alias ShellExecuteA ShellExecute;\n    alias ShellExecuteExA ShellExecuteEx;\n    alias SHFileOperationA SHFileOperation;\n    alias SHGetFileInfoA SHGetFileInfo;\n    alias SHQueryRecycleBinA SHQueryRecycleBin;\n    alias SHEmptyRecycleBinA SHEmptyRecycleBin;\n}\n\nalias NOTIFYICONDATA* PNOTIFYICONDATA;\nalias SHELLEXECUTEINFO* LPSHELLEXECUTEINFO;\nalias SHFILEOPSTRUCT* LPSHFILEOPSTRUCT;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/shldisp.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_shldisp.d)\n */\nmodule core.sys.windows.shldisp;\nversion (Windows):\n\nprivate import core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes;\n\n// options for IAutoComplete2\nenum DWORD ACO_AUTOSUGGEST = 0x01;\n\ninterface IAutoComplete : IUnknown {\n    HRESULT Init(HWND, IUnknown, LPCOLESTR, LPCOLESTR);\n    HRESULT Enable(BOOL);\n}\nalias IAutoComplete LPAUTOCOMPLETE;\n\ninterface IAutoComplete2 : IAutoComplete {\n    HRESULT SetOptions(DWORD);\n    HRESULT GetOptions(DWORD*);\n}\nalias IAutoComplete2 LPAUTOCOMPLETE2;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/shlguid.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_shlguid.d)\n */\nmodule core.sys.windows.shlguid;\nversion (Windows):\n\nprivate import core.sys.windows.basetyps, core.sys.windows.w32api;\n\n// FIXME: clean up Windows version support\n\n// I think this is just a helper macro for other win32 headers?\n//MACRO #define DEFINE_SHLGUID(n,l,w1,w2) DEFINE_GUID(n,l,w1,w2,0xC0,0,0,0,0,0,0,0x46)\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/shlobj.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 4.0\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_shlobj.d)\n */\nmodule core.sys.windows.shlobj;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"shell32\");\n\n// TODO: fix bitfields\n// TODO: CMIC_VALID_SEE_FLAGS\n// SHGetFolderPath in shfolder.dll on W9x, NT4, also in shell32.dll on W2K\n\nimport core.sys.windows.commctrl, core.sys.windows.ole2, core.sys.windows.shlguid, core.sys.windows.shellapi;\nprivate import core.sys.windows.prsht, core.sys.windows.unknwn, core.sys.windows.w32api, core.sys.windows.winbase,\n  core.sys.windows.winnt, core.sys.windows.winuser, core.sys.windows.wtypes, core.sys.windows.objfwd, core.sys.windows.objidl;\nprivate import core.sys.windows.winnetwk; // for NETRESOURCE\nprivate import core.sys.windows.oaidl : VARIANT;\n\n\n// FIXME: clean up Windows version support\n\nalign(1):\n\nenum BIF_RETURNONLYFSDIRS = 1;\nenum BIF_DONTGOBELOWDOMAIN = 2;\nenum BIF_STATUSTEXT = 4;\nenum BIF_RETURNFSANCESTORS = 8;\nenum BIF_EDITBOX = 16;\nenum BIF_VALIDATE = 32;\nenum BIF_NEWDIALOGSTYLE = 64;\nenum BIF_BROWSEINCLUDEURLS = 128;\nenum BIF_USENEWUI =  BIF_EDITBOX | BIF_NEWDIALOGSTYLE;\nenum BIF_BROWSEFORCOMPUTER = 0x1000;\nenum BIF_BROWSEFORPRINTER = 0x2000;\nenum BIF_BROWSEINCLUDEFILES = 0x4000;\nenum BIF_SHAREABLE = 0x8000;\nenum BFFM_INITIALIZED = 1;\nenum BFFM_SELCHANGED = 2;\nenum BFFM_VALIDATEFAILEDA = 3;\nenum BFFM_VALIDATEFAILEDW = 4;\nenum BFFM_SETSTATUSTEXTA = WM_USER + 100;\nenum BFFM_ENABLEOK = WM_USER + 101;\nenum BFFM_SETSELECTIONA = WM_USER + 102;\nenum BFFM_SETSELECTIONW = WM_USER + 103;\nenum BFFM_SETSTATUSTEXTW = WM_USER + 104;\nenum BFFM_SETOKTEXT = WM_USER + 105;\nenum BFFM_SETEXPANDED = WM_USER + 106;\n\nversion (Unicode) {\n    alias BFFM_SETSTATUSTEXTW BFFM_SETSTATUSTEXT;\n    alias BFFM_SETSELECTIONW BFFM_SETSELECTION;\n    alias BFFM_VALIDATEFAILEDW BFFM_VALIDATEFAILED;\n} else {\n    alias BFFM_SETSTATUSTEXTA BFFM_SETSTATUSTEXT;\n    alias BFFM_SETSELECTIONA BFFM_SETSELECTION;\n    alias BFFM_VALIDATEFAILEDA BFFM_VALIDATEFAILED;\n}\n\nenum DVASPECT_SHORTNAME = 2;\n\nenum SHARD {\n    SHARD_PIDL            = 1,\n    SHARD_PATHA,\n    SHARD_PATHW,\n    SHARD_APPIDINFO,\n    SHARD_APPIDINFOIDLIST,\n    SHARD_LINK,\n    SHARD_APPIDINFOLINK,\n    SHARD_SHELLITEM,   // = 8\n    SHARD_PATH = (_WIN32_UNICODE ? SHARD_PATHW : SHARD_PATHA)\n}\n\nenum SHCNE_RENAMEITEM = 1;\nenum SHCNE_CREATE = 2;\nenum SHCNE_DELETE = 4;\nenum SHCNE_MKDIR = 8;\nenum SHCNE_RMDIR = 16;\nenum SHCNE_MEDIAINSERTED = 32;\nenum SHCNE_MEDIAREMOVED = 64;\nenum SHCNE_DRIVEREMOVED = 128;\nenum SHCNE_DRIVEADD = 256;\nenum SHCNE_NETSHARE = 512;\nenum SHCNE_NETUNSHARE = 1024;\nenum SHCNE_ATTRIBUTES = 2048;\nenum SHCNE_UPDATEDIR = 4096;\nenum SHCNE_UPDATEITEM = 8192;\nenum SHCNE_SERVERDISCONNECT = 16384;\nenum SHCNE_UPDATEIMAGE = 32768;\nenum SHCNE_DRIVEADDGUI = 65536;\nenum SHCNE_RENAMEFOLDER = 0x20000;\nenum SHCNE_FREESPACE = 0x40000;\nenum SHCNE_ASSOCCHANGED = 0x8000000;\nenum SHCNE_DISKEVENTS = 0x2381F;\nenum SHCNE_GLOBALEVENTS = 0xC0581E0;\nenum SHCNE_ALLEVENTS = 0x7FFFFFFF;\nenum SHCNE_INTERRUPT = 0x80000000;\n\nenum SHCNF_IDLIST = 0;\nenum SHCNF_PATHA = 1;\nenum SHCNF_PRINTERA = 2;\nenum SHCNF_DWORD = 3;\nenum SHCNF_PATHW = 5;\nenum SHCNF_PRINTERW = 6;\nenum SHCNF_TYPE = 0xFF;\nenum SHCNF_FLUSH = 0x1000;\nenum SHCNF_FLUSHNOWAIT = 0x2000;\n\nversion (Unicode) {\n    alias SHCNF_PATHW SHCNF_PATH;\n    alias SHCNF_PRINTERW SHCNF_PRINTER;\n} else {\n    alias SHCNF_PATHA SHCNF_PATH;\n    alias SHCNF_PRINTERA SHCNF_PRINTER;\n}\n\nenum SFGAOF : DWORD {\n    SFGAO_CANCOPY         = DROPEFFECT.DROPEFFECT_COPY,\n    SFGAO_CANMOVE         = DROPEFFECT.DROPEFFECT_MOVE,\n    SFGAO_CANLINK         = DROPEFFECT.DROPEFFECT_LINK,\n    SFGAO_CANRENAME       = 0x00000010L,\n    SFGAO_CANDELETE       = 0x00000020L,\n    SFGAO_HASPROPSHEET    = 0x00000040L,\n    SFGAO_DROPTARGET      = 0x00000100L,\n    SFGAO_CAPABILITYMASK  = 0x00000177L,\n    SFGAO_ISSLOW          = 0x00004000L,\n    SFGAO_GHOSTED         = 0x00008000L,\n    SFGAO_LINK            = 0x00010000L,\n    SFGAO_SHARE           = 0x00020000L,\n    SFGAO_READONLY        = 0x00040000L,\n    SFGAO_HIDDEN          = 0x00080000L,\n    SFGAO_DISPLAYATTRMASK = (SFGAO_ISSLOW | SFGAO_GHOSTED | SFGAO_LINK\n                            | SFGAO_SHARE | SFGAO_READONLY | SFGAO_HIDDEN),\n    SFGAO_FILESYSANCESTOR = 0x10000000L,\n    SFGAO_FOLDER          = 0x20000000L,\n    SFGAO_FILESYSTEM      = 0x40000000L,\n    SFGAO_HASSUBFOLDER    = 0x80000000L,\n    SFGAO_CONTENTSMASK    = 0x80000000L,\n    SFGAO_VALIDATE        = 0x01000000L,\n    SFGAO_REMOVABLE       = 0x02000000L,\n    SFGAO_COMPRESSED      = 0x04000000L\n}\nenum STRRET_WSTR = 0;\nenum STRRET_OFFSET = 1;\nenum STRRET_CSTR = 2;\n\nenum {\n    SHGDFIL_FINDDATA = 1,\n    SHGDFIL_NETRESOURCE,\n    SHGDFIL_DESCRIPTIONID\n}\n\nenum {\n    SHDID_ROOT_REGITEM = 1,\n    SHDID_FS_FILE,\n    SHDID_FS_DIRECTORY,\n    SHDID_FS_OTHER,\n    SHDID_COMPUTER_DRIVE35,\n    SHDID_COMPUTER_DRIVE525,\n    SHDID_COMPUTER_REMOVABLE,\n    SHDID_COMPUTER_FIXED,\n    SHDID_COMPUTER_NETDRIVE,\n    SHDID_COMPUTER_CDROM,\n    SHDID_COMPUTER_RAMDISK,\n    SHDID_COMPUTER_OTHER,\n    SHDID_NET_DOMAIN,\n    SHDID_NET_SERVER,\n    SHDID_NET_SHARE,\n    SHDID_NET_RESTOFNET,\n    SHDID_NET_OTHER\n}\n\nconst TCHAR[] REGSTR_PATH_EXPLORER = \"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\";\nconst TCHAR[] REGSTR_PATH_SPECIAL_FOLDERS=REGSTR_PATH_EXPLORER ~ \"\\\\Shell Folders\";\n\nenum {\n    CSIDL_DESKTOP            =  0,\n    CSIDL_INTERNET,\n    CSIDL_PROGRAMS,\n    CSIDL_CONTROLS,\n    CSIDL_PRINTERS,\n    CSIDL_PERSONAL,\n    CSIDL_FAVORITES,\n    CSIDL_STARTUP,\n    CSIDL_RECENT,\n    CSIDL_SENDTO,\n    CSIDL_BITBUCKET,\n    CSIDL_STARTMENU,      // = 11\n    CSIDL_MYMUSIC            = 13,\n    CSIDL_MYVIDEO,        // = 14\n    CSIDL_DESKTOPDIRECTORY   = 16,\n    CSIDL_DRIVES,\n    CSIDL_NETWORK,\n    CSIDL_NETHOOD,\n    CSIDL_FONTS,\n    CSIDL_TEMPLATES,\n    CSIDL_COMMON_STARTMENU,\n    CSIDL_COMMON_PROGRAMS,\n    CSIDL_COMMON_STARTUP,\n    CSIDL_COMMON_DESKTOPDIRECTORY,\n    CSIDL_APPDATA,\n    CSIDL_PRINTHOOD,\n    CSIDL_LOCAL_APPDATA,\n    CSIDL_ALTSTARTUP,\n    CSIDL_COMMON_ALTSTARTUP,\n    CSIDL_COMMON_FAVORITES,\n    CSIDL_INTERNET_CACHE,\n    CSIDL_COOKIES,\n    CSIDL_HISTORY,\n    CSIDL_COMMON_APPDATA,\n    CSIDL_WINDOWS,\n    CSIDL_SYSTEM,\n    CSIDL_PROGRAM_FILES,\n    CSIDL_MYPICTURES,\n    CSIDL_PROFILE,\n    CSIDL_SYSTEMX86,\n    CSIDL_PROGRAM_FILESX86,\n    CSIDL_PROGRAM_FILES_COMMON,\n    CSIDL_PROGRAM_FILES_COMMONX86,\n    CSIDL_COMMON_TEMPLATES,\n    CSIDL_COMMON_DOCUMENTS,\n    CSIDL_COMMON_ADMINTOOLS,\n    CSIDL_ADMINTOOLS,\n    CSIDL_CONNECTIONS,  // = 49\n    CSIDL_COMMON_MUSIC     = 53,\n    CSIDL_COMMON_PICTURES,\n    CSIDL_COMMON_VIDEO,\n    CSIDL_RESOURCES,\n    CSIDL_RESOURCES_LOCALIZED,\n    CSIDL_COMMON_OEM_LINKS,\n    CSIDL_CDBURN_AREA,  // = 59\n    CSIDL_COMPUTERSNEARME  = 61,\n    CSIDL_FLAG_DONT_VERIFY = 0x4000,\n    CSIDL_FLAG_CREATE      = 0x8000,\n    CSIDL_FLAG_MASK        = 0xFF00\n}\n\nconst TCHAR[]\n    CFSTR_SHELLIDLIST       = \"Shell IDList Array\",\n    CFSTR_SHELLIDLISTOFFSET = \"Shell Object Offsets\",\n    CFSTR_NETRESOURCES      = \"Net Resource\",\n    CFSTR_FILECONTENTS      = \"FileContents\",\n    CFSTR_FILENAMEA         = \"FileName\",\n    CFSTR_FILENAMEMAPA      = \"FileNameMap\",\n    CFSTR_FILEDESCRIPTORA   = \"FileGroupDescriptor\",\n    CFSTR_INETURLA          = \"UniformResourceLocator\",\n    CFSTR_SHELLURL          = CFSTR_INETURLA,\n    CFSTR_FILENAMEW         = \"FileNameW\",\n    CFSTR_FILENAMEMAPW      = \"FileNameMapW\",\n    CFSTR_FILEDESCRIPTORW   = \"FileGroupDescriptorW\",\n    CFSTR_INETURLW          = \"UniformResourceLocatorW\";\n\nversion (Unicode) {\n    alias CFSTR_FILENAMEW CFSTR_FILENAME;\n    alias CFSTR_FILENAMEMAPW CFSTR_FILENAMEMAP;\n    alias CFSTR_FILEDESCRIPTORW CFSTR_FILEDESCRIPTOR;\n    alias CFSTR_INETURLW CFSTR_INETURL;\n} else {\n    alias CFSTR_FILENAMEA CFSTR_FILENAME;\n    alias CFSTR_FILENAMEMAPA CFSTR_FILENAMEMAP;\n    alias CFSTR_FILEDESCRIPTORA CFSTR_FILEDESCRIPTOR;\n    alias CFSTR_INETURLA CFSTR_INETURL;\n}\nconst TCHAR[]\n    CFSTR_PRINTERGROUP        = \"PrinterFriendlyName\",\n    CFSTR_INDRAGLOOP          = \"InShellDragLoop\",\n    CFSTR_PASTESUCCEEDED      = \"Paste Succeeded\",\n    CFSTR_PERFORMEDDROPEFFECT = \"Performed DropEffect\",\n    CFSTR_PREFERREDDROPEFFECT = \"Preferred DropEffect\";\n\nenum CMF_NORMAL=0;\nenum CMF_DEFAULTONLY=1;\nenum CMF_VERBSONLY=2;\nenum CMF_EXPLORE=4;\nenum CMF_NOVERBS=8;\nenum CMF_CANRENAME=16;\nenum CMF_NODEFAULT=32;\nenum CMF_INCLUDESTATIC=64;\nenum CMF_RESERVED=0xffff0000;\nenum GCS_VERBA=0;\nenum GCS_HELPTEXTA=1;\nenum GCS_VALIDATEA=2;\nenum GCS_VERBW=4;\nenum GCS_HELPTEXTW=5;\nenum GCS_VALIDATEW=6;\nenum GCS_UNICODE=4;\n\nversion (Unicode) {\n    alias GCS_VERBW GCS_VERB;\n    alias GCS_HELPTEXTW GCS_HELPTEXT;\n    alias GCS_VALIDATEW GCS_VALIDATE;\n} else {\n    alias GCS_VERBA GCS_VERB;\n    alias GCS_HELPTEXTA GCS_HELPTEXT;\n    alias GCS_VALIDATEA GCS_VALIDATE;\n}\n\nconst TCHAR[]\n    CMDSTR_NEWFOLDER   = \"NewFolder\",\n    CMDSTR_VIEWLIST    = \"ViewList\",\n    CMDSTR_VIEWDETAILS = \"ViewDetails\";\n\nenum CMIC_MASK_HOTKEY     = SEE_MASK_HOTKEY;\nenum CMIC_MASK_ICON       = SEE_MASK_ICON;\nenum CMIC_MASK_FLAG_NO_UI = SEE_MASK_FLAG_NO_UI;\nenum CMIC_MASK_MODAL      = 0x80000000;\n// TODO: This isn't defined anywhere in MinGW.\n//const CMIC_VALID_SEE_FLAGS=SEE_VALID_CMIC_FLAGS;\n\nenum GIL_OPENICON = 1;\nenum GIL_FORSHELL = 2;\nenum GIL_SIMULATEDOC = 1;\nenum GIL_PERINSTANCE = 2;\nenum GIL_PERCLASS = 4;\nenum GIL_NOTFILENAME = 8;\nenum GIL_DONTCACHE = 16;\n\nenum FVSIF_RECT = 1;\nenum FVSIF_PINNED = 2;\nenum FVSIF_NEWFAILED = 0x8000000;\nenum FVSIF_NEWFILE = 0x80000000;\nenum FVSIF_CANVIEWIT = 0x40000000;\n\nenum CDBOSC_SETFOCUS = 0;\nenum CDBOSC_KILLFOCUS = 1;\nenum CDBOSC_SELCHANGE = 2;\nenum CDBOSC_RENAME = 3;\n\nenum FCIDM_SHVIEWFIRST = 0;\nenum FCIDM_SHVIEWLAST = 0x7fff;\nenum FCIDM_BROWSERFIRST = 0xa000;\nenum FCIDM_BROWSERLAST = 0xbf00;\nenum FCIDM_GLOBALFIRST = 0x8000;\nenum FCIDM_GLOBALLAST = 0x9fff;\nenum FCIDM_MENU_FILE = FCIDM_GLOBALFIRST;\nenum FCIDM_MENU_EDIT = FCIDM_GLOBALFIRST+0x0040;\nenum FCIDM_MENU_VIEW = FCIDM_GLOBALFIRST+0x0080;\nenum FCIDM_MENU_VIEW_SEP_OPTIONS = FCIDM_GLOBALFIRST+0x0081;\nenum FCIDM_MENU_TOOLS = FCIDM_GLOBALFIRST+0x00c0;\nenum FCIDM_MENU_TOOLS_SEP_GOTO = FCIDM_GLOBALFIRST+0x00c1;\nenum FCIDM_MENU_HELP = FCIDM_GLOBALFIRST+0x0100;\nenum FCIDM_MENU_FIND = FCIDM_GLOBALFIRST+0x0140;\nenum FCIDM_MENU_EXPLORE = FCIDM_GLOBALFIRST+0x0150;\nenum FCIDM_MENU_FAVORITES = FCIDM_GLOBALFIRST+0x0170;\nenum FCIDM_TOOLBAR = FCIDM_BROWSERFIRST;\nenum FCIDM_STATUS = FCIDM_BROWSERFIRST+1;\n\nenum SBSP_DEFBROWSER = 0;\nenum SBSP_SAMEBROWSER = 1;\nenum SBSP_NEWBROWSER = 2;\nenum SBSP_DEFMODE = 0;\nenum SBSP_OPENMODE = 16;\nenum SBSP_EXPLOREMODE = 32;\nenum SBSP_ABSOLUTE = 0;\nenum SBSP_RELATIVE = 0x1000;\nenum SBSP_PARENT = 0x2000;\nenum SBSP_INITIATEDBYHLINKFRAME = 0x80000000;\nenum SBSP_REDIRECT = 0x40000000;\n\nenum {\n    FCW_STATUS=1,\n    FCW_TOOLBAR,\n    FCW_TREE\n}\n\nenum FCT_MERGE=1;\nenum FCT_CONFIGABLE=2;\nenum FCT_ADDTOEND=4;\n\nenum SVSI_DESELECT=0;\nenum SVSI_SELECT=1;\nenum SVSI_EDIT=3;\nenum SVSI_DESELECTOTHERS=4;\nenum SVSI_ENSUREVISIBLE=8;\nenum SVSI_FOCUSED=16;\n\nenum SVGIO_BACKGROUND=0;\nenum SVGIO_SELECTION=1;\nenum SVGIO_ALLVIEW=2;\n\nenum UINT SV2GV_CURRENTVIEW=-1;\nenum UINT SV2GV_DEFAULTVIEW=-2;\n\nalias DWORD SHGDNF;\n\nstruct CIDA {\n    UINT    cidl;\n    UINT[1] aoffset;\n}\nalias CIDA* LPIDA;\n\nstruct SHITEMID {\n    USHORT  cb;\n    BYTE[1] abID;\n}\nalias SHITEMID*        LPSHITEMID;\nalias const(SHITEMID)* LPCSHITEMID;\n\nstruct ITEMIDLIST {\n    SHITEMID mkid;\n}\nalias ITEMIDLIST*        LPITEMIDLIST;\nalias const(ITEMIDLIST)* LPCITEMIDLIST;\n\nextern (Windows) alias int function(HWND, UINT, LPARAM, LPARAM) BFFCALLBACK;\n\nalign (8) {\nstruct BROWSEINFOA {\n    HWND          hwndOwner;\n    LPCITEMIDLIST pidlRoot;\n    LPSTR         pszDisplayName;\n    LPCSTR        lpszTitle;\n    UINT          ulFlags;\n    BFFCALLBACK   lpfn;\n    LPARAM        lParam;\n    int           iImage;\n}\nalias BROWSEINFOA* PBROWSEINFOA, LPBROWSEINFOA;\n\nstruct BROWSEINFOW {\n    HWND          hwndOwner;\n    LPCITEMIDLIST pidlRoot;\n    LPWSTR        pszDisplayName;\n    LPCWSTR       lpszTitle;\n    UINT          ulFlags;\n    BFFCALLBACK   lpfn;\n    LPARAM        lParam;\n    int           iImage;\n}\nalias BROWSEINFOW* PBROWSEINFOW, LPBROWSEINFOW;\n} // align (8)\n\nstruct CMINVOKECOMMANDINFO {\n    DWORD cbSize = this.sizeof;\n    DWORD fMask;\n    HWND hwnd;\n    LPCSTR lpVerb;\n    LPCSTR lpParameters;\n    LPCSTR lpDirectory;\n    int nShow;\n    DWORD dwHotKey;\n    HANDLE hIcon;\n}\nalias CMINVOKECOMMANDINFO* LPCMINVOKECOMMANDINFO;\n\nstruct DROPFILES {\n    DWORD pFiles;\n    POINT pt;\n    BOOL fNC;\n    BOOL fWide;\n}\nalias DROPFILES* LPDROPFILES;\n\nenum SHGNO {\n    SHGDN_NORMAL             = 0,\n    SHGDN_INFOLDER,\n    SHGDN_FOREDITING         = 0x1000,\n    SHGDN_INCLUDE_NONFILESYS = 0x2000,\n    SHGDN_FORADDRESSBAR      = 0x4000,\n    SHGDN_FORPARSING         = 0x8000\n}\n\nenum SHCONTF {\n    SHCONTF_FOLDERS            = 32,\n    SHCONTF_NONFOLDERS         = 64,\n    SHCONTF_INCLUDEHIDDEN      = 128,\n    SHCONTF_INIT_ON_FIRST_NEXT = 256,\n    SHCONTF_NETPRINTERSRCH     = 512,\n    SHCONTF_SHAREABLE          = 1024,\n    SHCONTF_STORAGE            = 2048\n}\n\nalign(8) struct STRRET {\n    UINT uType;\n    union {\n        LPWSTR pOleStr;\n        UINT uOffset;\n        char[MAX_PATH] cStr;\n    }\n}\nalias STRRET* LPSTRRET;\n\nenum FD_FLAGS {\n    FD_CLSID      = 1,\n    FD_SIZEPOINT  = 2,\n    FD_ATTRIBUTES = 4,\n    FD_CREATETIME = 8,\n    FD_ACCESSTIME = 16,\n    FD_WRITESTIME = 32,\n    FD_FILESIZE   = 64,\n    FD_LINKUI     = 0x8000\n}\n\nstruct FILEDESCRIPTORA {\n    DWORD dwFlags;\n    CLSID clsid;\n    SIZEL sizel;\n    POINTL pointl;\n    DWORD dwFileAttributes;\n    FILETIME ftCreationTime;\n    FILETIME ftLastAccessTime;\n    FILETIME ftLastWriteTime;\n    DWORD nFileSizeHigh;\n    DWORD nFileSizeLow;\n    CHAR[MAX_PATH] cFileName;\n}\nalias FILEDESCRIPTORA* LPFILEDESCRIPTORA;\n\nstruct FILEDESCRIPTORW {\n    DWORD dwFlags;\n    CLSID clsid;\n    SIZEL sizel;\n    POINTL pointl;\n    DWORD dwFileAttributes;\n    FILETIME ftCreationTime;\n    FILETIME ftLastAccessTime;\n    FILETIME ftLastWriteTime;\n    DWORD nFileSizeHigh;\n    DWORD nFileSizeLow;\n    WCHAR[MAX_PATH] cFileName;\n}\nalias FILEDESCRIPTORW* LPFILEDESCRIPTORW;\n\nstruct FILEGROUPDESCRIPTORA {\n    UINT cItems;\n    FILEDESCRIPTORA[1] fgd;\n}\nalias FILEGROUPDESCRIPTORA* LPFILEGROUPDESCRIPTORA;\n\nstruct FILEGROUPDESCRIPTORW {\n    UINT cItems;\n    FILEDESCRIPTORW[1] fgd;\n}\nalias FILEGROUPDESCRIPTORW* LPFILEGROUPDESCRIPTORW;\n\nenum SLR_FLAGS {\n    SLR_NO_UI      = 1,\n    SLR_ANY_MATCH  = 2,\n    SLR_UPDATE     = 4,\n    SLR_NOUPDATE   = 8,\n    SLR_NOSEARCH   = 16,\n    SLR_NOTRACK    = 32,\n    SLR_NOLINKINFO = 64,\n    SLR_INVOKE_MSI = 128\n}\n\nenum SLGP_FLAGS {\n    SLGP_SHORTPATH=1,\n    SLGP_UNCPRIORITY=2,\n    SLGP_RAWPATH=4\n}\n\nalias PBYTE LPVIEWSETTINGS;\n\nenum FOLDERFLAGS {\n    FWF_AUTOARRANGE         = 1,\n    FWF_ABBREVIATEDNAMES    = 2,\n    FWF_SNAPTOGRID          = 4,\n    FWF_OWNERDATA           = 8,\n    FWF_BESTFITWINDOW       = 16,\n    FWF_DESKTOP             = 32,\n    FWF_SINGLESEL           = 64,\n    FWF_NOSUBFOLDERS        = 128,\n    FWF_TRANSPARENT         = 256,\n    FWF_NOCLIENTEDGE        = 512,\n    FWF_NOSCROLL            = 0x400,\n    FWF_ALIGNLEFT           = 0x800,\n    FWF_SINGLECLICKACTIVATE = 0x8000\n}\n\nenum FOLDERVIEWMODE {\n    FVM_ICON      = 1,\n    FVM_SMALLICON,\n    FVM_LIST,\n    FVM_DETAILS\n}\n\nstruct FOLDERSETTINGS {\n    UINT ViewMode;\n    UINT fFlags;\n}\nalias FOLDERSETTINGS*        LPFOLDERSETTINGS;\nalias const(FOLDERSETTINGS)* LPCFOLDERSETTINGS;\n\nstruct FVSHOWINFO {\n    DWORD cbSize = this.sizeof;\n    HWND hwndOwner;\n    int iShow;\n    DWORD dwFlags;\n    RECT rect;\n    LPUNKNOWN punkRel;\n    OLECHAR[MAX_PATH] strNewFile;\n}\nalias FVSHOWINFO* LPFVSHOWINFO;\n\nstruct NRESARRAY {\n    UINT cItems;\n    NETRESOURCE[1] nr;\n}\nalias NRESARRAY* LPNRESARRAY;\n\nenum {\n    SBSC_HIDE,\n    SBSC_SHOW,\n    SBSC_TOGGLE,\n    SBSC_QUERY\n}\n\nenum {\n    SBCMDID_ENABLESHOWTREE,\n    SBCMDID_SHOWCONTROL,\n    SBCMDID_CANCELNAVIGATION,\n    SBCMDID_MAYSAVECHANGES,\n    SBCMDID_SETHLINKFRAME,\n    SBCMDID_ENABLESTOP,\n    SBCMDID_OPTIONS\n}\nenum SVUIA_STATUS {\n    SVUIA_DEACTIVATE,\n    SVUIA_ACTIVATE_NOFOCUS,\n    SVUIA_ACTIVATE_FOCUS,\n    SVUIA_INPLACEACTIVATE\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n\n    struct EXTRASEARCH\n     {\n        GUID guidSearch;\n        WCHAR[80] wszFriendlyName;\n        WCHAR[2084] wszUrl;\n    }\n    alias EXTRASEARCH* LPEXTRASEARCH;\n\n    alias DWORD SHCOLSTATEF;\n\n    struct SHCOLUMNID {\n        GUID fmtid;\n        DWORD pid;\n    }\n    alias SHCOLUMNID*        LPSHCOLUMNID;\n    alias const(SHCOLUMNID)* LPCSHCOLUMNID;\n\n    struct SHELLDETAILS {\n        int fmt;\n        int cxChar;\n        STRRET str;\n    }\n    alias SHELLDETAILS* LPSHELLDETAILS;\n\n    struct PERSIST_FOLDER_TARGET_INFO\n     {\n        LPITEMIDLIST pidlTargetFolder;\n        WCHAR[MAX_PATH] szTargetParsingName;\n        WCHAR[MAX_PATH] szNetworkProvider;\n        DWORD dwAttributes;\n        int csidl;\n    }\n\n    enum SHGFP_TYPE {\n        SHGFP_TYPE_CURRENT = 0,\n        SHGFP_TYPE_DEFAULT = 1,\n    }\n\n}\n\ninterface IEnumIDList : IUnknown {\n    HRESULT Next(ULONG, LPITEMIDLIST*, ULONG*);\n    HRESULT Skip(ULONG);\n    HRESULT Reset();\n    HRESULT Clone(IEnumIDList*);\n}\nalias IEnumIDList LPENUMIDLIST;\n\ninterface IObjMgr : IUnknown {\n    HRESULT Append(IUnknown);\n    HRESULT Remove(IUnknown);\n}\n\ninterface IContextMenu : IUnknown {\n    HRESULT QueryContextMenu(HMENU, UINT, UINT, UINT, UINT);\n    HRESULT InvokeCommand(LPCMINVOKECOMMANDINFO);\n    HRESULT GetCommandString(UINT_PTR, UINT, PUINT, LPSTR, UINT);\n}\nalias IContextMenu LPCONTEXTMENU;\n\ninterface IContextMenu2 : IContextMenu {\n    HRESULT HandleMenuMsg(UINT, WPARAM, LPARAM);\n};\nalias IContextMenu2 LPCONTEXTMENU2;\n\nstatic if (_WIN32_IE >= 0x500) {\n    align(8) {\n        struct SHCOLUMNINIT {\n            ULONG dwFlags;\n            ULONG dwReserved;\n            WCHAR[MAX_PATH] wszFolder;\n        }\n        alias SHCOLUMNINIT*        LPSHCOLUMNINIT;\n        alias const(SHCOLUMNINIT)* LPCSHCOLUMNINIT;\n\n        struct SHCOLUMNDATA {\n            ULONG dwFlags;\n            DWORD dwFileAttributes;\n            ULONG dwReserved;\n            WCHAR *pwszExt;\n            WCHAR[MAX_PATH] wszFile;\n        }\n        alias SHCOLUMNDATA*        LPSHCOLUMNDATA;\n        alias const(SHCOLUMNDATA)* LPCSHCOLUMNDATA;\n    }\n\nenum MAX_COLUMN_NAME_LEN = 80;\nenum MAX_COLUMN_DESC_LEN = 128;\n\n    align(1) struct SHCOLUMNINFO {\n        align(1):\n        SHCOLUMNID scid;\n        VARTYPE vt;\n        DWORD fmt;\n        UINT cChars;\n        DWORD csFlags;\n        WCHAR[MAX_COLUMN_NAME_LEN] wszTitle;\n        WCHAR[MAX_COLUMN_DESC_LEN] wszDescription;\n    }\n    alias SHCOLUMNINFO*        LPSHCOLUMNINFO;\n    alias const(SHCOLUMNINFO)* LPCSHCOLUMNINFO;\n\n    enum SHCOLSTATE {\n        SHCOLSTATE_TYPE_STR      = 0x00000001,\n        SHCOLSTATE_TYPE_INT      = 0x00000002,\n        SHCOLSTATE_TYPE_DATE     = 0x00000003,\n        SHCOLSTATE_TYPEMASK      = 0x0000000f,\n        SHCOLSTATE_ONBYDEFAULT   = 0x00000010,\n        SHCOLSTATE_SLOW          = 0x00000020,\n        SHCOLSTATE_EXTENDED      = 0x00000040,\n        SHCOLSTATE_SECONDARYUI   = 0x00000080,\n        SHCOLSTATE_HIDDEN        = 0x00000100,\n        SHCOLSTATE_PREFER_VARCMP = 0x00000200\n    }\n\n    interface IColumnProvider : IUnknown {\n        HRESULT Initialize(LPCSHCOLUMNINIT);\n        HRESULT GetColumnInfo(DWORD, SHCOLUMNINFO*);\n        HRESULT GetItemData(LPCSHCOLUMNID, LPCSHCOLUMNDATA, VARIANT*);\n    }\n}/* _WIN32_IE >= 0x500 */\n\ninterface IQueryInfo : IUnknown {\n    HRESULT GetInfoTip(DWORD, WCHAR**);\n    HRESULT GetInfoFlags(DWORD*);\n}\n\ninterface IShellExtInit : IUnknown {\n    HRESULT Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY);\n}\nalias IShellExtInit LPSHELLEXTINIT;\n\ninterface IShellPropSheetExt : IUnknown {\n    HRESULT AddPages(LPFNADDPROPSHEETPAGE, LPARAM);\n    HRESULT ReplacePage(UINT, LPFNADDPROPSHEETPAGE, LPARAM);\n}\nalias IShellPropSheetExt LPSHELLPROPSHEETEXT;\n\ninterface IExtractIconA : IUnknown {\n    HRESULT GetIconLocation(UINT, LPSTR, UINT, int*, PUINT);\n    HRESULT Extract(LPCSTR, UINT, HICON*, HICON*, UINT);\n};\nalias IExtractIconA LPEXTRACTICONA;\n\ninterface IExtractIconW : IUnknown {\n    HRESULT GetIconLocation(UINT, LPWSTR, UINT, int*, PUINT);\n    HRESULT Extract(LPCWSTR, UINT, HICON*, HICON*, UINT);\n}\nalias IExtractIconW LPEXTRACTICONW;\n\nversion (Unicode) {\n    alias IExtractIconW IExtractIcon;\n    alias LPEXTRACTICONW LPEXTRACTICON;\n} else {\n    alias IExtractIconA IExtractIcon;\n    alias LPEXTRACTICONA LPEXTRACTICON;\n}\n\ninterface IShellLinkA : IUnknown {\n    HRESULT GetPath(LPSTR, int, WIN32_FIND_DATAA*, DWORD);\n    HRESULT GetIDList(LPITEMIDLIST*);\n    HRESULT SetIDList(LPCITEMIDLIST);\n    HRESULT GetDescription(LPSTR, int);\n    HRESULT SetDescription(LPCSTR);\n    HRESULT GetWorkingDirectory(LPSTR, int);\n    HRESULT SetWorkingDirectory(LPCSTR);\n    HRESULT GetArguments(LPSTR, int);\n    HRESULT SetArguments(LPCSTR);\n    HRESULT GetHotkey(PWORD);\n    HRESULT SetHotkey(WORD);\n    HRESULT GetShowCmd(int*);\n    HRESULT SetShowCmd(int);\n    HRESULT GetIconLocation(LPSTR, int, int*);\n    HRESULT SetIconLocation(LPCSTR, int);\n    HRESULT SetRelativePath(LPCSTR , DWORD);\n    HRESULT Resolve(HWND, DWORD);\n    HRESULT SetPath(LPCSTR);\n}\n\ninterface IShellLinkW : IUnknown {\n    HRESULT GetPath(LPWSTR, int, WIN32_FIND_DATAW*, DWORD);\n    HRESULT GetIDList(LPITEMIDLIST*);\n    HRESULT SetIDList(LPCITEMIDLIST);\n    HRESULT GetDescription(LPWSTR, int);\n    HRESULT SetDescription(LPCWSTR);\n    HRESULT GetWorkingDirectory(LPWSTR, int);\n    HRESULT SetWorkingDirectory(LPCWSTR);\n    HRESULT GetArguments(LPWSTR, int);\n    HRESULT SetArguments(LPCWSTR);\n    HRESULT GetHotkey(PWORD);\n    HRESULT SetHotkey(WORD);\n    HRESULT GetShowCmd(int*);\n    HRESULT SetShowCmd(int);\n    HRESULT GetIconLocation(LPWSTR, int, int*);\n    HRESULT SetIconLocation(LPCWSTR, int);\n    HRESULT SetRelativePath(LPCWSTR , DWORD);\n    HRESULT Resolve(HWND, DWORD);\n    HRESULT SetPath(LPCWSTR);\n}\n\n\ninterface IShellFolder : IUnknown {\n    HRESULT ParseDisplayName(HWND, LPBC, LPOLESTR, PULONG, LPITEMIDLIST*, PULONG);\n    HRESULT EnumObjects(HWND, DWORD, LPENUMIDLIST*);\n    HRESULT BindToObject(LPCITEMIDLIST, LPBC, REFIID, PVOID*);\n    HRESULT BindToStorage(LPCITEMIDLIST, LPBC, REFIID, PVOID*);\n    HRESULT CompareIDs(LPARAM, LPCITEMIDLIST, LPCITEMIDLIST);\n    HRESULT CreateViewObject(HWND, REFIID, PVOID*);\n    HRESULT GetAttributesOf(UINT, LPCITEMIDLIST*, PULONG);\n    HRESULT GetUIObjectOf(HWND, UINT, LPCITEMIDLIST*, REFIID, PUINT, PVOID*);\n    HRESULT GetDisplayNameOf(LPCITEMIDLIST, DWORD, LPSTRRET);\n    HRESULT SetNameOf(HWND, LPCITEMIDLIST, LPCOLESTR, DWORD, LPITEMIDLIST*);\n}\nalias IShellFolder LPSHELLFOLDER;\n\nstatic if (_WIN32_IE >= 0x500) {\n\ninterface IEnumExtraSearch: IUnknown {\n    HRESULT Next(ULONG, LPEXTRASEARCH*, ULONG*);\n    HRESULT Skip(ULONG);\n    HRESULT Reset();\n    HRESULT Clone(IEnumExtraSearch*);\n}\nalias IEnumExtraSearch LPENUMEXTRASEARCH;\n\ninterface IShellFolder2 : IShellFolder {\n    HRESULT ParseDisplayName(HWND, LPBC, LPOLESTR, PULONG, LPITEMIDLIST*, PULONG);\n    HRESULT EnumObjects(HWND, DWORD, LPENUMIDLIST*);\n    HRESULT BindToObject(LPCITEMIDLIST, LPBC, REFIID, PVOID*);\n    HRESULT BindToStorage(LPCITEMIDLIST, LPBC, REFIID, PVOID*);\n    HRESULT CompareIDs(LPARAM, LPCITEMIDLIST, LPCITEMIDLIST);\n    HRESULT CreateViewObject(HWND, REFIID, PVOID*);\n    HRESULT GetAttributesOf(UINT, LPCITEMIDLIST*, PULONG);\n    HRESULT GetUIObjectOf(HWND, UINT, LPCITEMIDLIST*, REFIID, PUINT, PVOID*);\n    HRESULT GetDisplayNameOf(LPCITEMIDLIST, DWORD, LPSTRRET);\n    HRESULT SetNameOf(HWND, LPCITEMIDLIST, LPCOLESTR, DWORD, LPITEMIDLIST*);\n    HRESULT GetDefaultSearchGUID(GUID*);\n    HRESULT EnumSearches(IEnumExtraSearch*);\n    HRESULT GetDefaultColumn(DWORD, ULONG*, ULONG*);\n    HRESULT GetDefaultColumnState(UINT, SHCOLSTATEF*);\n    HRESULT GetDetailsEx(LPCITEMIDLIST, const(SHCOLUMNID)*, VARIANT*);\n    HRESULT GetDetailsOf(LPCITEMIDLIST, UINT, SHELLDETAILS*);\n    HRESULT MapColumnToSCID(UINT, SHCOLUMNID*);\n}\nalias IShellFolder2 LPSHELLFOLDER2;\n\n} /* _WIN32_IE >= 0x500 */\n\ninterface ICopyHook : IUnknown {\n    UINT CopyCallback(HWND, UINT, UINT, LPCSTR, DWORD, LPCSTR, DWORD);\n}\nalias ICopyHook LPCOPYHOOK;\n\ninterface IFileViewerSite : IUnknown {\n    HRESULT SetPinnedWindow(HWND);\n    HRESULT GetPinnedWindow(HWND*);\n}\nalias IFileViewerSite LPFILEVIEWERSITE;\n\ninterface IFileViewer : IUnknown {\n    HRESULT ShowInitialize(LPFILEVIEWERSITE);\n    HRESULT Show(LPFVSHOWINFO);\n    HRESULT PrintTo(LPSTR, BOOL);\n}\nalias IFileViewer LPFILEVIEWER;\n\ninterface IFileSystemBindData : IUnknown {\n    HRESULT SetFindData(const(WIN32_FIND_DATAW)*);\n    HRESULT GetFindData(WIN32_FIND_DATAW*);\n}\n\ninterface IPersistFolder : IPersist {\n    HRESULT GetClassID(CLSID*);\n    HRESULT Initialize(LPCITEMIDLIST);\n}\nalias IPersistFolder LPPERSISTFOLDER;\n\nstatic if (_WIN32_IE >= 0x400 || _WIN32_WINNT >= 0x500) {\n\ninterface IPersistFolder2 : IPersistFolder {\n    HRESULT GetClassID(CLSID*);\n    HRESULT Initialize(LPCITEMIDLIST);\n    HRESULT GetCurFolder(LPITEMIDLIST*);\n}\nalias IPersistFolder2 LPPERSISTFOLDER2;\n\n}/* _WIN32_IE >= 0x400 || _WIN32_WINNT >= 0x500 */\n\nstatic if (_WIN32_IE >= 0x500) {\n\ninterface IPersistFolder3 : IPersistFolder2 {\n    HRESULT GetClassID(CLSID*);\n    HRESULT Initialize(LPCITEMIDLIST);\n    HRESULT GetCurFolder(LPITEMIDLIST*);\n    HRESULT InitializeEx(IBindCtx, LPCITEMIDLIST, const(PERSIST_FOLDER_TARGET_INFO)*);\n    HRESULT GetFolderTargetInfo(PERSIST_FOLDER_TARGET_INFO*);\n}\nalias IPersistFolder3 LPPERSISTFOLDER3;\n\n} /* _WIN32_IE >= 0x500 */\n\nalias IShellBrowser LPSHELLBROWSER;\nalias IShellView LPSHELLVIEW;\n\ninterface IShellBrowser : IOleWindow {\n    HRESULT GetWindow(HWND*);\n    HRESULT ContextSensitiveHelp(BOOL);\n    HRESULT InsertMenusSB(HMENU, LPOLEMENUGROUPWIDTHS);\n    HRESULT SetMenuSB(HMENU, HOLEMENU, HWND);\n    HRESULT RemoveMenusSB(HMENU);\n    HRESULT SetStatusTextSB(LPCOLESTR);\n    HRESULT EnableModelessSB(BOOL);\n    HRESULT TranslateAcceleratorSB(LPMSG, WORD);\n    HRESULT BrowseObject(LPCITEMIDLIST, UINT);\n    HRESULT GetViewStateStream(DWORD, LPSTREAM*);\n    HRESULT GetControlWindow(UINT, HWND*);\n    HRESULT SendControlMsg(UINT, UINT, WPARAM, LPARAM, LRESULT*);\n    HRESULT QueryActiveShellView(LPSHELLVIEW*);\n    HRESULT OnViewWindowActive(LPSHELLVIEW);\n    HRESULT SetToolbarItems(LPTBBUTTON, UINT, UINT);\n}\n\ninterface IShellView : IOleWindow {\n    HRESULT GetWindow(HWND*);\n    HRESULT ContextSensitiveHelp(BOOL);\n    HRESULT TranslateAccelerator(LPMSG);\n//[No] #ifdef _FIX_ENABLEMODELESS_CONFLICT\n//[No]  STDMETHOD(EnableModelessSV)(THIS_ BOOL) PURE;\n//[Yes] #else\n    HRESULT EnableModeless(BOOL);\n//[Yes] #endif\n    HRESULT UIActivate(UINT);\n    HRESULT Refresh();\n    HRESULT CreateViewWindow(IShellView, LPCFOLDERSETTINGS, LPSHELLBROWSER, RECT*, HWND*);\n    HRESULT DestroyViewWindow();\n    HRESULT GetCurrentInfo(LPFOLDERSETTINGS);\n    HRESULT AddPropertySheetPages(DWORD, LPFNADDPROPSHEETPAGE, LPARAM);\n    HRESULT SaveViewState();\n    HRESULT SelectItem(LPCITEMIDLIST, UINT);\n    HRESULT GetItemObject(UINT, REFIID, PVOID*);\n}\n\ninterface ICommDlgBrowser : IUnknown {\n    HRESULT OnDefaultCommand(IShellView);\n    HRESULT OnStateChange(IShellView, ULONG);\n    HRESULT IncludeObject(IShellView, LPCITEMIDLIST);\n}\nalias ICommDlgBrowser LPCOMMDLGBROWSER;\n\nalias GUID SHELLVIEWID;\n\nstruct SV2CVW2_PARAMS {\n    DWORD cbSize = this.sizeof;\n    IShellView psvPrev;\n    FOLDERSETTINGS  *pfs;\n    IShellBrowser psbOwner;\n    RECT *prcView;\nconst(SHELLVIEWID)* pvid;\n    HWND hwndView;\n}\nalias SV2CVW2_PARAMS* LPSV2CVW2_PARAMS;\n\ninterface IShellView2 : IShellView {\n    HRESULT GetWindow(HWND*);\n    HRESULT ContextSensitiveHelp(BOOL);\n    HRESULT TranslateAccelerator(LPMSG);\n//[No] #ifdef _FIX_ENABLEMODELESS_CONFLICT\n//[No]  STDMETHOD(EnableModelessSV)(THIS_ BOOL) PURE;\n//[Yes] #else\n    HRESULT EnableModeless(BOOL);\n//[Yes] #endif\n    HRESULT UIActivate(UINT);\n    HRESULT Refresh();\n    HRESULT CreateViewWindow(IShellView, LPCFOLDERSETTINGS, LPSHELLBROWSER, RECT*, HWND*);\n    HRESULT DestroyViewWindow();\n    HRESULT GetCurrentInfo(LPFOLDERSETTINGS);\n    HRESULT AddPropertySheetPages(DWORD, LPFNADDPROPSHEETPAGE, LPARAM);\n    HRESULT SaveViewState();\n    HRESULT SelectItem(LPCITEMIDLIST, UINT);\n    HRESULT GetItemObject(UINT, REFIID, PVOID*);\n    HRESULT GetView(SHELLVIEWID*, ULONG);\n    HRESULT CreateViewWindow2(LPSV2CVW2_PARAMS);\n}\n\ninterface IShellExecuteHookA : IUnknown {\n    HRESULT Execute(LPSHELLEXECUTEINFOA);\n}\n\ninterface IShellExecuteHookW : IUnknown {\n    HRESULT Execute(LPSHELLEXECUTEINFOW);\n}\n\ninterface IShellIcon : IUnknown {\n    HRESULT GetIconOf(LPCITEMIDLIST, UINT, PINT);\n}\nalias IShellIcon LPSHELLICON;\n\nstruct SHELLFLAGSTATE {\n    short _bf;\n/*\n    BOOL fShowAllObjects : 1;\n    BOOL fShowExtensions : 1;\n    BOOL fNoConfirmRecycle : 1;\n    BOOL fShowSysFiles : 1;\n    BOOL fShowCompColor : 1;\n    BOOL fDoubleClickInWebView : 1;\n    BOOL fDesktopHTML : 1;\n    BOOL fWin95Classic : 1;\n    BOOL fDontPrettyPath : 1;\n    BOOL fShowAttribCol : 1;\n    BOOL fMapNetDrvBtn : 1;\n    BOOL fShowInfoTip : 1;\n    BOOL fHideIcons : 1;\n    UINT fRestFlags : 3;\n*/\n    @property bool fShowAllObjects()       { return cast(bool) (_bf & 0x0001); }\n    @property bool fShowExtensions()       { return cast(bool) (_bf & 0x0002); }\n    @property bool fNoConfirmRecycle()     { return cast(bool) (_bf & 0x0004); }\n    @property bool fShowSysFiles()         { return cast(bool) (_bf & 0x0008); }\n    @property bool fShowCompColor()        { return cast(bool) (_bf & 0x0010); }\n    @property bool fDoubleClickInWebView() { return cast(bool) (_bf & 0x0020); }\n    @property bool fDesktopHTML()          { return cast(bool) (_bf & 0x0040); }\n    @property bool fWin95Classic()         { return cast(bool) (_bf & 0x0080); }\n    @property bool fDontPrettyPath()       { return cast(bool) (_bf & 0x0100); }\n    @property bool fShowAttribCol()        { return cast(bool) (_bf & 0x0200); }\n    @property bool fMapNetDrvBtn()         { return cast(bool) (_bf & 0x0400); }\n    @property bool fShowInfoTip()          { return cast(bool) (_bf & 0x0800); }\n    @property bool fHideIcons()            { return cast(bool) (_bf & 0x1000); }\n    @property ubyte fRestFlags()           { return cast(ubyte) (_bf >> 13); }\n\n    @property bool fShowAllObjects(bool f)       { _bf = cast(ushort) ((_bf & ~0xFFFE) | f);        return f; }\n    @property bool fShowExtensions(bool f)       { _bf = cast(ushort) ((_bf & ~0xFFFD) | (f <<  1)); return f; }\n    @property bool fNoConfirmRecycle(bool f)     { _bf = cast(ushort) ((_bf & ~0xFFFB) | (f <<  2)); return f; }\n    @property bool fShowSysFiles(bool f)         { _bf = cast(ushort) ((_bf & ~0xFFF8) | (f <<  3)); return f; }\n    @property bool fShowCompColor(bool f)        { _bf = cast(ushort) ((_bf & ~0xFFEF) | (f <<  4)); return f; }\n    @property bool fDoubleClickInWebView(bool f) { _bf = cast(ushort) ((_bf & ~0xFFDF) | (f <<  5)); return f; }\n    @property bool fDesktopHTML(bool f)          { _bf = cast(ushort) ((_bf & ~0xFFBF) | (f <<  6)); return f; }\n    @property bool fWin95Classic(bool f)         { _bf = cast(ushort) ((_bf & ~0xFF8F) | (f <<  7)); return f; }\n    @property bool fDontPrettyPath(bool f)       { _bf = cast(ushort) ((_bf & ~0xFEFF) | (f <<  8)); return f; }\n    @property bool fShowAttribCol(bool f)        { _bf = cast(ushort) ((_bf & ~0xFDFF) | (f <<  9)); return f; }\n    @property bool fMapNetDrvBtn(bool f)         { _bf = cast(ushort) ((_bf & ~0xFBFF) | (f << 10)); return f; }\n    @property bool fShowInfoTip(bool f)          { _bf = cast(ushort) ((_bf & ~0xF8FF) | (f << 11)); return f; }\n    @property bool fHideIcons(bool f)            { _bf = cast(ushort) ((_bf & ~0xEFFF) | (f << 12)); return f; }\n    @property ubyte fRestFlags(ubyte f)          { _bf = cast(ushort) ((_bf & ~0x1FFF) | (f << 13)); return cast(ubyte) (f & 7); }\n}\nalias SHELLFLAGSTATE* LPSHELLFLAGSTATE;\n\nenum SSF_SHOWALLOBJECTS = 0x1;\nenum SSF_SHOWEXTENSIONS = 0x2;\nenum SSF_SHOWCOMPCOLOR = 0x8;\nenum SSF_SHOWSYSFILES = 0x20;\nenum SSF_DOUBLECLICKINWEBVIEW = 0x80;\nenum SSF_SHOWATTRIBCOL = 0x100;\nenum SSF_DESKTOPHTML = 0x200;\nenum SSF_WIN95CLASSIC = 0x400;\nenum SSF_DONTPRETTYPATH = 0x800;\nenum SSF_MAPNETDRVBUTTON = 0x1000;\nenum SSF_SHOWINFOTIP = 0x2000;\nenum SSF_HIDEICONS = 0x4000;\nenum SSF_NOCONFIRMRECYCLE = 0x8000;\n\ninterface IShellIconOverlayIdentifier : IUnknown {\n    HRESULT IsMemberOf(LPCWSTR, DWORD);\n    HRESULT GetOverlayInfo(LPWSTR, int, int*, DWORD*);\n    HRESULT GetPriority(int*);\n}\n\nenum ISIOI_ICONFILE  = 0x00000001;\nenum ISIOI_ICONINDEX = 0x00000002;\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    struct SHELLSTATE {\n        uint _bf1;\n        DWORD dwWin95Unused;\n        UINT uWin95Unused;\n        LONG lParamSort;\n        int iSortDirection;\n        UINT _version;\n        UINT uNotUsed;\n        uint _bf2;\n    /*\n        BOOL fShowAllObjects : 1;\n        BOOL fShowExtensions : 1;\n        BOOL fNoConfirmRecycle : 1;\n        BOOL fShowSysFiles : 1;\n        BOOL fShowCompColor : 1;\n        BOOL fDoubleClickInWebView : 1;\n        BOOL fDesktopHTML : 1;\n        BOOL fWin95Classic : 1;\n        BOOL fDontPrettyPath : 1;\n        BOOL fShowAttribCol : 1;\n        BOOL fMapNetDrvBtn : 1;\n        BOOL fShowInfoTip : 1;\n        BOOL fHideIcons : 1;\n        BOOL fWebView : 1;\n        BOOL fFilter : 1;\n        BOOL fShowSuperHidden : 1;\n        BOOL fNoNetCrawling : 1;\n    */\n        @property bool fShowAllObjects()       { return cast(bool) (_bf1 & 0x00000001); }\n        @property bool fShowExtensions()       { return cast(bool) (_bf1 & 0x00000002); }\n        @property bool fNoConfirmRecycle()     { return cast(bool) (_bf1 & 0x00000004); }\n        @property bool fShowSysFiles()         { return cast(bool) (_bf1 & 0x00000008); }\n        @property bool fShowCompColor()        { return cast(bool) (_bf1 & 0x00000010); }\n        @property bool fDoubleClickInWebView() { return cast(bool) (_bf1 & 0x00000020); }\n        @property bool fDesktopHTML()          { return cast(bool) (_bf1 & 0x00000040); }\n        @property bool fWin95Classic()         { return cast(bool) (_bf1 & 0x00000080); }\n        @property bool fDontPrettyPath()       { return cast(bool) (_bf1 & 0x00000100); }\n        @property bool fShowAttribCol()        { return cast(bool) (_bf1 & 0x00000200); }\n        @property bool fMapNetDrvBtn()         { return cast(bool) (_bf1 & 0x00000400); }\n        @property bool fShowInfoTip()          { return cast(bool) (_bf1 & 0x00000800); }\n        @property bool fHideIcons()            { return cast(bool) (_bf1 & 0x00001000); }\n        @property bool fWebView()              { return cast(bool) (_bf1 & 0x00002000); }\n        @property bool fFilter()               { return cast(bool) (_bf1 & 0x00004000); }\n        @property bool fShowSuperHidden()      { return cast(bool) (_bf1 & 0x00008000); }\n        @property bool fNoNetCrawling()        { return cast(bool) (_bf1 & 0x00010000); }\n\n        @property bool fShowAllObjects(bool f)       { _bf1 = cast(uint) ((_bf1 & ~0xFFFFFFFE) | f);         return f; }\n        @property bool fShowExtensions(bool f)       { _bf1 = cast(uint) ((_bf1 & ~0xFFFFFFFD) | (f <<  1)); return f; }\n        @property bool fNoConfirmRecycle(bool f)     { _bf1 = cast(uint) ((_bf1 & ~0xFFFFFFFB) | (f <<  2)); return f; }\n        @property bool fShowSysFiles(bool f)         { _bf1 = cast(uint) ((_bf1 & ~0xFFFFFFF8) | (f <<  3)); return f; }\n        @property bool fShowCompColor(bool f)        { _bf1 = cast(uint) ((_bf1 & ~0xFFFFFFEF) | (f <<  4)); return f; }\n        @property bool fDoubleClickInWebView(bool f) { _bf1 = cast(uint) ((_bf1 & ~0xFFFFFFDF) | (f <<  5)); return f; }\n        @property bool fDesktopHTML(bool f)          { _bf1 = cast(uint) ((_bf1 & ~0xFFFFFFBF) | (f <<  6)); return f; }\n        @property bool fWin95Classic(bool f)         { _bf1 = cast(uint) ((_bf1 & ~0xFFFFFF8F) | (f <<  7)); return f; }\n        @property bool fDontPrettyPath(bool f)       { _bf1 = cast(uint) ((_bf1 & ~0xFFFFFEFF) | (f <<  8)); return f; }\n        @property bool fShowAttribCol(bool f)        { _bf1 = cast(uint) ((_bf1 & ~0xFFFFFDFF) | (f <<  9)); return f; }\n        @property bool fMapNetDrvBtn(bool f)         { _bf1 = cast(uint) ((_bf1 & ~0xFFFFFBFF) | (f << 10)); return f; }\n        @property bool fShowInfoTip(bool f)          { _bf1 = cast(uint) ((_bf1 & ~0xFFFFF8FF) | (f << 11)); return f; }\n        @property bool fHideIcons(bool f)            { _bf1 = cast(uint) ((_bf1 & ~0xFFFFEFFF) | (f << 12)); return f; }\n        @property bool fWebView(bool f)              { _bf1 = cast(uint) ((_bf1 & ~0xFFFFDFFF) | (f << 13)); return f; }\n        @property bool fFilter(bool f)               { _bf1 = cast(uint) ((_bf1 & ~0xFFFFBFFF) | (f << 14)); return f; }\n        @property bool fShowSuperHidden(bool f)      { _bf1 = cast(uint) ((_bf1 & ~0xFFFF8FFF) | (f << 15)); return f; }\n        @property bool fNoNetCrawling(bool f)        { _bf1 = cast(uint) ((_bf1 & ~0xFFFEFFFF) | (f << 16)); return f; }\n    /*\n        BOOL fSepProcess : 1;\n        BOOL fStartPanelOn : 1;\n        BOOL fShowStartPage : 1;\n        UINT fSpareFlags : 13;\n    */\n        @property bool fSepProcess()           { return cast(bool) (_bf2 & 0x00000001); }\n        @property bool fStartPanelOn()         { return cast(bool) (_bf2 & 0x00000002); }\n        @property bool fShowStartPage()        { return cast(bool) (_bf2 & 0x00000004); }\n        @property ushort fSpareFlags()         { return cast(ushort) ((_bf2 & 0x0000FFF8) >> 3); }\n\n        @property bool fSepProcess(bool f)     { _bf2 = cast(uint) ((_bf2 & ~0xFFFFFFFE) | f);        return f; }\n        @property bool fStartPanelOn(bool f)   { _bf2 = cast(uint) ((_bf2 & ~0xFFFFFFFD) | (f << 1)); return f; }\n        @property bool fShowStartPage(bool f)  { _bf2 = cast(uint) ((_bf2 & ~0xFFFFFFFB) | (f << 2)); return f; }\n        @property ushort fSpareFlags(ushort f) {\n            _bf2 = cast(ushort) ((_bf2 & ~0xFFFF0007) | ((f & 0x1FFF) << 3));\n            return cast(ushort) (f & 0x1FFF);\n        }\n    }\n    alias SHELLSTATE* LPSHELLSTATE;\n}\n\nstatic if (_WIN32_IE >= 0x500) {\n    align(8) {\n        struct SHDRAGIMAGE {\n            SIZE sizeDragImage;\n            POINT ptOffset;\n            HBITMAP hbmpDragImage;\n            COLORREF crColorKey;\n        }\n        alias SHDRAGIMAGE* LPSHDRAGIMAGE;\n    }\n\n    interface IDragSourceHelper : IUnknown {\n        HRESULT InitializeFromBitmap(LPSHDRAGIMAGE pshdi, IDataObject pDataObject);\n        HRESULT InitializeFromWindow(HWND hwnd, POINT* ppt, IDataObject pDataObject);\n    }\n\n    interface IDropTargetHelper : IUnknown {\n        HRESULT DragEnter(HWND hwndTarget, IDataObject pDataObject, POINT* ppt, DWORD dwEffect);\n        HRESULT DragLeave();\n        HRESULT DragOver(POINT* ppt, DWORD dwEffect);\n        HRESULT Drop(IDataObject pDataObject, POINT* ppt, DWORD dwEffect);\n        HRESULT Show(BOOL fShow);\n    }\n}\n\nextern (Windows):\nvoid SHAddToRecentDocs(UINT, PCVOID);\nLPITEMIDLIST SHBrowseForFolderA(PBROWSEINFOA);\nLPITEMIDLIST SHBrowseForFolderW(PBROWSEINFOW);\nvoid SHChangeNotify(LONG, UINT, PCVOID, PCVOID);\nHRESULT SHGetDataFromIDListA(LPSHELLFOLDER, LPCITEMIDLIST, int, PVOID, int);\nHRESULT SHGetDataFromIDListW(LPSHELLFOLDER, LPCITEMIDLIST, int, PVOID, int);\nHRESULT SHGetDesktopFolder(LPSHELLFOLDER*);\nHRESULT SHGetInstanceExplorer(IUnknown*);\nHRESULT SHGetMalloc(LPMALLOC*);\nBOOL SHGetPathFromIDListA(LPCITEMIDLIST, LPSTR);\nBOOL SHGetPathFromIDListW(LPCITEMIDLIST, LPWSTR);\nHRESULT SHGetSpecialFolderLocation(HWND, int, LPITEMIDLIST*);\nHRESULT SHLoadInProc(REFCLSID);\n\nstatic if (_WIN32_IE >= 0x400) {\n    BOOL SHGetSpecialFolderPathA(HWND, LPSTR, int, BOOL);\n    BOOL SHGetSpecialFolderPathW(HWND, LPWSTR, int, BOOL);\n}\n\n/* SHGetFolderPath in shfolder.dll on W9x, NT4, also in shell32.dll on W2K */\nHRESULT SHGetFolderPathA(HWND, int, HANDLE, DWORD, LPSTR);\nHRESULT SHGetFolderPathW(HWND, int, HANDLE, DWORD, LPWSTR);\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    INT SHGetIconOverlayIndexW(LPCWSTR pszIconPath, int iIconIndex);\n    INT SHGetIconOverlayIndexA(LPCSTR pszIconPath, int iIconIndex);\n    HRESULT SHGetFolderLocation(HWND, int, HANDLE, DWORD, LPITEMIDLIST*);\n    INT SHCreateDirectoryExA(HWND, LPCSTR, LPSECURITY_ATTRIBUTES);\n    INT SHCreateDirectoryExW(HWND, LPCWSTR, LPSECURITY_ATTRIBUTES);\n    HRESULT SHBindToParent(LPCITEMIDLIST, REFIID, VOID**, LPCITEMIDLIST*);\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        PRF_VERIFYEXISTS         = 0x0001,\n        PRF_TRYPROGRAMEXTENSIONS = (0x0002 | PRF_VERIFYEXISTS),\n        PRF_FIRSTDIRDEF          = 0x0004,\n        PRF_DONTFINDLNK          = 0x0008,\n        IDO_SHGIOI_SHARE         = 0x0FFFFFFF,\n        IDO_SHGIOI_LINK          = 0x0FFFFFFE,\n        IDO_SHGIOI_SLOWFILE      = 0x0FFFFFFD,\n        IDO_SHGIOI_DEFAULT       = 0x0FFFFFFC\n    }\n\n    struct SHDESCRIPTIONID {\n        DWORD dwDescriptionId;\n        CLSID clsid;\n    }\n    alias SHDESCRIPTIONID* LPSHDESCRIPTIONID;\n\n    BOOL PathResolve(LPWSTR, LPCWSTR*, UINT);\n    HRESULT SHGetFolderPathAndSubDirA(HWND, int, HANDLE, DWORD, LPCSTR, LPSTR);\n    HRESULT SHGetFolderPathAndSubDirW(HWND, int, HANDLE, DWORD, LPCWSTR, LPWSTR);\n    HRESULT SHParseDisplayName(LPCWSTR, IBindCtx, LPITEMIDLIST, SFGAOF, SFGAOF*);\n}\n\nvoid SHGetSettings(LPSHELLFLAGSTATE, DWORD);\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    void SHGetSetSettings(LPSHELLSTATE, DWORD, BOOL);\n    BOOL ILIsEqual(LPCITEMIDLIST, LPCITEMIDLIST);\n    BOOL ILIsParent(LPCITEMIDLIST, LPCITEMIDLIST, BOOL);\n    BOOL ILRemoveLastID(LPITEMIDLIST);\n    HRESULT ILLoadFromStream(IStream, LPITEMIDLIST*);\n    HRESULT ILSaveToStream(IStream, LPCITEMIDLIST);\n    LPITEMIDLIST ILAppendID(LPITEMIDLIST, LPCSHITEMID, BOOL);\n    LPITEMIDLIST ILClone(LPCITEMIDLIST);\n    LPITEMIDLIST ILCloneFirst(LPCITEMIDLIST);\n    LPITEMIDLIST ILCombine(LPCITEMIDLIST, LPCITEMIDLIST);\n    LPITEMIDLIST ILFindChild(LPCITEMIDLIST, LPCITEMIDLIST);\n    LPITEMIDLIST ILFindLastID(LPCITEMIDLIST);\n    LPITEMIDLIST ILGetNext(LPCITEMIDLIST);\n    UINT ILGetSize(LPCITEMIDLIST);\n    void ILFree(LPITEMIDLIST);\n\n    HRESULT SHCoCreateInstance(LPCWSTR, REFCLSID, IUnknown, REFIID, void**);\n}\n\nversion (Unicode) {\n    alias IShellExecuteHookW IShellExecuteHook;\n    alias IShellLinkW IShellLink;\n    alias BROWSEINFOW BROWSEINFO;\n    alias SHBrowseForFolderW SHBrowseForFolder;\n    alias SHGetDataFromIDListW SHGetDataFromIDList;\n    alias SHGetPathFromIDListW SHGetPathFromIDList;\n    static if (_WIN32_IE >= 0x400) {\n        alias SHGetSpecialFolderPathW SHGetSpecialFolderPath;\n    }\n    alias SHGetFolderPathW SHGetFolderPath;\n    static if (_WIN32_WINNT >= 0x500) {\n        alias SHGetIconOverlayIndexW SHGetIconOverlayIndex;\n        alias SHCreateDirectoryExW SHCreateDirectoryEx;\n    }\n    static if (_WIN32_WINNT >= 0x501) {\n        alias SHGetFolderPathAndSubDirW SHGetFolderPathAndSubDir;\n    }\n    alias FILEDESCRIPTORW FILEDESCRIPTOR;\n    alias LPFILEDESCRIPTORW LPFILEDESCRIPTOR;\n    alias FILEGROUPDESCRIPTORW FILEGROUPDESCRIPTOR;\n    alias LPFILEGROUPDESCRIPTORW LPFILEGROUPDESCRIPTOR;\n\n} else {\n    alias IShellExecuteHookA IShellExecuteHook;\n    alias IShellLinkA IShellLink;\n    alias BROWSEINFOA BROWSEINFO;\n    alias SHBrowseForFolderA SHBrowseForFolder;\n    alias SHGetDataFromIDListA SHGetDataFromIDList;\n    alias SHGetPathFromIDListA SHGetPathFromIDList;\n    static if (_WIN32_IE >= 0x400) {\n        alias SHGetSpecialFolderPathA SHGetSpecialFolderPath;\n    }\n    alias SHGetFolderPathA SHGetFolderPath;\n    static if (_WIN32_WINNT >= 0x500) {\n        alias SHGetIconOverlayIndexA SHGetIconOverlayIndex;\n        alias SHCreateDirectoryExA SHCreateDirectoryEx;\n    }\n    static if (_WIN32_WINNT >= 0x501) {\n        alias SHGetFolderPathAndSubDirA SHGetFolderPathAndSubDir;\n    }\n    alias FILEDESCRIPTORA FILEDESCRIPTOR;\n    alias LPFILEDESCRIPTORA LPFILEDESCRIPTOR;\n    alias FILEGROUPDESCRIPTORA FILEGROUPDESCRIPTOR;\n    alias LPFILEGROUPDESCRIPTORA LPFILEGROUPDESCRIPTOR;\n}\nalias BROWSEINFO* PBROWSEINFO, LPBROWSEINFO;\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    interface IFolderView : IUnknown {\n       HRESULT GetAutoArrange();\n       HRESULT GetCurrentViewMode(UINT);\n       HRESULT GetDefaultSpacing(POINT*);\n       HRESULT GetFocusedItem(int*);\n       HRESULT GetFolder(REFIID, PVOID*);\n       HRESULT GetItemPosition(LPCITEMIDLIST, POINT*);\n       HRESULT GetSelectionMarkedItem(int*);\n       HRESULT GetSpacing(POINT*);\n       HRESULT Item(int, LPITEMIDLIST*);\n       HRESULT ItemCount(UINT, int*);\n       HRESULT Items(UINT, REFIID, PVOID*);\n       HRESULT SelectAndPositionItems(UINT, LPCITEMIDLIST*, POINT*, DWORD);\n       HRESULT SelectItem(int, DWORD);\n       HRESULT SetCurrentViewMode(UINT);\n    }\n    alias IFolderView LPFOLDERVIEW;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/shlwapi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_shlwapi.d)\n */\nmodule core.sys.windows.shlwapi;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"shlwapi\");\n\n/* Changes compared to MinGW:\nwnsprintf functions are not included.\n// Macros unneeded for D\n#define StrCmpIA lstrcmpiA;\n#define StrCmpA lstrcmpA;\n#define StrCpyA lstrcpyA;\n#define StrCpyNA lstrcpynA;\n#define MAKEDLLVERULL(major, minor, build, qfe) \\\n        (((ULONGLONG)(major) << 48) | \\\n         ((ULONGLONG)(minor) << 32) | \\\n         ((ULONGLONG)(build) << 16) | \\\n         ((ULONGLONG)(  qfe) <<  0))\n*/\n\nimport core.sys.windows.objbase, core.sys.windows.shlobj;\nprivate import core.sys.windows.basetyps, core.sys.windows.objidl, core.sys.windows.unknwn, core.sys.windows.windef,\n  core.sys.windows.winbase, core.sys.windows.winreg;\n\nenum DLLVER_PLATFORM_WINDOWS = 0x00000001;\nenum DLLVER_PLATFORM_NT      = 0x00000002;\n\nenum URL_DONT_ESCAPE_EXTRA_INFO  = 0x02000000;\nenum URL_DONT_SIMPLIFY           = 0x08000000;\nenum URL_ESCAPE_PERCENT          = 0x00001000;\nenum URL_ESCAPE_SEGMENT_ONLY     = 0x00002000;\nenum URL_ESCAPE_SPACES_ONLY      = 0x04000000;\nenum URL_ESCAPE_UNSAFE           = 0x20000000;\nenum URL_INTERNAL_PATH           = 0x00800000;\nenum URL_PARTFLAG_KEEPSCHEME     = 0x00000001;\nenum URL_PLUGGABLE_PROTOCOL      = 0x40000000;\nenum URL_UNESCAPE                = 0x10000000;\nenum URL_UNESCAPE_HIGH_ANSI_ONLY = 0x00400000;\nenum URL_UNESCAPE_INPLACE        = 0x00100000;\n\nalign(1):\nstruct DLLVERSIONINFO\n{\n    DWORD cbSize = this.sizeof;\n    DWORD dwMajorVersion;\n    DWORD dwMinorVersion;\n    DWORD dwBuildNumber;\n    DWORD dwPlatformID;\n}\n\nstruct DLLVERSIONINFO2\n{\n    DLLVERSIONINFO info1;\n    DWORD dwFlags;\n    ULONGLONG ullVersion;\n}\n\nenum ASSOCSTR {\n    ASSOCSTR_COMMAND,\n    ASSOCSTR_EXECUTABLE,\n    ASSOCSTR_FRIENDLYDOCNAME,\n    ASSOCSTR_FRIENDLYAPPNAME,\n    ASSOCSTR_NOOPEN,\n    ASSOCSTR_SHELLNEWVALUE,\n    ASSOCSTR_DDECOMMAND,\n    ASSOCSTR_DDEIFEXEC,\n    ASSOCSTR_DDEAPPLICATION,\n    ASSOCSTR_DDETOPIC\n}\n\nenum ASSOCKEY\n{\n    ASSOCKEY_SHELLEXECCLASS = 1,\n    ASSOCKEY_APP,\n    ASSOCKEY_CLASS,\n    ASSOCKEY_BASECLASS\n}\n\nenum ASSOCDATA\n{\n    ASSOCDATA_MSIDESCRIPTOR = 1,\n    ASSOCDATA_NOACTIVATEHANDLER,\n    ASSOCDATA_QUERYCLASSSTORE\n}\n\nalias DWORD ASSOCF;\n\nenum SHREGDEL_FLAGS\n{\n    SHREGDEL_DEFAULT = 0x00000000,\n    SHREGDEL_HKCU    = 0x00000001,\n    SHREGDEL_HKLM    = 0x00000010,\n    SHREGDEL_BOTH    = 0x00000011\n}\n\nenum SHREGENUM_FLAGS\n{\n    SHREGENUM_DEFAULT = 0x00000000,\n    SHREGENUM_HKCU    = 0x00000001,\n    SHREGENUM_HKLM    = 0x00000010,\n    SHREGENUM_BOTH    = 0x00000011\n}\n\nenum URLIS\n{\n    URLIS_URL,\n    URLIS_OPAQUE,\n    URLIS_NOHISTORY,\n    URLIS_FILEURL,\n    URLIS_APPLIABLE,\n    URLIS_DIRECTORY,\n    URLIS_HASQUERY\n}\n\nmixin DECLARE_HANDLE!(\"HUSKEY\");\nalias HUSKEY* PHUSKEY;\n\nextern (Windows)\n{\n    alias HRESULT function (DLLVERSIONINFO *) DLLGETVERSIONPROC;\n}\n\n\nBOOL IntlStrEqNA(LPCSTR pStr1, LPCSTR pStr2, int nChar)\n{\n    return IntlStrEqWorkerA(TRUE, pStr1, pStr2, nChar);\n}\n\nBOOL IntlStrEqNW(LPCWSTR pStr1, LPCWSTR pStr2, int nChar)\n{\n    return IntlStrEqWorkerW(TRUE, pStr1, pStr2, nChar);\n}\n\nBOOL IntlStrEqNIA(LPCSTR pStr1, LPCSTR pStr2, int nChar)\n{\n    return IntlStrEqWorkerA(FALSE, pStr1, pStr2, nChar);\n}\n\nBOOL IntlStrEqNIW(LPCWSTR pStr1, LPCWSTR pStr2, int nChar)\n{\n    return IntlStrEqWorkerW(FALSE, pStr1, pStr2, nChar);\n}\n\nBOOL UrlIsFileUrlA(LPCSTR pszURL)\n{\n    return UrlIsA(pszURL, URLIS.URLIS_FILEURL);\n}\n\nBOOL UrlIsFileUrlW(LPCWSTR pszURL)\n{\n    return UrlIsW(pszURL, URLIS.URLIS_FILEURL);\n}\n\nHRESULT UrlUnescapeInPlaceA(LPSTR pszUrl, DWORD dwFlags)\n{\n    return UrlUnescapeA(pszUrl, null, null, dwFlags | URL_UNESCAPE_INPLACE);\n}\nHRESULT UrlUnescapeInPlaceW(LPWSTR pszUrl, DWORD dwFlags)\n{\n    return UrlUnescapeW(pszUrl, null, null, dwFlags | URL_UNESCAPE_INPLACE);\n}\n\nextern (Windows):\nBOOL ChrCmpIA(WORD, WORD);\nBOOL ChrCmpIW(WCHAR, WCHAR);\nBOOL IntlStrEqWorkerA(BOOL, LPCSTR, LPCSTR, int);\nBOOL IntlStrEqWorkerW(BOOL, LPCWSTR, LPCWSTR, int);\nHRESULT SHStrDupA(LPCSTR, LPWSTR*);\nHRESULT SHStrDupW(LPCWSTR, LPWSTR*);\nLPSTR StrCatA(LPSTR, LPCSTR);\nLPWSTR StrCatW(LPWSTR, LPCWSTR);\nLPSTR StrCatBuffA(LPSTR, LPCSTR, int);\nLPWSTR StrCatBuffW(LPWSTR, LPCWSTR, int);\nDWORD StrCatChainW(LPWSTR, DWORD, DWORD, LPCWSTR);\nLPSTR StrChrA(LPCSTR, WORD);\nLPWSTR StrChrW(LPCWSTR, WCHAR);\nLPSTR StrChrIA(LPCSTR, WORD);\nLPWSTR StrChrIW(LPCWSTR, WCHAR);\nint StrCmpIW(LPCWSTR, LPCWSTR);\nint StrCmpW(LPCWSTR, LPCWSTR);\nLPWSTR StrCpyW(LPWSTR, LPCWSTR);\nLPWSTR StrCpyNW(LPWSTR, LPCWSTR, int);\nint StrCmpNA(LPCSTR, LPCSTR, int);\nint StrCmpNW(LPCWSTR, LPCWSTR, int);\nint StrCmpNIA(LPCSTR, LPCSTR, int);\nint StrCmpNIW(LPCWSTR, LPCWSTR, int);\nint StrCSpnA(LPCSTR, LPCSTR);\nint StrCSpnW(LPCWSTR, LPCWSTR);\nint StrCSpnIA(LPCSTR, LPCSTR);\nint StrCSpnIW(LPCWSTR, LPCWSTR);\nLPSTR StrDupA(LPCSTR);\nLPWSTR StrDupW(LPCWSTR);\nLPSTR StrFormatByteSize64A(LONGLONG, LPSTR, UINT);\nLPSTR StrFormatByteSizeA(DWORD, LPSTR, UINT);\nLPWSTR StrFormatByteSizeW(LONGLONG, LPWSTR, UINT);\nLPSTR StrFormatKBSizeA(LONGLONG, LPSTR, UINT);\nLPWSTR StrFormatKBSizeW(LONGLONG, LPWSTR, UINT);\nint StrFromTimeIntervalA(LPSTR, UINT, DWORD, int);\nint StrFromTimeIntervalW(LPWSTR, UINT, DWORD, int);\nBOOL StrIsIntlEqualA(BOOL, LPCSTR, LPCSTR, int);\nBOOL StrIsIntlEqualW(BOOL, LPCWSTR, LPCWSTR, int);\nLPSTR StrNCatA(LPSTR, LPCSTR, int);\nLPWSTR StrNCatW(LPWSTR, LPCWSTR, int);\nLPSTR StrPBrkA(LPCSTR, LPCSTR);\nLPWSTR StrPBrkW(LPCWSTR, LPCWSTR);\nLPSTR StrRChrA(LPCSTR, LPCSTR, WORD);\nLPWSTR StrRChrW(LPCWSTR, LPCWSTR, WCHAR);\nLPSTR StrRChrIA(LPCSTR, LPCSTR, WORD);\nLPWSTR StrRChrIW(LPCWSTR, LPCWSTR, WCHAR);\nLPSTR StrRStrIA(LPCSTR, LPCSTR, LPCSTR);\nLPWSTR StrRStrIW(LPCWSTR, LPCWSTR, LPCWSTR);\nint StrSpnA(LPCSTR, LPCSTR);\nint StrSpnW(LPCWSTR, LPCWSTR);\nLPSTR StrStrA(LPCSTR, LPCSTR);\nLPSTR StrStrIA(LPCSTR, LPCSTR);\nLPWSTR StrStrIW(LPCWSTR, LPCWSTR);\nLPWSTR StrStrW(LPCWSTR, LPCWSTR);\nint StrToIntA(LPCSTR);\nint StrToIntW(LPCWSTR);\nBOOL StrToIntExA(LPCSTR, DWORD, int*);\nBOOL StrToIntExW(LPCWSTR, DWORD, int*);\nBOOL StrTrimA(LPSTR, LPCSTR);\nBOOL StrTrimW(LPWSTR, LPCWSTR);\nLPSTR PathAddBackslashA(LPSTR);\nLPWSTR PathAddBackslashW(LPWSTR);\nBOOL PathAddExtensionA(LPSTR, LPCSTR);\nBOOL PathAddExtensionW(LPWSTR, LPCWSTR);\nBOOL PathAppendA(LPSTR, LPCSTR);\nBOOL PathAppendW(LPWSTR, LPCWSTR);\nLPSTR PathBuildRootA(LPSTR, int);\nLPWSTR PathBuildRootW(LPWSTR, int);\nBOOL PathCanonicalizeA(LPSTR, LPCSTR);\nBOOL PathCanonicalizeW(LPWSTR, LPCWSTR);\nLPSTR PathCombineA(LPSTR, LPCSTR, LPCSTR);\nLPWSTR PathCombineW(LPWSTR, LPCWSTR, LPCWSTR);\nint PathCommonPrefixA(LPCSTR, LPCSTR, LPSTR);\nint PathCommonPrefixW(LPCWSTR, LPCWSTR, LPWSTR);\nBOOL PathCompactPathA(HDC, LPSTR, UINT);\nBOOL PathCompactPathW(HDC, LPWSTR, UINT);\nBOOL PathCompactPathExA(LPSTR, LPCSTR, UINT, DWORD);\nBOOL PathCompactPathExW(LPWSTR, LPCWSTR, UINT, DWORD);\nHRESULT PathCreateFromUrlA(LPCSTR, LPSTR, LPDWORD, DWORD);\nHRESULT PathCreateFromUrlW(LPCWSTR, LPWSTR, LPDWORD, DWORD);\nBOOL PathFileExistsA(LPCSTR);\nBOOL PathFileExistsW(LPCWSTR);\nLPSTR PathFindExtensionA(LPCSTR);\nLPWSTR PathFindExtensionW(LPCWSTR);\nLPSTR PathFindFileNameA(LPCSTR);\nLPWSTR PathFindFileNameW(LPCWSTR);\nLPSTR PathFindNextComponentA(LPCSTR);\nLPWSTR PathFindNextComponentW(LPCWSTR);\nBOOL PathFindOnPathA(LPSTR, LPCSTR*);\nBOOL PathFindOnPathW(LPWSTR, LPCWSTR*);\nLPCSTR PathFindSuffixArrayA(LPCSTR, LPCSTR*, int);\nLPCWSTR PathFindSuffixArrayW(LPCWSTR, LPCWSTR*, int);\nLPSTR PathGetArgsA(LPCSTR);\nLPWSTR PathGetArgsW(LPCWSTR);\nUINT PathGetCharTypeA(UCHAR);\nUINT PathGetCharTypeW(WCHAR);\nint PathGetDriveNumberA(LPCSTR);\nint PathGetDriveNumberW(LPCWSTR);\nBOOL PathIsContentTypeA(LPCSTR, LPCSTR);\nBOOL PathIsContentTypeW(LPCWSTR, LPCWSTR);\nBOOL PathIsDirectoryA(LPCSTR);\nBOOL PathIsDirectoryEmptyA(LPCSTR);\nBOOL PathIsDirectoryEmptyW(LPCWSTR);\nBOOL PathIsDirectoryW(LPCWSTR);\nBOOL PathIsFileSpecA(LPCSTR);\nBOOL PathIsFileSpecW(LPCWSTR);\nBOOL PathIsLFNFileSpecA(LPCSTR);\nBOOL PathIsLFNFileSpecW(LPCWSTR);\nBOOL PathIsNetworkPathA(LPCSTR);\nBOOL PathIsNetworkPathW(LPCWSTR);\nBOOL PathIsPrefixA(LPCSTR, LPCSTR);\nBOOL PathIsPrefixW(LPCWSTR, LPCWSTR);\nBOOL PathIsRelativeA(LPCSTR);\nBOOL PathIsRelativeW(LPCWSTR);\nBOOL PathIsRootA(LPCSTR);\nBOOL PathIsRootW(LPCWSTR);\nBOOL PathIsSameRootA(LPCSTR, LPCSTR);\nBOOL PathIsSameRootW(LPCWSTR, LPCWSTR);\nBOOL PathIsSystemFolderA(LPCSTR, DWORD);\nBOOL PathIsSystemFolderW(LPCWSTR, DWORD);\nBOOL PathIsUNCA(LPCSTR);\nBOOL PathIsUNCServerA(LPCSTR);\nBOOL PathIsUNCServerShareA(LPCSTR);\nBOOL PathIsUNCServerShareW(LPCWSTR);\nBOOL PathIsUNCServerW(LPCWSTR);\nBOOL PathIsUNCW(LPCWSTR);\nBOOL PathIsURLA(LPCSTR);\nBOOL PathIsURLW(LPCWSTR);\nBOOL PathMakePrettyA(LPSTR);\nBOOL PathMakePrettyW(LPWSTR);\nBOOL PathMakeSystemFolderA(LPSTR);\nBOOL PathMakeSystemFolderW(LPWSTR);\nBOOL PathMatchSpecA(LPCSTR, LPCSTR);\nBOOL PathMatchSpecW(LPCWSTR, LPCWSTR);\nint PathParseIconLocationA(LPSTR);\nint PathParseIconLocationW(LPWSTR);\nvoid PathQuoteSpacesA(LPSTR);\nvoid PathQuoteSpacesW(LPWSTR);\nBOOL PathRelativePathToA(LPSTR, LPCSTR, DWORD, LPCSTR, DWORD);\nBOOL PathRelativePathToW(LPWSTR, LPCWSTR, DWORD, LPCWSTR, DWORD);\nvoid PathRemoveArgsA(LPSTR);\nvoid PathRemoveArgsW(LPWSTR);\nLPSTR PathRemoveBackslashA(LPSTR);\nLPWSTR PathRemoveBackslashW(LPWSTR);\nvoid PathRemoveBlanksA(LPSTR);\nvoid PathRemoveBlanksW(LPWSTR);\nvoid PathRemoveExtensionA(LPSTR);\nvoid PathRemoveExtensionW(LPWSTR);\nBOOL PathRemoveFileSpecA(LPSTR);\nBOOL PathRemoveFileSpecW(LPWSTR);\nBOOL PathRenameExtensionA(LPSTR, LPCSTR);\nBOOL PathRenameExtensionW(LPWSTR, LPCWSTR);\nBOOL PathSearchAndQualifyA(LPCSTR, LPSTR, UINT);\nBOOL PathSearchAndQualifyW(LPCWSTR, LPWSTR, UINT);\nvoid PathSetDlgItemPathA(HWND, int, LPCSTR);\nvoid PathSetDlgItemPathW(HWND, int, LPCWSTR);\nLPSTR PathSkipRootA(LPCSTR);\nLPWSTR PathSkipRootW(LPCWSTR);\nvoid PathStripPathA(LPSTR);\nvoid PathStripPathW(LPWSTR);\nBOOL PathStripToRootA(LPSTR);\nBOOL PathStripToRootW(LPWSTR);\nvoid PathUndecorateA(LPSTR);\nvoid PathUndecorateW(LPWSTR);\nBOOL PathUnExpandEnvStringsA(LPCSTR, LPSTR, UINT);\nBOOL PathUnExpandEnvStringsW(LPCWSTR, LPWSTR, UINT);\nBOOL PathUnmakeSystemFolderA(LPSTR);\nBOOL PathUnmakeSystemFolderW(LPWSTR);\nvoid PathUnquoteSpacesA(LPSTR);\nvoid PathUnquoteSpacesW(LPWSTR);\nHRESULT SHAutoComplete(HWND, DWORD);\nBOOL SHCreateThread(LPTHREAD_START_ROUTINE, void*, DWORD, LPTHREAD_START_ROUTINE);\nDWORD SHCopyKeyA(HKEY, LPCSTR, HKEY, DWORD);\nDWORD SHCopyKeyW(HKEY, LPCWSTR, HKEY, DWORD);\nDWORD SHDeleteEmptyKeyA(HKEY, LPCSTR);\nDWORD SHDeleteEmptyKeyW(HKEY, LPCWSTR);\nDWORD SHDeleteKeyA(HKEY, LPCSTR);\nDWORD SHDeleteKeyW(HKEY, LPCWSTR);\nDWORD SHEnumKeyExA(HKEY, DWORD, LPSTR, LPDWORD);\nDWORD SHEnumKeyExW(HKEY, DWORD, LPWSTR, LPDWORD);\nDWORD SHQueryInfoKeyA(HKEY, LPDWORD, LPDWORD, LPDWORD, LPDWORD);\nDWORD SHQueryInfoKeyW(HKEY, LPDWORD, LPDWORD, LPDWORD, LPDWORD);\nDWORD SHQueryValueExA(HKEY, LPCSTR, LPDWORD, LPDWORD, LPVOID, LPDWORD);\nDWORD SHQueryValueExW(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPVOID, LPDWORD);\nHRESULT SHGetThreadRef(IUnknown*);\nHRESULT SHSetThreadRef(IUnknown);\nBOOL SHSkipJunction(IBindCtx, const(CLSID)*);\nDWORD SHEnumValueA(HKEY, DWORD, LPSTR, LPDWORD, LPDWORD, LPVOID, LPDWORD);\nDWORD SHEnumValueW(HKEY, DWORD, LPWSTR, LPDWORD, LPDWORD, LPVOID, LPDWORD);\nDWORD SHGetValueA(HKEY, LPCSTR, LPCSTR, LPDWORD, LPVOID, LPDWORD);\nDWORD SHGetValueW(HKEY, LPCWSTR, LPCWSTR, LPDWORD, LPVOID, LPDWORD);\nDWORD SHSetValueA(HKEY, LPCSTR, LPCSTR, DWORD, LPCVOID, DWORD);\nDWORD SHSetValueW(HKEY, LPCWSTR, LPCWSTR, DWORD, LPCVOID, DWORD);\nDWORD SHDeleteValueA(HKEY, LPCSTR, LPCSTR);\nDWORD SHDeleteValueW(HKEY, LPCWSTR, LPCWSTR);\nHRESULT AssocCreate(CLSID, const(IID)* , const(LPVOID)*);\nHRESULT AssocQueryKeyA(ASSOCF, ASSOCKEY, LPCSTR, LPCSTR, HKEY*);\nHRESULT AssocQueryKeyW(ASSOCF, ASSOCKEY, LPCWSTR, LPCWSTR, HKEY*);\nHRESULT AssocQueryStringA(ASSOCF, ASSOCSTR, LPCSTR, LPCSTR, LPSTR, DWORD*);\nHRESULT AssocQueryStringByKeyA(ASSOCF, ASSOCSTR, HKEY, LPCSTR, LPSTR, DWORD*);\nHRESULT AssocQueryStringByKeyW(ASSOCF, ASSOCSTR, HKEY, LPCWSTR, LPWSTR, DWORD*);\nHRESULT AssocQueryStringW(ASSOCF, ASSOCSTR, LPCWSTR, LPCWSTR, LPWSTR, DWORD*);\nHRESULT UrlApplySchemeA(LPCSTR, LPSTR, LPDWORD, DWORD);\nHRESULT UrlApplySchemeW(LPCWSTR, LPWSTR, LPDWORD, DWORD);\nHRESULT UrlCanonicalizeA(LPCSTR, LPSTR, LPDWORD, DWORD);\nHRESULT UrlCanonicalizeW(LPCWSTR, LPWSTR, LPDWORD, DWORD);\nHRESULT UrlCombineA(LPCSTR, LPCSTR, LPSTR, LPDWORD, DWORD);\nHRESULT UrlCombineW(LPCWSTR, LPCWSTR, LPWSTR, LPDWORD, DWORD);\nint UrlCompareA(LPCSTR, LPCSTR, BOOL);\nint UrlCompareW(LPCWSTR, LPCWSTR, BOOL);\nHRESULT UrlCreateFromPathA(LPCSTR, LPSTR, LPDWORD, DWORD);\nHRESULT UrlCreateFromPathW(LPCWSTR, LPWSTR, LPDWORD, DWORD);\nHRESULT UrlEscapeA(LPCSTR, LPSTR, LPDWORD, DWORD);\nHRESULT UrlEscapeW(LPCWSTR, LPWSTR, LPDWORD, DWORD);\nLPCSTR UrlGetLocationA(LPCSTR);\nLPCWSTR UrlGetLocationW(LPCWSTR);\nHRESULT UrlGetPartA(LPCSTR, LPSTR, LPDWORD, DWORD, DWORD);\nHRESULT UrlGetPartW(LPCWSTR, LPWSTR, LPDWORD, DWORD, DWORD);\nHRESULT UrlHashA(LPCSTR, LPBYTE, DWORD);\nHRESULT UrlHashW(LPCWSTR, LPBYTE, DWORD);\nBOOL UrlIsA(LPCSTR, URLIS);\nBOOL UrlIsW(LPCWSTR, URLIS);\nBOOL UrlIsNoHistoryA(LPCSTR);\nBOOL UrlIsNoHistoryW(LPCWSTR);\nBOOL UrlIsOpaqueA(LPCSTR);\nBOOL UrlIsOpaqueW(LPCWSTR);\nHRESULT UrlUnescapeA(LPSTR, LPSTR, LPDWORD, DWORD);\nHRESULT UrlUnescapeW(LPWSTR, LPWSTR, LPDWORD, DWORD);\nDWORD SHRegCloseUSKey(HUSKEY);\nLONG SHRegCreateUSKeyA(LPCSTR, REGSAM, HUSKEY, PHUSKEY, DWORD);\nLONG SHRegCreateUSKeyW(LPCWSTR, REGSAM, HUSKEY, PHUSKEY, DWORD);\nLONG SHRegDeleteEmptyUSKeyA(HUSKEY, LPCSTR, SHREGDEL_FLAGS);\nLONG SHRegDeleteEmptyUSKeyW(HUSKEY, LPCWSTR, SHREGDEL_FLAGS);\nLONG SHRegDeleteUSValueA(HUSKEY, LPCSTR, SHREGDEL_FLAGS);\nLONG SHRegDeleteUSValueW(HUSKEY, LPCWSTR, SHREGDEL_FLAGS);\nHKEY SHRegDuplicateHKey(HKEY);\nDWORD SHRegEnumUSKeyA(HUSKEY, DWORD, LPSTR, LPDWORD, SHREGENUM_FLAGS);\nDWORD SHRegEnumUSKeyW(HUSKEY, DWORD, LPWSTR, LPDWORD, SHREGENUM_FLAGS);\nDWORD SHRegEnumUSValueA(HUSKEY, DWORD, LPSTR, LPDWORD, LPDWORD, LPVOID, LPDWORD, SHREGENUM_FLAGS);\nDWORD SHRegEnumUSValueW(HUSKEY, DWORD, LPWSTR, LPDWORD, LPDWORD, LPVOID, LPDWORD, SHREGENUM_FLAGS);\nBOOL SHRegGetBoolUSValueA(LPCSTR, LPCSTR, BOOL, BOOL);\nBOOL SHRegGetBoolUSValueW(LPCWSTR, LPCWSTR, BOOL, BOOL);\nDWORD SHRegGetPathA(HKEY, LPCSTR, LPCSTR, LPSTR, DWORD);\nDWORD SHRegGetPathW(HKEY, LPCWSTR, LPCWSTR, LPWSTR, DWORD);\nLONG SHRegGetUSValueA(LPCSTR, LPCSTR, LPDWORD, LPVOID, LPDWORD, BOOL, LPVOID, DWORD);\nLONG SHRegGetUSValueW(LPCWSTR, LPCWSTR, LPDWORD, LPVOID, LPDWORD, BOOL, LPVOID, DWORD);\nLONG SHRegOpenUSKeyA(LPCSTR, REGSAM, HUSKEY, PHUSKEY, BOOL);\nLONG SHRegOpenUSKeyW(LPCWSTR, REGSAM, HUSKEY, PHUSKEY, BOOL);\nDWORD SHRegQueryInfoUSKeyA(HUSKEY, LPDWORD, LPDWORD, LPDWORD, LPDWORD, SHREGENUM_FLAGS);\nDWORD SHRegQueryInfoUSKeyW(HUSKEY, LPDWORD, LPDWORD, LPDWORD, LPDWORD, SHREGENUM_FLAGS);\nLONG SHRegQueryUSValueA(HUSKEY, LPCSTR, LPDWORD, LPVOID, LPDWORD, BOOL, LPVOID, DWORD);\nLONG SHRegQueryUSValueW(HUSKEY, LPCWSTR, LPDWORD, LPVOID, LPDWORD, BOOL, LPVOID, DWORD);\nDWORD SHRegSetPathA(HKEY, LPCSTR, LPCSTR, LPCSTR, DWORD);\nDWORD SHRegSetPathW(HKEY, LPCWSTR, LPCWSTR, LPCWSTR, DWORD);\nLONG SHRegSetUSValueA(LPCSTR, LPCSTR, DWORD, LPVOID, DWORD, DWORD);\nLONG SHRegSetUSValueW(LPCWSTR, LPCWSTR, DWORD, LPVOID, DWORD, DWORD);\nLONG SHRegWriteUSValueA(HUSKEY, LPCSTR, DWORD, LPVOID, DWORD, DWORD);\nLONG SHRegWriteUSValueW(HUSKEY, LPCWSTR, DWORD, LPVOID, DWORD, DWORD);\nHRESULT HashData(LPBYTE, DWORD, LPBYTE, DWORD);\nHPALETTE SHCreateShellPalette(HDC);\nCOLORREF ColorHLSToRGB(WORD, WORD, WORD);\nCOLORREF ColorAdjustLuma(COLORREF, int, BOOL);\nvoid ColorRGBToHLS(COLORREF, WORD*, WORD*, WORD*);\n/** Should not be necessary for D?\nextern (C):\nint  wnsprintfA(LPSTR, int, LPCSTR, ...);\nint  wnsprintfW(LPWSTR, int, LPCWSTR, ...);\nextern (Windows):\nint wvnsprintfA(LPSTR, int, LPCSTR, va_list);\nint wvnsprintfW(LPWSTR, int, LPCWSTR, va_list);\n*/\n\nHINSTANCE MLLoadLibraryA(LPCSTR, HANDLE, DWORD, LPCSTR, BOOL);\nHINSTANCE MLLoadLibraryW(LPCWSTR, HANDLE, DWORD, LPCWSTR, BOOL);\n\nHRESULT DllInstall(BOOL, LPCWSTR);\n\nHRESULT StrRetToBufA(LPSTRRET, LPCITEMIDLIST, LPSTR, UINT);\nHRESULT StrRetToBufW(LPSTRRET, LPCITEMIDLIST, LPWSTR, UINT);\nHRESULT StrRetToStrA(LPSTRRET, LPCITEMIDLIST, LPSTR*);\nHRESULT StrRetToStrW(LPSTRRET, LPCITEMIDLIST, LPWSTR*);\nHRESULT SHCreateStreamOnFileA(LPCSTR, DWORD, IStream*);\nHRESULT SHCreateStreamOnFileW(LPCWSTR, DWORD, IStream*);\nIStream SHOpenRegStream2A(HKEY, LPCSTR, LPCSTR, DWORD);\nIStream SHOpenRegStream2W(HKEY, LPCWSTR, LPCWSTR, DWORD);\nIStream SHOpenRegStreamA(HKEY, LPCSTR, LPCSTR, DWORD);\nIStream SHOpenRegStreamW(HKEY, LPCWSTR, LPCWSTR, DWORD);\n\nversion (Unicode) {\nalias ChrCmpIW ChrCmpI;\nalias IntlStrEqNW IntlStrEqN;\nalias IntlStrEqNIW IntlStrEqNI;\nalias IntlStrEqWorkerW IntlStrEqWorker;\nalias SHStrDupW SHStrDup;\nalias StrCatW StrCat;\nalias StrCatBuffW StrCatBuff;\nalias StrChrW StrChr;\nalias StrChrIW StrChrI;\nalias StrCmpW StrCmp;\nalias StrCmpIW StrCmpI;\nalias StrCmpNIW StrCmpNI;\nalias StrCmpNW StrCmpN;\nalias StrCpyNW StrCpyN;\nalias StrCpyW StrCpy;\nalias StrCSpnIW StrCSpnI;\nalias StrCSpnW StrCSpn;\nalias StrDupW StrDup;\nalias StrFormatByteSizeW StrFormatByteSize;\nalias StrFormatKBSizeW StrFormatKBSize;\nalias StrFromTimeIntervalW StrFromTimeInterval;\nalias StrIsIntlEqualW StrIsIntlEqual;\nalias StrNCatW StrNCat;\nalias StrPBrkW StrPBrk;\nalias StrRChrW StrRChr;\nalias StrRChrIW StrRChrI;\nalias StrRetToBufW StrRetToBuf;\nalias StrRetToStrW StrRetToStr;\nalias StrRStrIW StrRStrI;\nalias StrSpnW StrSpn;\nalias StrStrIW StrStrI;\nalias StrStrW StrStr;\nalias StrToIntW StrToInt;\nalias StrToIntExW StrToIntEx;\nalias StrTrimW StrTrim;\nalias PathAddBackslashW PathAddBackslash;\nalias PathAddExtensionW PathAddExtension;\nalias PathAppendW PathAppend;\nalias PathBuildRootW PathBuildRoot;\nalias PathCanonicalizeW PathCanonicalize;\nalias PathCombineW PathCombine;\nalias PathCommonPrefixW PathCommonPrefix;\nalias PathCompactPathW PathCompactPath;\nalias PathCompactPathExW PathCompactPathEx;\nalias PathCreateFromUrlW PathCreateFromUrl;\nalias PathFileExistsW PathFileExists;\nalias PathFindExtensionW PathFindExtension;\nalias PathFindFileNameW PathFindFileName;\nalias PathFindNextComponentW PathFindNextComponent;\nalias PathFindOnPathW PathFindOnPath;\nalias PathFindSuffixArrayW PathFindSuffixArray;\nalias PathGetArgsW PathGetArgs;\nalias PathGetCharTypeW PathGetCharType;\nalias PathGetDriveNumberW PathGetDriveNumber;\nalias PathIsContentTypeW PathIsContentType;\nalias PathIsDirectoryEmptyW PathIsDirectoryEmpty;\nalias PathIsDirectoryW PathIsDirectory;\nalias PathIsFileSpecW PathIsFileSpec;\nalias PathIsLFNFileSpecW PathIsLFNFileSpec;\nalias PathIsNetworkPathW PathIsNetworkPath;\nalias PathIsPrefixW PathIsPrefix;\nalias PathIsRelativeW PathIsRelative;\nalias PathIsRootW PathIsRoot;\nalias PathIsSameRootW PathIsSameRoot;\nalias PathIsSystemFolderW PathIsSystemFolder;\nalias PathIsUNCServerShareW PathIsUNCServerShare;\nalias PathIsUNCServerW PathIsUNCServer;\nalias PathIsUNCW PathIsUNC;\nalias PathIsURLW PathIsURL;\nalias PathMakePrettyW PathMakePretty;\nalias PathMakeSystemFolderW PathMakeSystemFolder;\nalias PathMatchSpecW PathMatchSpec;\nalias PathParseIconLocationW PathParseIconLocation;\nalias PathQuoteSpacesW PathQuoteSpaces;\nalias PathRelativePathToW PathRelativePathTo;\nalias PathRemoveArgsW PathRemoveArgs;\nalias PathRemoveBackslashW PathRemoveBackslash;\nalias PathRemoveBlanksW PathRemoveBlanks;\nalias PathRemoveExtensionW PathRemoveExtension;\nalias PathRemoveFileSpecW PathRemoveFileSpec;\nalias PathRenameExtensionW PathRenameExtension;\nalias PathSearchAndQualifyW PathSearchAndQualify;\nalias PathSetDlgItemPathW PathSetDlgItemPath;\nalias PathSkipRootW PathSkipRoot;\nalias PathStripPathW PathStripPath;\nalias PathStripToRootW PathStripToRoot;\nalias PathUndecorateW PathUndecorate;\nalias PathUnExpandEnvStringsW PathUnExpandEnvStrings;\nalias PathUnmakeSystemFolderW PathUnmakeSystemFolder;\nalias PathUnquoteSpacesW PathUnquoteSpaces;\nalias SHCreateStreamOnFileW SHCreateStreamOnFile;\nalias SHOpenRegStreamW SHOpenRegStream;\nalias SHOpenRegStream2W SHOpenRegStream2;\nalias SHCopyKeyW SHCopyKey;\nalias SHDeleteEmptyKeyW SHDeleteEmptyKey;\nalias SHDeleteKeyW SHDeleteKey;\nalias SHEnumKeyExW SHEnumKeyEx;\nalias SHQueryInfoKeyW SHQueryInfoKey;\nalias SHQueryValueExW SHQueryValueEx;\nalias SHEnumValueW SHEnumValue;\nalias SHGetValueW SHGetValue;\nalias SHSetValueW SHSetValue;\nalias SHDeleteValueW SHDeleteValue;\nalias AssocQueryKeyW AssocQueryKey;\nalias AssocQueryStringByKeyW AssocQueryStringByKey;\nalias AssocQueryStringW AssocQueryString;\nalias UrlApplySchemeW UrlApplyScheme;\nalias UrlCanonicalizeW UrlCanonicalize;\nalias UrlCombineW UrlCombine;\nalias UrlCompareW UrlCompare;\nalias UrlCreateFromPathW UrlCreateFromPath;\nalias UrlEscapeW UrlEscape;\nalias UrlGetLocationW UrlGetLocation;\nalias UrlGetPartW UrlGetPart;\nalias UrlHashW UrlHash;\nalias UrlIsW UrlIs;\nalias UrlIsFileUrlW UrlIsFileUrl;\nalias UrlIsNoHistoryW UrlIsNoHistory;\nalias UrlIsOpaqueW UrlIsOpaque;\nalias UrlUnescapeW UrlUnescape;\nalias UrlUnescapeInPlaceW UrlUnescapeInPlace;\nalias SHRegCreateUSKeyW SHRegCreateUSKey;\nalias SHRegDeleteEmptyUSKeyW SHRegDeleteEmptyUSKey;\nalias SHRegDeleteUSValueW SHRegDeleteUSValue;\nalias SHRegEnumUSKeyW SHRegEnumUSKey;\nalias SHRegEnumUSValueW SHRegEnumUSValue;\nalias SHRegGetBoolUSValueW SHRegGetBoolUSValue;\nalias SHRegGetPathW SHRegGetPath;\nalias SHRegGetUSValueW SHRegGetUSValue;\nalias SHRegOpenUSKeyW SHRegOpenUSKey;\nalias SHRegQueryInfoUSKeyW SHRegQueryInfoUSKey;\nalias SHRegQueryUSValueW SHRegQueryUSValue;\nalias SHRegSetPathW SHRegSetPath;\nalias SHRegSetUSValueW SHRegSetUSValue;\nalias SHRegWriteUSValueW SHRegWriteUSValue;\n//alias wnsprintfW wnsprintf;\n//alias wvnsprintfW wvnsprintf;\n} else {\nalias ChrCmpIA ChrCmpI;\nalias IntlStrEqNA IntlStrEqN;\nalias IntlStrEqNIA IntlStrEqNI;\nalias IntlStrEqWorkerA IntlStrEqWorker;\nalias SHStrDupA SHStrDup;\nalias StrCatBuffA StrCatBuff;\nalias StrChrA StrChr;\nalias StrChrIA StrChrI;\nalias StrCmpNIA StrCmpNI;\nalias StrCmpNA StrCmpN;\nalias StrCSpnIA StrCSpnI;\nalias StrCSpnA StrCSpn;\nalias StrDupA StrDup;\nalias StrFormatByteSizeA StrFormatByteSize;\nalias StrFormatKBSizeA StrFormatKBSize;\nalias StrFromTimeIntervalA StrFromTimeInterval;\nalias StrIsIntlEqualA StrIsIntlEqual;\nalias StrNCatA StrNCat;\nalias StrPBrkA StrPBrk;\nalias StrRChrA StrRChr;\nalias StrRChrIA StrRChrI;\nalias StrRetToBufA StrRetToBuf;\nalias StrRetToStrA StrRetToStr;\nalias StrRStrIA StrRStrI;\nalias StrSpnA StrSpn;\nalias StrStrIA StrStrI;\nalias StrStrA StrStr;\nalias StrToIntA StrToInt;\nalias StrToIntExA StrToIntEx;\nalias StrTrimA StrTrim;\nalias PathAddBackslashA PathAddBackslash;\nalias PathAddExtensionA PathAddExtension;\nalias PathAppendA PathAppend;\nalias PathBuildRootA PathBuildRoot;\nalias PathCanonicalizeA PathCanonicalize;\nalias PathCombineA PathCombine;\nalias PathCommonPrefixA PathCommonPrefix;\nalias PathCompactPathA PathCompactPath;\nalias PathCompactPathExA PathCompactPathEx;\nalias PathCreateFromUrlA PathCreateFromUrl;\nalias PathFileExistsA PathFileExists;\nalias PathFindExtensionA PathFindExtension;\nalias PathFindFileNameA PathFindFileName;\nalias PathFindNextComponentA PathFindNextComponent;\nalias PathFindOnPathA PathFindOnPath;\nalias PathFindSuffixArrayA PathFindSuffixArray;\nalias PathGetArgsA PathGetArgs;\nalias PathGetCharTypeA PathGetCharType;\nalias PathGetDriveNumberA PathGetDriveNumber;\nalias PathIsContentTypeA PathIsContentType;\nalias PathIsDirectoryEmptyA PathIsDirectoryEmpty;\nalias PathIsDirectoryA PathIsDirectory;\nalias PathIsFileSpecA PathIsFileSpec;\nalias PathIsLFNFileSpecA PathIsLFNFileSpec;\nalias PathIsNetworkPathA PathIsNetworkPath;\nalias PathIsPrefixA PathIsPrefix;\nalias PathIsRelativeA PathIsRelative;\nalias PathIsRootA PathIsRoot;\nalias PathIsSameRootA PathIsSameRoot;\nalias PathIsSystemFolderA PathIsSystemFolder;\nalias PathIsUNCServerShareA PathIsUNCServerShare;\nalias PathIsUNCServerA PathIsUNCServer;\nalias PathIsUNCA PathIsUNC;\nalias PathIsURLA PathIsURL;\nalias PathMakePrettyA PathMakePretty;\nalias PathMakeSystemFolderA PathMakeSystemFolder;\nalias PathMatchSpecA PathMatchSpec;\nalias PathParseIconLocationA PathParseIconLocation;\nalias PathQuoteSpacesA PathQuoteSpaces;\nalias PathRelativePathToA PathRelativePathTo;\nalias PathRemoveArgsA PathRemoveArgs;\nalias PathRemoveBackslashA PathRemoveBackslash;\nalias PathRemoveBlanksA PathRemoveBlanks;\nalias PathRemoveExtensionA PathRemoveExtension;\nalias PathRemoveFileSpecA PathRemoveFileSpec;\nalias PathRenameExtensionA PathRenameExtension;\nalias PathSearchAndQualifyA PathSearchAndQualify;\nalias PathSetDlgItemPathA PathSetDlgItemPath;\nalias PathSkipRootA PathSkipRoot;\nalias PathStripPathA PathStripPath;\nalias PathStripToRootA PathStripToRoot;\nalias PathUndecorateA PathUndecorate;\nalias PathUnExpandEnvStringsA PathUnExpandEnvStrings;\nalias PathUnmakeSystemFolderA PathUnmakeSystemFolder;\nalias PathUnquoteSpacesA PathUnquoteSpaces;\nalias SHCreateStreamOnFileA SHCreateStreamOnFile;\nalias SHOpenRegStreamA SHOpenRegStream;\nalias SHOpenRegStream2A SHOpenRegStream2;\nalias SHCopyKeyA SHCopyKey;\nalias SHDeleteEmptyKeyA SHDeleteEmptyKey;\nalias SHDeleteKeyA SHDeleteKey;\nalias SHEnumKeyExA SHEnumKeyEx;\nalias SHQueryInfoKeyA SHQueryInfoKey;\nalias SHQueryValueExA SHQueryValueEx;\nalias SHEnumValueA SHEnumValue;\nalias SHGetValueA SHGetValue;\nalias SHSetValueA SHSetValue;\nalias SHDeleteValueA SHDeleteValue;\nalias AssocQueryKeyA AssocQueryKey;\nalias AssocQueryStringByKeyA AssocQueryStringByKey;\nalias AssocQueryStringA AssocQueryString;\nalias UrlApplySchemeA UrlApplyScheme;\nalias UrlCanonicalizeA UrlCanonicalize;\nalias UrlCombineA UrlCombine;\nalias UrlCompareA UrlCompare;\nalias UrlCreateFromPathA UrlCreateFromPath;\nalias UrlEscapeA UrlEscape;\nalias UrlGetLocationA UrlGetLocation;\nalias UrlGetPartA UrlGetPart;\nalias UrlHashA UrlHash;\nalias UrlIsA UrlIs;\nalias UrlIsNoHistoryA UrlIsNoHistory;\nalias UrlIsOpaqueA UrlIsOpaque;\nalias UrlUnescapeA UrlUnescape;\nalias UrlUnescapeInPlaceA UrlUnescapeInPlace;\nalias SHRegCreateUSKeyA SHRegCreateUSKey;\nalias SHRegDeleteEmptyUSKeyA SHRegDeleteEmptyUSKey;\nalias SHRegDeleteUSValueA SHRegDeleteUSValue;\nalias SHRegEnumUSKeyA SHRegEnumUSKey;\nalias SHRegEnumUSValueA SHRegEnumUSValue;\nalias SHRegGetBoolUSValueA SHRegGetBoolUSValue;\nalias SHRegGetPathA SHRegGetPath;\nalias SHRegGetUSValueA SHRegGetUSValue;\nalias SHRegOpenUSKeyA SHRegOpenUSKey;\nalias SHRegQueryInfoUSKeyA SHRegQueryInfoUSKey;\nalias SHRegQueryUSValueA SHRegQueryUSValue;\nalias SHRegSetPathA SHRegSetPath;\nalias SHRegSetUSValueA SHRegSetUSValue;\nalias SHRegWriteUSValueA SHRegWriteUSValue;\n//alias wnsprintfA wnsprintf;\n//alias wvnsprintfA wvnsprintf;\n}\n\nalias StrToInt StrToLong;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/snmp.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_snmp.d)\n */\nmodule core.sys.windows.snmp;\nversion (Windows):\n\nprivate import core.sys.windows.windows;\n\n// These are not documented on MSDN\nenum {\n    DEFAULT_SNMP_PORT_UDP     =   161,\n    DEFAULT_SNMP_PORT_IPX     = 36879,\n    DEFAULT_SNMPTRAP_PORT_UDP =   162,\n    DEFAULT_SNMPTRAP_PORT_IPX = 36880\n}\n\nenum : BYTE {\n    ASN_UNIVERSAL                 = 0x00,\n    ASN_PRIMITIVE                 = 0x00,\n    ASN_CONSTRUCTOR               = 0x20,\n    ASN_APPLICATION               = 0x40,\n    ASN_CONTEXT                   = 0x80,\n    ASN_PRIVATE                   = 0xC0,\n\n    SNMP_PDU_GET                  = ASN_CONTEXT | ASN_CONSTRUCTOR,\n    SNMP_PDU_GETNEXT,\n    SNMP_PDU_RESPONSE,\n    SNMP_PDU_SET,\n    SNMP_PDU_GETBULK,          // = ASN_CONTEXT | ASN_CONSTRUCTOR | 4\n    SNMP_PDU_V1TRAP               = ASN_CONTEXT | ASN_CONSTRUCTOR | 4,\n    SNMP_PDU_INFORM               = ASN_CONTEXT | ASN_CONSTRUCTOR | 6,\n    SNMP_PDU_TRAP,\n    SNMP_PDU_REPORT,\n    ASN_INTEGER                   = ASN_UNIVERSAL | ASN_PRIMITIVE | 2,\n    ASN_BITS,\n    ASN_OCTETSTRING,\n    ASN_NULL,\n    ASN_OBJECTIDENTIFIER,      // = ASN_UNIVERSAL | ASN_PRIMITIVE | 6\n    ASN_INTEGER32                 = ASN_INTEGER,\n    ASN_SEQUENCE                  = ASN_UNIVERSAL | ASN_CONSTRUCTOR | 0x10,\n    ASN_SEQUENCEOF                = ASN_SEQUENCE,\n    ASN_IPADDRESS                 = ASN_APPLICATION | ASN_PRIMITIVE,\n    ASN_COUNTER32,\n    ASN_GAUGE32,\n    ASN_TIMETICKS,\n    ASN_OPAQUE,                // = ASN_APPLICATION | ASN_PRIMITIVE | 4\n    ASN_COUNTER64                 = ASN_APPLICATION | ASN_PRIMITIVE | 6,\n    ASN_UNSIGNED32,            // = ASN_APPLICATION | ASN_PRIMITIVE | 7\n    SNMP_EXCEPTION_NOSUCHOBJECT   = ASN_CONTEXT | ASN_PRIMITIVE,\n    SNMP_EXCEPTION_NOSUCHINSTANCE,\n    SNMP_EXCEPTION_ENDOFMIBVIEW,\n    SNMP_EXTENSION_GET            = SNMP_PDU_GET,\n    SNMP_EXTENSION_GET_NEXT       = SNMP_PDU_GETNEXT,\n    SNMP_EXTENSION_GET_BULK       = SNMP_PDU_GETBULK,\n    SNMP_EXTENSION_SET_TEST       = ASN_PRIVATE | ASN_CONSTRUCTOR,\n    SNMP_EXTENSION_SET_COMMIT     = SNMP_PDU_SET,\n    SNMP_EXTENSION_SET_UNDO       = ASN_PRIVATE | ASN_CONSTRUCTOR | 1,\n    SNMP_EXTENSION_SET_CLEANUP\n}\n\n\nenum : AsnInteger {\n    SNMP_ERRORSTATUS_NOERROR,\n    SNMP_ERRORSTATUS_TOOBIG,\n    SNMP_ERRORSTATUS_NOSUCHNAME,\n    SNMP_ERRORSTATUS_BADVALUE,\n    SNMP_ERRORSTATUS_READONLY,\n    SNMP_ERRORSTATUS_GENERR,\n    SNMP_ERRORSTATUS_NOACCESS,\n    SNMP_ERRORSTATUS_WRONGTYPE,\n    SNMP_ERRORSTATUS_WRONGLENGTH,\n    SNMP_ERRORSTATUS_WRONGENCODING,\n    SNMP_ERRORSTATUS_WRONGVALUE,\n    SNMP_ERRORSTATUS_NOCREATION,\n    SNMP_ERRORSTATUS_INCONSISTENTVALUE,\n    SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE,\n    SNMP_ERRORSTATUS_COMMITFAILED,\n    SNMP_ERRORSTATUS_UNDOFAILED,\n    SNMP_ERRORSTATUS_AUTHORIZATIONERROR,\n    SNMP_ERRORSTATUS_NOTWRITABLE,\n    SNMP_ERRORSTATUS_INCONSISTENTNAME\n}\n\nenum : AsnInteger {\n    SNMP_GENERICTRAP_COLDSTART,\n    SNMP_GENERICTRAP_WARMSTART,\n    SNMP_GENERICTRAP_LINKDOWN,\n    SNMP_GENERICTRAP_LINKUP,\n    SNMP_GENERICTRAP_AUTHFAILURE,\n    SNMP_GENERICTRAP_EGPNEIGHLOSS,\n    SNMP_GENERICTRAP_ENTERSPECIFIC\n}\n\n// These are not documented on MSDN\nenum {\n    SNMP_ACCESS_NONE,\n    SNMP_ACCESS_NOTIFY,\n    SNMP_ACCESS_READ_ONLY,\n    SNMP_ACCESS_READ_WRITE,\n    SNMP_ACCESS_READ_CREATE\n}\n\nenum : BOOL {\n    SNMPAPI_ERROR   = false,\n    SNMPAPI_NOERROR = true\n}\n\nenum : INT {\n    SNMP_LOG_SILENT,\n    SNMP_LOG_FATAL,\n    SNMP_LOG_ERROR,\n    SNMP_LOG_WARNING,\n    SNMP_LOG_TRACE,\n    SNMP_LOG_VERBOSE\n}\n\nenum INT\n    SNMP_OUTPUT_TO_CONSOLE  = 1,\n    SNMP_OUTPUT_TO_LOGFILE  = 2,\n    SNMP_OUTPUT_TO_EVENTLOG = 4,\n    SNMP_OUTPUT_TO_DEBUGGER = 8;\n\nenum size_t SNMP_MAX_OID_LEN = 128;\n\nenum : DWORD {\n    SNMP_MEM_ALLOC_ERROR          =  1,\n    SNMP_BERAPI_INVALID_LENGTH    = 10,\n    SNMP_BERAPI_INVALID_TAG,\n    SNMP_BERAPI_OVERFLOW,\n    SNMP_BERAPI_SHORT_BUFFER,\n    SNMP_BERAPI_INVALID_OBJELEM,\n    SNMP_PDUAPI_UNRECOGNIZED_PDU  = 20,\n    SNMP_PDUAPI_INVALID_ES,\n    SNMP_PDUAPI_INVALID_GT,\n    SNMP_AUTHAPI_INVALID_VERSION  = 30,\n    SNMP_AUTHAPI_INVALID_MSG_TYPE,\n    SNMP_AUTHAPI_TRIV_AUTH_FAILED,\n}\n\nalias INT SNMPAPI;\nalias LONG AsnInteger32;\nalias ULONG AsnUnsigned32, AsnCounter32, AsnGauge32, AsnTimeticks;\nalias ULARGE_INTEGER AsnCounter64;\n\nalign (4):\n\nstruct AsnOctetString {\nalign (4):\n    BYTE* stream;\n    UINT  length;\n    BOOL  dynamic;\n}\nalias AsnOctetString AsnBits, AsnSequence, AsnImplicitSequence,\n  AsnIPAddress, AsnNetworkAddress, AsnDisplayString, AsnOpaque;\n\nstruct AsnObjectIdentifier {\nalign (4):\n    UINT  idLength;\n    UINT* ids;\n}\nalias AsnObjectIdentifier AsnObjectName;\n\nstruct AsnAny {\nalign (4):\n    BYTE      asnType;\n    union _asnValue {\n        AsnInteger32        number;\n        AsnUnsigned32       unsigned32;\n        AsnCounter64        counter64;\n        AsnOctetString      string;\n        AsnBits             bits;\n        AsnObjectIdentifier object;\n        AsnSequence         sequence;\n        AsnIPAddress        address;\n        AsnCounter32        counter;\n        AsnGauge32          gauge;\n        AsnTimeticks        ticks;\n        AsnOpaque           arbitrary;\n    }\n    _asnValue asnValue;\n}\nalias AsnAny AsnObjectSyntax;\n\nstruct SnmpVarBind {\nalign (4):\n    AsnObjectName   name;\n    AsnObjectSyntax value;\n}\n\nstruct SnmpVarBindList {\nalign (4):\n    SnmpVarBind* list;\n    UINT         len;\n}\n\nextern (Windows) {\n    VOID SnmpExtensionClose();\n    BOOL SnmpExtensionInit(DWORD, HANDLE*, AsnObjectIdentifier*);\n    BOOL SnmpExtensionInitEx(AsnObjectIdentifier*);\n    BOOL SnmpExtensionMonitor(LPVOID);\n    BOOL SnmpExtensionQuery(BYTE, SnmpVarBindList*, AsnInteger32*,\n      AsnInteger32*);\n    BOOL SnmpExtensionQueryEx(DWORD, DWORD, SnmpVarBindList*, AsnOctetString*,\n      AsnInteger32*, AsnInteger32*);\n    BOOL SnmpExtensionTrap(AsnObjectIdentifier*, AsnInteger32*, AsnInteger32*,\n      AsnTimeticks*, SnmpVarBindList*);\n    DWORD SnmpSvcGetUptime();\n    VOID SnmpSvcSetLogLevel(INT);\n    VOID SnmpSvcSetLogType(INT);\n    SNMPAPI SnmpUtilAsnAnyCpy(AsnAny*, AsnAny*);\n    VOID SnmpUtilAsnAnyFree(AsnAny*);\n    VOID SnmpUtilDbgPrint(INT, LPSTR, ...);\n    LPSTR SnmpUtilIdsToA(UINT*, UINT);\n    LPVOID SnmpUtilMemAlloc(UINT);\n    VOID SnmpUtilMemFree(LPVOID);\n    LPVOID SnmpUtilMemReAlloc(LPVOID, UINT);\n    SNMPAPI SnmpUtilOctetsCmp(AsnOctetString*, AsnOctetString*);\n    SNMPAPI SnmpUtilOctetsCpy(AsnOctetString*, AsnOctetString*);\n    VOID SnmpUtilOctetsFree(AsnOctetString*);\n    SNMPAPI SnmpUtilOctetsNCmp(AsnOctetString*, AsnOctetString*, UINT);\n    SNMPAPI SnmpUtilOidAppend(AsnObjectIdentifier*, AsnObjectIdentifier*);\n    SNMPAPI SnmpUtilOidCmp(AsnObjectIdentifier*, AsnObjectIdentifier*);\n    SNMPAPI SnmpUtilOidCpy(AsnObjectIdentifier*, AsnObjectIdentifier*);\n    VOID SnmpUtilOidFree(AsnObjectIdentifier*);\n    SNMPAPI SnmpUtilOidNCmp(AsnObjectIdentifier*, AsnObjectIdentifier*, UINT);\n    LPSTR SnmpUtilOidToA(AsnObjectIdentifier*);\n    VOID SnmpUtilPrintAsnAny(AsnAny*);\n    VOID SnmpUtilPrintOid(AsnObjectIdentifier*);\n    SNMPAPI SnmpUtilVarBindCpy(SnmpVarBind*, SnmpVarBind*);\n    SNMPAPI SnmpUtilVarBindListCpy(SnmpVarBindList*, SnmpVarBindList*);\n    VOID SnmpUtilVarBindFree(SnmpVarBind*);\n    VOID SnmpUtilVarBindListFree(SnmpVarBindList*);\n}\n\nalias SnmpUtilMemAlloc SNMP_malloc;\nalias SnmpUtilMemFree SNMP_free;\nalias SnmpUtilMemReAlloc SNMP_realloc;\nalias SnmpUtilMemAlloc SNMP_DBG_malloc;\nalias SnmpUtilMemFree SNMP_DBG_free;\nalias SnmpUtilMemReAlloc SNMP_DBG_realloc;\nalias SnmpUtilOidAppend SNMP_oidappend;\nalias SnmpUtilOidCmp SNMP_oidcmp;\nalias SnmpUtilOidCpy SNMP_oidcpy;\nalias SnmpUtilOidFree SNMP_oidfree;\nalias SnmpUtilOidNCmp SNMP_oidncmp;\nalias SnmpUtilPrintAsnAny SNMP_printany;\nalias SnmpUtilVarBindCpy SNMP_CopyVarBind;\nalias SnmpUtilVarBindListCpy SNMP_CopyVarBindList;\nalias SnmpUtilVarBindFree SNMP_FreeVarBind;\nalias SnmpUtilVarBindListFree SNMP_FreeVarBindList;\nalias ASN_IPADDRESS ASN_RFC1155_IPADDRESS;\nalias ASN_COUNTER32 ASN_RFC1155_COUNTER;\nalias ASN_GAUGE32 ASN_RFC1155_GAUGE;\nalias ASN_TIMETICKS ASN_RFC1155_TIMETICKS;\nalias ASN_OPAQUE ASN_RFC1155_OPAQUE;\nalias ASN_OCTETSTRING ASN_RFC1213_DISPSTRING;\nalias SNMP_PDU_GET ASN_RFC1157_GETREQUEST;\nalias SNMP_PDU_GETNEXT ASN_RFC1157_GETNEXTREQUEST;\nalias SNMP_PDU_RESPONSE ASN_RFC1157_GETRESPONSE;\nalias SNMP_PDU_SET ASN_RFC1157_SETREQUEST;\nalias SNMP_PDU_V1TRAP ASN_RFC1157_TRAP;\nalias ASN_CONTEXT ASN_CONTEXTSPECIFIC;\nalias ASN_PRIMITIVE ASN_PRIMATIVE;\nalias SnmpVarBindList RFC1157VarBindList;\nalias SnmpVarBind RFC1157VarBind;\nalias AsnInteger32 AsnInteger;\nalias AsnCounter32 AsnCounter;\nalias AsnGauge32 AsnGauge;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/sql.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_sql.d)\n */\nmodule core.sys.windows.sql;\nversion (Windows):\n\npublic import core.sys.windows.sqltypes;\nprivate import core.sys.windows.windef;\n\nenum ODBCVER = 0x0351;\n\nenum SQL_ACCESSIBLE_PROCEDURES=20;\nenum SQL_ACCESSIBLE_TABLES=19;\nenum SQL_ALL_TYPES=0;\nenum SQL_ALTER_TABLE=86;\nenum SQL_API_SQLALLOCCONNECT=1;\nenum SQL_API_SQLALLOCENV=2;\nenum SQL_API_SQLALLOCSTMT=3;\nenum SQL_API_SQLBINDCOL=4;\nenum SQL_API_SQLCANCEL=5;\nenum SQL_API_SQLCOLUMNS=40;\nenum SQL_API_SQLCONNECT=7;\nenum SQL_API_SQLDATASOURCES=57;\nenum SQL_API_SQLDESCRIBECOL=8;\nenum SQL_API_SQLDISCONNECT=9;\nenum SQL_API_SQLERROR=10;\nenum SQL_API_SQLEXECDIRECT=11;\nenum SQL_API_SQLEXECUTE=12;\nenum SQL_API_SQLFETCH=13;\nenum SQL_API_SQLFREECONNECT=14;\nenum SQL_API_SQLFREEENV=15;\nenum SQL_API_SQLFREESTMT=16;\nenum SQL_API_SQLGETCONNECTOPTION=42;\nenum SQL_API_SQLGETCURSORNAME=17;\nenum SQL_API_SQLGETDATA=43;\nenum SQL_API_SQLGETFUNCTIONS=44;\nenum SQL_API_SQLGETINFO=45;\nenum SQL_API_SQLGETSTMTOPTION=46;\nenum SQL_API_SQLGETTYPEINFO=47;\nenum SQL_API_SQLNUMRESULTCOLS=18;\nenum SQL_API_SQLPARAMDATA=48;\nenum SQL_API_SQLPREPARE=19;\nenum SQL_API_SQLPUTDATA=49;\nenum SQL_API_SQLROWCOUNT=20;\nenum SQL_API_SQLSETCONNECTOPTION=50;\nenum SQL_API_SQLSETCURSORNAME=21;\nenum SQL_API_SQLSETPARAM=22;\nenum SQL_API_SQLSETSTMTOPTION=51;\nenum SQL_API_SQLSPECIALCOLUMNS=52;\nenum SQL_API_SQLSTATISTICS=53;\nenum SQL_API_SQLTABLES=54;\nenum SQL_API_SQLTRANSACT=23;\n\nenum SQL_CB_DELETE=0;\nenum SQL_CB_CLOSE=1;\nenum SQL_CB_PRESERVE=2;\n\nenum SQL_CHAR=1;\nenum SQL_CLOSE=0;\nenum SQL_COMMIT=0;\nenum SQL_CURSOR_COMMIT_BEHAVIOR=23;\nenum SQL_DATA_AT_EXEC=-2;\nenum SQL_DATA_SOURCE_NAME=2;\nenum SQL_DATA_SOURCE_READ_ONLY=25;\nenum SQL_DBMS_NAME=17;\nenum SQL_DBMS_VER=18;\nenum SQL_DECIMAL=3;\nenum SQL_DEFAULT_TXN_ISOLATION=26;\nenum SQL_DOUBLE=8;\nenum SQL_DROP=1;\nenum SQL_ERROR=-1;\n\nenum SQL_FD_FETCH_NEXT=1;\nenum SQL_FD_FETCH_FIRST=2;\nenum SQL_FD_FETCH_LAST=4;\nenum SQL_FD_FETCH_PRIOR=8;\nenum SQL_FD_FETCH_ABSOLUTE=16;\nenum SQL_FD_FETCH_RELATIVE=32;\n\nenum SQL_FETCH_ABSOLUTE=5;\nenum SQL_FETCH_DIRECTION=8;\nenum SQL_FETCH_FIRST=2;\nenum SQL_FETCH_LAST=3;\nenum SQL_FETCH_NEXT=1;\nenum SQL_FETCH_PRIOR=4;\nenum SQL_FETCH_RELATIVE=6;\nenum SQL_FLOAT=6;\nenum SQL_GD_ANY_COLUMN=1;\nenum SQL_GD_ANY_ORDER=2;\nenum SQL_GETDATA_EXTENSIONS=81;\nenum SQL_IC_LOWER=2;\nenum SQL_IC_MIXED=4;\nenum SQL_IC_SENSITIVE=3;\nenum SQL_IC_UPPER=1;\nenum SQL_IDENTIFIER_CASE=28;\nenum SQL_IDENTIFIER_QUOTE_CHAR=29;\n\nenum SQL_INDEX_ALL=1;\nenum SQL_INDEX_CLUSTERED=1;\nenum SQL_INDEX_HASHED=2;\nenum SQL_INDEX_OTHER=3;\nenum SQL_INDEX_UNIQUE=0;\n\nenum SQL_INTEGER=4;\nenum SQL_INTEGRITY=73;\nenum SQL_INVALID_HANDLE=-2;\n\nenum SQL_MAX_CATALOG_NAME_LEN=34;\nenum SQL_MAX_COLUMN_NAME_LEN=30;\nenum SQL_MAX_COLUMNS_IN_GROUP_BY=97;\nenum SQL_MAX_COLUMNS_IN_INDEX=98;\nenum SQL_MAX_COLUMNS_IN_ORDER_BY=99;\nenum SQL_MAX_COLUMNS_IN_SELECT=100;\nenum SQL_MAX_COLUMNS_IN_TABLE=101;\nenum SQL_MAX_CURSOR_NAME_LEN=31;\nenum SQL_MAX_INDEX_SIZE=102;\nenum SQL_MAX_MESSAGE_LENGTH=512;\nenum SQL_MAX_ROW_SIZE=104;\nenum SQL_MAX_SCHEMA_NAME_LEN=32;\nenum SQL_MAX_STATEMENT_LEN=105;\nenum SQL_MAX_TABLE_NAME_LEN=35;\nenum SQL_MAX_TABLES_IN_SELECT=106;\nenum SQL_MAX_USER_NAME_LEN=107;\n\nenum SQL_MAXIMUM_CATALOG_NAME_LENGTH=SQL_MAX_CATALOG_NAME_LEN;\nenum SQL_MAXIMUM_COLUMN_NAME_LENGTH=SQL_MAX_COLUMN_NAME_LEN;\nenum SQL_MAXIMUM_COLUMNS_IN_GROUP_BY=SQL_MAX_COLUMNS_IN_GROUP_BY;\nenum SQL_MAXIMUM_COLUMNS_IN_INDEX=SQL_MAX_COLUMNS_IN_INDEX;\nenum SQL_MAXIMUM_COLUMNS_IN_ORDER_BY=SQL_MAX_COLUMNS_IN_ORDER_BY;\nenum SQL_MAXIMUM_COLUMNS_IN_SELECT=SQL_MAX_COLUMNS_IN_SELECT;\nenum SQL_MAXIMUM_CURSOR_NAME_LENGTH=SQL_MAX_CURSOR_NAME_LEN;\nenum SQL_MAXIMUM_INDEX_SIZE=SQL_MAX_INDEX_SIZE;\nenum SQL_MAXIMUM_ROW_SIZE=SQL_MAX_ROW_SIZE;\nenum SQL_MAXIMUM_SCHEMA_NAME_LENGTH=SQL_MAX_SCHEMA_NAME_LEN;\nenum SQL_MAXIMUM_STATEMENT_LENGTH=SQL_MAX_STATEMENT_LEN;\nenum SQL_MAXIMUM_TABLES_IN_SELECT=SQL_MAX_TABLES_IN_SELECT;\nenum SQL_MAXIMUM_USER_NAME_LENGTH=SQL_MAX_USER_NAME_LEN;\n\nenum SQL_NC_HIGH=0;\nenum SQL_NC_LOW=1;\nenum SQL_NEED_DATA=99;\nenum SQL_NO_NULLS=0;\nenum SQL_NTS=-3;\nenum LONG SQL_NTSL=-3;\nenum SQL_NULL_COLLATION=85;\nenum SQL_NULL_DATA=-1;\nenum SQL_NULL_HDBC=0;\nenum SQL_NULL_HENV=0;\nenum SQL_NULL_HSTMT=0;\nenum SQL_NULLABLE=1;\nenum SQL_NULLABLE_UNKNOWN=2;\nenum SQL_NUMERIC=2;\nenum SQL_ORDER_BY_COLUMNS_IN_SELECT=90;\nenum SQL_PC_PSEUDO=2;\nenum SQL_PC_UNKNOWN=0;\nenum SQL_REAL=7;\nenum SQL_RESET_PARAMS=3;\nenum SQL_ROLLBACK=1;\nenum SQL_SCCO_LOCK=2;\nenum SQL_SCCO_OPT_ROWVER=4;\nenum SQL_SCCO_OPT_VALUES=8;\nenum SQL_SCCO_READ_ONLY=1;\nenum SQL_SCOPE_CURROW=0;\nenum SQL_SCOPE_SESSION=2;\nenum SQL_SCOPE_TRANSACTION=1;\nenum SQL_SCROLL_CONCURRENCY=43;\nenum SQL_SEARCH_PATTERN_ESCAPE=14;\nenum SQL_SERVER_NAME=13;\nenum SQL_SMALLINT=5;\nenum SQL_SPECIAL_CHARACTERS=94;\nenum SQL_STILL_EXECUTING=2;\n//MACRO #define SQL_SUCCEEDED(rc) (((rc)&(~1))==0)\n\nenum SQL_SUCCESS=0;\nenum SQL_SUCCESS_WITH_INFO=1;\n\nenum SQL_TC_ALL=2;\nenum SQL_TC_DDL_COMMIT=3;\nenum SQL_TC_DDL_IGNORE=4;\nenum SQL_TC_DML=1;\nenum SQL_TC_NONE=0;\n\n\nenum SQL_TXN_CAPABLE=46;\nenum SQL_TXN_ISOLATION_OPTION=72;\nenum SQL_TXN_READ_COMMITTED=2;\nenum SQL_TXN_READ_UNCOMMITTED=1;\nenum SQL_TXN_REPEATABLE_READ=4;\nenum SQL_TXN_SERIALIZABLE=8;\n\nenum SQL_TRANSACTION_CAPABLE=SQL_TXN_CAPABLE;\nenum SQL_TRANSACTION_ISOLATION_OPTION=SQL_TXN_ISOLATION_OPTION;\nenum SQL_TRANSACTION_READ_COMMITTED=SQL_TXN_READ_COMMITTED;\nenum SQL_TRANSACTION_READ_UNCOMMITTED=SQL_TXN_READ_UNCOMMITTED;\nenum SQL_TRANSACTION_REPEATABLE_READ=SQL_TXN_REPEATABLE_READ;\nenum SQL_TRANSACTION_SERIALIZABLE=SQL_TXN_SERIALIZABLE;\n\nenum SQL_UNBIND=2;\nenum SQL_UNKNOWN_TYPE=0;\nenum SQL_USER_NAME=47;\nenum SQL_VARCHAR=12;\n\nstatic if (ODBCVER >= 0x0200) {\nenum SQL_AT_ADD_COLUMN  = 1;\nenum SQL_AT_DROP_COLUMN = 2;\n}\n\nstatic if (ODBCVER >= 0x0201) {\nenum SQL_OJ_LEFT               =  1;\nenum SQL_OJ_RIGHT              =  2;\nenum SQL_OJ_FULL               =  4;\nenum SQL_OJ_NESTED             =  8;\nenum SQL_OJ_NOT_ORDERED        = 16;\nenum SQL_OJ_INNER              = 32;\nenum SQL_OJ_ALL_COMPARISON_OPS = 64;\n}\n\nstatic if (ODBCVER >= 0x0300) {\nenum SQL_AM_CONNECTION=1;\nenum SQL_AM_NONE=0;\nenum SQL_AM_STATEMENT=2;\nenum SQL_API_SQLALLOCHANDLE=1001;\nenum SQL_API_SQLBINDPARAM=1002;\nenum SQL_API_SQLCLOSECURSOR=1003;\nenum SQL_API_SQLCOLATTRIBUTE=6;\nenum SQL_API_SQLCOPYDESC=1004;\nenum SQL_API_SQLENDTRAN=1005;\nenum SQL_API_SQLFETCHSCROLL=1021;\nenum SQL_API_SQLFREEHANDLE=1006;\nenum SQL_API_SQLGETCONNECTATTR=1007;\nenum SQL_API_SQLGETDESCFIELD=1008;\nenum SQL_API_SQLGETDESCREC=1009;\nenum SQL_API_SQLGETDIAGFIELD=1010;\nenum SQL_API_SQLGETDIAGREC=1011;\nenum SQL_API_SQLGETENVATTR=1012;\nenum SQL_API_SQLGETSTMTATTR=1014;\nenum SQL_API_SQLSETCONNECTATTR=1016;\nenum SQL_API_SQLSETDESCFIELD=1017;\nenum SQL_API_SQLSETDESCREC=1018;\nenum SQL_API_SQLSETENVATTR=1019;\nenum SQL_API_SQLSETSTMTATTR=1020;\nenum SQL_ARD_TYPE=-99;\nenum SQL_AT_ADD_CONSTRAINT=8;\nenum SQL_ATTR_APP_PARAM_DESC=10011;\nenum SQL_ATTR_APP_ROW_DESC=10010;\nenum SQL_ATTR_AUTO_IPD=10001;\nenum SQL_ATTR_CURSOR_SCROLLABLE=-1;\nenum SQL_ATTR_CURSOR_SENSITIVITY=-2;\nenum SQL_ATTR_IMP_PARAM_DESC=10013;\nenum SQL_ATTR_IMP_ROW_DESC=10012;\nenum SQL_ATTR_METADATA_ID=10014;\nenum SQL_ATTR_OUTPUT_NTS=10001;\nenum SQL_CATALOG_NAME=10003;\nenum SQL_CODE_DATE=1;\nenum SQL_CODE_TIME=2;\nenum SQL_CODE_TIMESTAMP=3;\nenum SQL_COLLATION_SEQ=10004;\nenum SQL_CURSOR_SENSITIVITY=10001;\nenum SQL_DATE_LEN=10;\nenum SQL_DATETIME=9;\nenum SQL_DEFAULT=99;\n\nenum SQL_DESC_ALLOC_AUTO=1;\nenum SQL_DESC_ALLOC_USER=2;\nenum SQL_DESC_ALLOC_TYPE=1099;\nenum SQL_DESC_COUNT=1001;\nenum SQL_DESC_TYPE=1002;\nenum SQL_DESC_LENGTH=1003;\nenum SQL_DESC_OCTET_LENGTH_PTR=1004;\nenum SQL_DESC_PRECISION=1005;\nenum SQL_DESC_SCALE=1006;\nenum SQL_DESC_DATETIME_INTERVAL_CODE=1007;\nenum SQL_DESC_NULLABLE=1008;\nenum SQL_DESC_INDICATOR_PTR=1009;\nenum SQL_DESC_DATA_PTR=1010;\nenum SQL_DESC_NAME=1011;\nenum SQL_DESC_UNNAMED=1012;\nenum SQL_DESC_OCTET_LENGTH=1013;\n\nenum SQL_DESCRIBE_PARAMETER=10002;\n\nenum SQL_DIAG_ALTER_DOMAIN=3;\nenum SQL_DIAG_ALTER_TABLE=4;\nenum SQL_DIAG_CALL=7;\nenum SQL_DIAG_CLASS_ORIGIN=8;\nenum SQL_DIAG_CONNECTION_NAME=10;\nenum SQL_DIAG_CREATE_ASSERTION=6;\nenum SQL_DIAG_CREATE_CHARACTER_SET=8;\nenum SQL_DIAG_CREATE_COLLATION=10;\nenum SQL_DIAG_CREATE_DOMAIN=23;\nenum SQL_DIAG_CREATE_INDEX=-1;\nenum SQL_DIAG_CREATE_SCHEMA=64;\nenum SQL_DIAG_CREATE_TABLE=77;\nenum SQL_DIAG_CREATE_TRANSLATION=79;\nenum SQL_DIAG_CREATE_VIEW=84;\nenum SQL_DIAG_DELETE_WHERE=19;\nenum SQL_DIAG_DROP_ASSERTION=24;\nenum SQL_DIAG_DROP_CHARACTER_SET=25;\nenum SQL_DIAG_DROP_COLLATION=26;\nenum SQL_DIAG_DROP_DOMAIN=27;\nenum SQL_DIAG_DROP_INDEX=(-2);\nenum SQL_DIAG_DROP_SCHEMA=31;\nenum SQL_DIAG_DROP_TABLE=32;\nenum SQL_DIAG_DROP_TRANSLATION=33;\nenum SQL_DIAG_DROP_VIEW=36;\nenum SQL_DIAG_DYNAMIC_DELETE_CURSOR=38;\nenum SQL_DIAG_DYNAMIC_FUNCTION=7;\nenum SQL_DIAG_DYNAMIC_FUNCTION_CODE=12;\nenum SQL_DIAG_DYNAMIC_UPDATE_CURSOR=81;\nenum SQL_DIAG_GRANT=48;\nenum SQL_DIAG_INSERT=50;\nenum SQL_DIAG_MESSAGE_TEXT=6;\nenum SQL_DIAG_NATIVE=5;\nenum SQL_DIAG_NUMBER=2;\nenum SQL_DIAG_RETURNCODE=1;\nenum SQL_DIAG_REVOKE=59;\nenum SQL_DIAG_ROW_COUNT=3;\nenum SQL_DIAG_SELECT_CURSOR=85;\nenum SQL_DIAG_SERVER_NAME=11;\nenum SQL_DIAG_SQLSTATE=4;\nenum SQL_DIAG_SUBCLASS_ORIGIN=9;\nenum SQL_DIAG_UNKNOWN_STATEMENT=0;\nenum SQL_DIAG_UPDATE_WHERE=82;\n\nenum SQL_FALSE=0;\nenum SQL_HANDLE_DBC=2;\nenum SQL_HANDLE_DESC=4;\nenum SQL_HANDLE_ENV=1;\nenum SQL_HANDLE_STMT=3;\nenum SQL_INSENSITIVE=1;\nenum SQL_MAX_CONCURRENT_ACTIVITIES=1;\nenum SQL_MAX_DRIVER_CONNECTIONS=0;\nenum SQL_MAX_IDENTIFIER_LEN=10005;\nenum SQL_MAXIMUM_CONCURRENT_ACTIVITIES=SQL_MAX_CONCURRENT_ACTIVITIES;\nenum SQL_MAXIMUM_DRIVER_CONNECTIONS=SQL_MAX_DRIVER_CONNECTIONS;\nenum SQL_MAXIMUM_IDENTIFIER_LENGTH=SQL_MAX_IDENTIFIER_LEN;\nenum SQL_NAMED=0;\nenum SQL_NO_DATA=100;\nenum SQL_NONSCROLLABLE=0;\nenum SQL_NULL_HANDLE=0L;\nenum SQL_NULL_HDESC=0;\nenum SQL_OJ_CAPABILITIES=115;\nenum SQL_OUTER_JOIN_CAPABILITIES=SQL_OJ_CAPABILITIES;\nenum SQL_PC_NON_PSEUDO=1;\n\nenum SQL_PRED_NONE=0;\nenum SQL_PRED_CHAR=1;\nenum SQL_PRED_BASIC=2;\n\nenum SQL_ROW_IDENTIFIER=1;\nenum SQL_SCROLLABLE=1;\nenum SQL_SENSITIVE=2;\nenum SQL_TIME_LEN=8;\nenum SQL_TIMESTAMP_LEN=19;\nenum SQL_TRUE=1;\nenum SQL_TYPE_DATE=91;\nenum SQL_TYPE_TIME=92;\nenum SQL_TYPE_TIMESTAMP=93;\nenum SQL_UNNAMED=1;\nenum SQL_UNSPECIFIED=0;\nenum SQL_XOPEN_CLI_YEAR=10000;\n}//#endif /* ODBCVER >= 0x0300 */\n\nextern (Windows) {\n    deprecated {\n        SQLRETURN SQLAllocConnect(SQLHENV, SQLHDBC*);\n        SQLRETURN SQLAllocEnv(SQLHENV*);\n        SQLRETURN SQLAllocStmt(SQLHDBC, SQLHSTMT*);\n        SQLRETURN SQLError(SQLHENV, SQLHDBC, SQLHSTMT, SQLCHAR*, SQLINTEGER*, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n        SQLRETURN SQLFreeConnect(SQLHDBC);\n        SQLRETURN SQLFreeEnv(SQLHENV);\n        SQLRETURN SQLSetParam(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, SQLSMALLINT, SQLULEN, SQLSMALLINT, SQLPOINTER, SQLLEN*);\n        SQLRETURN SQLGetConnectOption(SQLHDBC, SQLUSMALLINT, SQLPOINTER);\n        SQLRETURN SQLGetStmtOption(SQLHSTMT, SQLUSMALLINT, SQLPOINTER);\n        SQLRETURN SQLSetConnectOption(SQLHDBC, SQLUSMALLINT, SQLULEN);\n        SQLRETURN SQLSetStmtOption(SQLHSTMT, SQLUSMALLINT, SQLROWCOUNT);\n    }\n    SQLRETURN SQLBindCol(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, SQLPOINTER, SQLLEN, SQLLEN*);\n    SQLRETURN SQLCancel(SQLHSTMT);\n    SQLRETURN SQLConnect(SQLHDBC, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLDescribeCol(SQLHSTMT, SQLUSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLSMALLINT*, SQLULEN*, SQLSMALLINT*, SQLSMALLINT*);\n    SQLRETURN SQLDisconnect(SQLHDBC);\n    SQLRETURN SQLExecDirect(SQLHSTMT, SQLCHAR*, SQLINTEGER);\n    SQLRETURN SQLExecute(SQLHSTMT);\n    SQLRETURN SQLFetch(SQLHSTMT);\n    SQLRETURN SQLFreeStmt(SQLHSTMT, SQLUSMALLINT);\n    SQLRETURN SQLGetCursorName(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLNumResultCols(SQLHSTMT, SQLSMALLINT*);\n    SQLRETURN SQLPrepare(SQLHSTMT, SQLCHAR*, SQLINTEGER);\n    SQLRETURN SQLRowCount(SQLHSTMT, SQLLEN*);\n    SQLRETURN SQLSetCursorName(SQLHSTMT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLTransact(SQLHENV, SQLHDBC, SQLUSMALLINT);\n    SQLRETURN SQLColumns(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLGetData(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, SQLPOINTER, SQLLEN, SQLLEN*);\n    SQLRETURN SQLGetFunctions(SQLHDBC, SQLUSMALLINT, SQLUSMALLINT*);\n    SQLRETURN SQLGetInfo(SQLHDBC, SQLUSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLGetTypeInfo(SQLHSTMT, SQLSMALLINT);\n    SQLRETURN SQLParamData(SQLHSTMT, SQLPOINTER*);\n    SQLRETURN SQLPutData(SQLHSTMT, SQLPOINTER, SQLLEN);\n    SQLRETURN SQLSpecialColumns(SQLHSTMT, SQLUSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLUSMALLINT, SQLUSMALLINT);\n    SQLRETURN SQLStatistics(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLUSMALLINT, SQLUSMALLINT);\n    SQLRETURN SQLTables(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLDataSources(SQLHENV, SQLUSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n\n    static if (ODBCVER >= 0x0300) {\n        SQLRETURN SQLAllocHandle(SQLSMALLINT, SQLHANDLE, SQLHANDLE*);\n        SQLRETURN SQLBindParam(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, SQLSMALLINT, SQLULEN, SQLSMALLINT, SQLPOINTER, SQLLEN*);\n        SQLRETURN SQLCloseCursor(SQLHSTMT);\n        SQLRETURN SQLColAttribute(SQLHSTMT, SQLUSMALLINT, SQLUSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*, SQLPOINTER);\n        SQLRETURN SQLCopyDesc(SQLHDESC, SQLHDESC);\n        SQLRETURN SQLEndTran(SQLSMALLINT, SQLHANDLE, SQLSMALLINT);\n        SQLRETURN SQLFetchScroll(SQLHSTMT, SQLSMALLINT, SQLROWOFFSET);\n        SQLRETURN SQLFreeHandle(SQLSMALLINT, SQLHANDLE);\n        SQLRETURN SQLGetConnectAttr(SQLHDBC, SQLINTEGER, SQLPOINTER, SQLINTEGER, SQLINTEGER*);\n        SQLRETURN SQLGetDescField(SQLHDESC, SQLSMALLINT, SQLSMALLINT, SQLPOINTER, SQLINTEGER, SQLINTEGER*);\n        SQLRETURN SQLGetDescRec(SQLHDESC, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*,\n          SQLSMALLINT*, SQLSMALLINT*, SQLLEN*, SQLSMALLINT*, SQLSMALLINT*, SQLSMALLINT*);\n        SQLRETURN SQLGetDiagField(SQLSMALLINT, SQLHANDLE, SQLSMALLINT, SQLSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*);\n        SQLRETURN SQLGetDiagRec(SQLSMALLINT, SQLHANDLE, SQLSMALLINT, SQLCHAR*, SQLINTEGER*, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n        SQLRETURN SQLGetEnvAttr(SQLHENV, SQLINTEGER, SQLPOINTER, SQLINTEGER, SQLINTEGER*);\n        SQLRETURN SQLGetStmtAttr(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER, SQLINTEGER*);\n        SQLRETURN SQLSetConnectAttr(SQLHDBC, SQLINTEGER, SQLPOINTER, SQLINTEGER);\n        SQLRETURN SQLSetDescField(SQLHDESC, SQLSMALLINT, SQLSMALLINT, SQLPOINTER, SQLINTEGER);\n        SQLRETURN SQLSetDescRec(SQLHDESC, SQLSMALLINT, SQLSMALLINT, SQLSMALLINT, SQLLEN, SQLSMALLINT,\n            SQLSMALLINT, SQLPOINTER, SQLLEN*, SQLLEN*);\n        SQLRETURN SQLSetEnvAttr(SQLHENV, SQLINTEGER, SQLPOINTER, SQLINTEGER);\n        SQLRETURN SQLSetStmtAttr(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER);\n    }/* (ODBCVER >= 0x0300) */\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/sqlext.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_sqlext.d)\n */\nmodule core.sys.windows.sqlext;\nversion (Windows):\n\n/* Conversion notes:\n   The MinGW file was a horrible mess. All of the #defines were sorted alphabetically,\n   which is crazy. This file needs a lot of work.\n   In MinGW, sqlext #includes sqlucode, but sqlucode #includes sqlext,\n   creating a circular dependency!\n*/\n\npublic import core.sys.windows.sql;\nprivate import core.sys.windows.windef;\n\nenum SQL_SPEC_MAJOR = 3;\nenum SQL_SPEC_MINOR = 51;\nconst char[] SQL_SPEC_STRING = \"03.51\";\nenum SQL_ACCESS_MODE = 101;\nenum SQL_ACTIVE_CONNECTIONS = 0;\nenum SQL_ACTIVE_STATEMENTS  = 1;\n\nenum SQL_DATE = 9;\nenum SQL_TIME = 10;\nenum SQL_SIGNED_OFFSET = -20;\nenum SQL_TINYINT = -6;\nenum SQL_TIMESTAMP = 11;\nenum SQL_UNSIGNED_OFFSET = -22;\n\nenum SQL_ADD = 4;\nenum SQL_ALL_EXCEPT_LIKE = 2;\n\nenum SQL_API_ALL_FUNCTIONS       =   0;\nenum SQL_API_SQLCOLATTRIBUTES    =   6;\nenum SQL_API_SQLDRIVERCONNECT    =  41;\nenum SQL_API_SQLBROWSECONNECT    =  55;\nenum SQL_API_SQLCOLUMNPRIVILEGES =  56;\nenum SQL_API_SQLDESCRIBEPARAM    =  58;\nenum SQL_API_SQLEXTENDEDFETCH    =  59;\nenum SQL_API_SQLFOREIGNKEYS      =  60;\nenum SQL_API_SQLMORERESULTS      =  61;\nenum SQL_API_SQLNATIVESQL        =  62;\nenum SQL_API_SQLNUMPARAMS        =  63;\nenum SQL_API_SQLPARAMOPTIONS     =  64;\nenum SQL_API_SQLPRIMARYKEYS      =  65;\nenum SQL_API_SQLPROCEDURECOLUMNS =  66;\nenum SQL_API_SQLPROCEDURES       =  67;\nenum SQL_API_SQLSETPOS           =  68;\nenum SQL_API_SQLSETSCROLLOPTIONS =  69;\nenum SQL_API_SQLTABLEPRIVILEGES  =  70;\nenum SQL_API_SQLDRIVERS          =  71;\nenum SQL_API_SQLBINDPARAMETER    =  72;\nenum SQL_API_LOADBYORDINAL       = 199;\n\nenum SQL_ASYNC_ENABLE = 4;\nenum SQL_ASYNC_ENABLE_OFF = 0UL;\nenum SQL_ASYNC_ENABLE_ON = 1UL;\nenum SQL_ASYNC_ENABLE_DEFAULT = SQL_ASYNC_ENABLE_OFF;\n\nenum SQL_ATTR_CONNECTION_DEAD = 1209;\nenum SQL_ATTR_READONLY = 0;\nenum SQL_ATTR_READWRITE_UNKNOWN = 2;\nenum SQL_ATTR_WRITE = 1;\n\nenum SQL_AUTOCOMMIT = 102;\nenum SQL_AUTOCOMMIT_OFF = 0UL;\nenum SQL_AUTOCOMMIT_ON = 1UL;\nenum SQL_AUTOCOMMIT_DEFAULT = SQL_AUTOCOMMIT_ON;\nenum SQL_BEST_ROWID = 1;\nenum SQL_BIGINT = -5;\nenum SQL_BINARY = -2;\nenum SQL_BIND_BY_COLUMN = 0UL;\nenum SQL_BIND_TYPE = 5;\nenum SQL_BIND_TYPE_DEFAULT = SQL_BIND_BY_COLUMN;\nenum SQL_BIT = -7;\n\nenum SQL_BOOKMARK_PERSISTENCE = 82;\n\n// for BOOKMARK_PERSISTENCE\nenum SQL_BP_CLOSE       = 1;\nenum SQL_BP_DELETE      = 2;\nenum SQL_BP_DROP        = 4;\nenum SQL_BP_TRANSACTION = 8;\nenum SQL_BP_UPDATE      = 16;\nenum SQL_BP_OTHER_HSTMT = 32;\nenum SQL_BP_SCROLL      = 64;\n\nenum SQL_C_BINARY    = SQL_BINARY;\nenum SQL_C_BIT       = SQL_BIT;\nenum SQL_C_CHAR      = SQL_CHAR;\nenum SQL_C_DATE      = SQL_DATE;\nenum SQL_C_DOUBLE    = SQL_DOUBLE;\nenum SQL_C_FLOAT     = SQL_REAL;\nenum SQL_C_LONG      = SQL_INTEGER;\nenum SQL_C_SHORT     = SQL_SMALLINT;\nenum SQL_C_SLONG     = SQL_C_LONG+SQL_SIGNED_OFFSET;\nenum SQL_C_SSHORT    = SQL_C_SHORT+SQL_SIGNED_OFFSET;\nenum SQL_C_STINYINT  = SQL_TINYINT+SQL_SIGNED_OFFSET;\nenum SQL_C_TIME      = SQL_TIME;\nenum SQL_C_TIMESTAMP = SQL_TIMESTAMP;\nenum SQL_C_TINYINT   = SQL_TINYINT;\nenum SQL_C_ULONG     = SQL_C_LONG+SQL_UNSIGNED_OFFSET;\nenum SQL_C_USHORT    = SQL_C_SHORT+SQL_UNSIGNED_OFFSET;\nenum SQL_C_UTINYINT  = SQL_TINYINT+SQL_UNSIGNED_OFFSET;\nenum SQL_C_BOOKMARK  = SQL_C_ULONG;\nenum SQL_C_DEFAULT   = 99;\n\nenum SQL_CASCADE = 0;\nenum SQL_CB_NON_NULL = 1;\nenum SQL_CB_NULL = 0;\ndeprecated {\nenum SQL_CC_CLOSE = SQL_CB_CLOSE;/* deprecated */\nenum SQL_CC_DELETE = SQL_CB_DELETE;/* deprecated */\nenum SQL_CC_PRESERVE = SQL_CB_PRESERVE;/* deprecated */\n}\nenum SQL_CD_FALSE = 0L;\nenum SQL_CD_TRUE = 1L;\n\nenum SQL_CN_ANY = 2;\nenum SQL_CN_DIFFERENT = 1;\nenum SQL_CN_NONE = 0;\n\nenum SQL_COLUMN_ALIAS = 87;\n\nenum SQL_COLUMN_COUNT = 0;\nenum SQL_COLUMN_NAME = 1;\nenum SQL_COLUMN_DISPLAY_SIZE = 6;\nenum SQL_COLUMN_LABEL = 18;\nenum SQL_COLUMN_LENGTH = 3;\nenum SQL_COLUMN_MONEY = 9;\nenum SQL_COLUMN_NULLABLE = 7;\nenum SQL_COLUMN_OWNER_NAME = 16;\nenum SQL_COLUMN_PRECISION = 4;\nenum SQL_COLUMN_QUALIFIER_NAME = 17;\nenum SQL_COLUMN_SCALE = 5;\nenum SQL_COLUMN_UNSIGNED = 8;\nenum SQL_COLUMN_UPDATABLE = 10;\nenum SQL_COLUMN_AUTO_INCREMENT = 11;\nenum SQL_COLUMN_CASE_SENSITIVE = 12;\nenum SQL_COLUMN_SEARCHABLE = 13;\nenum SQL_COLUMN_TYPE = 2;\nenum SQL_COLUMN_TYPE_NAME = 14;\nenum SQL_COLUMN_TABLE_NAME = 15;\n\nenum SQL_CONCAT_NULL_BEHAVIOR = 22;\n\nenum SQL_CONCUR_READ_ONLY = 1;\nenum SQL_CONCUR_DEFAULT   = SQL_CONCUR_READ_ONLY;\nenum SQL_CONCUR_LOCK      = 2;\nenum SQL_CONCUR_ROWVER    = 3;\nenum SQL_CONCUR_TIMESTAMP = SQL_CONCUR_ROWVER;/* deprecated */\nenum SQL_CONCUR_VALUES    = 4;\n\nenum SQL_CONCURRENCY = 7;\nenum SQL_CONVERT_BIGINT = 53;\nenum SQL_CONVERT_BINARY = 54;\nenum SQL_CONVERT_BIT = 55;\nenum SQL_CONVERT_CHAR = 56;\nenum SQL_CONVERT_DATE = 57;\nenum SQL_CONVERT_DECIMAL = 58;\nenum SQL_CONVERT_DOUBLE = 59;\nenum SQL_CONVERT_FLOAT = 60;\nenum SQL_CONVERT_FUNCTIONS = 48;\nenum SQL_CONVERT_INTEGER = 61;\nenum SQL_CONVERT_LONGVARBINARY = 71;\nenum SQL_CONVERT_LONGVARCHAR = 62;\nenum SQL_CONVERT_NUMERIC = 63;\nenum SQL_CONVERT_REAL = 64;\nenum SQL_CONVERT_SMALLINT = 65;\nenum SQL_CONVERT_TIME = 66;\nenum SQL_CONVERT_TIMESTAMP = 67;\nenum SQL_CONVERT_TINYINT = 68;\nenum SQL_CONVERT_VARBINARY = 69;\nenum SQL_CONVERT_VARCHAR = 70;\nenum SQL_CORRELATION_NAME = 74;\nenum SQL_CR_CLOSE = SQL_CB_CLOSE;/* deprecated */\nenum SQL_CR_DELETE = SQL_CB_DELETE;/* deprecated */\nenum SQL_CR_PRESERVE = SQL_CB_PRESERVE;/* deprecated */\n\nenum : ULONG {\n    SQL_CUR_USE_IF_NEEDED = 0,\n    SQL_CUR_USE_ODBC,\n    SQL_CUR_USE_DRIVER,\n    SQL_CUR_DEFAULT = SQL_CUR_USE_DRIVER\n}\n\nenum SQL_CURRENT_QUALIFIER = 109;\nenum SQL_CURSOR_DYNAMIC = 2UL;\nenum SQL_CURSOR_FORWARD_ONLY = 0UL;\nenum SQL_CURSOR_KEYSET_DRIVEN = 1UL;\nenum SQL_CURSOR_ROLLBACK_BEHAVIOR = 24;\nenum SQL_CURSOR_STATIC = 3UL;\nenum SQL_CURSOR_TYPE = 6;\nenum SQL_CURSOR_TYPE_DEFAULT = SQL_CURSOR_FORWARD_ONLY;\n\nenum SQL_CV_CASCADED = 0x00000004L;\nenum SQL_CV_CHECK_OPTION = 0x00000002L;\nenum SQL_CV_CREATE_VIEW = 0x00000001L;\nenum SQL_CV_LOCAL = 0x00000008L;\nenum SQL_CVT_BIGINT = 0x00004000L;\nenum SQL_CVT_BINARY = 0x00000400L;\nenum SQL_CVT_BIT = 0x00001000L;\nenum SQL_CVT_CHAR = 0x00000001L;\nenum SQL_CVT_DATE = 0x00008000L;\nenum SQL_CVT_DECIMAL = 0x00000004L;\nenum SQL_CVT_DOUBLE = 0x00000080L;\nenum SQL_CVT_FLOAT = 0x00000020L;\nenum SQL_CVT_INTEGER = 0x00000008L;\nenum SQL_CVT_LONGVARBINARY = 0x00040000L;\nenum SQL_CVT_LONGVARCHAR = 0x00000200L;\nenum SQL_CVT_NUMERIC = 0x00000002L;\nenum SQL_CVT_REAL = 0x00000040L;\nenum SQL_CVT_SMALLINT = 0x00000010L;\nenum SQL_CVT_TIME = 0x00010000L;\nenum SQL_CVT_TIMESTAMP = 0x00020000L;\nenum SQL_CVT_TINYINT = 0x00002000L;\nenum SQL_CVT_VARBINARY = 0x00000800L;\nenum SQL_CVT_VARCHAR = 0x00000100L;\nenum SQL_DATABASE_NAME = 16;/* deprecated */\n\nenum SQL_DEFAULT_PARAM = -5;\nenum SQL_DELETE = 3;\n\nenum SQL_DRIVER_COMPLETE = 1;\nenum SQL_DRIVER_COMPLETE_REQUIRED = 3;\nenum SQL_DRIVER_HDBC = 3;\nenum SQL_DRIVER_HENV = 4;\nenum SQL_DRIVER_HLIB = 76;\nenum SQL_DRIVER_HSTMT = 5;\nenum SQL_DRIVER_NAME = 6;\nenum SQL_DRIVER_NOPROMPT = 0;\nenum SQL_DRIVER_ODBC_VER = 77;\nenum SQL_DRIVER_PROMPT = 2;\nenum SQL_DRIVER_VER = 7;\n\nenum SQL_DTC_ENLIST_EXPENSIVE = 1;\nenum SQL_DTC_UNENLIST_EXPENSIVE = 2;\nenum SQL_DTC_TRANSITION_COST = 1750;\nenum SQL_ENSURE = 1;\nenum SQL_ENTIRE_ROWSET = 0;\nenum SQL_EXPRESSIONS_IN_ORDERBY = 27;\nenum SQL_FD_FETCH_BOOKMARK = 128;\nenum SQL_FD_FETCH_PREV = SQL_FD_FETCH_PRIOR;/* deprecated */\nenum SQL_FD_FETCH_RESUME = 64;\nenum SQL_FETCH_BOOKMARK = 8;\nenum SQL_FETCH_PREV = SQL_FETCH_PRIOR;/* deprecated */\nenum SQL_FETCH_RESUME = 7;/* deprecated */\n\nenum SQL_FILE_NOT_SUPPORTED = 0x0000;\nenum SQL_FILE_TABLE = 0x0001;\nenum SQL_FILE_QUALIFIER = 0x0002;\nenum SQL_FILE_CATALOG = SQL_FILE_QUALIFIER;\nenum SQL_FILE_USAGE = 84;\n\nenum SQL_FN_CVT_CONVERT = 0x00000001L;\nenum SQL_FN_NUM_ABS = 0x00000001L;\nenum SQL_FN_NUM_ACOS = 0x00000002L;\nenum SQL_FN_NUM_ASIN = 0x00000004L;\nenum SQL_FN_NUM_ATAN = 0x00000008L;\nenum SQL_FN_NUM_ATAN2 = 0x00000010L;\nenum SQL_FN_NUM_CEILING = 0x00000020L;\nenum SQL_FN_NUM_COS = 0x00000040L;\nenum SQL_FN_NUM_COT = 0x00000080L;\nenum SQL_FN_NUM_DEGREES = 0x00040000L;\nenum SQL_FN_NUM_EXP = 0x00000100L;\nenum SQL_FN_NUM_FLOOR = 0x00000200L;\nenum SQL_FN_NUM_LOG = 0x00000400L;\nenum SQL_FN_NUM_LOG10 = 0x00080000L;\nenum SQL_FN_NUM_MOD = 0x00000800L;\nenum SQL_FN_NUM_PI = 0x00010000L;\nenum SQL_FN_NUM_POWER = 0x00100000L;\nenum SQL_FN_NUM_RADIANS = 0x00200000L;\nenum SQL_FN_NUM_RAND = 0x00020000L;\nenum SQL_FN_NUM_ROUND = 0x00400000L;\nenum SQL_FN_NUM_SIGN = 0x00001000L;\nenum SQL_FN_NUM_SIN = 0x00002000L;\nenum SQL_FN_NUM_SQRT = 0x00004000L;\nenum SQL_FN_NUM_TAN = 0x00008000L;\nenum SQL_FN_NUM_TRUNCATE = 0x00800000L;\nenum SQL_FN_STR_ASCII = 0x00002000L;\nenum SQL_FN_STR_CHAR = 0x00004000L;\nenum SQL_FN_STR_CONCAT = 0x00000001L;\nenum SQL_FN_STR_DIFFERENCE = 0x00008000L;\nenum SQL_FN_STR_INSERT = 0x00000002L;\nenum SQL_FN_STR_LCASE = 0x00000040L;\nenum SQL_FN_STR_LEFT = 0x00000004L;\nenum SQL_FN_STR_LENGTH = 0x00000010L;\nenum SQL_FN_STR_LOCATE = 0x00000020L;\nenum SQL_FN_STR_LOCATE_2 = 0x00010000L;\nenum SQL_FN_STR_LTRIM = 0x00000008L;\nenum SQL_FN_STR_REPEAT = 0x00000080L;\nenum SQL_FN_STR_REPLACE = 0x00000100L;\nenum SQL_FN_STR_RIGHT = 0x00000200L;\nenum SQL_FN_STR_RTRIM = 0x00000400L;\nenum SQL_FN_STR_SOUNDEX = 0x00020000L;\nenum SQL_FN_STR_SPACE = 0x00040000L;\nenum SQL_FN_STR_SUBSTRING = 0x00000800L;\nenum SQL_FN_STR_UCASE = 0x00001000L;\nenum SQL_FN_SYS_DBNAME = 0x00000002L;\nenum SQL_FN_SYS_IFNULL = 0x00000004L;\nenum SQL_FN_SYS_USERNAME = 0x00000001L;\nenum SQL_FN_TD_CURDATE = 0x00000002L;\nenum SQL_FN_TD_CURTIME = 0x00000200L;\nenum SQL_FN_TD_DAYNAME = 0x00008000L;\nenum SQL_FN_TD_DAYOFMONTH = 0x00000004L;\nenum SQL_FN_TD_DAYOFWEEK = 0x00000008L;\nenum SQL_FN_TD_DAYOFYEAR = 0x00000010L;\nenum SQL_FN_TD_HOUR = 0x00000400L;\nenum SQL_FN_TD_MINUTE = 0x00000800L;\nenum SQL_FN_TD_MONTH = 0x00000020L;\nenum SQL_FN_TD_MONTHNAME = 0x00010000L;\nenum SQL_FN_TD_NOW = 0x00000001L;\nenum SQL_FN_TD_QUARTER = 0x00000040L;\nenum SQL_FN_TD_SECOND = 0x00001000L;\nenum SQL_FN_TD_TIMESTAMPADD = 0x00002000L;\nenum SQL_FN_TD_TIMESTAMPDIFF = 0x00004000L;\nenum SQL_FN_TD_WEEK = 0x00000080L;\nenum SQL_FN_TD_YEAR = 0x00000100L;\nenum SQL_FN_TSI_DAY = 0x00000010L;\nenum SQL_FN_TSI_FRAC_SECOND = 0x00000001L;\nenum SQL_FN_TSI_HOUR = 0x00000008L;\nenum SQL_FN_TSI_MINUTE = 0x00000004L;\nenum SQL_FN_TSI_MONTH = 0x00000040L;\nenum SQL_FN_TSI_QUARTER = 0x00000080L;\nenum SQL_FN_TSI_SECOND = 0x00000002L;\nenum SQL_FN_TSI_WEEK = 0x00000020L;\nenum SQL_FN_TSI_YEAR = 0x00000100L;\nenum SQL_GB_GROUP_BY_CONTAINS_SELECT = 2;\nenum SQL_GB_GROUP_BY_EQUALS_SELECT = 1;\nenum SQL_GB_NO_RELATION = 3;\nenum SQL_GB_NOT_SUPPORTED = 0;\nenum SQL_GD_BLOCK = 4;\nenum SQL_GD_BOUND = 8;\nenum SQL_GET_BOOKMARK = 13;\nenum SQL_GROUP_BY = 88;\nenum SQL_IGNORE = -6;\nenum SQL_INFO_FIRST = 0;\nenum SQL_KEYSET_SIZE = 8;\nenum SQL_KEYSET_SIZE_DEFAULT = 0UL;\nenum SQL_KEYWORDS = 89;\nenum SQL_LCK_EXCLUSIVE = 2;\nenum SQL_LCK_NO_CHANGE = 1;\nenum SQL_LCK_UNLOCK = 4;\n\nenum SQL_LEN_BINARY_ATTR_OFFSET  = -100;\nenum SQL_LEN_DATA_AT_EXEC_OFFSET = -100;\n//MACRO #define SQL_LEN_BINARY_ATTR(length) (-(length)+SQL_LEN_BINARY_ATTR_OFFSET)\n//MACRO #define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET)\n\nenum SQL_LIKE_ESCAPE_CLAUSE = 113;\nenum SQL_LIKE_ONLY = 1;\nenum SQL_LOCK_EXCLUSIVE = 1;\nenum SQL_LOCK_NO_CHANGE = 0;\nenum SQL_LOCK_TYPES = 78;\nenum SQL_LOCK_UNLOCK = 2;\nenum SQL_LOGIN_TIMEOUT = 103;\nenum SQL_LOGIN_TIMEOUT_DEFAULT = 15UL;\nenum SQL_LONGVARBINARY = -4;\nenum SQL_LONGVARCHAR = -1;\nenum SQL_MAX_BINARY_LITERAL_LEN = 112;\nenum SQL_MAX_CHAR_LITERAL_LEN = 108;\nenum SQL_MAX_DSN_LENGTH = 32;\nenum SQL_MAX_LENGTH = 3;\nenum SQL_MAX_LENGTH_DEFAULT = 0UL;\nenum SQL_MAX_OPTION_STRING_LENGTH = 256;\nenum SQL_MAX_OWNER_NAME_LEN = 32;\nenum SQL_MAX_PROCEDURE_NAME_LEN = 33;\nenum SQL_MAX_QUALIFIER_NAME_LEN = 34;\nenum SQL_MAX_ROW_SIZE_INCLUDES_LONG = 103;\nenum SQL_MAX_ROWS = 1;\nenum SQL_MAX_ROWS_DEFAULT = 0UL;\n\nenum SQL_MODE_READ_WRITE = 0UL;\nenum SQL_MODE_READ_ONLY = 1UL;\nenum SQL_MODE_DEFAULT = SQL_MODE_READ_WRITE;\n\nenum SQL_MULT_RESULT_SETS = 36;\nenum SQL_MULTIPLE_ACTIVE_TXN = 37;\nenum SQL_NC_END = 0x0004;\nenum SQL_NC_START = 0x0002;\nenum SQL_NEED_LONG_DATA_LEN = 111;\nenum SQL_NNC_NON_NULL = 0x0001;\nenum SQL_NNC_NULL = 0x0000;\nenum SQL_NO_TOTAL = -4;\nenum SQL_NON_NULLABLE_COLUMNS = 75;\n\nenum SQL_NOSCAN_OFF = 0UL;\nenum SQL_NOSCAN_ON = 1UL;\nenum SQL_NOSCAN = 2;\nenum SQL_NOSCAN_DEFAULT = SQL_NOSCAN_OFF;\n\nenum SQL_NUMERIC_FUNCTIONS = 49;\nenum SQL_OAC_LEVEL1 = 0x0001;\nenum SQL_OAC_LEVEL2 = 0x0002;\nenum SQL_OAC_NONE = 0x0000;\nenum SQL_ODBC_API_CONFORMANCE = 9;\nenum SQL_ODBC_CURSORS = 110;\nenum SQL_ODBC_SAG_CLI_CONFORMANCE = 12;\nenum SQL_ODBC_SQL_CONFORMANCE = 15;\nenum SQL_ODBC_SQL_OPT_IEF = 73;\nenum SQL_ODBC_VER = 10;\nenum SQL_OPT_TRACE = 104;\n\nenum SQL_OPT_TRACE_FILE_DEFAULT = \"\\\\SQL.LOG\";\nenum SQL_OPT_TRACE_OFF = 0UL;\nenum SQL_OPT_TRACE_DEFAULT = SQL_OPT_TRACE_OFF;\nenum SQL_OPT_TRACE_ON = 1UL;\n\nenum SQL_OPT_TRACEFILE = 105;\nenum SQL_OSC_CORE = 1;\nenum SQL_OSC_EXTENDED = 2;\nenum SQL_OSC_MINIMUM = 0;\nenum SQL_OSCC_COMPLIANT = 1;\nenum SQL_OSCC_NOT_COMPLIANT = 0;\nenum SQL_OU_DML_STATEMENTS = 1;\nenum SQL_OU_INDEX_DEFINITION = 8;\nenum SQL_OU_PRIVILEGE_DEFINITION = 16;\nenum SQL_OU_PROCEDURE_INVOCATION = 2;\nenum SQL_OU_TABLE_DEFINITION = 4;\nenum SQL_OUTER_JOINS = 38;\nenum SQL_OWNER_TERM = 39;\nenum SQL_OWNER_USAGE = 91;\nenum SQL_PACKET_SIZE = 112;\nenum SQL_PARAM_INPUT = 1;\nenum SQL_PARAM_INPUT_OUTPUT = 2;\nenum SQL_PARAM_OUTPUT = 4;\nenum SQL_PARAM_TYPE_DEFAULT = SQL_PARAM_INPUT_OUTPUT;\nenum SQL_PARAM_TYPE_UNKNOWN = 0;\nenum SQL_PC_NOT_PSEUDO = 1;\nenum SQL_POS_ADD = 16;\nenum SQL_POS_DELETE = 8;\nenum SQL_POS_OPERATIONS = 79;\nenum SQL_POS_POSITION = 1;\nenum SQL_POS_REFRESH = 2;\nenum SQL_POS_UPDATE = 4;\nenum SQL_POSITION = 0;\nenum SQL_POSITIONED_STATEMENTS = 80;\nenum SQL_PROCEDURE_TERM = 40;\nenum SQL_PROCEDURES = 21;\nenum SQL_PS_POSITIONED_DELETE = 1;\nenum SQL_PS_POSITIONED_UPDATE = 2;\nenum SQL_PS_SELECT_FOR_UPDATE = 4;\nenum SQL_PT_FUNCTION = 2;\nenum SQL_PT_PROCEDURE = 1;\nenum SQL_PT_UNKNOWN = 0;\nenum SQL_QL_END = 0x0002;\nenum SQL_QL_START = 0x0001;\nenum SQL_QU_DML_STATEMENTS = 1;\nenum SQL_QU_INDEX_DEFINITION = 8;\nenum SQL_QU_PRIVILEGE_DEFINITION = 16;\nenum SQL_QU_PROCEDURE_INVOCATION = 2;\nenum SQL_QU_TABLE_DEFINITION = 4;\nenum SQL_QUALIFIER_LOCATION = 114;\nenum SQL_QUALIFIER_NAME_SEPARATOR = 41;\nenum SQL_QUALIFIER_TERM = 42;\nenum SQL_QUALIFIER_USAGE = 92;\nenum SQL_QUERY_TIMEOUT = 0;\nenum SQL_QUERY_TIMEOUT_DEFAULT = 0UL;\nenum SQL_QUICK = 0;\nenum SQL_QUIET_MODE = 111;\nenum SQL_QUOTED_IDENTIFIER_CASE = 93;\n\nenum SQL_RD_OFF = 0UL;\nenum SQL_RD_ON = 1UL;\nenum SQL_RD_DEFAULT = SQL_RD_ON;\n\nenum SQL_REFRESH = 1;\nenum SQL_RESTRICT = 1;\nenum SQL_RESULT_COL = 3;\nenum SQL_RETRIEVE_DATA = 11;\nenum SQL_RETURN_VALUE = 5;\nenum SQL_ROW_ADDED = 4;\nenum SQL_ROW_DELETED = 1;\nenum SQL_ROW_ERROR = 5;\nenum SQL_ROW_NOROW = 3;\nenum SQL_ROW_NUMBER = 14;\nenum SQL_ROW_SUCCESS = 0;\nenum SQL_ROW_UPDATED = 2;\nenum SQL_ROW_UPDATES = 11;\nenum SQL_ROWSET_SIZE = 9;\nenum SQL_ROWSET_SIZE_DEFAULT = 1UL;\nenum SQL_ROWVER = 2;\nenum SQL_SC_NON_UNIQUE = 0UL;\nenum SQL_SC_TRY_UNIQUE = 1UL;\nenum SQL_SC_UNIQUE = 2UL;\nenum SQL_SCCO_OPT_TIMESTAMP = SQL_SCCO_OPT_ROWVER;/* deprecated */\nenum SQL_SCROLL_DYNAMIC = -2L;/* deprecated */\nenum SQL_SCROLL_FORWARD_ONLY = 0L;/* deprecated */\nenum SQL_SCROLL_KEYSET_DRIVEN = -1L;/* deprecated */\nenum SQL_SCROLL_OPTIONS = 44;\nenum SQL_SCROLL_STATIC = -3L;/* deprecated */\nenum SQL_SEARCHABLE = 3;\nenum SQL_SET_NULL = 2;\nenum SQL_SETPARAM_VALUE_MAX = -1L;\nenum SQL_SETPOS_MAX_LOCK_VALUE = SQL_LOCK_UNLOCK;\nenum SQL_SETPOS_MAX_OPTION_VALUE = SQL_ADD;\nenum SQL_SIMULATE_CURSOR = 10;\nenum SQL_SO_DYNAMIC = 4;\nenum SQL_SO_FORWARD_ONLY = 1;\nenum SQL_SO_KEYSET_DRIVEN = 2;\nenum SQL_SO_MIXED = 8;\nenum SQL_SO_STATIC = 16;\nenum SQL_SQ_COMPARISON = 1;\nenum SQL_SQ_CORRELATED_SUBQUERIES = 16;\nenum SQL_SQ_EXISTS = 2;\nenum SQL_SQ_IN = 4;\nenum SQL_SQ_QUANTIFIED = 8;\nenum SQL_SQLSTATE_SIZE = 5;\nenum SQL_SS_ADDITIONS = 1;\nenum SQL_SS_DELETIONS = 2;\nenum SQL_SS_UPDATES = 4;\nenum SQL_STATIC_SENSITIVITY = 83;\nenum SQL_STRING_FUNCTIONS = 50;\nenum SQL_SUBQUERIES = 95;\nenum SQL_SYSTEM_FUNCTIONS = 51;\nenum SQL_TABLE_STAT = 0;\nenum SQL_TABLE_TERM = 45;\nenum SQL_TIMEDATE_ADD_INTERVALS = 109;\nenum SQL_TIMEDATE_DIFF_INTERVALS = 110;\nenum SQL_TIMEDATE_FUNCTIONS = 52;\nenum SQL_TRANSLATE_DLL = 106;\nenum SQL_TRANSLATE_OPTION = 107;\nenum SQL_TXN_ISOLATION = 108;\nenum SQL_TXN_VERSIONING = 16;\nenum SQL_TYPE_NULL = 0;\nenum SQL_U_UNION = 1;\nenum SQL_U_UNION_ALL = 2;\n\nenum SQL_UB_OFF = 0UL;\nenum SQL_UB_DEFAULT = SQL_UB_OFF;\nenum SQL_UB_ON = 01UL;\n\nenum SQL_UNION = 96;\nenum SQL_UNSEARCHABLE = 0;\nenum SQL_UPDATE = 2;\nenum SQL_USE_BOOKMARKS = 12;\nenum SQL_VARBINARY = -3;\n\nenum SQL_COLATT_OPT_MAX = SQL_COLUMN_LABEL;\nenum SQL_COLATT_OPT_MIN = SQL_COLUMN_COUNT;\nenum SQL_PRED_SEARCHABLE = SQL_SEARCHABLE;\n\n//MACRO #define SQL_POSITION_TO(s, r) SQLSetPos(s, r, SQL_POSITION, SQL_LOCK_NO_CHANGE)\n\n//MACRO #define SQL_LOCK_RECORD(s, r, l) SQLSetPos(s, r, SQL_POSITION, l)\n\n//MACRO #define SQL_REFRESH_RECORD(s, r, l) SQLSetPos(s, r, SQL_REFRESH, l)\n\n//MACRO #define SQL_UPDATE_RECORD(s, r) SQLSetPos(s, r, SQL_UPDATE, SQL_LOCK_NO_CHANGE)\n\n//MACRO #define SQL_DELETE_RECORD(s, r) SQLSetPos(s, r, SQL_DELETE, SQL_LOCK_NO_CHANGE)\n\n//MACRO #define SQL_ADD_RECORD(s, r) SQLSetPos(s, r, SQL_ADD, SQL_LOCK_NO_CHANGE)\n\n\nstatic if (ODBCVER < 0x0300) {\nenum SQL_CONNECT_OPT_DRVR_START = 1000;\nenum SQL_CONN_OPT_MAX = SQL_PACKET_SIZE;\nenum SQL_CONN_OPT_MIN = SQL_ACCESS_MODE;\nenum SQL_STMT_OPT_MAX = SQL_ROW_NUMBER;\nenum SQL_STMT_OPT_MIN = SQL_QUERY_TIMEOUT;\nenum SQL_TYPE_DRIVER_START = SQL_INTERVAL_YEAR;\nenum SQL_TYPE_DRIVER_END = SQL_UNICODE_LONGVARCHAR;\nenum SQL_TYPE_MIN = SQL_BIT;\nenum SQL_TYPE_MAX = SQL_VARCHAR;\n}\n\nstatic if (ODBCVER < 0x0300) {\nenum SQL_NO_DATA_FOUND = 100;\nenum SQL_INTERVAL_YEAR = -80;\nenum SQL_INTERVAL_MONTH = -81;\nenum SQL_INTERVAL_YEAR_TO_MONTH = -82;\nenum SQL_INTERVAL_DAY = -83;\nenum SQL_INTERVAL_HOUR = -84;\nenum SQL_INTERVAL_MINUTE = -85;\nenum SQL_INTERVAL_SECOND = -86;\nenum SQL_INTERVAL_DAY_TO_HOUR = -87;\nenum SQL_INTERVAL_DAY_TO_MINUTE = -88;\nenum SQL_INTERVAL_DAY_TO_SECOND = -89;\nenum SQL_INTERVAL_HOUR_TO_MINUTE = -90;\nenum SQL_INTERVAL_HOUR_TO_SECOND = -91;\nenum SQL_INTERVAL_MINUTE_TO_SECOND = -92;\n} else {\nenum SQL_NO_DATA_FOUND = SQL_NO_DATA;\nenum SQL_CODE_YEAR = 1;\nenum SQL_CODE_MONTH = 2;\nenum SQL_CODE_DAY = 3;\nenum SQL_CODE_HOUR = 4;\nenum SQL_CODE_MINUTE = 5;\nenum SQL_CODE_SECOND = 6;\nenum SQL_CODE_YEAR_TO_MONTH = 7;\nenum SQL_CODE_DAY_TO_HOUR = 8;\nenum SQL_CODE_DAY_TO_MINUTE = 9;\nenum SQL_CODE_DAY_TO_SECOND = 10;\nenum SQL_CODE_HOUR_TO_MINUTE = 11;\nenum SQL_CODE_HOUR_TO_SECOND = 12;\nenum SQL_CODE_MINUTE_TO_SECOND = 13;\nenum SQL_INTERVAL_YEAR = 100 + SQL_CODE_YEAR;\nenum SQL_INTERVAL_MONTH = 100 + SQL_CODE_MONTH;\nenum SQL_INTERVAL_DAY = 100 + SQL_CODE_DAY;\nenum SQL_INTERVAL_HOUR = 100 + SQL_CODE_HOUR;\nenum SQL_INTERVAL_MINUTE = 100 + SQL_CODE_MINUTE;\nenum SQL_INTERVAL_SECOND = 100 + SQL_CODE_SECOND;\nenum SQL_INTERVAL_YEAR_TO_MONTH = 100 + SQL_CODE_YEAR_TO_MONTH;\nenum SQL_INTERVAL_DAY_TO_HOUR = 100 + SQL_CODE_DAY_TO_HOUR;\nenum SQL_INTERVAL_DAY_TO_MINUTE = 100 + SQL_CODE_DAY_TO_MINUTE;\nenum SQL_INTERVAL_DAY_TO_SECOND = 100 + SQL_CODE_DAY_TO_SECOND;\nenum SQL_INTERVAL_HOUR_TO_MINUTE = 100 + SQL_CODE_HOUR_TO_MINUTE;\nenum SQL_INTERVAL_HOUR_TO_SECOND = 100 + SQL_CODE_HOUR_TO_SECOND;\nenum SQL_INTERVAL_MINUTE_TO_SECOND = 100 + SQL_CODE_MINUTE_TO_SECOND;\n}//[Yes] #endif\n\n\nstatic if ((ODBCVER >= 0x0201) && (ODBCVER < 0x0300)) {\nenum SQL_OJ_CAPABILITIES = 65003;\n}\n\nstatic if (ODBCVER >= 0x0250) {\nenum SQL_NO_ACTION   = 3;\nenum SQL_SET_DEFAULT = 4;\n}\n\nstatic if (ODBCVER >= 0x0300) {\nenum SQL_ACTIVE_ENVIRONMENTS = 116;\nenum SQL_AD_ADD_CONSTRAINT_DEFERRABLE = 0x00000080L;\nenum SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED = 0x00000020L;\nenum SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE = 0x00000040L;\nenum SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE = 0x00000100L;\nenum SQL_AD_ADD_DOMAIN_CONSTRAINT = 0x00000002L;\nenum SQL_AD_ADD_DOMAIN_DEFAULT = 0x00000008L;\nenum SQL_AD_CONSTRAINT_NAME_DEFINITION = 0x00000001L;\nenum SQL_AD_DROP_DOMAIN_CONSTRAINT = 0x00000004L;\nenum SQL_AD_DROP_DOMAIN_DEFAULT = 0x00000010L;\nenum SQL_AF_ALL = 0x00000040L;\nenum SQL_AF_AVG = 0x00000001L;\nenum SQL_AF_COUNT = 0x00000002L;\nenum SQL_AF_DISTINCT = 0x00000020L;\nenum SQL_AF_MAX = 0x00000004L;\nenum SQL_AF_MIN = 0x00000008L;\nenum SQL_AF_SUM = 0x00000010L;\nenum SQL_AGGREGATE_FUNCTIONS = 169;\nenum SQL_ALL_CATALOGS = \"%\";\nenum SQL_ALL_SCHEMAS = \"%\";\nenum SQL_ALL_TABLE_TYPES = \"%\";\nenum SQL_ALTER_DOMAIN = 117;\nenum SQL_AM_CONNECTION = 1;\nenum SQL_AM_NONE = 0;\nenum SQL_AM_STATEMENT = 2;\nenum SQL_API_ODBC3_ALL_FUNCTIONS = 999;\nenum SQL_API_ODBC3_ALL_FUNCTIONS_SIZE = 250;\nenum SQL_API_SQLALLOCHANDLESTD = 73;\nenum SQL_API_SQLBULKOPERATIONS = 24;\nenum SQL_ASYNC_MODE = 10021;\nenum SQL_AT_ADD_COLUMN_COLLATION = 0x00000080L;\nenum SQL_AT_ADD_COLUMN_DEFAULT = 0x00000040L;\nenum SQL_AT_ADD_COLUMN_SINGLE = 0x00000020L;\nenum SQL_AT_ADD_TABLE_CONSTRAINT = 0x00001000L;\nenum SQL_AT_CONSTRAINT_DEFERRABLE = 0x00040000L;\nenum SQL_AT_CONSTRAINT_INITIALLY_DEFERRED = 0x00010000L;\nenum SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE = 0x00020000L;\nenum SQL_AT_CONSTRAINT_NAME_DEFINITION = 0x00008000L;\nenum SQL_AT_CONSTRAINT_NON_DEFERRABLE = 0x00080000L;\nenum SQL_AT_DROP_COLUMN_CASCADE = 0x00000400L;\nenum SQL_AT_DROP_COLUMN_DEFAULT = 0x00000200L;\nenum SQL_AT_DROP_COLUMN_RESTRICT = 0x00000800L;\nenum SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE = 0x00002000L;\nenum SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT = 0x00004000L;\nenum SQL_AT_SET_COLUMN_DEFAULT = 0x00000100L;\nenum SQL_ATTR_ACCESS_MODE = SQL_ACCESS_MODE;\nenum SQL_ATTR_ASYNC_ENABLE = 4;\nenum SQL_ATTR_AUTOCOMMIT = SQL_AUTOCOMMIT;\nenum SQL_ATTR_CONCURRENCY = SQL_CONCURRENCY;\nenum SQL_ATTR_CONNECTION_POOLING = 201;\nenum SQL_ATTR_CONNECTION_TIMEOUT = 113;\nenum SQL_ATTR_CP_MATCH = 202;\nenum SQL_ATTR_CURRENT_CATALOG = SQL_CURRENT_QUALIFIER;\nenum SQL_ATTR_CURSOR_TYPE = SQL_CURSOR_TYPE;\nenum SQL_ATTR_DISCONNECT_BEHAVIOR = 114;\nenum SQL_ATTR_ENABLE_AUTO_IPD = 15;\nenum SQL_ATTR_ENLIST_IN_DTC = 1207;\nenum SQL_ATTR_ENLIST_IN_XA = 1208;\nenum SQL_ATTR_FETCH_BOOKMARK_PTR = 16;\nenum SQL_ATTR_KEYSET_SIZE = SQL_KEYSET_SIZE;\nenum SQL_ATTR_LOGIN_TIMEOUT = SQL_LOGIN_TIMEOUT;\nenum SQL_ATTR_MAX_LENGTH = SQL_MAX_LENGTH;\nenum SQL_ATTR_MAX_ROWS = SQL_MAX_ROWS;\nenum SQL_ATTR_NOSCAN = SQL_NOSCAN;\nenum SQL_ATTR_ODBC_CURSORS = SQL_ODBC_CURSORS;\nenum SQL_ATTR_ODBC_VERSION = 200;\nenum SQL_ATTR_PACKET_SIZE = SQL_PACKET_SIZE;\nenum SQL_ATTR_PARAM_BIND_OFFSET_PTR = 17;\nenum SQL_ATTR_PARAM_BIND_TYPE = 18;\nenum SQL_ATTR_PARAM_OPERATION_PTR = 19;\nenum SQL_ATTR_PARAM_STATUS_PTR = 20;\nenum SQL_ATTR_PARAMS_PROCESSED_PTR = 21;\nenum SQL_ATTR_PARAMSET_SIZE = 22;\nenum SQL_ATTR_QUERY_TIMEOUT = SQL_QUERY_TIMEOUT;\nenum SQL_ATTR_QUIET_MODE = SQL_QUIET_MODE;\nenum SQL_ATTR_RETRIEVE_DATA = SQL_RETRIEVE_DATA;\nenum SQL_ATTR_ROW_ARRAY_SIZE = 27;\nenum SQL_ATTR_ROW_BIND_OFFSET_PTR = 23;\nenum SQL_ATTR_ROW_BIND_TYPE = SQL_BIND_TYPE;\nenum SQL_ATTR_ROW_NUMBER = SQL_ROW_NUMBER;\nenum SQL_ATTR_ROW_OPERATION_PTR = 24;\nenum SQL_ATTR_ROW_STATUS_PTR = 25;\nenum SQL_ATTR_ROWS_FETCHED_PTR = 26;\nenum SQL_ATTR_SIMULATE_CURSOR = SQL_SIMULATE_CURSOR;\nenum SQL_ATTR_TRACE = SQL_OPT_TRACE;\nenum SQL_ATTR_TRACEFILE = SQL_OPT_TRACEFILE;\nenum SQL_ATTR_TRANSLATE_LIB = SQL_TRANSLATE_DLL;\nenum SQL_ATTR_TRANSLATE_OPTION = SQL_TRANSLATE_OPTION;\nenum SQL_ATTR_TXN_ISOLATION = SQL_TXN_ISOLATION;\nenum SQL_ATTR_USE_BOOKMARKS = SQL_USE_BOOKMARKS;\nenum SQL_BATCH_ROW_COUNT = 120;\nenum SQL_BATCH_SUPPORT = 121;\nenum SQL_BRC_EXPLICIT = 0x0000002;\nenum SQL_BRC_PROCEDURES = 0x0000001;\nenum SQL_BRC_ROLLED_UP = 0x0000004;\nenum SQL_BS_ROW_COUNT_EXPLICIT = 0x00000002L;\nenum SQL_BS_ROW_COUNT_PROC = 0x00000008L;\nenum SQL_BS_SELECT_EXPLICIT = 0x00000001L;\nenum SQL_BS_SELECT_PROC = 0x00000004L;\nenum SQL_C_INTERVAL_DAY = SQL_INTERVAL_DAY;\nenum SQL_C_INTERVAL_DAY_TO_HOUR = SQL_INTERVAL_DAY_TO_HOUR;\nenum SQL_C_INTERVAL_DAY_TO_MINUTE = SQL_INTERVAL_DAY_TO_MINUTE;\nenum SQL_C_INTERVAL_DAY_TO_SECOND = SQL_INTERVAL_DAY_TO_SECOND;\nenum SQL_C_INTERVAL_HOUR = SQL_INTERVAL_HOUR;\nenum SQL_C_INTERVAL_HOUR_TO_MINUTE = SQL_INTERVAL_HOUR_TO_MINUTE;\nenum SQL_C_INTERVAL_HOUR_TO_SECOND = SQL_INTERVAL_HOUR_TO_SECOND;\nenum SQL_C_INTERVAL_MINUTE = SQL_INTERVAL_MINUTE;\nenum SQL_C_INTERVAL_MINUTE_TO_SECOND = SQL_INTERVAL_MINUTE_TO_SECOND;\nenum SQL_C_INTERVAL_MONTH = SQL_INTERVAL_MONTH;\nenum SQL_C_INTERVAL_SECOND = SQL_INTERVAL_SECOND;\nenum SQL_C_INTERVAL_YEAR = SQL_INTERVAL_YEAR;\nenum SQL_C_INTERVAL_YEAR_TO_MONTH = SQL_INTERVAL_YEAR_TO_MONTH;\nenum SQL_C_NUMERIC = SQL_NUMERIC;\nenum SQL_C_SBIGINT = SQL_BIGINT+SQL_SIGNED_OFFSET;\nenum SQL_C_TYPE_DATE = SQL_TYPE_DATE;\nenum SQL_C_TYPE_TIME = SQL_TYPE_TIME;\nenum SQL_C_TYPE_TIMESTAMP = SQL_TYPE_TIMESTAMP;\nenum SQL_C_UBIGINT = SQL_BIGINT+SQL_UNSIGNED_OFFSET;\nenum SQL_C_VARBOOKMARK = SQL_C_BINARY;\nenum SQL_CA_CONSTRAINT_DEFERRABLE = 0x00000040L;\nenum SQL_CA_CONSTRAINT_INITIALLY_DEFERRED = 0x00000010L;\nenum SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE = 0x00000020L;\nenum SQL_CA_CONSTRAINT_NON_DEFERRABLE = 0x00000080L;\nenum SQL_CA_CREATE_ASSERTION = 0x00000001L;\nenum SQL_CA1_ABSOLUTE = 0x00000002L;\nenum SQL_CA1_BOOKMARK = 0x00000008L;\nenum SQL_CA1_BULK_ADD = 0x00010000L;\nenum SQL_CA1_BULK_DELETE_BY_BOOKMARK = 0x00040000L;\nenum SQL_CA1_BULK_FETCH_BY_BOOKMARK = 0x00080000L;\nenum SQL_CA1_BULK_UPDATE_BY_BOOKMARK = 0x00020000L;\nenum SQL_CA1_LOCK_EXCLUSIVE = 0x00000080L;\nenum SQL_CA1_LOCK_NO_CHANGE = 0x00000040L;\nenum SQL_CA1_LOCK_UNLOCK = 0x00000100L;\nenum SQL_CA1_NEXT = 0x00000001L;\nenum SQL_CA1_POS_DELETE = 0x00000800L;\nenum SQL_CA1_POS_POSITION = 0x00000200L;\nenum SQL_CA1_POS_REFRESH = 0x00001000L;\nenum SQL_CA1_POS_UPDATE = 0x00000400L;\nenum SQL_CA1_POSITIONED_DELETE = 0x00004000L;\nenum SQL_CA1_POSITIONED_UPDATE = 0x00002000L;\nenum SQL_CA1_RELATIVE = 0x00000004L;\nenum SQL_CA1_SELECT_FOR_UPDATE = 0x00008000L;\nenum SQL_CA2_CRC_APPROXIMATE = 0x00002000L;\nenum SQL_CA2_CRC_EXACT = 0x00001000L;\nenum SQL_CA2_LOCK_CONCURRENCY = 0x00000002L;\n\nenum SQL_CA2_MAX_ROWS_CATALOG = 0x00000800L;\nenum SQL_CA2_MAX_ROWS_DELETE  = 0x00000200L;\nenum SQL_CA2_MAX_ROWS_INSERT  = 0x00000100L;\nenum SQL_CA2_MAX_ROWS_SELECT  = 0x00000080L;\nenum SQL_CA2_MAX_ROWS_UPDATE  = 0x00000400L;\nenum SQL_CA2_MAX_ROWS_AFFECTS_ALL = SQL_CA2_MAX_ROWS_SELECT | SQL_CA2_MAX_ROWS_INSERT |\n        SQL_CA2_MAX_ROWS_DELETE | SQL_CA2_MAX_ROWS_UPDATE | SQL_CA2_MAX_ROWS_CATALOG;\n\nenum SQL_CA2_OPT_ROWVER_CONCURRENCY = 0x00000004L;\nenum SQL_CA2_OPT_VALUES_CONCURRENCY = 0x00000008L;\nenum SQL_CA2_READ_ONLY_CONCURRENCY = 0x00000001L;\nenum SQL_CA2_SENSITIVITY_ADDITIONS = 0x00000010L;\nenum SQL_CA2_SENSITIVITY_DELETIONS = 0x00000020L;\nenum SQL_CA2_SENSITIVITY_UPDATES = 0x00000040L;\nenum SQL_CA2_SIMULATE_NON_UNIQUE = 0x00004000L;\nenum SQL_CA2_SIMULATE_TRY_UNIQUE = 0x00008000L;\nenum SQL_CA2_SIMULATE_UNIQUE = 0x00010000L;\nenum SQL_CATALOG_LOCATION = SQL_QUALIFIER_LOCATION;\nenum SQL_CATALOG_NAME_SEPARATOR = SQL_QUALIFIER_NAME_SEPARATOR;\nenum SQL_CATALOG_TERM = SQL_QUALIFIER_TERM;\nenum SQL_CATALOG_USAGE = SQL_QUALIFIER_USAGE;\nenum SQL_CCOL_CREATE_COLLATION = 0x00000001L;\nenum SQL_CCS_COLLATE_CLAUSE = 0x00000002L;\nenum SQL_CCS_CREATE_CHARACTER_SET = 0x00000001L;\nenum SQL_CCS_LIMITED_COLLATION = 0x00000004L;\nenum SQL_CDO_COLLATION = 0x00000008L;\nenum SQL_CDO_CONSTRAINT = 0x00000004L;\nenum SQL_CDO_CONSTRAINT_DEFERRABLE = 0x00000080L;\nenum SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED = 0x00000020L;\nenum SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE = 0x00000040L;\nenum SQL_CDO_CONSTRAINT_NAME_DEFINITION = 0x00000010L;\nenum SQL_CDO_CONSTRAINT_NON_DEFERRABLE = 0x00000100L;\nenum SQL_CDO_CREATE_DOMAIN = 0x00000001L;\nenum SQL_CDO_DEFAULT = 0x00000002L;\nenum SQL_CL_END = SQL_QL_END;\nenum SQL_CL_START = SQL_QL_START;\nenum SQL_COL_PRED_BASIC = SQL_ALL_EXCEPT_LIKE;\nenum SQL_COL_PRED_CHAR = SQL_LIKE_ONLY;\nenum SQL_COLUMN_DRIVER_START = 1000;\nenum SQL_COLUMN_IGNORE = SQL_IGNORE;\nenum SQL_COLUMN_NUMBER_UNKNOWN = -2;\nenum SQL_CONVERT_GUID = 173;\n\nenum SQL_CONVERT_WCHAR               = 122;\nenum SQL_CONVERT_INTERVAL_DAY_TIME   = 123;\nenum SQL_CONVERT_INTERVAL_YEAR_MONTH = 124;\nenum SQL_CONVERT_WLONGVARCHAR        = 125;\nenum SQL_CONVERT_WVARCHAR            = 126;\n\nenum SQL_CREATE_ASSERTION     = 127;\nenum SQL_CREATE_CHARACTER_SET = 128;\nenum SQL_CREATE_COLLATION     = 129;\nenum SQL_CREATE_DOMAIN        = 130;\nenum SQL_CREATE_SCHEMA        = 131;\nenum SQL_CREATE_TABLE         = 132;\nenum SQL_CREATE_TRANSLATION   = 133;\nenum SQL_CREATE_VIEW          = 134;\n\n\nenum SQL_CP_OFF            = 0UL;\nenum SQL_CP_DEFAULT        = SQL_CP_OFF;\nenum SQL_CP_ONE_PER_DRIVER = 1UL;\nenum SQL_CP_ONE_PER_HENV   = 2UL;\n\nenum SQL_CP_STRICT_MATCH  = 0UL;\nenum SQL_CP_MATCH_DEFAULT = SQL_CP_STRICT_MATCH;\nenum SQL_CP_RELAXED_MATCH = 1UL;\n\nenum SQL_CS_CREATE_SCHEMA         = 0x00000001L;\nenum SQL_CS_AUTHORIZATION         = 0x00000002L;\nenum SQL_CS_DEFAULT_CHARACTER_SET = 0x00000004L;\n\nenum SQL_CT_COLUMN_COLLATION = 0x00000800L;\nenum SQL_CT_COLUMN_CONSTRAINT = 0x00000200L;\nenum SQL_CT_COLUMN_DEFAULT = 0x00000400L;\nenum SQL_CT_COMMIT_DELETE = 0x00000004L;\nenum SQL_CT_COMMIT_PRESERVE = 0x00000002L;\nenum SQL_CT_CONSTRAINT_DEFERRABLE = 0x00000080L;\nenum SQL_CT_CONSTRAINT_INITIALLY_DEFERRED = 0x00000020L;\nenum SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE = 0x00000040L;\nenum SQL_CT_CONSTRAINT_NAME_DEFINITION = 0x00002000L;\nenum SQL_CT_CONSTRAINT_NON_DEFERRABLE = 0x00000100L;\nenum SQL_CT_CREATE_TABLE = 0x00000001L;\nenum SQL_CT_GLOBAL_TEMPORARY = 0x00000008L;\nenum SQL_CT_LOCAL_TEMPORARY = 0x00000010L;\nenum SQL_CT_TABLE_CONSTRAINT = 0x00001000L;\n\nenum SQL_CTR_CREATE_TRANSLATION = 0x00000001L;\n\nenum SQL_CU_DML_STATEMENTS = SQL_QU_DML_STATEMENTS;\nenum SQL_CU_INDEX_DEFINITION = SQL_QU_INDEX_DEFINITION;\nenum SQL_CU_PRIVILEGE_DEFINITION = SQL_QU_PRIVILEGE_DEFINITION;\nenum SQL_CU_PROCEDURE_INVOCATION = SQL_QU_PROCEDURE_INVOCATION;\nenum SQL_CU_TABLE_DEFINITION = SQL_QU_TABLE_DEFINITION;\n\nenum SQL_CVT_INTERVAL_YEAR_MONTH = 0x00080000L;\nenum SQL_CVT_INTERVAL_DAY_TIME   = 0x00100000L;\nenum SQL_CVT_WCHAR               = 0x00200000L;\nenum SQL_CVT_WLONGVARCHAR        = 0x00400000L;\nenum SQL_CVT_WVARCHAR            = 0x00800000L;\nenum SQL_CVT_GUID                = 0x01000000L;\n\nenum SQL_DA_DROP_ASSERTION = 0x00000001L;\nenum SQL_DATETIME_LITERALS = 119;\n\nenum SQL_DB_DISCONNECT     = 1UL;\nenum SQL_DB_RETURN_TO_POOL = 0UL;\nenum SQL_DB_DEFAULT        = SQL_DB_RETURN_TO_POOL;\n\nenum SQL_DC_DROP_COLLATION = 0x00000001L;\nenum SQL_DCS_DROP_CHARACTER_SET = 0x00000001L;\nenum SQL_DD_CASCADE = 0x00000004L;\nenum SQL_DD_DROP_DOMAIN = 0x00000001L;\nenum SQL_DD_RESTRICT = 0x00000002L;\nenum SQL_DDL_INDEX = 170;\nenum SQL_DELETE_BY_BOOKMARK = 6;\nenum SQL_DESC_ARRAY_SIZE = 20;\nenum SQL_DESC_ARRAY_STATUS_PTR = 21;\nenum SQL_DESC_AUTO_UNIQUE_VALUE = SQL_COLUMN_AUTO_INCREMENT;\nenum SQL_DESC_BASE_COLUMN_NAME = 22;\nenum SQL_DESC_BASE_TABLE_NAME = 23;\nenum SQL_DESC_BIND_OFFSET_PTR = 24;\nenum SQL_DESC_BIND_TYPE = 25;\nenum SQL_DESC_CASE_SENSITIVE = SQL_COLUMN_CASE_SENSITIVE;\nenum SQL_DESC_CATALOG_NAME = SQL_COLUMN_QUALIFIER_NAME;\nenum SQL_DESC_CONCISE_TYPE = SQL_COLUMN_TYPE;\nenum SQL_DESC_DATETIME_INTERVAL_PRECISION = 26;\nenum SQL_DESC_DISPLAY_SIZE = SQL_COLUMN_DISPLAY_SIZE;\nenum SQL_DESC_FIXED_PREC_SCALE = SQL_COLUMN_MONEY;\nenum SQL_DESC_LABEL = SQL_COLUMN_LABEL;\nenum SQL_DESC_LITERAL_PREFIX = 27;\nenum SQL_DESC_LITERAL_SUFFIX = 28;\nenum SQL_DESC_LOCAL_TYPE_NAME = 29;\nenum SQL_DESC_MAXIMUM_SCALE = 30;\nenum SQL_DESC_MINIMUM_SCALE = 31;\nenum SQL_DESC_NUM_PREC_RADIX = 32;\nenum SQL_DESC_PARAMETER_TYPE = 33;\nenum SQL_DESC_ROWS_PROCESSED_PTR = 34;\nenum SQL_DESC_SCHEMA_NAME = SQL_COLUMN_OWNER_NAME;\nenum SQL_DESC_SEARCHABLE = SQL_COLUMN_SEARCHABLE;\nenum SQL_DESC_TABLE_NAME = SQL_COLUMN_TABLE_NAME;\nenum SQL_DESC_TYPE_NAME = SQL_COLUMN_TYPE_NAME;\nenum SQL_DESC_UNSIGNED = SQL_COLUMN_UNSIGNED;\nenum SQL_DESC_UPDATABLE = SQL_COLUMN_UPDATABLE;\nenum SQL_DI_CREATE_INDEX = 0x00000001L;\nenum SQL_DI_DROP_INDEX = 0x00000002L;\n\nenum SQL_DIAG_COLUMN_NUMBER = -1247;\nenum SQL_DIAG_ROW_NUMBER = -1248;\nenum SQL_DIAG_CURSOR_ROW_COUNT = -1249;\n\nenum SQL_DL_SQL92_DATE = 0x00000001L;\nenum SQL_DL_SQL92_INTERVAL_DAY = 0x00000020L;\nenum SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR = 0x00000400L;\nenum SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE = 0x00000800L;\nenum SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND = 0x00001000L;\nenum SQL_DL_SQL92_INTERVAL_HOUR = 0x00000040L;\nenum SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE = 0x00002000L;\nenum SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND = 0x00004000L;\nenum SQL_DL_SQL92_INTERVAL_MINUTE = 0x00000080L;\nenum SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND = 0x00008000L;\nenum SQL_DL_SQL92_INTERVAL_MONTH = 0x00000010L;\nenum SQL_DL_SQL92_INTERVAL_SECOND = 0x00000100L;\nenum SQL_DL_SQL92_INTERVAL_YEAR = 0x00000008L;\nenum SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH = 0x00000200L;\nenum SQL_DL_SQL92_TIME = 0x00000002L;\nenum SQL_DL_SQL92_TIMESTAMP = 0x00000004L;\nenum SQL_DM_VER = 171;\nenum SQL_DRIVER_HDESC = 135;\nenum SQL_DROP_ASSERTION = 136;\nenum SQL_DROP_CHARACTER_SET = 137;\nenum SQL_DROP_COLLATION = 138;\nenum SQL_DROP_DOMAIN = 139;\nenum SQL_DROP_SCHEMA = 140;\nenum SQL_DROP_TABLE = 141;\nenum SQL_DROP_TRANSLATION = 142;\nenum SQL_DROP_VIEW = 143;\nenum SQL_DS_CASCADE = 0x00000004L;\nenum SQL_DS_DROP_SCHEMA = 0x00000001L;\nenum SQL_DS_RESTRICT = 0x00000002L;\nenum SQL_DT_CASCADE = 0x00000004L;\nenum SQL_DT_DROP_TABLE = 0x00000001L;\nenum SQL_DT_RESTRICT = 0x00000002L;\nenum SQL_DTC_DONE = 0L;\nenum SQL_DTR_DROP_TRANSLATION = 0x00000001L;\nenum SQL_DV_CASCADE = 0x00000004L;\nenum SQL_DV_DROP_VIEW = 0x00000001L;\nenum SQL_DV_RESTRICT = 0x00000002L;\nenum SQL_DYNAMIC_CURSOR_ATTRIBUTES1 = 144;\nenum SQL_DYNAMIC_CURSOR_ATTRIBUTES2 = 145;\nenum SQL_EXT_API_LAST = SQL_API_SQLBINDPARAMETER;\nenum SQL_EXT_API_START = 40;\nenum SQL_FETCH_BY_BOOKMARK = 7;\nenum SQL_FETCH_FIRST_SYSTEM = 32;\nenum SQL_FETCH_FIRST_USER = 31;\nenum SQL_FN_CVT_CAST = 0x00000002L;\nenum SQL_FN_STR_BIT_LENGTH = 0x00080000L;\nenum SQL_FN_STR_CHAR_LENGTH = 0x00100000L;\nenum SQL_FN_STR_CHARACTER_LENGTH = 0x00200000L;\nenum SQL_FN_STR_OCTET_LENGTH = 0x00400000L;\nenum SQL_FN_STR_POSITION = 0x00800000L;\nenum SQL_FN_TD_CURRENT_DATE = 0x00020000L;\nenum SQL_FN_TD_CURRENT_TIME = 0x00040000L;\nenum SQL_FN_TD_CURRENT_TIMESTAMP = 0x00080000L;\nenum SQL_FN_TD_EXTRACT = 0x00100000L;\nenum SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 = 146;\nenum SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 = 147;\n    /* #define SQL_FUNC_EXISTS(exists, api)\n       ((*(((UWORD*) (exists)) + ((api) >> 4)) & (1 << ((api) & 15)) ) ?\n       SQL_TRUE : SQL_FALSE )\n    */\nenum SQL_GB_COLLATE = 0x0004;\nenum SQL_HANDLE_SENV = 5;\n\nenum SQL_IK_NONE = 0;\nenum SQL_IK_ASC = 1;\nenum SQL_IK_DESC = 2;\nenum SQL_IK_ALL = SQL_IK_ASC | SQL_IK_DESC;\n\nenum SQL_INDEX_KEYWORDS = 148;\nenum SQL_INFO_DRIVER_START = 1000;\nenum SQL_INFO_LAST = SQL_QUALIFIER_LOCATION;\nenum SQL_INFO_SCHEMA_VIEWS = 149;\nenum SQL_INITIALLY_DEFERRED = 5;\nenum SQL_INITIALLY_IMMEDIATE = 6;\nenum SQL_INSERT_STATEMENT = 172;\nenum SQL_INTERVAL = 10;\nenum SQL_IS_INSERT_LITERALS = 0x00000001L;\nenum SQL_IS_INSERT_SEARCHED = 0x00000002L;\nenum SQL_IS_INTEGER = -6;\nenum SQL_IS_POINTER = -4;\nenum SQL_IS_SELECT_INTO = 0x00000004L;\nenum SQL_IS_SMALLINT = -8;\nenum SQL_IS_UINTEGER = -5;\nenum SQL_IS_USMALLINT = -7;\nenum SQL_ISV_ASSERTIONS = 0x00000001L;\nenum SQL_ISV_CHARACTER_SETS = 0x00000002L;\nenum SQL_ISV_CHECK_CONSTRAINTS = 0x00000004L;\nenum SQL_ISV_COLLATIONS = 0x00000008L;\nenum SQL_ISV_COLUMN_DOMAIN_USAGE = 0x00000010L;\nenum SQL_ISV_COLUMN_PRIVILEGES = 0x00000020L;\nenum SQL_ISV_COLUMNS = 0x00000040L;\nenum SQL_ISV_CONSTRAINT_COLUMN_USAGE = 0x00000080L;\nenum SQL_ISV_CONSTRAINT_TABLE_USAGE = 0x00000100L;\nenum SQL_ISV_DOMAIN_CONSTRAINTS = 0x00000200L;\nenum SQL_ISV_DOMAINS = 0x00000400L;\nenum SQL_ISV_KEY_COLUMN_USAGE = 0x00000800L;\nenum SQL_ISV_REFERENTIAL_CONSTRAINTS = 0x00001000L;\nenum SQL_ISV_SCHEMATA = 0x00002000L;\nenum SQL_ISV_SQL_LANGUAGES = 0x00004000L;\nenum SQL_ISV_TABLE_CONSTRAINTS = 0x00008000L;\nenum SQL_ISV_TABLE_PRIVILEGES = 0x00010000L;\nenum SQL_ISV_TABLES = 0x00020000L;\nenum SQL_ISV_TRANSLATIONS = 0x00040000L;\nenum SQL_ISV_USAGE_PRIVILEGES = 0x00080000L;\nenum SQL_ISV_VIEW_COLUMN_USAGE = 0x00100000L;\nenum SQL_ISV_VIEW_TABLE_USAGE = 0x00200000L;\nenum SQL_ISV_VIEWS = 0x00400000L;\nenum SQL_KEYSET_CURSOR_ATTRIBUTES1 = 150;\nenum SQL_KEYSET_CURSOR_ATTRIBUTES2 = 151;\nenum SQL_MAX_ASYNC_CONCURRENT_STATEMENTS = 10022;\nenum SQL_NO_COLUMN_NUMBER = -1;\nenum SQL_NO_ROW_NUMBER = -1;\nenum SQL_NOT_DEFERRABLE = 7;\nenum SQL_NUM_EXTENSIONS = SQL_EXT_API_LAST-SQL_EXT_API_START+1;\nenum SQL_NUM_FUNCTIONS = 23;\nenum SQL_ODBC_INTERFACE_CONFORMANCE = 152;\n\n    enum : ULONG {\n        SQL_OIC_CORE = 1,\n        SQL_OIC_LEVEL1,\n        SQL_OIC_LEVEL2\n    }\n    enum : ULONG {\n        SQL_OV_ODBC2 = 2,\n        SQL_OV_ODBC3 = 3\n    }\n\nenum ULONG\n        SQL_PARAM_BIND_BY_COLUMN = 0,\n        SQL_PARAM_BIND_TYPE_DEFAULT = SQL_PARAM_BIND_BY_COLUMN;\n\nenum SQL_PARAM_ARRAY_ROW_COUNTS = 153;\nenum SQL_PARAM_ARRAY_SELECTS = 154;\nenum SQL_PARAM_DIAG_UNAVAILABLE = 1;\nenum SQL_PARAM_ERROR = 5;\nenum SQL_PARAM_IGNORE = 1;\nenum SQL_PARAM_PROCEED = 0;\nenum SQL_PARAM_SUCCESS = 0;\nenum SQL_PARAM_SUCCESS_WITH_INFO = 6;\nenum SQL_PARAM_UNUSED = 7;\n\nenum SQL_PARC_BATCH = 1;\nenum SQL_PARC_NO_BATCH = 2;\nenum SQL_PAS_BATCH = 1;\nenum SQL_PAS_NO_BATCH = 2;\nenum SQL_PAS_NO_SELECT = 3;\n\nenum SQL_ROW_IGNORE = 1;\nenum SQL_ROW_NUMBER_UNKNOWN = -2;\nenum SQL_ROW_PROCEED = 0;\nenum SQL_ROW_SUCCESS_WITH_INFO = 6;\n\nenum SQL_SC_FIPS127_2_TRANSITIONAL = 0x00000002L;\nenum SQL_SC_SQL92_ENTRY = 0x00000001L;\nenum SQL_SC_SQL92_FULL = 0x00000008L;\nenum SQL_SC_SQL92_INTERMEDIATE = 0x00000004L;\n\nenum SQL_SCC_ISO92_CLI = 0x00000002L;\nenum SQL_SCC_XOPEN_CLI_VERSION1 = 0x00000001L;\n\nenum SQL_SCHEMA_TERM = SQL_OWNER_TERM;\nenum SQL_SCHEMA_USAGE = SQL_OWNER_USAGE;\nenum SQL_SDF_CURRENT_DATE = 0x00000001L;\nenum SQL_SDF_CURRENT_TIME = 0x00000002L;\nenum SQL_SDF_CURRENT_TIMESTAMP = 0x00000004L;\nenum SQL_SFKD_CASCADE = 0x00000001L;\nenum SQL_SFKD_NO_ACTION = 0x00000002L;\nenum SQL_SFKD_SET_DEFAULT = 0x00000004L;\nenum SQL_SFKD_SET_NULL = 0x00000008L;\nenum SQL_SFKU_CASCADE = 0x00000001L;\nenum SQL_SFKU_NO_ACTION = 0x00000002L;\nenum SQL_SFKU_SET_DEFAULT = 0x00000004L;\nenum SQL_SFKU_SET_NULL = 0x00000008L;\nenum SQL_SG_DELETE_TABLE = 0x00000020L;\nenum SQL_SG_INSERT_COLUMN = 0x00000080L;\nenum SQL_SG_INSERT_TABLE = 0x00000040L;\nenum SQL_SG_REFERENCES_COLUMN = 0x00000200L;\nenum SQL_SG_REFERENCES_TABLE = 0x00000100L;\nenum SQL_SG_SELECT_TABLE = 0x00000400L;\nenum SQL_SG_UPDATE_COLUMN = 0x00001000L;\nenum SQL_SG_UPDATE_TABLE = 0x00000800L;\nenum SQL_SG_USAGE_ON_CHARACTER_SET = 0x00000002L;\nenum SQL_SG_USAGE_ON_COLLATION = 0x00000004L;\nenum SQL_SG_USAGE_ON_DOMAIN = 0x00000001L;\nenum SQL_SG_USAGE_ON_TRANSLATION = 0x00000008L;\nenum SQL_SG_WITH_GRANT_OPTION = 0x00000010L;\nenum SQL_SNVF_BIT_LENGTH = 0x00000001L;\nenum SQL_SNVF_CHAR_LENGTH = 0x00000002L;\nenum SQL_SNVF_CHARACTER_LENGTH = 0x00000004L;\nenum SQL_SNVF_EXTRACT = 0x00000008L;\nenum SQL_SNVF_OCTET_LENGTH = 0x00000010L;\nenum SQL_SNVF_POSITION = 0x00000020L;\nenum SQL_SP_BETWEEN = 0x00000800L;\nenum SQL_SP_COMPARISON = 0x00001000L;\nenum SQL_SP_EXISTS = 0x00000001L;\nenum SQL_SP_IN = 0x00000400L;\nenum SQL_SP_ISNOTNULL = 0x00000002L;\nenum SQL_SP_ISNULL = 0x00000004L;\nenum SQL_SP_LIKE = 0x00000200L;\nenum SQL_SP_MATCH_FULL = 0x00000008L;\nenum SQL_SP_MATCH_PARTIAL = 0x00000010L;\nenum SQL_SP_MATCH_UNIQUE_FULL = 0x00000020L;\nenum SQL_SP_MATCH_UNIQUE_PARTIAL = 0x00000040L;\nenum SQL_SP_OVERLAPS = 0x00000080L;\nenum SQL_SP_QUANTIFIED_COMPARISON = 0x00002000L;\nenum SQL_SP_UNIQUE = 0x00000100L;\nenum SQL_SQL_CONFORMANCE = 118;\nenum SQL_SQL92_DATETIME_FUNCTIONS = 155;\nenum SQL_SQL92_FOREIGN_KEY_DELETE_RULE = 156;\nenum SQL_SQL92_FOREIGN_KEY_UPDATE_RULE = 157;\nenum SQL_SQL92_GRANT = 158;\nenum SQL_SQL92_NUMERIC_VALUE_FUNCTIONS = 159;\nenum SQL_SQL92_PREDICATES = 160;\nenum SQL_SQL92_RELATIONAL_JOIN_OPERATORS = 161;\nenum SQL_SQL92_REVOKE = 162;\nenum SQL_SQL92_ROW_VALUE_CONSTRUCTOR = 163;\nenum SQL_SQL92_STRING_FUNCTIONS = 164;\nenum SQL_SQL92_VALUE_EXPRESSIONS = 165;\nenum SQL_SR_CASCADE = 0x00000020L;\nenum SQL_SR_DELETE_TABLE = 0x00000080L;\nenum SQL_SR_GRANT_OPTION_FOR = 0x00000010L;\nenum SQL_SR_INSERT_COLUMN = 0x00000200L;\nenum SQL_SR_INSERT_TABLE = 0x00000100L;\nenum SQL_SR_REFERENCES_COLUMN = 0x00000800L;\nenum SQL_SR_REFERENCES_TABLE = 0x00000400L;\nenum SQL_SR_RESTRICT = 0x00000040L;\nenum SQL_SR_SELECT_TABLE = 0x00001000L;\nenum SQL_SR_UPDATE_COLUMN = 0x00004000L;\nenum SQL_SR_UPDATE_TABLE = 0x00002000L;\nenum SQL_SR_USAGE_ON_CHARACTER_SET = 0x00000002L;\nenum SQL_SR_USAGE_ON_COLLATION = 0x00000004L;\nenum SQL_SR_USAGE_ON_DOMAIN = 0x00000001L;\nenum SQL_SR_USAGE_ON_TRANSLATION = 0x00000008L;\nenum SQL_SRJO_CORRESPONDING_CLAUSE = 0x00000001L;\nenum SQL_SRJO_CROSS_JOIN = 0x00000002L;\nenum SQL_SRJO_EXCEPT_JOIN = 0x00000004L;\nenum SQL_SRJO_FULL_OUTER_JOIN = 0x00000008L;\nenum SQL_SRJO_INNER_JOIN = 0x00000010L;\nenum SQL_SRJO_INTERSECT_JOIN = 0x00000020L;\nenum SQL_SRJO_LEFT_OUTER_JOIN = 0x00000040L;\nenum SQL_SRJO_NATURAL_JOIN = 0x00000080L;\nenum SQL_SRJO_RIGHT_OUTER_JOIN = 0x00000100L;\nenum SQL_SRJO_UNION_JOIN = 0x00000200L;\nenum SQL_SRVC_DEFAULT = 0x00000004L;\nenum SQL_SRVC_NULL = 0x00000002L;\nenum SQL_SRVC_ROW_SUBQUERY = 0x00000008L;\nenum SQL_SRVC_VALUE_EXPRESSION = 0x00000001L;\nenum SQL_SSF_CONVERT = 0x00000001L;\nenum SQL_SSF_LOWER = 0x00000002L;\nenum SQL_SSF_SUBSTRING = 0x00000008L;\nenum SQL_SSF_TRANSLATE = 0x00000010L;\nenum SQL_SSF_TRIM_BOTH = 0x00000020L;\nenum SQL_SSF_TRIM_LEADING = 0x00000040L;\nenum SQL_SSF_TRIM_TRAILING = 0x00000080L;\nenum SQL_SSF_UPPER = 0x00000004L;\nenum SQL_STANDARD_CLI_CONFORMANCE = 166;\nenum SQL_STATIC_CURSOR_ATTRIBUTES1 = 167;\nenum SQL_STATIC_CURSOR_ATTRIBUTES2 = 168;\nenum SQL_SU_DML_STATEMENTS = SQL_OU_DML_STATEMENTS;\nenum SQL_SU_INDEX_DEFINITION = SQL_OU_INDEX_DEFINITION;\nenum SQL_SU_PRIVILEGE_DEFINITION = SQL_OU_PRIVILEGE_DEFINITION;\nenum SQL_SU_PROCEDURE_INVOCATION = SQL_OU_PROCEDURE_INVOCATION;\nenum SQL_SU_TABLE_DEFINITION = SQL_OU_TABLE_DEFINITION;\nenum SQL_SVE_CASE = 0x00000001L;\nenum SQL_SVE_CAST = 0x00000002L;\nenum SQL_SVE_COALESCE = 0x00000004L;\nenum SQL_SVE_NULLIF = 0x00000008L;\nenum SQL_UB_FIXED = SQL_UB_ON;\nenum SQL_UB_VARIABLE = 2UL;\nenum SQL_UNION_STATEMENT = SQL_UNION;\nenum SQL_UPDATE_BY_BOOKMARK = 5;\nenum SQL_US_UNION = SQL_U_UNION;\nenum SQL_US_UNION_ALL = SQL_U_UNION_ALL;\n}//[Yes] #endif /* ODBCVER >= 0x300 */\nstatic if (ODBCVER >= 0x0350) {\nenum SQL_DESC_ROWVER = 35;\nenum SQL_GUID = -11;\nenum SQL_C_GUID = SQL_GUID;\n    //#ifdef ODBC_STD\n    //#define SQLAllocHandle SQLAllocHandleStd\n    //#define SQLAllocEnv(p) SQLAllocHandleStd(SQL_HANDLE_ENV, SQL_NULL_HANDLE, p)\n    //#define SQL_YEAR SQL_CODE_YEAR\n    //#define SQL_MONTH SQL_CODE_MONTH\n    //#define SQL_DAY SQL_CODE_DAY\n    //#define SQL_HOUR SQL_CODE_HOUR\n    //#define SQL_MINUTE SQL_CODE_MINUTE\n    //#define SQL_SECOND SQL_CODE_SECOND\n    //#define SQL_YEAR_TO_MONTH SQL_CODE_YEAR_TO_MONTH\n    //#define SQL_DAY_TO_HOUR SQL_CODE_DAY_TO_HOUR\n    //#define SQL_DAY_TO_MINUTE SQL_CODE_DAY_TO_MINUTE\n    //#define SQL_DAY_TO_SECOND SQL_CODE_DAY_TO_SECOND\n    //#define SQL_HOUR_TO_MINUTE SQL_CODE_HOUR_TO_MINUTE\n    //#define SQL_HOUR_TO_SECOND SQL_CODE_HOUR_TO_SECOND\n    //#define SQL_MINUTE_TO_SECOND SQL_CODE_MINUTE_TO_SECOND\n    //#endif /* ODBC_STD */\n}//#endif /* ODBCVER >= 0x0350 */\n\n//static if (ODBCVER >= 0x0351) {\nenum SQL_ATTR_ANSI_APP=115;\nenum SQL_AA_TRUE=1L;\nenum SQL_AA_FALSE=0L;\n//}//[Yes] #endif\n\nenum TRACE_VERSION=1000;\nenum TRACE_ON=1;\n\nconst char [] SQL_ODBC_KEYWORDS =\n    \"ABSOLUTE, ACTION, ADA, ADD, ALL, ALLOCATE, ALTER, AND, ANY, ARE, AS, \"\n    ~ \"ASC, ASSERTION, AT, AUTHORIZATION, AVG, \"\n    ~ \"BEGIN, BETWEEN, BIT, BIT_LENGTH, BOTH, BY, CASCADE, CASCADED, CASE, CAST, CATALOG, \"\n    ~ \"CHAR, CHAR_LENGTH, CHARACTER, CHARACTER_LENGTH, CHECK, CLOSE, COALESCE, \"\n    ~ \"COLLATE, COLLATION, COLUMN, COMMIT, CONNECT, CONNECTION, CONSTRAINT, \"\n    ~ \"CONSTRAINTS, CONTINUE, CONVERT, CORRESPONDING, COUNT, CREATE, CROSS, CURRENT, \"\n    ~ \"CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR, \"\n    ~ \"DATE, DAY, DEALLOCATE, DEC, DECIMAL, DECLARE, DEFAULT, DEFERRABLE, \"\n    ~ \"DEFERRED, DELETE, DESC, DESCRIBE, DESCRIPTOR, DIAGNOSTICS, DISCONNECT, \"\n    ~ \"DISTINCT, DOMAIN, DOUBLE, DROP, \"\n    ~ \"ELSE, END, END-EXEC, ESCAPE, EXCEPT, EXCEPTION, EXEC, EXECUTE, \"\n    ~ \"EXISTS, EXTERNAL, EXTRACT, \"\n    ~ \"FALSE, FETCH, FIRST, FLOAT, FOR, FOREIGN, FORTRAN, FOUND, FROM, FULL, \"\n    ~ \"GET, GLOBAL, GO, GOTO, GRANT, GROUP, HAVING, HOUR, \"\n    ~ \"IDENTITY, IMMEDIATE, IN, INCLUDE, INDEX, INDICATOR, INITIALLY, INNER, \"\n    ~ \"INPUT, INSENSITIVE, INSERT, INT, INTEGER, INTERSECT, INTERVAL, INTO, IS, ISOLATION, \"\n    ~ \"JOIN, KEY, LANGUAGE, LAST, LEADING, LEFT, LEVEL, LIKE, LOCAL, LOWER, \"\n    ~ \"MATCH, MAX, MIN, MINUTE, MODULE, MONTH, \"\n    ~ \"NAMES, NATIONAL, NATURAL, NCHAR, NEXT, NO, NONE, NOT, NULL, NULLIF, NUMERIC, \"\n    ~ \"OCTET_LENGTH, OF, ON, ONLY, OPEN, OPTION, OR, ORDER, OUTER, OUTPUT, OVERLAPS, \"\n    ~ \"PAD, PARTIAL, PASCAL, PLI, POSITION, PRECISION, PREPARE, PRESERVE, \"\n    ~ \"PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC, \"\n    ~ \"READ, REAL, REFERENCES, RELATIVE, RESTRICT, REVOKE, RIGHT, ROLLBACK, ROWS\"\n    ~ \"SCHEMA, SCROLL, SECOND, SECTION, SELECT, SESSION, SESSION_USER, SET, SIZE, \"\n    ~ \"SMALLINT, SOME, SPACE, SQL, SQLCA, SQLCODE, SQLERROR, SQLSTATE, SQLWARNING, \"\n    ~ \"SUBSTRING, SUM, SYSTEM_USER, \"\n    ~ \"TABLE, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE, \"\n    ~ \"TO, TRAILING, TRANSACTION, TRANSLATE, TRANSLATION, TRIM, TRUE, \"\n    ~ \"UNION, UNIQUE, UNKNOWN, UPDATE, UPPER, USAGE, USER, USING, \"\n    ~ \"VALUE, VALUES, VARCHAR, VARYING, VIEW, WHEN, WHENEVER, WHERE, WITH, WORK, WRITE, \"\n    ~ \"YEAR, ZONE\";\nextern (Windows) {\n    SQLRETURN SQLDriverConnect(SQLHDBC, SQLHWND, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLUSMALLINT);\n    SQLRETURN SQLBrowseConnect(SQLHDBC, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLColumnPrivileges(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLColAttributes(SQLHSTMT, SQLUSMALLINT, SQLUSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*, SQLLEN*);\n    SQLRETURN SQLDescribeParam(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT*, SQLULEN*, SQLSMALLINT*, SQLSMALLINT*);\n    SQLRETURN SQLExtendedFetch(SQLHSTMT, SQLUSMALLINT, SQLINTEGER, SQLUINTEGER*, SQLUSMALLINT*);\n    SQLRETURN SQLForeignKeys(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLMoreResults(SQLHSTMT);\n    SQLRETURN SQLNativeSql(SQLHDBC, SQLCHAR*, SQLINTEGER, SQLCHAR*, SQLINTEGER, SQLINTEGER*);\n    SQLRETURN SQLNumParams(SQLHSTMT, SQLSMALLINT*);\n    SQLRETURN SQLParamOptions(SQLHSTMT, SQLUINTEGER, SQLUINTEGER*);\n    SQLRETURN SQLPrimaryKeys(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLProcedureColumns(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLProcedures(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLSetPos(SQLHSTMT, SQLUSMALLINT, SQLUSMALLINT, SQLUSMALLINT);\n    SQLRETURN SQLTablePrivileges(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLDrivers(SQLHENV, SQLUSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLBindParameter(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, SQLSMALLINT, SQLSMALLINT, SQLULEN, SQLSMALLINT, SQLPOINTER, SQLLEN, SQLLEN*);\n    SQLRETURN SQLSetScrollOptions(SQLHSTMT, SQLUSMALLINT, SQLLEN, SQLUSMALLINT);/* deprecated */\n    DWORD ODBCGetTryWaitValue();\n    BOOL ODBCSetTryWaitValue(DWORD);\n    RETCODE TraceOpenLogFile(LPWSTR, LPWSTR, DWORD);\n    RETCODE TraceCloseLogFile();\n    VOID TraceReturn(RETCODE, RETCODE);\n    DWORD TraceVersion();\n    //static if (ODBCVER >= 0x0300) {\n    SQLRETURN SQLBulkOperations(SQLHSTMT, SQLSMALLINT);\n    SQLRETURN SQLAllocHandleStd( SQLSMALLINT, SQLHANDLE, SQLHANDLE*);\n    //}\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/sqltypes.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_sqltypes.d)\n */\nmodule core.sys.windows.sqltypes;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\n/* Conversion notes:\n  It's assumed that ODBC >= 0x0300.\n*/\n\nprivate import core.sys.windows.windef;\nprivate import core.sys.windows.basetyps; // for GUID\n\nalias byte SCHAR, SQLSCHAR;\nalias int SDWORD, SLONG, SQLINTEGER;\nalias short SWORD, SSHORT, RETCODE, SQLSMALLINT;\nalias ULONG UDWORD;\nalias USHORT UWORD, SQLUSMALLINT;\nalias double SDOUBLE, LDOUBLE;\nalias float SFLOAT;\nalias PVOID PTR, HENV, HDBC, HSTMT, SQLPOINTER;\nalias UCHAR SQLCHAR;\n// #ifndef _WIN64\nalias UDWORD SQLUINTEGER;\n// #endif\n\n//static if (ODBCVER >= 0x0300) {\nalias TypeDef!(HANDLE) SQLHANDLE;\nalias SQLHANDLE SQLHENV, SQLHDBC, SQLHSTMT, SQLHDESC;\n/*\n} else {\nalias void* SQLHENV;\nalias void* SQLHDBC;\nalias void* SQLHSTMT;\n}\n*/\nalias SQLSMALLINT SQLRETURN;\nalias HWND SQLHWND;\nalias ULONG BOOKMARK;\n\nalias SQLINTEGER SQLLEN, SQLROWOFFSET;\nalias SQLUINTEGER SQLROWCOUNT, SQLULEN;\nalias DWORD SQLTRANSID;\nalias SQLUSMALLINT SQLSETPOSIROW;\nalias wchar SQLWCHAR;\n\nversion (Unicode) {\n    alias SQLWCHAR SQLTCHAR;\n} else {\n    alias SQLCHAR  SQLTCHAR;\n}\n//static if (ODBCVER >= 0x0300) {\nalias ubyte  SQLDATE, SQLDECIMAL;\nalias double SQLDOUBLE, SQLFLOAT;\nalias ubyte  SQLNUMERIC;\nalias float  SQLREAL;\nalias ubyte  SQLTIME, SQLTIMESTAMP, SQLVARCHAR;\nalias long   ODBCINT64, SQLBIGINT;\nalias ulong  SQLUBIGINT;\n//}\n\nstruct DATE_STRUCT {\n    SQLSMALLINT year;\n    SQLUSMALLINT month;\n    SQLUSMALLINT day;\n}\n\nstruct TIME_STRUCT {\n    SQLUSMALLINT hour;\n    SQLUSMALLINT minute;\n    SQLUSMALLINT second;\n}\n\nstruct TIMESTAMP_STRUCT {\n    SQLSMALLINT year;\n    SQLUSMALLINT month;\n    SQLUSMALLINT day;\n    SQLUSMALLINT hour;\n    SQLUSMALLINT minute;\n    SQLUSMALLINT second;\n    SQLUINTEGER fraction;\n}\n\n//static if (ODBCVER >= 0x0300) {\nalias DATE_STRUCT SQL_DATE_STRUCT;\nalias TIME_STRUCT SQL_TIME_STRUCT;\nalias TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT;\n\nenum SQLINTERVAL {\n    SQL_IS_YEAR = 1,\n    SQL_IS_MONTH,\n    SQL_IS_DAY,\n    SQL_IS_HOUR,\n    SQL_IS_MINUTE,\n    SQL_IS_SECOND,\n    SQL_IS_YEAR_TO_MONTH,\n    SQL_IS_DAY_TO_HOUR,\n    SQL_IS_DAY_TO_MINUTE,\n    SQL_IS_DAY_TO_SECOND,\n    SQL_IS_HOUR_TO_MINUTE,\n    SQL_IS_HOUR_TO_SECOND,\n    SQL_IS_MINUTE_TO_SECOND\n}\n\nstruct SQL_YEAR_MONTH_STRUCT {\n    SQLUINTEGER year;\n    SQLUINTEGER month;\n}\n\nstruct SQL_DAY_SECOND_STRUCT {\n    SQLUINTEGER day;\n    SQLUINTEGER hour;\n    SQLUINTEGER minute;\n    SQLUINTEGER second;\n    SQLUINTEGER fraction;\n}\n\nstruct SQL_INTERVAL_STRUCT {\n    SQLINTERVAL interval_type;\n    SQLSMALLINT interval_sign;\n    union _intval {\n        SQL_YEAR_MONTH_STRUCT year_month;\n        SQL_DAY_SECOND_STRUCT day_second;\n    }\n    _intval intval;\n}\n\nenum SQL_MAX_NUMERIC_LEN = 16;\n\nstruct SQL_NUMERIC_STRUCT {\n    SQLCHAR precision;\n    SQLSCHAR scale;\n    SQLCHAR sign;\n    SQLCHAR[SQL_MAX_NUMERIC_LEN] val;\n}\n// } ODBCVER >= 0x0300\nalias GUID SQLGUID;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/sqlucode.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_sqlucode.d)\n */\nmodule core.sys.windows.sqlucode;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.sqlext;\n\nenum SQL_WCHAR        = -8;\nenum SQL_WVARCHAR     = -9;\nenum SQL_WLONGVARCHAR = -10;\nenum SQL_C_WCHAR      = SQL_WCHAR;\n\nenum SQL_SQLSTATE_SIZEW = 10;\nversion (Unicode) {\nenum SQL_C_TCHAR = SQL_C_WCHAR;\n} else {\nenum SQL_C_TCHAR = SQL_C_CHAR;\n}\n\n// Moved from sqlext\nstatic if (ODBCVER <= 0x0300) {\nenum SQL_UNICODE             = -95;\nenum SQL_UNICODE_VARCHAR     = -96;\nenum SQL_UNICODE_LONGVARCHAR = -97;\nenum SQL_UNICODE_CHAR        = SQL_UNICODE;\n} else {\nenum SQL_UNICODE             = SQL_WCHAR;\nenum SQL_UNICODE_VARCHAR     = SQL_WVARCHAR;\nenum SQL_UNICODE_LONGVARCHAR = SQL_WLONGVARCHAR;\nenum SQL_UNICODE_CHAR        = SQL_WCHAR;\n}\n\nextern (Windows) {\n    SQLRETURN SQLBrowseConnectA(SQLHDBC, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLBrowseConnectW(SQLHDBC, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLColAttributeA(SQLHSTMT, SQLSMALLINT, SQLSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*, SQLPOINTER);\n    SQLRETURN SQLColAttributeW(SQLHSTMT, SQLUSMALLINT, SQLUSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*, SQLPOINTER);\n    SQLRETURN SQLColAttributesA(SQLHSTMT, SQLUSMALLINT, SQLUSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*, SQLLEN*);\n    SQLRETURN SQLColAttributesW(SQLHSTMT, SQLUSMALLINT, SQLUSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*, SQLLEN*);\n    SQLRETURN SQLColumnPrivilegesA( SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT , SQLCHAR*, SQLSMALLINT );\n    SQLRETURN SQLColumnPrivilegesW( SQLHSTMT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT );\n    SQLRETURN SQLColumnsA(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT , SQLCHAR*, SQLSMALLINT );\n    SQLRETURN SQLColumnsW(SQLHSTMT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT , SQLWCHAR*, SQLSMALLINT );\n    SQLRETURN SQLConnectA(SQLHDBC, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLConnectW(SQLHDBC, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT);\n    SQLRETURN SQLDataSourcesA(SQLHENV, SQLUSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLDataSourcesW(SQLHENV, SQLUSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLDescribeColA(SQLHSTMT, SQLUSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLSMALLINT*, SQLULEN*, SQLSMALLINT*, SQLSMALLINT*);\n    SQLRETURN SQLDescribeColW(SQLHSTMT, SQLUSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLSMALLINT*, SQLULEN*, SQLSMALLINT*, SQLSMALLINT*);\n    SQLRETURN SQLDriverConnectA(SQLHDBC, SQLHWND, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLUSMALLINT);\n    SQLRETURN SQLDriverConnectW(SQLHDBC, SQLHWND, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLUSMALLINT);\n    SQLRETURN SQLDriversA(SQLHENV, SQLUSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLDriversW(SQLHENV, SQLUSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLErrorA(SQLHENV, SQLHDBC, SQLHSTMT, SQLCHAR*, SQLINTEGER*, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLErrorW(SQLHENV, SQLHDBC, SQLHSTMT, SQLWCHAR*, SQLINTEGER*, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLExecDirectA(SQLHSTMT, SQLCHAR*, SQLINTEGER);\n    SQLRETURN SQLExecDirectW(SQLHSTMT, SQLWCHAR*, SQLINTEGER);\n    SQLRETURN SQLForeignKeysA(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLForeignKeysW(SQLHSTMT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT);\n    SQLRETURN SQLGetConnectAttrA(SQLHDBC, SQLINTEGER, SQLPOINTER, SQLINTEGER, SQLINTEGER*);\n    SQLRETURN SQLGetConnectAttrW(SQLHDBC, SQLINTEGER, SQLPOINTER, SQLINTEGER, SQLINTEGER*);\n    SQLRETURN SQLGetConnectOptionA(SQLHDBC, SQLUSMALLINT, SQLPOINTER);\n    SQLRETURN SQLGetConnectOptionW(SQLHDBC, SQLUSMALLINT, SQLPOINTER);\n    SQLRETURN SQLGetCursorNameA(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLGetCursorNameW(SQLHSTMT, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLGetInfoA(SQLHDBC, SQLUSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLGetInfoW(SQLHDBC, SQLUSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*);\n    SQLRETURN SQLGetTypeInfoA(SQLHSTMT, SQLSMALLINT);\n    SQLRETURN SQLGetTypeInfoW(SQLHSTMT, SQLSMALLINT);\n    SQLRETURN SQLNativeSqlA(SQLHDBC, SQLCHAR*, SQLINTEGER, SQLCHAR*, SQLINTEGER, SQLINTEGER*);\n    SQLRETURN SQLNativeSqlW(SQLHDBC, SQLWCHAR*, SQLINTEGER, SQLWCHAR*, SQLINTEGER, SQLINTEGER*);\n    SQLRETURN SQLPrepareA(SQLHSTMT, SQLCHAR*, SQLINTEGER);\n    SQLRETURN SQLPrepareW(SQLHSTMT, SQLWCHAR*, SQLINTEGER);\n    SQLRETURN SQLPrimaryKeysA(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT );\n    SQLRETURN SQLPrimaryKeysW(SQLHSTMT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT);\n    SQLRETURN SQLProcedureColumnsA(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLProcedureColumnsW(SQLHSTMT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT);\n    SQLRETURN SQLProceduresA(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLProceduresW(SQLHSTMT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT);\n    SQLRETURN SQLSetConnectAttrA(SQLHDBC, SQLINTEGER, SQLPOINTER, SQLINTEGER);\n    SQLRETURN SQLSetConnectAttrW(SQLHDBC, SQLINTEGER, SQLPOINTER, SQLINTEGER);\n    SQLRETURN SQLSetConnectOptionA(SQLHDBC, SQLUSMALLINT, SQLULEN);\n    SQLRETURN SQLSetConnectOptionW(SQLHDBC, SQLUSMALLINT, SQLULEN);\n    SQLRETURN SQLSetCursorNameA(SQLHSTMT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLSetCursorNameW(SQLHSTMT, SQLWCHAR*, SQLSMALLINT);\n    SQLRETURN SQLSpecialColumnsA(SQLHSTMT, SQLUSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT , SQLUSMALLINT, SQLUSMALLINT);\n    SQLRETURN SQLSpecialColumnsW(SQLHSTMT, SQLUSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT , SQLUSMALLINT, SQLUSMALLINT);\n    SQLRETURN SQLStatisticsA(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT , SQLUSMALLINT, SQLUSMALLINT);\n    SQLRETURN SQLStatisticsW(SQLHSTMT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT , SQLUSMALLINT, SQLUSMALLINT);\n    SQLRETURN SQLTablePrivilegesA(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLTablePrivilegesW(SQLHSTMT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT );\n    SQLRETURN SQLTablesA(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT);\n    SQLRETURN SQLTablesW(SQLHSTMT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT);\n    static if (ODBCVER >= 0x0300) {\n        SQLRETURN SQLGetDescFieldA(SQLHDESC, SQLSMALLINT, SQLSMALLINT, SQLPOINTER, SQLINTEGER, SQLINTEGER*);\n        SQLRETURN SQLGetDescFieldW(SQLHDESC, SQLSMALLINT, SQLSMALLINT, SQLPOINTER, SQLINTEGER, SQLINTEGER*);\n        SQLRETURN SQLSetDescFieldA(SQLHDESC, SQLSMALLINT, SQLSMALLINT, SQLPOINTER, SQLINTEGER);\n        SQLRETURN SQLSetDescFieldW(SQLHDESC, SQLSMALLINT, SQLSMALLINT, SQLPOINTER, SQLINTEGER);\n        SQLRETURN SQLGetDescRecA(SQLHDESC, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLSMALLINT*, SQLSMALLINT*, SQLLEN*, SQLSMALLINT*, SQLSMALLINT*, SQLSMALLINT*);\n        SQLRETURN SQLGetDescRecW(SQLHDESC, SQLSMALLINT, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLSMALLINT*, SQLSMALLINT*, SQLLEN*, SQLSMALLINT*, SQLSMALLINT*, SQLSMALLINT*);\n        SQLRETURN SQLGetDiagFieldA(SQLSMALLINT, SQLHANDLE, SQLSMALLINT, SQLSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*);\n        SQLRETURN SQLGetDiagFieldW(SQLSMALLINT, SQLHANDLE, SQLSMALLINT, SQLSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*);\n        SQLRETURN SQLGetDiagRecA(SQLSMALLINT, SQLHANDLE, SQLSMALLINT, SQLCHAR*, SQLINTEGER*, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*);\n        SQLRETURN SQLGetDiagRecW(SQLSMALLINT, SQLHANDLE, SQLSMALLINT, SQLWCHAR*, SQLINTEGER*, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*);\n        SQLRETURN SQLGetStmtAttrA(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER, SQLINTEGER*);\n        SQLRETURN SQLGetStmtAttrW(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER, SQLINTEGER*);\n        SQLRETURN SQLSetStmtAttrA(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER);\n        SQLRETURN SQLSetStmtAttrW(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER);\n    } // #endif /* (ODBCVER >= 0x0300) */\n}\n\nversion (Unicode) {\n    alias SQLBrowseConnectW SQLBrowseConnect;\n    alias SQLColAttributeW SQLColAttribute;\n    alias SQLColAttributesW SQLColAttributes;\n    alias SQLColumnPrivilegesW SQLColumnPrivileges;\n    alias SQLColumnsW SQLColumns;\n    alias SQLConnectW SQLConnect;\n    alias SQLDataSourcesW SQLDataSources;\n    alias SQLDescribeColW SQLDescribeCol;\n    alias SQLDriverConnectW SQLDriverConnect;\n    alias SQLDriversW SQLDrivers;\n    alias SQLErrorW SQLError;\n    alias SQLExecDirectW SQLExecDirect;\n    alias SQLForeignKeysW SQLForeignKeys;\n    alias SQLGetConnectAttrW SQLGetConnectAttr;\n    alias SQLGetConnectOptionW SQLGetConnectOption;\n    alias SQLGetCursorNameW SQLGetCursorName;\n    alias SQLGetDescFieldW SQLGetDescField;\n    alias SQLGetDescRecW SQLGetDescRec;\n    alias SQLGetDiagFieldW SQLGetDiagField;\n    alias SQLGetDiagRecW SQLGetDiagRec;\n    alias SQLGetInfoW SQLGetInfo;\n    alias SQLGetStmtAttrW SQLGetStmtAttr;\n    alias SQLGetTypeInfoW SQLGetTypeInfo;\n    alias SQLNativeSqlW SQLNativeSql;\n    alias SQLPrepareW SQLPrepare;\n    alias SQLPrimaryKeysW SQLPrimaryKeys;\n    alias SQLProcedureColumnsW SQLProcedureColumns;\n    alias SQLProceduresW SQLProcedures;\n    alias SQLSetConnectAttrW SQLSetConnectAttr;\n    alias SQLSetConnectOptionW SQLSetConnectOption;\n    alias SQLSetCursorNameW SQLSetCursorName;\n    alias SQLSetDescFieldW SQLSetDescField;\n    alias SQLSetStmtAttrW SQLSetStmtAttr;\n    alias SQLSpecialColumnsW SQLSpecialColumns;\n    alias SQLStatisticsW SQLStatistics;\n    alias SQLTablePrivilegesW SQLTablePrivileges;\n    alias SQLTablesW SQLTables;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/sspi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Ellery Newcomer\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_sspi.d)\n */\nmodule core.sys.windows.sspi;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nimport core.sys.windows.windef;\nimport core.sys.windows.ntdef;\nimport core.sys.windows.w32api;\nimport core.sys.windows.security;\nimport core.sys.windows.ntsecapi;\nimport core.sys.windows.subauth;\n\nenum :ULONG{\n    SECPKG_CRED_INBOUND = 1,\n    SECPKG_CRED_OUTBOUND = 2,\n    SECPKG_CRED_BOTH = (SECPKG_CRED_OUTBOUND|SECPKG_CRED_INBOUND),\n    SECPKG_CRED_ATTR_NAMES = 1,\n}\n\nenum :ULONG{\n    SECPKG_FLAG_INTEGRITY = 1,\n    SECPKG_FLAG_PRIVACY = 2,\n    SECPKG_FLAG_TOKEN_ONLY = 4,\n    SECPKG_FLAG_DATAGRAM = 8,\n    SECPKG_FLAG_CONNECTION = 16,\n    SECPKG_FLAG_MULTI_REQUIRED = 32,\n    SECPKG_FLAG_CLIENT_ONLY = 64,\n    SECPKG_FLAG_EXTENDED_ERROR = 128,\n    SECPKG_FLAG_IMPERSONATION = 256,\n    SECPKG_FLAG_ACCEPT_WIN32_NAME = 512,\n    SECPKG_FLAG_STREAM = 1024,\n}\n\nenum :ULONG{\n    SECPKG_ATTR_AUTHORITY = 6,\n    SECPKG_ATTR_CONNECTION_INFO = 90,\n    SECPKG_ATTR_ISSUER_LIST = 80,\n    SECPKG_ATTR_ISSUER_LIST_EX = 89,\n    SECPKG_ATTR_KEY_INFO = 5,\n    SECPKG_ATTR_LIFESPAN = 2,\n    SECPKG_ATTR_LOCAL_CERT_CONTEXT = 84,\n    SECPKG_ATTR_LOCAL_CRED = 82,\n    SECPKG_ATTR_NAMES = 1,\n    SECPKG_ATTR_PROTO_INFO = 7,\n    SECPKG_ATTR_REMOTE_CERT_CONTEXT = 83,\n    SECPKG_ATTR_REMOTE_CRED = 81,\n    SECPKG_ATTR_SIZES = 0,\n    SECPKG_ATTR_STREAM_SIZES = 4,\n}\n\nenum :ULONG{\n    SECBUFFER_EMPTY = 0,\n    SECBUFFER_DATA = 1,\n    SECBUFFER_TOKEN = 2,\n    SECBUFFER_PKG_PARAMS = 3,\n    SECBUFFER_MISSING = 4,\n    SECBUFFER_EXTRA = 5,\n    SECBUFFER_STREAM_TRAILER = 6,\n    SECBUFFER_STREAM_HEADER = 7,\n    SECBUFFER_PADDING = 9,\n    SECBUFFER_STREAM = 10,\n    SECBUFFER_READONLY = 0x80000000,\n    SECBUFFER_ATTRMASK = 0xf0000000,\n}\n\nenum UNISP_NAME_A = \"Microsoft Unified Security Protocol Provider\";\nenum UNISP_NAME_W = \"Microsoft Unified Security Protocol Provider\"w;\nenum SECBUFFER_VERSION = 0;\n\nalias UNICODE_STRING SECURITY_STRING;\nalias UNICODE_STRING* PSECURITY_STRING;\n\nextern(Windows):\n\nstruct SecHandle {\n    ULONG_PTR dwLower;\n    ULONG_PTR dwUpper;\n}\nalias SecHandle* PSecHandle;\nstruct SecBuffer {\n    ULONG cbBuffer;\n    ULONG BufferType;\n    PVOID pvBuffer;\n}\nalias SecBuffer* PSecBuffer;\nalias SecHandle CredHandle;\nalias PSecHandle PCredHandle;\nalias SecHandle CtxtHandle;\nalias PSecHandle PCtxtHandle;\nstruct SECURITY_INTEGER {\n    uint LowPart;\n    int HighPart;\n}\nalias SECURITY_INTEGER TimeStamp;\nalias SECURITY_INTEGER* PTimeStamp;\nstruct SecBufferDesc {\n    ULONG ulVersion;\n    ULONG cBuffers;\n    PSecBuffer pBuffers;\n}\nalias SecBufferDesc* PSecBufferDesc;\nstruct SecPkgContext_StreamSizes {\n    ULONG cbHeader;\n    ULONG cbTrailer;\n    ULONG cbMaximumMessage;\n    ULONG cBuffers;\n    ULONG cbBlockSize;\n}\nalias SecPkgContext_StreamSizes* PSecPkgContext_StreamSizes;\nstruct SecPkgContext_Sizes {\n    ULONG cbMaxToken;\n    ULONG cbMaxSignature;\n    ULONG cbBlockSize;\n    ULONG cbSecurityTrailer;\n}\nalias SecPkgContext_Sizes* PSecPkgContext_Sizes;\nstruct SecPkgContext_AuthorityW {\n    SEC_WCHAR* sAuthorityName;\n}\nalias SecPkgContext_AuthorityW* PSecPkgContext_AuthorityW;\nstruct SecPkgContext_AuthorityA {\n    SEC_CHAR* sAuthorityName;\n}\nalias SecPkgContext_AuthorityA* PSecPkgContext_AuthorityA;\nstruct SecPkgContext_KeyInfoW {\n    SEC_WCHAR* sSignatureAlgorithmName;\n    SEC_WCHAR* sEncryptAlgorithmName;\n    ULONG KeySize;\n    ULONG SignatureAlgorithm;\n    ULONG EncryptAlgorithm;\n}\nalias SecPkgContext_KeyInfoW* PSecPkgContext_KeyInfoW;\nstruct SecPkgContext_KeyInfoA {\n    SEC_CHAR* sSignatureAlgorithmName;\n    SEC_CHAR* sEncryptAlgorithmName;\n    ULONG KeySize;\n    ULONG SignatureAlgorithm;\n    ULONG EncryptAlgorithm;\n}\nalias SecPkgContext_KeyInfoA* PSecPkgContext_KeyInfoA;\nstruct SecPkgContext_LifeSpan {\n    TimeStamp tsStart;\n    TimeStamp tsExpiry;\n}\nalias SecPkgContext_LifeSpan* PSecPkgContext_LifeSpan;\nstruct SecPkgContext_NamesW {\n    SEC_WCHAR* sUserName;\n}\nalias SecPkgContext_NamesW* PSecPkgContext_NamesW;\nstruct SecPkgContext_NamesA {\n    SEC_CHAR* sUserName;\n}\nalias SecPkgContext_NamesA* PSecPkgContext_NamesA;\nstruct SecPkgInfoW {\n    ULONG fCapabilities;\n    USHORT wVersion;\n    USHORT wRPCID;\n    ULONG cbMaxToken;\n    SEC_WCHAR* Name;\n    SEC_WCHAR* Comment;\n}\nalias SecPkgInfoW* PSecPkgInfoW;\nstruct SecPkgInfoA {\n    ULONG fCapabilities;\n    USHORT wVersion;\n    USHORT wRPCID;\n    ULONG cbMaxToken;\n    SEC_CHAR* Name;\n    SEC_CHAR* Comment;\n}\nalias SecPkgInfoA* PSecPkgInfoA;\n/* supported only in win2k+, so it should be a PSecPkgInfoW */\n/* PSDK does not say it has ANSI/Unicode versions */\nstruct SecPkgContext_PackageInfo {\n    PSecPkgInfoW PackageInfo;\n}\nalias SecPkgContext_PackageInfo* PSecPkgContext_PackageInfo;\nstruct SecPkgCredentials_NamesW {\n    SEC_WCHAR* sUserName;\n}\nalias SecPkgCredentials_NamesW* PSecPkgCredentials_NamesW;\nstruct SecPkgCredentials_NamesA {\n    SEC_CHAR* sUserName;\n}\nalias SecPkgCredentials_NamesA* PSecPkgCredentials_NamesA;\n\n/* TODO: missing type in SDK */\nalias void function() SEC_GET_KEY_FN;\n\nalias SECURITY_STATUS function(PULONG,PSecPkgInfoW*) ENUMERATE_SECURITY_PACKAGES_FN_W;\nalias SECURITY_STATUS function(PULONG,PSecPkgInfoA*) ENUMERATE_SECURITY_PACKAGES_FN_A;\nalias SECURITY_STATUS function(PCredHandle,ULONG,PVOID) QUERY_CREDENTIALS_ATTRIBUTES_FN_W;\nalias SECURITY_STATUS function(PCredHandle,ULONG,PVOID) QUERY_CREDENTIALS_ATTRIBUTES_FN_A;\nalias SECURITY_STATUS function(SEC_WCHAR*,SEC_WCHAR*,ULONG,PLUID,PVOID,SEC_GET_KEY_FN,PVOID,PCredHandle,PTimeStamp) ACQUIRE_CREDENTIALS_HANDLE_FN_W;\nalias SECURITY_STATUS function(SEC_CHAR*,SEC_CHAR*,ULONG,PLUID,PVOID,SEC_GET_KEY_FN,PVOID,PCredHandle,PTimeStamp) ACQUIRE_CREDENTIALS_HANDLE_FN_A;\nalias SECURITY_STATUS function(PCredHandle) FREE_CREDENTIALS_HANDLE_FN;\nalias SECURITY_STATUS function(PCredHandle,PCtxtHandle,SEC_WCHAR*,ULONG,ULONG,ULONG,PSecBufferDesc,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp) INITIALIZE_SECURITY_CONTEXT_FN_W;\nalias SECURITY_STATUS function(PCredHandle,PCtxtHandle,SEC_CHAR*,ULONG,ULONG,ULONG,PSecBufferDesc,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp) INITIALIZE_SECURITY_CONTEXT_FN_A;\nalias SECURITY_STATUS function(PCredHandle,PCtxtHandle,PSecBufferDesc,ULONG,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp) ACCEPT_SECURITY_CONTEXT_FN;\nalias SECURITY_STATUS function(PCtxtHandle,PSecBufferDesc) COMPLETE_AUTH_TOKEN_FN;\nalias SECURITY_STATUS function(PCtxtHandle) DELETE_SECURITY_CONTEXT_FN;\nalias SECURITY_STATUS function(PCtxtHandle,PSecBufferDesc) APPLY_CONTROL_TOKEN_FN_W;\nalias SECURITY_STATUS function(PCtxtHandle,PSecBufferDesc) APPLY_CONTROL_TOKEN_FN_A;\nalias SECURITY_STATUS function(PCtxtHandle,ULONG,PVOID) QUERY_CONTEXT_ATTRIBUTES_FN_A;\nalias SECURITY_STATUS function(PCtxtHandle,ULONG,PVOID) QUERY_CONTEXT_ATTRIBUTES_FN_W;\nalias SECURITY_STATUS function(PCtxtHandle) IMPERSONATE_SECURITY_CONTEXT_FN;\nalias SECURITY_STATUS function(PCtxtHandle) REVERT_SECURITY_CONTEXT_FN;\nalias SECURITY_STATUS function(PCtxtHandle,ULONG,PSecBufferDesc,ULONG) MAKE_SIGNATURE_FN;\nalias SECURITY_STATUS function(PCtxtHandle,PSecBufferDesc,ULONG,PULONG) VERIFY_SIGNATURE_FN;\nalias SECURITY_STATUS function(PVOID) FREE_CONTEXT_BUFFER_FN;\nalias SECURITY_STATUS function(SEC_CHAR*,PSecPkgInfoA*) QUERY_SECURITY_PACKAGE_INFO_FN_A;\nalias SECURITY_STATUS function(PCtxtHandle,HANDLE*) QUERY_SECURITY_CONTEXT_TOKEN_FN;\nalias SECURITY_STATUS function(SEC_WCHAR*,PSecPkgInfoW*) QUERY_SECURITY_PACKAGE_INFO_FN_W;\nalias SECURITY_STATUS function(PCtxtHandle,ULONG,PSecBufferDesc,ULONG) ENCRYPT_MESSAGE_FN;\nalias SECURITY_STATUS function(PCtxtHandle,PSecBufferDesc,ULONG,PULONG) DECRYPT_MESSAGE_FN;\n\n/* No, it really is FreeCredentialsHandle, see the thread beginning\n * http://sourceforge.net/mailarchive/message.php?msg_id=4321080 for a\n * discovery discussion. */\nstruct SecurityFunctionTableW{\n    uint dwVersion;\n    ENUMERATE_SECURITY_PACKAGES_FN_W EnumerateSecurityPackagesW;\n    QUERY_CREDENTIALS_ATTRIBUTES_FN_W QueryCredentialsAttributesW;\n    ACQUIRE_CREDENTIALS_HANDLE_FN_W AcquireCredentialsHandleW;\n    FREE_CREDENTIALS_HANDLE_FN FreeCredentialsHandle;\n    void* Reserved2;\n    INITIALIZE_SECURITY_CONTEXT_FN_W InitializeSecurityContextW;\n    ACCEPT_SECURITY_CONTEXT_FN AcceptSecurityContext;\n    COMPLETE_AUTH_TOKEN_FN CompleteAuthToken;\n    DELETE_SECURITY_CONTEXT_FN DeleteSecurityContext;\n    APPLY_CONTROL_TOKEN_FN_W ApplyControlTokenW;\n    QUERY_CONTEXT_ATTRIBUTES_FN_W QueryContextAttributesW;\n    IMPERSONATE_SECURITY_CONTEXT_FN ImpersonateSecurityContext;\n    REVERT_SECURITY_CONTEXT_FN RevertSecurityContext;\n    MAKE_SIGNATURE_FN MakeSignature;\n    VERIFY_SIGNATURE_FN VerifySignature;\n    FREE_CONTEXT_BUFFER_FN FreeContextBuffer;\n    QUERY_SECURITY_PACKAGE_INFO_FN_W QuerySecurityPackageInfoW;\n    void* Reserved3;\n    void* Reserved4;\n    void* Reserved5;\n    void* Reserved6;\n    void* Reserved7;\n    void* Reserved8;\n    QUERY_SECURITY_CONTEXT_TOKEN_FN QuerySecurityContextToken;\n    ENCRYPT_MESSAGE_FN EncryptMessage;\n    DECRYPT_MESSAGE_FN DecryptMessage;\n}\nalias SecurityFunctionTableW* PSecurityFunctionTableW;\nstruct SecurityFunctionTableA{\n    uint dwVersion;\n    ENUMERATE_SECURITY_PACKAGES_FN_A EnumerateSecurityPackagesA;\n    QUERY_CREDENTIALS_ATTRIBUTES_FN_A QueryCredentialsAttributesA;\n    ACQUIRE_CREDENTIALS_HANDLE_FN_A AcquireCredentialsHandleA;\n    FREE_CREDENTIALS_HANDLE_FN FreeCredentialsHandle;\n    void* Reserved2;\n    INITIALIZE_SECURITY_CONTEXT_FN_A InitializeSecurityContextA;\n    ACCEPT_SECURITY_CONTEXT_FN AcceptSecurityContext;\n    COMPLETE_AUTH_TOKEN_FN CompleteAuthToken;\n    DELETE_SECURITY_CONTEXT_FN DeleteSecurityContext;\n    APPLY_CONTROL_TOKEN_FN_A ApplyControlTokenA;\n    QUERY_CONTEXT_ATTRIBUTES_FN_A QueryContextAttributesA;\n    IMPERSONATE_SECURITY_CONTEXT_FN ImpersonateSecurityContext;\n    REVERT_SECURITY_CONTEXT_FN RevertSecurityContext;\n    MAKE_SIGNATURE_FN MakeSignature;\n    VERIFY_SIGNATURE_FN VerifySignature;\n    FREE_CONTEXT_BUFFER_FN FreeContextBuffer;\n    QUERY_SECURITY_PACKAGE_INFO_FN_A QuerySecurityPackageInfoA;\n    void* Reserved3;\n    void* Reserved4;\n    void* Unknown1;\n    void* Unknown2;\n    void* Unknown3;\n    void* Unknown4;\n    void* Unknown5;\n    ENCRYPT_MESSAGE_FN EncryptMessage;\n    DECRYPT_MESSAGE_FN DecryptMessage;\n}\nalias SecurityFunctionTableA* PSecurityFunctionTableA;\nalias PSecurityFunctionTableA function() INIT_SECURITY_INTERFACE_A;\nalias PSecurityFunctionTableW function() INIT_SECURITY_INTERFACE_W;\n\nSECURITY_STATUS FreeCredentialsHandle(PCredHandle);\nSECURITY_STATUS EnumerateSecurityPackagesA(PULONG,PSecPkgInfoA*);\nSECURITY_STATUS EnumerateSecurityPackagesW(PULONG,PSecPkgInfoW*);\nSECURITY_STATUS AcquireCredentialsHandleA(SEC_CHAR*,SEC_CHAR*,ULONG,PLUID,PVOID,SEC_GET_KEY_FN,PVOID,PCredHandle,PTimeStamp);\nSECURITY_STATUS AcquireCredentialsHandleW(SEC_WCHAR*,SEC_WCHAR*,ULONG,PLUID,PVOID,SEC_GET_KEY_FN,PVOID,PCredHandle,PTimeStamp);\nSECURITY_STATUS AcceptSecurityContext(PCredHandle,PCtxtHandle,PSecBufferDesc,ULONG,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp);\nSECURITY_STATUS InitializeSecurityContextA(PCredHandle,PCtxtHandle,SEC_CHAR*,ULONG,ULONG,ULONG,PSecBufferDesc,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp);\nSECURITY_STATUS InitializeSecurityContextW(PCredHandle,PCtxtHandle,SEC_WCHAR*,ULONG,ULONG,ULONG,PSecBufferDesc,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp);\nSECURITY_STATUS FreeContextBuffer(PVOID);\nSECURITY_STATUS QueryContextAttributesA(PCtxtHandle,ULONG,PVOID);\nSECURITY_STATUS QueryContextAttributesW(PCtxtHandle,ULONG,PVOID);\nSECURITY_STATUS QueryCredentialsAttributesA(PCredHandle,ULONG,PVOID);\nSECURITY_STATUS QueryCredentialsAttributesW(PCredHandle,ULONG,PVOID);\nstatic if (_WIN32_WINNT >= 0x500){\n    SECURITY_STATUS QuerySecurityContextToken(PCtxtHandle,HANDLE*);\n}\nSECURITY_STATUS DecryptMessage(PCtxtHandle,PSecBufferDesc,ULONG,PULONG);\nSECURITY_STATUS EncryptMessage(PCtxtHandle,ULONG,PSecBufferDesc,ULONG);\nSECURITY_STATUS DeleteSecurityContext(PCtxtHandle);\nSECURITY_STATUS CompleteAuthToken(PCtxtHandle,PSecBufferDesc);\nSECURITY_STATUS ApplyControlTokenA(PCtxtHandle,PSecBufferDesc);\nSECURITY_STATUS ApplyControlTokenW(PCtxtHandle,PSecBufferDesc);\nSECURITY_STATUS ImpersonateSecurityContext(PCtxtHandle);\nSECURITY_STATUS RevertSecurityContext(PCtxtHandle);\nSECURITY_STATUS MakeSignature(PCtxtHandle,ULONG,PSecBufferDesc,ULONG);\nSECURITY_STATUS VerifySignature(PCtxtHandle,PSecBufferDesc,ULONG,PULONG);\nSECURITY_STATUS QuerySecurityPackageInfoA(SEC_CHAR*,PSecPkgInfoA*);\nSECURITY_STATUS QuerySecurityPackageInfoW(SEC_WCHAR*,PSecPkgInfoW*);\nPSecurityFunctionTableA InitSecurityInterfaceA();\nPSecurityFunctionTableW InitSecurityInterfaceW();\n\nversion (Unicode) {\n    alias UNISP_NAME_W UNISP_NAME;\n    alias SecPkgInfoW SecPkgInfo;\n    alias PSecPkgInfoW PSecPkgInfo;\n    alias SecPkgCredentials_NamesW SecPkgCredentials_Names;\n    alias PSecPkgCredentials_NamesW PSecPkgCredentials_Names;\n    alias SecPkgContext_AuthorityW SecPkgContext_Authority;\n    alias PSecPkgContext_AuthorityW PSecPkgContext_Authority;\n    alias SecPkgContext_KeyInfoW SecPkgContext_KeyInfo;\n    alias PSecPkgContext_KeyInfoW PSecPkgContext_KeyInfo;\n    alias SecPkgContext_NamesW SecPkgContext_Names;\n    alias PSecPkgContext_NamesW PSecPkgContext_Names;\n    alias SecurityFunctionTableW SecurityFunctionTable;\n    alias PSecurityFunctionTableW PSecurityFunctionTable;\n    alias AcquireCredentialsHandleW AcquireCredentialsHandle;\n    alias EnumerateSecurityPackagesW EnumerateSecurityPackages;\n    alias InitializeSecurityContextW InitializeSecurityContext;\n    alias QueryContextAttributesW QueryContextAttributes;\n    alias QueryCredentialsAttributesW QueryCredentialsAttributes;\n    alias QuerySecurityPackageInfoW QuerySecurityPackageInfo;\n    alias ApplyControlTokenW ApplyControlToken;\n    alias ENUMERATE_SECURITY_PACKAGES_FN_W ENUMERATE_SECURITY_PACKAGES_FN;\n    alias QUERY_CREDENTIALS_ATTRIBUTES_FN_W QUERY_CREDENTIALS_ATTRIBUTES_FN;\n    alias ACQUIRE_CREDENTIALS_HANDLE_FN_W ACQUIRE_CREDENTIALS_HANDLE_FN;\n    alias INITIALIZE_SECURITY_CONTEXT_FN_W INITIALIZE_SECURITY_CONTEXT_FN;\n    alias APPLY_CONTROL_TOKEN_FN_W APPLY_CONTROL_TOKEN_FN;\n    alias QUERY_CONTEXT_ATTRIBUTES_FN_W QUERY_CONTEXT_ATTRIBUTES_FN;\n    alias QUERY_SECURITY_PACKAGE_INFO_FN_W QUERY_SECURITY_PACKAGE_INFO_FN;\n    alias INIT_SECURITY_INTERFACE_W INIT_SECURITY_INTERFACE;\n}else{\n    alias UNISP_NAME_A UNISP_NAME;\n    alias SecPkgInfoA SecPkgInfo;\n    alias PSecPkgInfoA PSecPkgInfo;\n    alias SecPkgCredentials_NamesA SecPkgCredentials_Names;\n    alias PSecPkgCredentials_NamesA PSecPkgCredentials_Names;\n    alias SecPkgContext_AuthorityA SecPkgContext_Authority;\n    alias PSecPkgContext_AuthorityA PSecPkgContext_Authority;\n    alias SecPkgContext_KeyInfoA SecPkgContext_KeyInfo;\n    alias PSecPkgContext_KeyInfoA PSecPkgContext_KeyInfo;\n    alias SecPkgContext_NamesA SecPkgContext_Names;\n    alias PSecPkgContext_NamesA PSecPkgContext_Names;\n    alias SecurityFunctionTableA SecurityFunctionTable;\n    alias PSecurityFunctionTableA PSecurityFunctionTable;\n    alias AcquireCredentialsHandleA AcquireCredentialsHandle;\n    alias EnumerateSecurityPackagesA EnumerateSecurityPackages;\n    alias InitializeSecurityContextA InitializeSecurityContext;\n    alias QueryContextAttributesA QueryContextAttributes;\n    alias QueryCredentialsAttributesA QueryCredentialsAttributes;\n    alias QuerySecurityPackageInfoA QuerySecurityPackageInfo;\n    alias ApplyControlTokenA ApplyControlToken;\n    alias ENUMERATE_SECURITY_PACKAGES_FN_A ENUMERATE_SECURITY_PACKAGES_FN;\n    alias QUERY_CREDENTIALS_ATTRIBUTES_FN_A QUERY_CREDENTIALS_ATTRIBUTES_FN;\n    alias ACQUIRE_CREDENTIALS_HANDLE_FN_A ACQUIRE_CREDENTIALS_HANDLE_FN;\n    alias INITIALIZE_SECURITY_CONTEXT_FN_A INITIALIZE_SECURITY_CONTEXT_FN;\n    alias APPLY_CONTROL_TOKEN_FN_A APPLY_CONTROL_TOKEN_FN;\n    alias QUERY_CONTEXT_ATTRIBUTES_FN_A QUERY_CONTEXT_ATTRIBUTES_FN;\n    alias QUERY_SECURITY_PACKAGE_INFO_FN_A QUERY_SECURITY_PACKAGE_INFO_FN;\n    alias INIT_SECURITY_INTERFACE_A INIT_SECURITY_INTERFACE;\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/stacktrace.d",
    "content": "/**\n * ...\n *\n * Copyright: Copyright Benjamin Thaut 2010 - 2013.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Benjamin Thaut, Sean Kelly\n * Source:    $(DRUNTIMESRC core/sys/windows/_stacktrace.d)\n */\n\nmodule core.sys.windows.stacktrace;\nversion (Windows):\n\nimport core.demangle;\nimport core.runtime;\nimport core.stdc.stdlib;\nimport core.stdc.string;\nimport core.sys.windows.dbghelp;\nimport core.sys.windows.windows;\n\n//debug=PRINTF;\ndebug(PRINTF) import core.stdc.stdio;\n\n\nextern(Windows) void RtlCaptureContext(CONTEXT* ContextRecord);\nextern(Windows) DWORD GetEnvironmentVariableA(LPCSTR lpName, LPSTR pBuffer, DWORD nSize);\n\nextern(Windows) alias USHORT function(ULONG FramesToSkip, ULONG FramesToCapture, PVOID *BackTrace, PULONG BackTraceHash) RtlCaptureStackBackTraceFunc;\n\nprivate __gshared RtlCaptureStackBackTraceFunc RtlCaptureStackBackTrace;\nprivate __gshared immutable bool initialized;\n\n\nclass StackTrace : Throwable.TraceInfo\n{\npublic:\n    /**\n     * Constructor\n     * Params:\n     *  skip = The number of stack frames to skip.\n     *  context = The context to receive the stack trace from. Can be null.\n     */\n    this(size_t skip, CONTEXT* context)\n    {\n        if (context is null)\n        {\n            version (Win64)\n                static enum INTERNALFRAMES = 3;\n            else version (Win32)\n                static enum INTERNALFRAMES = 2;\n\n            skip += INTERNALFRAMES; //skip the stack frames within the StackTrace class\n        }\n        else\n        {\n            //When a exception context is given the first stack frame is repeated for some reason\n            version (Win64)\n                static enum INTERNALFRAMES = 1;\n            else version (Win32)\n                static enum INTERNALFRAMES = 1;\n\n            skip += INTERNALFRAMES;\n        }\n        if ( initialized )\n            m_trace = trace(skip, context);\n    }\n\n    int opApply( scope int delegate(ref const(char[])) dg ) const\n    {\n        return opApply( (ref size_t, ref const(char[]) buf)\n                        {\n                            return dg( buf );\n                        });\n    }\n\n\n    int opApply( scope int delegate(ref size_t, ref const(char[])) dg ) const\n    {\n        int result;\n        foreach ( i, e; resolve(m_trace) )\n        {\n            if ( (result = dg( i, e )) != 0 )\n                break;\n        }\n        return result;\n    }\n\n\n    @trusted override string toString() const\n    {\n        string result;\n\n        foreach ( e; this )\n        {\n            result ~= e ~ \"\\n\";\n        }\n        return result;\n    }\n\n    /**\n     * Receive a stack trace in the form of an address list.\n     * Params:\n     *  skip = How many stack frames should be skipped.\n     *  context = The context that should be used. If null the current context is used.\n     * Returns:\n     *  A list of addresses that can be passed to resolve at a later point in time.\n     */\n    static ulong[] trace(size_t skip = 0, CONTEXT* context = null)\n    {\n        synchronized( typeid(StackTrace) )\n        {\n            return traceNoSync(skip, context);\n        }\n    }\n\n    /**\n     * Resolve a stack trace.\n     * Params:\n     *  addresses = A list of addresses to resolve.\n     * Returns:\n     *  An array of strings with the results.\n     */\n    @trusted static char[][] resolve(const(ulong)[] addresses)\n    {\n        synchronized( typeid(StackTrace) )\n        {\n            return resolveNoSync(addresses);\n        }\n    }\n\nprivate:\n    ulong[] m_trace;\n\n\n    static ulong[] traceNoSync(size_t skip, CONTEXT* context)\n    {\n        auto dbghelp  = DbgHelp.get();\n        if (dbghelp is null)\n            return []; // dbghelp.dll not available\n\n        if (RtlCaptureStackBackTrace !is null && context is null)\n        {\n            size_t[63] buffer = void; // On windows xp the sum of \"frames to skip\" and \"frames to capture\" can't be greater then 63\n            auto backtraceLength = RtlCaptureStackBackTrace(cast(ULONG)skip, cast(ULONG)(buffer.length - skip), cast(void**)buffer.ptr, null);\n\n            // If we get a backtrace and it does not have the maximum length use it.\n            // Otherwise rely on tracing through StackWalk64 which is slower but works when no frame pointers are available.\n            if (backtraceLength > 1 && backtraceLength < buffer.length - skip)\n            {\n                debug(PRINTF) printf(\"Using result from RtlCaptureStackBackTrace\\n\");\n                version (Win64)\n                {\n                    return buffer[0..backtraceLength].dup;\n                }\n                else version (Win32)\n                {\n                    auto result = new ulong[backtraceLength];\n                    foreach (i, ref e; result)\n                    {\n                        e = buffer[i];\n                    }\n                    return result;\n                }\n            }\n        }\n\n        HANDLE       hThread  = GetCurrentThread();\n        HANDLE       hProcess = GetCurrentProcess();\n        CONTEXT      ctxt;\n\n        if (context is null)\n        {\n            ctxt.ContextFlags = CONTEXT_FULL;\n            RtlCaptureContext(&ctxt);\n        }\n        else\n        {\n            ctxt = *context;\n        }\n\n        //x86\n        STACKFRAME64 stackframe;\n        with (stackframe)\n        {\n            version (X86)\n            {\n                enum Flat = ADDRESS_MODE.AddrModeFlat;\n                AddrPC.Offset    = ctxt.Eip;\n                AddrPC.Mode      = Flat;\n                AddrFrame.Offset = ctxt.Ebp;\n                AddrFrame.Mode   = Flat;\n                AddrStack.Offset = ctxt.Esp;\n                AddrStack.Mode   = Flat;\n            }\n        else version (X86_64)\n            {\n                enum Flat = ADDRESS_MODE.AddrModeFlat;\n                AddrPC.Offset    = ctxt.Rip;\n                AddrPC.Mode      = Flat;\n                AddrFrame.Offset = ctxt.Rbp;\n                AddrFrame.Mode   = Flat;\n                AddrStack.Offset = ctxt.Rsp;\n                AddrStack.Mode   = Flat;\n            }\n        }\n\n        version (X86)         enum imageType = IMAGE_FILE_MACHINE_I386;\n        else version (X86_64) enum imageType = IMAGE_FILE_MACHINE_AMD64;\n        else                  static assert(0, \"unimplemented\");\n\n        ulong[] result;\n        size_t frameNum = 0;\n\n        // do ... while so that we don't skip the first stackframe\n        do\n        {\n            if ( stackframe.AddrPC.Offset == stackframe.AddrReturn.Offset )\n            {\n                debug(PRINTF) printf(\"Endless callstack\\n\");\n                break;\n            }\n            if (frameNum >= skip)\n            {\n                result ~= stackframe.AddrPC.Offset;\n            }\n            frameNum++;\n        }\n        while (dbghelp.StackWalk64(imageType, hProcess, hThread, &stackframe,\n                                   &ctxt, null, null, null, null));\n        return result;\n    }\n\n    static char[][] resolveNoSync(const(ulong)[] addresses)\n    {\n        auto dbghelp  = DbgHelp.get();\n        if (dbghelp is null)\n            return []; // dbghelp.dll not available\n\n        HANDLE hProcess = GetCurrentProcess();\n\n        static struct BufSymbol\n        {\n        align(1):\n            IMAGEHLP_SYMBOLA64 _base;\n            TCHAR[1024] _buf;\n        }\n        BufSymbol bufSymbol=void;\n        IMAGEHLP_SYMBOLA64* symbol = &bufSymbol._base;\n        symbol.SizeOfStruct = IMAGEHLP_SYMBOLA64.sizeof;\n        symbol.MaxNameLength = bufSymbol._buf.length;\n\n        char[][] trace;\n        foreach (pc; addresses)\n        {\n            if ( pc != 0 )\n            {\n                char[] res;\n                if (dbghelp.SymGetSymFromAddr64(hProcess, pc, null, symbol) &&\n                    *symbol.Name.ptr)\n                {\n                    DWORD disp;\n                    IMAGEHLP_LINEA64 line=void;\n                    line.SizeOfStruct = IMAGEHLP_LINEA64.sizeof;\n\n                    if (dbghelp.SymGetLineFromAddr64(hProcess, pc, &disp, &line))\n                        res = formatStackFrame(cast(void*)pc, symbol.Name.ptr,\n                                               line.FileName, line.LineNumber);\n                    else\n                        res = formatStackFrame(cast(void*)pc, symbol.Name.ptr);\n                }\n                else\n                    res = formatStackFrame(cast(void*)pc);\n                trace ~= res;\n            }\n        }\n        return trace;\n    }\n\n    static char[] formatStackFrame(void* pc)\n    {\n        import core.stdc.stdio : snprintf;\n        char[2+2*size_t.sizeof+1] buf=void;\n\n        immutable len = snprintf(buf.ptr, buf.length, \"0x%p\", pc);\n        cast(uint)len < buf.length || assert(0);\n        return buf[0 .. len].dup;\n    }\n\n    static char[] formatStackFrame(void* pc, char* symName)\n    {\n        char[2048] demangleBuf=void;\n\n        auto res = formatStackFrame(pc);\n        res ~= \" in \";\n        const(char)[] tempSymName = symName[0 .. strlen(symName)];\n        //Deal with dmd mangling of long names\n        version (CRuntime_DigitalMars)\n        {\n            size_t decodeIndex = 0;\n            tempSymName = decodeDmdString(tempSymName, decodeIndex);\n        }\n        res ~= demangle(tempSymName, demangleBuf);\n        return res;\n    }\n\n    static char[] formatStackFrame(void* pc, char* symName,\n                                   in char* fileName, uint lineNum)\n    {\n        import core.stdc.stdio : snprintf;\n        char[11] buf=void;\n\n        auto res = formatStackFrame(pc, symName);\n        res ~= \" at \";\n        res ~= fileName[0 .. strlen(fileName)];\n        res ~= \"(\";\n        immutable len = snprintf(buf.ptr, buf.length, \"%u\", lineNum);\n        cast(uint)len < buf.length || assert(0);\n        res ~= buf[0 .. len];\n        res ~= \")\";\n        return res;\n    }\n}\n\n\n// Workaround OPTLINK bug (Bugzilla 8263)\nextern(Windows) BOOL FixupDebugHeader(HANDLE hProcess, ULONG ActionCode,\n                                      ulong CallbackContext, ulong UserContext)\n{\n    if (ActionCode == CBA_READ_MEMORY)\n    {\n        auto p = cast(IMAGEHLP_CBA_READ_MEMORY*)CallbackContext;\n        if (!(p.addr & 0xFF) && p.bytes == 0x1C &&\n            // IMAGE_DEBUG_DIRECTORY.PointerToRawData\n            (*cast(DWORD*)(p.addr + 24) & 0xFF) == 0x20)\n        {\n            immutable base = DbgHelp.get().SymGetModuleBase64(hProcess, p.addr);\n            // IMAGE_DEBUG_DIRECTORY.AddressOfRawData\n            if (base + *cast(DWORD*)(p.addr + 20) == p.addr + 0x1C &&\n                *cast(DWORD*)(p.addr + 0x1C) == 0 &&\n                *cast(DWORD*)(p.addr + 0x20) == ('N'|'B'<<8|'0'<<16|'9'<<24))\n            {\n                debug(PRINTF) printf(\"fixup IMAGE_DEBUG_DIRECTORY.AddressOfRawData\\n\");\n                memcpy(p.buf, cast(void*)p.addr, 0x1C);\n                *cast(DWORD*)(p.buf + 20) = cast(DWORD)(p.addr - base) + 0x20;\n                *p.bytesread = 0x1C;\n                return TRUE;\n            }\n        }\n    }\n    return FALSE;\n}\n\nprivate string generateSearchPath()\n{\n    __gshared string[3] defaultPathList = [\"_NT_SYMBOL_PATH\",\n                                           \"_NT_ALTERNATE_SYMBOL_PATH\",\n                                           \"SYSTEMROOT\"];\n\n    string path;\n    char[2048] temp;\n    DWORD len;\n\n    foreach ( e; defaultPathList )\n    {\n        if ( (len = GetEnvironmentVariableA( e.ptr, temp.ptr, temp.length )) > 0 )\n        {\n            path ~= temp[0 .. len];\n            path ~= \";\";\n        }\n    }\n    path ~= \"\\0\";\n    return path;\n}\n\n\nshared static this()\n{\n    auto dbghelp = DbgHelp.get();\n\n    if ( dbghelp is null )\n        return; // dbghelp.dll not available\n\n    auto kernel32Handle = LoadLibraryA( \"kernel32.dll\" );\n    if (kernel32Handle !is null)\n    {\n        RtlCaptureStackBackTrace = cast(RtlCaptureStackBackTraceFunc) GetProcAddress(kernel32Handle, \"RtlCaptureStackBackTrace\");\n        debug(PRINTF)\n        {\n            if (RtlCaptureStackBackTrace !is null)\n                printf(\"Found RtlCaptureStackBackTrace\\n\");\n        }\n    }\n\n    debug(PRINTF)\n    {\n        API_VERSION* dbghelpVersion = dbghelp.ImagehlpApiVersion();\n        printf(\"DbgHelp Version %d.%d.%d\\n\", dbghelpVersion.MajorVersion, dbghelpVersion.MinorVersion, dbghelpVersion.Revision);\n    }\n\n    HANDLE hProcess = GetCurrentProcess();\n\n    DWORD symOptions = dbghelp.SymGetOptions();\n    symOptions |= SYMOPT_LOAD_LINES;\n    symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS;\n    symOptions |= SYMOPT_DEFERRED_LOAD;\n    symOptions  = dbghelp.SymSetOptions( symOptions );\n\n    debug(PRINTF) printf(\"Search paths: %s\\n\", generateSearchPath().ptr);\n\n    if (!dbghelp.SymInitialize(hProcess, generateSearchPath().ptr, TRUE))\n        return;\n\n    dbghelp.SymRegisterCallback64(hProcess, &FixupDebugHeader, 0);\n\n    initialized = true;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/stat.d",
    "content": "\n/// $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n/// Author: Walter Bright\n\nmodule core.sys.windows.stat;\nversion (Windows):\n\nextern (C) nothrow @nogc:\n\n// Posix version is in core.sys.posix.sys.stat\n\nenum S_IFMT   = 0xF000;\nenum S_IFDIR  = 0x4000;\nenum S_IFCHR  = 0x2000;\nenum S_IFIFO  = 0x1000;\nenum S_IFREG  = 0x8000;\nenum S_IREAD  = 0x0100;\nenum S_IWRITE = 0x0080;\nenum S_IEXEC  = 0x0040;\nenum S_IFBLK  = 0x6000;\nenum S_IFNAM  = 0x5000;\n\n@safe pure\n{\nint S_ISREG(int m)  { return (m & S_IFMT) == S_IFREG; }\nint S_ISBLK(int m)  { return (m & S_IFMT) == S_IFBLK; }\nint S_ISNAM(int m)  { return (m & S_IFMT) == S_IFNAM; }\nint S_ISDIR(int m)  { return (m & S_IFMT) == S_IFDIR; }\nint S_ISCHR(int m)  { return (m & S_IFMT) == S_IFCHR; }\n}\n\nstruct struct_stat\n{\n    short st_dev;\n    ushort st_ino;\n    ushort st_mode;\n    short st_nlink;\n    ushort st_uid;\n    ushort st_gid;\n    short st_rdev;\n    short dummy;\n    int st_size;\n    int st_atime;\n    int st_mtime;\n    int st_ctime;\n}\n\nint  stat(const(char)*, struct_stat *);\nint  fstat(int, struct_stat *) @trusted;\nint  _wstat(const(wchar)*, struct_stat *);\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/subauth.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_subauth.d)\n */\nmodule core.sys.windows.subauth;\nversion (Windows):\n\nprivate import core.sys.windows.ntdef, core.sys.windows.windef;\n\n/+\nalias LONG NTSTATUS;\nalias NTSTATUS* PNTSTATUS;\n+/\n\nenum : ULONG {\n    MSV1_0_PASSTHRU    = 1,\n    MSV1_0_GUEST_LOGON = 2\n}\n\n// USER_ALL_INFORMATION.WhichFields (Undocumented)\nenum ULONG\n    MSV1_0_VALIDATION_LOGOFF_TIME  = 1,\n    MSV1_0_VALIDATION_KICKOFF_TIME = 2,\n    MSV1_0_VALIDATION_LOGON_SERVER = 4,\n    MSV1_0_VALIDATION_LOGON_DOMAIN = 8,\n    MSV1_0_VALIDATION_SESSION_KEY  = 16,\n    MSV1_0_VALIDATION_USER_FLAGS   = 32,\n    MSV1_0_VALIDATION_USER_ID      = 64;\n\n// ?ActionsPerformed? (Undocumented)\nenum MSV1_0_SUBAUTH_ACCOUNT_DISABLED = 1;\nenum MSV1_0_SUBAUTH_PASSWORD         = 2;\nenum MSV1_0_SUBAUTH_WORKSTATIONS = 4;\nenum MSV1_0_SUBAUTH_LOGON_HOURS = 8;\nenum MSV1_0_SUBAUTH_ACCOUNT_EXPIRY = 16;\nenum MSV1_0_SUBAUTH_PASSWORD_EXPIRY = 32;\nenum MSV1_0_SUBAUTH_ACCOUNT_TYPE = 64;\nenum MSV1_0_SUBAUTH_LOCKOUT = 128;\n\nenum NEXT_FREE_ACCOUNT_CONTROL_BIT = 131072;\n\nenum SAM_DAYS_PER_WEEK    = 7;\nenum SAM_HOURS_PER_WEEK   = 168;\nenum SAM_MINUTES_PER_WEEK = 10080;\n\nenum : NTSTATUS {\n    STATUS_SUCCESS                = 0,\n    STATUS_INVALID_INFO_CLASS     = 0xC0000003,\n    STATUS_NO_SUCH_USER           = 0xC0000064,\n    STATUS_WRONG_PASSWORD         = 0xC000006A,\n    STATUS_PASSWORD_RESTRICTION   = 0xC000006C,\n    STATUS_LOGON_FAILURE          = 0xC000006D,\n    STATUS_ACCOUNT_RESTRICTION    = 0xC000006E,\n    STATUS_INVALID_LOGON_HOURS    = 0xC000006F,\n    STATUS_INVALID_WORKSTATION    = 0xC0000070,\n    STATUS_PASSWORD_EXPIRED       = 0xC0000071,\n    STATUS_ACCOUNT_DISABLED       = 0xC0000072,\n    STATUS_INSUFFICIENT_RESOURCES = 0xC000009A,\n    STATUS_ACCOUNT_EXPIRED        = 0xC0000193,\n    STATUS_PASSWORD_MUST_CHANGE   = 0xC0000224,\n    STATUS_ACCOUNT_LOCKED_OUT     = 0xC0000234\n}\n\n// Note: undocumented in MSDN\n// USER_ALL_INFORMATION.UserAccountControl\nenum ULONG\n    USER_ACCOUNT_DISABLED                = 1,\n    USER_HOME_DIRECTORY_REQUIRED         = 2,\n    USER_PASSWORD_NOT_REQUIRED           = 4,\n    USER_TEMP_DUPLICATE_ACCOUNT          = 8,\n    USER_NORMAL_ACCOUNT                  = 16,\n    USER_MNS_LOGON_ACCOUNT               = 32,\n    USER_INTERDOMAIN_TRUST_ACCOUNT       = 64,\n    USER_WORKSTATION_TRUST_ACCOUNT       = 128,\n    USER_SERVER_TRUST_ACCOUNT            = 256,\n    USER_DONT_EXPIRE_PASSWORD            = 512,\n    USER_ACCOUNT_AUTO_LOCKED             = 1024,\n    USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 2048,\n    USER_SMARTCARD_REQUIRED              = 4096,\n    USER_TRUSTED_FOR_DELEGATION          = 8192,\n    USER_NOT_DELEGATED                   = 16384,\n    USER_USE_DES_KEY_ONLY                = 32768,\n    USER_DONT_REQUIRE_PREAUTH            = 65536,\n\n    USER_MACHINE_ACCOUNT_MASK            = 448,\n    USER_ACCOUNT_TYPE_MASK               = 472,\n    USER_ALL_PARAMETERS                  = 2097152;\n\n/+\nstruct UNICODE_STRING {\n    USHORT Length;\n    USHORT MaximumLength;\n    PWSTR Buffer;\n}\nalias UNICODE_STRING* PUNICODE_STRING;\n\nstruct STRING {\n    USHORT Length;\n    USHORT MaximumLength;\n    PCHAR Buffer;\n}\nalias STRING* PSTRING;\n+/\n\nmixin DECLARE_HANDLE!(\"SAM_HANDLE\");\nalias SAM_HANDLE* PSAM_HANDLE;\n\nstruct OLD_LARGE_INTEGER {\n    ULONG LowPart;\n    LONG HighPart;\n}\nalias OLD_LARGE_INTEGER* POLD_LARGE_INTEGER;\n\nenum NETLOGON_LOGON_INFO_CLASS {\n    NetlogonInteractiveInformation = 1,\n    NetlogonNetworkInformation,\n    NetlogonServiceInformation,\n    NetlogonGenericInformation,\n    NetlogonInteractiveTransitiveInformation,\n    NetlogonNetworkTransitiveInformation,\n    NetlogonServiceTransitiveInformation\n}\n\n\nenum CYPHER_BLOCK_LENGTH = 8;\nenum USER_SESSION_KEY_LENGTH = CYPHER_BLOCK_LENGTH * 2;\nenum CLEAR_BLOCK_LENGTH = 8;\n\nstruct CYPHER_BLOCK {\n    CHAR[CYPHER_BLOCK_LENGTH] data;\n}\nalias CYPHER_BLOCK* PCYPHER_BLOCK;\n\nstruct CLEAR_BLOCK {\n    CHAR[CLEAR_BLOCK_LENGTH] data;\n}\nalias CLEAR_BLOCK* PCLEAR_BLOCK;\n\nstruct LM_OWF_PASSWORD {\n    CYPHER_BLOCK[2] data;\n}\nalias LM_OWF_PASSWORD* PLM_OWF_PASSWORD;\n\nstruct USER_SESSION_KEY {\n    CYPHER_BLOCK[2] data;\n}\nalias USER_SESSION_KEY* PUSER_SESSION_KEY;\n\nalias CLEAR_BLOCK LM_CHALLENGE;\nalias LM_CHALLENGE* PLM_CHALLENGE;\n\nalias LM_OWF_PASSWORD NT_OWF_PASSWORD;\nalias NT_OWF_PASSWORD* PNT_OWF_PASSWORD;\nalias LM_CHALLENGE NT_CHALLENGE;\nalias NT_CHALLENGE* PNT_CHALLENGE;\n\nstruct LOGON_HOURS {\n    USHORT UnitsPerWeek;\n    PUCHAR LogonHours;\n}\nalias LOGON_HOURS* PLOGON_HOURS;\n\nstruct SR_SECURITY_DESCRIPTOR {\n    ULONG Length;\n    PUCHAR SecurityDescriptor;\n}\nalias SR_SECURITY_DESCRIPTOR* PSR_SECURITY_DESCRIPTOR;\n\nalign(4):\nstruct USER_ALL_INFORMATION {\n    LARGE_INTEGER LastLogon;\n    LARGE_INTEGER LastLogoff;\n    LARGE_INTEGER PasswordLastSet;\n    LARGE_INTEGER AccountExpires;\n    LARGE_INTEGER PasswordCanChange;\n    LARGE_INTEGER PasswordMustChange;\n    UNICODE_STRING UserName;\n    UNICODE_STRING FullName;\n    UNICODE_STRING HomeDirectory;\n    UNICODE_STRING HomeDirectoryDrive;\n    UNICODE_STRING ScriptPath;\n    UNICODE_STRING ProfilePath;\n    UNICODE_STRING AdminComment;\n    UNICODE_STRING WorkStations;\n    UNICODE_STRING UserComment;\n    UNICODE_STRING Parameters;\n    UNICODE_STRING LmPassword;\n    UNICODE_STRING NtPassword;\n    UNICODE_STRING PrivateData;\n    SR_SECURITY_DESCRIPTOR SecurityDescriptor;\n    ULONG UserId;\n    ULONG PrimaryGroupId;\n    ULONG UserAccountControl;\n    ULONG WhichFields;\n    LOGON_HOURS LogonHours;\n    USHORT BadPasswordCount;\n    USHORT LogonCount;\n    USHORT CountryCode;\n    USHORT CodePage;\n    BOOLEAN LmPasswordPresent;\n    BOOLEAN NtPasswordPresent;\n    BOOLEAN PasswordExpired;\n    BOOLEAN PrivateDataSensitive;\n}\nalias USER_ALL_INFORMATION* PUSER_ALL_INFORMATION;\nalign:\n\nstruct MSV1_0_VALIDATION_INFO {\n    LARGE_INTEGER LogoffTime;\n    LARGE_INTEGER KickoffTime;\n    UNICODE_STRING LogonServer;\n    UNICODE_STRING LogonDomainName;\n    USER_SESSION_KEY SessionKey;\n    BOOLEAN Authoritative;\n    ULONG UserFlags;\n    ULONG WhichFields;\n    ULONG UserId;\n}\nalias MSV1_0_VALIDATION_INFO* PMSV1_0_VALIDATION_INFO;\n\nstruct NETLOGON_LOGON_IDENTITY_INFO {\n    UNICODE_STRING LogonDomainName;\n    ULONG ParameterControl;\n    OLD_LARGE_INTEGER LogonId;\n    UNICODE_STRING UserName;\n    UNICODE_STRING Workstation;\n}\nalias NETLOGON_LOGON_IDENTITY_INFO* PNETLOGON_LOGON_IDENTITY_INFO;\n\nstruct NETLOGON_INTERACTIVE_INFO {\n    NETLOGON_LOGON_IDENTITY_INFO Identity;\n    LM_OWF_PASSWORD LmOwfPassword;\n    NT_OWF_PASSWORD NtOwfPassword;\n}\nalias NETLOGON_INTERACTIVE_INFO* PNETLOGON_INTERACTIVE_INFO;\n\nstruct NETLOGON_GENERIC_INFO {\n    NETLOGON_LOGON_IDENTITY_INFO Identity;\n    UNICODE_STRING PackageName;\n    ULONG DataLength;\n    PUCHAR LogonData;\n}\nalias NETLOGON_GENERIC_INFO* PNETLOGON_GENERIC_INFO;\n\nstruct NETLOGON_NETWORK_INFO {\n    NETLOGON_LOGON_IDENTITY_INFO Identity;\n    LM_CHALLENGE LmChallenge;\n    STRING NtChallengeResponse;\n    STRING LmChallengeResponse;\n}\nalias NETLOGON_NETWORK_INFO* PNETLOGON_NETWORK_INFO;\n\nstruct NETLOGON_SERVICE_INFO {\n    NETLOGON_LOGON_IDENTITY_INFO Identity;\n    LM_OWF_PASSWORD LmOwfPassword;\n    NT_OWF_PASSWORD NtOwfPassword;\n}\nalias NETLOGON_SERVICE_INFO* PNETLOGON_SERVICE_INFO;\n\nextern (Windows) {\nNTSTATUS Msv1_0SubAuthenticationRoutine(NETLOGON_LOGON_INFO_CLASS,PVOID,\n    ULONG,PUSER_ALL_INFORMATION,PULONG,PULONG,\n    PBOOLEAN,PLARGE_INTEGER,PLARGE_INTEGER);\nNTSTATUS Msv1_0SubAuthenticationFilter(NETLOGON_LOGON_INFO_CLASS,PVOID,\n    ULONG,PUSER_ALL_INFORMATION,PULONG,PULONG,\n    PBOOLEAN,PLARGE_INTEGER,PLARGE_INTEGER);\nNTSTATUS Msv1_0SubAuthenticationRoutineGeneric(PVOID,ULONG,PULONG,PVOID*);\nNTSTATUS Msv1_0SubAuthenticationRoutineEx(NETLOGON_LOGON_INFO_CLASS,PVOID,\n    ULONG,PUSER_ALL_INFORMATION,SAM_HANDLE,\n    PMSV1_0_VALIDATION_INFO,PULONG);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/threadaux.d",
    "content": "/**\n * This module provides OS specific helper function for threads support\n *\n * Copyright: Copyright Digital Mars 2010 - 2010.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Source:    $(DRUNTIMESRC core/sys/windows/_threadaux.d)\n * Authors:   Rainer Schuetze\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule core.sys.windows.threadaux;\nversion (Windows):\n\nimport core.sys.windows.windows;\nimport core.stdc.stdlib;\n\npublic import core.thread;\n\nextern(Windows)\nHANDLE OpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId) nothrow;\n\nextern (C) extern __gshared int _tls_index;\n\nextern (C) // rt.minfo\n{\n    void rt_moduleTlsCtor();\n    void rt_moduleTlsDtor();\n}\n\nprivate:\n///////////////////////////////////////////////////////////////////\nstruct thread_aux\n{\n    // don't let symbols leak into other modules\n\n    enum SystemProcessInformation = 5;\n    enum STATUS_INFO_LENGTH_MISMATCH = 0xc0000004;\n\n    // structs subject to change according to MSDN, more info at http://undocumented.ntinternals.net\n    // declarations according to http://processhacker.sourceforge.net/doc/ntexapi_8h_source.html\n    // NOTE: the declarations assume default alignment for Win64 and contain some padding data\n    struct UNICODE_STRING\n    {\n        short Length;\n        short MaximumLength;\n        wchar* Buffer;\n    }\n    // process or thread ID, documentation says it is a HANDLE, but it's actually the ID (a DWORD)\n    alias size_t PTID;\n\n    struct _SYSTEM_PROCESS_INFORMATION\n    {\n        int     NextEntryOffset; // When this entry is 0, there are no more processes to be read.\n        int     NumberOfThreads;\n        long    WorkingSetPrivateSize;\n        uint    HardFaultCount;\n        uint    NumberOfThreadsHighWatermark;\n        ulong   CycleTime;\n        long    CreateTime;\n        long    UserTime;\n        long    KernelTime;\n        UNICODE_STRING      ImageName;\n        int     BasePriority;\n        PTID    /*Unique*/ProcessId;\n        PTID    InheritedFromUniqueProcessId;\n        uint    HandleCount;\n        uint    SessionId;\n        size_t  UniqueProcessKey;\n        size_t  PeakVirtualSize;\n        size_t  VirtualSize;\n        uint    PageFaultCount;\n        size_t  PeakWorkingSetSize;\n        size_t  WorkingSetSize;\n        size_t  QuotaPeakPagedPoolUsage;\n        size_t  QuotaPagedPoolUsage;\n        size_t  QuotaPeakNonPagedPoolUsage;\n        size_t  QuotaNonPagedPoolUsage;\n        size_t  PagefileUsage;\n        size_t  PeakPagefileUsage;\n        size_t  PrivatePageCount;\n        long    ReadOperationCount;\n        long    WriteOperationCount;\n        long    OtherOperationCount;\n        long    ReadTransferCount;\n        long    WriteTransferCount;\n        long    OtherTransferCount;\n\n        // SYSTEM_THREAD_INFORMATION or SYSTEM_EXTENDED_THREAD_INFORMATION structures follow.\n    }\n\n    struct _SYSTEM_THREAD_INFORMATION\n    {\n        long    KernelTime;\n        long    UserTime;\n        long    CreateTime;\n        uint    WaitTime;\n        void*   StartAddress;\n        PTID    ProcessId;\n        PTID    ThreadId;\n        int     Priority;\n        int     BasePriority;\n        uint    ContextSwitches;\n        uint    ThreadState;\n        int     WaitReason;\n        int     reserved;\n    }\n\n    alias fnNtQuerySystemInformation = extern(Windows)\n    HRESULT function( uint SystemInformationClass, void* info, uint infoLength, uint* ReturnLength ) nothrow;\n\n    enum ThreadBasicInformation = 0;\n\n    struct THREAD_BASIC_INFORMATION\n    {\n        int    ExitStatus;\n        void** TebBaseAddress;\n        PTID   ProcessId;\n        PTID   ThreadId;\n        size_t AffinityMask;\n        int    Priority;\n        int    BasePriority;\n    }\n\n    alias fnNtQueryInformationThread = extern(Windows)\n    int function( HANDLE ThreadHandle, uint ThreadInformationClass, void* buf, uint size, uint* ReturnLength ) nothrow;\n\n    enum SYNCHRONIZE = 0x00100000;\n    enum THREAD_GET_CONTEXT = 8;\n    enum THREAD_QUERY_INFORMATION = 0x40;\n    enum THREAD_SUSPEND_RESUME = 2;\n\n    ///////////////////////////////////////////////////////////////////\n    // get the thread environment block (TEB) of the thread with the given handle\n    static void** getTEB( HANDLE hnd ) nothrow\n    {\n        HANDLE nthnd = GetModuleHandleA( \"NTDLL\" );\n        assert( nthnd, \"cannot get module handle for ntdll\" );\n        fnNtQueryInformationThread fn = cast(fnNtQueryInformationThread) GetProcAddress( nthnd, \"NtQueryInformationThread\" );\n        assert( fn, \"cannot find NtQueryInformationThread in ntdll\" );\n\n        THREAD_BASIC_INFORMATION tbi;\n        int Status = (*fn)(hnd, ThreadBasicInformation, &tbi, tbi.sizeof, null);\n        assert(Status == 0);\n\n        return tbi.TebBaseAddress;\n    }\n\n    // get the thread environment block (TEB) of the thread with the given identifier\n    static void** getTEB( uint id ) nothrow\n    {\n        HANDLE hnd = OpenThread( THREAD_QUERY_INFORMATION, FALSE, id );\n        assert( hnd, \"OpenThread failed\" );\n\n        void** teb = getTEB( hnd );\n        CloseHandle( hnd );\n        return teb;\n    }\n\n    // get linear address of TEB of current thread\n    static void** getTEB() nothrow\n    {\n        version (Win32)\n        {\n            version (GNU_InlineAsm)\n            {\n                void** teb;\n                asm pure nothrow @nogc { \"movl %%fs:0x18, %0;\" : \"=r\" teb; }\n                return teb;\n            }\n            else\n            {\n                asm pure nothrow @nogc\n                {\n                    naked;\n                    mov EAX,FS:[0x18];\n                    ret;\n                }\n            }\n        }\n        else version (Win64)\n        {\n            version (GNU_InlineAsm)\n            {\n                void** teb;\n                asm pure nothrow @nogc { \"movq %%gs:0x30, %0;\" : \"=r\" teb; }\n                return teb;\n            }\n            else\n            {\n                asm pure nothrow @nogc\n                {\n                    naked;\n                    mov RAX,0x30;\n                    mov RAX,GS:[RAX]; // immediate value causes fixup\n                    ret;\n                }\n            }\n        }\n        else\n        {\n            static assert(false);\n        }\n    }\n\n    // get the stack bottom (the top address) of the thread with the given handle\n    static void* getThreadStackBottom( HANDLE hnd ) nothrow\n    {\n        void** teb = getTEB( hnd );\n        return teb[1];\n    }\n\n    // get the stack bottom (the top address) of the thread with the given identifier\n    static void* getThreadStackBottom( uint id ) nothrow\n    {\n        void** teb = getTEB( id );\n        return teb[1];\n    }\n\n    // create a thread handle with full access to the thread with the given identifier\n    static HANDLE OpenThreadHandle( uint id ) nothrow\n    {\n        return OpenThread( SYNCHRONIZE|THREAD_GET_CONTEXT|THREAD_QUERY_INFORMATION|THREAD_SUSPEND_RESUME, FALSE, id );\n    }\n\n    ///////////////////////////////////////////////////////////////////\n    // enumerate threads of the given process calling the passed function on each thread\n    // using function instead of delegate here to avoid allocating closure\n    static bool enumProcessThreads( uint procid, bool function( uint id, void* context ) dg, void* context )\n    {\n        HANDLE hnd = GetModuleHandleA( \"NTDLL\" );\n        fnNtQuerySystemInformation fn = cast(fnNtQuerySystemInformation) GetProcAddress( hnd, \"NtQuerySystemInformation\" );\n        if ( !fn )\n            return false;\n\n        uint sz = 16384;\n        uint retLength;\n        HRESULT rc;\n        char* buf;\n        for ( ; ; )\n        {\n            buf = cast(char*) core.stdc.stdlib.malloc(sz);\n            if (!buf)\n                return false;\n            rc = fn( SystemProcessInformation, buf, sz, &retLength );\n            if ( rc != STATUS_INFO_LENGTH_MISMATCH )\n                break;\n            core.stdc.stdlib.free( buf );\n            sz *= 2;\n        }\n        scope(exit) core.stdc.stdlib.free( buf );\n\n        if (rc != 0)\n            return false;\n\n        auto pinfo = cast(_SYSTEM_PROCESS_INFORMATION*) buf;\n        auto pend  = cast(_SYSTEM_PROCESS_INFORMATION*) (buf + retLength);\n        for ( ; pinfo < pend; )\n        {\n            if ( pinfo.ProcessId == procid )\n            {\n                auto tinfo = cast(_SYSTEM_THREAD_INFORMATION*)(pinfo + 1);\n                for ( int i = 0; i < pinfo.NumberOfThreads; i++, tinfo++ )\n                    if ( tinfo.ProcessId == procid )\n                        if ( !dg( cast(uint) tinfo.ThreadId, context ) ) // IDs are actually DWORDs\n                            return false;\n            }\n            if ( pinfo.NextEntryOffset == 0 )\n                break;\n            pinfo = cast(_SYSTEM_PROCESS_INFORMATION*) (cast(char*) pinfo + pinfo.NextEntryOffset);\n        }\n        return true;\n    }\n\n    static bool enumProcessThreads( bool function( uint id, void* context ) dg, void* context )\n    {\n        return enumProcessThreads( GetCurrentProcessId(), dg, context );\n    }\n\n    // execute function on the TLS for the given thread\n    alias extern(C) void function() externCVoidFunc;\n    static void impersonate_thread( uint id, externCVoidFunc fn )\n    {\n        impersonate_thread(id, () => fn());\n    }\n\n    static void impersonate_thread( uint id, scope void delegate() dg)\n    {\n        if ( id == GetCurrentThreadId() )\n        {\n            dg();\n            return;\n        }\n\n        // temporarily set current TLS array pointer to the array pointer of the referenced thread\n        void** curteb = getTEB();\n        void** teb    = getTEB( id );\n        assert( teb && curteb );\n\n        void** curtlsarray = cast(void**) curteb[11];\n        void** tlsarray    = cast(void**) teb[11];\n        if ( !curtlsarray || !tlsarray )\n            return;\n\n        curteb[11] = tlsarray;\n\n        // swap out the TLS slots aswell\n        version (Win64)\n        {\n            enum TEB_offset_TlsSlots = 0x1480;\n            enum TEB_offset_TlsExpansionSlots = 0x1780;\n        }\n        else\n        {\n            enum TEB_offset_TlsSlots = 0xE10;\n            enum TEB_offset_TlsExpansionSlots = 0xF94;\n        }\n        void* tlsSlotsAdr(void** teb) { return cast(void*) teb + TEB_offset_TlsSlots; }\n        ref void* tlsExpansionSlots(void** teb) { return *cast(void**)(cast(void*) teb + TEB_offset_TlsExpansionSlots); }\n\n        import core.stdc.string;\n        void*[64] slots = void;\n        memcpy(slots.ptr, tlsSlotsAdr(curteb), slots.sizeof);\n        void* extraSlots = tlsExpansionSlots(curteb);\n\n        memcpy(tlsSlotsAdr(curteb), tlsSlotsAdr(teb), slots.sizeof);\n        tlsExpansionSlots(curteb) = tlsExpansionSlots(teb);\n\n        dg();\n\n        curteb[11] = curtlsarray;\n\n        // copy the TLS slots back in case they have been changed in dg\n        memcpy(tlsSlotsAdr(teb), tlsSlotsAdr(curteb), slots.sizeof);\n        tlsExpansionSlots(teb) = tlsExpansionSlots(curteb);\n\n        memcpy(tlsSlotsAdr(curteb), slots.ptr, slots.sizeof);\n        tlsExpansionSlots(curteb) = extraSlots;\n    }\n}\n\npublic:\n// forward as few symbols as possible into the \"global\" name space\nalias thread_aux.getTEB getTEB;\nalias thread_aux.getThreadStackBottom getThreadStackBottom;\nalias thread_aux.OpenThreadHandle OpenThreadHandle;\nalias thread_aux.enumProcessThreads enumProcessThreads;\nalias thread_aux.impersonate_thread impersonate_thread;\n\n// get the start of the TLS memory of the thread with the given handle\nvoid* GetTlsDataAddress( HANDLE hnd ) nothrow\n{\n    if ( void** teb = getTEB( hnd ) )\n        if ( void** tlsarray = cast(void**) teb[11] )\n            return tlsarray[_tls_index];\n    return null;\n}\n\n// get the start of the TLS memory of the thread with the given identifier\nvoid* GetTlsDataAddress( uint id ) nothrow\n{\n    HANDLE hnd = OpenThread( thread_aux.THREAD_QUERY_INFORMATION, FALSE, id );\n    assert( hnd, \"OpenThread failed\" );\n\n    void* tls = GetTlsDataAddress( hnd );\n    CloseHandle( hnd );\n    return tls;\n}\n\n///////////////////////////////////////////////////////////////////\n// run rt_moduleTlsCtor in the context of the given thread\nvoid thread_moduleTlsCtor( uint id )\n{\n    thread_aux.impersonate_thread(id, &rt_moduleTlsCtor);\n}\n\n///////////////////////////////////////////////////////////////////\n// run rt_moduleTlsDtor in the context of the given thread\nvoid thread_moduleTlsDtor( uint id )\n{\n    thread_aux.impersonate_thread(id, &rt_moduleTlsDtor);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/tlhelp32.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_tlhelp32.d)\n */\nmodule core.sys.windows.tlhelp32;\nversion (Windows):\npragma(lib, \"kernel32\");\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.windef;\n\nenum : uint {\n    HF32_DEFAULT = 1,\n    HF32_SHARED\n}\n\nenum : uint {\n    LF32_FIXED    = 0x1,\n    LF32_FREE     = 0x2,\n    LF32_MOVEABLE = 0x4\n}\n\nenum MAX_MODULE_NAME32 = 255;\n\nenum : uint {\n    TH32CS_SNAPHEAPLIST = 0x1,\n    TH32CS_SNAPPROCESS  = 0x2,\n    TH32CS_SNAPTHREAD   = 0x4,\n    TH32CS_SNAPMODULE   = 0x8,\n    TH32CS_SNAPALL      = (TH32CS_SNAPHEAPLIST|TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD|TH32CS_SNAPMODULE),\n    TH32CS_INHERIT      = 0x80000000\n}\n\nstruct HEAPLIST32 {\n    SIZE_T dwSize;\n    DWORD th32ProcessID;\n    ULONG_PTR th32HeapID;\n    DWORD dwFlags;\n}\nalias HEAPLIST32* PHEAPLIST32;\nalias HEAPLIST32* LPHEAPLIST32;\n\nstruct HEAPENTRY32 {\n    SIZE_T dwSize;\n    HANDLE hHandle;\n    ULONG_PTR dwAddress;\n    SIZE_T dwBlockSize;\n    DWORD dwFlags;\n    DWORD dwLockCount;\n    DWORD dwResvd;\n    DWORD th32ProcessID;\n    ULONG_PTR th32HeapID;\n}\nalias HEAPENTRY32* PHEAPENTRY32;\nalias HEAPENTRY32* LPHEAPENTRY32;\n\nstruct PROCESSENTRY32W {\n    DWORD dwSize;\n    DWORD cntUsage;\n    DWORD th32ProcessID;\n    ULONG_PTR th32DefaultHeapID;\n    DWORD th32ModuleID;\n    DWORD cntThreads;\n    DWORD th32ParentProcessID;\n    LONG pcPriClassBase;\n    DWORD dwFlags;\n    WCHAR[MAX_PATH] szExeFile;\n}\nalias PROCESSENTRY32W* PPROCESSENTRY32W;\nalias PROCESSENTRY32W* LPPROCESSENTRY32W;\n\nstruct THREADENTRY32 {\n    DWORD dwSize;\n    DWORD cntUsage;\n    DWORD th32ThreadID;\n    DWORD th32OwnerProcessID;\n    LONG tpBasePri;\n    LONG tpDeltaPri;\n    DWORD dwFlags;\n}\nalias THREADENTRY32* PTHREADENTRY32;\nalias THREADENTRY32* LPTHREADENTRY32;\n\nstruct MODULEENTRY32W {\n    DWORD dwSize;\n    DWORD th32ModuleID;\n    DWORD th32ProcessID;\n    DWORD GlblcntUsage;\n    DWORD ProccntUsage;\n    BYTE *modBaseAddr;\n    DWORD modBaseSize;\n    HMODULE hModule;\n    WCHAR[MAX_MODULE_NAME32 + 1] szModule;\n    WCHAR[MAX_PATH] szExePath;\n}\nalias MODULEENTRY32W* PMODULEENTRY32W;\nalias MODULEENTRY32W* LPMODULEENTRY32W;\n\nversion (Unicode) {\n    alias PROCESSENTRY32W PROCESSENTRY32;\n    alias PPROCESSENTRY32W PPROCESSENTRY32;\n    alias LPPROCESSENTRY32W LPPROCESSENTRY32;\n\n    alias MODULEENTRY32W MODULEENTRY32;\n    alias PMODULEENTRY32W PMODULEENTRY32;\n    alias LPMODULEENTRY32W LPMODULEENTRY32;\n} else {\n    struct PROCESSENTRY32 {\n        DWORD dwSize;\n        DWORD cntUsage;\n        DWORD th32ProcessID;\n        ULONG_PTR th32DefaultHeapID;\n        DWORD th32ModuleID;\n        DWORD cntThreads;\n        DWORD th32ParentProcessID;\n        LONG pcPriClassBase;\n        DWORD dwFlags;\n        CHAR[MAX_PATH] szExeFile;\n    }\n    alias PROCESSENTRY32* PPROCESSENTRY32;\n    alias PROCESSENTRY32* LPPROCESSENTRY32;\n\n    struct MODULEENTRY32 {\n        DWORD dwSize;\n        DWORD th32ModuleID;\n        DWORD th32ProcessID;\n        DWORD GlblcntUsage;\n        DWORD ProccntUsage;\n        BYTE *modBaseAddr;\n        DWORD modBaseSize;\n        HMODULE hModule;\n        char[MAX_MODULE_NAME32 + 1] szModule;\n        char[MAX_PATH] szExePath;\n    }\n    alias MODULEENTRY32* PMODULEENTRY32;\n    alias MODULEENTRY32* LPMODULEENTRY32;\n}\n\n\nextern(Windows) nothrow @nogc {\n    BOOL Heap32First(LPHEAPENTRY32,DWORD,ULONG_PTR);\n    BOOL Heap32ListFirst(HANDLE,LPHEAPLIST32);\n    BOOL Heap32ListNext(HANDLE,LPHEAPLIST32);\n    BOOL Heap32Next(LPHEAPENTRY32);\n    BOOL Thread32First(HANDLE,LPTHREADENTRY32);\n    BOOL Thread32Next(HANDLE,LPTHREADENTRY32);\n    BOOL Toolhelp32ReadProcessMemory(DWORD,LPCVOID,LPVOID,SIZE_T,SIZE_T*);\n    HANDLE CreateToolhelp32Snapshot(DWORD,DWORD);\n    BOOL Module32FirstW(HANDLE,LPMODULEENTRY32W);\n    BOOL Module32NextW(HANDLE,LPMODULEENTRY32W);\n    BOOL Process32FirstW(HANDLE,LPPROCESSENTRY32W);\n    BOOL Process32NextW(HANDLE,LPPROCESSENTRY32W);\n}\n\nversion (Unicode) {\n    alias Module32FirstW Module32First;\n    alias Module32NextW Module32Next;\n    alias Process32FirstW Process32First;\n    alias Process32NextW Process32Next;\n} else {\n    extern(Windows) nothrow @nogc {\n        BOOL Module32First(HANDLE,LPMODULEENTRY32);\n        BOOL Module32Next(HANDLE,LPMODULEENTRY32);\n        BOOL Process32First(HANDLE,LPPROCESSENTRY32);\n        BOOL Process32Next(HANDLE,LPPROCESSENTRY32);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/tmschema.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_tmschema.d)\n */\nmodule core.sys.windows.tmschema;\nversion (Windows):\n\n/* BUTTON parts */\nenum {\n    BP_PUSHBUTTON = 1,\n    BP_RADIOBUTTON = 2,\n    BP_CHECKBOX = 3,\n    BP_GROUPBOX = 4,\n    BP_USERBUTTON = 5\n}\n\nenum {\n    CBS_UNCHECKEDNORMAL = 1,\n    CBS_UNCHECKEDHOT = 2,\n    CBS_UNCHECKEDPRESSED = 3,\n    CBS_UNCHECKEDDISABLED = 4,\n    CBS_CHECKEDNORMAL = 5,\n    CBS_CHECKEDHOT = 6,\n    CBS_CHECKEDPRESSED = 7,\n    CBS_CHECKEDDISABLED = 8,\n    CBS_MIXEDNORMAL = 9,\n    CBS_MIXEDHOT = 10,\n    CBS_MIXEDPRESSED = 11,\n    CBS_MIXEDDISABLED = 12\n}\n\nenum {\n    GBS_NORMAL = 1,\n    GBS_DISABLED = 2\n}\n\nenum {\n    PBS_NORMAL = 1,\n    PBS_HOT = 2,\n    PBS_PRESSED = 3,\n    PBS_DISABLED = 4,\n    PBS_DEFAULTED = 5\n}\n\nenum {\n    RBS_UNCHECKEDNORMAL = 1,\n    RBS_UNCHECKEDHOT = 2,\n    RBS_UNCHECKEDPRESSED = 3,\n    RBS_UNCHECKEDDISABLED = 4,\n    RBS_CHECKEDNORMAL = 5,\n    RBS_CHECKEDHOT = 6,\n    RBS_CHECKEDPRESSED = 7,\n    RBS_CHECKEDDISABLED = 8\n}\n\n/* CLOCK parts */\nenum {\n    CLP_TIME = 1\n}\n\nenum {\n    CLS_NORMAL = 1\n}\n\n/* COMBOBOX parts */\nenum {\n    CP_DROPDOWNBUTTON = 1\n}\n\nenum {\n    CBXS_NORMAL = 1,\n    CBXS_HOT = 2,\n    CBXS_PRESSED = 3,\n    CBXS_DISABLED = 4\n}\n\n/* EDIT parts */\nenum {\n    EP_EDITTEXT = 1,\n    EP_CARET = 2\n}\n\nenum {\n    ETS_NORMAL = 1,\n    ETS_HOT = 2,\n    ETS_SELECTED = 3,\n    ETS_DISABLED = 4,\n    ETS_FOCUSED = 5,\n    ETS_READONLY = 6,\n    ETS_ASSIST = 7\n}\n/* EXPLORERBAR parts */\nenum {\n    EBP_HEADERBACKGROUND = 1,\n    EBP_HEADERCLOSE = 2,\n    EBP_HEADERPIN = 3,\n    EBP_IEBARMENU = 4,\n    EBP_NORMALGROUPBACKGROUND = 5,\n    EBP_NORMALGROUPCOLLAPSE = 6,\n    EBP_NORMALGROUPEXPAND = 7,\n    EBP_NORMALGROUPHEAD = 8,\n    EBP_SPECIALGROUPBACKGROUND = 9,\n    EBP_SPECIALGROUPCOLLAPSE = 10,\n    EBP_SPECIALGROUPEXPAND = 11,\n    EBP_SPECIALGROUPHEAD = 12\n}\n\nenum {\n    EBHC_NORMAL = 1,\n    EBHC_HOT = 2,\n    EBHC_PRESSED = 3\n}\n\nenum {\n    EBHP_NORMAL = 1,\n    EBHP_HOT = 2,\n    EBHP_PRESSED = 3,\n    EBHP_SELECTEDNORMAL = 4,\n    EBHP_SELECTEDHOT = 5,\n    EBHP_SELECTEDPRESSED = 6\n}\n\nenum {\n    EBM_NORMAL = 1,\n    EBM_HOT = 2,\n    EBM_PRESSED = 3\n}\n\nenum {\n    EBNGC_NORMAL = 1,\n    EBNGC_HOT = 2,\n    EBNGC_PRESSED = 3\n}\n\nenum {\n    EBNGE_NORMAL = 1,\n    EBNGE_HOT = 2,\n    EBNGE_PRESSED = 3\n}\n\nenum {\n    EBSGC_NORMAL = 1,\n    EBSGC_HOT = 2,\n    EBSGC_PRESSED = 3\n}\n\nenum {\n    EBSGE_NORMAL = 1,\n    EBSGE_HOT = 2,\n    EBSGE_PRESSED = 3\n}\n\n/* HEADER parts */\nenum {\n    HP_HEADERITEM = 1,\n    HP_HEADERITEMLEFT = 2,\n    HP_HEADERITEMRIGHT = 3,\n    HP_HEADERSORTARROW = 4\n}\n\nenum {\n    HIS_NORMAL = 1,\n    HIS_HOT = 2,\n    HIS_PRESSED = 3\n}\n\nenum {\n    HILS_NORMAL = 1,\n    HILS_HOT = 2,\n    HILS_PRESSED = 3\n}\n\nenum {\n    HIRS_NORMAL = 1,\n    HIRS_HOT = 2,\n    HIRS_PRESSED = 3\n}\n\nenum {\n    HSAS_SORTEDUP = 1,\n    HSAS_SORTEDDOWN = 2\n}\n\n/* LISTVIEW parts */\nenum {\n    LVP_LISTITEM = 1,\n    LVP_LISTGROUP = 2,\n    LVP_LISTDETAIL = 3,\n    LVP_LISTSORTEDDETAIL = 4,\n    LVP_EMPTYTEXT = 5\n}\n\nenum {\n    LIS_NORMAL = 1,\n    LIS_HOT = 2,\n    LIS_SELECTED = 3,\n    LIS_DISABLED = 4,\n    LIS_SELECTEDNOTFOCUS = 5\n}\n\n/* MENU parts */\nenum {\n    MP_MENUITEM = 1,\n    MP_MENUDROPDOWN = 2,\n    MP_MENUBARITEM = 3,\n    MP_MENUBARDROPDOWN = 4,\n    MP_CHEVRON = 5,\n    MP_SEPARATOR = 6\n}\n\nenum {\n    MS_NORMAL = 1,\n    MS_SELECTED = 2,\n    MS_DEMOTED = 3\n}\n/* MENUBAND parts */\nenum {\n    MDP_NEWAPPBUTTON = 1,\n    MDP_SEPERATOR = 2\n}\n\nenum {\n    MDS_NORMAL = 1,\n    MDS_HOT = 2,\n    MDS_PRESSED = 3,\n    MDS_DISABLED = 4,\n    MDS_CHECKED = 5,\n    MDS_HOTCHECKED = 6\n}\n\n/* PAGE parts */\nenum {\n    PGRP_UP = 1,\n    PGRP_DOWN = 2,\n    PGRP_UPHORZ = 3,\n    PGRP_DOWNHORZ = 4\n}\n\nenum {\n    DNS_NORMAL = 1,\n    DNS_HOT = 2,\n    DNS_PRESSED = 3,\n    DNS_DISABLED = 4\n}\n\nenum {\n    DNHZS_NORMAL = 1,\n    DNHZS_HOT = 2,\n    DNHZS_PRESSED = 3,\n    DNHZS_DISABLED = 4\n}\n\nenum {\n    UPS_NORMAL = 1,\n    UPS_HOT = 2,\n    UPS_PRESSED = 3,\n    UPS_DISABLED = 4\n}\n\nenum {\n    UPHZS_NORMAL = 1,\n    UPHZS_HOT = 2,\n    UPHZS_PRESSED = 3,\n    UPHZS_DISABLED = 4\n}\n\n/* PROGRESS parts */\nenum {\n    PP_BAR = 1,\n    PP_BARVERT = 2,\n    PP_CHUNK = 3,\n    PP_CHUNKVERT = 4\n}\n\n/* REBAR parts */\nenum {\n    RP_GRIPPER = 1,\n    RP_GRIPPERVERT = 2,\n    RP_BAND = 3,\n    RP_CHEVRON = 4,\n    RP_CHEVRONVERT = 5\n}\n\nenum {\n    CHEVS_NORMAL = 1,\n    CHEVS_HOT = 2,\n    CHEVS_PRESSED = 3\n}\n\n/* SCROLLBAR parts */\nenum {\n    SBP_ARROWBTN = 1,\n    SBP_THUMBBTNHORZ = 2,\n    SBP_THUMBBTNVERT = 3,\n    SBP_LOWERTRACKHORZ = 4,\n    SBP_UPPERTRACKHORZ = 5,\n    SBP_LOWERTRACKVERT = 6,\n    SBP_UPPERTRACKVERT = 7,\n    SBP_GRIPPERHORZ = 8,\n    SBP_GRIPPERVERT = 9,\n    SBP_SIZEBOX = 10\n}\n\nenum {\n    ABS_UPNORMAL = 1,\n    ABS_UPHOT = 2,\n    ABS_UPPRESSED = 3,\n    ABS_UPDISABLED = 4,\n    ABS_DOWNNORMAL = 5,\n    ABS_DOWNHOT = 6,\n    ABS_DOWNPRESSED = 7,\n    ABS_DOWNDISABLED = 8,\n    ABS_LEFTNORMAL = 9,\n    ABS_LEFTHOT = 10,\n    ABS_LEFTPRESSED = 11,\n    ABS_LEFTDISABLED = 12,\n    ABS_RIGHTNORMAL = 13,\n    ABS_RIGHTHOT = 14,\n    ABS_RIGHTPRESSED = 15,\n    ABS_RIGHTDISABLED = 16\n}\n\nenum {\n    SCRBS_NORMAL = 1,\n    SCRBS_HOT = 2,\n    SCRBS_PRESSED = 3,\n    SCRBS_DISABLED = 4\n}\n\nenum {\n    SZB_RIGHTALIGN = 1,\n    SZB_LEFTALIGN = 2\n}\n\n/* SPIN parts */\nenum {\n    SPNP_UP = 1,\n    SPNP_DOWN = 2,\n    SPNP_UPHORZ = 3,\n    SPNP_DOWNHORZ = 4\n}\n\n/* STARTPANEL parts */\nenum {\n    SPP_USERPANE = 1,\n    SPP_MOREPROGRAMS = 2,\n    SPP_MOREPROGRAMSARROW = 3,\n    SPP_PROGLIST = 4,\n    SPP_PROGLISTSEPARATOR = 5,\n    SPP_PLACESLIST = 6,\n    SPP_PLACESLISTSEPARATOR = 7,\n    SPP_LOGOFF = 8,\n    SPP_LOGOFFBUTTONS = 9,\n    SPP_USERPICTURE = 10,\n    SPP_PREVIEW = 11\n}\n\nenum {\n    SPLS_NORMAL = 1,\n    SPLS_HOT = 2,\n    SPLS_PRESSED = 3\n}\n\nenum {\n    SPS_NORMAL = 1,\n    SPS_HOT = 2,\n    SPS_PRESSED = 3\n}\n\n/* STATUS parts */\nenum {\n    SP_PANE = 1,\n    SP_GRIPPERPANE = 2,\n    SP_GRIPPER = 3\n}\n\n/* TAB parts */\nenum {\n    TABP_TABITEM = 1,\n    TABP_TABITEMLEFTEDGE = 2,\n    TABP_TABITEMRIGHTEDGE = 3,\n    TABP_TABITEMBOTHEDGE = 4,\n    TABP_TOPTABITEM = 5,\n    TABP_TOPTABITEMLEFTEDGE = 6,\n    TABP_TOPTABITEMRIGHTEDGE = 7,\n    TABP_TOPTABITEMBOTHEDGE = 8,\n    TABP_PANE = 9,\n    TABP_BODY = 10\n}\n\nenum {\n    TIS_NORMAL = 1,\n    TIS_HOT = 2,\n    TIS_SELECTED = 3,\n    TIS_DISABLED = 4,\n    TIS_FOCUSED = 5\n}\n\nenum {\n    TIBES_NORMAL = 1,\n    TIBES_HOT = 2,\n    TIBES_SELECTED = 3,\n    TIBES_DISABLED = 4,\n    TIBES_FOCUSED = 5\n}\n\nenum {\n    TILES_NORMAL = 1,\n    TILES_HOT = 2,\n    TILES_SELECTED = 3,\n    TILES_DISABLED = 4,\n    TILES_FOCUSED = 5\n}\n\nenum {\n    TIRES_NORMAL = 1,\n    TIRES_HOT = 2,\n    TIRES_SELECTED = 3,\n    TIRES_DISABLED = 4,\n    TIRES_FOCUSED = 5\n}\n\nenum {\n    TTIS_NORMAL = 1,\n    TTIS_HOT = 2,\n    TTIS_SELECTED = 3,\n    TTIS_DISABLED = 4,\n    TTIS_FOCUSED = 5\n}\n\nenum {\n    TTIBES_NORMAL = 1,\n    TTIBES_HOT = 2,\n    TTIBES_SELECTED = 3,\n    TTIBES_DISABLED = 4,\n    TTIBES_FOCUSED = 5\n}\n\nenum {\n    TTILES_NORMAL = 1,\n    TTILES_HOT = 2,\n    TTILES_SELECTED = 3,\n    TTILES_DISABLED = 4,\n    TTILES_FOCUSED = 5\n}\n\nenum {\n    TTIRES_NORMAL = 1,\n    TTIRES_HOT = 2,\n    TTIRES_SELECTED = 3,\n    TTIRES_DISABLED = 4,\n    TTIRES_FOCUSED = 5\n}\n\n/* TASKBAND parts */\nenum {\n    TDP_GROUPCOUNT = 1,\n    TDP_FLASHBUTTON = 2,\n    TDP_FLASHBUTTONGROUPMENU = 3\n}\n\n/* TASKBAR parts */\nenum {\n    TBP_BACKGROUNDBOTTOM = 1,\n    TBP_BACKGROUNDRIGHT = 2,\n    TBP_BACKGROUNDTOP = 3,\n    TBP_BACKGROUNDLEFT = 4,\n    TBP_SIZINGBARBOTTOM = 5,\n    TBP_SIZINGBARRIGHT = 6,\n    TBP_SIZINGBARTOP = 7,\n    TBP_SIZINGBARLEFT = 8\n}\n\n/* TOOLBAR parts */\nenum {\n    TP_BUTTON = 1,\n    TP_DROPDOWNBUTTON = 2,\n    TP_SPLITBUTTON = 3,\n    TP_SPLITBUTTONDROPDOWN = 4,\n    TP_SEPARATOR = 5,\n    TP_SEPARATORVERT = 6\n}\n\nenum {\n    TS_NORMAL = 1,\n    TS_HOT = 2,\n    TS_PRESSED = 3,\n    TS_DISABLED = 4,\n    TS_CHECKED = 5,\n    TS_HOTCHECKED = 6\n}\n\n/* TOOLTIP parts */\nenum {\n    TTP_STANDARD = 1,\n    TTP_STANDARDTITLE = 2,\n    TTP_BALLOON = 3,\n    TTP_BALLOONTITLE = 4,\n    TTP_CLOSE = 5\n}\n\nenum {\n    TTBS_NORMAL = 1,\n    TTBS_LINK = 2\n}\n\nenum {\n    TTCS_NORMAL = 1,\n    TTCS_HOT = 2,\n    TTCS_PRESSED = 3\n}\n\nenum {\n    TTSS_NORMAL = 1,\n    TTSS_LINK = 2\n}\n\n/* TRACKBAR parts */\nenum {\n    TKP_TRACK = 1,\n    TKP_TRACKVERT = 2,\n    TKP_THUMB = 3,\n    TKP_THUMBBOTTOM = 4,\n    TKP_THUMBTOP = 5,\n    TKP_THUMBVERT = 6,\n    TKP_THUMBLEFT = 7,\n    TKP_THUMBRIGHT = 8,\n    TKP_TICS = 9,\n    TKP_TICSVERT = 10\n}\n\nenum {\n    TUS_NORMAL = 1,\n    TUS_HOT = 2,\n    TUS_PRESSED = 3,\n    TUS_FOCUSED = 4,\n    TUS_DISABLED = 5\n}\n\nenum {\n    TUBS_NORMAL = 1,\n    TUBS_HOT = 2,\n    TUBS_PRESSED = 3,\n    TUBS_FOCUSED = 4,\n    TUBS_DISABLED = 5\n}\n\nenum {\n    TUVLS_NORMAL = 1,\n    TUVLS_HOT = 2,\n    TUVLS_PRESSED = 3,\n    TUVLS_FOCUSED = 4,\n    TUVLS_DISABLED = 5\n}\n\nenum {\n    TUVRS_NORMAL = 1,\n    TUVRS_HOT = 2,\n    TUVRS_PRESSED = 3,\n    TUVRS_FOCUSED = 4,\n    TUVRS_DISABLED = 5\n}\n\nenum {\n    TUTS_NORMAL = 1,\n    TUTS_HOT = 2,\n    TUTS_PRESSED = 3,\n    TUTS_FOCUSED = 4,\n    TUTS_DISABLED = 5\n}\n\nenum {\n    TUVS_NORMAL = 1,\n    TUVS_HOT = 2,\n    TUVS_PRESSED = 3,\n    TUVS_FOCUSED = 4,\n    TUVS_DISABLED = 5\n}\n\nenum {\n    TSS_NORMAL = 1\n}\n\nenum {\n    TSVS_NORMAL = 1\n}\n\nenum {\n    TRS_NORMAL = 1\n}\n\nenum {\n    TRVS_NORMAL = 1\n}\n\n/* TRAYNOTIFY parts */\nenum {\n    TNP_BACKGROUND = 1,\n    TNP_ANIMBACKGROUND = 2\n}\n\n/* TREEVIEW parts */\nenum {\n    TVP_TREEITEM = 1,\n    TVP_GLYPH = 2,\n    TVP_BRANCH = 3\n}\n\nenum {\n    GLPS_CLOSED = 1,\n    GLPS_OPENED = 2\n}\n\nenum {\n    TREIS_NORMAL = 1,\n    TREIS_HOT = 2,\n    TREIS_SELECTED = 3,\n    TREIS_DISABLED = 4,\n    TREIS_SELECTEDNOTFOCUS = 5\n}\n\n/* WINDOW parts */\nenum {\n    WP_CAPTION = 1,\n    WP_SMALLCAPTION = 2,\n    WP_MINCAPTION = 3,\n    WP_SMALLMINCAPTION = 4,\n    WP_MAXCAPTION = 5,\n    WP_SMALLMAXCAPTION = 6,\n    WP_FRAMELEFT = 7,\n    WP_FRAMERIGHT = 8,\n    WP_FRAMEBOTTOM = 9,\n    WP_SMALLFRAMELEFT = 10,\n    WP_SMALLFRAMERIGHT = 11,\n    WP_SMALLFRAMEBOTTOM = 12,\n    WP_SYSBUTTON = 13,\n    WP_MDISYSBUTTON = 14,\n    WP_MINBUTTON = 15,\n    WP_MDIMINBUTTON = 16,\n    WP_MAXBUTTON = 17,\n    WP_CLOSEBUTTON = 18,\n    WP_SMALLCLOSEBUTTON = 19,\n    WP_MDICLOSEBUTTON = 20,\n    WP_RESTOREBUTTON = 21,\n    WP_MDIRESTOREBUTTON = 22,\n    WP_HELPBUTTON = 23,\n    WP_MDIHELPBUTTON = 24,\n    WP_HORZSCROLL = 25,\n    WP_HORZTHUMB = 26,\n    WP_VERTSCROLL = 27,\n    WP_VERTTHUMB = 28,\n    WP_DIALOG = 29,\n    WP_CAPTIONSIZINGTEMPLATE = 30,\n    WP_SMALLCAPTIONSIZINGTEMPLATE = 31,\n    WP_FRAMELEFTSIZINGTEMPLATE = 32,\n    WP_SMALLFRAMELEFTSIZINGTEMPLATE = 33,\n    WP_FRAMERIGHTSIZINGTEMPLATE = 34,\n    WP_SMALLFRAMERIGHTSIZINGTEMPLATE = 35,\n    WP_FRAMEBOTTOMSIZINGTEMPLATE = 36,\n    WP_SMALLFRAMEBOTTOMSIZINGTEMPLATE = 37\n}\n\nenum {\n    CS_ACTIVE = 1,\n    CS_INACTIVE = 2,\n    CS_DISABLED = 3\n}\n\nenum {\n    CBS_NORMAL = 1,\n    CBS_HOT = 2,\n    CBS_PUSHED = 3,\n    CBS_DISABLED = 4\n}\n\nenum {\n    FS_ACTIVE = 1,\n    FS_INACTIVE = 2\n}\n\nenum {\n    HBS_NORMAL = 1,\n    HBS_HOT = 2,\n    HBS_PUSHED = 3,\n    HBS_DISABLED = 4\n}\n\nenum {\n    HSS_NORMAL = 1,\n    HSS_HOT = 2,\n    HSS_PUSHED = 3,\n    HSS_DISABLED = 4\n}\n\nenum {\n    HTS_NORMAL = 1,\n    HTS_HOT = 2,\n    HTS_PUSHED = 3,\n    HTS_DISABLED = 4\n}\n\nenum {\n    MAXBS_NORMAL = 1,\n    MAXBS_HOT = 2,\n    MAXBS_PUSHED = 3,\n    MAXBS_DISABLED = 4\n}\n\nenum {\n    MXCS_ACTIVE = 1,\n    MXCS_INACTIVE = 2,\n    MXCS_DISABLED = 3\n}\n\nenum {\n    MINBS_NORMAL = 1,\n    MINBS_HOT = 2,\n    MINBS_PUSHED = 3,\n    MINBS_DISABLED = 4\n}\n\nenum {\n    RBS_NORMAL = 1,\n    RBS_HOT = 2,\n    RBS_PUSHED = 3,\n    RBS_DISABLED = 4\n}\n\nenum {\n    SBS_NORMAL = 1,\n    SBS_HOT = 2,\n    SBS_PUSHED = 3,\n    SBS_DISABLED = 4\n}\n\nenum {\n    MNCS_ACTIVE = 1,\n    MNCS_INACTIVE = 2,\n    MNCS_DISABLED = 3\n}\n\nenum {\n    VSS_NORMAL = 1,\n    VSS_HOT = 2,\n    VSS_PUSHED = 3,\n    VSS_DISABLED = 4\n}\n\nenum {\n    VTS_NORMAL = 1,\n    VTS_HOT = 2,\n    VTS_PUSHED = 3,\n    VTS_DISABLED = 4\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/unknwn.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_unknwn.d)\n */\nmodule core.sys.windows.unknwn;\nversion (Windows):\n\nimport core.sys.windows.objfwd, core.sys.windows.windef, core.sys.windows.wtypes;\nprivate import core.sys.windows.basetyps;\n\nextern (Windows) {\n    void* MIDL_user_allocate(size_t);\n    void MIDL_user_free(void*);\n}\n\n\nextern (Windows) {\n\n    interface IUnknown {\n        HRESULT QueryInterface(IID* riid, void** pvObject);\n        ULONG AddRef();\n        ULONG Release();\n    }\n\n    alias IUnknown LPUNKNOWN;\n\n    interface IClassFactory : IUnknown {\n        HRESULT CreateInstance(IUnknown UnkOuter, IID* riid, void** pvObject);\n        HRESULT LockServer(BOOL fLock);\n    }\n    alias IClassFactory LPCLASSFACTORY;\n\n    /+\n    // These do not seem to be necessary (or desirable) for D.\n    HRESULT IUnknown_QueryInterface_Proxy(IUnknown,REFIID,void**);\n    ULONG IUnknown_AddRef_Proxy(IUnknown);\n    ULONG IUnknown_Release_Proxy(IUnknown);\n    HRESULT IClassFactory_RemoteCreateInstance_Proxy(IClassFactory,REFIID,IUnknown*);\n    HRESULT IClassFactory_RemoteLockServer_Proxy(IClassFactory,BOOL);\n    HRESULT IClassFactory_CreateInstance_Proxy(IClassFactory,IUnknown,REFIID,void**);\n    HRESULT IClassFactory_CreateInstance_Stub(IClassFactory,REFIID,IUnknown*);\n    HRESULT IClassFactory_LockServer_Proxy(IClassFactory,BOOL);\n    HRESULT IClassFactory_LockServer_Stub(IClassFactory,BOOL);\n\n    void IUnknown_QueryInterface_Stub(LPRPCSTUBBUFFER,LPRPCCHANNELBUFFER,PRPC_MESSAGE,PDWORD);\n    void IUnknown_AddRef_Stub(LPRPCSTUBBUFFER,LPRPCCHANNELBUFFER,PRPC_MESSAGE,PDWORD);\n    void IUnknown_Release_Stub(LPRPCSTUBBUFFER,LPRPCCHANNELBUFFER,PRPC_MESSAGE,PDWORD);\n    void IClassFactory_RemoteCreateInstance_Stub(LPRPCSTUBBUFFER,LPRPCCHANNELBUFFER,PRPC_MESSAGE,PDWORD);\n    void IClassFactory_RemoteLockServer_Stub(LPRPCSTUBBUFFER,LPRPCCHANNELBUFFER,PRPC_MESSAGE,PDWORD);\n    +/\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/uuid.d",
    "content": "module core.sys.windows.uuid;\nversion (Windows):\n\nimport core.sys.windows.basetyps;\n\nconst IID _DBBMKGUID = {0xF6304BB0, 0xD188, 0x11CD, [0xAD, 0x48, 0x00, 0xAA, 0x00, 0x3C, 0x9C, 0xB6]};\nconst IID _DBCIDGUID = {0xFE284700, 0xD188, 0x11CD, [0xAD, 0x48, 0x00, 0xAA, 0x00, 0x3C, 0x9C, 0xB6]};\nconst IID _GUID_NAMEONLY = {0xE8BF1170, 0xD188, 0x11CD, [0xAD, 0x48, 0x00, 0xAA, 0x00, 0x3C, 0x9C, 0xB6]};\nconst IID ARRAYID_PathProperties = {0x7ECBBA04, 0x2D97, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID BFID_GRAY_16 = {0xF9D6BC00, 0x449C, 0x11D0, [0x91, 0x8C, 0x00, 0xAA, 0x00, 0x6C, 0x1A, 0x01]};\nconst IID BFID_GRAY_8 = {0xD93DE910, 0x449C, 0x11D0, [0x91, 0x8C, 0x00, 0xAA, 0x00, 0x6C, 0x1A, 0x01]};\nconst IID BFID_MONOCHROME = {0xE436EB78, 0x524F, 0x11CE, [0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70]};\nconst IID BFID_RGB_24 = {0xE436EB7D, 0x524F, 0x11CE, [0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70]};\nconst IID BFID_RGB_32 = {0xE436EB7E, 0x524F, 0x11CE, [0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70]};\nconst IID BFID_RGB_4 = {0xE436EB79, 0x524F, 0x11CE, [0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70]};\nconst IID BFID_RGB_555 = {0xE436EB7C, 0x524F, 0x11CE, [0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70]};\nconst IID BFID_RGB_565 = {0xE436EB7B, 0x524F, 0x11CE, [0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70]};\nconst IID BFID_RGB_8 = {0xE436EB7A, 0x524F, 0x11CE, [0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70]};\nconst IID BFID_RGBA_32 = {0x773C9AC0, 0x3274, 0x11D0, [0xB7, 0x24, 0x00, 0xAA, 0x00, 0x6C, 0x1A, 0x01]};\nconst IID BHID_LinkTargetItem = {0x3981E228, 0xF559, 0x11D3, [0x8E, 0x3A, 0x00, 0xC0, 0x4F, 0x68, 0x37, 0xD5]};\nconst IID BHID_SFObject = {0x3981E224, 0xF559, 0x11D3, [0x8E, 0x3A, 0x00, 0xC0, 0x4F, 0x68, 0x37, 0xD5]};\nconst IID BHID_SFUIObject = {0x3981E225, 0xF559, 0x11D3, [0x8E, 0x3A, 0x00, 0xC0, 0x4F, 0x68, 0x37, 0xD5]};\nconst IID BHID_SFViewObject = {0x3981E226, 0xF559, 0x11D3, [0x8E, 0x3A, 0x00, 0xC0, 0x4F, 0x68, 0x37, 0xD5]};\nconst IID BHID_Storage = {0x3981E227, 0xF559, 0x11D3, [0x8E, 0x3A, 0x00, 0xC0, 0x4F, 0x68, 0x37, 0xD5]};\nconst IID BHID_StorageEnum = {0x4621A4E3, 0xF0D6, 0x4773, [0x8A, 0x9C, 0x46, 0xE7, 0x7B, 0x17, 0x48, 0x40]};\nconst IID BHID_Stream = {0x1CEBB3AB, 0x7C10, 0x499A, [0xA4, 0x17, 0x92, 0xCA, 0x16, 0xC4, 0xCB, 0x83]};\nconst IID CATID_BrowsableShellExt = {0x00021490, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CATID_BrowseInPlace = {0x00021491, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CATID_ClusCfgCapabilities = {0x4653EEC4, 0x2788, 0x4EBD, [0xA8, 0x31, 0x7E, 0x0D, 0x9F, 0x82, 0xD6, 0xE7]};\nconst IID CATID_ClusCfgMemberSetChangeListener = {0x8A43EAD4, 0x10F1, 0x440D, [0x8D, 0xAA, 0x1F, 0xE3, 0x8D, 0x16, 0x98, 0xCD]};\nconst IID CATID_ClusCfgResourceTypes = {0x7C4CAE52, 0xCAC9, 0x499D, [0x82, 0xC6, 0xBC, 0x6A, 0x21, 0x77, 0xE5, 0x56]};\nconst IID CATID_ClusCfgStartupListeners = {0xDF406DB4, 0x7872, 0x4A99, [0xBB, 0x3C, 0x14, 0xA9, 0xC3, 0x39, 0x33, 0xD1]};\nconst IID CATID_CommBand = {0x00021494, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CATID_Control = {0x40FC6ED4, 0x2438, 0x11CF, [0xA3, 0xDB, 0x08, 0x00, 0x36, 0xF1, 0x25, 0x02]};\nconst IID CATID_DesignTimeUIActivatableControl = {0xF2BB56D1, 0xDB07, 0x11D1, [0xAA, 0x6B, 0x00, 0x60, 0x97, 0xDB, 0x95, 0x39]};\nconst IID CATID_DeskBand = {0x00021492, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CATID_DocObject = {0x40FC6ED8, 0x2438, 0x11CF, [0xA3, 0xDB, 0x08, 0x00, 0x36, 0xF1, 0x25, 0x02]};\nconst IID CATID_EnumClusCfgManagedResources = {0x02A34F88, 0xD31A, 0x4688, [0xBD, 0xDD, 0x38, 0xA7, 0x39, 0xE4, 0xF8, 0x9B]};\nconst IID CATID_InfoBand = {0x00021493, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CATID_Insertable = {0x40FC6ED3, 0x2438, 0x11CF, [0xA3, 0xDB, 0x08, 0x00, 0x36, 0xF1, 0x25, 0x02]};\nconst IID CATID_InternetAware = {0x0DE86A58, 0x2BAA, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID CATID_IsShortcut = {0x40FC6ED6, 0x2438, 0x11CF, [0xA3, 0xDB, 0x08, 0x00, 0x36, 0xF1, 0x25, 0x02]};\nconst IID CATID_MARSHALER = {0x00000003, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CATID_NeverShowExt = {0x40FC6ED7, 0x2438, 0x11CF, [0xA3, 0xDB, 0x08, 0x00, 0x36, 0xF1, 0x25, 0x02]};\nconst IID CATID_PersistsToFile = {0x0DE86A56, 0x2BAA, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID CATID_PersistsToMemory = {0x0DE86A55, 0x2BAA, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID CATID_PersistsToMoniker = {0x0DE86A51, 0x2BAA, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID CATID_PersistsToPropertyBag = {0x0DE86A57, 0x2BAA, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID CATID_PersistsToStorage = {0x0DE86A52, 0x2BAA, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID CATID_PersistsToStream = {0x0DE86A54, 0x2BAA, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID CATID_PersistsToStreamInit = {0x0DE86A53, 0x2BAA, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID CATID_Printable = {0x40FC6ED9, 0x2438, 0x11CF, [0xA3, 0xDB, 0x08, 0x00, 0x36, 0xF1, 0x25, 0x02]};\nconst IID CATID_Programmable = {0x40FC6ED5, 0x2438, 0x11CF, [0xA3, 0xDB, 0x08, 0x00, 0x36, 0xF1, 0x25, 0x02]};\nconst IID CATID_RequiresDataPathHost = {0x0DE86A50, 0x2BAA, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID CATID_SafeForInitializing = {0x7DD95802, 0x9882, 0x11CF, [0x9F, 0xA9, 0x00, 0xAA, 0x00, 0x6C, 0x42, 0xC4]};\nconst IID CATID_SafeForScripting = {0x7DD95801, 0x9882, 0x11CF, [0x9F, 0xA9, 0x00, 0xAA, 0x00, 0x6C, 0x42, 0xC4]};\nconst IID CGID_DocHostCommandHandler = {0xF38BC242, 0xB950, 0x11D1, [0x89, 0x18, 0x00, 0xC0, 0x4F, 0xC2, 0xC8, 0x36]};\nconst IID CGID_DownloadHost = {0xE0608728, 0xAE4C, 0x11D1, [0xBA, 0x40, 0x00, 0xC0, 0x4F, 0xB9, 0x2D, 0x79]};\nconst IID CGID_Explorer = {0x000214D0, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CGID_ExplorerBarDoc = {0x000214D3, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CGID_InternetExplorer = {0xEB7EED00, 0xF74D, 0x11D2, [0xBB, 0x7F, 0x00, 0x10, 0x4B, 0x35, 0xE7, 0xF9]};\nconst IID CGID_MSHTML = {0xDE4BA900, 0x59CA, 0x11CF, [0x95, 0x92, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID CGID_ShellDocView = {0x000214D1, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CGID_ShellServiceObject = {0x000214D2, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CGID_ShortCut = {0x93A68750, 0x951A, 0x11D1, [0x94, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]};\nconst IID CLSID_1 = {0xD34F1813, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_2 = {0xD34F1814, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_3 = {0xD34F1815, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_4 = {0xD34F1816, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_5 = {0xD34F1817, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_6 = {0xD34F1818, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_7 = {0xD34F1819, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_8 = {0xD34F181A, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_9 = {0xD34F181B, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_a = {0xD34F181C, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_AboutProtocol = {0x3050F406, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_AccessControlEntry = {0xB75AC000, 0x9BDD, 0x11D0, [0x85, 0x2C, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID CLSID_AccessControlList = {0xB85EA052, 0x9BDD, 0x11D0, [0x85, 0x2C, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID CLSID_AccountDiscovery = {0x3DAB30ED, 0x8132, 0x40BF, [0xA8, 0xBA, 0x7B, 0x50, 0x57, 0xF0, 0xCD, 0x10]};\nconst IID CLSID_ACLCustomMRU = {0x6935DB93, 0x21E8, 0x4CCC, [0xBE, 0xB9, 0x9F, 0xE3, 0xC7, 0x7A, 0x29, 0x7A]};\nconst IID CLSID_ACLHistory = {0x00BB2764, 0x6A77, 0x11D0, [0xA5, 0x35, 0x00, 0xC0, 0x4F, 0xD7, 0xD0, 0x62]};\nconst IID CLSID_ACListISF = {0x03C036F1, 0xA186, 0x11D0, [0x82, 0x4A, 0x00, 0xAA, 0x00, 0x5B, 0x43, 0x83]};\nconst IID CLSID_ACLMRU = {0x6756A641, 0xDE71, 0x11D0, [0x83, 0x1B, 0x00, 0xAA, 0x00, 0x5B, 0x43, 0x83]};\nconst IID CLSID_ACLMulti = {0x00BB2765, 0x6A77, 0x11D0, [0xA5, 0x35, 0x00, 0xC0, 0x4F, 0xD7, 0xD0, 0x62]};\nconst IID CLSID_ActiveDesktop = {0x75048700, 0xEF1F, 0x11D0, [0x98, 0x88, 0x00, 0x60, 0x97, 0xDE, 0xAC, 0xF9]};\nconst IID CLSID_AdapterInfo = {0x6F9942C9, 0xC1B1, 0x4AB5, [0x93, 0xDA, 0x60, 0x58, 0x99, 0x1D, 0xC8, 0xF3]};\nconst IID CLSID_AddrControl = {0x00000348, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_AddressBarParser = {0xE0E11A09, 0x5CB8, 0x4B6C, [0x83, 0x32, 0xE0, 0x07, 0x20, 0xA1, 0x68, 0xF2]};\nconst IID CLSID_ADsDSOObject = {0x549365D0, 0xEC26, 0x11CF, [0x83, 0x10, 0x00, 0xAA, 0x00, 0xB5, 0x05, 0xDB]};\nconst IID CLSID_ADsSecurityUtility = {0xF270C64A, 0xFFB8, 0x4AE4, [0x85, 0xFE, 0x3A, 0x75, 0xE5, 0x34, 0x79, 0x66]};\nconst IID CLSID_ADSystemInfo = {0x50B6327F, 0xAFD1, 0x11D2, [0x9C, 0xB9, 0x00, 0x00, 0xF8, 0x7A, 0x36, 0x9E]};\nconst IID CLSID_AlgSetup = {0x27D0BCCC, 0x344D, 0x4287, [0xAF, 0x37, 0x0C, 0x72, 0xC1, 0x61, 0xC1, 0x4C]};\nconst IID CLSID_AllClasses = {0x00000330, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_AlphabeticalCategorizer = {0x3C2654C6, 0x7372, 0x4F6B, [0xB3, 0x10, 0x55, 0xD6, 0x12, 0x8F, 0x49, 0xD2]};\nconst IID CLSID_AnchorClick = {0x13D5413C, 0x33B9, 0x11D2, [0x95, 0xA7, 0x00, 0xC0, 0x4F, 0x8E, 0xCB, 0x02]};\nconst IID CLSID_AnimationComposerFactory = {0x332B2A56, 0xF86C, 0x47E7, [0x86, 0x02, 0xFC, 0x42, 0xAC, 0x8B, 0x99, 0x20]};\nconst IID CLSID_AnimationComposerSiteFactory = {0x16911A65, 0xD41D, 0x4431, [0x87, 0xF7, 0xE7, 0x57, 0xF4, 0xD0, 0x3B, 0xD8]};\nconst IID CLSID_ApplicationGatewayServices = {0xF8ADE1D3, 0x49DF, 0x4B75, [0x90, 0x05, 0xEF, 0x95, 0x08, 0xE6, 0xA3, 0x37]};\nconst IID CLSID_AutoComplete = {0x00BB2763, 0x6A77, 0x11D0, [0xA5, 0x35, 0x00, 0xC0, 0x4F, 0xD7, 0xD0, 0x62]};\nconst IID CLSID_AutoDiscoveryProvider = {0xC4F3D5BF, 0x4809, 0x44E3, [0x84, 0xA4, 0x36, 0x8B, 0x6B, 0x33, 0xB0, 0xB4]};\nconst IID CLSID_AutoplayForSlideShow = {0x00E7B358, 0xF65B, 0x4DCF, [0x83, 0xDF, 0xCD, 0x02, 0x6B, 0x94, 0xBF, 0xD4]};\nconst IID CLSID_b = {0xD34F181D, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_BackgroundCopyManager = {0x4991D34B, 0x80A1, 0x4291, [0x83, 0xB6, 0x33, 0x28, 0x36, 0x6B, 0x90, 0x97]};\nconst IID CLSID_BackgroundCopyManager1_5 = {0xF087771F, 0xD74F, 0x4C1A, [0xBB, 0x8A, 0xE1, 0x6A, 0xCA, 0x91, 0x24, 0xEA]};\nconst IID CLSID_BackgroundCopyQMgr = {0x69AD4AEE, 0x51BE, 0x439B, [0xA9, 0x2C, 0x86, 0xAE, 0x49, 0x0E, 0x8B, 0x30]};\nconst IID CLSID_BackLink = {0xFCBF906F, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_BasicImageEffects = {0x16B280C8, 0xEE70, 0x11D1, [0x90, 0x66, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID CLSID_BasicImageEffectsPP = {0x16B280C9, 0xEE70, 0x11D1, [0x90, 0x66, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID CLSID_BlockFormats = {0x3050F831, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_BridgeTerminal = {0x8EBAE7A3, 0x8943, 0x11D1, [0x96, 0xB8, 0x00, 0xC0, 0x4F, 0xB6, 0xE8, 0x66]};\nconst IID CLSID_c = {0xD34F181E, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_CAccPropServices = {0xB5F8350B, 0x0548, 0x48B1, [0xA6, 0xEE, 0x88, 0xBD, 0x00, 0xB4, 0xA5, 0xE7]};\nconst IID CLSID_CActiveIMM = {0x4955DD33, 0xB159, 0x11D0, [0x8F, 0xCF, 0x00, 0xAA, 0x00, 0x6B, 0xCC, 0x59]};\nconst IID CLSID_CAnchorBrowsePropertyPage = {0x3050F3BB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CaseIgnoreList = {0x15F88A55, 0x4680, 0x11D1, [0xA3, 0xB4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_CCheckBox = {0x3050F686, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CColorPropPage = {0x0BE35201, 0x8F91, 0x11CE, [0x9D, 0xE3, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51]};\nconst IID CLSID_CCombobox = {0x3050F678, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CDBurn = {0xFBEB8A05, 0xBEEE, 0x4442, [0x80, 0x4E, 0x40, 0x9D, 0x6C, 0x45, 0x15, 0xE9]};\nconst IID CLSID_CDebugDocumentHelper = {0x83B8BCA6, 0x687C, 0x11D0, [0xA4, 0x05, 0x00, 0xAA, 0x00, 0x60, 0x27, 0x5C]};\nconst IID CLSID_CDeviceRect = {0x3050F6D4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CDirect3DRM = {0x4516EC41, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID CLSID_CDirect3DRMAnimation = {0x4FA35698, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMAnimationSet = {0x4FA35699, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMClippedVisual = {0x5434E72D, 0x6D66, 0x11D1, [0xBB, 0x0B, 0x00, 0x00, 0xF8, 0x75, 0x86, 0x5A]};\nconst IID CLSID_CDirect3DRMDevice = {0x4FA3568E, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMFace = {0x4FA35693, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMFrame = {0x4FA35690, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMFrameInterpolator = {0x0DE9EAA2, 0x3B84, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID CLSID_CDirect3DRMLight = {0x4FA35694, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMLightInterpolator = {0x0DE9EAA6, 0x3B84, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID CLSID_CDirect3DRMMaterial = {0x4FA35697, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMMaterialInterpolato = {0x0DE9EAA7, 0x3B84, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID CLSID_CDirect3DRMMesh = {0x4FA35691, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMMeshBuilder = {0x4FA35692, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMMeshInterpolator = {0x0DE9EAA3, 0x3B84, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID CLSID_CDirect3DRMProgressiveMesh = {0x4516EC40, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID CLSID_CDirect3DRMShadow = {0x4FA3569B, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMTexture = {0x4FA35695, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMTextureInterpolator = {0x0DE9EAA8, 0x3B84, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID CLSID_CDirect3DRMUserVisual = {0x4FA3569A, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMViewport = {0x4FA3568F, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirect3DRMViewportInterpolato = {0x0DE9EAA1, 0x3B84, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID CLSID_CDirect3DRMWrap = {0x4FA35696, 0x623F, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID CLSID_CDirectXFile = {0x4516EC43, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID CLSID_CDLAgent = {0x7D559C10, 0x9FE9, 0x11D0, [0x93, 0xF7, 0x00, 0xAA, 0x00, 0x59, 0xCE, 0x02]};\nconst IID CLSID_CdlProtocol = {0x3DD53D40, 0x7B8B, 0x11D0, [0xB0, 0x13, 0x00, 0xAA, 0x00, 0x59, 0xCE, 0x02]};\nconst IID CLSID_CDocBrowsePropertyPage = {0x3050F3B4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CDownloadBehavior = {0x3050F5BE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CEnroll = {0x43F8F289, 0x7A20, 0x11D0, [0x8F, 0x06, 0x00, 0xC0, 0x4F, 0xC2, 0x95, 0xE1]};\nconst IID CLSID_CEventObj = {0x3050F48A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CFontPropPage = {0x0BE35200, 0x8F91, 0x11CE, [0x9D, 0xE3, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51]};\nconst IID CLSID_CFSIconOverlayManager = {0x63B51F81, 0xC868, 0x11D0, [0x99, 0x9C, 0x00, 0xC0, 0x4F, 0xD6, 0x55, 0xE1]};\nconst IID CLSID_ChannelAgent = {0xE3A8BDE6, 0xABCE, 0x11D0, [0xBC, 0x4B, 0x00, 0xC0, 0x4F, 0xD9, 0x29, 0xDB]};\nconst IID CLSID_ChannelMgr = {0xB3CDAE90, 0xD170, 0x11D0, [0x80, 0x2B, 0x00, 0xC0, 0x4F, 0xD7, 0x5D, 0x13]};\nconst IID CLSID_CHeaderFooter = {0x3050F6CD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CHtmlArea = {0x3050F64F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CIEOptionElement = {0x3050F698, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CIESelectElement = {0x3050F688, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CImageBrowsePropertyPage = {0x3050F3B3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_ClassInstallFilter = {0x32B533BB, 0xEDAE, 0x11D0, [0xBD, 0x5A, 0x00, 0xAA, 0x00, 0xB9, 0x2A, 0xF1]};\nconst IID CLSID_CLayoutRect = {0x3050F664, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_ClientCaps = {0x7E8BC44E, 0xAEFF, 0x11D1, [0x89, 0xC2, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4]};\nconst IID CLSID_ClusAppWiz = {0x24F97150, 0x6689, 0x11D1, [0x9A, 0xA7, 0x00, 0xC0, 0x4F, 0xB9, 0x3A, 0x80]};\nconst IID CLSID_ClusCfgAsyncEvictCleanup = {0x08F35A72, 0xD7C4, 0x42F4, [0xBC, 0x81, 0x51, 0x88, 0xE1, 0x9D, 0xFA, 0x39]};\nconst IID CLSID_ClusCfgEvictCleanup = {0x32152BE9, 0xDE8C, 0x4D0F, [0x81, 0xB0, 0xBC, 0xE5, 0xD1, 0x1E, 0xCB, 0x00]};\nconst IID CLSID_ClusCfgResTypeGenScript = {0xD513C4F4, 0x1D34, 0x44A3, [0x83, 0xD4, 0x81, 0x26, 0x51, 0xDB, 0x89, 0x18]};\nconst IID CLSID_ClusCfgResTypeMajorityNodeSet = {0xB6870B44, 0x0BDF, 0x4B46, [0xAC, 0x1F, 0x6C, 0x69, 0x1B, 0x62, 0x2E, 0xDF]};\nconst IID CLSID_ClusCfgResTypeServices = {0x6A370489, 0xBB52, 0x4727, [0xB7, 0x40, 0x08, 0xF4, 0x94, 0x16, 0x34, 0x78]};\nconst IID CLSID_ClusCfgStartupNotify = {0x105EEEB6, 0x32FD, 0x4EA9, [0x89, 0x12, 0x84, 0x3A, 0x7F, 0xF3, 0xCA, 0x2D]};\nconst IID CLSID_ClusCfgWizard = {0x1919C4FE, 0x6F46, 0x4027, [0x97, 0x7D, 0x0E, 0xF1, 0xC8, 0xF2, 0x63, 0x72]};\nconst IID CLSID_ClusterConfigurationType = {0xBF3768C2, 0xE0E5, 0x448F, [0x95, 0x2B, 0x25, 0xD4, 0x33, 0x2D, 0xEF, 0xA3]};\nconst IID CLSID_CMimeTypes = {0x3050F3FE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CMLangConvertCharset = {0xD66D6F99, 0xCDAA, 0x11D0, [0xB8, 0x22, 0x00, 0xC0, 0x4F, 0xC9, 0xB3, 0x1F]};\nconst IID CLSID_CMLangString = {0xC04D65CF, 0xB70D, 0x11D0, [0xB1, 0x88, 0x00, 0xAA, 0x00, 0x38, 0xC9, 0x69]};\nconst IID CLSID_CMultiLanguage = {0x275C23E2, 0x3747, 0x11D0, [0x9F, 0xEA, 0x00, 0xAA, 0x00, 0x3F, 0x86, 0x46]};\nconst IID CLSID_CNetCfg = {0x5B035261, 0x40F9, 0x11D1, [0xAA, 0xEC, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID CLSID_CoDitherToRGB8 = {0xA860CE50, 0x3910, 0x11D0, [0x86, 0xFC, 0x00, 0xA0, 0xC9, 0x13, 0xF7, 0x50]};\nconst IID CLSID_CoMapMIMEToCLSID = {0x30C3B080, 0x30FB, 0x11D0, [0xB7, 0x24, 0x00, 0xAA, 0x00, 0x6C, 0x1A, 0x01]};\nconst IID CLSID_ComBinding = {0x00000328, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_CommonQuery = {0x83BC5EC0, 0x6F2A, 0x11D0, [0xA1, 0xC4, 0x00, 0xAA, 0x00, 0xC1, 0x6E, 0x65]};\nconst IID CLSID_CompositePP = {0x25B33660, 0xFD83, 0x11D1, [0x8A, 0xDE, 0x44, 0x45, 0x53, 0x54, 0x00, 0x01]};\nconst IID CLSID_ConnectionCommonUi = {0x7007ACD1, 0x3202, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID CLSID_ConnectionManager = {0xBA126AD1, 0x2166, 0x11D1, [0xB1, 0xD0, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID CLSID_ConnectionManager2 = {0xBA126AE5, 0x2166, 0x11D1, [0xB1, 0xD0, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID CLSID_ControlPanel = {0x21EC2020, 0x3AEA, 0x1069, [0xA2, 0xDD, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D]};\nconst IID CLSID_ConvertVBX = {0xFB8F0822, 0x0164, 0x101B, [0x84, 0xED, 0x08, 0x00, 0x2B, 0x2E, 0xC7, 0x13]};\nconst IID CLSID_ConvolvePP = {0x25B33661, 0xFD83, 0x11D1, [0x8A, 0xDE, 0x44, 0x45, 0x53, 0x54, 0x00, 0x01]};\nconst IID CLSID_COpsProfile = {0x3050F402, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CoSniffStream = {0x6A01FDA0, 0x30DF, 0x11D0, [0xB7, 0x24, 0x00, 0xAA, 0x00, 0x6C, 0x1A, 0x01]};\nconst IID CLSID_CPersistDataPeer = {0x3050F487, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CPersistHistory = {0x3050F4C8, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CPersistShortcut = {0x3050F4C6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CPersistSnapshot = {0x3050F4C9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CPersistUserData = {0x3050F48E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CPicturePropPage = {0x0BE35202, 0x8F91, 0x11CE, [0x9D, 0xE3, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51]};\nconst IID CLSID_CPlugins = {0x3050F3FF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CRadioButton = {0x3050F69C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CrBarn = {0xC3BDF740, 0x0B58, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_CrBarnPP = {0xFCAD7436, 0xF151, 0x4110, [0xB9, 0x7E, 0x32, 0xBD, 0x60, 0x7F, 0xBD, 0xB8]};\nconst IID CLSID_CrBlindPP = {0x213052C1, 0x100D, 0x11D2, [0x8B, 0x82, 0x00, 0xA0, 0xC9, 0x3C, 0x09, 0xB2]};\nconst IID CLSID_CrBlinds = {0x00C429C0, 0x0BA9, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_CrBlur = {0x7312498D, 0xE87A, 0x11D1, [0x81, 0xE0, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID CLSID_CrBlurPP = {0x623E287E, 0xFC0E, 0x11D1, [0x9A, 0x77, 0x00, 0x00, 0xF8, 0x75, 0x6A, 0x10]};\nconst IID CLSID_CrEmboss = {0xF515306D, 0x0156, 0x11D2, [0x81, 0xEA, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID CLSID_CrEngrave = {0xF515306E, 0x0156, 0x11D2, [0x81, 0xEA, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID CLSID_CrInset = {0x93073C40, 0x0BA5, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_CrIris = {0x3F69F351, 0x0379, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_CrIrisPP = {0x80DE22C4, 0x0F44, 0x11D2, [0x8B, 0x82, 0x00, 0xA0, 0xC9, 0x3C, 0x09, 0xB2]};\nconst IID CLSID_CrRadialWipe = {0x424B71AF, 0x0695, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_CrRadialWipePP = {0x33D932E0, 0x0F48, 0x11D2, [0x8B, 0x82, 0x00, 0xA0, 0xC9, 0x3C, 0x09, 0xB2]};\nconst IID CLSID_CrSlide = {0x810E402F, 0x056B, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_CrSlidePP = {0xCC8CEDE1, 0x1003, 0x11D2, [0x8B, 0x82, 0x00, 0xA0, 0xC9, 0x3C, 0x09, 0xB2]};\nconst IID CLSID_CrSpiral = {0xACA97E00, 0x0C7D, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_CrSpiralPP = {0xC6A4FE81, 0x1022, 0x11D2, [0x8B, 0x82, 0x00, 0xA0, 0xC9, 0x3C, 0x09, 0xB2]};\nconst IID CLSID_CrStretch = {0x7658F2A2, 0x0A83, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_CrStretchPP = {0x15FB95E0, 0x0F77, 0x11D2, [0x8B, 0x82, 0x00, 0xA0, 0xC9, 0x3C, 0x09, 0xB2]};\nconst IID CLSID_CrWheel = {0x5AE1DAE0, 0x1461, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_CrWheelPP = {0xFA9F6180, 0x1464, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_CrZigzag = {0xE6E73D20, 0x0C8A, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_CrZigzagPP = {0x1559A3C1, 0x102B, 0x11D2, [0x8B, 0x82, 0x00, 0xA0, 0xC9, 0x3C, 0x09, 0xB2]};\nconst IID CLSID_CScriptErrorList = {0xEFD01300, 0x160F, 0x11D2, [0xBB, 0x2E, 0x00, 0x80, 0x5F, 0xF7, 0xEF, 0xCA]};\nconst IID CLSID_CScrollBar = {0x3050F68A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CSliderBar = {0x3050F68E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CSpinButton = {0x3050F68C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CTemplatePrinter = {0x3050F6B3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_CUrlHistory = {0x3C374A40, 0xBAE4, 0x11CF, [0xBF, 0x7D, 0x00, 0xAA, 0x00, 0x69, 0x46, 0xEE]};\nconst IID CLSID_CURLSearchHook = {0xCFBFAE00, 0x17A6, 0x11D0, [0x99, 0xCB, 0x00, 0xC0, 0x4F, 0xD6, 0x44, 0x97]};\nconst IID CLSID_CurrentUserClasses = {0x00000332, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_CUtilityButton = {0x3050F6B0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_d = {0xD34F181F, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_DAArray = {0x9CDE7340, 0x3C20, 0x11D0, [0xA3, 0x30, 0x00, 0xAA, 0x00, 0xB9, 0x2C, 0x03]};\nconst IID CLSID_DABbox2 = {0x50B4791E, 0x4731, 0x11D0, [0x89, 0x12, 0x00, 0xC0, 0x4F, 0xC2, 0xA0, 0xCA]};\nconst IID CLSID_DABbox3 = {0x4A933703, 0xE36F, 0x11D0, [0x9B, 0x99, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID CLSID_DABehavior = {0xC46C1BF2, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DABoolean = {0x25B0F91D, 0xD23D, 0x11D0, [0x9B, 0x85, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID CLSID_DACamera = {0xC46C1BD9, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAColor = {0xC46C1BC9, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DADashStyle = {0x9CADDC0C, 0xAD56, 0x11D1, [0x9F, 0xF8, 0x00, 0xC0, 0x4F, 0xA3, 0x21, 0x95]};\nconst IID CLSID_DAEndStyle = {0xFC54BEAB, 0x5B12, 0x11D1, [0x8E, 0x7B, 0x00, 0xC0, 0x4F, 0xC2, 0x9D, 0x46]};\nconst IID CLSID_DAEvent = {0x3E2487C4, 0x8709, 0x11D0, [0xB1, 0x77, 0x00, 0xC0, 0x4F, 0xC2, 0xA0, 0xCA]};\nconst IID CLSID_DAFontStyle = {0x3F3DA01A, 0x4705, 0x11D0, [0x87, 0x10, 0x00, 0xC0, 0x4F, 0xC2, 0x9D, 0x46]};\nconst IID CLSID_DAGeometry = {0xC46C1BDB, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAImage = {0xC46C1BCB, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAImportationResult = {0x283807B3, 0x2C60, 0x11D0, [0xA3, 0x1D, 0x00, 0xAA, 0x00, 0xB9, 0x2C, 0x03]};\nconst IID CLSID_DAJoinStyle = {0xFC54BEAA, 0x5B12, 0x11D1, [0x8E, 0x7B, 0x00, 0xC0, 0x4F, 0xC2, 0x9D, 0x46]};\nconst IID CLSID_DALineStyle = {0x283807B8, 0x2C60, 0x11D0, [0xA3, 0x1D, 0x00, 0xAA, 0x00, 0xB9, 0x2C, 0x03]};\nconst IID CLSID_DAMatte = {0xC46C1BC3, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAMicrophone = {0xC46C1BE3, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAMontage = {0xC46C1BD7, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DANumber = {0xC46C1BC7, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAPair = {0xBC0BFD34, 0xD21D, 0x11D0, [0x93, 0x85, 0x00, 0xC0, 0x4F, 0xB6, 0xBD, 0x36]};\nconst IID CLSID_DAPath2 = {0xC46C1BCF, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAPickableResult = {0x34F681D0, 0x3640, 0x11CF, [0x92, 0x94, 0x00, 0xAA, 0x00, 0xB8, 0xA7, 0x33]};\nconst IID CLSID_DAPoint2 = {0xC46C1BD5, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAPoint3 = {0xC46C1BE5, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DarwinAppPublisher = {0xCFCCC7A0, 0xA282, 0x11D1, [0x90, 0x82, 0x00, 0x60, 0x08, 0x05, 0x93, 0x82]};\nconst IID CLSID_DASound = {0xC46C1BD1, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAStatics = {0xC46C1BF3, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAString = {0xC46C1BD3, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DataChannel = {0xBBB36F15, 0x408D, 0x4056, [0x8C, 0x27, 0x92, 0x08, 0x43, 0xD4, 0x0B, 0xE5]};\nconst IID CLSID_DATransform2 = {0xC46C1BDF, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DATransform3 = {0xC46C1BC5, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DATuple = {0x283807B7, 0x2C60, 0x11D0, [0xA3, 0x1D, 0x00, 0xAA, 0x00, 0xB9, 0x2C, 0x03]};\nconst IID CLSID_DAUserData = {0x283807B4, 0x2C60, 0x11D0, [0xA3, 0x1D, 0x00, 0xAA, 0x00, 0xB9, 0x2C, 0x03]};\nconst IID CLSID_DAVector2 = {0xC46C1BE1, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAVector3 = {0xC46C1BC0, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAView = {0x960D8EFF, 0xE494, 0x11D1, [0xAB, 0x75, 0x00, 0xC0, 0x4F, 0xD9, 0x2B, 0x6B]};\nconst IID CLSID_DAViewerControl = {0xC46C1BEB, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DAViewerControlWindowed = {0xC46C1BF1, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID CLSID_DCOMAccessControl = {0x0000031D, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_DebugHelper = {0x0BFCC060, 0x8C1D, 0x11D0, [0xAC, 0xCD, 0x00, 0xAA, 0x00, 0x60, 0x27, 0x5C]};\nconst IID CLSID_DeCompMimeFilter = {0x8F6B0360, 0xB80D, 0x11D0, [0xA9, 0xB3, 0x00, 0x60, 0x97, 0x94, 0x23, 0x11]};\nconst IID CLSID_DefaultDebugSessionProvider = {0x834128A2, 0x51F4, 0x11D0, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID CLSID_DirectDraw = {0xD7B70EE0, 0x4340, 0x11CF, [0xB0, 0x63, 0x00, 0x20, 0xAF, 0xC2, 0xCD, 0x35]};\nconst IID CLSID_DirectDrawClipper = {0x593817A0, 0x7DB3, 0x11CF, [0xA2, 0xDE, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56]};\nconst IID CLSID_DirectDrawFactory2 = {0xB9DC4790, 0x4AF1, 0x11D1, [0x8C, 0x4C, 0x00, 0xC0, 0x4F, 0xD9, 0x30, 0xC5]};\nconst IID CLSID_DirectInput = {0x25E609E0, 0xB259, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID CLSID_DirectInputDevice = {0x25E609E1, 0xB259, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID CLSID_DirectMusic = {0x636B9F10, 0x0C7D, 0x11D1, [0x95, 0xB2, 0x00, 0x20, 0xAF, 0xDC, 0x74, 0x21]};\nconst IID CLSID_DirectMusicBand = {0x79BA9E00, 0xB6EE, 0x11D1, [0x86, 0xBE, 0x00, 0xC0, 0x4F, 0xBF, 0x8F, 0xEF]};\nconst IID CLSID_DirectMusicBandTrack = {0xD2AC2894, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicChordMap = {0xD2AC288F, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicChordMapTrack = {0xD2AC2896, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicChordTrack = {0xD2AC288B, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicCollection = {0x480FF4B0, 0x28B2, 0x11D1, [0xBE, 0xF7, 0x00, 0xC0, 0x4F, 0xBF, 0x8F, 0xEF]};\nconst IID CLSID_DirectMusicCommandTrack = {0xD2AC288C, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicComposer = {0xD2AC2890, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicGraph = {0xD2AC2884, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicLoader = {0xD2AC2892, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicMotifTrack = {0xD2AC288E, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicMuteTrack = {0xD2AC2898, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicPerformance = {0xD2AC2881, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicSegment = {0xD2AC2882, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicSegmentState = {0xD2AC2883, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicSeqTrack = {0xD2AC2886, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicSignPostTrack = {0xF17E8672, 0xC3B4, 0x11D1, [0x87, 0x0B, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicStyle = {0xD2AC288A, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicStyleTrack = {0xD2AC288D, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicSynth = {0x58C2B4D0, 0x46E7, 0x11D1, [0x89, 0xAC, 0x00, 0xA0, 0xC9, 0x05, 0x41, 0x29]};\nconst IID CLSID_DirectMusicSysExTrack = {0xD2AC2887, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicTempoTrack = {0xD2AC2885, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectMusicTimeSigTrack = {0xD2AC2888, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID CLSID_DirectPlay = {0xD1EB6D20, 0x8923, 0x11D0, [0x9D, 0x97, 0x00, 0xA0, 0xC9, 0x0A, 0x43, 0xCB]};\nconst IID CLSID_DirectPlayLobby = {0x2FE8F810, 0xB2A5, 0x11D0, [0xA7, 0x87, 0x00, 0x00, 0xF8, 0x03, 0xAB, 0xFC]};\nconst IID CLSID_DirectSound = {0x47D4D946, 0x62E8, 0x11CF, [0x93, 0xBC, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID CLSID_DirectSound8 = {956419135, 33973, 20388, [186, 53, 170, 129, 114, 184, 160, 155]};\nconst IID CLSID_DirectSoundCapture = {0xB0210780, 0x89CD, 0x11D0, [0xAF, 0x08, 0x00, 0xA0, 0xC9, 0x25, 0xCD, 0x16]};\nconst IID CLSID_DirectSoundCapture8 = {3837570067, 32665, 18696, [154, 142, 116, 227, 191, 36, 182, 225]};\nconst IID CLSID_DirectSoundFullDuplex = {4272173068, 31065, 16711, [178, 106, 35, 119, 185, 231, 169, 29]};\nconst IID CLSID_DispatchMapper = {0xE9225296, 0xC759, 0x11D1, [0xA0, 0x2B, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID CLSID_DNWithBinary = {0x7E99C0A3, 0xF935, 0x11D2, [0xBA, 0x96, 0x00, 0xC0, 0x4F, 0xB6, 0xD0, 0xD1]};\nconst IID CLSID_DNWithString = {0x334857CC, 0xF934, 0x11D2, [0xBA, 0x96, 0x00, 0xC0, 0x4F, 0xB6, 0xD0, 0xD1]};\nconst IID CLSID_DocFileColumnProvider = {0x24F14F01, 0x7B1C, 0x11D1, [0x83, 0x8F, 0x00, 0x00, 0xF8, 0x04, 0x61, 0xCF]};\nconst IID CLSID_DocHostUIHandler = {0x7057E952, 0xBD1B, 0x11D1, [0x89, 0x19, 0x00, 0xC0, 0x4F, 0xC2, 0xC8, 0x36]};\nconst IID CLSID_DOMChildrenCollection = {0x3050F5AA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_DOMDocument = {0x2933BF90, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID CLSID_DOMFreeThreadedDocument = {0x2933BF91, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID CLSID_DragDropHelper = {0x4657278A, 0x411B, 0x11D2, [0x83, 0x9A, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xD0]};\nconst IID CLSID_DriveSizeCategorizer = {0x94357B53, 0xCA29, 0x4B78, [0x83, 0xAE, 0xE8, 0xFE, 0x74, 0x09, 0x13, 0x4F]};\nconst IID CLSID_DriveTypeCategorizer = {0xB0A8F3CF, 0x4333, 0x4BAB, [0x88, 0x73, 0x1C, 0xCB, 0x1C, 0xAD, 0xA4, 0x8B]};\nconst IID CLSID_DsDisplaySpecifier = {0x1AB4A8C0, 0x6A0B, 0x11D2, [0xAD, 0x49, 0x00, 0xC0, 0x4F, 0xA3, 0x1A, 0x86]};\nconst IID CLSID_DsDomainTreeBrowser = {0x1698790A, 0xE2B4, 0x11D0, [0xB0, 0xB1, 0x00, 0xC0, 0x4F, 0xD8, 0xDC, 0xA6]};\nconst IID CLSID_DsFindAdvanced = {0x83EE3FE3, 0x57D9, 0x11D0, [0xB9, 0x32, 0x00, 0xA0, 0x24, 0xAB, 0x2D, 0xBB]};\nconst IID CLSID_DsFindComputer = {0x16006700, 0x87AD, 0x11D0, [0x91, 0x40, 0x00, 0xAA, 0x00, 0xC1, 0x6E, 0x65]};\nconst IID CLSID_DsFindContainer = {0xC1B3CBF2, 0x886A, 0x11D0, [0x91, 0x40, 0x00, 0xAA, 0x00, 0xC1, 0x6E, 0x65]};\nconst IID CLSID_DsFindDomainController = {0x538C7B7E, 0xD25E, 0x11D0, [0x97, 0x42, 0x00, 0xA0, 0xC9, 0x06, 0xAF, 0x45]};\nconst IID CLSID_DsFindFrsMembers = {0x94CE4B18, 0xB3D3, 0x11D1, [0xB9, 0xB4, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0xB0]};\nconst IID CLSID_DsFindObjects = {0x83EE3FE1, 0x57D9, 0x11D0, [0xB9, 0x32, 0x00, 0xA0, 0x24, 0xAB, 0x2D, 0xBB]};\nconst IID CLSID_DsFindPeople = {0x83EE3FE2, 0x57D9, 0x11D0, [0xB9, 0x32, 0x00, 0xA0, 0x24, 0xAB, 0x2D, 0xBB]};\nconst IID CLSID_DsFindPrinter = {0xB577F070, 0x7EE2, 0x11D0, [0x91, 0x3F, 0x00, 0xAA, 0x00, 0xC1, 0x6E, 0x65]};\nconst IID CLSID_DsFindVolume = {0xC1B3CBF1, 0x886A, 0x11D0, [0x91, 0x40, 0x00, 0xAA, 0x00, 0xC1, 0x6E, 0x65]};\nconst IID CLSID_DsFolderProperties = {0x9E51E0D0, 0x6E0F, 0x11D2, [0x96, 0x01, 0x00, 0xC0, 0x4F, 0xA3, 0x1A, 0x86]};\nconst IID CLSID_DsPropertyPages = {0x0D45D530, 0x764B, 0x11D0, [0xA1, 0xCA, 0x00, 0xAA, 0x00, 0xC1, 0x6E, 0x65]};\nconst IID CLSID_DsQuery = {0x8A23E65E, 0x31C2, 0x11D0, [0x89, 0x1C, 0x00, 0xA0, 0x24, 0xAB, 0x2D, 0xBB]};\nconst IID CLSID_DWbemClassObject = {0x64AB3751, 0x12BC, 0x11D1, [0x9E, 0x61, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID CLSID_DWbemContext = {0x752FF212, 0xF7B7, 0x11D0, [0x9E, 0x4D, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID CLSID_DWbemLocator = {0xCB7CA032, 0xF729, 0x11D0, [0x9E, 0x4D, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID CLSID_DX2D = {0x473AA80B, 0x4577, 0x11D1, [0x81, 0xA8, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID CLSID_DXFade = {0x16B280C5, 0xEE70, 0x11D1, [0x90, 0x66, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID CLSID_DXGradient = {0xC6365470, 0xF667, 0x11D1, [0x90, 0x67, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID CLSID_DXLUTBuilder = {0x1E54333B, 0x2A00, 0x11D1, [0x81, 0x98, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID CLSID_DXRasterizer = {0x8652CE55, 0x9E80, 0x11D1, [0x90, 0x53, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID CLSID_DXSurface = {0x0E890F83, 0x5F79, 0x11D1, [0x90, 0x43, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID CLSID_DXSurfaceModifier = {0x3E669F1D, 0x9C23, 0x11D1, [0x90, 0x53, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID CLSID_DXTAlpha = {0xADC6CB82, 0x424C, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID CLSID_DXTAlphaImageLoader = {0x0C7EFBDE, 0x0303, 0x4C6F, [0xA4, 0xF7, 0x31, 0xFA, 0x2B, 0xE5, 0xE3, 0x97]};\nconst IID CLSID_DXTAlphaImageLoaderPP = {0x8C80CE2D, 0x850D, 0x47DA, [0x8E, 0xCD, 0x55, 0x02, 0x35, 0x62, 0xD1, 0x67]};\nconst IID CLSID_DXTAlphaPP = {0xD687A7E0, 0x4BA4, 0x11D2, [0x8A, 0xDE, 0x00, 0xA0, 0xC9, 0x8E, 0x65, 0x27]};\nconst IID CLSID_DXTaskManager = {0x4CB26C03, 0xFF93, 0x11D0, [0x81, 0x7E, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID CLSID_DXTBarn = {0xEC9BA17D, 0x60B5, 0x462B, [0xA6, 0xD8, 0x14, 0xB8, 0x90, 0x57, 0xE2, 0x2A]};\nconst IID CLSID_DXTBlinds = {0x9A4A4A51, 0xFB3A, 0x4F4B, [0x9B, 0x57, 0xA2, 0x91, 0x2A, 0x28, 0x97, 0x69]};\nconst IID CLSID_DXTCheckerBoard = {0xB3EE7802, 0x8224, 0x4787, [0xA1, 0xEA, 0xF0, 0xDE, 0x16, 0xDE, 0xAB, 0xD3]};\nconst IID CLSID_DXTCheckerBoardPP = {0xCBF47525, 0x98D2, 0x45EA, [0xB8, 0x43, 0xFD, 0x21, 0x3D, 0x93, 0x2B, 0x10]};\nconst IID CLSID_DXTChroma = {0x421516C1, 0x3CF8, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID CLSID_DXTChromaPP = {0xEC7E0760, 0x4C76, 0x11D2, [0x8A, 0xDE, 0x00, 0xA0, 0xC9, 0x8E, 0x65, 0x27]};\nconst IID CLSID_DXTComposite = {0x9A43A844, 0x0831, 0x11D1, [0x81, 0x7F, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID CLSID_DXTConvolution = {0x2BC0EF29, 0xE6BA, 0x11D1, [0x81, 0xDD, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID CLSID_DXTDropShadow = {0xADC6CB86, 0x424C, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID CLSID_DXTDropShadowPP = {0xEC7E0761, 0x4C76, 0x11D2, [0x8A, 0xDE, 0x00, 0xA0, 0xC9, 0x8E, 0x65, 0x27]};\nconst IID CLSID_DXTFilter = {0x385A91BC, 0x1E8A, 0x4E4A, [0xA7, 0xA6, 0xF4, 0xFC, 0x1E, 0x6C, 0xA1, 0xBD]};\nconst IID CLSID_DXTFilterBehavior = {0x649EEC1E, 0xB579, 0x4E8C, [0xBB, 0x3B, 0x49, 0x97, 0xF8, 0x42, 0x65, 0x36]};\nconst IID CLSID_DXTFilterCollection = {0xA7EE7F34, 0x3BD1, 0x427F, [0x92, 0x31, 0xF9, 0x41, 0xE9, 0xB7, 0xE1, 0xFE]};\nconst IID CLSID_DXTFilterFactory = {0x81397204, 0xF51A, 0x4571, [0x8D, 0x7B, 0xDC, 0x03, 0x05, 0x21, 0xAA, 0xBD]};\nconst IID CLSID_DXTGlow = {0x9F8E6421, 0x3D9B, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID CLSID_DXTGlowPP = {0xEC7E0764, 0x4C76, 0x11D2, [0x8A, 0xDE, 0x00, 0xA0, 0xC9, 0x8E, 0x65, 0x27]};\nconst IID CLSID_DXTGradientD = {0x623E2882, 0xFC0E, 0x11D1, [0x9A, 0x77, 0x00, 0x00, 0xF8, 0x75, 0x6A, 0x10]};\nconst IID CLSID_DXTGradientWipe = {0xB96F67A2, 0x30C2, 0x47E8, [0xBD, 0x85, 0x70, 0xA2, 0xC9, 0x48, 0xB5, 0x0F]};\nconst IID CLSID_DXTICMFilter = {0xA1BFB370, 0x5A9F, 0x4429, [0xBB, 0x72, 0xB1, 0x3E, 0x2F, 0xEA, 0xED, 0xEF]};\nconst IID CLSID_DXTICMFilterPP = {0x1958FB12, 0x31E6, 0x47E5, [0xAA, 0x49, 0xB2, 0x3D, 0x12, 0xC8, 0x53, 0xE6]};\nconst IID CLSID_DXTInset = {0x76F363F2, 0x7E9F, 0x4ED7, [0xA6, 0xA7, 0xEE, 0x30, 0x35, 0x1B, 0x66, 0x28]};\nconst IID CLSID_DXTIris = {0x049F2CE6, 0xD996, 0x4721, [0x89, 0x7A, 0xDB, 0x15, 0xCE, 0x9E, 0xB7, 0x3D]};\nconst IID CLSID_DXTLabel = {0x54702535, 0x2606, 0x11D1, [0x99, 0x9C, 0x00, 0x00, 0xF8, 0x75, 0x6A, 0x10]};\nconst IID CLSID_DXTLight = {0xF9EFBEC2, 0x4302, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID CLSID_DXTLightPP = {0x694AF25F, 0x124D, 0x11D3, [0x91, 0xD5, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID CLSID_DXTMaskFilter = {0x3A04D93B, 0x1EDD, 0x4F3F, [0xA3, 0x75, 0xA0, 0x3E, 0xC1, 0x95, 0x72, 0xC4]};\nconst IID CLSID_DXTMatrix = {0x4ABF5A06, 0x5568, 0x4834, [0xBE, 0xE3, 0x32, 0x7A, 0x6D, 0x95, 0xA6, 0x85]};\nconst IID CLSID_DXTMatrixPP = {0xC591103A, 0xB3A8, 0x4D47, [0xA3, 0xF7, 0x2A, 0xEE, 0xE4, 0xB8, 0x01, 0x3F]};\nconst IID CLSID_DXTMetaBurnFilm = {0x107045D1, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaCenterPeel = {0xAA0D4D0C, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID CLSID_DXTMetaColorFade = {0x2A54C908, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaFlowMotion = {0x2A54C90B, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaGriddler = {0x2A54C911, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaGriddler2 = {0x2A54C913, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaJaws = {0x2A54C904, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaLightWipe = {0x107045C8, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaLiquid = {0xAA0D4D0A, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID CLSID_DXTMetaPageTurn = {0xAA0D4D08, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID CLSID_DXTMetaPeelPiece = {0xAA0D4D10, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID CLSID_DXTMetaPeelSmall = {0xAA0D4D0E, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID CLSID_DXTMetaPeelSplit = {0xAA0D4D12, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID CLSID_DXTMetaRadialScaleWipe = {0x107045CA, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaRipple = {0xAA0D4D03, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID CLSID_DXTMetaRoll = {0x9C61F46E, 0x0530, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID CLSID_DXTMetaThreshold = {0x2A54C915, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaTwister = {0x107045CF, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaVacuum = {0x2A54C90D, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaWater = {0x107045C5, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaWhiteOut = {0x107045CC, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID CLSID_DXTMetaWormHole = {0x0E6AE022, 0x0C83, 0x11D2, [0x8C, 0xD4, 0x00, 0x10, 0x4B, 0xC7, 0x5D, 0x9A]};\nconst IID CLSID_DXTMotionBlur = {0xDD13DE77, 0xD3BA, 0x42D4, [0xB5, 0xC6, 0x77, 0x45, 0xFA, 0x4E, 0x2D, 0x4B]};\nconst IID CLSID_DXTMotionBlurPP = {0x926433E1, 0x7F8F, 0x4BC6, [0xBE, 0xC4, 0x8C, 0x12, 0x6C, 0x6B, 0x7D, 0xC4]};\nconst IID CLSID_DXTRadialWipe = {0x164484A9, 0x35D9, 0x4FB7, [0x9F, 0xAB, 0x48, 0x27, 0x3B, 0x96, 0xAA, 0x1D]};\nconst IID CLSID_DXTRandomBars = {0x2E7700B7, 0x27C4, 0x437F, [0x9F, 0xBF, 0x1E, 0x8B, 0xE2, 0x81, 0x75, 0x66]};\nconst IID CLSID_DXTRandomBarsPP = {0xE3E6AE11, 0x7FDC, 0x40C4, [0xAF, 0xBF, 0x1D, 0xCE, 0xA8, 0x28, 0x62, 0xCC]};\nconst IID CLSID_DXTRandomDissolve = {0xF7F4A1B6, 0x8E87, 0x452F, [0xA2, 0xD7, 0x30, 0x77, 0xF5, 0x08, 0xDB, 0xC0]};\nconst IID CLSID_DXTransformFactory = {0xD1FE6762, 0xFC48, 0x11D0, [0x88, 0x3A, 0x3C, 0x8B, 0x00, 0xC1, 0x00, 0x00]};\nconst IID CLSID_DXTRedirect = {0x42B07B28, 0x2280, 0x4937, [0xB0, 0x35, 0x02, 0x93, 0xFB, 0x81, 0x27, 0x81]};\nconst IID CLSID_DXTRevealTrans = {0xE31E87C4, 0x86EA, 0x4940, [0x9B, 0x8A, 0x5B, 0xD5, 0xD1, 0x79, 0xA7, 0x37]};\nconst IID CLSID_DXTScale = {0x555278E2, 0x05DB, 0x11D1, [0x88, 0x3A, 0x3C, 0x8B, 0x00, 0xC1, 0x00, 0x00]};\nconst IID CLSID_DXTShadow = {0xE71B4063, 0x3E59, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID CLSID_DXTShadowPP = {0xEC7E0765, 0x4C76, 0x11D2, [0x8A, 0xDE, 0x00, 0xA0, 0xC9, 0x8E, 0x65, 0x27]};\nconst IID CLSID_DXTSlide = {0xD1C5A1E7, 0xCC47, 0x4E32, [0xBD, 0xD2, 0x4B, 0x3C, 0x5F, 0xC5, 0x0A, 0xF5]};\nconst IID CLSID_DXTSpiral = {0x4A03DCB9, 0x6E17, 0x4A39, [0x88, 0x45, 0x4E, 0xE7, 0xDC, 0x53, 0x31, 0xA5]};\nconst IID CLSID_DXTStretch = {0xF088DE73, 0xBDD0, 0x4E3C, [0x81, 0xF8, 0x6D, 0x32, 0xF4, 0xFE, 0x9D, 0x28]};\nconst IID CLSID_DXTStrips = {0x63A4B1FC, 0x259A, 0x4A5B, [0x81, 0x29, 0xA8, 0x3B, 0x8C, 0x9E, 0x6F, 0x4F]};\nconst IID CLSID_DXTStripsPP = {0xFEC0B7EE, 0x7AEC, 0x4067, [0x9E, 0xE1, 0xFA, 0xCF, 0xB7, 0xCE, 0x9A, 0xF9]};\nconst IID CLSID_DXTWave = {0xADC6CB88, 0x424C, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID CLSID_DXTWavePP = {0xF12456C0, 0x4C9E, 0x11D2, [0x8A, 0xDE, 0x00, 0xA0, 0xC9, 0x8E, 0x65, 0x27]};\nconst IID CLSID_DXTWipe = {0xAF279B30, 0x86EB, 0x11D1, [0x81, 0xBF, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID CLSID_DXTWipePP = {0x7FFE4D08, 0xFBFD, 0x11D1, [0x9A, 0x77, 0x00, 0x00, 0xF8, 0x75, 0x6A, 0x10]};\nconst IID CLSID_DXTZigzag = {0x23E26328, 0x3928, 0x40F2, [0x95, 0xE5, 0x93, 0xCA, 0xD6, 0x90, 0x16, 0xEB]};\nconst IID CLSID_EAPOLManager = {0xBA126AE4, 0x2166, 0x11D1, [0xB1, 0xD0, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID CLSID_Email = {0x8F92A857, 0x478E, 0x11D1, [0xA3, 0xB4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_EnumAdapterInfo = {0x6F9942CA, 0xC1B1, 0x4AB5, [0x93, 0xDA, 0x60, 0x58, 0x99, 0x1D, 0xC8, 0xF3]};\nconst IID CLSID_EVENTQUEUE = {0x6E0FF466, 0x339E, 0x11D1, [0xBE, 0x5B, 0x00, 0xC0, 0x4F, 0xC9, 0xE2, 0xBB]};\nconst IID CLSID_EXTENDEDERRORINFO = {0xC8B522CF, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID CLSID_FadePP = {0x16B280C6, 0xEE70, 0x11D1, [0x90, 0x66, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID CLSID_FaxNumber = {0xA5062215, 0x4681, 0x11D1, [0xA3, 0xB4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_FilePlaybackTerminal = {0x0CB9914C, 0x79CD, 0x47DC, [0xAD, 0xB0, 0x32, 0x7F, 0x47, 0xCE, 0xFB, 0x20]};\nconst IID CLSID_FileProtocol = {0x79EAC9E7, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_FileRecordingTerminal = {0x521F3D06, 0xC3D0, 0x4511, [0x86, 0x17, 0x86, 0xB9, 0xA7, 0x83, 0xDA, 0x77]};\nconst IID CLSID_FileRecordingTrack = {0xBF14A2E4, 0xE88B, 0x4EF5, [0x97, 0x40, 0x5A, 0xC5, 0xD0, 0x22, 0xF8, 0xC9]};\nconst IID CLSID_FileSearchBand = {0xC4EE31F3, 0x4768, 0x11D2, [0xBE, 0x5C, 0x00, 0xA0, 0xC9, 0xA8, 0x3D, 0xA1]};\nconst IID CLSID_FileSysColumnProvider = {0x0D2E74C4, 0x3C34, 0x11D2, [0xA2, 0x7E, 0x00, 0xC0, 0x4F, 0xC3, 0x08, 0x71]};\nconst IID CLSID_FileTerminal = {0xAAF578F1, 0xDC70, 0x11D0, [0x8E, 0xD3, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID CLSID_FolderShortcut = {0x0AFACED1, 0xE828, 0x11D1, [0x91, 0x87, 0xB5, 0x32, 0xF1, 0xE9, 0x57, 0x5D]};\nconst IID CLSID_FolderViewHost = {0x20B1CB23, 0x6968, 0x4EB9, [0xB7, 0xD4, 0xA6, 0x6D, 0x00, 0xD0, 0x7C, 0xEE]};\nconst IID CLSID_FontNames = {0x3050F83A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_FramesCollection = {0x3050F7F6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_FreeSpaceCategorizer = {0xB5607793, 0x24AC, 0x44C7, [0x82, 0xE2, 0x83, 0x17, 0x26, 0xAA, 0x6C, 0xB7]};\nconst IID CLSID_FtpProtocol = {0x79EAC9E3, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_GblComponentCategoriesMgr = {0x0002E006, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_GLOBAL_BROADCAST = {0xD34F1810, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_GopherProtocol = {0x79EAC9E4, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_GradientPP = {0x623E2880, 0xFC0E, 0x11D1, [0x9A, 0x77, 0x00, 0x00, 0xF8, 0x75, 0x6A, 0x10]};\nconst IID CLSID_HandsetTerminal = {0xAAF578EB, 0xDC70, 0x11D0, [0x8E, 0xD3, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID CLSID_HeadsetTerminal = {0xAAF578ED, 0xDC70, 0x11D0, [0x8E, 0xD3, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID CLSID_HNetCfgMgr = {0x46C166AA, 0x3108, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID CLSID_Hold = {0xB3AD3E13, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_HomeNetAutoConfigService = {0x9A8EA3B5, 0x572E, 0x4CB3, [0x9E, 0xB9, 0xEC, 0x68, 0x9A, 0xC5, 0x75, 0xAE]};\nconst IID CLSID_HomePage = {0x766BF2AE, 0xD650, 0x11D1, [0x98, 0x11, 0x00, 0xC0, 0x4F, 0xC3, 0x1D, 0x2E]};\nconst IID CLSID_HostDialogHelper = {0x429AF92C, 0xA51F, 0x11D2, [0x86, 0x1E, 0x00, 0xC0, 0x4F, 0xA3, 0x5C, 0x89]};\nconst IID CLSID_HTADocument = {0x3050F5C8, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTCAttachBehavior = {0x3050F5F5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTCDefaultDispatch = {0x3050F4FC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTCDescBehavior = {0x3050F5DD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTCEventBehavior = {0x3050F4FE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTCMethodBehavior = {0x3050F630, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTCPropertyBehavior = {0x3050F5DE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLAnchorElement = {0x3050F248, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLAppBehavior = {0x3050F5CB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLApplication = {0x3050F4D8, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLAreaElement = {0x3050F283, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLAreasCollection = {0x3050F4CA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLAttributeCollection = {0x3050F4CC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLBaseElement = {0x3050F276, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLBaseFontElement = {0x3050F282, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLBGsound = {0x3050F370, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLBlockElement = {0x3050F281, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLBody = {0x3050F24A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLBRElement = {0x3050F280, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLButtonElement = {0x3050F2C6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLCommentElement = {0x3050F317, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLCurrentStyle = {0x3050F3DC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLDDElement = {0x3050F27F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLDefaults = {0x3050F6C8, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLDialog = {0x3050F28A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLDivElement = {0x3050F27E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLDivPosition = {0x3050F249, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HtmlDlgSafeHelper = {0x3050F819, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLDListElement = {0x3050F27D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLDocument = {0x25336920, 0x03F9, 0x11CF, [0x8F, 0xD0, 0x00, 0xAA, 0x00, 0x68, 0x6F, 0x13]};\nconst IID CLSID_HTMLDOMAttribute = {0x3050F4B2, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLDOMImplementation = {0x3050F80E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLDOMTextNode = {0x3050F4BA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLDTElement = {0x3050F27C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLElementCollection = {0x3050F4CB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLEmbed = {0x3050F25D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLFieldSetElement = {0x3050F3E8, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLFontElement = {0x3050F27B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLFormElement = {0x3050F251, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLFrameBase = {0x3050F312, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLFrameElement = {0x3050F314, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLFrameSetSite = {0x3050F31A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLGenericElement = {0x3050F4B8, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLHeadElement = {0x3050F493, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLHeaderElement = {0x3050F27A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLHistory = {0xFECEAAA3, 0x8405, 0x11CF, [0x8B, 0xA1, 0x00, 0xAA, 0x00, 0x47, 0x6D, 0xA6]};\nconst IID CLSID_HTMLHRElement = {0x3050F252, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLHtmlElement = {0x3050F491, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLIFrame = {0x3050F316, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLImageElementFactory = {0x3050F38F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLImg = {0x3050F241, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLInputButtonElement = {0x3050F2B4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLInputElement = {0x3050F5D8, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLInputFileElement = {0x3050F2AE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLInputImage = {0x3050F2C4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLInputTextElement = {0x3050F2AB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLIsIndexElement = {0x3050F278, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLLabelElement = {0x3050F32B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLLegendElement = {0x3050F3E9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLLIElement = {0x3050F273, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLLinkElement = {0x3050F277, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLListElement = {0x3050F272, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLLoadOptions = {0x18845040, 0x0FA5, 0x11D1, [0xBA, 0x19, 0x00, 0xC0, 0x4F, 0xD9, 0x12, 0xD0]};\nconst IID CLSID_HTMLLocation = {0x163BB1E1, 0x6E00, 0x11CF, [0x83, 0x7A, 0x48, 0xDC, 0x04, 0xC1, 0x00, 0x00]};\nconst IID CLSID_HTMLMapElement = {0x3050F271, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLMarqueeElement = {0x3050F2B9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLMetaElement = {0x3050F275, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLNamespace = {0x3050F6BC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLNamespaceCollection = {0x3050F6B9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLNavigator = {0xFECEAAA6, 0x8405, 0x11CF, [0x8B, 0xA1, 0x00, 0xAA, 0x00, 0x47, 0x6D, 0xA6]};\nconst IID CLSID_HTMLNextIdElement = {0x3050F279, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLNoShowElement = {0x3050F38B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLObjectElement = {0x3050F24E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLOListElement = {0x3050F270, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLOptionButtonElement = {0x3050F2BE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLOptionElement = {0x3050F24D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLOptionElementFactory = {0x3050F38D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLParaElement = {0x3050F26F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLParamElement = {0x3050F83E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLPhraseElement = {0x3050F26E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLPluginDocument = {0x25336921, 0x03F9, 0x11CF, [0x8F, 0xD0, 0x00, 0xAA, 0x00, 0x68, 0x6F, 0x13]};\nconst IID CLSID_HTMLPopup = {0x3050F667, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLRenderStyle = {0x3050F6AA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLRichtextElement = {0x3050F2DF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLRuleStyle = {0x3050F3D0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLScreen = {0x3050F35D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLScriptElement = {0x3050F28C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLSelectElement = {0x3050F245, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLSpanElement = {0x3050F3F5, 0x98B4, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLSpanFlow = {0x3050F3E6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLStyle = {0x3050F285, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLStyleElement = {0x3050F37D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLStyleFontFace = {0x3050F3D4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLStyleSheet = {0x3050F2E4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLStyleSheetPage = {0x3050F7EF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLStyleSheetPagesCollection = {0x3050F7F1, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLStyleSheetRule = {0x3050F3CE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLStyleSheetRulesCollection = {0x3050F3CD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLStyleSheetsCollection = {0x3050F37F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLTable = {0x3050F26B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLTableCaption = {0x3050F2EC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLTableCell = {0x3050F246, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLTableCol = {0x3050F26C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLTableRow = {0x3050F26D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLTableSection = {0x3050F2E9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLTextAreaElement = {0x3050F2AC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLTextElement = {0x3050F26A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLTitleElement = {0x3050F284, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLUListElement = {0x3050F269, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLUnknownElement = {0x3050F268, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLUrnCollection = {0x3050F580, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HTMLWindow2 = {0xD48A6EC6, 0x6A4A, 0x11CF, [0x94, 0xA7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID CLSID_HTMLWindowProxy = {0x3050F391, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_HttpProtocol = {0x79EAC9E2, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_HttpSProtocol = {0x79EAC9E5, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_HWShellExecute = {0xFFB8655F, 0x81B9, 0x4FCE, [0xB8, 0x9C, 0x9A, 0x6B, 0xA7, 0x6D, 0x13, 0xE7]};\nconst IID CLSID_IActiveXSafetyProvider = {0xAAF8C6CE, 0xF972, 0x11D0, [0x97, 0xEB, 0x00, 0xAA, 0x00, 0x61, 0x53, 0x33]};\nconst IID CLSID_IImageDecodeFilter = {0x607FD4E8, 0x0A03, 0x11D1, [0xAB, 0x1D, 0x00, 0xC0, 0x4F, 0xC9, 0xB3, 0x04]};\nconst IID CLSID_IImgCtx = {0x3050F3D6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_ImageList = {0x7C476BA2, 0x02B1, 0x48F4, [0x80, 0x48, 0xB2, 0x46, 0x19, 0xDD, 0xC0, 0x58]};\nconst IID CLSID_ImageProperties = {0x7AB770C7, 0x0E23, 0x4D7A, [0x8A, 0xA2, 0x19, 0xBF, 0xAD, 0x47, 0x98, 0x29]};\nconst IID CLSID_InProcFreeMarshaler = {0x0000033A, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_IntDitherer = {0x05F6FE1A, 0xECEF, 0x11D0, [0xAA, 0xE7, 0x00, 0xC0, 0x4F, 0xC9, 0xB3, 0x04]};\nconst IID CLSID_IntelliForms = {0x613AB92E, 0x16BF, 0x11D2, [0xBC, 0xA5, 0x00, 0xC0, 0x4F, 0xD9, 0x29, 0xDB]};\nconst IID CLSID_Internet = {0x871C5380, 0x42A0, 0x1069, [0xA2, 0xEA, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D]};\nconst IID CLSID_InternetButtons = {0x1E796980, 0x9CC5, 0x11D1, [0xA8, 0x3F, 0x00, 0xC0, 0x4F, 0xC9, 0x9D, 0x61]};\nconst IID CLSID_InternetConnectionBeaconServic = {0x04DF613A, 0x5610, 0x11D4, [0x9E, 0xC8, 0x00, 0xB0, 0xD0, 0x22, 0xDD, 0x1F]};\nconst IID CLSID_InternetExplorer = {0x0002DF01, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_InternetPrintOrdering = {0xADD36AA8, 0x751A, 0x4579, [0xA2, 0x66, 0xD6, 0x6F, 0x52, 0x02, 0xCC, 0xBB]};\nconst IID CLSID_InternetSecurityManager = {0x7B8A2D94, 0x0AC9, 0x11D1, [0x89, 0x6C, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4]};\nconst IID CLSID_InternetShortcut = {0xFBF23B40, 0xE3F0, 0x101B, [0x84, 0x88, 0x00, 0xAA, 0x00, 0x3E, 0x56, 0xF8]};\nconst IID CLSID_InternetZoneManager = {0x7B8A2D95, 0x0AC9, 0x11D1, [0x89, 0x6C, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4]};\nconst IID CLSID_LanConnectionManager = {0xBA126AD3, 0x2166, 0x11D1, [0xB1, 0xD0, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID CLSID_LargeInteger = {0x927971F5, 0x0939, 0x11D1, [0x8B, 0xE1, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID CLSID_LDAPConnectionObject = {0x7DA2A9C4, 0x0C46, 0x43BD, [0xB0, 0x4E, 0xD9, 0x2B, 0x1B, 0xE2, 0x7C, 0x45]};\nconst IID CLSID_LDAPObject = {0x05709878, 0x5195, 0x466C, [0x9E, 0x64, 0x48, 0x7C, 0xE3, 0xCA, 0x20, 0xBF]};\nconst IID CLSID_LinkColumnProvider = {0x24F14F02, 0x7B1C, 0x11D1, [0x83, 0x8F, 0x00, 0x00, 0xF8, 0x04, 0x61, 0xCF]};\nconst IID CLSID_LocalMachineClasses = {0x00000331, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_LogManager = {0x8FDA8FA4, 0x8763, 0x479F, [0xB9, 0xB1, 0x22, 0x02, 0xB2, 0x80, 0xD2, 0x93]};\nconst IID CLSID_LUTBuilderPP = {0x25B33662, 0xFD83, 0x11D1, [0x8A, 0xDE, 0x44, 0x45, 0x53, 0x54, 0x00, 0x01]};\nconst IID CLSID_MachineDebugManager = {0x0C0A3666, 0x30C9, 0x11D0, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID CLSID_MailAutoDiscovery = {0x008FD5DD, 0x6DBB, 0x48E3, [0x99, 0x1B, 0x2D, 0x3E, 0xD6, 0x58, 0x51, 0x6A]};\nconst IID CLSID_MailProtocolADEntry = {0x61A5D6F3, 0xC131, 0x4C35, [0xBF, 0x40, 0x90, 0xA5, 0x0F, 0x21, 0x41, 0x22]};\nconst IID CLSID_ManualResetEvent = {0x0000032C, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_McastAddressAllocation = {0xDF0DAEF2, 0xA289, 0x11D1, [0x86, 0x97, 0x00, 0x60, 0x08, 0xB0, 0xE5, 0xD2]};\nconst IID CLSID_MediaStreamTerminal = {0xE2F7AEF7, 0x4971, 0x11D1, [0xA6, 0x71, 0x00, 0x60, 0x97, 0xC9, 0xA2, 0xE8]};\nconst IID CLSID_MergedCategorizer = {0x8E827C11, 0x33E7, 0x4BC1, [0xB2, 0x42, 0x8C, 0xD9, 0xA1, 0xC2, 0xB3, 0x04]};\nconst IID CLSID_MHTMLDocument = {0x3050F3D9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_MicrophoneTerminal = {0xAAF578EF, 0xDC70, 0x11D0, [0x8E, 0xD3, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID CLSID_MicrosoftDS = {0xFE1290F0, 0xCFBD, 0x11CF, [0xA3, 0x30, 0x00, 0xAA, 0x00, 0xC1, 0x6E, 0x65]};\nconst IID CLSID_MigrationWizardAuto = {0x67331D85, 0xBE17, 0x42F6, [0x8D, 0x3F, 0x47, 0xB8, 0xE8, 0xB2, 0x66, 0x37]};\nconst IID CLSID_MkProtocol = {0x79EAC9E6, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_MofCompiler = {0x6DAF9757, 0x2E37, 0x11D2, [0xAE, 0xC9, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID CLSID_MountedVolume = {0x12518493, 0x00B2, 0x11D2, [0x9F, 0xA5, 0x9E, 0x34, 0x20, 0x52, 0x41, 0x53]};\nconst IID CLSID_MSBurnEngineObj = {0x520CCA67, 0x51A5, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID CLSID_MSDATT = {0xC8B522CE, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID CLSID_MSDAVTM = {0x0C733A8E, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID CLSID_MSDiscMasterObj = {0x520CCA63, 0x51A5, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID CLSID_MSDiscRecorderObj = {0x520CCA61, 0x51A5, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID CLSID_MSDiscStashObj = {0x520CCA65, 0x51A5, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID CLSID_MSEnumDiscRecordersObj = {0x8A03567A, 0x63CB, 0x4BA8, [0xBA, 0xF6, 0x52, 0x11, 0x98, 0x16, 0xD1, 0xEF]};\nconst IID CLSID_MSOButtons = {0x178F34B8, 0xA282, 0x11D2, [0x86, 0xC5, 0x00, 0xC0, 0x4F, 0x8E, 0xEA, 0x99]};\nconst IID CLSID_MyComputer = {0x20D04FE0, 0x3AEA, 0x1069, [0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D]};\nconst IID CLSID_MyDocuments = {0x450D8FBA, 0xAD25, 0x11D0, [0x98, 0xA8, 0x08, 0x00, 0x36, 0x1B, 0x11, 0x03]};\nconst IID CLSID_NameTranslate = {0x274FAE1F, 0x3626, 0x11D1, [0xA3, 0xA4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_NetAddress = {0xB0B71247, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_NetConnectionHNetUtil = {0xBA126AE3, 0x2166, 0x11D1, [0xB1, 0xD0, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID CLSID_NetConnectionUiUtilities = {0x7007ACD3, 0x3202, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID CLSID_NetCrawler = {0x601AC3DC, 0x786A, 0x4EB0, [0xBF, 0x40, 0xEE, 0x35, 0x21, 0xE7, 0x0B, 0xFB]};\nconst IID CLSID_NetSharingManager = {0x5C63C1AD, 0x3956, 0x4FF8, [0x84, 0x86, 0x40, 0x03, 0x47, 0x58, 0x31, 0x5B]};\nconst IID CLSID_NetworkDomain = {0x46E06680, 0x4BF0, 0x11D1, [0x83, 0xEE, 0x00, 0xA0, 0xC9, 0x0D, 0xC8, 0x49]};\nconst IID CLSID_NetworkPlaces = {0x208D2C60, 0x3AEA, 0x1069, [0xA2, 0xD7, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D]};\nconst IID CLSID_NetworkServer = {0xC0542A90, 0x4BF0, 0x11D1, [0x83, 0xEE, 0x00, 0xA0, 0xC9, 0x0D, 0xC8, 0x49]};\nconst IID CLSID_NetworkShare = {0x54A754C0, 0x4BF0, 0x11D1, [0x83, 0xEE, 0x00, 0xA0, 0xC9, 0x0D, 0xC8, 0x49]};\nconst IID CLSID_NetworkType = {0xD4F3D51B, 0x1755, 0x4953, [0x9C, 0x8B, 0x24, 0x95, 0xAB, 0xE5, 0xE0, 0x7E]};\nconst IID CLSID_NodeType = {0x1AAA3D11, 0x4792, 0x44E4, [0x9D, 0x49, 0x78, 0xFE, 0xD3, 0x69, 0x1A, 0x14]};\nconst IID CLSID_NotificaitonTest1 = {0xC733E501, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_NotificaitonTest2 = {0xC733E502, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_NotificaitonTest3 = {0xC733E503, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_NotificaitonTest4 = {0xC733E504, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_NotificationManager = {0xE1813DD0, 0xAADA, 0x4738, [0xB5, 0xFF, 0x96, 0xB4, 0x18, 0x9C, 0x50, 0x19]};\nconst IID CLSID_ObjectManager = {0x955661BD, 0xCCA2, 0x4EAC, [0x91, 0xD0, 0xA0, 0x39, 0x6A, 0x28, 0xAE, 0xFD]};\nconst IID CLSID_OctetList = {0x1241400F, 0x4680, 0x11D1, [0xA3, 0xB4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_OldHTMLDocument = {0xD48A6EC9, 0x6A4A, 0x11CF, [0x94, 0xA7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID CLSID_OldHTMLFormElement = {0x0D04D285, 0x6BEC, 0x11CF, [0x8B, 0x97, 0x00, 0xAA, 0x00, 0x47, 0x6D, 0xA6]};\nconst IID CLSID_OLEDB_CONVERSIONLIBRARY = {0xC8B522D1, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID CLSID_OLEDB_ENUMERATOR = {0xC8B522D0, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID CLSID_OLEDB_ROWPOSITIONLIBRARY = {0x2048EEE6, 0x7FA2, 0x11D0, [0x9E, 0x6A, 0x00, 0xA0, 0xC9, 0x13, 0x8C, 0x29]};\nconst IID CLSID_PassportClientServices = {0x2D2307C8, 0x7DB4, 0x40D6, [0x91, 0x00, 0xD5, 0x2A, 0xF4, 0xF9, 0x7A, 0x5B]};\nconst IID CLSID_Path = {0xB2538919, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_Pathname = {0x080D0D78, 0xF421, 0x11D0, [0xA3, 0x6E, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_PeerFactory = {0x3050F4CF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_PendingProxyConnection = {0xD8A68E5E, 0x2B37, 0x426C, [0xA3, 0x29, 0xC1, 0x17, 0xC1, 0x4C, 0x42, 0x9E]};\nconst IID CLSID_PersistentDataChannel = {0xBC9B54AB, 0x7883, 0x4C13, [0x90, 0x9F, 0x03, 0x3D, 0x03, 0x26, 0x79, 0x90]};\nconst IID CLSID_PersistPropset = {0xFB8F0821, 0x0164, 0x101B, [0x84, 0xED, 0x08, 0x00, 0x2B, 0x2E, 0xC7, 0x13]};\nconst IID CLSID_Picture_Dib = {0x00000316, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_Picture_EnhMetafile = {0x00000319, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_Picture_Metafile = {0x00000315, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_Pixelate = {0x4CCEA634, 0xFBE0, 0x11D1, [0x90, 0x6A, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID CLSID_PixelatePP = {0x4CCEA635, 0xFBE0, 0x11D1, [0x90, 0x6A, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID CLSID_PluggableSuperclassRegistratio = {0xBB918E32, 0x2A5C, 0x4986, [0xAB, 0x40, 0x16, 0x86, 0xA0, 0x34, 0x39, 0x0A]};\nconst IID CLSID_PluggableTerminalRegistration = {0x45234E3E, 0x61CC, 0x4311, [0xA3, 0xAB, 0x24, 0x80, 0x82, 0x55, 0x44, 0x82]};\nconst IID CLSID_PostAgent = {0xD8BD2030, 0x6FC9, 0x11D0, [0x86, 0x4F, 0x00, 0xAA, 0x00, 0x68, 0x09, 0xD9]};\nconst IID CLSID_PostalAddress = {0x0A75AFCD, 0x4680, 0x11D1, [0xA3, 0xB4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_PrimaryControlChannel = {0x3CEB5509, 0xC1CD, 0x432F, [0x9D, 0x8F, 0x65, 0xD1, 0xE2, 0x86, 0xAA, 0x80]};\nconst IID CLSID_Printers = {0x2227A280, 0x3AEA, 0x1069, [0xA2, 0xDE, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D]};\nconst IID CLSID_PROCESS_BROADCAST = {0xD34F1811, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_ProcessDebugManager = {0x78A51822, 0x51F4, 0x11D0, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID CLSID_ProgressDialog = {0xF8383852, 0xFCD3, 0x11D1, [0xA6, 0xB9, 0x00, 0x60, 0x97, 0xDF, 0x5B, 0xD4]};\nconst IID CLSID_PropertiesUI = {0xD912F8CF, 0x0396, 0x4915, [0x88, 0x4E, 0xFB, 0x42, 0x5D, 0x32, 0x94, 0x3B]};\nconst IID CLSID_PropertyEntry = {0x72D3EDC2, 0xA4C4, 0x11D0, [0x85, 0x33, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID CLSID_PropertyValue = {0x7B9E38B0, 0xA97C, 0x11D0, [0x85, 0x34, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID CLSID_PSBindCtx = {0x00000312, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_PSClassObject = {0x0000030E, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_PSClientSite = {0x0000030D, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_PSDragDrop = {0x00000311, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_PSEnumerators = {0x00000313, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_PseudoSink = {0xE002E4F0, 0xE6EA, 0x11D2, [0x9C, 0xB3, 0x00, 0x10, 0x5A, 0x1F, 0x48, 0x01]};\nconst IID CLSID_PSGenObject = {0x0000030C, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_PSInPlaceActive = {0x0000030F, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_PSInPlaceFrame = {0x00000310, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_PSUrlMonProxy = {0x79EAC9F1, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_PublishDropTarget = {0xCC6EEFFB, 0x43F6, 0x46C5, [0x96, 0x19, 0x51, 0xD5, 0x71, 0x96, 0x7F, 0x7D]};\nconst IID CLSID_PublishingWizard = {0x6B33163C, 0x76A5, 0x4B6C, [0xBF, 0x21, 0x45, 0xDE, 0x9C, 0xD5, 0x03, 0xA1]};\nconst IID CLSID_QueryAssociations = {0xA07034FD, 0x6CAA, 0x4954, [0xAC, 0x3F, 0x97, 0xA2, 0x72, 0x16, 0xF9, 0x8A]};\nconst IID CLSID_QueryCancelAutoPlay = {0x331F1768, 0x05A9, 0x4DDD, [0xB8, 0x6E, 0xDA, 0xE3, 0x4D, 0xDC, 0x99, 0x8A]};\nconst IID CLSID_RecycleBin = {0x645FF040, 0x5081, 0x101B, [0x9F, 0x08, 0x00, 0xAA, 0x00, 0x2F, 0x95, 0x4E]};\nconst IID CLSID_RemoteUnknownPSFactory = {0x00000340, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_Rendezvous = {0xF1029E5B, 0xCB5B, 0x11D0, [0x8D, 0x59, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID CLSID_ReplicaPointer = {0xF5D1BADF, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_Request = {0x6BC096B1, 0x0CE6, 0x11D1, [0xBA, 0xAE, 0x00, 0xC0, 0x4F, 0xC2, 0xE2, 0x0D]};\nconst IID CLSID_RequestMakeCall = {0xAC48FFE0, 0xF8C4, 0x11D1, [0xA0, 0x30, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID CLSID_ResProtocol = {0x3050F3BC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_RTCClient = {0x7A42EA29, 0xA2B7, 0x40C4, [0xB0, 0x91, 0xF6, 0xF0, 0x24, 0xAA, 0x89, 0xBE]};\nconst IID CLSID_Scriptlet = {0xAE24FDAE, 0x03C6, 0x11D1, [0x8B, 0x76, 0x00, 0x80, 0xC7, 0x44, 0xF3, 0x89]};\nconst IID CLSID_SdoMachine = {0xE9218AE7, 0x9E91, 0x11D1, [0xBF, 0x60, 0x00, 0x80, 0xC7, 0x84, 0x6B, 0xC0]};\nconst IID CLSID_SdpConferenceBlob = {0x9B2719DD, 0xB696, 0x11D0, [0xA4, 0x89, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID CLSID_SearchAssistantOC = {0xB45FF030, 0x4447, 0x11D2, [0x85, 0xDE, 0x00, 0xC0, 0x4F, 0xA3, 0x5C, 0x89]};\nconst IID CLSID_SearchCommand = {0xB005E690, 0x678D, 0x11D1, [0xB7, 0x58, 0x00, 0xA0, 0xC9, 0x05, 0x64, 0xFE]};\nconst IID CLSID_SecondaryControlChannel = {0x7B3181A0, 0xC92F, 0x4567, [0xB0, 0xFA, 0xCD, 0x9A, 0x10, 0xEC, 0xD7, 0xD1]};\nconst IID CLSID_SecurityDescriptor = {0xB958F73C, 0x9BDD, 0x11D0, [0x85, 0x2C, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID CLSID_SENS = {0xD597CAFE, 0x5B9F, 0x11D1, [0x8D, 0xD2, 0x00, 0xAA, 0x00, 0x4A, 0xBD, 0x5E]};\nconst IID CLSID_ServiceManager = {0xABD0388A, 0xDEC1, 0x44F3, [0x98, 0xE1, 0x8D, 0x5C, 0xC8, 0x0B, 0x97, 0xEB]};\nconst IID CLSID_SharingApplicationDefinition = {0x46C166B0, 0x3108, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID CLSID_SharingConfiguration = {0x46C166B1, 0x3108, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID CLSID_SharingManagerEnumApplicationDe = {0x46C166AE, 0x3108, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID CLSID_SharingManagerEnumPortMapping = {0x46C166AF, 0x3108, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID CLSID_SharingManagerEnumPrivateConnec = {0x46C166AD, 0x3108, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID CLSID_SharingManagerEnumPublicConnect = {0x46C166AC, 0x3108, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID CLSID_Shell = {0x13709620, 0xC279, 0x11CE, [0xA4, 0x9E, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID CLSID_ShellBrowserWindow = {0xC08AFD90, 0xF2A1, 0x11D1, [0x84, 0x55, 0x00, 0xA0, 0xC9, 0x1F, 0x38, 0x80]};\nconst IID CLSID_ShellDesktop = {0x00021400, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_ShellDispatchInproc = {0x0A89A860, 0xD7B1, 0x11CE, [0x83, 0x50, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID CLSID_ShellFolderItem = {0x2FE352EA, 0xFD1F, 0x11D2, [0xB1, 0xF4, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x3E]};\nconst IID CLSID_ShellFolderView = {0x62112AA1, 0xEBE4, 0x11CF, [0xA5, 0xFB, 0x00, 0x20, 0xAF, 0xE7, 0x29, 0x2D]};\nconst IID CLSID_ShellFolderViewOC = {0x9BA05971, 0xF6A8, 0x11CF, [0xA4, 0x42, 0x00, 0xA0, 0xC9, 0x0A, 0x8F, 0x39]};\nconst IID CLSID_ShellFSFolder = {0xF3364BA0, 0x65B9, 0x11CE, [0xA9, 0xBA, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37]};\nconst IID CLSID_ShellImageDataFactory = {0x66E4E4FB, 0xF385, 0x4DD0, [0x8D, 0x74, 0xA2, 0xEF, 0xD1, 0xBC, 0x61, 0x78]};\nconst IID CLSID_ShellLink = {0x00021401, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_ShellLinkObject = {0x11219420, 0x1768, 0x11D1, [0x95, 0xBE, 0x00, 0x60, 0x97, 0x97, 0xEA, 0x4F]};\nconst IID CLSID_ShellLocalMachine = {0x60664CAF, 0xAF0D, 0x0005, [0xA3, 0x00, 0x5C, 0x7D, 0x25, 0xFF, 0x22, 0xA0]};\nconst IID CLSID_ShellLogonEnumUsers = {0x60664CAF, 0xAF0D, 0x0004, [0xA3, 0x00, 0x5C, 0x7D, 0x25, 0xFF, 0x22, 0xA0]};\nconst IID CLSID_ShellLogonStatusHost = {0x60664CAF, 0xAF0D, 0x0007, [0xA3, 0x00, 0x5C, 0x7D, 0x25, 0xFF, 0x22, 0xA0]};\nconst IID CLSID_ShellLogonUser = {0x60664CAF, 0xAF0D, 0x0003, [0xA3, 0x00, 0x5C, 0x7D, 0x25, 0xFF, 0x22, 0xA0]};\nconst IID CLSID_ShellNameSpace = {0x55136805, 0xB2DE, 0x11D1, [0xB9, 0xF2, 0x00, 0xA0, 0xC9, 0x8B, 0xC5, 0x47]};\nconst IID CLSID_ShellUIHelper = {0x64AB4BB7, 0x111E, 0x11D1, [0x8F, 0x79, 0x00, 0xC0, 0x4F, 0xC2, 0xFB, 0xE1]};\nconst IID CLSID_ShellWindows = {0x9BA05972, 0xF6A8, 0x11CF, [0xA4, 0x42, 0x00, 0xA0, 0xC9, 0x0A, 0x8F, 0x39]};\nconst IID CLSID_SizeCategorizer = {0x55D7B852, 0xF6D1, 0x42F2, [0xAA, 0x75, 0x87, 0x28, 0xA1, 0xB2, 0xD2, 0x64]};\nconst IID CLSID_SoftDistExt = {0xB15B8DC0, 0xC7E1, 0x11D0, [0x86, 0x80, 0x00, 0xAA, 0x00, 0xBD, 0xCB, 0x71]};\nconst IID CLSID_SpeakerphoneTerminal = {0xAAF578EE, 0xDC70, 0x11D0, [0x8E, 0xD3, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID CLSID_SpeakersTerminal = {0xAAF578F0, 0xDC70, 0x11D0, [0x8E, 0xD3, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID CLSID_SpeechUIServer = {0x1443904B, 0x34E4, 0x40F6, [0xB3, 0x0F, 0x6B, 0xEB, 0x81, 0x26, 0x7B, 0x80]};\nconst IID CLSID_StaticDib = {0x00000316, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_StaticMetafile = {0x00000315, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_StdAsyncActManager = {0x00000329, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_StdComponentCategoriesMgr = {0x0002E005, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_StdEncodingFilterFac = {0x54C37CD0, 0xD944, 0x11D0, [0xA9, 0xF4, 0x00, 0x60, 0x97, 0x94, 0x23, 0x11]};\nconst IID CLSID_StdEvent = {0x0000032B, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_StdFont = {0x0BE35203, 0x8F91, 0x11CE, [0x9D, 0xE3, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51]};\nconst IID CLSID_StdGlobalInterfaceTable = {0x00000323, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_StdHlink = {0x79EAC9D0, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_StdHlinkBrowseContext = {0x79EAC9D1, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_StdMarshal = {0x00000017, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_StdNotificationMgr = {0xC733E4AF, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_StdPicture = {0x0BE35204, 0x8F91, 0x11CE, [0x9D, 0xE3, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51]};\nconst IID CLSID_StdURLMoniker = {0x79EAC9E0, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_StdURLProtocol = {0x79EAC9E1, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_StgFolder = {0xE773F1AF, 0x3A65, 0x4866, [0x85, 0x7D, 0x84, 0x6F, 0xC9, 0xC4, 0x59, 0x8A]};\nconst IID CLSID_StockColorPage = {0x7EBDAAE1, 0x8120, 0x11CF, [0x89, 0x9F, 0x00, 0xAA, 0x00, 0x68, 0x8B, 0x10]};\nconst IID CLSID_StockFontPage = {0x7EBDAAE0, 0x8120, 0x11CF, [0x89, 0x9F, 0x00, 0xAA, 0x00, 0x68, 0x8B, 0x10]};\nconst IID CLSID_StockPicturePage = {0x7EBDAAE2, 0x8120, 0x11CF, [0x89, 0x9F, 0x00, 0xAA, 0x00, 0x68, 0x8B, 0x10]};\nconst IID CLSID_SubscriptionMgr = {0xABBE31D0, 0x6DAE, 0x11D0, [0xBE, 0xCA, 0x00, 0xC0, 0x4F, 0xD9, 0x40, 0xBE]};\nconst IID CLSID_SubscriptionThrottler = {0x1E9B00E5, 0x9846, 0x11D1, [0xA1, 0xEE, 0x00, 0xC0, 0x4F, 0xC2, 0xFB, 0xE1]};\nconst IID CLSID_SWbemDateTime = {0x47DFBE54, 0xCF76, 0x11D3, [0xB3, 0x8F, 0x00, 0x10, 0x5A, 0x1F, 0x47, 0x3A]};\nconst IID CLSID_SWbemEventSource = {0x04B83D58, 0x21AE, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemLastError = {0xC2FEEEAC, 0xCFCD, 0x11D1, [0x8B, 0x05, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemLocator = {0x76A64158, 0xCB41, 0x11D1, [0x8B, 0x02, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemMethod = {0x04B83D5B, 0x21AE, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemMethodSet = {0x04B83D5A, 0x21AE, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemNamedValue = {0x04B83D60, 0x21AE, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemNamedValueSet = {0x9AED384E, 0xCE8B, 0x11D1, [0x8B, 0x05, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemObject = {0x04B83D62, 0x21AE, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemObjectEx = {0xD6BDAFB2, 0x9435, 0x491F, [0xBB, 0x87, 0x6A, 0xA0, 0xF0, 0xBC, 0x31, 0xA2]};\nconst IID CLSID_SWbemObjectPath = {0x5791BC26, 0xCE9C, 0x11D1, [0x97, 0xBF, 0x00, 0x00, 0xF8, 0x1E, 0x84, 0x9C]};\nconst IID CLSID_SWbemObjectSet = {0x04B83D61, 0x21AE, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemPrivilege = {0x26EE67BC, 0x5804, 0x11D2, [0x8B, 0x4A, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemPrivilegeSet = {0x26EE67BE, 0x5804, 0x11D2, [0x8B, 0x4A, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemProperty = {0x04B83D5D, 0x21AE, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemPropertySet = {0x04B83D5C, 0x21AE, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemQualifier = {0x04B83D5F, 0x21AE, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemQualifierSet = {0x04B83D5E, 0x21AE, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemRefreshableItem = {0x8C6854BC, 0xDE4B, 0x11D3, [0xB3, 0x90, 0x00, 0x10, 0x5A, 0x1F, 0x47, 0x3A]};\nconst IID CLSID_SWbemRefresher = {0xD269BF5C, 0xD9C1, 0x11D3, [0xB3, 0x8F, 0x00, 0x10, 0x5A, 0x1F, 0x47, 0x3A]};\nconst IID CLSID_SWbemSecurity = {0xB54D66E9, 0x2287, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemServices = {0x04B83D63, 0x21AE, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID CLSID_SWbemServicesEx = {0x62E522DC, 0x8CF3, 0x40A8, [0x8B, 0x2E, 0x37, 0xD5, 0x95, 0x65, 0x1E, 0x40]};\nconst IID CLSID_SWbemSink = {0x75718C9A, 0xF029, 0x11D1, [0xA1, 0xAC, 0x00, 0xC0, 0x4F, 0xB6, 0xC2, 0x23]};\nconst IID CLSID_SynchronizeContainer = {0x0000032D, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID CLSID_SyncMgr = {0x6295DF27, 0x35EE, 0x11D1, [0x87, 0x07, 0x00, 0xC0, 0x4F, 0xD9, 0x33, 0x27]};\nconst IID CLSID_TAPI = {0x21D6D48E, 0xA88B, 0x11D0, [0x83, 0xDD, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID CLSID_TaskbarList = {0x56FDF344, 0xFD6D, 0x11D0, [0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90]};\nconst IID CLSID_TaskManager = {0xC0F615A7, 0xF874, 0x4521, [0x87, 0x91, 0xED, 0x3B, 0x84, 0x01, 0x7E, 0xF7]};\nconst IID CLSID_TerminalManager = {0x7170F2E0, 0x9BE3, 0x11D0, [0xA0, 0x09, 0x00, 0xAA, 0x00, 0xB6, 0x05, 0xA4]};\nconst IID CLSID_THREAD_BROADCAST = {0xD34F1812, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_ThreadDialogProcParam = {0x3050F5EB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID CLSID_ThumbnailFCNHandler = {0xCEFC65D8, 0x66D8, 0x11D1, [0x8D, 0x8C, 0x00, 0x00, 0xF8, 0x04, 0xB0, 0x57]};\nconst IID CLSID_ThumbnailUpdater = {0xA3C63918, 0x889D, 0x11D1, [0x83, 0xE9, 0x00, 0xC0, 0x4F, 0xC2, 0xC6, 0xD4]};\nconst IID CLSID_TIME = {0xE32EF57B, 0x7FDE, 0x4765, [0x9B, 0xC5, 0xA1, 0xBA, 0x97, 0x05, 0xC4, 0x4E]};\nconst IID CLSID_TIMEAnimation = {0xF99D135A, 0xC07C, 0x449E, [0x96, 0x5C, 0x7D, 0xBB, 0x7C, 0x55, 0x4A, 0x51]};\nconst IID CLSID_TimeCategorizer = {0x3BB4118F, 0xDDFD, 0x4D30, [0xA3, 0x48, 0x9F, 0xB5, 0xD6, 0xBF, 0x1A, 0xFE]};\nconst IID CLSID_TIMEColorAnimation = {0x62F75052, 0xF3EC, 0x4A64, [0x84, 0xFB, 0xAB, 0x18, 0xE0, 0x74, 0x6E, 0xD8]};\nconst IID CLSID_TIMEFactory = {0x17237A20, 0x3ADB, 0x48EC, [0xB1, 0x82, 0x35, 0x29, 0x1F, 0x11, 0x57, 0x90]};\nconst IID CLSID_TIMEFilterAnimation = {0xC54515D0, 0xF2E5, 0x4BDD, [0xAA, 0x86, 0x1E, 0x4F, 0x23, 0xE4, 0x80, 0xE7]};\nconst IID CLSID_TIMEMotionAnimation = {0x0019A09D, 0x1A81, 0x41C5, [0x89, 0xEC, 0xD9, 0xE7, 0x37, 0x81, 0x13, 0x03]};\nconst IID CLSID_TIMESetAnimation = {0xBA91CE53, 0xBAEB, 0x4F05, [0x86, 0x1C, 0x0A, 0x2A, 0x09, 0x34, 0xF8, 0x2E]};\nconst IID CLSID_Timestamp = {0xB2BED2EB, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_ToolbarExtButtons = {0x2CE4B5D8, 0xA28F, 0x11D2, [0x86, 0xC5, 0x00, 0xC0, 0x4F, 0x8E, 0xEA, 0x99]};\nconst IID CLSID_TrackFile = {0x8790C947, 0xA30B, 0x11D0, [0x8C, 0xAB, 0x00, 0xC0, 0x4F, 0xD9, 0x0F, 0x85]};\nconst IID CLSID_TrkForceOwnership = {0xA2531F45, 0xC67D, 0x11D0, [0x8C, 0xB1, 0x00, 0xC0, 0x4F, 0xD9, 0x0F, 0x85]};\nconst IID CLSID_TrkRestoreNotify = {0xD0056F6C, 0xE2A0, 0x11D0, [0xB1, 0xC2, 0x00, 0xC0, 0x4F, 0xB9, 0x38, 0x6D]};\nconst IID CLSID_TrkRestoreParser = {0x755939E4, 0xE381, 0x11D0, [0xB1, 0xC5, 0x00, 0xC0, 0x4F, 0xB9, 0x38, 0x6D]};\nconst IID CLSID_TypedName = {0xB33143CB, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID CLSID_UmiLDAPQueryObject = {0xCD5D4D76, 0xA818, 0x4F95, [0xB9, 0x58, 0x79, 0x70, 0xFD, 0x94, 0x12, 0xCA]};\nconst IID CLSID_UnsecuredApartment = {0x49BD2028, 0x1523, 0x11D1, [0xAD, 0x79, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID CLSID_UPnPDescriptionDocument = {0x1D8A9B47, 0x3A28, 0x4CE2, [0x8A, 0x4B, 0xBD, 0x34, 0xE4, 0x5B, 0xCE, 0xEB]};\nconst IID CLSID_UPnPDevice = {0xA32552C5, 0xBA61, 0x457A, [0xB5, 0x9A, 0xA2, 0x56, 0x1E, 0x12, 0x5E, 0x33]};\nconst IID CLSID_UPnPDeviceFinder = {0xE2085F28, 0xFEB7, 0x404A, [0xB8, 0xE7, 0xE6, 0x59, 0xBD, 0xEA, 0xAA, 0x02]};\nconst IID CLSID_UPnPDeviceHostICSSupport = {0x797A9BB1, 0x9E49, 0x4E63, [0xAF, 0xE1, 0x1B, 0x45, 0xB9, 0xDC, 0x81, 0x62]};\nconst IID CLSID_UPnPDeviceHostSetup = {0xB4609411, 0xC81C, 0x4CCE, [0x8C, 0x76, 0xC6, 0xB5, 0x0C, 0x94, 0x02, 0xC6]};\nconst IID CLSID_UPnPDevices = {0xB9E84FFD, 0xAD3C, 0x40A4, [0xB8, 0x35, 0x08, 0x82, 0xEB, 0xCB, 0xAA, 0xA8]};\nconst IID CLSID_UPnPNAT = {0xAE1E00AA, 0x3FD5, 0x403C, [0x8A, 0x27, 0x2B, 0xBD, 0xC3, 0x0C, 0xD0, 0xE1]};\nconst IID CLSID_UPnPRegistrar = {0x204810B9, 0x73B2, 0x11D4, [0xBF, 0x42, 0x00, 0xB0, 0xD0, 0x11, 0x8B, 0x56]};\nconst IID CLSID_UPnPService = {0xC624BA95, 0xFBCB, 0x4409, [0x8C, 0x03, 0x8C, 0xCE, 0xEC, 0x53, 0x3E, 0xF1]};\nconst IID CLSID_UPnPServices = {0xC0BC4B4A, 0xA406, 0x4EFC, [0x93, 0x2F, 0xB8, 0x54, 0x6B, 0x81, 0x00, 0xCC]};\nconst IID CLSID_UrlMkBindCtx = {0x79EAC9F2, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID CLSID_UserEventTimer = {0x864A1288, 0x354C, 0x4D19, [0x9D, 0x68, 0xC2, 0x74, 0x2B, 0xB1, 0x49, 0x97]};\nconst IID CLSID_UserEventTimerCallback = {0x15FFFD13, 0x5140, 0x41B8, [0xB8, 0x9A, 0xC8, 0xD5, 0x75, 0x9C, 0xD2, 0xB2]};\nconst IID CLSID_UserNotification = {0x0010890E, 0x8789, 0x413C, [0xAD, 0xBC, 0x48, 0xF5, 0xB5, 0x11, 0xB3, 0xAF]};\nconst IID CLSID_VideoInputTerminal = {0xAAF578EC, 0xDC70, 0x11D0, [0x8E, 0xD3, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID CLSID_VideoWindowTerm = {0xF7438990, 0xD6EB, 0x11D0, [0x82, 0xA6, 0x00, 0xAA, 0x00, 0xB5, 0xCA, 0x1B]};\nconst IID CLSID_VirusScan = {0xE88E5DE0, 0xBD3E, 0x11CF, [0xAA, 0xFA, 0x00, 0xAA, 0x00, 0xB6, 0x01, 0x5C]};\nconst IID CLSID_WbemAdministrativeLocator = {0xCB8555CC, 0x9128, 0x11D1, [0xAD, 0x9B, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID CLSID_WbemAuthenticatedLocator = {0xCD184336, 0x9128, 0x11D1, [0xAD, 0x9B, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID CLSID_WbemBackupRestore = {0xC49E32C6, 0xBC8B, 0x11D2, [0x85, 0xD4, 0x00, 0x10, 0x5A, 0x1F, 0x83, 0x04]};\nconst IID CLSID_WbemClassObject = {0x9A653086, 0x174F, 0x11D2, [0xB5, 0xF9, 0x00, 0x10, 0x4B, 0x70, 0x3E, 0xFD]};\nconst IID CLSID_WbemContext = {0x674B6698, 0xEE92, 0x11D0, [0xAD, 0x71, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID CLSID_WbemDCOMTransport = {0xF7CE2E13, 0x8C90, 0x11D1, [0x9E, 0x7B, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID CLSID_WbemDecoupledBasicEventProvide = {0xF5F75737, 0x2843, 0x4F22, [0x93, 0x3D, 0xC7, 0x6A, 0x97, 0xCD, 0xA6, 0x2F]};\nconst IID CLSID_WbemDecoupledRegistrar = {0x4CFC7932, 0x0F9D, 0x4BEF, [0x9C, 0x32, 0x8E, 0xA2, 0xA6, 0xB5, 0x6F, 0xCB]};\nconst IID CLSID_WbemDefPath = {0xCF4CC405, 0xE2C5, 0x4DDD, [0xB3, 0xCE, 0x5E, 0x75, 0x82, 0xD8, 0xC9, 0xFA]};\nconst IID CLSID_WbemLevel1Login = {0x8BC3F05E, 0xD86B, 0x11D0, [0xA0, 0x75, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID CLSID_WbemLocalAddrRes = {0xA1044801, 0x8F7E, 0x11D1, [0x9E, 0x7C, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID CLSID_WbemLocator = {0x4590F811, 0x1D3A, 0x11D0, [0x89, 0x1F, 0x00, 0xAA, 0x00, 0x4B, 0x2E, 0x24]};\nconst IID CLSID_WbemObjectTextSrc = {0x8D1C559D, 0x84F0, 0x4BB3, [0xA7, 0xD5, 0x56, 0xA7, 0x43, 0x5A, 0x9B, 0xA6]};\nconst IID CLSID_WbemQuery = {0xEAC8A024, 0x21E2, 0x4523, [0xAD, 0x73, 0xA7, 0x1A, 0x0A, 0xA2, 0xF5, 0x6A]};\nconst IID CLSID_WbemRefresher = {0xC71566F2, 0x561E, 0x11D1, [0xAD, 0x87, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID CLSID_WbemStatusCodeText = {0xEB87E1BD, 0x3233, 0x11D2, [0xAE, 0xC9, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID CLSID_WbemUnauthenticatedLocator = {0x443E7B79, 0xDE31, 0x11D2, [0xB3, 0x40, 0x00, 0x10, 0x4B, 0xCC, 0x4B, 0x4A]};\nconst IID CLSID_WbemUninitializedClassObject = {0x7A0227F6, 0x7108, 0x11D1, [0xAD, 0x90, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID CLSID_WebBrowser = {0x8856F961, 0x340A, 0x11D0, [0xA9, 0x6B, 0x00, 0xC0, 0x4F, 0xD7, 0x05, 0xA2]};\nconst IID CLSID_WebBrowser_V1 = {0xEAB22AC3, 0x30C1, 0x11CF, [0xA7, 0xEB, 0x00, 0x00, 0xC0, 0x5B, 0xAE, 0x0B]};\nconst IID CLSID_WebCheck = {0xE6FB5E20, 0xDE35, 0x11CF, [0x9C, 0x87, 0x00, 0xAA, 0x00, 0x51, 0x27, 0xED]};\nconst IID CLSID_WebCheckDefaultProcess = {0xC733E4B0, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID CLSID_WebCheckOfflineSync = {0x7FC0B86E, 0x5FA7, 0x11D1, [0xBC, 0x7C, 0x00, 0xC0, 0x4F, 0xD9, 0x29, 0xDB]};\nconst IID CLSID_WebCrawlerAgent = {0x08165EA0, 0xE946, 0x11CF, [0x9C, 0x87, 0x00, 0xAA, 0x00, 0x51, 0x27, 0xED]};\nconst IID CLSID_WebViewFolderContents = {0x1820FED0, 0x473E, 0x11D0, [0xA9, 0x6C, 0x00, 0xC0, 0x4F, 0xD7, 0x05, 0xA2]};\nconst IID CLSID_WebWizardHost = {0xC827F149, 0x55C1, 0x4D28, [0x93, 0x5E, 0x57, 0xE4, 0x7C, 0xAE, 0xD9, 0x73]};\nconst IID CLSID_wfolders = {0xBAE31F9A, 0x1B81, 0x11D2, [0xA9, 0x7A, 0x00, 0xC0, 0x4F, 0x8E, 0xCB, 0x02]};\nconst IID CLSID_WinNTConnectionObject = {0x7992C6EB, 0xD142, 0x4332, [0x83, 0x1E, 0x31, 0x54, 0xC5, 0x0A, 0x83, 0x16]};\nconst IID CLSID_WinNTObject = {0xB8324185, 0x4050, 0x4220, [0x98, 0x0A, 0xAB, 0x14, 0x62, 0x3E, 0x06, 0x3A]};\nconst IID CLSID_WinNTSystemInfo = {0x66182EC4, 0xAFD1, 0x11D2, [0x9C, 0xB9, 0x00, 0x00, 0xF8, 0x7A, 0x36, 0x9E]};\nconst IID CLSID_WMIExtension = {0xF0975AFE, 0x5C7F, 0x11D2, [0x8B, 0x74, 0x00, 0x10, 0x4B, 0x2A, 0xFB, 0x41]};\nconst IID CLSID_XMLDocument = {0xCFC399AF, 0xD876, 0x11D0, [0x9C, 0x10, 0x00, 0xC0, 0x4F, 0xC9, 0x9C, 0x8E]};\nconst IID CLSID_XMLDSOControl = {0x550DDA30, 0x0541, 0x11D2, [0x9C, 0xA9, 0x00, 0x60, 0xB0, 0xEC, 0x3D, 0x39]};\nconst IID CLSID_XMLHTTPRequest = {0xED8C108E, 0x4349, 0x11D2, [0x91, 0xA4, 0x00, 0xC0, 0x4F, 0x79, 0x69, 0xE8]};\nconst IID CLSID_XMLParser = {0xD2423620, 0x51A0, 0x11D2, [0x9C, 0xAF, 0x00, 0x60, 0xB0, 0xEC, 0x3D, 0x39]};\nconst IID DB_PROPERTY_AUTOMATICUPDATE = {0xC8B52209, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_BTREE = {0xC8B52201, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_CHECK_OPTION = {0xC8B5220B, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_CLUSTERED = {0xC8B521FF, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_CONSTRAINT_CHECK_DEFERRE = {0xC8B521F0, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_DISALLOWNULL = {0xC8B52205, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_DROP_CASCADE = {0xC8B521F3, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_EXPLICITUPDATE = {0xC8B5220A, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_FILLFACTOR = {0xC8B52203, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_HASH = {0xC8B52202, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_IGNOREANYNULL = {0xC8B52207, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_IGNORENULL = {0xC8B52206, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_INITIALSIZE = {0xC8B52204, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_NONCLUSTERED = {0xC8B52200, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_ON_COMMIT_PRESERVE_ROWS = {0xC8B52230, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_PRIMARY = {0xC8B521FC, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_SORTBOOKMARKS = {0xC8B52208, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DB_PROPERTY_UNIQUE = {0xC8B521F5, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBCOL_SELFCOLUMNS = {0xC8B52231, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBCOL_SPECIALCOL = {0xC8B52232, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_COMMAND = {0xC8B522F8, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_CONTAINEROBJECT = {0xC8B522FB, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_DBSQL = {0xC8B521FB, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_DEFAULT = {0xC8B521FB, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_DSO = {0xC8B522F4, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_HISTOGRAM_ROWSET = {0xC8B52300, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_LDAPDialect = {0xEFF65380, 0x9C98, 0x11CF, [0xB9, 0x63, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_LIKE_DOS = {0xC8B521F7, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_LIKE_MAPI = {0xC8B521F9, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_LIKE_OFS = {0xC8B521F8, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_LIKE_SQL = {0xC8B521F6, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_MDX = {0xA07CCCD0, 0x8148, 0x11D0, [0x87, 0xBB, 0x00, 0xC0, 0x4F, 0xC3, 0x39, 0x42]};\nconst IID DBGUID_ROW = {0xC8B522F7, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_ROWSET = {0xC8B522F6, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_SESSION = {0xC8B522F5, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_SQL = {0xC8B522D7, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBGUID_STREAM = {0xC8B522F9, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_CHARACTERSET = {0xC8B522ED, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_COLLATION = {0xC8B522EA, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_COLUMN = {0xC8B522E4, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_DATABASE = {0xC8B522E5, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_DOMAIN = {0xC8B522E9, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_PROCEDURE = {0xC8B522E6, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_SCHEMA = {0xC8B522E8, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_SCHEMAROWSET = {0xC8B522EC, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_TABLE = {0xC8B522E2, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_TRANSLATION = {0xC8B522EE, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_TRUSTEE = {0xC8B522EB, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBOBJECT_VIEW = {0xC8B522E7, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_ADSIBIND = {0x6DA66DC8, 0xB7E8, 0x11D2, [0x9D, 0x60, 0x00, 0xC0, 0x4F, 0x68, 0x93, 0x45]};\nconst IID DBPROPSET_ADSISEARCH = {0xCFCFC928, 0x9AA2, 0x11D0, [0xA7, 0x9A, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0xA8]};\nconst IID DBPROPSET_COLUMN = {0xC8B522B9, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_COLUMNALL = {0xC8B522F0, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_CONSTRAINTALL = {0xC8B522FA, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_DATASOURCE = {0xC8B522BA, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_DATASOURCEALL = {0xC8B522C0, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_DATASOURCEINFO = {0xC8B522BB, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_DATASOURCEINFOALL = {0xC8B522C1, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_DBINIT = {0xC8B522BC, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_DBINITALL = {0xC8B522CA, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_INDEX = {0xC8B522BD, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_INDEXALL = {0xC8B522F1, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_PROPERTIESINERROR = {0xC8B522D4, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_ROWSET = {0xC8B522BE, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_ROWSETALL = {0xC8B522C2, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_SESSION = {0xC8B522C6, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_SESSIONALL = {0xC8B522C7, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_STREAM = {0xC8B522FD, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_STREAMALL = {0xC8B522FE, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_TABLE = {0xC8B522BF, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_TABLEALL = {0xC8B522F2, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_TRUSTEE = {0xC8B522E1, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_TRUSTEEALL = {0xC8B522F3, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_VIEW = {0xC8B522DF, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBPROPSET_VIEWALL = {0xC8B522FC, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_ASSERTIONS = {0xC8B52210, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_CATALOGS = {0xC8B52211, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_CHARACTER_SETS = {0xC8B52212, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_CHECK_CONSTRAINTS = {0xC8B52215, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_CHECK_CONSTRAINTS_BY_TABLE = {0xC8B52301, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_COLLATIONS = {0xC8B52213, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_COLUMN_DOMAIN_USAGE = {0xC8B5221B, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_COLUMN_PRIVILEGES = {0xC8B52221, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_COLUMNS = {0xC8B52214, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_CONSTRAINT_COLUMN_USAGE = {0xC8B52216, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_CONSTRAINT_TABLE_USAGE = {0xC8B52217, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_FOREIGN_KEYS = {0xC8B522C4, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_INDEXES = {0xC8B5221E, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_KEY_COLUMN_USAGE = {0xC8B52218, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_PRIMARY_KEYS = {0xC8B522C5, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_PROCEDURE_COLUMNS = {0xC8B522C9, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_PROCEDURE_PARAMETERS = {0xC8B522B8, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_PROCEDURES = {0xC8B52224, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_PROVIDER_TYPES = {0xC8B5222C, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_REFERENTIAL_CONSTRAINTS = {0xC8B52219, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_SCHEMATA = {0xC8B52225, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_SQL_LANGUAGES = {0xC8B52226, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_STATISTICS = {0xC8B52227, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_TABLE_CONSTRAINTS = {0xC8B5221A, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_TABLE_PRIVILEGES = {0xC8B52222, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_TABLE_STATISTICS = {0xC8B522FF, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_TABLES = {0xC8B52229, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_TABLES_INFO = {0xC8B522E0, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_TRANSLATIONS = {0xC8B5222A, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_TRUSTEE = {0xC8B522EF, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_USAGE_PRIVILEGES = {0xC8B52223, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_VIEW_COLUMN_USAGE = {0xC8B5222E, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_VIEW_TABLE_USAGE = {0xC8B5222F, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DBSCHEMA_VIEWS = {0xC8B5222D, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID DDVPTYPE_BROOKTREE = {0x1352A560, 0xDA61, 0x11CF, [0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8]};\nconst IID DDVPTYPE_CCIR656 = {0xFCA326A0, 0xDA60, 0x11CF, [0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8]};\nconst IID DDVPTYPE_E_HREFH_VREFL = {0x92783220, 0xDA60, 0x11CF, [0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8]};\nconst IID DDVPTYPE_E_HREFL_VREFL = {0xE09C77E0, 0xDA60, 0x11CF, [0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8]};\nconst IID DDVPTYPE_PHILIPS = {0x332CF160, 0xDA61, 0x11CF, [0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8]};\nconst IID DIID__SearchAssistantEvents = {0x1611FDDA, 0x445B, 0x11D2, [0x85, 0xDE, 0x00, 0xC0, 0x4F, 0xA3, 0x5C, 0x89]};\nconst IID DIID_DispCEventObj = {0x3050F558, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispDOMChildrenCollection = {0x3050F577, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTCAttachBehavior = {0x3050F583, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTCDefaultDispatch = {0x3050F573, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTCDescBehavior = {0x3050F57E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTCEventBehavior = {0x3050F574, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTCMethodBehavior = {0x3050F587, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTCPropertyBehavior = {0x3050F57F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLAnchorElement = {0x3050F502, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLAppBehavior = {0x3050F57C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLAreaElement = {0x3050F503, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLAreasCollection = {0x3050F56A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLAttributeCollection = {0x3050F56C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLBaseElement = {0x3050F518, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLBaseFontElement = {0x3050F504, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLBGsound = {0x3050F53C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLBlockElement = {0x3050F506, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLBody = {0x3050F507, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLBRElement = {0x3050F53A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLButtonElement = {0x3050F51F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLCommentElement = {0x3050F50A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLCurrentStyle = {0x3050F557, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLDDElement = {0x3050F50B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLDefaults = {0x3050F58C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLDivElement = {0x3050F50C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLDivPosition = {0x3050F50F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLDListElement = {0x3050F53B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLDocument = {0x3050F55F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLDOMAttribute = {0x3050F564, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLDOMImplementation = {0x3050F58F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLDOMTextNode = {0x3050F565, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLDTElement = {0x3050F50D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLElementCollection = {0x3050F56B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLEmbed = {0x3050F52E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLFieldSetElement = {0x3050F545, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLFontElement = {0x3050F512, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLFormElement = {0x3050F510, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLFrameBase = {0x3050F541, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLFrameElement = {0x3050F513, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLFrameSetSite = {0x3050F514, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLGenericElement = {0x3050F563, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLHeadElement = {0x3050F561, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLHeaderElement = {0x3050F515, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLHRElement = {0x3050F53D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLHtmlElement = {0x3050F560, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLIFrame = {0x3050F51B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLImg = {0x3050F51C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLInputElement = {0x3050F57D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLIsIndexElement = {0x3050F519, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLLabelElement = {0x3050F522, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLLegendElement = {0x3050F546, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLLIElement = {0x3050F523, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLLinkElement = {0x3050F524, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLListElement = {0x3050F525, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLMapElement = {0x3050F526, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLMarqueeElement = {0x3050F527, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLMetaElement = {0x3050F517, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLNextIdElement = {0x3050F51A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLNoShowElement = {0x3050F528, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLObjectElement = {0x3050F529, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLOListElement = {0x3050F52A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLOptionElement = {0x3050F52B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLParaElement = {0x3050F52C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLParamElement = {0x3050F590, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLPhraseElement = {0x3050F52D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLPopup = {0x3050F589, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLRenderStyle = {0x3050F58B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLRichtextElement = {0x3050F54D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLRuleStyle = {0x3050F55C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLScreen = {0x3050F591, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLScriptElement = {0x3050F530, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLSelectElement = {0x3050F531, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLSpanElement = {0x3050F548, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLSpanFlow = {0x3050F544, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLStyle = {0x3050F55A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLStyleElement = {0x3050F511, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLStyleSheet = {0x3050F58D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLTable = {0x3050F532, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLTableCaption = {0x3050F508, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLTableCell = {0x3050F536, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLTableCol = {0x3050F533, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLTableRow = {0x3050F535, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLTableSection = {0x3050F534, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLTextAreaElement = {0x3050F521, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLTextElement = {0x3050F537, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLTitleElement = {0x3050F516, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLUListElement = {0x3050F538, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLUnknownElement = {0x3050F539, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLWindow2 = {0x3050F55D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispHTMLWindowProxy = {0x3050F55E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispIHTMLInputButtonElement = {0x3050F51E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispIHTMLInputFileElement = {0x3050F542, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispIHTMLInputImage = {0x3050F51D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispIHTMLInputTextElement = {0x3050F520, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DispIHTMLOptionButtonElement = {0x3050F509, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_DMigrationWizardAutoEvents = {0xD2AC137D, 0xA6D8, 0x43B6, [0x98, 0x79, 0xEA, 0x34, 0xB6, 0x7E, 0x18, 0x80]};\nconst IID DIID_DSearchCommandEvents = {0x60890160, 0x69F0, 0x11D1, [0xB7, 0x58, 0x00, 0xA0, 0xC9, 0x05, 0x64, 0xFE]};\nconst IID DIID_DShellFolderViewEvents = {0x62112AA2, 0xEBE4, 0x11CF, [0xA5, 0xFB, 0x00, 0x20, 0xAF, 0xE7, 0x29, 0x2D]};\nconst IID DIID_DShellNameSpaceEvents = {0x55136806, 0xB2DE, 0x11D1, [0xB9, 0xF2, 0x00, 0xA0, 0xC9, 0x8B, 0xC5, 0x47]};\nconst IID DIID_DShellWindowsEvents = {0xFE4106E0, 0x399A, 0x11D0, [0xA4, 0x8C, 0x00, 0xA0, 0xC9, 0x0A, 0x8F, 0x39]};\nconst IID DIID_DWebBridgeEvents = {0xA6D897FF, 0x0A95, 0x11D1, [0xB0, 0xBA, 0x00, 0x60, 0x08, 0x16, 0x6E, 0x11]};\nconst IID DIID_DWebBrowserEvents = {0xEAB22AC2, 0x30C1, 0x11CF, [0xA7, 0xEB, 0x00, 0x00, 0xC0, 0x5B, 0xAE, 0x0B]};\nconst IID DIID_DWebBrowserEvents2 = {0x34A715A0, 0x6587, 0x11D0, [0x92, 0x4A, 0x00, 0x20, 0xAF, 0xC7, 0xAC, 0x4D]};\nconst IID DIID_HTMLAnchorEvents = {0x3050F29D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLAnchorEvents2 = {0x3050F610, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLAreaEvents = {0x3050F366, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLAreaEvents2 = {0x3050F611, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLButtonElementEvents = {0x3050F2B3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLButtonElementEvents2 = {0x3050F617, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLControlElementEvents = {0x3050F4EA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLControlElementEvents2 = {0x3050F612, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLDocumentEvents = {0x3050F260, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLDocumentEvents2 = {0x3050F613, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLElementEvents = {0x3050F33C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLElementEvents2 = {0x3050F60F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLFormElementEvents = {0x3050F364, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLFormElementEvents2 = {0x3050F614, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLFrameSiteEvents = {0x3050F800, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLFrameSiteEvents2 = {0x3050F7FF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLImgEvents = {0x3050F25B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLImgEvents2 = {0x3050F616, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLInputFileElementEvents = {0x3050F2AF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLInputFileElementEvents2 = {0x3050F61A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLInputImageEvents = {0x3050F2C3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLInputImageEvents2 = {0x3050F61B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLInputTextElementEvents = {0x3050F2A7, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLInputTextElementEvents2 = {0x3050F618, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLLabelEvents = {0x3050F329, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLLabelEvents2 = {0x3050F61C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLLinkElementEvents = {0x3050F3CC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLLinkElementEvents2 = {0x3050F61D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLMapEvents = {0x3050F3BA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLMapEvents2 = {0x3050F61E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLMarqueeElementEvents = {0x3050F2B8, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLMarqueeElementEvents2 = {0x3050F61F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLNamespaceEvents = {0x3050F6BD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLObjectElementEvents = {0x3050F3C4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLObjectElementEvents2 = {0x3050F620, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLOptionButtonElementEvents = {0x3050F2BD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLOptionButtonElementEvents2 = {0x3050F619, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLPersistEvents = {0x3050F4C7, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLScriptEvents = {0x3050F3E2, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLScriptEvents2 = {0x3050F621, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLSelectElementEvents = {0x3050F302, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLSelectElementEvents2 = {0x3050F622, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLStyleElementEvents = {0x3050F3CB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLStyleElementEvents2 = {0x3050F615, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLTableEvents = {0x3050F407, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLTableEvents2 = {0x3050F623, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLTextContainerEvents = {0x1FF6AA72, 0x5842, 0x11CF, [0xA7, 0x07, 0x00, 0xAA, 0x00, 0xC0, 0x09, 0x8D]};\nconst IID DIID_HTMLTextContainerEvents2 = {0x3050F624, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_HTMLWindowEvents = {0x96A0A4E0, 0xD062, 0x11CF, [0x94, 0xB6, 0x00, 0xAA, 0x00, 0x60, 0x27, 0x5C]};\nconst IID DIID_HTMLWindowEvents2 = {0x3050F625, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_IRTCDispatchEventNotification = {0x176DDFBE, 0xFEC0, 0x4D55, [0xBC, 0x87, 0x84, 0xCF, 0xF1, 0xEF, 0x7F, 0x91]};\nconst IID DIID_ISWbemSinkEvents = {0x75718CA0, 0xF029, 0x11D1, [0xA1, 0xAC, 0x00, 0xC0, 0x4F, 0xB6, 0xC2, 0x23]};\nconst IID DIID_ITTAPIDispatchEventNotification = {0x9F34325B, 0x7E62, 0x11D2, [0x94, 0x57, 0x00, 0xC0, 0x4F, 0x8E, 0xC8, 0x88]};\nconst IID DIID_LayoutRectEvents = {0x3050F674, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID DIID_XMLDOMDocumentEvents = {0x3EFAA427, 0x272F, 0x11D2, [0x83, 0x6F, 0x00, 0x00, 0xF8, 0x7A, 0x77, 0x82]};\nconst IID DPAID_ComPort = {0xF2F0CE00, 0xE0AF, 0x11CF, [0x9C, 0x4E, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID DPAID_INet = {0xC4A54DA0, 0xE0AF, 0x11CF, [0x9C, 0x4E, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID DPAID_INetPort = {0xE4524541, 0x8EA5, 0x11D1, [0x8A, 0x96, 0x00, 0x60, 0x97, 0xB0, 0x14, 0x11]};\nconst IID DPAID_INetW = {0xE63232A0, 0x9DBF, 0x11D0, [0x9C, 0xC1, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID DPAID_LobbyProvider = {0x59B95640, 0x9667, 0x11D0, [0xA7, 0x7D, 0x00, 0x00, 0xF8, 0x03, 0xAB, 0xFC]};\nconst IID DPAID_Modem = {0xF6DCC200, 0xA2FE, 0x11D0, [0x9C, 0x4F, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID DPAID_ModemW = {0x01FD92E0, 0xA2FF, 0x11D0, [0x9C, 0x4F, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID DPAID_Phone = {0x78EC89A0, 0xE0AF, 0x11CF, [0x9C, 0x4E, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID DPAID_PhoneW = {0xBA5A7A70, 0x9DBF, 0x11D0, [0x9C, 0xC1, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID DPAID_ServiceProvider = {0x07D916C0, 0xE0AF, 0x11CF, [0x9C, 0x4E, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID DPAID_TotalSize = {0x1318F560, 0x912C, 0x11D0, [0x9D, 0xAA, 0x00, 0xA0, 0xC9, 0x0A, 0x43, 0xCB]};\nconst IID DPLPROPERTY_LobbyGuid = {0xF56920A0, 0xD218, 0x11D0, [0xBA, 0x39, 0x00, 0xC0, 0x4F, 0xD7, 0xED, 0x67]};\nconst IID DPLPROPERTY_MessagesSupported = {0x762CCDA1, 0xD916, 0x11D0, [0xBA, 0x39, 0x00, 0xC0, 0x4F, 0xD7, 0xED, 0x67]};\nconst IID DPLPROPERTY_PlayerGuid = {0xB4319322, 0xD20D, 0x11D0, [0xBA, 0x39, 0x00, 0xC0, 0x4F, 0xD7, 0xED, 0x67]};\nconst IID DPLPROPERTY_PlayerScore = {0x48784000, 0xD219, 0x11D0, [0xBA, 0x39, 0x00, 0xC0, 0x4F, 0xD7, 0xED, 0x67]};\nconst IID DPSPGUID_IPX = {0x685BC400, 0x9D2C, 0x11CF, [0xA9, 0xCD, 0x00, 0xAA, 0x00, 0x68, 0x86, 0xE3]};\nconst IID DPSPGUID_MODEM = {0x44EAA760, 0xCB68, 0x11CF, [0x9C, 0x4E, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID DPSPGUID_SERIAL = {0x0F1D6860, 0x88D9, 0x11CF, [0x9C, 0x4E, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID DPSPGUID_TCPIP = {0x36E95EE0, 0x8577, 0x11CF, [0x96, 0x0C, 0x00, 0x80, 0xC7, 0x53, 0x4E, 0x82]};\nconst IID DS3DALG_HRTF_FULL = {0xC2413340, 0x1C1B, 0x11D2, [0x94, 0xF5, 0x00, 0xC0, 0x4F, 0xC2, 0x8A, 0xCA]};\nconst IID DS3DALG_HRTF_LIGHT = {0xC2413342, 0x1C1B, 0x11D2, [0x94, 0xF5, 0x00, 0xC0, 0x4F, 0xC2, 0x8A, 0xCA]};\nconst IID DS3DALG_NO_VIRTUALIZATION = {0xC241333F, 0x1C1B, 0x11D2, [0x94, 0xF5, 0x00, 0xC0, 0x4F, 0xC2, 0x8A, 0xCA]};\nconst IID FLAGID_Internet = {0x96300DA0, 0x2BAB, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID FMTID_AudioSummaryInformation = {0x64440490, 0x4C8B, 0x11D1, [0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03]};\nconst IID FMTID_Briefcase = {0x328D8B21, 0x7729, 0x4BFC, [0x95, 0x4C, 0x90, 0x2B, 0x32, 0x9D, 0x56, 0xB0]};\nconst IID FMTID_DiscardableInformation = {0xD725EBB0, 0xC9B8, 0x11D1, [0x89, 0xBC, 0x00, 0x00, 0xF8, 0x04, 0xB0, 0x57]};\nconst IID FMTID_Displaced = {0x9B174B33, 0x40FF, 0x11D2, [0xA2, 0x7E, 0x00, 0xC0, 0x4F, 0xC3, 0x08, 0x71]};\nconst IID FMTID_DocSummaryInformation = {0xD5CDD502, 0x2E9C, 0x101B, [0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE]};\nconst IID FMTID_DRM = {0xAEAC19E4, 0x89AE, 0x4508, [0xB9, 0xB7, 0xBB, 0x86, 0x7A, 0xBE, 0xE2, 0xED]};\nconst IID FMTID_ImageProperties = {0x14B81DA1, 0x0135, 0x4D31, [0x96, 0xD9, 0x6C, 0xBF, 0xC9, 0x67, 0x1A, 0x99]};\nconst IID FMTID_ImageSummaryInformation = {0x6444048F, 0x4C8B, 0x11D1, [0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03]};\nconst IID FMTID_InternetSite = {0x000214A1, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID FMTID_Intshcut = {0x000214A0, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID FMTID_MediaFileSummaryInformation = {0x64440492, 0x4C8B, 0x11D1, [0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03]};\nconst IID FMTID_Misc = {0x9B174B34, 0x40FF, 0x11D2, [0xA2, 0x7E, 0x00, 0xC0, 0x4F, 0xC3, 0x08, 0x71]};\nconst IID FMTID_MUSIC = {0x56A3372E, 0xCE9C, 0x11D2, [0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6]};\nconst IID FMTID_PropertyBag = {0x20001801, 0x5DE6, 0x11D1, [0x8E, 0x38, 0x00, 0xC0, 0x4F, 0xB9, 0x38, 0x6D]};\nconst IID FMTID_Query = {0x49691C90, 0x7E17, 0x101A, [0xA9, 0x1C, 0x08, 0x00, 0x2B, 0x2E, 0xCD, 0xA9]};\nconst IID FMTID_ShellDetails = {0x28636AA6, 0x953D, 0x11D2, [0xB5, 0xD6, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xD0]};\nconst IID FMTID_Storage = {0xB725F130, 0x47EF, 0x101A, [0xA5, 0xF1, 0x02, 0x60, 0x8C, 0x9E, 0xEB, 0xAC]};\nconst IID FMTID_SummaryInformation = {0xF29F85E0, 0x4FF9, 0x1068, [0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9]};\nconst IID FMTID_UserDefinedProperties = {0xD5CDD505, 0x2E9C, 0x101B, [0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE]};\nconst IID FMTID_VideoSummaryInformation = {0x64440491, 0x4C8B, 0x11D1, [0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03]};\nconst IID FMTID_Volume = {0x9B174B35, 0x40FF, 0x11D2, [0xA2, 0x7E, 0x00, 0xC0, 0x4F, 0xC3, 0x08, 0x71]};\nconst IID FMTID_WebView = {0xF2275480, 0xF782, 0x4291, [0xBD, 0x94, 0xF1, 0x36, 0x93, 0x51, 0x3A, 0xEC]};\nconst IID GUID_ACPI_CMOS_INTERFACE_STANDARD = {0x3A8D0384, 0x6505, 0x40CA, [0xBC, 0x39, 0x56, 0xC1, 0x5F, 0x8C, 0x5F, 0xED]};\nconst IID GUID_ACPI_INTERFACE_STANDARD = {0xB091A08A, 0xBA97, 0x11D0, [0xBD, 0x14, 0x00, 0xAA, 0x00, 0xB7, 0xB3, 0x2A]};\nconst IID GUID_ACPI_PORT_RANGES_INTERFACE_STAND = {0xF14F609B, 0xCBBD, 0x4957, [0xA6, 0x74, 0xBC, 0x00, 0x21, 0x3F, 0x1C, 0x97]};\nconst IID GUID_ACPI_REGS_INTERFACE_STANDARD = {0x06141966, 0x7245, 0x6369, [0x46, 0x2E, 0x4E, 0x65, 0x6C, 0x73, 0x6F, 0x6E]};\nconst IID GUID_ARBITER_INTERFACE_STANDARD = {0xE644F185, 0x8C0E, 0x11D0, [0xBE, 0xCF, 0x08, 0x00, 0x2B, 0xE2, 0x09, 0x2F]};\nconst IID GUID_BUS_INTERFACE_STANDARD = {0x496B8280, 0x6F25, 0x11D0, [0xBE, 0xAF, 0x08, 0x00, 0x2B, 0xE2, 0x09, 0x2F]};\nconst IID GUID_BUS_TYPE_1394 = {0xF74E73EB, 0x9AC5, 0x45EB, [0xBE, 0x4D, 0x77, 0x2C, 0xC7, 0x1D, 0xDF, 0xB3]};\nconst IID GUID_BUS_TYPE_AVC = {0xC06FF265, 0xAE09, 0x48F0, [0x81, 0x2C, 0x16, 0x75, 0x3D, 0x7C, 0xBA, 0x83]};\nconst IID GUID_BUS_TYPE_DOT4PRT = {0x441EE001, 0x4342, 0x11D5, [0xA1, 0x84, 0x00, 0xC0, 0x4F, 0x60, 0x52, 0x4D]};\nconst IID GUID_BUS_TYPE_EISA = {0xDDC35509, 0xF3FC, 0x11D0, [0xA5, 0x37, 0x00, 0x00, 0xF8, 0x75, 0x3E, 0xD1]};\nconst IID GUID_BUS_TYPE_HID = {0xEEAF37D0, 0x1963, 0x47C4, [0xAA, 0x48, 0x72, 0x47, 0x6D, 0xB7, 0xCF, 0x49]};\nconst IID GUID_BUS_TYPE_INTERNAL = {0x1530EA73, 0x086B, 0x11D1, [0xA0, 0x9F, 0x00, 0xC0, 0x4F, 0xC3, 0x40, 0xB1]};\nconst IID GUID_BUS_TYPE_IRDA = {0x7AE17DC1, 0xC944, 0x44D6, [0x88, 0x1F, 0x4C, 0x2E, 0x61, 0x05, 0x3B, 0xC1]};\nconst IID GUID_BUS_TYPE_ISAPNP = {0xE676F854, 0xD87D, 0x11D0, [0x92, 0xB2, 0x00, 0xA0, 0xC9, 0x05, 0x5F, 0xC5]};\nconst IID GUID_BUS_TYPE_LPTENUM = {0xC4CA1000, 0x2DDC, 0x11D5, [0xA1, 0x7A, 0x00, 0xC0, 0x4F, 0x60, 0x52, 0x4D]};\nconst IID GUID_BUS_TYPE_MCA = {0x1C75997A, 0xDC33, 0x11D0, [0x92, 0xB2, 0x00, 0xA0, 0xC9, 0x05, 0x5F, 0xC5]};\nconst IID GUID_BUS_TYPE_PCI = {0xC8EBDFB0, 0xB510, 0x11D0, [0x80, 0xE5, 0x00, 0xA0, 0xC9, 0x25, 0x42, 0xE3]};\nconst IID GUID_BUS_TYPE_PCMCIA = {0x09343630, 0xAF9F, 0x11D0, [0x92, 0xE9, 0x00, 0x00, 0xF8, 0x1E, 0x1B, 0x30]};\nconst IID GUID_BUS_TYPE_SERENUM = {0x77114A87, 0x8944, 0x11D1, [0xBD, 0x90, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0x2D]};\nconst IID GUID_BUS_TYPE_USB = {0x9D7DEBBC, 0xC85D, 0x11D1, [0x9E, 0xB4, 0x00, 0x60, 0x08, 0xC3, 0xA1, 0x9A]};\nconst IID GUID_BUS_TYPE_USBPRINT = {0x441EE000, 0x4342, 0x11D5, [0xA1, 0x84, 0x00, 0xC0, 0x4F, 0x60, 0x52, 0x4D]};\nconst IID GUID_Button = {0xA36D02F0, 0xC9F3, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_CHECKVALUEEXCLUSIVE = {0x6650430C, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_ChordParam = {0xD2AC289E, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_Clear_All_Bands = {0xD2AC28AB, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_COLOR = {0x66504301, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_ColorControlCallbacks = {0xEFD60CC2, 0x49E7, 0x11D0, [0x88, 0x9D, 0x00, 0xAA, 0x00, 0xBB, 0xB7, 0x6A]};\nconst IID GUID_CommandParam = {0xD2AC289D, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_CommandParam2 = {0x28F97EF7, 0x9538, 0x11D2, [0x97, 0xA9, 0x00, 0xC0, 0x4F, 0xA3, 0x6E, 0x58]};\nconst IID GUID_ConnectToDLSCollection = {0x1DB1AE6B, 0xE92E, 0x11D1, [0xA8, 0xC5, 0x00, 0xC0, 0x4F, 0xA3, 0x72, 0x6E]};\nconst IID GUID_ConstantForce = {0x13541C20, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_CustomForce = {0x13541C2B, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_D3DCallbacks2 = {0x0BA584E1, 0x70B6, 0x11D0, [0x88, 0x9D, 0x00, 0xAA, 0x00, 0xBB, 0xB7, 0x6A]};\nconst IID GUID_D3DCallbacks3 = {0xDDF41230, 0xEC0A, 0x11D0, [0xA9, 0xB6, 0x00, 0xAA, 0x00, 0xC0, 0x99, 0x3E]};\nconst IID GUID_D3DExtendedCaps = {0x7DE41F80, 0x9D93, 0x11D0, [0x89, 0xAB, 0x00, 0xA0, 0xC9, 0x05, 0x41, 0x29]};\nconst IID GUID_D3DParseUnknownCommandCallback = {0x2E04FFA0, 0x98E4, 0x11D1, [0x8C, 0xE1, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0xA8]};\nconst IID GUID_Damper = {0x13541C28, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_DDMoreCaps = {0x880BAF30, 0xB030, 0x11D0, [0x8E, 0xA7, 0x00, 0x60, 0x97, 0x97, 0xEA, 0x5B]};\nconst IID GUID_DDMoreSurfaceCaps = {0x3B8A0466, 0xF269, 0x11D1, [0x88, 0x0B, 0x00, 0xC0, 0x4F, 0xD9, 0x30, 0xC5]};\nconst IID GUID_DDStereoMode = {0xF828169C, 0xA8E8, 0x11D2, [0xA1, 0xF2, 0x00, 0xA0, 0xC9, 0x83, 0xEA, 0xF6]};\nconst IID GUID_DefaultGMCollection = {0xF17E8673, 0xC3B4, 0x11D1, [0x87, 0x0B, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_DEVCLASS_1394 = {0x6BDD1FC1, 0x810F, 0x11D0, [0xBE, 0xC7, 0x08, 0x00, 0x2B, 0xE2, 0x09, 0x2F]};\nconst IID GUID_DEVCLASS_1394DEBUG = {0x66F250D6, 0x7801, 0x4A64, [0xB1, 0x39, 0xEE, 0xA8, 0x0A, 0x45, 0x0B, 0x24]};\nconst IID GUID_DEVCLASS_61883 = {0x7EBEFBC0, 0x3200, 0x11D2, [0xB4, 0xC2, 0x00, 0xA0, 0xC9, 0x69, 0x7D, 0x07]};\nconst IID GUID_DEVCLASS_ADAPTER = {0x4D36E964, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_APMSUPPORT = {0xD45B1C18, 0xC8FA, 0x11D1, [0x9F, 0x77, 0x00, 0x00, 0xF8, 0x05, 0xF5, 0x30]};\nconst IID GUID_DEVCLASS_AVC = {0xC06FF265, 0xAE09, 0x48F0, [0x81, 0x2C, 0x16, 0x75, 0x3D, 0x7C, 0xBA, 0x83]};\nconst IID GUID_DEVCLASS_BATTERY = {0x72631E54, 0x78A4, 0x11D0, [0xBC, 0xF7, 0x00, 0xAA, 0x00, 0xB7, 0xB3, 0x2A]};\nconst IID GUID_DEVCLASS_BLUETOOTH = {0xE0CBF06C, 0xCD8B, 0x4647, [0xBB, 0x8A, 0x26, 0x3B, 0x43, 0xF0, 0xF9, 0x74]};\nconst IID GUID_DEVCLASS_CDROM = {0x4D36E965, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_COMPUTER = {0x4D36E966, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_DECODER = {0x6BDD1FC2, 0x810F, 0x11D0, [0xBE, 0xC7, 0x08, 0x00, 0x2B, 0xE2, 0x09, 0x2F]};\nconst IID GUID_DEVCLASS_DISKDRIVE = {0x4D36E967, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_DISPLAY = {0x4D36E968, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_DOT4 = {0x48721B56, 0x6795, 0x11D2, [0xB1, 0xA8, 0x00, 0x80, 0xC7, 0x2E, 0x74, 0xA2]};\nconst IID GUID_DEVCLASS_DOT4PRINT = {0x49CE6AC8, 0x6F86, 0x11D2, [0xB1, 0xE5, 0x00, 0x80, 0xC7, 0x2E, 0x74, 0xA2]};\nconst IID GUID_DEVCLASS_ENUM1394 = {0xC459DF55, 0xDB08, 0x11D1, [0xB0, 0x09, 0x00, 0xA0, 0xC9, 0x08, 0x1F, 0xF6]};\nconst IID GUID_DEVCLASS_FDC = {0x4D36E969, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_FLOPPYDISK = {0x4D36E980, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_FSFILTER_ACTIVITYMONIT = {0xB86DFF51, 0xA31E, 0x4BAC, [0xB3, 0xCF, 0xE8, 0xCF, 0xE7, 0x5C, 0x9F, 0xC2]};\nconst IID GUID_DEVCLASS_FSFILTER_ANTIVIRUS = {0xB1D1A169, 0xC54F, 0x4379, [0x81, 0xDB, 0xBE, 0xE7, 0xD8, 0x8D, 0x74, 0x54]};\nconst IID GUID_DEVCLASS_FSFILTER_CFSMETADATASER = {0xCDCF0939, 0xB75B, 0x4630, [0xBF, 0x76, 0x80, 0xF7, 0xBA, 0x65, 0x58, 0x84]};\nconst IID GUID_DEVCLASS_FSFILTER_COMPRESSION = {0xF3586BAF, 0xB5AA, 0x49B5, [0x8D, 0x6C, 0x05, 0x69, 0x28, 0x4C, 0x63, 0x9F]};\nconst IID GUID_DEVCLASS_FSFILTER_CONTENTSCREEN = {0x3E3F0674, 0xC83C, 0x4558, [0xBB, 0x26, 0x98, 0x20, 0xE1, 0xEB, 0xA5, 0xC5]};\nconst IID GUID_DEVCLASS_FSFILTER_CONTINUOUSBACK = {0x71AA14F8, 0x6FAD, 0x4622, [0xAD, 0x77, 0x92, 0xBB, 0x9D, 0x7E, 0x69, 0x47]};\nconst IID GUID_DEVCLASS_FSFILTER_COPYPROTECTIO = {0x89786FF1, 0x9C12, 0x402F, [0x9C, 0x9E, 0x17, 0x75, 0x3C, 0x7F, 0x43, 0x75]};\nconst IID GUID_DEVCLASS_FSFILTER_ENCRYPTION = {0xA0A701C0, 0xA511, 0x42FF, [0xAA, 0x6C, 0x06, 0xDC, 0x03, 0x95, 0x57, 0x6F]};\nconst IID GUID_DEVCLASS_FSFILTER_HSM = {0xD546500A, 0x2AEB, 0x45F6, [0x94, 0x82, 0xF4, 0xB1, 0x79, 0x9C, 0x31, 0x77]};\nconst IID GUID_DEVCLASS_FSFILTER_INFRASTRUCTUR = {0xE55FA6F9, 0x128C, 0x4D04, [0xAB, 0xAB, 0x63, 0x0C, 0x74, 0xB1, 0x45, 0x3A]};\nconst IID GUID_DEVCLASS_FSFILTER_OPENFILEBACKU = {0xF8ECAFA6, 0x66D1, 0x41A5, [0x89, 0x9B, 0x66, 0x58, 0x5D, 0x72, 0x16, 0xB7]};\nconst IID GUID_DEVCLASS_FSFILTER_PHYSICALQUOTAM = {0x6A0A8E78, 0xBBA6, 0x4FC4, [0xA7, 0x09, 0x1E, 0x33, 0xCD, 0x09, 0xD6, 0x7E]};\nconst IID GUID_DEVCLASS_FSFILTER_QUOTAMANAGEME = {0x8503C911, 0xA6C7, 0x4919, [0x8F, 0x79, 0x50, 0x28, 0xF5, 0x86, 0x6B, 0x0C]};\nconst IID GUID_DEVCLASS_FSFILTER_REPLICATION = {0x48D3EBC4, 0x4CF8, 0x48FF, [0xB8, 0x69, 0x9C, 0x68, 0xAD, 0x42, 0xEB, 0x9F]};\nconst IID GUID_DEVCLASS_FSFILTER_SECURITYENHANC = {0xD02BC3DA, 0x0C8E, 0x4945, [0x9B, 0xD5, 0xF1, 0x88, 0x3C, 0x22, 0x6C, 0x8C]};\nconst IID GUID_DEVCLASS_FSFILTER_SYSTEM = {0x5D1B9AAA, 0x01E2, 0x46AF, [0x84, 0x9F, 0x27, 0x2B, 0x3F, 0x32, 0x4C, 0x46]};\nconst IID GUID_DEVCLASS_FSFILTER_SYSTEMRECOVER = {0x2DB15374, 0x706E, 0x4131, [0xA0, 0xC7, 0xD7, 0xC7, 0x8E, 0xB0, 0x28, 0x9A]};\nconst IID GUID_DEVCLASS_FSFILTER_UNDELETE = {0xFE8F1572, 0xC67A, 0x48C0, [0xBB, 0xAC, 0x0B, 0x5C, 0x6D, 0x66, 0xCA, 0xFB]};\nconst IID GUID_DEVCLASS_GPS = {0x6BDD1FC3, 0x810F, 0x11D0, [0xBE, 0xC7, 0x08, 0x00, 0x2B, 0xE2, 0x09, 0x2F]};\nconst IID GUID_DEVCLASS_HDC = {0x4D36E96A, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_HIDCLASS = {0x745A17A0, 0x74D3, 0x11D0, [0xB6, 0xFE, 0x00, 0xA0, 0xC9, 0x0F, 0x57, 0xDA]};\nconst IID GUID_DEVCLASS_IMAGE = {0x6BDD1FC6, 0x810F, 0x11D0, [0xBE, 0xC7, 0x08, 0x00, 0x2B, 0xE2, 0x09, 0x2F]};\nconst IID GUID_DEVCLASS_INFRARED = {0x6BDD1FC5, 0x810F, 0x11D0, [0xBE, 0xC7, 0x08, 0x00, 0x2B, 0xE2, 0x09, 0x2F]};\nconst IID GUID_DEVCLASS_KEYBOARD = {0x4D36E96B, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_LEGACYDRIVER = {0x8ECC055D, 0x047F, 0x11D1, [0xA5, 0x37, 0x00, 0x00, 0xF8, 0x75, 0x3E, 0xD1]};\nconst IID GUID_DEVCLASS_MEDIA = {0x4D36E96C, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_MEDIUM_CHANGER = {0xCE5939AE, 0xEBDE, 0x11D0, [0xB1, 0x81, 0x00, 0x00, 0xF8, 0x75, 0x3E, 0xC4]};\nconst IID GUID_DEVCLASS_MODEM = {0x4D36E96D, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_MONITOR = {0x4D36E96E, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_MOUSE = {0x4D36E96F, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_MTD = {0x4D36E970, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_MULTIFUNCTION = {0x4D36E971, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_MULTIPORTSERIAL = {0x50906CB8, 0xBA12, 0x11D1, [0xBF, 0x5D, 0x00, 0x00, 0xF8, 0x05, 0xF5, 0x30]};\nconst IID GUID_DEVCLASS_NET = {0x4D36E972, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_NETCLIENT = {0x4D36E973, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_NETSERVICE = {0x4D36E974, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_NETTRANS = {0x4D36E975, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_NODRIVER = {0x4D36E976, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_PCMCIA = {0x4D36E977, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_PNPPRINTERS = {0x4658EE7E, 0xF050, 0x11D1, [0xB6, 0xBD, 0x00, 0xC0, 0x4F, 0xA3, 0x72, 0xA7]};\nconst IID GUID_DEVCLASS_PORTS = {0x4D36E978, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_PRINTER = {0x4D36E979, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_PRINTERUPGRADE = {0x4D36E97A, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_PROCESSOR = {0x50127DC3, 0x0F36, 0x415E, [0xA6, 0xCC, 0x4C, 0xB3, 0xBE, 0x91, 0x0B, 0x65]};\nconst IID GUID_DEVCLASS_SBP2 = {0xD48179BE, 0xEC20, 0x11D1, [0xB6, 0xB8, 0x00, 0xC0, 0x4F, 0xA3, 0x72, 0xA7]};\nconst IID GUID_DEVCLASS_SCSIADAPTER = {0x4D36E97B, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_SMARTCARDREADER = {0x50DD5230, 0xBA8A, 0x11D1, [0xBF, 0x5D, 0x00, 0x00, 0xF8, 0x05, 0xF5, 0x30]};\nconst IID GUID_DEVCLASS_SOUND = {0x4D36E97C, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_SYSTEM = {0x4D36E97D, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_TAPEDRIVE = {0x6D807884, 0x7D21, 0x11CF, [0x80, 0x1C, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_UNKNOWN = {0x4D36E97E, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVCLASS_USB = {0x36FC9E60, 0xC465, 0x11CF, [0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_DEVCLASS_VOLUME = {0x71A27CDD, 0x812A, 0x11D0, [0xBE, 0xC7, 0x08, 0x00, 0x2B, 0xE2, 0x09, 0x2F]};\nconst IID GUID_DEVCLASS_VOLUMESNAPSHOT = {0x533C5B84, 0xEC70, 0x11D2, [0x95, 0x05, 0x00, 0xC0, 0x4F, 0x79, 0xDE, 0xAF]};\nconst IID GUID_DEVCLASS_WCEUSBS = {0x25DBCE51, 0x6C8F, 0x4A72, [0x8A, 0x6D, 0xB5, 0x4C, 0x2B, 0x4F, 0xC8, 0x35]};\nconst IID GUID_DEVICE_INTERFACE_ARRIVAL = {0xCB3A4004, 0x46F0, 0x11D0, [0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F]};\nconst IID GUID_DEVICE_INTERFACE_REMOVAL = {0xCB3A4005, 0x46F0, 0x11D0, [0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F]};\nconst IID GUID_DEVINTERFACE_CDCHANGER = {0x53F56312, 0xB6BF, 0x11D0, [0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B]};\nconst IID GUID_DEVINTERFACE_CDROM = {0x53F56308, 0xB6BF, 0x11D0, [0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B]};\nconst IID GUID_DEVINTERFACE_COMPORT = {0x86E0D1E0, 0x8089, 0x11D0, [0x9C, 0xE4, 0x08, 0x00, 0x3E, 0x30, 0x1F, 0x73]};\nconst IID GUID_DEVINTERFACE_DISK = {0x53F56307, 0xB6BF, 0x11D0, [0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B]};\nconst IID GUID_DEVINTERFACE_FLOPPY = {0x53F56311, 0xB6BF, 0x11D0, [0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B]};\nconst IID GUID_DEVINTERFACE_MEDIUMCHANGER = {0x53F56310, 0xB6BF, 0x11D0, [0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B]};\nconst IID GUID_DEVINTERFACE_PARTITION = {0x53F5630A, 0xB6BF, 0x11D0, [0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B]};\nconst IID GUID_DEVINTERFACE_SERENUM_BUS_ENUMERA = {0x4D36E978, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_DEVINTERFACE_STORAGEPORT = {0x2ACCFE60, 0xC130, 0x11D2, [0xB0, 0x82, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B]};\nconst IID GUID_DEVINTERFACE_TAPE = {0x53F5630B, 0xB6BF, 0x11D0, [0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B]};\nconst IID GUID_DEVINTERFACE_VOLUME = {0x53F5630D, 0xB6BF, 0x11D0, [0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B]};\nconst IID GUID_DEVINTERFACE_WRITEONCEDISK = {0x53F5630C, 0xB6BF, 0x11D0, [0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B]};\nconst IID GUID_DirectDrawPaletteStream = {0x730C7FFC, 0x5347, 0x11D1, [0x8C, 0x4D, 0x00, 0xC0, 0x4F, 0xD9, 0x30, 0xC5]};\nconst IID GUID_DirectDrawSurfaceStream = {0xE043BC46, 0x5317, 0x11D1, [0x8C, 0x4D, 0x00, 0xC0, 0x4F, 0xD9, 0x30, 0xC5]};\nconst IID GUID_DirectMusicAllTypes = {0xD2AC2893, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_Disable_Auto_Download = {0xD2AC28AA, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_DisableTempo = {0x45FC707D, 0x1DB4, 0x11D2, [0xBC, 0xAC, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEB]};\nconst IID GUID_DisableTimeSig = {0x45FC707B, 0x1DB4, 0x11D2, [0xBC, 0xAC, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEB]};\nconst IID GUID_DMUS_PROP_DLS1 = {0x178F2F27, 0xC364, 0x11D1, [0xA7, 0x60, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x12]};\nconst IID GUID_DMUS_PROP_DLS2 = {0xF14599E5, 0x4689, 0x11D2, [0xAF, 0xA6, 0x00, 0xAA, 0x00, 0x24, 0xD8, 0xB6]};\nconst IID GUID_DMUS_PROP_Effects = {0xCDA8D611, 0x684A, 0x11D2, [0x87, 0x1E, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_DMUS_PROP_GM_Hardware = {0x178F2F24, 0xC364, 0x11D1, [0xA7, 0x60, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x12]};\nconst IID GUID_DMUS_PROP_GS_Capable = {0x6496ABA2, 0x61B0, 0x11D2, [0xAF, 0xA6, 0x00, 0xAA, 0x00, 0x24, 0xD8, 0xB6]};\nconst IID GUID_DMUS_PROP_GS_Hardware = {0x178F2F25, 0xC364, 0x11D1, [0xA7, 0x60, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x12]};\nconst IID GUID_DMUS_PROP_INSTRUMENT2 = {0x865FD372, 0x9F67, 0x11D2, [0x87, 0x2A, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_DMUS_PROP_LegacyCaps = {0xCFA7CDC2, 0x00A1, 0x11D2, [0xAA, 0xD5, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x12]};\nconst IID GUID_DMUS_PROP_MemorySize = {0x178F2F28, 0xC364, 0x11D1, [0xA7, 0x60, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x12]};\nconst IID GUID_DMUS_PROP_SampleMemorySize = {0x178F2F28, 0xC364, 0x11D1, [0xA7, 0x60, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x12]};\nconst IID GUID_DMUS_PROP_SamplePlaybackRate = {0x2A91F713, 0xA4BF, 0x11D2, [0xBB, 0xDF, 0x00, 0x60, 0x08, 0x33, 0xDB, 0xD8]};\nconst IID GUID_DMUS_PROP_SynthSink_DSOUND = {0x0AA97844, 0xC877, 0x11D1, [0x87, 0x0C, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_DMUS_PROP_SynthSink_WAVE = {0x0AA97845, 0xC877, 0x11D1, [0x87, 0x0C, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_DMUS_PROP_Volume = {0xFEDFAE25, 0xE46E, 0x11D1, [0xAA, 0xCE, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x12]};\nconst IID GUID_DMUS_PROP_WavesReverb = {0x04CB5622, 0x32E5, 0x11D2, [0xAF, 0xA6, 0x00, 0xAA, 0x00, 0x24, 0xD8, 0xB6]};\nconst IID GUID_DMUS_PROP_WriteLatency = {0x268A0FA0, 0x60F2, 0x11D2, [0xAF, 0xA6, 0x00, 0xAA, 0x00, 0x24, 0xD8, 0xB6]};\nconst IID GUID_DMUS_PROP_WritePeriod = {0x268A0FA1, 0x60F2, 0x11D2, [0xAF, 0xA6, 0x00, 0xAA, 0x00, 0x24, 0xD8, 0xB6]};\nconst IID GUID_DMUS_PROP_XG_Capable = {0x6496ABA1, 0x61B0, 0x11D2, [0xAF, 0xA6, 0x00, 0xAA, 0x00, 0x24, 0xD8, 0xB6]};\nconst IID GUID_DMUS_PROP_XG_Hardware = {0x178F2F26, 0xC364, 0x11D1, [0xA7, 0x60, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x12]};\nconst IID GUID_Download = {0xD2AC28A7, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_Enable_Auto_Download = {0xD2AC28A9, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_EnableTempo = {0x45FC707E, 0x1DB4, 0x11D2, [0xBC, 0xAC, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEB]};\nconst IID GUID_EnableTimeSig = {0x45FC707C, 0x1DB4, 0x11D2, [0xBC, 0xAC, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEB]};\nconst IID GUID_FONTBOLD = {0x6650430F, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_FONTITALIC = {0x66504310, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_FONTNAME = {0x6650430D, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_FONTSIZE = {0x6650430E, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_FONTSTRIKETHROUGH = {0x66504312, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_FONTUNDERSCORE = {0x66504311, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_Friction = {0x13541C2A, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_HANDLE = {0x66504313, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_HasPathProperties = {0x0002DE81, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID GUID_HIDClass = {0x745A17A0, 0x74D3, 0x11D0, [0xB6, 0xFE, 0x00, 0xA0, 0xC9, 0x0F, 0x57, 0xDA]};\nconst IID GUID_HIMETRIC = {0x66504300, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_HWPROFILE_CHANGE_CANCELLED = {0xCB3A4002, 0x46F0, 0x11D0, [0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F]};\nconst IID GUID_HWPROFILE_CHANGE_COMPLETE = {0xCB3A4003, 0x46F0, 0x11D0, [0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F]};\nconst IID GUID_HWPROFILE_QUERY_CHANGE = {0xCB3A4001, 0x46F0, 0x11D0, [0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F]};\nconst IID GUID_IDirectMusicBand = {0xD2AC28AC, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_IDirectMusicChordMap = {0xD2AC28AD, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_IDirectMusicStyle = {0xD2AC28A1, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_Inertia = {0x13541C29, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_INT_ROUTE_INTERFACE_STANDARD = {0x70941BF4, 0x0073, 0x11D1, [0xA0, 0x9E, 0x00, 0xC0, 0x4F, 0xC3, 0x40, 0xB1]};\nconst IID GUID_Joystick = {0x6F1D2B70, 0xD5A0, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_KernelCallbacks = {0x80863800, 0x6B06, 0x11D0, [0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8]};\nconst IID GUID_KernelCaps = {0xFFAA7540, 0x7AA8, 0x11D0, [0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8]};\nconst IID GUID_Key = {0x55728220, 0xD33C, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_KeyboardClass = {0x4D36E96B, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_LEGACY_DEVICE_DETECTION_STANDAR = {0x50FEB0DE, 0x596A, 0x11D2, [0xA5, 0xB8, 0x00, 0x00, 0xF8, 0x1A, 0x46, 0x19]};\nconst IID GUID_MediaClass = {0x4D36E96C, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_MF_ENUMERATION_INTERFACE = {0xAEB895F0, 0x5586, 0x11D1, [0x8D, 0x84, 0x00, 0xA0, 0xC9, 0x06, 0xB2, 0x44]};\nconst IID GUID_Miscellaneous2Callbacks = {0x406B2F00, 0x3E5A, 0x11D1, [0xB6, 0x40, 0x00, 0xAA, 0x00, 0xA1, 0xF9, 0x6A]};\nconst IID GUID_MiscellaneousCallbacks = {0xEFD60CC0, 0x49E7, 0x11D0, [0x88, 0x9D, 0x00, 0xAA, 0x00, 0xBB, 0xB7, 0x6A]};\nconst IID GUID_MotionCompCallbacks = {0xB1122B40, 0x5DA5, 0x11D1, [0x8F, 0xCF, 0x00, 0xC0, 0x4F, 0xC2, 0x9B, 0x4E]};\nconst IID GUID_MouseClass = {0x4D36E96F, 0xE325, 0x11CE, [0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18]};\nconst IID GUID_MuteParam = {0xD2AC28AF, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_NDIS_802_11_ADD_WEP = {0x4307BFF0, 0x2129, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_AUTHENTICATION_MODE = {0x43920A24, 0x2129, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_BASIC_RATES = {0x4A198516, 0x2068, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_BSSID = {0x2504B6C2, 0x1FA5, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_BSSID_LIST = {0x69526F9A, 0x2062, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_BSSID_LIST_SCAN = {0x0D9E01E1, 0xBA70, 0x11D4, [0xB6, 0x75, 0x00, 0x20, 0x48, 0x57, 0x03, 0x37]};\nconst IID GUID_NDIS_802_11_CONFIGURATION = {0x4A4DF982, 0x2068, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_DESIRED_RATES = {0x452EE08E, 0x2536, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_DISASSOCIATE = {0x43671F40, 0x2129, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_FRAGMENTATION_THRESH = {0x69AAA7C4, 0x2062, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_INFRASTRUCTURE_MODE = {0x697D5A7E, 0x2062, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_NETWORK_TYPE_IN_USE = {0x857E2326, 0x2041, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_NETWORK_TYPES_SUPPOR = {0x8531D6E6, 0x2041, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_NUMBER_OF_ANTENNAS = {0x01779336, 0x2064, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_POWER_MODE = {0x85BE837C, 0x2041, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_PRIVACY_FILTER = {0x6733C4E9, 0x4792, 0x11D4, [0x97, 0xF1, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_REMOVE_WEP = {0x433C345C, 0x2129, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_RSSI = {0x1507DB16, 0x2053, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_RSSI_TRIGGER = {0x155689B8, 0x2053, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_RTS_THRESHOLD = {0x0134D07E, 0x2064, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_RX_ANTENNA_SELECTED = {0x01AC07A2, 0x2064, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_SSID = {0x7D2A90EA, 0x2041, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_STATISTICS = {0x42BB73B0, 0x2129, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_SUPPORTED_RATES = {0x49DB8722, 0x2068, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_TX_ANTENNA_SELECTED = {0x01DBB74A, 0x2064, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_TX_POWER_LEVEL = {0x11E6BA76, 0x2053, 0x11D4, [0x97, 0xEB, 0x00, 0xC0, 0x4F, 0x79, 0xC4, 0x03]};\nconst IID GUID_NDIS_802_11_WEP_STATUS = {0xB027A21F, 0x3CFA, 0x4125, [0x80, 0x0B, 0x3F, 0x7A, 0x18, 0xFD, 0xDC, 0xDC]};\nconst IID GUID_NDIS_802_3_CURRENT_ADDRESS = {0x44795700, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_3_MAC_OPTIONS = {0x44795703, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_3_MAXIMUM_LIST_SIZE = {0x44795702, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_3_MULTICAST_LIST = {0x44795701, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_3_PERMANENT_ADDRESS = {0x447956FF, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_3_RCV_ERROR_ALIGNMENT = {0x44795704, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_3_XMIT_MORE_COLLISIONS = {0x44795706, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_3_XMIT_ONE_COLLISION = {0x44795705, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_5_CURRENT_ADDRESS = {0x44795708, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_5_CURRENT_FUNCTIONAL = {0x44795709, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_5_CURRENT_GROUP = {0x4479570A, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_5_CURRENT_RING_STATE = {0xACF14032, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_5_CURRENT_RING_STATUS = {0x890A36EC, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_5_LAST_OPEN_STATUS = {0x4479570B, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_5_LINE_ERRORS = {0xACF14033, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_5_LOST_FRAMES = {0xACF14034, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_802_5_PERMANENT_ADDRESS = {0x44795707, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_HW_CURRENT_ADDRESS = {0x791AD1A1, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_MAX_AAL0_PACKET_SIZE = {0x791AD1A5, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_MAX_AAL1_PACKET_SIZE = {0x791AD1A6, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_MAX_AAL34_PACKET_SIZE = {0x791AD1A7, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_MAX_AAL5_PACKET_SIZE = {0x791AD191, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_MAX_ACTIVE_VCI_BITS = {0x791AD1A3, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_MAX_ACTIVE_VCS = {0x791AD1A2, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_MAX_ACTIVE_VPI_BITS = {0x791AD1A4, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_RCV_CELLS_DROPPED = {0x0A21480C, 0xE35F, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_RCV_CELLS_OK = {0x0A21480A, 0xE35F, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_SUPPORTED_AAL_TYPES = {0x791AD1A0, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_SUPPORTED_SERVICE_CATEG = {0x791AD19F, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_SUPPORTED_VC_RATES = {0x791AD19E, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ATM_XMIT_CELLS_OK = {0x0A21480B, 0xE35F, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ENUMERATE_ADAPTER = {0x981F2D7F, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_ENUMERATE_VC = {0x981F2D82, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_ATTACHMENT_TYPE = {0xACF1403D, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_DOWNSTREAM_NODE_LONG = {0xACF1403F, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_FRAME_ERRORS = {0xACF14040, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_FRAMES_LOST = {0xACF14041, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_LCONNECTION_STATE = {0xACF14045, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_LCT_FAILURES = {0xACF14043, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_LEM_REJECTS = {0xACF14044, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_LONG_CURRENT_ADDR = {0xACF14036, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_LONG_MAX_LIST_SIZE = {0xACF14038, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_LONG_MULTICAST_LIST = {0xACF14037, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_LONG_PERMANENT_ADDR = {0xACF14035, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_RING_MGT_STATE = {0xACF14042, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_SHORT_CURRENT_ADDR = {0xACF1403A, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_SHORT_MAX_LIST_SIZE = {0xACF1403C, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_SHORT_MULTICAST_LIST = {0xACF1403B, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_SHORT_PERMANENT_ADDR = {0xACF14039, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_FDDI_UPSTREAM_NODE_LONG = {0xACF1403E, 0xA61C, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_DRIVER_VERSION = {0x791AD198, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_HARDWARE_STATUS = {0x791AD192, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_LINK_SPEED = {0x791AD195, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_MAC_OPTIONS = {0x791AD19A, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_MEDIA_CONNECT_STATU = {0x791AD19B, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_MEDIA_IN_USE = {0x791AD194, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_MEDIA_SUPPORTED = {0x791AD193, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_MINIMUM_LINK_SPEED = {0x791AD19D, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_RCV_PDUS_ERROR = {0x0A214808, 0xE35F, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_RCV_PDUS_NO_BUFFER = {0x0A214809, 0xE35F, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_RCV_PDUS_OK = {0x0A214806, 0xE35F, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_VENDOR_DESCRIPTION = {0x791AD197, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_VENDOR_DRIVER_VERSI = {0x791AD19C, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_VENDOR_ID = {0x791AD196, 0xE35C, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_XMIT_PDUS_ERROR = {0x0A214807, 0xE35F, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CO_XMIT_PDUS_OK = {0x0A214805, 0xE35F, 0x11D0, [0x96, 0x92, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CURRENT_LOOKAHEAD = {0x5EC10361, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_CURRENT_PACKET_FILTER = {0x5EC10360, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_DRIVER_VERSION = {0x5EC10362, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_HARDWARE_STATUS = {0x5EC10354, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_LINK_SPEED = {0x5EC10359, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_MAC_OPTIONS = {0x5EC10365, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_MAXIMUM_FRAME_SIZE = {0x5EC10358, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_MAXIMUM_LOOKAHEAD = {0x5EC10357, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_MAXIMUM_SEND_PACKETS = {0x5EC10367, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_MAXIMUM_TOTAL_SIZE = {0x5EC10363, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_MEDIA_CONNECT_STATUS = {0x5EC10366, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_MEDIA_IN_USE = {0x5EC10356, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_MEDIA_SUPPORTED = {0x5EC10355, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_PHYSICAL_MEDIUM = {0x418CA16D, 0x3937, 0x4208, [0x94, 0x0A, 0xEC, 0x61, 0x96, 0x27, 0x80, 0x85]};\nconst IID GUID_NDIS_GEN_RCV_ERROR = {0x447956FD, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_RCV_NO_BUFFER = {0x447956FE, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_RCV_OK = {0x447956FB, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_RECEIVE_BLOCK_SIZE = {0x5EC1035D, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_RECEIVE_BUFFER_SPACE = {0x5EC1035B, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_TRANSMIT_BLOCK_SIZE = {0x5EC1035C, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_TRANSMIT_BUFFER_SPACE = {0x5EC1035A, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_VENDOR_DESCRIPTION = {0x5EC1035F, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_VENDOR_DRIVER_VERSION = {0x447956F9, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_VENDOR_ID = {0x5EC1035E, 0xA61A, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_VLAN_ID = {0x765DC702, 0xC5E8, 0x4B67, [0x84, 0x3B, 0x3F, 0x5A, 0x4F, 0xF2, 0x64, 0x8B]};\nconst IID GUID_NDIS_GEN_XMIT_ERROR = {0x447956FC, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_GEN_XMIT_OK = {0x447956FA, 0xA61B, 0x11D0, [0x8D, 0xD4, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_LAN_CLASS = {0xAD498944, 0x762F, 0x11D0, [0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_NOTIFY_ADAPTER_ARRIVAL = {0x981F2D81, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_NOTIFY_ADAPTER_REMOVAL = {0x981F2D80, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_NOTIFY_BIND = {0x5413531C, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_NOTIFY_UNBIND = {0x6E3CE1EC, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_NOTIFY_VC_ARRIVAL = {0x182F9E0C, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_NOTIFY_VC_REMOVAL = {0x981F2D79, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_STATUS_LINK_SPEED_CHANGE = {0x981F2D85, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_STATUS_MEDIA_CONNECT = {0x981F2D7D, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_STATUS_MEDIA_DISCONNECT = {0x981F2D7E, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_STATUS_MEDIA_SPECIFIC_INDIC = {0x981F2D84, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_STATUS_RESET_END = {0x981F2D77, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_STATUS_RESET_START = {0x981F2D76, 0xB1F3, 0x11D0, [0x8D, 0xD7, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C]};\nconst IID GUID_NDIS_WAKE_ON_MAGIC_PACKET_ONLY = {0xA14F1C97, 0x8839, 0x4F8A, [0x99, 0x96, 0xA2, 0x89, 0x96, 0xEB, 0xBF, 0x1D]};\nconst IID GUID_NETSHELL_PROPS = {0x2D15A9A1, 0xA556, 0x4189, [0x91, 0xAD, 0x02, 0x74, 0x58, 0xF1, 0x1A, 0x07]};\nconst IID GUID_NonLocalVidMemCaps = {0x86C4FA80, 0x8D84, 0x11D0, [0x94, 0xE8, 0x00, 0xC0, 0x4F, 0xC3, 0x41, 0x37]};\nconst IID GUID_NOTIFICATION_CHORD = {0xD2AC289B, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_NOTIFICATION_COMMAND = {0xD2AC289C, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_NOTIFICATION_MEASUREANDBEAT = {0xD2AC289A, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_NOTIFICATION_PERFORMANCE = {0x81F75BC5, 0x4E5D, 0x11D2, [0xBC, 0xC7, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEB]};\nconst IID GUID_NOTIFICATION_SEGMENT = {0xD2AC2899, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_NULL = {0x00000000, 0x0000, 0x0000, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]};\nconst IID GUID_OPTIONVALUEEXCLUSIVE = {0x6650430B, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_OptSurfaceKmodeInfo = {0xE05C8472, 0x51D4, 0x11D1, [0x8C, 0xCE, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0xA8]};\nconst IID GUID_OptSurfaceUmodeInfo = {0x9D792804, 0x5FA8, 0x11D1, [0x8C, 0xD0, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0xA8]};\nconst IID GUID_PathProperty = {0x0002DE80, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID GUID_PCI_BUS_INTERFACE_STANDARD = {0x496B8281, 0x6F25, 0x11D0, [0xBE, 0xAF, 0x08, 0x00, 0x2B, 0xE2, 0x09, 0x2F]};\nconst IID GUID_PCI_DEVICE_PRESENT_INTERFACE = {0xD1B82C26, 0xBF49, 0x45EF, [0xB2, 0x16, 0x71, 0xCB, 0xD7, 0x88, 0x9B, 0x57]};\nconst IID GUID_PCMCIA_BUS_INTERFACE_STANDARD = {0x76173AF0, 0xC504, 0x11D1, [0x94, 0x7F, 0x00, 0xC0, 0x4F, 0xB9, 0x60, 0xEE]};\nconst IID GUID_PerfAutoDownload = {0xFB09565B, 0x3631, 0x11D2, [0xBC, 0xB8, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEB]};\nconst IID GUID_PerfMasterGrooveLevel = {0xD2AC28B2, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_PerfMasterTempo = {0xD2AC28B0, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_PerfMasterVolume = {0xD2AC28B1, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_PNP_CUSTOM_NOTIFICATION = {0xACA73F8E, 0x8D23, 0x11D1, [0xAC, 0x7D, 0x00, 0x00, 0xF8, 0x75, 0x71, 0xD0]};\nconst IID GUID_PNP_POWER_NOTIFICATION = {0xC2CF0660, 0xEB7A, 0x11D1, [0xBD, 0x7F, 0x00, 0x00, 0xF8, 0x75, 0x71, 0xD0]};\nconst IID GUID_POV = {0xA36D02F2, 0xC9F3, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_POWER_DEVICE_ENABLE = {0x827C0A6F, 0xFEB0, 0x11D0, [0xBD, 0x26, 0x00, 0xAA, 0x00, 0xB7, 0xB3, 0x2A]};\nconst IID GUID_POWER_DEVICE_TIMEOUTS = {0xA45DA735, 0xFEB0, 0x11D0, [0xBD, 0x26, 0x00, 0xAA, 0x00, 0xB7, 0xB3, 0x2A]};\nconst IID GUID_POWER_DEVICE_WAKE_ENABLE = {0xA9546A82, 0xFEB0, 0x11D0, [0xBD, 0x26, 0x00, 0xAA, 0x00, 0xB7, 0xB3, 0x2A]};\nconst IID GUID_QOS_BESTEFFORT_BANDWIDTH = {0xED885290, 0x40EC, 0x11D1, [0x2C, 0x91, 0x00, 0xAA, 0x00, 0x57, 0x49, 0x15]};\nconst IID GUID_QOS_ENABLE_AVG_STATS = {0xBAFB6D11, 0x27C4, 0x4801, [0xA4, 0x6F, 0xEF, 0x80, 0x80, 0xC1, 0x88, 0xC8]};\nconst IID GUID_QOS_ENABLE_WINDOW_ADJUSTMENT = {0xAA966725, 0xD3E9, 0x4C55, [0xB3, 0x35, 0x2A, 0x00, 0x27, 0x9A, 0x1E, 0x64]};\nconst IID GUID_QOS_FLOW_8021P_CONFORMING = {0x08C1E013, 0xFCD2, 0x11D2, [0xBE, 0x1E, 0x00, 0xA0, 0xC9, 0x9E, 0xE6, 0x3B]};\nconst IID GUID_QOS_FLOW_8021P_NONCONFORMING = {0x09023F91, 0xFCD2, 0x11D2, [0xBE, 0x1E, 0x00, 0xA0, 0xC9, 0x9E, 0xE6, 0x3B]};\nconst IID GUID_QOS_FLOW_COUNT = {0x1147F880, 0x40ED, 0x11D1, [0x2C, 0x91, 0x00, 0xAA, 0x00, 0x57, 0x49, 0x15]};\nconst IID GUID_QOS_FLOW_IP_CONFORMING = {0x07F99A8B, 0xFCD2, 0x11D2, [0xBE, 0x1E, 0x00, 0xA0, 0xC9, 0x9E, 0xE6, 0x3B]};\nconst IID GUID_QOS_FLOW_IP_NONCONFORMING = {0x087A5987, 0xFCD2, 0x11D2, [0xBE, 0x1E, 0x00, 0xA0, 0xC9, 0x9E, 0xE6, 0x3B]};\nconst IID GUID_QOS_FLOW_MODE = {0x5C82290A, 0x515A, 0x11D2, [0x8E, 0x58, 0x00, 0xC0, 0x4F, 0xC9, 0xBF, 0xCB]};\nconst IID GUID_QOS_ISSLOW_FLOW = {0xABF273A4, 0xEE07, 0x11D2, [0xBE, 0x1B, 0x00, 0xA0, 0xC9, 0x9E, 0xE6, 0x3B]};\nconst IID GUID_QOS_LATENCY = {0xFC408EF0, 0x40EC, 0x11D1, [0x2C, 0x91, 0x00, 0xAA, 0x00, 0x57, 0x49, 0x15]};\nconst IID GUID_QOS_MAX_OUTSTANDING_SENDS = {0x161FFA86, 0x6120, 0x11D1, [0x2C, 0x91, 0x00, 0xAA, 0x00, 0x57, 0x49, 0x15]};\nconst IID GUID_QOS_NON_BESTEFFORT_LIMIT = {0x185C44E0, 0x40ED, 0x11D1, [0x2C, 0x91, 0x00, 0xAA, 0x00, 0x57, 0x49, 0x15]};\nconst IID GUID_QOS_REMAINING_BANDWIDTH = {0xC4C51720, 0x40EC, 0x11D1, [0x2C, 0x91, 0x00, 0xAA, 0x00, 0x57, 0x49, 0x15]};\nconst IID GUID_QOS_STATISTICS_BUFFER = {0xBB2C0980, 0xE900, 0x11D1, [0xB0, 0x7E, 0x00, 0x80, 0xC7, 0x13, 0x82, 0xBF]};\nconst IID GUID_QOS_TIMER_RESOLUTION = {0xBA10CC88, 0xF13E, 0x11D2, [0xBE, 0x1B, 0x00, 0xA0, 0xC9, 0x9E, 0xE6, 0x3B]};\nconst IID GUID_RampForce = {0x13541C21, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_RhythmParam = {0xD2AC289F, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_RxAxis = {0xA36D02F4, 0xC9F3, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_RyAxis = {0xA36D02F5, 0xC9F3, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_RzAxis = {0xA36D02E3, 0xC9F3, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_SawtoothDown = {0x13541C26, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_SawtoothUp = {0x13541C25, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_SeedVariations = {0x65B76FA5, 0xFF37, 0x11D2, [0x81, 0x4E, 0x00, 0xC0, 0x4F, 0xA3, 0x6E, 0x58]};\nconst IID GUID_Sine = {0x13541C23, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_Slider = {0xA36D02E4, 0xC9F3, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_Spring = {0x13541C27, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_Square = {0x13541C22, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_StandardMIDIFile = {0x06621075, 0xE92E, 0x11D1, [0xA8, 0xC5, 0x00, 0xC0, 0x4F, 0xA3, 0x72, 0x6E]};\nconst IID GUID_SysKeyboard = {0x6F1D2B61, 0xD5A0, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_SysKeyboardEm = {0x6F1D2B82, 0xD5A0, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_SysKeyboardEm2 = {0x6F1D2B83, 0xD5A0, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_SysMouse = {0x6F1D2B60, 0xD5A0, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_SysMouseEm = {0x6F1D2B80, 0xD5A0, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_SysMouseEm2 = {0x6F1D2B81, 0xD5A0, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_TARGET_DEVICE_QUERY_REMOVE = {0xCB3A4006, 0x46F0, 0x11D0, [0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F]};\nconst IID GUID_TARGET_DEVICE_REMOVE_CANCELLED = {0xCB3A4007, 0x46F0, 0x11D0, [0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F]};\nconst IID GUID_TARGET_DEVICE_REMOVE_COMPLETE = {0xCB3A4008, 0x46F0, 0x11D0, [0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F]};\nconst IID GUID_TempoParam = {0xD2AC28A5, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_TimeSignature = {0xD2AC28A4, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_TRANSLATOR_INTERFACE_STANDARD = {0x6C154A92, 0xAACF, 0x11D0, [0x8D, 0x2A, 0x00, 0xA0, 0xC9, 0x06, 0xB2, 0x44]};\nconst IID GUID_Triangle = {0x13541C24, 0x8E33, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID GUID_TRISTATE = {0x6650430A, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_Unknown = {0xA36D02F3, 0xC9F3, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_Unload = {0xD2AC28A8, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID GUID_UserModeDriverInfo = {0xF0B0E8E2, 0x5F97, 0x11D1, [0x8C, 0xD0, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0xA8]};\nconst IID GUID_UserModeDriverPassword = {0x97F861B6, 0x60A1, 0x11D1, [0x8C, 0xD0, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0xA8]};\nconst IID GUID_VideoPortCallbacks = {0xEFD60CC1, 0x49E7, 0x11D0, [0x88, 0x9D, 0x00, 0xAA, 0x00, 0xBB, 0xB7, 0x6A]};\nconst IID GUID_VideoPortCaps = {0xEFD60CC3, 0x49E7, 0x11D0, [0x88, 0x9D, 0x00, 0xAA, 0x00, 0xBB, 0xB7, 0x6A]};\nconst IID GUID_XAxis = {0xA36D02E0, 0xC9F3, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_XPOS = {0x66504306, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_XPOSPIXEL = {0x66504302, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_XSIZE = {0x66504308, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_XSIZEPIXEL = {0x66504304, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_YAxis = {0xA36D02E1, 0xC9F3, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_YPOS = {0x66504307, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_YPOSPIXEL = {0x66504303, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_YSIZE = {0x66504309, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_YSIZEPIXEL = {0x66504305, 0xBE0F, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID GUID_ZAxis = {0xA36D02E2, 0xC9F3, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID GUID_ZPixelFormats = {0x93869880, 0x36CF, 0x11D1, [0x9B, 0x1B, 0x00, 0xAA, 0x00, 0xBB, 0xB8, 0xAE]};\nconst IID IID_AsyncIAdviseSink = {0x00000150, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_AsyncIAdviseSink2 = {0x00000151, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_AsyncIBackgroundCopyCallback = {0xCA29D251, 0xB4BB, 0x4679, [0xA3, 0xD9, 0xAE, 0x80, 0x06, 0x11, 0x9D, 0x54]};\nconst IID IID_AsyncIClusCfgBaseCluster = {0xA8A5C614, 0x2518, 0x47F5, [0x96, 0xCA, 0xCA, 0xFA, 0x7F, 0xFB, 0xAF, 0x68]};\nconst IID IID_AsyncIClusCfgCallback = {0xEBCE8945, 0xAC69, 0x4B3A, [0x86, 0x5D, 0xE2, 0xD4, 0xEB, 0x33, 0xE4, 0x1B]};\nconst IID IID_AsyncIClusCfgClusterInfo = {0x8BDBA247, 0x04F5, 0x4114, [0x83, 0x7E, 0xB2, 0x63, 0x41, 0x2A, 0x4B, 0x64]};\nconst IID IID_AsyncIClusCfgCredentials = {0x54AA9406, 0xA409, 0x4B49, [0xB3, 0x14, 0x5F, 0x0A, 0x0C, 0xE4, 0xC8, 0x8F]};\nconst IID IID_AsyncIClusCfgEvictCleanup = {0x6FE3E362, 0xD373, 0x4C5F, [0xA0, 0xAF, 0x1D, 0xFE, 0x84, 0x93, 0xC6, 0x55]};\nconst IID IID_AsyncIClusCfgInitialize = {0x2A0EB82E, 0xF878, 0x492A, [0x95, 0x1E, 0xAE, 0x00, 0x09, 0x18, 0xC4, 0xA6]};\nconst IID IID_AsyncIClusCfgIPAddressInfo = {0xAAEAF0A5, 0xE310, 0x4604, [0xA5, 0x5E, 0x2F, 0x9D, 0xDC, 0x41, 0x57, 0xA9]};\nconst IID IID_AsyncIClusCfgManagedResourceInfo = {0x73616028, 0x1243, 0x4749, [0xAD, 0x84, 0x0B, 0x5E, 0xB3, 0x58, 0xFF, 0xA0]};\nconst IID IID_AsyncIClusCfgMemberSetChangeListe = {0x2B645350, 0x2643, 0x4ABC, [0xA4, 0xE5, 0x82, 0x4D, 0x88, 0x1B, 0x75, 0x82]};\nconst IID IID_AsyncIClusCfgNetworkInfo = {0xED71FD2D, 0xAD02, 0x4DFC, [0xB3, 0x76, 0x5F, 0xFA, 0x5F, 0x5A, 0x7C, 0x2C]};\nconst IID IID_AsyncIClusCfgNodeInfo = {0x4F3BB40B, 0xDF27, 0x40A0, [0xB3, 0x1A, 0xBA, 0x18, 0x32, 0x4C, 0xEB, 0x9D]};\nconst IID IID_AsyncIClusCfgPartitionInfo = {0xEC1EBD9F, 0x5866, 0x4846, [0x89, 0x52, 0xEC, 0x36, 0xC3, 0x96, 0x1E, 0xEF]};\nconst IID IID_AsyncIClusCfgResourceTypeCreate = {0x3AFCE3B9, 0x5F3E, 0x4DDF, [0xA8, 0xF4, 0x4B, 0x4F, 0xCB, 0xF2, 0x8F, 0x8F]};\nconst IID IID_AsyncIClusCfgResourceTypeInfo = {0xC649A282, 0xC847, 0x4F5C, [0x98, 0x41, 0xD2, 0xF7, 0x3B, 0x5A, 0xA7, 0x1D]};\nconst IID IID_AsyncIClusCfgServer = {0x2A1640AA, 0x4561, 0x4A08, [0xB5, 0xD9, 0x0A, 0xA3, 0x8C, 0x6B, 0xE6, 0x28]};\nconst IID IID_AsyncIClusCfgStartupListener = {0xD282CAF0, 0x2EDE, 0x4AB9, [0xA5, 0xD5, 0xF7, 0xBD, 0xE3, 0xD2, 0x3F, 0x10]};\nconst IID IID_AsyncIClusCfgStartupNotify = {0xC2B0D06A, 0x6353, 0x4EE1, [0xB2, 0x53, 0x6B, 0x0D, 0x75, 0xDB, 0x2C, 0xD3]};\nconst IID IID_AsyncIEnumClusCfgIPAddresses = {0xBD5F35BA, 0x0BC0, 0x455F, [0x92, 0x6D, 0xC3, 0xD3, 0x56, 0x41, 0x94, 0x87]};\nconst IID IID_AsyncIEnumClusCfgManagedResource = {0xB138483F, 0x9695, 0x4FA6, [0xA9, 0x8F, 0x0D, 0xE2, 0xFB, 0x35, 0x54, 0x49]};\nconst IID IID_AsyncIEnumClusCfgNetworks = {0xF56B9B0D, 0xE7B8, 0x49EC, [0xA8, 0x43, 0x54, 0x75, 0x07, 0x6B, 0x94, 0x7D]};\nconst IID IID_AsyncIEnumClusCfgPartitions = {0x4440BB6A, 0xB0AC, 0x479D, [0xB5, 0x34, 0x72, 0x65, 0xA3, 0x1D, 0x6C, 0x56]};\nconst IID IID_AsyncIMultiQI = {0x000E0020, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_AsyncIPipeByte = {0xDB2F3ACB, 0x2F86, 0x11D1, [0x8E, 0x04, 0x00, 0xC0, 0x4F, 0xB9, 0x98, 0x9A]};\nconst IID IID_AsyncIPipeDouble = {0xDB2F3ACF, 0x2F86, 0x11D1, [0x8E, 0x04, 0x00, 0xC0, 0x4F, 0xB9, 0x98, 0x9A]};\nconst IID IID_AsyncIPipeLong = {0xDB2F3ACD, 0x2F86, 0x11D1, [0x8E, 0x04, 0x00, 0xC0, 0x4F, 0xB9, 0x98, 0x9A]};\nconst IID IID_AsyncIUnknown = {0x000E0000, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_DFConstraint = {0x4A3DF050, 0x23BD, 0x11D2, [0x93, 0x9F, 0x00, 0xA0, 0xC9, 0x1E, 0xED, 0xBA]};\nconst IID IID_DIEnumWbemClassObject = {0xCB7CA037, 0xF729, 0x11D0, [0x9E, 0x4D, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID IID_DIWbemCallResult = {0xCB7CA039, 0xF729, 0x11D0, [0x9E, 0x4D, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID IID_DIWbemClassObject = {0xCB7CA033, 0xF729, 0x11D0, [0x9E, 0x4D, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID IID_DIWbemContext = {0xCB7CA038, 0xF729, 0x11D0, [0x9E, 0x4D, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID IID_DIWbemLocator = {0xCB7CA035, 0xF729, 0x11D0, [0x9E, 0x4D, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID IID_DIWbemObjectSink = {0xCB7CA036, 0xF729, 0x11D0, [0x9E, 0x4D, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID IID_DIWbemQualifierSet = {0xCB7CA034, 0xF729, 0x11D0, [0x9E, 0x4D, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID IID_DIWbemServices = {0xCB7CA03A, 0xF729, 0x11D0, [0x9E, 0x4D, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID IID_Folder = {0xBBCBDE60, 0xC3FF, 0x11CE, [0x83, 0x50, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_Folder2 = {0xF0D2D8EF, 0x3890, 0x11D2, [0xBF, 0x8B, 0x00, 0xC0, 0x4F, 0xB9, 0x36, 0x61]};\nconst IID IID_Folder3 = {0xA7AE5F64, 0xC4D7, 0x4D7F, [0x93, 0x07, 0x4D, 0x24, 0xEE, 0x54, 0xB8, 0x41]};\nconst IID IID_FolderItem = {0xFAC32C80, 0xCBE4, 0x11CE, [0x83, 0x50, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_FolderItem2 = {0xEDC817AA, 0x92B8, 0x11D1, [0xB0, 0x75, 0x00, 0xC0, 0x4F, 0xC3, 0x3A, 0xA5]};\nconst IID IID_FolderItems = {0x744129E0, 0xCBE5, 0x11CE, [0x83, 0x50, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_FolderItems2 = {0xC94F0AD0, 0xF363, 0x11D2, [0xA3, 0x27, 0x00, 0xC0, 0x4F, 0x8E, 0xEC, 0x7F]};\nconst IID IID_FolderItems3 = {0xEAA7C309, 0xBBEC, 0x49D5, [0x82, 0x1D, 0x64, 0xD9, 0x66, 0xCB, 0x66, 0x7F]};\nconst IID IID_FolderItemVerb = {0x08EC3E00, 0x50B0, 0x11CF, [0x96, 0x0C, 0x00, 0x80, 0xC7, 0xF4, 0xEE, 0x85]};\nconst IID IID_FolderItemVerbs = {0x1F8352C0, 0x50B0, 0x11CF, [0x96, 0x0C, 0x00, 0x80, 0xC7, 0xF4, 0xEE, 0x85]};\nconst IID IID_IAccessControl = {0xEEDD23E0, 0x8410, 0x11CE, [0xA1, 0xC3, 0x08, 0x00, 0x2B, 0x2B, 0x8D, 0x8F]};\nconst IID IID_IAccessible = {0x618736E0, 0x3C3D, 0x11CF, [0x81, 0x0C, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71]};\nconst IID IID_IAccessibleHandler = {0x03022430, 0xABC4, 0x11D0, [0xBD, 0xE2, 0x00, 0xAA, 0x00, 0x1A, 0x19, 0x53]};\nconst IID IID_IAccessor = {0x0C733A8C, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IAccIdentity = {0x7852B78D, 0x1CFD, 0x41C1, [0xA6, 0x15, 0x9C, 0x0C, 0x85, 0x96, 0x0B, 0x5F]};\nconst IID IID_IAccountDiscovery = {0xFA202BBC, 0x6ABE, 0x4C17, [0xB1, 0x84, 0x57, 0x0B, 0x6C, 0xF2, 0x56, 0xA6]};\nconst IID IID_IAccPropServer = {0x76C0DBBB, 0x15E0, 0x4E7B, [0xB6, 0x1B, 0x20, 0xEE, 0xEA, 0x20, 0x01, 0xE0]};\nconst IID IID_IAccPropServices = {0x6E26E776, 0x04F0, 0x495D, [0x80, 0xE4, 0x33, 0x30, 0x35, 0x2E, 0x31, 0x69]};\nconst IID IID_IACList = {0x77A130B0, 0x94FD, 0x11D0, [0xA5, 0x44, 0x00, 0xC0, 0x4F, 0xD7, 0xD0, 0x62]};\nconst IID IID_IACList2 = {0x470141A0, 0x5186, 0x11D2, [0xBB, 0xB6, 0x00, 0x60, 0x97, 0x7B, 0x46, 0x4C]};\nconst IID IID_IActionProgress = {0x49FF1173, 0xEADC, 0x446D, [0x92, 0x85, 0x15, 0x64, 0x53, 0xA6, 0x43, 0x1C]};\nconst IID IID_IActionProgressDialog = {0x49FF1172, 0xEADC, 0x446D, [0x92, 0x85, 0x15, 0x64, 0x53, 0xA6, 0x43, 0x1C]};\nconst IID IID_IActiveDesktop = {0xF490EB00, 0x1240, 0x11D1, [0x98, 0x88, 0x00, 0x60, 0x97, 0xDE, 0xAC, 0xF9]};\nconst IID IID_IActiveIME = {0x6FE20962, 0xD077, 0x11D0, [0x8F, 0xE7, 0x00, 0xAA, 0x00, 0x6B, 0xCC, 0x59]};\nconst IID IID_IActiveIME2 = {0xE1C4BF0E, 0x2D53, 0x11D2, [0x93, 0xE1, 0x00, 0x60, 0xB0, 0x67, 0xB8, 0x6E]};\nconst IID IID_IActiveIMMApp = {0x08C0E040, 0x62D1, 0x11D1, [0x93, 0x26, 0x00, 0x60, 0xB0, 0x67, 0xB8, 0x6E]};\nconst IID IID_IActiveIMMIME = {0x08C03411, 0xF96B, 0x11D0, [0xA4, 0x75, 0x00, 0xAA, 0x00, 0x6B, 0xCC, 0x59]};\nconst IID IID_IActiveIMMMessagePumpOwner = {0xB5CF2CFA, 0x8AEB, 0x11D1, [0x93, 0x64, 0x00, 0x60, 0xB0, 0x67, 0xB8, 0x6E]};\nconst IID IID_IActiveIMMRegistrar = {0xB3458082, 0xBD00, 0x11D1, [0x93, 0x9B, 0x00, 0x60, 0xB0, 0x67, 0xB8, 0x6E]};\nconst IID IID_IActiveScript = {0xBB1A2AE1, 0xA4F9, 0x11CF, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID IID_IActiveScriptAuthor = {0x9C109DA0, 0x7006, 0x11D1, [0xB3, 0x6C, 0x00, 0xA0, 0xC9, 0x11, 0xE8, 0xB2]};\nconst IID IID_IActiveScriptAuthorProcedure = {0x7E2D4B70, 0xBD9A, 0x11D0, [0x93, 0x36, 0x00, 0xA0, 0xC9, 0x0D, 0xCA, 0xA9]};\nconst IID IID_IActiveScriptDebug = {0x51973C10, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IActiveScriptDebug32 = {0x51973C10, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IActiveScriptDebug64 = {0xBC437E23, 0xF5B8, 0x47F4, [0xBB, 0x79, 0x7D, 0x1C, 0xE5, 0x48, 0x3B, 0x86]};\nconst IID IID_IActiveScriptEncode = {0xBB1A2AE3, 0xA4F9, 0x11CF, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID IID_IActiveScriptError = {0xEAE1BA61, 0xA4ED, 0x11CF, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID IID_IActiveScriptError64 = {0xB21FB2A1, 0x5B8F, 0x4963, [0x8C, 0x21, 0x21, 0x45, 0x0F, 0x84, 0xED, 0x7F]};\nconst IID IID_IActiveScriptErrorDebug = {0x51973C12, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IActiveScriptGarbageCollector = {0x6AA2C4A0, 0x2B53, 0x11D4, [0xA2, 0xA0, 0x00, 0x10, 0x4B, 0xD3, 0x50, 0x90]};\nconst IID IID_IActiveScriptHostEncode = {0xBEE9B76E, 0xCFE3, 0x11D1, [0xB7, 0x47, 0x00, 0xC0, 0x4F, 0xC2, 0xB0, 0x85]};\nconst IID IID_IActiveScriptParse = {0xBB1A2AE2, 0xA4F9, 0x11CF, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID IID_IActiveScriptParse32 = {0xBB1A2AE2, 0xA4F9, 0x11CF, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID IID_IActiveScriptParse64 = {0xC7EF7658, 0xE1EE, 0x480E, [0x97, 0xEA, 0xD5, 0x2C, 0xB4, 0xD7, 0x6D, 0x17]};\nconst IID IID_IActiveScriptParseProcedure = {0xAA5B6A80, 0xB834, 0x11D0, [0x93, 0x2F, 0x00, 0xA0, 0xC9, 0x0D, 0xCA, 0xA9]};\nconst IID IID_IActiveScriptParseProcedure2_32 = {0x71EE5B20, 0xFB04, 0x11D1, [0xB3, 0xA8, 0x00, 0xA0, 0xC9, 0x11, 0xE8, 0xB2]};\nconst IID IID_IActiveScriptParseProcedure2_64 = {0xFE7C4271, 0x210C, 0x448D, [0x9F, 0x54, 0x76, 0xDA, 0xB7, 0x04, 0x7B, 0x28]};\nconst IID IID_IActiveScriptParseProcedure32 = {0xAA5B6A80, 0xB834, 0x11D0, [0x93, 0x2F, 0x00, 0xA0, 0xC9, 0x0D, 0xCA, 0xA9]};\nconst IID IID_IActiveScriptParseProcedure64 = {0xC64713B6, 0xE029, 0x4CC5, [0x92, 0x00, 0x43, 0x8B, 0x72, 0x89, 0x0B, 0x6A]};\nconst IID IID_IActiveScriptParseProcedureOld = {0x1CFF0050, 0x6FDD, 0x11D0, [0x93, 0x28, 0x00, 0xA0, 0xC9, 0x0D, 0xCA, 0xA9]};\nconst IID IID_IActiveScriptParseProcedureOld32 = {0x1CFF0050, 0x6FDD, 0x11D0, [0x93, 0x28, 0x00, 0xA0, 0xC9, 0x0D, 0xCA, 0xA9]};\nconst IID IID_IActiveScriptParseProcedureOld64 = {0x21F57128, 0x08C9, 0x4638, [0xBA, 0x12, 0x22, 0xD1, 0x5D, 0x88, 0xDC, 0x5C]};\nconst IID IID_IActiveScriptProperty = {0x4954E0D0, 0xFBC7, 0x11D1, [0x84, 0x10, 0x00, 0x60, 0x08, 0xC3, 0xFB, 0xFC]};\nconst IID IID_IActiveScriptSIPInfo = {0x764651D0, 0x38DE, 0x11D4, [0xA2, 0xA3, 0x00, 0x10, 0x4B, 0xD3, 0x50, 0x90]};\nconst IID IID_IActiveScriptSite = {0xDB01A1E3, 0xA42B, 0x11CF, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID IID_IActiveScriptSiteDebug32 = {0x51973C11, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IActiveScriptSiteDebug64 = {0xD6B96B0A, 0x7463, 0x402C, [0x92, 0xAC, 0x89, 0x98, 0x42, 0x26, 0x94, 0x2F]};\nconst IID IID_IActiveScriptSiteInterruptPoll = {0x539698A0, 0xCDCA, 0x11CF, [0xA5, 0xEB, 0x00, 0xAA, 0x00, 0x47, 0xA0, 0x63]};\nconst IID IID_IActiveScriptSiteWindow = {0xD10F6761, 0x83E9, 0x11CF, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID IID_IActiveScriptStats = {0xB8DA6310, 0xE19B, 0x11D0, [0x93, 0x3C, 0x00, 0xA0, 0xC9, 0x0D, 0xCA, 0xA9]};\nconst IID IID_IActiveXSafetyProvider = {0x69FF5101, 0xFC63, 0x11D0, [0x97, 0xEB, 0x00, 0xAA, 0x00, 0x61, 0x53, 0x33]};\nconst IID IID_IAdapterInfo = {0x480BF94A, 0x09FD, 0x4F8A, [0xA3, 0xE0, 0xB0, 0x70, 0x02, 0x82, 0xD8, 0x4D]};\nconst IID IID_IAdapterNotificationSink = {0x44AB2DC3, 0x23B2, 0x47DE, [0x82, 0x28, 0x2E, 0x1C, 0xCE, 0xEB, 0x99, 0x11]};\nconst IID IID_IAddEvents = {0xD710A6AE, 0x3371, 0x11D1, [0xBE, 0x5B, 0x00, 0xC0, 0x4F, 0xC9, 0xE2, 0xBB]};\nconst IID IID_IAddressBarParser = {0xC9D81948, 0x443A, 0x40C7, [0x94, 0x5C, 0x5E, 0x17, 0x1B, 0x8C, 0x66, 0xB4]};\nconst IID IID_IAddrExclusionControl = {0x00000148, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IAddrTrackingControl = {0x00000147, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IADs = {0xFD8256D0, 0xFD15, 0x11CE, [0xAB, 0xC4, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53]};\nconst IID IID_IADsAccessControlEntry = {0xB4F3A14C, 0x9BDD, 0x11D0, [0x85, 0x2C, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsAccessControlList = {0xB7EE91CC, 0x9BDD, 0x11D0, [0x85, 0x2C, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsAcePrivate = {0xFD145DF2, 0xFD96, 0x4135, [0x9B, 0x22, 0x68, 0xFF, 0x0F, 0x6B, 0xF5, 0xBB]};\nconst IID IID_IADsAcl = {0x8452D3AB, 0x0869, 0x11D1, [0xA3, 0x77, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsADSystemInfo = {0x5BB11929, 0xAFD1, 0x11D2, [0x9C, 0xB9, 0x00, 0x00, 0xF8, 0x7A, 0x36, 0x9E]};\nconst IID IID_IADsBackLink = {0xFD1302BD, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsCaseIgnoreList = {0x7B66B533, 0x4680, 0x11D1, [0xA3, 0xB4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsClass = {0xC8F93DD0, 0x4AE0, 0x11CF, [0x9E, 0x73, 0x00, 0xAA, 0x00, 0x4A, 0x56, 0x91]};\nconst IID IID_IADsCollection = {0x72B945E0, 0x253B, 0x11CF, [0xA9, 0x88, 0x00, 0xAA, 0x00, 0x6B, 0xC1, 0x49]};\nconst IID IID_IADsComputer = {0xEFE3CC70, 0x1D9F, 0x11CF, [0xB1, 0xF3, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53]};\nconst IID IID_IADsComputerOperations = {0xEF497680, 0x1D9F, 0x11CF, [0xB1, 0xF3, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53]};\nconst IID IID_IADsContainer = {0x001677D0, 0xFD16, 0x11CE, [0xAB, 0xC4, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53]};\nconst IID IID_IADsDeleteOps = {0xB2BD0902, 0x8878, 0x11D1, [0x8C, 0x21, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsDNWithBinary = {0x7E99C0A2, 0xF935, 0x11D2, [0xBA, 0x96, 0x00, 0xC0, 0x4F, 0xB6, 0xD0, 0xD1]};\nconst IID IID_IADsDNWithString = {0x370DF02E, 0xF934, 0x11D2, [0xBA, 0x96, 0x00, 0xC0, 0x4F, 0xB6, 0xD0, 0xD1]};\nconst IID IID_IADsDomain = {0x00E4C220, 0xFD16, 0x11CE, [0xAB, 0xC4, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53]};\nconst IID IID_IADsEmail = {0x97AF011A, 0x478E, 0x11D1, [0xA3, 0xB4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsExtension = {0x3D35553C, 0xD2B0, 0x11D1, [0xB1, 0x7B, 0x00, 0x00, 0xF8, 0x75, 0x93, 0xA0]};\nconst IID IID_IADsFaxNumber = {0xA910DEA9, 0x4680, 0x11D1, [0xA3, 0xB4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsFileService = {0xA89D1900, 0x31CA, 0x11CF, [0xA9, 0x8A, 0x00, 0xAA, 0x00, 0x6B, 0xC1, 0x49]};\nconst IID IID_IADsFileServiceOperations = {0xA02DED10, 0x31CA, 0x11CF, [0xA9, 0x8A, 0x00, 0xAA, 0x00, 0x6B, 0xC1, 0x49]};\nconst IID IID_IADsFileShare = {0xEB6DCAF0, 0x4B83, 0x11CF, [0xA9, 0x95, 0x00, 0xAA, 0x00, 0x6B, 0xC1, 0x49]};\nconst IID IID_IADsGroup = {0x27636B00, 0x410F, 0x11CF, [0xB1, 0xFF, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53]};\nconst IID IID_IADsHold = {0xB3EB3B37, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsLargeInteger = {0x9068270B, 0x0939, 0x11D1, [0x8B, 0xE1, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsLocality = {0xA05E03A2, 0xEFFE, 0x11CF, [0x8A, 0xBC, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsMembers = {0x451A0030, 0x72EC, 0x11CF, [0xB0, 0x3B, 0x00, 0xAA, 0x00, 0x6E, 0x09, 0x75]};\nconst IID IID_IADsNamespaces = {0x28B96BA0, 0xB330, 0x11CF, [0xA9, 0xAD, 0x00, 0xAA, 0x00, 0x6B, 0xC1, 0x49]};\nconst IID IID_IADsNameTranslate = {0xB1B272A3, 0x3625, 0x11D1, [0xA3, 0xA4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsNetAddress = {0xB21A50A9, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsO = {0xA1CD2DC6, 0xEFFE, 0x11CF, [0x8A, 0xBC, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsObjectOptions = {0x46F14FDA, 0x232B, 0x11D1, [0xA8, 0x08, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0xA8]};\nconst IID IID_IADsObjOptPrivate = {0x81CBB829, 0x1867, 0x11D2, [0x92, 0x20, 0x00, 0xC0, 0x4F, 0xB6, 0xD0, 0xD1]};\nconst IID IID_IADsOctetList = {0x7B28B80F, 0x4680, 0x11D1, [0xA3, 0xB4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsOpenDSObject = {0xDDF2891E, 0x0F9C, 0x11D0, [0x8A, 0xD4, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsOU = {0xA2F733B8, 0xEFFE, 0x11CF, [0x8A, 0xBC, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsPath = {0xB287FCD5, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsPathname = {0xD592AED4, 0xF420, 0x11D0, [0xA3, 0x6E, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsPathnameProvider = {0xAACD1D30, 0x8BD0, 0x11D2, [0x92, 0xA9, 0x00, 0xC0, 0x4F, 0x79, 0xF8, 0x34]};\nconst IID IID_IADsPostalAddress = {0x7ADECF29, 0x4680, 0x11D1, [0xA3, 0xB4, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsPrintJob = {0x32FB6780, 0x1ED0, 0x11CF, [0xA9, 0x88, 0x00, 0xAA, 0x00, 0x6B, 0xC1, 0x49]};\nconst IID IID_IADsPrintJobOperations = {0x9A52DB30, 0x1ECF, 0x11CF, [0xA9, 0x88, 0x00, 0xAA, 0x00, 0x6B, 0xC1, 0x49]};\nconst IID IID_IADsPrintQueue = {0xB15160D0, 0x1226, 0x11CF, [0xA9, 0x85, 0x00, 0xAA, 0x00, 0x6B, 0xC1, 0x49]};\nconst IID IID_IADsPrintQueueOperations = {0x124BE5C0, 0x156E, 0x11CF, [0xA9, 0x86, 0x00, 0xAA, 0x00, 0x6B, 0xC1, 0x49]};\nconst IID IID_IADsProperty = {0xC8F93DD3, 0x4AE0, 0x11CF, [0x9E, 0x73, 0x00, 0xAA, 0x00, 0x4A, 0x56, 0x91]};\nconst IID IID_IADsPropertyEntry = {0x05792C8E, 0x941F, 0x11D0, [0x85, 0x29, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsPropertyList = {0xC6F602B6, 0x8F69, 0x11D0, [0x85, 0x28, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsPropertyValue = {0x79FA9AD0, 0xA97C, 0x11D0, [0x85, 0x34, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsPropertyValue2 = {0x306E831C, 0x5BC7, 0x11D1, [0xA3, 0xB8, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsReplicaPointer = {0xF60FB803, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsResource = {0x34A05B20, 0x4AAB, 0x11CF, [0xAE, 0x2C, 0x00, 0xAA, 0x00, 0x6E, 0xBF, 0xB9]};\nconst IID IID_IADsSearch = {0xC69F7780, 0x4008, 0x11D0, [0xB9, 0x4C, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0xA8]};\nconst IID IID_IADsSecurityDescriptor = {0xB8C787CA, 0x9BDD, 0x11D0, [0x85, 0x2C, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsSecurityUtility = {0xA63251B2, 0x5F21, 0x474B, [0xAB, 0x52, 0x4A, 0x8E, 0xFA, 0xD1, 0x08, 0x95]};\nconst IID IID_IADsService = {0x68AF66E0, 0x31CA, 0x11CF, [0xA9, 0x8A, 0x00, 0xAA, 0x00, 0x6B, 0xC1, 0x49]};\nconst IID IID_IADsServiceOperations = {0x5D7B33F0, 0x31CA, 0x11CF, [0xA9, 0x8A, 0x00, 0xAA, 0x00, 0x6B, 0xC1, 0x49]};\nconst IID IID_IADsSession = {0x398B7DA0, 0x4AAB, 0x11CF, [0xAE, 0x2C, 0x00, 0xAA, 0x00, 0x6E, 0xBF, 0xB9]};\nconst IID IID_IADsSyntax = {0xC8F93DD2, 0x4AE0, 0x11CF, [0x9E, 0x73, 0x00, 0xAA, 0x00, 0x4A, 0x56, 0x91]};\nconst IID IID_IADsTimestamp = {0xB2F5A901, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsTypedName = {0xB371A349, 0x4080, 0x11D1, [0xA3, 0xAC, 0x00, 0xC0, 0x4F, 0xB9, 0x50, 0xDC]};\nconst IID IID_IADsUmiHelperPrivate = {0x4FE243F0, 0xAD89, 0x4CBC, [0x9B, 0x14, 0x48, 0x61, 0x26, 0x44, 0x6A, 0xE0]};\nconst IID IID_IADsUser = {0x3E37E320, 0x17E2, 0x11CF, [0xAB, 0xC4, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53]};\nconst IID IID_IADsValue = {0x1E3EF0AA, 0xAEF5, 0x11D0, [0x85, 0x37, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IADsWinNTSystemInfo = {0x6C6D65DC, 0xAFD1, 0x11D2, [0x9C, 0xB9, 0x00, 0x00, 0xF8, 0x7A, 0x36, 0x9E]};\nconst IID IID_IAdviseSink = {0x0000010F, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IAdviseSink2 = {0x00000125, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IAdviseSinkEx = {0x3AF24290, 0x0C96, 0x11CE, [0xA0, 0xCF, 0x00, 0xAA, 0x00, 0x60, 0x0A, 0xB8]};\nconst IID IID_IAlertReport = {0x4E81DFE8, 0x4CA0, 0x101A, [0x82, 0x06, 0x08, 0x00, 0x2B, 0x2F, 0xC0, 0x9B]};\nconst IID IID_IAlertTarget = {0x589B61C0, 0x54E6, 0x11CE, [0x94, 0xDD, 0x00, 0xAA, 0x00, 0x51, 0xE4, 0x0F]};\nconst IID IID_IAlgSetup = {0xA779AF1A, 0x009A, 0x4C44, [0xB9, 0xF0, 0x8F, 0x0F, 0x4C, 0xF2, 0xAE, 0x49]};\nconst IID IID_IAlterIndex = {0x0C733AA6, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IAlterTable = {0x0C733AA5, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IAnchorClick = {0x13D5413B, 0x33B9, 0x11D2, [0x95, 0xA7, 0x00, 0xC0, 0x4F, 0x8E, 0xCB, 0x02]};\nconst IID IID_IAnimationComposer = {0x5459C83D, 0x322B, 0x44B3, [0x8D, 0xAA, 0x24, 0xC9, 0x47, 0xE7, 0xB2, 0x75]};\nconst IID IID_IAnimationComposer2 = {0x1A4F0E79, 0x09CD, 0x47F3, [0xAF, 0xF1, 0x48, 0x3B, 0xF3, 0xA2, 0x22, 0xDC]};\nconst IID IID_IAnimationComposerFactory = {0xBEEB3233, 0xF71F, 0x4683, [0x8B, 0x05, 0x9A, 0x53, 0x14, 0xC9, 0x7D, 0xBC]};\nconst IID IID_IAnimationComposerSite = {0x488FCB56, 0x8FD6, 0x4CDA, [0xA0, 0x6A, 0x5B, 0xB2, 0x32, 0x93, 0x0E, 0xCA]};\nconst IID IID_IAnimationComposerSiteFactory = {0xB4EA5681, 0xED72, 0x4EFE, [0xBB, 0xD7, 0x7C, 0x47, 0xD1, 0x32, 0x56, 0x96]};\nconst IID IID_IAnimationComposerSiteSink = {0x8EF76C64, 0x71CD, 0x480F, [0x96, 0xFC, 0xBA, 0x26, 0x96, 0xE6, 0x59, 0xBE]};\nconst IID IID_IAnimationFragment = {0x319DFD88, 0x0AC6, 0x4AB1, [0xA1, 0x9F, 0x90, 0x22, 0x3B, 0xA2, 0xDA, 0x16]};\nconst IID IID_IAnimationRoot = {0x29DF6387, 0x30B4, 0x4A62, [0x89, 0x1B, 0xA9, 0xC5, 0xBE, 0x37, 0xBE, 0x88]};\nconst IID IID_IApplicationDebugger = {0x51973C2A, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IApplicationDebuggerUI = {0x51973C2B, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IApplicationGateway = {0x5134842B, 0xFDCE, 0x485D, [0x93, 0xCD, 0xDE, 0x16, 0x40, 0x64, 0x3B, 0xBE]};\nconst IID IID_IApplicationGatewayServices = {0x5134842A, 0xFDCE, 0x485D, [0x93, 0xCD, 0xDE, 0x16, 0x40, 0x64, 0x3B, 0xBE]};\nconst IID IID_IAppPublisher = {0x07250A10, 0x9CF9, 0x11D1, [0x90, 0x76, 0x00, 0x60, 0x08, 0x05, 0x93, 0x82]};\nconst IID IID_IAsyncBindCtx = {0x79EAC9D4, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IAsyncManager = {0x0000002A, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IAsyncMoniker = {0x79EAC9D3, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IAsyncOperation = {0x3D8B0590, 0xF691, 0x11D2, [0x8E, 0xA9, 0x00, 0x60, 0x97, 0xDF, 0x5B, 0xD4]};\nconst IID IID_IAsyncRpcChannelBuffer = {0xA5029FB6, 0x3C34, 0x11D1, [0x9C, 0x99, 0x00, 0xC0, 0x4F, 0xB9, 0x98, 0xAA]};\nconst IID IID_IAttributesRaw = {0x6BC096A8, 0x0CE6, 0x11D1, [0xBA, 0xAE, 0x00, 0xC0, 0x4F, 0xC2, 0xE2, 0x0D]};\nconst IID IID_IAuditControl = {0x1DA6292F, 0xBC66, 0x11CE, [0xAA, 0xE3, 0x00, 0xAA, 0x00, 0x4C, 0x27, 0x37]};\nconst IID IID_IAuthenticate = {0x79EAC9D0, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IAutoComplete = {0x00BB2762, 0x6A77, 0x11D0, [0xA5, 0x35, 0x00, 0xC0, 0x4F, 0xD7, 0xD0, 0x62]};\nconst IID IID_IAutoComplete2 = {0xEAC04BC0, 0x3791, 0x11D2, [0xBB, 0x95, 0x00, 0x60, 0x97, 0x7B, 0x46, 0x4C]};\nconst IID IID_IAutoCompleteDropDown = {0x3CD141F4, 0x3C6A, 0x11D2, [0xBC, 0xAA, 0x00, 0xC0, 0x4F, 0xD9, 0x29, 0xDB]};\nconst IID IID_IAutoCompList = {0x00BB2760, 0x6A77, 0x11D0, [0xA5, 0x35, 0x00, 0xC0, 0x4F, 0xD7, 0xD0, 0x62]};\nconst IID IID_IAutoDiscoveryProvider = {0x9DCF4A37, 0x01DE, 0x4549, [0xA9, 0xCB, 0x3A, 0xC3, 0x1E, 0xC2, 0x3C, 0x4F]};\nconst IID IID_IBackgroundCopyCallback = {0x97EA99C7, 0x0186, 0x4AD4, [0x8D, 0xF9, 0xC5, 0xB4, 0xE0, 0xED, 0x6B, 0x22]};\nconst IID IID_IBackgroundCopyCallback1 = {0x084F6593, 0x3800, 0x4E08, [0x9B, 0x59, 0x99, 0xFA, 0x59, 0xAD, 0xDF, 0x82]};\nconst IID IID_IBackgroundCopyError = {0x19C613A0, 0xFCB8, 0x4F28, [0x81, 0xAE, 0x89, 0x7C, 0x3D, 0x07, 0x8F, 0x81]};\nconst IID IID_IBackgroundCopyFile = {0x01B7BD23, 0xFB88, 0x4A77, [0x84, 0x90, 0x58, 0x91, 0xD3, 0xE4, 0x65, 0x3A]};\nconst IID IID_IBackgroundCopyGroup = {0x1DED80A7, 0x53EA, 0x424F, [0x8A, 0x04, 0x17, 0xFE, 0xA9, 0xAD, 0xC4, 0xF5]};\nconst IID IID_IBackgroundCopyJob = {0x37668D37, 0x507E, 0x4160, [0x93, 0x16, 0x26, 0x30, 0x6D, 0x15, 0x0B, 0x12]};\nconst IID IID_IBackgroundCopyJob1 = {0x59F5553C, 0x2031, 0x4629, [0xBB, 0x18, 0x26, 0x45, 0xA6, 0x97, 0x09, 0x47]};\nconst IID IID_IBackgroundCopyJob2 = {0x54B50739, 0x686F, 0x45EB, [0x9D, 0xFF, 0xD6, 0xA9, 0xA0, 0xFA, 0xA9, 0xAF]};\nconst IID IID_IBackgroundCopyManager = {0x5CE34C0D, 0x0DC9, 0x4C1F, [0x89, 0x7C, 0xDA, 0xA1, 0xB7, 0x8C, 0xEE, 0x7C]};\nconst IID IID_IBackgroundCopyQMgr = {0x16F41C69, 0x09F5, 0x41D2, [0x8C, 0xD8, 0x3C, 0x08, 0xC4, 0x7B, 0xC8, 0xA8]};\nconst IID IID_IBidiRequestSpl = {0x9C007000, 0xFFA8, 0x44FF, [0xB2, 0xB3, 0xAE, 0x91, 0x02, 0xC7, 0x4D, 0x4C]};\nconst IID IID_IBindCtx = {0x0000000E, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IBindEventHandler = {0x63CDBCB0, 0xC1B1, 0x11D0, [0x93, 0x36, 0x00, 0xA0, 0xC9, 0x0D, 0xCA, 0xA9]};\nconst IID IID_IBindHost = {0xFC4801A1, 0x2BA9, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID IID_IBinding = {0x79EAC9C0, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IBindProtocol = {0x79EAC9CD, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IBindResource = {0x0C733AB1, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IBindStatusCallback = {0x79EAC9C1, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IBindStatusCallbackHolder = {0x79EAC9CC, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IBindStatusCallbackMsg = {0x79EAC9D5, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IBitsTest1 = {0x51A183DB, 0x67E0, 0x4472, [0x86, 0x02, 0x3D, 0xBC, 0x73, 0x0B, 0x7E, 0xF5]};\nconst IID IID_IBlockFormats = {0x3050F830, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IBlockingLock = {0x30F3D47A, 0x6447, 0x11D1, [0x8E, 0x3C, 0x00, 0xC0, 0x4F, 0xB9, 0x38, 0x6D]};\nconst IID IID_IBoundObject = {0x9BFBBC00, 0xEFF1, 0x101A, [0x84, 0xED, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IBoundObjectSite = {0x9BFBBC01, 0xEFF1, 0x101A, [0x84, 0xED, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IBriefcaseStg = {0x8BCE1FA1, 0x0921, 0x101B, [0xB1, 0xFF, 0x00, 0xDD, 0x01, 0x0C, 0xCC, 0x48]};\nconst IID IID_IBurnEngine = {0x520CCA66, 0x51A5, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID IID_ICallFactory = {0x1C733A30, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICallFrame = {0xD573B4B0, 0x894E, 0x11D2, [0xB8, 0xB6, 0x00, 0xC0, 0x4F, 0xB9, 0x61, 0x8A]};\nconst IID IID_ICallFrameEvents = {0xFD5E0843, 0xFC91, 0x11D0, [0x97, 0xD7, 0x00, 0xC0, 0x4F, 0xB9, 0x61, 0x8A]};\nconst IID IID_ICallFrameWalker = {0x08B23919, 0x392D, 0x11D2, [0xB8, 0xA4, 0x00, 0xC0, 0x4F, 0xB9, 0x61, 0x8A]};\nconst IID IID_ICallIndirect = {0xD573B4B1, 0x894E, 0x11D2, [0xB8, 0xB6, 0x00, 0xC0, 0x4F, 0xB9, 0x61, 0x8A]};\nconst IID IID_ICallInterceptor = {0x60C7CA75, 0x896D, 0x11D2, [0xB8, 0xB6, 0x00, 0xC0, 0x4F, 0xB9, 0x61, 0x8A]};\nconst IID IID_ICallUnmarshal = {0x5333B003, 0x2E42, 0x11D2, [0xB8, 0x9D, 0x00, 0xC0, 0x4F, 0xB9, 0x61, 0x8A]};\nconst IID IID_ICancelMethodCalls = {0x00000029, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ICatalogFileInfo = {0x711C7600, 0x6B48, 0x11D1, [0xB4, 0x03, 0x00, 0xAA, 0x00, 0xB9, 0x2A, 0xF1]};\nconst IID IID_ICategorizer = {0xA3B14589, 0x9174, 0x49A8, [0x89, 0xA3, 0x06, 0xA1, 0xAE, 0x2B, 0x9B, 0xA7]};\nconst IID IID_ICategoryProvider = {0x9AF64809, 0x5864, 0x4C26, [0xA7, 0x20, 0xC1, 0xF7, 0x8C, 0x08, 0x6E, 0xE3]};\nconst IID IID_ICatInformation = {0x0002E013, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ICatRegister = {0x0002E012, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ICDBurn = {0x3D73A659, 0xE5D0, 0x4D42, [0xAF, 0xC0, 0x51, 0x21, 0xBA, 0x42, 0x5C, 0x8D]};\nconst IID IID_ICEnroll = {0x43F8F288, 0x7A20, 0x11D0, [0x8F, 0x06, 0x00, 0xC0, 0x4F, 0xC2, 0x95, 0xE1]};\nconst IID IID_ICEnroll2 = {0x704CA730, 0xC90B, 0x11D1, [0x9B, 0xEC, 0x00, 0xC0, 0x4F, 0xC2, 0x95, 0xE1]};\nconst IID IID_ICEnroll3 = {0xC28C2D95, 0xB7DE, 0x11D2, [0xA4, 0x21, 0x00, 0xC0, 0x4F, 0x79, 0xFE, 0x8E]};\nconst IID IID_ICEnroll4 = {0xC1F1188A, 0x2EB5, 0x4A80, [0x84, 0x1B, 0x7E, 0x72, 0x9A, 0x35, 0x6D, 0x90]};\nconst IID IID_IChannelHook = {0x1008C4A0, 0x7613, 0x11CF, [0x9A, 0xF1, 0x00, 0x20, 0xAF, 0x6E, 0x72, 0xF4]};\nconst IID IID_IChannelMgr = {0x85BD8E82, 0x0FBA, 0x11D1, [0x90, 0xC3, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x68]};\nconst IID IID_IChapteredRowset = {0x0C733A93, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICheckBox = {0x3050F685, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ICiAdmin = {0xAE67C7D8, 0x85D3, 0x11D0, [0x8C, 0x45, 0x00, 0xC0, 0x4F, 0xC2, 0xDB, 0x8D]};\nconst IID IID_ICiAdminParams = {0xA82D48C6, 0x3F0F, 0x11D0, [0x8C, 0x91, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCAdviseStatus = {0xCA05734A, 0x1218, 0x11D3, [0xAE, 0x7A, 0x00, 0xC0, 0x4F, 0x72, 0xF8, 0x31]};\nconst IID IID_ICiCDeferredPropRetriever = {0xC273AF70, 0x6D72, 0x11D0, [0x8D, 0x64, 0x00, 0xA0, 0xC9, 0x08, 0xDB, 0xF1]};\nconst IID IID_ICiCDocName = {0x76615076, 0x3C2B, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCDocNameToWorkidTranslator = {0x25FC3F54, 0x3CB4, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCDocNameToWorkidTranslatorEx = {0x7BBA76E6, 0xA0E3, 0x11D2, [0xBC, 0x5D, 0x00, 0xC0, 0x4F, 0xA3, 0x54, 0xBA]};\nconst IID IID_ICiCDocStore = {0x46625468, 0x3C32, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCDocStoreEx = {0xF98282A7, 0xFA72, 0x11D1, [0x97, 0x98, 0x00, 0xC0, 0x4F, 0xC2, 0xF4, 0x10]};\nconst IID IID_ICiCDocStoreLocator = {0x97EE7C06, 0x5908, 0x11D0, [0x8C, 0x9B, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCEventLogItem = {0x44CC886A, 0x4314, 0x11D0, [0x8C, 0x91, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCFilterClient = {0xA1E0BCB6, 0x3C24, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCFilterStatus = {0xBC5F3D60, 0x8BBC, 0x11D1, [0x8F, 0x73, 0x00, 0xA0, 0xC9, 0x19, 0x17, 0xF5]};\nconst IID IID_ICiCIndexNotificationStatus = {0x5FFF3840, 0x8E76, 0x11D0, [0x8D, 0x69, 0x00, 0xA0, 0xC9, 0x08, 0xDB, 0xF1]};\nconst IID IID_ICiCLangRes = {0x914C2E6C, 0x43FE, 0x11D0, [0x8C, 0x91, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiControl = {0x63DEB7F4, 0x3CCB, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCOpenedDoc = {0x151EDFBE, 0x3C2F, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCPropertyStorage = {0x4C46225A, 0x3CB5, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCPropRetriever = {0x77D9B2DA, 0x4401, 0x11D0, [0x8C, 0x91, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCQueryNotification = {0x0A9E9F6C, 0x3CE2, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCQuerySession = {0xAE461FD6, 0x4E1D, 0x11D0, [0x8C, 0x94, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCResourceMonitor = {0xF700FF8E, 0x20EE, 0x11D2, [0x80, 0xF7, 0x00, 0xC0, 0x4F, 0xA3, 0x54, 0xBA]};\nconst IID IID_ICiCScope = {0x1021C882, 0x3CC0, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCScopeChecker = {0x7D820C9C, 0x3CBC, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCScopeEnumerator = {0xCF8505EA, 0x3CCA, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCSecurityChecker = {0xCA130CF4, 0x3CC2, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiCUserSecurity = {0x5D01D9CE, 0x3CC2, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiDocChangeNotifySink = {0x8BFA1386, 0x3CE5, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiEnumWorkids = {0x77900150, 0xA09C, 0x11D0, [0xA8, 0x0D, 0x00, 0xA0, 0xC9, 0x06, 0x24, 0x1A]};\nconst IID IID_ICiFrameworkQuery = {0xAE67C7D9, 0x85D3, 0x11D0, [0x8C, 0x45, 0x00, 0xC0, 0x4F, 0xC2, 0xDB, 0x8D]};\nconst IID IID_ICiIndexNotification = {0x4F2CD6E0, 0x8E74, 0x11D0, [0x8D, 0x69, 0x00, 0xA0, 0xC9, 0x08, 0xDB, 0xF1]};\nconst IID IID_ICiIndexNotificationEntry = {0x210769D0, 0x8E75, 0x11D0, [0x8D, 0x69, 0x00, 0xA0, 0xC9, 0x08, 0xDB, 0xF1]};\nconst IID IID_ICiISearchCreator = {0x7DC07FA0, 0x902E, 0x11D0, [0xA8, 0x0C, 0x00, 0xA0, 0xC9, 0x06, 0x24, 0x1A]};\nconst IID IID_ICiManager = {0xCF0FCF56, 0x3CCE, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiPersistIncrFile = {0x31B311E2, 0x4498, 0x11D0, [0x8C, 0x91, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_ICiQueryPropertyMapper = {0xD2333EB0, 0x756B, 0x11D0, [0x8D, 0x66, 0x00, 0xA0, 0xC9, 0x08, 0xDB, 0xF1]};\nconst IID IID_ICiStartup = {0x68232CB8, 0x3CCC, 0x11D0, [0x8C, 0x90, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_IClassActivator = {0x00000140, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IClassFactory = {0x00000001, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IClassFactory2 = {0xB196B28F, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IClassFactoryEx = {0x342D1EA0, 0xAE25, 0x11D1, [0x89, 0xC5, 0x00, 0x60, 0x08, 0xC3, 0xFB, 0xFC]};\nconst IID IID_IClientCaps = {0x7E8BC44D, 0xAEFF, 0x11D1, [0x89, 0xC2, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4]};\nconst IID IID_IClientSecurity = {0x0000013D, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IClusCfgAsyncEvictCleanup = {0x52C80B95, 0xC1AD, 0x4240, [0x8D, 0x89, 0x72, 0xE9, 0xFA, 0x84, 0x02, 0x5E]};\nconst IID IID_IClusCfgBaseCluster = {0xA8A5C613, 0x2518, 0x47F5, [0x96, 0xCA, 0xCA, 0xFA, 0x7F, 0xFB, 0xAF, 0x68]};\nconst IID IID_IClusCfgCallback = {0x238DCA63, 0xE2EF, 0x4F32, [0xA2, 0x4D, 0xAC, 0xBF, 0x97, 0x5B, 0xE8, 0x42]};\nconst IID IID_IClusCfgCapabilities = {0xD94AB253, 0x36C7, 0x41C1, [0xB5, 0x2E, 0x26, 0xB4, 0x51, 0x97, 0x5C, 0x8D]};\nconst IID IID_IClusCfgClusterConnection = {0xCE6EF90C, 0x3602, 0x41E7, [0x95, 0xBD, 0xAA, 0xFD, 0x37, 0xA6, 0x76, 0xDF]};\nconst IID IID_IClusCfgClusterInfo = {0x85B4BBC0, 0xDDC4, 0x4AE7, [0x82, 0x68, 0xF4, 0x85, 0x0B, 0xB2, 0xA6, 0xEE]};\nconst IID IID_IClusCfgCredentials = {0x54AA9406, 0xA409, 0x4B49, [0xB3, 0x14, 0x5F, 0x0A, 0x0C, 0xE4, 0xC8, 0x8E]};\nconst IID IID_IClusCfgEvictCleanup = {0x6FE3E361, 0xD373, 0x4C5F, [0xA0, 0xAF, 0x1D, 0xFE, 0x84, 0x93, 0xC6, 0x55]};\nconst IID IID_IClusCfgGroupCfg = {0xDCB6D3D2, 0xA55F, 0x49E5, [0xA6, 0x4A, 0x0C, 0xCF, 0xEB, 0x01, 0xED, 0x3A]};\nconst IID IID_IClusCfgInitialize = {0x2A0EB82D, 0xF878, 0x492A, [0x95, 0x1E, 0xAE, 0x00, 0x09, 0x18, 0xC4, 0xA6]};\nconst IID IID_IClusCfgIPAddressInfo = {0xAAEAF0A5, 0xE310, 0x4604, [0xA5, 0x5E, 0x2F, 0x9D, 0xDC, 0x41, 0x57, 0xA8]};\nconst IID IID_IClusCfgManagedResourceCfg = {0x60300A0F, 0x77E1, 0x440C, [0xBD, 0x94, 0x6B, 0xFB, 0x0D, 0xBF, 0xDB, 0x3A]};\nconst IID IID_IClusCfgManagedResourceInfo = {0xE0324847, 0x1520, 0x41B0, [0xB9, 0x60, 0x54, 0x19, 0x8D, 0xA5, 0xF8, 0xAF]};\nconst IID IID_IClusCfgMemberSetChangeListener = {0x2B64534F, 0x2643, 0x4ABC, [0xA4, 0xE5, 0x82, 0x4D, 0x88, 0x1B, 0x75, 0x82]};\nconst IID IID_IClusCfgNetworkInfo = {0x19FC7580, 0x950A, 0x44A6, [0x96, 0x6E, 0x74, 0xB1, 0x4B, 0x20, 0x91, 0x8F]};\nconst IID IID_IClusCfgNodeInfo = {0xE4B5FA15, 0xDD07, 0x439E, [0xA6, 0x23, 0x88, 0x23, 0x52, 0x4E, 0x3D, 0x19]};\nconst IID IID_IClusCfgPartitionInfo = {0xEC1EBD9F, 0x5866, 0x4846, [0x89, 0x52, 0xEC, 0x36, 0xC3, 0x96, 0x1E, 0xEE]};\nconst IID IID_IClusCfgPollingCallback = {0xC72DB1FD, 0x51A2, 0x43E6, [0xB7, 0x08, 0xD9, 0xDB, 0x7D, 0xA7, 0x96, 0x30]};\nconst IID IID_IClusCfgPollingCallbackInfo = {0x2AF55DA7, 0xCB6F, 0x40DE, [0xBB, 0x11, 0x66, 0x73, 0x46, 0x4B, 0x2C, 0x54]};\nconst IID IID_IClusCfgResourceCreate = {0x0647B41A, 0xC777, 0x443C, [0x94, 0x32, 0x02, 0xCC, 0xCF, 0x4F, 0xF4, 0x43]};\nconst IID IID_IClusCfgResourcePostCreate = {0x72A9BF54, 0x13B6, 0x451F, [0x91, 0x0D, 0x69, 0x13, 0xEB, 0xF0, 0x25, 0xAB]};\nconst IID IID_IClusCfgResourcePreCreate = {0x4240F6A1, 0x9D49, 0x427E, [0x8F, 0x3D, 0x09, 0x38, 0x4E, 0x1F, 0x59, 0xE4]};\nconst IID IID_IClusCfgResourceTypeCreate = {0x3AFCE3B8, 0x5F3E, 0x4DDF, [0xA8, 0xF4, 0x4B, 0x4F, 0xCB, 0xF2, 0x8F, 0x8F]};\nconst IID IID_IClusCfgResourceTypeInfo = {0xC649A281, 0xC847, 0x4F5C, [0x98, 0x41, 0xD2, 0xF7, 0x3B, 0x5A, 0xA7, 0x1D]};\nconst IID IID_IClusCfgResTypeServicesInitializ = {0x6E109698, 0xDFC4, 0x4471, [0xAC, 0xE1, 0x04, 0x14, 0x93, 0x1B, 0x3B, 0xB3]};\nconst IID IID_IClusCfgServer = {0x4C06EAE6, 0x990E, 0x4051, [0x8A, 0xA1, 0xAD, 0x4B, 0x4E, 0xAE, 0x9C, 0xAF]};\nconst IID IID_IClusCfgSetCredentials = {0x58E6E5B9, 0x4788, 0x4D9A, [0x82, 0x55, 0x1E, 0x27, 0x4E, 0x5D, 0xCC, 0xB0]};\nconst IID IID_IClusCfgStartupListener = {0xD282CAEF, 0x2EDE, 0x4AB9, [0xA5, 0xD5, 0xF7, 0xBD, 0xE3, 0xD2, 0x3F, 0x0F]};\nconst IID IID_IClusCfgStartupNotify = {0xC2B0D069, 0x6353, 0x4EE1, [0xB2, 0x53, 0x6B, 0x0D, 0x75, 0xDB, 0x2C, 0xD3]};\nconst IID IID_IClusCfgVerify = {0xD47BBEEC, 0x2286, 0x4514, [0xAA, 0x90, 0x7E, 0x88, 0xBD, 0x0F, 0xE5, 0x43]};\nconst IID IID_IClusCfgWizard = {0x2EB57A3B, 0xDA8D, 0x4B56, [0x97, 0xCF, 0xA3, 0x19, 0x1B, 0xF8, 0xFD, 0x5B]};\nconst IID IID_IClusterApplicationWizard = {0x24F97151, 0x6689, 0x11D1, [0x9A, 0xA7, 0x00, 0xC0, 0x4F, 0xB9, 0x3A, 0x80]};\nconst IID IID_ICodeInstall = {0x79EAC9D1, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IColumnMapper = {0x0B63E37A, 0x9CCC, 0x11D0, [0xBC, 0xDB, 0x00, 0x80, 0x5F, 0xCC, 0xCE, 0x04]};\nconst IID IID_IColumnMapperCreator = {0x0B63E37B, 0x9CCC, 0x11D0, [0xBC, 0xDB, 0x00, 0x80, 0x5F, 0xCC, 0xCE, 0x04]};\nconst IID IID_IColumnProvider = {0xE8025004, 0x1C42, 0x11D2, [0xBE, 0x2C, 0x00, 0xA0, 0xC9, 0xA8, 0x3D, 0xA1]};\nconst IID IID_IColumnsInfo = {0x0C733A11, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IColumnsInfo2 = {0x0C733AB8, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IColumnsRowset = {0x0C733A10, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICombobox = {0x3050F677, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ICommand = {0x0C733A63, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICommandCost = {0x0C733A4E, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICommandPersist = {0x0C733AA7, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICommandPrepare = {0x0C733A26, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICommandProperties = {0x0C733A79, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICommandStream = {0x0C733ABF, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICommandText = {0x0C733A27, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICommandTree = {0x0C733A87, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICommandValidate = {0x0C733A18, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICommandWithParameters = {0x0C733A64, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICommDlgBrowser = {0x000214F1, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ICommDlgBrowser2 = {0x10339516, 0x2894, 0x11D2, [0x90, 0x39, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x3E]};\nconst IID IID_ICommonQuery = {0xAB50DEC0, 0x6F1D, 0x11D0, [0xA1, 0xC4, 0x00, 0xAA, 0x00, 0xC1, 0x6E, 0x65]};\nconst IID IID_IComThreadingInfo = {0x000001CE, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IConfigurationConnection = {0xDDAD8191, 0x66C5, 0x4A30, [0xA4, 0xDF, 0xCB, 0x6C, 0x21, 0x67, 0x04, 0xCA]};\nconst IID IID_IConnectionInfo = {0x15182CE3, 0x82D7, 0x473F, [0x92, 0xDE, 0x70, 0x6E, 0x2B, 0xCE, 0xA9, 0x02]};\nconst IID IID_IConnectionManager = {0xC0017768, 0x1BF3, 0x4352, [0x8D, 0x6C, 0x3A, 0x8C, 0x1D, 0x0F, 0xB4, 0x77]};\nconst IID IID_IConnectionPoint = {0xB196B286, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IConnectionPointContainer = {0xB196B284, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IContextCallback = {0x000001DA, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IContextMenu = {0x000214E4, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IContextMenu2 = {0x000214F4, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IContextMenu3 = {0xBCFCE0A0, 0xEC17, 0x11D0, [0x8D, 0x10, 0x00, 0xA0, 0xC9, 0x0F, 0x27, 0x19]};\nconst IID IID_IContinue = {0x0000012A, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IContinueCallback = {0xB722BCCA, 0x4E68, 0x101B, [0xA2, 0xBC, 0x00, 0xAA, 0x00, 0x40, 0x47, 0x70]};\nconst IID IID_IConvertType = {0x0C733A88, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICrBarn = {0x276A2EE0, 0x0B5D, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID IID_ICrBarn2 = {0xB66A7A1B, 0x8FC6, 0x448C, [0xA2, 0xEB, 0x3C, 0x55, 0x95, 0x74, 0x78, 0xA1]};\nconst IID IID_ICrBlinds = {0x5AF5C340, 0x0BA9, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID IID_ICrBlinds2 = {0x7059D403, 0x599A, 0x4264, [0x81, 0x40, 0x64, 0x1E, 0xB8, 0xAE, 0x1F, 0x64]};\nconst IID IID_ICrBlur = {0x9F7C7827, 0xE87A, 0x11D1, [0x81, 0xE0, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_ICreateErrorInfo = {0x22F03340, 0x547D, 0x101B, [0x8E, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19]};\nconst IID IID_ICreateRow = {0x0C733AB2, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ICreateTypeInfo = {0x00020405, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ICreateTypeInfo2 = {0x0002040E, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ICreateTypeLib = {0x00020406, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ICreateTypeLib2 = {0x0002040F, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ICrEmboss = {0xE4ACFB80, 0x053E, 0x11D2, [0x81, 0xEA, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_ICrEngrave = {0xE4ACFB7F, 0x053E, 0x11D2, [0x81, 0xEA, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_ICrInset = {0x05C5EE20, 0x0BA6, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID IID_ICrIris = {0x3F69F350, 0x0379, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID IID_ICrIris2 = {0xF7B06961, 0xBA8C, 0x4970, [0x91, 0x8B, 0x1C, 0x60, 0xCB, 0x9F, 0xF1, 0x80]};\nconst IID IID_ICrRadialWipe = {0x424B71AE, 0x0695, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID IID_ICrSlide = {0x810E402E, 0x056B, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID IID_ICrSpiral = {0x0DE527A0, 0x0C7E, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID IID_ICrStretch = {0x6684AF00, 0x0A87, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID IID_ICrWheel = {0x3943DE80, 0x1464, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID IID_ICrZigzag = {0x4E5A64A0, 0x0C8B, 0x11D2, [0xA4, 0x84, 0x00, 0xC0, 0x4F, 0x8E, 0xFB, 0x69]};\nconst IID IID_ICSSFilter = {0x3050F3EC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ICSSFilterDispatch = {0x9519152B, 0x9484, 0x4A6C, [0xB6, 0xA7, 0x4F, 0x25, 0xE9, 0x2D, 0x6C, 0x6B]};\nconst IID IID_ICSSFilterSite = {0x3050F3ED, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ICurrentWorkingDirectory = {0x91956D21, 0x9276, 0x11D1, [0x92, 0x1A, 0x00, 0x60, 0x97, 0xDF, 0x5B, 0xD4]};\nconst IID IID_ICursor = {0x9F6AA700, 0xD188, 0x11CD, [0xAD, 0x48, 0x00, 0xAA, 0x00, 0x3C, 0x9C, 0xB6]};\nconst IID IID_ICursorFind = {0xE01D7850, 0xD188, 0x11CD, [0xAD, 0x48, 0x00, 0xAA, 0x00, 0x3C, 0x9C, 0xB6]};\nconst IID IID_ICursorMove = {0xACFF0690, 0xD188, 0x11CD, [0xAD, 0x48, 0x00, 0xAA, 0x00, 0x3C, 0x9C, 0xB6]};\nconst IID IID_ICursorScroll = {0xBB87E420, 0xD188, 0x11CD, [0xAD, 0x48, 0x00, 0xAA, 0x00, 0x3C, 0x9C, 0xB6]};\nconst IID IID_ICursorUpdateARow = {0xD14216A0, 0xD188, 0x11CD, [0xAD, 0x48, 0x00, 0xAA, 0x00, 0x3C, 0x9C, 0xB6]};\nconst IID IID_ICustomDoc = {0x3050F3F0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ICustomRatingHelper = {0xD0D9842D, 0xE211, 0x4B2C, [0x88, 0xDC, 0xBC, 0x72, 0x93, 0x42, 0xDF, 0xCB]};\nconst IID IID_IDA2Array = {0x2A8F0B06, 0xBE2B, 0x11D1, [0xB2, 0x19, 0x00, 0xC0, 0x4F, 0xC2, 0xA0, 0xCA]};\nconst IID IID_IDA2Behavior = {0xC46C1BF0, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDA2Event = {0x69B5BC70, 0x9B19, 0x11D0, [0x9B, 0x60, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID IID_IDA2FontStyle = {0x283807B5, 0x2C60, 0x11D0, [0xA3, 0x1D, 0x00, 0xAA, 0x00, 0xB9, 0x2C, 0x03]};\nconst IID IID_IDA2Geometry = {0x4A933702, 0xE36F, 0x11D0, [0x9B, 0x99, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID IID_IDA2Image = {0x45393DF0, 0x54B9, 0x11CF, [0x92, 0xA2, 0x00, 0xAA, 0x00, 0xB8, 0xA7, 0x33]};\nconst IID IID_IDA2LineStyle = {0x2AE71568, 0x4B34, 0x11D1, [0xB1, 0xE3, 0x00, 0xC0, 0x4F, 0xC2, 0xA0, 0xCA]};\nconst IID IID_IDA2Statics = {0xD17506C2, 0x6B26, 0x11D0, [0x89, 0x14, 0x00, 0xC0, 0x4F, 0xC2, 0xA0, 0xCA]};\nconst IID IID_IDA2View = {0x5F00F545, 0xDF18, 0x11D1, [0xAB, 0x6F, 0x00, 0xC0, 0x4F, 0xD9, 0x2B, 0x6B]};\nconst IID IID_IDA2ViewerControl = {0xC46C1BEF, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDA2ViewerControlWindowed = {0xC46C1BED, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAArray = {0xFA261CF0, 0xC44E, 0x11D1, [0x9B, 0xE4, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID IID_IDABbox2 = {0xBA8B033E, 0x1E91, 0x11D1, [0x88, 0x09, 0x00, 0xC0, 0x4F, 0xC2, 0x9D, 0x46]};\nconst IID IID_IDABbox3 = {0x0E41257B, 0x812D, 0x11D0, [0x9B, 0x4A, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID IID_IDABehavior = {0x5DFB2651, 0x9668, 0x11D0, [0xB1, 0x7B, 0x00, 0xC0, 0x4F, 0xC2, 0xA0, 0xCA]};\nconst IID IID_IDABoolean = {0xC46C1BDA, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDABvrHook = {0x50B4791F, 0x4731, 0x11D0, [0x89, 0x12, 0x00, 0xC0, 0x4F, 0xC2, 0xA0, 0xCA]};\nconst IID IID_IDACamera = {0xC46C1BCA, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAColor = {0xC46C1BDC, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDADashStyle = {0xF3E1B522, 0xD8A6, 0x11D1, [0x9B, 0xE5, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID IID_IDADrawingSurface = {0xC46C1BF4, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDADXTransformResult = {0xAF868305, 0xAB0B, 0x11D0, [0x87, 0x6A, 0x00, 0xC0, 0x4F, 0xC2, 0x9D, 0x46]};\nconst IID IID_IDAEndStyle = {0xB6FFC24C, 0x7E13, 0x11D0, [0x9B, 0x47, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID IID_IDAEvent = {0xC46C1BCE, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAFontStyle = {0xC46C1BC1, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAGeometry = {0xC46C1BCC, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAImage = {0xC46C1BC4, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAImport = {0xC46C1BEE, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAImportationResult = {0xB90E5258, 0x574A, 0x11D1, [0x8E, 0x7B, 0x00, 0xC0, 0x4F, 0xC2, 0x9D, 0x46]};\nconst IID IID_IDAJoinStyle = {0xA3034056, 0xEC1C, 0x11D1, [0x9B, 0xE8, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID IID_IDALineStyle = {0x69AD90EF, 0x1C20, 0x11D1, [0x88, 0x01, 0x00, 0xC0, 0x4F, 0xC2, 0x9D, 0x46]};\nconst IID IID_IDAMatte = {0xC46C1BE4, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAMicrophone = {0xC46C1BD8, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAModifiableBehavior = {0xC46C1BEC, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAMontage = {0xC46C1BC8, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDANumber = {0xD17506C3, 0x6B26, 0x11D0, [0x89, 0x14, 0x00, 0xC0, 0x4F, 0xC2, 0xA0, 0xCA]};\nconst IID IID_IDAPair = {0x542FB453, 0x5003, 0x11CF, [0x92, 0xA2, 0x00, 0xAA, 0x00, 0xB8, 0xA7, 0x33]};\nconst IID IID_IDAPath2 = {0xC46C1BD0, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAPickableResult = {0xC46C1BDE, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAPoint2 = {0x9CDE7341, 0x3C20, 0x11D0, [0xA3, 0x30, 0x00, 0xAA, 0x00, 0xB9, 0x2C, 0x03]};\nconst IID IID_IDAPoint3 = {0xC46C1BD6, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAPreferences = {0xB90E525A, 0x574A, 0x11D1, [0x8E, 0x7B, 0x00, 0xC0, 0x4F, 0xC2, 0x9D, 0x46]};\nconst IID IID_IDASite = {0xB90E5259, 0x574A, 0x11D1, [0x8E, 0x7B, 0x00, 0xC0, 0x4F, 0xC2, 0x9D, 0x46]};\nconst IID IID_IDASound = {0xC46C1BE6, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAStatics = {0x5DFB2650, 0x9668, 0x11D0, [0xB1, 0x7B, 0x00, 0xC0, 0x4F, 0xC2, 0xA0, 0xCA]};\nconst IID IID_IDAString = {0xC46C1BD2, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDataAdviseHolder = {0x00000110, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IDataChannel = {0xAD42D12A, 0x4AD0, 0x4856, [0x91, 0x9E, 0xE8, 0x54, 0xC9, 0x1D, 0x18, 0x56]};\nconst IID IID_IDataConvert = {0x0C733A8D, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDataFilter = {0x69D14C80, 0xC18E, 0x11D0, [0xA9, 0xCE, 0x00, 0x60, 0x97, 0x94, 0x23, 0x11]};\nconst IID IID_IDataObject = {0x0000010E, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IDATransform2 = {0xC46C1BD4, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDATransform3 = {0xC46C1BE0, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDATuple = {0x542FB452, 0x5003, 0x11CF, [0x92, 0xA2, 0x00, 0xAA, 0x00, 0xB8, 0xA7, 0x33]};\nconst IID IID_IDAUntilNotifier = {0x25B0F91C, 0xD23D, 0x11D0, [0x9B, 0x85, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID IID_IDAUserData = {0xBACD4D86, 0x4A4F, 0x11D1, [0x9B, 0xC8, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID IID_IDAVector2 = {0xC46C1BC6, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAVector3 = {0xC46C1BE2, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAView = {0xAF868304, 0xAB0B, 0x11D0, [0x87, 0x6A, 0x00, 0xC0, 0x4F, 0xC2, 0x9D, 0x46]};\nconst IID IID_IDAViewerControl = {0xC46C1BDD, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAViewerControlWindowed = {0xC46C1BCD, 0x3C52, 0x11D0, [0x92, 0x00, 0x84, 0x8C, 0x1D, 0x00, 0x00, 0x00]};\nconst IID IID_IDAViewSite = {0xBCBB1F75, 0xE384, 0x11D0, [0x9B, 0x99, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID IID_IDBAsynchNotify = {0x0C733A96, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDBAsynchStatus = {0x0C733A95, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDBBinderProperties = {0x0C733AB3, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDBCreateCommand = {0x0C733A1D, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDBCreateSession = {0x0C733A5D, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDBDataSourceAdmin = {0x0C733A7A, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDBInfo = {0x0C733A89, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDBInitialize = {0x0C733A8B, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDBProperties = {0x0C733A8A, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDBSchemaCommand = {0x0C733A50, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDBSchemaRowset = {0x0C733A7B, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDCInfo = {0x0C733A9C, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IDDVideoAcceleratorContainer = {0xACA12120, 0x3356, 0x11D1, [0x8F, 0xCF, 0x00, 0xC0, 0x4F, 0xC2, 0x9B, 0x4E]};\nconst IID IID_IDDVideoPortContainer = {0x6C142760, 0xA733, 0x11CE, [0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60]};\nconst IID IID_IDebug = {0x00000123, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IDebugApplication = {0x51973C32, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugApplication32 = {0x51973C32, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugApplication64 = {0x4DEDC754, 0x04C7, 0x4F10, [0x9E, 0x60, 0x16, 0xA3, 0x90, 0xFE, 0x6E, 0x62]};\nconst IID IID_IDebugApplicationEx = {0x51973C00, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugApplicationNode = {0x51973C34, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugApplicationNodeEvents = {0x51973C35, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugApplicationThread = {0x51973C38, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugApplicationThread64 = {0x9DAC5886, 0xDBAD, 0x456D, [0x9D, 0xEE, 0x5D, 0xEC, 0x39, 0xAB, 0x3D, 0xDA]};\nconst IID IID_IDebugAsyncOperation = {0x51973C1B, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugAsyncOperationCallBack = {0x51973C1C, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugCodeContext = {0x51973C13, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugCookie = {0x51973C39, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugDocument = {0x51973C21, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugDocumentContext = {0x51973C28, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugDocumentHelper32 = {0x51973C26, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugDocumentHelper64 = {0xC4C7363C, 0x20FD, 0x47F9, [0xBD, 0x82, 0x48, 0x55, 0xE0, 0x15, 0x08, 0x71]};\nconst IID IID_IDebugDocumentHelperEx = {0x51973C02, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugDocumentHost = {0x51973C27, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugDocumentInfo = {0x51973C1F, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugDocumentProvider = {0x51973C20, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugDocumentText = {0x51973C22, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugDocumentTextAuthor = {0x51973C24, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugDocumentTextEvents = {0x51973C23, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugDocumentTextExternalAuthor = {0x51973C25, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugExpression = {0x51973C14, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugExpressionCallBack = {0x51973C16, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugExpressionContext = {0x51973C15, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugExtendedProperty = {0x51973C52, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugFormatter = {0x51973C05, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugHelper = {0x51973C3F, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugHelperEx = {0x51973C08, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugOut = {0xC733E4F1, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_IDebugProperty = {0x51973C50, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugPropertyEnumType_All = {0x51973C55, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugPropertyEnumType_Arguments = {0x51973C57, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugPropertyEnumType_Locals = {0x51973C56, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugPropertyEnumType_LocalsPlus = {0x51973C58, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugPropertyEnumType_Registers = {0x51973C59, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugRegister = {0xC733E4F0, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_IDebugSessionProvider = {0x51973C29, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugSessionProviderEx = {0x51973C09, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugSetValueCallback = {0x51973C06, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugStackFrame = {0x51973C17, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugStackFrameSniffer = {0x51973C18, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugStackFrameSnifferEx = {0x51973C19, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugStackFrameSnifferEx32 = {0x51973C19, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugStackFrameSnifferEx64 = {0x8CD12AF4, 0x49C1, 0x4D52, [0x8D, 0x8A, 0xC1, 0x46, 0xF4, 0x75, 0x81, 0xAA]};\nconst IID IID_IDebugStream = {0x00000124, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IDebugSyncOperation = {0x51973C1A, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugThreadCall = {0x51973C36, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugThreadCall32 = {0x51973C36, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IDebugThreadCall64 = {0xCB3FA335, 0xE979, 0x42FD, [0x9F, 0xCF, 0xA7, 0x54, 0x6A, 0x0F, 0x39, 0x05]};\nconst IID IID_IDelaydC = {0xBFF9C030, 0xB58F, 0x11CE, [0xB5, 0xB0, 0x00, 0xAA, 0x00, 0x6C, 0xB3, 0x7D]};\nconst IID IID_IDelayedRelease = {0x000214ED, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IDelegateFolder = {0xADD8BA80, 0x002B, 0x11D0, [0x8F, 0x0F, 0x00, 0xC0, 0x4F, 0xD7, 0xD0, 0x62]};\nconst IID IID_IDeskBand = {0xEB0FE172, 0x1A3A, 0x11D0, [0x89, 0xB3, 0x00, 0xA0, 0xC9, 0x0A, 0x90, 0xAC]};\nconst IID IID_IDeviceRect = {0x3050F6D5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IDfReserved1 = {0x00000013, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IDfReserved2 = {0x00000014, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IDfReserved3 = {0x00000015, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IDialBranding = {0x8AECAFA9, 0x4306, 0x43CC, [0x8C, 0x5A, 0x76, 0x5F, 0x29, 0x79, 0xCC, 0x16]};\nconst IID IID_IDialEngine = {0x39FD782B, 0x7905, 0x40D5, [0x91, 0x48, 0x3C, 0x9B, 0x19, 0x04, 0x23, 0xD5]};\nconst IID IID_IDialEventSink = {0x2D86F4FF, 0x6E2D, 0x4488, [0xB2, 0xE9, 0x69, 0x34, 0xAF, 0xD4, 0x1B, 0xEA]};\nconst IID IID_IDifferencing = {0x994F0AF0, 0x2977, 0x11CE, [0xBB, 0x80, 0x08, 0x00, 0x2B, 0x36, 0xB2, 0xB0]};\nconst IID IID_IDirect3D = {0x3BBA0080, 0x2421, 0x11CF, [0xA3, 0x1A, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56]};\nconst IID IID_IDirect3D2 = {0x6AAE1EC1, 0x662A, 0x11D0, [0x88, 0x9D, 0x00, 0xAA, 0x00, 0xBB, 0xB7, 0x6A]};\nconst IID IID_IDirect3D3 = {0xBB223240, 0xE72B, 0x11D0, [0xA9, 0xB4, 0x00, 0xAA, 0x00, 0xC0, 0x99, 0x3E]};\nconst IID IID_IDirect3D7 = {0xF5049E77, 0x4861, 0x11D2, [0xA4, 0x07, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0xA8]};\nconst IID IID_IDirect3DDevice = {0x64108800, 0x957D, 0x11D0, [0x89, 0xAB, 0x00, 0xA0, 0xC9, 0x05, 0x41, 0x29]};\nconst IID IID_IDirect3DDevice2 = {0x93281501, 0x8CF8, 0x11D0, [0x89, 0xAB, 0x00, 0xA0, 0xC9, 0x05, 0x41, 0x29]};\nconst IID IID_IDirect3DDevice3 = {0xB0AB3B60, 0x33D7, 0x11D1, [0xA9, 0x81, 0x00, 0xC0, 0x4F, 0xD7, 0xB1, 0x74]};\nconst IID IID_IDirect3DDevice7 = {0xF5049E79, 0x4861, 0x11D2, [0xA4, 0x07, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0xA8]};\nconst IID IID_IDirect3DExecuteBuffer = {0x4417C145, 0x33AD, 0x11CF, [0x81, 0x6F, 0x00, 0x00, 0xC0, 0x20, 0x15, 0x6E]};\nconst IID IID_IDirect3DHALDevice = {0x84E63DE0, 0x46AA, 0x11CF, [0x81, 0x6F, 0x00, 0x00, 0xC0, 0x20, 0x15, 0x6E]};\nconst IID IID_IDirect3DLight = {0x4417C142, 0x33AD, 0x11CF, [0x81, 0x6F, 0x00, 0x00, 0xC0, 0x20, 0x15, 0x6E]};\nconst IID IID_IDirect3DMaterial = {0x4417C144, 0x33AD, 0x11CF, [0x81, 0x6F, 0x00, 0x00, 0xC0, 0x20, 0x15, 0x6E]};\nconst IID IID_IDirect3DMaterial2 = {0x93281503, 0x8CF8, 0x11D0, [0x89, 0xAB, 0x00, 0xA0, 0xC9, 0x05, 0x41, 0x29]};\nconst IID IID_IDirect3DMaterial3 = {0xCA9C46F4, 0xD3C5, 0x11D1, [0xB7, 0x5A, 0x00, 0x60, 0x08, 0x52, 0xB3, 0x12]};\nconst IID IID_IDirect3DMMXDevice = {0x881949A1, 0xD6F3, 0x11D0, [0x89, 0xAB, 0x00, 0xA0, 0xC9, 0x05, 0x41, 0x29]};\nconst IID IID_IDirect3DNullDevice = {0x8767DF22, 0xBACC, 0x11D1, [0x89, 0x69, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0xA8]};\nconst IID IID_IDirect3DRampDevice = {0xF2086B20, 0x259F, 0x11CF, [0xA3, 0x1A, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56]};\nconst IID IID_IDirect3DRefDevice = {0x50936643, 0x13E9, 0x11D1, [0x89, 0xAA, 0x00, 0xA0, 0xC9, 0x05, 0x41, 0x29]};\nconst IID IID_IDirect3DRGBDevice = {0xA4665C60, 0x2673, 0x11CF, [0xA3, 0x1A, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56]};\nconst IID IID_IDirect3DRM = {0x2BC49361, 0x8327, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRM2 = {0x4516ECC8, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID IID_IDirect3DRM3 = {0x4516EC83, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID IID_IDirect3DRMAnimation = {0xEB16CB0D, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMAnimation2 = {0xFF6B7F77, 0xA40E, 0x11D1, [0x91, 0xF9, 0x00, 0x00, 0xF8, 0x75, 0x8E, 0x66]};\nconst IID IID_IDirect3DRMAnimationArray = {0xD5F1CAE0, 0x4BD7, 0x11D1, [0xB9, 0x74, 0x00, 0x60, 0x08, 0x3E, 0x45, 0xF3]};\nconst IID IID_IDirect3DRMAnimationSet = {0xEB16CB0E, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMAnimationSet2 = {0xFF6B7F79, 0xA40E, 0x11D1, [0x91, 0xF9, 0x00, 0x00, 0xF8, 0x75, 0x8E, 0x66]};\nconst IID IID_IDirect3DRMClippedVisual = {0x5434E733, 0x6D66, 0x11D1, [0xBB, 0x0B, 0x00, 0x00, 0xF8, 0x75, 0x86, 0x5A]};\nconst IID IID_IDirect3DRMDevice = {0xE9E19280, 0x6E05, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMDevice2 = {0x4516EC78, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID IID_IDirect3DRMDevice3 = {0x549F498B, 0xBFEB, 0x11D1, [0x8E, 0xD8, 0x00, 0xA0, 0xC9, 0x67, 0xA4, 0x82]};\nconst IID IID_IDirect3DRMDeviceArray = {0xEB16CB10, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMFace = {0xEB16CB07, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMFace2 = {0x4516EC81, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID IID_IDirect3DRMFaceArray = {0xEB16CB17, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMFrame = {0xEB16CB03, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMFrame2 = {0xC3DFBD60, 0x3988, 0x11D0, [0x9E, 0xC2, 0x00, 0x00, 0xC0, 0x29, 0x1A, 0xC3]};\nconst IID IID_IDirect3DRMFrame3 = {0xFF6B7F70, 0xA40E, 0x11D1, [0x91, 0xF9, 0x00, 0x00, 0xF8, 0x75, 0x8E, 0x66]};\nconst IID IID_IDirect3DRMFrameArray = {0xEB16CB12, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMInterpolator = {0x242F6BC1, 0x3849, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID IID_IDirect3DRMLight = {0xEB16CB08, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMLightArray = {0xEB16CB14, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMMaterial = {0xEB16CB0B, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMMaterial2 = {0xFF6B7F75, 0xA40E, 0x11D1, [0x91, 0xF9, 0x00, 0x00, 0xF8, 0x75, 0x8E, 0x66]};\nconst IID IID_IDirect3DRMMesh = {0xA3A80D01, 0x6E12, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMMeshBuilder = {0xA3A80D02, 0x6E12, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMMeshBuilder2 = {0x4516EC77, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID IID_IDirect3DRMMeshBuilder3 = {0x4516EC82, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID IID_IDirect3DRMObject = {0xEB16CB00, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMObject2 = {0x4516EC7C, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID IID_IDirect3DRMObjectArray = {0x242F6BC2, 0x3849, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID IID_IDirect3DRMPicked2Array = {0x4516EC7B, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID IID_IDirect3DRMPickedArray = {0xEB16CB16, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMProgressiveMesh = {0x4516EC79, 0x8F20, 0x11D0, [0x9B, 0x6D, 0x00, 0x00, 0xC0, 0x78, 0x1B, 0xC3]};\nconst IID IID_IDirect3DRMShadow = {0xAF359780, 0x6BA3, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMShadow2 = {0x86B44E25, 0x9C82, 0x11D1, [0xBB, 0x0B, 0x00, 0xA0, 0xC9, 0x81, 0xA0, 0xA6]};\nconst IID IID_IDirect3DRMTexture = {0xEB16CB09, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMTexture2 = {0x120F30C0, 0x1629, 0x11D0, [0x94, 0x1C, 0x00, 0x80, 0xC8, 0x0C, 0xFA, 0x7B]};\nconst IID IID_IDirect3DRMTexture3 = {0xFF6B7F73, 0xA40E, 0x11D1, [0x91, 0xF9, 0x00, 0x00, 0xF8, 0x75, 0x8E, 0x66]};\nconst IID IID_IDirect3DRMUserVisual = {0x59163DE0, 0x6D43, 0x11CF, [0xAC, 0x4A, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMViewport = {0xEB16CB02, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMViewport2 = {0x4A1B1BE6, 0xBFED, 0x11D1, [0x8E, 0xD8, 0x00, 0xA0, 0xC9, 0x67, 0xA4, 0x82]};\nconst IID IID_IDirect3DRMViewportArray = {0xEB16CB11, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMVisual = {0xEB16CB04, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMVisualArray = {0xEB16CB13, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMWinDevice = {0xC5016CC0, 0xD273, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DRMWrap = {0xEB16CB0A, 0xD271, 0x11CE, [0xAC, 0x48, 0x00, 0x00, 0xC0, 0x38, 0x25, 0xA1]};\nconst IID IID_IDirect3DTexture = {0x2CDCD9E0, 0x25A0, 0x11CF, [0xA3, 0x1A, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56]};\nconst IID IID_IDirect3DTexture2 = {0x93281502, 0x8CF8, 0x11D0, [0x89, 0xAB, 0x00, 0xA0, 0xC9, 0x05, 0x41, 0x29]};\nconst IID IID_IDirect3DTnLHalDevice = {0xF5049E78, 0x4861, 0x11D2, [0xA4, 0x07, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0xA8]};\nconst IID IID_IDirect3DVertexBuffer = {0x7A503555, 0x4A83, 0x11D1, [0xA5, 0xDB, 0x00, 0xA0, 0xC9, 0x03, 0x67, 0xF8]};\nconst IID IID_IDirect3DVertexBuffer7 = {0xF5049E7D, 0x4861, 0x11D2, [0xA4, 0x07, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0xA8]};\nconst IID IID_IDirect3DViewport = {0x4417C146, 0x33AD, 0x11CF, [0x81, 0x6F, 0x00, 0x00, 0xC0, 0x20, 0x15, 0x6E]};\nconst IID IID_IDirect3DViewport2 = {0x93281500, 0x8CF8, 0x11D0, [0x89, 0xAB, 0x00, 0xA0, 0xC9, 0x05, 0x41, 0x29]};\nconst IID IID_IDirect3DViewport3 = {0xB0AB3B61, 0x33D7, 0x11D1, [0xA9, 0x81, 0x00, 0xC0, 0x4F, 0xD7, 0xB1, 0x74]};\nconst IID IID_IDirectDraw = {0x6C14DB80, 0xA733, 0x11CE, [0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60]};\nconst IID IID_IDirectDraw2 = {0xB3A6F3E0, 0x2B43, 0x11CF, [0xA2, 0xDE, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56]};\nconst IID IID_IDirectDraw4 = {0x9C59509A, 0x39BD, 0x11D1, [0x8C, 0x4A, 0x00, 0xC0, 0x4F, 0xD9, 0x30, 0xC5]};\nconst IID IID_IDirectDraw7 = {0x15E65EC0, 0x3B9C, 0x11D2, [0xB9, 0x2F, 0x00, 0x60, 0x97, 0x97, 0xEA, 0x5B]};\nconst IID IID_IDirectDrawClipper = {0x6C14DB85, 0xA733, 0x11CE, [0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60]};\nconst IID IID_IDirectDrawColorControl = {0x4B9F0EE0, 0x0D7E, 0x11D0, [0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8]};\nconst IID IID_IDirectDrawFactory2 = {0x89B2C488, 0x4AF4, 0x11D1, [0x8C, 0x4C, 0x00, 0xC0, 0x4F, 0xD9, 0x30, 0xC5]};\nconst IID IID_IDirectDrawGammaControl = {0x69C11C3E, 0xB46B, 0x11D1, [0xAD, 0x7A, 0x00, 0xC0, 0x4F, 0xC2, 0x9B, 0x4E]};\nconst IID IID_IDirectDrawKernel = {0x8D56C120, 0x6A08, 0x11D0, [0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8]};\nconst IID IID_IDirectDrawOptSurface = {0x51191F1E, 0x4F2B, 0x11D1, [0x8C, 0xC3, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0xA8]};\nconst IID IID_IDirectDrawPalette = {0x6C14DB84, 0xA733, 0x11CE, [0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60]};\nconst IID IID_IDirectDrawPalette2 = {0xC03C477E, 0x6519, 0x11D1, [0x8C, 0x52, 0x00, 0xC0, 0x4F, 0xD9, 0x30, 0xC5]};\nconst IID IID_IDirectDrawSurface = {0x6C14DB81, 0xA733, 0x11CE, [0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60]};\nconst IID IID_IDirectDrawSurface2 = {0x57805885, 0x6EEC, 0x11CF, [0x94, 0x41, 0xA8, 0x23, 0x03, 0xC1, 0x0E, 0x27]};\nconst IID IID_IDirectDrawSurface3 = {0xDA044E00, 0x69B2, 0x11D0, [0xA1, 0xD5, 0x00, 0xAA, 0x00, 0xB8, 0xDF, 0xBB]};\nconst IID IID_IDirectDrawSurface4 = {0x0B2B8630, 0xAD35, 0x11D0, [0x8E, 0xA6, 0x00, 0x60, 0x97, 0x97, 0xEA, 0x5B]};\nconst IID IID_IDirectDrawSurface7 = {0x06675A80, 0x3B9B, 0x11D2, [0xB9, 0x2F, 0x00, 0x60, 0x97, 0x97, 0xEA, 0x5B]};\nconst IID IID_IDirectDrawSurfaceKernel = {0x60755DA0, 0x6A40, 0x11D0, [0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8]};\nconst IID IID_IDirectDrawVideoAccelerator = {0xC9B2D740, 0x3356, 0x11D1, [0x8F, 0xCF, 0x00, 0xC0, 0x4F, 0xC2, 0x9B, 0x4E]};\nconst IID IID_IDirectDrawVideoPort = {0xB36D93E0, 0x2B43, 0x11CF, [0xA2, 0xDE, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56]};\nconst IID IID_IDirectInput2A = {0x5944E662, 0xAA8A, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IDirectInput2W = {0x5944E663, 0xAA8A, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IDirectInput7A = {0x9A4CB684, 0x236D, 0x11D3, [0x8E, 0x9D, 0x00, 0xC0, 0x4F, 0x68, 0x44, 0xAE]};\nconst IID IID_IDirectInput7W = {0x9A4CB685, 0x236D, 0x11D3, [0x8E, 0x9D, 0x00, 0xC0, 0x4F, 0x68, 0x44, 0xAE]};\nconst IID IID_IDirectInput8A = {3212410928, 18490, 19874, [170, 153, 93, 100, 237, 54, 151, 0]};\nconst IID IID_IDirectInput8W = {3212410929, 18490, 19874, [170, 153, 93, 100, 237, 54, 151, 0]};\nconst IID IID_IDirectInputA = {0x89521360, 0xAA8A, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IDirectInputDevice2A = {0x5944E682, 0xC92E, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IDirectInputDevice2W = {0x5944E683, 0xC92E, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IDirectInputDevice7A = {0x57D7C6BC, 0x2356, 0x11D3, [0x8E, 0x9D, 0x00, 0xC0, 0x4F, 0x68, 0x44, 0xAE]};\nconst IID IID_IDirectInputDevice7W = {0x57D7C6BD, 0x2356, 0x11D3, [0x8E, 0x9D, 0x00, 0xC0, 0x4F, 0x68, 0x44, 0xAE]};\nconst IID IID_IDirectInputDevice8A = {1423184000, 56341, 18483, [164, 27, 116, 143, 115, 163, 129, 121]};\nconst IID IID_IDirectInputDevice8W = {1423184001, 56341, 18483, [164, 27, 116, 143, 115, 163, 129, 121]};\nconst IID IID_IDirectInputDeviceA = {0x5944E680, 0xC92E, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IDirectInputDeviceW = {0x5944E681, 0xC92E, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IDirectInputEffect = {0xE7E1F7C0, 0x88D2, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID IID_IDirectInputEffectDriver = {0x02538130, 0x898F, 0x11D0, [0x9A, 0xD0, 0x00, 0xA0, 0xC9, 0xA0, 0x6E, 0x35]};\nconst IID IID_IDirectInputJoyConfig = {0x1DE12AB1, 0xC9F5, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IDirectInputPIDDriver = {0xEEC6993A, 0xB3FD, 0x11D2, [0xA9, 0x16, 0x00, 0xC0, 0x4F, 0xB9, 0x86, 0x38]};\nconst IID IID_IDirectInputW = {0x89521361, 0xAA8A, 0x11CF, [0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IDirectMusic = {0x6536115A, 0x7B2D, 0x11D2, [0xBA, 0x18, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x12]};\nconst IID IID_IDirectMusic2 = {0x6FC2CAE1, 0xBC78, 0x11D2, [0xAF, 0xA6, 0x00, 0xAA, 0x00, 0x24, 0xD8, 0xB6]};\nconst IID IID_IDirectMusicBand = {0xD2AC28C0, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicBuffer = {0xD2AC2878, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicChordMap = {0xD2AC28BE, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicCollection = {0xD2AC287C, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicComposer = {0xD2AC28BF, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicDownload = {0xD2AC287B, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicDownloadedInstrument = {0xD2AC287E, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicGetLoader = {0x68A04844, 0xD13D, 0x11D1, [0xAF, 0xA6, 0x00, 0xAA, 0x00, 0x24, 0xD8, 0xB6]};\nconst IID IID_IDirectMusicGraph = {0x2BEFC277, 0x5497, 0x11D2, [0xBC, 0xCB, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEB]};\nconst IID IID_IDirectMusicInstrument = {0xD2AC287D, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicLoader = {0x2FFAACA2, 0x5DCA, 0x11D2, [0xAF, 0xA6, 0x00, 0xAA, 0x00, 0x24, 0xD8, 0xB6]};\nconst IID IID_IDirectMusicObject = {0xD2AC28B5, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicPerformance = {0x07D43D03, 0x6523, 0x11D2, [0x87, 0x1D, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicPerformance2 = {0x6FC2CAE0, 0xBC78, 0x11D2, [0xAF, 0xA6, 0x00, 0xAA, 0x00, 0x24, 0xD8, 0xB6]};\nconst IID IID_IDirectMusicPort = {0x08F2D8C9, 0x37C2, 0x11D2, [0xB9, 0xF9, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x12]};\nconst IID IID_IDirectMusicPortDownload = {0xD2AC287A, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicSegment = {0xF96029A2, 0x4282, 0x11D2, [0x87, 0x17, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicSegment2 = {0xD38894D1, 0xC052, 0x11D2, [0x87, 0x2F, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicSegmentState = {0xA3AFDCC7, 0xD3EE, 0x11D1, [0xBC, 0x8D, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEB]};\nconst IID IID_IDirectMusicStyle = {0xD2AC28BD, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicThru = {0xCED153E7, 0x3606, 0x11D2, [0xB9, 0xF9, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x12]};\nconst IID IID_IDirectMusicTool = {0xD2AC28BA, 0xB39B, 0x11D1, [0x87, 0x04, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectMusicTrack = {0xF96029A1, 0x4282, 0x11D2, [0x87, 0x17, 0x00, 0x60, 0x08, 0x93, 0xB1, 0xBD]};\nconst IID IID_IDirectoryObject = {0xE798DE2C, 0x22E4, 0x11D0, [0x84, 0xFE, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IDirectorySchemaMgmt = {0x75DB3B9C, 0xA4D8, 0x11D0, [0xA7, 0x9C, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0xA8]};\nconst IID IID_IDirectorySearch = {0x109BA8EC, 0x92F0, 0x11D0, [0xA7, 0x90, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0xA8]};\nconst IID IID_IDirectPlay = {0x5454E9A0, 0xDB65, 0x11CE, [0x92, 0x1C, 0x00, 0xAA, 0x00, 0x6C, 0x49, 0x72]};\nconst IID IID_IDirectPlay2 = {0x2B74F7C0, 0x9154, 0x11CF, [0xA9, 0xCD, 0x00, 0xAA, 0x00, 0x68, 0x86, 0xE3]};\nconst IID IID_IDirectPlay2A = {0x9D460580, 0xA822, 0x11CF, [0x96, 0x0C, 0x00, 0x80, 0xC7, 0x53, 0x4E, 0x82]};\nconst IID IID_IDirectPlay3 = {0x133EFE40, 0x32DC, 0x11D0, [0x9C, 0xFB, 0x00, 0xA0, 0xC9, 0x0A, 0x43, 0xCB]};\nconst IID IID_IDirectPlay3A = {0x133EFE41, 0x32DC, 0x11D0, [0x9C, 0xFB, 0x00, 0xA0, 0xC9, 0x0A, 0x43, 0xCB]};\nconst IID IID_IDirectPlay4 = {0x0AB1C530, 0x4745, 0x11D1, [0xA7, 0xA1, 0x00, 0x00, 0xF8, 0x03, 0xAB, 0xFC]};\nconst IID IID_IDirectPlay4A = {0x0AB1C531, 0x4745, 0x11D1, [0xA7, 0xA1, 0x00, 0x00, 0xF8, 0x03, 0xAB, 0xFC]};\nconst IID IID_IDirectPlayLobby = {0xAF465C71, 0x9588, 0x11CF, [0xA0, 0x20, 0x00, 0xAA, 0x00, 0x61, 0x57, 0xAC]};\nconst IID IID_IDirectPlayLobby2 = {0x0194C220, 0xA303, 0x11D0, [0x9C, 0x4F, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID IID_IDirectPlayLobby2A = {0x1BB4AF80, 0xA303, 0x11D0, [0x9C, 0x4F, 0x00, 0xA0, 0xC9, 0x05, 0x42, 0x5E]};\nconst IID IID_IDirectPlayLobby3 = {0x2DB72490, 0x652C, 0x11D1, [0xA7, 0xA8, 0x00, 0x00, 0xF8, 0x03, 0xAB, 0xFC]};\nconst IID IID_IDirectPlayLobby3A = {0x2DB72491, 0x652C, 0x11D1, [0xA7, 0xA8, 0x00, 0x00, 0xF8, 0x03, 0xAB, 0xFC]};\nconst IID IID_IDirectPlayLobbyA = {0x26C66A70, 0xB367, 0x11CF, [0xA0, 0x24, 0x00, 0xAA, 0x00, 0x61, 0x57, 0xAC]};\nconst IID IID_IDirectSound = {0x279AFA83, 0x4981, 0x11CE, [0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60]};\nconst IID IID_IDirectSound3DBuffer = {0x279AFA86, 0x4981, 0x11CE, [0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60]};\nconst IID IID_IDirectSound3DListener = {0x279AFA84, 0x4981, 0x11CE, [0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60]};\nconst IID IID_IDirectSoundBuffer = {0x279AFA85, 0x4981, 0x11CE, [0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60]};\nconst IID IID_IDirectSoundBuffer8 = {1747297353, 29988, 19842, [146, 15, 80, 227, 106, 179, 171, 30]};\nconst IID IID_IDirectSoundCapture = {0xB0210781, 0x89CD, 0x11D0, [0xAF, 0x08, 0x00, 0xA0, 0xC9, 0x25, 0xCD, 0x16]};\nconst IID IID_IDirectSoundCaptureBuffer = {0xB0210782, 0x89CD, 0x11D0, [0xAF, 0x08, 0x00, 0xA0, 0xC9, 0x25, 0xCD, 0x16]};\nconst IID IID_IDirectSoundNotify = {0xB0210783, 0x89CD, 0x11D0, [0xAF, 0x08, 0x00, 0xA0, 0xC9, 0x25, 0xCD, 0x16]};\nconst IID IID_IDirectWriterLock = {0x0E6D4D92, 0x6738, 0x11CF, [0x96, 0x08, 0x00, 0xAA, 0x00, 0x68, 0x0D, 0xB4]};\nconst IID IID_IDirectXFile = {0x3D82AB40, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID IID_IDirectXFileBinary = {0x3D82AB46, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID IID_IDirectXFileData = {0x3D82AB44, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID IID_IDirectXFileDataReference = {0x3D82AB45, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID IID_IDirectXFileEnumObject = {0x3D82AB41, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID IID_IDirectXFileObject = {0x3D82AB43, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID IID_IDirectXFileSaveObject = {0x3D82AB42, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID IID_IDiscardableBrowserProperty = {0x49C3DE7C, 0xD329, 0x11D0, [0xAB, 0x73, 0x00, 0xC0, 0x4F, 0xC3, 0x3E, 0x80]};\nconst IID IID_IDiscMaster = {0x520CCA62, 0x51A5, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID IID_IDiscMasterProgressEvents = {0xEC9E51C1, 0x4E5D, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID IID_IDiscRecorder = {0x85AC9776, 0xCA88, 0x4CF2, [0x89, 0x4E, 0x09, 0x59, 0x8C, 0x07, 0x8A, 0x41]};\nconst IID IID_IDiscStash = {0x520CCA64, 0x51A5, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID IID_IDispatch = {0x00020400, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IDispatchEx = {0xA6EF9860, 0xC720, 0x11D0, [0x93, 0x37, 0x00, 0xA0, 0xC9, 0x0D, 0xCA, 0xA9]};\nconst IID IID_IDispError = {0xA6EF9861, 0xC720, 0x11D0, [0x93, 0x37, 0x00, 0xA0, 0xC9, 0x0D, 0xCA, 0xA9]};\nconst IID IID_IDisplayPointer = {0x3050F69E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IDisplayServices = {0x3050F69D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IDithererImpl = {0x7C48E840, 0x3910, 0x11D0, [0x86, 0xFC, 0x00, 0xA0, 0xC9, 0x13, 0xF7, 0x50]};\nconst IID IID_IDocHostShowUI = {0xC4D244B0, 0xD43E, 0x11CF, [0x89, 0x3B, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x1A]};\nconst IID IID_IDocHostUIHandler = {0xBD3F23C0, 0xD43E, 0x11CF, [0x89, 0x3B, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x1A]};\nconst IID IID_IDocHostUIHandler2 = {0x3050F6D0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IDockingWindow = {0x012DD920, 0x7B26, 0x11D0, [0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8]};\nconst IID IID_IDockingWindowFrame = {0x47D2657A, 0x7B27, 0x11D0, [0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8]};\nconst IID IID_IDockingWindowSite = {0x2A342FC2, 0x7B26, 0x11D0, [0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8]};\nconst IID IID_IDoTask = {0x0230C9F8, 0xEE7F, 0x4307, [0x98, 0xDB, 0x72, 0x6E, 0xBC, 0xAE, 0x55, 0xD6]};\nconst IID IID_IDownloadBehavior = {0x3050F5BD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IDownloadManager = {0x988934A4, 0x064B, 0x11D3, [0xBB, 0x80, 0x00, 0x10, 0x4B, 0x35, 0xE7, 0xF9]};\nconst IID IID_IDownloadNotify = {0xCAEB5D28, 0xAE4C, 0x11D1, [0xBA, 0x40, 0x00, 0xC0, 0x4F, 0xB9, 0x2D, 0x79]};\nconst IID IID_IDragSourceHelper = {0xDE5BF786, 0x477A, 0x11D2, [0x83, 0x9D, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xD0]};\nconst IID IID_IDropSource = {0x00000121, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IDropTarget = {0x00000122, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IDropTargetHelper = {0x4657278B, 0x411B, 0x11D2, [0x83, 0x9A, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xD0]};\nconst IID IID_IDsBrowseDomainTree = {0x7CABCF1E, 0x78F5, 0x11D2, [0x96, 0x0C, 0x00, 0xC0, 0x4F, 0xA3, 0x1A, 0x86]};\nconst IID IID_IDsQueryColumnHandler = {0xC072999E, 0xFA49, 0x11D1, [0xA0, 0xAF, 0x00, 0xC0, 0x4F, 0xA3, 0x1A, 0x86]};\nconst IID IID_IDummy = {0x0D7CA54A, 0xD252, 0x4FCB, [0x91, 0x04, 0xF6, 0xDD, 0xD3, 0x10, 0xB3, 0xF9]};\nconst IID IID_IDummyHICONIncluder = {0x947990DE, 0xCC28, 0x11D2, [0xA0, 0xF7, 0x00, 0x80, 0x5F, 0x85, 0x8F, 0xB1]};\nconst IID IID_IDX2D = {0x9EFD02A9, 0xA996, 0x11D1, [0x81, 0xC9, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_IDX2DDebug = {0x03BB2457, 0xA279, 0x11D1, [0x81, 0xC6, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_IDXARGBReadPtr = {0xEAAAC2D6, 0xC290, 0x11D1, [0x90, 0x5D, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXARGBReadWritePtr = {0xEAAAC2D7, 0xC290, 0x11D1, [0x90, 0x5D, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXARGBSurfaceInit = {0x9EA3B63A, 0xC37D, 0x11D1, [0x90, 0x5E, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXBaseObject = {0x17B59B2B, 0x9CC8, 0x11D1, [0x90, 0x53, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXBasicImage = {0x16B280C7, 0xEE70, 0x11D1, [0x90, 0x66, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXDCLock = {0x0F619456, 0xCF39, 0x11D1, [0x90, 0x5E, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXDLUTBuilder = {0x73068231, 0x35EE, 0x11D1, [0x81, 0xA1, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_IDXDMapper = {0x7FD9088B, 0x35ED, 0x11D1, [0x81, 0xA1, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_IDXEffect = {0xE31FB81B, 0x1335, 0x11D1, [0x81, 0x89, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_IDXGradient = {0xB2024B51, 0xEE77, 0x11D1, [0x90, 0x66, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXGradient2 = {0xD0EF2A80, 0x61DC, 0x11D2, [0xB2, 0xEB, 0x00, 0xA0, 0xC9, 0x36, 0xB2, 0x12]};\nconst IID IID_IDXLookupTable = {0x01BAFC7F, 0x9E63, 0x11D1, [0x90, 0x53, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXLUTBuilder = {0xF4370FC1, 0xCADB, 0x11D0, [0xB5, 0x2C, 0x00, 0xA0, 0xC9, 0x05, 0x43, 0x73]};\nconst IID IID_IDXMapper = {0x555278E5, 0x05DB, 0x11D1, [0x88, 0x3A, 0x3C, 0x8B, 0x00, 0xC1, 0x00, 0x00]};\nconst IID IID_IDXPixelate = {0xD33E180F, 0xFBE9, 0x11D1, [0x90, 0x6A, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXRasterizer = {0x9EA3B635, 0xC37D, 0x11D1, [0x90, 0x5E, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXRawSurface = {0x09756C8A, 0xD96A, 0x11D1, [0x90, 0x62, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXSurface = {0xB39FD73F, 0xE139, 0x11D1, [0x90, 0x65, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXSurfaceFactory = {0x144946F5, 0xC4D4, 0x11D1, [0x81, 0xD1, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_IDXSurfaceInit = {0x9EA3B639, 0xC37D, 0x11D1, [0x90, 0x5E, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXSurfaceModifier = {0x9EA3B637, 0xC37D, 0x11D1, [0x90, 0x5E, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXSurfacePick = {0x30A5FB79, 0xE11F, 0x11D1, [0x90, 0x64, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXTAlpha = {0x1D4637E0, 0x383C, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID IID_IDXTAlphaImageLoader = {0xA5F2D3E8, 0x7A7E, 0x48E5, [0xBC, 0x75, 0x40, 0x79, 0x0B, 0xE4, 0xA9, 0x41]};\nconst IID IID_IDXTaskManager = {0x254DBBC1, 0xF922, 0x11D0, [0x88, 0x3A, 0x3C, 0x8B, 0x00, 0xC1, 0x00, 0x00]};\nconst IID IID_IDXTBindHost = {0xD26BCE55, 0xE9DC, 0x11D1, [0x90, 0x66, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXTCheckerBoard = {0xAD3C2576, 0x117C, 0x4510, [0x84, 0xDD, 0xB6, 0x68, 0x97, 0x1D, 0xCF, 0xD1]};\nconst IID IID_IDXTChroma = {0x1D4637E2, 0x383C, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID IID_IDXTClipOrigin = {0xEE1663D8, 0x0988, 0x4C48, [0x9F, 0xD6, 0xDB, 0x44, 0x50, 0x88, 0x56, 0x68]};\nconst IID IID_IDXTComposite = {0x9A43A843, 0x0831, 0x11D1, [0x81, 0x7F, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_IDXTConvolution = {0x7BA7F8AF, 0xE5EA, 0x11D1, [0x81, 0xDD, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_IDXTDropShadow = {0x1D4637E3, 0x383C, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID IID_IDXTFade = {0x16B280C4, 0xEE70, 0x11D1, [0x90, 0x66, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXTFilter = {0x6187E5A2, 0xA445, 0x4608, [0x8F, 0xC0, 0xBE, 0x7A, 0x6C, 0x8D, 0xB3, 0x86]};\nconst IID IID_IDXTFilterBehavior = {0x14D7DDDD, 0xACA2, 0x4E45, [0x95, 0x04, 0x38, 0x08, 0xAB, 0xEB, 0x4F, 0x92]};\nconst IID IID_IDXTFilterBehaviorSite = {0x909B23C2, 0x9018, 0x499F, [0xA8, 0x6D, 0x4E, 0x7D, 0xA9, 0x37, 0xE9, 0x31]};\nconst IID IID_IDXTFilterCollection = {0x22B07B33, 0x8BFB, 0x49D4, [0x9B, 0x90, 0x09, 0x38, 0x37, 0x0C, 0x90, 0x19]};\nconst IID IID_IDXTFilterController = {0x5CF315F2, 0x273D, 0x47B6, [0xB9, 0xED, 0xF7, 0x5D, 0xC3, 0xB0, 0x15, 0x0B]};\nconst IID IID_IDXTGlow = {0x1D4637E4, 0x383C, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID IID_IDXTGradientD = {0x623E2881, 0xFC0E, 0x11D1, [0x9A, 0x77, 0x00, 0x00, 0xF8, 0x75, 0x6A, 0x10]};\nconst IID IID_IDXTGridSize = {0xD6BBE91E, 0xFF60, 0x11D2, [0x8F, 0x6E, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x74]};\nconst IID IID_IDXTICMFilter = {0x734321ED, 0x1E7B, 0x4E1C, [0xBB, 0xFA, 0x89, 0xC8, 0x19, 0x80, 0x0E, 0x2F]};\nconst IID IID_IDXTLabel = {0xC0C17F0E, 0xAE41, 0x11D1, [0x9A, 0x3B, 0x00, 0x00, 0xF8, 0x75, 0x6A, 0x10]};\nconst IID IID_IDXTLight = {0xF9EFBEC1, 0x4302, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID IID_IDXTMask = {0xA1067146, 0xB063, 0x47D7, [0xA5, 0x4A, 0x2C, 0x23, 0x09, 0xE9, 0x88, 0x9D]};\nconst IID IID_IDXTMatrix = {0xAC66A493, 0x0F0C, 0x4C76, [0x82, 0x5C, 0x9D, 0x68, 0xBE, 0xDE, 0x91, 0x88]};\nconst IID IID_IDXTMetaBurnFilm = {0x107045D0, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaCenterPeel = {0xAA0D4D0B, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID IID_IDXTMetaColorFade = {0x2A54C907, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaFlowMotion = {0x2A54C90A, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaGriddler = {0x2A54C910, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaGriddler2 = {0x2A54C912, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaJaws = {0x2A54C903, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaLightWipe = {0x107045C7, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaLiquid = {0xAA0D4D09, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID IID_IDXTMetaPageTurn = {0xAA0D4D07, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID IID_IDXTMetaPeelPiece = {0xAA0D4D0F, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID IID_IDXTMetaPeelSmall = {0xAA0D4D0D, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID IID_IDXTMetaPeelSplit = {0xAA0D4D11, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID IID_IDXTMetaRadialScaleWipe = {0x107045C9, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaRipple = {0xAA0D4D02, 0x06A3, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID IID_IDXTMetaRoll = {0x9C61F46D, 0x0530, 0x11D2, [0x8F, 0x98, 0x00, 0xC0, 0x4F, 0xB9, 0x2E, 0xB7]};\nconst IID IID_IDXTMetaThreshold = {0x2A54C914, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaTwister = {0x107045CE, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaVacuum = {0x2A54C90C, 0x07AA, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaWater = {0x107045C4, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaWhiteOut = {0x107045CB, 0x06E0, 0x11D2, [0x8D, 0x6D, 0x00, 0xC0, 0x4F, 0x8E, 0xF8, 0xE0]};\nconst IID IID_IDXTMetaWormHole = {0x0E6AE021, 0x0C83, 0x11D2, [0x8C, 0xD4, 0x00, 0x10, 0x4B, 0xC7, 0x5D, 0x9A]};\nconst IID IID_IDXTMotionBlur = {0x089057BE, 0xD3F5, 0x4A2C, [0xB1, 0x0A, 0xA5, 0x13, 0x01, 0x84, 0xA0, 0xF7]};\nconst IID IID_IDXTRandomBars = {0x8A6D2022, 0x4A8F, 0x4EB9, [0xBB, 0x25, 0xAA, 0x05, 0x20, 0x1F, 0x9C, 0x84]};\nconst IID IID_IDXTransform = {0x30A5FB78, 0xE11F, 0x11D1, [0x90, 0x64, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXTransformFactory = {0x6A950B2B, 0xA971, 0x11D1, [0x81, 0xC8, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_IDXTRedirect = {0x02F5140B, 0x626F, 0x4019, [0x9C, 0x9E, 0x2D, 0xAA, 0x1E, 0x93, 0xE8, 0xFC]};\nconst IID IID_IDXTRedirectFilterInit = {0xD1A57094, 0x21F7, 0x4E6C, [0x93, 0xE5, 0xF5, 0xF7, 0x7F, 0x74, 0x82, 0x93]};\nconst IID IID_IDXTRevealTrans = {0xB8095006, 0xA128, 0x464B, [0x8B, 0x2D, 0x90, 0x58, 0x0A, 0xEE, 0x2B, 0x05]};\nconst IID IID_IDXTScale = {0xB39FD742, 0xE139, 0x11D1, [0x90, 0x65, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXTScaleOutput = {0xB2024B50, 0xEE77, 0x11D1, [0x90, 0x66, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0x9D]};\nconst IID IID_IDXTShadow = {0x1D4637E6, 0x383C, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID IID_IDXTStrips = {0xA83C9B5C, 0xFB11, 0x4AF5, [0x8F, 0x65, 0xD0, 0x3F, 0x15, 0x1D, 0x3E, 0xD5]};\nconst IID IID_IDXTWave = {0x1D4637E7, 0x383C, 0x11D2, [0x95, 0x2A, 0x00, 0xC0, 0x4F, 0xA3, 0x4F, 0x05]};\nconst IID IID_IDXTWipe = {0xAF279B2F, 0x86EB, 0x11D1, [0x81, 0xBF, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID IID_IDXTWipe2 = {0xE1FF8091, 0x442B, 0x4801, [0x88, 0xB6, 0x2B, 0x47, 0xB1, 0x61, 0x1F, 0xD2]};\nconst IID IID_IDynamicPortMapping = {0x4FC80282, 0x23B6, 0x4378, [0x9A, 0x27, 0xCD, 0x8F, 0x17, 0xC9, 0x40, 0x0C]};\nconst IID IID_IDynamicPortMappingCollection = {0xB60DE00F, 0x156E, 0x4E8D, [0x9E, 0xC1, 0x3A, 0x23, 0x42, 0xC1, 0x08, 0x99]};\nconst IID IID_IEditDebugServices = {0x3050F60B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementAdorner = {0x3050F607, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehavior = {0x3050F425, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorCategory = {0x3050F4ED, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorFactory = {0x3050F429, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorFocus = {0x3050F6B6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorLayout = {0x3050F6BA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorLayout2 = {0x3050F846, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorRender = {0x3050F4AA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorSite = {0x3050F427, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorSiteCategory = {0x3050F4EE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorSiteLayout = {0x3050F6B7, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorSiteLayout2 = {0x3050F847, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorSiteOM = {0x3050F489, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorSiteOM2 = {0x3050F659, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorSiteRender = {0x3050F4A7, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorSubmit = {0x3050F646, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementBehaviorUI = {0x3050F4BF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementNamespace = {0x3050F671, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementNamespaceFactory = {0x3050F672, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementNamespaceFactory2 = {0x3050F805, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementNamespaceFactoryCallback = {0x3050F7FD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementNamespacePrivate = {0x3050F7FF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementNamespaceTable = {0x3050F670, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IElementSegment = {0x3050F68F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IEmptyVolumeCache = {0x8FCE5227, 0x04DA, 0x11D1, [0xA0, 0x04, 0x00, 0x80, 0x5F, 0x8A, 0xBE, 0x06]};\nconst IID IID_IEmptyVolumeCache2 = {0x02B7E3BA, 0x4DB3, 0x11D2, [0xB2, 0xD9, 0x00, 0xC0, 0x4F, 0x8E, 0xEC, 0x8C]};\nconst IID IID_IEmptyVolumeCacheCallBack = {0x6E793361, 0x73C6, 0x11D0, [0x84, 0x69, 0x00, 0xAA, 0x00, 0x44, 0x29, 0x01]};\nconst IID IID_IEncodingFilterFactory = {0x70BDDE00, 0xC18E, 0x11D0, [0xA9, 0xCE, 0x00, 0x60, 0x97, 0x94, 0x23, 0x11]};\nconst IID IID_IEnroll = {0xACAA7838, 0x4585, 0x11D1, [0xAB, 0x57, 0x00, 0xC0, 0x4F, 0xC2, 0x95, 0xE1]};\nconst IID IID_IEnroll2 = {0xC080E199, 0xB7DF, 0x11D2, [0xA4, 0x21, 0x00, 0xC0, 0x4F, 0x79, 0xFE, 0x8E]};\nconst IID IID_IEnroll4 = {0xF8053FE5, 0x78F4, 0x448F, [0xA0, 0xDB, 0x41, 0xD6, 0x1B, 0x73, 0x44, 0x6B]};\nconst IID IID_IEntryID = {0xE4D19810, 0xD188, 0x11CD, [0xAD, 0x48, 0x00, 0xAA, 0x00, 0x3C, 0x9C, 0xB6]};\nconst IID IID_IEnumACDGroup = {0x5AFC3157, 0x4BCC, 0x11D1, [0xBF, 0x80, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_IEnumACString = {0x8E74C210, 0xCF9D, 0x4EAF, [0xA4, 0x03, 0x73, 0x56, 0x42, 0x8F, 0x0A, 0x5A]};\nconst IID IID_IEnumAdapterInfo = {0xA23F9D11, 0x714C, 0x41FE, [0x84, 0x71, 0xFF, 0xB1, 0x9B, 0xC2, 0x84, 0x54]};\nconst IID IID_IEnumAddress = {0x1666FCA1, 0x9363, 0x11D0, [0x83, 0x5C, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_IEnumAgent = {0x5AFC314D, 0x4BCC, 0x11D1, [0xBF, 0x80, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_IEnumAgentHandler = {0x587E8C28, 0x9802, 0x11D1, [0xA0, 0xA4, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_IEnumAgentSession = {0x5AFC314E, 0x4BCC, 0x11D1, [0xBF, 0x80, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_IEnumBackgroundCopyFiles = {0xCA51E165, 0xC365, 0x424C, [0x8D, 0x41, 0x24, 0xAA, 0xA4, 0xFF, 0x3C, 0x40]};\nconst IID IID_IEnumBackgroundCopyGroups = {0xD993E603, 0x4AA4, 0x47C5, [0x86, 0x65, 0xC2, 0x0D, 0x39, 0xC2, 0xBA, 0x4F]};\nconst IID IID_IEnumBackgroundCopyJobs = {0x1AF4F612, 0x3B71, 0x466F, [0x8F, 0x58, 0x7B, 0x6F, 0x73, 0xAC, 0x57, 0xAD]};\nconst IID IID_IEnumBackgroundCopyJobs1 = {0x8BAEBA9D, 0x8F1C, 0x42C4, [0xB8, 0x2C, 0x09, 0xAE, 0x79, 0x98, 0x0D, 0x25]};\nconst IID IID_IEnumBstr = {0x35372049, 0x0BC6, 0x11D2, [0xA0, 0x33, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_IEnumCall = {0xAE269CF6, 0x935E, 0x11D0, [0x83, 0x5C, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_IEnumCallback = {0x00000108, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumCallHub = {0xA3C15450, 0x5B92, 0x11D1, [0x8F, 0x4E, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_IEnumCallingCard = {0x0C4D8F02, 0x8DDB, 0x11D1, [0xA0, 0x9E, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_IEnumCATEGORYINFO = {0x0002E011, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumChannels = {0xA4C65425, 0x0F82, 0x11D1, [0x90, 0xC3, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x68]};\nconst IID IID_IEnumClusCfgIPAddresses = {0xBD5F35BA, 0x0BC0, 0x455F, [0x92, 0x6D, 0xC3, 0xD3, 0x56, 0x41, 0x94, 0x86]};\nconst IID IID_IEnumClusCfgManagedResources = {0x7DBE11EB, 0xA5DF, 0x4534, [0xAB, 0xF6, 0x8B, 0xAC, 0x7B, 0x53, 0xFC, 0x95]};\nconst IID IID_IEnumClusCfgNetworks = {0xCF3FAED8, 0x1322, 0x4BCB, [0x99, 0x23, 0xB5, 0xB7, 0x45, 0xA6, 0x9E, 0x36]};\nconst IID IID_IEnumClusCfgPartitions = {0x4440BB6A, 0xB0AC, 0x479D, [0xB5, 0x34, 0x72, 0x65, 0xA3, 0x1D, 0x6C, 0x55]};\nconst IID IID_IEnumCodePage = {0x275C23E3, 0x3747, 0x11D0, [0x9F, 0xEA, 0x00, 0xAA, 0x00, 0x3F, 0x86, 0x46]};\nconst IID IID_IEnumConnectionPoints = {0xB196B285, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IEnumConnections = {0xB196B287, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IEnumCookies = {0x5E3E482E, 0x3C22, 0x482C, [0xB6, 0x64, 0x69, 0x30, 0x51, 0xAD, 0x0A, 0x5D]};\nconst IID IID_IEnumDebugApplicationNodes = {0x51973C3A, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IEnumDebugCodeContexts = {0x51973C1D, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IEnumDebugExpressionContexts = {0x51973C40, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IEnumDebugExtendedPropertyInfo = {0x51973C53, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IEnumDebugPropertyInfo = {0x51973C51, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IEnumDebugStackFrames = {0x51973C1E, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IEnumDebugStackFrames64 = {0x0DC38853, 0xC1B0, 0x4176, [0xA9, 0x84, 0xB2, 0x98, 0x36, 0x10, 0x27, 0xAF]};\nconst IID IID_IEnumDialableAddrs = {0x34621D70, 0x6CFF, 0x11D1, [0xAF, 0xF7, 0x00, 0xC0, 0x4F, 0xC3, 0x1F, 0xEE]};\nconst IID IID_IEnumDirectory = {0x34621D6D, 0x6CFF, 0x11D1, [0xAF, 0xF7, 0x00, 0xC0, 0x4F, 0xC3, 0x1F, 0xEE]};\nconst IID IID_IEnumDirectoryObject = {0x06C9B64A, 0x306D, 0x11D1, [0x97, 0x74, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_IEnumDiscMasterFormats = {0xDDF445E1, 0x54BA, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID IID_IEnumDiscRecorders = {0x9B1921E1, 0x54AC, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID IID_IEnumExtraSearch = {0x0E700BE1, 0x9DB6, 0x11D1, [0xA1, 0xCE, 0x00, 0xC0, 0x4F, 0xD7, 0x5D, 0x13]};\nconst IID IID_IEnumFORMATETC = {0x00000103, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumGeneric = {0x00000106, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumGUID = {0x0002E000, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumHLITEM = {0x79EAC9C6, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IEnumHNetApplicationProtocols = {0x85D18B7B, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IEnumHNetBridgedConnections = {0x85D18B7D, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IEnumHNetBridges = {0x85D18B77, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IEnumHNetFirewalledConnections = {0x85D18B78, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IEnumHNetIcsPrivateConnections = {0x85D18B7A, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IEnumHNetIcsPublicConnections = {0x85D18B79, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IEnumHNetPortMappingBindings = {0x85D18B81, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IEnumHNetPortMappingProtocols = {0x85D18B7C, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IEnumHolder = {0x00000107, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumIDList = {0x000214F2, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumInputContext = {0x09B5EAB0, 0xF997, 0x11D1, [0x93, 0xD4, 0x00, 0x60, 0xB0, 0x67, 0xB8, 0x6E]};\nconst IID IID_IEnumItemProperties = {0xF72C8D96, 0x6DBD, 0x11D1, [0xA1, 0xE8, 0x00, 0xC0, 0x4F, 0xC2, 0xFB, 0xE1]};\nconst IID IID_IEnumLocation = {0x0C4D8F01, 0x8DDB, 0x11D1, [0xA0, 0x9E, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_IEnumMcastScope = {0xDF0DAF09, 0xA289, 0x11D1, [0x86, 0x97, 0x00, 0x60, 0x08, 0xB0, 0xE5, 0xD2]};\nconst IID IID_IEnumMedia = {0xCA8397BE, 0x2FA4, 0x11D1, [0x97, 0x74, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_IEnumMoniker = {0x00000102, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumNetCfgBindingInterface = {0xC0E8AE90, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_IEnumNetCfgBindingPath = {0xC0E8AE91, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_IEnumNetCfgComponent = {0xC0E8AE92, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_IEnumNetConnection = {0xC08956A0, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_IEnumNetSharingEveryConnection = {0xC08956B8, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_IEnumNetSharingPortMapping = {0xC08956B0, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_IEnumNetSharingPrivateConnection = {0xC08956B5, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_IEnumNetSharingPublicConnection = {0xC08956B4, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_IEnumNodes = {0xC477E363, 0xAF0A, 0x4203, [0xA6, 0x04, 0x45, 0xCD, 0x60, 0x7D, 0xD7, 0x10]};\nconst IID IID_IEnumNotification = {0xC733E4A8, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_IEnumNotificationSinkItem = {0xC733E4AA, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_IEnumOleDocumentViews = {0xB722BCC8, 0x4E68, 0x101B, [0xA2, 0xBC, 0x00, 0xAA, 0x00, 0x40, 0x47, 0x70]};\nconst IID IID_IEnumOleUndoUnits = {0xB3E7C340, 0xEF97, 0x11CE, [0x9B, 0xC9, 0x00, 0xAA, 0x00, 0x60, 0x8E, 0x01]};\nconst IID IID_IEnumOLEVERB = {0x00000104, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumParticipant = {0x0A91B56C, 0x5A35, 0x11D2, [0x95, 0xA0, 0x00, 0xA0, 0x24, 0x4D, 0x22, 0x98]};\nconst IID IID_IEnumPhone = {0xF15B7669, 0x4780, 0x4595, [0x8C, 0x89, 0xFB, 0x36, 0x9C, 0x8C, 0xF7, 0xAA]};\nconst IID IID_IEnumPluggableSuperclassInfo = {0xE9586A80, 0x89E6, 0x4CFF, [0x93, 0x1D, 0x47, 0x8D, 0x57, 0x51, 0xF4, 0xC0]};\nconst IID IID_IEnumPluggableTerminalClassInfo = {0x4567450C, 0xDBEE, 0x4E3F, [0xAA, 0xF5, 0x37, 0xBF, 0x9E, 0xBF, 0x5E, 0x29]};\nconst IID IID_IEnumPrivacyRecords = {0x3050F844, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IEnumPropertyMap = {0xC733E4A1, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_IEnumPublishedApps = {0x0B124F8C, 0x91F0, 0x11D1, [0xB8, 0xB5, 0x00, 0x60, 0x08, 0x05, 0x93, 0x82]};\nconst IID IID_IEnumQueue = {0x5AFC3158, 0x4BCC, 0x11D1, [0xBF, 0x80, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_IEnumRegisterWordA = {0x08C03412, 0xF96B, 0x11D0, [0xA4, 0x75, 0x00, 0xAA, 0x00, 0x6B, 0xCC, 0x59]};\nconst IID IID_IEnumRegisterWordW = {0x4955DD31, 0xB159, 0x11D0, [0x8F, 0xCF, 0x00, 0xAA, 0x00, 0x6B, 0xCC, 0x59]};\nconst IID IID_IEnumRemoteDebugApplications = {0x51973C3B, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IEnumRemoteDebugApplicationThrea = {0x51973C3C, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IEnumRfc1766 = {0x3DC39D1D, 0xC030, 0x11D0, [0xB8, 0x1B, 0x00, 0xC0, 0x4F, 0xC9, 0xB3, 0x1F]};\nconst IID IID_IEnumScheduleGroup = {0xC733E4A9, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_IEnumScript = {0xAE5F1430, 0x388B, 0x11D2, [0x83, 0x80, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0xA1]};\nconst IID IID_IEnumSTATDATA = {0x00000105, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumSTATPROPBAG = {0x20021801, 0x5DE6, 0x11D1, [0x8E, 0x38, 0x00, 0xC0, 0x4F, 0xB9, 0x38, 0x6D]};\nconst IID IID_IEnumSTATPROPSETSTG = {0x0000013B, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumSTATPROPSTG = {0x00000139, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumSTATSTG = {0x0000000D, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumSTATURL = {0x3C374A42, 0xBAE4, 0x11CF, [0xBF, 0x7D, 0x00, 0xAA, 0x00, 0x69, 0x46, 0xEE]};\nconst IID IID_IEnumStream = {0xEE3BD606, 0x3868, 0x11D2, [0xA0, 0x45, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_IEnumString = {0x00000101, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumSubscription = {0xF72C8D97, 0x6DBD, 0x11D1, [0xA1, 0xE8, 0x00, 0xC0, 0x4F, 0xC2, 0xFB, 0xE1]};\nconst IID IID_IEnumSubStream = {0xEE3BD609, 0x3868, 0x11D2, [0xA0, 0x45, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_IEnumSyncItems = {0xF0E1589A, 0xA700, 0x11D1, [0x98, 0x31, 0x00, 0xC0, 0x4F, 0xD9, 0x10, 0xDD]};\nconst IID IID_IEnumSyncSchedules = {0xF0E15898, 0xA700, 0x11D1, [0x98, 0x31, 0x00, 0xC0, 0x4F, 0xD9, 0x10, 0xDD]};\nconst IID IID_IEnumTerminal = {0xAE269CF4, 0x935E, 0x11D0, [0x83, 0x5C, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_IEnumTerminalClass = {0xAE269CF5, 0x935E, 0x11D0, [0x83, 0x5C, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_IEnumTime = {0x9055322E, 0x2FA8, 0x11D1, [0x97, 0x74, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_IEnumTravelLogEntry = {0x7EBFDD85, 0xAD18, 0x11D3, [0xA4, 0xC5, 0x00, 0xC0, 0x4F, 0x72, 0xD6, 0xB8]};\nconst IID IID_IEnumUnknown = {0x00000100, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumVARIANT = {0x00020404, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IEnumWbemClassObject = {0x027947E1, 0xD731, 0x11CE, [0xA3, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]};\nconst IID IID_IErrorInfo = {0x1CF2B120, 0x547D, 0x101B, [0x8E, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19]};\nconst IID IID_IErrorLog = {0x3127CA40, 0x446E, 0x11CE, [0x81, 0x35, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51]};\nconst IID IID_IErrorLookup = {0x0C733A66, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IErrorRecords = {0x0C733A67, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IESP = {0xE99A04AA, 0xAB95, 0x11D0, [0xBE, 0x96, 0x00, 0xA0, 0xC9, 0x49, 0x89, 0xDE]};\nconst IID IID_IExtendObjectManager = {0xCA7BB0B9, 0x700C, 0x4DC5, [0x99, 0x1E, 0x75, 0xF9, 0xE6, 0x5E, 0xE9, 0x75]};\nconst IID IID_IExtensionServices = {0x79EAC9CB, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IExternalConnection = {0x00000019, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IExtractIconA = {0x000214EB, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IExtractIconW = {0x000214FA, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IExtractImage = {0xBB2E617C, 0x0920, 0x11D1, [0x9A, 0x0B, 0x00, 0xC0, 0x4F, 0xC2, 0xD6, 0xC1]};\nconst IID IID_IExtractImage2 = {0x953BB1EE, 0x93B4, 0x11D1, [0x98, 0xA3, 0x00, 0xC0, 0x4F, 0xB6, 0x87, 0xDA]};\nconst IID IID_IFileSearchBand = {0x2D91EEA1, 0x9932, 0x11D2, [0xBE, 0x86, 0x00, 0xA0, 0xC9, 0xA8, 0x3D, 0xA1]};\nconst IID IID_IFileSystemBindData = {0x01E18D10, 0x4D8B, 0x11D2, [0x85, 0x5D, 0x00, 0x60, 0x08, 0x05, 0x93, 0x67]};\nconst IID IID_IFileViewerA = {0x000214F0, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IFileViewerSite = {0x000214F3, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IFileViewerW = {0x000214F8, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IFillLockBytes = {0x99CAF010, 0x415E, 0x11CF, [0x88, 0x14, 0x00, 0xAA, 0x00, 0xB5, 0x69, 0xF5]};\nconst IID IID_IFilter = {0x89BCB740, 0x6119, 0x101A, [0xBC, 0xB7, 0x00, 0xDD, 0x01, 0x06, 0x55, 0xAF]};\nconst IID IID_IFilterAnimationInfo = {0x02E29300, 0xC758, 0x49B4, [0x9E, 0x11, 0xC5, 0x8B, 0xFE, 0x90, 0x55, 0x8B]};\nconst IID IID_IFilterStatus = {0xF4EB8260, 0x8DDA, 0x11D1, [0xB3, 0xAA, 0x00, 0xA0, 0xC9, 0x06, 0x37, 0x96]};\nconst IID IID_IFolderFilter = {0x9CC22886, 0xDC8E, 0x11D2, [0xB1, 0xD0, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x3E]};\nconst IID IID_IFolderFilterSite = {0xC0A651F5, 0xB48B, 0x11D2, [0xB5, 0xED, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6]};\nconst IID IID_IFolderView = {0xCDE725B0, 0xCCC9, 0x4519, [0x91, 0x7E, 0x32, 0x5D, 0x72, 0xFA, 0xB4, 0xCE]};\nconst IID IID_IFolderViewHost = {0x1EA58F02, 0xD55A, 0x411D, [0xB0, 0x9E, 0x9E, 0x65, 0xAC, 0x21, 0x60, 0x5B]};\nconst IID IID_IFolderViewOC = {0x9BA05970, 0xF6A8, 0x11CF, [0xA4, 0x42, 0x00, 0xA0, 0xC9, 0x0A, 0x8F, 0x39]};\nconst IID IID_IFont = {0xBEF6E002, 0xA874, 0x101A, [0x8B, 0xBA, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID IID_IFontDisp = {0xBEF6E003, 0xA874, 0x101A, [0x8B, 0xBA, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID IID_IFontEventsDisp = {0x4EF6100A, 0xAF88, 0x11D0, [0x98, 0x46, 0x00, 0xC0, 0x4F, 0xC2, 0x99, 0x93]};\nconst IID IID_IFontNames = {0x3050F839, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IForegroundTransfer = {0x00000145, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IFsCiAdmin = {0x75398C30, 0x7A26, 0x11D0, [0xA8, 0x0A, 0x00, 0xA0, 0xC9, 0x06, 0x24, 0x1A]};\nconst IID IID_IGatherData = {0x65318F4A, 0xB63C, 0x4E21, [0xAD, 0xDC, 0xBD, 0xCF, 0xB9, 0x69, 0xE1, 0x81]};\nconst IID IID_IGetClusterDataInfo = {0x97DEDE51, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IGetClusterGroupInfo = {0x97DEDE54, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IGetClusterNetInterfaceInfo = {0x97DEDE57, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IGetClusterNetworkInfo = {0x97DEDE56, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IGetClusterNodeInfo = {0x97DEDE53, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IGetClusterObjectInfo = {0x97DEDE52, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IGetClusterResourceInfo = {0x97DEDE55, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IGetClusterUIInfo = {0x97DEDE50, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IGetDataSource = {0x0C733A75, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IGetRow = {0x0C733AAF, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IGetSession = {0x0C733ABA, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IGetSourceRow = {0x0C733ABB, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IGlobalInterfaceTable = {0x00000146, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IH26XEncodeOptions = {0x65698D40, 0x282D, 0x11D0, [0x88, 0x00, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IH26XEncoderControl = {0xF9B78AA1, 0xEA12, 0x11CF, [0x9F, 0xEC, 0x00, 0xAA, 0x00, 0xA5, 0x9F, 0x69]};\nconst IID IID_IH26XRTPControl = {0x1FC3F2C0, 0x2BFD, 0x11D0, [0x88, 0x00, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IH26XSnapshot = {0x3CB194A0, 0x10AA, 0x11D0, [0x88, 0x00, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IH26XVideoEffects = {0x21555140, 0x9C2B, 0x11CF, [0x90, 0xFA, 0x00, 0xAA, 0x00, 0xA7, 0x29, 0xEA]};\nconst IID IID_IH323LineEx = {0x44CF6A9D, 0xCB40, 0x4BBC, [0xB2, 0xD3, 0xB6, 0xAA, 0x93, 0x32, 0x2C, 0x71]};\nconst IID IID_IHeaderFooter = {0x3050F6CE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHighlightRenderingServices = {0x3050F606, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHighlightSegment = {0x3050F690, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHlink = {0x79EAC9C3, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IHlinkBrowseContext = {0x79EAC9C7, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IHlinkFrame = {0x79EAC9C5, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IHlinkSite = {0x79EAC9C2, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IHlinkTarget = {0x79EAC9C4, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IHNetApplicationProtocol = {0x85D18B7F, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetBridge = {0x85D18B75, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetBridgedConnection = {0x85D18B76, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetBridgeSettings = {0x85D18B6D, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetCfgMgr = {0x85D18B6C, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetConnection = {0x85D18B71, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetFirewalledConnection = {0x85D18B72, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetFirewallSettings = {0x85D18B6E, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetIcsPrivateConnection = {0x85D18B74, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetIcsPublicConnection = {0x85D18B73, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetIcsSettings = {0x85D18B6F, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetPortMappingBinding = {0x85D18B80, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetPortMappingProtocol = {0x85D18B7E, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHNetProtocolSettings = {0x85D18B70, 0x3032, 0x11D4, [0x93, 0x48, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x71]};\nconst IID IID_IHomePage = {0x766BF2AF, 0xD650, 0x11D1, [0x98, 0x11, 0x00, 0xC0, 0x4F, 0xC3, 0x1D, 0x2E]};\nconst IID IID_IHostBehaviorInit = {0x3050F842, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHostDialogHelper = {0x53DEC138, 0xA51E, 0x11D2, [0x86, 0x1E, 0x00, 0xC0, 0x4F, 0xA3, 0x5C, 0x89]};\nconst IID IID_IHTCAttachBehavior = {0x3050F5F4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTCAttachBehavior2 = {0x3050F7EB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTCDefaultDispatch = {0x3050F4FD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTCDescBehavior = {0x3050F5DC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTCEventBehavior = {0x3050F4FF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTCMethodBehavior = {0x3050F631, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTCPropertyBehavior = {0x3050F5DF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLAnchorElement = {0x3050F1DA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLAnchorElement2 = {0x3050F825, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLAppBehavior = {0x3050F5CA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLAppBehavior2 = {0x3050F5C9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLAppBehavior3 = {0x3050F5CD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHtmlArea = {0x3050F64E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLAreaElement = {0x3050F265, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLAreasCollection = {0x3050F383, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLAreasCollection2 = {0x3050F5EC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLAreasCollection3 = {0x3050F837, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLAttributeCollection = {0x3050F4C3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLAttributeCollection2 = {0x3050F80A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLBaseElement = {0x3050F204, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLBaseFontElement = {0x3050F202, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLBGsound = {0x3050F369, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLBlockElement = {0x3050F208, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLBlockElement2 = {0x3050F823, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLBodyElement = {0x3050F1D8, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLBodyElement2 = {0x3050F5C5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLBookmarkCollection = {0x3050F4CE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLBRElement = {0x3050F1F0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLButtonElement = {0x3050F2BB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLCaret = {0x3050F604, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLChangeLog = {0x3050F649, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLChangePlayback = {0x3050F6E0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLChangeSink = {0x3050F64A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLCommentElement = {0x3050F20C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLCommentElement2 = {0x3050F813, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLComputedStyle = {0x3050F6C3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLControlElement = {0x3050F4E9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLControlRange = {0x3050F29C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLControlRange2 = {0x3050F65E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLCurrentStyle = {0x3050F3DB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLCurrentStyle2 = {0x3050F658, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLCurrentStyle3 = {0x3050F818, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDatabinding = {0x3050F3F2, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDataTransfer = {0x3050F4B3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDDElement = {0x3050F1F2, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDialog = {0x3050F216, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDialog2 = {0x3050F5E0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDialog3 = {0x3050F388, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDivElement = {0x3050F200, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDivPosition = {0x3050F212, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHtmlDlgSafeHelper = {0x3050F81A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDListElement = {0x3050F1F1, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDocument = {0x626FC520, 0xA41E, 0x11CF, [0xA7, 0x31, 0x00, 0xA0, 0xC9, 0x08, 0x26, 0x37]};\nconst IID IID_IHTMLDocument2 = {0x332C4425, 0x26CB, 0x11D0, [0xB4, 0x83, 0x00, 0xC0, 0x4F, 0xD9, 0x01, 0x19]};\nconst IID IID_IHTMLDocument3 = {0x3050F485, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDocument4 = {0x3050F69A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDocument5 = {0x3050F80C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDOMAttribute = {0x3050F4B0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDOMAttribute2 = {0x3050F810, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDOMChildrenCollection = {0x3050F5AB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDOMImplementation = {0x3050F80D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDOMNode = {0x3050F5DA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDOMNode2 = {0x3050F80B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDOMTextNode = {0x3050F4B1, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDOMTextNode2 = {0x3050F809, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDTElement = {0x3050F1F3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLDXTransform = {0x30E2AB7D, 0x4FDD, 0x4159, [0xB7, 0xEA, 0xDC, 0x72, 0x2B, 0xF4, 0xAD, 0xE5]};\nconst IID IID_IHTMLEditDesigner = {0x3050F662, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLEditHost = {0x3050F6A0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLEditHost2 = {0x3050F848, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0D]};\nconst IID IID_IHTMLEditingServices = {0x3050F7FB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLEditor = {0x3050F7FA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLEditServices = {0x3050F663, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLEditServices2 = {0x3050F812, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLElement = {0x3050F1FF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLElement2 = {0x3050F434, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLElement3 = {0x3050F673, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLElement4 = {0x3050F80F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLElementCollection = {0x3050F21F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLElementCollection2 = {0x3050F5EE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLElementCollection3 = {0x3050F835, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLElementDefaults = {0x3050F6C9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLElementRender = {0x3050F669, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLEmbedElement = {0x3050F25F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLEventObj = {0x3050F32D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLEventObj2 = {0x3050F48B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLEventObj3 = {0x3050F680, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLEventObj4 = {0x3050F814, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFieldSetElement = {0x3050F3E7, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFieldSetElement2 = {0x3050F833, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFilterPainter = {0x3050F6DE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFilterPaintSite = {0x3050F6D3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFiltersCollection = {0x3050F3EE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFontElement = {0x3050F1D9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFontNamesCollection = {0x3050F376, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFontSizesCollection = {0x3050F377, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFormElement = {0x3050F1F7, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFormElement2 = {0x3050F4F6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFormElement3 = {0x3050F836, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFrameBase = {0x3050F311, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFrameBase2 = {0x3050F6DB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFrameBase3 = {0x3050F82E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFrameElement = {0x3050F313, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFrameElement2 = {0x3050F7F5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFramesCollection2 = {0x332C4426, 0x26CB, 0x11D0, [0xB4, 0x83, 0x00, 0xC0, 0x4F, 0xD9, 0x01, 0x19]};\nconst IID IID_IHTMLFrameSetElement = {0x3050F319, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLFrameSetElement2 = {0x3050F5C6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLGenericElement = {0x3050F4B7, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLHeadElement = {0x3050F81D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLHeaderElement = {0x3050F1F6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLHRElement = {0x3050F1F4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLHtmlElement = {0x3050F81C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLIFrameElement = {0x3050F315, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLIFrameElement2 = {0x3050F4E6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLImageElementFactory = {0x3050F38E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLImgElement = {0x3050F240, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLImgElement2 = {0x3050F826, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLInputButtonElement = {0x3050F2B2, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLInputElement = {0x3050F5D2, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLInputElement2 = {0x3050F821, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLInputFileElement = {0x3050F2AD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLInputHiddenElement = {0x3050F2A4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLInputImage = {0x3050F2C2, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLInputTextElement = {0x3050F2A6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLIPrintCollection = {0x3050F6B5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLIsIndexElement = {0x3050F206, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLIsIndexElement2 = {0x3050F82F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLLabelElement = {0x3050F32A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLLabelElement2 = {0x3050F832, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLLegendElement = {0x3050F3EA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLLegendElement2 = {0x3050F834, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLLIElement = {0x3050F1E0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLLinkElement = {0x3050F205, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLLinkElement2 = {0x3050F4E5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLLinkElement3 = {0x3050F81E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLListElement = {0x3050F20E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLListElement2 = {0x3050F822, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHtmlLoadOptions = {0xA71A0808, 0x0F88, 0x11D1, [0xBA, 0x19, 0x00, 0xC0, 0x4F, 0xD9, 0x12, 0xD0]};\nconst IID IID_IHTMLLocation = {0x163BB1E0, 0x6E00, 0x11CF, [0x83, 0x7A, 0x48, 0xDC, 0x04, 0xC1, 0x00, 0x00]};\nconst IID IID_IHTMLMapElement = {0x3050F266, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLMarqueeElement = {0x3050F2B5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLMetaElement = {0x3050F203, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLMetaElement2 = {0x3050F81F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLMimeTypesCollection = {0x3050F3FC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLModelessInit = {0x3050F5E4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLNamespace = {0x3050F6BB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLNamespaceCollection = {0x3050F6B8, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLNextIdElement = {0x3050F207, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLNoShowElement = {0x3050F38A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLObjectElement = {0x3050F24F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLObjectElement2 = {0x3050F4CD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLObjectElement3 = {0x3050F827, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLOListElement = {0x3050F1DE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLOMWindowServices = {0x3050F5FC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLOpsProfile = {0x3050F401, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLOptionButtonElement = {0x3050F2BC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLOptionElement = {0x3050F211, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLOptionElement2 = {0x3050F697, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLOptionElement3 = {0x3050F820, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLOptionElementFactory = {0x3050F38C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLOptionsHolder = {0x3050F378, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPainter = {0x3050F6A6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPainterEventInfo = {0x3050F6DF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPainterOverlay = {0x3050F7E3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPaintSite = {0x3050F6A7, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLParaElement = {0x3050F1F5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLParamElement = {0x3050F83D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPersistData = {0x3050F4C5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPersistDataOM = {0x3050F4C0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPhraseElement = {0x3050F20A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPhraseElement2 = {0x3050F824, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPluginsCollection = {0x3050F3FD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPopup = {0x3050F666, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPrivateWindow = {0x3050F6DC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPrivateWindow2 = {0x3050F7E5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLPrivateWindow3 = {0x3050F840, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLRect = {0x3050F4A3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLRectCollection = {0x3050F4A4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLRenderStyle = {0x3050F6AE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLRuleStyle = {0x3050F3CF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLRuleStyle2 = {0x3050F4AC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLRuleStyle3 = {0x3050F657, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLRuleStyle4 = {0x3050F817, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLScreen = {0x3050F35C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLScreen2 = {0x3050F84A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLScriptElement = {0x3050F28B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLScriptElement2 = {0x3050F828, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLSelectElement = {0x3050F244, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLSelectElement2 = {0x3050F5ED, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLSelectElement3 = {0x3050F687, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLSelectElement4 = {0x3050F838, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLSelectionObject = {0x3050F25A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLSelectionObject2 = {0x3050F7EC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLSpanElement = {0x3050F3F3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLSpanFlow = {0x3050F3E5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyle = {0x3050F25E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyle2 = {0x3050F4A2, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyle3 = {0x3050F656, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyle4 = {0x3050F816, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyleElement = {0x3050F375, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyleFontFace = {0x3050F3D5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyleSheet = {0x3050F2E3, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyleSheet2 = {0x3050F3D1, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyleSheetPage = {0x3050F7EE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyleSheetPagesCollection = {0x3050F7F0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyleSheetRule = {0x3050F357, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyleSheetRulesCollection = {0x3050F2E5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLStyleSheetsCollection = {0x3050F37E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLSubmitData = {0x3050F645, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTable = {0x3050F21E, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTable2 = {0x3050F4AD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTable3 = {0x3050F829, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableCaption = {0x3050F2EB, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableCell = {0x3050F23D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableCell2 = {0x3050F82D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableCol = {0x3050F23A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableCol2 = {0x3050F82A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableRow = {0x3050F23C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableRow2 = {0x3050F4A1, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableRow3 = {0x3050F82C, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableRowMetrics = {0x3050F413, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableSection = {0x3050F23B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableSection2 = {0x3050F5C7, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTableSection3 = {0x3050F82B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTextAreaElement = {0x3050F2AA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTextContainer = {0x3050F230, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTextElement = {0x3050F218, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTextRangeMetrics = {0x3050F40B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTextRangeMetrics2 = {0x3050F4A6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTitleElement = {0x3050F322, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTxtRange = {0x3050F220, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLTxtRangeCollection = {0x3050F7ED, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLUListElement = {0x3050F1DD, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLUniqueName = {0x3050F4D0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLUnknownElement = {0x3050F209, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLUrnCollection = {0x3050F5E2, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLUserDataOM = {0x3050F48F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLViewFilter = {0x3050F2F1, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLViewFilterSite = {0x3050F2F4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLWindow2 = {0x332C4427, 0x26CB, 0x11D0, [0xB4, 0x83, 0x00, 0xC0, 0x4F, 0xD9, 0x01, 0x19]};\nconst IID IID_IHTMLWindow3 = {0x3050F4AE, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHTMLWindow4 = {0x3050F6CF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IHttpNegotiate = {0x79EAC9D2, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IHttpNegotiate2 = {0x4F9F9FCB, 0xE0F4, 0x48EB, [0xB7, 0xAB, 0xFA, 0x2E, 0xA9, 0x36, 0x5C, 0xB4]};\nconst IID IID_IHttpSecurity = {0x79EAC9D7, 0xBAFA, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IHWEventHandler = {0xC1FB73D0, 0xEC3A, 0x4BA2, [0xB5, 0x12, 0x8C, 0xDB, 0x91, 0x87, 0xB6, 0xD1]};\nconst IID IID_IImageDecodeEventSink = {0xBAA342A0, 0x2DED, 0x11D0, [0x86, 0xF4, 0x00, 0xA0, 0xC9, 0x13, 0xF7, 0x50]};\nconst IID IID_IImageDecodeFilter = {0xA3CCEDF3, 0x2DE2, 0x11D0, [0x86, 0xF4, 0x00, 0xA0, 0xC9, 0x13, 0xF7, 0x50]};\nconst IID IID_IImageList = {0x46EB5926, 0x582E, 0x4017, [0x9F, 0xDF, 0xE8, 0x99, 0x8D, 0xAA, 0x09, 0x50]};\nconst IID IID_IIMEServices = {0x3050F6CA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IImgCtx = {0x3050F3D7, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IIndexDefinition = {0x0C733A68, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IInputObject = {0x68284FAA, 0x6A48, 0x11D0, [0x8C, 0x78, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xB4]};\nconst IID IID_IInputObjectSite = {0xF1DB8392, 0x7331, 0x11D0, [0x8C, 0x99, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8]};\nconst IID IID_IIntDitherer = {0x06670CA0, 0xECEF, 0x11D0, [0xAA, 0xE7, 0x00, 0xC0, 0x4F, 0xC9, 0xB3, 0x04]};\nconst IID IID_IIntelliForms = {0x9B9F68E6, 0x1AAA, 0x11D2, [0xBC, 0xA5, 0x00, 0xC0, 0x4F, 0xD9, 0x29, 0xDB]};\nconst IID IID_IInterfaceRelated = {0xD1FB5A79, 0x7706, 0x11D1, [0xAD, 0xBA, 0x00, 0xC0, 0x4F, 0xC2, 0xAD, 0xC0]};\nconst IID IID_IInternalMoniker = {0x00000011, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IInternalUnknown = {0x00000021, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IInternet = {0x79EAC9E0, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetBindInfo = {0x79EAC9E1, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetConnectionDevice = {0x04DF6137, 0x5610, 0x11D4, [0x9E, 0xC8, 0x00, 0xB0, 0xD0, 0x22, 0xDD, 0x1F]};\nconst IID IID_IInternetConnectionDeviceClient = {0x04DF6139, 0x5610, 0x11D4, [0x9E, 0xC8, 0x00, 0xB0, 0xD0, 0x22, 0xDD, 0x1F]};\nconst IID IID_IInternetConnectionDeviceSharedCo = {0x04DF6138, 0x5610, 0x11D4, [0x9E, 0xC8, 0x00, 0xB0, 0xD0, 0x22, 0xDD, 0x1F]};\nconst IID IID_IInternetHostSecurityManager = {0x3AF280B6, 0xCB3F, 0x11D0, [0x89, 0x1E, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4]};\nconst IID IID_IInternetPriority = {0x79EAC9EB, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetProtocol = {0x79EAC9E4, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetProtocolInfo = {0x79EAC9EC, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetProtocolRoot = {0x79EAC9E3, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetProtocolSink = {0x79EAC9E5, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetProtocolSinkStackable = {0x79EAC9F0, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetSecurityManager = {0x79EAC9EE, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetSecurityMgrSite = {0x79EAC9ED, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetSession = {0x79EAC9E7, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetThreadSwitch = {0x79EAC9E8, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IInternetZoneManager = {0x79EAC9EF, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IIpxAdapterInfo = {0x98133270, 0x4B20, 0x11D1, [0xAB, 0x01, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_IItemNameLimits = {0x1DF0D7F1, 0xB267, 0x4D28, [0x8B, 0x10, 0x12, 0xE2, 0x32, 0x02, 0xA5, 0xC4]};\nconst IID IID_IJolietDiscMaster = {0xE3BC42CE, 0x4E5C, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID IID_IKeyFrameControl = {0xC3341386, 0xAF91, 0x4EF9, [0x83, 0xB6, 0xBE, 0x37, 0x62, 0xE4, 0x2E, 0xCB]};\nconst IID IID_IKsControl = {0x28F54685, 0x06FD, 0x11D2, [0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96]};\nconst IID IID_IKsPropertySet = {0x31EFAC30, 0x515C, 0x11D0, [0xA9, 0xAA, 0x00, 0xAA, 0x00, 0x61, 0xBE, 0x93]};\nconst IID IID_ILayoutRect = {0x3050F665, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ILayoutStorage = {0x0E6D4D90, 0x6738, 0x11CF, [0x96, 0x08, 0x00, 0xAA, 0x00, 0x68, 0x0D, 0xB4]};\nconst IID IID_ILineInfo = {0x3050F7E2, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ILocalMachine = {0x60664CAF, 0xAF0D, 0x1005, [0xA3, 0x00, 0x5C, 0x7D, 0x25, 0xFF, 0x22, 0xA0]};\nconst IID IID_ILockBytes = {0x0000000A, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ILogger = {0xD9598418, 0x304E, 0x4F94, [0xB6, 0xA1, 0xE6, 0x42, 0xFE, 0x95, 0xED, 0x57]};\nconst IID IID_ILogManager = {0x4759DC11, 0x8DA0, 0x4261, [0xBB, 0xFB, 0xEC, 0x32, 0x19, 0x11, 0xD1, 0xC9]};\nconst IID IID_ILogonEnumUsers = {0x60664CAF, 0xAF0D, 0x1004, [0xA3, 0x00, 0x5C, 0x7D, 0x25, 0xFF, 0x22, 0xA0]};\nconst IID IID_ILogonStatusHost = {0x60664CAF, 0xAF0D, 0x1007, [0xA3, 0x00, 0x5C, 0x7D, 0x25, 0xFF, 0x22, 0xA0]};\nconst IID IID_ILogonUser = {0x60664CAF, 0xAF0D, 0x1003, [0xA3, 0x00, 0x5C, 0x7D, 0x25, 0xFF, 0x22, 0xA0]};\nconst IID IID_IMachineDebugManager = {0x51973C2C, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IMachineDebugManagerCookie = {0x51973C2D, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IMachineDebugManagerEvents = {0x51973C2E, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IMailAutoDiscovery = {0x80402DEE, 0xB114, 0x4D32, [0xB4, 0x4E, 0x82, 0xFD, 0x82, 0x34, 0xC9, 0x2A]};\nconst IID IID_IMailProtocolADEntry = {0x40EF8C68, 0xD554, 0x47ED, [0xAA, 0x37, 0xE5, 0xFB, 0x6B, 0xC9, 0x10, 0x75]};\nconst IID IID_IMalloc = {0x00000002, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IMallocSpy = {0x0000001D, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IMapMIMEToCLSID = {0xD9E89500, 0x30FA, 0x11D0, [0xB7, 0x24, 0x00, 0xAA, 0x00, 0x6C, 0x1A, 0x01]};\nconst IID IID_IMarkupContainer = {0x3050F5F9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IMarkupContainer2 = {0x3050F648, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IMarkupPointer = {0x3050F49F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IMarkupPointer2 = {0x3050F675, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IMarkupServices = {0x3050F4A0, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IMarkupServices2 = {0x3050F682, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IMarkupTextFrags = {0x3050F5FA, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IMarshal = {0x00000003, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IMarshal2 = {0x000001CF, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IMcastAddressAllocation = {0xDF0DAEF1, 0xA289, 0x11D1, [0x86, 0x97, 0x00, 0x60, 0x08, 0xB0, 0xE5, 0xD2]};\nconst IID IID_IMcastLeaseInfo = {0xDF0DAEFD, 0xA289, 0x11D1, [0x86, 0x97, 0x00, 0x60, 0x08, 0xB0, 0xE5, 0xD2]};\nconst IID IID_IMcastScope = {0xDF0DAEF4, 0xA289, 0x11D1, [0x86, 0x97, 0x00, 0x60, 0x08, 0xB0, 0xE5, 0xD2]};\nconst IID IID_IMDDataset = {0xA07CCCD1, 0x8148, 0x11D0, [0x87, 0xBB, 0x00, 0xC0, 0x4F, 0xC3, 0x39, 0x42]};\nconst IID IID_IMDFind = {0xA07CCCD2, 0x8148, 0x11D0, [0x87, 0xBB, 0x00, 0xC0, 0x4F, 0xC3, 0x39, 0x42]};\nconst IID IID_IMDRangeRowset = {0x0C733AA0, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IMessageFilter = {0x00000016, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IMigrationWizardAuto = {0xCE20DAB9, 0xB353, 0x469B, [0x8B, 0x4D, 0x6D, 0xBB, 0x3A, 0x7B, 0xA0, 0x16]};\nconst IID IID_IMimeInfo = {0xF77459A0, 0xBF9A, 0x11CF, [0xBA, 0x4E, 0x00, 0xC0, 0x4F, 0xD7, 0x08, 0x16]};\nconst IID IID_IMLangCodePages = {0x359F3443, 0xBD4A, 0x11D0, [0xB1, 0x88, 0x00, 0xAA, 0x00, 0x38, 0xC9, 0x69]};\nconst IID IID_IMLangConvertCharset = {0xD66D6F98, 0xCDAA, 0x11D0, [0xB8, 0x22, 0x00, 0xC0, 0x4F, 0xC9, 0xB3, 0x1F]};\nconst IID IID_IMLangFontLink = {0x359F3441, 0xBD4A, 0x11D0, [0xB1, 0x88, 0x00, 0xAA, 0x00, 0x38, 0xC9, 0x69]};\nconst IID IID_IMLangFontLink2 = {0xDCCFC162, 0x2B38, 0x11D2, [0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A]};\nconst IID IID_IMLangLineBreakConsole = {0xF5BE2EE1, 0xBFD7, 0x11D0, [0xB1, 0x88, 0x00, 0xAA, 0x00, 0x38, 0xC9, 0x69]};\nconst IID IID_IMLangString = {0xC04D65CE, 0xB70D, 0x11D0, [0xB1, 0x88, 0x00, 0xAA, 0x00, 0x38, 0xC9, 0x69]};\nconst IID IID_IMLangStringAStr = {0xC04D65D2, 0xB70D, 0x11D0, [0xB1, 0x88, 0x00, 0xAA, 0x00, 0x38, 0xC9, 0x69]};\nconst IID IID_IMLangStringBufA = {0xD24ACD23, 0xBA72, 0x11D0, [0xB1, 0x88, 0x00, 0xAA, 0x00, 0x38, 0xC9, 0x69]};\nconst IID IID_IMLangStringBufW = {0xD24ACD21, 0xBA72, 0x11D0, [0xB1, 0x88, 0x00, 0xAA, 0x00, 0x38, 0xC9, 0x69]};\nconst IID IID_IMLangStringWStr = {0xC04D65D0, 0xB70D, 0x11D0, [0xB1, 0x88, 0x00, 0xAA, 0x00, 0x38, 0xC9, 0x69]};\nconst IID IID_IMofCompiler = {0x6DAF974E, 0x2E37, 0x11D2, [0xAE, 0xC9, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID IID_IMoniker = {0x0000000F, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IMonikerProp = {0xA5CA5F7F, 0x1847, 0x4D87, [0x9C, 0x5B, 0x91, 0x85, 0x09, 0xF7, 0x51, 0x1D]};\nconst IID IID_IMountedVolume = {0x12518492, 0x00B2, 0x11D2, [0x9F, 0xA5, 0x9E, 0x34, 0x20, 0x52, 0x41, 0x53]};\nconst IID IID_IMulticastControl = {0x410FA507, 0x4DC6, 0x415A, [0x90, 0x14, 0x63, 0x38, 0x75, 0xD5, 0x40, 0x6E]};\nconst IID IID_IMultiLanguage = {0x275C23E1, 0x3747, 0x11D0, [0x9F, 0xEA, 0x00, 0xAA, 0x00, 0x3F, 0x86, 0x46]};\nconst IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11D2, [0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A]};\nconst IID IID_IMultiLanguage3 = {0x4E5868AB, 0xB157, 0x4623, [0x9A, 0xCC, 0x6A, 0x1D, 0x9C, 0xAE, 0xBE, 0x04]};\nconst IID IID_IMultiplePropertyAccess = {0xEC81FEDE, 0xD432, 0x11CE, [0x92, 0x44, 0x00, 0x20, 0xAF, 0x6E, 0x72, 0xDB]};\nconst IID IID_IMultipleResults = {0x0C733A90, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IMultiQI = {0x00000020, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_INamedPropertyBag = {0xFB700430, 0x952C, 0x11D1, [0x94, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]};\nconst IID IID_INATEventManager = {0x624BD588, 0x9060, 0x4109, [0xB0, 0xB0, 0x1A, 0xDB, 0xBC, 0xAC, 0x32, 0xDF]};\nconst IID IID_INATExternalIPAddressCallback = {0x9C416740, 0xA34E, 0x446F, [0xBA, 0x06, 0xAB, 0xD0, 0x4C, 0x31, 0x49, 0xAE]};\nconst IID IID_INATNumberOfEntriesCallback = {0xC83A0A74, 0x91EE, 0x41B6, [0xB6, 0x7A, 0x67, 0xE0, 0xF0, 0x0B, 0xBD, 0x78]};\nconst IID IID_INetCfg = {0xC0E8AE93, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgBindingInterface = {0xC0E8AE94, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgBindingPath = {0xC0E8AE96, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgClass = {0xC0E8AE97, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgClassSetup = {0xC0E8AE9D, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgComponent = {0xC0E8AE99, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgComponentBindings = {0xC0E8AE9E, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgComponentControl = {0x932238DF, 0xBEA1, 0x11D0, [0x92, 0x98, 0x00, 0xC0, 0x4F, 0xC9, 0x9D, 0xCF]};\nconst IID IID_INetCfgComponentNotifyBinding = {0x932238E1, 0xBEA1, 0x11D0, [0x92, 0x98, 0x00, 0xC0, 0x4F, 0xC9, 0x9D, 0xCF]};\nconst IID IID_INetCfgComponentNotifyGlobal = {0x932238E2, 0xBEA1, 0x11D0, [0x92, 0x98, 0x00, 0xC0, 0x4F, 0xC9, 0x9D, 0xCF]};\nconst IID IID_INetCfgComponentPrivate = {0x98133273, 0x4B20, 0x11D1, [0xAB, 0x01, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgComponentPropertyUi = {0x932238E0, 0xBEA1, 0x11D0, [0x92, 0x98, 0x00, 0xC0, 0x4F, 0xC9, 0x9D, 0xCF]};\nconst IID IID_INetCfgComponentSetup = {0x932238E3, 0xBEA1, 0x11D0, [0x92, 0x98, 0x00, 0xC0, 0x4F, 0xC9, 0x9D, 0xCF]};\nconst IID IID_INetCfgComponentSysPrep = {0xC0E8AE9A, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgComponentUpperEdge = {0x932238E4, 0xBEA1, 0x11D0, [0x92, 0x98, 0x00, 0xC0, 0x4F, 0xC9, 0x9D, 0xCF]};\nconst IID IID_INetCfgInternalSetup = {0x98133276, 0x4B20, 0x11D1, [0xAB, 0x01, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgLock = {0xC0E8AE9F, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgPnpReconfigCallback = {0x8D84BD35, 0xE227, 0x11D2, [0xB7, 0x00, 0x00, 0xA0, 0xC9, 0x8A, 0x6A, 0x85]};\nconst IID IID_INetCfgSpecialCase = {0xC0E8AE95, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCfgSysPrep = {0xC0E8AE98, 0x306E, 0x11D1, [0xAA, 0xCF, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnection = {0xC08956A1, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnection2 = {0xFAEDCF6A, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionBrandingInfo = {0xFAEDCF5B, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionCMUtil = {0xFAEDCF60, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionCommonUi = {0xC08956A5, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionConnectUi = {0xC08956A3, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionHNetUtil = {0xFAEDCF64, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionManager = {0xC08956A2, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionManager2 = {0xFAEDCF69, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionManagerDebug = {0xFAEDCF5D, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionManagerEvents = {0xC08956BA, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionNotifySink = {0xFAEDCF5C, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionPropertyUi = {0xC08956A4, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionPropertyUi2 = {0xC08956B9, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionProps = {0xF4277C95, 0xCE5B, 0x463D, [0x81, 0x67, 0x56, 0x62, 0xD9, 0xBC, 0xAA, 0x72]};\nconst IID IID_INetConnectionRefresh = {0xFAEDCF5F, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionSysTray = {0xFAEDCF65, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionUiLock = {0xFAEDCF50, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionUiUtilities = {0xFAEDCF5E, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionWizardUi = {0xFAEDCF51, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetConnectionWizardUiContext = {0xFAEDCF52, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetCrawler = {0x49C929EE, 0xA1B7, 0x4C58, [0xB5, 0x39, 0xE6, 0x3B, 0xE3, 0x92, 0xB6, 0xF3]};\nconst IID IID_INetDefaultConnection = {0xFAEDCF66, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetInboundConnection = {0xFAEDCF53, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetInstallQueue = {0x98133274, 0x4B20, 0x11D1, [0xAB, 0x01, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetLanConnection = {0xFAEDCF54, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetLanConnectionUiInfo = {0xC08956A6, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetLanConnectionWizardUi = {0xFAEDCF56, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetMachinePolicies = {0xFAEDCF68, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetRasConnection = {0xFAEDCF57, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetRasConnectionIpUiInfo = {0xFAEDCF58, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetSharedAccessConnection = {0xFAEDCF55, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetSharingConfiguration = {0xC08956B6, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetSharingEveryConnectionCollect = {0x33C4643C, 0x7811, 0x46FA, [0xA8, 0x9A, 0x76, 0x85, 0x97, 0xBD, 0x72, 0x23]};\nconst IID IID_INetSharingManager = {0xC08956B7, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetSharingPortMapping = {0xC08956B1, 0x1CD3, 0x11D1, [0xB1, 0xC5, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_INetSharingPortMappingCollection = {0x02E4A2DE, 0xDA20, 0x4E34, [0x89, 0xC8, 0xAC, 0x22, 0x27, 0x5A, 0x01, 0x0B]};\nconst IID IID_INetSharingPortMappingProps = {0x24B7E9B5, 0xE38F, 0x4685, [0x85, 0x1B, 0x00, 0x89, 0x2C, 0xF5, 0xF9, 0x40]};\nconst IID IID_INetSharingPrivateConnectionColle = {0x38AE69E0, 0x4409, 0x402A, [0xA2, 0xCB, 0xE9, 0x65, 0xC7, 0x27, 0xF8, 0x40]};\nconst IID IID_INetSharingPublicConnectionCollec = {0x7D7A6355, 0xF372, 0x4971, [0xA1, 0x49, 0xBF, 0xC9, 0x27, 0xBE, 0x76, 0x2A]};\nconst IID IID_INewShortcutHookA = {0x000214E1, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_INewShortcutHookW = {0x000214F7, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_INewWDEvents = {0x0751C551, 0x7568, 0x41C9, [0x8E, 0x5B, 0xE2, 0x2E, 0x38, 0x91, 0x92, 0x36]};\nconst IID IID_INotification = {0xC733E4A3, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_INotificationHelper = {0xC733E4AB, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_INotificationManager = {0x95531501, 0x8782, 0x4845, [0x90, 0x1D, 0x31, 0x2F, 0x36, 0xBA, 0x6C, 0x6E]};\nconst IID IID_INotificationMgr = {0xC733E4A4, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_INotificationPing = {0xC733E4AC, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_INotificationProcessMgr0 = {0xC733E4AE, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_INotificationReport = {0xC733E4A7, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_INotificationRunning = {0xC733E4AD, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_INotificationSink = {0xC733E4A5, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_INotifyDBEvents = {0xDB526CC0, 0xD188, 0x11CD, [0xAD, 0x48, 0x00, 0xAA, 0x00, 0x3C, 0x9C, 0xB6]};\nconst IID IID_INotifyReplica = {0x99180163, 0xDA16, 0x101A, [0x93, 0x5C, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_INotifyUI = {0xE5E8D401, 0x1A37, 0x4FBF, [0x88, 0x0C, 0x82, 0x6C, 0xC8, 0x95, 0x16, 0xFD]};\nconst IID IID_IObjectAccessControl = {0x0C733AA3, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IObjectIdentity = {0xCA04B7E6, 0x0D21, 0x11D1, [0x8C, 0xC5, 0x00, 0xC0, 0x4F, 0xC2, 0xB0, 0x85]};\nconst IID IID_IObjectManager = {0xD51351DF, 0x6394, 0x4236, [0x97, 0x83, 0x65, 0xED, 0x05, 0x63, 0x10, 0x68]};\nconst IID IID_IObjectSafety = {0xCB5BDC81, 0x93C1, 0x11CF, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID IID_IObjectWithSite = {0xFC4801A3, 0x2BA9, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID IID_IObjMgr = {0x00BB2761, 0x6A77, 0x11D0, [0xA5, 0x35, 0x00, 0xC0, 0x4F, 0xD7, 0xD0, 0x62]};\nconst IID IID_IOInet = {0x79EAC9E0, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IOInetBindClient = {0x79EAC9E2, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IOInetBindInfo = {0x79EAC9E1, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IOInetCache = {0x79EAC9EA, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IOInetPriority = {0x79EAC9EB, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IOInetProtocol = {0x79EAC9E4, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IOInetProtocolInfo = {0x79EAC9EC, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IOInetProtocolRoot = {0x79EAC9E3, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IOInetProtocolSink = {0x79EAC9E5, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IOInetSession = {0x79EAC967, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IOInetThreadSwitch = {0x79EAC968, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IOldSyncMgrRegister = {0x894D8C55, 0xBDDF, 0x11D1, [0xB8, 0x5D, 0x00, 0xC0, 0x4F, 0xB9, 0x39, 0x81]};\nconst IID IID_IOldSyncMgrSynchronize = {0x6295DF28, 0x35EE, 0x11D1, [0x87, 0x07, 0x00, 0xC0, 0x4F, 0xD9, 0x33, 0x27]};\nconst IID IID_IOldSyncMgrSynchronizeCallback = {0x6295DF29, 0x35EE, 0x11D1, [0x87, 0x07, 0x00, 0xC0, 0x4F, 0xD9, 0x33, 0x27]};\nconst IID IID_IOleAdviseHolder = {0x00000111, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleCache = {0x0000011E, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleCache2 = {0x00000128, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleCacheControl = {0x00000129, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleClientSite = {0x00000118, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleCommandTarget = {0xB722BCCB, 0x4E68, 0x101B, [0xA2, 0xBC, 0x00, 0xAA, 0x00, 0x40, 0x47, 0x70]};\nconst IID IID_IOleContainer = {0x0000011B, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleControl = {0xB196B288, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IOleControlSite = {0xB196B289, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IOleDocument = {0xB722BCC5, 0x4E68, 0x101B, [0xA2, 0xBC, 0x00, 0xAA, 0x00, 0x40, 0x47, 0x70]};\nconst IID IID_IOleDocumentSite = {0xB722BCC7, 0x4E68, 0x101B, [0xA2, 0xBC, 0x00, 0xAA, 0x00, 0x40, 0x47, 0x70]};\nconst IID IID_IOleDocumentView = {0xB722BCC6, 0x4E68, 0x101B, [0xA2, 0xBC, 0x00, 0xAA, 0x00, 0x40, 0x47, 0x70]};\nconst IID IID_IOleInPlaceActiveObject = {0x00000117, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleInPlaceFrame = {0x00000116, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleInPlaceObject = {0x00000113, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleInPlaceObjectWindowless = {0x1C2056CC, 0x5EF4, 0x101B, [0x8B, 0xC8, 0x00, 0xAA, 0x00, 0x3E, 0x3B, 0x29]};\nconst IID IID_IOleInPlaceSite = {0x00000119, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleInPlaceSiteEx = {0x9C2CAD80, 0x3424, 0x11CF, [0xB6, 0x70, 0x00, 0xAA, 0x00, 0x4C, 0xD6, 0xD8]};\nconst IID IID_IOleInPlaceSiteWindowless = {0x922EADA0, 0x3424, 0x11CF, [0xB6, 0x70, 0x00, 0xAA, 0x00, 0x4C, 0xD6, 0xD8]};\nconst IID IID_IOleInPlaceUIWindow = {0x00000115, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleItemContainer = {0x0000011C, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleLink = {0x0000011D, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleManager = {0x0000011F, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleObject = {0x00000112, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleParentUndoUnit = {0xA1FAF330, 0xEF97, 0x11CE, [0x9B, 0xC9, 0x00, 0xAA, 0x00, 0x60, 0x8E, 0x01]};\nconst IID IID_IOlePresObj = {0x00000120, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOleUndoManager = {0xD001F200, 0xEF97, 0x11CE, [0x9B, 0xC9, 0x00, 0xAA, 0x00, 0x60, 0x8E, 0x01]};\nconst IID IID_IOleUndoUnit = {0x894AD3B0, 0xEF97, 0x11CE, [0x9B, 0xC9, 0x00, 0xAA, 0x00, 0x60, 0x8E, 0x01]};\nconst IID IID_IOleWindow = {0x00000114, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOmHistory = {0xFECEAAA2, 0x8405, 0x11CF, [0x8B, 0xA1, 0x00, 0xAA, 0x00, 0x47, 0x6D, 0xA6]};\nconst IID IID_IOmNavigator = {0xFECEAAA5, 0x8405, 0x11CF, [0x8B, 0xA1, 0x00, 0xAA, 0x00, 0x47, 0x6D, 0xA6]};\nconst IID IID_IOpaqueDataInfo = {0x000001A9, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IOpenRowset = {0x0C733A69, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IOplockStorage = {0x8D19C834, 0x8879, 0x11D1, [0x83, 0xE9, 0x00, 0xC0, 0x4F, 0xC2, 0xC6, 0xD4]};\nconst IID IID_IOpsProfileSimple = {0x7DD1362C, 0x28B6, 0x11D2, [0xBC, 0xA7, 0x00, 0xC0, 0x4F, 0xD9, 0x29, 0xDB]};\nconst IID IID_IOptionArray = {0x22B6D492, 0x0F88, 0x11D1, [0xBA, 0x19, 0x00, 0xC0, 0x4F, 0xD9, 0x12, 0xD0]};\nconst IID IID_IOverlappedCompletion = {0x521A28F0, 0xE40B, 0x11CE, [0xB2, 0xC9, 0x00, 0xAA, 0x00, 0x68, 0x09, 0x37]};\nconst IID IID_IOverlappedStream = {0x49384070, 0xE40A, 0x11CE, [0xB2, 0xC9, 0x00, 0xAA, 0x00, 0x68, 0x09, 0x37]};\nconst IID IID_IParentRowset = {0x0C733AAA, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IParseDisplayName = {0x0000011A, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IParser = {0x186442B0, 0x472E, 0x11D1, [0x89, 0x52, 0x00, 0xC0, 0x4F, 0xD6, 0x11, 0xD7]};\nconst IID IID_IParserSession = {0x186442B1, 0x472E, 0x11D1, [0x89, 0x52, 0x00, 0xC0, 0x4F, 0xD6, 0x11, 0xD7]};\nconst IID IID_IParserTreeProperties = {0x186442B2, 0x472E, 0x11D1, [0x89, 0x52, 0x00, 0xC0, 0x4F, 0xD6, 0x11, 0xD7]};\nconst IID IID_IParserVerify = {0x186442B3, 0x472E, 0x11D1, [0x89, 0x52, 0x00, 0xC0, 0x4F, 0xD6, 0x11, 0xD7]};\nconst IID IID_IPassportClientServices = {0xB30F7305, 0x5967, 0x45D1, [0xB7, 0xBC, 0xD6, 0xEB, 0x71, 0x63, 0xD7, 0x70]};\nconst IID IID_IPeerFactory = {0x6663F9D3, 0xB482, 0x11D1, [0x89, 0xC6, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4]};\nconst IID IID_IPendingProxyConnection = {0xB68E5043, 0x3E3D, 0x4CC2, [0xB9, 0xC1, 0x5F, 0x8F, 0x88, 0xFE, 0xE8, 0x1C]};\nconst IID IID_IPerPropertyBrowsing = {0x376BD3AA, 0x3845, 0x101B, [0x84, 0xED, 0x08, 0x00, 0x2B, 0x2E, 0xC7, 0x13]};\nconst IID IID_IPerPropertyBrowsing2 = {0x51973C54, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IPersist = {0x0000010C, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IPersistentDataChannel = {0xA180E934, 0xD92A, 0x415D, [0x91, 0x44, 0x75, 0x9F, 0x80, 0x54, 0xE8, 0xF6]};\nconst IID IID_IPersistFile = {0x0000010B, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IPersistFolder = {0x000214EA, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IPersistFolder2 = {0x1AC3D9F0, 0x175C, 0x11D1, [0x95, 0xBE, 0x00, 0x60, 0x97, 0x97, 0xEA, 0x4F]};\nconst IID IID_IPersistFolder3 = {0xCEF04FDF, 0xFE72, 0x11D2, [0x87, 0xA5, 0x00, 0xC0, 0x4F, 0x68, 0x37, 0xCF]};\nconst IID IID_IPersistHistory = {0x91A565C1, 0xE38F, 0x11D0, [0x94, 0xBF, 0x00, 0xA0, 0xC9, 0x05, 0x5C, 0xBF]};\nconst IID IID_IPersistIDList = {0x1079ACFC, 0x29BD, 0x11D3, [0x8E, 0x0D, 0x00, 0xC0, 0x4F, 0x68, 0x37, 0xD5]};\nconst IID IID_IPersistMemory = {0xBD1AE5E0, 0xA6AE, 0x11CE, [0xBD, 0x37, 0x50, 0x42, 0x00, 0xC1, 0x00, 0x00]};\nconst IID IID_IPersistMoniker = {0x79EAC9C9, 0xBAF9, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IPersistNetConnection = {0xFAEDCF59, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_IPersistPropertyBag = {0x37D84F60, 0x42CB, 0x11CE, [0x81, 0x35, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51]};\nconst IID IID_IPersistPropertyBag2 = {0x22F55881, 0x280B, 0x11D0, [0xA8, 0xA9, 0x00, 0xA0, 0xC9, 0x0C, 0x20, 0x04]};\nconst IID IID_IPersistQuery = {0x1A3114B8, 0xA62E, 0x11D0, [0xA6, 0xC5, 0x00, 0xA0, 0xC9, 0x06, 0xAF, 0x45]};\nconst IID IID_IPersistStorage = {0x0000010A, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IPersistStream = {0x00000109, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IPersistStreamInit = {0x7FD52380, 0x4E07, 0x101B, [0xAE, 0x2D, 0x08, 0x00, 0x2B, 0x2E, 0xC7, 0x13]};\nconst IID IID_IPhraseSink = {0xCC906FF0, 0xC058, 0x101A, [0xB5, 0x54, 0x08, 0x00, 0x2B, 0x33, 0xB0, 0xE6]};\nconst IID IID_IPicture = {0x7BF80980, 0xBF32, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID IID_IPictureDisp = {0x7BF80981, 0xBF32, 0x101A, [0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID IID_IPipeByte = {0xDB2F3ACA, 0x2F86, 0x11D1, [0x8E, 0x04, 0x00, 0xC0, 0x4F, 0xB9, 0x98, 0x9A]};\nconst IID IID_IPipeDouble = {0xDB2F3ACE, 0x2F86, 0x11D1, [0x8E, 0x04, 0x00, 0xC0, 0x4F, 0xB9, 0x98, 0x9A]};\nconst IID IID_IPipeLong = {0xDB2F3ACC, 0x2F86, 0x11D1, [0x8E, 0x04, 0x00, 0xC0, 0x4F, 0xB9, 0x98, 0x9A]};\nconst IID IID_IPointerInactive = {0x55980BA0, 0x35AA, 0x11CF, [0xB6, 0x71, 0x00, 0xAA, 0x00, 0x4C, 0xD6, 0xD8]};\nconst IID IID_IPrimaryControlChannel = {0x1A2E8B62, 0x9012, 0x4BE6, [0x84, 0xAE, 0x32, 0xBD, 0x66, 0xBA, 0x65, 0x7A]};\nconst IID IID_IPrint = {0xB722BCC9, 0x4E68, 0x101B, [0xA2, 0xBC, 0x00, 0xAA, 0x00, 0x40, 0x47, 0x70]};\nconst IID IID_IPrintDialogCallback = {0x5852A2C3, 0x6530, 0x11D1, [0xB6, 0xA3, 0x00, 0x00, 0xF8, 0x75, 0x7B, 0xF9]};\nconst IID IID_IPrintDialogServices = {0x509AAEDA, 0x5639, 0x11D1, [0xB6, 0xA1, 0x00, 0x00, 0xF8, 0x75, 0x7B, 0xF9]};\nconst IID IID_IPrivacyServices = {0x3050F84B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IPrivateDispatch = {0x86AB4BBE, 0x65F6, 0x11D1, [0x8C, 0x13, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IPrivateUnknown = {0x89126BAB, 0x6EAD, 0x11D1, [0x8C, 0x18, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0x03]};\nconst IID IID_IPrivSyncMgrSynchronizeInvoke = {0x6295DF2E, 0x35EE, 0x11D1, [0x87, 0x07, 0x00, 0xC0, 0x4F, 0xD9, 0x33, 0x27]};\nconst IID IID_IProcessDebugManager = {0x51973C2F, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IProcessDebugManager32 = {0x51973C2F, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IProcessDebugManager64 = {0x56B9FC1C, 0x63A9, 0x4CC1, [0xAC, 0x21, 0x08, 0x7D, 0x69, 0xA1, 0x7F, 0xAB]};\nconst IID IID_IProcessInitControl = {0x72380D55, 0x8D2B, 0x43A3, [0x85, 0x13, 0x2B, 0x6E, 0xF3, 0x14, 0x34, 0xE9]};\nconst IID IID_IProfferService = {0xCB728B20, 0xF786, 0x11CE, [0x92, 0xAD, 0x00, 0xAA, 0x00, 0xA7, 0x4C, 0xD0]};\nconst IID IID_IProgressDialog = {0xEBBC7C04, 0x315E, 0x11D2, [0xB6, 0x2F, 0x00, 0x60, 0x97, 0xDF, 0x5B, 0xD4]};\nconst IID IID_IProgressNotify = {0xA9D758A0, 0x4617, 0x11CF, [0x95, 0xFC, 0x00, 0xAA, 0x00, 0x68, 0x0D, 0xB4]};\nconst IID IID_IProgSink = {0x3050F371, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IPropertyBag = {0x55272A00, 0x42CB, 0x11CE, [0x81, 0x35, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51]};\nconst IID IID_IPropertyBag2 = {0x22F55882, 0x280B, 0x11D0, [0xA8, 0xA9, 0x00, 0xA0, 0xC9, 0x0C, 0x20, 0x04]};\nconst IID IID_IPropertyBagEx = {0x20011801, 0x5DE6, 0x11D1, [0x8E, 0x38, 0x00, 0xC0, 0x4F, 0xB9, 0x38, 0x6D]};\nconst IID IID_IPropertyFrame = {0xB196B28A, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IPropertyMap = {0xC733E4A2, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_IPropertyMapper = {0xB324B226, 0x41A0, 0x11D0, [0x8C, 0x91, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E]};\nconst IID IID_IPropertyNotifySink = {0x9BFBBC02, 0xEFF1, 0x101A, [0x84, 0xED, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IPropertyPage = {0xB196B28D, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IPropertyPage2 = {0x01E44665, 0x24AC, 0x101B, [0x84, 0xED, 0x08, 0x00, 0x2B, 0x2E, 0xC7, 0x13]};\nconst IID IID_IPropertyPageSite = {0xB196B28C, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IPropertySetContainer = {0xB4FFAE60, 0xA7CA, 0x11CD, [0xB5, 0x8B, 0x00, 0x00, 0x6B, 0x82, 0x91, 0x56]};\nconst IID IID_IPropertySetStorage = {0x0000013A, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IPropertyStorage = {0x00000138, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IPropertyUI = {0x757A7D9F, 0x919A, 0x4118, [0x99, 0xD7, 0xDB, 0xB2, 0x08, 0xC8, 0xCC, 0x66]};\nconst IID IID_IPropSheetPage = {0x000214F6, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IProvideClassInfo = {0xB196B283, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_IProvideClassInfo2 = {0xA6BC3AC0, 0xDBAA, 0x11CE, [0x9D, 0xE3, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51]};\nconst IID IID_IProvideExpressionContexts = {0x51973C41, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IProvideMoniker = {0x0C733A4D, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IProvideMultipleClassInfo = {0xA7ABA9C1, 0x8983, 0x11CF, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID IID_IProxy = {0x00000027, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IProxyManager = {0x00000008, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IPSFactory = {0x00000009, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IPSFactoryBuffer = {0xD5F569D0, 0x593B, 0x101A, [0xB5, 0x69, 0x08, 0x00, 0x2B, 0x2D, 0xBF, 0x7A]};\nconst IID IID_IPublishedApp = {0x1BC752E0, 0x9046, 0x11D1, [0xB8, 0xB3, 0x00, 0x60, 0x08, 0x05, 0x93, 0x82]};\nconst IID IID_IPublishingWizard = {0xAA9198BB, 0xCCEC, 0x472D, [0xBE, 0xED, 0x19, 0xA4, 0xF6, 0x73, 0x3F, 0x7A]};\nconst IID IID_IQualityControl = {0x6BC096AB, 0x0CE6, 0x11D1, [0xBA, 0xAE, 0x00, 0xC0, 0x4F, 0xC2, 0xE2, 0x0D]};\nconst IID IID_IQuery = {0x0C733A51, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IQueryAssociations = {0xC46CA590, 0x3C3F, 0x11D2, [0xBE, 0xE6, 0x00, 0x00, 0xF8, 0x05, 0xCA, 0x57]};\nconst IID IID_IQueryCancelAutoPlay = {0xDDEFE873, 0x6997, 0x4E68, [0xBE, 0x26, 0x39, 0xB6, 0x33, 0xAD, 0xBE, 0x12]};\nconst IID IID_IQueryContinue = {0x7307055C, 0xB24A, 0x486B, [0x9F, 0x25, 0x16, 0x3E, 0x59, 0x7A, 0x28, 0xA9]};\nconst IID IID_IQueryForm = {0x8CFCEE30, 0x39BD, 0x11D0, [0xB8, 0xD1, 0x00, 0xA0, 0x24, 0xAB, 0x2D, 0xBB]};\nconst IID IID_IQueryFrame = {0x7E8C7C20, 0x7C9D, 0x11D0, [0x91, 0x3F, 0x00, 0xAA, 0x00, 0xC1, 0x6E, 0x65]};\nconst IID IID_IQueryHandler = {0xA60CC73F, 0xE0FC, 0x11D0, [0x97, 0x50, 0x00, 0xA0, 0xC9, 0x06, 0xAF, 0x45]};\nconst IID IID_IQueryInfo = {0x00021500, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IQuickActivate = {0xCF51ED10, 0x62FE, 0x11CF, [0xBF, 0x86, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0x36]};\nconst IID IID_IRadioButton = {0x3050F69B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IRatingNotification = {0x639447BD, 0xB2D3, 0x44B9, [0x9F, 0xB0, 0x51, 0x0F, 0x23, 0xCB, 0x45, 0xE4]};\nconst IID IID_IReadData = {0x0C733A6A, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IReadEvents = {0xF64AEFDE, 0x3376, 0x11D1, [0xBE, 0x5B, 0x00, 0xC0, 0x4F, 0xC9, 0xE2, 0xBB]};\nconst IID IID_IRecalcEngine = {0x3050F496, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IRecalcHost = {0x3050F497, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IRecalcHostDebug = {0x3050F5F7, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IRecalcProperty = {0x3050F5D6, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IReconcilableObject = {0x99180162, 0xDA16, 0x101A, [0x93, 0x5C, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IReconcileInitiator = {0x99180161, 0xDA16, 0x101A, [0x93, 0x5C, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IRecordInfo = {0x0000002F, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IRedbookDiscMaster = {0xE3BC42CD, 0x4E5C, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID IID_IReferenceClock = {0x56A86897, 0x0AD4, 0x11CE, [0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70]};\nconst IID IID_IRegisterProvider = {0x0C733AB9, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRegisterVirusScanEngine = {0x0825E060, 0xB961, 0x11CF, [0xAA, 0xFA, 0x00, 0xAA, 0x00, 0xB6, 0x01, 0x5C]};\nconst IID IID_IReleaseMarshalBuffers = {0xEB0CB9E8, 0x7996, 0x11D2, [0x87, 0x2E, 0x00, 0x00, 0xF8, 0x08, 0x08, 0x59]};\nconst IID IID_IRemoteCallBack = {0x8947C648, 0x3833, 0x11D1, [0x86, 0x82, 0x00, 0xC0, 0x4F, 0xBF, 0xE1, 0x71]};\nconst IID IID_IRemoteComputer = {0x000214FE, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IRemoteDebugApplication = {0x51973C30, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IRemoteDebugApplicationEvents = {0x51973C33, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IRemoteDebugApplicationEx = {0x51973C01, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IRemoteDebugApplicationThread = {0x51973C37, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_IRemoteDebugApplicationThreadEx = {0xB9B32B0C, 0x9147, 0x11D1, [0x94, 0xEA, 0x00, 0xC0, 0x4F, 0xA3, 0x02, 0xA1]};\nconst IID IID_IRemoteDelaydC = {0x394540A0, 0x6FCF, 0x11D0, [0xAC, 0xE0, 0x00, 0x00, 0xF8, 0x01, 0x14, 0xD3]};\nconst IID IID_IRemoteESP = {0xE99A04AB, 0xAB95, 0x11D0, [0xBE, 0x96, 0x00, 0xA0, 0xC9, 0x49, 0x89, 0xDE]};\nconst IID IID_IRemoteFinder = {0x944AD532, 0xB09D, 0x11CE, [0xB5, 0x9C, 0x00, 0xAA, 0x00, 0x6C, 0xB3, 0x7D]};\nconst IID IID_IRemoteStats = {0x944AD531, 0xB09D, 0x11CE, [0xB5, 0x9C, 0x00, 0xAA, 0x00, 0x6C, 0xB3, 0x7D]};\nconst IID IID_IRequest = {0x6BC096A7, 0x0CE6, 0x11D1, [0xBA, 0xAE, 0x00, 0xC0, 0x4F, 0xC2, 0xE2, 0x0D]};\nconst IID IID_IRequestHandler = {0x6BC096AA, 0x0CE6, 0x11D1, [0xBA, 0xAE, 0x00, 0xC0, 0x4F, 0xC2, 0xE2, 0x0D]};\nconst IID IID_IRequestSource = {0x6BC096A9, 0x0CE6, 0x11D1, [0xBA, 0xAE, 0x00, 0xC0, 0x4F, 0xC2, 0xE2, 0x0D]};\nconst IID IID_IRequestState = {0x6BC096BA, 0x0CE6, 0x11D1, [0xBA, 0xAE, 0x00, 0xC0, 0x4F, 0xC2, 0xE2, 0x0D]};\nconst IID IID_IResolveShellLink = {0x5CD52983, 0x9449, 0x11D2, [0x96, 0x3A, 0x00, 0xC0, 0x4F, 0x79, 0xAD, 0xF0]};\nconst IID IID_IRichEditOle = {0x00020D00, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IRichEditOleCallback = {0x00020D03, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IRootStorage = {0x00000012, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IROTData = {0xF29F6BC0, 0x5021, 0x11CE, [0xAA, 0x15, 0x00, 0x00, 0x69, 0x01, 0x29, 0x3F]};\nconst IID IID_IRow = {0x0C733AB4, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowChange = {0x0C733AB5, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowInfo = {0x0C733AC1, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowPosition = {0x0C733A94, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowPositionChange = {0x0997A571, 0x126E, 0x11D0, [0x9F, 0x8A, 0x00, 0xA0, 0xC9, 0xA0, 0x63, 0x1E]};\nconst IID IID_IRowSchemaChange = {0x0C733AAE, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowset = {0x0C733A7C, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetAsynch = {0x0C733A0F, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetBookmark = {0x0C733AC2, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetChange = {0x0C733A05, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetChapterMember = {0x0C733AA8, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetCopyRows = {0x0C733A6B, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetCurrentIndex = {0x0C733ABD, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetExactScroll = {0x0C733A7F, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetFind = {0x0C733A9D, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetIdentity = {0x0C733A09, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetIndex = {0x0C733A82, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetInfo = {0x0C733A55, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetKeys = {0x0C733A12, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetLocate = {0x0C733A7D, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetNewRowAfter = {0x0C733A71, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetNextRowset = {0x0C733A72, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetNotify = {0x0C733A83, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetQueryStatus = {0xA7AC77ED, 0xF8D7, 0x11CE, [0xA7, 0x98, 0x00, 0x20, 0xF8, 0x00, 0x80, 0x24]};\nconst IID IID_IRowsetRefresh = {0x0C733AA9, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetResynch = {0x0C733A84, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetScroll = {0x0C733A7E, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetUpdate = {0x0C733A6D, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetView = {0x0C733A99, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetWatchAll = {0x0C733A73, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetWatchNotify = {0x0C733A44, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetWatchRegion = {0x0C733A45, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRowsetWithParameters = {0x0C733A6E, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IRpcChannel = {0x00000004, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IRpcChannelBuffer = {0xD5F56B60, 0x593B, 0x101A, [0xB5, 0x69, 0x08, 0x00, 0x2B, 0x2D, 0xBF, 0x7A]};\nconst IID IID_IRpcChannelBuffer2 = {0x594F31D0, 0x7F19, 0x11D0, [0xB1, 0x94, 0x00, 0xA0, 0xC9, 0x0D, 0xC8, 0xBF]};\nconst IID IID_IRpcChannelBuffer3 = {0x25B15600, 0x0115, 0x11D0, [0xBF, 0x0D, 0x00, 0xAA, 0x00, 0xB8, 0xDF, 0xD2]};\nconst IID IID_IRpcHelper = {0x00000149, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IRpcOptions = {0x00000144, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IRpcProxy = {0x00000007, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IRpcProxyBuffer = {0xD5F56A34, 0x593B, 0x101A, [0xB5, 0x69, 0x08, 0x00, 0x2B, 0x2D, 0xBF, 0x7A]};\nconst IID IID_IRpcStub = {0x00000005, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IRpcStubBuffer = {0xD5F56AFC, 0x593B, 0x101A, [0xB5, 0x69, 0x08, 0x00, 0x2B, 0x2D, 0xBF, 0x7A]};\nconst IID IID_IRpcSyntaxNegotiate = {0x58A08519, 0x24C8, 0x4935, [0xB4, 0x82, 0x3F, 0xD8, 0x23, 0x33, 0x3A, 0x4F]};\nconst IID IID_IRTC = {0x4811EA40, 0xB582, 0x11CE, [0xB5, 0xAF, 0x00, 0xAA, 0x00, 0x6C, 0xB3, 0x7D]};\nconst IID IID_IRTCBuddy = {0xFCB136C8, 0x7B90, 0x4E0C, [0xBE, 0xFE, 0x56, 0xED, 0xF0, 0xBA, 0x6F, 0x1C]};\nconst IID IID_IRTCBuddyEvent = {0xF36D755D, 0x17E6, 0x404E, [0x95, 0x4F, 0x0F, 0xC0, 0x75, 0x74, 0xC7, 0x8D]};\nconst IID IID_IRTCClient = {0x07829E45, 0x9A34, 0x408E, [0xA0, 0x11, 0xBD, 0xDF, 0x13, 0x48, 0x7C, 0xD1]};\nconst IID IID_IRTCClientEvent = {0x2B493B7A, 0x3CBA, 0x4170, [0x9C, 0x8B, 0x76, 0xA9, 0xDA, 0xCD, 0xD6, 0x44]};\nconst IID IID_IRTCClientPresence = {0x11C3CBCC, 0x0744, 0x42D1, [0x96, 0x8A, 0x51, 0xAA, 0x1B, 0xB2, 0x74, 0xC6]};\nconst IID IID_IRTCClientProvisioning = {0xB9F5CF06, 0x65B9, 0x4A80, [0xA0, 0xE6, 0x73, 0xCA, 0xE3, 0xEF, 0x38, 0x22]};\nconst IID IID_IRTCCollection = {0xEC7C8096, 0xB918, 0x4044, [0x94, 0xF1, 0xE4, 0xFB, 0xA0, 0x36, 0x1D, 0x5C]};\nconst IID IID_IRTCEnumBuddies = {0xF7296917, 0x5569, 0x4B3B, [0xB3, 0xAF, 0x98, 0xD1, 0x14, 0x4B, 0x2B, 0x87]};\nconst IID IID_IRTCEnumParticipants = {0xFCD56F29, 0x4A4F, 0x41B2, [0xBA, 0x5C, 0xF5, 0xBC, 0xCC, 0x06, 0x0B, 0xF6]};\nconst IID IID_IRTCEnumProfiles = {0x29B7C41C, 0xED82, 0x4BCA, [0x84, 0xAD, 0x39, 0xD5, 0x10, 0x1B, 0x58, 0xE3]};\nconst IID IID_IRTCEnumWatchers = {0xA87D55D7, 0xDB74, 0x4ED1, [0x9C, 0xA4, 0x77, 0xA0, 0xE4, 0x1B, 0x41, 0x3E]};\nconst IID IID_IRTCEventNotification = {0x13FA24C7, 0x5748, 0x4B21, [0x91, 0xF5, 0x73, 0x97, 0x60, 0x9C, 0xE7, 0x47]};\nconst IID IID_IRTCIntensityEvent = {0x4C23BF51, 0x390C, 0x4992, [0xA4, 0x1D, 0x41, 0xEE, 0xC0, 0x5B, 0x2A, 0x4B]};\nconst IID IID_IRTCMediaEvent = {0x099944FB, 0xBCDA, 0x453E, [0x8C, 0x41, 0xE1, 0x3D, 0xA2, 0xAD, 0xF7, 0xF3]};\nconst IID IID_IRTCMessagingEvent = {0xD3609541, 0x1B29, 0x4DE5, [0xA4, 0xAD, 0x5A, 0xEB, 0xAF, 0x31, 0x95, 0x12]};\nconst IID IID_IRTCParticipant = {0xAE86ADD5, 0x26B1, 0x4414, [0xAF, 0x1D, 0xB9, 0x4C, 0xD9, 0x38, 0xD7, 0x39]};\nconst IID IID_IRTCParticipantStateChangeEvent = {0x09BCB597, 0xF0FA, 0x48F9, [0xB4, 0x20, 0x46, 0x8C, 0xEA, 0x7F, 0xDE, 0x04]};\nconst IID IID_IRTCPresenceContact = {0x8B22F92C, 0xCD90, 0x42DB, [0xA7, 0x33, 0x21, 0x22, 0x05, 0xC3, 0xE3, 0xDF]};\nconst IID IID_IRTCProfile = {0xD07ECA9E, 0x4062, 0x4DD4, [0x9E, 0x7D, 0x72, 0x2A, 0x49, 0xBA, 0x73, 0x03]};\nconst IID IID_IRTCProfileEvent = {0xD6D5AB3B, 0x770E, 0x43E8, [0x80, 0x0A, 0x79, 0xB0, 0x62, 0x39, 0x5F, 0xCA]};\nconst IID IID_IRTCRegistrationStateChangeEvent = {0x62D0991B, 0x50AB, 0x4F02, [0xB9, 0x48, 0xCA, 0x94, 0xF2, 0x6F, 0x8F, 0x95]};\nconst IID IID_IRTCSession = {0x387C8086, 0x99BE, 0x42FB, [0x99, 0x73, 0x7C, 0x0F, 0xC0, 0xCA, 0x9F, 0xA8]};\nconst IID IID_IRTCSessionOperationCompleteEven = {0xA6BFF4C0, 0xF7C8, 0x4D3C, [0x9A, 0x41, 0x35, 0x50, 0xF7, 0x8A, 0x95, 0xB0]};\nconst IID IID_IRTCSessionStateChangeEvent = {0xB5BAD703, 0x5952, 0x48B3, [0x93, 0x21, 0x7F, 0x45, 0x00, 0x52, 0x15, 0x06]};\nconst IID IID_IRTCWatcher = {0xC7CEDAD8, 0x346B, 0x4D1B, [0xAC, 0x02, 0xA2, 0x08, 0x8D, 0xF9, 0xBE, 0x4F]};\nconst IID IID_IRTCWatcherEvent = {0xF30D7261, 0x587A, 0x424F, [0x82, 0x2C, 0x31, 0x27, 0x88, 0xF4, 0x35, 0x48]};\nconst IID IID_IRunnableObject = {0x00000126, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IRunnableTask = {0x85788D00, 0x6807, 0x11D0, [0xB8, 0x10, 0x00, 0xC0, 0x4F, 0xD7, 0x06, 0xEC]};\nconst IID IID_IRunningObjectTable = {0x00000010, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IScheduleGroup = {0xC733E4A6, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID IID_IScopedOperations = {0x0C733AB0, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IScriptEntry = {0x0AEE2A95, 0xBCBB, 0x11D0, [0x8C, 0x72, 0x00, 0xC0, 0x4F, 0xC2, 0xB0, 0x85]};\nconst IID IID_IScriptErrorList = {0xF3470F24, 0x15FD, 0x11D2, [0xBB, 0x2E, 0x00, 0x80, 0x5F, 0xF7, 0xEF, 0xCA]};\nconst IID IID_IScriptNode = {0x0AEE2A94, 0xBCBB, 0x11D0, [0x8C, 0x72, 0x00, 0xC0, 0x4F, 0xC2, 0xB0, 0x85]};\nconst IID IID_IScriptScriptlet = {0x0AEE2A96, 0xBCBB, 0x11D0, [0x8C, 0x72, 0x00, 0xC0, 0x4F, 0xC2, 0xB0, 0x85]};\nconst IID IID_IScrollBar = {0x3050F689, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ISdo = {0x56BC53DE, 0x96DB, 0x11D1, [0xBF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]};\nconst IID IID_ISdoCollection = {0x56BC53E2, 0x96DB, 0x11D1, [0xBF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]};\nconst IID IID_ISdoDictionaryOld = {0xD432E5F4, 0x53D8, 0x11D2, [0x9A, 0x3A, 0x00, 0xC0, 0x4F, 0xB9, 0x98, 0xAC]};\nconst IID IID_ISdoMachine = {0x479F6E75, 0x49A2, 0x11D2, [0x8E, 0xCA, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x19]};\nconst IID IID_ISdoServiceControl = {0x479F6E74, 0x49A2, 0x11D2, [0x8E, 0xCA, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x19]};\nconst IID IID_ISearch = {0xBA9239A4, 0x3DD5, 0x11D2, [0xBF, 0x8B, 0x00, 0xC0, 0x4F, 0xB9, 0x36, 0x61]};\nconst IID IID_ISearchAssistantOC = {0x72423E8F, 0x8011, 0x11D2, [0xBE, 0x79, 0x00, 0xA0, 0xC9, 0xA8, 0x3D, 0xA1]};\nconst IID IID_ISearchAssistantOC2 = {0x72423E8F, 0x8011, 0x11D2, [0xBE, 0x79, 0x00, 0xA0, 0xC9, 0xA8, 0x3D, 0xA2]};\nconst IID IID_ISearchAssistantOC3 = {0x72423E8F, 0x8011, 0x11D2, [0xBE, 0x79, 0x00, 0xA0, 0xC9, 0xA8, 0x3D, 0xA3]};\nconst IID IID_ISearchCommandExt = {0x1D2EFD50, 0x75CE, 0x11D1, [0xB7, 0x5A, 0x00, 0xA0, 0xC9, 0x05, 0x64, 0xFE]};\nconst IID IID_ISearchContext = {0x09F656A2, 0x41AF, 0x480C, [0x88, 0xF7, 0x16, 0xCC, 0x0D, 0x16, 0x46, 0x15]};\nconst IID IID_ISearches = {0x47C922A2, 0x3DD5, 0x11D2, [0xBF, 0x8B, 0x00, 0xC0, 0x4F, 0xB9, 0x36, 0x61]};\nconst IID IID_ISearchQueryHits = {0xED8CE7E0, 0x106C, 0x11CE, [0x84, 0xE2, 0x00, 0xAA, 0x00, 0x4B, 0x99, 0x86]};\nconst IID IID_ISecondaryControlChannel = {0xA23F9D10, 0x714C, 0x41FE, [0x84, 0x71, 0xFF, 0xB1, 0x9B, 0xC2, 0x84, 0x54]};\nconst IID IID_ISecureUrlHost = {0xC81984C4, 0x74C8, 0x11D2, [0xBA, 0xA9, 0x00, 0xC0, 0x4F, 0xC2, 0x04, 0x0E]};\nconst IID IID_ISecurityInfo = {0x0C733AA4, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ISegment = {0x3050F683, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ISegmentList = {0x3050F605, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ISegmentListIterator = {0x3050F692, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ISelectionObject2 = {0x3050F7FC, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ISelectionServices = {0x3050F684, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ISelectionServicesListener = {0x3050F699, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ISensLogon = {0xD597BAB3, 0x5B9F, 0x11D1, [0x8D, 0xD2, 0x00, 0xAA, 0x00, 0x4A, 0xBD, 0x5E]};\nconst IID IID_ISensLogon2 = {0xD597BAB4, 0x5B9F, 0x11D1, [0x8D, 0xD2, 0x00, 0xAA, 0x00, 0x4A, 0xBD, 0x5E]};\nconst IID IID_ISensNetwork = {0xD597BAB1, 0x5B9F, 0x11D1, [0x8D, 0xD2, 0x00, 0xAA, 0x00, 0x4A, 0xBD, 0x5E]};\nconst IID IID_ISensOnNow = {0xD597BAB2, 0x5B9F, 0x11D1, [0x8D, 0xD2, 0x00, 0xAA, 0x00, 0x4A, 0xBD, 0x5E]};\nconst IID IID_ISequenceNumber = {0x3050F6C1, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ISequentialStream = {0x0C733A30, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IServerSecurity = {0x0000013E, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IServiceProvider = {0x6D5140C1, 0x7436, 0x11CE, [0x80, 0x34, 0x00, 0xAA, 0x00, 0x60, 0x09, 0xFA]};\nconst IID IID_ISessionProperties = {0x0C733A85, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ISetNextStatement = {0x51973C03, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_ISharedAccessBeacon = {0xFAEDCF6B, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_ISharedAccessBeaconFinder = {0xFAEDCF67, 0x31FE, 0x11D1, [0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_IShellApp = {0xA3E14960, 0x935F, 0x11D1, [0xB8, 0xB8, 0x00, 0x60, 0x08, 0x05, 0x93, 0x82]};\nconst IID IID_IShellBrowser = {0x000214E2, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellChangeNotify = {0xD82BE2B1, 0x5764, 0x11D0, [0xA9, 0x6E, 0x00, 0xC0, 0x4F, 0xD7, 0x05, 0xA2]};\nconst IID IID_IShellCopyHookA = {0x000214EF, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellCopyHookW = {0x000214FC, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellDetails = {0x000214EC, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellDetails3 = {0xD2A105C0, 0x87D5, 0x11D1, [0x83, 0x91, 0x00, 0x00, 0xF8, 0x04, 0x61, 0xCF]};\nconst IID IID_IShellDispatch = {0xD8F015C0, 0xC278, 0x11CE, [0xA4, 0x9E, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IShellDispatch2 = {0xA4C6892C, 0x3BA9, 0x11D2, [0x9D, 0xEA, 0x00, 0xC0, 0x4F, 0xB1, 0x61, 0x62]};\nconst IID IID_IShellDispatch3 = {0x177160CA, 0xBB5A, 0x411C, [0x84, 0x1D, 0xBD, 0x38, 0xFA, 0xCD, 0xEA, 0xA0]};\nconst IID IID_IShellDispatch4 = {0xEFD84B2D, 0x4BCF, 0x4298, [0xBE, 0x25, 0xEB, 0x54, 0x2A, 0x59, 0xFB, 0xDA]};\nconst IID IID_IShellExecuteHookA = {0x000214F5, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellExecuteHookW = {0x000214FB, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellExtInit = {0x000214E8, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellFavoritesNameSpace = {0x55136804, 0xB2DE, 0x11D1, [0xB9, 0xF2, 0x00, 0xA0, 0xC9, 0x8B, 0xC5, 0x47]};\nconst IID IID_IShellFolder = {0x000214E6, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellFolder2 = {0x93F2F68C, 0x1D1B, 0x11D3, [0xA3, 0x0E, 0x00, 0xC0, 0x4F, 0x79, 0xAB, 0xD1]};\nconst IID IID_IShellFolderViewCB = {0x2047E320, 0xF2A9, 0x11CE, [0xAE, 0x65, 0x08, 0x00, 0x2B, 0x2E, 0x12, 0x62]};\nconst IID IID_IShellFolderViewDual = {0xE7A1AF80, 0x4D96, 0x11CF, [0x96, 0x0C, 0x00, 0x80, 0xC7, 0xF4, 0xEE, 0x85]};\nconst IID IID_IShellFolderViewDual2 = {0x31C147B6, 0x0ADE, 0x4A3C, [0xB5, 0x14, 0xDD, 0xF9, 0x32, 0xEF, 0x6D, 0x17]};\nconst IID IID_IShellIcon = {0x000214E5, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellIconOverlay = {0x7D688A70, 0xC613, 0x11D0, [0x99, 0x9B, 0x00, 0xC0, 0x4F, 0xD6, 0x55, 0xE1]};\nconst IID IID_IShellIconOverlayIdentifier = {0x0C6C4200, 0xC589, 0x11D0, [0x99, 0x9A, 0x00, 0xC0, 0x4F, 0xD6, 0x55, 0xE1]};\nconst IID IID_IShellImageData = {0xBFDEEC12, 0x8040, 0x4403, [0xA5, 0xEA, 0x9E, 0x07, 0xDA, 0xFC, 0xF5, 0x30]};\nconst IID IID_IShellImageDataAbort = {0x53FB8E58, 0x50C0, 0x4003, [0xB4, 0xAA, 0x0C, 0x8D, 0xF2, 0x8E, 0x7F, 0x3A]};\nconst IID IID_IShellImageDataFactory = {0x9BE8ED5C, 0xEDAB, 0x4D75, [0x90, 0xF3, 0xBD, 0x5B, 0xDB, 0xB2, 0x1C, 0x82]};\nconst IID IID_IShellLinkA = {0x000214EE, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellLinkDataList = {0x45E2B4AE, 0xB1C3, 0x11D0, [0xB9, 0x2F, 0x00, 0xA0, 0xC9, 0x03, 0x12, 0xE1]};\nconst IID IID_IShellLinkDual = {0x88A05C00, 0xF000, 0x11CE, [0x83, 0x50, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00]};\nconst IID IID_IShellLinkDual2 = {0x317EE249, 0xF12E, 0x11D2, [0xB1, 0xE4, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x3E]};\nconst IID IID_IShellLinkW = {0x000214F9, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellNameSpace = {0xE572D3C9, 0x37BE, 0x4AE2, [0x82, 0x5D, 0xD5, 0x21, 0x76, 0x3E, 0x31, 0x08]};\nconst IID IID_IShellPropSheetExt = {0x000214E9, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellUIHelper = {0x729FE2F8, 0x1EA8, 0x11D1, [0x8F, 0x85, 0x00, 0xC0, 0x4F, 0xC2, 0xFB, 0xE1]};\nconst IID IID_IShellView = {0x000214E3, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IShellView2 = {0x88E39E80, 0x3578, 0x11CF, [0xAE, 0x69, 0x08, 0x00, 0x2B, 0x2E, 0x12, 0x62]};\nconst IID IID_IShellWindows = {0x85CB6900, 0x4D95, 0x11CF, [0x96, 0x0C, 0x00, 0x80, 0xC7, 0xF4, 0xEE, 0x85]};\nconst IID IID_ISimpleCommandCreator = {0x5E341AB7, 0x02D0, 0x11D1, [0x90, 0x0C, 0x00, 0xA0, 0xC9, 0x06, 0x37, 0x96]};\nconst IID IID_ISimpleConnectionPoint = {0x51973C3E, 0xCB0C, 0x11D0, [0xB5, 0xC9, 0x00, 0xA0, 0x24, 0x4A, 0x0E, 0x7A]};\nconst IID IID_ISimpleFrameSite = {0x742B0E01, 0x14E6, 0x101B, [0x91, 0x4E, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB]};\nconst IID IID_ISliderBar = {0x3050F68D, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ISniffStream = {0x4EF17940, 0x30E0, 0x11D0, [0xB7, 0x24, 0x00, 0xAA, 0x00, 0x6C, 0x1A, 0x01]};\nconst IID IID_ISOAPRequest = {0xAD194525, 0x6E01, 0x4BCA, [0x92, 0x9C, 0x23, 0xC7, 0x38, 0x33, 0x36, 0xAF]};\nconst IID IID_ISoftDistExt = {0xB15B8DC1, 0xC7E1, 0x11D0, [0x86, 0x80, 0x00, 0xAA, 0x00, 0xBD, 0xCB, 0x71]};\nconst IID IID_ISourcesRowset = {0x0C733A1E, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ISpecialSystemProperties = {0x000001B9, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ISpecifyPropertyPages = {0xB196B28B, 0xBAB4, 0x101A, [0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07]};\nconst IID IID_ISpinButton = {0x3050F68B, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ISQLErrorInfo = {0x0C733A74, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IStandardActivator = {0x000001B8, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IStandardInfo = {0xF1D9C1A5, 0x9589, 0x40DD, [0xB6, 0x3D, 0x9B, 0xB0, 0xB3, 0x8A, 0x10, 0x22]};\nconst IID IID_IStaticPortMapping = {0x6F10711F, 0x729B, 0x41E5, [0x93, 0xB8, 0xF2, 0x1D, 0x0F, 0x81, 0x8D, 0xF1]};\nconst IID IID_IStaticPortMappingCollection = {0xCD1F3E77, 0x66D6, 0x4664, [0x82, 0xC7, 0x36, 0xDB, 0xB6, 0x41, 0xD0, 0xF1]};\nconst IID IID_IStats = {0x944AD530, 0xB09D, 0x11CE, [0xB5, 0x9C, 0x00, 0xAA, 0x00, 0x6C, 0xB3, 0x7D]};\nconst IID IID_IStdMarshalInfo = {0x00000018, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IStemmer = {0xEFBAF140, 0x7F42, 0x11CE, [0xBE, 0x57, 0x00, 0xAA, 0x00, 0x51, 0xFE, 0x20]};\nconst IID IID_IStemSink = {0xFE77C330, 0x7F42, 0x11CE, [0xBE, 0x57, 0x00, 0xAA, 0x00, 0x51, 0xFE, 0x20]};\nconst IID IID_IStorage = {0x0000000B, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IStream = {0x0000000C, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IStub = {0x00000026, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IStubManager = {0x00000006, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ISubDivisionProvider = {0x3050F4D2, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ISubscriptionAgentControl = {0xA89E8FF0, 0x70F4, 0x11D1, [0xBC, 0x7F, 0x00, 0xC0, 0x4F, 0xD9, 0x29, 0xDB]};\nconst IID IID_ISubscriptionAgentEvents = {0xA89E8FF1, 0x70F4, 0x11D1, [0xBC, 0x7F, 0x00, 0xC0, 0x4F, 0xD9, 0x29, 0xDB]};\nconst IID IID_ISubscriptionAgentShellExt = {0x81B184BA, 0xB302, 0x11D1, [0x85, 0x52, 0x00, 0xC0, 0x4F, 0xA3, 0x5C, 0x89]};\nconst IID IID_ISubscriptionItem = {0xA97559F8, 0x6C4A, 0x11D1, [0xA1, 0xE8, 0x00, 0xC0, 0x4F, 0xC2, 0xFB, 0xE1]};\nconst IID IID_ISubscriptionMgr = {0x085FB2C0, 0x0DF8, 0x11D1, [0x8F, 0x4B, 0x00, 0xA0, 0xC9, 0x05, 0x41, 0x3F]};\nconst IID IID_ISubscriptionMgr2 = {0x614BC270, 0xAEDF, 0x11D1, [0xA1, 0xF9, 0x00, 0xC0, 0x4F, 0xC2, 0xFB, 0xE1]};\nconst IID IID_ISubscriptionMgrPriv = {0xD66B399E, 0xAF1D, 0x11D1, [0xA1, 0xF9, 0x00, 0xC0, 0x4F, 0xC2, 0xFB, 0xE1]};\nconst IID IID_ISubscriptionThrottler = {0x1E9B00E4, 0x9846, 0x11D1, [0xA1, 0xEE, 0x00, 0xC0, 0x4F, 0xC2, 0xFB, 0xE1]};\nconst IID IID_ISupportErrorInfo = {0xDF0B3D60, 0x548F, 0x101B, [0x8E, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19]};\nconst IID IID_ISurrogate = {0x00000022, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ISWbemDateTime = {0x5E97458A, 0xCF77, 0x11D3, [0xB3, 0x8F, 0x00, 0x10, 0x5A, 0x1F, 0x47, 0x3A]};\nconst IID IID_ISWbemEventSource = {0x27D54D92, 0x0EBE, 0x11D2, [0x8B, 0x22, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemLastError = {0xD962DB84, 0xD4BB, 0x11D1, [0x8B, 0x09, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemLocator = {0x76A6415B, 0xCB41, 0x11D1, [0x8B, 0x02, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemMethod = {0x422E8E90, 0xD955, 0x11D1, [0x8B, 0x09, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemMethodSet = {0xC93BA292, 0xD955, 0x11D1, [0x8B, 0x09, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemNamedValue = {0x76A64164, 0xCB41, 0x11D1, [0x8B, 0x02, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemNamedValueSet = {0xCF2376EA, 0xCE8C, 0x11D1, [0x8B, 0x05, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemObject = {0x76A6415A, 0xCB41, 0x11D1, [0x8B, 0x02, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemObjectEx = {0x269AD56A, 0x8A67, 0x4129, [0xBC, 0x8C, 0x05, 0x06, 0xDC, 0xFE, 0x98, 0x80]};\nconst IID IID_ISWbemObjectPath = {0x5791BC27, 0xCE9C, 0x11D1, [0x97, 0xBF, 0x00, 0x00, 0xF8, 0x1E, 0x84, 0x9C]};\nconst IID IID_ISWbemObjectSet = {0x76A6415F, 0xCB41, 0x11D1, [0x8B, 0x02, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemPrivilege = {0x26EE67BD, 0x5804, 0x11D2, [0x8B, 0x4A, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemPrivilegeSet = {0x26EE67BF, 0x5804, 0x11D2, [0x8B, 0x4A, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemProperty = {0x1A388F98, 0xD4BA, 0x11D1, [0x8B, 0x09, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemPropertySet = {0xDEA0A7B2, 0xD4BA, 0x11D1, [0x8B, 0x09, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemQualifier = {0x79B05932, 0xD3B7, 0x11D1, [0x8B, 0x06, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemQualifierSet = {0x9B16ED16, 0xD3DF, 0x11D1, [0x8B, 0x08, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemRefreshableItem = {0x5AD4BF92, 0xDAAB, 0x11D3, [0xB3, 0x8F, 0x00, 0x10, 0x5A, 0x1F, 0x47, 0x3A]};\nconst IID IID_ISWbemRefresher = {0x14D8250E, 0xD9C2, 0x11D3, [0xB3, 0x8F, 0x00, 0x10, 0x5A, 0x1F, 0x47, 0x3A]};\nconst IID IID_ISWbemSecurity = {0xB54D66E6, 0x2287, 0x11D2, [0x8B, 0x33, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemServices = {0x76A6415C, 0xCB41, 0x11D1, [0x8B, 0x02, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID IID_ISWbemServicesEx = {0xD2F68443, 0x85DC, 0x427E, [0x91, 0xD8, 0x36, 0x65, 0x54, 0xCC, 0x75, 0x4C]};\nconst IID IID_ISWbemSink = {0x75718C9F, 0xF029, 0x11D1, [0xA1, 0xAC, 0x00, 0xC0, 0x4F, 0xB6, 0xC2, 0x23]};\nconst IID IID_ISynchronize = {0x00000030, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ISynchronizeContainer = {0x00000033, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ISynchronizedCallBack = {0x74C26041, 0x70D1, 0x11D1, [0xB7, 0x5A, 0x00, 0xA0, 0xC9, 0x05, 0x64, 0xFE]};\nconst IID IID_ISynchronizeEvent = {0x00000032, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ISynchronizeHandle = {0x00000031, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ISynchronizeMutex = {0x00000025, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ISyncMgrEnumItems = {0x6295DF2A, 0x35EE, 0x11D1, [0x87, 0x07, 0x00, 0xC0, 0x4F, 0xD9, 0x33, 0x27]};\nconst IID IID_ISyncMgrRegisterCSC = {0x47681A61, 0xBC74, 0x11D2, [0xB5, 0xC5, 0x00, 0xC0, 0x4F, 0xB9, 0x39, 0x81]};\nconst IID IID_ISyncMgrSynchronizeInvoke = {0x6295DF2C, 0x35EE, 0x11D1, [0x87, 0x07, 0x00, 0xC0, 0x4F, 0xD9, 0x33, 0x27]};\nconst IID IID_ISyncSchedule = {0xF0E15899, 0xA700, 0x11D1, [0x98, 0x31, 0x00, 0xC0, 0x4F, 0xD9, 0x10, 0xDD]};\nconst IID IID_ISyncScheduleMgr = {0xF0E15897, 0xA700, 0x11D1, [0x98, 0x31, 0x00, 0xC0, 0x4F, 0xD9, 0x10, 0xDD]};\nconst IID IID_ISyncSchedulep = {0xF0E1589B, 0xA700, 0x11D1, [0x98, 0x31, 0x00, 0xC0, 0x4F, 0xD9, 0x10, 0xDD]};\nconst IID IID_ITableCreation = {0x0C733ABC, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ITableDefinition = {0x0C733A86, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ITableDefinitionWithConstraints = {0x0C733AAB, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ITableRename = {0x0C733A77, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ITACDGroup = {0x5AFC3148, 0x4BCC, 0x11D1, [0xBF, 0x80, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITACDGroupEvent = {0x297F3032, 0xBD11, 0x11D1, [0xA0, 0xA7, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITAddress = {0xB1EFC386, 0x9355, 0x11D0, [0x83, 0x5C, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_ITAddress2 = {0xB0AE5D9B, 0xBE51, 0x46C9, [0xB0, 0xF7, 0xDF, 0xA8, 0xA2, 0x2A, 0x8B, 0xC4]};\nconst IID IID_ITAddressCapabilities = {0x8DF232F5, 0x821B, 0x11D1, [0xBB, 0x5C, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITAddressDeviceSpecificEvent = {0x3ACB216B, 0x40BD, 0x487A, [0x86, 0x72, 0x5C, 0xE7, 0x7B, 0xD7, 0xE3, 0xA3]};\nconst IID IID_ITAddressEvent = {0x831CE2D1, 0x83B5, 0x11D1, [0xBB, 0x5C, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITAddressTranslation = {0x0C4D8F03, 0x8DDB, 0x11D1, [0xA0, 0x9E, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITAddressTranslationInfo = {0xAFC15945, 0x8D40, 0x11D1, [0xA0, 0x9E, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITAgent = {0x5770ECE5, 0x4B27, 0x11D1, [0xBF, 0x80, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITAgentEvent = {0x5AFC314A, 0x4BCC, 0x11D1, [0xBF, 0x80, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITAgentHandler = {0x587E8C22, 0x9802, 0x11D1, [0xA0, 0xA4, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITAgentHandlerEvent = {0x297F3034, 0xBD11, 0x11D1, [0xA0, 0xA7, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITAgentSession = {0x5AFC3147, 0x4BCC, 0x11D1, [0xBF, 0x80, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITAgentSessionEvent = {0x5AFC314B, 0x4BCC, 0x11D1, [0xBF, 0x80, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITAllocatorProperties = {0xC1BC3C90, 0xBCFE, 0x11D1, [0x97, 0x45, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_ITAMMediaFormat = {0x0364EB00, 0x4A77, 0x11D1, [0xA6, 0x71, 0x00, 0x60, 0x97, 0xC9, 0xA2, 0xE8]};\nconst IID IID_ITargetContainer = {0x7847EC01, 0x2BEC, 0x11D0, [0x82, 0xB4, 0x00, 0xA0, 0xC9, 0x0C, 0x29, 0xC5]};\nconst IID IID_ITargetEmbedding = {0x548793C0, 0x9E74, 0x11CF, [0x96, 0x55, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0x23]};\nconst IID IID_ITargetFrame = {0xD5F78C80, 0x5252, 0x11CF, [0x90, 0xFA, 0x00, 0xAA, 0x00, 0x42, 0x10, 0x6E]};\nconst IID IID_ITargetFrame2 = {0x86D52E11, 0x94A8, 0x11D0, [0x82, 0xAF, 0x00, 0xC0, 0x4F, 0xD5, 0xAE, 0x38]};\nconst IID IID_ITargetFramePriv = {0x9216E421, 0x2BF5, 0x11D0, [0x82, 0xB4, 0x00, 0xA0, 0xC9, 0x0C, 0x29, 0xC5]};\nconst IID IID_ITargetNotify = {0x863A99A0, 0x21BC, 0x11D0, [0x82, 0xB4, 0x00, 0xA0, 0xC9, 0x0C, 0x29, 0xC5]};\nconst IID IID_ITargetNotify2 = {0x3050F6B1, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ITaskAnalyzeCluster = {0x795737A1, 0xE13A, 0x45EB, [0x8D, 0xFD, 0x81, 0x85, 0xC4, 0xB7, 0xAD, 0x4E]};\nconst IID IID_ITaskbarList = {0x56FDF342, 0xFD6D, 0x11D0, [0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90]};\nconst IID IID_ITaskbarList2 = {0x602D4995, 0xB13A, 0x429B, [0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17]};\nconst IID IID_ITaskCommitClusterChanges = {0x1BF12DDE, 0xF8B0, 0x49B1, [0xA4, 0x58, 0x67, 0x47, 0xDB, 0x78, 0x8A, 0x47]};\nconst IID IID_ITaskCompareAndPushInformation = {0xD4F1C2AF, 0xB370, 0x49DE, [0x87, 0x68, 0x40, 0x10, 0xB5, 0x68, 0x63, 0x6C]};\nconst IID IID_ITaskGatherClusterInfo = {0xE167965C, 0xC5D6, 0x493C, [0xA3, 0x43, 0x4C, 0x10, 0x5C, 0x01, 0xDD, 0xE7]};\nconst IID IID_ITaskGatherInformation = {0xB9AAF3F8, 0x238E, 0x4993, [0xBA, 0x31, 0x14, 0x85, 0x98, 0x04, 0xF9, 0x2C]};\nconst IID IID_ITaskGatherNodeInfo = {0xF19A2E01, 0x2CB3, 0x47B4, [0x8F, 0x5D, 0xB9, 0x77, 0x17, 0x6B, 0x45, 0xC8]};\nconst IID IID_ITaskGetDomains = {0xDFCB4ACD, 0xC4DB, 0x4DB4, [0x8E, 0xBB, 0x1D, 0xD0, 0x7A, 0x9D, 0x5B, 0x82]};\nconst IID IID_ITaskGetDomainsCallback = {0x85402E44, 0x6834, 0x41DF, [0x85, 0x90, 0x01, 0x82, 0x7D, 0x12, 0x4E, 0x1B]};\nconst IID IID_ITaskLoginDomain = {0x76AD8E51, 0x53C3, 0x4347, [0x89, 0x5D, 0x6C, 0x30, 0xF4, 0x13, 0x93, 0x74]};\nconst IID IID_ITaskLoginDomainCallback = {0xEFAF3C43, 0x7A8F, 0x469B, [0xB8, 0xBB, 0xC8, 0x0C, 0x57, 0x47, 0xCE, 0x05]};\nconst IID IID_ITaskManager = {0x16116694, 0xDFC5, 0x470B, [0xAC, 0x12, 0x46, 0xFB, 0xB0, 0x1C, 0xEF, 0x10]};\nconst IID IID_ITaskPollingCallback = {0x49E92395, 0x66AF, 0x4ADD, [0xA4, 0x1E, 0x43, 0x51, 0x2C, 0xB5, 0x19, 0xB3]};\nconst IID IID_ITaskVerifyIPAddress = {0x0C95E1B1, 0x0CFF, 0x4740, [0x8A, 0xBD, 0x69, 0x91, 0x2D, 0x10, 0x5B, 0xD1]};\nconst IID IID_ITASRTerminalEvent = {0xEE016A02, 0x4FA9, 0x467C, [0x93, 0x3F, 0x5A, 0x15, 0xB1, 0x23, 0x77, 0xD7]};\nconst IID IID_ITAttributeList = {0x5037FB82, 0xCAE9, 0x11D0, [0x8D, 0x58, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_ITAudioDeviceControl = {0x6C0AB6C5, 0x21E3, 0x11D3, [0xA5, 0x77, 0x00, 0xC0, 0x4F, 0x8E, 0xF6, 0xE3]};\nconst IID IID_ITAudioSettings = {0x6C0AB6C6, 0x21E3, 0x11D3, [0xA5, 0x77, 0x00, 0xC0, 0x4F, 0x8E, 0xF6, 0xE3]};\nconst IID IID_ITAutomatedPhoneControl = {0x1EE1AF0E, 0x6159, 0x4A61, [0xB7, 0x9B, 0x6A, 0x4B, 0xA3, 0xFC, 0x9D, 0xFC]};\nconst IID IID_ITBasicAudioTerminal = {0xB1EFC38D, 0x9355, 0x11D0, [0x83, 0x5C, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_ITBasicCallControl = {0xB1EFC389, 0x9355, 0x11D0, [0x83, 0x5C, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_ITBasicCallControl2 = {0x161A4A56, 0x1E99, 0x4B3F, [0xA4, 0x6A, 0x16, 0x8F, 0x38, 0xA5, 0xEE, 0x4C]};\nconst IID IID_ITCallHub = {0xA3C1544E, 0x5B92, 0x11D1, [0x8F, 0x4E, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITCallHubEvent = {0xA3C15451, 0x5B92, 0x11D1, [0x8F, 0x4E, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITCallInfo = {0x350F85D1, 0x1227, 0x11D3, [0x83, 0xD4, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITCallInfo2 = {0x94D70CA6, 0x7AB0, 0x4DAA, [0x81, 0xCA, 0xB8, 0xF8, 0x64, 0x3F, 0xAE, 0xC1]};\nconst IID IID_ITCallInfoChangeEvent = {0x5D4B65F9, 0xE51C, 0x11D1, [0xA0, 0x2F, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITCallingCard = {0x0C4D8F00, 0x8DDB, 0x11D1, [0xA0, 0x9E, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITCallMediaEvent = {0xFF36B87F, 0xEC3A, 0x11D0, [0x8E, 0xE4, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITCallNotificationEvent = {0x895801DF, 0x3DD6, 0x11D1, [0x8F, 0x30, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITCallQualityControl = {0xFE1D8AE0, 0xEDC4, 0x49B5, [0x8F, 0x8C, 0x4D, 0xE4, 0x0F, 0x9C, 0xDF, 0xAF]};\nconst IID IID_ITCallStateEvent = {0x62F47097, 0x95C9, 0x11D0, [0x83, 0x5D, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_ITCollection = {0x5EC5ACF2, 0x9C02, 0x11D0, [0x83, 0x62, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_ITCollection2 = {0xE6DDDDA5, 0xA6D3, 0x48FF, [0x87, 0x37, 0xD3, 0x2F, 0xC4, 0xD9, 0x54, 0x77]};\nconst IID IID_ITConferenceBlob = {0xC259D7AA, 0xC8AB, 0x11D0, [0x8D, 0x58, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_ITConnection = {0x8FA381D4, 0xC8C2, 0x11D0, [0x8D, 0x58, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_ITcpipProperties = {0x98133271, 0x4B20, 0x11D1, [0xAB, 0x01, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E]};\nconst IID IID_ITCustomTone = {0x357AD764, 0xB3C6, 0x4B2A, [0x8F, 0xA5, 0x07, 0x22, 0x82, 0x7A, 0x92, 0x54]};\nconst IID IID_ITDetectTone = {0x961F79BD, 0x3097, 0x49DF, [0xA1, 0xD6, 0x90, 0x9B, 0x77, 0xE8, 0x9C, 0xA0]};\nconst IID IID_ITDigitDetectionEvent = {0x80D3BFAC, 0x57D9, 0x11D2, [0xA0, 0x4A, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITDigitGenerationEvent = {0x80D3BFAD, 0x57D9, 0x11D2, [0xA0, 0x4A, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITDigitsGatheredEvent = {0xE52EC4C1, 0xCBA3, 0x441A, [0x9E, 0x6A, 0x93, 0xCB, 0x90, 0x9E, 0x97, 0x24]};\nconst IID IID_ITDirectory = {0x34621D6C, 0x6CFF, 0x11D1, [0xAF, 0xF7, 0x00, 0xC0, 0x4F, 0xC3, 0x1F, 0xEE]};\nconst IID IID_ITDirectoryObject = {0x34621D6E, 0x6CFF, 0x11D1, [0xAF, 0xF7, 0x00, 0xC0, 0x4F, 0xC3, 0x1F, 0xEE]};\nconst IID IID_ITDirectoryObjectConference = {0xF1029E5D, 0xCB5B, 0x11D0, [0x8D, 0x59, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_ITDirectoryObjectUser = {0x34621D6F, 0x6CFF, 0x11D1, [0xAF, 0xF7, 0x00, 0xC0, 0x4F, 0xC3, 0x1F, 0xEE]};\nconst IID IID_ITDispatchMapper = {0xE9225295, 0xC759, 0x11D1, [0xA0, 0x2B, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITemplatePrinter = {0x3050F6B4, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ITemplatePrinter2 = {0x3050F83F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ITFileTerminalEvent = {0xE4A7FBAC, 0x8C17, 0x4427, [0x9F, 0x55, 0x9F, 0x58, 0x9A, 0xC8, 0xAF, 0x00]};\nconst IID IID_ITFileTrack = {0x31CA6EA9, 0xC08A, 0x4BEA, [0x88, 0x11, 0x8E, 0x9C, 0x1B, 0xA3, 0xEA, 0x3A]};\nconst IID IID_ITfLangBarAddIn = {0xC9ADDAC3, 0x15CB, 0x4957, [0xB9, 0x3C, 0xDB, 0x08, 0x73, 0xFF, 0x98, 0xBB]};\nconst IID IID_ITFormatControl = {0x6C0AB6C1, 0x21E3, 0x11D3, [0xA5, 0x77, 0x00, 0xC0, 0x4F, 0x8E, 0xF6, 0xE3]};\nconst IID IID_ITForwardInformation = {0x449F659E, 0x88A3, 0x11D1, [0xBB, 0x5D, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITForwardInformation2 = {0x5229B4ED, 0xB260, 0x4382, [0x8E, 0x1A, 0x5D, 0xF3, 0xA8, 0xA4, 0xCC, 0xC0]};\nconst IID IID_ITfSpeechUIServer = {0x90E9A944, 0x9244, 0x489F, [0xA7, 0x8F, 0xDE, 0x67, 0xAF, 0xC0, 0x13, 0xA7]};\nconst IID IID_IThumbnailCapture = {0x4EA39266, 0x7211, 0x409F, [0xB6, 0x22, 0xF6, 0x3D, 0xBD, 0x16, 0xC5, 0x33]};\nconst IID IID_IThumbnailExtractor = {0x969DC708, 0x5C76, 0x11D1, [0x8D, 0x86, 0x00, 0x00, 0xF8, 0x04, 0xB0, 0x57]};\nconst IID IID_ITILSConfig = {0x34621D72, 0x6CFF, 0x11D1, [0xAF, 0xF7, 0x00, 0xC0, 0x4F, 0xC3, 0x1F, 0xEE]};\nconst IID IID_ITIMEActiveElementCollection = {0x403E2540, 0x4520, 0x11D3, [0x93, 0xAB, 0x00, 0xA0, 0xC9, 0x67, 0xA4, 0x38]};\nconst IID IID_ITimeAndNoticeControl = {0xBC0BF6AE, 0x8878, 0x11D1, [0x83, 0xE9, 0x00, 0xC0, 0x4F, 0xC2, 0xC6, 0xD4]};\nconst IID IID_ITIMEAnimationElement = {0xA74F14B1, 0xB6A2, 0x430A, [0xA5, 0xE8, 0x1F, 0x4E, 0x53, 0xF7, 0x10, 0xFE]};\nconst IID IID_ITIMEAnimationElement2 = {0x29CE8661, 0xBD43, 0x421A, [0xB6, 0x16, 0xE9, 0xB3, 0x1F, 0x33, 0xA5, 0x72]};\nconst IID IID_ITIMEBodyElement = {0x8C90E348, 0xEC0A, 0x4229, [0x90, 0xB0, 0xE5, 0x7D, 0x2C, 0xA4, 0x5C, 0xCB]};\nconst IID IID_ITIMEDMusicPlayerObject = {0x407954F5, 0x2BAB, 0x4CFA, [0x95, 0x4D, 0x24, 0x9F, 0x9F, 0xCE, 0x43, 0xA1]};\nconst IID IID_ITIMEDVDPlayerObject = {0x3AF7AB68, 0x4F29, 0x462C, [0xAA, 0x6E, 0x58, 0x72, 0x44, 0x88, 0x99, 0xE3]};\nconst IID IID_ITIMEElement = {0x1C2EF64E, 0xF07D, 0x4338, [0x97, 0x71, 0x91, 0x54, 0x49, 0x1C, 0xD8, 0xB9]};\nconst IID IID_ITIMEElementCollection = {0x50ABC224, 0x6D53, 0x4F83, [0x91, 0x35, 0x24, 0x40, 0xA4, 0x1B, 0x7B, 0xC8]};\nconst IID IID_ITIMEFactory = {0xCD51E446, 0x3006, 0x434F, [0x90, 0xE2, 0xE3, 0x7E, 0x8F, 0xB8, 0xCA, 0x8F]};\nconst IID IID_ITIMEMediaElement = {0x47A6972F, 0xAE65, 0x4A6B, [0xAE, 0x63, 0xD0, 0xC1, 0xD5, 0x30, 0x7B, 0x58]};\nconst IID IID_ITIMEMediaElement2 = {0x9EE29400, 0x7EE6, 0x453A, [0x85, 0xB3, 0x4E, 0xC2, 0x8E, 0x03, 0x05, 0xB4]};\nconst IID IID_ITIMEMediaPlayer = {0xEA4A95BE, 0xACC9, 0x4BF0, [0x85, 0xA4, 0x1B, 0xF3, 0xC5, 0x1E, 0x43, 0x1C]};\nconst IID IID_ITIMEMediaPlayerAudio = {0xFFAACFDA, 0xB374, 0x4F22, [0xAC, 0x9A, 0xC5, 0xBB, 0x94, 0x37, 0xCB, 0x56]};\nconst IID IID_ITIMEMediaPlayerControl = {0x897A99E7, 0xF386, 0x45C8, [0xB5, 0x1B, 0x3A, 0x25, 0xBB, 0xCB, 0xBA, 0x69]};\nconst IID IID_ITIMEMediaPlayerNetwork = {0xB9987FCA, 0x7FBB, 0x4015, [0xBD, 0x3D, 0x74, 0x18, 0x60, 0x55, 0x14, 0xDA]};\nconst IID IID_ITIMEMediaPlayerSite = {0xBF0571ED, 0x344F, 0x4F58, [0x82, 0xC7, 0x74, 0x31, 0xED, 0x0F, 0xD8, 0x34]};\nconst IID IID_ITIMEPlayItem = {0x2A6096D9, 0x2CE0, 0x47DC, [0xA8, 0x13, 0x90, 0x99, 0xA2, 0x46, 0x63, 0x09]};\nconst IID IID_ITIMEPlayItem2 = {0x4262CD38, 0x6BDC, 0x40A4, [0xBC, 0x50, 0x4C, 0xC5, 0x03, 0x66, 0xE7, 0x02]};\nconst IID IID_ITIMEPlayList = {0xE9B75B62, 0xDD97, 0x4B19, [0x8F, 0xD9, 0x96, 0x46, 0x29, 0x29, 0x52, 0xE0]};\nconst IID IID_ITimer = {0x3050F360, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ITimerService = {0x3050F35F, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ITimerSink = {0x3050F361, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ITIMEState = {0xDD5EC62A, 0x9D77, 0x4573, [0x80, 0xA8, 0x75, 0x85, 0x94, 0xE6, 0x9C, 0xEA]};\nconst IID IID_ITIMETransitionElement = {0xF383D66F, 0x5E68, 0x4FC2, [0xB6, 0x41, 0x03, 0x67, 0x2B, 0x54, 0x3A, 0x49]};\nconst IID IID_ITLegacyAddressMediaControl = {0xAB493640, 0x4C0B, 0x11D2, [0xA0, 0x46, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITLegacyAddressMediaControl2 = {0xB0EE512B, 0xA531, 0x409E, [0x9D, 0xD9, 0x40, 0x99, 0xFE, 0x86, 0xC7, 0x38]};\nconst IID IID_ITLegacyCallMediaControl = {0xD624582F, 0xCC23, 0x4436, [0xB8, 0xA5, 0x47, 0xC6, 0x25, 0xC8, 0x04, 0x5D]};\nconst IID IID_ITLegacyCallMediaControl2 = {0x57CA332D, 0x7BC2, 0x44F1, [0xA6, 0x0C, 0x93, 0x6F, 0xE8, 0xD7, 0xCE, 0x73]};\nconst IID IID_ITLegacyWaveSupport = {0x207823EA, 0xE252, 0x11D2, [0xB7, 0x7E, 0x00, 0x80, 0xC7, 0x13, 0x53, 0x81]};\nconst IID IID_ITLocalParticipant = {0x39CBF055, 0xF77A, 0x11D2, [0xA8, 0x24, 0x00, 0xC0, 0x4F, 0x8E, 0xF6, 0xE3]};\nconst IID IID_ITLocationInfo = {0x0C4D8EFF, 0x8DDB, 0x11D1, [0xA0, 0x9E, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITMedia = {0x0CC1F053, 0xCAEB, 0x11D0, [0x8D, 0x58, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_ITMediaCollection = {0x6A8E16A2, 0x0ABC, 0x11D1, [0x97, 0x6D, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_ITMediaControl = {0xC445DDE8, 0x5199, 0x4BC7, [0x98, 0x07, 0x5F, 0xFB, 0x92, 0xE4, 0x2E, 0x09]};\nconst IID IID_ITMediaPlayback = {0x627E8AE6, 0xAE4C, 0x4A69, [0xBB, 0x63, 0x2A, 0xD6, 0x25, 0x40, 0x4B, 0x77]};\nconst IID IID_ITMediaRecord = {0xF5DD4592, 0x5476, 0x4CC1, [0x9D, 0x4D, 0xFA, 0xD3, 0xEE, 0xFE, 0x7D, 0xB2]};\nconst IID IID_ITMediaSupport = {0xB1EFC384, 0x9355, 0x11D0, [0x83, 0x5C, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_ITMSPAddress = {0xEE3BD600, 0x3868, 0x11D2, [0xA0, 0x45, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITMultiTrackTerminal = {0xFE040091, 0xADE8, 0x4072, [0x95, 0xC9, 0xBF, 0x7D, 0xE8, 0xC5, 0x4B, 0x44]};\nconst IID IID_ITParticipant = {0x5899B820, 0x5A34, 0x11D2, [0x95, 0xA0, 0x00, 0xA0, 0x24, 0x4D, 0x22, 0x98]};\nconst IID IID_ITParticipantControl = {0xD2EE6684, 0x5A34, 0x11D2, [0x95, 0xA0, 0x00, 0xA0, 0x24, 0x4D, 0x22, 0x98]};\nconst IID IID_ITParticipantEvent = {0x8BB35070, 0x2DAD, 0x11D3, [0xA5, 0x80, 0x00, 0xC0, 0x4F, 0x8E, 0xF6, 0xE3]};\nconst IID IID_ITParticipantSubStreamControl = {0x2C679108, 0x5A35, 0x11D2, [0x95, 0xA0, 0x00, 0xA0, 0x24, 0x4D, 0x22, 0x98]};\nconst IID IID_ITPhone = {0x09D48DB4, 0x10CC, 0x4388, [0x9D, 0xE7, 0xA8, 0x46, 0x56, 0x18, 0x97, 0x5A]};\nconst IID IID_ITPhoneDeviceSpecificEvent = {0x63FFB2A6, 0x872B, 0x4CD3, [0xA5, 0x01, 0x32, 0x6E, 0x8F, 0xB4, 0x0A, 0xF7]};\nconst IID IID_ITPhoneEvent = {0x8F942DD8, 0x64ED, 0x4AAF, [0xA7, 0x7D, 0xB2, 0x3D, 0xB0, 0x83, 0x7E, 0xAD]};\nconst IID IID_ITPluggableTerminalClassInfo = {0x41757F4A, 0xCF09, 0x4B34, [0xBC, 0x96, 0x0A, 0x79, 0xD2, 0x39, 0x00, 0x76]};\nconst IID IID_ITPluggableTerminalClassRegistrat = {0x924A3723, 0xA00B, 0x4F5F, [0x9F, 0xEE, 0x8E, 0x9A, 0xEB, 0x9E, 0x82, 0xAA]};\nconst IID IID_ITPluggableTerminalEventSink = {0x6E0887BE, 0xBA1A, 0x492E, [0xBD, 0x10, 0x40, 0x20, 0xEC, 0x5E, 0x33, 0xE0]};\nconst IID IID_ITPluggableTerminalEventSinkRegis = {0xF7115709, 0xA216, 0x4957, [0xA7, 0x59, 0x06, 0x0A, 0xB3, 0x2A, 0x90, 0xD1]};\nconst IID IID_ITPluggableTerminalInitializatio = {0xAED6483C, 0x3304, 0x11D2, [0x86, 0xF1, 0x00, 0x60, 0x08, 0xB0, 0xE5, 0xD2]};\nconst IID IID_ITPluggableTerminalSuperclassInf = {0x6D54E42C, 0x4625, 0x4359, [0xA6, 0xF7, 0x63, 0x19, 0x99, 0x10, 0x7E, 0x05]};\nconst IID IID_ITPluggableTerminalSuperclassRegi = {0x60D3C08A, 0xC13E, 0x4195, [0x9A, 0xB0, 0x8D, 0xE7, 0x68, 0x09, 0x0F, 0x25]};\nconst IID IID_ITPrivateEvent = {0x0E269CD0, 0x10D4, 0x4121, [0x9C, 0x22, 0x9C, 0x85, 0xD6, 0x25, 0x65, 0x0D]};\nconst IID IID_ITQOSApplicationID = {0xE8C89D27, 0xA3BD, 0x47D5, [0xA6, 0xFC, 0xD2, 0xAE, 0x40, 0xCD, 0xBC, 0x6E]};\nconst IID IID_ITQOSEvent = {0xCFA3357C, 0xAD77, 0x11D1, [0xBB, 0x68, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITQueue = {0x5AFC3149, 0x4BCC, 0x11D1, [0xBF, 0x80, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITQueueEvent = {0x297F3033, 0xBD11, 0x11D1, [0xA0, 0xA7, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITrackFile = {0x8790C948, 0xA30B, 0x11D0, [0x8C, 0xAB, 0x00, 0xC0, 0x4F, 0xD9, 0x0F, 0x85]};\nconst IID IID_ITransaction = {0x0FB15084, 0xAF41, 0x11CE, [0xBD, 0x2B, 0x20, 0x4C, 0x4F, 0x4F, 0x50, 0x20]};\nconst IID IID_ITransaction2 = {0x34021548, 0x0065, 0x11D3, [0xBA, 0xC1, 0x00, 0xC0, 0x4F, 0x79, 0x7B, 0xE2]};\nconst IID IID_ITransactionCloner = {0x02656950, 0x2152, 0x11D0, [0x94, 0x4C, 0x00, 0xA0, 0xC9, 0x05, 0x41, 0x6E]};\nconst IID IID_ITransactionDispenser = {0x3A6AD9E1, 0x23B9, 0x11CF, [0xAD, 0x60, 0x00, 0xAA, 0x00, 0xA7, 0x4C, 0xCD]};\nconst IID IID_ITransactionJoin = {0x0C733A5E, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ITransactionLocal = {0x0C733A5F, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ITransactionObject = {0x0C733A60, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ITransactionOptions = {0x3A6AD9E0, 0x23B9, 0x11CF, [0xAD, 0x60, 0x00, 0xAA, 0x00, 0xA7, 0x4C, 0xCD]};\nconst IID IID_ITransactionOutcomeEvents = {0x3A6AD9E2, 0x23B9, 0x11CF, [0xAD, 0x60, 0x00, 0xAA, 0x00, 0xA7, 0x4C, 0xCD]};\nconst IID IID_ITransmt = {0xB3C9F150, 0xB593, 0x11CE, [0xB5, 0xB0, 0x00, 0xAA, 0x00, 0x6C, 0xB3, 0x7D]};\nconst IID IID_ITravelEntry = {0xF46EDB3B, 0xBC2F, 0x11D0, [0x94, 0x12, 0x00, 0xAA, 0x00, 0xA3, 0xEB, 0xD3]};\nconst IID IID_ITravelLog = {0x66A9CB08, 0x4802, 0x11D2, [0xA5, 0x61, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8]};\nconst IID IID_ITravelLogClient = {0x3050F67A, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ITravelLogClient2 = {0x0AD364CE, 0xADCB, 0x11D3, [0x82, 0x69, 0x00, 0x80, 0x5F, 0xC7, 0x32, 0xC0]};\nconst IID IID_ITravelLogEntry = {0x7EBFDD87, 0xAD18, 0x11D3, [0xA4, 0xC5, 0x00, 0xC0, 0x4F, 0x72, 0xD6, 0xB8]};\nconst IID IID_ITravelLogEx = {0x3050F679, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_ITravelLogStg = {0x7EBFDD80, 0xAD18, 0x11D3, [0xA4, 0xC5, 0x00, 0xC0, 0x4F, 0x72, 0xD6, 0xB8]};\nconst IID IID_ITRendezvous = {0x34621D6B, 0x6CFF, 0x11D1, [0xAF, 0xF7, 0x00, 0xC0, 0x4F, 0xC3, 0x1F, 0xEE]};\nconst IID IID_ITRequest = {0xAC48FFDF, 0xF8C4, 0x11D1, [0xA0, 0x30, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITRequestEvent = {0xAC48FFDE, 0xF8C4, 0x11D1, [0xA0, 0x30, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITridentEventSink = {0x1DC9CA50, 0x06EF, 0x11D2, [0x84, 0x15, 0x00, 0x60, 0x08, 0xC3, 0xFB, 0xFC]};\nconst IID IID_ITrkForceOwnership = {0xA2531F44, 0xC67D, 0x11D0, [0x8C, 0xB1, 0x00, 0xC0, 0x4F, 0xD9, 0x0F, 0x85]};\nconst IID IID_ITrkRestoreNotify = {0xD0056F6B, 0xE2A0, 0x11D0, [0xB1, 0xC2, 0x00, 0xC0, 0x4F, 0xB9, 0x38, 0x6D]};\nconst IID IID_ITrkRestoreParser = {0x755939E3, 0xE381, 0x11D0, [0xB1, 0xC5, 0x00, 0xC0, 0x4F, 0xB9, 0x38, 0x6D]};\nconst IID IID_ITrusteeAdmin = {0x0C733AA1, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ITrusteeGroupAdmin = {0x0C733AA2, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_ITScriptableAudioFormat = {0xB87658BD, 0x3C59, 0x4F64, [0xBE, 0x74, 0xAE, 0xDE, 0x3E, 0x86, 0xA8, 0x1E]};\nconst IID IID_ITSdp = {0x9B2719D8, 0xB696, 0x11D0, [0xA4, 0x89, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_ITStaticAudioTerminal = {0xA86B7871, 0xD14C, 0x48E6, [0x92, 0x2E, 0xA8, 0xD1, 0x5F, 0x98, 0x48, 0x00]};\nconst IID IID_ITStream = {0xEE3BD605, 0x3868, 0x11D2, [0xA0, 0x45, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITStreamControl = {0xEE3BD604, 0x3868, 0x11D2, [0xA0, 0x45, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITStreamQualityControl = {0x6C0AB6C2, 0x21E3, 0x11D3, [0xA5, 0x77, 0x00, 0xC0, 0x4F, 0x8E, 0xF6, 0xE3]};\nconst IID IID_ITSubStream = {0xEE3BD608, 0x3868, 0x11D2, [0xA0, 0x45, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITSubStreamControl = {0xEE3BD607, 0x3868, 0x11D2, [0xA0, 0x45, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITTAPI = {0xB1EFC382, 0x9355, 0x11D0, [0x83, 0x5C, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_ITTAPI2 = {0x54FBDC8C, 0xD90F, 0x4DAD, [0x96, 0x95, 0xB3, 0x73, 0x09, 0x7F, 0x09, 0x4B]};\nconst IID IID_ITTAPICallCenter = {0x5AFC3154, 0x4BCC, 0x11D1, [0xBF, 0x80, 0x00, 0x80, 0x5F, 0xC1, 0x47, 0xD3]};\nconst IID IID_ITTAPIEventNotification = {0xEDDB9426, 0x3B91, 0x11D1, [0x8F, 0x30, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITTAPIObjectEvent = {0xF4854D48, 0x937A, 0x11D1, [0xBB, 0x58, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID IID_ITTAPIObjectEvent2 = {0x359DDA6E, 0x68CE, 0x4383, [0xBF, 0x0B, 0x16, 0x91, 0x33, 0xC4, 0x1B, 0x46]};\nconst IID IID_ITTerminal = {0xB1EFC38A, 0x9355, 0x11D0, [0x83, 0x5C, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_ITTerminalControl = {0xAED6483B, 0x3304, 0x11D2, [0x86, 0xF1, 0x00, 0x60, 0x08, 0xB0, 0xE5, 0xD2]};\nconst IID IID_ITTerminalManager = {0x7170F2DE, 0x9BE3, 0x11D0, [0xA0, 0x09, 0x00, 0xAA, 0x00, 0xB6, 0x05, 0xA4]};\nconst IID IID_ITTerminalManager2 = {0xBB33DEC6, 0xB2C7, 0x46E6, [0x9E, 0xD1, 0x49, 0x8B, 0x91, 0xFA, 0x85, 0xAC]};\nconst IID IID_ITTerminalSupport = {0xB1EFC385, 0x9355, 0x11D0, [0x83, 0x5C, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID IID_ITTerminalSupport2 = {0xF3EB39BC, 0x1B1F, 0x4E99, [0xA0, 0xC0, 0x56, 0x30, 0x5C, 0x4D, 0xD5, 0x91]};\nconst IID IID_ITTime = {0x2652BB78, 0x1516, 0x11D1, [0x97, 0x71, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_ITTimeCollection = {0x0CC1F04F, 0xCAEB, 0x11D0, [0x8D, 0x58, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID IID_ITToneDetectionEvent = {0x407E0FAF, 0xD047, 0x4753, [0xB0, 0xC6, 0x8E, 0x06, 0x03, 0x73, 0xFE, 0xCD]};\nconst IID IID_ITToneTerminalEvent = {0xE6F56009, 0x611F, 0x4945, [0xBB, 0xD2, 0x2D, 0x0C, 0xE5, 0x61, 0x20, 0x56]};\nconst IID IID_ITTTSTerminalEvent = {0xD964788F, 0x95A5, 0x461D, [0xAB, 0x0C, 0xB9, 0x90, 0x0A, 0x6C, 0x27, 0x13]};\nconst IID IID_ITypeChangeEvents = {0x00020410, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ITypeComp = {0x00020403, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ITypeFactory = {0x0000002E, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ITypeInfo = {0x00020401, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ITypeInfo2 = {0x00020412, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ITypeLib = {0x00020402, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ITypeLib2 = {0x00020411, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_ITypeMarshal = {0x0000002D, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IUmiADSIPrivate = {0xCFCECB01, 0x3123, 0x4926, [0xB5, 0xE3, 0x62, 0x78, 0x08, 0x27, 0x26, 0x43]};\nconst IID IID_IUniformResourceLocatorA = {0xFBF23B80, 0xE3F0, 0x101B, [0x84, 0x88, 0x00, 0xAA, 0x00, 0x3E, 0x56, 0xF8]};\nconst IID IID_IUniformResourceLocatorW = {0xCABB0DA0, 0xDA57, 0x11CF, [0x99, 0x74, 0x00, 0x20, 0xAF, 0xD7, 0x97, 0x62]};\nconst IID IID_IUnknown = {0x00000000, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IUnsecuredApartment = {0x1CFABA8C, 0x1523, 0x11D1, [0xAD, 0x79, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID IID_IUPnPDescriptionDocument = {0x11D1C1B2, 0x7DAA, 0x4C9E, [0x95, 0x95, 0x7F, 0x82, 0xED, 0x20, 0x6D, 0x1E]};\nconst IID IID_IUPnPDescriptionDocumentCallback = {0x77394C69, 0x5486, 0x40D6, [0x9B, 0xC3, 0x49, 0x91, 0x98, 0x3E, 0x02, 0xDA]};\nconst IID IID_IUPnPDevice = {0x3D44D0D1, 0x98C9, 0x4889, [0xAC, 0xD1, 0xF9, 0xD6, 0x74, 0xBF, 0x22, 0x21]};\nconst IID IID_IUPnPDeviceControl = {0x204810BA, 0x73B2, 0x11D4, [0xBF, 0x42, 0x00, 0xB0, 0xD0, 0x11, 0x8B, 0x56]};\nconst IID IID_IUPnPDeviceDocumentAccess = {0xE7772804, 0x3287, 0x418E, [0x90, 0x72, 0xCF, 0x2B, 0x47, 0x23, 0x89, 0x81]};\nconst IID IID_IUPnPDeviceFinder = {0xADDA3D55, 0x6F72, 0x4319, [0xBF, 0xF9, 0x18, 0x60, 0x0A, 0x53, 0x9B, 0x10]};\nconst IID IID_IUPnPDeviceFinderAddCallbackWithI = {0x983DFC0B, 0x1796, 0x44DF, [0x89, 0x75, 0xCA, 0x54, 0x5B, 0x62, 0x0E, 0xE5]};\nconst IID IID_IUPnPDeviceFinderCallback = {0x415A984A, 0x88B3, 0x49F3, [0x92, 0xAF, 0x05, 0x08, 0xBE, 0xDF, 0x0D, 0x6C]};\nconst IID IID_IUPnPDeviceHostICSSupport = {0x3FFC5AE5, 0xA66B, 0x499C, [0xA1, 0x80, 0xC7, 0x39, 0x3D, 0xB6, 0xBA, 0x8D]};\nconst IID IID_IUPnPDeviceHostSetup = {0x6BD34909, 0x54E7, 0x4FBF, [0x85, 0x62, 0x7B, 0x89, 0x70, 0x9A, 0x58, 0x9A]};\nconst IID IID_IUPnPDeviceProvider = {0x204810B8, 0x73B2, 0x11D4, [0xBF, 0x42, 0x00, 0xB0, 0xD0, 0x11, 0x8B, 0x56]};\nconst IID IID_IUPnPDevices = {0xFDBC0C73, 0xBDA3, 0x4C66, [0xAC, 0x4F, 0xF2, 0xD9, 0x6F, 0xDA, 0xD6, 0x8C]};\nconst IID IID_IUPnPEventSink = {0x204810B4, 0x73B2, 0x11D4, [0xBF, 0x42, 0x00, 0xB0, 0xD0, 0x11, 0x8B, 0x56]};\nconst IID IID_IUPnPEventSource = {0x204810B5, 0x73B2, 0x11D4, [0xBF, 0x42, 0x00, 0xB0, 0xD0, 0x11, 0x8B, 0x56]};\nconst IID IID_IUPnPNAT = {0xB171C812, 0xCC76, 0x485A, [0x94, 0xD8, 0xB6, 0xB3, 0xA2, 0x79, 0x4E, 0x99]};\nconst IID IID_IUPnPPrivateCallbackHelper = {0x8DCC8327, 0xDBE9, 0x48E6, [0x84, 0x6C, 0x33, 0x72, 0x58, 0x65, 0xD5, 0x0C]};\nconst IID IID_IUPnPPrivateDocumentCallbackHelp = {0x19432A8E, 0x4A32, 0x4860, [0xB8, 0xFB, 0x95, 0xB1, 0x11, 0x7C, 0xD4, 0xE5]};\nconst IID IID_IUPnPPrivateServiceHelper2 = {0x340F4076, 0x6856, 0x48F9, [0xB3, 0xC4, 0x97, 0xB9, 0x1B, 0x68, 0xD7, 0x7E]};\nconst IID IID_IUPnPRegistrar = {0x204810B6, 0x73B2, 0x11D4, [0xBF, 0x42, 0x00, 0xB0, 0xD0, 0x11, 0x8B, 0x56]};\nconst IID IID_IUPnPReregistrar = {0x204810B7, 0x73B2, 0x11D4, [0xBF, 0x42, 0x00, 0xB0, 0xD0, 0x11, 0x8B, 0x56]};\nconst IID IID_IUPnPService = {0xA295019C, 0xDC65, 0x47DD, [0x90, 0xDC, 0x7F, 0xE9, 0x18, 0xA1, 0xAB, 0x44]};\nconst IID IID_IUPnPServiceCallback = {0x31FADCA9, 0xAB73, 0x464B, [0xB6, 0x7D, 0x5C, 0x1D, 0x0F, 0x83, 0xC8, 0xB8]};\nconst IID IID_IUPnPServiceCallbackPrivate = {0x24EA2515, 0xF612, 0x4528, [0xBA, 0x82, 0x7B, 0xD3, 0xDB, 0xBA, 0xD3, 0x03]};\nconst IID IID_IUPnPServices = {0x3F8C8E9E, 0x9A7A, 0x4DC8, [0xBC, 0x41, 0xFF, 0x31, 0xFA, 0x37, 0x49, 0x56]};\nconst IID IID_IUrlHistoryNotify = {0xBC40BEC1, 0xC493, 0x11D0, [0x83, 0x1B, 0x00, 0xC0, 0x4F, 0xD5, 0xAE, 0x38]};\nconst IID IID_IUrlHistoryStg = {0x3C374A41, 0xBAE4, 0x11CF, [0xBF, 0x7D, 0x00, 0xAA, 0x00, 0x69, 0x46, 0xEE]};\nconst IID IID_IUrlHistoryStg2 = {0xAFA0DC11, 0xC313, 0x11D0, [0x83, 0x1A, 0x00, 0xC0, 0x4F, 0xD5, 0xAE, 0x38]};\nconst IID IID_IUrlMon = {0x00000026, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IURLSearchHook = {0xAC60F6A0, 0x0FD9, 0x11D0, [0x99, 0xCB, 0x00, 0xC0, 0x4F, 0xD6, 0x44, 0x97]};\nconst IID IID_IURLSearchHook2 = {0x5EE44DA4, 0x6D32, 0x46E3, [0x86, 0xBC, 0x07, 0x54, 0x0D, 0xED, 0xD0, 0xE0]};\nconst IID IID_IUrlTrackingStg = {0xF2F8CBB3, 0xB040, 0x11D0, [0xBB, 0x16, 0x00, 0xC0, 0x4F, 0xB6, 0x6F, 0x63]};\nconst IID IID_IUserEventTimer = {0x0F504B94, 0x6E42, 0x42E6, [0x99, 0xE0, 0xE2, 0x0F, 0xAF, 0xE5, 0x2A, 0xB4]};\nconst IID IID_IUserEventTimerCallback = {0xE9EAD8E6, 0x2A25, 0x410E, [0x9B, 0x58, 0xA9, 0xFB, 0xEF, 0x1D, 0xD1, 0xA2]};\nconst IID IID_IUserNotification = {0xBA9711BA, 0x5893, 0x4787, [0xA7, 0xE1, 0x41, 0x27, 0x71, 0x51, 0x55, 0x0B]};\nconst IID IID_IUtilityButton = {0x3050F6AF, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID IID_IVariantChangeType = {0xA6EF9862, 0xC720, 0x11D0, [0x93, 0x37, 0x00, 0xA0, 0xC9, 0x0D, 0xCA, 0xA9]};\nconst IID IID_IVersionHost = {0x667115AC, 0xDC02, 0x11D1, [0xBA, 0x57, 0x00, 0xC0, 0x4F, 0xC2, 0x04, 0x0E]};\nconst IID IID_IVersionVector = {0x4EB01410, 0xDB1A, 0x11D1, [0xBA, 0x53, 0x00, 0xC0, 0x4F, 0xC2, 0x04, 0x0E]};\nconst IID IID_IViewChapter = {0x0C733A98, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IViewFilter = {0x0C733A9B, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IViewObject = {0x0000010D, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IViewObject2 = {0x00000127, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IViewObjectEx = {0x3AF24292, 0x0C96, 0x11CE, [0xA0, 0xCF, 0x00, 0xAA, 0x00, 0x60, 0x0A, 0xB8]};\nconst IID IID_IViewRowset = {0x0C733A97, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IViewSort = {0x0C733A9A, 0x2A1C, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID IID_IVirusScanEngine = {0x083DB180, 0xB4A8, 0x11CF, [0xAA, 0xFA, 0x00, 0xAA, 0x00, 0xB6, 0x01, 0x5C]};\nconst IID IID_IVirusScanner = {0x4589BEE0, 0xB4B1, 0x11CF, [0xAA, 0xFA, 0x00, 0xAA, 0x00, 0xB6, 0x01, 0x5C]};\nconst IID IID_IWaitMultiple = {0x0000002B, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IWbemAddressResolution = {0xF7CE2E12, 0x8C90, 0x11D1, [0x9E, 0x7B, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID IID_IWbemBackupRestore = {0xC49E32C7, 0xBC8B, 0x11D2, [0x85, 0xD4, 0x00, 0x10, 0x5A, 0x1F, 0x83, 0x04]};\nconst IID IID_IWbemBackupRestoreEx = {0xA359DEC5, 0xE813, 0x4834, [0x8A, 0x2A, 0xBA, 0x7F, 0x1D, 0x77, 0x7D, 0x76]};\nconst IID IID_IWbemCallResult = {0x44ACA675, 0xE8FC, 0x11D0, [0xA0, 0x7C, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID IID_IWbemCallStatus = {0x4212DC47, 0x142E, 0x4C6C, [0xBC, 0x49, 0x6C, 0xA2, 0x32, 0xDD, 0x09, 0x59]};\nconst IID IID_IWbemClassObject = {0xDC12A681, 0x737F, 0x11CF, [0x88, 0x4D, 0x00, 0xAA, 0x00, 0x4B, 0x2E, 0x24]};\nconst IID IID_IWbemClientConnectionTransport = {0xA889C72A, 0xFCC1, 0x4A9E, [0xAF, 0x61, 0xED, 0x07, 0x13, 0x33, 0xFB, 0x5B]};\nconst IID IID_IWbemClientTransport = {0xF7CE2E11, 0x8C90, 0x11D1, [0x9E, 0x7B, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID IID_IWbemConfigure = {0x9A368276, 0x26CF, 0x11D0, [0xAD, 0x3C, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID IID_IWbemConfigureRefresher = {0x49353C92, 0x516B, 0x11D1, [0xAE, 0xA6, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID IID_IWbemConnectorLogin = {0xD8EC9CB1, 0xB135, 0x4F10, [0x8B, 0x1B, 0xC7, 0x18, 0x8B, 0xB0, 0xD1, 0x86]};\nconst IID IID_IWbemConstructClassObject = {0x9EF76194, 0x70D5, 0x11D1, [0xAD, 0x90, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID IID_IWbemContext = {0x44ACA674, 0xE8FC, 0x11D0, [0xA0, 0x7C, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID IID_IWbemDecoupledBasicEventProvider = {0x86336D20, 0xCA11, 0x4786, [0x9E, 0xF1, 0xBC, 0x8A, 0x94, 0x6B, 0x42, 0xFC]};\nconst IID IID_IWbemDecoupledEventSink = {0xCD94EBF2, 0xE622, 0x11D2, [0x9C, 0xB3, 0x00, 0x10, 0x5A, 0x1F, 0x48, 0x01]};\nconst IID IID_IWbemDecoupledRegistrar = {0x1005CBCF, 0xE64F, 0x4646, [0xBC, 0xD3, 0x3A, 0x08, 0x9D, 0x8A, 0x84, 0xB4]};\nconst IID IID_IWbemEventConsumerProvider = {0xE246107A, 0xB06E, 0x11D0, [0xAD, 0x61, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID IID_IWbemEventConsumerProviderEx = {0x17CF534A, 0xD8A3, 0x4AD0, [0xAC, 0x92, 0x5E, 0x3D, 0x01, 0x71, 0x71, 0x51]};\nconst IID IID_IWbemEventProvider = {0xE245105B, 0xB06E, 0x11D0, [0xAD, 0x61, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID IID_IWbemEventProviderQuerySink = {0x580ACAF8, 0xFA1C, 0x11D0, [0xAD, 0x72, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID IID_IWbemEventProviderSecurity = {0x631F7D96, 0xD993, 0x11D2, [0xB3, 0x39, 0x00, 0x10, 0x5A, 0x1F, 0x4A, 0xAF]};\nconst IID IID_IWbemEventSink = {0x3AE0080A, 0x7E3A, 0x4366, [0xBF, 0x89, 0x0F, 0xEE, 0xDC, 0x93, 0x16, 0x59]};\nconst IID IID_IWbemHiPerfEnum = {0x2705C288, 0x79AE, 0x11D2, [0xB3, 0x48, 0x00, 0x10, 0x5A, 0x1F, 0x81, 0x77]};\nconst IID IID_IWbemHiPerfProvider = {0x49353C93, 0x516B, 0x11D1, [0xAE, 0xA6, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID IID_IWbemLevel1Login = {0xF309AD18, 0xD86A, 0x11D0, [0xA0, 0x75, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID IID_IWbemLocator = {0xDC12A687, 0x737F, 0x11CF, [0x88, 0x4D, 0x00, 0xAA, 0x00, 0x4B, 0x2E, 0x24]};\nconst IID IID_IWbemObjectAccess = {0x49353C9A, 0x516B, 0x11D1, [0xAE, 0xA6, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID IID_IWbemObjectSink = {0x7C857801, 0x7381, 0x11CF, [0x88, 0x4D, 0x00, 0xAA, 0x00, 0x4B, 0x2E, 0x24]};\nconst IID IID_IWbemObjectTextSrc = {0xBFBF883A, 0xCAD7, 0x11D3, [0xA1, 0x1B, 0x00, 0x10, 0x5A, 0x1F, 0x51, 0x5A]};\nconst IID IID_IWbemPath = {0x3BC15AF2, 0x736C, 0x477E, [0x9E, 0x51, 0x23, 0x8A, 0xF8, 0x66, 0x7D, 0xCC]};\nconst IID IID_IWbemPathKeyList = {0x9AE62877, 0x7544, 0x4BB0, [0xAA, 0x26, 0xA1, 0x38, 0x24, 0x65, 0x9E, 0xD6]};\nconst IID IID_IWbemPropertyProvider = {0xCE61E841, 0x65BC, 0x11D0, [0xB6, 0xBD, 0x00, 0xAA, 0x00, 0x32, 0x40, 0xC7]};\nconst IID IID_IWbemProviderIdentity = {0x631F7D97, 0xD993, 0x11D2, [0xB3, 0x39, 0x00, 0x10, 0x5A, 0x1F, 0x4A, 0xAF]};\nconst IID IID_IWbemProviderInit = {0x1BE41572, 0x91DD, 0x11D1, [0xAE, 0xB2, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID IID_IWbemProviderInitSink = {0x1BE41571, 0x91DD, 0x11D1, [0xAE, 0xB2, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID IID_IWbemQualifierSet = {0xDC12A680, 0x737F, 0x11CF, [0x88, 0x4D, 0x00, 0xAA, 0x00, 0x4B, 0x2E, 0x24]};\nconst IID IID_IWbemQuery = {0x81166F58, 0xDD98, 0x11D3, [0xA1, 0x20, 0x00, 0x10, 0x5A, 0x1F, 0x51, 0x5A]};\nconst IID IID_IWbemRawSdAccessor = {0xC1E2D759, 0xCABD, 0x11D3, [0xA1, 0x1B, 0x00, 0x10, 0x5A, 0x1F, 0x51, 0x5A]};\nconst IID IID_IWbemRefresher = {0x49353C99, 0x516B, 0x11D1, [0xAE, 0xA6, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID IID_IWbemServices = {0x9556DC99, 0x828C, 0x11CF, [0xA3, 0x7E, 0x00, 0xAA, 0x00, 0x32, 0x40, 0xC7]};\nconst IID IID_IWbemShutdown = {0xB7B31DF9, 0xD515, 0x11D3, [0xA1, 0x1C, 0x00, 0x10, 0x5A, 0x1F, 0x51, 0x5A]};\nconst IID IID_IWbemStatusCodeText = {0xEB87E1BC, 0x3233, 0x11D2, [0xAE, 0xC9, 0x00, 0xC0, 0x4F, 0xB6, 0x88, 0x20]};\nconst IID IID_IWbemTransport = {0x553FE584, 0x2156, 0x11D0, [0xB6, 0xAE, 0x00, 0xAA, 0x00, 0x32, 0x40, 0xC7]};\nconst IID IID_IWbemUnboundObjectSink = {0xE246107B, 0xB06E, 0x11D0, [0xAD, 0x61, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID IID_IWBScriptControl = {0xA5170870, 0x0CF8, 0x11D1, [0x8B, 0x91, 0x00, 0x80, 0xC7, 0x44, 0xF3, 0x89]};\nconst IID IID_IWCContextMenuCallback = {0x97DEDE64, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IWCPropertySheetCallback = {0x97DEDE60, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IWCWizard97Callback = {0x97DEDE67, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IWCWizardCallback = {0x97DEDE62, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IWebBridge = {0xAE24FDAD, 0x03C6, 0x11D1, [0x8B, 0x76, 0x00, 0x80, 0xC7, 0x44, 0xF3, 0x89]};\nconst IID IID_IWebBrowser = {0xEAB22AC1, 0x30C1, 0x11CF, [0xA7, 0xEB, 0x00, 0x00, 0xC0, 0x5B, 0xAE, 0x0B]};\nconst IID IID_IWebBrowser2 = {0xD30C1661, 0xCDAF, 0x11D0, [0x8A, 0x3E, 0x00, 0xC0, 0x4F, 0xC9, 0xE2, 0x6E]};\nconst IID IID_IWebBrowserApp = {0x0002DF05, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID IID_IWebWizardExtension = {0x0E6B3F66, 0x98D1, 0x48C0, [0xA2, 0x22, 0xFB, 0xDE, 0x74, 0xE2, 0xFB, 0xC5]};\nconst IID IID_IWebWizardHost = {0x18BCC359, 0x4990, 0x4BFB, [0xB9, 0x51, 0x3C, 0x83, 0x70, 0x2B, 0xE5, 0xF9]};\nconst IID IID_IWEExtendContextMenu = {0x97DEDE65, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IWEExtendPropertySheet = {0x97DEDE61, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IWEExtendWizard = {0x97DEDE63, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IWEExtendWizard97 = {0x97DEDE68, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_IWEInvokeCommand = {0x97DEDE66, 0xFC6B, 0x11CF, [0xB5, 0xF5, 0x00, 0xA0, 0xC9, 0x0A, 0xB5, 0x05]};\nconst IID IID_Iwfolders = {0xBAE31F98, 0x1B81, 0x11D2, [0xA9, 0x7A, 0x00, 0xC0, 0x4F, 0x8E, 0xCB, 0x02]};\nconst IID IID_IWindowForBindingUI = {0x79EAC9D5, 0xBAFA, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IWinInetHttpInfo = {0x79EAC9D8, 0xBAFA, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IWinInetInfo = {0x79EAC9D6, 0xBAFA, 0x11CE, [0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B]};\nconst IID IID_IWizardExtension = {0xC02EA696, 0x86CC, 0x491E, [0x9B, 0x23, 0x74, 0x39, 0x4A, 0x04, 0x44, 0xA8]};\nconst IID IID_IWizardSite = {0x88960F5B, 0x422F, 0x4E7B, [0x80, 0x13, 0x73, 0x41, 0x53, 0x81, 0xC3, 0xC3]};\nconst IID IID_IWMIExtension = {0xADC1F06E, 0x5C7E, 0x11D2, [0x8B, 0x74, 0x00, 0x10, 0x4B, 0x2A, 0xFB, 0x41]};\nconst IID IID_IWordBreaker = {0xD53552C8, 0x77E3, 0x101A, [0xB5, 0x52, 0x08, 0x00, 0x2B, 0x33, 0xB0, 0xE6]};\nconst IID IID_IWordSink = {0xCC907054, 0xC058, 0x101A, [0xB5, 0x54, 0x08, 0x00, 0x2B, 0x33, 0xB0, 0xE6]};\nconst IID IID_IWrappedProtocol = {0x53C84785, 0x8425, 0x4DC5, [0x97, 0x1B, 0xE5, 0x8D, 0x9C, 0x19, 0xF9, 0xB6]};\nconst IID IID_IXMLAttribute = {0xD4D4A0FC, 0x3B73, 0x11D1, [0xB2, 0xB4, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0x96]};\nconst IID IID_IXMLDocument = {0xF52E2B61, 0x18A1, 0x11D1, [0xB1, 0x05, 0x00, 0x80, 0x5F, 0x49, 0x91, 0x6B]};\nconst IID IID_IXMLDocument2 = {0x2B8DE2FE, 0x8D2D, 0x11D1, [0xB2, 0xFC, 0x00, 0xC0, 0x4F, 0xD9, 0x15, 0xA9]};\nconst IID IID_IXMLDOMAttribute = {0x2933BF85, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMCDATASection = {0x2933BF8A, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMCharacterData = {0x2933BF84, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMComment = {0x2933BF88, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMDocument = {0x2933BF81, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMDocumentFragment = {0x3EFAA413, 0x272F, 0x11D2, [0x83, 0x6F, 0x00, 0x00, 0xF8, 0x7A, 0x77, 0x82]};\nconst IID IID_IXMLDOMDocumentType = {0x2933BF8B, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMElement = {0x2933BF86, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMEntity = {0x2933BF8D, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMEntityReference = {0x2933BF8E, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMImplementation = {0x2933BF8F, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMNamedNodeMap = {0x2933BF83, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMNode = {0x2933BF80, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMNodeList = {0x2933BF82, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMNotation = {0x2933BF8C, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMParseError = {0x3EFAA426, 0x272F, 0x11D2, [0x83, 0x6F, 0x00, 0x00, 0xF8, 0x7A, 0x77, 0x82]};\nconst IID IID_IXMLDOMProcessingInstruction = {0x2933BF89, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDOMText = {0x2933BF87, 0x7B36, 0x11D2, [0xB2, 0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60]};\nconst IID IID_IXMLDSOControl = {0x310AFA62, 0x0575, 0x11D2, [0x9C, 0xA9, 0x00, 0x60, 0xB0, 0xEC, 0x3D, 0x39]};\nconst IID IID_IXMLElement = {0x3F7F31AC, 0xE15F, 0x11D0, [0x9C, 0x25, 0x00, 0xC0, 0x4F, 0xC9, 0x9C, 0x8E]};\nconst IID IID_IXMLElement2 = {0x2B8DE2FF, 0x8D2D, 0x11D1, [0xB2, 0xFC, 0x00, 0xC0, 0x4F, 0xD9, 0x15, 0xA9]};\nconst IID IID_IXMLElementCollection = {0x65725580, 0x9B5D, 0x11D0, [0x9B, 0xFE, 0x00, 0xC0, 0x4F, 0xC9, 0x9C, 0x8E]};\nconst IID IID_IXMLError = {0x948C5AD3, 0xC58D, 0x11D0, [0x9C, 0x0B, 0x00, 0xC0, 0x4F, 0xC9, 0x9C, 0x8E]};\nconst IID IID_IXMLGenericParse = {0xE4E23071, 0x4D07, 0x11D2, [0xAE, 0x76, 0x00, 0x80, 0xC7, 0x3B, 0xC1, 0x99]};\nconst IID IID_IXMLHttpRequest = {0xED8C108D, 0x4349, 0x11D2, [0x91, 0xA4, 0x00, 0xC0, 0x4F, 0x79, 0x69, 0xE8]};\nconst IID IID_IXMLNodeFactory = {0xD242361F, 0x51A0, 0x11D2, [0x9C, 0xAF, 0x00, 0x60, 0xB0, 0xEC, 0x3D, 0x39]};\nconst IID IID_IXMLNodeSource = {0xD242361D, 0x51A0, 0x11D2, [0x9C, 0xAF, 0x00, 0x60, 0xB0, 0xEC, 0x3D, 0x39]};\nconst IID IID_IXMLParser = {0xD242361E, 0x51A0, 0x11D2, [0x9C, 0xAF, 0x00, 0x60, 0xB0, 0xEC, 0x3D, 0x39]};\nconst IID IID_IXTLRuntime = {0x3EFAA425, 0x272F, 0x11D2, [0x83, 0x6F, 0x00, 0x00, 0xF8, 0x7A, 0x77, 0x82]};\nconst IID IID_StdOle = {0x00020430, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID KSDATAFORMAT_SUBTYPE_DIRECTMUSIC = {0x1A82F8BC, 0x3F8B, 0x11D2, [0xB7, 0x74, 0x00, 0x60, 0x08, 0x33, 0x16, 0xC1]};\nconst IID KSDATAFORMAT_SUBTYPE_MIDI = {0x1D262760, 0xE957, 0x11CF, [0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00]};\nconst IID LIBID_Accessibility = {0x1EA4DBF0, 0x3C3B, 0x11CF, [0x81, 0x0C, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71]};\nconst IID LIBID_ActiveIMM = {0x4955DD30, 0xB159, 0x11D0, [0x8F, 0xCF, 0x00, 0xAA, 0x00, 0x6B, 0xCC, 0x59]};\nconst IID LIBID_ADs = {0x97D25DB0, 0x0363, 0x11CF, [0xAB, 0xC4, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53]};\nconst IID LIBID_ALGLib = {0xB6D1D098, 0xE235, 0x4B99, [0xBA, 0x98, 0x7C, 0x62, 0x4F, 0xD8, 0x75, 0xDB]};\nconst IID LIBID_AutoDiscovery = {0x4EAFB888, 0x81CB, 0x4EBA, [0xBA, 0xC9, 0xDA, 0x25, 0x4E, 0x57, 0x21, 0xF1]};\nconst IID LIBID_BackgroundCopyManager = {0x1DEEB74F, 0x7915, 0x4560, [0xB5, 0x58, 0x91, 0x8C, 0x83, 0xF1, 0x76, 0xA6]};\nconst IID LIBID_BackgroundCopyManager1_5 = {0xEA9319EA, 0xC628, 0x480F, [0x83, 0x31, 0x76, 0x8F, 0xAC, 0x39, 0x7E, 0x4E]};\nconst IID LIBID_BackgroundCopyQMgr = {0xF5B26DCB, 0xB37E, 0x4D7C, [0xAE, 0x7A, 0x1C, 0xB3, 0xFB, 0xEB, 0x18, 0x3E]};\nconst IID LIBID_CHANNELMGR = {0x4804F2E0, 0xD16E, 0x11D0, [0x80, 0x2B, 0x00, 0xC0, 0x4F, 0xD7, 0x5D, 0x13]};\nconst IID LIBID_CLADMWIZLib = {0x24F97140, 0x6689, 0x11D1, [0x9A, 0xA7, 0x00, 0xC0, 0x4F, 0xB9, 0x3A, 0x80]};\nconst IID LIBID_ClusCfgWizard = {0x6D01FEDC, 0x8D34, 0x4728, [0xAD, 0x0B, 0xB3, 0xA2, 0x1A, 0x10, 0x3B, 0x42]};\nconst IID LIBID_CommonControlObjects = {0xBCADA15B, 0xB428, 0x420C, [0x8D, 0x28, 0x02, 0x35, 0x90, 0x92, 0x4C, 0x9F]};\nconst IID LIBID_DirectAnimation = {0xBCBB1F74, 0xE384, 0x11D0, [0x9B, 0x99, 0x00, 0xC0, 0x4F, 0xC2, 0xF5, 0x1D]};\nconst IID LIBID_DWbemServices_v3 = {0xCB7CA031, 0xF729, 0x11D0, [0x9E, 0x4D, 0x00, 0xC0, 0x4F, 0xC3, 0x24, 0xA8]};\nconst IID LIBID_DXTMSFTLib = {0x5E77EB03, 0x937C, 0x11D1, [0xB0, 0x47, 0x00, 0xAA, 0x00, 0x3B, 0x60, 0x61]};\nconst IID LIBID_DXTRANSLib = {0x54314D1D, 0x35FE, 0x11D1, [0x81, 0xA1, 0x00, 0x00, 0xF8, 0x75, 0x57, 0xDB]};\nconst IID LIBID_DXTRANSPLib = {0x527A4DA4, 0x7F2C, 0x11D2, [0xB1, 0x2D, 0x00, 0x00, 0xF8, 0x1F, 0x59, 0x95]};\nconst IID LIBID_EventQLib = {0xA70080F2, 0x403B, 0x11D1, [0x88, 0x36, 0x00, 0xA0, 0xC9, 0x49, 0xAC, 0x67]};\nconst IID LIBID_IASPolicyLib = {0x6BC096A5, 0x0CE6, 0x11D1, [0xBA, 0xAE, 0x00, 0xC0, 0x4F, 0xC2, 0xE2, 0x0D]};\nconst IID LIBID_IEXTagLib = {0x7E8BC440, 0xAEFF, 0x11D1, [0x89, 0xC2, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4]};\nconst IID LIBID_IMAPILib = {0xC49F2184, 0x50A7, 0x11D3, [0x91, 0x44, 0x00, 0x10, 0x4B, 0xA1, 0x1C, 0x5E]};\nconst IID LIBID_ImgUtilLib = {0xCF790840, 0x2DC4, 0x11D0, [0xB7, 0x24, 0x00, 0xAA, 0x00, 0x6C, 0x1A, 0x01]};\nconst IID LIBID_ITRKADMNLib = {0xA2531F35, 0xC67D, 0x11D0, [0x8C, 0xB1, 0x00, 0xC0, 0x4F, 0xD9, 0x0F, 0x85]};\nconst IID LIBID_McastLib = {0x64217CC0, 0xA285, 0x11D1, [0x86, 0x97, 0x00, 0x60, 0x08, 0xB0, 0xE5, 0xD2]};\nconst IID LIBID_MSHTML = {0x3050F1C5, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID LIBID_MSHTMLINTERNAL = {0x3050F7E1, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID LIBID_MSTIME = {0x87C96271, 0xADDB, 0x4745, [0xB2, 0xE8, 0xDF, 0x88, 0xA8, 0x47, 0x2F, 0xD1]};\nconst IID LIBID_MSXML = {0xD63E0CE2, 0xA0A2, 0x11D0, [0x9C, 0x02, 0x00, 0xC0, 0x4F, 0xC9, 0x9C, 0x8E]};\nconst IID LIBID_MultiLanguage = {0x275C23E0, 0x3747, 0x11D0, [0x9F, 0xEA, 0x00, 0xAA, 0x00, 0x3F, 0x86, 0x46]};\nconst IID LIBID_NATUPNPLib = {0x1C565858, 0xF302, 0x471E, [0xB4, 0x09, 0xF1, 0x80, 0xAA, 0x4A, 0xBE, 0xC6]};\nconst IID LIBID_NETCONLib = {0x43E734CA, 0x043D, 0x4A70, [0x9A, 0x2C, 0xA8, 0xF2, 0x54, 0x06, 0x3D, 0x91]};\nconst IID LIBID_PassiveSink = {0xE002EEEF, 0xE6EA, 0x11D2, [0x9C, 0xB3, 0x00, 0x10, 0x5A, 0x1F, 0x48, 0x01]};\nconst IID LIBID_ProcessDebugManagerLib = {0x78A51821, 0x51F4, 0x11D0, [0x8F, 0x20, 0x00, 0x80, 0x5F, 0x2C, 0xD0, 0x64]};\nconst IID LIBID_RENDLib = {0xF1029E4D, 0xCB5B, 0x11D0, [0x8D, 0x59, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID LIBID_RTCCORELib = {0xCD260094, 0xDE10, 0x4AEE, [0xAC, 0x73, 0xEF, 0x87, 0xF6, 0xE1, 0x26, 0x83]};\nconst IID LIBID_SDOIASLib = {0x81DDF732, 0x4AA8, 0x4A35, [0xBD, 0xFF, 0x8B, 0x42, 0xEF, 0xE7, 0xC6, 0x24]};\nconst IID LIBID_SDPBLBLib = {0xC259D79A, 0xC8AB, 0x11D0, [0x8D, 0x58, 0x00, 0xC0, 0x4F, 0xD9, 0x1A, 0xC0]};\nconst IID LIBID_SensEvents = {0xD597DEED, 0x5B9F, 0x11D1, [0x8D, 0xD2, 0x00, 0xAA, 0x00, 0x4A, 0xBD, 0x5E]};\nconst IID LIBID_SHDocVw = {0xEAB22AC0, 0x30C1, 0x11CF, [0xA7, 0xEB, 0x00, 0x00, 0xC0, 0x5B, 0xAE, 0x0B]};\nconst IID LIBID_Shell32 = {0x50A7E9B0, 0x70EF, 0x11D1, [0xB7, 0x5A, 0x00, 0xA0, 0xC9, 0x05, 0x64, 0xFE]};\nconst IID LIBID_ShellImageData = {0x0B8AFF06, 0x8DF0, 0x4F13, [0x8E, 0x25, 0x25, 0xB2, 0x31, 0x9C, 0x43, 0x6A]};\nconst IID LIBID_ShellObjects = {0x50A7E9B1, 0x70EF, 0x11D1, [0xB7, 0x5A, 0x00, 0xA0, 0xC9, 0x05, 0x64, 0xFE]};\nconst IID LIBID_SHGINALib = {0x0A055C02, 0xBABE, 0x4480, [0xBB, 0x7B, 0xA8, 0xEC, 0x72, 0x3C, 0xE9, 0xC0]};\nconst IID LIBID_SubscriptionMgr = {0xC54FD88A, 0xFFA1, 0x11D0, [0xBC, 0x5E, 0x00, 0xC0, 0x4F, 0xD9, 0x29, 0xDB]};\nconst IID LIBID_TAPI3Lib = {0x21D6D480, 0xA88B, 0x11D0, [0x83, 0xDD, 0x00, 0xAA, 0x00, 0x3C, 0xCA, 0xBD]};\nconst IID LIBID_TERMMGRLib = {0x28DCD85B, 0xACA4, 0x11D0, [0xA0, 0x28, 0x00, 0xAA, 0x00, 0xB6, 0x05, 0xA4]};\nconst IID LIBID_UPnPHostLib = {0x204810B3, 0x73B2, 0x11D4, [0xBF, 0x42, 0x00, 0xB0, 0xD0, 0x11, 0x8B, 0x56]};\nconst IID LIBID_UPNPLib = {0xDB3442A7, 0xA2E9, 0x4A59, [0x9C, 0xB5, 0xF5, 0xC1, 0xA5, 0xD9, 0x01, 0xE5]};\nconst IID LIBID_VIRUSSCAN = {0x5F47DB70, 0xD9FE, 0x11D0, [0x95, 0x64, 0x00, 0x60, 0x97, 0x97, 0xEA, 0x4F]};\nconst IID LIBID_WbemClient_v1 = {0x7EC196FE, 0x7005, 0x11D1, [0xAD, 0x90, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID LIBID_WbemProviders_v1 = {0x092DF710, 0x7010, 0x11D1, [0xAD, 0x90, 0x00, 0xC0, 0x4F, 0xD8, 0xFD, 0xFF]};\nconst IID LIBID_WbemScripting = {0x565783C6, 0xCB41, 0x11D1, [0x8B, 0x02, 0x00, 0x60, 0x08, 0x06, 0xD9, 0xB6]};\nconst IID LIBID_WbemTransports_v1 = {0x027947F3, 0xD731, 0x11CE, [0xA3, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]};\nconst IID LIBID_WbemUtilities_v1 = {0x226C9290, 0xDD96, 0x11D3, [0xA1, 0x20, 0x00, 0x10, 0x5A, 0x1F, 0x51, 0x5A]};\nconst IID LIBID_WebCheck = {0x10BD2E25, 0xF235, 0x11CF, [0xB5, 0xDD, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xEC]};\nconst IID LIBID_WMIEXTENSIONLib = {0xE503D000, 0x5C7F, 0x11D2, [0x8B, 0x74, 0x00, 0x10, 0x4B, 0x2A, 0xFB, 0x41]};\nconst IID LIBID_XENROLLLib = {0x43F8F27B, 0x7A20, 0x11D0, [0x8F, 0x06, 0x00, 0xC0, 0x4F, 0xC2, 0x95, 0xE1]};\nconst IID LIBID_XMLPSR = {0xD242361C, 0x51A0, 0x11D2, [0x9C, 0xAF, 0x00, 0x60, 0xB0, 0xEC, 0x3D, 0x39]};\nconst IID MDGUID_MDX = {0xA07CCCD0, 0x8148, 0x11D0, [0x87, 0xBB, 0x00, 0xC0, 0x4F, 0xC3, 0x39, 0x42]};\nconst IID MDSCHEMA_ACTIONS = {0xA07CCD08, 0x8148, 0x11D0, [0x87, 0xBB, 0x00, 0xC0, 0x4F, 0xC3, 0x39, 0x42]};\nconst IID MDSCHEMA_COMMANDS = {0xA07CCD09, 0x8148, 0x11D0, [0x87, 0xBB, 0x00, 0xC0, 0x4F, 0xC3, 0x39, 0x42]};\nconst IID MDSCHEMA_CUBES = {0xC8B522D8, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID MDSCHEMA_DIMENSIONS = {0xC8B522D9, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID MDSCHEMA_FUNCTIONS = {0xA07CCD07, 0x8148, 0x11D0, [0x87, 0xBB, 0x00, 0xC0, 0x4F, 0xC3, 0x39, 0x42]};\nconst IID MDSCHEMA_HIERARCHIES = {0xC8B522DA, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID MDSCHEMA_LEVELS = {0xC8B522DB, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID MDSCHEMA_MEASURES = {0xC8B522DC, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID MDSCHEMA_MEMBERS = {0xC8B522DE, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID MDSCHEMA_PROPERTIES = {0xC8B522DD, 0x5CF3, 0x11CE, [0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D]};\nconst IID MDSCHEMA_SETS = {0xA07CCD0B, 0x8148, 0x11D0, [0x87, 0xBB, 0x00, 0xC0, 0x4F, 0xC3, 0x39, 0x42]};\nconst IID NAMEDTIMER_DRAW = {0x3050F362, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID NOTFCOOKIE_SCHEDULE_GROUP_DAILY = {0xD34F18B0, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTFCOOKIE_SCHEDULE_GROUP_MANUAL = {0xD34F18B3, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTFCOOKIE_SCHEDULE_GROUP_MONTHLY = {0xD34F18B2, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTFCOOKIE_SCHEDULE_GROUP_WEEKLY = {0xD34F18B1, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_11 = {0xD34F17FB, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_12 = {0xD34F17FC, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_13 = {0xD34F17FD, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_14 = {0xD34F17FE, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_15 = {0xD34F17FF, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_AGENT_INIT = {0x1E4A7390, 0xC70B, 0x11D0, [0x95, 0xF8, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xEC]};\nconst IID NOTIFICATIONTYPE_AGENT_START = {0xD34F17EC, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_ALERT = {0xD34F17E3, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_ANOUNCMENT = {0xD34F17E1, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_BEGIN_REPORT = {0xD34F17EE, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_CONFIG_CHANGED = {0xD34F17F2, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_CONNECT_TO_INTERNET = {0xD34F17F0, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_d = {0xD34F17F8, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_DISCONNECT_FROM_INTE = {0xD34F17F1, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_e = {0xD34F17F9, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_END_REPORT = {0xD34F17EF, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_f = {0xD34F17FA, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_GROUP_DONE = {0xD34F1885, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_GROUP_RESTART = {0xD34F1884, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_GROUP_START = {0xD34F1883, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_i6 = {0xD34F1886, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_i7 = {0xD34F1887, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_i8 = {0xD34F1888, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_i9 = {0xD34F1889, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_iA = {0xD34F188A, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_iB = {0xD34F188B, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_iC = {0xD34F188C, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_iD = {0xD34F188D, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_iE = {0xD34F188E, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_iF = {0xD34F188F, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_INET_IDLE = {0xD34F17E4, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_INET_OFFLINE = {0xD34F17E5, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_INET_ONLINE = {0xD34F17E6, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_ITEM_DONE = {0xD34F1882, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_ITEM_RESTART = {0xD34F1881, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_ITEM_START = {0xD34F1880, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_NULL = {0xD34F17E0, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_PROGRESS_REPORT = {0xD34F17F3, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_0 = {0xD34F1800, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_1 = {0xD34F1801, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_2 = {0xD34F1802, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_3 = {0xD34F1803, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_4 = {0xD34F1804, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_5 = {0xD34F1805, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_6 = {0xD34F1806, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_7 = {0xD34F1807, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_8 = {0xD34F1808, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_9 = {0xD34F1809, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_A = {0xD34F180A, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_B = {0xD34F180B, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_C = {0xD34F180C, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_D = {0xD34F180D, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_E = {0xD34F180E, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_START_F = {0xD34F180F, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_TASK = {0xD34F17E2, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_TASKS_ABORT = {0xD34F17E9, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_TASKS_COMPLETED = {0xD34F17EA, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_TASKS_ERROR = {0xD34F17F7, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_TASKS_PROGRESS = {0xD34F17EB, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_TASKS_RESUME = {0xD34F17E8, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_TASKS_STARTED = {0xD34F17F6, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_TASKS_SUSPEND = {0xD34F17E7, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_USER_IDLE_BEGIN = {0xD34F17F4, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID NOTIFICATIONTYPE_USER_IDLE_END = {0xD34F17F5, 0x576E, 0x11D0, [0xB2, 0x8C, 0x00, 0xC0, 0x4F, 0xD7, 0xCD, 0x22]};\nconst IID OLE_DATAPATH_ALLIMAGE = {0x0002DE0E, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_ALLMM = {0x0002DE18, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_ALLTEXT = {0x0002DE1E, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_ANSITEXT = {0x0002DE19, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_AVI = {0x0002DE0F, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_BASICAUDIO = {0x0002DE12, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_BIFF = {0x0002DE21, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_BMP = {0x0002DE01, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_CGM = {0x0002DE0B, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_COMMONIMAGE = {0x0002DE0D, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_DIB = {0x0002DE02, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_DIF = {0x0002DE1F, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_ENHMF = {0x0002DE04, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_EPS = {0x0002DE0C, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_GIF = {0x0002DE05, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_HTML = {0x0002DE1C, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_JPEG = {0x0002DE06, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_MIDI = {0x0002DE13, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_MPEG = {0x0002DE10, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_PALETTE = {0x0002DE22, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_PCX = {0x0002DE09, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_PENDATA = {0x0002DE23, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_PICT = {0x0002DE0A, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_POSTSCRIPT = {0x0002DE1D, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_QUICKTIME = {0x0002DE11, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_RIFF = {0x0002DE15, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_RTF = {0x0002DE1B, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_SOUND = {0x0002DE16, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_SYLK = {0x0002DE20, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_TIFF = {0x0002DE07, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_UNICODE = {0x0002DE1A, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_VIDEO = {0x0002DE17, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_WAV = {0x0002DE14, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_WMF = {0x0002DE03, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLE_DATAPATH_XBM = {0x0002DE08, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};\nconst IID OLEDB_SVC_DSLPropertyPages = {0x51740C02, 0x7E8E, 0x11D2, [0xA0, 0x2D, 0x00, 0xC0, 0x4F, 0xA3, 0x73, 0x48]};\nconst IID PSGUID_QUERY = {0x49691C90, 0x7E17, 0x101A, [0xA9, 0x1C, 0x08, 0x00, 0x2B, 0x2E, 0xCD, 0xA9]};\nconst IID RESCLASSTYPE_IPAddress = {0x57A80E0F, 0x6F18, 0x458B, [0xA7, 0x2A, 0xD1, 0x17, 0x0C, 0x47, 0x93, 0x90]};\nconst IID RESCLASSTYPE_NetworkName = {0xBBA69EB9, 0xF5D0, 0x487B, [0x92, 0xAE, 0x1B, 0xA1, 0x0F, 0x39, 0x21, 0x58]};\nconst IID RESCLASSTYPE_StorageDevice = {0x12453A47, 0x8C5E, 0x4837, [0xBA, 0xC6, 0xB2, 0x54, 0xB8, 0xF2, 0x64, 0xCC]};\nconst IID RESTYPE_ClusterIPAddress = {0xE50DF832, 0x477C, 0x440C, [0xB7, 0xA3, 0x38, 0x23, 0xA6, 0xEF, 0x6C, 0xCB]};\nconst IID RESTYPE_ClusterNetName = {0xB2897CCF, 0x8D2C, 0x4BC1, [0xB4, 0x96, 0x6E, 0x2B, 0xC7, 0xA0, 0xBB, 0x38]};\nconst IID RESTYPE_ClusterQuorumDisk = {0xD9DDFB80, 0x0BDC, 0x40D4, [0xB3, 0x96, 0x1A, 0xFD, 0x77, 0xDD, 0xD1, 0x9C]};\nconst IID RESTYPE_GenericScript = {0xF372184D, 0xDFDB, 0x4370, [0xA0, 0x05, 0xE1, 0xEF, 0x30, 0x1B, 0x23, 0xA4]};\nconst IID RESTYPE_IPAddress = {0xE61ADE71, 0xC79A, 0x4FDA, [0xB1, 0xDB, 0xA9, 0xB8, 0xD2, 0x0C, 0x8B, 0x14]};\nconst IID RESTYPE_LocalQuorum = {0xF004656D, 0x5B48, 0x4580, [0xA1, 0xF4, 0xC3, 0xEC, 0x14, 0x98, 0x3D, 0x1E]};\nconst IID RESTYPE_MajorityNodeSet = {0x56BFAE11, 0xD2F7, 0x4F4F, [0x99, 0x52, 0x55, 0xAF, 0x19, 0xBA, 0xC3, 0xE9]};\nconst IID RESTYPE_NetworkName = {0xC1D2FE1E, 0xD332, 0x445F, [0x8D, 0xA1, 0x12, 0xE5, 0xE2, 0xD3, 0x7C, 0xBF]};\nconst IID RESTYPE_PhysicalDisk = {0xCC558763, 0x3386, 0x42EF, [0xB1, 0x50, 0xBE, 0x79, 0x33, 0x44, 0xD4, 0x5F]};\nconst IID SID_CtxQueryAssociations = {0xFAADFC40, 0xB777, 0x4B69, [0xAA, 0x81, 0x77, 0x03, 0x5E, 0xF0, 0xE6, 0xE8]};\nconst IID SID_SContainerDispatch = {0xB722BE00, 0x4E68, 0x101B, [0xA2, 0xBC, 0x00, 0xAA, 0x00, 0x40, 0x47, 0x70]};\nconst IID SID_SDataPathBrowser = {0xFC4801A5, 0x2BA9, 0x11CF, [0xA2, 0x29, 0x00, 0xAA, 0x00, 0x3D, 0x73, 0x52]};\nconst IID SID_SGetViewFromViewDual = {0x889A935D, 0x971E, 0x4B12, [0xB9, 0x0C, 0x24, 0xDF, 0xC9, 0xE1, 0xE5, 0xE8]};\nconst IID SID_SHTMLEditServices = {0x3050F7F9, 0x98B5, 0x11CF, [0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B]};\nconst IID SID_STopLevelBrowser = {0x4C96BE40, 0x915C, 0x11CF, [0x99, 0xD3, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37]};\nconst IID SID_STopWindow = {0x49E1B500, 0x4636, 0x11D3, [0x97, 0xF7, 0x00, 0xC0, 0x4F, 0x45, 0xD0, 0xB3]};\nconst IID SID_SVersionHost = {0x371EA634, 0xDC5C, 0x11D1, [0xBA, 0x57, 0x00, 0xC0, 0x4F, 0xC2, 0x04, 0x0E]};\nconst IID TAPIMEDIATYPE_Audio = {0x028ED8C2, 0xDC7A, 0x11D0, [0x8E, 0xD3, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID TAPIMEDIATYPE_DataModem = {0x028ED8C6, 0xDC7A, 0x11D0, [0x8E, 0xD3, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID TAPIMEDIATYPE_G3Fax = {0x028ED8C7, 0xDC7A, 0x11D0, [0x8E, 0xD3, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID TAPIMEDIATYPE_Video = {0x028ED8C4, 0xDC7A, 0x11D0, [0x8E, 0xD3, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID TAPIPROTOCOL_H323 = {0x831CE2D7, 0x83B5, 0x11D1, [0xBB, 0x5C, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID TAPIPROTOCOL_Multicast = {0x831CE2D8, 0x83B5, 0x11D1, [0xBB, 0x5C, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID TAPIPROTOCOL_PSTN = {0x831CE2D6, 0x83B5, 0x11D1, [0xBB, 0x5C, 0x00, 0xC0, 0x4F, 0xB6, 0x80, 0x9F]};\nconst IID TASK_AnalyzeCluster = {0x3140B5A6, 0x9AFA, 0x4588, [0x8C, 0xA0, 0x9B, 0xE8, 0xF8, 0xB6, 0x15, 0x06]};\nconst IID TASK_CommitClusterChanges = {0x2D03030B, 0xF084, 0x4807, [0xBB, 0xAC, 0x94, 0x26, 0x9E, 0x50, 0xB5, 0x6F]};\nconst IID TASKID_Major_Check_Cluster_Feasibili = {0xEBC8AEFF, 0x10C3, 0x4D5B, [0xAC, 0x17, 0xFC, 0x0F, 0x4C, 0x38, 0x71, 0xB7]};\nconst IID TASKID_Major_Check_Node_Feasibility = {0xCC5E57B1, 0x4520, 0x4672, [0xB4, 0xBA, 0xA2, 0x88, 0xEC, 0x42, 0x94, 0x6E]};\nconst IID TASKID_Major_Checking_For_Existing_Cl = {0xB8453B8F, 0x92FD, 0x4350, [0xA6, 0xD9, 0x55, 0x1F, 0xD0, 0x18, 0xB7, 0x91]};\nconst IID TASKID_Major_Client_And_Server_Log = {0xCD36919C, 0x9F31, 0x46B4, [0xA2, 0x9D, 0xAC, 0x87, 0xF4, 0xE6, 0xCC, 0x93]};\nconst IID TASKID_Major_Client_Log = {0x64ECA0EA, 0x9CB6, 0x4324, [0x97, 0x02, 0xDF, 0x15, 0xC6, 0x96, 0xC3, 0x0A]};\nconst IID TASKID_Major_Configure_Cluster_Servic = {0x7C5F0774, 0x1611, 0x42B5, [0xAF, 0x3C, 0x6E, 0x12, 0x4A, 0xC4, 0xD3, 0x6B]};\nconst IID TASKID_Major_Configure_Resource_Type = {0x6D47AF1F, 0x7F17, 0x4B80, [0x8F, 0xAB, 0x3A, 0x2D, 0x19, 0xB1, 0x23, 0x3D]};\nconst IID TASKID_Major_Configure_Resources = {0x411BCDEC, 0x69D3, 0x4485, [0x8D, 0x5D, 0xE1, 0x9E, 0xE7, 0x7A, 0x6D, 0xD4]};\nconst IID TASKID_Major_Establish_Connection = {0x93C32F99, 0x39CA, 0x4D38, [0x9D, 0x7F, 0x27, 0x07, 0xCA, 0x0E, 0xAF, 0x46]};\nconst IID TASKID_Major_Find_Devices = {0x036BF567, 0x2377, 0x4BB3, [0x8A, 0xE1, 0xE4, 0x10, 0x4E, 0x2E, 0xB3, 0xC5]};\nconst IID TASKID_Major_Reanalyze = {0xE25968DA, 0x9C7B, 0x42DB, [0xAD, 0xA9, 0xBC, 0x4E, 0x34, 0xF1, 0x7E, 0x6E]};\nconst IID TASKID_Major_Server_Log = {0x05AA0768, 0x5F49, 0x49CD, [0xAF, 0xDC, 0x96, 0xF9, 0xD5, 0x18, 0x02, 0xD4]};\nconst IID TASKID_Minor_Update_Progress = {0x2362D3DA, 0xA6A4, 0x4551, [0xB8, 0x46, 0x7B, 0xB3, 0xA1, 0x36, 0x5F, 0x56]};\nconst IID TID_D3DRMAnimation = {0x3D82AB4F, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_D3DRMAnimationKey = {0x10DD46A8, 0x775B, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMAnimationOptions = {0xE2BF56C0, 0x840F, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMAnimationSet = {0x3D82AB50, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_D3DRMAppData = {0xE5745280, 0xB24F, 0x11CF, [0x9D, 0xD5, 0x00, 0xAA, 0x00, 0xA7, 0x1A, 0x2F]};\nconst IID TID_D3DRMBoolean = {0x537DA6A0, 0xCA37, 0x11D0, [0x94, 0x1C, 0x00, 0x80, 0xC8, 0x0C, 0xFA, 0x7B]};\nconst IID TID_D3DRMBoolean2d = {0x4885AE63, 0x78E8, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMCamera = {0x3D82AB51, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_D3DRMColorRGB = {0xD3E16E81, 0x7835, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMColorRGBA = {0x35FF44E0, 0x6C7C, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMCoords2d = {0xF6F23F44, 0x7686, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMExternalVisual = {0x98116AA0, 0xBDBA, 0x11D1, [0x82, 0xC0, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x71]};\nconst IID TID_D3DRMFloatKeys = {0x10DD46A9, 0x775B, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMFrame = {0x3D82AB46, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_D3DRMFramePosition = {0xE2BF56C1, 0x840F, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMFrameRotation = {0xE2BF56C3, 0x840F, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMFrameTransformMatrix = {0xF6F23F41, 0x7686, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMFrameVelocity = {0xE2BF56C2, 0x840F, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMGuid = {0xA42790E0, 0x7810, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMIndexedColor = {0x1630B820, 0x7842, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMInfo = {0x2B957100, 0x9E9A, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_D3DRMInlineData = {0x3A23EEA0, 0x94B1, 0x11D0, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_D3DRMLight = {0x3D82AB4A, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_D3DRMLightAttenuation = {0xA8A98BA0, 0xC5E5, 0x11CF, [0xB9, 0x41, 0x00, 0x80, 0xC8, 0x0C, 0xFA, 0x7B]};\nconst IID TID_D3DRMLightPenumbra = {0xAED22741, 0xB31F, 0x11CF, [0x9D, 0xD5, 0x00, 0xAA, 0x00, 0xA7, 0x1A, 0x2F]};\nconst IID TID_D3DRMLightRange = {0xAED22742, 0xB31F, 0x11CF, [0x9D, 0xD5, 0x00, 0xAA, 0x00, 0xA7, 0x1A, 0x2F]};\nconst IID TID_D3DRMLightUmbra = {0xAED22740, 0xB31F, 0x11CF, [0x9D, 0xD5, 0x00, 0xAA, 0x00, 0xA7, 0x1A, 0x2F]};\nconst IID TID_D3DRMMaterial = {0x3D82AB4D, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_D3DRMMaterialAmbientColor = {0x01411840, 0x7786, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMMaterialArray = {0x35FF44E1, 0x6C7C, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMMaterialDiffuseColor = {0x01411841, 0x7786, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMMaterialEmissiveColor = {0xD3E16E80, 0x7835, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMMaterialPower = {0x01411843, 0x7786, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMMaterialSpecularColor = {0x01411842, 0x7786, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMMaterialWrap = {0x4885AE60, 0x78E8, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMMatrix4x4 = {0xF6F23F45, 0x7686, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMMesh = {0x3D82AB44, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_D3DRMMeshFace = {0x3D82AB5F, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_D3DRMMeshFaceWraps = {0xED1EC5C0, 0xC0A8, 0x11D0, [0x94, 0x1C, 0x00, 0x80, 0xC8, 0x0C, 0xFA, 0x7B]};\nconst IID TID_D3DRMMeshMaterialList = {0xF6F23F42, 0x7686, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMMeshNormals = {0xF6F23F43, 0x7686, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMMeshTextureCoords = {0xF6F23F40, 0x7686, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMMeshVertexColors = {0x1630B821, 0x7842, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMProgressiveMesh = {0x8A63C360, 0x997D, 0x11D0, [0x94, 0x1C, 0x00, 0x80, 0xC8, 0x0C, 0xFA, 0x7B]};\nconst IID TID_D3DRMPropertyBag = {0x7F0F21E1, 0xBFE1, 0x11D1, [0x82, 0xC0, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x71]};\nconst IID TID_D3DRMRightHanded = {0x7F5D5EA0, 0xD53A, 0x11D1, [0x82, 0xC0, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x71]};\nconst IID TID_D3DRMStringProperty = {0x7F0F21E0, 0xBFE1, 0x11D1, [0x82, 0xC0, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x71]};\nconst IID TID_D3DRMTextureFilename = {0xA42790E1, 0x7810, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMTextureReference = {0xA42790E2, 0x7810, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMTimedFloatKeys = {0xF406B180, 0x7B3B, 0x11CF, [0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3]};\nconst IID TID_D3DRMUrl = {0x3A23EEA1, 0x94B1, 0x11D0, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_D3DRMVector = {0x3D82AB5E, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID TID_DXFILEHeader = {0x3D82AB43, 0x62DA, 0x11CF, [0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33]};\nconst IID WKPDID_D3DDebugObjectName = {1117490210, 37256, 19212, [135, 66, 172, 176, 191, 133, 194, 0]};\nconst IID WKPDID_D3DDebugObjectNameW = {1288331224, 37407, 17096, [133, 102, 112, 202, 242, 169, 183, 65]};\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/vfw.d",
    "content": "/**\n * Windows API header module\n *\n * written in the D programming language\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_vfw.d)\n */\n\nmodule core.sys.windows.vfw;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"vfw32\");\n\nprivate import\n    core.sys.windows.commdlg,\n    core.sys.windows.wingdi,\n    core.sys.windows.mmsystem,\n    core.sys.windows.unknwn,\n    core.sys.windows.w32api,\n    core.sys.windows.windef,\n    core.sys.windows.winuser;\n\nextern(Windows) {\n    DWORD VideoForWindowsVersion();\n    LONG InitVFW();\n    LONG TermVFW();\n}\n\nDWORD MKFOURCC(char ch0, char ch1, char ch2, char ch3) {\n    return (cast(DWORD)ch0) | ((cast(DWORD)ch1) << 8) | ((cast(DWORD)ch2) << 16) | ((cast(DWORD)ch3) << 24);\n}\n\n/**\n * COMPMAN - Installable Compression Manager.\n */\n\nenum ICVERSION = 0x0104;\n\nalias TypeDef!(HANDLE) HIC;\n\nenum BI_1632 = 0x32333631;\n\ntemplate aviTWOCC(char c0, char c1) {\nenum WORD aviTWOCC = c0 | (c1 << 8);\n}\n\nenum ICTYPE_VIDEO  = mmioFOURCC!('v', 'i', 'd', 'c');\nenum ICTYPE_AUDIO  = mmioFOURCC!('a', 'u', 'd', 'c');\n\nenum {\n    ICERR_OK            = 0,\n    ICERR_DONTDRAW      = 1,\n    ICERR_NEWPALETTE    = 2,\n    ICERR_GOTOKEYFRAME  = 3,\n    ICERR_STOPDRAWING   = 4,\n}\n\nenum ICERR_UNSUPPORTED = -1;\nenum ICERR_BADFORMAT   = -2;\nenum ICERR_MEMORY      = -3;\nenum ICERR_INTERNAL    = -4;\nenum ICERR_BADFLAGS    = -5;\nenum ICERR_BADPARAM    = -6;\nenum ICERR_BADSIZE     = -7;\nenum ICERR_BADHANDLE   = -8;\nenum ICERR_CANTUPDATE  = -9;\nenum ICERR_ABORT       = -10;\nenum ICERR_ERROR       = -100;\nenum ICERR_BADBITDEPTH = -200;\nenum ICERR_BADIMAGESIZE = -201;\n\nenum ICERR_CUSTOM = -400;\n\nenum {\n    ICMODE_COMPRESS         = 1,\n    ICMODE_DECOMPRESS,\n    ICMODE_FASTDECOMPRESS,\n    ICMODE_QUERY,\n    ICMODE_FASTCOMPRESS,\n    ICMODE_DRAW             = 8,\n}\n\nenum ICMODE_INTERNALF_FUNCTION32   = 0x8000;\nenum ICMODE_INTERNALF_MASK         = 0x8000;\n\nenum {\n    AVIIF_LIST      = 0x00000001,\n    AVIIF_TWOCC     = 0x00000002,\n    AVIIF_KEYFRAME  = 0x00000010,\n}\n\nenum ICQUALITY_LOW     = 0;\nenum ICQUALITY_HIGH    = 10000;\nenum ICQUALITY_DEFAULT = -1;\n\nenum {\n    ICM_USER            = DRV_USER + 0x0000,\n    ICM_RESERVED_LOW    = DRV_USER + 0x1000,\n    ICM_RESERVED_HIGH   = DRV_USER + 0x2000,\n    ICM_RESERVED        = ICM_RESERVED_LOW,\n}\n\n// messages\n\nenum {\n    ICM_GETSTATE            = ICM_RESERVED + 0,\n    ICM_SETSTATE            = ICM_RESERVED + 1,\n    ICM_GETINFO             = ICM_RESERVED + 2,\n    ICM_CONFIGURE           = ICM_RESERVED + 10,\n    ICM_ABOUT               = ICM_RESERVED + 11,\n    ICM_GETERRORTEXT        = ICM_RESERVED + 12,\n    ICM_GETFORMATNAME       = ICM_RESERVED + 20,\n    ICM_ENUMFORMATS         = ICM_RESERVED + 21,\n    ICM_GETDEFAULTQUALITY   = ICM_RESERVED + 30,\n    ICM_GETQUALITY          = ICM_RESERVED + 31,\n    ICM_SETQUALITY          = ICM_RESERVED + 32,\n    ICM_SET                 = ICM_RESERVED + 40,\n    ICM_GET                 = ICM_RESERVED + 41,\n}\n\nenum ICM_FRAMERATE     = mmioFOURCC!('F','r','m','R');\nenum ICM_KEYFRAMERATE  = mmioFOURCC!('K','e','y','R');\n\n// ICM specific messages.\n\nenum {\n    ICM_COMPRESS_GET_FORMAT     = ICM_USER + 4,\n    ICM_COMPRESS_GET_SIZE       = ICM_USER + 5,\n    ICM_COMPRESS_QUERY          = ICM_USER + 6,\n    ICM_COMPRESS_BEGIN          = ICM_USER + 7,\n    ICM_COMPRESS                = ICM_USER + 8,\n    ICM_COMPRESS_END            = ICM_USER + 9,\n    ICM_DECOMPRESS_GET_FORMAT   = ICM_USER + 10,\n    ICM_DECOMPRESS_QUERY        = ICM_USER + 11,\n    ICM_DECOMPRESS_BEGIN        = ICM_USER + 12,\n    ICM_DECOMPRESS              = ICM_USER + 13,\n    ICM_DECOMPRESS_END          = ICM_USER + 14,\n    ICM_DECOMPRESS_SET_PALETTE  = ICM_USER + 29,\n    ICM_DECOMPRESS_GET_PALETTE  = ICM_USER + 30,\n    ICM_DRAW_QUERY              = ICM_USER + 31,\n    ICM_DRAW_BEGIN              = ICM_USER + 15,\n    ICM_DRAW_GET_PALETTE        = ICM_USER + 16,\n    ICM_DRAW_UPDATE             = ICM_USER + 17,\n    ICM_DRAW_START              = ICM_USER + 18,\n    ICM_DRAW_STOP               = ICM_USER + 19,\n    ICM_DRAW_BITS               = ICM_USER + 20,\n    ICM_DRAW_END                = ICM_USER + 21,\n    ICM_DRAW_GETTIME            = ICM_USER + 32,\n    ICM_DRAW                    = ICM_USER + 33,\n    ICM_DRAW_WINDOW             = ICM_USER + 34,\n    ICM_DRAW_SETTIME            = ICM_USER + 35,\n    ICM_DRAW_REALIZE            = ICM_USER + 36,\n    ICM_DRAW_FLUSH              = ICM_USER + 37,\n    ICM_DRAW_RENDERBUFFER       = ICM_USER + 38,\n    ICM_DRAW_START_PLAY         = ICM_USER + 39,\n    ICM_DRAW_STOP_PLAY          = ICM_USER + 40,\n    ICM_DRAW_SUGGESTFORMAT      = ICM_USER + 50,\n    ICM_DRAW_CHANGEPALETTE      = ICM_USER + 51,\n    ICM_DRAW_IDLE               = ICM_USER + 52,\n    ICM_GETBUFFERSWANTED        = ICM_USER + 41,\n    ICM_GETDEFAULTKEYFRAMERATE  = ICM_USER + 42,\n    ICM_DECOMPRESSEX_BEGIN      = ICM_USER + 60,\n    ICM_DECOMPRESSEX_QUERY      = ICM_USER + 61,\n    ICM_DECOMPRESSEX            = ICM_USER + 62,\n    ICM_DECOMPRESSEX_END        = ICM_USER + 63,\n    ICM_COMPRESS_FRAMES_INFO    = ICM_USER + 70,\n    ICM_COMPRESS_FRAMES         = ICM_USER + 71,\n    ICM_SET_STATUS_PROC         = ICM_USER + 72,\n}\n\nstruct ICOPEN {\n    DWORD   dwSize;\n    DWORD   fccType;\n    DWORD   fccHandler;\n    DWORD   dwVersion;\n    DWORD   dwFlags;\n    LRESULT dwError;\n    LPVOID  pV1Reserved;\n    LPVOID  pV2Reserved;\n    DWORD   dnDevNode;\n}\n\nstruct ICINFO {\n    DWORD   dwSize;\n    DWORD   fccType;\n    DWORD   fccHandler;\n    DWORD   dwFlags;\n    DWORD   dwVersion;\n    DWORD   dwVersionICM;\n    WCHAR[16]   szName;\n    WCHAR[128]  szDescription;\n    WCHAR[128]  szDriver;\n}\n\nenum {\n    VIDCF_QUALITY           = 0x0001,\n    VIDCF_CRUNCH            = 0x0002,\n    VIDCF_TEMPORAL          = 0x0004,\n    VIDCF_COMPRESSFRAMES    = 0x0008,\n    VIDCF_DRAW              = 0x0010,\n    VIDCF_FASTTEMPORALC     = 0x0020,\n    VIDCF_FASTTEMPORALD     = 0x0080,\n}\n\nenum ICCOMPRESS_KEYFRAME = 0x00000001L;\n\nstruct ICCOMPRESS {\n    DWORD               dwFlags;\n    LPBITMAPINFOHEADER  lpbiOutput;\n    LPVOID              lpOutput;\n    LPBITMAPINFOHEADER  lpbiInput;\n    LPVOID              lpInput;\n    LPDWORD             lpckid;\n    LPDWORD             lpdwFlags;\n    LONG                lFrameNum;\n    DWORD               dwFrameSize;\n    DWORD               dwQuality;\n    LPBITMAPINFOHEADER  lpbiPrev;\n    LPVOID              lpPrev;\n}\n\nenum ICCOMPRESSFRAMES_PADDING = 0x00000001;\n\nstruct ICCOMPRESSFRAMES {\n    DWORD               dwFlags;\n    LPBITMAPINFOHEADER  lpbiOutput;\n    LPARAM              lOutput;\n    LPBITMAPINFOHEADER  lpbiInput;\n    LPARAM              lInput;\n    LONG                lStartFrame;\n    LONG                lFrameCount;\n    LONG                lQuality;\n    LONG                lDataRate;\n    LONG                lKeyRate;\n    DWORD               dwRate;\n    DWORD               dwScale;    DWORD       dwOverheadPerFrame;\n    DWORD               dwReserved2;\nextern (Windows):\n    LONG function(LPARAM lInput, LONG lFrame, LPVOID lpBits, LONG len) GetData;\n    LONG function(LPARAM lOutput, LONG lFrame, LPVOID lpBits, LONG len) PutData;\n}\n\nenum {\n    ICSTATUS_START  = 0,\n    ICSTATUS_STATUS = 1,\n    ICSTATUS_END    = 2,\n    ICSTATUS_ERROR  = 3,\n    ICSTATUS_YIELD  = 4,\n}\n\nstruct ICSETSTATUSPROC {\n    DWORD   dwFlags;\n    LPARAM  lParam;\nextern (Windows)\n    LONG function(LPARAM lParam, UINT message, LONG l) Status;\n}\n\nenum {\n    ICDECOMPRESS_NOTKEYFRAME    = 0x08000000,\n    ICDECOMPRESS_NULLFRAME      = 0x10000000,\n    ICDECOMPRESS_PREROLL        = 0x20000000,\n    ICDECOMPRESS_UPDATE         = 0x40000000,\n    ICDECOMPRESS_HURRYUP        = 0x80000000,\n}\n\nstruct ICDECOMPRESS {\n    DWORD               dwFlags;\n    LPBITMAPINFOHEADER  lpbiInput;\n    LPVOID              lpInput;\n    LPBITMAPINFOHEADER  lpbiOutput;\n    LPVOID              lpOutput;\n    DWORD               ckid;\n}\n\nstruct ICDECOMPRESSEX {\n    DWORD               dwFlags;\n    LPBITMAPINFOHEADER  lpbiSrc;\n    LPVOID              lpSrc;\n    LPBITMAPINFOHEADER  lpbiDst;\n    LPVOID              lpDst;\n    int                 xDst;\n    int                 yDst;\n    int                 dxDst;\n    int                 dyDst;\n    int                 xSrc;\n    int                 ySrc;\n    int                 dxSrc;\n    int                 dySrc;\n}\n\nenum {\n    ICDRAW_QUERY        = 0x00000001,\n    ICDRAW_FULLSCREEN   = 0x00000002,\n    ICDRAW_HDC          = 0x00000004,\n    ICDRAW_ANIMATE      = 0x00000008,\n    ICDRAW_CONTINUE     = 0x00000010,\n    ICDRAW_MEMORYDC     = 0x00000020,\n    ICDRAW_UPDATING     = 0x00000040,\n    ICDRAW_RENDER       = 0x00000080,\n    ICDRAW_BUFFER       = 0x00000100,\n}\n\nstruct ICDRAWBEGIN {\n    DWORD               dwFlags;\n    HPALETTE            hpal;\n    HWND                hwnd;\n    HDC                 hdc;\n    int                 xDst;\n    int                 yDst;\n    int                 dxDst;\n    int                 dyDst;\n    LPBITMAPINFOHEADER  lpbi;\n    int                 xSrc;\n    int                 ySrc;\n    int                 dxSrc;\n    int                 dySrc;\n    DWORD               dwRate;\n    DWORD               dwScale;\n}\n\nenum {\n    ICDRAW_NOTKEYFRAME  = 0x08000000,\n    ICDRAW_NULLFRAME    = 0x10000000,\n    ICDRAW_PREROLL      = 0x20000000,\n    ICDRAW_UPDATE       = 0x40000000,\n    ICDRAW_HURRYUP      = 0x80000000,\n}\n\nstruct ICDRAW {\n    DWORD           dwFlags;\n    LPVOID          lpFormat;\n    LPVOID          lpData;\n    DWORD           cbData;\n    LONG            lTime;\n}\n\nstruct ICDRAWSUGGEST {\n    LPBITMAPINFOHEADER  lpbiIn;\n    LPBITMAPINFOHEADER  lpbiSuggest;\n    int                 dxSrc;\n    int                 dySrc;\n    int                 dxDst;\n    int                 dyDst;\n    HIC                 hicDecompressor;\n}\n\nstruct ICPALETTE {\n    DWORD           dwFlags;\n    int             iStart;\n    int             iLen;\n    LPPALETTEENTRY  lppe;\n}\n\n\n/**\n * ICM function declarations\n */\n\nextern (Windows) {\n    BOOL ICInfo(DWORD fccType, DWORD fccHandler, ICINFO *lpicinfo);\n    BOOL ICInstall(DWORD fccType, DWORD fccHandler, LPARAM lParam, LPSTR szDesc, UINT wFlags);\n    BOOL ICRemove(DWORD fccType, DWORD fccHandler, UINT wFlags);\n    LRESULT ICGetInfo(HIC hic, ICINFO *picinfo, DWORD cb);\n    HIC ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode);\n    HIC ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler);\n    LRESULT ICClose(HIC hic);\n    LRESULT ICSendMessage(HIC hic, UINT msg, DWORD_PTR dw1, DWORD_PTR dw2);\n}\n\nenum {\n    ICINSTALL_FUNCTION  = 0x0001,\n    ICINSTALL_DRIVER    = 0x0002,\n    ICINSTALL_HDRV      = 0x0004,\n    ICINSTALL_UNICODE   = 0x8000,\n    ICINSTALL_DRIVERW   = 0x8002,\n}\n\n// query macros\n\nenum ICMF_CONFIGURE_QUERY  = 0x00000001;\nenum ICMF_ABOUT_QUERY      = 0x00000001;\n\nDWORD ICQueryAbout(HIC hic) {\n    return ICSendMessage(hic, ICM_ABOUT, -1, ICMF_ABOUT_QUERY) == ICERR_OK;\n}\n\nDWORD ICAbout(HIC hic, HWND hwnd) {\n    return cast(DWORD) ICSendMessage(hic, ICM_ABOUT, cast(DWORD_PTR) cast(UINT_PTR) hwnd, 0);\n}\n\nDWORD ICQueryConfigure(HIC hic) {\n    return (ICSendMessage(hic, ICM_CONFIGURE, -1, ICMF_CONFIGURE_QUERY) == ICERR_OK);\n}\n\nDWORD ICConfigure(HIC hic, HWND hwnd) {\n    return cast(DWORD) ICSendMessage(hic, ICM_CONFIGURE, cast(DWORD_PTR) cast(UINT_PTR) hwnd, 0);\n}\n\nDWORD ICGetState(HIC hic, LPVOID pv, DWORD_PTR cb) {\n    return cast(DWORD) ICSendMessage(hic, ICM_GETSTATE, cast(DWORD_PTR) pv, cb);\n}\n\nDWORD ICSetState(HIC hic, LPVOID pv, DWORD_PTR cb) {\n    return cast(DWORD) ICSendMessage(hic, ICM_SETSTATE, cast(DWORD_PTR) pv, cb);\n}\n\nDWORD ICGetStateSize(HIC hic) {\n    return ICGetState(hic, null, 0);\n}\n\nDWORD dwICValue;\n\nDWORD ICGetDefaultQuality(HIC hic) {\n    ICSendMessage(hic, ICM_GETDEFAULTQUALITY, cast(DWORD_PTR)&dwICValue, DWORD.sizeof);\n    return dwICValue;\n}\n\nDWORD ICGetDefaultKeyFrameRate(HIC hic) {\n    ICSendMessage(hic, ICM_GETDEFAULTKEYFRAMERATE, cast(DWORD_PTR)&dwICValue, DWORD.sizeof);\n    return dwICValue;\n}\n\nDWORD ICDrawWindow(HIC hic, LPVOID prc) {\n    return cast(DWORD) ICSendMessage(hic, ICM_DRAW_WINDOW, cast(DWORD_PTR) prc, RECT.sizeof);\n}\n\nextern (Windows) {\n    DWORD ICCompress(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData,\n        LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits, LPDWORD lpckid, LPDWORD lpdwFlags,\n        LONG lFrameNum, DWORD dwFrameSize, DWORD dwQuality, LPBITMAPINFOHEADER lpbiPrev, LPVOID lpPrev);\n}\n\nLRESULT ICCompressBegin(HIC hic, LPVOID lpbiInput, LPVOID lpbiOutput) {\n    return ICSendMessage(hic, ICM_COMPRESS_BEGIN, cast(DWORD_PTR)lpbiInput, cast(DWORD_PTR)lpbiOutput);\n}\nLRESULT ICCompressQuery(HIC hic, LPVOID lpbiInput, LPVOID lpbiOutput) {\n    return ICSendMessage(hic, ICM_COMPRESS_QUERY, cast(DWORD_PTR)lpbiInput, cast(DWORD_PTR)lpbiOutput);\n}\nLRESULT ICCompressGetFormat(HIC hic, LPVOID lpbiInput, LPVOID lpbiOutput) {\n    return ICSendMessage(hic, ICM_COMPRESS_GET_FORMAT, cast(DWORD_PTR)lpbiInput, cast(DWORD_PTR)lpbiOutput);\n}\nDWORD ICCompressGetFormatSize(HIC hic, LPVOID lpbi) {\n    return cast(DWORD)ICCompressGetFormat(hic, lpbi, null);\n}\nDWORD ICCompressGetSize(HIC hic, LPVOID lpbiInput, LPVOID lpbiOutput) {\n    return cast(DWORD)ICSendMessage(hic, ICM_COMPRESS_GET_SIZE, cast(DWORD_PTR)lpbiInput, cast(DWORD_PTR)lpbiOutput);\n}\nLRESULT ICCompressEnd(HIC hic) {\n    return ICSendMessage(hic, ICM_COMPRESS_END, 0, 0);\n}\n\nextern (Windows) {\n    DWORD ICDecompress(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData, LPBITMAPINFOHEADER lpbi, LPVOID lpBits);\n}\n\nLRESULT ICDecompressBegin(HIC hic, LPVOID lpbiInput, LPVOID lpbiOutput) {\n    return ICSendMessage(hic, ICM_DECOMPRESS_BEGIN, cast(DWORD_PTR)lpbiInput, cast(DWORD_PTR)lpbiOutput);\n}\nLRESULT ICDecompressQuery(HIC hic, LPVOID lpbiInput, LPVOID lpbiOutput) {\n    return ICSendMessage(hic, ICM_DECOMPRESS_QUERY, cast(DWORD_PTR)lpbiInput, cast(DWORD_PTR)lpbiOutput);\n}\nLONG ICDecompressGetFormat(HIC hic, LPVOID lpbiInput, LPVOID lpbiOutput) {\n    return cast(LONG)ICSendMessage(hic, ICM_DECOMPRESS_GET_FORMAT, cast(DWORD_PTR)lpbiInput, cast(DWORD_PTR)lpbiOutput);\n}\nLONG ICDecompressGetFormatSize(HIC hic, LPVOID lpbi) {\n    return ICDecompressGetFormat(hic, lpbi, null);\n}\nLRESULT ICDecompressGetPalette(HIC hic, LPVOID lpbiInput, LPVOID lpbiOutput) {\n    return ICSendMessage(hic, ICM_DECOMPRESS_GET_PALETTE, cast(DWORD_PTR)lpbiInput, cast(DWORD_PTR)lpbiOutput);\n}\nLRESULT ICDecompressSetPalette(HIC hic, LPVOID lpbiPalette) {\n    return ICSendMessage(hic, ICM_DECOMPRESS_SET_PALETTE, cast(DWORD_PTR)lpbiPalette, 0);\n}\nLRESULT ICDecompressEnd(HIC hic) {\n    return ICSendMessage(hic, ICM_DECOMPRESS_END, 0, 0);\n}\n\nLRESULT ICDecompressEx(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiSrc,\n    LPVOID lpSrc, int xSrc, int ySrc, int dxSrc, int dySrc, LPBITMAPINFOHEADER lpbiDst,\n    LPVOID lpDst, int xDst, int yDst, int dxDst, int dyDst) {\n    ICDECOMPRESSEX ic;\n\n    ic.dwFlags = dwFlags;\n    ic.lpbiSrc = lpbiSrc;\n    ic.lpSrc = lpSrc;\n    ic.xSrc = xSrc;\n    ic.ySrc = ySrc;\n    ic.dxSrc = dxSrc;\n    ic.dySrc = dySrc;\n    ic.lpbiDst = lpbiDst;\n    ic.lpDst = lpDst;\n    ic.xDst = xDst;\n    ic.yDst = yDst;\n    ic.dxDst = dxDst;\n    ic.dyDst = dyDst;\n\n    return ICSendMessage(hic, ICM_DECOMPRESSEX, cast(DWORD_PTR)&ic, ic.sizeof);\n}\n\nLRESULT ICDecompressExBegin(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiSrc,\n    LPVOID lpSrc, int xSrc, int ySrc, int dxSrc, int dySrc, LPBITMAPINFOHEADER lpbiDst,\n    LPVOID lpDst, int xDst, int yDst, int dxDst, int dyDst) {\n    ICDECOMPRESSEX ic;\n\n    ic.dwFlags = dwFlags;\n    ic.lpbiSrc = lpbiSrc;\n    ic.lpSrc = lpSrc;\n    ic.xSrc = xSrc;\n    ic.ySrc = ySrc;\n    ic.dxSrc = dxSrc;\n    ic.dySrc = dySrc;\n    ic.lpbiDst = lpbiDst;\n    ic.lpDst = lpDst;\n    ic.xDst = xDst;\n    ic.yDst = yDst;\n    ic.dxDst = dxDst;\n    ic.dyDst = dyDst;\n\n    return ICSendMessage(hic, ICM_DECOMPRESSEX_BEGIN, cast(DWORD_PTR)&ic, ic.sizeof);\n}\n\nLRESULT ICDecompressExQuery(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiSrc,\n    LPVOID lpSrc, int xSrc, int ySrc, int dxSrc, int dySrc, LPBITMAPINFOHEADER lpbiDst,\n    LPVOID lpDst, int xDst, int yDst, int dxDst, int dyDst) {\n    ICDECOMPRESSEX ic;\n\n    ic.dwFlags = dwFlags;\n    ic.lpbiSrc = lpbiSrc;\n    ic.lpSrc = lpSrc;\n    ic.xSrc = xSrc;\n    ic.ySrc = ySrc;\n    ic.dxSrc = dxSrc;\n    ic.dySrc = dySrc;\n    ic.lpbiDst = lpbiDst;\n    ic.lpDst = lpDst;\n    ic.xDst = xDst;\n    ic.yDst = yDst;\n    ic.dxDst = dxDst;\n    ic.dyDst = dyDst;\n\n    return ICSendMessage(hic, ICM_DECOMPRESSEX_QUERY, cast(DWORD_PTR)&ic, ic.sizeof);\n}\n\nLRESULT ICDecompressExEnd(HIC hic) {\n    return ICSendMessage(hic, ICM_DECOMPRESSEX_END, 0, 0);\n}\n\nextern (Windows) {\n    DWORD ICDrawBegin(HIC hic, DWORD dwFlags, HPALETTE hpal, HWND hwnd, HDC hdc,\n        int xDst, int yDst, int dxDst, int dyDst, LPBITMAPINFOHEADER lpbi,\n        int xSrc, int ySrc, int dxSrc, int dySrc, DWORD dwRate, DWORD dwScale);\n}\n\nextern (Windows) {\n    DWORD ICDraw(HIC hic, DWORD dwFlags, LPVOID lpFormat, LPVOID lpData, DWORD cbData, LONG lTime);\n}\n\nLRESULT ICDrawSuggestFormat(HIC hic, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut,\n    int dxSrc, int dySrc, int dxDst, int dyDst, HIC hicDecomp) {\n    ICDRAWSUGGEST ic;\n\n    ic.lpbiIn = lpbiIn;\n    ic.lpbiSuggest = lpbiOut;\n    ic.dxSrc = dxSrc;\n    ic.dySrc = dySrc;\n    ic.dxDst = dxDst;\n    ic.dyDst = dyDst;\n    ic.hicDecompressor = hicDecomp;\n\n    return ICSendMessage(hic, ICM_DRAW_SUGGESTFORMAT, cast(DWORD_PTR)&ic, ic.sizeof);\n}\n\nLRESULT ICDrawQuery(HIC hic, LPVOID lpbiInput) {\n    return ICSendMessage(hic, ICM_DRAW_QUERY, cast(DWORD_PTR)lpbiInput, 0L);\n}\nLRESULT ICDrawChangePalette(HIC hic, LPVOID lpbiInput) {\n    return ICSendMessage(hic, ICM_DRAW_CHANGEPALETTE, cast(DWORD_PTR)lpbiInput, 0L);\n}\nLRESULT ICGetBuffersWanted(HIC hic, LPVOID lpdwBuffers) {\n    return ICSendMessage(hic, ICM_GETBUFFERSWANTED, cast(DWORD_PTR)lpdwBuffers, 0);\n}\nLRESULT ICDrawEnd(HIC hic) {\n    return ICSendMessage(hic, ICM_DRAW_END, 0, 0);\n}\nLRESULT ICDrawStart(HIC hic) {\n    return ICSendMessage(hic, ICM_DRAW_START, 0, 0);\n}\nLRESULT ICDrawStartPlay(HIC hic, DWORD lFrom, DWORD lTo) {\n    return ICSendMessage(hic, ICM_DRAW_START_PLAY, cast(DWORD_PTR)lFrom, cast(DWORD_PTR)lTo);\n}\nLRESULT ICDrawStop(HIC hic) {\n    return ICSendMessage(hic, ICM_DRAW_STOP, 0, 0);\n}\nLRESULT ICDrawStopPlay(HIC hic) {\n    return ICSendMessage(hic, ICM_DRAW_STOP_PLAY, 0, 0);\n}\nLRESULT ICDrawGetTime(HIC hic, LPVOID lplTime) {\n    return ICSendMessage(hic, ICM_DRAW_GETTIME, cast(DWORD_PTR)lplTime, 0);\n}\nLRESULT ICDrawSetTime(HIC hic, DWORD lTime) {\n    return ICSendMessage(hic, ICM_DRAW_SETTIME, cast(DWORD_PTR)lTime, 0);\n}\nLRESULT ICDrawRealize(HIC hic, HDC hdc, BOOL fBackground) {\n    return ICSendMessage(hic, ICM_DRAW_REALIZE, cast(DWORD_PTR)hdc, cast(DWORD_PTR)fBackground);\n}\nLRESULT ICDrawFlush(HIC hic) {\n    return ICSendMessage(hic, ICM_DRAW_FLUSH, 0, 0);\n}\nLRESULT ICDrawRenderBuffer(HIC hic) {\n    return ICSendMessage(hic, ICM_DRAW_RENDERBUFFER, 0, 0);\n}\n\nextern (Windows)\nLRESULT ICSetStatusProc(HIC hic, DWORD dwFlags, LRESULT lParam, LONG function(LPARAM, UINT, LONG) fpfnStatus) {\n    ICSETSTATUSPROC ic;\n\n    ic.dwFlags = dwFlags;\n    ic.lParam = lParam;\n    ic.Status = fpfnStatus;\n\n    return ICSendMessage(hic, ICM_SET_STATUS_PROC, cast(DWORD_PTR)&ic, ic.sizeof);\n}\n\nHIC ICDecompressOpen(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut) {\n    return ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, ICMODE_DECOMPRESS);\n}\n\nHIC ICDrawOpen(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn) {\n    return ICLocate(fccType, fccHandler, lpbiIn, null, ICMODE_DRAW);\n}\n\nextern (Windows) {\n    HIC ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, WORD wFlags);\n    HIC ICGetDisplayFormat(HIC hic, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, int BitDepth, int dx, int dy);\n    HANDLE ICImageCompress(HIC hic, UINT uiFlags, LPBITMAPINFO lpbiIn, LPVOID lpBits, LPBITMAPINFO lpbiOut, LONG lQuality, LONG* plSize);\n    HANDLE ICImageDecompress(HIC hic, UINT uiFlags, LPBITMAPINFO lpbiIn, LPVOID lpBits, LPBITMAPINFO lpbiOut);\n}\n\nstruct COMPVARS {\n    LONG        cbSize = this.sizeof;\n    DWORD       dwFlags;\n    HIC         hic;\n    DWORD               fccType;\n    DWORD               fccHandler;\n    LPBITMAPINFO    lpbiIn;\n    LPBITMAPINFO    lpbiOut;\n    LPVOID      lpBitsOut;\n    LPVOID      lpBitsPrev;\n    LONG        lFrame;\n    LONG        lKey;\n    LONG        lDataRate;\n    LONG        lQ;\n    LONG        lKeyCount;\n    LPVOID      lpState;\n    LONG        cbState;\n}\nalias COMPVARS* PCOMPVARS;\n\nenum ICMF_COMPVARS_VALID = 0x00000001;\n\nextern (Windows) {\n    BOOL ICCompressorChoose(HWND hwnd, UINT uiFlags, LPVOID pvIn, LPVOID lpData, PCOMPVARS pc, LPSTR lpszTitle);\n}\n\nenum {\n    ICMF_CHOOSE_KEYFRAME        = 0x0001,\n    ICMF_CHOOSE_DATARATE        = 0x0002,\n    ICMF_CHOOSE_PREVIEW         = 0x0004,\n    ICMF_CHOOSE_ALLCOMPRESSORS  = 0x0008,\n}\n\nextern (Windows) {\n    BOOL ICSeqCompressFrameStart(PCOMPVARS pc, LPBITMAPINFO lpbiIn);\n    void ICSeqCompressFrameEnd(PCOMPVARS pc);\n    LPVOID ICSeqCompressFrame(PCOMPVARS pc, UINT uiFlags, LPVOID lpBits, BOOL* pfKey, LONG* plSize);\n    void ICCompressorFree(PCOMPVARS pc);\n}\n\nmixin DECLARE_HANDLE!(\"HDRAWDIB\");\n\nenum {\n    DDF_0001            = 0x0001,\n    DDF_UPDATE          = 0x0002,\n    DDF_SAME_HDC        = 0x0004,\n    DDF_SAME_DRAW       = 0x0008,\n    DDF_DONTDRAW        = 0x0010,\n    DDF_ANIMATE         = 0x0020,\n    DDF_BUFFER          = 0x0040,\n    DDF_JUSTDRAWIT      = 0x0080,\n    DDF_FULLSCREEN      = 0x0100,\n    DDF_BACKGROUNDPAL   = 0x0200,\n    DDF_NOTKEYFRAME     = 0x0400,\n    DDF_HURRYUP         = 0x0800,\n    DDF_HALFTONE        = 0x1000,\n    DDF_2000            = 0x2000,\n    DDF_PREROLL         = DDF_DONTDRAW,\n    DDF_SAME_DIB        = DDF_SAME_DRAW,\n    DDF_SAME_SIZE       = DDF_SAME_DRAW,\n}\n\nextern (Windows) {\n    BOOL DrawDibInit();\n    HDRAWDIB DrawDibOpen();\n    BOOL DrawDibClose(HDRAWDIB hdd);\n    LPVOID DrawDibGetBuffer(HDRAWDIB hdd, LPBITMAPINFOHEADER lpbi, DWORD dwSize, DWORD dwFlags);\n    UINT DrawDibError(HDRAWDIB hdd);\n    HPALETTE DrawDibGetPalette(HDRAWDIB hdd);\n    BOOL DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal);\n    BOOL DrawDibChangePalette(HDRAWDIB hdd, int iStart, int iLen, LPPALETTEENTRY lppe);\n    UINT DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground);\n    BOOL DrawDibStart(HDRAWDIB hdd, DWORD rate);\n    BOOL DrawDibStop(HDRAWDIB hdd);\n    BOOL DrawDibBegin(HDRAWDIB hdd, HDC hdc, int dxDst, int dyDst, LPBITMAPINFOHEADER lpbi, int dxSrc, int dySrc, UINT wFlags);\n    BOOL DrawDibDraw(HDRAWDIB hdd, HDC hdc, int xDst, int yDst, int dxDst, int dyDst, LPBITMAPINFOHEADER lpbi,\n        LPVOID lpBits, int xSrc, int ySrc, int dxSrc, int dySrc, UINT wFlags);\n}\n\nBOOL DrawDibUpdate(HDRAWDIB hdd, HDC hdc, int x, int y) {\n    return DrawDibDraw(hdd, hdc, x, y, 0, 0, null, null, 0, 0, 0, 0, DDF_UPDATE);\n}\n\nextern (Windows) {\n    BOOL DrawDibEnd(HDRAWDIB hdd);\n}\n\nstruct DRAWDIBTIME {\n    LONG    timeCount;\n    LONG    timeDraw;\n    LONG    timeDecompress;\n    LONG    timeDither;\n    LONG    timeStretch;\n    LONG    timeBlt;\n    LONG    timeSetDIBits;\n}\nalias DRAWDIBTIME* LPDRAWDIBTIME;\n\nextern (Windows) {\n    BOOL DrawDibTime(HDRAWDIB hdd, LPDRAWDIBTIME lpddtime);\n}\n\nenum {\n    PD_CAN_DRAW_DIB         = 0x0001,\n    PD_CAN_STRETCHDIB       = 0x0002,\n    PD_STRETCHDIB_1_1_OK    = 0x0004,\n    PD_STRETCHDIB_1_2_OK    = 0x0008,\n    PD_STRETCHDIB_1_N_OK    = 0x0010,\n}\n\nextern (Windows) {\n    LRESULT DrawDibProfileDisplay(LPBITMAPINFOHEADER lpbi);\n    void StretchDIB(LPBITMAPINFOHEADER biDst, LPVOID lpDst, int DstX, int DstY,\n        int DstXE, int DstYE, LPBITMAPINFOHEADER biSrc, LPVOID lpSrc,\n        int SrcX, int SrcY, int SrcXE, int SrcYE);\n}\n\nalias DWORD FOURCC;\n\nalias WORD TWOCC;\n\nenum formtypeAVI           = mmioFOURCC!('A', 'V', 'I', ' ');\nenum listtypeAVIHEADER     = mmioFOURCC!('h', 'd', 'r', 'l');\nenum ckidAVIMAINHDR        = mmioFOURCC!('a', 'v', 'i', 'h');\nenum listtypeSTREAMHEADER  = mmioFOURCC!('s', 't', 'r', 'l');\nenum ckidSTREAMHEADER      = mmioFOURCC!('s', 't', 'r', 'h');\nenum ckidSTREAMFORMAT      = mmioFOURCC!('s', 't', 'r', 'f');\nenum ckidSTREAMHANDLERDATA = mmioFOURCC!('s', 't', 'r', 'd');\nenum ckidSTREAMNAME        = mmioFOURCC!('s', 't', 'r', 'n');\nenum listtypeAVIMOVIE      = mmioFOURCC!('m', 'o', 'v', 'i');\nenum listtypeAVIRECORD     = mmioFOURCC!('r', 'e', 'c', ' ');\nenum ckidAVINEWINDEX       = mmioFOURCC!('i', 'd', 'x', '1');\nenum streamtypeVIDEO       = mmioFOURCC!('v', 'i', 'd', 's');\nenum streamtypeAUDIO       = mmioFOURCC!('a', 'u', 'd', 's');\nenum streamtypeMIDI        = mmioFOURCC!('m', 'i', 'd', 's');\nenum streamtypeTEXT        = mmioFOURCC!('t', 'x', 't', 's');\n\nenum cktypeDIBbits         = aviTWOCC!('d', 'b');\nenum cktypeDIBcompressed   = aviTWOCC!('d', 'c');\nenum cktypePALchange       = aviTWOCC!('p', 'c');\nenum cktypeWAVEbytes       = aviTWOCC!('w', 'b');\n\nenum ckidAVIPADDING        = mmioFOURCC!('J', 'U', 'N', 'K');\n\nDWORD FromHex(char n) {\n    return (n >= 'A') ? n + 10 - 'A' : n - '0';\n}\n\nWORD StreamFromFOURCC(DWORD fcc) {\n    return cast(WORD)((FromHex(LOBYTE(LOWORD(fcc))) << 4) + (FromHex(HIBYTE(LOWORD(fcc)))));\n}\n\nWORD TWOCCFromFOURCC(DWORD fcc) {\n    return HIWORD(fcc);\n}\n\nBYTE ToHex(DWORD n) {\n    return cast(BYTE)((n > 9) ? n - 10 + 'A' : n + '0');\n}\n\nDWORD MAKEAVICKID(WORD tcc, WORD stream) {\n    return MAKELONG(cast(WORD)((ToHex(stream & 0x0f) << 8) | (ToHex((stream & 0xf0) >> 4))), tcc);\n}\n\nenum {\n    AVIF_HASINDEX       = 0x00000010,\n    AVIF_MUSTUSEINDEX   = 0x00000020,\n    AVIF_ISINTERLEAVED  = 0x00000100,\n    AVIF_WASCAPTUREFILE = 0x00010000,\n    AVIF_COPYRIGHTED    = 0x00020000,\n}\n\nenum AVI_HEADERSIZE = 2048;\n\nstruct MainAVIHeader {\n    DWORD dwMicroSecPerFrame;\n    DWORD dwMaxBytesPerSec;\n    DWORD dwPaddingGranularity;\n    DWORD dwFlags;\n    DWORD dwTotalFrames;\n    DWORD dwInitialFrames;\n    DWORD dwStreams;\n    DWORD dwSuggestedBufferSize;\n    DWORD dwWidth;\n    DWORD dwHeight;\n    DWORD[4] dwReserved;\n}\n\nenum AVISF_DISABLED = 0x00000001;\n\nenum AVISF_VIDEO_PALCHANGES = 0x00010000;\n\nstruct AVIStreamHeader {\n    FOURCC      fccType;\n    FOURCC      fccHandler;\n    DWORD       dwFlags;\n    WORD        wPriority;\n    WORD        wLanguage;\n    DWORD       dwInitialFrames;\n    DWORD       dwScale;\n    DWORD       dwRate;\n    DWORD       dwStart;\n    DWORD       dwLength;\n    DWORD       dwSuggestedBufferSize;\n    DWORD       dwQuality;\n    DWORD       dwSampleSize;\n    RECT        rcFrame;\n}\n\nenum {\n    AVIIF_FIRSTPART = 0x00000020L,\n    AVIIF_LASTPART  = 0x00000040L,\n    AVIIF_MIDPART   = (AVIIF_LASTPART|AVIIF_FIRSTPART),\n    AVIIF_NOTIME    = 0x00000100L,\n    AVIIF_COMPUSE   = 0x0FFF0000L,\n}\n\nstruct AVIINDEXENTRY {\n    DWORD       ckid;\n    DWORD       dwFlags;\n    DWORD       dwChunkOffset;\n    DWORD       dwChunkLength;\n}\n\nstruct AVIPALCHANGE {\n    BYTE        bFirstEntry;\n    BYTE        bNumEntries;\n    WORD        wFlags;\n    PALETTEENTRY[1] _peNew;\n    PALETTEENTRY* peNew() return { return _peNew.ptr; }\n}\n\nenum AVIGETFRAMEF_BESTDISPLAYFMT = 1;\n\nstruct AVISTREAMINFOW {\n    DWORD   fccType;\n    DWORD   fccHandler;\n    DWORD   dwFlags;\n    DWORD   dwCaps;\n    WORD    wPriority;\n    WORD    wLanguage;\n    DWORD   dwScale;\n    DWORD   dwRate;\n    DWORD   dwStart;\n    DWORD   dwLength;\n    DWORD   dwInitialFrames;\n    DWORD   dwSuggestedBufferSize;\n    DWORD   dwQuality;\n    DWORD   dwSampleSize;\n    RECT    rcFrame;\n    DWORD   dwEditCount;\n    DWORD   dwFormatChangeCount;\n    WCHAR[64]   szName;\n}\nalias AVISTREAMINFOW* LPAVISTREAMINFOW;\n\nstruct AVISTREAMINFOA {\n    DWORD   fccType;\n    DWORD   fccHandler;\n    DWORD   dwFlags;\n    DWORD   dwCaps;\n    WORD    wPriority;\n    WORD    wLanguage;\n    DWORD   dwScale;\n    DWORD   dwRate;\n    DWORD   dwStart;\n    DWORD   dwLength;\n    DWORD   dwInitialFrames;\n    DWORD   dwSuggestedBufferSize;\n    DWORD   dwQuality;\n    DWORD   dwSampleSize;\n    RECT    rcFrame;\n    DWORD   dwEditCount;\n    DWORD   dwFormatChangeCount;\n    char[64]    szName;\n}\nalias AVISTREAMINFOA* LPAVISTREAMINFOA;\n\nversion (Unicode) {\n    alias AVISTREAMINFOW    AVISTREAMINFO;\n    alias LPAVISTREAMINFOW  LPAVISTREAMINFO;\n} else { // Unicode\n    alias AVISTREAMINFOA    AVISTREAMINFO;\n    alias LPAVISTREAMINFOA  LPAVISTREAMINFO;\n}\n\nenum AVISTREAMINFO_DISABLED        = 0x00000001;\nenum AVISTREAMINFO_FORMATCHANGES   = 0x00010000;\n\nstruct AVIFILEINFOW {\n    DWORD   dwMaxBytesPerSec;\n    DWORD   dwFlags;\n    DWORD   dwCaps;\n    DWORD   dwStreams;\n    DWORD   dwSuggestedBufferSize;\n    DWORD   dwWidth;\n    DWORD   dwHeight;\n    DWORD   dwScale;\n    DWORD   dwRate;\n    DWORD   dwLength;\n    DWORD   dwEditCount;\n    WCHAR[64]   szFileType;\n}\nalias AVIFILEINFOW* LPAVIFILEINFOW;\n\nstruct AVIFILEINFOA {\n    DWORD   dwMaxBytesPerSec;\n    DWORD   dwFlags;\n    DWORD   dwCaps;\n    DWORD   dwStreams;\n    DWORD   dwSuggestedBufferSize;\n    DWORD   dwWidth;\n    DWORD   dwHeight;\n    DWORD   dwScale;\n    DWORD   dwRate;\n    DWORD   dwLength;\n    DWORD   dwEditCount;\n    char[64]    szFileType;\n}\nalias AVIFILEINFOA* LPAVIFILEINFOA;\n\nversion (Unicode) {\n    alias AVIFILEINFOW  AVIFILEINFO;\n    alias LPAVIFILEINFOW    LPAVIFILEINFO;\n} else { // Unicode\n    alias AVIFILEINFOA  AVIFILEINFO;\n    alias LPAVIFILEINFOA    LPAVIFILEINFO;\n}\n\nenum {\n    AVIFILEINFO_HASINDEX        = 0x00000010,\n    AVIFILEINFO_MUSTUSEINDEX    = 0x00000020,\n    AVIFILEINFO_ISINTERLEAVED   = 0x00000100,\n    AVIFILEINFO_WASCAPTUREFILE  = 0x00010000,\n    AVIFILEINFO_COPYRIGHTED     = 0x00020000,\n}\n\nenum {\n    AVIFILECAPS_CANREAD         = 0x00000001,\n    AVIFILECAPS_CANWRITE        = 0x00000002,\n    AVIFILECAPS_ALLKEYFRAMES    = 0x00000010,\n    AVIFILECAPS_NOCOMPRESSION   = 0x00000020,\n}\n\nextern (Windows) {\n    alias BOOL function(int) AVISAVECALLBACK;\n}\n\nstruct AVICOMPRESSOPTIONS {\n    DWORD   fccType;\n    DWORD   fccHandler;\n    DWORD   dwKeyFrameEvery;\n    DWORD   dwQuality;\n    DWORD   dwBytesPerSecond;\n    DWORD   dwFlags;\n    LPVOID  lpFormat;\n    DWORD   cbFormat;\n    LPVOID  lpParms;\n    DWORD   cbParms;\n    DWORD   dwInterleaveEvery;\n}\nalias AVICOMPRESSOPTIONS* LPAVICOMPRESSOPTIONS;\n\nenum {\n    AVICOMPRESSF_INTERLEAVE = 0x00000001,\n    AVICOMPRESSF_DATARATE   = 0x00000002,\n    AVICOMPRESSF_KEYFRAMES  = 0x00000004,\n    AVICOMPRESSF_VALID      = 0x00000008,\n}\n\n/+ TODO:\nDECLARE_INTERFACE_(IAVIStream, IUnknown)\n{\n    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;\n    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;\n    STDMETHOD_(ULONG,Release) (THIS) PURE;\n\n    STDMETHOD(Create)      (THIS_ LPARAM lParam1, LPARAM lParam2) PURE ;\n    STDMETHOD(Info)        (THIS_ AVISTREAMINFOW FAR * psi, LONG lSize) PURE ;\n    STDMETHOD_(LONG, FindSample)(THIS_ LONG lPos, LONG lFlags) PURE ;\n    STDMETHOD(ReadFormat)  (THIS_ LONG lPos,\n                LPVOID lpFormat, LONG FAR *lpcbFormat) PURE ;\n    STDMETHOD(SetFormat)   (THIS_ LONG lPos,\n                LPVOID lpFormat, LONG cbFormat) PURE ;\n    STDMETHOD(Read)        (THIS_ LONG lStart, LONG lSamples,\n                LPVOID lpBuffer, LONG cbBuffer,\n                LONG FAR * plBytes, LONG FAR * plSamples) PURE ;\n    STDMETHOD(Write)       (THIS_ LONG lStart, LONG lSamples,\n                LPVOID lpBuffer, LONG cbBuffer,\n                DWORD dwFlags,\n                LONG FAR *plSampWritten,\n                LONG FAR *plBytesWritten) PURE ;\n    STDMETHOD(Delete)      (THIS_ LONG lStart, LONG lSamples) PURE;\n    STDMETHOD(ReadData)    (THIS_ DWORD fcc, LPVOID lp, LONG FAR *lpcb) PURE ;\n    STDMETHOD(WriteData)   (THIS_ DWORD fcc, LPVOID lp, LONG cb) PURE ;\n#ifdef _WIN32\n    STDMETHOD(SetInfo) (THIS_ AVISTREAMINFOW FAR * lpInfo,\n                LONG cbInfo) PURE;\n#else\n    STDMETHOD(Reserved1)            (THIS) PURE;\n    STDMETHOD(Reserved2)            (THIS) PURE;\n    STDMETHOD(Reserved3)            (THIS) PURE;\n    STDMETHOD(Reserved4)            (THIS) PURE;\n    STDMETHOD(Reserved5)            (THIS) PURE;\n#endif\n};\n\nalias TypeDef!(IAVIStream FAR*) PAVISTREAM;\n\n#undef  INTERFACE\n#define INTERFACE   IAVIStreaming\n\nDECLARE_INTERFACE_(IAVIStreaming, IUnknown)\n{\n    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;\n    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;\n    STDMETHOD_(ULONG,Release) (THIS) PURE;\n\n    STDMETHOD(Begin) (THIS_\n              LONG  lStart,\n              LONG  lEnd,\n              LONG  lRate) PURE;\n    STDMETHOD(End)   (THIS) PURE;\n};\n\nalias TypeDef!(IAVIStreaming FAR*) PAVISTREAMING;\n\n\n#undef  INTERFACE\n#define INTERFACE   IAVIEditStream\n\nDECLARE_INTERFACE_(IAVIEditStream, IUnknown)\n{\n    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;\n    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;\n    STDMETHOD_(ULONG,Release) (THIS) PURE;\n\n    STDMETHOD(Cut) (THIS_ LONG FAR *plStart,\n              LONG FAR *plLength,\n              PAVISTREAM FAR * ppResult) PURE;\n    STDMETHOD(Copy) (THIS_ LONG FAR *plStart,\n               LONG FAR *plLength,\n               PAVISTREAM FAR * ppResult) PURE;\n    STDMETHOD(Paste) (THIS_ LONG FAR *plPos,\n                LONG FAR *plLength,\n                PAVISTREAM pstream,\n                LONG lStart,\n                LONG lEnd) PURE;\n    STDMETHOD(Clone) (THIS_ PAVISTREAM FAR *ppResult) PURE;\n    STDMETHOD(SetInfo) (THIS_ AVISTREAMINFOW FAR * lpInfo,\n                LONG cbInfo) PURE;\n};\n\nalias TypeDef!(IAVIEditStream FAR*) PAVIEDITSTREAM;\n\n#undef  INTERFACE\n#define INTERFACE   IAVIPersistFile\n\nDECLARE_INTERFACE_(IAVIPersistFile, IPersistFile)\n{\n    STDMETHOD(Reserved1)(THIS) PURE;\n};\n\nalias TypeDef!(IAVIPersistFile FAR*) PAVIPERSISTFILE;\n\n#undef  INTERFACE\n#define INTERFACE   IAVIFile\n#define PAVIFILE IAVIFile FAR*\n\nDECLARE_INTERFACE_(IAVIFile, IUnknown)\n{\n    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;\n    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;\n    STDMETHOD_(ULONG,Release) (THIS) PURE;\n\n    STDMETHOD(Info)                 (THIS_\n                                     AVIFILEINFOW FAR * pfi,\n                                     LONG lSize) PURE;\n    STDMETHOD(GetStream)            (THIS_\n                                     PAVISTREAM FAR * ppStream,\n                     DWORD fccType,\n                                     LONG lParam) PURE;\n    STDMETHOD(CreateStream)         (THIS_\n                                     PAVISTREAM FAR * ppStream,\n                                     AVISTREAMINFOW FAR * psi) PURE;\n    STDMETHOD(WriteData)            (THIS_\n                                     DWORD ckid,\n                                     LPVOID lpData,\n                                     LONG cbData) PURE;\n    STDMETHOD(ReadData)             (THIS_\n                                     DWORD ckid,\n                                     LPVOID lpData,\n                                     LONG FAR *lpcbData) PURE;\n    STDMETHOD(EndRecord)            (THIS) PURE;\n    STDMETHOD(DeleteStream)         (THIS_\n                     DWORD fccType,\n                                     LONG lParam) PURE;\n};\n\n#undef PAVIFILE\nalias TypeDef!(IAVIFile FAR*) PAVIFILE;\n\n#undef  INTERFACE\n#define INTERFACE   IGetFrame\n#define PGETFRAME   IGetFrame FAR*\n\nDECLARE_INTERFACE_(IGetFrame, IUnknown)\n{\n    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;\n    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;\n    STDMETHOD_(ULONG,Release) (THIS) PURE;\n\n    STDMETHOD_(LPVOID,GetFrame) (THIS_ LONG lPos) PURE;\n\n    STDMETHOD(Begin) (THIS_ LONG lStart, LONG lEnd, LONG lRate) PURE;\n    STDMETHOD(End) (THIS) PURE;\n\n    STDMETHOD(SetFormat) (THIS_ LPBITMAPINFOHEADER lpbi, LPVOID lpBits, int x, int y, int dx, int dy) PURE;\n};\n\n#undef PGETFRAME\nalias TypeDef!(IGetFrame FAR*) PGETFRAME;\n\n#define DEFINE_AVIGUID(name, l, w1, w2)    DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46)\n\nDEFINE_AVIGUID(IID_IAVIFile,            0x00020020, 0, 0);\nDEFINE_AVIGUID(IID_IAVIStream,          0x00020021, 0, 0);\nDEFINE_AVIGUID(IID_IAVIStreaming,       0x00020022, 0, 0);\nDEFINE_AVIGUID(IID_IGetFrame,           0x00020023, 0, 0);\nDEFINE_AVIGUID(IID_IAVIEditStream,      0x00020024, 0, 0);\nDEFINE_AVIGUID(IID_IAVIPersistFile,     0x00020025, 0, 0);\n#ifndef UNICODE\nDEFINE_AVIGUID(CLSID_AVISimpleUnMarshal,        0x00020009, 0, 0);\n#endif\n\nDEFINE_AVIGUID(CLSID_AVIFile,           0x00020000, 0, 0);\n\n#define AVIFILEHANDLER_CANREAD      0x0001\n#define AVIFILEHANDLER_CANWRITE     0x0002\n#define AVIFILEHANDLER_CANACCEPTNONRGB  0x0004\n\nSTDAPI_(void) AVIFileInit(void);\nSTDAPI_(void) AVIFileExit(void);\n\nSTDAPI_(ULONG) AVIFileAddRef       (PAVIFILE pfile);\nSTDAPI_(ULONG) AVIFileRelease      (PAVIFILE pfile);\n\n#ifdef _WIN32\nSTDAPI AVIFileOpenA       (PAVIFILE FAR * ppfile, LPCSTR szFile,\n              UINT uMode, LPCLSID lpHandler);\nSTDAPI AVIFileOpenW       (PAVIFILE FAR * ppfile, LPCWSTR szFile,\n              UINT uMode, LPCLSID lpHandler);\n#ifdef UNICODE\n#define AVIFileOpen   AVIFileOpenW\n#else\n#define AVIFileOpen   AVIFileOpenA\n#endif\n#else\nSTDAPI AVIFileOpen       (PAVIFILE FAR * ppfile, LPCSTR szFile,\n              UINT uMode, LPCLSID lpHandler);\n#define AVIFileOpenW    AVIFileOpen\n#endif\n\n#ifdef _WIN32\nSTDAPI AVIFileInfoW (PAVIFILE pfile, LPAVIFILEINFOW pfi, LONG lSize);\nSTDAPI AVIFileInfoA (PAVIFILE pfile, LPAVIFILEINFOA pfi, LONG lSize);\n#ifdef UNICODE\n#define AVIFileInfo AVIFileInfoW\n#else\n#define AVIFileInfo AVIFileInfoA\n#endif\n#else\nSTDAPI AVIFileInfo (PAVIFILE pfile, LPAVIFILEINFO pfi, LONG lSize);\n#define AVIFileInfoW AVIFileInfo\n#endif\n\n\nSTDAPI AVIFileGetStream     (PAVIFILE pfile, PAVISTREAM FAR * ppavi, DWORD fccType, LONG lParam);\n\n\n#ifdef _WIN32\nSTDAPI AVIFileCreateStreamW (PAVIFILE pfile, PAVISTREAM FAR *ppavi, AVISTREAMINFOW FAR * psi);\nSTDAPI AVIFileCreateStreamA (PAVIFILE pfile, PAVISTREAM FAR *ppavi, AVISTREAMINFOA FAR * psi);\n#ifdef UNICODE\n#define AVIFileCreateStream AVIFileCreateStreamW\n#else\n#define AVIFileCreateStream AVIFileCreateStreamA\n#endif\n#else\nSTDAPI AVIFileCreateStream(PAVIFILE pfile, PAVISTREAM FAR *ppavi, AVISTREAMINFO FAR * psi);\n#define AVIFileCreateStreamW AVIFileCreateStream\n#endif\n\nSTDAPI AVIFileWriteData (PAVIFILE pfile,\n                     DWORD ckid,\n                     LPVOID lpData,\n                     LONG cbData);\nSTDAPI AVIFileReadData  (PAVIFILE pfile,\n                     DWORD ckid,\n                     LPVOID lpData,\n                     LONG FAR *lpcbData);\nSTDAPI AVIFileEndRecord (PAVIFILE pfile);\n\nSTDAPI_(ULONG) AVIStreamAddRef       (PAVISTREAM pavi);\nSTDAPI_(ULONG) AVIStreamRelease      (PAVISTREAM pavi);\n\nSTDAPI AVIStreamInfoW (PAVISTREAM pavi, LPAVISTREAMINFOW psi, LONG lSize);\nSTDAPI AVIStreamInfoA (PAVISTREAM pavi, LPAVISTREAMINFOA psi, LONG lSize);\n#ifdef UNICODE\n#define AVIStreamInfo   AVIStreamInfoW\n#else\n#define AVIStreamInfo   AVIStreamInfoA\n#endif\n\nSTDAPI_(LONG) AVIStreamFindSample(PAVISTREAM pavi, LONG lPos, LONG lFlags);\nSTDAPI AVIStreamReadFormat   (PAVISTREAM pavi, LONG lPos,LPVOID lpFormat,LONG FAR *lpcbFormat);\nSTDAPI AVIStreamSetFormat    (PAVISTREAM pavi, LONG lPos,LPVOID lpFormat,LONG cbFormat);\nSTDAPI AVIStreamReadData     (PAVISTREAM pavi, DWORD fcc, LPVOID lp, LONG FAR *lpcb);\nSTDAPI AVIStreamWriteData    (PAVISTREAM pavi, DWORD fcc, LPVOID lp, LONG cb);\n\nSTDAPI AVIStreamRead         (PAVISTREAM pavi,\n                  LONG lStart,\n                  LONG lSamples,\n                  LPVOID lpBuffer,\n                  LONG cbBuffer,\n                  LONG FAR * plBytes,\n                  LONG FAR * plSamples);\n#define AVISTREAMREAD_CONVENIENT    (-1L)\n\nSTDAPI AVIStreamWrite        (PAVISTREAM pavi,\n                  LONG lStart, LONG lSamples,\n                  LPVOID lpBuffer, LONG cbBuffer, DWORD dwFlags,\n                  LONG FAR *plSampWritten,\n                  LONG FAR *plBytesWritten);\n\nSTDAPI_(LONG) AVIStreamStart        (PAVISTREAM pavi);\nSTDAPI_(LONG) AVIStreamLength       (PAVISTREAM pavi);\nSTDAPI_(LONG) AVIStreamTimeToSample (PAVISTREAM pavi, LONG lTime);\nSTDAPI_(LONG) AVIStreamSampleToTime (PAVISTREAM pavi, LONG lSample);\n\n\nSTDAPI AVIStreamBeginStreaming(PAVISTREAM pavi, LONG lStart, LONG lEnd, LONG lRate);\nSTDAPI AVIStreamEndStreaming(PAVISTREAM pavi);\n\nSTDAPI_(PGETFRAME) AVIStreamGetFrameOpen(PAVISTREAM pavi,\n                     LPBITMAPINFOHEADER lpbiWanted);\nSTDAPI_(LPVOID) AVIStreamGetFrame(PGETFRAME pg, LONG lPos);\nSTDAPI AVIStreamGetFrameClose(PGETFRAME pg);\n\nSTDAPI AVIStreamOpenFromFileA(PAVISTREAM FAR *ppavi, LPCSTR szFile,\n                 DWORD fccType, LONG lParam,\n                 UINT mode, CLSID FAR *pclsidHandler);\nSTDAPI AVIStreamOpenFromFileW(PAVISTREAM FAR *ppavi, LPCWSTR szFile,\n                 DWORD fccType, LONG lParam,\n                 UINT mode, CLSID FAR *pclsidHandler);\n#ifdef UNICODE\n#define AVIStreamOpenFromFile   AVIStreamOpenFromFileW\n#else\n#define AVIStreamOpenFromFile   AVIStreamOpenFromFileA\n#endif\n\nSTDAPI AVIStreamCreate(PAVISTREAM FAR *ppavi, LONG lParam1, LONG lParam2,\n               CLSID FAR *pclsidHandler);\n\n\n\n#define FIND_DIR        0x0000000FL\n#define FIND_NEXT       0x00000001L\n#define FIND_PREV       0x00000004L\n#define FIND_FROM_START 0x00000008L\n\n#define FIND_TYPE       0x000000F0L\n#define FIND_KEY        0x00000010L\n#define FIND_ANY        0x00000020L\n#define FIND_FORMAT     0x00000040L\n\n#define FIND_RET        0x0000F000L\n#define FIND_POS        0x00000000L\n#define FIND_LENGTH     0x00001000L\n#define FIND_OFFSET     0x00002000L\n#define FIND_SIZE       0x00003000L\n#define FIND_INDEX      0x00004000L\n\n#define AVIStreamFindKeyFrame AVIStreamFindSample\n#define FindKeyFrame    FindSample\n\n#define AVIStreamClose AVIStreamRelease\n#define AVIFileClose   AVIFileRelease\n#define AVIStreamInit  AVIFileInit\n#define AVIStreamExit  AVIFileExit\n\n#define SEARCH_NEAREST  FIND_PREV\n#define SEARCH_BACKWARD FIND_PREV\n#define SEARCH_FORWARD  FIND_NEXT\n#define SEARCH_KEY      FIND_KEY\n#define SEARCH_ANY      FIND_ANY\n\n#define     AVIStreamSampleToSample(pavi1, pavi2, l)            AVIStreamTimeToSample(pavi1,AVIStreamSampleToTime(pavi2, l))\n\n#define     AVIStreamNextSample(pavi, l)            AVIStreamFindSample(pavi,l+1,FIND_NEXT|FIND_ANY)\n\n#define     AVIStreamPrevSample(pavi, l)            AVIStreamFindSample(pavi,l-1,FIND_PREV|FIND_ANY)\n\n#define     AVIStreamNearestSample(pavi, l)            AVIStreamFindSample(pavi,l,FIND_PREV|FIND_ANY)\n\n#define     AVIStreamNextKeyFrame(pavi,l)            AVIStreamFindSample(pavi,l+1,FIND_NEXT|FIND_KEY)\n\n#define     AVIStreamPrevKeyFrame(pavi, l)            AVIStreamFindSample(pavi,l-1,FIND_PREV|FIND_KEY)\n\n#define     AVIStreamNearestKeyFrame(pavi, l)            AVIStreamFindSample(pavi,l,FIND_PREV|FIND_KEY)\n\n#define     AVIStreamIsKeyFrame(pavi, l)            (AVIStreamNearestKeyFrame(pavi,l) == l)\n\n#define     AVIStreamPrevSampleTime(pavi, t)            AVIStreamSampleToTime(pavi, AVIStreamPrevSample(pavi,AVIStreamTimeToSample(pavi,t)))\n\n#define     AVIStreamNextSampleTime(pavi, t)            AVIStreamSampleToTime(pavi, AVIStreamNextSample(pavi,AVIStreamTimeToSample(pavi,t)))\n\n#define     AVIStreamNearestSampleTime(pavi, t)            AVIStreamSampleToTime(pavi, AVIStreamNearestSample(pavi,AVIStreamTimeToSample(pavi,t)))\n\n#define     AVIStreamNextKeyFrameTime(pavi, t)            AVIStreamSampleToTime(pavi, AVIStreamNextKeyFrame(pavi,AVIStreamTimeToSample(pavi, t)))\n\n#define     AVIStreamPrevKeyFrameTime(pavi, t)            AVIStreamSampleToTime(pavi, AVIStreamPrevKeyFrame(pavi,AVIStreamTimeToSample(pavi, t)))\n\n#define     AVIStreamNearestKeyFrameTime(pavi, t)            AVIStreamSampleToTime(pavi, AVIStreamNearestKeyFrame(pavi,AVIStreamTimeToSample(pavi, t)))\n\n#define     AVIStreamStartTime(pavi)            AVIStreamSampleToTime(pavi, AVIStreamStart(pavi))\n\n#define     AVIStreamLengthTime(pavi)            AVIStreamSampleToTime(pavi, AVIStreamLength(pavi))\n\n#define     AVIStreamEnd(pavi)            (AVIStreamStart(pavi) + AVIStreamLength(pavi))\n\n#define     AVIStreamEndTime(pavi)            AVIStreamSampleToTime(pavi, AVIStreamEnd(pavi))\n\n#define     AVIStreamSampleSize(pavi, lPos, plSize)     AVIStreamRead(pavi,lPos,1,NULL,0,plSize,NULL)\n\n#define     AVIStreamFormatSize(pavi, lPos, plSize)            AVIStreamReadFormat(pavi,lPos,NULL,plSize)\n\n#define     AVIStreamDataSize(pavi, fcc, plSize)            AVIStreamReadData(pavi,fcc,NULL,plSize)\n\n#ifndef comptypeDIB\n#define comptypeDIB         mmioFOURCC('D', 'I', 'B', ' ')\n#endif\n\nSTDAPI AVIMakeCompressedStream(\n        PAVISTREAM FAR *        ppsCompressed,\n        PAVISTREAM          ppsSource,\n        AVICOMPRESSOPTIONS FAR *    lpOptions,\n        CLSID FAR *pclsidHandler);\n\nEXTERN_C HRESULT CDECL AVISaveA (LPCSTR               szFile,\n        CLSID FAR *pclsidHandler,\n        AVISAVECALLBACK     lpfnCallback,\n        int                 nStreams,\n        PAVISTREAM      pfile,\n        LPAVICOMPRESSOPTIONS lpOptions,\n        ...);\n\nSTDAPI AVISaveVA(LPCSTR               szFile,\n        CLSID FAR *pclsidHandler,\n        AVISAVECALLBACK     lpfnCallback,\n        int                 nStreams,\n        PAVISTREAM FAR *    ppavi,\n        LPAVICOMPRESSOPTIONS FAR *plpOptions);\nEXTERN_C HRESULT CDECL AVISaveW (LPCWSTR               szFile,\n        CLSID FAR *pclsidHandler,\n        AVISAVECALLBACK     lpfnCallback,\n        int                 nStreams,\n        PAVISTREAM      pfile,\n        LPAVICOMPRESSOPTIONS lpOptions,\n        ...);\n\nSTDAPI AVISaveVW(LPCWSTR               szFile,\n        CLSID FAR *pclsidHandler,\n        AVISAVECALLBACK     lpfnCallback,\n        int                 nStreams,\n        PAVISTREAM FAR *    ppavi,\n        LPAVICOMPRESSOPTIONS FAR *plpOptions);\n#ifdef UNICODE\n#define AVISave     AVISaveW\n#define AVISaveV    AVISaveVW\n#else\n#define AVISave     AVISaveA\n#define AVISaveV    AVISaveVA\n#endif\n\n\n\nSTDAPI_(INT_PTR) AVISaveOptions(HWND hwnd,\n                 UINT   uiFlags,\n                 int    nStreams,\n                 PAVISTREAM FAR *ppavi,\n                 LPAVICOMPRESSOPTIONS FAR *plpOptions);\n\nSTDAPI AVISaveOptionsFree(int nStreams,\n                 LPAVICOMPRESSOPTIONS FAR *plpOptions);\n\nSTDAPI AVIBuildFilterW(LPWSTR lpszFilter, LONG cbFilter, BOOL fSaving);\nSTDAPI AVIBuildFilterA(LPSTR lpszFilter, LONG cbFilter, BOOL fSaving);\n#ifdef UNICODE\n#define AVIBuildFilter  AVIBuildFilterW\n#else\n#define AVIBuildFilter  AVIBuildFilterA\n#endif\nSTDAPI AVIMakeFileFromStreams(PAVIFILE FAR *    ppfile,\n                   int      nStreams,\n                   PAVISTREAM FAR * papStreams);\n\nSTDAPI AVIMakeStreamFromClipboard(UINT cfFormat, HANDLE hGlobal, PAVISTREAM FAR *ppstream);\n\nSTDAPI AVIPutFileOnClipboard(PAVIFILE pf);\n\nSTDAPI AVIGetFromClipboard(PAVIFILE FAR * lppf);\n\nSTDAPI AVIClearClipboard(void);\n\nSTDAPI CreateEditableStream(\n        PAVISTREAM FAR *        ppsEditable,\n        PAVISTREAM          psSource);\n\nSTDAPI EditStreamCut(PAVISTREAM pavi, LONG FAR *plStart, LONG FAR *plLength, PAVISTREAM FAR * ppResult);\n\nSTDAPI EditStreamCopy(PAVISTREAM pavi, LONG FAR *plStart, LONG FAR *plLength, PAVISTREAM FAR * ppResult);\n\nSTDAPI EditStreamPaste(PAVISTREAM pavi, LONG FAR *plPos, LONG FAR *plLength, PAVISTREAM pstream, LONG lStart, LONG lEnd);\n\nSTDAPI EditStreamClone(PAVISTREAM pavi, PAVISTREAM FAR *ppResult);\n\n\nSTDAPI EditStreamSetNameA(PAVISTREAM pavi, LPCSTR lpszName);\nSTDAPI EditStreamSetNameW(PAVISTREAM pavi, LPCWSTR lpszName);\nSTDAPI EditStreamSetInfoW(PAVISTREAM pavi, LPAVISTREAMINFOW lpInfo, LONG cbInfo);\nSTDAPI EditStreamSetInfoA(PAVISTREAM pavi, LPAVISTREAMINFOA lpInfo, LONG cbInfo);\n#ifdef UNICODE\n#define EditStreamSetInfo   EditStreamSetInfoW\n#define EditStreamSetName   EditStreamSetNameW\n#else\n#define EditStreamSetInfo   EditStreamSetInfoA\n#define EditStreamSetName   EditStreamSetNameA\n#endif\n+/\nenum AVIERR_OK = 0L;\n\nSCODE MAKE_AVIERR(DWORD error) {\n    return MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, 0x4000 + error);\n}\n\nenum AVIERR_UNSUPPORTED    = MAKE_AVIERR(101);\nenum AVIERR_BADFORMAT      = MAKE_AVIERR(102);\nenum AVIERR_MEMORY         = MAKE_AVIERR(103);\nenum AVIERR_INTERNAL       = MAKE_AVIERR(104);\nenum AVIERR_BADFLAGS       = MAKE_AVIERR(105);\nenum AVIERR_BADPARAM       = MAKE_AVIERR(106);\nenum AVIERR_BADSIZE        = MAKE_AVIERR(107);\nenum AVIERR_BADHANDLE      = MAKE_AVIERR(108);\nenum AVIERR_FILEREAD       = MAKE_AVIERR(109);\nenum AVIERR_FILEWRITE      = MAKE_AVIERR(110);\nenum AVIERR_FILEOPEN       = MAKE_AVIERR(111);\nenum AVIERR_COMPRESSOR     = MAKE_AVIERR(112);\nenum AVIERR_NOCOMPRESSOR   = MAKE_AVIERR(113);\nenum AVIERR_READONLY       = MAKE_AVIERR(114);\nenum AVIERR_NODATA         = MAKE_AVIERR(115);\nenum AVIERR_BUFFERTOOSMALL = MAKE_AVIERR(116);\nenum AVIERR_CANTCOMPRESS   = MAKE_AVIERR(117);\nenum AVIERR_USERABORT      = MAKE_AVIERR(198);\nenum AVIERR_ERROR          = MAKE_AVIERR(199);\n\nconst TCHAR[] MCIWND_WINDOW_CLASS = \"MCIWndClass\";\n\nextern (Windows) {\n    HWND MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance, DWORD dwStyle, LPCSTR szFile);\n    HWND MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance, DWORD dwStyle, LPCWSTR szFile);\n}\n\nversion (Unicode) {\n    alias MCIWndCreateW MCIWndCreate;\n} else { // Unicode\n    alias MCIWndCreateA MCIWndCreate;\n}\n\nextern(Windows) {\n    BOOL MCIWndRegisterClass();\n}\n\nenum {\n    MCIWNDOPENF_NEW             = 0x0001,\n    MCIWNDF_NOAUTOSIZEWINDOW    = 0x0001,\n    MCIWNDF_NOPLAYBAR           = 0x0002,\n    MCIWNDF_NOAUTOSIZEMOVIE     = 0x0004,\n    MCIWNDF_NOMENU              = 0x0008,\n    MCIWNDF_SHOWNAME            = 0x0010,\n    MCIWNDF_SHOWPOS             = 0x0020,\n    MCIWNDF_SHOWMODE            = 0x0040,\n    MCIWNDF_SHOWALL             = 0x0070,\n    MCIWNDF_NOTIFYMODE          = 0x0100,\n    MCIWNDF_NOTIFYPOS           = 0x0200,\n    MCIWNDF_NOTIFYSIZE          = 0x0400,\n    MCIWNDF_NOTIFYERROR         = 0x1000,\n    MCIWNDF_NOTIFYALL           = 0x1F00,\n    MCIWNDF_NOTIFYANSI          = 0x0080,\n    MCIWNDF_NOTIFYMEDIAA        = 0x0880,\n    MCIWNDF_NOTIFYMEDIAW        = 0x0800,\n}\n\nversion (Unicode) {\n    alias MCIWNDF_NOTIFYMEDIAW  MCIWNDF_NOTIFYMEDIA;\n} else { // Unicode\n    alias MCIWNDF_NOTIFYMEDIAA  MCIWNDF_NOTIFYMEDIA;\n}\n\nenum {\n    MCIWNDF_RECORD      = 0x2000,\n    MCIWNDF_NOERRORDLG  = 0x4000,\n    MCIWNDF_NOOPEN      = 0x8000,\n}\n\n// can macros\n\nBOOL MCIWndCanPlay(HWND hwnd)\n    { return cast(BOOL)SendMessage(hwnd, MCIWNDM_CAN_PLAY, 0, 0); }\nBOOL MCIWndCanRecord(HWND hwnd)\n    { return cast(BOOL)SendMessage(hwnd, MCIWNDM_CAN_RECORD, 0, 0); }\nBOOL MCIWndCanSave(HWND hwnd)\n    { return cast(BOOL)SendMessage(hwnd, MCIWNDM_CAN_SAVE, 0, 0); }\nBOOL MCIWndCanWindow(HWND hwnd)\n    { return cast(BOOL)SendMessage(hwnd, MCIWNDM_CAN_WINDOW, 0, 0); }\nBOOL MCIWndCanEject(HWND hwnd)\n    { return cast(BOOL)SendMessage(hwnd, MCIWNDM_CAN_EJECT, 0, 0); }\nBOOL MCIWndCanConfig(HWND hwnd)\n    { return cast(BOOL)SendMessage(hwnd, MCIWNDM_CAN_CONFIG, 0, 0); }\nBOOL MCIWndPaletteKick(HWND hwnd)\n    { return cast(BOOL)SendMessage(hwnd, MCIWNDM_PALETTEKICK, 0, 0); }\nLONG MCIWndSave(HWND hwnd, LPVOID szFile)\n    { return cast(LONG)SendMessage(hwnd, MCI_SAVE, 0, cast(LPARAM)szFile); }\nLONG MCIWndSaveDialog(HWND hwnd)\n    { return MCIWndSave(hwnd, cast(LPVOID)-1); }\nLONG MCIWndNew(HWND hwnd, LPVOID lp)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_NEW, 0, cast(LPARAM)lp); }\nLONG MCIWndRecord(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCI_RECORD, 0, 0); }\nLONG MCIWndOpen(HWND hwnd, LPVOID sz, UINT f)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_OPEN, cast(WPARAM)f, cast(LPARAM)sz); }\nLONG MCIWndOpenDialog(HWND hwnd)\n    { return MCIWndOpen(hwnd, cast(LPVOID)-1, 0); }\nLONG MCIWndClose(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCI_CLOSE, 0, 0); }\nLONG MCIWndPlay(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCI_PLAY, 0, 0); }\nLONG MCIWndStop(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCI_STOP, 0, 0); }\nLONG MCIWndPause(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCI_PAUSE, 0, 0); }\nLONG MCIWndResume(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCI_RESUME, 0, 0); }\nLONG MCIWndSeek(HWND hwnd, LONG lPos)\n    { return cast(LONG)SendMessage(hwnd, MCI_SEEK, 0, cast(LPARAM)lPos); }\nLONG MCIWndHome(HWND hwnd)\n    { return MCIWndSeek(hwnd, MCIWND_START); }\nLONG MCIWndEnd(HWND hwnd)\n    { return MCIWndSeek(hwnd, MCIWND_END); }\nLONG MCIWndEject(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_EJECT, 0, 0); }\nLONG MCIWndGetSource(HWND hwnd, LPRECT prc)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_GET_SOURCE, 0, cast(LPARAM)prc); }\nLONG MCIWndPutSource(HWND hwnd, LPRECT prc)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_PUT_SOURCE, 0, cast(LPARAM)prc); }\nLONG MCIWndGetDest(HWND hwnd, LPRECT prc)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_GET_DEST, 0, cast(LPARAM)prc); }\nLONG MCIWndPutDest(HWND hwnd, LPRECT prc)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_PUT_DEST, 0, cast(LPARAM)prc); }\nLONG MCIWndPlayReverse(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_PLAYREVERSE, 0, 0); }\nLONG MCIWndPlayFrom(HWND hwnd, LONG lPos)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_PLAYFROM, 0, cast(LPARAM)lPos); }\nLONG MCIWndPlayTo(HWND hwnd, LONG lPos)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_PLAYTO, 0, cast(LPARAM)lPos); }\nLONG MCIWndPlayFromTo(HWND hwnd, LONG lStart, LONG lEnd)\n    { MCIWndSeek(hwnd, lStart); return MCIWndPlayTo(hwnd, lEnd); }\nUINT MCIWndGetDeviceID(HWND hwnd)\n    { return cast(UINT)SendMessage(hwnd, MCIWNDM_GETDEVICEID, 0, 0); }\nUINT MCIWndGetAlias(HWND hwnd)\n    { return cast(UINT)SendMessage(hwnd, MCIWNDM_GETALIAS, 0, 0); }\nLONG MCIWndGetMode(HWND hwnd, LPTSTR lp, UINT len)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_GETMODE, cast(WPARAM)len, cast(LPARAM)lp); }\nLONG MCIWndGetPosition(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_GETPOSITION, 0, 0); }\nLONG MCIWndGetPositionString(HWND hwnd, LPTSTR lp, UINT len)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_GETPOSITION, cast(WPARAM)len, cast(LPARAM)lp); }\nLONG MCIWndGetStart(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_GETSTART, 0, 0); }\nLONG MCIWndGetLength(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_GETLENGTH, 0, 0); }\nLONG MCIWndGetEnd(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_GETEND, 0, 0); }\nLONG MCIWndStep(HWND hwnd, LONG n)\n    { return cast(LONG)SendMessage(hwnd, MCI_STEP, 0, cast(LPARAM)n); }\nvoid MCIWndDestroy(HWND hwnd)\n    { SendMessage(hwnd, WM_CLOSE, 0, 0); }\nvoid MCIWndSetZoom(HWND hwnd, UINT iZoom)\n    { SendMessage(hwnd, MCIWNDM_SETZOOM, 0, cast(LPARAM)iZoom); }\nUINT MCIWndGetZoom(HWND hwnd)\n    { return cast(UINT)SendMessage(hwnd, MCIWNDM_GETZOOM, 0, 0); }\nLONG MCIWndSetVolume(HWND hwnd, UINT iVol)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_SETVOLUME, 0, cast(LPARAM)iVol); }\nLONG MCIWndGetVolume(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_GETVOLUME, 0, 0); }\nLONG MCIWndSetSpeed(HWND hwnd, UINT iSpeed)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_SETSPEED, 0, cast(LPARAM)iSpeed); }\nLONG MCIWndGetSpeed(HWND hwnd)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_GETSPEED, 0, 0); }\nLONG MCIWndSetTimeFormat(HWND hwnd, LPTSTR lp)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_SETTIMEFORMAT, 0, cast(LPARAM)lp); }\nLONG MCIWndUseFrames(HWND hwnd)\n    { return MCIWndSetTimeFormat(hwnd, (cast(TCHAR[])\"frames\").ptr); }\nLONG MCIWndUseTime(HWND hwnd)\n    { return MCIWndSetTimeFormat(hwnd, (cast(TCHAR[])\"ms\").ptr); }\nLONG MCIWndGetTimeFormat(HWND hwnd, LPTSTR lp, UINT len)\n    { return cast(LONG)SendMessage(hwnd, MCIWNDM_GETTIMEFORMAT, cast(WPARAM)len, cast(LPARAM)lp); }\nvoid MCIWndValidateMedia(HWND hwnd)\n    { SendMessage(hwnd, MCIWNDM_VALIDATEMEDIA, 0, 0); }\nvoid MCIWndSetRepeat(HWND hwnd, BOOL f)\n    { SendMessage(hwnd, MCIWNDM_SETREPEAT, 0, cast(LPARAM)f); }\nBOOL MCIWndGetRepeat(HWND hwnd)\n    { return cast(BOOL)SendMessage(hwnd, MCIWNDM_GETREPEAT, 0, 0); }\nvoid MCIWndSetActiveTimer(HWND hwnd, UINT active)\n    { SendMessage(hwnd, MCIWNDM_SETACTIVETIMER, cast(WPARAM)active, 0); }\nvoid MCIWndSetInactiveTimer(HWND hwnd, UINT inactive)\n    { SendMessage(hwnd, MCIWNDM_SETINACTIVETIMER, cast(WPARAM)inactive, 0); }\nvoid MCIWndSetTimers(HWND hwnd, UINT active, UINT inactive)\n    { SendMessage(hwnd, MCIWNDM_SETTIMERS, cast(WPARAM)active, cast(LPARAM)inactive); }\nUINT MCIWndGetActiveTimer(HWND hwnd)\n    { return cast(UINT)SendMessage(hwnd, MCIWNDM_GETACTIVETIMER, 0, 0); }\nUINT MCIWndGetInactiveTimer(HWND hwnd)\n    { return cast(UINT)SendMessage(hwnd, MCIWNDM_GETINACTIVETIMER, 0, 0); }\nLONG MCIWndRealize(HWND hwnd, BOOL fBkgnd)\n    { return cast(LONG) SendMessage(hwnd, MCIWNDM_REALIZE, cast(WPARAM)fBkgnd, 0); }\nLONG MCIWndSendString(HWND hwnd, LPTSTR sz)\n    { return cast(LONG) SendMessage(hwnd, MCIWNDM_SENDSTRING, 0, cast(LPARAM)sz); }\nLONG MCIWndReturnString(HWND hwnd, LPVOID lp, UINT len)\n    { return cast(LONG) SendMessage(hwnd, MCIWNDM_RETURNSTRING, cast(WPARAM)len, cast(LPARAM)lp); }\nLONG MCIWndGetError(HWND hwnd, LPVOID lp, UINT len)\n    { return cast(LONG) SendMessage(hwnd, MCIWNDM_GETERROR, cast(WPARAM)len, cast(LPARAM)lp); }\nHPALETTE MCIWndGetPalette(HWND hwnd)\n    { return cast(HPALETTE)SendMessage(hwnd, MCIWNDM_GETPALETTE, 0, 0); }\nLONG MCIWndSetPalette(HWND hwnd, HPALETTE hpal)\n    { return cast(LONG) SendMessage(hwnd, MCIWNDM_SETPALETTE, cast(WPARAM)hpal, 0); }\nLONG MCIWndGetFileName(HWND hwnd, LPVOID lp, UINT len)\n    { return cast(LONG) SendMessage(hwnd, MCIWNDM_GETFILENAME, cast(WPARAM)len, cast(LPARAM)lp); }\nLONG MCIWndGetDevice(HWND hwnd, LPVOID lp, UINT len)\n    { return cast(LONG) SendMessage(hwnd, MCIWNDM_GETDEVICE, cast(WPARAM)len, cast(LPARAM)lp); }\nUINT MCIWndGetStyles(HWND hwnd)\n    { return cast(UINT) SendMessage(hwnd, MCIWNDM_GETSTYLES, 0, 0); }\nLONG MCIWndChangeStyles(HWND hwnd, UINT mask, LONG value)\n    { return cast(LONG) SendMessage(hwnd, MCIWNDM_CHANGESTYLES, cast(WPARAM)mask, cast(LPARAM)value); }\nLONG MCIWndOpenInterface(HWND hwnd, LPUNKNOWN pUnk)\n    { return cast(LONG) SendMessage(hwnd, MCIWNDM_OPENINTERFACE, 0, cast(LPARAM)cast(void*)pUnk); }\nLONG MCIWndSetOwner(HWND hwnd, HWND hwndP)\n    { return cast(LONG) SendMessage(hwnd, MCIWNDM_SETOWNER, cast(WPARAM)hwndP, 0); }\n\nenum {\n    MCIWNDM_GETDEVICEID         = WM_USER + 100,\n    MCIWNDM_SENDSTRINGA         = WM_USER + 101,\n    MCIWNDM_GETPOSITIONA        = WM_USER + 102,\n    MCIWNDM_GETSTART            = WM_USER + 103,\n    MCIWNDM_GETLENGTH           = WM_USER + 104,\n    MCIWNDM_GETEND              = WM_USER + 105,\n    MCIWNDM_GETMODEA            = WM_USER + 106,\n    MCIWNDM_EJECT               = WM_USER + 107,\n    MCIWNDM_SETZOOM             = WM_USER + 108,\n    MCIWNDM_GETZOOM             = WM_USER + 109,\n    MCIWNDM_SETVOLUME           = WM_USER + 110,\n    MCIWNDM_GETVOLUME           = WM_USER + 111,\n    MCIWNDM_SETSPEED            = WM_USER + 112,\n    MCIWNDM_GETSPEED            = WM_USER + 113,\n    MCIWNDM_SETREPEAT           = WM_USER + 114,\n    MCIWNDM_GETREPEAT           = WM_USER + 115,\n    MCIWNDM_REALIZE             = WM_USER + 118,\n    MCIWNDM_SETTIMEFORMATA      = WM_USER + 119,\n    MCIWNDM_GETTIMEFORMATA      = WM_USER + 120,\n    MCIWNDM_VALIDATEMEDIA       = WM_USER + 121,\n    MCIWNDM_PLAYFROM            = WM_USER + 122,\n    MCIWNDM_PLAYTO              = WM_USER + 123,\n    MCIWNDM_GETFILENAMEA        = WM_USER + 124,\n    MCIWNDM_GETDEVICEA          = WM_USER + 125,\n    MCIWNDM_GETPALETTE          = WM_USER + 126,\n    MCIWNDM_SETPALETTE          = WM_USER + 127,\n    MCIWNDM_GETERRORA           = WM_USER + 128,\n    MCIWNDM_SETTIMERS           = WM_USER + 129,\n    MCIWNDM_SETACTIVETIMER      = WM_USER + 130,\n    MCIWNDM_SETINACTIVETIMER    = WM_USER + 131,\n    MCIWNDM_GETACTIVETIMER      = WM_USER + 132,\n    MCIWNDM_GETINACTIVETIMER    = WM_USER + 133,\n    MCIWNDM_NEWA                = WM_USER + 134,\n    MCIWNDM_CHANGESTYLES        = WM_USER + 135,\n    MCIWNDM_GETSTYLES           = WM_USER + 136,\n    MCIWNDM_GETALIAS            = WM_USER + 137,\n    MCIWNDM_RETURNSTRINGA       = WM_USER + 138,\n    MCIWNDM_PLAYREVERSE         = WM_USER + 139,\n    MCIWNDM_GET_SOURCE          = WM_USER + 140,\n    MCIWNDM_PUT_SOURCE          = WM_USER + 141,\n    MCIWNDM_GET_DEST            = WM_USER + 142,\n    MCIWNDM_PUT_DEST            = WM_USER + 143,\n    MCIWNDM_CAN_PLAY            = WM_USER + 144,\n    MCIWNDM_CAN_WINDOW          = WM_USER + 145,\n    MCIWNDM_CAN_RECORD          = WM_USER + 146,\n    MCIWNDM_CAN_SAVE            = WM_USER + 147,\n    MCIWNDM_CAN_EJECT           = WM_USER + 148,\n    MCIWNDM_CAN_CONFIG          = WM_USER + 149,\n    MCIWNDM_PALETTEKICK         = WM_USER + 150,\n    MCIWNDM_OPENINTERFACE       = WM_USER + 151,\n    MCIWNDM_SETOWNER            = WM_USER + 152,\n    MCIWNDM_OPENA               = WM_USER + 153,\n    MCIWNDM_SENDSTRINGW         = WM_USER + 201,\n    MCIWNDM_GETPOSITIONW        = WM_USER + 202,\n    MCIWNDM_GETMODEW            = WM_USER + 206,\n    MCIWNDM_SETTIMEFORMATW      = WM_USER + 219,\n    MCIWNDM_GETTIMEFORMATW      = WM_USER + 220,\n    MCIWNDM_GETFILENAMEW        = WM_USER + 224,\n    MCIWNDM_GETDEVICEW          = WM_USER + 225,\n    MCIWNDM_GETERRORW           = WM_USER + 228,\n    MCIWNDM_NEWW                = WM_USER + 234,\n    MCIWNDM_RETURNSTRINGW       = WM_USER + 238,\n    MCIWNDM_OPENW               = WM_USER + 252,\n}\n\nversion (Unicode) {\n    alias MCIWNDM_SENDSTRINGW       MCIWNDM_SENDSTRING;\n    alias MCIWNDM_GETPOSITIONW      MCIWNDM_GETPOSITION;\n    alias MCIWNDM_GETMODEW          MCIWNDM_GETMODE;\n    alias MCIWNDM_SETTIMEFORMATW    MCIWNDM_SETTIMEFORMAT;\n    alias MCIWNDM_GETTIMEFORMATW    MCIWNDM_GETTIMEFORMAT;\n    alias MCIWNDM_GETFILENAMEW      MCIWNDM_GETFILENAME;\n    alias MCIWNDM_GETDEVICEW        MCIWNDM_GETDEVICE;\n    alias MCIWNDM_GETERRORW         MCIWNDM_GETERROR;\n    alias MCIWNDM_NEWW              MCIWNDM_NEW;\n    alias MCIWNDM_RETURNSTRINGW     MCIWNDM_RETURNSTRING;\n    alias MCIWNDM_OPENW             MCIWNDM_OPEN;\n} else { // Unicode\n    alias MCIWNDM_SENDSTRINGA       MCIWNDM_SENDSTRING;\n    alias MCIWNDM_GETPOSITIONA      MCIWNDM_GETPOSITION;\n    alias MCIWNDM_GETMODEA          MCIWNDM_GETMODE;\n    alias MCIWNDM_SETTIMEFORMATA    MCIWNDM_SETTIMEFORMAT;\n    alias MCIWNDM_GETTIMEFORMATA    MCIWNDM_GETTIMEFORMAT;\n    alias MCIWNDM_GETFILENAMEA      MCIWNDM_GETFILENAME;\n    alias MCIWNDM_GETDEVICEA        MCIWNDM_GETDEVICE;\n    alias MCIWNDM_GETERRORA         MCIWNDM_GETERROR;\n    alias MCIWNDM_NEWA              MCIWNDM_NEW;\n    alias MCIWNDM_RETURNSTRINGA     MCIWNDM_RETURNSTRING;\n    alias MCIWNDM_OPENA             MCIWNDM_OPEN;\n}\n\nenum {\n    MCIWNDM_NOTIFYMODE  = WM_USER + 200,\n    MCIWNDM_NOTIFYPOS   = WM_USER + 201,\n    MCIWNDM_NOTIFYSIZE  = WM_USER + 202,\n    MCIWNDM_NOTIFYMEDIA = WM_USER + 203,\n    MCIWNDM_NOTIFYERROR = WM_USER + 205,\n}\n\nenum MCIWND_START  = -1;\nenum MCIWND_END    = -2;\n\nenum {\n    MCI_CLOSE   = 0x0804,\n    MCI_PLAY    = 0x0806,\n    MCI_SEEK    = 0x0807,\n    MCI_STOP    = 0x0808,\n    MCI_PAUSE   = 0x0809,\n    MCI_STEP    = 0x080E,\n    MCI_RECORD  = 0x080F,\n    MCI_SAVE    = 0x0813,\n    MCI_CUT     = 0x0851,\n    MCI_COPY    = 0x0852,\n    MCI_PASTE   = 0x0853,\n    MCI_RESUME  = 0x0855,\n    MCI_DELETE  = 0x0856,\n}\n\nenum {\n    MCI_MODE_NOT_READY  = 524,\n    MCI_MODE_STOP,\n    MCI_MODE_PLAY,\n    MCI_MODE_RECORD,\n    MCI_MODE_SEEK,\n    MCI_MODE_PAUSE,\n    MCI_MODE_OPEN,\n}\n\nalias TypeDef!(HANDLE) HVIDEO;\nalias HVIDEO* LPHVIDEO;\n\n// Error Return Values\n\nenum {\n    DV_ERR_OK               = 0,\n    DV_ERR_BASE             = 1,\n    DV_ERR_NONSPECIFIC      = DV_ERR_BASE,\n    DV_ERR_BADFORMAT        = DV_ERR_BASE + 1,\n    DV_ERR_STILLPLAYING     = DV_ERR_BASE + 2,\n    DV_ERR_UNPREPARED       = DV_ERR_BASE + 3,\n    DV_ERR_SYNC             = DV_ERR_BASE + 4,\n    DV_ERR_TOOMANYCHANNELS  = DV_ERR_BASE + 5,\n    DV_ERR_NOTDETECTED      = DV_ERR_BASE + 6,\n    DV_ERR_BADINSTALL       = DV_ERR_BASE + 7,\n    DV_ERR_CREATEPALETTE    = DV_ERR_BASE + 8,\n    DV_ERR_SIZEFIELD        = DV_ERR_BASE + 9,\n    DV_ERR_PARAM1           = DV_ERR_BASE + 10,\n    DV_ERR_PARAM2           = DV_ERR_BASE + 11,\n    DV_ERR_CONFIG1          = DV_ERR_BASE + 12,\n    DV_ERR_CONFIG2          = DV_ERR_BASE + 13,\n    DV_ERR_FLAGS            = DV_ERR_BASE + 14,\n    DV_ERR_13               = DV_ERR_BASE + 15,\n    DV_ERR_NOTSUPPORTED     = DV_ERR_BASE + 16,\n    DV_ERR_NOMEM            = DV_ERR_BASE + 17,\n    DV_ERR_ALLOCATED        = DV_ERR_BASE + 18,\n    DV_ERR_BADDEVICEID      = DV_ERR_BASE + 19,\n    DV_ERR_INVALHANDLE      = DV_ERR_BASE + 20,\n    DV_ERR_BADERRNUM        = DV_ERR_BASE + 21,\n    DV_ERR_NO_BUFFERS       = DV_ERR_BASE + 22,\n    DV_ERR_MEM_CONFLICT     = DV_ERR_BASE + 23,\n    DV_ERR_IO_CONFLICT      = DV_ERR_BASE + 24,\n    DV_ERR_DMA_CONFLICT     = DV_ERR_BASE + 25,\n    DV_ERR_INT_CONFLICT     = DV_ERR_BASE + 26,\n    DV_ERR_PROTECT_ONLY     = DV_ERR_BASE + 27,\n    DV_ERR_LASTERROR        = DV_ERR_BASE + 27,\n    DV_ERR_USER_MSG         = DV_ERR_BASE + 1000,\n}\n\n// Callback Messages\n\nenum {\n    MM_DRVM_OPEN    = 0x3D0,\n    MM_DRVM_CLOSE,\n    MM_DRVM_DATA,\n    MM_DRVM_ERROR,\n}\n\nenum {\n    DV_VM_OPEN  = MM_DRVM_OPEN,\n    DV_VM_CLOSE = MM_DRVM_CLOSE,\n    DV_VM_DATA  = MM_DRVM_DATA,\n    DV_VM_ERROR = MM_DRVM_ERROR,\n}\n\n/**\n * Structures\n */\n\nstruct VIDEOHDR {\n    LPBYTE      lpData;\n    DWORD       dwBufferLength;\n    DWORD       dwBytesUsed;\n    DWORD       dwTimeCaptured;\n    DWORD_PTR   dwUser;\n    DWORD       dwFlags;\n    DWORD_PTR[4]dwReserved;\n}\nalias VIDEOHDR* PVIDEOHDR, LPVIDEOHDR;\n\nenum {\n    VHDR_DONE       = 0x00000001,\n    VHDR_PREPARED   = 0x00000002,\n    VHDR_INQUEUE    = 0x00000004,\n    VHDR_KEYFRAME   = 0x00000008,\n    VHDR_VALID      = 0x0000000F,\n}\n\nstruct CHANNEL_CAPS {\n    DWORD   dwFlags;\n    DWORD   dwSrcRectXMod;\n    DWORD   dwSrcRectYMod;\n    DWORD   dwSrcRectWidthMod;\n    DWORD   dwSrcRectHeightMod;\n    DWORD   dwDstRectXMod;\n    DWORD   dwDstRectYMod;\n    DWORD   dwDstRectWidthMod;\n    DWORD   dwDstRectHeightMod;\n}\nalias CHANNEL_CAPS* PCHANNEL_CAPS, LPCHANNEL_CAPS;\n\nenum {\n    VCAPS_OVERLAY       = 0x00000001,\n    VCAPS_SRC_CAN_CLIP  = 0x00000002,\n    VCAPS_DST_CAN_CLIP  = 0x00000004,\n    VCAPS_CAN_SCALE     = 0x00000008,\n}\n\n/**\n * API Flags\n */\n\nenum {\n    VIDEO_EXTERNALIN            = 0x0001,\n    VIDEO_EXTERNALOUT           = 0x0002,\n    VIDEO_IN                    = 0x0004,\n    VIDEO_OUT                   = 0x0008,\n    VIDEO_DLG_QUERY             = 0x0010,\n}\n\nenum {\n    VIDEO_CONFIGURE_QUERYSIZE   = 0x0001,\n    VIDEO_CONFIGURE_CURRENT     = 0x0010,\n    VIDEO_CONFIGURE_NOMINAL     = 0x0020,\n    VIDEO_CONFIGURE_MIN         = 0x0040,\n    VIDEO_CONFIGURE_MAX         = 0x0080,\n    VIDEO_CONFIGURE_SET         = 0x1000,\n    VIDEO_CONFIGURE_GET         = 0x2000,\n    VIDEO_CONFIGURE_QUERY       = 0x8000,\n}\n\n/**\n * CONFIGURE MESSAGES\n */\n\nenum {\n    DVM_USER            = 0x4000,\n    DVM_CONFIGURE_START = 0x1000,\n    DVM_CONFIGURE_END   = 0x1FFF,\n    DVM_PALETTE         = DVM_CONFIGURE_START + 1,\n    DVM_FORMAT          = DVM_CONFIGURE_START + 2,\n    DVM_PALETTERGB555   = DVM_CONFIGURE_START + 3,\n    DVM_SRC_RECT        = DVM_CONFIGURE_START + 4,\n    DVM_DST_RECT        = DVM_CONFIGURE_START + 5,\n}\n\n/**\n * AVICap window class\n */\n\nLRESULT AVICapSM(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {\n    if (IsWindow(hWnd)) {\n        return SendMessage(hWnd, msg, wParam, lParam);\n    }\n    return 0;\n}\n\nenum {\n    WM_CAP_START                = WM_USER,\n    WM_CAP_UNICODE_START        = WM_USER + 100,\n\n    WM_CAP_GET_CAPSTREAMPTR     = WM_CAP_START + 1,\n    WM_CAP_SET_CALLBACK_ERRORA  = WM_CAP_START + 2,\n    WM_CAP_SET_CALLBACK_STATUSA = WM_CAP_START + 3,\n\n    WM_CAP_SET_CALLBACK_ERRORW  = WM_CAP_UNICODE_START + 2,\n    WM_CAP_SET_CALLBACK_STATUSW = WM_CAP_UNICODE_START + 3,\n}\n\nversion (Unicode) {\n    alias WM_CAP_SET_CALLBACK_ERRORW    WM_CAP_SET_CALLBACK_ERROR;\n    alias WM_CAP_SET_CALLBACK_STATUSW   WM_CAP_SET_CALLBACK_STATUS;\n} else { // Unicode\n    alias WM_CAP_SET_CALLBACK_ERRORA    WM_CAP_SET_CALLBACK_ERROR;\n    alias WM_CAP_SET_CALLBACK_STATUSA   WM_CAP_SET_CALLBACK_STATUS;\n}\n\nenum {\n    WM_CAP_SET_CALLBACK_YIELD       = WM_CAP_START + 4,\n    WM_CAP_SET_CALLBACK_FRAME       = WM_CAP_START + 5,\n    WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START + 6,\n    WM_CAP_SET_CALLBACK_WAVESTREAM  = WM_CAP_START + 7,\n    WM_CAP_GET_USER_DATA            = WM_CAP_START + 8,\n    WM_CAP_SET_USER_DATA            = WM_CAP_START + 9,\n    WM_CAP_DRIVER_CONNECT           = WM_CAP_START + 10,\n    WM_CAP_DRIVER_DISCONNECT        = WM_CAP_START + 11,\n    WM_CAP_DRIVER_GET_NAMEA         = WM_CAP_START + 12,\n    WM_CAP_DRIVER_GET_VERSIONA      = WM_CAP_START + 13,\n\n    WM_CAP_DRIVER_GET_NAMEW         = WM_CAP_UNICODE_START + 12,\n    WM_CAP_DRIVER_GET_VERSIONW      = WM_CAP_UNICODE_START + 13,\n}\n\nversion (Unicode) {\n    alias WM_CAP_DRIVER_GET_NAMEW       WM_CAP_DRIVER_GET_NAME;\n    alias WM_CAP_DRIVER_GET_VERSIONW    WM_CAP_DRIVER_GET_VERSION;\n} else { // Unicode\n    alias WM_CAP_DRIVER_GET_NAMEA       WM_CAP_DRIVER_GET_NAME;\n    alias WM_CAP_DRIVER_GET_VERSIONA    WM_CAP_DRIVER_GET_VERSION;\n}\n\nenum {\n    WM_CAP_DRIVER_GET_CAPS          = WM_CAP_START + 14,\n    WM_CAP_FILE_SET_CAPTURE_FILEA   = WM_CAP_START + 20,\n    WM_CAP_FILE_GET_CAPTURE_FILEA   = WM_CAP_START + 21,\n    WM_CAP_FILE_SAVEASA             = WM_CAP_START + 23,\n    WM_CAP_FILE_SAVEDIBA            = WM_CAP_START + 25,\n\n    WM_CAP_FILE_SET_CAPTURE_FILEW   = WM_CAP_UNICODE_START + 20,\n    WM_CAP_FILE_GET_CAPTURE_FILEW   = WM_CAP_UNICODE_START + 21,\n    WM_CAP_FILE_SAVEASW             = WM_CAP_UNICODE_START + 23,\n    WM_CAP_FILE_SAVEDIBW            = WM_CAP_UNICODE_START + 25,\n}\n\nversion (Unicode) {\n    alias WM_CAP_FILE_SET_CAPTURE_FILEW WM_CAP_FILE_SET_CAPTURE_FILE;\n    alias WM_CAP_FILE_GET_CAPTURE_FILEW WM_CAP_FILE_GET_CAPTURE_FILE;\n    alias WM_CAP_FILE_SAVEASW           WM_CAP_FILE_SAVEAS;\n    alias WM_CAP_FILE_SAVEDIBW          WM_CAP_FILE_SAVEDIB;\n} else { // Unicode\n    alias WM_CAP_FILE_SET_CAPTURE_FILEA WM_CAP_FILE_SET_CAPTURE_FILE;\n    alias WM_CAP_FILE_GET_CAPTURE_FILEA WM_CAP_FILE_GET_CAPTURE_FILE;\n    alias WM_CAP_FILE_SAVEASA           WM_CAP_FILE_SAVEAS;\n    alias WM_CAP_FILE_SAVEDIBA          WM_CAP_FILE_SAVEDIB;\n}\n\nenum {\n    WM_CAP_FILE_ALLOCATE        = WM_CAP_START + 22,\n    WM_CAP_FILE_SET_INFOCHUNK   = WM_CAP_START + 24,\n    WM_CAP_EDIT_COPY            = WM_CAP_START + 30,\n    WM_CAP_SET_AUDIOFORMAT      = WM_CAP_START + 35,\n    WM_CAP_GET_AUDIOFORMAT      = WM_CAP_START + 36,\n    WM_CAP_DLG_VIDEOFORMAT      = WM_CAP_START + 41,\n    WM_CAP_DLG_VIDEOSOURCE      = WM_CAP_START + 42,\n    WM_CAP_DLG_VIDEODISPLAY     = WM_CAP_START + 43,\n    WM_CAP_GET_VIDEOFORMAT      = WM_CAP_START + 44,\n    WM_CAP_SET_VIDEOFORMAT      = WM_CAP_START + 45,\n    WM_CAP_DLG_VIDEOCOMPRESSION = WM_CAP_START + 46,\n    WM_CAP_SET_PREVIEW          = WM_CAP_START + 50,\n    WM_CAP_SET_OVERLAY          = WM_CAP_START + 51,\n    WM_CAP_SET_PREVIEWRATE      = WM_CAP_START + 52,\n    WM_CAP_SET_SCALE            = WM_CAP_START + 53,\n    WM_CAP_GET_STATUS           = WM_CAP_START + 54,\n    WM_CAP_SET_SCROLL           = WM_CAP_START + 55,\n    WM_CAP_GRAB_FRAME           = WM_CAP_START + 60,\n    WM_CAP_GRAB_FRAME_NOSTOP    = WM_CAP_START + 61,\n    WM_CAP_SEQUENCE             = WM_CAP_START + 62,\n    WM_CAP_SEQUENCE_NOFILE      = WM_CAP_START + 63,\n    WM_CAP_SET_SEQUENCE_SETUP   = WM_CAP_START + 64,\n    WM_CAP_GET_SEQUENCE_SETUP   = WM_CAP_START + 65,\n    WM_CAP_SET_MCI_DEVICEA      = WM_CAP_START + 66,\n    WM_CAP_GET_MCI_DEVICEA      = WM_CAP_START + 67,\n\n    WM_CAP_SET_MCI_DEVICEW      = WM_CAP_UNICODE_START + 66,\n    WM_CAP_GET_MCI_DEVICEW      = WM_CAP_UNICODE_START + 67,\n}\n\nversion (Unicode) {\n    alias WM_CAP_SET_MCI_DEVICEW    WM_CAP_SET_MCI_DEVICE;\n    alias WM_CAP_GET_MCI_DEVICEW    WM_CAP_GET_MCI_DEVICE;\n} else { // Unicode\n    alias WM_CAP_SET_MCI_DEVICEA    WM_CAP_SET_MCI_DEVICE;\n    alias WM_CAP_GET_MCI_DEVICEA    WM_CAP_GET_MCI_DEVICE;\n}\n\nenum {\n    WM_CAP_STOP                 = WM_CAP_START + 68,\n    WM_CAP_ABORT                = WM_CAP_START + 69,\n    WM_CAP_SINGLE_FRAME_OPEN    = WM_CAP_START + 70,\n    WM_CAP_SINGLE_FRAME_CLOSE   = WM_CAP_START + 71,\n    WM_CAP_SINGLE_FRAME         = WM_CAP_START + 72,\n    WM_CAP_PAL_OPENA            = WM_CAP_START + 80,\n    WM_CAP_PAL_SAVEA            = WM_CAP_START + 81,\n\n    WM_CAP_PAL_OPENW            = WM_CAP_UNICODE_START + 80,\n    WM_CAP_PAL_SAVEW            = WM_CAP_UNICODE_START + 81,\n}\n\nversion (Unicode) {\n    alias WM_CAP_PAL_OPENW  WM_CAP_PAL_OPEN;\n    alias WM_CAP_PAL_SAVEW  WM_CAP_PAL_SAVE;\n} else { // Unicode\n    alias WM_CAP_PAL_OPENA  WM_CAP_PAL_OPEN;\n    alias WM_CAP_PAL_SAVEA  WM_CAP_PAL_SAVE;\n}\n\nenum {\n    WM_CAP_PAL_PASTE                = WM_CAP_START + 82,\n    WM_CAP_PAL_AUTOCREATE           = WM_CAP_START + 83,\n    WM_CAP_PAL_MANUALCREATE         = WM_CAP_START + 84,\n    WM_CAP_SET_CALLBACK_CAPCONTROL  = WM_CAP_START + 85,\n    WM_CAP_UNICODE_END              = WM_CAP_PAL_SAVEW,\n    WM_CAP_END                      = WM_CAP_UNICODE_END,\n}\n\n/**\n * message wrapper\n */\n\nBOOL capSetCallbackOnError(HWND hWnd, LPVOID fpProc)                { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_CALLBACK_ERROR, 0, cast(LPARAM)fpProc); }\nBOOL capSetCallbackOnStatus(HWND hWnd, LPVOID fpProc)               { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_CALLBACK_STATUS, 0, cast(LPARAM)fpProc); }\nBOOL capSetCallbackOnYield(HWND hWnd, LPVOID fpProc)                { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_CALLBACK_YIELD, 0, cast(LPARAM)fpProc); }\nBOOL capSetCallbackOnFrame(HWND hWnd, LPVOID fpProc)                { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_CALLBACK_FRAME, 0, cast(LPARAM)fpProc); }\nBOOL capSetCallbackOnVideoStream(HWND hWnd, LPVOID fpProc)          { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, cast(LPARAM)fpProc); }\nBOOL capSetCallbackOnWaveStream(HWND hWnd, LPVOID fpProc)           { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_CALLBACK_WAVESTREAM, 0, cast(LPARAM)fpProc); }\nBOOL capSetCallbackOnCapControl(HWND hWnd, LPVOID fpProc)           { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_CALLBACK_CAPCONTROL, 0, cast(LPARAM)fpProc); }\n\nBOOL capSetUserData(HWND hWnd, LPARAM lUser)                        { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_USER_DATA, 0, lUser); }\nBOOL capGetUserData(HWND hWnd)                                      { return cast(BOOL)AVICapSM(hWnd, WM_CAP_GET_USER_DATA, 0, 0); }\n\nBOOL capDriverConnect(HWND hWnd, WPARAM i)                          { return cast(BOOL)AVICapSM(hWnd, WM_CAP_DRIVER_CONNECT, i, 0); }\nBOOL capDriverDisconnect(HWND hWnd)                                 { return cast(BOOL)AVICapSM(hWnd, WM_CAP_DRIVER_DISCONNECT, 0, 0); }\nBOOL capDriverGetName(HWND hWnd, LPTSTR szName, WPARAM wSize)       { return cast(BOOL)AVICapSM(hWnd, WM_CAP_DRIVER_GET_NAME, wSize, cast(LPARAM)szName); }\nBOOL capDriverGetVersion(HWND hWnd, LPTSTR szVer, WPARAM wSize)     { return cast(BOOL)AVICapSM(hWnd, WM_CAP_DRIVER_GET_VERSION, wSize, cast(LPARAM)szVer); }\nBOOL capDriverGetCaps(HWND hWnd, LPCAPDRIVERCAPS s, WPARAM wSize)   { return cast(BOOL)AVICapSM(hWnd, WM_CAP_DRIVER_GET_CAPS, wSize, cast(LPARAM)s); }\n\nBOOL capFileSetCaptureFile(HWND hWnd, LPTSTR szName)                { return cast(BOOL)AVICapSM(hWnd, WM_CAP_FILE_SET_CAPTURE_FILE, 0, cast(LPARAM)szName); }\nBOOL capFileGetCaptureFile(HWND hWnd, LPTSTR szName, WPARAM wSize)  { return cast(BOOL)AVICapSM(hWnd, WM_CAP_FILE_GET_CAPTURE_FILE, wSize, cast(LPARAM)szName); }\nBOOL capFileAlloc(HWND hWnd, WPARAM wSize)                          { return cast(BOOL)AVICapSM(hWnd, WM_CAP_FILE_ALLOCATE, wSize, 0); }\nBOOL capFileSaveAs(HWND hWnd, LPTSTR szName)                        { return cast(BOOL)AVICapSM(hWnd, WM_CAP_FILE_SAVEAS, 0, cast(LPARAM)szName); }\nBOOL capFileSetInfoChunk(HWND hWnd, LPCAPINFOCHUNK lpInfoChunk)     { return cast(BOOL)AVICapSM(hWnd, WM_CAP_FILE_SET_INFOCHUNK, 0, cast(LPARAM)lpInfoChunk); }\nBOOL capFileSaveDIB(HWND hWnd, LPTSTR szName)                       { return cast(BOOL)AVICapSM(hWnd, WM_CAP_FILE_SAVEDIB, 0, cast(LPARAM)szName); }\n\nBOOL capEditCopy(HWND hWnd)                                         { return cast(BOOL)AVICapSM(hWnd, WM_CAP_EDIT_COPY, 0, 0); }\n\nBOOL capSetAudioFormat(HWND hWnd, LPWAVEFORMATEX s, WPARAM wSize)   { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_AUDIOFORMAT, wSize, cast(LPARAM)s); }\nDWORD capGetAudioFormat(HWND hWnd, LPWAVEFORMATEX s, WPARAM wSize)  { return cast(DWORD)AVICapSM(hWnd, WM_CAP_GET_AUDIOFORMAT, wSize, cast(LPARAM)s); }\nDWORD capGetAudioFormatSize(HWND hWnd)                              { return cast(DWORD)AVICapSM(hWnd, WM_CAP_GET_AUDIOFORMAT, 0, 0); }\n\nBOOL capDlgVideoFormat(HWND hWnd)                                   { return cast(BOOL)AVICapSM(hWnd, WM_CAP_DLG_VIDEOFORMAT, 0, 0); }\nBOOL capDlgVideoSource(HWND hWnd)                                   { return cast(BOOL)AVICapSM(hWnd, WM_CAP_DLG_VIDEOSOURCE, 0, 0); }\nBOOL capDlgVideoDisplay(HWND hWnd)                                  { return cast(BOOL)AVICapSM(hWnd, WM_CAP_DLG_VIDEODISPLAY, 0, 0); }\nBOOL capDlgVideoCompression(HWND hWnd)                              { return cast(BOOL)AVICapSM(hWnd, WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0); }\n\nDWORD capGetVideoFormat(HWND hWnd, void* s, WPARAM wSize)           { return cast(DWORD)AVICapSM(hWnd, WM_CAP_GET_VIDEOFORMAT, wSize, cast(LPARAM)s); }\nDWORD capGetVideoFormatSize(HWND hWnd)                              { return cast(DWORD)AVICapSM(hWnd, WM_CAP_GET_VIDEOFORMAT, 0, 0); }\nBOOL capSetVideoFormat(HWND hWnd, void* s, WPARAM wSize)            { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_VIDEOFORMAT, wSize, cast(LPARAM)s); }\n\nBOOL capPreview(HWND hWnd, BOOL f)                                  { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_PREVIEW, cast(WPARAM)f, 0); }\nBOOL capPreviewRate(HWND hWnd, WPARAM wMS)                          { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_PREVIEWRATE, wMS, 0); }\nBOOL capOverlay(HWND hWnd, BOOL f)                                  { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_OVERLAY, cast(WPARAM)f, 0); }\nBOOL capPreviewScale(HWND hWnd, BOOL f)                             { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_SCALE, cast(WPARAM)f, 0); }\nBOOL capGetStatus(HWND hWnd, LPCAPSTATUS s, WPARAM wSize)           { return cast(BOOL)AVICapSM(hWnd, WM_CAP_GET_STATUS, wSize, cast(LPARAM)s); }\nBOOL capSetScrollPos(HWND hWnd, LPPOINT lpP)                        { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_SCROLL, 0, cast(LPARAM)lpP); }\n\nBOOL capGrabFrame(HWND hWnd)                                        { return cast(BOOL)AVICapSM(hWnd, WM_CAP_GRAB_FRAME, 0, 0); }\nBOOL capGrabFrameNoStop(HWND hWnd)                                  { return cast(BOOL)AVICapSM(hWnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0); }\n\nBOOL capCaptureSequence(HWND hWnd)                                  { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SEQUENCE, 0, 0); }\nBOOL capCaptureSequenceNoFile(HWND hWnd)                            { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SEQUENCE_NOFILE, 0, 0); }\nBOOL capCaptureStop(HWND hWnd)                                      { return cast(BOOL)AVICapSM(hWnd, WM_CAP_STOP, 0, 0); }\nBOOL capCaptureAbort(HWND hWnd)                                     { return cast(BOOL)AVICapSM(hWnd, WM_CAP_ABORT, 0, 0); }\n\nBOOL capCaptureSingleFrameOpen(HWND hWnd)                           { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SINGLE_FRAME_OPEN, 0, 0); }\nBOOL capCaptureSingleFrameClose(HWND hWnd)                          { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SINGLE_FRAME_CLOSE, 0, 0); }\nBOOL capCaptureSingleFrame(HWND hWnd)                               { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SINGLE_FRAME, 0, 0); }\n\nBOOL capCaptureGetSetup(HWND hWnd, LPCAPTUREPARMS s, WPARAM wSize)  { return cast(BOOL)AVICapSM(hWnd, WM_CAP_GET_SEQUENCE_SETUP, wSize, cast(LPARAM)s); }\nBOOL capCaptureSetSetup(HWND hWnd, LPCAPTUREPARMS s, WPARAM wSize)  { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_SEQUENCE_SETUP, wSize, cast(LPARAM)s); }\n\nBOOL capSetMCIDeviceName(HWND hWnd, LPTSTR szName)                  { return cast(BOOL)AVICapSM(hWnd, WM_CAP_SET_MCI_DEVICE, 0, cast(LPARAM)szName); }\nBOOL capGetMCIDeviceName(HWND hWnd, LPTSTR szName, WPARAM wSize)    { return cast(BOOL)AVICapSM(hWnd, WM_CAP_GET_MCI_DEVICE, wSize, cast(LPARAM)szName); }\n\nBOOL capPaletteOpen(HWND hWnd, LPTSTR szName)                       { return cast(BOOL)AVICapSM(hWnd, WM_CAP_PAL_OPEN, 0, cast(LPARAM)szName); }\nBOOL capPaletteSave(HWND hWnd, LPTSTR szName)                       { return cast(BOOL)AVICapSM(hWnd, WM_CAP_PAL_SAVE, 0, cast(LPARAM)szName); }\nBOOL capPalettePaste(HWND hWnd)                                     { return cast(BOOL)AVICapSM(hWnd, WM_CAP_PAL_PASTE, 0, 0); }\nBOOL capPaletteAuto(HWND hWnd, WPARAM iFrames, LPARAM iColors)      { return cast(BOOL)AVICapSM(hWnd, WM_CAP_PAL_AUTOCREATE, iFrames, iColors); }\nBOOL capPaletteManual(HWND hWnd, WPARAM fGrab, LPARAM iColors)      { return cast(BOOL)AVICapSM(hWnd, WM_CAP_PAL_MANUALCREATE, fGrab, iColors); }\n\n/**\n * structs\n */\n\nstruct CAPDRIVERCAPS {\n    UINT    wDeviceIndex;\n    BOOL    fHasOverlay;\n    BOOL    fHasDlgVideoSource;\n    BOOL    fHasDlgVideoFormat;\n    BOOL    fHasDlgVideoDisplay;\n    BOOL    fCaptureInitialized;\n    BOOL    fDriverSuppliesPalettes;\n    HANDLE  hVideoIn;\n    HANDLE  hVideoOut;\n    HANDLE  hVideoExtIn;\n    HANDLE  hVideoExtOut;\n}\nalias CAPDRIVERCAPS* PCAPDRIVERCAPS, LPCAPDRIVERCAPS;\n\nstruct CAPSTATUS {\n    UINT        uiImageWidth;\n    UINT        uiImageHeight;\n    BOOL        fLiveWindow;\n    BOOL        fOverlayWindow;\n    BOOL        fScale;\n    POINT       ptScroll;\n    BOOL        fUsingDefaultPalette;\n    BOOL        fAudioHardware;\n    BOOL        fCapFileExists;\n    DWORD       dwCurrentVideoFrame;\n    DWORD       dwCurrentVideoFramesDropped;\n    DWORD       dwCurrentWaveSamples;\n    DWORD       dwCurrentTimeElapsedMS;\n    HPALETTE    hPalCurrent;\n    BOOL        fCapturingNow;\n    DWORD       dwReturn;\n    UINT        wNumVideoAllocated;\n    UINT        wNumAudioAllocated;\n}\nalias CAPSTATUS* PCAPSTATUS, LPCAPSTATUS;\n\nstruct CAPTUREPARMS {\n    DWORD   dwRequestMicroSecPerFrame;\n    BOOL    fMakeUserHitOKToCapture;\n    UINT    wPercentDropForError;\n    BOOL    fYield;\n    DWORD   dwIndexSize;\n    UINT    wChunkGranularity;\n    BOOL    fUsingDOSMemory;\n    UINT    wNumVideoRequested;\n    BOOL    fCaptureAudio;\n    UINT    wNumAudioRequested;\n    UINT    vKeyAbort;\n    BOOL    fAbortLeftMouse;\n    BOOL    fAbortRightMouse;\n    BOOL    fLimitEnabled;\n    UINT    wTimeLimit;\n    BOOL    fMCIControl;\n    BOOL    fStepMCIDevice;\n    DWORD   dwMCIStartTime;\n    DWORD   dwMCIStopTime;\n    BOOL    fStepCaptureAt2x;\n    UINT    wStepCaptureAverageFrames;\n    DWORD   dwAudioBufferSize;\n    BOOL    fDisableWriteCache;\n    UINT    AVStreamMaster;\n}\nalias CAPTUREPARMS* PCAPTUREPARMS, LPCAPTUREPARMS;\n\nenum AVSTREAMMASTER_AUDIO = 0;\nenum AVSTREAMMASTER_NONE  = 1;\n\nstruct CAPINFOCHUNK {\n    FOURCC  fccInfoID;\n    LPVOID  lpData;\n    LONG    cbData;\n}\nalias CAPINFOCHUNK* PCAPINFOCHUNK, LPCAPINFOCHUNK;\n\n// Callback Definitions\n\nextern (Windows) {\n    alias LRESULT function(HWND hWnd) CAPYIELDCALLBACK;\n    alias LRESULT function(HWND hWnd, int nID, LPCWSTR lpsz) CAPSTATUSCALLBACKW;\n    alias LRESULT function(HWND hWnd, int nID, LPCWSTR lpsz) CAPERRORCALLBACKW;\n    alias LRESULT function(HWND hWnd, int nID, LPCSTR lpsz) CAPSTATUSCALLBACKA;\n    alias LRESULT function(HWND hWnd, int nID, LPCSTR lpsz) CAPERRORCALLBACKA;\n}\n\nversion (Unicode) {\n    alias CAPSTATUSCALLBACKW    CAPSTATUSCALLBACK;\n    alias CAPERRORCALLBACKW     CAPERRORCALLBACK;\n} else { // Unicode\n    alias CAPSTATUSCALLBACKA    CAPSTATUSCALLBACK;\n    alias CAPERRORCALLBACKA     CAPERRORCALLBACK;\n}\n\nextern (Windows) {\n    alias LRESULT function(HWND hWnd, LPVIDEOHDR lpVHdr) CAPVIDEOCALLBACK;\n    alias LRESULT function(HWND hWnd, LPWAVEHDR lpWHdr) CAPWAVECALLBACK;\n    alias LRESULT function(HWND hWnd, int nState) CAPCONTROLCALLBACK;\n}\n\n//  CapControlCallback states\nenum CONTROLCALLBACK_PREROLL   = 1;\nenum CONTROLCALLBACK_CAPTURING = 2;\n\nextern (Windows) {\n    HWND capCreateCaptureWindowA(LPCSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hwndParent, int nID);\n    BOOL capGetDriverDescriptionA(UINT wDriverIndex, LPSTR lpszName, int cbName, LPSTR lpszVer, int cbVer);\n    HWND capCreateCaptureWindowW(LPCWSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hwndParent, int nID);\n    BOOL capGetDriverDescriptionW(UINT wDriverIndex, LPWSTR lpszName, int cbName, LPWSTR lpszVer, int cbVer);\n}\n\nversion (Unicode) {\n    alias capCreateCaptureWindowW   capCreateCaptureWindow;\n    alias capGetDriverDescriptionW  capGetDriverDescription;\n} else { // Unicode\n    alias capCreateCaptureWindowA   capCreateCaptureWindow;\n    alias capGetDriverDescriptionA  capGetDriverDescription;\n}\n\n// New Information chunk IDs\nenum infotypeDIGITIZATION_TIME = mmioFOURCC!('I', 'D', 'I', 'T');\nenum infotypeSMPTE_TIME        = mmioFOURCC!('I', 'S', 'M', 'P');\n\n// status and error callbacks\nenum {\n    IDS_CAP_BEGIN                   = 300,\n    IDS_CAP_END                     = 301,\n\n    IDS_CAP_INFO                    = 401,\n    IDS_CAP_OUTOFMEM                = 402,\n    IDS_CAP_FILEEXISTS              = 403,\n    IDS_CAP_ERRORPALOPEN            = 404,\n    IDS_CAP_ERRORPALSAVE            = 405,\n    IDS_CAP_ERRORDIBSAVE            = 406,\n    IDS_CAP_DEFAVIEXT               = 407,\n    IDS_CAP_DEFPALEXT               = 408,\n    IDS_CAP_CANTOPEN                = 409,\n    IDS_CAP_SEQ_MSGSTART            = 410,\n    IDS_CAP_SEQ_MSGSTOP             = 411,\n\n    IDS_CAP_VIDEDITERR              = 412,\n    IDS_CAP_READONLYFILE            = 413,\n    IDS_CAP_WRITEERROR              = 414,\n    IDS_CAP_NODISKSPACE             = 415,\n    IDS_CAP_SETFILESIZE             = 416,\n    IDS_CAP_SAVEASPERCENT           = 417,\n\n    IDS_CAP_DRIVER_ERROR            = 418,\n\n    IDS_CAP_WAVE_OPEN_ERROR         = 419,\n    IDS_CAP_WAVE_ALLOC_ERROR        = 420,\n    IDS_CAP_WAVE_PREPARE_ERROR      = 421,\n    IDS_CAP_WAVE_ADD_ERROR          = 422,\n    IDS_CAP_WAVE_SIZE_ERROR         = 423,\n\n    IDS_CAP_VIDEO_OPEN_ERROR        = 424,\n    IDS_CAP_VIDEO_ALLOC_ERROR       = 425,\n    IDS_CAP_VIDEO_PREPARE_ERROR     = 426,\n    IDS_CAP_VIDEO_ADD_ERROR         = 427,\n    IDS_CAP_VIDEO_SIZE_ERROR        = 428,\n\n    IDS_CAP_FILE_OPEN_ERROR         = 429,\n    IDS_CAP_FILE_WRITE_ERROR        = 430,\n    IDS_CAP_RECORDING_ERROR         = 431,\n    IDS_CAP_RECORDING_ERROR2        = 432,\n    IDS_CAP_AVI_INIT_ERROR          = 433,\n    IDS_CAP_NO_FRAME_CAP_ERROR      = 434,\n    IDS_CAP_NO_PALETTE_WARN         = 435,\n    IDS_CAP_MCI_CONTROL_ERROR       = 436,\n    IDS_CAP_MCI_CANT_STEP_ERROR     = 437,\n    IDS_CAP_NO_AUDIO_CAP_ERROR      = 438,\n    IDS_CAP_AVI_DRAWDIB_ERROR       = 439,\n    IDS_CAP_COMPRESSOR_ERROR        = 440,\n    IDS_CAP_AUDIO_DROP_ERROR        = 441,\n    IDS_CAP_AUDIO_DROP_COMPERROR    = 442,\n\n    IDS_CAP_STAT_LIVE_MODE          = 500,\n    IDS_CAP_STAT_OVERLAY_MODE       = 501,\n    IDS_CAP_STAT_CAP_INIT           = 502,\n    IDS_CAP_STAT_CAP_FINI           = 503,\n    IDS_CAP_STAT_PALETTE_BUILD      = 504,\n    IDS_CAP_STAT_OPTPAL_BUILD       = 505,\n    IDS_CAP_STAT_I_FRAMES           = 506,\n    IDS_CAP_STAT_L_FRAMES           = 507,\n    IDS_CAP_STAT_CAP_L_FRAMES       = 508,\n    IDS_CAP_STAT_CAP_AUDIO          = 509,\n    IDS_CAP_STAT_VIDEOCURRENT       = 510,\n    IDS_CAP_STAT_VIDEOAUDIO         = 511,\n    IDS_CAP_STAT_VIDEOONLY          = 512,\n    IDS_CAP_STAT_FRAMESDROPPED      = 513,\n}\n\n/**\n * FilePreview dialog.\n */\n\nextern (Windows) {\n    BOOL GetOpenFileNamePreviewA(LPOPENFILENAMEA lpofn);\n    BOOL GetSaveFileNamePreviewA(LPOPENFILENAMEA lpofn);\n    BOOL GetOpenFileNamePreviewW(LPOPENFILENAMEW lpofn);\n    BOOL GetSaveFileNamePreviewW(LPOPENFILENAMEW lpofn);\n}\n\nversion (Unicode) {\n    alias GetOpenFileNamePreviewW   GetOpenFileNamePreview;\n    alias GetSaveFileNamePreviewW   GetSaveFileNamePreview;\n} else { // Unicode\n    alias GetOpenFileNamePreviewA   GetOpenFileNamePreview;\n    alias GetSaveFileNamePreviewA   GetSaveFileNamePreview;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/w32api.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 4.0\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_w32api.d)\n */\nmodule core.sys.windows.w32api;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\nenum __W32API_VERSION = 3.17;\nenum __W32API_MAJOR_VERSION = 3;\nenum __W32API_MINOR_VERSION = 17;\n\n/*  These version identifiers are used to specify the minimum version of Windows that an\n *  application will support.\n *\n *  Previously the minimum Windows 9x and Windows NT versions could be specified.  However, since\n *  Windows 9x is no longer supported, either by Microsoft or by DMD, this distinction has been\n *  removed in order to simplify the bindings.\n */\n version (Windows10) {\n    enum uint _WIN32_WINNT = 0x604;\n} else version (Windows8_1) {    // also Windows2012R2\n    enum uint _WIN32_WINNT = 0x603;\n} else version (Windows8) {      // also Windows2012\n    enum uint _WIN32_WINNT = 0x602;\n} else version (Windows7) {      // also Windows2008R2\n    enum uint _WIN32_WINNT = 0x601;\n} else version (WindowsVista) {  // also Windows2008\n    enum uint _WIN32_WINNT = 0x600;\n} else version (Windows2003) {   // also WindowsHomeServer, WindowsXP64\n    enum uint _WIN32_WINNT = 0x502;\n} else version (WindowsXP) {\n    enum uint _WIN32_WINNT = 0x501;\n} else version (Windows2000) {\n    // Current DMD doesn't support any version of Windows older than XP,\n    // but third-party compilers could use this\n    enum uint _WIN32_WINNT = 0x500;\n} else {\n    enum uint _WIN32_WINNT = 0x501;\n}\n\nversion (IE10) {\n    enum uint _WIN32_IE = 0xA00;\n} else version (IE9) {\n    enum uint _WIN32_IE = 0x900;\n} else version (IE8) {\n    enum uint _WIN32_IE = 0x800;\n} else version (IE7) {\n    enum uint _WIN32_IE = 0x700;\n} else version (IE602) {\n    enum uint _WIN32_IE = 0x603;\n} else version (IE601) {\n    enum uint _WIN32_IE = 0x601;\n} else version (IE6) {\n    enum uint _WIN32_IE = 0x600;\n} else version (IE56) {\n    enum uint _WIN32_IE = 0x560;\n} else version (IE501) {\n    enum uint _WIN32_IE = 0x501;\n} else version (IE5) {\n    enum uint _WIN32_IE = 0x500;\n} else version (IE401) {\n    enum uint _WIN32_IE = 0x401;\n} else version (IE4) {\n    enum uint _WIN32_IE = 0x400;\n} else version (IE3) {\n    enum uint _WIN32_IE = 0x300;\n} else static if (_WIN32_WINNT >= 0x410) {\n    enum uint _WIN32_IE = 0x400;\n} else {\n    enum uint _WIN32_IE = 0;\n}\n\ndebug (WindowsUnitTest) {\n    unittest {\n        printf(\"Windows NT version: %03x\\n\", _WIN32_WINNT);\n        printf(\"IE version:         %03x\\n\", _WIN32_IE);\n    }\n}\n\nversion (Unicode) {\n    enum bool _WIN32_UNICODE = true;\n    package template DECLARE_AW(string name) {\n        mixin(\"alias \" ~ name ~ \"W \" ~ name ~ \";\");\n    }\n} else {\n    enum bool _WIN32_UNICODE = false;\n    package template DECLARE_AW(string name) {\n        mixin(\"alias \" ~ name ~ \"A \" ~ name ~ \";\");\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winbase.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.10\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winbase.d)\n */\nmodule core.sys.windows.winbase;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"kernel32\");\n\n/**\nTranslation Notes:\nThe following macros are obsolete, and have no effect.\n\nLockSegment(w), MakeProcInstance(p, i), UnlockResource(h), UnlockSegment(w)\nFreeModule(m), FreeProcInstance(p), GetFreeSpace(w), DefineHandleTable(w)\nSetSwapAreaSize(w), LimitEmsPages(n), Yield()\n\n// These are not required for DMD.\n\n//FIXME:\n// #ifndef UNDER_CE\n    int WinMain(HINSTANCE, HINSTANCE, LPSTR, int);\n#else\n    int WinMain(HINSTANCE, HINSTANCE, LPWSTR, int);\n#endif\nint wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);\n\n*/\n\nimport core.sys.windows.windef, core.sys.windows.winver;\nprivate import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.winnt;\n\n// FIXME:\n//alias void va_list;\nimport core.stdc.stdarg : va_list;\n\n\n// COMMPROP structure, used by GetCommProperties()\n// -----------------------------------------------\n\n// Communications provider type\nenum : DWORD {\n    PST_UNSPECIFIED,\n    PST_RS232,\n    PST_PARALLELPORT,\n    PST_RS422,\n    PST_RS423,\n    PST_RS449,\n    PST_MODEM,      // =      6\n    PST_FAX            = 0x0021,\n    PST_SCANNER        = 0x0022,\n    PST_NETWORK_BRIDGE = 0x0100,\n    PST_LAT            = 0x0101,\n    PST_TCPIP_TELNET   = 0x0102,\n    PST_X25            = 0x0103\n}\n\n// Max baud rate\nenum : DWORD {\n    BAUD_075    = 0x00000001,\n    BAUD_110    = 0x00000002,\n    BAUD_134_5  = 0x00000004,\n    BAUD_150    = 0x00000008,\n    BAUD_300    = 0x00000010,\n    BAUD_600    = 0x00000020,\n    BAUD_1200   = 0x00000040,\n    BAUD_1800   = 0x00000080,\n    BAUD_2400   = 0x00000100,\n    BAUD_4800   = 0x00000200,\n    BAUD_7200   = 0x00000400,\n    BAUD_9600   = 0x00000800,\n    BAUD_14400  = 0x00001000,\n    BAUD_19200  = 0x00002000,\n    BAUD_38400  = 0x00004000,\n    BAUD_56K    = 0x00008000,\n    BAUD_128K   = 0x00010000,\n    BAUD_115200 = 0x00020000,\n    BAUD_57600  = 0x00040000,\n    BAUD_USER   = 0x10000000\n}\n\n// Comm capabilities\nenum : DWORD {\n    PCF_DTRDSR        = 0x0001,\n    PCF_RTSCTS        = 0x0002,\n    PCF_RLSD          = 0x0004,\n    PCF_PARITY_CHECK  = 0x0008,\n    PCF_XONXOFF       = 0x0010,\n    PCF_SETXCHAR      = 0x0020,\n    PCF_TOTALTIMEOUTS = 0x0040,\n    PCF_INTTIMEOUTS   = 0x0080,\n    PCF_SPECIALCHARS  = 0x0100,\n    PCF_16BITMODE     = 0x0200\n}\n\nenum  : DWORD {\n    SP_PARITY       = 1,\n    SP_BAUD         = 2,\n    SP_DATABITS     = 4,\n    SP_STOPBITS     = 8,\n    SP_HANDSHAKING  = 16,\n    SP_PARITY_CHECK = 32,\n    SP_RLSD         = 64\n}\n\nenum : DWORD {\n    DATABITS_5   = 1,\n    DATABITS_6   = 2,\n    DATABITS_7   = 4,\n    DATABITS_8   = 8,\n    DATABITS_16  = 16,\n    DATABITS_16X = 32\n}\n\nenum : WORD {\n    STOPBITS_10  = 0x0001,\n    STOPBITS_15  = 0x0002,\n    STOPBITS_20  = 0x0004,\n    PARITY_NONE  = 0x0100,\n    PARITY_ODD   = 0x0200,\n    PARITY_EVEN  = 0x0400,\n    PARITY_MARK  = 0x0800,\n    PARITY_SPACE = 0x1000\n}\n\n// used by dwServiceMask\nenum SP_SERIALCOMM = 1;\n\nstruct COMMPROP {\n    WORD  wPacketLength;\n    WORD  wPacketVersion;\n    DWORD dwServiceMask;\n    DWORD dwReserved1;\n    DWORD dwMaxTxQueue;\n    DWORD dwMaxRxQueue;\n    DWORD dwMaxBaud;\n    DWORD dwProvSubType;\n    DWORD dwProvCapabilities;\n    DWORD dwSettableParams;\n    DWORD dwSettableBaud;\n    WORD  wSettableData;\n    WORD  wSettableStopParity;\n    DWORD dwCurrentTxQueue;\n    DWORD dwCurrentRxQueue;\n    DWORD dwProvSpec1;\n    DWORD dwProvSpec2;\n    WCHAR _wcProvChar;\n\n    WCHAR* wcProvChar() return { return &_wcProvChar; }\n}\nalias COMMPROP* LPCOMMPROP;\n\n// ----------\n\n// for DEBUG_EVENT\nenum : DWORD {\n    EXCEPTION_DEBUG_EVENT = 1,\n    CREATE_THREAD_DEBUG_EVENT,\n    CREATE_PROCESS_DEBUG_EVENT,\n    EXIT_THREAD_DEBUG_EVENT,\n    EXIT_PROCESS_DEBUG_EVENT,\n    LOAD_DLL_DEBUG_EVENT,\n    UNLOAD_DLL_DEBUG_EVENT,\n    OUTPUT_DEBUG_STRING_EVENT,\n    RIP_EVENT\n}\n\nenum HFILE HFILE_ERROR = cast(HFILE) (-1);\n\n// for SetFilePointer()\nenum : DWORD {\n    FILE_BEGIN   = 0,\n    FILE_CURRENT = 1,\n    FILE_END     = 2\n}\nenum DWORD INVALID_SET_FILE_POINTER = -1;\n\n\n// for OpenFile()\ndeprecated enum : UINT {\n    OF_READ             = 0,\n    OF_WRITE            = 0x0001,\n    OF_READWRITE        = 0x0002,\n    OF_SHARE_COMPAT     = 0,\n    OF_SHARE_EXCLUSIVE  = 0x0010,\n    OF_SHARE_DENY_WRITE = 0x0020,\n    OF_SHARE_DENY_READ  = 0x0030,\n    OF_SHARE_DENY_NONE  = 0x0040,\n    OF_PARSE            = 0x0100,\n    OF_DELETE           = 0x0200,\n    OF_VERIFY           = 0x0400,\n    OF_CANCEL           = 0x0800,\n    OF_CREATE           = 0x1000,\n    OF_PROMPT           = 0x2000,\n    OF_EXIST            = 0x4000,\n    OF_REOPEN           = 0x8000\n}\n\nenum : DWORD {\n    NMPWAIT_NOWAIT           =  1,\n    NMPWAIT_WAIT_FOREVER     = -1,\n    NMPWAIT_USE_DEFAULT_WAIT =  0\n}\n\n// for ClearCommError()\nenum DWORD\n    CE_RXOVER   = 0x0001,\n    CE_OVERRUN  = 0x0002,\n    CE_RXPARITY = 0x0004,\n    CE_FRAME    = 0x0008,\n    CE_BREAK    = 0x0010,\n    CE_TXFULL   = 0x0100,\n    CE_PTO      = 0x0200,\n    CE_IOE      = 0x0400,\n    CE_DNS      = 0x0800,\n    CE_OOP      = 0x1000,\n    CE_MODE     = 0x8000;\n\n// for CopyProgressRoutine callback.\nenum : DWORD {\n    PROGRESS_CONTINUE = 0,\n    PROGRESS_CANCEL   = 1,\n    PROGRESS_STOP     = 2,\n    PROGRESS_QUIET    = 3\n}\n\nenum : DWORD {\n    CALLBACK_CHUNK_FINISHED = 0,\n    CALLBACK_STREAM_SWITCH  = 1\n}\n\n// CopyFileEx()\nenum : DWORD {\n    COPY_FILE_FAIL_IF_EXISTS = 1,\n    COPY_FILE_RESTARTABLE    = 2\n}\n\nenum : DWORD {\n    FILE_MAP_COPY       = 1,\n    FILE_MAP_WRITE      = 2,\n    FILE_MAP_READ       = 4,\n    FILE_MAP_ALL_ACCESS = 0x000F001F\n}\n\nenum : DWORD {\n    MUTEX_ALL_ACCESS       = 0x001f0001,\n    MUTEX_MODIFY_STATE     = 0x00000001,\n    SEMAPHORE_ALL_ACCESS   = 0x001f0003,\n    SEMAPHORE_MODIFY_STATE = 0x00000002,\n    EVENT_ALL_ACCESS       = 0x001f0003,\n    EVENT_MODIFY_STATE     = 0x00000002\n}\n\n// CreateNamedPipe()\nenum : DWORD {\n    PIPE_ACCESS_INBOUND  = 1,\n    PIPE_ACCESS_OUTBOUND = 2,\n    PIPE_ACCESS_DUPLEX   = 3\n}\n\nenum DWORD\n    PIPE_TYPE_BYTE        = 0,\n    PIPE_TYPE_MESSAGE     = 4,\n    PIPE_READMODE_BYTE    = 0,\n    PIPE_READMODE_MESSAGE = 2,\n    PIPE_WAIT             = 0,\n    PIPE_NOWAIT           = 1;\n\n// GetNamedPipeInfo()\nenum DWORD\n    PIPE_CLIENT_END  = 0,\n    PIPE_SERVER_END  = 1;\n\nenum DWORD PIPE_UNLIMITED_INSTANCES = 255;\n\n// dwCreationFlags for CreateProcess() and CreateProcessAsUser()\nenum : DWORD {\n    DEBUG_PROCESS               = 0x00000001,\n    DEBUG_ONLY_THIS_PROCESS     = 0x00000002,\n    CREATE_SUSPENDED            = 0x00000004,\n    DETACHED_PROCESS            = 0x00000008,\n    CREATE_NEW_CONSOLE          = 0x00000010,\n    NORMAL_PRIORITY_CLASS       = 0x00000020,\n    IDLE_PRIORITY_CLASS         = 0x00000040,\n    HIGH_PRIORITY_CLASS         = 0x00000080,\n    REALTIME_PRIORITY_CLASS     = 0x00000100,\n    CREATE_NEW_PROCESS_GROUP    = 0x00000200,\n    CREATE_UNICODE_ENVIRONMENT  = 0x00000400,\n    CREATE_SEPARATE_WOW_VDM     = 0x00000800,\n    CREATE_SHARED_WOW_VDM       = 0x00001000,\n    CREATE_FORCEDOS             = 0x00002000,\n    BELOW_NORMAL_PRIORITY_CLASS = 0x00004000,\n    ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000,\n    CREATE_BREAKAWAY_FROM_JOB   = 0x01000000,\n    CREATE_WITH_USERPROFILE     = 0x02000000,\n    CREATE_DEFAULT_ERROR_MODE   = 0x04000000,\n    CREATE_NO_WINDOW            = 0x08000000,\n    PROFILE_USER                = 0x10000000,\n    PROFILE_KERNEL              = 0x20000000,\n    PROFILE_SERVER              = 0x40000000\n}\n\nenum DWORD CONSOLE_TEXTMODE_BUFFER = 1;\n\n// CreateFile()\nenum : DWORD {\n    CREATE_NEW = 1,\n    CREATE_ALWAYS,\n    OPEN_EXISTING,\n    OPEN_ALWAYS,\n    TRUNCATE_EXISTING\n}\n\n// CreateFile()\nenum DWORD\n    FILE_FLAG_WRITE_THROUGH      = 0x80000000,\n    FILE_FLAG_OVERLAPPED         = 0x40000000,\n    FILE_FLAG_NO_BUFFERING       = 0x20000000,\n    FILE_FLAG_RANDOM_ACCESS      = 0x10000000,\n    FILE_FLAG_SEQUENTIAL_SCAN    = 0x08000000,\n    FILE_FLAG_DELETE_ON_CLOSE    = 0x04000000,\n    FILE_FLAG_BACKUP_SEMANTICS   = 0x02000000,\n    FILE_FLAG_POSIX_SEMANTICS    = 0x01000000,\n    FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000,\n    FILE_FLAG_OPEN_NO_RECALL     = 0x00100000;\n\nstatic if (_WIN32_WINNT >= 0x500) {\nenum DWORD FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000;\n}\n\n// for CreateFile()\nenum DWORD\n    SECURITY_ANONYMOUS        = SECURITY_IMPERSONATION_LEVEL.SecurityAnonymous<<16,\n    SECURITY_IDENTIFICATION   = SECURITY_IMPERSONATION_LEVEL.SecurityIdentification<<16,\n    SECURITY_IMPERSONATION    = SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation<<16,\n    SECURITY_DELEGATION       = SECURITY_IMPERSONATION_LEVEL.SecurityDelegation<<16,\n    SECURITY_CONTEXT_TRACKING = 0x00040000,\n    SECURITY_EFFECTIVE_ONLY   = 0x00080000,\n    SECURITY_SQOS_PRESENT     = 0x00100000,\n    SECURITY_VALID_SQOS_FLAGS = 0x001F0000;\n\n\n// Thread exit code\nenum DWORD STILL_ACTIVE = 0x103;\n\n/*  ??? The only documentation of this seems to be about Windows CE and to\n *  state what _doesn't_ support it.\n */\nenum DWORD FIND_FIRST_EX_CASE_SENSITIVE = 1;\n\n// GetBinaryType()\nenum : DWORD {\n    SCS_32BIT_BINARY = 0,\n    SCS_DOS_BINARY,\n    SCS_WOW_BINARY,\n    SCS_PIF_BINARY,\n    SCS_POSIX_BINARY,\n    SCS_OS216_BINARY\n}\n\nenum size_t\n    MAX_COMPUTERNAME_LENGTH = 15,\n    HW_PROFILE_GUIDLEN      = 39,\n    MAX_PROFILE_LEN         = 80;\n\n// HW_PROFILE_INFO\nenum DWORD\n    DOCKINFO_UNDOCKED      = 1,\n    DOCKINFO_DOCKED        = 2,\n    DOCKINFO_USER_SUPPLIED = 4,\n    DOCKINFO_USER_UNDOCKED = DOCKINFO_USER_SUPPLIED | DOCKINFO_UNDOCKED,\n    DOCKINFO_USER_DOCKED   = DOCKINFO_USER_SUPPLIED | DOCKINFO_DOCKED;\n\n// DriveType(), RealDriveType()\nenum : int {\n    DRIVE_UNKNOWN = 0,\n    DRIVE_NO_ROOT_DIR,\n    DRIVE_REMOVABLE,\n    DRIVE_FIXED,\n    DRIVE_REMOTE,\n    DRIVE_CDROM,\n    DRIVE_RAMDISK\n}\n\n// GetFileType()\nenum : DWORD {\n    FILE_TYPE_UNKNOWN = 0,\n    FILE_TYPE_DISK,\n    FILE_TYPE_CHAR,\n    FILE_TYPE_PIPE,\n    FILE_TYPE_REMOTE = 0x8000\n}\n\n// Get/SetHandleInformation()\nenum DWORD\n    HANDLE_FLAG_INHERIT            = 0x01,\n    HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x02;\n\nenum : DWORD {\n    STD_INPUT_HANDLE  = 0xFFFFFFF6,\n    STD_OUTPUT_HANDLE = 0xFFFFFFF5,\n    STD_ERROR_HANDLE  = 0xFFFFFFF4\n}\n\nenum HANDLE INVALID_HANDLE_VALUE = cast(HANDLE) (-1);\n\nenum : DWORD {\n    GET_TAPE_MEDIA_INFORMATION = 0,\n    GET_TAPE_DRIVE_INFORMATION = 1\n}\n\nenum : DWORD {\n    SET_TAPE_MEDIA_INFORMATION = 0,\n    SET_TAPE_DRIVE_INFORMATION = 1\n}\n\n// SetThreadPriority()/GetThreadPriority()\nenum : int {\n    THREAD_PRIORITY_IDLE          = -15,\n    THREAD_PRIORITY_LOWEST        =  -2,\n    THREAD_PRIORITY_BELOW_NORMAL  =  -1,\n    THREAD_PRIORITY_NORMAL        =   0,\n    THREAD_PRIORITY_ABOVE_NORMAL  =   1,\n    THREAD_PRIORITY_HIGHEST       =   2,\n    THREAD_PRIORITY_TIME_CRITICAL =  15,\n    THREAD_PRIORITY_ERROR_RETURN  = 2147483647\n}\n\nenum : DWORD {\n    TIME_ZONE_ID_UNKNOWN,\n    TIME_ZONE_ID_STANDARD,\n    TIME_ZONE_ID_DAYLIGHT,\n    TIME_ZONE_ID_INVALID = 0xFFFFFFFF\n}\n\nenum DWORD\n    FS_CASE_SENSITIVE         =     1,\n    FS_CASE_IS_PRESERVED      =     2,\n    FS_UNICODE_STORED_ON_DISK =     4,\n    FS_PERSISTENT_ACLS        =     8,\n    FS_FILE_COMPRESSION       =    16,\n    FS_VOL_IS_COMPRESSED      = 32768;\n\n// Flags for GlobalAlloc\nenum UINT\n    GMEM_FIXED       = 0,\n    GMEM_MOVEABLE    = 0x0002,\n    GMEM_ZEROINIT    = 0x0040,\n    GPTR             = 0x0040,\n    GHND             = 0x0042,\n    GMEM_MODIFY      = 0x0080,  // used only for GlobalRealloc\n    GMEM_VALID_FLAGS = 0x7F72;\n\n/+  // Obselete flags (Win16 only)\n    GMEM_NOCOMPACT=16;\n    GMEM_NODISCARD=32;\n    GMEM_DISCARDABLE=256;\n    GMEM_NOT_BANKED=4096;\n    GMEM_LOWER=4096;\n    GMEM_SHARE=8192;\n    GMEM_DDESHARE=8192;\n\n    GMEM_LOCKCOUNT=255;\n\n// for GlobalFlags()\n    GMEM_DISCARDED      = 16384;\n    GMEM_INVALID_HANDLE = 32768;\n\n    GMEM_NOTIFY         = 16384;\n+/\n\nenum UINT\n    LMEM_FIXED          = 0,\n    LMEM_MOVEABLE       = 0x0002,\n    LMEM_NONZEROLPTR    = 0,\n    NONZEROLPTR         = 0,\n    LMEM_NONZEROLHND    = 0x0002,\n    NONZEROLHND         = 0x0002,\n    LMEM_DISCARDABLE    = 0x0F00,\n    LMEM_NOCOMPACT      = 0x0010,\n    LMEM_NODISCARD      = 0x0020,\n    LMEM_ZEROINIT       = 0x0040,\n    LPTR                = 0x0040,\n    LHND                = 0x0042,\n    LMEM_MODIFY         = 0x0080,\n    LMEM_LOCKCOUNT      = 0x00FF,\n    LMEM_DISCARDED      = 0x4000,\n    LMEM_INVALID_HANDLE = 0x8000;\n\n\n\n// used in EXCEPTION_RECORD\nenum : DWORD {\n    STATUS_WAIT_0                      = 0,\n    STATUS_ABANDONED_WAIT_0            = 0x00000080,\n    STATUS_USER_APC                    = 0x000000C0,\n    STATUS_TIMEOUT                     = 0x00000102,\n    STATUS_PENDING                     = 0x00000103,\n\n    STATUS_SEGMENT_NOTIFICATION        = 0x40000005,\n    STATUS_GUARD_PAGE_VIOLATION        = 0x80000001,\n    STATUS_DATATYPE_MISALIGNMENT       = 0x80000002,\n    STATUS_BREAKPOINT                  = 0x80000003,\n    STATUS_SINGLE_STEP                 = 0x80000004,\n\n    STATUS_ACCESS_VIOLATION            = 0xC0000005,\n    STATUS_IN_PAGE_ERROR               = 0xC0000006,\n    STATUS_INVALID_HANDLE              = 0xC0000008,\n\n    STATUS_NO_MEMORY                   = 0xC0000017,\n    STATUS_ILLEGAL_INSTRUCTION         = 0xC000001D,\n    STATUS_NONCONTINUABLE_EXCEPTION    = 0xC0000025,\n    STATUS_INVALID_DISPOSITION         = 0xC0000026,\n    STATUS_ARRAY_BOUNDS_EXCEEDED       = 0xC000008C,\n    STATUS_FLOAT_DENORMAL_OPERAND      = 0xC000008D,\n    STATUS_FLOAT_DIVIDE_BY_ZERO        = 0xC000008E,\n    STATUS_FLOAT_INEXACT_RESULT        = 0xC000008F,\n    STATUS_FLOAT_INVALID_OPERATION     = 0xC0000090,\n    STATUS_FLOAT_OVERFLOW              = 0xC0000091,\n    STATUS_FLOAT_STACK_CHECK           = 0xC0000092,\n    STATUS_FLOAT_UNDERFLOW             = 0xC0000093,\n    STATUS_INTEGER_DIVIDE_BY_ZERO      = 0xC0000094,\n    STATUS_INTEGER_OVERFLOW            = 0xC0000095,\n    STATUS_PRIVILEGED_INSTRUCTION      = 0xC0000096,\n    STATUS_STACK_OVERFLOW              = 0xC00000FD,\n    STATUS_CONTROL_C_EXIT              = 0xC000013A,\n    STATUS_DLL_INIT_FAILED             = 0xC0000142,\n    STATUS_DLL_INIT_FAILED_LOGOFF      = 0xC000026B,\n\n    CONTROL_C_EXIT                     = STATUS_CONTROL_C_EXIT,\n\n    EXCEPTION_ACCESS_VIOLATION         = STATUS_ACCESS_VIOLATION,\n    EXCEPTION_DATATYPE_MISALIGNMENT    = STATUS_DATATYPE_MISALIGNMENT,\n    EXCEPTION_BREAKPOINT               = STATUS_BREAKPOINT,\n    EXCEPTION_SINGLE_STEP              = STATUS_SINGLE_STEP,\n    EXCEPTION_ARRAY_BOUNDS_EXCEEDED    = STATUS_ARRAY_BOUNDS_EXCEEDED,\n    EXCEPTION_FLT_DENORMAL_OPERAND     = STATUS_FLOAT_DENORMAL_OPERAND,\n    EXCEPTION_FLT_DIVIDE_BY_ZERO       = STATUS_FLOAT_DIVIDE_BY_ZERO,\n    EXCEPTION_FLT_INEXACT_RESULT       = STATUS_FLOAT_INEXACT_RESULT,\n    EXCEPTION_FLT_INVALID_OPERATION    = STATUS_FLOAT_INVALID_OPERATION,\n    EXCEPTION_FLT_OVERFLOW             = STATUS_FLOAT_OVERFLOW,\n    EXCEPTION_FLT_STACK_CHECK          = STATUS_FLOAT_STACK_CHECK,\n    EXCEPTION_FLT_UNDERFLOW            = STATUS_FLOAT_UNDERFLOW,\n    EXCEPTION_INT_DIVIDE_BY_ZERO       = STATUS_INTEGER_DIVIDE_BY_ZERO,\n    EXCEPTION_INT_OVERFLOW             = STATUS_INTEGER_OVERFLOW,\n    EXCEPTION_PRIV_INSTRUCTION         = STATUS_PRIVILEGED_INSTRUCTION,\n    EXCEPTION_IN_PAGE_ERROR            = STATUS_IN_PAGE_ERROR,\n    EXCEPTION_ILLEGAL_INSTRUCTION      = STATUS_ILLEGAL_INSTRUCTION,\n    EXCEPTION_NONCONTINUABLE_EXCEPTION = STATUS_NONCONTINUABLE_EXCEPTION,\n    EXCEPTION_STACK_OVERFLOW           = STATUS_STACK_OVERFLOW,\n    EXCEPTION_INVALID_DISPOSITION      = STATUS_INVALID_DISPOSITION,\n    EXCEPTION_GUARD_PAGE               = STATUS_GUARD_PAGE_VIOLATION,\n    EXCEPTION_INVALID_HANDLE           = STATUS_INVALID_HANDLE\n}\n\n// for PROCESS_HEAP_ENTRY\nenum WORD\n    PROCESS_HEAP_REGION            =  1,\n    PROCESS_HEAP_UNCOMMITTED_RANGE =  2,\n    PROCESS_HEAP_ENTRY_BUSY        =  4,\n    PROCESS_HEAP_ENTRY_MOVEABLE    = 16,\n    PROCESS_HEAP_ENTRY_DDESHARE    = 32;\n\n// for LoadLibraryEx()\nenum DWORD\n    DONT_RESOLVE_DLL_REFERENCES   = 0x01, // not for WinME and earlier\n    LOAD_LIBRARY_AS_DATAFILE      = 0x02,\n    LOAD_WITH_ALTERED_SEARCH_PATH = 0x08,\n    LOAD_IGNORE_CODE_AUTHZ_LEVEL  = 0x10; // only for XP and later\n\n// for LockFile()\nenum DWORD\n    LOCKFILE_FAIL_IMMEDIATELY = 1,\n    LOCKFILE_EXCLUSIVE_LOCK   = 2;\n\nenum MAXIMUM_WAIT_OBJECTS  = 64;\nenum MAXIMUM_SUSPEND_COUNT = 0x7F;\n\nenum WAIT_OBJECT_0    = 0;\nenum WAIT_ABANDONED_0 = 128;\n\n//const WAIT_TIMEOUT=258;  // also in winerror.h\n\nenum : DWORD {\n    WAIT_IO_COMPLETION = 0x000000C0,\n    WAIT_ABANDONED     = 0x00000080,\n    WAIT_FAILED        = 0xFFFFFFFF\n}\n\n// PurgeComm()\nenum DWORD\n    PURGE_TXABORT = 1,\n    PURGE_RXABORT = 2,\n    PURGE_TXCLEAR = 4,\n    PURGE_RXCLEAR = 8;\n\n// ReadEventLog()\nenum DWORD\n    EVENTLOG_SEQUENTIAL_READ = 1,\n    EVENTLOG_SEEK_READ       = 2,\n    EVENTLOG_FORWARDS_READ   = 4,\n    EVENTLOG_BACKWARDS_READ  = 8;\n\n// ReportEvent()\nenum : WORD {\n    EVENTLOG_SUCCESS          = 0,\n    EVENTLOG_ERROR_TYPE       = 1,\n    EVENTLOG_WARNING_TYPE     = 2,\n    EVENTLOG_INFORMATION_TYPE = 4,\n    EVENTLOG_AUDIT_SUCCESS    = 8,\n    EVENTLOG_AUDIT_FAILURE    = 16\n}\n\n// FormatMessage()\nenum DWORD\n    FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x0100,\n    FORMAT_MESSAGE_IGNORE_INSERTS  = 0x0200,\n    FORMAT_MESSAGE_FROM_STRING     = 0x0400,\n    FORMAT_MESSAGE_FROM_HMODULE    = 0x0800,\n    FORMAT_MESSAGE_FROM_SYSTEM     = 0x1000,\n    FORMAT_MESSAGE_ARGUMENT_ARRAY  = 0x2000;\n\nenum DWORD FORMAT_MESSAGE_MAX_WIDTH_MASK = 255;\n\n// also in ddk/ntapi.h\n// To restore default error mode, call SetErrorMode(0)\nenum {\n    SEM_FAILCRITICALERRORS     = 0x0001,\n    SEM_NOGPFAULTERRORBOX      = 0x0002,\n    SEM_NOALIGNMENTFAULTEXCEPT = 0x0004,\n    SEM_NOOPENFILEERRORBOX     = 0x8000\n}\n// end ntapi.h\n\nenum {\n    SLE_ERROR = 1,\n    SLE_MINORERROR,\n    SLE_WARNING\n}\n\nenum SHUTDOWN_NORETRY = 1;\n\n// Return type for exception filters.\nenum : LONG {\n    EXCEPTION_EXECUTE_HANDLER    =  1,\n    EXCEPTION_CONTINUE_EXECUTION = -1,\n    EXCEPTION_CONTINUE_SEARCH    =  0\n}\n\nenum  : ATOM {\n    MAXINTATOM   = 0xC000,\n    INVALID_ATOM = 0\n}\n\nenum IGNORE   = 0;\nenum INFINITE = 0xFFFFFFFF;\n\n// EscapeCommFunction()\nenum {\n    SETXOFF    = 1,\n    SETXON,\n    SETRTS,\n    CLRRTS,\n    SETDTR,\n    CLRDTR, // = 6\n    SETBREAK   = 8,\n    CLRBREAK   = 9\n}\n\n\n// for SetCommMask()\nenum DWORD\n    EV_RXCHAR   = 0x0001,\n    EV_RXFLAG   = 0x0002,\n    EV_TXEMPTY  = 0x0004,\n    EV_CTS      = 0x0008,\n    EV_DSR      = 0x0010,\n    EV_RLSD     = 0x0020,\n    EV_BREAK    = 0x0040,\n    EV_ERR      = 0x0080,\n    EV_RING     = 0x0100,\n    EV_PERR     = 0x0200,\n    EV_RX80FULL = 0x0400,\n    EV_EVENT1   = 0x0800,\n    EV_EVENT2   = 0x1000;\n\n// GetCommModemStatus()\nenum DWORD\n    MS_CTS_ON  = 0x0010,\n    MS_DSR_ON  = 0x0020,\n    MS_RING_ON = 0x0040,\n    MS_RLSD_ON = 0x0080;\n\n\n// DCB\nenum : BYTE {\n    NOPARITY = 0,\n    ODDPARITY,\n    EVENPARITY,\n    MARKPARITY,\n    SPACEPARITY\n}\n// DCB\nenum : BYTE {\n    ONESTOPBIT = 0,\n    ONE5STOPBITS,\n    TWOSTOPBITS\n}\n// DCB\nenum : DWORD {\n    CBR_110    =    110,\n    CBR_300    =    300,\n    CBR_600    =    600,\n    CBR_1200   =   1200,\n    CBR_2400   =   2400,\n    CBR_4800   =   4800,\n    CBR_9600   =   9600,\n    CBR_14400  =  14400,\n    CBR_19200  =  19200,\n    CBR_38400  =  38400,\n    CBR_56000  =  56000,\n    CBR_57600  =  57600,\n    CBR_115200 = 115200,\n    CBR_128000 = 128000,\n    CBR_256000 = 256000\n}\n// DCB, 2-bit bitfield\nenum {\n    DTR_CONTROL_DISABLE = 0,\n    DTR_CONTROL_ENABLE,\n    DTR_CONTROL_HANDSHAKE\n}\n\n// DCB, 2-bit bitfield\nenum {\n    RTS_CONTROL_DISABLE = 0,\n    RTS_CONTROL_ENABLE,\n    RTS_CONTROL_HANDSHAKE,\n    RTS_CONTROL_TOGGLE,\n}\n\n// WIN32_STREAM_ID\nenum : DWORD {\n    BACKUP_INVALID = 0,\n    BACKUP_DATA,\n    BACKUP_EA_DATA,\n    BACKUP_SECURITY_DATA,\n    BACKUP_ALTERNATE_DATA,\n    BACKUP_LINK,\n    BACKUP_PROPERTY_DATA,\n    BACKUP_OBJECT_ID,\n    BACKUP_REPARSE_DATA,\n    BACKUP_SPARSE_BLOCK\n}\n\n// WIN32_STREAM_ID\nenum : DWORD {\n    STREAM_NORMAL_ATTRIBUTE    = 0,\n    STREAM_MODIFIED_WHEN_READ  = 1,\n    STREAM_CONTAINS_SECURITY   = 2,\n    STREAM_CONTAINS_PROPERTIES = 4\n}\n\n// STARTUPINFO\nenum DWORD\n    STARTF_USESHOWWINDOW    = 0x0001,\n    STARTF_USESIZE          = 0x0002,\n    STARTF_USEPOSITION      = 0x0004,\n    STARTF_USECOUNTCHARS    = 0x0008,\n    STARTF_USEFILLATTRIBUTE = 0x0010,\n    STARTF_RUNFULLSCREEN    = 0x0020,\n    STARTF_FORCEONFEEDBACK  = 0x0040,\n    STARTF_FORCEOFFFEEDBACK = 0x0080,\n    STARTF_USESTDHANDLES    = 0x0100,\n    STARTF_USEHOTKEY        = 0x0200;\n\n// ???\nenum {\n    TC_NORMAL  = 0,\n    TC_HARDERR = 1,\n    TC_GP_TRAP = 2,\n    TC_SIGNAL  = 3\n}\n\n/+ These seem to be Windows CE-specific\nenum {\n    AC_LINE_OFFLINE      = 0,\n    AC_LINE_ONLINE       = 1,\n    AC_LINE_BACKUP_POWER = 2,\n    AC_LINE_UNKNOWN      = 255\n}\n\nenum {\n    BATTERY_FLAG_HIGH          = 1,\n    BATTERY_FLAG_LOW           = 2,\n    BATTERY_FLAG_CRITICAL      = 4,\n    BATTERY_FLAG_CHARGING      = 8,\n    BATTERY_FLAG_NO_BATTERY    = 128,\n    BATTERY_FLAG_UNKNOWN       = 255,\n    BATTERY_PERCENTAGE_UNKNOWN = 255,\n    BATTERY_LIFE_UNKNOWN       = 0xFFFFFFFF\n}\n+/\n\n// ???\nenum HINSTANCE_ERROR = 32;\n\n// returned from GetFileSize()\nenum DWORD INVALID_FILE_SIZE = 0xFFFFFFFF;\n\nenum DWORD TLS_OUT_OF_INDEXES = 0xFFFFFFFF;\n\n// GetWriteWatch()\nenum DWORD WRITE_WATCH_FLAG_RESET = 1;\n\n// for LogonUser()\nenum : DWORD {\n    LOGON32_LOGON_INTERACTIVE = 2,\n    LOGON32_LOGON_NETWORK     = 3,\n    LOGON32_LOGON_BATCH       = 4,\n    LOGON32_LOGON_SERVICE     = 5,\n    LOGON32_LOGON_UNLOCK      = 7\n}\n\n// for LogonUser()\nenum : DWORD {\n    LOGON32_PROVIDER_DEFAULT,\n    LOGON32_PROVIDER_WINNT35,\n    LOGON32_PROVIDER_WINNT40,\n    LOGON32_PROVIDER_WINNT50\n}\n\n// for MoveFileEx()\nenum DWORD\n    MOVEFILE_REPLACE_EXISTING   = 1,\n    MOVEFILE_COPY_ALLOWED       = 2,\n    MOVEFILE_DELAY_UNTIL_REBOOT = 4,\n    MOVEFILE_WRITE_THROUGH      = 8;\n\n// DefineDosDevice()\nenum DWORD\n    DDD_RAW_TARGET_PATH       = 1,\n    DDD_REMOVE_DEFINITION     = 2,\n    DDD_EXACT_MATCH_ON_REMOVE = 4;\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    enum : DWORD {\n        LOGON32_LOGON_NETWORK_CLEARTEXT = 8,\n        LOGON32_LOGON_NEW_CREDENTIALS   = 9\n    }\n\n    // ReplaceFile()\nenum DWORD\n        REPLACEFILE_WRITE_THROUGH       = 1,\n        REPLACEFILE_IGNORE_MERGE_ERRORS = 2;\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\nenum DWORD\n        GET_MODULE_HANDLE_EX_FLAG_PIN                = 1,\n        GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT = 2,\n        GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS       = 4;\n\n    // for ACTCTX\nenum DWORD\n        ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID = 0x01,\n        ACTCTX_FLAG_LANGID_VALID                 = 0x02,\n        ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID     = 0x04,\n        ACTCTX_FLAG_RESOURCE_NAME_VALID          = 0x08,\n        ACTCTX_FLAG_SET_PROCESS_DEFAULT          = 0x10,\n        ACTCTX_FLAG_APPLICATION_NAME_VALID       = 0x20,\n        ACTCTX_FLAG_HMODULE_VALID                = 0x80;\n\n    // DeactivateActCtx()\nenum DWORD DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION = 1;\n    // FindActCtxSectionString()\nenum DWORD FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX          = 1;\n    // QueryActCtxW()\nenum DWORD\n        QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX             = 0x04,\n        QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE             = 0x08,\n        QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS             = 0x10;\n\n    enum {\n        LOGON_WITH_PROFILE        = 1,\n        LOGON_NETCREDENTIALS_ONLY\n    }\n}\n\n// ----\n\nstruct FILETIME {\n    DWORD dwLowDateTime;\n    DWORD dwHighDateTime;\n}\nalias FILETIME* PFILETIME, LPFILETIME;\n\nstruct BY_HANDLE_FILE_INFORMATION {\n    DWORD    dwFileAttributes;\n    FILETIME ftCreationTime;\n    FILETIME ftLastAccessTime;\n    FILETIME ftLastWriteTime;\n    DWORD    dwVolumeSerialNumber;\n    DWORD    nFileSizeHigh;\n    DWORD    nFileSizeLow;\n    DWORD    nNumberOfLinks;\n    DWORD    nFileIndexHigh;\n    DWORD    nFileIndexLow;\n}\nalias BY_HANDLE_FILE_INFORMATION* LPBY_HANDLE_FILE_INFORMATION;\n\nstruct DCB {\n    DWORD DCBlength = DCB.sizeof;\n    DWORD BaudRate;\n/+\n    DWORD fBinary:1;              // Binary Mode (skip EOF check)\n    DWORD fParity:1;              // Enable parity checking\n    DWORD fOutxCtsFlow:1;         // CTS handshaking on output\n    DWORD fOutxDsrFlow:1;         // DSR handshaking on output\n    DWORD fDtrControl:2;          // DTR Flow control\n    DWORD fDsrSensitivity:1;      // DSR Sensitivity\n    DWORD fTXContinueOnXoff:1;    // Continue TX when Xoff sent\n    DWORD fOutX:1;                // Enable output X-ON/X-OFF\n    DWORD fInX:1;                 // Enable input X-ON/X-OFF\n    DWORD fErrorChar:1;           // Enable Err Replacement\n    DWORD fNull:1;                // Enable Null stripping\n    DWORD fRtsControl:2;          // Rts Flow control\n    DWORD fAbortOnError:1;        // Abort all reads and writes on Error\n    DWORD fDummy2:17;             // Reserved\n+/\n    uint _bf;\n    bool fBinary(bool f)           { _bf = (_bf & ~0x0001) | f; return f; }\n    bool fParity(bool f)           { _bf = (_bf & ~0x0002) | (f<<1); return f; }\n    bool fOutxCtsFlow(bool f)      { _bf = (_bf & ~0x0004) | (f<<2); return f; }\n    bool fOutxDsrFlow(bool f)      { _bf = (_bf & ~0x0008) | (f<<3); return f; }\n    byte fDtrControl(byte x)       { _bf = (_bf & ~0x0030) | (x<<4); return cast(byte)(x & 3); }\n    bool fDsrSensitivity(bool f)   { _bf = (_bf & ~0x0040) | (f<<6); return f; }\n    bool fTXContinueOnXoff(bool f) { _bf = (_bf & ~0x0080) | (f<<7); return f; }\n    bool fOutX(bool f)             { _bf = (_bf & ~0x0100) | (f<<8); return f; }\n    bool fInX(bool f)              { _bf = (_bf & ~0x0200) | (f<<9); return f; }\n    bool fErrorChar(bool f)        { _bf = (_bf & ~0x0400) | (f<<10); return f; }\n    bool fNull(bool f)             { _bf = (_bf & ~0x0800) | (f<<11); return f; }\n    byte fRtsControl(byte x)       { _bf = (_bf & ~0x3000) | (x<<12); return cast(byte)(x & 3); }\n    bool fAbortOnError(bool f)     { _bf = (_bf & ~0x4000) | (f<<14); return f; }\n\n    bool fBinary()           { return cast(bool) (_bf & 1); }\n    bool fParity()           { return cast(bool) (_bf & 2); }\n    bool fOutxCtsFlow()      { return cast(bool) (_bf & 4); }\n    bool fOutxDsrFlow()      { return cast(bool) (_bf & 8); }\n    byte fDtrControl()       { return cast(byte) ((_bf & (32+16))>>4); }\n    bool fDsrSensitivity()   { return cast(bool) (_bf & 64); }\n    bool fTXContinueOnXoff() { return cast(bool) (_bf & 128); }\n    bool fOutX()             { return cast(bool) (_bf & 256); }\n    bool fInX()              { return cast(bool) (_bf & 512); }\n    bool fErrorChar()        { return cast(bool) (_bf & 1024); }\n    bool fNull()             { return cast(bool) (_bf & 2048); }\n    byte fRtsControl()       { return cast(byte) ((_bf & (4096+8192))>>12); }\n    bool fAbortOnError()     { return cast(bool) (_bf & 16384); }\n\n    WORD wReserved;\n    WORD XonLim;\n    WORD XoffLim;\n    BYTE ByteSize;\n    BYTE Parity;\n    BYTE StopBits;\n    char XonChar;\n    char XoffChar;\n    char ErrorChar;\n    char EofChar;\n    char EvtChar;\n    WORD wReserved1;\n}\nalias DCB* LPDCB;\n\nstruct COMMCONFIG {\n    DWORD dwSize = COMMCONFIG.sizeof;\n    WORD  wVersion;\n    WORD  wReserved;\n    DCB   dcb;\n    DWORD dwProviderSubType;\n    DWORD dwProviderOffset;\n    DWORD dwProviderSize;\n    WCHAR _wcProviderData;\n\n    WCHAR* wcProviderData() return { return &_wcProviderData; }\n}\nalias COMMCONFIG* LPCOMMCONFIG;\n\nstruct COMMTIMEOUTS {\n    DWORD ReadIntervalTimeout;\n    DWORD ReadTotalTimeoutMultiplier;\n    DWORD ReadTotalTimeoutConstant;\n    DWORD WriteTotalTimeoutMultiplier;\n    DWORD WriteTotalTimeoutConstant;\n}\nalias COMMTIMEOUTS* LPCOMMTIMEOUTS;\n\nstruct COMSTAT {\n/+\n    DWORD fCtsHold:1;\n    DWORD fDsrHold:1;\n    DWORD fRlsdHold:1;\n    DWORD fXoffHold:1;\n    DWORD fXoffSent:1;\n    DWORD fEof:1;\n    DWORD fTxim:1;\n    DWORD fReserved:25;\n+/\n    DWORD _bf;\n    bool fCtsHold(bool f)  { _bf = (_bf & ~1) | f; return f; }\n    bool fDsrHold(bool f)  { _bf = (_bf & ~2) | (f<<1); return f; }\n    bool fRlsdHold(bool f) { _bf = (_bf & ~4) | (f<<2); return f; }\n    bool fXoffHold(bool f) { _bf = (_bf & ~8) | (f<<3); return f; }\n    bool fXoffSent(bool f) { _bf = (_bf & ~16) | (f<<4); return f; }\n    bool fEof(bool f)      { _bf = (_bf & ~32) | (f<<5); return f; }\n    bool fTxim(bool f)     { _bf = (_bf & ~64) | (f<<6); return f; }\n\n    bool fCtsHold()  { return cast(bool) (_bf & 1); }\n    bool fDsrHold()  { return cast(bool) (_bf & 2); }\n    bool fRlsdHold() { return cast(bool) (_bf & 4); }\n    bool fXoffHold() { return cast(bool) (_bf & 8); }\n    bool fXoffSent() { return cast(bool) (_bf & 16); }\n    bool fEof()      { return cast(bool) (_bf & 32); }\n    bool fTxim()     { return cast(bool) (_bf & 64); }\n\n    DWORD cbInQue;\n    DWORD cbOutQue;\n}\nalias COMSTAT* LPCOMSTAT;\n\nstruct CREATE_PROCESS_DEBUG_INFO {\n    HANDLE hFile;\n    HANDLE hProcess;\n    HANDLE hThread;\n    LPVOID lpBaseOfImage;\n    DWORD  dwDebugInfoFileOffset;\n    DWORD  nDebugInfoSize;\n    LPVOID lpThreadLocalBase;\n    LPTHREAD_START_ROUTINE lpStartAddress;\n    LPVOID lpImageName;\n    WORD   fUnicode;\n}\nalias CREATE_PROCESS_DEBUG_INFO* LPCREATE_PROCESS_DEBUG_INFO;\n\nstruct CREATE_THREAD_DEBUG_INFO {\n    HANDLE hThread;\n    LPVOID lpThreadLocalBase;\n    LPTHREAD_START_ROUTINE lpStartAddress;\n}\nalias CREATE_THREAD_DEBUG_INFO* LPCREATE_THREAD_DEBUG_INFO;\n\nstruct EXCEPTION_DEBUG_INFO {\n    EXCEPTION_RECORD ExceptionRecord;\n    DWORD            dwFirstChance;\n}\nalias EXCEPTION_DEBUG_INFO* LPEXCEPTION_DEBUG_INFO;\n\nstruct EXIT_THREAD_DEBUG_INFO {\n    DWORD dwExitCode;\n}\nalias EXIT_THREAD_DEBUG_INFO* LPEXIT_THREAD_DEBUG_INFO;\n\nstruct EXIT_PROCESS_DEBUG_INFO {\n    DWORD dwExitCode;\n}\nalias EXIT_PROCESS_DEBUG_INFO* LPEXIT_PROCESS_DEBUG_INFO;\n\nstruct LOAD_DLL_DEBUG_INFO {\n    HANDLE hFile;\n    LPVOID lpBaseOfDll;\n    DWORD  dwDebugInfoFileOffset;\n    DWORD  nDebugInfoSize;\n    LPVOID lpImageName;\n    WORD   fUnicode;\n}\nalias LOAD_DLL_DEBUG_INFO* LPLOAD_DLL_DEBUG_INFO;\n\nstruct UNLOAD_DLL_DEBUG_INFO {\n    LPVOID lpBaseOfDll;\n}\nalias UNLOAD_DLL_DEBUG_INFO* LPUNLOAD_DLL_DEBUG_INFO;\n\nstruct OUTPUT_DEBUG_STRING_INFO {\n    LPSTR lpDebugStringData;\n    WORD  fUnicode;\n    WORD  nDebugStringLength;\n}\nalias OUTPUT_DEBUG_STRING_INFO* LPOUTPUT_DEBUG_STRING_INFO;\n\nstruct RIP_INFO {\n    DWORD dwError;\n    DWORD dwType;\n}\nalias RIP_INFO* LPRIP_INFO;\n\nstruct DEBUG_EVENT {\n    DWORD dwDebugEventCode;\n    DWORD dwProcessId;\n    DWORD dwThreadId;\n    union {\n        EXCEPTION_DEBUG_INFO      Exception;\n        CREATE_THREAD_DEBUG_INFO  CreateThread;\n        CREATE_PROCESS_DEBUG_INFO CreateProcessInfo;\n        EXIT_THREAD_DEBUG_INFO    ExitThread;\n        EXIT_PROCESS_DEBUG_INFO   ExitProcess;\n        LOAD_DLL_DEBUG_INFO       LoadDll;\n        UNLOAD_DLL_DEBUG_INFO     UnloadDll;\n        OUTPUT_DEBUG_STRING_INFO  DebugString;\n        RIP_INFO                  RipInfo;\n    }\n}\nalias DEBUG_EVENT* LPDEBUG_EVENT;\n\nstruct OVERLAPPED {\n    ULONG_PTR Internal;\n    ULONG_PTR InternalHigh;\n    union {\n        struct {\n            DWORD     Offset;\n            DWORD     OffsetHigh;\n        }\n        PVOID     Pointer;\n    }\n    HANDLE    hEvent;\n}\nalias OVERLAPPED* POVERLAPPED, LPOVERLAPPED;\n\nstruct STARTUPINFOA {\n    DWORD  cb = STARTUPINFOA.sizeof;\n    LPSTR  lpReserved;\n    LPSTR  lpDesktop;\n    LPSTR  lpTitle;\n    DWORD  dwX;\n    DWORD  dwY;\n    DWORD  dwXSize;\n    DWORD  dwYSize;\n    DWORD  dwXCountChars;\n    DWORD  dwYCountChars;\n    DWORD  dwFillAttribute;\n    DWORD  dwFlags;\n    WORD   wShowWindow;\n    WORD   cbReserved2;\n    PBYTE  lpReserved2;\n    HANDLE hStdInput;\n    HANDLE hStdOutput;\n    HANDLE hStdError;\n}\nalias STARTUPINFOA* LPSTARTUPINFOA;\n\nstruct STARTUPINFOW {\n    DWORD  cb = STARTUPINFOW.sizeof;\n    LPWSTR lpReserved;\n    LPWSTR lpDesktop;\n    LPWSTR lpTitle;\n    DWORD  dwX;\n    DWORD  dwY;\n    DWORD  dwXSize;\n    DWORD  dwYSize;\n    DWORD  dwXCountChars;\n    DWORD  dwYCountChars;\n    DWORD  dwFillAttribute;\n    DWORD  dwFlags;\n    WORD   wShowWindow;\n    WORD   cbReserved2;\n    PBYTE  lpReserved2;\n    HANDLE hStdInput;\n    HANDLE hStdOutput;\n    HANDLE hStdError;\n}\nalias STARTUPINFOW STARTUPINFO_W;\nalias STARTUPINFOW* LPSTARTUPINFOW, LPSTARTUPINFO_W;\n\nstruct PROCESS_INFORMATION {\n    HANDLE hProcess;\n    HANDLE hThread;\n    DWORD  dwProcessId;\n    DWORD  dwThreadId;\n}\nalias PROCESS_INFORMATION* PPROCESS_INFORMATION, LPPROCESS_INFORMATION;\n\n/*\nstruct CRITICAL_SECTION_DEBUG {\n    WORD              Type;\n    WORD              CreatorBackTraceIndex;\n    CRITICAL_SECTION* CriticalSection;\n    LIST_ENTRY        ProcessLocksList;\n    DWORD             EntryCount;\n    DWORD             ContentionCount;\n    DWORD[2]          Spare;\n}\nalias CRITICAL_SECTION_DEBUG* PCRITICAL_SECTION_DEBUG;\n\nstruct CRITICAL_SECTION {\n    PCRITICAL_SECTION_DEBUG DebugInfo;\n    LONG   LockCount;\n    LONG   RecursionCount;\n    HANDLE OwningThread;\n    HANDLE LockSemaphore;\n    DWORD  SpinCount;\n}\nalias CRITICAL_SECTION* PCRITICAL_SECTION, LPCRITICAL_SECTION;\n*/\n\nalias CRITICAL_SECTION_DEBUG = RTL_CRITICAL_SECTION_DEBUG;\nalias CRITICAL_SECTION_DEBUG* PCRITICAL_SECTION_DEBUG;\n\nalias CRITICAL_SECTION = RTL_CRITICAL_SECTION;\nalias CRITICAL_SECTION* PCRITICAL_SECTION, LPCRITICAL_SECTION;\n\nstruct SYSTEMTIME {\n    WORD wYear;\n    WORD wMonth;\n    WORD wDayOfWeek;\n    WORD wDay;\n    WORD wHour;\n    WORD wMinute;\n    WORD wSecond;\n    WORD wMilliseconds;\n}\nalias SYSTEMTIME* LPSYSTEMTIME;\n\nstruct WIN32_FILE_ATTRIBUTE_DATA {\n    DWORD    dwFileAttributes;\n    FILETIME ftCreationTime;\n    FILETIME ftLastAccessTime;\n    FILETIME ftLastWriteTime;\n    DWORD    nFileSizeHigh;\n    DWORD    nFileSizeLow;\n}\nalias WIN32_FILE_ATTRIBUTE_DATA* LPWIN32_FILE_ATTRIBUTE_DATA;\n\nstruct WIN32_FIND_DATAA {\n    DWORD          dwFileAttributes;\n    FILETIME       ftCreationTime;\n    FILETIME       ftLastAccessTime;\n    FILETIME       ftLastWriteTime;\n    DWORD          nFileSizeHigh;\n    DWORD          nFileSizeLow;\n// #ifdef _WIN32_WCE\n//  DWORD dwOID;\n// #else\n    DWORD          dwReserved0;\n    DWORD          dwReserved1;\n// #endif\n    CHAR[MAX_PATH] cFileName;\n// #ifndef _WIN32_WCE\n    CHAR[14]       cAlternateFileName;\n// #endif\n}\nalias WIN32_FIND_DATAA* PWIN32_FIND_DATAA, LPWIN32_FIND_DATAA;\n\nstruct WIN32_FIND_DATAW {\n    DWORD           dwFileAttributes;\n    FILETIME        ftCreationTime;\n    FILETIME        ftLastAccessTime;\n    FILETIME        ftLastWriteTime;\n    DWORD           nFileSizeHigh;\n    DWORD           nFileSizeLow;\n// #ifdef _WIN32_WCE\n//  DWORD dwOID;\n// #else\n    DWORD           dwReserved0;\n    DWORD           dwReserved1;\n// #endif\n    WCHAR[MAX_PATH] cFileName;\n// #ifndef _WIN32_WCE\n    WCHAR[14]       cAlternateFileName;\n// #endif\n}\nalias WIN32_FIND_DATAW* PWIN32_FIND_DATAW, LPWIN32_FIND_DATAW;\n\nstruct WIN32_STREAM_ID {\n    DWORD         dwStreamId;\n    DWORD         dwStreamAttributes;\n    LARGE_INTEGER Size;\n    DWORD         dwStreamNameSize;\n    WCHAR         _cStreamName;\n\n    WCHAR* cStreamName() return { return &_cStreamName; }\n}\nalias WIN32_STREAM_ID* LPWIN32_STREAM_ID;\n\nenum FINDEX_INFO_LEVELS {\n    FindExInfoStandard,\n    FindExInfoMaxInfoLevel\n}\n\nenum FINDEX_SEARCH_OPS {\n    FindExSearchNameMatch,\n    FindExSearchLimitToDirectories,\n    FindExSearchLimitToDevices,\n    FindExSearchMaxSearchOp\n}\n\nenum ACL_INFORMATION_CLASS {\n    AclRevisionInformation = 1,\n    AclSizeInformation\n}\n\nstruct HW_PROFILE_INFOA {\n    DWORD dwDockInfo;\n    CHAR[HW_PROFILE_GUIDLEN] szHwProfileGuid;\n    CHAR[MAX_PROFILE_LEN]    szHwProfileName;\n}\nalias HW_PROFILE_INFOA* LPHW_PROFILE_INFOA;\n\nstruct HW_PROFILE_INFOW {\n    DWORD dwDockInfo;\n    WCHAR[HW_PROFILE_GUIDLEN] szHwProfileGuid;\n    WCHAR[MAX_PROFILE_LEN]    szHwProfileName;\n}\nalias HW_PROFILE_INFOW* LPHW_PROFILE_INFOW;\n\n/*  ??? MSDN documents this only for Windows CE/Mobile, but it's used by\n *  GetFileAttributesEx, which is in desktop Windows.\n */\nenum GET_FILEEX_INFO_LEVELS {\n    GetFileExInfoStandard,\n    GetFileExMaxInfoLevel\n}\n\nstruct SYSTEM_INFO {\n    union {\n        DWORD dwOemId;\n        struct {\n            WORD wProcessorArchitecture;\n            WORD wReserved;\n        }\n    }\n    DWORD dwPageSize;\n    PVOID lpMinimumApplicationAddress;\n    PVOID lpMaximumApplicationAddress;\n    DWORD_PTR dwActiveProcessorMask;\n    DWORD dwNumberOfProcessors;\n    DWORD dwProcessorType;\n    DWORD dwAllocationGranularity;\n    WORD  wProcessorLevel;\n    WORD  wProcessorRevision;\n}\nalias SYSTEM_INFO* LPSYSTEM_INFO;\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    struct SYSTEM_POWER_STATUS {\n        BYTE ACLineStatus;\n        BYTE BatteryFlag;\n        BYTE BatteryLifePercent;\n        BYTE Reserved1;\n        DWORD BatteryLifeTime;\n        DWORD BatteryFullLifeTime;\n    }\n    alias SYSTEM_POWER_STATUS* LPSYSTEM_POWER_STATUS;\n}\n\nstruct TIME_ZONE_INFORMATION {\n    LONG       Bias;\n    WCHAR[32]  StandardName;\n    SYSTEMTIME StandardDate;\n    LONG       StandardBias;\n    WCHAR[32]  DaylightName;\n    SYSTEMTIME DaylightDate;\n    LONG       DaylightBias;\n}\nalias TIME_ZONE_INFORMATION* LPTIME_ZONE_INFORMATION;\n\n// Does not exist in Windows headers, only MSDN\n// documentation (for TIME_ZONE_INFORMATION).\n// Provided solely for compatibility with the old\n// core.sys.windows.windows\nstruct REG_TZI_FORMAT {\n    LONG Bias;\n    LONG StandardBias;\n    LONG DaylightBias;\n    SYSTEMTIME StandardDate;\n    SYSTEMTIME DaylightDate;\n}\n\n// MSDN documents this, possibly erroneously, as Win2000+.\nstruct MEMORYSTATUS {\n    DWORD dwLength;\n    DWORD dwMemoryLoad;\n    SIZE_T dwTotalPhys;\n    SIZE_T dwAvailPhys;\n    SIZE_T dwTotalPageFile;\n    SIZE_T dwAvailPageFile;\n    SIZE_T dwTotalVirtual;\n    SIZE_T dwAvailVirtual;\n}\nalias MEMORYSTATUS* LPMEMORYSTATUS;\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    struct MEMORYSTATUSEX {\n        DWORD     dwLength;\n        DWORD     dwMemoryLoad;\n        DWORDLONG ullTotalPhys;\n        DWORDLONG ullAvailPhys;\n        DWORDLONG ullTotalPageFile;\n        DWORDLONG ullAvailPageFile;\n        DWORDLONG ullTotalVirtual;\n        DWORDLONG ullAvailVirtual;\n        DWORDLONG ullAvailExtendedVirtual;\n    }\n    alias MEMORYSTATUSEX* LPMEMORYSTATUSEX;\n}\n\nstruct LDT_ENTRY {\n    WORD LimitLow;\n    WORD BaseLow;\n    struct {\n        BYTE BaseMid;\n        BYTE Flags1;\n        BYTE Flags2;\n        BYTE BaseHi;\n\n        byte Type(byte f)        { Flags1 = cast(BYTE) ((Flags1 & 0xE0) | f); return cast(byte)(f & 0x1F); }\n        byte Dpl(byte f)         { Flags1 = cast(BYTE) ((Flags1 & 0x9F) | (f<<5)); return cast(byte)(f & 3); }\n        bool Pres(bool f)        { Flags1 = cast(BYTE) ((Flags1 & 0x7F) | (f<<7)); return f; }\n\n        byte LimitHi(byte f)     { Flags2 = cast(BYTE) ((Flags2 & 0xF0) | (f&0x0F)); return cast(byte)(f & 0x0F); }\n        bool Sys(bool f)         { Flags2 = cast(BYTE) ((Flags2 & 0xEF) | (f<<4)); return f; }\n        // Next bit is reserved\n        bool Default_Big(bool f) { Flags2 = cast(BYTE) ((Flags2 & 0xBF) | (f<<6)); return f; }\n        bool Granularity(bool f) { Flags2 = cast(BYTE) ((Flags2 & 0x7F) | (f<<7)); return f; }\n\n        byte Type()        { return cast(byte) (Flags1 & 0x1F); }\n        byte Dpl()         { return cast(byte) ((Flags1 & 0x60)>>5); }\n        bool Pres()        { return cast(bool) (Flags1 & 0x80); }\n\n        byte LimitHi()     { return cast(byte) (Flags2 & 0x0F); }\n        bool Sys()         { return cast(bool) (Flags2 & 0x10); }\n        bool Default_Big() { return cast(bool) (Flags2 & 0x40); }\n        bool Granularity() { return cast(bool) (Flags2 & 0x80); }\n    }\n/+\n    union  HighWord {\n        struct Bytes {\n            BYTE BaseMid;\n            BYTE Flags1;\n            BYTE Flags2;\n            BYTE BaseHi;\n        }\n    struct Bits {\n        DWORD BaseMid:8;\n        DWORD Type:5;\n        DWORD Dpl:2;\n        DWORD Pres:1;\n        DWORD LimitHi:4;\n        DWORD Sys:1;\n        DWORD Reserved_0:1;\n        DWORD Default_Big:1;\n        DWORD Granularity:1;\n        DWORD BaseHi:8;\n    }\n    }\n+/\n}\nalias LDT_ENTRY* PLDT_ENTRY, LPLDT_ENTRY;\n\n/*  As with the other memory management functions and structures, MSDN's\n *  Windows version info shall be taken with a cup of salt.\n */\nstruct PROCESS_HEAP_ENTRY {\n    PVOID lpData;\n    DWORD cbData;\n    BYTE  cbOverhead;\n    BYTE  iRegionIndex;\n    WORD  wFlags;\n    union {\n        struct _Block {\n            HANDLE   hMem;\n            DWORD[3] dwReserved;\n        }\n        _Block Block;\n        struct _Region {\n            DWORD    dwCommittedSize;\n            DWORD    dwUnCommittedSize;\n            LPVOID   lpFirstBlock;\n            LPVOID   lpLastBlock;\n        }\n        _Region Region;\n    }\n}\nalias PROCESS_HEAP_ENTRY* LPPROCESS_HEAP_ENTRY;\n\nstruct OFSTRUCT {\n    BYTE      cBytes = OFSTRUCT.sizeof;\n    BYTE      fFixedDisk;\n    WORD      nErrCode;\n    WORD      Reserved1;\n    WORD      Reserved2;\n    CHAR[128] szPathName; // const OFS_MAXPATHNAME = 128;\n}\nalias OFSTRUCT* LPOFSTRUCT, POFSTRUCT;\n\n/*  ??? MSDN documents this only for Windows CE, but it's used by\n *  ImageGetCertificateData, which is in desktop Windows.\n */\nstruct WIN_CERTIFICATE {\n    DWORD dwLength;\n    WORD  wRevision;\n    WORD  wCertificateType;\n    BYTE  _bCertificate;\n\n    BYTE* bCertificate() return { return &_bCertificate; }\n}\nalias WIN_CERTIFICATE* LPWIN_CERTIFICATE;\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    enum COMPUTER_NAME_FORMAT {\n        ComputerNameNetBIOS,\n        ComputerNameDnsHostname,\n        ComputerNameDnsDomain,\n        ComputerNameDnsFullyQualified,\n        ComputerNamePhysicalNetBIOS,\n        ComputerNamePhysicalDnsHostname,\n        ComputerNamePhysicalDnsDomain,\n        ComputerNamePhysicalDnsFullyQualified,\n        ComputerNameMax\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    struct ACTCTXA {\n        ULONG cbSize = this.sizeof;\n        DWORD dwFlags;\n        LPCSTR lpSource;\n        USHORT wProcessorArchitecture;\n        LANGID wLangId;\n        LPCSTR lpAssemblyDirectory;\n        LPCSTR lpResourceName;\n        LPCSTR lpApplicationName;\n        HMODULE hModule;\n    }\n    alias ACTCTXA*        PACTCTXA;\n    alias const(ACTCTXA)* PCACTCTXA;\n\n    struct ACTCTXW {\n        ULONG cbSize = this.sizeof;\n        DWORD dwFlags;\n        LPCWSTR lpSource;\n        USHORT wProcessorArchitecture;\n        LANGID wLangId;\n        LPCWSTR lpAssemblyDirectory;\n        LPCWSTR lpResourceName;\n        LPCWSTR lpApplicationName;\n        HMODULE hModule;\n    }\n    alias ACTCTXW*        PACTCTXW;\n    alias const(ACTCTXW)* PCACTCTXW;\n\n    struct ACTCTX_SECTION_KEYED_DATA {\n        ULONG cbSize = this.sizeof;\n        ULONG ulDataFormatVersion;\n        PVOID lpData;\n        ULONG ulLength;\n        PVOID lpSectionGlobalData;\n        ULONG ulSectionGlobalDataLength;\n        PVOID lpSectionBase;\n        ULONG ulSectionTotalLength;\n        HANDLE hActCtx;\n        HANDLE ulAssemblyRosterIndex;\n    }\n    alias ACTCTX_SECTION_KEYED_DATA*        PACTCTX_SECTION_KEYED_DATA;\n    alias const(ACTCTX_SECTION_KEYED_DATA)* PCACTCTX_SECTION_KEYED_DATA;\n\n    enum MEMORY_RESOURCE_NOTIFICATION_TYPE {\n        LowMemoryResourceNotification,\n        HighMemoryResourceNotification\n    }\n\n} // (_WIN32_WINNT >= 0x501)\n\nstatic if (_WIN32_WINNT >= 0x410) {\n    /*  apparently used only by SetThreadExecutionState (Win2000+)\n     *  and DDK functions (version compatibility not established)\n     */\n    alias DWORD EXECUTION_STATE;\n}\n\n// Callbacks\nextern (Windows) {\n    alias DWORD function(LPVOID) LPTHREAD_START_ROUTINE;\n    alias DWORD function(LARGE_INTEGER, LARGE_INTEGER, LARGE_INTEGER, LARGE_INTEGER,\n        DWORD, DWORD, HANDLE, HANDLE, LPVOID)  LPPROGRESS_ROUTINE;\n    alias void function(PVOID) LPFIBER_START_ROUTINE;\n\n    alias BOOL function(HMODULE, LPCSTR, LPCSTR, WORD, LONG_PTR) ENUMRESLANGPROCA;\n    alias BOOL function(HMODULE, LPCWSTR, LPCWSTR, WORD, LONG_PTR) ENUMRESLANGPROCW;\n    alias BOOL function(HMODULE, LPCSTR, LPSTR, LONG_PTR) ENUMRESNAMEPROCA;\n    alias BOOL function(HMODULE, LPCWSTR, LPWSTR, LONG_PTR) ENUMRESNAMEPROCW;\n    alias BOOL function(HMODULE, LPSTR, LONG_PTR) ENUMRESTYPEPROCA;\n    alias BOOL function(HMODULE, LPWSTR, LONG_PTR) ENUMRESTYPEPROCW;\n    alias void function(DWORD, DWORD, LPOVERLAPPED) LPOVERLAPPED_COMPLETION_ROUTINE;\n    alias LONG function(LPEXCEPTION_POINTERS) PTOP_LEVEL_EXCEPTION_FILTER;\n    alias PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;\n\n    alias void function(ULONG_PTR) PAPCFUNC;\n    alias void function(PVOID, DWORD, DWORD) PTIMERAPCROUTINE;\n\n    static if (_WIN32_WINNT >= 0x500) {\n        alias void function(PVOID, BOOLEAN) WAITORTIMERCALLBACK;\n    }\n}\n\nLPTSTR MAKEINTATOM()(ushort i) {\n    return cast(LPTSTR) cast(size_t) i;\n}\n\nextern (Windows) nothrow @nogc {\n    // The following Win16 functions are obselete in Win32.\n    int _hread(HFILE, LPVOID, int);\n    int _hwrite(HFILE, LPCSTR, int);\n    HFILE _lclose(HFILE);\n    HFILE _lcreat(LPCSTR, int);\n    LONG _llseek(HFILE, LONG, int);\n    HFILE _lopen(LPCSTR, int);\n    UINT _lread(HFILE, LPVOID, UINT);\n    UINT _lwrite(HFILE, LPCSTR, UINT);\n    SIZE_T GlobalCompact(DWORD);\n    VOID GlobalFix(HGLOBAL);\n\n    // MSDN contradicts itself on GlobalFlags:\n    // \"This function is provided only for compatibility with 16-bit versions of Windows.\"\n    // but also requires Windows 2000 or above\n    UINT GlobalFlags(HGLOBAL);\n    VOID GlobalUnfix(HGLOBAL);\n    BOOL GlobalUnWire(HGLOBAL);\n    PVOID GlobalWire(HGLOBAL);\n    SIZE_T LocalCompact(UINT);\n    UINT LocalFlags(HLOCAL);\n    SIZE_T LocalShrink(HLOCAL, UINT);\n\n    /+\n    //--------------------------------------\n    // These functions are problematic\n\n    version (UseNtoSKernel) {}else {\n        /* CAREFUL: These are exported from ntoskrnl.exe and declared in winddk.h\n           as __fastcall functions, but are  exported from kernel32.dll as __stdcall */\n        static if (_WIN32_WINNT >= 0x501) {\n         VOID InitializeSListHead(PSLIST_HEADER);\n        }\n        LONG InterlockedCompareExchange(LPLONG, LONG, LONG);\n        // PVOID WINAPI InterlockedCompareExchangePointer(PVOID*, PVOID, PVOID);\n        (PVOID)InterlockedCompareExchange((LPLONG)(d)    (PVOID)InterlockedCompareExchange((LPLONG)(d), (LONG)(e), (LONG)(c))\n        LONG InterlockedDecrement(LPLONG);\n        LONG InterlockedExchange(LPLONG, LONG);\n        // PVOID WINAPI InterlockedExchangePointer(PVOID*, PVOID);\n        (PVOID)InterlockedExchange((LPLONG)((PVOID)InterlockedExchange((LPLONG)(t), (LONG)(v))\n        LONG InterlockedExchangeAdd(LPLONG, LONG);\n\n        static if (_WIN32_WINNT >= 0x501) {\n        PSLIST_ENTRY InterlockedFlushSList(PSLIST_HEADER);\n        }\n        LONG InterlockedIncrement(LPLONG);\n        static if (_WIN32_WINNT >= 0x501) {\n        PSLIST_ENTRY InterlockedPopEntrySList(PSLIST_HEADER);\n        PSLIST_ENTRY InterlockedPushEntrySList(PSLIST_HEADER, PSLIST_ENTRY);\n        }\n    } // #endif //  __USE_NTOSKRNL__\n    //--------------------------------------\n    +/\n\n    LONG InterlockedIncrement(LPLONG lpAddend);\n    LONG InterlockedDecrement(LPLONG lpAddend);\n    LONG InterlockedExchange(LPLONG Target, LONG Value);\n    LONG InterlockedExchangeAdd(LPLONG Addend, LONG Value);\n    LONG InterlockedCompareExchange(LONG *Destination, LONG Exchange, LONG Comperand);\n\n    ATOM AddAtomA(LPCSTR);\n    ATOM AddAtomW(LPCWSTR);\n    BOOL AreFileApisANSI();\n    BOOL Beep(DWORD, DWORD);\n    HANDLE BeginUpdateResourceA(LPCSTR, BOOL);\n    HANDLE BeginUpdateResourceW(LPCWSTR, BOOL);\n    BOOL BuildCommDCBA(LPCSTR, LPDCB);\n    BOOL BuildCommDCBW(LPCWSTR, LPDCB);\n    BOOL BuildCommDCBAndTimeoutsA(LPCSTR, LPDCB, LPCOMMTIMEOUTS);\n    BOOL BuildCommDCBAndTimeoutsW(LPCWSTR, LPDCB, LPCOMMTIMEOUTS);\n    BOOL CallNamedPipeA(LPCSTR, PVOID, DWORD, PVOID, DWORD, PDWORD, DWORD);\n    BOOL CallNamedPipeW(LPCWSTR, PVOID, DWORD, PVOID, DWORD, PDWORD, DWORD);\n    BOOL CancelDeviceWakeupRequest(HANDLE);\n    BOOL CheckTokenMembership(HANDLE, PSID, PBOOL);\n    BOOL ClearCommBreak(HANDLE);\n    BOOL ClearCommError(HANDLE, PDWORD, LPCOMSTAT);\n    BOOL CloseHandle(HANDLE) @trusted;\n    BOOL CommConfigDialogA(LPCSTR, HWND, LPCOMMCONFIG);\n    BOOL CommConfigDialogW(LPCWSTR, HWND, LPCOMMCONFIG);\n    LONG CompareFileTime(const(FILETIME)*, const(FILETIME)*);\n    BOOL ContinueDebugEvent(DWORD, DWORD, DWORD);\n    BOOL CopyFileA(LPCSTR, LPCSTR, BOOL);\n    BOOL CopyFileW(LPCWSTR, LPCWSTR, BOOL);\n    BOOL CopyFileExA(LPCSTR, LPCSTR, LPPROGRESS_ROUTINE, LPVOID, LPBOOL, DWORD);\n    BOOL CopyFileExW(LPCWSTR, LPCWSTR, LPPROGRESS_ROUTINE, LPVOID, LPBOOL, DWORD);\n\n    /+ FIXME\n    alias memmove RtlMoveMemory;\n    alias memcpy RtlCopyMemory;\n\n    void RtlFillMemory(PVOID dest, SIZE_T len, BYTE fill) {\n        memset(dest, fill, len);\n    }\n\n    void RtlZeroMemory(PVOID dest, SIZE_T len) {\n        RtlFillMemory(dest, len, 0);\n    }\n\n    alias RtlMoveMemory MoveMemory;\n    alias RtlCopyMemory CopyMemory;\n    alias RtlFillMemory FillMemory;\n    alias RtlZeroMemory ZeroMemory;\n    +/\n    BOOL CreateDirectoryA(LPCSTR, LPSECURITY_ATTRIBUTES);\n    BOOL CreateDirectoryW(LPCWSTR, LPSECURITY_ATTRIBUTES);\n    BOOL CreateDirectoryExA(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES);\n    BOOL CreateDirectoryExW(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);\n    HANDLE CreateEventA(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCSTR);\n    HANDLE CreateEventW(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR);\n    HANDLE CreateFileA(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);\n    HANDLE CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);\n    HANDLE CreateIoCompletionPort(HANDLE, HANDLE, ULONG_PTR, DWORD);\n    HANDLE CreateMailslotA(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES);\n    HANDLE CreateMailslotW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES);\n    HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES, BOOL, LPCSTR);\n    HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES, BOOL, LPCWSTR);\n    BOOL CreatePipe(PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD);\n    BOOL CreateProcessA(LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, PVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION);\n    BOOL CreateProcessW(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, PVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);\n    HANDLE CreateSemaphoreA(LPSECURITY_ATTRIBUTES, LONG, LONG, LPCSTR) @trusted;\n    HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES, LONG, LONG, LPCWSTR) @trusted;\n    HANDLE CreateThread(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, PVOID, DWORD, PDWORD);\n    BOOL DebugActiveProcess(DWORD);\n    void DebugBreak();\n    ATOM DeleteAtom(ATOM);\n    void DeleteCriticalSection(PCRITICAL_SECTION);\n    BOOL DeleteFileA(LPCSTR);\n    BOOL DeleteFileW(LPCWSTR);\n    BOOL DisableThreadLibraryCalls(HMODULE);\n    BOOL DosDateTimeToFileTime(WORD, WORD, LPFILETIME);\n    BOOL DuplicateHandle(HANDLE, HANDLE, HANDLE, PHANDLE, DWORD, BOOL, DWORD);\n    BOOL EndUpdateResourceA(HANDLE, BOOL);\n    BOOL EndUpdateResourceW(HANDLE, BOOL);\n    void EnterCriticalSection(LPCRITICAL_SECTION);\n    void EnterCriticalSection(shared(CRITICAL_SECTION)*);\n    BOOL EnumResourceLanguagesA(HMODULE, LPCSTR, LPCSTR, ENUMRESLANGPROC, LONG_PTR);\n    BOOL EnumResourceLanguagesW(HMODULE, LPCWSTR, LPCWSTR, ENUMRESLANGPROC, LONG_PTR);\n    BOOL EnumResourceNamesA(HMODULE, LPCSTR, ENUMRESNAMEPROC, LONG_PTR);\n    BOOL EnumResourceNamesW(HMODULE, LPCWSTR, ENUMRESNAMEPROC, LONG_PTR);\n    BOOL EnumResourceTypesA(HMODULE, ENUMRESTYPEPROC, LONG_PTR);\n    BOOL EnumResourceTypesW(HMODULE, ENUMRESTYPEPROC, LONG_PTR);\n    BOOL EscapeCommFunction(HANDLE, DWORD);\n    void ExitProcess(UINT); // Never returns\n    void ExitThread(DWORD); // Never returns\n    DWORD ExpandEnvironmentStringsA(LPCSTR, LPSTR, DWORD);\n    DWORD ExpandEnvironmentStringsW(LPCWSTR, LPWSTR, DWORD);\n    void FatalAppExitA(UINT, LPCSTR);\n    void FatalAppExitW(UINT, LPCWSTR);\n    void FatalExit(int);\n    BOOL FileTimeToDosDateTime(const(FILETIME)*, LPWORD, LPWORD);\n    BOOL FileTimeToLocalFileTime(const(FILETIME)*, LPFILETIME);\n    BOOL FileTimeToSystemTime(const(FILETIME)*, LPSYSTEMTIME);\n    ATOM FindAtomA(LPCSTR);\n    ATOM FindAtomW(LPCWSTR);\n    BOOL FindClose(HANDLE);\n    BOOL FindCloseChangeNotification(HANDLE);\n    HANDLE FindFirstChangeNotificationA(LPCSTR, BOOL, DWORD);\n    HANDLE FindFirstChangeNotificationW(LPCWSTR, BOOL, DWORD);\n    HANDLE FindFirstFileA(LPCSTR, LPWIN32_FIND_DATAA);\n    HANDLE FindFirstFileW(LPCWSTR, LPWIN32_FIND_DATAW);\n    BOOL FindNextChangeNotification(HANDLE);\n    BOOL FindNextFileA(HANDLE, LPWIN32_FIND_DATAA);\n    BOOL FindNextFileW(HANDLE, LPWIN32_FIND_DATAW);\n    HRSRC FindResourceA(HMODULE, LPCSTR, LPCSTR);\n    HRSRC FindResourceW(HINSTANCE, LPCWSTR, LPCWSTR);\n    HRSRC FindResourceExA(HINSTANCE, LPCSTR, LPCSTR, WORD);\n    HRSRC FindResourceExW(HINSTANCE, LPCWSTR, LPCWSTR, WORD);\n    BOOL FlushFileBuffers(HANDLE);\n    BOOL FlushInstructionCache(HANDLE, PCVOID, SIZE_T);\n    DWORD FormatMessageA(DWORD, PCVOID, DWORD, DWORD, LPSTR, DWORD, va_list*);\n    DWORD FormatMessageW(DWORD, PCVOID, DWORD, DWORD, LPWSTR, DWORD, va_list*);\n    BOOL FreeEnvironmentStringsA(LPSTR);\n    BOOL FreeEnvironmentStringsW(LPWSTR);\n    BOOL FreeLibrary(HMODULE);\n    void FreeLibraryAndExitThread(HMODULE, DWORD); // never returns\n    BOOL FreeResource(HGLOBAL);\n    UINT GetAtomNameA(ATOM, LPSTR, int);\n    UINT GetAtomNameW(ATOM, LPWSTR, int);\n    LPSTR GetCommandLineA();\n    LPWSTR GetCommandLineW();\n    BOOL GetCommConfig(HANDLE, LPCOMMCONFIG, PDWORD);\n    BOOL GetCommMask(HANDLE, PDWORD);\n    BOOL GetCommModemStatus(HANDLE, PDWORD);\n    BOOL GetCommProperties(HANDLE, LPCOMMPROP);\n    BOOL GetCommState(HANDLE, LPDCB);\n    BOOL GetCommTimeouts(HANDLE, LPCOMMTIMEOUTS);\n    BOOL GetComputerNameA(LPSTR, PDWORD);\n    BOOL GetComputerNameW(LPWSTR, PDWORD);\n    DWORD GetCurrentDirectoryA(DWORD, LPSTR);\n    DWORD GetCurrentDirectoryW(DWORD, LPWSTR);\n    HANDLE GetCurrentProcess();\n    DWORD GetCurrentProcessId();\n    HANDLE GetCurrentThread();\n/* In MinGW:\n#ifdef _WIN32_WCE\nextern DWORD GetCurrentThreadId(void);\n#else\nWINBASEAPI DWORD WINAPI GetCurrentThreadId(void);\n#endif\n*/\n    DWORD GetCurrentThreadId();\n\n    alias GetTickCount GetCurrentTime;\n\n    BOOL GetDefaultCommConfigA(LPCSTR, LPCOMMCONFIG, PDWORD);\n    BOOL GetDefaultCommConfigW(LPCWSTR, LPCOMMCONFIG, PDWORD);\n    BOOL GetDiskFreeSpaceA(LPCSTR, PDWORD, PDWORD, PDWORD, PDWORD);\n    BOOL GetDiskFreeSpaceW(LPCWSTR, PDWORD, PDWORD, PDWORD, PDWORD);\n    BOOL GetDiskFreeSpaceExA(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);\n    BOOL GetDiskFreeSpaceExW(LPCWSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);\n    UINT GetDriveTypeA(LPCSTR);\n    UINT GetDriveTypeW(LPCWSTR);\n    LPSTR GetEnvironmentStringsA();\n    LPWSTR GetEnvironmentStringsW();\n    DWORD GetEnvironmentVariableA(LPCSTR, LPSTR, DWORD);\n    DWORD GetEnvironmentVariableW(LPCWSTR, LPWSTR, DWORD);\n    BOOL GetExitCodeProcess(HANDLE, PDWORD);\n    BOOL GetExitCodeThread(HANDLE, PDWORD);\n    DWORD GetFileAttributesA(LPCSTR);\n    DWORD GetFileAttributesW(LPCWSTR);\n    BOOL GetFileInformationByHandle(HANDLE, LPBY_HANDLE_FILE_INFORMATION);\n    DWORD GetFileSize(HANDLE, PDWORD);\n    BOOL GetFileTime(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME);\n    DWORD GetFileType(HANDLE);\n    DWORD GetFullPathNameA(LPCSTR, DWORD, LPSTR, LPSTR*);\n    DWORD GetFullPathNameW(LPCWSTR, DWORD, LPWSTR, LPWSTR*);\n    DWORD GetLastError() @trusted;\n    void GetLocalTime(LPSYSTEMTIME);\n    DWORD GetLogicalDrives();\n    DWORD GetLogicalDriveStringsA(DWORD, LPSTR);\n    DWORD GetLogicalDriveStringsW(DWORD, LPWSTR);\n    BOOL GetMailslotInfo(HANDLE, PDWORD, PDWORD, PDWORD, PDWORD);\n    DWORD GetModuleFileNameA(HINSTANCE, LPSTR, DWORD);\n    DWORD GetModuleFileNameW(HINSTANCE, LPWSTR, DWORD);\n    HMODULE GetModuleHandleA(LPCSTR);\n    HMODULE GetModuleHandleW(LPCWSTR);\n    BOOL GetNamedPipeHandleStateA(HANDLE, PDWORD, PDWORD, PDWORD, PDWORD, LPSTR, DWORD);\n    BOOL GetNamedPipeHandleStateW(HANDLE, PDWORD, PDWORD, PDWORD, PDWORD, LPWSTR, DWORD);\n    BOOL GetNamedPipeInfo(HANDLE, PDWORD, PDWORD, PDWORD, PDWORD);\n    BOOL GetOverlappedResult(HANDLE, LPOVERLAPPED, PDWORD, BOOL);\n    DWORD GetPriorityClass(HANDLE);\n    UINT GetPrivateProfileIntA(LPCSTR, LPCSTR, INT, LPCSTR);\n    UINT GetPrivateProfileIntW(LPCWSTR, LPCWSTR, INT, LPCWSTR);\n    DWORD GetPrivateProfileSectionA(LPCSTR, LPSTR, DWORD, LPCSTR);\n    DWORD GetPrivateProfileSectionW(LPCWSTR, LPWSTR, DWORD, LPCWSTR);\n    DWORD GetPrivateProfileSectionNamesA(LPSTR, DWORD, LPCSTR);\n    DWORD GetPrivateProfileSectionNamesW(LPWSTR, DWORD, LPCWSTR);\n    DWORD GetPrivateProfileStringA(LPCSTR, LPCSTR, LPCSTR, LPSTR, DWORD, LPCSTR);\n    DWORD GetPrivateProfileStringW(LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, DWORD, LPCWSTR);\n    BOOL GetPrivateProfileStructA(LPCSTR, LPCSTR, LPVOID, UINT, LPCSTR);\n    BOOL GetPrivateProfileStructW(LPCWSTR, LPCWSTR, LPVOID, UINT, LPCWSTR);\n    FARPROC GetProcAddress(HMODULE, LPCSTR); // 1st param wrongly HINSTANCE in MinGW\n    BOOL GetProcessAffinityMask(HANDLE, PDWORD_PTR, PDWORD_PTR);\n    DWORD GetProcessVersion(DWORD);\n    UINT GetProfileIntA(LPCSTR, LPCSTR, INT);\n    UINT GetProfileIntW(LPCWSTR, LPCWSTR, INT);\n    DWORD GetProfileSectionA(LPCSTR, LPSTR, DWORD);\n    DWORD GetProfileSectionW(LPCWSTR, LPWSTR, DWORD);\n    DWORD GetProfileStringA(LPCSTR, LPCSTR, LPCSTR, LPSTR, DWORD);\n    DWORD GetProfileStringW(LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, DWORD);\n    DWORD GetShortPathNameA(LPCSTR, LPSTR, DWORD);\n    DWORD GetShortPathNameW(LPCWSTR, LPWSTR, DWORD);\n    VOID GetStartupInfoA(LPSTARTUPINFOA);\n    VOID GetStartupInfoW(LPSTARTUPINFOW);\n    HANDLE GetStdHandle(DWORD);\n    UINT GetSystemDirectoryA(LPSTR, UINT);\n    UINT GetSystemDirectoryW(LPWSTR, UINT);\n    VOID GetSystemInfo(LPSYSTEM_INFO);\n    VOID GetSystemTime(LPSYSTEMTIME);\n    BOOL GetSystemTimeAdjustment(PDWORD, PDWORD, PBOOL);\n    void GetSystemTimeAsFileTime(LPFILETIME);\n    UINT GetTempFileNameA(LPCSTR, LPCSTR, UINT, LPSTR);\n    UINT GetTempFileNameW(LPCWSTR, LPCWSTR, UINT, LPWSTR);\n    DWORD GetTempPathA(DWORD, LPSTR);\n    DWORD GetTempPathW(DWORD, LPWSTR);\n    BOOL GetThreadContext(HANDLE, LPCONTEXT);\n    int GetThreadPriority(HANDLE);\n    BOOL GetThreadSelectorEntry(HANDLE, DWORD, LPLDT_ENTRY);\n    DWORD GetTickCount();\n    DWORD GetTimeZoneInformation(LPTIME_ZONE_INFORMATION);\n    BOOL GetUserNameA (LPSTR, PDWORD);\n    BOOL GetUserNameW(LPWSTR, PDWORD);\n    DWORD GetVersion();\n    BOOL GetVersionExA(LPOSVERSIONINFOA);\n    BOOL GetVersionExW(LPOSVERSIONINFOW);\n    BOOL GetVolumeInformationA(LPCSTR, LPSTR, DWORD, PDWORD, PDWORD, PDWORD, LPSTR, DWORD);\n    BOOL GetVolumeInformationW(LPCWSTR, LPWSTR, DWORD, PDWORD, PDWORD, PDWORD, LPWSTR, DWORD);\n    UINT GetWindowsDirectoryA(LPSTR, UINT);\n    UINT GetWindowsDirectoryW(LPWSTR, UINT);\n    DWORD GetWindowThreadProcessId(HWND, PDWORD);\n    ATOM GlobalAddAtomA(LPCSTR);\n    ATOM GlobalAddAtomW(LPCWSTR);\n    ATOM GlobalDeleteAtom(ATOM);\n    ATOM GlobalFindAtomA(LPCSTR);\n    ATOM GlobalFindAtomW(LPCWSTR);\n    UINT GlobalGetAtomNameA(ATOM, LPSTR, int);\n    UINT GlobalGetAtomNameW(ATOM, LPWSTR, int);\n\n    bool HasOverlappedIoCompleted(LPOVERLAPPED lpOverlapped) {\n        return lpOverlapped.Internal != STATUS_PENDING;\n    }\n\n    BOOL InitAtomTable(DWORD);\n    VOID InitializeCriticalSection(LPCRITICAL_SECTION) @trusted;\n    /*  ??? The next two are allegedly obsolete and \"supported only for\n     *  backward compatibility with the 16-bit Windows API\".  Yet the\n     *  replacements IsBadReadPtr and IsBadWritePtr are apparently Win2000+\n     *  only.  Where's the mistake?\n     */\n    BOOL IsBadHugeReadPtr(PCVOID, UINT_PTR);\n    BOOL IsBadHugeWritePtr(PVOID, UINT_PTR);\n    BOOL IsBadReadPtr(PCVOID, UINT_PTR);\n    BOOL IsBadStringPtrA(LPCSTR, UINT_PTR);\n    BOOL IsBadStringPtrW(LPCWSTR, UINT_PTR);\n    BOOL IsBadWritePtr(PVOID, UINT_PTR);\n    void LeaveCriticalSection(LPCRITICAL_SECTION);\n    void LeaveCriticalSection(shared(CRITICAL_SECTION)*);\n    HINSTANCE LoadLibraryA(LPCSTR);\n    HINSTANCE LoadLibraryW(LPCWSTR);\n    HINSTANCE LoadLibraryExA(LPCSTR, HANDLE, DWORD);\n    HINSTANCE LoadLibraryExW(LPCWSTR, HANDLE, DWORD);\n    DWORD LoadModule(LPCSTR, PVOID);\n    HGLOBAL LoadResource(HINSTANCE, HRSRC);\n    BOOL LocalFileTimeToFileTime(const(FILETIME)*, LPFILETIME);\n    BOOL LockFile(HANDLE, DWORD, DWORD, DWORD, DWORD);\n    PVOID LockResource(HGLOBAL);\n\n    LPSTR lstrcatA(LPSTR, LPCSTR);\n    LPWSTR lstrcatW(LPWSTR, LPCWSTR);\n    int lstrcmpA(LPCSTR, LPCSTR);\n    int lstrcmpiA(LPCSTR, LPCSTR);\n    int lstrcmpiW(LPCWSTR, LPCWSTR);\n    int lstrcmpW(LPCWSTR, LPCWSTR);\n    LPSTR lstrcpyA(LPSTR, LPCSTR);\n    LPSTR lstrcpynA(LPSTR, LPCSTR, int);\n    LPWSTR lstrcpynW(LPWSTR, LPCWSTR, int);\n    LPWSTR lstrcpyW(LPWSTR, LPCWSTR);\n    int lstrlenA(LPCSTR);\n    int lstrlenW(LPCWSTR);\n\n    BOOL MoveFileA(LPCSTR, LPCSTR);\n    BOOL MoveFileW(LPCWSTR, LPCWSTR);\n    int MulDiv(int, int, int);\n    HANDLE OpenEventA(DWORD, BOOL, LPCSTR);\n    HANDLE OpenEventW(DWORD, BOOL, LPCWSTR);\n    deprecated HFILE OpenFile(LPCSTR, LPOFSTRUCT, UINT);\n    HANDLE OpenMutexA(DWORD, BOOL, LPCSTR);\n    HANDLE OpenMutexW(DWORD, BOOL, LPCWSTR);\n    HANDLE OpenProcess(DWORD, BOOL, DWORD);\n    HANDLE OpenSemaphoreA(DWORD, BOOL, LPCSTR);\n    HANDLE OpenSemaphoreW(DWORD, BOOL, LPCWSTR);\n    void OutputDebugStringA(LPCSTR);\n    void OutputDebugStringW(LPCWSTR);\n    BOOL PeekNamedPipe(HANDLE, PVOID, DWORD, PDWORD, PDWORD, PDWORD);\n    BOOL PulseEvent(HANDLE);\n    BOOL PurgeComm(HANDLE, DWORD);\n    BOOL QueryPerformanceCounter(PLARGE_INTEGER);\n    BOOL QueryPerformanceFrequency(PLARGE_INTEGER);\n    DWORD QueueUserAPC(PAPCFUNC, HANDLE, ULONG_PTR);\n    void RaiseException(DWORD, DWORD, DWORD, const(ULONG_PTR)*);\n    BOOL ReadFile(HANDLE, PVOID, DWORD, PDWORD, LPOVERLAPPED);\n    BOOL ReadFileEx(HANDLE, PVOID, DWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE);\n    BOOL ReadProcessMemory(HANDLE, PCVOID, PVOID, SIZE_T, SIZE_T*);\n    BOOL ReleaseMutex(HANDLE);\n    BOOL ReleaseSemaphore(HANDLE, LONG, LPLONG);\n    BOOL RemoveDirectoryA(LPCSTR);\n    BOOL RemoveDirectoryW(LPCWSTR);\n/* In MinGW:\n#ifdef _WIN32_WCE\nextern BOOL ResetEvent(HANDLE);\n#else\nWINBASEAPI BOOL WINAPI ResetEvent(HANDLE);\n#endif\n*/\n    BOOL ResetEvent(HANDLE);\n    DWORD ResumeThread(HANDLE);\n    DWORD SearchPathA(LPCSTR, LPCSTR, LPCSTR, DWORD, LPSTR, LPSTR*);\n    DWORD SearchPathW(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPWSTR, LPWSTR*);\n    BOOL SetCommBreak(HANDLE);\n    BOOL SetCommConfig(HANDLE, LPCOMMCONFIG, DWORD);\n    BOOL SetCommMask(HANDLE, DWORD);\n    BOOL SetCommState(HANDLE, LPDCB);\n    BOOL SetCommTimeouts(HANDLE, LPCOMMTIMEOUTS);\n    BOOL SetComputerNameA(LPCSTR);\n    BOOL SetComputerNameW(LPCWSTR);\n    BOOL SetCurrentDirectoryA(LPCSTR);\n    BOOL SetCurrentDirectoryW(LPCWSTR);\n    BOOL SetDefaultCommConfigA(LPCSTR, LPCOMMCONFIG, DWORD);\n    BOOL SetDefaultCommConfigW(LPCWSTR, LPCOMMCONFIG, DWORD);\n    BOOL SetEndOfFile(HANDLE);\n    BOOL SetEnvironmentVariableA(LPCSTR, LPCSTR);\n    BOOL SetEnvironmentVariableW(LPCWSTR, LPCWSTR);\n    UINT SetErrorMode(UINT);\n/* In MinGW:\n#ifdef _WIN32_WCE\nextern BOOL SetEvent(HANDLE);\n#else\nWINBASEAPI BOOL WINAPI SetEvent(HANDLE);\n#endif\n*/\n    BOOL SetEvent(HANDLE);\n    VOID SetFileApisToANSI();\n    VOID SetFileApisToOEM();\n    BOOL SetFileAttributesA(LPCSTR, DWORD);\n    BOOL SetFileAttributesW(LPCWSTR, DWORD);\n    DWORD SetFilePointer(HANDLE, LONG, PLONG, DWORD);\n    BOOL SetFileTime(HANDLE, const(FILETIME)*, const(FILETIME)*, const(FILETIME)*);\n    deprecated UINT SetHandleCount(UINT);\n    void SetLastError(DWORD);\n    void SetLastErrorEx(DWORD, DWORD);\n    BOOL SetLocalTime(const(SYSTEMTIME)*);\n    BOOL SetMailslotInfo(HANDLE, DWORD);\n    BOOL SetNamedPipeHandleState(HANDLE, PDWORD, PDWORD, PDWORD);\n    BOOL SetPriorityClass(HANDLE, DWORD);\n    BOOL SetStdHandle(DWORD, HANDLE);\n    BOOL SetSystemTime(const(SYSTEMTIME)*);\n    DWORD_PTR SetThreadAffinityMask(HANDLE, DWORD_PTR);\n    BOOL SetThreadContext(HANDLE, const(CONTEXT)*);\n    BOOL SetThreadPriority(HANDLE, int);\n    BOOL SetTimeZoneInformation(const(TIME_ZONE_INFORMATION)*);\n    LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER);\n    BOOL SetupComm(HANDLE, DWORD, DWORD);\n    BOOL SetVolumeLabelA(LPCSTR, LPCSTR);\n    BOOL SetVolumeLabelW(LPCWSTR, LPCWSTR);\n\n    DWORD SizeofResource(HINSTANCE, HRSRC);\n    void Sleep(DWORD);\n    DWORD SleepEx(DWORD, BOOL);\n    DWORD SuspendThread(HANDLE);\n    BOOL SystemTimeToFileTime(const(SYSTEMTIME)*, LPFILETIME);\n    BOOL TerminateProcess(HANDLE, UINT);\n    BOOL TerminateThread(HANDLE, DWORD);\n    DWORD TlsAlloc();\n    BOOL TlsFree(DWORD);\n    PVOID TlsGetValue(DWORD);\n    BOOL TlsSetValue(DWORD, PVOID);\n    BOOL TransactNamedPipe(HANDLE, PVOID, DWORD, PVOID, DWORD, PDWORD, LPOVERLAPPED);\n    BOOL TransmitCommChar(HANDLE, char);\n    LONG UnhandledExceptionFilter(LPEXCEPTION_POINTERS);\n    BOOL UnlockFile(HANDLE, DWORD, DWORD, DWORD, DWORD);\n    BOOL WaitCommEvent(HANDLE, PDWORD, LPOVERLAPPED);\n    BOOL WaitForDebugEvent(LPDEBUG_EVENT, DWORD);\n    DWORD WaitForMultipleObjects(DWORD, const(HANDLE)*, BOOL, DWORD);\n    DWORD WaitForMultipleObjectsEx(DWORD, const(HANDLE)*, BOOL, DWORD, BOOL);\n    DWORD WaitForSingleObject(HANDLE, DWORD);\n    DWORD WaitForSingleObjectEx(HANDLE, DWORD, BOOL);\n    BOOL WaitNamedPipeA(LPCSTR, DWORD);\n    BOOL WaitNamedPipeW(LPCWSTR, DWORD);\n    // undocumented on MSDN\n    BOOL WinLoadTrustProvider(GUID*);\n    BOOL WriteFile(HANDLE, PCVOID, DWORD, PDWORD, LPOVERLAPPED);\n    BOOL WriteFileEx(HANDLE, PCVOID, DWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE);\n    BOOL WritePrivateProfileSectionA(LPCSTR, LPCSTR, LPCSTR);\n    BOOL WritePrivateProfileSectionW(LPCWSTR, LPCWSTR, LPCWSTR);\n    BOOL WritePrivateProfileStringA(LPCSTR, LPCSTR, LPCSTR, LPCSTR);\n    BOOL WritePrivateProfileStringW(LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR);\n    BOOL WritePrivateProfileStructA(LPCSTR, LPCSTR, LPVOID, UINT, LPCSTR);\n    BOOL WritePrivateProfileStructW(LPCWSTR, LPCWSTR, LPVOID, UINT, LPCWSTR);\n    BOOL WriteProcessMemory(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*);\n    BOOL WriteProfileSectionA(LPCSTR, LPCSTR);\n    BOOL WriteProfileSectionW(LPCWSTR, LPCWSTR);\n    BOOL WriteProfileStringA(LPCSTR, LPCSTR, LPCSTR);\n    BOOL WriteProfileStringW(LPCWSTR, LPCWSTR, LPCWSTR);\n\n    /*  Memory allocation functions.\n     *  MSDN documents these erroneously as Win2000+; thus it is uncertain what\n     *  version compatibility they really have.\n     */\n    HGLOBAL GlobalAlloc(UINT, SIZE_T);\n    HGLOBAL GlobalDiscard(HGLOBAL);\n    HGLOBAL GlobalFree(HGLOBAL);\n    HGLOBAL GlobalHandle(PCVOID);\n    LPVOID GlobalLock(HGLOBAL);\n    VOID GlobalMemoryStatus(LPMEMORYSTATUS);\n    HGLOBAL GlobalReAlloc(HGLOBAL, SIZE_T, UINT);\n    SIZE_T GlobalSize(HGLOBAL);\n    BOOL GlobalUnlock(HGLOBAL);\n    PVOID HeapAlloc(HANDLE, DWORD, SIZE_T);\n    SIZE_T HeapCompact(HANDLE, DWORD);\n    HANDLE HeapCreate(DWORD, SIZE_T, SIZE_T);\n    BOOL HeapDestroy(HANDLE);\n    BOOL HeapFree(HANDLE, DWORD, PVOID);\n    BOOL HeapLock(HANDLE);\n    PVOID HeapReAlloc(HANDLE, DWORD, PVOID, SIZE_T);\n    SIZE_T HeapSize(HANDLE, DWORD, PCVOID);\n    BOOL HeapUnlock(HANDLE);\n    BOOL HeapValidate(HANDLE, DWORD, PCVOID);\n    BOOL HeapWalk(HANDLE, LPPROCESS_HEAP_ENTRY);\n    HLOCAL LocalAlloc(UINT, SIZE_T);\n    HLOCAL LocalDiscard(HLOCAL);\n    HLOCAL LocalFree(HLOCAL);\n    HLOCAL LocalHandle(LPCVOID);\n    PVOID LocalLock(HLOCAL);\n    HLOCAL LocalReAlloc(HLOCAL, SIZE_T, UINT);\n    SIZE_T LocalSize(HLOCAL);\n    BOOL LocalUnlock(HLOCAL);\n    PVOID VirtualAlloc(PVOID, SIZE_T, DWORD, DWORD);\n    PVOID VirtualAllocEx(HANDLE, PVOID, SIZE_T, DWORD, DWORD);\n    BOOL VirtualFree(PVOID, SIZE_T, DWORD);\n    BOOL VirtualFreeEx(HANDLE, PVOID, SIZE_T, DWORD);\n    BOOL VirtualLock(PVOID, SIZE_T);\n    BOOL VirtualProtect(PVOID, SIZE_T, DWORD, PDWORD);\n    BOOL VirtualProtectEx(HANDLE, PVOID, SIZE_T, DWORD, PDWORD);\n    SIZE_T VirtualQuery(LPCVOID, PMEMORY_BASIC_INFORMATION, SIZE_T);\n    SIZE_T VirtualQueryEx(HANDLE, LPCVOID, PMEMORY_BASIC_INFORMATION, SIZE_T);\n    BOOL VirtualUnlock(PVOID, SIZE_T);\n// not in MinGW 4.0 - ???\n    static if (_WIN32_WINNT >= 0x600) {\n        BOOL CancelIoEx(HANDLE, LPOVERLAPPED);\n    }\n\n    BOOL CancelIo(HANDLE);\n    BOOL CancelWaitableTimer(HANDLE);\n    PVOID ConvertThreadToFiber(PVOID);\n    LPVOID CreateFiber(SIZE_T, LPFIBER_START_ROUTINE, LPVOID);\n    HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES, BOOL, LPCSTR);\n    HANDLE CreateWaitableTimerW(LPSECURITY_ATTRIBUTES, BOOL, LPCWSTR);\n    void DeleteFiber(PVOID);\n    BOOL GetFileAttributesExA(LPCSTR, GET_FILEEX_INFO_LEVELS, PVOID);\n    BOOL GetFileAttributesExW(LPCWSTR, GET_FILEEX_INFO_LEVELS, PVOID);\n    DWORD GetLongPathNameA(LPCSTR, LPSTR, DWORD);\n    DWORD GetLongPathNameW(LPCWSTR, LPWSTR, DWORD);\n    BOOL InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION, DWORD);\n    BOOL IsDebuggerPresent();\n    HANDLE OpenWaitableTimerA(DWORD, BOOL, LPCSTR);\n    HANDLE OpenWaitableTimerW(DWORD, BOOL, LPCWSTR);\n    DWORD QueryDosDeviceA(LPCSTR, LPSTR, DWORD);\n    DWORD QueryDosDeviceW(LPCWSTR, LPWSTR, DWORD);\n    BOOL SetWaitableTimer(HANDLE, const(LARGE_INTEGER)*, LONG, PTIMERAPCROUTINE, PVOID, BOOL);\n    void SwitchToFiber(PVOID);\n\n    static if (_WIN32_WINNT >= 0x500) {\n        HANDLE OpenThread(DWORD, BOOL, DWORD);\n    }\n\n    BOOL AccessCheck(PSECURITY_DESCRIPTOR, HANDLE, DWORD, PGENERIC_MAPPING, PPRIVILEGE_SET, PDWORD, PDWORD, PBOOL);\n    BOOL AccessCheckAndAuditAlarmA(LPCSTR, LPVOID, LPSTR, LPSTR, PSECURITY_DESCRIPTOR, DWORD, PGENERIC_MAPPING, BOOL, PDWORD, PBOOL, PBOOL);\n    BOOL AccessCheckAndAuditAlarmW(LPCWSTR, LPVOID, LPWSTR, LPWSTR, PSECURITY_DESCRIPTOR, DWORD, PGENERIC_MAPPING, BOOL, PDWORD, PBOOL, PBOOL);\n    BOOL AddAccessAllowedAce(PACL, DWORD, DWORD, PSID);\n    BOOL AddAccessDeniedAce(PACL, DWORD, DWORD, PSID);\n    BOOL AddAce(PACL, DWORD, DWORD, PVOID, DWORD);\n    BOOL AddAuditAccessAce(PACL, DWORD, DWORD, PSID, BOOL, BOOL);\n    BOOL AdjustTokenGroups(HANDLE, BOOL, PTOKEN_GROUPS, DWORD, PTOKEN_GROUPS, PDWORD);\n    BOOL AdjustTokenPrivileges(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);\n    BOOL AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, PSID*);\n    BOOL AllocateLocallyUniqueId(PLUID);\n    BOOL AreAllAccessesGranted(DWORD, DWORD);\n    BOOL AreAnyAccessesGranted(DWORD, DWORD);\n    BOOL BackupEventLogA(HANDLE, LPCSTR);\n    BOOL BackupEventLogW(HANDLE, LPCWSTR);\n    BOOL BackupRead(HANDLE, LPBYTE, DWORD, LPDWORD, BOOL, BOOL, LPVOID*);\n    BOOL BackupSeek(HANDLE, DWORD, DWORD, LPDWORD, LPDWORD, LPVOID*);\n    BOOL BackupWrite(HANDLE, LPBYTE, DWORD, LPDWORD, BOOL, BOOL, LPVOID*);\n    BOOL ClearEventLogA(HANDLE, LPCSTR);\n    BOOL ClearEventLogW(HANDLE, LPCWSTR);\n    BOOL CloseEventLog(HANDLE);\n    BOOL ConnectNamedPipe(HANDLE, LPOVERLAPPED);\n    BOOL CopySid(DWORD, PSID, PSID);\n    HANDLE CreateNamedPipeA(LPCSTR, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPSECURITY_ATTRIBUTES);\n    HANDLE CreateNamedPipeW(LPCWSTR, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPSECURITY_ATTRIBUTES);\n    BOOL CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR*, BOOL, HANDLE, PGENERIC_MAPPING);\n    BOOL CreateProcessAsUserA(HANDLE, LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, PVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION);\n    BOOL CreateProcessAsUserW(HANDLE, LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, PVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);\n    HANDLE CreateRemoteThread(HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD);\n    DWORD CreateTapePartition(HANDLE, DWORD, DWORD, DWORD);\n    BOOL DefineDosDeviceA(DWORD, LPCSTR, LPCSTR);\n    BOOL DefineDosDeviceW(DWORD, LPCWSTR, LPCWSTR);\n    BOOL DeleteAce(PACL, DWORD);\n    BOOL DeregisterEventSource(HANDLE);\n    BOOL DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR*);\n    BOOL DeviceIoControl(HANDLE, DWORD, PVOID, DWORD, PVOID, DWORD, PDWORD, POVERLAPPED);\n    BOOL DisconnectNamedPipe(HANDLE);\n    BOOL DuplicateToken(HANDLE, SECURITY_IMPERSONATION_LEVEL, PHANDLE);\n    BOOL DuplicateTokenEx(HANDLE, DWORD, LPSECURITY_ATTRIBUTES, SECURITY_IMPERSONATION_LEVEL, TOKEN_TYPE, PHANDLE);\n    BOOL EqualPrefixSid(PSID, PSID);\n    BOOL EqualSid(PSID, PSID);\n    DWORD EraseTape(HANDLE, DWORD, BOOL);\n    HANDLE FindFirstFileExA(LPCSTR, FINDEX_INFO_LEVELS, PVOID, FINDEX_SEARCH_OPS, PVOID, DWORD);\n    HANDLE FindFirstFileExW(LPCWSTR, FINDEX_INFO_LEVELS, PVOID, FINDEX_SEARCH_OPS, PVOID, DWORD);\n    BOOL FindFirstFreeAce(PACL, PVOID*);\n    PVOID FreeSid(PSID);\n    BOOL GetAce(PACL, DWORD, LPVOID*);\n    BOOL GetAclInformation(PACL, PVOID, DWORD, ACL_INFORMATION_CLASS);\n    BOOL GetBinaryTypeA(LPCSTR, PDWORD);\n    BOOL GetBinaryTypeW(LPCWSTR, PDWORD);\n    DWORD GetCompressedFileSizeA(LPCSTR, PDWORD);\n    DWORD GetCompressedFileSizeW(LPCWSTR, PDWORD);\n    BOOL GetCurrentHwProfileA(LPHW_PROFILE_INFOA);\n    BOOL GetCurrentHwProfileW(LPHW_PROFILE_INFOW);\n    BOOL GetFileSecurityA(LPCSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, PDWORD);\n    BOOL GetFileSecurityW(LPCWSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, PDWORD);\n    BOOL GetHandleInformation(HANDLE, PDWORD);\n    BOOL GetKernelObjectSecurity(HANDLE, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, PDWORD);\n    DWORD GetLengthSid(PSID);\n    BOOL GetNumberOfEventLogRecords(HANDLE, PDWORD);\n    BOOL GetOldestEventLogRecord(HANDLE, PDWORD);\n    BOOL GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, PDWORD);\n    BOOL GetProcessPriorityBoost(HANDLE, PBOOL);\n    BOOL GetProcessShutdownParameters(PDWORD, PDWORD);\n    BOOL GetProcessTimes(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);\n    HWINSTA GetProcessWindowStation();\n    BOOL GetProcessWorkingSetSize(HANDLE, PSIZE_T, PSIZE_T);\n    BOOL GetQueuedCompletionStatus(HANDLE, PDWORD, PULONG_PTR, LPOVERLAPPED*, DWORD);\n    BOOL GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR_CONTROL, PDWORD);\n    BOOL GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR, LPBOOL, PACL*, LPBOOL);\n    BOOL GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR, PSID*, LPBOOL);\n    DWORD GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR);\n    BOOL GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR, PSID*, LPBOOL);\n    BOOL GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR, LPBOOL, PACL*, LPBOOL);\n    PSID_IDENTIFIER_AUTHORITY GetSidIdentifierAuthority(PSID);\n    DWORD GetSidLengthRequired(UCHAR);\n    PDWORD GetSidSubAuthority(PSID, DWORD);\n    PUCHAR GetSidSubAuthorityCount(PSID);\n    DWORD GetTapeParameters(HANDLE, DWORD, PDWORD, PVOID);\n    DWORD GetTapePosition(HANDLE, DWORD, PDWORD, PDWORD, PDWORD);\n    DWORD GetTapeStatus(HANDLE);\n    BOOL GetThreadPriorityBoost(HANDLE, PBOOL);\n    BOOL GetThreadTimes(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);\n    BOOL GetTokenInformation(HANDLE, TOKEN_INFORMATION_CLASS, PVOID, DWORD, PDWORD);\n    BOOL ImpersonateLoggedOnUser(HANDLE);\n    BOOL ImpersonateNamedPipeClient(HANDLE);\n    BOOL ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL);\n    BOOL InitializeAcl(PACL, DWORD, DWORD);\n    DWORD SetCriticalSectionSpinCount(LPCRITICAL_SECTION, DWORD);\n    BOOL InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR, DWORD);\n    BOOL InitializeSid(PSID, PSID_IDENTIFIER_AUTHORITY, BYTE);\n    BOOL IsProcessorFeaturePresent(DWORD);\n    BOOL IsTextUnicode(PCVOID, int, LPINT);\n    BOOL IsValidAcl(PACL);\n    BOOL IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR);\n    BOOL IsValidSid(PSID);\n    BOOL LockFileEx(HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED);\n    BOOL LogonUserA(LPSTR, LPSTR, LPSTR, DWORD, DWORD, PHANDLE);\n    BOOL LogonUserW(LPWSTR, LPWSTR, LPWSTR, DWORD, DWORD, PHANDLE);\n    BOOL LookupAccountNameA(LPCSTR, LPCSTR, PSID, PDWORD, LPSTR, PDWORD, PSID_NAME_USE);\n    BOOL LookupAccountNameW(LPCWSTR, LPCWSTR, PSID, PDWORD, LPWSTR, PDWORD, PSID_NAME_USE);\n    BOOL LookupAccountSidA(LPCSTR, PSID, LPSTR, PDWORD, LPSTR, PDWORD, PSID_NAME_USE);\n    BOOL LookupAccountSidW(LPCWSTR, PSID, LPWSTR, PDWORD, LPWSTR, PDWORD, PSID_NAME_USE);\n    BOOL LookupPrivilegeDisplayNameA(LPCSTR, LPCSTR, LPSTR, PDWORD, PDWORD);\n    BOOL LookupPrivilegeDisplayNameW(LPCWSTR, LPCWSTR, LPWSTR, PDWORD, PDWORD);\n    BOOL LookupPrivilegeNameA(LPCSTR, PLUID, LPSTR, PDWORD);\n    BOOL LookupPrivilegeNameW(LPCWSTR, PLUID, LPWSTR, PDWORD);\n    BOOL LookupPrivilegeValueA(LPCSTR, LPCSTR, PLUID);\n    BOOL LookupPrivilegeValueW(LPCWSTR, LPCWSTR, PLUID);\n    BOOL MakeAbsoluteSD(PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, PDWORD, PACL, PDWORD, PACL, PDWORD, PSID, PDWORD, PSID, PDWORD);\n    BOOL MakeSelfRelativeSD(PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, PDWORD);\n    VOID MapGenericMask(PDWORD, PGENERIC_MAPPING);\n    BOOL MoveFileExA(LPCSTR, LPCSTR, DWORD);\n    BOOL MoveFileExW(LPCWSTR, LPCWSTR, DWORD);\n    BOOL NotifyChangeEventLog(HANDLE, HANDLE);\n    BOOL ObjectCloseAuditAlarmA(LPCSTR, PVOID, BOOL);\n    BOOL ObjectCloseAuditAlarmW(LPCWSTR, PVOID, BOOL);\n    BOOL ObjectDeleteAuditAlarmA(LPCSTR, PVOID, BOOL);\n    BOOL ObjectDeleteAuditAlarmW(LPCWSTR, PVOID, BOOL);\n    BOOL ObjectOpenAuditAlarmA(LPCSTR, PVOID, LPSTR, LPSTR, PSECURITY_DESCRIPTOR, HANDLE, DWORD, DWORD, PPRIVILEGE_SET, BOOL, BOOL, PBOOL);\n    BOOL ObjectOpenAuditAlarmW(LPCWSTR, PVOID, LPWSTR, LPWSTR, PSECURITY_DESCRIPTOR, HANDLE, DWORD, DWORD, PPRIVILEGE_SET, BOOL, BOOL, PBOOL);\n    BOOL ObjectPrivilegeAuditAlarmA(LPCSTR, PVOID, HANDLE, DWORD, PPRIVILEGE_SET, BOOL);\n    BOOL ObjectPrivilegeAuditAlarmW(LPCWSTR, PVOID, HANDLE, DWORD, PPRIVILEGE_SET, BOOL);\n    HANDLE OpenBackupEventLogA(LPCSTR, LPCSTR);\n    HANDLE OpenBackupEventLogW(LPCWSTR, LPCWSTR);\n    HANDLE OpenEventLogA(LPCSTR, LPCSTR);\n    HANDLE OpenEventLogW(LPCWSTR, LPCWSTR);\n    BOOL OpenProcessToken(HANDLE, DWORD, PHANDLE);\n    BOOL OpenThreadToken(HANDLE, DWORD, BOOL, PHANDLE);\n    BOOL PostQueuedCompletionStatus(HANDLE, DWORD, ULONG_PTR, LPOVERLAPPED);\n    DWORD PrepareTape(HANDLE, DWORD, BOOL);\n    BOOL PrivilegeCheck(HANDLE, PPRIVILEGE_SET, PBOOL);\n    BOOL PrivilegedServiceAuditAlarmA(LPCSTR, LPCSTR, HANDLE, PPRIVILEGE_SET, BOOL);\n    BOOL PrivilegedServiceAuditAlarmW(LPCWSTR, LPCWSTR, HANDLE, PPRIVILEGE_SET, BOOL);\n    BOOL ReadDirectoryChangesW(HANDLE, PVOID, DWORD, BOOL, DWORD, PDWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE);\n    BOOL ReadEventLogA(HANDLE, DWORD, DWORD, PVOID, DWORD, DWORD*, DWORD*);\n    BOOL ReadEventLogW(HANDLE, DWORD, DWORD, PVOID, DWORD, DWORD*, DWORD*);\n    BOOL ReadFileScatter(HANDLE, FILE_SEGMENT_ELEMENT*, DWORD, LPDWORD, LPOVERLAPPED);\n    HANDLE RegisterEventSourceA (LPCSTR, LPCSTR);\n    HANDLE RegisterEventSourceW(LPCWSTR, LPCWSTR);\n    BOOL ReportEventA(HANDLE, WORD, WORD, DWORD, PSID, WORD, DWORD, LPCSTR*, PVOID);\n    BOOL ReportEventW(HANDLE, WORD, WORD, DWORD, PSID, WORD, DWORD, LPCWSTR*, PVOID);\n    BOOL RevertToSelf();\n    BOOL SetAclInformation(PACL, PVOID, DWORD, ACL_INFORMATION_CLASS);\n    BOOL SetFileSecurityA(LPCSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR);\n    BOOL SetFileSecurityW(LPCWSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR);\n    BOOL SetHandleInformation(HANDLE, DWORD, DWORD);\n    BOOL SetKernelObjectSecurity(HANDLE, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR);\n    BOOL SetPrivateObjectSecurity(SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR*, PGENERIC_MAPPING, HANDLE);\n    BOOL SetProcessAffinityMask(HANDLE, DWORD_PTR);\n    BOOL SetProcessPriorityBoost(HANDLE, BOOL);\n    BOOL SetProcessShutdownParameters(DWORD, DWORD);\n    BOOL SetProcessWorkingSetSize(HANDLE, SIZE_T, SIZE_T);\n    BOOL SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR, BOOL, PACL, BOOL);\n    BOOL SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR, PSID, BOOL);\n    BOOL SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR, PSID, BOOL);\n    BOOL SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR, BOOL, PACL, BOOL);\n    BOOL SetSystemTimeAdjustment(DWORD, BOOL);\n    DWORD SetTapeParameters(HANDLE, DWORD, PVOID);\n    DWORD SetTapePosition(HANDLE, DWORD, DWORD, DWORD, DWORD, BOOL);\n    BOOL SetThreadPriorityBoost(HANDLE, BOOL);\n    BOOL SetThreadToken(PHANDLE, HANDLE);\n    BOOL SetTokenInformation(HANDLE, TOKEN_INFORMATION_CLASS, PVOID, DWORD);\n    DWORD SignalObjectAndWait(HANDLE, HANDLE, DWORD, BOOL);\n    BOOL SwitchToThread();\n    BOOL SystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME);\n    BOOL TzSpecificLocalTimeToSystemTime(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME);\n    BOOL TryEnterCriticalSection(LPCRITICAL_SECTION);\n    BOOL TryEnterCriticalSection(shared(CRITICAL_SECTION)*);\n    BOOL UnlockFileEx(HANDLE, DWORD, DWORD, DWORD, LPOVERLAPPED);\n    BOOL UpdateResourceA(HANDLE, LPCSTR, LPCSTR, WORD, PVOID, DWORD);\n    BOOL UpdateResourceW(HANDLE, LPCWSTR, LPCWSTR, WORD, PVOID, DWORD);\n    BOOL WriteFileGather(HANDLE, FILE_SEGMENT_ELEMENT*, DWORD, LPDWORD, LPOVERLAPPED);\n    DWORD WriteTapemark(HANDLE, DWORD, DWORD, BOOL);\n\n    static if (_WIN32_WINNT >= 0x500) {\n        BOOL AddAccessAllowedAceEx(PACL, DWORD, DWORD, DWORD, PSID);\n        BOOL AddAccessDeniedAceEx(PACL, DWORD, DWORD, DWORD, PSID);\n        PVOID AddVectoredExceptionHandler(ULONG, PVECTORED_EXCEPTION_HANDLER);\n        BOOL AllocateUserPhysicalPages(HANDLE, PULONG_PTR, PULONG_PTR);\n        BOOL AssignProcessToJobObject(HANDLE, HANDLE);\n        BOOL ChangeTimerQueueTimer(HANDLE,HANDLE,ULONG,ULONG);\n        LPVOID CreateFiberEx(SIZE_T, SIZE_T, DWORD, LPFIBER_START_ROUTINE, LPVOID);\n        HANDLE CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR);\n        HANDLE CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCWSTR);\n        BOOL CreateHardLinkA(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES);\n        BOOL CreateHardLinkW(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);\n        HANDLE CreateJobObjectA(LPSECURITY_ATTRIBUTES, LPCSTR);\n        HANDLE CreateJobObjectW(LPSECURITY_ATTRIBUTES, LPCWSTR);\n        BOOL CreateProcessWithLogonW(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPCWSTR, LPWSTR, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);\n        HANDLE CreateTimerQueue();\n        BOOL CreateTimerQueueTimer(PHANDLE, HANDLE, WAITORTIMERCALLBACK, PVOID, DWORD, DWORD, ULONG);\n        BOOL DeleteTimerQueue(HANDLE);\n        BOOL DeleteTimerQueueEx(HANDLE, HANDLE);\n        BOOL DeleteTimerQueueTimer(HANDLE, HANDLE, HANDLE);\n        BOOL DeleteVolumeMountPointA(LPCSTR);\n        BOOL DeleteVolumeMountPointW(LPCWSTR);\n        BOOL DnsHostnameToComputerNameA(LPCSTR, LPSTR, LPDWORD);\n        BOOL DnsHostnameToComputerNameW(LPCWSTR, LPWSTR, LPDWORD);\n        BOOL EncryptFileA(LPCSTR);\n        BOOL EncryptFileW(LPCWSTR);\n        BOOL FileEncryptionStatusA(LPCSTR, LPDWORD);\n        BOOL FileEncryptionStatusW(LPCWSTR, LPDWORD);\n        HANDLE FindFirstVolumeA(LPCSTR, DWORD);\n        HANDLE FindFirstVolumeMountPointA(LPSTR, LPSTR, DWORD);\n        HANDLE FindFirstVolumeMountPointW(LPWSTR, LPWSTR, DWORD);\n        HANDLE FindFirstVolumeW(LPCWSTR, DWORD);\n        BOOL FindNextVolumeA(HANDLE, LPCSTR, DWORD);\n        BOOL FindNextVolumeW(HANDLE, LPWSTR, DWORD);\n        BOOL FindNextVolumeMountPointA(HANDLE, LPSTR, DWORD);\n        BOOL FindNextVolumeMountPointW(HANDLE, LPWSTR, DWORD);\n        BOOL FindVolumeClose(HANDLE);\n        BOOL FindVolumeMountPointClose(HANDLE);\n        BOOL FlushViewOfFile(PCVOID, SIZE_T);\n        BOOL FreeUserPhysicalPages(HANDLE, PULONG_PTR, PULONG_PTR);\n        BOOL GetComputerNameExA(COMPUTER_NAME_FORMAT, LPSTR, LPDWORD);\n        BOOL GetComputerNameExW(COMPUTER_NAME_FORMAT, LPWSTR, LPDWORD);\n        BOOL GetFileSizeEx(HANDLE, PLARGE_INTEGER);\n        BOOL GetModuleHandleExA(DWORD, LPCSTR, HMODULE*);\n        BOOL GetModuleHandleExW(DWORD, LPCWSTR, HMODULE*);\n        HANDLE GetProcessHeap();\n        DWORD GetProcessHeaps(DWORD, PHANDLE);\n        BOOL GetProcessIoCounters(HANDLE, PIO_COUNTERS);\n        BOOL GetSystemPowerStatus(LPSYSTEM_POWER_STATUS);\n        UINT GetSystemWindowsDirectoryA(LPSTR, UINT);\n        UINT GetSystemWindowsDirectoryW(LPWSTR, UINT);\n        BOOL GetVolumeNameForVolumeMountPointA(LPCSTR, LPSTR, DWORD);\n        BOOL GetVolumeNameForVolumeMountPointW(LPCWSTR, LPWSTR, DWORD);\n        BOOL GetVolumePathNameA(LPCSTR, LPSTR, DWORD);\n        BOOL GetVolumePathNameW(LPCWSTR, LPWSTR, DWORD);\n        BOOL GlobalMemoryStatusEx(LPMEMORYSTATUSEX);\n        BOOL IsBadCodePtr(FARPROC);\n        BOOL IsSystemResumeAutomatic();\n        BOOL MapUserPhysicalPages(PVOID, ULONG_PTR, PULONG_PTR);\n        BOOL MapUserPhysicalPagesScatter(PVOID*, ULONG_PTR, PULONG_PTR);\n        PVOID MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);\n        PVOID MapViewOfFileEx(HANDLE, DWORD, DWORD, DWORD, SIZE_T, PVOID);\n        HANDLE OpenFileMappingA(DWORD, BOOL, LPCSTR);\n        HANDLE OpenFileMappingW(DWORD, BOOL, LPCWSTR);\n        BOOL ProcessIdToSessionId(DWORD, DWORD*);\n        BOOL QueryInformationJobObject(HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD, LPDWORD);\n        ULONG RemoveVectoredExceptionHandler(PVOID);\n        BOOL ReplaceFileA(LPCSTR, LPCSTR, LPCSTR, DWORD, LPVOID, LPVOID);\n        BOOL ReplaceFileW(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPVOID, LPVOID);\n        BOOL SetComputerNameExA(COMPUTER_NAME_FORMAT, LPCSTR);\n        BOOL SetComputerNameExW(COMPUTER_NAME_FORMAT, LPCWSTR);\n        BOOL SetFilePointerEx(HANDLE, LARGE_INTEGER, PLARGE_INTEGER, DWORD);\n        BOOL SetInformationJobObject(HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD);\n        BOOL SetSecurityDescriptorControl(PSECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SECURITY_DESCRIPTOR_CONTROL);\n        BOOL SetSystemPowerState(BOOL, BOOL);\n        EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE);\n        DWORD SetThreadIdealProcessor(HANDLE, DWORD);\n        BOOL SetVolumeMountPointA(LPCSTR, LPCSTR);\n        BOOL SetVolumeMountPointW(LPCWSTR, LPCWSTR);\n        BOOL TerminateJobObject(HANDLE, UINT);\n        BOOL UnmapViewOfFile(PCVOID);\n        BOOL UnregisterWait(HANDLE);\n        BOOL UnregisterWaitEx(HANDLE, HANDLE);\n        BOOL VerifyVersionInfoA(LPOSVERSIONINFOEXA, DWORD, DWORDLONG);\n        BOOL VerifyVersionInfoW(LPOSVERSIONINFOEXW, DWORD, DWORDLONG);\n    }\n\n    static if (_WIN32_WINNT >= 0x501) {\n        BOOL ActivateActCtx(HANDLE, ULONG_PTR*);\n        void AddRefActCtx(HANDLE);\n        BOOL CheckNameLegalDOS8Dot3A(LPCSTR, LPSTR, DWORD, PBOOL, PBOOL);\n        BOOL CheckNameLegalDOS8Dot3W(LPCWSTR, LPSTR, DWORD, PBOOL, PBOOL);\n        BOOL CheckRemoteDebuggerPresent(HANDLE, PBOOL);\n        BOOL ConvertFiberToThread();\n        HANDLE CreateActCtxA(PCACTCTXA);\n        HANDLE CreateActCtxW(PCACTCTXW);\n        HANDLE CreateMemoryResourceNotification(MEMORY_RESOURCE_NOTIFICATION_TYPE);\n        BOOL DeactivateActCtx(DWORD, ULONG_PTR);\n        BOOL DebugActiveProcessStop(DWORD);\n        BOOL DebugBreakProcess(HANDLE);\n        BOOL DebugSetProcessKillOnExit(BOOL);\n        BOOL FindActCtxSectionGuid(DWORD, const(GUID)*, ULONG, const(GUID)*,\n          PACTCTX_SECTION_KEYED_DATA);\n        BOOL FindActCtxSectionStringA(DWORD, const(GUID)*, ULONG, LPCSTR,\n          PACTCTX_SECTION_KEYED_DATA);\n        BOOL FindActCtxSectionStringW(DWORD, const(GUID)*, ULONG, LPCWSTR,\n          PACTCTX_SECTION_KEYED_DATA);\n        BOOL GetCurrentActCtx(HANDLE*);\n        VOID GetNativeSystemInfo(LPSYSTEM_INFO);\n        BOOL GetProcessHandleCount(HANDLE, PDWORD);\n        BOOL GetSystemRegistryQuota(PDWORD, PDWORD);\n        BOOL GetSystemTimes(LPFILETIME, LPFILETIME, LPFILETIME);\n        UINT GetSystemWow64DirectoryA(LPSTR, UINT);\n        UINT GetSystemWow64DirectoryW(LPWSTR, UINT);\n        BOOL GetThreadIOPendingFlag(HANDLE, PBOOL);\n        BOOL GetVolumePathNamesForVolumeNameA(LPCSTR, LPSTR, DWORD, PDWORD);\n        BOOL GetVolumePathNamesForVolumeNameW(LPCWSTR, LPWSTR, DWORD, PDWORD);\n        UINT GetWriteWatch(DWORD, PVOID, SIZE_T, PVOID*, PULONG_PTR, PULONG);\n        BOOL HeapQueryInformation(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T);\n        BOOL HeapSetInformation(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T);\n        BOOL IsProcessInJob(HANDLE, HANDLE, PBOOL);\n        BOOL IsWow64Process(HANDLE, PBOOL);\n        BOOL QueryActCtxW(DWORD, HANDLE, PVOID, ULONG, PVOID, SIZE_T, SIZE_T*);\n        BOOL QueryMemoryResourceNotification(HANDLE, PBOOL);\n        void ReleaseActCtx(HANDLE);\n        UINT ResetWriteWatch(LPVOID, SIZE_T);\n        BOOL SetFileShortNameA(HANDLE, LPCSTR);\n        BOOL SetFileShortNameW(HANDLE, LPCWSTR);\n        BOOL SetFileValidData(HANDLE, LONGLONG);\n        BOOL ZombifyActCtx(HANDLE);\n    }\n\n    static if (_WIN32_WINNT >= 0x502) {\n        DWORD GetFirmwareEnvironmentVariableA(LPCSTR, LPCSTR, PVOID, DWORD);\n        DWORD GetFirmwareEnvironmentVariableW(LPCWSTR, LPCWSTR, PVOID, DWORD);\n        DWORD GetDllDirectoryA(DWORD, LPSTR);\n        DWORD GetDllDirectoryW(DWORD, LPWSTR);\n        DWORD GetThreadId(HANDLE);\n        DWORD GetProcessId(HANDLE);\n        HANDLE ReOpenFile(HANDLE, DWORD, DWORD, DWORD);\n        BOOL SetDllDirectoryA(LPCSTR);\n        BOOL SetDllDirectoryW(LPCWSTR);\n        BOOL SetFirmwareEnvironmentVariableA(LPCSTR, LPCSTR, PVOID, DWORD);\n        BOOL SetFirmwareEnvironmentVariableW(LPCWSTR, LPCWSTR, PVOID, DWORD);\n    }\n\n    // ???\n    static if (_WIN32_WINNT >= 0x510) {\n        VOID RestoreLastError(DWORD);\n    }\n}\n\n// For compatibility with old core.sys.windows.windows:\nversion (LittleEndian) nothrow @nogc\n{\n    BOOL QueryPerformanceCounter(long* lpPerformanceCount) { return QueryPerformanceCounter(cast(PLARGE_INTEGER)lpPerformanceCount); }\n    BOOL QueryPerformanceFrequency(long* lpFrequency) { return QueryPerformanceFrequency(cast(PLARGE_INTEGER)lpFrequency); }\n}\n\nmixin DECLARE_AW!(\"STARTUPINFO\");\nversion (Unicode) {\n    //alias STARTUPINFOW STARTUPINFO;\n    alias WIN32_FIND_DATAW WIN32_FIND_DATA;\n    alias ENUMRESLANGPROCW ENUMRESLANGPROC;\n    alias ENUMRESNAMEPROCW ENUMRESNAMEPROC;\n    alias ENUMRESTYPEPROCW ENUMRESTYPEPROC;\n    alias AddAtomW AddAtom;\n    alias BeginUpdateResourceW BeginUpdateResource;\n    alias BuildCommDCBW BuildCommDCB;\n    alias BuildCommDCBAndTimeoutsW BuildCommDCBAndTimeouts;\n    alias CallNamedPipeW CallNamedPipe;\n    alias CommConfigDialogW CommConfigDialog;\n    alias CopyFileW CopyFile;\n    alias CopyFileExW CopyFileEx;\n    alias CreateDirectoryW CreateDirectory;\n    alias CreateDirectoryExW CreateDirectoryEx;\n    alias CreateEventW CreateEvent;\n    alias CreateFileW CreateFile;\n    alias CreateMailslotW CreateMailslot;\n    alias CreateMutexW CreateMutex;\n    alias CreateProcessW CreateProcess;\n    alias CreateSemaphoreW CreateSemaphore;\n    alias DeleteFileW DeleteFile;\n    alias EndUpdateResourceW EndUpdateResource;\n    alias EnumResourceLanguagesW EnumResourceLanguages;\n    alias EnumResourceNamesW EnumResourceNames;\n    alias EnumResourceTypesW EnumResourceTypes;\n    alias ExpandEnvironmentStringsW ExpandEnvironmentStrings;\n    alias FatalAppExitW FatalAppExit;\n    alias FindAtomW FindAtom;\n    alias FindFirstChangeNotificationW FindFirstChangeNotification;\n    alias FindFirstFileW FindFirstFile;\n    alias FindNextFileW FindNextFile;\n    alias FindResourceW FindResource;\n    alias FindResourceExW FindResourceEx;\n    alias FormatMessageW FormatMessage;\n    alias FreeEnvironmentStringsW FreeEnvironmentStrings;\n    alias GetAtomNameW GetAtomName;\n    alias GetCommandLineW GetCommandLine;\n    alias GetComputerNameW GetComputerName;\n    alias GetCurrentDirectoryW GetCurrentDirectory;\n    alias GetDefaultCommConfigW GetDefaultCommConfig;\n    alias GetDiskFreeSpaceW GetDiskFreeSpace;\n    alias GetDiskFreeSpaceExW GetDiskFreeSpaceEx;\n    alias GetDriveTypeW GetDriveType;\n    alias GetEnvironmentStringsW GetEnvironmentStrings;\n    alias GetEnvironmentVariableW GetEnvironmentVariable;\n    alias GetFileAttributesW GetFileAttributes;\n    alias GetFullPathNameW GetFullPathName;\n    alias GetLogicalDriveStringsW GetLogicalDriveStrings;\n    alias GetModuleFileNameW GetModuleFileName;\n    alias GetModuleHandleW GetModuleHandle;\n    alias GetNamedPipeHandleStateW GetNamedPipeHandleState;\n    alias GetPrivateProfileIntW GetPrivateProfileInt;\n    alias GetPrivateProfileSectionW GetPrivateProfileSection;\n    alias GetPrivateProfileSectionNamesW GetPrivateProfileSectionNames;\n    alias GetPrivateProfileStringW GetPrivateProfileString;\n    alias GetPrivateProfileStructW GetPrivateProfileStruct;\n    alias GetProfileIntW GetProfileInt;\n    alias GetProfileSectionW GetProfileSection;\n    alias GetProfileStringW GetProfileString;\n    alias GetShortPathNameW GetShortPathName;\n    alias GetStartupInfoW GetStartupInfo;\n    alias GetSystemDirectoryW GetSystemDirectory;\n    alias GetTempFileNameW GetTempFileName;\n    alias GetTempPathW GetTempPath;\n    alias GetUserNameW GetUserName;\n    alias GetVersionExW GetVersionEx;\n    alias GetVolumeInformationW GetVolumeInformation;\n    alias GetWindowsDirectoryW GetWindowsDirectory;\n    alias GlobalAddAtomW GlobalAddAtom;\n    alias GlobalFindAtomW GlobalFindAtom;\n    alias GlobalGetAtomNameW GlobalGetAtomName;\n    alias IsBadStringPtrW IsBadStringPtr;\n    alias LoadLibraryW LoadLibrary;\n    alias LoadLibraryExW LoadLibraryEx;\n    alias lstrcatW lstrcat;\n    alias lstrcmpW lstrcmp;\n    alias lstrcmpiW lstrcmpi;\n    alias lstrcpyW lstrcpy;\n    alias lstrcpynW lstrcpyn;\n    alias lstrlenW lstrlen;\n    alias MoveFileW MoveFile;\n    alias OpenEventW OpenEvent;\n    alias OpenMutexW OpenMutex;\n    alias OpenSemaphoreW OpenSemaphore;\n    alias OutputDebugStringW OutputDebugString;\n    alias RemoveDirectoryW RemoveDirectory;\n    alias SearchPathW SearchPath;\n    alias SetComputerNameW SetComputerName;\n    alias SetCurrentDirectoryW SetCurrentDirectory;\n    alias SetDefaultCommConfigW SetDefaultCommConfig;\n    alias SetEnvironmentVariableW SetEnvironmentVariable;\n    alias SetFileAttributesW SetFileAttributes;\n    alias SetVolumeLabelW SetVolumeLabel;\n    alias WaitNamedPipeW WaitNamedPipe;\n    alias WritePrivateProfileSectionW WritePrivateProfileSection;\n    alias WritePrivateProfileStringW WritePrivateProfileString;\n    alias WritePrivateProfileStructW WritePrivateProfileStruct;\n    alias WriteProfileSectionW WriteProfileSection;\n    alias WriteProfileStringW WriteProfileString;\n    alias CreateWaitableTimerW CreateWaitableTimer;\n    alias GetFileAttributesExW GetFileAttributesEx;\n    alias GetLongPathNameW GetLongPathName;\n    alias QueryDosDeviceW QueryDosDevice;\n\n    alias HW_PROFILE_INFOW HW_PROFILE_INFO;\n    alias AccessCheckAndAuditAlarmW AccessCheckAndAuditAlarm;\n    alias BackupEventLogW BackupEventLog;\n    alias ClearEventLogW ClearEventLog;\n    alias CreateNamedPipeW CreateNamedPipe;\n    alias CreateProcessAsUserW CreateProcessAsUser;\n    alias DefineDosDeviceW DefineDosDevice;\n    alias FindFirstFileExW FindFirstFileEx;\n    alias GetBinaryTypeW GetBinaryType;\n    alias GetCompressedFileSizeW GetCompressedFileSize;\n    alias GetFileSecurityW GetFileSecurity;\n    alias LogonUserW LogonUser;\n    alias LookupAccountNameW LookupAccountName;\n    alias LookupAccountSidW LookupAccountSid;\n    alias LookupPrivilegeDisplayNameW LookupPrivilegeDisplayName;\n    alias LookupPrivilegeNameW LookupPrivilegeName;\n    alias LookupPrivilegeValueW LookupPrivilegeValue;\n    alias MoveFileExW MoveFileEx;\n    alias ObjectCloseAuditAlarmW ObjectCloseAuditAlarm;\n    alias ObjectDeleteAuditAlarmW ObjectDeleteAuditAlarm;\n    alias ObjectOpenAuditAlarmW ObjectOpenAuditAlarm;\n    alias ObjectPrivilegeAuditAlarmW ObjectPrivilegeAuditAlarm;\n    alias OpenBackupEventLogW OpenBackupEventLog;\n    alias OpenEventLogW OpenEventLog;\n    alias PrivilegedServiceAuditAlarmW PrivilegedServiceAuditAlarm;\n    alias ReadEventLogW ReadEventLog;\n    alias RegisterEventSourceW RegisterEventSource;\n    alias ReportEventW ReportEvent;\n    alias SetFileSecurityW SetFileSecurity;\n    alias UpdateResourceW UpdateResource;\n\n    static if (_WIN32_WINNT >= 0x500) {\n        alias CreateFileMappingW CreateFileMapping;\n        alias CreateHardLinkW CreateHardLink;\n        alias CreateJobObjectW CreateJobObject;\n        alias DeleteVolumeMountPointW DeleteVolumeMountPoint;\n        alias DnsHostnameToComputerNameW DnsHostnameToComputerName;\n        alias EncryptFileW EncryptFile;\n        alias FileEncryptionStatusW FileEncryptionStatus;\n        alias FindFirstVolumeW FindFirstVolume;\n        alias FindFirstVolumeMountPointW FindFirstVolumeMountPoint;\n        alias FindNextVolumeW FindNextVolume;\n        alias FindNextVolumeMountPointW FindNextVolumeMountPoint;\n        alias GetModuleHandleExW GetModuleHandleEx;\n        alias GetSystemWindowsDirectoryW GetSystemWindowsDirectory;\n        alias GetVolumeNameForVolumeMountPointW GetVolumeNameForVolumeMountPoint;\n        alias GetVolumePathNameW GetVolumePathName;\n        alias OpenFileMappingW OpenFileMapping;\n        alias ReplaceFileW ReplaceFile;\n        alias SetVolumeMountPointW SetVolumeMountPoint;\n        alias VerifyVersionInfoW VerifyVersionInfo;\n    }\n\n    static if (_WIN32_WINNT >= 0x501) {\n        alias ACTCTXW ACTCTX;\n        alias CheckNameLegalDOS8Dot3W CheckNameLegalDOS8Dot3;\n        alias CreateActCtxW CreateActCtx;\n        alias FindActCtxSectionStringW FindActCtxSectionString;\n        alias GetSystemWow64DirectoryW GetSystemWow64Directory;\n        alias GetVolumePathNamesForVolumeNameW GetVolumePathNamesForVolumeName;\n        alias SetFileShortNameW SetFileShortName;\n    }\n\n    static if (_WIN32_WINNT >= 0x502) {\n        alias SetFirmwareEnvironmentVariableW SetFirmwareEnvironmentVariable;\n        alias SetDllDirectoryW SetDllDirectory;\n        alias GetDllDirectoryW GetDllDirectory;\n    }\n\n} else {\n    //alias STARTUPINFOA STARTUPINFO;\n    alias WIN32_FIND_DATAA WIN32_FIND_DATA;\n    alias ENUMRESLANGPROCW ENUMRESLANGPROC;\n    alias ENUMRESNAMEPROCW ENUMRESNAMEPROC;\n    alias ENUMRESTYPEPROCW ENUMRESTYPEPROC;\n    alias AddAtomA AddAtom;\n    alias BeginUpdateResourceA BeginUpdateResource;\n    alias BuildCommDCBA BuildCommDCB;\n    alias BuildCommDCBAndTimeoutsA BuildCommDCBAndTimeouts;\n    alias CallNamedPipeA CallNamedPipe;\n    alias CommConfigDialogA CommConfigDialog;\n    alias CopyFileA CopyFile;\n    alias CopyFileExA CopyFileEx;\n    alias CreateDirectoryA CreateDirectory;\n    alias CreateDirectoryExA CreateDirectoryEx;\n    alias CreateEventA CreateEvent;\n    alias CreateFileA CreateFile;\n    alias CreateMailslotA CreateMailslot;\n    alias CreateMutexA CreateMutex;\n    alias CreateProcessA CreateProcess;\n    alias CreateSemaphoreA CreateSemaphore;\n    alias DeleteFileA DeleteFile;\n    alias EndUpdateResourceA EndUpdateResource;\n    alias EnumResourceLanguagesA EnumResourceLanguages;\n    alias EnumResourceNamesA EnumResourceNames;\n    alias EnumResourceTypesA EnumResourceTypes;\n    alias ExpandEnvironmentStringsA ExpandEnvironmentStrings;\n    alias FatalAppExitA FatalAppExit;\n    alias FindAtomA FindAtom;\n    alias FindFirstChangeNotificationA FindFirstChangeNotification;\n    alias FindFirstFileA FindFirstFile;\n    alias FindNextFileA FindNextFile;\n    alias FindResourceA FindResource;\n    alias FindResourceExA FindResourceEx;\n    alias FormatMessageA FormatMessage;\n    alias FreeEnvironmentStringsA FreeEnvironmentStrings;\n    alias GetAtomNameA GetAtomName;\n    alias GetCommandLineA GetCommandLine;\n    alias GetComputerNameA GetComputerName;\n    alias GetCurrentDirectoryA GetCurrentDirectory;\n    alias GetDefaultCommConfigA GetDefaultCommConfig;\n    alias GetDiskFreeSpaceA GetDiskFreeSpace;\n    alias GetDiskFreeSpaceExA GetDiskFreeSpaceEx;\n    alias GetDriveTypeA GetDriveType;\n    alias GetEnvironmentStringsA GetEnvironmentStrings;\n    alias GetEnvironmentVariableA GetEnvironmentVariable;\n    alias GetFileAttributesA GetFileAttributes;\n    alias GetFullPathNameA GetFullPathName;\n    alias GetLogicalDriveStringsA GetLogicalDriveStrings;\n    alias GetNamedPipeHandleStateA GetNamedPipeHandleState;\n    alias GetModuleHandleA GetModuleHandle;\n    alias GetModuleFileNameA GetModuleFileName;\n    alias GetPrivateProfileIntA GetPrivateProfileInt;\n    alias GetPrivateProfileSectionA GetPrivateProfileSection;\n    alias GetPrivateProfileSectionNamesA GetPrivateProfileSectionNames;\n    alias GetPrivateProfileStringA GetPrivateProfileString;\n    alias GetPrivateProfileStructA GetPrivateProfileStruct;\n    alias GetProfileIntA GetProfileInt;\n    alias GetProfileSectionA GetProfileSection;\n    alias GetProfileStringA GetProfileString;\n    alias GetShortPathNameA GetShortPathName;\n    alias GetStartupInfoA GetStartupInfo;\n    alias GetSystemDirectoryA GetSystemDirectory;\n    alias GetTempFileNameA GetTempFileName;\n    alias GetTempPathA GetTempPath;\n    alias GetUserNameA GetUserName;\n    alias GetVersionExA GetVersionEx;\n    alias GetVolumeInformationA GetVolumeInformation;\n    alias GetWindowsDirectoryA GetWindowsDirectory;\n    alias GlobalAddAtomA GlobalAddAtom;\n    alias GlobalFindAtomA GlobalFindAtom;\n    alias GlobalGetAtomNameA GlobalGetAtomName;\n    alias IsBadStringPtrA IsBadStringPtr;\n    alias LoadLibraryA LoadLibrary;\n    alias LoadLibraryExA LoadLibraryEx;\n    alias lstrcatA lstrcat;\n    alias lstrcmpA lstrcmp;\n    alias lstrcmpiA lstrcmpi;\n    alias lstrcpyA lstrcpy;\n    alias lstrcpynA lstrcpyn;\n    alias lstrlenA lstrlen;\n    alias MoveFileA MoveFile;\n    alias OpenEventA OpenEvent;\n    alias OpenMutexA OpenMutex;\n    alias OpenSemaphoreA OpenSemaphore;\n    alias OutputDebugStringA OutputDebugString;\n    alias RemoveDirectoryA RemoveDirectory;\n    alias SearchPathA SearchPath;\n    alias SetComputerNameA SetComputerName;\n    alias SetCurrentDirectoryA SetCurrentDirectory;\n    alias SetDefaultCommConfigA SetDefaultCommConfig;\n    alias SetEnvironmentVariableA SetEnvironmentVariable;\n    alias SetFileAttributesA SetFileAttributes;\n    alias SetVolumeLabelA SetVolumeLabel;\n    alias WaitNamedPipeA WaitNamedPipe;\n    alias WritePrivateProfileSectionA WritePrivateProfileSection;\n    alias WritePrivateProfileStringA WritePrivateProfileString;\n    alias WritePrivateProfileStructA WritePrivateProfileStruct;\n    alias WriteProfileSectionA WriteProfileSection;\n    alias WriteProfileStringA WriteProfileString;\n    alias CreateWaitableTimerA CreateWaitableTimer;\n    alias GetFileAttributesExA GetFileAttributesEx;\n    alias GetLongPathNameA GetLongPathName;\n    alias QueryDosDeviceA QueryDosDevice;\n\n    alias HW_PROFILE_INFOA HW_PROFILE_INFO;\n    alias AccessCheckAndAuditAlarmA AccessCheckAndAuditAlarm;\n    alias BackupEventLogA BackupEventLog;\n    alias ClearEventLogA ClearEventLog;\n    alias CreateNamedPipeA CreateNamedPipe;\n    alias CreateProcessAsUserA CreateProcessAsUser;\n    alias DefineDosDeviceA DefineDosDevice;\n    alias FindFirstFileExA FindFirstFileEx;\n    alias GetBinaryTypeA GetBinaryType;\n    alias GetCompressedFileSizeA GetCompressedFileSize;\n    alias GetFileSecurityA GetFileSecurity;\n    alias LogonUserA LogonUser;\n    alias LookupAccountNameA LookupAccountName;\n    alias LookupAccountSidA LookupAccountSid;\n    alias LookupPrivilegeDisplayNameA LookupPrivilegeDisplayName;\n    alias LookupPrivilegeNameA LookupPrivilegeName;\n    alias LookupPrivilegeValueA LookupPrivilegeValue;\n    alias MoveFileExA MoveFileEx;\n    alias ObjectCloseAuditAlarmA ObjectCloseAuditAlarm;\n    alias ObjectDeleteAuditAlarmA ObjectDeleteAuditAlarm;\n    alias ObjectOpenAuditAlarmA ObjectOpenAuditAlarm;\n    alias ObjectPrivilegeAuditAlarmA ObjectPrivilegeAuditAlarm;\n    alias OpenBackupEventLogA OpenBackupEventLog;\n    alias OpenEventLogA OpenEventLog;\n    alias PrivilegedServiceAuditAlarmA PrivilegedServiceAuditAlarm;\n    alias ReadEventLogA ReadEventLog;\n    alias RegisterEventSourceA RegisterEventSource;\n    alias ReportEventA ReportEvent;\n    alias SetFileSecurityA SetFileSecurity;\n    alias UpdateResourceA UpdateResource;\n\n    static if (_WIN32_WINNT >= 0x500) {\n        alias CreateFileMappingA CreateFileMapping;\n        alias CreateHardLinkA CreateHardLink;\n        alias CreateJobObjectA CreateJobObject;\n        alias DeleteVolumeMountPointA DeleteVolumeMountPoint;\n        alias DnsHostnameToComputerNameA DnsHostnameToComputerName;\n        alias EncryptFileA EncryptFile;\n        alias FileEncryptionStatusA FileEncryptionStatus;\n        alias FindFirstVolumeA FindFirstVolume;\n        alias FindFirstVolumeMountPointA FindFirstVolumeMountPoint;\n        alias FindNextVolumeA FindNextVolume;\n        alias FindNextVolumeMountPointA FindNextVolumeMountPoint;\n        alias GetModuleHandleExA GetModuleHandleEx;\n        alias GetSystemWindowsDirectoryA GetSystemWindowsDirectory;\n        alias GetVolumeNameForVolumeMountPointA GetVolumeNameForVolumeMountPoint;\n        alias GetVolumePathNameA GetVolumePathName;\n        alias OpenFileMappingA OpenFileMapping;\n        alias ReplaceFileA ReplaceFile;\n        alias SetVolumeMountPointA SetVolumeMountPoint;\n        alias VerifyVersionInfoA VerifyVersionInfo;\n    }\n\n    static if (_WIN32_WINNT >= 0x501) {\n        alias ACTCTXA ACTCTX;\n        alias CheckNameLegalDOS8Dot3A CheckNameLegalDOS8Dot3;\n        alias CreateActCtxA CreateActCtx;\n        alias FindActCtxSectionStringA FindActCtxSectionString;\n        alias GetSystemWow64DirectoryA GetSystemWow64Directory;\n        alias GetVolumePathNamesForVolumeNameA GetVolumePathNamesForVolumeName;\n        alias SetFileShortNameA SetFileShortName;\n    }\n\n    static if (_WIN32_WINNT >= 0x502) {\n        alias GetDllDirectoryA GetDllDirectory;\n        alias SetDllDirectoryA SetDllDirectory;\n        alias SetFirmwareEnvironmentVariableA SetFirmwareEnvironmentVariable;\n    }\n}\n\nalias STARTUPINFO* LPSTARTUPINFO;\nalias WIN32_FIND_DATA* LPWIN32_FIND_DATA;\n\nalias HW_PROFILE_INFO* LPHW_PROFILE_INFO;\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    alias ACTCTX* PACTCTX, PCACTCTX;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winber.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winber.d)\n */\nmodule core.sys.windows.winber;\nversion (Windows):\n\n/* Comment from MinGW\n  winber.h - Header file for the Windows LDAP Basic Encoding Rules API\n\n  Written by Filip Navara <xnavara@volny.cz>\n\n  References:\n    The C LDAP Application Program Interface\n    http://www.watersprings.org/pub/id/draft-ietf-ldapext-ldap-c-api-05.txt\n\n    Lightweight Directory Access Protocol Reference\n    http://msdn.microsoft.com/library/en-us/netdir/ldap/ldap_reference.asp\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n */\n\n import core.sys.windows.basetsd;\n\n/* Opaque structure\n *  http://msdn.microsoft.com/library/en-us/ldap/ldap/berelement.asp\n */\nstruct BerElement;\n\nalias int ber_int_t, ber_slen_t;\nalias uint ber_uint_t, ber_len_t, ber_tag_t;\n\nalign(4):\nstruct BerValue {\n    ber_len_t bv_len;\n    char*     bv_val;\n}\nalias BerValue LDAP_BERVAL, BERVAL;\nalias BerValue* PLDAP_BERVAL, PBERVAL;\n\nenum ber_tag_t\n    LBER_ERROR   = -1,\n    LBER_DEFAULT = -1,\n    LBER_USE_DER =  1;\n\n/*  FIXME: In MinGW, these are WINBERAPI == DECLSPEC_IMPORT.  Linkage\n *  attribute?\n */\nextern (C) {\n    BerElement* ber_init(const(BerValue)*);\n    int ber_printf(BerElement*, const(char)*, ...);\n    int ber_flatten(BerElement*, BerValue**);\n    ber_tag_t ber_scanf(BerElement*, const(char)*, ...);\n    ber_tag_t ber_peek_tag(BerElement*, ber_len_t*);\n    ber_tag_t ber_skip_tag(BerElement*, ber_len_t*);\n    ber_tag_t ber_first_element(BerElement*, ber_len_t*, char**);\n    ber_tag_t ber_next_element(BerElement*, ber_len_t*, char*);\n    void ber_bvfree(BerValue*);\n    void ber_bvecfree(BerValue**);\n    void ber_free(BerElement*, int);\n    BerValue* ber_bvdup(BerValue*);\n    BerElement* ber_alloc_t(int);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/wincon.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_wincon.d)\n */\nmodule core.sys.windows.wincon;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"kernel32\");\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef;\n\n// FIXME: clean up Windows version support\n\nenum {\n    FOREGROUND_BLUE             = 0x0001,\n    FOREGROUND_GREEN            = 0x0002,\n    FOREGROUND_RED              = 0x0004,\n    FOREGROUND_INTENSITY        = 0x0008,\n    BACKGROUND_BLUE             = 0x0010,\n    BACKGROUND_GREEN            = 0x0020,\n    BACKGROUND_RED              = 0x0040,\n    BACKGROUND_INTENSITY        = 0x0080,\n\n    COMMON_LVB_LEADING_BYTE     = 0x0100,\n    COMMON_LVB_TRAILING_BYTE    = 0x0200,\n    COMMON_LVB_GRID_HORIZONTAL  = 0x0400,\n    COMMON_LVB_GRID_LVERTICAL   = 0x0800,\n    COMMON_LVB_GRID_RVERTICAL   = 0x1000,\n    COMMON_LVB_REVERSE_VIDEO    = 0x4000,\n    COMMON_LVB_UNDERSCORE       = 0x8000,\n\n    COMMON_LVB_SBCSDBCS         = 0x0300,\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        CONSOLE_FULLSCREEN_MODE = 1,\n        CONSOLE_WINDOWED_MODE   = 0\n    }\n}\n\nenum {\n    CTRL_C_EVENT        = 0,\n    CTRL_BREAK_EVENT    = 1,\n    CTRL_CLOSE_EVENT    = 2,\n    CTRL_LOGOFF_EVENT   = 5,\n    CTRL_SHUTDOWN_EVENT = 6\n}\n\nenum {\n    ENABLE_PROCESSED_INPUT        = 1,\n    ENABLE_LINE_INPUT             = 2,\n    ENABLE_ECHO_INPUT             = 4,\n    ENABLE_WINDOW_INPUT           = 8,\n    ENABLE_MOUSE_INPUT            = 16,\n    ENABLE_INSERT_MODE            = 32,\n    ENABLE_QUICK_EDIT_MODE        = 64,\n    ENABLE_EXTENDED_FLAGS         = 128,\n    ENABLE_AUTO_POSITION          = 256,\n    ENABLE_VIRTUAL_TERMINAL_INPUT = 512\n}\n\nenum {\n    ENABLE_PROCESSED_OUTPUT            = 1,\n    ENABLE_WRAP_AT_EOL_OUTPUT          = 2,\n    ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4,\n    DISABLE_NEWLINE_AUTO_RETURN        = 8,\n    ENABLE_LVB_GRID_WORLDWIDE          = 16\n}\n\nenum {\n    KEY_EVENT                 = 1,\n    MOUSE_EVENT               = 2,\n    WINDOW_BUFFER_SIZE_EVENT  = 4,\n    MENU_EVENT                = 8,\n    FOCUS_EVENT               = 16\n}\nenum {\n    RIGHT_ALT_PRESSED  = 1,\n    LEFT_ALT_PRESSED   = 2,\n    RIGHT_CTRL_PRESSED = 4,\n    LEFT_CTRL_PRESSED  = 8,\n    SHIFT_PRESSED      = 16,\n    NUMLOCK_ON         = 32,\n    SCROLLLOCK_ON      = 64,\n    CAPSLOCK_ON        = 128,\n    ENHANCED_KEY       = 256\n}\nenum {\n    FROM_LEFT_1ST_BUTTON_PRESSED  = 1,\n    RIGHTMOST_BUTTON_PRESSED      = 2,\n    FROM_LEFT_2ND_BUTTON_PRESSED  = 4,\n    FROM_LEFT_3RD_BUTTON_PRESSED  = 8,\n    FROM_LEFT_4TH_BUTTON_PRESSED  = 16\n}\n\nenum {\n    MOUSE_MOVED   = 1,\n    DOUBLE_CLICK  = 2,\n    MOUSE_WHEELED = 4\n}\n\nstruct CHAR_INFO {\n    union _Char {\n        WCHAR UnicodeChar;\n        CHAR AsciiChar;\n    }\n    union {\n        _Char Char;\n        WCHAR UnicodeChar;\n        CHAR AsciiChar;\n    }\n    WORD Attributes;\n}\nalias CHAR_INFO* PCHAR_INFO;\n\nstruct SMALL_RECT {\n    SHORT Left;\n    SHORT Top;\n    SHORT Right;\n    SHORT Bottom;\n}\nalias SMALL_RECT* PSMALL_RECT;\n\nstruct CONSOLE_CURSOR_INFO {\n    DWORD dwSize;\n    BOOL  bVisible;\n}\nalias CONSOLE_CURSOR_INFO* PCONSOLE_CURSOR_INFO;\n\nstruct COORD {\n    SHORT X;\n    SHORT Y;\n}\nalias COORD* PCOORD;\n\nstruct CONSOLE_FONT_INFO {\n    DWORD nFont;\n    COORD dwFontSize;\n}\nalias CONSOLE_FONT_INFO* PCONSOLE_FONT_INFO;\n\nstruct CONSOLE_SCREEN_BUFFER_INFO {\n    COORD      dwSize;\n    COORD      dwCursorPosition;\n    WORD       wAttributes;\n    SMALL_RECT srWindow;\n    COORD      dwMaximumWindowSize;\n}\nalias CONSOLE_SCREEN_BUFFER_INFO* PCONSOLE_SCREEN_BUFFER_INFO;\n\nalias extern(Windows) BOOL function(DWORD) nothrow PHANDLER_ROUTINE;\n\nstruct KEY_EVENT_RECORD {\n    BOOL  bKeyDown;\n    WORD  wRepeatCount;\n    WORD  wVirtualKeyCode;\n    WORD  wVirtualScanCode;\n    union _uChar {\n        WCHAR UnicodeChar;\n        CHAR  AsciiChar;\n    }\n    union {\n        WCHAR UnicodeChar;\n        CHAR  AsciiChar;\n        _uChar uChar;\n    }\n    DWORD dwControlKeyState;\n}\nalias KEY_EVENT_RECORD* PKEY_EVENT_RECORD;\n\nstruct MOUSE_EVENT_RECORD {\n    COORD dwMousePosition;\n    DWORD dwButtonState;\n    DWORD dwControlKeyState;\n    DWORD dwEventFlags;\n}\nalias MOUSE_EVENT_RECORD* PMOUSE_EVENT_RECORD;\n\nstruct WINDOW_BUFFER_SIZE_RECORD {\n    COORD dwSize;\n}\nalias WINDOW_BUFFER_SIZE_RECORD* PWINDOW_BUFFER_SIZE_RECORD;\n\nstruct MENU_EVENT_RECORD {\n    UINT dwCommandId;\n}\nalias MENU_EVENT_RECORD* PMENU_EVENT_RECORD;\n\nstruct FOCUS_EVENT_RECORD {\n    BOOL bSetFocus;\n}\nalias FOCUS_EVENT_RECORD* PFOCUS_EVENT_RECORD;\n\nstruct INPUT_RECORD {\n    WORD EventType;\n    union _Event {\n        KEY_EVENT_RECORD KeyEvent;\n        MOUSE_EVENT_RECORD MouseEvent;\n        WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;\n        MENU_EVENT_RECORD MenuEvent;\n        FOCUS_EVENT_RECORD FocusEvent;\n    }\n    union {\n        KEY_EVENT_RECORD KeyEvent;\n        MOUSE_EVENT_RECORD MouseEvent;\n        WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;\n        MENU_EVENT_RECORD MenuEvent;\n        FOCUS_EVENT_RECORD FocusEvent;\n        _Event Event;\n    }\n}\nalias INPUT_RECORD* PINPUT_RECORD;\n\nextern (Windows) nothrow @nogc:\n\nBOOL AllocConsole();\nHANDLE CreateConsoleScreenBuffer(DWORD, DWORD, const(SECURITY_ATTRIBUTES)*, DWORD, LPVOID);\nBOOL FillConsoleOutputAttribute(HANDLE, WORD, DWORD, COORD, PDWORD);\nBOOL FillConsoleOutputCharacterA(HANDLE, CHAR, DWORD, COORD, PDWORD);\nBOOL FillConsoleOutputCharacterW(HANDLE, WCHAR, DWORD, COORD, PDWORD);\nBOOL FlushConsoleInputBuffer(HANDLE);\nBOOL FreeConsole();\nBOOL GenerateConsoleCtrlEvent(DWORD, DWORD);\nUINT GetConsoleCP();\nBOOL GetConsoleCursorInfo(HANDLE, PCONSOLE_CURSOR_INFO);\nBOOL GetConsoleMode(HANDLE,PDWORD);\nUINT GetConsoleOutputCP();\nBOOL GetConsoleScreenBufferInfo(HANDLE, PCONSOLE_SCREEN_BUFFER_INFO);\nDWORD GetConsoleTitleA(LPSTR, DWORD);\nDWORD GetConsoleTitleW(LPWSTR, DWORD);\nCOORD GetLargestConsoleWindowSize(HANDLE);\nBOOL GetNumberOfConsoleInputEvents(HANDLE, PDWORD);\nBOOL GetNumberOfConsoleMouseButtons(PDWORD);\nBOOL PeekConsoleInputA(HANDLE, PINPUT_RECORD, DWORD, PDWORD);\nBOOL PeekConsoleInputW(HANDLE, PINPUT_RECORD, DWORD, PDWORD);\nBOOL ReadConsoleA(HANDLE, PVOID, DWORD, PDWORD, PVOID);\nBOOL ReadConsoleW(HANDLE, PVOID, DWORD, PDWORD, PVOID);\nBOOL ReadConsoleInputA(HANDLE, PINPUT_RECORD, DWORD, PDWORD);\nBOOL ReadConsoleInputW(HANDLE, PINPUT_RECORD, DWORD, PDWORD);\nBOOL ReadConsoleOutputAttribute(HANDLE, LPWORD, DWORD, COORD, LPDWORD);\nBOOL ReadConsoleOutputCharacterA(HANDLE, LPSTR, DWORD, COORD, PDWORD);\nBOOL ReadConsoleOutputCharacterW(HANDLE, LPWSTR, DWORD, COORD, PDWORD);\nBOOL ReadConsoleOutputA(HANDLE, PCHAR_INFO, COORD, COORD, PSMALL_RECT);\nBOOL ReadConsoleOutputW(HANDLE, PCHAR_INFO, COORD, COORD, PSMALL_RECT);\nBOOL ScrollConsoleScreenBufferA(HANDLE, const(SMALL_RECT)*, const(SMALL_RECT)*, COORD, const(CHAR_INFO)*);\nBOOL ScrollConsoleScreenBufferW(HANDLE, const(SMALL_RECT)*, const(SMALL_RECT)*, COORD, const(CHAR_INFO)*);\nBOOL SetConsoleActiveScreenBuffer(HANDLE);\nBOOL SetConsoleCP(UINT);\nBOOL SetConsoleCtrlHandler(PHANDLER_ROUTINE, BOOL);\nBOOL SetConsoleCursorInfo(HANDLE, const(CONSOLE_CURSOR_INFO)*);\nBOOL SetConsoleCursorPosition(HANDLE, COORD);\n\n\nstatic if (_WIN32_WINNT >= 0x500) {\nBOOL GetConsoleDisplayMode(LPDWORD);\nHWND GetConsoleWindow();\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\nBOOL AttachConsole(DWORD);\nBOOL SetConsoleDisplayMode(HANDLE, DWORD, PCOORD);\nenum DWORD ATTACH_PARENT_PROCESS = cast(DWORD)-1;\n}\n\nBOOL SetConsoleMode(HANDLE, DWORD);\nBOOL SetConsoleOutputCP(UINT);\nBOOL SetConsoleScreenBufferSize(HANDLE, COORD);\nBOOL SetConsoleTextAttribute(HANDLE, WORD);\nBOOL SetConsoleTitleA(LPCSTR);\nBOOL SetConsoleTitleW(LPCWSTR);\nBOOL SetConsoleWindowInfo(HANDLE, BOOL, const(SMALL_RECT)*);\nBOOL WriteConsoleA(HANDLE, PCVOID, DWORD, PDWORD, PVOID);\nBOOL WriteConsoleW(HANDLE, PCVOID, DWORD, PDWORD, PVOID);\nBOOL WriteConsoleInputA(HANDLE, const(INPUT_RECORD)*, DWORD, PDWORD);\nBOOL WriteConsoleInputW(HANDLE, const(INPUT_RECORD)*, DWORD, PDWORD);\nBOOL WriteConsoleOutputA(HANDLE, const(CHAR_INFO)*, COORD, COORD, PSMALL_RECT);\nBOOL WriteConsoleOutputW(HANDLE, const(CHAR_INFO)*, COORD, COORD, PSMALL_RECT);\nBOOL WriteConsoleOutputAttribute(HANDLE, const(WORD)*, DWORD, COORD, PDWORD);\nBOOL WriteConsoleOutputCharacterA(HANDLE, LPCSTR, DWORD, COORD, PDWORD);\nBOOL WriteConsoleOutputCharacterW(HANDLE, LPCWSTR, DWORD, COORD, PDWORD);\n\nversion (Unicode) {\n    alias FillConsoleOutputCharacterW FillConsoleOutputCharacter;\n    alias GetConsoleTitleW GetConsoleTitle;\n    alias PeekConsoleInputW PeekConsoleInput;\n    alias ReadConsoleW ReadConsole;\n    alias ReadConsoleInputW ReadConsoleInput;\n    alias ReadConsoleOutputW ReadConsoleOutput;\n    alias ReadConsoleOutputCharacterW ReadConsoleOutputCharacter;\n    alias ScrollConsoleScreenBufferW ScrollConsoleScreenBuffer;\n    alias SetConsoleTitleW SetConsoleTitle;\n    alias WriteConsoleW WriteConsole;\n    alias WriteConsoleInputW WriteConsoleInput;\n    alias WriteConsoleOutputW WriteConsoleOutput;\n    alias WriteConsoleOutputCharacterW WriteConsoleOutputCharacter;\n} else {\n    alias FillConsoleOutputCharacterA FillConsoleOutputCharacter;\n    alias GetConsoleTitleA GetConsoleTitle;\n    alias PeekConsoleInputA PeekConsoleInput;\n    alias ReadConsoleA ReadConsole;\n    alias ReadConsoleInputA ReadConsoleInput;\n    alias ReadConsoleOutputA ReadConsoleOutput;\n    alias ReadConsoleOutputCharacterA ReadConsoleOutputCharacter;\n    alias ScrollConsoleScreenBufferA ScrollConsoleScreenBuffer;\n    alias SetConsoleTitleA SetConsoleTitle;\n    alias WriteConsoleA WriteConsole;\n    alias WriteConsoleInputA WriteConsoleInput;\n    alias WriteConsoleOutputA WriteConsoleOutput;\n    alias WriteConsoleOutputCharacterA WriteConsoleOutputCharacter;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/wincrypt.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_wincrypt.d)\n */\nmodule core.sys.windows.wincrypt;\nversion (Windows):\npragma(lib, \"advapi32\");\n\nversion (ANSI) {} else version = Unicode;\n\nprivate import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;\n\n/* FIXME:\n *  Types of some constants\n *  Types of macros\n *  Inits of various \"size\" and \"version\" members\n *  Why are some #ifdefs commented out?\n */\n\nconst TCHAR[]\n    MS_DEF_PROV = \"Microsoft Base Cryptographic Provider v1.0\",\n    MS_ENHANCED_PROV = \"Microsoft Enhanced Cryptographic Provider v1.0\",\n    MS_STRONG_PROV = \"Microsoft Strong Cryptographic Provider\",\n    MS_DEF_RSA_SIG_PROV = \"Microsoft RSA Signature Cryptographic Provider\",\n    MS_DEF_RSA_SCHANNEL_PROV = \"Microsoft RSA SChannel Cryptographic Provider\",\n    MS_DEF_DSS_PROV = \"Microsoft Base DSS Cryptographic Provider\",\n    MS_DEF_DSS_DH_PROV\n      = \"Microsoft Base DSS and Diffie-Hellman Cryptographic Provider\",\n    MS_ENH_DSS_DH_PROV\n      = \"Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider\",\n    MS_DEF_DH_SCHANNEL_PROV = \"Microsoft DH SChannel Cryptographic Provider\",\n    MS_SCARD_PROV = \"Microsoft Base Smart Card Crypto Provider\";\n\nstatic if (_WIN32_WINNT > 0x501) {\nconst TCHAR[] MS_ENH_RSA_AES_PROV\n      = \"Microsoft Enhanced RSA and AES Cryptographic Provider\";\n} else static if (_WIN32_WINNT == 0x501) {\nconst TCHAR[] MS_ENH_RSA_AES_PROV\n      = \"Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)\";\n}\n\nALG_ID GET_ALG_CLASS(ALG_ID x) { return x & 0xE000; }\nALG_ID GET_ALG_TYPE (ALG_ID x) { return x & 0x1E00; }\nALG_ID GET_ALG_SID  (ALG_ID x) { return x & 0x01FF; }\n\nenum : ALG_ID {\n    ALG_CLASS_ANY           = 0,\n    ALG_CLASS_SIGNATURE     = 0x2000,\n    ALG_CLASS_MSG_ENCRYPT   = 0x4000,\n    ALG_CLASS_DATA_ENCRYPT  = 0x6000,\n    ALG_CLASS_HASH          = 0x8000,\n    ALG_CLASS_KEY_EXCHANGE  = 0xA000,\n    ALG_CLASS_ALL           = 0xE000\n}\n\nenum : ALG_ID {\n    ALG_TYPE_ANY           = 0,\n    ALG_TYPE_DSS           = 0x0200,\n    ALG_TYPE_RSA           = 0x0400,\n    ALG_TYPE_BLOCK         = 0x0600,\n    ALG_TYPE_STREAM        = 0x0800,\n    ALG_TYPE_DH            = 0x0A00,\n    ALG_TYPE_SECURECHANNEL = 0x0C00\n}\n\nenum : ALG_ID {\n    ALG_SID_ANY          =  0,\n    ALG_SID_RSA_ANY      =  0,\n    ALG_SID_RSA_PKCS,\n    ALG_SID_RSA_MSATWORK,\n    ALG_SID_RSA_ENTRUST,\n    ALG_SID_RSA_PGP,  // =  4\n    ALG_SID_DSS_ANY      =  0,\n    ALG_SID_DSS_PKCS,\n    ALG_SID_DSS_DMS,  // =  2\n    ALG_SID_DES          =  1,\n    ALG_SID_3DES         =  3,\n    ALG_SID_DESX,\n    ALG_SID_IDEA,\n    ALG_SID_CAST,\n    ALG_SID_SAFERSK64,\n    ALG_SID_SAFERSK128,\n    ALG_SID_3DES_112,\n    ALG_SID_SKIPJACK,\n    ALG_SID_TEK,\n    ALG_SID_CYLINK_MEK,\n    ALG_SID_RC5,      // = 13\n    ALG_SID_RC2          =  2,\n    ALG_SID_RC4          =  1,\n    ALG_SID_SEAL         =  2,\n    ALG_SID_MD2          =  1,\n    ALG_SID_MD4,\n    ALG_SID_MD5,\n    ALG_SID_SHA,\n    ALG_SID_MAC,\n    ALG_SID_RIPEMD,\n    ALG_SID_RIPEMD160,\n    ALG_SID_SSL3SHAMD5,\n    ALG_SID_HMAC,\n    ALG_SID_TLS1PRF,  // = 10\n    ALG_SID_AES_128      = 14,\n    ALG_SID_AES_192,\n    ALG_SID_AES_256,\n    ALG_SID_AES,      // = 17\n    ALG_SID_EXAMPLE      = 80\n}\n\nenum : ALG_ID {\n    CALG_MD2        = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD2,\n    CALG_MD4        = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4,\n    CALG_MD5        = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5,\n    CALG_SHA        = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA,\n    CALG_SHA1       = CALG_SHA,\n    CALG_MAC        = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAC,\n    CALG_3DES       = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 3,\n    CALG_CYLINK_MEK = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 12,\n    CALG_SKIPJACK   = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 10,\n    CALG_KEA_KEYX   = ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_STREAM | ALG_TYPE_DSS | 4,\n    CALG_RSA_SIGN   = ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | ALG_SID_RSA_ANY,\n    CALG_DSS_SIGN   = ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_DSS_ANY,\n    CALG_RSA_KEYX   = ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RSA | ALG_SID_RSA_ANY,\n    CALG_DES        = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DES,\n    CALG_RC2        = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_RC2,\n    CALG_RC4        = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_RC4,\n    CALG_SEAL       = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_SEAL,\n    CALG_DH_EPHEM   = ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_STREAM | ALG_TYPE_DSS\n                      | ALG_SID_DSS_DMS,\n    CALG_DESX       = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DESX,\n// is undefined ALG_CLASS_DHASH in MinGW - presuming typo\n    CALG_TLS1PRF    = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_TLS1PRF,\n    CALG_AES_128    = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_128,\n    CALG_AES_192    = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_192,\n    CALG_AES_256    = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_256,\n    CALG_AES        = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES,\n}\n\nenum {\n    CRYPT_VERIFYCONTEXT = 0xF0000000,\n}\n\nenum {\n    CRYPT_NEWKEYSET = 8,\n    CRYPT_DELETEKEYSET = 16,\n    CRYPT_MACHINE_KEYSET = 32,\n    CRYPT_SILENT = 64,\n}\n\nenum {\n    CRYPT_EXPORTABLE = 1,\n    CRYPT_USER_PROTECTED = 2,\n    CRYPT_CREATE_SALT = 4,\n    CRYPT_UPDATE_KEY = 8,\n}\n\nenum {\n    SIMPLEBLOB = 1,\n    PUBLICKEYBLOB = 6,\n    PRIVATEKEYBLOB = 7,\n    PLAINTEXTKEYBLOB = 8,\n    OPAQUEKEYBLOB = 9,\n    PUBLICKEYBLOBEX = 10,\n    SYMMETRICWRAPKEYBLOB = 11,\n}\n\nenum {\n    AT_KEYEXCHANGE = 1,\n    AT_SIGNATURE = 2,\n}\n\nenum {\n    CRYPT_USERDATA = 1,\n}\n\nenum {\n    PKCS5_PADDING = 1,\n}\n\nenum {\n    CRYPT_MODE_CBC = 1,\n    CRYPT_MODE_ECB = 2,\n    CRYPT_MODE_OFB = 3,\n    CRYPT_MODE_CFB = 4,\n    CRYPT_MODE_CTS = 5,\n    CRYPT_MODE_CBCI = 6,\n    CRYPT_MODE_CFBP = 7,\n    CRYPT_MODE_OFBP = 8,\n    CRYPT_MODE_CBCOFM = 9,\n    CRYPT_MODE_CBCOFMI = 10,\n}\n\nenum {\n    CRYPT_ENCRYPT = 1,\n    CRYPT_DECRYPT = 2,\n    CRYPT_EXPORT = 4,\n    CRYPT_READ = 8,\n    CRYPT_WRITE = 16,\n    CRYPT_MAC = 32,\n}\n\nenum {\n    HP_ALGID = 1,\n    HP_HASHVAL = 2,\n    HP_HASHSIZE = 4,\n    HP_HMAC_INFO = 5,\n}\n\nenum {\n    CRYPT_FAILED = FALSE,\n    CRYPT_SUCCEED = TRUE,\n}\n\nbool RCRYPT_SUCCEEDED(BOOL r) { return r==CRYPT_SUCCEED; }\nbool RCRYPT_FAILED(BOOL r) { return r==CRYPT_FAILED; }\n\nenum {\n    PP_ENUMALGS = 1,\n    PP_ENUMCONTAINERS = 2,\n    PP_IMPTYPE = 3,\n    PP_NAME = 4,\n    PP_VERSION = 5,\n    PP_CONTAINER = 6,\n    PP_CHANGE_PASSWORD  = 7,\n    PP_KEYSET_SEC_DESCR = 8,\n    PP_CERTCHAIN    = 9,\n    PP_KEY_TYPE_SUBTYPE = 10,\n    PP_PROVTYPE = 16,\n    PP_KEYSTORAGE   = 17,\n    PP_APPLI_CERT   = 18,\n    PP_SYM_KEYSIZE  = 19,\n    PP_SESSION_KEYSIZE  = 20,\n    PP_UI_PROMPT    = 21,\n    PP_ENUMALGS_EX  = 22,\n    PP_ENUMMANDROOTS = 25,\n    PP_ENUMELECTROOTS = 26,\n    PP_KEYSET_TYPE = 27,\n    PP_ADMIN_PIN = 31,\n    PP_KEYEXCHANGE_PIN = 32,\n    PP_SIGNATURE_PIN = 33,\n    PP_SIG_KEYSIZE_INC = 34,\n    PP_KEYX_KEYSIZE_INC = 35,\n    PP_UNIQUE_CONTAINER = 36,\n    PP_SGC_INFO = 37,\n    PP_USE_HARDWARE_RNG = 38,\n    PP_KEYSPEC = 39,\n    PP_ENUMEX_SIGNING_PROT = 40,\n}\n\nenum {\n    CRYPT_FIRST = 1,\n    CRYPT_NEXT = 2,\n}\n\nenum {\n    CRYPT_IMPL_HARDWARE = 1,\n    CRYPT_IMPL_SOFTWARE = 2,\n    CRYPT_IMPL_MIXED = 3,\n    CRYPT_IMPL_UNKNOWN = 4,\n}\n\nenum {\n    PROV_RSA_FULL = 1,\n    PROV_RSA_SIG = 2,\n    PROV_DSS = 3,\n    PROV_FORTEZZA = 4,\n    PROV_MS_MAIL = 5,\n    PROV_SSL = 6,\n    PROV_STT_MER = 7,\n    PROV_STT_ACQ = 8,\n    PROV_STT_BRND = 9,\n    PROV_STT_ROOT = 10,\n    PROV_STT_ISS = 11,\n    PROV_RSA_SCHANNEL = 12,\n    PROV_DSS_DH = 13,\n    PROV_EC_ECDSA_SIG = 14,\n    PROV_EC_ECNRA_SIG = 15,\n    PROV_EC_ECDSA_FULL = 16,\n    PROV_EC_ECNRA_FULL = 17,\n    PROV_DH_SCHANNEL = 18,\n    PROV_SPYRUS_LYNKS = 20,\n    PROV_RNG = 21,\n    PROV_INTEL_SEC = 22,\n    PROV_RSA_AES = 24,\n    MAXUIDLEN = 64,\n}\n\nenum {\n    CUR_BLOB_VERSION = 2,\n}\n\nenum {\n    X509_ASN_ENCODING = 1,\n    PKCS_7_ASN_ENCODING  = 65536,\n}\n\nenum {\n    CERT_V1 = 0,\n    CERT_V2 = 1,\n    CERT_V3 = 2,\n}\n\nenum {\n    CERT_E_CHAINING = (-2146762486),\n    CERT_E_CN_NO_MATCH = (-2146762481),\n    CERT_E_EXPIRED = (-2146762495),\n    CERT_E_PURPOSE = (-2146762490),\n    CERT_E_REVOCATION_FAILURE = (-2146762482),\n    CERT_E_REVOKED = (-2146762484),\n    CERT_E_ROLE = (-2146762493),\n    CERT_E_UNTRUSTEDROOT = (-2146762487),\n    CERT_E_UNTRUSTEDTESTROOT = (-2146762483),\n    CERT_E_VALIDITYPERIODNESTING = (-2146762494),\n    CERT_E_WRONG_USAGE = (-2146762480),\n    CERT_E_PATHLENCONST = (-2146762492),\n    CERT_E_CRITICAL = (-2146762491),\n    CERT_E_ISSUERCHAINING = (-2146762489),\n    CERT_E_MALFORMED = (-2146762488),\n    CRYPT_E_REVOCATION_OFFLINE = (-2146885613),\n    CRYPT_E_REVOKED = (-2146885616),\n    TRUST_E_BASIC_CONSTRAINTS = (-2146869223),\n    TRUST_E_CERT_SIGNATURE = (-2146869244),\n    TRUST_E_FAIL = (-2146762485),\n}\n\nenum {\n    CERT_TRUST_NO_ERROR = 0,\n    CERT_TRUST_IS_NOT_TIME_VALID = 1,\n    CERT_TRUST_IS_NOT_TIME_NESTED = 2,\n    CERT_TRUST_IS_REVOKED = 4,\n    CERT_TRUST_IS_NOT_SIGNATURE_VALID = 8,\n    CERT_TRUST_IS_NOT_VALID_FOR_USAGE = 16,\n    CERT_TRUST_IS_UNTRUSTED_ROOT = 32,\n    CERT_TRUST_REVOCATION_STATUS_UNKNOWN = 64,\n    CERT_TRUST_IS_CYCLIC = 128,\n    CERT_TRUST_IS_PARTIAL_CHAIN = 65536,\n    CERT_TRUST_CTL_IS_NOT_TIME_VALID = 131072,\n    CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID = 262144,\n    CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE = 524288,\n}\n\nenum {\n    CERT_TRUST_HAS_EXACT_MATCH_ISSUER = 1,\n    CERT_TRUST_HAS_KEY_MATCH_ISSUER = 2,\n    CERT_TRUST_HAS_NAME_MATCH_ISSUER = 4,\n    CERT_TRUST_IS_SELF_SIGNED = 8,\n    CERT_TRUST_IS_COMPLEX_CHAIN = 65536,\n}\n\nenum {\n    CERT_CHAIN_POLICY_BASE              = cast(LPCSTR) 1,\n    CERT_CHAIN_POLICY_AUTHENTICODE      = cast(LPCSTR) 2,\n    CERT_CHAIN_POLICY_AUTHENTICODE_TS   = cast(LPCSTR) 3,\n    CERT_CHAIN_POLICY_SSL               = cast(LPCSTR) 4,\n    CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = cast(LPCSTR) 5,\n    CERT_CHAIN_POLICY_NT_AUTH           = cast(LPCSTR) 6,\n}\n\nenum {\n    USAGE_MATCH_TYPE_AND = 0,\n    USAGE_MATCH_TYPE_OR = 1,\n}\n\nenum {\n    CERT_SIMPLE_NAME_STR = 1,\n    CERT_OID_NAME_STR = 2,\n    CERT_X500_NAME_STR = 3,\n}\nenum {\n    CERT_NAME_STR_SEMICOLON_FLAG = 1073741824,\n    CERT_NAME_STR_CRLF_FLAG = 134217728,\n    CERT_NAME_STR_NO_PLUS_FLAG = 536870912,\n    CERT_NAME_STR_NO_QUOTING_FLAG = 268435456,\n    CERT_NAME_STR_REVERSE_FLAG = 33554432,\n    CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG = 131072,\n}\n\nenum {\n    CERT_FIND_ANY = 0,\n    CERT_FIND_CERT_ID = 1048576,\n    CERT_FIND_CTL_USAGE = 655360,\n    CERT_FIND_ENHKEY_USAGE = 655360,\n    CERT_FIND_EXISTING = 851968,\n    CERT_FIND_HASH = 65536,\n    CERT_FIND_ISSUER_ATTR = 196612,\n    CERT_FIND_ISSUER_NAME = 131076,\n    CERT_FIND_ISSUER_OF = 786432,\n    CERT_FIND_KEY_IDENTIFIER = 983040,\n    CERT_FIND_KEY_SPEC = 589824,\n    CERT_FIND_MD5_HASH = 262144,\n    CERT_FIND_PROPERTY = 327680,\n    CERT_FIND_PUBLIC_KEY = 393216,\n    CERT_FIND_SHA1_HASH = 65536,\n    CERT_FIND_SIGNATURE_HASH = 917504,\n    CERT_FIND_SUBJECT_ATTR = 196615,\n    CERT_FIND_SUBJECT_CERT = 720896,\n    CERT_FIND_SUBJECT_NAME = 131079,\n    CERT_FIND_SUBJECT_STR_A = 458759,\n    CERT_FIND_SUBJECT_STR_W = 524295,\n    CERT_FIND_ISSUER_STR_A = 458756,\n    CERT_FIND_ISSUER_STR_W = 524292,\n}\n\nenum {\n    CERT_FIND_OR_ENHKEY_USAGE_FLAG = 16,\n    CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG  = 1,\n    CERT_FIND_NO_ENHKEY_USAGE_FLAG  = 8,\n    CERT_FIND_VALID_ENHKEY_USAGE_FLAG  = 32,\n    CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG  = 2,\n}\n\nenum {\n    CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG  = 2,\n    CERT_UNICODE_IS_RDN_ATTRS_FLAG = 1,\n    CERT_CHAIN_FIND_BY_ISSUER = 1,\n}\n\nenum {\n    CERT_CHAIN_FIND_BY_ISSUER_COMPARE_KEY_FLAG = 1,\n    CERT_CHAIN_FIND_BY_ISSUER_COMPLEX_CHAIN_FLAG = 2,\n    CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_URL_FLAG = 4,\n    CERT_CHAIN_FIND_BY_ISSUER_LOCAL_MACHINE_FLAG = 8,\n    CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG = 16384,\n    CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_FLAG = 32768,\n}\n\nenum {\n    CERT_STORE_PROV_SYSTEM = 10,\n    CERT_SYSTEM_STORE_LOCAL_MACHINE = 131072,\n}\n\nenum {\n    szOID_PKIX_KP_SERVER_AUTH = \"4235600\",\n    szOID_SERVER_GATED_CRYPTO = \"4235658\",\n    szOID_SGC_NETSCAPE = \"2.16.840.1.113730.4.1\",\n    szOID_PKIX_KP_CLIENT_AUTH = \"1.3.6.1.5.5.7.3.2\",\n}\n\nenum {\n    CRYPT_NOHASHOID = 0x00000001,\n    CRYPT_NO_SALT = 0x10,\n    CRYPT_PREGEN = 0x40,\n}\n\nenum {\n    CRYPT_RECIPIENT = 0x10,\n    CRYPT_INITIATOR = 0x40,\n    CRYPT_ONLINE = 0x80,\n    CRYPT_SF = 0x100,\n    CRYPT_CREATE_IV = 0x200,\n    CRYPT_KEK = 0x400,\n    CRYPT_DATA_KEY = 0x800,\n    CRYPT_VOLATILE = 0x1000,\n    CRYPT_SGCKEY = 0x2000,\n}\n\nenum {\n    KP_IV               = 0x00000001,\n    KP_SALT             = 0x00000002,\n    KP_PADDING          = 0x00000003,\n    KP_MODE             = 0x00000004,\n    KP_MODE_BITS        = 0x00000005,\n    KP_PERMISSIONS      = 0x00000006,\n    KP_ALGID            = 0x00000007,\n    KP_BLOCKLEN         = 0x00000008,\n    KP_KEYLEN           = 0x00000009,\n    KP_SALT_EX          = 0x0000000a,\n    KP_P                = 0x0000000b,\n    KP_G                = 0x0000000c,\n    KP_Q                = 0x0000000d,\n    KP_X                = 0x0000000e,\n    KP_Y                = 0x0000000f,\n    KP_RA               = 0x00000010,\n    KP_RB               = 0x00000011,\n    KP_INFO             = 0x00000012,\n    KP_EFFECTIVE_KEYLEN = 0x00000013,\n    KP_SCHANNEL_ALG     = 0x00000014,\n    KP_PUB_PARAMS       = 0x00000027,\n}\n\nenum {\n    CRYPT_FLAG_PCT1    = 0x0001,\n    CRYPT_FLAG_SSL2    = 0x0002,\n    CRYPT_FLAG_SSL3    = 0x0004,\n    CRYPT_FLAG_TLS1    = 0x0008,\n    CRYPT_FLAG_IPSEC   = 0x0010,\n    CRYPT_FLAG_SIGNING = 0x0020,\n}\n\nenum {\n    SCHANNEL_MAC_KEY    = 0x00000000,\n    SCHANNEL_ENC_KEY    = 0x00000001,\n}\n\nenum {\n    INTERNATIONAL_USAGE = 0x00000001,\n}\n\n\nalias UINT ALG_ID;\nalias ULONG_PTR HCRYPTPROV, HCRYPTKEY, HCRYPTHASH;\nalias PVOID HCERTSTORE, HCRYPTMSG, HCERTCHAINENGINE;\n\nstruct VTableProvStruc {\n    FARPROC FuncVerifyImage;\n}\nalias VTableProvStruc* PVTableProvStruc;\n\nstruct _CRYPTOAPI_BLOB {\n    DWORD cbData;\n    BYTE* pbData;\n}\nalias _CRYPTOAPI_BLOB CRYPT_INTEGER_BLOB, CRYPT_UINT_BLOB,\n  CRYPT_OBJID_BLOB, CERT_NAME_BLOB, CERT_RDN_VALUE_BLOB, CERT_BLOB,\n  CRL_BLOB, DATA_BLOB, CRYPT_DATA_BLOB, CRYPT_HASH_BLOB,\n  CRYPT_DIGEST_BLOB, CRYPT_DER_BLOB, CRYPT_ATTR_BLOB;\nalias _CRYPTOAPI_BLOB* PCRYPT_INTEGER_BLOB, PCRYPT_UINT_BLOB,\n  PCRYPT_OBJID_BLOB, PCERT_NAME_BLOB, PCERT_RDN_VALUE_BLOB, PCERT_BLOB,\n  PCRL_BLOB, PDATA_BLOB, PCRYPT_DATA_BLOB, PCRYPT_HASH_BLOB,\n  PCRYPT_DIGEST_BLOB, PCRYPT_DER_BLOB, PCRYPT_ATTR_BLOB;\n\n// not described in SDK; has the same layout as HTTPSPolicyCallbackData\nstruct SSL_EXTRA_CERT_CHAIN_POLICY_PARA {\n    DWORD  cbStruct;\n    DWORD  dwAuthType;\n    DWORD  fdwChecks;\n    LPWSTR pwszServerName;\n}\nalias SSL_EXTRA_CERT_CHAIN_POLICY_PARA HTTPSPolicyCallbackData;\nalias SSL_EXTRA_CERT_CHAIN_POLICY_PARA* PSSL_EXTRA_CERT_CHAIN_POLICY_PARA,\n  PHTTPSPolicyCallbackData;\n\n/* #if (_WIN32_WINNT>=0x500) */\nstruct CERT_CHAIN_POLICY_PARA {\n    DWORD cbSize = CERT_CHAIN_POLICY_PARA.sizeof;\n    DWORD dwFlags;\n    void* pvExtraPolicyPara;\n}\nalias CERT_CHAIN_POLICY_PARA* PCERT_CHAIN_POLICY_PARA;\n\nstruct CERT_CHAIN_POLICY_STATUS {\n    DWORD cbSize = CERT_CHAIN_POLICY_STATUS.sizeof;\n    DWORD dwError;\n    LONG  lChainIndex;\n    LONG  lElementIndex;\n    void* pvExtraPolicyStatus;\n}\nalias CERT_CHAIN_POLICY_STATUS* PCERT_CHAIN_POLICY_STATUS;\n/* #endif */\n\nstruct CRYPT_ALGORITHM_IDENTIFIER {\n    LPSTR pszObjId;\n    CRYPT_OBJID_BLOB Parameters;\n}\nalias CRYPT_ALGORITHM_IDENTIFIER* PCRYPT_ALGORITHM_IDENTIFIER;\n\nstruct CRYPT_BIT_BLOB {\n    DWORD cbData;\n    BYTE* pbData;\n    DWORD cUnusedBits;\n}\nalias CRYPT_BIT_BLOB* PCRYPT_BIT_BLOB;\n\nstruct CERT_PUBLIC_KEY_INFO {\n    CRYPT_ALGORITHM_IDENTIFIER Algorithm;\n    CRYPT_BIT_BLOB             PublicKey;\n}\nalias CERT_PUBLIC_KEY_INFO* PCERT_PUBLIC_KEY_INFO;\n\nstruct CERT_EXTENSION {\n    LPSTR            pszObjId;\n    BOOL             fCritical;\n    CRYPT_OBJID_BLOB Value;\n}\nalias CERT_EXTENSION* PCERT_EXTENSION;\n\nstruct CERT_INFO {\n    DWORD dwVersion;\n    CRYPT_INTEGER_BLOB SerialNumber;\n    CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;\n    CERT_NAME_BLOB Issuer;\n    FILETIME NotBefore;\n    FILETIME NotAfter;\n    CERT_NAME_BLOB Subject;\n    CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;\n    CRYPT_BIT_BLOB IssuerUniqueId;\n    CRYPT_BIT_BLOB SubjectUniqueId;\n    DWORD cExtension;\n    PCERT_EXTENSION rgExtension;\n}\nalias CERT_INFO* PCERT_INFO;\n\nstruct CERT_CONTEXT {\n    DWORD      dwCertEncodingType;\n    BYTE*      pbCertEncoded;\n    DWORD      cbCertEncoded;\n    PCERT_INFO pCertInfo;\n    HCERTSTORE hCertStore;\n}\nalias CERT_CONTEXT*        PCERT_CONTEXT;\nalias const(CERT_CONTEXT)* PCCERT_CONTEXT;\n\nstruct CTL_USAGE {\n    DWORD  cUsageIdentifier;\n    LPSTR* rgpszUsageIdentifier;\n}\nalias CTL_USAGE CERT_ENHKEY_USAGE;\nalias CTL_USAGE* PCTRL_USAGE, PCERT_ENHKEY_USAGE;\n\nstruct CERT_USAGE_MATCH {\n    DWORD             dwType;\n    CERT_ENHKEY_USAGE Usage;\n}\nalias CERT_USAGE_MATCH* PCERT_USAGE_MATCH;\n/* #if (_WIN32_WINNT>=0x500) */\n\nstruct CERT_CHAIN_PARA {\n    DWORD            cbSize = CERT_CHAIN_PARA.sizeof;\n    CERT_USAGE_MATCH RequestedUsage;\n//#if CERT_CHAIN_PARA_HAS_EXTRA_FIELDS\n    CERT_USAGE_MATCH RequestedIssuancePolicy;\n    DWORD            dwUrlRetrievalTimeout;\n    BOOL             fCheckRevocationFreshnessTime;\n    DWORD            dwRevocationFreshnessTime;\n//#endif\n}\nalias CERT_CHAIN_PARA* PCERT_CHAIN_PARA;\n\nextern (Windows) alias BOOL function(PCCERT_CONTEXT, void*)\n  PFN_CERT_CHAIN_FIND_BY_ISSUER_CALLBACK;\n\nstruct CERT_CHAIN_FIND_BY_ISSUER_PARA {\n    DWORD  cbSize = CERT_CHAIN_FIND_BY_ISSUER_PARA.sizeof;\n    LPCSTR pszUsageIdentifier;\n    DWORD  dwKeySpec;\n    DWORD  dwAcquirePrivateKeyFlags;\n    DWORD  cIssuer;\n    CERT_NAME_BLOB* rgIssuer;\n    PFN_CERT_CHAIN_FIND_BY_ISSUER_CALLBACK pfnFIndCallback;\n    void*  pvFindArg;\n    DWORD* pdwIssuerChainIndex;\n    DWORD* pdwIssuerElementIndex;\n}\nalias CERT_CHAIN_FIND_BY_ISSUER_PARA* PCERT_CHAIN_FIND_BY_ISSUER_PARA;\n/* #endif */\n\nstruct CERT_TRUST_STATUS {\n    DWORD dwErrorStatus;\n    DWORD dwInfoStatus;\n}\nalias CERT_TRUST_STATUS* PCERT_TRUST_STATUS;\n\nstruct CRL_ENTRY {\n    CRYPT_INTEGER_BLOB SerialNumber;\n    FILETIME           RevocationDate;\n    DWORD              cExtension;\n    PCERT_EXTENSION    rgExtension;\n}\nalias CRL_ENTRY* PCRL_ENTRY;\n\nstruct CRL_INFO {\n    DWORD           dwVersion;\n    CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;\n    CERT_NAME_BLOB  Issuer;\n    FILETIME        ThisUpdate;\n    FILETIME        NextUpdate;\n    DWORD           cCRLEntry;\n    PCRL_ENTRY      rgCRLEntry;\n    DWORD           cExtension;\n    PCERT_EXTENSION rgExtension;\n}\nalias CRL_INFO* PCRL_INFO;\n\nstruct CRL_CONTEXT {\n    DWORD      dwCertEncodingType;\n    BYTE*      pbCrlEncoded;\n    DWORD      cbCrlEncoded;\n    PCRL_INFO  pCrlInfo;\n    HCERTSTORE hCertStore;\n}\nalias CRL_CONTEXT*        PCRL_CONTEXT;\nalias const(CRL_CONTEXT)* PCCRL_CONTEXT;\n\nstruct CERT_REVOCATION_CRL_INFO {\n    DWORD         cbSize = CERT_REVOCATION_CRL_INFO.sizeof;\n    PCCRL_CONTEXT pBaseCRLContext;\n    PCCRL_CONTEXT pDeltaCRLContext;\n    PCRL_ENTRY    pCrlEntry;\n    BOOL          fDeltaCrlEntry;\n}\nalias CERT_REVOCATION_CRL_INFO* PCERT_REVOCATION_CRL_INFO;\n\nstruct CERT_REVOCATION_INFO {\n    DWORD  cbSize = CERT_REVOCATION_INFO.sizeof;\n    DWORD  dwRevocationResult;\n    LPCSTR pszRevocationOid;\n    LPVOID pvOidSpecificInfo;\n    BOOL   fHasFreshnessTime;\n    DWORD  dwFreshnessTime;\n    PCERT_REVOCATION_CRL_INFO pCrlInfo;\n}\nalias CERT_REVOCATION_INFO* PCERT_REVOCATION_INFO;\n\n/* #if (_WIN32_WINNT>=0x500) */\nstruct CERT_CHAIN_ELEMENT {\n    DWORD                 cbSize = CERT_CHAIN_ELEMENT.sizeof;\n    PCCERT_CONTEXT        pCertContext;\n    CERT_TRUST_STATUS     TrustStatus;\n    PCERT_REVOCATION_INFO pRevocationInfo;\n    PCERT_ENHKEY_USAGE    pIssuanceUsage;\n    PCERT_ENHKEY_USAGE    pApplicationUsage;\n}\nalias CERT_CHAIN_ELEMENT* PCERT_CHAIN_ELEMENT;\n/* #endif */\n\nstruct CRYPT_ATTRIBUTE {\n    LPSTR            pszObjId;\n    DWORD            cValue;\n    PCRYPT_ATTR_BLOB rgValue;\n}\nalias CRYPT_ATTRIBUTE* PCRYPT_ATTRIBUTE;\n\nstruct CTL_ENTRY {\n    CRYPT_DATA_BLOB  SubjectIdentifier;\n    DWORD            cAttribute;\n    PCRYPT_ATTRIBUTE rgAttribute;\n}\nalias CTL_ENTRY* PCTL_ENTRY;\n\nstruct CTL_INFO {\n    DWORD              dwVersion;\n    CTL_USAGE          SubjectUsage;\n    CRYPT_DATA_BLOB    ListIdentifier;\n    CRYPT_INTEGER_BLOB SequenceNumber;\n    FILETIME           ThisUpdate;\n    FILETIME           NextUpdate;\n    CRYPT_ALGORITHM_IDENTIFIER SubjectAlgorithm;\n    DWORD              cCTLEntry;\n    PCTL_ENTRY         rgCTLEntry;\n    DWORD              cExtension;\n    PCERT_EXTENSION    rgExtension;\n}\nalias CTL_INFO* PCTL_INFO;\n\nstruct CTL_CONTEXT {\n    DWORD      dwMsgAndCertEncodingType;\n    BYTE*      pbCtlEncoded;\n    DWORD      cbCtlEncoded;\n    PCTL_INFO  pCtlInfo;\n    HCERTSTORE hCertStore;\n    HCRYPTMSG  hCryptMsg;\n    BYTE*      pbCtlContent;\n    DWORD      cbCtlContent;\n}\nalias CTL_CONTEXT*        PCTL_CONTEXT;\nalias const(CTL_CONTEXT)* PCCTL_CONTEXT;\n\nstruct CERT_TRUST_LIST_INFO {\n    DWORD         cbSize = CERT_TRUST_LIST_INFO.sizeof;\n    PCTL_ENTRY    pCtlEntry;\n    PCCTL_CONTEXT pCtlContext;\n}\nalias CERT_TRUST_LIST_INFO* PCERT_TRUST_LIST_INFO;\n\nstruct CERT_SIMPLE_CHAIN {\n    DWORD                 cbSize = CERT_SIMPLE_CHAIN.sizeof;\n    CERT_TRUST_STATUS     TrustStatus;\n    DWORD                 cElement;\n    PCERT_CHAIN_ELEMENT*  rgpElement;\n    PCERT_TRUST_LIST_INFO pTrustListInfo;\n    BOOL                  fHasRevocationFreshnessTime;\n    DWORD                 dwRevocationFreshnessTime;\n}\nalias CERT_SIMPLE_CHAIN* PCERT_SIMPLE_CHAIN;\n\n/* #if (_WIN32_WINNT>=0x500) */\nalias const(CERT_CHAIN_CONTEXT)* PCCERT_CHAIN_CONTEXT;\nstruct CERT_CHAIN_CONTEXT {\n    DWORD                 cbSize = CERT_CHAIN_CONTEXT.sizeof;\n    CERT_TRUST_STATUS     TrustStatus;\n    DWORD                 cChain;\n    PCERT_SIMPLE_CHAIN*   rgpChain;\n    DWORD                 cLowerQualityChainContext;\n    PCCERT_CHAIN_CONTEXT* rgpLowerQualityChainContext;\n    BOOL                  fHasRevocationFreshnessTime;\n    DWORD                 dwRevocationFreshnessTime;\n}\nalias CERT_CHAIN_CONTEXT* PCERT_CHAIN_CONTEXT;\n/* #endif */\n\nstruct PROV_ENUMALGS {\n    ALG_ID   aiAlgid;\n    DWORD    dwBitLen;\n    DWORD    dwNameLen;\n    CHAR[20] szName;\n}\n\nstruct PUBLICKEYSTRUC {\n    BYTE   bType;\n    BYTE   bVersion;\n    WORD   reserved;\n    ALG_ID aiKeyAlg;\n}\nalias PUBLICKEYSTRUC BLOBHEADER;\n\nstruct RSAPUBKEY {\n    DWORD magic;\n    DWORD bitlen;\n    DWORD pubexp;\n}\n\nstruct HMAC_INFO {\n    ALG_ID HashAlgid;\n    BYTE*  pbInnerString;\n    DWORD  cbInnerString;\n    BYTE*  pbOuterString;\n    DWORD  cbOuterString;\n}\nalias HMAC_INFO* PHMAC_INFO;\n\nextern (Windows) @nogc nothrow {\n    BOOL CertCloseStore(HCERTSTORE, DWORD);\n    BOOL CertGetCertificateChain(HCERTCHAINENGINE, PCCERT_CONTEXT, LPFILETIME,\n      HCERTSTORE, PCERT_CHAIN_PARA, DWORD, LPVOID, PCCERT_CHAIN_CONTEXT*);\n    BOOL CertVerifyCertificateChainPolicy(LPCSTR, PCCERT_CHAIN_CONTEXT,\n      PCERT_CHAIN_POLICY_PARA, PCERT_CHAIN_POLICY_STATUS);\n    void CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT);\n    DWORD CertNameToStrA(DWORD, PCERT_NAME_BLOB, DWORD, LPSTR, DWORD);\n    DWORD CertNameToStrW(DWORD, PCERT_NAME_BLOB, DWORD, LPWSTR, DWORD);\n    HCERTSTORE CertOpenSystemStoreA(HCRYPTPROV, LPCSTR);\n    HCERTSTORE CertOpenSystemStoreW(HCRYPTPROV, LPCWSTR);\n    HCERTSTORE CertOpenStore(LPCSTR, DWORD, HCRYPTPROV, DWORD, const(void)*);\n    PCCERT_CONTEXT CertFindCertificateInStore(HCERTSTORE, DWORD, DWORD, DWORD,\nconst(void)*, PCCERT_CONTEXT);\n    BOOL CertFreeCertificateContext(PCCERT_CONTEXT);\n    PCCERT_CONTEXT CertGetIssuerCertificateFromStore(HCERTSTORE,\n      PCCERT_CONTEXT, PCCERT_CONTEXT, DWORD*);\n    PCCERT_CHAIN_CONTEXT CertFindChainInStore(HCERTSTORE, DWORD, DWORD, DWORD,\nconst(void)*, PCCERT_CHAIN_CONTEXT);\n\n    BOOL CryptAcquireContextA(HCRYPTPROV*, LPCSTR, LPCSTR, DWORD, DWORD);\n    BOOL CryptAcquireContextW(HCRYPTPROV*, LPCWSTR, LPCWSTR, DWORD, DWORD);\n     BOOL CryptContextAddRef(HCRYPTPROV, DWORD*, DWORD);\n    BOOL CryptReleaseContext(HCRYPTPROV, ULONG_PTR);\n    BOOL CryptGenKey(HCRYPTPROV, ALG_ID, DWORD, HCRYPTKEY*);\n    BOOL CryptDeriveKey(HCRYPTPROV, ALG_ID, HCRYPTHASH, DWORD, HCRYPTKEY*);\n    BOOL CryptDestroyKey(HCRYPTKEY);\n    static if (_WIN32_WINNT >= 0x500) {\n        BOOL CryptDuplicateHash(HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);\n        BOOL CryptDuplicateKey(HCRYPTKEY, DWORD*, DWORD, HCRYPTKEY*);\n    }\n    BOOL CryptSetKeyParam(HCRYPTKEY, DWORD, PBYTE, DWORD);\n    BOOL CryptGetKeyParam(HCRYPTKEY, DWORD, PBYTE, PDWORD, DWORD);\n    BOOL CryptSetHashParam(HCRYPTHASH, DWORD, PBYTE, DWORD);\n    BOOL CryptGetHashParam(HCRYPTHASH, DWORD, PBYTE, PDWORD, DWORD);\n    BOOL CryptSetProvParam(HCRYPTPROV, DWORD, PBYTE, DWORD);\n    BOOL CryptGetProvParam(HCRYPTPROV, DWORD, PBYTE, PDWORD, DWORD);\n    BOOL CryptGenRandom(HCRYPTPROV, DWORD, PBYTE);\n    BOOL CryptGetUserKey(HCRYPTPROV, DWORD, HCRYPTKEY*);\n    BOOL CryptExportKey(HCRYPTKEY, HCRYPTKEY, DWORD, DWORD, PBYTE, PDWORD);\n    BOOL CryptImportKey(HCRYPTPROV, PBYTE, DWORD, HCRYPTKEY, DWORD,\n      HCRYPTKEY*);\n    BOOL CryptEncrypt(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, PBYTE, PDWORD,\n      DWORD);\n    BOOL CryptDecrypt(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, PBYTE, PDWORD);\n    BOOL CryptCreateHash(HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH*);\n    BOOL CryptHashData(HCRYPTHASH, PBYTE, DWORD, DWORD);\n    BOOL CryptHashSessionKey(HCRYPTHASH, HCRYPTKEY, DWORD);\n    BOOL CryptGetHashValue(HCRYPTHASH, DWORD, PBYTE, PDWORD);\n    BOOL CryptDestroyHash(HCRYPTHASH);\n    BOOL CryptSignHashA(HCRYPTHASH, DWORD, LPCSTR, DWORD, PBYTE, PDWORD);\n    BOOL CryptSignHashW(HCRYPTHASH, DWORD, LPCWSTR, DWORD, PBYTE, PDWORD);\n    BOOL CryptVerifySignatureA(HCRYPTHASH, PBYTE, DWORD, HCRYPTKEY, LPCSTR,\n      DWORD);\n    BOOL CryptVerifySignatureW(HCRYPTHASH, PBYTE, DWORD, HCRYPTKEY, LPCWSTR,\n      DWORD);\n    BOOL CryptSetProviderA(LPCSTR, DWORD);\n    BOOL CryptSetProviderW(LPCWSTR, DWORD);\n}\n\nversion (Unicode) {\n    alias CertNameToStrW CertNameToStr;\n    alias CryptAcquireContextW CryptAcquireContext;\n    alias CryptSignHashW CryptSignHash;\n    alias CryptVerifySignatureW CryptVerifySignature;\n    alias CryptSetProviderW CryptSetProvider;\n    alias CertOpenSystemStoreW CertOpenSystemStore;\n    /+alias CERT_FIND_SUBJECT_STR_W CERT_FIND_SUBJECT_STR;\n    alias CERT_FIND_ISSUER_STR_W CERT_FIND_ISSUER_STR;+/\n} else {\n    alias CertNameToStrA CertNameToStr;\n    alias CryptAcquireContextA CryptAcquireContext;\n    alias CryptSignHashA CryptSignHash;\n    alias CryptVerifySignatureA CryptVerifySignature;\n    alias CryptSetProviderA CryptSetProvider;\n    alias CertOpenSystemStoreA CertOpenSystemStore;\n    /+alias CERT_FIND_SUBJECT_STR_A CERT_FIND_SUBJECT_STR;\n    alias CERT_FIND_ISSUER_STR_A CERT_FIND_ISSUER_STR;+/\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/windef.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_windef.d)\n */\nmodule core.sys.windows.windef;\nversion (Windows):\n\npublic import core.sys.windows.winnt;\nprivate import core.sys.windows.w32api;\n\nenum size_t MAX_PATH = 260;\n\npure nothrow @nogc {\n    ushort MAKEWORD(ubyte a, ubyte b) {\n        return cast(ushort) ((b << 8) | a);\n    }\n\n    ushort MAKEWORD(ushort a, ushort b) {\n        assert((a & 0xFF00) == 0);\n        assert((b & 0xFF00) == 0);\n        return MAKEWORD(cast(ubyte)a, cast(ubyte)b);\n    }\n\n    uint MAKELONG(ushort a, ushort b) {\n        return cast(uint) ((b << 16) | a);\n    }\n\n    uint MAKELONG(uint a, uint b) {\n        assert((a & 0xFFFF0000) == 0);\n        assert((b & 0xFFFF0000) == 0);\n        return MAKELONG(cast(ushort)a, cast(ushort)b);\n    }\n\n    ushort LOWORD(ulong l) {\n        return cast(ushort) l;\n    }\n\n    ushort HIWORD(ulong l) {\n        return cast(ushort) (l >>> 16);\n    }\n\n    ubyte LOBYTE(ushort w) {\n        return cast(ubyte) w;\n    }\n\n    ubyte HIBYTE(ushort w) {\n        return cast(ubyte) (w >>> 8);\n    }\n}\n\nenum NULL = null;\nstatic assert (is(typeof({\n    void test(int* p) {}\n    test(NULL);\n})));\n\nalias ubyte        BYTE;\nalias ubyte*       PBYTE, LPBYTE;\nalias ushort       USHORT, WORD, ATOM;\nalias ushort*      PUSHORT, PWORD, LPWORD;\nalias uint         ULONG, DWORD, UINT, COLORREF;\nalias uint*        PULONG, PDWORD, LPDWORD, PUINT, LPUINT, LPCOLORREF;\nalias int          WINBOOL, BOOL, INT, LONG, HFILE, HRESULT;\nalias int*         PWINBOOL, LPWINBOOL, PBOOL, LPBOOL, PINT, LPINT, LPLONG;\nalias float        FLOAT;\nalias float*       PFLOAT;\nalias const(void)* PCVOID, LPCVOID;\n\nalias UINT_PTR WPARAM;\nalias LONG_PTR LPARAM, LRESULT;\n\nmixin DECLARE_HANDLE!(\"HHOOK\");\nmixin DECLARE_HANDLE!(\"HGLOBAL\");\nmixin DECLARE_HANDLE!(\"HLOCAL\");\nmixin DECLARE_HANDLE!(\"GLOBALHANDLE\");\nmixin DECLARE_HANDLE!(\"LOCALHANDLE\");\nmixin DECLARE_HANDLE!(\"HGDIOBJ\");\nmixin DECLARE_HANDLE!(\"HACCEL\");\nmixin DECLARE_HANDLE!(\"HBITMAP\", HGDIOBJ);\nmixin DECLARE_HANDLE!(\"HBRUSH\", HGDIOBJ);\nmixin DECLARE_HANDLE!(\"HCOLORSPACE\");\nmixin DECLARE_HANDLE!(\"HDC\");\nmixin DECLARE_HANDLE!(\"HGLRC\");\nmixin DECLARE_HANDLE!(\"HDESK\");\nmixin DECLARE_HANDLE!(\"HENHMETAFILE\");\nmixin DECLARE_HANDLE!(\"HFONT\", HGDIOBJ);\nmixin DECLARE_HANDLE!(\"HICON\");\nmixin DECLARE_HANDLE!(\"HINSTANCE\");\nmixin DECLARE_HANDLE!(\"HKEY\");\nmixin DECLARE_HANDLE!(\"HMENU\");\nmixin DECLARE_HANDLE!(\"HMETAFILE\");\nmixin DECLARE_HANDLE!(\"HMODULE\");\nmixin DECLARE_HANDLE!(\"HMONITOR\");\nmixin DECLARE_HANDLE!(\"HPALETTE\");\nmixin DECLARE_HANDLE!(\"HPEN\", HGDIOBJ);\nmixin DECLARE_HANDLE!(\"HRGN\", HGDIOBJ);\nmixin DECLARE_HANDLE!(\"HRSRC\");\nmixin DECLARE_HANDLE!(\"HSTR\");\nmixin DECLARE_HANDLE!(\"HTASK\");\nmixin DECLARE_HANDLE!(\"HWND\");\nmixin DECLARE_HANDLE!(\"HWINSTA\");\nmixin DECLARE_HANDLE!(\"HKL\");\nmixin DECLARE_HANDLE!(\"HCURSOR\");\nalias HKEY* PHKEY;\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    mixin DECLARE_HANDLE!(\"HTERMINAL\");\n    mixin DECLARE_HANDLE!(\"HWINEVENTHOOK\");\n}\n\nalias extern (Windows) INT_PTR function() nothrow FARPROC, NEARPROC, PROC;\n\nstruct RECT {\n    LONG left;\n    LONG top;\n    LONG right;\n    LONG bottom;\n}\nalias RECT RECTL;\nalias RECT*        PRECT, NPRECT, LPRECT, PRECTL, LPRECTL;\nalias const(RECT)* LPCRECT, LPCRECTL;\n\nstruct POINT {\n    LONG x;\n    LONG y;\n}\nalias POINT POINTL;\nalias POINT* PPOINT, NPPOINT, LPPOINT, PPOINTL, LPPOINTL;\n\nstruct SIZE {\n    LONG cx;\n    LONG cy;\n}\nalias SIZE SIZEL;\nalias SIZE* PSIZE, LPSIZE, PSIZEL, LPSIZEL;\n\nstruct POINTS {\n    SHORT x;\n    SHORT y;\n}\nalias POINTS* PPOINTS, LPPOINTS;\n\nenum : BOOL {\n    FALSE = 0,\n    TRUE  = 1\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/windows.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 4.0\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_windows.d)\n */\nmodule core.sys.windows.windows;\nversion (Windows):\n\n/*\n    windows.h - main header file for the Win32 API\n\n    Written by Anders Norlander <anorland@hem2.passagen.se>\n\n    This file is part of a free library for the Win32 API.\n\n    This library is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n*/\n\npublic import core.sys.windows.w32api;\npublic import core.sys.windows.core;\n\npublic import core.sys.windows.cderr;\npublic import core.sys.windows.dde;\npublic import core.sys.windows.ddeml;\npublic import core.sys.windows.dlgs;\npublic import core.sys.windows.imm;\npublic import core.sys.windows.lzexpand;\npublic import core.sys.windows.mmsystem;\npublic import core.sys.windows.nb30;\npublic import core.sys.windows.winsvc;\n\npublic import core.sys.windows.rpc;\npublic import core.sys.windows.shellapi;\npublic import core.sys.windows.winperf;\npublic import core.sys.windows.commdlg;\npublic import core.sys.windows.winspool;\npublic import core.sys.windows.ole2;\n\npublic import core.sys.windows.winreg;\n\npublic import core.sys.windows.winsock2;\n\n/+\n#if (_WIN32_WINNT >= 0x400)\n#include <winsock2.h>\n/*\n * MS likes to include mswsock.h here as well,\n * but that can cause undefined symbols if\n * winsock2.h is included before windows.h\n */\n#else\n#include <winsock.h>\n#endif /*  (_WIN32_WINNT >= 0x400) */\n+/\n\n// For compatibility with previous\n// core.sys.windows.windows...\npublic import core.sys.windows.imagehlp;\npublic import core.sys.windows.dbghelp_types;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winerror.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winerror.d)\n */\nmodule core.sys.windows.winerror;\nversion (Windows):\n\n/* Comments from the Mingw header:\n * WAIT_TIMEOUT is also defined in winbase.h\n */\n\nprivate import core.sys.windows.windef;\n\nalias int SCODE; // was in core.sys.windows.wtypes.\n\nenum : uint {\n    ERROR_SUCCESS                                         =     0,\n    NO_ERROR                                              =     0,\n    ERROR_INVALID_FUNCTION,\n    ERROR_FILE_NOT_FOUND,\n    ERROR_PATH_NOT_FOUND,\n    ERROR_TOO_MANY_OPEN_FILES,\n    ERROR_ACCESS_DENIED,\n    ERROR_INVALID_HANDLE,\n    ERROR_ARENA_TRASHED,\n    ERROR_NOT_ENOUGH_MEMORY,\n    ERROR_INVALID_BLOCK,\n    ERROR_BAD_ENVIRONMENT,\n    ERROR_BAD_FORMAT,\n    ERROR_INVALID_ACCESS,\n    ERROR_INVALID_DATA,\n    ERROR_OUTOFMEMORY,\n    ERROR_INVALID_DRIVE,\n    ERROR_CURRENT_DIRECTORY,\n    ERROR_NOT_SAME_DEVICE,\n    ERROR_NO_MORE_FILES,\n    ERROR_WRITE_PROTECT,\n    ERROR_BAD_UNIT,\n    ERROR_NOT_READY,\n    ERROR_BAD_COMMAND,\n    ERROR_CRC,\n    ERROR_BAD_LENGTH,\n    ERROR_SEEK,\n    ERROR_NOT_DOS_DISK,\n    ERROR_SECTOR_NOT_FOUND,\n    ERROR_OUT_OF_PAPER,\n    ERROR_WRITE_FAULT,\n    ERROR_READ_FAULT,\n    ERROR_GEN_FAILURE,\n    ERROR_SHARING_VIOLATION,\n    ERROR_LOCK_VIOLATION,\n    ERROR_WRONG_DISK,                                  // =    34\n    ERROR_SHARING_BUFFER_EXCEEDED                         =    36,\n    ERROR_HANDLE_EOF                                      =    38,\n    ERROR_HANDLE_DISK_FULL,                            // =    39\n    ERROR_NOT_SUPPORTED                                   =    50,\n    ERROR_REM_NOT_LIST,\n    ERROR_DUP_NAME,\n    ERROR_BAD_NETPATH,\n    ERROR_NETWORK_BUSY,\n    ERROR_DEV_NOT_EXIST,\n    ERROR_TOO_MANY_CMDS,\n    ERROR_ADAP_HDW_ERR,\n    ERROR_BAD_NET_RESP,\n    ERROR_UNEXP_NET_ERR,\n    ERROR_BAD_REM_ADAP,\n    ERROR_PRINTQ_FULL,\n    ERROR_NO_SPOOL_SPACE,\n    ERROR_PRINT_CANCELLED,\n    ERROR_NETNAME_DELETED,\n    ERROR_NETWORK_ACCESS_DENIED,\n    ERROR_BAD_DEV_TYPE,\n    ERROR_BAD_NET_NAME,\n    ERROR_TOO_MANY_NAMES,\n    ERROR_TOO_MANY_SESS,\n    ERROR_SHARING_PAUSED,\n    ERROR_REQ_NOT_ACCEP,\n    ERROR_REDIR_PAUSED,                                // =    72\n    ERROR_FILE_EXISTS                                     =    80,\n    ERROR_CANNOT_MAKE                                     =    82,\n    ERROR_FAIL_I24,\n    ERROR_OUT_OF_STRUCTURES,\n    ERROR_ALREADY_ASSIGNED,\n    ERROR_INVALID_PASSWORD,\n    ERROR_INVALID_PARAMETER,\n    ERROR_NET_WRITE_FAULT,\n    ERROR_NO_PROC_SLOTS,                               // =    89\n    ERROR_TOO_MANY_SEMAPHORES                             =   100,\n    ERROR_EXCL_SEM_ALREADY_OWNED,\n    ERROR_SEM_IS_SET,\n    ERROR_TOO_MANY_SEM_REQUESTS,\n    ERROR_INVALID_AT_INTERRUPT_TIME,\n    ERROR_SEM_OWNER_DIED,\n    ERROR_SEM_USER_LIMIT,\n    ERROR_DISK_CHANGE,\n    ERROR_DRIVE_LOCKED,\n    ERROR_BROKEN_PIPE,\n    ERROR_OPEN_FAILED,\n    ERROR_BUFFER_OVERFLOW,\n    ERROR_DISK_FULL,\n    ERROR_NO_MORE_SEARCH_HANDLES,\n    ERROR_INVALID_TARGET_HANDLE,                       // =   114\n    ERROR_INVALID_CATEGORY                                =   117,\n    ERROR_INVALID_VERIFY_SWITCH,\n    ERROR_BAD_DRIVER_LEVEL,\n    ERROR_CALL_NOT_IMPLEMENTED,\n    ERROR_SEM_TIMEOUT,\n    ERROR_INSUFFICIENT_BUFFER,\n    ERROR_INVALID_NAME,\n    ERROR_INVALID_LEVEL,\n    ERROR_NO_VOLUME_LABEL,\n    ERROR_MOD_NOT_FOUND,\n    ERROR_PROC_NOT_FOUND,\n    ERROR_WAIT_NO_CHILDREN,\n    ERROR_CHILD_NOT_COMPLETE,\n    ERROR_DIRECT_ACCESS_HANDLE,\n    ERROR_NEGATIVE_SEEK,\n    ERROR_SEEK_ON_DEVICE,\n    ERROR_IS_JOIN_TARGET,\n    ERROR_IS_JOINED,\n    ERROR_IS_SUBSTED,\n    ERROR_NOT_JOINED,\n    ERROR_NOT_SUBSTED,\n    ERROR_JOIN_TO_JOIN,\n    ERROR_SUBST_TO_SUBST,\n    ERROR_JOIN_TO_SUBST,\n    ERROR_SUBST_TO_JOIN,\n    ERROR_BUSY_DRIVE,\n    ERROR_SAME_DRIVE,\n    ERROR_DIR_NOT_ROOT,\n    ERROR_DIR_NOT_EMPTY,\n    ERROR_IS_SUBST_PATH,\n    ERROR_IS_JOIN_PATH,\n    ERROR_PATH_BUSY,\n    ERROR_IS_SUBST_TARGET,\n    ERROR_SYSTEM_TRACE,\n    ERROR_INVALID_EVENT_COUNT,\n    ERROR_TOO_MANY_MUXWAITERS,\n    ERROR_INVALID_LIST_FORMAT,\n    ERROR_LABEL_TOO_LONG,\n    ERROR_TOO_MANY_TCBS,\n    ERROR_SIGNAL_REFUSED,\n    ERROR_DISCARDED,\n    ERROR_NOT_LOCKED,\n    ERROR_BAD_THREADID_ADDR,\n    ERROR_BAD_ARGUMENTS,\n    ERROR_BAD_PATHNAME,\n    ERROR_SIGNAL_PENDING,                              // =   162\n    ERROR_MAX_THRDS_REACHED                               =   164,\n    ERROR_LOCK_FAILED                                     =   167,\n    ERROR_BUSY                                            =   170,\n    ERROR_CANCEL_VIOLATION                                =   173,\n    ERROR_ATOMIC_LOCKS_NOT_SUPPORTED,                  // =   174\n    ERROR_INVALID_SEGMENT_NUMBER                          =   180,\n    ERROR_INVALID_ORDINAL                                 =   182,\n    ERROR_ALREADY_EXISTS,                              // =   183\n    ERROR_INVALID_FLAG_NUMBER                             =   186,\n    ERROR_SEM_NOT_FOUND,\n    ERROR_INVALID_STARTING_CODESEG,\n    ERROR_INVALID_STACKSEG,\n    ERROR_INVALID_MODULETYPE,\n    ERROR_INVALID_EXE_SIGNATURE,\n    ERROR_EXE_MARKED_INVALID,\n    ERROR_BAD_EXE_FORMAT,\n    ERROR_ITERATED_DATA_EXCEEDS_64k,\n    ERROR_INVALID_MINALLOCSIZE,\n    ERROR_DYNLINK_FROM_INVALID_RING,\n    ERROR_IOPL_NOT_ENABLED,\n    ERROR_INVALID_SEGDPL,\n    ERROR_AUTODATASEG_EXCEEDS_64k,\n    ERROR_RING2SEG_MUST_BE_MOVABLE,\n    ERROR_RELOC_CHAIN_XEEDS_SEGLIM,\n    ERROR_INFLOOP_IN_RELOC_CHAIN,\n    ERROR_ENVVAR_NOT_FOUND,                            // =   203\n    ERROR_NO_SIGNAL_SENT                                  =   205,\n    ERROR_FILENAME_EXCED_RANGE,\n    ERROR_RING2_STACK_IN_USE,\n    ERROR_META_EXPANSION_TOO_LONG,\n    ERROR_INVALID_SIGNAL_NUMBER,\n    ERROR_THREAD_1_INACTIVE,                           // =   210\n    ERROR_LOCKED                                          =   212,\n    ERROR_TOO_MANY_MODULES                                =   214,\n    ERROR_NESTING_NOT_ALLOWED,\n    ERROR_EXE_MACHINE_TYPE_MISMATCH,\n    ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY,\n    ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY,      // =   218\n    ERROR_BAD_PIPE                                        =   230,\n    ERROR_PIPE_BUSY,\n    ERROR_NO_DATA,\n    ERROR_PIPE_NOT_CONNECTED,\n    ERROR_MORE_DATA,                                   // =   234\n    ERROR_VC_DISCONNECTED                                 =   240,\n    ERROR_INVALID_EA_NAME                                 =   254,\n    ERROR_EA_LIST_INCONSISTENT,                        // =   255\n    WAIT_TIMEOUT                                          =   258,\n    ERROR_NO_MORE_ITEMS,                               // =   259\n    ERROR_CANNOT_COPY                                     =   266,\n    ERROR_DIRECTORY,                                   // =   267\n    ERROR_EAS_DIDNT_FIT                                   =   275,\n    ERROR_EA_FILE_CORRUPT,\n    ERROR_EA_TABLE_FULL,\n    ERROR_INVALID_EA_HANDLE,                           // =   278\n    ERROR_EAS_NOT_SUPPORTED                               =   282,\n    ERROR_NOT_OWNER                                       =   288,\n    ERROR_TOO_MANY_POSTS                                  =   298,\n    ERROR_PARTIAL_COPY,\n    ERROR_OPLOCK_NOT_GRANTED,\n    ERROR_INVALID_OPLOCK_PROTOCOL,\n    ERROR_DISK_TOO_FRAGMENTED,\n    ERROR_DELETE_PENDING,                              // =   303\n    ERROR_MR_MID_NOT_FOUND                                =   317,\n    ERROR_SCOPE_NOT_FOUND,                             // =   318\n    ERROR_INVALID_ADDRESS                                 =   487,\n    ERROR_ARITHMETIC_OVERFLOW                             =   534,\n    ERROR_PIPE_CONNECTED,\n    ERROR_PIPE_LISTENING,                              // =   536\n    ERROR_EA_ACCESS_DENIED                                =   994,\n    ERROR_OPERATION_ABORTED,\n    ERROR_IO_INCOMPLETE,\n    ERROR_IO_PENDING,\n    ERROR_NOACCESS,\n    ERROR_SWAPERROR,                                   // =   999\n    ERROR_STACK_OVERFLOW                                  =  1001,\n    ERROR_INVALID_MESSAGE,\n    ERROR_CAN_NOT_COMPLETE,\n    ERROR_INVALID_FLAGS,\n    ERROR_UNRECOGNIZED_VOLUME,\n    ERROR_FILE_INVALID,\n    ERROR_FULLSCREEN_MODE,\n    ERROR_NO_TOKEN,\n    ERROR_BADDB,\n    ERROR_BADKEY,\n    ERROR_CANTOPEN,\n    ERROR_CANTREAD,\n    ERROR_CANTWRITE,\n    ERROR_REGISTRY_RECOVERED,\n    ERROR_REGISTRY_CORRUPT,\n    ERROR_REGISTRY_IO_FAILED,\n    ERROR_NOT_REGISTRY_FILE,\n    ERROR_KEY_DELETED,\n    ERROR_NO_LOG_SPACE,\n    ERROR_KEY_HAS_CHILDREN,\n    ERROR_CHILD_MUST_BE_VOLATILE,\n    ERROR_NOTIFY_ENUM_DIR,                             // =  1022\n    ERROR_DEPENDENT_SERVICES_RUNNING                      =  1051,\n    ERROR_INVALID_SERVICE_CONTROL,\n    ERROR_SERVICE_REQUEST_TIMEOUT,\n    ERROR_SERVICE_NO_THREAD,\n    ERROR_SERVICE_DATABASE_LOCKED,\n    ERROR_SERVICE_ALREADY_RUNNING,\n    ERROR_INVALID_SERVICE_ACCOUNT,\n    ERROR_SERVICE_DISABLED,\n    ERROR_CIRCULAR_DEPENDENCY,\n    ERROR_SERVICE_DOES_NOT_EXIST,\n    ERROR_SERVICE_CANNOT_ACCEPT_CTRL,\n    ERROR_SERVICE_NOT_ACTIVE,\n    ERROR_FAILED_SERVICE_CONTROLLER_CONNECT,\n    ERROR_EXCEPTION_IN_SERVICE,\n    ERROR_DATABASE_DOES_NOT_EXIST,\n    ERROR_SERVICE_SPECIFIC_ERROR,\n    ERROR_PROCESS_ABORTED,\n    ERROR_SERVICE_DEPENDENCY_FAIL,\n    ERROR_SERVICE_LOGON_FAILED,\n    ERROR_SERVICE_START_HANG,\n    ERROR_INVALID_SERVICE_LOCK,\n    ERROR_SERVICE_MARKED_FOR_DELETE,\n    ERROR_SERVICE_EXISTS,\n    ERROR_ALREADY_RUNNING_LKG,\n    ERROR_SERVICE_DEPENDENCY_DELETED,\n    ERROR_BOOT_ALREADY_ACCEPTED,\n    ERROR_SERVICE_NEVER_STARTED,\n    ERROR_DUPLICATE_SERVICE_NAME,\n    ERROR_DIFFERENT_SERVICE_ACCOUNT,\n    ERROR_CANNOT_DETECT_DRIVER_FAILURE,\n    ERROR_CANNOT_DETECT_PROCESS_ABORT,\n    ERROR_NO_RECOVERY_PROGRAM,\n    ERROR_SERVICE_NOT_IN_EXE,\n    ERROR_NOT_SAFEBOOT_SERVICE,                        // =  1084\n    ERROR_END_OF_MEDIA                                    =  1100,\n    ERROR_FILEMARK_DETECTED,\n    ERROR_BEGINNING_OF_MEDIA,\n    ERROR_SETMARK_DETECTED,\n    ERROR_NO_DATA_DETECTED,\n    ERROR_PARTITION_FAILURE,\n    ERROR_INVALID_BLOCK_LENGTH,\n    ERROR_DEVICE_NOT_PARTITIONED,\n    ERROR_UNABLE_TO_LOCK_MEDIA,\n    ERROR_UNABLE_TO_UNLOAD_MEDIA,\n    ERROR_MEDIA_CHANGED,\n    ERROR_BUS_RESET,\n    ERROR_NO_MEDIA_IN_DRIVE,\n    ERROR_NO_UNICODE_TRANSLATION,\n    ERROR_DLL_INIT_FAILED,\n    ERROR_SHUTDOWN_IN_PROGRESS,\n    ERROR_NO_SHUTDOWN_IN_PROGRESS,\n    ERROR_IO_DEVICE,\n    ERROR_SERIAL_NO_DEVICE,\n    ERROR_IRQ_BUSY,\n    ERROR_MORE_WRITES,\n    ERROR_COUNTER_TIMEOUT,\n    ERROR_FLOPPY_ID_MARK_NOT_FOUND,\n    ERROR_FLOPPY_WRONG_CYLINDER,\n    ERROR_FLOPPY_UNKNOWN_ERROR,\n    ERROR_FLOPPY_BAD_REGISTERS,\n    ERROR_DISK_RECALIBRATE_FAILED,\n    ERROR_DISK_OPERATION_FAILED,\n    ERROR_DISK_RESET_FAILED,\n    ERROR_EOM_OVERFLOW,\n    ERROR_NOT_ENOUGH_SERVER_MEMORY,\n    ERROR_POSSIBLE_DEADLOCK,\n    ERROR_MAPPED_ALIGNMENT,                            // =  1132\n    ERROR_SET_POWER_STATE_VETOED                          =  1140,\n    ERROR_SET_POWER_STATE_FAILED,\n    ERROR_TOO_MANY_LINKS,                              // =  1142\n    ERROR_OLD_WIN_VERSION                                 =  1150,\n    ERROR_APP_WRONG_OS,\n    ERROR_SINGLE_INSTANCE_APP,\n    ERROR_RMODE_APP,\n    ERROR_INVALID_DLL,\n    ERROR_NO_ASSOCIATION,\n    ERROR_DDE_FAIL,\n    ERROR_DLL_NOT_FOUND,\n    ERROR_NO_MORE_USER_HANDLES,\n    ERROR_MESSAGE_SYNC_ONLY,\n    ERROR_SOURCE_ELEMENT_EMPTY,\n    ERROR_DESTINATION_ELEMENT_FULL,\n    ERROR_ILLEGAL_ELEMENT_ADDRESS,\n    ERROR_MAGAZINE_NOT_PRESENT,\n    ERROR_DEVICE_REINITIALIZATION_NEEDED,\n    ERROR_DEVICE_REQUIRES_CLEANING,\n    ERROR_DEVICE_DOOR_OPEN,\n    ERROR_DEVICE_NOT_CONNECTED,\n    ERROR_NOT_FOUND,\n    ERROR_NO_MATCH,\n    ERROR_SET_NOT_FOUND,\n    ERROR_POINT_NOT_FOUND,\n    ERROR_NO_TRACKING_SERVICE,\n    ERROR_NO_VOLUME_ID,                                // =  1173\n    ERROR_UNABLE_TO_REMOVE_REPLACED                       =  1175,\n    ERROR_UNABLE_TO_MOVE_REPLACEMENT,\n    ERROR_UNABLE_TO_MOVE_REPLACEMENT_2,\n    ERROR_JOURNAL_DELETE_IN_PROGRESS,\n    ERROR_JOURNAL_NOT_ACTIVE,\n    ERROR_POTENTIAL_FILE_FOUND,\n    ERROR_JOURNAL_ENTRY_DELETED,                       // =  1181\n    ERROR_BAD_DEVICE                                      =  1200,\n    ERROR_CONNECTION_UNAVAIL,\n    ERROR_DEVICE_ALREADY_REMEMBERED,\n    ERROR_NO_NET_OR_BAD_PATH,\n    ERROR_BAD_PROVIDER,\n    ERROR_CANNOT_OPEN_PROFILE,\n    ERROR_BAD_PROFILE,\n    ERROR_NOT_CONTAINER,\n    ERROR_EXTENDED_ERROR,\n    ERROR_INVALID_GROUPNAME,\n    ERROR_INVALID_COMPUTERNAME,\n    ERROR_INVALID_EVENTNAME,\n    ERROR_INVALID_DOMAINNAME,\n    ERROR_INVALID_SERVICENAME,\n    ERROR_INVALID_NETNAME,\n    ERROR_INVALID_SHARENAME,\n    ERROR_INVALID_PASSWORDNAME,\n    ERROR_INVALID_MESSAGENAME,\n    ERROR_INVALID_MESSAGEDEST,\n    ERROR_SESSION_CREDENTIAL_CONFLICT,\n    ERROR_REMOTE_SESSION_LIMIT_EXCEEDED,\n    ERROR_DUP_DOMAINNAME,\n    ERROR_NO_NETWORK,\n    ERROR_CANCELLED,\n    ERROR_USER_MAPPED_FILE,\n    ERROR_CONNECTION_REFUSED,\n    ERROR_GRACEFUL_DISCONNECT,\n    ERROR_ADDRESS_ALREADY_ASSOCIATED,\n    ERROR_ADDRESS_NOT_ASSOCIATED,\n    ERROR_CONNECTION_INVALID,\n    ERROR_CONNECTION_ACTIVE,\n    ERROR_NETWORK_UNREACHABLE,\n    ERROR_HOST_UNREACHABLE,\n    ERROR_PROTOCOL_UNREACHABLE,\n    ERROR_PORT_UNREACHABLE,\n    ERROR_REQUEST_ABORTED,\n    ERROR_CONNECTION_ABORTED,\n    ERROR_RETRY,\n    ERROR_CONNECTION_COUNT_LIMIT,\n    ERROR_LOGIN_TIME_RESTRICTION,\n    ERROR_LOGIN_WKSTA_RESTRICTION,\n    ERROR_INCORRECT_ADDRESS,\n    ERROR_ALREADY_REGISTERED,\n    ERROR_SERVICE_NOT_FOUND,\n    ERROR_NOT_AUTHENTICATED,\n    ERROR_NOT_LOGGED_ON,\n    ERROR_CONTINUE,\n    ERROR_ALREADY_INITIALIZED,\n    ERROR_NO_MORE_DEVICES,\n    ERROR_NO_SUCH_SITE,\n    ERROR_DOMAIN_CONTROLLER_EXISTS,\n    ERROR_ONLY_IF_CONNECTED,\n    ERROR_OVERRIDE_NOCHANGES,\n    ERROR_BAD_USER_PROFILE,\n    ERROR_NOT_SUPPORTED_ON_SBS,\n    ERROR_SERVER_SHUTDOWN_IN_PROGRESS,\n    ERROR_HOST_DOWN,\n    ERROR_NON_ACCOUNT_SID,\n    ERROR_NON_DOMAIN_SID,\n    ERROR_APPHELP_BLOCK,\n    ERROR_ACCESS_DISABLED_BY_POLICY,\n    ERROR_REG_NAT_CONSUMPTION,\n    ERROR_CSCSHARE_OFFLINE,\n    ERROR_PKINIT_FAILURE,\n    ERROR_SMARTCARD_SUBSYSTEM_FAILURE,\n    ERROR_DOWNGRADE_DETECTED,\n    SEC_E_SMARTCARD_CERT_REVOKED,\n    SEC_E_ISSUING_CA_UNTRUSTED,\n    SEC_E_REVOCATION_OFFLINE_C,\n    SEC_E_PKINIT_CLIENT_FAILUR,\n    SEC_E_SMARTCARD_CERT_EXPIRED,\n    ERROR_MACHINE_LOCKED,                              // =  1271\n    ERROR_CALLBACK_SUPPLIED_INVALID_DATA                  =  1273,\n    ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED,\n    ERROR_DRIVER_BLOCKED,\n    ERROR_INVALID_IMPORT_OF_NON_DLL,\n    ERROR_ACCESS_DISABLED_WEBBLADE,\n    ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER,\n    ERROR_RECOVERY_FAILURE,\n    ERROR_ALREADY_FIBER,\n    ERROR_ALREADY_THREAD,\n    ERROR_STACK_BUFFER_OVERRUN,\n    ERROR_PARAMETER_QUOTA_EXCEEDED,\n    ERROR_DEBUGGER_INACTIVE,                           // =  1284\n    ERROR_NOT_ALL_ASSIGNED                                =  1300,\n    ERROR_SOME_NOT_MAPPED,\n    ERROR_NO_QUOTAS_FOR_ACCOUNT,\n    ERROR_LOCAL_USER_SESSION_KEY,\n    ERROR_NULL_LM_PASSWORD,\n    ERROR_UNKNOWN_REVISION,\n    ERROR_REVISION_MISMATCH,\n    ERROR_INVALID_OWNER,\n    ERROR_INVALID_PRIMARY_GROUP,\n    ERROR_NO_IMPERSONATION_TOKEN,\n    ERROR_CANT_DISABLE_MANDATORY,\n    ERROR_NO_LOGON_SERVERS,\n    ERROR_NO_SUCH_LOGON_SESSION,\n    ERROR_NO_SUCH_PRIVILEGE,\n    ERROR_PRIVILEGE_NOT_HELD,\n    ERROR_INVALID_ACCOUNT_NAME,\n    ERROR_USER_EXISTS,\n    ERROR_NO_SUCH_USER,\n    ERROR_GROUP_EXISTS,\n    ERROR_NO_SUCH_GROUP,\n    ERROR_MEMBER_IN_GROUP,\n    ERROR_MEMBER_NOT_IN_GROUP,\n    ERROR_LAST_ADMIN,\n    ERROR_WRONG_PASSWORD,\n    ERROR_ILL_FORMED_PASSWORD,\n    ERROR_PASSWORD_RESTRICTION,\n    ERROR_LOGON_FAILURE,\n    ERROR_ACCOUNT_RESTRICTION,\n    ERROR_INVALID_LOGON_HOURS,\n    ERROR_INVALID_WORKSTATION,\n    ERROR_PASSWORD_EXPIRED,\n    ERROR_ACCOUNT_DISABLED,\n    ERROR_NONE_MAPPED,\n    ERROR_TOO_MANY_LUIDS_REQUESTED,\n    ERROR_LUIDS_EXHAUSTED,\n    ERROR_INVALID_SUB_AUTHORITY,\n    ERROR_INVALID_ACL,\n    ERROR_INVALID_SID,\n    ERROR_INVALID_SECURITY_DESCR,                      // =  1338\n    ERROR_BAD_INHERITANCE_ACL                             =  1340,\n    ERROR_SERVER_DISABLED,\n    ERROR_SERVER_NOT_DISABLED,\n    ERROR_INVALID_ID_AUTHORITY,\n    ERROR_ALLOTTED_SPACE_EXCEEDED,\n    ERROR_INVALID_GROUP_ATTRIBUTES,\n    ERROR_BAD_IMPERSONATION_LEVEL,\n    ERROR_CANT_OPEN_ANONYMOUS,\n    ERROR_BAD_VALIDATION_CLASS,\n    ERROR_BAD_TOKEN_TYPE,\n    ERROR_NO_SECURITY_ON_OBJECT,\n    ERROR_CANT_ACCESS_DOMAIN_INFO,\n    ERROR_INVALID_SERVER_STATE,\n    ERROR_INVALID_DOMAIN_STATE,\n    ERROR_INVALID_DOMAIN_ROLE,\n    ERROR_NO_SUCH_DOMAIN,\n    ERROR_DOMAIN_EXISTS,\n    ERROR_DOMAIN_LIMIT_EXCEEDED,\n    ERROR_INTERNAL_DB_CORRUPTION,\n    ERROR_INTERNAL_ERROR,\n    ERROR_GENERIC_NOT_MAPPED,\n    ERROR_BAD_DESCRIPTOR_FORMAT,\n    ERROR_NOT_LOGON_PROCESS,\n    ERROR_LOGON_SESSION_EXISTS,\n    ERROR_NO_SUCH_PACKAGE,\n    ERROR_BAD_LOGON_SESSION_STATE,\n    ERROR_LOGON_SESSION_COLLISION,\n    ERROR_INVALID_LOGON_TYPE,\n    ERROR_CANNOT_IMPERSONATE,\n    ERROR_RXACT_INVALID_STATE,\n    ERROR_RXACT_COMMIT_FAILURE,\n    ERROR_SPECIAL_ACCOUNT,\n    ERROR_SPECIAL_GROUP,\n    ERROR_SPECIAL_USER,\n    ERROR_MEMBERS_PRIMARY_GROUP,\n    ERROR_TOKEN_ALREADY_IN_USE,\n    ERROR_NO_SUCH_ALIAS,\n    ERROR_MEMBER_NOT_IN_ALIAS,\n    ERROR_MEMBER_IN_ALIAS,\n    ERROR_ALIAS_EXISTS,\n    ERROR_LOGON_NOT_GRANTED,\n    ERROR_TOO_MANY_SECRETS,\n    ERROR_SECRET_TOO_LONG,\n    ERROR_INTERNAL_DB_ERROR,\n    ERROR_TOO_MANY_CONTEXT_IDS,\n    ERROR_LOGON_TYPE_NOT_GRANTED,\n    ERROR_NT_CROSS_ENCRYPTION_REQUIRED,\n    ERROR_NO_SUCH_MEMBER,\n    ERROR_INVALID_MEMBER,\n    ERROR_TOO_MANY_SIDS,\n    ERROR_LM_CROSS_ENCRYPTION_REQUIRED,\n    ERROR_NO_INHERITANCE,\n    ERROR_FILE_CORRUPT,\n    ERROR_DISK_CORRUPT,\n    ERROR_NO_USER_SESSION_KEY,\n    ERROR_LICENSE_QUOTA_EXCEEDED,\n    ERROR_WRONG_TARGET_NAME,\n    ERROR_MUTUAL_AUTH_FAILED,\n    ERROR_TIME_SKEW,\n    ERROR_CURRENT_DOMAIN_NOT_ALLOWED,\n    ERROR_INVALID_WINDOW_HANDLE,\n    ERROR_INVALID_MENU_HANDLE,\n    ERROR_INVALID_CURSOR_HANDLE,\n    ERROR_INVALID_ACCEL_HANDLE,\n    ERROR_INVALID_HOOK_HANDLE,\n    ERROR_INVALID_DWP_HANDLE,\n    ERROR_TLW_WITH_WSCHILD,\n    ERROR_CANNOT_FIND_WND_CLASS,\n    ERROR_WINDOW_OF_OTHER_THREAD,\n    ERROR_HOTKEY_ALREADY_REGISTERED,\n    ERROR_CLASS_ALREADY_EXISTS,\n    ERROR_CLASS_DOES_NOT_EXIST,\n    ERROR_CLASS_HAS_WINDOWS,\n    ERROR_INVALID_INDEX,\n    ERROR_INVALID_ICON_HANDLE,\n    ERROR_PRIVATE_DIALOG_INDEX,\n    ERROR_LISTBOX_ID_NOT_FOUND,\n    ERROR_NO_WILDCARD_CHARACTERS,\n    ERROR_CLIPBOARD_NOT_OPEN,\n    ERROR_HOTKEY_NOT_REGISTERED,\n    ERROR_WINDOW_NOT_DIALOG,\n    ERROR_CONTROL_ID_NOT_FOUND,\n    ERROR_INVALID_COMBOBOX_MESSAGE,\n    ERROR_WINDOW_NOT_COMBOBOX,\n    ERROR_INVALID_EDIT_HEIGHT,\n    ERROR_DC_NOT_FOUND,\n    ERROR_INVALID_HOOK_FILTER,\n    ERROR_INVALID_FILTER_PROC,\n    ERROR_HOOK_NEEDS_HMOD,\n    ERROR_GLOBAL_ONLY_HOOK,\n    ERROR_JOURNAL_HOOK_SET,\n    ERROR_HOOK_NOT_INSTALLED,\n    ERROR_INVALID_LB_MESSAGE,\n    ERROR_SETCOUNT_ON_BAD_LB,\n    ERROR_LB_WITHOUT_TABSTOPS,\n    ERROR_DESTROY_OBJECT_OF_OTHER_THREAD,\n    ERROR_CHILD_WINDOW_MENU,\n    ERROR_NO_SYSTEM_MENU,\n    ERROR_INVALID_MSGBOX_STYLE,\n    ERROR_INVALID_SPI_VALUE,\n    ERROR_SCREEN_ALREADY_LOCKED,\n    ERROR_HWNDS_HAVE_DIFF_PARENT,\n    ERROR_NOT_CHILD_WINDOW,\n    ERROR_INVALID_GW_COMMAND,\n    ERROR_INVALID_THREAD_ID,\n    ERROR_NON_MDICHILD_WINDOW,\n    ERROR_POPUP_ALREADY_ACTIVE,\n    ERROR_NO_SCROLLBARS,\n    ERROR_INVALID_SCROLLBAR_RANGE,\n    ERROR_INVALID_SHOWWIN_COMMAND,\n    ERROR_NO_SYSTEM_RESOURCES,\n    ERROR_NONPAGED_SYSTEM_RESOURCES,\n    ERROR_PAGED_SYSTEM_RESOURCES,\n    ERROR_WORKING_SET_QUOTA,\n    ERROR_PAGEFILE_QUOTA,\n    ERROR_COMMITMENT_LIMIT,\n    ERROR_MENU_ITEM_NOT_FOUND,\n    ERROR_INVALID_KEYBOARD_HANDLE,\n    ERROR_HOOK_TYPE_NOT_ALLOWED,\n    ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION,\n    ERROR_TIMEOUT,\n    ERROR_INVALID_MONITOR_HANDLE,                      // =  1461\n    ERROR_EVENTLOG_FILE_CORRUPT                           =  1500,\n    ERROR_EVENTLOG_CANT_START,\n    ERROR_LOG_FILE_FULL,\n    ERROR_EVENTLOG_FILE_CHANGED,                       // =  1503\n    ERROR_INSTALL_SERVICE_FAILURE                         =  1601,\n    ERROR_INSTALL_USEREXIT,\n    ERROR_INSTALL_FAILURE,\n    ERROR_INSTALL_SUSPEND,\n    ERROR_UNKNOWN_PRODUCT,\n    ERROR_UNKNOWN_FEATURE,\n    ERROR_UNKNOWN_COMPONENT,\n    ERROR_UNKNOWN_PROPERTY,\n    ERROR_INVALID_HANDLE_STATE,\n    ERROR_BAD_CONFIGURATION,\n    ERROR_INDEX_ABSENT,\n    ERROR_INSTALL_SOURCE_ABSENT,\n    ERROR_INSTALL_PACKAGE_VERSION,\n    ERROR_PRODUCT_UNINSTALLED,\n    ERROR_BAD_QUERY_SYNTAX,\n    ERROR_INVALID_FIELD,\n    ERROR_DEVICE_REMOVED,\n    ERROR_INSTALL_ALREADY_RUNNING,\n    ERROR_INSTALL_PACKAGE_OPEN_FAILED,\n    ERROR_INSTALL_PACKAGE_INVALID,\n    ERROR_INSTALL_UI_FAILURE,\n    ERROR_INSTALL_LOG_FAILURE,\n    ERROR_INSTALL_LANGUAGE_UNSUPPORTED,\n    ERROR_INSTALL_TRANSFORM_FAILURE,\n    ERROR_INSTALL_PACKAGE_REJECTED,\n    ERROR_FUNCTION_NOT_CALLED,\n    ERROR_FUNCTION_FAILED,\n    ERROR_INVALID_TABLE,\n    ERROR_DATATYPE_MISMATCH,\n    ERROR_UNSUPPORTED_TYPE,\n    ERROR_CREATE_FAILED,\n    ERROR_INSTALL_TEMP_UNWRITABLE,\n    ERROR_INSTALL_PLATFORM_UNSUPPORTED,\n    ERROR_INSTALL_NOTUSED,\n    ERROR_PATCH_PACKAGE_OPEN_FAILED,\n    ERROR_PATCH_PACKAGE_INVALID,\n    ERROR_PATCH_PACKAGE_UNSUPPORTED,\n    ERROR_PRODUCT_VERSION,\n    ERROR_INVALID_COMMAND_LINE,\n    ERROR_INSTALL_REMOTE_DISALLOWED,\n    ERROR_SUCCESS_REBOOT_INITIATED,\n    ERROR_PATCH_TARGET_NOT_FOUND,\n    ERROR_PATCH_PACKAGE_REJECTED,\n    ERROR_INSTALL_TRANSFORM_REJECTED,\n    ERROR_INSTALL_REMOTE_PROHIBITED,                   // =  1645\n    RPC_S_INVALID_STRING_BINDING                          =  1700,\n    RPC_S_WRONG_KIND_OF_BINDING,\n    RPC_S_INVALID_BINDING,\n    RPC_S_PROTSEQ_NOT_SUPPORTED,\n    RPC_S_INVALID_RPC_PROTSEQ,\n    RPC_S_INVALID_STRING_UUID,\n    RPC_S_INVALID_ENDPOINT_FORMAT,\n    RPC_S_INVALID_NET_ADDR,\n    RPC_S_NO_ENDPOINT_FOUND,\n    RPC_S_INVALID_TIMEOUT,\n    RPC_S_OBJECT_NOT_FOUND,\n    RPC_S_ALREADY_REGISTERED,\n    RPC_S_TYPE_ALREADY_REGISTERED,\n    RPC_S_ALREADY_LISTENING,\n    RPC_S_NO_PROTSEQS_REGISTERED,\n    RPC_S_NOT_LISTENING,\n    RPC_S_UNKNOWN_MGR_TYPE,\n    RPC_S_UNKNOWN_IF,\n    RPC_S_NO_BINDINGS,\n    RPC_S_NO_PROTSEQS,\n    RPC_S_CANT_CREATE_ENDPOINT,\n    RPC_S_OUT_OF_RESOURCES,\n    RPC_S_SERVER_UNAVAILABLE,\n    RPC_S_SERVER_TOO_BUSY,\n    RPC_S_INVALID_NETWORK_OPTIONS,\n    RPC_S_NO_CALL_ACTIVE,\n    RPC_S_CALL_FAILED,\n    RPC_S_CALL_FAILED_DNE,\n    RPC_S_PROTOCOL_ERROR,                              // =  1728\n    RPC_S_UNSUPPORTED_TRANS_SYN                           =  1730,\n    RPC_S_UNSUPPORTED_TYPE                                =  1732,\n    RPC_S_INVALID_TAG,\n    RPC_S_INVALID_BOUND,\n    RPC_S_NO_ENTRY_NAME,\n    RPC_S_INVALID_NAME_SYNTAX,\n    RPC_S_UNSUPPORTED_NAME_SYNTAX,                     // =  1737\n    RPC_S_UUID_NO_ADDRESS                                 =  1739,\n    RPC_S_DUPLICATE_ENDPOINT,\n    RPC_S_UNKNOWN_AUTHN_TYPE,\n    RPC_S_MAX_CALLS_TOO_SMALL,\n    RPC_S_STRING_TOO_LONG,\n    RPC_S_PROTSEQ_NOT_FOUND,\n    RPC_S_PROCNUM_OUT_OF_RANGE,\n    RPC_S_BINDING_HAS_NO_AUTH,\n    RPC_S_UNKNOWN_AUTHN_SERVICE,\n    RPC_S_UNKNOWN_AUTHN_LEVEL,\n    RPC_S_INVALID_AUTH_IDENTITY,\n    RPC_S_UNKNOWN_AUTHZ_SERVICE,\n    EPT_S_INVALID_ENTRY,\n    EPT_S_CANT_PERFORM_OP,\n    EPT_S_NOT_REGISTERED,\n    RPC_S_NOTHING_TO_EXPORT,\n    RPC_S_INCOMPLETE_NAME,\n    RPC_S_INVALID_VERS_OPTION,\n    RPC_S_NO_MORE_MEMBERS,\n    RPC_S_NOT_ALL_OBJS_UNEXPORTED,\n    RPC_S_INTERFACE_NOT_FOUND,\n    RPC_S_ENTRY_ALREADY_EXISTS,\n    RPC_S_ENTRY_NOT_FOUND,\n    RPC_S_NAME_SERVICE_UNAVAILABLE,\n    RPC_S_INVALID_NAF_ID,\n    RPC_S_CANNOT_SUPPORT,\n    RPC_S_NO_CONTEXT_AVAILABLE,\n    RPC_S_INTERNAL_ERROR,\n    RPC_S_ZERO_DIVIDE,\n    RPC_S_ADDRESS_ERROR,\n    RPC_S_FP_DIV_ZERO,\n    RPC_S_FP_UNDERFLOW,\n    RPC_S_FP_OVERFLOW,\n    RPC_X_NO_MORE_ENTRIES,\n    RPC_X_SS_CHAR_TRANS_OPEN_FAIL,\n    RPC_X_SS_CHAR_TRANS_SHORT_FILE,\n    RPC_X_SS_IN_NULL_CONTEXT,                          // =  1775\n    RPC_X_SS_CONTEXT_DAMAGED                              =  1777,\n    RPC_X_SS_HANDLES_MISMATCH,\n    RPC_X_SS_CANNOT_GET_CALL_HANDLE,\n    RPC_X_NULL_REF_POINTER,\n    RPC_X_ENUM_VALUE_OUT_OF_RANGE,\n    RPC_X_BYTE_COUNT_TOO_SMALL,\n    RPC_X_BAD_STUB_DATA,\n    ERROR_INVALID_USER_BUFFER,\n    ERROR_UNRECOGNIZED_MEDIA,\n    ERROR_NO_TRUST_LSA_SECRET,\n    ERROR_NO_TRUST_SAM_ACCOUNT,\n    ERROR_TRUSTED_DOMAIN_FAILURE,\n    ERROR_TRUSTED_RELATIONSHIP_FAILURE,\n    ERROR_TRUST_FAILURE,\n    RPC_S_CALL_IN_PROGRESS,\n    ERROR_NETLOGON_NOT_STARTED,\n    ERROR_ACCOUNT_EXPIRED,\n    ERROR_REDIRECTOR_HAS_OPEN_HANDLES,\n    ERROR_PRINTER_DRIVER_ALREADY_INSTALLED,\n    ERROR_UNKNOWN_PORT,\n    ERROR_UNKNOWN_PRINTER_DRIVER,\n    ERROR_UNKNOWN_PRINTPROCESSOR,\n    ERROR_INVALID_SEPARATOR_FILE,\n    ERROR_INVALID_PRIORITY,\n    ERROR_INVALID_PRINTER_NAME,\n    ERROR_PRINTER_ALREADY_EXISTS,\n    ERROR_INVALID_PRINTER_COMMAND,\n    ERROR_INVALID_DATATYPE,\n    ERROR_INVALID_ENVIRONMENT,\n    RPC_S_NO_MORE_BINDINGS,\n    ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT,\n    ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT,\n    ERROR_NOLOGON_SERVER_TRUST_ACCOUNT,\n    ERROR_DOMAIN_TRUST_INCONSISTENT,\n    ERROR_SERVER_HAS_OPEN_HANDLES,\n    ERROR_RESOURCE_DATA_NOT_FOUND,\n    ERROR_RESOURCE_TYPE_NOT_FOUND,\n    ERROR_RESOURCE_NAME_NOT_FOUND,\n    ERROR_RESOURCE_LANG_NOT_FOUND,\n    ERROR_NOT_ENOUGH_QUOTA,\n    RPC_S_NO_INTERFACES,\n    RPC_S_CALL_CANCELLED,\n    RPC_S_BINDING_INCOMPLETE,\n    RPC_S_COMM_FAILURE,\n    RPC_S_UNSUPPORTED_AUTHN_LEVEL,\n    RPC_S_NO_PRINC_NAME,\n    RPC_S_NOT_RPC_ERROR,\n    RPC_S_UUID_LOCAL_ONLY,\n    RPC_S_SEC_PKG_ERROR,\n    RPC_S_NOT_CANCELLED,\n    RPC_X_INVALID_ES_ACTION,\n    RPC_X_WRONG_ES_VERSION,\n    RPC_X_WRONG_STUB_VERSION,\n    RPC_X_INVALID_PIPE_OBJECT,\n    RPC_X_WRONG_PIPE_ORDER,\n    RPC_X_WRONG_PIPE_VERSION,                          // =  1832\n    RPC_S_GROUP_MEMBER_NOT_FOUND                          =  1898,\n    EPT_S_CANT_CREATE,\n    RPC_S_INVALID_OBJECT,\n    ERROR_INVALID_TIME,\n    ERROR_INVALID_FORM_NAME,\n    ERROR_INVALID_FORM_SIZE,\n    ERROR_ALREADY_WAITING,\n    ERROR_PRINTER_DELETED,\n    ERROR_INVALID_PRINTER_STATE,\n    ERROR_PASSWORD_MUST_CHANGE,\n    ERROR_DOMAIN_CONTROLLER_NOT_FOUND,\n    ERROR_ACCOUNT_LOCKED_OUT,\n    OR_INVALID_OXID,\n    OR_INVALID_OID,\n    OR_INVALID_SET,\n    RPC_S_SEND_INCOMPLETE,\n    RPC_S_INVALID_ASYNC_HANDLE,\n    RPC_S_INVALID_ASYNC_CALL,\n    RPC_X_PIPE_CLOSED,\n    RPC_X_PIPE_DISCIPLINE_ERROR,\n    RPC_X_PIPE_EMPTY,\n    ERROR_NO_SITENAME,\n    ERROR_CANT_ACCESS_FILE,\n    ERROR_CANT_RESOLVE_FILENAME,\n    RPC_S_ENTRY_TYPE_MISMATCH,\n    RPC_S_NOT_ALL_OBJS_EXPORTED,\n    RPC_S_INTERFACE_NOT_EXPORTED,\n    RPC_S_PROFILE_NOT_ADDED,\n    RPC_S_PRF_ELT_NOT_ADDED,\n    RPC_S_PRF_ELT_NOT_REMOVED,\n    RPC_S_GRP_ELT_NOT_ADDED,\n    RPC_S_GRP_ELT_NOT_REMOVED,\n    ERROR_KM_DRIVER_BLOCKED,\n    ERROR_CONTEXT_EXPIRED,\n    ERROR_PER_USER_TRUST_QUOTA_EXCEEDED,\n    ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED,\n    ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED,            // =  1934\n    ERROR_INVALID_PIXEL_FORMAT                            =  2000,\n    ERROR_BAD_DRIVER,\n    ERROR_INVALID_WINDOW_STYLE,\n    ERROR_METAFILE_NOT_SUPPORTED,\n    ERROR_TRANSFORM_NOT_SUPPORTED,\n    ERROR_CLIPPING_NOT_SUPPORTED,                      // =  2005\n    ERROR_INVALID_CMM                                     =  2010,\n    ERROR_INVALID_PROFILE,\n    ERROR_TAG_NOT_FOUND,\n    ERROR_TAG_NOT_PRESENT,\n    ERROR_DUPLICATE_TAG,\n    ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE,\n    ERROR_PROFILE_NOT_FOUND,\n    ERROR_INVALID_COLORSPACE,\n    ERROR_ICM_NOT_ENABLED,\n    ERROR_DELETING_ICM_XFORM,\n    ERROR_INVALID_TRANSFORM,\n    ERROR_COLORSPACE_MISMATCH,\n    ERROR_INVALID_COLORINDEX,                          // =  2022\n    ERROR_CONNECTED_OTHER_PASSWORD                        =  2108,\n    ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT,            // =  2109\n    ERROR_BAD_USERNAME                                    =  2202,\n    ERROR_NOT_CONNECTED                                   =  2250,\n    ERROR_OPEN_FILES                                      =  2401,\n    ERROR_ACTIVE_CONNECTIONS,                          // =  2402\n    ERROR_DEVICE_IN_USE                                   =  2404,\n    ERROR_UNKNOWN_PRINT_MONITOR                           =  3000,\n    ERROR_PRINTER_DRIVER_IN_USE,\n    ERROR_SPOOL_FILE_NOT_FOUND,\n    ERROR_SPL_NO_STARTDOC,\n    ERROR_SPL_NO_ADDJOB,\n    ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED,\n    ERROR_PRINT_MONITOR_ALREADY_INSTALLED,\n    ERROR_INVALID_PRINT_MONITOR,\n    ERROR_PRINT_MONITOR_IN_USE,\n    ERROR_PRINTER_HAS_JOBS_QUEUED,\n    ERROR_SUCCESS_REBOOT_REQUIRED,\n    ERROR_SUCCESS_RESTART_REQUIRED,\n    ERROR_PRINTER_NOT_FOUND,\n    ERROR_PRINTER_DRIVER_WARNED,\n    ERROR_PRINTER_DRIVER_BLOCKED,                      // =  3014\n    ERROR_WINS_INTERNAL                                   =  4000,\n    ERROR_CAN_NOT_DEL_LOCAL_WINS,\n    ERROR_STATIC_INIT,\n    ERROR_INC_BACKUP,\n    ERROR_FULL_BACKUP,\n    ERROR_REC_NON_EXISTENT,\n    ERROR_RPL_NOT_ALLOWED,                             // =  4006\n    ERROR_DHCP_ADDRESS_CONFLICT                           =  4100,\n    ERROR_WMI_GUID_NOT_FOUND                              =  4200,\n    ERROR_WMI_INSTANCE_NOT_FOUND,\n    ERROR_WMI_ITEMID_NOT_FOUND,\n    ERROR_WMI_TRY_AGAIN,\n    ERROR_WMI_DP_NOT_FOUND,\n    ERROR_WMI_UNRESOLVED_INSTANCE_REF,\n    ERROR_WMI_ALREADY_ENABLED,\n    ERROR_WMI_GUID_DISCONNECTED,\n    ERROR_WMI_SERVER_UNAVAILABLE,\n    ERROR_WMI_DP_FAILED,\n    ERROR_WMI_INVALID_MOF,\n    ERROR_WMI_INVALID_REGINFO,\n    ERROR_WMI_ALREADY_DISABLED,\n    ERROR_WMI_READ_ONLY,\n    ERROR_WMI_SET_FAILURE,                             // =  4214\n    ERROR_INVALID_MEDIA                                   =  4300,\n    ERROR_INVALID_LIBRARY,\n    ERROR_INVALID_MEDIA_POOL,\n    ERROR_DRIVE_MEDIA_MISMATCH,\n    ERROR_MEDIA_OFFLINE,\n    ERROR_LIBRARY_OFFLINE,\n    ERROR_EMPTY,\n    ERROR_NOT_EMPTY,\n    ERROR_MEDIA_UNAVAILABLE,\n    ERROR_RESOURCE_DISABLED,\n    ERROR_INVALID_CLEANER,\n    ERROR_UNABLE_TO_CLEAN,\n    ERROR_OBJECT_NOT_FOUND,\n    ERROR_DATABASE_FAILURE,\n    ERROR_DATABASE_FULL,\n    ERROR_MEDIA_INCOMPATIBLE,\n    ERROR_RESOURCE_NOT_PRESENT,\n    ERROR_INVALID_OPERATION,\n    ERROR_MEDIA_NOT_AVAILABLE,\n    ERROR_DEVICE_NOT_AVAILABLE,\n    ERROR_REQUEST_REFUSED,\n    ERROR_INVALID_DRIVE_OBJECT,\n    ERROR_LIBRARY_FULL,\n    ERROR_MEDIUM_NOT_ACCESSIBLE,\n    ERROR_UNABLE_TO_LOAD_MEDIUM,\n    ERROR_UNABLE_TO_INVENTORY_DRIVE,\n    ERROR_UNABLE_TO_INVENTORY_SLOT,\n    ERROR_UNABLE_TO_INVENTORY_TRANSPORT,\n    ERROR_TRANSPORT_FULL,\n    ERROR_CONTROLLING_IEPORT,\n    ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA,\n    ERROR_CLEANER_SLOT_SET,\n    ERROR_CLEANER_SLOT_NOT_SET,\n    ERROR_CLEANER_CARTRIDGE_SPENT,\n    ERROR_UNEXPECTED_OMID,\n    ERROR_CANT_DELETE_LAST_ITEM,\n    ERROR_MESSAGE_EXCEEDS_MAX_SIZE,\n    ERROR_VOLUME_CONTAINS_SYS_FILES,\n    ERROR_INDIGENOUS_TYPE,\n    ERROR_NO_SUPPORTING_DRIVES,\n    ERROR_CLEANER_CARTRIDGE_INSTALLED,                 // =  4340\n    ERROR_FILE_OFFLINE                                    =  4350,\n    ERROR_REMOTE_STORAGE_NOT_ACTIVE,\n    ERROR_REMOTE_STORAGE_MEDIA_ERROR,                  // =  4352\n    ERROR_NOT_A_REPARSE_POINT                             =  4390,\n    ERROR_REPARSE_ATTRIBUTE_CONFLICT,\n    ERROR_INVALID_REPARSE_DATA,\n    ERROR_REPARSE_TAG_INVALID,\n    ERROR_REPARSE_TAG_MISMATCH,                        // =  4394\n    ERROR_VOLUME_NOT_SIS_ENABLED                          =  4500,\n    ERROR_DEPENDENT_RESOURCE_EXISTS                       =  5001,\n    ERROR_DEPENDENCY_NOT_FOUND,\n    ERROR_DEPENDENCY_ALREADY_EXISTS,\n    ERROR_RESOURCE_NOT_ONLINE,\n    ERROR_HOST_NODE_NOT_AVAILABLE,\n    ERROR_RESOURCE_NOT_AVAILABLE,\n    ERROR_RESOURCE_NOT_FOUND,\n    ERROR_SHUTDOWN_CLUSTER,\n    ERROR_CANT_EVICT_ACTIVE_NODE,\n    ERROR_OBJECT_ALREADY_EXISTS,\n    ERROR_OBJECT_IN_LIST,\n    ERROR_GROUP_NOT_AVAILABLE,\n    ERROR_GROUP_NOT_FOUND,\n    ERROR_GROUP_NOT_ONLINE,\n    ERROR_HOST_NODE_NOT_RESOURCE_OWNER,\n    ERROR_HOST_NODE_NOT_GROUP_OWNER,\n    ERROR_RESMON_CREATE_FAILED,\n    ERROR_RESMON_ONLINE_FAILED,\n    ERROR_RESOURCE_ONLINE,\n    ERROR_QUORUM_RESOURCE,\n    ERROR_NOT_QUORUM_CAPABLE,\n    ERROR_CLUSTER_SHUTTING_DOWN,\n    ERROR_INVALID_STATE,\n    ERROR_RESOURCE_PROPERTIES_STORED,\n    ERROR_NOT_QUORUM_CLASS,\n    ERROR_CORE_RESOURCE,\n    ERROR_QUORUM_RESOURCE_ONLINE_FAILED,\n    ERROR_QUORUMLOG_OPEN_FAILED,\n    ERROR_CLUSTERLOG_CORRUPT,\n    ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE,\n    ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE,\n    ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND,\n    ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE,\n    ERROR_QUORUM_OWNER_ALIVE,\n    ERROR_NETWORK_NOT_AVAILABLE,\n    ERROR_NODE_NOT_AVAILABLE,\n    ERROR_ALL_NODES_NOT_AVAILABLE,\n    ERROR_RESOURCE_FAILED,\n    ERROR_CLUSTER_INVALID_NODE,\n    ERROR_CLUSTER_NODE_EXISTS,\n    ERROR_CLUSTER_JOIN_IN_PROGRESS,\n    ERROR_CLUSTER_NODE_NOT_FOUND,\n    ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND,\n    ERROR_CLUSTER_NETWORK_EXISTS,\n    ERROR_CLUSTER_NETWORK_NOT_FOUND,\n    ERROR_CLUSTER_NETINTERFACE_EXISTS,\n    ERROR_CLUSTER_NETINTERFACE_NOT_FOUND,\n    ERROR_CLUSTER_INVALID_REQUEST,\n    ERROR_CLUSTER_INVALID_NETWORK_PROVIDER,\n    ERROR_CLUSTER_NODE_DOWN,\n    ERROR_CLUSTER_NODE_UNREACHABLE,\n    ERROR_CLUSTER_NODE_NOT_MEMBER,\n    ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS,\n    ERROR_CLUSTER_INVALID_NETWORK,                     // =  5054\n    ERROR_CLUSTER_NODE_UP                                 =  5056,\n    ERROR_CLUSTER_IPADDR_IN_USE,\n    ERROR_CLUSTER_NODE_NOT_PAUSED,\n    ERROR_CLUSTER_NO_SECURITY_CONTEXT,\n    ERROR_CLUSTER_NETWORK_NOT_INTERNAL,\n    ERROR_CLUSTER_NODE_ALREADY_UP,\n    ERROR_CLUSTER_NODE_ALREADY_DOWN,\n    ERROR_CLUSTER_NETWORK_ALREADY_ONLINE,\n    ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE,\n    ERROR_CLUSTER_NODE_ALREADY_MEMBER,\n    ERROR_CLUSTER_LAST_INTERNAL_NETWORK,\n    ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS,\n    ERROR_INVALID_OPERATION_ON_QUORUM,\n    ERROR_DEPENDENCY_NOT_ALLOWED,\n    ERROR_CLUSTER_NODE_PAUSED,\n    ERROR_NODE_CANT_HOST_RESOURCE,\n    ERROR_CLUSTER_NODE_NOT_READY,\n    ERROR_CLUSTER_NODE_SHUTTING_DOWN,\n    ERROR_CLUSTER_JOIN_ABORTED,\n    ERROR_CLUSTER_INCOMPATIBLE_VERSIONS,\n    ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED,\n    ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED,\n    ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND,\n    ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED,\n    ERROR_CLUSTER_RESNAME_NOT_FOUND,\n    ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED,\n    ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST,\n    ERROR_CLUSTER_DATABASE_SEQMISMATCH,\n    ERROR_RESMON_INVALID_STATE,\n    ERROR_CLUSTER_GUM_NOT_LOCKER,\n    ERROR_QUORUM_DISK_NOT_FOUND,\n    ERROR_DATABASE_BACKUP_CORRUPT,\n    ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT,\n    ERROR_RESOURCE_PROPERTY_UNCHANGEABLE,              // =  5089\n    ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE                =  5890,\n    ERROR_CLUSTER_QUORUMLOG_NOT_FOUND,\n    ERROR_CLUSTER_MEMBERSHIP_HALT,\n    ERROR_CLUSTER_INSTANCE_ID_MISMATCH,\n    ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP,\n    ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH,\n    ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP,\n    ERROR_CLUSTER_PARAMETER_MISMATCH,\n    ERROR_NODE_CANNOT_BE_CLUSTERED,\n    ERROR_CLUSTER_WRONG_OS_VERSION,\n    ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME,\n    ERROR_CLUSCFG_ALREADY_COMMITTED,\n    ERROR_CLUSCFG_ROLLBACK_FAILED,\n    ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT,\n    ERROR_CLUSTER_OLD_VERSION,\n    ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME,       // =  5905\n    ERROR_ENCRYPTION_FAILED                               =  6000,\n    ERROR_DECRYPTION_FAILED,\n    ERROR_FILE_ENCRYPTED,\n    ERROR_NO_RECOVERY_POLICY,\n    ERROR_NO_EFS,\n    ERROR_WRONG_EFS,\n    ERROR_NO_USER_KEYS,\n    ERROR_FILE_NOT_ENCRYPTED,\n    ERROR_NOT_EXPORT_FORMAT,\n    ERROR_FILE_READ_ONLY,\n    ERROR_DIR_EFS_DISALLOWED,\n    ERROR_EFS_SERVER_NOT_TRUSTED,\n    ERROR_BAD_RECOVERY_POLICY,\n    ERROR_EFS_ALG_BLOB_TOO_BIG,\n    ERROR_VOLUME_NOT_SUPPORT_EFS,\n    ERROR_EFS_DISABLED,\n    ERROR_EFS_VERSION_NOT_SUPPORT,                     // =  6016\n    ERROR_NO_BROWSER_SERVERS_FOUND                        =  6118,\n    SCHED_E_SERVICE_NOT_LOCALSYSTEM                       =  6200,\n\n    ERROR_CTX_WINSTATION_NAME_INVALID                     =  7001,\n    ERROR_CTX_INVALID_PD,\n    ERROR_CTX_PD_NOT_FOUND,\n    ERROR_CTX_WD_NOT_FOUND,\n    ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY,\n    ERROR_CTX_SERVICE_NAME_COLLISION,\n    ERROR_CTX_CLOSE_PENDING,\n    ERROR_CTX_NO_OUTBUF,\n    ERROR_CTX_MODEM_INF_NOT_FOUND,\n    ERROR_CTX_INVALID_MODEMNAME,\n    ERROR_CTX_MODEM_RESPONSE_ERROR,\n    ERROR_CTX_MODEM_RESPONSE_TIMEOUT,\n    ERROR_CTX_MODEM_RESPONSE_NO_CARRIER,\n    ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE,\n    ERROR_CTX_MODEM_RESPONSE_BUSY,\n    ERROR_CTX_MODEM_RESPONSE_VOICE,\n    ERROR_CTX_TD_ERROR,                                // =  7017\n    ERROR_CTX_WINSTATION_NOT_FOUND                        =  7022,\n    ERROR_CTX_WINSTATION_ALREADY_EXISTS,\n    ERROR_CTX_WINSTATION_BUSY,\n    ERROR_CTX_BAD_VIDEO_MODE,                          // =  7025\n    ERROR_CTX_GRAPHICS_INVALID                            =  7035,\n    ERROR_CTX_LOGON_DISABLED                              =  7037,\n    ERROR_CTX_NOT_CONSOLE,                             // =  7038\n    ERROR_CTX_CLIENT_QUERY_TIMEOUT                        =  7040,\n    ERROR_CTX_CONSOLE_DISCONNECT,\n    ERROR_CTX_CONSOLE_CONNECT,                         // =  7042\n    ERROR_CTX_SHADOW_DENIED                               =  7044,\n    ERROR_CTX_WINSTATION_ACCESS_DENIED,                // =  7045\n    ERROR_CTX_INVALID_WD                                  =  7049,\n    ERROR_CTX_SHADOW_INVALID,\n    ERROR_CTX_SHADOW_DISABLED,\n    ERROR_CTX_CLIENT_LICENSE_IN_USE,\n    ERROR_CTX_CLIENT_LICENSE_NOT_SET,\n    ERROR_CTX_LICENSE_NOT_AVAILABLE,\n    ERROR_CTX_LICENSE_CLIENT_INVALID,\n    ERROR_CTX_LICENSE_EXPIRED,\n    ERROR_CTX_SHADOW_NOT_RUNNING,\n    ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE,\n    ERROR_ACTIVATION_COUNT_EXCEEDED,                   // =  7059\n\n    FRS_ERR_INVALID_API_SEQUENCE                          =  8001,\n    FRS_ERR_STARTING_SERVICE,\n    FRS_ERR_STOPPING_SERVICE,\n    FRS_ERR_INTERNAL_API,\n    FRS_ERR_INTERNAL,\n    FRS_ERR_SERVICE_COMM,\n    FRS_ERR_INSUFFICIENT_PRIV,\n    FRS_ERR_AUTHENTICATION,\n    FRS_ERR_PARENT_INSUFFICIENT_PRIV,\n    FRS_ERR_PARENT_AUTHENTICATION,\n    FRS_ERR_CHILD_TO_PARENT_COMM,\n    FRS_ERR_PARENT_TO_CHILD_COMM,\n    FRS_ERR_SYSVOL_POPULATE,\n    FRS_ERR_SYSVOL_POPULATE_TIMEOUT,\n    FRS_ERR_SYSVOL_IS_BUSY,\n    FRS_ERR_SYSVOL_DEMOTE,\n    FRS_ERR_INVALID_SERVICE_PARAMETER,                 // =  8017\n    ERROR_DS_NOT_INSTALLED                                =  8200,\n    ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY,\n    ERROR_DS_NO_ATTRIBUTE_OR_VALUE,\n    ERROR_DS_INVALID_ATTRIBUTE_SYNTAX,\n    ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED,\n    ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS,\n    ERROR_DS_BUSY,\n    ERROR_DS_UNAVAILABLE,\n    ERROR_DS_NO_RIDS_ALLOCATED,\n    ERROR_DS_NO_MORE_RIDS,\n    ERROR_DS_INCORRECT_ROLE_OWNER,\n    ERROR_DS_RIDMGR_INIT_ERROR,\n    ERROR_DS_OBJ_CLASS_VIOLATION,\n    ERROR_DS_CANT_ON_NON_LEAF,\n    ERROR_DS_CANT_ON_RDN,\n    ERROR_DS_CANT_MOD_OBJ_CLASS,\n    ERROR_DS_CROSS_DOM_MOVE_ERROR,\n    ERROR_DS_GC_NOT_AVAILABLE,\n    ERROR_SHARED_POLICY,\n    ERROR_POLICY_OBJECT_NOT_FOUND,\n    ERROR_POLICY_ONLY_IN_DS,\n    ERROR_PROMOTION_ACTIVE,\n    ERROR_NO_PROMOTION_ACTIVE,                         // =  8222\n    ERROR_DS_OPERATIONS_ERROR                             =  8224,\n    ERROR_DS_PROTOCOL_ERROR,\n    ERROR_DS_TIMELIMIT_EXCEEDED,\n    ERROR_DS_SIZELIMIT_EXCEEDED,\n    ERROR_DS_ADMIN_LIMIT_EXCEEDED,\n    ERROR_DS_COMPARE_FALSE,\n    ERROR_DS_COMPARE_TRUE,\n    ERROR_DS_AUTH_METHOD_NOT_SUPPORTED,\n    ERROR_DS_STRONG_AUTH_REQUIRED,\n    ERROR_DS_INAPPROPRIATE_AUTH,\n    ERROR_DS_AUTH_UNKNOWN,\n    ERROR_DS_REFERRAL,\n    ERROR_DS_UNAVAILABLE_CRIT_EXTENSION,\n    ERROR_DS_CONFIDENTIALITY_REQUIRED,\n    ERROR_DS_INAPPROPRIATE_MATCHING,\n    ERROR_DS_CONSTRAINT_VIOLATION,\n    ERROR_DS_NO_SUCH_OBJECT,\n    ERROR_DS_ALIAS_PROBLEM,\n    ERROR_DS_INVALID_DN_SYNTAX,\n    ERROR_DS_IS_LEAF,\n    ERROR_DS_ALIAS_DEREF_PROBLEM,\n    ERROR_DS_UNWILLING_TO_PERFORM,\n    ERROR_DS_LOOP_DETECT,\n    ERROR_DS_NAMING_VIOLATION,\n    ERROR_DS_OBJECT_RESULTS_TOO_LARGE,\n    ERROR_DS_AFFECTS_MULTIPLE_DSAS,\n    ERROR_DS_SERVER_DOWN,\n    ERROR_DS_LOCAL_ERROR,\n    ERROR_DS_ENCODING_ERROR,\n    ERROR_DS_DECODING_ERROR,\n    ERROR_DS_FILTER_UNKNOWN,\n    ERROR_DS_PARAM_ERROR,\n    ERROR_DS_NOT_SUPPORTED,\n    ERROR_DS_NO_RESULTS_RETURNED,\n    ERROR_DS_CONTROL_NOT_FOUND,\n    ERROR_DS_CLIENT_LOOP,\n    ERROR_DS_REFERRAL_LIMIT_EXCEEDED,\n    ERROR_DS_SORT_CONTROL_MISSING,\n    ERROR_DS_OFFSET_RANGE_ERROR,                       // =  8262\n    ERROR_DS_ROOT_MUST_BE_NC                              =  8301,\n    ERROR_DS_ADD_REPLICA_INHIBITED,\n    ERROR_DS_ATT_NOT_DEF_IN_SCHEMA,\n    ERROR_DS_MAX_OBJ_SIZE_EXCEEDED,\n    ERROR_DS_OBJ_STRING_NAME_EXISTS,\n    ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA,\n    ERROR_DS_RDN_DOESNT_MATCH_SCHEMA,\n    ERROR_DS_NO_REQUESTED_ATTS_FOUND,\n    ERROR_DS_USER_BUFFER_TO_SMALL,\n    ERROR_DS_ATT_IS_NOT_ON_OBJ,\n    ERROR_DS_ILLEGAL_MOD_OPERATION,\n    ERROR_DS_OBJ_TOO_LARGE,\n    ERROR_DS_BAD_INSTANCE_TYPE,\n    ERROR_DS_MASTERDSA_REQUIRED,\n    ERROR_DS_OBJECT_CLASS_REQUIRED,\n    ERROR_DS_MISSING_REQUIRED_ATT,\n    ERROR_DS_ATT_NOT_DEF_FOR_CLASS,\n    ERROR_DS_ATT_ALREADY_EXISTS,                       // =  8318\n    ERROR_DS_CANT_ADD_ATT_VALUES                          =  8320,\n    ERROR_DS_SINGLE_VALUE_CONSTRAINT,\n    ERROR_DS_RANGE_CONSTRAINT,\n    ERROR_DS_ATT_VAL_ALREADY_EXISTS,\n    ERROR_DS_CANT_REM_MISSING_ATT,\n    ERROR_DS_CANT_REM_MISSING_ATT_VAL,\n    ERROR_DS_ROOT_CANT_BE_SUBREF,\n    ERROR_DS_NO_CHAINING,\n    ERROR_DS_NO_CHAINED_EVAL,\n    ERROR_DS_NO_PARENT_OBJECT,\n    ERROR_DS_PARENT_IS_AN_ALIAS,\n    ERROR_DS_CANT_MIX_MASTER_AND_REPS,\n    ERROR_DS_CHILDREN_EXIST,\n    ERROR_DS_OBJ_NOT_FOUND,\n    ERROR_DS_ALIASED_OBJ_MISSING,\n    ERROR_DS_BAD_NAME_SYNTAX,\n    ERROR_DS_ALIAS_POINTS_TO_ALIAS,\n    ERROR_DS_CANT_DEREF_ALIAS,\n    ERROR_DS_OUT_OF_SCOPE,\n    ERROR_DS_OBJECT_BEING_REMOVED,\n    ERROR_DS_CANT_DELETE_DSA_OBJ,\n    ERROR_DS_GENERIC_ERROR,\n    ERROR_DS_DSA_MUST_BE_INT_MASTER,\n    ERROR_DS_CLASS_NOT_DSA,\n    ERROR_DS_INSUFF_ACCESS_RIGHTS,\n    ERROR_DS_ILLEGAL_SUPERIOR,\n    ERROR_DS_ATTRIBUTE_OWNED_BY_SAM,\n    ERROR_DS_NAME_TOO_MANY_PARTS,\n    ERROR_DS_NAME_TOO_LONG,\n    ERROR_DS_NAME_VALUE_TOO_LONG,\n    ERROR_DS_NAME_UNPARSEABLE,\n    ERROR_DS_NAME_TYPE_UNKNOWN,\n    ERROR_DS_NOT_AN_OBJECT,\n    ERROR_DS_SEC_DESC_TOO_SHORT,\n    ERROR_DS_SEC_DESC_INVALID,\n    ERROR_DS_NO_DELETED_NAME,\n    ERROR_DS_SUBREF_MUST_HAVE_PARENT,\n    ERROR_DS_NCNAME_MUST_BE_NC,\n    ERROR_DS_CANT_ADD_SYSTEM_ONLY,\n    ERROR_DS_CLASS_MUST_BE_CONCRETE,\n    ERROR_DS_INVALID_DMD,\n    ERROR_DS_OBJ_GUID_EXISTS,\n    ERROR_DS_NOT_ON_BACKLINK,\n    ERROR_DS_NO_CROSSREF_FOR_NC,\n    ERROR_DS_SHUTTING_DOWN,\n    ERROR_DS_UNKNOWN_OPERATION,\n    ERROR_DS_INVALID_ROLE_OWNER,\n    ERROR_DS_COULDNT_CONTACT_FSMO,\n    ERROR_DS_CROSS_NC_DN_RENAME,\n    ERROR_DS_CANT_MOD_SYSTEM_ONLY,\n    ERROR_DS_REPLICATOR_ONLY,\n    ERROR_DS_OBJ_CLASS_NOT_DEFINED,\n    ERROR_DS_OBJ_CLASS_NOT_SUBCLASS,\n    ERROR_DS_NAME_REFERENCE_INVALID,\n    ERROR_DS_CROSS_REF_EXISTS,\n    ERROR_DS_CANT_DEL_MASTER_CROSSREF,\n    ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD,\n    ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX,\n    ERROR_DS_DUP_RDN,\n    ERROR_DS_DUP_OID,\n    ERROR_DS_DUP_MAPI_ID,\n    ERROR_DS_DUP_SCHEMA_ID_GUID,\n    ERROR_DS_DUP_LDAP_DISPLAY_NAME,\n    ERROR_DS_SEMANTIC_ATT_TEST,\n    ERROR_DS_SYNTAX_MISMATCH,\n    ERROR_DS_EXISTS_IN_MUST_HAVE,\n    ERROR_DS_EXISTS_IN_MAY_HAVE,\n    ERROR_DS_NONEXISTENT_MAY_HAVE,\n    ERROR_DS_NONEXISTENT_MUST_HAVE,\n    ERROR_DS_AUX_CLS_TEST_FAIL,\n    ERROR_DS_NONEXISTENT_POSS_SUP,\n    ERROR_DS_SUB_CLS_TEST_FAIL,\n    ERROR_DS_BAD_RDN_ATT_ID_SYNTAX,\n    ERROR_DS_EXISTS_IN_AUX_CLS,\n    ERROR_DS_EXISTS_IN_SUB_CLS,\n    ERROR_DS_EXISTS_IN_POSS_SUP,\n    ERROR_DS_RECALCSCHEMA_FAILED,\n    ERROR_DS_TREE_DELETE_NOT_FINISHED,\n    ERROR_DS_CANT_DELETE,\n    ERROR_DS_ATT_SCHEMA_REQ_ID,\n    ERROR_DS_BAD_ATT_SCHEMA_SYNTAX,\n    ERROR_DS_CANT_CACHE_ATT,\n    ERROR_DS_CANT_CACHE_CLASS,\n    ERROR_DS_CANT_REMOVE_ATT_CACHE,\n    ERROR_DS_CANT_REMOVE_CLASS_CACHE,\n    ERROR_DS_CANT_RETRIEVE_DN,\n    ERROR_DS_MISSING_SUPREF,\n    ERROR_DS_CANT_RETRIEVE_INSTANCE,\n    ERROR_DS_CODE_INCONSISTENCY,\n    ERROR_DS_DATABASE_ERROR,\n    ERROR_DS_GOVERNSID_MISSING,\n    ERROR_DS_MISSING_EXPECTED_ATT,\n    ERROR_DS_NCNAME_MISSING_CR_REF,\n    ERROR_DS_SECURITY_CHECKING_ERROR,\n    ERROR_DS_SCHEMA_NOT_LOADED,\n    ERROR_DS_SCHEMA_ALLOC_FAILED,\n    ERROR_DS_ATT_SCHEMA_REQ_SYNTAX,\n    ERROR_DS_GCVERIFY_ERROR,\n    ERROR_DS_DRA_SCHEMA_MISMATCH,\n    ERROR_DS_CANT_FIND_DSA_OBJ,\n    ERROR_DS_CANT_FIND_EXPECTED_NC,\n    ERROR_DS_CANT_FIND_NC_IN_CACHE,\n    ERROR_DS_CANT_RETRIEVE_CHILD,\n    ERROR_DS_SECURITY_ILLEGAL_MODIFY,\n    ERROR_DS_CANT_REPLACE_HIDDEN_REC,\n    ERROR_DS_BAD_HIERARCHY_FILE,\n    ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED,\n    ERROR_DS_CONFIG_PARAM_MISSING,\n    ERROR_DS_COUNTING_AB_INDICES_FAILED,\n    ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED,\n    ERROR_DS_INTERNAL_FAILURE,\n    ERROR_DS_UNKNOWN_ERROR,\n    ERROR_DS_ROOT_REQUIRES_CLASS_TOP,\n    ERROR_DS_REFUSING_FSMO_ROLES,\n    ERROR_DS_MISSING_FSMO_SETTINGS,\n    ERROR_DS_UNABLE_TO_SURRENDER_ROLES,\n    ERROR_DS_DRA_GENERIC,\n    ERROR_DS_DRA_INVALID_PARAMETER,\n    ERROR_DS_DRA_BUSY,\n    ERROR_DS_DRA_BAD_DN,\n    ERROR_DS_DRA_BAD_NC,\n    ERROR_DS_DRA_DN_EXISTS,\n    ERROR_DS_DRA_INTERNAL_ERROR,\n    ERROR_DS_DRA_INCONSISTENT_DIT,\n    ERROR_DS_DRA_CONNECTION_FAILED,\n    ERROR_DS_DRA_BAD_INSTANCE_TYPE,\n    ERROR_DS_DRA_OUT_OF_MEM,\n    ERROR_DS_DRA_MAIL_PROBLEM,\n    ERROR_DS_DRA_REF_ALREADY_EXISTS,\n    ERROR_DS_DRA_REF_NOT_FOUND,\n    ERROR_DS_DRA_OBJ_IS_REP_SOURCE,\n    ERROR_DS_DRA_DB_ERROR,\n    ERROR_DS_DRA_NO_REPLICA,\n    ERROR_DS_DRA_ACCESS_DENIED,\n    ERROR_DS_DRA_NOT_SUPPORTED,\n    ERROR_DS_DRA_RPC_CANCELLED,\n    ERROR_DS_DRA_SOURCE_DISABLED,\n    ERROR_DS_DRA_SINK_DISABLED,\n    ERROR_DS_DRA_NAME_COLLISION,\n    ERROR_DS_DRA_SOURCE_REINSTALLED,\n    ERROR_DS_DRA_MISSING_PARENT,\n    ERROR_DS_DRA_PREEMPTED,\n    ERROR_DS_DRA_ABANDON_SYNC,\n    ERROR_DS_DRA_SHUTDOWN,\n    ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET,\n    ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA,\n    ERROR_DS_DRA_EXTN_CONNECTION_FAILED,\n    ERROR_DS_INSTALL_SCHEMA_MISMATCH,\n    ERROR_DS_DUP_LINK_ID,\n    ERROR_DS_NAME_ERROR_RESOLVING,\n    ERROR_DS_NAME_ERROR_NOT_FOUND,\n    ERROR_DS_NAME_ERROR_NOT_UNIQUE,\n    ERROR_DS_NAME_ERROR_NO_MAPPING,\n    ERROR_DS_NAME_ERROR_DOMAIN_ONLY,\n    ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING,\n    ERROR_DS_CONSTRUCTED_ATT_MOD,\n    ERROR_DS_WRONG_OM_OBJ_CLASS,\n    ERROR_DS_DRA_REPL_PENDING,\n    ERROR_DS_DS_REQUIRED,\n    ERROR_DS_INVALID_LDAP_DISPLAY_NAME,\n    ERROR_DS_NON_BASE_SEARCH,\n    ERROR_DS_CANT_RETRIEVE_ATTS,\n    ERROR_DS_BACKLINK_WITHOUT_LINK,\n    ERROR_DS_EPOCH_MISMATCH,\n    ERROR_DS_SRC_NAME_MISMATCH,\n    ERROR_DS_SRC_AND_DST_NC_IDENTICAL,\n    ERROR_DS_DST_NC_MISMATCH,\n    ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC,\n    ERROR_DS_SRC_GUID_MISMATCH,\n    ERROR_DS_CANT_MOVE_DELETED_OBJECT,\n    ERROR_DS_PDC_OPERATION_IN_PROGRESS,\n    ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD,\n    ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION,\n    ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS,\n    ERROR_DS_NC_MUST_HAVE_NC_PARENT,\n    ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE,\n    ERROR_DS_DST_DOMAIN_NOT_NATIVE,\n    ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER,\n    ERROR_DS_CANT_MOVE_ACCOUNT_GROUP,\n    ERROR_DS_CANT_MOVE_RESOURCE_GROUP,\n    ERROR_DS_INVALID_SEARCH_FLAG,\n    ERROR_DS_NO_TREE_DELETE_ABOVE_NC,\n    ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE,\n    ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE,\n    ERROR_DS_SAM_INIT_FAILURE,\n    ERROR_DS_SENSITIVE_GROUP_VIOLATION,\n    ERROR_DS_CANT_MOD_PRIMARYGROUPID,\n    ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD,\n    ERROR_DS_NONSAFE_SCHEMA_CHANGE,\n    ERROR_DS_SCHEMA_UPDATE_DISALLOWED,\n    ERROR_DS_CANT_CREATE_UNDER_SCHEMA,\n    ERROR_DS_INSTALL_NO_SRC_SCH_VERSION,\n    ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE,\n    ERROR_DS_INVALID_GROUP_TYPE,\n    ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN,\n    ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN,\n    ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER,\n    ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER,\n    ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER,\n    ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER,\n    ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER,\n    ERROR_DS_HAVE_PRIMARY_MEMBERS,\n    ERROR_DS_STRING_SD_CONVERSION_FAILED,\n    ERROR_DS_NAMING_MASTER_GC,\n    ERROR_DS_LOOKUP_FAILURE,\n    ERROR_DS_COULDNT_UPDATE_SPNS,\n    ERROR_DS_CANT_RETRIEVE_SD,\n    ERROR_DS_KEY_NOT_UNIQUE,\n    ERROR_DS_WRONG_LINKED_ATT_SYNTAX,\n    ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD,\n    ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY,\n    ERROR_DS_CANT_START,\n    ERROR_DS_INIT_FAILURE,\n    ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION,\n    ERROR_DS_SOURCE_DOMAIN_IN_FOREST,\n    ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST,\n    ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED,\n    ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN,\n    ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER,\n    ERROR_DS_SRC_SID_EXISTS_IN_FOREST,\n    ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH,\n    ERROR_SAM_INIT_FAILURE,\n    ERROR_DS_DRA_SCHEMA_INFO_SHIP,\n    ERROR_DS_DRA_SCHEMA_CONFLICT,\n    ERROR_DS_DRA_EARLIER_SCHEMA_CONLICT,\n    ERROR_DS_DRA_OBJ_NC_MISMATCH,\n    ERROR_DS_NC_STILL_HAS_DSAS,\n    ERROR_DS_GC_REQUIRED,\n    ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY,\n    ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS,\n    ERROR_DS_CANT_ADD_TO_GC,\n    ERROR_DS_NO_CHECKPOINT_WITH_PDC,\n    ERROR_DS_SOURCE_AUDITING_NOT_ENABLED,\n    ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC,\n    ERROR_DS_INVALID_NAME_FOR_SPN,\n    ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS,\n    ERROR_DS_UNICODEPWD_NOT_IN_QUOTES,\n    ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED,\n    ERROR_DS_MUST_BE_RUN_ON_DST_DC,\n    ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER,\n    ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ,\n    ERROR_DS_INIT_FAILURE_CONSOLE,\n    ERROR_DS_SAM_INIT_FAILURE_CONSOLE,\n    ERROR_DS_FOREST_VERSION_TOO_HIGH,\n    ERROR_DS_DOMAIN_VERSION_TOO_HIGH,\n    ERROR_DS_FOREST_VERSION_TOO_LOW,\n    ERROR_DS_DOMAIN_VERSION_TOO_LOW,\n    ERROR_DS_INCOMPATIBLE_VERSION,\n    ERROR_DS_LOW_DSA_VERSION,\n    ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN,\n    ERROR_DS_NOT_SUPPORTED_SORT_ORDER,\n    ERROR_DS_NAME_NOT_UNIQUE,\n    ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4,\n    ERROR_DS_OUT_OF_VERSION_STORE,\n    ERROR_DS_INCOMPATIBLE_CONTROLS_USED,\n    ERROR_DS_NO_REF_DOMAIN,\n    ERROR_DS_RESERVED_LINK_ID,\n    ERROR_DS_LINK_ID_NOT_AVAILABLE,\n    ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER,\n    ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE,\n    ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC,\n    ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG,\n    ERROR_DS_MODIFYDN_WRONG_GRANDPARENT,\n    ERROR_DS_NAME_ERROR_TRUST_REFERRAL,\n    ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER,\n    ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD,\n    ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2,\n    ERROR_DS_THREAD_LIMIT_EXCEEDED,\n    ERROR_DS_NOT_CLOSEST,\n    ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF,\n    ERROR_DS_SINGLE_USER_MODE_FAILED,\n    ERROR_DS_NTDSCRIPT_SYNTAX_ERROR,\n    ERROR_DS_NTDSCRIPT_PROCESS_ERROR,\n    ERROR_DS_DIFFERENT_REPL_EPOCHS,\n    ERROR_DS_DRS_EXTENSIONS_CHANGED,\n    ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR,\n    ERROR_DS_NO_MSDS_INTID,\n    ERROR_DS_DUP_MSDS_INTID,\n    ERROR_DS_EXISTS_IN_RDNATTID,\n    ERROR_DS_AUTHORIZATION_FAILED,\n    ERROR_DS_INVALID_SCRIPT,\n    ERROR_DS_REMOTE_CROSSREF_OP_FAILED,\n    ERROR_DS_CROSS_REF_BUSY,\n    ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN,\n    ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC,\n    ERROR_DS_DUPLICATE_ID_FOUND,\n    ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT,\n    ERROR_DS_GROUP_CONVERSION_ERROR,\n    ERROR_DS_CANT_MOVE_APP_BASIC_GROUP,\n    ERROR_DS_CANT_MOVE_APP_QUERY_GROUP,\n    ERROR_DS_ROLE_NOT_VERIFIED,\n    ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL,\n    ERROR_DS_DOMAIN_RENAME_IN_PROGRESS,\n    ERROR_DS_EXISTING_AD_CHILD_NC,                     // =  8613\n    DNS_ERROR_RCODE_FORMAT_ERROR                          =  9001,\n    DNS_ERROR_RCODE_SERVER_FAILURE,\n    DNS_ERROR_RCODE_NAME_ERROR,\n    DNS_ERROR_RCODE_NOT_IMPLEMENTED,\n    DNS_ERROR_RCODE_REFUSED,\n    DNS_ERROR_RCODE_YXDOMAIN,\n    DNS_ERROR_RCODE_YXRRSET,\n    DNS_ERROR_RCODE_NXRRSET,\n    DNS_ERROR_RCODE_NOTAUTH,\n    DNS_ERROR_RCODE_NOTZONE,                           // =  9010\n    DNS_ERROR_RCODE_BADSIG                                =  9016,\n    DNS_ERROR_RCODE_BADKEY,\n    DNS_ERROR_RCODE_BADTIME,                           // =  9018\n    DNS_INFO_NO_RECORDS                                   =  9501,\n    DNS_ERROR_BAD_PACKET,\n    DNS_ERROR_NO_PACKET,\n    DNS_ERROR_RCODE,\n    DNS_ERROR_UNSECURE_PACKET,                         // =  9505\n    DNS_ERROR_INVALID_TYPE                                =  9551,\n    DNS_ERROR_INVALID_IP_ADDRESS,\n    DNS_ERROR_INVALID_PROPERTY,\n    DNS_ERROR_TRY_AGAIN_LATER,\n    DNS_ERROR_NOT_UNIQUE,\n    DNS_ERROR_NON_RFC_NAME,\n    DNS_STATUS_FQDN,\n    DNS_STATUS_DOTTED_NAME,\n    DNS_STATUS_SINGLE_PART_NAME,\n    DNS_ERROR_INVALID_NAME_CHAR,\n    DNS_ERROR_NUMERIC_NAME,\n    DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER,\n    DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION,\n    DNS_ERROR_CANNOT_FIND_ROOT_HINTS,\n    DNS_ERROR_INCONSISTENT_ROOT_HINTS,                 // =  9565\n    DNS_ERROR_ZONE_DOES_NOT_EXIST                         =  9601,\n    DNS_ERROR_NO_ZONE_INFO,\n    DNS_ERROR_INVALID_ZONE_OPERATION,\n    DNS_ERROR_ZONE_CONFIGURATION_ERROR,\n    DNS_ERROR_ZONE_HAS_NO_SOA_RECORD,\n    DNS_ERROR_ZONE_HAS_NO_NS_RECORDS,\n    DNS_ERROR_ZONE_LOCKED,\n    DNS_ERROR_ZONE_CREATION_FAILED,\n    DNS_ERROR_ZONE_ALREADY_EXISTS,\n    DNS_ERROR_AUTOZONE_ALREADY_EXISTS,\n    DNS_ERROR_INVALID_ZONE_TYPE,\n    DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP,\n    DNS_ERROR_ZONE_NOT_SECONDARY,\n    DNS_ERROR_NEED_SECONDARY_ADDRESSES,\n    DNS_ERROR_WINS_INIT_FAILED,\n    DNS_ERROR_NEED_WINS_SERVERS,\n    DNS_ERROR_NBSTAT_INIT_FAILED,\n    DNS_ERROR_SOA_DELETE_INVALID,\n    DNS_ERROR_FORWARDER_ALREADY_EXISTS,\n    DNS_ERROR_ZONE_REQUIRES_MASTER_IP,\n    DNS_ERROR_ZONE_IS_SHUTDOWN,                        // =  9621\n    DNS_ERROR_PRIMARY_REQUIRES_DATAFILE                   =  9651,\n    DNS_ERROR_INVALID_DATAFILE_NAME,\n    DNS_ERROR_DATAFILE_OPEN_FAILURE,\n    DNS_ERROR_FILE_WRITEBACK_FAILED,\n    DNS_ERROR_DATAFILE_PARSING,                        // =  9655\n    DNS_ERROR_RECORD_DOES_NOT_EXIST                       =  9701,\n    DNS_ERROR_RECORD_FORMAT,\n    DNS_ERROR_NODE_CREATION_FAILED,\n    DNS_ERROR_UNKNOWN_RECORD_TYPE,\n    DNS_ERROR_RECORD_TIMED_OUT,\n    DNS_ERROR_NAME_NOT_IN_ZONE,\n    DNS_ERROR_CNAME_LOOP,\n    DNS_ERROR_NODE_IS_CNAME,\n    DNS_ERROR_CNAME_COLLISION,\n    DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT,\n    DNS_ERROR_RECORD_ALREADY_EXISTS,\n    DNS_ERROR_SECONDARY_DATA,\n    DNS_ERROR_NO_CREATE_CACHE_DATA,\n    DNS_ERROR_NAME_DOES_NOT_EXIST,\n    DNS_WARNING_PTR_CREATE_FAILED,\n    DNS_WARNING_DOMAIN_UNDELETED,\n    DNS_ERROR_DS_UNAVAILABLE,\n    DNS_ERROR_DS_ZONE_ALREADY_EXISTS,\n    DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE,                  // =  9719\n    DNS_INFO_AXFR_COMPLETE                                =  9751,\n    DNS_ERROR_AXFR,\n    DNS_INFO_ADDED_LOCAL_WINS,                         // =  9753\n    DNS_STATUS_CONTINUE_NEEDED                            =  9801,\n    DNS_ERROR_NO_TCPIP                                    =  9851,\n    DNS_ERROR_NO_DNS_SERVERS,                          // =  9852\n    DNS_ERROR_DP_DOES_NOT_EXIST                           =  9901,\n    DNS_ERROR_DP_ALREADY_EXISTS,\n    DNS_ERROR_DP_NOT_ENLISTED,\n    DNS_ERROR_DP_ALREADY_ENLISTED,\n    DNS_ERROR_DP_NOT_AVAILABLE,                        // =  9905\n\n/+  already in winsock2.d defined!\n\n    WSABASEERR                                            = 10000,\n    WSAEINTR                                              = 10004,\n    WSAEBADF                                              = 10009,\n    WSAEACCES                                             = 10013,\n    WSAEFAULT,                                         // = 10014\n    WSAEINVAL                                             = 10022,\n    WSAEMFILE                                             = 10024,\n    WSAEWOULDBLOCK                                        = 10035,\n    WSAEINPROGRESS,\n    WSAEALREADY,\n    WSAENOTSOCK,\n    WSAEDESTADDRREQ,\n    WSAEMSGSIZE,\n    WSAEPROTOTYPE,\n    WSAENOPROTOOPT,\n    WSAEPROTONOSUPPORT,\n    WSAESOCKTNOSUPPORT,\n    WSAEOPNOTSUPP,\n    WSAEPFNOSUPPORT,\n    WSAEAFNOSUPPORT,\n    WSAEADDRINUSE,\n    WSAEADDRNOTAVAIL,\n    WSAENETDOWN,\n    WSAENETUNREACH,\n    WSAENETRESET,\n    WSAECONNABORTED,\n    WSAECONNRESET,\n    WSAENOBUFS,\n    WSAEISCONN,\n    WSAENOTCONN,\n    WSAESHUTDOWN,\n    WSAETOOMANYREFS,\n    WSAETIMEDOUT,\n    WSAECONNREFUSED,\n    WSAELOOP,\n    WSAENAMETOOLONG,\n    WSAEHOSTDOWN,\n    WSAEHOSTUNREACH,\n    WSAENOTEMPTY,\n    WSAEPROCLIM,\n    WSAEUSERS,\n    WSAEDQUOT,\n    WSAESTALE,\n    WSAEREMOTE,                                        // = 10071\n    WSASYSNOTREADY                                        = 10091,\n    WSAVERNOTSUPPORTED,\n    WSANOTINITIALISED,                                 // = 10093\n    WSAEDISCON                                            = 10101,\n    WSAENOMORE,\n    WSAECANCELLED,\n    WSAEINVALIDPROCTABLE,\n    WSAEINVALIDPROVIDER,\n    WSAEPROVIDERFAILEDINIT,\n    WSASYSCALLFAILURE,\n    WSASERVICE_NOT_FOUND,\n    WSATYPE_NOT_FOUND,\n    WSA_E_NO_MORE,\n    WSA_E_CANCELLED,\n    WSAEREFUSED,                                       // = 10112\n    WSAHOST_NOT_FOUND                                     = 11001,\n    WSATRY_AGAIN,\n    WSANO_RECOVERY,\n    WSANO_DATA,\n    WSA_QOS_RECEIVERS,\n    WSA_QOS_SENDERS,\n    WSA_QOS_NO_SENDERS,\n    WSA_QOS_NO_RECEIVERS,\n    WSA_QOS_REQUEST_CONFIRMED,\n    WSA_QOS_ADMISSION_FAILURE,\n    WSA_QOS_POLICY_FAILURE,\n    WSA_QOS_BAD_STYLE,\n    WSA_QOS_BAD_OBJECT,\n    WSA_QOS_TRAFFIC_CTRL_ERROR,\n    WSA_QOS_GENERIC_ERROR,\n    WSA_QOS_ESERVICETYPE,\n    WSA_QOS_EFLOWSPEC,\n    WSA_QOS_EPROVSPECBUF,\n    WSA_QOS_EFILTERSTYLE,\n    WSA_QOS_EFILTERTYPE,\n    WSA_QOS_EFILTERCOUNT,\n    WSA_QOS_EOBJLENGTH,\n    WSA_QOS_EFLOWCOUNT,\n    WSA_QOS_EUNKNOWNPSOBJ,\n    WSA_QOS_EPOLICYOBJ,\n    WSA_QOS_EFLOWDESC,\n    WSA_QOS_EPSFLOWSPEC,\n    WSA_QOS_EPSFILTERSPEC,\n    WSA_QOS_ESDMODEOBJ,\n    WSA_QOS_ESHAPERATEOBJ,\n    WSA_QOS_RESERVED_PETYPE,                           // = 11031\n\n+/\n\n    ERROR_IPSEC_QM_POLICY_EXISTS                          = 13000,\n    ERROR_IPSEC_QM_POLICY_NOT_FOUND,\n    ERROR_IPSEC_QM_POLICY_IN_USE,\n    ERROR_IPSEC_MM_POLICY_EXISTS,\n    ERROR_IPSEC_MM_POLICY_NOT_FOUND,\n    ERROR_IPSEC_MM_POLICY_IN_USE,\n    ERROR_IPSEC_MM_FILTER_EXISTS,\n    ERROR_IPSEC_MM_FILTER_NOT_FOUND,\n    ERROR_IPSEC_TRANSPORT_FILTER_EXISTS,\n    ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND,\n    ERROR_IPSEC_MM_AUTH_EXISTS,\n    ERROR_IPSEC_MM_AUTH_NOT_FOUND,\n    ERROR_IPSEC_MM_AUTH_IN_USE,\n    ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND,\n    ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND,\n    ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND,\n    ERROR_IPSEC_TUNNEL_FILTER_EXISTS,\n    ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND,\n    ERROR_IPSEC_MM_FILTER_PENDING_DELETION,\n    ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION,\n    ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION,\n    ERROR_IPSEC_MM_POLICY_PENDING_DELETION,\n    ERROR_IPSEC_MM_AUTH_PENDING_DELETION,\n    ERROR_IPSEC_QM_POLICY_PENDING_DELETION,\n    WARNING_IPSEC_MM_POLICY_PRUNED,\n    WARNING_IPSEC_QM_POLICY_PRUNED,                    // = 13025\n    ERROR_IPSEC_IKE_AUTH_FAIL                             = 13801,\n    ERROR_IPSEC_IKE_ATTRIB_FAIL,\n    ERROR_IPSEC_IKE_NEGOTIATION_PENDING,\n    ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR,\n    ERROR_IPSEC_IKE_TIMED_OUT,\n    ERROR_IPSEC_IKE_NO_CERT,\n    ERROR_IPSEC_IKE_SA_DELETED,\n    ERROR_IPSEC_IKE_SA_REAPED,\n    ERROR_IPSEC_IKE_MM_ACQUIRE_DROP,\n    ERROR_IPSEC_IKE_QM_ACQUIRE_DROP,\n    ERROR_IPSEC_IKE_QUEUE_DROP_MM,\n    ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM,\n    ERROR_IPSEC_IKE_DROP_NO_RESPONSE,\n    ERROR_IPSEC_IKE_MM_DELAY_DROP,\n    ERROR_IPSEC_IKE_QM_DELAY_DROP,\n    ERROR_IPSEC_IKE_ERROR,\n    ERROR_IPSEC_IKE_CRL_FAILED,\n    ERROR_IPSEC_IKE_INVALID_KEY_USAGE,\n    ERROR_IPSEC_IKE_INVALID_CERT_TYPE,\n    ERROR_IPSEC_IKE_NO_PRIVATE_KEY,                    // = 13820\n    ERROR_IPSEC_IKE_DH_FAIL                               = 13822,\n    ERROR_IPSEC_IKE_INVALID_HEADER                        = 13824,\n    ERROR_IPSEC_IKE_NO_POLICY,\n    ERROR_IPSEC_IKE_INVALID_SIGNATURE,\n    ERROR_IPSEC_IKE_KERBEROS_ERROR,\n    ERROR_IPSEC_IKE_NO_PUBLIC_KEY,\n    ERROR_IPSEC_IKE_PROCESS_ERR,\n    ERROR_IPSEC_IKE_PROCESS_ERR_SA,\n    ERROR_IPSEC_IKE_PROCESS_ERR_PROP,\n    ERROR_IPSEC_IKE_PROCESS_ERR_TRANS,\n    ERROR_IPSEC_IKE_PROCESS_ERR_KE,\n    ERROR_IPSEC_IKE_PROCESS_ERR_ID,\n    ERROR_IPSEC_IKE_PROCESS_ERR_CERT,\n    ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ,\n    ERROR_IPSEC_IKE_PROCESS_ERR_HASH,\n    ERROR_IPSEC_IKE_PROCESS_ERR_SIG,\n    ERROR_IPSEC_IKE_PROCESS_ERR_NONCE,\n    ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY,\n    ERROR_IPSEC_IKE_PROCESS_ERR_DELETE,\n    ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR,\n    ERROR_IPSEC_IKE_INVALID_PAYLOAD,\n    ERROR_IPSEC_IKE_LOAD_SOFT_SA,\n    ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN,\n    ERROR_IPSEC_IKE_INVALID_COOKIE,\n    ERROR_IPSEC_IKE_NO_PEER_CERT,\n    ERROR_IPSEC_IKE_PEER_CRL_FAILED,\n    ERROR_IPSEC_IKE_POLICY_CHANGE,\n    ERROR_IPSEC_IKE_NO_MM_POLICY,\n    ERROR_IPSEC_IKE_NOTCBPRIV,\n    ERROR_IPSEC_IKE_SECLOADFAIL,\n    ERROR_IPSEC_IKE_FAILSSPINIT,\n    ERROR_IPSEC_IKE_FAILQUERYSSP,\n    ERROR_IPSEC_IKE_SRVACQFAIL,\n    ERROR_IPSEC_IKE_SRVQUERYCRED,\n    ERROR_IPSEC_IKE_GETSPIFAIL,\n    ERROR_IPSEC_IKE_INVALID_FILTER,\n    ERROR_IPSEC_IKE_OUT_OF_MEMORY,\n    ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED,\n    ERROR_IPSEC_IKE_INVALID_POLICY,\n    ERROR_IPSEC_IKE_UNKNOWN_DOI,\n    ERROR_IPSEC_IKE_INVALID_SITUATION,\n    ERROR_IPSEC_IKE_DH_FAILURE,\n    ERROR_IPSEC_IKE_INVALID_GROUP,\n    ERROR_IPSEC_IKE_ENCRYPT,\n    ERROR_IPSEC_IKE_DECRYPT,\n    ERROR_IPSEC_IKE_POLICY_MATCH,\n    ERROR_IPSEC_IKE_UNSUPPORTED_ID,\n    ERROR_IPSEC_IKE_INVALID_HASH,\n    ERROR_IPSEC_IKE_INVALID_HASH_ALG,\n    ERROR_IPSEC_IKE_INVALID_HASH_SIZE,\n    ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG,\n    ERROR_IPSEC_IKE_INVALID_AUTH_ALG,\n    ERROR_IPSEC_IKE_INVALID_SIG,\n    ERROR_IPSEC_IKE_LOAD_FAILED,\n    ERROR_IPSEC_IKE_RPC_DELETE,\n    ERROR_IPSEC_IKE_BENIGN_REINIT,\n    ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY, // = 13879\n    ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN                   = 13881,\n    ERROR_IPSEC_IKE_MM_LIMIT,\n    ERROR_IPSEC_IKE_NEGOTIATION_DISABLED,\n    ERROR_IPSEC_IKE_NEG_STATUS_END,\n    ERROR_SXS_SECTION_NOT_FOUND,\n    ERROR_SXS_CANT_GEN_ACTCTX,\n    ERROR_SXS_INVALID_ACTCTXDATA_FORMAT,\n    ERROR_SXS_ASSEMBLY_NOT_FOUND,\n    ERROR_SXS_MANIFEST_FORMAT_ERROR,\n    ERROR_SXS_MANIFEST_PARSE_ERROR,\n    ERROR_SXS_ACTIVATION_CONTEXT_DISABLED,\n    ERROR_SXS_KEY_NOT_FOUND,\n    ERROR_SXS_VERSION_CONFLICT,\n    ERROR_SXS_WRONG_SECTION_TYPE,\n    ERROR_SXS_THREAD_QUERIES_DISABLED,\n    ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET,\n    ERROR_SXS_UNKNOWN_ENCODING_GROUP,\n    ERROR_SXS_UNKNOWN_ENCODING,\n    ERROR_SXS_INVALID_XML_NAMESPACE_URI,\n    ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED,\n    ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED,\n    ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE,\n    ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE,\n    ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE,\n    ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT,\n    ERROR_SXS_DUPLICATE_DLL_NAME,\n    ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME,\n    ERROR_SXS_DUPLICATE_CLSID,\n    ERROR_SXS_DUPLICATE_IID,\n    ERROR_SXS_DUPLICATE_TLBID,\n    ERROR_SXS_DUPLICATE_PROGID,\n    ERROR_SXS_DUPLICATE_ASSEMBLY_NAME,\n    ERROR_SXS_FILE_HASH_MISMATCH,\n    ERROR_SXS_POLICY_PARSE_ERROR,\n    ERROR_SXS_XML_E_MISSINGQUOTE,\n    ERROR_SXS_XML_E_COMMENTSYNTAX,\n    ERROR_SXS_XML_E_BADSTARTNAMECHAR,\n    ERROR_SXS_XML_E_BADNAMECHAR,\n    ERROR_SXS_XML_E_BADCHARINSTRING,\n    ERROR_SXS_XML_E_XMLDECLSYNTAX,\n    ERROR_SXS_XML_E_BADCHARDATA,\n    ERROR_SXS_XML_E_MISSINGWHITESPACE,\n    ERROR_SXS_XML_E_EXPECTINGTAGEND,\n    ERROR_SXS_XML_E_MISSINGSEMICOLON,\n    ERROR_SXS_XML_E_UNBALANCEDPAREN,\n    ERROR_SXS_XML_E_INTERNALERROR,\n    ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE,\n    ERROR_SXS_XML_E_INCOMPLETE_ENCODING,\n    ERROR_SXS_XML_E_MISSING_PAREN,\n    ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE,\n    ERROR_SXS_XML_E_MULTIPLE_COLONS,\n    ERROR_SXS_XML_E_INVALID_DECIMAL,\n    ERROR_SXS_XML_E_INVALID_HEXIDECIMAL,\n    ERROR_SXS_XML_E_INVALID_UNICODE,\n    ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK,\n    ERROR_SXS_XML_E_UNEXPECTEDENDTAG,\n    ERROR_SXS_XML_E_UNCLOSEDTAG,\n    ERROR_SXS_XML_E_DUPLICATEATTRIBUTE,\n    ERROR_SXS_XML_E_MULTIPLEROOTS,\n    ERROR_SXS_XML_E_INVALIDATROOTLEVEL,\n    ERROR_SXS_XML_E_BADXMLDECL,\n    ERROR_SXS_XML_E_MISSINGROOT,\n    ERROR_SXS_XML_E_UNEXPECTEDEOF,\n    ERROR_SXS_XML_E_BADPEREFINSUBSET,\n    ERROR_SXS_XML_E_UNCLOSEDSTARTTAG,\n    ERROR_SXS_XML_E_UNCLOSEDENDTAG,\n    ERROR_SXS_XML_E_UNCLOSEDSTRING,\n    ERROR_SXS_XML_E_UNCLOSEDCOMMENT,\n    ERROR_SXS_XML_E_UNCLOSEDDECL,\n    ERROR_SXS_XML_E_UNCLOSEDCDATA,\n    ERROR_SXS_XML_E_RESERVEDNAMESPACE,\n    ERROR_SXS_XML_E_INVALIDENCODING,\n    ERROR_SXS_XML_E_INVALIDSWITCH,\n    ERROR_SXS_XML_E_BADXMLCASE,\n    ERROR_SXS_XML_E_INVALID_STANDALONE,\n    ERROR_SXS_XML_E_UNEXPECTED_STANDALONE,\n    ERROR_SXS_XML_E_INVALID_VERSION,\n    ERROR_SXS_XML_E_MISSINGEQUALS,\n    ERROR_SXS_PROTECTION_RECOVERY_FAILED,\n    ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT,\n    ERROR_SXS_PROTECTION_CATALOG_NOT_VALID,\n    ERROR_SXS_UNTRANSLATABLE_HRESULT,\n    ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING,\n    ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE,\n    ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME // = 14080\n}\n\nenum : HRESULT {\n    S_OK                                   = 0x00000000,\n    S_FALSE                                = 0x00000001,\n\n    NOERROR                                = 0x00000000,\n\n    E_PENDING                              = 0x8000000A,\n    E_NOTIMPL                              = 0x80004001,\n    E_NOINTERFACE                          = 0x80004002,\n    E_POINTER                              = 0x80004003,\n    E_ABORT                                = 0x80004004,\n    E_FAIL                                 = 0x80004005,\n    E_ACCESSDENIED                         = 0x80070005,\n    E_HANDLE                               = 0x80070006,\n    E_OUTOFMEMORY                          = 0x8007000E,\n    E_INVALIDARG                           = 0x80070057,\n    E_UNEXPECTED                           = 0x8000FFFF,\n\n    CO_E_INIT_TLS                          = 0x80004006,\n    CO_E_INIT_SHARED_ALLOCATOR             = 0x80004007,\n    CO_E_INIT_MEMORY_ALLOCATOR             = 0x80004008,\n    CO_E_INIT_CLASS_CACHE                  = 0x80004009,\n    CO_E_INIT_RPC_CHANNEL                  = 0x8000400A,\n    CO_E_INIT_TLS_SET_CHANNEL_CONTROL      = 0x8000400B,\n    CO_E_INIT_TLS_CHANNEL_CONTROL          = 0x8000400C,\n    CO_E_INIT_UNACCEPTED_USER_ALLOCATOR    = 0x8000400D,\n    CO_E_INIT_SCM_MUTEX_EXISTS             = 0x8000400E,\n    CO_E_INIT_SCM_FILE_MAPPING_EXISTS      = 0x8000400F,\n    CO_E_INIT_SCM_MAP_VIEW_OF_FILE         = 0x80004010,\n    CO_E_INIT_SCM_EXEC_FAILURE             = 0x80004011,\n    CO_E_INIT_ONLY_SINGLE_THREADED         = 0x80004012,\n\n    RPC_E_CALL_REJECTED                    = 0x80010001,\n    RPC_E_CALL_CANCELED                    = 0x80010002,\n    RPC_E_CANTPOST_INSENDCALL              = 0x80010003,\n    RPC_E_CANTCALLOUT_INASYNCCALL          = 0x80010004,\n    RPC_E_CANTCALLOUT_INEXTERNALCALL       = 0x80010005,\n    RPC_E_CONNECTION_TERMINATED            = 0x80010006,\n    RPC_E_SERVER_DIED                      = 0x80010007,\n    RPC_E_CLIENT_DIED                      = 0x80010008,\n    RPC_E_INVALID_DATAPACKET               = 0x80010009,\n    RPC_E_CANTTRANSMIT_CALL                = 0x8001000A,\n    RPC_E_CLIENT_CANTMARSHAL_DATA          = 0x8001000B,\n    RPC_E_CLIENT_CANTUNMARSHAL_DATA        = 0x8001000C,\n    RPC_E_SERVER_CANTMARSHAL_DATA          = 0x8001000D,\n    RPC_E_SERVER_CANTUNMARSHAL_DATA        = 0x8001000E,\n    RPC_E_INVALID_DATA                     = 0x8001000F,\n    RPC_E_INVALID_PARAMETER                = 0x80010010,\n    RPC_E_CANTCALLOUT_AGAIN                = 0x80010011,\n    RPC_E_SERVER_DIED_DNE                  = 0x80010012,\n    RPC_E_SYS_CALL_FAILED                  = 0x80010100,\n    RPC_E_OUT_OF_RESOURCES                 = 0x80010101,\n    RPC_E_ATTEMPTED_MULTITHREAD            = 0x80010102,\n    RPC_E_NOT_REGISTERED                   = 0x80010103,\n    RPC_E_FAULT                            = 0x80010104,\n    RPC_E_SERVERFAULT                      = 0x80010105,\n    RPC_E_CHANGED_MODE                     = 0x80010106,\n    RPC_E_INVALIDMETHOD                    = 0x80010107,\n    RPC_E_DISCONNECTED                     = 0x80010108,\n    RPC_E_RETRY                            = 0x80010109,\n    RPC_E_SERVERCALL_RETRYLATER            = 0x8001010A,\n    RPC_E_SERVERCALL_REJECTED              = 0x8001010B,\n    RPC_E_INVALID_CALLDATA                 = 0x8001010C,\n    RPC_E_CANTCALLOUT_ININPUTSYNCCALL      = 0x8001010D,\n    RPC_E_WRONG_THREAD                     = 0x8001010E,\n    RPC_E_THREAD_NOT_INIT                  = 0x8001010F,\n    RPC_E_UNEXPECTED                       = 0x8001FFFF,\n\n    DISP_E_UNKNOWNINTERFACE                = 0x80020001,\n    DISP_E_MEMBERNOTFOUND                  = 0x80020003,\n    DISP_E_PARAMNOTFOUND                   = 0x80020004,\n    DISP_E_TYPEMISMATCH                    = 0x80020005,\n    DISP_E_UNKNOWNNAME                     = 0x80020006,\n    DISP_E_NONAMEDARGS                     = 0x80020007,\n    DISP_E_BADVARTYPE                      = 0x80020008,\n    DISP_E_EXCEPTION                       = 0x80020009,\n    DISP_E_OVERFLOW                        = 0x8002000A,\n    DISP_E_BADINDEX                        = 0x8002000B,\n    DISP_E_UNKNOWNLCID                     = 0x8002000C,\n    DISP_E_ARRAYISLOCKED                   = 0x8002000D,\n    DISP_E_BADPARAMCOUNT                   = 0x8002000E,\n    DISP_E_PARAMNOTOPTIONAL                = 0x8002000F,\n    DISP_E_BADCALLEE                       = 0x80020010,\n    DISP_E_NOTACOLLECTION                  = 0x80020011,\n    DISP_E_DIVBYZERO                       = 0x80020012,\n\n    TYPE_E_BUFFERTOOSMALL                  = 0x80028016,\n    TYPE_E_INVDATAREAD                     = 0x80028018,\n    TYPE_E_UNSUPFORMAT                     = 0x80028019,\n    TYPE_E_REGISTRYACCESS                  = 0x8002801C,\n    TYPE_E_LIBNOTREGISTERED                = 0x8002801D,\n    TYPE_E_UNDEFINEDTYPE                   = 0x80028027,\n    TYPE_E_QUALIFIEDNAMEDISALLOWED         = 0x80028028,\n    TYPE_E_INVALIDSTATE                    = 0x80028029,\n    TYPE_E_WRONGTYPEKIND                   = 0x8002802A,\n    TYPE_E_ELEMENTNOTFOUND                 = 0x8002802B,\n    TYPE_E_AMBIGUOUSNAME                   = 0x8002802C,\n    TYPE_E_NAMECONFLICT                    = 0x8002802D,\n    TYPE_E_UNKNOWNLCID                     = 0x8002802E,\n    TYPE_E_DLLFUNCTIONNOTFOUND             = 0x8002802F,\n    TYPE_E_BADMODULEKIND                   = 0x800288BD,\n    TYPE_E_SIZETOOBIG                      = 0x800288C5,\n    TYPE_E_DUPLICATEID                     = 0x800288C6,\n    TYPE_E_INVALIDID                       = 0x800288CF,\n    TYPE_E_TYPEMISMATCH                    = 0x80028CA0,\n    TYPE_E_OUTOFBOUNDS                     = 0x80028CA1,\n    TYPE_E_IOERROR                         = 0x80028CA2,\n    TYPE_E_CANTCREATETMPFILE               = 0x80028CA3,\n    TYPE_E_CANTLOADLIBRARY                 = 0x80029C4A,\n    TYPE_E_INCONSISTENTPROPFUNCS           = 0x80029C83,\n    TYPE_E_CIRCULARTYPE                    = 0x80029C84,\n\n    STG_E_INVALIDFUNCTION                  = 0x80030001,\n    STG_E_FILENOTFOUND                     = 0x80030002,\n    STG_E_PATHNOTFOUND                     = 0x80030003,\n    STG_E_TOOMANYOPENFILES                 = 0x80030004,\n    STG_E_ACCESSDENIED                     = 0x80030005,\n    STG_E_INVALIDHANDLE                    = 0x80030006,\n    STG_E_INSUFFICIENTMEMORY               = 0x80030008,\n    STG_E_INVALIDPOINTER                   = 0x80030009,\n    STG_E_NOMOREFILES                      = 0x80030012,\n    STG_E_DISKISWRITEPROTECTED             = 0x80030013,\n    STG_E_SEEKERROR                        = 0x80030019,\n    STG_E_WRITEFAULT                       = 0x8003001D,\n    STG_E_READFAULT                        = 0x8003001E,\n    STG_E_SHAREVIOLATION                   = 0x80030020,\n    STG_E_LOCKVIOLATION                    = 0x80030021,\n    STG_E_FILEALREADYEXISTS                = 0x80030050,\n    STG_E_INVALIDPARAMETER                 = 0x80030057,\n    STG_E_MEDIUMFULL                       = 0x80030070,\n    STG_E_ABNORMALAPIEXIT                  = 0x800300FA,\n    STG_E_INVALIDHEADER                    = 0x800300FB,\n    STG_E_INVALIDNAME                      = 0x800300FC,\n    STG_E_UNKNOWN                          = 0x800300FD,\n    STG_E_UNIMPLEMENTEDFUNCTION            = 0x800300FE,\n    STG_E_INVALIDFLAG                      = 0x800300FF,\n    STG_E_INUSE                            = 0x80030100,\n    STG_E_NOTCURRENT                       = 0x80030101,\n    STG_E_REVERTED                         = 0x80030102,\n    STG_E_CANTSAVE                         = 0x80030103,\n    STG_E_OLDFORMAT                        = 0x80030104,\n    STG_E_OLDDLL                           = 0x80030105,\n    STG_E_SHAREREQUIRED                    = 0x80030106,\n    STG_E_NOTFILEBASEDSTORAGE              = 0x80030107,\n    STG_E_EXTANTMARSHALLINGS               = 0x80030108,\n    STG_S_CONVERTED                        = 0x00030200,\n\n    OLE_E_FIRST                            = 0x80040000,\n    OLE_S_FIRST                            = 0x00040000,\n    OLE_E_OLEVERB                          = 0x80040000,\n    OLE_S_USEREG                           = 0x00040000,\n    OLE_E_ADVF                             = 0x80040001,\n    OLE_S_STATIC                           = 0x00040001,\n    OLE_E_ENUM_NOMORE                      = 0x80040002,\n    OLE_S_MAC_CLIPFORMAT                   = 0x00040002,\n    OLE_E_ADVISENOTSUPPORTED               = 0x80040003,\n    OLE_E_NOCONNECTION                     = 0x80040004,\n    OLE_E_NOTRUNNING                       = 0x80040005,\n    OLE_E_NOCACHE                          = 0x80040006,\n    OLE_E_BLANK                            = 0x80040007,\n    OLE_E_CLASSDIFF                        = 0x80040008,\n    OLE_E_CANT_GETMONIKER                  = 0x80040009,\n    OLE_E_CANT_BINDTOSOURCE                = 0x8004000A,\n    OLE_E_STATIC                           = 0x8004000B,\n    OLE_E_PROMPTSAVECANCELLED              = 0x8004000C,\n    OLE_E_INVALIDRECT                      = 0x8004000D,\n    OLE_E_WRONGCOMPOBJ                     = 0x8004000E,\n    OLE_E_INVALIDHWND                      = 0x8004000F,\n    OLE_E_NOT_INPLACEACTIVE                = 0x80040010,\n    OLE_E_CANTCONVERT                      = 0x80040011,\n    OLE_E_NOSTORAGE                        = 0x80040012,\n\n    DV_E_FORMATETC                         = 0x80040064,\n    DV_E_DVTARGETDEVICE                    = 0x80040065,\n    DV_E_STGMEDIUM                         = 0x80040066,\n    DV_E_STATDATA                          = 0x80040067,\n    DV_E_LINDEX                            = 0x80040068,\n    DV_E_TYMED                             = 0x80040069,\n    DV_E_CLIPFORMAT                        = 0x8004006A,\n    DV_E_DVASPECT                          = 0x8004006B,\n    DV_E_DVTARGETDEVICE_SIZE               = 0x8004006C,\n    DV_E_NOIVIEWOBJECT                     = 0x8004006D,\n\n    OLE_E_LAST                             = 0x800400FF,\n    OLE_S_LAST                             = 0x000400FF,\n    DRAGDROP_E_FIRST                       = 0x80040100,\n    DRAGDROP_S_FIRST                       = 0x00040100,\n    DRAGDROP_E_NOTREGISTERED               = 0x80040100,\n    DRAGDROP_S_DROP                        = 0x00040100,\n    DRAGDROP_E_ALREADYREGISTERED           = 0x80040101,\n    DRAGDROP_S_CANCEL                      = 0x00040101,\n    DRAGDROP_E_INVALIDHWND                 = 0x80040102,\n    DRAGDROP_S_USEDEFAULTCURSORS           = 0x00040102,\n    DRAGDROP_E_LAST                        = 0x8004010F,\n    DRAGDROP_S_LAST                        = 0x0004010F,\n    CLASSFACTORY_E_FIRST                   = 0x80040110,\n    CLASSFACTORY_S_FIRST                   = 0x00040110,\n    CLASS_E_NOAGGREGATION                  = 0x80040110,\n    CLASS_E_CLASSNOTAVAILABLE              = 0x80040111,\n    CLASSFACTORY_E_LAST                    = 0x8004011F,\n    CLASSFACTORY_S_LAST                    = 0x0004011F,\n    MARSHAL_E_FIRST                        = 0x80040120,\n    MARSHAL_S_FIRST                        = 0x00040120,\n    MARSHAL_E_LAST                         = 0x8004012F,\n    MARSHAL_S_LAST                         = 0x0004012F,\n    DATA_E_FIRST                           = 0x80040130,\n    DATA_S_FIRST                           = 0x00040130,\n    DATA_S_SAMEFORMATETC                   = 0x00040130,\n    DATA_E_LAST                            = 0x8004013F,\n    DATA_S_LAST                            = 0x0004013F,\n    VIEW_E_FIRST                           = 0x80040140,\n    VIEW_S_FIRST                           = 0x00040140,\n    VIEW_E_DRAW                            = 0x80040140,\n    VIEW_S_ALREADY_FROZEN                  = 0x00040140,\n    VIEW_E_LAST                            = 0x8004014F,\n    VIEW_S_LAST                            = 0x0004014F,\n    REGDB_E_FIRST                          = 0x80040150,\n    REGDB_S_FIRST                          = 0x00040150,\n    REGDB_E_READREGDB                      = 0x80040150,\n    REGDB_E_WRITEREGDB                     = 0x80040151,\n    REGDB_E_KEYMISSING                     = 0x80040152,\n    REGDB_E_INVALIDVALUE                   = 0x80040153,\n    REGDB_E_CLASSNOTREG                    = 0x80040154,\n    REGDB_E_IIDNOTREG                      = 0x80040155,\n    REGDB_E_LAST                           = 0x8004015F,\n    REGDB_S_LAST                           = 0x0004015F,\n    CACHE_E_FIRST                          = 0x80040170,\n    CACHE_S_FIRST                          = 0x00040170,\n    CACHE_E_NOCACHE_UPDATED                = 0x80040170,\n    CACHE_S_FORMATETC_NOTSUPPORTED         = 0x00040170,\n    CACHE_S_SAMECACHE                      = 0x00040171,\n    CACHE_S_SOMECACHES_NOTUPDATED          = 0x00040172,\n    CACHE_E_LAST                           = 0x8004017F,\n    CACHE_S_LAST                           = 0x0004017F,\n    OLEOBJ_E_FIRST                         = 0x80040180,\n    OLEOBJ_S_FIRST                         = 0x00040180,\n    OLEOBJ_E_NOVERBS                       = 0x80040180,\n    OLEOBJ_S_INVALIDVERB                   = 0x00040180,\n    OLEOBJ_E_INVALIDVERB                   = 0x80040181,\n    OLEOBJ_S_CANNOT_DOVERB_NOW             = 0x00040181,\n    OLEOBJ_S_INVALIDHWND                   = 0x00040182,\n    OLEOBJ_E_LAST                          = 0x8004018F,\n    OLEOBJ_S_LAST                          = 0x0004018F,\n    CLIENTSITE_E_FIRST                     = 0x80040190,\n    CLIENTSITE_S_FIRST                     = 0x00040190,\n    CLIENTSITE_E_LAST                      = 0x8004019F,\n    CLIENTSITE_S_LAST                      = 0x0004019F,\n    INPLACE_E_NOTUNDOABLE                  = 0x800401A0,\n    INPLACE_E_FIRST                        = 0x800401A0,\n    INPLACE_S_FIRST                        = 0x000401A0,\n    INPLACE_S_TRUNCATED                    = 0x000401A0,\n    INPLACE_E_NOTOOLSPACE                  = 0x800401A1,\n    INPLACE_E_LAST                         = 0x800401AF,\n    INPLACE_S_LAST                         = 0x000401AF,\n    ENUM_E_FIRST                           = 0x800401B0,\n    ENUM_S_FIRST                           = 0x000401B0,\n    ENUM_E_LAST                            = 0x800401BF,\n    ENUM_S_LAST                            = 0x000401BF,\n    CONVERT10_E_FIRST                      = 0x800401C0,\n    CONVERT10_S_FIRST                      = 0x000401C0,\n    CONVERT10_E_OLESTREAM_GET              = 0x800401C0,\n    CONVERT10_S_NO_PRESENTATION            = 0x000401C0,\n    CONVERT10_E_OLESTREAM_PUT              = 0x800401C1,\n    CONVERT10_E_OLESTREAM_FMT              = 0x800401C2,\n    CONVERT10_E_OLESTREAM_BITMAP_TO_DIB    = 0x800401C3,\n    CONVERT10_E_STG_FMT                    = 0x800401C4,\n    CONVERT10_E_STG_NO_STD_STREAM          = 0x800401C5,\n    CONVERT10_E_STG_DIB_TO_BITMAP          = 0x800401C6,\n    CONVERT10_E_LAST                       = 0x800401CF,\n    CONVERT10_S_LAST                       = 0x000401CF,\n    CLIPBRD_E_FIRST                        = 0x800401D0,\n    CLIPBRD_S_FIRST                        = 0x000401D0,\n    CLIPBRD_E_CANT_OPEN                    = 0x800401D0,\n    CLIPBRD_E_CANT_EMPTY                   = 0x800401D1,\n    CLIPBRD_E_CANT_SET                     = 0x800401D2,\n    CLIPBRD_E_BAD_DATA                     = 0x800401D3,\n    CLIPBRD_E_CANT_CLOSE                   = 0x800401D4,\n    CLIPBRD_E_LAST                         = 0x800401DF,\n    CLIPBRD_S_LAST                         = 0x000401DF,\n    MK_E_FIRST                             = 0x800401E0,\n    MK_S_FIRST                             = 0x000401E0,\n    MK_E_CONNECTMANUALLY                   = 0x800401E0,\n    MK_E_EXCEEDEDDEADLINE                  = 0x800401E1,\n    MK_E_NEEDGENERIC                       = 0x800401E2,\n    MK_S_REDUCED_TO_SELF                   = 0x000401E2,\n    MK_E_UNAVAILABLE                       = 0x800401E3,\n    MK_E_SYNTAX                            = 0x800401E4,\n    MK_S_ME                                = 0x000401E4,\n    MK_E_NOOBJECT                          = 0x800401E5,\n    MK_S_HIM                               = 0x000401E5,\n    MK_E_INVALIDEXTENSION                  = 0x800401E6,\n    MK_S_US                                = 0x000401E6,\n    MK_E_INTERMEDIATEINTERFACENOTSUPPORTED = 0x800401E7,\n    MK_S_MONIKERALREADYREGISTERED          = 0x000401E7,\n    MK_E_NOTBINDABLE                       = 0x800401E8,\n    MK_E_NOTBOUND                          = 0x800401E9,\n    MK_E_CANTOPENFILE                      = 0x800401EA,\n    MK_E_MUSTBOTHERUSER                    = 0x800401EB,\n    MK_E_NOINVERSE                         = 0x800401EC,\n    MK_E_NOSTORAGE                         = 0x800401ED,\n    MK_E_NOPREFIX                          = 0x800401EE,\n    MK_E_LAST                              = 0x800401EF,\n    MK_S_LAST                              = 0x000401EF,\n    MK_E_ENUMERATION_FAILED                = 0x800401EF,\n    CO_E_FIRST                             = 0x800401F0,\n    CO_S_FIRST                             = 0x000401F0,\n    CO_E_NOTINITIALIZED                    = 0x800401F0,\n    CO_E_ALREADYINITIALIZED                = 0x800401F1,\n    CO_E_CANTDETERMINECLASS                = 0x800401F2,\n    CO_E_CLASSSTRING                       = 0x800401F3,\n    CO_E_IIDSTRING                         = 0x800401F4,\n    CO_E_APPNOTFOUND                       = 0x800401F5,\n    CO_E_APPSINGLEUSE                      = 0x800401F6,\n    CO_E_ERRORINAPP                        = 0x800401F7,\n    CO_E_DLLNOTFOUND                       = 0x800401F8,\n    CO_E_ERRORINDLL                        = 0x800401F9,\n    CO_E_WRONGOSFORAPP                     = 0x800401FA,\n    CO_E_OBJNOTREG                         = 0x800401FB,\n    CO_E_OBJISREG                          = 0x800401FC,\n    CO_E_OBJNOTCONNECTED                   = 0x800401FD,\n    CO_E_APPDIDNTREG                       = 0x800401FE,\n    CO_E_LAST                              = 0x800401FF,\n    CO_S_LAST                              = 0x000401FF,\n    CO_E_RELEASED                          = 0x800401FF,\n\n    CO_E_CLASS_CREATE_FAILED               = 0x80080001,\n    CO_E_SCM_ERROR                         = 0x80080002,\n    CO_E_SCM_RPC_FAILURE                   = 0x80080003,\n    CO_E_BAD_PATH                          = 0x80080004,\n    CO_E_SERVER_EXEC_FAILURE               = 0x80080005,\n    CO_E_OBJSRV_RPC_FAILURE                = 0x80080006,\n    MK_E_NO_NORMALIZED                     = 0x80080007,\n    CO_E_SERVER_STOPPING                   = 0x80080008,\n    MEM_E_INVALID_ROOT                     = 0x80080009,\n    MEM_E_INVALID_LINK                     = 0x80080010,\n    MEM_E_INVALID_SIZE                     = 0x80080011,\n    CO_S_NOTALLINTERFACES                  = 0x00080012,\n\n    NTE_BAD_UID                            = 0x80090001,\n    NTE_BAD_HASH                           = 0x80090002,\n    NTE_BAD_KEY                            = 0x80090003,\n    NTE_BAD_LEN                            = 0x80090004,\n    NTE_BAD_DATA                           = 0x80090005,\n    NTE_BAD_SIGNATURE                      = 0x80090006,\n    NTE_BAD_VER                            = 0x80090007,\n    NTE_BAD_ALGID                          = 0x80090008,\n    NTE_BAD_FLAGS                          = 0x80090009,\n    NTE_BAD_TYPE                           = 0x8009000A,\n    NTE_BAD_KEY_STATE                      = 0x8009000B,\n    NTE_BAD_HASH_STATE                     = 0x8009000C,\n    NTE_NO_KEY                             = 0x8009000D,\n    NTE_NO_MEMORY                          = 0x8009000E,\n    NTE_EXISTS                             = 0x8009000F,\n    NTE_PERM                               = 0x80090010,\n    NTE_NOT_FOUND                          = 0x80090011,\n    NTE_DOUBLE_ENCRYPT                     = 0x80090012,\n    NTE_BAD_PROVIDER                       = 0x80090013,\n    NTE_BAD_PROV_TYPE                      = 0x80090014,\n    NTE_BAD_PUBLIC_KEY                     = 0x80090015,\n    NTE_BAD_KEYSET                         = 0x80090016,\n    NTE_PROV_TYPE_NOT_DEF                  = 0x80090017,\n    NTE_PROV_TYPE_ENTRY_BAD                = 0x80090018,\n    NTE_KEYSET_NOT_DEF                     = 0x80090019,\n    NTE_KEYSET_ENTRY_BAD                   = 0x8009001A,\n    NTE_PROV_TYPE_NO_MATCH                 = 0x8009001B,\n    NTE_SIGNATURE_FILE_BAD                 = 0x8009001C,\n    NTE_PROVIDER_DLL_FAIL                  = 0x8009001D,\n    NTE_PROV_DLL_NOT_FOUND                 = 0x8009001E,\n    NTE_BAD_KEYSET_PARAM                   = 0x8009001F,\n    NTE_FAIL                               = 0x80090020,\n    NTE_SYS_ERR                            = 0x80090021\n}\n\n\nenum : uint {\n    SEVERITY_SUCCESS = 0,\n    SEVERITY_ERROR   = 1\n}\n\nenum : uint {\n    FACILITY_NULL     =   0,\n    FACILITY_RPC,\n    FACILITY_DISPATCH,\n    FACILITY_STORAGE,\n    FACILITY_ITF,  // =   4\n    FACILITY_WIN32    =   7,\n    FACILITY_WINDOWS  =   8,\n    FACILITY_CONTROL  =  10,\n    FACILITY_NT_BIT   = 0x10000000\n}\n\n// C Macros\n\npure nothrow @nogc {\n    bool SUCCEEDED(HRESULT Status) {\n        return Status >= 0;\n    }\n\n    bool FAILED(HRESULT Status) {\n        return Status < 0;\n    }\n\n    bool IS_ERROR(HRESULT Status) {\n        return (Status >>> 31) == SEVERITY_ERROR;\n    }\n\n    ushort HRESULT_CODE(HRESULT r) {\n        return cast(ushort) (r & 0xFFFF);\n    }\n\n    ushort SCODE_CODE(SCODE r) {\n        return cast(ushort) (r & 0xFFFF);\n    }\n\n    ushort HRESULT_FACILITY(HRESULT r) {\n        return cast(ushort) ((r>>16) & 0x1fff);\n    }\n\n    ushort SCODE_FACILITY(SCODE r) {\n        return cast(ushort) ((r>>16) & 0x1fff);\n    }\n\n    ushort HRESULT_SEVERITY(HRESULT r) {\n        return cast(ushort) ((r>>31) & 0x1);\n    }\n\n    ushort SCODE_SEVERITY(SCODE r) {\n        return cast(ushort) ((r>>31) & 0x1);\n    }\n\n    HRESULT MAKE_HRESULT(bool s, uint f, uint c) {\n        return (s << 31) | (f << 16) | c;\n    }\n\n    SCODE MAKE_SCODE(bool s, uint f, uint c) {\n        return (s << 31) | (f << 16) | c;\n    }\n\n    SCODE GetScode(HRESULT hr) {\n        return hr;\n    }\n\n    HRESULT ResultFromScode(SCODE c) {\n        return c;\n    }\n\n    HRESULT HRESULT_FROM_NT(HRESULT x) {\n        return x | FACILITY_NT_BIT;\n    }\n\n    HRESULT HRESULT_FROM_WIN32(HRESULT x) {\n        return  x ? (x & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000 : 0;\n    }\n\n    HRESULT PropagateResult(HRESULT hrPrevious, SCODE scBase) {\n        return scBase;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/wingdi.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_wingdi.d)\n */\nmodule core.sys.windows.wingdi;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"gdi32\");\n\n// FIXME: clean up Windows version support\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winver;\n\n// BITMAPINFOHEADER.biCompression\nenum : DWORD {\n    BI_RGB = 0,\n    BI_RLE8,\n    BI_RLE4,\n    BI_BITFIELDS,\n    BI_JPEG,\n    BI_PNG\n}\n\n// ---\n// COLORADJUSTMENT -- only for NT 3.1+, Win2000+\nenum WORD\n    CA_NEGATIVE   = 1,\n    CA_LOG_FILTER = 2;\n\n// COLORADJUSTMENT\nenum : WORD  {\n    ILLUMINANT_DEVICE_DEFAULT = 0,\n    ILLUMINANT_A,\n    ILLUMINANT_B,\n    ILLUMINANT_C,\n    ILLUMINANT_D50,\n    ILLUMINANT_D55,\n    ILLUMINANT_D65,\n    ILLUMINANT_D75,\n    ILLUMINANT_F2,\n    ILLUMINANT_MAX_INDEX   = ILLUMINANT_F2,\n    ILLUMINANT_TUNGSTEN    = ILLUMINANT_A,\n    ILLUMINANT_DAYLIGHT    = ILLUMINANT_C,\n    ILLUMINANT_FLUORESCENT = ILLUMINANT_F2,\n    ILLUMINANT_NTSC        = ILLUMINANT_C\n}\n\nenum {\n    RGB_GAMMA_MIN       = 2500,\n    RGB_GAMMA_MAX       = 65000,\n    REFERENCE_WHITE_MIN = 6000,\n    REFERENCE_WHITE_MAX = 10000,\n    REFERENCE_BLACK_MIN = 0,\n    REFERENCE_BLACK_MAX = 4000,\n    COLOR_ADJ_MIN       = -100,\n    COLOR_ADJ_MAX       = 100,\n}\n//---\n\n/* FIXME: move to core.sys.windows.winuser ? */\n// DrawIconEx()\nenum : UINT {\n    DI_MASK        = 1,\n    DI_IMAGE       = 2,\n    DI_NORMAL      = 3,\n    DI_COMPAT      = 4,\n    DI_DEFAULTSIZE = 8\n}\n\n// DOCINFO\nenum : DWORD {\n    DI_APPBANDING = 1,\n    DI_ROPS_READ_DESTINATION = 2,\n}\n\n// ENHMETAHEADER\nenum : DWORD {\n    EMR_HEADER = 1,\n    EMR_POLYBEZIER,\n    EMR_POLYGON,\n    EMR_POLYLINE,\n    EMR_POLYBEZIERTO,\n    EMR_POLYLINETO,\n    EMR_POLYPOLYLINE,\n    EMR_POLYPOLYGON,\n    EMR_SETWINDOWEXTEX,\n    EMR_SETWINDOWORGEX,\n    EMR_SETVIEWPORTEXTEX,\n    EMR_SETVIEWPORTORGEX,\n    EMR_SETBRUSHORGEX,\n    EMR_EOF,\n    EMR_SETPIXELV,\n    EMR_SETMAPPERFLAGS,\n    EMR_SETMAPMODE,\n    EMR_SETBKMODE,\n    EMR_SETPOLYFILLMODE,\n    EMR_SETROP2,\n    EMR_SETSTRETCHBLTMODE,\n    EMR_SETTEXTALIGN,\n    EMR_SETCOLORADJUSTMENT,\n    EMR_SETTEXTCOLOR,\n    EMR_SETBKCOLOR,\n    EMR_OFFSETCLIPRGN,\n    EMR_MOVETOEX,\n    EMR_SETMETARGN,\n    EMR_EXCLUDECLIPRECT,\n    EMR_INTERSECTCLIPRECT,\n    EMR_SCALEVIEWPORTEXTEX,\n    EMR_SCALEWINDOWEXTEX,\n    EMR_SAVEDC,\n    EMR_RESTOREDC,\n    EMR_SETWORLDTRANSFORM,\n    EMR_MODIFYWORLDTRANSFORM,\n    EMR_SELECTOBJECT,\n    EMR_CREATEPEN,\n    EMR_CREATEBRUSHINDIRECT,\n    EMR_DELETEOBJECT,\n    EMR_ANGLEARC,\n    EMR_ELLIPSE,\n    EMR_RECTANGLE,\n    EMR_ROUNDRECT,\n    EMR_ARC,\n    EMR_CHORD,\n    EMR_PIE,\n    EMR_SELECTPALETTE,\n    EMR_CREATEPALETTE,\n    EMR_SETPALETTEENTRIES,\n    EMR_RESIZEPALETTE,\n    EMR_REALIZEPALETTE,\n    EMR_EXTFLOODFILL,\n    EMR_LINETO,\n    EMR_ARCTO,\n    EMR_POLYDRAW,\n    EMR_SETARCDIRECTION,\n    EMR_SETMITERLIMIT,\n    EMR_BEGINPATH,\n    EMR_ENDPATH,\n    EMR_CLOSEFIGURE,\n    EMR_FILLPATH,\n    EMR_STROKEANDFILLPATH,\n    EMR_STROKEPATH,\n    EMR_FLATTENPATH,\n    EMR_WIDENPATH,\n    EMR_SELECTCLIPPATH,\n    EMR_ABORTPATH, // 68\n    // reserved 69\n    EMR_GDICOMMENT = 70,\n    EMR_FILLRGN,\n    EMR_FRAMERGN,\n    EMR_INVERTRGN,\n    EMR_PAINTRGN,\n    EMR_EXTSELECTCLIPRGN,\n    EMR_BITBLT,\n    EMR_STRETCHBLT,\n    EMR_MASKBLT,\n    EMR_PLGBLT,\n    EMR_SETDIBITSTODEVICE,\n    EMR_STRETCHDIBITS,\n    EMR_EXTCREATEFONTINDIRECTW,\n    EMR_EXTTEXTOUTA,\n    EMR_EXTTEXTOUTW,\n    EMR_POLYBEZIER16,\n    EMR_POLYGON16,\n    EMR_POLYLINE16,\n    EMR_POLYBEZIERTO16,\n    EMR_POLYLINETO16,\n    EMR_POLYPOLYLINE16,\n    EMR_POLYPOLYGON16,\n    EMR_POLYDRAW16,\n    EMR_CREATEMONOBRUSH,\n    EMR_CREATEDIBPATTERNBRUSHPT,\n    EMR_EXTCREATEPEN,\n    EMR_POLYTEXTOUTA,\n    EMR_POLYTEXTOUTW, // 97\n    EMR_SETICMMODE,\n    EMR_CREATECOLORSPACE,\n    EMR_SETCOLORSPACE,\n    EMR_DELETECOLORSPACE,\n    EMR_GLSRECORD,\n    EMR_GLSBOUNDEDRECORD,\n    EMR_PIXELFORMAT, // = 104\n    // reserved 105 - 110\n    EMR_COLORCORRECTPALETTE = 111,\n    EMR_SETICMPROFILEA,\n    EMR_SETICMPROFILEW,\n    EMR_ALPHABLEND,\n    EMR_SETLAYOUT,\n    EMR_TRANSPARENTBLT, // 116\n    // reserved 117\n    EMR_GRADIENTFILL = 118,\n    // reserved 119, 120\n    EMR_COLORMATCHTOTARGETW = 121,\n    EMR_CREATECOLORSPACEW // 122\n}\n\nenum EMR_MIN = EMR_HEADER;\n\nstatic if (_WIN32_WINNT >= 0x500) {\nenum EMR_MAX = EMR_CREATECOLORSPACEW;\n} else {\nenum EMR_MAX = EMR_PIXELFORMAT;\n}\n\n// ENHMETAHEADER.dSignature, ENHMETAHEADER3.dSignature,\n// EMRFORMAT.dSignature\nenum : DWORD {\n    ENHMETA_SIGNATURE = 1179469088,\n    EPS_SIGNATURE     = 0x46535045\n}\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    // AddFontResourceEx()\n    enum : DWORD {\n        FR_PRIVATE  = 0x10,\n        FR_NOT_ENUM = 0x20\n    }\n}\n\nenum {\n    META_SAVEDC                = 0x1E,\n    META_REALIZEPALETTE        = 0x35,\n    META_SETPALENTRIES         = 0x37,\n    META_CREATEPALETTE         = 0xf7,\n    META_SETBKMODE             = 0x102,\n    META_SETMAPMODE            = 0x103,\n    META_SETROP2               = 0x104,\n    META_SETRELABS             = 0x105,\n    META_SETPOLYFILLMODE       = 0x106,\n    META_SETSTRETCHBLTMODE     = 0x107,\n    META_SETTEXTCHAREXTRA      = 0x108,\n    META_RESTOREDC             = 0x127,\n    META_INVERTREGION          = 0x12A,\n    META_PAINTREGION           = 0x12B,\n    META_SELECTCLIPREGION      = 0x12C,\n    META_SELECTOBJECT          = 0x12D,\n    META_SETTEXTALIGN          = 0x12E,\n    META_RESIZEPALETTE         = 0x139,\n    META_DIBCREATEPATTERNBRUSH = 0x142,\n    META_SETLAYOUT             = 0x149,\n    META_DELETEOBJECT          = 0x1F0,\n    META_CREATEPATTERNBRUSH    = 0x1F9,\n    META_SETBKCOLOR            = 0x201,\n    META_SETTEXTCOLOR          = 0x209,\n    META_SETTEXTJUSTIFICATION  = 0x20A,\n    META_SETWINDOWORG          = 0x20B,\n    META_SETWINDOWEXT          = 0x20C,\n    META_SETVIEWPORTORG        = 0x20D,\n    META_SETVIEWPORTEXT        = 0x20E,\n    META_OFFSETWINDOWORG       = 0x20F,\n    META_OFFSETVIEWPORTORG     = 0x211,\n    META_LINETO                = 0x213,\n    META_MOVETO                = 0x214,\n    META_OFFSETCLIPRGN         = 0x220,\n    META_FILLREGION            = 0x228,\n    META_SETMAPPERFLAGS        = 0x231,\n    META_SELECTPALETTE         = 0x234,\n    META_CREATEPENINDIRECT     = 0x2FA,\n    META_CREATEFONTINDIRECT    = 0x2FB,\n    META_CREATEBRUSHINDIRECT   = 0x2FC,\n    META_POLYGON               = 0x324,\n    META_POLYLINE              = 0x325,\n    META_SCALEWINDOWEXT        = 0x410,\n    META_SCALEVIEWPORTEXT      = 0x412,\n    META_EXCLUDECLIPRECT       = 0x415,\n    META_INTERSECTCLIPRECT     = 0x416,\n    META_ELLIPSE               = 0x418,\n    META_FLOODFILL             = 0x419,\n    META_RECTANGLE             = 0x41B,\n    META_SETPIXEL              = 0x41F,\n    META_FRAMEREGION           = 0x429,\n    META_ANIMATEPALETTE        = 0x436,\n    META_TEXTOUT               = 0x521,\n    META_POLYPOLYGON           = 0x538,\n    META_EXTFLOODFILL          = 0x548,\n    META_ROUNDRECT             = 0x61C,\n    META_PATBLT                = 0x61D,\n    META_ESCAPE                = 0x626,\n    META_CREATEREGION          = 0x6FF,\n    META_ARC                   = 0x817,\n    META_PIE                   = 0x81A,\n    META_CHORD                 = 0x830,\n    META_BITBLT                = 0x922,\n    META_DIBBITBLT             = 0x940,\n    META_EXTTEXTOUT            = 0xA32,\n    META_STRETCHBLT            = 0xB23,\n    META_DIBSTRETCHBLT         = 0xB41,\n    META_SETDIBTODEV           = 0xD33,\n    META_STRETCHDIB            = 0xF43\n}\n\n// EMRPOLYDRAW\nenum : BYTE {\n    PT_CLOSEFIGURE = 1,\n    PT_LINETO      = 2,\n    PT_BEZIERTO    = 4,\n    PT_MOVETO      = 6\n}\n\n// ----\n// PIXELFORMATDESCRIPTOR.iPixelType\nenum : BYTE {\n    PFD_TYPE_RGBA       = 0,\n    PFD_TYPE_COLORINDEX = 1\n}\n\n//deprecated {\n// PIXELFORMATDESCRIPTOR.\nenum byte\n    PFD_MAIN_PLANE     = 0,\n    PFD_OVERLAY_PLANE  = 1,\n    PFD_UNDERLAY_PLANE = -1;\n//}\n// PIXELFORMATDESCRIPTOR.dwFlags\nenum DWORD\n    PFD_DOUBLEBUFFER          = 0x00000001,\n    PFD_STEREO                = 0x00000002,\n    PFD_DRAW_TO_WINDOW        = 0x00000004,\n    PFD_DRAW_TO_BITMAP        = 0x00000008,\n    PFD_SUPPORT_GDI           = 0x00000010,\n    PFD_SUPPORT_OPENGL        = 0x00000020,\n    PFD_GENERIC_FORMAT        = 0x00000040,\n    PFD_NEED_PALETTE          = 0x00000080,\n    PFD_NEED_SYSTEM_PALETTE   = 0x00000100,\n    PFD_SWAP_EXCHANGE         = 0x00000200,\n    PFD_SWAP_COPY             = 0x00000400,\n    PFD_SWAP_LAYER_BUFFERS    = 0x00000800,\n    PFD_GENERIC_ACCELERATED   = 0x00001000,\n    PFD_SUPPORT_DIRECTDRAW    = 0x00002000,\n    PFD_DIRECT3D_ACCELERATED  = 0x00004000,\n    PFD_SUPPORT_COMPOSITION   = 0x00008000,\n    /* PIXELFORMATDESCRIPTOR flags for use in ChoosePixelFormat only */\n    PFD_DEPTH_DONTCARE        = 0x20000000,\n    PFD_DOUBLEBUFFER_DONTCARE = 0x40000000,\n    PFD_STEREO_DONTCARE       = 0x80000000;\n\n// ----\n\nenum DWORD\n    BLACKNESS   = 0x000042,\n    NOTSRCERASE = 0x1100A6,\n    NOTSRCCOPY  = 0x330008,\n    SRCERASE    = 0x440328,\n    DSTINVERT   = 0x550009,\n    PATINVERT   = 0x5A0049,\n    SRCINVERT   = 0x660046,\n    SRCAND      = 0x8800C6,\n    MERGEPAINT  = 0xBB0226,\n    MERGECOPY   = 0xC000CA,\n    SRCCOPY     = 0xCC0020,\n    SRCPAINT    = 0xEE0086,\n    PATCOPY     = 0xF00021,\n    PATPAINT    = 0xFB0A09,\n    WHITENESS   = 0xFF0062;\nstatic if (_WIN32_WINNT >= 0x500) {\nenum DWORD\n        NOMIRRORBITMAP = 0x80000000,\n        CAPTUREBLT     = 0x40000000;\n}\n\n// GetROP2(), SetROP2()\nenum : int {\n    R2_BLACK       = 1,\n    R2_NOTMERGEPEN = 2,\n    R2_MASKNOTPEN  = 3,\n    R2_NOTCOPYPEN  = 4,\n    R2_MASKPENNOT  = 5,\n    R2_NOT         = 6,\n    R2_XORPEN      = 7,\n    R2_NOTMASKPEN  = 8,\n    R2_MASKPEN     = 9,\n    R2_NOTXORPEN   = 10,\n    R2_NOP         = 11,\n    R2_MERGENOTPEN = 12,\n    R2_COPYPEN     = 13,\n    R2_MERGEPENNOT = 14,\n    R2_MERGEPEN    = 15,\n    R2_WHITE       = 16\n}\n\nenum R2_LAST = R2_WHITE;\n\n// CheckColorsInGamut()\nenum ubyte\n    CM_IN_GAMUT     = 0,\n    CM_OUT_OF_GAMUT = 255;\n\n/* UpdateICMRegKey Constants               */\nenum int\n    ICM_ADDPROFILE = 1,\n    ICM_DELETEPROFILE = 2,\n    ICM_QUERYPROFILE = 3,\n    ICM_SETDEFAULTPROFILE = 4,\n    ICM_REGISTERICMATCHER = 5,\n    ICM_UNREGISTERICMATCHER = 6,\n    ICM_QUERYMATCH = 7;\n\nenum : int {\n    RGN_AND  = 1,\n    RGN_OR   = 2,\n    RGN_XOR  = 3,\n    RGN_DIFF = 4,\n    RGN_COPY = 5\n}\n\nenum RGN_MIN = RGN_AND;\nenum RGN_MAX = RGN_COPY;\n\n// Return values for CombineRgn()\nenum {\n    NULLREGION    = 1,\n    SIMPLEREGION  = 2,\n    COMPLEXREGION = 3\n}\n\nenum ERROR = 0;\nalias ERROR RGN_ERROR;\n\n// CreateDIBitmap()\nenum DWORD CBM_INIT = 4;\n\n// CreateDIBitmap()\nenum : UINT {\n    DIB_RGB_COLORS = 0,\n    DIB_PAL_COLORS = 1\n}\n\n// ---\n//  Values for LOGFONT and CreateFont()\n\n// FIXME: For D, replace with lfFaceName.length()\nenum LF_FACESIZE     = 32;\nenum LF_FULLFACESIZE = 64;\n\n// FIXME: Not needed for D, only EXTLOGFONT\nenum ELF_VENDOR_SIZE = 4;\n\n// ???\nenum ELF_VERSION = 0;\nenum ELF_CULTURE_LATIN = 0;\n\n// LOGFONT.lfWeight\nenum LONG\n    FW_DONTCARE   = 0,\n    FW_THIN       = 100,\n    FW_EXTRALIGHT = 200,\n    FW_ULTRALIGHT = FW_EXTRALIGHT,\n    FW_LIGHT      = 300,\n    FW_NORMAL     = 400,\n    FW_REGULAR    = FW_NORMAL,\n    FW_MEDIUM     = 500,\n    FW_SEMIBOLD   = 600,\n    FW_DEMIBOLD   = FW_SEMIBOLD,\n    FW_BOLD       = 700,\n    FW_EXTRABOLD  = 800,\n    FW_ULTRABOLD  = FW_EXTRABOLD,\n    FW_HEAVY      = 900,\n    FW_BLACK      = FW_HEAVY;\n\n// LOGFONT.lfCharSet\nenum : DWORD {\n    ANSI_CHARSET        = 0,\n    DEFAULT_CHARSET     = 1,\n    SYMBOL_CHARSET      = 2,\n    MAC_CHARSET         = 77,\n    SHIFTJIS_CHARSET    = 128,\n    HANGEUL_CHARSET     = 129,\n    HANGUL_CHARSET      = 129,\n    JOHAB_CHARSET       = 130,\n    GB2312_CHARSET      = 134,\n    CHINESEBIG5_CHARSET = 136,\n    GREEK_CHARSET       = 161,\n    TURKISH_CHARSET     = 162,\n    VIETNAMESE_CHARSET  = 163,\n    HEBREW_CHARSET      = 177,\n    ARABIC_CHARSET      = 178,\n    BALTIC_CHARSET      = 186,\n    RUSSIAN_CHARSET     = 204,\n    THAI_CHARSET        = 222,\n    EASTEUROPE_CHARSET  = 238,\n    OEM_CHARSET         = 255\n}\n\n// LOGFONT.lfOutPrecision\nenum : BYTE {\n    OUT_DEFAULT_PRECIS = 0,\n    OUT_STRING_PRECIS,\n    OUT_CHARACTER_PRECIS,\n    OUT_STROKE_PRECIS,\n    OUT_TT_PRECIS,\n    OUT_DEVICE_PRECIS,\n    OUT_RASTER_PRECIS,\n    OUT_TT_ONLY_PRECIS,\n    OUT_OUTLINE_PRECIS,\n    OUT_SCREEN_OUTLINE_PRECIS,\n    OUT_PS_ONLY_PRECIS, // 10\n}\n\n// LOGFONT.lfClipPrecision\nenum : BYTE  {\n    CLIP_DEFAULT_PRECIS   = 0,\n    CLIP_CHARACTER_PRECIS = 1,\n    CLIP_STROKE_PRECIS    = 2,\n    CLIP_MASK             = 15,\n    CLIP_LH_ANGLES        = 16,\n    CLIP_TT_ALWAYS        = 32,\n    CLIP_DFA_DISABLE      = 64,\n    CLIP_EMBEDDED         = 128\n}\n\n// LOGFONT.lfQuality\nenum : BYTE {\n    DEFAULT_QUALITY = 0,\n    DRAFT_QUALITY,\n    PROOF_QUALITY,\n    NONANTIALIASED_QUALITY,\n    ANTIALIASED_QUALITY\n}\n\n// LOGFONT.lfPitchAndFamily\n\nenum BYTE\n    DEFAULT_PITCH  = 0,\n    FIXED_PITCH    = 1,\n    VARIABLE_PITCH = 2,\n    MONO_FONT      = 8,\n    FF_DONTCARE    = 0,\n    FF_ROMAN       = 16,\n    FF_SWISS       = 32,\n    FF_SCRIPT      = 64,\n    FF_MODERN      = 48,\n    FF_DECORATIVE  = 80;\n\n// ----\n// Enums for the PANOSE struct\n\nenum PANOSE_COUNT=10;\n\nenum {\n    PAN_FAMILYTYPE_INDEX = 0,\n    PAN_SERIFSTYLE_INDEX,\n    PAN_WEIGHT_INDEX,\n    PAN_PROPORTION_INDEX,\n    PAN_CONTRAST_INDEX,\n    PAN_STROKEVARIATION_INDEX,\n    PAN_ARMSTYLE_INDEX,\n    PAN_LETTERFORM_INDEX,\n    PAN_MIDLINE_INDEX,\n    PAN_XHEIGHT_INDEX\n}\n\nenum PAN_CULTURE_LATIN=0;\n\n// NOTE: the first two values (PAN_ANY and PAN_NO_FIT) apply to all these enums!\nenum : BYTE {\n    PAN_ANY    = 0,\n    PAN_NO_FIT = 1,\n}\n\nenum : BYTE {\n    PAN_FAMILY_TEXT_DISPLAY = 2,\n    PAN_FAMILY_SCRIPT,\n    PAN_FAMILY_DECORATIVE,\n    PAN_FAMILY_PICTORIAL\n}\nenum : BYTE {\n    PAN_SERIF_COVE = 2,\n    PAN_SERIF_OBTUSE_COVE,\n    PAN_SERIF_SQUARE_COVE,\n    PAN_SERIF_OBTUSE_SQUARE_COVE,\n    PAN_SERIF_SQUARE,\n    PAN_SERIF_THIN,\n    PAN_SERIF_BONE,\n    PAN_SERIF_EXAGGERATED,\n    PAN_SERIF_TRIANGLE,\n    PAN_SERIF_NORMAL_SANS,\n    PAN_SERIF_OBTUSE_SANS,\n    PAN_SERIF_PERP_SANS,\n    PAN_SERIF_FLARED,\n    PAN_SERIF_ROUNDED\n}\n\nenum : BYTE {\n    PAN_WEIGHT_VERY_LIGHT = 2,\n    PAN_WEIGHT_LIGHT,\n    PAN_WEIGHT_THIN,\n    PAN_WEIGHT_BOOK,\n    PAN_WEIGHT_MEDIUM,\n    PAN_WEIGHT_DEMI,\n    PAN_WEIGHT_BOLD,\n    PAN_WEIGHT_HEAVY,\n    PAN_WEIGHT_BLACK,\n    PAN_WEIGHT_NORD\n}\n\nenum : BYTE {\n    PAN_PROP_OLD_STYLE = 2,\n    PAN_PROP_MODERN,\n    PAN_PROP_EVEN_WIDTH,\n    PAN_PROP_EXPANDED,\n    PAN_PROP_CONDENSED,\n    PAN_PROP_VERY_EXPANDED,\n    PAN_PROP_VERY_CONDENSED,\n    PAN_PROP_MONOSPACED\n}\n\nenum : BYTE {\n    PAN_CONTRAST_NONE = 2,\n    PAN_CONTRAST_VERY_LOW,\n    PAN_CONTRAST_LOW,\n    PAN_CONTRAST_MEDIUM_LOW,\n    PAN_CONTRAST_MEDIUM,\n    PAN_CONTRAST_MEDIUM_HIGH,\n    PAN_CONTRAST_HIGH,\n    PAN_CONTRAST_VERY_HIGH\n}\n\n// PANOSE.bStrokeVariation\nenum : BYTE {\n    PAN_STROKE_GRADUAL_DIAG = 2,\n    PAN_STROKE_GRADUAL_TRAN,\n    PAN_STROKE_GRADUAL_VERT,\n    PAN_STROKE_GRADUAL_HORZ,\n    PAN_STROKE_RAPID_VERT,\n    PAN_STROKE_RAPID_HORZ,\n    PAN_STROKE_INSTANT_VERT\n}\n\n// PANOSE.bArmStyle\nenum : BYTE {\n    PAN_STRAIGHT_ARMS_HORZ = 2,\n    PAN_STRAIGHT_ARMS_WEDGE,\n    PAN_STRAIGHT_ARMS_VERT,\n    PAN_STRAIGHT_ARMS_SINGLE_SERIF,\n    PAN_STRAIGHT_ARMS_DOUBLE_SERIF,\n    PAN_BENT_ARMS_HORZ,\n    PAN_BENT_ARMS_WEDGE,\n    PAN_BENT_ARMS_VERT,\n    PAN_BENT_ARMS_SINGLE_SERIF,\n    PAN_BENT_ARMS_DOUBLE_SERIF\n}\n\n// PANOSE.bLetterForm\nenum : BYTE {\n    PAN_LETT_NORMAL_CONTACT = 2,\n    PAN_LETT_NORMAL_WEIGHTED,\n    PAN_LETT_NORMAL_BOXED,\n    PAN_LETT_NORMAL_FLATTENED,\n    PAN_LETT_NORMAL_ROUNDED,\n    PAN_LETT_NORMAL_OFF_CENTER,\n    PAN_LETT_NORMAL_SQUARE,\n    PAN_LETT_OBLIQUE_CONTACT,\n    PAN_LETT_OBLIQUE_WEIGHTED,\n    PAN_LETT_OBLIQUE_BOXED,\n    PAN_LETT_OBLIQUE_FLATTENED,\n    PAN_LETT_OBLIQUE_ROUNDED,\n    PAN_LETT_OBLIQUE_OFF_CENTER,\n    PAN_LETT_OBLIQUE_SQUARE\n}\n\n// PANOSE.bMidLine\nenum : BYTE {\n    PAN_MIDLINE_STANDARD_TRIMMED = 2,\n    PAN_MIDLINE_STANDARD_POINTED,\n    PAN_MIDLINE_STANDARD_SERIFED,\n    PAN_MIDLINE_HIGH_TRIMMED,\n    PAN_MIDLINE_HIGH_POINTED,\n    PAN_MIDLINE_HIGH_SERIFED,\n    PAN_MIDLINE_CONSTANT_TRIMMED,\n    PAN_MIDLINE_CONSTANT_POINTED,\n    PAN_MIDLINE_CONSTANT_SERIFED,\n    PAN_MIDLINE_LOW_TRIMMED,\n    PAN_MIDLINE_LOW_POINTED,\n    PAN_MIDLINE_LOW_SERIFED\n}\n\n// PANOSE.bXHeight\nenum : BYTE {\n    PAN_XHEIGHT_CONSTANT_SMALL = 2,\n    PAN_XHEIGHT_CONSTANT_STD,\n    PAN_XHEIGHT_CONSTANT_LARGE,\n    PAN_XHEIGHT_DUCKING_SMALL,\n    PAN_XHEIGHT_DUCKING_STD,\n    PAN_XHEIGHT_DUCKING_LARGE\n}\n\n// ----\n// ???\nenum FS_LATIN1      = 0x00000001;\nenum FS_LATIN2      = 0x00000002;\nenum FS_CYRILLIC    = 0x00000004;\nenum FS_GREEK       = 0x00000008;\nenum FS_TURKISH     = 0x00000010;\nenum FS_HEBREW      = 0x00000020;\nenum FS_ARABIC      = 0x00000040;\nenum FS_BALTIC      = 0x00000080;\nenum FS_VIETNAMESE  = 0x00000100;\nenum FS_THAI        = 0x00010000;\nenum FS_JISJAPAN    = 0x00020000;\nenum FS_CHINESESIMP = 0x00040000;\nenum FS_WANSUNG     = 0x00080000;\nenum FS_CHINESETRAD = 0x00100000;\nenum FS_JOHAB       = 0x00200000;\nenum FS_SYMBOL      = 0x80000000;\n\n// ----\n// Poly Fill Mode\nenum : int {\n    ALTERNATE = 1,\n    WINDING = 2\n}\nenum int POLYFILL_LAST = WINDING;\n\n//---\n// LOGBRUSH\nenum : LONG {\n    HS_HORIZONTAL = 0,\n    HS_VERTICAL,\n    HS_FDIAGONAL,\n    HS_BDIAGONAL,\n    HS_CROSS,\n    HS_DIAGCROSS\n}\n\n//LOGBRUSH.lbStyle\nenum : UINT {\n    BS_SOLID = 0,\n    BS_NULL  = 1,\n    BS_HOLLOW = BS_NULL,\n    BS_HATCHED,\n    BS_PATTERN,\n    BS_INDEXED,\n    BS_DIBPATTERN,\n    BS_DIBPATTERNPT,\n    BS_PATTERN8X8,\n    BS_DIBPATTERN8X8,\n    BS_MONOPATTERN,\n}\n//-----\n// EXTLOGPEN, ExtCreatePen()\n\n// EXTLOGPEN.elpPenStyle\nenum : DWORD {\n    PS_SOLID       = 0,\n    PS_DASH        = 1,\n    PS_DOT         = 2,\n    PS_DASHDOT     = 3,\n    PS_DASHDOTDOT  = 4,\n    PS_NULL        = 5,\n    PS_INSIDEFRAME = 6,\n    PS_USERSTYLE   = 7,\n    PS_ALTERNATE   = 8,\n    PS_STYLE_MASK  = 15,\n}\n\nenum : DWORD {\n    PS_COSMETIC      = 0x00000000,\n    PS_GEOMETRIC     = 0x00010000,\n    PS_TYPE_MASK     = 0x000F0000,\n}\nenum : DWORD {\n    PS_ENDCAP_ROUND  = 0x00000000,\n    PS_ENDCAP_SQUARE = 0x00000100,\n    PS_ENDCAP_FLAT   = 0x00000200,\n    PS_ENDCAP_MASK   = 0x00000F00,\n}\nenum : DWORD {\n    PS_JOIN_ROUND    = 0x00000000,\n    PS_JOIN_BEVEL    = 0x00001000,\n    PS_JOIN_MITER    = 0x00002000,\n    PS_JOIN_MASK     = 0x0000F000,\n}\n\n// ---\n// DeviceCapabilities()\n\nenum : WORD {\n    DC_FIELDS = 1,\n    DC_PAPERS,\n    DC_PAPERSIZE,\n    DC_MINEXTENT,\n    DC_MAXEXTENT,\n    DC_BINS,\n    DC_DUPLEX,\n    DC_SIZE,\n    DC_EXTRA,\n    DC_VERSION,\n    DC_DRIVER,\n    DC_BINNAMES,\n    DC_ENUMRESOLUTIONS,\n    DC_FILEDEPENDENCIES,\n    DC_TRUETYPE,\n    DC_PAPERNAMES,\n    DC_ORIENTATION,\n    DC_COPIES,\n    DC_BINADJUST,\n    DC_EMF_COMPLIANT,\n    DC_DATATYPE_PRODUCED,\n    DC_COLLATE,\n    DC_MANUFACTURER,\n    DC_MODEL,\n}\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    enum {\n        DC_PERSONALITY = 25,\n        DC_PRINTRATE = 26,\n        DC_PRINTRATEUNIT = 27,\n        DC_PRINTERMEM = 28,\n        DC_MEDIAREADY = 29,\n        DC_STAPLE = 30,\n        DC_PRINTRATEPPM = 31,\n        DC_COLORDEVICE = 32,\n        DC_NUP = 33,\n        DC_MEDIATYPENAMES = 34,\n        DC_MEDIATYPES = 35,\n    }\n    enum {\n        PRINTRATEUNIT_PPM = 1,\n        PRINTRATEUNIT_CPS = 2,\n        PRINTRATEUNIT_LPM = 3,\n        PRINTRATEUNIT_IPM = 4,\n    }\n}\n\n\n// return from DC_TRUETYPE\nenum DWORD\n    DCTT_BITMAP           = 1,\n    DCTT_DOWNLOAD         = 2,\n    DCTT_SUBDEV           = 4,\n    DCTT_DOWNLOAD_OUTLINE = 8;\n\n// return from DC_BINADJUST\nenum : DWORD {\n    DCBA_FACEUPNONE     = 0x0000,\n    DCBA_FACEUPCENTER   = 0x0001,\n    DCBA_FACEUPLEFT     = 0x0002,\n    DCBA_FACEUPRIGHT    = 0x0003,\n    DCBA_FACEDOWNNONE   = 0x0100,\n    DCBA_FACEDOWNCENTER = 0x0101,\n    DCBA_FACEDOWNLEFT   = 0x0102,\n    DCBA_FACEDOWNRIGHT  = 0x0103,\n}\n//---\n\nenum FLOODFILLBORDER  = 0;\nenum FLOODFILLSURFACE = 1;\n\n// ExtTextOut()\nenum UINT\n    ETO_OPAQUE         = 0x0002,\n    ETO_CLIPPED        = 0x0004,\n    ETO_GLYPH_INDEX    = 0x0010,\n    ETO_RTLREADING     = 0x0080,\n    ETO_NUMERICSLOCAL  = 0x0400,\n    ETO_NUMERICSLATIN  = 0x0800,\n    ETO_IGNORELANGUAGE = 0x1000;\nstatic if (_WIN32_WINNT >= 0x500) {\nenum UINT\n        ETO_PDY = 0x2000;\n}\n\n// GdiComment()\nenum {\n    GDICOMMENT_BEGINGROUP       = 0x00000002,\n    GDICOMMENT_ENDGROUP         = 0x00000003,\n    GDICOMMENT_UNICODE_STRING   = 0x00000040,\n    GDICOMMENT_UNICODE_END      = 0x00000080,\n    GDICOMMENT_MULTIFORMATS     = 0x40000004,\n    GDICOMMENT_IDENTIFIER       = 0x43494447,\n    GDICOMMENT_WINDOWS_METAFILE = 0x80000001,\n}\n\n// Get/SetArcDirection()\nenum : int {\n    AD_COUNTERCLOCKWISE = 1,\n    AD_CLOCKWISE        = 2\n}\n\nenum RDH_RECTANGLES = 1;\n\n// GCPRESULTS.lpClass\nenum {\n    GCPCLASS_LATIN  = 1,\n    GCPCLASS_HEBREW = 2,\n    GCPCLASS_ARABIC = 2,\n    GCPCLASS_NEUTRAL,\n    GCPCLASS_LOCALNUMBER,\n    GCPCLASS_LATINNUMBER,\n    GCPCLASS_LATINNUMERICTERMINATOR,\n    GCPCLASS_LATINNUMERICSEPARATOR,\n    GCPCLASS_NUMERICSEPARATOR, // = 8,\n    GCPCLASS_POSTBOUNDRTL = 16,\n    GCPCLASS_POSTBOUNDLTR = 32,\n    GCPCLASS_PREBOUNDRTL  = 64,\n    GCPCLASS_PREBOUNDLTR  = 128,\n    GCPGLYPH_LINKAFTER    = 0x4000,\n    GCPGLYPH_LINKBEFORE   = 0x8000\n}\n\n// GetBoundsRect(), SetBoundsRect()\nenum UINT\n    DCB_RESET      = 1,\n    DCB_ACCUMULATE = 2,\n    DCB_SET        = DCB_RESET | DCB_ACCUMULATE,\n    DCB_ENABLE     = 4,\n    DCB_DISABLE    = 8,\n    DCB_DIRTY      = DCB_ACCUMULATE;\n\n//---\n// GetObjectType()\nenum : DWORD {\n    OBJ_PEN = 1,\n    OBJ_BRUSH,\n    OBJ_DC,\n    OBJ_METADC,\n    OBJ_PAL,\n    OBJ_FONT,\n    OBJ_BITMAP,\n    OBJ_REGION,\n    OBJ_METAFILE,\n    OBJ_MEMDC,\n    OBJ_EXTPEN,\n    OBJ_ENHMETADC,\n    OBJ_ENHMETAFILE,\n    OBJ_COLORSPACE,\n}\n\n//---------------------\n// Capabilities for GetDeviceCaps(dc, xxx)\n\nenum : int {\n    DRIVERVERSION   = 0,\n    TECHNOLOGY      = 2,\n    HORZSIZE        = 4,\n    VERTSIZE        = 6,\n    HORZRES         = 8,\n    VERTRES         = 10,\n    BITSPIXEL       = 12,\n    PLANES          = 14,\n    NUMBRUSHES      = 16,\n    NUMPENS         = 18,\n    NUMMARKERS      = 20,\n    NUMFONTS        = 22,\n    NUMCOLORS       = 24,\n    PDEVICESIZE     = 26,\n    CURVECAPS       = 28,\n    LINECAPS        = 30,\n    POLYGONALCAPS   = 32,\n    TEXTCAPS        = 34,\n    CLIPCAPS        = 36,\n    RASTERCAPS      = 38,\n    ASPECTX         = 40,\n    ASPECTY         = 42,\n    ASPECTXY        = 44,\n    LOGPIXELSX      = 88,\n    LOGPIXELSY      = 90,\n    SIZEPALETTE     = 104,\n    NUMRESERVED     = 106,\n    COLORRES        = 108,\n    PHYSICALWIDTH   = 110,\n    PHYSICALHEIGHT  = 111,\n    PHYSICALOFFSETX = 112,\n    PHYSICALOFFSETY = 113,\n    SCALINGFACTORX  = 114,\n    SCALINGFACTORY  = 115,\n    VREFRESH        = 116,\n    DESKTOPVERTRES  = 117,\n    DESKTOPHORZRES  = 118,\n    BLTALIGNMENT    = 119\n}\nstatic if (_WIN32_WINNT >= 0x500) {\nenum : int {\n    SHADEBLENDCAPS  = 120,\n    COLORMGMTCAPS   = 121,\n}\n}\n\n// Return values for GetDeviceCaps(dc, TECHNOLOGY)\nenum : int {\n    DT_PLOTTER = 0,\n    DT_RASDISPLAY,\n    DT_RASPRINTER,\n    DT_RASCAMERA,\n    DT_CHARSTREAM,\n    DT_METAFILE,\n    DT_DISPFILE // = 6\n}\n\n// Return values for GetDeviceCaps(dc, RASTERCAPS)\nenum int\n    RC_NONE         = 0,\n    RC_BITBLT       = 1,\n    RC_BANDING      = 2,\n    RC_SCALING      = 4,\n    RC_BITMAP64     = 8,\n    RC_GDI20_OUTPUT = 16,\n    RC_GDI20_STATE  = 32,\n    RC_SAVEBITMAP   = 64,\n    RC_DI_BITMAP    = 128,\n    RC_PALETTE      = 256,\n    RC_DIBTODEV     = 512,\n    RC_BIGFONT      = 1024,\n    RC_STRETCHBLT   = 2048,\n    RC_FLOODFILL    = 4096,\n    RC_STRETCHDIB   = 8192,\n    RC_OP_DX_OUTPUT = 0x4000,\n    RC_DEVBITS      = 0x8000;\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    /* Shading and blending caps */\nenum SB_NONE = 0x00000000;\nenum SB_CONST_ALPHA = 0x00000001;\nenum SB_PIXEL_ALPHA = 0x00000002;\nenum SB_PREMULT_ALPHA = 0x00000004;\nenum SB_GRAD_RECT = 0x00000010;\nenum SB_GRAD_TRI = 0x00000020;\n    /* Color Management caps */\nenum CM_NONE = 0x00000000;\nenum CM_DEVICE_ICM = 0x00000001;\nenum CM_GAMMA_RAMP = 0x00000002;\nenum CM_CMYK_COLOR = 0x00000004;\n}\n\n// Return values for GetDeviceCaps(dc, CURVECAPS)\nenum int\n    CC_NONE       = 0,\n    CC_CIRCLES    = 1,\n    CC_PIE        = 2,\n    CC_CHORD      = 4,\n    CC_ELLIPSES   = 8,\n    CC_WIDE       = 16,\n    CC_STYLED     = 32,\n    CC_WIDESTYLED = 64,\n    CC_INTERIORS  = 128,\n    CC_ROUNDRECT  = 256;\n\n// Return values for GetDeviceCaps(dc, LINECAPS)\n\nenum int\n    LC_NONE       = 0,\n    LC_POLYLINE   = 2,\n    LC_MARKER     = 4,\n    LC_POLYMARKER = 8,\n    LC_WIDE       = 16,\n    LC_STYLED     = 32,\n    LC_WIDESTYLED = 64,\n    LC_INTERIORS  = 128;\n\n// Return values for GetDeviceCaps(dc, POLYGONALCAPS)\n\nenum int\n    PC_NONE        = 0,\n    PC_POLYGON     = 1,\n    PC_RECTANGLE   = 2,\n    PC_WINDPOLYGON = 4,\n    PC_TRAPEZOID   = 4,\n    PC_SCANLINE    = 8,\n    PC_WIDE        = 16,\n    PC_STYLED      = 32,\n    PC_WIDESTYLED  = 64,\n    PC_INTERIORS   = 128,\n    PC_POLYPOLYGON = 256,\n    PC_PATHS       = 512;\n\n/* Clipping Capabilities */\nenum int CP_NONE = 0,\n    CP_RECTANGLE = 1,\n    CP_REGION = 2;\n\n// Return values for GetDeviceCaps(dc, TEXTCAPS)\n\nenum int\n    TC_OP_CHARACTER = 1,\n    TC_OP_STROKE    = 2,\n    TC_CP_STROKE    = 4,\n    TC_CR_90        = 8,\n    TC_CR_ANY       = 16,\n    TC_SF_X_YINDEP  = 32,\n    TC_SA_DOUBLE    = 64,\n    TC_SA_INTEGER   = 128,\n    TC_SA_CONTIN    = 256,\n    TC_EA_DOUBLE    = 512,\n    TC_IA_ABLE      = 1024,\n    TC_UA_ABLE      = 2048,\n    TC_SO_ABLE      = 4096,\n    TC_RA_ABLE      = 8192,\n    TC_VA_ABLE      = 16384,\n    TC_RESERVED     = 32768,\n    TC_SCROLLBLT    = 65536;\n\n// End GetDeviceCaps\n//---------------------\n// GetCharacterPlacement(), and GetFontLanguageInfo()\nenum DWORD\n    GCP_DBCS            = 1,\n    GCP_REORDER         = 2,\n    GCP_USEKERNING      = 8,\n    GCP_GLYPHSHAPE      = 16,\n    GCP_LIGATE          = 32,\n    GCP_DIACRITIC       = 256,\n    GCP_KASHIDA         = 1024,\n    GCP_ERROR           = 0x8000,\n    GCP_JUSTIFY         = 0x10000,\n    GCP_CLASSIN         = 0x80000,\n    GCP_MAXEXTENT       = 0x100000,\n    GCP_JUSTIFYIN       = 0x200000,\n    GCP_DISPLAYZWG      = 0x400000,\n    GCP_SYMSWAPOFF      = 0x800000,\n    GCP_NUMERICOVERRIDE = 0x1000000,\n    GCP_NEUTRALOVERRIDE = 0x2000000,\n    GCP_NUMERICSLATIN   = 0x4000000,\n    GCP_NUMERICSLOCAL   = 0x8000000,\n    // Only for GetFontLanguageInfo()\n    FLI_GLYPHS          = 0x40000,\n    FLI_MASK            = 0x103b;\n\n// GetGlyphOutline()\nenum : UINT {\n    GGO_METRICS      = 0,\n    GGO_BITMAP       = 1,\n    GGO_NATIVE       = 2,\n    GGO_BEZIER       = 3,\n    GGO_GRAY2_BITMAP = 4,\n    GGO_GRAY4_BITMAP = 5,\n    GGO_GRAY8_BITMAP = 6,\n    GGO_GLYPH_INDEX  = 128,\n    GGO_UNHINTED     = 256\n}\n\nenum : int {\n    GM_COMPATIBLE = 1,\n    GM_ADVANCED\n}\nenum GM_LAST = GM_ADVANCED;\n\nenum : int {\n    MM_TEXT = 1,\n    MM_LOMETRIC,\n    MM_HIMETRIC,\n    MM_LOENGLISH,\n    MM_HIENGLISH,\n    MM_TWIPS,\n    MM_ISOTROPIC,\n    MM_ANISOTROPIC,\n}\n\nenum int\n    MM_MIN = MM_TEXT,\n    MM_MAX = MM_ANISOTROPIC,\n    MM_MAX_FIXEDSCALE = MM_TWIPS;\n\nenum ABSOLUTE = 1;\nenum RELATIVE = 2;\n\nenum : BYTE {\n    PC_RESERVED   = 1,\n    PC_EXPLICIT   = 2,\n    PC_NOCOLLAPSE = 4\n}\n\n/* FIXME: move to core.sys.windows.commctrl ? */\n// ImageList\nenum COLORREF\n    CLR_NONE    = 0xffffffff,\n    CLR_INVALID = CLR_NONE,\n    CLR_DEFAULT = 0xff000000;\n\n// RASTERIZER_STATUS.wFlags\nenum short\n    TT_AVAILABLE = 1,\n    TT_ENABLED   = 2;\n\n// GetStockObject()\nenum : int {\n    WHITE_BRUSH = 0,\n    LTGRAY_BRUSH,\n    GRAY_BRUSH,\n    DKGRAY_BRUSH,\n    BLACK_BRUSH,\n    HOLLOW_BRUSH, // = 5\n    NULL_BRUSH = HOLLOW_BRUSH,\n    WHITE_PEN = 6,\n    BLACK_PEN,\n    NULL_PEN, // = 8\n    OEM_FIXED_FONT = 10,\n    ANSI_FIXED_FONT,\n    ANSI_VAR_FONT,\n    SYSTEM_FONT,\n    DEVICE_DEFAULT_FONT,\n    DEFAULT_PALETTE,\n    SYSTEM_FIXED_FONT,\n    DEFAULT_GUI_FONT = SYSTEM_FIXED_FONT + 1,\n}\nstatic if (_WIN32_WINNT >= 0x500) {\n    enum : int {\n        DC_BRUSH = DEFAULT_GUI_FONT + 1,\n        DC_PEN,\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x500) {\nenum STOCK_LAST = DC_PEN;\n} else {\nenum STOCK_LAST = DEFAULT_GUI_FONT;\n}\n\n// Get/SetSystemPaletteUse()\nenum : UINT {\n    SYSPAL_ERROR    = 0,\n    SYSPAL_STATIC   = 1,\n    SYSPAL_NOSTATIC = 2,\n    SYSPAL_NOSTATIC256 = 3,\n}\n\n// SetTextAlign()\nenum UINT\n    TA_TOP        = 0,\n    TA_CENTER     = 6,\n    TA_BOTTOM     = 8,\n    TA_BASELINE   = 24,\n    TA_LEFT       = 0,\n    TA_RIGHT      = 2,\n    TA_RTLREADING = 256,\n    TA_NOUPDATECP = 0,\n    TA_UPDATECP   = 1,\n    TA_MASK       = TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING,\n    VTA_BASELINE  = TA_BASELINE,\n    VTA_CENTER    = TA_CENTER,\n    VTA_LEFT      = TA_BOTTOM,\n    VTA_RIGHT     = TA_TOP,\n    VTA_BOTTOM    = TA_RIGHT,\n    VTA_TOP       = TA_LEFT;\n\n// EMRMODIFYWORLDTRANSFORM.iMode\nenum : DWORD {\n    MWT_IDENTITY = 1,\n    MWT_LEFTMULTIPLY,\n    MWT_RIGHTMULTIPLY\n}\n\nenum DWORD\n    MWT_MIN = MWT_IDENTITY,\n    MWT_MAX = MWT_RIGHTMULTIPLY;\n\nenum {\n    TRANSPARENT = 1,\n    OPAQUE      = 2\n}\n\n// Get/SetStretchMode()\nenum : int {\n    BLACKONWHITE = 1,\n    WHITEONBLACK = 2,\n    COLORONCOLOR = 3,\n    HALFTONE     = 4,\n\n    STRETCH_ANDSCANS    = 1,\n    STRETCH_ORSCANS     = 2,\n    STRETCH_DELETESCANS = 3,\n    STRETCH_HALFTONE    = 4,\n\n    MAXSTRETCHBLTMODE   = 4\n}\n\n// TranslateCharsetInfo()\nenum : DWORD {\n    TCI_SRCCHARSET  = 1,\n    TCI_SRCCODEPAGE = 2,\n    TCI_SRCFONTSIG  = 3,\n    TCI_SRCLOCALE   = 0x1000,\n}\n\n// SetICMMode()\nenum : int {\n    ICM_OFF   = 1,\n    ICM_ON    = 2,\n    ICM_QUERY = 3,\n    ICM_DONE_OUTSIDEDC = 4,\n}\n\n// ----\n// Escape() Spooler Error Codes\nenum : int {\n    SP_NOTREPORTED = 0x4000,\n    SP_ERROR       = -1,\n    SP_APPABORT    = -2,\n    SP_USERABORT   = -3,\n    SP_OUTOFDISK   = -4,\n    SP_OUTOFMEMORY = -5\n}\n\n// Escape(), ExtEscape()\n// Most of the following are deprecated (Win16 only)\nenum : int {\n    NEWFRAME      = 1,\n    ABORTDOC      = 2,\n    NEXTBAND      = 3,\n    SETCOLORTABLE = 4,\n    GETCOLORTABLE = 5,\n    FLUSHOUTPUT   = 6,\n    DRAFTMODE     = 7,\n    QUERYESCSUPPORT = 8,\n    SETABORTPROC  = 9,\n    STARTDOC      = 10,\n    ENDDOC        = 11,\n    GETPHYSPAGESIZE   = 12,\n    GETPRINTINGOFFSET = 13,\n    GETSCALINGFACTOR  = 14,\n    MFCOMMENT         = 15,\n    GETPENWIDTH       = 16,\n    SETCOPYCOUNT      = 17,\n    SELECTPAPERSOURCE = 18,\n    DEVICEDATA        = 19,\n    PASSTHROUGH       = 19,\n    GETTECHNOLOGY     = 20,\n    SETLINECAP = 21,\n    SETLINEJOIN = 22,\n    SETMITERLIMIT = 23,\n    BANDINFO = 24,\n    DRAWPATTERNRECT = 25,\n    GETVECTORPENSIZE = 26,\n    GETVECTORBRUSHSIZE = 27,\n    ENABLEDUPLEX = 28,\n    GETSETPAPERBINS = 29,\n    GETSETPRINTORIENT = 30,\n    ENUMPAPERBINS = 31,\n    SETDIBSCALING = 32,\n    EPSPRINTING = 33,\n    ENUMPAPERMETRICS = 34,\n    GETSETPAPERMETRICS = 35,\n    POSTSCRIPT_DATA = 37,\n    POSTSCRIPT_IGNORE = 38,\n    MOUSETRAILS = 39,\n    GETDEVICEUNITS = 42,\n    GETEXTENDEDTEXTMETRICS = 256,\n    GETEXTENTTABLE = 257,\n    GETPAIRKERNTABLE = 258,\n    GETTRACKKERNTABLE = 259,\n    EXTTEXTOUT = 512,\n    GETFACENAME = 513,\n    DOWNLOADFACE = 514,\n    ENABLERELATIVEWIDTHS = 768,\n    ENABLEPAIRKERNING = 769,\n    SETKERNTRACK = 770,\n    SETALLJUSTVALUES = 771,\n    SETCHARSET = 772,\n    STRETCHBLT = 2048,\n    METAFILE_DRIVER = 2049,\n    GETSETSCREENPARAMS = 3072,\n    QUERYDIBSUPPORT = 3073,\n    BEGIN_PATH = 4096,\n    CLIP_TO_PATH = 4097,\n    END_PATH = 4098,\n    EXT_DEVICE_CAPS = 4099,\n    RESTORE_CTM = 4100,\n    SAVE_CTM = 4101,\n    SET_ARC_DIRECTION = 4102,\n    SET_BACKGROUND_COLOR = 4103,\n    SET_POLY_MODE = 4104,\n    SET_SCREEN_ANGLE = 4105,\n    SET_SPREAD = 4106,\n    TRANSFORM_CTM = 4107,\n    SET_CLIP_BOX = 4108,\n    SET_BOUNDS = 4109,\n    SET_MIRROR_MODE = 4110,\n    OPENCHANNEL = 4110,\n    DOWNLOADHEADER = 4111,\n    CLOSECHANNEL = 4112,\n    POSTSCRIPT_PASSTHROUGH  = 4115,\n    ENCAPSULATED_POSTSCRIPT = 4116,\n    POSTSCRIPT_IDENTIFY = 4117,\n    POSTSCRIPT_INJECTION = 4118,\n    CHECKJPEGFORMAT = 4119,\n    CHECKPNGFORMAT = 4120,\n    GET_PS_FEATURESETTING = 4121,\n    SPCLPASSTHROUGH2 = 4568,\n}\n\nenum : int {\n    PSIDENT_GDICENTRIC = 0,\n    PSIDENT_PSCENTRIC = 1,\n}\n\n/*\n * Header structure for the input buffer to POSTSCRIPT_INJECTION escape\n */\nstruct PSINJECTDATA {\n    DWORD DataBytes;\n    WORD  InjectionPoint;\n    WORD  PageNumber;\n}\nalias PSINJECTDATA* PPSINJECTDATA;\n\n/* Constants for PSINJECTDATA.InjectionPoint field */\nenum {\n    PSINJECT_BEGINSTREAM = 1,\n    PSINJECT_PSADOBE = 2,\n    PSINJECT_PAGESATEND = 3,\n    PSINJECT_PAGES = 4,\n    PSINJECT_DOCNEEDEDRES = 5,\n    PSINJECT_DOCSUPPLIEDRES = 6,\n    PSINJECT_PAGEORDER = 7,\n    PSINJECT_ORIENTATION = 8,\n    PSINJECT_BOUNDINGBOX = 9,\n    PSINJECT_DOCUMENTPROCESSCOLORS = 10,\n    PSINJECT_COMMENTS = 11,\n    PSINJECT_BEGINDEFAULTS = 12,\n    PSINJECT_ENDDEFAULTS = 13,\n    PSINJECT_BEGINPROLOG = 14,\n    PSINJECT_ENDPROLOG = 15,\n    PSINJECT_BEGINSETUP = 16,\n    PSINJECT_ENDSETUP = 17,\n    PSINJECT_TRAILER = 18,\n    PSINJECT_EOF = 19,\n    PSINJECT_ENDSTREAM = 20,\n    PSINJECT_DOCUMENTPROCESSCOLORSATEND = 21,\n\n    PSINJECT_PAGENUMBER = 100,\n    PSINJECT_BEGINPAGESETUP = 101,\n    PSINJECT_ENDPAGESETUP = 102,\n    PSINJECT_PAGETRAILER = 103,\n    PSINJECT_PLATECOLOR = 104,\n    PSINJECT_SHOWPAGE = 105,\n    PSINJECT_PAGEBBOX = 106,\n    PSINJECT_ENDPAGECOMMENTS = 107,\n\n    PSINJECT_VMSAVE = 200,\n    PSINJECT_VMRESTORE = 201,\n}\n\n/* Parameter for GET_PS_FEATURESETTING escape */\nenum {\n    FEATURESETTING_NUP = 0,\n    FEATURESETTING_OUTPUT = 1,\n    FEATURESETTING_PSLEVEL = 2,\n    FEATURESETTING_CUSTPAPER = 3,\n    FEATURESETTING_MIRROR = 4,\n    FEATURESETTING_NEGATIVE = 5,\n    FEATURESETTING_PROTOCOL = 6,\n}\n\nenum {\n    FEATURESETTING_PRIVATE_BEGIN = 0x1000,\n    FEATURESETTING_PRIVATE_END = 0x1FFF,\n}\n\n/* Value returned for FEATURESETTING_PROTOCOL */\nenum PSPROTOCOL_ASCII = 0;\nenum PSPROTOCOL_BCP = 1;\nenum PSPROTOCOL_TBCP = 2;\nenum PSPROTOCOL_BINARY = 3;\n\n// ----\n\nenum WPARAM PR_JOBSTATUS = 0;\n\n// ???\nenum QDI_SETDIBITS   = 1;\nenum QDI_GETDIBITS   = 2;\nenum QDI_DIBTOSCREEN = 4;\nenum QDI_STRETCHDIB  = 8;\n\nenum ASPECT_FILTERING = 1;\n\n// LOGCOLORSPACE.lcsCSType\nenum : LCSCSTYPE {\n    LCS_CALIBRATED_RGB = 0,\n    LCS_DEVICE_RGB,\n    LCS_DEVICE_CMYK\n} /* What this for? */\n\n// LOGCOLORSPACE.lcsIntent\nenum : LCSGAMUTMATCH {\n    LCS_GM_BUSINESS         = 1,\n    LCS_GM_GRAPHICS         = 2,\n    LCS_GM_IMAGES           = 4,\n    LCS_GM_ABS_COLORIMETRIC = 8,\n}\n\nenum DWORD\n    RASTER_FONTTYPE   = 1,\n    DEVICE_FONTTYPE   = 2,\n    TRUETYPE_FONTTYPE = 4;\n\n// ---\n// DEVMODE struct\n\n// FIXME: Not needed for D (use .length instead)\nenum CCHDEVICENAME = 32;\nenum CCHFORMNAME   = 32;\n\n// DEVMODE.dmSpecVersion\n// current version of specification\nenum WORD DM_SPECVERSION = 0x0401;\n\n// DEVMODE.dmOrientation\nenum : short {\n    DMORIENT_PORTRAIT  = 1,\n    DMORIENT_LANDSCAPE = 2\n}\n\n// DEVMODE.dmPaperSize\nenum : short {\n    DMPAPER_LETTER = 1,\n    DMPAPER_LETTERSMALL,\n    DMPAPER_TABLOID,\n    DMPAPER_LEDGER,\n    DMPAPER_LEGAL,\n    DMPAPER_STATEMENT,\n    DMPAPER_EXECUTIVE,\n    DMPAPER_A3,\n    DMPAPER_A4,\n    DMPAPER_A4SMALL,\n    DMPAPER_A5,\n    DMPAPER_B4,\n    DMPAPER_B5,\n    DMPAPER_FOLIO,\n    DMPAPER_QUARTO,\n    DMPAPER_10X14,\n    DMPAPER_11X17,\n    DMPAPER_NOTE,\n    DMPAPER_ENV_9,\n    DMPAPER_ENV_10,\n    DMPAPER_ENV_11,\n    DMPAPER_ENV_12,\n    DMPAPER_ENV_14,\n    DMPAPER_CSHEET,\n    DMPAPER_DSHEET,\n    DMPAPER_ESHEET,\n    DMPAPER_ENV_DL,\n    DMPAPER_ENV_C5,\n    DMPAPER_ENV_C3,\n    DMPAPER_ENV_C4,\n    DMPAPER_ENV_C6,\n    DMPAPER_ENV_C65,\n    DMPAPER_ENV_B4,\n    DMPAPER_ENV_B5,\n    DMPAPER_ENV_B6,\n    DMPAPER_ENV_ITALY,\n    DMPAPER_ENV_MONARCH,\n    DMPAPER_ENV_PERSONAL,\n    DMPAPER_FANFOLD_US,\n    DMPAPER_FANFOLD_STD_GERMAN,\n    DMPAPER_FANFOLD_LGL_GERMAN,\n    DMPAPER_ISO_B4,\n    DMPAPER_JAPANESE_POSTCARD,\n    DMPAPER_9X11,\n    DMPAPER_10X11,\n    DMPAPER_15X11,\n    DMPAPER_ENV_INVITE,\n    DMPAPER_RESERVED_48,\n    DMPAPER_RESERVED_49,\n    DMPAPER_LETTER_EXTRA,\n    DMPAPER_LEGAL_EXTRA,\n    DMPAPER_TABLOID_EXTRA,\n    DMPAPER_A4_EXTRA,\n    DMPAPER_LETTER_TRANSVERSE,\n    DMPAPER_A4_TRANSVERSE,\n    DMPAPER_LETTER_EXTRA_TRANSVERSE,\n    DMPAPER_A_PLUS,\n    DMPAPER_B_PLUS,\n    DMPAPER_LETTER_PLUS,\n    DMPAPER_A4_PLUS,\n    DMPAPER_A5_TRANSVERSE,\n    DMPAPER_B5_TRANSVERSE,\n    DMPAPER_A3_EXTRA,\n    DMPAPER_A5_EXTRA,\n    DMPAPER_B5_EXTRA,\n    DMPAPER_A2,\n    DMPAPER_A3_TRANSVERSE,\n    DMPAPER_A3_EXTRA_TRANSVERSE // = 68\n}\nstatic if (_WIN32_WINNT >= 0x500) {\n    enum : short {\n        DMPAPER_DBL_JAPANESE_POSTCARD = 69,\n        DMPAPER_A6,\n        DMPAPER_JENV_KAKU2,\n        DMPAPER_JENV_KAKU3,\n        DMPAPER_JENV_CHOU3,\n        DMPAPER_JENV_CHOU4,\n        DMPAPER_LETTER_ROTATED,\n        DMPAPER_A3_ROTATED,\n        DMPAPER_A4_ROTATED,\n        DMPAPER_A5_ROTATED,\n        DMPAPER_B4_JIS_ROTATED,\n        DMPAPER_B5_JIS_ROTATED,\n        DMPAPER_JAPANESE_POSTCARD_ROTATED,\n        DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED,\n        DMPAPER_A6_ROTATED,\n        DMPAPER_JENV_KAKU2_ROTATED,\n        DMPAPER_JENV_KAKU3_ROTATED,\n        DMPAPER_JENV_CHOU3_ROTATED,\n        DMPAPER_JENV_CHOU4_ROTATED,\n        DMPAPER_B6_JIS,\n        DMPAPER_B6_JIS_ROTATED,\n        DMPAPER_12X11,\n        DMPAPER_JENV_YOU4,\n        DMPAPER_JENV_YOU4_ROTATED,\n        DMPAPER_P16K,\n        DMPAPER_P32K,\n        DMPAPER_P32KBIG,\n        DMPAPER_PENV_1,\n        DMPAPER_PENV_2,\n        DMPAPER_PENV_3,\n        DMPAPER_PENV_4,\n        DMPAPER_PENV_5,\n        DMPAPER_PENV_6,\n        DMPAPER_PENV_7,\n        DMPAPER_PENV_8,\n        DMPAPER_PENV_9,\n        DMPAPER_PENV_10,\n        DMPAPER_P16K_ROTATED,\n        DMPAPER_P32K_ROTATED,\n        DMPAPER_P32KBIG_ROTATED,\n        DMPAPER_PENV_1_ROTATED,\n        DMPAPER_PENV_2_ROTATED,\n        DMPAPER_PENV_3_ROTATED,\n        DMPAPER_PENV_4_ROTATED,\n        DMPAPER_PENV_5_ROTATED,\n        DMPAPER_PENV_6_ROTATED,\n        DMPAPER_PENV_7_ROTATED,\n        DMPAPER_PENV_8_ROTATED,\n        DMPAPER_PENV_9_ROTATED,\n        DMPAPER_PENV_10_ROTATED // 118\n    }\n}\n\nenum short DMPAPER_FIRST = DMPAPER_LETTER;\n\nstatic if (_WIN32_WINNT >= 0x500) {\nenum short DMPAPER_LAST = DMPAPER_PENV_10_ROTATED;\n} else {\nenum short DMPAPER_LAST = DMPAPER_A3_EXTRA_TRANSVERSE;\n}\n\nenum short DMPAPER_USER = 256;\n\n\n// DEVMODE.dmDefaultSource\nenum : short {\n    DMBIN_ONLYONE = 1,\n    DMBIN_UPPER   = 1,\n    DMBIN_LOWER,\n    DMBIN_MIDDLE,\n    DMBIN_MANUAL,\n    DMBIN_ENVELOPE,\n    DMBIN_ENVMANUAL,\n    DMBIN_AUTO,\n    DMBIN_TRACTOR,\n    DMBIN_SMALLFMT,\n    DMBIN_LARGEFMT,\n    DMBIN_LARGECAPACITY, // = 11\n    DMBIN_CASSETTE   = 14,\n    DMBIN_FORMSOURCE,\n}\nenum : short {\n    DMBIN_FIRST = DMBIN_UPPER,\n    DMBIN_LAST = DMBIN_FORMSOURCE,\n    DMBIN_USER = 256,\n}\n\n// DEVMODE.dmPrintQuality\nenum : short {\n    DMRES_DRAFT  = -1,\n    DMRES_LOW    = -2,\n    DMRES_MEDIUM = -3,\n    DMRES_HIGH   = -4\n}\n\n// DEVMODE.dmColor\nenum : short {\n    DMCOLOR_MONOCHROME = 1,\n    DMCOLOR_COLOR      = 2\n}\n\n// DEVMODE.dmDuplex\nenum : short {\n    DMDUP_SIMPLEX    = 1,\n    DMDUP_VERTICAL   = 2,\n    DMDUP_HORIZONTAL = 3\n}\n\n// DEVMODE.dmTTOption\nenum : short {\n    DMTT_BITMAP = 1,\n    DMTT_DOWNLOAD,\n    DMTT_SUBDEV,\n    DMTT_DOWNLOAD_OUTLINE\n}\n\n// DEVMODE.dmCollate\nenum : short {\n    DMCOLLATE_FALSE = 0,\n    DMCOLLATE_TRUE\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    /* DEVMODE dmDisplayOrientation specifiations */\n    enum : short {\n        DMDO_DEFAULT = 0,\n        DMDO_90 = 1,\n        DMDO_180 = 2,\n        DMDO_270 = 3,\n    }\n\n    /* DEVMODE dmDisplayFixedOutput specifiations */\n    enum : short {\n        DMDFO_DEFAULT = 0,\n        DMDFO_STRETCH = 1,\n        DMDFO_CENTER = 2,\n    }\n}\n\n\n/* FIXME: this flags are deprecated ? */\n// DEVMODE.dmDisplayFlags\nenum DWORD\n    DM_GRAYSCALE  = 1,\n    DM_INTERLACED = 2;\n\nenum DWORD\n    DMDISPLAYFLAGS_TEXTMODE = 0x00000004;\n\n/* dmNup , multiple logical page per physical page options */\nenum DWORD\n    DMNUP_SYSTEM = 1,\n    DMNUP_ONEUP = 2;\n\n// DEVMODE.dmFields\nenum DWORD\n    DM_ORIENTATION        = 0x00000001,\n    DM_PAPERSIZE          = 0x00000002,\n    DM_PAPERLENGTH        = 0x00000004,\n    DM_PAPERWIDTH         = 0x00000008,\n    DM_SCALE              = 0x00000010;\nstatic if (_WIN32_WINNT >= 0x500) {\nenum DWORD\n        DM_POSITION       = 0x00000020,\n        DM_NUP            = 0x00000040;\n}\nstatic if (_WIN32_WINNT >= 0x501) {\nenum DWORD\n        DM_DISPLAYORIENTATION = 0x00000080;\n}\nenum DWORD\n    DM_COPIES             = 0x00000100,\n    DM_DEFAULTSOURCE      = 0x00000200,\n    DM_PRINTQUALITY       = 0x00000400,\n    DM_COLOR              = 0x00000800,\n    DM_DUPLEX             = 0x00001000,\n    DM_YRESOLUTION        = 0x00002000,\n    DM_TTOPTION           = 0x00004000,\n    DM_COLLATE            = 0x00008000,\n    DM_FORMNAME           = 0x00010000,\n    DM_LOGPIXELS          = 0x00020000,\n    DM_BITSPERPEL         = 0x00040000,\n    DM_PELSWIDTH          = 0x00080000,\n    DM_PELSHEIGHT         = 0x00100000,\n    DM_DISPLAYFLAGS       = 0x00200000,\n    DM_DISPLAYFREQUENCY   = 0x00400000,\n    DM_ICMMETHOD          = 0x00800000,\n    DM_ICMINTENT          = 0x01000000,\n    DM_MEDIATYPE          = 0x02000000,\n    DM_DITHERTYPE         = 0x04000000,\n    DM_PANNINGWIDTH       = 0x08000000,\n    DM_PANNINGHEIGHT      = 0x10000000;\nstatic if (_WIN32_WINNT >= 0x501) {\nenum DWORD\n        DM_DISPLAYFIXEDOUTPUT = 0x20000000;\n}\n\n// DEVMODE.dmICMMethod\nenum : DWORD {\n    DMICMMETHOD_NONE   = 1,\n    DMICMMETHOD_SYSTEM = 2,\n    DMICMMETHOD_DRIVER = 3,\n    DMICMMETHOD_DEVICE = 4,\n    DMICMMETHOD_USER   = 256\n}\n\n// DEVMODE.dmICMIntent\nenum : DWORD {\n    DMICM_SATURATE    = 1,\n    DMICM_CONTRAST    = 2,\n    DMICM_COLORIMETRIC = 3,\n    DMICM_ABS_COLORIMETRIC = 4,\n    DMICM_USER        = 256\n}\n\n// DEVMODE.dmMediaType\nenum : DWORD {\n    DMMEDIA_STANDARD     = 1,\n    DMMEDIA_TRANSPARENCY = 2,\n    DMMEDIA_GLOSSY       = 3,\n    DMMEDIA_USER         = 256\n}\n\n// DEVMODE.dmDitherType\nenum : DWORD {\n    DMDITHER_NONE = 1,\n    DMDITHER_COARSE,\n    DMDITHER_FINE,\n    DMDITHER_LINEART,\n    DMDITHER_ERRORDIFFUSION,\n    DMDITHER_RESERVED6,\n    DMDITHER_RESERVED7,\n    DMDITHER_RESERVED8,\n    DMDITHER_RESERVED9,\n    DMDITHER_GRAYSCALE,\n    DMDITHER_USER = 256\n}\n\n// ----\n// DocumentProperties()\nenum DWORD\n    DM_UPDATE      = 1,\n    DM_COPY        = 2,\n    DM_PROMPT      = 4,\n    DM_MODIFY      = 8,\n    DM_IN_BUFFER   = DM_MODIFY,\n    DM_IN_PROMPT   = DM_PROMPT,\n    DM_OUT_BUFFER  = DM_COPY,\n    DM_OUT_DEFAULT = DM_UPDATE;\n// ---\n\nenum GDI_ERROR = 0xFFFFFFFF;\nenum HGDI_ERROR= cast(HANDLE)GDI_ERROR;\n\n// TEXTMETRIC.tmPitchAndFamily\nenum BYTE\n    TMPF_FIXED_PITCH = 1,\n    TMPF_VECTOR      = 2,\n    TMPF_TRUETYPE    = 4,\n    TMPF_DEVICE      = 8;\n\n// NEWTEXTMETRIC.ntmFlags\nenum DWORD\n    NTM_ITALIC         = 0x00000001,\n    NTM_BOLD           = 0x00000020,\n    NTM_REGULAR        = 0x00000040,\n    NTM_NONNEGATIVE_AC = 0x00010000,\n    NTM_PS_OPENTYPE    = 0x00020000,\n    NTM_TT_OPENTYPE    = 0x00040000,\n    NTM_MULTIPLEMASTER = 0x00080000,\n    NTM_TYPE1          = 0x00100000,\n    NTM_DSIG           = 0x00200000;\n\n// ---\nenum DWORD TT_POLYGON_TYPE = 24;\n\n// TTPOLYCURVE\nenum : WORD {\n    TT_PRIM_LINE    = 1,\n    TT_PRIM_QSPLINE = 2,\n    TT_PRIM_CSPLINE = 3,\n}\n// ---\nenum FONTMAPPER_MAX = 10;\nenum ENHMETA_STOCK_OBJECT = 0x80000000;\nenum WGL_FONT_LINES = 0;\nenum WGL_FONT_POLYGONS = 1;\n\n// ---\n// LAYERPLANEDESCRIPTOR.dwFlags\nenum DWORD\n    LPD_DOUBLEBUFFER   = 1,\n    LPD_STEREO         = 2,\n    LPD_SUPPORT_GDI    = 16,\n    LPD_SUPPORT_OPENGL = 32,\n    LPD_SHARE_DEPTH    = 64,\n    LPD_SHARE_STENCIL  = 128,\n    LPD_SHARE_ACCUM    = 256,\n    LPD_SWAP_EXCHANGE  = 512,\n    LPD_SWAP_COPY      = 1024,\n    LPD_TRANSPARENT    = 4096;\n\n// LAYERPLANEDESCRIPTOR.iPixelType\nenum : BYTE {\n    LPD_TYPE_RGBA       = 0,\n    LPD_TYPE_COLORINDEX = 1\n}\n\n// ---\n\n// wglSwapLayerBuffers()\nenum UINT\n    WGL_SWAP_MAIN_PLANE = 1,\n    WGL_SWAP_OVERLAY1   = 2,\n    WGL_SWAP_OVERLAY2   = 4,\n    WGL_SWAP_OVERLAY3   = 8,\n    WGL_SWAP_OVERLAY4   = 16,\n    WGL_SWAP_OVERLAY5   = 32,\n    WGL_SWAP_OVERLAY6   = 64,\n    WGL_SWAP_OVERLAY7   = 128,\n    WGL_SWAP_OVERLAY8   = 256,\n    WGL_SWAP_OVERLAY9   = 512,\n    WGL_SWAP_OVERLAY10  = 1024,\n    WGL_SWAP_OVERLAY11  = 2048,\n    WGL_SWAP_OVERLAY12  = 4096,\n    WGL_SWAP_OVERLAY13  = 8192,\n    WGL_SWAP_OVERLAY14  = 16384,\n    WGL_SWAP_OVERLAY15  = 32768,\n    WGL_SWAP_UNDERLAY1  = 65536,\n    WGL_SWAP_UNDERLAY2  = 0x20000,\n    WGL_SWAP_UNDERLAY3  = 0x40000,\n    WGL_SWAP_UNDERLAY4  = 0x80000,\n    WGL_SWAP_UNDERLAY5  = 0x100000,\n    WGL_SWAP_UNDERLAY6  = 0x200000,\n    WGL_SWAP_UNDERLAY7  = 0x400000,\n    WGL_SWAP_UNDERLAY8  = 0x800000,\n    WGL_SWAP_UNDERLAY9  = 0x1000000,\n    WGL_SWAP_UNDERLAY10 = 0x2000000,\n    WGL_SWAP_UNDERLAY11 = 0x4000000,\n    WGL_SWAP_UNDERLAY12 = 0x8000000,\n    WGL_SWAP_UNDERLAY13 = 0x10000000,\n    WGL_SWAP_UNDERLAY14 = 0x20000000,\n    WGL_SWAP_UNDERLAY15 = 0x40000000;\n\nenum AC_SRC_OVER  = 0x00;\nenum AC_SRC_ALPHA = 0x01;\n\n// ???\nenum AC_SRC_NO_PREMULT_ALPHA = 0x01;\nenum AC_SRC_NO_ALPHA         = 0x02;\nenum AC_DST_NO_PREMULT_ALPHA = 0x10;\nenum AC_DST_NO_ALPHA         = 0x20;\n\nenum LAYOUT_RTL = 1;\nenum LAYOUT_BTT = 2;\nenum LAYOUT_VBH = 4;\nenum LAYOUT_BITMAPORIENTATIONPRESERVED = 8;\n\nenum CS_ENABLE = 0x00000001;\nenum CS_DISABLE = 0x00000002;\nenum CS_DELETE_TRANSFORM = 0x00000003;\n\nstatic if (_WIN32_WINNT > 0x500) {\nenum GRADIENT_FILL_RECT_H=0x00;\nenum GRADIENT_FILL_RECT_V=0x01;\nenum GRADIENT_FILL_TRIANGLE=0x02;\nenum GRADIENT_FILL_OP_FLAG=0xff;\nenum COLORMATCHTOTARGET_EMBEDED=0x00000001;\nenum CREATECOLORSPACE_EMBEDED=0x00000001;\nenum SETICMPROFILE_EMBEDED=0x00000001;\n}\n\n// DISPLAY_DEVICE.StateFlags\nenum DWORD\n    DISPLAY_DEVICE_ATTACHED_TO_DESKTOP = 0x00000001,\n    DISPLAY_DEVICE_MULTI_DRIVER        = 0x00000002,\n    DISPLAY_DEVICE_PRIMARY_DEVICE      = 0x00000004,\n    DISPLAY_DEVICE_MIRRORING_DRIVER    = 0x00000008,\n    DISPLAY_DEVICE_VGA_COMPATIBLE      = 0x00000010,\n    DISPLAY_DEVICE_REMOVABLE           = 0x00000020,\n    DISPLAY_DEVICE_DISCONNECT          = 0x02000000,\n    DISPLAY_DEVICE_REMOTE              = 0x04000000,\n    DISPLAY_DEVICE_MODESPRUNED         = 0x08000000;\n\n/* Child device state */\nenum DWORD\n    DISPLAY_DEVICE_ACTIVE = 0x00000001,\n    DISPLAY_DEVICE_ATTACHED = 0x00000002;\n\nstatic if (_WIN32_WINNT >= 0x500) {\nenum GGI_MARK_NONEXISTING_GLYPHS = 1;\n}\n\n// ----------\n//   STRUCTS\n// ----------\n\nstruct ABC {\n    int  abcA;\n    UINT abcB;\n    int  abcC;\n}\nalias ABC* PABC, NPABC, LPABC;\n\nstruct ABCFLOAT {\n    FLOAT abcfA;\n    FLOAT abcfB;\n    FLOAT abcfC;\n}\nalias ABCFLOAT* PABCFLOAT, NPABCFLOAT, LPABCFLOAT;\n\nstruct BITMAP {\n    LONG   bmType;\n    LONG   bmWidth;\n    LONG   bmHeight;\n    LONG   bmWidthBytes;\n    WORD   bmPlanes;\n    WORD   bmBitsPixel;\n    LPVOID bmBits;\n}\nalias BITMAP* PBITMAP, NPBITMAP, LPBITMAP;\n\nstruct BITMAPCOREHEADER {\n    DWORD bcSize;\n    WORD  bcWidth;\n    WORD  bcHeight;\n    WORD  bcPlanes;\n    WORD  bcBitCount;\n}\nalias BITMAPCOREHEADER* PBITMAPCOREHEADER, LPBITMAPCOREHEADER;\n\nalign(1):\nstruct RGBTRIPLE {\n    BYTE rgbtBlue;\n    BYTE rgbtGreen;\n    BYTE rgbtRed;\n}\nalias RGBTRIPLE* LPRGBTRIPLE;\n\nalign(2):\nstruct BITMAPFILEHEADER {\nalign(2):\n    WORD  bfType;\n    DWORD bfSize;\n    WORD  bfReserved1;\n    WORD  bfReserved2;\n    DWORD bfOffBits;\n}\nalias BITMAPFILEHEADER* LPBITMAPFILEHEADER, PBITMAPFILEHEADER;\n\nalign:\n\nstruct BITMAPCOREINFO {\n    BITMAPCOREHEADER bmciHeader;\n    RGBTRIPLE[1]     bmciColors;\n}\nalias BITMAPCOREINFO* LPBITMAPCOREINFO, PBITMAPCOREINFO;\n\nstruct BITMAPINFOHEADER {\n    DWORD biSize;\n    LONG  biWidth;\n    LONG  biHeight;\n    WORD  biPlanes;\n    WORD  biBitCount;\n    DWORD biCompression;\n    DWORD biSizeImage;\n    LONG  biXPelsPerMeter;\n    LONG  biYPelsPerMeter;\n    DWORD biClrUsed;\n    DWORD biClrImportant;\n}\n\nalias BITMAPINFOHEADER* LPBITMAPINFOHEADER, PBITMAPINFOHEADER;\n\nstruct RGBQUAD {\n    BYTE rgbBlue;\n    BYTE rgbGreen;\n    BYTE rgbRed;\n    BYTE rgbReserved;\n};\nalias RGBQUAD* LPRGBQUAD;\n\nstruct BITMAPINFO {\n    BITMAPINFOHEADER bmiHeader;\n    RGBQUAD[1]       bmiColors;\n};\nalias BITMAPINFO* PBITMAPINFO, LPBITMAPINFO;\n\nalias int FXPT16DOT16;\nalias int* LPFXPT16DOT16;\nalias int FXPT2DOT30;\nalias int* LPFXPT2DOT30;\n\nstruct CIEXYZ {\n    FXPT2DOT30 ciexyzX;\n    FXPT2DOT30 ciexyzY;\n    FXPT2DOT30 ciexyzZ;\n}\nalias CIEXYZ* LPCIEXYZ;\n\nstruct CIEXYZTRIPLE {\n    CIEXYZ ciexyzRed;\n    CIEXYZ ciexyzGreen;\n    CIEXYZ ciexyzBlue;\n}\nalias CIEXYZTRIPLE* LPCIEXYZTRIPLE;\n\nstruct BITMAPV4HEADER {\n    DWORD        bV4Size;\n    LONG         bV4Width;\n    LONG         bV4Height;\n    WORD         bV4Planes;\n    WORD         bV4BitCount;\n    DWORD        bV4V4Compression;\n    DWORD        bV4SizeImage;\n    LONG         bV4XPelsPerMeter;\n    LONG         bV4YPelsPerMeter;\n    DWORD        bV4ClrUsed;\n    DWORD        bV4ClrImportant;\n    DWORD        bV4RedMask;\n    DWORD        bV4GreenMask;\n    DWORD        bV4BlueMask;\n    DWORD        bV4AlphaMask;\n    DWORD        bV4CSType;\n    CIEXYZTRIPLE bV4Endpoints;\n    DWORD        bV4GammaRed;\n    DWORD        bV4GammaGreen;\n    DWORD        bV4GammaBlue;\n}\nalias BITMAPV4HEADER* LPBITMAPV4HEADER, PBITMAPV4HEADER;\n\nstruct BITMAPV5HEADER {\n    DWORD bV5Size;\n    LONG bV5Width;\n    LONG bV5Height;\n    WORD bV5Planes;\n    WORD bV5BitCount;\n    DWORD bV5Compression;\n    DWORD bV5SizeImage;\n    LONG bV5XPelsPerMeter;\n    LONG bV5YPelsPerMeter;\n    DWORD bV5ClrUsed;\n    DWORD bV5ClrImportant;\n    DWORD bV5RedMask;\n    DWORD bV5GreenMask;\n    DWORD bV5BlueMask;\n    DWORD bV5AlphaMask;\n    DWORD bV5CSType;\n    CIEXYZTRIPLE bV5Endpoints;\n    DWORD bV5GammaRed;\n    DWORD bV5GammaGreen;\n    DWORD bV5GammaBlue;\n    DWORD bV5Intent;\n    DWORD bV5ProfileData;\n    DWORD bV5ProfileSize;\n    DWORD bV5Reserved;\n}\nalias BITMAPV5HEADER* LPBITMAPV5HEADER, PBITMAPV5HEADER;\n\nstruct FONTSIGNATURE {\n    DWORD[4] fsUsb;\n    DWORD[2] fsCsb;\n}\nalias FONTSIGNATURE* PFONTSIGNATURE, LPFONTSIGNATURE;\n\nstruct CHARSETINFO {\n    UINT ciCharset;\n    UINT ciACP;\n    FONTSIGNATURE fs;\n}\nalias CHARSETINFO* PCHARSETINFO, NPCHARSETINFO, LPCHARSETINFO;\n\nstruct COLORADJUSTMENT {\n    WORD  caSize;\n    WORD  caFlags;\n    WORD  caIlluminantIndex;\n    WORD  caRedGamma;\n    WORD  caGreenGamma;\n    WORD  caBlueGamma;\n    WORD  caReferenceBlack;\n    WORD  caReferenceWhite;\n    SHORT caContrast;\n    SHORT caBrightness;\n    SHORT caColorfulness;\n    SHORT caRedGreenTint;\n}\nalias COLORADJUSTMENT* PCOLORADJUSTMENT, LPCOLORADJUSTMENT;\n\nstruct DEVMODEA {\n    BYTE[CCHDEVICENAME] dmDeviceName;\n    WORD   dmSpecVersion;\n    WORD   dmDriverVersion;\n    WORD   dmSize;\n    WORD   dmDriverExtra;\n    DWORD  dmFields;\n    union {\n        struct {\n            short dmOrientation;\n            short dmPaperSize;\n            short dmPaperLength;\n            short dmPaperWidth;\n            short dmScale;\n            short dmCopies;\n            short dmDefaultSource;\n            short dmPrintQuality;\n        }\n        struct {\n            POINTL dmPosition;\n            DWORD  dmDisplayOrientation;\n            DWORD  dmDisplayFixedOutput;\n        }\n    }\n    short  dmColor;\n    short  dmDuplex;\n    short  dmYResolution;\n    short  dmTTOption;\n    short  dmCollate;\n    BYTE[CCHFORMNAME]   dmFormName;\n    WORD   dmLogPixels;\n    DWORD  dmBitsPerPel;\n    DWORD  dmPelsWidth;\n    DWORD  dmPelsHeight;\n    union {\n        DWORD  dmDisplayFlags;\n        DWORD  dmNup;\n    }\n    DWORD  dmDisplayFrequency;\n    DWORD  dmICMMethod;\n    DWORD  dmICMIntent;\n    DWORD  dmMediaType;\n    DWORD  dmDitherType;\n    DWORD  dmReserved1;\n    DWORD  dmReserved2;\n    DWORD  dmPanningWidth;\n    DWORD  dmPanningHeight;\n}\nalias DEVMODEA* PDEVMODEA, NPDEVMODEA, LPDEVMODEA;\n\nstruct DEVMODEW {\n    WCHAR[CCHDEVICENAME]   dmDeviceName;\n    WORD   dmSpecVersion;\n    WORD   dmDriverVersion;\n    WORD   dmSize;\n    WORD   dmDriverExtra;\n    DWORD  dmFields;\n    union {\n        struct {\n            short dmOrientation;\n            short dmPaperSize;\n            short dmPaperLength;\n            short dmPaperWidth;\n            short dmScale;\n            short dmCopies;\n            short dmDefaultSource;\n            short dmPrintQuality;\n        }\n        struct {\n            POINTL dmPosition;\n            DWORD  dmDisplayOrientation;\n            DWORD  dmDisplayFixedOutput;\n        }\n    }\n\n    short  dmColor;\n    short  dmDuplex;\n    short  dmYResolution;\n    short  dmTTOption;\n    short  dmCollate;\n    WCHAR[CCHFORMNAME]  dmFormName;\n    WORD   dmLogPixels;\n    DWORD  dmBitsPerPel;\n    DWORD  dmPelsWidth;\n    DWORD  dmPelsHeight;\n    union {\n        DWORD  dmDisplayFlags;\n        DWORD  dmNup;\n    }\n    DWORD  dmDisplayFrequency;\n    DWORD  dmICMMethod;\n    DWORD  dmICMIntent;\n    DWORD  dmMediaType;\n    DWORD  dmDitherType;\n    DWORD  dmReserved1;\n    DWORD  dmReserved2;\n    DWORD  dmPanningWidth;\n    DWORD  dmPanningHeight;\n}\nalias DEVMODEW* PDEVMODEW, NPDEVMODEW, LPDEVMODEW;\n\n/*\n * Information about output options\n */\nstruct PSFEATURE_OUTPUT {\n    BOOL bPageIndependent;\n    BOOL bSetPageDevice;\n}\nalias PSFEATURE_OUTPUT* PPSFEATURE_OUTPUT;\n\n/*\n * Information about custom paper size\n */\nstruct PSFEATURE_CUSTPAPER {\n    LONG lOrientation;\n    LONG lWidth;\n    LONG lHeight;\n    LONG lWidthOffset;\n    LONG lHeightOffset;\n}\nalias PSFEATURE_CUSTPAPER* PPSFEATURE_CUSTPAPER;\n\nstruct DIBSECTION {\n    BITMAP           dsBm;\n    BITMAPINFOHEADER dsBmih;\n    DWORD[3]         dsBitfields;\n    HANDLE           dshSection;\n    DWORD            dsOffset;\n}\nalias DIBSECTION* PDIBSECTION;\n\nstruct DOCINFOA {\n    int    cbSize = DOCINFOA.sizeof;\n    LPCSTR lpszDocName;\n    LPCSTR lpszOutput;\n    LPCSTR lpszDatatype;\n    DWORD  fwType;\n}\nalias DOCINFOA* LPDOCINFOA;\n\nstruct DOCINFOW {\n    int     cbSize = DOCINFOW.sizeof;\n    LPCWSTR lpszDocName;\n    LPCWSTR lpszOutput;\n    LPCWSTR lpszDatatype;\n    DWORD   fwType;\n}\nalias DOCINFOW* LPDOCINFOW;\n\n\nstruct PANOSE {\n    BYTE bFamilyType;\n    BYTE bSerifStyle;\n    BYTE bWeight;\n    BYTE bProportion;\n    BYTE bContrast;\n    BYTE bStrokeVariation;\n    BYTE bArmStyle;\n    BYTE bLetterform;\n    BYTE bMidline;\n    BYTE bXHeight;\n}\nalias PANOSE* LPPANOSE;\n\nstruct LOGFONTA {\n    LONG lfHeight;\n    LONG lfWidth;\n    LONG lfEscapement;\n    LONG lfOrientation;\n    LONG lfWeight;\n    BYTE lfItalic;\n    BYTE lfUnderline;\n    BYTE lfStrikeOut;\n    BYTE lfCharSet;\n    BYTE lfOutPrecision;\n    BYTE lfClipPrecision;\n    BYTE lfQuality;\n    BYTE lfPitchAndFamily;\n    CHAR[LF_FACESIZE] lfFaceName;\n}\nalias LOGFONTA* PLOGFONTA, NPLOGFONTA, LPLOGFONTA;\n\nstruct LOGFONTW {\n    LONG lfHeight;\n    LONG lfWidth;\n    LONG lfEscapement;\n    LONG lfOrientation;\n    LONG lfWeight;\n    BYTE lfItalic;\n    BYTE lfUnderline;\n    BYTE lfStrikeOut;\n    BYTE lfCharSet;\n    BYTE lfOutPrecision;\n    BYTE lfClipPrecision;\n    BYTE lfQuality;\n    BYTE lfPitchAndFamily;\n    WCHAR[LF_FACESIZE] lfFaceName;\n}\nalias LOGFONTW* PLOGFONTW, NPLOGFONTW, LPLOGFONTW;\n\nstruct EXTLOGFONTA {\n    LOGFONTA              elfLogFont;\n    BYTE[LF_FULLFACESIZE] elfFullName;\n    BYTE[LF_FACESIZE]     elfStyle;\n    DWORD                 elfVersion;\n    DWORD                 elfStyleSize;\n    DWORD                 elfMatch;\n    DWORD                 elfReserved;\n    BYTE[ELF_VENDOR_SIZE] elfVendorId;\n    DWORD                 elfCulture;\n    PANOSE                elfPanose;\n}\nalias EXTLOGFONTA* PEXTLOGFONTA, NPEXTLOGFONTA, LPEXTLOGFONTA;\n\nstruct EXTLOGFONTW {\n    LOGFONTW               elfLogFont;\n    WCHAR[LF_FULLFACESIZE] elfFullName;\n    WCHAR[LF_FACESIZE]     elfStyle;\n    DWORD                  elfVersion;\n    DWORD                  elfStyleSize;\n    DWORD                  elfMatch;\n    DWORD                  elfReserved;\n    BYTE[ELF_VENDOR_SIZE]  elfVendorId;\n    DWORD                  elfCulture;\n    PANOSE                 elfPanose;\n}\nalias EXTLOGFONTW* PEXTLOGFONTW, NPEXTLOGFONTW, LPEXTLOGFONTW;\n\nstruct LOGPEN {\n    UINT     lopnStyle;\n    POINT    lopnWidth;\n    COLORREF lopnColor;\n}\nalias LOGPEN* PLOGPEN, NPLOGPEN, LPLOGPEN;\n\n// ---------------------- EMR ------------\n\nstruct EMR {\n    DWORD iType;\n    DWORD nSize;\n}\nalias EMR* PEMR;\n\nstruct EMRANGLEARC {\n    EMR    emr;\n    POINTL ptlCenter;\n    DWORD  nRadius;\n    FLOAT  eStartAngle;\n    FLOAT  eSweepAngle;\n}\nalias EMRANGLEARC* PEMRANGLEARC;\n\nstruct EMRARC {\n    EMR    emr;\n    RECTL  rclBox;\n    POINTL ptlStart;\n    POINTL ptlEnd;\n}\nalias EMRARC* PEMRARC;\nalias TypeDef!(EMRARC) EMRARCTO;\nalias EMRARCTO* PEMRARCTO;\nalias TypeDef!(EMRARC) EMRCHORD;\nalias EMRCHORD* PEMRCHORD;\nalias TypeDef!(EMRARC) EMRPIE;\nalias EMRPIE* PEMRPIE;\n\nstruct XFORM {\n    FLOAT eM11;\n    FLOAT eM12;\n    FLOAT eM21;\n    FLOAT eM22;\n    FLOAT eDx;\n    FLOAT eDy;\n}\nalias XFORM* PXFORM, LPXFORM;\n\nstruct EMRBITBLT {\n    EMR      emr;\n    RECTL    rclBounds;\n    LONG     xDest;\n    LONG     yDest;\n    LONG     cxDest;\n    LONG     cyDest;\n    DWORD    dwRop;\n    LONG     xSrc;\n    LONG     ySrc;\n    XFORM    xformSrc;\n    COLORREF crBkColorSrc;\n    DWORD    iUsageSrc;\n    DWORD    offBmiSrc;\n    DWORD    cbBmiSrc;\n    DWORD    offBitsSrc;\n    DWORD    cbBitsSrc;\n}\nalias EMRBITBLT* PEMRBITBLT;\n\nstruct LOGBRUSH {\n    UINT     lbStyle;\n    COLORREF lbColor;\n    ULONG_PTR lbHatch;\n}\nalias TypeDef!(LOGBRUSH) PATTERN;\nalias LOGBRUSH* PLOGBRUSH, NPLOGBRUSH, LPLOGBRUSH;\nalias PATTERN* PPATTERN, NPPATTERN, LPPATTERN;\n\nstruct LOGBRUSH32 {\n    UINT lbStyle;\n    COLORREF lbColor;\n    ULONG lbHatch;\n}\nalias LOGBRUSH32* PLOGBRUSH32, NPLOGBRUSH32, LPLOGBRUSH32;\n\nstruct EMRCREATEBRUSHINDIRECT {\n    EMR      emr;\n    DWORD    ihBrush;\n    LOGBRUSH32 lb;\n}\nalias EMRCREATEBRUSHINDIRECT* PEMRCREATEBRUSHINDIRECT;\n\nalias LONG LCSCSTYPE, LCSGAMUTMATCH;\n\nstruct LOGCOLORSPACEA {\n    DWORD lcsSignature;\n    DWORD lcsVersion;\n    DWORD lcsSize;\n    LCSCSTYPE lcsCSType;\n    LCSGAMUTMATCH lcsIntent;\n    CIEXYZTRIPLE lcsEndpoints;\n    DWORD lcsGammaRed;\n    DWORD lcsGammaGreen;\n    DWORD lcsGammaBlue;\n    CHAR[MAX_PATH] lcsFilename;\n}\nalias LOGCOLORSPACEA* LPLOGCOLORSPACEA;\n\nstruct LOGCOLORSPACEW {\n    DWORD lcsSignature;\n    DWORD lcsVersion;\n    DWORD lcsSize;\n    LCSCSTYPE lcsCSType;\n    LCSGAMUTMATCH lcsIntent;\n    CIEXYZTRIPLE lcsEndpoints;\n    DWORD lcsGammaRed;\n    DWORD lcsGammaGreen;\n    DWORD lcsGammaBlue;\n    WCHAR[MAX_PATH] lcsFilename;\n}\nalias LOGCOLORSPACEW* LPLOGCOLORSPACEW;\n\nalias USHORT COLOR16;\nstruct TRIVERTEX {\n    LONG x;\n    LONG y;\n    COLOR16 Red;\n    COLOR16 Green;\n    COLOR16 Blue;\n    COLOR16 Alpha;\n}\nalias TRIVERTEX* PTRIVERTEX, LPTRIVERTEX;\n\nstruct EMRGLSRECORD {\n    EMR emr;\n    DWORD cbData;\n    BYTE[1] Data;\n}\nalias EMRGLSRECORD* PEMRGLSRECORD;\n\nstruct EMRGLSBOUNDEDRECORD {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD cbData;\n    BYTE[1] Data;\n}\nalias EMRGLSBOUNDEDRECORD* PEMRGLSBOUNDEDRECORD;\n\nstruct EMRPIXELFORMAT {\n    EMR emr;\n    PIXELFORMATDESCRIPTOR pfd;\n}\nalias EMRPIXELFORMAT* PEMRPIXELFORMAT;\n\nstruct EMRCREATECOLORSPACE {\n    EMR emr;\n    DWORD ihCS;\n    LOGCOLORSPACEA lcs; // ANSI version\n}\nalias EMRCREATECOLORSPACE* PEMRCREATECOLORSPACE;\n\nstruct EMRSETCOLORSPACE {\n    EMR emr;\n    DWORD ihCS;\n}\nalias EMRSETCOLORSPACE* PEMRSETCOLORSPACE;\nalias TypeDef!(EMRSETCOLORSPACE) EMRSELECTCOLORSPACE;\nalias EMRSELECTCOLORSPACE* PEMRSELECTCOLORSPACE;\nalias TypeDef!(EMRSETCOLORSPACE) EMRDELETECOLORSPACE;\nalias EMRDELETECOLORSPACE* PEMRDELETECOLORSPACE;\n\nstatic if (_WIN32_WINNT >= 0x500) {\n\n    struct EMREXTESCAPE {\n        EMR emr;\n        INT iEscape;\n        INT cbEscData;\n        BYTE[1] EscData;\n    }\n    alias EMREXTESCAPE* PEMREXTESCAPE;\n    alias TypeDef!(EMREXTESCAPE) EMRDRAWESCAPE;\n    alias EMRDRAWESCAPE* PEMRDRAWESCAPE;\n\n    struct EMRNAMEDESCAPE {\n        EMR emr;\n        INT iEscape;\n        INT cbDriver;\n        INT cbEscData;\n        BYTE[1] EscData;\n    }\n    alias EMRNAMEDESCAPE* PEMRNAMEDESCAPE;\n\n    struct EMRSETICMPROFILE {\n        EMR emr;\n        DWORD dwFlags;\n        DWORD cbName;\n        DWORD cbData;\n        BYTE[1] Data;\n    }\n    alias EMRSETICMPROFILE* PEMRSETICMPROFILE;\n    alias TypeDef!(EMRSETICMPROFILE) EMRSETICMPROFILEA;\n    alias EMRSETICMPROFILEA* PEMRSETICMPROFILEA;\n    alias TypeDef!(EMRSETICMPROFILE) EMRSETICMPROFILEW;\n    alias EMRSETICMPROFILEW* PEMRSETICMPROFILEW;\n\n    struct EMRCREATECOLORSPACEW {\n        EMR emr;\n        DWORD ihCS;\n        LOGCOLORSPACEW lcs;\n        DWORD dwFlags;\n        DWORD cbData;\n        BYTE[1] Data;\n    }\n    alias EMRCREATECOLORSPACEW* PEMRCREATECOLORSPACEW;\n\n    struct EMRCOLORMATCHTOTARGET {\n        EMR emr;\n        DWORD dwAction;\n        DWORD dwFlags;\n        DWORD cbName;\n        DWORD cbData;\n        BYTE[1] Data;\n    }\n    alias EMRCOLORMATCHTOTARGET* PEMRCOLORMATCHTOTARGET;\n\n    struct EMRCOLORCORRECTPALETTE {\n        EMR emr;\n        DWORD ihPalette;\n        DWORD nFirstEntry;\n        DWORD nPalEntries;\n        DWORD nReserved;\n    }\n    alias EMRCOLORCORRECTPALETTE* PEMRCOLORCORRECTPALETTE;\n\n    struct EMRALPHABLEND {\n        EMR emr;\n        RECTL rclBounds;\n        LONG xDest;\n        LONG yDest;\n        LONG cxDest;\n        LONG cyDest;\n        DWORD dwRop;\n        LONG xSrc;\n        LONG ySrc;\n        XFORM xformSrc;\n        COLORREF crBkColorSrc;\n        DWORD iUsageSrc;\n        DWORD offBmiSrc;\n        DWORD cbBmiSrc;\n        DWORD offBitsSrc;\n        DWORD cbBitsSrc;\n        LONG cxSrc;\n        LONG cySrc;\n    }\n    alias EMRALPHABLEND* PEMRALPHABLEND;\n\n    struct EMRGRADIENTFILL {\n        EMR emr;\n        RECTL rclBounds;\n        DWORD nVer;\n        DWORD nTri;\n        ULONG ulMode;\n        TRIVERTEX[1] Ver;\n    }\n    alias EMRGRADIENTFILL* PEMRGRADIENTFILL;\n\n    struct EMRTRANSPARENTBLT {\n        EMR emr;\n        RECTL rclBounds;\n        LONG xDest;\n        LONG yDest;\n        LONG cxDest;\n        LONG cyDest;\n        DWORD dwRop;\n        LONG xSrc;\n        LONG ySrc;\n        XFORM xformSrc;\n        COLORREF crBkColorSrc;\n        DWORD iUsageSrc;\n        DWORD offBmiSrc;\n        DWORD cbBmiSrc;\n        DWORD offBitsSrc;\n        DWORD cbBitsSrc;\n        LONG cxSrc;\n        LONG cySrc;\n    }\n    alias EMRTRANSPARENTBLT* PEMRTRANSPARENTBLT;\n}\n\nstruct EMRCREATEDIBPATTERNBRUSHPT {\n    EMR emr;\n    DWORD ihBrush;\n    DWORD iUsage;\n    DWORD offBmi;\n    DWORD cbBmi;\n    DWORD offBits;\n    DWORD cbBits;\n}\nalias EMRCREATEDIBPATTERNBRUSHPT* PEMRCREATEDIBPATTERNBRUSHPT;\n\nstruct EMRCREATEMONOBRUSH {\n    EMR emr;\n    DWORD ihBrush;\n    DWORD iUsage;\n    DWORD offBmi;\n    DWORD cbBmi;\n    DWORD offBits;\n    DWORD cbBits;\n}\nalias EMRCREATEMONOBRUSH* PEMRCREATEMONOBRUSH;\n\nstruct PALETTEENTRY {\n    BYTE peRed;\n    BYTE peGreen;\n    BYTE peBlue;\n    BYTE peFlags;\n}\nalias PALETTEENTRY* PPALETTEENTRY, LPPALETTEENTRY;\n\nstruct LOGPALETTE {\n    WORD palVersion;\n    WORD palNumEntries;\n    PALETTEENTRY[1] palPalEntry;\n}\nalias LOGPALETTE* PLOGPALETTE, NPLOGPALETTE, LPLOGPALETTE;\n\nstruct EMRCREATEPALETTE {\n    EMR emr;\n    DWORD ihPal;\n    LOGPALETTE lgpl;\n}\nalias EMRCREATEPALETTE* PEMRCREATEPALETTE;\n\nstruct EMRCREATEPEN {\n    EMR emr;\n    DWORD ihPen;\n    LOGPEN lopn;\n}\nalias EMRCREATEPEN* PEMRCREATEPEN;\n\nstruct EMRELLIPSE {\n    EMR emr;\n    RECTL rclBox;\n}\nalias EMRELLIPSE* PEMRELLIPSE;\n\nalias TypeDef!(EMRELLIPSE) EMRRECTANGLE;\nalias EMRRECTANGLE* PEMRRECTANGLE;\n\nstruct EMREOF {\n    EMR emr;\n    DWORD nPalEntries;\n    DWORD offPalEntries;\n    DWORD nSizeLast;\n}\nalias EMREOF* PEMREOF;\n\nstruct EMREXCLUDECLIPRECT {\n    EMR emr;\n    RECTL rclClip;\n}\nalias EMREXCLUDECLIPRECT* PEMREXCLUDECLIPRECT;\nalias TypeDef!(EMREXCLUDECLIPRECT) EMRINTERSECTCLIPRECT;\nalias EMRINTERSECTCLIPRECT* PEMRINTERSECTCLIPRECT;\n\nstruct EMREXTCREATEFONTINDIRECTW {\n    EMR emr;\n    DWORD ihFont;\n    EXTLOGFONTW elfw;\n}\nalias EMREXTCREATEFONTINDIRECTW* PEMREXTCREATEFONTINDIRECTW;\n\nstruct EXTLOGPEN {\n    UINT elpPenStyle;\n    UINT elpWidth;\n    UINT elpBrushStyle;\n    COLORREF elpColor;\n    ULONG_PTR elpHatch;\n    DWORD elpNumEntries;\n    DWORD[1] elpStyleEntry;\n}\nalias EXTLOGPEN* PEXTLOGPEN, NPEXTLOGPEN, LPEXTLOGPEN;\n\nstruct EXTLOGPEN32 {\n    UINT elpPenStyle;\n    UINT elpWidth;\n    UINT elpBrushStyle;\n    COLORREF elpColor;\n    ULONG elpHatch;\n    DWORD elpNumEntries;\n    DWORD[1] elpStyleEntry;\n}\nalias EXTLOGPEN32* PEXTLOGPEN32, NPEXTLOGPEN32, LPEXTLOGPEN32;\n\nstruct EMREXTCREATEPEN {\n    EMR emr;\n    DWORD ihPen;\n    DWORD offBmi;\n    DWORD cbBmi;\n    DWORD offBits;\n    DWORD cbBits;\n    EXTLOGPEN32 elp;\n}\nalias EMREXTCREATEPEN* PEMREXTCREATEPEN;\n\nstruct EMREXTFLOODFILL {\n    EMR emr;\n    POINTL ptlStart;\n    COLORREF crColor;\n    DWORD iMode;\n}\nalias EMREXTFLOODFILL* PEMREXTFLOODFILL;\n\nstruct EMREXTSELECTCLIPRGN {\n    EMR emr;\n    DWORD cbRgnData;\n    DWORD iMode;\n    BYTE [1]RgnData;\n}\nalias EMREXTSELECTCLIPRGN* PEMREXTSELECTCLIPRGN;\n\nstruct EMRTEXT {\n    POINTL ptlReference;\n    DWORD nChars;\n    DWORD offString;\n    DWORD fOptions;\n    RECTL rcl;\n    DWORD offDx;\n}\nalias EMRTEXT* PEMRTEXT;\n\nstruct EMREXTTEXTOUTA {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD iGraphicsMode;\n    FLOAT exScale;\n    FLOAT eyScale;\n    EMRTEXT emrtext;\n}\nalias EMREXTTEXTOUTA* PEMREXTTEXTOUTA;\nalias TypeDef!(EMREXTTEXTOUTA) EMREXTTEXTOUTW;\nalias EMREXTTEXTOUTW* PEMREXTTEXTOUTW;\n\nstruct EMRFILLPATH {\n    EMR emr;\n    RECTL rclBounds;\n}\nalias EMRFILLPATH* PEMRFILLPATH;\n\nalias TypeDef!(EMRFILLPATH) EMRSTROKEANDFILLPATH;\nalias EMRSTROKEANDFILLPATH* PEMRSTROKEANDFILLPATH;\n\nalias TypeDef!(EMRFILLPATH) EMRSTROKEPATH;\nalias EMRSTROKEPATH* PEMRSTROKEPATH;\n\nstruct EMRFILLRGN {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD cbRgnData;\n    DWORD ihBrush;\n    BYTE[1] RgnData;\n}\nalias EMRFILLRGN* PEMRFILLRGN;\n\nstruct EMRFORMAT {\n    DWORD dSignature;\n    DWORD nVersion;\n    DWORD cbData;\n    DWORD offData;\n}\nalias EMRFORMAT* PEMRFORMAT;\n\nstruct EMRFRAMERGN {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD cbRgnData;\n    DWORD ihBrush;\n    SIZEL szlStroke;\n    BYTE[1] RgnData;\n}\nalias EMRFRAMERGN* PEMRFRAMERGN;\n\nstruct EMRGDICOMMENT {\n    EMR emr;\n    DWORD cbData;\n    BYTE[1] Data;\n}\nalias EMRGDICOMMENT* PEMRGDICOMMENT;\n\nstruct EMRINVERTRGN {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD cbRgnData;\n    BYTE[1] RgnData;\n}\nalias EMRINVERTRGN* PEMRINVERTRGN;\nalias TypeDef!(EMRINVERTRGN) EMRPAINTRGN;\nalias EMRPAINTRGN* PEMRPAINTRGN;\n\nstruct EMRLINETO {\n    EMR emr;\n    POINTL ptl;\n}\nalias EMRLINETO* PEMRLINETO;\nalias TypeDef!(EMRLINETO) EMRMOVETOEX;\nalias EMRMOVETOEX* PEMRMOVETOEX;\n\nstruct EMRMASKBLT {\n    EMR emr;\n    RECTL rclBounds;\n    LONG xDest;\n    LONG yDest;\n    LONG cxDest;\n    LONG cyDest;\n    DWORD dwRop;\n    LONG xSrc;\n    LONG ySrc;\n    XFORM xformSrc;\n    COLORREF crBkColorSrc;\n    DWORD iUsageSrc;\n    DWORD offBmiSrc;\n    DWORD cbBmiSrc;\n    DWORD offBitsSrc;\n    DWORD cbBitsSrc;\n    LONG xMask;\n    LONG yMask;\n    DWORD iUsageMask;\n    DWORD offBmiMask;\n    DWORD cbBmiMask;\n    DWORD offBitsMask;\n    DWORD cbBitsMask;\n}\nalias EMRMASKBLT* PEMRMASKBLT;\n\nstruct EMRMODIFYWORLDTRANSFORM {\n    EMR emr;\n    XFORM xform;\n    DWORD iMode;\n}\nalias EMRMODIFYWORLDTRANSFORM* PEMRMODIFYWORLDTRANSFORM;\n\nstruct EMROFFSETCLIPRGN {\n    EMR emr;\n    POINTL ptlOffset;\n}\nalias EMROFFSETCLIPRGN* PEMROFFSETCLIPRGN;\n\nstruct EMRPLGBLT {\n    EMR emr;\n    RECTL rclBounds;\n    POINTL[3] aptlDest;\n    LONG xSrc;\n    LONG ySrc;\n    LONG cxSrc;\n    LONG cySrc;\n    XFORM xformSrc;\n    COLORREF crBkColorSrc;\n    DWORD iUsageSrc;\n    DWORD offBmiSrc;\n    DWORD cbBmiSrc;\n    DWORD offBitsSrc;\n    DWORD cbBitsSrc;\n    LONG xMask;\n    LONG yMask;\n    DWORD iUsageMask;\n    DWORD offBmiMask;\n    DWORD cbBmiMask;\n    DWORD offBitsMask;\n    DWORD cbBitsMask;\n}\nalias EMRPLGBLT* PEMRPLGBLT;\n\nstruct EMRPOLYDRAW {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD cptl;\n    POINTL[1] aptl;\n    BYTE[1] abTypes;\n}\nalias EMRPOLYDRAW* PEMRPOLYDRAW;\n\nstruct EMRPOLYDRAW16 {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD cpts;\n    POINTS[1] apts;\n    BYTE[1] abTypes;\n}\nalias EMRPOLYDRAW16* PEMRPOLYDRAW16;\n\nstruct EMRPOLYLINE {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD cptl;\n    POINTL[1] aptl;\n}\nalias EMRPOLYLINE* PEMRPOLYLINE;\nalias TypeDef!(EMRPOLYLINE) EMRPOLYBEZIER;\nalias EMRPOLYBEZIER* PEMRPOLYBEZIER;\nalias TypeDef!(EMRPOLYLINE) EMRPOLYGON;\nalias EMRPOLYGON* PEMRPOLYGON;\nalias TypeDef!(EMRPOLYLINE) EMRPOLYBEZIERTO;\nalias EMRPOLYBEZIERTO* PEMRPOLYBEZIERTO;\nalias TypeDef!(EMRPOLYLINE) EMRPOLYLINETO;\nalias EMRPOLYLINETO* PEMRPOLYLINETO;\n\nstruct EMRPOLYLINE16 {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD cpts;\n    POINTS[1] apts;\n}\nalias EMRPOLYLINE16* PEMRPOLYLINE16;\nalias TypeDef!(EMRPOLYLINE16) EMRPOLYBEZIER16;\nalias EMRPOLYBEZIER16* PEMRPOLYBEZIER16;\nalias TypeDef!(EMRPOLYLINE16) EMRPOLYGON16;\nalias EMRPOLYGON16* PEMRPOLYGON16;\nalias TypeDef!(EMRPOLYLINE16) EMRPOLYBEZIERTO16;\nalias EMRPOLYBEZIERTO16* PEMRPOLYBEZIERTO16;\nalias TypeDef!(EMRPOLYLINE16) EMRPOLYLINETO16;\nalias EMRPOLYLINETO16* PEMRPOLYLINETO16;\n\nstruct EMRPOLYPOLYLINE {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD nPolys;\n    DWORD cptl;\n    DWORD[1] aPolyCounts;\n    POINTL[1] aptl;\n}\nalias EMRPOLYPOLYLINE* PEMRPOLYPOLYLINE;\nalias TypeDef!(EMRPOLYPOLYLINE) EMRPOLYPOLYGON;\nalias EMRPOLYPOLYGON* PEMRPOLYPOLYGON;\n\nstruct EMRPOLYPOLYLINE16 {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD nPolys;\n    DWORD cpts;\n    DWORD[1] aPolyCounts;\n    POINTS[1] apts;\n}\nalias EMRPOLYPOLYLINE16* PEMRPOLYPOLYLINE16;\nalias TypeDef!(EMRPOLYPOLYLINE16) EMRPOLYPOLYGON16;\nalias EMRPOLYPOLYGON16* PEMRPOLYPOLYGON16;\n\nstruct EMRPOLYTEXTOUTA {\n    EMR emr;\n    RECTL rclBounds;\n    DWORD iGraphicsMode;\n    FLOAT exScale;\n    FLOAT eyScale;\n    LONG cStrings;\n    EMRTEXT[1] aemrtext;\n}\nalias EMRPOLYTEXTOUTA* PEMRPOLYTEXTOUTA;\nalias TypeDef!(EMRPOLYTEXTOUTA) EMRPOLYTEXTOUTW;\nalias EMRPOLYTEXTOUTW* PEMRPOLYTEXTOUTW;\n\nstruct EMRRESIZEPALETTE {\n    EMR emr;\n    DWORD ihPal;\n    DWORD cEntries;\n}\nalias EMRRESIZEPALETTE* PEMRRESIZEPALETTE;\n\nstruct EMRRESTOREDC {\n    EMR emr;\n    LONG iRelative;\n}\nalias EMRRESTOREDC* PEMRRESTOREDC;\n\nstruct EMRROUNDRECT {\n    EMR emr;\n    RECTL rclBox;\n    SIZEL szlCorner;\n}\nalias EMRROUNDRECT* PEMRROUNDRECT;\n\nstruct EMRSCALEVIEWPORTEXTEX {\n    EMR emr;\n    LONG xNum;\n    LONG xDenom;\n    LONG yNum;\n    LONG yDenom;\n}\nalias EMRSCALEVIEWPORTEXTEX* PEMRSCALEVIEWPORTEXTEX;\nalias TypeDef!(EMRSCALEVIEWPORTEXTEX) EMRSCALEWINDOWEXTEX;\nalias EMRSCALEWINDOWEXTEX* PEMRSCALEWINDOWEXTEX;\n\nstruct EMRSELECTOBJECT {\n    EMR emr;\n    DWORD ihObject;\n}\nalias EMRSELECTOBJECT* PEMRSELECTOBJECT;\nalias TypeDef!(EMRSELECTOBJECT) EMRDELETEOBJECT;\nalias EMRDELETEOBJECT* PEMRDELETEOBJECT;\n\nstruct EMRSELECTPALETTE {\n    EMR emr;\n    DWORD ihPal;\n}\nalias EMRSELECTPALETTE* PEMRSELECTPALETTE;\n\nstruct EMRSETARCDIRECTION {\n    EMR emr;\n    DWORD iArcDirection;\n}\nalias EMRSETARCDIRECTION* PEMRSETARCDIRECTION;\n\nstruct EMRSETTEXTCOLOR {\n    EMR emr;\n    COLORREF crColor;\n}\nalias EMRSETTEXTCOLOR* PEMRSETTEXTCOLOR;\nalias TypeDef!(EMRSETTEXTCOLOR) EMRSETBKCOLOR;\nalias EMRSETBKCOLOR* PEMRSETBKCOLOR;\n\nstruct EMRSETCOLORADJUSTMENT {\n    EMR emr;\n    COLORADJUSTMENT ColorAdjustment;\n}\nalias EMRSETCOLORADJUSTMENT* PEMRSETCOLORADJUSTMENT;\n\nstruct EMRSETDIBITSTODEVICE {\n    EMR emr;\n    RECTL rclBounds;\n    LONG xDest;\n    LONG yDest;\n    LONG xSrc;\n    LONG ySrc;\n    LONG cxSrc;\n    LONG cySrc;\n    DWORD offBmiSrc;\n    DWORD cbBmiSrc;\n    DWORD offBitsSrc;\n    DWORD cbBitsSrc;\n    DWORD iUsageSrc;\n    DWORD iStartScan;\n    DWORD cScans;\n}\nalias EMRSETDIBITSTODEVICE* PEMRSETDIBITSTODEVICE;\n\nstruct EMRSETMAPPERFLAGS {\n    EMR emr;\n    DWORD dwFlags;\n}\nalias EMRSETMAPPERFLAGS* PEMRSETMAPPERFLAGS;\n\nstruct EMRSETMITERLIMIT {\n    EMR emr;\n    FLOAT eMiterLimit;\n}\nalias EMRSETMITERLIMIT* PEMRSETMITERLIMIT;\n\nstruct EMRSETPALETTEENTRIES {\n    EMR emr;\n    DWORD ihPal;\n    DWORD iStart;\n    DWORD cEntries;\n    PALETTEENTRY[1] aPalEntries;\n}\nalias EMRSETPALETTEENTRIES* PEMRSETPALETTEENTRIES;\n\nstruct EMRSETPIXELV {\n    EMR emr;\n    POINTL ptlPixel;\n    COLORREF crColor;\n}\nalias EMRSETPIXELV* PEMRSETPIXELV;\n\nstruct EMRSETVIEWPORTEXTEX {\n    EMR emr;\n    SIZEL szlExtent;\n}\nalias EMRSETVIEWPORTEXTEX* PEMRSETVIEWPORTEXTEX;\nalias TypeDef!(EMRSETVIEWPORTEXTEX) EMRSETWINDOWEXTEX;\nalias EMRSETWINDOWEXTEX* PEMRSETWINDOWEXTEX;\n\nstruct EMRSETVIEWPORTORGEX {\n    EMR emr;\n    POINTL ptlOrigin;\n}\nalias EMRSETVIEWPORTORGEX* PEMRSETVIEWPORTORGEX;\nalias TypeDef!(EMRSETVIEWPORTORGEX) EMRSETWINDOWORGEX;\nalias EMRSETWINDOWORGEX* PEMRSETWINDOWORGEX;\nalias TypeDef!(EMRSETVIEWPORTORGEX) EMRSETBRUSHORGEX;\nalias EMRSETBRUSHORGEX* PEMRSETBRUSHORGEX;\n\nstruct EMRSETWORLDTRANSFORM {\n    EMR emr;\n    XFORM xform;\n}\nalias EMRSETWORLDTRANSFORM* PEMRSETWORLDTRANSFORM;\n\nstruct EMRSTRETCHBLT {\n    EMR emr;\n    RECTL rclBounds;\n    LONG xDest;\n    LONG yDest;\n    LONG cxDest;\n    LONG cyDest;\n    DWORD dwRop;\n    LONG xSrc;\n    LONG ySrc;\n    XFORM xformSrc;\n    COLORREF crBkColorSrc;\n    DWORD iUsageSrc;\n    DWORD offBmiSrc;\n    DWORD cbBmiSrc;\n    DWORD offBitsSrc;\n    DWORD cbBitsSrc;\n    LONG cxSrc;\n    LONG cySrc;\n}\nalias EMRSTRETCHBLT* PEMRSTRETCHBLT;\n\nstruct EMRSTRETCHDIBITS {\n    EMR emr;\n    RECTL rclBounds;\n    LONG xDest;\n    LONG yDest;\n    LONG xSrc;\n    LONG ySrc;\n    LONG cxSrc;\n    LONG cySrc;\n    DWORD offBmiSrc;\n    DWORD cbBmiSrc;\n    DWORD offBitsSrc;\n    DWORD cbBitsSrc;\n    DWORD iUsageSrc;\n    DWORD dwRop;\n    LONG cxDest;\n    LONG cyDest;\n}\nalias EMRSTRETCHDIBITS* PEMRSTRETCHDIBITS;\n\nstruct EMRABORTPATH {\n    EMR emr;\n}\nalias EMRABORTPATH* PEMRABORTPATH;\nalias TypeDef!(EMRABORTPATH) EMRBEGINPATH;\nalias EMRBEGINPATH* PEMRBEGINPATH;\nalias TypeDef!(EMRABORTPATH) EMRENDPATH;\nalias EMRENDPATH* PEMRENDPATH;\nalias TypeDef!(EMRABORTPATH) EMRCLOSEFIGURE;\nalias EMRCLOSEFIGURE* PEMRCLOSEFIGURE;\nalias TypeDef!(EMRABORTPATH) EMRFLATTENPATH;\nalias EMRFLATTENPATH* PEMRFLATTENPATH;\nalias TypeDef!(EMRABORTPATH) EMRWIDENPATH;\nalias EMRWIDENPATH* PEMRWIDENPATH;\nalias TypeDef!(EMRABORTPATH) EMRSETMETARGN;\nalias EMRSETMETARGN* PEMRSETMETARGN;\nalias TypeDef!(EMRABORTPATH) EMRSAVEDC;\nalias EMRSAVEDC* PEMRSAVEDC;\nalias TypeDef!(EMRABORTPATH) EMRREALIZEPALETTE;\nalias EMRREALIZEPALETTE* PEMRREALIZEPALETTE;\n\nstruct EMRSELECTCLIPPATH {\n    EMR emr;\n    DWORD iMode;\n}\nalias EMRSELECTCLIPPATH* PEMRSELECTCLIPPATH;\nalias TypeDef!(EMRSELECTCLIPPATH) EMRSETBKMODE;\nalias EMRSETBKMODE* PEMRSETBKMODE;\nalias TypeDef!(EMRSELECTCLIPPATH) EMRSETMAPMODE;\nalias EMRSETMAPMODE* PEMRSETMAPMODE;\nalias TypeDef!(EMRSELECTCLIPPATH) EMRSETPOLYFILLMODE;\nalias EMRSETPOLYFILLMODE* PEMRSETPOLYFILLMODE;\nalias TypeDef!(EMRSELECTCLIPPATH) EMRSETROP2;\nalias EMRSETROP2* PEMRSETROP2;\nalias TypeDef!(EMRSELECTCLIPPATH) EMRSETSTRETCHBLTMODE;\nalias EMRSETSTRETCHBLTMODE* PEMRSETSTRETCHBLTMODE;\nalias TypeDef!(EMRSELECTCLIPPATH) EMRSETICMMODE;\nalias EMRSETICMMODE* PEMRSETICMMODE;\nalias TypeDef!(EMRSELECTCLIPPATH) EMRSETTEXTALIGN;\nalias EMRSETTEXTALIGN* PEMRSETTEXTALIGN;\nalias TypeDef!(EMRSELECTCLIPPATH) EMRENABLEICM;\nalias EMRENABLEICM* PEMRENABLEICM;\nstatic if (_WIN32_WINNT >= 0x500) {\n    alias TypeDef!(EMRSELECTCLIPPATH) EMRSETLAYOUT;\n    alias EMRSETLAYOUT* PEMRSETLAYOUT;\n}\n\nalign(2):\nstruct METAHEADER {\nalign(2):\n    WORD mtType;\n    WORD mtHeaderSize;\n    WORD mtVersion;\n    DWORD mtSize;\n    WORD mtNoObjects;\n    DWORD mtMaxRecord;\n    WORD mtNoParameters;\n}\nalias METAHEADER* PMETAHEADER;\nalias METAHEADER* LPMETAHEADER;\n\nalign:\n\nstruct ENHMETAHEADER {\n    DWORD iType = EMR_HEADER;\n    DWORD nSize = ENHMETAHEADER.sizeof;\n    RECTL rclBounds;\n    RECTL rclFrame;\n    DWORD dSignature = ENHMETA_SIGNATURE;\n    DWORD nVersion;\n    DWORD nBytes;\n    DWORD nRecords;\n    WORD nHandles;\n    WORD sReserved;\n    DWORD nDescription;\n    DWORD offDescription;\n    DWORD nPalEntries;\n    SIZEL szlDevice;\n    SIZEL szlMillimeters;\n    DWORD cbPixelFormat;\n    DWORD offPixelFormat;\n    DWORD bOpenGL;\n    static if (_WIN32_WINNT >= 0x500) {\n        SIZEL szlMicrometers;\n    }\n}\nalias ENHMETAHEADER* PENHMETAHEADER, LPENHMETAHEADER;\n\nstruct METARECORD {\n    DWORD rdSize;\n    WORD rdFunction;\n    WORD[1] rdParm;\n}\nalias METARECORD* PMETARECORD;\nalias METARECORD* LPMETARECORD;\n\nstruct ENHMETARECORD {\n    DWORD iType;\n    DWORD nSize;\n    DWORD[1] dParm;\n}\nalias ENHMETARECORD* PENHMETARECORD, LPENHMETARECORD;\n\n// ---\n\nstruct HANDLETABLE {\n    HGDIOBJ[1] objectHandle;\n}\nalias HANDLETABLE* PHANDLETABLE, LPHANDLETABLE;\n\nstruct TEXTMETRICA {\n    LONG tmHeight;\n    LONG tmAscent;\n    LONG tmDescent;\n    LONG tmInternalLeading;\n    LONG tmExternalLeading;\n    LONG tmAveCharWidth;\n    LONG tmMaxCharWidth;\n    LONG tmWeight;\n    LONG tmOverhang;\n    LONG tmDigitizedAspectX;\n    LONG tmDigitizedAspectY;\n    BYTE tmFirstChar;\n    BYTE tmLastChar;\n    BYTE tmDefaultChar;\n    BYTE tmBreakChar;\n    BYTE tmItalic;\n    BYTE tmUnderlined;\n    BYTE tmStruckOut;\n    BYTE tmPitchAndFamily;\n    BYTE tmCharSet;\n}\nalias TEXTMETRICA* PTEXTMETRICA, NPTEXTMETRICA, LPTEXTMETRICA;\n\nstruct TEXTMETRICW {\n    LONG tmHeight;\n    LONG tmAscent;\n    LONG tmDescent;\n    LONG tmInternalLeading;\n    LONG tmExternalLeading;\n    LONG tmAveCharWidth;\n    LONG tmMaxCharWidth;\n    LONG tmWeight;\n    LONG tmOverhang;\n    LONG tmDigitizedAspectX;\n    LONG tmDigitizedAspectY;\n    WCHAR tmFirstChar;\n    WCHAR tmLastChar;\n    WCHAR tmDefaultChar;\n    WCHAR tmBreakChar;\n    BYTE tmItalic;\n    BYTE tmUnderlined;\n    BYTE tmStruckOut;\n    BYTE tmPitchAndFamily;\n    BYTE tmCharSet;\n}\nalias TEXTMETRICW* PTEXTMETRICW, NPTEXTMETRICW, LPTEXTMETRICW;\n\nstruct RGNDATAHEADER {\n    DWORD dwSize;\n    DWORD iType;\n    DWORD nCount;\n    DWORD nRgnSize;\n    RECT rcBound;\n}\nalias RGNDATAHEADER* PRGNDATAHEADER;\n\nstruct RGNDATA {\n    RGNDATAHEADER rdh;\n    char[1] Buffer;\n}\nalias RGNDATA* PRGNDATA, NPRGNDATA, LPRGNDATA;\n\n/* for GetRandomRgn */\nenum SYSRGN=4;\nstruct GCP_RESULTSA {\n    DWORD lStructSize;\n    LPSTR lpOutString;\n    UINT* lpOrder;\n    INT* lpDx;\n    INT* lpCaretPos;\n    LPSTR lpClass;\n    LPWSTR lpGlyphs;\n    UINT nGlyphs;\n    UINT nMaxFit;\n}\nalias GCP_RESULTSA* LPGCP_RESULTSA;\n\nstruct GCP_RESULTSW {\n    DWORD lStructSize;\n    LPWSTR lpOutString;\n    UINT* lpOrder;\n    INT* lpDx;\n    INT* lpCaretPos;\n    LPWSTR lpClass;\n    LPWSTR lpGlyphs;\n    UINT nGlyphs;\n    UINT nMaxFit;\n}\nalias GCP_RESULTSW* LPGCP_RESULTSW;\n\nstruct GLYPHMETRICS {\n    UINT gmBlackBoxX;\n    UINT gmBlackBoxY;\n    POINT gmptGlyphOrigin;\n    short gmCellIncX;\n    short gmCellIncY;\n}\nalias GLYPHMETRICS* LPGLYPHMETRICS;\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    struct WCRANGE {\n        WCHAR  wcLow;\n        USHORT cGlyphs;\n    }\n    alias WCRANGE* PWCRANGE, LPWCRANGE;\n\n    struct GLYPHSET {\n        DWORD cbThis;\n        DWORD flAccel;\n        DWORD cGlyphsSupported;\n        DWORD cRanges;\n        WCRANGE[1] ranges;\n    }\n    alias GLYPHSET* PGLYPHSET, LPGLYPHSET;\n\nenum DWORD GS_8BIT_INDICES = 0x00000001;\n}\n\nstruct KERNINGPAIR {\n    WORD wFirst;\n    WORD wSecond;\n    int iKernAmount;\n}\nalias KERNINGPAIR* LPKERNINGPAIR;\n\nstruct FIXED {\n    WORD fract;\n    short value;\n}\n\nstruct MAT2 {\n    FIXED eM11;\n    FIXED eM12;\n    FIXED eM21;\n    FIXED eM22;\n}\nalias MAT2* LPMAT2;\n\nstruct OUTLINETEXTMETRICA {\n    UINT otmSize;\n    TEXTMETRICA otmTextMetrics;\n    BYTE otmFiller;\n    PANOSE otmPanoseNumber;\n    UINT otmfsSelection;\n    UINT otmfsType;\n    int otmsCharSlopeRise;\n    int otmsCharSlopeRun;\n    int otmItalicAngle;\n    UINT otmEMSquare;\n    int otmAscent;\n    int otmDescent;\n    UINT otmLineGap;\n    UINT otmsCapEmHeight;\n    UINT otmsXHeight;\n    RECT otmrcFontBox;\n    int otmMacAscent;\n    int otmMacDescent;\n    UINT otmMacLineGap;\n    UINT otmusMinimumPPEM;\n    POINT otmptSubscriptSize;\n    POINT otmptSubscriptOffset;\n    POINT otmptSuperscriptSize;\n    POINT otmptSuperscriptOffset;\n    UINT otmsStrikeoutSize;\n    int otmsStrikeoutPosition;\n    int otmsUnderscoreSize;\n    int otmsUnderscorePosition;\n    PSTR otmpFamilyName;\n    PSTR otmpFaceName;\n    PSTR otmpStyleName;\n    PSTR otmpFullName;\n}\nalias OUTLINETEXTMETRICA* POUTLINETEXTMETRICA, NPOUTLINETEXTMETRICA, LPOUTLINETEXTMETRICA;\n\nstruct OUTLINETEXTMETRICW {\n    UINT otmSize;\n    TEXTMETRICW otmTextMetrics;\n    BYTE otmFiller;\n    PANOSE otmPanoseNumber;\n    UINT otmfsSelection;\n    UINT otmfsType;\n    int otmsCharSlopeRise;\n    int otmsCharSlopeRun;\n    int otmItalicAngle;\n    UINT otmEMSquare;\n    int otmAscent;\n    int otmDescent;\n    UINT otmLineGap;\n    UINT otmsCapEmHeight;\n    UINT otmsXHeight;\n    RECT otmrcFontBox;\n    int otmMacAscent;\n    int otmMacDescent;\n    UINT otmMacLineGap;\n    UINT otmusMinimumPPEM;\n    POINT otmptSubscriptSize;\n    POINT otmptSubscriptOffset;\n    POINT otmptSuperscriptSize;\n    POINT otmptSuperscriptOffset;\n    UINT otmsStrikeoutSize;\n    int otmsStrikeoutPosition;\n    int otmsUnderscoreSize;\n    int otmsUnderscorePosition;\n    PSTR otmpFamilyName;\n    PSTR otmpFaceName;\n    PSTR otmpStyleName;\n    PSTR otmpFullName;\n}\nalias OUTLINETEXTMETRICW* POUTLINETEXTMETRICW, NPOUTLINETEXTMETRICW, LPOUTLINETEXTMETRICW;\n\nstruct RASTERIZER_STATUS {\n    short nSize;\n    short wFlags;\n    short nLanguageID;\n}\nalias RASTERIZER_STATUS* LPRASTERIZER_STATUS;\n\nstruct POLYTEXTA {\n    int x;\n    int y;\n    UINT n;\n    LPCSTR lpstr;\n    UINT uiFlags;\n    RECT rcl;\n    int* pdx;\n}\nalias POLYTEXTA* PPOLYTEXTA, NPPOLYTEXTA, LPPOLYTEXTA;\n\nstruct POLYTEXTW {\n    int x;\n    int y;\n    UINT n;\n    LPCWSTR lpstr;\n    UINT uiFlags;\n    RECT rcl;\n    int* pdx;\n}\nalias POLYTEXTW* PPOLYTEXTW, NPPOLYTEXTW, LPPOLYTEXTW;\n\nstruct PIXELFORMATDESCRIPTOR {\n    WORD nSize;\n    WORD nVersion;\n    DWORD dwFlags;\n    BYTE iPixelType;\n    BYTE cColorBits;\n    BYTE cRedBits;\n    BYTE cRedShift;\n    BYTE cGreenBits;\n    BYTE cGreenShift;\n    BYTE cBlueBits;\n    BYTE cBlueShift;\n    BYTE cAlphaBits;\n    BYTE cAlphaShift;\n    BYTE cAccumBits;\n    BYTE cAccumRedBits;\n    BYTE cAccumGreenBits;\n    BYTE cAccumBlueBits;\n    BYTE cAccumAlphaBits;\n    BYTE cDepthBits;\n    BYTE cStencilBits;\n    BYTE cAuxBuffers;\n    BYTE iLayerType;\n    BYTE bReserved;\n    DWORD dwLayerMask;\n    DWORD dwVisibleMask;\n    DWORD dwDamageMask;\n}\nalias PIXELFORMATDESCRIPTOR* PPIXELFORMATDESCRIPTOR, LPPIXELFORMATDESCRIPTOR;\n\nstruct METAFILEPICT {\n    LONG mm;\n    LONG xExt;\n    LONG yExt;\n    HMETAFILE hMF;\n}\nalias METAFILEPICT* LPMETAFILEPICT;\n\nstruct LOCALESIGNATURE {\n    DWORD[4] lsUsb;\n    DWORD[2] lsCsbDefault;\n    DWORD[2] lsCsbSupported;\n}\nalias LOCALESIGNATURE* PLOCALESIGNATURE, LPLOCALESIGNATURE;\n\nalias LONG LCSTYPE; /* What this for? */\n\nalign(4):\nstruct NEWTEXTMETRICA {\n    LONG tmHeight;\n    LONG tmAscent;\n    LONG tmDescent;\n    LONG tmInternalLeading;\n    LONG tmExternalLeading;\n    LONG tmAveCharWidth;\n    LONG tmMaxCharWidth;\n    LONG tmWeight;\n    LONG tmOverhang;\n    LONG tmDigitizedAspectX;\n    LONG tmDigitizedAspectY;\n    BYTE tmFirstChar;\n    BYTE tmLastChar;\n    BYTE tmDefaultChar;\n    BYTE tmBreakChar;\n    BYTE tmItalic;\n    BYTE tmUnderlined;\n    BYTE tmStruckOut;\n    BYTE tmPitchAndFamily;\n    BYTE tmCharSet;\n    DWORD ntmFlags;\n    UINT ntmSizeEM;\n    UINT ntmCellHeight;\n    UINT ntmAvgWidth;\n}\nalias NEWTEXTMETRICA* PNEWTEXTMETRICA, NPNEWTEXTMETRICA, LPNEWTEXTMETRICA;\n\nstruct NEWTEXTMETRICW {\n    LONG tmHeight;\n    LONG tmAscent;\n    LONG tmDescent;\n    LONG tmInternalLeading;\n    LONG tmExternalLeading;\n    LONG tmAveCharWidth;\n    LONG tmMaxCharWidth;\n    LONG tmWeight;\n    LONG tmOverhang;\n    LONG tmDigitizedAspectX;\n    LONG tmDigitizedAspectY;\n    WCHAR tmFirstChar;\n    WCHAR tmLastChar;\n    WCHAR tmDefaultChar;\n    WCHAR tmBreakChar;\n    BYTE tmItalic;\n    BYTE tmUnderlined;\n    BYTE tmStruckOut;\n    BYTE tmPitchAndFamily;\n    BYTE tmCharSet;\n    DWORD ntmFlags;\n    UINT ntmSizeEM;\n    UINT ntmCellHeight;\n    UINT ntmAvgWidth;\n}\nalias NEWTEXTMETRICW* PNEWTEXTMETRICW, NPNEWTEXTMETRICW, LPNEWTEXTMETRICW;\n\nalign:\nstruct NEWTEXTMETRICEXA {\n    NEWTEXTMETRICA ntmTm;\n    FONTSIGNATURE ntmFontSig;\n}\n\nstruct NEWTEXTMETRICEXW {\n    NEWTEXTMETRICW ntmTm;\n    FONTSIGNATURE ntmFontSig;\n}\n\nstruct PELARRAY {\n    LONG paXCount;\n    LONG paYCount;\n    LONG paXExt;\n    LONG paYExt;\n    BYTE paRGBs;\n}\nalias PELARRAY* PPELARRAY, NPPELARRAY, LPPELARRAY;\n\nstruct ENUMLOGFONTA {\n    LOGFONTA elfLogFont;\n    BYTE[LF_FULLFACESIZE] elfFullName;\n    BYTE[LF_FACESIZE] elfStyle;\n}\nalias ENUMLOGFONTA* LPENUMLOGFONTA;\n\nstruct ENUMLOGFONTW {\n    LOGFONTW elfLogFont;\n    WCHAR[LF_FULLFACESIZE] elfFullName;\n    WCHAR[LF_FACESIZE] elfStyle;\n}\nalias ENUMLOGFONTW* LPENUMLOGFONTW;\n\nstruct ENUMLOGFONTEXA {\n    LOGFONTA elfLogFont;\n    BYTE[LF_FULLFACESIZE] elfFullName;\n    BYTE[LF_FACESIZE] elfStyle;\n    BYTE[LF_FACESIZE] elfScript;\n}\nalias ENUMLOGFONTEXA* LPENUMLOGFONTEXA;\n\nstruct ENUMLOGFONTEXW {\n    LOGFONTW elfLogFont;\n    WCHAR[LF_FULLFACESIZE] elfFullName;\n    WCHAR[LF_FACESIZE] elfStyle;\n    WCHAR[LF_FACESIZE] elfScript;\n}\nalias ENUMLOGFONTEXW* LPENUMLOGFONTEXW;\n\nstruct POINTFX {\n    FIXED x;\n    FIXED y;\n}\nalias POINTFX* LPPOINTFX;\n\nstruct TTPOLYCURVE {\n    WORD wType;\n    WORD cpfx;\n    POINTFX[1] apfx;\n}\nalias TTPOLYCURVE* LPTTPOLYCURVE;\n\nstruct TTPOLYGONHEADER {\n    DWORD cb;\n    DWORD dwType;\n    POINTFX pfxStart;\n}\nalias TTPOLYGONHEADER* LPTTPOLYGONHEADER;\n\nstruct POINTFLOAT {\n    FLOAT x;\n    FLOAT y;\n}\nalias POINTFLOAT* PPOINTFLOAT;\n\nstruct GLYPHMETRICSFLOAT {\n    FLOAT gmfBlackBoxX;\n    FLOAT gmfBlackBoxY;\n    POINTFLOAT gmfptGlyphOrigin;\n    FLOAT gmfCellIncX;\n    FLOAT gmfCellIncY;\n}\nalias GLYPHMETRICSFLOAT* PGLYPHMETRICSFLOAT, LPGLYPHMETRICSFLOAT;\n\nstruct LAYERPLANEDESCRIPTOR {\n    WORD nSize;\n    WORD nVersion;\n    DWORD dwFlags;\n    BYTE iPixelType;\n    BYTE cColorBits;\n    BYTE cRedBits;\n    BYTE cRedShift;\n    BYTE cGreenBits;\n    BYTE cGreenShift;\n    BYTE cBlueBits;\n    BYTE cBlueShift;\n    BYTE cAlphaBits;\n    BYTE cAlphaShift;\n    BYTE cAccumBits;\n    BYTE cAccumRedBits;\n    BYTE cAccumGreenBits;\n    BYTE cAccumBlueBits;\n    BYTE cAccumAlphaBits;\n    BYTE cDepthBits;\n    BYTE cStencilBits;\n    BYTE cAuxBuffers;\n    BYTE iLayerPlane;\n    BYTE bReserved;\n    COLORREF crTransparent;\n}\nalias LAYERPLANEDESCRIPTOR* PLAYERPLANEDESCRIPTOR, LPLAYERPLANEDESCRIPTOR;\n\nstruct BLENDFUNCTION {\n    BYTE BlendOp;\n    BYTE BlendFlags;\n    BYTE SourceConstantAlpha;\n    BYTE AlphaFormat;\n}\nalias BLENDFUNCTION* PBLENDFUNCTION, LPBLENDFUNCTION;\n\nenum MM_MAX_NUMAXES = 16;\n\nstruct DESIGNVECTOR {\n    DWORD dvReserved;\n    DWORD dvNumAxes;\n    LONG[MM_MAX_NUMAXES] dvValues;\n}\nalias DESIGNVECTOR* PDESIGNVECTOR, LPDESIGNVECTOR;\nenum STAMP_DESIGNVECTOR = 0x8000000 + 'd' + ('v' << 8);\nenum STAMP_AXESLIST     = 0x8000000 + 'a' + ('l' << 8);\n\nstatic if (_WIN32_WINNT >= 0x500) {\n\nenum MM_MAX_AXES_NAMELEN = 16;\n\n    struct AXISINFOA {\n        LONG axMinValue;\n        LONG axMaxValue;\n        BYTE[MM_MAX_AXES_NAMELEN] axAxisName;\n    }\n    alias AXISINFOA* PAXISINFOA, LPAXISINFOA;\n\n    struct AXISINFOW {\n        LONG axMinValue;\n        LONG axMaxValue;\n        WCHAR[MM_MAX_AXES_NAMELEN] axAxisName;\n    }\n    alias AXISINFOW* PAXISINFOW, LPAXISINFOW;\n\n    version (Unicode) {\n        alias AXISINFOW AXISINFO;\n        alias PAXISINFOW PAXISINFO;\n        alias LPAXISINFOW LPAXISINFO;\n    }\n    else {\n        alias AXISINFOA AXISINFO;\n        alias PAXISINFOA PAXISINFO;\n        alias LPAXISINFOA LPAXISINFO;\n    }\n\n    struct AXESLISTA {\n        DWORD axlReserved;\n        DWORD axlNumAxes;\n        AXISINFOA[MM_MAX_NUMAXES] axlAxisInfo;\n    }\n    alias AXESLISTA* PAXESLISTA, LPAXESLISTA;\n\n    struct AXESLISTW {\n        DWORD axlReserved;\n        DWORD axlNumAxes;\n        AXISINFOW[MM_MAX_NUMAXES] axlAxisInfo;\n    }\n    alias AXESLISTW* PAXESLISTW, LPAXESLISTW;\n\n    version (Unicode) {\n        alias AXESLISTW AXESLIST;\n        alias PAXESLISTW PAXESLIST;\n        alias LPAXESLISTW LPAXESLIST;\n    }\n    else {\n        alias AXESLISTA AXESLIST;\n        alias PAXESLISTA PAXESLIST;\n        alias LPAXESLISTA LPAXESLIST;\n    }\n\n    struct ENUMLOGFONTEXDVA {\n        ENUMLOGFONTEXA elfEnumLogfontEx;\n        DESIGNVECTOR   elfDesignVector;\n    }\n    alias ENUMLOGFONTEXDVA* PENUMLOGFONTEXDVA, LPENUMLOGFONTEXDVA;\n\n    struct ENUMLOGFONTEXDVW {\n        ENUMLOGFONTEXW elfEnumLogfontEx;\n        DESIGNVECTOR   elfDesignVector;\n    }\n    alias ENUMLOGFONTEXDVW* PENUMLOGFONTEXDVW, LPENUMLOGFONTEXDVW;\n\nextern(Windows) nothrow @nogc {\n    HFONT CreateFontIndirectExA(const(ENUMLOGFONTEXDVA)*);\n    HFONT CreateFontIndirectExW(const(ENUMLOGFONTEXDVW)*);\n}\n    version (Unicode)\n        alias CreateFontIndirectExW CreateFontIndirectEx;\n    else\n        alias CreateFontIndirectExA CreateFontIndirectEx;\n\n    struct ENUMTEXTMETRICA {\n        NEWTEXTMETRICEXA etmNewTextMetricEx;\n        AXESLISTA etmAxesList;\n    }\n    alias ENUMTEXTMETRICA* PENUMTEXTMETRICA, LPENUMTEXTMETRICA;\n\n    struct ENUMTEXTMETRICW {\n        NEWTEXTMETRICEXW etmNewTextMetricEx;\n        AXESLISTW etmAxesList;\n    }\n    alias ENUMTEXTMETRICW* PENUMTEXTMETRICW, LPENUMTEXTMETRICW;\n\n    version (Unicode) {\n        alias ENUMTEXTMETRICW ENUMTEXTMETRIC;\n        alias PENUMTEXTMETRICW PENUMTEXTMETRIC;\n        alias LPENUMTEXTMETRICW LPENUMTEXTMETRIC;\n    }\n    else {\n        alias ENUMTEXTMETRICA ENUMTEXTMETRIC;\n        alias PENUMTEXTMETRICA PENUMTEXTMETRIC;\n        alias LPENUMTEXTMETRICA LPENUMTEXTMETRIC;\n    }\n} /* _WIN32_WINNT >= 0x500 */\n\nstruct GRADIENT_TRIANGLE {\n    ULONG Vertex1;\n    ULONG Vertex2;\n    ULONG Vertex3;\n}\nalias GRADIENT_TRIANGLE* PGRADIENT_TRIANGLE, LPGRADIENT_TRIANGLE;\n\nstruct GRADIENT_RECT {\n    ULONG UpperLeft;\n    ULONG LowerRight;\n}\nalias GRADIENT_RECT* PGRADIENT_RECT, LPGRADIENT_RECT;\n\nstruct DISPLAY_DEVICEA {\n    DWORD cb;\n    CHAR[32] DeviceName;\n    CHAR[128] DeviceString;\n    DWORD StateFlags;\n    CHAR[128] DeviceID;\n    CHAR[128] DeviceKey;\n}\nalias DISPLAY_DEVICEA* PDISPLAY_DEVICEA, LPDISPLAY_DEVICEA;\n\nstruct DISPLAY_DEVICEW {\n    DWORD cb;\n    WCHAR[32] DeviceName;\n    WCHAR[128] DeviceString;\n    DWORD StateFlags;\n    WCHAR[128] DeviceID;\n    WCHAR[128] DeviceKey;\n}\nalias DISPLAY_DEVICEW* PDISPLAY_DEVICEW, LPDISPLAY_DEVICEW;\n\nstruct DRAWPATRECT {\n    POINT ptPosition;\n    POINT ptSize;\n    WORD wStyle;\n    WORD wPattern;\n}\nalias DRAWPATRECT* PDRAWPATRECT;\n\n// ---------\n// Callbacks\nextern (Windows) {\n    alias BOOL function (HDC, int) ABORTPROC;\n    alias int function (HDC, HANDLETABLE*, METARECORD*, int, LPARAM) MFENUMPROC;\n    alias int function (HDC, HANDLETABLE*, const(ENHMETARECORD)*, int, LPARAM) ENHMFENUMPROC;\n    alias int function (const(LOGFONTA)*, const(TEXTMETRICA)*, DWORD, LPARAM) FONTENUMPROCA, OLDFONTENUMPROCA;\n    alias int function (const(LOGFONTW)*, const(TEXTMETRICW)*, DWORD, LPARAM) FONTENUMPROCW, OLDFONTENUMPROCW;\n    alias int function (LPSTR, LPARAM) ICMENUMPROCA;\n    alias int function (LPWSTR, LPARAM) ICMENUMPROCW;\n    alias void function (LPVOID, LPARAM) GOBJENUMPROC;\n    alias void function (int, int, LPARAM) LINEDDAPROC;\n    alias UINT function (HWND, HMODULE, LPDEVMODEA, LPSTR, LPSTR, LPDEVMODEA, LPSTR, UINT) LPFNDEVMODE;\n    alias DWORD function (LPSTR, LPSTR, UINT, LPSTR, LPDEVMODEA) LPFNDEVCAPS;\n}\n\n// ---------\n// C Macros.\n// FIXME:\n//POINTS MAKEPOINTS(DWORD dwValue) #define MAKEPOINTS(l) (*((POINTS*)&(l)))\n\nnothrow @nogc {\n    DWORD MAKEROP4(DWORD fore, DWORD back) {\n        return ((back<<8) & 0xFF000000) | (fore);\n    }\n\n    COLORREF CMYK(BYTE c, BYTE m, BYTE y, BYTE k) {\n        return cast(COLORREF)(k | (y << 8) | (m << 16) | (c << 24));\n    }\n\n    BYTE GetCValue(COLORREF cmyk) {\n        return cast(BYTE)(cmyk >> 24);\n    }\n\n    BYTE GetMValue(COLORREF cmyk) {\n        return cast(BYTE)(cmyk >> 16);\n    }\n\n    BYTE GetYValue(COLORREF cmyk) {\n        return cast(BYTE)(cmyk >> 8);\n    }\n\n    BYTE GetKValue(COLORREF cmyk) {\n        return cast(BYTE)cmyk;\n    }\n\n    COLORREF RGB(/*BYTE*/uint r, /*BYTE*/uint g, /*BYTE*/uint b) {\n        return cast(COLORREF)(r | (g << 8) | (b << 16));\n    }\n\n    BYTE GetRValue(COLORREF c) {\n        return cast(BYTE)c;\n    }\n\n    BYTE GetGValue(COLORREF c) {\n        return cast(BYTE)(c >> 8);\n    }\n\n    BYTE GetBValue(COLORREF c) {\n        return cast(BYTE)(c >> 16);\n    }\n\n    COLORREF PALETTEINDEX(WORD i) {\n        return 0x01000000 | cast(COLORREF) i;\n    }\n\n    COLORREF PALETTERGB(BYTE r, BYTE g, BYTE b) {\n        return 0x02000000|RGB(r, g, b);\n    }\n}\n\nextern(Windows) nothrow @nogc {\n    int AbortDoc(HDC);\n    BOOL AbortPath(HDC);\n    int AddFontResourceA(LPCSTR);\n    int AddFontResourceW(LPCWSTR);\n    BOOL AngleArc(HDC, int, int, DWORD, FLOAT, FLOAT);\n    BOOL AnimatePalette(HPALETTE, UINT, UINT, const(PALETTEENTRY)*);\n    BOOL Arc(HDC, int, int, int, int, int, int, int, int);\n    BOOL ArcTo(HDC, int, int, int, int, int, int, int, int);\n    BOOL BeginPath(HDC);\n    BOOL BitBlt(HDC, int, int, int, int, HDC, int, int, DWORD);\n    BOOL CancelDC(HDC);\n    BOOL CheckColorsInGamut(HDC, PVOID, PVOID, DWORD);\n    BOOL Chord(HDC, int, int, int, int, int, int, int, int);\n    int ChoosePixelFormat(HDC, const(PIXELFORMATDESCRIPTOR)*);\n    HENHMETAFILE CloseEnhMetaFile(HDC);\n    BOOL CloseFigure(HDC);\n    HMETAFILE CloseMetaFile(HDC);\n    BOOL ColorMatchToTarget(HDC, HDC, DWORD);\n    BOOL ColorCorrectPalette(HDC, HPALETTE, DWORD, DWORD);\n    int CombineRgn(HRGN, HRGN, HRGN, int);\n    BOOL CombineTransform(LPXFORM, const(XFORM)*, const(XFORM)*);\n    HENHMETAFILE CopyEnhMetaFileA(HENHMETAFILE, LPCSTR);\n    HENHMETAFILE CopyEnhMetaFileW(HENHMETAFILE, LPCWSTR);\n    HMETAFILE CopyMetaFileA(HMETAFILE, LPCSTR);\n    HMETAFILE CopyMetaFileW(HMETAFILE, LPCWSTR);\n    HBITMAP CreateBitmap(int, int, UINT, UINT, PCVOID);\n    HBITMAP CreateBitmapIndirect(const(BITMAP)*);\n    HBRUSH CreateBrushIndirect(const(LOGBRUSH)*);\n    HCOLORSPACE CreateColorSpaceA(LPLOGCOLORSPACEA);\n    HCOLORSPACE CreateColorSpaceW(LPLOGCOLORSPACEW);\n    HBITMAP CreateCompatibleBitmap(HDC, int, int);\n    HDC CreateCompatibleDC(HDC);\n    HDC CreateDCA(LPCSTR, LPCSTR, LPCSTR, const(DEVMODEA)*);\n    HDC CreateDCW(LPCWSTR, LPCWSTR, LPCWSTR, const(DEVMODEW)*);\n    HBITMAP CreateDIBitmap(HDC, const(BITMAPINFOHEADER)*, DWORD, PCVOID, const(BITMAPINFO)*, UINT);\n    HBRUSH CreateDIBPatternBrush(HGLOBAL, UINT);\n    HBRUSH CreateDIBPatternBrushPt(PCVOID, UINT);\n    HBITMAP CreateDIBSection(HDC, const(BITMAPINFO)*, UINT, void**, HANDLE, DWORD);\n    HBITMAP CreateDiscardableBitmap(HDC, int, int);\n    HRGN CreateEllipticRgn(int, int, int, int);\n    HRGN CreateEllipticRgnIndirect(LPCRECT);\n    HDC CreateEnhMetaFileA(HDC, LPCSTR, LPCRECT, LPCSTR);\n    HDC CreateEnhMetaFileW(HDC, LPCWSTR, LPCRECT, LPCWSTR);\n    HFONT CreateFontA(int, int, int, int, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPCSTR);\n    HFONT CreateFontW(int, int, int, int, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPCWSTR);\n    HFONT CreateFontIndirectA(const(LOGFONTA)*);\n    HFONT CreateFontIndirectW(const(LOGFONTW)*);\n    HPALETTE CreateHalftonePalette(HDC);\n    HBRUSH CreateHatchBrush(int, COLORREF);\n    HDC CreateICA(LPCSTR, LPCSTR, LPCSTR, const(DEVMODEA)*);\n    HDC CreateICW(LPCWSTR, LPCWSTR, LPCWSTR, const(DEVMODEW)*);\n    HDC CreateMetaFileA(LPCSTR);\n    HDC CreateMetaFileW(LPCWSTR);\n    HPALETTE CreatePalette(const(LOGPALETTE)*);\n    HBRUSH CreatePatternBrush(HBITMAP);\n    HPEN CreatePen(int, int, COLORREF);\n    HPEN CreatePenIndirect(const(LOGPEN)*);\n    HRGN CreatePolygonRgn(const(POINT)*, int, int);\n    HRGN CreatePolyPolygonRgn(const(POINT)*, const(INT)*, int, int);\n    HRGN CreateRectRgn(int, int, int, int);\n    HRGN CreateRectRgnIndirect(LPCRECT);\n    HRGN CreateRoundRectRgn(int, int, int, int, int, int);\n    BOOL CreateScalableFontResourceA(DWORD, LPCSTR, LPCSTR, LPCSTR);\n    BOOL CreateScalableFontResourceW(DWORD, LPCWSTR, LPCWSTR, LPCWSTR);\n    HBRUSH CreateSolidBrush(COLORREF);\n    BOOL DeleteColorSpace(HCOLORSPACE);\n    BOOL DeleteDC(HDC);\n    BOOL DeleteEnhMetaFile(HENHMETAFILE);\n    BOOL DeleteMetaFile(HMETAFILE);\n    BOOL DeleteObject(HGDIOBJ);\n    int DescribePixelFormat(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);\n    DWORD DeviceCapabilitiesA(LPCSTR, LPCSTR, WORD, LPSTR, const(DEVMODEA)*);\n    DWORD DeviceCapabilitiesW(LPCWSTR, LPCWSTR, WORD, LPWSTR, const(DEVMODEW)*);\n    BOOL DPtoLP(HDC, LPPOINT, int);\n    int DrawEscape(HDC, int, int, LPCSTR);\n    BOOL Ellipse(HDC, int, int, int, int);\n    int EndDoc(HDC);\n    int EndPage(HDC);\n    BOOL EndPath(HDC);\n    BOOL EnumEnhMetaFile(HDC, HENHMETAFILE, ENHMFENUMPROC, PVOID, LPCRECT);\n    int EnumFontFamiliesA(HDC, LPCSTR, FONTENUMPROCA, LPARAM);\n    int EnumFontFamiliesW(HDC, LPCWSTR, FONTENUMPROCW, LPARAM);\n    int EnumFontFamiliesExA(HDC, PLOGFONTA, FONTENUMPROCA, LPARAM, DWORD);\n    int EnumFontFamiliesExW(HDC, PLOGFONTW, FONTENUMPROCW, LPARAM, DWORD);\n    int EnumFontsA(HDC, LPCSTR, FONTENUMPROCA, LPARAM);\n    int EnumFontsW(HDC, LPCWSTR, FONTENUMPROCW, LPARAM);\n    int EnumICMProfilesA(HDC, ICMENUMPROCA, LPARAM);\n    int EnumICMProfilesW(HDC, ICMENUMPROCW, LPARAM);\n    BOOL EnumMetaFile(HDC, HMETAFILE, MFENUMPROC, LPARAM);\n    int EnumObjects(HDC, int, GOBJENUMPROC, LPARAM);\n    BOOL EqualRgn(HRGN, HRGN);\n    int Escape(HDC, int, int, LPCSTR, PVOID);\n    int ExcludeClipRect(HDC, int, int, int, int);\n    int ExcludeUpdateRgn(HDC, HWND);\n    HPEN ExtCreatePen(DWORD, DWORD, const(LOGBRUSH)*, DWORD, const(DWORD)*);\n    HRGN ExtCreateRegion(const(XFORM)*, DWORD, const(RGNDATA)*);\n    int ExtEscape(HDC, int, int, LPCSTR, int, LPSTR);\n    BOOL ExtFloodFill(HDC, int, int, COLORREF, UINT);\n    int ExtSelectClipRgn(HDC, HRGN, int);\n    BOOL ExtTextOutA(HDC, int, int, UINT, LPCRECT, LPCSTR, UINT, const(INT)*);\n    BOOL ExtTextOutW(HDC, int, int, UINT, LPCRECT, LPCWSTR, UINT, const(INT)*);\n    BOOL FillPath(HDC);\n    int FillRect(HDC, LPCRECT, HBRUSH);\n    int FillRgn(HDC, HRGN, HBRUSH);\n    BOOL FixBrushOrgEx(HDC, int, int, LPPOINT);\n    BOOL FlattenPath(HDC);\n    BOOL FloodFill(HDC, int, int, COLORREF);\n    BOOL FrameRgn(HDC, HRGN, HBRUSH, int, int);\n    BOOL GdiComment(HDC, UINT, const(BYTE)*);\n    BOOL GdiFlush();\n    DWORD GdiGetBatchLimit();\n    DWORD GdiSetBatchLimit(DWORD);\n    int GetArcDirection(HDC);\n    BOOL GetAspectRatioFilterEx(HDC, LPSIZE);\n    LONG GetBitmapBits(HBITMAP, LONG, PVOID);\n    BOOL GetBitmapDimensionEx(HBITMAP, LPSIZE);\n    COLORREF GetBkColor(HDC);\n    int GetBkMode(HDC);\n    UINT GetBoundsRect(HDC, LPRECT, UINT);\n    BOOL GetBrushOrgEx(HDC, LPPOINT);\n    BOOL GetCharABCWidthsA(HDC, UINT, UINT, LPABC);\n    BOOL GetCharABCWidthsW(HDC, UINT, UINT, LPABC);\n    BOOL GetCharABCWidthsFloatA(HDC, UINT, UINT, LPABCFLOAT);\n    BOOL GetCharABCWidthsFloatW(HDC, UINT, UINT, LPABCFLOAT);\n    DWORD GetCharacterPlacementA(HDC, LPCSTR, int, int, LPGCP_RESULTSA, DWORD);\n    DWORD GetCharacterPlacementW(HDC, LPCWSTR, int, int, LPGCP_RESULTSW, DWORD);\n    BOOL GetCharWidth32A(HDC, UINT, UINT, LPINT);\n    BOOL GetCharWidth32W(HDC, UINT, UINT, LPINT);\n    BOOL GetCharWidthA(HDC, UINT, UINT, LPINT);\n    BOOL GetCharWidthW(HDC, UINT, UINT, LPINT);\n    BOOL GetCharWidthFloatA(HDC, UINT, UINT, PFLOAT);\n    BOOL GetCharWidthFloatW(HDC, UINT, UINT, PFLOAT);\n    int GetClipBox(HDC, LPRECT);\n    int GetClipRgn(HDC, HRGN);\n    BOOL GetColorAdjustment(HDC, LPCOLORADJUSTMENT);\n    HANDLE GetColorSpace(HDC);\n    HGDIOBJ GetCurrentObject(HDC, UINT);\n    BOOL GetCurrentPositionEx(HDC, LPPOINT);\n    HCURSOR GetCursor();\n    BOOL GetDCOrgEx(HDC, LPPOINT);\n    static if (_WIN32_WINNT >= 0x500)\n    {\n        DWORD GetDCPenColor(HGDIOBJ);\n        COLORREF GetDCBrushColor(HGDIOBJ);\n    }\n    int GetDeviceCaps(HDC, int);\n    BOOL GetDeviceGammaRamp(HDC, PVOID);\n    UINT GetDIBColorTable(HDC, UINT, UINT, RGBQUAD*);\n    int GetDIBits(HDC, HBITMAP, UINT, UINT, PVOID, LPBITMAPINFO, UINT);\n    HENHMETAFILE GetEnhMetaFileA(LPCSTR);\n    HENHMETAFILE GetEnhMetaFileW(LPCWSTR);\n    UINT GetEnhMetaFileBits(HENHMETAFILE, UINT, LPBYTE);\n    UINT GetEnhMetaFileDescriptionA(HENHMETAFILE, UINT, LPSTR);\n    UINT GetEnhMetaFileDescriptionW(HENHMETAFILE, UINT, LPWSTR);\n    UINT GetEnhMetaFileHeader(HENHMETAFILE, UINT, LPENHMETAHEADER);\n    UINT GetEnhMetaFilePaletteEntries(HENHMETAFILE, UINT, LPPALETTEENTRY);\n    UINT GetEnhMetaFilePixelFormat(HENHMETAFILE, DWORD, const(PIXELFORMATDESCRIPTOR)*);\n    DWORD GetFontData(HDC, DWORD, DWORD, PVOID, DWORD);\n    DWORD GetFontLanguageInfo(HDC);\n    DWORD GetGlyphOutlineA(HDC, UINT, UINT, LPGLYPHMETRICS, DWORD, PVOID, const(MAT2)*);\n    DWORD GetGlyphOutlineW(HDC, UINT, UINT, LPGLYPHMETRICS, DWORD, PVOID, const(MAT2)*);\n    int GetGraphicsMode(HDC);\n    BOOL GetICMProfileA(HDC, DWORD, LPSTR);\n    BOOL GetICMProfileW(HDC, DWORD, LPWSTR);\n    DWORD GetKerningPairsA(HDC, DWORD, LPKERNINGPAIR);\n    DWORD GetKerningPairsW(HDC, DWORD, LPKERNINGPAIR);\n    BOOL GetLogColorSpaceA(HCOLORSPACE, LPLOGCOLORSPACEA, DWORD);\n    BOOL GetLogColorSpaceW(HCOLORSPACE, LPLOGCOLORSPACEW, DWORD);\n    int GetMapMode(HDC);\n    HMETAFILE GetMetaFileA(LPCSTR);\n    HMETAFILE GetMetaFileW(LPCWSTR);\n    UINT GetMetaFileBitsEx(HMETAFILE, UINT, PVOID);\n    int GetMetaRgn(HDC, HRGN);\n    BOOL GetMiterLimit(HDC, PFLOAT);\n    COLORREF GetNearestColor(HDC, COLORREF);\n    UINT GetNearestPaletteIndex(HPALETTE, COLORREF);\n    int GetObjectA(HGDIOBJ, int, PVOID);\n    int GetObjectW(HGDIOBJ, int, PVOID);\n    DWORD GetObjectType(HGDIOBJ);\n    UINT GetOutlineTextMetricsA(HDC, UINT, LPOUTLINETEXTMETRICA);\n    UINT GetOutlineTextMetricsW(HDC, UINT, LPOUTLINETEXTMETRICW);\n    UINT GetPaletteEntries(HPALETTE, UINT, UINT, LPPALETTEENTRY);\n    int GetPath(HDC, LPPOINT, PBYTE, int);\n    COLORREF GetPixel(HDC, int, int);\n    int GetPixelFormat(HDC);\n    int GetPolyFillMode(HDC);\n    BOOL GetRasterizerCaps(LPRASTERIZER_STATUS, UINT);\n    int GetRandomRgn (HDC, HRGN, INT);\n    DWORD GetRegionData(HRGN, DWORD, LPRGNDATA);\n    int GetRgnBox(HRGN, LPRECT);\n    int GetROP2(HDC);\n    HGDIOBJ GetStockObject(int);\n    int GetStretchBltMode(HDC);\n    UINT GetSystemPaletteEntries(HDC, UINT, UINT, LPPALETTEENTRY);\n    UINT GetSystemPaletteUse(HDC);\n    UINT GetTextAlign(HDC);\n    int GetTextCharacterExtra(HDC);\n    int GetTextCharset(HDC);\n    int GetTextCharsetInfo(HDC, LPFONTSIGNATURE, DWORD);\n    COLORREF GetTextColor(HDC);\n    BOOL GetTextExtentExPointA(HDC, LPCSTR, int, int, LPINT, LPINT, LPSIZE);\n    BOOL GetTextExtentExPointW(HDC, LPCWSTR, int, int, LPINT, LPINT, LPSIZE);\n    BOOL GetTextExtentPointA(HDC, LPCSTR, int, LPSIZE);\n    BOOL GetTextExtentPointW(HDC, LPCWSTR, int, LPSIZE);\n    BOOL GetTextExtentPoint32A(HDC, LPCSTR, int, LPSIZE);\n    BOOL GetTextExtentPoint32W(HDC, LPCWSTR, int, LPSIZE);\n    int GetTextFaceA(HDC, int, LPSTR);\n    int GetTextFaceW(HDC, int, LPWSTR);\n    BOOL GetTextMetricsA(HDC, LPTEXTMETRICA);\n    BOOL GetTextMetricsW(HDC, LPTEXTMETRICW);\n    BOOL GetViewportExtEx(HDC, LPSIZE);\n    BOOL GetViewportOrgEx(HDC, LPPOINT);\n    BOOL GetWindowExtEx(HDC, LPSIZE);\n    BOOL GetWindowOrgEx(HDC, LPPOINT);\n    UINT GetWinMetaFileBits(HENHMETAFILE, UINT, LPBYTE, INT, HDC);\n    BOOL GetWorldTransform(HDC, LPXFORM);\n    int IntersectClipRect(HDC, int, int, int, int);\n    BOOL InvertRgn(HDC, HRGN);\n    BOOL LineDDA(int, int, int, int, LINEDDAPROC, LPARAM);\n    BOOL LineTo(HDC, int, int);\n    BOOL LPtoDP(HDC, LPPOINT, int);\n    BOOL MaskBlt(HDC, int, int, int, int, HDC, int, int, HBITMAP, int, int, DWORD);\n    BOOL ModifyWorldTransform(HDC, const(XFORM)*, DWORD);\n    BOOL MoveToEx(HDC, int, int, LPPOINT);\n    int OffsetClipRgn(HDC, int, int);\n    int OffsetRgn(HRGN, int, int);\n    BOOL OffsetViewportOrgEx(HDC, int, int, LPPOINT);\n    BOOL OffsetWindowOrgEx(HDC, int, int, LPPOINT);\n    BOOL PaintRgn(HDC, HRGN);\n    BOOL PatBlt(HDC, int, int, int, int, DWORD);\n    HRGN PathToRegion(HDC);\n    BOOL Pie(HDC, int, int, int, int, int, int, int, int);\n    BOOL PlayEnhMetaFile(HDC, HENHMETAFILE, LPCRECT);\n    BOOL PlayEnhMetaFileRecord(HDC, LPHANDLETABLE, const(ENHMETARECORD)*, UINT);\n    BOOL PlayMetaFile(HDC, HMETAFILE);\n    BOOL PlayMetaFileRecord(HDC, LPHANDLETABLE, LPMETARECORD, UINT);\n    BOOL PlgBlt(HDC, const(POINT)*, HDC, int, int, int, int, HBITMAP, int, int);\n    BOOL PolyBezier(HDC, const(POINT)*, DWORD);\n    BOOL PolyBezierTo(HDC, const(POINT)*, DWORD);\n    BOOL PolyDraw(HDC, const(POINT)*, const(BYTE)*, int);\n    BOOL Polygon(HDC, const(POINT)*, int);\n    BOOL Polyline(HDC, const(POINT)*, int);\n    BOOL PolylineTo(HDC, const(POINT)*, DWORD);\n    BOOL PolyPolygon(HDC, const(POINT)*, const(INT)*, int);\n    BOOL PolyPolyline(HDC, const(POINT)*, const(DWORD)*, DWORD);\n    BOOL PolyTextOutA(HDC, const(POLYTEXTA)*, int);\n    BOOL PolyTextOutW(HDC, const(POLYTEXTW)*, int);\n    BOOL PtInRegion(HRGN, int, int);\n    BOOL PtVisible(HDC, int, int);\n    UINT RealizePalette(HDC);\n    BOOL Rectangle(HDC, int, int, int, int);\n    BOOL RectInRegion(HRGN, LPCRECT);\n    BOOL RectVisible(HDC, LPCRECT);\n    BOOL RemoveFontResourceA(LPCSTR);\n    BOOL RemoveFontResourceW(LPCWSTR);\n\n    HDC ResetDCA(HDC, const(DEVMODEA)*);\n    HDC ResetDCW(HDC, const(DEVMODEW)*);\n    BOOL ResizePalette(HPALETTE, UINT);\n    BOOL RestoreDC(HDC, int);\n    BOOL RoundRect(HDC, int, int, int, int, int, int);\n    int SaveDC(HDC);\n    BOOL ScaleViewportExtEx(HDC, int, int, int, int, LPSIZE);\n    BOOL ScaleWindowExtEx(HDC, int, int, int, int, LPSIZE);\n    BOOL SelectClipPath(HDC, int);\n    int SelectClipRgn(HDC, HRGN);\n    HGDIOBJ SelectObject(HDC, HGDIOBJ);\n    HPALETTE SelectPalette(HDC, HPALETTE, BOOL);\n    int SetAbortProc(HDC, ABORTPROC);\n    int SetArcDirection(HDC, int);\n    LONG SetBitmapBits(HBITMAP, DWORD, PCVOID);\n    BOOL SetBitmapDimensionEx(HBITMAP, int, int, LPSIZE);\n    COLORREF SetBkColor(HDC, COLORREF);\n    int SetBkMode(HDC, int);\n    UINT SetBoundsRect(HDC, LPCRECT, UINT);\n    BOOL SetBrushOrgEx(HDC, int, int, LPPOINT);\n    BOOL SetColorAdjustment(HDC, const(COLORADJUSTMENT)*);\n    BOOL SetColorSpace(HDC, HCOLORSPACE);\n\n    BOOL SetDeviceGammaRamp(HDC, PVOID);\n    UINT SetDIBColorTable(HDC, UINT, UINT, const(RGBQUAD)*);\n    int SetDIBits(HDC, HBITMAP, UINT, UINT, PCVOID, const(BITMAPINFO)*, UINT);\n    int SetDIBitsToDevice(HDC, int, int, DWORD, DWORD, int, int, UINT, UINT, PCVOID, const(BITMAPINFO)*, UINT);\n    HENHMETAFILE SetEnhMetaFileBits(UINT, const(BYTE)*);\n    int SetGraphicsMode(HDC, int);\n    int SetICMMode(HDC, int);\n    BOOL SetICMProfileA(HDC, LPSTR);\n    BOOL SetICMProfileW(HDC, LPWSTR);\n    int SetMapMode(HDC, int);\n\n    static if (_WIN32_WINNT >= 0x500) {\n        DWORD SetLayout(HDC hdc, DWORD l);\n        DWORD GetLayout(HDC hdc);\n    }\n\n    DWORD SetMapperFlags(HDC, DWORD);\n    HMETAFILE SetMetaFileBitsEx(UINT, const(BYTE)*);\n    int SetMetaRgn(HDC);\n    BOOL SetMiterLimit(HDC, FLOAT, PFLOAT);\n    UINT SetPaletteEntries(HPALETTE, UINT, UINT, const(PALETTEENTRY)*);\n    COLORREF SetPixel(HDC, int, int, COLORREF);\n    BOOL SetPixelFormat(HDC, int, const(PIXELFORMATDESCRIPTOR)*);\n    BOOL SetPixelV(HDC, int, int, COLORREF);\n    int SetPolyFillMode(HDC, int);\n    BOOL SetRectRgn(HRGN, int, int, int, int);\n    int SetROP2(HDC, int);\n    int SetStretchBltMode(HDC, int);\n    UINT SetSystemPaletteUse(HDC, UINT);\n    UINT SetTextAlign(HDC, UINT);\n    int SetTextCharacterExtra(HDC, int);\n    COLORREF SetTextColor(HDC, COLORREF);\n    BOOL SetTextJustification(HDC, int, int);\n    BOOL SetViewportExtEx(HDC, int, int, LPSIZE);\n    BOOL SetViewportOrgEx(HDC, int, int, LPPOINT);\n    BOOL SetWindowExtEx(HDC, int, int, LPSIZE);\n    BOOL SetWindowOrgEx(HDC, int, int, LPPOINT);\n    HENHMETAFILE SetWinMetaFileBits(UINT, const(BYTE)*, HDC, const(METAFILEPICT)*);\n    BOOL SetWorldTransform(HDC, const(XFORM)*);\n    int StartDocA(HDC, const(DOCINFOA)*);\n    int StartDocW(HDC, const(DOCINFOW)*);\n    int StartPage(HDC);\n    BOOL StretchBlt(HDC, int, int, int, int, HDC, int, int, int, int, DWORD);\n    int StretchDIBits(HDC, int, int, int, int, int, int, int, int, const(VOID)* , const(BITMAPINFO)* , UINT, DWORD);\n    BOOL StrokeAndFillPath(HDC);\n    BOOL StrokePath(HDC);\n    BOOL SwapBuffers(HDC);\n    BOOL TextOutA(HDC, int, int, LPCSTR, int);\n    BOOL TextOutW(HDC, int, int, LPCWSTR, int);\n    BOOL TranslateCharsetInfo(PDWORD, LPCHARSETINFO, DWORD);\n    BOOL UnrealizeObject(HGDIOBJ);\n    BOOL UpdateColors(HDC);\n    BOOL UpdateICMRegKeyA(DWORD, DWORD, LPSTR, UINT);\n    BOOL UpdateICMRegKeyW(DWORD, DWORD, LPWSTR, UINT);\n    BOOL WidenPath(HDC);\n    BOOL wglCopyContext(HGLRC, HGLRC, UINT);\n    HGLRC wglCreateContext(HDC);\n    HGLRC wglCreateLayerContext(HDC, int);\n    BOOL wglDeleteContext(HGLRC);\n    BOOL wglDescribeLayerPlane(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR);\n    HGLRC wglGetCurrentContext();\n    HDC wglGetCurrentDC();\n    int wglGetLayerPaletteEntries(HDC, int, int, int, COLORREF*);\n    PROC wglGetProcAddress(LPCSTR);\n    BOOL wglMakeCurrent(HDC, HGLRC);\n    BOOL wglRealizeLayerPalette(HDC, int, BOOL);\n    int wglSetLayerPaletteEntries(HDC, int, int, int, const(COLORREF)*);\n    BOOL wglShareLists(HGLRC, HGLRC);\n    BOOL wglSwapLayerBuffers(HDC, UINT);\n    BOOL wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD);\n    BOOL wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD);\n    BOOL wglUseFontOutlinesA(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT);\n    BOOL wglUseFontOutlinesW(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT);\n\n    static if (_WIN32_WINNT >= 0x500) {\n    alias WGLSWAP* PWGLSWAP;\n    struct WGLSWAP {\n        HDC hdc;\n        UINT uiFlags;\n    }\nenum WGL_SWAPMULTIPLE_MAX = 16;\n    DWORD  wglSwapMultipleBuffers(UINT, WGLSWAP*);\n}\n\nstatic if (_WIN32_WINNT >= 0x500) {\n        BOOL AlphaBlend(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION);\n        BOOL GradientFill(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG);\n        BOOL TransparentBlt(HDC, int, int, int, int, HDC, int, int, int, int, UINT);\n    }\n\n    static if (_WIN32_WINNT >= 0x500) {\n        COLORREF SetDCBrushColor(HDC, COLORREF);\n        COLORREF SetDCPenColor(HDC, COLORREF);\n        HANDLE AddFontMemResourceEx(PVOID, DWORD, PVOID, DWORD*);\n        int AddFontResourceExA(LPCSTR, DWORD, PVOID);\n        int AddFontResourceExW(LPCWSTR, DWORD, PVOID);\n        BOOL RemoveFontMemResourceEx(HANDLE);\n        BOOL RemoveFontResourceExA(LPCSTR, DWORD, PVOID);\n        BOOL RemoveFontResourceExW(LPCWSTR, DWORD, PVOID);\n        DWORD GetFontUnicodeRanges(HDC, LPGLYPHSET);\n        DWORD GetGlyphIndicesA(HDC, LPCSTR, int, LPWORD, DWORD);\n        DWORD GetGlyphIndicesW(HDC, LPCWSTR, int, LPWORD, DWORD);\n        BOOL GetTextExtentPointI(HDC, LPWORD, int, LPSIZE);\n        BOOL GetTextExtentExPointI(HDC, LPWORD, int, int, LPINT, LPINT, LPSIZE);\n        BOOL GetCharWidthI(HDC, UINT, UINT, LPWORD, LPINT);\n        BOOL GetCharABCWidthsI(HDC, UINT, UINT, LPWORD, LPABC);\n    }\n} // extern (Windows)\n\nversion (Unicode) {\n    alias WCHAR BCHAR;\n    alias DOCINFOW DOCINFO;\n    alias LOGFONTW LOGFONT;\n\n    alias TEXTMETRICW TEXTMETRIC;\n    alias NPTEXTMETRICW NPTEXTMETRIC;\n    alias ICMENUMPROCW ICMENUMPROC;\n    alias FONTENUMPROCW FONTENUMPROC;\n    alias DEVMODEW DEVMODE;\n\n    alias EXTLOGFONTW EXTLOGFONT;\n    alias GCP_RESULTSW GCP_RESULTS;\n    alias OUTLINETEXTMETRICW OUTLINETEXTMETRIC;\n    alias POLYTEXTW POLYTEXT;\n    alias LOGCOLORSPACEW LOGCOLORSPACE;\n    alias NEWTEXTMETRICW NEWTEXTMETRIC;\n    alias NEWTEXTMETRICEXW NEWTEXTMETRICEX;\n    alias ENUMLOGFONTW ENUMLOGFONT;\n    alias ENUMLOGFONTEXW ENUMLOGFONTEX;\n    alias DISPLAY_DEVICEW DISPLAY_DEVICE;\n    alias AddFontResourceW AddFontResource;\n\n    alias CopyEnhMetaFileW CopyEnhMetaFile;\n    alias CopyMetaFileW CopyMetaFile;\n    alias CreateColorSpaceW CreateColorSpace;\n    alias CreateDCW CreateDC;\n    alias CreateEnhMetaFileW CreateEnhMetaFile;\n    alias CreateFontW CreateFont;\n    alias CreateFontIndirectW CreateFontIndirect;\n    alias CreateICW CreateIC;\n    alias CreateMetaFileW CreateMetaFile;\n    alias CreateScalableFontResourceW CreateScalableFontResource;\n    alias DeviceCapabilitiesW DeviceCapabilities;\n    alias EnumFontFamiliesW EnumFontFamilies;\n    alias EnumFontFamiliesExW EnumFontFamiliesEx;\n    alias EnumFontsW EnumFonts;\n    alias EnumICMProfilesW EnumICMProfiles;\n    alias ExtTextOutW ExtTextOut;\n    alias GetCharABCWidthsFloatW GetCharABCWidthsFloat;\n    alias GetCharABCWidthsW GetCharABCWidths;\n    alias GetCharacterPlacementW GetCharacterPlacement;\n    alias GetCharWidth32W GetCharWidth32;\n    alias GetCharWidthFloatW GetCharWidthFloat;\n    alias GetCharWidthW GetCharWidth;\n    alias GetEnhMetaFileW GetEnhMetaFile;\n    alias GetEnhMetaFileDescriptionW GetEnhMetaFileDescription;\n    alias GetGlyphOutlineW GetGlyphOutline;\n    alias GetICMProfileW GetICMProfile;\n    alias GetKerningPairsW GetKerningPairs;\n    alias GetLogColorSpaceW GetLogColorSpace;\n    alias GetMetaFileW GetMetaFile;\n    alias GetObjectW GetObject;\n    alias GetOutlineTextMetricsW GetOutlineTextMetrics;\n    alias GetTextExtentPointW GetTextExtentPoint;\n    alias GetTextExtentExPointW GetTextExtentExPoint;\n    alias GetTextExtentPoint32W GetTextExtentPoint32;\n    alias GetTextFaceW GetTextFace;\n    alias GetTextMetricsW GetTextMetrics;\n    alias PolyTextOutW PolyTextOut;\n    alias RemoveFontResourceW RemoveFontResource;\n\n    alias ResetDCW ResetDC;\n    alias SetICMProfileW SetICMProfile;\n    alias StartDocW StartDoc;\n    alias TextOutW TextOut;\n    alias UpdateICMRegKeyW UpdateICMRegKey;\n    alias wglUseFontBitmapsW wglUseFontBitmaps;\n    alias wglUseFontOutlinesW wglUseFontOutlines;\n    static if (_WIN32_WINNT >= 0x500) {\n        alias ENUMLOGFONTEXDVW ENUMLOGFONTEXDV;\n        alias PENUMLOGFONTEXDVW PENUMLOGFONTEXDV;\n        alias LPENUMLOGFONTEXDVW LPENUMLOGFONTEXDV;\n        alias AddFontResourceExW AddFontResourceEx;\n        alias RemoveFontResourceExW RemoveFontResourceEx;\n        alias GetGlyphIndicesW GetGlyphIndices;\n    }\n} else { /* non-unicode build */\n    alias BYTE BCHAR;\n    alias DOCINFOA DOCINFO;\n    alias LOGFONTA LOGFONT;\n    alias TEXTMETRICA TEXTMETRIC;\n    alias NPTEXTMETRICA NPTEXTMETRIC;\n    alias ICMENUMPROCA ICMENUMPROC;\n    alias FONTENUMPROCA FONTENUMPROC;\n    alias DEVMODEA DEVMODE;\n    alias EXTLOGFONTA EXTLOGFONT;\n    alias GCP_RESULTSA GCP_RESULTS;\n    alias OUTLINETEXTMETRICA OUTLINETEXTMETRIC;\n    alias POLYTEXTA POLYTEXT;\n    alias LOGCOLORSPACEA LOGCOLORSPACE;\n    alias NEWTEXTMETRICA NEWTEXTMETRIC;\n    alias NEWTEXTMETRICEXA NEWTEXTMETRICEX;\n    alias ENUMLOGFONTA ENUMLOGFONT;\n    alias ENUMLOGFONTEXA ENUMLOGFONTEX;\n    alias DISPLAY_DEVICEA DISPLAY_DEVICE;\n\n    alias AddFontResourceA AddFontResource;\n    alias CopyEnhMetaFileA CopyEnhMetaFile;\n    alias CopyMetaFileA CopyMetaFile;\n    alias CreateColorSpaceA CreateColorSpace;\n    alias CreateDCA CreateDC;\n    alias CreateEnhMetaFileA CreateEnhMetaFile;\n    alias CreateFontA CreateFont;\n    alias CreateFontIndirectA CreateFontIndirect;\n    alias CreateICA CreateIC;\n    alias CreateMetaFileA CreateMetaFile;\n    alias CreateScalableFontResourceA CreateScalableFontResource;\n    alias DeviceCapabilitiesA DeviceCapabilities;\n    alias EnumFontFamiliesA EnumFontFamilies;\n    alias EnumFontFamiliesExA EnumFontFamiliesEx;\n    alias EnumFontsA EnumFonts;\n    alias EnumICMProfilesA EnumICMProfiles;\n    alias ExtTextOutA ExtTextOut;\n    alias GetCharWidthFloatA GetCharWidthFloat;\n    alias GetCharWidthA GetCharWidth;\n    alias GetCharacterPlacementA GetCharacterPlacement;\n    alias GetCharABCWidthsA GetCharABCWidths;\n    alias GetCharABCWidthsFloatA GetCharABCWidthsFloat;\n    alias GetCharWidth32A GetCharWidth32;\n    alias GetEnhMetaFileA GetEnhMetaFile;\n    alias GetEnhMetaFileDescriptionA GetEnhMetaFileDescription;\n    alias GetGlyphOutlineA GetGlyphOutline;\n    alias GetICMProfileA GetICMProfile;\n    alias GetKerningPairsA GetKerningPairs;\n    alias GetLogColorSpaceA GetLogColorSpace;\n    alias GetMetaFileA GetMetaFile;\n    alias GetObjectA GetObject;\n    alias GetOutlineTextMetricsA GetOutlineTextMetrics;\n    alias GetTextExtentPointA GetTextExtentPoint;\n    alias GetTextExtentExPointA GetTextExtentExPoint;\n    alias GetTextExtentPoint32A GetTextExtentPoint32;\n    alias GetTextFaceA GetTextFace;\n    alias GetTextMetricsA GetTextMetrics;\n    alias PolyTextOutA PolyTextOut;\n    alias RemoveFontResourceA RemoveFontResource;\n    alias ResetDCA ResetDC;\n    alias SetICMProfileA SetICMProfile;\n    alias StartDocA StartDoc;\n    alias TextOutA TextOut;\n    alias UpdateICMRegKeyA UpdateICMRegKey;\n    alias wglUseFontBitmapsA wglUseFontBitmaps;\n    alias wglUseFontOutlinesA wglUseFontOutlines;\n    static if (_WIN32_WINNT >= 0x500) {\n        alias ENUMLOGFONTEXDVA ENUMLOGFONTEXDV;\n        alias PENUMLOGFONTEXDVA PENUMLOGFONTEXDV;\n        alias LPENUMLOGFONTEXDVA LPENUMLOGFONTEXDV;\n        alias AddFontResourceExA AddFontResourceEx;\n        alias RemoveFontResourceExA RemoveFontResourceEx;\n        alias GetGlyphIndicesA GetGlyphIndices;\n    }\n}\n\n// Common to both ASCII & UNICODE\nalias DOCINFO* LPDOCINFO;\nalias LOGFONT* PLOGFONT, NPLOGFONT, LPLOGFONT;\nalias TEXTMETRIC* PTEXTMETRIC, LPTEXTMETRIC;\nalias DEVMODE* PDEVMODE, NPDEVMODE, LPDEVMODE;\nalias EXTLOGFONT* PEXTLOGFONT, NPEXTLOGFONT, LPEXTLOGFONT;\nalias GCP_RESULTS* LPGCP_RESULTS;\nalias OUTLINETEXTMETRIC* POUTLINETEXTMETRIC, NPOUTLINETEXTMETRIC, LPOUTLINETEXTMETRIC;\nalias POLYTEXT* PPOLYTEXT, NPPOLYTEXT, LPPOLYTEXT;\nalias LOGCOLORSPACE* LPLOGCOLORSPACE;\nalias NEWTEXTMETRIC* PNEWTEXTMETRIC, NPNEWTEXTMETRIC, LPNEWTEXTMETRIC;\nalias ENUMLOGFONT* LPENUMLOGFONT;\nalias ENUMLOGFONTEX* LPENUMLOGFONTEX;\nalias DISPLAY_DEVICE* PDISPLAY_DEVICE, LPDISPLAY_DEVICE;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winhttp.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from Windows SDK Headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winhttp.d)\n */\nmodule core.sys.windows.winhttp;\nversion (Windows):\npragma(lib, \"winhttp\");\n// FIXME: Grouping of constants. Windows SDK doesn't make this entirely clear\n// FIXME: Verify WINHTTP_STATUS_CALLBACK function declaration works correctly\n\nimport core.sys.windows.w32api;\nimport core.sys.windows.winbase;\nimport core.sys.windows.windef;\nimport core.sys.windows.winsock2;  // Selective Imports BUG (: SOCKADDR_STORAGE;)\n\nalias HINTERNET = void*;\nalias LPHINTERNET = HINTERNET*;\nalias INTERNET_PORT = WORD;\nalias LPINTERNET_PORT = INTERNET_PORT*;\nalias INTERNET_SCHEME = int;\nalias LPINTERNET_SCHEME = INTERNET_SCHEME*;\n\n// Protocol 'Manifests'\nenum : DWORD {\n    INTERNET_DEFAULT_PORT       = 0,\n    INTERNET_DEFAULT_HTTP_PORT  = 80,\n    INTERNET_DEFAULT_HTTPS_PORT = 443\n}\n\n// WinHttpOpen() Flags:\nenum DWORD WINHTTP_FLAG_ASYNC = 0x10000000;\n\n// WinHttpOpenRequest() Flags:\nenum : DWORD {\n    WINHTTP_FLAG_SECURE               = 0x00800000,\n    WINHTTP_FLAG_ESCAPE_PERCENT       = 0x00000004,\n    WINHTTP_FLAG_NULL_CODEPAGE        = 0x00000008,\n    WINHTTP_FLAG_BYPASS_PROXY_CACHE   = 0x00000100,\n    WINHTTP_FLAG_REFRESH              = WINHTTP_FLAG_BYPASS_PROXY_CACHE,\n    WINHTTP_FLAG_ESCAPE_DISABLE       = 0x00000040,\n    WINHTTP_FLAG_ESCAPE_DISABLE_QUERY = 0x00000080,\n\n    SECURITY_FLAG_IGNORE_UNKNOWN_CA        = 0x00000100,\n    SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000,\n    SECURITY_FLAG_IGNORE_CERT_CN_INVALID   = 0x00001000,\n    SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE  = 0x00000200\n}\n\nstruct WINHTTP_ASYNC_RESULT {\n    DWORD_PTR dwResult;\n    DWORD dwError;\n}\nalias LPWINHTTP_ASYNC_RESULT = WINHTTP_ASYNC_RESULT*;\n\nstruct HTTP_VERSION_INFO {\n    DWORD dwMajorVersion;\n    DWORD dwMinorVersion;\n}\nalias LPHTTP_VERSION_INFO = HTTP_VERSION_INFO*;\n\n// URL Scheme\nenum : DWORD {\n    INTERNET_SCHEME_HTTP  = 1,\n    INTERNET_SCHEME_HTTPS = 2,\n    INTERNET_SCHEME_FTP   = 3,\n    INTERNET_SCHEME_SOCKS = 4\n}\n\nstruct URL_COMPONENTS {\n    DWORD   dwStructSize;\n    LPWSTR  lpszScheme;\n    DWORD   dwSchemeLength;\n    INTERNET_SCHEME nScheme;\n    LPWSTR  lpszHostName;\n    DWORD   dwHostNameLength;\n    INTERNET_PORT nPort;\n    LPWSTR  lpszUserName;\n    DWORD   dwUserNameLength;\n    LPWSTR  lpszPassword;\n    DWORD   dwPasswordLength;\n    LPWSTR  lpszUrlPath;\n    DWORD   dwUrlPathLength;\n    LPWSTR  lpszExtraInfo;\n    DWORD   dwExtraInfoLength;\n}\nalias LPURL_COMPONENTS = URL_COMPONENTS*;\nalias URL_COMPONENTSW = URL_COMPONENTS;\nalias LPURL_COMPONENTSW = URL_COMPONENTS*;\n\nstruct WINHTTP_PROXY_INFO {\n    DWORD  dwAccessType;\n    LPWSTR lpszProxy;\n    LPWSTR lpszProxyBypass;\n}\nalias LPWINHTTP_PROXY_INFO = WINHTTP_PROXY_INFO*;\nalias WINHTTP_PROXY_INFOW = WINHTTP_PROXY_INFO;\nalias LPWINHTTP_PROXY_INFOW = WINHTTP_PROXY_INFO*;\n\nstruct WINHTTP_AUTOPROXY_OPTIONS {\n    DWORD   dwFlags;\n    DWORD   dwAutoDetectFlags;\n    LPCWSTR lpszAutoConfigUrl;\n    LPVOID  lpvReserved;\n    DWORD   dwReserved;\n    BOOL    fAutoLogonIfChallenged;\n}\n\nenum : DWORD {\n    WINHTTP_AUTOPROXY_AUTO_DETECT           = 0x00000001,\n    WINHTTP_AUTOPROXY_CONFIG_URL            = 0x00000002,\n    WINHTTP_AUTOPROXY_HOST_KEEPCASE         = 0x00000004,\n    WINHTTP_AUTOPROXY_HOST_LOWERCASE        = 0x00000008,\n    WINHTTP_AUTOPROXY_RUN_INPROCESS         = 0x00010000,\n    WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY   = 0x00020000,\n    WINHTTP_AUTOPROXY_NO_DIRECTACCESS       = 0x00040000,\n    WINHTTP_AUTOPROXY_NO_CACHE_CLIENT       = 0x00080000,\n    WINHTTP_AUTOPROXY_NO_CACHE_SVC          = 0x00100000,\n\n    WINHTTP_AUTOPROXY_SORT_RESULTS          = 0x00400000\n}\n\n// dwAutoDetectFlags\nenum : DWORD {\n    WINHTTP_AUTO_DETECT_TYPE_DHCP           = 0x00000001,\n    WINHTTP_AUTO_DETECT_TYPE_DNS_A          = 0x00000002\n}\n\nstruct WINHTTP_CERTIFICATE_INFO {\n    FILETIME ftExpiry;\n    FILETIME ftStart;\n    LPWSTR lpszSubjectInfo;\n    LPWSTR lpszIssuerInfo;\n    LPWSTR lpszProtocolName;\n    LPWSTR lpszSignatureAlgName;\n    LPWSTR lpszEncryptionAlgName;\n    DWORD dwKeySize;\n}\n\n// This structure is only defined #if _WS2DEF_ defined (from <ws2def.h>) - per Windows SDK\nalign(4)\nstruct WINHTTP_CONNECTION_INFO {\nalign(4):\n    DWORD cbSize;\n    version (Win64)\n        DWORD _padding; // cheap trick without the alignment switch over this file\n    SOCKADDR_STORAGE LocalAddress;\n    SOCKADDR_STORAGE RemoteAddress;\n}\n\n// WinHttpTimeFromSystemTime\nenum DWORD WINHTTP_TIME_FORMAT_BUFSIZE  = 62;\n\n// CrackUrl, CombineUrl\nenum : DWORD {\n    ICU_NO_ENCODE           = 0x20000000,\n    ICU_DECODE              = 0x10000000,\n    ICU_NO_META             = 0x08000000,\n    ICU_ENCODE_SPACES_ONLY  = 0x04000000,\n    ICU_BROWSER_MODE        = 0x02000000,\n    ICU_ENCODE_PERCENT      = 0x00001000\n}\n// WinHttpCrackUrl, WinHttpCreateUrl\nenum : DWORD {\n    ICU_ESCAPE            = 0x80000000,\n    ICU_ESCAPE_AUTHORITY  = 0x00002000,\n    ICU_REJECT_USERPWD    = 0x00004000\n}\nenum : DWORD {\n    WINHTTP_ACCESS_TYPE_DEFAULT_PROXY             = 0,\n    WINHTTP_ACCESS_TYPE_NO_PROXY                  = 1,\n    WINHTTP_ACCESS_TYPE_NAMED_PROXY               = 3,\n    WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY           = 4\n}\n// WinHttpOpen 'prettifiers'\nenum LPCWSTR WINHTTP_NO_PROXY_NAME         = null;\nenum LPCWSTR WINHTTP_NO_PROXY_BYPASS       = null;\n\nenum LPVOID WINHTTP_NO_CLIENT_CERT_CONTEXT = null;\n\n// WinHttp{Query|Set}Option\nenum : DWORD {\n    WINHTTP_FIRST_OPTION                         = WINHTTP_OPTION_CALLBACK,\n\n    WINHTTP_OPTION_CALLBACK                      = 1,\n    WINHTTP_OPTION_RESOLVE_TIMEOUT               = 2,\n    WINHTTP_OPTION_CONNECT_TIMEOUT               = 3,\n    WINHTTP_OPTION_CONNECT_RETRIES               = 4,\n    WINHTTP_OPTION_SEND_TIMEOUT                  = 5,\n    WINHTTP_OPTION_RECEIVE_TIMEOUT               = 6,\n    WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT      = 7,\n    WINHTTP_OPTION_HANDLE_TYPE                   = 9,\n    WINHTTP_OPTION_READ_BUFFER_SIZE             = 12,\n    WINHTTP_OPTION_WRITE_BUFFER_SIZE            = 13,\n    WINHTTP_OPTION_PARENT_HANDLE                = 21,\n    WINHTTP_OPTION_EXTENDED_ERROR               = 24,\n    WINHTTP_OPTION_SECURITY_FLAGS               = 31,\n    WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT  = 32,\n    WINHTTP_OPTION_URL                          = 34,\n    WINHTTP_OPTION_SECURITY_KEY_BITNESS         = 36,\n    WINHTTP_OPTION_PROXY                        = 38,\n    WINHTTP_OPTION_PROXY_RESULT_ENTRY           = 39,\n\n    WINHTTP_OPTION_USER_AGENT                   = 41,\n    WINHTTP_OPTION_CONTEXT_VALUE                = 45,\n    WINHTTP_OPTION_CLIENT_CERT_CONTEXT          = 47,\n    WINHTTP_OPTION_REQUEST_PRIORITY             = 58,\n    WINHTTP_OPTION_HTTP_VERSION                 = 59,\n    WINHTTP_OPTION_DISABLE_FEATURE              = 63,\n\n    WINHTTP_OPTION_CODEPAGE                     = 68,\n    WINHTTP_OPTION_MAX_CONNS_PER_SERVER         = 73,\n    WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER     = 74,\n    WINHTTP_OPTION_AUTOLOGON_POLICY             = 77,\n    WINHTTP_OPTION_SERVER_CERT_CONTEXT          = 78,\n    WINHTTP_OPTION_ENABLE_FEATURE               = 79,\n    WINHTTP_OPTION_WORKER_THREAD_COUNT          = 80,\n    WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT     = 81,\n    WINHTTP_OPTION_PASSPORT_COBRANDING_URL      = 82,\n    WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH      = 83,\n    WINHTTP_OPTION_SECURE_PROTOCOLS             = 84,\n    WINHTTP_OPTION_ENABLETRACING                = 85,\n    WINHTTP_OPTION_PASSPORT_SIGN_OUT            = 86,\n    WINHTTP_OPTION_PASSPORT_RETURN_URL          = 87,\n    WINHTTP_OPTION_REDIRECT_POLICY              = 88,\n    WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS = 89,\n    WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE     = 90,\n    WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE     = 91,\n    WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE      = 92,\n    WINHTTP_OPTION_CONNECTION_INFO              = 93,\n    WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST      = 94,\n    WINHTTP_OPTION_SPN                          = 96,\n\n    WINHTTP_OPTION_GLOBAL_PROXY_CREDS           = 97,\n    WINHTTP_OPTION_GLOBAL_SERVER_CREDS          = 98,\n\n    WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT            = 99,\n    WINHTTP_OPTION_REJECT_USERPWD_IN_URL          = 100,\n    WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS  = 101,\n\n    WINHTTP_OPTION_RECEIVE_PROXY_CONNECT_RESPONSE = 103,\n    WINHTTP_OPTION_IS_PROXY_CONNECT_RESPONSE      = 104,\n\n    WINHTTP_OPTION_SERVER_SPN_USED              = 106,\n    WINHTTP_OPTION_PROXY_SPN_USED               = 107,\n\n    WINHTTP_OPTION_SERVER_CBT                   = 108,\n\n    WINHTTP_OPTION_UNSAFE_HEADER_PARSING          = 110,\n    WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS = 111,\n\n    WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET          = 114,\n    WINHTTP_OPTION_WEB_SOCKET_CLOSE_TIMEOUT       = 115,\n    WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL  = 116,\n\n    WINHTTP_OPTION_DECOMPRESSION                  = 118,\n\n    WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE = 122,\n    WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE    = 123,\n\n    //WINHTTP_LAST_OPTION => Moved outside of enum - static if () constraints within enums\n\n    WINHTTP_OPTION_USERNAME                      = 0x1000,\n    WINHTTP_OPTION_PASSWORD                      = 0x1001,\n    WINHTTP_OPTION_PROXY_USERNAME                = 0x1002,\n    WINHTTP_OPTION_PROXY_PASSWORD                = 0x1003,\n\n    WINHTTP_CONNS_PER_SERVER_UNLIMITED    = 0xFFFFFFFF,\n\n    WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM = 0,\n    WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW    = 1,\n    WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH   = 2,\n\n    WINHTTP_AUTOLOGON_SECURITY_LEVEL_DEFAULT = WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM,\n\n    WINHTTP_OPTION_REDIRECT_POLICY_NEVER                      = 0,\n    WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP     = 1,\n    WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS                     = 2,\n\n    WINHTTP_OPTION_REDIRECT_POLICY_LAST      = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,\n    WINHTTP_OPTION_REDIRECT_POLICY_DEFAULT   = WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,\n\n    WINHTTP_DISABLE_PASSPORT_AUTH    = 0x00000000,\n    WINHTTP_ENABLE_PASSPORT_AUTH     = 0x10000000,\n    WINHTTP_DISABLE_PASSPORT_KEYRING = 0x20000000,\n    WINHTTP_ENABLE_PASSPORT_KEYRING  = 0x40000000,\n\n    WINHTTP_DISABLE_COOKIES                   = 0x00000001,\n    WINHTTP_DISABLE_REDIRECTS                 = 0x00000002,\n    WINHTTP_DISABLE_AUTHENTICATION            = 0x00000004,\n    WINHTTP_DISABLE_KEEP_ALIVE                = 0x00000008,\n\n    WINHTTP_ENABLE_SSL_REVOCATION             = 0x00000001,\n    WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION   = 0x00000002,\n\n    WINHTTP_DISABLE_SPN_SERVER_PORT           = 0x00000000,\n    WINHTTP_ENABLE_SPN_SERVER_PORT            = 0x00000001,\n    WINHTTP_OPTION_SPN_MASK                   = WINHTTP_ENABLE_SPN_SERVER_PORT\n}\n\n// Windows 8.1 SDK:\nstatic if (_WIN32_WINNT >= 0x602) {\n    enum DWORD WINHTTP_LAST_OPTION            = WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE;\n} else {    // Windows 7.0A SDK:\n    enum DWORD WINHTTP_LAST_OPTION            = WINHTTP_OPTION_SERVER_CBT;\n}\n\nenum : DWORD {\n    WINHTTP_DECOMPRESSION_FLAG_GZIP    = 0x00000001,\n    WINHTTP_DECOMPRESSION_FLAG_DEFLATE = 0x00000002,\n    WINHTTP_DECOMPRESSION_FLAG_ALL = (WINHTTP_DECOMPRESSION_FLAG_GZIP | WINHTTP_DECOMPRESSION_FLAG_DEFLATE)\n}\n\nstruct WINHTTP_CREDS {\n    LPSTR lpszUserName;\n    LPSTR lpszPassword;\n    LPSTR lpszRealm;\n    DWORD dwAuthScheme;\n    LPSTR lpszHostName;\n    DWORD dwPort;\n}\nalias PWINHTTP_CREDS = WINHTTP_CREDS*;\n\nstruct WINHTTP_CREDS_EX {\n    LPSTR lpszUserName;\n    LPSTR lpszPassword;\n    LPSTR lpszRealm;\n    DWORD dwAuthScheme;\n    LPSTR lpszHostName;\n    DWORD dwPort;\n    LPSTR lpszUrl;\n}\nalias PWINHTTP_CREDS_EX = WINHTTP_CREDS_EX*;\n\nenum : DWORD {\n    WINHTTP_HANDLE_TYPE_SESSION                = 1,\n    WINHTTP_HANDLE_TYPE_CONNECT                = 2,\n    WINHTTP_HANDLE_TYPE_REQUEST                = 3,\n\n    WINHTTP_AUTH_SCHEME_BASIC      = 0x00000001,\n    WINHTTP_AUTH_SCHEME_NTLM       = 0x00000002,\n    WINHTTP_AUTH_SCHEME_PASSPORT   = 0x00000004,\n    WINHTTP_AUTH_SCHEME_DIGEST     = 0x00000008,\n    WINHTTP_AUTH_SCHEME_NEGOTIATE  = 0x00000010,\n\n    WINHTTP_AUTH_TARGET_SERVER = 0x00000000,\n    WINHTTP_AUTH_TARGET_PROXY  = 0x00000001,\n\n    SECURITY_FLAG_SECURE                    = 0x00000001,\n    SECURITY_FLAG_STRENGTH_WEAK             = 0x10000000,\n    SECURITY_FLAG_STRENGTH_MEDIUM           = 0x40000000,\n    SECURITY_FLAG_STRENGTH_STRONG           = 0x20000000,\n\n    WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED         = 0x00000001,\n    WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT            = 0x00000002,\n    WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED            = 0x00000004,\n    WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA              = 0x00000008,\n    WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID         = 0x00000010,\n    WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID       = 0x00000020,\n    WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE        = 0x00000040,\n    WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR  = 0x80000000,\n\n    WINHTTP_FLAG_SECURE_PROTOCOL_SSL2   = 0x00000008,\n    WINHTTP_FLAG_SECURE_PROTOCOL_SSL3   = 0x00000020,\n    WINHTTP_FLAG_SECURE_PROTOCOL_TLS1   = 0x00000080,\n    WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 = 0x00000200,\n    WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 = 0x00000800,\n    WINHTTP_FLAG_SECURE_PROTOCOL_ALL    = (WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 |\n                                                 WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 |\n                                                 WINHTTP_FLAG_SECURE_PROTOCOL_TLS1)\n}\n\nalias extern(Windows) int fnWINHTTP_STATUS_CALLBACK(HINTERNET hInternet, DWORD_PTR dwContext,\n                          DWORD dwInternetStatus, LPVOID lpvStatusInformation,DWORD dwStatusInformationLength);\nalias WINHTTP_STATUS_CALLBACK = fnWINHTTP_STATUS_CALLBACK*;\nalias LPWINHTTP_STATUS_CALLBACK = WINHTTP_STATUS_CALLBACK*;\n\nenum : DWORD {\n    WINHTTP_CALLBACK_STATUS_RESOLVING_NAME          = 0x00000001,\n    WINHTTP_CALLBACK_STATUS_NAME_RESOLVED           = 0x00000002,\n    WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER    = 0x00000004,\n    WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER     = 0x00000008,\n    WINHTTP_CALLBACK_STATUS_SENDING_REQUEST         = 0x00000010,\n    WINHTTP_CALLBACK_STATUS_REQUEST_SENT            = 0x00000020,\n    WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE      = 0x00000040,\n    WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED       = 0x00000080,\n    WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION      = 0x00000100,\n    WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED       = 0x00000200,\n    WINHTTP_CALLBACK_STATUS_HANDLE_CREATED          = 0x00000400,\n    WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING          = 0x00000800,\n    WINHTTP_CALLBACK_STATUS_DETECTING_PROXY         = 0x00001000,\n    WINHTTP_CALLBACK_STATUS_REDIRECT                = 0x00004000,\n    WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE   = 0x00008000,\n    WINHTTP_CALLBACK_STATUS_SECURE_FAILURE          = 0x00010000,\n    WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE       = 0x00020000,\n    WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE          = 0x00040000,\n    WINHTTP_CALLBACK_STATUS_READ_COMPLETE           = 0x00080000,\n    WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE          = 0x00100000,\n    WINHTTP_CALLBACK_STATUS_REQUEST_ERROR           = 0x00200000,\n    WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE    = 0x00400000\n}\n\nenum : DWORD {\n    WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE = 0x01000000,\n    WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE          = 0x02000000,\n    WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE       = 0x04000000\n}\n\nenum : DWORD {\n    API_RECEIVE_RESPONSE        = 1,\n    API_QUERY_DATA_AVAILABLE    = 2,\n    API_READ_DATA               = 3,\n    API_WRITE_DATA              = 4,\n    API_SEND_REQUEST            = 5\n}\n\nenum : DWORD {\n    WINHTTP_CALLBACK_FLAG_RESOLVE_NAME            = (WINHTTP_CALLBACK_STATUS_RESOLVING_NAME | WINHTTP_CALLBACK_STATUS_NAME_RESOLVED),\n    WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER       = (WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER | WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER),\n    WINHTTP_CALLBACK_FLAG_SEND_REQUEST            = (WINHTTP_CALLBACK_STATUS_SENDING_REQUEST | WINHTTP_CALLBACK_STATUS_REQUEST_SENT),\n    WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE        = (WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE | WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED),\n    WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION        = (WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION | WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED),\n    WINHTTP_CALLBACK_FLAG_HANDLES                 = (WINHTTP_CALLBACK_STATUS_HANDLE_CREATED | WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING),\n    WINHTTP_CALLBACK_FLAG_DETECTING_PROXY         = WINHTTP_CALLBACK_STATUS_DETECTING_PROXY,\n    WINHTTP_CALLBACK_FLAG_REDIRECT                = WINHTTP_CALLBACK_STATUS_REDIRECT,\n    WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE   = WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE,\n    WINHTTP_CALLBACK_FLAG_SECURE_FAILURE          = WINHTTP_CALLBACK_STATUS_SECURE_FAILURE,\n    WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE    = WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE,\n    WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE       = WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE,\n    WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE          = WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE,\n    WINHTTP_CALLBACK_FLAG_READ_COMPLETE           = WINHTTP_CALLBACK_STATUS_READ_COMPLETE,\n    WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE          = WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE,\n    WINHTTP_CALLBACK_FLAG_REQUEST_ERROR           = WINHTTP_CALLBACK_STATUS_REQUEST_ERROR\n}\n\nenum DWORD WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE  = WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE;\n\n// Windows 8+/2012+\nstatic if (_WIN32_WINNT >= 0x602)   {\n  enum DWORD WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS        =  (WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE\n                                                        | WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE\n                                                        | WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE\n                                                        | WINHTTP_CALLBACK_STATUS_READ_COMPLETE\n                                                        | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE\n                                                        | WINHTTP_CALLBACK_STATUS_REQUEST_ERROR);\n} else {\n  enum DWORD WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS        =  (WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE\n                                                        | WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE\n                                                        | WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE\n                                                        | WINHTTP_CALLBACK_STATUS_READ_COMPLETE\n                                                        | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE\n                                                        | WINHTTP_CALLBACK_STATUS_REQUEST_ERROR\n                                                        | WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE);\n}\n\nenum DWORD  WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS      =  0xffffffff;\n\nenum WINHTTP_INVALID_STATUS_CALLBACK        = (cast(WINHTTP_STATUS_CALLBACK)(-1L));\n\nenum : DWORD {\n    WINHTTP_QUERY_MIME_VERSION               = 0,\n    WINHTTP_QUERY_CONTENT_TYPE               = 1,\n    WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING  = 2,\n    WINHTTP_QUERY_CONTENT_ID                 = 3,\n    WINHTTP_QUERY_CONTENT_DESCRIPTION        = 4,\n    WINHTTP_QUERY_CONTENT_LENGTH             = 5,\n    WINHTTP_QUERY_CONTENT_LANGUAGE           = 6,\n    WINHTTP_QUERY_ALLOW                      = 7,\n    WINHTTP_QUERY_PUBLIC                     = 8,\n    WINHTTP_QUERY_DATE                       = 9,\n    WINHTTP_QUERY_EXPIRES                    = 10,\n    WINHTTP_QUERY_LAST_MODIFIED              = 11,\n    WINHTTP_QUERY_MESSAGE_ID                 = 12,\n    WINHTTP_QUERY_URI                        = 13,\n    WINHTTP_QUERY_DERIVED_FROM               = 14,\n    WINHTTP_QUERY_COST                       = 15,\n    WINHTTP_QUERY_LINK                       = 16,\n    WINHTTP_QUERY_PRAGMA                     = 17,\n    WINHTTP_QUERY_VERSION                    = 18,\n    WINHTTP_QUERY_STATUS_CODE                = 19,\n    WINHTTP_QUERY_STATUS_TEXT                = 20,\n    WINHTTP_QUERY_RAW_HEADERS                = 21,\n    WINHTTP_QUERY_RAW_HEADERS_CRLF           = 22,\n    WINHTTP_QUERY_CONNECTION                 = 23,\n    WINHTTP_QUERY_ACCEPT                     = 24,\n    WINHTTP_QUERY_ACCEPT_CHARSET             = 25,\n    WINHTTP_QUERY_ACCEPT_ENCODING            = 26,\n    WINHTTP_QUERY_ACCEPT_LANGUAGE            = 27,\n    WINHTTP_QUERY_AUTHORIZATION              = 28,\n    WINHTTP_QUERY_CONTENT_ENCODING           = 29,\n    WINHTTP_QUERY_FORWARDED                  = 30,\n    WINHTTP_QUERY_FROM                       = 31,\n    WINHTTP_QUERY_IF_MODIFIED_SINCE          = 32,\n    WINHTTP_QUERY_LOCATION                   = 33,\n    WINHTTP_QUERY_ORIG_URI                   = 34,\n    WINHTTP_QUERY_REFERER                    = 35,\n    WINHTTP_QUERY_RETRY_AFTER                = 36,\n    WINHTTP_QUERY_SERVER                     = 37,\n    WINHTTP_QUERY_TITLE                      = 38,\n    WINHTTP_QUERY_USER_AGENT                 = 39,\n    WINHTTP_QUERY_WWW_AUTHENTICATE           = 40,\n    WINHTTP_QUERY_PROXY_AUTHENTICATE         = 41,\n    WINHTTP_QUERY_ACCEPT_RANGES              = 42,\n    WINHTTP_QUERY_SET_COOKIE                 = 43,\n    WINHTTP_QUERY_COOKIE                     = 44,\n    WINHTTP_QUERY_REQUEST_METHOD             = 45,\n    WINHTTP_QUERY_REFRESH                    = 46,\n    WINHTTP_QUERY_CONTENT_DISPOSITION        = 47,\n\n    // HTTP 1.1 defined headers\n\n    WINHTTP_QUERY_AGE                        = 48,\n    WINHTTP_QUERY_CACHE_CONTROL              = 49,\n    WINHTTP_QUERY_CONTENT_BASE               = 50,\n    WINHTTP_QUERY_CONTENT_LOCATION           = 51,\n    WINHTTP_QUERY_CONTENT_MD5                = 52,\n    WINHTTP_QUERY_CONTENT_RANGE              = 53,\n    WINHTTP_QUERY_ETAG                       = 54,\n    WINHTTP_QUERY_HOST                       = 55,\n    WINHTTP_QUERY_IF_MATCH                   = 56,\n    WINHTTP_QUERY_IF_NONE_MATCH              = 57,\n    WINHTTP_QUERY_IF_RANGE                   = 58,\n    WINHTTP_QUERY_IF_UNMODIFIED_SINCE        = 59,\n    WINHTTP_QUERY_MAX_FORWARDS               = 60,\n    WINHTTP_QUERY_PROXY_AUTHORIZATION        = 61,\n    WINHTTP_QUERY_RANGE                      = 62,\n    WINHTTP_QUERY_TRANSFER_ENCODING          = 63,\n    WINHTTP_QUERY_UPGRADE                    = 64,\n    WINHTTP_QUERY_VARY                       = 65,\n    WINHTTP_QUERY_VIA                        = 66,\n    WINHTTP_QUERY_WARNING                    = 67,\n    WINHTTP_QUERY_EXPECT                     = 68,\n    WINHTTP_QUERY_PROXY_CONNECTION           = 69,\n    WINHTTP_QUERY_UNLESS_MODIFIED_SINCE      = 70,\n\n    WINHTTP_QUERY_PROXY_SUPPORT              = 75,\n    WINHTTP_QUERY_AUTHENTICATION_INFO        = 76,\n    WINHTTP_QUERY_PASSPORT_URLS              = 77,\n    WINHTTP_QUERY_PASSPORT_CONFIG            = 78,\n\n    WINHTTP_QUERY_MAX                        = 78,\n\n    WINHTTP_QUERY_CUSTOM                     = 65535,\n\n    WINHTTP_QUERY_FLAG_REQUEST_HEADERS         = 0x80000000,\n\n    WINHTTP_QUERY_FLAG_SYSTEMTIME              = 0x40000000,\n\n    WINHTTP_QUERY_FLAG_NUMBER                  = 0x20000000\n}\n\nenum : DWORD {\n    HTTP_STATUS_CONTINUE            = 100,\n    HTTP_STATUS_SWITCH_PROTOCOLS    = 101,\n\n    HTTP_STATUS_OK                  = 200,\n    HTTP_STATUS_CREATED             = 201,\n    HTTP_STATUS_ACCEPTED            = 202,\n    HTTP_STATUS_PARTIAL             = 203,\n    HTTP_STATUS_NO_CONTENT          = 204,\n    HTTP_STATUS_RESET_CONTENT       = 205,\n    HTTP_STATUS_PARTIAL_CONTENT     = 206,\n    HTTP_STATUS_WEBDAV_MULTI_STATUS = 207,\n\n    HTTP_STATUS_AMBIGUOUS           = 300,\n    HTTP_STATUS_MOVED               = 301,\n    HTTP_STATUS_REDIRECT            = 302,\n    HTTP_STATUS_REDIRECT_METHOD     = 303,\n    HTTP_STATUS_NOT_MODIFIED        = 304,\n    HTTP_STATUS_USE_PROXY           = 305,\n    HTTP_STATUS_REDIRECT_KEEP_VERB  = 307,\n\n    HTTP_STATUS_BAD_REQUEST       = 400,\n    HTTP_STATUS_DENIED            = 401,\n    HTTP_STATUS_PAYMENT_REQ       = 402,\n    HTTP_STATUS_FORBIDDEN         = 403,\n    HTTP_STATUS_NOT_FOUND         = 404,\n    HTTP_STATUS_BAD_METHOD        = 405,\n    HTTP_STATUS_NONE_ACCEPTABLE   = 406,\n    HTTP_STATUS_PROXY_AUTH_REQ    = 407,\n    HTTP_STATUS_REQUEST_TIMEOUT   = 408,\n    HTTP_STATUS_CONFLICT          = 409,\n    HTTP_STATUS_GONE              = 410,\n    HTTP_STATUS_LENGTH_REQUIRED   = 411,\n    HTTP_STATUS_PRECOND_FAILED    = 412,\n    HTTP_STATUS_REQUEST_TOO_LARGE = 413,\n    HTTP_STATUS_URI_TOO_LONG      = 414,\n    HTTP_STATUS_UNSUPPORTED_MEDIA = 415,\n    HTTP_STATUS_RETRY_WITH        = 449,\n\n    HTTP_STATUS_SERVER_ERROR      = 500,\n    HTTP_STATUS_NOT_SUPPORTED     = 501,\n    HTTP_STATUS_BAD_GATEWAY       = 502,\n    HTTP_STATUS_SERVICE_UNAVAIL   = 503,\n    HTTP_STATUS_GATEWAY_TIMEOUT   = 504,\n    HTTP_STATUS_VERSION_NOT_SUP   = 505,\n\n    HTTP_STATUS_FIRST             = HTTP_STATUS_CONTINUE,\n    HTTP_STATUS_LAST              = HTTP_STATUS_VERSION_NOT_SUP\n}\n\nenum LPCWSTR WINHTTP_NO_REFERER             = null;\nenum LPCWSTR * WINHTTP_DEFAULT_ACCEPT_TYPES = null;\n\nenum : DWORD {\n    WINHTTP_ADDREQ_INDEX_MASK     = 0x0000FFFF,\n    WINHTTP_ADDREQ_FLAGS_MASK     = 0xFFFF0000,\n\n    WINHTTP_ADDREQ_FLAG_ADD_IF_NEW = 0x10000000,\n\n    WINHTTP_ADDREQ_FLAG_ADD        = 0x20000000,\n\n    WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA       = 0x40000000,\n    WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON   = 0x01000000,\n    WINHTTP_ADDREQ_FLAG_COALESCE                  = WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA,\n\n    WINHTTP_ADDREQ_FLAG_REPLACE    = 0x80000000,\n\n    WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH = 0\n}\n\nenum LPCWSTR WINHTTP_NO_ADDITIONAL_HEADERS = null;\nenum LPVOID WINHTTP_NO_REQUEST_DATA        = null;\n\nenum LPCWSTR WINHTTP_HEADER_NAME_BY_INDEX  = null;\nenum LPVOID WINHTTP_NO_OUTPUT_BUFFER       = null;\nenum LPDWORD WINHTTP_NO_HEADER_INDEX       = null;\n\nstruct WINHTTP_CURRENT_USER_IE_PROXY_CONFIG {\n    BOOL    fAutoDetect;\n    LPWSTR  lpszAutoConfigUrl;\n    LPWSTR  lpszProxy;\n    LPWSTR  lpszProxyBypass;\n}\n\n// WinHttp API error returns\nenum : DWORD {\n    WINHTTP_ERROR_BASE                   = 12000,\n\n    ERROR_WINHTTP_OUT_OF_HANDLES         = (WINHTTP_ERROR_BASE + 1),\n    ERROR_WINHTTP_TIMEOUT                = (WINHTTP_ERROR_BASE + 2),\n    ERROR_WINHTTP_INTERNAL_ERROR         = (WINHTTP_ERROR_BASE + 4),\n    ERROR_WINHTTP_INVALID_URL            = (WINHTTP_ERROR_BASE + 5),\n    ERROR_WINHTTP_UNRECOGNIZED_SCHEME    = (WINHTTP_ERROR_BASE + 6),\n    ERROR_WINHTTP_NAME_NOT_RESOLVED      = (WINHTTP_ERROR_BASE + 7),\n    ERROR_WINHTTP_INVALID_OPTION         = (WINHTTP_ERROR_BASE + 9),\n    ERROR_WINHTTP_OPTION_NOT_SETTABLE    = (WINHTTP_ERROR_BASE + 11),\n    ERROR_WINHTTP_SHUTDOWN               = (WINHTTP_ERROR_BASE + 12),\n\n    ERROR_WINHTTP_LOGIN_FAILURE          = (WINHTTP_ERROR_BASE + 15),\n    ERROR_WINHTTP_OPERATION_CANCELLED    = (WINHTTP_ERROR_BASE + 17),\n    ERROR_WINHTTP_INCORRECT_HANDLE_TYPE  = (WINHTTP_ERROR_BASE + 18),\n    ERROR_WINHTTP_INCORRECT_HANDLE_STATE = (WINHTTP_ERROR_BASE + 19),\n    ERROR_WINHTTP_CANNOT_CONNECT         = (WINHTTP_ERROR_BASE + 29),\n    ERROR_WINHTTP_CONNECTION_ERROR       = (WINHTTP_ERROR_BASE + 30),\n    ERROR_WINHTTP_RESEND_REQUEST         = (WINHTTP_ERROR_BASE + 32),\n\n    ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED = (WINHTTP_ERROR_BASE + 44),\n\n    ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN = (WINHTTP_ERROR_BASE + 100),\n    ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND = (WINHTTP_ERROR_BASE + 101),\n    ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND  = (WINHTTP_ERROR_BASE + 102),\n    ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN  = (WINHTTP_ERROR_BASE + 103),\n\n    ERROR_WINHTTP_HEADER_NOT_FOUND           = (WINHTTP_ERROR_BASE + 150),\n    ERROR_WINHTTP_INVALID_SERVER_RESPONSE    = (WINHTTP_ERROR_BASE + 152),\n    ERROR_WINHTTP_INVALID_HEADER             = (WINHTTP_ERROR_BASE + 153),\n    ERROR_WINHTTP_INVALID_QUERY_REQUEST      = (WINHTTP_ERROR_BASE + 154),\n    ERROR_WINHTTP_HEADER_ALREADY_EXISTS      = (WINHTTP_ERROR_BASE + 155),\n    ERROR_WINHTTP_REDIRECT_FAILED            = (WINHTTP_ERROR_BASE + 156),\n\n    ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR  = (WINHTTP_ERROR_BASE + 178),\n    ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT     = (WINHTTP_ERROR_BASE + 166),\n    ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT = (WINHTTP_ERROR_BASE + 167),\n    ERROR_WINHTTP_UNHANDLED_SCRIPT_TYPE     = (WINHTTP_ERROR_BASE + 176),\n    ERROR_WINHTTP_SCRIPT_EXECUTION_ERROR    = (WINHTTP_ERROR_BASE + 177),\n\n    ERROR_WINHTTP_NOT_INITIALIZED        = (WINHTTP_ERROR_BASE + 172),\n    ERROR_WINHTTP_SECURE_FAILURE         = (WINHTTP_ERROR_BASE + 175),\n\n    ERROR_WINHTTP_SECURE_CERT_DATE_INVALID  = (WINHTTP_ERROR_BASE + 37),\n    ERROR_WINHTTP_SECURE_CERT_CN_INVALID    = (WINHTTP_ERROR_BASE + 38),\n    ERROR_WINHTTP_SECURE_INVALID_CA         = (WINHTTP_ERROR_BASE + 45),\n    ERROR_WINHTTP_SECURE_CERT_REV_FAILED    = (WINHTTP_ERROR_BASE + 57),\n    ERROR_WINHTTP_SECURE_CHANNEL_ERROR      = (WINHTTP_ERROR_BASE + 157),\n    ERROR_WINHTTP_SECURE_INVALID_CERT       = (WINHTTP_ERROR_BASE + 169),\n    ERROR_WINHTTP_SECURE_CERT_REVOKED       = (WINHTTP_ERROR_BASE + 170),\n    ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE   = (WINHTTP_ERROR_BASE + 179),\n\n    ERROR_WINHTTP_AUTODETECTION_FAILED                  = (WINHTTP_ERROR_BASE + 180),\n    ERROR_WINHTTP_HEADER_COUNT_EXCEEDED                 = (WINHTTP_ERROR_BASE + 181),\n    ERROR_WINHTTP_HEADER_SIZE_OVERFLOW                  = (WINHTTP_ERROR_BASE + 182),\n    ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW = (WINHTTP_ERROR_BASE + 183),\n    ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW               = (WINHTTP_ERROR_BASE + 184),\n    ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY            = (WINHTTP_ERROR_BASE + 185),\n    ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY     = (WINHTTP_ERROR_BASE + 186),\n\n    WINHTTP_ERROR_LAST                                  = (WINHTTP_ERROR_BASE + 186)\n}\n\nenum : DWORD {\n    WINHTTP_RESET_STATE                  = 0x00000001,\n    WINHTTP_RESET_SWPAD_CURRENT_NETWORK  = 0x00000002,\n    WINHTTP_RESET_SWPAD_ALL              = 0x00000004,\n    WINHTTP_RESET_SCRIPT_CACHE           = 0x00000008,\n    WINHTTP_RESET_ALL                    = 0x0000FFFF,\n    WINHTTP_RESET_NOTIFY_NETWORK_CHANGED = 0x00010000,\n    WINHTTP_RESET_OUT_OF_PROC            = 0x00020000\n}\n\nenum : DWORD {\n    WINHTTP_WEB_SOCKET_MAX_CLOSE_REASON_LENGTH = 123,\n    WINHTTP_WEB_SOCKET_MIN_KEEPALIVE_VALUE     = 15000\n}\n\n// Version(Windows8) || Version(Windows2012):\nstatic if (_WIN32_WINNT >= 0x602)\n{\n    enum WINHTTP_WEB_SOCKET_OPERATION : DWORD\n    {\n        WINHTTP_WEB_SOCKET_SEND_OPERATION                   = 0,\n        WINHTTP_WEB_SOCKET_RECEIVE_OPERATION                = 1,\n        WINHTTP_WEB_SOCKET_CLOSE_OPERATION                  = 2,\n        WINHTTP_WEB_SOCKET_SHUTDOWN_OPERATION               = 3\n    }\n    enum WINHTTP_WEB_SOCKET_BUFFER_TYPE : DWORD\n    {\n        WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE       = 0,\n        WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE      = 1,\n        WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE         = 2,\n        WINHTTP_WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE        = 3,\n        WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE                = 4\n    }\n    enum WINHTTP_WEB_SOCKET_CLOSE_STATUS : DWORD\n    {\n        WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS                = 1000,\n        WINHTTP_WEB_SOCKET_ENDPOINT_TERMINATED_CLOSE_STATUS    = 1001,\n        WINHTTP_WEB_SOCKET_PROTOCOL_ERROR_CLOSE_STATUS         = 1002,\n        WINHTTP_WEB_SOCKET_INVALID_DATA_TYPE_CLOSE_STATUS      = 1003,\n        WINHTTP_WEB_SOCKET_EMPTY_CLOSE_STATUS                  = 1005,\n        WINHTTP_WEB_SOCKET_ABORTED_CLOSE_STATUS                = 1006,\n        WINHTTP_WEB_SOCKET_INVALID_PAYLOAD_CLOSE_STATUS        = 1007,\n        WINHTTP_WEB_SOCKET_POLICY_VIOLATION_CLOSE_STATUS       = 1008,\n        WINHTTP_WEB_SOCKET_MESSAGE_TOO_BIG_CLOSE_STATUS        = 1009,\n        WINHTTP_WEB_SOCKET_UNSUPPORTED_EXTENSIONS_CLOSE_STATUS = 1010,\n        WINHTTP_WEB_SOCKET_SERVER_ERROR_CLOSE_STATUS           = 1011,\n        WINHTTP_WEB_SOCKET_SECURE_HANDSHAKE_ERROR_CLOSE_STATUS = 1015\n    }\n    struct WINHTTP_PROXY_RESULT_ENTRY {\n        BOOL            fProxy;\n        BOOL            fBypass;\n        INTERNET_SCHEME ProxyScheme;\n        PWSTR           pwszProxy;\n        INTERNET_PORT   ProxyPort;\n    }\n    struct WINHTTP_PROXY_RESULT {\n        DWORD cEntries;\n        WINHTTP_PROXY_RESULT_ENTRY *pEntries;\n    }\n    struct WINHTTP_WEB_SOCKET_ASYNC_RESULT {\n        WINHTTP_ASYNC_RESULT AsyncResult;\n        WINHTTP_WEB_SOCKET_OPERATION Operation;\n    }\n    struct WINHTTP_WEB_SOCKET_STATUS {\n        DWORD dwBytesTransferred;\n        WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType;\n    }\n}\n\n\nextern (Windows) {\n    BOOL WinHttpAddRequestHeaders(HINTERNET hRequest, LPCWSTR pwszHeaders, DWORD dwHeadersLength, DWORD dwModifiers);\n\n    BOOL WinHttpCheckPlatform();\n\n    BOOL WinHttpCloseHandle(HINTERNET hInternet);\n\n    HINTERNET WinHttpConnect(HINTERNET hSession, LPCWSTR pswzServerName, INTERNET_PORT nServerPort, DWORD dwReserved);\n\n    BOOL WinHttpCrackUrl(LPCWSTR pwszUrl, DWORD dwUrlLength, DWORD dwFlags, LPURL_COMPONENTS lpUrlComponents);\n\n    BOOL WinHttpCreateUrl(LPURL_COMPONENTS lpUrlComponents, DWORD dwFlags, LPWSTR pwszUrl, LPDWORD lpdwUrlLength);\n    BOOL WinHttpDetectAutoProxyConfigUrl(DWORD dwAutoDetectFlags, LPWSTR *ppwszAutoConfigUrl);\n\n    BOOL WinHttpGetDefaultProxyConfiguration(WINHTTP_PROXY_INFO *pProxyInfo);\n    BOOL WinHttpGetIEProxyConfigForCurrentUser(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG *pProxyConfig);\n    BOOL WinHttpGetProxyForUrl(HINTERNET hSession,  LPCWSTR lpcwszUrl,\n                               WINHTTP_AUTOPROXY_OPTIONS *pAutoProxyOptions, WINHTTP_PROXY_INFO *pProxyInfo);\n\n    HINTERNET WinHttpOpen(LPCWSTR pwszUserAgent, DWORD dwAccessType, LPCWSTR pwszProxyName,\n                          LPCWSTR pwszProxyBypass, DWORD dwFlags);\n    HINTERNET WinHttpOpenRequest(HINTERNET hConnect, LPCWSTR pwszVerb, LPCWSTR pwszObjectName,\n                                 LPCWSTR pwszVersion, LPCWSTR pwszReferrer,\n                                 LPCWSTR *ppwszAcceptTypes, DWORD dwFlags);\n\n    BOOL WinHttpQueryAuthSchemes(HINTERNET hRequest, LPDWORD lpdwSupportedSchemes,\n                                 LPDWORD lpdwFirstScheme, LPDWORD pdwAuthTarget);\n    BOOL WinHttpQueryDataAvailable(HINTERNET hRequest, LPDWORD lpdwNumberOfBytesAvailable);\n    BOOL WinHttpQueryHeaders(HINTERNET hRequest, DWORD dwInfoLevel, LPCWSTR pwszName,\n                             LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex);\n    BOOL WinHttpQueryOption(HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer,\n                            LPDWORD lpdwBufferLength);\n\n    BOOL WinHttpReadData(HINTERNET hRequest, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead,\n                         LPDWORD lpdwNumberOfBytesRead);\n    BOOL WinHttpReceiveResponse(HINTERNET hRequest, LPVOID lpReserved);\n\n    BOOL WinHttpSendRequest(HINTERNET hRequest, LPCWSTR pwszHeaders, DWORD dwHeadersLength,\n                            LPVOID lpOptional, DWORD dwOptionalLength, DWORD dwTotalLength, DWORD_PTR dwContext);\n\n    BOOL WinHttpSetCredentials(HINTERNET hRequest, DWORD AuthTargets, DWORD AuthScheme,\n                               LPCWSTR pwszUserName, LPCWSTR pwszPassword, LPVOID pAuthParams);\n    BOOL WinHttpSetDefaultProxyConfiguration(WINHTTP_PROXY_INFO *pProxyInfo);\n    BOOL WinHttpSetOption(HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, DWORD dwBufferLength);\n    WINHTTP_STATUS_CALLBACK WinHttpSetStatusCallback(HINTERNET hInternet,\n                                                     WINHTTP_STATUS_CALLBACK lpfnInternetCallback,\n                                                     DWORD dwNotificationFlags, DWORD_PTR dwReserved);\n    BOOL WinHttpSetTimeouts(HINTERNET hInternet, int dwResolveTimeout, int dwConnectTimeout,\n                            int dwSendTimeout, int dwReceiveTimeout);\n\n    BOOL WinHttpTimeFromSystemTime(const SYSTEMTIME *pst, LPWSTR pwszTime);\n    BOOL WinHttpTimeToSystemTime(LPCWSTR pwszTime, SYSTEMTIME *pst);\n\n    BOOL WinHttpWriteData(HINTERNET hRequest, LPCVOID lpBuffer, DWORD dwNumberOfBytesToWrite,\n                          LPDWORD lpdwNumberOfBytesWritten);\n\n  // Version(Windows8) || Version(Windows2012):\n  static if (_WIN32_WINNT >= 0x602) {\n    DWORD WinHttpCreateProxyResolver(HINTERNET hSession, HINTERNET *phResolver);\n    void WinHttpFreeProxyResult(WINHTTP_PROXY_RESULT *pProxyResult);\n    DWORD WinHttpGetProxyForUrlEx(HINTERNET hResolver, PCWSTR pcwszUrl,\n                                  WINHTTP_AUTOPROXY_OPTIONS *pAutoProxyOptions, DWORD_PTR pContext);\n    DWORD WinHttpGetProxyResult(HINTERNET hResolver, WINHTTP_PROXY_RESULT *pProxyResult);\n    DWORD WinHttpResetAutoProxy(HINTERNET hSession, DWORD dwFlags);\n    DWORD WinHttpWebSocketClose(HINTERNET hWebSocket, USHORT usStatus, PVOID pvReason, DWORD dwReasonLength);\n    HINTERNET WinHttpWebSocketCompleteUpgrade(HINTERNET hRequest, DWORD_PTR pContext);\n    DWORD WinHttpWebSocketQueryCloseStatus(HINTERNET hWebSocket, USHORT *pusStatus, PVOID pvReason,\n                                           DWORD dwReasonLength, DWORD *pdwReasonLengthConsumed);\n    DWORD WinHttpWebSocketReceive(HINTERNET hWebSocket, PVOID pvBuffer,  DWORD dwBufferLength,\n                                  DWORD *pdwBytesRead, WINHTTP_WEB_SOCKET_BUFFER_TYPE *peBufferType);\n    DWORD WinHttpWebSocketSend(HINTERNET hWebSocket, WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType,\n                               PVOID pvBuffer, DWORD dwBufferLength);\n    DWORD WinHttpWebSocketShutdown(HINTERNET hWebSocket, USHORT usStatus, PVOID pvReason, DWORD dwReasonLength);\n  }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/wininet.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_wininet.d)\n */\nmodule core.sys.windows.wininet;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"wininet\");\n\n// FIXME: check types and grouping of constants\n\nimport core.sys.windows.windows;\n\nenum {\n    INTERNET_INVALID_PORT_NUMBER =    0,\n    INTERNET_DEFAULT_FTP_PORT    =   21,\n    INTERNET_DEFAULT_GOPHER_PORT =   70,\n    INTERNET_DEFAULT_HTTP_PORT   =   80,\n    INTERNET_DEFAULT_HTTPS_PORT  =  443,\n    INTERNET_DEFAULT_SOCKS_PORT  = 1080\n}\n\nenum size_t\n    MAX_CACHE_ENTRY_INFO_SIZE       =  4096,\n    INTERNET_MAX_HOST_NAME_LENGTH   =   256,\n    INTERNET_MAX_USER_NAME_LENGTH   =   128,\n    INTERNET_MAX_PASSWORD_LENGTH    =   128,\n    INTERNET_MAX_PORT_NUMBER_LENGTH =     5,\n    INTERNET_MAX_PORT_NUMBER_VALUE  = 65535,\n    INTERNET_MAX_PATH_LENGTH        =  2048,\n    INTERNET_MAX_SCHEME_LENGTH      =    32,\n    INTERNET_MAX_URL_LENGTH         = INTERNET_MAX_SCHEME_LENGTH\n                                      + \"://\".length\n                                      + INTERNET_MAX_PATH_LENGTH;\n\nenum : DWORD {\n    INTERNET_KEEP_ALIVE_UNKNOWN  = DWORD.max,\n    INTERNET_KEEP_ALIVE_DISABLED = 0,\n    INTERNET_KEEP_ALIVE_ENABLED\n}\n\nenum {\n    INTERNET_REQFLAG_FROM_CACHE = 1,\n    INTERNET_REQFLAG_ASYNC      = 2\n}\n\nenum DWORD\n    INTERNET_FLAG_RELOAD                   = 0x80000000,\n    INTERNET_FLAG_RAW_DATA                 = 0x40000000,\n    INTERNET_FLAG_EXISTING_CONNECT         = 0x20000000,\n    INTERNET_FLAG_ASYNC                    = 0x10000000,\n    INTERNET_FLAG_PASSIVE                  = 0x08000000,\n    INTERNET_FLAG_NO_CACHE_WRITE           = 0x04000000,\n    INTERNET_FLAG_DONT_CACHE               = INTERNET_FLAG_NO_CACHE_WRITE,\n    INTERNET_FLAG_MAKE_PERSISTENT          = 0x02000000,\n    INTERNET_FLAG_OFFLINE                  = 0x01000000,\n    INTERNET_FLAG_SECURE                   = 0x00800000,\n    INTERNET_FLAG_KEEP_CONNECTION          = 0x00400000,\n    INTERNET_FLAG_NO_AUTO_REDIRECT         = 0x00200000,\n    INTERNET_FLAG_READ_PREFETCH            = 0x00100000,\n    INTERNET_FLAG_NO_COOKIES               = 0x00080000,\n    INTERNET_FLAG_NO_AUTH                  = 0x00040000,\n    INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP  = 0x00008000,\n    INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS = 0x00004000,\n    INTERNET_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000,\n    INTERNET_FLAG_IGNORE_CERT_CN_INVALID   = 0x00001000,\n    INTERNET_FLAG_RESYNCHRONIZE            = 0x00000800,\n    INTERNET_FLAG_HYPERLINK                = 0x00000400,\n    INTERNET_FLAG_NO_UI                    = 0x00000200,\n    INTERNET_FLAG_PRAGMA_NOCACHE           = 0x00000100,\n    INTERNET_FLAG_MUST_CACHE_REQUEST       = 0x00000010,\n    INTERNET_FLAG_TRANSFER_ASCII           = FTP_TRANSFER_TYPE_ASCII,\n    INTERNET_FLAG_TRANSFER_BINARY          = FTP_TRANSFER_TYPE_BINARY,\n\n    SECURITY_INTERNET_MASK                 = 0x0000F000,\n    SECURITY_SET_MASK                      = SECURITY_INTERNET_MASK,\n\n    INTERNET_FLAGS_MASK                    = 0xFFFCFE13,\n    INTERNET_OPTIONS_MASK                  = ~INTERNET_FLAGS_MASK;\n\nenum INTERNET_NO_CALLBACK = 0;\nenum INTERNET_RFC1123_FORMAT = 0;\nenum size_t INTERNET_RFC1123_BUFSIZE = 30;\n\nenum DWORD\n    ICU_ESCAPE             = 0x80000000,\n    ICU_USERNAME           = 0x40000000,\n    ICU_NO_ENCODE          = 0x20000000,\n    ICU_DECODE             = 0x10000000,\n    ICU_NO_META            = 0x08000000,\n    ICU_ENCODE_SPACES_ONLY = 0x04000000,\n    ICU_BROWSER_MODE       = 0x02000000;\n\nenum {\n    INTERNET_OPEN_TYPE_PRECONFIG = 0,\n    INTERNET_OPEN_TYPE_DIRECT    = 1,\n    INTERNET_OPEN_TYPE_PROXY     = 3,\n    PRE_CONFIG_INTERNET_ACCESS   = INTERNET_OPEN_TYPE_PRECONFIG,\n    LOCAL_INTERNET_ACCESS        = INTERNET_OPEN_TYPE_DIRECT,\n    GATEWAY_INTERNET_ACCESS      = 2,\n    CERN_PROXY_INTERNET_ACCESS   = INTERNET_OPEN_TYPE_PROXY,\n}\n\nenum ISO_GLOBAL      = 1;\nenum ISO_REGISTRY    = 2;\nenum ISO_VALID_FLAGS = ISO_GLOBAL | ISO_REGISTRY;\n\nenum {\n    INTERNET_OPTION_CALLBACK                    =  1,\n    INTERNET_OPTION_CONNECT_TIMEOUT,\n    INTERNET_OPTION_CONNECT_RETRIES,\n    INTERNET_OPTION_CONNECT_BACKOFF,\n    INTERNET_OPTION_SEND_TIMEOUT,\n    INTERNET_OPTION_CONTROL_SEND_TIMEOUT        = INTERNET_OPTION_SEND_TIMEOUT,\n    INTERNET_OPTION_RECEIVE_TIMEOUT,\n    INTERNET_OPTION_CONTROL_RECEIVE_TIMEOUT  = INTERNET_OPTION_RECEIVE_TIMEOUT,\n    INTERNET_OPTION_DATA_SEND_TIMEOUT,\n    INTERNET_OPTION_DATA_RECEIVE_TIMEOUT,\n    INTERNET_OPTION_HANDLE_TYPE,\n    INTERNET_OPTION_CONTEXT_VALUE,\n    INTERNET_OPTION_LISTEN_TIMEOUT,\n    INTERNET_OPTION_READ_BUFFER_SIZE,\n    INTERNET_OPTION_WRITE_BUFFER_SIZE,       // = 13\n    INTERNET_OPTION_ASYNC_ID                    = 15,\n    INTERNET_OPTION_ASYNC_PRIORITY,          // = 16\n    INTERNET_OPTION_PARENT_HANDLE               = 21,\n    INTERNET_OPTION_KEEP_CONNECTION,\n    INTERNET_OPTION_REQUEST_FLAGS,\n    INTERNET_OPTION_EXTENDED_ERROR,          // = 24\n    INTERNET_OPTION_OFFLINE_MODE                = 26,\n    INTERNET_OPTION_CACHE_STREAM_HANDLE,\n    INTERNET_OPTION_USERNAME,\n    INTERNET_OPTION_PASSWORD,\n    INTERNET_OPTION_ASYNC,\n    INTERNET_OPTION_SECURITY_FLAGS,\n    INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,\n    INTERNET_OPTION_DATAFILE_NAME,\n    INTERNET_OPTION_URL,\n    INTERNET_OPTION_SECURITY_CERTIFICATE,\n    INTERNET_OPTION_SECURITY_KEY_BITNESS,\n    INTERNET_OPTION_REFRESH,\n    INTERNET_OPTION_PROXY,\n    INTERNET_OPTION_SETTINGS_CHANGED,\n    INTERNET_OPTION_VERSION,\n    INTERNET_OPTION_USER_AGENT,\n    INTERNET_OPTION_END_BROWSER_SESSION,\n    INTERNET_OPTION_PROXY_USERNAME,\n    INTERNET_OPTION_PROXY_PASSWORD,          // = 44\n    INTERNET_FIRST_OPTION                       = INTERNET_OPTION_CALLBACK,\n    // why?\n    INTERNET_LAST_OPTION                        = INTERNET_OPTION_USER_AGENT\n}\n\nenum INTERNET_PRIORITY_FOREGROUND = 1000;\n\nenum {\n    INTERNET_HANDLE_TYPE_INTERNET = 1,\n    INTERNET_HANDLE_TYPE_CONNECT_FTP,\n    INTERNET_HANDLE_TYPE_CONNECT_GOPHER,\n    INTERNET_HANDLE_TYPE_CONNECT_HTTP,\n    INTERNET_HANDLE_TYPE_FTP_FIND,\n    INTERNET_HANDLE_TYPE_FTP_FIND_HTML,\n    INTERNET_HANDLE_TYPE_FTP_FILE,\n    INTERNET_HANDLE_TYPE_FTP_FILE_HTML,\n    INTERNET_HANDLE_TYPE_GOPHER_FIND,\n    INTERNET_HANDLE_TYPE_GOPHER_FIND_HTML,\n    INTERNET_HANDLE_TYPE_GOPHER_FILE,\n    INTERNET_HANDLE_TYPE_GOPHER_FILE_HTML,\n    INTERNET_HANDLE_TYPE_HTTP_REQUEST\n}\n\nenum DWORD\n    SECURITY_FLAG_SECURE                   = 0x00000001,\n    SECURITY_FLAG_SSL                      = 0x00000002,\n    SECURITY_FLAG_SSL3                     = 0x00000004,\n    SECURITY_FLAG_PCT                      = 0x00000008,\n    SECURITY_FLAG_PCT4                     = 0x00000010,\n    SECURITY_FLAG_IETFSSL4                 = 0x00000020,\n    SECURITY_FLAG_IGNORE_REVOCATION        = 0x00000080,\n    SECURITY_FLAG_IGNORE_UNKNOWN_CA        = 0x00000100,\n    SECURITY_FLAG_IGNORE_WRONG_USAGE       = 0x00000200,\n    SECURITY_FLAG_40BIT                    = 0x10000000,\n    SECURITY_FLAG_128BIT                   = 0x20000000,\n    SECURITY_FLAG_56BIT                    = 0x40000000,\n    SECURITY_FLAG_UNKNOWNBIT               = 0x80000000,\n    SECURITY_FLAG_NORMALBITNESS            = SECURITY_FLAG_40BIT,\n    SECURITY_FLAG_IGNORE_CERT_CN_INVALID   = INTERNET_FLAG_IGNORE_CERT_CN_INVALID,\n    SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = INTERNET_FLAG_IGNORE_CERT_DATE_INVALID,\n    SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTPS = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS,\n    SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTP  = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP;\n\nenum {\n    INTERNET_SERVICE_FTP = 1,\n    INTERNET_SERVICE_GOPHER,\n    INTERNET_SERVICE_HTTP\n}\n\nenum {\n    INTERNET_STATUS_RESOLVING_NAME        =  10,\n    INTERNET_STATUS_NAME_RESOLVED         =  11,\n    INTERNET_STATUS_CONNECTING_TO_SERVER  =  20,\n    INTERNET_STATUS_CONNECTED_TO_SERVER   =  21,\n    INTERNET_STATUS_SENDING_REQUEST       =  30,\n    INTERNET_STATUS_REQUEST_SENT          =  31,\n    INTERNET_STATUS_RECEIVING_RESPONSE    =  40,\n    INTERNET_STATUS_RESPONSE_RECEIVED     =  41,\n    INTERNET_STATUS_CTL_RESPONSE_RECEIVED =  42,\n    INTERNET_STATUS_PREFETCH              =  43,\n    INTERNET_STATUS_CLOSING_CONNECTION    =  50,\n    INTERNET_STATUS_CONNECTION_CLOSED     =  51,\n    INTERNET_STATUS_HANDLE_CREATED        =  60,\n    INTERNET_STATUS_HANDLE_CLOSING        =  70,\n    INTERNET_STATUS_REQUEST_COMPLETE      = 100,\n    INTERNET_STATUS_REDIRECT              = 110\n}\n\nenum {\n    FTP_TRANSFER_TYPE_UNKNOWN = 0,\n    FTP_TRANSFER_TYPE_ASCII   = 1,\n    FTP_TRANSFER_TYPE_BINARY  = 2,\n    FTP_TRANSFER_TYPE_MASK    = 3\n}\n\nenum size_t\n    MAX_GOPHER_DISPLAY_TEXT   = 128,\n    MAX_GOPHER_SELECTOR_TEXT  = 256,\n    MAX_GOPHER_HOST_NAME      = INTERNET_MAX_HOST_NAME_LENGTH,\n    MAX_GOPHER_LOCATOR_LENGTH\n      = 1 + MAX_GOPHER_DISPLAY_TEXT + 1 + MAX_GOPHER_SELECTOR_TEXT + 1\n        + MAX_GOPHER_HOST_NAME + 1 + INTERNET_MAX_PORT_NUMBER_LENGTH + 4;\n\nenum DWORD\n    GOPHER_TYPE_TEXT_FILE      = 0x00000001,\n    GOPHER_TYPE_DIRECTORY      = 0x00000002,\n    GOPHER_TYPE_CSO            = 0x00000004,\n    GOPHER_TYPE_ERROR          = 0x00000008,\n    GOPHER_TYPE_MAC_BINHEX     = 0x00000010,\n    GOPHER_TYPE_DOS_ARCHIVE    = 0x00000020,\n    GOPHER_TYPE_UNIX_UUENCODED = 0x00000040,\n    GOPHER_TYPE_INDEX_SERVER   = 0x00000080,\n    GOPHER_TYPE_TELNET         = 0x00000100,\n    GOPHER_TYPE_BINARY         = 0x00000200,\n    GOPHER_TYPE_REDUNDANT      = 0x00000400,\n    GOPHER_TYPE_TN3270         = 0x00000800,\n    GOPHER_TYPE_GIF            = 0x00001000,\n    GOPHER_TYPE_IMAGE          = 0x00002000,\n    GOPHER_TYPE_BITMAP         = 0x00004000,\n    GOPHER_TYPE_MOVIE          = 0x00008000,\n    GOPHER_TYPE_SOUND          = 0x00010000,\n    GOPHER_TYPE_HTML           = 0x00020000,\n    GOPHER_TYPE_PDF            = 0x00040000,\n    GOPHER_TYPE_CALENDAR       = 0x00080000,\n    GOPHER_TYPE_INLINE         = 0x00100000,\n    GOPHER_TYPE_UNKNOWN        = 0x20000000,\n    GOPHER_TYPE_ASK            = 0x40000000,\n    GOPHER_TYPE_GOPHER_PLUS    = 0x80000000,\n    GOPHER_TYPE_FILE_MASK      = 0x001FF271;\n\nBOOL IS_GOPHER_FILE(DWORD t) {\n    return !!(t & GOPHER_TYPE_FILE_MASK);\n}\n\nBOOL IS_GOPHER_DIRECTORY(DWORD t) {\n    return !!(t & GOPHER_TYPE_DIRECTORY);\n}\n\nBOOL IS_GOPHER_PHONE_SERVER(DWORD t) {\n    return !!(t & GOPHER_TYPE_CSO);\n}\n\nBOOL IS_GOPHER_ERROR(DWORD t) {\n    return !!(t & GOPHER_TYPE_ERROR);\n}\n\nBOOL IS_GOPHER_INDEX_SERVER(DWORD t) {\n    return !!(t & GOPHER_TYPE_INDEX_SERVER);\n}\n\nBOOL IS_GOPHER_TELNET_SESSION(DWORD t) {\n    return !!(t & GOPHER_TYPE_TELNET);\n}\n\nBOOL IS_GOPHER_BACKUP_SERVER(DWORD t) {\n    return !!(t & GOPHER_TYPE_REDUNDANT);\n}\n\nBOOL IS_GOPHER_TN3270_SESSION(DWORD t) {\n    return !!(t & GOPHER_TYPE_TN3270);\n}\n\nBOOL IS_GOPHER_ASK(DWORD t) {\n    return !!(t & GOPHER_TYPE_ASK);\n}\n\nBOOL IS_GOPHER_PLUS(DWORD t) {\n    return !!(t & GOPHER_TYPE_GOPHER_PLUS);\n}\n\nBOOL IS_GOPHER_TYPE_KNOWN(DWORD t) {\n    return !(t & GOPHER_TYPE_UNKNOWN);\n}\n\nenum size_t\n    MAX_GOPHER_CATEGORY_NAME    = 128,\n    MAX_GOPHER_ATTRIBUTE_NAME   = 128,\n    MIN_GOPHER_ATTRIBUTE_LENGTH = 256;\n\nconst TCHAR[]\n    GOPHER_INFO_CATEGORY      = \"+INFO\",\n    GOPHER_ADMIN_CATEGORY     = \"+ADMIN\",\n    GOPHER_VIEWS_CATEGORY     = \"+VIEWS\",\n    GOPHER_ABSTRACT_CATEGORY  = \"+ABSTRACT\",\n    GOPHER_VERONICA_CATEGORY  = \"+VERONICA\",\n    GOPHER_ADMIN_ATTRIBUTE    = \"Admin\",\n    GOPHER_MOD_DATE_ATTRIBUTE = \"Mod-Date\",\n    GOPHER_TTL_ATTRIBUTE      = \"TTL\",\n    GOPHER_SCORE_ATTRIBUTE    = \"Score\",\n    GOPHER_RANGE_ATTRIBUTE    = \"Score-range\",\n    GOPHER_SITE_ATTRIBUTE     = \"Site\",\n    GOPHER_ORG_ATTRIBUTE      = \"Org\",\n    GOPHER_LOCATION_ATTRIBUTE = \"Loc\",\n    GOPHER_GEOG_ATTRIBUTE     = \"Geog\",\n    GOPHER_TIMEZONE_ATTRIBUTE = \"TZ\",\n    GOPHER_PROVIDER_ATTRIBUTE = \"Provider\",\n    GOPHER_VERSION_ATTRIBUTE  = \"Version\",\n    GOPHER_ABSTRACT_ATTRIBUTE = \"Abstract\",\n    GOPHER_VIEW_ATTRIBUTE     = \"View\",\n    GOPHER_TREEWALK_ATTRIBUTE = \"treewalk\";\n\nenum : DWORD {\n    GOPHER_ATTRIBUTE_ID_BASE = 0xABCCCC00,\n    GOPHER_CATEGORY_ID_ALL,\n    GOPHER_CATEGORY_ID_INFO,\n    GOPHER_CATEGORY_ID_ADMIN,\n    GOPHER_CATEGORY_ID_VIEWS,\n    GOPHER_CATEGORY_ID_ABSTRACT,\n    GOPHER_CATEGORY_ID_VERONICA,\n    GOPHER_CATEGORY_ID_ASK,\n    GOPHER_CATEGORY_ID_UNKNOWN,\n    GOPHER_ATTRIBUTE_ID_ALL,\n    GOPHER_ATTRIBUTE_ID_ADMIN,\n    GOPHER_ATTRIBUTE_ID_MOD_DATE,\n    GOPHER_ATTRIBUTE_ID_TTL,\n    GOPHER_ATTRIBUTE_ID_SCORE,\n    GOPHER_ATTRIBUTE_ID_RANGE,\n    GOPHER_ATTRIBUTE_ID_SITE,\n    GOPHER_ATTRIBUTE_ID_ORG,\n    GOPHER_ATTRIBUTE_ID_LOCATION,\n    GOPHER_ATTRIBUTE_ID_GEOG,\n    GOPHER_ATTRIBUTE_ID_TIMEZONE,\n    GOPHER_ATTRIBUTE_ID_PROVIDER,\n    GOPHER_ATTRIBUTE_ID_VERSION,\n    GOPHER_ATTRIBUTE_ID_ABSTRACT,\n    GOPHER_ATTRIBUTE_ID_VIEW,\n    GOPHER_ATTRIBUTE_ID_TREEWALK,\n    GOPHER_ATTRIBUTE_ID_UNKNOWN\n}\n\nenum HTTP_MAJOR_VERSION   = 1;\nenum HTTP_MINOR_VERSION   = 0;\nconst TCHAR[] HTTP_VERSION = \"HTTP/1.0\";\n\nenum : DWORD {\n    HTTP_QUERY_MIME_VERSION,\n    HTTP_QUERY_CONTENT_TYPE,\n    HTTP_QUERY_CONTENT_TRANSFER_ENCODING,\n    HTTP_QUERY_CONTENT_ID,\n    HTTP_QUERY_CONTENT_DESCRIPTION,\n    HTTP_QUERY_CONTENT_LENGTH,\n    HTTP_QUERY_CONTENT_LANGUAGE,\n    HTTP_QUERY_ALLOW,\n    HTTP_QUERY_PUBLIC,\n    HTTP_QUERY_DATE,\n    HTTP_QUERY_EXPIRES,\n    HTTP_QUERY_LAST_MODIFIED,\n    HTTP_QUERY_MESSAGE_ID,\n    HTTP_QUERY_URI,\n    HTTP_QUERY_DERIVED_FROM,\n    HTTP_QUERY_COST,\n    HTTP_QUERY_LINK,\n    HTTP_QUERY_PRAGMA,\n    HTTP_QUERY_VERSION,\n    HTTP_QUERY_STATUS_CODE,\n    HTTP_QUERY_STATUS_TEXT,\n    HTTP_QUERY_RAW_HEADERS,\n    HTTP_QUERY_RAW_HEADERS_CRLF,\n    HTTP_QUERY_CONNECTION,\n    HTTP_QUERY_ACCEPT,\n    HTTP_QUERY_ACCEPT_CHARSET,\n    HTTP_QUERY_ACCEPT_ENCODING,\n    HTTP_QUERY_ACCEPT_LANGUAGE,\n    HTTP_QUERY_AUTHORIZATION,\n    HTTP_QUERY_CONTENT_ENCODING,\n    HTTP_QUERY_FORWARDED,\n    HTTP_QUERY_FROM,\n    HTTP_QUERY_IF_MODIFIED_SINCE,\n    HTTP_QUERY_LOCATION,\n    HTTP_QUERY_ORIG_URI,\n    HTTP_QUERY_REFERER,\n    HTTP_QUERY_RETRY_AFTER,\n    HTTP_QUERY_SERVER,\n    HTTP_QUERY_TITLE,\n    HTTP_QUERY_USER_AGENT,\n    HTTP_QUERY_WWW_AUTHENTICATE,\n    HTTP_QUERY_PROXY_AUTHENTICATE,\n    HTTP_QUERY_ACCEPT_RANGES,\n    HTTP_QUERY_SET_COOKIE,\n    HTTP_QUERY_COOKIE,\n    HTTP_QUERY_REQUEST_METHOD,\n    HTTP_QUERY_MAX    = 45,\n    HTTP_QUERY_CUSTOM = 65535\n}\n\nenum DWORD\n    HTTP_QUERY_FLAG_REQUEST_HEADERS = 0x80000000,\n    HTTP_QUERY_FLAG_SYSTEMTIME      = 0x40000000,\n    HTTP_QUERY_FLAG_NUMBER          = 0x20000000,\n    HTTP_QUERY_FLAG_COALESCE        = 0x10000000,\n    HTTP_QUERY_MODIFIER_FLAGS_MASK  = 0xF0000000,\n    HTTP_QUERY_HEADER_MASK          = ~HTTP_QUERY_MODIFIER_FLAGS_MASK;\n\nenum {\n    HTTP_STATUS_OK                 = 200,\n    HTTP_STATUS_CREATED,\n    HTTP_STATUS_ACCEPTED,\n    HTTP_STATUS_PARTIAL,\n    HTTP_STATUS_NO_CONTENT,     // = 204\n    HTTP_STATUS_AMBIGUOUS          = 300,\n    HTTP_STATUS_MOVED,\n    HTTP_STATUS_REDIRECT,\n    HTTP_STATUS_REDIRECT_METHOD,\n    HTTP_STATUS_NOT_MODIFIED,   // = 304\n    HTTP_STATUS_BAD_REQUEST        = 400,\n    HTTP_STATUS_DENIED,\n    HTTP_STATUS_PAYMENT_REQ,\n    HTTP_STATUS_FORBIDDEN,\n    HTTP_STATUS_NOT_FOUND,\n    HTTP_STATUS_BAD_METHOD,\n    HTTP_STATUS_NONE_ACCEPTABLE,\n    HTTP_STATUS_PROXY_AUTH_REQ,\n    HTTP_STATUS_REQUEST_TIMEOUT,\n    HTTP_STATUS_CONFLICT,\n    HTTP_STATUS_GONE,\n    HTTP_STATUS_AUTH_REFUSED,   // = 411\n    HTTP_STATUS_SERVER_ERROR       = 500,\n    HTTP_STATUS_NOT_SUPPORTED,\n    HTTP_STATUS_BAD_GATEWAY,\n    HTTP_STATUS_SERVICE_UNAVAIL,\n    HTTP_STATUS_GATEWAY_TIMEOUT // = 504\n}\n\nenum {\n    INTERNET_PREFETCH_PROGRESS,\n    INTERNET_PREFETCH_COMPLETE,\n    INTERNET_PREFETCH_ABORTED\n}\n\nenum FLAGS_ERROR_UI_FILTER_FOR_ERRORS    = 0x01;\nenum FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS = 0x02;\nenum FLAGS_ERROR_UI_FLAGS_GENERATE_DATA  = 0x04;\nenum FLAGS_ERROR_UI_FLAGS_NO_UI          = 0x08;\n\nenum DWORD\n    HTTP_ADDREQ_INDEX_MASK                   = 0x0000FFFF,\n    HTTP_ADDREQ_FLAGS_MASK                   = 0xFFFF0000,\n    HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON = 0x01000000,\n    HTTP_ADDREQ_FLAG_ADD_IF_NEW              = 0x10000000,\n    HTTP_ADDREQ_FLAG_ADD                     = 0x20000000,\n    HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA     = 0x40000000,\n    HTTP_ADDREQ_FLAG_COALESCE          = HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA,\n    HTTP_ADDREQ_FLAG_REPLACE                 = 0x80000000;\n\nenum {\n    INTERNET_ERROR_BASE                       = 12000,\n    ERROR_INTERNET_OUT_OF_HANDLES,\n    ERROR_INTERNET_TIMEOUT,\n    ERROR_INTERNET_EXTENDED_ERROR,\n    ERROR_INTERNET_INTERNAL_ERROR,\n    ERROR_INTERNET_INVALID_URL,\n    ERROR_INTERNET_UNRECOGNIZED_SCHEME,\n    ERROR_INTERNET_NAME_NOT_RESOLVED,\n    ERROR_INTERNET_PROTOCOL_NOT_FOUND,\n    ERROR_INTERNET_INVALID_OPTION,\n    ERROR_INTERNET_BAD_OPTION_LENGTH,\n    ERROR_INTERNET_OPTION_NOT_SETTABLE,\n    ERROR_INTERNET_SHUTDOWN,\n    ERROR_INTERNET_INCORRECT_USER_NAME,\n    ERROR_INTERNET_INCORRECT_PASSWORD,\n    ERROR_INTERNET_LOGIN_FAILURE,\n    ERROR_INTERNET_INVALID_OPERATION,\n    ERROR_INTERNET_OPERATION_CANCELLED,\n    ERROR_INTERNET_INCORRECT_HANDLE_TYPE,\n    ERROR_INTERNET_INCORRECT_HANDLE_STATE,\n    ERROR_INTERNET_NOT_PROXY_REQUEST,\n    ERROR_INTERNET_REGISTRY_VALUE_NOT_FOUND,\n    ERROR_INTERNET_BAD_REGISTRY_PARAMETER,\n    ERROR_INTERNET_NO_DIRECT_ACCESS,\n    ERROR_INTERNET_NO_CONTEXT,\n    ERROR_INTERNET_NO_CALLBACK,\n    ERROR_INTERNET_REQUEST_PENDING,\n    ERROR_INTERNET_INCORRECT_FORMAT,\n    ERROR_INTERNET_ITEM_NOT_FOUND,\n    ERROR_INTERNET_CANNOT_CONNECT,\n    ERROR_INTERNET_CONNECTION_ABORTED,\n    ERROR_INTERNET_CONNECTION_RESET,\n    ERROR_INTERNET_FORCE_RETRY,\n    ERROR_INTERNET_INVALID_PROXY_REQUEST,\n    ERROR_INTERNET_NEED_UI,                // = INTERNET_ERROR_BASE +  34\n    ERROR_INTERNET_HANDLE_EXISTS              = INTERNET_ERROR_BASE +  36,\n    ERROR_INTERNET_SEC_CERT_DATE_INVALID,\n    ERROR_INTERNET_SEC_CERT_CN_INVALID,\n    ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR,\n    ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR,\n    ERROR_INTERNET_MIXED_SECURITY,\n    ERROR_INTERNET_CHG_POST_IS_NON_SECURE,\n    ERROR_INTERNET_POST_IS_NON_SECURE,\n    ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED,\n    ERROR_INTERNET_INVALID_CA,\n    ERROR_INTERNET_CLIENT_AUTH_NOT_SETUP,\n    ERROR_INTERNET_ASYNC_THREAD_FAILED,\n    ERROR_INTERNET_REDIRECT_SCHEME_CHANGE, // = INTERNET_ERROR_BASE +  48\n\n    ERROR_FTP_TRANSFER_IN_PROGRESS            = INTERNET_ERROR_BASE + 110,\n    ERROR_FTP_DROPPED,                     // = INTERNET_ERROR_BASE + 111\n    ERROR_GOPHER_PROTOCOL_ERROR               = INTERNET_ERROR_BASE + 130,\n    ERROR_GOPHER_NOT_FILE,\n    ERROR_GOPHER_DATA_ERROR,\n    ERROR_GOPHER_END_OF_DATA,\n    ERROR_GOPHER_INVALID_LOCATOR,\n    ERROR_GOPHER_INCORRECT_LOCATOR_TYPE,\n    ERROR_GOPHER_NOT_GOPHER_PLUS,\n    ERROR_GOPHER_ATTRIBUTE_NOT_FOUND,\n    ERROR_GOPHER_UNKNOWN_LOCATOR,          // = INTERNET_ERROR_BASE + 138,\n    ERROR_HTTP_HEADER_NOT_FOUND               = INTERNET_ERROR_BASE + 150,\n    ERROR_HTTP_DOWNLEVEL_SERVER,\n    ERROR_HTTP_INVALID_SERVER_RESPONSE,\n    ERROR_HTTP_INVALID_HEADER,\n    ERROR_HTTP_INVALID_QUERY_REQUEST,\n    ERROR_HTTP_HEADER_ALREADY_EXISTS,\n    ERROR_HTTP_REDIRECT_FAILED,\n    ERROR_INTERNET_SECURITY_CHANNEL_ERROR,\n    ERROR_INTERNET_UNABLE_TO_CACHE_FILE,\n    ERROR_INTERNET_TCPIP_NOT_INSTALLED,\n    ERROR_HTTP_NOT_REDIRECTED,             // = INTERNET_ERROR_BASE + 160\n    // why?\n    INTERNET_ERROR_LAST                  = ERROR_INTERNET_TCPIP_NOT_INSTALLED\n}\n\n\nenum NORMAL_CACHE_ENTRY     = 0x000001;\nenum STABLE_CACHE_ENTRY     = 0x000002;\nenum STICKY_CACHE_ENTRY     = 0x000004;\nenum SPARSE_CACHE_ENTRY     = 0x010000;\nenum OCX_CACHE_ENTRY        = 0x020000;\nenum COOKIE_CACHE_ENTRY     = 0x100000;\nenum URLHISTORY_CACHE_ENTRY = 0x200000;\n\nenum CACHE_ENTRY_ATTRIBUTE_FC  = 0x0004;\nenum CACHE_ENTRY_HITRATE_FC    = 0x0010;\nenum CACHE_ENTRY_MODTIME_FC    = 0x0040;\nenum CACHE_ENTRY_EXPTIME_FC    = 0x0080;\nenum CACHE_ENTRY_ACCTIME_FC    = 0x0100;\nenum CACHE_ENTRY_SYNCTIME_FC   = 0x0200;\nenum CACHE_ENTRY_HEADERINFO_FC = 0x0400;\n\nenum {\n    WININET_API_FLAG_ASYNC       = 1,\n    WININET_API_FLAG_SYNC        = 4,\n    WININET_API_FLAG_USE_CONTEXT = 8\n}\n\n// FIXME: how should these really be grouped?\nenum {\n    IRF_ASYNC       = WININET_API_FLAG_ASYNC,\n    IRF_SYNC        = WININET_API_FLAG_SYNC,\n    IRF_USE_CONTEXT = WININET_API_FLAG_USE_CONTEXT,\n}\nenum IRF_NO_WAIT = 8;\n\nenum {\n    HSR_ASYNC = WININET_API_FLAG_ASYNC,\n    HSR_SYNC = WININET_API_FLAG_SYNC,\n    HSR_USE_CONTEXT = WININET_API_FLAG_USE_CONTEXT,\n}\n\nenum HSR_INITIATE =  8;\nenum HSR_DOWNLOAD = 16;\nenum HSR_CHUNKED  = 32;\n\nenum INTERNET_DIAL_UNATTENDED              = 0x8000;\nenum INTERNET_DIALSTATE_DISCONNECTED       = 1;\nenum INTERENT_GOONLINE_REFRESH             = 1;\nenum INTERENT_GOONLINE_MASK                = 1;\nenum INTERNET_AUTODIAL_FORCE_ONLINE        = 1;\nenum INTERNET_AUTODIAL_FORCE_UNATTENDED    = 2;\nenum INTERNET_AUTODIAL_FAILIFSECURITYCHECK = 4;\nenum INTERNET_CONNECTION_MODEM             = 0x01;\nenum INTERNET_CONNECTION_LAN               = 0x02;\nenum INTERNET_CONNECTION_PROXY             = 0x04;\nenum INTERNET_CONNECTION_MODEM_BUSY        = 0x08;\nenum INTERNET_RAS_INSTALLED                = 0x10;\nenum INTERNET_CONNECTION_OFFLINE           = 0x20;\nenum INTERNET_CONNECTION_CONFIGURED        = 0x40;\n\nenum {\n    CACHEGROUP_SEARCH_ALL   = 0,\n    CACHEGROUP_SEARCH_BYURL = 1\n}\n\nenum {\n    INTERNET_CACHE_GROUP_ADD    = 0,\n    INTERNET_CACHE_GROUP_REMOVE = 1\n}\n\nmixin DECLARE_HANDLE!(\"HINTERNET\"); // doesn't work - bug\n/*struct HINTERNET {\n    HANDLE h;\n    alias h this;\n}*/\nalias HINTERNET* LPHINTERNET;\n\nalias LONGLONG GROUPID;\nalias WORD INTERNET_PORT;\nalias WORD* LPINTERNET_PORT;\n\nenum INTERNET_SCHEME {\n    INTERNET_SCHEME_PARTIAL = -2,\n    INTERNET_SCHEME_UNKNOWN,\n    INTERNET_SCHEME_DEFAULT,\n    INTERNET_SCHEME_FTP,\n    INTERNET_SCHEME_GOPHER,\n    INTERNET_SCHEME_HTTP,\n    INTERNET_SCHEME_HTTPS,\n    INTERNET_SCHEME_FILE,\n    INTERNET_SCHEME_NEWS,\n    INTERNET_SCHEME_MAILTO,\n    INTERNET_SCHEME_SOCKS,\n    INTERNET_SCHEME_FIRST = INTERNET_SCHEME_FTP,\n    INTERNET_SCHEME_LAST = INTERNET_SCHEME_SOCKS\n}\nalias INTERNET_SCHEME* LPINTERNET_SCHEME;\n\nstruct INTERNET_ASYNC_RESULT {\n    DWORD_PTR dwResult;\n    DWORD dwError;\n}\nalias INTERNET_ASYNC_RESULT* LPINTERNET_ASYNC_RESULT;\n\nstruct INTERNET_PREFETCH_STATUS {\n    DWORD dwStatus;\n    DWORD dwSize;\n}\nalias INTERNET_PREFETCH_STATUS* LPINTERNET_PREFETCH_STATUS;\n\nstruct INTERNET_PROXY_INFO {\n    DWORD dwAccessType;\n    LPCTSTR lpszProxy;\n    LPCTSTR lpszProxyBypass;\n}\nalias INTERNET_PROXY_INFO* LPINTERNET_PROXY_INFO;\n\nstruct INTERNET_VERSION_INFO {\n    DWORD dwMajorVersion;\n    DWORD dwMinorVersion;\n}\nalias INTERNET_VERSION_INFO* LPINTERNET_VERSION_INFO;\n\nstruct URL_COMPONENTSA {\n    DWORD           dwStructSize = URL_COMPONENTSA.sizeof;\n    LPSTR           lpszScheme;\n    DWORD           dwSchemeLength;\n    INTERNET_SCHEME nScheme;\n    LPSTR           lpszHostName;\n    DWORD           dwHostNameLength;\n    INTERNET_PORT   nPort;\n    LPSTR           lpszUserName;\n    DWORD           dwUserNameLength;\n    LPSTR           lpszPassword;\n    DWORD           dwPasswordLength;\n    LPSTR           lpszUrlPath;\n    DWORD           dwUrlPathLength;\n    LPSTR           lpszExtraInfo;\n    DWORD           dwExtraInfoLength;\n}\nalias URL_COMPONENTSA* LPURL_COMPONENTSA;\n\nstruct URL_COMPONENTSW {\n    DWORD  dwStructSize = URL_COMPONENTSW.sizeof;\n    LPWSTR lpszScheme;\n    DWORD  dwSchemeLength;\n    INTERNET_SCHEME nScheme;\n    LPWSTR lpszHostName;\n    DWORD  dwHostNameLength;\n    INTERNET_PORT nPort;\n    LPWSTR lpszUserName;\n    DWORD  dwUserNameLength;\n    LPWSTR lpszPassword;\n    DWORD  dwPasswordLength;\n    LPWSTR lpszUrlPath;\n    DWORD  dwUrlPathLength;\n    LPWSTR lpszExtraInfo;\n    DWORD  dwExtraInfoLength;\n}\nalias URL_COMPONENTSW* LPURL_COMPONENTSW;\n\nstruct INTERNET_CERTIFICATE_INFO {\n    FILETIME ftExpiry;\n    FILETIME ftStart;\n    LPTSTR   lpszSubjectInfo;\n    LPTSTR   lpszIssuerInfo;\n    LPTSTR   lpszProtocolName;\n    LPTSTR   lpszSignatureAlgName;\n    LPTSTR   lpszEncryptionAlgName;\n    DWORD    dwKeySize;\n}\nalias INTERNET_CERTIFICATE_INFO* LPINTERNET_CERTIFICATE_INFO;\n\nextern (Windows) alias void function(HINTERNET, DWORD_PTR, DWORD, PVOID, DWORD)\n  INTERNET_STATUS_CALLBACK;\nalias INTERNET_STATUS_CALLBACK* LPINTERNET_STATUS_CALLBACK;\n\nenum INTERNET_INVALID_STATUS_CALLBACK\n  = cast(INTERNET_STATUS_CALLBACK) -1;\n\nstruct GOPHER_FIND_DATAA {\n    CHAR[MAX_GOPHER_DISPLAY_TEXT+1] DisplayString;\n    DWORD    GopherType;\n    DWORD    SizeLow;\n    DWORD    SizeHigh;\n    FILETIME LastModificationTime;\n    CHAR[MAX_GOPHER_LOCATOR_LENGTH+1] Locator;\n}\nalias GOPHER_FIND_DATAA* LPGOPHER_FIND_DATAA;\n\nstruct GOPHER_FIND_DATAW {\n    WCHAR[MAX_GOPHER_DISPLAY_TEXT+1] DisplayString;\n    DWORD    GopherType;\n    DWORD    SizeLow;\n    DWORD    SizeHigh;\n    FILETIME LastModificationTime;\n    WCHAR[MAX_GOPHER_LOCATOR_LENGTH+1] Locator;\n}\nalias GOPHER_FIND_DATAW* LPGOPHER_FIND_DATAW;\n\nstruct GOPHER_ADMIN_ATTRIBUTE_TYPE {\n    LPCTSTR Comment;\n    LPCTSTR EmailAddress;\n}\nalias GOPHER_ADMIN_ATTRIBUTE_TYPE* LPGOPHER_ADMIN_ATTRIBUTE_TYPE;\n\nstruct GOPHER_MOD_DATE_ATTRIBUTE_TYPE {\n    FILETIME DateAndTime;\n}\nalias GOPHER_MOD_DATE_ATTRIBUTE_TYPE* LPGOPHER_MOD_DATE_ATTRIBUTE_TYPE;\n\nstruct GOPHER_TTL_ATTRIBUTE_TYPE {\n    DWORD Ttl;\n}\nalias GOPHER_TTL_ATTRIBUTE_TYPE* LPGOPHER_TTL_ATTRIBUTE_TYPE;\n\nstruct GOPHER_SCORE_ATTRIBUTE_TYPE {\n    INT Score;\n}\nalias GOPHER_SCORE_ATTRIBUTE_TYPE* LPGOPHER_SCORE_ATTRIBUTE_TYPE;\n\nstruct GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE {\n    INT LowerBound;\n    INT UpperBound;\n}\nalias GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE* LPGOPHER_SCORE_RANGE_ATTRIBUTE_TYPE;\n\nstruct GOPHER_SITE_ATTRIBUTE_TYPE {\n    LPCTSTR Site;\n}\nalias GOPHER_SITE_ATTRIBUTE_TYPE* LPGOPHER_SITE_ATTRIBUTE_TYPE;\n\nstruct GOPHER_ORGANIZATION_ATTRIBUTE_TYPE {\n    LPCTSTR Organization;\n}\nalias GOPHER_ORGANIZATION_ATTRIBUTE_TYPE* LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPE;\n\nstruct GOPHER_LOCATION_ATTRIBUTE_TYPE {\n    LPCTSTR Location;\n}\nalias GOPHER_LOCATION_ATTRIBUTE_TYPE* LPGOPHER_LOCATION_ATTRIBUTE_TYPE;\n\nstruct GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE {\n    INT DegreesNorth;\n    INT MinutesNorth;\n    INT SecondsNorth;\n    INT DegreesEast;\n    INT MinutesEast;\n    INT SecondsEast;\n}\nalias GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE*\n  LPGOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE;\n\nstruct GOPHER_TIMEZONE_ATTRIBUTE_TYPE {\n    INT Zone;\n}\nalias GOPHER_TIMEZONE_ATTRIBUTE_TYPE* LPGOPHER_TIMEZONE_ATTRIBUTE_TYPE;\n\nstruct GOPHER_PROVIDER_ATTRIBUTE_TYPE {\n    LPCTSTR Provider;\n}\nalias GOPHER_PROVIDER_ATTRIBUTE_TYPE* LPGOPHER_PROVIDER_ATTRIBUTE_TYPE;\n\nstruct GOPHER_VERSION_ATTRIBUTE_TYPE {\n    LPCTSTR Version;\n}\nalias GOPHER_VERSION_ATTRIBUTE_TYPE* LPGOPHER_VERSION_ATTRIBUTE_TYPE;\n\nstruct GOPHER_ABSTRACT_ATTRIBUTE_TYPE {\n    LPCTSTR ShortAbstract;\n    LPCTSTR AbstractFile;\n}\nalias GOPHER_ABSTRACT_ATTRIBUTE_TYPE* LPGOPHER_ABSTRACT_ATTRIBUTE_TYPE;\n\nstruct GOPHER_VIEW_ATTRIBUTE_TYPE {\n    LPCTSTR ContentType;\n    LPCTSTR Language;\n    DWORD   Size;\n}\nalias GOPHER_VIEW_ATTRIBUTE_TYPE* LPGOPHER_VIEW_ATTRIBUTE_TYPE;\n\nstruct GOPHER_VERONICA_ATTRIBUTE_TYPE {\n    BOOL TreeWalk;\n}\nalias GOPHER_VERONICA_ATTRIBUTE_TYPE* LPGOPHER_VERONICA_ATTRIBUTE_TYPE;\n\nstruct GOPHER_ASK_ATTRIBUTE_TYPE {\n    LPCTSTR QuestionType;\n    LPCTSTR QuestionText;\n}\nalias GOPHER_ASK_ATTRIBUTE_TYPE* LPGOPHER_ASK_ATTRIBUTE_TYPE;\n\nstruct GOPHER_UNKNOWN_ATTRIBUTE_TYPE {\n    LPCTSTR Text;\n}\nalias GOPHER_UNKNOWN_ATTRIBUTE_TYPE* LPGOPHER_UNKNOWN_ATTRIBUTE_TYPE;\n\nstruct GOPHER_ATTRIBUTE_TYPE {\n    DWORD CategoryId;\n    DWORD AttributeId;\n    union {\n        GOPHER_ADMIN_ATTRIBUTE_TYPE                 Admin;\n        GOPHER_MOD_DATE_ATTRIBUTE_TYPE              ModDate;\n        GOPHER_TTL_ATTRIBUTE_TYPE                   Ttl;\n        GOPHER_SCORE_ATTRIBUTE_TYPE                 Score;\n        GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE           ScoreRange;\n        GOPHER_SITE_ATTRIBUTE_TYPE                  Site;\n        GOPHER_ORGANIZATION_ATTRIBUTE_TYPE          Organization;\n        GOPHER_LOCATION_ATTRIBUTE_TYPE              Location;\n        GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE GeographicalLocation;\n        GOPHER_TIMEZONE_ATTRIBUTE_TYPE              TimeZone;\n        GOPHER_PROVIDER_ATTRIBUTE_TYPE              Provider;\n        GOPHER_VERSION_ATTRIBUTE_TYPE               Version;\n        GOPHER_ABSTRACT_ATTRIBUTE_TYPE              Abstract;\n        GOPHER_VIEW_ATTRIBUTE_TYPE                  View;\n        GOPHER_VERONICA_ATTRIBUTE_TYPE              Veronica;\n        GOPHER_ASK_ATTRIBUTE_TYPE                   Ask;\n        GOPHER_UNKNOWN_ATTRIBUTE_TYPE               Unknown;\n    } /+AttributeType;+/\n}\nalias GOPHER_ATTRIBUTE_TYPE* LPGOPHER_ATTRIBUTE_TYPE;\n\nextern (Windows)\nalias BOOL function(LPGOPHER_ATTRIBUTE_TYPE, DWORD)\n  GOPHER_ATTRIBUTE_ENUMERATOR;\n\nstruct INTERNET_CACHE_ENTRY_INFOA {\n    DWORD    dwStructSize = INTERNET_CACHE_ENTRY_INFOA.sizeof;\n    LPSTR    lpszSourceUrlName;\n    LPSTR    lpszLocalFileName;\n    DWORD    CacheEntryType;\n    DWORD    dwUseCount;\n    DWORD    dwHitRate;\n    DWORD    dwSizeLow;\n    DWORD    dwSizeHigh;\n    FILETIME LastModifiedTime;\n    FILETIME ExpireTime;\n    FILETIME LastAccessTime;\n    FILETIME LastSyncTime;\n    PBYTE    lpHeaderInfo;\n    DWORD    dwHeaderInfoSize;\n    LPSTR    lpszFileExtension;\n    DWORD    dwReserved;\n}\nalias INTERNET_CACHE_ENTRY_INFOA* LPINTERNET_CACHE_ENTRY_INFOA;\n\nstruct INTERNET_CACHE_ENTRY_INFOW {\n    DWORD    dwStructSize = INTERNET_CACHE_ENTRY_INFOW.sizeof;\n    LPWSTR   lpszSourceUrlName;\n    LPWSTR   lpszLocalFileName;\n    DWORD    CacheEntryType;\n    DWORD    dwUseCount;\n    DWORD    dwHitRate;\n    DWORD    dwSizeLow;\n    DWORD    dwSizeHigh;\n    FILETIME LastModifiedTime;\n    FILETIME ExpireTime;\n    FILETIME LastAccessTime;\n    FILETIME LastSyncTime;\n    PBYTE    lpHeaderInfo;\n    DWORD    dwHeaderInfoSize;\n    LPWSTR   lpszFileExtension;\n    DWORD    dwReserved;\n}\nalias INTERNET_CACHE_ENTRY_INFOW* LPINTERNET_CACHE_ENTRY_INFOW;\n\nstruct INTERNET_BUFFERSA {\n    DWORD              dwStructSize = INTERNET_BUFFERSA.sizeof;\n    INTERNET_BUFFERSA* Next;\n    LPCSTR             lpcszHeader;\n    DWORD              dwHeadersLength;\n    DWORD              dwHeadersTotal;\n    LPVOID             lpvBuffer;\n    DWORD              dwBufferLength;\n    DWORD              dwBufferTotal;\n    DWORD              dwOffsetLow;\n    DWORD              dwOffsetHigh;\n}\nalias INTERNET_BUFFERSA* LPINTERNET_BUFFERSA;\n\nstruct INTERNET_BUFFERSW {\n    DWORD              dwStructSize = INTERNET_BUFFERSW.sizeof;\n    INTERNET_BUFFERSW* Next;\n    LPCWSTR            lpcszHeader;\n    DWORD              dwHeadersLength;\n    DWORD              dwHeadersTotal;\n    LPVOID             lpvBuffer;\n    DWORD              dwBufferLength;\n    DWORD              dwBufferTotal;\n    DWORD              dwOffsetLow;\n    DWORD              dwOffsetHigh;\n}\nalias INTERNET_BUFFERSW* LPINTERNET_BUFFERSW;\n\nenum size_t\n    GROUP_OWNER_STORAGE_SIZE =   4,\n    GROUPNAME_MAX_LENGTH     = 120;\n\nstruct INTERNET_CACHE_GROUP_INFOA {\n    DWORD dwGroupSize;\n    DWORD dwGroupFlags;\n    DWORD dwGroupType;\n    DWORD dwDiskUsage;\n    DWORD dwDiskQuota;\n    DWORD[GROUP_OWNER_STORAGE_SIZE] dwOwnerStorage;\n    CHAR[GROUPNAME_MAX_LENGTH]      szGroupName;\n}\nalias INTERNET_CACHE_GROUP_INFOA* LPINTERNET_CACHE_GROUP_INFOA;\n\nstruct INTERNET_CACHE_GROUP_INFOW {\n    DWORD dwGroupSize;\n    DWORD dwGroupFlags;\n    DWORD dwGroupType;\n    DWORD dwDiskUsage;\n    DWORD dwDiskQuota;\n    DWORD[GROUP_OWNER_STORAGE_SIZE] dwOwnerStorage;\n    WCHAR[GROUPNAME_MAX_LENGTH]     szGroupName;\n}\nalias INTERNET_CACHE_GROUP_INFOW* LPINTERNET_CACHE_GROUP_INFOW;\n\nextern (Windows) {\n    BOOL InternetTimeFromSystemTime(SYSTEMTIME*, DWORD, LPSTR, DWORD);\n    BOOL InternetTimeToSystemTime(LPCSTR, SYSTEMTIME*, DWORD);\n    BOOL InternetDebugGetLocalTime(SYSTEMTIME*, PDWORD);\n    BOOL InternetCrackUrlA(LPCSTR, DWORD, DWORD, LPURL_COMPONENTSA);\n    BOOL InternetCrackUrlW(LPCWSTR, DWORD, DWORD, LPURL_COMPONENTSW);\n    BOOL InternetCreateUrlA(LPURL_COMPONENTSA, DWORD, LPSTR, PDWORD);\n    BOOL InternetCreateUrlW(LPURL_COMPONENTSW, DWORD, LPWSTR, PDWORD);\n    BOOL InternetCanonicalizeUrlA(LPCSTR, LPSTR, PDWORD, DWORD);\n    BOOL InternetCanonicalizeUrlW(LPCWSTR, LPWSTR, PDWORD, DWORD);\n    BOOL InternetCheckConnectionA(LPCSTR, DWORD, DWORD);\n    BOOL InternetCheckConnectionW(LPCWSTR, DWORD, DWORD);\n    BOOL InternetCombineUrlA(LPCSTR, LPCSTR, LPSTR, PDWORD, DWORD);\n    BOOL InternetCombineUrlW(LPCWSTR, LPCWSTR, LPWSTR, PDWORD, DWORD);\n    HINTERNET InternetOpenA(LPCSTR, DWORD, LPCSTR, LPCSTR, DWORD);\n    HINTERNET InternetOpenW(LPCWSTR, DWORD, LPCWSTR, LPCWSTR, DWORD);\n    BOOL InternetCloseHandle(HINTERNET);\n    HINTERNET InternetConnectA(HINTERNET, LPCSTR, INTERNET_PORT, LPCSTR,\n      LPCSTR, DWORD, DWORD, DWORD_PTR);\n    HINTERNET InternetConnectW(HINTERNET, LPCWSTR, INTERNET_PORT, LPCWSTR,\n      LPCWSTR, DWORD, DWORD, DWORD_PTR);\n    HINTERNET InternetOpenUrlA(HINTERNET, LPCSTR, LPCSTR, DWORD, DWORD,\n      DWORD_PTR);\n    HINTERNET InternetOpenUrlW(HINTERNET, LPCWSTR, LPCWSTR, DWORD, DWORD,\n      DWORD_PTR);\n    BOOL InternetReadFile(HINTERNET, PVOID, DWORD, PDWORD);\n    DWORD InternetSetFilePointer(HINTERNET, LONG, PVOID, DWORD, DWORD_PTR);\n    BOOL InternetWriteFile(HINTERNET, LPCVOID, DWORD, PDWORD);\n    BOOL InternetQueryDataAvailable(HINTERNET, PDWORD, DWORD, DWORD_PTR);\n    BOOL InternetFindNextFileA(HINTERNET, PVOID);\n    BOOL InternetFindNextFileW(HINTERNET, PVOID);\n    BOOL InternetQueryOptionA(HINTERNET, DWORD, PVOID, PDWORD);\n    BOOL InternetQueryOptionW(HINTERNET, DWORD, PVOID, PDWORD);\n    BOOL InternetSetOptionA(HINTERNET, DWORD, PVOID, DWORD);\n    BOOL InternetSetOptionW(HINTERNET, DWORD, PVOID, DWORD);\n    BOOL InternetSetOptionExA(HINTERNET, DWORD, PVOID, DWORD, DWORD);\n    BOOL InternetSetOptionExW(HINTERNET, DWORD, PVOID, DWORD, DWORD);\n    BOOL InternetGetLastResponseInfoA(PDWORD, LPSTR, PDWORD);\n    BOOL InternetGetLastResponseInfoW(PDWORD, LPWSTR, PDWORD);\n    INTERNET_STATUS_CALLBACK InternetSetStatusCallback(HINTERNET,\n      INTERNET_STATUS_CALLBACK);\n    DWORD FtpGetFileSize(HINTERNET, LPDWORD);\n    HINTERNET FtpFindFirstFileA(HINTERNET, LPCSTR, LPWIN32_FIND_DATAA, DWORD,\n      DWORD_PTR);\n    HINTERNET FtpFindFirstFileW(HINTERNET, LPCWSTR, LPWIN32_FIND_DATAW, DWORD,\n      DWORD_PTR);\n    BOOL FtpGetFileA(HINTERNET, LPCSTR, LPCSTR, BOOL, DWORD, DWORD, DWORD_PTR);\n    BOOL FtpGetFileW(HINTERNET, LPCWSTR, LPCWSTR, BOOL, DWORD, DWORD, DWORD_PTR);\n    BOOL FtpPutFileA(HINTERNET, LPCSTR, LPCSTR, DWORD, DWORD_PTR);\n    BOOL FtpPutFileW(HINTERNET, LPCWSTR, LPCWSTR, DWORD, DWORD_PTR);\n    BOOL FtpDeleteFileA(HINTERNET, LPCSTR);\n    BOOL FtpDeleteFileW(HINTERNET, LPCWSTR);\n    BOOL FtpRenameFileA(HINTERNET, LPCSTR, LPCSTR);\n    BOOL FtpRenameFileW(HINTERNET, LPCWSTR, LPCWSTR);\n    HINTERNET FtpOpenFileA(HINTERNET, LPCSTR, DWORD, DWORD, DWORD_PTR);\n    HINTERNET FtpOpenFileW(HINTERNET, LPCWSTR, DWORD, DWORD, DWORD_PTR);\n    BOOL FtpCreateDirectoryA(HINTERNET, LPCSTR);\n    BOOL FtpCreateDirectoryW(HINTERNET, LPCWSTR);\n    BOOL FtpRemoveDirectoryA(HINTERNET, LPCSTR);\n    BOOL FtpRemoveDirectoryW(HINTERNET, LPCWSTR);\n    BOOL FtpSetCurrentDirectoryA(HINTERNET, LPCSTR);\n    BOOL FtpSetCurrentDirectoryW(HINTERNET, LPCWSTR);\n    BOOL FtpGetCurrentDirectoryA(HINTERNET, LPSTR, PDWORD);\n    BOOL FtpGetCurrentDirectoryW(HINTERNET, LPWSTR, PDWORD);\n    BOOL FtpCommandA(HINTERNET, BOOL, DWORD, LPCSTR, DWORD_PTR, HINTERNET*);\n    BOOL FtpCommandW(HINTERNET, BOOL, DWORD, LPCWSTR, DWORD_PTR, HINTERNET*);\n    BOOL GopherCreateLocatorA(LPCSTR, INTERNET_PORT, LPCSTR, LPCSTR, DWORD,\n      LPSTR, PDWORD);\n    BOOL GopherCreateLocatorW(LPCWSTR, INTERNET_PORT, LPCWSTR, LPCWSTR, DWORD,\n      LPWSTR, PDWORD);\n    BOOL GopherGetLocatorTypeA(LPCSTR, PDWORD);\n    BOOL GopherGetLocatorTypeW(LPCWSTR, PDWORD);\n    HINTERNET GopherFindFirstFileA(HINTERNET, LPCSTR, LPCSTR,\n      LPGOPHER_FIND_DATAA, DWORD, DWORD_PTR);\n    HINTERNET GopherFindFirstFileW(HINTERNET, LPCWSTR, LPCWSTR,\n      LPGOPHER_FIND_DATAW, DWORD, DWORD_PTR);\n    HINTERNET GopherOpenFileA(HINTERNET, LPCSTR, LPCSTR, DWORD, DWORD_PTR);\n    HINTERNET GopherOpenFileW(HINTERNET, LPCWSTR, LPCWSTR, DWORD, DWORD_PTR);\n    BOOL GopherGetAttributeA(HINTERNET, LPCSTR, LPCSTR, LPBYTE, DWORD,\n      PDWORD, GOPHER_ATTRIBUTE_ENUMERATOR, DWORD_PTR);\n    BOOL GopherGetAttributeW(HINTERNET, LPCWSTR, LPCWSTR, LPBYTE, DWORD,\n      PDWORD, GOPHER_ATTRIBUTE_ENUMERATOR, DWORD_PTR);\n    HINTERNET HttpOpenRequestA(HINTERNET, LPCSTR, LPCSTR, LPCSTR, LPCSTR,\n      LPCSTR*, DWORD, DWORD_PTR);\n    HINTERNET HttpOpenRequestW(HINTERNET, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR,\n      LPCWSTR*, DWORD, DWORD_PTR);\n    BOOL HttpAddRequestHeadersA(HINTERNET, LPCSTR, DWORD, DWORD);\n    BOOL HttpAddRequestHeadersW(HINTERNET, LPCWSTR, DWORD, DWORD);\n    BOOL HttpSendRequestA(HINTERNET, LPCSTR, DWORD, PVOID, DWORD);\n    BOOL HttpSendRequestW(HINTERNET, LPCWSTR, DWORD, PVOID, DWORD);\n    BOOL HttpQueryInfoA(HINTERNET, DWORD, PVOID, PDWORD, PDWORD);\n    BOOL HttpQueryInfoW(HINTERNET, DWORD, PVOID, PDWORD, PDWORD);\n    BOOL InternetSetCookieA(LPCSTR, LPCSTR, LPCSTR);\n    BOOL InternetSetCookieW(LPCWSTR, LPCWSTR, LPCWSTR);\n    BOOL InternetGetCookieA(LPCSTR, LPCSTR, LPSTR, PDWORD);\n    BOOL InternetGetCookieW(LPCWSTR, LPCWSTR, LPWSTR, PDWORD);\n    DWORD InternetAttemptConnect(DWORD);\n    DWORD InternetErrorDlg(HWND, HINTERNET, DWORD, DWORD, PVOID*);\n    DWORD InternetConfirmZoneCrossing(HWND, LPSTR, LPSTR, BOOL);\n    BOOL CreateUrlCacheEntryA(LPCSTR, DWORD, LPCSTR, LPSTR, DWORD);\n    BOOL CreateUrlCacheEntryW(LPCWSTR, DWORD, LPCWSTR, LPWSTR, DWORD);\n    BOOL CommitUrlCacheEntryA(LPCSTR, LPCSTR, FILETIME, FILETIME, DWORD,\n      LPBYTE, DWORD, LPCSTR, DWORD);\n    BOOL CommitUrlCacheEntryW(LPCWSTR, LPCWSTR, FILETIME, FILETIME, DWORD,\n      LPBYTE, DWORD, LPCWSTR, DWORD);\n    BOOL RetrieveUrlCacheEntryFileA(LPCSTR, LPINTERNET_CACHE_ENTRY_INFOA,\n      PDWORD, DWORD);\n    BOOL RetrieveUrlCacheEntryFileW(LPCWSTR, LPINTERNET_CACHE_ENTRY_INFOW,\n      PDWORD, DWORD);\n    BOOL UnlockUrlCacheEntryFile(LPCSTR, DWORD);\n    HANDLE RetrieveUrlCacheEntryStreamA(LPCSTR, LPINTERNET_CACHE_ENTRY_INFOA,\n      PDWORD, BOOL, DWORD);\n    HANDLE RetrieveUrlCacheEntryStreamW(LPCWSTR, LPINTERNET_CACHE_ENTRY_INFOW,\n      PDWORD, BOOL, DWORD);\n    BOOL ReadUrlCacheEntryStream(HANDLE, DWORD, PVOID, PDWORD, DWORD);\n    BOOL UnlockUrlCacheEntryStream(HANDLE, DWORD);\n    BOOL GetUrlCacheEntryInfoA(LPCSTR, LPINTERNET_CACHE_ENTRY_INFOA, PDWORD);\n    BOOL GetUrlCacheEntryInfoW(LPCWSTR, LPINTERNET_CACHE_ENTRY_INFOW, PDWORD);\n    BOOL SetUrlCacheEntryInfoA(LPCSTR, LPINTERNET_CACHE_ENTRY_INFOA, DWORD);\n    BOOL SetUrlCacheEntryInfoW(LPCWSTR, LPINTERNET_CACHE_ENTRY_INFOW, DWORD);\n    HANDLE FindFirstUrlCacheEntryA(LPCSTR, LPINTERNET_CACHE_ENTRY_INFOA,\n      PDWORD);\n    HANDLE FindFirstUrlCacheEntryW(LPCWSTR, LPINTERNET_CACHE_ENTRY_INFOW,\n      PDWORD);\n    BOOL FindNextUrlCacheEntryA(HANDLE, LPINTERNET_CACHE_ENTRY_INFOA, PDWORD);\n    BOOL FindNextUrlCacheEntryW(HANDLE, LPINTERNET_CACHE_ENTRY_INFOW, PDWORD);\n    BOOL FindCloseUrlCache(HANDLE);\n    BOOL DeleteUrlCacheEntry(LPCSTR);\n    DWORD AuthenticateUser(PVOID*, LPSTR, LPSTR, DWORD, LPSTR, DWORD, LPSTR,\n      LPSTR);\n    BOOL HttpSendRequestExA(HINTERNET, LPINTERNET_BUFFERSA,\n      LPINTERNET_BUFFERSA, DWORD, DWORD_PTR);\n    BOOL HttpSendRequestExW(HINTERNET, LPINTERNET_BUFFERSW,\n      LPINTERNET_BUFFERSW, DWORD, DWORD_PTR);\n    BOOL HttpEndRequestA(HINTERNET, LPINTERNET_BUFFERSA, DWORD, DWORD_PTR);\n    BOOL HttpEndRequestW(HINTERNET, LPINTERNET_BUFFERSW, DWORD, DWORD_PTR);\n    DWORD InternetDial(HWND, LPTSTR, DWORD, LPDWORD, DWORD);\n    DWORD InternetHangUp(DWORD_PTR, DWORD);\n    BOOL InternetGoOnline(LPTSTR, HWND, DWORD);\n    BOOL InternetAutodial(DWORD, DWORD);\n    BOOL InternetAutodialHangup(DWORD);\n    BOOL InternetGetConnectedState(LPDWORD, DWORD);\n    BOOL InternetSetDialState(LPCTSTR, DWORD, DWORD);\n    BOOL InternetReadFileExA(HINTERNET, LPINTERNET_BUFFERSA, DWORD, DWORD_PTR);\n    BOOL InternetReadFileExW(HINTERNET, LPINTERNET_BUFFERSW, DWORD, DWORD_PTR);\n    GROUPID CreateUrlCacheGroup(DWORD, LPVOID);\n    BOOL DeleteUrlCacheGroup(GROUPID, DWORD, LPVOID);\n    HANDLE FindFirstUrlCacheGroup(DWORD, DWORD, LPVOID, DWORD, GROUPID*,\n      LPVOID);\n    BOOL FindNextUrlCacheGroup(HANDLE, GROUPID*, LPVOID);\n    BOOL GetUrlCacheGroupAttributeA(GROUPID, DWORD, DWORD,\n      LPINTERNET_CACHE_GROUP_INFOA, LPDWORD, LPVOID);\n    BOOL GetUrlCacheGroupAttributeW(GROUPID, DWORD, DWORD,\n      LPINTERNET_CACHE_GROUP_INFOW, LPDWORD, LPVOID);\n    BOOL SetUrlCacheGroupAttributeA(GROUPID, DWORD, DWORD,\n      LPINTERNET_CACHE_GROUP_INFOA, LPVOID);\n    BOOL SetUrlCacheGroupAttributeW(GROUPID, DWORD, DWORD,\n      LPINTERNET_CACHE_GROUP_INFOW, LPVOID);\n}\n\nversion (Unicode) {\n    alias URL_COMPONENTSW URL_COMPONENTS;\n    alias LPURL_COMPONENTSW LPURL_COMPONENTS;\n    alias GOPHER_FIND_DATAW GOPHER_FIND_DATA;\n    alias LPGOPHER_FIND_DATAW LPGOPHER_FIND_DATA;\n    alias INTERNET_CACHE_ENTRY_INFOW INTERNET_CACHE_ENTRY_INFO;\n    alias LPINTERNET_CACHE_ENTRY_INFOW LPINTERNET_CACHE_ENTRY_INFO;\n    alias INTERNET_BUFFERSW INTERNET_BUFFERS;\n    alias INTERNET_CACHE_GROUP_INFOW INTERNET_CACHE_GROUP_INFO;\n    alias LPINTERNET_CACHE_GROUP_INFOW LPINTERNET_CACHE_GROUP_INFO;\n    alias InternetCrackUrlW InternetCrackUrl;\n    alias InternetCreateUrlW InternetCreateUrl;\n    alias InternetCanonicalizeUrlW InternetCanonicalizeUrl;\n    alias InternetCheckConnectionW InternetCheckConnection;\n    alias InternetCombineUrlW InternetCombineUrl;\n    alias InternetOpenW InternetOpen;\n    alias InternetConnectW InternetConnect;\n    alias InternetOpenUrlW InternetOpenUrl;\n    alias InternetFindNextFileW InternetFindNextFile;\n    alias InternetQueryOptionW InternetQueryOption;\n    alias InternetSetOptionW InternetSetOption;\n    alias InternetSetOptionExW InternetSetOptionEx;\n    alias InternetGetLastResponseInfoW InternetGetLastResponseInfo;\n    alias InternetReadFileExW InternetReadFileEx;\n    alias FtpFindFirstFileW FtpFindFirstFile;\n    alias FtpGetFileW FtpGetFile;\n    alias FtpPutFileW FtpPutFile;\n    alias FtpDeleteFileW FtpDeleteFile;\n    alias FtpRenameFileW FtpRenameFile;\n    alias FtpOpenFileW FtpOpenFile;\n    alias FtpCreateDirectoryW FtpCreateDirectory;\n    alias FtpRemoveDirectoryW FtpRemoveDirectory;\n    alias FtpSetCurrentDirectoryW FtpSetCurrentDirectory;\n    alias FtpGetCurrentDirectoryW FtpGetCurrentDirectory;\n    alias FtpCommandW FtpCommand;\n    alias GopherGetLocatorTypeW GopherGetLocatorType;\n    alias GopherCreateLocatorW GopherCreateLocator;\n    alias GopherFindFirstFileW GopherFindFirstFile;\n    alias GopherOpenFileW GopherOpenFile;\n    alias GopherGetAttributeW GopherGetAttribute;\n    alias HttpSendRequestW HttpSendRequest;\n    alias HttpOpenRequestW HttpOpenRequest;\n    alias HttpAddRequestHeadersW HttpAddRequestHeaders;\n    alias HttpQueryInfoW HttpQueryInfo;\n    alias InternetSetCookieW InternetSetCookie;\n    alias InternetGetCookieW InternetGetCookie;\n    alias CreateUrlCacheEntryW CreateUrlCacheEntry;\n    alias RetrieveUrlCacheEntryStreamW RetrieveUrlCacheEntryStream;\n    alias FindNextUrlCacheEntryW FindNextUrlCacheEntry;\n    alias CommitUrlCacheEntryW CommitUrlCacheEntry;\n    alias GetUrlCacheEntryInfoW GetUrlCacheEntryInfo;\n    alias SetUrlCacheEntryInfoW SetUrlCacheEntryInfo;\n    alias FindFirstUrlCacheEntryW FindFirstUrlCacheEntry;\n    alias RetrieveUrlCacheEntryFileW RetrieveUrlCacheEntryFile;\n    alias HttpSendRequestExW HttpSendRequestEx;\n    alias HttpEndRequestW HttpEndRequest;\n    alias GetUrlCacheGroupAttributeW GetUrlCacheGroupAttribute;\n    alias SetUrlCacheGroupAttributeW SetUrlCacheGroupAttribute;\n} else {\n    alias URL_COMPONENTSA URL_COMPONENTS;\n    alias LPURL_COMPONENTSA LPURL_COMPONENTS;\n    alias GOPHER_FIND_DATAA GOPHER_FIND_DATA;\n    alias LPGOPHER_FIND_DATAA LPGOPHER_FIND_DATA;\n    alias INTERNET_CACHE_ENTRY_INFOA INTERNET_CACHE_ENTRY_INFO;\n    alias LPINTERNET_CACHE_ENTRY_INFOA LPINTERNET_CACHE_ENTRY_INFO;\n    alias INTERNET_BUFFERSA INTERNET_BUFFERS;\n    alias INTERNET_CACHE_GROUP_INFOA INTERNET_CACHE_GROUP_INFO;\n    alias LPINTERNET_CACHE_GROUP_INFOA LPINTERNET_CACHE_GROUP_INFO;\n    alias GopherGetAttributeA GopherGetAttribute;\n    alias InternetCrackUrlA InternetCrackUrl;\n    alias InternetCreateUrlA InternetCreateUrl;\n    alias InternetCanonicalizeUrlA InternetCanonicalizeUrl;\n    alias InternetCheckConnectionA InternetCheckConnection;\n    alias InternetCombineUrlA InternetCombineUrl;\n    alias InternetOpenA InternetOpen;\n    alias InternetConnectA InternetConnect;\n    alias InternetOpenUrlA InternetOpenUrl;\n    alias InternetFindNextFileA InternetFindNextFile;\n    alias InternetQueryOptionA InternetQueryOption;\n    alias InternetSetOptionA InternetSetOption;\n    alias InternetSetOptionExA InternetSetOptionEx;\n    alias InternetGetLastResponseInfoA InternetGetLastResponseInfo;\n    alias InternetReadFileExA InternetReadFileEx;\n    alias FtpFindFirstFileA FtpFindFirstFile;\n    alias FtpGetFileA FtpGetFile;\n    alias FtpPutFileA FtpPutFile;\n    alias FtpDeleteFileA FtpDeleteFile;\n    alias FtpRenameFileA FtpRenameFile;\n    alias FtpOpenFileA FtpOpenFile;\n    alias FtpCreateDirectoryA FtpCreateDirectory;\n    alias FtpRemoveDirectoryA FtpRemoveDirectory;\n    alias FtpSetCurrentDirectoryA FtpSetCurrentDirectory;\n    alias FtpGetCurrentDirectoryA FtpGetCurrentDirectory;\n    alias FtpCommandA FtpCommand;\n    alias GopherGetLocatorTypeA GopherGetLocatorType;\n    alias GopherCreateLocatorA GopherCreateLocator;\n    alias GopherFindFirstFileA GopherFindFirstFile;\n    alias GopherOpenFileA GopherOpenFile;\n    alias HttpSendRequestA HttpSendRequest;\n    alias HttpOpenRequestA HttpOpenRequest;\n    alias HttpAddRequestHeadersA HttpAddRequestHeaders;\n    alias HttpQueryInfoA HttpQueryInfo;\n    alias InternetSetCookieA InternetSetCookie;\n    alias InternetGetCookieA InternetGetCookie;\n    alias CreateUrlCacheEntryA CreateUrlCacheEntry;\n    alias RetrieveUrlCacheEntryStreamA RetrieveUrlCacheEntryStream;\n    alias FindNextUrlCacheEntryA FindNextUrlCacheEntry;\n    alias CommitUrlCacheEntryA CommitUrlCacheEntry;\n    alias GetUrlCacheEntryInfoA GetUrlCacheEntryInfo;\n    alias SetUrlCacheEntryInfoA SetUrlCacheEntryInfo;\n    alias FindFirstUrlCacheEntryA FindFirstUrlCacheEntry;\n    alias RetrieveUrlCacheEntryFileA RetrieveUrlCacheEntryFile;\n    alias HttpSendRequestExA HttpSendRequestEx;\n    alias HttpEndRequestA HttpEndRequest;\n    alias GetUrlCacheGroupAttributeA GetUrlCacheGroupAttribute;\n    alias SetUrlCacheGroupAttributeA SetUrlCacheGroupAttribute;\n}\n\nalias INTERNET_BUFFERS* LPINTERNET_BUFFERS;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winioctl.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winioctl.d)\n */\nmodule core.sys.windows.winioctl;\nversion (Windows):\n\n// FIXME: check types of some constants\n\nprivate import core.sys.windows.basetyps, core.sys.windows.windef;\n\nenum size_t\n    HIST_NO_OF_BUCKETS = 24,\n    HISTOGRAM_BUCKET_SIZE = HISTOGRAM_BUCKET.sizeof,\n    DISK_HISTOGRAM_SIZE = DISK_HISTOGRAM.sizeof;\n\nalias DWORD DEVICE_TYPE;\n\nenum : DEVICE_TYPE {\n    FILE_DEVICE_BEEP               = 1,\n    FILE_DEVICE_CD_ROM,\n    FILE_DEVICE_CD_ROM_FILE_SYSTEM,\n    FILE_DEVICE_CONTROLLER,\n    FILE_DEVICE_DATALINK,\n    FILE_DEVICE_DFS,\n    FILE_DEVICE_DISK,\n    FILE_DEVICE_DISK_FILE_SYSTEM,\n    FILE_DEVICE_FILE_SYSTEM,\n    FILE_DEVICE_INPORT_PORT,\n    FILE_DEVICE_KEYBOARD,\n    FILE_DEVICE_MAILSLOT,\n    FILE_DEVICE_MIDI_IN,\n    FILE_DEVICE_MIDI_OUT,\n    FILE_DEVICE_MOUSE,\n    FILE_DEVICE_MULTI_UNC_PROVIDER,\n    FILE_DEVICE_NAMED_PIPE,\n    FILE_DEVICE_NETWORK,\n    FILE_DEVICE_NETWORK_BROWSER,\n    FILE_DEVICE_NETWORK_FILE_SYSTEM,\n    FILE_DEVICE_NULL,\n    FILE_DEVICE_PARALLEL_PORT,\n    FILE_DEVICE_PHYSICAL_NETCARD,\n    FILE_DEVICE_PRINTER,\n    FILE_DEVICE_SCANNER,\n    FILE_DEVICE_SERIAL_MOUSE_PORT,\n    FILE_DEVICE_SERIAL_PORT,\n    FILE_DEVICE_SCREEN,\n    FILE_DEVICE_SOUND,\n    FILE_DEVICE_STREAMS,\n    FILE_DEVICE_TAPE,\n    FILE_DEVICE_TAPE_FILE_SYSTEM,\n    FILE_DEVICE_TRANSPORT,\n    FILE_DEVICE_UNKNOWN,\n    FILE_DEVICE_VIDEO,\n    FILE_DEVICE_VIRTUAL_DISK,\n    FILE_DEVICE_WAVE_IN,\n    FILE_DEVICE_WAVE_OUT,\n    FILE_DEVICE_8042_PORT,\n    FILE_DEVICE_NETWORK_REDIRECTOR,\n    FILE_DEVICE_BATTERY,\n    FILE_DEVICE_BUS_EXTENDER,\n    FILE_DEVICE_MODEM,\n    FILE_DEVICE_VDM,\n    FILE_DEVICE_MASS_STORAGE,\n    FILE_DEVICE_SMB,\n    FILE_DEVICE_KS,\n    FILE_DEVICE_CHANGER,\n    FILE_DEVICE_SMARTCARD,\n    FILE_DEVICE_ACPI,\n    FILE_DEVICE_DVD,\n    FILE_DEVICE_FULLSCREEN_VIDEO,\n    FILE_DEVICE_DFS_FILE_SYSTEM,\n    FILE_DEVICE_DFS_VOLUME,\n    FILE_DEVICE_SERENUM,\n    FILE_DEVICE_TERMSRV,\n    FILE_DEVICE_KSEC            // = 57\n}\n\nenum {\n    METHOD_BUFFERED,\n    METHOD_IN_DIRECT,\n    METHOD_OUT_DIRECT,\n    METHOD_NEITHER\n}\n\nenum {\n    FILE_ANY_ACCESS,\n    FILE_SPECIAL_ACCESS = 0,\n    FILE_READ_ACCESS,\n    FILE_WRITE_ACCESS\n}\n\n/*  Bit pattern:\n *  tttttttt tttttttt aaffffff ffffffmm\n */\n/+\n#define CTL_CODE(t, f, m, a) (((t)<<16)|((a)<<14)|((f)<<2)|(m))\n+/\n\ntemplate CTL_CODE_T(DEVICE_TYPE t, uint f, uint m, uint a) {\nenum DWORD CTL_CODE_T = (t << 16) | (a << 14) | (f << 2) | m;\n}\n\nDEVICE_TYPE DEVICE_TYPE_FROM_CTL_CODE(DWORD c) {\n    return (c & 0xFFFF0000) >> 16;\n}\n\nenum DEVICE_TYPE\n    IOCTL_STORAGE_BASE = FILE_DEVICE_MASS_STORAGE,\n    IOCTL_DISK_BASE    = FILE_DEVICE_DISK,\n    IOCTL_VOLUME_BASE  = 'V';\n\nenum : DWORD {\n    IOCTL_STORAGE_CHECK_VERIFY           = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_STORAGE_CHECK_VERIFY2          = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_STORAGE_MEDIA_REMOVAL          = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_STORAGE_EJECT_MEDIA            = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_STORAGE_LOAD_MEDIA             = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_STORAGE_LOAD_MEDIA2            = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_STORAGE_RESERVE                = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_STORAGE_RELEASE                = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_STORAGE_FIND_NEW_DEVICES       = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_STORAGE_EJECTION_CONTROL       = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0250, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_STORAGE_MCN_CONTROL            = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0251, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_STORAGE_GET_MEDIA_TYPES        = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0300, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_STORAGE_GET_MEDIA_TYPES_EX     = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0301, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_STORAGE_RESET_BUS              = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_STORAGE_RESET_DEVICE           = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_STORAGE_GET_DEVICE_NUMBER      = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_STORAGE_PREDICT_FAILURE        = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0440, METHOD_BUFFERED, FILE_ANY_ACCESS),\n\n    IOCTL_DISK_GET_DRIVE_GEOMETRY        = CTL_CODE_T!(IOCTL_DISK_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_GET_PARTITION_INFO        = CTL_CODE_T!(IOCTL_DISK_BASE, 1, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_SET_PARTITION_INFO        = CTL_CODE_T!(IOCTL_DISK_BASE, 2, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS),\n    IOCTL_DISK_GET_DRIVE_LAYOUT          = CTL_CODE_T!(IOCTL_DISK_BASE, 3, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_SET_DRIVE_LAYOUT          = CTL_CODE_T!(IOCTL_DISK_BASE, 4, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS),\n    IOCTL_DISK_VERIFY                    = CTL_CODE_T!(IOCTL_DISK_BASE, 5, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_FORMAT_TRACKS             = CTL_CODE_T!(IOCTL_DISK_BASE, 6, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS),\n    IOCTL_DISK_REASSIGN_BLOCKS           = CTL_CODE_T!(IOCTL_DISK_BASE, 7, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS),\n    IOCTL_DISK_PERFORMANCE               = CTL_CODE_T!(IOCTL_DISK_BASE, 8, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_IS_WRITABLE               = CTL_CODE_T!(IOCTL_DISK_BASE, 9, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_LOGGING                   = CTL_CODE_T!(IOCTL_DISK_BASE, 10, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_FORMAT_TRACKS_EX          = CTL_CODE_T!(IOCTL_DISK_BASE, 11, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS),\n    IOCTL_DISK_HISTOGRAM_STRUCTURE       = CTL_CODE_T!(IOCTL_DISK_BASE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_HISTOGRAM_DATA            = CTL_CODE_T!(IOCTL_DISK_BASE, 13, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_HISTOGRAM_RESET           = CTL_CODE_T!(IOCTL_DISK_BASE, 14, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_REQUEST_STRUCTURE         = CTL_CODE_T!(IOCTL_DISK_BASE, 15, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_REQUEST_DATA              = CTL_CODE_T!(IOCTL_DISK_BASE, 16, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_GET_PARTITION_INFO_EX     = CTL_CODE_T!(IOCTL_DISK_BASE, 0x12, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_SET_PARTITION_INFO_EX     = CTL_CODE_T!(IOCTL_DISK_BASE, 0x13, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),\n    IOCTL_DISK_GET_DRIVE_LAYOUT_EX       = CTL_CODE_T!(IOCTL_DISK_BASE, 0x14, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_SET_DRIVE_LAYOUT_EX       = CTL_CODE_T!(IOCTL_DISK_BASE, 0x15, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),\n    IOCTL_DISK_CREATE_DISK               = CTL_CODE_T!(IOCTL_DISK_BASE, 0x16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),\n    IOCTL_DISK_GET_LENGTH_INFO           = CTL_CODE_T!(IOCTL_DISK_BASE, 0x17, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_PERFORMANCE_OFF           = CTL_CODE_T!(IOCTL_DISK_BASE, 0x18, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_GET_DRIVE_GEOMETRY_EX     = CTL_CODE_T!(IOCTL_DISK_BASE, 0x28, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_GROW_PARTITION            = CTL_CODE_T!(IOCTL_DISK_BASE, 0x34, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),\n    IOCTL_DISK_GET_CACHE_INFORMATION     = CTL_CODE_T!(IOCTL_DISK_BASE, 0x35, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_SET_CACHE_INFORMATION     = CTL_CODE_T!(IOCTL_DISK_BASE, 0x36, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),\n    IOCTL_DISK_DELETE_DRIVE_LAYOUT       = CTL_CODE_T!(IOCTL_DISK_BASE, 0x40, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),\n    IOCTL_DISK_UPDATE_PROPERTIES         = CTL_CODE_T!(IOCTL_DISK_BASE, 0x50, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_CHECK_VERIFY              = CTL_CODE_T!(IOCTL_DISK_BASE, 0x200, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_MEDIA_REMOVAL             = CTL_CODE_T!(IOCTL_DISK_BASE, 0x201, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_EJECT_MEDIA               = CTL_CODE_T!(IOCTL_DISK_BASE, 0x202, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_LOAD_MEDIA                = CTL_CODE_T!(IOCTL_DISK_BASE, 0x203, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_RESERVE                   = CTL_CODE_T!(IOCTL_DISK_BASE, 0x204, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_RELEASE                   = CTL_CODE_T!(IOCTL_DISK_BASE, 0x205, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_FIND_NEW_DEVICES          = CTL_CODE_T!(IOCTL_DISK_BASE, 0x206, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_REMOVE_DEVICE             = CTL_CODE_T!(IOCTL_DISK_BASE, 0x207, METHOD_BUFFERED, FILE_READ_ACCESS),\n    IOCTL_DISK_GET_MEDIA_TYPES           = CTL_CODE_T!(IOCTL_DISK_BASE, 0x300, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_DISK_UPDATE_DRIVE_SIZE         = CTL_CODE_T!(IOCTL_DISK_BASE, 0x0032, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),\n    IOCTL_SERIAL_LSRMST_INSERT           = CTL_CODE_T!(FILE_DEVICE_SERIAL_PORT, 31, METHOD_BUFFERED, FILE_ANY_ACCESS),\n\n    IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = CTL_CODE_T!(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    IOCTL_VOLUME_IS_CLUSTERED            = CTL_CODE_T!(IOCTL_VOLUME_BASE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS),\n\n    FSCTL_LOCK_VOLUME                    = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    FSCTL_UNLOCK_VOLUME                  = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 7, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    FSCTL_DISMOUNT_VOLUME                = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    FSCTL_MOUNT_DBLS_VOLUME              = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 13, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    FSCTL_GET_COMPRESSION                = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 15, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    FSCTL_SET_COMPRESSION                = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 16, METHOD_BUFFERED, FILE_READ_DATA|FILE_WRITE_DATA),\n    FSCTL_READ_COMPRESSION               = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 17, METHOD_NEITHER, FILE_READ_DATA),\n    FSCTL_WRITE_COMPRESSION              = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 18, METHOD_NEITHER, FILE_WRITE_DATA),\n    FSCTL_GET_NTFS_VOLUME_DATA           = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 25, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    FSCTL_GET_VOLUME_BITMAP              = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 27, METHOD_NEITHER, FILE_ANY_ACCESS),\n    FSCTL_GET_RETRIEVAL_POINTERS         = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 28, METHOD_NEITHER, FILE_ANY_ACCESS),\n    FSCTL_MOVE_FILE                      = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 29, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    FSCTL_GET_REPARSE_POINT              = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    FSCTL_SET_REPARSE_POINT              = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    FSCTL_DELETE_REPARSE_POINT           = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_ANY_ACCESS),\n    FSCTL_SET_SPARSE                     = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_SPECIAL_ACCESS),\n}\n\nenum : BYTE {\n    PARTITION_ENTRY_UNUSED,\n    PARTITION_FAT_12,\n    PARTITION_XENIX_1,\n    PARTITION_XENIX_2,\n    PARTITION_FAT_16,\n    PARTITION_EXTENDED,\n    PARTITION_HUGE,\n    PARTITION_IFS,         // = 0x07\n    PARTITION_FAT32           = 0x0B,\n    PARTITION_FAT32_XINT13    = 0x0C,\n    PARTITION_XINT13          = 0x0E,\n    PARTITION_XINT13_EXTENDED = 0x0F,\n    PARTITION_PREP            = 0x41,\n    PARTITION_LDM             = 0x42,\n    PARTITION_UNIX            = 0x63\n}\n\nenum BYTE\n    PARTITION_NTFT = 0x80,\n    VALID_NTFT     = 0xC0;\n\nenum {\n    SERIAL_LSRMST_ESCAPE,\n    SERIAL_LSRMST_LSR_DATA,\n    SERIAL_LSRMST_LSR_NODATA,\n    SERIAL_LSRMST_MST\n}\n\nenum {\n    DISK_LOGGING_START,\n    DISK_LOGGING_STOP,\n    DISK_LOGGING_DUMP,\n    DISK_BINNING\n}\n\nalias WORD BAD_TRACK_NUMBER;\nalias WORD* PBAD_TRACK_NUMBER;\n\nenum BIN_TYPES {\n    RequestSize, RequestLocation\n}\n\nstruct BIN_RANGE {\n    LARGE_INTEGER StartValue;\n    LARGE_INTEGER Length;\n}\nalias BIN_RANGE* PBIN_RANGE;\n\nstruct BIN_COUNT {\n    BIN_RANGE BinRange;\n    DWORD     BinCount;\n}\nalias BIN_COUNT* PBIN_COUNT;\n\nstruct BIN_RESULTS {\n    DWORD     NumberOfBins;\n    BIN_COUNT _BinCounts;\n\n    BIN_COUNT* BinCounts() return { return &_BinCounts; }\n}\nalias BIN_RESULTS* PBIN_RESULTS;\n\nenum PARTITION_STYLE {\n    PARTITION_STYLE_MBR,\n    PARTITION_STYLE_GPT,\n    PARTITION_STYLE_RAW\n}\n\nstruct CREATE_DISK_GPT {\n    GUID  DiskId;\n    DWORD MaxPartitionCount;\n}\nalias CREATE_DISK_GPT* PCREATE_DISK_GPT;\n\nstruct CREATE_DISK_MBR {\n    DWORD Signature;\n}\nalias CREATE_DISK_MBR* PCREATE_DISK_MBR;\n\nstruct CREATE_DISK {\n    PARTITION_STYLE PartitionStyle;\n    union {\n        CREATE_DISK_MBR Mbr;\n        CREATE_DISK_GPT Gpt;\n    }\n}\nalias CREATE_DISK* PCREATE_DISK;\n\nenum DISK_CACHE_RETENTION_PRIORITY {\n    EqualPriority,\n    KeepPrefetchedData,\n    KeepReadData\n}\n\nstruct DISK_CACHE_INFORMATION {\n    BOOLEAN ParametersSavable;\n    BOOLEAN ReadCacheEnabled;\n    BOOLEAN WriteCacheEnabled;\n    DISK_CACHE_RETENTION_PRIORITY ReadRetentionPriority;\n    DISK_CACHE_RETENTION_PRIORITY WriteRetentionPriority;\n    WORD    DisablePrefetchTransferLength;\n    BOOLEAN PrefetchScalar;\n    union {\n        struct _ScalarPrefetch {\n            WORD Minimum;\n            WORD Maximum;\n            WORD MaximumBlocks;\n        }\n        _ScalarPrefetch ScalarPrefetch;\n        struct _BlockPrefetch {\n            WORD Minimum;\n            WORD Maximum;\n        }\n        _BlockPrefetch BlockPrefetch;\n    }\n}\nalias DISK_CACHE_INFORMATION* PDISK_CACHE_INFORMATION;\n\nenum DETECTION_TYPE {\n    DetectNone,\n    DetectInt13,\n    DetectExInt13\n}\n\nstruct DISK_INT13_INFO {\n    WORD  DriveSelect;\n    DWORD MaxCylinders;\n    WORD  SectorsPerTrack;\n    WORD  MaxHeads;\n    WORD  NumberDrives;\n    }\nalias DISK_INT13_INFO* PDISK_INT13_INFO;\n\nstruct DISK_EX_INT13_INFO {\n    WORD    ExBufferSize;\n    WORD    ExFlags;\n    DWORD   ExCylinders;\n    DWORD   ExHeads;\n    DWORD   ExSectorsPerTrack;\n    DWORD64 ExSectorsPerDrive;\n    WORD    ExSectorSize;\n    WORD    ExReserved;\n}\nalias DISK_EX_INT13_INFO* PDISK_EX_INT13_INFO;\n\nstruct DISK_DETECTION_INFO {\n    DWORD              SizeOfDetectInfo;\n    DETECTION_TYPE     DetectionType;\n    DISK_INT13_INFO    Int13;\n    DISK_EX_INT13_INFO ExInt13;\n}\nalias DISK_DETECTION_INFO* PDISK_DETECTION_INFO;\n\nenum MEDIA_TYPE {\n    Unknown,\n    F5_1Pt2_512,\n    F3_1Pt44_512,\n    F3_2Pt88_512,\n    F3_20Pt8_512,\n    F3_720_512,\n    F5_360_512,\n    F5_320_512,\n    F5_320_1024,\n    F5_180_512,\n    F5_160_512,\n    RemovableMedia,\n    FixedMedia,\n    F3_120M_512,\n    F3_640_512,\n    F5_640_512,\n    F5_720_512,\n    F3_1Pt2_512,\n    F3_1Pt23_1024,\n    F5_1Pt23_1024,\n    F3_128Mb_512,\n    F3_230Mb_512,\n    F8_256_128,\n    F3_200Mb_512,\n    F3_240M_512,\n    F3_32M_512\n}\nalias MEDIA_TYPE* PMEDIA_TYPE;\n\nstruct DISK_GEOMETRY {\n    LARGE_INTEGER Cylinders;\n    MEDIA_TYPE    MediaType;\n    DWORD         TracksPerCylinder;\n    DWORD         SectorsPerTrack;\n    DWORD         BytesPerSector;\n}\nalias DISK_GEOMETRY* PDISK_GEOMETRY;\n\nstruct DISK_GEOMETRY_EX {\n    DISK_GEOMETRY Geometry;\n    LARGE_INTEGER DiskSize;\n    BYTE          _Data;\n\n    BYTE* Data() return { return &_Data; }\n}\nalias DISK_GEOMETRY_EX* PDISK_GEOMETRY_EX;\n\nstruct DISK_GROW_PARTITION {\n    DWORD         PartitionNumber;\n    LARGE_INTEGER BytesToGrow;\n}\nalias DISK_GROW_PARTITION* PDISK_GROW_PARTITION;\n\nstruct DISK_PARTITION_INFO {\n    DWORD           SizeOfPartitionInfo;\n    PARTITION_STYLE PartitionStyle;\n    union {\n        //struct {\n            DWORD Signature;\n        //} Mbr;\n        //struct {\n            GUID DiskId;\n        //} Gpt;\n    }\n}\nalias DISK_PARTITION_INFO* PDISK_PARTITION_INFO;\n\nstruct DISK_PERFORMANCE {\n    LARGE_INTEGER BytesRead;\n    LARGE_INTEGER BytesWritten;\n    LARGE_INTEGER ReadTime;\n    LARGE_INTEGER WriteTime;\n    DWORD         ReadCount;\n    DWORD         WriteCount;\n    DWORD         QueueDepth;\n}\nalias DISK_PERFORMANCE* PDISK_PERFORMANCE;\n\nstruct DISK_RECORD {\n    LARGE_INTEGER ByteOffset;\n    LARGE_INTEGER StartTime;\n    LARGE_INTEGER EndTime;\n    PVOID         VirtualAddress;\n    DWORD         NumberOfBytes;\n    BYTE          DeviceNumber;\n    BOOLEAN       ReadRequest;\n}\nalias DISK_RECORD* PDISK_RECORD;\n\nstruct DISK_LOGGING {\n    BYTE  Function;\n    PVOID BufferAddress;\n    DWORD BufferSize;\n}\nalias DISK_LOGGING* PDISK_LOGGING;\n\nstruct DISKQUOTA_USER_INFORMATION {\n    LONGLONG QuotaUsed;\n    LONGLONG QuotaThreshold;\n    LONGLONG QuotaLimit;\n}\nalias DISKQUOTA_USER_INFORMATION* PDISKQUOTA_USER_INFORMATION;\n\nstruct FORMAT_PARAMETERS {\n    MEDIA_TYPE MediaType;\n    DWORD      StartCylinderNumber;\n    DWORD      EndCylinderNumber;\n    DWORD      StartHeadNumber;\n    DWORD      EndHeadNumber;\n}\nalias FORMAT_PARAMETERS* PFORMAT_PARAMETERS;\n\nstruct FORMAT_EX_PARAMETERS {\n    MEDIA_TYPE MediaType;\n    DWORD      StartCylinderNumber;\n    DWORD      EndCylinderNumber;\n    DWORD      StartHeadNumber;\n    DWORD      EndHeadNumber;\n    WORD       FormatGapLength;\n    WORD       SectorsPerTrack;\n    WORD       _SectorNumber;\n\n    WORD* SectorNumber() return { return &_SectorNumber; }\n}\nalias FORMAT_EX_PARAMETERS* PFORMAT_EX_PARAMETERS;\n\nstruct GET_LENGTH_INFORMATION {\n    LARGE_INTEGER Length;\n}\n\nstruct HISTOGRAM_BUCKET {\n    DWORD Reads;\n    DWORD Writes;\n}\nalias HISTOGRAM_BUCKET* PHISTOGRAM_BUCKET;\n\nstruct DISK_HISTOGRAM {\n    LARGE_INTEGER     DiskSize;\n    LARGE_INTEGER     Start;\n    LARGE_INTEGER     End;\n    LARGE_INTEGER     Average;\n    LARGE_INTEGER     AverageRead;\n    LARGE_INTEGER     AverageWrite;\n    DWORD             Granularity;\n    DWORD             Size;\n    DWORD             ReadCount;\n    DWORD             WriteCount;\n    PHISTOGRAM_BUCKET Histogram;\n}\nalias DISK_HISTOGRAM* PDISK_HISTOGRAM;\n\nstruct DISK_EXTENT {\n    DWORD         DiskNumber;\n    LARGE_INTEGER StartingOffset;\n    LARGE_INTEGER ExtentLength;\n}\nalias DISK_EXTENT* PDISK_EXTENT;\n\nstruct VOLUME_DISK_EXTENTS {\n    DWORD       NumberOfDiskExtents;\n    DISK_EXTENT _Extents;\n\n    DISK_EXTENT* Extents() return { return &_Extents; }\n}\nalias VOLUME_DISK_EXTENTS* PVOLUME_DISK_EXTENTS;\n\nstruct PARTITION_INFORMATION {\n    LARGE_INTEGER StartingOffset;\n    LARGE_INTEGER PartitionLength;\n    DWORD         HiddenSectors;\n    DWORD         PartitionNumber;\n    BYTE          PartitionType;\n    BOOLEAN       BootIndicator;\n    BOOLEAN       RecognizedPartition;\n    BOOLEAN       RewritePartition;\n}\nalias PARTITION_INFORMATION* PPARTITION_INFORMATION;\n\nstruct DRIVE_LAYOUT_INFORMATION {\n    DWORD                 PartitionCount;\n    DWORD                 Signature;\n    PARTITION_INFORMATION _PartitionEntry;\n\n    PARTITION_INFORMATION* PartitionEntry() return { return &_PartitionEntry; }\n}\nalias DRIVE_LAYOUT_INFORMATION* PDRIVE_LAYOUT_INFORMATION;\n\nstruct DRIVE_LAYOUT_INFORMATION_GPT {\n    GUID          DiskId;\n    LARGE_INTEGER StartingUsableOffset;\n    LARGE_INTEGER UsableLength;\n    ULONG         MaxPartitionCount;\n}\nalias DRIVE_LAYOUT_INFORMATION_GPT* PDRIVE_LAYOUT_INFORMATION_GPT;\n\nstruct DRIVE_LAYOUT_INFORMATION_MBR {\n    ULONG Signature;\n}\nalias DRIVE_LAYOUT_INFORMATION_MBR* PDRIVE_LAYOUT_INFORMATION_MBR;\n\nstruct PARTITION_INFORMATION_MBR {\n    BYTE    PartitionType;\n    BOOLEAN BootIndicator;\n    BOOLEAN RecognizedPartition;\n    DWORD   HiddenSectors;\n}\n\nstruct PARTITION_INFORMATION_GPT {\n    GUID      PartitionType;\n    GUID      PartitionId;\n    DWORD64   Attributes;\n    WCHAR[36] Name;\n}\n\nstruct PARTITION_INFORMATION_EX {\n    PARTITION_STYLE PartitionStyle;\n    LARGE_INTEGER   StartingOffset;\n    LARGE_INTEGER   PartitionLength;\n    DWORD           PartitionNumber;\n    BOOLEAN         RewritePartition;\n    union {\n        PARTITION_INFORMATION_MBR Mbr;\n        PARTITION_INFORMATION_GPT Gpt;\n    }\n}\n\nstruct DRIVE_LAYOUT_INFORMATION_EX {\n    DWORD PartitionStyle;\n    DWORD PartitionCount;\n    union {\n        DRIVE_LAYOUT_INFORMATION_MBR Mbr;\n        DRIVE_LAYOUT_INFORMATION_GPT Gpt;\n    }\n    PARTITION_INFORMATION_EX _PartitionEntry;\n\n    PARTITION_INFORMATION_EX* PartitionEntry() return { return &_PartitionEntry; }\n}\nalias DRIVE_LAYOUT_INFORMATION_EX* PDRIVE_LAYOUT_INFORMATION_EX;\n\nstruct MOVE_FILE_DATA {\n    HANDLE FileHandle;\n    LARGE_INTEGER StartingVcn;\n    LARGE_INTEGER StartingLcn;\n    DWORD ClusterCount;\n}\nalias MOVE_FILE_DATA* PMOVE_FILE_DATA;\n\nstruct PERF_BIN {\n    DWORD     NumberOfBins;\n    DWORD     TypeOfBin;\n    BIN_RANGE _BinsRanges;\n\n    BIN_RANGE* BinsRanges() return { return &_BinsRanges; }\n}\nalias PERF_BIN* PPERF_BIN;\n\nstruct PREVENT_MEDIA_REMOVAL {\n    BOOLEAN PreventMediaRemoval;\n}\nalias PREVENT_MEDIA_REMOVAL* PPREVENT_MEDIA_REMOVAL;\n\nstruct RETRIEVAL_POINTERS_BUFFER {\n    DWORD         ExtentCount;\n    LARGE_INTEGER StartingVcn;\n    // In MinGW, this is declared as struct { ... } Extents[1];\n    struct Extent {\n        LARGE_INTEGER NextVcn;\n        LARGE_INTEGER Lcn;\n    }\n    Extent _Extents;\n\n    Extent* Extents() return { return &_Extents; }\n}\nalias RETRIEVAL_POINTERS_BUFFER* PRETRIEVAL_POINTERS_BUFFER;\n\nstruct REASSIGN_BLOCKS {\n    WORD  Reserved;\n    WORD  Count;\n    DWORD _BlockNumber;\n\n    DWORD* BlockNumber() return { return &_BlockNumber; }\n}\nalias REASSIGN_BLOCKS* PREASSIGN_BLOCKS;\n\nstruct SET_PARTITION_INFORMATION {\n    BYTE PartitionType;\n}\nalias SET_PARTITION_INFORMATION* PSET_PARTITION_INFORMATION;\n\nstruct STARTING_LCN_INPUT_BUFFER {\n    LARGE_INTEGER StartingLcn;\n}\nalias STARTING_LCN_INPUT_BUFFER* PSTARTING_LCN_INPUT_BUFFER;\n\nstruct STARTING_VCN_INPUT_BUFFER {\n    LARGE_INTEGER StartingVcn;\n}\nalias STARTING_VCN_INPUT_BUFFER* PSTARTING_VCN_INPUT_BUFFER;\n\nstruct VERIFY_INFORMATION {\n    LARGE_INTEGER StartingOffset;\n    DWORD         Length;\n}\nalias VERIFY_INFORMATION* PVERIFY_INFORMATION;\n\nstruct VOLUME_BITMAP_BUFFER {\n    LARGE_INTEGER StartingLcn;\n    LARGE_INTEGER BitmapSize;\n    BYTE          _Buffer;\n\n    BYTE* Buffer() return { return &_Buffer; }\n}\nalias VOLUME_BITMAP_BUFFER* PVOLUME_BITMAP_BUFFER;\n\nstruct NTFS_VOLUME_DATA_BUFFER {\n    LARGE_INTEGER VolumeSerialNumber;\n    LARGE_INTEGER NumberSectors;\n    LARGE_INTEGER TotalClusters;\n    LARGE_INTEGER FreeClusters;\n    LARGE_INTEGER TotalReserved;\n    DWORD         BytesPerSector;\n    DWORD         BytesPerCluster;\n    DWORD         BytesPerFileRecordSegment;\n    DWORD         ClustersPerFileRecordSegment;\n    LARGE_INTEGER MftValidDataLength;\n    LARGE_INTEGER MftStartLcn;\n    LARGE_INTEGER Mft2StartLcn;\n    LARGE_INTEGER MftZoneStart;\n    LARGE_INTEGER MftZoneEnd;\n}\nalias NTFS_VOLUME_DATA_BUFFER* PNTFS_VOLUME_DATA_BUFFER;\n\n\nbool IsRecognizedPartition(BYTE t) {\n    return ((t & PARTITION_NTFT)\n      && ((t & (-1 - VALID_NTFT)) == PARTITION_FAT_12\n        || (t & (-1 - VALID_NTFT)) == PARTITION_FAT_16\n        || (t & (-1 - VALID_NTFT)) == PARTITION_IFS\n        || (t & (-1 - VALID_NTFT)) == PARTITION_HUGE\n        || (t & (-1 - VALID_NTFT)) == PARTITION_FAT32\n        || (t & (-1 - VALID_NTFT)) == PARTITION_FAT32_XINT13\n        || (t & (-1 - VALID_NTFT)) == PARTITION_XINT13))\n      || (t & (-1 - PARTITION_NTFT)) == PARTITION_FAT_12\n      || (t & (-1 - PARTITION_NTFT)) == PARTITION_FAT_16\n      || (t & (-1 - PARTITION_NTFT)) == PARTITION_IFS\n      || (t & (-1 - PARTITION_NTFT)) == PARTITION_HUGE\n      || (t & (-1 - PARTITION_NTFT)) == PARTITION_FAT32\n      || (t & (-1 - PARTITION_NTFT)) == PARTITION_FAT32_XINT13\n      || (t & (-1 - PARTITION_NTFT)) == PARTITION_XINT13;\n}\n\nbool IsContainerPartition(BYTE t) {\n    return ((t & PARTITION_NTFT)\n      && ((t & (-1 - VALID_NTFT)) == PARTITION_EXTENDED\n        || (t & (-1 - VALID_NTFT)) == PARTITION_XINT13_EXTENDED))\n      || (t & (-1 - PARTITION_NTFT)) == PARTITION_EXTENDED\n      || (t & (-1 - PARTITION_NTFT)) == PARTITION_XINT13_EXTENDED;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winldap.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winldap.d)\n */\nmodule core.sys.windows.winldap;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\n/* Comment from MinGW\n  winldap.h - Header file for the Windows LDAP API\n\n  Written by Filip Navara <xnavara@volny.cz>\n\n  References:\n    The C LDAP Application Program Interface\n    http://www.watersprings.org/pub/id/draft-ietf-ldapext-ldap-c-api-05.txt\n\n    Lightweight Directory Access Protocol Reference\n    http://msdn.microsoft.com/library/en-us/netdir/ldap/ldap_reference.asp\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n*/\n\nimport core.sys.windows.schannel, core.sys.windows.winber;\nprivate import core.sys.windows.wincrypt, core.sys.windows.windef;\n\n//align(4):\n\nenum {\n    LDAP_VERSION1    = 1,\n    LDAP_VERSION2    = 2,\n    LDAP_VERSION3    = 3,\n    LDAP_VERSION     = LDAP_VERSION2,\n    LDAP_VERSION_MIN = LDAP_VERSION2,\n    LDAP_VERSION_MAX = LDAP_VERSION3\n}\n\n/*  MinGW defines ANSI and Unicode versions as LDAP_VENDOR_NAME and\n *  LDAP_VENDOR_NAME_W respectively; similarly with other string constants\n *  defined in this module.\n */\nconst TCHAR[] LDAP_VENDOR_NAME = \"Microsoft Corporation.\";\n\nenum LDAP_API_VERSION          = 2004;\nenum LDAP_VENDOR_VERSION       =  510;\nenum LDAP_API_INFO_VERSION     =    1;\nenum LDAP_FEATURE_INFO_VERSION =    1;\n\nenum {\n    LDAP_SUCCESS                    = 0x00,\n    LDAP_OPT_SUCCESS                = LDAP_SUCCESS,\n    LDAP_OPERATIONS_ERROR,\n    LDAP_PROTOCOL_ERROR,\n    LDAP_TIMELIMIT_EXCEEDED,\n    LDAP_SIZELIMIT_EXCEEDED,\n    LDAP_COMPARE_FALSE,\n    LDAP_COMPARE_TRUE,\n    LDAP_STRONG_AUTH_NOT_SUPPORTED,\n    LDAP_AUTH_METHOD_NOT_SUPPORTED  = LDAP_STRONG_AUTH_NOT_SUPPORTED,\n    LDAP_STRONG_AUTH_REQUIRED,\n    LDAP_REFERRAL_V2,\n    LDAP_PARTIAL_RESULTS            = LDAP_REFERRAL_V2,\n    LDAP_REFERRAL,\n    LDAP_ADMIN_LIMIT_EXCEEDED,\n    LDAP_UNAVAILABLE_CRIT_EXTENSION,\n    LDAP_CONFIDENTIALITY_REQUIRED,\n    LDAP_SASL_BIND_IN_PROGRESS,  // = 0x0e\n    LDAP_NO_SUCH_ATTRIBUTE          = 0x10,\n    LDAP_UNDEFINED_TYPE,\n    LDAP_INAPPROPRIATE_MATCHING,\n    LDAP_CONSTRAINT_VIOLATION,\n    LDAP_TYPE_OR_VALUE_EXISTS,\n    LDAP_ATTRIBUTE_OR_VALUE_EXISTS  = LDAP_TYPE_OR_VALUE_EXISTS,\n    LDAP_INVALID_SYNTAX,         // = 0x15\n    LDAP_NO_SUCH_OBJECT             = 0x20,\n    LDAP_ALIAS_PROBLEM,\n    LDAP_INVALID_DN_SYNTAX,\n    LDAP_IS_LEAF,\n    LDAP_ALIAS_DEREF_PROBLEM,    // = 0x24\n    LDAP_INAPPROPRIATE_AUTH         = 0x30,\n    LDAP_INVALID_CREDENTIALS,\n    LDAP_INSUFFICIENT_ACCESS,\n    LDAP_INSUFFICIENT_RIGHTS        = LDAP_INSUFFICIENT_ACCESS,\n    LDAP_BUSY,\n    LDAP_UNAVAILABLE,\n    LDAP_UNWILLING_TO_PERFORM,\n    LDAP_LOOP_DETECT,            // = 0x36\n    LDAP_NAMING_VIOLATION           = 0x40,\n    LDAP_OBJECT_CLASS_VIOLATION,\n    LDAP_NOT_ALLOWED_ON_NONLEAF,\n    LDAP_NOT_ALLOWED_ON_RDN,\n    LDAP_ALREADY_EXISTS,\n    LDAP_NO_OBJECT_CLASS_MODS,\n    LDAP_RESULTS_TOO_LARGE,\n    LDAP_AFFECTS_MULTIPLE_DSAS,  // = 0x47\n    LDAP_OTHER                      = 0x50,\n    LDAP_SERVER_DOWN,\n    LDAP_LOCAL_ERROR,\n    LDAP_ENCODING_ERROR,\n    LDAP_DECODING_ERROR,\n    LDAP_TIMEOUT,\n    LDAP_AUTH_UNKNOWN,\n    LDAP_FILTER_ERROR,\n    LDAP_USER_CANCELLED,\n    LDAP_PARAM_ERROR,\n    LDAP_NO_MEMORY,\n    LDAP_CONNECT_ERROR,\n    LDAP_NOT_SUPPORTED,\n    LDAP_CONTROL_NOT_FOUND,\n    LDAP_NO_RESULTS_RETURNED,\n    LDAP_MORE_RESULTS_TO_RETURN,\n    LDAP_CLIENT_LOOP,\n    LDAP_REFERRAL_LIMIT_EXCEEDED // = 0x61\n}\n\nenum {\n    LDAP_PORT        =  389,\n    LDAP_SSL_PORT    =  636,\n    LDAP_GC_PORT     = 3268,\n    LDAP_SSL_GC_PORT = 3269\n}\n\nenum void*\n    LDAP_OPT_OFF = null,\n    LDAP_OPT_ON = cast(void*) 1;\n\nenum {\n    LDAP_OPT_API_INFO               = 0x00,\n    LDAP_OPT_DESC,\n    LDAP_OPT_DEREF,\n    LDAP_OPT_SIZELIMIT,\n    LDAP_OPT_TIMELIMIT,\n    LDAP_OPT_THREAD_FN_PTRS,\n    LDAP_OPT_REBIND_FN,\n    LDAP_OPT_REBIND_ARG,\n    LDAP_OPT_REFERRALS,\n    LDAP_OPT_RESTART,\n    LDAP_OPT_SSL,\n    LDAP_OPT_TLS                    = LDAP_OPT_SSL,\n    LDAP_OPT_IO_FN_PTRS,         // = 0x0b\n    LDAP_OPT_CACHE_FN_PTRS          = 0x0d,\n    LDAP_OPT_CACHE_STRATEGY,\n    LDAP_OPT_CACHE_ENABLE,\n    LDAP_OPT_REFERRAL_HOP_LIMIT,\n    LDAP_OPT_PROTOCOL_VERSION,\n    LDAP_OPT_VERSION                = LDAP_OPT_PROTOCOL_VERSION,\n    LDAP_OPT_SERVER_CONTROLS,\n    LDAP_OPT_CLIENT_CONTROLS,    // = 0x13\n    LDAP_OPT_API_FEATURE_INFO       = 0x15,\n    LDAP_OPT_HOST_NAME              = 0x30,\n    LDAP_OPT_ERROR_NUMBER,\n    LDAP_OPT_ERROR_STRING,\n    LDAP_OPT_SERVER_ERROR,\n    LDAP_OPT_SERVER_EXT_ERROR,   // = 0x34\n    LDAP_OPT_PING_KEEP_ALIVE        = 0x36,\n    LDAP_OPT_PING_WAIT_TIME,\n    LDAP_OPT_PING_LIMIT,         // = 0x38\n    LDAP_OPT_DNSDOMAIN_NAME         = 0x3b,\n    LDAP_OPT_GETDSNAME_FLAGS        = 0x3d,\n    LDAP_OPT_HOST_REACHABLE,\n    LDAP_OPT_PROMPT_CREDENTIALS,\n    LDAP_OPT_TCP_KEEPALIVE,      // = 0x40\n    LDAP_OPT_REFERRAL_CALLBACK      = 0x70,\n    LDAP_OPT_CLIENT_CERTIFICATE     = 0x80,\n    LDAP_OPT_SERVER_CERTIFICATE, // = 0x81\n    LDAP_OPT_AUTO_RECONNECT         = 0x91,\n    LDAP_OPT_SSPI_FLAGS,\n    LDAP_OPT_SSL_INFO,\n    LDAP_OPT_TLS_INFO               = LDAP_OPT_SSL_INFO,\n    LDAP_OPT_REF_DEREF_CONN_PER_MSG,\n    LDAP_OPT_SIGN,\n    LDAP_OPT_ENCRYPT,\n    LDAP_OPT_SASL_METHOD,\n    LDAP_OPT_AREC_EXCLUSIVE,\n    LDAP_OPT_SECURITY_CONTEXT,\n    LDAP_OPT_ROOTDSE_CACHE       // = 0x9a\n}\n\nenum {\n    LDAP_DEREF_NEVER,\n    LDAP_DEREF_SEARCHING,\n    LDAP_DEREF_FINDING,\n    LDAP_DEREF_ALWAYS\n}\n\nenum LDAP_NO_LIMIT = 0;\n\nconst TCHAR[] LDAP_CONTROL_REFERRALS = \"1.2.840.113556.1.4.616\";\n\n// FIXME: check type (declared with U suffix in MinGW)\nenum : uint {\n    LDAP_CHASE_SUBORDINATE_REFERRALS = 0x20,\n    LDAP_CHASE_EXTERNAL_REFERRALS    = 0x40\n}\n\nenum {\n    LDAP_SCOPE_DEFAULT = -1,\n    LDAP_SCOPE_BASE,\n    LDAP_SCOPE_ONELEVEL,\n    LDAP_SCOPE_SUBTREE\n}\n\nenum {\n    LDAP_MOD_ADD,\n    LDAP_MOD_DELETE,\n    LDAP_MOD_REPLACE,\n    LDAP_MOD_BVALUES = 0x80\n}\n\nenum : int {\n    LDAP_RES_BIND             = 0x61,\n    LDAP_RES_SEARCH_ENTRY     = 0x64,\n    LDAP_RES_SEARCH_RESULT    = 0x65,\n    LDAP_RES_MODIFY           = 0x67,\n    LDAP_RES_ADD              = 0x69,\n    LDAP_RES_DELETE           = 0x6b,\n    LDAP_RES_MODRDN           = 0x6d,\n    LDAP_RES_COMPARE          = 0x6f,\n    LDAP_RES_SEARCH_REFERENCE = 0x73,\n    LDAP_RES_EXTENDED         = 0x78,\n    LDAP_RES_ANY              = -1\n}\n\nenum {\n    LDAP_MSG_ONE,\n    LDAP_MSG_ALL,\n    LDAP_MSG_RECEIVED\n}\n\nconst TCHAR[]\n    LDAP_SERVER_SORT_OID         = \"1.2.840.113556.1.4.473\",\n    LDAP_SERVER_RESP_SORT_OID    = \"1.2.840.113556.1.4.474\",\n    LDAP_PAGED_RESULT_OID_STRING = \"1.2.840.113556.1.4.319\",\n    LDAP_CONTROL_VLVREQUEST      = \"2.16.840.1.113730.3.4.9\",\n    LDAP_CONTROL_VLVRESPONSE     = \"2.16.840.1.113730.3.4.10\",\n    LDAP_START_TLS_OID           = \"1.3.6.1.4.1.1466.20037\",\n    LDAP_TTL_EXTENDED_OP_OID     = \"1.3.6.1.4.1.1466.101.119.1\";\n\nenum {\n    LDAP_AUTH_NONE      = 0x00U,\n    LDAP_AUTH_SIMPLE    = 0x80U,\n    LDAP_AUTH_SASL      = 0x83U,\n    LDAP_AUTH_OTHERKIND = 0x86U,\n    LDAP_AUTH_EXTERNAL  = LDAP_AUTH_OTHERKIND | 0x0020U,\n    LDAP_AUTH_SICILY    = LDAP_AUTH_OTHERKIND | 0x0200U,\n    LDAP_AUTH_NEGOTIATE = LDAP_AUTH_OTHERKIND | 0x0400U,\n    LDAP_AUTH_MSN       = LDAP_AUTH_OTHERKIND | 0x0800U,\n    LDAP_AUTH_NTLM      = LDAP_AUTH_OTHERKIND | 0x1000U,\n    LDAP_AUTH_DIGEST    = LDAP_AUTH_OTHERKIND | 0x4000U,\n    LDAP_AUTH_DPA       = LDAP_AUTH_OTHERKIND | 0x2000U,\n    LDAP_AUTH_SSPI      = LDAP_AUTH_NEGOTIATE\n}\n\nenum {\n    LDAP_FILTER_AND        = 0xa0,\n    LDAP_FILTER_OR,\n    LDAP_FILTER_NOT,\n    LDAP_FILTER_EQUALITY,\n    LDAP_FILTER_SUBSTRINGS,\n    LDAP_FILTER_GE,\n    LDAP_FILTER_LE,     // = 0xa6\n    LDAP_FILTER_APPROX     = 0xa8,\n    LDAP_FILTER_EXTENSIBLE,\n    LDAP_FILTER_PRESENT    = 0x87\n}\n\nenum {\n    LDAP_SUBSTRING_INITIAL = 0x80,\n    LDAP_SUBSTRING_ANY,\n    LDAP_SUBSTRING_FINAL\n}\n\n// should be opaque structure\nstruct LDAP {\n    struct _ld_sp {\n        UINT_PTR sb_sd;\n        UCHAR[(10*ULONG.sizeof)+1] Reserved1;\n        ULONG_PTR sb_naddr;\n        UCHAR[(6*ULONG.sizeof)] Reserved2;\n    }\n    _ld_sp   ld_sp;\n    PCHAR    ld_host;\n    ULONG    ld_version;\n    UCHAR    ld_lberoptions;\n    int      ld_deref;\n    int      ld_timelimit;\n    int      ld_sizelimit;\n    int      ld_errno;\n    PCHAR    ld_matched;\n    PCHAR    ld_error;\n}\nalias LDAP* PLDAP;\n\n// should be opaque structure\nstruct LDAPMessage {\n    ULONG        lm_msgid;\n    ULONG        lm_msgtype;\n    BerElement*  lm_ber;\n    LDAPMessage* lm_chain;\n    LDAPMessage* lm_next;\n    ULONG        lm_time;\n}\nalias LDAPMessage* PLDAPMessage;\n\nstruct LDAP_TIMEVAL {\n    LONG tv_sec;\n    LONG tv_usec;\n}\nalias LDAP_TIMEVAL* PLDAP_TIMEVAL;\n\nstruct LDAPAPIInfoA {\n    int    ldapai_info_version;\n    int    ldapai_api_version;\n    int    ldapai_protocol_version;\n    char** ldapai_extensions;\n    char*  ldapai_vendor_name;\n    int    ldapai_vendor_version;\n}\nalias LDAPAPIInfoA* PLDAPAPIInfoA;\n\nstruct LDAPAPIInfoW {\n    int     ldapai_info_version;\n    int     ldapai_api_version;\n    int     ldapai_protocol_version;\n    PWCHAR* ldapai_extensions;\n    PWCHAR  ldapai_vendor_name;\n    int     ldapai_vendor_version;\n}\nalias LDAPAPIInfoW* PLDAPAPIInfoW;\n\nstruct LDAPAPIFeatureInfoA {\n    int   ldapaif_info_version;\n    char* ldapaif_name;\n    int   ldapaif_version;\n}\nalias LDAPAPIFeatureInfoA* PLDAPAPIFeatureInfoA;\n\nstruct LDAPAPIFeatureInfoW {\n    int    ldapaif_info_version;\n    PWCHAR ldapaif_name;\n    int    ldapaif_version;\n}\nalias LDAPAPIFeatureInfoW* PLDAPAPIFeatureInfoW;\n\nstruct LDAPControlA {\n    PCHAR    ldctl_oid;\n    BerValue ldctl_value;\n    BOOLEAN  ldctl_iscritical;\n}\nalias LDAPControlA* PLDAPControlA;\n\nstruct LDAPControlW {\n    PWCHAR   ldctl_oid;\n    BerValue ldctl_value;\n    BOOLEAN  ldctl_iscritical;\n}\nalias LDAPControlW* PLDAPControlW;\n\n/*  Do we really need these?  In MinGW, LDAPModA/W have only mod_op, mod_type\n *  and mod_vals, and macros are used to simulate anonymous unions in those\n *  structures.\n */\nunion mod_vals_u_tA {\n    PCHAR*     modv_strvals;\n    BerValue** modv_bvals;\n}\n\nunion mod_vals_u_tW {\n    PWCHAR*    modv_strvals;\n    BerValue** modv_bvals;\n}\n\nstruct LDAPModA {\n    ULONG         mod_op;\n    PCHAR         mod_type;\n\n    union {\n        mod_vals_u_tA mod_vals;\n        // The following members are defined as macros in MinGW.\n        PCHAR*        mod_values;\n        BerValue**    mod_bvalues;\n    }\n}\nalias LDAPModA* PLDAPModA;\n\nstruct LDAPModW {\n    ULONG         mod_op;\n    PWCHAR        mod_type;\n\n    union {\n        mod_vals_u_tW mod_vals;\n        // The following members are defined as macros in MinGW.\n        PWCHAR*       mod_values;\n        BerValue**    mod_bvalues;\n    }\n}\nalias LDAPModW* PLDAPModW;\n\n/* Opaque structure\n *  http://msdn.microsoft.com/library/en-us/ldap/ldap/ldapsearch.asp\n */\nstruct LDAPSearch;\nalias LDAPSearch* PLDAPSearch;\n\nstruct LDAPSortKeyA {\n    PCHAR   sk_attrtype;\n    PCHAR   sk_matchruleoid;\n    BOOLEAN sk_reverseorder;\n}\nalias LDAPSortKeyA* PLDAPSortKeyA;\n\nstruct LDAPSortKeyW {\n    PWCHAR  sk_attrtype;\n    PWCHAR  sk_matchruleoid;\n    BOOLEAN sk_reverseorder;\n}\nalias LDAPSortKeyW* PLDAPSortKeyW;\n\n/*  MinGW defines these as immediate function typedefs, which don't translate\n *  well into D.\n */\nextern (C) {\n    alias ULONG function(PLDAP, PLDAP, PWCHAR, PCHAR, ULONG, PVOID, PVOID,\n      PLDAP*) QUERYFORCONNECTION;\n    alias BOOLEAN function(PLDAP, PLDAP, PWCHAR, PCHAR, PLDAP, ULONG, PVOID,\n      PVOID, ULONG) NOTIFYOFNEWCONNECTION;\n    alias ULONG function(PLDAP, PLDAP) DEREFERENCECONNECTION;\n    alias BOOLEAN function(PLDAP, PSecPkgContext_IssuerListInfoEx,\n      PCCERT_CONTEXT*) QUERYCLIENTCERT;\n}\n\nstruct LDAP_REFERRAL_CALLBACK {\n    ULONG                  SizeOfCallbacks;\n    QUERYFORCONNECTION*    QueryForConnection;\n    NOTIFYOFNEWCONNECTION* NotifyRoutine;\n    DEREFERENCECONNECTION* DereferenceRoutine;\n}\nalias LDAP_REFERRAL_CALLBACK* PLDAP_REFERRAL_CALLBACK;\n\nstruct LDAPVLVInfo {\n    int       ldvlv_version;\n    uint      ldvlv_before_count;\n    uint      ldvlv_after_count;\n    uint      ldvlv_offset;\n    uint      ldvlv_count;\n    BerValue* ldvlv_attrvalue;\n    BerValue* ldvlv_context;\n    void*     ldvlv_extradata;\n}\n\n/*\n * Under Microsoft WinLDAP the function ldap_error is only stub.\n * This macro uses LDAP structure to get error string and pass it to the user.\n */\nprivate extern (C) int printf(in char* format, ...);\nint ldap_perror(LDAP* handle, char* message) {\n    return printf(\"%s: %s\\n\", message, handle.ld_error);\n}\n\n/*  FIXME: In MinGW, these are WINLDAPAPI == DECLSPEC_IMPORT.  Linkage\n *  attribute?\n */\nextern (C) {\n    PLDAP ldap_initA(PCHAR, ULONG);\n    PLDAP ldap_initW(PWCHAR, ULONG);\n    PLDAP ldap_openA(PCHAR, ULONG);\n    PLDAP ldap_openW(PWCHAR, ULONG);\n    PLDAP cldap_openA(PCHAR, ULONG);\n    PLDAP cldap_openW(PWCHAR, ULONG);\n    ULONG ldap_connect(LDAP*, LDAP_TIMEVAL*);\n    PLDAP ldap_sslinitA(PCHAR, ULONG, int);\n    PLDAP ldap_sslinitW(PWCHAR, ULONG, int);\n    ULONG ldap_start_tls_sA(LDAP*, PLDAPControlA*, PLDAPControlA*);\n    ULONG ldap_start_tls_sW(LDAP*, PLDAPControlW*, PLDAPControlW*);\n    BOOLEAN ldap_stop_tls_s(LDAP*);\n    ULONG ldap_get_optionA(LDAP*, int, void*);\n    ULONG ldap_get_optionW(LDAP*, int, void*);\n    ULONG ldap_set_optionA(LDAP*, int, void*);\n    ULONG ldap_set_optionW(LDAP*, int, void*);\n    ULONG ldap_control_freeA(LDAPControlA*);\n    ULONG ldap_control_freeW(LDAPControlW*);\n    ULONG ldap_controls_freeA(LDAPControlA**);\n    ULONG ldap_controls_freeW(LDAPControlW**);\n    ULONG ldap_free_controlsA(LDAPControlA**);\n    ULONG ldap_free_controlsW(LDAPControlW**);\n    ULONG ldap_sasl_bindA(LDAP*, PCHAR, PCHAR, BERVAL*, PLDAPControlA*,\n      PLDAPControlA*, int*);\n    ULONG ldap_sasl_bindW(LDAP*, PWCHAR, PWCHAR, BERVAL*, PLDAPControlW*,\n      PLDAPControlW*, int*);\n    ULONG ldap_sasl_bind_sA(LDAP*, PCHAR, PCHAR, BERVAL*, PLDAPControlA*,\n      PLDAPControlA*, PBERVAL*);\n    ULONG ldap_sasl_bind_sW(LDAP*, PWCHAR, PWCHAR, BERVAL*, PLDAPControlW*,\n      PLDAPControlW*, PBERVAL*);\n    ULONG ldap_simple_bindA(LDAP*, PCHAR, PCHAR);\n    ULONG ldap_simple_bindW(LDAP*, PWCHAR, PWCHAR);\n    ULONG ldap_simple_bind_sA(LDAP*, PCHAR, PCHAR);\n    ULONG ldap_simple_bind_sW(LDAP*, PWCHAR, PWCHAR);\n    ULONG ldap_unbind(LDAP*);\n    ULONG ldap_unbind_s(LDAP*);\n    ULONG ldap_search_extA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG,\n      PLDAPControlW*, PLDAPControlW*, ULONG, ULONG, ULONG*);\n    ULONG ldap_search_extW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG,\n      PLDAPControlW*, PLDAPControlW*, ULONG, ULONG, ULONG*);\n    ULONG ldap_search_ext_sA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG,\n      PLDAPControlA*, PLDAPControlA*, LDAP_TIMEVAL*, ULONG, LDAPMessage**);\n    ULONG ldap_search_ext_sW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG,\n      PLDAPControlW*, PLDAPControlW*, LDAP_TIMEVAL*, ULONG, LDAPMessage**);\n    ULONG ldap_searchA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG);\n    ULONG ldap_searchW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG);\n    ULONG ldap_search_sA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG,\n      LDAPMessage**);\n    ULONG ldap_search_sW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG,\n      LDAPMessage**);\n    ULONG ldap_search_stA(LDAP*, PCHAR, ULONG, PCHAR, PCHAR[], ULONG,\n      LDAP_TIMEVAL*, LDAPMessage**);\n    ULONG ldap_search_stW(LDAP*, PWCHAR, ULONG, PWCHAR, PWCHAR[], ULONG,\n      LDAP_TIMEVAL*, LDAPMessage**);\n    ULONG ldap_compare_extA(LDAP*, PCHAR, PCHAR, PCHAR, BerValue*,\n      PLDAPControlA*, PLDAPControlA*, ULONG*);\n    ULONG ldap_compare_extW(LDAP*, PWCHAR, PWCHAR, PWCHAR, BerValue*,\n      PLDAPControlW*, PLDAPControlW*, ULONG*);\n    ULONG ldap_compare_ext_sA(LDAP*, PCHAR, PCHAR, PCHAR, BerValue*,\n      PLDAPControlA*, PLDAPControlA*);\n    ULONG ldap_compare_ext_sW(LDAP*, PWCHAR, PWCHAR, PWCHAR, BerValue*,\n      PLDAPControlW*, PLDAPControlW*);\n    ULONG ldap_compareA(LDAP*, PCHAR, PCHAR, PCHAR);\n    ULONG ldap_compareW(LDAP*, PWCHAR, PWCHAR, PWCHAR);\n    ULONG ldap_compare_sA(LDAP*, PCHAR, PCHAR, PCHAR);\n    ULONG ldap_compare_sW(LDAP*, PWCHAR, PWCHAR, PWCHAR);\n    ULONG ldap_modify_extA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*,\n      PLDAPControlA*, ULONG*);\n    ULONG ldap_modify_extW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*,\n      PLDAPControlW*, ULONG*);\n    ULONG ldap_modify_ext_sA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*,\n      PLDAPControlA*);\n    ULONG ldap_modify_ext_sW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*,\n      PLDAPControlW*);\n    ULONG ldap_modifyA(LDAP*, PCHAR, LDAPModA*[]);\n    ULONG ldap_modifyW(LDAP*, PWCHAR, LDAPModW*[]);\n    ULONG ldap_modify_sA(LDAP*, PCHAR, LDAPModA*[]);\n    ULONG ldap_modify_sW(LDAP*, PWCHAR, LDAPModW*[]);\n    ULONG ldap_rename_extA(LDAP*, PCHAR, PCHAR, PCHAR, INT, PLDAPControlA*,\n      PLDAPControlA*, ULONG*);\n    ULONG ldap_rename_extW(LDAP*, PWCHAR, PWCHAR, PWCHAR, INT, PLDAPControlW*,\n      PLDAPControlW*, ULONG*);\n    ULONG ldap_rename_ext_sA(LDAP*, PCHAR, PCHAR, PCHAR, INT,\n      PLDAPControlA*, PLDAPControlA*);\n    ULONG ldap_rename_ext_sW(LDAP*, PWCHAR, PWCHAR, PWCHAR, INT,\n      PLDAPControlW*, PLDAPControlW*);\n    ULONG ldap_add_extA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*,\n      PLDAPControlA*, ULONG*);\n    ULONG ldap_add_extW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*,\n      PLDAPControlW*, ULONG*);\n    ULONG ldap_add_ext_sA(LDAP*, PCHAR, LDAPModA*[], PLDAPControlA*,\n      PLDAPControlA*);\n    ULONG ldap_add_ext_sW(LDAP*, PWCHAR, LDAPModW*[], PLDAPControlW*,\n      PLDAPControlW*);\n    ULONG ldap_addA(LDAP*, PCHAR, LDAPModA*[]);\n    ULONG ldap_addW(LDAP*, PWCHAR, LDAPModW*[]);\n    ULONG ldap_add_sA(LDAP*, PCHAR, LDAPModA*[]);\n    ULONG ldap_add_sW(LDAP*, PWCHAR, LDAPModW*[]);\n    ULONG ldap_delete_extA(LDAP*, PCHAR, PLDAPControlA*, PLDAPControlA*,\n      ULONG*);\n    ULONG ldap_delete_extW(LDAP*, PWCHAR, PLDAPControlW*, PLDAPControlW*,\n      ULONG*);\n    ULONG ldap_delete_ext_sA(LDAP*, PCHAR, PLDAPControlA*, PLDAPControlA*);\n    ULONG ldap_delete_ext_sW(LDAP*, PWCHAR, PLDAPControlW*, PLDAPControlW*);\n    ULONG ldap_deleteA(LDAP*, PCHAR);\n    ULONG ldap_deleteW(LDAP*, PWCHAR);\n    ULONG ldap_delete_sA(LDAP*, PCHAR);\n    ULONG ldap_delete_sW(LDAP*, PWCHAR);\n    ULONG ldap_extended_operationA(LDAP*, PCHAR, BerValue*, PLDAPControlA*,\n      PLDAPControlA*, ULONG*);\n    ULONG ldap_extended_operationW(LDAP*, PWCHAR, BerValue*, PLDAPControlW*,\n      PLDAPControlW*, ULONG*);\n    ULONG ldap_extended_operation_sA(LDAP*, PCHAR, BerValue*, PLDAPControlA*,\n      PLDAPControlA*, PCHAR*, BerValue**);\n    ULONG ldap_extended_operation_sW(LDAP*, PWCHAR, BerValue*, PLDAPControlW*,\n      PLDAPControlW*, PWCHAR*, BerValue**);\n    ULONG ldap_close_extended_op(LDAP*, ULONG);\n    ULONG ldap_abandon(LDAP*, ULONG);\n    ULONG ldap_result(LDAP*, ULONG, ULONG, LDAP_TIMEVAL*, LDAPMessage**);\n    ULONG ldap_msgfree(LDAPMessage*);\n    ULONG ldap_parse_resultA(LDAP*, LDAPMessage*, ULONG*, PCHAR*, PCHAR*,\n      PCHAR**, PLDAPControlA**, BOOLEAN);\n    ULONG ldap_parse_resultW(LDAP*, LDAPMessage*, ULONG*, PWCHAR*, PWCHAR*,\n      PWCHAR**, PLDAPControlW**, BOOLEAN);\n    ULONG ldap_parse_extended_resultA(LDAP, LDAPMessage*, PCHAR*, BerValue**,\n      BOOLEAN);\n    ULONG ldap_parse_extended_resultW(LDAP, LDAPMessage*, PWCHAR*, BerValue**,\n      BOOLEAN);\n    PCHAR ldap_err2stringA(ULONG);\n    PWCHAR ldap_err2stringW(ULONG);\n    ULONG LdapGetLastError();\n    ULONG LdapMapErrorToWin32(ULONG);\n    ULONG ldap_result2error(LDAP*, LDAPMessage*, ULONG);\n    PLDAPMessage ldap_first_entry(LDAP*, LDAPMessage*);\n    PLDAPMessage ldap_next_entry(LDAP*, LDAPMessage*);\n    PLDAPMessage ldap_first_reference(LDAP*, LDAPMessage*);\n    PLDAPMessage ldap_next_reference(LDAP*, LDAPMessage*);\n    ULONG ldap_count_entries(LDAP*, LDAPMessage*);\n    ULONG ldap_count_references(LDAP*, LDAPMessage*);\n    PCHAR ldap_first_attributeA(LDAP*, LDAPMessage*, BerElement**);\n    PWCHAR ldap_first_attributeW(LDAP*, LDAPMessage*, BerElement**);\n    PCHAR ldap_next_attributeA(LDAP*, LDAPMessage*, BerElement*);\n    PWCHAR ldap_next_attributeW(LDAP*, LDAPMessage*, BerElement*);\n    VOID ldap_memfreeA(PCHAR);\n    VOID ldap_memfreeW(PWCHAR);\n    PCHAR* ldap_get_valuesA(LDAP*, LDAPMessage*, PCHAR);\n    PWCHAR* ldap_get_valuesW(LDAP*, LDAPMessage*, PWCHAR);\n    BerValue** ldap_get_values_lenA(LDAP*, LDAPMessage*, PCHAR);\n    BerValue** ldap_get_values_lenW(LDAP*, LDAPMessage*, PWCHAR);\n    ULONG ldap_count_valuesA(PCHAR*);\n    ULONG ldap_count_valuesW(PWCHAR*);\n    ULONG ldap_count_values_len(BerValue**);\n    ULONG ldap_value_freeA(PCHAR*);\n    ULONG ldap_value_freeW(PWCHAR*);\n    ULONG ldap_value_free_len(BerValue**);\n    PCHAR ldap_get_dnA(LDAP*, LDAPMessage*);\n    PWCHAR ldap_get_dnW(LDAP*, LDAPMessage*);\n    PCHAR ldap_explode_dnA(PCHAR, ULONG);\n    PWCHAR ldap_explode_dnW(PWCHAR, ULONG);\n    PCHAR ldap_dn2ufnA(PCHAR);\n    PWCHAR ldap_dn2ufnW(PWCHAR);\n    ULONG ldap_ufn2dnA(PCHAR, PCHAR*);\n    ULONG ldap_ufn2dnW(PWCHAR, PWCHAR*);\n    ULONG ldap_parse_referenceA(LDAP*, LDAPMessage*, PCHAR**);\n    ULONG ldap_parse_referenceW(LDAP*, LDAPMessage*, PWCHAR**);\n    ULONG ldap_check_filterA(LDAP*, PCHAR);\n    ULONG ldap_check_filterW(LDAP*, PWCHAR);\n    ULONG ldap_create_page_controlA(PLDAP, ULONG, BerValue*, UCHAR,\n      PLDAPControlA*);\n    ULONG ldap_create_page_controlW(PLDAP, ULONG, BerValue*, UCHAR,\n      PLDAPControlW*);\n    ULONG ldap_create_sort_controlA(PLDAP, PLDAPSortKeyA*, UCHAR,\n      PLDAPControlA*);\n    ULONG ldap_create_sort_controlW(PLDAP, PLDAPSortKeyW*, UCHAR,\n    PLDAPControlW*);\n    INT ldap_create_vlv_controlA(LDAP*, LDAPVLVInfo*, UCHAR, LDAPControlA**);\n    INT ldap_create_vlv_controlW(LDAP*, LDAPVLVInfo*, UCHAR, LDAPControlW**);\n    ULONG ldap_encode_sort_controlA(PLDAP, PLDAPSortKeyA*, PLDAPControlA,\n      BOOLEAN);\n    ULONG ldap_encode_sort_controlW(PLDAP, PLDAPSortKeyW*, PLDAPControlW,\n      BOOLEAN);\n    ULONG ldap_escape_filter_elementA(PCHAR, ULONG, PCHAR, ULONG);\n    ULONG ldap_escape_filter_elementW(PWCHAR, ULONG, PWCHAR, ULONG);\n    ULONG ldap_get_next_page(PLDAP, PLDAPSearch, ULONG, ULONG*);\n    ULONG ldap_get_next_page_s(PLDAP, PLDAPSearch, LDAP_TIMEVAL*, ULONG,\n      ULONG*, LDAPMessage**);\n    ULONG ldap_get_paged_count(PLDAP, PLDAPSearch, ULONG*, PLDAPMessage);\n    ULONG ldap_parse_page_controlA(PLDAP, PLDAPControlA*, ULONG*, BerValue**);\n    ULONG ldap_parse_page_controlW(PLDAP, PLDAPControlW*, ULONG*, BerValue**);\n    ULONG ldap_parse_sort_controlA(PLDAP, PLDAPControlA*, ULONG*, PCHAR*);\n    ULONG ldap_parse_sort_controlW(PLDAP, PLDAPControlW*, ULONG*, PWCHAR*);\n    INT ldap_parse_vlv_controlA(LDAP*, LDAPControlA**, uint*, uint*,\n      BerValue**, int*);\n    INT ldap_parse_vlv_controlW(LDAP*, LDAPControlW**, uint*, uint*,\n      BerValue**, int*);\n    PLDAPSearch ldap_search_init_pageA(PLDAP, PCHAR, ULONG, PCHAR, PCHAR[],\n      ULONG, PLDAPControlA*, PLDAPControlA*, ULONG, ULONG, PLDAPSortKeyA*);\n    PLDAPSearch ldap_search_init_pageW(PLDAP, PWCHAR, ULONG, PWCHAR, PWCHAR[],\n      ULONG, PLDAPControlW*, PLDAPControlW*, ULONG, ULONG, PLDAPSortKeyW*);\n    ULONG ldap_search_abandon_page(PLDAP, PLDAPSearch);\n    LDAP ldap_conn_from_msg(LDAP*, LDAPMessage*);\n    INT LdapUnicodeToUTF8(LPCWSTR, int, LPSTR, int);\n    INT LdapUTF8ToUnicode(LPCSTR, int, LPWSTR, int);\n    deprecated {\n        ULONG ldap_bindA(LDAP*, PCHAR, PCHAR, ULONG);\n        ULONG ldap_bindW(LDAP*, PWCHAR, PWCHAR, ULONG);\n        ULONG ldap_bind_sA(LDAP*, PCHAR, PCHAR, ULONG);\n        ULONG ldap_bind_sW(LDAP*, PWCHAR, PWCHAR, ULONG);\n        ULONG ldap_modrdnA(LDAP*, PCHAR, PCHAR);\n        ULONG ldap_modrdnW(LDAP*, PWCHAR, PWCHAR);\n        ULONG ldap_modrdn_sA(LDAP*, PCHAR, PCHAR);\n        ULONG ldap_modrdn_sW(LDAP*, PWCHAR, PWCHAR);\n        ULONG ldap_modrdn2A(LDAP*, PCHAR, PCHAR, INT);\n        ULONG ldap_modrdn2W(LDAP*, PWCHAR, PWCHAR, INT);\n        ULONG ldap_modrdn2_sA(LDAP*, PCHAR, PCHAR, INT);\n        ULONG ldap_modrdn2_sW(LDAP*, PWCHAR, PWCHAR, INT);\n    }\n}\n\nversion (Unicode) {\n    alias LDAPControlW LDAPControl;\n    alias PLDAPControlW PLDAPControl;\n    alias LDAPModW LDAPMod;\n    alias LDAPModW PLDAPMod;\n    alias LDAPSortKeyW LDAPSortKey;\n    alias PLDAPSortKeyW PLDAPSortKey;\n    alias LDAPAPIInfoW LDAPAPIInfo;\n    alias PLDAPAPIInfoW PLDAPAPIInfo;\n    alias LDAPAPIFeatureInfoW LDAPAPIFeatureInfo;\n    alias PLDAPAPIFeatureInfoW PLDAPAPIFeatureInfo;\n    alias cldap_openW cldap_open;\n    alias ldap_openW ldap_open;\n    alias ldap_simple_bindW ldap_simple_bind;\n    alias ldap_simple_bind_sW ldap_simple_bind_s;\n    alias ldap_sasl_bindW ldap_sasl_bind;\n    alias ldap_sasl_bind_sW ldap_sasl_bind_s;\n    alias ldap_initW ldap_init;\n    alias ldap_sslinitW ldap_sslinit;\n    alias ldap_get_optionW ldap_get_option;\n    alias ldap_set_optionW ldap_set_option;\n    alias ldap_start_tls_sW ldap_start_tls_s;\n    alias ldap_addW ldap_add;\n    alias ldap_add_extW ldap_add_ext;\n    alias ldap_add_sW ldap_add_s;\n    alias ldap_add_ext_sW ldap_add_ext_s;\n    alias ldap_compareW ldap_compare;\n    alias ldap_compare_extW ldap_compare_ext;\n    alias ldap_compare_sW ldap_compare_s;\n    alias ldap_compare_ext_sW ldap_compare_ext_s;\n    alias ldap_deleteW ldap_delete;\n    alias ldap_delete_extW ldap_delete_ext;\n    alias ldap_delete_sW ldap_delete_s;\n    alias ldap_delete_ext_sW ldap_delete_ext_s;\n    alias ldap_extended_operation_sW ldap_extended_operation_s;\n    alias ldap_extended_operationW ldap_extended_operation;\n    alias ldap_modifyW ldap_modify;\n    alias ldap_modify_extW ldap_modify_ext;\n    alias ldap_modify_sW ldap_modify_s;\n    alias ldap_modify_ext_sW ldap_modify_ext_s;\n    alias ldap_check_filterW ldap_check_filter;\n    alias ldap_count_valuesW ldap_count_values;\n    alias ldap_create_page_controlW ldap_create_page_control;\n    alias ldap_create_sort_controlW ldap_create_sort_control;\n    alias ldap_create_vlv_controlW ldap_create_vlv_control;\n    alias ldap_encode_sort_controlW ldap_encode_sort_control;\n    alias ldap_escape_filter_elementW ldap_escape_filter_element;\n    alias ldap_first_attributeW ldap_first_attribute;\n    alias ldap_next_attributeW ldap_next_attribute;\n    alias ldap_get_valuesW ldap_get_values;\n    alias ldap_get_values_lenW ldap_get_values_len;\n    alias ldap_parse_extended_resultW ldap_parse_extended_result;\n    alias ldap_parse_page_controlW ldap_parse_page_control;\n    alias ldap_parse_referenceW ldap_parse_reference;\n    alias ldap_parse_resultW ldap_parse_result;\n    alias ldap_parse_sort_controlW ldap_parse_sort_control;\n    alias ldap_parse_vlv_controlW ldap_parse_vlv_control;\n    alias ldap_searchW ldap_search;\n    alias ldap_search_sW ldap_search_s;\n    alias ldap_search_stW ldap_search_st;\n    alias ldap_search_extW ldap_search_ext;\n    alias ldap_search_ext_sW ldap_search_ext_s;\n    alias ldap_search_init_pageW ldap_search_init_page;\n    alias ldap_err2stringW ldap_err2string;\n    alias ldap_control_freeW ldap_control_free;\n    alias ldap_controls_freeW ldap_controls_free;\n    alias ldap_free_controlsW ldap_free_controls;\n    alias ldap_memfreeW ldap_memfree;\n    alias ldap_value_freeW ldap_value_free;\n    alias ldap_dn2ufnW ldap_dn2ufn;\n    alias ldap_ufn2dnW ldap_ufn2dn;\n    alias ldap_explode_dnW ldap_explode_dn;\n    alias ldap_get_dnW ldap_get_dn;\n    alias ldap_rename_extW ldap_rename;\n    alias ldap_rename_ext_sW ldap_rename_s;\n    alias ldap_rename_extW ldap_rename_ext;\n    alias ldap_rename_ext_sW ldap_rename_ext_s;\n    deprecated {\n        alias ldap_bindW ldap_bind;\n        alias ldap_bind_sW ldap_bind_s;\n        alias ldap_modrdnW ldap_modrdn;\n        alias ldap_modrdn_sW ldap_modrdn_s;\n        alias ldap_modrdn2W ldap_modrdn2;\n        alias ldap_modrdn2_sW ldap_modrdn2_s;\n    }\n} else {\n    alias LDAPControlA LDAPControl;\n    alias PLDAPControlA PLDAPControl;\n    alias LDAPModA LDAPMod;\n    alias LDAPModA PLDAPMod;\n    alias LDAPSortKeyA LDAPSortKey;\n    alias PLDAPSortKeyA PLDAPSortKey;\n    alias LDAPAPIInfoA LDAPAPIInfo;\n    alias PLDAPAPIInfoA PLDAPAPIInfo;\n    alias LDAPAPIFeatureInfoA LDAPAPIFeatureInfo;\n    alias PLDAPAPIFeatureInfoA PLDAPAPIFeatureInfo;\n    alias cldap_openA cldap_open;\n    alias ldap_openA ldap_open;\n    alias ldap_simple_bindA ldap_simple_bind;\n    alias ldap_simple_bind_sA ldap_simple_bind_s;\n    alias ldap_sasl_bindA ldap_sasl_bind;\n    alias ldap_sasl_bind_sA ldap_sasl_bind_s;\n    alias ldap_initA ldap_init;\n    alias ldap_sslinitA ldap_sslinit;\n    alias ldap_get_optionA ldap_get_option;\n    alias ldap_set_optionA ldap_set_option;\n    alias ldap_start_tls_sA ldap_start_tls_s;\n    alias ldap_addA ldap_add;\n    alias ldap_add_extA ldap_add_ext;\n    alias ldap_add_sA ldap_add_s;\n    alias ldap_add_ext_sA ldap_add_ext_s;\n    alias ldap_compareA ldap_compare;\n    alias ldap_compare_extA ldap_compare_ext;\n    alias ldap_compare_sA ldap_compare_s;\n    alias ldap_compare_ext_sA ldap_compare_ext_s;\n    alias ldap_deleteA ldap_delete;\n    alias ldap_delete_extA ldap_delete_ext;\n    alias ldap_delete_sA ldap_delete_s;\n    alias ldap_delete_ext_sA ldap_delete_ext_s;\n    alias ldap_extended_operation_sA ldap_extended_operation_s;\n    alias ldap_extended_operationA ldap_extended_operation;\n    alias ldap_modifyA ldap_modify;\n    alias ldap_modify_extA ldap_modify_ext;\n    alias ldap_modify_sA ldap_modify_s;\n    alias ldap_modify_ext_sA ldap_modify_ext_s;\n    alias ldap_check_filterA ldap_check_filter;\n    alias ldap_count_valuesA ldap_count_values;\n    alias ldap_create_page_controlA ldap_create_page_control;\n    alias ldap_create_sort_controlA ldap_create_sort_control;\n    alias ldap_create_vlv_controlA ldap_create_vlv_control;\n    alias ldap_encode_sort_controlA ldap_encode_sort_control;\n    alias ldap_escape_filter_elementA ldap_escape_filter_element;\n    alias ldap_first_attributeA ldap_first_attribute;\n    alias ldap_next_attributeA ldap_next_attribute;\n    alias ldap_get_valuesA ldap_get_values;\n    alias ldap_get_values_lenA ldap_get_values_len;\n    alias ldap_parse_extended_resultA ldap_parse_extended_result;\n    alias ldap_parse_page_controlA ldap_parse_page_control;\n    alias ldap_parse_referenceA ldap_parse_reference;\n    alias ldap_parse_resultA ldap_parse_result;\n    alias ldap_parse_sort_controlA ldap_parse_sort_control;\n    alias ldap_parse_vlv_controlA ldap_parse_vlv_control;\n    alias ldap_searchA ldap_search;\n    alias ldap_search_sA ldap_search_s;\n    alias ldap_search_stA ldap_search_st;\n    alias ldap_search_extA ldap_search_ext;\n    alias ldap_search_ext_sA ldap_search_ext_s;\n    alias ldap_search_init_pageA ldap_search_init_page;\n    alias ldap_err2stringA ldap_err2string;\n    alias ldap_control_freeA ldap_control_free;\n    alias ldap_controls_freeA ldap_controls_free;\n    alias ldap_free_controlsA ldap_free_controls;\n    alias ldap_memfreeA ldap_memfree;\n    alias ldap_value_freeA ldap_value_free;\n    alias ldap_dn2ufnA ldap_dn2ufn;\n    alias ldap_ufn2dnA ldap_ufn2dn;\n    alias ldap_explode_dnA ldap_explode_dn;\n    alias ldap_get_dnA ldap_get_dn;\n    alias ldap_rename_extA ldap_rename;\n    alias ldap_rename_ext_sA ldap_rename_s;\n    alias ldap_rename_extA ldap_rename_ext;\n    alias ldap_rename_ext_sA ldap_rename_ext_s;\n    deprecated {\n        alias ldap_bindA ldap_bind;\n        alias ldap_bind_sA ldap_bind_s;\n        alias ldap_modrdnA ldap_modrdn;\n        alias ldap_modrdn_sA ldap_modrdn_s;\n        alias ldap_modrdn2A ldap_modrdn2;\n        alias ldap_modrdn2_sA ldap_modrdn2_s;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winnetwk.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winnetwk.d)\n */\nmodule core.sys.windows.winnetwk;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"mpr\");\n\nprivate import core.sys.windows.winbase, core.sys.windows.winerror, core.sys.windows.winnt;\n\nenum : DWORD {\n    WNNC_NET_MSNET       = 0x00010000,\n    WNNC_NET_LANMAN      = 0x00020000,\n    WNNC_NET_NETWARE     = 0x00030000,\n    WNNC_NET_VINES       = 0x00040000,\n    WNNC_NET_10NET       = 0x00050000,\n    WNNC_NET_LOCUS       = 0x00060000,\n    WNNC_NET_SUN_PC_NFS  = 0x00070000,\n    WNNC_NET_LANSTEP     = 0x00080000,\n    WNNC_NET_9TILES      = 0x00090000,\n    WNNC_NET_LANTASTIC   = 0x000A0000,\n    WNNC_NET_AS400       = 0x000B0000,\n    WNNC_NET_FTP_NFS     = 0x000C0000,\n    WNNC_NET_PATHWORKS   = 0x000D0000,\n    WNNC_NET_LIFENET     = 0x000E0000,\n    WNNC_NET_POWERLAN    = 0x000F0000,\n    WNNC_NET_BWNFS       = 0x00100000,\n    WNNC_NET_COGENT      = 0x00110000,\n    WNNC_NET_FARALLON    = 0x00120000,\n    WNNC_NET_APPLETALK   = 0x00130000,\n    WNNC_NET_INTERGRAPH  = 0x00140000,\n    WNNC_NET_SYMFONET    = 0x00150000,\n    WNNC_NET_CLEARCASE   = 0x00160000,\n    WNNC_NET_FRONTIER    = 0x00170000,\n    WNNC_NET_BMC         = 0x00180000,\n    WNNC_NET_DCE         = 0x00190000,\n    WNNC_NET_AVID        = 0x001A0000,\n    WNNC_NET_DOCUSPACE   = 0x001B0000,\n    WNNC_NET_MANGOSOFT   = 0x001C0000,\n    WNNC_NET_SERNET      = 0x001D0000,\n    WNNC_NET_DECORB      = 0x00200000,\n    WNNC_NET_PROTSTOR    = 0x00210000,\n    WNNC_NET_FJ_REDIR    = 0x00220000,\n    WNNC_NET_DISTINCT    = 0x00230000,\n    WNNC_NET_TWINS       = 0x00240000,\n    WNNC_NET_RDR2SAMPLE  = 0x00250000,\n    WNNC_NET_CSC         = 0x00260000,\n    WNNC_NET_3IN1        = 0x00270000,\n    WNNC_NET_EXTENDNET   = 0x00290000,\n    WNNC_NET_OBJECT_DIRE = 0x00300000,\n    WNNC_NET_MASFAX      = 0x00310000,\n    WNNC_NET_HOB_NFS     = 0x00320000,\n    WNNC_NET_SHIVA       = 0x00330000,\n    WNNC_NET_IBMAL       = 0x00340000,\n    WNNC_CRED_MANAGER    = 0xFFFF0000\n}\n\nenum : DWORD {\n    RESOURCE_CONNECTED  = 1,\n    RESOURCE_GLOBALNET  = 2,\n    RESOURCE_REMEMBERED = 3,\n    RESOURCE_RECENT     = 4,\n    RESOURCE_CONTEXT    = 5\n}\n\nenum DWORD\n    RESOURCETYPE_ANY      = 0,\n    RESOURCETYPE_DISK     = 1,\n    RESOURCETYPE_PRINT    = 2,\n    RESOURCETYPE_RESERVED = 8,\n    RESOURCETYPE_UNKNOWN  = 0xFFFFFFFF;\n\nenum DWORD\n    RESOURCEUSAGE_CONNECTABLE   = 0x00000001,\n    RESOURCEUSAGE_CONTAINER     = 0x00000002,\n    RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004,\n    RESOURCEUSAGE_SIBLING       = 0x00000008,\n    RESOURCEUSAGE_ATTACHED      = 0x00000010,\n    RESOURCEUSAGE_ALL           = (RESOURCEUSAGE_CONNECTABLE\n                                  | RESOURCEUSAGE_CONTAINER\n                                  | RESOURCEUSAGE_ATTACHED),\n    RESOURCEUSAGE_RESERVED      = 0x80000000;\n\nenum : DWORD {\n    RESOURCEDISPLAYTYPE_GENERIC,\n    RESOURCEDISPLAYTYPE_DOMAIN,\n    RESOURCEDISPLAYTYPE_SERVER,\n    RESOURCEDISPLAYTYPE_SHARE,\n    RESOURCEDISPLAYTYPE_FILE,\n    RESOURCEDISPLAYTYPE_GROUP,\n    RESOURCEDISPLAYTYPE_NETWORK,\n    RESOURCEDISPLAYTYPE_ROOT,\n    RESOURCEDISPLAYTYPE_SHAREADMIN,\n    RESOURCEDISPLAYTYPE_DIRECTORY,\n    RESOURCEDISPLAYTYPE_TREE // = 10\n}\n\nenum NETPROPERTY_PERSISTENT = 1;\n\nenum DWORD\n    CONNECT_UPDATE_PROFILE =   1,\n    CONNECT_UPDATE_RECENT  =   2,\n    CONNECT_TEMPORARY      =   4,\n    CONNECT_INTERACTIVE    =   8,\n    CONNECT_PROMPT         =  16,\n    CONNECT_NEED_DRIVE     =  32,\n    CONNECT_REFCOUNT       =  64,\n    CONNECT_REDIRECT       = 128,\n    CONNECT_LOCALDRIVE     = 256,\n    CONNECT_CURRENT_MEDIA  = 512;\n\nenum DWORD\n    CONNDLG_RO_PATH     =  1,\n    CONNDLG_CONN_POINT  =  2,\n    CONNDLG_USE_MRU     =  4,\n    CONNDLG_HIDE_BOX    =  8,\n    CONNDLG_PERSIST     = 16,\n    CONNDLG_NOT_PERSIST = 32;\n\nenum DWORD\n    DISC_UPDATE_PROFILE =  1,\n    DISC_NO_FORCE       = 64;\n\nenum DWORD\n    WNFMT_MULTILINE   =  1,\n    WNFMT_ABBREVIATED =  2,\n    WNFMT_INENUM      = 16,\n    WNFMT_CONNECTION  = 32;\n\nenum : DWORD {\n    WN_SUCCESS                   = NO_ERROR,\n    WN_NO_ERROR                  = NO_ERROR,\n    WN_NOT_SUPPORTED             = ERROR_NOT_SUPPORTED,\n    WN_CANCEL                    = ERROR_CANCELLED,\n    WN_RETRY                     = ERROR_RETRY,\n    WN_NET_ERROR                 = ERROR_UNEXP_NET_ERR,\n    WN_MORE_DATA                 = ERROR_MORE_DATA,\n    WN_BAD_POINTER               = ERROR_INVALID_ADDRESS,\n    WN_BAD_VALUE                 = ERROR_INVALID_PARAMETER,\n    WN_BAD_USER                  = ERROR_BAD_USERNAME,\n    WN_BAD_PASSWORD              = ERROR_INVALID_PASSWORD,\n    WN_ACCESS_DENIED             = ERROR_ACCESS_DENIED,\n    WN_FUNCTION_BUSY             = ERROR_BUSY,\n    WN_WINDOWS_ERROR             = ERROR_UNEXP_NET_ERR,\n    WN_OUT_OF_MEMORY             = ERROR_NOT_ENOUGH_MEMORY,\n    WN_NO_NETWORK                = ERROR_NO_NETWORK,\n    WN_EXTENDED_ERROR            = ERROR_EXTENDED_ERROR,\n    WN_BAD_LEVEL                 = ERROR_INVALID_LEVEL,\n    WN_BAD_HANDLE                = ERROR_INVALID_HANDLE,\n    WN_NOT_INITIALIZING          = ERROR_ALREADY_INITIALIZED,\n    WN_NO_MORE_DEVICES           = ERROR_NO_MORE_DEVICES,\n    WN_NOT_CONNECTED             = ERROR_NOT_CONNECTED,\n    WN_OPEN_FILES                = ERROR_OPEN_FILES,\n    WN_DEVICE_IN_USE             = ERROR_DEVICE_IN_USE,\n    WN_BAD_NETNAME               = ERROR_BAD_NET_NAME,\n    WN_BAD_LOCALNAME             = ERROR_BAD_DEVICE,\n    WN_ALREADY_CONNECTED         = ERROR_ALREADY_ASSIGNED,\n    WN_DEVICE_ERROR              = ERROR_GEN_FAILURE,\n    WN_CONNECTION_CLOSED         = ERROR_CONNECTION_UNAVAIL,\n    WN_NO_NET_OR_BAD_PATH        = ERROR_NO_NET_OR_BAD_PATH,\n    WN_BAD_PROVIDER              = ERROR_BAD_PROVIDER,\n    WN_CANNOT_OPEN_PROFILE       = ERROR_CANNOT_OPEN_PROFILE,\n    WN_BAD_PROFILE               = ERROR_BAD_PROFILE,\n    WN_BAD_DEV_TYPE              = ERROR_BAD_DEV_TYPE,\n    WN_DEVICE_ALREADY_REMEMBERED = ERROR_DEVICE_ALREADY_REMEMBERED,\n    WN_NO_MORE_ENTRIES           = ERROR_NO_MORE_ITEMS,\n    WN_NOT_CONTAINER             = ERROR_NOT_CONTAINER,\n    WN_NOT_AUTHENTICATED         = ERROR_NOT_AUTHENTICATED,\n    WN_NOT_LOGGED_ON             = ERROR_NOT_LOGGED_ON,\n    WN_NOT_VALIDATED             = ERROR_NO_LOGON_SERVERS\n}\n\nenum : DWORD {\n    UNIVERSAL_NAME_INFO_LEVEL = 1,\n    REMOTE_NAME_INFO_LEVEL\n}\n\nenum DWORD\n    NETINFO_DLL16      = 1,\n    NETINFO_DISKRED    = 4,\n    NETINFO_PRINTERRED = 8;\n\nenum DWORD\n    RP_LOGON   = 1,\n    RP_INIFILE = 2;\n\nenum DWORD PP_DISPLAYERRORS = 1;\n\nenum DWORD\n    WNCON_FORNETCARD = 1,\n    WNCON_NOTROUTED  = 2,\n    WNCON_SLOWLINK   = 4,\n    WNCON_DYNAMIC    = 8;\n\nstruct NETRESOURCEA {\n    DWORD dwScope;\n    DWORD dwType;\n    DWORD dwDisplayType;\n    DWORD dwUsage;\n    LPSTR lpLocalName;\n    LPSTR lpRemoteName;\n    LPSTR lpComment;\n    LPSTR lpProvider;\n}\nalias NETRESOURCEA* LPNETRESOURCEA;\n\nstruct NETRESOURCEW {\n    DWORD  dwScope;\n    DWORD  dwType;\n    DWORD  dwDisplayType;\n    DWORD  dwUsage;\n    LPWSTR lpLocalName;\n    LPWSTR lpRemoteName;\n    LPWSTR lpComment ;\n    LPWSTR lpProvider;\n}\nalias NETRESOURCEW* LPNETRESOURCEW;\n\nstruct CONNECTDLGSTRUCTA {\n    DWORD          cbStructure;\n    HWND           hwndOwner;\n    LPNETRESOURCEA lpConnRes;\n    DWORD          dwFlags;\n    DWORD          dwDevNum;\n}\nalias CONNECTDLGSTRUCTA* LPCONNECTDLGSTRUCTA;\n\nstruct CONNECTDLGSTRUCTW {\n    DWORD          cbStructure;\n    HWND           hwndOwner;\n    LPNETRESOURCEW lpConnRes;\n    DWORD          dwFlags;\n    DWORD          dwDevNum;\n}\nalias CONNECTDLGSTRUCTW* LPCONNECTDLGSTRUCTW;\n\nstruct DISCDLGSTRUCTA {\n    DWORD cbStructure;\n    HWND  hwndOwner;\n    LPSTR lpLocalName;\n    LPSTR lpRemoteName;\n    DWORD dwFlags;\n}\nalias DISCDLGSTRUCTA* LPDISCDLGSTRUCTA;\n\nstruct DISCDLGSTRUCTW {\n    DWORD  cbStructure;\n    HWND   hwndOwner;\n    LPWSTR lpLocalName;\n    LPWSTR lpRemoteName;\n    DWORD  dwFlags;\n}\nalias DISCDLGSTRUCTW* LPDISCDLGSTRUCTW;\n\nstruct UNIVERSAL_NAME_INFOA {\n    LPSTR lpUniversalName;\n}\nalias UNIVERSAL_NAME_INFOA* LPUNIVERSAL_NAME_INFOA;\n\nstruct UNIVERSAL_NAME_INFOW {\n    LPWSTR lpUniversalName;\n}\nalias UNIVERSAL_NAME_INFOW* LPUNIVERSAL_NAME_INFOW;\n\nstruct REMOTE_NAME_INFOA {\n    LPSTR lpUniversalName;\n    LPSTR lpConnectionName;\n    LPSTR lpRemainingPath;\n}\nalias REMOTE_NAME_INFOA* LPREMOTE_NAME_INFOA;\n\nstruct REMOTE_NAME_INFOW {\n    LPWSTR lpUniversalName;\n    LPWSTR lpConnectionName;\n    LPWSTR lpRemainingPath;\n}\nalias REMOTE_NAME_INFOW* LPREMOTE_NAME_INFOW;\n\nstruct NETINFOSTRUCT {\n    DWORD cbStructure;\n    DWORD dwProviderVersion;\n    DWORD dwStatus;\n    DWORD dwCharacteristics;\n    ULONG_PTR dwHandle;\n    WORD  wNetType;\n    DWORD dwPrinters;\n    DWORD dwDrives;\n}\nalias NETINFOSTRUCT* LPNETINFOSTRUCT;\n\nextern (Pascal) {\n    alias UINT function(LPCSTR, LPSTR, UINT) PFNGETPROFILEPATHA;\n    alias UINT function(LPCWSTR, LPWSTR, UINT) PFNGETPROFILEPATHW;\n    alias UINT function(LPCSTR, LPCSTR, DWORD) PFNRECONCILEPROFILEA;\n    alias UINT function(LPCWSTR, LPCWSTR, DWORD) PFNRECONCILEPROFILEW;\n    alias BOOL function(HWND, LPCSTR, LPCSTR, LPCSTR, DWORD)\n      PFNPROCESSPOLICIESA;\n    alias BOOL function(HWND, LPCWSTR, LPCWSTR, LPCWSTR, DWORD)\n      PFNPROCESSPOLICIESW;\n}\n\nstruct NETCONNECTINFOSTRUCT {\n    DWORD cbStructure;\n    DWORD dwFlags;\n    DWORD dwSpeed;\n    DWORD dwDelay;\n    DWORD dwOptDataSize;\n}\nalias NETCONNECTINFOSTRUCT* LPNETCONNECTINFOSTRUCT;\n\nextern (Windows) {\n    DWORD WNetAddConnection2A(LPNETRESOURCEA, LPCSTR, LPCSTR, DWORD);\n    DWORD WNetAddConnection2W(LPNETRESOURCEW, LPCWSTR, LPCWSTR, DWORD);\n    DWORD WNetAddConnection3A(HWND, LPNETRESOURCEA, LPCSTR, LPCSTR, DWORD);\n    DWORD WNetAddConnection3W(HWND, LPNETRESOURCEW, LPCWSTR, LPCWSTR, DWORD);\n    DWORD WNetCancelConnection2A(LPCSTR, DWORD, BOOL);\n    DWORD WNetCancelConnection2W(LPCWSTR, DWORD, BOOL);\n    DWORD WNetGetConnectionA(LPCSTR, LPSTR, PDWORD);\n    DWORD WNetGetConnectionW(LPCWSTR, LPWSTR, PDWORD);\n    DWORD WNetUseConnectionA(HWND, LPNETRESOURCEA, LPCSTR, LPCSTR, DWORD,\n      LPSTR, PDWORD, PDWORD);\n    DWORD WNetUseConnectionW(HWND, LPNETRESOURCEW, LPCWSTR, LPCWSTR, DWORD,\n      LPWSTR, PDWORD, PDWORD);\n    DWORD WNetSetConnectionA(LPCSTR, DWORD, PVOID);\n    DWORD WNetSetConnectionW(LPCWSTR, DWORD, PVOID);\n    DWORD WNetConnectionDialog(HWND, DWORD);\n    DWORD WNetDisconnectDialog(HWND, DWORD);\n    DWORD WNetConnectionDialog1A(LPCONNECTDLGSTRUCTA);\n    DWORD WNetConnectionDialog1W(LPCONNECTDLGSTRUCTW);\n    DWORD WNetDisconnectDialog1A(LPDISCDLGSTRUCTA);\n    DWORD WNetDisconnectDialog1W(LPDISCDLGSTRUCTW);\n    DWORD WNetOpenEnumA(DWORD, DWORD, DWORD, LPNETRESOURCEA, LPHANDLE);\n    DWORD WNetOpenEnumW(DWORD, DWORD, DWORD, LPNETRESOURCEW, LPHANDLE);\n    DWORD WNetEnumResourceA(HANDLE, PDWORD, PVOID, PDWORD);\n    DWORD WNetEnumResourceW(HANDLE, PDWORD, PVOID, PDWORD);\n    DWORD WNetCloseEnum(HANDLE);\n    DWORD WNetGetUniversalNameA(LPCSTR, DWORD, PVOID, PDWORD);\n    DWORD WNetGetUniversalNameW(LPCWSTR, DWORD, PVOID, PDWORD);\n    DWORD WNetGetUserA(LPCSTR, LPSTR, PDWORD);\n    DWORD WNetGetUserW(LPCWSTR, LPWSTR, PDWORD);\n    DWORD WNetGetProviderNameA(DWORD, LPSTR, PDWORD);\n    DWORD WNetGetProviderNameW(DWORD, LPWSTR, PDWORD);\n    DWORD WNetGetNetworkInformationA(LPCSTR, LPNETINFOSTRUCT);\n    DWORD WNetGetNetworkInformationW(LPCWSTR, LPNETINFOSTRUCT);\n    DWORD WNetGetResourceInformationA(LPNETRESOURCEA, LPVOID, LPDWORD,\n      LPSTR*);\n    DWORD WNetGetResourceInformationW(LPNETRESOURCEA, LPVOID, LPDWORD,\n      LPWSTR*);\n    DWORD WNetGetResourceParentA(LPNETRESOURCEA, LPVOID, LPDWORD);\n    DWORD WNetGetResourceParentW(LPNETRESOURCEW, LPVOID, LPDWORD);\n    DWORD WNetGetLastErrorA(PDWORD, LPSTR, DWORD, LPSTR, DWORD);\n    DWORD WNetGetLastErrorW(PDWORD, LPWSTR, DWORD, LPWSTR, DWORD);\n    DWORD MultinetGetConnectionPerformanceA(LPNETRESOURCEA,\n      LPNETCONNECTINFOSTRUCT);\n    DWORD MultinetGetConnectionPerformanceW(LPNETRESOURCEW,\n      LPNETCONNECTINFOSTRUCT);\n    deprecated {\n        DWORD WNetAddConnectionA(LPCSTR, LPCSTR, LPCSTR);\n        DWORD WNetAddConnectionW(LPCWSTR, LPCWSTR, LPCWSTR);\n        DWORD WNetCancelConnectionA(LPCSTR, BOOL);\n        DWORD WNetCancelConnectionW(LPCWSTR, BOOL);\n    }\n}\n\nversion (Unicode) {\n    alias PFNGETPROFILEPATHW PFNGETPROFILEPATH;\n    alias PFNRECONCILEPROFILEW PFNRECONCILEPROFILE;\n    alias PFNPROCESSPOLICIESW PFNPROCESSPOLICIES;\n    alias NETRESOURCEW NETRESOURCE;\n    alias CONNECTDLGSTRUCTW CONNECTDLGSTRUCT;\n    alias DISCDLGSTRUCTW DISCDLGSTRUCT;\n    alias REMOTE_NAME_INFOW REMOTE_NAME_INFO;\n    alias UNIVERSAL_NAME_INFOW UNIVERSAL_NAME_INFO;\n    alias WNetAddConnection2W WNetAddConnection2;\n    alias WNetAddConnection3W WNetAddConnection3;\n    alias WNetCancelConnection2W WNetCancelConnection2;\n    alias WNetGetConnectionW WNetGetConnection;\n    alias WNetUseConnectionW WNetUseConnection;\n    alias WNetSetConnectionW WNetSetConnection;\n    alias WNetConnectionDialog1W WNetConnectionDialog1;\n    alias WNetDisconnectDialog1W WNetDisconnectDialog1;\n    alias WNetOpenEnumW WNetOpenEnum;\n    alias WNetEnumResourceW WNetEnumResource;\n    alias WNetGetUniversalNameW WNetGetUniversalName;\n    alias WNetGetUserW WNetGetUser;\n    alias WNetGetProviderNameW WNetGetProviderName;\n    alias WNetGetNetworkInformationW WNetGetNetworkInformation;\n    alias WNetGetResourceInformationW WNetGetResourceInformation;\n    alias WNetGetResourceParentW WNetGetResourceParent;\n    alias WNetGetLastErrorW WNetGetLastError;\n    alias MultinetGetConnectionPerformanceW MultinetGetConnectionPerformance;\n    deprecated {\n        alias WNetAddConnectionW WNetAddConnection;\n        alias WNetCancelConnectionW WNetCancelConnection;\n    }\n} else {\n    alias PFNGETPROFILEPATHA PFNGETPROFILEPATH;\n    alias PFNRECONCILEPROFILEA PFNRECONCILEPROFILE;\n    alias PFNPROCESSPOLICIESA PFNPROCESSPOLICIES;\n    alias NETRESOURCEA NETRESOURCE;\n    alias CONNECTDLGSTRUCTA CONNECTDLGSTRUCT;\n    alias DISCDLGSTRUCTA DISCDLGSTRUCT;\n    alias REMOTE_NAME_INFOA REMOTE_NAME_INFO;\n    alias UNIVERSAL_NAME_INFOA UNIVERSAL_NAME_INFO;\n    alias WNetAddConnection2A WNetAddConnection2;\n    alias WNetAddConnection3A WNetAddConnection3;\n    alias WNetCancelConnection2A WNetCancelConnection2;\n    alias WNetGetConnectionA WNetGetConnection;\n    alias WNetUseConnectionA WNetUseConnection;\n    alias WNetSetConnectionA WNetSetConnection;\n    alias WNetConnectionDialog1A WNetConnectionDialog1;\n    alias WNetDisconnectDialog1A WNetDisconnectDialog1;\n    alias WNetOpenEnumA WNetOpenEnum;\n    alias WNetEnumResourceA WNetEnumResource;\n    alias WNetGetUniversalNameA WNetGetUniversalName;\n    alias WNetGetUserA WNetGetUser;\n    alias WNetGetProviderNameA WNetGetProviderName;\n    alias WNetGetNetworkInformationA WNetGetNetworkInformation;\n    alias WNetGetResourceInformationA WNetGetResourceInformation;\n    alias WNetGetResourceParentA WNetGetResourceParent;\n    alias WNetGetLastErrorA WNetGetLastError;\n    alias MultinetGetConnectionPerformanceA MultinetGetConnectionPerformance;\n    deprecated {\n        alias WNetAddConnectionA WNetAddConnection;\n        alias WNetCancelConnectionA WNetCancelConnection;\n    }\n}\n\nalias NETRESOURCE* LPNETRESOURCE;\nalias CONNECTDLGSTRUCT* LPCONNECTDLGSTRUCT;\nalias DISCDLGSTRUCT* LPDISCDLGSTRUCT;\nalias REMOTE_NAME_INFO* LPREMOTE_NAME_INFO;\nalias UNIVERSAL_NAME_INFO* LPUNIVERSAL_NAME_INFO;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winnls.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winnls.d)\n */\nmodule core.sys.windows.winnls;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"kernel32\");\n\nprivate import core.sys.windows.basetsd, core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;\n\nalias DWORD LCTYPE, CALTYPE, CALID, LGRPID, GEOID, GEOTYPE, GEOCLASS;\n\nenum size_t\n    MAX_DEFAULTCHAR =  2,\n    MAX_LEADBYTES   = 12;\n\nenum LCTYPE\n    LOCALE_USE_CP_ACP    = 0x40000000,\n    LOCALE_RETURN_NUMBER = 0x20000000;\n\nenum : LCTYPE {\n    LOCALE_ILANGUAGE = 1,\n    LOCALE_SLANGUAGE,\n    LOCALE_SABBREVLANGNAME,\n    LOCALE_SNATIVELANGNAME,\n    LOCALE_ICOUNTRY,\n    LOCALE_SCOUNTRY,\n    LOCALE_SABBREVCTRYNAME,\n    LOCALE_SNATIVECTRYNAME,\n    LOCALE_IDEFAULTLANGUAGE,\n    LOCALE_IDEFAULTCOUNTRY,\n    LOCALE_IDEFAULTCODEPAGE,\n    LOCALE_SLIST,\n    LOCALE_IMEASURE,\n    LOCALE_SDECIMAL,\n    LOCALE_STHOUSAND,\n    LOCALE_SGROUPING,\n    LOCALE_IDIGITS,\n    LOCALE_ILZERO,\n    LOCALE_SNATIVEDIGITS,\n    LOCALE_SCURRENCY,\n    LOCALE_SINTLSYMBOL,\n    LOCALE_SMONDECIMALSEP,\n    LOCALE_SMONTHOUSANDSEP,\n    LOCALE_SMONGROUPING,\n    LOCALE_ICURRDIGITS,\n    LOCALE_IINTLCURRDIGITS,\n    LOCALE_ICURRENCY,\n    LOCALE_INEGCURR,\n    LOCALE_SDATE,\n    LOCALE_STIME,\n    LOCALE_SSHORTDATE,\n    LOCALE_SLONGDATE,\n    LOCALE_IDATE,\n    LOCALE_ILDATE,\n    LOCALE_ITIME,\n    LOCALE_ICENTURY,\n    LOCALE_ITLZERO,\n    LOCALE_IDAYLZERO,\n    LOCALE_IMONLZERO,\n    LOCALE_S1159,\n    LOCALE_S2359,\n    LOCALE_SDAYNAME1,\n    LOCALE_SDAYNAME2,\n    LOCALE_SDAYNAME3,\n    LOCALE_SDAYNAME4,\n    LOCALE_SDAYNAME5,\n    LOCALE_SDAYNAME6,\n    LOCALE_SDAYNAME7,\n    LOCALE_SABBREVDAYNAME1,\n    LOCALE_SABBREVDAYNAME2,\n    LOCALE_SABBREVDAYNAME3,\n    LOCALE_SABBREVDAYNAME4,\n    LOCALE_SABBREVDAYNAME5,\n    LOCALE_SABBREVDAYNAME6,\n    LOCALE_SABBREVDAYNAME7,\n    LOCALE_SMONTHNAME1,\n    LOCALE_SMONTHNAME2,\n    LOCALE_SMONTHNAME3,\n    LOCALE_SMONTHNAME4,\n    LOCALE_SMONTHNAME5,\n    LOCALE_SMONTHNAME6,\n    LOCALE_SMONTHNAME7,\n    LOCALE_SMONTHNAME8,\n    LOCALE_SMONTHNAME9,\n    LOCALE_SMONTHNAME10,\n    LOCALE_SMONTHNAME11,\n    LOCALE_SMONTHNAME12,\n    LOCALE_SABBREVMONTHNAME1,\n    LOCALE_SABBREVMONTHNAME2,\n    LOCALE_SABBREVMONTHNAME3,\n    LOCALE_SABBREVMONTHNAME4,\n    LOCALE_SABBREVMONTHNAME5,\n    LOCALE_SABBREVMONTHNAME6,\n    LOCALE_SABBREVMONTHNAME7,\n    LOCALE_SABBREVMONTHNAME8,\n    LOCALE_SABBREVMONTHNAME9,\n    LOCALE_SABBREVMONTHNAME10,\n    LOCALE_SABBREVMONTHNAME11,\n    LOCALE_SABBREVMONTHNAME12,\n    LOCALE_SPOSITIVESIGN,\n    LOCALE_SNEGATIVESIGN,\n    LOCALE_IPOSSIGNPOSN,\n    LOCALE_INEGSIGNPOSN,\n    LOCALE_IPOSSYMPRECEDES,\n    LOCALE_IPOSSEPBYSPACE,\n    LOCALE_INEGSYMPRECEDES,\n    LOCALE_INEGSEPBYSPACE,\n    LOCALE_FONTSIGNATURE,\n    LOCALE_SISO639LANGNAME,\n    LOCALE_SISO3166CTRYNAME, // = 90\n    LOCALE_SENGLANGUAGE         = 0x1001,\n    LOCALE_SENGCOUNTRY          = 0x1002,\n    LOCALE_IDEFAULTANSICODEPAGE = 0x1004,\n    LOCALE_INEGNUMBER           = 0x1010,\n    LOCALE_STIMEFORMAT          = 0x1003,\n    LOCALE_ITIMEMARKPOSN        = 0x1005,\n    LOCALE_ICALENDARTYPE        = 0x1009,\n    LOCALE_IOPTIONALCALENDAR    = 0x100B,\n    LOCALE_IFIRSTDAYOFWEEK      = 0x100C,\n    LOCALE_IFIRSTWEEKOFYEAR     = 0x100D,\n    LOCALE_SMONTHNAME13         = 0x100E,\n    LOCALE_SABBREVMONTHNAME13   = 0x100F\n}\n\nenum : LCID {\n    LOCALE_USER_DEFAULT   = 0x400,\n    LOCALE_SYSTEM_DEFAULT = 0x800\n}\n\nenum DWORD\n    NORM_IGNORECASE     =       1,\n    NORM_IGNORENONSPACE =       2,\n    NORM_IGNORESYMBOLS  =       4,\n    SORT_STRINGSORT     = 0x01000,\n    NORM_IGNOREKANATYPE = 0x10000,\n    NORM_IGNOREWIDTH    = 0x20000;\n\nenum DWORD\n    LCMAP_LOWERCASE           = 0x00000100,\n    LCMAP_UPPERCASE           = 0x00000200,\n    LCMAP_SORTKEY             = 0x00000400,\n    LCMAP_BYTEREV             = 0x00000800,\n    LCMAP_HIRAGANA            = 0x00100000,\n    LCMAP_KATAKANA            = 0x00200000,\n    LCMAP_HALFWIDTH           = 0x00400000,\n    LCMAP_FULLWIDTH           = 0x00800000,\n    LCMAP_LINGUISTIC_CASING   = 0x01000000,\n    LCMAP_SIMPLIFIED_CHINESE  = 0x02000000,\n    LCMAP_TRADITIONAL_CHINESE = 0x04000000;\n\nenum CALID ENUM_ALL_CALENDARS = -1;\n\nenum DWORD\n    DATE_SHORTDATE        =          1,\n    DATE_LONGDATE         =          2,\n    DATE_USE_ALT_CALENDAR =          4,\n    LOCALE_NOUSEROVERRIDE = 0x80000000;\n\nenum : DWORD {\n    CP_INSTALLED = 1,\n    CP_SUPPORTED\n}\n\nenum : DWORD {\n    LCID_INSTALLED       = 1,\n    LCID_SUPPORTED       = 2,\n    LCID_ALTERNATE_SORTS = 4\n}\n\nenum DWORD\n    MAP_FOLDCZONE   =  16,\n    MAP_PRECOMPOSED =  32,\n    MAP_COMPOSITE   =  64,\n    MAP_FOLDDIGITS  = 128;\n\nenum : UINT {\n    CP_ACP,\n    CP_OEMCP,\n    CP_MACCP,\n    CP_THREAD_ACP, // =     3\n    CP_SYMBOL         =    42,\n    CP_UTF7           = 65000,\n    CP_UTF8           = 65001\n}\n\nenum : DWORD {\n    CT_CTYPE1 = 1,\n    CT_CTYPE2 = 2,\n    CT_CTYPE3 = 4\n}\n\nenum WORD\n    C1_UPPER  =   1,\n    C1_LOWER  =   2,\n    C1_DIGIT  =   4,\n    C1_SPACE  =   8,\n    C1_PUNCT  =  16,\n    C1_CNTRL  =  32,\n    C1_BLANK  =  64,\n    C1_XDIGIT = 128,\n    C1_ALPHA  = 256;\n\nenum : WORD {\n    C2_NOTAPPLICABLE,\n    C2_LEFTTORIGHT,\n    C2_RIGHTTOLEFT,\n    C2_EUROPENUMBER,\n    C2_EUROPESEPARATOR,\n    C2_EUROPETERMINATOR,\n    C2_ARABICNUMBER,\n    C2_COMMONSEPARATOR,\n    C2_BLOCKSEPARATOR,\n    C2_SEGMENTSEPARATOR,\n    C2_WHITESPACE,\n    C2_OTHERNEUTRAL  // = 11\n}\n\nenum WORD\n    C3_NOTAPPLICABLE =      0,\n    C3_NONSPACING    =      1,\n    C3_DIACRITIC     =      2,\n    C3_VOWELMARK     =      4,\n    C3_SYMBOL        =      8,\n    C3_KATAKANA      = 0x0010,\n    C3_HIRAGANA      = 0x0020,\n    C3_HALFWIDTH     = 0x0040,\n    C3_FULLWIDTH     = 0x0080,\n    C3_IDEOGRAPH     = 0x0100,\n    C3_KASHIDA       = 0x0200,\n    C3_LEXICAL       = 0x0400,\n    C3_ALPHA         = 0x8000;\n\nenum DWORD\n    TIME_NOMINUTESORSECONDS = 1,\n    TIME_NOSECONDS          = 2,\n    TIME_NOTIMEMARKER       = 4,\n    TIME_FORCE24HOURFORMAT  = 8;\n\nenum DWORD\n    MB_PRECOMPOSED       = 1,\n    MB_COMPOSITE         = 2,\n    MB_USEGLYPHCHARS     = 4,\n    MB_ERR_INVALID_CHARS = 8;\n\nenum DWORD\n    WC_DISCARDNS      =  16,\n    WC_SEPCHARS       =  32,\n    WC_DEFAULTCHAR    =  64,\n    WC_COMPOSITECHECK = 512;\n\nenum : LONG {\n    CTRY_DEFAULT            =   0,\n    CTRY_DOMINICAN_REPUBLIC =   1,\n    CTRY_PUERTO_RICO        =   1,\n    CTRY_CARIBBEAN          =   1,\n    CTRY_JAMAICA            =   1,\n    CTRY_UNITED_STATES      =   1,\n    CTRY_TRINIDAD_Y_TOBAGO  =   1,\n    CTRY_CANADA             =   2,\n    CTRY_RUSSIA             =   7,\n    CTRY_UZBEKISTAN         =   7,\n    CTRY_KAZAKSTAN          =   7,\n    CTRY_TATARSTAN          =   7,\n    CTRY_EGYPT              =  20,\n    CTRY_SOUTH_AFRICA       =  27,\n    CTRY_GREECE             =  30,\n    CTRY_NETHERLANDS        =  31,\n    CTRY_BELGIUM            =  32,\n    CTRY_FRANCE             =  33,\n    CTRY_MONACO             =  33,\n    CTRY_SPAIN              =  34,\n    CTRY_HUNGARY            =  36,\n    CTRY_ITALY              =  39,\n    CTRY_ROMANIA            =  40,\n    CTRY_SWITZERLAND        =  41,\n    CTRY_LIECHTENSTEIN      =  41,\n    CTRY_AUSTRIA            =  43,\n    CTRY_UNITED_KINGDOM     =  44,\n    CTRY_DENMARK            =  45,\n    CTRY_SWEDEN             =  46,\n    CTRY_NORWAY             =  47,\n    CTRY_POLAND             =  48,\n    CTRY_GERMANY            =  49,\n    CTRY_PERU               =  51,\n    CTRY_MEXICO             =  52,\n    CTRY_ARGENTINA          =  54,\n    CTRY_BRAZIL             =  55,\n    CTRY_CHILE              =  56,\n    CTRY_COLOMBIA           =  57,\n    CTRY_VENEZUELA          =  58,\n    CTRY_MALAYSIA           =  60,\n    CTRY_AUSTRALIA          =  61,\n    CTRY_INDONESIA          =  62,\n    CTRY_PHILIPPINES        =  63,\n    CTRY_NEW_ZEALAND        =  64,\n    CTRY_SINGAPORE          =  65,\n    CTRY_THAILAND           =  66,\n    CTRY_JAPAN              =  81,\n    CTRY_SOUTH_KOREA        =  82,\n    CTRY_VIET_NAM           =  84,\n    CTRY_PRCHINA            =  86,\n    CTRY_TURKEY             =  90,\n    CTRY_INDIA              =  91,\n    CTRY_PAKISTAN           =  92,\n    CTRY_MOROCCO            = 212,\n    CTRY_ALGERIA            = 213,\n    CTRY_TUNISIA            = 216,\n    CTRY_LIBYA              = 218,\n    CTRY_KENYA              = 254,\n    CTRY_ZIMBABWE           = 263,\n    CTRY_FAEROE_ISLANDS     = 298,\n    CTRY_PORTUGAL           = 351,\n    CTRY_LUXEMBOURG         = 352,\n    CTRY_IRELAND            = 353,\n    CTRY_ICELAND            = 354,\n    CTRY_ALBANIA            = 355,\n    CTRY_FINLAND            = 358,\n    CTRY_BULGARIA           = 359,\n    CTRY_LITHUANIA          = 370,\n    CTRY_LATVIA             = 371,\n    CTRY_ESTONIA            = 372,\n    CTRY_ARMENIA            = 374,\n    CTRY_BELARUS            = 375,\n    CTRY_UKRAINE            = 380,\n    CTRY_SERBIA             = 381,\n    CTRY_CROATIA            = 385,\n    CTRY_SLOVENIA           = 386,\n    CTRY_MACEDONIA          = 389,\n    CTRY_CZECH              = 420,\n    CTRY_SLOVAK             = 421,\n    CTRY_BELIZE             = 501,\n    CTRY_GUATEMALA          = 502,\n    CTRY_EL_SALVADOR        = 503,\n    CTRY_HONDURAS           = 504,\n    CTRY_NICARAGUA          = 505,\n    CTRY_COSTA_RICA         = 506,\n    CTRY_PANAMA             = 507,\n    CTRY_BOLIVIA            = 591,\n    CTRY_ECUADOR            = 593,\n    CTRY_PARAGUAY           = 595,\n    CTRY_URUGUAY            = 598,\n    CTRY_BRUNEI_DARUSSALAM  = 673,\n    CTRY_HONG_KONG          = 852,\n    CTRY_MACAU              = 853,\n    CTRY_TAIWAN             = 886,\n    CTRY_MALDIVES           = 960,\n    CTRY_LEBANON            = 961,\n    CTRY_JORDAN             = 962,\n    CTRY_SYRIA              = 963,\n    CTRY_IRAQ               = 964,\n    CTRY_KUWAIT             = 965,\n    CTRY_SAUDI_ARABIA       = 966,\n    CTRY_YEMEN              = 967,\n    CTRY_OMAN               = 968,\n    CTRY_UAE                = 971,\n    CTRY_ISRAEL             = 972,\n    CTRY_BAHRAIN            = 973,\n    CTRY_QATAR              = 974,\n    CTRY_MONGOLIA           = 976,\n    CTRY_IRAN               = 981,\n    CTRY_AZERBAIJAN         = 994,\n    CTRY_GEORGIA            = 995,\n    CTRY_KYRGYZSTAN         = 996\n}\n\nenum : CALTYPE {\n    CAL_ICALINTVALUE          = 1,\n    CAL_SCALNAME,\n    CAL_IYEAROFFSETRANGE,\n    CAL_SERASTRING,\n    CAL_SSHORTDATE,\n    CAL_SLONGDATE,\n    CAL_SDAYNAME1,\n    CAL_SDAYNAME2,\n    CAL_SDAYNAME3,\n    CAL_SDAYNAME4,\n    CAL_SDAYNAME5,\n    CAL_SDAYNAME6,\n    CAL_SDAYNAME7,\n    CAL_SABBREVDAYNAME1,\n    CAL_SABBREVDAYNAME2,\n    CAL_SABBREVDAYNAME3,\n    CAL_SABBREVDAYNAME4,\n    CAL_SABBREVDAYNAME5,\n    CAL_SABBREVDAYNAME6,\n    CAL_SABBREVDAYNAME7,\n    CAL_SMONTHNAME1,\n    CAL_SMONTHNAME2,\n    CAL_SMONTHNAME3,\n    CAL_SMONTHNAME4,\n    CAL_SMONTHNAME5,\n    CAL_SMONTHNAME6,\n    CAL_SMONTHNAME7,\n    CAL_SMONTHNAME8,\n    CAL_SMONTHNAME9,\n    CAL_SMONTHNAME10,\n    CAL_SMONTHNAME11,\n    CAL_SMONTHNAME12,\n    CAL_SMONTHNAME13,\n    CAL_SABBREVMONTHNAME1,\n    CAL_SABBREVMONTHNAME2,\n    CAL_SABBREVMONTHNAME3,\n    CAL_SABBREVMONTHNAME4,\n    CAL_SABBREVMONTHNAME5,\n    CAL_SABBREVMONTHNAME6,\n    CAL_SABBREVMONTHNAME7,\n    CAL_SABBREVMONTHNAME8,\n    CAL_SABBREVMONTHNAME9,\n    CAL_SABBREVMONTHNAME10,\n    CAL_SABBREVMONTHNAME11,\n    CAL_SABBREVMONTHNAME12,\n    CAL_SABBREVMONTHNAME13 // = 46\n}\n\n\nenum : CALTYPE {\n    CAL_GREGORIAN                =  1,\n    CAL_GREGORIAN_US,\n    CAL_JAPAN,\n    CAL_TAIWAN,\n    CAL_KOREA,\n    CAL_HIJRI,\n    CAL_THAI,\n    CAL_HEBREW,\n    CAL_GREGORIAN_ME_FRENCH,\n    CAL_GREGORIAN_ARABIC,\n    CAL_GREGORIAN_XLIT_ENGLISH,\n    CAL_GREGORIAN_XLIT_FRENCH // = 12\n}\n\nenum : int {\n    CSTR_LESS_THAN    = 1,\n    CSTR_EQUAL,\n    CSTR_GREATER_THAN\n}\n\nenum : DWORD {\n    LGRPID_INSTALLED = 1,\n    LGRPID_SUPPORTED\n}\n\nenum : LGRPID {\n    LGRPID_WESTERN_EUROPE = 1,\n    LGRPID_CENTRAL_EUROPE,\n    LGRPID_BALTIC,\n    LGRPID_GREEK,\n    LGRPID_CYRILLIC,\n    LGRPID_TURKISH,\n    LGRPID_JAPANESE,\n    LGRPID_KOREAN,\n    LGRPID_TRADITIONAL_CHINESE,\n    LGRPID_SIMPLIFIED_CHINESE,\n    LGRPID_THAI,\n    LGRPID_HEBREW,\n    LGRPID_ARABIC,\n    LGRPID_VIETNAMESE,\n    LGRPID_INDIC,\n    LGRPID_GEORGIAN,\n    LGRPID_ARMENIAN // = 17\n}\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    enum : LCTYPE {\n        LOCALE_SYEARMONTH             = 0x1006,\n        LOCALE_SENGCURRNAME           = 0x1007,\n        LOCALE_SNATIVECURRNAME        = 0x1008,\n        LOCALE_IDEFAULTEBCDICCODEPAGE = 0x1012,\n        LOCALE_SSORTNAME              = 0x1013,\n        LOCALE_IDIGITSUBSTITUTION     = 0x1014,\n        LOCALE_IPAPERSIZE             = 0x100A\n    }\n\nenum DWORD\n        DATE_YEARMONTH  =  8,\n        DATE_LTRREADING = 16,\n        DATE_RTLREADING = 32;\n\nenum DWORD MAP_EXPAND_LIGATURES = 0x2000;\nenum DWORD WC_NO_BEST_FIT_CHARS = 1024;\n\n    enum : CALTYPE {\n        CAL_SYEARMONTH       = 47,\n        CAL_ITWODIGITYEARMAX = 48,\n        CAL_NOUSEROVERRIDE   = LOCALE_NOUSEROVERRIDE,\n        CAL_RETURN_NUMBER    = LOCALE_RETURN_NUMBER,\n        CAL_USE_CP_ACP       = LOCALE_USE_CP_ACP\n    }\n} // (_WIN32_WINNT >= 0x500)\n\nextern (Windows) {\n    alias BOOL function(LPSTR) CALINFO_ENUMPROCA;\n    alias BOOL function(LPWSTR) CALINFO_ENUMPROCW;\n    alias BOOL function(LPSTR, CALID) CALINFO_ENUMPROCEXA;\n    alias BOOL function(LPWSTR, CALID) CALINFO_ENUMPROCEXW;\n    alias BOOL function(LGRPID, LPSTR, LPSTR, DWORD, LONG_PTR)\n      LANGUAGEGROUP_ENUMPROCA;\n    alias BOOL function(LGRPID, LPWSTR, LPWSTR, DWORD, LONG_PTR)\n      LANGUAGEGROUP_ENUMPROCW;\n    alias BOOL function(LGRPID, LCID, LPSTR, LONG_PTR)\n      LANGGROUPLOCALE_ENUMPROCA;\n    alias BOOL function(LGRPID, LCID, LPWSTR, LONG_PTR)\n      LANGGROUPLOCALE_ENUMPROCW;\n    alias BOOL function(LPWSTR, LONG_PTR) UILANGUAGE_ENUMPROCW;\n    alias BOOL function(LPSTR, LONG_PTR) UILANGUAGE_ENUMPROCA;\n    alias BOOL function(LPSTR) LOCALE_ENUMPROCA;\n    alias BOOL function(LPWSTR) LOCALE_ENUMPROCW;\n    alias BOOL function(LPSTR) CODEPAGE_ENUMPROCA;\n    alias BOOL function(LPWSTR) CODEPAGE_ENUMPROCW;\n    alias BOOL function(LPSTR) DATEFMT_ENUMPROCA;\n    alias BOOL function(LPWSTR) DATEFMT_ENUMPROCW;\n    alias BOOL function(LPSTR, CALID) DATEFMT_ENUMPROCEXA;\n    alias BOOL function(LPWSTR, CALID) DATEFMT_ENUMPROCEXW;\n    alias BOOL function(LPSTR) TIMEFMT_ENUMPROCA;\n    alias BOOL function(LPWSTR) TIMEFMT_ENUMPROCW;\n    alias BOOL function(GEOID) GEO_ENUMPROC;\n}\n\nenum NLS_FUNCTION {\n    COMPARE_STRING = 0x0001\n}\n\nenum SYSGEOCLASS {\n    GEOCLASS_NATION = 16,\n    GEOCLASS_REGION = 14\n}\n\nenum SYSGEOTYPE {\n    GEO_NATION            = 0x0001,\n    GEO_LATITUDE          = 0x0002,\n    GEO_LONGITUDE         = 0x0003,\n    GEO_ISO2              = 0x0004,\n    GEO_ISO3              = 0x0005,\n    GEO_RFC1766           = 0x0006,\n    GEO_LCID              = 0x0007,\n    GEO_FRIENDLYNAME      = 0x0008,\n    GEO_OFFICIALNAME      = 0x0009,\n    GEO_TIMEZONES         = 0x000a,\n    GEO_OFFICIALLANGUAGES = 0x000a\n}\n\nstruct CPINFO {\n    UINT                  MaxCharSize;\n    BYTE[MAX_DEFAULTCHAR] DefaultChar;\n    BYTE[MAX_LEADBYTES]   LeadByte;\n}\nalias CPINFO* LPCPINFO;\n\nstruct CPINFOEXA {\n    UINT                  MaxCharSize;\n    BYTE[MAX_DEFAULTCHAR] DefaultChar;\n    BYTE[MAX_LEADBYTES]   LeadByte;\n    WCHAR                 UnicodeDefaultChar;\n    UINT                  CodePage;\n    CHAR[MAX_PATH]        CodePageName;\n}\nalias CPINFOEXA* LPCPINFOEXA;\n\nstruct CPINFOEXW {\n    UINT                  MaxCharSize;\n    BYTE[MAX_DEFAULTCHAR] DefaultChar;\n    BYTE[MAX_LEADBYTES]   LeadByte;\n    WCHAR                 UnicodeDefaultChar;\n    UINT                  CodePage;\n    WCHAR[MAX_PATH]       CodePageName;\n}\nalias CPINFOEXW* LPCPINFOEXW;\n\nstruct CURRENCYFMTA {\n    UINT  NumDigits;\n    UINT  LeadingZero;\n    UINT  Grouping;\n    LPSTR lpDecimalSep;\n    LPSTR lpThousandSep;\n    UINT  NegativeOrder;\n    UINT  PositiveOrder;\n    LPSTR lpCurrencySymbol;\n}\nalias CURRENCYFMTA* LPCURRENCYFMTA;\n\nstruct CURRENCYFMTW {\n    UINT   NumDigits;\n    UINT   LeadingZero;\n    UINT   Grouping;\n    LPWSTR lpDecimalSep;\n    LPWSTR lpThousandSep;\n    UINT   NegativeOrder;\n    UINT   PositiveOrder;\n    LPWSTR lpCurrencySymbol;\n}\nalias CURRENCYFMTW* LPCURRENCYFMTW;\n\nstruct NLSVERSIONINFO {\n    DWORD dwNLSVersionInfoSize;\n    DWORD dwNLSVersion;\n    DWORD dwDefinedVersion;\n}\nalias NLSVERSIONINFO* LPNLSVERSIONINFO;\n\nstruct NUMBERFMTA {\n    UINT  NumDigits;\n    UINT  LeadingZero;\n    UINT  Grouping;\n    LPSTR lpDecimalSep;\n    LPSTR lpThousandSep;\n    UINT  NegativeOrder;\n}\nalias NUMBERFMTA* LPNUMBERFMTA;\n\nstruct NUMBERFMTW {\n    UINT   NumDigits;\n    UINT   LeadingZero;\n    UINT   Grouping;\n    LPWSTR lpDecimalSep;\n    LPWSTR lpThousandSep;\n    UINT   NegativeOrder;\n}\nalias NUMBERFMTW* LPNUMBERFMTW;\n\nextern (Windows) nothrow @nogc {\n    int CompareStringA(LCID, DWORD, LPCSTR, int, LPCSTR, int);\n    int CompareStringW(LCID, DWORD, LPCWSTR, int, LPCWSTR, int);\n    LCID ConvertDefaultLocale(LCID);\n    BOOL EnumCalendarInfoA(CALINFO_ENUMPROCA, LCID, CALID, CALTYPE);\n    BOOL EnumCalendarInfoW(CALINFO_ENUMPROCW, LCID, CALID, CALTYPE);\n    BOOL EnumDateFormatsA(DATEFMT_ENUMPROCA, LCID, DWORD);\n    BOOL EnumDateFormatsW(DATEFMT_ENUMPROCW, LCID, DWORD);\n    BOOL EnumSystemCodePagesA(CODEPAGE_ENUMPROCA, DWORD);\n    BOOL EnumSystemCodePagesW(CODEPAGE_ENUMPROCW, DWORD);\n    BOOL EnumSystemGeoID(GEOCLASS, GEOID, GEO_ENUMPROC);\n    BOOL EnumSystemLocalesA(LOCALE_ENUMPROCA, DWORD);\n    BOOL EnumSystemLocalesW(LOCALE_ENUMPROCW, DWORD);\n    BOOL EnumTimeFormatsA(TIMEFMT_ENUMPROCA, LCID, DWORD);\n    BOOL EnumTimeFormatsW(TIMEFMT_ENUMPROCW, LCID, DWORD);\n    int FoldStringA(DWORD, LPCSTR, int, LPSTR, int);\n    int FoldStringW(DWORD, LPCWSTR, int, LPWSTR, int);\n    UINT GetACP();\n    int GetCalendarInfoA(LCID, CALID, CALTYPE, LPSTR, int, LPDWORD);\n    int GetCalendarInfoW(LCID, CALID, CALTYPE, LPWSTR, int, LPDWORD);\n    BOOL GetCPInfo(UINT, LPCPINFO);\n    BOOL GetCPInfoExA(UINT, DWORD, LPCPINFOEXA);\n    BOOL GetCPInfoExW(UINT, DWORD, LPCPINFOEXW);\n    int GetCurrencyFormatA(LCID, DWORD, LPCSTR,  const(CURRENCYFMTA)*, LPSTR, int);\n    int GetCurrencyFormatW(LCID, DWORD, LPCWSTR,  const(CURRENCYFMTW)*, LPWSTR,\n      int);\n    int GetDateFormatA(LCID, DWORD,  const(SYSTEMTIME)*, LPCSTR, LPSTR, int);\n    int GetDateFormatW(LCID, DWORD,  const(SYSTEMTIME)*, LPCWSTR, LPWSTR, int);\n    int GetGeoInfoA(GEOID, GEOTYPE, LPSTR, int, LANGID);\n    int GetGeoInfoW(GEOID, GEOTYPE, LPWSTR, int, LANGID);\n    int GetLocaleInfoA(LCID, LCTYPE, LPSTR, int);\n    int GetLocaleInfoW(LCID, LCTYPE, LPWSTR, int);\n    BOOL GetNLSVersion(NLS_FUNCTION, LCID, LPNLSVERSIONINFO);\n    int GetNumberFormatA(LCID, DWORD, LPCSTR,  const(NUMBERFMTA)*, LPSTR, int);\n    int GetNumberFormatW(LCID, DWORD, LPCWSTR,  const(NUMBERFMTW)*, LPWSTR, int);\n    UINT GetOEMCP();\n    BOOL GetStringTypeA(LCID, DWORD, LPCSTR, int, LPWORD);\n    BOOL GetStringTypeW(DWORD, LPCWSTR, int, LPWORD);\n    BOOL GetStringTypeExA(LCID, DWORD, LPCSTR, int, LPWORD);\n    BOOL GetStringTypeExW(LCID, DWORD, LPCWSTR, int, LPWORD);\n    LANGID GetSystemDefaultLangID();\n    LCID GetSystemDefaultLCID();\n    LCID GetThreadLocale();\n    int GetTimeFormatA(LCID, DWORD,  const(SYSTEMTIME)*, LPCSTR, LPSTR, int);\n    int GetTimeFormatW(LCID, DWORD,  const(SYSTEMTIME)*, LPCWSTR, LPWSTR, int);\n    LANGID GetUserDefaultLangID();\n    LCID GetUserDefaultLCID();\n    GEOID GetUserGeoID(GEOCLASS);\n    BOOL IsDBCSLeadByte(BYTE);\n    BOOL IsDBCSLeadByteEx(UINT, BYTE);\n    BOOL IsNLSDefinedString(NLS_FUNCTION, DWORD, LPNLSVERSIONINFO, LPCWSTR,\n      int);\n    BOOL IsValidCodePage(UINT);\n    BOOL IsValidLocale(LCID, DWORD);\n    int LCMapStringA(LCID, DWORD, LPCSTR, int, LPSTR, int);\n    int LCMapStringW(LCID, DWORD, LPCWSTR, int, LPWSTR, int);\n    int MultiByteToWideChar(UINT, DWORD, LPCSTR, int, LPWSTR, int);\n    int SetCalendarInfoA(LCID, CALID, CALTYPE, LPCSTR);\n    int SetCalendarInfoW(LCID, CALID, CALTYPE, LPCWSTR);\n    BOOL SetLocaleInfoA(LCID, LCTYPE, LPCSTR);\n    BOOL SetLocaleInfoW(LCID, LCTYPE, LPCWSTR);\n    BOOL SetThreadLocale(LCID);\n    BOOL SetUserGeoID(GEOID);\n    int WideCharToMultiByte(UINT, DWORD, LPCWSTR, int, LPSTR, int, LPCSTR,\n      LPBOOL);\n\n    static if (_WIN32_WINNT >= 0x410) {\n        BOOL EnumCalendarInfoExA(CALINFO_ENUMPROCEXA, LCID, CALID, CALTYPE);\n        BOOL EnumCalendarInfoExW(CALINFO_ENUMPROCEXW, LCID, CALID, CALTYPE);\n        BOOL EnumDateFormatsExA(DATEFMT_ENUMPROCEXA, LCID, DWORD);\n        BOOL EnumDateFormatsExW(DATEFMT_ENUMPROCEXW, LCID, DWORD);\n        BOOL IsValidLanguageGroup(LGRPID, DWORD);\n    }\n\n    static if (_WIN32_WINNT >= 0x500) {\n        LANGID GetSystemDefaultUILanguage();\n        LANGID GetUserDefaultUILanguage();\n\n        BOOL EnumSystemLanguageGroupsA(LANGUAGEGROUP_ENUMPROCA, DWORD,\n          LONG_PTR);\n        BOOL EnumSystemLanguageGroupsW(LANGUAGEGROUP_ENUMPROCW, DWORD,\n          LONG_PTR);\n        BOOL EnumLanguageGroupLocalesA(LANGGROUPLOCALE_ENUMPROCA, LGRPID,\n          DWORD, LONG_PTR);\n        BOOL EnumLanguageGroupLocalesW(LANGGROUPLOCALE_ENUMPROCW, LGRPID,\n          DWORD, LONG_PTR);\n        BOOL EnumUILanguagesA(UILANGUAGE_ENUMPROCA, DWORD, LONG_PTR);\n        BOOL EnumUILanguagesW(UILANGUAGE_ENUMPROCW, DWORD, LONG_PTR);\n    }\n}\n\nversion (Unicode) {\n    alias CALINFO_ENUMPROCW CALINFO_ENUMPROC;\n    alias CALINFO_ENUMPROCEXW CALINFO_ENUMPROCEX;\n    alias LOCALE_ENUMPROCW LOCALE_ENUMPROC;\n    alias CODEPAGE_ENUMPROCW CODEPAGE_ENUMPROC;\n    alias DATEFMT_ENUMPROCW DATEFMT_ENUMPROC;\n    alias DATEFMT_ENUMPROCEXW DATEFMT_ENUMPROCEX;\n    alias TIMEFMT_ENUMPROCW TIMEFMT_ENUMPROC;\n    alias LANGUAGEGROUP_ENUMPROCW LANGUAGEGROUP_ENUMPROC;\n    alias LANGGROUPLOCALE_ENUMPROCW LANGGROUPLOCALE_ENUMPROC;\n    alias UILANGUAGE_ENUMPROCW UILANGUAGE_ENUMPROC;\n    alias CPINFOEXW CPINFOEX;\n    alias LPCPINFOEXW LPCPINFOEX;\n    alias CURRENCYFMTW CURRENCYFMT;\n    alias LPCURRENCYFMTW LPCURRENCYFMT;\n    alias NUMBERFMTW NUMBERFMT;\n    alias LPNUMBERFMTW LPNUMBERFMT;\n    alias CompareStringW CompareString;\n    alias EnumCalendarInfoW EnumCalendarInfo;\n    alias EnumSystemCodePagesW EnumSystemCodePages;\n    alias EnumSystemLocalesW EnumSystemLocales;\n    alias EnumTimeFormatsW EnumTimeFormats;\n    alias FoldStringW FoldString;\n    alias GetCalendarInfoW GetCalendarInfo;\n    alias GetCPInfoExW GetCPInfoEx;\n    alias GetCurrencyFormatW GetCurrencyFormat;\n    alias GetDateFormatW GetDateFormat;\n    alias GetGeoInfoW GetGeoInfo;\n    alias GetLocaleInfoW GetLocaleInfo;\n    alias GetNumberFormatW GetNumberFormat;\n    alias GetStringTypeExW GetStringTypeEx;\n    alias GetTimeFormatW GetTimeFormat;\n    alias LCMapStringW LCMapString;\n    alias SetCalendarInfoW SetCalendarInfo;\n    alias SetLocaleInfoW SetLocaleInfo;\n\n    static if (_WIN32_WINNT >= 0x410) {\n        alias EnumCalendarInfoExW EnumCalendarInfoEx;\n        alias EnumDateFormatsExW EnumDateFormatsEx;\n    }\n\n    static if (_WIN32_WINNT >= 0x500) {\n        alias EnumSystemLanguageGroupsW EnumSystemLanguageGroups;\n        alias EnumLanguageGroupLocalesW EnumLanguageGroupLocales;\n        alias EnumUILanguagesW EnumUILanguages;\n    }\n\n} else {\n    alias CALINFO_ENUMPROCA CALINFO_ENUMPROC;\n    alias CALINFO_ENUMPROCEXA CALINFO_ENUMPROCEX;\n    alias LOCALE_ENUMPROCA LOCALE_ENUMPROC;\n    alias CODEPAGE_ENUMPROCA CODEPAGE_ENUMPROC;\n    alias DATEFMT_ENUMPROCA DATEFMT_ENUMPROC;\n    alias DATEFMT_ENUMPROCEXA DATEFMT_ENUMPROCEX;\n    alias TIMEFMT_ENUMPROCA TIMEFMT_ENUMPROC;\n    alias LANGUAGEGROUP_ENUMPROCA LANGUAGEGROUP_ENUMPROC;\n    alias LANGGROUPLOCALE_ENUMPROCA LANGGROUPLOCALE_ENUMPROC;\n    alias UILANGUAGE_ENUMPROCA UILANGUAGE_ENUMPROC;\n    alias CPINFOEXA CPINFOEX;\n    alias LPCPINFOEXA LPCPINFOEX;\n    alias CURRENCYFMTA CURRENCYFMT;\n    alias LPCURRENCYFMTA LPCURRENCYFMT;\n    alias NUMBERFMTA NUMBERFMT;\n    alias LPNUMBERFMTA LPNUMBERFMT;\n    alias CompareStringA CompareString;\n    alias EnumCalendarInfoA EnumCalendarInfo;\n    alias EnumSystemCodePagesA EnumSystemCodePages;\n    alias EnumSystemLocalesA EnumSystemLocales;\n    alias EnumTimeFormatsA EnumTimeFormats;\n    alias FoldStringA FoldString;\n    alias GetCalendarInfoA GetCalendarInfo;\n    alias GetCPInfoExA GetCPInfoEx;\n    alias GetCurrencyFormatA GetCurrencyFormat;\n    alias GetDateFormatA GetDateFormat;\n    alias GetGeoInfoA GetGeoInfo;\n    alias GetLocaleInfoA GetLocaleInfo;\n    alias GetNumberFormatA GetNumberFormat;\n    alias GetStringTypeExA GetStringTypeEx;\n    alias GetTimeFormatA GetTimeFormat;\n    alias LCMapStringA LCMapString;\n    alias SetCalendarInfoA SetCalendarInfo;\n    alias SetLocaleInfoA SetLocaleInfo;\n\n    static if (_WIN32_WINNT >= 0x410) {\n        alias EnumCalendarInfoExA EnumCalendarInfoEx;\n        alias EnumDateFormatsExA EnumDateFormatsEx;\n    }\n\n    static if (_WIN32_WINNT >= 0x500) {\n        alias EnumSystemLanguageGroupsA EnumSystemLanguageGroups;\n        alias EnumLanguageGroupLocalesA EnumLanguageGroupLocales;\n        alias EnumUILanguagesA EnumUILanguages;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winnt.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW API for MS-Windows 3.12\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winnt.d)\n */\nmodule core.sys.windows.winnt;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\n\npublic import core.sys.windows.basetsd, core.sys.windows.windef, core.sys.windows.winerror;\nprivate import core.sys.windows.w32api;\n\n/* Translation Notes:\nThe following macros are unneeded for D:\nFIELD_OFFSET(t,f), CONTAINING_RECORD(address, type, field)\n*/\n\nalias void   VOID;\nalias char   CHAR, CCHAR;\nalias wchar  WCHAR;\nalias bool   BOOLEAN;\nalias byte   FCHAR;\nalias ubyte  UCHAR;\nalias short  SHORT;\nalias ushort LANGID, FSHORT;\nalias uint   LCID, FLONG, ACCESS_MASK;\nalias long   LONGLONG, USN;\nalias ulong  DWORDLONG, ULONGLONG;\n\nalias void*  PVOID, LPVOID;\nalias char*  PSZ, PCHAR, PCCHAR, LPCH, PCH, LPSTR, PSTR;\nalias wchar* PWCHAR, LPWCH, PWCH, LPWSTR, PWSTR;\nalias bool*  PBOOLEAN;\nalias ubyte* PUCHAR;\nalias short* PSHORT;\nalias int*   PLONG;\nalias uint*  PLCID, PACCESS_MASK;\nalias long*  PLONGLONG;\nalias ulong* PDWORDLONG, PULONGLONG;\n\n// FIXME(MinGW) for __WIN64\nalias void*  PVOID64;\n\n// const versions\nalias const(char)*  PCCH, LPCCH, PCSTR, LPCSTR;\nalias const(wchar)* LPCWCH, PCWCH, LPCWSTR, PCWSTR;\n\nversion (Unicode) {\n    alias WCHAR TCHAR, _TCHAR;\n} else {\n    alias CHAR TCHAR, _TCHAR;\n}\n\nalias TCHAR         TBYTE;\nalias TCHAR*        PTCH , PTBYTE, LPTCH , PTSTR , LPTSTR , LP, PTCHAR;\nalias const(TCHAR)* PCTCH,         LPCTCH, PCTSTR, LPCTSTR            ;\n\nenum char ANSI_NULL = '\\0';\nenum wchar UNICODE_NULL = '\\0';\n\nenum APPLICATION_ERROR_MASK       = 0x20000000;\nenum ERROR_SEVERITY_SUCCESS       = 0x00000000;\nenum ERROR_SEVERITY_INFORMATIONAL = 0x40000000;\nenum ERROR_SEVERITY_WARNING       = 0x80000000;\nenum ERROR_SEVERITY_ERROR         = 0xC0000000;\n\n// MinGW: also in ddk/ntifs.h\nenum : USHORT {\n    COMPRESSION_FORMAT_NONE     = 0x0000,\n    COMPRESSION_FORMAT_DEFAULT  = 0x0001,\n    COMPRESSION_FORMAT_LZNT1    = 0x0002,\n    COMPRESSION_ENGINE_STANDARD = 0x0000,\n    COMPRESSION_ENGINE_MAXIMUM  = 0x0100,\n    COMPRESSION_ENGINE_HIBER    = 0x0200\n}\n\n// ACCESS_DENIED_OBJECT_ACE, etc\nenum DWORD\n    ACE_OBJECT_TYPE_PRESENT           = 0x00000001,\n    ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x00000002;\n\n// ACE_HEADER.AceType\n// also in ddk/ntifs.h\nenum : BYTE {\n    ACCESS_ALLOWED_ACE_TYPE,\n    ACCESS_DENIED_ACE_TYPE,\n    SYSTEM_AUDIT_ACE_TYPE,\n    SYSTEM_ALARM_ACE_TYPE\n}\n\n// ACE_HEADER.AceFlags\nenum BYTE\n    OBJECT_INHERIT_ACE         = 0x01,\n    CONTAINER_INHERIT_ACE      = 0x02,\n    NO_PROPAGATE_INHERIT_ACE   = 0x04,\n    INHERIT_ONLY_ACE           = 0x08,\n    INHERITED_ACE              = 0x10,\n    VALID_INHERIT_FLAGS        = 0x1F,\n    SUCCESSFUL_ACCESS_ACE_FLAG = 0x40,\n    FAILED_ACCESS_ACE_FLAG     = 0x80;\n\n// Access Mask Format\nenum ACCESS_MASK\n    DELETE                   = 0x00010000,\n    READ_CONTROL             = 0x00020000,\n    WRITE_DAC                = 0x00040000,\n    WRITE_OWNER              = 0x00080000,\n    SYNCHRONIZE              = 0x00100000,\n    ACCESS_SYSTEM_SECURITY   = 0x01000000,\n    MAXIMUM_ALLOWED          = 0x02000000,\n    GENERIC_READ             = 0x80000000,\n    GENERIC_WRITE            = 0x40000000,\n    GENERIC_EXECUTE          = 0x20000000,\n    GENERIC_ALL              = 0x10000000,\n    STANDARD_RIGHTS_REQUIRED = 0x000F0000,\n    STANDARD_RIGHTS_READ     = 0x00020000,\n    STANDARD_RIGHTS_WRITE    = 0x00020000,\n    STANDARD_RIGHTS_EXECUTE  = 0x00020000,\n    STANDARD_RIGHTS_ALL      = 0x001F0000,\n    SPECIFIC_RIGHTS_ALL      = 0x0000FFFF;\n\n\nenum DWORD INVALID_FILE_ATTRIBUTES = -1;\n\n// MinGW: Also in ddk/winddk.h\nenum DWORD\n    FILE_LIST_DIRECTORY       = 0x00000001,\n    FILE_READ_DATA            = 0x00000001,\n    FILE_ADD_FILE             = 0x00000002,\n    FILE_WRITE_DATA           = 0x00000002,\n    FILE_ADD_SUBDIRECTORY     = 0x00000004,\n    FILE_APPEND_DATA          = 0x00000004,\n    FILE_CREATE_PIPE_INSTANCE = 0x00000004,\n    FILE_READ_EA              = 0x00000008,\n    FILE_READ_PROPERTIES      = 0x00000008,\n    FILE_WRITE_EA             = 0x00000010,\n    FILE_WRITE_PROPERTIES     = 0x00000010,\n    FILE_EXECUTE              = 0x00000020,\n    FILE_TRAVERSE             = 0x00000020,\n    FILE_DELETE_CHILD         = 0x00000040,\n    FILE_READ_ATTRIBUTES      = 0x00000080,\n    FILE_WRITE_ATTRIBUTES     = 0x00000100;\n\nenum DWORD\n    FILE_SHARE_READ        = 0x00000001,\n    FILE_SHARE_WRITE       = 0x00000002,\n    FILE_SHARE_DELETE      = 0x00000004,\n    FILE_SHARE_VALID_FLAGS = 0x00000007;\n\nenum DWORD\n    FILE_ATTRIBUTE_READONLY            = 0x00000001,\n    FILE_ATTRIBUTE_HIDDEN              = 0x00000002,\n    FILE_ATTRIBUTE_SYSTEM              = 0x00000004,\n    FILE_ATTRIBUTE_DIRECTORY           = 0x00000010,\n    FILE_ATTRIBUTE_ARCHIVE             = 0x00000020,\n    FILE_ATTRIBUTE_DEVICE              = 0x00000040,\n    FILE_ATTRIBUTE_NORMAL              = 0x00000080,\n    FILE_ATTRIBUTE_TEMPORARY           = 0x00000100,\n    FILE_ATTRIBUTE_SPARSE_FILE         = 0x00000200,\n    FILE_ATTRIBUTE_REPARSE_POINT       = 0x00000400,\n    FILE_ATTRIBUTE_COMPRESSED          = 0x00000800,\n    FILE_ATTRIBUTE_OFFLINE             = 0x00001000,\n    FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,\n    FILE_ATTRIBUTE_ENCRYPTED           = 0x00004000,\n    FILE_ATTRIBUTE_VALID_FLAGS         = 0x00007fb7,\n    FILE_ATTRIBUTE_VALID_SET_FLAGS     = 0x000031a7;\n\n// These are not documented on MSDN\nenum FILE_COPY_STRUCTURED_STORAGE = 0x00000041;\nenum FILE_STRUCTURED_STORAGE      = 0x00000441;\n\n// Nor are these\nenum FILE_VALID_OPTION_FLAGS          = 0x00ffffff;\nenum FILE_VALID_PIPE_OPTION_FLAGS     = 0x00000032;\nenum FILE_VALID_MAILSLOT_OPTION_FLAGS = 0x00000032;\nenum FILE_VALID_SET_FLAGS             = 0x00000036;\n\nenum ULONG\n    FILE_SUPERSEDE           = 0x00000000,\n    FILE_OPEN                = 0x00000001,\n    FILE_CREATE              = 0x00000002,\n    FILE_OPEN_IF             = 0x00000003,\n    FILE_OVERWRITE           = 0x00000004,\n    FILE_OVERWRITE_IF        = 0x00000005,\n    FILE_MAXIMUM_DISPOSITION = 0x00000005;\n\nenum ULONG\n    FILE_DIRECTORY_FILE            = 0x00000001,\n    FILE_WRITE_THROUGH             = 0x00000002,\n    FILE_SEQUENTIAL_ONLY           = 0x00000004,\n    FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008,\n    FILE_SYNCHRONOUS_IO_ALERT      = 0x00000010,\n    FILE_SYNCHRONOUS_IO_NONALERT   = 0x00000020,\n    FILE_NON_DIRECTORY_FILE        = 0x00000040,\n    FILE_CREATE_TREE_CONNECTION    = 0x00000080,\n    FILE_COMPLETE_IF_OPLOCKED      = 0x00000100,\n    FILE_NO_EA_KNOWLEDGE           = 0x00000200,\n    FILE_OPEN_FOR_RECOVERY         = 0x00000400,\n    FILE_RANDOM_ACCESS             = 0x00000800,\n    FILE_DELETE_ON_CLOSE           = 0x00001000,\n    FILE_OPEN_BY_FILE_ID           = 0x00002000,\n    FILE_OPEN_FOR_BACKUP_INTENT    = 0x00004000,\n    FILE_NO_COMPRESSION            = 0x00008000,\n    FILE_RESERVE_OPFILTER          = 0x00100000,\n    FILE_OPEN_REPARSE_POINT        = 0x00200000,\n    FILE_OPEN_NO_RECALL            = 0x00400000,\n    FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000;\n\n\nenum ACCESS_MASK\n    FILE_ALL_ACCESS      = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x01FF,\n    FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES\n                           | FILE_EXECUTE | SYNCHRONIZE,\n    FILE_GENERIC_READ    = STANDARD_RIGHTS_READ | FILE_READ_DATA\n                           | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE,\n    FILE_GENERIC_WRITE   = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA\n                           | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA\n                           | SYNCHRONIZE;\n\n// MinGW: end winddk.h\n// MinGW: also in ddk/ntifs.h\nenum DWORD\n    FILE_NOTIFY_CHANGE_FILE_NAME    = 0x00000001,\n    FILE_NOTIFY_CHANGE_DIR_NAME     = 0x00000002,\n    FILE_NOTIFY_CHANGE_NAME         = 0x00000003,\n    FILE_NOTIFY_CHANGE_ATTRIBUTES   = 0x00000004,\n    FILE_NOTIFY_CHANGE_SIZE         = 0x00000008,\n    FILE_NOTIFY_CHANGE_LAST_WRITE   = 0x00000010,\n    FILE_NOTIFY_CHANGE_LAST_ACCESS  = 0x00000020,\n    FILE_NOTIFY_CHANGE_CREATION     = 0x00000040,\n    FILE_NOTIFY_CHANGE_EA           = 0x00000080,\n    FILE_NOTIFY_CHANGE_SECURITY     = 0x00000100,\n    FILE_NOTIFY_CHANGE_STREAM_NAME  = 0x00000200,\n    FILE_NOTIFY_CHANGE_STREAM_SIZE  = 0x00000400,\n    FILE_NOTIFY_CHANGE_STREAM_WRITE = 0x00000800,\n    FILE_NOTIFY_VALID_MASK          = 0x00000fff;\n\nenum DWORD\n    FILE_CASE_SENSITIVE_SEARCH      = 0x00000001,\n    FILE_CASE_PRESERVED_NAMES       = 0x00000002,\n    FILE_UNICODE_ON_DISK            = 0x00000004,\n    FILE_PERSISTENT_ACLS            = 0x00000008,\n    FILE_FILE_COMPRESSION           = 0x00000010,\n    FILE_VOLUME_QUOTAS              = 0x00000020,\n    FILE_SUPPORTS_SPARSE_FILES      = 0x00000040,\n    FILE_SUPPORTS_REPARSE_POINTS    = 0x00000080,\n    FILE_SUPPORTS_REMOTE_STORAGE    = 0x00000100,\n    FS_LFN_APIS                     = 0x00004000,\n    FILE_VOLUME_IS_COMPRESSED       = 0x00008000,\n    FILE_SUPPORTS_OBJECT_IDS        = 0x00010000,\n    FILE_SUPPORTS_ENCRYPTION        = 0x00020000,\n    FILE_NAMED_STREAMS              = 0x00040000,\n    FILE_READ_ONLY_VOLUME           = 0x00080000,\n    FILE_SEQUENTIAL_WRITE_ONCE      = 0x00100000,\n    FILE_SUPPORTS_TRANSACTIONS      = 0x00200000;\n\n// These are not documented on MSDN\nenum ACCESS_MASK\n    IO_COMPLETION_QUERY_STATE  = 1,\n    IO_COMPLETION_MODIFY_STATE = 2,\n    IO_COMPLETION_ALL_ACCESS   = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 3;\n// MinGW: end ntifs.h\n\n// MinGW: also in ddk/winddk.h\nenum DWORD\n    DUPLICATE_CLOSE_SOURCE    = 1,\n    DUPLICATE_SAME_ACCESS     = 2,\n    DUPLICATE_SAME_ATTRIBUTES = 4;\n// MinGW: end winddk.k\n\nenum DWORD\n    MAILSLOT_NO_MESSAGE   = -1,\n    MAILSLOT_WAIT_FOREVER = -1;\n\nenum ACCESS_MASK\n    PROCESS_TERMINATE         = 0x0001,\n    PROCESS_CREATE_THREAD     = 0x0002,\n    PROCESS_SET_SESSIONID     = 0x0004,\n    PROCESS_VM_OPERATION      = 0x0008,\n    PROCESS_VM_READ           = 0x0010,\n    PROCESS_VM_WRITE          = 0x0020,\n    PROCESS_DUP_HANDLE        = 0x0040,\n    PROCESS_CREATE_PROCESS    = 0x0080,\n    PROCESS_SET_QUOTA         = 0x0100,\n    PROCESS_SET_INFORMATION   = 0x0200,\n    PROCESS_QUERY_INFORMATION = 0x0400,\n    PROCESS_ALL_ACCESS        = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x0FFF;\n\nenum ACCESS_MASK\n    THREAD_TERMINATE            = 0x0001,\n    THREAD_SUSPEND_RESUME       = 0x0002,\n    THREAD_GET_CONTEXT          = 0x0008,\n    THREAD_SET_CONTEXT          = 0x0010,\n    THREAD_SET_INFORMATION      = 0x0020,\n    THREAD_QUERY_INFORMATION    = 0x0040,\n    THREAD_SET_THREAD_TOKEN     = 0x0080,\n    THREAD_IMPERSONATE          = 0x0100,\n    THREAD_DIRECT_IMPERSONATION = 0x0200,\n    THREAD_ALL_ACCESS           = STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3FF;\n\n// These are not documented on MSDN\nenum THREAD_BASE_PRIORITY_LOWRT =  15;\nenum THREAD_BASE_PRIORITY_MAX   =   2;\nenum THREAD_BASE_PRIORITY_MIN   =  -2;\nenum THREAD_BASE_PRIORITY_IDLE  = -15;\n\nenum DWORD EXCEPTION_NONCONTINUABLE      =  1;\nenum size_t EXCEPTION_MAXIMUM_PARAMETERS = 15;\n\n// These are not documented on MSDN\nenum ACCESS_MASK\n    MUTANT_QUERY_STATE = 1,\n    MUTANT_ALL_ACCESS =  STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | MUTANT_QUERY_STATE;\n\nenum ACCESS_MASK\n    TIMER_QUERY_STATE  = 1,\n    TIMER_MODIFY_STATE = 2,\n    TIMER_ALL_ACCESS   = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | TIMER_QUERY_STATE\n                         | TIMER_MODIFY_STATE;\n\nenum SID_IDENTIFIER_AUTHORITY\n    SECURITY_NULL_SID_AUTHORITY        = {[5: 0]},\n    SECURITY_WORLD_SID_AUTHORITY       = {[5: 1]},\n    SECURITY_LOCAL_SID_AUTHORITY       = {[5: 2]},\n    SECURITY_CREATOR_SID_AUTHORITY     = {[5: 3]},\n    SECURITY_NON_UNIQUE_AUTHORITY      = {[5: 4]},\n    SECURITY_NT_AUTHORITY              = {[5: 5]},\n    SECURITY_MANDATORY_LABEL_AUTHORITY = {[5: 6]};\n\nenum DWORD\n    SECURITY_NULL_RID                   =  0,\n    SECURITY_WORLD_RID                  =  0,\n    SECURITY_LOCAL_RID                  =  0,\n    SECURITY_CREATOR_OWNER_RID          =  0,\n    SECURITY_CREATOR_GROUP_RID          =  1,\n    SECURITY_DIALUP_RID                 =  1,\n    SECURITY_NETWORK_RID                =  2,\n    SECURITY_BATCH_RID                  =  3,\n    SECURITY_INTERACTIVE_RID            =  4,\n    SECURITY_LOGON_IDS_RID              =  5,\n    SECURITY_SERVICE_RID                =  6,\n    SECURITY_LOCAL_SYSTEM_RID           = 18,\n    SECURITY_BUILTIN_DOMAIN_RID         = 32,\n    SECURITY_PRINCIPAL_SELF_RID         = 10,\n    SECURITY_CREATOR_OWNER_SERVER_RID   =  2,\n    SECURITY_CREATOR_GROUP_SERVER_RID   =  3,\n    SECURITY_LOGON_IDS_RID_COUNT        =  3,\n    SECURITY_ANONYMOUS_LOGON_RID        =  7,\n    SECURITY_PROXY_RID                  =  8,\n    SECURITY_ENTERPRISE_CONTROLLERS_RID =  9,\n    SECURITY_SERVER_LOGON_RID           = SECURITY_ENTERPRISE_CONTROLLERS_RID,\n    SECURITY_AUTHENTICATED_USER_RID     = 11,\n    SECURITY_RESTRICTED_CODE_RID        = 12,\n    SECURITY_NT_NON_UNIQUE_RID          = 21,\n    SID_REVISION                        =  1;\n\nenum : DWORD {\n    DOMAIN_USER_RID_ADMIN        = 0x01F4,\n    DOMAIN_USER_RID_GUEST        = 0x01F5,\n    DOMAIN_GROUP_RID_ADMINS      = 0x0200,\n    DOMAIN_GROUP_RID_USERS       = 0x0201,\n    DOMAIN_ALIAS_RID_ADMINS      = 0x0220,\n    DOMAIN_ALIAS_RID_USERS       = 0x0221,\n    DOMAIN_ALIAS_RID_GUESTS      = 0x0222,\n    DOMAIN_ALIAS_RID_POWER_USERS = 0x0223,\n    DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x0224,\n    DOMAIN_ALIAS_RID_SYSTEM_OPS  = 0x0225,\n    DOMAIN_ALIAS_RID_PRINT_OPS   = 0x0226,\n    DOMAIN_ALIAS_RID_BACKUP_OPS  = 0x0227,\n    DOMAIN_ALIAS_RID_REPLICATOR  = 0x0228\n}\n\nenum : WORD {\n    SECURITY_MANDATORY_UNTRUSTED_RID         = 0,\n    SECURITY_MANDATORY_LOW_RID               = 0x1000,\n    SECURITY_MANDATORY_MEDIUM_RID            = 0x2000,\n    SECURITY_MANDATORY_HIGH_RID              = 0x3000,\n    SECURITY_MANDATORY_SYSTEM_RID            = 0x4000,\n    SECURITY_MANDATORY_PROTECTED_PROCESS_RID = 0x5000,\n    SECURITY_MANDATORY_MAXIMUM_USER_RID      = SECURITY_MANDATORY_SYSTEM_RID\n}\n\nconst TCHAR[]\n    SE_CREATE_TOKEN_NAME           = \"SeCreateTokenPrivilege\",\n    SE_ASSIGNPRIMARYTOKEN_NAME     = \"SeAssignPrimaryTokenPrivilege\",\n    SE_LOCK_MEMORY_NAME            = \"SeLockMemoryPrivilege\",\n    SE_INCREASE_QUOTA_NAME         = \"SeIncreaseQuotaPrivilege\",\n    SE_UNSOLICITED_INPUT_NAME      = \"SeUnsolicitedInputPrivilege\",\n    SE_MACHINE_ACCOUNT_NAME        = \"SeMachineAccountPrivilege\",\n    SE_TCB_NAME                    = \"SeTcbPrivilege\",\n    SE_SECURITY_NAME               = \"SeSecurityPrivilege\",\n    SE_TAKE_OWNERSHIP_NAME         = \"SeTakeOwnershipPrivilege\",\n    SE_LOAD_DRIVER_NAME            = \"SeLoadDriverPrivilege\",\n    SE_SYSTEM_PROFILE_NAME         = \"SeSystemProfilePrivilege\",\n    SE_SYSTEMTIME_NAME             = \"SeSystemtimePrivilege\",\n    SE_PROF_SINGLE_PROCESS_NAME    = \"SeProfileSingleProcessPrivilege\",\n    SE_INC_BASE_PRIORITY_NAME      = \"SeIncreaseBasePriorityPrivilege\",\n    SE_CREATE_PAGEFILE_NAME        = \"SeCreatePagefilePrivilege\",\n    SE_CREATE_PERMANENT_NAME       = \"SeCreatePermanentPrivilege\",\n    SE_BACKUP_NAME                 = \"SeBackupPrivilege\",\n    SE_RESTORE_NAME                = \"SeRestorePrivilege\",\n    SE_SHUTDOWN_NAME               = \"SeShutdownPrivilege\",\n    SE_DEBUG_NAME                  = \"SeDebugPrivilege\",\n    SE_AUDIT_NAME                  = \"SeAuditPrivilege\",\n    SE_SYSTEM_ENVIRONMENT_NAME     = \"SeSystemEnvironmentPrivilege\",\n    SE_CHANGE_NOTIFY_NAME          = \"SeChangeNotifyPrivilege\",\n    SE_REMOTE_SHUTDOWN_NAME        = \"SeRemoteShutdownPrivilege\",\n    SE_CREATE_GLOBAL_NAME          = \"SeCreateGlobalPrivilege\",\n    SE_UNDOCK_NAME                 = \"SeUndockPrivilege\",\n    SE_MANAGE_VOLUME_NAME          = \"SeManageVolumePrivilege\",\n    SE_IMPERSONATE_NAME            = \"SeImpersonatePrivilege\",\n    SE_ENABLE_DELEGATION_NAME      = \"SeEnableDelegationPrivilege\",\n    SE_SYNC_AGENT_NAME             = \"SeSyncAgentPrivilege\",\n    SE_TRUSTED_CREDMAN_ACCESS_NAME = \"SeTrustedCredManAccessPrivilege\",\n    SE_RELABEL_NAME                = \"SeRelabelPrivilege\",\n    SE_INCREASE_WORKING_SET_NAME   = \"SeIncreaseWorkingSetPrivilege\",\n    SE_TIME_ZONE_NAME              = \"SeTimeZonePrivilege\",\n    SE_CREATE_SYMBOLIC_LINK_NAME   = \"SeCreateSymbolicLinkPrivilege\";\n\nenum DWORD\n    SE_GROUP_MANDATORY          = 0x00000001,\n    SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002,\n    SE_GROUP_ENABLED            = 0x00000004,\n    SE_GROUP_OWNER              = 0x00000008,\n    SE_GROUP_USE_FOR_DENY_ONLY  = 0x00000010,\n    SE_GROUP_INTEGRITY          = 0x00000020,\n    SE_GROUP_INTEGRITY_ENABLED  = 0x00000040,\n    SE_GROUP_RESOURCE           = 0x20000000,\n    SE_GROUP_LOGON_ID           = 0xC0000000;\n\n// Primary language identifiers\nenum : USHORT {\n    LANG_NEUTRAL,\n    LANG_ARABIC,\n    LANG_BULGARIAN,\n    LANG_CATALAN,\n    LANG_CHINESE,\n    LANG_CZECH,\n    LANG_DANISH,\n    LANG_GERMAN,\n    LANG_GREEK,\n    LANG_ENGLISH,\n    LANG_SPANISH,\n    LANG_FINNISH,\n    LANG_FRENCH,\n    LANG_HEBREW,\n    LANG_HUNGARIAN,\n    LANG_ICELANDIC,\n    LANG_ITALIAN,\n    LANG_JAPANESE,\n    LANG_KOREAN,\n    LANG_DUTCH,\n    LANG_NORWEGIAN,\n    LANG_POLISH,\n    LANG_PORTUGUESE,    // = 0x16\n    LANG_ROMANIAN          = 0x18,\n    LANG_RUSSIAN,\n    LANG_CROATIAN,      // = 0x1A\n    LANG_SERBIAN           = 0x1A,\n    LANG_BOSNIAN           = 0x1A,\n    LANG_SLOVAK,\n    LANG_ALBANIAN,\n    LANG_SWEDISH,\n    LANG_THAI,\n    LANG_TURKISH,\n    LANG_URDU,\n    LANG_INDONESIAN,\n    LANG_UKRAINIAN,\n    LANG_BELARUSIAN,\n    LANG_SLOVENIAN,\n    LANG_ESTONIAN,\n    LANG_LATVIAN,\n    LANG_LITHUANIAN,    // = 0x27\n    LANG_FARSI             = 0x29,\n    LANG_PERSIAN           = 0x29,\n    LANG_VIETNAMESE,\n    LANG_ARMENIAN,\n    LANG_AZERI,\n    LANG_BASQUE,\n    LANG_LOWER_SORBIAN, // = 0x2E\n    LANG_UPPER_SORBIAN     = 0x2E,\n    LANG_MACEDONIAN,    // = 0x2F\n    LANG_TSWANA            = 0x32,\n    LANG_XHOSA             = 0x34,\n    LANG_ZULU,\n    LANG_AFRIKAANS,\n    LANG_GEORGIAN,\n    LANG_FAEROESE,\n    LANG_HINDI,\n    LANG_MALTESE,\n    LANG_SAMI,\n    LANG_IRISH,         // = 0x3C\n    LANG_MALAY             = 0x3E,\n    LANG_KAZAK,\n    LANG_KYRGYZ,\n    LANG_SWAHILI,       // = 0x41\n    LANG_UZBEK             = 0x43,\n    LANG_TATAR,\n    LANG_BENGALI,\n    LANG_PUNJABI,\n    LANG_GUJARATI,\n    LANG_ORIYA,\n    LANG_TAMIL,\n    LANG_TELUGU,\n    LANG_KANNADA,\n    LANG_MALAYALAM,\n    LANG_ASSAMESE,\n    LANG_MARATHI,\n    LANG_SANSKRIT,\n    LANG_MONGOLIAN,\n    LANG_TIBETAN,\n    LANG_WELSH,\n    LANG_KHMER,\n    LANG_LAO,           // = 0x54\n    LANG_GALICIAN          = 0x56,\n    LANG_KONKANI,\n    LANG_MANIPURI,\n    LANG_SINDHI,\n    LANG_SYRIAC,\n    LANG_SINHALESE,     // = 0x5B\n    LANG_INUKTITUT         = 0x5D,\n    LANG_AMHARIC,\n    LANG_TAMAZIGHT,\n    LANG_KASHMIRI,\n    LANG_NEPALI,\n    LANG_FRISIAN,\n    LANG_PASHTO,\n    LANG_FILIPINO,\n    LANG_DIVEHI,        // = 0x65\n    LANG_HAUSA             = 0x68,\n    LANG_YORUBA            = 0x6A,\n    LANG_QUECHUA,\n    LANG_SOTHO,\n    LANG_BASHKIR,\n    LANG_LUXEMBOURGISH,\n    LANG_GREENLANDIC,\n    LANG_IGBO,          // = 0x70\n    LANG_TIGRIGNA          = 0x73,\n    LANG_YI                = 0x78,\n    LANG_MAPUDUNGUN        = 0x7A,\n    LANG_MOHAWK            = 0x7C,\n    LANG_BRETON            = 0x7E,\n    LANG_UIGHUR            = 0x80,\n    LANG_MAORI,\n    LANG_OCCITAN,\n    LANG_CORSICAN,\n    LANG_ALSATIAN,\n    LANG_YAKUT,\n    LANG_KICHE,\n    LANG_KINYARWANDA,\n    LANG_WOLOF,         // = 0x88\n    LANG_DARI              = 0x8C,\n    LANG_MALAGASY,      // = 0x8D\n\n    LANG_SERBIAN_NEUTRAL   = 0x7C1A,\n    LANG_BOSNIAN_NEUTRAL   = 0x781A,\n\n    LANG_INVARIANT         = 0x7F\n}\n\n\n// Sublanguage identifiers\nenum : USHORT {\n    SUBLANG_NEUTRAL,\n    SUBLANG_DEFAULT,\n    SUBLANG_SYS_DEFAULT,\n    SUBLANG_CUSTOM_DEFAULT,                  // =  3\n    SUBLANG_UI_CUSTOM_DEFAULT                   =  3,\n    SUBLANG_CUSTOM_UNSPECIFIED,              // =  4\n\n    SUBLANG_AFRIKAANS_SOUTH_AFRICA              =  1,\n    SUBLANG_ALBANIAN_ALBANIA                    =  1,\n    SUBLANG_ALSATIAN_FRANCE                     =  1,\n    SUBLANG_AMHARIC_ETHIOPIA                    =  1,\n\n    SUBLANG_ARABIC_SAUDI_ARABIA                 =  1,\n    SUBLANG_ARABIC_IRAQ,\n    SUBLANG_ARABIC_EGYPT,\n    SUBLANG_ARABIC_LIBYA,\n    SUBLANG_ARABIC_ALGERIA,\n    SUBLANG_ARABIC_MOROCCO,\n    SUBLANG_ARABIC_TUNISIA,\n    SUBLANG_ARABIC_OMAN,\n    SUBLANG_ARABIC_YEMEN,\n    SUBLANG_ARABIC_SYRIA,\n    SUBLANG_ARABIC_JORDAN,\n    SUBLANG_ARABIC_LEBANON,\n    SUBLANG_ARABIC_KUWAIT,\n    SUBLANG_ARABIC_UAE,\n    SUBLANG_ARABIC_BAHRAIN,\n    SUBLANG_ARABIC_QATAR,                    // = 16\n\n    SUBLANG_ARMENIAN_ARMENIA                    =  1,\n    SUBLANG_ASSAMESE_INDIA                      =  1,\n\n    SUBLANG_AZERI_LATIN                         =  1,\n    SUBLANG_AZERI_CYRILLIC,                  // =  2\n\n    SUBLANG_BASHKIR_RUSSIA                      =  1,\n    SUBLANG_BASQUE_BASQUE                       =  1,\n    SUBLANG_BELARUSIAN_BELARUS                  =  1,\n    SUBLANG_BENGALI_INDIA                       =  1,\n\n    SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN    =  5,\n    SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC =  8,\n\n    SUBLANG_BRETON_FRANCE                       =  1,\n    SUBLANG_BULGARIAN_BULGARIA                  =  1,\n    SUBLANG_CATALAN_CATALAN                     =  1,\n\n    SUBLANG_CHINESE_TRADITIONAL                 =  1,\n    SUBLANG_CHINESE_SIMPLIFIED,\n    SUBLANG_CHINESE_HONGKONG,\n    SUBLANG_CHINESE_SINGAPORE,\n    SUBLANG_CHINESE_MACAU,                   // =  5\n\n    SUBLANG_CORSICAN_FRANCE                     =  1,\n\n    SUBLANG_CROATIAN_CROATIA                    =  1,\n    SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN   =  4,\n\n    SUBLANG_CZECH_CZECH_REPUBLIC                =  1,\n    SUBLANG_DANISH_DENMARK                      =  1,\n    SUBLANG_DIVEHI_MALDIVES                     =  1,\n\n    SUBLANG_DUTCH                               =  1,\n    SUBLANG_DUTCH_BELGIAN,                   // =  2\n\n    SUBLANG_ENGLISH_US                          =  1,\n    SUBLANG_ENGLISH_UK,\n    SUBLANG_ENGLISH_AUS,\n    SUBLANG_ENGLISH_CAN,\n    SUBLANG_ENGLISH_NZ,\n    SUBLANG_ENGLISH_EIRE,                    // =  6\n    SUBLANG_ENGLISH_IRELAND                     =  6,\n    SUBLANG_ENGLISH_SOUTH_AFRICA,\n    SUBLANG_ENGLISH_JAMAICA,\n    SUBLANG_ENGLISH_CARIBBEAN,\n    SUBLANG_ENGLISH_BELIZE,\n    SUBLANG_ENGLISH_TRINIDAD,\n    SUBLANG_ENGLISH_ZIMBABWE,\n    SUBLANG_ENGLISH_PHILIPPINES,             // = 13\n    SUBLANG_ENGLISH_INDIA                       = 16,\n    SUBLANG_ENGLISH_MALAYSIA,\n    SUBLANG_ENGLISH_SINGAPORE,               // = 18\n\n    SUBLANG_ESTONIAN_ESTONIA                    =  1,\n    SUBLANG_FAEROESE_FAROE_ISLANDS              =  1,\n    SUBLANG_FILIPINO_PHILIPPINES                =  1,\n    SUBLANG_FINNISH_FINLAND                     =  1,\n\n    SUBLANG_FRENCH                              =  1,\n    SUBLANG_FRENCH_BELGIAN,\n    SUBLANG_FRENCH_CANADIAN,\n    SUBLANG_FRENCH_SWISS,\n    SUBLANG_FRENCH_LUXEMBOURG,\n    SUBLANG_FRENCH_MONACO,                   // =  6\n\n    SUBLANG_FRISIAN_NETHERLANDS                 =  1,\n    SUBLANG_GALICIAN_GALICIAN                   =  1,\n    SUBLANG_GEORGIAN_GEORGIA                    =  1,\n\n    SUBLANG_GERMAN                              =  1,\n    SUBLANG_GERMAN_SWISS,\n    SUBLANG_GERMAN_AUSTRIAN,\n    SUBLANG_GERMAN_LUXEMBOURG,\n    SUBLANG_GERMAN_LIECHTENSTEIN,            // =  5\n\n    SUBLANG_GREEK_GREECE                        =  1,\n    SUBLANG_GREENLANDIC_GREENLAND               =  1,\n    SUBLANG_GUJARATI_INDIA                      =  1,\n    SUBLANG_HAUSA_NIGERIA                       =  1,\n    SUBLANG_HEBREW_ISRAEL                       =  1,\n    SUBLANG_HINDI_INDIA                         =  1,\n    SUBLANG_HUNGARIAN_HUNGARY                   =  1,\n    SUBLANG_ICELANDIC_ICELAND                   =  1,\n    SUBLANG_IGBO_NIGERIA                        =  1,\n    SUBLANG_INDONESIAN_INDONESIA                =  1,\n\n    SUBLANG_INUKTITUT_CANADA                    =  1,\n    SUBLANG_INUKTITUT_CANADA_LATIN              =  1,\n\n    SUBLANG_IRISH_IRELAND                       =  1,\n\n    SUBLANG_ITALIAN                             =  1,\n    SUBLANG_ITALIAN_SWISS,                   // =  2\n\n    SUBLANG_JAPANESE_JAPAN                      =  1,\n\n    SUBLANG_KASHMIRI_INDIA                      =  2,\n    SUBLANG_KASHMIRI_SASIA                      =  2,\n\n    SUBLANG_KAZAK_KAZAKHSTAN                    =  1,\n    SUBLANG_KHMER_CAMBODIA                      =  1,\n    SUBLANG_KICHE_GUATEMALA                     =  1,\n    SUBLANG_KINYARWANDA_RWANDA                  =  1,\n    SUBLANG_KONKANI_INDIA                       =  1,\n    SUBLANG_KOREAN                              =  1,\n    SUBLANG_KOREAN_JOHAB                        =  2,\n    SUBLANG_KYRGYZ_KYRGYZSTAN                   =  1,\n    SUBLANG_LAO_LAO_PDR                         =  1,\n    SUBLANG_LATVIAN_LATVIA                      =  1,\n\n    SUBLANG_LITHUANIAN                          =  1,\n    SUBLANG_LITHUANIAN_LITHUANIA                =  1,\n\n    SUBLANG_LOWER_SORBIAN_GERMANY               =  1,\n    SUBLANG_LUXEMBOURGISH_LUXEMBOURG            =  1,\n    SUBLANG_MACEDONIAN_MACEDONIA                =  1,\n    SUBLANG_MALAYALAM_INDIA                     =  1,\n    SUBLANG_MALTESE_MALTA                       =  1,\n    SUBLANG_MAORI_NEW_ZEALAND                   =  1,\n    SUBLANG_MAPUDUNGUN_CHILE                    =  1,\n    SUBLANG_MARATHI_INDIA                       =  1,\n    SUBLANG_MOHAWK_MOHAWK                       =  1,\n\n    SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA         =  1,\n    SUBLANG_MONGOLIAN_PRC,                   // =  2\n\n    SUBLANG_MALAY_MALAYSIA                      =  1,\n    SUBLANG_MALAY_BRUNEI_DARUSSALAM,         // =  2\n\n    SUBLANG_NEPALI_NEPAL                        =  1,\n    SUBLANG_NEPALI_INDIA,                    // =  2\n\n    SUBLANG_NORWEGIAN_BOKMAL                    =  1,\n    SUBLANG_NORWEGIAN_NYNORSK,               // =  2\n\n    SUBLANG_OCCITAN_FRANCE                      =  1,\n    SUBLANG_ORIYA_INDIA                         =  1,\n    SUBLANG_PASHTO_AFGHANISTAN                  =  1,\n    SUBLANG_PERSIAN_IRAN                        =  1,\n    SUBLANG_POLISH_POLAND                       =  1,\n\n    SUBLANG_PORTUGUESE_BRAZILIAN                =  1,\n    SUBLANG_PORTUGUESE                          =  2,\n    SUBLANG_PORTUGUESE_PORTUGAL,             // =  2\n\n    SUBLANG_PUNJABI_INDIA                       =  1,\n\n    SUBLANG_QUECHUA_BOLIVIA                     =  1,\n    SUBLANG_QUECHUA_ECUADOR,\n    SUBLANG_QUECHUA_PERU,                    // =  3\n\n    SUBLANG_ROMANIAN_ROMANIA                    =  1,\n    SUBLANG_ROMANSH_SWITZERLAND                 =  1,\n    SUBLANG_RUSSIAN_RUSSIA                      =  1,\n\n    SUBLANG_SAMI_NORTHERN_NORWAY                =  1,\n    SUBLANG_SAMI_NORTHERN_SWEDEN,\n    SUBLANG_SAMI_NORTHERN_FINLAND,           // =  3\n    SUBLANG_SAMI_SKOLT_FINLAND                  =  3,\n    SUBLANG_SAMI_INARI_FINLAND                  =  3,\n    SUBLANG_SAMI_LULE_NORWAY,\n    SUBLANG_SAMI_LULE_SWEDEN,\n    SUBLANG_SAMI_SOUTHERN_NORWAY,\n    SUBLANG_SAMI_SOUTHERN_SWEDEN,            // =  7\n\n    SUBLANG_SANSKRIT_INDIA                      =  1,\n\n    SUBLANG_SERBIAN_LATIN                       =  2,\n    SUBLANG_SERBIAN_CYRILLIC,                // =  3\n    SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN    =  6,\n    SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC =  7,\n\n    SUBLANG_SINDHI_AFGHANISTAN                  =  2,\n    SUBLANG_SINHALESE_SRI_LANKA                 =  1,\n    SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA         =  1,\n    SUBLANG_SLOVAK_SLOVAKIA                     =  1,\n    SUBLANG_SLOVENIAN_SLOVENIA                  =  1,\n\n    SUBLANG_SPANISH                             =  1,\n    SUBLANG_SPANISH_MEXICAN,\n    SUBLANG_SPANISH_MODERN,\n    SUBLANG_SPANISH_GUATEMALA,\n    SUBLANG_SPANISH_COSTA_RICA,\n    SUBLANG_SPANISH_PANAMA,\n    SUBLANG_SPANISH_DOMINICAN_REPUBLIC,\n    SUBLANG_SPANISH_VENEZUELA,\n    SUBLANG_SPANISH_COLOMBIA,\n    SUBLANG_SPANISH_PERU,\n    SUBLANG_SPANISH_ARGENTINA,\n    SUBLANG_SPANISH_ECUADOR,\n    SUBLANG_SPANISH_CHILE,\n    SUBLANG_SPANISH_URUGUAY,\n    SUBLANG_SPANISH_PARAGUAY,\n    SUBLANG_SPANISH_BOLIVIA,\n    SUBLANG_SPANISH_EL_SALVADOR,\n    SUBLANG_SPANISH_HONDURAS,\n    SUBLANG_SPANISH_NICARAGUA,\n    SUBLANG_SPANISH_PUERTO_RICO,\n    SUBLANG_SPANISH_US,                      // = 21\n\n    SUBLANG_SWEDISH                             =  1,\n    SUBLANG_SWEDISH_SWEDEN                      =  1,\n    SUBLANG_SWEDISH_FINLAND,                 // =  2\n\n    SUBLANG_SYRIAC                              =  1,\n    SUBLANG_TAJIK_TAJIKISTAN                    =  1,\n    SUBLANG_TAMAZIGHT_ALGERIA_LATIN             =  2,\n    SUBLANG_TAMIL_INDIA                         =  1,\n    SUBLANG_TATAR_RUSSIA                        =  1,\n    SUBLANG_TELUGU_INDIA                        =  1,\n    SUBLANG_THAI_THAILAND                       =  1,\n    SUBLANG_TIBETAN_PRC                         =  1,\n    SUBLANG_TIBETAN_BHUTAN                      =  2,\n    SUBLANG_TIGRIGNA_ERITREA                    =  1,\n    SUBLANG_TSWANA_SOUTH_AFRICA                 =  1,\n    SUBLANG_TURKISH_TURKEY                      =  1,\n    SUBLANG_TURKMEN_TURKMENISTAN                =  1,\n    SUBLANG_UIGHUR_PRC                          =  1,\n    SUBLANG_UKRAINIAN_UKRAINE                   =  1,\n    SUBLANG_UPPER_SORBIAN_GERMANY               =  1,\n\n    SUBLANG_URDU_PAKISTAN                       =  1,\n    SUBLANG_URDU_INDIA,                      // =  2\n\n    SUBLANG_UZBEK_LATIN                         =  1,\n    SUBLANG_UZBEK_CYRILLIC,                  // =  2\n\n    SUBLANG_VIETNAMESE_VIETNAM                  =  1,\n    SUBLANG_WELSH_UNITED_KINGDOM                =  1,\n    SUBLANG_WOLOF_SENEGAL                       =  1,\n    SUBLANG_YORUBA_NIGERIA                      =  1,\n    SUBLANG_XHOSA_SOUTH_AFRICA                  =  1,\n    SUBLANG_YAKUT_RUSSIA                        =  1,\n    SUBLANG_YI_PRC                              =  1,\n    SUBLANG_ZULU_SOUTH_AFRICA                   =  1\n}\n\n// This is not documented on MSDN\nenum NLS_VALID_LOCALE_MASK = 1048575;\n\n// Sorting identifiers\nenum : WORD {\n    SORT_DEFAULT              = 0,\n    SORT_JAPANESE_XJIS        = 0,\n    SORT_JAPANESE_UNICODE     = 1,\n    SORT_CHINESE_BIG5         = 0,\n    SORT_CHINESE_PRCP         = 0,\n    SORT_CHINESE_UNICODE      = 1,\n    SORT_CHINESE_PRC          = 2,\n    SORT_CHINESE_BOPOMOFO     = 3,\n    SORT_KOREAN_KSC           = 0,\n    SORT_KOREAN_UNICODE       = 1,\n    SORT_GERMAN_PHONE_BOOK    = 1,\n    SORT_HUNGARIAN_DEFAULT    = 0,\n    SORT_HUNGARIAN_TECHNICAL  = 1,\n    SORT_GEORGIAN_TRADITIONAL = 0,\n    SORT_GEORGIAN_MODERN      = 1\n}\n\npure nothrow @nogc {\n    WORD MAKELANGID(/*USHORT*/uint p, /*USHORT*/ uint s) { return cast(WORD)((s << 10) | p); }\n    WORD PRIMARYLANGID(/*WORD*/uint lgid) { return cast(WORD)(lgid & 0x3FF); }\n    WORD SUBLANGID(/*WORD*/uint lgid) { return cast(WORD)(lgid >>> 10); }\n\n    DWORD MAKELCID(/*WORD*/uint lgid, /*WORD*/uint srtid) { return (cast(DWORD) srtid << 16) | cast(DWORD) lgid; }\n    // ???\n    //DWORD MAKESORTLCID(WORD lgid, WORD srtid, WORD ver) { return (MAKELCID(lgid, srtid)) | ((cast(DWORD)ver) << 20); }\n    WORD LANGIDFROMLCID(LCID lcid) { return cast(WORD) lcid; }\n    WORD SORTIDFROMLCID(LCID lcid) { return cast(WORD) ((lcid >>> 16) & 0x0F); }\n    WORD SORTVERSIONFROMLCID(LCID lcid) { return cast(WORD) ((lcid >>> 20) & 0x0F); }\n}\n\nenum WORD LANG_SYSTEM_DEFAULT = (SUBLANG_SYS_DEFAULT << 10) | LANG_NEUTRAL;\nenum WORD LANG_USER_DEFAULT   = (SUBLANG_DEFAULT << 10) | LANG_NEUTRAL;\nenum DWORD LOCALE_NEUTRAL     = (SORT_DEFAULT << 16)\n                                 | (SUBLANG_NEUTRAL << 10) | LANG_NEUTRAL;\n\n// ---\nenum : BYTE {\n    ACL_REVISION    = 2,\n    ACL_REVISION_DS = 4\n}\n\n// These are not documented on MSDN\nenum : BYTE {\n    ACL_REVISION1    = 1,\n    ACL_REVISION2,\n    ACL_REVISION3,\n    ACL_REVISION4 // = 4\n}\n\nenum BYTE\n    MIN_ACL_REVISION = 2,\n    MAX_ACL_REVISION = 4;\n\n/+\n// These aren't necessary for D.\nenum MINCHAR=0x80;\nenum MAXCHAR=0x7f;\nenum MINSHORT=0x8000;\nenum MAXSHORT=0x7fff;\nenum MINLONG=0x80000000;\nenum MAXLONG=0x7fffffff;\nenum MAXBYTE=0xff;\nenum MAXWORD=0xffff;\nenum MAXDWORD=0xffffffff;\n+/\n\n// SYSTEM_INFO.dwProcessorType\nenum : DWORD {\n    PROCESSOR_INTEL_386     =   386,\n    PROCESSOR_INTEL_486     =   486,\n    PROCESSOR_INTEL_PENTIUM =   586,\n    PROCESSOR_MIPS_R4000    =  4000,\n    PROCESSOR_ALPHA_21064   = 21064,\n    PROCESSOR_INTEL_IA64    =  2200\n}\n\n// SYSTEM_INFO.wProcessorArchitecture\nenum : WORD {\n    PROCESSOR_ARCHITECTURE_INTEL,\n    PROCESSOR_ARCHITECTURE_MIPS,\n    PROCESSOR_ARCHITECTURE_ALPHA,\n    PROCESSOR_ARCHITECTURE_PPC,\n    PROCESSOR_ARCHITECTURE_SHX,\n    PROCESSOR_ARCHITECTURE_ARM,\n    PROCESSOR_ARCHITECTURE_IA64,\n    PROCESSOR_ARCHITECTURE_ALPHA64,\n    PROCESSOR_ARCHITECTURE_MSIL,\n    PROCESSOR_ARCHITECTURE_AMD64,\n    PROCESSOR_ARCHITECTURE_IA32_ON_WIN64, // = 10\n    PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF\n}\n\n// IsProcessorFeaturePresent()\nenum : DWORD {\n    PF_FLOATING_POINT_PRECISION_ERRATA,\n    PF_FLOATING_POINT_EMULATED,\n    PF_COMPARE_EXCHANGE_DOUBLE,\n    PF_MMX_INSTRUCTIONS_AVAILABLE,\n    PF_PPC_MOVEMEM_64BIT_OK,\n    PF_ALPHA_BYTE_INSTRUCTIONS,\n    PF_XMMI_INSTRUCTIONS_AVAILABLE,\n    PF_3DNOW_INSTRUCTIONS_AVAILABLE,\n    PF_RDTSC_INSTRUCTION_AVAILABLE,\n    PF_PAE_ENABLED,\n    PF_XMMI64_INSTRUCTIONS_AVAILABLE\n}\n\n// MinGW: also in ddk/ntifs.h\nenum : DWORD {\n    FILE_ACTION_ADDED = 1,\n    FILE_ACTION_REMOVED,\n    FILE_ACTION_MODIFIED,\n    FILE_ACTION_RENAMED_OLD_NAME,\n    FILE_ACTION_RENAMED_NEW_NAME,\n    FILE_ACTION_ADDED_STREAM,\n    FILE_ACTION_REMOVED_STREAM,\n    FILE_ACTION_MODIFIED_STREAM,\n    FILE_ACTION_REMOVED_BY_DELETE,\n    FILE_ACTION_ID_NOT_TUNNELLED,\n    FILE_ACTION_TUNNELLED_ID_COLLISION // = 11\n}\n// MinGW: end ntifs.h\n\nenum DWORD\n    HEAP_NO_SERIALIZE             = 0x01,\n    HEAP_GROWABLE                 = 0x02,\n    HEAP_GENERATE_EXCEPTIONS      = 0x04,\n    HEAP_ZERO_MEMORY              = 0x08,\n    HEAP_REALLOC_IN_PLACE_ONLY    = 0x10,\n    HEAP_TAIL_CHECKING_ENABLED    = 0x20,\n    HEAP_FREE_CHECKING_ENABLED    = 0x40,\n    HEAP_DISABLE_COALESCE_ON_FREE = 0x80;\n\n// These are not documented on MSDN\nenum HEAP_CREATE_ALIGN_16       = 0;\nenum HEAP_CREATE_ENABLE_TRACING = 0x020000;\nenum HEAP_MAXIMUM_TAG           = 0x000FFF;\nenum HEAP_PSEUDO_TAG_FLAG       = 0x008000;\nenum HEAP_TAG_SHIFT             = 16;\n// ???\n//MACRO #define HEAP_MAKE_TAG_FLAGS(b,o) ((DWORD)((b)+(o)<<16)))\n\nenum ACCESS_MASK\n    KEY_QUERY_VALUE        = 0x000001,\n    KEY_SET_VALUE          = 0x000002,\n    KEY_CREATE_SUB_KEY     = 0x000004,\n    KEY_ENUMERATE_SUB_KEYS = 0x000008,\n    KEY_NOTIFY             = 0x000010,\n    KEY_CREATE_LINK        = 0x000020,\n    KEY_WRITE              = 0x020006,\n    KEY_EXECUTE            = 0x020019,\n    KEY_READ               = 0x020019,\n    KEY_ALL_ACCESS         = 0x0F003F;\n\nstatic if (_WIN32_WINNT >= 0x502) {\nenum ACCESS_MASK\n        KEY_WOW64_64KEY    = 0x000100,\n        KEY_WOW64_32KEY    = 0x000200;\n}\n\nenum DWORD\n    REG_WHOLE_HIVE_VOLATILE = 1,\n    REG_REFRESH_HIVE        = 2,\n    REG_NO_LAZY_FLUSH       = 4;\n\nenum DWORD\n    REG_OPTION_RESERVED       =  0,\n    REG_OPTION_NON_VOLATILE   =  0,\n    REG_OPTION_VOLATILE       =  1,\n    REG_OPTION_CREATE_LINK    =  2,\n    REG_OPTION_BACKUP_RESTORE =  4,\n    REG_OPTION_OPEN_LINK      =  8,\n    REG_LEGAL_OPTION          = 15;\n\nenum SECURITY_INFORMATION\n    OWNER_SECURITY_INFORMATION            = 0x00000001,\n    GROUP_SECURITY_INFORMATION            = 0x00000002,\n    DACL_SECURITY_INFORMATION             = 0x00000004,\n    SACL_SECURITY_INFORMATION             = 0x00000008,\n    LABEL_SECURITY_INFORMATION            = 0x00000010,\n    UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000,\n    UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000,\n    PROTECTED_SACL_SECURITY_INFORMATION   = 0x40000000,\n    PROTECTED_DACL_SECURITY_INFORMATION   = 0x80000000;\n\nenum DWORD MAXIMUM_PROCESSORS = 32;\n\n// VirtualAlloc(), etc\n// -------------------\n\nenum : DWORD {\n    PAGE_NOACCESS          = 0x0001,\n    PAGE_READONLY          = 0x0002,\n    PAGE_READWRITE         = 0x0004,\n    PAGE_WRITECOPY         = 0x0008,\n    PAGE_EXECUTE           = 0x0010,\n    PAGE_EXECUTE_READ      = 0x0020,\n    PAGE_EXECUTE_READWRITE = 0x0040,\n    PAGE_EXECUTE_WRITECOPY = 0x0080,\n    PAGE_GUARD             = 0x0100,\n    PAGE_NOCACHE           = 0x0200\n}\n\nenum : DWORD {\n    MEM_COMMIT      = 0x00001000,\n    MEM_RESERVE     = 0x00002000,\n    MEM_DECOMMIT    = 0x00004000,\n    MEM_RELEASE     = 0x00008000,\n    MEM_FREE        = 0x00010000,\n    MEM_PRIVATE     = 0x00020000,\n    MEM_MAPPED      = 0x00040000,\n    MEM_RESET       = 0x00080000,\n    MEM_TOP_DOWN    = 0x00100000,\n    MEM_WRITE_WATCH = 0x00200000, // MinGW (???): 98/Me\n    MEM_PHYSICAL    = 0x00400000,\n    MEM_4MB_PAGES   = 0x80000000\n}\n\n// MinGW: also in ddk/ntifs.h\n// CreateFileMapping()\nenum DWORD\n    SEC_BASED     = 0x00200000,\n    SEC_NO_CHANGE = 0x00400000,\n    SEC_FILE      = 0x00800000,\n    SEC_IMAGE     = 0x01000000,\n    SEC_VLM       = 0x02000000,\n    SEC_RESERVE   = 0x04000000,\n    SEC_COMMIT    = 0x08000000,\n    SEC_NOCACHE   = 0x10000000,\n    MEM_IMAGE     = SEC_IMAGE;\n// MinGW: end ntifs.h\n\n// ???\nenum ACCESS_MASK\n    SECTION_QUERY       = 0x000001,\n    SECTION_MAP_WRITE   = 0x000002,\n    SECTION_MAP_READ    = 0x000004,\n    SECTION_MAP_EXECUTE = 0x000008,\n    SECTION_EXTEND_SIZE = 0x000010,\n    SECTION_ALL_ACCESS  = 0x0F001F;\n\n// These are not documented on MSDN\nenum MESSAGE_RESOURCE_UNICODE = 1;\nenum RTL_CRITSECT_TYPE        = 0;\nenum RTL_RESOURCE_TYPE        = 1;\n\n// COFF file format\n// ----------------\n\n// IMAGE_FILE_HEADER.Characteristics\nenum WORD\n    IMAGE_FILE_RELOCS_STRIPPED         = 0x0001,\n    IMAGE_FILE_EXECUTABLE_IMAGE        = 0x0002,\n    IMAGE_FILE_LINE_NUMS_STRIPPED      = 0x0004,\n    IMAGE_FILE_LOCAL_SYMS_STRIPPED     = 0x0008,\n    IMAGE_FILE_AGGRESIVE_WS_TRIM       = 0x0010,\n    IMAGE_FILE_LARGE_ADDRESS_AWARE     = 0x0020,\n    IMAGE_FILE_BYTES_REVERSED_LO       = 0x0080,\n    IMAGE_FILE_32BIT_MACHINE           = 0x0100,\n    IMAGE_FILE_DEBUG_STRIPPED          = 0x0200,\n    IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,\n    IMAGE_FILE_NET_RUN_FROM_SWAP       = 0x0800,\n    IMAGE_FILE_SYSTEM                  = 0x1000,\n    IMAGE_FILE_DLL                     = 0x2000,\n    IMAGE_FILE_UP_SYSTEM_ONLY          = 0x4000,\n    IMAGE_FILE_BYTES_REVERSED_HI       = 0x8000;\n\n// IMAGE_FILE_HEADER.Machine\nenum : WORD {\n    IMAGE_FILE_MACHINE_UNKNOWN   = 0x0000,\n    IMAGE_FILE_MACHINE_I386      = 0x014C,\n    IMAGE_FILE_MACHINE_R3000     = 0x0162,\n    IMAGE_FILE_MACHINE_R4000     = 0x0166,\n    IMAGE_FILE_MACHINE_R10000    = 0x0168,\n    IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x0169,\n    IMAGE_FILE_MACHINE_ALPHA     = 0x0184,\n    IMAGE_FILE_MACHINE_SH3       = 0x01A2,\n    IMAGE_FILE_MACHINE_SH3DSP    = 0x01A3,\n    IMAGE_FILE_MACHINE_SH4       = 0x01A6,\n    IMAGE_FILE_MACHINE_SH5       = 0x01A8,\n    IMAGE_FILE_MACHINE_ARM       = 0x01C0,\n    IMAGE_FILE_MACHINE_THUMB     = 0x01C2,\n    IMAGE_FILE_MACHINE_AM33      = 0x01D3,\n    IMAGE_FILE_MACHINE_POWERPC   = 0x01F0,\n    IMAGE_FILE_MACHINE_POWERPCFP = 0x01F1,\n    IMAGE_FILE_MACHINE_IA64      = 0x0200,\n    IMAGE_FILE_MACHINE_MIPS16    = 0x0266,\n    IMAGE_FILE_MACHINE_MIPSFPU   = 0x0366,\n    IMAGE_FILE_MACHINE_MIPSFPU16 = 0x0466,\n    IMAGE_FILE_MACHINE_EBC       = 0x0EBC,\n    IMAGE_FILE_MACHINE_AMD64     = 0x8664,\n    IMAGE_FILE_MACHINE_M32R      = 0x9041\n}\n\n// ???\nenum  {\n    IMAGE_DOS_SIGNATURE    = 0x5A4D,\n    IMAGE_OS2_SIGNATURE    = 0x454E,\n    IMAGE_OS2_SIGNATURE_LE = 0x454C,\n    IMAGE_VXD_SIGNATURE    = 0x454C,\n    IMAGE_NT_SIGNATURE     = 0x4550\n}\n\n// IMAGE_OPTIONAL_HEADER.Magic\nenum : WORD {\n    IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x010B,\n    IMAGE_ROM_OPTIONAL_HDR_MAGIC  = 0x0107,\n    IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x020B\n}\n\n// IMAGE_OPTIONAL_HEADER.Subsystem\nenum : WORD {\n    IMAGE_SUBSYSTEM_UNKNOWN                  =  0,\n    IMAGE_SUBSYSTEM_NATIVE,\n    IMAGE_SUBSYSTEM_WINDOWS_GUI,\n    IMAGE_SUBSYSTEM_WINDOWS_CUI,          // =  3\n    IMAGE_SUBSYSTEM_OS2_CUI                  =  5,\n    IMAGE_SUBSYSTEM_POSIX_CUI                =  7,\n    IMAGE_SUBSYSTEM_NATIVE_WINDOWS,\n    IMAGE_SUBSYSTEM_WINDOWS_CE_GUI,\n    IMAGE_SUBSYSTEM_EFI_APPLICATION,\n    IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER,\n    IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER,\n    IMAGE_SUBSYSTEM_EFI_ROM,\n    IMAGE_SUBSYSTEM_XBOX,                 // = 14\n    IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16\n}\n\n// IMAGE_OPTIONAL_HEADER.DllCharacteristics\nenum WORD\n    IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE         = 0x0040,\n    IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY      = 0x0080,\n    IMAGE_DLL_CHARACTERISTICS_NX_COMPAT            = 0x0100,\n    IMAGE_DLLCHARACTERISTICS_NO_ISOLATION          = 0x0200,\n    IMAGE_DLLCHARACTERISTICS_NO_SEH                = 0x0400,\n    IMAGE_DLLCHARACTERISTICS_NO_BIND               = 0x0800,\n    IMAGE_DLLCHARACTERISTICS_WDM_DRIVER            = 0x2000,\n    IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000;\n\n// ???\nenum IMAGE_SEPARATE_DEBUG_SIGNATURE = 0x4944;\n\nenum size_t\n    IMAGE_NUMBEROF_DIRECTORY_ENTRIES =  16,\n    IMAGE_SIZEOF_ROM_OPTIONAL_HEADER =  56,\n    IMAGE_SIZEOF_STD_OPTIONAL_HEADER =  28,\n    IMAGE_SIZEOF_NT_OPTIONAL_HEADER  = 224,\n    IMAGE_SIZEOF_SHORT_NAME          =   8,\n    IMAGE_SIZEOF_SECTION_HEADER      =  40,\n    IMAGE_SIZEOF_SYMBOL              =  18,\n    IMAGE_SIZEOF_AUX_SYMBOL          =  18,\n    IMAGE_SIZEOF_RELOCATION          =  10,\n    IMAGE_SIZEOF_BASE_RELOCATION     =   8,\n    IMAGE_SIZEOF_LINENUMBER          =   6,\n    IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR  =  60,\n    SIZEOF_RFPO_DATA                 =  16;\n\nPIMAGE_SECTION_HEADER IMAGE_FIRST_SECTION(PIMAGE_NT_HEADERS h) {\n    return cast(PIMAGE_SECTION_HEADER)\n        (&h.OptionalHeader + h.FileHeader.SizeOfOptionalHeader);\n}\n\n// ImageDirectoryEntryToDataEx()\nenum : USHORT {\n    IMAGE_DIRECTORY_ENTRY_EXPORT             =  0,\n    IMAGE_DIRECTORY_ENTRY_IMPORT,\n    IMAGE_DIRECTORY_ENTRY_RESOURCE,\n    IMAGE_DIRECTORY_ENTRY_EXCEPTION,\n    IMAGE_DIRECTORY_ENTRY_SECURITY,\n    IMAGE_DIRECTORY_ENTRY_BASERELOC,\n    IMAGE_DIRECTORY_ENTRY_DEBUG,\n    IMAGE_DIRECTORY_ENTRY_COPYRIGHT,      // =  7\n    IMAGE_DIRECTORY_ENTRY_ARCHITECTURE       =  7,\n    IMAGE_DIRECTORY_ENTRY_GLOBALPTR,\n    IMAGE_DIRECTORY_ENTRY_TLS,\n    IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,\n    IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,\n    IMAGE_DIRECTORY_ENTRY_IAT,\n    IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT,\n    IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, // = 14\n}\n\n// IMAGE_SECTION_HEADER.Characteristics\nenum DWORD\n    IMAGE_SCN_TYPE_REG               = 0x00000000,\n    IMAGE_SCN_TYPE_DSECT             = 0x00000001,\n    IMAGE_SCN_TYPE_NOLOAD            = 0x00000002,\n    IMAGE_SCN_TYPE_GROUP             = 0x00000004,\n    IMAGE_SCN_TYPE_NO_PAD            = 0x00000008,\n    IMAGE_SCN_TYPE_COPY              = 0x00000010,\n    IMAGE_SCN_CNT_CODE               = 0x00000020,\n    IMAGE_SCN_CNT_INITIALIZED_DATA   = 0x00000040,\n    IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,\n    IMAGE_SCN_LNK_OTHER              = 0x00000100,\n    IMAGE_SCN_LNK_INFO               = 0x00000200,\n    IMAGE_SCN_TYPE_OVER              = 0x00000400,\n    IMAGE_SCN_LNK_REMOVE             = 0x00000800,\n    IMAGE_SCN_LNK_COMDAT             = 0x00001000,\n    IMAGE_SCN_MEM_FARDATA            = 0x00008000,\n    IMAGE_SCN_GPREL                  = 0x00008000,\n    IMAGE_SCN_MEM_PURGEABLE          = 0x00020000,\n    IMAGE_SCN_MEM_16BIT              = 0x00020000,\n    IMAGE_SCN_MEM_LOCKED             = 0x00040000,\n    IMAGE_SCN_MEM_PRELOAD            = 0x00080000,\n    IMAGE_SCN_ALIGN_1BYTES           = 0x00100000,\n    IMAGE_SCN_ALIGN_2BYTES           = 0x00200000,\n    IMAGE_SCN_ALIGN_4BYTES           = 0x00300000,\n    IMAGE_SCN_ALIGN_8BYTES           = 0x00400000,\n    IMAGE_SCN_ALIGN_16BYTES          = 0x00500000,\n    IMAGE_SCN_ALIGN_32BYTES          = 0x00600000,\n    IMAGE_SCN_ALIGN_64BYTES          = 0x00700000,\n    IMAGE_SCN_ALIGN_128BYTES         = 0x00800000,\n    IMAGE_SCN_ALIGN_256BYTES         = 0x00900000,\n    IMAGE_SCN_ALIGN_512BYTES         = 0x00A00000,\n    IMAGE_SCN_ALIGN_1024BYTES        = 0x00B00000,\n    IMAGE_SCN_ALIGN_2048BYTES        = 0x00C00000,\n    IMAGE_SCN_ALIGN_4096BYTES        = 0x00D00000,\n    IMAGE_SCN_ALIGN_8192BYTES        = 0x00E00000,\n    IMAGE_SCN_LNK_NRELOC_OVFL        = 0x01000000,\n    IMAGE_SCN_MEM_DISCARDABLE        = 0x02000000,\n    IMAGE_SCN_MEM_NOT_CACHED         = 0x04000000,\n    IMAGE_SCN_MEM_NOT_PAGED          = 0x08000000,\n    IMAGE_SCN_MEM_SHARED             = 0x10000000,\n    IMAGE_SCN_MEM_EXECUTE            = 0x20000000,\n    IMAGE_SCN_MEM_READ               = 0x40000000,\n    IMAGE_SCN_MEM_WRITE              = 0x80000000;\n\n/*  The following constants are mostlydocumented at\n *  http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/pecoff.doc\n *  but don't seem to be defined in the HTML docs.\n */\nenum : SHORT {\n    IMAGE_SYM_UNDEFINED =  0,\n    IMAGE_SYM_ABSOLUTE  = -1,\n    IMAGE_SYM_DEBUG     = -2\n}\n\nenum : ubyte {\n    IMAGE_SYM_TYPE_NULL,\n    IMAGE_SYM_TYPE_VOID,\n    IMAGE_SYM_TYPE_CHAR,\n    IMAGE_SYM_TYPE_SHORT,\n    IMAGE_SYM_TYPE_INT,\n    IMAGE_SYM_TYPE_LONG,\n    IMAGE_SYM_TYPE_FLOAT,\n    IMAGE_SYM_TYPE_DOUBLE,\n    IMAGE_SYM_TYPE_STRUCT,\n    IMAGE_SYM_TYPE_UNION,\n    IMAGE_SYM_TYPE_ENUM,\n    IMAGE_SYM_TYPE_MOE,\n    IMAGE_SYM_TYPE_BYTE,\n    IMAGE_SYM_TYPE_WORD,\n    IMAGE_SYM_TYPE_UINT,\n    IMAGE_SYM_TYPE_DWORD // = 15\n}\nenum IMAGE_SYM_TYPE_PCODE = 32768; // ???\n\nenum : ubyte {\n    IMAGE_SYM_DTYPE_NULL,\n    IMAGE_SYM_DTYPE_POINTER,\n    IMAGE_SYM_DTYPE_FUNCTION,\n    IMAGE_SYM_DTYPE_ARRAY\n}\n\nenum : BYTE {\n    IMAGE_SYM_CLASS_END_OF_FUNCTION  = 0xFF,\n    IMAGE_SYM_CLASS_NULL             =   0,\n    IMAGE_SYM_CLASS_AUTOMATIC,\n    IMAGE_SYM_CLASS_EXTERNAL,\n    IMAGE_SYM_CLASS_STATIC,\n    IMAGE_SYM_CLASS_REGISTER,\n    IMAGE_SYM_CLASS_EXTERNAL_DEF,\n    IMAGE_SYM_CLASS_LABEL,\n    IMAGE_SYM_CLASS_UNDEFINED_LABEL,\n    IMAGE_SYM_CLASS_MEMBER_OF_STRUCT,\n    IMAGE_SYM_CLASS_ARGUMENT,\n    IMAGE_SYM_CLASS_STRUCT_TAG,\n    IMAGE_SYM_CLASS_MEMBER_OF_UNION,\n    IMAGE_SYM_CLASS_UNION_TAG,\n    IMAGE_SYM_CLASS_TYPE_DEFINITION,\n    IMAGE_SYM_CLASS_UNDEFINED_STATIC,\n    IMAGE_SYM_CLASS_ENUM_TAG,\n    IMAGE_SYM_CLASS_MEMBER_OF_ENUM,\n    IMAGE_SYM_CLASS_REGISTER_PARAM,\n    IMAGE_SYM_CLASS_BIT_FIELD,    // =  18\n    IMAGE_SYM_CLASS_FAR_EXTERNAL     =  68,\n    IMAGE_SYM_CLASS_BLOCK            = 100,\n    IMAGE_SYM_CLASS_FUNCTION,\n    IMAGE_SYM_CLASS_END_OF_STRUCT,\n    IMAGE_SYM_CLASS_FILE,\n    IMAGE_SYM_CLASS_SECTION,\n    IMAGE_SYM_CLASS_WEAK_EXTERNAL,// = 105\n    IMAGE_SYM_CLASS_CLR_TOKEN        = 107\n}\n\nenum : BYTE {\n    IMAGE_COMDAT_SELECT_NODUPLICATES = 1,\n    IMAGE_COMDAT_SELECT_ANY,\n    IMAGE_COMDAT_SELECT_SAME_SIZE,\n    IMAGE_COMDAT_SELECT_EXACT_MATCH,\n    IMAGE_COMDAT_SELECT_ASSOCIATIVE,\n    IMAGE_COMDAT_SELECT_LARGEST,\n    IMAGE_COMDAT_SELECT_NEWEST    // = 7\n}\n\nenum : DWORD {\n    IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1,\n    IMAGE_WEAK_EXTERN_SEARCH_LIBRARY,\n    IMAGE_WEAK_EXTERN_SEARCH_ALIAS\n}\n\nenum : WORD {\n    IMAGE_REL_I386_ABSOLUTE       = 0x0000,\n    IMAGE_REL_I386_DIR16          = 0x0001,\n    IMAGE_REL_I386_REL16          = 0x0002,\n    IMAGE_REL_I386_DIR32          = 0x0006,\n    IMAGE_REL_I386_DIR32NB        = 0x0007,\n    IMAGE_REL_I386_SEG12          = 0x0009,\n    IMAGE_REL_I386_SECTION        = 0x000A,\n    IMAGE_REL_I386_SECREL         = 0x000B,\n    IMAGE_REL_I386_TOKEN          = 0x000C,\n    IMAGE_REL_I386_SECREL7        = 0x000D,\n    IMAGE_REL_I386_REL32          = 0x0014\n}\n\nenum : WORD {\n    IMAGE_REL_AMD64_ABSOLUTE      = 0x0000,\n    IMAGE_REL_AMD64_ADDR64        = 0x0001,\n    IMAGE_REL_AMD64_ADDR32        = 0x0002,\n    IMAGE_REL_AMD64_ADDR32NB      = 0x0003,\n    IMAGE_REL_AMD64_REL32         = 0x0004,\n    IMAGE_REL_AMD64_REL32_1       = 0x0005,\n    IMAGE_REL_AMD64_REL32_2       = 0x0006,\n    IMAGE_REL_AMD64_REL32_3       = 0x0007,\n    IMAGE_REL_AMD64_REL32_4       = 0x0008,\n    IMAGE_REL_AMD64_REL32_5       = 0x0009,\n    IMAGE_REL_AMD64_SECTION       = 0x000A,\n    IMAGE_REL_AMD64_SECREL        = 0x000B,\n    IMAGE_REL_AMD64_SECREL7       = 0x000C,\n    IMAGE_REL_AMD64_TOKEN         = 0x000D,\n    IMAGE_REL_AMD64_SREL32        = 0x000E,\n    IMAGE_REL_AMD64_PAIR          = 0x000F,\n    IMAGE_REL_AMD64_SSPAN32       = 0x0010\n}\n\nenum : WORD {\n    IMAGE_REL_IA64_ABSOLUTE       = 0x0000,\n    IMAGE_REL_IA64_IMM14          = 0x0001,\n    IMAGE_REL_IA64_IMM22          = 0x0002,\n    IMAGE_REL_IA64_IMM64          = 0x0003,\n    IMAGE_REL_IA64_DIR32          = 0x0004,\n    IMAGE_REL_IA64_DIR64          = 0x0005,\n    IMAGE_REL_IA64_PCREL21B       = 0x0006,\n    IMAGE_REL_IA64_PCREL21M       = 0x0007,\n    IMAGE_REL_IA64_PCREL21F       = 0x0008,\n    IMAGE_REL_IA64_GPREL22        = 0x0009,\n    IMAGE_REL_IA64_LTOFF22        = 0x000A,\n    IMAGE_REL_IA64_SECTION        = 0x000B,\n    IMAGE_REL_IA64_SECREL22       = 0x000C,\n    IMAGE_REL_IA64_SECREL64I      = 0x000D,\n    IMAGE_REL_IA64_SECREL32       = 0x000E,\n    IMAGE_REL_IA64_DIR32NB        = 0x0010,\n    IMAGE_REL_IA64_SREL14         = 0x0011,\n    IMAGE_REL_IA64_SREL22         = 0x0012,\n    IMAGE_REL_IA64_SREL32         = 0x0013,\n    IMAGE_REL_IA64_UREL32         = 0x0014,\n    IMAGE_REL_IA64_PCREL60X       = 0x0015,\n    IMAGE_REL_IA64_PCREL60B       = 0x0016,\n    IMAGE_REL_IA64_PCREL60F       = 0x0017,\n    IMAGE_REL_IA64_PCREL60I       = 0x0018,\n    IMAGE_REL_IA64_PCREL60M       = 0x0019,\n    IMAGE_REL_IA64_IMMGPREL64     = 0x001A,\n    IMAGE_REL_IA64_TOKEN          = 0x001B,\n    IMAGE_REL_IA64_GPREL32        = 0x001C,\n    IMAGE_REL_IA64_ADDEND         = 0x001F\n}\n\nenum : WORD {\n    IMAGE_REL_SH3_ABSOLUTE        = 0x0000,\n    IMAGE_REL_SH3_DIRECT16        = 0x0001,\n    IMAGE_REL_SH3_DIRECT32        = 0x0002,\n    IMAGE_REL_SH3_DIRECT8         = 0x0003,\n    IMAGE_REL_SH3_DIRECT8_WORD    = 0x0004,\n    IMAGE_REL_SH3_DIRECT8_LONG    = 0x0005,\n    IMAGE_REL_SH3_DIRECT4         = 0x0006,\n    IMAGE_REL_SH3_DIRECT4_WORD    = 0x0007,\n    IMAGE_REL_SH3_DIRECT4_LONG    = 0x0008,\n    IMAGE_REL_SH3_PCREL8_WORD     = 0x0009,\n    IMAGE_REL_SH3_PCREL8_LONG     = 0x000A,\n    IMAGE_REL_SH3_PCREL12_WORD    = 0x000B,\n    IMAGE_REL_SH3_STARTOF_SECTION = 0x000C,\n    IMAGE_REL_SH3_SIZEOF_SECTION  = 0x000D,\n    IMAGE_REL_SH3_SECTION         = 0x000E,\n    IMAGE_REL_SH3_SECREL          = 0x000F,\n    IMAGE_REL_SH3_DIRECT32_NB     = 0x0010,\n    IMAGE_REL_SH3_GPREL4_LONG     = 0x0011,\n    IMAGE_REL_SH3_TOKEN           = 0x0012,\n    IMAGE_REL_SHM_PCRELPT         = 0x0013,\n    IMAGE_REL_SHM_REFLO           = 0x0014,\n    IMAGE_REL_SHM_REFHALF         = 0x0015,\n    IMAGE_REL_SHM_RELLO           = 0x0016,\n    IMAGE_REL_SHM_RELHALF         = 0x0017,\n    IMAGE_REL_SHM_PAIR            = 0x0018,\n    IMAGE_REL_SHM_NOMODE          = 0x8000\n}\n\nenum : WORD {\n    IMAGE_REL_M32R_ABSOLUTE       = 0x0000,\n    IMAGE_REL_M32R_ADDR32         = 0x0001,\n    IMAGE_REL_M32R_ADDR32NB       = 0x0002,\n    IMAGE_REL_M32R_ADDR24         = 0x0003,\n    IMAGE_REL_M32R_GPREL16        = 0x0004,\n    IMAGE_REL_M32R_PCREL24        = 0x0005,\n    IMAGE_REL_M32R_PCREL16        = 0x0006,\n    IMAGE_REL_M32R_PCREL8         = 0x0007,\n    IMAGE_REL_M32R_REFHALF        = 0x0008,\n    IMAGE_REL_M32R_REFHI          = 0x0009,\n    IMAGE_REL_M32R_REFLO          = 0x000A,\n    IMAGE_REL_M32R_PAIR           = 0x000B,\n    IMAGE_REL_M32R_SECTION        = 0x000C,\n    IMAGE_REL_M32R_SECREL         = 0x000D,\n    IMAGE_REL_M32R_TOKEN          = 0x000E\n}\n\nenum : WORD {\n    IMAGE_REL_MIPS_ABSOLUTE       = 0x0000,\n    IMAGE_REL_MIPS_REFHALF        = 0x0001,\n    IMAGE_REL_MIPS_REFWORD        = 0x0002,\n    IMAGE_REL_MIPS_JMPADDR        = 0x0003,\n    IMAGE_REL_MIPS_REFHI          = 0x0004,\n    IMAGE_REL_MIPS_REFLO          = 0x0005,\n    IMAGE_REL_MIPS_GPREL          = 0x0006,\n    IMAGE_REL_MIPS_LITERAL        = 0x0007,\n    IMAGE_REL_MIPS_SECTION        = 0x000A,\n    IMAGE_REL_MIPS_SECREL         = 0x000B,\n    IMAGE_REL_MIPS_SECRELLO       = 0x000C,\n    IMAGE_REL_MIPS_SECRELHI       = 0x000D,\n    IMAGE_REL_MIPS_JMPADDR16      = 0x0010,\n    IMAGE_REL_MIPS_REFWORDNB      = 0x0022,\n    IMAGE_REL_MIPS_PAIR           = 0x0025\n}\n\n\nenum : WORD {\n    IMAGE_REL_ALPHA_ABSOLUTE,\n    IMAGE_REL_ALPHA_REFLONG,\n    IMAGE_REL_ALPHA_REFQUAD,\n    IMAGE_REL_ALPHA_GPREL32,\n    IMAGE_REL_ALPHA_LITERAL,\n    IMAGE_REL_ALPHA_LITUSE,\n    IMAGE_REL_ALPHA_GPDISP,\n    IMAGE_REL_ALPHA_BRADDR,\n    IMAGE_REL_ALPHA_HINT,\n    IMAGE_REL_ALPHA_INLINE_REFLONG,\n    IMAGE_REL_ALPHA_REFHI,\n    IMAGE_REL_ALPHA_REFLO,\n    IMAGE_REL_ALPHA_PAIR,\n    IMAGE_REL_ALPHA_MATCH,\n    IMAGE_REL_ALPHA_SECTION,\n    IMAGE_REL_ALPHA_SECREL,\n    IMAGE_REL_ALPHA_REFLONGNB,\n    IMAGE_REL_ALPHA_SECRELLO,\n    IMAGE_REL_ALPHA_SECRELHI // = 18\n}\n\nenum : WORD {\n    IMAGE_REL_PPC_ABSOLUTE,\n    IMAGE_REL_PPC_ADDR64,\n    IMAGE_REL_PPC_ADDR32,\n    IMAGE_REL_PPC_ADDR24,\n    IMAGE_REL_PPC_ADDR16,\n    IMAGE_REL_PPC_ADDR14,\n    IMAGE_REL_PPC_REL24,\n    IMAGE_REL_PPC_REL14,\n    IMAGE_REL_PPC_TOCREL16,\n    IMAGE_REL_PPC_TOCREL14,\n    IMAGE_REL_PPC_ADDR32NB,\n    IMAGE_REL_PPC_SECREL,\n    IMAGE_REL_PPC_SECTION,\n    IMAGE_REL_PPC_IFGLUE,\n    IMAGE_REL_PPC_IMGLUE,\n    IMAGE_REL_PPC_SECREL16,\n    IMAGE_REL_PPC_REFHI,\n    IMAGE_REL_PPC_REFLO,\n    IMAGE_REL_PPC_PAIR // = 18\n}\n\n// ???\nenum IMAGE_REL_PPC_TYPEMASK = 0x00FF;\nenum IMAGE_REL_PPC_NEG      = 0x0100;\nenum IMAGE_REL_PPC_BRTAKEN  = 0x0200;\nenum IMAGE_REL_PPC_BRNTAKEN = 0x0400;\nenum IMAGE_REL_PPC_TOCDEFN  = 0x0800;\n\nenum {\n    IMAGE_REL_BASED_ABSOLUTE,\n    IMAGE_REL_BASED_HIGH,\n    IMAGE_REL_BASED_LOW,\n    IMAGE_REL_BASED_HIGHLOW,\n    IMAGE_REL_BASED_HIGHADJ,\n    IMAGE_REL_BASED_MIPS_JMPADDR\n}\n// End of constants documented in pecoff.doc\n\nenum size_t IMAGE_ARCHIVE_START_SIZE = 8;\n\nconst TCHAR[]\n    IMAGE_ARCHIVE_START            = \"!<arch>\\n\",\n    IMAGE_ARCHIVE_END              = \"`\\n\",\n    IMAGE_ARCHIVE_PAD              = \"\\n\",\n    IMAGE_ARCHIVE_LINKER_MEMBER    = \"/               \",\n    IMAGE_ARCHIVE_LONGNAMES_MEMBER = \"//              \";\n\nenum IMAGE_ORDINAL_FLAG32 = 0x80000000;\n\nulong IMAGE_ORDINAL64(ulong Ordinal) { return Ordinal & 0xFFFF; }\nuint IMAGE_ORDINAL32(uint Ordinal)   { return Ordinal & 0xFFFF; }\n\nbool IMAGE_SNAP_BY_ORDINAL32(uint Ordinal) {\n    return (Ordinal & IMAGE_ORDINAL_FLAG32) != 0;\n}\n\nenum ulong IMAGE_ORDINAL_FLAG64 = 0x8000000000000000;\n\nbool IMAGE_SNAP_BY_ORDINAL64(ulong Ordinal) {\n    return (Ordinal & IMAGE_ORDINAL_FLAG64) != 0;\n}\n\n// ???\nenum IMAGE_RESOURCE_NAME_IS_STRING    = 0x80000000;\nenum IMAGE_RESOURCE_DATA_IS_DIRECTORY = 0x80000000;\n\nenum : DWORD {\n    IMAGE_DEBUG_TYPE_UNKNOWN,\n    IMAGE_DEBUG_TYPE_COFF,\n    IMAGE_DEBUG_TYPE_CODEVIEW,\n    IMAGE_DEBUG_TYPE_FPO,\n    IMAGE_DEBUG_TYPE_MISC,\n    IMAGE_DEBUG_TYPE_EXCEPTION,\n    IMAGE_DEBUG_TYPE_FIXUP,\n    IMAGE_DEBUG_TYPE_OMAP_TO_SRC,\n    IMAGE_DEBUG_TYPE_OMAP_FROM_SRC,\n    IMAGE_DEBUG_TYPE_BORLAND // = 9\n}\n\nenum : ubyte {\n    FRAME_FPO,\n    FRAME_TRAP,\n    FRAME_TSS,\n    FRAME_NONFPO\n}\n\n// ???\nenum IMAGE_DEBUG_MISC_EXENAME = 1;\n\n// ???\nenum N_BTMASK = 0x000F;\nenum N_TMASK  = 0x0030;\nenum N_TMASK1 = 0x00C0;\nenum N_TMASK2 = 0x00F0;\nenum N_BTSHFT = 4;\nenum N_TSHIFT = 2;\n\nenum int\n    IS_TEXT_UNICODE_ASCII16            = 0x0001,\n    IS_TEXT_UNICODE_STATISTICS         = 0x0002,\n    IS_TEXT_UNICODE_CONTROLS           = 0x0004,\n    IS_TEXT_UNICODE_SIGNATURE          = 0x0008,\n    IS_TEXT_UNICODE_REVERSE_ASCII16    = 0x0010,\n    IS_TEXT_UNICODE_REVERSE_STATISTICS = 0x0020,\n    IS_TEXT_UNICODE_REVERSE_CONTROLS   = 0x0040,\n    IS_TEXT_UNICODE_REVERSE_SIGNATURE  = 0x0080,\n    IS_TEXT_UNICODE_ILLEGAL_CHARS      = 0x0100,\n    IS_TEXT_UNICODE_ODD_LENGTH         = 0x0200,\n    IS_TEXT_UNICODE_NULL_BYTES         = 0x1000,\n    IS_TEXT_UNICODE_UNICODE_MASK       = 0x000F,\n    IS_TEXT_UNICODE_REVERSE_MASK       = 0x00F0,\n    IS_TEXT_UNICODE_NOT_UNICODE_MASK   = 0x0F00,\n    IS_TEXT_UNICODE_NOT_ASCII_MASK     = 0xF000;\n\nenum DWORD\n    SERVICE_KERNEL_DRIVER       = 0x0001,\n    SERVICE_FILE_SYSTEM_DRIVER  = 0x0002,\n    SERVICE_ADAPTER             = 0x0004,\n    SERVICE_RECOGNIZER_DRIVER   = 0x0008,\n    SERVICE_WIN32_OWN_PROCESS   = 0x0010,\n    SERVICE_WIN32_SHARE_PROCESS = 0x0020,\n    SERVICE_INTERACTIVE_PROCESS = 0x0100,\n    SERVICE_DRIVER              = 0x000B,\n    SERVICE_WIN32               = 0x0030,\n    SERVICE_TYPE_ALL            = 0x013F;\n\nenum : DWORD {\n    SERVICE_BOOT_START   = 0,\n    SERVICE_SYSTEM_START = 1,\n    SERVICE_AUTO_START   = 2,\n    SERVICE_DEMAND_START = 3,\n    SERVICE_DISABLED     = 4\n}\n\nenum : DWORD {\n    SERVICE_ERROR_IGNORE   = 0,\n    SERVICE_ERROR_NORMAL   = 1,\n    SERVICE_ERROR_SEVERE   = 2,\n    SERVICE_ERROR_CRITICAL = 3\n}\n\n\nenum uint\n    SE_OWNER_DEFAULTED          = 0x0001,\n    SE_GROUP_DEFAULTED          = 0x0002,\n    SE_DACL_PRESENT             = 0x0004,\n    SE_DACL_DEFAULTED           = 0x0008,\n    SE_SACL_PRESENT             = 0x0010,\n    SE_SACL_DEFAULTED           = 0x0020,\n    SE_DACL_AUTO_INHERIT_REQ    = 0x0100,\n    SE_SACL_AUTO_INHERIT_REQ    = 0x0200,\n    SE_DACL_AUTO_INHERITED      = 0x0400,\n    SE_SACL_AUTO_INHERITED      = 0x0800,\n    SE_DACL_PROTECTED           = 0x1000,\n    SE_SACL_PROTECTED           = 0x2000,\n    SE_SELF_RELATIVE            = 0x8000;\n\nenum SECURITY_IMPERSONATION_LEVEL {\n    SecurityAnonymous,\n    SecurityIdentification,\n    SecurityImpersonation,\n    SecurityDelegation\n}\nalias SECURITY_IMPERSONATION_LEVEL* PSECURITY_IMPERSONATION_LEVEL;\n\nalias BOOLEAN SECURITY_CONTEXT_TRACKING_MODE;\nalias BOOLEAN* PSECURITY_CONTEXT_TRACKING_MODE;\n\nenum size_t SECURITY_DESCRIPTOR_MIN_LENGTH = 20;\n\nenum DWORD\n    SECURITY_DESCRIPTOR_REVISION  = 1,\n    SECURITY_DESCRIPTOR_REVISION1 = 1;\n\nenum DWORD\n    SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001,\n    SE_PRIVILEGE_ENABLED            = 0x00000002,\n    SE_PRIVILEGE_USED_FOR_ACCESS    = 0x80000000;\n\nenum DWORD PRIVILEGE_SET_ALL_NECESSARY = 1;\n\nenum SECURITY_IMPERSONATION_LEVEL\n    SECURITY_MAX_IMPERSONATION_LEVEL = SECURITY_IMPERSONATION_LEVEL.SecurityDelegation,\n    DEFAULT_IMPERSONATION_LEVEL      = SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation;\n\nenum BOOLEAN\n    SECURITY_DYNAMIC_TRACKING = true,\n    SECURITY_STATIC_TRACKING  = false;\n\n// also in ddk/ntifs.h\nenum DWORD\n    TOKEN_ASSIGN_PRIMARY    = 0x0001,\n    TOKEN_DUPLICATE         = 0x0002,\n    TOKEN_IMPERSONATE       = 0x0004,\n    TOKEN_QUERY             = 0x0008,\n    TOKEN_QUERY_SOURCE      = 0x0010,\n    TOKEN_ADJUST_PRIVILEGES = 0x0020,\n    TOKEN_ADJUST_GROUPS     = 0x0040,\n    TOKEN_ADJUST_DEFAULT    = 0x0080,\n\n    TOKEN_ALL_ACCESS        = STANDARD_RIGHTS_REQUIRED\n                              | TOKEN_ASSIGN_PRIMARY\n                              | TOKEN_DUPLICATE\n                              | TOKEN_IMPERSONATE\n                              | TOKEN_QUERY\n                              | TOKEN_QUERY_SOURCE\n                              | TOKEN_ADJUST_PRIVILEGES\n                              | TOKEN_ADJUST_GROUPS\n                              | TOKEN_ADJUST_DEFAULT,\n    TOKEN_READ              = STANDARD_RIGHTS_READ | TOKEN_QUERY,\n    TOKEN_WRITE             = STANDARD_RIGHTS_WRITE\n                              | TOKEN_ADJUST_PRIVILEGES\n                              | TOKEN_ADJUST_GROUPS\n                              | TOKEN_ADJUST_DEFAULT,\n    TOKEN_EXECUTE           = STANDARD_RIGHTS_EXECUTE;\n\nenum size_t TOKEN_SOURCE_LENGTH = 8;\n// end ddk/ntifs.h\n\nenum : DWORD {\n    DLL_PROCESS_DETACH,\n    DLL_PROCESS_ATTACH,\n    DLL_THREAD_ATTACH,\n    DLL_THREAD_DETACH\n}\n\nenum : DWORD {\n    DBG_CONTINUE              = 0x00010002,\n    DBG_TERMINATE_THREAD      = 0x40010003,\n    DBG_TERMINATE_PROCESS     = 0x40010004,\n    DBG_CONTROL_C             = 0x40010005,\n    DBG_CONTROL_BREAK         = 0x40010008,\n    DBG_EXCEPTION_NOT_HANDLED = 0x80010001\n}\n\nenum : DWORD {\n    TAPE_ABSOLUTE_POSITION,\n    TAPE_LOGICAL_POSITION,\n    TAPE_PSEUDO_LOGICAL_POSITION\n}\n\nenum : DWORD {\n    TAPE_REWIND,\n    TAPE_ABSOLUTE_BLOCK,\n    TAPE_LOGICAL_BLOCK,\n    TAPE_PSEUDO_LOGICAL_BLOCK,\n    TAPE_SPACE_END_OF_DATA,\n    TAPE_SPACE_RELATIVE_BLOCKS,\n    TAPE_SPACE_FILEMARKS,\n    TAPE_SPACE_SEQUENTIAL_FMKS,\n    TAPE_SPACE_SETMARKS,\n    TAPE_SPACE_SEQUENTIAL_SMKS\n}\n\nenum DWORD\n    TAPE_DRIVE_FIXED            = 0x00000001,\n    TAPE_DRIVE_SELECT           = 0x00000002,\n    TAPE_DRIVE_INITIATOR        = 0x00000004,\n    TAPE_DRIVE_ERASE_SHORT      = 0x00000010,\n    TAPE_DRIVE_ERASE_LONG       = 0x00000020,\n    TAPE_DRIVE_ERASE_BOP_ONLY   = 0x00000040,\n    TAPE_DRIVE_ERASE_IMMEDIATE  = 0x00000080,\n    TAPE_DRIVE_TAPE_CAPACITY    = 0x00000100,\n    TAPE_DRIVE_TAPE_REMAINING   = 0x00000200,\n    TAPE_DRIVE_FIXED_BLOCK      = 0x00000400,\n    TAPE_DRIVE_VARIABLE_BLOCK   = 0x00000800,\n    TAPE_DRIVE_WRITE_PROTECT    = 0x00001000,\n    TAPE_DRIVE_EOT_WZ_SIZE      = 0x00002000,\n    TAPE_DRIVE_ECC              = 0x00010000,\n    TAPE_DRIVE_COMPRESSION      = 0x00020000,\n    TAPE_DRIVE_PADDING          = 0x00040000,\n    TAPE_DRIVE_REPORT_SMKS      = 0x00080000,\n    TAPE_DRIVE_GET_ABSOLUTE_BLK = 0x00100000,\n    TAPE_DRIVE_GET_LOGICAL_BLK  = 0x00200000,\n    TAPE_DRIVE_SET_EOT_WZ_SIZE  = 0x00400000,\n    TAPE_DRIVE_EJECT_MEDIA      = 0x01000000,\n    TAPE_DRIVE_CLEAN_REQUESTS   = 0x02000000,\n    TAPE_DRIVE_SET_CMP_BOP_ONLY = 0x04000000,\n    TAPE_DRIVE_RESERVED_BIT     = 0x80000000;\n\nenum DWORD\n    TAPE_DRIVE_LOAD_UNLOAD      = 0x80000001,\n    TAPE_DRIVE_TENSION          = 0x80000002,\n    TAPE_DRIVE_LOCK_UNLOCK      = 0x80000004,\n    TAPE_DRIVE_REWIND_IMMEDIATE = 0x80000008,\n    TAPE_DRIVE_SET_BLOCK_SIZE   = 0x80000010,\n    TAPE_DRIVE_LOAD_UNLD_IMMED  = 0x80000020,\n    TAPE_DRIVE_TENSION_IMMED    = 0x80000040,\n    TAPE_DRIVE_LOCK_UNLK_IMMED  = 0x80000080,\n    TAPE_DRIVE_SET_ECC          = 0x80000100,\n    TAPE_DRIVE_SET_COMPRESSION  = 0x80000200,\n    TAPE_DRIVE_SET_PADDING      = 0x80000400,\n    TAPE_DRIVE_SET_REPORT_SMKS  = 0x80000800,\n    TAPE_DRIVE_ABSOLUTE_BLK     = 0x80001000,\n    TAPE_DRIVE_ABS_BLK_IMMED    = 0x80002000,\n    TAPE_DRIVE_LOGICAL_BLK      = 0x80004000,\n    TAPE_DRIVE_LOG_BLK_IMMED    = 0x80008000,\n    TAPE_DRIVE_END_OF_DATA      = 0x80010000,\n    TAPE_DRIVE_RELATIVE_BLKS    = 0x80020000,\n    TAPE_DRIVE_FILEMARKS        = 0x80040000,\n    TAPE_DRIVE_SEQUENTIAL_FMKS  = 0x80080000,\n    TAPE_DRIVE_SETMARKS         = 0x80100000,\n    TAPE_DRIVE_SEQUENTIAL_SMKS  = 0x80200000,\n    TAPE_DRIVE_REVERSE_POSITION = 0x80400000,\n    TAPE_DRIVE_SPACE_IMMEDIATE  = 0x80800000,\n    TAPE_DRIVE_WRITE_SETMARKS   = 0x81000000,\n    TAPE_DRIVE_WRITE_FILEMARKS  = 0x82000000,\n    TAPE_DRIVE_WRITE_SHORT_FMKS = 0x84000000,\n    TAPE_DRIVE_WRITE_LONG_FMKS  = 0x88000000,\n    TAPE_DRIVE_WRITE_MARK_IMMED = 0x90000000,\n    TAPE_DRIVE_FORMAT           = 0xA0000000,\n    TAPE_DRIVE_FORMAT_IMMEDIATE = 0xC0000000,\n    TAPE_DRIVE_HIGH_FEATURES    = 0x80000000;\n\nenum : DWORD {\n    TAPE_FIXED_PARTITIONS     = 0,\n    TAPE_SELECT_PARTITIONS    = 1,\n    TAPE_INITIATOR_PARTITIONS = 2\n}\n\nenum : DWORD {\n    TAPE_SETMARKS,\n    TAPE_FILEMARKS,\n    TAPE_SHORT_FILEMARKS,\n    TAPE_LONG_FILEMARKS\n}\n\nenum : DWORD {\n    TAPE_ERASE_SHORT,\n    TAPE_ERASE_LONG\n}\n\nenum : DWORD {\n    TAPE_LOAD,\n    TAPE_UNLOAD,\n    TAPE_TENSION,\n    TAPE_LOCK,\n    TAPE_UNLOCK,\n    TAPE_FORMAT\n}\n\nenum : ULONG32 {\n    VER_PLATFORM_WIN32s,\n    VER_PLATFORM_WIN32_WINDOWS,\n    VER_PLATFORM_WIN32_NT\n}\n\nenum : UCHAR {\n    VER_NT_WORKSTATION = 1,\n    VER_NT_DOMAIN_CONTROLLER,\n    VER_NT_SERVER\n}\n\nenum USHORT\n    VER_SUITE_SMALLBUSINESS            = 0x0001,\n    VER_SUITE_ENTERPRISE               = 0x0002,\n    VER_SUITE_BACKOFFICE               = 0x0004,\n    VER_SUITE_TERMINAL                 = 0x0010,\n    VER_SUITE_SMALLBUSINESS_RESTRICTED = 0x0020,\n    VER_SUITE_EMBEDDEDNT               = 0x0040,\n    VER_SUITE_DATACENTER               = 0x0080,\n    VER_SUITE_SINGLEUSERTS             = 0x0100,\n    VER_SUITE_PERSONAL                 = 0x0200,\n    VER_SUITE_BLADE                    = 0x0400,\n    VER_SUITE_STORAGE_SERVER           = 0x2000,\n    VER_SUITE_COMPUTE_SERVER           = 0x4000;\n\nenum ULONG\n    WT_EXECUTEDEFAULT            = 0x00000000,\n    WT_EXECUTEINIOTHREAD         = 0x00000001,\n    WT_EXECUTEINWAITTHREAD       = 0x00000004,\n    WT_EXECUTEONLYONCE           = 0x00000008,\n    WT_EXECUTELONGFUNCTION       = 0x00000010,\n    WT_EXECUTEINTIMERTHREAD      = 0x00000020,\n    WT_EXECUTEINPERSISTENTTHREAD = 0x00000080,\n    WT_TRANSFER_IMPERSONATION    = 0x00000100;\n\nstatic if (_WIN32_WINNT >= 0x500) {\nenum DWORD\n        VER_MINORVERSION     = 0x01,\n        VER_MAJORVERSION     = 0x02,\n        VER_BUILDNUMBER      = 0x04,\n        VER_PLATFORMID       = 0x08,\n        VER_SERVICEPACKMINOR = 0x10,\n        VER_SERVICEPACKMAJOR = 0x20,\n        VER_SUITENAME        = 0x40,\n        VER_PRODUCT_TYPE     = 0x80;\n\n    enum : DWORD {\n        VER_EQUAL = 1,\n        VER_GREATER,\n        VER_GREATER_EQUAL,\n        VER_LESS,\n        VER_LESS_EQUAL,\n        VER_AND,\n        VER_OR // = 7\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum : ULONG {\n        ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION       = 1,\n        ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,\n        ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION,\n        ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION,\n        ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,\n        ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION,\n        ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION, // = 7\n        ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES             = 9\n    }\n}\n\n// Macros\nBYTE BTYPE(BYTE x) { return cast(BYTE) (x & N_BTMASK); }\nbool ISPTR(uint x) { return (x & N_TMASK) == (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT); }\nbool ISFCN(uint x) { return (x & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT); }\nbool ISARY(uint x) { return (x & N_TMASK) == (IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT); }\nbool ISTAG(uint x) {\n    return x == IMAGE_SYM_CLASS_STRUCT_TAG\n        || x == IMAGE_SYM_CLASS_UNION_TAG\n        || x == IMAGE_SYM_CLASS_ENUM_TAG;\n}\nuint INCREF(uint x) {\n    return ((x & ~N_BTMASK) << N_TSHIFT) | (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT)\n      | (x & N_BTMASK);\n}\nuint DECREF(uint x) { return ((x >>> N_TSHIFT) & ~N_BTMASK) | (x & N_BTMASK); }\n\nenum DWORD TLS_MINIMUM_AVAILABLE = 64;\n\nenum ULONG\n    IO_REPARSE_TAG_RESERVED_ZERO  = 0,\n    IO_REPARSE_TAG_RESERVED_ONE   = 1,\n    IO_REPARSE_TAG_RESERVED_RANGE = IO_REPARSE_TAG_RESERVED_ONE,\n    IO_REPARSE_TAG_SYMBOLIC_LINK  = IO_REPARSE_TAG_RESERVED_ZERO,\n    IO_REPARSE_TAG_MOUNT_POINT    = 0xA0000003,\n    IO_REPARSE_TAG_SYMLINK        = 0xA000000C,\n    IO_REPARSE_TAG_VALID_VALUES   = 0xE000FFFF;\n\n/*  Although these are semantically boolean, they are documented and\n *  implemented to return ULONG; this behaviour is preserved for compatibility\n */\nULONG IsReparseTagMicrosoft(ULONG x)     { return x & 0x80000000; }\nULONG IsReparseTagHighLatency(ULONG x)   { return x & 0x40000000; }\nULONG IsReparseTagNameSurrogate(ULONG x) { return x & 0x20000000; }\n\nbool IsReparseTagValid(ULONG x) {\n    return !(x & ~IO_REPARSE_TAG_VALID_VALUES) && (x > IO_REPARSE_TAG_RESERVED_RANGE);\n}\n\n// Doesn't seem to make sense, but anyway....\nULONG WT_SET_MAX_THREADPOOL_THREADS(ref ULONG Flags, ushort Limit) {\n    return Flags |= Limit << 16;\n}\n\nimport core.sys.windows.basetyps;\n/* also in core.sys.windows.basetyps\nstruct GUID {\n    uint  Data1;\n    ushort Data2;\n    ushort Data3;\n    ubyte  Data4[8];\n}\nalias GUID* REFGUID, LPGUID;\n*/\n\nstruct GENERIC_MAPPING {\n    ACCESS_MASK GenericRead;\n    ACCESS_MASK GenericWrite;\n    ACCESS_MASK GenericExecute;\n    ACCESS_MASK GenericAll;\n}\nalias GENERIC_MAPPING* PGENERIC_MAPPING;\n\nstruct ACE_HEADER {\n    BYTE AceType;\n    BYTE AceFlags;\n    WORD AceSize;\n}\nalias ACE_HEADER* PACE_HEADER;\n\nstruct ACCESS_ALLOWED_ACE {\n    ACE_HEADER  Header;\n    ACCESS_MASK Mask;\n    DWORD       SidStart;\n}\nalias ACCESS_ALLOWED_ACE* PACCESS_ALLOWED_ACE;\n\nstruct ACCESS_DENIED_ACE {\n    ACE_HEADER  Header;\n    ACCESS_MASK Mask;\n    DWORD       SidStart;\n}\nalias ACCESS_DENIED_ACE* PACCESS_DENIED_ACE;\n\nstruct SYSTEM_AUDIT_ACE {\n    ACE_HEADER  Header;\n    ACCESS_MASK Mask;\n    DWORD       SidStart;\n}\nalias SYSTEM_AUDIT_ACE *PSYSTEM_AUDIT_ACE;\n\nstruct SYSTEM_ALARM_ACE {\n    ACE_HEADER  Header;\n    ACCESS_MASK Mask;\n    DWORD       SidStart;\n}\nalias SYSTEM_ALARM_ACE* PSYSTEM_ALARM_ACE;\n\nstruct ACCESS_ALLOWED_OBJECT_ACE {\n    ACE_HEADER  Header;\n    ACCESS_MASK Mask;\n    DWORD       Flags;\n    GUID        ObjectType;\n    GUID        InheritedObjectType;\n    DWORD       SidStart;\n}\nalias ACCESS_ALLOWED_OBJECT_ACE* PACCESS_ALLOWED_OBJECT_ACE;\n\nstruct ACCESS_DENIED_OBJECT_ACE {\n    ACE_HEADER  Header;\n    ACCESS_MASK Mask;\n    DWORD       Flags;\n    GUID        ObjectType;\n    GUID        InheritedObjectType;\n    DWORD       SidStart;\n}\nalias ACCESS_DENIED_OBJECT_ACE* PACCESS_DENIED_OBJECT_ACE;\n\nstruct SYSTEM_AUDIT_OBJECT_ACE {\n    ACE_HEADER  Header;\n    ACCESS_MASK Mask;\n    DWORD       Flags;\n    GUID        ObjectType;\n    GUID        InheritedObjectType;\n    DWORD       SidStart;\n}\nalias SYSTEM_AUDIT_OBJECT_ACE* PSYSTEM_AUDIT_OBJECT_ACE;\n\nstruct SYSTEM_ALARM_OBJECT_ACE {\n    ACE_HEADER  Header;\n    ACCESS_MASK Mask;\n    DWORD       Flags;\n    GUID        ObjectType;\n    GUID        InheritedObjectType;\n    DWORD       SidStart;\n}\nalias SYSTEM_ALARM_OBJECT_ACE* PSYSTEM_ALARM_OBJECT_ACE;\n\nstruct ACL {\n    BYTE AclRevision;\n    BYTE Sbz1;\n    WORD AclSize;\n    WORD AceCount;\n    WORD Sbz2;\n}\nalias ACL* PACL;\n\nstruct ACL_REVISION_INFORMATION {\n    DWORD AclRevision;\n}\n\nstruct ACL_SIZE_INFORMATION {\n    DWORD AceCount;\n    DWORD AclBytesInUse;\n    DWORD AclBytesFree;\n}\n\nversion (X86) {\n    // ???\nenum SIZE_OF_80387_REGISTERS     = 80;\nenum CONTEXT_i386                = 0x010000;\nenum CONTEXT_i486                = 0x010000;\nenum CONTEXT_CONTROL             = CONTEXT_i386 | 0x01;\nenum CONTEXT_INTEGER             = CONTEXT_i386 | 0x02;\nenum CONTEXT_SEGMENTS            = CONTEXT_i386 | 0x04;\nenum CONTEXT_FLOATING_POINT      = CONTEXT_i386 | 0x08;\nenum CONTEXT_DEBUG_REGISTERS     = CONTEXT_i386 | 0x10;\nenum CONTEXT_EXTENDED_REGISTERS  = CONTEXT_i386 | 0x20;\nenum CONTEXT_FULL                = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS;\nenum CONTEXT_ALL                 = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS |\n                                        CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS |\n                                        CONTEXT_EXTENDED_REGISTERS;\n\nenum MAXIMUM_SUPPORTED_EXTENSION = 512;\n\n    struct FLOATING_SAVE_AREA {\n        DWORD    ControlWord;\n        DWORD    StatusWord;\n        DWORD    TagWord;\n        DWORD    ErrorOffset;\n        DWORD    ErrorSelector;\n        DWORD    DataOffset;\n        DWORD    DataSelector;\n        BYTE[80] RegisterArea;\n        DWORD    Cr0NpxState;\n    }\n\n    struct CONTEXT {\n        DWORD ContextFlags;\n        DWORD Dr0;\n        DWORD Dr1;\n        DWORD Dr2;\n        DWORD Dr3;\n        DWORD Dr6;\n        DWORD Dr7;\n        FLOATING_SAVE_AREA FloatSave;\n        DWORD SegGs;\n        DWORD SegFs;\n        DWORD SegEs;\n        DWORD SegDs;\n        DWORD Edi;\n        DWORD Esi;\n        DWORD Ebx;\n        DWORD Edx;\n        DWORD Ecx;\n        DWORD Eax;\n        DWORD Ebp;\n        DWORD Eip;\n        DWORD SegCs;\n        DWORD EFlags;\n        DWORD Esp;\n        DWORD SegSs;\n        BYTE[MAXIMUM_SUPPORTED_EXTENSION] ExtendedRegisters;\n    }\n\n} else version (X86_64)\n{\nenum CONTEXT_AMD64 = 0x100000;\n\nenum CONTEXT_CONTROL         = (CONTEXT_AMD64 | 0x1L);\nenum CONTEXT_INTEGER         = (CONTEXT_AMD64 | 0x2L);\nenum CONTEXT_SEGMENTS        = (CONTEXT_AMD64 | 0x4L);\nenum CONTEXT_FLOATING_POINT  = (CONTEXT_AMD64 | 0x8L);\nenum CONTEXT_DEBUG_REGISTERS = (CONTEXT_AMD64 | 0x10L);\n\nenum CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT);\nenum CONTEXT_ALL  = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS);\n\nenum CONTEXT_EXCEPTION_ACTIVE    = 0x8000000;\nenum CONTEXT_SERVICE_ACTIVE      = 0x10000000;\nenum CONTEXT_EXCEPTION_REQUEST   = 0x40000000;\nenum CONTEXT_EXCEPTION_REPORTING = 0x80000000;\n\nenum INITIAL_MXCSR = 0x1f80;\nenum INITIAL_FPCSR = 0x027f;\n\n    align(16) struct M128A\n    {\n        ULONGLONG Low;\n        LONGLONG High;\n    }\n    alias M128A* PM128A;\n\n    struct XMM_SAVE_AREA32\n    {\n        WORD ControlWord;\n        WORD StatusWord;\n        BYTE TagWord;\n        BYTE Reserved1;\n        WORD ErrorOpcode;\n        DWORD ErrorOffset;\n        WORD ErrorSelector;\n        WORD Reserved2;\n        DWORD DataOffset;\n        WORD DataSelector;\n        WORD Reserved3;\n        DWORD MxCsr;\n        DWORD MxCsr_Mask;\n        M128A[8] FloatRegisters;\n        M128A[16] XmmRegisters;\n        BYTE[96] Reserved4;\n    }\n    alias XMM_SAVE_AREA32 PXMM_SAVE_AREA32;\nenum LEGACY_SAVE_AREA_LENGTH = XMM_SAVE_AREA32.sizeof;\n\n    align(16) struct CONTEXT\n    {\n        DWORD64 P1Home;\n        DWORD64 P2Home;\n        DWORD64 P3Home;\n        DWORD64 P4Home;\n        DWORD64 P5Home;\n        DWORD64 P6Home;\n        DWORD ContextFlags;\n        DWORD MxCsr;\n        WORD SegCs;\n        WORD SegDs;\n        WORD SegEs;\n        WORD SegFs;\n        WORD SegGs;\n        WORD SegSs;\n        DWORD EFlags;\n        DWORD64 Dr0;\n        DWORD64 Dr1;\n        DWORD64 Dr2;\n        DWORD64 Dr3;\n        DWORD64 Dr6;\n        DWORD64 Dr7;\n        DWORD64 Rax;\n        DWORD64 Rcx;\n        DWORD64 Rdx;\n        DWORD64 Rbx;\n        DWORD64 Rsp;\n        DWORD64 Rbp;\n        DWORD64 Rsi;\n        DWORD64 Rdi;\n        DWORD64 R8;\n        DWORD64 R9;\n        DWORD64 R10;\n        DWORD64 R11;\n        DWORD64 R12;\n        DWORD64 R13;\n        DWORD64 R14;\n        DWORD64 R15;\n        DWORD64 Rip;\n        union\n        {\n            XMM_SAVE_AREA32 FltSave;\n            XMM_SAVE_AREA32 FloatSave;\n            struct\n            {\n                M128A[2] Header;\n                M128A[8] Legacy;\n                M128A Xmm0;\n                M128A Xmm1;\n                M128A Xmm2;\n                M128A Xmm3;\n                M128A Xmm4;\n                M128A Xmm5;\n                M128A Xmm6;\n                M128A Xmm7;\n                M128A Xmm8;\n                M128A Xmm9;\n                M128A Xmm10;\n                M128A Xmm11;\n                M128A Xmm12;\n                M128A Xmm13;\n                M128A Xmm14;\n                M128A Xmm15;\n            };\n        };\n        M128A[26] VectorRegister;\n        DWORD64 VectorControl;\n        DWORD64 DebugControl;\n        DWORD64 LastBranchToRip;\n        DWORD64 LastBranchFromRip;\n        DWORD64 LastExceptionToRip;\n        DWORD64 LastExceptionFromRip;\n    }\n\n} else {\n    static assert(false, \"Unsupported CPU\");\n    // Versions for PowerPC, Alpha, SHX, and MIPS removed.\n}\n\nalias CONTEXT* PCONTEXT, LPCONTEXT;\n\nstruct EXCEPTION_RECORD {\n    DWORD ExceptionCode;\n    DWORD ExceptionFlags;\n    EXCEPTION_RECORD* ExceptionRecord;\n    PVOID ExceptionAddress;\n    DWORD NumberParameters;\n    ULONG_PTR[EXCEPTION_MAXIMUM_PARAMETERS] ExceptionInformation;\n}\nalias EXCEPTION_RECORD* PEXCEPTION_RECORD, LPEXCEPTION_RECORD;\n\nstruct EXCEPTION_POINTERS {\n    PEXCEPTION_RECORD ExceptionRecord;\n    PCONTEXT          ContextRecord;\n}\nalias EXCEPTION_POINTERS* PEXCEPTION_POINTERS, LPEXCEPTION_POINTERS;\n\nunion LARGE_INTEGER {\n    struct {\n        uint LowPart;\n        int  HighPart;\n    }\n    long QuadPart;\n}\nalias LARGE_INTEGER* PLARGE_INTEGER;\n\nunion ULARGE_INTEGER {\n    struct {\n        uint LowPart;\n        uint HighPart;\n    }\n    ulong QuadPart;\n}\nalias ULARGE_INTEGER* PULARGE_INTEGER;\n\nalias LARGE_INTEGER LUID;\nalias LUID* PLUID;\n\nenum LUID SYSTEM_LUID = { QuadPart:999 };\n\nalign(4) struct LUID_AND_ATTRIBUTES {\n    LUID  Luid;\n    DWORD Attributes;\n}\nalias LUID_AND_ATTRIBUTES* PLUID_AND_ATTRIBUTES;\n\nalign(4) struct PRIVILEGE_SET {\n    DWORD PrivilegeCount;\n    DWORD Control;\n    LUID_AND_ATTRIBUTES _Privilege;\n\n    LUID_AND_ATTRIBUTES* Privilege() return { return &_Privilege; }\n}\nalias PRIVILEGE_SET* PPRIVILEGE_SET;\n\nstruct SECURITY_ATTRIBUTES {\n    DWORD  nLength;\n    LPVOID lpSecurityDescriptor;\n    BOOL   bInheritHandle;\n}\nalias SECURITY_ATTRIBUTES* PSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES;\n\nstruct SECURITY_QUALITY_OF_SERVICE {\n    DWORD   Length;\n    SECURITY_IMPERSONATION_LEVEL   ImpersonationLevel;\n    SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;\n    BOOLEAN EffectiveOnly;\n}\nalias SECURITY_QUALITY_OF_SERVICE* PSECURITY_QUALITY_OF_SERVICE;\n\nalias PVOID PACCESS_TOKEN;\n\nstruct SE_IMPERSONATION_STATE {\n    PACCESS_TOKEN Token;\n    BOOLEAN       CopyOnOpen;\n    BOOLEAN       EffectiveOnly;\n    SECURITY_IMPERSONATION_LEVEL Level;\n}\nalias SE_IMPERSONATION_STATE* PSE_IMPERSONATION_STATE;\n\nstruct SID_IDENTIFIER_AUTHORITY {\n    BYTE[6] Value;\n}\nalias SID_IDENTIFIER_AUTHORITY* PSID_IDENTIFIER_AUTHORITY, LPSID_IDENTIFIER_AUTHORITY;\n\nalias PVOID PSID;\n\nstruct SID {\n    BYTE  Revision;\n    BYTE  SubAuthorityCount;\n    SID_IDENTIFIER_AUTHORITY IdentifierAuthority;\n    DWORD _SubAuthority;\n\n    DWORD* SubAuthority() return { return &_SubAuthority; }\n}\nalias SID* PISID;\n\nstruct SID_AND_ATTRIBUTES {\n    PSID  Sid;\n    DWORD Attributes;\n}\nalias SID_AND_ATTRIBUTES* PSID_AND_ATTRIBUTES;\n\nstruct TOKEN_SOURCE {\n    CHAR[TOKEN_SOURCE_LENGTH] SourceName;\n    LUID SourceIdentifier;\n}\nalias TOKEN_SOURCE* PTOKEN_SOURCE;\n\nstruct TOKEN_CONTROL {\n    LUID         TokenId;\n    LUID         AuthenticationId;\n    LUID         ModifiedId;\n    TOKEN_SOURCE TokenSource;\n}\nalias TOKEN_CONTROL* PTOKEN_CONTROL;\n\nstruct TOKEN_DEFAULT_DACL {\n    PACL DefaultDacl;\n}\nalias TOKEN_DEFAULT_DACL* PTOKEN_DEFAULT_DACL;\n\nstruct TOKEN_GROUPS {\n    DWORD GroupCount;\n    SID_AND_ATTRIBUTES _Groups;\n\n    SID_AND_ATTRIBUTES* Groups() return { return &_Groups; }\n}\nalias TOKEN_GROUPS* PTOKEN_GROUPS, LPTOKEN_GROUPS;\n\nstruct TOKEN_OWNER {\n    PSID Owner;\n}\nalias TOKEN_OWNER* PTOKEN_OWNER;\n\nstruct TOKEN_PRIMARY_GROUP {\n    PSID PrimaryGroup;\n}\nalias TOKEN_PRIMARY_GROUP* PTOKEN_PRIMARY_GROUP;\n\nstruct TOKEN_PRIVILEGES {\n    DWORD PrivilegeCount;\n    LUID_AND_ATTRIBUTES _Privileges;\n\n    LUID_AND_ATTRIBUTES* Privileges() return { return &_Privileges; }\n}\nalias TOKEN_PRIVILEGES* PTOKEN_PRIVILEGES, LPTOKEN_PRIVILEGES;\n\nenum TOKEN_TYPE {\n    TokenPrimary = 1,\n    TokenImpersonation\n}\nalias TOKEN_TYPE* PTOKEN_TYPE;\n\nstruct TOKEN_STATISTICS {\n    LUID          TokenId;\n    LUID          AuthenticationId;\n    LARGE_INTEGER ExpirationTime;\n    TOKEN_TYPE    TokenType;\n    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;\n    DWORD         DynamicCharged;\n    DWORD         DynamicAvailable;\n    DWORD         GroupCount;\n    DWORD         PrivilegeCount;\n    LUID          ModifiedId;\n}\nalias TOKEN_STATISTICS* PTOKEN_STATISTICS;\n\nstruct TOKEN_USER {\n    SID_AND_ATTRIBUTES User;\n}\nalias TOKEN_USER* PTOKEN_USER;\n\nalias DWORD SECURITY_INFORMATION;\nalias SECURITY_INFORMATION* PSECURITY_INFORMATION;\nalias WORD SECURITY_DESCRIPTOR_CONTROL;\nalias SECURITY_DESCRIPTOR_CONTROL* PSECURITY_DESCRIPTOR_CONTROL;\n\nstruct SECURITY_DESCRIPTOR {\n    BYTE Revision;\n    BYTE Sbz1;\n    SECURITY_DESCRIPTOR_CONTROL Control;\n    PSID Owner;\n    PSID Group;\n    PACL Sacl;\n    PACL Dacl;\n}\nalias SECURITY_DESCRIPTOR* PSECURITY_DESCRIPTOR, PISECURITY_DESCRIPTOR;\n\nenum TOKEN_INFORMATION_CLASS {\n    TokenUser = 1,\n    TokenGroups,\n    TokenPrivileges,\n    TokenOwner,\n    TokenPrimaryGroup,\n    TokenDefaultDacl,\n    TokenSource,\n    TokenType,\n    TokenImpersonationLevel,\n    TokenStatistics,\n    TokenRestrictedSids,\n    TokenSessionId,\n    TokenGroupsAndPrivileges,\n    TokenSessionReference,\n    TokenSandBoxInert,\n    TokenAuditPolicy,\n    TokenOrigin\n}\n\nenum SID_NAME_USE {\n    SidTypeUser = 1,\n    SidTypeGroup,\n    SidTypeDomain,\n    SidTypeAlias,\n    SidTypeWellKnownGroup,\n    SidTypeDeletedAccount,\n    SidTypeInvalid,\n    SidTypeUnknown,\n    SidTypeComputer\n}\nalias SID_NAME_USE* PSID_NAME_USE;\n\nstruct QUOTA_LIMITS {\n    SIZE_T PagedPoolLimit;\n    SIZE_T NonPagedPoolLimit;\n    SIZE_T MinimumWorkingSetSize;\n    SIZE_T MaximumWorkingSetSize;\n    SIZE_T PagefileLimit;\n    LARGE_INTEGER TimeLimit;\n}\nalias QUOTA_LIMITS* PQUOTA_LIMITS;\n\nstruct IO_COUNTERS {\n    ULONGLONG ReadOperationCount;\n    ULONGLONG WriteOperationCount;\n    ULONGLONG OtherOperationCount;\n    ULONGLONG ReadTransferCount;\n    ULONGLONG WriteTransferCount;\n    ULONGLONG OtherTransferCount;\n}\nalias IO_COUNTERS* PIO_COUNTERS;\n\nstruct FILE_NOTIFY_INFORMATION {\n    DWORD NextEntryOffset;\n    DWORD Action;\n    DWORD FileNameLength;\n    WCHAR _FileName;\n\n    WCHAR* FileName() return { return &_FileName; }\n}\nalias FILE_NOTIFY_INFORMATION* PFILE_NOTIFY_INFORMATION;\n\nstruct TAPE_ERASE {\n    DWORD   Type;\n    BOOLEAN Immediate;\n}\nalias TAPE_ERASE* PTAPE_ERASE;\n\nstruct TAPE_GET_DRIVE_PARAMETERS {\n    BOOLEAN ECC;\n    BOOLEAN Compression;\n    BOOLEAN DataPadding;\n    BOOLEAN ReportSetmarks;\n    DWORD   DefaultBlockSize;\n    DWORD   MaximumBlockSize;\n    DWORD   MinimumBlockSize;\n    DWORD   MaximumPartitionCount;\n    DWORD   FeaturesLow;\n    DWORD   FeaturesHigh;\n    DWORD   EOTWarningZoneSize;\n}\nalias TAPE_GET_DRIVE_PARAMETERS* PTAPE_GET_DRIVE_PARAMETERS;\n\nstruct TAPE_GET_MEDIA_PARAMETERS {\n    LARGE_INTEGER Capacity;\n    LARGE_INTEGER Remaining;\n    DWORD         BlockSize;\n    DWORD         PartitionCount;\n    BOOLEAN       WriteProtected;\n}\nalias TAPE_GET_MEDIA_PARAMETERS* PTAPE_GET_MEDIA_PARAMETERS;\n\nstruct TAPE_GET_POSITION {\n    ULONG Type;\n    ULONG Partition;\n    ULONG OffsetLow;\n    ULONG OffsetHigh;\n}\nalias TAPE_GET_POSITION* PTAPE_GET_POSITION;\n\nstruct TAPE_PREPARE {\n    DWORD   Operation;\n    BOOLEAN Immediate;\n}\nalias TAPE_PREPARE* PTAPE_PREPARE;\n\nstruct TAPE_SET_DRIVE_PARAMETERS {\n    BOOLEAN ECC;\n    BOOLEAN Compression;\n    BOOLEAN DataPadding;\n    BOOLEAN ReportSetmarks;\n    ULONG   EOTWarningZoneSize;\n}\nalias TAPE_SET_DRIVE_PARAMETERS* PTAPE_SET_DRIVE_PARAMETERS;\n\nstruct TAPE_SET_MEDIA_PARAMETERS {\n    ULONG BlockSize;\n}\nalias TAPE_SET_MEDIA_PARAMETERS* PTAPE_SET_MEDIA_PARAMETERS;\n\nstruct TAPE_SET_POSITION {\n    DWORD         Method;\n    DWORD         Partition;\n    LARGE_INTEGER Offset;\n    BOOLEAN       Immediate;\n}\nalias TAPE_SET_POSITION* PTAPE_SET_POSITION;\n\nstruct TAPE_WRITE_MARKS {\n    DWORD   Type;\n    DWORD   Count;\n    BOOLEAN Immediate;\n}\nalias TAPE_WRITE_MARKS* PTAPE_WRITE_MARKS;\n\nstruct TAPE_CREATE_PARTITION {\n    DWORD Method;\n    DWORD Count;\n    DWORD Size;\n}\nalias TAPE_CREATE_PARTITION* PTAPE_CREATE_PARTITION;\n\nstruct MEMORY_BASIC_INFORMATION {\n    PVOID BaseAddress;\n    PVOID AllocationBase;\n    DWORD AllocationProtect;\n    SIZE_T RegionSize;\n    DWORD State;\n    DWORD Protect;\n    DWORD Type;\n}\nalias MEMORY_BASIC_INFORMATION* PMEMORY_BASIC_INFORMATION;\n\nstruct MESSAGE_RESOURCE_ENTRY {\n    WORD Length;\n    WORD Flags;\n    BYTE _Text;\n\n    BYTE* Text() return { return &_Text; }\n}\nalias MESSAGE_RESOURCE_ENTRY* PMESSAGE_RESOURCE_ENTRY;\n\nstruct MESSAGE_RESOURCE_BLOCK {\n    DWORD LowId;\n    DWORD HighId;\n    DWORD OffsetToEntries;\n}\nalias MESSAGE_RESOURCE_BLOCK* PMESSAGE_RESOURCE_BLOCK;\n\nstruct MESSAGE_RESOURCE_DATA {\n    DWORD NumberOfBlocks;\n    MESSAGE_RESOURCE_BLOCK _Blocks;\n\n    MESSAGE_RESOURCE_BLOCK* Blocks() return { return &_Blocks; }\n}\nalias MESSAGE_RESOURCE_DATA* PMESSAGE_RESOURCE_DATA;\n\nstruct LIST_ENTRY {\n    LIST_ENTRY* Flink;\n    LIST_ENTRY* Blink;\n}\nalias LIST_ENTRY* PLIST_ENTRY;\nalias LIST_ENTRY _LIST_ENTRY;\n\nstruct SINGLE_LIST_ENTRY {\n    SINGLE_LIST_ENTRY* Next;\n}\n\nversion (Win64) {\n    align (16)\n    struct SLIST_ENTRY {\n        SLIST_ENTRY* Next;\n    }\n} else {\n    alias SINGLE_LIST_ENTRY SLIST_ENTRY;\n}\nalias SINGLE_LIST_ENTRY* PSINGLE_LIST_ENTRY, PSLIST_ENTRY;\n\nunion SLIST_HEADER {\n    ULONGLONG       Alignment;\n    struct {\n        SLIST_ENTRY Next;\n        WORD        Depth;\n        WORD        Sequence;\n    }\n}\nalias SLIST_HEADER* PSLIST_HEADER;\n\nstruct RTL_CRITICAL_SECTION_DEBUG {\n    WORD       Type;\n    WORD       CreatorBackTraceIndex;\n    RTL_CRITICAL_SECTION* CriticalSection;\n    LIST_ENTRY ProcessLocksList;\n    DWORD      EntryCount;\n    DWORD      ContentionCount;\n    DWORD[2]   Spare;\n}\nalias RTL_CRITICAL_SECTION_DEBUG* PRTL_CRITICAL_SECTION_DEBUG;\nalias RTL_CRITICAL_SECTION_DEBUG _RTL_CRITICAL_SECTION_DEBUG;\n\nstruct RTL_CRITICAL_SECTION {\n    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;\n    LONG   LockCount;\n    LONG   RecursionCount;\n    HANDLE OwningThread;\n    HANDLE LockSemaphore;\n    ULONG_PTR SpinCount;\n    alias Reserved = SpinCount;\n}\nalias RTL_CRITICAL_SECTION* PRTL_CRITICAL_SECTION;\nalias RTL_CRITICAL_SECTION _RTL_CRITICAL_SECTION;\n\nstruct EVENTLOGRECORD {\n    DWORD Length;\n    DWORD Reserved;\n    DWORD RecordNumber;\n    DWORD TimeGenerated;\n    DWORD TimeWritten;\n    DWORD EventID;\n    WORD  EventType;\n    WORD  NumStrings;\n    WORD  EventCategory;\n    WORD  ReservedFlags;\n    DWORD ClosingRecordNumber;\n    DWORD StringOffset;\n    DWORD UserSidLength;\n    DWORD UserSidOffset;\n    DWORD DataLength;\n    DWORD DataOffset;\n}\nalias EVENTLOGRECORD* PEVENTLOGRECORD;\n\nstruct OSVERSIONINFOA {\n    DWORD     dwOSVersionInfoSize = OSVERSIONINFOA.sizeof;\n    DWORD     dwMajorVersion;\n    DWORD     dwMinorVersion;\n    DWORD     dwBuildNumber;\n    DWORD     dwPlatformId;\n    CHAR[128] szCSDVersion;\n}\nalias OSVERSIONINFOA* POSVERSIONINFOA, LPOSVERSIONINFOA;\n\nstruct OSVERSIONINFOW {\n    DWORD      dwOSVersionInfoSize = OSVERSIONINFOW.sizeof;\n    DWORD      dwMajorVersion;\n    DWORD      dwMinorVersion;\n    DWORD      dwBuildNumber;\n    DWORD      dwPlatformId;\n    WCHAR[128] szCSDVersion;\n}\nalias OSVERSIONINFOW* POSVERSIONINFOW, LPOSVERSIONINFOW;\n\nstruct OSVERSIONINFOEXA {\n    DWORD     dwOSVersionInfoSize;\n    DWORD     dwMajorVersion;\n    DWORD     dwMinorVersion;\n    DWORD     dwBuildNumber;\n    DWORD     dwPlatformId;\n    CHAR[128] szCSDVersion;\n    WORD      wServicePackMajor;\n    WORD      wServicePackMinor;\n    WORD      wSuiteMask;\n    BYTE      wProductType;\n    BYTE      wReserved;\n}\nalias OSVERSIONINFOEXA* POSVERSIONINFOEXA, LPOSVERSIONINFOEXA;\n\nstruct OSVERSIONINFOEXW {\n    DWORD      dwOSVersionInfoSize;\n    DWORD      dwMajorVersion;\n    DWORD      dwMinorVersion;\n    DWORD      dwBuildNumber;\n    DWORD      dwPlatformId;\n    WCHAR[128] szCSDVersion;\n    WORD       wServicePackMajor;\n    WORD       wServicePackMinor;\n    WORD       wSuiteMask;\n    BYTE       wProductType;\n    BYTE       wReserved;\n}\nalias OSVERSIONINFOEXW* POSVERSIONINFOEXW, LPOSVERSIONINFOEXW;\n\nalign(2) struct IMAGE_VXD_HEADER {\n    WORD     e32_magic;\n    BYTE     e32_border;\n    BYTE     e32_worder;\n    DWORD    e32_level;\n    WORD     e32_cpu;\n    WORD     e32_os;\n    DWORD    e32_ver;\n    DWORD    e32_mflags;\n    DWORD    e32_mpages;\n    DWORD    e32_startobj;\n    DWORD    e32_eip;\n    DWORD    e32_stackobj;\n    DWORD    e32_esp;\n    DWORD    e32_pagesize;\n    DWORD    e32_lastpagesize;\n    DWORD    e32_fixupsize;\n    DWORD    e32_fixupsum;\n    DWORD    e32_ldrsize;\n    DWORD    e32_ldrsum;\n    DWORD    e32_objtab;\n    DWORD    e32_objcnt;\n    DWORD    e32_objmap;\n    DWORD    e32_itermap;\n    DWORD    e32_rsrctab;\n    DWORD    e32_rsrccnt;\n    DWORD    e32_restab;\n    DWORD    e32_enttab;\n    DWORD    e32_dirtab;\n    DWORD    e32_dircnt;\n    DWORD    e32_fpagetab;\n    DWORD    e32_frectab;\n    DWORD    e32_impmod;\n    DWORD    e32_impmodcnt;\n    DWORD    e32_impproc;\n    DWORD    e32_pagesum;\n    DWORD    e32_datapage;\n    DWORD    e32_preload;\n    DWORD    e32_nrestab;\n    DWORD    e32_cbnrestab;\n    DWORD    e32_nressum;\n    DWORD    e32_autodata;\n    DWORD    e32_debuginfo;\n    DWORD    e32_debuglen;\n    DWORD    e32_instpreload;\n    DWORD    e32_instdemand;\n    DWORD    e32_heapsize;\n    BYTE[12] e32_res3;\n    DWORD    e32_winresoff;\n    DWORD    e32_winreslen;\n    WORD     e32_devid;\n    WORD     e32_ddkver;\n}\nalias IMAGE_VXD_HEADER* PIMAGE_VXD_HEADER;\n\nalign(4):\nstruct IMAGE_FILE_HEADER {\n    WORD  Machine;\n    WORD  NumberOfSections;\n    DWORD TimeDateStamp;\n    DWORD PointerToSymbolTable;\n    DWORD NumberOfSymbols;\n    WORD  SizeOfOptionalHeader;\n    WORD  Characteristics;\n}\nalias IMAGE_FILE_HEADER* PIMAGE_FILE_HEADER;\n// const IMAGE_SIZEOF_FILE_HEADER = IMAGE_FILE_HEADER.sizeof;\n\nstruct IMAGE_DATA_DIRECTORY {\n    DWORD VirtualAddress;\n    DWORD Size;\n}\nalias IMAGE_DATA_DIRECTORY* PIMAGE_DATA_DIRECTORY;\n\nstruct IMAGE_OPTIONAL_HEADER32 {\n    WORD  Magic;\n    BYTE  MajorLinkerVersion;\n    BYTE  MinorLinkerVersion;\n    DWORD SizeOfCode;\n    DWORD SizeOfInitializedData;\n    DWORD SizeOfUninitializedData;\n    DWORD AddressOfEntryPoint;\n    DWORD BaseOfCode;\n    DWORD BaseOfData;\n    DWORD ImageBase;\n    DWORD SectionAlignment;\n    DWORD FileAlignment;\n    WORD  MajorOperatingSystemVersion;\n    WORD  MinorOperatingSystemVersion;\n    WORD  MajorImageVersion;\n    WORD  MinorImageVersion;\n    WORD  MajorSubsystemVersion;\n    WORD  MinorSubsystemVersion;\n    DWORD Win32VersionValue;\n    DWORD SizeOfImage;\n    DWORD SizeOfHeaders;\n    DWORD CheckSum;\n    WORD  Subsystem;\n    WORD  DllCharacteristics;\n    DWORD SizeOfStackReserve;\n    DWORD SizeOfStackCommit;\n    DWORD SizeOfHeapReserve;\n    DWORD SizeOfHeapCommit;\n    DWORD LoaderFlags;\n    DWORD NumberOfRvaAndSizes;\n    IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] DataDirectory;\n}\nalias IMAGE_OPTIONAL_HEADER32* PIMAGE_OPTIONAL_HEADER32;\n\nstruct IMAGE_OPTIONAL_HEADER64 {\n    WORD      Magic;\n    BYTE      MajorLinkerVersion;\n    BYTE      MinorLinkerVersion;\n    DWORD     SizeOfCode;\n    DWORD     SizeOfInitializedData;\n    DWORD     SizeOfUninitializedData;\n    DWORD     AddressOfEntryPoint;\n    DWORD     BaseOfCode;\n    ULONGLONG ImageBase;\n    DWORD     SectionAlignment;\n    DWORD     FileAlignment;\n    WORD      MajorOperatingSystemVersion;\n    WORD      MinorOperatingSystemVersion;\n    WORD      MajorImageVersion;\n    WORD      MinorImageVersion;\n    WORD      MajorSubsystemVersion;\n    WORD      MinorSubsystemVersion;\n    DWORD     Win32VersionValue;\n    DWORD     SizeOfImage;\n    DWORD     SizeOfHeaders;\n    DWORD     CheckSum;\n    WORD      Subsystem;\n    WORD      DllCharacteristics;\n    ULONGLONG SizeOfStackReserve;\n    ULONGLONG SizeOfStackCommit;\n    ULONGLONG SizeOfHeapReserve;\n    ULONGLONG SizeOfHeapCommit;\n    DWORD     LoaderFlags;\n    DWORD     NumberOfRvaAndSizes;\n    IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] DataDirectory;\n}\nalias IMAGE_OPTIONAL_HEADER64* PIMAGE_OPTIONAL_HEADER64;\n\nstruct IMAGE_ROM_OPTIONAL_HEADER {\n    WORD     Magic;\n    BYTE     MajorLinkerVersion;\n    BYTE     MinorLinkerVersion;\n    DWORD    SizeOfCode;\n    DWORD    SizeOfInitializedData;\n    DWORD    SizeOfUninitializedData;\n    DWORD    AddressOfEntryPoint;\n    DWORD    BaseOfCode;\n    DWORD    BaseOfData;\n    DWORD    BaseOfBss;\n    DWORD    GprMask;\n    DWORD[4] CprMask;\n    DWORD    GpValue;\n}\nalias IMAGE_ROM_OPTIONAL_HEADER* PIMAGE_ROM_OPTIONAL_HEADER;\n\nalign(2):\nstruct IMAGE_DOS_HEADER {\n    WORD     e_magic;\n    WORD     e_cblp;\n    WORD     e_cp;\n    WORD     e_crlc;\n    WORD     e_cparhdr;\n    WORD     e_minalloc;\n    WORD     e_maxalloc;\n    WORD     e_ss;\n    WORD     e_sp;\n    WORD     e_csum;\n    WORD     e_ip;\n    WORD     e_cs;\n    WORD     e_lfarlc;\n    WORD     e_ovno;\n    WORD[4] e_res;\n    WORD     e_oemid;\n    WORD     e_oeminfo;\n    WORD[10] e_res2;\n    LONG     e_lfanew;\n}\nalias IMAGE_DOS_HEADER* PIMAGE_DOS_HEADER;\n\nstruct IMAGE_OS2_HEADER {\n    WORD ne_magic;\n    CHAR ne_ver;\n    CHAR ne_rev;\n    WORD ne_enttab;\n    WORD ne_cbenttab;\n    LONG ne_crc;\n    WORD ne_flags;\n    WORD ne_autodata;\n    WORD ne_heap;\n    WORD ne_stack;\n    LONG ne_csip;\n    LONG ne_sssp;\n    WORD ne_cseg;\n    WORD ne_cmod;\n    WORD ne_cbnrestab;\n    WORD ne_segtab;\n    WORD ne_rsrctab;\n    WORD ne_restab;\n    WORD ne_modtab;\n    WORD ne_imptab;\n    LONG ne_nrestab;\n    WORD ne_cmovent;\n    WORD ne_align;\n    WORD ne_cres;\n    BYTE ne_exetyp;\n    BYTE ne_flagsothers;\n    WORD ne_pretthunks;\n    WORD ne_psegrefbytes;\n    WORD ne_swaparea;\n    WORD ne_expver;\n}\nalias IMAGE_OS2_HEADER* PIMAGE_OS2_HEADER;\n\nalign(4) struct IMAGE_NT_HEADERS32 {\n    DWORD                 Signature;\n    IMAGE_FILE_HEADER     FileHeader;\n    IMAGE_OPTIONAL_HEADER32 OptionalHeader;\n}\nalias IMAGE_NT_HEADERS32* PIMAGE_NT_HEADERS32;\n\nalign(4) struct IMAGE_NT_HEADERS64 {\n    DWORD                 Signature;\n    IMAGE_FILE_HEADER     FileHeader;\n    IMAGE_OPTIONAL_HEADER64 OptionalHeader;\n}\nalias IMAGE_NT_HEADERS64* PIMAGE_NT_HEADERS64;\n\nstruct IMAGE_ROM_HEADERS {\n    IMAGE_FILE_HEADER         FileHeader;\n    IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;\n}\nalias IMAGE_ROM_HEADERS* PIMAGE_ROM_HEADERS;\n\nstruct IMAGE_SECTION_HEADER {\n    BYTE[IMAGE_SIZEOF_SHORT_NAME] Name;\n    union _Misc {\n        DWORD PhysicalAddress;\n        DWORD VirtualSize;\n    }\n    _Misc Misc;\n    DWORD VirtualAddress;\n    DWORD SizeOfRawData;\n    DWORD PointerToRawData;\n    DWORD PointerToRelocations;\n    DWORD PointerToLinenumbers;\n    WORD  NumberOfRelocations;\n    WORD  NumberOfLinenumbers;\n    DWORD Characteristics;\n}\nalias IMAGE_SECTION_HEADER* PIMAGE_SECTION_HEADER;\n\nstruct IMAGE_SYMBOL {\n    union _N {\n        BYTE[8]   ShortName;\n        struct _Name {\n            DWORD Short;\n            DWORD Long;\n        }\n        _Name Name;\n        DWORD[2]  LongName; // PBYTE[2]\n    }\n    _N    N;\n    DWORD Value;\n    SHORT SectionNumber;\n    WORD  Type;\n    BYTE  StorageClass;\n    BYTE  NumberOfAuxSymbols;\n}\nalias IMAGE_SYMBOL* PIMAGE_SYMBOL;\n\nunion IMAGE_AUX_SYMBOL {\n    struct _Sym {\n        DWORD           TagIndex;\n        union _Misc {\n            struct _LnSz {\n                WORD    Linenumber;\n                WORD    Size;\n            }\n            _LnSz       LnSz;\n            DWORD       TotalSize;\n        }\n        _Misc Misc;\n        union _FcnAry {\n            struct _Function {\n                DWORD   PointerToLinenumber;\n                DWORD   PointerToNextFunction;\n            }\n            _Function   Function;\n            struct _Array {\n                WORD[4] Dimension;\n            }\n            _Array      Array;\n        }\n        _FcnAry         FcnAry;\n        WORD            TvIndex;\n    }\n    _Sym                Sym;\n    struct _File {\n        BYTE[IMAGE_SIZEOF_SYMBOL] Name;\n    }\n    _File               File;\n    struct _Section {\n        DWORD           Length;\n        WORD            NumberOfRelocations;\n        WORD            NumberOfLinenumbers;\n        DWORD           CheckSum;\n        SHORT           Number;\n        BYTE            Selection;\n    }\n    _Section            Section;\n}\nalias IMAGE_AUX_SYMBOL* PIMAGE_AUX_SYMBOL;\n\nstruct IMAGE_COFF_SYMBOLS_HEADER {\n    DWORD NumberOfSymbols;\n    DWORD LvaToFirstSymbol;\n    DWORD NumberOfLinenumbers;\n    DWORD LvaToFirstLinenumber;\n    DWORD RvaToFirstByteOfCode;\n    DWORD RvaToLastByteOfCode;\n    DWORD RvaToFirstByteOfData;\n    DWORD RvaToLastByteOfData;\n}\nalias IMAGE_COFF_SYMBOLS_HEADER* PIMAGE_COFF_SYMBOLS_HEADER;\n\nstruct IMAGE_RELOCATION {\n    union {\n        DWORD VirtualAddress;\n        DWORD RelocCount;\n    }\n    DWORD     SymbolTableIndex;\n    WORD      Type;\n}\nalias IMAGE_RELOCATION* PIMAGE_RELOCATION;\n\nalign(4) struct IMAGE_BASE_RELOCATION {\n    DWORD VirtualAddress;\n    DWORD SizeOfBlock;\n}\nalias IMAGE_BASE_RELOCATION* PIMAGE_BASE_RELOCATION;\n\nalign(2) struct IMAGE_LINENUMBER {\n    union _Type {\n        DWORD SymbolTableIndex;\n        DWORD VirtualAddress;\n    }\n    _Type Type;\n    WORD  Linenumber;\n}\nalias IMAGE_LINENUMBER* PIMAGE_LINENUMBER;\n\nalign(4):\nstruct IMAGE_ARCHIVE_MEMBER_HEADER {\n    BYTE[16] Name;\n    BYTE[12] Date;\n    BYTE[6]  UserID;\n    BYTE[6]  GroupID;\n    BYTE[8]  Mode;\n    BYTE[10] Size;\n    BYTE[2]  EndHeader;\n}\nalias IMAGE_ARCHIVE_MEMBER_HEADER* PIMAGE_ARCHIVE_MEMBER_HEADER;\n\nstruct IMAGE_EXPORT_DIRECTORY {\n    DWORD Characteristics;\n    DWORD TimeDateStamp;\n    WORD  MajorVersion;\n    WORD  MinorVersion;\n    DWORD Name;\n    DWORD Base;\n    DWORD NumberOfFunctions;\n    DWORD NumberOfNames;\n    DWORD AddressOfFunctions;\n    DWORD AddressOfNames;\n    DWORD AddressOfNameOrdinals;\n}\nalias IMAGE_EXPORT_DIRECTORY* PIMAGE_EXPORT_DIRECTORY;\n\nstruct IMAGE_IMPORT_BY_NAME {\n    WORD Hint;\n    BYTE _Name;\n\n    BYTE* Name() return { return &_Name; }\n}\nalias IMAGE_IMPORT_BY_NAME* PIMAGE_IMPORT_BY_NAME;\n\nstruct IMAGE_THUNK_DATA32 {\n    union _u1 {\n        DWORD ForwarderString;\n        DWORD Function;\n        DWORD Ordinal;\n        DWORD AddressOfData;\n    }\n    _u1 u1;\n}\nalias IMAGE_THUNK_DATA32* PIMAGE_THUNK_DATA32;\n\nstruct IMAGE_THUNK_DATA64 {\n    union _u1 {\n        ULONGLONG ForwarderString;\n        ULONGLONG Function;\n        ULONGLONG Ordinal;\n        ULONGLONG AddressOfData;\n    }\n    _u1 u1;\n}\nalias IMAGE_THUNK_DATA64* PIMAGE_THUNK_DATA64;\n\nstruct IMAGE_IMPORT_DESCRIPTOR {\n    union {\n        DWORD Characteristics;\n        DWORD OriginalFirstThunk;\n    }\n    DWORD TimeDateStamp;\n    DWORD ForwarderChain;\n    DWORD Name;\n    DWORD FirstThunk;\n}\nalias IMAGE_IMPORT_DESCRIPTOR* PIMAGE_IMPORT_DESCRIPTOR;\n\nstruct IMAGE_BOUND_IMPORT_DESCRIPTOR {\n    DWORD TimeDateStamp;\n    WORD  OffsetModuleName;\n    WORD  NumberOfModuleForwarderRefs;\n}\nalias IMAGE_BOUND_IMPORT_DESCRIPTOR* PIMAGE_BOUND_IMPORT_DESCRIPTOR;\n\nstruct IMAGE_BOUND_FORWARDER_REF {\n    DWORD TimeDateStamp;\n    WORD  OffsetModuleName;\n    WORD  Reserved;\n}\nalias IMAGE_BOUND_FORWARDER_REF* PIMAGE_BOUND_FORWARDER_REF;\n\nstruct IMAGE_TLS_DIRECTORY32 {\n    DWORD StartAddressOfRawData;\n    DWORD EndAddressOfRawData;\n    DWORD AddressOfIndex;\n    DWORD AddressOfCallBacks;\n    DWORD SizeOfZeroFill;\n    DWORD Characteristics;\n}\nalias IMAGE_TLS_DIRECTORY32* PIMAGE_TLS_DIRECTORY32;\n\nstruct IMAGE_TLS_DIRECTORY64 {\n    ULONGLONG StartAddressOfRawData;\n    ULONGLONG EndAddressOfRawData;\n    ULONGLONG AddressOfIndex;\n    ULONGLONG AddressOfCallBacks;\n    DWORD     SizeOfZeroFill;\n    DWORD     Characteristics;\n}\nalias IMAGE_TLS_DIRECTORY64* PIMAGE_TLS_DIRECTORY64;\n\nstruct IMAGE_RESOURCE_DIRECTORY {\n    DWORD Characteristics;\n    DWORD TimeDateStamp;\n    WORD  MajorVersion;\n    WORD  MinorVersion;\n    WORD  NumberOfNamedEntries;\n    WORD  NumberOfIdEntries;\n}\nalias IMAGE_RESOURCE_DIRECTORY* PIMAGE_RESOURCE_DIRECTORY;\n\nstruct IMAGE_RESOURCE_DIRECTORY_ENTRY {\n    union {\n        /+struct {\n            DWORD NameOffset:31;\n            DWORD NameIsString:1;\n        }+/\n        DWORD Name;\n        WORD Id;\n    }\n    DWORD OffsetToData;\n        /+struct {\n            DWORD OffsetToDirectory:31;\n            DWORD DataIsDirectory:1;\n        }+/\n\n    uint NameOffset()        { return Name & 0x7FFFFFFF; }\n    bool NameIsString()      { return cast(bool)(Name & 0x80000000); }\n    uint OffsetToDirectory() { return OffsetToData & 0x7FFFFFFF; }\n    bool DataIsDirectory()   { return cast(bool)(OffsetToData & 0x80000000); }\n\n    uint NameOffset(uint n) {\n        Name = (Name & 0x80000000) | (n & 0x7FFFFFFF);\n        return n & 0x7FFFFFFF;\n    }\n\n    bool NameIsString(bool n) {\n        Name = (Name & 0x7FFFFFFF) | (n << 31); return n;\n    }\n\n    uint OffsetToDirectory(uint o) {\n        OffsetToData = (OffsetToData & 0x80000000) | (o & 0x7FFFFFFF);\n        return o & 0x7FFFFFFF;\n    }\n\n    bool DataIsDirectory(bool d) {\n        OffsetToData = (OffsetToData & 0x7FFFFFFF) | (d << 31); return d;\n    }\n}\nalias IMAGE_RESOURCE_DIRECTORY_ENTRY* PIMAGE_RESOURCE_DIRECTORY_ENTRY;\n\nstruct IMAGE_RESOURCE_DIRECTORY_STRING {\n    WORD Length;\n    CHAR _NameString;\n\n    CHAR* NameString() return { return &_NameString; }\n}\nalias IMAGE_RESOURCE_DIRECTORY_STRING* PIMAGE_RESOURCE_DIRECTORY_STRING;\n\nstruct IMAGE_RESOURCE_DIR_STRING_U {\n    WORD  Length;\n    WCHAR _NameString;\n\n    WCHAR* NameString() return { return &_NameString; }\n}\nalias IMAGE_RESOURCE_DIR_STRING_U* PIMAGE_RESOURCE_DIR_STRING_U;\n\nstruct IMAGE_RESOURCE_DATA_ENTRY {\n    DWORD OffsetToData;\n    DWORD Size;\n    DWORD CodePage;\n    DWORD Reserved;\n}\nalias IMAGE_RESOURCE_DATA_ENTRY* PIMAGE_RESOURCE_DATA_ENTRY;\n\nstruct IMAGE_LOAD_CONFIG_DIRECTORY32 {\n    DWORD    Characteristics;\n    DWORD    TimeDateStamp;\n    WORD     MajorVersion;\n    WORD     MinorVersion;\n    DWORD    GlobalFlagsClear;\n    DWORD    GlobalFlagsSet;\n    DWORD    CriticalSectionDefaultTimeout;\n    DWORD    DeCommitFreeBlockThreshold;\n    DWORD    DeCommitTotalFreeThreshold;\n    PVOID    LockPrefixTable;\n    DWORD    MaximumAllocationSize;\n    DWORD    VirtualMemoryThreshold;\n    DWORD    ProcessHeapFlags;\n    DWORD[4] Reserved;\n}\nalias IMAGE_LOAD_CONFIG_DIRECTORY32* PIMAGE_LOAD_CONFIG_DIRECTORY32;\n\nstruct IMAGE_LOAD_CONFIG_DIRECTORY64 {\n    DWORD     Characteristics;\n    DWORD     TimeDateStamp;\n    WORD      MajorVersion;\n    WORD      MinorVersion;\n    DWORD     GlobalFlagsClear;\n    DWORD     GlobalFlagsSet;\n    DWORD     CriticalSectionDefaultTimeout;\n    ULONGLONG DeCommitFreeBlockThreshold;\n    ULONGLONG DeCommitTotalFreeThreshold;\n    ULONGLONG LockPrefixTable;\n    ULONGLONG MaximumAllocationSize;\n    ULONGLONG VirtualMemoryThreshold;\n    ULONGLONG ProcessAffinityMask;\n    DWORD     ProcessHeapFlags;\n    WORD      CSDFlags;\n    WORD      Reserved1;\n    ULONGLONG EditList;\n    DWORD[2]  Reserved;\n}\nalias IMAGE_LOAD_CONFIG_DIRECTORY64* PIMAGE_LOAD_CONFIG_DIRECTORY64;\n\nversion (Win64) {\n    alias IMAGE_LOAD_CONFIG_DIRECTORY64 IMAGE_LOAD_CONFIG_DIRECTORY;\n} else {\n    alias IMAGE_LOAD_CONFIG_DIRECTORY32 IMAGE_LOAD_CONFIG_DIRECTORY;\n}\nalias IMAGE_LOAD_CONFIG_DIRECTORY* PIMAGE_LOAD_CONFIG_DIRECTORY;\n\n// Note versions for Alpha, Alpha64, ARM removed.\nstruct IMAGE_RUNTIME_FUNCTION_ENTRY {\n    DWORD BeginAddress;\n    DWORD EndAddress;\n    union {\n        DWORD UnwindInfoAddress;\n        DWORD UnwindData;\n    }\n}\nalias IMAGE_RUNTIME_FUNCTION_ENTRY* PIMAGE_RUNTIME_FUNCTION_ENTRY;\n\nstruct IMAGE_CE_RUNTIME_FUNCTION_ENTRY {\n    uint      FuncStart;\n    union {\n        ubyte PrologLen;\n        uint  _bf;\n    }\n/+\n    unsigned int FuncLen:22;\n    unsigned int ThirtyTwoBit:1;\n    unsigned int ExceptionFlag:1;\n+/\n    uint FuncLen()       { return (_bf >> 8) & 0x3FFFFF; }\n    bool ThirtyTwoBit()  { return cast(bool)(_bf & 0x40000000); }\n    bool ExceptionFlag() { return cast(bool)(_bf & 0x80000000); }\n\n    uint FuncLen(uint f) {\n        _bf = (_bf & ~0x3FFFFF00) | ((f & 0x3FFFFF) << 8); return f & 0x3FFFFF;\n    }\n\n    bool ThirtyTwoBit(bool t) {\n        _bf = (_bf & ~0x40000000) | (t << 30); return t;\n    }\n\n    bool ExceptionFlag(bool e) {\n        _bf = (_bf & ~0x80000000) | (e << 31); return e;\n    }\n}\nalias IMAGE_CE_RUNTIME_FUNCTION_ENTRY* PIMAGE_CE_RUNTIME_FUNCTION_ENTRY;\n\nstruct IMAGE_DEBUG_DIRECTORY {\n    DWORD Characteristics;\n    DWORD TimeDateStamp;\n    WORD  MajorVersion;\n    WORD  MinorVersion;\n    DWORD Type;\n    DWORD SizeOfData;\n    DWORD AddressOfRawData;\n    DWORD PointerToRawData;\n}\nalias IMAGE_DEBUG_DIRECTORY* PIMAGE_DEBUG_DIRECTORY;\n\nstruct FPO_DATA {\n    DWORD  ulOffStart;\n    DWORD  cbProcSize;\n    DWORD  cdwLocals;\n    WORD   cdwParams;\n    ubyte  cbProlog;\n    ubyte  _bf;\n/+\n    WORD cbRegs:3;\n    WORD fHasSEH:1;\n    WORD fUseBP:1;\n    WORD reserved:1;\n    WORD cbFrame:2;\n+/\n    ubyte cbRegs()  { return cast(ubyte)(_bf & 0x07); }\n    bool fHasSEH()  { return cast(bool)(_bf & 0x08); }\n    bool fUseBP()   { return cast(bool)(_bf & 0x10); }\n    bool reserved() { return cast(bool)(_bf & 0x20); }\n    ubyte cbFrame() { return cast(ubyte)(_bf >> 6); }\n\n    ubyte cbRegs(ubyte c) {\n        _bf = cast(ubyte) ((_bf & ~0x07) | (c & 0x07));\n        return cast(ubyte)(c & 0x07);\n    }\n\n    bool fHasSEH(bool f)  { _bf = cast(ubyte)((_bf & ~0x08) | (f << 3)); return f; }\n    bool fUseBP(bool f)   { _bf = cast(ubyte)((_bf & ~0x10) | (f << 4)); return f; }\n    bool reserved(bool r) { _bf = cast(ubyte)((_bf & ~0x20) | (r << 5)); return r; }\n\n    ubyte cbFrame(ubyte c) {\n        _bf = cast(ubyte) ((_bf & ~0xC0) | ((c & 0x03) << 6));\n        return cast(ubyte)(c & 0x03);\n    }\n}\nalias FPO_DATA* PFPO_DATA;\n\nstruct IMAGE_DEBUG_MISC {\n    DWORD   DataType;\n    DWORD   Length;\n    BOOLEAN Unicode;\n    BYTE[3] Reserved;\n    BYTE    _Data;\n\n    BYTE*   Data() return { return &_Data; }\n}\nalias IMAGE_DEBUG_MISC* PIMAGE_DEBUG_MISC;\n\nstruct IMAGE_FUNCTION_ENTRY {\n    DWORD StartingAddress;\n    DWORD EndingAddress;\n    DWORD EndOfPrologue;\n}\nalias IMAGE_FUNCTION_ENTRY* PIMAGE_FUNCTION_ENTRY;\n\nstruct IMAGE_FUNCTION_ENTRY64 {\n    ULONGLONG     StartingAddress;\n    ULONGLONG     EndingAddress;\n    union {\n        ULONGLONG EndOfPrologue;\n        ULONGLONG UnwindInfoAddress;\n    }\n}\nalias IMAGE_FUNCTION_ENTRY64* PIMAGE_FUNCTION_ENTRY64;\n\nstruct IMAGE_SEPARATE_DEBUG_HEADER {\n    WORD     Signature;\n    WORD     Flags;\n    WORD     Machine;\n    WORD     Characteristics;\n    DWORD    TimeDateStamp;\n    DWORD    CheckSum;\n    DWORD    ImageBase;\n    DWORD    SizeOfImage;\n    DWORD    NumberOfSections;\n    DWORD    ExportedNamesSize;\n    DWORD    DebugDirectorySize;\n    DWORD    SectionAlignment;\n    DWORD[2] Reserved;\n}\nalias IMAGE_SEPARATE_DEBUG_HEADER* PIMAGE_SEPARATE_DEBUG_HEADER;\n\nenum SERVICE_NODE_TYPE {\n    DriverType               = SERVICE_KERNEL_DRIVER,\n    FileSystemType           = SERVICE_FILE_SYSTEM_DRIVER,\n    Win32ServiceOwnProcess   = SERVICE_WIN32_OWN_PROCESS,\n    Win32ServiceShareProcess = SERVICE_WIN32_SHARE_PROCESS,\n    AdapterType              = SERVICE_ADAPTER,\n    RecognizerType           = SERVICE_RECOGNIZER_DRIVER\n}\n\nenum SERVICE_LOAD_TYPE {\n    BootLoad    = SERVICE_BOOT_START,\n    SystemLoad  = SERVICE_SYSTEM_START,\n    AutoLoad    = SERVICE_AUTO_START,\n    DemandLoad  = SERVICE_DEMAND_START,\n    DisableLoad = SERVICE_DISABLED\n}\n\nenum SERVICE_ERROR_TYPE {\n    IgnoreError   = SERVICE_ERROR_IGNORE,\n    NormalError   = SERVICE_ERROR_NORMAL,\n    SevereError   = SERVICE_ERROR_SEVERE,\n    CriticalError = SERVICE_ERROR_CRITICAL\n}\nalias SERVICE_ERROR_TYPE _CM_ERROR_CONTROL_TYPE;\n\n//DAC: According to MSJ, 'UnderTheHood', May 1996, this\n// structure is not documented in any official Microsoft header file.\nalias void EXCEPTION_REGISTRATION_RECORD;\n\nalign:\nstruct NT_TIB {\n    EXCEPTION_REGISTRATION_RECORD *ExceptionList;\n    PVOID StackBase;\n    PVOID StackLimit;\n    PVOID SubSystemTib;\n    union {\n        PVOID FiberData;\n        DWORD Version;\n    }\n    PVOID ArbitraryUserPointer;\n    NT_TIB *Self;\n}\nalias NT_TIB* PNT_TIB;\n\nstruct REPARSE_DATA_BUFFER {\n    DWORD  ReparseTag;\n    WORD   ReparseDataLength;\n    WORD   Reserved;\n    union {\n        struct _GenericReparseBuffer {\n            BYTE  _DataBuffer;\n\n            BYTE* DataBuffer() return { return &_DataBuffer; }\n        }\n        _GenericReparseBuffer GenericReparseBuffer;\n        struct _SymbolicLinkReparseBuffer {\n            WORD  SubstituteNameOffset;\n            WORD  SubstituteNameLength;\n            WORD  PrintNameOffset;\n            WORD  PrintNameLength;\n            // ??? This is in MinGW, but absent in MSDN docs\n            ULONG Flags;\n            WCHAR _PathBuffer;\n\n            WCHAR* PathBuffer() return { return &_PathBuffer; }\n        }\n        _SymbolicLinkReparseBuffer SymbolicLinkReparseBuffer;\n        struct _MountPointReparseBuffer {\n            WORD  SubstituteNameOffset;\n            WORD  SubstituteNameLength;\n            WORD  PrintNameOffset;\n            WORD  PrintNameLength;\n            WCHAR _PathBuffer;\n\n            WCHAR* PathBuffer() return { return &_PathBuffer; }\n        }\n        _MountPointReparseBuffer MountPointReparseBuffer;\n    }\n}\nalias REPARSE_DATA_BUFFER *PREPARSE_DATA_BUFFER;\n\nstruct REPARSE_GUID_DATA_BUFFER {\n    DWORD    ReparseTag;\n    WORD     ReparseDataLength;\n    WORD     Reserved;\n    GUID     ReparseGuid;\n    struct _GenericReparseBuffer {\n        BYTE _DataBuffer;\n\n        BYTE* DataBuffer() return { return &_DataBuffer; }\n    }\n    _GenericReparseBuffer GenericReparseBuffer;\n}\nalias REPARSE_GUID_DATA_BUFFER* PREPARSE_GUID_DATA_BUFFER;\n\nenum size_t\n    REPARSE_DATA_BUFFER_HEADER_SIZE = REPARSE_DATA_BUFFER.GenericReparseBuffer.offsetof,\n    REPARSE_GUID_DATA_BUFFER_HEADER_SIZE = REPARSE_GUID_DATA_BUFFER.GenericReparseBuffer.offsetof,\n    MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384;\n\n\nstruct REPARSE_POINT_INFORMATION {\n    WORD ReparseDataLength;\n    WORD UnparsedNameLength;\n}\nalias REPARSE_POINT_INFORMATION* PREPARSE_POINT_INFORMATION;\n\nunion FILE_SEGMENT_ELEMENT {\n    PVOID64   Buffer;\n    ULONGLONG Alignment;\n}\nalias FILE_SEGMENT_ELEMENT* PFILE_SEGMENT_ELEMENT;\n\n// JOBOBJECT_BASIC_LIMIT_INFORMATION.LimitFlags constants\nenum DWORD\n    JOB_OBJECT_LIMIT_WORKINGSET                 = 0x0001,\n    JOB_OBJECT_LIMIT_PROCESS_TIME               = 0x0002,\n    JOB_OBJECT_LIMIT_JOB_TIME                   = 0x0004,\n    JOB_OBJECT_LIMIT_ACTIVE_PROCESS             = 0x0008,\n    JOB_OBJECT_LIMIT_AFFINITY                   = 0x0010,\n    JOB_OBJECT_LIMIT_PRIORITY_CLASS             = 0x0020,\n    JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME          = 0x0040,\n    JOB_OBJECT_LIMIT_SCHEDULING_CLASS           = 0x0080,\n    JOB_OBJECT_LIMIT_PROCESS_MEMORY             = 0x0100,\n    JOB_OBJECT_LIMIT_JOB_MEMORY                 = 0x0200,\n    JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION = 0x0400,\n    JOB_OBJECT_BREAKAWAY_OK                     = 0x0800,\n    JOB_OBJECT_SILENT_BREAKAWAY                 = 0x1000;\n\n// JOBOBJECT_BASIC_UI_RESTRICTIONS.UIRestrictionsClass constants\nenum DWORD\n    JOB_OBJECT_UILIMIT_HANDLES          = 0x0001,\n    JOB_OBJECT_UILIMIT_READCLIPBOARD    = 0x0002,\n    JOB_OBJECT_UILIMIT_WRITECLIPBOARD   = 0x0004,\n    JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS = 0x0008,\n    JOB_OBJECT_UILIMIT_DISPLAYSETTINGS  = 0x0010,\n    JOB_OBJECT_UILIMIT_GLOBALATOMS      = 0x0020,\n    JOB_OBJECT_UILIMIT_DESKTOP          = 0x0040,\n    JOB_OBJECT_UILIMIT_EXITWINDOWS      = 0x0080;\n\n// JOBOBJECT_SECURITY_LIMIT_INFORMATION.SecurityLimitFlags constants\nenum DWORD\n    JOB_OBJECT_SECURITY_NO_ADMIN         = 0x0001,\n    JOB_OBJECT_SECURITY_RESTRICTED_TOKEN = 0x0002,\n    JOB_OBJECT_SECURITY_ONLY_TOKEN       = 0x0004,\n    JOB_OBJECT_SECURITY_FILTER_TOKENS    = 0x0008;\n\n// JOBOBJECT_END_OF_JOB_TIME_INFORMATION.EndOfJobTimeAction constants\nenum : DWORD {\n    JOB_OBJECT_TERMINATE_AT_END_OF_JOB,\n    JOB_OBJECT_POST_AT_END_OF_JOB\n}\n\nenum : DWORD {\n    JOB_OBJECT_MSG_END_OF_JOB_TIME = 1,\n    JOB_OBJECT_MSG_END_OF_PROCESS_TIME,\n    JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT,\n    JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO,\n    JOB_OBJECT_MSG_NEW_PROCESS,\n    JOB_OBJECT_MSG_EXIT_PROCESS,\n    JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS,\n    JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT,\n    JOB_OBJECT_MSG_JOB_MEMORY_LIMIT\n}\n\nenum JOBOBJECTINFOCLASS {\n    JobObjectBasicAccountingInformation = 1,\n    JobObjectBasicLimitInformation,\n    JobObjectBasicProcessIdList,\n    JobObjectBasicUIRestrictions,\n    JobObjectSecurityLimitInformation,\n    JobObjectEndOfJobTimeInformation,\n    JobObjectAssociateCompletionPortInformation,\n    JobObjectBasicAndIoAccountingInformation,\n    JobObjectExtendedLimitInformation,\n    JobObjectJobSetInformation,\n    MaxJobObjectInfoClass\n}\n\nstruct JOBOBJECT_BASIC_ACCOUNTING_INFORMATION {\n    LARGE_INTEGER TotalUserTime;\n    LARGE_INTEGER TotalKernelTime;\n    LARGE_INTEGER ThisPeriodTotalUserTime;\n    LARGE_INTEGER ThisPeriodTotalKernelTime;\n    DWORD         TotalPageFaultCount;\n    DWORD         TotalProcesses;\n    DWORD         ActiveProcesses;\n    DWORD         TotalTerminatedProcesses;\n}\nalias JOBOBJECT_BASIC_ACCOUNTING_INFORMATION* PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION;\n\nstruct JOBOBJECT_BASIC_LIMIT_INFORMATION {\n    LARGE_INTEGER PerProcessUserTimeLimit;\n    LARGE_INTEGER PerJobUserTimeLimit;\n    DWORD         LimitFlags;\n    SIZE_T        MinimumWorkingSetSize;\n    SIZE_T        MaximumWorkingSetSize;\n    DWORD         ActiveProcessLimit;\n    ULONG_PTR     Affinity;\n    DWORD         PriorityClass;\n    DWORD         SchedulingClass;\n}\nalias JOBOBJECT_BASIC_LIMIT_INFORMATION* PJOBOBJECT_BASIC_LIMIT_INFORMATION;\n\nstruct JOBOBJECT_BASIC_PROCESS_ID_LIST {\n    DWORD     NumberOfAssignedProcesses;\n    DWORD     NumberOfProcessIdsInList;\n    ULONG_PTR _ProcessIdList;\n\n    ULONG_PTR* ProcessIdList() return { return &_ProcessIdList; }\n}\nalias JOBOBJECT_BASIC_PROCESS_ID_LIST* PJOBOBJECT_BASIC_PROCESS_ID_LIST;\n\nstruct JOBOBJECT_BASIC_UI_RESTRICTIONS {\n    DWORD UIRestrictionsClass;\n}\nalias JOBOBJECT_BASIC_UI_RESTRICTIONS* PJOBOBJECT_BASIC_UI_RESTRICTIONS;\n\nstruct JOBOBJECT_SECURITY_LIMIT_INFORMATION {\n    DWORD             SecurityLimitFlags;\n    HANDLE            JobToken;\n    PTOKEN_GROUPS     SidsToDisable;\n    PTOKEN_PRIVILEGES PrivilegesToDelete;\n    PTOKEN_GROUPS     RestrictedSids;\n}\nalias JOBOBJECT_SECURITY_LIMIT_INFORMATION* PJOBOBJECT_SECURITY_LIMIT_INFORMATION;\n\nstruct JOBOBJECT_END_OF_JOB_TIME_INFORMATION {\n    DWORD EndOfJobTimeAction;\n}\nalias JOBOBJECT_END_OF_JOB_TIME_INFORMATION* PJOBOBJECT_END_OF_JOB_TIME_INFORMATION;\n\nstruct JOBOBJECT_ASSOCIATE_COMPLETION_PORT {\n    PVOID  CompletionKey;\n    HANDLE CompletionPort;\n}\nalias JOBOBJECT_ASSOCIATE_COMPLETION_PORT* PJOBOBJECT_ASSOCIATE_COMPLETION_PORT;\n\nstruct JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION {\n    JOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicInfo;\n    IO_COUNTERS IoInfo;\n}\nalias JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION *PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION;\n\nstruct JOBOBJECT_EXTENDED_LIMIT_INFORMATION {\n    JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;\n    IO_COUNTERS IoInfo;\n    SIZE_T      ProcessMemoryLimit;\n    SIZE_T      JobMemoryLimit;\n    SIZE_T      PeakProcessMemoryUsed;\n    SIZE_T      PeakJobMemoryUsed;\n}\nalias JOBOBJECT_EXTENDED_LIMIT_INFORMATION* PJOBOBJECT_EXTENDED_LIMIT_INFORMATION;\n\nstruct JOBOBJECT_JOBSET_INFORMATION {\n    DWORD MemberLevel;\n}\nalias JOBOBJECT_JOBSET_INFORMATION* PJOBOBJECT_JOBSET_INFORMATION;\n\n// MinGW: Making these defines conditional on _WIN32_WINNT will break ddk includes\n//static if (_WIN32_WINNT >= 0x500) {\n\nenum DWORD\n    ES_SYSTEM_REQUIRED  = 0x00000001,\n    ES_DISPLAY_REQUIRED = 0x00000002,\n    ES_USER_PRESENT     = 0x00000004,\n    ES_CONTINUOUS       = 0x80000000;\n\nenum LATENCY_TIME {\n    LT_DONT_CARE,\n    LT_LOWEST_LATENCY\n}\nalias LATENCY_TIME* PLATENCY_TIME;\n\nenum SYSTEM_POWER_STATE {\n    PowerSystemUnspecified,\n    PowerSystemWorking,\n    PowerSystemSleeping1,\n    PowerSystemSleeping2,\n    PowerSystemSleeping3,\n    PowerSystemHibernate,\n    PowerSystemShutdown,\n    PowerSystemMaximum\n}\nalias SYSTEM_POWER_STATE* PSYSTEM_POWER_STATE;\n\nenum POWER_SYSTEM_MAXIMUM = SYSTEM_POWER_STATE.PowerSystemMaximum;\n\nenum POWER_ACTION {\n    PowerActionNone,\n    PowerActionReserved,\n    PowerActionSleep,\n    PowerActionHibernate,\n    PowerActionShutdown,\n    PowerActionShutdownReset,\n    PowerActionShutdownOff,\n    PowerActionWarmEject\n}\nalias POWER_ACTION* PPOWER_ACTION;\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum SYSTEM_POWER_CONDITION {\n        PoAc,\n        PoDc,\n        PoHot,\n        PoConditionMaximum\n    }\n    alias SYSTEM_POWER_CONDITION* PSYSTEM_POWER_CONDITION;\n}\n\nenum DEVICE_POWER_STATE {\n    PowerDeviceUnspecified,\n    PowerDeviceD0,\n    PowerDeviceD1,\n    PowerDeviceD2,\n    PowerDeviceD3,\n    PowerDeviceMaximum\n}\nalias DEVICE_POWER_STATE* PDEVICE_POWER_STATE;\n\nalign(4):\nstruct BATTERY_REPORTING_SCALE {\n    DWORD Granularity;\n    DWORD Capacity;\n}\nalias BATTERY_REPORTING_SCALE* PBATTERY_REPORTING_SCALE;\n\nstruct POWER_ACTION_POLICY {\n    POWER_ACTION Action;\n    ULONG        Flags;\n    ULONG        EventCode;\n}\nalias POWER_ACTION_POLICY* PPOWER_ACTION_POLICY;\n\n// POWER_ACTION_POLICY.Flags constants\nenum ULONG\n    POWER_ACTION_QUERY_ALLOWED  = 0x00000001,\n    POWER_ACTION_UI_ALLOWED     = 0x00000002,\n    POWER_ACTION_OVERRIDE_APPS  = 0x00000004,\n    POWER_ACTION_LIGHTEST_FIRST = 0x10000000,\n    POWER_ACTION_LOCK_CONSOLE   = 0x20000000,\n    POWER_ACTION_DISABLE_WAKES  = 0x40000000,\n    POWER_ACTION_CRITICAL       = 0x80000000;\n\n// POWER_ACTION_POLICY.EventCode constants\nenum ULONG\n    POWER_LEVEL_USER_NOTIFY_TEXT  = 0x00000001,\n    POWER_LEVEL_USER_NOTIFY_SOUND = 0x00000002,\n    POWER_LEVEL_USER_NOTIFY_EXEC  = 0x00000004,\n    POWER_USER_NOTIFY_BUTTON      = 0x00000008,\n    POWER_USER_NOTIFY_SHUTDOWN    = 0x00000010,\n    POWER_FORCE_TRIGGER_RESET     = 0x80000000;\n\nenum size_t\n    DISCHARGE_POLICY_CRITICAL = 0,\n    DISCHARGE_POLICY_LOW      = 1,\n    NUM_DISCHARGE_POLICIES    = 4;\n\nenum : BYTE {\n    PO_THROTTLE_NONE,\n    PO_THROTTLE_CONSTANT,\n    PO_THROTTLE_DEGRADE,\n    PO_THROTTLE_ADAPTIVE,\n    PO_THROTTLE_MAXIMUM\n}\n\nstruct SYSTEM_POWER_LEVEL {\n    BOOLEAN             Enable;\n    UCHAR[3]            Spare;\n    ULONG               BatteryLevel;\n    POWER_ACTION_POLICY PowerPolicy;\n    SYSTEM_POWER_STATE  MinSystemState;\n}\nalias SYSTEM_POWER_LEVEL* PSYSTEM_POWER_LEVEL;\n\nstruct SYSTEM_POWER_POLICY {\n    ULONG               Revision;\n    POWER_ACTION_POLICY PowerButton;\n    POWER_ACTION_POLICY SleepButton;\n    POWER_ACTION_POLICY LidClose;\n    SYSTEM_POWER_STATE  LidOpenWake;\n    ULONG               Reserved;\n    POWER_ACTION_POLICY Idle;\n    ULONG               IdleTimeout;\n    UCHAR               IdleSensitivity;\n    UCHAR               DynamicThrottle;\n    UCHAR[2]            Spare2;\n    SYSTEM_POWER_STATE  MinSleep;\n    SYSTEM_POWER_STATE  MaxSleep;\n    SYSTEM_POWER_STATE  ReducedLatencySleep;\n    ULONG               WinLogonFlags;\n    ULONG               Spare3;\n    ULONG               DozeS4Timeout;\n    ULONG               BroadcastCapacityResolution;\n    SYSTEM_POWER_LEVEL[NUM_DISCHARGE_POLICIES] DischargePolicy;\n    ULONG               VideoTimeout;\n    BOOLEAN             VideoDimDisplay;\n    ULONG[3]            VideoReserved;\n    ULONG               SpindownTimeout;\n    BOOLEAN             OptimizeForPower;\n    UCHAR               FanThrottleTolerance;\n    UCHAR               ForcedThrottle;\n    UCHAR               MinThrottle;\n    POWER_ACTION_POLICY OverThrottled;\n}\nalias SYSTEM_POWER_POLICY* PSYSTEM_POWER_POLICY;\n\nstruct SYSTEM_POWER_CAPABILITIES {\n    BOOLEAN                    PowerButtonPresent;\n    BOOLEAN                    SleepButtonPresent;\n    BOOLEAN                    LidPresent;\n    BOOLEAN                    SystemS1;\n    BOOLEAN                    SystemS2;\n    BOOLEAN                    SystemS3;\n    BOOLEAN                    SystemS4;\n    BOOLEAN                    SystemS5;\n    BOOLEAN                    HiberFilePresent;\n    BOOLEAN                    FullWake;\n    BOOLEAN                    VideoDimPresent;\n    BOOLEAN                    ApmPresent;\n    BOOLEAN                    UpsPresent;\n    BOOLEAN                    ThermalControl;\n    BOOLEAN                    ProcessorThrottle;\n    UCHAR                      ProcessorMinThrottle;\n    UCHAR                      ProcessorMaxThrottle;\n    UCHAR[4]                   spare2;\n    BOOLEAN                    DiskSpinDown;\n    UCHAR[8]                   spare3;\n    BOOLEAN                    SystemBatteriesPresent;\n    BOOLEAN                    BatteriesAreShortTerm;\n    BATTERY_REPORTING_SCALE[3] BatteryScale;\n    SYSTEM_POWER_STATE         AcOnLineWake;\n    SYSTEM_POWER_STATE         SoftLidWake;\n    SYSTEM_POWER_STATE         RtcWake;\n    SYSTEM_POWER_STATE         MinDeviceWakeState;\n    SYSTEM_POWER_STATE         DefaultLowLatencyWake;\n}\nalias SYSTEM_POWER_CAPABILITIES* PSYSTEM_POWER_CAPABILITIES;\n\nstruct SYSTEM_BATTERY_STATE {\n    BOOLEAN    AcOnLine;\n    BOOLEAN    BatteryPresent;\n    BOOLEAN    Charging;\n    BOOLEAN    Discharging;\n    BOOLEAN[4] Spare1;\n    ULONG      MaxCapacity;\n    ULONG      RemainingCapacity;\n    ULONG      Rate;\n    ULONG      EstimatedTime;\n    ULONG      DefaultAlert1;\n    ULONG      DefaultAlert2;\n}\nalias SYSTEM_BATTERY_STATE* PSYSTEM_BATTERY_STATE;\n\nenum POWER_INFORMATION_LEVEL {\n    SystemPowerPolicyAc,\n    SystemPowerPolicyDc,\n    VerifySystemPolicyAc,\n    VerifySystemPolicyDc,\n    SystemPowerCapabilities,\n    SystemBatteryState,\n    SystemPowerStateHandler,\n    ProcessorStateHandler,\n    SystemPowerPolicyCurrent,\n    AdministratorPowerPolicy,\n    SystemReserveHiberFile,\n    ProcessorInformation,\n    SystemPowerInformation,\n    ProcessorStateHandler2,\n    LastWakeTime,\n    LastSleepTime,\n    SystemExecutionState,\n    SystemPowerStateNotifyHandler,\n    ProcessorPowerPolicyAc,\n    ProcessorPowerPolicyDc,\n    VerifyProcessorPowerPolicyAc,\n    VerifyProcessorPowerPolicyDc,\n    ProcessorPowerPolicyCurrent\n}\n\n//#if 1 /* (WIN32_WINNT >= 0x0500) */\nstruct SYSTEM_POWER_INFORMATION {\n    ULONG MaxIdlenessAllowed;\n    ULONG Idleness;\n    ULONG TimeRemaining;\n    UCHAR CoolingMode;\n}\nalias SYSTEM_POWER_INFORMATION* PSYSTEM_POWER_INFORMATION;\n//#endif\n\nstruct PROCESSOR_POWER_POLICY_INFO {\n    ULONG    TimeCheck;\n    ULONG    DemoteLimit;\n    ULONG    PromoteLimit;\n    UCHAR    DemotePercent;\n    UCHAR    PromotePercent;\n    UCHAR[2] Spare;\n    uint     _bf;\n\n    bool AllowDemotion()  { return cast(bool)(_bf & 1); }\n    bool AllowPromotion() { return cast(bool)(_bf & 2); }\n\n    bool AllowDemotion(bool a)  { _bf = (_bf & ~1) | a; return a; }\n    bool AllowPromotion(bool a) { _bf = (_bf & ~2) | (a << 1); return a; }\n/+\n    ULONG  AllowDemotion : 1;\n    ULONG  AllowPromotion : 1;\n    ULONG  Reserved : 30;\n+/\n}\nalias PROCESSOR_POWER_POLICY_INFO* PPROCESSOR_POWER_POLICY_INFO;\n\nstruct PROCESSOR_POWER_POLICY {\n    ULONG    Revision;\n    UCHAR    DynamicThrottle;\n    UCHAR[3] Spare;\n    ULONG    Reserved;\n    ULONG    PolicyCount;\n    PROCESSOR_POWER_POLICY_INFO[3] Policy;\n}\nalias PROCESSOR_POWER_POLICY* PPROCESSOR_POWER_POLICY;\n\nstruct ADMINISTRATOR_POWER_POLICY {\n    SYSTEM_POWER_STATE MinSleep;\n    SYSTEM_POWER_STATE MaxSleep;\n    ULONG              MinVideoTimeout;\n    ULONG              MaxVideoTimeout;\n    ULONG              MinSpindownTimeout;\n    ULONG              MaxSpindownTimeout;\n}\nalias ADMINISTRATOR_POWER_POLICY* PADMINISTRATOR_POWER_POLICY;\n\n//}//#endif /* _WIN32_WINNT >= 0x500 */\n\nextern (Windows) {\n    alias void function(PVOID, DWORD, PVOID) PIMAGE_TLS_CALLBACK;\n\n    static if (_WIN32_WINNT >= 0x500) {\n        alias LONG function(PEXCEPTION_POINTERS) PVECTORED_EXCEPTION_HANDLER;\n        alias void function(PVOID, BOOLEAN) WAITORTIMERCALLBACKFUNC;\n    }\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum HEAP_INFORMATION_CLASS {\n        HeapCompatibilityInformation\n    }\n\n    enum ACTIVATION_CONTEXT_INFO_CLASS {\n        ActivationContextBasicInformation = 1,\n        ActivationContextDetailedInformation,\n        AssemblyDetailedInformationInActivationContext,\n        FileInformationInAssemblyOfAssemblyInActivationContext\n    }\n\n    align struct ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION {\n        DWORD         ulFlags;\n        DWORD         ulEncodedAssemblyIdentityLength;\n        DWORD         ulManifestPathType;\n        DWORD         ulManifestPathLength;\n        LARGE_INTEGER liManifestLastWriteTime;\n        DWORD         ulPolicyPathType;\n        DWORD         ulPolicyPathLength;\n        LARGE_INTEGER liPolicyLastWriteTime;\n        DWORD         ulMetadataSatelliteRosterIndex;\n        DWORD         ulManifestVersionMajor;\n        DWORD         ulManifestVersionMinor;\n        DWORD         ulPolicyVersionMajor;\n        DWORD         ulPolicyVersionMinor;\n        DWORD         ulAssemblyDirectoryNameLength;\n        PCWSTR        lpAssemblyEncodedAssemblyIdentity;\n        PCWSTR        lpAssemblyManifestPath;\n        PCWSTR        lpAssemblyPolicyPath;\n        PCWSTR        lpAssemblyDirectoryName;\n    }\n    alias ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION*\n      PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION;\n    alias const(ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION)*\n      PCACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION;\n\n    struct ACTIVATION_CONTEXT_DETAILED_INFORMATION {\n        DWORD  dwFlags;\n        DWORD  ulFormatVersion;\n        DWORD  ulAssemblyCount;\n        DWORD  ulRootManifestPathType;\n        DWORD  ulRootManifestPathChars;\n        DWORD  ulRootConfigurationPathType;\n        DWORD  ulRootConfigurationPathChars;\n        DWORD  ulAppDirPathType;\n        DWORD  ulAppDirPathChars;\n        PCWSTR lpRootManifestPath;\n        PCWSTR lpRootConfigurationPath;\n        PCWSTR lpAppDirPath;\n    }\n    alias ACTIVATION_CONTEXT_DETAILED_INFORMATION*\n      PACTIVATION_CONTEXT_DETAILED_INFORMATION;\n    alias const(ACTIVATION_CONTEXT_DETAILED_INFORMATION)*\n      PCACTIVATION_CONTEXT_DETAILED_INFORMATION;\n\n    struct ACTIVATION_CONTEXT_QUERY_INDEX {\n        ULONG ulAssemblyIndex;\n        ULONG ulFileIndexInAssembly;\n    }\n    alias ACTIVATION_CONTEXT_QUERY_INDEX*        PACTIVATION_CONTEXT_QUERY_INDEX;\n    alias const(ACTIVATION_CONTEXT_QUERY_INDEX)* PCACTIVATION_CONTEXT_QUERY_INDEX;\n\n    struct ASSEMBLY_FILE_DETAILED_INFORMATION {\n        DWORD  ulFlags;\n        DWORD  ulFilenameLength;\n        DWORD  ulPathLength;\n        PCWSTR lpFileName;\n        PCWSTR lpFilePath;\n    }\n    alias ASSEMBLY_FILE_DETAILED_INFORMATION*\n      PASSEMBLY_FILE_DETAILED_INFORMATION;\n    alias const(ASSEMBLY_FILE_DETAILED_INFORMATION)*\n      PCASSEMBLY_FILE_DETAILED_INFORMATION;\n}\n\nversion (Unicode) {\n    alias OSVERSIONINFOW OSVERSIONINFO;\n    alias OSVERSIONINFOEXW OSVERSIONINFOEX;\n} else {\n    alias OSVERSIONINFOA OSVERSIONINFO;\n    alias OSVERSIONINFOEXA OSVERSIONINFOEX;\n}\n\nalias OSVERSIONINFO*   POSVERSIONINFO,   LPOSVERSIONINFO;\nalias OSVERSIONINFOEX* POSVERSIONINFOEX, LPOSVERSIONINFOEX;\n\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    extern (Windows) ULONGLONG VerSetConditionMask(ULONGLONG, DWORD, BYTE);\n}\n\nversion (Win64) {\nenum WORD IMAGE_NT_OPTIONAL_HDR_MAGIC = IMAGE_NT_OPTIONAL_HDR64_MAGIC;\n\n    alias IMAGE_ORDINAL_FLAG64 IMAGE_ORDINAL_FLAG;\n    alias IMAGE_SNAP_BY_ORDINAL64 IMAGE_SNAP_BY_ORDINAL;\n    alias IMAGE_ORDINAL64 IMAGE_ORDINAL;\n    alias IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER;\n    alias IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS;\n    alias IMAGE_THUNK_DATA64 IMAGE_THUNK_DATA;\n    alias IMAGE_TLS_DIRECTORY64 IMAGE_TLS_DIRECTORY;\n} else {\nenum WORD IMAGE_NT_OPTIONAL_HDR_MAGIC = IMAGE_NT_OPTIONAL_HDR32_MAGIC;\n\n    alias IMAGE_ORDINAL_FLAG32 IMAGE_ORDINAL_FLAG;\n    alias IMAGE_ORDINAL32 IMAGE_ORDINAL;\n    alias IMAGE_SNAP_BY_ORDINAL32 IMAGE_SNAP_BY_ORDINAL;\n    alias IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER;\n    alias IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS;\n    alias IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA;\n    alias IMAGE_TLS_DIRECTORY32 IMAGE_TLS_DIRECTORY;\n}\n\nalias IMAGE_OPTIONAL_HEADER* PIMAGE_OPTIONAL_HEADER;\nalias IMAGE_NT_HEADERS* PIMAGE_NT_HEADERS;\nalias IMAGE_THUNK_DATA* PIMAGE_THUNK_DATA;\nalias IMAGE_TLS_DIRECTORY* PIMAGE_TLS_DIRECTORY;\n\n// TODO: MinGW implements these in assembly.  How to translate?\nPVOID GetCurrentFiber();\nPVOID GetFiberData();\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winperf.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winperf.d)\n */\nmodule core.sys.windows.winperf;\nversion (Windows):\n\nimport core.sys.windows.windef;\nimport core.sys.windows.winbase; // for SYSTEMTIME\n\nenum PERF_DATA_VERSION=1;\nenum PERF_DATA_REVISION=1;\nenum PERF_NO_INSTANCES=-1;\nenum PERF_SIZE_DWORD=0;\nenum PERF_SIZE_LARGE=256;\nenum PERF_SIZE_ZERO=512;\nenum PERF_SIZE_VARIABLE_LEN=768;\nenum PERF_TYPE_NUMBER=0;\nenum PERF_TYPE_COUNTER=1024;\nenum PERF_TYPE_TEXT=2048;\nenum PERF_TYPE_ZERO=0xC00;\nenum PERF_NUMBER_HEX=0;\nenum PERF_NUMBER_DECIMAL=0x10000;\nenum PERF_NUMBER_DEC_1000=0x20000;\nenum PERF_COUNTER_VALUE=0;\nenum PERF_COUNTER_RATE=0x10000;\nenum PERF_COUNTER_FRACTION=0x20000;\nenum PERF_COUNTER_BASE=0x30000;\nenum PERF_COUNTER_ELAPSED=0x40000;\nenum PERF_COUNTER_QUEUELEN=0x50000;\nenum PERF_COUNTER_HISTOGRAM=0x60000;\nenum PERF_TEXT_UNICODE=0;\nenum PERF_TEXT_ASCII=0x10000;\nenum PERF_TIMER_TICK=0;\nenum PERF_TIMER_100NS=0x100000;\nenum PERF_OBJECT_TIMER=0x200000;\nenum PERF_DELTA_COUNTER=0x400000;\nenum PERF_DELTA_BASE=0x800000;\nenum PERF_INVERSE_COUNTER=0x1000000;\nenum PERF_MULTI_COUNTER=0x2000000;\nenum PERF_DISPLAY_NO_SUFFIX=0;\nenum PERF_DISPLAY_PER_SEC=0x10000000;\nenum PERF_DISPLAY_PERCENT=0x20000000;\nenum PERF_DISPLAY_SECONDS=0x30000000;\nenum PERF_DISPLAY_NOSHOW=0x40000000;\nenum PERF_COUNTER_HISTOGRAM_TYPE=0x80000000;\nenum PERF_NO_UNIQUE_ID=(-1);\nenum PERF_DETAIL_NOVICE=100;\nenum PERF_DETAIL_ADVANCED=200;\nenum PERF_DETAIL_EXPERT=300;\nenum PERF_DETAIL_WIZARD=400;\nenum PERF_COUNTER_COUNTER=(PERF_SIZE_DWORD|PERF_TYPE_COUNTER|PERF_COUNTER_RATE|PERF_TIMER_TICK|PERF_DELTA_COUNTER|PERF_DISPLAY_PER_SEC);\nenum PERF_COUNTER_TIMER=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_COUNTER_RATE|PERF_TIMER_TICK|PERF_DELTA_COUNTER|PERF_DISPLAY_PERCENT);\nenum PERF_COUNTER_QUEUELEN_TYPE=(PERF_SIZE_DWORD|PERF_TYPE_COUNTER|PERF_COUNTER_QUEUELEN|PERF_TIMER_TICK|PERF_DELTA_COUNTER|PERF_DISPLAY_NO_SUFFIX);\nenum PERF_COUNTER_BULK_COUNT=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_COUNTER_RATE|PERF_TIMER_TICK|PERF_DELTA_COUNTER|PERF_DISPLAY_PER_SEC);\nenum PERF_COUNTER_TEXT=(PERF_SIZE_VARIABLE_LEN|PERF_TYPE_TEXT|PERF_TEXT_UNICODE|PERF_DISPLAY_NO_SUFFIX);\nenum PERF_COUNTER_RAWCOUNT=(PERF_SIZE_DWORD|PERF_TYPE_NUMBER|PERF_NUMBER_DECIMAL|PERF_DISPLAY_NO_SUFFIX);\nenum PERF_COUNTER_LARGE_RAWCOUNT=(PERF_SIZE_LARGE|PERF_TYPE_NUMBER|PERF_NUMBER_DECIMAL|PERF_DISPLAY_NO_SUFFIX);\nenum PERF_COUNTER_RAWCOUNT_HEX=(PERF_SIZE_DWORD|PERF_TYPE_NUMBER|PERF_NUMBER_HEX|PERF_DISPLAY_NO_SUFFIX);\nenum PERF_COUNTER_LARGE_RAWCOUNT_HEX=(PERF_SIZE_LARGE|PERF_TYPE_NUMBER|PERF_NUMBER_HEX|PERF_DISPLAY_NO_SUFFIX);\nenum PERF_SAMPLE_FRACTION=(PERF_SIZE_DWORD|PERF_TYPE_COUNTER|PERF_COUNTER_FRACTION|PERF_DELTA_COUNTER|PERF_DELTA_BASE|PERF_DISPLAY_PERCENT);\nenum PERF_SAMPLE_COUNTER=(PERF_SIZE_DWORD|PERF_TYPE_COUNTER|PERF_COUNTER_RATE|PERF_TIMER_TICK|PERF_DELTA_COUNTER|PERF_DISPLAY_NO_SUFFIX);\nenum PERF_COUNTER_NODATA=(PERF_SIZE_ZERO|PERF_DISPLAY_NOSHOW);\nenum PERF_COUNTER_TIMER_INV=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_COUNTER_RATE|PERF_TIMER_TICK|PERF_DELTA_COUNTER|PERF_INVERSE_COUNTER|PERF_DISPLAY_PERCENT);\nenum PERF_SAMPLE_BASE=(PERF_SIZE_DWORD|PERF_TYPE_COUNTER|PERF_COUNTER_BASE|PERF_DISPLAY_NOSHOW|1);\nenum PERF_AVERAGE_TIMER=(PERF_SIZE_DWORD|PERF_TYPE_COUNTER|PERF_COUNTER_FRACTION|PERF_DISPLAY_SECONDS);\nenum PERF_AVERAGE_BASE=(PERF_SIZE_DWORD|PERF_TYPE_COUNTER|PERF_COUNTER_BASE|PERF_DISPLAY_NOSHOW|2);\nenum PERF_AVERAGE_BULK=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_COUNTER_FRACTION|PERF_DISPLAY_NOSHOW);\nenum PERF_100NSEC_TIMER=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_COUNTER_RATE|PERF_TIMER_100NS|PERF_DELTA_COUNTER|PERF_DISPLAY_PERCENT);\nenum PERF_100NSEC_TIMER_INV=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_COUNTER_RATE|PERF_TIMER_100NS|PERF_DELTA_COUNTER|PERF_INVERSE_COUNTER|PERF_DISPLAY_PERCENT);\nenum PERF_COUNTER_MULTI_TIMER=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_COUNTER_RATE|PERF_DELTA_COUNTER|PERF_TIMER_TICK|PERF_MULTI_COUNTER|PERF_DISPLAY_PERCENT);\nenum PERF_COUNTER_MULTI_TIMER_INV=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_COUNTER_RATE|PERF_DELTA_COUNTER|PERF_MULTI_COUNTER|PERF_TIMER_TICK|PERF_INVERSE_COUNTER|PERF_DISPLAY_PERCENT);\nenum PERF_COUNTER_MULTI_BASE=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_COUNTER_BASE|PERF_MULTI_COUNTER|PERF_DISPLAY_NOSHOW);\nenum PERF_100NSEC_MULTI_TIMER=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_DELTA_COUNTER|PERF_COUNTER_RATE|PERF_TIMER_100NS|PERF_MULTI_COUNTER|PERF_DISPLAY_PERCENT);\nenum PERF_100NSEC_MULTI_TIMER_INV=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_DELTA_COUNTER|PERF_COUNTER_RATE|PERF_TIMER_100NS|PERF_MULTI_COUNTER|PERF_INVERSE_COUNTER|PERF_DISPLAY_PERCENT);\nenum PERF_RAW_FRACTION=(PERF_SIZE_DWORD|PERF_TYPE_COUNTER|PERF_COUNTER_FRACTION|PERF_DISPLAY_PERCENT);\nenum PERF_RAW_BASE=(PERF_SIZE_DWORD|PERF_TYPE_COUNTER|PERF_COUNTER_BASE|PERF_DISPLAY_NOSHOW|3);\nenum PERF_ELAPSED_TIME=(PERF_SIZE_LARGE|PERF_TYPE_COUNTER|PERF_COUNTER_ELAPSED|PERF_OBJECT_TIMER|PERF_DISPLAY_SECONDS);\n\nstruct PERF_DATA_BLOCK {\n    WCHAR[4] Signature;\n    DWORD LittleEndian;\n    DWORD Version;\n    DWORD Revision;\n    DWORD TotalByteLength;\n    DWORD HeaderLength;\n    DWORD NumObjectTypes;\n    LONG DefaultObject;\n    SYSTEMTIME SystemTime;\n    LARGE_INTEGER PerfTime;\n    LARGE_INTEGER PerfFreq;\n    LARGE_INTEGER PerfTime100nSec;\n    DWORD SystemNameLength;\n    DWORD SystemNameOffset;\n}\nalias PERF_DATA_BLOCK * PPERF_DATA_BLOCK;\n\nstruct PERF_OBJECT_TYPE {\n    DWORD TotalByteLength;\n    DWORD DefinitionLength;\n    DWORD HeaderLength;\n    DWORD ObjectNameTitleIndex;\nversion (Win64) {\n    DWORD ObjectNameTitle;\n} else {\n    LPWSTR ObjectNameTitle;\n}\n    DWORD ObjectHelpTitleIndex;\nversion (Win64) {\n    DWORD ObjectHelpTitle;\n} else {\n    LPWSTR ObjectHelpTitle;\n}\n    DWORD DetailLevel;\n    DWORD NumCounters;\n    LONG DefaultCounter;\n    LONG NumInstances;\n    DWORD CodePage;\n    LARGE_INTEGER PerfTime;\n    LARGE_INTEGER PerfFreq;\n}\nalias PERF_OBJECT_TYPE * PPERF_OBJECT_TYPE;\n\nstruct PERF_COUNTER_DEFINITION {\n    DWORD ByteLength;\n    DWORD CounterNameTitleIndex;\nversion (Win64) {\n    DWORD CounterNameTitle;\n} else {\n    LPWSTR CounterNameTitle;\n}\n    DWORD CounterHelpTitleIndex;\nversion (Win64) {\n    DWORD CounterHelpTitle;\n} else {\n    LPWSTR CounterHelpTitle;\n}\n    LONG DefaultScale;\n    DWORD DetailLevel;\n    DWORD CounterType;\n    DWORD CounterSize;\n    DWORD CounterOffset;\n}\nalias PERF_COUNTER_DEFINITION * PPERF_COUNTER_DEFINITION;\n\nstruct PERF_INSTANCE_DEFINITION {\n    DWORD ByteLength;\n    DWORD ParentObjectTitleIndex;\n    DWORD ParentObjectInstance;\n    LONG UniqueID;\n    DWORD NameOffset;\n    DWORD NameLength;\n}\nalias PERF_INSTANCE_DEFINITION * PPERF_INSTANCE_DEFINITION;\n\nstruct PERF_COUNTER_BLOCK {\n    DWORD ByteLength;\n}\nalias PERF_COUNTER_BLOCK * PPERF_COUNTER_BLOCK;\n\nextern (Windows):\nalias DWORD function (LPWSTR) PM_OPEN_PROC;\nalias DWORD function (LPWSTR,PVOID*,PDWORD,PDWORD) PM_COLLECT_PROC;\nalias DWORD function () PM_CLOSE_PROC;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winreg.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winreg.d)\n */\nmodule core.sys.windows.winreg;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"advapi32\");\n\nprivate import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;\n\nenum : HKEY { // for some reason, DMD errors if I don't give all the values explicitly\n    HKEY_CLASSES_ROOT        = cast(HKEY) 0x80000000,\n    HKEY_CURRENT_USER        = cast(HKEY) 0x80000001,\n    HKEY_LOCAL_MACHINE       = cast(HKEY) 0x80000002,\n    HKEY_USERS               = cast(HKEY) 0x80000003,\n    HKEY_PERFORMANCE_DATA    = cast(HKEY) 0x80000004,\n    HKEY_CURRENT_CONFIG      = cast(HKEY) 0x80000005,\n    HKEY_DYN_DATA            = cast(HKEY) 0x80000006,\n    HKEY_PERFORMANCE_TEXT    = cast(HKEY) 0x80000050,\n    HKEY_PERFORMANCE_NLSTEXT = cast(HKEY) 0x80000060,\n}\n\n//enum : DWORD {\n//    REG_OPTION_NON_VOLATILE,\n//    REG_OPTION_VOLATILE\n//}\n\nenum : DWORD {\n    REG_CREATED_NEW_KEY = 1,\n    REG_OPENED_EXISTING_KEY\n}\n\nenum : DWORD {\n    REG_NONE                       = 0,\n    REG_SZ,\n    REG_EXPAND_SZ,\n    REG_BINARY,\n    REG_DWORD_LITTLE_ENDIAN,\n    REG_DWORD                      = REG_DWORD_LITTLE_ENDIAN,\n    REG_DWORD_BIG_ENDIAN,\n    REG_LINK,\n    REG_MULTI_SZ,\n    REG_RESOURCE_LIST,\n    REG_FULL_RESOURCE_DESCRIPTOR,\n    REG_RESOURCE_REQUIREMENTS_LIST,\n    REG_QWORD_LITTLE_ENDIAN,\n    REG_QWORD                      = REG_QWORD_LITTLE_ENDIAN\n}\n\nenum DWORD\n    REG_NOTIFY_CHANGE_NAME       = 1,\n    REG_NOTIFY_CHANGE_ATTRIBUTES = 2,\n    REG_NOTIFY_CHANGE_LAST_SET   = 4,\n    REG_NOTIFY_CHANGE_SECURITY   = 8;\n\nalias ACCESS_MASK REGSAM;\n\nstruct VALENTA {\n    LPSTR ve_valuename;\n    DWORD ve_valuelen;\n    DWORD_PTR ve_valueptr;\n    DWORD ve_type;\n}\nalias VALENTA* PVALENTA;\n\nstruct VALENTW {\n    LPWSTR ve_valuename;\n    DWORD  ve_valuelen;\n    DWORD_PTR ve_valueptr;\n    DWORD  ve_type;\n}\nalias VALENTW* PVALENTW;\n\n// RRF - Registry Routine Flags (for RegGetValue)\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum : DWORD {\n        RRF_RT_REG_NONE      = 0x00000001,\n        RRF_RT_REG_SZ        = 0x00000002,\n        RRF_RT_REG_EXPAND_SZ = 0x00000004,\n        RRF_RT_REG_BINARY    = 0x00000008,\n        RRF_RT_REG_DWORD     = 0x00000010,\n        RRF_RT_REG_MULTI_SZ  = 0x00000020,\n        RRF_RT_REG_QWORD     = 0x00000040,\n        RRF_RT_DWORD         = RRF_RT_REG_BINARY | RRF_RT_REG_DWORD,\n        RRF_RT_QWORD         = RRF_RT_REG_BINARY | RRF_RT_REG_QWORD,\n        RRF_RT_ANY           = 0x0000FFFF,\n        RRF_NOEXPAND         = 0x10000000,\n        RRF_ZEROONFAILURE    = 0x20000000\n    }\n}\n\nextern (Windows) nothrow @nogc {\n    LONG RegCloseKey(in HKEY);\n    LONG RegConnectRegistryA(LPCSTR, HKEY, PHKEY);\n    LONG RegConnectRegistryW(LPCWSTR, HKEY, PHKEY);\n    LONG RegCreateKeyExA(in HKEY, LPCSTR, DWORD, LPSTR, DWORD, REGSAM,\n      LPSECURITY_ATTRIBUTES, PHKEY, PDWORD);\n    LONG RegCreateKeyExW(in HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM,\n      LPSECURITY_ATTRIBUTES, PHKEY, PDWORD);\n    LONG RegDeleteKeyA(in HKEY, LPCSTR);\n    LONG RegDeleteKeyW(in HKEY, LPCWSTR);\n    LONG RegDeleteValueA(in HKEY, LPCSTR);\n    LONG RegDeleteValueW(in HKEY, LPCWSTR);\n    LONG RegEnumKeyExA(in HKEY, DWORD, LPSTR, PDWORD, PDWORD, LPSTR, PDWORD,\n      PFILETIME);\n    LONG RegEnumKeyExW(in HKEY, DWORD, LPWSTR, PDWORD, PDWORD, LPWSTR, PDWORD,\n      PFILETIME);\n    LONG RegEnumValueA(in HKEY, DWORD, LPSTR, PDWORD, PDWORD, PDWORD, LPBYTE,\n      PDWORD);\n    LONG RegEnumValueW(in HKEY, DWORD, LPWSTR, PDWORD, PDWORD, PDWORD, LPBYTE,\n      PDWORD);\n    LONG RegFlushKey(in HKEY);\n    LONG RegLoadKeyA(in HKEY, LPCSTR, LPCSTR);\n    LONG RegLoadKeyW(in HKEY, LPCWSTR, LPCWSTR);\n    LONG RegOpenKeyExA(in HKEY, LPCSTR, DWORD, REGSAM, PHKEY);\n    LONG RegOpenKeyExW(in HKEY, LPCWSTR, DWORD, REGSAM, PHKEY);\n    LONG RegQueryInfoKeyA(in HKEY, LPSTR, PDWORD, PDWORD, PDWORD, PDWORD,\n      PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PFILETIME);\n    LONG RegQueryInfoKeyW(in HKEY, LPWSTR, PDWORD, PDWORD, PDWORD, PDWORD,\n      PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PFILETIME);\n    LONG RegQueryMultipleValuesA(in HKEY, PVALENTA, DWORD, LPSTR, LPDWORD);\n    LONG RegQueryMultipleValuesW(in HKEY, PVALENTW, DWORD, LPWSTR, LPDWORD);\n    LONG RegQueryValueExA(in HKEY, LPCSTR, LPDWORD, LPDWORD, /*LPBYTE*/LPVOID, LPDWORD);\n    LONG RegQueryValueExW(in HKEY, LPCWSTR, LPDWORD, LPDWORD, /*LPBYTE*/LPVOID, LPDWORD);\n    LONG RegReplaceKeyA(in HKEY, LPCSTR, LPCSTR, LPCSTR);\n    LONG RegReplaceKeyW(in HKEY, LPCWSTR, LPCWSTR, LPCWSTR);\n    LONG RegSaveKeyA(in HKEY, LPCSTR, LPSECURITY_ATTRIBUTES);\n    LONG RegSaveKeyW(in HKEY, LPCWSTR, LPSECURITY_ATTRIBUTES);\n    LONG RegSetKeySecurity(in HKEY, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR);\n    LONG RegSetValueExA(in HKEY, LPCSTR, DWORD, DWORD, const(BYTE)*, DWORD);\n    LONG RegSetValueExW(in HKEY, LPCWSTR, DWORD, DWORD, const(BYTE)*, DWORD);\n    LONG RegUnLoadKeyA(in HKEY, LPCSTR);\n    LONG RegUnLoadKeyW(in HKEY, LPCWSTR);\n    LONG RegNotifyChangeKeyValue(in HKEY, BOOL, DWORD, HANDLE, BOOL);\n\n    BOOL AbortSystemShutdownA(LPCSTR);\n    BOOL AbortSystemShutdownW(LPCWSTR);\n    BOOL InitiateSystemShutdownA(LPSTR, LPSTR, DWORD, BOOL, BOOL);\n    BOOL InitiateSystemShutdownW(LPWSTR, LPWSTR, DWORD, BOOL, BOOL);\n    LONG RegGetKeySecurity(in HKEY, SECURITY_INFORMATION,\n      PSECURITY_DESCRIPTOR, PDWORD);\n    LONG RegRestoreKeyA(in HKEY, LPCSTR, DWORD);\n    LONG RegRestoreKeyW(in HKEY, LPCWSTR, DWORD);\n    LONG RegSetKeySecurity(in HKEY, SECURITY_INFORMATION,\n      PSECURITY_DESCRIPTOR);\n\n    static if (_WIN32_WINNT >= 0x500) {\n        LONG RegDisablePredefinedCache();\n        LONG RegOpenCurrentUser(REGSAM, PHKEY);\n        LONG RegOpenUserClassesRoot(HANDLE, DWORD, REGSAM, PHKEY);\n    }\n\n    static if (_WIN32_WINNT >= 0x501) {\n        LONG RegSaveKeyExA(in HKEY, LPCSTR, LPSECURITY_ATTRIBUTES, DWORD);\n        LONG RegSaveKeyExW(in HKEY, LPCWSTR, LPSECURITY_ATTRIBUTES, DWORD);\n    }\n\n    static if (_WIN32_WINNT >= 0x600) {\n        LONG RegGetValueA(in HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue,\n          DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);\n        LONG RegGetValueW(in HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue,\n          DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);\n    }\n\n    //deprecated {\n        LONG RegCreateKeyA(in HKEY, LPCSTR, PHKEY);\n        LONG RegCreateKeyW(in HKEY, LPCWSTR, PHKEY);\n        LONG RegEnumKeyA(in HKEY, DWORD, LPSTR, DWORD);\n        LONG RegEnumKeyW(in HKEY, DWORD, LPWSTR, DWORD);\n        LONG RegOpenKeyA(in HKEY, LPCSTR, PHKEY);\n        LONG RegOpenKeyW(in HKEY, LPCWSTR, PHKEY);\n        LONG RegQueryValueA(in HKEY, LPCSTR, LPSTR, PLONG);\n        LONG RegQueryValueW(in HKEY, LPCWSTR, LPWSTR, PLONG);\n        LONG RegSetValueA(in HKEY, LPCSTR, DWORD, LPCSTR, DWORD);\n        LONG RegSetValueW(in HKEY, LPCWSTR, DWORD, LPCWSTR, DWORD);\n    //}\n}\n\nversion (Unicode) {\n    alias VALENTW VALENT;\n    alias RegConnectRegistryW RegConnectRegistry;\n    alias RegCreateKeyExW RegCreateKeyEx;\n    alias RegDeleteKeyW RegDeleteKey;\n    alias RegDeleteValueW RegDeleteValue;\n    alias RegEnumKeyExW RegEnumKeyEx;\n    alias RegEnumValueW RegEnumValue;\n    alias RegLoadKeyW RegLoadKey;\n    alias RegOpenKeyExW RegOpenKeyEx;\n    alias RegQueryInfoKeyW RegQueryInfoKey;\n    alias RegQueryMultipleValuesW RegQueryMultipleValues;\n    alias RegQueryValueExW RegQueryValueEx;\n    alias RegReplaceKeyW RegReplaceKey;\n    alias RegSaveKeyW RegSaveKey;\n    alias RegSetValueExW RegSetValueEx;\n    alias RegUnLoadKeyW RegUnLoadKey;\n\n    alias AbortSystemShutdownW AbortSystemShutdown;\n    alias InitiateSystemShutdownW InitiateSystemShutdown;\n    alias RegRestoreKeyW RegRestoreKey;\n    static if (_WIN32_WINNT >= 0x501) {\n        alias RegSaveKeyExA RegSaveKeyEx;\n    }\n    static if (_WIN32_WINNT >= 0x600) {\n        alias RegGetValueW RegGetValue;\n    }\n    //deprecated {\n        alias RegCreateKeyW RegCreateKey;\n        alias RegEnumKeyW RegEnumKey;\n        alias RegOpenKeyW RegOpenKey;\n        alias RegQueryValueW RegQueryValue;\n        alias RegSetValueW RegSetValue;\n    //}\n} else {\n    alias VALENTA VALENT;\n    alias RegConnectRegistryA RegConnectRegistry;\n    alias RegCreateKeyExA RegCreateKeyEx;\n    alias RegDeleteKeyA RegDeleteKey;\n    alias RegDeleteValueA RegDeleteValue;\n    alias RegEnumKeyExA RegEnumKeyEx;\n    alias RegEnumValueA RegEnumValue;\n    alias RegLoadKeyA RegLoadKey;\n    alias RegOpenKeyExA RegOpenKeyEx;\n    alias RegQueryInfoKeyA RegQueryInfoKey;\n    alias RegQueryMultipleValuesA RegQueryMultipleValues;\n    alias RegQueryValueExA RegQueryValueEx;\n    alias RegReplaceKeyA RegReplaceKey;\n    alias RegSaveKeyA RegSaveKey;\n    alias RegSetValueExA RegSetValueEx;\n    alias RegUnLoadKeyA RegUnLoadKey;\n    alias AbortSystemShutdownA AbortSystemShutdown;\n    alias InitiateSystemShutdownA InitiateSystemShutdown;\n    alias RegRestoreKeyW RegRestoreKey;\n    static if (_WIN32_WINNT >= 0x501) {\n        alias RegSaveKeyExA RegSaveKeyEx;\n    }\n    static if (_WIN32_WINNT >= 0x600) {\n        alias RegGetValueA RegGetValue;\n    }\n    //deprecated {\n        alias RegCreateKeyA RegCreateKey;\n        alias RegEnumKeyA RegEnumKey;\n        alias RegOpenKeyA RegOpenKey;\n        alias RegQueryValueA RegQueryValue;\n        alias RegSetValueA RegSetValue;\n    //}\n}\n\nalias VALENT* PVALENT;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winsock2.d",
    "content": "/*\n    Written by Christopher E. Miller\n    $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n*/\n\n\nmodule core.sys.windows.winsock2;\nversion (Windows):\n\npragma(lib, \"ws2_32\");\n\nextern(Windows):\nnothrow:\n\nalias SOCKET = size_t;\nalias socklen_t = int;\n\nenum SOCKET INVALID_SOCKET = cast(SOCKET)~0;\nenum int SOCKET_ERROR = -1;\n\nenum WSADESCRIPTION_LEN = 256;\nenum WSASYS_STATUS_LEN = 128;\n\nstruct WSADATA\n{\n    ushort wVersion;\n    ushort wHighVersion;\n    char[WSADESCRIPTION_LEN + 1] szDescription;\n    char[WSASYS_STATUS_LEN + 1] szSystemStatus;\n    ushort iMaxSockets;\n    ushort iMaxUdpDg;\n    char* lpVendorInfo;\n}\nalias LPWSADATA = WSADATA*;\n\n\nenum int IOCPARM_MASK =  0x7F;\nenum int IOC_IN =        cast(int)0x80000000;\nenum int FIONBIO =       cast(int)(IOC_IN | ((uint.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 126);\n\nenum NI_MAXHOST = 1025;\nenum NI_MAXSERV = 32;\n\n@nogc\n{\nint WSAStartup(ushort wVersionRequested, LPWSADATA lpWSAData);\nint WSACleanup();\nSOCKET socket(int af, int type, int protocol);\nint ioctlsocket(SOCKET s, int cmd, uint* argp);\nint bind(SOCKET s, const(sockaddr)* name, socklen_t namelen);\nint connect(SOCKET s, const(sockaddr)* name, socklen_t namelen);\nint listen(SOCKET s, int backlog);\nSOCKET accept(SOCKET s, sockaddr* addr, socklen_t* addrlen);\nint closesocket(SOCKET s);\nint shutdown(SOCKET s, int how);\nint getpeername(SOCKET s, sockaddr* name, socklen_t* namelen);\nint getsockname(SOCKET s, sockaddr* name, socklen_t* namelen);\nint send(SOCKET s, const(void)* buf, int len, int flags);\nint sendto(SOCKET s, const(void)* buf, int len, int flags, const(sockaddr)* to, socklen_t tolen);\nint recv(SOCKET s, void* buf, int len, int flags);\nint recvfrom(SOCKET s, void* buf, int len, int flags, sockaddr* from, socklen_t* fromlen);\nint getsockopt(SOCKET s, int level, int optname, void* optval, socklen_t* optlen);\nint setsockopt(SOCKET s, int level, int optname, const(void)* optval, socklen_t optlen);\nuint inet_addr(const char* cp);\nint select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, const(timeval)* timeout);\nchar* inet_ntoa(in_addr ina);\nhostent* gethostbyname(const char* name);\nhostent* gethostbyaddr(const(void)* addr, int len, int type);\nprotoent* getprotobyname(const char* name);\nprotoent* getprotobynumber(int number);\nservent* getservbyname(const char* name, const char* proto);\nservent* getservbyport(int port, const char* proto);\n}\n\nenum: int\n{\n    NI_NOFQDN =          0x01,\n    NI_NUMERICHOST =     0x02,\n    NI_NAMEREQD =        0x04,\n    NI_NUMERICSERV =     0x08,\n    NI_DGRAM  =          0x10,\n}\n\n@nogc\n{\nint gethostname(const char* name, int namelen);\nint getaddrinfo(const(char)* nodename, const(char)* servname, const(addrinfo)* hints, addrinfo** res);\nvoid freeaddrinfo(addrinfo* ai);\nint getnameinfo(const(sockaddr)* sa, socklen_t salen, char* host, uint hostlen, char* serv, uint servlen, int flags);\n}\n\nenum WSABASEERR = 10000;\n\nenum: int\n{\n    /*\n     * Windows Sockets definitions of regular Microsoft C error constants\n     */\n    WSAEINTR = (WSABASEERR+4),\n    WSAEBADF = (WSABASEERR+9),\n    WSAEACCES = (WSABASEERR+13),\n    WSAEFAULT = (WSABASEERR+14),\n    WSAEINVAL = (WSABASEERR+22),\n    WSAEMFILE = (WSABASEERR+24),\n\n    /*\n     * Windows Sockets definitions of regular Berkeley error constants\n     */\n    WSAEWOULDBLOCK = (WSABASEERR+35),\n    WSAEINPROGRESS = (WSABASEERR+36),\n    WSAEALREADY = (WSABASEERR+37),\n    WSAENOTSOCK = (WSABASEERR+38),\n    WSAEDESTADDRREQ = (WSABASEERR+39),\n    WSAEMSGSIZE = (WSABASEERR+40),\n    WSAEPROTOTYPE = (WSABASEERR+41),\n    WSAENOPROTOOPT = (WSABASEERR+42),\n    WSAEPROTONOSUPPORT = (WSABASEERR+43),\n    WSAESOCKTNOSUPPORT = (WSABASEERR+44),\n    WSAEOPNOTSUPP = (WSABASEERR+45),\n    WSAEPFNOSUPPORT = (WSABASEERR+46),\n    WSAEAFNOSUPPORT = (WSABASEERR+47),\n    WSAEADDRINUSE = (WSABASEERR+48),\n    WSAEADDRNOTAVAIL = (WSABASEERR+49),\n    WSAENETDOWN = (WSABASEERR+50),\n    WSAENETUNREACH = (WSABASEERR+51),\n    WSAENETRESET = (WSABASEERR+52),\n    WSAECONNABORTED = (WSABASEERR+53),\n    WSAECONNRESET = (WSABASEERR+54),\n    WSAENOBUFS = (WSABASEERR+55),\n    WSAEISCONN = (WSABASEERR+56),\n    WSAENOTCONN = (WSABASEERR+57),\n    WSAESHUTDOWN = (WSABASEERR+58),\n    WSAETOOMANYREFS = (WSABASEERR+59),\n    WSAETIMEDOUT = (WSABASEERR+60),\n    WSAECONNREFUSED = (WSABASEERR+61),\n    WSAELOOP = (WSABASEERR+62),\n    WSAENAMETOOLONG = (WSABASEERR+63),\n    WSAEHOSTDOWN = (WSABASEERR+64),\n    WSAEHOSTUNREACH = (WSABASEERR+65),\n    WSAENOTEMPTY = (WSABASEERR+66),\n    WSAEPROCLIM = (WSABASEERR+67),\n    WSAEUSERS = (WSABASEERR+68),\n    WSAEDQUOT = (WSABASEERR+69),\n    WSAESTALE = (WSABASEERR+70),\n    WSAEREMOTE = (WSABASEERR+71),\n\n    /*\n     * Extended Windows Sockets error constant definitions\n     */\n    WSASYSNOTREADY = (WSABASEERR+91),\n    WSAVERNOTSUPPORTED = (WSABASEERR+92),\n    WSANOTINITIALISED = (WSABASEERR+93),\n\n    /* Authoritative Answer: Host not found */\n    WSAHOST_NOT_FOUND = (WSABASEERR+1001),\n    HOST_NOT_FOUND = WSAHOST_NOT_FOUND,\n\n    /* Non-Authoritative: Host not found, or SERVERFAIL */\n    WSATRY_AGAIN = (WSABASEERR+1002),\n    TRY_AGAIN = WSATRY_AGAIN,\n\n    /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */\n    WSANO_RECOVERY = (WSABASEERR+1003),\n    NO_RECOVERY = WSANO_RECOVERY,\n\n    /* Valid name, no data record of requested type */\n    WSANO_DATA = (WSABASEERR+1004),\n    NO_DATA = WSANO_DATA,\n\n    /* no address, look for MX record */\n    WSANO_ADDRESS = WSANO_DATA,\n    NO_ADDRESS = WSANO_ADDRESS\n}\n\n/*\n * Windows Sockets errors redefined as regular Berkeley error constants\n */\nenum: int\n{\n    EWOULDBLOCK = WSAEWOULDBLOCK,\n    EINPROGRESS = WSAEINPROGRESS,\n    EALREADY = WSAEALREADY,\n    ENOTSOCK = WSAENOTSOCK,\n    EDESTADDRREQ = WSAEDESTADDRREQ,\n    EMSGSIZE = WSAEMSGSIZE,\n    EPROTOTYPE = WSAEPROTOTYPE,\n    ENOPROTOOPT = WSAENOPROTOOPT,\n    EPROTONOSUPPORT = WSAEPROTONOSUPPORT,\n    ESOCKTNOSUPPORT = WSAESOCKTNOSUPPORT,\n    EOPNOTSUPP = WSAEOPNOTSUPP,\n    EPFNOSUPPORT = WSAEPFNOSUPPORT,\n    EAFNOSUPPORT = WSAEAFNOSUPPORT,\n    EADDRINUSE = WSAEADDRINUSE,\n    EADDRNOTAVAIL = WSAEADDRNOTAVAIL,\n    ENETDOWN = WSAENETDOWN,\n    ENETUNREACH = WSAENETUNREACH,\n    ENETRESET = WSAENETRESET,\n    ECONNABORTED = WSAECONNABORTED,\n    ECONNRESET = WSAECONNRESET,\n    ENOBUFS = WSAENOBUFS,\n    EISCONN = WSAEISCONN,\n    ENOTCONN = WSAENOTCONN,\n    ESHUTDOWN = WSAESHUTDOWN,\n    ETOOMANYREFS = WSAETOOMANYREFS,\n    ETIMEDOUT = WSAETIMEDOUT,\n    ECONNREFUSED = WSAECONNREFUSED,\n    ELOOP = WSAELOOP,\n    ENAMETOOLONG = WSAENAMETOOLONG,\n    EHOSTDOWN = WSAEHOSTDOWN,\n    EHOSTUNREACH = WSAEHOSTUNREACH,\n    ENOTEMPTY = WSAENOTEMPTY,\n    EPROCLIM = WSAEPROCLIM,\n    EUSERS = WSAEUSERS,\n    EDQUOT = WSAEDQUOT,\n    ESTALE = WSAESTALE,\n    EREMOTE = WSAEREMOTE\n}\n\nenum: int\n{\n    EAI_NONAME    = WSAHOST_NOT_FOUND,\n}\n\nint WSAGetLastError() @trusted @nogc;\n\n\nenum: int\n{\n    AF_UNSPEC =     0,\n\n    AF_UNIX =       1,\n    AF_INET =       2,\n    AF_IMPLINK =    3,\n    AF_PUP =        4,\n    AF_CHAOS =      5,\n    AF_NS =         6,\n    AF_IPX =        AF_NS,\n    AF_ISO =        7,\n    AF_OSI =        AF_ISO,\n    AF_ECMA =       8,\n    AF_DATAKIT =    9,\n    AF_CCITT =      10,\n    AF_SNA =        11,\n    AF_DECnet =     12,\n    AF_DLI =        13,\n    AF_LAT =        14,\n    AF_HYLINK =     15,\n    AF_APPLETALK =  16,\n    AF_NETBIOS =    17,\n    AF_VOICEVIEW =  18,\n    AF_FIREFOX =    19,\n    AF_UNKNOWN1 =   20,\n    AF_BAN =        21,\n    AF_ATM =        22,\n    AF_INET6 =      23,\n    AF_CLUSTER =    24,\n    AF_12844 =      25,\n    AF_IRDA =       26,\n    AF_NETDES =     28,\n\n    AF_MAX =        29,\n\n\n    PF_UNSPEC     = AF_UNSPEC,\n\n    PF_UNIX =       AF_UNIX,\n    PF_INET =       AF_INET,\n    PF_IMPLINK =    AF_IMPLINK,\n    PF_PUP =        AF_PUP,\n    PF_CHAOS =      AF_CHAOS,\n    PF_NS =         AF_NS,\n    PF_IPX =        AF_IPX,\n    PF_ISO =        AF_ISO,\n    PF_OSI =        AF_OSI,\n    PF_ECMA =       AF_ECMA,\n    PF_DATAKIT =    AF_DATAKIT,\n    PF_CCITT =      AF_CCITT,\n    PF_SNA =        AF_SNA,\n    PF_DECnet =     AF_DECnet,\n    PF_DLI =        AF_DLI,\n    PF_LAT =        AF_LAT,\n    PF_HYLINK =     AF_HYLINK,\n    PF_APPLETALK =  AF_APPLETALK,\n    PF_VOICEVIEW =  AF_VOICEVIEW,\n    PF_FIREFOX =    AF_FIREFOX,\n    PF_UNKNOWN1 =   AF_UNKNOWN1,\n    PF_BAN =        AF_BAN,\n    PF_INET6 =      AF_INET6,\n\n    PF_MAX        = AF_MAX,\n}\n\n\nenum: int\n{\n    SOL_SOCKET = 0xFFFF,\n}\n\n\nenum: int\n{\n    SO_DEBUG =        0x0001,\n    SO_ACCEPTCONN =   0x0002,\n    SO_REUSEADDR =    0x0004,\n    SO_KEEPALIVE =    0x0008,\n    SO_DONTROUTE =    0x0010,\n    SO_BROADCAST =    0x0020,\n    SO_USELOOPBACK =  0x0040,\n    SO_LINGER =       0x0080,\n    SO_DONTLINGER =   ~SO_LINGER,\n    SO_OOBINLINE =    0x0100,\n    SO_SNDBUF =       0x1001,\n    SO_RCVBUF =       0x1002,\n    SO_SNDLOWAT =     0x1003,\n    SO_RCVLOWAT =     0x1004,\n    SO_SNDTIMEO =     0x1005,\n    SO_RCVTIMEO =     0x1006,\n    SO_ERROR =        0x1007,\n    SO_TYPE =         0x1008,\n    SO_EXCLUSIVEADDRUSE = ~SO_REUSEADDR,\n\n    TCP_NODELAY =    1,\n\n    IP_OPTIONS                  = 1,\n\n    IP_HDRINCL                  = 2,\n    IP_TOS                      = 3,\n    IP_TTL                      = 4,\n    IP_MULTICAST_IF             = 9,\n    IP_MULTICAST_TTL            = 10,\n    IP_MULTICAST_LOOP           = 11,\n    IP_ADD_MEMBERSHIP           = 12,\n    IP_DROP_MEMBERSHIP          = 13,\n    IP_DONTFRAGMENT             = 14,\n    IP_ADD_SOURCE_MEMBERSHIP    = 15,\n    IP_DROP_SOURCE_MEMBERSHIP   = 16,\n    IP_BLOCK_SOURCE             = 17,\n    IP_UNBLOCK_SOURCE           = 18,\n    IP_PKTINFO                  = 19,\n\n    IPV6_UNICAST_HOPS =    4,\n    IPV6_MULTICAST_IF =    9,\n    IPV6_MULTICAST_HOPS =  10,\n    IPV6_MULTICAST_LOOP =  11,\n    IPV6_ADD_MEMBERSHIP =  12,\n    IPV6_DROP_MEMBERSHIP = 13,\n    IPV6_JOIN_GROUP =      IPV6_ADD_MEMBERSHIP,\n    IPV6_LEAVE_GROUP =     IPV6_DROP_MEMBERSHIP,\n    IPV6_V6ONLY = 27,\n}\n\n\n/// Default FD_SETSIZE value.\n/// In C/C++, it is redefinable by #define-ing the macro before #include-ing\n/// winsock.h. In D, use the $(D FD_CREATE) function to allocate a $(D fd_set)\n/// of an arbitrary size.\nenum int FD_SETSIZE = 64;\n\n\nstruct fd_set_custom(uint SETSIZE)\n{\n    uint fd_count;\n    SOCKET[SETSIZE] fd_array;\n}\n\nalias fd_set = fd_set_custom!FD_SETSIZE;\n\n// Removes.\nvoid FD_CLR(SOCKET fd, fd_set* set) pure @nogc\n{\n    uint c = set.fd_count;\n    SOCKET* start = set.fd_array.ptr;\n    SOCKET* stop = start + c;\n\n    for (; start != stop; start++)\n    {\n        if (*start == fd)\n            goto found;\n    }\n    return; //not found\n\n    found:\n    for (++start; start != stop; start++)\n    {\n        *(start - 1) = *start;\n    }\n\n    set.fd_count = c - 1;\n}\n\n\n// Tests.\nint FD_ISSET(SOCKET fd, const(fd_set)* set) pure @nogc\n{\nconst(SOCKET)* start = set.fd_array.ptr;\nconst(SOCKET)* stop = start + set.fd_count;\n\n    for (; start != stop; start++)\n    {\n        if (*start == fd)\n            return true;\n    }\n    return false;\n}\n\n\n// Adds.\nvoid FD_SET(SOCKET fd, fd_set* set)     pure @nogc\n{\n    uint c = set.fd_count;\n    set.fd_array.ptr[c] = fd;\n    set.fd_count = c + 1;\n}\n\n\n// Resets to zero.\nvoid FD_ZERO(fd_set* set) pure @nogc\n{\n    set.fd_count = 0;\n}\n\n\n/// Creates a new $(D fd_set) with the specified capacity.\nfd_set* FD_CREATE(uint capacity) pure\n{\n    // Take into account alignment (SOCKET may be 64-bit and require 64-bit alignment on 64-bit systems)\n    size_t size = (fd_set_custom!1).sizeof - SOCKET.sizeof + (SOCKET.sizeof * capacity);\n    auto data = new ubyte[size];\n    auto set = cast(fd_set*)data.ptr;\n    FD_ZERO(set);\n    return set;\n}\n\nstruct linger\n{\n    ushort l_onoff;\n    ushort l_linger;\n}\n\n\nstruct protoent\n{\n    char* p_name;\n    char** p_aliases;\n    short p_proto;\n}\n\n\nstruct servent\n{\n    char* s_name;\n    char** s_aliases;\n\n    version (Win64)\n    {\n        char* s_proto;\n        short s_port;\n    }\n    else version (Win32)\n    {\n        short s_port;\n        char* s_proto;\n    }\n}\n\n\n/+\nunion in6_addr\n{\n    private union _u_t\n    {\n        ubyte[16] Byte;\n        ushort[8] Word;\n    }\n    _u_t u;\n}\n\n\nstruct in_addr6\n{\n    ubyte[16] s6_addr;\n}\n+/\n\n@safe pure @nogc\n{\n    ushort htons(ushort x);\n    uint htonl(uint x);\n    ushort ntohs(ushort x);\n    uint ntohl(uint x);\n}\n\n\nenum: int\n{\n    SOCK_STREAM =     1,\n    SOCK_DGRAM =      2,\n    SOCK_RAW =        3,\n    SOCK_RDM =        4,\n    SOCK_SEQPACKET =  5,\n}\n\n\nenum: int\n{\n    IPPROTO_IP =    0,\n    IPPROTO_ICMP =  1,\n    IPPROTO_IGMP =  2,\n    IPPROTO_GGP =   3,\n    IPPROTO_TCP =   6,\n    IPPROTO_PUP =   12,\n    IPPROTO_UDP =   17,\n    IPPROTO_IDP =   22,\n    IPPROTO_IPV6 =  41,\n    IPPROTO_ND =    77,\n    IPPROTO_RAW =   255,\n\n    IPPROTO_MAX =   256,\n}\n\n\nenum: int\n{\n    MSG_OOB =        0x1,\n    MSG_PEEK =       0x2,\n    MSG_DONTROUTE =  0x4\n}\n\n\nenum: int\n{\n    SD_RECEIVE =  0,\n    SD_SEND =     1,\n    SD_BOTH =     2,\n}\n\n\nenum: uint\n{\n    INADDR_ANY =        0,\n    INADDR_LOOPBACK =   0x7F000001,\n    INADDR_BROADCAST =  0xFFFFFFFF,\n    INADDR_NONE =       0xFFFFFFFF,\n    ADDR_ANY =          INADDR_ANY,\n}\n\n\nenum: int\n{\n    AI_PASSIVE = 0x1,\n    AI_CANONNAME = 0x2,\n    AI_NUMERICHOST = 0x4,\n    AI_ADDRCONFIG = 0x0400,\n    AI_NON_AUTHORITATIVE = 0x04000,\n    AI_SECURE = 0x08000,\n    AI_RETURN_PREFERRED_NAMES = 0x010000,\n}\n\n\nstruct timeval\n{\n    int tv_sec;\n    int tv_usec;\n}\n\n\nunion in_addr\n{\n    private union _S_un_t\n    {\n        private struct _S_un_b_t\n        {\n            ubyte s_b1, s_b2, s_b3, s_b4;\n        }\n        _S_un_b_t S_un_b;\n\n        private struct _S_un_w_t\n        {\n            ushort s_w1, s_w2;\n        }\n        _S_un_w_t S_un_w;\n\n        uint S_addr;\n    }\n    _S_un_t S_un;\n\n    uint s_addr;\n\n    struct\n    {\n        ubyte s_net, s_host;\n\n        union\n        {\n            ushort s_imp;\n\n            struct\n            {\n                ubyte s_lh, s_impno;\n            }\n        }\n    }\n}\n\n\nunion in6_addr\n{\n    private union _in6_u_t\n    {\n        ubyte[16] u6_addr8;\n        ushort[8] u6_addr16;\n        uint[4] u6_addr32;\n    }\n    _in6_u_t in6_u;\n\n    ubyte[16] s6_addr8;\n    ushort[8] s6_addr16;\n    uint[4] s6_addr32;\n\n    alias s6_addr = s6_addr8;\n}\n\n\nenum in6_addr IN6ADDR_ANY = { s6_addr8: [0] };\nenum in6_addr IN6ADDR_LOOPBACK = { s6_addr8: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] };\n//alias IN6ADDR_ANY_INIT = IN6ADDR_ANY;\n//alias IN6ADDR_LOOPBACK_INIT = IN6ADDR_LOOPBACK;\n\nenum int INET_ADDRSTRLEN = 16;\nenum int INET6_ADDRSTRLEN = 46;\n\n\n\n\nstruct sockaddr\n{\n    short sa_family;\n    ubyte[14] sa_data;\n}\nalias sockaddr SOCKADDR;\nalias SOCKADDR* PSOCKADDR, LPSOCKADDR;\n\nstruct sockaddr_storage\n{\n    short     ss_family;\n    char[6]   __ss_pad1;\n    long      __ss_align;\n    char[112] __ss_pad2;\n}\nalias sockaddr_storage SOCKADDR_STORAGE;\nalias SOCKADDR_STORAGE* PSOCKADDR_STORAGE;\n\nstruct sockaddr_in\n{\n    short sin_family = AF_INET;\n    ushort sin_port;\n    in_addr sin_addr;\n    ubyte[8] sin_zero;\n}\nalias sockaddr_in SOCKADDR_IN;\nalias SOCKADDR_IN* PSOCKADDR_IN, LPSOCKADDR_IN;\n\n\nstruct sockaddr_in6\n{\n    short sin6_family = AF_INET6;\n    ushort sin6_port;\n    uint sin6_flowinfo;\n    in6_addr sin6_addr;\n    uint sin6_scope_id;\n}\n\n\nstruct addrinfo\n{\n    int ai_flags;\n    int ai_family;\n    int ai_socktype;\n    int ai_protocol;\n    size_t ai_addrlen;\n    char* ai_canonname;\n    sockaddr* ai_addr;\n    addrinfo* ai_next;\n}\n\n\nstruct hostent\n{\n    char* h_name;\n    char** h_aliases;\n    short h_addrtype;\n    short h_length;\n    char** h_addr_list;\n\n\n    char* h_addr() @safe pure nothrow @nogc\n    {\n        return h_addr_list[0];\n    }\n}\n\n// Note: These are Winsock2!!\nstruct WSAOVERLAPPED;\nalias LPWSAOVERLAPPED = WSAOVERLAPPED*;\nalias LPWSAOVERLAPPED_COMPLETION_ROUTINE = void function(uint, uint, LPWSAOVERLAPPED, uint);\nint WSAIoctl(SOCKET s, uint dwIoControlCode,\n    void* lpvInBuffer, uint cbInBuffer,\n    void* lpvOutBuffer, uint cbOutBuffer,\n    uint* lpcbBytesReturned,\n    LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);\n\n\nenum IOC_VENDOR = 0x18000000;\nenum SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4;\n\n/* Argument structure for SIO_KEEPALIVE_VALS */\nstruct tcp_keepalive\n{\n    uint onoff;\n    uint keepalivetime;\n    uint keepaliveinterval;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winspool.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winspool.d)\n */\nmodule core.sys.windows.winspool;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"winspool\");\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.wingdi;\nprivate import core.sys.windows.winbase; // for SYSTEMTIME\n\n// FIXME: clean up Windows version support\n\nenum DI_CHANNEL=1;\nenum DI_CHANNEL_WRITE=2;\nenum DI_READ_SPOOL_JOB=3;\n\nenum FORM_BUILTIN=1;\n\nenum JOB_CONTROL_PAUSE=1;\nenum JOB_CONTROL_RESUME=2;\nenum JOB_CONTROL_CANCEL=3;\nenum JOB_CONTROL_RESTART=4;\nenum JOB_CONTROL_DELETE=5;\nenum JOB_STATUS_PAUSED=1;\nenum JOB_STATUS_ERROR=2;\nenum JOB_STATUS_DELETING=4;\nenum JOB_STATUS_SPOOLING=8;\nenum JOB_STATUS_PRINTING=16;\nenum JOB_STATUS_OFFLINE=32;\nenum JOB_STATUS_PAPEROUT=0x40;\nenum JOB_STATUS_PRINTED=0x80;\nenum JOB_STATUS_DELETED=0x100;\nenum JOB_STATUS_BLOCKED_DEVQ=0x200;\nenum JOB_STATUS_USER_INTERVENTION=0x400;\n\nenum JOB_POSITION_UNSPECIFIED=0;\n\nenum JOB_NOTIFY_TYPE=1;\n\nenum JOB_NOTIFY_FIELD_PRINTER_NAME=0;\nenum JOB_NOTIFY_FIELD_MACHINE_NAME=1;\nenum JOB_NOTIFY_FIELD_PORT_NAME=2;\nenum JOB_NOTIFY_FIELD_USER_NAME=3;\nenum JOB_NOTIFY_FIELD_NOTIFY_NAME=4;\nenum JOB_NOTIFY_FIELD_DATATYPE=5;\nenum JOB_NOTIFY_FIELD_PRINT_PROCESSOR=6;\nenum JOB_NOTIFY_FIELD_PARAMETERS=7;\nenum JOB_NOTIFY_FIELD_DRIVER_NAME=8;\nenum JOB_NOTIFY_FIELD_DEVMODE=9;\nenum JOB_NOTIFY_FIELD_STATUS=10;\nenum JOB_NOTIFY_FIELD_STATUS_STRING=11;\nenum JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR=12;\nenum JOB_NOTIFY_FIELD_DOCUMENT=13;\nenum JOB_NOTIFY_FIELD_PRIORITY=14;\nenum JOB_NOTIFY_FIELD_POSITION=15;\nenum JOB_NOTIFY_FIELD_SUBMITTED=16;\nenum JOB_NOTIFY_FIELD_START_TIME=17;\nenum JOB_NOTIFY_FIELD_UNTIL_TIME=18;\nenum JOB_NOTIFY_FIELD_TIME=19;\nenum JOB_NOTIFY_FIELD_TOTAL_PAGES=20;\nenum JOB_NOTIFY_FIELD_PAGES_PRINTED=21;\nenum JOB_NOTIFY_FIELD_TOTAL_BYTES=22;\nenum JOB_NOTIFY_FIELD_BYTES_PRINTED=23;\n\nenum JOB_ACCESS_ADMINISTER = 16;\nenum JOB_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | JOB_ACCESS_ADMINISTER;\nenum JOB_READ       = STANDARD_RIGHTS_READ     | JOB_ACCESS_ADMINISTER;\nenum JOB_WRITE      = STANDARD_RIGHTS_WRITE    | JOB_ACCESS_ADMINISTER;\nenum JOB_EXECUTE    = STANDARD_RIGHTS_EXECUTE  | JOB_ACCESS_ADMINISTER;\n\nenum PRINTER_NOTIFY_OPTIONS_REFRESH=1;\nenum PRINTER_ACCESS_ADMINISTER=4;\nenum PRINTER_ACCESS_USE=8;\n\nenum PRINTER_ERROR_INFORMATION=0x80000000;\nenum PRINTER_ERROR_WARNING=0x40000000;\nenum PRINTER_ERROR_SEVERE=0x20000000;\nenum PRINTER_ERROR_OUTOFPAPER=1;\nenum PRINTER_ERROR_JAM=2;\nenum PRINTER_ERROR_OUTOFTONER=4;\n\nenum PRINTER_CONTROL_PAUSE=1;\nenum PRINTER_CONTROL_RESUME=2;\nenum PRINTER_CONTROL_PURGE=3;\nenum PRINTER_CONTROL_SET_STATUS=4;\n\nenum PRINTER_STATUS_PAUSED = 1;\nenum PRINTER_STATUS_ERROR = 2;\nenum PRINTER_STATUS_PENDING_DELETION = 4;\nenum PRINTER_STATUS_PAPER_JAM = 8;\nenum PRINTER_STATUS_PAPER_OUT = 0x10;\nenum PRINTER_STATUS_MANUAL_FEED = 0x20;\nenum PRINTER_STATUS_PAPER_PROBLEM = 0x40;\nenum PRINTER_STATUS_OFFLINE = 0x80;\nenum PRINTER_STATUS_IO_ACTIVE = 0x100;\nenum PRINTER_STATUS_BUSY = 0x200;\nenum PRINTER_STATUS_PRINTING = 0x400;\nenum PRINTER_STATUS_OUTPUT_BIN_FULL = 0x800;\nenum PRINTER_STATUS_NOT_AVAILABLE = 0x1000;\nenum PRINTER_STATUS_WAITING = 0x2000;\nenum PRINTER_STATUS_PROCESSING = 0x4000;\nenum PRINTER_STATUS_INITIALIZING = 0x8000;\nenum PRINTER_STATUS_WARMING_UP = 0x10000;\nenum PRINTER_STATUS_TONER_LOW = 0x20000;\nenum PRINTER_STATUS_NO_TONER = 0x40000;\nenum PRINTER_STATUS_PAGE_PUNT = 0x80000;\nenum PRINTER_STATUS_USER_INTERVENTION = 0x100000;\nenum PRINTER_STATUS_OUT_OF_MEMORY = 0x200000;\nenum PRINTER_STATUS_DOOR_OPEN = 0x400000;\nenum PRINTER_STATUS_SERVER_UNKNOWN = 0x800000;\nenum PRINTER_STATUS_POWER_SAVE = 0x1000000;\n\nenum PRINTER_ATTRIBUTE_QUEUED=1;\nenum PRINTER_ATTRIBUTE_DIRECT=2;\nenum PRINTER_ATTRIBUTE_DEFAULT=4;\nenum PRINTER_ATTRIBUTE_SHARED=8;\nenum PRINTER_ATTRIBUTE_NETWORK=0x10;\nenum PRINTER_ATTRIBUTE_HIDDEN=0x20;\nenum PRINTER_ATTRIBUTE_LOCAL=0x40;\nenum PRINTER_ATTRIBUTE_ENABLE_DEVQ=0x80;\nenum PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS=0x100;\nenum PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST=0x200;\nenum PRINTER_ATTRIBUTE_WORK_OFFLINE=0x400;\nenum PRINTER_ATTRIBUTE_ENABLE_BIDI=0x800;\nenum PRINTER_ATTRIBUTE_RAW_ONLY=0x1000;\nenum PRINTER_ATTRIBUTE_PUBLISHED=0x2000;\n\nenum PRINTER_ENUM_DEFAULT=1;\nenum PRINTER_ENUM_LOCAL=2;\nenum PRINTER_ENUM_CONNECTIONS=4;\nenum PRINTER_ENUM_FAVORITE=4;\nenum PRINTER_ENUM_NAME=8;\nenum PRINTER_ENUM_REMOTE=16;\nenum PRINTER_ENUM_SHARED=32;\nenum PRINTER_ENUM_NETWORK=0x40;\nenum PRINTER_ENUM_EXPAND=0x4000;\nenum PRINTER_ENUM_CONTAINER=0x8000;\nenum PRINTER_ENUM_ICONMASK=0xff0000;\nenum PRINTER_ENUM_ICON1=0x10000;\nenum PRINTER_ENUM_ICON2=0x20000;\nenum PRINTER_ENUM_ICON3=0x40000;\nenum PRINTER_ENUM_ICON4=0x80000;\nenum PRINTER_ENUM_ICON5=0x100000;\nenum PRINTER_ENUM_ICON6=0x200000;\nenum PRINTER_ENUM_ICON7=0x400000;\nenum PRINTER_ENUM_ICON8=0x800000;\n\nenum PRINTER_NOTIFY_TYPE=0;\n\nenum PRINTER_NOTIFY_FIELD_SERVER_NAME=0;\nenum PRINTER_NOTIFY_FIELD_PRINTER_NAME=1;\nenum PRINTER_NOTIFY_FIELD_SHARE_NAME=2;\nenum PRINTER_NOTIFY_FIELD_PORT_NAME=3;\nenum PRINTER_NOTIFY_FIELD_DRIVER_NAME=4;\nenum PRINTER_NOTIFY_FIELD_COMMENT=5;\nenum PRINTER_NOTIFY_FIELD_LOCATION=6;\nenum PRINTER_NOTIFY_FIELD_DEVMODE=7;\nenum PRINTER_NOTIFY_FIELD_SEPFILE=8;\nenum PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR=9;\nenum PRINTER_NOTIFY_FIELD_PARAMETERS=10;\nenum PRINTER_NOTIFY_FIELD_DATATYPE=11;\nenum PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR=12;\nenum PRINTER_NOTIFY_FIELD_ATTRIBUTES=13;\nenum PRINTER_NOTIFY_FIELD_PRIORITY=14;\nenum PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY=15;\nenum PRINTER_NOTIFY_FIELD_START_TIME=16;\nenum PRINTER_NOTIFY_FIELD_UNTIL_TIME=17;\nenum PRINTER_NOTIFY_FIELD_STATUS=18;\nenum PRINTER_NOTIFY_FIELD_STATUS_STRING=19;\nenum PRINTER_NOTIFY_FIELD_CJOBS=20;\nenum PRINTER_NOTIFY_FIELD_AVERAGE_PPM=21;\nenum PRINTER_NOTIFY_FIELD_TOTAL_PAGES=22;\nenum PRINTER_NOTIFY_FIELD_PAGES_PRINTED=23;\nenum PRINTER_NOTIFY_FIELD_TOTAL_BYTES=24;\nenum PRINTER_NOTIFY_FIELD_BYTES_PRINTED=25;\n\nenum PRINTER_CHANGE_ADD_PRINTER=1;\nenum PRINTER_CHANGE_SET_PRINTER=2;\nenum PRINTER_CHANGE_DELETE_PRINTER=4;\nenum PRINTER_CHANGE_FAILED_CONNECTION_PRINTER=8;\nenum PRINTER_CHANGE_PRINTER=0xFF;\nenum PRINTER_CHANGE_ADD_JOB=0x100;\nenum PRINTER_CHANGE_SET_JOB=0x200;\nenum PRINTER_CHANGE_DELETE_JOB=0x400;\nenum PRINTER_CHANGE_WRITE_JOB=0x800;\nenum PRINTER_CHANGE_JOB=0xFF00;\nenum PRINTER_CHANGE_ADD_FORM=0x10000;\nenum PRINTER_CHANGE_SET_FORM=0x20000;\nenum PRINTER_CHANGE_DELETE_FORM=0x40000;\nenum PRINTER_CHANGE_FORM=0x70000;\nenum PRINTER_CHANGE_ADD_PORT=0x100000;\nenum PRINTER_CHANGE_CONFIGURE_PORT=0x200000;\nenum PRINTER_CHANGE_DELETE_PORT=0x400000;\nenum PRINTER_CHANGE_PORT=0x700000;\nenum PRINTER_CHANGE_ADD_PRINT_PROCESSOR=0x1000000;\nenum PRINTER_CHANGE_DELETE_PRINT_PROCESSOR=0x4000000;\nenum PRINTER_CHANGE_PRINT_PROCESSOR=0x7000000;\nenum PRINTER_CHANGE_ADD_PRINTER_DRIVER=0x10000000;\nenum PRINTER_CHANGE_SET_PRINTER_DRIVER=0x20000000;\nenum PRINTER_CHANGE_DELETE_PRINTER_DRIVER=0x40000000;\nenum PRINTER_CHANGE_PRINTER_DRIVER=0x70000000;\nenum PRINTER_CHANGE_TIMEOUT=0x80000000;\nenum PRINTER_CHANGE_ALL=0x7777FFFF;\n\nenum PRINTER_NOTIFY_INFO_DISCARDED=1;\nenum PRINTER_ALL_ACCESS=(STANDARD_RIGHTS_REQUIRED|PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE);\nenum PRINTER_READ=(STANDARD_RIGHTS_READ|PRINTER_ACCESS_USE);\nenum PRINTER_WRITE=(STANDARD_RIGHTS_WRITE|PRINTER_ACCESS_USE);\nenum PRINTER_EXECUTE=(STANDARD_RIGHTS_EXECUTE|PRINTER_ACCESS_USE);\nenum NO_PRIORITY=0;\nenum MAX_PRIORITY=99;\nenum MIN_PRIORITY=1;\nenum DEF_PRIORITY=1;\nenum PORT_TYPE_WRITE=1;\nenum PORT_TYPE_READ=2;\nenum PORT_TYPE_REDIRECTED=4;\nenum PORT_TYPE_NET_ATTACHED=8;\nenum SERVER_ACCESS_ADMINISTER=1;\nenum SERVER_ACCESS_ENUMERATE=2;\n\nenum SERVER_ALL_ACCESS=(STANDARD_RIGHTS_REQUIRED|SERVER_ACCESS_ADMINISTER|SERVER_ACCESS_ENUMERATE);\nenum SERVER_READ=(STANDARD_RIGHTS_READ|SERVER_ACCESS_ENUMERATE);\nenum SERVER_WRITE=(STANDARD_RIGHTS_WRITE|SERVER_ACCESS_ADMINISTER|SERVER_ACCESS_ENUMERATE);\nenum SERVER_EXECUTE=(STANDARD_RIGHTS_EXECUTE|SERVER_ACCESS_ENUMERATE);\n\nenum PORT_STATUS_TYPE_ERROR=1;\nenum PORT_STATUS_TYPE_WARNING=2;\nenum PORT_STATUS_TYPE_INFO=3;\n\nenum PORT_STATUS_OFFLINE=1;\nenum PORT_STATUS_PAPER_JAM=2;\nenum PORT_STATUS_PAPER_OUT=3;\nenum PORT_STATUS_OUTPUT_BIN_FULL=4;\nenum PORT_STATUS_PAPER_PROBLEM=5;\nenum PORT_STATUS_NO_TONER=6;\nenum PORT_STATUS_DOOR_OPEN=7;\nenum PORT_STATUS_USER_INTERVENTION=8;\nenum PORT_STATUS_OUT_OF_MEMORY=9;\nenum PORT_STATUS_TONER_LOW=10;\nenum PORT_STATUS_WARMING_UP=11;\nenum PORT_STATUS_POWER_SAVE=12;\n\nstruct ADDJOB_INFO_1A {\n    LPSTR Path;\n    DWORD JobId;\n}\nalias ADDJOB_INFO_1A* PADDJOB_INFO_1A, LPADDJOB_INFO_1A;\n\nstruct ADDJOB_INFO_1W {\n    LPWSTR Path;\n    DWORD JobId;\n}\nalias ADDJOB_INFO_1W* PADDJOB_INFO_1W, LPADDJOB_INFO_1W;\n\nstruct DATATYPES_INFO_1A {\n    LPSTR pName;\n}\nalias DATATYPES_INFO_1A* PDATATYPES_INFO_1A, LPDATATYPES_INFO_1A;\n\nstruct DATATYPES_INFO_1W {\n    LPWSTR pName;\n}\nalias DATATYPES_INFO_1W* PDATATYPES_INFO_1W, LPDATATYPES_INFO_1W;\n\nstruct JOB_INFO_1A {\n    DWORD JobId;\n    LPSTR pPrinterName;\n    LPSTR pMachineName;\n    LPSTR pUserName;\n    LPSTR pDocument;\n    LPSTR pDatatype;\n    LPSTR pStatus;\n    DWORD Status;\n    DWORD Priority;\n    DWORD Position;\n    DWORD TotalPages;\n    DWORD PagesPrinted;\n    SYSTEMTIME Submitted;\n}\nalias JOB_INFO_1A* PJOB_INFO_1A, LPJOB_INFO_1A;\n\nstruct JOB_INFO_1W {\n    DWORD JobId;\n    LPWSTR pPrinterName;\n    LPWSTR pMachineName;\n    LPWSTR pUserName;\n    LPWSTR pDocument;\n    LPWSTR pDatatype;\n    LPWSTR pStatus;\n    DWORD Status;\n    DWORD Priority;\n    DWORD Position;\n    DWORD TotalPages;\n    DWORD PagesPrinted;\n    SYSTEMTIME Submitted;\n}\nalias JOB_INFO_1W* PJOB_INFO_1W, LPJOB_INFO_1W;\n\nstruct JOB_INFO_2A {\n    DWORD JobId;\n    LPSTR pPrinterName;\n    LPSTR pMachineName;\n    LPSTR pUserName;\n    LPSTR pDocument;\n    LPSTR pNotifyName;\n    LPSTR pDatatype;\n    LPSTR pPrintProcessor;\n    LPSTR pParameters;\n    LPSTR pDriverName;\n    LPDEVMODEA pDevMode;\n    LPSTR pStatus;\n    PSECURITY_DESCRIPTOR pSecurityDescriptor;\n    DWORD Status;\n    DWORD Priority;\n    DWORD Position;\n    DWORD StartTime;\n    DWORD UntilTime;\n    DWORD TotalPages;\n    DWORD Size;\n    SYSTEMTIME Submitted;\n    DWORD Time;\n    DWORD PagesPrinted;\n}\nalias JOB_INFO_2A* PJOB_INFO_2A, LPJOB_INFO_2A;\n\nstruct JOB_INFO_2W {\n    DWORD JobId;\n    LPWSTR pPrinterName;\n    LPWSTR pMachineName;\n    LPWSTR pUserName;\n    LPWSTR pDocument;\n    LPWSTR pNotifyName;\n    LPWSTR pDatatype;\n    LPWSTR pPrintProcessor;\n    LPWSTR pParameters;\n    LPWSTR pDriverName;\n    LPDEVMODEW pDevMode;\n    LPWSTR pStatus;\n    PSECURITY_DESCRIPTOR pSecurityDescriptor;\n    DWORD Status;\n    DWORD Priority;\n    DWORD Position;\n    DWORD StartTime;\n    DWORD UntilTime;\n    DWORD TotalPages;\n    DWORD Size;\n    SYSTEMTIME Submitted;\n    DWORD Time;\n    DWORD PagesPrinted;\n}\nalias JOB_INFO_2W* PJOB_INFO_2W, LPJOB_INFO_2W;\n\nstruct DOC_INFO_1A {\n    LPSTR pDocName;\n    LPSTR pOutputFile;\n    LPSTR pDatatype;\n}\nalias DOC_INFO_1A* PDOC_INFO_1A, LPDOC_INFO_1A;\n\nstruct DOC_INFO_1W {\n    LPWSTR pDocName;\n    LPWSTR pOutputFile;\n    LPWSTR pDatatype;\n}\nalias DOC_INFO_1W* PDOC_INFO_1W, LPDOC_INFO_1W;\n\nstruct DOC_INFO_2A {\n    LPSTR pDocName;\n    LPSTR pOutputFile;\n    LPSTR pDatatype;\n    DWORD dwMode;\n    DWORD JobId;\n}\nalias DOC_INFO_2A* PDOC_INFO_2A, LPDOC_INFO_2A;\n\nstruct DOC_INFO_2W {\n    LPWSTR pDocName;\n    LPWSTR pOutputFile;\n    LPWSTR pDatatype;\n    DWORD  dwMode;\n    DWORD  JobId;\n}\nalias DOC_INFO_2W* PDOC_INFO_2W, LPDOC_INFO_2W;\n\nstruct DRIVER_INFO_1A {\n    LPSTR pName;\n}\nalias DRIVER_INFO_1A* PDRIVER_INFO_1A, LPDRIVER_INFO_1A;\n\nstruct DRIVER_INFO_1W {\n    LPWSTR pName;\n}\nalias DRIVER_INFO_1W* PDRIVER_INFO_1W, LPDRIVER_INFO_1W;\n\nstruct DRIVER_INFO_2A {\n    DWORD cVersion;\n    LPSTR pName;\n    LPSTR pEnvironment;\n    LPSTR pDriverPath;\n    LPSTR pDataFile;\n    LPSTR pConfigFile;\n}\nalias DRIVER_INFO_2A* PDRIVER_INFO_2A, LPDRIVER_INFO_2A;\n\nstruct DRIVER_INFO_2W {\n    DWORD  cVersion;\n    LPWSTR pName;\n    LPWSTR pEnvironment;\n    LPWSTR pDriverPath;\n    LPWSTR pDataFile;\n    LPWSTR pConfigFile;\n}\nalias DRIVER_INFO_2W* PDRIVER_INFO_2W, LPDRIVER_INFO_2W;\n\nstruct DRIVER_INFO_3A {\n    DWORD cVersion;\n    LPSTR pName;\n    LPSTR pEnvironment;\n    LPSTR pDriverPath;\n    LPSTR pDataFile;\n    LPSTR pConfigFile;\n    LPSTR pHelpFile;\n    LPSTR pDependentFiles;\n    LPSTR pMonitorName;\n    LPSTR pDefaultDataType;\n}\nalias DRIVER_INFO_3A* PDRIVER_INFO_3A, LPDRIVER_INFO_3A;\n\nstruct DRIVER_INFO_3W {\n    DWORD  cVersion;\n    LPWSTR pName;\n    LPWSTR pEnvironment;\n    LPWSTR pDriverPath;\n    LPWSTR pDataFile;\n    LPWSTR pConfigFile;\n    LPWSTR pHelpFile;\n    LPWSTR pDependentFiles;\n    LPWSTR pMonitorName;\n    LPWSTR pDefaultDataType;\n}\nalias DRIVER_INFO_3W* PDRIVER_INFO_3W, LPDRIVER_INFO_3W;\n\nstruct MONITOR_INFO_1A {\n    LPSTR pName;\n}\nalias MONITOR_INFO_1A* PMONITOR_INFO_1A, LPMONITOR_INFO_1A;\n\nstruct MONITOR_INFO_1W {\n    LPWSTR pName;\n}\nalias MONITOR_INFO_1W* PMONITOR_INFO_1W, LPMONITOR_INFO_1W;\n\nstruct PORT_INFO_1A {\n    LPSTR pName;\n}\nalias PORT_INFO_1A* PPORT_INFO_1A, LPPORT_INFO_1A;\n\nstruct PORT_INFO_1W {\n    LPWSTR pName;\n}\nalias PORT_INFO_1W* PPORT_INFO_1W, LPPORT_INFO_1W;\n\nstruct MONITOR_INFO_2A {\n    LPSTR pName;\n    LPSTR pEnvironment;\n    LPSTR pDLLName;\n}\nalias MONITOR_INFO_2A* PMONITOR_INFO_2A, LPMONITOR_INFO_2A;\n\nstruct MONITOR_INFO_2W {\n    LPWSTR pName;\n    LPWSTR pEnvironment;\n    LPWSTR pDLLName;\n}\nalias MONITOR_INFO_2W* PMONITOR_INFO_2W, LPMONITOR_INFO_2W;\n\nstruct PORT_INFO_2A {\n    LPSTR pPortName;\n    LPSTR pMonitorName;\n    LPSTR pDescription;\n    DWORD fPortType;\n    DWORD Reserved;\n}\nalias PORT_INFO_2A* PPORT_INFO_2A, LPPORT_INFO_2A;\n\nstruct PORT_INFO_2W {\n    LPWSTR pPortName;\n    LPWSTR pMonitorName;\n    LPWSTR pDescription;\n    DWORD fPortType;\n    DWORD Reserved;\n}\nalias PORT_INFO_2W* PPORT_INFO_2W, LPPORT_INFO_2W;\n\nstruct PORT_INFO_3A {\n    DWORD dwStatus;\n    LPSTR pszStatus;\n    DWORD dwSeverity;\n}\nalias PORT_INFO_3A* PPORT_INFO_3A, LPPORT_INFO_3A;\n\nstruct PORT_INFO_3W {\n    DWORD dwStatus;\n    LPWSTR pszStatus;\n    DWORD dwSeverity;\n}\nalias PORT_INFO_3W* PPORT_INFO_3W, LPPORT_INFO_3W;\n\nstruct PRINTER_INFO_1A {\n    DWORD Flags;\n    LPSTR pDescription;\n    LPSTR pName;\n    LPSTR pComment;\n}\nalias PRINTER_INFO_1A* PPRINTER_INFO_1A, LPPRINTER_INFO_1A;\n\nstruct PRINTER_INFO_1W {\n    DWORD  Flags;\n    LPWSTR pDescription;\n    LPWSTR pName;\n    LPWSTR pComment;\n}\nalias PRINTER_INFO_1W* PPRINTER_INFO_1W, LPPRINTER_INFO_1W;\n\nstruct PRINTER_INFO_2A {\n    LPSTR pServerName;\n    LPSTR pPrinterName;\n    LPSTR pShareName;\n    LPSTR pPortName;\n    LPSTR pDriverName;\n    LPSTR pComment;\n    LPSTR pLocation;\n    LPDEVMODEA pDevMode;\n    LPSTR pSepFile;\n    LPSTR pPrintProcessor;\n    LPSTR pDatatype;\n    LPSTR pParameters;\n    PSECURITY_DESCRIPTOR pSecurityDescriptor;\n    DWORD Attributes;\n    DWORD Priority;\n    DWORD DefaultPriority;\n    DWORD StartTime;\n    DWORD UntilTime;\n    DWORD Status;\n    DWORD cJobs;\n    DWORD AveragePPM;\n}\nalias PRINTER_INFO_2A* PPRINTER_INFO_2A, LPPRINTER_INFO_2A;\n\nstruct PRINTER_INFO_2W {\n    LPWSTR pServerName;\n    LPWSTR pPrinterName;\n    LPWSTR pShareName;\n    LPWSTR pPortName;\n    LPWSTR pDriverName;\n    LPWSTR pComment;\n    LPWSTR pLocation;\n    LPDEVMODEW pDevMode;\n    LPWSTR pSepFile;\n    LPWSTR pPrintProcessor;\n    LPWSTR pDatatype;\n    LPWSTR pParameters;\n    PSECURITY_DESCRIPTOR pSecurityDescriptor;\n    DWORD Attributes;\n    DWORD Priority;\n    DWORD DefaultPriority;\n    DWORD StartTime;\n    DWORD UntilTime;\n    DWORD Status;\n    DWORD cJobs;\n    DWORD AveragePPM;\n}\nalias PRINTER_INFO_2W* PPRINTER_INFO_2W, LPPRINTER_INFO_2W;\n\nstruct PRINTER_INFO_3 {\n    PSECURITY_DESCRIPTOR pSecurityDescriptor;\n}\nalias PRINTER_INFO_3* PPRINTER_INFO_3, LPPRINTER_INFO_3;\n\nstruct PRINTER_INFO_4A {\n    LPSTR pPrinterName;\n    LPSTR pServerName;\n    DWORD Attributes;\n}\nalias PRINTER_INFO_4A* PPRINTER_INFO_4A, LPPRINTER_INFO_4A;\n\nstruct PRINTER_INFO_4W {\n    LPWSTR pPrinterName;\n    LPWSTR pServerName;\n    DWORD Attributes;\n}\nalias PRINTER_INFO_4W* PPRINTER_INFO_4W, LPPRINTER_INFO_4W;\n\nstruct PRINTER_INFO_5A {\n    LPSTR pPrinterName;\n    LPSTR pPortName;\n    DWORD Attributes;\n    DWORD DeviceNotSelectedTimeout;\n    DWORD TransmissionRetryTimeout;\n}\nalias PRINTER_INFO_5A* PPRINTER_INFO_5A, LPPRINTER_INFO_5A;\n\nstruct PRINTER_INFO_5W {\n    LPWSTR pPrinterName;\n    LPWSTR pPortName;\n    DWORD Attributes;\n    DWORD DeviceNotSelectedTimeout;\n    DWORD TransmissionRetryTimeout;\n}\nalias PRINTER_INFO_5W* PPRINTER_INFO_5W, LPPRINTER_INFO_5W;\n\nstruct PRINTER_INFO_6 {\n    DWORD dwStatus;\n}\nalias PRINTER_INFO_6* PPRINTER_INFO_6, LPPRINTER_INFO_6;\n\nstruct PRINTPROCESSOR_INFO_1A {\n    LPSTR pName;\n}\nalias PRINTPROCESSOR_INFO_1A* PPRINTPROCESSOR_INFO_1A, LPPRINTPROCESSOR_INFO_1A;\n\nstruct PRINTPROCESSOR_INFO_1W {\n    LPWSTR pName;\n}\nalias PRINTPROCESSOR_INFO_1W* PPRINTPROCESSOR_INFO_1W, LPPRINTPROCESSOR_INFO_1W;\n\nstruct PRINTER_NOTIFY_INFO_DATA {\n    WORD  Type;\n    WORD  Field;\n    DWORD Reserved;\n    DWORD Id;\n    union _NotifyData {\n        DWORD[2] adwData;\n        struct _Data {\n            DWORD cbBuf;\n            PVOID pBuf;\n        }\n        _Data Data;\n    }\n    _NotifyData NotifyData;\n}\nalias PRINTER_NOTIFY_INFO_DATA* PPRINTER_NOTIFY_INFO_DATA, LPPRINTER_NOTIFY_INFO_DATA;\n\nstruct PRINTER_NOTIFY_INFO {\n    DWORD Version;\n    DWORD Flags;\n    DWORD Count;\n    PRINTER_NOTIFY_INFO_DATA[1] aData;\n}\nalias PRINTER_NOTIFY_INFO* PPRINTER_NOTIFY_INFO, LPPRINTER_NOTIFY_INFO;\n\nstruct FORM_INFO_1A {\n    DWORD Flags;\n    LPSTR pName;\n    SIZEL Size;\n    RECTL ImageableArea;\n}\nalias FORM_INFO_1A* PFORM_INFO_1A, LPFORM_INFO_1A;\n\nstruct FORM_INFO_1W {\n    DWORD  Flags;\n    LPWSTR pName;\n    SIZEL  Size;\n    RECTL  ImageableArea;\n}\nalias FORM_INFO_1W* PFORM_INFO_1W, LPFORM_INFO_1W;\n\nstruct PRINTER_DEFAULTSA {\n    LPSTR       pDatatype;\n    LPDEVMODE   pDevMode;\n    ACCESS_MASK DesiredAccess;\n}\nalias PRINTER_DEFAULTSA* PPRINTER_DEFAULTSA, LPPRINTER_DEFAULTSA;\n\nstruct PRINTER_DEFAULTSW {\n    LPWSTR pDatatype;\n    LPDEVMODE pDevMode;\n    ACCESS_MASK DesiredAccess;\n}\nalias PRINTER_DEFAULTSW* PPRINTER_DEFAULTSW, LPPRINTER_DEFAULTSW;\n\nextern (Windows):\nBOOL AbortPrinter(HANDLE);\nBOOL AddFormA(HANDLE, DWORD, PBYTE);\nBOOL AddFormW(HANDLE, DWORD, PBYTE);\nBOOL AddJobA(HANDLE, DWORD, PBYTE, DWORD, PDWORD);\nBOOL AddJobW(HANDLE, DWORD, PBYTE, DWORD, PDWORD);\nBOOL AddMonitorA(LPSTR, DWORD, PBYTE);\nBOOL AddMonitorW(LPWSTR, DWORD, PBYTE);\nBOOL AddPortA(LPSTR, HWND, LPSTR);\nBOOL AddPortW(LPWSTR, HWND, LPWSTR);\nHANDLE AddPrinterA(LPSTR, DWORD, PBYTE);\nHANDLE AddPrinterW(LPWSTR, DWORD, PBYTE);\nBOOL AddPrinterConnectionA(LPSTR);\nBOOL AddPrinterConnectionW(LPWSTR);\nBOOL AddPrinterDriverA(LPSTR, DWORD, PBYTE);\nBOOL AddPrinterDriverW(LPWSTR, DWORD, PBYTE);\nBOOL AddPrintProcessorA(LPSTR, LPSTR, LPSTR, LPSTR);\nBOOL AddPrintProcessorW(LPWSTR, LPWSTR, LPWSTR, LPWSTR);\nBOOL AddPrintProvidorA(LPSTR, DWORD, PBYTE);\nBOOL AddPrintProvidorW(LPWSTR, DWORD, PBYTE);\nLONG AdvancedDocumentPropertiesA(HWND, HANDLE, LPSTR, PDEVMODE, PDEVMODEA);\nLONG AdvancedDocumentPropertiesW(HWND, HANDLE, LPWSTR, PDEVMODE, PDEVMODEW);\nBOOL ClosePrinter(HANDLE);\nBOOL ConfigurePortA(LPSTR, HWND, LPSTR);\nBOOL ConfigurePortW(LPWSTR, HWND, LPWSTR);\nHANDLE ConnectToPrinterDlg(HWND, DWORD);\nBOOL DeleteFormA(HANDLE, LPSTR);\nBOOL DeleteFormW(HANDLE, LPWSTR);\nBOOL DeleteMonitorA(LPSTR, LPSTR, LPSTR);\nBOOL DeleteMonitorW(LPWSTR, LPWSTR, LPWSTR);\nBOOL DeletePortA(LPSTR, HWND, LPSTR);\nBOOL DeletePortW(LPWSTR, HWND, LPWSTR);\nBOOL DeletePrinter(HANDLE);\nBOOL DeletePrinterConnectionA(LPSTR);\nBOOL DeletePrinterConnectionW(LPWSTR);\nDWORD DeletePrinterDataA(HANDLE, LPSTR);\nDWORD DeletePrinterDataW(HANDLE, LPWSTR);\nBOOL DeletePrinterDriverA(LPSTR, LPSTR, LPSTR);\nBOOL DeletePrinterDriverW(LPWSTR, LPWSTR, LPWSTR);\nBOOL DeletePrintProcessorA(LPSTR, LPSTR, LPSTR);\nBOOL DeletePrintProcessorW(LPWSTR, LPWSTR, LPWSTR);\nBOOL DeletePrintProvidorA(LPSTR, LPSTR, LPSTR);\nBOOL DeletePrintProvidorW(LPWSTR, LPWSTR, LPWSTR);\nLONG DocumentPropertiesA(HWND, HANDLE, LPSTR, PDEVMODEA, PDEVMODEA, DWORD);\nLONG DocumentPropertiesW(HWND, HANDLE, LPWSTR, PDEVMODEW, PDEVMODEW, DWORD);\nBOOL EndDocPrinter(HANDLE);\nBOOL EndPagePrinter(HANDLE);\nBOOL EnumFormsA(HANDLE, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumFormsW(HANDLE, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumJobsA(HANDLE, DWORD, DWORD, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumJobsW(HANDLE, DWORD, DWORD, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumMonitorsA(LPSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumMonitorsW(LPWSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumPortsA(LPSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumPortsW(LPWSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nDWORD EnumPrinterDataA(HANDLE, DWORD, LPSTR, DWORD, PDWORD, PDWORD, PBYTE, DWORD, PDWORD);\nDWORD EnumPrinterDataW(HANDLE, DWORD, LPWSTR, DWORD, PDWORD, PDWORD, PBYTE, DWORD, PDWORD);\nBOOL EnumPrinterDriversA(LPSTR, LPSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumPrinterDriversW(LPWSTR, LPWSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumPrintersA(DWORD, LPSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumPrintersW(DWORD, LPWSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumPrintProcessorDatatypesA(LPSTR, LPSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumPrintProcessorDatatypesW(LPWSTR, LPWSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumPrintProcessorsA(LPSTR, LPSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL EnumPrintProcessorsW(LPWSTR, LPWSTR, DWORD, PBYTE, DWORD, PDWORD, PDWORD);\nBOOL FindClosePrinterChangeNotification(HANDLE);\nHANDLE FindFirstPrinterChangeNotification(HANDLE, DWORD, DWORD, PVOID);\nHANDLE FindNextPrinterChangeNotification(HANDLE, PDWORD, PVOID, PVOID*);\nBOOL FreePrinterNotifyInfo(PPRINTER_NOTIFY_INFO);\n\nstatic if (_WIN32_WINNT >= 0x500) {\nBOOL GetDefaultPrinterA(LPSTR, LPDWORD);\nBOOL GetDefaultPrinterW(LPWSTR, LPDWORD);\n}\n\nBOOL GetFormA(HANDLE, LPSTR, DWORD, PBYTE, DWORD, PDWORD);\nBOOL GetFormW(HANDLE, LPWSTR, DWORD, PBYTE, DWORD, PDWORD);\nBOOL GetJobA(HANDLE, DWORD, DWORD, PBYTE, DWORD, PDWORD);\nBOOL GetJobW(HANDLE, DWORD, DWORD, PBYTE, DWORD, PDWORD);\nBOOL GetPrinterA(HANDLE, DWORD, PBYTE, DWORD, PDWORD);\nBOOL GetPrinterW(HANDLE, DWORD, PBYTE, DWORD, PDWORD);\nDWORD GetPrinterDataA(HANDLE, LPSTR, PDWORD, PBYTE, DWORD, PDWORD);\nDWORD GetPrinterDataW(HANDLE, LPWSTR, PDWORD, PBYTE, DWORD, PDWORD);\nDWORD GetPrinterDriverA(HANDLE, LPSTR, DWORD, PBYTE, DWORD, PDWORD);\nDWORD GetPrinterDriverW(HANDLE, LPWSTR, DWORD, PBYTE, DWORD, PDWORD);\nDWORD GetPrinterDriverDirectoryA(LPSTR, LPSTR, DWORD, PBYTE, DWORD, PDWORD);\nDWORD GetPrinterDriverDirectoryW(LPWSTR, LPWSTR, DWORD, PBYTE, DWORD, PDWORD);\nDWORD GetPrintProcessorDirectoryA(LPSTR, LPSTR, DWORD, PBYTE, DWORD, PDWORD);\nDWORD GetPrintProcessorDirectoryW(LPWSTR, LPWSTR, DWORD, PBYTE, DWORD, PDWORD);\nBOOL OpenPrinterA(LPSTR, PHANDLE, LPPRINTER_DEFAULTSA);\nBOOL OpenPrinterW(LPWSTR, PHANDLE, LPPRINTER_DEFAULTSW);\nDWORD PrinterMessageBoxA(HANDLE, DWORD, HWND, LPSTR, LPSTR, DWORD);\nDWORD PrinterMessageBoxW(HANDLE, DWORD, HWND, LPWSTR, LPWSTR, DWORD);\nBOOL PrinterProperties(HWND, HANDLE);\nBOOL ReadPrinter(HANDLE, PVOID, DWORD, PDWORD);\nBOOL ResetPrinterA(HANDLE, LPPRINTER_DEFAULTSA);\nBOOL ResetPrinterW(HANDLE, LPPRINTER_DEFAULTSW);\nBOOL ScheduleJob(HANDLE, DWORD);\nBOOL SetFormA(HANDLE, LPSTR, DWORD, PBYTE);\nBOOL SetFormW(HANDLE, LPWSTR, DWORD, PBYTE);\nBOOL SetJobA(HANDLE, DWORD, DWORD, PBYTE, DWORD);\nBOOL SetJobW(HANDLE, DWORD, DWORD, PBYTE, DWORD);\nBOOL SetPrinterA(HANDLE, DWORD, PBYTE, DWORD);\nBOOL SetPrinterW(HANDLE, DWORD, PBYTE, DWORD);\nBOOL SetPrinterDataA(HANDLE, LPSTR, DWORD, PBYTE, DWORD);\nBOOL SetPrinterDataW(HANDLE, LPWSTR, DWORD, PBYTE, DWORD);\nDWORD StartDocPrinterA(HANDLE, DWORD, PBYTE);\nDWORD StartDocPrinterW(HANDLE, DWORD, PBYTE);\nBOOL StartPagePrinter(HANDLE);\nDWORD WaitForPrinterChange(HANDLE, DWORD);\nBOOL WritePrinter(HANDLE, PVOID, DWORD, PDWORD);\n\nversion (Unicode) {\n\nalias JOB_INFO_1W JOB_INFO_1;\nalias JOB_INFO_2W JOB_INFO_2;\nalias ADDJOB_INFO_1W ADDJOB_INFO_1;\nalias DATATYPES_INFO_1W DATATYPES_INFO_1;\nalias MONITOR_INFO_1W MONITOR_INFO_1;\nalias MONITOR_INFO_2W MONITOR_INFO_2;\nalias DOC_INFO_1W DOC_INFO_1;\nalias DOC_INFO_2W DOC_INFO_2;\nalias PORT_INFO_1W PORT_INFO_1;\nalias PORT_INFO_2W PORT_INFO_2;\nalias PORT_INFO_3W PORT_INFO_3;\nalias DRIVER_INFO_2W DRIVER_INFO_2;\nalias PRINTER_INFO_1W PRINTER_INFO_1;\nalias PRINTER_INFO_2W PRINTER_INFO_2;\nalias PRINTER_INFO_4W PRINTER_INFO_4;\nalias PRINTER_INFO_5W PRINTER_INFO_5;\nalias PRINTPROCESSOR_INFO_1W PRINTPROCESSOR_INFO_1;\nalias FORM_INFO_1W FORM_INFO_1;\nalias PRINTER_DEFAULTSW PRINTER_DEFAULTS;\n\nalias AddFormW AddForm;\nalias AddJobW AddJob;\nalias AddMonitorW AddMonitor;\nalias AddPortW AddPort;\nalias AddPrinterW AddPrinter;\nalias AddPrinterConnectionW AddPrinterConnection;\nalias AddPrinterDriverW AddPrinterDriver;\nalias AddPrintProcessorW AddPrintProcessor;\nalias AddPrintProvidorW AddPrintProvidor;\nalias AdvancedDocumentPropertiesW AdvancedDocumentProperties;\nalias ConfigurePortW ConfigurePort;\nalias DeleteFormW DeleteForm;\nalias DeleteMonitorW DeleteMonitor;\nalias DeletePortW DeletePort;\nalias DeletePrinterConnectionW DeletePrinterConnection;\nalias DeletePrinterDataW DeletePrinterData;\nalias DeletePrinterDriverW DeletePrinterDriver;\nalias DeletePrintProcessorW DeletePrintProcessor;\nalias DeletePrintProvidorW DeletePrintProvidor;\nalias DocumentPropertiesW DocumentProperties;\nalias EnumFormsW EnumForms;\nalias EnumJobsW EnumJobs;\nalias EnumMonitorsW EnumMonitors;\nalias EnumPortsW EnumPorts;\nalias EnumPrinterDataW EnumPrinterData;\nalias EnumPrinterDriversW EnumPrinterDrivers;\nalias EnumPrintersW EnumPrinters;\nalias EnumPrintProcessorDatatypesW EnumPrintProcessorDatatypes;\nalias EnumPrintProcessorsW EnumPrintProcessors;\n\nstatic if (_WIN32_WINNT >= 0x500) {\nalias GetDefaultPrinterW GetDefaultPrinter;\n}\n\nalias GetFormW GetForm;\nalias GetJobW GetJob;\nalias GetPrinterW GetPrinter;\nalias GetPrinterDataW GetPrinterData;\nalias GetPrinterDriverW GetPrinterDriver;\nalias GetPrinterDriverDirectoryW GetPrinterDriverDirectory;\nalias GetPrintProcessorDirectoryW GetPrintProcessorDirectory;\nalias OpenPrinterW OpenPrinter;\nalias PrinterMessageBoxW PrinterMessageBox;\nalias ResetPrinterW ResetPrinter;\nalias SetFormW SetForm;\nalias SetJobW SetJob;\nalias SetPrinterW SetPrinter;\nalias SetPrinterDataW SetPrinterData;\nalias StartDocPrinterW StartDocPrinter;\n\n} else {\n\nalias JOB_INFO_1A JOB_INFO_1;\nalias JOB_INFO_2A JOB_INFO_2;\nalias ADDJOB_INFO_1A ADDJOB_INFO_1;\nalias DATATYPES_INFO_1A DATATYPES_INFO_1;\nalias MONITOR_INFO_1A MONITOR_INFO_1;\nalias MONITOR_INFO_2A MONITOR_INFO_2;\nalias DOC_INFO_1A DOC_INFO_1;\nalias DOC_INFO_2A DOC_INFO_2;\nalias PORT_INFO_1A PORT_INFO_1;\nalias PORT_INFO_2A PORT_INFO_2;\nalias PORT_INFO_3A PORT_INFO_3;\nalias DRIVER_INFO_2A DRIVER_INFO_2;\nalias PRINTER_INFO_1A PRINTER_INFO_1;\nalias PRINTER_INFO_2A PRINTER_INFO_2;\nalias PRINTER_INFO_4A PRINTER_INFO_4;\nalias PRINTER_INFO_5A PRINTER_INFO_5;\nalias PRINTPROCESSOR_INFO_1A PRINTPROCESSOR_INFO_1;\nalias FORM_INFO_1A FORM_INFO_1;\nalias PRINTER_DEFAULTSA PRINTER_DEFAULTS;\n\nalias AddFormA AddForm;\nalias AddJobA AddJob;\nalias AddMonitorA AddMonitor;\nalias AddPortA AddPort;\nalias AddPrinterA AddPrinter;\nalias AddPrinterConnectionA AddPrinterConnection;\nalias AddPrinterDriverA AddPrinterDriver;\nalias AddPrintProcessorA AddPrintProcessor;\nalias AddPrintProvidorA AddPrintProvidor;\nalias AdvancedDocumentPropertiesA AdvancedDocumentProperties;\nalias ConfigurePortA ConfigurePort;\nalias DeleteFormA DeleteForm;\nalias DeleteMonitorA DeleteMonitor;\nalias DeletePortA DeletePort;\nalias DeletePrinterConnectionA DeletePrinterConnection;\nalias DeletePrinterDataA DeletePrinterData;\nalias DeletePrinterDriverA DeletePrinterDriver;\nalias DeletePrintProcessorA DeletePrintProcessor;\nalias DeletePrintProvidorA DeletePrintProvidor;\nalias DocumentPropertiesA DocumentProperties;\nalias EnumFormsA EnumForms;\nalias EnumJobsA EnumJobs;\nalias EnumMonitorsA EnumMonitors;\nalias EnumPortsA EnumPorts;\nalias EnumPrinterDataA EnumPrinterData;\nalias EnumPrinterDriversA EnumPrinterDrivers;\nalias EnumPrintersA EnumPrinters;\nalias EnumPrintProcessorDatatypesA EnumPrintProcessorDatatypes;\nalias EnumPrintProcessorsA EnumPrintProcessors;\n\nstatic if (_WIN32_WINNT >= 0x500) {\nalias GetDefaultPrinterA GetDefaultPrinter;\n}\n\nalias GetFormA GetForm;\nalias GetJobA GetJob;\nalias GetPrinterA GetPrinter;\nalias GetPrinterDataA GetPrinterData;\nalias GetPrinterDriverA GetPrinterDriver;\nalias GetPrinterDriverDirectoryA GetPrinterDriverDirectory;\nalias GetPrintProcessorDirectoryA GetPrintProcessorDirectory;\nalias OpenPrinterA OpenPrinter;\nalias PrinterMessageBoxA PrinterMessageBox;\nalias ResetPrinterA ResetPrinter;\nalias SetFormA SetForm;\nalias SetJobA SetJob;\nalias SetPrinterA SetPrinter;\nalias SetPrinterDataA SetPrinterData;\nalias StartDocPrinterA StartDocPrinter;\n}\n\nalias JOB_INFO_1* PJOB_INFO_1, LPJOB_INFO_1;\nalias JOB_INFO_2* PJOB_INFO_2, LPJOB_INFO_2;\nalias ADDJOB_INFO_1* PADDJOB_INFO_1, LPADDJOB_INFO_1;\nalias DATATYPES_INFO_1* PDATATYPES_INFO_1, LPDATATYPES_INFO_1;\nalias MONITOR_INFO_1* PMONITOR_INFO_1, LPMONITOR_INFO_1;\nalias MONITOR_INFO_2* PMONITOR_INFO_2, LPMONITOR_INFO_2;\nalias DOC_INFO_1* PDOC_INFO_1, LPDOC_INFO_1;\nalias DOC_INFO_2* PDOC_INFO_2, LPDOC_INFO_2;\nalias PORT_INFO_1* PPORT_INFO_1, LPPORT_INFO_1;\nalias PORT_INFO_2* PPORT_INFO_2, LPPORT_INFO_2;\nalias PORT_INFO_3* PPORT_INFO_3, LPPORT_INFO_3;\nalias DRIVER_INFO_2* PDRIVER_INFO_2, LPDRIVER_INFO_2;\nalias PRINTER_INFO_1* PPRINTER_INFO_1, LPPRINTER_INFO_1;\nalias PRINTER_INFO_2* PPRINTER_INFO_2, LPPRINTER_INFO_2;\nalias PRINTER_INFO_4* PPRINTER_INFO_4, LPPRINTER_INFO_4;\nalias PRINTER_INFO_5* PPRINTER_INFO_5, LPPRINTER_INFO_5;\nalias PRINTPROCESSOR_INFO_1* PPRINTPROCESSOR_INFO_1, LPPRINTPROCESSOR_INFO_1;\nalias FORM_INFO_1* PFORM_INFO_1, LPFORM_INFO_1;\nalias PRINTER_DEFAULTS* PPRINTER_DEFAULTS, LPPRINTER_DEFAULTS;\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winsvc.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winsvc.d)\n */\nmodule core.sys.windows.winsvc;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"advapi32\");\n\nprivate import core.sys.windows.w32api, core.sys.windows.windef;\n\n// FIXME: check Windows version support\n\nconst TCHAR[]\n    SERVICES_ACTIVE_DATABASE = \"ServicesActive\",\n    SERVICES_FAILED_DATABASE = \"ServicesFailed\";\n\nconst TCHAR SC_GROUP_IDENTIFIER = '+';\n\nenum DWORD\n    SC_MANAGER_ALL_ACCESS         = 0xf003f,\n    SC_MANAGER_CONNECT            =  1,\n    SC_MANAGER_CREATE_SERVICE     =  2,\n    SC_MANAGER_ENUMERATE_SERVICE  =  4,\n    SC_MANAGER_LOCK               =  8,\n    SC_MANAGER_QUERY_LOCK_STATUS  = 16,\n    SC_MANAGER_MODIFY_BOOT_CONFIG = 32;\n\nenum DWORD SERVICE_NO_CHANGE = 0xffffffff;\n\nenum : DWORD {\n    SERVICE_STOPPED = 1,\n    SERVICE_START_PENDING,\n    SERVICE_STOP_PENDING,\n    SERVICE_RUNNING,\n    SERVICE_CONTINUE_PENDING,\n    SERVICE_PAUSE_PENDING,\n    SERVICE_PAUSED // = 7\n}\n\nenum DWORD\n    SERVICE_ACCEPT_STOP                  =   1,\n    SERVICE_ACCEPT_PAUSE_CONTINUE        =   2,\n    SERVICE_ACCEPT_SHUTDOWN              =   4,\n    SERVICE_ACCEPT_PARAMCHANGE           =   8,\n    SERVICE_ACCEPT_NETBINDCHANGE         =  16,\n    SERVICE_ACCEPT_HARDWAREPROFILECHANGE =  32,\n    SERVICE_ACCEPT_POWEREVENT            =  64,\n    SERVICE_ACCEPT_SESSIONCHANGE         = 128;\n\nenum : DWORD {\n    SERVICE_CONTROL_STOP = 1,\n    SERVICE_CONTROL_PAUSE,\n    SERVICE_CONTROL_CONTINUE,\n    SERVICE_CONTROL_INTERROGATE,\n    SERVICE_CONTROL_SHUTDOWN,\n    SERVICE_CONTROL_PARAMCHANGE,\n    SERVICE_CONTROL_NETBINDADD,\n    SERVICE_CONTROL_NETBINDREMOVE,\n    SERVICE_CONTROL_NETBINDENABLE,\n    SERVICE_CONTROL_NETBINDDISABLE,\n    SERVICE_CONTROL_DEVICEEVENT,\n    SERVICE_CONTROL_HARDWAREPROFILECHANGE,\n    SERVICE_CONTROL_POWEREVENT,\n    SERVICE_CONTROL_SESSIONCHANGE, // = 14\n}\n\nenum : DWORD {\n    SERVICE_ACTIVE = 1,\n    SERVICE_INACTIVE,\n    SERVICE_STATE_ALL\n}\n\nenum DWORD\n    SERVICE_QUERY_CONFIG         = 0x0001,\n    SERVICE_CHANGE_CONFIG        = 0x0002,\n    SERVICE_QUERY_STATUS         = 0x0004,\n    SERVICE_ENUMERATE_DEPENDENTS = 0x0008,\n    SERVICE_START                = 0x0010,\n    SERVICE_STOP                 = 0x0020,\n    SERVICE_PAUSE_CONTINUE       = 0x0040,\n    SERVICE_INTERROGATE          = 0x0080,\n    SERVICE_USER_DEFINED_CONTROL = 0x0100,\n    SERVICE_ALL_ACCESS           = 0x01FF | STANDARD_RIGHTS_REQUIRED;\n\n// This is not documented on the MSDN site\nenum SERVICE_RUNS_IN_SYSTEM_PROCESS = 1;\n\nenum : DWORD {\n    SERVICE_CONFIG_DESCRIPTION         = 1,\n    SERVICE_CONFIG_FAILURE_ACTIONS,\n    SERVICE_CONFIG_DELAYED_AUTO_START_INFO,\n    SERVICE_CONFIG_FAILURE_ACTIONS_FLAG,\n    SERVICE_CONFIG_SERVICE_SID_INFO,\n    SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO,\n    SERVICE_CONFIG_PRESHUTDOWN_INFO // = 7\n}\n\nstruct SERVICE_STATUS {\n    DWORD dwServiceType;\n    DWORD dwCurrentState;\n    DWORD dwControlsAccepted;\n    DWORD dwWin32ExitCode;\n    DWORD dwServiceSpecificExitCode;\n    DWORD dwCheckPoint;\n    DWORD dwWaitHint;\n}\nalias SERVICE_STATUS* LPSERVICE_STATUS;\n\nstruct ENUM_SERVICE_STATUSA {\n    LPSTR          lpServiceName;\n    LPSTR          lpDisplayName;\n    SERVICE_STATUS ServiceStatus;\n}\nalias ENUM_SERVICE_STATUSA* LPENUM_SERVICE_STATUSA;\n\nstruct ENUM_SERVICE_STATUSW {\n    LPWSTR         lpServiceName;\n    LPWSTR         lpDisplayName;\n    SERVICE_STATUS ServiceStatus;\n}\nalias ENUM_SERVICE_STATUSW* LPENUM_SERVICE_STATUSW;\n\nstruct QUERY_SERVICE_CONFIGA {\n    DWORD dwServiceType;\n    DWORD dwStartType;\n    DWORD dwErrorControl;\n    LPSTR lpBinaryPathName;\n    LPSTR lpLoadOrderGroup;\n    DWORD dwTagId;\n    LPSTR lpDependencies;\n    LPSTR lpServiceStartName;\n    LPSTR lpDisplayName;\n}\nalias QUERY_SERVICE_CONFIGA* LPQUERY_SERVICE_CONFIGA;\n\nstruct QUERY_SERVICE_CONFIGW {\n    DWORD  dwServiceType;\n    DWORD  dwStartType;\n    DWORD  dwErrorControl;\n    LPWSTR lpBinaryPathName;\n    LPWSTR lpLoadOrderGroup;\n    DWORD  dwTagId;\n    LPWSTR lpDependencies;\n    LPWSTR lpServiceStartName;\n    LPWSTR lpDisplayName;\n}\nalias QUERY_SERVICE_CONFIGW* LPQUERY_SERVICE_CONFIGW;\n\nstruct QUERY_SERVICE_LOCK_STATUSA {\n    DWORD fIsLocked;\n    LPSTR lpLockOwner;\n    DWORD dwLockDuration;\n}\nalias QUERY_SERVICE_LOCK_STATUSA* LPQUERY_SERVICE_LOCK_STATUSA;\n\nstruct QUERY_SERVICE_LOCK_STATUSW {\n    DWORD  fIsLocked;\n    LPWSTR lpLockOwner;\n    DWORD  dwLockDuration;\n}\nalias QUERY_SERVICE_LOCK_STATUSW* LPQUERY_SERVICE_LOCK_STATUSW;\n\nextern (Windows) {\n    alias void function(DWORD, LPSTR*)  LPSERVICE_MAIN_FUNCTIONA;\n    alias void function(DWORD, LPWSTR*) LPSERVICE_MAIN_FUNCTIONW;\n}\n\nstruct SERVICE_TABLE_ENTRYA {\n    LPSTR                    lpServiceName;\n    LPSERVICE_MAIN_FUNCTIONA lpServiceProc;\n}\nalias SERVICE_TABLE_ENTRYA* LPSERVICE_TABLE_ENTRYA;\n\nstruct SERVICE_TABLE_ENTRYW {\n    LPWSTR                   lpServiceName;\n    LPSERVICE_MAIN_FUNCTIONW lpServiceProc;\n}\nalias SERVICE_TABLE_ENTRYW* LPSERVICE_TABLE_ENTRYW;\n\nmixin DECLARE_HANDLE!(\"SC_HANDLE\");\nalias SC_HANDLE* LPSC_HANDLE;\nalias void* SC_LOCK;\nmixin DECLARE_HANDLE!(\"SERVICE_STATUS_HANDLE\");\n\nextern (Windows) {\n    alias void function(DWORD) LPHANDLER_FUNCTION;\n    alias DWORD function(DWORD, DWORD, LPVOID, LPVOID) LPHANDLER_FUNCTION_EX;\n}\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    struct SERVICE_STATUS_PROCESS {\n        DWORD dwServiceType;\n        DWORD dwCurrentState;\n        DWORD dwControlsAccepted;\n        DWORD dwWin32ExitCode;\n        DWORD dwServiceSpecificExitCode;\n        DWORD dwCheckPoint;\n        DWORD dwWaitHint;\n        DWORD dwProcessId;\n        DWORD dwServiceFlags;\n    }\n    alias SERVICE_STATUS_PROCESS* LPSERVICE_STATUS_PROCESS;\n\n    enum SC_STATUS_TYPE {\n        SC_STATUS_PROCESS_INFO = 0\n    }\n\n    enum SC_ENUM_TYPE {\n        SC_ENUM_PROCESS_INFO = 0\n    }\n\n    struct ENUM_SERVICE_STATUS_PROCESSA {\n        LPSTR                  lpServiceName;\n        LPSTR                  lpDisplayName;\n        SERVICE_STATUS_PROCESS ServiceStatusProcess;\n    }\n    alias ENUM_SERVICE_STATUS_PROCESSA* LPENUM_SERVICE_STATUS_PROCESSA;\n\n    struct ENUM_SERVICE_STATUS_PROCESSW {\n        LPWSTR                 lpServiceName;\n        LPWSTR                 lpDisplayName;\n        SERVICE_STATUS_PROCESS ServiceStatusProcess;\n    }\n    alias ENUM_SERVICE_STATUS_PROCESSW* LPENUM_SERVICE_STATUS_PROCESSW;\n\n    struct SERVICE_DESCRIPTIONA {\n        LPSTR lpDescription;\n    }\n    alias SERVICE_DESCRIPTIONA* LPSERVICE_DESCRIPTIONA;\n\n    struct SERVICE_DESCRIPTIONW {\n        LPWSTR lpDescription;\n    }\n    alias SERVICE_DESCRIPTIONW* LPSERVICE_DESCRIPTIONW;\n\n    enum SC_ACTION_TYPE {\n        SC_ACTION_NONE,\n        SC_ACTION_RESTART,\n        SC_ACTION_REBOOT,\n        SC_ACTION_RUN_COMMAND\n    }\n\n    struct SC_ACTION {\n        SC_ACTION_TYPE Type;\n        DWORD          Delay;\n    }\n    alias SC_ACTION* LPSC_ACTION;\n\n    struct SERVICE_FAILURE_ACTIONSA {\n        DWORD      dwResetPeriod;\n        LPSTR      lpRebootMsg;\n        LPSTR      lpCommand;\n        DWORD      cActions;\n        SC_ACTION* lpsaActions;\n    }\n    alias SERVICE_FAILURE_ACTIONSA* LPSERVICE_FAILURE_ACTIONSA;\n\n    struct SERVICE_FAILURE_ACTIONSW {\n        DWORD      dwResetPeriod;\n        LPWSTR     lpRebootMsg;\n        LPWSTR     lpCommand;\n        DWORD      cActions;\n        SC_ACTION* lpsaActions;\n    }\n    alias SERVICE_FAILURE_ACTIONSW* LPSERVICE_FAILURE_ACTIONSW;\n}\n\nextern (Windows) {\n    BOOL ChangeServiceConfigA(SC_HANDLE, DWORD, DWORD, DWORD, LPCSTR,\n      LPCSTR, LPDWORD, LPCSTR, LPCSTR, LPCSTR, LPCSTR);\n    BOOL ChangeServiceConfigW(SC_HANDLE, DWORD, DWORD, DWORD, LPCWSTR,\n      LPCWSTR, LPDWORD, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR);\n    BOOL CloseServiceHandle(SC_HANDLE);\n    BOOL ControlService(SC_HANDLE, DWORD, LPSERVICE_STATUS);\n    SC_HANDLE CreateServiceA(SC_HANDLE, LPCSTR, LPCSTR, DWORD, DWORD,\n      DWORD, DWORD, LPCSTR, LPCSTR, PDWORD, LPCSTR, LPCSTR, LPCSTR);\n    SC_HANDLE CreateServiceW(SC_HANDLE, LPCWSTR, LPCWSTR, DWORD, DWORD,\n      DWORD, DWORD, LPCWSTR, LPCWSTR, PDWORD, LPCWSTR, LPCWSTR, LPCWSTR);\n    BOOL DeleteService(SC_HANDLE);\n    BOOL EnumDependentServicesA(SC_HANDLE, DWORD, LPENUM_SERVICE_STATUSA,\n      DWORD, PDWORD, PDWORD);\n    BOOL EnumDependentServicesW(SC_HANDLE, DWORD, LPENUM_SERVICE_STATUSW,\n      DWORD, PDWORD, PDWORD);\n    BOOL EnumServicesStatusA(SC_HANDLE, DWORD, DWORD, LPENUM_SERVICE_STATUSA,\n      DWORD, PDWORD, PDWORD, PDWORD);\n    BOOL EnumServicesStatusW(SC_HANDLE, DWORD, DWORD, LPENUM_SERVICE_STATUSW,\n      DWORD, PDWORD, PDWORD, PDWORD);\n    BOOL GetServiceDisplayNameA(SC_HANDLE, LPCSTR, LPSTR, PDWORD);\n    BOOL GetServiceDisplayNameW(SC_HANDLE, LPCWSTR, LPWSTR, PDWORD);\n    BOOL GetServiceKeyNameA(SC_HANDLE, LPCSTR, LPSTR, PDWORD);\n    BOOL GetServiceKeyNameW(SC_HANDLE, LPCWSTR, LPWSTR, PDWORD);\n    SC_LOCK LockServiceDatabase(SC_HANDLE);\n    BOOL NotifyBootConfigStatus(BOOL);\n    SC_HANDLE OpenSCManagerA(LPCSTR, LPCSTR, DWORD);\n    SC_HANDLE OpenSCManagerW(LPCWSTR, LPCWSTR, DWORD);\n    SC_HANDLE OpenServiceA(SC_HANDLE, LPCSTR, DWORD);\n    SC_HANDLE OpenServiceW(SC_HANDLE, LPCWSTR, DWORD);\n    BOOL QueryServiceConfigA(SC_HANDLE, LPQUERY_SERVICE_CONFIGA, DWORD,\n      PDWORD);\n    BOOL QueryServiceConfigW(SC_HANDLE, LPQUERY_SERVICE_CONFIGW, DWORD,\n      PDWORD);\n    BOOL QueryServiceLockStatusA(SC_HANDLE, LPQUERY_SERVICE_LOCK_STATUSA,\n      DWORD, PDWORD);\n    BOOL QueryServiceLockStatusW(SC_HANDLE, LPQUERY_SERVICE_LOCK_STATUSW,\n      DWORD, PDWORD);\n    BOOL QueryServiceObjectSecurity(SC_HANDLE, SECURITY_INFORMATION,\n      PSECURITY_DESCRIPTOR, DWORD, LPDWORD);\n    BOOL QueryServiceStatus(SC_HANDLE, LPSERVICE_STATUS);\n    SERVICE_STATUS_HANDLE RegisterServiceCtrlHandlerA(LPCSTR,\n      LPHANDLER_FUNCTION);\n    SERVICE_STATUS_HANDLE RegisterServiceCtrlHandlerW(LPCWSTR,\n      LPHANDLER_FUNCTION);\n    BOOL SetServiceObjectSecurity(SC_HANDLE, SECURITY_INFORMATION,\n      PSECURITY_DESCRIPTOR);\n    BOOL SetServiceStatus(SERVICE_STATUS_HANDLE, LPSERVICE_STATUS);\n    BOOL StartServiceA(SC_HANDLE, DWORD, LPCSTR*);\n    BOOL StartServiceW(SC_HANDLE, DWORD, LPCWSTR*);\n    BOOL StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA);\n    BOOL StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW);\n    BOOL UnlockServiceDatabase(SC_LOCK);\n\n    static if (_WIN32_WINNT >= 0x500) {\n        BOOL EnumServicesStatusExA(SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPBYTE,\n          DWORD, LPDWORD, LPDWORD, LPDWORD, LPCSTR);\n        BOOL EnumServicesStatusExW(SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPBYTE,\n          DWORD, LPDWORD, LPDWORD, LPDWORD, LPCWSTR);\n        BOOL QueryServiceConfig2A(SC_HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);\n        BOOL QueryServiceConfig2W(SC_HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);\n        BOOL QueryServiceStatusEx(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD,\n          LPDWORD);\n        SERVICE_STATUS_HANDLE RegisterServiceCtrlHandlerExA(LPCSTR,\n          LPHANDLER_FUNCTION_EX, LPVOID);\n        SERVICE_STATUS_HANDLE RegisterServiceCtrlHandlerExW(LPCWSTR,\n          LPHANDLER_FUNCTION_EX, LPVOID);\n    }\n\n    static if (_WIN32_WINNT >= 0x501) {\n        BOOL ChangeServiceConfig2A(SC_HANDLE, DWORD, LPVOID);\n        BOOL ChangeServiceConfig2W(SC_HANDLE, DWORD, LPVOID);\n    }\n}\n\nversion (Unicode) {\n    alias ENUM_SERVICE_STATUSW ENUM_SERVICE_STATUS;\n    alias QUERY_SERVICE_CONFIGW QUERY_SERVICE_CONFIG;\n    alias QUERY_SERVICE_LOCK_STATUSW QUERY_SERVICE_LOCK_STATUS;\n    alias LPSERVICE_MAIN_FUNCTIONW LPSERVICE_MAIN_FUNCTION;\n    alias SERVICE_TABLE_ENTRYW SERVICE_TABLE_ENTRY;\n    alias ChangeServiceConfigW ChangeServiceConfig;\n    alias CreateServiceW CreateService;\n    alias EnumDependentServicesW EnumDependentServices;\n    alias EnumServicesStatusW EnumServicesStatus;\n    alias GetServiceDisplayNameW GetServiceDisplayName;\n    alias GetServiceKeyNameW GetServiceKeyName;\n    alias OpenSCManagerW OpenSCManager;\n    alias OpenServiceW OpenService;\n    alias QueryServiceConfigW QueryServiceConfig;\n    alias QueryServiceLockStatusW QueryServiceLockStatus;\n    alias RegisterServiceCtrlHandlerW RegisterServiceCtrlHandler;\n    alias StartServiceW StartService;\n    alias StartServiceCtrlDispatcherW StartServiceCtrlDispatcher;\n\n    static if (_WIN32_WINNT >= 0x500) {\n        alias ENUM_SERVICE_STATUS_PROCESSW ENUM_SERVICE_STATUS_PROCESS;\n        alias SERVICE_DESCRIPTIONW SERVICE_DESCRIPTION;\n        alias SERVICE_FAILURE_ACTIONSW SERVICE_FAILURE_ACTIONS;\n        alias EnumServicesStatusExW EnumServicesStatusEx;\n        alias QueryServiceConfig2W QueryServiceConfig2;\n        alias RegisterServiceCtrlHandlerExW RegisterServiceCtrlHandlerEx;\n    }\n\n    static if (_WIN32_WINNT >= 0x501) {\n        alias ChangeServiceConfig2W ChangeServiceConfig2;\n    }\n\n} else {\n    alias ENUM_SERVICE_STATUSA ENUM_SERVICE_STATUS;\n    alias QUERY_SERVICE_CONFIGA QUERY_SERVICE_CONFIG;\n    alias QUERY_SERVICE_LOCK_STATUSA QUERY_SERVICE_LOCK_STATUS;\n    alias LPSERVICE_MAIN_FUNCTIONA LPSERVICE_MAIN_FUNCTION;\n    alias SERVICE_TABLE_ENTRYA SERVICE_TABLE_ENTRY;\n    alias ChangeServiceConfigA ChangeServiceConfig;\n    alias CreateServiceA CreateService;\n    alias EnumDependentServicesA EnumDependentServices;\n    alias EnumServicesStatusA EnumServicesStatus;\n    alias GetServiceDisplayNameA GetServiceDisplayName;\n    alias GetServiceKeyNameA GetServiceKeyName;\n    alias OpenSCManagerA OpenSCManager;\n    alias OpenServiceA OpenService;\n    alias QueryServiceConfigA QueryServiceConfig;\n    alias QueryServiceLockStatusA QueryServiceLockStatus;\n    alias RegisterServiceCtrlHandlerA RegisterServiceCtrlHandler;\n    alias StartServiceA StartService;\n    alias StartServiceCtrlDispatcherA StartServiceCtrlDispatcher;\n\n    static if (_WIN32_WINNT >= 0x500) {\n        alias ENUM_SERVICE_STATUS_PROCESSA ENUM_SERVICE_STATUS_PROCESS;\n        alias SERVICE_DESCRIPTIONA SERVICE_DESCRIPTION;\n        alias SERVICE_FAILURE_ACTIONSA SERVICE_FAILURE_ACTIONS;\n        alias EnumServicesStatusExA EnumServicesStatusEx;\n        alias QueryServiceConfig2A QueryServiceConfig2;\n        alias RegisterServiceCtrlHandlerExA RegisterServiceCtrlHandlerEx;\n    }\n\n    static if (_WIN32_WINNT >= 0x501) {\n        alias ChangeServiceConfig2A ChangeServiceConfig2;\n    }\n\n}\n\nalias ENUM_SERVICE_STATUS* LPENUM_SERVICE_STATUS;\nalias QUERY_SERVICE_CONFIG* LPQUERY_SERVICE_CONFIG;\nalias QUERY_SERVICE_LOCK_STATUS* LPQUERY_SERVICE_LOCK_STATUS;\nalias SERVICE_TABLE_ENTRY* LPSERVICE_TABLE_ENTRY;\n\nstatic if (_WIN32_WINNT >= 0x500) {\n    alias ENUM_SERVICE_STATUS_PROCESS* LPENUM_SERVICE_STATUS_PROCESS;\n    alias SERVICE_DESCRIPTION* LPSERVICE_DESCRIPTION;\n    alias SERVICE_FAILURE_ACTIONS* LPSERVICE_FAILURE_ACTIONS;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winuser.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winuser.d)\n */\nmodule core.sys.windows.winuser;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"user32\");\n\n// Conversion Notes:\n// The following macros were for win16 only, and are not included in this file:\n//#define EnumTaskWindows(h, f, p) EnumThreadWindows((DWORD)h, f, p)\n//#define PostAppMessageA(t, m, w, l) PostThreadMessageA((DWORD)t, m, w, l)\n//#define PostAppMessageW(t, m, w, l) PostThreadMessageW((DWORD)t, m, w, l)\n//#define GetSysModalWindow() (NULL)\n//#define SetSysModalWindow(h) (NULL)\n//#define GetWindowTask(hWnd) ((HANDLE)GetWindowThreadProcessId(hWnd, NULL))\n//#define DefHookProc(c, p, lp, h) CallNextHookEx((HHOOK)*h, c, p, lp)\n\nprivate import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.wingdi;\nprivate import core.sys.windows.windef; // for HMONITOR\n\n// FIXME: clean up Windows version support\n\nLPTSTR MAKEINTATOM_T()(int i) {\n    return cast(LPTSTR) i;\n}\n\nenum LPTSTR WC_DIALOG = MAKEINTATOM_T(0x8002);\n\nenum {\n    FAPPCOMMAND_MOUSE = 0x8000,\n    FAPPCOMMAND_KEY   = 0,\n    FAPPCOMMAND_OEM   = 0x1000,\n    FAPPCOMMAND_MASK  = 0xF000\n}\n\nenum {\n    MNGO_NOINTERFACE = 0,\n    MNGO_NOERROR,\n    MNGOF_TOPGAP     = 1,\n    MNGOF_BOTTOMGAP\n}\n\nenum {\n    FVIRTKEY  = 1,\n    FNOINVERT = 2,\n    FSHIFT    = 4,\n    FCONTROL  = 8,\n    FALT      = 16\n}\n\nenum {\n    ATF_TIMEOUTON     = 1,\n    ATF_ONOFFFEEDBACK = 2,\n    ATF_AVAILABLE     = 4 // May be obsolete. Not in recent MS docs.\n}\n\nenum {\n    WH_MIN             = -1,\n    WH_MSGFILTER       = -1,\n    WH_JOURNALRECORD,\n    WH_JOURNALPLAYBACK,\n    WH_KEYBOARD,\n    WH_GETMESSAGE,\n    WH_CALLWNDPROC,\n    WH_CBT,\n    WH_SYSMSGFILTER,\n    WH_MOUSE,\n    WH_HARDWARE,\n    WH_DEBUG,\n    WH_SHELL,\n    WH_FOREGROUNDIDLE,\n    WH_CALLWNDPROCRET,\n    WH_KEYBOARD_LL,\n    WH_MOUSE_LL,    // = 14\n    WH_MAX             = 14,\n    WH_MINHOOK         = WH_MIN,\n    WH_MAXHOOK         = WH_MAX\n}\n\nenum {\n    HC_ACTION       = 0,\n    HC_GETNEXT,\n    HC_SKIP,\n    HC_NOREMOVE, // = 3\n    HC_NOREM        = HC_NOREMOVE,\n    HC_SYSMODALON,\n    HC_SYSMODALOFF\n}\n\nenum {\n    HCBT_MOVESIZE    = 0,\n    HCBT_MINMAX,\n    HCBT_QS,\n    HCBT_CREATEWND,\n    HCBT_DESTROYWND,\n    HCBT_ACTIVATE,\n    HCBT_CLICKSKIPPED,\n    HCBT_KEYSKIPPED,\n    HCBT_SYSCOMMAND,\n    HCBT_SETFOCUS // = 9\n}\n\nenum {\n    CF_TEXT                = 0x0001,\n    CF_BITMAP,\n    CF_METAFILEPICT,\n    CF_SYLK,\n    CF_DIF,\n    CF_TIFF,\n    CF_OEMTEXT,\n    CF_DIB,\n    CF_PALETTE,\n    CF_PENDATA,\n    CF_RIFF,\n    CF_WAVE,\n    CF_UNICODETEXT,\n    CF_ENHMETAFILE,\n    CF_HDROP,\n    CF_LOCALE,\n    CF_DIBV5,\n    CF_MAX,             // = 0x0012\n    CF_OWNERDISPLAY        = 0x0080,\n    CF_DSPTEXT,\n    CF_DSPBITMAP,\n    CF_DSPMETAFILEPICT, // = 0x0083\n    CF_DSPENHMETAFILE      = 0x008E,\n    CF_PRIVATEFIRST        = 0x0200,\n    CF_PRIVATELAST         = 0x02FF,\n    CF_GDIOBJFIRST         = 0x0300,\n    CF_GDIOBJLAST          = 0x03FF\n}\n\nenum HKL_PREV = 0;\nenum HKL_NEXT = 1;\n\nenum KLF_ACTIVATE       = 1;\nenum KLF_SUBSTITUTE_OK  = 2;\nenum KLF_UNLOADPREVIOUS = 4;\nenum KLF_REORDER        = 8;\nenum KLF_REPLACELANG    = 16;\nenum KLF_NOTELLSHELL    = 128;\nenum KLF_SETFORPROCESS  = 256;\nenum KL_NAMELENGTH      = 9;\n\nenum MF_ENABLED = 0;\nenum MF_GRAYED = 1;\nenum MF_DISABLED = 2;\nenum MF_BITMAP = 4;\nenum MF_CHECKED = 8;\nenum MF_MENUBARBREAK = 32;\nenum MF_MENUBREAK = 64;\nenum MF_OWNERDRAW = 256;\nenum MF_POPUP = 16;\nenum MF_SEPARATOR = 0x800;\nenum MF_STRING = 0;\nenum MF_UNCHECKED = 0;\nenum MF_DEFAULT = 4096;\nenum MF_SYSMENU = 0x2000;\nenum MF_HELP = 0x4000;\nenum MF_END = 128;\nenum MF_RIGHTJUSTIFY = 0x4000;\nenum MF_MOUSESELECT = 0x8000;\nenum MF_INSERT = 0;\nenum MF_CHANGE = 128;\nenum MF_APPEND = 256;\nenum MF_DELETE = 512;\nenum MF_REMOVE = 4096;\nenum MF_USECHECKBITMAPS = 512;\nenum MF_UNHILITE = 0;\nenum MF_HILITE = 128;\n\n// Also defined in dbt.h\nenum BSM_ALLCOMPONENTS      = 0;\nenum BSM_VXDS               = 1;\nenum BSM_NETDRIVER          = 2;\nenum BSM_INSTALLABLEDRIVERS = 4;\nenum BSM_APPLICATIONS       = 8;\nenum BSM_ALLDESKTOPS        = 16;\n\nenum {\n    BSF_QUERY              = 0x0001,\n    BSF_IGNORECURRENTTASK  = 0x0002,\n    BSF_FLUSHDISK          = 0x0004,\n    BSF_NOHANG             = 0x0008,\n    BSF_POSTMESSAGE        = 0x0010,\n    BSF_FORCEIFHUNG        = 0x0020,\n    BSF_NOTIMEOUTIFNOTHUNG = 0x0040,\n    BSF_ALLOWSFW           = 0x0080,\n    BSF_SENDNOTIFYMESSAGE  = 0x0100\n}\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        BSF_RETURNHDESK    = 0x0200,\n        BSF_LUID           = 0x0400\n    }\n}\n\nenum BROADCAST_QUERY_DENY = 1112363332;\nenum DWORD ENUM_CURRENT_SETTINGS  = -1;\nenum DWORD ENUM_REGISTRY_SETTINGS = -2;\n\nenum CDS_UPDATEREGISTRY = 1;\nenum CDS_TEST           = 2;\nenum CDS_FULLSCREEN     = 4;\nenum CDS_GLOBAL         = 8;\nenum CDS_SET_PRIMARY    = 16;\nenum CDS_NORESET        = 0x10000000;\nenum CDS_SETRECT        = 0x20000000;\nenum CDS_RESET          = 0x40000000;\n\nenum {\n    DISP_CHANGE_BADPARAM   = -5,\n    DISP_CHANGE_BADFLAGS,\n    DISP_CHANGE_NOTUPDATED,\n    DISP_CHANGE_BADMODE,\n    DISP_CHANGE_FAILED,\n    DISP_CHANGE_SUCCESSFUL,\n    DISP_CHANGE_RESTART // =  1\n}\n\nenum BST_UNCHECKED     = 0;\nenum BST_CHECKED       = 1;\nenum BST_INDETERMINATE = 2;\nenum BST_PUSHED        = 4;\nenum BST_FOCUS         = 8;\n\nenum MF_BYCOMMAND  = 0;\nenum MF_BYPOSITION = 1024;\n// [Redefined] MF_UNCHECKED = 0\n// [Redefined] MF_HILITE = 128\n// [Redefined] MF_UNHILITE = 0\n\nenum CWP_ALL             = 0;\nenum CWP_SKIPINVISIBLE   = 1;\nenum CWP_SKIPDISABLED    = 2;\nenum CWP_SKIPTRANSPARENT = 4;\n\nenum IMAGE_BITMAP = 0;\nenum IMAGE_ICON = 1;\nenum IMAGE_CURSOR = 2;\nenum IMAGE_ENHMETAFILE = 3;\n\nenum DF_ALLOWOTHERACCOUNTHOOK = 1;\n\nenum DESKTOP_READOBJECTS     = 1;\nenum DESKTOP_CREATEWINDOW    = 2;\nenum DESKTOP_CREATEMENU      = 4;\nenum DESKTOP_HOOKCONTROL     = 8;\nenum DESKTOP_JOURNALRECORD   = 16;\nenum DESKTOP_JOURNALPLAYBACK = 32;\nenum DESKTOP_ENUMERATE       = 64;\nenum DESKTOP_WRITEOBJECTS    = 128;\nenum DESKTOP_SWITCHDESKTOP   = 256;\n\nenum int CW_USEDEFAULT = 0x80000000;\n\nenum {\n    WS_OVERLAPPED       = 0,\n    WS_TILED            = WS_OVERLAPPED,\n    WS_MAXIMIZEBOX      = 0x00010000,\n    WS_MINIMIZEBOX      = 0x00020000,\n    WS_TABSTOP          = 0x00010000,\n    WS_GROUP            = 0x00020000,\n    WS_THICKFRAME       = 0x00040000,\n    WS_SIZEBOX          = WS_THICKFRAME,\n    WS_SYSMENU          = 0x00080000,\n    WS_HSCROLL          = 0x00100000,\n    WS_VSCROLL          = 0x00200000,\n    WS_DLGFRAME         = 0x00400000,\n    WS_BORDER           = 0x00800000,\n    WS_CAPTION          = 0x00c00000,\n    WS_OVERLAPPEDWINDOW = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,\n    WS_TILEDWINDOW      = WS_OVERLAPPEDWINDOW,\n    WS_MAXIMIZE         = 0x01000000,\n    WS_CLIPCHILDREN     = 0x02000000,\n    WS_CLIPSIBLINGS     = 0x04000000,\n    WS_DISABLED         = 0x08000000,\n    WS_VISIBLE          = 0x10000000,\n    WS_MINIMIZE         = 0x20000000,\n    WS_ICONIC           = WS_MINIMIZE,\n    WS_CHILD            = 0x40000000,\n    WS_CHILDWINDOW      = 0x40000000,\n    WS_POPUP            = 0x80000000,\n    WS_POPUPWINDOW      = WS_POPUP|WS_BORDER|WS_SYSMENU,\n}\n\nenum MDIS_ALLCHILDSTYLES = 1;\n\nenum BS_3STATE = 5;\nenum BS_AUTO3STATE = 6;\nenum BS_AUTOCHECKBOX = 3;\nenum BS_AUTORADIOBUTTON = 9;\nenum BS_BITMAP = 128;\nenum BS_BOTTOM = 0x800;\nenum BS_CENTER = 0x300;\nenum BS_CHECKBOX = 2;\nenum BS_DEFPUSHBUTTON = 1;\nenum BS_GROUPBOX = 7;\nenum BS_ICON = 64;\nenum BS_LEFT = 256;\nenum BS_LEFTTEXT = 32;\nenum BS_MULTILINE = 0x2000;\nenum BS_NOTIFY = 0x4000;\nenum BS_OWNERDRAW = 0xb;\nenum BS_PUSHBUTTON = 0;\nenum BS_PUSHLIKE = 4096;\nenum BS_RADIOBUTTON = 4;\nenum BS_RIGHT = 512;\nenum BS_RIGHTBUTTON = 32;\nenum BS_TEXT = 0;\nenum BS_TOP = 0x400;\nenum BS_USERBUTTON = 8;\nenum BS_VCENTER = 0xc00;\nenum BS_FLAT = 0x8000;\n\nenum CBS_AUTOHSCROLL = 64;\nenum CBS_DISABLENOSCROLL = 0x800;\nenum CBS_DROPDOWN = 2;\nenum CBS_DROPDOWNLIST = 3;\nenum CBS_HASSTRINGS = 512;\nenum CBS_LOWERCASE = 0x4000;\nenum CBS_NOINTEGRALHEIGHT = 0x400;\nenum CBS_OEMCONVERT = 128;\nenum CBS_OWNERDRAWFIXED = 16;\nenum CBS_OWNERDRAWVARIABLE = 32;\nenum CBS_SIMPLE = 1;\nenum CBS_SORT = 256;\nenum CBS_UPPERCASE = 0x2000;\n\nenum ES_AUTOHSCROLL = 128;\nenum ES_AUTOVSCROLL = 64;\nenum ES_CENTER = 1;\nenum ES_LEFT = 0;\nenum ES_LOWERCASE = 16;\nenum ES_MULTILINE = 4;\nenum ES_NOHIDESEL = 256;\nenum ES_NUMBER = 0x2000;\nenum ES_OEMCONVERT = 0x400;\nenum ES_PASSWORD = 32;\nenum ES_READONLY = 0x800;\nenum ES_RIGHT = 2;\nenum ES_UPPERCASE = 8;\nenum ES_WANTRETURN = 4096;\n\nenum LBS_DISABLENOSCROLL = 4096;\nenum LBS_EXTENDEDSEL = 0x800;\nenum LBS_HASSTRINGS = 64;\nenum LBS_MULTICOLUMN = 512;\nenum LBS_MULTIPLESEL = 8;\nenum LBS_NODATA = 0x2000;\nenum LBS_NOINTEGRALHEIGHT = 256;\nenum LBS_NOREDRAW = 4;\nenum LBS_NOSEL = 0x4000;\nenum LBS_NOTIFY = 1;\nenum LBS_OWNERDRAWFIXED = 16;\nenum LBS_OWNERDRAWVARIABLE = 32;\nenum LBS_SORT = 2;\nenum LBS_STANDARD = 0xa00003;\nenum LBS_USETABSTOPS = 128;\nenum LBS_WANTKEYBOARDINPUT = 0x400;\n\nenum SBS_BOTTOMALIGN = 4;\nenum SBS_HORZ = 0;\nenum SBS_LEFTALIGN = 2;\nenum SBS_RIGHTALIGN = 4;\nenum SBS_SIZEBOX = 8;\nenum SBS_SIZEBOXBOTTOMRIGHTALIGN = 4;\nenum SBS_SIZEBOXTOPLEFTALIGN = 2;\nenum SBS_SIZEGRIP = 16;\nenum SBS_TOPALIGN = 2;\nenum SBS_VERT = 1;\n\nenum SS_BITMAP = 14;\nenum SS_BLACKFRAME = 7;\nenum SS_BLACKRECT = 4;\nenum SS_CENTER = 1;\nenum SS_CENTERIMAGE = 512;\nenum SS_ENHMETAFILE = 15;\nenum SS_ETCHEDFRAME = 18;\nenum SS_ETCHEDHORZ = 16;\nenum SS_ETCHEDVERT = 17;\nenum SS_GRAYFRAME = 8;\nenum SS_GRAYRECT = 5;\nenum SS_ICON = 3;\nenum SS_LEFT = 0;\nenum SS_LEFTNOWORDWRAP = 0xc;\nenum SS_NOPREFIX = 128;\nenum SS_NOTIFY = 256;\nenum SS_OWNERDRAW = 0xd;\nenum SS_REALSIZEIMAGE = 0x800;\nenum SS_RIGHT = 2;\nenum SS_RIGHTJUST = 0x400;\nenum SS_SIMPLE = 11;\nenum SS_SUNKEN = 4096;\nenum SS_WHITEFRAME = 9;\nenum SS_WHITERECT = 6;\nenum SS_USERITEM = 10;\nenum SS_TYPEMASK = 0x0000001FL;\nenum SS_ENDELLIPSIS = 0x00004000L;\nenum SS_PATHELLIPSIS = 0x00008000L;\nenum SS_WORDELLIPSIS = 0x0000C000L;\nenum SS_ELLIPSISMASK = 0x0000C000L;\n\nenum DS_ABSALIGN      = 0x0001;\nenum DS_3DLOOK        = 0x0004;\nenum DS_SYSMODAL      = 0x0002;\nenum DS_FIXEDSYS      = 0x0008;\nenum DS_NOFAILCREATE  = 0x0010;\nenum DS_LOCALEDIT     = 0x0020;\nenum DS_SETFONT       = 0x0040;\nenum DS_MODALFRAME    = 0x0080;\nenum DS_NOIDLEMSG     = 0x0100;\nenum DS_SETFOREGROUND = 0x0200;\nenum DS_CONTROL       = 0x0400;\nenum DS_CENTER        = 0x0800;\nenum DS_CENTERMOUSE   = 0x1000;\nenum DS_CONTEXTHELP   = 0x2000;\nenum DS_SHELLFONT     = DS_SETFONT | DS_FIXEDSYS;\n\nenum WS_EX_ACCEPTFILES = 16;\nenum WS_EX_APPWINDOW = 0x40000;\nenum WS_EX_CLIENTEDGE = 512;\nenum WS_EX_COMPOSITED = 0x2000000;  // XP\nenum WS_EX_CONTEXTHELP = 0x400;\nenum WS_EX_CONTROLPARENT = 0x10000;\nenum WS_EX_DLGMODALFRAME = 1;\nenum WS_EX_LAYERED = 0x80000;  // w2k\nenum WS_EX_LAYOUTRTL = 0x400000;  // w98, w2k\nenum WS_EX_LEFT = 0;\nenum WS_EX_LEFTSCROLLBAR = 0x4000;\nenum WS_EX_LTRREADING = 0;\nenum WS_EX_MDICHILD = 64;\nenum WS_EX_NOACTIVATE = 0x8000000;  // w2k\nenum WS_EX_NOINHERITLAYOUT = 0x100000;  // w2k\nenum WS_EX_NOPARENTNOTIFY = 4;\nenum WS_EX_OVERLAPPEDWINDOW = 0x300;\nenum WS_EX_PALETTEWINDOW = 0x188;\nenum WS_EX_RIGHT = 0x1000;\nenum WS_EX_RIGHTSCROLLBAR = 0;\nenum WS_EX_RTLREADING = 0x2000;\nenum WS_EX_STATICEDGE = 0x20000;\nenum WS_EX_TOOLWINDOW = 128;\nenum WS_EX_TOPMOST = 8;\nenum WS_EX_TRANSPARENT = 32;\nenum WS_EX_WINDOWEDGE = 256;\n\nenum WINSTA_ENUMDESKTOPS      = 1;\nenum WINSTA_READATTRIBUTES    = 2;\nenum WINSTA_ACCESSCLIPBOARD   = 4;\nenum WINSTA_CREATEDESKTOP     = 8;\nenum WINSTA_WRITEATTRIBUTES   = 16;\nenum WINSTA_ACCESSGLOBALATOMS = 32;\nenum WINSTA_EXITWINDOWS       = 64;\nenum WINSTA_ENUMERATE         = 256;\nenum WINSTA_READSCREEN        = 512;\n\nenum DDL_READWRITE = 0;\nenum DDL_READONLY  = 1;\nenum DDL_HIDDEN    = 2;\nenum DDL_SYSTEM    = 4;\nenum DDL_DIRECTORY = 16;\nenum DDL_ARCHIVE   = 32;\nenum DDL_POSTMSGS  = 8192;\nenum DDL_DRIVES    = 16384;\nenum DDL_EXCLUSIVE = 32768;\n\nenum {\n    DC_ACTIVE       = 0x0001,\n    DC_SMALLCAP     = 0x0002,\n    DC_ICON         = 0x0004,\n    DC_TEXT         = 0x0008,\n    DC_INBUTTON     = 0x0010,\n    DC_GRADIENT     = 0x0020\n}\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum DC_BUTTONS = 0x1000;\n}\n\n// Where are these documented?\n//enum DC_CAPTION = DC_ICON|DC_TEXT|DC_BUTTONS;\n//enum DC_NC      = DC_CAPTION|DC_FRAME;\n\nenum BDR_RAISEDOUTER = 1;\nenum BDR_SUNKENOUTER = 2;\nenum BDR_RAISEDINNER = 4;\nenum BDR_SUNKENINNER = 8;\nenum BDR_OUTER       = 3;\nenum BDR_INNER       = 0xc;\nenum BDR_RAISED      = 5;\nenum BDR_SUNKEN      = 10;\n\nenum EDGE_RAISED = BDR_RAISEDOUTER|BDR_RAISEDINNER;\nenum EDGE_SUNKEN = BDR_SUNKENOUTER|BDR_SUNKENINNER;\nenum EDGE_ETCHED = BDR_SUNKENOUTER|BDR_RAISEDINNER;\nenum EDGE_BUMP   = BDR_RAISEDOUTER|BDR_SUNKENINNER;\n\nenum BF_LEFT                    = 1;\nenum BF_TOP                     = 2;\nenum BF_RIGHT                   = 4;\nenum BF_BOTTOM                  = 8;\nenum BF_TOPLEFT                 = BF_TOP|BF_LEFT;\nenum BF_TOPRIGHT                = BF_TOP|BF_RIGHT;\nenum BF_BOTTOMLEFT              = BF_BOTTOM|BF_LEFT;\nenum BF_BOTTOMRIGHT             = BF_BOTTOM|BF_RIGHT;\nenum BF_RECT                    = BF_LEFT|BF_TOP|BF_RIGHT|BF_BOTTOM ;\nenum BF_DIAGONAL                = 16;\nenum BF_DIAGONAL_ENDTOPRIGHT    = BF_DIAGONAL|BF_TOP|BF_RIGHT;\nenum BF_DIAGONAL_ENDTOPLEFT     = BF_DIAGONAL|BF_TOP|BF_LEFT;\nenum BF_DIAGONAL_ENDBOTTOMLEFT  = BF_DIAGONAL|BF_BOTTOM|BF_LEFT;\nenum BF_DIAGONAL_ENDBOTTOMRIGHT = BF_DIAGONAL|BF_BOTTOM|BF_RIGHT;\nenum BF_MIDDLE                  = 0x800;\nenum BF_SOFT                    = 0x1000;\nenum BF_ADJUST                  = 0x2000;\nenum BF_FLAT                    = 0x4000;\nenum BF_MONO                    = 0x8000;\n\nenum {\n    DFC_CAPTION      = 1,\n    DFC_MENU,\n    DFC_SCROLL,\n    DFC_BUTTON,\n    DFC_POPUPMENU // = 5\n}\n\nenum {\n    DFCS_CAPTIONCLOSE,\n    DFCS_CAPTIONMIN,\n    DFCS_CAPTIONMAX,\n    DFCS_CAPTIONRESTORE,\n    DFCS_CAPTIONHELP // = 4\n}\n\nenum {\n    DFCS_MENUARROW      = 0,\n    DFCS_MENUCHECK      = 1,\n    DFCS_MENUBULLET     = 2,\n    DFCS_MENUARROWRIGHT = 4\n}\n\nenum {\n    DFCS_SCROLLUP            =  0,\n    DFCS_SCROLLDOWN          =  1,\n    DFCS_SCROLLLEFT          =  2,\n    DFCS_SCROLLRIGHT         =  3,\n    DFCS_SCROLLCOMBOBOX      =  5,\n    DFCS_SCROLLSIZEGRIP      =  8,\n    DFCS_SCROLLSIZEGRIPRIGHT = 16\n}\n\nenum {\n    DFCS_BUTTONCHECK         = 0,\n    DFCS_BUTTONRADIOIMAGE    = 0x0001,\n    DFCS_BUTTONRADIOMASK     = 0x0002,\n    DFCS_BUTTONRADIO         = 0x0004,\n    DFCS_BUTTON3STATE        = 0x0008,\n    DFCS_BUTTONPUSH          = 0x0010,\n    DFCS_INACTIVE            = 0x0100,\n    DFCS_PUSHED              = 0x0200,\n    DFCS_CHECKED             = 0x0400,\n    DFCS_TRANSPARENT         = 0x0800,\n    DFCS_HOT                 = 0x1000,\n    DFCS_ADJUSTRECT          = 0x2000,\n    DFCS_FLAT                = 0x4000,\n    DFCS_MONO                = 0x8000\n}\n\nenum {\n    DST_COMPLEX = 0,\n    DST_TEXT,\n    DST_PREFIXTEXT,\n    DST_ICON,\n    DST_BITMAP // = 4\n}\n\nenum DSS_NORMAL = 0;\nenum DSS_UNION = 16;\nenum DSS_DISABLED = 32;\nenum DSS_MONO = 128;\nenum DSS_RIGHT = 0x8000;\n\nenum DT_BOTTOM = 8;\nenum DT_CALCRECT = 1024;\nenum DT_CENTER = 1;\nenum DT_EDITCONTROL = 8192;\nenum DT_END_ELLIPSIS = 32768;\nenum DT_PATH_ELLIPSIS = 16384;\nenum DT_WORD_ELLIPSIS = 0x40000;\nenum DT_EXPANDTABS = 64;\nenum DT_EXTERNALLEADING = 512;\nenum DT_LEFT = 0;\nenum DT_MODIFYSTRING = 65536;\nenum DT_NOCLIP = 256;\nenum DT_NOPREFIX = 2048;\nenum DT_RIGHT = 2;\nenum DT_RTLREADING = 131072;\nenum DT_SINGLELINE = 32;\nenum DT_TABSTOP = 128;\nenum DT_TOP = 0;\nenum DT_VCENTER = 4;\nenum DT_WORDBREAK = 16;\nenum DT_INTERNAL = 4096;\n\nenum WB_ISDELIMITER = 2;\nenum WB_LEFT = 0;\nenum WB_RIGHT = 1;\n\nenum SB_HORZ = 0;\nenum SB_VERT = 1;\nenum SB_CTL = 2;\nenum SB_BOTH = 3;\n\nenum ESB_DISABLE_BOTH = 3;\nenum ESB_DISABLE_DOWN = 2;\nenum ESB_DISABLE_LEFT = 1;\nenum ESB_DISABLE_LTUP = 1;\nenum ESB_DISABLE_RIGHT = 2;\nenum ESB_DISABLE_RTDN = 2;\nenum ESB_DISABLE_UP = 1;\nenum ESB_ENABLE_BOTH = 0;\n\nenum SB_LINEUP = 0;\nenum SB_LINEDOWN = 1;\nenum SB_LINELEFT = 0;\nenum SB_LINERIGHT = 1;\nenum SB_PAGEUP = 2;\nenum SB_PAGEDOWN = 3;\nenum SB_PAGELEFT = 2;\nenum SB_PAGERIGHT = 3;\nenum SB_THUMBPOSITION = 4;\nenum SB_THUMBTRACK = 5;\nenum SB_ENDSCROLL = 8;\nenum SB_LEFT = 6;\nenum SB_RIGHT = 7;\nenum SB_BOTTOM = 7;\nenum SB_TOP = 6;\n\n//MACRO #define IS_INTRESOURCE(i) (((ULONG_PTR)(i) >> 16) == 0)\n\ntemplate MAKEINTRESOURCE_T(WORD i) {\n    enum LPTSTR MAKEINTRESOURCE_T = cast(LPTSTR)(i);\n}\n\nnothrow @nogc {\n    LPSTR MAKEINTRESOURCEA(/*WORD*/uint i) {\n        return cast(LPSTR) i;\n    }\n\n    LPWSTR MAKEINTRESOURCEW(/*WORD*/uint i) {\n        return cast(LPWSTR) i;\n    }\n}\n\nenum RT_CURSOR       = MAKEINTRESOURCE_T!(1);\nenum RT_BITMAP       = MAKEINTRESOURCE_T!(2);\nenum RT_ICON         = MAKEINTRESOURCE_T!(3);\nenum RT_MENU         = MAKEINTRESOURCE_T!(4);\nenum RT_DIALOG       = MAKEINTRESOURCE_T!(5);\nenum RT_STRING       = MAKEINTRESOURCE_T!(6);\nenum RT_FONTDIR      = MAKEINTRESOURCE_T!(7);\nenum RT_FONT         = MAKEINTRESOURCE_T!(8);\nenum RT_ACCELERATOR  = MAKEINTRESOURCE_T!(9);\nenum RT_RCDATA       = MAKEINTRESOURCE_T!(10);\nenum RT_MESSAGETABLE = MAKEINTRESOURCE_T!(11);\n\nenum RT_GROUP_CURSOR = MAKEINTRESOURCE_T!(12);\nenum RT_GROUP_ICON   = MAKEINTRESOURCE_T!(14);\nenum RT_VERSION      = MAKEINTRESOURCE_T!(16);\nenum RT_DLGINCLUDE   = MAKEINTRESOURCE_T!(17);\nenum RT_PLUGPLAY     = MAKEINTRESOURCE_T!(19);\nenum RT_VXD          = MAKEINTRESOURCE_T!(20);\nenum RT_ANICURSOR    = MAKEINTRESOURCE_T!(21);\nenum RT_ANIICON      = MAKEINTRESOURCE_T!(22);\nenum RT_HTML         = MAKEINTRESOURCE_T!(23);\nenum RT_MANIFEST     = MAKEINTRESOURCE_T!(24);\n\nenum CREATEPROCESS_MANIFEST_RESOURCE_ID                 = MAKEINTRESOURCE_T!(1);\nenum ISOLATIONAWARE_MANIFEST_RESOURCE_ID                = MAKEINTRESOURCE_T!(2);\nenum ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID = MAKEINTRESOURCE_T!(3);\n\nenum {\n    EWX_LOGOFF      =  0,\n    EWX_SHUTDOWN    =  1,\n    EWX_REBOOT      =  2,\n    EWX_FORCE       =  4,\n    EWX_POWEROFF    =  8,\n    EWX_FORCEIFHUNG = 16\n}\n\nenum CS_BYTEALIGNCLIENT = 4096;\nenum CS_BYTEALIGNWINDOW = 8192;\nenum CS_KEYCVTWINDOW = 4;\nenum CS_NOKEYCVT = 256;\nenum CS_CLASSDC = 64;\nenum CS_DBLCLKS = 8;\nenum CS_GLOBALCLASS = 16384;\nenum CS_HREDRAW = 2;\nenum CS_NOCLOSE = 512;\nenum CS_OWNDC = 32;\nenum CS_PARENTDC = 128;\nenum CS_SAVEBITS = 2048;\nenum CS_VREDRAW = 1;\nenum CS_IME = 0x10000;\n\nenum GCW_ATOM = -32;\nenum GCL_CBCLSEXTRA = -20;\nenum GCL_CBWNDEXTRA = -18;\nenum GCL_HBRBACKGROUND = -10;\nenum GCL_HCURSOR = -12;\nenum GCL_HICON = -14;\nenum GCL_HICONSM = -34;\nenum GCL_HMODULE = -16;\nenum GCL_MENUNAME = -8;\nenum GCL_STYLE = -26;\nenum GCL_WNDPROC = -24;\n\nalias GCL_HICONSM GCLP_HICONSM;\nalias GCL_HICON GCLP_HICON;\nalias GCL_HCURSOR GCLP_HCURSOR;\nalias GCL_HBRBACKGROUND GCLP_HBRBACKGROUND;\nalias GCL_HMODULE  GCLP_HMODULE;\nalias GCL_MENUNAME GCLP_MENUNAME;\nalias GCL_WNDPROC  GCLP_WNDPROC;\n\nenum {\n    IDC_ARROW       = MAKEINTRESOURCE_T!(32512),\n    IDC_IBEAM       = MAKEINTRESOURCE_T!(32513),\n    IDC_WAIT        = MAKEINTRESOURCE_T!(32514),\n    IDC_CROSS       = MAKEINTRESOURCE_T!(32515),\n    IDC_UPARROW     = MAKEINTRESOURCE_T!(32516),\n    IDC_SIZE        = MAKEINTRESOURCE_T!(32640),\n    IDC_ICON        = MAKEINTRESOURCE_T!(32641),\n    IDC_SIZENWSE    = MAKEINTRESOURCE_T!(32642),\n    IDC_SIZENESW    = MAKEINTRESOURCE_T!(32643),\n    IDC_SIZEWE      = MAKEINTRESOURCE_T!(32644),\n    IDC_SIZENS      = MAKEINTRESOURCE_T!(32645),\n    IDC_SIZEALL     = MAKEINTRESOURCE_T!(32646),\n    IDC_NO          = MAKEINTRESOURCE_T!(32648),\n    IDC_HAND        = MAKEINTRESOURCE_T!(32649),\n    IDC_APPSTARTING = MAKEINTRESOURCE_T!(32650),\n    IDC_HELP        = MAKEINTRESOURCE_T!(32651),\n    IDI_APPLICATION = MAKEINTRESOURCE_T!(32512),\n    IDI_HAND        = MAKEINTRESOURCE_T!(32513),\n    IDI_QUESTION    = MAKEINTRESOURCE_T!(32514),\n    IDI_EXCLAMATION = MAKEINTRESOURCE_T!(32515),\n    IDI_ASTERISK    = MAKEINTRESOURCE_T!(32516),\n    IDI_WINLOGO     = MAKEINTRESOURCE_T!(32517),\n    IDI_WARNING     = IDI_EXCLAMATION,\n    IDI_ERROR       = IDI_HAND,\n    IDI_INFORMATION = IDI_ASTERISK\n}\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum IDI_SHIELD = MAKEINTRESOURCE_T!(32518);\n}\n\nenum {\n    MIIM_STATE      = 0x0001,\n    MIIM_ID         = 0x0002,\n    MIIM_SUBMENU    = 0x0004,\n    MIIM_CHECKMARKS = 0x0008,\n    MIIM_TYPE       = 0x0010,\n    MIIM_DATA       = 0x0020,\n    MIIM_STRING     = 0x0040,\n    MIIM_BITMAP     = 0x0080,\n    MIIM_FTYPE      = 0x0100\n}\n\nenum {\n    MFT_BITMAP       = 0x0004,\n    MFT_MENUBARBREAK = 0x0020,\n    MFT_MENUBREAK    = 0x0040,\n    MFT_OWNERDRAW    = 0x0100,\n    MFT_RADIOCHECK   = 0x0200,\n    MFT_RIGHTJUSTIFY = 0x4000,\n    MFT_SEPARATOR    = 0x0800,\n    MFT_RIGHTORDER   = 0x2000,\n    MFT_STRING       = 0\n}\n\nenum {\n    MFS_CHECKED   = 8,\n    MFS_DEFAULT   = 4096,\n    MFS_DISABLED  = 3,\n    MFS_ENABLED   = 0,\n    MFS_GRAYED    = 3,\n    MFS_HILITE    = 128,\n    MFS_UNCHECKED = 0,\n    MFS_UNHILITE  = 0\n}\n\nenum {\n    GW_HWNDFIRST = 0,\n    GW_HWNDLAST,\n    GW_HWNDNEXT,\n    GW_HWNDPREV,\n    GW_OWNER,\n    GW_CHILD  // = 5\n}\n\nenum {\n    SW_HIDE            =  0,\n    SW_NORMAL          =  1,\n    SW_SHOWNORMAL      =  1,\n    SW_SHOWMINIMIZED   =  2,\n    SW_MAXIMIZE        =  3,\n    SW_SHOWMAXIMIZED   =  3,\n    SW_SHOWNOACTIVATE  =  4,\n    SW_SHOW            =  5,\n    SW_MINIMIZE        =  6,\n    SW_SHOWMINNOACTIVE =  7,\n    SW_SHOWNA          =  8,\n    SW_RESTORE         =  9,\n    SW_SHOWDEFAULT     = 10,\n    SW_FORCEMINIMIZE   = 11,\n    SW_MAX             = 11\n}\n\nenum {\n    SW_PARENTCLOSING  = 1,\n    SW_OTHERZOOM,\n    SW_PARENTOPENING,\n    SW_OTHERUNZOOM // = 4\n}\n\nenum { // is this a different SW from the previous?\n    SW_SCROLLCHILDREN = 0x01,\n    SW_INVALIDATE     = 0x02,\n    SW_ERASE          = 0x04,\n    SW_SMOOTHSCROLL   = 0x10\n}\n\nenum {\n    MB_OK                        = 0,\n    MB_OKCANCEL,\n    MB_ABORTRETRYIGNORE,\n    MB_YESNOCANCEL,\n    MB_YESNO,\n    MB_RETRYCANCEL,\n    MB_CANCELTRYCONTINUE,     // = 6\n    MB_TYPEMASK                  = 0x0000000F,\n    MB_ICONHAND                  = 0x00000010,\n    MB_ICONSTOP                  = MB_ICONHAND,\n    MB_ICONERROR                 = MB_ICONHAND,\n    MB_ICONQUESTION              = 0x00000020,\n    MB_ICONEXCLAMATION           = 0x00000030,\n    MB_ICONWARNING               = MB_ICONEXCLAMATION,\n    MB_ICONASTERISK              = 0x00000040,\n    MB_ICONINFORMATION           = MB_ICONASTERISK,\n    MB_USERICON                  = 0x00000080,\n    MB_ICONMASK                  = 0x000000F0,\n\n    MB_DEFBUTTON1                = 0,\n    MB_DEFBUTTON2                = 0x00000100,\n    MB_DEFBUTTON3                = 0x00000200,\n    MB_DEFBUTTON4                = 0x00000300,\n    MB_DEFMASK                   = 0x00000F00,\n\n    MB_APPLMODAL                 = 0,\n    MB_SYSTEMMODAL               = 0x00001000,\n    MB_TASKMODAL                 = 0x00002000,\n    MB_MODEMASK                  = 0x00003000,\n\n    MB_HELP                      = 0x00004000,\n    MB_NOFOCUS                   = 0x00008000,\n    MB_MISCMASK                  = 0x0000C000,\n\n    MB_SETFOREGROUND             = 0x00010000,\n    MB_DEFAULT_DESKTOP_ONLY      = 0x00020000,\n    MB_TOPMOST                   = 0x00040000,\n    MB_SERVICE_NOTIFICATION_NT3X = 0x00040000,\n    MB_RIGHT                     = 0x00080000,\n    MB_RTLREADING                = 0x00100000,\n    MB_SERVICE_NOTIFICATION      = 0x00200000\n}\n\nenum {\n    IDOK          = 1,\n    IDCANCEL,\n    IDABORT,\n    IDRETRY,\n    IDIGNORE,\n    IDYES,\n    IDNO,\n    IDCLOSE,\n    IDHELP,\n    IDTRYAGAIN,\n    IDCONTINUE // = 11\n}\n\nenum GWL_EXSTYLE = -20;\nenum GWL_STYLE = -16;\nenum GWL_WNDPROC = -4;\nenum GWLP_WNDPROC = -4;\nenum GWL_HINSTANCE = -6;\nenum GWLP_HINSTANCE = -6;\nenum GWL_HWNDPARENT = -8;\nenum GWLP_HWNDPARENT = -8;\nenum GWL_ID = -12;\nenum GWLP_ID = -12;\nenum GWL_USERDATA = -21;\nenum GWLP_USERDATA = -21;\n\nenum DWL_DLGPROC = 4;\nenum DWLP_DLGPROC = 4;\nenum DWL_MSGRESULT = 0;\nenum DWLP_MSGRESULT = 0;\nenum DWL_USER = 8;\nenum DWLP_USER = 8;\n\nenum QS_KEY            = 1;\nenum QS_MOUSEMOVE      = 2;\nenum QS_MOUSEBUTTON    = 4;\nenum QS_MOUSE          = 6;\nenum QS_POSTMESSAGE    = 8;\nenum QS_TIMER          = 16;\nenum QS_PAINT          = 32;\nenum QS_SENDMESSAGE    = 64;\nenum QS_HOTKEY         = 128;\nenum QS_ALLPOSTMESSAGE = 256;\nstatic if (_WIN32_WINNT >= 0x501) {\nenum QS_RAWINPUT       = 1024;\nenum QS_INPUT          = 1031;\nenum QS_ALLEVENTS      = 1215;\nenum QS_ALLINPUT       = 1279;\n} else {\nenum QS_INPUT          = 7;\nenum QS_ALLEVENTS      = 191;\nenum QS_ALLINPUT       = 255;\n}\n\nenum MWMO_WAITALL        = 1;\nenum MWMO_ALERTABLE      = 2;\nenum MWMO_INPUTAVAILABLE = 4;\n\nenum COLOR_3DDKSHADOW = 21;\nenum COLOR_3DFACE = 15;\nenum COLOR_3DHILIGHT = 20;\nenum COLOR_3DHIGHLIGHT = 20;\nenum COLOR_3DLIGHT = 22;\nenum COLOR_BTNHILIGHT = 20;\nenum COLOR_3DSHADOW = 16;\nenum COLOR_ACTIVEBORDER = 10;\nenum COLOR_ACTIVECAPTION = 2;\nenum COLOR_APPWORKSPACE = 12;\nenum COLOR_BACKGROUND = 1;\nenum COLOR_DESKTOP = 1;\nenum COLOR_BTNFACE = 15;\nenum COLOR_BTNHIGHLIGHT = 20;\nenum COLOR_BTNSHADOW = 16;\nenum COLOR_BTNTEXT = 18;\nenum COLOR_CAPTIONTEXT = 9;\nenum COLOR_GRAYTEXT = 17;\nenum COLOR_HIGHLIGHT = 13;\nenum COLOR_HIGHLIGHTTEXT = 14;\nenum COLOR_INACTIVEBORDER = 11;\nenum COLOR_INACTIVECAPTION = 3;\nenum COLOR_INACTIVECAPTIONTEXT = 19;\nenum COLOR_INFOBK = 24;\nenum COLOR_INFOTEXT = 23;\nenum COLOR_MENU = 4;\nenum COLOR_MENUTEXT = 7;\nenum COLOR_SCROLLBAR = 0;\nenum COLOR_WINDOW = 5;\nenum COLOR_WINDOWFRAME = 6;\nenum COLOR_WINDOWTEXT = 8;\nenum COLOR_HOTLIGHT = 26;\nenum COLOR_GRADIENTACTIVECAPTION = 27;\nenum COLOR_GRADIENTINACTIVECAPTION = 28;\n\nenum CTLCOLOR_MSGBOX = 0;\nenum CTLCOLOR_EDIT = 1;\nenum CTLCOLOR_LISTBOX = 2;\nenum CTLCOLOR_BTN = 3;\nenum CTLCOLOR_DLG = 4;\nenum CTLCOLOR_SCROLLBAR = 5;\nenum CTLCOLOR_STATIC = 6;\nenum CTLCOLOR_MAX = 7;\n\n// For GetSystemMetrics()\nenum : int {\n    SM_CXSCREEN = 0,\n    SM_CYSCREEN,\n    SM_CXVSCROLL,\n    SM_CYHSCROLL,\n    SM_CYCAPTION,\n    SM_CXBORDER,\n    SM_CYBORDER,\n    SM_CXDLGFRAME,    // = 7\n    SM_CXFIXEDFRAME      = SM_CXDLGFRAME,\n    SM_CYDLGFRAME,    // = 8\n    SM_CYFIXEDFRAME      = SM_CYDLGFRAME,\n    SM_CYVTHUMB,      // = 9\n    SM_CXHTHUMB,\n    SM_CXICON,\n    SM_CYICON,\n    SM_CXCURSOR,\n    SM_CYCURSOR,\n    SM_CYMENU,\n    SM_CXFULLSCREEN,\n    SM_CYFULLSCREEN,\n    SM_CYKANJIWINDOW,\n    SM_MOUSEPRESENT,\n    SM_CYVSCROLL,\n    SM_CXHSCROLL,\n    SM_DEBUG,\n    SM_SWAPBUTTON,\n    SM_RESERVED1,\n    SM_RESERVED2,\n    SM_RESERVED3,\n    SM_RESERVED4,\n    SM_CXMIN,\n    SM_CYMIN,\n    SM_CXSIZE,\n    SM_CYSIZE,\n    SM_CXSIZEFRAME,   // = 32,\n    SM_CXFRAME           = SM_CXSIZEFRAME,\n    SM_CYSIZEFRAME,   // = 33\n    SM_CYFRAME           = SM_CYSIZEFRAME,\n    SM_CXMINTRACK,\n    SM_CYMINTRACK,\n    SM_CXDOUBLECLK,\n    SM_CYDOUBLECLK,\n    SM_CXICONSPACING,\n    SM_CYICONSPACING,\n    SM_MENUDROPALIGNMENT,\n    SM_PENWINDOWS,\n    SM_DBCSENABLED,\n    SM_CMOUSEBUTTONS,\n    SM_SECURE,\n    SM_CXEDGE,\n    SM_CYEDGE,\n    SM_CXMINSPACING,\n    SM_CYMINSPACING,\n    SM_CXSMICON,\n    SM_CYSMICON,\n    SM_CYSMCAPTION,\n    SM_CXSMSIZE,\n    SM_CYSMSIZE,\n    SM_CXMENUSIZE,\n    SM_CYMENUSIZE,\n    SM_ARRANGE,\n    SM_CXMINIMIZED,\n    SM_CYMINIMIZED,\n    SM_CXMAXTRACK,\n    SM_CYMAXTRACK,\n    SM_CXMAXIMIZED,\n    SM_CYMAXIMIZED,\n    SM_NETWORK,       // = 63\n    SM_CLEANBOOT         = 67,\n    SM_CXDRAG,\n    SM_CYDRAG,\n    SM_SHOWSOUNDS,\n    SM_CXMENUCHECK,\n    SM_CYMENUCHECK,\n    SM_SLOWMACHINE,\n    SM_MIDEASTENABLED,\n    SM_MOUSEWHEELPRESENT,\n    SM_XVIRTUALSCREEN,\n    SM_YVIRTUALSCREEN,\n    SM_CXVIRTUALSCREEN,\n    SM_CYVIRTUALSCREEN,\n    SM_CMONITORS,\n    SM_SAMEDISPLAYFORMAT,\n    SM_IMMENABLED,\n    SM_CXFOCUSBORDER,\n    SM_CYFOCUSBORDER, // = 84\n    SM_TABLETPC          = 86,\n    SM_MEDIACENTER,\n    SM_STARTER,       // = 88\n    SM_CMETRICS          = 88,\n    SM_SERVERR2,\n    SM_REMOTESESSION     = 0x1000,\n}\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {  // These are only for WinXP and later\n        SM_SHUTTINGDOWN  = 0x2000,\n        SM_REMOTECONTROL = 0x2001\n    }\n}\n\nenum ARW_BOTTOMLEFT = 0;\nenum ARW_BOTTOMRIGHT = 1;\nenum ARW_HIDE = 8;\nenum ARW_TOPLEFT = 2;\nenum ARW_TOPRIGHT = 3;\nenum ARW_DOWN = 4;\nenum ARW_LEFT = 0;\nenum ARW_RIGHT = 0;\nenum ARW_UP = 4;\n\nenum UOI_FLAGS = 1;\nenum UOI_NAME = 2;\nenum UOI_TYPE = 3;\nenum UOI_USER_SID = 4;\n\n// For the fuLoad parameter of LoadImage()\nenum : UINT {\n    LR_DEFAULTCOLOR     = 0,\n    LR_MONOCHROME       = 0x0001,\n    LR_COLOR            = 0x0002,\n    LR_COPYRETURNORG    = 0x0004,\n    LR_COPYDELETEORG    = 0x0008,\n    LR_LOADFROMFILE     = 0x0010,\n    LR_LOADTRANSPARENT  = 0x0020,\n    LR_DEFAULTSIZE      = 0x0040,\n    LR_VGACOLOR         = 0x0080,\n    LR_LOADREALSIZE     = 0x0080,\n    LR_LOADMAP3DCOLORS  = 0x1000,\n    LR_CREATEDIBSECTION = 0x2000,\n    LR_COPYFROMRESOURCE = 0x4000,\n    LR_SHARED           = 0x8000\n}\n\nenum {\n    KEYEVENTF_EXTENDEDKEY = 1,\n    KEYEVENTF_KEYUP       = 2,\n    KEYEVENTF_UNICODE     = 4,\n    KEYEVENTF_SCANCODE    = 8\n}\n\nenum OBM_BTNCORNERS = 32758;\nenum OBM_BTSIZE = 32761;\nenum OBM_CHECK = 32760;\nenum OBM_CHECKBOXES = 32759;\nenum OBM_CLOSE = 32754;\nenum OBM_COMBO = 32738;\nenum OBM_DNARROW = 32752;\nenum OBM_DNARROWD = 32742;\nenum OBM_DNARROWI = 32736;\nenum OBM_LFARROW = 32750;\nenum OBM_LFARROWI = 32734;\nenum OBM_LFARROWD = 32740;\nenum OBM_MNARROW = 32739;\nenum OBM_OLD_CLOSE = 32767;\nenum OBM_OLD_DNARROW = 32764;\nenum OBM_OLD_LFARROW = 32762;\nenum OBM_OLD_REDUCE = 32757;\nenum OBM_OLD_RESTORE = 32755;\nenum OBM_OLD_RGARROW = 32763;\nenum OBM_OLD_UPARROW = 32765;\nenum OBM_OLD_ZOOM = 32756;\nenum OBM_REDUCE = 32749;\nenum OBM_REDUCED = 32746;\nenum OBM_RESTORE = 32747;\nenum OBM_RESTORED = 32744;\nenum OBM_RGARROW = 32751;\nenum OBM_RGARROWD = 32741;\nenum OBM_RGARROWI = 32735;\nenum OBM_SIZE = 32766;\nenum OBM_UPARROW = 32753;\nenum OBM_UPARROWD = 32743;\nenum OBM_UPARROWI = 32737;\nenum OBM_ZOOM = 32748;\nenum OBM_ZOOMD = 32745;\n\nenum OCR_NORMAL = 32512;\nenum OCR_IBEAM = 32513;\nenum OCR_WAIT = 32514;\nenum OCR_CROSS = 32515;\nenum OCR_UP = 32516;\nenum OCR_SIZE = 32640;\nenum OCR_ICON = 32641;\nenum OCR_SIZENWSE = 32642;\nenum OCR_SIZENESW = 32643;\nenum OCR_SIZEWE = 32644;\nenum OCR_SIZENS = 32645;\nenum OCR_SIZEALL = 32646;\nenum OCR_NO = 32648;\nenum OCR_APPSTARTING = 32650;\n\nenum OIC_SAMPLE = 32512;\nenum OIC_HAND = 32513;\nenum OIC_QUES = 32514;\nenum OIC_BANG = 32515;\nenum OIC_NOTE = 32516;\nenum OIC_WINLOGO = 32517;\nenum OIC_WARNING = OIC_BANG;\nenum OIC_ERROR = OIC_HAND;\nenum OIC_INFORMATION = OIC_NOTE;\n\nenum HELPINFO_MENUITEM = 2;\nenum HELPINFO_WINDOW = 1;\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        WTS_CONSOLE_CONNECT = 1,\n        WTS_CONSOLE_DISCONNECT,\n        WTS_REMOTE_CONNECT,\n        WTS_REMOTE_DISCONNECT,\n        WTS_SESSION_LOGON,\n        WTS_SESSION_LOGOFF,\n        WTS_SESSION_LOCK,\n        WTS_SESSION_UNLOCK,\n        WTS_SESSION_REMOTE_CONTROL // = 9\n    }\n}\n\nenum MSGF_DIALOGBOX = 0;\nenum MSGF_MESSAGEBOX = 1;\nenum MSGF_MENU = 2;\nenum MSGF_MOVE = 3;\nenum MSGF_SIZE = 4;\nenum MSGF_SCROLLBAR = 5;\nenum MSGF_NEXTWINDOW = 6;\nenum MSGF_MAINLOOP = 8;\nenum MSGF_USER = 4096;\n\nenum {\n    MOUSEEVENTF_MOVE       = 0x0001,\n    MOUSEEVENTF_LEFTDOWN   = 0x0002,\n    MOUSEEVENTF_LEFTUP     = 0x0004,\n    MOUSEEVENTF_RIGHTDOWN  = 0x0008,\n    MOUSEEVENTF_RIGHTUP    = 0x0010,\n    MOUSEEVENTF_MIDDLEDOWN = 0x0020,\n    MOUSEEVENTF_MIDDLEUP   = 0x0040,\n    MOUSEEVENTF_XDOWN      = 0x0080,\n    MOUSEEVENTF_XUP        = 0x0100,\n    MOUSEEVENTF_WHEEL      = 0x0800,\n    MOUSEEVENTF_ABSOLUTE   = 0x8000\n}\n\nenum PM_NOREMOVE = 0;\nenum PM_REMOVE = 1;\nenum PM_NOYIELD = 2;\n\nenum : HWND {\n    HWND_BROADCAST = cast(HWND) 0xFFFF,\n    HWND_MESSAGE   = cast(HWND)     -3,\n    HWND_NOTOPMOST = cast(HWND)     -2,\n    HWND_TOPMOST   = cast(HWND)     -1,\n    HWND_TOP       = cast(HWND)      0,\n    HWND_DESKTOP   = cast(HWND)      0,\n    HWND_BOTTOM    = cast(HWND)      1\n}\n\nenum RDW_INVALIDATE      = 1;\nenum RDW_INTERNALPAINT   = 2;\nenum RDW_ERASE           = 4;\nenum RDW_VALIDATE        = 8;\nenum RDW_NOINTERNALPAINT = 16;\nenum RDW_NOERASE         = 32;\nenum RDW_NOCHILDREN      = 64;\nenum RDW_ALLCHILDREN     = 128;\nenum RDW_UPDATENOW       = 256;\nenum RDW_ERASENOW        = 512;\nenum RDW_FRAME           = 1024;\nenum RDW_NOFRAME         = 2048;\n\nenum {\n    SMTO_NORMAL             = 0,\n    SMTO_BLOCK              = 1,\n    SMTO_ABORTIFHUNG        = 2,\n    SMTO_NOTIMEOUTIFNOTHUNG = 8\n}\n\nenum SIF_ALL = 23;\nenum SIF_PAGE = 2;\nenum SIF_POS = 4;\nenum SIF_RANGE = 1;\nenum SIF_DISABLENOSCROLL = 8;\nenum SIF_TRACKPOS = 16;\n\nenum SWP_DRAWFRAME = 32;\nenum SWP_FRAMECHANGED = 32;\nenum SWP_HIDEWINDOW = 128;\nenum SWP_NOACTIVATE = 16;\nenum SWP_NOCOPYBITS = 256;\nenum SWP_NOMOVE = 2;\nenum SWP_NOSIZE = 1;\nenum SWP_NOREDRAW = 8;\nenum SWP_NOZORDER = 4;\nenum SWP_SHOWWINDOW = 64;\nenum SWP_NOOWNERZORDER = 512;\nenum SWP_NOREPOSITION = 512;\nenum SWP_NOSENDCHANGING = 1024;\nenum SWP_DEFERERASE = 8192;\nenum SWP_ASYNCWINDOWPOS = 16384;\n\nenum { // passed variously as int or WPARAM\n    HSHELL_WINDOWCREATED    =     1,\n    HSHELL_WINDOWDESTROYED,\n    HSHELL_ACTIVATESHELLWINDOW,\n    HSHELL_WINDOWACTIVATED,\n    HSHELL_GETMINRECT,\n    HSHELL_REDRAW,\n    HSHELL_TASKMAN,\n    HSHELL_LANGUAGE,     // =     8\n    HSHELL_ENDTASK          =    10,\n    HSHELL_ACCESSIBILITYSTATE,\n    HSHELL_APPCOMMAND,   // =    12\n    HSHELL_RUDEAPPACTIVATED = 32772,\n    HSHELL_FLASH            = 32774\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum {\n        HSHELL_WINDOWREPLACED = 13,\n        HSHELL_WINDOWREPLACING\n    }\n}\n\nenum {\n    SPI_GETBEEP                   = 0x0001,\n    SPI_SETBEEP                   = 0x0002,\n    SPI_GETMOUSE                  = 0x0003,\n    SPI_SETMOUSE                  = 0x0004,\n    SPI_GETBORDER                 = 0x0005,\n    SPI_SETBORDER                 = 0x0006,\n    SPI_GETKEYBOARDSPEED          = 0x000A,\n    SPI_SETKEYBOARDSPEED          = 0x000B,\n    SPI_LANGDRIVER                = 0x000C,\n    SPI_ICONHORIZONTALSPACING     = 0x000D,\n    SPI_GETSCREENSAVETIMEOUT      = 0x000E,\n    SPI_SETSCREENSAVETIMEOUT      = 0x000F,\n    SPI_GETSCREENSAVEACTIVE       = 0x0010,\n    SPI_SETSCREENSAVEACTIVE       = 0x0011,\n    SPI_GETGRIDGRANULARITY        = 0x0012,\n    SPI_SETGRIDGRANULARITY        = 0x0013,\n    SPI_SETDESKWALLPAPER          = 0x0014,\n    SPI_SETDESKPATTERN            = 0x0015,\n    SPI_GETKEYBOARDDELAY          = 0x0016,\n    SPI_SETKEYBOARDDELAY          = 0x0017,\n    SPI_ICONVERTICALSPACING       = 0x0018,\n    SPI_GETICONTITLEWRAP          = 0x0019,\n    SPI_SETICONTITLEWRAP          = 0x001A,\n    SPI_GETMENUDROPALIGNMENT      = 0x001B,\n    SPI_SETMENUDROPALIGNMENT      = 0x001C,\n    SPI_SETDOUBLECLKWIDTH         = 0x001D,\n    SPI_SETDOUBLECLKHEIGHT        = 0x001E,\n    SPI_GETICONTITLELOGFONT       = 0x001F,\n    SPI_SETDOUBLECLICKTIME        = 0x0020,\n    SPI_SETMOUSEBUTTONSWAP        = 0x0021,\n    SPI_SETICONTITLELOGFONT       = 0x0022,\n    SPI_GETFASTTASKSWITCH         = 0x0023,\n    SPI_SETFASTTASKSWITCH         = 0x0024,\n    SPI_SETDRAGFULLWINDOWS        = 0x0025,\n    SPI_GETDRAGFULLWINDOWS        = 0x0026,\n    SPI_GETNONCLIENTMETRICS       = 0x0029,\n    SPI_SETNONCLIENTMETRICS       = 0x002A,\n    SPI_GETMINIMIZEDMETRICS       = 0x002B,\n    SPI_SETMINIMIZEDMETRICS       = 0x002C,\n    SPI_GETICONMETRICS            = 0x002D,\n    SPI_SETICONMETRICS            = 0x002E,\n    SPI_SETWORKAREA               = 0x002F,\n    SPI_GETWORKAREA               = 0x0030,\n    SPI_SETPENWINDOWS             = 0x0031,\n    SPI_GETFILTERKEYS             = 0x0032,\n    SPI_SETFILTERKEYS             = 0x0033,\n    SPI_GETTOGGLEKEYS             = 0x0034,\n    SPI_SETTOGGLEKEYS             = 0x0035,\n    SPI_GETMOUSEKEYS              = 0x0036,\n    SPI_SETMOUSEKEYS              = 0x0037,\n    SPI_GETSHOWSOUNDS             = 0x0038,\n    SPI_SETSHOWSOUNDS             = 0x0039,\n    SPI_GETSTICKYKEYS             = 0x003A,\n    SPI_SETSTICKYKEYS             = 0x003B,\n    SPI_GETACCESSTIMEOUT          = 0x003C,\n    SPI_SETACCESSTIMEOUT          = 0x003D,\n    SPI_GETSERIALKEYS             = 0x003E,\n    SPI_SETSERIALKEYS             = 0x003F,\n    SPI_GETSOUNDSENTRY            = 0x0040,\n    SPI_SETSOUNDSENTRY            = 0x0041,\n    SPI_GETHIGHCONTRAST           = 0x0042,\n    SPI_SETHIGHCONTRAST           = 0x0043,\n    SPI_GETKEYBOARDPREF           = 0x0044,\n    SPI_SETKEYBOARDPREF           = 0x0045,\n    SPI_GETSCREENREADER           = 0x0046,\n    SPI_SETSCREENREADER           = 0x0047,\n    SPI_GETANIMATION              = 0x0048,\n    SPI_SETANIMATION              = 0x0049,\n    SPI_GETFONTSMOOTHING          = 0x004A,\n    SPI_SETFONTSMOOTHING          = 0x004B,\n    SPI_SETDRAGWIDTH              = 0x004C,\n    SPI_SETDRAGHEIGHT             = 0x004D,\n    SPI_SETHANDHELD               = 0x004E,\n    SPI_GETLOWPOWERTIMEOUT        = 0x004F,\n    SPI_GETPOWEROFFTIMEOUT        = 0x0050,\n    SPI_SETLOWPOWERTIMEOUT        = 0x0051,\n    SPI_SETPOWEROFFTIMEOUT        = 0x0052,\n    SPI_GETLOWPOWERACTIVE         = 0x0053,\n    SPI_GETPOWEROFFACTIVE         = 0x0054,\n    SPI_SETLOWPOWERACTIVE         = 0x0055,\n    SPI_SETPOWEROFFACTIVE         = 0x0056,\n    SPI_SETCURSORS                = 0x0057,\n    SPI_SETICONS                  = 0x0058,\n    SPI_GETDEFAULTINPUTLANG       = 0x0059,\n    SPI_SETDEFAULTINPUTLANG       = 0x005A,\n    SPI_SETLANGTOGGLE             = 0x005B,\n    SPI_GETWINDOWSEXTENSION       = 0x005C,\n    SPI_SETMOUSETRAILS            = 0x005D,\n    SPI_GETMOUSETRAILS            = 0x005E,\n    SPI_GETSNAPTODEFBUTTON        = 0x005F,\n    SPI_SETSNAPTODEFBUTTON        = 0x0060,\n    //SPI_SCREENSAVERRUNNING        = 0x0061, // mistake in older MinGW?\n    SPI_SETSCREENSAVERRUNNING     = 0x0061,\n    SPI_GETMOUSEHOVERWIDTH        = 0x0062,\n    SPI_SETMOUSEHOVERWIDTH        = 0x0063,\n    SPI_GETMOUSEHOVERHEIGHT       = 0x0064,\n    SPI_SETMOUSEHOVERHEIGHT       = 0x0065,\n    SPI_GETMOUSEHOVERTIME         = 0x0066,\n    SPI_SETMOUSEHOVERTIME         = 0x0067,\n    SPI_GETWHEELSCROLLLINES       = 0x0068,\n    SPI_SETWHEELSCROLLLINES       = 0x0069,\n    SPI_GETMENUSHOWDELAY          = 0x006A,\n    SPI_SETMENUSHOWDELAY          = 0x006B,\n    SPI_GETSHOWIMEUI              = 0x006E,\n    SPI_SETSHOWIMEUI              = 0x006F,\n    SPI_GETMOUSESPEED             = 0x0070,\n    SPI_SETMOUSESPEED             = 0x0071,\n    SPI_GETSCREENSAVERRUNNING     = 0x0072,\n    SPI_GETDESKWALLPAPER          = 0x0073,\n    SPI_GETACTIVEWINDOWTRACKING   = 0x1000,\n    SPI_SETACTIVEWINDOWTRACKING   = 0x1001,\n    SPI_GETMENUANIMATION          = 0x1002,\n    SPI_SETMENUANIMATION          = 0x1003,\n    SPI_GETCOMBOBOXANIMATION      = 0x1004,\n    SPI_SETCOMBOBOXANIMATION      = 0x1005,\n    SPI_GETLISTBOXSMOOTHSCROLLING = 0x1006,\n    SPI_SETLISTBOXSMOOTHSCROLLING = 0x1007,\n    SPI_GETGRADIENTCAPTIONS       = 0x1008,\n    SPI_SETGRADIENTCAPTIONS       = 0x1009,\n    SPI_GETKEYBOARDCUES           = 0x100A,\n    SPI_GETMENUUNDERLINES         = SPI_GETKEYBOARDCUES,\n    SPI_SETKEYBOARDCUES           = 0x100B,\n    SPI_SETMENUUNDERLINES         = SPI_SETKEYBOARDCUES,\n    SPI_GETACTIVEWNDTRKZORDER     = 0x100C,\n    SPI_SETACTIVEWNDTRKZORDER     = 0x100D,\n    SPI_GETHOTTRACKING            = 0x100E,\n    SPI_SETHOTTRACKING            = 0x100F,\n    SPI_GETMENUFADE               = 0x1012,\n    SPI_SETMENUFADE               = 0x1013,\n    SPI_GETSELECTIONFADE          = 0x1014,\n    SPI_SETSELECTIONFADE          = 0x1015,\n    SPI_GETTOOLTIPANIMATION       = 0x1016,\n    SPI_SETTOOLTIPANIMATION       = 0x1017,\n    SPI_GETTOOLTIPFADE            = 0x1018,\n    SPI_SETTOOLTIPFADE            = 0x1019,\n    SPI_GETCURSORSHADOW           = 0x101A,\n    SPI_SETCURSORSHADOW           = 0x101B,\n    SPI_GETBLOCKSENDINPUTRESETS   = 0x1026,\n    SPI_SETBLOCKSENDINPUTRESETS   = 0x1027,\n    SPI_GETUIEFFECTS              = 0x103E,\n    SPI_SETUIEFFECTS              = 0x103F,\n    SPI_GETFOREGROUNDLOCKTIMEOUT  = 0x2000,\n    SPI_SETFOREGROUNDLOCKTIMEOUT  = 0x2001,\n    SPI_GETACTIVEWNDTRKTIMEOUT    = 0x2002,\n    SPI_SETACTIVEWNDTRKTIMEOUT    = 0x2003,\n    SPI_GETFOREGROUNDFLASHCOUNT   = 0x2004,\n    SPI_SETFOREGROUNDFLASHCOUNT   = 0x2005,\n    SPI_GETCARETWIDTH             = 0x2006,\n    SPI_SETCARETWIDTH             = 0x2007\n}\n\nenum {\n    SPIF_UPDATEINIFILE    = 1,\n    SPIF_SENDWININICHANGE = 2,\n    SPIF_SENDCHANGE       = SPIF_SENDWININICHANGE\n}\n\n// [Redefined] ATF_ONOFFFEEDBACK = 2\n// [Redefined] ATF_TIMEOUTON = 1\nenum WM_APP = 32768;\nenum WM_ACTIVATE = 6;\nenum WM_ACTIVATEAPP = 28;\nenum WM_AFXFIRST = 864;\nenum WM_AFXLAST = 895;\nenum WM_ASKCBFORMATNAME = 780;\nenum WM_CANCELJOURNAL = 75;\nenum WM_CANCELMODE = 31;\nenum WM_CAPTURECHANGED = 533;\nenum WM_CHANGECBCHAIN = 781;\nenum WM_CHAR = 258;\nenum WM_CHARTOITEM = 47;\nenum WM_CHILDACTIVATE = 34;\nenum WM_CLEAR = 771;\nenum WM_CLOSE = 16;\nenum WM_COMMAND = 273;\nenum WM_COMMNOTIFY = 68; // obsolete\nenum WM_COMPACTING = 65;\nenum WM_COMPAREITEM = 57;\nenum WM_CONTEXTMENU = 123;\nenum WM_COPY = 769;\nenum WM_COPYDATA = 74;\nenum WM_CREATE = 1;\nenum WM_CTLCOLORBTN = 309;\nenum WM_CTLCOLORDLG = 310;\nenum WM_CTLCOLOREDIT = 307;\nenum WM_CTLCOLORLISTBOX = 308;\nenum WM_CTLCOLORMSGBOX = 306;\nenum WM_CTLCOLORSCROLLBAR = 311;\nenum WM_CTLCOLORSTATIC = 312;\nenum WM_CUT = 768;\nenum WM_DEADCHAR = 259;\nenum WM_DELETEITEM = 45;\nenum WM_DESTROY = 2;\nenum WM_DESTROYCLIPBOARD = 775;\nenum WM_DEVICECHANGE = 537;\nenum WM_DEVMODECHANGE = 27;\nenum WM_DISPLAYCHANGE = 126;\nenum WM_DRAWCLIPBOARD = 776;\nenum WM_DRAWITEM = 43;\nenum WM_DROPFILES = 563;\nenum WM_ENABLE = 10;\nenum WM_ENDSESSION = 22;\nenum WM_ENTERIDLE = 289;\nenum WM_ENTERMENULOOP = 529;\nenum WM_ENTERSIZEMOVE = 561;\nenum WM_ERASEBKGND = 20;\nenum WM_EXITMENULOOP = 530;\nenum WM_EXITSIZEMOVE = 562;\nenum WM_FONTCHANGE = 29;\nenum WM_GETDLGCODE = 135;\nenum WM_GETFONT = 49;\nenum WM_GETHOTKEY = 51;\nenum WM_GETICON = 127;\nenum WM_GETMINMAXINFO = 36;\nenum WM_GETTEXT = 13;\nenum WM_GETTEXTLENGTH = 14;\nenum WM_HANDHELDFIRST = 856;\nenum WM_HANDHELDLAST = 863;\nenum WM_HELP = 83;\nenum WM_HOTKEY = 786;\nenum WM_HSCROLL = 276;\nenum WM_HSCROLLCLIPBOARD = 782;\nenum WM_ICONERASEBKGND = 39;\nenum WM_INITDIALOG = 272;\nenum WM_INITMENU = 278;\nenum WM_INITMENUPOPUP = 279;\nenum WM_INPUTLANGCHANGE = 81;\nenum WM_INPUTLANGCHANGEREQUEST = 80;\nenum WM_KEYDOWN = 256;\nenum WM_KEYUP = 257;\nenum WM_KILLFOCUS = 8;\nenum WM_MDIACTIVATE = 546;\nenum WM_MDICASCADE = 551;\nenum WM_MDICREATE = 544;\nenum WM_MDIDESTROY = 545;\nenum WM_MDIGETACTIVE = 553;\nenum WM_MDIICONARRANGE = 552;\nenum WM_MDIMAXIMIZE = 549;\nenum WM_MDINEXT = 548;\nenum WM_MDIREFRESHMENU = 564;\nenum WM_MDIRESTORE = 547;\nenum WM_MDISETMENU = 560;\nenum WM_MDITILE = 550;\nenum WM_MEASUREITEM = 44;\nenum WM_UNINITMENUPOPUP = 0x0125;\nenum WM_MENURBUTTONUP = 290;\nenum WM_MENUCOMMAND = 0x0126;\nenum WM_MENUGETOBJECT = 0x0124;\nenum WM_MENUDRAG = 0x0123;\n\nenum WM_CHANGEUISTATE = 0x0127;\nenum WM_UPDATEUISTATE = 0x0128;\nenum WM_QUERYUISTATE  = 0x0129;\n\n// LOWORD(wParam) values in WM_*UISTATE*\nenum {\n    UIS_SET          =  1,\n    UIS_CLEAR        =  2,\n    UIS_INITIALIZE   =  3\n}\n\n// HIWORD(wParam) values in WM_*UISTATE*\nenum {\n    UISF_HIDEFOCUS   =  0x1,\n    UISF_HIDEACCEL   =  0x2\n}\n\n\nstatic if (_WIN32_WINNT >= 0x501) {\n\n    // HIWORD(wParam) values in WM_*UISTATE*\n    enum {\n        UISF_ACTIVE      =  0x4\n    }\n\n}\n\nenum WM_MENUCHAR = 288;\nenum WM_MENUSELECT = 287;\nenum WM_MOVE = 3;\nenum WM_MOVING = 534;\nenum WM_NCACTIVATE = 134;\nenum WM_NCCALCSIZE = 131;\nenum WM_NCCREATE = 129;\nenum WM_NCDESTROY = 130;\nenum WM_NCHITTEST = 132;\nenum WM_NCLBUTTONDBLCLK = 163;\nenum WM_NCLBUTTONDOWN = 161;\nenum WM_NCLBUTTONUP = 162;\nenum WM_NCMBUTTONDBLCLK = 169;\nenum WM_NCMBUTTONDOWN = 167;\nenum WM_NCMBUTTONUP = 168;\nenum WM_NCXBUTTONDOWN = 171;\nenum WM_NCXBUTTONUP = 172;\nenum WM_NCXBUTTONDBLCLK = 173;\nenum WM_NCMOUSEHOVER = 0x02A0;\nenum WM_NCMOUSELEAVE = 0x02A2;\nenum WM_NCMOUSEMOVE = 160;\nenum WM_NCPAINT = 133;\nenum WM_NCRBUTTONDBLCLK = 166;\nenum WM_NCRBUTTONDOWN = 164;\nenum WM_NCRBUTTONUP = 165;\nenum WM_NEXTDLGCTL = 40;\nenum WM_NEXTMENU = 531;\nenum WM_NOTIFY = 78;\nenum WM_NOTIFYFORMAT = 85;\nenum WM_NULL = 0;\nenum WM_PAINT = 15;\nenum WM_PAINTCLIPBOARD = 777;\nenum WM_PAINTICON = 38;\nenum WM_PALETTECHANGED = 785;\nenum WM_PALETTEISCHANGING = 784;\nenum WM_PARENTNOTIFY = 528;\nenum WM_PASTE = 770;\nenum WM_PENWINFIRST = 896;\nenum WM_PENWINLAST = 911;\nenum WM_POWER = 72;\nenum WM_POWERBROADCAST = 536;\nenum WM_PRINT = 791;\nenum WM_PRINTCLIENT = 792;\nenum WM_APPCOMMAND = 0x0319;\nenum WM_QUERYDRAGICON = 55;\nenum WM_QUERYENDSESSION = 17;\nenum WM_QUERYNEWPALETTE = 783;\nenum WM_QUERYOPEN = 19;\nenum WM_QUEUESYNC = 35;\nenum WM_QUIT = 18;\nenum WM_RENDERALLFORMATS = 774;\nenum WM_RENDERFORMAT = 773;\nenum WM_SETCURSOR = 32;\nenum WM_SETFOCUS = 7;\nenum WM_SETFONT = 48;\nenum WM_SETHOTKEY = 50;\nenum WM_SETICON = 128;\nenum WM_SETREDRAW = 11;\nenum WM_SETTEXT = 12;\nenum WM_SETTINGCHANGE = 26;\nenum WM_SHOWWINDOW = 24;\nenum WM_SIZE = 5;\nenum WM_SIZECLIPBOARD = 779;\nenum WM_SIZING = 532;\nenum WM_SPOOLERSTATUS = 42;\nenum WM_STYLECHANGED = 125;\nenum WM_STYLECHANGING = 124;\nenum WM_SYSCHAR = 262;\nenum WM_SYSCOLORCHANGE = 21;\nenum WM_SYSCOMMAND = 274;\nenum WM_SYSDEADCHAR = 263;\nenum WM_SYSKEYDOWN = 260;\nenum WM_SYSKEYUP = 261;\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum WM_TABLET_FIRST = 704;\n    enum WM_TABLET_LAST = 735;\n}\nenum WM_TCARD = 82;\nenum WM_THEMECHANGED = 794;\nenum WM_TIMECHANGE = 30;\nenum WM_TIMER = 275;\nenum WM_UNDO = 772;\nenum WM_USER = 1024;\nenum WM_USERCHANGED = 84;\nenum WM_VKEYTOITEM = 46;\nenum WM_VSCROLL = 277;\nenum WM_VSCROLLCLIPBOARD = 778;\nenum WM_WINDOWPOSCHANGED = 71;\nenum WM_WINDOWPOSCHANGING = 70;\nenum WM_WININICHANGE = 26;\nstatic if (_WIN32_WINNT >= 0x501) {\nenum WM_WTSSESSION_CHANGE = 689;\n}\nenum WM_INPUT = 255;\nenum WM_KEYFIRST = 256;\nstatic if (_WIN32_WINNT >= 0x501) {\nenum WM_UNICHAR = 265;\nenum WM_KEYLAST = 265;\nenum UNICODE_NOCHAR = 0xFFFF;\n} else {\nenum WM_KEYLAST = 264;\n}\nenum WM_SYNCPAINT = 136;\nenum WM_MOUSEACTIVATE = 33;\nenum WM_MOUSEMOVE = 512;\nenum WM_LBUTTONDOWN = 513;\nenum WM_LBUTTONUP = 514;\nenum WM_LBUTTONDBLCLK = 515;\nenum WM_RBUTTONDOWN = 516;\nenum WM_RBUTTONUP = 517;\nenum WM_RBUTTONDBLCLK = 518;\nenum WM_MBUTTONDOWN = 519;\nenum WM_MBUTTONUP = 520;\nenum WM_MBUTTONDBLCLK = 521;\nenum WM_MOUSEWHEEL = 522;\nenum WM_MOUSEFIRST = 512;\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum WM_XBUTTONDOWN = 523;\n    enum WM_XBUTTONUP = 524;\n    enum WM_XBUTTONDBLCLK = 525;\n}\nstatic if (_WIN32_WINNT >= 0x600) { // FIXME: where did this come from? what version is it?\n    enum WM_MOUSEHWHEEL = 526;\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum WM_MOUSELAST = WM_MOUSEHWHEEL;\n} else static if (_WIN32_WINNT >= 0x501) {\n    enum WM_MOUSELAST = WM_XBUTTONDBLCLK;\n} else {\n    enum WM_MOUSELAST = WM_MOUSEWHEEL;\n}\n\nenum WM_MOUSEHOVER = 0x2A1;\nenum WM_MOUSELEAVE = 0x2A3;\n\nenum WHEEL_DELTA = 120;\n\nSHORT GET_WHEEL_DELTA_WPARAM()(WPARAM wparam) {\n    return cast(SHORT) HIWORD(wparam);\n}\n\nenum WHEEL_PAGESCROLL = uint.max;\n\nenum BM_CLICK = 245;\nenum BM_GETCHECK = 240;\nenum BM_GETIMAGE = 246;\nenum BM_GETSTATE = 242;\nenum BM_SETCHECK = 241;\nenum BM_SETIMAGE = 247;\nstatic if (_WIN32_WINNT >= 0x600) {\n    enum BM_SETDONTCLICK = 248;\n}\nenum BM_SETSTATE = 243;\nenum BM_SETSTYLE = 244;\nenum BN_CLICKED = 0;\nenum BN_DBLCLK = 5;\nenum BN_DISABLE = 4;\nenum BN_DOUBLECLICKED = 5;\nenum BN_HILITE = 2;\nenum BN_KILLFOCUS = 7;\nenum BN_PAINT = 1;\nenum BN_PUSHED = 2;\nenum BN_SETFOCUS = 6;\nenum BN_UNHILITE = 3;\nenum BN_UNPUSHED = 3;\nenum CB_ADDSTRING = 323;\nenum CB_DELETESTRING = 324;\nenum CB_DIR = 325;\nenum CB_FINDSTRING = 332;\nenum CB_FINDSTRINGEXACT = 344;\nenum CB_GETCOUNT = 326;\nenum CB_GETCURSEL = 327;\nenum CB_GETDROPPEDCONTROLRECT = 338;\nenum CB_GETDROPPEDSTATE = 343;\nenum CB_GETDROPPEDWIDTH = 351;\nenum CB_GETEDITSEL = 320;\nenum CB_GETEXTENDEDUI = 342;\nenum CB_GETHORIZONTALEXTENT = 349;\nenum CB_GETITEMDATA = 336;\nenum CB_GETITEMHEIGHT = 340;\nenum CB_GETLBTEXT = 328;\nenum CB_GETLBTEXTLEN = 329;\nenum CB_GETLOCALE = 346;\nenum CB_GETTOPINDEX = 347;\nenum CB_INITSTORAGE = 353;\nenum CB_INSERTSTRING = 330;\nenum CB_LIMITTEXT = 321;\nenum CB_RESETCONTENT = 331;\nenum CB_SELECTSTRING = 333;\nenum CB_SETCURSEL = 334;\nenum CB_SETDROPPEDWIDTH = 352;\nenum CB_SETEDITSEL = 322;\nenum CB_SETEXTENDEDUI = 341;\nenum CB_SETHORIZONTALEXTENT = 350;\nenum CB_SETITEMDATA = 337;\nenum CB_SETITEMHEIGHT = 339;\nenum CB_SETLOCALE = 345;\nenum CB_SETTOPINDEX = 348;\nenum CB_SHOWDROPDOWN = 335;\n\nstatic if (_WIN32_WINNT >= 0x501) {\nenum CB_GETCOMBOBOXINFO = 356;\n}\n\nenum CBN_CLOSEUP = 8;\nenum CBN_DBLCLK = 2;\nenum CBN_DROPDOWN = 7;\nenum CBN_EDITCHANGE = 5;\nenum CBN_EDITUPDATE = 6;\nenum CBN_ERRSPACE = (-1);\nenum CBN_KILLFOCUS = 4;\nenum CBN_SELCHANGE = 1;\nenum CBN_SELENDCANCEL = 10;\nenum CBN_SELENDOK = 9;\nenum CBN_SETFOCUS = 3;\n\nenum EM_CANUNDO = 198;\nenum EM_CHARFROMPOS = 215;\nenum EM_EMPTYUNDOBUFFER = 205;\nenum EM_FMTLINES = 200;\nenum EM_GETFIRSTVISIBLELINE = 206;\nenum EM_GETHANDLE = 189;\nenum EM_GETLIMITTEXT = 213;\nenum EM_GETLINE = 196;\nenum EM_GETLINECOUNT = 186;\nenum EM_GETMARGINS = 212;\nenum EM_GETMODIFY = 184;\nenum EM_GETPASSWORDCHAR = 210;\nenum EM_GETRECT = 178;\nenum EM_GETSEL = 176;\nenum EM_GETTHUMB = 190;\nenum EM_GETWORDBREAKPROC = 209;\nenum EM_LIMITTEXT = 197;\nenum EM_LINEFROMCHAR = 201;\nenum EM_LINEINDEX = 187;\nenum EM_LINELENGTH = 193;\nenum EM_LINESCROLL = 182;\nenum EM_POSFROMCHAR = 214;\nenum EM_REPLACESEL = 194;\nenum EM_SCROLL = 181;\nenum EM_SCROLLCARET = 183;\nenum EM_SETHANDLE = 188;\nenum EM_SETLIMITTEXT = 197;\nenum EM_SETMARGINS = 211;\nenum EM_SETMODIFY = 185;\nenum EM_SETPASSWORDCHAR = 204;\nenum EM_SETREADONLY = 207;\nenum EM_SETRECT = 179;\nenum EM_SETRECTNP = 180;\nenum EM_SETSEL = 177;\nenum EM_SETTABSTOPS = 203;\nenum EM_SETWORDBREAKPROC = 208;\nenum EM_UNDO = 199;\n\nenum EM_SETIMESTATUS = 216;\nenum EM_GETIMESTATUS = 217;\n\nenum EN_CHANGE = 768;\nenum EN_ERRSPACE = 1280;\nenum EN_HSCROLL = 1537;\nenum EN_KILLFOCUS = 512;\nenum EN_MAXTEXT = 1281;\nenum EN_SETFOCUS = 256;\nenum EN_UPDATE = 1024;\nenum EN_VSCROLL = 1538;\n\nenum LB_ADDFILE = 406;\nenum LB_ADDSTRING = 384;\nenum LB_DELETESTRING = 386;\nenum LB_DIR = 397;\nenum LB_FINDSTRING = 399;\nenum LB_FINDSTRINGEXACT = 418;\nenum LB_GETANCHORINDEX = 413;\nenum LB_GETCARETINDEX = 415;\nenum LB_GETCOUNT = 395;\nenum LB_GETCURSEL = 392;\nenum LB_GETHORIZONTALEXTENT = 403;\nenum LB_GETITEMDATA = 409;\nenum LB_GETITEMHEIGHT = 417;\nenum LB_GETITEMRECT = 408;\nenum LB_GETLOCALE = 422;\nenum LB_GETSEL = 391;\nenum LB_GETSELCOUNT = 400;\nenum LB_GETSELITEMS = 401;\nenum LB_GETTEXT = 393;\nenum LB_GETTEXTLEN = 394;\nenum LB_GETTOPINDEX = 398;\nenum LB_INITSTORAGE = 424;\nenum LB_INSERTSTRING = 385;\nenum LB_ITEMFROMPOINT = 425;\nenum LB_RESETCONTENT = 388;\nenum LB_SELECTSTRING = 396;\nenum LB_SELITEMRANGE = 411;\nenum LB_SELITEMRANGEEX = 387;\nenum LB_SETANCHORINDEX = 412;\nenum LB_SETCARETINDEX = 414;\nenum LB_SETCOLUMNWIDTH = 405;\nenum LB_SETCOUNT = 423;\nenum LB_SETCURSEL = 390;\nenum LB_SETHORIZONTALEXTENT = 404;\nenum LB_SETITEMDATA = 410;\nenum LB_SETITEMHEIGHT = 416;\nenum LB_SETLOCALE = 421;\nenum LB_SETSEL = 389;\nenum LB_SETTABSTOPS = 402;\nenum LB_SETTOPINDEX = 407;\nstatic if (_WIN32_WINNT >= 0x501) {\nenum LB_GETLISTBOXINFO = 434;\n}\n\nenum LBN_DBLCLK = 2;\nenum LBN_ERRSPACE = -2;\nenum LBN_KILLFOCUS = 5;\nenum LBN_SELCANCEL = 3;\nenum LBN_SELCHANGE = 1;\nenum LBN_SETFOCUS = 4;\n\nenum SBM_ENABLE_ARROWS = 228;\nenum SBM_GETPOS = 225;\nenum SBM_GETRANGE = 227;\nenum SBM_GETSCROLLINFO = 234;\nenum SBM_SETPOS = 224;\nenum SBM_SETRANGE = 226;\nenum SBM_SETRANGEREDRAW = 230;\nenum SBM_SETSCROLLINFO = 233;\nstatic if (_WIN32_WINNT >= 0x501) {\nenum SBM_GETSCROLLBARINFO = 235;\n}\n\nenum STM_GETICON = 369;\nenum STM_GETIMAGE = 371;\nenum STM_SETICON = 368;\nenum STM_SETIMAGE = 370;\nenum STN_CLICKED = 0;\nenum STN_DBLCLK = 1;\nenum STN_DISABLE = 3;\nenum STN_ENABLE = 2;\nenum STM_MSGMAX = 372;\n\nenum DM_GETDEFID   = WM_USER;\nenum DM_SETDEFID   = WM_USER+1;\nenum DM_REPOSITION = WM_USER+2;\n\nenum PSM_PAGEINFO  = WM_USER+100;\nenum PSM_SHEETINFO = WM_USER+101;\n\nenum PSI_SETACTIVE = 1;\nenum PSI_KILLACTIVE = 2;\nenum PSI_APPLY = 3;\nenum PSI_RESET = 4;\nenum PSI_HASHELP = 5;\nenum PSI_HELP = 6;\nenum PSI_CHANGED = 1;\nenum PSI_GUISTART = 2;\nenum PSI_REBOOT = 3;\nenum PSI_GETSIBLINGS = 4;\n\nenum DCX_WINDOW = 1;\nenum DCX_CACHE = 2;\nenum DCX_PARENTCLIP = 32;\nenum DCX_CLIPSIBLINGS = 16;\nenum DCX_CLIPCHILDREN = 8;\nenum DCX_NORESETATTRS = 4;\nenum DCX_INTERSECTUPDATE = 0x200;\nenum DCX_LOCKWINDOWUPDATE = 0x400;\nenum DCX_EXCLUDERGN = 64;\nenum DCX_INTERSECTRGN = 128;\nenum DCX_EXCLUDEUPDATE = 256;\nenum DCX_VALIDATE = 0x200000;\n\nenum GMDI_GOINTOPOPUPS = 2;\nenum GMDI_USEDISABLED = 1;\nenum FKF_AVAILABLE = 2;\nenum FKF_CLICKON = 64;\nenum FKF_FILTERKEYSON = 1;\nenum FKF_HOTKEYACTIVE = 4;\nenum FKF_HOTKEYSOUND = 16;\nenum FKF_CONFIRMHOTKEY = 8;\nenum FKF_INDICATOR = 32;\nenum HCF_HIGHCONTRASTON = 1;\nenum HCF_AVAILABLE = 2;\nenum HCF_HOTKEYACTIVE = 4;\nenum HCF_CONFIRMHOTKEY = 8;\nenum HCF_HOTKEYSOUND = 16;\nenum HCF_INDICATOR = 32;\nenum HCF_HOTKEYAVAILABLE = 64;\nenum MKF_AVAILABLE = 2;\nenum MKF_CONFIRMHOTKEY = 8;\nenum MKF_HOTKEYACTIVE = 4;\nenum MKF_HOTKEYSOUND = 16;\nenum MKF_INDICATOR = 32;\nenum MKF_MOUSEKEYSON = 1;\nenum MKF_MODIFIERS = 64;\nenum MKF_REPLACENUMBERS = 128;\nenum SERKF_ACTIVE = 8;  // May be obsolete. Not in recent MS docs.\nenum SERKF_AVAILABLE = 2;\nenum SERKF_INDICATOR = 4;\nenum SERKF_SERIALKEYSON = 1;\nenum SSF_AVAILABLE = 2;\nenum SSF_SOUNDSENTRYON = 1;\nenum SSTF_BORDER = 2;\nenum SSTF_CHARS = 1;\nenum SSTF_DISPLAY = 3;\nenum SSTF_NONE = 0;\nenum SSGF_DISPLAY = 3;\nenum SSGF_NONE = 0;\nenum SSWF_CUSTOM = 4;\nenum SSWF_DISPLAY = 3;\nenum SSWF_NONE = 0;\nenum SSWF_TITLE = 1;\nenum SSWF_WINDOW = 2;\nenum SKF_AUDIBLEFEEDBACK = 64;\nenum SKF_AVAILABLE = 2;\nenum SKF_CONFIRMHOTKEY = 8;\nenum SKF_HOTKEYACTIVE = 4;\nenum SKF_HOTKEYSOUND = 16;\nenum SKF_INDICATOR = 32;\nenum SKF_STICKYKEYSON = 1;\nenum SKF_TRISTATE = 128;\nenum SKF_TWOKEYSOFF = 256;\nenum TKF_AVAILABLE = 2;\nenum TKF_CONFIRMHOTKEY = 8;\nenum TKF_HOTKEYACTIVE = 4;\nenum TKF_HOTKEYSOUND = 16;\nenum TKF_TOGGLEKEYSON = 1;\nenum MDITILE_SKIPDISABLED = 2;\nenum MDITILE_HORIZONTAL = 1;\nenum MDITILE_VERTICAL = 0;\n\nenum {\n    VK_LBUTTON = 0x01,\n    VK_RBUTTON = 0x02,\n    VK_CANCEL = 0x03,\n    VK_MBUTTON = 0x04,\n    VK_XBUTTON1 = 0x05,\n    VK_XBUTTON2 = 0x06,\n    VK_BACK = 0x08,\n    VK_TAB = 0x09,\n    VK_CLEAR = 0x0C,\n    VK_RETURN = 0x0D,\n    VK_SHIFT = 0x10,\n    VK_CONTROL = 0x11,\n    VK_MENU = 0x12,\n    VK_PAUSE = 0x13,\n    VK_CAPITAL = 0x14,\n    VK_KANA = 0x15,\n    VK_HANGEUL = 0x15,\n    VK_HANGUL = 0x15,\n    VK_JUNJA = 0x17,\n    VK_FINAL = 0x18,\n    VK_HANJA = 0x19,\n    VK_KANJI = 0x19,\n    VK_ESCAPE = 0x1B,\n    VK_CONVERT = 0x1C,\n    VK_NONCONVERT = 0x1D,\n    VK_ACCEPT = 0x1E,\n    VK_MODECHANGE = 0x1F,\n    VK_SPACE = 0x20,\n    VK_PRIOR = 0x21,\n    VK_NEXT = 0x22,\n    VK_END = 0x23,\n    VK_HOME = 0x24,\n    VK_LEFT = 0x25,\n    VK_UP = 0x26,\n    VK_RIGHT = 0x27,\n    VK_DOWN = 0x28,\n    VK_SELECT = 0x29,\n    VK_PRINT = 0x2A,\n    VK_EXECUTE = 0x2B,\n    VK_SNAPSHOT = 0x2C,\n    VK_INSERT = 0x2D,\n    VK_DELETE = 0x2E,\n    VK_HELP = 0x2F,\n    VK_LWIN = 0x5B,\n    VK_RWIN = 0x5C,\n    VK_APPS = 0x5D,\n    VK_SLEEP = 0x5F,\n    VK_NUMPAD0 = 0x60,\n    VK_NUMPAD1 = 0x61,\n    VK_NUMPAD2 = 0x62,\n    VK_NUMPAD3 = 0x63,\n    VK_NUMPAD4 = 0x64,\n    VK_NUMPAD5 = 0x65,\n    VK_NUMPAD6 = 0x66,\n    VK_NUMPAD7 = 0x67,\n    VK_NUMPAD8 = 0x68,\n    VK_NUMPAD9 = 0x69,\n    VK_MULTIPLY = 0x6A,\n    VK_ADD = 0x6B,\n    VK_SEPARATOR = 0x6C,\n    VK_SUBTRACT = 0x6D,\n    VK_DECIMAL = 0x6E,\n    VK_DIVIDE = 0x6F,\n    VK_F1 = 0x70,\n    VK_F2 = 0x71,\n    VK_F3 = 0x72,\n    VK_F4 = 0x73,\n    VK_F5 = 0x74,\n    VK_F6 = 0x75,\n    VK_F7 = 0x76,\n    VK_F8 = 0x77,\n    VK_F9 = 0x78,\n    VK_F10 = 0x79,\n    VK_F11 = 0x7A,\n    VK_F12 = 0x7B,\n    VK_F13 = 0x7C,\n    VK_F14 = 0x7D,\n    VK_F15 = 0x7E,\n    VK_F16 = 0x7F,\n    VK_F17 = 0x80,\n    VK_F18 = 0x81,\n    VK_F19 = 0x82,\n    VK_F20 = 0x83,\n    VK_F21 = 0x84,\n    VK_F22 = 0x85,\n    VK_F23 = 0x86,\n    VK_F24 = 0x87,\n    VK_NUMLOCK = 0x90,\n    VK_SCROLL = 0x91,\n    VK_LSHIFT = 0xA0,\n    VK_RSHIFT = 0xA1,\n    VK_LCONTROL = 0xA2,\n    VK_RCONTROL = 0xA3,\n    VK_LMENU = 0xA4,\n    VK_RMENU = 0xA5,\n    VK_BROWSER_BACK = 0xA6,\n    VK_BROWSER_FORWARD = 0xA7,\n    VK_BROWSER_REFRESH = 0xA8,\n    VK_BROWSER_STOP = 0xA9,\n    VK_BROWSER_SEARCH = 0xAA,\n    VK_BROWSER_FAVORITES = 0xAB,\n    VK_BROWSER_HOME = 0xAC,\n    VK_VOLUME_MUTE = 0xAD,\n    VK_VOLUME_DOWN = 0xAE,\n    VK_VOLUME_UP = 0xAF,\n    VK_MEDIA_NEXT_TRACK = 0xB0,\n    VK_MEDIA_PREV_TRACK = 0xB1,\n    VK_MEDIA_STOP = 0xB2,\n    VK_MEDIA_PLAY_PAUSE = 0xB3,\n    VK_LAUNCH_MAIL = 0xB4,\n    VK_LAUNCH_MEDIA_SELECT = 0xB5,\n    VK_LAUNCH_APP1 = 0xB6,\n    VK_LAUNCH_APP2 = 0xB7,\n    VK_OEM_1 = 0xBA,\n    VK_OEM_PLUS = 0xBB,\n    VK_OEM_COMMA = 0xBC,\n    VK_OEM_MINUS = 0xBD,\n    VK_OEM_PERIOD = 0xBE,\n    VK_OEM_2 = 0xBF,\n    VK_OEM_3 = 0xC0,\n    VK_OEM_4 = 0xDB,\n    VK_OEM_5 = 0xDC,\n    VK_OEM_6 = 0xDD,\n    VK_OEM_7 = 0xDE,\n    VK_OEM_8 = 0xDF,\n    VK_OEM_102 = 0xE2,\n    VK_PROCESSKEY = 0xE5,\n    VK_PACKET = 0xE7,\n    VK_ATTN = 0xF6,\n    VK_CRSEL = 0xF7,\n    VK_EXSEL = 0xF8,\n    VK_EREOF = 0xF9,\n    VK_PLAY = 0xFA,\n    VK_ZOOM = 0xFB,\n    VK_NONAME = 0xFC,\n    VK_PA1 = 0xFD,\n    VK_OEM_CLEAR = 0xFE,\n}\n\nenum TME_HOVER = 1;\nenum TME_LEAVE = 2;\nenum TME_QUERY = 0x40000000;\nenum TME_CANCEL = 0x80000000;\n\nenum HOVER_DEFAULT = 0xFFFFFFFF;\n\nenum MK_LBUTTON = 1;\nenum MK_RBUTTON = 2;\nenum MK_SHIFT = 4;\nenum MK_CONTROL = 8;\nenum MK_MBUTTON = 16;\nenum MK_XBUTTON1 = 32;\nenum MK_XBUTTON2 = 64;\n\nenum {\n    TPM_RECURSE      = 0x0001,\n    TPM_LEFTBUTTON   = 0,\n    TPM_RIGHTBUTTON  = 0x0002,\n    TPM_LEFTALIGN    = 0,\n    TPM_CENTERALIGN  = 0x0004,\n    TPM_RIGHTALIGN   = 0x0008,\n    TPM_TOPALIGN     = 0,\n    TPM_VCENTERALIGN = 0x0010,\n    TPM_BOTTOMALIGN  = 0x0020,\n    TPM_HORIZONTAL   = 0,\n    TPM_VERTICAL     = 0x0040,\n    TPM_NONOTIFY     = 0x0080,\n    TPM_RETURNCMD    = 0x0100\n}\n\nenum HELP_COMMAND = 0x102;\nenum HELP_CONTENTS = 3;\nenum HELP_CONTEXT = 1;\nenum HELP_CONTEXTPOPUP = 8;\nenum HELP_FORCEFILE = 9;\nenum HELP_HELPONHELP = 4;\nenum HELP_INDEX = 3;\nenum HELP_KEY = 0x101;\nenum HELP_MULTIKEY = 0x201;\nenum HELP_PARTIALKEY = 0x105;\nenum HELP_QUIT = 2;\nenum HELP_SETCONTENTS = 5;\nenum HELP_SETINDEX = 5;\nenum HELP_SETWINPOS = 0x203;\nenum HELP_CONTEXTMENU = 0xa;\nenum HELP_FINDER = 0xb;\nenum HELP_WM_HELP = 0xc;\nenum HELP_TCARD = 0x8000;\nenum HELP_TCARD_DATA = 16;\nenum HELP_TCARD_OTHER_CALLER = 0x11;\n\nenum IDH_NO_HELP = 28440;\nenum IDH_MISSING_CONTEXT = 28441;\nenum IDH_GENERIC_HELP_BUTTON = 28442;\nenum IDH_OK = 28443;\nenum IDH_CANCEL = 28444;\nenum IDH_HELP = 28445;\n\nenum LB_CTLCODE = 0;\nenum LB_OKAY = 0;\nenum LB_ERR = -1;\nenum LB_ERRSPACE = -2;\n\nenum CB_OKAY = 0;\nenum CB_ERR = -1;\nenum CB_ERRSPACE = -2;\n\nenum HIDE_WINDOW = 0;\n\nenum SHOW_OPENWINDOW = 1;\nenum SHOW_ICONWINDOW = 2;\nenum SHOW_FULLSCREEN = 3;\nenum SHOW_OPENNOACTIVATE = 4;\n\nenum KF_EXTENDED = 256;\nenum KF_DLGMODE = 2048;\nenum KF_MENUMODE = 4096;\nenum KF_ALTDOWN = 8192;\nenum KF_REPEAT = 16384;\nenum KF_UP = 32768;\n\nenum WSF_VISIBLE = 1;\n\nenum PWR_OK = 1;\nenum PWR_FAIL = -1;\nenum PWR_SUSPENDREQUEST = 1;\nenum PWR_SUSPENDRESUME = 2;\nenum PWR_CRITICALRESUME = 3;\n\nenum NFR_ANSI = 1;\nenum NFR_UNICODE = 2;\nenum NF_QUERY = 3;\nenum NF_REQUERY = 4;\n\nenum MENULOOP_WINDOW = 0;\nenum MENULOOP_POPUP = 1;\n\nenum WMSZ_LEFT = 1;\nenum WMSZ_RIGHT = 2;\nenum WMSZ_TOP = 3;\nenum WMSZ_TOPLEFT = 4;\nenum WMSZ_TOPRIGHT = 5;\nenum WMSZ_BOTTOM = 6;\nenum WMSZ_BOTTOMLEFT = 7;\nenum WMSZ_BOTTOMRIGHT = 8;\n\nenum HTERROR = -2;\nenum HTTRANSPARENT = -1;\nenum HTNOWHERE = 0;\nenum HTCLIENT = 1;\nenum HTCAPTION = 2;\nenum HTSYSMENU = 3;\nenum HTGROWBOX = 4;\nenum HTSIZE = 4;\nenum HTMENU = 5;\nenum HTHSCROLL = 6;\nenum HTVSCROLL = 7;\nenum HTMINBUTTON = 8;\nenum HTMAXBUTTON = 9;\nenum HTREDUCE = 8;\nenum HTZOOM = 9;\nenum HTLEFT = 10;\nenum HTSIZEFIRST = 10;\nenum HTRIGHT = 11;\nenum HTTOP = 12;\nenum HTTOPLEFT = 13;\nenum HTTOPRIGHT = 14;\nenum HTBOTTOM = 15;\nenum HTBOTTOMLEFT = 16;\nenum HTBOTTOMRIGHT = 17;\nenum HTSIZELAST = 17;\nenum HTBORDER = 18;\nenum HTOBJECT = 19;\nenum HTCLOSE = 20;\nenum HTHELP = 21;\n\nenum MA_ACTIVATE = 1;\nenum MA_ACTIVATEANDEAT = 2;\nenum MA_NOACTIVATE = 3;\nenum MA_NOACTIVATEANDEAT = 4;\n\nenum SIZE_RESTORED = 0;\nenum SIZE_MINIMIZED = 1;\nenum SIZE_MAXIMIZED = 2;\nenum SIZE_MAXSHOW = 3;\nenum SIZE_MAXHIDE = 4;\n\nenum SIZENORMAL = 0;\nenum SIZEICONIC = 1;\nenum SIZEFULLSCREEN = 2;\nenum SIZEZOOMSHOW = 3;\nenum SIZEZOOMHIDE = 4;\n\nenum WVR_ALIGNTOP = 16;\nenum WVR_ALIGNLEFT = 32;\nenum WVR_ALIGNBOTTOM = 64;\nenum WVR_ALIGNRIGHT = 128;\nenum WVR_HREDRAW = 256;\nenum WVR_VREDRAW = 512;\nenum WVR_REDRAW = (WVR_HREDRAW|WVR_VREDRAW);\nenum WVR_VALIDRECTS = 1024;\n\nenum PRF_CHECKVISIBLE = 1;\nenum PRF_NONCLIENT = 2;\nenum PRF_CLIENT = 4;\nenum PRF_ERASEBKGND = 8;\nenum PRF_CHILDREN = 16;\nenum PRF_OWNED = 32;\n\nenum IDANI_OPEN = 1;\nenum IDANI_CLOSE = 2;\nenum IDANI_CAPTION = 3;\n\nenum WPF_RESTORETOMAXIMIZED = 2;\nenum WPF_SETMINPOSITION = 1;\n\nenum ODT_MENU = 1;\nenum ODT_LISTBOX = 2;\nenum ODT_COMBOBOX = 3;\nenum ODT_BUTTON = 4;\nenum ODT_STATIC = 5;\nenum ODA_DRAWENTIRE = 1;\nenum ODA_SELECT = 2;\nenum ODA_FOCUS = 4;\nenum ODS_SELECTED = 1;\nenum ODS_GRAYED = 2;\nenum ODS_DISABLED = 4;\nenum ODS_CHECKED = 8;\nenum ODS_FOCUS = 16;\nenum ODS_DEFAULT = 32;\nenum ODS_COMBOBOXEDIT = 4096;\n\nenum IDHOT_SNAPWINDOW = -1;\nenum IDHOT_SNAPDESKTOP = -2;\n\nenum DBWF_LPARAMPOINTER = 0x8000;\nenum DLGWINDOWEXTRA = 30;\nenum MNC_IGNORE = 0;\nenum MNC_CLOSE = 1;\nenum MNC_EXECUTE = 2;\nenum MNC_SELECT = 3;\nenum DOF_EXECUTABLE = 0x8001;\nenum DOF_DOCUMENT = 0x8002;\nenum DOF_DIRECTORY = 0x8003;\nenum DOF_MULTIPLE = 0x8004;\nenum DOF_PROGMAN = 1;\nenum DOF_SHELLDATA = 2;\nenum DO_DROPFILE = 0x454C4946;\nenum DO_PRINTFILE = 0x544E5250;\n\nenum SC_SIZE = 0xF000;\nenum SC_MOVE = 0xF010;\nenum SC_MINIMIZE = 0xF020;\nenum SC_ICON = 0xf020;\nenum SC_MAXIMIZE = 0xF030;\nenum SC_ZOOM = 0xF030;\nenum SC_NEXTWINDOW = 0xF040;\nenum SC_PREVWINDOW = 0xF050;\nenum SC_CLOSE = 0xF060;\nenum SC_VSCROLL = 0xF070;\nenum SC_HSCROLL = 0xF080;\nenum SC_MOUSEMENU = 0xF090;\nenum SC_KEYMENU = 0xF100;\nenum SC_ARRANGE = 0xF110;\nenum SC_RESTORE = 0xF120;\nenum SC_TASKLIST = 0xF130;\nenum SC_SCREENSAVE = 0xF140;\nenum SC_HOTKEY = 0xF150;\nenum SC_DEFAULT = 0xF160;\nenum SC_MONITORPOWER = 0xF170;\nenum SC_CONTEXTHELP = 0xF180;\nenum SC_SEPARATOR = 0xF00F;\n\nenum EC_LEFTMARGIN = 1;\nenum EC_RIGHTMARGIN = 2;\nenum EC_USEFONTINFO = 0xffff;\n\nenum DC_HASDEFID = 0x534B;\n\nenum DLGC_WANTARROWS = 1;\nenum DLGC_WANTTAB = 2;\nenum DLGC_WANTALLKEYS = 4;\nenum DLGC_WANTMESSAGE = 4;\nenum DLGC_HASSETSEL = 8;\nenum DLGC_DEFPUSHBUTTON = 16;\nenum DLGC_UNDEFPUSHBUTTON = 32;\nenum DLGC_RADIOBUTTON = 64;\nenum DLGC_WANTCHARS = 128;\nenum DLGC_STATIC = 256;\nenum DLGC_BUTTON = 0x2000;\n\nenum WA_INACTIVE = 0;\nenum WA_ACTIVE = 1;\nenum WA_CLICKACTIVE = 2;\n\nenum ICON_SMALL = 0;\nenum ICON_BIG = 1;\nstatic if (_WIN32_WINNT >= 0x501) {\nenum ICON_SMALL2 = 2;\n}\n\nenum HBITMAP\n    HBMMENU_CALLBACK = cast(HBITMAP)-1,\n    HBMMENU_SYSTEM = cast(HBITMAP)1,\n    HBMMENU_MBAR_RESTORE = cast(HBITMAP)2,\n    HBMMENU_MBAR_MINIMIZE = cast(HBITMAP)3,\n    HBMMENU_MBAR_CLOSE = cast(HBITMAP)5,\n    HBMMENU_MBAR_CLOSE_D = cast(HBITMAP)6,\n    HBMMENU_MBAR_MINIMIZE_D = cast(HBITMAP)7,\n    HBMMENU_POPUP_CLOSE = cast(HBITMAP)8,\n    HBMMENU_POPUP_RESTORE = cast(HBITMAP)9,\n    HBMMENU_POPUP_MAXIMIZE = cast(HBITMAP)10,\n    HBMMENU_POPUP_MINIMIZE = cast(HBITMAP)11;\n\nenum MOD_ALT = 1;\nenum MOD_CONTROL = 2;\nenum MOD_SHIFT = 4;\nenum MOD_WIN = 8;\nenum MOD_IGNORE_ALL_MODIFIER = 1024;\nenum MOD_ON_KEYUP = 2048;\nenum MOD_RIGHT = 16384;\nenum MOD_LEFT = 32768;\n\nenum LLKHF_EXTENDED = (KF_EXTENDED >> 8);\nenum LLKHF_INJECTED = 0x00000010;\nenum LLKHF_ALTDOWN = (KF_ALTDOWN >> 8);\nenum LLKHF_UP = (KF_UP >> 8);\n\nenum CURSOR_SHOWING = 0x00000001;\nenum WS_ACTIVECAPTION = 0x00000001;\nenum ENDSESSION_LOGOFF = 0x80000000;\n\nenum GA_PARENT    = 1;\nenum GA_ROOT      = 2;\nenum GA_ROOTOWNER = 3;\n\nenum {\n    MAPVK_VK_TO_VSC,\n    MAPVK_VSC_TO_VK,\n    MAPVK_VK_TO_CHAR,\n    MAPVK_VSC_TO_VK_EX,\n    MAPVK_VK_TO_VSC_EX // = 4\n}\n\nenum {\n    INPUT_MOUSE,\n    INPUT_KEYBOARD,\n    INPUT_HARDWARE // = 2\n}\n\n// Callbacks\n// ---------\nextern (Windows) nothrow {\n    alias INT_PTR function(HWND, UINT, WPARAM, LPARAM)   DLGPROC;\n    alias void function(HWND, UINT, UINT_PTR, DWORD)     TIMERPROC;\n    alias BOOL function(HDC, LPARAM, int)                GRAYSTRINGPROC;\n    alias LRESULT function(int, WPARAM, LPARAM)          HOOKPROC;\n    alias BOOL function(HWND, LPCSTR, HANDLE)            PROPENUMPROCA;\n    alias BOOL function(HWND, LPCWSTR, HANDLE)           PROPENUMPROCW;\n    alias BOOL function(HWND, LPSTR, HANDLE, ULONG_PTR)  PROPENUMPROCEXA;\n    alias BOOL function(HWND, LPWSTR, HANDLE, ULONG_PTR) PROPENUMPROCEXW;\n    alias int function(LPSTR, int, int, int)             EDITWORDBREAKPROCA;\n    alias int function(LPWSTR, int, int, int)            EDITWORDBREAKPROCW;\n    alias LRESULT function(HWND, UINT, WPARAM, LPARAM)   WNDPROC;\n    alias BOOL function(HDC, LPARAM, WPARAM, int, int)   DRAWSTATEPROC;\n    alias BOOL function(HWND, LPARAM)                    WNDENUMPROC;\n    alias BOOL function(HWND, LPARAM)                    ENUMWINDOWSPROC;\n    alias void function(LPHELPINFO)                      MSGBOXCALLBACK;\n\n    alias BOOL function(HMONITOR, HDC, LPRECT, LPARAM)   MONITORENUMPROC;\n    alias BOOL function(LPSTR, LPARAM)                   NAMEENUMPROCA;\n    alias BOOL function(LPWSTR, LPARAM)                  NAMEENUMPROCW;\n    alias void function(HWND, UINT, ULONG_PTR, LRESULT)  SENDASYNCPROC;\n\n    alias NAMEENUMPROCA DESKTOPENUMPROCA;\n    alias NAMEENUMPROCW DESKTOPENUMPROCW;\n    alias NAMEENUMPROCA WINSTAENUMPROCA;\n    alias NAMEENUMPROCW WINSTAENUMPROCW;\n}\n\nmixin DECLARE_HANDLE!(\"HDWP\");\nmixin DECLARE_HANDLE!(\"HDEVNOTIFY\");\n\nstruct MENUGETOBJECTINFO {\n    DWORD dwFlags;\n    UINT  uPos;\n    HMENU hmenu;\n    PVOID riid;\n    PVOID pvObj;\n}\nalias MENUGETOBJECTINFO* PMENUGETOBJECTINFO;\n\nstruct ACCEL {\n    BYTE fVirt;\n    WORD key;\n    WORD cmd;\n}\nalias ACCEL* LPACCEL;\n\nstruct ACCESSTIMEOUT {\n    UINT  cbSize = ACCESSTIMEOUT.sizeof;\n    DWORD dwFlags;\n    DWORD iTimeOutMSec;\n}\nalias ACCESSTIMEOUT* LPACCESSTIMEOUT;\n\nstruct ANIMATIONINFO {\n    UINT cbSize = ANIMATIONINFO.sizeof;\n    int  iMinAnimate;\n}\nalias ANIMATIONINFO* LPANIMATIONINFO;\n\nstruct CREATESTRUCTA {\n    LPVOID    lpCreateParams;\n    HINSTANCE hInstance;\n    HMENU     hMenu;\n    HWND      hwndParent;\n    int       cy;\n    int       cx;\n    int       y;\n    int       x;\n    LONG      style;\n    LPCSTR    lpszName;\n    LPCSTR    lpszClass;\n    DWORD     dwExStyle;\n}\nalias CREATESTRUCTA* LPCREATESTRUCTA;\n\nstruct CREATESTRUCTW {\n    LPVOID    lpCreateParams;\n    HINSTANCE hInstance;\n    HMENU     hMenu;\n    HWND      hwndParent;\n    int       cy;\n    int       cx;\n    int       y;\n    int       x;\n    LONG      style;\n    LPCWSTR   lpszName;\n    LPCWSTR   lpszClass;\n    DWORD     dwExStyle;\n}\nalias CREATESTRUCTW* LPCREATESTRUCTW;\n\nstruct CBT_CREATEWNDA {\n    LPCREATESTRUCTA lpcs;\n    HWND            hwndInsertAfter;\n}\nalias CBT_CREATEWNDA* LPCBT_CREATEWNDA;\n\nstruct CBT_CREATEWNDW {\n    LPCREATESTRUCTW lpcs;\n    HWND            hwndInsertAfter;\n}\nalias CBT_CREATEWNDW* LPCBT_CREATEWNDW;\n\nstruct CBTACTIVATESTRUCT {\n    BOOL fMouse;\n    HWND hWndActive;\n}\nalias CBTACTIVATESTRUCT* LPCBTACTIVATESTRUCT;\n\nstatic if (_WIN32_WINNT >= 0x501) {\n\nstruct WTSSESSION_NOTIFICATION\n{\n    DWORD cbSize;\n    DWORD dwSessionId;\n}\nalias WTSSESSION_NOTIFICATION* PWTSSESSION_NOTIFICATION;\n\n}\n\nstruct CLIENTCREATESTRUCT {\n    HANDLE hWindowMenu;\n    UINT   idFirstChild;\n}\nalias CLIENTCREATESTRUCT* LPCLIENTCREATESTRUCT;\n\nstruct COMPAREITEMSTRUCT {\n    UINT  CtlType;\n    UINT  CtlID;\n    HWND  hwndItem;\n    UINT  itemID1;\n    ULONG_PTR itemData1;\n    UINT  itemID2;\n    ULONG_PTR itemData2;\n    DWORD dwLocaleId;\n}\nalias COMPAREITEMSTRUCT* LPCOMPAREITEMSTRUCT;\n\nstruct COPYDATASTRUCT {\n    ULONG_PTR dwData;\n    DWORD cbData;\n    PVOID lpData;\n}\nalias COPYDATASTRUCT* PCOPYDATASTRUCT;\n\nstruct CURSORSHAPE {\n    int xHotSpot;\n    int yHotSpot;\n    int cx;\n    int cy;\n    int cbWidth;\n    BYTE Planes;\n    BYTE BitsPixel;\n}\nalias CURSORSHAPE* LPCURSORSHAPE;\n\nstruct CWPRETSTRUCT {\n    LRESULT lResult;\n    LPARAM lParam;\n    WPARAM wParam;\n    DWORD message;\n    HWND hwnd;\n}\n\nstruct CWPSTRUCT {\n    LPARAM lParam;\n    WPARAM wParam;\n    UINT message;\n    HWND hwnd;\n}\nalias CWPSTRUCT* PCWPSTRUCT;\n\nstruct DEBUGHOOKINFO {\n    DWORD idThread;\n    DWORD idThreadInstaller;\n    LPARAM lParam;\n    WPARAM wParam;\n    int code;\n}\nalias DEBUGHOOKINFO* PDEBUGHOOKINFO, LPDEBUGHOOKINFO;\n\nstruct DELETEITEMSTRUCT {\n    UINT CtlType;\n    UINT CtlID;\n    UINT itemID;\n    HWND hwndItem;\n    ULONG_PTR itemData;\n}\nalias DELETEITEMSTRUCT* PDELETEITEMSTRUCT, LPDELETEITEMSTRUCT;\n\nalign(2):\nstruct DLGITEMTEMPLATE {\n    DWORD style;\n    DWORD dwExtendedStyle;\n    short x;\n    short y;\n    short cx;\n    short cy;\n    WORD id;\n}\nalias DLGITEMTEMPLATE* LPDLGITEMTEMPLATE;\n\nstruct DLGTEMPLATE {\n    DWORD style;\n    DWORD dwExtendedStyle;\n    WORD  cdit;\n    short x;\n    short y;\n    short cx;\n    short cy;\n}\nalias DLGTEMPLATE*        LPDLGTEMPLATE, LPDLGTEMPLATEA, LPDLGTEMPLATEW;\nalias const(DLGTEMPLATE)* LPCDLGTEMPLATE, LPCDLGTEMPLATEA, LPCDLGTEMPLATEW;\n\nalign:\n\nstruct DRAWITEMSTRUCT {\n    UINT  CtlType;\n    UINT  CtlID;\n    UINT  itemID;\n    UINT  itemAction;\n    UINT  itemState;\n    HWND  hwndItem;\n    HDC   hDC;\n    RECT  rcItem;\n    ULONG_PTR itemData;\n}\nalias DRAWITEMSTRUCT* LPDRAWITEMSTRUCT, PDRAWITEMSTRUCT;\n\nstruct DRAWTEXTPARAMS {\n    UINT cbSize = DRAWTEXTPARAMS.sizeof;\n    int  iTabLength;\n    int  iLeftMargin;\n    int  iRightMargin;\n    UINT uiLengthDrawn;\n}\nalias DRAWTEXTPARAMS* LPDRAWTEXTPARAMS;\n\nstruct PAINTSTRUCT {\n    HDC      hdc;\n    BOOL     fErase;\n    RECT     rcPaint;\n    BOOL     fRestore;\n    BOOL     fIncUpdate;\n    BYTE[32] rgbReserved;\n}\nalias PAINTSTRUCT* PPAINTSTRUCT, NPPAINTSTRUCT, LPPAINTSTRUCT;\n\nstruct MSG {\n    HWND   hwnd;\n    UINT   message;\n    WPARAM wParam;\n    LPARAM lParam;\n    DWORD  time;\n    POINT  pt;\n}\nalias MSG* NPMSG, LPMSG, PMSG;\n\nstruct ICONINFO {\n    BOOL    fIcon;\n    DWORD   xHotspot;\n    DWORD   yHotspot;\n    HBITMAP hbmMask;\n    HBITMAP hbmColor;\n}\nalias ICONINFO* PICONINFO;\n\nstruct NMHDR {\n    HWND hwndFrom;\n    UINT_PTR idFrom;\n    UINT code;\n}\nalias NMHDR* LPNMHDR;\n\nstruct WNDCLASSA {\n    UINT      style;\n    WNDPROC   lpfnWndProc;\n    int       cbClsExtra;\n    int       cbWndExtra;\n    HINSTANCE hInstance;\n    HICON     hIcon;\n    HCURSOR   hCursor;\n    HBRUSH    hbrBackground;\n    LPCSTR    lpszMenuName;\n    LPCSTR    lpszClassName;\n}\nalias WNDCLASSA* NPWNDCLASSA, LPWNDCLASSA, PWNDCLASSA;\n\nstruct WNDCLASSW {\n    UINT      style;\n    WNDPROC   lpfnWndProc;\n    int       cbClsExtra;\n    int       cbWndExtra;\n    HINSTANCE hInstance;\n    HICON     hIcon;\n    HCURSOR   hCursor;\n    HBRUSH    hbrBackground;\n    LPCWSTR   lpszMenuName;\n    LPCWSTR   lpszClassName;\n}\nalias WNDCLASSW* NPWNDCLASSW, LPWNDCLASSW, PWNDCLASSW;\n\nstruct WNDCLASSEXA {\n    UINT      cbSize = WNDCLASSEXA.sizeof;\n    UINT      style;\n    WNDPROC   lpfnWndProc;\n    int       cbClsExtra;\n    int       cbWndExtra;\n    HINSTANCE hInstance;\n    HICON     hIcon;\n    HCURSOR   hCursor;\n    HBRUSH    hbrBackground;\n    LPCSTR    lpszMenuName;\n    LPCSTR    lpszClassName;\n    HICON     hIconSm;\n}\nalias WNDCLASSEXA* NPWNDCLASSEXA, LPWNDCLASSEXA, PWNDCLASSEXA;\n\nstruct WNDCLASSEXW {\n    UINT      cbSize = WNDCLASSEXW.sizeof;\n    UINT      style;\n    WNDPROC   lpfnWndProc;\n    int       cbClsExtra;\n    int       cbWndExtra;\n    HINSTANCE hInstance;\n    HICON     hIcon;\n    HCURSOR   hCursor;\n    HBRUSH    hbrBackground;\n    LPCWSTR   lpszMenuName;\n    LPCWSTR   lpszClassName;\n    HICON     hIconSm;\n}\nalias WNDCLASSEXW* LPWNDCLASSEXW, PWNDCLASSEXW;\n\nstruct MENUITEMINFOA {\n    UINT      cbSize = MENUITEMINFOA.sizeof;\n    UINT      fMask;\n    UINT      fType;\n    UINT      fState;\n    UINT      wID;\n    HMENU     hSubMenu;\n    HBITMAP   hbmpChecked;\n    HBITMAP   hbmpUnchecked;\n    ULONG_PTR dwItemData;\n    LPSTR     dwTypeData;\n    UINT      cch;\n    HBITMAP   hbmpItem;\n}\nalias MENUITEMINFOA*        LPMENUITEMINFOA;\nalias const(MENUITEMINFOA)* LPCMENUITEMINFOA;\n\nstruct MENUITEMINFOW {\n    UINT      cbSize = MENUITEMINFOW.sizeof;\n    UINT      fMask;\n    UINT      fType;\n    UINT      fState;\n    UINT      wID;\n    HMENU     hSubMenu;\n    HBITMAP   hbmpChecked;\n    HBITMAP   hbmpUnchecked;\n    ULONG_PTR dwItemData;\n    LPWSTR    dwTypeData;\n    UINT      cch;\n    HBITMAP   hbmpItem;\n}\nalias MENUITEMINFOW*        LPMENUITEMINFOW;\nalias const(MENUITEMINFOW)* LPCMENUITEMINFOW;\n\nstruct SCROLLINFO {\n    UINT cbSize = this.sizeof;\n    UINT fMask;\n    int nMin;\n    int nMax;\n    UINT nPage;\n    int nPos;\n    int nTrackPos;\n}\nalias SCROLLINFO*        LPSCROLLINFO;\nalias const(SCROLLINFO)* LPCSCROLLINFO;\n\nstruct WINDOWPLACEMENT {\n    UINT length;\n    UINT flags;\n    UINT showCmd;\n    POINT ptMinPosition;\n    POINT ptMaxPosition;\n    RECT rcNormalPosition;\n}\nalias WINDOWPLACEMENT* LPWINDOWPLACEMENT, PWINDOWPLACEMENT;\n\nstruct MENUITEMTEMPLATEHEADER {\n    WORD versionNumber;\n    WORD offset;\n}\n\nstruct MENUITEMTEMPLATE {\n    WORD mtOption;\n    WORD mtID;\n    WCHAR[1] mtString;\n}\n\nalias void MENUTEMPLATE, MENUTEMPLATEA, MENUTEMPLATEW;\n\nalias MENUTEMPLATE* LPMENUTEMPLATEA, LPMENUTEMPLATEW, LPMENUTEMPLATE;\n\nstruct HELPINFO {\n    UINT cbSize = this.sizeof;\n    int iContextType;\n    int iCtrlId;\n    HANDLE hItemHandle;\n    DWORD_PTR dwContextId;\n    POINT MousePos;\n}\nalias HELPINFO* LPHELPINFO;\n\nstruct MSGBOXPARAMSA {\n    UINT cbSize = this.sizeof;\n    HWND hwndOwner;\n    HINSTANCE hInstance;\n    LPCSTR lpszText;\n    LPCSTR lpszCaption;\n    DWORD dwStyle;\n    LPCSTR lpszIcon;\n    DWORD_PTR dwContextHelpId;\n    MSGBOXCALLBACK lpfnMsgBoxCallback;\n    DWORD dwLanguageId;\n}\nalias MSGBOXPARAMSA* PMSGBOXPARAMSA, LPMSGBOXPARAMSA;\n\nstruct MSGBOXPARAMSW {\n    UINT cbSize = this.sizeof;\n    HWND hwndOwner;\n    HINSTANCE hInstance;\n    LPCWSTR lpszText;\n    LPCWSTR lpszCaption;\n    DWORD dwStyle;\n    LPCWSTR lpszIcon;\n    DWORD_PTR dwContextHelpId;\n    MSGBOXCALLBACK lpfnMsgBoxCallback;\n    DWORD dwLanguageId;\n}\nalias MSGBOXPARAMSW* PMSGBOXPARAMSW, LPMSGBOXPARAMSW;\n\nstruct USEROBJECTFLAGS {\n    BOOL fInherit;\n    BOOL fReserved;\n    DWORD dwFlags;\n}\n\nstruct FILTERKEYS {\n    UINT cbSize = this.sizeof;\n    DWORD dwFlags;\n    DWORD iWaitMSec;\n    DWORD iDelayMSec;\n    DWORD iRepeatMSec;\n    DWORD iBounceMSec;\n}\n\nstruct HIGHCONTRASTA {\n    UINT cbSize = this.sizeof;\n    DWORD dwFlags;\n    LPSTR lpszDefaultScheme;\n}\nalias HIGHCONTRASTA* LPHIGHCONTRASTA;\n\nstruct HIGHCONTRASTW {\n    UINT cbSize = this.sizeof;\n    DWORD dwFlags;\n    LPWSTR lpszDefaultScheme;\n}\nalias HIGHCONTRASTW* LPHIGHCONTRASTW;\n\nstruct ICONMETRICSA {\n    UINT cbSize = this.sizeof;\n    int iHorzSpacing;\n    int iVertSpacing;\n    int iTitleWrap;\n    LOGFONTA lfFont;\n}\nalias ICONMETRICSA* LPICONMETRICSA;\n\nstruct ICONMETRICSW {\n    UINT cbSize = this.sizeof;\n    int iHorzSpacing;\n    int iVertSpacing;\n    int iTitleWrap;\n    LOGFONTW lfFont;\n}\nalias ICONMETRICSW* LPICONMETRICSW;\n\nstruct MINIMIZEDMETRICS {\n    UINT cbSize = this.sizeof;\n    int iWidth;\n    int iHorzGap;\n    int iVertGap;\n    int iArrange;\n}\nalias MINIMIZEDMETRICS* LPMINIMIZEDMETRICS;\n\nstruct MOUSEKEYS {\n    UINT cbSize = this.sizeof;\n    DWORD dwFlags;\n    DWORD iMaxSpeed;\n    DWORD iTimeToMaxSpeed;\n    DWORD iCtrlSpeed;\n    DWORD dwReserved1;\n    DWORD dwReserved2;\n}\nalias MOUSEKEYS* LPMOUSEKEYS;\n\nstruct NONCLIENTMETRICSA {\n    UINT cbSize = this.sizeof;\n    int iBorderWidth;\n    int iScrollWidth;\n    int iScrollHeight;\n    int iCaptionWidth;\n    int iCaptionHeight;\n    LOGFONTA lfCaptionFont;\n    int iSmCaptionWidth;\n    int iSmCaptionHeight;\n    LOGFONTA lfSmCaptionFont;\n    int iMenuWidth;\n    int iMenuHeight;\n    LOGFONTA lfMenuFont;\n    LOGFONTA lfStatusFont;\n    LOGFONTA lfMessageFont;\n}\nalias NONCLIENTMETRICSA* LPNONCLIENTMETRICSA;\n\nstruct NONCLIENTMETRICSW {\n    UINT cbSize = this.sizeof;\n    int iBorderWidth;\n    int iScrollWidth;\n    int iScrollHeight;\n    int iCaptionWidth;\n    int iCaptionHeight;\n    LOGFONTW lfCaptionFont;\n    int iSmCaptionWidth;\n    int iSmCaptionHeight;\n    LOGFONTW lfSmCaptionFont;\n    int iMenuWidth;\n    int iMenuHeight;\n    LOGFONTW lfMenuFont;\n    LOGFONTW lfStatusFont;\n    LOGFONTW lfMessageFont;\n}\nalias NONCLIENTMETRICSW* LPNONCLIENTMETRICSW;\n\nstruct SERIALKEYSA {\n    UINT cbSize = this.sizeof;\n    DWORD dwFlags;\n    LPSTR lpszActivePort;\n    LPSTR lpszPort;\n    UINT iBaudRate;\n    UINT iPortState;\n    UINT iActive;\n}\nalias SERIALKEYSA* LPSERIALKEYSA;\n\nstruct SERIALKEYSW {\n    UINT cbSize = this.sizeof;\n    DWORD dwFlags;\n    LPWSTR lpszActivePort;\n    LPWSTR lpszPort;\n    UINT iBaudRate;\n    UINT iPortState;\n    UINT iActive;\n}\nalias SERIALKEYSW* LPSERIALKEYSW;\n\nstruct SOUNDSENTRYA {\n    UINT cbSize = this.sizeof;\n    DWORD dwFlags;\n    DWORD iFSTextEffect;\n    DWORD iFSTextEffectMSec;\n    DWORD iFSTextEffectColorBits;\n    DWORD iFSGrafEffect;\n    DWORD iFSGrafEffectMSec;\n    DWORD iFSGrafEffectColor;\n    DWORD iWindowsEffect;\n    DWORD iWindowsEffectMSec;\n    LPSTR lpszWindowsEffectDLL;\n    DWORD iWindowsEffectOrdinal;\n}\nalias SOUNDSENTRYA* LPSOUNDSENTRYA;\n\nstruct SOUNDSENTRYW {\n    UINT cbSize = this.sizeof;\n    DWORD dwFlags;\n    DWORD iFSTextEffect;\n    DWORD iFSTextEffectMSec;\n    DWORD iFSTextEffectColorBits;\n    DWORD iFSGrafEffect;\n    DWORD iFSGrafEffectMSec;\n    DWORD iFSGrafEffectColor;\n    DWORD iWindowsEffect;\n    DWORD iWindowsEffectMSec;\n    LPWSTR lpszWindowsEffectDLL;\n    DWORD iWindowsEffectOrdinal;\n}\nalias SOUNDSENTRYW* LPSOUNDSENTRYW;\n\nstruct STICKYKEYS {\n    DWORD cbSize = this.sizeof;\n    DWORD dwFlags;\n}\nalias STICKYKEYS* LPSTICKYKEYS;\n\nstruct TOGGLEKEYS {\n    DWORD cbSize = this.sizeof;\n    DWORD dwFlags;\n}\n\nstruct MOUSEHOOKSTRUCT {\n    POINT pt;\n    HWND hwnd;\n    UINT wHitTestCode;\n    ULONG_PTR dwExtraInfo;\n}\nalias MOUSEHOOKSTRUCT* LPMOUSEHOOKSTRUCT, PMOUSEHOOKSTRUCT;\n\nstruct TRACKMOUSEEVENT {\n    DWORD cbSize = this.sizeof;\n    DWORD dwFlags;\n    HWND  hwndTrack;\n    DWORD dwHoverTime;\n}\nalias TRACKMOUSEEVENT* LPTRACKMOUSEEVENT;\n\nstruct TPMPARAMS {\n    UINT cbSize = this.sizeof;\n    RECT rcExclude;\n}\nalias TPMPARAMS* LPTPMPARAMS;\n\nstruct EVENTMSG {\n    UINT message;\n    UINT paramL;\n    UINT paramH;\n    DWORD time;\n    HWND hwnd;\n}\nalias EVENTMSG* PEVENTMSGMSG, LPEVENTMSGMSG, PEVENTMSG, LPEVENTMSG;\n\nstruct WINDOWPOS {\n    HWND hwnd;\n    HWND hwndInsertAfter;\n    int x;\n    int y;\n    int cx;\n    int cy;\n    UINT flags;\n}\nalias WINDOWPOS* PWINDOWPOS, LPWINDOWPOS;\n\nstruct NCCALCSIZE_PARAMS {\n    RECT[3] rgrc;\n    PWINDOWPOS lppos;\n}\nalias NCCALCSIZE_PARAMS* LPNCCALCSIZE_PARAMS;\n\nstruct MDICREATESTRUCTA {\n    LPCSTR szClass;\n    LPCSTR szTitle;\n    HANDLE hOwner;\n    int x;\n    int y;\n    int cx;\n    int cy;\n    DWORD style;\n    LPARAM lParam;\n}\nalias MDICREATESTRUCTA* LPMDICREATESTRUCTA;\n\nstruct MDICREATESTRUCTW {\n    LPCWSTR szClass;\n    LPCWSTR szTitle;\n    HANDLE hOwner;\n    int x;\n    int y;\n    int cx;\n    int cy;\n    DWORD style;\n    LPARAM lParam;\n}\nalias MDICREATESTRUCTW* LPMDICREATESTRUCTW;\n\nstruct MINMAXINFO {\n    POINT ptReserved;\n    POINT ptMaxSize;\n    POINT ptMaxPosition;\n    POINT ptMinTrackSize;\n    POINT ptMaxTrackSize;\n}\nalias MINMAXINFO* PMINMAXINFO, LPMINMAXINFO;\n\nstruct MDINEXTMENU {\n    HMENU hmenuIn;\n    HMENU hmenuNext;\n    HWND hwndNext;\n}\nalias MDINEXTMENU* PMDINEXTMENU, LPMDINEXTMENU;\n\nstruct MEASUREITEMSTRUCT {\n    UINT CtlType;\n    UINT CtlID;\n    UINT itemID;\n    UINT itemWidth;\n    UINT itemHeight;\n    ULONG_PTR itemData;\n}\nalias MEASUREITEMSTRUCT* PMEASUREITEMSTRUCT, LPMEASUREITEMSTRUCT;\n\nstruct DROPSTRUCT {\n    HWND hwndSource;\n    HWND hwndSink;\n    DWORD wFmt;\n    ULONG_PTR dwData;\n    POINT ptDrop;\n    DWORD dwControlData;\n}\nalias DROPSTRUCT* PDROPSTRUCT, LPDROPSTRUCT;\n\nalias DWORD HELPPOLY;\n\nstruct MULTIKEYHELPA {\n    DWORD mkSize;\n    CHAR mkKeylist;\n    CHAR[1] szKeyphrase;\n}\nalias MULTIKEYHELPA* PMULTIKEYHELPA, LPMULTIKEYHELPA;\n\nstruct MULTIKEYHELPW {\n    DWORD mkSize;\n    WCHAR mkKeylist;\n    WCHAR[1] szKeyphrase;\n}\nalias MULTIKEYHELPW* PMULTIKEYHELPW, LPMULTIKEYHELPW;\n\nstruct HELPWININFOA {\n    int wStructSize;\n    int x;\n    int y;\n    int dx;\n    int dy;\n    int wMax;\n    CHAR[2] rgchMember;\n}\nalias HELPWININFOA* PHELPWININFOA, LPHELPWININFOA;\n\nstruct HELPWININFOW {\n    int wStructSize;\n    int x;\n    int y;\n    int dx;\n    int dy;\n    int wMax;\n    WCHAR[2] rgchMember;\n}\nalias HELPWININFOW* PHELPWININFOW, LPHELPWININFOW;\n\nstruct STYLESTRUCT {\n    DWORD styleOld;\n    DWORD styleNew;\n}\nalias STYLESTRUCT* LPSTYLESTRUCT;\n\nstruct ALTTABINFO {\n    DWORD cbSize = this.sizeof;\n    int   cItems;\n    int   cColumns;\n    int   cRows;\n    int   iColFocus;\n    int   iRowFocus;\n    int   cxItem;\n    int   cyItem;\n    POINT ptStart;\n}\nalias ALTTABINFO* PALTTABINFO, LPALTTABINFO;\n\nstruct COMBOBOXINFO {\n    DWORD cbSize = this.sizeof;\n    RECT rcItem;\n    RECT rcButton;\n    DWORD stateButton;\n    HWND hwndCombo;\n    HWND hwndItem;\n    HWND hwndList;\n}\nalias COMBOBOXINFO* PCOMBOBOXINFO, LPCOMBOBOXINFO;\n\nstruct CURSORINFO {\n    DWORD cbSize = this.sizeof;\n    DWORD flags;\n    HCURSOR hCursor;\n    POINT ptScreenPos;\n}\nalias CURSORINFO* PCURSORINFO, LPCURSORINFO;\n\nstruct MENUBARINFO {\n    DWORD cbSize = this.sizeof;\n    RECT  rcBar;\n    HMENU hMenu;\n    HWND  hwndMenu;\n    byte bf_; // Simulated bitfield\n//  BOOL  fBarFocused:1;\n//  BOOL  fFocused:1;\n    bool fBarFocused()       { return (bf_ & 1) == 1; }\n    bool fFocused()          { return (bf_ & 2) == 2; }\n    bool fBarFocused(bool b) { bf_ = cast(byte) ((bf_ & 0xFE) | b);           return b; }\n    bool fFocused(bool b)    { bf_ = cast(byte) (b ? (bf_ | 2) : bf_ & 0xFD); return b; }\n}\nalias MENUBARINFO* PMENUBARINFO;\n\nstruct MENUINFO {\n    DWORD cbSize = this.sizeof;\n    DWORD fMask;\n    DWORD dwStyle;\n    UINT cyMax;\n    HBRUSH  hbrBack;\n    DWORD   dwContextHelpID;\n    ULONG_PTR dwMenuData;\n}\nalias MENUINFO*        LPMENUINFO;\nalias const(MENUINFO)* LPCMENUINFO;\n\n\nenum CCHILDREN_SCROLLBAR = 5;\n\nstruct SCROLLBARINFO {\n    DWORD cbSize = this.sizeof;\n    RECT  rcScrollBar;\n    int   dxyLineButton;\n    int   xyThumbTop;\n    int   xyThumbBottom;\n    int   reserved;\n    DWORD[CCHILDREN_SCROLLBAR+1] rgstate;\n}\nalias SCROLLBARINFO* PSCROLLBARINFO, LPSCROLLBARINFO;\n\nenum CCHILDREN_TITLEBAR = 5;\n\nstruct WINDOWINFO {\n    DWORD cbSize = WINDOWINFO.sizeof;\n    RECT  rcWindow;\n    RECT  rcClient;\n    DWORD dwStyle;\n    DWORD dwExStyle;\n    DWORD dwWindowStatus;\n    UINT  cxWindowBorders;\n    UINT  cyWindowBorders;\n    ATOM  atomWindowType;\n    WORD  wCreatorVersion;\n}\nalias WINDOWINFO* PWINDOWINFO, LPWINDOWINFO;\n\nstruct LASTINPUTINFO {\n    UINT cbSize = this.sizeof;\n    DWORD dwTime;\n}\nalias LASTINPUTINFO* PLASTINPUTINFO;\n\nstruct MONITORINFO {\n    DWORD cbSize = this.sizeof;\n    RECT rcMonitor;\n    RECT rcWork;\n    DWORD dwFlags;\n}\nalias MONITORINFO* LPMONITORINFO;\n\nenum CCHDEVICENAME = 32;\n\nstruct MONITORINFOEXA {\n    DWORD cbSize = MONITORINFOEXA.sizeof;\n    RECT  rcMonitor;\n    RECT  rcWork;\n    DWORD dwFlags;\n    CHAR[CCHDEVICENAME] szDevice;\n}\nalias MONITORINFOEXA* LPMONITORINFOEXA;\n\nstruct MONITORINFOEXW {\n    DWORD cbSize = MONITORINFOEXW.sizeof;\n    RECT  rcMonitor;\n    RECT  rcWork;\n    DWORD dwFlags;\n    WCHAR[CCHDEVICENAME] szDevice;\n}\nalias MONITORINFOEXW* LPMONITORINFOEXW;\n\nstruct KBDLLHOOKSTRUCT {\n    DWORD vkCode;\n    DWORD scanCode;\n    DWORD flags;\n    DWORD time;\n    ULONG_PTR dwExtraInfo;\n}\nalias KBDLLHOOKSTRUCT* LPKBDLLHOOKSTRUCT, PKBDLLHOOKSTRUCT;\n\nstruct MSLLHOOKSTRUCT {\n    POINT     pt;\n    DWORD     mouseData;\n    DWORD     flags;\n    DWORD     time;\n    ULONG_PTR dwExtraInfo;\n}\nalias MSLLHOOKSTRUCT* PMSLLHOOKSTRUCT;\n\nstruct MOUSEINPUT {\n    LONG dx;\n    LONG dy;\n    DWORD mouseData;\n    DWORD dwFlags;\n    DWORD time;\n    ULONG_PTR dwExtraInfo;\n}\nalias MOUSEINPUT* PMOUSEINPUT;\n\nstruct KEYBDINPUT {\n    WORD wVk;\n    WORD wScan;\n    DWORD dwFlags;\n    DWORD time;\n    ULONG_PTR dwExtraInfo;\n}\nalias KEYBDINPUT* PKEYBDINPUT;\n\nstruct HARDWAREINPUT {\n    DWORD uMsg;\n    WORD wParamL;\n    WORD wParamH;\n}\nalias HARDWAREINPUT* PHARDWAREINPUT;\n\nstruct INPUT {\n    DWORD type;\n    union {\n        MOUSEINPUT mi;\n        KEYBDINPUT ki;\n        HARDWAREINPUT hi;\n    }\n}\nalias INPUT* PINPUT, LPINPUT;\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    align(4) struct BSMINFO {\n        UINT  cbSize = this.sizeof;\n        HDESK hdesk;\n        HWND  hwnd;\nalign(4) LUID  luid;\n    }\n    alias BSMINFO* PBSMINFO;\n\n    alias TypeDef!(HANDLE) HRAWINPUT;\n\n    struct RAWINPUTHEADER {\n        DWORD dwType;\n        DWORD dwSize;\n        HANDLE hDevice;\n        WPARAM wParam;\n    }\n    alias RAWINPUTHEADER* PRAWINPUTHEADER;\n\n    struct RAWMOUSE {\n        USHORT usFlags;\n        union {\n            ULONG ulButtons;\n            struct {\n                USHORT usButtonFlags;\n                USHORT usButtonData;\n            }\n        }\n        ULONG ulRawButtons;\n        LONG lLastX;\n        LONG lLastY;\n        ULONG ulExtraInformation;\n    }\n    alias RAWMOUSE* PRAWMOUSE, LPRAWMOUSE;\n\n    struct RAWKEYBOARD {\n        USHORT MakeCode;\n        USHORT Flags;\n        USHORT Reserved;\n        USHORT VKey;\n        UINT Message;\n        ULONG ExtraInformation;\n    }\n    alias RAWKEYBOARD* PRAWKEYBOARD, LPRAWKEYBOARD;\n\n    struct RAWHID {\n        DWORD dwSizeHid;\n        DWORD dwCount;\n        BYTE bRawData;\n    }\n    alias RAWHID* PRAWHID, LPRAWHID;\n\n    struct RAWINPUT {\n        RAWINPUTHEADER header;\n        union _data {\n            RAWMOUSE    mouse;\n            RAWKEYBOARD keyboard;\n            RAWHID      hid;\n        }\n        _data data;\n    }\n    alias RAWINPUT* PRAWINPUT, LPRAWINPUT;\n\n    struct RAWINPUTDEVICE {\n        USHORT usUsagePage;\n        USHORT usUsage;\n        DWORD dwFlags;\n        HWND hwndTarget;\n    }\n    alias RAWINPUTDEVICE*        PRAWINPUTDEVICE, LPRAWINPUTDEVICE;\n    alias const(RAWINPUTDEVICE)* PCRAWINPUTDEVICE;\n\n    struct RAWINPUTDEVICELIST {\n        HANDLE hDevice;\n        DWORD dwType;\n    }\n    alias RAWINPUTDEVICELIST* PRAWINPUTDEVICELIST;\n\n    struct RID_DEVICE_INFO_MOUSE {\n        DWORD dwId;\n        DWORD dwNumberOfButtons;\n        DWORD dwSampleRate;\n        BOOL  fHasHorizontalWheel;\n    }\n\n    struct RID_DEVICE_INFO_KEYBOARD {\n        DWORD dwType;\n        DWORD dwSubType;\n        DWORD dwKeyboardMode;\n        DWORD dwNumberOfFunctionKeys;\n        DWORD dwNumberOfIndicators;\n        DWORD dwNumberOfKeysTotal;\n    }\n\n    struct RID_DEVICE_INFO_HID {\n        DWORD dwVendorId;\n        DWORD dwProductId;\n        DWORD dwVersionNumber;\n        USHORT usUsagePage;\n        USHORT usUsage;\n    }\n\n    struct RID_DEVICE_INFO {\n        DWORD cbSize = this.sizeof;\n        DWORD dwType;\n        union {\n            RID_DEVICE_INFO_MOUSE mouse;\n            RID_DEVICE_INFO_KEYBOARD keyboard;\n            RID_DEVICE_INFO_HID hid;\n        }\n    }\n}// (_WIN32_WINNT >= 0x501)\n\nalias CharToOemA AnsiToOem;\nalias OemToCharA OemToAnsi;\nalias CharToOemBuffA AnsiToOemBuff;\nalias OemToCharBuffA OemToAnsiBuff;\nalias CharUpperA AnsiUpper;\nalias CharUpperBuffA AnsiUpperBuff;\nalias CharLowerA AnsiLower;\nalias CharLowerBuffA AnsiLowerBuff;\nalias CharNextA AnsiNext;\nalias CharPrevA AnsiPrev;\n\nalias MAKELONG MAKEWPARAM;\nalias MAKELONG MAKELPARAM;\nalias MAKELONG MAKELRESULT;\n\nvoid POINTSTOPOINT()(out POINT p, LONG ps) {\n    p.x = LOWORD(ps);\n    p.y = HIWORD(ps);\n}\n\nPOINTS POINTTOPOINTS()(in POINT p) {\n    return MAKELONG(p.x, p.y);\n}\n\nextern (Windows) nothrow @nogc {\n    HKL ActivateKeyboardLayout(HKL, UINT);\n    BOOL AdjustWindowRect(LPRECT, DWORD, BOOL);\n    BOOL AdjustWindowRectEx(LPRECT, DWORD, BOOL, DWORD);\n    BOOL AnyPopup();\n    BOOL AppendMenuA(HMENU, UINT, UINT_PTR, LPCSTR);\n    BOOL AppendMenuW(HMENU, UINT, UINT_PTR, LPCWSTR);\n    UINT ArrangeIconicWindows(HWND);\n    BOOL AttachThreadInput(DWORD, DWORD, BOOL);\n    HDWP BeginDeferWindowPos(int);\n    HDC BeginPaint(HWND, LPPAINTSTRUCT);\n    BOOL BringWindowToTop(HWND);\n    BOOL CallMsgFilterA(LPMSG, INT);\n    BOOL CallMsgFilterW(LPMSG, INT);\n    LRESULT CallNextHookEx(HHOOK, int, WPARAM, LPARAM);\n    LRESULT CallWindowProcA(WNDPROC, HWND, UINT, WPARAM, LPARAM);\n    LRESULT CallWindowProcW(WNDPROC, HWND, UINT, WPARAM, LPARAM);\n    WORD CascadeWindows(HWND, UINT, LPCRECT, UINT, const(HWND)*);\n    BOOL ChangeClipboardChain(HWND, HWND);\n\n    LONG ChangeDisplaySettingsA(PDEVMODEA, DWORD);\n    LONG ChangeDisplaySettingsW(PDEVMODEW, DWORD);\n    LONG ChangeDisplaySettingsExA(LPCSTR, LPDEVMODEA, HWND, DWORD, LPVOID);\n    LONG ChangeDisplaySettingsExW(LPCWSTR, LPDEVMODEW, HWND, DWORD, LPVOID);\n\n    BOOL ChangeMenuA(HMENU, UINT, LPCSTR, UINT, UINT);\n    BOOL ChangeMenuW(HMENU, UINT, LPCWSTR, UINT, UINT);\n    LPSTR CharLowerA(LPSTR);\n    LPWSTR CharLowerW(LPWSTR);\n    DWORD CharLowerBuffA(LPSTR, DWORD);\n    DWORD CharLowerBuffW(LPWSTR, DWORD);\n    LPSTR CharNextA(LPCSTR);\n    LPWSTR CharNextW(LPCWSTR);\n    LPSTR CharNextExA(WORD, LPCSTR, DWORD);\n    LPWSTR CharNextExW(WORD, LPCWSTR, DWORD);\n    LPSTR CharPrevA(LPCSTR, LPCSTR);\n    LPWSTR CharPrevW(LPCWSTR, LPCWSTR);\n    LPSTR CharPrevExA(WORD, LPCSTR, LPCSTR, DWORD);\n    LPWSTR CharPrevExW(WORD, LPCWSTR, LPCWSTR, DWORD);\n    BOOL CharToOemA(LPCSTR, LPSTR);\n    BOOL CharToOemW(LPCWSTR, LPSTR);\n    BOOL CharToOemBuffA(LPCSTR, LPSTR, DWORD);\n    BOOL CharToOemBuffW(LPCWSTR, LPSTR, DWORD);\n    LPSTR CharUpperA(LPSTR);\n    LPWSTR CharUpperW(LPWSTR);\n    DWORD CharUpperBuffA(LPSTR, DWORD);\n    DWORD CharUpperBuffW(LPWSTR, DWORD);\n    BOOL CheckDlgButton(HWND, int, UINT);\n    DWORD CheckMenuItem(HMENU, UINT, UINT);\n    BOOL CheckMenuRadioItem(HMENU, UINT, UINT, UINT, UINT);\n    BOOL CheckRadioButton(HWND, int, int, int);\n    HWND ChildWindowFromPoint(HWND, POINT);\n    HWND ChildWindowFromPointEx(HWND, POINT, UINT);\n    BOOL ClientToScreen(HWND, LPPOINT);\n    BOOL ClipCursor(LPCRECT);\n    BOOL CloseClipboard();\n    BOOL CloseDesktop(HDESK);\n    BOOL CloseWindow(HWND);\n    BOOL CloseWindowStation(HWINSTA);\n    int CopyAcceleratorTableA(HACCEL, LPACCEL, int);\n    int CopyAcceleratorTableW(HACCEL, LPACCEL, int);\n\n    HICON CopyIcon(HICON);\n    HANDLE CopyImage(HANDLE, UINT, int, int, UINT);\n    BOOL CopyRect(LPRECT, LPCRECT);\n    int CountClipboardFormats();\n    HACCEL CreateAcceleratorTableA(LPACCEL, int);\n    HACCEL CreateAcceleratorTableW(LPACCEL, int);\n    BOOL CreateCaret(HWND, HBITMAP, int, int);\n    HCURSOR CreateCursor(HINSTANCE, int, int, int, int, PCVOID, PCVOID);\n\n    HDESK CreateDesktopA(LPCSTR, LPCSTR, LPDEVMODEA, DWORD, ACCESS_MASK, LPSECURITY_ATTRIBUTES);\n    HDESK CreateDesktopW(LPCWSTR, LPCWSTR, LPDEVMODEW, DWORD, ACCESS_MASK, LPSECURITY_ATTRIBUTES);\n\n    HWND CreateDialogParamA(HINSTANCE, LPCSTR, HWND, DLGPROC, LPARAM);\n    HWND CreateDialogParamW(HINSTANCE, LPCWSTR, HWND, DLGPROC, LPARAM);\n    HWND CreateDialogIndirectParamA(HINSTANCE, LPCDLGTEMPLATE, HWND, DLGPROC, LPARAM);\n    HWND CreateDialogIndirectParamW(HINSTANCE, LPCDLGTEMPLATE, HWND, DLGPROC, LPARAM);\n\n    HICON CreateIcon(HINSTANCE, int, int, BYTE, BYTE, const(BYTE)*, BYTE*);\n    HICON CreateIconFromResource(PBYTE, DWORD, BOOL, DWORD);\n    HICON CreateIconFromResourceEx(PBYTE, DWORD, BOOL, DWORD, int, int, UINT);\n    HICON CreateIconIndirect(PICONINFO);\n    HWND CreateMDIWindowA(LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HINSTANCE, LPARAM);\n    HWND CreateMDIWindowW(LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HINSTANCE, LPARAM);\n    HMENU CreateMenu();\n    HMENU CreatePopupMenu();\n\n    HWND CreateWindowExA(DWORD, LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID);\n    HWND CreateWindowExW(DWORD, LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID);\n\n    HWINSTA CreateWindowStationA(LPSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES);\n    HWINSTA CreateWindowStationW(LPWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES);\n    LRESULT DefDlgProcA(HWND, UINT, WPARAM, LPARAM);\n    LRESULT DefDlgProcW(HWND, UINT, WPARAM, LPARAM);\n    HDWP DeferWindowPos(HDWP, HWND, HWND, int, int, int, int, UINT);\n    LRESULT DefFrameProcA(HWND, HWND, UINT, WPARAM, LPARAM);\n    LRESULT DefFrameProcW(HWND, HWND, UINT, WPARAM, LPARAM);\n\n    LRESULT DefMDIChildProcA(HWND, UINT, WPARAM, LPARAM);\n    LRESULT DefMDIChildProcW(HWND, UINT, WPARAM, LPARAM);\n    LRESULT DefWindowProcA(HWND, UINT, WPARAM, LPARAM);\n    LRESULT DefWindowProcW(HWND, UINT, WPARAM, LPARAM);\n    BOOL DeleteMenu(HMENU, UINT, UINT);\n    BOOL DeregisterShellHookWindow(HWND);\n    BOOL DestroyAcceleratorTable(HACCEL);\n    BOOL DestroyCaret();\n    BOOL DestroyCursor(HCURSOR);\n    BOOL DestroyIcon(HICON);\n    BOOL DestroyMenu(HMENU);\n    BOOL DestroyWindow(HWND);\n\n    INT_PTR DialogBoxParamA(HINSTANCE, LPCSTR, HWND, DLGPROC, LPARAM);\n    INT_PTR DialogBoxParamW(HINSTANCE, LPCWSTR, HWND, DLGPROC, LPARAM);\n    INT_PTR DialogBoxIndirectParamA(HINSTANCE, LPCDLGTEMPLATE, HWND, DLGPROC, LPARAM);\n    INT_PTR DialogBoxIndirectParamW(HINSTANCE, LPCDLGTEMPLATE, HWND, DLGPROC, LPARAM);\n\n} // extern (Windows)\n\nnothrow @nogc {\n    HCURSOR CopyCursor(HCURSOR c) {\n        return cast(HCURSOR)CopyIcon(cast(HICON)c);\n    }\n\n    HWND CreateDialogA(HINSTANCE h, LPCSTR n, HWND w, DLGPROC f) {\n        return CreateDialogParamA(h, n, w, f, 0);\n    }\n\n    HWND CreateDialogW(HINSTANCE h, LPCWSTR n, HWND w, DLGPROC f) {\n        return CreateDialogParamW(h, n, w, f, 0);\n    }\n\n    HWND CreateDialogIndirectA(HINSTANCE h, LPCDLGTEMPLATE t, HWND w, DLGPROC f) {\n        return CreateDialogIndirectParamA(h, t, w, f, 0);\n    }\n\n    HWND CreateDialogIndirectW(HINSTANCE h, LPCDLGTEMPLATE t, HWND w, DLGPROC f) {\n        return CreateDialogIndirectParamW(h, t, w, f, 0);\n    }\n\n    HWND CreateWindowA(LPCSTR a, LPCSTR b, DWORD c, int d, int e, int f, int g, HWND h, HMENU i, HINSTANCE j, LPVOID k) {\n        return CreateWindowExA(0, a, b, c, d, e, f, g, h, i, j, k);\n    }\n\n    HWND CreateWindowW(LPCWSTR a, LPCWSTR b, DWORD c, int d, int e, int f, int g, HWND h, HMENU i, HINSTANCE j, LPVOID k) {\n        return CreateWindowExW(0, a, b, c, d, e, f, g, h, i, j, k);\n    }\n\n    INT_PTR DialogBoxA(HINSTANCE i, LPCSTR t, HWND p, DLGPROC f) {\n        return DialogBoxParamA(i, t, p, f, 0);\n    }\n\n    INT_PTR DialogBoxW(HINSTANCE i, LPCWSTR t, HWND p, DLGPROC f) {\n        return DialogBoxParamW(i, t, p, f, 0);\n    }\n\n    INT_PTR DialogBoxIndirectA(HINSTANCE i, LPCDLGTEMPLATE t, HWND p, DLGPROC f) {\n        return DialogBoxIndirectParamA(i, t, p, f, 0);\n    }\n\n    INT_PTR DialogBoxIndirectW(HINSTANCE i, LPCDLGTEMPLATE t, HWND p, DLGPROC f) {\n        return DialogBoxIndirectParamW(i, t, p, f, 0);\n    }\n\n    BOOL ExitWindows(UINT r, DWORD c) {\n        return ExitWindowsEx(EWX_LOGOFF, 0);\n    }\n}\nalias GetWindow GetNextWindow;\n\nextern (Windows) nothrow @nogc:\nLONG DispatchMessageA(const(MSG)*);\nLONG DispatchMessageW(const(MSG)*);\nint DlgDirListA(HWND, LPSTR, int, int, UINT);\nint DlgDirListW(HWND, LPWSTR, int, int, UINT);\nint DlgDirListComboBoxA(HWND, LPSTR, int, int, UINT);\nint DlgDirListComboBoxW(HWND, LPWSTR, int, int, UINT);\nBOOL DlgDirSelectComboBoxExA(HWND, LPSTR, int, int);\nBOOL DlgDirSelectComboBoxExW(HWND, LPWSTR, int, int);\nBOOL DlgDirSelectExA(HWND, LPSTR, int, int);\nBOOL DlgDirSelectExW(HWND, LPWSTR, int, int);\nBOOL DragDetect(HWND, POINT);\nDWORD DragObject(HWND, HWND, UINT, ULONG_PTR, HCURSOR);\nBOOL DrawAnimatedRects(HWND, int, LPCRECT, LPCRECT);\nBOOL DrawCaption(HWND, HDC, LPCRECT, UINT);\nBOOL DrawEdge(HDC, LPRECT, UINT, UINT);\nBOOL DrawFocusRect(HDC, LPCRECT);\nBOOL DrawFrameControl(HDC, LPRECT, UINT, UINT);\nBOOL DrawIcon(HDC, int, int, HICON);\nBOOL DrawIconEx(HDC, int, int, HICON, int, int, UINT, HBRUSH, UINT);\nBOOL DrawMenuBar(HWND);\nBOOL DrawStateA(HDC, HBRUSH, DRAWSTATEPROC, LPARAM, WPARAM, int, int, int, int, UINT);\nBOOL DrawStateW(HDC, HBRUSH, DRAWSTATEPROC, LPARAM, WPARAM, int, int, int, int, UINT);\nint DrawTextA(HDC, LPCSTR, int, LPRECT, UINT);\nint DrawTextW(HDC, LPCWSTR, int, LPRECT, UINT);\nint DrawTextExA(HDC, LPSTR, int, LPRECT, UINT, LPDRAWTEXTPARAMS);\nint DrawTextExW(HDC, LPWSTR, int, LPRECT, UINT, LPDRAWTEXTPARAMS);\nBOOL EmptyClipboard();\nBOOL EnableMenuItem(HMENU, UINT, UINT);\nBOOL EnableScrollBar(HWND, UINT, UINT);\nBOOL EnableWindow(HWND, BOOL);\nBOOL EndDeferWindowPos(HDWP);\nBOOL EndDialog(HWND, INT_PTR);\nBOOL EndMenu();\nBOOL EndPaint(HWND, const(PAINTSTRUCT)*);\nBOOL EnumChildWindows(HWND, ENUMWINDOWSPROC, LPARAM);\nUINT EnumClipboardFormats(UINT);\nBOOL EnumDesktopsA(HWINSTA, DESKTOPENUMPROCA, LPARAM);\nBOOL EnumDesktopsW(HWINSTA, DESKTOPENUMPROCW, LPARAM);\nBOOL EnumDesktopWindows(HDESK, ENUMWINDOWSPROC, LPARAM);\nBOOL EnumDisplaySettingsA(LPCSTR, DWORD, PDEVMODEA);\nBOOL EnumDisplaySettingsW(LPCWSTR, DWORD, PDEVMODEW);\n\nBOOL EnumDisplayDevicesA(LPCSTR, DWORD, PDISPLAY_DEVICEA, DWORD);\nBOOL EnumDisplayDevicesW(LPCWSTR, DWORD, PDISPLAY_DEVICEW, DWORD);\n\nint EnumPropsA(HWND, PROPENUMPROCA);\nint EnumPropsW(HWND, PROPENUMPROCW);\nint EnumPropsExA(HWND, PROPENUMPROCEXA, LPARAM);\nint EnumPropsExW(HWND, PROPENUMPROCEXW, LPARAM);\n\nBOOL EnumThreadWindows(DWORD, WNDENUMPROC, LPARAM);\nBOOL EnumWindows(WNDENUMPROC, LPARAM);\nBOOL EnumWindowStationsA(WINSTAENUMPROCA, LPARAM);\nBOOL EnumWindowStationsW(WINSTAENUMPROCW, LPARAM);\nBOOL EqualRect(LPCRECT, LPCRECT);\n\nBOOL ExitWindowsEx(UINT, DWORD);\nHWND FindWindowA(LPCSTR, LPCSTR);\nHWND FindWindowExA(HWND, HWND, LPCSTR, LPCSTR);\nHWND FindWindowExW(HWND, HWND, LPCWSTR, LPCWSTR);\nHWND FindWindowW(LPCWSTR, LPCWSTR);\nBOOL FlashWindow(HWND, BOOL);\n\nint FrameRect(HDC, LPCRECT, HBRUSH);\nBOOL FrameRgn(HDC, HRGN, HBRUSH, int, int);\nHWND GetActiveWindow();\nHWND GetAncestor(HWND, UINT);\nSHORT GetAsyncKeyState(int);\nHWND GetCapture();\nUINT GetCaretBlinkTime();\nBOOL GetCaretPos(LPPOINT);\nBOOL GetClassInfoA(HINSTANCE, LPCSTR, LPWNDCLASSA);\nBOOL GetClassInfoExA(HINSTANCE, LPCSTR, LPWNDCLASSEXA);\nBOOL GetClassInfoW(HINSTANCE, LPCWSTR, LPWNDCLASSW);\nBOOL GetClassInfoExW(HINSTANCE, LPCWSTR, LPWNDCLASSEXW);\nDWORD GetClassLongA(HWND, int);\nDWORD GetClassLongW(HWND, int);\nint GetClassNameA(HWND, LPSTR, int);\nint GetClassNameW(HWND, LPWSTR, int);\nWORD GetClassWord(HWND, int);\nBOOL GetClientRect(HWND, LPRECT);\nHANDLE GetClipboardData(UINT);\nint GetClipboardFormatNameA(UINT, LPSTR, int);\nint GetClipboardFormatNameW(UINT, LPWSTR, int);\nHWND GetClipboardOwner();\nHWND GetClipboardViewer();\nBOOL GetClipCursor(LPRECT);\nBOOL GetCursorPos(LPPOINT);\nHDC GetDC(HWND);\nHDC GetDCEx(HWND, HRGN, DWORD);\nHWND GetDesktopWindow();\nint GetDialogBaseUnits();\nint GetDlgCtrlID(HWND);\nHWND GetDlgItem(HWND, int);\nUINT GetDlgItemInt(HWND, int, PBOOL, BOOL);\nUINT GetDlgItemTextA(HWND, int, LPSTR, int);\nUINT GetDlgItemTextW(HWND, int, LPWSTR, int);\nUINT GetDoubleClickTime();\nHWND GetFocus();\nHWND GetForegroundWindow();\n\nBOOL GetIconInfo(HICON, PICONINFO);\nBOOL GetInputState();\nUINT GetKBCodePage();\nHKL GetKeyboardLayout(DWORD);\nUINT GetKeyboardLayoutList(int, HKL*);\nBOOL GetKeyboardLayoutNameA(LPSTR);\nBOOL GetKeyboardLayoutNameW(LPWSTR);\nBOOL GetKeyboardState(PBYTE);\nint GetKeyboardType(int);\nint GetKeyNameTextA(LONG, LPSTR, int);\nint GetKeyNameTextW(LONG, LPWSTR, int);\nSHORT GetKeyState(int);\nHWND GetLastActivePopup(HWND);\nHMENU GetMenu(HWND);\nLONG GetMenuCheckMarkDimensions();\nDWORD GetMenuContextHelpId(HMENU);\nUINT GetMenuDefaultItem(HMENU, UINT, UINT);\nint GetMenuItemCount(HMENU);\nUINT GetMenuItemID(HMENU, int);\nBOOL GetMenuItemInfoA(HMENU, UINT, BOOL, LPMENUITEMINFOA);\nBOOL GetMenuItemInfoW(HMENU, UINT, BOOL, LPMENUITEMINFOW);\nBOOL GetMenuItemRect(HWND, HMENU, UINT, LPRECT);\nUINT GetMenuState(HMENU, UINT, UINT);\nint GetMenuStringA(HMENU, UINT, LPSTR, int, UINT);\nint GetMenuStringW(HMENU, UINT, LPWSTR, int, UINT);\nBOOL GetMessageA(LPMSG, HWND, UINT, UINT);\nBOOL GetMessageW(LPMSG, HWND, UINT, UINT);\nLONG GetMessageExtraInfo();\nDWORD GetMessagePos();\nLONG GetMessageTime();\n\nHWND GetNextDlgGroupItem(HWND, HWND, BOOL);\nHWND GetNextDlgTabItem(HWND, HWND, BOOL);\n\nHWND GetOpenClipboardWindow();\nHWND GetParent(HWND);\nint GetPriorityClipboardFormat(UINT*, int);\nHANDLE GetPropA(HWND, LPCSTR);\nHANDLE GetPropW(HWND, LPCWSTR);\n\nDWORD GetQueueStatus(UINT);\nBOOL GetScrollInfo(HWND, int, LPSCROLLINFO);\nint GetScrollPos(HWND, int);\nBOOL GetScrollRange(HWND, int, LPINT, LPINT);\n\nHMENU GetSubMenu(HMENU, int);\nDWORD GetSysColor(int);\nHBRUSH GetSysColorBrush(int);\n\nHMENU GetSystemMenu(HWND, BOOL);\nint GetSystemMetrics(int);\nDWORD GetTabbedTextExtentA(HDC, LPCSTR, int, int, LPINT);\nDWORD GetTabbedTextExtentW(HDC, LPCWSTR, int, int, LPINT);\nLONG GetWindowLongA(HWND, int);\nLONG GetWindowLongW(HWND, int);\n\nHDESK GetThreadDesktop(DWORD);\nHWND GetTopWindow(HWND);\nBOOL GetUpdateRect(HWND, LPRECT, BOOL);\nint GetUpdateRgn(HWND, HRGN, BOOL);\nBOOL GetUserObjectInformationA(HANDLE, int, PVOID, DWORD, PDWORD);\nBOOL GetUserObjectInformationW(HANDLE, int, PVOID, DWORD, PDWORD);\nBOOL GetUserObjectSecurity(HANDLE, PSECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, PDWORD);\nHWND GetWindow(HWND, UINT);\nDWORD GetWindowContextHelpId(HWND);\nHDC GetWindowDC(HWND);\nBOOL GetWindowPlacement(HWND, WINDOWPLACEMENT*);\nBOOL GetWindowRect(HWND, LPRECT);\nint GetWindowRgn(HWND, HRGN);\nint GetWindowTextA(HWND, LPSTR, int);\nint GetWindowTextLengthA(HWND);\nint GetWindowTextLengthW(HWND);\nint GetWindowTextW(HWND, LPWSTR, int);\nWORD GetWindowWord(HWND, int);\nBOOL GetAltTabInfoA(HWND, int, PALTTABINFO, LPSTR, UINT);\nBOOL GetAltTabInfoW(HWND, int, PALTTABINFO, LPWSTR, UINT);\nBOOL GetComboBoxInfo(HWND, PCOMBOBOXINFO);\nBOOL GetCursorInfo(PCURSORINFO);\nBOOL GetLastInputInfo(PLASTINPUTINFO);\nDWORD GetListBoxInfo(HWND);\nBOOL GetMenuBarInfo(HWND, LONG, LONG, PMENUBARINFO);\nBOOL GetMenuInfo(HMENU, LPMENUINFO);\nBOOL GetScrollBarInfo(HWND, LONG, PSCROLLBARINFO);\nBOOL GetTitleBarInfo(HWND, PTITLEBARINFO);\nBOOL GetWindowInfo(HWND, PWINDOWINFO);\nUINT GetWindowModuleFileNameA(HWND, LPSTR, UINT);\nUINT GetWindowModuleFileNameW(HWND, LPWSTR, UINT);\nBOOL GrayStringA(HDC, HBRUSH, GRAYSTRINGPROC, LPARAM, int, int, int, int, int);\nBOOL GrayStringW(HDC, HBRUSH, GRAYSTRINGPROC, LPARAM, int, int, int, int, int);\nBOOL HideCaret(HWND);\nBOOL HiliteMenuItem(HWND, HMENU, UINT, UINT);\nBOOL InflateRect(LPRECT, int, int);\nBOOL InSendMessage();\nBOOL InsertMenuA(HMENU, UINT, UINT, UINT_PTR, LPCSTR);\nBOOL InsertMenuW(HMENU, UINT, UINT, UINT_PTR, LPCWSTR);\nBOOL InsertMenuItemA(HMENU, UINT, BOOL, LPCMENUITEMINFOA);\nBOOL InsertMenuItemW(HMENU, UINT, BOOL, LPCMENUITEMINFOW);\nINT InternalGetWindowText(HWND, LPWSTR, INT);\nBOOL IntersectRect(LPRECT, LPCRECT, LPCRECT);\nBOOL InvalidateRect(HWND, LPCRECT, BOOL);\nBOOL InvalidateRgn(HWND, HRGN, BOOL);\nBOOL InvertRect(HDC, LPCRECT);\nBOOL IsCharAlphaA(CHAR ch);\nBOOL IsCharAlphaNumericA(CHAR);\nBOOL IsCharAlphaNumericW(WCHAR);\nBOOL IsCharAlphaW(WCHAR);\nBOOL IsCharLowerA(CHAR);\nBOOL IsCharLowerW(WCHAR);\nBOOL IsCharUpperA(CHAR);\nBOOL IsCharUpperW(WCHAR);\nBOOL IsChild(HWND, HWND);\nBOOL IsClipboardFormatAvailable(UINT);\nBOOL IsDialogMessageA(HWND, LPMSG);\nBOOL IsDialogMessageW(HWND, LPMSG);\nUINT IsDlgButtonChecked(HWND, int);\nBOOL IsIconic(HWND);\nBOOL IsMenu(HMENU);\nBOOL IsRectEmpty(LPCRECT);\nBOOL IsWindow(HWND);\nBOOL IsWindowEnabled(HWND);\nBOOL IsWindowUnicode(HWND);\nBOOL IsWindowVisible(HWND);\nBOOL IsZoomed(HWND);\nvoid keybd_event(BYTE, BYTE, DWORD, ULONG_PTR);\nBOOL KillTimer(HWND, UINT_PTR);\nHACCEL LoadAcceleratorsA(HINSTANCE, LPCSTR);\nHACCEL LoadAcceleratorsW(HINSTANCE, LPCWSTR);\nHBITMAP LoadBitmapA(HINSTANCE, LPCSTR);\nHBITMAP LoadBitmapW(HINSTANCE, LPCWSTR);\nHCURSOR LoadCursorA(HINSTANCE, LPCSTR);\nHCURSOR LoadCursorFromFileA(LPCSTR);\nHCURSOR LoadCursorFromFileW(LPCWSTR);\nHCURSOR LoadCursorW(HINSTANCE, LPCWSTR);\nHICON LoadIconA(HINSTANCE, LPCSTR);\nHICON LoadIconW(HINSTANCE, LPCWSTR);\nHANDLE LoadImageA(HINSTANCE, LPCSTR, UINT, int, int, UINT);\nHANDLE LoadImageW(HINSTANCE, LPCWSTR, UINT, int, int, UINT);\nHKL LoadKeyboardLayoutA(LPCSTR, UINT);\nHKL LoadKeyboardLayoutW(LPCWSTR, UINT);\nHMENU LoadMenuA(HINSTANCE, LPCSTR);\nHMENU LoadMenuIndirectA(const(MENUTEMPLATE)*);\nHMENU LoadMenuIndirectW(const(MENUTEMPLATE)*);\nHMENU LoadMenuW(HINSTANCE, LPCWSTR);\nint LoadStringA(HINSTANCE, UINT, LPSTR, int);\nint LoadStringW(HINSTANCE, UINT, LPWSTR, int);\nBOOL LockWindowUpdate(HWND);\nint LookupIconIdFromDirectory(PBYTE, BOOL);\nint LookupIconIdFromDirectoryEx(PBYTE, BOOL, int, int, UINT);\nBOOL MapDialogRect(HWND, LPRECT);\nUINT MapVirtualKeyA(UINT, UINT);\nUINT MapVirtualKeyExA(UINT, UINT, HKL);\nUINT MapVirtualKeyExW(UINT, UINT, HKL);\nUINT MapVirtualKeyW(UINT, UINT);\nint MapWindowPoints(HWND, HWND, LPPOINT, UINT);\nint MenuItemFromPoint(HWND, HMENU, POINT);\nBOOL MessageBeep(UINT);\nint MessageBoxA(HWND, LPCSTR, LPCSTR, UINT);\nint MessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT);\nint MessageBoxExA(HWND, LPCSTR, LPCSTR, UINT, WORD);\nint MessageBoxExW(HWND, LPCWSTR, LPCWSTR, UINT, WORD);\nint MessageBoxIndirectA(const(MSGBOXPARAMSA)*);\nint MessageBoxIndirectW(const(MSGBOXPARAMSW)*);\nBOOL ModifyMenuA(HMENU, UINT, UINT, UINT_PTR, LPCSTR);\nBOOL ModifyMenuW(HMENU, UINT, UINT, UINT_PTR, LPCWSTR);\nvoid mouse_event(DWORD, DWORD, DWORD, DWORD, ULONG_PTR);\nBOOL MoveWindow(HWND, int, int, int, int, BOOL);\nDWORD MsgWaitForMultipleObjects(DWORD, const(HANDLE)*, BOOL, DWORD, DWORD);\nDWORD MsgWaitForMultipleObjectsEx(DWORD, const(HANDLE)*, DWORD, DWORD, DWORD);\nDWORD OemKeyScan(WORD);\nBOOL OemToCharA(LPCSTR, LPSTR);\nBOOL OemToCharBuffA(LPCSTR, LPSTR, DWORD);\nBOOL OemToCharBuffW(LPCSTR, LPWSTR, DWORD);\nBOOL OemToCharW(LPCSTR, LPWSTR);\nBOOL OffsetRect(LPRECT, int, int);\nBOOL OpenClipboard(HWND);\nHDESK OpenDesktopA(LPSTR, DWORD, BOOL, DWORD);\nHDESK OpenDesktopW(LPWSTR, DWORD, BOOL, DWORD);\nBOOL OpenIcon(HWND);\nHDESK OpenInputDesktop(DWORD, BOOL, DWORD);\nHWINSTA OpenWindowStationA(LPSTR, BOOL, DWORD);\nHWINSTA OpenWindowStationW(LPWSTR, BOOL, DWORD);\nBOOL PaintDesktop(HDC);\nBOOL PeekMessageA(LPMSG, HWND, UINT, UINT, UINT);\nBOOL PeekMessageW(LPMSG, HWND, UINT, UINT, UINT);\nBOOL PostMessageA(HWND, UINT, WPARAM, LPARAM);\nBOOL PostMessageW(HWND, UINT, WPARAM, LPARAM);\nvoid PostQuitMessage(int);\nBOOL PostThreadMessageA(DWORD, UINT, WPARAM, LPARAM);\nBOOL PostThreadMessageW(DWORD, UINT, WPARAM, LPARAM);\nBOOL PtInRect(LPCRECT, POINT);\nHWND RealChildWindowFromPoint(HWND, POINT);\nUINT RealGetWindowClassA(HWND, LPSTR, UINT);\nUINT RealGetWindowClassW(HWND, LPWSTR, UINT);\nBOOL RedrawWindow(HWND, LPCRECT, HRGN, UINT);\nATOM RegisterClassA(const(WNDCLASSA)*);\nATOM RegisterClassW(const(WNDCLASSW)*);\nATOM RegisterClassExA(const(WNDCLASSEXA)*);\nATOM RegisterClassExW(const(WNDCLASSEXW)*);\nUINT RegisterClipboardFormatA(LPCSTR);\nUINT RegisterClipboardFormatW(LPCWSTR);\nBOOL RegisterHotKey(HWND, int, UINT, UINT);\nUINT RegisterWindowMessageA(LPCSTR);\nUINT RegisterWindowMessageW(LPCWSTR);\nBOOL ReleaseCapture();\nint ReleaseDC(HWND, HDC);\nBOOL RemoveMenu(HMENU, UINT, UINT);\nHANDLE RemovePropA(HWND, LPCSTR);\nHANDLE RemovePropW(HWND, LPCWSTR);\nBOOL ReplyMessage(LRESULT);\nBOOL ScreenToClient(HWND, LPPOINT);\nBOOL ScrollDC(HDC, int, int, LPCRECT, LPCRECT, HRGN, LPRECT);\nBOOL ScrollWindow(HWND, int, int, LPCRECT, LPCRECT);\nint ScrollWindowEx(HWND, int, int, LPCRECT, LPCRECT, HRGN, LPRECT, UINT);\nLONG SendDlgItemMessageA(HWND, int, UINT, WPARAM, LPARAM);\nLONG SendDlgItemMessageW(HWND, int, UINT, WPARAM, LPARAM);\nLRESULT SendMessageA(HWND, UINT, WPARAM, LPARAM);\nBOOL SendMessageCallbackA(HWND, UINT, WPARAM, LPARAM, SENDASYNCPROC, ULONG_PTR);\nBOOL SendMessageCallbackW(HWND, UINT, WPARAM, LPARAM, SENDASYNCPROC, ULONG_PTR);\nLRESULT SendMessageTimeoutA(HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD);\nLRESULT SendMessageTimeoutW(HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD);\nLRESULT SendMessageW(HWND, UINT, WPARAM, LPARAM);\nBOOL SendNotifyMessageA(HWND, UINT, WPARAM, LPARAM);\nBOOL SendNotifyMessageW(HWND, UINT, WPARAM, LPARAM);\nHWND SetActiveWindow(HWND);\nHWND SetCapture(HWND hWnd);\nBOOL SetCaretBlinkTime(UINT);\nBOOL SetCaretPos(int, int);\nDWORD SetClassLongA(HWND, int, LONG);\nDWORD SetClassLongW(HWND, int, LONG);\nWORD SetClassWord(HWND, int, WORD);\nHANDLE SetClipboardData(UINT, HANDLE);\nHWND SetClipboardViewer(HWND);\nHCURSOR SetCursor(HCURSOR);\nBOOL SetCursorPos(int, int);\nvoid SetDebugErrorLevel(DWORD);\nBOOL SetDlgItemInt(HWND, int, UINT, BOOL);\nBOOL SetDlgItemTextA(HWND, int, LPCSTR);\nBOOL SetDlgItemTextW(HWND, int, LPCWSTR);\nBOOL SetDoubleClickTime(UINT);\nHWND SetFocus(HWND);\nBOOL SetForegroundWindow(HWND);\nBOOL SetKeyboardState(PBYTE);\nBOOL SetMenu(HWND, HMENU);\nBOOL SetMenuContextHelpId(HMENU, DWORD);\nBOOL SetMenuDefaultItem(HMENU, UINT, UINT);\nBOOL SetMenuInfo(HMENU, LPCMENUINFO);\nBOOL SetMenuItemBitmaps(HMENU, UINT, UINT, HBITMAP, HBITMAP);\nBOOL SetMenuItemInfoA(HMENU, UINT, BOOL, LPCMENUITEMINFOA);\nBOOL SetMenuItemInfoW(HMENU, UINT, BOOL, LPCMENUITEMINFOW);\nLPARAM SetMessageExtraInfo(LPARAM);\nBOOL SetMessageQueue(int);\nHWND SetParent(HWND, HWND);\nBOOL SetProcessWindowStation(HWINSTA);\nBOOL SetPropA(HWND, LPCSTR, HANDLE);\nBOOL SetPropW(HWND, LPCWSTR, HANDLE);\nBOOL SetRect(LPRECT, int, int, int, int);\nBOOL SetRectEmpty(LPRECT);\nint SetScrollInfo(HWND, int, LPCSCROLLINFO, BOOL);\nint SetScrollPos(HWND, int, int, BOOL);\nBOOL SetScrollRange(HWND, int, int, int, BOOL);\nBOOL SetSysColors(int, const(INT)*, const(COLORREF)*);\nBOOL SetSystemCursor(HCURSOR, DWORD);\nBOOL SetThreadDesktop(HDESK);\nUINT_PTR SetTimer(HWND, UINT_PTR, UINT, TIMERPROC);\nBOOL SetUserObjectInformationA(HANDLE, int, PVOID, DWORD);\nBOOL SetUserObjectInformationW(HANDLE, int, PVOID, DWORD);\nBOOL SetUserObjectSecurity(HANDLE, PSECURITY_INFORMATION, PSECURITY_DESCRIPTOR);\nBOOL SetWindowContextHelpId(HWND, DWORD);\nLONG SetWindowLongA(HWND, int, LONG);\nLONG SetWindowLongW(HWND, int, LONG);\nBOOL SetWindowPlacement(HWND hWnd, const(WINDOWPLACEMENT)*);\nBOOL SetWindowPos(HWND, HWND, int, int, int, int, UINT);\nint SetWindowRgn(HWND, HRGN, BOOL);\nHHOOK SetWindowsHookA(int, HOOKPROC);\nHHOOK SetWindowsHookW(int, HOOKPROC);\nHHOOK SetWindowsHookExA(int, HOOKPROC, HINSTANCE, DWORD);\nHHOOK SetWindowsHookExW(int, HOOKPROC, HINSTANCE, DWORD);\nBOOL SetWindowTextA(HWND, LPCSTR);\nBOOL SetWindowTextW(HWND, LPCWSTR);\nWORD SetWindowWord(HWND, int, WORD);\nBOOL ShowCaret(HWND);\nint ShowCursor(BOOL);\nBOOL ShowOwnedPopups(HWND, BOOL);\nBOOL ShowScrollBar(HWND, int, BOOL);\nBOOL ShowWindow(HWND, int);\nBOOL ShowWindowAsync(HWND, int);\nBOOL SubtractRect(LPRECT, LPCRECT, LPCRECT);\nBOOL SwapMouseButton(BOOL);\nBOOL SwitchDesktop(HDESK);\nBOOL SystemParametersInfoA(UINT, UINT, PVOID, UINT);\nBOOL SystemParametersInfoW(UINT, UINT, PVOID, UINT);\nLONG TabbedTextOutA(HDC, int, int, LPCSTR, int, int, LPINT, int);\nLONG TabbedTextOutW(HDC, int, int, LPCWSTR, int, int, LPINT, int);\nWORD TileWindows(HWND, UINT, LPCRECT, UINT, const(HWND)*);\nint ToAscii(UINT, UINT, PBYTE, LPWORD, UINT);\nint ToAsciiEx(UINT, UINT, PBYTE, LPWORD, UINT, HKL);\nint ToUnicode(UINT, UINT, PBYTE, LPWSTR, int, UINT);\nint ToUnicodeEx(UINT, UINT, PBYTE, LPWSTR, int, UINT, HKL);\nBOOL TrackMouseEvent(LPTRACKMOUSEEVENT);\nBOOL TrackPopupMenu(HMENU, UINT, int, int, int, HWND, LPCRECT);\nBOOL TrackPopupMenuEx(HMENU, UINT, int, int, HWND, LPTPMPARAMS);\nint TranslateAcceleratorA(HWND, HACCEL, LPMSG);\nint TranslateAcceleratorW(HWND, HACCEL, LPMSG);\nBOOL TranslateMDISysAccel(HWND, LPMSG);\nBOOL TranslateMessage(const(MSG)*);\nBOOL UnhookWindowsHook(int, HOOKPROC);\nBOOL UnhookWindowsHookEx(HHOOK);\nBOOL UnionRect(LPRECT, LPCRECT, LPCRECT);\nBOOL UnloadKeyboardLayout(HKL);\nBOOL UnregisterClassA(LPCSTR, HINSTANCE);\nBOOL UnregisterClassW(LPCWSTR, HINSTANCE);\nBOOL UnregisterHotKey(HWND, int);\nBOOL UpdateWindow(HWND);\nBOOL ValidateRect(HWND, LPCRECT);\nBOOL ValidateRgn(HWND, HRGN);\nSHORT VkKeyScanA(CHAR);\nSHORT VkKeyScanExA(CHAR, HKL);\nSHORT VkKeyScanExW(WCHAR, HKL);\nSHORT VkKeyScanW(WCHAR);\nDWORD WaitForInputIdle(HANDLE, DWORD);\nBOOL WaitMessage();\nHWND WindowFromDC(HDC hDC);\nHWND WindowFromPoint(POINT);\nUINT WinExec(LPCSTR, UINT);\nBOOL WinHelpA(HWND, LPCSTR, UINT, ULONG_PTR);\nBOOL WinHelpW(HWND, LPCWSTR, UINT, ULONG_PTR);\n\nextern (C) {\n    int wsprintfA(LPSTR, LPCSTR, ...);\n    int wsprintfW(LPWSTR, LPCWSTR, ...);\n}\n\n\n// These shouldn't be necessary for D.\nalias TypeDef!(char*) va_list_;\nint wvsprintfA(LPSTR, LPCSTR, va_list_ arglist);\nint wvsprintfW(LPWSTR, LPCWSTR, va_list_ arglist);\n\nenum : DWORD {\n    MONITOR_DEFAULTTONULL,\n    MONITOR_DEFAULTTOPRIMARY,\n    MONITOR_DEFAULTTONEAREST // = 2\n}\nenum MONITORINFOF_PRIMARY = 1;\n\nenum EDS_RAWMODE = 0x00000002;\n\nenum {\n    ISMEX_NOSEND   = 0,\n    ISMEX_SEND     = 1,\n    ISMEX_NOTIFY   = 2,\n    ISMEX_CALLBACK = 4,\n    ISMEX_REPLIED  = 8\n}\n\nstruct TITLEBARINFO {\n    DWORD cbSize = TITLEBARINFO.sizeof;\n    RECT  rcTitleBar;\n    DWORD[CCHILDREN_TITLEBAR+1] rgstate;\n}\nalias TITLEBARINFO* PTITLEBARINFO, LPTITLEBARINFO;\n\nstatic if (_WIN32_WINNT >= 0x501) { // *** correct?\n    struct FLASHWINFO {\n        UINT  cbSize = this.sizeof;\n        HWND  hwnd;\n        DWORD dwFlags;\n        UINT  uCount;\n        DWORD dwTimeout;\n    }\n    alias FLASHWINFO* PFLASHWINFO;\n}\n\nenum DWORD ASFW_ANY = -1;\nenum : UINT {\n    LSFW_LOCK = 1,\n    LSFW_UNLOCK\n}\nenum {\n    GMMP_USE_DISPLAY_POINTS = 1,\n    GMMP_USE_HIGH_RESOLUTION_POINTS\n}\n\nstruct MOUSEMOVEPOINT {\n    int x;\n    int y;\n    DWORD time;\n    ULONG_PTR dwExtraInfo;\n}\nalias MOUSEMOVEPOINT* PMOUSEMOVEPOINT, LPMOUSEMOVEPOINT;\n\nenum {\n    MIM_MAXHEIGHT       =  1,\n    MIM_BACKGROUND      =  2,\n    MIM_HELPID          =  4,\n    MIM_MENUDATA        =  8,\n    MIM_STYLE           = 16,\n    MIM_APPLYTOSUBMENUS = 0x80000000L\n}\n\nenum {\n    MNS_NOCHECK     = 0x80000000,\n    MNS_MODELESS    = 0x40000000,\n    MNS_DRAGDROP    = 0x20000000,\n    MNS_AUTODISMISS = 0x10000000,\n    MNS_NOTIFYBYPOS = 0x08000000,\n    MNS_CHECKORBMP  = 0x04000000\n}\n\nenum {\n    PM_QS_INPUT       = (QS_INPUT << 16),\n    PM_QS_POSTMESSAGE = ((QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER) << 16),\n    PM_QS_PAINT       = (QS_PAINT << 16),\n    PM_QS_SENDMESSAGE = (QS_SENDMESSAGE << 16)\n}\n/*\n#define WM_GETOBJECT 0x003D\n#define WM_CHANGEUISTATE 0x0127\n#define WM_UPDATEUISTATE 0x0128\n#define WM_QUERYUISTATE 0x0129\n#define WM_UNINITMENUPOPUP 0x0125\n#define WM_MENURBUTTONUP 290\n#define WM_MENUCOMMAND 0x0126\n#define WM_MENUGETOBJECT 0x0124\n#define WM_MENUDRAG 0x0123\n#define WM_APPCOMMAND 0x0319\n#define WM_NCXBUTTONDOWN 171\n#define WM_NCXBUTTONUP 172\n#define WM_NCXBUTTONDBLCLK 173\n#define WM_NCMOUSEHOVER 0x02A0\n#define WM_NCMOUSELEAVE 0x02A2*/\n\nenum {\n    FLASHW_STOP      = 0,\n    FLASHW_CAPTION   = 0x01,\n    FLASHW_TRAY      = 0x02,\n    FLASHW_ALL       = 0x03,\n    FLASHW_TIMER     = 0x04,\n    FLASHW_TIMERNOFG = 0x0C\n}\n\nenum CHILDID_SELF = 0;\n\nenum {\n    OBJID_WINDOW   = 0x00000000,\n    OBJID_SOUND    = 0xFFFFFFF5,\n    OBJID_ALERT    = 0xFFFFFFF6,\n    OBJID_CURSOR   = 0xFFFFFFF7,\n    OBJID_CARET    = 0xFFFFFFF8,\n    OBJID_SIZEGRIP = 0xFFFFFFF9,\n    OBJID_HSCROLL  = 0xFFFFFFFA,\n    OBJID_VSCROLL  = 0xFFFFFFFB,\n    OBJID_CLIENT   = 0xFFFFFFFC,\n    OBJID_MENU     = 0xFFFFFFFD,\n    OBJID_TITLEBAR = 0xFFFFFFFE,\n    OBJID_SYSMENU  = 0xFFFFFFFF\n}\n\nenum {\n    GUI_CARETBLINKING  = 0x0001,\n    GUI_INMOVESIZE     = 0x0002,\n    GUI_INMENUMODE     = 0x0004,\n    GUI_SYSTEMMENUMODE = 0x0008,\n    GUI_POPUPMENUMODE  = 0x0010\n}\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum GUI_16BITTASK = 0x0020;\n}\n\nenum {\n    WINEVENT_OUTOFCONTEXT   = 0x00,\n    WINEVENT_SKIPOWNTHREAD  = 0x01,\n    WINEVENT_SKIPOWNPROCESS = 0x02,\n    WINEVENT_INCONTEXT      = 0x04\n}\n\nenum {\n    AW_HOR_POSITIVE = 0x00000001,\n    AW_HOR_NEGATIVE = 0x00000002,\n    AW_VER_POSITIVE = 0x00000004,\n    AW_VER_NEGATIVE = 0x00000008,\n    AW_CENTER       = 0x00000010,\n    AW_HIDE         = 0x00010000,\n    AW_ACTIVATE     = 0x00020000,\n    AW_SLIDE        = 0x00040000,\n    AW_BLEND        = 0x00080000\n}\n\nenum {\n    DEVICE_NOTIFY_WINDOW_HANDLE  = 0x00000000,\n    DEVICE_NOTIFY_SERVICE_HANDLE = 0x00000001\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004;\n}\n\nenum : DWORD {\n    EVENT_MIN                          = 0x00000001,\n    EVENT_SYSTEM_SOUND                 = 0x00000001,\n    EVENT_SYSTEM_ALERT,\n    EVENT_SYSTEM_FOREGROUND,\n    EVENT_SYSTEM_MENUSTART,\n    EVENT_SYSTEM_MENUEND,\n    EVENT_SYSTEM_MENUPOPUPSTART,\n    EVENT_SYSTEM_MENUPOPUPEND,\n    EVENT_SYSTEM_CAPTURESTART,\n    EVENT_SYSTEM_CAPTUREEND,\n    EVENT_SYSTEM_MOVESIZESTART,\n    EVENT_SYSTEM_MOVESIZEEND,\n    EVENT_SYSTEM_CONTEXTHELPSTART,\n    EVENT_SYSTEM_CONTEXTHELPEND,\n    EVENT_SYSTEM_DRAGDROPSTART,\n    EVENT_SYSTEM_DRAGDROPEND,\n    EVENT_SYSTEM_DIALOGSTART,\n    EVENT_SYSTEM_DIALOGEND,\n    EVENT_SYSTEM_SCROLLINGSTART,\n    EVENT_SYSTEM_SCROLLINGEND,\n    EVENT_SYSTEM_SWITCHSTART,\n    EVENT_SYSTEM_SWITCHEND,\n    EVENT_SYSTEM_MINIMIZESTART,\n    EVENT_SYSTEM_MINIMIZEEND,       // = 0x00000017\n    EVENT_OBJECT_CREATE                = 0x00008000,\n    EVENT_OBJECT_DESTROY,\n    EVENT_OBJECT_SHOW,\n    EVENT_OBJECT_HIDE,\n    EVENT_OBJECT_REORDER,\n    EVENT_OBJECT_FOCUS,\n    EVENT_OBJECT_SELECTION,\n    EVENT_OBJECT_SELECTIONADD,\n    EVENT_OBJECT_SELECTIONREMOVE,\n    EVENT_OBJECT_SELECTIONWITHIN,\n    EVENT_OBJECT_STATECHANGE,\n    EVENT_OBJECT_LOCATIONCHANGE,\n    EVENT_OBJECT_NAMECHANGE,\n    EVENT_OBJECT_DESCRIPTIONCHANGE,\n    EVENT_OBJECT_VALUECHANGE,\n    EVENT_OBJECT_PARENTCHANGE,\n    EVENT_OBJECT_HELPCHANGE,\n    EVENT_OBJECT_DEFACTIONCHANGE,\n    EVENT_OBJECT_ACCELERATORCHANGE, // = 0x00008012\n    EVENT_MAX                          = 0x7FFFFFFF\n}\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum : DWORD {\n        EVENT_CONSOLE_CARET                = 0x00004000,\n        EVENT_CONSOLE_UPDATE_REGION,\n        EVENT_CONSOLE_UPDATE_SIMPLE,\n        EVENT_CONSOLE_UPDATE_SCROLL,\n        EVENT_CONSOLE_LAYOUT,\n        EVENT_CONSOLE_START_APPLICATION,\n        EVENT_CONSOLE_END_APPLICATION,  // = 0x00004007\n    }\n\n    enum : LONG {\n        CONSOLE_CARET_SELECTION  = 1,\n        CONSOLE_CARET_VISIBLE // = 2\n    }\n    enum LONG CONSOLE_APPLICATION_16BIT = 1;\n}\n\nenum {\n    LWA_COLORKEY = 1,\n    LWA_ALPHA\n}\nenum {\n    ULW_COLORKEY = 1,\n    ULW_ALPHA    = 2,\n    ULW_OPAQUE   = 4\n}\nenum {\n    GR_GDIOBJECTS,\n    GR_USEROBJECTS\n}\n\nenum {\n    XBUTTON1 = 1,\n    XBUTTON2\n}\n\nstruct GUITHREADINFO {\n    DWORD cbSize = this.sizeof;\n    DWORD flags;\n    HWND  hwndActive;\n    HWND  hwndFocus;\n    HWND  hwndCapture;\n    HWND  hwndMenuOwner;\n    HWND  hwndMoveSize;\n    HWND  hwndCaret;\n    RECT  rcCaret;\n}\nalias GUITHREADINFO* PGUITHREADINFO, LPGUITHREADINFO;\nextern (Windows) {\n    alias void function(HWINEVENTHOOK, DWORD, HWND, LONG, LONG, DWORD, DWORD) WINEVENTPROC;\n}\n// *** line 4680 of MinGW 4.0\nint BroadcastSystemMessageA(DWORD, LPDWORD, UINT, WPARAM, LPARAM);\nint BroadcastSystemMessageW(DWORD, LPDWORD, UINT, WPARAM, LPARAM);\n\nUINT SendInput(UINT, LPINPUT, int);\nBOOL EnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);\nBOOL GetMonitorInfoA(HMONITOR, LPMONITORINFO);\nextern(D) BOOL GetMonitorInfoA(HMONITOR m, LPMONITORINFOEXA mi) { return GetMonitorInfoA(m, cast(LPMONITORINFO)mi); }\nBOOL GetMonitorInfoW(HMONITOR, LPMONITORINFO);\nextern(D) BOOL GetMonitorInfoW(HMONITOR m, LPMONITORINFOEXW mi) { return GetMonitorInfoW(m, cast(LPMONITORINFO)mi); }\nHMONITOR MonitorFromPoint(POINT, DWORD);\nHMONITOR MonitorFromRect(LPCRECT, DWORD);\nHMONITOR MonitorFromWindow(HWND, DWORD);\nBOOL AllowSetForegroundWindow(DWORD);\nBOOL AnimateWindow(HWND, DWORD, DWORD);\nBOOL EndTask(HWND, BOOL, BOOL);\nBOOL EnumDisplaySettingsExA(LPCSTR, DWORD, LPDEVMODEA, DWORD);\nBOOL EnumDisplaySettingsExW(LPCWSTR, DWORD, LPDEVMODEW, DWORD);\nDWORD GetClipboardSequenceNumber();\nDWORD GetGuiResources(HANDLE, DWORD);\nBOOL GetGUIThreadInfo(DWORD, LPGUITHREADINFO);\n\nint GetMouseMovePointsEx(UINT, LPMOUSEMOVEPOINT, LPMOUSEMOVEPOINT, int, DWORD);\nBOOL GetProcessDefaultLayout(DWORD*);\nHWND GetShellWindow();\nBOOL IsHungAppWindow(HWND);\nDWORD InSendMessageEx(LPVOID);\nBOOL LockSetForegroundWindow(UINT);\nBOOL LockWorkStation();\nvoid NotifyWinEvent(DWORD, HWND, LONG, LONG);\nHDEVNOTIFY RegisterDeviceNotificationA(HANDLE, LPVOID, DWORD);\nHDEVNOTIFY RegisterDeviceNotificationW(HANDLE, LPVOID, DWORD);\nBOOL SetProcessDefaultLayout(DWORD);\nHWINEVENTHOOK SetWinEventHook(UINT, UINT, HMODULE, WINEVENTPROC, DWORD, DWORD, UINT);\nvoid SwitchToThisWindow(HWND, BOOL);\nBOOL SetLayeredWindowAttributes(HWND, COLORREF, BYTE, DWORD);\nBOOL UpdateLayeredWindow(HWND, HDC, POINT*, SIZE*, HDC, POINT*, COLORREF, BLENDFUNCTION*, DWORD);\nBOOL UserHandleGrantAccess(HANDLE, HANDLE, BOOL);\nBOOL UnhookWinEvent(HWINEVENTHOOK);\nBOOL UnregisterDeviceNotification(HANDLE);\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    int BroadcastSystemMessageExA(DWORD, LPDWORD, UINT, WPARAM, LPARAM, PBSMINFO);\n    int BroadcastSystemMessageExW(DWORD, LPDWORD, UINT, WPARAM, LPARAM, PBSMINFO);\n    LRESULT DefRawInputProc(PRAWINPUT*, INT, UINT);\n    BOOL FlashWindowEx(PFLASHWINFO);\n    BOOL GetLayeredWindowAttributes(HWND, COLORREF*, BYTE*, DWORD*);\n    UINT GetRawInputBuffer(PRAWINPUT, PUINT, UINT);\n    UINT GetRawInputData(HRAWINPUT, UINT, LPVOID, PUINT, UINT);\n    UINT GetRawInputDeviceInfoA(HANDLE, UINT, LPVOID, PUINT);\n    UINT GetRawInputDeviceInfoW(HANDLE, UINT, LPVOID, PUINT);\n    UINT GetRawInputDeviceList(PRAWINPUTDEVICELIST, PUINT, UINT);\n    UINT GetRegisteredRawInputDevices(PRAWINPUTDEVICE, PUINT, UINT);\n    BOOL IsGUIThread(BOOL);\n    BOOL IsWinEventHookInstalled(DWORD);\n    BOOL PrintWindow(HWND, HDC, UINT);\n    BOOL RegisterRawInputDevices(PCRAWINPUTDEVICE, UINT, UINT);\n}\n\nversion (Win64) {\n    ULONG_PTR GetClassLongPtrA(HWND, int);\n    ULONG_PTR GetClassLongPtrW(HWND, int);\n    ULONG_PTR SetClassLongPtrA(HWND, int, LONG_PTR);\n    ULONG_PTR SetClassLongPtrW(HWND, int, LONG_PTR);\n    LONG_PTR GetWindowLongPtrA(HWND, int);\n    LONG_PTR GetWindowLongPtrW(HWND, int);\n    LONG_PTR SetWindowLongPtrA(HWND, int, LONG_PTR);\n    LONG_PTR SetWindowLongPtrW(HWND, int, LONG_PTR);\n} else {\n    alias GetClassLongA GetClassLongPtrA;\n    alias GetClassLongW GetClassLongPtrW;\n    alias SetClassLongA SetClassLongPtrA;\n    alias SetClassLongW SetClassLongPtrW;\n    alias GetWindowLongA GetWindowLongPtrA;\n    alias GetWindowLongW GetWindowLongPtrW;\n    alias SetWindowLongA SetWindowLongPtrA;\n    alias SetWindowLongW SetWindowLongPtrW;\n}\n\n\n// -----\n// Aliases for Unicode or Ansi\nversion (Unicode) {\n    alias EDITWORDBREAKPROCW EDITWORDBREAKPROC;\n    alias PROPENUMPROCW PROPENUMPROC;\n    alias PROPENUMPROCEXW PROPENUMPROCEX;\n    alias DESKTOPENUMPROCW DESKTOPENUMPROC;\n    alias WINSTAENUMPROCW WINSTAENUMPROC;\n    alias MAKEINTRESOURCEW MAKEINTRESOURCE;\n\n    alias WNDCLASSW WNDCLASS;\n    alias WNDCLASSEXW WNDCLASSEX;\n    alias MENUITEMINFOW MENUITEMINFO;\n    alias LPCMENUITEMINFOW LPCMENUITEMINFO;\n    alias MSGBOXPARAMSW MSGBOXPARAMS;\n    alias HIGHCONTRASTW HIGHCONTRAST;\n    alias SERIALKEYSW SERIALKEYS;\n    alias SOUNDSENTRYW SOUNDSENTRY;\n    alias CREATESTRUCTW CREATESTRUCT;\n    alias CBT_CREATEWNDW CBT_CREATEWND;\n    alias MDICREATESTRUCTW MDICREATESTRUCT;\n    alias MULTIKEYHELPW MULTIKEYHELP;\n    alias MONITORINFOEXW MONITORINFOEX;\n    alias ICONMETRICSW ICONMETRICS;\n    alias NONCLIENTMETRICSW NONCLIENTMETRICS;\n\n    alias AppendMenuW AppendMenu;\n    alias BroadcastSystemMessageW BroadcastSystemMessage;\n    static if (_WIN32_WINNT >= 0x501) {\n        alias BroadcastSystemMessageExW BroadcastSystemMessageEx;\n    }\n    alias CallMsgFilterW CallMsgFilter;\n    alias CallWindowProcW CallWindowProc;\n    alias ChangeMenuW ChangeMenu;\n    alias CharLowerW CharLower;\n    alias CharLowerBuffW CharLowerBuff;\n    alias CharNextW CharNext;\n    alias CharNextExW CharNextEx;\n    alias CharPrevW CharPrev;\n    alias CharPrevExW CharPrevEx;\n    alias CharToOemW CharToOem;\n    alias CharToOemBuffW CharToOemBuff;\n    alias CharUpperW CharUpper;\n    alias CharUpperBuffW CharUpperBuff;\n    alias CopyAcceleratorTableW CopyAcceleratorTable;\n    alias CreateAcceleratorTableW CreateAcceleratorTable;\n    alias CreateDialogW CreateDialog;\n    alias CreateDialogIndirectW CreateDialogIndirect;\n    alias CreateDialogIndirectParamW CreateDialogIndirectParam;\n    alias CreateDialogParamW CreateDialogParam;\n    alias CreateMDIWindowW CreateMDIWindow;\n    alias CreateWindowW CreateWindow;\n    alias CreateWindowExW CreateWindowEx;\n    alias CreateWindowStationW CreateWindowStation;\n    alias DefDlgProcW DefDlgProc;\n    alias DefFrameProcW DefFrameProc;\n    alias DefMDIChildProcW DefMDIChildProc;\n    alias DefWindowProcW DefWindowProc;\n    alias DialogBoxW DialogBox;\n    alias DialogBoxIndirectW DialogBoxIndirect;\n    alias DialogBoxIndirectParamW DialogBoxIndirectParam;\n    alias DialogBoxParamW DialogBoxParam;\n    alias DispatchMessageW DispatchMessage;\n    alias DlgDirListW DlgDirList;\n    alias DlgDirListComboBoxW DlgDirListComboBox;\n    alias DlgDirSelectComboBoxExW DlgDirSelectComboBoxEx;\n    alias DlgDirSelectExW DlgDirSelectEx;\n    alias DrawStateW DrawState;\n    alias DrawTextW DrawText;\n    alias DrawTextExW DrawTextEx;\n    alias EnumDesktopsW EnumDesktops;\n    alias EnumPropsW EnumProps;\n    alias EnumPropsExW EnumPropsEx;\n    alias EnumWindowStationsW EnumWindowStations;\n    alias FindWindowW FindWindow;\n    alias FindWindowExW FindWindowEx;\n    alias GetClassInfoW GetClassInfo;\n    alias GetClassInfoExW GetClassInfoEx;\n    alias GetClassLongW GetClassLong;\n    alias GetClassLongPtrW GetClassLongPtr;\n    alias GetClassNameW GetClassName;\n    alias GetClipboardFormatNameW GetClipboardFormatName;\n    alias GetDlgItemTextW GetDlgItemText;\n    alias GetKeyboardLayoutNameW GetKeyboardLayoutName;\n    alias GetKeyNameTextW GetKeyNameText;\n    alias GetMenuItemInfoW GetMenuItemInfo;\n    alias GetMenuStringW GetMenuString;\n    alias GetMessageW GetMessage;\n    alias GetMonitorInfoW GetMonitorInfo;\n    alias GetPropW GetProp;\n    static if (_WIN32_WINNT >= 0x501) {\n        alias GetRawInputDeviceInfoW GetRawInputDeviceInfo;\n    }\n    alias GetTabbedTextExtentW GetTabbedTextExtent;\n    alias GetUserObjectInformationW GetUserObjectInformation;\n    alias GetWindowLongW GetWindowLong;\n    alias GetWindowLongPtrW GetWindowLongPtr;\n    alias GetWindowTextW GetWindowText;\n    alias GetWindowTextLengthW GetWindowTextLength;\n    alias GetAltTabInfoW GetAltTabInfo;\n    alias GetWindowModuleFileNameW GetWindowModuleFileName;\n    alias GrayStringW GrayString;\n    alias InsertMenuW InsertMenu;\n    alias InsertMenuItemW InsertMenuItem;\n    alias IsCharAlphaW IsCharAlpha;\n    alias IsCharAlphaNumericW IsCharAlphaNumeric;\n    alias IsCharLowerW IsCharLower;\n    alias IsCharUpperW IsCharUpper;\n    alias IsDialogMessageW IsDialogMessage;\n    alias LoadAcceleratorsW LoadAccelerators;\n    alias LoadBitmapW LoadBitmap;\n    alias LoadCursorW LoadCursor;\n    alias LoadCursorFromFileW LoadCursorFromFile;\n    alias LoadIconW LoadIcon;\n    alias LoadImageW LoadImage;\n    alias LoadKeyboardLayoutW LoadKeyboardLayout;\n    alias LoadMenuW LoadMenu;\n    alias LoadMenuIndirectW LoadMenuIndirect;\n    alias LoadStringW LoadString;\n    alias MapVirtualKeyW MapVirtualKey;\n    alias MapVirtualKeyExW MapVirtualKeyEx;\n    alias MessageBoxW MessageBox;\n    alias MessageBoxExW MessageBoxEx;\n    alias MessageBoxIndirectW MessageBoxIndirect;\n    alias ModifyMenuW ModifyMenu;\n    alias OemToCharW OemToChar;\n    alias OemToCharBuffW OemToCharBuff;\n    alias OpenDesktopW OpenDesktop;\n    alias OpenWindowStationW OpenWindowStation;\n    alias PeekMessageW PeekMessage;\n    alias PostMessageW PostMessage;\n    alias PostThreadMessageW PostThreadMessage;\n    alias RealGetWindowClassW RealGetWindowClass;\n    alias RegisterClassW RegisterClass;\n    alias RegisterClassExW RegisterClassEx;\n    alias RegisterClipboardFormatW RegisterClipboardFormat;\n    alias RegisterDeviceNotificationW RegisterDeviceNotification;\n    alias RegisterWindowMessageW RegisterWindowMessage;\n    alias RemovePropW RemoveProp;\n    alias SendDlgItemMessageW SendDlgItemMessage;\n    alias SendMessageW SendMessage;\n    alias SendMessageCallbackW SendMessageCallback;\n    alias SendMessageTimeoutW SendMessageTimeout;\n    alias SendNotifyMessageW SendNotifyMessage;\n    alias SetClassLongW SetClassLong;\n    alias SetClassLongPtrW SetClassLongPtr;\n    alias SetDlgItemTextW SetDlgItemText;\n    alias SetMenuItemInfoW SetMenuItemInfo;\n    alias SetPropW SetProp;\n    alias SetUserObjectInformationW SetUserObjectInformation;\n    alias SetWindowLongW SetWindowLong;\n    alias SetWindowLongPtrW SetWindowLongPtr;\n    alias SetWindowsHookW SetWindowsHook;\n    alias SetWindowsHookExW SetWindowsHookEx;\n    alias SetWindowTextW SetWindowText;\n    alias SystemParametersInfoW SystemParametersInfo;\n    alias TabbedTextOutW TabbedTextOut;\n    alias TranslateAcceleratorW TranslateAccelerator;\n    alias UnregisterClassW UnregisterClass;\n    alias VkKeyScanW VkKeyScan;\n    alias VkKeyScanExW VkKeyScanEx;\n    alias WinHelpW WinHelp;\n    alias wsprintfW wsprintf;\n    alias wvsprintfW wvsprintf;\n\n    alias ChangeDisplaySettingsW ChangeDisplaySettings;\n    alias ChangeDisplaySettingsExW ChangeDisplaySettingsEx;\n    alias CreateDesktopW CreateDesktop;\n    alias EnumDisplaySettingsW EnumDisplaySettings;\n    alias EnumDisplaySettingsExW EnumDisplaySettingsEx;\n    alias EnumDisplayDevicesW EnumDisplayDevices;\n\n} else { // ANSI\n\n    alias EDITWORDBREAKPROCA EDITWORDBREAKPROC;\n    alias PROPENUMPROCA PROPENUMPROC;\n    alias PROPENUMPROCEXA PROPENUMPROCEX;\n    alias DESKTOPENUMPROCA DESKTOPENUMPROC;\n    alias WINSTAENUMPROCA WINSTAENUMPROC;\n    alias MAKEINTRESOURCEA MAKEINTRESOURCE;\n\n    alias WNDCLASSA WNDCLASS;\n    alias WNDCLASSEXA WNDCLASSEX;\n    alias MENUITEMINFOA MENUITEMINFO;\n    alias LPCMENUITEMINFOA LPCMENUITEMINFO;\n    alias MSGBOXPARAMSA MSGBOXPARAMS;\n    alias HIGHCONTRASTA HIGHCONTRAST;\n    alias SERIALKEYSA SERIALKEYS;\n    alias SOUNDSENTRYA SOUNDSENTRY;\n    alias CREATESTRUCTA CREATESTRUCT;\n    alias CBT_CREATEWNDA CBT_CREATEWND;\n    alias MDICREATESTRUCTA MDICREATESTRUCT;\n    alias MULTIKEYHELPA MULTIKEYHELP;\n    alias MONITORINFOEXA MONITORINFOEX;\n    alias ICONMETRICSA ICONMETRICS;\n    alias NONCLIENTMETRICSA NONCLIENTMETRICS;\n\n    alias AppendMenuA AppendMenu;\n    alias BroadcastSystemMessageA BroadcastSystemMessage;\n    static if (_WIN32_WINNT >= 0x501) {\n        alias BroadcastSystemMessageExA BroadcastSystemMessageEx;\n    }\n    alias CallMsgFilterA CallMsgFilter;\n    alias CallWindowProcA CallWindowProc;\n    alias ChangeMenuA ChangeMenu;\n    alias CharLowerA CharLower;\n    alias CharLowerBuffA CharLowerBuff;\n    alias CharNextA CharNext;\n    alias CharNextExA CharNextEx;\n    alias CharPrevA CharPrev;\n    alias CharPrevExA CharPrevEx;\n    alias CharToOemA CharToOem;\n    alias CharToOemBuffA CharToOemBuff;\n    alias CharUpperA CharUpper;\n    alias CharUpperBuffA CharUpperBuff;\n    alias CopyAcceleratorTableA CopyAcceleratorTable;\n    alias CreateAcceleratorTableA CreateAcceleratorTable;\n    alias CreateDialogA CreateDialog;\n    alias CreateDialogIndirectA CreateDialogIndirect;\n    alias CreateDialogIndirectParamA CreateDialogIndirectParam;\n    alias CreateDialogParamA CreateDialogParam;\n    alias CreateMDIWindowA CreateMDIWindow;\n    alias CreateWindowA CreateWindow;\n    alias CreateWindowExA CreateWindowEx;\n    alias CreateWindowStationA CreateWindowStation;\n    alias DefDlgProcA DefDlgProc;\n    alias DefFrameProcA DefFrameProc;\n    alias DefMDIChildProcA DefMDIChildProc;\n    alias DefWindowProcA DefWindowProc;\n    alias DialogBoxA DialogBox;\n    alias DialogBoxIndirectA DialogBoxIndirect;\n    alias DialogBoxIndirectParamA DialogBoxIndirectParam;\n    alias DialogBoxParamA DialogBoxParam;\n    alias DispatchMessageA DispatchMessage;\n    alias DlgDirListA DlgDirList;\n    alias DlgDirListComboBoxA DlgDirListComboBox;\n    alias DlgDirSelectComboBoxExA DlgDirSelectComboBoxEx;\n    alias DlgDirSelectExA DlgDirSelectEx;\n    alias DrawStateA DrawState;\n    alias DrawTextA DrawText;\n    alias DrawTextExA DrawTextEx;\n    alias EnumDesktopsA EnumDesktops;\n    alias EnumPropsA EnumProps;\n    alias EnumPropsExA EnumPropsEx;\n    alias EnumWindowStationsA EnumWindowStations;\n    alias FindWindowA FindWindow;\n    alias FindWindowExA FindWindowEx;\n    alias GetClassInfoA GetClassInfo;\n    alias GetClassInfoExA GetClassInfoEx;\n    alias GetClassLongA GetClassLong;\n    alias GetClassLongPtrA GetClassLongPtr;\n    alias GetClassNameA GetClassName;\n    alias GetClipboardFormatNameA GetClipboardFormatName;\n    alias GetDlgItemTextA GetDlgItemText;\n    alias GetKeyboardLayoutNameA GetKeyboardLayoutName;\n    alias GetKeyNameTextA GetKeyNameText;\n    alias GetMenuItemInfoA GetMenuItemInfo;\n    alias GetMenuStringA GetMenuString;\n    alias GetMessageA GetMessage;\n    alias GetMonitorInfoA GetMonitorInfo;\n    alias GetPropA GetProp;\n    static if (_WIN32_WINNT >= 0x501) {\n        alias GetRawInputDeviceInfoA GetRawInputDeviceInfo;\n    }\n    alias GetTabbedTextExtentA GetTabbedTextExtent;\n    alias GetUserObjectInformationA GetUserObjectInformation;\n    alias GetWindowLongA GetWindowLong;\n    alias GetWindowLongPtrA GetWindowLongPtr;\n    alias GetWindowTextA GetWindowText;\n    alias GetWindowTextLengthA GetWindowTextLength;\n    alias GetAltTabInfoA GetAltTabInfo;\n    alias GetWindowModuleFileNameA GetWindowModuleFileName;\n    alias GrayStringA GrayString;\n    alias InsertMenuA InsertMenu;\n    alias InsertMenuItemA InsertMenuItem;\n    alias IsCharAlphaA IsCharAlpha;\n    alias IsCharAlphaNumericA IsCharAlphaNumeric;\n    alias IsCharLowerA IsCharLower;\n    alias IsCharUpperA IsCharUpper;\n    alias IsDialogMessageA IsDialogMessage;\n    alias LoadAcceleratorsA LoadAccelerators;\n    alias LoadBitmapA LoadBitmap;\n    alias LoadCursorA LoadCursor;\n    alias LoadIconA LoadIcon;\n    alias LoadCursorFromFileA LoadCursorFromFile;\n    alias LoadImageA LoadImage;\n    alias LoadKeyboardLayoutA LoadKeyboardLayout;\n    alias LoadMenuA LoadMenu;\n    alias LoadMenuIndirectA LoadMenuIndirect;\n    alias LoadStringA LoadString;\n    alias MapVirtualKeyA MapVirtualKey;\n    alias MapVirtualKeyExA MapVirtualKeyEx;\n    alias MessageBoxA MessageBox;\n    alias MessageBoxExA MessageBoxEx;\n    alias MessageBoxIndirectA MessageBoxIndirect;\n    alias ModifyMenuA ModifyMenu;\n    alias OemToCharA OemToChar;\n    alias OemToCharBuffA OemToCharBuff;\n    alias OpenDesktopA OpenDesktop;\n    alias OpenWindowStationA OpenWindowStation;\n    alias PeekMessageA PeekMessage;\n    alias PostMessageA PostMessage;\n    alias PostThreadMessageA PostThreadMessage;\n    alias RealGetWindowClassA RealGetWindowClass;\n    alias RegisterClassA RegisterClass;\n    alias RegisterClassExA RegisterClassEx;\n    alias RegisterClipboardFormatA RegisterClipboardFormat;\n    alias RegisterDeviceNotificationA RegisterDeviceNotification;\n    alias RegisterWindowMessageA RegisterWindowMessage;\n    alias RemovePropA RemoveProp;\n    alias SendDlgItemMessageA SendDlgItemMessage;\n    alias SendMessageA SendMessage;\n    alias SendMessageCallbackA SendMessageCallback;\n    alias SendMessageTimeoutA SendMessageTimeout;\n    alias SendNotifyMessageA SendNotifyMessage;\n    alias SetClassLongA SetClassLong;\n    alias SetClassLongPtrA SetClassLongPtr;\n    alias SetDlgItemTextA SetDlgItemText;\n    alias SetMenuItemInfoA SetMenuItemInfo;\n    alias SetPropA SetProp;\n    alias SetUserObjectInformationA SetUserObjectInformation;\n    alias SetWindowLongA SetWindowLong;\n    alias SetWindowLongPtrA SetWindowLongPtr;\n    alias SetWindowsHookA SetWindowsHook;\n    alias SetWindowsHookExA SetWindowsHookEx;\n    alias SetWindowTextA SetWindowText;\n    alias SystemParametersInfoA SystemParametersInfo;\n    alias TabbedTextOutA TabbedTextOut;\n    alias TranslateAcceleratorA TranslateAccelerator;\n    alias UnregisterClassA UnregisterClass;\n    alias VkKeyScanA VkKeyScan;\n    alias VkKeyScanExA VkKeyScanEx;\n    alias WinHelpA WinHelp;\n    alias wsprintfA wsprintf;\n    alias wvsprintfA wvsprintf;\n\n    alias ChangeDisplaySettingsA ChangeDisplaySettings;\n    alias ChangeDisplaySettingsExA ChangeDisplaySettingsEx;\n    alias CreateDesktopA CreateDesktop;\n    alias EnumDisplaySettingsA EnumDisplaySettings;\n    alias EnumDisplaySettingsExA EnumDisplaySettingsEx;\n    alias EnumDisplayDevicesA EnumDisplayDevices;\n}\n\nalias WNDCLASS* LPWNDCLASS, PWNDCLASS;\nalias WNDCLASSEX* LPWNDCLASSEX, PWNDCLASSEX;\nalias MENUITEMINFO* LPMENUITEMINFO;\nalias MSGBOXPARAMS* PMSGBOXPARAMS, LPMSGBOXPARAMS;\nalias HIGHCONTRAST* LPHIGHCONTRAST;\nalias SERIALKEYS* LPSERIALKEYS;\nalias SOUNDSENTRY* LPSOUNDSENTRY;\nalias CREATESTRUCT* LPCREATESTRUCT;\nalias CBT_CREATEWND* LPCBT_CREATEWND;\nalias MDICREATESTRUCT* LPMDICREATESTRUCT;\nalias MULTIKEYHELP* PMULTIKEYHELP, LPMULTIKEYHELP;\nalias MONITORINFOEX* LPMONITORINFOEX;\nalias ICONMETRICS* LPICONMETRICS;\nalias NONCLIENTMETRICS* LPNONCLIENTMETRICS;\n\nstatic if (_WIN32_WINNT >= 0x501) {\n    enum PW_CLIENTONLY               = 0x00000001;\n    enum RIM_INPUT                   = 0x00000000;\n    enum RIM_INPUTSINK               = 0x00000001;\n    enum RIM_TYPEMOUSE               = 0x00000000;\n    enum RIM_TYPEKEYBOARD            = 0x00000001;\n    enum RIM_TYPEHID                 = 0x00000002;\n    enum MOUSE_MOVE_RELATIVE         = 0x00000000;\n    enum MOUSE_MOVE_ABSOLUTE         = 0x00000001;\n    enum MOUSE_VIRTUAL_DESKTOP       = 0x00000002;\n    enum MOUSE_ATTRIBUTES_CHANGED    = 0x00000004;\n    enum RI_MOUSE_LEFT_BUTTON_DOWN   = 0x0001;\n    enum RI_MOUSE_LEFT_BUTTON_UP     = 0x0002;\n    enum RI_MOUSE_RIGHT_BUTTON_DOWN  = 0x0004;\n    enum RI_MOUSE_RIGHT_BUTTON_UP    = 0x0008;\n    enum RI_MOUSE_MIDDLE_BUTTON_DOWN = 0x0010;\n    enum RI_MOUSE_MIDDLE_BUTTON_UP   = 0x0020;\n    enum RI_MOUSE_BUTTON_1_DOWN = RI_MOUSE_LEFT_BUTTON_DOWN;\n    enum RI_MOUSE_BUTTON_1_UP   = RI_MOUSE_LEFT_BUTTON_UP;\n    enum RI_MOUSE_BUTTON_2_DOWN = RI_MOUSE_RIGHT_BUTTON_DOWN;\n    enum RI_MOUSE_BUTTON_2_UP   = RI_MOUSE_RIGHT_BUTTON_UP;\n    enum RI_MOUSE_BUTTON_3_DOWN = RI_MOUSE_MIDDLE_BUTTON_DOWN;\n    enum RI_MOUSE_BUTTON_3_UP   = RI_MOUSE_MIDDLE_BUTTON_UP;\n    enum RI_MOUSE_BUTTON_4_DOWN = 0x0040;\n    enum RI_MOUSE_BUTTON_4_UP   = 0x0080;\n    enum RI_MOUSE_BUTTON_5_DOWN = 0x0100;\n    enum RI_MOUSE_BUTTON_5_UP   = 0x0200;\n    enum RI_MOUSE_WHEEL         = 0x0400;\n    enum KEYBOARD_OVERRUN_MAKE_CODE = 0x00ff;\n    enum RI_KEY_MAKE            = 0x0000;\n    enum RI_KEY_BREAK           = 0x0001;\n    enum RI_KEY_E0              = 0x0002;\n    enum RI_KEY_E1              = 0x0004;\n    enum RI_KEY_TERMSRV_SET_LED = 0x0008;\n    enum RI_KEY_TERMSRV_SHADOW  = 0x0010;\n\n    enum RID_INPUT          = 0x10000003;\n    enum RID_HEADER         = 0x10000005;\n\n    enum RIDI_PREPARSEDDATA = 0x20000005;\n    enum RIDI_DEVICENAME    = 0x20000007;\n    enum RIDI_DEVICEINFO    = 0x2000000b;\n\n    enum RIDEV_REMOVE       = 0x00000001;\n    enum RIDEV_EXCLUDE      = 0x00000010;\n    enum RIDEV_PAGEONLY     = 0x00000020;\n    enum RIDEV_NOLEGACY     = 0x00000030;\n    enum RIDEV_INPUTSINK    = 0x00000100;\n    enum RIDEV_CAPTUREMOUSE = 0x00000200;\n    enum RIDEV_NOHOTKEYS    = 0x00000200;\n    enum RIDEV_APPKEYS      = 0x00000400;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/winver.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * Authors: Stewart Gordon\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_winver.d)\n */\nmodule core.sys.windows.winver;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"version\");\n\nprivate import core.sys.windows.windef;\n\n// FIXME: type weirdness\nenum {\n    VS_FILE_INFO    =  16,\n    VS_VERSION_INFO =   1,\n    VS_USER_DEFINED = 100\n}\n\nenum {\n    VS_FFI_SIGNATURE     = 0xFEEF04BD,\n    VS_FFI_STRUCVERSION  =    0x10000,\n    VS_FFI_FILEFLAGSMASK =       0x3F\n}\n\nenum {\n    VS_FF_DEBUG        =  1,\n    VS_FF_PRERELEASE   =  2,\n    VS_FF_PATCHED      =  4,\n    VS_FF_PRIVATEBUILD =  8,\n    VS_FF_INFOINFERRED = 16,\n    VS_FF_SPECIALBUILD = 32\n}\n\nenum {\n    VOS_UNKNOWN       =       0,\n    VOS_DOS           = 0x10000,\n    VOS_OS216         = 0x20000,\n    VOS_OS232         = 0x30000,\n    VOS_NT            = 0x40000,\n    VOS__BASE         =       0,\n    VOS__WINDOWS16    =       1,\n    VOS__PM16         =       2,\n    VOS__PM32         =       3,\n    VOS__WINDOWS32    =       4,\n    VOS_DOS_WINDOWS16 = 0x10001,\n    VOS_DOS_WINDOWS32 = 0x10004,\n    VOS_OS216_PM16    = 0x20002,\n    VOS_OS232_PM32    = 0x30003,\n    VOS_NT_WINDOWS32  = 0x40004\n}\n\nenum {\n    VFT_UNKNOWN    = 0,\n    VFT_APP        = 1,\n    VFT_DLL        = 2,\n    VFT_DRV        = 3,\n    VFT_FONT       = 4,\n    VFT_VXD        = 5,\n    VFT_STATIC_LIB = 7\n}\n\nenum {\n    VFT2_UNKNOWN         =  0,\n    VFT2_DRV_PRINTER     =  1,\n    VFT2_DRV_KEYBOARD    =  2,\n    VFT2_DRV_LANGUAGE    =  3,\n    VFT2_DRV_DISPLAY     =  4,\n    VFT2_DRV_MOUSE       =  5,\n    VFT2_DRV_NETWORK     =  6,\n    VFT2_DRV_SYSTEM      =  7,\n    VFT2_DRV_INSTALLABLE =  8,\n    VFT2_DRV_SOUND       =  9,\n    VFT2_DRV_COMM        = 10,\n    VFT2_DRV_INPUTMETHOD = 11,\n    VFT2_FONT_RASTER     =  1,\n    VFT2_FONT_VECTOR     =  2,\n    VFT2_FONT_TRUETYPE   =  3\n}\n\nenum : DWORD {\n    VFFF_ISSHAREDFILE = 1\n}\n\nenum : DWORD {\n    VFF_CURNEDEST    = 1,\n    VFF_FILEINUSE    = 2,\n    VFF_BUFFTOOSMALL = 4\n}\n\nenum : DWORD {\n    VIFF_FORCEINSTALL  = 1,\n    VIFF_DONTDELETEOLD\n}\n\nenum {\n    VIF_TEMPFILE         = 0x00001,\n    VIF_MISMATCH         = 0x00002,\n    VIF_SRCOLD           = 0x00004,\n    VIF_DIFFLANG         = 0x00008,\n    VIF_DIFFCODEPG       = 0x00010,\n    VIF_DIFFTYPE         = 0x00020,\n    VIF_WRITEPROT        = 0x00040,\n    VIF_FILEINUSE        = 0x00080,\n    VIF_OUTOFSPACE       = 0x00100,\n    VIF_ACCESSVIOLATION  = 0x00200,\n    VIF_SHARINGVIOLATION = 0x00400,\n    VIF_CANNOTCREATE     = 0x00800,\n    VIF_CANNOTDELETE     = 0x01000,\n    VIF_CANNOTRENAME     = 0x02000,\n    VIF_CANNOTDELETECUR  = 0x04000,\n    VIF_OUTOFMEMORY      = 0x08000,\n    VIF_CANNOTREADSRC    = 0x10000,\n    VIF_CANNOTREADDST    = 0x20000,\n    VIF_BUFFTOOSMALL     = 0x40000\n}\n\nstruct VS_FIXEDFILEINFO {\n    DWORD dwSignature;\n    DWORD dwStrucVersion;\n    DWORD dwFileVersionMS;\n    DWORD dwFileVersionLS;\n    DWORD dwProductVersionMS;\n    DWORD dwProductVersionLS;\n    DWORD dwFileFlagsMask;\n    DWORD dwFileFlags;\n    DWORD dwFileOS;\n    DWORD dwFileType;\n    DWORD dwFileSubtype;\n    DWORD dwFileDateMS;\n    DWORD dwFileDateLS;\n}\n\nextern (Windows) {\n    DWORD VerFindFileA(DWORD, LPCSTR, LPCSTR, LPCSTR, LPSTR, PUINT, LPSTR,\n      PUINT);\n    DWORD VerFindFileW(DWORD, LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, PUINT, LPWSTR,\n      PUINT);\n    DWORD VerInstallFileA(DWORD, LPCSTR, LPCSTR, LPCSTR, LPCSTR, LPCSTR, LPSTR,\n      PUINT);\n    DWORD VerInstallFileW(DWORD, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR,\n      LPWSTR, PUINT);\n    DWORD GetFileVersionInfoSizeA(LPCSTR, PDWORD);\n    DWORD GetFileVersionInfoSizeW(LPCWSTR, PDWORD);\n    BOOL GetFileVersionInfoA(LPCSTR, DWORD, DWORD, PVOID);\n    BOOL GetFileVersionInfoW(LPCWSTR, DWORD, DWORD, PVOID);\n    DWORD VerLanguageNameA(DWORD, LPSTR, DWORD);\n    DWORD VerLanguageNameW(DWORD, LPWSTR, DWORD);\n    BOOL VerQueryValueA(LPCVOID, LPCSTR, LPVOID*, PUINT);\n    BOOL VerQueryValueW(LPCVOID, LPCWSTR, LPVOID*, PUINT);\n}\n\nversion (Unicode) {\n    alias VerFindFileW VerFindFile;\n    alias VerQueryValueW VerQueryValue;\n    alias VerInstallFileW VerInstallFile;\n    alias GetFileVersionInfoSizeW GetFileVersionInfoSize;\n    alias GetFileVersionInfoW GetFileVersionInfo;\n    alias VerLanguageNameW VerLanguageName;\n    alias VerQueryValueW VerQueryValue;\n} else {\n    alias VerQueryValueA VerQueryValue;\n    alias VerFindFileA VerFindFile;\n    alias VerInstallFileA VerInstallFile;\n    alias GetFileVersionInfoSizeA GetFileVersionInfoSize;\n    alias GetFileVersionInfoA GetFileVersionInfo;\n    alias VerLanguageNameA VerLanguageName;\n    alias VerQueryValueA VerQueryValue;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/wtsapi32.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW-w64 API\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_wtsapi32.d)\n */\nmodule core.sys.windows.wtsapi32;\nversion (Windows):\n\nversion (ANSI) {} else version = Unicode;\npragma(lib, \"wtsapi32\");\nprivate import core.sys.windows.w32api;\nimport core.sys.windows.windef;\n\nenum {\n    WTS_CURRENT_SERVER        = null,\n    WTS_CURRENT_SERVER_HANDLE = null,\n    WTS_CURRENT_SERVER_NAME   = null\n}\n\nenum DWORD WTS_CURRENT_SESSION = cast(DWORD) -1;\n\nenum {\n    IDTIMEOUT = 32000,\n    IDASYNC   = 32001\n}\n\nenum {\n    WTS_WSD_LOGOFF     = 0x01,\n    WTS_WSD_SHUTDOWN   = 0x02,\n    WTS_WSD_REBOOT     = 0x04,\n    WTS_WSD_POWEROFF   = 0x08,\n    WTS_WSD_FASTREBOOT = 0x10\n}\n\nenum WTS_CONNECTSTATE_CLASS {\n    WTSActive,\n    WTSConnected,\n    WTSConnectQuery,\n    WTSShadow,\n    WTSDisconnected,\n    WTSIdle,\n    WTSListen,\n    WTSReset,\n    WTSDown,\n    WTSInit\n}\n\nstruct WTS_SERVER_INFOW {\n    LPWSTR pServerName;\n}\nalias WTS_SERVER_INFOW* PWTS_SERVER_INFOW;\n\nstruct WTS_SERVER_INFOA {\n    LPSTR pServerName;\n}\nalias WTS_SERVER_INFOA* PWTS_SERVER_INFOA;\n\nversion (Unicode) {\n    alias WTS_SERVER_INFOW  WTS_SERVER_INFO;\n    alias PWTS_SERVER_INFOW PWTS_SERVER_INFO;\n} else {\n    alias WTS_SERVER_INFOA  WTS_SERVER_INFO;\n    alias PWTS_SERVER_INFOA PWTS_SERVER_INFO;\n}\n\nstruct WTS_SESSION_INFOW {\n    DWORD SessionId;\n    LPWSTR pWinStationName;\n    WTS_CONNECTSTATE_CLASS State;\n}\nalias WTS_SESSION_INFOW* PWTS_SESSION_INFOW;\n\nstruct WTS_SESSION_INFOA {\n    DWORD SessionId;\n    LPSTR pWinStationName;\n    WTS_CONNECTSTATE_CLASS State;\n}\nalias WTS_SESSION_INFOA* PWTS_SESSION_INFOA;\n\nversion (Unicode) {\n    alias WTS_SESSION_INFOW  WTS_SESSION_INFO;\n    alias PWTS_SESSION_INFOW PWTS_SESSION_INFO;\n} else {\n    alias WTS_SESSION_INFOA  WTS_SESSION_INFO;\n    alias PWTS_SESSION_INFOA PWTS_SESSION_INFO;\n}\n\nstruct WTS_PROCESS_INFOW {\n    DWORD SessionId;\n    DWORD ProcessId;\n    LPWSTR pProcessName;\n    PSID pUserSid;\n}\nalias WTS_PROCESS_INFOW* PWTS_PROCESS_INFOW;\n\nstruct WTS_PROCESS_INFOA {\n    DWORD SessionId;\n    DWORD ProcessId;\n    LPSTR pProcessName;\n    PSID pUserSid;\n}\nalias WTS_PROCESS_INFOA* PWTS_PROCESS_INFOA;\n\nversion (Unicode) {\n    alias WTS_PROCESS_INFOW  WTS_PROCESS_INFO;\n    alias PWTS_PROCESS_INFOW PWTS_PROCESS_INFO;\n} else {\n    alias WTS_PROCESS_INFOA  WTS_PROCESS_INFO;\n    alias PWTS_PROCESS_INFOA PWTS_PROCESS_INFO;\n}\n\nenum {\n    WTS_PROTOCOL_TYPE_CONSOLE,\n    WTS_PROTOCOL_TYPE_ICA,\n    WTS_PROTOCOL_TYPE_RDP\n}\n\nenum WTS_INFO_CLASS {\n    WTSInitialProgram,\n    WTSApplicationName,\n    WTSWorkingDirectory,\n    WTSOEMId,\n    WTSSessionId,\n    WTSUserName,\n    WTSWinStationName,\n    WTSDomainName,\n    WTSConnectState,\n    WTSClientBuildNumber,\n    WTSClientName,\n    WTSClientDirectory,\n    WTSClientProductId,\n    WTSClientHardwareId,\n    WTSClientAddress,\n    WTSClientDisplay,\n    WTSClientProtocolType,\n    WTSIdleTime,\n    WTSLogonTime,\n    WTSIncomingBytes,\n    WTSOutgoingBytes,\n    WTSIncomingFrames,\n    WTSOutgoingFrames,\n    WTSClientInfo,\n    WTSSessionInfo, // = 24\n}\n\nstruct WTS_CLIENT_ADDRESS {\n    DWORD    AddressFamily;\n    BYTE[20] Address;\n}\nalias WTS_CLIENT_ADDRESS* PWTS_CLIENT_ADDRESS;\n\nstruct WTS_CLIENT_DISPLAY {\n    DWORD HorizontalResolution;\n    DWORD VerticalResolution;\n    DWORD ColorDepth;\n}\nalias WTS_CLIENT_DISPLAY* PWTS_CLIENT_DISPLAY;\n\nenum WTS_CONFIG_CLASS {\n    WTSUserConfigInitialProgram,\n    WTSUserConfigWorkingDirectory,\n    WTSUserConfigfInheritInitialProgram,\n    WTSUserConfigfAllowLogonTerminalServer,\n    WTSUserConfigTimeoutSettingsConnections,\n    WTSUserConfigTimeoutSettingsDisconnections,\n    WTSUserConfigTimeoutSettingsIdle,\n    WTSUserConfigfDeviceClientDrives,\n    WTSUserConfigfDeviceClientPrinters,\n    WTSUserConfigfDeviceClientDefaultPrinter,\n    WTSUserConfigBrokenTimeoutSettings,\n    WTSUserConfigReconnectSettings,\n    WTSUserConfigModemCallbackSettings,\n    WTSUserConfigModemCallbackPhoneNumber,\n    WTSUserConfigShadowingSettings,\n    WTSUserConfigTerminalServerProfilePath,\n    WTSUserConfigTerminalServerHomeDir,\n    WTSUserConfigTerminalServerHomeDirDrive,\n    WTSUserConfigfTerminalServerRemoteHomeDir\n}\n\nenum {\n    WTS_EVENT_NONE        = 0x0,\n    WTS_EVENT_CREATE      = 0x1,\n    WTS_EVENT_DELETE      = 0x2,\n    WTS_EVENT_RENAME      = 0x4,\n    WTS_EVENT_CONNECT     = 0x8,\n    WTS_EVENT_DISCONNECT  = 0x10,\n    WTS_EVENT_LOGON       = 0x20,\n    WTS_EVENT_LOGOFF      = 0x40,\n    WTS_EVENT_STATECHANGE = 0x80,\n    WTS_EVENT_LICENSE     = 0x100,\n    WTS_EVENT_ALL         = 0x7fffffff,\n    WTS_EVENT_FLUSH       = 0x80000000\n}\n\nenum WTS_VIRTUAL_CLASS {\n    WTSVirtualClientData,\n    WTSVirtualFileHandle\n}\n\nversion (Unicode) {\n    alias WTSEnumerateServersW WTSEnumerateServers;\n    alias WTSOpenServerW WTSOpenServer;\n    alias WTSEnumerateSessionsW WTSEnumerateSessions;\n    alias WTSEnumerateProcessesW WTSEnumerateProcesses;\n    alias WTSQuerySessionInformationW WTSQuerySessionInformation;\n    alias WTSQueryUserConfigW WTSQueryUserConfig;\n    alias WTSSetUserConfigW WTSSetUserConfig;\n    alias WTSSendMessageW WTSSendMessage;\n} else {\n    alias WTSEnumerateServersA WTSEnumerateServers;\n    alias WTSOpenServerA WTSOpenServer;\n    alias WTSEnumerateSessionsA WTSEnumerateSessions;\n    alias WTSEnumerateProcessesA WTSEnumerateProcesses;\n    alias WTSQuerySessionInformationA WTSQuerySessionInformation;\n    alias WTSQueryUserConfigA WTSQueryUserConfig;\n    alias WTSSetUserConfigA WTSSetUserConfig;\n    alias WTSSendMessageA WTSSendMessage;\n}\n\nextern(Windows) {\n    WINBOOL WTSEnumerateServersW(LPWSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOW* ppServerInfo, DWORD* pCount);\n    WINBOOL WTSEnumerateServersA(LPSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOA* ppServerInfo, DWORD* pCount);\n    HANDLE WTSOpenServerW(LPWSTR pServerName);\n    HANDLE WTSOpenServerA(LPSTR pServerName);\n    VOID WTSCloseServer(HANDLE hServer);\n    WINBOOL WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOW* ppSessionInfo, DWORD* pCount);\n    WINBOOL WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOA* ppSessionInfo, DWORD* pCount);\n    WINBOOL WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount);\n    WINBOOL WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOA* ppProcessInfo, DWORD* pCount);\n    WINBOOL WTSTerminateProcess(HANDLE hServer, DWORD ProcessId, DWORD ExitCode);\n    WINBOOL WTSQuerySessionInformationW(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPWSTR* ppBuffer, DWORD* pBytesReturned);\n    WINBOOL WTSQuerySessionInformationA(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPSTR* ppBuffer, DWORD* pBytesReturned);\n    WINBOOL WTSQueryUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR* ppBuffer, DWORD* pBytesReturned);\n    WINBOOL WTSQueryUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR* ppBuffer, DWORD* pBytesReturned);\n    WINBOOL WTSSetUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR pBuffer, DWORD DataLength);\n    WINBOOL WTSSetUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR pBuffer, DWORD DataLength);\n    WINBOOL WTSSendMessageW(HANDLE hServer, DWORD SessionId, LPWSTR pTitle, DWORD TitleLength, LPWSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, WINBOOL bWait);\n    WINBOOL WTSSendMessageA(HANDLE hServer, DWORD SessionId, LPSTR pTitle, DWORD TitleLength, LPSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, WINBOOL bWait);\n    WINBOOL WTSDisconnectSession(HANDLE hServer, DWORD SessionId, WINBOOL bWait);\n    WINBOOL WTSLogoffSession(HANDLE hServer, DWORD SessionId, WINBOOL bWait);\n    WINBOOL WTSShutdownSystem(HANDLE hServer, DWORD ShutdownFlag);\n    WINBOOL WTSWaitSystemEvent(HANDLE hServer, DWORD EventMask, DWORD* pEventFlags);\n    HANDLE WTSVirtualChannelOpen(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName);\n    WINBOOL WTSVirtualChannelClose(HANDLE hChannelHandle);\n    WINBOOL WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead);\n    WINBOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, PULONG pBytesWritten);\n    WINBOOL WTSVirtualChannelPurgeInput(HANDLE hChannelHandle);\n    WINBOOL WTSVirtualChannelPurgeOutput(HANDLE hChannelHandle);\n    WINBOOL WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS, PVOID* ppBuffer, DWORD* pBytesReturned);\n    VOID WTSFreeMemory(PVOID pMemory);\n\n    WINBOOL WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags);\n    WINBOOL WTSUnRegisterSessionNotification(HWND hWnd);\n    WINBOOL WTSQueryUserToken(ULONG SessionId, PHANDLE phToken);\n}\n\nenum {\n    NOTIFY_FOR_ALL_SESSIONS = 1,\n    NOTIFY_FOR_THIS_SESSION = 0\n}\n\nenum {\n    USERNAME_LENGTH       = 20,\n    CLIENTNAME_LENGTH     = 20,\n    CLIENTADDRESS_LENGTH  = 30,\n    WINSTATIONNAME_LENGTH = 32,\n    DOMAIN_LENGTH         = 17\n}\n\nstatic if (_WIN32_WINNT >= 0x600) {\n    struct WTSCLIENTW {\n        WCHAR[CLIENTNAME_LENGTH + 1]      ClientName;\n        WCHAR[DOMAIN_LENGTH + 1]          Domain;\n        WCHAR[USERNAME_LENGTH + 1]        UserName;\n        WCHAR[MAX_PATH + 1]               WorkDirectory;\n        WCHAR[MAX_PATH + 1]               InitialProgram;\n        BYTE                              EncryptionLevel;\n        ULONG                             ClientAddressFamily;\n        USHORT[CLIENTADDRESS_LENGTH + 1]  ClientAddress;\n        USHORT                            HRes;\n        USHORT                            VRes;\n        USHORT                            ColorDepth;\n        WCHAR[MAX_PATH + 1]               ClientDirectory;\n        ULONG                             ClientBuildNumber;\n        ULONG                             ClientHardwareId;\n        USHORT                            ClientProductId;\n        USHORT                            OutBufCountHost;\n        USHORT                            OutBufCountClient;\n        USHORT                            OutBufLength;\n        WCHAR[MAX_PATH + 1]               DeviceId;\n    }\n    alias WTSCLIENTW* PWTSCLIENTW;\n\n    struct WTSCLIENTA {\n        CHAR[CLIENTNAME_LENGTH + 1]       ClientName;\n        CHAR[DOMAIN_LENGTH + 1 ]          Domain;\n        CHAR[USERNAME_LENGTH + 1]         UserName;\n        CHAR[MAX_PATH + 1]                WorkDirectory;\n        CHAR[MAX_PATH + 1]                InitialProgram;\n        BYTE                              EncryptionLevel;\n        ULONG                             ClientAddressFamily;\n        USHORT[CLIENTADDRESS_LENGTH + 1]  ClientAddress;\n        USHORT                            HRes;\n        USHORT                            VRes;\n        USHORT                            ColorDepth;\n        CHAR[MAX_PATH + 1]                ClientDirectory;\n        ULONG                             ClientBuildNumber;\n        ULONG                             ClientHardwareId;\n        USHORT                            ClientProductId;\n        USHORT                            OutBufCountHost;\n        USHORT                            OutBufCountClient;\n        USHORT                            OutBufLength;\n        CHAR[MAX_PATH + 1]                DeviceId;\n    }\n    alias WTSCLIENTA* PWTSCLIENTA;\n\n    version (Unicode) {\n        alias WTSCLIENTW  WTSCLIENT;\n        alias PWTSCLIENTW PWTSCLIENT;\n    } else {\n        alias WTSCLIENTA  WTSCLIENT;\n        alias PWTSCLIENTA PWTSCLIENT;\n    }\n\n    struct WTSINFOW {\n        WTS_CONNECTSTATE_CLASS       State;\n        DWORD                        SessionId;\n        DWORD                        IncomingBytes;\n        DWORD                        OutgoingBytes;\n        DWORD                        IncomingFrames;\n        DWORD                        OutgoingFrames;\n        DWORD                        IncomingCompressedBytes;\n        DWORD                        OutgoingCompressedBytes;\n        WCHAR[WINSTATIONNAME_LENGTH] WinStationName;\n        WCHAR[DOMAIN_LENGTH]         Domain;\n        WCHAR[USERNAME_LENGTH+1]     UserName;\n        LARGE_INTEGER                ConnectTime;\n        LARGE_INTEGER                DisconnectTime;\n        LARGE_INTEGER                LastInputTime;\n        LARGE_INTEGER                LogonTime;\n        LARGE_INTEGER                CurrentTime;\n    }\n    alias WTSINFOW* PWTSINFOW;\n\n    struct WTSINFOA {\n        WTS_CONNECTSTATE_CLASS      State;\n        DWORD                       SessionId;\n        DWORD                       IncomingBytes;\n        DWORD                       OutgoingBytes;\n        DWORD                       IncomingFrames;\n        DWORD                       OutgoingFrames;\n        DWORD                       IncomingCompressedBytes;\n        DWORD                       OutgoingCompressedBytes;\n        CHAR[WINSTATIONNAME_LENGTH] WinStationName;\n        CHAR[DOMAIN_LENGTH]         Domain;\n        CHAR[USERNAME_LENGTH+1]     UserName;\n        LARGE_INTEGER               ConnectTime;\n        LARGE_INTEGER               DisconnectTime;\n        LARGE_INTEGER               LastInputTime;\n        LARGE_INTEGER               LogonTime;\n        LARGE_INTEGER               CurrentTime;\n    }\n    alias WTSINFOA* PWTSINFOA;\n\n    version (Unicode) {\n        alias WTSINFOW  WTSINFO;\n        alias PWTSINFOW PWTSINFO;\n    } else {\n        alias WTSINFOA  WTSINFO;\n        alias PWTSINFOA PWTSINFO;\n    }\n\n    extern(Windows) {\n        WINBOOL WTSConnectSessionA(\n            ULONG LogonId,\n            ULONG TargetLogonId,\n            PSTR   pPassword,\n            WINBOOL bWait\n        );\n\n        WINBOOL WTSConnectSessionW(\n            ULONG LogonId,\n            ULONG TargetLogonId,\n            PWSTR  pPassword,\n            WINBOOL bWait\n        );\n\n        WINBOOL WTSRegisterSessionNotificationEx(\n            HANDLE hServer,\n            HWND hWnd,\n            DWORD dwFlags\n        );\n\n        WINBOOL WTSStartRemoteControlSessionA(\n            LPSTR pTargetServerName,\n            ULONG TargetLogonId,\n            BYTE HotkeyVk,\n            USHORT HotkeyModifiers\n        );\n\n        WINBOOL WTSStartRemoteControlSessionW(\n            LPWSTR pTargetServerName,\n            ULONG TargetLogonId,\n            BYTE HotkeyVk,\n            USHORT HotkeyModifiers\n        );\n\n        version (Unicode) {\n            alias WTSStartRemoteControlSessionW WTSStartRemoteControlSession;\n            alias WTSConnectSessionW WTSConnectSession;\n        } else {\n            alias WTSStartRemoteControlSessionA WTSStartRemoteControlSession;\n            alias WTSConnectSessionA WTSConnectSession;\n        }\n\n        WINBOOL WTSStopRemoteControlSession(\n            ULONG LogonId\n        );\n\n        WINBOOL WTSUnRegisterSessionNotificationEx(\n            HANDLE hServer,\n            HWND hWnd\n        );\n\n        HANDLE WTSVirtualChannelOpenEx(\n            DWORD SessionId,\n            LPSTR pVirtualName,\n            DWORD flags\n        );\n    } /* extern(Windows) */\n} /* static if (_WIN32_WINNT >= 0x600) */\n"
  },
  {
    "path": "libphobos/libdruntime/core/sys/windows/wtypes.d",
    "content": "/**\n * Windows API header module\n *\n * Translated from MinGW Windows headers\n *\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Source: $(DRUNTIMESRC src/core/sys/windows/_wtypes.d)\n */\nmodule core.sys.windows.wtypes;\nversion (Windows):\n\nimport core.sys.windows.rpc, core.sys.windows.rpcndr;\nprivate import core.sys.windows.windef;\nprivate import core.sys.windows.uuid; // for GUID_NULL\n\nalias GUID_NULL IID_NULL, CLSID_NULL;\n\nenum ROTFLAGS_REGISTRATIONKEEPSALIVE = 0x01;\nenum ROTFLAGS_ALLOWANYCLIENT         = 0x02;\n\n// also in winsock2.h\nstruct BLOB {\n    ULONG cbSize;\n    BYTE* pBlobData;\n}\nalias BLOB* PBLOB, LPBLOB;\n\nenum DVASPECT {\n    DVASPECT_CONTENT   = 1,\n    DVASPECT_THUMBNAIL = 2,\n    DVASPECT_ICON      = 4,\n    DVASPECT_DOCPRINT  = 8\n}\n\nenum DVASPECT2 {\n    DVASPECT_OPAQUE      = 16,\n    DVASPECT_TRANSPARENT = 32\n}\n\nenum STATFLAG {\n    STATFLAG_DEFAULT = 0,\n    STATFLAG_NONAME  = 1\n}\n\nenum MEMCTX {\n    MEMCTX_LOCAL = 0,\n    MEMCTX_TASK,\n    MEMCTX_SHARED,\n    MEMCTX_MACSYSTEM,\n    MEMCTX_UNKNOWN = -1,\n    MEMCTX_SAME = -2\n}\n\nenum MSHCTX {\n    MSHCTX_LOCAL = 0,\n    MSHCTX_NOSHAREDMEM,\n    MSHCTX_DIFFERENTMACHINE,\n    MSHCTX_INPROC,\n    MSHCTX_CROSSCTX\n}\n\nenum CLSCTX {\n    CLSCTX_INPROC_SERVER    = 0x1,\n    CLSCTX_INPROC_HANDLER   = 0x2,\n    CLSCTX_LOCAL_SERVER     = 0x4,\n    CLSCTX_INPROC_SERVER16  = 0x8,\n    CLSCTX_REMOTE_SERVER    = 0x10,\n    CLSCTX_INPROC_HANDLER16 = 0x20,\n    CLSCTX_INPROC_SERVERX86 = 0x40,\n    CLSCTX_INPROC_HANDLERX86 = 0x80,\n}\n\nenum MSHLFLAGS {\n    MSHLFLAGS_NORMAL,\n    MSHLFLAGS_TABLESTRONG,\n    MSHLFLAGS_TABLEWEAK\n}\n\nstruct FLAGGED_WORD_BLOB {\n    uint fFlags;\n    uint clSize;\n    ushort[1] asData;\n}\n\nalias WCHAR OLECHAR;\nalias LPWSTR LPOLESTR;\nalias LPCWSTR LPCOLESTR;\n\nalias ushort VARTYPE;\nalias short VARIANT_BOOL;\nalias VARIANT_BOOL _VARIANT_BOOL;\nenum VARIANT_BOOL VARIANT_TRUE = -1; // 0xffff;\nenum VARIANT_BOOL VARIANT_FALSE = 0;\n\nalias OLECHAR* BSTR;\nalias FLAGGED_WORD_BLOB* wireBSTR;\nalias BSTR* LPBSTR;\n//alias LONG SCODE; // also in winerror\nmixin DECLARE_HANDLE!(\"HCONTEXT\");\nmixin DECLARE_HANDLE!(\"HMETAFILEPICT\");\n\nunion CY {\n    struct {\n        uint Lo;\n        int Hi;\n    }\n    LONGLONG int64;\n}\n\nalias double DATE;\nstruct  BSTRBLOB {\n    ULONG cbSize;\n    PBYTE pData;\n}\nalias BSTRBLOB* LPBSTRBLOB;\n\n// Used only in the PROPVARIANT structure\n// According to the 2003 SDK, this should be in propidl.h, not here.\nstruct CLIPDATA {\n    ULONG cbSize;\n    int ulClipFmt;\n    PBYTE pClipData;\n}\n\nenum STGC {\n    STGC_DEFAULT,\n    STGC_OVERWRITE,\n    STGC_ONLYIFCURRENT,\n    STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE\n}\n\nenum STGMOVE {\n    STGMOVE_MOVE,\n    STGMOVE_COPY,\n    STGMOVE_SHALLOWCOPY\n}\n\nenum VARENUM {\n    VT_EMPTY,\n    VT_NULL,\n    VT_I2,\n    VT_I4,\n    VT_R4,\n    VT_R8,\n    VT_CY,\n    VT_DATE,\n    VT_BSTR,\n    VT_DISPATCH,\n    VT_ERROR,\n    VT_BOOL,\n    VT_VARIANT,\n    VT_UNKNOWN,\n    VT_DECIMAL,\n    VT_I1 = 16,\n    VT_UI1,\n    VT_UI2,\n    VT_UI4,\n    VT_I8,\n    VT_UI8,\n    VT_INT,\n    VT_UINT,\n    VT_VOID,\n    VT_HRESULT,\n    VT_PTR,\n    VT_SAFEARRAY,\n    VT_CARRAY,\n    VT_USERDEFINED,\n    VT_LPSTR,\n    VT_LPWSTR,\n    VT_RECORD   = 36,\n    VT_INT_PTR  = 37,\n    VT_UINT_PTR = 38,\n    VT_FILETIME = 64,\n    VT_BLOB,\n    VT_STREAM,\n    VT_STORAGE,\n    VT_STREAMED_OBJECT,\n    VT_STORED_OBJECT,\n    VT_BLOB_OBJECT,\n    VT_CF,\n    VT_CLSID,\n    VT_BSTR_BLOB     = 0xfff,\n    VT_VECTOR        = 0x1000,\n    VT_ARRAY         = 0x2000,\n    VT_BYREF         = 0x4000,\n    VT_RESERVED      = 0x8000,\n    VT_ILLEGAL       = 0xffff,\n    VT_ILLEGALMASKED = 0xfff,\n    VT_TYPEMASK      = 0xfff\n};\n\nstruct BYTE_SIZEDARR {\n    uint clSize;\n    byte* pData;\n}\n\nstruct WORD_SIZEDARR {\n    uint clSize;\n    ushort* pData;\n}\n\nstruct DWORD_SIZEDARR {\nuint clSize;\nuint* pData;\n}\n\nstruct HYPER_SIZEDARR {\n    uint clSize;\n    hyper* pData;\n}\n\nalias double DOUBLE;\n\n\nstruct DECIMAL {\n    USHORT wReserved;\n    union {\n        struct {\n            ubyte scale; // valid values are 0 to 28\n            ubyte sign; // 0 for positive, DECIMAL_NEG for negatives.\n            enum ubyte DECIMAL_NEG = 0x80;\n        }\n        USHORT signscale;\n    }\n    ULONG Hi32;\n    union {\n        struct {\n            ULONG Lo32;\n            ULONG Mid32;\n        }\n        ULONGLONG Lo64;\n    }\n    // #define DECIMAL_SETZERO(d) {(d).Lo64=(d).Hi32=(d).signscale=0;}\n    void setZero() { Lo64 = 0; Hi32 = 0; signscale = 0; }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/thread.d",
    "content": "/**\n * The thread module provides support for thread creation and management.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2012.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak\n * Source:    $(DRUNTIMESRC core/_thread.d)\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule core.thread;\n\n\npublic import core.time; // for Duration\nimport core.exception : onOutOfMemoryError;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nprivate\n{\n    // interface to rt.tlsgc\n    import core.internal.traits : externDFunc;\n\n    alias rt_tlsgc_init = externDFunc!(\"rt.tlsgc.init\", void* function() nothrow @nogc);\n    alias rt_tlsgc_destroy = externDFunc!(\"rt.tlsgc.destroy\", void function(void*) nothrow @nogc);\n\n    alias ScanDg = void delegate(void* pstart, void* pend) nothrow;\n    alias rt_tlsgc_scan =\n        externDFunc!(\"rt.tlsgc.scan\", void function(void*, scope ScanDg) nothrow);\n\n    alias rt_tlsgc_processGCMarks =\n        externDFunc!(\"rt.tlsgc.processGCMarks\", void function(void*, scope IsMarkedDg) nothrow);\n}\n\nversion (Solaris)\n{\n    import core.sys.solaris.sys.priocntl;\n    import core.sys.solaris.sys.types;\n    import core.sys.posix.sys.wait : idtype_t;\n}\n\n// this should be true for most architectures\nversion (GNU_StackGrowsDown)\n    version = StackGrowsDown;\n\n/**\n * Returns the process ID of the calling process, which is guaranteed to be\n * unique on the system. This call is always successful.\n *\n * Example:\n * ---\n * writefln(\"Current process id: %s\", getpid());\n * ---\n */\nversion (Posix)\n{\n    alias getpid = core.sys.posix.unistd.getpid;\n}\nelse version (Windows)\n{\n    alias getpid = core.sys.windows.windows.GetCurrentProcessId;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Thread and Fiber Exceptions\n///////////////////////////////////////////////////////////////////////////////\n\n\n/**\n * Base class for thread exceptions.\n */\nclass ThreadException : Exception\n{\n    @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)\n    {\n        super(msg, file, line, next);\n    }\n\n    @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__)\n    {\n        super(msg, file, line, next);\n    }\n}\n\n\n/**\n* Base class for thread errors to be used for function inside GC when allocations are unavailable.\n*/\nclass ThreadError : Error\n{\n    @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)\n    {\n        super(msg, file, line, next);\n    }\n\n    @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__)\n    {\n        super(msg, file, line, next);\n    }\n}\n\nprivate\n{\n    import core.atomic, core.memory, core.sync.mutex;\n\n    //\n    // exposed by compiler runtime\n    //\n    extern (C) void  rt_moduleTlsCtor();\n    extern (C) void  rt_moduleTlsDtor();\n\n    /**\n     * Hook for whatever EH implementation is used to save/restore some data\n     * per stack.\n     *\n     * Params:\n     *     newContext = The return value of the prior call to this function\n     *         where the stack was last swapped out, or null when a fiber stack\n     *         is switched in for the first time.\n     */\n    extern(C) void* _d_eh_swapContext(void* newContext) nothrow @nogc;\n\n    version (DigitalMars)\n    {\n        version (Windows)\n            alias swapContext = _d_eh_swapContext;\n        else\n        {\n            extern(C) void* _d_eh_swapContextDwarf(void* newContext) nothrow @nogc;\n\n            void* swapContext(void* newContext) nothrow @nogc\n            {\n                /* Detect at runtime which scheme is being used.\n                 * Eventually, determine it statically.\n                 */\n                static int which = 0;\n                final switch (which)\n                {\n                    case 0:\n                    {\n                        assert(newContext == null);\n                        auto p = _d_eh_swapContext(newContext);\n                        auto pdwarf = _d_eh_swapContextDwarf(newContext);\n                        if (p)\n                        {\n                            which = 1;\n                            return p;\n                        }\n                        else if (pdwarf)\n                        {\n                            which = 2;\n                            return pdwarf;\n                        }\n                        return null;\n                    }\n                    case 1:\n                        return _d_eh_swapContext(newContext);\n                    case 2:\n                        return _d_eh_swapContextDwarf(newContext);\n                }\n            }\n        }\n    }\n    else\n        alias swapContext = _d_eh_swapContext;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Thread Entry Point and Signal Handlers\n///////////////////////////////////////////////////////////////////////////////\n\n\nversion (Windows)\n{\n    private\n    {\n        import core.stdc.stdint : uintptr_t; // for _beginthreadex decl below\n        import core.stdc.stdlib;             // for malloc, atexit\n        import core.sys.windows.windows;\n        import core.sys.windows.threadaux;   // for OpenThreadHandle\n\n        extern (Windows) alias btex_fptr = uint function(void*);\n        extern (C) uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*) nothrow;\n\n        //\n        // Entry point for Windows threads\n        //\n        extern (Windows) uint thread_entryPoint( void* arg ) nothrow\n        {\n            Thread  obj = cast(Thread) arg;\n            assert( obj );\n\n            assert( obj.m_curr is &obj.m_main );\n            obj.m_main.bstack = getStackBottom();\n            obj.m_main.tstack = obj.m_main.bstack;\n            obj.m_tlsgcdata = rt_tlsgc_init();\n\n            Thread.setThis(obj);\n            Thread.add(obj);\n            scope (exit)\n            {\n                Thread.remove(obj);\n            }\n            Thread.add(&obj.m_main);\n\n            // NOTE: No GC allocations may occur until the stack pointers have\n            //       been set and Thread.getThis returns a valid reference to\n            //       this thread object (this latter condition is not strictly\n            //       necessary on Windows but it should be followed for the\n            //       sake of consistency).\n\n            // TODO: Consider putting an auto exception object here (using\n            //       alloca) forOutOfMemoryError plus something to track\n            //       whether an exception is in-flight?\n\n            void append( Throwable t )\n            {\n                obj.m_unhandled = Throwable.chainTogether(obj.m_unhandled, t);\n            }\n\n            version (D_InlineAsm_X86)\n            {\n                asm nothrow @nogc { fninit; }\n            }\n\n            try\n            {\n                rt_moduleTlsCtor();\n                try\n                {\n                    obj.run();\n                }\n                catch ( Throwable t )\n                {\n                    append( t );\n                }\n                rt_moduleTlsDtor();\n            }\n            catch ( Throwable t )\n            {\n                append( t );\n            }\n            return 0;\n        }\n\n\n        HANDLE GetCurrentThreadHandle() nothrow @nogc\n        {\n            const uint DUPLICATE_SAME_ACCESS = 0x00000002;\n\n            HANDLE curr = GetCurrentThread(),\n                   proc = GetCurrentProcess(),\n                   hndl;\n\n            DuplicateHandle( proc, curr, proc, &hndl, 0, TRUE, DUPLICATE_SAME_ACCESS );\n            return hndl;\n        }\n    }\n}\nelse version (Posix)\n{\n    private\n    {\n        import core.stdc.errno;\n        import core.sys.posix.semaphore;\n        import core.sys.posix.stdlib; // for malloc, valloc, free, atexit\n        import core.sys.posix.pthread;\n        import core.sys.posix.signal;\n        import core.sys.posix.time;\n\n        version (Darwin)\n        {\n            import core.sys.darwin.mach.thread_act;\n            import core.sys.darwin.pthread : pthread_mach_thread_np;\n        }\n\n        version (GNU)\n        {\n            import gcc.builtins;\n        }\n\n        //\n        // Entry point for POSIX threads\n        //\n        extern (C) void* thread_entryPoint( void* arg ) nothrow\n        {\n            version (Shared)\n            {\n                Thread obj = cast(Thread)(cast(void**)arg)[0];\n                auto loadedLibraries = (cast(void**)arg)[1];\n                .free(arg);\n            }\n            else\n            {\n                Thread obj = cast(Thread)arg;\n            }\n            assert( obj );\n\n            // loadedLibraries need to be inherited from parent thread\n            // before initilizing GC for TLS (rt_tlsgc_init)\n            version (Shared)\n            {\n                externDFunc!(\"rt.sections_elf_shared.inheritLoadedLibraries\",\n                             void function(void*) @nogc nothrow)(loadedLibraries);\n            }\n\n            assert( obj.m_curr is &obj.m_main );\n            obj.m_main.bstack = getStackBottom();\n            obj.m_main.tstack = obj.m_main.bstack;\n            obj.m_tlsgcdata = rt_tlsgc_init();\n\n            atomicStore!(MemoryOrder.raw)(obj.m_isRunning, true);\n            Thread.setThis(obj); // allocates lazy TLS (see Issue 11981)\n            Thread.add(obj);     // can only receive signals from here on\n            scope (exit)\n            {\n                Thread.remove(obj);\n                atomicStore!(MemoryOrder.raw)(obj.m_isRunning, false);\n            }\n            Thread.add(&obj.m_main);\n\n            static extern (C) void thread_cleanupHandler( void* arg ) nothrow @nogc\n            {\n                Thread  obj = cast(Thread) arg;\n                assert( obj );\n\n                // NOTE: If the thread terminated abnormally, just set it as\n                //       not running and let thread_suspendAll remove it from\n                //       the thread list.  This is safer and is consistent\n                //       with the Windows thread code.\n                atomicStore!(MemoryOrder.raw)(obj.m_isRunning,false);\n            }\n\n            // NOTE: Using void to skip the initialization here relies on\n            //       knowledge of how pthread_cleanup is implemented.  It may\n            //       not be appropriate for all platforms.  However, it does\n            //       avoid the need to link the pthread module.  If any\n            //       implementation actually requires default initialization\n            //       then pthread_cleanup should be restructured to maintain\n            //       the current lack of a link dependency.\n            static if ( __traits( compiles, pthread_cleanup ) )\n            {\n                pthread_cleanup cleanup = void;\n                cleanup.push( &thread_cleanupHandler, cast(void*) obj );\n            }\n            else static if ( __traits( compiles, pthread_cleanup_push ) )\n            {\n                pthread_cleanup_push( &thread_cleanupHandler, cast(void*) obj );\n            }\n            else\n            {\n                static assert( false, \"Platform not supported.\" );\n            }\n\n            // NOTE: No GC allocations may occur until the stack pointers have\n            //       been set and Thread.getThis returns a valid reference to\n            //       this thread object (this latter condition is not strictly\n            //       necessary on Windows but it should be followed for the\n            //       sake of consistency).\n\n            // TODO: Consider putting an auto exception object here (using\n            //       alloca) forOutOfMemoryError plus something to track\n            //       whether an exception is in-flight?\n\n            void append( Throwable t )\n            {\n                obj.m_unhandled = Throwable.chainTogether(obj.m_unhandled, t);\n            }\n\n            try\n            {\n                rt_moduleTlsCtor();\n                try\n                {\n                    obj.run();\n                }\n                catch ( Throwable t )\n                {\n                    append( t );\n                }\n                rt_moduleTlsDtor();\n                version (Shared)\n                {\n                    externDFunc!(\"rt.sections_elf_shared.cleanupLoadedLibraries\",\n                                 void function() @nogc nothrow)();\n                }\n            }\n            catch ( Throwable t )\n            {\n                append( t );\n            }\n\n            // NOTE: Normal cleanup is handled by scope(exit).\n\n            static if ( __traits( compiles, pthread_cleanup ) )\n            {\n                cleanup.pop( 0 );\n            }\n            else static if ( __traits( compiles, pthread_cleanup_push ) )\n            {\n                pthread_cleanup_pop( 0 );\n            }\n\n            return null;\n        }\n\n\n        //\n        // Used to track the number of suspended threads\n        //\n        __gshared sem_t suspendCount;\n\n\n        extern (C) void thread_suspendHandler( int sig ) nothrow\n        in\n        {\n            assert( sig == suspendSignalNumber );\n        }\n        do\n        {\n            void op(void* sp) nothrow\n            {\n                // NOTE: Since registers are being pushed and popped from the\n                //       stack, any other stack data used by this function should\n                //       be gone before the stack cleanup code is called below.\n                Thread obj = Thread.getThis();\n                assert(obj !is null);\n\n                if ( !obj.m_lock )\n                {\n                    obj.m_curr.tstack = getStackTop();\n                }\n\n                sigset_t    sigres = void;\n                int         status;\n\n                status = sigfillset( &sigres );\n                assert( status == 0 );\n\n                status = sigdelset( &sigres, resumeSignalNumber );\n                assert( status == 0 );\n\n                version (FreeBSD) obj.m_suspendagain = false;\n                status = sem_post( &suspendCount );\n                assert( status == 0 );\n\n                sigsuspend( &sigres );\n\n                if ( !obj.m_lock )\n                {\n                    obj.m_curr.tstack = obj.m_curr.bstack;\n                }\n            }\n\n            // avoid deadlocks on FreeBSD, see Issue 13416\n            version (FreeBSD)\n            {\n                auto obj = Thread.getThis();\n                if (THR_IN_CRITICAL(obj.m_addr))\n                {\n                    obj.m_suspendagain = true;\n                    if (sem_post(&suspendCount)) assert(0);\n                    return;\n                }\n            }\n\n            callWithStackShell(&op);\n        }\n\n\n        extern (C) void thread_resumeHandler( int sig ) nothrow\n        in\n        {\n            assert( sig == resumeSignalNumber );\n        }\n        do\n        {\n\n        }\n\n        // HACK libthr internal (thr_private.h) macro, used to\n        // avoid deadlocks in signal handler, see Issue 13416\n        version (FreeBSD) bool THR_IN_CRITICAL(pthread_t p) nothrow @nogc\n        {\n            import core.sys.posix.config : c_long;\n            import core.sys.posix.sys.types : lwpid_t;\n\n            // If the begin of pthread would be changed in libthr (unlikely)\n            // we'll run into undefined behavior, compare with thr_private.h.\n            static struct pthread\n            {\n                c_long tid;\n                static struct umutex { lwpid_t owner; uint flags; uint[2] ceilings; uint[4] spare; }\n                umutex lock;\n                uint cycle;\n                int locklevel;\n                int critical_count;\n                // ...\n            }\n            auto priv = cast(pthread*)p;\n            return priv.locklevel > 0 || priv.critical_count > 0;\n        }\n    }\n}\nelse\n{\n    // NOTE: This is the only place threading versions are checked.  If a new\n    //       version is added, the module code will need to be searched for\n    //       places where version-specific code may be required.  This can be\n    //       easily accomlished by searching for 'Windows' or 'Posix'.\n    static assert( false, \"Unknown threading implementation.\" );\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Thread\n///////////////////////////////////////////////////////////////////////////////\n\n\n/**\n * This class encapsulates all threading functionality for the D\n * programming language.  As thread manipulation is a required facility\n * for garbage collection, all user threads should derive from this\n * class, and instances of this class should never be explicitly deleted.\n * A new thread may be created using either derivation or composition, as\n * in the following example.\n */\nclass Thread\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Initialization\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Initializes a thread object which is associated with a static\n     * D function.\n     *\n     * Params:\n     *  fn = The thread function.\n     *  sz = The stack size for this thread.\n     *\n     * In:\n     *  fn must not be null.\n     */\n    this( void function() fn, size_t sz = 0 ) @safe pure nothrow @nogc\n    in\n    {\n        assert( fn );\n    }\n    do\n    {\n        this(sz);\n        () @trusted { m_fn   = fn; }();\n        m_call = Call.FN;\n        m_curr = &m_main;\n    }\n\n\n    /**\n     * Initializes a thread object which is associated with a dynamic\n     * D function.\n     *\n     * Params:\n     *  dg = The thread function.\n     *  sz = The stack size for this thread.\n     *\n     * In:\n     *  dg must not be null.\n     */\n    this( void delegate() dg, size_t sz = 0 ) @safe pure nothrow @nogc\n    in\n    {\n        assert( dg );\n    }\n    do\n    {\n        this(sz);\n        () @trusted { m_dg   = dg; }();\n        m_call = Call.DG;\n        m_curr = &m_main;\n    }\n\n\n    /**\n     * Cleans up any remaining resources used by this object.\n     */\n    ~this() nothrow @nogc\n    {\n        bool no_context = m_addr == m_addr.init;\n        bool not_registered = !next && !prev && (sm_tbeg !is this);\n\n        if (no_context || not_registered)\n        {\n            return;\n        }\n\n        version (Windows)\n        {\n            m_addr = m_addr.init;\n            CloseHandle( m_hndl );\n            m_hndl = m_hndl.init;\n        }\n        else version (Posix)\n        {\n            pthread_detach( m_addr );\n            m_addr = m_addr.init;\n        }\n        version (Darwin)\n        {\n            m_tmach = m_tmach.init;\n        }\n        rt_tlsgc_destroy( m_tlsgcdata );\n        m_tlsgcdata = null;\n    }\n\n\n    ///////////////////////////////////////////////////////////////////////////\n    // General Actions\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Starts the thread and invokes the function or delegate passed upon\n     * construction.\n     *\n     * In:\n     *  This routine may only be called once per thread instance.\n     *\n     * Throws:\n     *  ThreadException if the thread fails to start.\n     */\n    final Thread start() nothrow\n    in\n    {\n        assert( !next && !prev );\n    }\n    do\n    {\n        auto wasThreaded  = multiThreadedFlag;\n        multiThreadedFlag = true;\n        scope( failure )\n        {\n            if ( !wasThreaded )\n                multiThreadedFlag = false;\n        }\n\n        version (Windows) {} else\n        version (Posix)\n        {\n            pthread_attr_t  attr;\n\n            if ( pthread_attr_init( &attr ) )\n                onThreadError( \"Error initializing thread attributes\" );\n            if ( m_sz && pthread_attr_setstacksize( &attr, m_sz ) )\n                onThreadError( \"Error initializing thread stack size\" );\n        }\n\n        version (Windows)\n        {\n            // NOTE: If a thread is just executing DllMain()\n            //       while another thread is started here, it holds an OS internal\n            //       lock that serializes DllMain with CreateThread. As the code\n            //       might request a synchronization on slock (e.g. in thread_findByAddr()),\n            //       we cannot hold that lock while creating the thread without\n            //       creating a deadlock\n            //\n            // Solution: Create the thread in suspended state and then\n            //       add and resume it with slock acquired\n            assert(m_sz <= uint.max, \"m_sz must be less than or equal to uint.max\");\n            m_hndl = cast(HANDLE) _beginthreadex( null, cast(uint) m_sz, &thread_entryPoint, cast(void*) this, CREATE_SUSPENDED, &m_addr );\n            if ( cast(size_t) m_hndl == 0 )\n                onThreadError( \"Error creating thread\" );\n        }\n\n        slock.lock_nothrow();\n        scope(exit) slock.unlock_nothrow();\n        {\n            ++nAboutToStart;\n            pAboutToStart = cast(Thread*)realloc(pAboutToStart, Thread.sizeof * nAboutToStart);\n            pAboutToStart[nAboutToStart - 1] = this;\n            version (Windows)\n            {\n                if ( ResumeThread( m_hndl ) == -1 )\n                    onThreadError( \"Error resuming thread\" );\n            }\n            else version (Posix)\n            {\n                // NOTE: This is also set to true by thread_entryPoint, but set it\n                //       here as well so the calling thread will see the isRunning\n                //       state immediately.\n                atomicStore!(MemoryOrder.raw)(m_isRunning, true);\n                scope( failure ) atomicStore!(MemoryOrder.raw)(m_isRunning, false);\n\n                version (Shared)\n                {\n                    auto libs = externDFunc!(\"rt.sections_elf_shared.pinLoadedLibraries\",\n                                             void* function() @nogc nothrow)();\n\n                    auto ps = cast(void**).malloc(2 * size_t.sizeof);\n                    if (ps is null) onOutOfMemoryError();\n                    ps[0] = cast(void*)this;\n                    ps[1] = cast(void*)libs;\n                    if ( pthread_create( &m_addr, &attr, &thread_entryPoint, ps ) != 0 )\n                    {\n                        externDFunc!(\"rt.sections_elf_shared.unpinLoadedLibraries\",\n                                     void function(void*) @nogc nothrow)(libs);\n                        .free(ps);\n                        onThreadError( \"Error creating thread\" );\n                    }\n                }\n                else\n                {\n                    if ( pthread_create( &m_addr, &attr, &thread_entryPoint, cast(void*) this ) != 0 )\n                        onThreadError( \"Error creating thread\" );\n                }\n            }\n            version (Darwin)\n            {\n                m_tmach = pthread_mach_thread_np( m_addr );\n                if ( m_tmach == m_tmach.init )\n                    onThreadError( \"Error creating thread\" );\n            }\n\n            return this;\n        }\n    }\n\n    /**\n     * Waits for this thread to complete.  If the thread terminated as the\n     * result of an unhandled exception, this exception will be rethrown.\n     *\n     * Params:\n     *  rethrow = Rethrow any unhandled exception which may have caused this\n     *            thread to terminate.\n     *\n     * Throws:\n     *  ThreadException if the operation fails.\n     *  Any exception not handled by the joined thread.\n     *\n     * Returns:\n     *  Any exception not handled by this thread if rethrow = false, null\n     *  otherwise.\n     */\n    final Throwable join( bool rethrow = true )\n    {\n        version (Windows)\n        {\n            if ( WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 )\n                throw new ThreadException( \"Unable to join thread\" );\n            // NOTE: m_addr must be cleared before m_hndl is closed to avoid\n            //       a race condition with isRunning. The operation is done\n            //       with atomicStore to prevent compiler reordering.\n            atomicStore!(MemoryOrder.raw)(*cast(shared)&m_addr, m_addr.init);\n            CloseHandle( m_hndl );\n            m_hndl = m_hndl.init;\n        }\n        else version (Posix)\n        {\n            if ( pthread_join( m_addr, null ) != 0 )\n                throw new ThreadException( \"Unable to join thread\" );\n            // NOTE: pthread_join acts as a substitute for pthread_detach,\n            //       which is normally called by the dtor.  Setting m_addr\n            //       to zero ensures that pthread_detach will not be called\n            //       on object destruction.\n            m_addr = m_addr.init;\n        }\n        if ( m_unhandled )\n        {\n            if ( rethrow )\n                throw m_unhandled;\n            return m_unhandled;\n        }\n        return null;\n    }\n\n\n    ///////////////////////////////////////////////////////////////////////////\n    // General Properties\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Gets the OS identifier for this thread.\n     *\n     * Returns:\n     *  If the thread hasn't been started yet, returns $(LREF ThreadID)$(D.init).\n     *  Otherwise, returns the result of $(D GetCurrentThreadId) on Windows,\n     *  and $(D pthread_self) on POSIX.\n     *\n     *  The value is unique for the current process.\n     */\n    final @property ThreadID id() @safe @nogc\n    {\n        synchronized( this )\n        {\n            return m_addr;\n        }\n    }\n\n\n    /**\n     * Gets the user-readable label for this thread.\n     *\n     * Returns:\n     *  The name of this thread.\n     */\n    final @property string name() @safe @nogc\n    {\n        synchronized( this )\n        {\n            return m_name;\n        }\n    }\n\n\n    /**\n     * Sets the user-readable label for this thread.\n     *\n     * Params:\n     *  val = The new name of this thread.\n     */\n    final @property void name( string val ) @safe @nogc\n    {\n        synchronized( this )\n        {\n            m_name = val;\n        }\n    }\n\n\n    /**\n     * Gets the daemon status for this thread.  While the runtime will wait for\n     * all normal threads to complete before tearing down the process, daemon\n     * threads are effectively ignored and thus will not prevent the process\n     * from terminating.  In effect, daemon threads will be terminated\n     * automatically by the OS when the process exits.\n     *\n     * Returns:\n     *  true if this is a daemon thread.\n     */\n    final @property bool isDaemon() @safe @nogc\n    {\n        synchronized( this )\n        {\n            return m_isDaemon;\n        }\n    }\n\n\n    /**\n     * Sets the daemon status for this thread.  While the runtime will wait for\n     * all normal threads to complete before tearing down the process, daemon\n     * threads are effectively ignored and thus will not prevent the process\n     * from terminating.  In effect, daemon threads will be terminated\n     * automatically by the OS when the process exits.\n     *\n     * Params:\n     *  val = The new daemon status for this thread.\n     */\n    final @property void isDaemon( bool val ) @safe @nogc\n    {\n        synchronized( this )\n        {\n            m_isDaemon = val;\n        }\n    }\n\n\n    /**\n     * Tests whether this thread is running.\n     *\n     * Returns:\n     *  true if the thread is running, false if not.\n     */\n    final @property bool isRunning() nothrow @nogc\n    {\n        if ( m_addr == m_addr.init )\n        {\n            return false;\n        }\n\n        version (Windows)\n        {\n            uint ecode = 0;\n            GetExitCodeThread( m_hndl, &ecode );\n            return ecode == STILL_ACTIVE;\n        }\n        else version (Posix)\n        {\n            return atomicLoad(m_isRunning);\n        }\n    }\n\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Thread Priority Actions\n    ///////////////////////////////////////////////////////////////////////////\n\n    version (Windows)\n    {\n        @property static int PRIORITY_MIN() @nogc nothrow pure @safe\n        {\n            return THREAD_PRIORITY_IDLE;\n        }\n\n        @property static const(int) PRIORITY_MAX() @nogc nothrow pure @safe\n        {\n            return THREAD_PRIORITY_TIME_CRITICAL;\n        }\n\n        @property static int PRIORITY_DEFAULT() @nogc nothrow pure @safe\n        {\n            return THREAD_PRIORITY_NORMAL;\n        }\n    }\n    else\n    {\n        private struct Priority\n        {\n            int PRIORITY_MIN = int.min;\n            int PRIORITY_DEFAULT = int.min;\n            int PRIORITY_MAX = int.min;\n        }\n\n        /*\n        Lazily loads one of the members stored in a hidden global variable of\n        type `Priority`. Upon the first access of either member, the entire\n        `Priority` structure is initialized. Multiple initializations from\n        different threads calling this function are tolerated.\n\n        `which` must be one of `PRIORITY_MIN`, `PRIORITY_DEFAULT`,\n        `PRIORITY_MAX`.\n        */\n        private static int loadGlobal(string which)()\n        {\n            static shared Priority cache;\n            auto local = atomicLoad(mixin(\"cache.\" ~ which));\n            if (local != local.min) return local;\n            // There will be benign races\n            cache = loadPriorities;\n            return atomicLoad(mixin(\"cache.\" ~ which));\n        }\n\n        /*\n        Loads all priorities and returns them as a `Priority` structure. This\n        function is thread-neutral.\n        */\n        private static Priority loadPriorities() @nogc nothrow @trusted\n        {\n            Priority result;\n            version (Solaris)\n            {\n                pcparms_t pcParms;\n                pcinfo_t pcInfo;\n\n                pcParms.pc_cid = PC_CLNULL;\n                if (priocntl(idtype_t.P_PID, P_MYID, PC_GETPARMS, &pcParms) == -1)\n                    assert( 0, \"Unable to get scheduling class\" );\n\n                pcInfo.pc_cid = pcParms.pc_cid;\n                // PC_GETCLINFO ignores the first two args, use dummy values\n                if (priocntl(idtype_t.P_PID, 0, PC_GETCLINFO, &pcInfo) == -1)\n                    assert( 0, \"Unable to get scheduling class info\" );\n\n                pri_t* clparms = cast(pri_t*)&pcParms.pc_clparms;\n                pri_t* clinfo = cast(pri_t*)&pcInfo.pc_clinfo;\n\n                result.PRIORITY_MAX = clparms[0];\n\n                if (pcInfo.pc_clname == \"RT\")\n                {\n                    m_isRTClass = true;\n\n                    // For RT class, just assume it can't be changed\n                    result.PRIORITY_MIN = clparms[0];\n                    result.PRIORITY_DEFAULT = clparms[0];\n                }\n                else\n                {\n                    m_isRTClass = false;\n\n                    // For all other scheduling classes, there are\n                    // two key values -- uprilim and maxupri.\n                    // maxupri is the maximum possible priority defined\n                    // for the scheduling class, and valid priorities\n                    // range are in [-maxupri, maxupri].\n                    //\n                    // However, uprilim is an upper limit that the\n                    // current thread can set for the current scheduling\n                    // class, which can be less than maxupri.  As such,\n                    // use this value for priorityMax since this is\n                    // the effective maximum.\n\n                    // maxupri\n                    result.PRIORITY_MIN = -clinfo[0];\n                    // by definition\n                    result.PRIORITY_DEFAULT = 0;\n                }\n            }\n            else version (Posix)\n            {\n                int         policy;\n                sched_param param;\n                pthread_getschedparam( pthread_self(), &policy, &param ) == 0\n                    || assert(0, \"Internal error in pthread_getschedparam\");\n\n                result.PRIORITY_MIN = sched_get_priority_min( policy );\n                result.PRIORITY_MIN != -1\n                    || assert(0, \"Internal error in sched_get_priority_min\");\n                result.PRIORITY_DEFAULT = param.sched_priority;\n                result.PRIORITY_MAX = sched_get_priority_max( policy );\n                result.PRIORITY_MAX != -1 ||\n                    assert(0, \"Internal error in sched_get_priority_max\");\n            }\n            else\n            {\n                static assert(0, \"Your code here.\");\n            }\n            return result;\n        }\n\n        /**\n         * The minimum scheduling priority that may be set for a thread.  On\n         * systems where multiple scheduling policies are defined, this value\n         * represents the minimum valid priority for the scheduling policy of\n         * the process.\n         */\n        @property static int PRIORITY_MIN() @nogc nothrow pure @trusted\n        {\n            return (cast(int function() @nogc nothrow pure @safe)\n                &loadGlobal!\"PRIORITY_MIN\")();\n        }\n\n        /**\n         * The maximum scheduling priority that may be set for a thread.  On\n         * systems where multiple scheduling policies are defined, this value\n         * represents the maximum valid priority for the scheduling policy of\n         * the process.\n         */\n        @property static const(int) PRIORITY_MAX() @nogc nothrow pure @trusted\n        {\n            return (cast(int function() @nogc nothrow pure @safe)\n                &loadGlobal!\"PRIORITY_MAX\")();\n        }\n\n        /**\n         * The default scheduling priority that is set for a thread.  On\n         * systems where multiple scheduling policies are defined, this value\n         * represents the default priority for the scheduling policy of\n         * the process.\n         */\n        @property static int PRIORITY_DEFAULT() @nogc nothrow pure @trusted\n        {\n            return (cast(int function() @nogc nothrow pure @safe)\n                &loadGlobal!\"PRIORITY_DEFAULT\")();\n        }\n    }\n\n    version (NetBSD)\n    {\n        //NetBSD does not support priority for default policy\n        // and it is not possible change policy without root access\n        int fakePriority = int.max;\n    }\n\n    /**\n     * Gets the scheduling priority for the associated thread.\n     *\n     * Note: Getting the priority of a thread that already terminated\n     * might return the default priority.\n     *\n     * Returns:\n     *  The scheduling priority of this thread.\n     */\n    final @property int priority()\n    {\n        version (Windows)\n        {\n            return GetThreadPriority( m_hndl );\n        }\n        else version (NetBSD)\n        {\n           return fakePriority==int.max? PRIORITY_DEFAULT : fakePriority;\n        }\n        else version (Posix)\n        {\n            int         policy;\n            sched_param param;\n\n            if (auto err = pthread_getschedparam(m_addr, &policy, &param))\n            {\n                // ignore error if thread is not running => Bugzilla 8960\n                if (!atomicLoad(m_isRunning)) return PRIORITY_DEFAULT;\n                throw new ThreadException(\"Unable to get thread priority\");\n            }\n            return param.sched_priority;\n        }\n    }\n\n\n    /**\n     * Sets the scheduling priority for the associated thread.\n     *\n     * Note: Setting the priority of a thread that already terminated\n     * might have no effect.\n     *\n     * Params:\n     *  val = The new scheduling priority of this thread.\n     */\n    final @property void priority( int val )\n    in\n    {\n        assert(val >= PRIORITY_MIN);\n        assert(val <= PRIORITY_MAX);\n    }\n    do\n    {\n        version (Windows)\n        {\n            if ( !SetThreadPriority( m_hndl, val ) )\n                throw new ThreadException( \"Unable to set thread priority\" );\n        }\n        else version (Solaris)\n        {\n            // the pthread_setschedprio(3c) and pthread_setschedparam functions\n            // are broken for the default (TS / time sharing) scheduling class.\n            // instead, we use priocntl(2) which gives us the desired behavior.\n\n            // We hardcode the min and max priorities to the current value\n            // so this is a no-op for RT threads.\n            if (m_isRTClass)\n                return;\n\n            pcparms_t   pcparm;\n\n            pcparm.pc_cid = PC_CLNULL;\n            if (priocntl(idtype_t.P_LWPID, P_MYID, PC_GETPARMS, &pcparm) == -1)\n                throw new ThreadException( \"Unable to get scheduling class\" );\n\n            pri_t* clparms = cast(pri_t*)&pcparm.pc_clparms;\n\n            // clparms is filled in by the PC_GETPARMS call, only necessary\n            // to adjust the element that contains the thread priority\n            clparms[1] = cast(pri_t) val;\n\n            if (priocntl(idtype_t.P_LWPID, P_MYID, PC_SETPARMS, &pcparm) == -1)\n                throw new ThreadException( \"Unable to set scheduling class\" );\n        }\n        else version (NetBSD)\n        {\n           fakePriority = val;\n        }\n        else version (Posix)\n        {\n            static if (__traits(compiles, pthread_setschedprio))\n            {\n                if (auto err = pthread_setschedprio(m_addr, val))\n                {\n                    // ignore error if thread is not running => Bugzilla 8960\n                    if (!atomicLoad(m_isRunning)) return;\n                    throw new ThreadException(\"Unable to set thread priority\");\n                }\n            }\n            else\n            {\n                // NOTE: pthread_setschedprio is not implemented on Darwin, FreeBSD or DragonFlyBSD, so use\n                //       the more complicated get/set sequence below.\n                int         policy;\n                sched_param param;\n\n                if (auto err = pthread_getschedparam(m_addr, &policy, &param))\n                {\n                    // ignore error if thread is not running => Bugzilla 8960\n                    if (!atomicLoad(m_isRunning)) return;\n                    throw new ThreadException(\"Unable to set thread priority\");\n                }\n                param.sched_priority = val;\n                if (auto err = pthread_setschedparam(m_addr, policy, &param))\n                {\n                    // ignore error if thread is not running => Bugzilla 8960\n                    if (!atomicLoad(m_isRunning)) return;\n                    throw new ThreadException(\"Unable to set thread priority\");\n                }\n            }\n        }\n    }\n\n\n    unittest\n    {\n        auto thr = Thread.getThis();\n        immutable prio = thr.priority;\n        scope (exit) thr.priority = prio;\n\n        assert(prio == PRIORITY_DEFAULT);\n        assert(prio >= PRIORITY_MIN && prio <= PRIORITY_MAX);\n        thr.priority = PRIORITY_MIN;\n        assert(thr.priority == PRIORITY_MIN);\n        thr.priority = PRIORITY_MAX;\n        assert(thr.priority == PRIORITY_MAX);\n    }\n\n    unittest // Bugzilla 8960\n    {\n        import core.sync.semaphore;\n\n        auto thr = new Thread({});\n        thr.start();\n        Thread.sleep(1.msecs);       // wait a little so the thread likely has finished\n        thr.priority = PRIORITY_MAX; // setting priority doesn't cause error\n        auto prio = thr.priority;    // getting priority doesn't cause error\n        assert(prio >= PRIORITY_MIN && prio <= PRIORITY_MAX);\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Actions on Calling Thread\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Suspends the calling thread for at least the supplied period.  This may\n     * result in multiple OS calls if period is greater than the maximum sleep\n     * duration supported by the operating system.\n     *\n     * Params:\n     *  val = The minimum duration the calling thread should be suspended.\n     *\n     * In:\n     *  period must be non-negative.\n     *\n     * Example:\n     * ------------------------------------------------------------------------\n     *\n     * Thread.sleep( dur!(\"msecs\")( 50 ) );  // sleep for 50 milliseconds\n     * Thread.sleep( dur!(\"seconds\")( 5 ) ); // sleep for 5 seconds\n     *\n     * ------------------------------------------------------------------------\n     */\n    static void sleep( Duration val ) @nogc nothrow\n    in\n    {\n        assert( !val.isNegative );\n    }\n    do\n    {\n        version (Windows)\n        {\n            auto maxSleepMillis = dur!(\"msecs\")( uint.max - 1 );\n\n            // avoid a non-zero time to be round down to 0\n            if ( val > dur!\"msecs\"( 0 ) && val < dur!\"msecs\"( 1 ) )\n                val = dur!\"msecs\"( 1 );\n\n            // NOTE: In instances where all other threads in the process have a\n            //       lower priority than the current thread, the current thread\n            //       will not yield with a sleep time of zero.  However, unlike\n            //       yield(), the user is not asking for a yield to occur but\n            //       only for execution to suspend for the requested interval.\n            //       Therefore, expected performance may not be met if a yield\n            //       is forced upon the user.\n            while ( val > maxSleepMillis )\n            {\n                Sleep( cast(uint)\n                       maxSleepMillis.total!\"msecs\" );\n                val -= maxSleepMillis;\n            }\n            Sleep( cast(uint) val.total!\"msecs\" );\n        }\n        else version (Posix)\n        {\n            timespec tin  = void;\n            timespec tout = void;\n\n            val.split!(\"seconds\", \"nsecs\")(tin.tv_sec, tin.tv_nsec);\n            if ( val.total!\"seconds\" > tin.tv_sec.max )\n                tin.tv_sec  = tin.tv_sec.max;\n            while ( true )\n            {\n                if ( !nanosleep( &tin, &tout ) )\n                    return;\n                if ( errno != EINTR )\n                    assert(0, \"Unable to sleep for the specified duration\");\n                tin = tout;\n            }\n        }\n    }\n\n\n    /**\n     * Forces a context switch to occur away from the calling thread.\n     */\n    static void yield() @nogc nothrow\n    {\n        version (Windows)\n            SwitchToThread();\n        else version (Posix)\n            sched_yield();\n    }\n\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Thread Accessors\n    ///////////////////////////////////////////////////////////////////////////\n\n    /**\n     * Provides a reference to the calling thread.\n     *\n     * Returns:\n     *  The thread object representing the calling thread.  The result of\n     *  deleting this object is undefined.  If the current thread is not\n     *  attached to the runtime, a null reference is returned.\n     */\n    static Thread getThis() @safe nothrow @nogc\n    {\n        // NOTE: This function may not be called until thread_init has\n        //       completed.  See thread_suspendAll for more information\n        //       on why this might occur.\n        return sm_this;\n    }\n\n\n    /**\n     * Provides a list of all threads currently being tracked by the system.\n     * Note that threads in the returned array might no longer run (see\n     * $(D Thread.)$(LREF isRunning)).\n     *\n     * Returns:\n     *  An array containing references to all threads currently being\n     *  tracked by the system.  The result of deleting any contained\n     *  objects is undefined.\n     */\n    static Thread[] getAll()\n    {\n        static void resize(ref Thread[] buf, size_t nlen)\n        {\n            buf.length = nlen;\n        }\n        return getAllImpl!resize();\n    }\n\n\n    /**\n     * Operates on all threads currently being tracked by the system.  The\n     * result of deleting any Thread object is undefined.\n     * Note that threads passed to the callback might no longer run (see\n     * $(D Thread.)$(LREF isRunning)).\n     *\n     * Params:\n     *  dg = The supplied code as a delegate.\n     *\n     * Returns:\n     *  Zero if all elemented are visited, nonzero if not.\n     */\n    static int opApply(scope int delegate(ref Thread) dg)\n    {\n        import core.stdc.stdlib : free, realloc;\n\n        static void resize(ref Thread[] buf, size_t nlen)\n        {\n            buf = (cast(Thread*)realloc(buf.ptr, nlen * Thread.sizeof))[0 .. nlen];\n        }\n        auto buf = getAllImpl!resize;\n        scope(exit) if (buf.ptr) free(buf.ptr);\n\n        foreach (t; buf)\n        {\n            if (auto res = dg(t))\n                return res;\n        }\n        return 0;\n    }\n\n    unittest\n    {\n        auto t1 = new Thread({\n            foreach (_; 0 .. 20)\n                Thread.getAll;\n        }).start;\n        auto t2 = new Thread({\n            foreach (_; 0 .. 20)\n                GC.collect;\n        }).start;\n        t1.join();\n        t2.join();\n    }\n\n    private static Thread[] getAllImpl(alias resize)()\n    {\n        import core.atomic;\n\n        Thread[] buf;\n        while (true)\n        {\n            immutable len = atomicLoad!(MemoryOrder.raw)(*cast(shared)&sm_tlen);\n            resize(buf, len);\n            assert(buf.length == len);\n            synchronized (slock)\n            {\n                if (len == sm_tlen)\n                {\n                    size_t pos;\n                    for (Thread t = sm_tbeg; t; t = t.next)\n                        buf[pos++] = t;\n                    return buf;\n                }\n            }\n        }\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Stuff That Should Go Away\n    ///////////////////////////////////////////////////////////////////////////\n\n\nprivate:\n    //\n    // Initializes a thread object which has no associated executable function.\n    // This is used for the main thread initialized in thread_init().\n    //\n    this(size_t sz = 0) @safe pure nothrow @nogc\n    {\n        if (sz)\n        {\n            version (Posix)\n            {\n                // stack size must be a multiple of PAGESIZE\n                sz += PAGESIZE - 1;\n                sz -= sz % PAGESIZE;\n                // and at least PTHREAD_STACK_MIN\n                if (PTHREAD_STACK_MIN > sz)\n                    sz = PTHREAD_STACK_MIN;\n            }\n            m_sz = sz;\n        }\n        m_call = Call.NO;\n        m_curr = &m_main;\n    }\n\n\n    //\n    // Thread entry point.  Invokes the function or delegate passed on\n    // construction (if any).\n    //\n    final void run()\n    {\n        switch ( m_call )\n        {\n        case Call.FN:\n            m_fn();\n            break;\n        case Call.DG:\n            m_dg();\n            break;\n        default:\n            break;\n        }\n    }\n\n\nprivate:\n    //\n    // The type of routine passed on thread construction.\n    //\n    enum Call\n    {\n        NO,\n        FN,\n        DG\n    }\n\n\n    //\n    // Standard types\n    //\n    version (Windows)\n    {\n        alias TLSKey = uint;\n    }\n    else version (Posix)\n    {\n        alias TLSKey = pthread_key_t;\n    }\n\n\n    //\n    // Local storage\n    //\n    static Thread       sm_this;\n\n\n    //\n    // Main process thread\n    //\n    __gshared Thread    sm_main;\n\n    version (FreeBSD)\n    {\n        // set when suspend failed and should be retried, see Issue 13416\n        shared bool m_suspendagain;\n    }\n\n\n    //\n    // Standard thread data\n    //\n    version (Windows)\n    {\n        HANDLE          m_hndl;\n    }\n    else version (Darwin)\n    {\n        mach_port_t     m_tmach;\n    }\n    ThreadID            m_addr;\n    Call                m_call;\n    string              m_name;\n    union\n    {\n        void function() m_fn;\n        void delegate() m_dg;\n    }\n    size_t              m_sz;\n    version (Posix)\n    {\n        shared bool     m_isRunning;\n    }\n    bool                m_isDaemon;\n    bool                m_isInCriticalRegion;\n    Throwable           m_unhandled;\n\n    version (Solaris)\n    {\n        __gshared bool m_isRTClass;\n    }\n\nprivate:\n    ///////////////////////////////////////////////////////////////////////////\n    // Storage of Active Thread\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    //\n    // Sets a thread-local reference to the current thread object.\n    //\n    static void setThis( Thread t ) nothrow @nogc\n    {\n        sm_this = t;\n    }\n\n\nprivate:\n    ///////////////////////////////////////////////////////////////////////////\n    // Thread Context and GC Scanning Support\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    final void pushContext( Context* c ) nothrow @nogc\n    in\n    {\n        assert( !c.within );\n    }\n    do\n    {\n        m_curr.ehContext = swapContext(c.ehContext);\n        c.within = m_curr;\n        m_curr = c;\n    }\n\n\n    final void popContext() nothrow @nogc\n    in\n    {\n        assert( m_curr && m_curr.within );\n    }\n    do\n    {\n        Context* c = m_curr;\n        m_curr = c.within;\n        c.ehContext = swapContext(m_curr.ehContext);\n        c.within = null;\n    }\n\n\n    final Context* topContext() nothrow @nogc\n    in\n    {\n        assert( m_curr );\n    }\n    do\n    {\n        return m_curr;\n    }\n\n\n    static struct Context\n    {\n        void*           bstack,\n                        tstack;\n\n        /// Slot for the EH implementation to keep some state for each stack\n        /// (will be necessary for exception chaining, etc.). Opaque as far as\n        /// we are concerned here.\n        void*           ehContext;\n\n        Context*        within;\n        Context*        next,\n                        prev;\n    }\n\n\n    Context             m_main;\n    Context*            m_curr;\n    bool                m_lock;\n    void*               m_tlsgcdata;\n\n    version (Windows)\n    {\n      version (X86)\n      {\n        uint[8]         m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax\n      }\n      else version (X86_64)\n      {\n        ulong[16]       m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax\n                               // r8,r9,r10,r11,r12,r13,r14,r15\n      }\n      else\n      {\n        static assert(false, \"Architecture not supported.\" );\n      }\n    }\n    else version (Darwin)\n    {\n      version (X86)\n      {\n        uint[8]         m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax\n      }\n      else version (X86_64)\n      {\n        ulong[16]       m_reg; // rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax\n                               // r8,r9,r10,r11,r12,r13,r14,r15\n      }\n      else\n      {\n        static assert(false, \"Architecture not supported.\" );\n      }\n    }\n\n\nprivate:\n    ///////////////////////////////////////////////////////////////////////////\n    // GC Scanning Support\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    // NOTE: The GC scanning process works like so:\n    //\n    //          1. Suspend all threads.\n    //          2. Scan the stacks of all suspended threads for roots.\n    //          3. Resume all threads.\n    //\n    //       Step 1 and 3 require a list of all threads in the system, while\n    //       step 2 requires a list of all thread stacks (each represented by\n    //       a Context struct).  Traditionally, there was one stack per thread\n    //       and the Context structs were not necessary.  However, Fibers have\n    //       changed things so that each thread has its own 'main' stack plus\n    //       an arbitrary number of nested stacks (normally referenced via\n    //       m_curr).  Also, there may be 'free-floating' stacks in the system,\n    //       which are Fibers that are not currently executing on any specific\n    //       thread but are still being processed and still contain valid\n    //       roots.\n    //\n    //       To support all of this, the Context struct has been created to\n    //       represent a stack range, and a global list of Context structs has\n    //       been added to enable scanning of these stack ranges.  The lifetime\n    //       (and presence in the Context list) of a thread's 'main' stack will\n    //       be equivalent to the thread's lifetime.  So the Ccontext will be\n    //       added to the list on thread entry, and removed from the list on\n    //       thread exit (which is essentially the same as the presence of a\n    //       Thread object in its own global list).  The lifetime of a Fiber's\n    //       context, however, will be tied to the lifetime of the Fiber object\n    //       itself, and Fibers are expected to add/remove their Context struct\n    //       on construction/deletion.\n\n\n    //\n    // All use of the global thread lists/array should synchronize on this lock.\n    //\n    // Careful as the GC acquires this lock after the GC lock to suspend all\n    // threads any GC usage with slock held can result in a deadlock through\n    // lock order inversion.\n    @property static Mutex slock() nothrow @nogc\n    {\n        return cast(Mutex)_locks[0].ptr;\n    }\n\n    @property static Mutex criticalRegionLock() nothrow @nogc\n    {\n        return cast(Mutex)_locks[1].ptr;\n    }\n\n    __gshared align(Mutex.alignof) void[__traits(classInstanceSize, Mutex)][2] _locks;\n\n    static void initLocks() @nogc\n    {\n        foreach (ref lock; _locks)\n        {\n            lock[] = typeid(Mutex).initializer[];\n            (cast(Mutex)lock.ptr).__ctor();\n        }\n    }\n\n    static void termLocks() @nogc\n    {\n        foreach (ref lock; _locks)\n            (cast(Mutex)lock.ptr).__dtor();\n    }\n\n    __gshared Context*  sm_cbeg;\n\n    __gshared Thread    sm_tbeg;\n    __gshared size_t    sm_tlen;\n\n    // can't use rt.util.array in public code\n    __gshared Thread* pAboutToStart;\n    __gshared size_t nAboutToStart;\n\n    //\n    // Used for ordering threads in the global thread list.\n    //\n    Thread              prev;\n    Thread              next;\n\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Global Context List Operations\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    //\n    // Add a context to the global context list.\n    //\n    static void add( Context* c ) nothrow @nogc\n    in\n    {\n        assert( c );\n        assert( !c.next && !c.prev );\n    }\n    do\n    {\n        slock.lock_nothrow();\n        scope(exit) slock.unlock_nothrow();\n        assert(!suspendDepth); // must be 0 b/c it's only set with slock held\n\n        if (sm_cbeg)\n        {\n            c.next = sm_cbeg;\n            sm_cbeg.prev = c;\n        }\n        sm_cbeg = c;\n    }\n\n\n    //\n    // Remove a context from the global context list.\n    //\n    // This assumes slock being acquired. This isn't done here to\n    // avoid double locking when called from remove(Thread)\n    static void remove( Context* c ) nothrow @nogc\n    in\n    {\n        assert( c );\n        assert( c.next || c.prev );\n    }\n    do\n    {\n        if ( c.prev )\n            c.prev.next = c.next;\n        if ( c.next )\n            c.next.prev = c.prev;\n        if ( sm_cbeg == c )\n            sm_cbeg = c.next;\n        // NOTE: Don't null out c.next or c.prev because opApply currently\n        //       follows c.next after removing a node.  This could be easily\n        //       addressed by simply returning the next node from this\n        //       function, however, a context should never be re-added to the\n        //       list anyway and having next and prev be non-null is a good way\n        //       to ensure that.\n    }\n\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Global Thread List Operations\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    //\n    // Add a thread to the global thread list.\n    //\n    static void add( Thread t, bool rmAboutToStart = true ) nothrow @nogc\n    in\n    {\n        assert( t );\n        assert( !t.next && !t.prev );\n    }\n    do\n    {\n        slock.lock_nothrow();\n        scope(exit) slock.unlock_nothrow();\n        assert(t.isRunning); // check this with slock to ensure pthread_create already returned\n        assert(!suspendDepth); // must be 0 b/c it's only set with slock held\n\n        if (rmAboutToStart)\n        {\n            size_t idx = -1;\n            foreach (i, thr; pAboutToStart[0 .. nAboutToStart])\n            {\n                if (thr is t)\n                {\n                    idx = i;\n                    break;\n                }\n            }\n            assert(idx != -1);\n            import core.stdc.string : memmove;\n            memmove(pAboutToStart + idx, pAboutToStart + idx + 1, Thread.sizeof * (nAboutToStart - idx - 1));\n            pAboutToStart =\n                cast(Thread*)realloc(pAboutToStart, Thread.sizeof * --nAboutToStart);\n        }\n\n        if (sm_tbeg)\n        {\n            t.next = sm_tbeg;\n            sm_tbeg.prev = t;\n        }\n        sm_tbeg = t;\n        ++sm_tlen;\n    }\n\n\n    //\n    // Remove a thread from the global thread list.\n    //\n    static void remove( Thread t ) nothrow @nogc\n    in\n    {\n        assert( t );\n    }\n    do\n    {\n        // Thread was already removed earlier, might happen b/c of thread_detachInstance\n        if (!t.next && !t.prev && (sm_tbeg !is t))\n            return;\n\n        slock.lock_nothrow();\n        {\n            // NOTE: When a thread is removed from the global thread list its\n            //       main context is invalid and should be removed as well.\n            //       It is possible that t.m_curr could reference more\n            //       than just the main context if the thread exited abnormally\n            //       (if it was terminated), but we must assume that the user\n            //       retains a reference to them and that they may be re-used\n            //       elsewhere.  Therefore, it is the responsibility of any\n            //       object that creates contexts to clean them up properly\n            //       when it is done with them.\n            remove( &t.m_main );\n\n            if ( t.prev )\n                t.prev.next = t.next;\n            if ( t.next )\n                t.next.prev = t.prev;\n            if ( sm_tbeg is t )\n                sm_tbeg = t.next;\n            t.prev = t.next = null;\n            --sm_tlen;\n        }\n        // NOTE: Don't null out t.next or t.prev because opApply currently\n        //       follows t.next after removing a node.  This could be easily\n        //       addressed by simply returning the next node from this\n        //       function, however, a thread should never be re-added to the\n        //       list anyway and having next and prev be non-null is a good way\n        //       to ensure that.\n        slock.unlock_nothrow();\n    }\n}\n\n///\nunittest\n{\n    class DerivedThread : Thread\n    {\n        this()\n        {\n            super(&run);\n        }\n\n    private:\n        void run()\n        {\n            // Derived thread running.\n        }\n    }\n\n    void threadFunc()\n    {\n        // Composed thread running.\n    }\n\n    // create and start instances of each type\n    auto derived = new DerivedThread().start();\n    auto composed = new Thread(&threadFunc).start();\n    new Thread({\n        // Codes to run in the newly created thread.\n    }).start();\n}\n\nunittest\n{\n    int x = 0;\n\n    new Thread(\n    {\n        x++;\n    }).start().join();\n    assert( x == 1 );\n}\n\n\nunittest\n{\n    enum MSG = \"Test message.\";\n    string caughtMsg;\n\n    try\n    {\n        new Thread(\n        {\n            throw new Exception( MSG );\n        }).start().join();\n        assert( false, \"Expected rethrown exception.\" );\n    }\n    catch ( Throwable t )\n    {\n        assert( t.msg == MSG );\n    }\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// GC Support Routines\n///////////////////////////////////////////////////////////////////////////////\n\nversion (CoreDdoc)\n{\n    /**\n     * Instruct the thread module, when initialized, to use a different set of\n     * signals besides SIGUSR1 and SIGUSR2 for suspension and resumption of threads.\n     * This function should be called at most once, prior to thread_init().\n     * This function is Posix-only.\n     */\n    extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo) nothrow @nogc\n    {\n    }\n}\nelse version (Posix)\n{\n    extern (C) void thread_setGCSignals(int suspendSignalNo, int resumeSignalNo) nothrow @nogc\n    in\n    {\n        assert(suspendSignalNumber == 0);\n        assert(resumeSignalNumber  == 0);\n        assert(suspendSignalNo != 0);\n        assert(resumeSignalNo  != 0);\n    }\n    out\n    {\n        assert(suspendSignalNumber != 0);\n        assert(resumeSignalNumber  != 0);\n    }\n    do\n    {\n        suspendSignalNumber = suspendSignalNo;\n        resumeSignalNumber  = resumeSignalNo;\n    }\n}\n\nversion (Posix)\n{\n    __gshared int suspendSignalNumber;\n    __gshared int resumeSignalNumber;\n}\n\n/**\n * Initializes the thread module.  This function must be called by the\n * garbage collector on startup and before any other thread routines\n * are called.\n */\nextern (C) void thread_init() @nogc\n{\n    // NOTE: If thread_init itself performs any allocations then the thread\n    //       routines reserved for garbage collector use may be called while\n    //       thread_init is being processed.  However, since no memory should\n    //       exist to be scanned at this point, it is sufficient for these\n    //       functions to detect the condition and return immediately.\n\n    Thread.initLocks();\n    // The Android VM runtime intercepts SIGUSR1 and apparently doesn't allow\n    // its signal handler to run, so swap the two signals on Android, since\n    // thread_resumeHandler does nothing.\n    version (Android) thread_setGCSignals(SIGUSR2, SIGUSR1);\n\n    version (Darwin)\n    {\n    }\n    else version (Posix)\n    {\n        if ( suspendSignalNumber == 0 )\n        {\n            suspendSignalNumber = SIGUSR1;\n        }\n\n        if ( resumeSignalNumber == 0 )\n        {\n            resumeSignalNumber = SIGUSR2;\n        }\n\n        int         status;\n        sigaction_t sigusr1 = void;\n        sigaction_t sigusr2 = void;\n\n        // This is a quick way to zero-initialize the structs without using\n        // memset or creating a link dependency on their static initializer.\n        (cast(byte*) &sigusr1)[0 .. sigaction_t.sizeof] = 0;\n        (cast(byte*) &sigusr2)[0 .. sigaction_t.sizeof] = 0;\n\n        // NOTE: SA_RESTART indicates that system calls should restart if they\n        //       are interrupted by a signal, but this is not available on all\n        //       Posix systems, even those that support multithreading.\n        static if ( __traits( compiles, SA_RESTART ) )\n            sigusr1.sa_flags = SA_RESTART;\n        else\n            sigusr1.sa_flags   = 0;\n        sigusr1.sa_handler = &thread_suspendHandler;\n        // NOTE: We want to ignore all signals while in this handler, so fill\n        //       sa_mask to indicate this.\n        status = sigfillset( &sigusr1.sa_mask );\n        assert( status == 0 );\n\n        // NOTE: Since resumeSignalNumber should only be issued for threads within the\n        //       suspend handler, we don't want this signal to trigger a\n        //       restart.\n        sigusr2.sa_flags   = 0;\n        sigusr2.sa_handler = &thread_resumeHandler;\n        // NOTE: We want to ignore all signals while in this handler, so fill\n        //       sa_mask to indicate this.\n        status = sigfillset( &sigusr2.sa_mask );\n        assert( status == 0 );\n\n        status = sigaction( suspendSignalNumber, &sigusr1, null );\n        assert( status == 0 );\n\n        status = sigaction( resumeSignalNumber, &sigusr2, null );\n        assert( status == 0 );\n\n        status = sem_init( &suspendCount, 0, 0 );\n        assert( status == 0 );\n    }\n    if (typeid(Thread).initializer.ptr)\n        _mainThreadStore[] = typeid(Thread).initializer[];\n    Thread.sm_main = attachThread((cast(Thread)_mainThreadStore.ptr).__ctor());\n}\n\nprivate __gshared align(Thread.alignof) void[__traits(classInstanceSize, Thread)] _mainThreadStore;\n\nextern (C) void _d_monitordelete_nogc(Object h) @nogc;\n\n/**\n * Terminates the thread module. No other thread routine may be called\n * afterwards.\n */\nextern (C) void thread_term() @nogc\n{\n    assert(_mainThreadStore.ptr is cast(void*) Thread.sm_main);\n\n    // destruct manually as object.destroy is not @nogc\n    Thread.sm_main.__dtor();\n    _d_monitordelete_nogc(Thread.sm_main);\n    if (typeid(Thread).initializer.ptr)\n        _mainThreadStore[] = typeid(Thread).initializer[];\n    Thread.sm_main = null;\n\n    assert(Thread.sm_tbeg && Thread.sm_tlen == 1);\n    assert(!Thread.nAboutToStart);\n    if (Thread.pAboutToStart) // in case realloc(p, 0) doesn't return null\n    {\n        free(Thread.pAboutToStart);\n        Thread.pAboutToStart = null;\n    }\n    Thread.termLocks();\n}\n\n\n/**\n *\n */\nextern (C) bool thread_isMainThread() nothrow @nogc\n{\n    return Thread.getThis() is Thread.sm_main;\n}\n\n\n/**\n * Registers the calling thread for use with the D Runtime.  If this routine\n * is called for a thread which is already registered, no action is performed.\n *\n * NOTE: This routine does not run thread-local static constructors when called.\n *       If full functionality as a D thread is desired, the following function\n *       must be called after thread_attachThis:\n *\n *       extern (C) void rt_moduleTlsCtor();\n */\nextern (C) Thread thread_attachThis()\n{\n    if (auto t = Thread.getThis())\n        return t;\n\n    return attachThread(new Thread());\n}\n\nprivate Thread attachThread(Thread thisThread) @nogc\n{\n    Thread.Context* thisContext = &thisThread.m_main;\n    assert( thisContext == thisThread.m_curr );\n\n    version (Windows)\n    {\n        thisThread.m_addr  = GetCurrentThreadId();\n        thisThread.m_hndl  = GetCurrentThreadHandle();\n        thisContext.bstack = getStackBottom();\n        thisContext.tstack = thisContext.bstack;\n    }\n    else version (Posix)\n    {\n        thisThread.m_addr  = pthread_self();\n        thisContext.bstack = getStackBottom();\n        thisContext.tstack = thisContext.bstack;\n\n        atomicStore!(MemoryOrder.raw)(thisThread.m_isRunning, true);\n    }\n    thisThread.m_isDaemon = true;\n    thisThread.m_tlsgcdata = rt_tlsgc_init();\n    Thread.setThis( thisThread );\n\n    version (Darwin)\n    {\n        thisThread.m_tmach = pthread_mach_thread_np( thisThread.m_addr );\n        assert( thisThread.m_tmach != thisThread.m_tmach.init );\n    }\n\n    Thread.add( thisThread, false );\n    Thread.add( thisContext );\n    if ( Thread.sm_main !is null )\n        multiThreadedFlag = true;\n    return thisThread;\n}\n\n\nversion (Windows)\n{\n    // NOTE: These calls are not safe on Posix systems that use signals to\n    //       perform garbage collection.  The suspendHandler uses getThis()\n    //       to get the thread handle so getThis() must be a simple call.\n    //       Mutexes can't safely be acquired inside signal handlers, and\n    //       even if they could, the mutex needed (Thread.slock) is held by\n    //       thread_suspendAll().  So in short, these routines will remain\n    //       Windows-specific.  If they are truly needed elsewhere, the\n    //       suspendHandler will need a way to call a version of getThis()\n    //       that only does the TLS lookup without the fancy fallback stuff.\n\n    /// ditto\n    extern (C) Thread thread_attachByAddr( ThreadID addr )\n    {\n        return thread_attachByAddrB( addr, getThreadStackBottom( addr ) );\n    }\n\n\n    /// ditto\n    extern (C) Thread thread_attachByAddrB( ThreadID addr, void* bstack )\n    {\n        GC.disable(); scope(exit) GC.enable();\n\n        if (auto t = thread_findByAddr(addr))\n            return t;\n\n        Thread          thisThread  = new Thread();\n        Thread.Context* thisContext = &thisThread.m_main;\n        assert( thisContext == thisThread.m_curr );\n\n        thisThread.m_addr  = addr;\n        thisContext.bstack = bstack;\n        thisContext.tstack = thisContext.bstack;\n\n        thisThread.m_isDaemon = true;\n\n        if ( addr == GetCurrentThreadId() )\n        {\n            thisThread.m_hndl = GetCurrentThreadHandle();\n            thisThread.m_tlsgcdata = rt_tlsgc_init();\n            Thread.setThis( thisThread );\n        }\n        else\n        {\n            thisThread.m_hndl = OpenThreadHandle( addr );\n            impersonate_thread(addr,\n            {\n                thisThread.m_tlsgcdata = rt_tlsgc_init();\n                Thread.setThis( thisThread );\n            });\n        }\n\n        Thread.add( thisThread, false );\n        Thread.add( thisContext );\n        if ( Thread.sm_main !is null )\n            multiThreadedFlag = true;\n        return thisThread;\n    }\n}\n\n\n/**\n * Deregisters the calling thread from use with the runtime.  If this routine\n * is called for a thread which is not registered, the result is undefined.\n *\n * NOTE: This routine does not run thread-local static destructors when called.\n *       If full functionality as a D thread is desired, the following function\n *       must be called after thread_detachThis, particularly if the thread is\n *       being detached at some indeterminate time before program termination:\n *\n *       $(D extern(C) void rt_moduleTlsDtor();)\n */\nextern (C) void thread_detachThis() nothrow @nogc\n{\n    if (auto t = Thread.getThis())\n        Thread.remove(t);\n}\n\n\n/**\n * Deregisters the given thread from use with the runtime.  If this routine\n * is called for a thread which is not registered, the result is undefined.\n *\n * NOTE: This routine does not run thread-local static destructors when called.\n *       If full functionality as a D thread is desired, the following function\n *       must be called by the detached thread, particularly if the thread is\n *       being detached at some indeterminate time before program termination:\n *\n *       $(D extern(C) void rt_moduleTlsDtor();)\n */\nextern (C) void thread_detachByAddr( ThreadID addr )\n{\n    if ( auto t = thread_findByAddr( addr ) )\n        Thread.remove( t );\n}\n\n\n/// ditto\nextern (C) void thread_detachInstance( Thread t ) nothrow @nogc\n{\n    Thread.remove( t );\n}\n\n\nunittest\n{\n    import core.sync.semaphore;\n    auto sem = new Semaphore();\n\n    auto t = new Thread(\n    {\n        sem.notify();\n        Thread.sleep(100.msecs);\n    }).start();\n\n    sem.wait(); // thread cannot be detached while being started\n    thread_detachInstance(t);\n    foreach (t2; Thread)\n        assert(t !is t2);\n    t.join();\n}\n\n\n/**\n * Search the list of all threads for a thread with the given thread identifier.\n *\n * Params:\n *  addr = The thread identifier to search for.\n * Returns:\n *  The thread object associated with the thread identifier, null if not found.\n */\nstatic Thread thread_findByAddr( ThreadID addr )\n{\n    Thread.slock.lock_nothrow();\n    scope(exit) Thread.slock.unlock_nothrow();\n\n    // also return just spawned thread so that\n    // DLL_THREAD_ATTACH knows it's a D thread\n    foreach (t; Thread.pAboutToStart[0 .. Thread.nAboutToStart])\n        if (t.m_addr == addr)\n            return t;\n\n    foreach (t; Thread)\n        if (t.m_addr == addr)\n            return t;\n\n    return null;\n}\n\n\n/**\n * Sets the current thread to a specific reference. Only to be used\n * when dealing with externally-created threads (in e.g. C code).\n * The primary use of this function is when Thread.getThis() must\n * return a sensible value in, for example, TLS destructors. In\n * other words, don't touch this unless you know what you're doing.\n *\n * Params:\n *  t = A reference to the current thread. May be null.\n */\nextern (C) void thread_setThis(Thread t) nothrow @nogc\n{\n    Thread.setThis(t);\n}\n\n\n/**\n * Joins all non-daemon threads that are currently running.  This is done by\n * performing successive scans through the thread list until a scan consists\n * of only daemon threads.\n */\nextern (C) void thread_joinAll()\n{\n Lagain:\n    Thread.slock.lock_nothrow();\n    // wait for just spawned threads\n    if (Thread.nAboutToStart)\n    {\n        Thread.slock.unlock_nothrow();\n        Thread.yield();\n        goto Lagain;\n    }\n\n    // join all non-daemon threads, the main thread is also a daemon\n    auto t = Thread.sm_tbeg;\n    while (t)\n    {\n        if (!t.isRunning)\n        {\n            auto tn = t.next;\n            Thread.remove(t);\n            t = tn;\n        }\n        else if (t.isDaemon)\n        {\n            t = t.next;\n        }\n        else\n        {\n            Thread.slock.unlock_nothrow();\n            t.join(); // might rethrow\n            goto Lagain; // must restart iteration b/c of unlock\n        }\n    }\n    Thread.slock.unlock_nothrow();\n}\n\n\n/**\n * Performs intermediate shutdown of the thread module.\n */\nshared static ~this()\n{\n    // NOTE: The functionality related to garbage collection must be minimally\n    //       operable after this dtor completes.  Therefore, only minimal\n    //       cleanup may occur.\n    auto t = Thread.sm_tbeg;\n    while (t)\n    {\n        auto tn = t.next;\n        if (!t.isRunning)\n            Thread.remove(t);\n        t = tn;\n    }\n}\n\n\n// Used for needLock below.\nprivate __gshared bool multiThreadedFlag = false;\n\nversion (PPC64) version = ExternStackShell;\n\nversion (ExternStackShell)\n{\n    extern(D) public void callWithStackShell(scope void delegate(void* sp) nothrow fn) nothrow;\n}\nelse\n{\n    // Calls the given delegate, passing the current thread's stack pointer to it.\n    private void callWithStackShell(scope void delegate(void* sp) nothrow fn) nothrow\n    in\n    {\n        assert(fn);\n    }\n    do\n    {\n        // The purpose of the 'shell' is to ensure all the registers get\n        // put on the stack so they'll be scanned. We only need to push\n        // the callee-save registers.\n        void *sp = void;\n\n        version (GNU)\n        {\n            __builtin_unwind_init();\n            sp = &sp;\n        }\n        else version (AsmX86_Posix)\n        {\n            size_t[3] regs = void;\n            asm pure nothrow @nogc\n            {\n                mov [regs + 0 * 4], EBX;\n                mov [regs + 1 * 4], ESI;\n                mov [regs + 2 * 4], EDI;\n\n                mov sp[EBP], ESP;\n            }\n        }\n        else version (AsmX86_Windows)\n        {\n            size_t[3] regs = void;\n            asm pure nothrow @nogc\n            {\n                mov [regs + 0 * 4], EBX;\n                mov [regs + 1 * 4], ESI;\n                mov [regs + 2 * 4], EDI;\n\n                mov sp[EBP], ESP;\n            }\n        }\n        else version (AsmX86_64_Posix)\n        {\n            size_t[5] regs = void;\n            asm pure nothrow @nogc\n            {\n                mov [regs + 0 * 8], RBX;\n                mov [regs + 1 * 8], R12;\n                mov [regs + 2 * 8], R13;\n                mov [regs + 3 * 8], R14;\n                mov [regs + 4 * 8], R15;\n\n                mov sp[RBP], RSP;\n            }\n        }\n        else version (AsmX86_64_Windows)\n        {\n            size_t[7] regs = void;\n            asm pure nothrow @nogc\n            {\n                mov [regs + 0 * 8], RBX;\n                mov [regs + 1 * 8], RSI;\n                mov [regs + 2 * 8], RDI;\n                mov [regs + 3 * 8], R12;\n                mov [regs + 4 * 8], R13;\n                mov [regs + 5 * 8], R14;\n                mov [regs + 6 * 8], R15;\n\n                mov sp[RBP], RSP;\n            }\n        }\n        else\n        {\n            static assert(false, \"Architecture not supported.\");\n        }\n\n        fn(sp);\n    }\n}\n\n// Used for suspendAll/resumeAll below.\nprivate __gshared uint suspendDepth = 0;\n\n/**\n * Suspend the specified thread and load stack and register information for\n * use by thread_scanAll.  If the supplied thread is the calling thread,\n * stack and register information will be loaded but the thread will not\n * be suspended.  If the suspend operation fails and the thread is not\n * running then it will be removed from the global thread list, otherwise\n * an exception will be thrown.\n *\n * Params:\n *  t = The thread to suspend.\n *\n * Throws:\n *  ThreadError if the suspend operation fails for a running thread.\n * Returns:\n *  Whether the thread is now suspended (true) or terminated (false).\n */\nprivate bool suspend( Thread t ) nothrow\n{\n    Duration waittime = dur!\"usecs\"(10);\n Lagain:\n    if (!t.isRunning)\n    {\n        Thread.remove(t);\n        return false;\n    }\n    else if (t.m_isInCriticalRegion)\n    {\n        Thread.criticalRegionLock.unlock_nothrow();\n        Thread.sleep(waittime);\n        if (waittime < dur!\"msecs\"(10)) waittime *= 2;\n        Thread.criticalRegionLock.lock_nothrow();\n        goto Lagain;\n    }\n\n    version (Windows)\n    {\n        if ( t.m_addr != GetCurrentThreadId() && SuspendThread( t.m_hndl ) == 0xFFFFFFFF )\n        {\n            if ( !t.isRunning )\n            {\n                Thread.remove( t );\n                return false;\n            }\n            onThreadError( \"Unable to suspend thread\" );\n        }\n\n        CONTEXT context = void;\n        context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;\n\n        if ( !GetThreadContext( t.m_hndl, &context ) )\n            onThreadError( \"Unable to load thread context\" );\n        version (X86)\n        {\n            if ( !t.m_lock )\n                t.m_curr.tstack = cast(void*) context.Esp;\n            // eax,ebx,ecx,edx,edi,esi,ebp,esp\n            t.m_reg[0] = context.Eax;\n            t.m_reg[1] = context.Ebx;\n            t.m_reg[2] = context.Ecx;\n            t.m_reg[3] = context.Edx;\n            t.m_reg[4] = context.Edi;\n            t.m_reg[5] = context.Esi;\n            t.m_reg[6] = context.Ebp;\n            t.m_reg[7] = context.Esp;\n        }\n        else version (X86_64)\n        {\n            if ( !t.m_lock )\n                t.m_curr.tstack = cast(void*) context.Rsp;\n            // rax,rbx,rcx,rdx,rdi,rsi,rbp,rsp\n            t.m_reg[0] = context.Rax;\n            t.m_reg[1] = context.Rbx;\n            t.m_reg[2] = context.Rcx;\n            t.m_reg[3] = context.Rdx;\n            t.m_reg[4] = context.Rdi;\n            t.m_reg[5] = context.Rsi;\n            t.m_reg[6] = context.Rbp;\n            t.m_reg[7] = context.Rsp;\n            // r8,r9,r10,r11,r12,r13,r14,r15\n            t.m_reg[8]  = context.R8;\n            t.m_reg[9]  = context.R9;\n            t.m_reg[10] = context.R10;\n            t.m_reg[11] = context.R11;\n            t.m_reg[12] = context.R12;\n            t.m_reg[13] = context.R13;\n            t.m_reg[14] = context.R14;\n            t.m_reg[15] = context.R15;\n        }\n        else\n        {\n            static assert(false, \"Architecture not supported.\" );\n        }\n    }\n    else version (Darwin)\n    {\n        if ( t.m_addr != pthread_self() && thread_suspend( t.m_tmach ) != KERN_SUCCESS )\n        {\n            if ( !t.isRunning )\n            {\n                Thread.remove( t );\n                return false;\n            }\n            onThreadError( \"Unable to suspend thread\" );\n        }\n\n        version (X86)\n        {\n            x86_thread_state32_t    state = void;\n            mach_msg_type_number_t  count = x86_THREAD_STATE32_COUNT;\n\n            if ( thread_get_state( t.m_tmach, x86_THREAD_STATE32, &state, &count ) != KERN_SUCCESS )\n                onThreadError( \"Unable to load thread state\" );\n            if ( !t.m_lock )\n                t.m_curr.tstack = cast(void*) state.esp;\n            // eax,ebx,ecx,edx,edi,esi,ebp,esp\n            t.m_reg[0] = state.eax;\n            t.m_reg[1] = state.ebx;\n            t.m_reg[2] = state.ecx;\n            t.m_reg[3] = state.edx;\n            t.m_reg[4] = state.edi;\n            t.m_reg[5] = state.esi;\n            t.m_reg[6] = state.ebp;\n            t.m_reg[7] = state.esp;\n        }\n        else version (X86_64)\n        {\n            x86_thread_state64_t    state = void;\n            mach_msg_type_number_t  count = x86_THREAD_STATE64_COUNT;\n\n            if ( thread_get_state( t.m_tmach, x86_THREAD_STATE64, &state, &count ) != KERN_SUCCESS )\n                onThreadError( \"Unable to load thread state\" );\n            if ( !t.m_lock )\n                t.m_curr.tstack = cast(void*) state.rsp;\n            // rax,rbx,rcx,rdx,rdi,rsi,rbp,rsp\n            t.m_reg[0] = state.rax;\n            t.m_reg[1] = state.rbx;\n            t.m_reg[2] = state.rcx;\n            t.m_reg[3] = state.rdx;\n            t.m_reg[4] = state.rdi;\n            t.m_reg[5] = state.rsi;\n            t.m_reg[6] = state.rbp;\n            t.m_reg[7] = state.rsp;\n            // r8,r9,r10,r11,r12,r13,r14,r15\n            t.m_reg[8]  = state.r8;\n            t.m_reg[9]  = state.r9;\n            t.m_reg[10] = state.r10;\n            t.m_reg[11] = state.r11;\n            t.m_reg[12] = state.r12;\n            t.m_reg[13] = state.r13;\n            t.m_reg[14] = state.r14;\n            t.m_reg[15] = state.r15;\n        }\n        else\n        {\n            static assert(false, \"Architecture not supported.\" );\n        }\n    }\n    else version (Posix)\n    {\n        if ( t.m_addr != pthread_self() )\n        {\n            if ( pthread_kill( t.m_addr, suspendSignalNumber ) != 0 )\n            {\n                if ( !t.isRunning )\n                {\n                    Thread.remove( t );\n                    return false;\n                }\n                onThreadError( \"Unable to suspend thread\" );\n            }\n        }\n        else if ( !t.m_lock )\n        {\n            t.m_curr.tstack = getStackTop();\n        }\n    }\n    return true;\n}\n\n/**\n * Suspend all threads but the calling thread for \"stop the world\" garbage\n * collection runs.  This function may be called multiple times, and must\n * be followed by a matching number of calls to thread_resumeAll before\n * processing is resumed.\n *\n * Throws:\n *  ThreadError if the suspend operation fails for a running thread.\n */\nextern (C) void thread_suspendAll() nothrow\n{\n    // NOTE: We've got an odd chicken & egg problem here, because while the GC\n    //       is required to call thread_init before calling any other thread\n    //       routines, thread_init may allocate memory which could in turn\n    //       trigger a collection.  Thus, thread_suspendAll, thread_scanAll,\n    //       and thread_resumeAll must be callable before thread_init\n    //       completes, with the assumption that no other GC memory has yet\n    //       been allocated by the system, and thus there is no risk of losing\n    //       data if the global thread list is empty.  The check of\n    //       Thread.sm_tbeg below is done to ensure thread_init has completed,\n    //       and therefore that calling Thread.getThis will not result in an\n    //       error.  For the short time when Thread.sm_tbeg is null, there is\n    //       no reason not to simply call the multithreaded code below, with\n    //       the expectation that the foreach loop will never be entered.\n    if ( !multiThreadedFlag && Thread.sm_tbeg )\n    {\n        if ( ++suspendDepth == 1 )\n            suspend( Thread.getThis() );\n\n        return;\n    }\n\n    Thread.slock.lock_nothrow();\n    {\n        if ( ++suspendDepth > 1 )\n            return;\n\n        Thread.criticalRegionLock.lock_nothrow();\n        scope (exit) Thread.criticalRegionLock.unlock_nothrow();\n        size_t cnt;\n        auto t = Thread.sm_tbeg;\n        while (t)\n        {\n            auto tn = t.next;\n            if (suspend(t))\n                ++cnt;\n            t = tn;\n        }\n\n        version (Darwin)\n        {}\n        else version (Posix)\n        {\n            // subtract own thread\n            assert(cnt >= 1);\n            --cnt;\n        Lagain:\n            // wait for semaphore notifications\n            for (; cnt; --cnt)\n            {\n                while (sem_wait(&suspendCount) != 0)\n                {\n                    if (errno != EINTR)\n                        onThreadError(\"Unable to wait for semaphore\");\n                    errno = 0;\n                }\n            }\n            version (FreeBSD)\n            {\n                // avoid deadlocks, see Issue 13416\n                t = Thread.sm_tbeg;\n                while (t)\n                {\n                    auto tn = t.next;\n                    if (t.m_suspendagain && suspend(t))\n                        ++cnt;\n                    t = tn;\n                }\n                if (cnt)\n                    goto Lagain;\n             }\n        }\n    }\n}\n\n/**\n * Resume the specified thread and unload stack and register information.\n * If the supplied thread is the calling thread, stack and register\n * information will be unloaded but the thread will not be resumed.  If\n * the resume operation fails and the thread is not running then it will\n * be removed from the global thread list, otherwise an exception will be\n * thrown.\n *\n * Params:\n *  t = The thread to resume.\n *\n * Throws:\n *  ThreadError if the resume fails for a running thread.\n */\nprivate void resume( Thread t ) nothrow\n{\n    version (Windows)\n    {\n        if ( t.m_addr != GetCurrentThreadId() && ResumeThread( t.m_hndl ) == 0xFFFFFFFF )\n        {\n            if ( !t.isRunning )\n            {\n                Thread.remove( t );\n                return;\n            }\n            onThreadError( \"Unable to resume thread\" );\n        }\n\n        if ( !t.m_lock )\n            t.m_curr.tstack = t.m_curr.bstack;\n        t.m_reg[0 .. $] = 0;\n    }\n    else version (Darwin)\n    {\n        if ( t.m_addr != pthread_self() && thread_resume( t.m_tmach ) != KERN_SUCCESS )\n        {\n            if ( !t.isRunning )\n            {\n                Thread.remove( t );\n                return;\n            }\n            onThreadError( \"Unable to resume thread\" );\n        }\n\n        if ( !t.m_lock )\n            t.m_curr.tstack = t.m_curr.bstack;\n        t.m_reg[0 .. $] = 0;\n    }\n    else version (Posix)\n    {\n        if ( t.m_addr != pthread_self() )\n        {\n            if ( pthread_kill( t.m_addr, resumeSignalNumber ) != 0 )\n            {\n                if ( !t.isRunning )\n                {\n                    Thread.remove( t );\n                    return;\n                }\n                onThreadError( \"Unable to resume thread\" );\n            }\n        }\n        else if ( !t.m_lock )\n        {\n            t.m_curr.tstack = t.m_curr.bstack;\n        }\n    }\n}\n\n/**\n * Resume all threads but the calling thread for \"stop the world\" garbage\n * collection runs.  This function must be called once for each preceding\n * call to thread_suspendAll before the threads are actually resumed.\n *\n * In:\n *  This routine must be preceded by a call to thread_suspendAll.\n *\n * Throws:\n *  ThreadError if the resume operation fails for a running thread.\n */\nextern (C) void thread_resumeAll() nothrow\nin\n{\n    assert( suspendDepth > 0 );\n}\ndo\n{\n    // NOTE: See thread_suspendAll for the logic behind this.\n    if ( !multiThreadedFlag && Thread.sm_tbeg )\n    {\n        if ( --suspendDepth == 0 )\n            resume( Thread.getThis() );\n        return;\n    }\n\n    scope(exit) Thread.slock.unlock_nothrow();\n    {\n        if ( --suspendDepth > 0 )\n            return;\n\n        for ( Thread t = Thread.sm_tbeg; t; t = t.next )\n        {\n            // NOTE: We do not need to care about critical regions at all\n            //       here. thread_suspendAll takes care of everything.\n            resume( t );\n        }\n    }\n}\n\n/**\n * Indicates the kind of scan being performed by $(D thread_scanAllType).\n */\nenum ScanType\n{\n    stack, /// The stack and/or registers are being scanned.\n    tls, /// TLS data is being scanned.\n}\n\nalias ScanAllThreadsFn = void delegate(void*, void*) nothrow; /// The scanning function.\nalias ScanAllThreadsTypeFn = void delegate(ScanType, void*, void*) nothrow; /// ditto\n\n/**\n * The main entry point for garbage collection.  The supplied delegate\n * will be passed ranges representing both stack and register values.\n *\n * Params:\n *  scan        = The scanner function.  It should scan from p1 through p2 - 1.\n *\n * In:\n *  This routine must be preceded by a call to thread_suspendAll.\n */\nextern (C) void thread_scanAllType( scope ScanAllThreadsTypeFn scan ) nothrow\nin\n{\n    assert( suspendDepth > 0 );\n}\ndo\n{\n    callWithStackShell(sp => scanAllTypeImpl(scan, sp));\n}\n\n\nprivate void scanAllTypeImpl( scope ScanAllThreadsTypeFn scan, void* curStackTop ) nothrow\n{\n    Thread  thisThread  = null;\n    void*   oldStackTop = null;\n\n    if ( Thread.sm_tbeg )\n    {\n        thisThread  = Thread.getThis();\n        if ( !thisThread.m_lock )\n        {\n            oldStackTop = thisThread.m_curr.tstack;\n            thisThread.m_curr.tstack = curStackTop;\n        }\n    }\n\n    scope( exit )\n    {\n        if ( Thread.sm_tbeg )\n        {\n            if ( !thisThread.m_lock )\n            {\n                thisThread.m_curr.tstack = oldStackTop;\n            }\n        }\n    }\n\n    // NOTE: Synchronizing on Thread.slock is not needed because this\n    //       function may only be called after all other threads have\n    //       been suspended from within the same lock.\n    if (Thread.nAboutToStart)\n        scan(ScanType.stack, Thread.pAboutToStart, Thread.pAboutToStart + Thread.nAboutToStart);\n\n    for ( Thread.Context* c = Thread.sm_cbeg; c; c = c.next )\n    {\n        version (StackGrowsDown)\n        {\n            // NOTE: We can't index past the bottom of the stack\n            //       so don't do the \"+1\" for StackGrowsDown.\n            if ( c.tstack && c.tstack < c.bstack )\n                scan( ScanType.stack, c.tstack, c.bstack );\n        }\n        else\n        {\n            if ( c.bstack && c.bstack < c.tstack )\n                scan( ScanType.stack, c.bstack, c.tstack + 1 );\n        }\n    }\n\n    for ( Thread t = Thread.sm_tbeg; t; t = t.next )\n    {\n        version (Windows)\n        {\n            // Ideally, we'd pass ScanType.regs or something like that, but this\n            // would make portability annoying because it only makes sense on Windows.\n            scan( ScanType.stack, t.m_reg.ptr, t.m_reg.ptr + t.m_reg.length );\n        }\n\n        if (t.m_tlsgcdata !is null)\n            rt_tlsgc_scan(t.m_tlsgcdata, (p1, p2) => scan(ScanType.tls, p1, p2));\n    }\n}\n\n/**\n * The main entry point for garbage collection.  The supplied delegate\n * will be passed ranges representing both stack and register values.\n *\n * Params:\n *  scan        = The scanner function.  It should scan from p1 through p2 - 1.\n *\n * In:\n *  This routine must be preceded by a call to thread_suspendAll.\n */\nextern (C) void thread_scanAll( scope ScanAllThreadsFn scan ) nothrow\n{\n    thread_scanAllType((type, p1, p2) => scan(p1, p2));\n}\n\n\n/**\n * Signals that the code following this call is a critical region. Any code in\n * this region must finish running before the calling thread can be suspended\n * by a call to thread_suspendAll.\n *\n * This function is, in particular, meant to help maintain garbage collector\n * invariants when a lock is not used.\n *\n * A critical region is exited with thread_exitCriticalRegion.\n *\n * $(RED Warning):\n * Using critical regions is extremely error-prone. For instance, using locks\n * inside a critical region can easily result in a deadlock when another thread\n * holding the lock already got suspended.\n *\n * The term and concept of a 'critical region' comes from\n * $(LINK2 https://github.com/mono/mono/blob/521f4a198e442573c400835ef19bbb36b60b0ebb/mono/metadata/sgen-gc.h#L925 Mono's SGen garbage collector).\n *\n * In:\n *  The calling thread must be attached to the runtime.\n */\nextern (C) void thread_enterCriticalRegion() @nogc\nin\n{\n    assert(Thread.getThis());\n}\ndo\n{\n    synchronized (Thread.criticalRegionLock)\n        Thread.getThis().m_isInCriticalRegion = true;\n}\n\n\n/**\n * Signals that the calling thread is no longer in a critical region. Following\n * a call to this function, the thread can once again be suspended.\n *\n * In:\n *  The calling thread must be attached to the runtime.\n */\nextern (C) void thread_exitCriticalRegion() @nogc\nin\n{\n    assert(Thread.getThis());\n}\ndo\n{\n    synchronized (Thread.criticalRegionLock)\n        Thread.getThis().m_isInCriticalRegion = false;\n}\n\n\n/**\n * Returns true if the current thread is in a critical region; otherwise, false.\n *\n * In:\n *  The calling thread must be attached to the runtime.\n */\nextern (C) bool thread_inCriticalRegion() @nogc\nin\n{\n    assert(Thread.getThis());\n}\ndo\n{\n    synchronized (Thread.criticalRegionLock)\n        return Thread.getThis().m_isInCriticalRegion;\n}\n\n\n/**\n* A callback for thread errors in D during collections. Since an allocation is not possible\n*  a preallocated ThreadError will be used as the Error instance\n*\n* Returns:\n*  never returns\n* Throws:\n*  ThreadError.\n*/\nprivate void onThreadError(string msg) nothrow\n{\n    __gshared ThreadError error = new ThreadError(null);\n    error.msg = msg;\n    error.next = null;\n    import core.exception : SuppressTraceInfo;\n    error.info = SuppressTraceInfo.instance;\n    throw error;\n}\n\n\nunittest\n{\n    assert(!thread_inCriticalRegion());\n\n    {\n        thread_enterCriticalRegion();\n\n        scope (exit)\n            thread_exitCriticalRegion();\n\n        assert(thread_inCriticalRegion());\n    }\n\n    assert(!thread_inCriticalRegion());\n}\n\nunittest\n{\n    // NOTE: This entire test is based on the assumption that no\n    //       memory is allocated after the child thread is\n    //       started. If an allocation happens, a collection could\n    //       trigger, which would cause the synchronization below\n    //       to cause a deadlock.\n    // NOTE: DO NOT USE LOCKS IN CRITICAL REGIONS IN NORMAL CODE.\n\n    import core.sync.semaphore;\n\n    auto sema = new Semaphore(),\n         semb = new Semaphore();\n\n    auto thr = new Thread(\n    {\n        thread_enterCriticalRegion();\n        assert(thread_inCriticalRegion());\n        sema.notify();\n\n        semb.wait();\n        assert(thread_inCriticalRegion());\n\n        thread_exitCriticalRegion();\n        assert(!thread_inCriticalRegion());\n        sema.notify();\n\n        semb.wait();\n        assert(!thread_inCriticalRegion());\n    });\n\n    thr.start();\n\n    sema.wait();\n    synchronized (Thread.criticalRegionLock)\n        assert(thr.m_isInCriticalRegion);\n    semb.notify();\n\n    sema.wait();\n    synchronized (Thread.criticalRegionLock)\n        assert(!thr.m_isInCriticalRegion);\n    semb.notify();\n\n    thr.join();\n}\n\nunittest\n{\n    import core.sync.semaphore;\n\n    shared bool inCriticalRegion;\n    auto sema = new Semaphore(),\n         semb = new Semaphore();\n\n    auto thr = new Thread(\n    {\n        thread_enterCriticalRegion();\n        inCriticalRegion = true;\n        sema.notify();\n        semb.wait();\n\n        Thread.sleep(dur!\"msecs\"(1));\n        inCriticalRegion = false;\n        thread_exitCriticalRegion();\n    });\n    thr.start();\n\n    sema.wait();\n    assert(inCriticalRegion);\n    semb.notify();\n\n    thread_suspendAll();\n    assert(!inCriticalRegion);\n    thread_resumeAll();\n}\n\n/**\n * Indicates whether an address has been marked by the GC.\n */\nenum IsMarked : int\n{\n         no, /// Address is not marked.\n        yes, /// Address is marked.\n    unknown, /// Address is not managed by the GC.\n}\n\nalias IsMarkedDg = int delegate( void* addr ) nothrow; /// The isMarked callback function.\n\n/**\n * This routine allows the runtime to process any special per-thread handling\n * for the GC.  This is needed for taking into account any memory that is\n * referenced by non-scanned pointers but is about to be freed.  That currently\n * means the array append cache.\n *\n * Params:\n *  isMarked = The function used to check if $(D addr) is marked.\n *\n * In:\n *  This routine must be called just prior to resuming all threads.\n */\nextern(C) void thread_processGCMarks( scope IsMarkedDg isMarked ) nothrow\n{\n    for ( Thread t = Thread.sm_tbeg; t; t = t.next )\n    {\n        /* Can be null if collection was triggered between adding a\n         * thread and calling rt_tlsgc_init.\n         */\n        if (t.m_tlsgcdata !is null)\n            rt_tlsgc_processGCMarks(t.m_tlsgcdata, isMarked);\n    }\n}\n\n\nextern (C) @nogc nothrow\n{\n    version (CRuntime_Glibc) int pthread_getattr_np(pthread_t thread, pthread_attr_t* attr);\n    version (FreeBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr);\n    version (NetBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr);\n    version (DragonFlyBSD) int pthread_attr_get_np(pthread_t thread, pthread_attr_t* attr);\n    version (Solaris) int thr_stksegment(stack_t* stk);\n    version (CRuntime_Bionic) int pthread_getattr_np(pthread_t thid, pthread_attr_t* attr);\n    version (CRuntime_Musl) int pthread_getattr_np(pthread_t, pthread_attr_t*);\n    version (CRuntime_UClibc) int pthread_getattr_np(pthread_t thread, pthread_attr_t* attr);\n}\n\n\nprivate void* getStackTop() nothrow @nogc\n{\n    version (D_InlineAsm_X86)\n        asm pure nothrow @nogc { naked; mov EAX, ESP; ret; }\n    else version (D_InlineAsm_X86_64)\n        asm pure nothrow @nogc { naked; mov RAX, RSP; ret; }\n    else version (GNU)\n        return __builtin_frame_address(0);\n    else\n        static assert(false, \"Architecture not supported.\");\n}\n\n\nprivate void* getStackBottom() nothrow @nogc\n{\n    version (Windows)\n    {\n        version (D_InlineAsm_X86)\n            asm pure nothrow @nogc { naked; mov EAX, FS:4; ret; }\n        else version (D_InlineAsm_X86_64)\n            asm pure nothrow @nogc\n            {    naked;\n                 mov RAX, 8;\n                 mov RAX, GS:[RAX];\n                 ret;\n            }\n        else version (GNU_InlineAsm)\n        {\n            void *bottom;\n\n            version (X86)\n                asm pure nothrow @nogc { \"movl %%fs:4, %0;\" : \"=r\" bottom; }\n            else version (X86_64)\n                asm pure nothrow @nogc { \"movq %%gs:8, %0;\" : \"=r\" bottom; }\n            else\n                static assert(false, \"Platform not supported.\");\n\n            return bottom;\n        }\n        else\n            static assert(false, \"Architecture not supported.\");\n    }\n    else version (Darwin)\n    {\n        import core.sys.darwin.pthread;\n        return pthread_get_stackaddr_np(pthread_self());\n    }\n    else version (CRuntime_Glibc)\n    {\n        pthread_attr_t attr;\n        void* addr; size_t size;\n\n        pthread_getattr_np(pthread_self(), &attr);\n        pthread_attr_getstack(&attr, &addr, &size);\n        pthread_attr_destroy(&attr);\n        return addr + size;\n    }\n    else version (FreeBSD)\n    {\n        pthread_attr_t attr;\n        void* addr; size_t size;\n\n        pthread_attr_init(&attr);\n        pthread_attr_get_np(pthread_self(), &attr);\n        pthread_attr_getstack(&attr, &addr, &size);\n        pthread_attr_destroy(&attr);\n        return addr + size;\n    }\n    else version (NetBSD)\n    {\n        pthread_attr_t attr;\n        void* addr; size_t size;\n\n        pthread_attr_init(&attr);\n        pthread_attr_get_np(pthread_self(), &attr);\n        pthread_attr_getstack(&attr, &addr, &size);\n        pthread_attr_destroy(&attr);\n        return addr + size;\n    }\n    else version (DragonFlyBSD)\n    {\n        pthread_attr_t attr;\n        void* addr; size_t size;\n\n        pthread_attr_init(&attr);\n        pthread_attr_get_np(pthread_self(), &attr);\n        pthread_attr_getstack(&attr, &addr, &size);\n        pthread_attr_destroy(&attr);\n        return addr + size;\n    }\n    else version (Solaris)\n    {\n        stack_t stk;\n\n        thr_stksegment(&stk);\n        return stk.ss_sp;\n    }\n    else version (CRuntime_Bionic)\n    {\n        pthread_attr_t attr;\n        void* addr; size_t size;\n\n        pthread_getattr_np(pthread_self(), &attr);\n        pthread_attr_getstack(&attr, &addr, &size);\n        pthread_attr_destroy(&attr);\n        return addr + size;\n    }\n    else version (CRuntime_Musl)\n    {\n        pthread_attr_t attr;\n        void* addr; size_t size;\n\n        pthread_getattr_np(pthread_self(), &attr);\n        pthread_attr_getstack(&attr, &addr, &size);\n        pthread_attr_destroy(&attr);\n        return addr + size;\n    }\n    else version (CRuntime_UClibc)\n    {\n        pthread_attr_t attr;\n        void* addr; size_t size;\n\n        pthread_getattr_np(pthread_self(), &attr);\n        pthread_attr_getstack(&attr, &addr, &size);\n        pthread_attr_destroy(&attr);\n        return addr + size;\n    }\n    else\n        static assert(false, \"Platform not supported.\");\n}\n\n\n/**\n * Returns the stack top of the currently active stack within the calling\n * thread.\n *\n * In:\n *  The calling thread must be attached to the runtime.\n *\n * Returns:\n *  The address of the stack top.\n */\nextern (C) void* thread_stackTop() nothrow @nogc\nin\n{\n    // Not strictly required, but it gives us more flexibility.\n    assert(Thread.getThis());\n}\ndo\n{\n    return getStackTop();\n}\n\n\n/**\n * Returns the stack bottom of the currently active stack within the calling\n * thread.\n *\n * In:\n *  The calling thread must be attached to the runtime.\n *\n * Returns:\n *  The address of the stack bottom.\n */\nextern (C) void* thread_stackBottom() nothrow @nogc\nin\n{\n    assert(Thread.getThis());\n}\ndo\n{\n    return Thread.getThis().topContext().bstack;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Thread Group\n///////////////////////////////////////////////////////////////////////////////\n\n\n/**\n * This class is intended to simplify certain common programming techniques.\n */\nclass ThreadGroup\n{\n    /**\n     * Creates and starts a new Thread object that executes fn and adds it to\n     * the list of tracked threads.\n     *\n     * Params:\n     *  fn = The thread function.\n     *\n     * Returns:\n     *  A reference to the newly created thread.\n     */\n    final Thread create( void function() fn )\n    {\n        Thread t = new Thread( fn ).start();\n\n        synchronized( this )\n        {\n            m_all[t] = t;\n        }\n        return t;\n    }\n\n\n    /**\n     * Creates and starts a new Thread object that executes dg and adds it to\n     * the list of tracked threads.\n     *\n     * Params:\n     *  dg = The thread function.\n     *\n     * Returns:\n     *  A reference to the newly created thread.\n     */\n    final Thread create( void delegate() dg )\n    {\n        Thread t = new Thread( dg ).start();\n\n        synchronized( this )\n        {\n            m_all[t] = t;\n        }\n        return t;\n    }\n\n\n    /**\n     * Add t to the list of tracked threads if it is not already being tracked.\n     *\n     * Params:\n     *  t = The thread to add.\n     *\n     * In:\n     *  t must not be null.\n     */\n    final void add( Thread t )\n    in\n    {\n        assert( t );\n    }\n    do\n    {\n        synchronized( this )\n        {\n            m_all[t] = t;\n        }\n    }\n\n\n    /**\n     * Removes t from the list of tracked threads.  No operation will be\n     * performed if t is not currently being tracked by this object.\n     *\n     * Params:\n     *  t = The thread to remove.\n     *\n     * In:\n     *  t must not be null.\n     */\n    final void remove( Thread t )\n    in\n    {\n        assert( t );\n    }\n    do\n    {\n        synchronized( this )\n        {\n            m_all.remove( t );\n        }\n    }\n\n\n    /**\n     * Operates on all threads currently tracked by this object.\n     */\n    final int opApply( scope int delegate( ref Thread ) dg )\n    {\n        synchronized( this )\n        {\n            int ret = 0;\n\n            // NOTE: This loop relies on the knowledge that m_all uses the\n            //       Thread object for both the key and the mapped value.\n            foreach ( Thread t; m_all.keys )\n            {\n                ret = dg( t );\n                if ( ret )\n                    break;\n            }\n            return ret;\n        }\n    }\n\n\n    /**\n     * Iteratively joins all tracked threads.  This function will block add,\n     * remove, and opApply until it completes.\n     *\n     * Params:\n     *  rethrow = Rethrow any unhandled exception which may have caused the\n     *            current thread to terminate.\n     *\n     * Throws:\n     *  Any exception not handled by the joined threads.\n     */\n    final void joinAll( bool rethrow = true )\n    {\n        synchronized( this )\n        {\n            // NOTE: This loop relies on the knowledge that m_all uses the\n            //       Thread object for both the key and the mapped value.\n            foreach ( Thread t; m_all.keys )\n            {\n                t.join( rethrow );\n            }\n        }\n    }\n\n\nprivate:\n    Thread[Thread]  m_all;\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Fiber Platform Detection and Memory Allocation\n///////////////////////////////////////////////////////////////////////////////\n\n\nprivate\n{\n    version (D_InlineAsm_X86)\n    {\n        version (Windows)\n            version = AsmX86_Windows;\n        else version (Posix)\n            version = AsmX86_Posix;\n\n        version (Darwin)\n            version = AlignFiberStackTo16Byte;\n    }\n    else version (D_InlineAsm_X86_64)\n    {\n        version (Windows)\n        {\n            version = AsmX86_64_Windows;\n            version = AlignFiberStackTo16Byte;\n        }\n        else version (Posix)\n        {\n            version = AsmX86_64_Posix;\n            version = AlignFiberStackTo16Byte;\n        }\n    }\n    else version (X86)\n    {\n        version = AsmExternal;\n\n        version (MinGW)\n        {\n            version = GNU_AsmX86_Windows;\n            version = AlignFiberStackTo16Byte;\n        }\n        else version (Posix)\n        {\n            version = AsmX86_Posix;\n            version (OSX)\n                version = AlignFiberStackTo16Byte;\n        }\n    }\n    else version (X86_64)\n    {\n        version (D_X32)\n        {\n            // let X32 be handled by ucontext swapcontext\n        }\n        else\n        {\n            version = AsmExternal;\n            version = AlignFiberStackTo16Byte;\n\n            version (MinGW)\n                version = GNU_AsmX86_64_Windows;\n            else version (Posix)\n                version = AsmX86_64_Posix;\n        }\n    }\n    else version (PPC)\n    {\n        version (Posix)\n        {\n            version = AsmPPC_Posix;\n            version = AsmExternal;\n        }\n    }\n    else version (PPC64)\n    {\n        version (Posix)\n        {\n            version = AlignFiberStackTo16Byte;\n        }\n    }\n    else version (MIPS_O32)\n    {\n        version (Posix)\n        {\n            version = AsmMIPS_O32_Posix;\n            version = AsmExternal;\n        }\n    }\n    else version (AArch64)\n    {\n        version (Posix)\n        {\n            version = AsmAArch64_Posix;\n            version = AsmExternal;\n            version = AlignFiberStackTo16Byte;\n        }\n    }\n    else version (ARM)\n    {\n        version (Posix)\n        {\n            version = AsmARM_Posix;\n            version = AsmExternal;\n        }\n    }\n\n    version (Posix)\n    {\n        import core.sys.posix.unistd;   // for sysconf\n\n        version (AsmX86_Windows)    {} else\n        version (AsmX86_Posix)      {} else\n        version (AsmX86_64_Windows) {} else\n        version (AsmX86_64_Posix)   {} else\n        version (AsmExternal)       {} else\n        {\n            // NOTE: The ucontext implementation requires architecture specific\n            //       data definitions to operate so testing for it must be done\n            //       by checking for the existence of ucontext_t rather than by\n            //       a version identifier.  Please note that this is considered\n            //       an obsolescent feature according to the POSIX spec, so a\n            //       custom solution is still preferred.\n            import core.sys.posix.ucontext;\n        }\n    }\n\n    static immutable size_t PAGESIZE;\n    version (Posix) static immutable size_t PTHREAD_STACK_MIN;\n}\n\n\nshared static this()\n{\n    version (Windows)\n    {\n        SYSTEM_INFO info;\n        GetSystemInfo(&info);\n\n        PAGESIZE = info.dwPageSize;\n        assert(PAGESIZE < int.max);\n    }\n    else version (Posix)\n    {\n        PAGESIZE = cast(size_t)sysconf(_SC_PAGESIZE);\n        PTHREAD_STACK_MIN = cast(size_t)sysconf(_SC_THREAD_STACK_MIN);\n    }\n    else\n    {\n        static assert(0, \"unimplemented\");\n    }\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Fiber Entry Point and Context Switch\n///////////////////////////////////////////////////////////////////////////////\n\n\nprivate\n{\n    extern (C) void fiber_entryPoint() nothrow\n    {\n        Fiber   obj = Fiber.getThis();\n        assert( obj );\n\n        assert( Thread.getThis().m_curr is obj.m_ctxt );\n        atomicStore!(MemoryOrder.raw)(*cast(shared)&Thread.getThis().m_lock, false);\n        obj.m_ctxt.tstack = obj.m_ctxt.bstack;\n        obj.m_state = Fiber.State.EXEC;\n\n        try\n        {\n            obj.run();\n        }\n        catch ( Throwable t )\n        {\n            obj.m_unhandled = t;\n        }\n\n        static if ( __traits( compiles, ucontext_t ) )\n          obj.m_ucur = &obj.m_utxt;\n\n        obj.m_state = Fiber.State.TERM;\n        obj.switchOut();\n    }\n\n  // Look above the definition of 'class Fiber' for some information about the implementation of this routine\n  version (AsmExternal)\n  {\n      extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc;\n      version (AArch64)\n          extern (C) void fiber_trampoline() nothrow;\n  }\n  else\n    extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc\n    {\n        // NOTE: The data pushed and popped in this routine must match the\n        //       default stack created by Fiber.initStack or the initial\n        //       switch into a new context will fail.\n\n        version (AsmX86_Windows)\n        {\n            asm pure nothrow @nogc\n            {\n                naked;\n\n                // save current stack state\n                push EBP;\n                mov  EBP, ESP;\n                push EDI;\n                push ESI;\n                push EBX;\n                push dword ptr FS:[0];\n                push dword ptr FS:[4];\n                push dword ptr FS:[8];\n                push EAX;\n\n                // store oldp again with more accurate address\n                mov EAX, dword ptr 8[EBP];\n                mov [EAX], ESP;\n                // load newp to begin context switch\n                mov ESP, dword ptr 12[EBP];\n\n                // load saved state from new stack\n                pop EAX;\n                pop dword ptr FS:[8];\n                pop dword ptr FS:[4];\n                pop dword ptr FS:[0];\n                pop EBX;\n                pop ESI;\n                pop EDI;\n                pop EBP;\n\n                // 'return' to complete switch\n                pop ECX;\n                jmp ECX;\n            }\n        }\n        else version (AsmX86_64_Windows)\n        {\n            asm pure nothrow @nogc\n            {\n                naked;\n\n                // save current stack state\n                // NOTE: When changing the layout of registers on the stack,\n                //       make sure that the XMM registers are still aligned.\n                //       On function entry, the stack is guaranteed to not\n                //       be aligned to 16 bytes because of the return address\n                //       on the stack.\n                push RBP;\n                mov  RBP, RSP;\n                push R12;\n                push R13;\n                push R14;\n                push R15;\n                push RDI;\n                push RSI;\n                // 7 registers = 56 bytes; stack is now aligned to 16 bytes\n                sub RSP, 160;\n                movdqa [RSP + 144], XMM6;\n                movdqa [RSP + 128], XMM7;\n                movdqa [RSP + 112], XMM8;\n                movdqa [RSP + 96], XMM9;\n                movdqa [RSP + 80], XMM10;\n                movdqa [RSP + 64], XMM11;\n                movdqa [RSP + 48], XMM12;\n                movdqa [RSP + 32], XMM13;\n                movdqa [RSP + 16], XMM14;\n                movdqa [RSP], XMM15;\n                push RBX;\n                xor  RAX,RAX;\n                push qword ptr GS:[RAX];\n                push qword ptr GS:8[RAX];\n                push qword ptr GS:16[RAX];\n\n                // store oldp\n                mov [RCX], RSP;\n                // load newp to begin context switch\n                mov RSP, RDX;\n\n                // load saved state from new stack\n                pop qword ptr GS:16[RAX];\n                pop qword ptr GS:8[RAX];\n                pop qword ptr GS:[RAX];\n                pop RBX;\n                movdqa XMM15, [RSP];\n                movdqa XMM14, [RSP + 16];\n                movdqa XMM13, [RSP + 32];\n                movdqa XMM12, [RSP + 48];\n                movdqa XMM11, [RSP + 64];\n                movdqa XMM10, [RSP + 80];\n                movdqa XMM9, [RSP + 96];\n                movdqa XMM8, [RSP + 112];\n                movdqa XMM7, [RSP + 128];\n                movdqa XMM6, [RSP + 144];\n                add RSP, 160;\n                pop RSI;\n                pop RDI;\n                pop R15;\n                pop R14;\n                pop R13;\n                pop R12;\n                pop RBP;\n\n                // 'return' to complete switch\n                pop RCX;\n                jmp RCX;\n            }\n        }\n        else version (AsmX86_Posix)\n        {\n            asm pure nothrow @nogc\n            {\n                naked;\n\n                // save current stack state\n                push EBP;\n                mov  EBP, ESP;\n                push EDI;\n                push ESI;\n                push EBX;\n                push EAX;\n\n                // store oldp again with more accurate address\n                mov EAX, dword ptr 8[EBP];\n                mov [EAX], ESP;\n                // load newp to begin context switch\n                mov ESP, dword ptr 12[EBP];\n\n                // load saved state from new stack\n                pop EAX;\n                pop EBX;\n                pop ESI;\n                pop EDI;\n                pop EBP;\n\n                // 'return' to complete switch\n                pop ECX;\n                jmp ECX;\n            }\n        }\n        else version (AsmX86_64_Posix)\n        {\n            asm pure nothrow @nogc\n            {\n                naked;\n\n                // save current stack state\n                push RBP;\n                mov  RBP, RSP;\n                push RBX;\n                push R12;\n                push R13;\n                push R14;\n                push R15;\n\n                // store oldp\n                mov [RDI], RSP;\n                // load newp to begin context switch\n                mov RSP, RSI;\n\n                // load saved state from new stack\n                pop R15;\n                pop R14;\n                pop R13;\n                pop R12;\n                pop RBX;\n                pop RBP;\n\n                // 'return' to complete switch\n                pop RCX;\n                jmp RCX;\n            }\n        }\n        else static if ( __traits( compiles, ucontext_t ) )\n        {\n            Fiber   cfib = Fiber.getThis();\n            void*   ucur = cfib.m_ucur;\n\n            *oldp = &ucur;\n            swapcontext( **(cast(ucontext_t***) oldp),\n                          *(cast(ucontext_t**)  newp) );\n        }\n        else\n            static assert(0, \"Not implemented\");\n    }\n}\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Fiber\n///////////////////////////////////////////////////////////////////////////////\n/*\n * Documentation of Fiber internals:\n *\n * The main routines to implement when porting Fibers to new architectures are\n * fiber_switchContext and initStack. Some version constants have to be defined\n * for the new platform as well, search for \"Fiber Platform Detection and Memory Allocation\".\n *\n * Fibers are based on a concept called 'Context'. A Context describes the execution\n * state of a Fiber or main thread which is fully described by the stack, some\n * registers and a return address at which the Fiber/Thread should continue executing.\n * Please note that not only each Fiber has a Context, but each thread also has got a\n * Context which describes the threads stack and state. If you call Fiber fib; fib.call\n * the first time in a thread you switch from Threads Context into the Fibers Context.\n * If you call fib.yield in that Fiber you switch out of the Fibers context and back\n * into the Thread Context. (However, this is not always the case. You can call a Fiber\n * from within another Fiber, then you switch Contexts between the Fibers and the Thread\n * Context is not involved)\n *\n * In all current implementations the registers and the return address are actually\n * saved on a Contexts stack.\n *\n * The fiber_switchContext routine has got two parameters:\n * void** a:  This is the _location_ where we have to store the current stack pointer,\n *            the stack pointer of the currently executing Context (Fiber or Thread).\n * void*  b:  This is the pointer to the stack of the Context which we want to switch into.\n *            Note that we get the same pointer here as the one we stored into the void** a\n *            in a previous call to fiber_switchContext.\n *\n * In the simplest case, a fiber_switchContext rountine looks like this:\n * fiber_switchContext:\n *     push {return Address}\n *     push {registers}\n *     copy {stack pointer} into {location pointed to by a}\n *     //We have now switch to the stack of a different Context!\n *     copy {b} into {stack pointer}\n *     pop {registers}\n *     pop {return Address}\n *     jump to {return Address}\n *\n * The GC uses the value returned in parameter a to scan the Fibers stack. It scans from\n * the stack base to that value. As the GC dislikes false pointers we can actually optimize\n * this a little: By storing registers which can not contain references to memory managed\n * by the GC outside of the region marked by the stack base pointer and the stack pointer\n * saved in fiber_switchContext we can prevent the GC from scanning them.\n * Such registers are usually floating point registers and the return address. In order to\n * implement this, we return a modified stack pointer from fiber_switchContext. However,\n * we have to remember that when we restore the registers from the stack!\n *\n * --------------------------- <= Stack Base\n * |          Frame          | <= Many other stack frames\n * |          Frame          |\n * |-------------------------| <= The last stack frame. This one is created by fiber_switchContext\n * | registers with pointers |\n * |                         | <= Stack pointer. GC stops scanning here\n * |   return address        |\n * |floating point registers |\n * --------------------------- <= Real Stack End\n *\n * fiber_switchContext:\n *     push {registers with pointers}\n *     copy {stack pointer} into {location pointed to by a}\n *     push {return Address}\n *     push {Floating point registers}\n *     //We have now switch to the stack of a different Context!\n *     copy {b} into {stack pointer}\n *     //We now have to adjust the stack pointer to point to 'Real Stack End' so we can pop\n *     //the FP registers\n *     //+ or - depends on if your stack grows downwards or upwards\n *     {stack pointer} = {stack pointer} +- ({FPRegisters}.sizeof + {return address}.sizeof}\n *     pop {Floating point registers}\n *     pop {return Address}\n *     pop {registers with pointers}\n *     jump to {return Address}\n *\n * So the question now is which registers need to be saved? This depends on the specific\n * architecture ABI of course, but here are some general guidelines:\n * - If a register is callee-save (if the callee modifies the register it must saved and\n *   restored by the callee) it needs to be saved/restored in switchContext\n * - If a register is caller-save it needn't be saved/restored. (Calling fiber_switchContext\n *   is a function call and the compiler therefore already must save these registers before\n *   calling fiber_switchContext)\n * - Argument registers used for passing parameters to functions needn't be saved/restored\n * - The return register needn't be saved/restored (fiber_switchContext hasn't got a return type)\n * - All scratch registers needn't be saved/restored\n * - The link register usually needn't be saved/restored (but sometimes it must be cleared -\n *   see below for details)\n * - The frame pointer register - if it exists - is usually callee-save\n * - All current implementations do not save control registers\n *\n * What happens on the first switch into a Fiber? We never saved a state for this fiber before,\n * but the initial state is prepared in the initStack routine. (This routine will also be called\n * when a Fiber is being resetted). initStack must produce exactly the same stack layout as the\n * part of fiber_switchContext which saves the registers. Pay special attention to set the stack\n * pointer correctly if you use the GC optimization mentioned before. the return Address saved in\n * initStack must be the address of fiber_entrypoint.\n *\n * There's now a small but important difference between the first context switch into a fiber and\n * further context switches. On the first switch, Fiber.call is used and the returnAddress in\n * fiber_switchContext will point to fiber_entrypoint. The important thing here is that this jump\n * is a _function call_, we call fiber_entrypoint by jumping before it's function prologue. On later\n * calls, the user used yield() in a function, and therefore the return address points into a user\n * function, after the yield call. So here the jump in fiber_switchContext is a _function return_,\n * not a function call!\n *\n * The most important result of this is that on entering a function, i.e. fiber_entrypoint, we\n * would have to provide a return address / set the link register once fiber_entrypoint\n * returns. Now fiber_entrypoint does never return and therefore the actual value of the return\n * address / link register is never read/used and therefore doesn't matter. When fiber_switchContext\n * performs a _function return_ the value in the link register doesn't matter either.\n * However, the link register will still be saved to the stack in fiber_entrypoint and some\n * exception handling / stack unwinding code might read it from this stack location and crash.\n * The exact solution depends on your architecture, but see the ARM implementation for a way\n * to deal with this issue.\n *\n * The ARM implementation is meant to be used as a kind of documented example implementation.\n * Look there for a concrete example.\n *\n * FIXME: fiber_entrypoint might benefit from a @noreturn attribute, but D doesn't have one.\n */\n\n/**\n * This class provides a cooperative concurrency mechanism integrated with the\n * threading and garbage collection functionality.  Calling a fiber may be\n * considered a blocking operation that returns when the fiber yields (via\n * Fiber.yield()).  Execution occurs within the context of the calling thread\n * so synchronization is not necessary to guarantee memory visibility so long\n * as the same thread calls the fiber each time.  Please note that there is no\n * requirement that a fiber be bound to one specific thread.  Rather, fibers\n * may be freely passed between threads so long as they are not currently\n * executing.  Like threads, a new fiber thread may be created using either\n * derivation or composition, as in the following example.\n *\n * Warning:\n * Status registers are not saved by the current implementations. This means\n * floating point exception status bits (overflow, divide by 0), rounding mode\n * and similar stuff is set per-thread, not per Fiber!\n *\n * Warning:\n * On ARM FPU registers are not saved if druntime was compiled as ARM_SoftFloat.\n * If such a build is used on a ARM_SoftFP system which actually has got a FPU\n * and other libraries are using the FPU registers (other code is compiled\n * as ARM_SoftFP) this can cause problems. Druntime must be compiled as\n * ARM_SoftFP in this case.\n *\n * Authors: Based on a design by Mikola Lysenko.\n */\nclass Fiber\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Initialization\n    ///////////////////////////////////////////////////////////////////////////\n\n    version (Windows)\n        // exception handling walks the stack, invoking DbgHelp.dll which\n        // needs up to 16k of stack space depending on the version of DbgHelp.dll,\n        // the existence of debug symbols and other conditions. Avoid causing\n        // stack overflows by defaulting to a larger stack size\n        enum defaultStackPages = 8;\n    else\n        enum defaultStackPages = 4;\n\n    /**\n     * Initializes a fiber object which is associated with a static\n     * D function.\n     *\n     * Params:\n     *  fn = The fiber function.\n     *  sz = The stack size for this fiber.\n     *  guardPageSize = size of the guard page to trap fiber's stack\n     *                  overflows. Beware that using this will increase\n     *                  the number of mmaped regions on platforms using mmap\n     *                  so an OS-imposed limit may be hit.\n     *\n     * In:\n     *  fn must not be null.\n     */\n    this( void function() fn, size_t sz = PAGESIZE * defaultStackPages,\n          size_t guardPageSize = PAGESIZE ) nothrow\n    in\n    {\n        assert( fn );\n    }\n    do\n    {\n        allocStack( sz, guardPageSize );\n        reset( fn );\n    }\n\n\n    /**\n     * Initializes a fiber object which is associated with a dynamic\n     * D function.\n     *\n     * Params:\n     *  dg = The fiber function.\n     *  sz = The stack size for this fiber.\n     *  guardPageSize = size of the guard page to trap fiber's stack\n     *                  overflows. Beware that using this will increase\n     *                  the number of mmaped regions on platforms using mmap\n     *                  so an OS-imposed limit may be hit.\n     *\n     * In:\n     *  dg must not be null.\n     */\n    this( void delegate() dg, size_t sz = PAGESIZE * defaultStackPages,\n          size_t guardPageSize = PAGESIZE ) nothrow\n    in\n    {\n        assert( dg );\n    }\n    do\n    {\n        allocStack( sz, guardPageSize );\n        reset( dg );\n    }\n\n\n    /**\n     * Cleans up any remaining resources used by this object.\n     */\n    ~this() nothrow @nogc\n    {\n        // NOTE: A live reference to this object will exist on its associated\n        //       stack from the first time its call() method has been called\n        //       until its execution completes with State.TERM.  Thus, the only\n        //       times this dtor should be called are either if the fiber has\n        //       terminated (and therefore has no active stack) or if the user\n        //       explicitly deletes this object.  The latter case is an error\n        //       but is not easily tested for, since State.HOLD may imply that\n        //       the fiber was just created but has never been run.  There is\n        //       not a compelling case to create a State.INIT just to offer a\n        //       means of ensuring the user isn't violating this object's\n        //       contract, so for now this requirement will be enforced by\n        //       documentation only.\n        freeStack();\n    }\n\n\n    ///////////////////////////////////////////////////////////////////////////\n    // General Actions\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Transfers execution to this fiber object.  The calling context will be\n     * suspended until the fiber calls Fiber.yield() or until it terminates\n     * via an unhandled exception.\n     *\n     * Params:\n     *  rethrow = Rethrow any unhandled exception which may have caused this\n     *            fiber to terminate.\n     *\n     * In:\n     *  This fiber must be in state HOLD.\n     *\n     * Throws:\n     *  Any exception not handled by the joined thread.\n     *\n     * Returns:\n     *  Any exception not handled by this fiber if rethrow = false, null\n     *  otherwise.\n     */\n    // Not marked with any attributes, even though `nothrow @nogc` works\n    // because it calls arbitrary user code. Most of the implementation\n    // is already `@nogc nothrow`, but in order for `Fiber.call` to\n    // propagate the attributes of the user's function, the Fiber\n    // class needs to be templated.\n    final Throwable call( Rethrow rethrow = Rethrow.yes )\n    {\n        return rethrow ? call!(Rethrow.yes)() : call!(Rethrow.no);\n    }\n\n    /// ditto\n    final Throwable call( Rethrow rethrow )()\n    {\n        callImpl();\n        if ( m_unhandled )\n        {\n            Throwable t = m_unhandled;\n            m_unhandled = null;\n            static if ( rethrow )\n                throw t;\n            else\n                return t;\n        }\n        return null;\n    }\n\n    /// ditto\n    deprecated(\"Please pass Fiber.Rethrow.yes or .no instead of a boolean.\")\n    final Throwable call( bool rethrow )\n    {\n        return rethrow ? call!(Rethrow.yes)() : call!(Rethrow.no);\n    }\n\n    private void callImpl() nothrow @nogc\n    in\n    {\n        assert( m_state == State.HOLD );\n    }\n    do\n    {\n        Fiber   cur = getThis();\n\n        static if ( __traits( compiles, ucontext_t ) )\n          m_ucur = cur ? &cur.m_utxt : &Fiber.sm_utxt;\n\n        setThis( this );\n        this.switchIn();\n        setThis( cur );\n\n        static if ( __traits( compiles, ucontext_t ) )\n          m_ucur = null;\n\n        // NOTE: If the fiber has terminated then the stack pointers must be\n        //       reset.  This ensures that the stack for this fiber is not\n        //       scanned if the fiber has terminated.  This is necessary to\n        //       prevent any references lingering on the stack from delaying\n        //       the collection of otherwise dead objects.  The most notable\n        //       being the current object, which is referenced at the top of\n        //       fiber_entryPoint.\n        if ( m_state == State.TERM )\n        {\n            m_ctxt.tstack = m_ctxt.bstack;\n        }\n    }\n\n    /// Flag to control rethrow behavior of $(D $(LREF call))\n    enum Rethrow : bool { no, yes }\n\n    /**\n     * Resets this fiber so that it may be re-used, optionally with a\n     * new function/delegate.  This routine should only be called for\n     * fibers that have terminated, as doing otherwise could result in\n     * scope-dependent functionality that is not executed.\n     * Stack-based classes, for example, may not be cleaned up\n     * properly if a fiber is reset before it has terminated.\n     *\n     * In:\n     *  This fiber must be in state TERM or HOLD.\n     */\n    final void reset() nothrow @nogc\n    in\n    {\n        assert( m_state == State.TERM || m_state == State.HOLD );\n    }\n    do\n    {\n        m_ctxt.tstack = m_ctxt.bstack;\n        m_state = State.HOLD;\n        initStack();\n        m_unhandled = null;\n    }\n\n    /// ditto\n    final void reset( void function() fn ) nothrow @nogc\n    {\n        reset();\n        m_fn    = fn;\n        m_call  = Call.FN;\n    }\n\n    /// ditto\n    final void reset( void delegate() dg ) nothrow @nogc\n    {\n        reset();\n        m_dg    = dg;\n        m_call  = Call.DG;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // General Properties\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    /// A fiber may occupy one of three states: HOLD, EXEC, and TERM.\n    enum State\n    {\n        /** The HOLD state applies to any fiber that is suspended and ready to\n        be called. */\n        HOLD,\n        /** The EXEC state will be set for any fiber that is currently\n        executing. */\n        EXEC,\n        /** The TERM state is set when a fiber terminates. Once a fiber\n        terminates, it must be reset before it may be called again. */\n        TERM\n    }\n\n\n    /**\n     * Gets the current state of this fiber.\n     *\n     * Returns:\n     *  The state of this fiber as an enumerated value.\n     */\n    final @property State state() const @safe pure nothrow @nogc\n    {\n        return m_state;\n    }\n\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Actions on Calling Fiber\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Forces a context switch to occur away from the calling fiber.\n     */\n    static void yield() nothrow @nogc\n    {\n        Fiber   cur = getThis();\n        assert( cur, \"Fiber.yield() called with no active fiber\" );\n        assert( cur.m_state == State.EXEC );\n\n        static if ( __traits( compiles, ucontext_t ) )\n          cur.m_ucur = &cur.m_utxt;\n\n        cur.m_state = State.HOLD;\n        cur.switchOut();\n        cur.m_state = State.EXEC;\n    }\n\n\n    /**\n     * Forces a context switch to occur away from the calling fiber and then\n     * throws obj in the calling fiber.\n     *\n     * Params:\n     *  t = The object to throw.\n     *\n     * In:\n     *  t must not be null.\n     */\n    static void yieldAndThrow( Throwable t ) nothrow @nogc\n    in\n    {\n        assert( t );\n    }\n    do\n    {\n        Fiber   cur = getThis();\n        assert( cur, \"Fiber.yield() called with no active fiber\" );\n        assert( cur.m_state == State.EXEC );\n\n        static if ( __traits( compiles, ucontext_t ) )\n          cur.m_ucur = &cur.m_utxt;\n\n        cur.m_unhandled = t;\n        cur.m_state = State.HOLD;\n        cur.switchOut();\n        cur.m_state = State.EXEC;\n    }\n\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Fiber Accessors\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    /**\n     * Provides a reference to the calling fiber or null if no fiber is\n     * currently active.\n     *\n     * Returns:\n     *  The fiber object representing the calling fiber or null if no fiber\n     *  is currently active within this thread. The result of deleting this object is undefined.\n     */\n    static Fiber getThis() @safe nothrow @nogc\n    {\n        return sm_this;\n    }\n\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Static Initialization\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    version (Posix)\n    {\n        static this()\n        {\n            static if ( __traits( compiles, ucontext_t ) )\n            {\n              int status = getcontext( &sm_utxt );\n              assert( status == 0 );\n            }\n        }\n    }\n\nprivate:\n    //\n    // Initializes a fiber object which has no associated executable function.\n    //\n    this() @safe pure nothrow @nogc\n    {\n        m_call = Call.NO;\n    }\n\n\n    //\n    // Fiber entry point.  Invokes the function or delegate passed on\n    // construction (if any).\n    //\n    final void run()\n    {\n        switch ( m_call )\n        {\n        case Call.FN:\n            m_fn();\n            break;\n        case Call.DG:\n            m_dg();\n            break;\n        default:\n            break;\n        }\n    }\n\n\nprivate:\n    //\n    // The type of routine passed on fiber construction.\n    //\n    enum Call\n    {\n        NO,\n        FN,\n        DG\n    }\n\n\n    //\n    // Standard fiber data\n    //\n    Call                m_call;\n    union\n    {\n        void function() m_fn;\n        void delegate() m_dg;\n    }\n    bool                m_isRunning;\n    Throwable           m_unhandled;\n    State               m_state;\n\n\nprivate:\n    ///////////////////////////////////////////////////////////////////////////\n    // Stack Management\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    //\n    // Allocate a new stack for this fiber.\n    //\n    final void allocStack( size_t sz, size_t guardPageSize ) nothrow\n    in\n    {\n        assert( !m_pmem && !m_ctxt );\n    }\n    do\n    {\n        // adjust alloc size to a multiple of PAGESIZE\n        sz += PAGESIZE - 1;\n        sz -= sz % PAGESIZE;\n\n        // NOTE: This instance of Thread.Context is dynamic so Fiber objects\n        //       can be collected by the GC so long as no user level references\n        //       to the object exist.  If m_ctxt were not dynamic then its\n        //       presence in the global context list would be enough to keep\n        //       this object alive indefinitely.  An alternative to allocating\n        //       room for this struct explicitly would be to mash it into the\n        //       base of the stack being allocated below.  However, doing so\n        //       requires too much special logic to be worthwhile.\n        m_ctxt = new Thread.Context;\n\n        static if ( __traits( compiles, VirtualAlloc ) )\n        {\n            // reserve memory for stack\n            m_pmem = VirtualAlloc( null,\n                                   sz + guardPageSize,\n                                   MEM_RESERVE,\n                                   PAGE_NOACCESS );\n            if ( !m_pmem )\n                onOutOfMemoryError();\n\n            version (StackGrowsDown)\n            {\n                void* stack = m_pmem + guardPageSize;\n                void* guard = m_pmem;\n                void* pbase = stack + sz;\n            }\n            else\n            {\n                void* stack = m_pmem;\n                void* guard = m_pmem + sz;\n                void* pbase = stack;\n            }\n\n            // allocate reserved stack segment\n            stack = VirtualAlloc( stack,\n                                  sz,\n                                  MEM_COMMIT,\n                                  PAGE_READWRITE );\n            if ( !stack )\n                onOutOfMemoryError();\n\n            if (guardPageSize)\n            {\n                // allocate reserved guard page\n                guard = VirtualAlloc( guard,\n                                      guardPageSize,\n                                      MEM_COMMIT,\n                                      PAGE_READWRITE | PAGE_GUARD );\n                if ( !guard )\n                    onOutOfMemoryError();\n            }\n\n            m_ctxt.bstack = pbase;\n            m_ctxt.tstack = pbase;\n            m_size = sz;\n        }\n        else\n        {\n            version (Posix) import core.sys.posix.sys.mman; // mmap\n            version (FreeBSD) import core.sys.freebsd.sys.mman : MAP_ANON;\n            version (NetBSD) import core.sys.netbsd.sys.mman : MAP_ANON;\n            version (DragonFlyBSD) import core.sys.dragonflybsd.sys.mman : MAP_ANON;\n            version (CRuntime_Glibc) import core.sys.linux.sys.mman : MAP_ANON;\n            version (Darwin) import core.sys.darwin.sys.mman : MAP_ANON;\n            version (CRuntime_UClibc) import core.sys.linux.sys.mman : MAP_ANON;\n\n            static if ( __traits( compiles, mmap ) )\n            {\n                // Allocate more for the memory guard\n                sz += guardPageSize;\n\n                m_pmem = mmap( null,\n                               sz,\n                               PROT_READ | PROT_WRITE,\n                               MAP_PRIVATE | MAP_ANON,\n                               -1,\n                               0 );\n                if ( m_pmem == MAP_FAILED )\n                    m_pmem = null;\n            }\n            else static if ( __traits( compiles, valloc ) )\n            {\n                m_pmem = valloc( sz );\n            }\n            else static if ( __traits( compiles, malloc ) )\n            {\n                m_pmem = malloc( sz );\n            }\n            else\n            {\n                m_pmem = null;\n            }\n\n            if ( !m_pmem )\n                onOutOfMemoryError();\n\n            version (StackGrowsDown)\n            {\n                m_ctxt.bstack = m_pmem + sz;\n                m_ctxt.tstack = m_pmem + sz;\n                void* guard = m_pmem;\n            }\n            else\n            {\n                m_ctxt.bstack = m_pmem;\n                m_ctxt.tstack = m_pmem;\n                void* guard = m_pmem + sz - guardPageSize;\n            }\n            m_size = sz;\n\n            static if ( __traits( compiles, mmap ) )\n            {\n                if (guardPageSize)\n                {\n                    // protect end of stack\n                    if ( mprotect(guard, guardPageSize, PROT_NONE) == -1 )\n                        abort();\n                }\n            }\n            else\n            {\n                // Supported only for mmap allocated memory - results are\n                // undefined if applied to memory not obtained by mmap\n            }\n        }\n\n        Thread.add( m_ctxt );\n    }\n\n\n    //\n    // Free this fiber's stack.\n    //\n    final void freeStack() nothrow @nogc\n    in\n    {\n        assert( m_pmem && m_ctxt );\n    }\n    do\n    {\n        // NOTE: m_ctxt is guaranteed to be alive because it is held in the\n        //       global context list.\n        Thread.slock.lock_nothrow();\n        scope(exit) Thread.slock.unlock_nothrow();\n        Thread.remove( m_ctxt );\n\n        static if ( __traits( compiles, VirtualAlloc ) )\n        {\n            VirtualFree( m_pmem, 0, MEM_RELEASE );\n        }\n        else\n        {\n            import core.sys.posix.sys.mman; // munmap\n\n            static if ( __traits( compiles, mmap ) )\n            {\n                munmap( m_pmem, m_size );\n            }\n            else static if ( __traits( compiles, valloc ) )\n            {\n                free( m_pmem );\n            }\n            else static if ( __traits( compiles, malloc ) )\n            {\n                free( m_pmem );\n            }\n        }\n        m_pmem = null;\n        m_ctxt = null;\n    }\n\n\n    //\n    // Initialize the allocated stack.\n    // Look above the definition of 'class Fiber' for some information about the implementation of this routine\n    //\n    final void initStack() nothrow @nogc\n    in\n    {\n        assert( m_ctxt.tstack && m_ctxt.tstack == m_ctxt.bstack );\n        assert( cast(size_t) m_ctxt.bstack % (void*).sizeof == 0 );\n    }\n    do\n    {\n        void* pstack = m_ctxt.tstack;\n        scope( exit )  m_ctxt.tstack = pstack;\n\n        void push( size_t val ) nothrow\n        {\n            version (StackGrowsDown)\n            {\n                pstack -= size_t.sizeof;\n                *(cast(size_t*) pstack) = val;\n            }\n            else\n            {\n                pstack += size_t.sizeof;\n                *(cast(size_t*) pstack) = val;\n            }\n        }\n\n        // NOTE: On OS X the stack must be 16-byte aligned according\n        // to the IA-32 call spec. For x86_64 the stack also needs to\n        // be aligned to 16-byte according to SysV AMD64 ABI.\n        version (AlignFiberStackTo16Byte)\n        {\n            version (StackGrowsDown)\n            {\n                pstack = cast(void*)(cast(size_t)(pstack) - (cast(size_t)(pstack) & 0x0F));\n            }\n            else\n            {\n                pstack = cast(void*)(cast(size_t)(pstack) + (cast(size_t)(pstack) & 0x0F));\n            }\n        }\n\n        version (AsmX86_Windows)\n        {\n            version (StackGrowsDown) {} else static assert( false );\n\n            // On Windows Server 2008 and 2008 R2, an exploit mitigation\n            // technique known as SEHOP is activated by default. To avoid\n            // hijacking of the exception handler chain, the presence of a\n            // Windows-internal handler (ntdll.dll!FinalExceptionHandler) at\n            // its end is tested by RaiseException. If it is not present, all\n            // handlers are disregarded, and the program is thus aborted\n            // (see http://blogs.technet.com/b/srd/archive/2009/02/02/\n            // preventing-the-exploitation-of-seh-overwrites-with-sehop.aspx).\n            // For new threads, this handler is installed by Windows immediately\n            // after creation. To make exception handling work in fibers, we\n            // have to insert it for our new stacks manually as well.\n            //\n            // To do this, we first determine the handler by traversing the SEH\n            // chain of the current thread until its end, and then construct a\n            // registration block for the last handler on the newly created\n            // thread. We then continue to push all the initial register values\n            // for the first context switch as for the other implementations.\n            //\n            // Note that this handler is never actually invoked, as we install\n            // our own one on top of it in the fiber entry point function.\n            // Thus, it should not have any effects on OSes not implementing\n            // exception chain verification.\n\n            alias fp_t = void function(); // Actual signature not relevant.\n            static struct EXCEPTION_REGISTRATION\n            {\n                EXCEPTION_REGISTRATION* next; // sehChainEnd if last one.\n                fp_t handler;\n            }\n            enum sehChainEnd = cast(EXCEPTION_REGISTRATION*) 0xFFFFFFFF;\n\n            __gshared static fp_t finalHandler = null;\n            if ( finalHandler is null )\n            {\n                static EXCEPTION_REGISTRATION* fs0() nothrow\n                {\n                    asm pure nothrow @nogc\n                    {\n                        naked;\n                        mov EAX, FS:[0];\n                        ret;\n                    }\n                }\n                auto reg = fs0();\n                while ( reg.next != sehChainEnd ) reg = reg.next;\n\n                // Benign races are okay here, just to avoid re-lookup on every\n                // fiber creation.\n                finalHandler = reg.handler;\n            }\n\n            // When linking with /safeseh (supported by LDC, but not DMD)\n            // the exception chain must not extend to the very top\n            // of the stack, otherwise the exception chain is also considered\n            // invalid. Reserving additional 4 bytes at the top of the stack will\n            // keep the EXCEPTION_REGISTRATION below that limit\n            size_t reserve = EXCEPTION_REGISTRATION.sizeof + 4;\n            pstack -= reserve;\n            *(cast(EXCEPTION_REGISTRATION*)pstack) =\n                EXCEPTION_REGISTRATION( sehChainEnd, finalHandler );\n\n            push( cast(size_t) &fiber_entryPoint );                 // EIP\n            push( cast(size_t) m_ctxt.bstack - reserve );           // EBP\n            push( 0x00000000 );                                     // EDI\n            push( 0x00000000 );                                     // ESI\n            push( 0x00000000 );                                     // EBX\n            push( cast(size_t) m_ctxt.bstack - reserve );           // FS:[0]\n            push( cast(size_t) m_ctxt.bstack );                     // FS:[4]\n            push( cast(size_t) m_ctxt.bstack - m_size );            // FS:[8]\n            push( 0x00000000 );                                     // EAX\n        }\n        else version (AsmX86_64_Windows)\n        {\n            // Using this trampoline instead of the raw fiber_entryPoint\n            // ensures that during context switches, source and destination\n            // stacks have the same alignment. Otherwise, the stack would need\n            // to be shifted by 8 bytes for the first call, as fiber_entryPoint\n            // is an actual function expecting a stack which is not aligned\n            // to 16 bytes.\n            static void trampoline()\n            {\n                asm pure nothrow @nogc\n                {\n                    naked;\n                    sub RSP, 32; // Shadow space (Win64 calling convention)\n                    call fiber_entryPoint;\n                    xor RCX, RCX; // This should never be reached, as\n                    jmp RCX;      // fiber_entryPoint must never return.\n                }\n            }\n\n            push( cast(size_t) &trampoline );                       // RIP\n            push( 0x00000000_00000000 );                            // RBP\n            push( 0x00000000_00000000 );                            // R12\n            push( 0x00000000_00000000 );                            // R13\n            push( 0x00000000_00000000 );                            // R14\n            push( 0x00000000_00000000 );                            // R15\n            push( 0x00000000_00000000 );                            // RDI\n            push( 0x00000000_00000000 );                            // RSI\n            push( 0x00000000_00000000 );                            // XMM6 (high)\n            push( 0x00000000_00000000 );                            // XMM6 (low)\n            push( 0x00000000_00000000 );                            // XMM7 (high)\n            push( 0x00000000_00000000 );                            // XMM7 (low)\n            push( 0x00000000_00000000 );                            // XMM8 (high)\n            push( 0x00000000_00000000 );                            // XMM8 (low)\n            push( 0x00000000_00000000 );                            // XMM9 (high)\n            push( 0x00000000_00000000 );                            // XMM9 (low)\n            push( 0x00000000_00000000 );                            // XMM10 (high)\n            push( 0x00000000_00000000 );                            // XMM10 (low)\n            push( 0x00000000_00000000 );                            // XMM11 (high)\n            push( 0x00000000_00000000 );                            // XMM11 (low)\n            push( 0x00000000_00000000 );                            // XMM12 (high)\n            push( 0x00000000_00000000 );                            // XMM12 (low)\n            push( 0x00000000_00000000 );                            // XMM13 (high)\n            push( 0x00000000_00000000 );                            // XMM13 (low)\n            push( 0x00000000_00000000 );                            // XMM14 (high)\n            push( 0x00000000_00000000 );                            // XMM14 (low)\n            push( 0x00000000_00000000 );                            // XMM15 (high)\n            push( 0x00000000_00000000 );                            // XMM15 (low)\n            push( 0x00000000_00000000 );                            // RBX\n            push( 0xFFFFFFFF_FFFFFFFF );                            // GS:[0]\n            version (StackGrowsDown)\n            {\n                push( cast(size_t) m_ctxt.bstack );                 // GS:[8]\n                push( cast(size_t) m_ctxt.bstack - m_size );        // GS:[16]\n            }\n            else\n            {\n                push( cast(size_t) m_ctxt.bstack );                 // GS:[8]\n                push( cast(size_t) m_ctxt.bstack + m_size );        // GS:[16]\n            }\n        }\n        else version (AsmX86_Posix)\n        {\n            push( 0x00000000 );                                     // Return address of fiber_entryPoint call\n            push( cast(size_t) &fiber_entryPoint );                 // EIP\n            push( cast(size_t) m_ctxt.bstack );                     // EBP\n            push( 0x00000000 );                                     // EDI\n            push( 0x00000000 );                                     // ESI\n            push( 0x00000000 );                                     // EBX\n            push( 0x00000000 );                                     // EAX\n        }\n        else version (AsmX86_64_Posix)\n        {\n            push( 0x00000000_00000000 );                            // Return address of fiber_entryPoint call\n            push( cast(size_t) &fiber_entryPoint );                 // RIP\n            push( cast(size_t) m_ctxt.bstack );                     // RBP\n            push( 0x00000000_00000000 );                            // RBX\n            push( 0x00000000_00000000 );                            // R12\n            push( 0x00000000_00000000 );                            // R13\n            push( 0x00000000_00000000 );                            // R14\n            push( 0x00000000_00000000 );                            // R15\n        }\n        else version (AsmPPC_Posix)\n        {\n            version (StackGrowsDown)\n            {\n                pstack -= int.sizeof * 5;\n            }\n            else\n            {\n                pstack += int.sizeof * 5;\n            }\n\n            push( cast(size_t) &fiber_entryPoint );     // link register\n            push( 0x00000000 );                         // control register\n            push( 0x00000000 );                         // old stack pointer\n\n            // GPR values\n            version (StackGrowsDown)\n            {\n                pstack -= int.sizeof * 20;\n            }\n            else\n            {\n                pstack += int.sizeof * 20;\n            }\n\n            assert( (cast(size_t) pstack & 0x0f) == 0 );\n        }\n        else version (AsmMIPS_O32_Posix)\n        {\n            version (StackGrowsDown) {}\n            else static assert(0);\n\n            /* We keep the FP registers and the return address below\n             * the stack pointer, so they don't get scanned by the\n             * GC. The last frame before swapping the stack pointer is\n             * organized like the following.\n             *\n             *     |-----------|<= frame pointer\n             *     |    $gp    |\n             *     |   $s0-8   |\n             *     |-----------|<= stack pointer\n             *     |    $ra    |\n             *     |  align(8) |\n             *     |  $f20-30  |\n             *     |-----------|\n             *\n             */\n            enum SZ_GP = 10 * size_t.sizeof; // $gp + $s0-8\n            enum SZ_RA = size_t.sizeof;      // $ra\n            version (MIPS_HardFloat)\n            {\n                enum SZ_FP = 6 * 8;          // $f20-30\n                enum ALIGN = -(SZ_FP + SZ_RA) & (8 - 1);\n            }\n            else\n            {\n                enum SZ_FP = 0;\n                enum ALIGN = 0;\n            }\n\n            enum BELOW = SZ_FP + ALIGN + SZ_RA;\n            enum ABOVE = SZ_GP;\n            enum SZ = BELOW + ABOVE;\n\n            (cast(ubyte*)pstack - SZ)[0 .. SZ] = 0;\n            pstack -= ABOVE;\n            *cast(size_t*)(pstack - SZ_RA) = cast(size_t)&fiber_entryPoint;\n        }\n        else version (AsmAArch64_Posix)\n        {\n            // Like others, FP registers and return address (lr) are kept\n            // below the saved stack top (tstack) to hide from GC scanning.\n            // fiber_switchContext expects newp sp to look like this:\n            //   19: x19\n            //   ...\n            //    9: x29 (fp)  <-- newp tstack\n            //    8: x30 (lr)  [&fiber_entryPoint]\n            //    7: d8\n            //   ...\n            //    0: d15\n\n            version (StackGrowsDown) {}\n            else\n                static assert(false, \"Only full descending stacks supported on AArch64\");\n\n            // Only need to set return address (lr).  Everything else is fine\n            // zero initialized.\n            pstack -= size_t.sizeof * 11;    // skip past x19-x29\n            push(cast(size_t) &fiber_trampoline); // see threadasm.S for docs\n            pstack += size_t.sizeof;         // adjust sp (newp) above lr\n        }\n        else version (AsmARM_Posix)\n        {\n            /* We keep the FP registers and the return address below\n             * the stack pointer, so they don't get scanned by the\n             * GC. The last frame before swapping the stack pointer is\n             * organized like the following.\n             *\n             *   |  |-----------|<= 'frame starts here'\n             *   |  |     fp    | (the actual frame pointer, r11 isn't\n             *   |  |   r10-r4  |  updated and still points to the previous frame)\n             *   |  |-----------|<= stack pointer\n             *   |  |     lr    |\n             *   |  | 4byte pad |\n             *   |  |   d15-d8  |(if FP supported)\n             *   |  |-----------|\n             *   Y\n             *   stack grows down: The pointer value here is smaller than some lines above\n             */\n            // frame pointer can be zero, r10-r4 also zero initialized\n            version (StackGrowsDown)\n                pstack -= int.sizeof * 8;\n            else\n                static assert(false, \"Only full descending stacks supported on ARM\");\n\n            // link register\n            push( cast(size_t) &fiber_entryPoint );\n            /*\n             * We do not push padding and d15-d8 as those are zero initialized anyway\n             * Position the stack pointer above the lr register\n             */\n            pstack += int.sizeof * 1;\n        }\n        else version (GNU_AsmX86_Windows)\n        {\n            version (StackGrowsDown) {} else static assert( false );\n\n            // Currently, MinGW doesn't utilize SEH exceptions.\n            // See DMD AsmX86_Windows If this code ever becomes fails and SEH is used.\n\n            push( 0x00000000 );                                     // Return address of fiber_entryPoint call\n            push( cast(size_t) &fiber_entryPoint );                 // EIP\n            push( 0x00000000 );                                     // EBP\n            push( 0x00000000 );                                     // EDI\n            push( 0x00000000 );                                     // ESI\n            push( 0x00000000 );                                     // EBX\n            push( 0xFFFFFFFF );                                     // FS:[0] - Current SEH frame\n            push( cast(size_t) m_ctxt.bstack );                     // FS:[4] - Top of stack\n            push( cast(size_t) m_ctxt.bstack - m_size );            // FS:[8] - Bottom of stack\n            push( 0x00000000 );                                     // EAX\n        }\n        else version (GNU_AsmX86_64_Windows)\n        {\n            push( 0x00000000_00000000 );                            // Return address of fiber_entryPoint call\n            push( cast(size_t) &fiber_entryPoint );                 // RIP\n            push( 0x00000000_00000000 );                            // RBP\n            push( 0x00000000_00000000 );                            // RBX\n            push( 0x00000000_00000000 );                            // R12\n            push( 0x00000000_00000000 );                            // R13\n            push( 0x00000000_00000000 );                            // R14\n            push( 0x00000000_00000000 );                            // R15\n            push( 0xFFFFFFFF_FFFFFFFF );                            // GS:[0] - Current SEH frame\n            version (StackGrowsDown)\n            {\n                push( cast(size_t) m_ctxt.bstack );                 // GS:[8]  - Top of stack\n                push( cast(size_t) m_ctxt.bstack - m_size );        // GS:[16] - Bottom of stack\n            }\n            else\n            {\n                push( cast(size_t) m_ctxt.bstack );                 // GS:[8]  - Top of stack\n                push( cast(size_t) m_ctxt.bstack + m_size );        // GS:[16] - Bottom of stack\n            }\n        }\n        else static if ( __traits( compiles, ucontext_t ) )\n        {\n            getcontext( &m_utxt );\n            m_utxt.uc_stack.ss_sp   = m_pmem;\n            m_utxt.uc_stack.ss_size = m_size;\n            makecontext( &m_utxt, &fiber_entryPoint, 0 );\n            // NOTE: If ucontext is being used then the top of the stack will\n            //       be a pointer to the ucontext_t struct for that fiber.\n            push( cast(size_t) &m_utxt );\n        }\n        else\n            static assert(0, \"Not implemented\");\n    }\n\n\n    Thread.Context* m_ctxt;\n    size_t          m_size;\n    void*           m_pmem;\n\n    static if ( __traits( compiles, ucontext_t ) )\n    {\n        // NOTE: The static ucontext instance is used to represent the context\n        //       of the executing thread.\n        static ucontext_t       sm_utxt = void;\n        ucontext_t              m_utxt  = void;\n        ucontext_t*             m_ucur  = null;\n    }\n\n\nprivate:\n    ///////////////////////////////////////////////////////////////////////////\n    // Storage of Active Fiber\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    //\n    // Sets a thread-local reference to the current fiber object.\n    //\n    static void setThis( Fiber f ) nothrow @nogc\n    {\n        sm_this = f;\n    }\n\n    static Fiber sm_this;\n\n\nprivate:\n    ///////////////////////////////////////////////////////////////////////////\n    // Context Switching\n    ///////////////////////////////////////////////////////////////////////////\n\n\n    //\n    // Switches into the stack held by this fiber.\n    //\n    final void switchIn() nothrow @nogc\n    {\n        Thread  tobj = Thread.getThis();\n        void**  oldp = &tobj.m_curr.tstack;\n        void*   newp = m_ctxt.tstack;\n\n        // NOTE: The order of operations here is very important.  The current\n        //       stack top must be stored before m_lock is set, and pushContext\n        //       must not be called until after m_lock is set.  This process\n        //       is intended to prevent a race condition with the suspend\n        //       mechanism used for garbage collection.  If it is not followed,\n        //       a badly timed collection could cause the GC to scan from the\n        //       bottom of one stack to the top of another, or to miss scanning\n        //       a stack that still contains valid data.  The old stack pointer\n        //       oldp will be set again before the context switch to guarantee\n        //       that it points to exactly the correct stack location so the\n        //       successive pop operations will succeed.\n        *oldp = getStackTop();\n        atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, true);\n        tobj.pushContext( m_ctxt );\n\n        fiber_switchContext( oldp, newp );\n\n        // NOTE: As above, these operations must be performed in a strict order\n        //       to prevent Bad Things from happening.\n        tobj.popContext();\n        atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, false);\n        tobj.m_curr.tstack = tobj.m_curr.bstack;\n    }\n\n\n    //\n    // Switches out of the current stack and into the enclosing stack.\n    //\n    final void switchOut() nothrow @nogc\n    {\n        Thread  tobj = Thread.getThis();\n        void**  oldp = &m_ctxt.tstack;\n        void*   newp = tobj.m_curr.within.tstack;\n\n        // NOTE: The order of operations here is very important.  The current\n        //       stack top must be stored before m_lock is set, and pushContext\n        //       must not be called until after m_lock is set.  This process\n        //       is intended to prevent a race condition with the suspend\n        //       mechanism used for garbage collection.  If it is not followed,\n        //       a badly timed collection could cause the GC to scan from the\n        //       bottom of one stack to the top of another, or to miss scanning\n        //       a stack that still contains valid data.  The old stack pointer\n        //       oldp will be set again before the context switch to guarantee\n        //       that it points to exactly the correct stack location so the\n        //       successive pop operations will succeed.\n        *oldp = getStackTop();\n        atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, true);\n\n        fiber_switchContext( oldp, newp );\n\n        // NOTE: As above, these operations must be performed in a strict order\n        //       to prevent Bad Things from happening.\n        // NOTE: If use of this fiber is multiplexed across threads, the thread\n        //       executing here may be different from the one above, so get the\n        //       current thread handle before unlocking, etc.\n        tobj = Thread.getThis();\n        atomicStore!(MemoryOrder.raw)(*cast(shared)&tobj.m_lock, false);\n        tobj.m_curr.tstack = tobj.m_curr.bstack;\n    }\n}\n\n///\nunittest {\n    int counter;\n\n    class DerivedFiber : Fiber\n    {\n        this()\n        {\n            super( &run );\n        }\n\n    private :\n        void run()\n        {\n            counter += 2;\n        }\n    }\n\n    void fiberFunc()\n    {\n        counter += 4;\n        Fiber.yield();\n        counter += 8;\n    }\n\n    // create instances of each type\n    Fiber derived = new DerivedFiber();\n    Fiber composed = new Fiber( &fiberFunc );\n\n    assert( counter == 0 );\n\n    derived.call();\n    assert( counter == 2, \"Derived fiber increment.\" );\n\n    composed.call();\n    assert( counter == 6, \"First composed fiber increment.\" );\n\n    counter += 16;\n    assert( counter == 22, \"Calling context increment.\" );\n\n    composed.call();\n    assert( counter == 30, \"Second composed fiber increment.\" );\n\n    // since each fiber has run to completion, each should have state TERM\n    assert( derived.state == Fiber.State.TERM );\n    assert( composed.state == Fiber.State.TERM );\n}\n\nversion (unittest)\n{\n    class TestFiber : Fiber\n    {\n        this()\n        {\n            super(&run);\n        }\n\n        void run()\n        {\n            foreach (i; 0 .. 1000)\n            {\n                sum += i;\n                Fiber.yield();\n            }\n        }\n\n        enum expSum = 1000 * 999 / 2;\n        size_t sum;\n    }\n\n    void runTen()\n    {\n        TestFiber[10] fibs;\n        foreach (ref fib; fibs)\n            fib = new TestFiber();\n\n        bool cont;\n        do {\n            cont = false;\n            foreach (fib; fibs) {\n                if (fib.state == Fiber.State.HOLD)\n                {\n                    fib.call();\n                    cont |= fib.state != Fiber.State.TERM;\n                }\n            }\n        } while (cont);\n\n        foreach (fib; fibs)\n        {\n            assert(fib.sum == TestFiber.expSum);\n        }\n    }\n}\n\n\n// Single thread running separate fibers\nunittest\n{\n    runTen();\n}\n\n\n// Multiple threads running separate fibers\nunittest\n{\n    auto group = new ThreadGroup();\n    foreach (_; 0 .. 4)\n    {\n        group.create(&runTen);\n    }\n    group.joinAll();\n}\n\n\n// Multiple threads running shared fibers\nunittest\n{\n    shared bool[10] locks;\n    TestFiber[10] fibs;\n\n    void runShared()\n    {\n        bool cont;\n        do {\n            cont = false;\n            foreach (idx; 0 .. 10)\n            {\n                if (cas(&locks[idx], false, true))\n                {\n                    if (fibs[idx].state == Fiber.State.HOLD)\n                    {\n                        fibs[idx].call();\n                        cont |= fibs[idx].state != Fiber.State.TERM;\n                    }\n                    locks[idx] = false;\n                }\n                else\n                {\n                    cont = true;\n                }\n            }\n        } while (cont);\n    }\n\n    foreach (ref fib; fibs)\n    {\n        fib = new TestFiber();\n    }\n\n    auto group = new ThreadGroup();\n    foreach (_; 0 .. 4)\n    {\n        group.create(&runShared);\n    }\n    group.joinAll();\n\n    foreach (fib; fibs)\n    {\n        assert(fib.sum == TestFiber.expSum);\n    }\n}\n\n\n// Test exception handling inside fibers.\nversion (Win32) {\n    // broken on win32 under windows server 2012: bug 13821\n} else unittest {\n    enum MSG = \"Test message.\";\n    string caughtMsg;\n    (new Fiber({\n        try\n        {\n            throw new Exception(MSG);\n        }\n        catch (Exception e)\n        {\n            caughtMsg = e.msg;\n        }\n    })).call();\n    assert(caughtMsg == MSG);\n}\n\n\nunittest\n{\n    int x = 0;\n\n    (new Fiber({\n        x++;\n    })).call();\n    assert( x == 1 );\n}\n\nnothrow unittest\n{\n    new Fiber({}).call!(Fiber.Rethrow.no)();\n}\n\nunittest\n{\n    new Fiber({}).call(Fiber.Rethrow.yes);\n    new Fiber({}).call(Fiber.Rethrow.no);\n}\n\ndeprecated unittest\n{\n    new Fiber({}).call(true);\n    new Fiber({}).call(false);\n}\n\nversion (Win32) {\n    // broken on win32 under windows server 2012: bug 13821\n} else unittest {\n    enum MSG = \"Test message.\";\n\n    try\n    {\n        (new Fiber({\n            throw new Exception( MSG );\n        })).call();\n        assert( false, \"Expected rethrown exception.\" );\n    }\n    catch ( Throwable t )\n    {\n        assert( t.msg == MSG );\n    }\n}\n\n// Test exception chaining when switching contexts in finally blocks.\nunittest\n{\n    static void throwAndYield(string msg) {\n      try {\n        throw new Exception(msg);\n      } finally {\n        Fiber.yield();\n      }\n    }\n\n    static void fiber(string name) {\n      try {\n        try {\n          throwAndYield(name ~ \".1\");\n        } finally {\n          throwAndYield(name ~ \".2\");\n        }\n      } catch (Exception e) {\n        assert(e.msg == name ~ \".1\");\n        assert(e.next);\n        assert(e.next.msg == name ~ \".2\");\n        assert(!e.next.next);\n      }\n    }\n\n    auto first = new Fiber(() => fiber(\"first\"));\n    auto second = new Fiber(() => fiber(\"second\"));\n    first.call();\n    second.call();\n    first.call();\n    second.call();\n    first.call();\n    second.call();\n    assert(first.state == Fiber.State.TERM);\n    assert(second.state == Fiber.State.TERM);\n}\n\n// Test Fiber resetting\nunittest\n{\n    static string method;\n\n    static void foo()\n    {\n        method = \"foo\";\n    }\n\n    void bar()\n    {\n        method = \"bar\";\n    }\n\n    static void expect(Fiber fib, string s)\n    {\n        assert(fib.state == Fiber.State.HOLD);\n        fib.call();\n        assert(fib.state == Fiber.State.TERM);\n        assert(method == s); method = null;\n    }\n    auto fib = new Fiber(&foo);\n    expect(fib, \"foo\");\n\n    fib.reset();\n    expect(fib, \"foo\");\n\n    fib.reset(&foo);\n    expect(fib, \"foo\");\n\n    fib.reset(&bar);\n    expect(fib, \"bar\");\n\n    fib.reset(function void(){method = \"function\";});\n    expect(fib, \"function\");\n\n    fib.reset(delegate void(){method = \"delegate\";});\n    expect(fib, \"delegate\");\n}\n\n// Test unsafe reset in hold state\nunittest\n{\n    auto fib = new Fiber(function {ubyte[2048] buf = void; Fiber.yield();}, 4096);\n    foreach (_; 0 .. 10)\n    {\n        fib.call();\n        assert(fib.state == Fiber.State.HOLD);\n        fib.reset();\n    }\n}\n\n// stress testing GC stack scanning\nunittest\n{\n    import core.memory;\n\n    static void unreferencedThreadObject()\n    {\n        static void sleep() { Thread.sleep(dur!\"msecs\"(100)); }\n        auto thread = new Thread(&sleep).start();\n    }\n    unreferencedThreadObject();\n    GC.collect();\n\n    static class Foo\n    {\n        this(int value)\n        {\n            _value = value;\n        }\n\n        int bar()\n        {\n            return _value;\n        }\n\n        int _value;\n    }\n\n    static void collect()\n    {\n        auto foo = new Foo(2);\n        assert(foo.bar() == 2);\n        GC.collect();\n        Fiber.yield();\n        GC.collect();\n        assert(foo.bar() == 2);\n    }\n\n    auto fiber = new Fiber(&collect);\n\n    fiber.call();\n    GC.collect();\n    fiber.call();\n\n    // thread reference\n    auto foo = new Foo(2);\n\n    void collect2()\n    {\n        assert(foo.bar() == 2);\n        GC.collect();\n        Fiber.yield();\n        GC.collect();\n        assert(foo.bar() == 2);\n    }\n\n    fiber = new Fiber(&collect2);\n\n    fiber.call();\n    GC.collect();\n    fiber.call();\n\n    static void recurse(size_t cnt)\n    {\n        --cnt;\n        Fiber.yield();\n        if (cnt)\n        {\n            auto fib = new Fiber(() { recurse(cnt); });\n            fib.call();\n            GC.collect();\n            fib.call();\n        }\n    }\n    fiber = new Fiber(() { recurse(20); });\n    fiber.call();\n}\n\n\nversion (AsmX86_64_Windows)\n{\n    // Test Windows x64 calling convention\n    unittest\n    {\n        void testNonvolatileRegister(alias REG)()\n        {\n            auto zeroRegister = new Fiber(() {\n                mixin(\"asm pure nothrow @nogc { naked; xor \"~REG~\", \"~REG~\"; ret; }\");\n            });\n            long after;\n\n            mixin(\"asm pure nothrow @nogc { mov \"~REG~\", 0xFFFFFFFFFFFFFFFF; }\");\n            zeroRegister.call();\n            mixin(\"asm pure nothrow @nogc { mov after, \"~REG~\"; }\");\n\n            assert(after == -1);\n        }\n\n        void testNonvolatileRegisterSSE(alias REG)()\n        {\n            auto zeroRegister = new Fiber(() {\n                mixin(\"asm pure nothrow @nogc { naked; xorpd \"~REG~\", \"~REG~\"; ret; }\");\n            });\n            long[2] before = [0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF], after;\n\n            mixin(\"asm pure nothrow @nogc { movdqu \"~REG~\", before; }\");\n            zeroRegister.call();\n            mixin(\"asm pure nothrow @nogc { movdqu after, \"~REG~\"; }\");\n\n            assert(before == after);\n        }\n\n        testNonvolatileRegister!(\"R12\")();\n        testNonvolatileRegister!(\"R13\")();\n        testNonvolatileRegister!(\"R14\")();\n        testNonvolatileRegister!(\"R15\")();\n        testNonvolatileRegister!(\"RDI\")();\n        testNonvolatileRegister!(\"RSI\")();\n        testNonvolatileRegister!(\"RBX\")();\n\n        testNonvolatileRegisterSSE!(\"XMM6\")();\n        testNonvolatileRegisterSSE!(\"XMM7\")();\n        testNonvolatileRegisterSSE!(\"XMM8\")();\n        testNonvolatileRegisterSSE!(\"XMM9\")();\n        testNonvolatileRegisterSSE!(\"XMM10\")();\n        testNonvolatileRegisterSSE!(\"XMM11\")();\n        testNonvolatileRegisterSSE!(\"XMM12\")();\n        testNonvolatileRegisterSSE!(\"XMM13\")();\n        testNonvolatileRegisterSSE!(\"XMM14\")();\n        testNonvolatileRegisterSSE!(\"XMM15\")();\n    }\n}\n\n\nversion (D_InlineAsm_X86_64)\n{\n    unittest\n    {\n        void testStackAlignment()\n        {\n            void* pRSP;\n            asm pure nothrow @nogc\n            {\n                mov pRSP, RSP;\n            }\n            assert((cast(size_t)pRSP & 0xF) == 0);\n        }\n\n        auto fib = new Fiber(&testStackAlignment);\n        fib.call();\n    }\n}\n\n// regression test for Issue 13416\nversion (FreeBSD) unittest\n{\n    static void loop()\n    {\n        pthread_attr_t attr;\n        pthread_attr_init(&attr);\n        auto thr = pthread_self();\n        foreach (i; 0 .. 50)\n            pthread_attr_get_np(thr, &attr);\n        pthread_attr_destroy(&attr);\n    }\n\n    auto thr = new Thread(&loop).start();\n    foreach (i; 0 .. 50)\n    {\n        thread_suspendAll();\n        thread_resumeAll();\n    }\n    thr.join();\n}\n\nversion (DragonFlyBSD) unittest\n{\n    static void loop()\n    {\n        pthread_attr_t attr;\n        pthread_attr_init(&attr);\n        auto thr = pthread_self();\n        foreach (i; 0 .. 50)\n            pthread_attr_get_np(thr, &attr);\n        pthread_attr_destroy(&attr);\n    }\n\n    auto thr = new Thread(&loop).start();\n    foreach (i; 0 .. 50)\n    {\n        thread_suspendAll();\n        thread_resumeAll();\n    }\n    thr.join();\n}\n\nunittest\n{\n    // use >PAGESIZE to avoid stack overflow (e.g. in an syscall)\n    auto thr = new Thread(function{}, 4096 + 1).start();\n    thr.join();\n}\n\n/**\n * Represents the ID of a thread, as returned by $(D Thread.)$(LREF id).\n * The exact type varies from platform to platform.\n */\nversion (Windows)\n    alias ThreadID = uint;\nelse\nversion (Posix)\n    alias ThreadID = pthread_t;\n"
  },
  {
    "path": "libphobos/libdruntime/core/threadasm.S",
    "content": "/**\n * Support code for mutithreading.\n *\n * Copyright: Copyright Mikola Lysenko 2005 - 2012.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Mikola Lysenko, Martin Nowak, Kai Nacke\n */\n\n/*\n *          Copyright Mikola Lysenko 2005 - 2012.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\n#if (__linux__ || __FreeBSD__ || __NetBSD__ || __DragonFly__) && __ELF__\n/*\n * Mark the resulting object file as not requiring execution permissions on\n * stack memory. The absence of this section would mark the whole resulting\n * library as requiring an executable stack, making it impossible to\n * dynamically load druntime on several Linux platforms where this is\n * forbidden due to security policies.\n * Use %progbits instead of @progbits to support ARM and X86.\n */\n.section .note.GNU-stack,\"\",%progbits\n#endif\n\n/* Let preprocessor tell us if C symbols have a prefix: __USER_LABEL_PREFIX__ */\n#ifdef __USER_LABEL_PREFIX__\n#define GLUE2(a, b) a ## b\n#define GLUE(a, b) GLUE2(a, b)\n#define CSYM(name) GLUE(__USER_LABEL_PREFIX__, name)\n#else\n#define CSYM(name) name\n#endif\n\n/************************************************************************************\n * POWER PC ASM BITS\n ************************************************************************************/\n#if defined( __PPC64__ )\n\n#if defined(_CALL_ELF) && _CALL_ELF == 2\n#define USE_ABI_2\n#define LINKAGE_SZ   32\n#define LR_OFS       16\n#define TOC_OFS      24\n#define GPR_OFS      32\n#define STACK_SZ     (LINKAGE_SZ + 26*8)\n#define OFS_R3_R10   GPR_OFS\n#define OFS_R14_R31  (GPR_OFS+8*8)\n#else\n#define LINKAGE_SZ   48\n#define LR_OFS       16\n#define TOC_OFS      40\n#define GPR_OFS      112\n#define STACK_SZ     (LINKAGE_SZ + 8*8 + 18*8)\n#define OFS_R3_R10   (STACK_SZ+LINKAGE_SZ)\n#define OFS_R14_R31  GPR_OFS\n#endif\n\n    .text\n#if defined( USE_ABI_2 )\n    .abiversion 2\n#endif\n    .globl  _D4core6thread18callWithStackShellFNbMDFNbPvZvZv\n    .align  2\n    .type   _D4core6thread18callWithStackShellFNbMDFNbPvZvZv,@function\n#if defined( USE_ABI_2 )\n    .section .text._D4core6thread18callWithStackShellFNbMDFNbPvZvZv,\"a\",@progbits\n#else\n    .section .opd,\"aw\",@progbits\n#endif\n_D4core6thread18callWithStackShellFNbMDFNbPvZvZv:\n#if !defined( USE_ABI_2 )\n    .align  3\n    .quad .L._D4core6thread18callWithStackShellFNbMDFNbPvZvZv\n    .quad .TOC.@tocbase\n    .quad 0\n#endif\n    .text\n/*\n * Called with:\n * r3: pointer context\n * r4: pointer to function\n */\n.L._D4core6thread18callWithStackShellFNbMDFNbPvZvZv:\n    .cfi_startproc\n    stdu    1, -STACK_SZ(1)\n    mflr    0\n    std     0, LR_OFS(1)\n    .cfi_def_cfa_offset 256\n    .cfi_offset lr, 16\n\n    /* Save r14-r31 in general register save area */\n    std     14, (OFS_R14_R31 + 0 * 8)(1)\n    std     15, (OFS_R14_R31 + 1 * 8)(1)\n    std     16, (OFS_R14_R31 + 2 * 8)(1)\n    std     17, (OFS_R14_R31 + 3 * 8)(1)\n    std     18, (OFS_R14_R31 + 4 * 8)(1)\n    std     19, (OFS_R14_R31 + 5 * 8)(1)\n    std     20, (OFS_R14_R31 + 6 * 8)(1)\n    std     21, (OFS_R14_R31 + 7 * 8)(1)\n    std     22, (OFS_R14_R31 + 8 * 8)(1)\n    std     23, (OFS_R14_R31 + 9 * 8)(1)\n    std     24, (OFS_R14_R31 + 10 * 8)(1)\n    std     25, (OFS_R14_R31 + 11 * 8)(1)\n    std     26, (OFS_R14_R31 + 12 * 8)(1)\n    std     27, (OFS_R14_R31 + 13 * 8)(1)\n    std     28, (OFS_R14_R31 + 14 * 8)(1)\n    std     29, (OFS_R14_R31 + 15 * 8)(1)\n    std     30, (OFS_R14_R31 + 16 * 8)(1)\n    std     31, (OFS_R14_R31 + 17 * 8)(1)\n\n    /* Save r3-r10 in parameter save area of caller */\n    std     3, (OFS_R3_R10 + 0 * 8)(1)\n    std     4, (OFS_R3_R10 + 1 * 8)(1)\n    std     5, (OFS_R3_R10 + 2 * 8)(1)\n    std     6, (OFS_R3_R10 + 3 * 8)(1)\n    std     7, (OFS_R3_R10 + 4 * 8)(1)\n    std     8, (OFS_R3_R10 + 5 * 8)(1)\n    std     9, (OFS_R3_R10 + 6 * 8)(1)\n    std     10, (OFS_R3_R10 + 7 * 8)(1)\n\n    /* Save r2 in TOC save area */\n    std     2, TOC_OFS(1)\n\n    /* Do not save r11, r12 and r13. */\n\n    /* Call delegate:\n     * r3: pointer to context\n     * r4: pointer to stack\n     */\n    mr      5, 4\n    mr      4, 1\n    ld      6, 0(5)\n    ld      11, 16(5)\n    ld      2, 8(5)\n    mtctr   6\n    bctrl\n    nop\n\n    /* Restore r2 from TOC save area */\n    ld      2, TOC_OFS(1)\n\n    /* Restore r3-r10 from local variable space */\n    ld      3, (OFS_R3_R10 + 0 * 8)(1)\n    ld      4, (OFS_R3_R10 + 1 * 8)(1)\n    ld      5, (OFS_R3_R10 + 2 * 8)(1)\n    ld      6, (OFS_R3_R10 + 3 * 8)(1)\n    ld      7, (OFS_R3_R10 + 4 * 8)(1)\n    ld      8, (OFS_R3_R10 + 5 * 8)(1)\n    ld      9, (OFS_R3_R10 + 6 * 8)(1)\n    ld      10, (OFS_R3_R10 + 7 * 8)(1)\n\n    /* Restore r14-r31 from general register save area */\n    ld      14, (OFS_R14_R31 + 0 * 8)(1)\n    ld      15, (OFS_R14_R31 + 1 * 8)(1)\n    ld      16, (OFS_R14_R31 + 2 * 8)(1)\n    ld      17, (OFS_R14_R31 + 3 * 8)(1)\n    ld      18, (OFS_R14_R31 + 4 * 8)(1)\n    ld      19, (OFS_R14_R31 + 5 * 8)(1)\n    ld      20, (OFS_R14_R31 + 6 * 8)(1)\n    ld      21, (OFS_R14_R31 + 7 * 8)(1)\n    ld      22, (OFS_R14_R31 + 8 * 8)(1)\n    ld      23, (OFS_R14_R31 + 9 * 8)(1)\n    ld      24, (OFS_R14_R31 + 10 * 8)(1)\n    ld      25, (OFS_R14_R31 + 11 * 8)(1)\n    ld      26, (OFS_R14_R31 + 12 * 8)(1)\n    ld      27, (OFS_R14_R31 + 13 * 8)(1)\n    ld      28, (OFS_R14_R31 + 14 * 8)(1)\n    ld      29, (OFS_R14_R31 + 15 * 8)(1)\n    ld      30, (OFS_R14_R31 + 16 * 8)(1)\n    ld      31, (OFS_R14_R31 + 17 * 8)(1)\n\n    ld      0, LR_OFS(1)\n    mtlr    0\n    addi    1, 1, STACK_SZ\n    blr\n    .long 0\n    .quad 0\n.Lend:\n    .size _D4core6thread18callWithStackShellFNbMDFNbPvZvZv, .Lend-.L._D4core6thread18callWithStackShellFNbMDFNbPvZvZv\n    .cfi_endproc\n\n#elif defined( __ppc__ ) || defined( __PPC__ ) || defined( __powerpc__ )\n\n\n/**\n * Performs a context switch.\n *\n * r3 - old context pointer\n * r4 - new context pointer\n *\n */\n.text\n.align 2\n.globl _fiber_switchContext\n_fiber_switchContext:\n\n    /* Save linkage area */\n    mflr        0\n    mfcr        5\n    stw     0, 8(1)\n    stw     5, 4(1)\n\n    /* Save GPRs */\n    stw     11, (-1 * 4)(1)\n    stw     13, (-2 * 4)(1)\n    stw     14, (-3 * 4)(1)\n    stw     15, (-4 * 4)(1)\n    stw     16, (-5 * 4)(1)\n    stw     17, (-6 * 4)(1)\n    stw     18, (-7 * 4)(1)\n    stw     19, (-8 * 4)(1)\n    stw     20, (-9 * 4)(1)\n    stw     21, (-10 * 4)(1)\n    stw     22, (-11 * 4)(1)\n    stw     23, (-12 * 4)(1)\n    stw     24, (-13 * 4)(1)\n    stw     25, (-14 * 4)(1)\n    stw     26, (-15 * 4)(1)\n    stw     27, (-16 * 4)(1)\n    stw     28, (-17 * 4)(1)\n    stw     29, (-18 * 4)(1)\n    stw     30, (-19 * 4)(1)\n    stwu    31, (-20 * 4)(1)\n\n    /* We update the stack pointer here, since we do not want the GC to\n       scan the floating point registers. */\n\n    /* Save FPRs */\n    stfd    14, (-1 * 8)(1)\n    stfd    15, (-2 * 8)(1)\n    stfd    16, (-3 * 8)(1)\n    stfd    17, (-4 * 8)(1)\n    stfd    18, (-5 * 8)(1)\n    stfd    19, (-6 * 8)(1)\n    stfd    20, (-7 * 8)(1)\n    stfd    21, (-8 * 8)(1)\n    stfd    22, (-9 * 8)(1)\n    stfd    23, (-10 * 8)(1)\n    stfd    24, (-11 * 8)(1)\n    stfd    25, (-12 * 8)(1)\n    stfd    26, (-13 * 8)(1)\n    stfd    27, (-14 * 8)(1)\n    stfd    28, (-15 * 8)(1)\n    stfd    29, (-16 * 8)(1)\n    stfd    30, (-17 * 8)(1)\n    stfd    31, (-18 * 8)(1)\n\n    /* Update the old stack pointer */\n    stw     1, 0(3)\n\n    /* Set new stack pointer */\n    addi        1, 4, 20 * 4\n\n    /* Restore linkage area */\n    lwz     0, 8(1)\n    lwz     5, 4(1)\n\n    /* Restore GPRs */\n    lwz     11, (-1 * 4)(1)\n    lwz     13, (-2 * 4)(1)\n    lwz     14, (-3 * 4)(1)\n    lwz     15, (-4 * 4)(1)\n    lwz     16, (-5 * 4)(1)\n    lwz     17, (-6 * 4)(1)\n    lwz     18, (-7 * 4)(1)\n    lwz     19, (-8 * 4)(1)\n    lwz     20, (-9 * 4)(1)\n    lwz     21, (-10 * 4)(1)\n    lwz     22, (-11 * 4)(1)\n    lwz     23, (-12 * 4)(1)\n    lwz     24, (-13 * 4)(1)\n    lwz     25, (-14 * 4)(1)\n    lwz     26, (-15 * 4)(1)\n    lwz     27, (-16 * 4)(1)\n    lwz     28, (-17 * 4)(1)\n    lwz     29, (-18 * 4)(1)\n    lwz     30, (-19 * 4)(1)\n    lwz     31, (-20 * 4)(1)\n\n\n    /* Restore FPRs */\n    lfd     14, (-1 * 8)(4)\n    lfd     15, (-2 * 8)(4)\n    lfd     16, (-3 * 8)(4)\n    lfd     17, (-4 * 8)(4)\n    lfd     18, (-5 * 8)(4)\n    lfd     19, (-6 * 8)(4)\n    lfd     20, (-7 * 8)(4)\n    lfd     21, (-8 * 8)(4)\n    lfd     22, (-9 * 8)(4)\n    lfd     23, (-10 * 8)(4)\n    lfd     24, (-11 * 8)(4)\n    lfd     25, (-12 * 8)(4)\n    lfd     26, (-13 * 8)(4)\n    lfd     27, (-14 * 8)(4)\n    lfd     28, (-15 * 8)(4)\n    lfd     29, (-16 * 8)(4)\n    lfd     30, (-17 * 8)(4)\n    lfd     31, (-18 * 8)(4)\n\n    /* Set condition and link register */\n    mtcr        5\n    mtlr        0\n\n    /* Return and switch context */\n    blr\n\n#elif defined(__mips__) && _MIPS_SIM == _ABIO32\n/************************************************************************************\n * MIPS ASM BITS\n ************************************************************************************/\n\n/**\n * Performs a context switch.\n *\n * $a0 - void** - ptr to old stack pointer\n * $a1 - void*  - new stack pointer\n *\n */\n.text\n.globl fiber_switchContext\nfiber_switchContext:\n    addiu $sp, $sp, -(10 * 4)\n\n    // fp regs and return address are stored below the stack\n    // because we don't want the GC to scan them.\n\n#ifdef __mips_hard_float\n#define ALIGN8(val) (val + (-val & 7))\n#define BELOW (ALIGN8(6 * 8 + 4))\n    sdc1 $f20, (0 * 8 - BELOW)($sp)\n    sdc1 $f22, (1 * 8 - BELOW)($sp)\n    sdc1 $f24, (2 * 8 - BELOW)($sp)\n    sdc1 $f26, (3 * 8 - BELOW)($sp)\n    sdc1 $f28, (4 * 8 - BELOW)($sp)\n    sdc1 $f30, (5 * 8 - BELOW)($sp)\n#endif\n    sw $ra, -4($sp)\n\n    sw $s0, (0 * 4)($sp)\n    sw $s1, (1 * 4)($sp)\n    sw $s2, (2 * 4)($sp)\n    sw $s3, (3 * 4)($sp)\n    sw $s4, (4 * 4)($sp)\n    sw $s5, (5 * 4)($sp)\n    sw $s6, (6 * 4)($sp)\n    sw $s7, (7 * 4)($sp)\n    sw $s8, (8 * 4)($sp)\n    sw $gp, (9 * 4)($sp)\n\n    // swap stack pointer\n    sw $sp, 0($a0)\n    move $sp, $a1\n\n#ifdef __mips_hard_float\n    ldc1 $f20, (0 * 8 - BELOW)($sp)\n    ldc1 $f22, (1 * 8 - BELOW)($sp)\n    ldc1 $f24, (2 * 8 - BELOW)($sp)\n    ldc1 $f26, (3 * 8 - BELOW)($sp)\n    ldc1 $f28, (4 * 8 - BELOW)($sp)\n    ldc1 $f30, (5 * 8 - BELOW)($sp)\n#endif\n    lw $ra, -4($sp)\n\n    lw $s0, (0 * 4)($sp)\n    lw $s1, (1 * 4)($sp)\n    lw $s2, (2 * 4)($sp)\n    lw $s3, (3 * 4)($sp)\n    lw $s4, (4 * 4)($sp)\n    lw $s5, (5 * 4)($sp)\n    lw $s6, (6 * 4)($sp)\n    lw $s7, (7 * 4)($sp)\n    lw $s8, (8 * 4)($sp)\n    lw $gp, (9 * 4)($sp)\n\n    addiu $sp, $sp, (10 * 4)\n\n    jr $ra // return\n\n#elif defined(__arm__) && defined(__ARM_EABI__)\n/************************************************************************************\n * ARM ASM BITS\n ************************************************************************************/\n\n/**\n * Performs a context switch.\n *\n * Parameters:\n * r0 - void** - ptr to old stack pointer\n * r1 - void*  - new stack pointer\n *\n * ARM EABI registers:\n * r0-r3   : argument/scratch registers\n * r4-r10  : callee-save registers\n * r11     : frame pointer (or a callee save register if fp isn't needed)\n * r12 =ip : inter procedure register. We can treat it like any other scratch register\n * r13 =sp : stack pointer\n * r14 =lr : link register, it contains the return address (belonging to the function which called us)\n * r15 =pc : program counter\n *\n * For floating point registers:\n * According to AAPCS (version 2.09, section 5.1.2) only the d8-d15 registers need to be preserved\n * across method calls. This applies to all ARM FPU variants, whether they have 16 or 32 double registers\n * NEON support or not, half-float support or not and so on does not matter.\n *\n * Note: If this file was compiled with -mfloat-abi=soft but the code runs on a softfp system with fpu the d8-d15\n * registers won't be saved (we do not know that the system has got a fpu in that case) but the registers might actually\n * be used by other code if it was compiled with -mfloat-abi=softfp.\n *\n * Interworking is only supported on ARMv5+, not on ARM v4T as ARM v4t requires special stubs when changing\n * from thumb to arm mode or the other way round.\n */\n\n.text\n.align  2\n.global fiber_switchContext\n#if defined(__ARM_PCS_VFP) || (defined(__ARM_PCS) && !defined(__SOFTFP__)) // ARM_HardFloat  || ARM_SoftFP\n  .fpu vfp\n#endif\n.type   fiber_switchContext, %function\nfiber_switchContext:\n    .fnstart\n    push {r4-r11}\n    // update the oldp pointer. Link register and floating point registers stored later to prevent the GC from\n    // scanning them.\n    str sp, [r0]\n    // push r0 (or any other register) as well to keep stack 8byte aligned\n    push {r0, lr}\n\n    #if defined(__ARM_PCS_VFP) || (defined(__ARM_PCS) && !defined(__SOFTFP__)) // ARM_HardFloat  || ARM_SoftFP\n      vpush {d8-d15}\n      // now switch over to the new stack. Need to subtract (8*8[d8-d15]+2*4[r0, lr]) to position stack pointer\n      // below the last saved register. Remember we saved the SP before pushing [r0, lr, d8-d15]\n      sub sp, r1, #72\n      vpop {d8-d15}\n    #else\n      sub sp, r1, #8\n    #endif\n\n    // we don't really care about r0, we only used that for padding.\n    // r1 is now what used to be in the link register when saving.\n    pop {r0, r1, r4-r11}\n    /**\n     * The link register for the initial jump to fiber_entryPoint must be zero: The jump actually\n     * looks like a normal method call as we jump to the start of the fiber_entryPoint function.\n     * Although fiber_entryPoint never returns and therefore never accesses lr, it saves lr to the stack.\n     * ARM unwinding will then look at the stack, find lr and think that fiber_entryPoint was called by\n     * the function in lr! So if we have some address in lr the unwinder will try to continue stack unwinding,\n     * although it's already at the stack base and crash.\n     * In all other cases the content of lr doesn't matter.\n     * Note: If we simply loaded into lr above and then moved lr into pc, the initial method call\n     * to fiber_entryPoint would look as if it was called from fiber_entryPoint itself, as the fiber_entryPoint\n     * address is in lr on the initial context switch.\n     */\n    mov lr, #0\n    // return by writing lr into pc\n    mov pc, r1\n    .fnend\n\n#elif defined(__aarch64__)\n/************************************************************************************\n * AArch64 (arm64) ASM BITS\n ************************************************************************************/\n/**\n * preserve/restore AAPCS64 registers\n *   x19-x28 5.1.1 64-bit callee saved\n *   x29 fp, or possibly callee saved reg - depends on platform choice 5.2.3)\n *   x30 lr\n *   d8-d15  5.1.2 says callee only must save bottom 64-bits (the \"d\" regs)\n *\n * saved regs on stack will look like:\n *   19: x19\n *   18: x20\n *   ...\n *   10: x28\n *    9: x29 (fp)  <-- oldp / *newp save stack top\n *    8: x30 (lr)\n *    7: d8\n *   ...\n *    0: d15       <-- sp\n */\n        .text\n        .global CSYM(fiber_switchContext)\n        .p2align  2\n        .type   fiber_switchContext, %function\nCSYM(fiber_switchContext):\n        stp     d15, d14, [sp, #-20*8]!\n        stp     d13, d12, [sp, #2*8]\n        stp     d11, d10, [sp, #4*8]\n        stp     d9, d8,   [sp, #6*8]\n        stp     x30, x29, [sp, #8*8] // lr, fp\n        stp     x28, x27, [sp, #10*8]\n        stp     x26, x25, [sp, #12*8]\n        stp     x24, x23, [sp, #14*8]\n        stp     x22, x21, [sp, #16*8]\n        stp     x20, x19, [sp, #18*8]\n\n        // oldp is set above saved lr (x30) to hide it and float regs\n        // from GC\n        add     x19, sp, #9*8\n        str     x19, [x0]       // *oldp tstack\n        sub     sp, x1, #9*8    // switch to newp sp\n\n        ldp     x20, x19, [sp, #18*8]\n        ldp     x22, x21, [sp, #16*8]\n        ldp     x24, x23, [sp, #14*8]\n        ldp     x26, x25, [sp, #12*8]\n        ldp     x28, x27, [sp, #10*8]\n        ldp     x30, x29, [sp, #8*8] // lr, fp\n        ldp     d9, d8,   [sp, #6*8]\n        ldp     d11, d10, [sp, #4*8]\n        ldp     d13, d12, [sp, #2*8]\n        ldp     d15, d14, [sp], #20*8\n        ret\n\n/**\n * When generating any kind of backtrace (gdb, exception handling) for\n * a function called in a Fiber, we need to tell the unwinder to stop\n * at our Fiber main entry point, i.e. we need to mark the bottom of\n * the call stack. This can be done by clearing the link register lr\n * prior to calling fiber_entryPoint (i.e. in fiber_switchContext) or\n * using a .cfi_undefined directive for the link register in the\n * Fiber entry point. cfi_undefined seems to yield better results in gdb.\n * Unfortunately we can't place it into fiber_entryPoint using inline\n * asm, so we use this trampoline instead.\n */\n        .text\n        .global CSYM(fiber_trampoline)\n        .p2align  2\n        .type   fiber_trampoline, %function\nCSYM(fiber_trampoline):\n        .cfi_startproc\n        .cfi_undefined x30\n        // fiber_entryPoint never returns\n        bl fiber_entryPoint\n        .cfi_endproc\n#elif defined(__MINGW32__)\n/************************************************************************************\n * GDC MinGW ASM BITS\n ************************************************************************************/\n#if defined(__x86_64__)\n.global fiber_switchContext\nfiber_switchContext:\n    pushq %RBP;\n    movq %RSP, %RBP;\n    pushq %RBX;\n    pushq %R12;\n    pushq %R13;\n    pushq %R14;\n    pushq %R15;\n    pushq %GS:0;\n    pushq %GS:8;\n    pushq %GS:16;\n\n    // store oldp\n    movq %RSP, (%RCX);\n    // load newp to begin context switch\n    movq %RDX, %RSP;\n\n    // load saved state from new stack\n    popq %GS:16;\n    popq %GS:8;\n    popq %GS:0;\n    popq %R15;\n    popq %R14;\n    popq %R13;\n    popq %R12;\n    popq %RBX;\n    popq %RBP;\n\n    // 'return' to complete switch\n    popq %RCX;\n    jmp *%RCX;\n#elif defined(_X86_)\n.global _fiber_switchContext\n_fiber_switchContext:\n    // Save current stack state.save current stack state\n    // Standard CDECL prologue.\n    push %EBP;\n    mov  %ESP, %EBP;\n    push %EDI;\n    push %ESI;\n    push %EBX;\n    push %FS:0;\n    push %FS:4;\n    push %FS:8;\n    push %EAX;\n\n    // store oldp again with more accurate address\n    mov 8(%EBP), %EAX;\n    mov %ESP, (%EAX);\n    // load newp to begin context switch\n    mov 12(%EBP), %ESP;\n\n    // load saved state from new stack\n    pop %EAX;\n    pop %FS:8;\n    pop %FS:4;\n    pop %FS:0;\n    pop %EBX;\n    pop %ESI;\n    pop %EDI;\n    pop %EBP;\n\n    // 'return' to complete switch\n    ret;\n#endif\n\n// if POSIX boils down to this (reference http://nadeausoftware.com)\n#elif !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))\n/************************************************************************************\n * i386- and x86_64-apple-darwin POSIX ASM BITS\n ************************************************************************************/\n#if defined(__i386__)\n.text\n.p2align 4\n.globl CSYM(fiber_switchContext)\nCSYM(fiber_switchContext):\n    // save current stack state\n    push %ebp\n    mov  %esp, %ebp\n    push %edi\n    push %esi\n    push %ebx\n    push %eax\n\n    // store oldp again with more accurate address\n    mov 8(%ebp), %eax\n    mov %esp, (%eax)\n    // load newp to begin context switch\n    mov 12(%ebp), %esp\n\n    // load saved state from new stack\n    pop %eax\n    pop %ebx\n    pop %esi\n    pop %edi\n    pop %ebp\n\n    // 'return' to complete switch\n    ret\n\n#elif defined(__x86_64__) && !defined(__ILP32__)\n.text\n.p2align 4\n.globl CSYM(fiber_switchContext)\nCSYM(fiber_switchContext):\n    // Save current stack state.save current stack state\n    push %rbp\n    mov  %rsp, %rbp\n    push %rbx\n    push %r12\n    push %r13\n    push %r14\n    push %r15\n\n    // store oldp again with more accurate address\n    mov %rsp, (%rdi)\n    // load newp to begin context switch\n    mov %rsi, %rsp\n\n    // load saved state from new stack\n    pop %r15\n    pop %r14\n    pop %r13\n    pop %r12\n    pop %rbx\n    pop %rbp\n\n    // 'return' to complete switch\n    ret\n#endif\t// __x86_64__ && !__ILP32__\n\n#endif\t// posix\n"
  },
  {
    "path": "libphobos/libdruntime/core/time.d",
    "content": "//Written in the D programming language\n\n/++\n    Module containing core time functionality, such as $(LREF Duration) (which\n    represents a duration of time) or $(LREF MonoTime) (which represents a\n    timestamp of the system's monotonic clock).\n\n    Various functions take a string (or strings) to represent a unit of time\n    (e.g. $(D convert!(\"days\", \"hours\")(numDays))). The valid strings to use\n    with such functions are \"years\", \"months\", \"weeks\", \"days\", \"hours\",\n    \"minutes\", \"seconds\", \"msecs\" (milliseconds), \"usecs\" (microseconds),\n    \"hnsecs\" (hecto-nanoseconds - i.e. 100 ns) or some subset thereof. There\n    are a few functions that also allow \"nsecs\", but very little actually\n    has precision greater than hnsecs.\n\n    $(BOOKTABLE Cheat Sheet,\n    $(TR $(TH Symbol) $(TH Description))\n    $(LEADINGROW Types)\n    $(TR $(TDNW $(LREF Duration)) $(TD Represents a duration of time of weeks\n    or less (kept internally as hnsecs). (e.g. 22 days or 700 seconds).))\n    $(TR $(TDNW $(LREF TickDuration)) $(TD Represents a duration of time in\n    system clock ticks, using the highest precision that the system provides.))\n    $(TR $(TDNW $(LREF MonoTime)) $(TD Represents a monotonic timestamp in\n    system clock ticks, using the highest precision that the system provides.))\n    $(TR $(TDNW $(LREF FracSec)) $(TD Represents fractional seconds\n    (portions of time smaller than a second).))\n    $(LEADINGROW Functions)\n    $(TR $(TDNW $(LREF convert)) $(TD Generic way of converting between two time\n    units.))\n    $(TR $(TDNW $(LREF dur)) $(TD Allows constructing a $(LREF Duration) from\n    the given time units with the given length.))\n    $(TR $(TDNW $(LREF weeks)$(NBSP)$(LREF days)$(NBSP)$(LREF hours)$(BR)\n    $(LREF minutes)$(NBSP)$(LREF seconds)$(NBSP)$(LREF msecs)$(BR)\n    $(LREF usecs)$(NBSP)$(LREF hnsecs)$(NBSP)$(LREF nsecs))\n    $(TD Convenience aliases for $(LREF dur).))\n    $(TR $(TDNW $(LREF abs)) $(TD Returns the absolute value of a duration.))\n    )\n\n    $(BOOKTABLE Conversions,\n    $(TR $(TH )\n     $(TH From $(LREF Duration))\n     $(TH From $(LREF TickDuration))\n     $(TH From $(LREF FracSec))\n     $(TH From units)\n    )\n    $(TR $(TD $(B To $(LREF Duration)))\n     $(TD -)\n     $(TD $(D tickDuration.)$(REF_SHORT to, std,conv)$(D !Duration()))\n     $(TD -)\n     $(TD $(D dur!\"msecs\"(5)) or $(D 5.msecs()))\n    )\n    $(TR $(TD $(B To $(LREF TickDuration)))\n     $(TD $(D duration.)$(REF_SHORT to, std,conv)$(D !TickDuration()))\n     $(TD -)\n     $(TD -)\n     $(TD $(D TickDuration.from!\"msecs\"(msecs)))\n    )\n    $(TR $(TD $(B To $(LREF FracSec)))\n     $(TD $(D duration.fracSec))\n     $(TD -)\n     $(TD -)\n     $(TD $(D FracSec.from!\"msecs\"(msecs)))\n    )\n    $(TR $(TD $(B To units))\n     $(TD $(D duration.total!\"days\"))\n     $(TD $(D tickDuration.msecs))\n     $(TD $(D fracSec.msecs))\n     $(TD $(D convert!(\"days\", \"msecs\")(msecs)))\n    ))\n\n    Copyright: Copyright 2010 - 2012\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis) and Kato Shoichi\n    Source:    $(DRUNTIMESRC core/_time.d)\n    Macros:\n    NBSP=&nbsp;\n +/\nmodule core.time;\n\nimport core.exception;\nimport core.stdc.time;\nimport core.stdc.stdio;\nimport core.internal.traits : _Unqual = Unqual;\nimport core.internal.string;\n\nversion (Windows)\n{\nimport core.sys.windows.windows;\n}\nelse version (Posix)\n{\nimport core.sys.posix.time;\nimport core.sys.posix.sys.time;\n}\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\n//This probably should be moved somewhere else in druntime which\n//is Darwin-specific.\nversion (Darwin)\n{\n\npublic import core.sys.darwin.mach.kern_return;\n\nextern(C) nothrow @nogc\n{\n\nstruct mach_timebase_info_data_t\n{\n    uint numer;\n    uint denom;\n}\n\nalias mach_timebase_info_data_t* mach_timebase_info_t;\n\nkern_return_t mach_timebase_info(mach_timebase_info_t);\n\nulong mach_absolute_time();\n\n}\n\n}\n\n//To verify that an lvalue isn't required.\nversion (unittest) private T copy(T)(T t)\n{\n    return t;\n}\n\n\n/++\n    What type of clock to use with $(LREF MonoTime) / $(LREF MonoTimeImpl) or\n    $(D std.datetime.Clock.currTime). They default to $(D ClockType.normal),\n    and most programs do not need to ever deal with the others.\n\n    The other $(D ClockType)s are provided so that other clocks provided by the\n    underlying C, system calls can be used with $(LREF MonoTimeImpl) or\n    $(D std.datetime.Clock.currTime) without having to use the C API directly.\n\n    In the case of the monotonic time, $(LREF MonoTimeImpl) is templatized on\n    $(D ClockType), whereas with $(D std.datetime.Clock.currTime), its a runtime\n    argument, since in the case of the monotonic time, the type of the clock\n    affects the resolution of a $(LREF MonoTimeImpl) object, whereas with\n    $(REF SysTime, std,datetime), its resolution is always hecto-nanoseconds\n    regardless of the source of the time.\n\n    $(D ClockType.normal), $(D ClockType.coarse), and $(D ClockType.precise)\n    work with both $(D Clock.currTime) and $(LREF MonoTimeImpl).\n    $(D ClockType.second) only works with $(D Clock.currTime). The others only\n    work with $(LREF MonoTimeImpl).\n  +/\nversion (CoreDdoc) enum ClockType\n{\n    /++\n        Use the normal clock.\n      +/\n    normal = 0,\n\n    /++\n        $(BLUE Linux-Only)\n\n        Uses $(D CLOCK_BOOTTIME).\n      +/\n    bootTime = 1,\n\n    /++\n        Use the coarse clock, not the normal one (e.g. on Linux, that would be\n        $(D CLOCK_REALTIME_COARSE) instead of $(D CLOCK_REALTIME) for\n        $(D clock_gettime) if a function is using the realtime clock). It's\n        generally faster to get the time with the coarse clock than the normal\n        clock, but it's less precise (e.g. 1 msec instead of 1 usec or 1 nsec).\n        Howeover, it $(I is) guaranteed to still have sub-second precision\n        (just not as high as with $(D ClockType.normal)).\n\n        On systems which do not support a coarser clock,\n        $(D MonoTimeImpl!(ClockType.coarse)) will internally use the same clock\n        as $(D Monotime) does, and $(D Clock.currTime!(ClockType.coarse)) will\n        use the same clock as $(D Clock.currTime). This is because the coarse\n        clock is doing the same thing as the normal clock (just at lower\n        precision), whereas some of the other clock types\n        (e.g. $(D ClockType.processCPUTime)) mean something fundamentally\n        different. So, treating those as $(D ClockType.normal) on systems where\n        they weren't natively supported would give misleading results.\n\n        Most programs should not use the coarse clock, exactly because it's\n        less precise, and most programs don't need to get the time often\n        enough to care, but for those rare programs that need to get the time\n        extremely frequently (e.g. hundreds of thousands of times a second) but\n        don't care about high precision, the coarse clock might be appropriate.\n\n        Currently, only Linux and FreeBSD/DragonFlyBSD support a coarser clock, and on other\n        platforms, it's treated as $(D ClockType.normal).\n      +/\n    coarse = 2,\n\n    /++\n        Uses a more precise clock than the normal one (which is already very\n        precise), but it takes longer to get the time. Similarly to\n        $(D ClockType.coarse), if it's used on a system that does not support a\n        more precise clock than the normal one, it's treated as equivalent to\n        $(D ClockType.normal).\n\n        Currently, only FreeBSD/DragonFlyBSD supports a more precise clock, where it uses\n        $(D CLOCK_MONOTONIC_PRECISE) for the monotonic time and\n        $(D CLOCK_REALTIME_PRECISE) for the wall clock time.\n      +/\n    precise = 3,\n\n    /++\n        $(BLUE Linux,Solaris-Only)\n\n        Uses $(D CLOCK_PROCESS_CPUTIME_ID).\n      +/\n    processCPUTime = 4,\n\n    /++\n        $(BLUE Linux-Only)\n\n        Uses $(D CLOCK_MONOTONIC_RAW).\n      +/\n    raw = 5,\n\n    /++\n        Uses a clock that has a precision of one second (contrast to the coarse\n        clock, which has sub-second precision like the normal clock does).\n\n        FreeBSD/DragonFlyBSD are the only systems which specifically have a clock set up for\n        this (it has $(D CLOCK_SECOND) to use with $(D clock_gettime) which\n        takes advantage of an in-kernel cached value), but on other systems, the\n        fastest function available will be used, and the resulting $(D SysTime)\n        will be rounded down to the second if the clock that was used gave the\n        time at a more precise resolution. So, it's guaranteed that the time\n        will be given at a precision of one second and it's likely the case that\n        will be faster than $(D ClockType.normal), since there tend to be\n        several options on a system to get the time at low resolutions, and they\n        tend to be faster than getting the time at high resolutions.\n\n        So, the primary difference between $(D ClockType.coarse) and\n        $(D ClockType.second) is that $(D ClockType.coarse) sacrifices some\n        precision in order to get speed but is still fairly precise, whereas\n        $(D ClockType.second) tries to be as fast as possible at the expense of\n        all sub-second precision.\n      +/\n    second = 6,\n\n    /++\n        $(BLUE Linux,Solaris-Only)\n\n        Uses $(D CLOCK_THREAD_CPUTIME_ID).\n      +/\n    threadCPUTime = 7,\n\n    /++\n        $(BLUE FreeBSD-Only)\n\n        Uses $(D CLOCK_UPTIME).\n      +/\n    uptime = 8,\n\n    /++\n        $(BLUE FreeBSD-Only)\n\n        Uses $(D CLOCK_UPTIME_FAST).\n      +/\n    uptimeCoarse = 9,\n\n    /++\n        $(BLUE FreeBSD-Only)\n\n        Uses $(D CLOCK_UPTIME_PRECISE).\n      +/\n    uptimePrecise = 10,\n}\nelse version (Windows) enum ClockType\n{\n    normal = 0,\n    coarse = 2,\n    precise = 3,\n    second = 6,\n}\nelse version (Darwin) enum ClockType\n{\n    normal = 0,\n    coarse = 2,\n    precise = 3,\n    second = 6,\n}\nelse version (linux) enum ClockType\n{\n    normal = 0,\n    bootTime = 1,\n    coarse = 2,\n    precise = 3,\n    processCPUTime = 4,\n    raw = 5,\n    second = 6,\n    threadCPUTime = 7,\n}\nelse version (FreeBSD) enum ClockType\n{\n    normal = 0,\n    coarse = 2,\n    precise = 3,\n    second = 6,\n    uptime = 8,\n    uptimeCoarse = 9,\n    uptimePrecise = 10,\n}\nelse version (NetBSD) enum ClockType\n{\n    normal = 0,\n    coarse = 2,\n    precise = 3,\n    second = 6,\n}\nelse version (DragonFlyBSD) enum ClockType\n{\n    normal = 0,\n    coarse = 2,\n    precise = 3,\n    second = 6,\n    uptime = 8,\n    uptimeCoarse = 9,\n    uptimePrecise = 10,\n}\nelse version (Solaris) enum ClockType\n{\n    normal = 0,\n    coarse = 2,\n    precise = 3,\n    processCPUTime = 4,\n    second = 6,\n    threadCPUTime = 7,\n}\nelse\n{\n    // It needs to be decided (and implemented in an appropriate version branch\n    // here) which clock types new platforms are going to support. At minimum,\n    // the ones _not_ marked with $(D Blue Foo-Only) should be supported.\n    static assert(0, \"What are the clock types supported by this system?\");\n}\n\n// private, used to translate clock type to proper argument to clock_xxx\n// functions on posix systems\nversion (CoreDdoc)\n    private int _posixClock(ClockType clockType) { return 0; }\nelse\nversion (Posix)\n{\n    private auto _posixClock(ClockType clockType)\n    {\n        version (linux)\n        {\n            import core.sys.linux.time;\n            with(ClockType) final switch (clockType)\n            {\n            case bootTime: return CLOCK_BOOTTIME;\n            case coarse: return CLOCK_MONOTONIC_COARSE;\n            case normal: return CLOCK_MONOTONIC;\n            case precise: return CLOCK_MONOTONIC;\n            case processCPUTime: return CLOCK_PROCESS_CPUTIME_ID;\n            case raw: return CLOCK_MONOTONIC_RAW;\n            case threadCPUTime: return CLOCK_THREAD_CPUTIME_ID;\n            case second: assert(0);\n            }\n        }\n        else version (FreeBSD)\n        {\n            import core.sys.freebsd.time;\n            with(ClockType) final switch (clockType)\n            {\n            case coarse: return CLOCK_MONOTONIC_FAST;\n            case normal: return CLOCK_MONOTONIC;\n            case precise: return CLOCK_MONOTONIC_PRECISE;\n            case uptime: return CLOCK_UPTIME;\n            case uptimeCoarse: return CLOCK_UPTIME_FAST;\n            case uptimePrecise: return CLOCK_UPTIME_PRECISE;\n            case second: assert(0);\n            }\n        }\n        else version (NetBSD)\n        {\n            import core.sys.netbsd.time;\n            with(ClockType) final switch (clockType)\n            {\n            case coarse: return CLOCK_MONOTONIC;\n            case normal: return CLOCK_MONOTONIC;\n            case precise: return CLOCK_MONOTONIC;\n            case second: assert(0);\n            }\n        }\n        else version (DragonFlyBSD)\n        {\n            import core.sys.dragonflybsd.time;\n            with(ClockType) final switch (clockType)\n            {\n            case coarse: return CLOCK_MONOTONIC_FAST;\n            case normal: return CLOCK_MONOTONIC;\n            case precise: return CLOCK_MONOTONIC_PRECISE;\n            case uptime: return CLOCK_UPTIME;\n            case uptimeCoarse: return CLOCK_UPTIME_FAST;\n            case uptimePrecise: return CLOCK_UPTIME_PRECISE;\n            case second: assert(0);\n            }\n        }\n        else version (Solaris)\n        {\n            import core.sys.solaris.time;\n            with(ClockType) final switch (clockType)\n            {\n            case coarse: return CLOCK_MONOTONIC;\n            case normal: return CLOCK_MONOTONIC;\n            case precise: return CLOCK_MONOTONIC;\n            case processCPUTime: return CLOCK_PROCESS_CPUTIME_ID;\n            case threadCPUTime: return CLOCK_THREAD_CPUTIME_ID;\n            case second: assert(0);\n            }\n        }\n        else\n            // It needs to be decided (and implemented in an appropriate\n            // version branch here) which clock types new platforms are going\n            // to support. Also, ClockType's documentation should be updated to\n            // mention it if a new platform uses anything that's not supported\n            // on all platforms..\n            assert(0, \"What are the monotonic clock types supported by this system?\");\n    }\n}\n\nunittest\n{\n    // Make sure that the values are the same across platforms.\n    static if (is(typeof(ClockType.normal)))         static assert(ClockType.normal == 0);\n    static if (is(typeof(ClockType.bootTime)))       static assert(ClockType.bootTime == 1);\n    static if (is(typeof(ClockType.coarse)))         static assert(ClockType.coarse == 2);\n    static if (is(typeof(ClockType.precise)))        static assert(ClockType.precise == 3);\n    static if (is(typeof(ClockType.processCPUTime))) static assert(ClockType.processCPUTime == 4);\n    static if (is(typeof(ClockType.raw)))            static assert(ClockType.raw == 5);\n    static if (is(typeof(ClockType.second)))         static assert(ClockType.second == 6);\n    static if (is(typeof(ClockType.threadCPUTime)))  static assert(ClockType.threadCPUTime == 7);\n    static if (is(typeof(ClockType.uptime)))         static assert(ClockType.uptime == 8);\n    static if (is(typeof(ClockType.uptimeCoarse)))   static assert(ClockType.uptimeCoarse == 9);\n    static if (is(typeof(ClockType.uptimePrecise)))  static assert(ClockType.uptimePrecise == 10);\n}\n\n\n/++\n    Represents a duration of time of weeks or less (kept internally as hnsecs).\n    (e.g. 22 days or 700 seconds).\n\n    It is used when representing a duration of time - such as how long to\n    sleep with $(REF Thread.sleep, core,thread).\n\n    In std.datetime, it is also used as the result of various arithmetic\n    operations on time points.\n\n    Use the $(LREF dur) function or one of its non-generic aliases to create\n    $(D Duration)s.\n\n    It's not possible to create a Duration of months or years, because the\n    variable number of days in a month or year makes it impossible to convert\n    between months or years and smaller units without a specific date. So,\n    nothing uses $(D Duration)s when dealing with months or years. Rather,\n    functions specific to months and years are defined. For instance,\n    $(REF Date, std,datetime) has $(D add!\"years\") and $(D add!\"months\") for adding\n    years and months rather than creating a Duration of years or months and\n    adding that to a $(REF Date, std,datetime). But Duration is used when dealing\n    with weeks or smaller.\n\n    Examples:\n--------------------\nimport std.datetime;\n\nassert(dur!\"days\"(12) == dur!\"hnsecs\"(10_368_000_000_000L));\nassert(dur!\"hnsecs\"(27) == dur!\"hnsecs\"(27));\nassert(std.datetime.Date(2010, 9, 7) + dur!\"days\"(5) ==\n       std.datetime.Date(2010, 9, 12));\n\nassert(days(-12) == dur!\"hnsecs\"(-10_368_000_000_000L));\nassert(hnsecs(-27) == dur!\"hnsecs\"(-27));\nassert(std.datetime.Date(2010, 9, 7) - std.datetime.Date(2010, 10, 3) ==\n       days(-26));\n--------------------\n +/\nstruct Duration\n{\n@safe pure:\n\npublic:\n\n    /++\n        A $(D Duration) of $(D 0). It's shorter than doing something like\n        $(D dur!\"seconds\"(0)) and more explicit than $(D Duration.init).\n      +/\n    static @property nothrow @nogc Duration zero() { return Duration(0); }\n\n    /++\n        Largest $(D Duration) possible.\n      +/\n    static @property nothrow @nogc Duration max() { return Duration(long.max); }\n\n    /++\n        Most negative $(D Duration) possible.\n      +/\n    static @property nothrow @nogc Duration min() { return Duration(long.min); }\n\n    unittest\n    {\n        assert(zero == dur!\"seconds\"(0));\n        assert(Duration.max == Duration(long.max));\n        assert(Duration.min == Duration(long.min));\n        assert(Duration.min < Duration.zero);\n        assert(Duration.zero < Duration.max);\n        assert(Duration.min < Duration.max);\n        assert(Duration.min - dur!\"hnsecs\"(1) == Duration.max);\n        assert(Duration.max + dur!\"hnsecs\"(1) == Duration.min);\n    }\n\n\n    /++\n        Compares this $(D Duration) with the given $(D Duration).\n\n        Returns:\n            $(TABLE\n            $(TR $(TD this &lt; rhs) $(TD &lt; 0))\n            $(TR $(TD this == rhs) $(TD 0))\n            $(TR $(TD this &gt; rhs) $(TD &gt; 0))\n            )\n     +/\n    int opCmp(Duration rhs) const nothrow @nogc\n    {\n        if (_hnsecs < rhs._hnsecs)\n            return -1;\n        if (_hnsecs > rhs._hnsecs)\n            return 1;\n        return 0;\n    }\n\n    unittest\n    {\n        foreach (T; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            foreach (U; _TypeTuple!(Duration, const Duration, immutable Duration))\n            {\n                T t = 42;\n                // workaround https://issues.dlang.org/show_bug.cgi?id=18296\n                version (D_Coverage)\n                    U u = T(t._hnsecs);\n                else\n                    U u = t;\n                assert(t == u);\n                assert(copy(t) == u);\n                assert(t == copy(u));\n            }\n        }\n\n        foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            foreach (E; _TypeTuple!(Duration, const Duration, immutable Duration))\n            {\n                assert((cast(D)Duration(12)).opCmp(cast(E)Duration(12)) == 0);\n                assert((cast(D)Duration(-12)).opCmp(cast(E)Duration(-12)) == 0);\n\n                assert((cast(D)Duration(10)).opCmp(cast(E)Duration(12)) < 0);\n                assert((cast(D)Duration(-12)).opCmp(cast(E)Duration(12)) < 0);\n\n                assert((cast(D)Duration(12)).opCmp(cast(E)Duration(10)) > 0);\n                assert((cast(D)Duration(12)).opCmp(cast(E)Duration(-12)) > 0);\n\n                assert(copy(cast(D)Duration(12)).opCmp(cast(E)Duration(12)) == 0);\n                assert(copy(cast(D)Duration(-12)).opCmp(cast(E)Duration(-12)) == 0);\n\n                assert(copy(cast(D)Duration(10)).opCmp(cast(E)Duration(12)) < 0);\n                assert(copy(cast(D)Duration(-12)).opCmp(cast(E)Duration(12)) < 0);\n\n                assert(copy(cast(D)Duration(12)).opCmp(cast(E)Duration(10)) > 0);\n                assert(copy(cast(D)Duration(12)).opCmp(cast(E)Duration(-12)) > 0);\n\n                assert((cast(D)Duration(12)).opCmp(copy(cast(E)Duration(12))) == 0);\n                assert((cast(D)Duration(-12)).opCmp(copy(cast(E)Duration(-12))) == 0);\n\n                assert((cast(D)Duration(10)).opCmp(copy(cast(E)Duration(12))) < 0);\n                assert((cast(D)Duration(-12)).opCmp(copy(cast(E)Duration(12))) < 0);\n\n                assert((cast(D)Duration(12)).opCmp(copy(cast(E)Duration(10))) > 0);\n                assert((cast(D)Duration(12)).opCmp(copy(cast(E)Duration(-12))) > 0);\n            }\n        }\n    }\n\n\n    /++\n        Adds, subtracts or calculates the modulo of two durations.\n\n        The legal types of arithmetic for $(D Duration) using this operator are\n\n        $(TABLE\n        $(TR $(TD Duration) $(TD +) $(TD Duration) $(TD -->) $(TD Duration))\n        $(TR $(TD Duration) $(TD -) $(TD Duration) $(TD -->) $(TD Duration))\n        $(TR $(TD Duration) $(TD %) $(TD Duration) $(TD -->) $(TD Duration))\n        $(TR $(TD Duration) $(TD +) $(TD TickDuration) $(TD -->) $(TD Duration))\n        $(TR $(TD Duration) $(TD -) $(TD TickDuration) $(TD -->) $(TD Duration))\n        )\n\n        Params:\n            rhs = The duration to add to or subtract from this $(D Duration).\n      +/\n    Duration opBinary(string op, D)(D rhs) const nothrow @nogc\n        if (((op == \"+\" || op == \"-\" || op == \"%\") && is(_Unqual!D == Duration)) ||\n           ((op == \"+\" || op == \"-\") && is(_Unqual!D == TickDuration)))\n    {\n        static if (is(_Unqual!D == Duration))\n            return Duration(mixin(\"_hnsecs \" ~ op ~ \" rhs._hnsecs\"));\n        else if (is(_Unqual!D == TickDuration))\n            return Duration(mixin(\"_hnsecs \" ~ op ~ \" rhs.hnsecs\"));\n    }\n\n    unittest\n    {\n        foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            foreach (E; _TypeTuple!(Duration, const Duration, immutable Duration))\n            {\n                assert((cast(D)Duration(5)) + (cast(E)Duration(7)) == Duration(12));\n                assert((cast(D)Duration(5)) - (cast(E)Duration(7)) == Duration(-2));\n                assert((cast(D)Duration(5)) % (cast(E)Duration(7)) == Duration(5));\n                assert((cast(D)Duration(7)) + (cast(E)Duration(5)) == Duration(12));\n                assert((cast(D)Duration(7)) - (cast(E)Duration(5)) == Duration(2));\n                assert((cast(D)Duration(7)) % (cast(E)Duration(5)) == Duration(2));\n\n                assert((cast(D)Duration(5)) + (cast(E)Duration(-7)) == Duration(-2));\n                assert((cast(D)Duration(5)) - (cast(E)Duration(-7)) == Duration(12));\n                assert((cast(D)Duration(5)) % (cast(E)Duration(-7)) == Duration(5));\n                assert((cast(D)Duration(7)) + (cast(E)Duration(-5)) == Duration(2));\n                assert((cast(D)Duration(7)) - (cast(E)Duration(-5)) == Duration(12));\n                assert((cast(D)Duration(7)) % (cast(E)Duration(-5)) == Duration(2));\n\n                assert((cast(D)Duration(-5)) + (cast(E)Duration(7)) == Duration(2));\n                assert((cast(D)Duration(-5)) - (cast(E)Duration(7)) == Duration(-12));\n                assert((cast(D)Duration(-5)) % (cast(E)Duration(7)) == Duration(-5));\n                assert((cast(D)Duration(-7)) + (cast(E)Duration(5)) == Duration(-2));\n                assert((cast(D)Duration(-7)) - (cast(E)Duration(5)) == Duration(-12));\n                assert((cast(D)Duration(-7)) % (cast(E)Duration(5)) == Duration(-2));\n\n                assert((cast(D)Duration(-5)) + (cast(E)Duration(-7)) == Duration(-12));\n                assert((cast(D)Duration(-5)) - (cast(E)Duration(-7)) == Duration(2));\n                assert((cast(D)Duration(-5)) % (cast(E)Duration(7)) == Duration(-5));\n                assert((cast(D)Duration(-7)) + (cast(E)Duration(-5)) == Duration(-12));\n                assert((cast(D)Duration(-7)) - (cast(E)Duration(-5)) == Duration(-2));\n                assert((cast(D)Duration(-7)) % (cast(E)Duration(5)) == Duration(-2));\n            }\n\n            foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n            {\n                assertApprox((cast(D)Duration(5)) + cast(T)TickDuration.from!\"usecs\"(7), Duration(70), Duration(80));\n                assertApprox((cast(D)Duration(5)) - cast(T)TickDuration.from!\"usecs\"(7), Duration(-70), Duration(-60));\n                assertApprox((cast(D)Duration(7)) + cast(T)TickDuration.from!\"usecs\"(5), Duration(52), Duration(62));\n                assertApprox((cast(D)Duration(7)) - cast(T)TickDuration.from!\"usecs\"(5), Duration(-48), Duration(-38));\n\n                assertApprox((cast(D)Duration(5)) + cast(T)TickDuration.from!\"usecs\"(-7), Duration(-70), Duration(-60));\n                assertApprox((cast(D)Duration(5)) - cast(T)TickDuration.from!\"usecs\"(-7), Duration(70), Duration(80));\n                assertApprox((cast(D)Duration(7)) + cast(T)TickDuration.from!\"usecs\"(-5), Duration(-48), Duration(-38));\n                assertApprox((cast(D)Duration(7)) - cast(T)TickDuration.from!\"usecs\"(-5), Duration(52), Duration(62));\n\n                assertApprox((cast(D)Duration(-5)) + cast(T)TickDuration.from!\"usecs\"(7), Duration(60), Duration(70));\n                assertApprox((cast(D)Duration(-5)) - cast(T)TickDuration.from!\"usecs\"(7), Duration(-80), Duration(-70));\n                assertApprox((cast(D)Duration(-7)) + cast(T)TickDuration.from!\"usecs\"(5), Duration(38), Duration(48));\n                assertApprox((cast(D)Duration(-7)) - cast(T)TickDuration.from!\"usecs\"(5), Duration(-62), Duration(-52));\n\n                assertApprox((cast(D)Duration(-5)) + cast(T)TickDuration.from!\"usecs\"(-7), Duration(-80), Duration(-70));\n                assertApprox((cast(D)Duration(-5)) - cast(T)TickDuration.from!\"usecs\"(-7), Duration(60), Duration(70));\n                assertApprox((cast(D)Duration(-7)) + cast(T)TickDuration.from!\"usecs\"(-5), Duration(-62), Duration(-52));\n                assertApprox((cast(D)Duration(-7)) - cast(T)TickDuration.from!\"usecs\"(-5), Duration(38), Duration(48));\n            }\n        }\n    }\n\n\n    /++\n        Adds or subtracts two durations.\n\n        The legal types of arithmetic for $(D Duration) using this operator are\n\n        $(TABLE\n        $(TR $(TD TickDuration) $(TD +) $(TD Duration) $(TD -->) $(TD Duration))\n        $(TR $(TD TickDuration) $(TD -) $(TD Duration) $(TD -->) $(TD Duration))\n        )\n\n        Params:\n            lhs = The $(D TickDuration) to add to this $(D Duration) or to\n                  subtract this $(D Duration) from.\n      +/\n    Duration opBinaryRight(string op, D)(D lhs) const nothrow @nogc\n        if ((op == \"+\" || op == \"-\") &&\n            is(_Unqual!D == TickDuration))\n    {\n        return Duration(mixin(\"lhs.hnsecs \" ~ op ~ \" _hnsecs\"));\n    }\n\n    unittest\n    {\n        foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n            {\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(7)) + cast(D)Duration(5), Duration(70), Duration(80));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(7)) - cast(D)Duration(5), Duration(60), Duration(70));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(5)) + cast(D)Duration(7), Duration(52), Duration(62));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(5)) - cast(D)Duration(7), Duration(38), Duration(48));\n\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(-7)) + cast(D)Duration(5), Duration(-70), Duration(-60));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(-7)) - cast(D)Duration(5), Duration(-80), Duration(-70));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(-5)) + cast(D)Duration(7), Duration(-48), Duration(-38));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(-5)) - cast(D)Duration(7), Duration(-62), Duration(-52));\n\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(7)) + (cast(D)Duration(-5)), Duration(60), Duration(70));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(7)) - (cast(D)Duration(-5)), Duration(70), Duration(80));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(5)) + (cast(D)Duration(-7)), Duration(38), Duration(48));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(5)) - (cast(D)Duration(-7)), Duration(52), Duration(62));\n\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(-7)) + cast(D)Duration(-5), Duration(-80), Duration(-70));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(-7)) - cast(D)Duration(-5), Duration(-70), Duration(-60));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(-5)) + cast(D)Duration(-7), Duration(-62), Duration(-52));\n                assertApprox((cast(T)TickDuration.from!\"usecs\"(-5)) - cast(D)Duration(-7), Duration(-48), Duration(-38));\n            }\n        }\n    }\n\n\n    /++\n        Adds, subtracts or calculates the modulo of two durations as well as\n        assigning the result to this $(D Duration).\n\n        The legal types of arithmetic for $(D Duration) using this operator are\n\n        $(TABLE\n        $(TR $(TD Duration) $(TD +) $(TD Duration) $(TD -->) $(TD Duration))\n        $(TR $(TD Duration) $(TD -) $(TD Duration) $(TD -->) $(TD Duration))\n        $(TR $(TD Duration) $(TD %) $(TD Duration) $(TD -->) $(TD Duration))\n        $(TR $(TD Duration) $(TD +) $(TD TickDuration) $(TD -->) $(TD Duration))\n        $(TR $(TD Duration) $(TD -) $(TD TickDuration) $(TD -->) $(TD Duration))\n        )\n\n        Params:\n            rhs = The duration to add to or subtract from this $(D Duration).\n      +/\n    ref Duration opOpAssign(string op, D)(in D rhs) nothrow @nogc\n        if (((op == \"+\" || op == \"-\" || op == \"%\") && is(_Unqual!D == Duration)) ||\n           ((op == \"+\" || op == \"-\") && is(_Unqual!D == TickDuration)))\n    {\n        static if (is(_Unqual!D == Duration))\n            mixin(\"_hnsecs \" ~ op ~ \"= rhs._hnsecs;\");\n        else if (is(_Unqual!D == TickDuration))\n            mixin(\"_hnsecs \" ~ op ~ \"= rhs.hnsecs;\");\n        return this;\n    }\n\n    unittest\n    {\n        static void test1(string op, E)(Duration actual, in E rhs, Duration expected, size_t line = __LINE__)\n        {\n            if (mixin(\"actual \" ~ op ~ \" rhs\") != expected)\n                throw new AssertError(\"op failed\", __FILE__, line);\n\n            if (actual != expected)\n                throw new AssertError(\"op assign failed\", __FILE__, line);\n        }\n\n        static void test2(string op, E)\n                         (Duration actual, in E rhs, Duration lower, Duration upper, size_t line = __LINE__)\n        {\n            assertApprox(mixin(\"actual \" ~ op ~ \" rhs\"), lower, upper, \"op failed\", line);\n            assertApprox(actual, lower, upper, \"op assign failed\", line);\n        }\n\n        foreach (E; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            test1!\"+=\"(Duration(5), (cast(E)Duration(7)), Duration(12));\n            test1!\"-=\"(Duration(5), (cast(E)Duration(7)), Duration(-2));\n            test1!\"%=\"(Duration(5), (cast(E)Duration(7)), Duration(5));\n            test1!\"+=\"(Duration(7), (cast(E)Duration(5)), Duration(12));\n            test1!\"-=\"(Duration(7), (cast(E)Duration(5)), Duration(2));\n            test1!\"%=\"(Duration(7), (cast(E)Duration(5)), Duration(2));\n\n            test1!\"+=\"(Duration(5), (cast(E)Duration(-7)), Duration(-2));\n            test1!\"-=\"(Duration(5), (cast(E)Duration(-7)), Duration(12));\n            test1!\"%=\"(Duration(5), (cast(E)Duration(-7)), Duration(5));\n            test1!\"+=\"(Duration(7), (cast(E)Duration(-5)), Duration(2));\n            test1!\"-=\"(Duration(7), (cast(E)Duration(-5)), Duration(12));\n            test1!\"%=\"(Duration(7), (cast(E)Duration(-5)), Duration(2));\n\n            test1!\"+=\"(Duration(-5), (cast(E)Duration(7)), Duration(2));\n            test1!\"-=\"(Duration(-5), (cast(E)Duration(7)), Duration(-12));\n            test1!\"%=\"(Duration(-5), (cast(E)Duration(7)), Duration(-5));\n            test1!\"+=\"(Duration(-7), (cast(E)Duration(5)), Duration(-2));\n            test1!\"-=\"(Duration(-7), (cast(E)Duration(5)), Duration(-12));\n            test1!\"%=\"(Duration(-7), (cast(E)Duration(5)), Duration(-2));\n\n            test1!\"+=\"(Duration(-5), (cast(E)Duration(-7)), Duration(-12));\n            test1!\"-=\"(Duration(-5), (cast(E)Duration(-7)), Duration(2));\n            test1!\"%=\"(Duration(-5), (cast(E)Duration(-7)), Duration(-5));\n            test1!\"+=\"(Duration(-7), (cast(E)Duration(-5)), Duration(-12));\n            test1!\"-=\"(Duration(-7), (cast(E)Duration(-5)), Duration(-2));\n            test1!\"%=\"(Duration(-7), (cast(E)Duration(-5)), Duration(-2));\n        }\n\n        foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n        {\n            test2!\"+=\"(Duration(5), cast(T)TickDuration.from!\"usecs\"(7), Duration(70), Duration(80));\n            test2!\"-=\"(Duration(5), cast(T)TickDuration.from!\"usecs\"(7), Duration(-70), Duration(-60));\n            test2!\"+=\"(Duration(7), cast(T)TickDuration.from!\"usecs\"(5), Duration(52), Duration(62));\n            test2!\"-=\"(Duration(7), cast(T)TickDuration.from!\"usecs\"(5), Duration(-48), Duration(-38));\n\n            test2!\"+=\"(Duration(5), cast(T)TickDuration.from!\"usecs\"(-7), Duration(-70), Duration(-60));\n            test2!\"-=\"(Duration(5), cast(T)TickDuration.from!\"usecs\"(-7), Duration(70), Duration(80));\n            test2!\"+=\"(Duration(7), cast(T)TickDuration.from!\"usecs\"(-5), Duration(-48), Duration(-38));\n            test2!\"-=\"(Duration(7), cast(T)TickDuration.from!\"usecs\"(-5), Duration(52), Duration(62));\n\n            test2!\"+=\"(Duration(-5), cast(T)TickDuration.from!\"usecs\"(7), Duration(60), Duration(70));\n            test2!\"-=\"(Duration(-5), cast(T)TickDuration.from!\"usecs\"(7), Duration(-80), Duration(-70));\n            test2!\"+=\"(Duration(-7), cast(T)TickDuration.from!\"usecs\"(5), Duration(38), Duration(48));\n            test2!\"-=\"(Duration(-7), cast(T)TickDuration.from!\"usecs\"(5), Duration(-62), Duration(-52));\n\n            test2!\"+=\"(Duration(-5), cast(T)TickDuration.from!\"usecs\"(-7), Duration(-80), Duration(-70));\n            test2!\"-=\"(Duration(-5), cast(T)TickDuration.from!\"usecs\"(-7), Duration(60), Duration(70));\n            test2!\"+=\"(Duration(-7), cast(T)TickDuration.from!\"usecs\"(-5), Duration(-62), Duration(-52));\n            test2!\"-=\"(Duration(-7), cast(T)TickDuration.from!\"usecs\"(-5), Duration(38), Duration(48));\n        }\n\n        foreach (D; _TypeTuple!(const Duration, immutable Duration))\n        {\n            foreach (E; _TypeTuple!(Duration, const Duration, immutable Duration,\n                                   TickDuration, const TickDuration, immutable TickDuration))\n            {\n                D lhs = D(120);\n                E rhs = E(120);\n                static assert(!__traits(compiles, lhs += rhs), D.stringof ~ \" \" ~ E.stringof);\n            }\n        }\n    }\n\n\n    /++\n        Multiplies or divides the duration by an integer value.\n\n        The legal types of arithmetic for $(D Duration) using this operator\n        overload are\n\n        $(TABLE\n        $(TR $(TD Duration) $(TD *) $(TD long) $(TD -->) $(TD Duration))\n        $(TR $(TD Duration) $(TD /) $(TD long) $(TD -->) $(TD Duration))\n        )\n\n        Params:\n            value = The value to multiply this $(D Duration) by.\n      +/\n    Duration opBinary(string op)(long value) const nothrow @nogc\n        if (op == \"*\" || op == \"/\")\n    {\n        mixin(\"return Duration(_hnsecs \" ~ op ~ \" value);\");\n    }\n\n    unittest\n    {\n        foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            assert((cast(D)Duration(5)) * 7 == Duration(35));\n            assert((cast(D)Duration(7)) * 5 == Duration(35));\n\n            assert((cast(D)Duration(5)) * -7 == Duration(-35));\n            assert((cast(D)Duration(7)) * -5 == Duration(-35));\n\n            assert((cast(D)Duration(-5)) * 7 == Duration(-35));\n            assert((cast(D)Duration(-7)) * 5 == Duration(-35));\n\n            assert((cast(D)Duration(-5)) * -7 == Duration(35));\n            assert((cast(D)Duration(-7)) * -5 == Duration(35));\n\n            assert((cast(D)Duration(5)) * 0 == Duration(0));\n            assert((cast(D)Duration(-5)) * 0 == Duration(0));\n        }\n    }\n\n    unittest\n    {\n        foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            assert((cast(D)Duration(5)) / 7 == Duration(0));\n            assert((cast(D)Duration(7)) / 5 == Duration(1));\n\n            assert((cast(D)Duration(5)) / -7 == Duration(0));\n            assert((cast(D)Duration(7)) / -5 == Duration(-1));\n\n            assert((cast(D)Duration(-5)) / 7 == Duration(0));\n            assert((cast(D)Duration(-7)) / 5 == Duration(-1));\n\n            assert((cast(D)Duration(-5)) / -7 == Duration(0));\n            assert((cast(D)Duration(-7)) / -5 == Duration(1));\n        }\n    }\n\n\n    /++\n        Multiplies/Divides the duration by an integer value as well as\n        assigning the result to this $(D Duration).\n\n        The legal types of arithmetic for $(D Duration) using this operator\n        overload are\n\n        $(TABLE\n        $(TR $(TD Duration) $(TD *) $(TD long) $(TD -->) $(TD Duration))\n        $(TR $(TD Duration) $(TD /) $(TD long) $(TD -->) $(TD Duration))\n        )\n\n        Params:\n            value = The value to multiply/divide this $(D Duration) by.\n      +/\n    ref Duration opOpAssign(string op)(long value) nothrow @nogc\n        if (op == \"*\" || op == \"/\")\n    {\n        mixin(\"_hnsecs \" ~ op ~ \"= value;\");\n        return this;\n    }\n\n    unittest\n    {\n        static void test(D)(D actual, long value, Duration expected, size_t line = __LINE__)\n        {\n            if ((actual *= value) != expected)\n                throw new AssertError(\"op failed\", __FILE__, line);\n\n            if (actual != expected)\n                throw new AssertError(\"op assign failed\", __FILE__, line);\n        }\n\n        test(Duration(5), 7, Duration(35));\n        test(Duration(7), 5, Duration(35));\n\n        test(Duration(5), -7, Duration(-35));\n        test(Duration(7), -5, Duration(-35));\n\n        test(Duration(-5), 7, Duration(-35));\n        test(Duration(-7), 5, Duration(-35));\n\n        test(Duration(-5), -7, Duration(35));\n        test(Duration(-7), -5, Duration(35));\n\n        test(Duration(5), 0, Duration(0));\n        test(Duration(-5), 0, Duration(0));\n\n        const cdur = Duration(12);\n        immutable idur = Duration(12);\n        static assert(!__traits(compiles, cdur *= 12));\n        static assert(!__traits(compiles, idur *= 12));\n    }\n\n    unittest\n    {\n        static void test(Duration actual, long value, Duration expected, size_t line = __LINE__)\n        {\n            if ((actual /= value) != expected)\n                throw new AssertError(\"op failed\", __FILE__, line);\n\n            if (actual != expected)\n                throw new AssertError(\"op assign failed\", __FILE__, line);\n        }\n\n        test(Duration(5), 7, Duration(0));\n        test(Duration(7), 5, Duration(1));\n\n        test(Duration(5), -7, Duration(0));\n        test(Duration(7), -5, Duration(-1));\n\n        test(Duration(-5), 7, Duration(0));\n        test(Duration(-7), 5, Duration(-1));\n\n        test(Duration(-5), -7, Duration(0));\n        test(Duration(-7), -5, Duration(1));\n\n        const cdur = Duration(12);\n        immutable idur = Duration(12);\n        static assert(!__traits(compiles, cdur /= 12));\n        static assert(!__traits(compiles, idur /= 12));\n    }\n\n\n    /++\n        Divides two durations.\n\n        The legal types of arithmetic for $(D Duration) using this operator are\n\n        $(TABLE\n        $(TR $(TD Duration) $(TD /) $(TD Duration) $(TD -->) $(TD long))\n        )\n\n        Params:\n            rhs = The duration to divide this $(D Duration) by.\n      +/\n    long opBinary(string op)(Duration rhs) const nothrow @nogc\n        if (op == \"/\")\n    {\n        return _hnsecs / rhs._hnsecs;\n    }\n\n    unittest\n    {\n        assert(Duration(5) / Duration(7) == 0);\n        assert(Duration(7) / Duration(5) == 1);\n        assert(Duration(8) / Duration(4) == 2);\n\n        assert(Duration(5) / Duration(-7) == 0);\n        assert(Duration(7) / Duration(-5) == -1);\n        assert(Duration(8) / Duration(-4) == -2);\n\n        assert(Duration(-5) / Duration(7) == 0);\n        assert(Duration(-7) / Duration(5) == -1);\n        assert(Duration(-8) / Duration(4) == -2);\n\n        assert(Duration(-5) / Duration(-7) == 0);\n        assert(Duration(-7) / Duration(-5) == 1);\n        assert(Duration(-8) / Duration(-4) == 2);\n    }\n\n\n    /++\n        Multiplies an integral value and a $(D Duration).\n\n        The legal types of arithmetic for $(D Duration) using this operator\n        overload are\n\n        $(TABLE\n        $(TR $(TD long) $(TD *) $(TD Duration) $(TD -->) $(TD Duration))\n        )\n\n        Params:\n            value = The number of units to multiply this $(D Duration) by.\n      +/\n    Duration opBinaryRight(string op)(long value) const nothrow @nogc\n        if (op == \"*\")\n    {\n        return opBinary!op(value);\n    }\n\n    unittest\n    {\n        foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            assert(5 * cast(D)Duration(7) == Duration(35));\n            assert(7 * cast(D)Duration(5) == Duration(35));\n\n            assert(5 * cast(D)Duration(-7) == Duration(-35));\n            assert(7 * cast(D)Duration(-5) == Duration(-35));\n\n            assert(-5 * cast(D)Duration(7) == Duration(-35));\n            assert(-7 * cast(D)Duration(5) == Duration(-35));\n\n            assert(-5 * cast(D)Duration(-7) == Duration(35));\n            assert(-7 * cast(D)Duration(-5) == Duration(35));\n\n            assert(0 * cast(D)Duration(-5) == Duration(0));\n            assert(0 * cast(D)Duration(5) == Duration(0));\n        }\n    }\n\n\n    /++\n        Returns the negation of this $(D Duration).\n      +/\n    Duration opUnary(string op)() const nothrow @nogc\n        if (op == \"-\")\n    {\n        return Duration(-_hnsecs);\n    }\n\n    unittest\n    {\n        foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            assert(-(cast(D)Duration(7)) == Duration(-7));\n            assert(-(cast(D)Duration(5)) == Duration(-5));\n            assert(-(cast(D)Duration(-7)) == Duration(7));\n            assert(-(cast(D)Duration(-5)) == Duration(5));\n            assert(-(cast(D)Duration(0)) == Duration(0));\n        }\n    }\n\n\n    /++\n        Returns a $(LREF TickDuration) with the same number of hnsecs as this\n        $(D Duration).\n        Note that the conventional way to convert between $(D Duration) and\n        $(D TickDuration) is using $(REF to, std,conv), e.g.:\n        $(D duration.to!TickDuration())\n      +/\n    TickDuration opCast(T)() const nothrow @nogc\n        if (is(_Unqual!T == TickDuration))\n    {\n        return TickDuration.from!\"hnsecs\"(_hnsecs);\n    }\n\n    unittest\n    {\n        foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            foreach (units; _TypeTuple!(\"seconds\", \"msecs\", \"usecs\", \"hnsecs\"))\n            {\n                enum unitsPerSec = convert!(\"seconds\", units)(1);\n\n                if (TickDuration.ticksPerSec >= unitsPerSec)\n                {\n                    foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n                    {\n                        auto t = TickDuration.from!units(1);\n                        assertApprox(cast(T)cast(D)dur!units(1), t - TickDuration(1), t + TickDuration(1), units);\n                        t = TickDuration.from!units(2);\n                        assertApprox(cast(T)cast(D)dur!units(2), t - TickDuration(1), t + TickDuration(1), units);\n                    }\n                }\n                else\n                {\n                    auto t = TickDuration.from!units(1);\n                    assert(t.to!(units, long)() == 0, units);\n                    t = TickDuration.from!units(1_000_000);\n                    assert(t.to!(units, long)() >= 900_000, units);\n                    assert(t.to!(units, long)() <= 1_100_000, units);\n                }\n            }\n        }\n    }\n\n    /++\n        Allow Duration to be used as a boolean.\n        Returns: `true` if this duration is non-zero.\n      +/\n    bool opCast(T : bool)() const nothrow @nogc\n    {\n        return _hnsecs != 0;\n    }\n\n    unittest\n    {\n        auto d = 10.minutes;\n        assert(d);\n        assert(!(d - d));\n        assert(d + d);\n    }\n\n    //Temporary hack until bug http://d.puremagic.com/issues/show_bug.cgi?id=5747 is fixed.\n    Duration opCast(T)() const nothrow @nogc\n        if (is(_Unqual!T == Duration))\n    {\n        return this;\n    }\n\n\n    /++\n        Splits out the Duration into the given units.\n\n        split takes the list of time units to split out as template arguments.\n        The time unit strings must be given in decreasing order. How it returns\n        the values for those units depends on the overload used.\n\n        The overload which accepts function arguments takes integral types in\n        the order that the time unit strings were given, and those integers are\n        passed by $(D ref). split assigns the values for the units to each\n        corresponding integer. Any integral type may be used, but no attempt is\n        made to prevent integer overflow, so don't use small integral types in\n        circumstances where the values for those units aren't likely to fit in\n        an integral type that small.\n\n        The overload with no arguments returns the values for the units in a\n        struct with members whose names are the same as the given time unit\n        strings. The members are all $(D long)s. This overload will also work\n        with no time strings being given, in which case $(I all) of the time\n        units from weeks through hnsecs will be provided (but no nsecs, since it\n        would always be $(D 0)).\n\n        For both overloads, the entire value of the Duration is split among the\n        units (rather than splitting the Duration across all units and then only\n        providing the values for the requested units), so if only one unit is\n        given, the result is equivalent to $(LREF total).\n\n        $(D \"nsecs\") is accepted by split, but $(D \"years\") and $(D \"months\")\n        are not.\n\n        For negative durations, all of the split values will be negative.\n      +/\n    template split(units...)\n        if (allAreAcceptedUnits!(\"weeks\", \"days\", \"hours\", \"minutes\", \"seconds\",\n                                \"msecs\", \"usecs\", \"hnsecs\", \"nsecs\")(units) &&\n           unitsAreInDescendingOrder(units))\n    {\n        /++ Ditto +/\n        void split(Args...)(out Args args) const nothrow @nogc\n            if (units.length != 0 && args.length == units.length && allAreMutableIntegralTypes!Args)\n        {\n            long hnsecs = _hnsecs;\n            foreach (i, unit; units)\n            {\n                static if (unit == \"nsecs\")\n                    args[i] = cast(Args[i])convert!(\"hnsecs\", \"nsecs\")(hnsecs);\n                else\n                    args[i] = cast(Args[i])splitUnitsFromHNSecs!unit(hnsecs);\n            }\n        }\n\n        /++ Ditto +/\n        auto split() const nothrow @nogc\n        {\n            static if (units.length == 0)\n                return split!(\"weeks\", \"days\", \"hours\", \"minutes\", \"seconds\", \"msecs\", \"usecs\", \"hnsecs\")();\n            else\n            {\n                static string genMemberDecls()\n                {\n                    string retval;\n                    foreach (unit; units)\n                    {\n                        retval ~= \"long \";\n                        retval ~= unit;\n                        retval ~= \"; \";\n                    }\n                    return retval;\n                }\n\n                static struct SplitUnits\n                {\n                    mixin(genMemberDecls());\n                }\n\n                static string genSplitCall()\n                {\n                    auto retval = \"split(\";\n                    foreach (i, unit; units)\n                    {\n                        retval ~= \"su.\";\n                        retval ~= unit;\n                        if (i < units.length - 1)\n                            retval ~= \", \";\n                        else\n                            retval ~= \");\";\n                    }\n                    return retval;\n                }\n\n                SplitUnits su = void;\n                mixin(genSplitCall());\n                return su;\n            }\n        }\n\n        /+\n            Whether all of the given arguments are integral types.\n          +/\n        private template allAreMutableIntegralTypes(Args...)\n        {\n            static if (Args.length == 0)\n                enum allAreMutableIntegralTypes = true;\n            else static if (!is(Args[0] == long) &&\n                           !is(Args[0] == int) &&\n                           !is(Args[0] == short) &&\n                           !is(Args[0] == byte) &&\n                           !is(Args[0] == ulong) &&\n                           !is(Args[0] == uint) &&\n                           !is(Args[0] == ushort) &&\n                           !is(Args[0] == ubyte))\n            {\n                enum allAreMutableIntegralTypes = false;\n            }\n            else\n                enum allAreMutableIntegralTypes = allAreMutableIntegralTypes!(Args[1 .. $]);\n        }\n\n        unittest\n        {\n            foreach (T; _TypeTuple!(long, int, short, byte, ulong, uint, ushort, ubyte))\n                static assert(allAreMutableIntegralTypes!T);\n            foreach (T; _TypeTuple!(long, int, short, byte, ulong, uint, ushort, ubyte))\n                static assert(!allAreMutableIntegralTypes!(const T));\n            foreach (T; _TypeTuple!(char, wchar, dchar, float, double, real, string))\n                static assert(!allAreMutableIntegralTypes!T);\n            static assert(allAreMutableIntegralTypes!(long, int, short, byte));\n            static assert(!allAreMutableIntegralTypes!(long, int, short, char, byte));\n            static assert(!allAreMutableIntegralTypes!(long, int*, short));\n        }\n    }\n\n    ///\n    unittest\n    {\n        {\n            auto d = dur!\"days\"(12) + dur!\"minutes\"(7) + dur!\"usecs\"(501223);\n            long days;\n            int seconds;\n            short msecs;\n            d.split!(\"days\", \"seconds\", \"msecs\")(days, seconds, msecs);\n            assert(days == 12);\n            assert(seconds == 7 * 60);\n            assert(msecs == 501);\n\n            auto splitStruct = d.split!(\"days\", \"seconds\", \"msecs\")();\n            assert(splitStruct.days == 12);\n            assert(splitStruct.seconds == 7 * 60);\n            assert(splitStruct.msecs == 501);\n\n            auto fullSplitStruct = d.split();\n            assert(fullSplitStruct.weeks == 1);\n            assert(fullSplitStruct.days == 5);\n            assert(fullSplitStruct.hours == 0);\n            assert(fullSplitStruct.minutes == 7);\n            assert(fullSplitStruct.seconds == 0);\n            assert(fullSplitStruct.msecs == 501);\n            assert(fullSplitStruct.usecs == 223);\n            assert(fullSplitStruct.hnsecs == 0);\n\n            assert(d.split!\"minutes\"().minutes == d.total!\"minutes\");\n        }\n\n        {\n            auto d = dur!\"days\"(12);\n            assert(d.split!\"weeks\"().weeks == 1);\n            assert(d.split!\"days\"().days == 12);\n\n            assert(d.split().weeks == 1);\n            assert(d.split().days == 5);\n        }\n\n        {\n            auto d = dur!\"days\"(7) + dur!\"hnsecs\"(42);\n            assert(d.split!(\"seconds\", \"nsecs\")().nsecs == 4200);\n        }\n\n        {\n            auto d = dur!\"days\"(-7) + dur!\"hours\"(-9);\n            auto result = d.split!(\"days\", \"hours\")();\n            assert(result.days == -7);\n            assert(result.hours == -9);\n        }\n    }\n\n    pure nothrow unittest\n    {\n        foreach (D; _TypeTuple!(const Duration, immutable Duration))\n        {\n            D d = dur!\"weeks\"(3) + dur!\"days\"(5) + dur!\"hours\"(19) + dur!\"minutes\"(7) +\n                  dur!\"seconds\"(2) + dur!\"hnsecs\"(1234567);\n            byte weeks;\n            ubyte days;\n            short hours;\n            ushort minutes;\n            int seconds;\n            uint msecs;\n            long usecs;\n            ulong hnsecs;\n            long nsecs;\n\n            d.split!(\"weeks\", \"days\", \"hours\", \"minutes\", \"seconds\", \"msecs\", \"usecs\", \"hnsecs\", \"nsecs\")\n                    (weeks, days, hours, minutes, seconds, msecs, usecs, hnsecs, nsecs);\n            assert(weeks == 3);\n            assert(days == 5);\n            assert(hours == 19);\n            assert(minutes == 7);\n            assert(seconds == 2);\n            assert(msecs == 123);\n            assert(usecs == 456);\n            assert(hnsecs == 7);\n            assert(nsecs == 0);\n\n            d.split!(\"weeks\", \"days\", \"hours\", \"seconds\", \"usecs\")(weeks, days, hours, seconds, usecs);\n            assert(weeks == 3);\n            assert(days == 5);\n            assert(hours == 19);\n            assert(seconds == 422);\n            assert(usecs == 123456);\n\n            d.split!(\"days\", \"minutes\", \"seconds\", \"nsecs\")(days, minutes, seconds, nsecs);\n            assert(days == 26);\n            assert(minutes == 1147);\n            assert(seconds == 2);\n            assert(nsecs == 123456700);\n\n            d.split!(\"minutes\", \"msecs\", \"usecs\", \"hnsecs\")(minutes, msecs, usecs, hnsecs);\n            assert(minutes == 38587);\n            assert(msecs == 2123);\n            assert(usecs == 456);\n            assert(hnsecs == 7);\n\n            {\n                auto result = d.split!(\"weeks\", \"days\", \"hours\", \"minutes\", \"seconds\",\n                                       \"msecs\", \"usecs\", \"hnsecs\", \"nsecs\");\n                assert(result.weeks == 3);\n                assert(result.days == 5);\n                assert(result.hours == 19);\n                assert(result.minutes == 7);\n                assert(result.seconds == 2);\n                assert(result.msecs == 123);\n                assert(result.usecs == 456);\n                assert(result.hnsecs == 7);\n                assert(result.nsecs == 0);\n            }\n\n            {\n                auto result = d.split!(\"weeks\", \"days\", \"hours\", \"seconds\", \"usecs\");\n                assert(result.weeks == 3);\n                assert(result.days == 5);\n                assert(result.hours == 19);\n                assert(result.seconds == 422);\n                assert(result.usecs == 123456);\n            }\n\n            {\n                auto result = d.split!(\"days\", \"minutes\", \"seconds\", \"nsecs\")();\n                assert(result.days == 26);\n                assert(result.minutes == 1147);\n                assert(result.seconds == 2);\n                assert(result.nsecs == 123456700);\n            }\n\n            {\n                auto result = d.split!(\"minutes\", \"msecs\", \"usecs\", \"hnsecs\")();\n                assert(result.minutes == 38587);\n                assert(result.msecs == 2123);\n                assert(result.usecs == 456);\n                assert(result.hnsecs == 7);\n            }\n\n            {\n                auto result = d.split();\n                assert(result.weeks == 3);\n                assert(result.days == 5);\n                assert(result.hours == 19);\n                assert(result.minutes == 7);\n                assert(result.seconds == 2);\n                assert(result.msecs == 123);\n                assert(result.usecs == 456);\n                assert(result.hnsecs == 7);\n                static assert(!is(typeof(result.nsecs)));\n            }\n\n            static assert(!is(typeof(d.split(\"seconds\", \"hnsecs\")(seconds))));\n            static assert(!is(typeof(d.split(\"hnsecs\", \"seconds\", \"minutes\")(hnsecs, seconds, minutes))));\n            static assert(!is(typeof(d.split(\"hnsecs\", \"seconds\", \"msecs\")(hnsecs, seconds, msecs))));\n            static assert(!is(typeof(d.split(\"seconds\", \"hnecs\", \"msecs\")(seconds, hnsecs, msecs))));\n            static assert(!is(typeof(d.split(\"seconds\", \"msecs\", \"msecs\")(seconds, msecs, msecs))));\n            static assert(!is(typeof(d.split(\"hnsecs\", \"seconds\", \"minutes\")())));\n            static assert(!is(typeof(d.split(\"hnsecs\", \"seconds\", \"msecs\")())));\n            static assert(!is(typeof(d.split(\"seconds\", \"hnecs\", \"msecs\")())));\n            static assert(!is(typeof(d.split(\"seconds\", \"msecs\", \"msecs\")())));\n            alias _TypeTuple!(\"nsecs\", \"hnsecs\", \"usecs\", \"msecs\", \"seconds\",\n                              \"minutes\", \"hours\", \"days\", \"weeks\") timeStrs;\n            foreach (i, str; timeStrs[1 .. $])\n                static assert(!is(typeof(d.split!(timeStrs[i - 1], str)())));\n\n            D nd = -d;\n\n            {\n                auto result = nd.split();\n                assert(result.weeks == -3);\n                assert(result.days == -5);\n                assert(result.hours == -19);\n                assert(result.minutes == -7);\n                assert(result.seconds == -2);\n                assert(result.msecs == -123);\n                assert(result.usecs == -456);\n                assert(result.hnsecs == -7);\n            }\n\n            {\n                auto result = nd.split!(\"weeks\", \"days\", \"hours\", \"minutes\", \"seconds\", \"nsecs\")();\n                assert(result.weeks == -3);\n                assert(result.days == -5);\n                assert(result.hours == -19);\n                assert(result.minutes == -7);\n                assert(result.seconds == -2);\n                assert(result.nsecs == -123456700);\n            }\n        }\n    }\n\n\n    /++\n        Returns the total number of the given units in this $(D Duration).\n        So, unlike $(D split), it does not strip out the larger units.\n      +/\n    @property long total(string units)() const nothrow @nogc\n        if (units == \"weeks\" ||\n           units == \"days\" ||\n           units == \"hours\" ||\n           units == \"minutes\" ||\n           units == \"seconds\" ||\n           units == \"msecs\" ||\n           units == \"usecs\" ||\n           units == \"hnsecs\" ||\n           units == \"nsecs\")\n    {\n        static if (units == \"nsecs\")\n            return convert!(\"hnsecs\", \"nsecs\")(_hnsecs);\n        else\n            return getUnitsFromHNSecs!units(_hnsecs);\n    }\n\n    ///\n    unittest\n    {\n        assert(dur!\"weeks\"(12).total!\"weeks\" == 12);\n        assert(dur!\"weeks\"(12).total!\"days\" == 84);\n\n        assert(dur!\"days\"(13).total!\"weeks\" == 1);\n        assert(dur!\"days\"(13).total!\"days\" == 13);\n\n        assert(dur!\"hours\"(49).total!\"days\" == 2);\n        assert(dur!\"hours\"(49).total!\"hours\" == 49);\n\n        assert(dur!\"nsecs\"(2007).total!\"hnsecs\" == 20);\n        assert(dur!\"nsecs\"(2007).total!\"nsecs\" == 2000);\n    }\n\n    unittest\n    {\n        foreach (D; _TypeTuple!(const Duration, immutable Duration))\n        {\n            assert((cast(D)dur!\"weeks\"(12)).total!\"weeks\" == 12);\n            assert((cast(D)dur!\"weeks\"(12)).total!\"days\" == 84);\n\n            assert((cast(D)dur!\"days\"(13)).total!\"weeks\" == 1);\n            assert((cast(D)dur!\"days\"(13)).total!\"days\" == 13);\n\n            assert((cast(D)dur!\"hours\"(49)).total!\"days\" == 2);\n            assert((cast(D)dur!\"hours\"(49)).total!\"hours\" == 49);\n\n            assert((cast(D)dur!\"nsecs\"(2007)).total!\"hnsecs\" == 20);\n            assert((cast(D)dur!\"nsecs\"(2007)).total!\"nsecs\" == 2000);\n        }\n    }\n\n\n    /++\n        Converts this `Duration` to a `string`.\n\n        The string is meant to be human readable, not machine parseable (e.g.\n        whether there is an `'s'` on the end of the unit name usually depends on\n        whether it's plural or not, and empty units are not included unless the\n        Duration is `zero`). Any code needing a specific string format should\n        use `total` or `split` to get the units needed to create the desired\n        string format and create the string itself.\n\n        The format returned by toString may or may not change in the future.\n      +/\n    string toString() const nothrow pure @safe\n    {\n        static void appListSep(ref string res, uint pos, bool last)\n        {\n            if (pos == 0)\n                return;\n            if (!last)\n                res ~= \", \";\n            else\n                res ~= pos == 1 ? \" and \" : \", and \";\n        }\n\n        static void appUnitVal(string units)(ref string res, long val)\n        {\n            immutable plural = val != 1;\n            string unit;\n            static if (units == \"seconds\")\n                unit = plural ? \"secs\" : \"sec\";\n            else static if (units == \"msecs\")\n                unit = \"ms\";\n            else static if (units == \"usecs\")\n                unit = \"μs\";\n            else\n                unit = plural ? units : units[0 .. $-1];\n            res ~= signedToTempString(val, 10);\n            res ~= \" \";\n            res ~= unit;\n        }\n\n        if (_hnsecs == 0)\n            return \"0 hnsecs\";\n\n        template TT(T...) { alias T TT; }\n        alias units = TT!(\"weeks\", \"days\", \"hours\", \"minutes\", \"seconds\", \"msecs\", \"usecs\");\n\n        long hnsecs = _hnsecs; string res; uint pos;\n        foreach (unit; units)\n        {\n            if (auto val = splitUnitsFromHNSecs!unit(hnsecs))\n            {\n                appListSep(res, pos++, hnsecs == 0);\n                appUnitVal!unit(res, val);\n            }\n            if (hnsecs == 0)\n                break;\n        }\n        if (hnsecs != 0)\n        {\n            appListSep(res, pos++, true);\n            appUnitVal!\"hnsecs\"(res, hnsecs);\n        }\n        return res;\n    }\n\n    ///\n    unittest\n    {\n        assert(Duration.zero.toString() == \"0 hnsecs\");\n        assert(weeks(5).toString() == \"5 weeks\");\n        assert(days(2).toString() == \"2 days\");\n        assert(hours(1).toString() == \"1 hour\");\n        assert(minutes(19).toString() == \"19 minutes\");\n        assert(seconds(42).toString() == \"42 secs\");\n        assert(msecs(42).toString() == \"42 ms\");\n        assert(usecs(27).toString() == \"27 μs\");\n        assert(hnsecs(5).toString() == \"5 hnsecs\");\n\n        assert(seconds(121).toString() == \"2 minutes and 1 sec\");\n        assert((minutes(5) + seconds(3) + usecs(4)).toString() ==\n               \"5 minutes, 3 secs, and 4 μs\");\n\n        assert(seconds(-42).toString() == \"-42 secs\");\n        assert(usecs(-5239492).toString() == \"-5 secs, -239 ms, and -492 μs\");\n    }\n\n    unittest\n    {\n        foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            assert((cast(D)Duration(0)).toString() == \"0 hnsecs\");\n            assert((cast(D)Duration(1)).toString() == \"1 hnsec\");\n            assert((cast(D)Duration(7)).toString() == \"7 hnsecs\");\n            assert((cast(D)Duration(10)).toString() == \"1 μs\");\n            assert((cast(D)Duration(20)).toString() == \"2 μs\");\n            assert((cast(D)Duration(10_000)).toString() == \"1 ms\");\n            assert((cast(D)Duration(20_000)).toString() == \"2 ms\");\n            assert((cast(D)Duration(10_000_000)).toString() == \"1 sec\");\n            assert((cast(D)Duration(20_000_000)).toString() == \"2 secs\");\n            assert((cast(D)Duration(600_000_000)).toString() == \"1 minute\");\n            assert((cast(D)Duration(1_200_000_000)).toString() == \"2 minutes\");\n            assert((cast(D)Duration(36_000_000_000)).toString() == \"1 hour\");\n            assert((cast(D)Duration(72_000_000_000)).toString() == \"2 hours\");\n            assert((cast(D)Duration(864_000_000_000)).toString() == \"1 day\");\n            assert((cast(D)Duration(1_728_000_000_000)).toString() == \"2 days\");\n            assert((cast(D)Duration(6_048_000_000_000)).toString() == \"1 week\");\n            assert((cast(D)Duration(12_096_000_000_000)).toString() == \"2 weeks\");\n\n            assert((cast(D)Duration(12)).toString() == \"1 μs and 2 hnsecs\");\n            assert((cast(D)Duration(120_795)).toString() == \"12 ms, 79 μs, and 5 hnsecs\");\n            assert((cast(D)Duration(12_096_020_900_003)).toString() == \"2 weeks, 2 secs, 90 ms, and 3 hnsecs\");\n\n            assert((cast(D)Duration(-1)).toString() == \"-1 hnsecs\");\n            assert((cast(D)Duration(-7)).toString() == \"-7 hnsecs\");\n            assert((cast(D)Duration(-10)).toString() == \"-1 μs\");\n            assert((cast(D)Duration(-20)).toString() == \"-2 μs\");\n            assert((cast(D)Duration(-10_000)).toString() == \"-1 ms\");\n            assert((cast(D)Duration(-20_000)).toString() == \"-2 ms\");\n            assert((cast(D)Duration(-10_000_000)).toString() == \"-1 secs\");\n            assert((cast(D)Duration(-20_000_000)).toString() == \"-2 secs\");\n            assert((cast(D)Duration(-600_000_000)).toString() == \"-1 minutes\");\n            assert((cast(D)Duration(-1_200_000_000)).toString() == \"-2 minutes\");\n            assert((cast(D)Duration(-36_000_000_000)).toString() == \"-1 hours\");\n            assert((cast(D)Duration(-72_000_000_000)).toString() == \"-2 hours\");\n            assert((cast(D)Duration(-864_000_000_000)).toString() == \"-1 days\");\n            assert((cast(D)Duration(-1_728_000_000_000)).toString() == \"-2 days\");\n            assert((cast(D)Duration(-6_048_000_000_000)).toString() == \"-1 weeks\");\n            assert((cast(D)Duration(-12_096_000_000_000)).toString() == \"-2 weeks\");\n\n            assert((cast(D)Duration(-12)).toString() == \"-1 μs and -2 hnsecs\");\n            assert((cast(D)Duration(-120_795)).toString() == \"-12 ms, -79 μs, and -5 hnsecs\");\n            assert((cast(D)Duration(-12_096_020_900_003)).toString() == \"-2 weeks, -2 secs, -90 ms, and -3 hnsecs\");\n        }\n    }\n\n\n    /++\n        Returns whether this $(D Duration) is negative.\n      +/\n    @property bool isNegative() const nothrow @nogc\n    {\n        return _hnsecs < 0;\n    }\n\n    unittest\n    {\n        foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            assert(!(cast(D)Duration(100)).isNegative);\n            assert(!(cast(D)Duration(1)).isNegative);\n            assert(!(cast(D)Duration(0)).isNegative);\n            assert((cast(D)Duration(-1)).isNegative);\n            assert((cast(D)Duration(-100)).isNegative);\n        }\n    }\n\n\nprivate:\n\n    /+\n        Params:\n            hnsecs = The total number of hecto-nanoseconds in this $(D Duration).\n      +/\n    this(long hnsecs) nothrow @nogc\n    {\n        _hnsecs = hnsecs;\n    }\n\n\n    long _hnsecs;\n}\n\n///\nunittest\n{\n    import core.time;\n\n    // using the dur template\n    auto numDays = dur!\"days\"(12);\n\n    // using the days function\n    numDays = days(12);\n\n    // alternatively using UFCS syntax\n    numDays = 12.days;\n\n    auto myTime = 100.msecs + 20_000.usecs + 30_000.hnsecs;\n    assert(myTime == 123.msecs);\n}\n\n/++\n    Converts a $(D TickDuration) to the given units as either an integral\n    value or a floating point value.\n\n    Params:\n        units = The units to convert to. Accepts $(D \"seconds\") and smaller\n                only.\n        T     = The type to convert to (either an integral type or a\n                floating point type).\n\n        td    = The TickDuration to convert\n  +/\nT to(string units, T, D)(D td) @safe pure nothrow @nogc\n    if (is(_Unqual!D == TickDuration) &&\n       (units == \"seconds\" ||\n        units == \"msecs\" ||\n        units == \"usecs\" ||\n        units == \"hnsecs\" ||\n        units == \"nsecs\"))\n{\n    static if (__traits(isIntegral, T) && T.sizeof >= 4)\n    {\n        enum unitsPerSec = convert!(\"seconds\", units)(1);\n\n        return cast(T) (td.length / (TickDuration.ticksPerSec / cast(real) unitsPerSec));\n    }\n    else static if (__traits(isFloating, T))\n    {\n        static if (units == \"seconds\")\n            return td.length / cast(T)TickDuration.ticksPerSec;\n        else\n        {\n            enum unitsPerSec = convert!(\"seconds\", units)(1);\n\n            return cast(T) (td.length /\n                (TickDuration.ticksPerSec / cast(real) unitsPerSec));\n        }\n    }\n    else\n        static assert(0, \"Incorrect template constraint.\");\n}\n\n///\nunittest\n{\n    auto t = TickDuration.from!\"seconds\"(1000);\n\n    long tl = to!(\"seconds\",long)(t);\n    assert(tl == 1000);\n\n    double td = to!(\"seconds\",double)(t);\n    assert(_abs(td - 1000) < 0.001);\n}\n\nunittest\n{\n    void testFun(string U)() {\n        auto t1v = 1000;\n        auto t2v = 333;\n\n        auto t1 = TickDuration.from!U(t1v);\n        auto t2 = TickDuration.from!U(t2v);\n\n        auto _str(F)(F val)\n        {\n            static if (is(F == int) || is(F == long))\n                return signedToTempString(val, 10);\n            else\n                return unsignedToTempString(val, 10);\n        }\n\n        foreach (F; _TypeTuple!(int,uint,long,ulong,float,double,real))\n        {\n            F t1f = to!(U,F)(t1);\n            F t2f = to!(U,F)(t2);\n            auto t12d = t1 / t2v;\n            auto t12m = t1 - t2;\n            F t3f = to!(U,F)(t12d);\n            F t4f = to!(U,F)(t12m);\n\n\n            static if (is(F == float) || is(F == double) || is(F == real))\n            {\n                assert((t1f - cast(F)t1v) <= 3.0,\n                    F.stringof ~ \" \" ~ U ~ \" \" ~ doubleToString(t1f) ~ \" \" ~\n                    doubleToString(cast(F)t1v)\n                );\n                assert((t2f - cast(F)t2v) <= 3.0,\n                    F.stringof ~ \" \" ~ U ~ \" \" ~ doubleToString(t2f) ~ \" \" ~\n                    doubleToString(cast(F)t2v)\n                );\n                assert(t3f - (cast(F)t1v) / (cast(F)t2v) <= 3.0,\n                    F.stringof ~ \" \" ~ U ~ \" \" ~ doubleToString(t3f) ~ \" \" ~\n                    doubleToString((cast(F)t1v)/(cast(F)t2v))\n                );\n                assert(t4f - (cast(F)(t1v - t2v)) <= 3.0,\n                    F.stringof ~ \" \" ~ U ~ \" \" ~ doubleToString(t4f) ~ \" \" ~\n                    doubleToString(cast(F)(t1v - t2v))\n                );\n            }\n            else\n            {\n                // even though this should be exact math it is not as internal\n                // in \"to\" floating point is used\n                assert(_abs(t1f) - _abs(cast(F)t1v) <= 3,\n                    F.stringof ~ \" \" ~ U ~ \" \" ~ _str(t1f) ~ \" \" ~\n                    _str(cast(F)t1v)\n                );\n                assert(_abs(t2f) - _abs(cast(F)t2v) <= 3,\n                    F.stringof ~ \" \" ~ U ~ \" \" ~ _str(t2f) ~ \" \" ~\n                    _str(cast(F)t2v)\n                );\n                assert(_abs(t3f) - _abs((cast(F)t1v) / (cast(F)t2v)) <= 3,\n                    F.stringof ~ \" \" ~ U ~ \" \" ~ _str(t3f) ~ \" \" ~\n                    _str((cast(F)t1v) / (cast(F)t2v))\n                );\n                assert(_abs(t4f) - _abs((cast(F)t1v) - (cast(F)t2v)) <= 3,\n                    F.stringof ~ \" \" ~ U ~ \" \" ~ _str(t4f) ~ \" \" ~\n                    _str((cast(F)t1v) - (cast(F)t2v))\n                );\n            }\n        }\n    }\n\n    testFun!\"seconds\"();\n    testFun!\"msecs\"();\n    testFun!\"usecs\"();\n}\n\n/++\n    These allow you to construct a $(D Duration) from the given time units\n    with the given length.\n\n    You can either use the generic function $(D dur) and give it the units as\n    a $(D string) or use the named aliases.\n\n    The possible values for units are $(D \"weeks\"), $(D \"days\"), $(D \"hours\"),\n    $(D \"minutes\"), $(D \"seconds\"), $(D \"msecs\") (milliseconds), $(D \"usecs\"),\n    (microseconds), $(D \"hnsecs\") (hecto-nanoseconds, i.e. 100 ns), and\n    $(D \"nsecs\").\n\n    Params:\n        units  = The time units of the $(D Duration) (e.g. $(D \"days\")).\n        length = The number of units in the $(D Duration).\n  +/\nDuration dur(string units)(long length) @safe pure nothrow @nogc\n    if (units == \"weeks\" ||\n       units == \"days\" ||\n       units == \"hours\" ||\n       units == \"minutes\" ||\n       units == \"seconds\" ||\n       units == \"msecs\" ||\n       units == \"usecs\" ||\n       units == \"hnsecs\" ||\n       units == \"nsecs\")\n{\n    return Duration(convert!(units, \"hnsecs\")(length));\n}\n\nalias weeks   = dur!\"weeks\";   /// Ditto\nalias days    = dur!\"days\";    /// Ditto\nalias hours   = dur!\"hours\";   /// Ditto\nalias minutes = dur!\"minutes\"; /// Ditto\nalias seconds = dur!\"seconds\"; /// Ditto\nalias msecs   = dur!\"msecs\";   /// Ditto\nalias usecs   = dur!\"usecs\";   /// Ditto\nalias hnsecs  = dur!\"hnsecs\";  /// Ditto\nalias nsecs   = dur!\"nsecs\";   /// Ditto\n\n///\nunittest\n{\n    // Generic\n    assert(dur!\"weeks\"(142).total!\"weeks\" == 142);\n    assert(dur!\"days\"(142).total!\"days\" == 142);\n    assert(dur!\"hours\"(142).total!\"hours\" == 142);\n    assert(dur!\"minutes\"(142).total!\"minutes\" == 142);\n    assert(dur!\"seconds\"(142).total!\"seconds\" == 142);\n    assert(dur!\"msecs\"(142).total!\"msecs\" == 142);\n    assert(dur!\"usecs\"(142).total!\"usecs\" == 142);\n    assert(dur!\"hnsecs\"(142).total!\"hnsecs\" == 142);\n    assert(dur!\"nsecs\"(142).total!\"nsecs\" == 100);\n\n    // Non-generic\n    assert(weeks(142).total!\"weeks\" == 142);\n    assert(days(142).total!\"days\" == 142);\n    assert(hours(142).total!\"hours\" == 142);\n    assert(minutes(142).total!\"minutes\" == 142);\n    assert(seconds(142).total!\"seconds\" == 142);\n    assert(msecs(142).total!\"msecs\" == 142);\n    assert(usecs(142).total!\"usecs\" == 142);\n    assert(hnsecs(142).total!\"hnsecs\" == 142);\n    assert(nsecs(142).total!\"nsecs\" == 100);\n}\n\nunittest\n{\n    foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n    {\n        assert(dur!\"weeks\"(7).total!\"weeks\" == 7);\n        assert(dur!\"days\"(7).total!\"days\" == 7);\n        assert(dur!\"hours\"(7).total!\"hours\" == 7);\n        assert(dur!\"minutes\"(7).total!\"minutes\" == 7);\n        assert(dur!\"seconds\"(7).total!\"seconds\" == 7);\n        assert(dur!\"msecs\"(7).total!\"msecs\" == 7);\n        assert(dur!\"usecs\"(7).total!\"usecs\" == 7);\n        assert(dur!\"hnsecs\"(7).total!\"hnsecs\" == 7);\n        assert(dur!\"nsecs\"(7).total!\"nsecs\" == 0);\n\n        assert(dur!\"weeks\"(1007) == weeks(1007));\n        assert(dur!\"days\"(1007) == days(1007));\n        assert(dur!\"hours\"(1007) == hours(1007));\n        assert(dur!\"minutes\"(1007) == minutes(1007));\n        assert(dur!\"seconds\"(1007) == seconds(1007));\n        assert(dur!\"msecs\"(1007) == msecs(1007));\n        assert(dur!\"usecs\"(1007) == usecs(1007));\n        assert(dur!\"hnsecs\"(1007) == hnsecs(1007));\n        assert(dur!\"nsecs\"(10) == nsecs(10));\n    }\n}\n\n// used in MonoTimeImpl\nprivate string _clockTypeName(ClockType clockType)\n{\n    final switch (clockType)\n    {\n        foreach (name; __traits(allMembers, ClockType))\n        {\n        case __traits(getMember, ClockType, name):\n            return name;\n        }\n    }\n    assert(0);\n}\n\n// used in MonoTimeImpl\nprivate size_t _clockTypeIdx(ClockType clockType)\n{\n    final switch (clockType)\n    {\n        foreach (i, name; __traits(allMembers, ClockType))\n        {\n        case __traits(getMember, ClockType, name):\n            return i;\n        }\n    }\n    assert(0);\n}\n\n\n/++\n    alias for $(D MonoTimeImpl) instantiated with $(D ClockType.normal). This is\n    what most programs should use. It's also what much of $(D MonoTimeImpl) uses\n    in its documentation (particularly in the examples), because that's what's\n    going to be used in most code.\n  +/\nalias MonoTime = MonoTimeImpl!(ClockType.normal);\n\n/++\n    Represents a timestamp of the system's monotonic clock.\n\n    A monotonic clock is one which always goes forward and never moves\n    backwards, unlike the system's wall clock time (as represented by\n    $(REF SysTime, std,datetime)). The system's wall clock time can be adjusted\n    by the user or by the system itself via services such as NTP, so it is\n    unreliable to use the wall clock time for timing. Timers which use the wall\n    clock time could easily end up never going off due to changes made to the\n    wall clock time or otherwise waiting for a different period of time than\n    that specified by the programmer. However, because the monotonic clock\n    always increases at a fixed rate and is not affected by adjustments to the\n    wall clock time, it is ideal for use with timers or anything which requires\n    high precision timing.\n\n    So, MonoTime should be used for anything involving timers and timing,\n    whereas $(REF SysTime, std,datetime) should be used when the wall clock time\n    is required.\n\n    The monotonic clock has no relation to wall clock time. Rather, it holds\n    its time as the number of ticks of the clock which have occurred since the\n    clock started (typically when the system booted up). So, to determine how\n    much time has passed between two points in time, one monotonic time is\n    subtracted from the other to determine the number of ticks which occurred\n    between the two points of time, and those ticks are divided by the number of\n    ticks that occur every second (as represented by MonoTime.ticksPerSecond)\n    to get a meaningful duration of time. Normally, MonoTime does these\n    calculations for the programmer, but the $(D ticks) and $(D ticksPerSecond)\n    properties are provided for those who require direct access to the system\n    ticks. The normal way that MonoTime would be used is\n\n--------------------\n    MonoTime before = MonoTime.currTime;\n    // do stuff...\n    MonoTime after = MonoTime.currTime;\n    Duration timeElapsed = after - before;\n--------------------\n\n    $(LREF MonoTime) is an alias to $(D MonoTimeImpl!(ClockType.normal)) and is\n    what most programs should use for the monotonic clock, so that's what is\n    used in most of $(D MonoTimeImpl)'s documentation. But $(D MonoTimeImpl)\n    can be instantiated with other clock types for those rare programs that need\n    it.\n\n    See_Also:\n        $(LREF ClockType)\n  +/\nstruct MonoTimeImpl(ClockType clockType)\n{\n    private enum _clockIdx = _clockTypeIdx(clockType);\n    private enum _clockName = _clockTypeName(clockType);\n\n@safe:\n\n    version (Windows)\n    {\n        static if (clockType != ClockType.coarse &&\n                  clockType != ClockType.normal &&\n                  clockType != ClockType.precise)\n        {\n            static assert(0, \"ClockType.\" ~ _clockName ~\n                             \" is not supported by MonoTimeImpl on this system.\");\n        }\n    }\n    else version (Darwin)\n    {\n        static if (clockType != ClockType.coarse &&\n                  clockType != ClockType.normal &&\n                  clockType != ClockType.precise)\n        {\n            static assert(0, \"ClockType.\" ~ _clockName ~\n                             \" is not supported by MonoTimeImpl on this system.\");\n        }\n    }\n    else version (Posix)\n    {\n        enum clockArg = _posixClock(clockType);\n    }\n    else\n        static assert(0, \"Unsupported platform\");\n\n    // POD value, test mutable/const/immutable conversion\n    unittest\n    {\n        MonoTimeImpl m;\n        const MonoTimeImpl cm = m;\n        immutable MonoTimeImpl im = m;\n        m = cm;\n        m = im;\n    }\n\n    /++\n        The current time of the system's monotonic clock. This has no relation\n        to the wall clock time, as the wall clock time can be adjusted (e.g.\n        by NTP), whereas the monotonic clock always moves forward. The source\n        of the monotonic time is system-specific.\n\n        On Windows, $(D QueryPerformanceCounter) is used. On Mac OS X,\n        $(D mach_absolute_time) is used, while on other POSIX systems,\n        $(D clock_gettime) is used.\n\n        $(RED Warning): On some systems, the monotonic clock may stop counting\n                        when the computer goes to sleep or hibernates. So, the\n                        monotonic clock may indicate less time than has actually\n                        passed if that occurs. This is known to happen on\n                        Mac OS X. It has not been tested whether it occurs on\n                        either Windows or Linux.\n      +/\n    static @property MonoTimeImpl currTime() @trusted nothrow @nogc\n    {\n        if (ticksPerSecond == 0)\n        {\n            import core.internal.abort : abort;\n            abort(\"MonoTimeImpl!(ClockType.\" ~ _clockName ~\n                      \") failed to get the frequency of the system's monotonic clock.\");\n        }\n\n        version (Windows)\n        {\n            long ticks = void;\n            QueryPerformanceCounter(&ticks);\n            return MonoTimeImpl(ticks);\n        }\n        else version (Darwin)\n            return MonoTimeImpl(mach_absolute_time());\n        else version (Posix)\n        {\n            timespec ts = void;\n            immutable error = clock_gettime(clockArg, &ts);\n            // clockArg is supported and if tv_sec is long or larger\n            // overflow won't happen before 292 billion years A.D.\n            static if (ts.tv_sec.max < long.max)\n            {\n                if (error)\n                {\n                    import core.internal.abort : abort;\n                    abort(\"Call to clock_gettime failed.\");\n                }\n            }\n            return MonoTimeImpl(convClockFreq(ts.tv_sec * 1_000_000_000L + ts.tv_nsec,\n                                              1_000_000_000L,\n                                              ticksPerSecond));\n        }\n    }\n\n\n    static @property pure nothrow @nogc\n    {\n    /++\n        A $(D MonoTime) of $(D 0) ticks. It's provided to be consistent with\n        $(D Duration.zero), and it's more explicit than $(D MonoTime.init).\n      +/\n    MonoTimeImpl zero() { return MonoTimeImpl(0); }\n\n    /++\n        Largest $(D MonoTime) possible.\n      +/\n    MonoTimeImpl max() { return MonoTimeImpl(long.max); }\n\n    /++\n        Most negative $(D MonoTime) possible.\n      +/\n    MonoTimeImpl min() { return MonoTimeImpl(long.min); }\n    }\n\n    unittest\n    {\n        assert(MonoTimeImpl.zero == MonoTimeImpl(0));\n        assert(MonoTimeImpl.max == MonoTimeImpl(long.max));\n        assert(MonoTimeImpl.min == MonoTimeImpl(long.min));\n        assert(MonoTimeImpl.min < MonoTimeImpl.zero);\n        assert(MonoTimeImpl.zero < MonoTimeImpl.max);\n        assert(MonoTimeImpl.min < MonoTimeImpl.max);\n    }\n\n\n    /++\n        Compares this MonoTime with the given MonoTime.\n\n        Returns:\n            $(BOOKTABLE,\n                $(TR $(TD this &lt; rhs) $(TD &lt; 0))\n                $(TR $(TD this == rhs) $(TD 0))\n                $(TR $(TD this &gt; rhs) $(TD &gt; 0))\n            )\n     +/\n    int opCmp(MonoTimeImpl rhs) const pure nothrow @nogc\n    {\n        if (_ticks < rhs._ticks)\n            return -1;\n        return _ticks > rhs._ticks ? 1 : 0;\n    }\n\n    unittest\n    {\n        const t = MonoTimeImpl.currTime;\n        assert(t == copy(t));\n    }\n\n    unittest\n    {\n        const before = MonoTimeImpl.currTime;\n        auto after = MonoTimeImpl(before._ticks + 42);\n        assert(before < after);\n        assert(copy(before) <= before);\n        assert(copy(after) > before);\n        assert(after >= copy(after));\n    }\n\n    unittest\n    {\n        const currTime = MonoTimeImpl.currTime;\n        assert(MonoTimeImpl(long.max) > MonoTimeImpl(0));\n        assert(MonoTimeImpl(0) > MonoTimeImpl(long.min));\n        assert(MonoTimeImpl(long.max) > currTime);\n        assert(currTime > MonoTimeImpl(0));\n        assert(MonoTimeImpl(0) < currTime);\n        assert(MonoTimeImpl(0) < MonoTimeImpl(long.max));\n        assert(MonoTimeImpl(long.min) < MonoTimeImpl(0));\n    }\n\n\n    /++\n        Subtracting two MonoTimes results in a $(LREF Duration) representing\n        the amount of time which elapsed between them.\n\n        The primary way that programs should time how long something takes is to\n        do\n--------------------\nMonoTime before = MonoTime.currTime;\n// do stuff\nMonoTime after = MonoTime.currTime;\n\n// How long it took.\nDuration timeElapsed = after - before;\n--------------------\n        or to use a wrapper (such as a stop watch type) which does that.\n\n        $(RED Warning):\n            Because $(LREF Duration) is in hnsecs, whereas MonoTime is in system\n            ticks, it's usually the case that this assertion will fail\n--------------------\nauto before = MonoTime.currTime;\n// do stuff\nauto after = MonoTime.currTime;\nauto timeElapsed = after - before;\nassert(before + timeElapsed == after);\n--------------------\n\n            This is generally fine, and by its very nature, converting from\n            system ticks to any type of seconds (hnsecs, nsecs, etc.) will\n            introduce rounding errors, but if code needs to avoid any of the\n            small rounding errors introduced by conversion, then it needs to use\n            MonoTime's $(D ticks) property and keep all calculations in ticks\n            rather than using $(LREF Duration).\n      +/\n    Duration opBinary(string op)(MonoTimeImpl rhs) const pure nothrow @nogc\n        if (op == \"-\")\n    {\n        immutable diff = _ticks - rhs._ticks;\n        return Duration(convClockFreq(diff , ticksPerSecond, hnsecsPer!\"seconds\"));\n    }\n\n    unittest\n    {\n        const t = MonoTimeImpl.currTime;\n        assert(t - copy(t) == Duration.zero);\n        static assert(!__traits(compiles, t + t));\n    }\n\n    unittest\n    {\n        static void test(in MonoTimeImpl before, in MonoTimeImpl after, in Duration min)\n        {\n            immutable diff = after - before;\n            assert(diff >= min);\n            auto calcAfter = before + diff;\n            assertApprox(calcAfter, calcAfter - Duration(1), calcAfter + Duration(1));\n            assert(before - after == -diff);\n        }\n\n        const before = MonoTimeImpl.currTime;\n        test(before, MonoTimeImpl(before._ticks + 4202), Duration.zero);\n        test(before, MonoTimeImpl.currTime, Duration.zero);\n\n        const durLargerUnits = dur!\"minutes\"(7) + dur!\"seconds\"(22);\n        test(before, before + durLargerUnits + dur!\"msecs\"(33) + dur!\"hnsecs\"(571), durLargerUnits);\n    }\n\n\n    /++\n        Adding or subtracting a $(LREF Duration) to/from a MonoTime results in\n        a MonoTime which is adjusted by that amount.\n      +/\n    MonoTimeImpl opBinary(string op)(Duration rhs) const pure nothrow @nogc\n        if (op == \"+\" || op == \"-\")\n    {\n        immutable rhsConverted = convClockFreq(rhs._hnsecs, hnsecsPer!\"seconds\", ticksPerSecond);\n        mixin(\"return MonoTimeImpl(_ticks \" ~ op ~ \" rhsConverted);\");\n    }\n\n    unittest\n    {\n        const t = MonoTimeImpl.currTime;\n        assert(t + Duration(0) == t);\n        assert(t - Duration(0) == t);\n    }\n\n    unittest\n    {\n        const t = MonoTimeImpl.currTime;\n\n        // We reassign ticks in order to get the same rounding errors\n        // that we should be getting with Duration (e.g. MonoTimeImpl may be\n        // at a higher precision than hnsecs, meaning that 7333 would be\n        // truncated when converting to hnsecs).\n        long ticks = 7333;\n        auto hnsecs = convClockFreq(ticks, ticksPerSecond, hnsecsPer!\"seconds\");\n        ticks = convClockFreq(hnsecs, hnsecsPer!\"seconds\", ticksPerSecond);\n\n        assert(t - Duration(hnsecs) == MonoTimeImpl(t._ticks - ticks));\n        assert(t + Duration(hnsecs) == MonoTimeImpl(t._ticks + ticks));\n    }\n\n\n    /++ Ditto +/\n    ref MonoTimeImpl opOpAssign(string op)(Duration rhs) pure nothrow @nogc\n        if (op == \"+\" || op == \"-\")\n    {\n        immutable rhsConverted = convClockFreq(rhs._hnsecs, hnsecsPer!\"seconds\", ticksPerSecond);\n        mixin(\"_ticks \" ~ op ~ \"= rhsConverted;\");\n        return this;\n    }\n\n    unittest\n    {\n        auto mt = MonoTimeImpl.currTime;\n        const initial = mt;\n        mt += Duration(0);\n        assert(mt == initial);\n        mt -= Duration(0);\n        assert(mt == initial);\n\n        // We reassign ticks in order to get the same rounding errors\n        // that we should be getting with Duration (e.g. MonoTimeImpl may be\n        // at a higher precision than hnsecs, meaning that 7333 would be\n        // truncated when converting to hnsecs).\n        long ticks = 7333;\n        auto hnsecs = convClockFreq(ticks, ticksPerSecond, hnsecsPer!\"seconds\");\n        ticks = convClockFreq(hnsecs, hnsecsPer!\"seconds\", ticksPerSecond);\n        auto before = MonoTimeImpl(initial._ticks - ticks);\n\n        assert((mt -= Duration(hnsecs)) == before);\n        assert(mt  == before);\n        assert((mt += Duration(hnsecs)) == initial);\n        assert(mt  == initial);\n    }\n\n\n    /++\n        The number of ticks in the monotonic time.\n\n        Most programs should not use this directly, but it's exposed for those\n        few programs that need it.\n\n        The main reasons that a program might need to use ticks directly is if\n        the system clock has higher precision than hnsecs, and the program needs\n        that higher precision, or if the program needs to avoid the rounding\n        errors caused by converting to hnsecs.\n      +/\n    @property long ticks() const pure nothrow @nogc\n    {\n        return _ticks;\n    }\n\n    unittest\n    {\n        const mt = MonoTimeImpl.currTime;\n        assert(mt.ticks == mt._ticks);\n    }\n\n\n    /++\n        The number of ticks that MonoTime has per second - i.e. the resolution\n        or frequency of the system's monotonic clock.\n\n        e.g. if the system clock had a resolution of microseconds, then\n        ticksPerSecond would be $(D 1_000_000).\n      +/\n    static @property long ticksPerSecond() pure nothrow @nogc\n    {\n        return _ticksPerSecond[_clockIdx];\n    }\n\n    unittest\n    {\n        assert(MonoTimeImpl.ticksPerSecond == _ticksPerSecond[_clockIdx]);\n    }\n\n\n    ///\n    string toString() const pure nothrow\n    {\n        static if (clockType == ClockType.normal)\n            return \"MonoTime(\" ~ signedToTempString(_ticks, 10) ~ \" ticks, \" ~ signedToTempString(ticksPerSecond, 10) ~ \" ticks per second)\";\n        else\n            return \"MonoTimeImpl!(ClockType.\" ~ _clockName ~ \")(\" ~ signedToTempString(_ticks, 10) ~ \" ticks, \" ~\n                   signedToTempString(ticksPerSecond, 10) ~ \" ticks per second)\";\n    }\n\n    unittest\n    {\n        static min(T)(T a, T b) { return a < b ? a : b; }\n\n        static void eat(ref string s, const(char)[] exp)\n        {\n            assert(s[0 .. min($, exp.length)] == exp, s~\" != \"~exp);\n            s = s[exp.length .. $];\n        }\n\n        immutable mt = MonoTimeImpl.currTime;\n        auto str = mt.toString();\n        static if (is(typeof(this) == MonoTime))\n            eat(str, \"MonoTime(\");\n        else\n            eat(str, \"MonoTimeImpl!(ClockType.\"~_clockName~\")(\");\n\n        eat(str, signedToTempString(mt._ticks, 10));\n        eat(str, \" ticks, \");\n        eat(str, signedToTempString(ticksPerSecond, 10));\n        eat(str, \" ticks per second)\");\n    }\n\nprivate:\n\n    // static immutable long _ticksPerSecond;\n\n    unittest\n    {\n        assert(_ticksPerSecond[_clockIdx]);\n    }\n\n\n    long _ticks;\n}\n\n// This is supposed to be a static variable in MonoTimeImpl with the static\n// constructor being in there, but https://issues.dlang.org/show_bug.cgi?id=14517\n// prevents that from working. However, moving it back to a static ctor will\n// reraise issues with other systems using MonoTime, so we should leave this\n// here even when that bug is fixed.\nprivate immutable long[__traits(allMembers, ClockType).length] _ticksPerSecond;\n\n// This is called directly from the runtime initilization function (rt_init),\n// instead of using a static constructor. Other subsystems inside the runtime\n// (namely, the GC) may need time functionality, but cannot wait until the\n// static ctors have run. Therefore, we initialize these specially. Because\n// it's a normal function, we need to do some dangerous casting PLEASE take\n// care when modifying this function, and it should NOT be called except from\n// the runtime init.\n//\n// NOTE: the code below SPECIFICALLY does not assert when it cannot initialize\n// the ticks per second array. This allows cases where a clock is never used on\n// a system that doesn't support it. See bugzilla issue\n// https://issues.dlang.org/show_bug.cgi?id=14863\n// The assert will occur when someone attempts to use _ticksPerSecond for that\n// value.\nextern(C) void _d_initMonoTime()\n{\n    // We need a mutable pointer to the ticksPerSecond array. Although this\n    // would appear to break immutability, it is logically the same as a static\n    // ctor. So we should ONLY write these values once (we will check for 0\n    // values when setting to ensure this is truly only called once).\n    auto tps = cast(long[])_ticksPerSecond[];\n\n    // If we try to do anything with ClockType in the documentation build, it'll\n    // trigger the static assertions related to ClockType, since the\n    // documentation build defines all of the possible ClockTypes, which won't\n    // work when they're used in the static ifs, because no system supports them\n    // all.\n    version (CoreDdoc)\n    {}\n    else version (Windows)\n    {\n        long ticksPerSecond;\n        if (QueryPerformanceFrequency(&ticksPerSecond) != 0)\n        {\n            foreach (i, typeStr; __traits(allMembers, ClockType))\n            {\n                // ensure we are only writing immutable data once\n                if (tps[i] != 0)\n                    // should only be called once\n                    assert(0);\n                tps[i] = ticksPerSecond;\n            }\n        }\n    }\n    else version (Darwin)\n    {\n        immutable long ticksPerSecond = machTicksPerSecond();\n        foreach (i, typeStr; __traits(allMembers, ClockType))\n        {\n            // ensure we are only writing immutable data once\n            if (tps[i] != 0)\n                // should only be called once\n                assert(0);\n            tps[i] = ticksPerSecond;\n        }\n    }\n    else version (Posix)\n    {\n        timespec ts;\n        foreach (i, typeStr; __traits(allMembers, ClockType))\n        {\n            static if (typeStr != \"second\")\n            {\n                enum clockArg = _posixClock(__traits(getMember, ClockType, typeStr));\n                if (clock_getres(clockArg, &ts) == 0)\n                {\n                    // ensure we are only writing immutable data once\n                    if (tps[i] != 0)\n                        // should only be called once\n                        assert(0);\n\n                    // For some reason, on some systems, clock_getres returns\n                    // a resolution which is clearly wrong:\n                    //  - it's a millisecond or worse, but the time is updated\n                    //    much more frequently than that.\n                    //  - it's negative\n                    //  - it's zero\n                    // In such cases, we'll just use nanosecond resolution.\n                    tps[i] = ts.tv_sec != 0 || ts.tv_nsec <= 0 || ts.tv_nsec >= 1000\n                        ? 1_000_000_000L : 1_000_000_000L / ts.tv_nsec;\n                }\n            }\n        }\n    }\n}\n\n\n// Tests for MonoTimeImpl.currTime. It has to be outside, because MonoTimeImpl\n// is a template. This unittest block also makes sure that MonoTimeImpl actually\n// is instantiated with all of the various ClockTypes so that those types and\n// their tests are compiled and run.\nunittest\n{\n    // This test is separate so that it can be tested with MonoTime and not just\n    // MonoTimeImpl.\n    auto norm1 = MonoTime.currTime;\n    auto norm2 = MonoTimeImpl!(ClockType.normal).currTime;\n    assert(norm1 <= norm2);\n\n    static bool clockSupported(ClockType c)\n    {\n        version (Linux_Pre_2639) // skip CLOCK_BOOTTIME on older linux kernels\n            return c != ClockType.second && c != ClockType.bootTime;\n        else\n            return c != ClockType.second; // second doesn't work with MonoTimeImpl\n\n    }\n\n    foreach (typeStr; __traits(allMembers, ClockType))\n    {\n        mixin(\"alias type = ClockType.\" ~ typeStr ~ \";\");\n        static if (clockSupported(type))\n        {\n            auto v1 = MonoTimeImpl!type.currTime;\n            auto v2 = MonoTimeImpl!type.currTime;\n            scope(failure)\n            {\n                printf(\"%s: v1 %s, v2 %s, tps %s\\n\",\n                       (type.stringof ~ \"\\0\").ptr,\n                       numToStringz(v1._ticks),\n                       numToStringz(v2._ticks),\n                       numToStringz(typeof(v1).ticksPerSecond));\n            }\n            assert(v1 <= v2);\n\n            foreach (otherStr; __traits(allMembers, ClockType))\n            {\n                mixin(\"alias other = ClockType.\" ~ otherStr ~ \";\");\n                static if (clockSupported(other))\n                {\n                    static assert(is(typeof({auto o1 = MonTimeImpl!other.currTime; auto b = v1 <= o1;})) ==\n                                  is(type == other));\n                }\n            }\n        }\n    }\n}\n\n\n/++\n    Converts the given time from one clock frequency/resolution to another.\n\n    See_Also:\n        $(LREF ticksToNSecs)\n  +/\nlong convClockFreq(long ticks, long srcTicksPerSecond, long dstTicksPerSecond) @safe pure nothrow @nogc\n{\n    // This would be more straightforward with floating point arithmetic,\n    // but we avoid it here in order to avoid the rounding errors that that\n    // introduces. Also, by splitting out the units in this way, we're able\n    // to deal with much larger values before running into problems with\n    // integer overflow.\n    return ticks / srcTicksPerSecond * dstTicksPerSecond +\n           ticks % srcTicksPerSecond * dstTicksPerSecond / srcTicksPerSecond;\n}\n\n///\nunittest\n{\n    // one tick is one second -> one tick is a hecto-nanosecond\n    assert(convClockFreq(45, 1, 10_000_000) == 450_000_000);\n\n    // one tick is one microsecond -> one tick is a millisecond\n    assert(convClockFreq(9029, 1_000_000, 1_000) == 9);\n\n    // one tick is 1/3_515_654 of a second -> 1/1_001_010 of a second\n    assert(convClockFreq(912_319, 3_515_654, 1_001_010) == 259_764);\n\n    // one tick is 1/MonoTime.ticksPerSecond -> one tick is a nanosecond\n    // Equivalent to ticksToNSecs\n    auto nsecs = convClockFreq(1982, MonoTime.ticksPerSecond, 1_000_000_000);\n}\n\nunittest\n{\n    assert(convClockFreq(99, 43, 57) == 131);\n    assert(convClockFreq(131, 57, 43) == 98);\n    assert(convClockFreq(1234567890, 10_000_000, 1_000_000_000) == 123456789000);\n    assert(convClockFreq(1234567890, 1_000_000_000, 10_000_000) == 12345678);\n    assert(convClockFreq(123456789000, 1_000_000_000, 10_000_000) == 1234567890);\n    assert(convClockFreq(12345678, 10_000_000, 1_000_000_000) == 1234567800);\n    assert(convClockFreq(13131, 3_515_654, 10_000_000) == 37350);\n    assert(convClockFreq(37350, 10_000_000, 3_515_654) == 13130);\n    assert(convClockFreq(37350, 3_515_654, 10_000_000) == 106239);\n    assert(convClockFreq(106239, 10_000_000, 3_515_654) == 37349);\n\n    // It would be too expensive to cover a large range of possible values for\n    // ticks, so we use random values in an attempt to get reasonable coverage.\n    import core.stdc.stdlib;\n    immutable seed = cast(int)time(null);\n    srand(seed);\n    scope(failure) printf(\"seed %d\\n\", seed);\n    enum freq1 = 5_527_551L;\n    enum freq2 = 10_000_000L;\n    enum freq3 = 1_000_000_000L;\n    enum freq4 = 98_123_320L;\n    immutable freq5 = MonoTime.ticksPerSecond;\n\n    // This makes it so that freq6 is the first multiple of 10 which is greater\n    // than or equal to freq5, which at one point was considered for MonoTime's\n    // ticksPerSecond rather than using the system's actual clock frequency, so\n    // it seemed like a good test case to have.\n    import core.stdc.math;\n    immutable numDigitsMinus1 = cast(int)floor(log10(freq5));\n    auto freq6 = cast(long)pow(10, numDigitsMinus1);\n    if (freq5 > freq6)\n        freq6 *= 10;\n\n    foreach (_; 0 .. 10_000)\n    {\n        long[2] values = [rand(), cast(long)rand() * (rand() % 16)];\n        foreach (i; values)\n        {\n            scope(failure) printf(\"i %s\\n\", numToStringz(i));\n            assertApprox(convClockFreq(convClockFreq(i, freq1, freq2), freq2, freq1), i - 10, i + 10);\n            assertApprox(convClockFreq(convClockFreq(i, freq2, freq1), freq1, freq2), i - 10, i + 10);\n\n            assertApprox(convClockFreq(convClockFreq(i, freq3, freq4), freq4, freq3), i - 100, i + 100);\n            assertApprox(convClockFreq(convClockFreq(i, freq4, freq3), freq3, freq4), i - 100, i + 100);\n\n            scope(failure) printf(\"sys %s mt %s\\n\", numToStringz(freq5), numToStringz(freq6));\n            assertApprox(convClockFreq(convClockFreq(i, freq5, freq6), freq6, freq5), i - 10, i + 10);\n            assertApprox(convClockFreq(convClockFreq(i, freq6, freq5), freq5, freq6), i - 10, i + 10);\n\n            // This is here rather than in a unittest block immediately after\n            // ticksToNSecs in order to avoid code duplication in the unit tests.\n            assert(convClockFreq(i, MonoTime.ticksPerSecond, 1_000_000_000) == ticksToNSecs(i));\n        }\n    }\n}\n\n\n/++\n    Convenience wrapper around $(LREF convClockFreq) which converts ticks at\n    a clock frequency of $(D MonoTime.ticksPerSecond) to nanoseconds.\n\n    It's primarily of use when $(D MonoTime.ticksPerSecond) is greater than\n    hecto-nanosecond resolution, and an application needs a higher precision\n    than hecto-nanoceconds.\n\n    See_Also:\n        $(LREF convClockFreq)\n  +/\nlong ticksToNSecs(long ticks) @safe pure nothrow @nogc\n{\n    return convClockFreq(ticks, MonoTime.ticksPerSecond, 1_000_000_000);\n}\n\n///\nunittest\n{\n    auto before = MonoTime.currTime;\n    // do stuff\n    auto after = MonoTime.currTime;\n    auto diffInTicks = after.ticks - before.ticks;\n    auto diffInNSecs = ticksToNSecs(diffInTicks);\n    assert(diffInNSecs == convClockFreq(diffInTicks, MonoTime.ticksPerSecond, 1_000_000_000));\n}\n\n\n/++\n    The reverse of $(LREF ticksToNSecs).\n  +/\nlong nsecsToTicks(long ticks) @safe pure nothrow @nogc\n{\n    return convClockFreq(ticks, 1_000_000_000, MonoTime.ticksPerSecond);\n}\n\nunittest\n{\n    long ticks = 123409832717333;\n    auto nsecs = convClockFreq(ticks, MonoTime.ticksPerSecond, 1_000_000_000);\n    ticks = convClockFreq(nsecs, 1_000_000_000, MonoTime.ticksPerSecond);\n    assert(nsecsToTicks(nsecs) == ticks);\n}\n\n\n\n/++\n    $(RED Warning: TickDuration will be deprecated in the near future (once all\n          uses of it in Phobos have been deprecated). Please use\n          $(LREF MonoTime) for the cases where a monotonic timestamp is needed\n          and $(LREF Duration) when a duration is needed, rather than using\n          TickDuration. It has been decided that TickDuration is too confusing\n          (e.g. it conflates a monotonic timestamp and a duration in monotonic\n           clock ticks) and that having multiple duration types is too awkward\n          and confusing.)\n\n   Represents a duration of time in system clock ticks.\n\n   The system clock ticks are the ticks of the system clock at the highest\n   precision that the system provides.\n  +/\nstruct TickDuration\n{\n    /++\n       The number of ticks that the system clock has in one second.\n\n       If $(D ticksPerSec) is $(D 0), then then $(D TickDuration) failed to\n       get the value of $(D ticksPerSec) on the current system, and\n       $(D TickDuration) is not going to work. That would be highly abnormal\n       though.\n      +/\n    static immutable long ticksPerSec;\n\n\n    /++\n        The tick of the system clock (as a $(D TickDuration)) when the\n        application started.\n      +/\n    static immutable TickDuration appOrigin;\n\n\n    static @property @safe pure nothrow @nogc\n    {\n    /++\n        It's the same as $(D TickDuration(0)), but it's provided to be\n        consistent with $(D Duration) and $(D FracSec), which provide $(D zero)\n        properties.\n      +/\n    TickDuration zero() { return TickDuration(0); }\n\n    /++\n        Largest $(D TickDuration) possible.\n      +/\n    TickDuration max() { return TickDuration(long.max); }\n\n    /++\n        Most negative $(D TickDuration) possible.\n      +/\n    TickDuration min() { return TickDuration(long.min); }\n    }\n\n    unittest\n    {\n        assert(zero == TickDuration(0));\n        assert(TickDuration.max == TickDuration(long.max));\n        assert(TickDuration.min == TickDuration(long.min));\n        assert(TickDuration.min < TickDuration.zero);\n        assert(TickDuration.zero < TickDuration.max);\n        assert(TickDuration.min < TickDuration.max);\n        assert(TickDuration.min - TickDuration(1) == TickDuration.max);\n        assert(TickDuration.max + TickDuration(1) == TickDuration.min);\n    }\n\n\n    @trusted shared static this()\n    {\n        version (Windows)\n        {\n            if (QueryPerformanceFrequency(cast(long*)&ticksPerSec) == 0)\n                ticksPerSec = 0;\n        }\n        else version (Darwin)\n        {\n            ticksPerSec = machTicksPerSecond();\n        }\n        else version (Posix)\n        {\n            static if (is(typeof(clock_gettime)))\n            {\n                timespec ts;\n\n                if (clock_getres(CLOCK_MONOTONIC, &ts) != 0)\n                    ticksPerSec = 0;\n                else\n                {\n                    //For some reason, on some systems, clock_getres returns\n                    //a resolution which is clearly wrong (it's a millisecond\n                    //or worse, but the time is updated much more frequently\n                    //than that). In such cases, we'll just use nanosecond\n                    //resolution.\n                    ticksPerSec = ts.tv_nsec >= 1000 ? 1_000_000_000\n                                                     : 1_000_000_000 / ts.tv_nsec;\n                }\n            }\n            else\n                ticksPerSec = 1_000_000;\n        }\n\n        if (ticksPerSec != 0)\n            appOrigin = TickDuration.currSystemTick;\n    }\n\n    unittest\n    {\n        assert(ticksPerSec);\n    }\n\n\n    /++\n       The number of system ticks in this $(D TickDuration).\n\n       You can convert this $(D length) into the number of seconds by dividing\n       it by $(D ticksPerSec) (or using one the appropriate property function\n       to do it).\n      +/\n    long length;\n\n    /++\n        Returns the total number of seconds in this $(D TickDuration).\n      +/\n    @property long seconds() @safe const pure nothrow @nogc\n    {\n        return this.to!(\"seconds\", long)();\n    }\n\n    unittest\n    {\n        foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n        {\n            assert((cast(T)TickDuration(ticksPerSec)).seconds == 1);\n            assert((cast(T)TickDuration(ticksPerSec - 1)).seconds == 0);\n            assert((cast(T)TickDuration(ticksPerSec * 2)).seconds == 2);\n            assert((cast(T)TickDuration(ticksPerSec * 2 - 1)).seconds == 1);\n            assert((cast(T)TickDuration(-1)).seconds == 0);\n            assert((cast(T)TickDuration(-ticksPerSec - 1)).seconds == -1);\n            assert((cast(T)TickDuration(-ticksPerSec)).seconds == -1);\n        }\n    }\n\n\n    /++\n        Returns the total number of milliseconds in this $(D TickDuration).\n      +/\n    @property long msecs() @safe const pure nothrow @nogc\n    {\n        return this.to!(\"msecs\", long)();\n    }\n\n\n    /++\n        Returns the total number of microseconds in this $(D TickDuration).\n      +/\n    @property long usecs() @safe const pure nothrow @nogc\n    {\n        return this.to!(\"usecs\", long)();\n    }\n\n\n    /++\n        Returns the total number of hecto-nanoseconds in this $(D TickDuration).\n      +/\n    @property long hnsecs() @safe const pure nothrow @nogc\n    {\n        return this.to!(\"hnsecs\", long)();\n    }\n\n\n    /++\n        Returns the total number of nanoseconds in this $(D TickDuration).\n      +/\n    @property long nsecs() @safe const pure nothrow @nogc\n    {\n        return this.to!(\"nsecs\", long)();\n    }\n\n\n    /++\n        This allows you to construct a $(D TickDuration) from the given time\n        units with the given length.\n\n        Params:\n            units  = The time units of the $(D TickDuration) (e.g. $(D \"msecs\")).\n            length = The number of units in the $(D TickDuration).\n      +/\n    static TickDuration from(string units)(long length) @safe pure nothrow @nogc\n        if (units == \"seconds\" ||\n           units == \"msecs\" ||\n           units == \"usecs\" ||\n           units == \"hnsecs\" ||\n           units == \"nsecs\")\n    {\n        enum unitsPerSec = convert!(\"seconds\", units)(1);\n\n        return TickDuration(cast(long)(length * (ticksPerSec / cast(real)unitsPerSec)));\n    }\n\n    unittest\n    {\n        foreach (units; _TypeTuple!(\"seconds\", \"msecs\", \"usecs\", \"nsecs\"))\n        {\n            foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n            {\n                assertApprox((cast(T)TickDuration.from!units(1000)).to!(units, long)(),\n                             500, 1500, units);\n                assertApprox((cast(T)TickDuration.from!units(1_000_000)).to!(units, long)(),\n                             900_000, 1_100_000, units);\n                assertApprox((cast(T)TickDuration.from!units(2_000_000)).to!(units, long)(),\n                             1_900_000, 2_100_000, units);\n            }\n        }\n    }\n\n\n    /++\n        Returns a $(LREF Duration) with the same number of hnsecs as this\n        $(D TickDuration).\n        Note that the conventional way to convert between $(D TickDuration)\n        and $(D Duration) is using $(REF to, std,conv), e.g.:\n        $(D tickDuration.to!Duration())\n      +/\n    Duration opCast(T)() @safe const pure nothrow @nogc\n        if (is(_Unqual!T == Duration))\n    {\n        return Duration(hnsecs);\n    }\n\n    unittest\n    {\n        foreach (D; _TypeTuple!(Duration, const Duration, immutable Duration))\n        {\n            foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n            {\n                auto expected = dur!\"seconds\"(1);\n                assert(cast(D)cast(T)TickDuration.from!\"seconds\"(1) == expected);\n\n                foreach (units; _TypeTuple!(\"msecs\", \"usecs\", \"hnsecs\"))\n                {\n                    D actual = cast(D)cast(T)TickDuration.from!units(1_000_000);\n                    assertApprox(actual, dur!units(900_000), dur!units(1_100_000));\n                }\n            }\n        }\n    }\n\n\n    //Temporary hack until bug http://d.puremagic.com/issues/show_bug.cgi?id=5747 is fixed.\n    TickDuration opCast(T)() @safe const pure nothrow @nogc\n        if (is(_Unqual!T == TickDuration))\n    {\n        return this;\n    }\n\n\n    /++\n        Adds or subtracts two $(D TickDuration)s as well as assigning the result\n        to this $(D TickDuration).\n\n        The legal types of arithmetic for $(D TickDuration) using this operator\n        are\n\n        $(TABLE\n        $(TR $(TD TickDuration) $(TD +=) $(TD TickDuration) $(TD -->) $(TD TickDuration))\n        $(TR $(TD TickDuration) $(TD -=) $(TD TickDuration) $(TD -->) $(TD TickDuration))\n        )\n\n        Params:\n            rhs = The $(D TickDuration) to add to or subtract from this\n                  $(D $(D TickDuration)).\n      +/\n    ref TickDuration opOpAssign(string op)(TickDuration rhs) @safe pure nothrow @nogc\n        if (op == \"+\" || op == \"-\")\n    {\n        mixin(\"length \" ~ op ~ \"= rhs.length;\");\n        return this;\n    }\n\n    unittest\n    {\n        foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n        {\n            auto a = TickDuration.currSystemTick;\n            auto result = a += cast(T)TickDuration.currSystemTick;\n            assert(a == result);\n            assert(a.to!(\"seconds\", real)() >= 0);\n\n            auto b = TickDuration.currSystemTick;\n            result = b -= cast(T)TickDuration.currSystemTick;\n            assert(b == result);\n            assert(b.to!(\"seconds\", real)() <= 0);\n\n            foreach (U; _TypeTuple!(const TickDuration, immutable TickDuration))\n            {\n                U u = TickDuration(12);\n                static assert(!__traits(compiles, u += cast(T)TickDuration.currSystemTick));\n                static assert(!__traits(compiles, u -= cast(T)TickDuration.currSystemTick));\n            }\n        }\n    }\n\n\n    /++\n        Adds or subtracts two $(D TickDuration)s.\n\n        The legal types of arithmetic for $(D TickDuration) using this operator\n        are\n\n        $(TABLE\n        $(TR $(TD TickDuration) $(TD +) $(TD TickDuration) $(TD -->) $(TD TickDuration))\n        $(TR $(TD TickDuration) $(TD -) $(TD TickDuration) $(TD -->) $(TD TickDuration))\n        )\n\n        Params:\n            rhs = The $(D TickDuration) to add to or subtract from this\n                  $(D TickDuration).\n      +/\n    TickDuration opBinary(string op)(TickDuration rhs) @safe const pure nothrow @nogc\n        if (op == \"+\" || op == \"-\")\n    {\n        return TickDuration(mixin(\"length \" ~ op ~ \" rhs.length\"));\n    }\n\n    unittest\n    {\n        foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n        {\n            T a = TickDuration.currSystemTick;\n            T b = TickDuration.currSystemTick;\n            assert((a + b).seconds > 0);\n            assert((a - b).seconds <= 0);\n        }\n    }\n\n\n    /++\n        Returns the negation of this $(D TickDuration).\n      +/\n    TickDuration opUnary(string op)() @safe const pure nothrow @nogc\n        if (op == \"-\")\n    {\n        return TickDuration(-length);\n    }\n\n    unittest\n    {\n        foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n        {\n            assert(-(cast(T)TickDuration(7)) == TickDuration(-7));\n            assert(-(cast(T)TickDuration(5)) == TickDuration(-5));\n            assert(-(cast(T)TickDuration(-7)) == TickDuration(7));\n            assert(-(cast(T)TickDuration(-5)) == TickDuration(5));\n            assert(-(cast(T)TickDuration(0)) == TickDuration(0));\n        }\n    }\n\n\n    /++\n       operator overloading \"<, >, <=, >=\"\n      +/\n    int opCmp(TickDuration rhs) @safe const pure nothrow @nogc\n    {\n        return length < rhs.length ? -1 : (length == rhs.length ? 0 : 1);\n    }\n\n    unittest\n    {\n        foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n        {\n            foreach (U; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n            {\n                T t = TickDuration.currSystemTick;\n                U u = t;\n                assert(t == u);\n                assert(copy(t) == u);\n                assert(t == copy(u));\n            }\n        }\n\n        foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n        {\n            foreach (U; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n            {\n                T t = TickDuration.currSystemTick;\n                U u = t + t;\n                assert(t < u);\n                assert(t <= t);\n                assert(u > t);\n                assert(u >= u);\n\n                assert(copy(t) < u);\n                assert(copy(t) <= t);\n                assert(copy(u) > t);\n                assert(copy(u) >= u);\n\n                assert(t < copy(u));\n                assert(t <= copy(t));\n                assert(u > copy(t));\n                assert(u >= copy(u));\n            }\n        }\n    }\n\n\n    /++\n        The legal types of arithmetic for $(D TickDuration) using this operator\n        overload are\n\n        $(TABLE\n        $(TR $(TD TickDuration) $(TD *) $(TD long) $(TD -->) $(TD TickDuration))\n        $(TR $(TD TickDuration) $(TD *) $(TD floating point) $(TD -->) $(TD TickDuration))\n        )\n\n        Params:\n            value = The value to divide from this duration.\n      +/\n    void opOpAssign(string op, T)(T value) @safe pure nothrow @nogc\n        if (op == \"*\" &&\n           (__traits(isIntegral, T) || __traits(isFloating, T)))\n    {\n        length = cast(long)(length * value);\n    }\n\n    unittest\n    {\n        immutable curr = TickDuration.currSystemTick;\n        TickDuration t1 = curr;\n        immutable t2 = curr + curr;\n        t1 *= 2;\n        assert(t1 == t2);\n\n        t1 = curr;\n        t1 *= 2.0;\n        immutable tol = TickDuration(cast(long)(_abs(t1.length) * double.epsilon * 2.0));\n        assertApprox(t1, t2 - tol, t2 + tol);\n\n        t1 = curr;\n        t1 *= 2.1;\n        assert(t1 > t2);\n\n        foreach (T; _TypeTuple!(const TickDuration, immutable TickDuration))\n        {\n            T t = TickDuration.currSystemTick;\n            assert(!__traits(compiles, t *= 12));\n            assert(!__traits(compiles, t *= 12.0));\n        }\n    }\n\n\n    /++\n        The legal types of arithmetic for $(D TickDuration) using this operator\n        overload are\n\n        $(TABLE\n        $(TR $(TD TickDuration) $(TD /) $(TD long) $(TD -->) $(TD TickDuration))\n        $(TR $(TD TickDuration) $(TD /) $(TD floating point) $(TD -->) $(TD TickDuration))\n        )\n\n        Params:\n            value = The value to divide from this $(D TickDuration).\n\n        Throws:\n            $(D TimeException) if an attempt to divide by $(D 0) is made.\n      +/\n    void opOpAssign(string op, T)(T value) @safe pure\n        if (op == \"/\" &&\n           (__traits(isIntegral, T) || __traits(isFloating, T)))\n    {\n        if (value == 0)\n            throw new TimeException(\"Attempted division by 0.\");\n\n        length = cast(long)(length / value);\n    }\n\n    unittest\n    {\n        immutable curr = TickDuration.currSystemTick;\n        immutable t1 = curr;\n        TickDuration t2 = curr + curr;\n        t2 /= 2;\n        assert(t1 == t2);\n\n        t2 = curr + curr;\n        t2 /= 2.0;\n        immutable tol = TickDuration(cast(long)(_abs(t2.length) * double.epsilon / 2.0));\n        assertApprox(t1, t2 - tol, t2 + tol);\n\n        t2 = curr + curr;\n        t2 /= 2.1;\n        assert(t1 > t2);\n\n        _assertThrown!TimeException(t2 /= 0);\n\n        foreach (T; _TypeTuple!(const TickDuration, immutable TickDuration))\n        {\n            T t = TickDuration.currSystemTick;\n            assert(!__traits(compiles, t /= 12));\n            assert(!__traits(compiles, t /= 12.0));\n        }\n    }\n\n\n    /++\n        The legal types of arithmetic for $(D TickDuration) using this operator\n        overload are\n\n        $(TABLE\n        $(TR $(TD TickDuration) $(TD *) $(TD long) $(TD -->) $(TD TickDuration))\n        $(TR $(TD TickDuration) $(TD *) $(TD floating point) $(TD -->) $(TD TickDuration))\n        )\n\n        Params:\n            value = The value to divide from this $(D TickDuration).\n      +/\n    TickDuration opBinary(string op, T)(T value) @safe const pure nothrow @nogc\n        if (op == \"*\" &&\n           (__traits(isIntegral, T) || __traits(isFloating, T)))\n    {\n        return TickDuration(cast(long)(length * value));\n    }\n\n    unittest\n    {\n        foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n        {\n            T t1 = TickDuration.currSystemTick;\n            T t2 = t1 + t1;\n            assert(t1 * 2 == t2);\n            immutable tol = TickDuration(cast(long)(_abs(t1.length) * double.epsilon * 2.0));\n            assertApprox(t1 * 2.0, t2 - tol, t2 + tol);\n            assert(t1 * 2.1 > t2);\n        }\n    }\n\n\n    /++\n        The legal types of arithmetic for $(D TickDuration) using this operator\n        overload are\n\n        $(TABLE\n        $(TR $(TD TickDuration) $(TD /) $(TD long) $(TD -->) $(TD TickDuration))\n        $(TR $(TD TickDuration) $(TD /) $(TD floating point) $(TD -->) $(TD TickDuration))\n        )\n\n        Params:\n            value = The value to divide from this $(D TickDuration).\n\n        Throws:\n            $(D TimeException) if an attempt to divide by $(D 0) is made.\n      +/\n    TickDuration opBinary(string op, T)(T value) @safe const pure\n        if (op == \"/\" &&\n           (__traits(isIntegral, T) || __traits(isFloating, T)))\n    {\n        if (value == 0)\n            throw new TimeException(\"Attempted division by 0.\");\n\n        return TickDuration(cast(long)(length / value));\n    }\n\n    unittest\n    {\n        foreach (T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))\n        {\n            T t1 = TickDuration.currSystemTick;\n            T t2 = t1 + t1;\n            assert(t2 / 2 == t1);\n            immutable tol = TickDuration(cast(long)(_abs(t2.length) * double.epsilon / 2.0));\n            assertApprox(t2 / 2.0, t1 - tol, t1 + tol);\n            assert(t2 / 2.1 < t1);\n\n            _assertThrown!TimeException(t2 / 0);\n        }\n    }\n\n\n    /++\n        Params:\n            ticks = The number of ticks in the TickDuration.\n      +/\n    @safe pure nothrow @nogc this(long ticks)\n    {\n        this.length = ticks;\n    }\n\n    unittest\n    {\n        foreach (i; [-42, 0, 42])\n            assert(TickDuration(i).length == i);\n    }\n\n\n    /++\n        The current system tick. The number of ticks per second varies from\n        system to system. $(D currSystemTick) uses a monotonic clock, so it's\n        intended for precision timing by comparing relative time values, not for\n        getting the current system time.\n\n        On Windows, $(D QueryPerformanceCounter) is used. On Mac OS X,\n        $(D mach_absolute_time) is used, while on other Posix systems,\n        $(D clock_gettime) is used. If $(D mach_absolute_time) or\n        $(D clock_gettime) is unavailable, then Posix systems use\n        $(D gettimeofday) (the decision is made when $(D TickDuration) is\n        compiled), which unfortunately, is not monotonic, but if\n        $(D mach_absolute_time) and $(D clock_gettime) aren't available, then\n        $(D gettimeofday) is the the best that there is.\n\n        $(RED Warning):\n            On some systems, the monotonic clock may stop counting when\n            the computer goes to sleep or hibernates. So, the monotonic\n            clock could be off if that occurs. This is known to happen\n            on Mac OS X. It has not been tested whether it occurs on\n            either Windows or on Linux.\n\n        Throws:\n            $(D TimeException) if it fails to get the time.\n      +/\n    static @property TickDuration currSystemTick() @trusted nothrow @nogc\n    {\n        import core.internal.abort : abort;\n        version (Windows)\n        {\n            ulong ticks = void;\n            QueryPerformanceCounter(cast(long*)&ticks);\n            return TickDuration(ticks);\n        }\n        else version (Darwin)\n        {\n            static if (is(typeof(mach_absolute_time)))\n                return TickDuration(cast(long)mach_absolute_time());\n            else\n            {\n                timeval tv = void;\n                gettimeofday(&tv, null);\n                return TickDuration(tv.tv_sec * TickDuration.ticksPerSec +\n                                    tv.tv_usec * TickDuration.ticksPerSec / 1000 / 1000);\n            }\n        }\n        else version (Posix)\n        {\n            static if (is(typeof(clock_gettime)))\n            {\n                timespec ts = void;\n                immutable error = clock_gettime(CLOCK_MONOTONIC, &ts);\n                // CLOCK_MONOTONIC is supported and if tv_sec is long or larger\n                // overflow won't happen before 292 billion years A.D.\n                static if (ts.tv_sec.max < long.max)\n                {\n                    if (error)\n                    {\n                        import core.internal.abort : abort;\n                        abort(\"Call to clock_gettime failed.\");\n                    }\n                }\n                return TickDuration(ts.tv_sec * TickDuration.ticksPerSec +\n                                    ts.tv_nsec * TickDuration.ticksPerSec / 1000 / 1000 / 1000);\n            }\n            else\n            {\n                timeval tv = void;\n                gettimeofday(&tv, null);\n                return TickDuration(tv.tv_sec * TickDuration.ticksPerSec +\n                                    tv.tv_usec * TickDuration.ticksPerSec / 1000 / 1000);\n            }\n        }\n    }\n\n    @safe nothrow unittest\n    {\n        assert(TickDuration.currSystemTick.length > 0);\n    }\n}\n\n\n/++\n    Generic way of converting between two time units. Conversions to smaller\n    units use truncating division. Years and months can be converted to each\n    other, small units can be converted to each other, but years and months\n    cannot be converted to or from smaller units (due to the varying number\n    of days in a month or year).\n\n    Params:\n        from  = The units of time to convert from.\n        to    = The units of time to convert to.\n        value = The value to convert.\n  +/\nlong convert(string from, string to)(long value) @safe pure nothrow @nogc\n    if (((from == \"weeks\" ||\n         from == \"days\" ||\n         from == \"hours\" ||\n         from == \"minutes\" ||\n         from == \"seconds\" ||\n         from == \"msecs\" ||\n         from == \"usecs\" ||\n         from == \"hnsecs\" ||\n         from == \"nsecs\") &&\n        (to == \"weeks\" ||\n         to == \"days\" ||\n         to == \"hours\" ||\n         to == \"minutes\" ||\n         to == \"seconds\" ||\n         to == \"msecs\" ||\n         to == \"usecs\" ||\n         to == \"hnsecs\" ||\n         to == \"nsecs\")) ||\n       ((from == \"years\" || from == \"months\") && (to == \"years\" || to == \"months\")))\n{\n    static if (from == \"years\")\n    {\n        static if (to == \"years\")\n            return value;\n        else static if (to == \"months\")\n            return value * 12;\n        else\n            static assert(0, \"A generic month or year cannot be converted to or from smaller units.\");\n    }\n    else static if (from == \"months\")\n    {\n        static if (to == \"years\")\n            return value / 12;\n        else static if (to == \"months\")\n            return value;\n        else\n            static assert(0, \"A generic month or year cannot be converted to or from smaller units.\");\n    }\n    else static if (from == \"nsecs\" && to == \"nsecs\")\n        return value;\n    else static if (from == \"nsecs\")\n        return convert!(\"hnsecs\", to)(value / 100);\n    else static if (to == \"nsecs\")\n        return convert!(from, \"hnsecs\")(value) * 100;\n    else\n        return (hnsecsPer!from * value) / hnsecsPer!to;\n}\n\n///\nunittest\n{\n    assert(convert!(\"years\", \"months\")(1) == 12);\n    assert(convert!(\"months\", \"years\")(12) == 1);\n\n    assert(convert!(\"weeks\", \"days\")(1) == 7);\n    assert(convert!(\"hours\", \"seconds\")(1) == 3600);\n    assert(convert!(\"seconds\", \"days\")(1) == 0);\n    assert(convert!(\"seconds\", \"days\")(86_400) == 1);\n\n    assert(convert!(\"nsecs\", \"nsecs\")(1) == 1);\n    assert(convert!(\"nsecs\", \"hnsecs\")(1) == 0);\n    assert(convert!(\"hnsecs\", \"nsecs\")(1) == 100);\n    assert(convert!(\"nsecs\", \"seconds\")(1) == 0);\n    assert(convert!(\"seconds\", \"nsecs\")(1) == 1_000_000_000);\n}\n\nunittest\n{\n    foreach (units; _TypeTuple!(\"weeks\", \"days\", \"hours\", \"seconds\", \"msecs\", \"usecs\", \"hnsecs\", \"nsecs\"))\n    {\n        static assert(!__traits(compiles, convert!(\"years\", units)(12)), units);\n        static assert(!__traits(compiles, convert!(units, \"years\")(12)), units);\n    }\n\n    foreach (units; _TypeTuple!(\"years\", \"months\", \"weeks\", \"days\",\n                               \"hours\", \"seconds\", \"msecs\", \"usecs\", \"hnsecs\", \"nsecs\"))\n    {\n        assert(convert!(units, units)(12) == 12);\n    }\n\n    assert(convert!(\"weeks\", \"hnsecs\")(1) == 6_048_000_000_000L);\n    assert(convert!(\"days\", \"hnsecs\")(1) == 864_000_000_000L);\n    assert(convert!(\"hours\", \"hnsecs\")(1) == 36_000_000_000L);\n    assert(convert!(\"minutes\", \"hnsecs\")(1) == 600_000_000L);\n    assert(convert!(\"seconds\", \"hnsecs\")(1) == 10_000_000L);\n    assert(convert!(\"msecs\", \"hnsecs\")(1) == 10_000);\n    assert(convert!(\"usecs\", \"hnsecs\")(1) == 10);\n\n    assert(convert!(\"hnsecs\", \"weeks\")(6_048_000_000_000L) == 1);\n    assert(convert!(\"hnsecs\", \"days\")(864_000_000_000L) == 1);\n    assert(convert!(\"hnsecs\", \"hours\")(36_000_000_000L) == 1);\n    assert(convert!(\"hnsecs\", \"minutes\")(600_000_000L) == 1);\n    assert(convert!(\"hnsecs\", \"seconds\")(10_000_000L) == 1);\n    assert(convert!(\"hnsecs\", \"msecs\")(10_000) == 1);\n    assert(convert!(\"hnsecs\", \"usecs\")(10) == 1);\n\n    assert(convert!(\"weeks\", \"days\")(1) == 7);\n    assert(convert!(\"days\", \"weeks\")(7) == 1);\n\n    assert(convert!(\"days\", \"hours\")(1) == 24);\n    assert(convert!(\"hours\", \"days\")(24) == 1);\n\n    assert(convert!(\"hours\", \"minutes\")(1) == 60);\n    assert(convert!(\"minutes\", \"hours\")(60) == 1);\n\n    assert(convert!(\"minutes\", \"seconds\")(1) == 60);\n    assert(convert!(\"seconds\", \"minutes\")(60) == 1);\n\n    assert(convert!(\"seconds\", \"msecs\")(1) == 1000);\n    assert(convert!(\"msecs\", \"seconds\")(1000) == 1);\n\n    assert(convert!(\"msecs\", \"usecs\")(1) == 1000);\n    assert(convert!(\"usecs\", \"msecs\")(1000) == 1);\n\n    assert(convert!(\"usecs\", \"hnsecs\")(1) == 10);\n    assert(convert!(\"hnsecs\", \"usecs\")(10) == 1);\n\n    assert(convert!(\"weeks\", \"nsecs\")(1) == 604_800_000_000_000L);\n    assert(convert!(\"days\", \"nsecs\")(1) == 86_400_000_000_000L);\n    assert(convert!(\"hours\", \"nsecs\")(1) == 3_600_000_000_000L);\n    assert(convert!(\"minutes\", \"nsecs\")(1) == 60_000_000_000L);\n    assert(convert!(\"seconds\", \"nsecs\")(1) == 1_000_000_000L);\n    assert(convert!(\"msecs\", \"nsecs\")(1) == 1_000_000);\n    assert(convert!(\"usecs\", \"nsecs\")(1) == 1000);\n    assert(convert!(\"hnsecs\", \"nsecs\")(1) == 100);\n\n    assert(convert!(\"nsecs\", \"weeks\")(604_800_000_000_000L) == 1);\n    assert(convert!(\"nsecs\", \"days\")(86_400_000_000_000L) == 1);\n    assert(convert!(\"nsecs\", \"hours\")(3_600_000_000_000L) == 1);\n    assert(convert!(\"nsecs\", \"minutes\")(60_000_000_000L) == 1);\n    assert(convert!(\"nsecs\", \"seconds\")(1_000_000_000L) == 1);\n    assert(convert!(\"nsecs\", \"msecs\")(1_000_000) == 1);\n    assert(convert!(\"nsecs\", \"usecs\")(1000) == 1);\n    assert(convert!(\"nsecs\", \"hnsecs\")(100) == 1);\n}\n\n\n// @@@DEPRECATED_2018-10@@@\n/++\n    $(RED Everything in druntime and Phobos that was using FracSec now uses\n          Duration for greater simplicity. So, FracSec has been deprecated.\n          It will be removed from the docs in October 2018, and removed\n          completely from druntime in October 2019.)\n\n    Represents fractional seconds.\n\n    This is the portion of the time which is smaller than a second and it cannot\n    hold values which would be greater than or equal to a second (or less than\n    or equal to a negative second).\n\n    It holds hnsecs internally, but you can create it using either milliseconds,\n    microseconds, or hnsecs. What it does is allow for a simple way to set or\n    adjust the fractional seconds portion of a $(D Duration) or a\n    $(REF SysTime, std,datetime) without having to worry about whether you're\n    dealing with milliseconds, microseconds, or hnsecs.\n\n    $(D FracSec)'s functions which take time unit strings do accept\n    $(D \"nsecs\"), but because the resolution of $(D Duration) and\n    $(REF SysTime, std,datetime) is hnsecs, you don't actually get precision higher\n    than hnsecs. $(D \"nsecs\") is accepted merely for convenience. Any values\n    given as nsecs will be converted to hnsecs using $(D convert) (which uses\n    truncating division when converting to smaller units).\n  +/\ndeprecated(\"FracSec has been deprecated in favor of just using Duration for the sake of simplicity\")\nstruct FracSec\n{\n@safe pure:\n\npublic:\n\n    /++\n        A $(D FracSec) of $(D 0). It's shorter than doing something like\n        $(D FracSec.from!\"msecs\"(0)) and more explicit than $(D FracSec.init).\n      +/\n    static @property nothrow @nogc FracSec zero() { return FracSec(0); }\n\n    unittest\n    {\n        assert(zero == FracSec.from!\"msecs\"(0));\n    }\n\n\n    /++\n        Create a $(D FracSec) from the given units ($(D \"msecs\"), $(D \"usecs\"),\n        or $(D \"hnsecs\")).\n\n        Params:\n            units = The units to create a FracSec from.\n            value = The number of the given units passed the second.\n\n        Throws:\n            $(D TimeException) if the given value would result in a $(D FracSec)\n            greater than or equal to $(D 1) second or less than or equal to\n            $(D -1) seconds.\n      +/\n    static FracSec from(string units)(long value)\n        if (units == \"msecs\" ||\n           units == \"usecs\" ||\n           units == \"hnsecs\" ||\n           units == \"nsecs\")\n    {\n        immutable hnsecs = cast(int)convert!(units, \"hnsecs\")(value);\n        _enforceValid(hnsecs);\n        return FracSec(hnsecs);\n    }\n\n    unittest\n    {\n        assert(FracSec.from!\"msecs\"(0) == FracSec(0));\n        assert(FracSec.from!\"usecs\"(0) == FracSec(0));\n        assert(FracSec.from!\"hnsecs\"(0) == FracSec(0));\n\n        foreach (sign; [1, -1])\n        {\n            _assertThrown!TimeException(from!\"msecs\"(1000 * sign));\n\n            assert(FracSec.from!\"msecs\"(1 * sign) == FracSec(10_000 * sign));\n            assert(FracSec.from!\"msecs\"(999 * sign) == FracSec(9_990_000 * sign));\n\n            _assertThrown!TimeException(from!\"usecs\"(1_000_000 * sign));\n\n            assert(FracSec.from!\"usecs\"(1 * sign) == FracSec(10 * sign));\n            assert(FracSec.from!\"usecs\"(999 * sign) == FracSec(9990 * sign));\n            assert(FracSec.from!\"usecs\"(999_999 * sign) == FracSec(9999_990 * sign));\n\n            _assertThrown!TimeException(from!\"hnsecs\"(10_000_000 * sign));\n\n            assert(FracSec.from!\"hnsecs\"(1 * sign) == FracSec(1 * sign));\n            assert(FracSec.from!\"hnsecs\"(999 * sign) == FracSec(999 * sign));\n            assert(FracSec.from!\"hnsecs\"(999_999 * sign) == FracSec(999_999 * sign));\n            assert(FracSec.from!\"hnsecs\"(9_999_999 * sign) == FracSec(9_999_999 * sign));\n\n            assert(FracSec.from!\"nsecs\"(1 * sign) == FracSec(0));\n            assert(FracSec.from!\"nsecs\"(10 * sign) == FracSec(0));\n            assert(FracSec.from!\"nsecs\"(99 * sign) == FracSec(0));\n            assert(FracSec.from!\"nsecs\"(100 * sign) == FracSec(1 * sign));\n            assert(FracSec.from!\"nsecs\"(99_999 * sign) == FracSec(999 * sign));\n            assert(FracSec.from!\"nsecs\"(99_999_999 * sign) == FracSec(999_999 * sign));\n            assert(FracSec.from!\"nsecs\"(999_999_999 * sign) == FracSec(9_999_999 * sign));\n        }\n    }\n\n\n    /++\n        Returns the negation of this $(D FracSec).\n      +/\n    FracSec opUnary(string op)() const nothrow @nogc\n        if (op == \"-\")\n    {\n        return FracSec(-_hnsecs);\n    }\n\n    unittest\n    {\n        foreach (val; [-7, -5, 0, 5, 7])\n        {\n            foreach (F; _TypeTuple!(FracSec, const FracSec, immutable FracSec))\n            {\n                F fs = FracSec(val);\n                assert(-fs == FracSec(-val));\n            }\n        }\n    }\n\n\n    /++\n        The value of this $(D FracSec) as milliseconds.\n      +/\n    @property int msecs() const nothrow @nogc\n    {\n        return cast(int)convert!(\"hnsecs\", \"msecs\")(_hnsecs);\n    }\n\n    unittest\n    {\n        foreach (F; _TypeTuple!(FracSec, const FracSec, immutable FracSec))\n        {\n            assert(FracSec(0).msecs == 0);\n\n            foreach (sign; [1, -1])\n            {\n                assert((cast(F)FracSec(1 * sign)).msecs == 0);\n                assert((cast(F)FracSec(999 * sign)).msecs == 0);\n                assert((cast(F)FracSec(999_999 * sign)).msecs == 99 * sign);\n                assert((cast(F)FracSec(9_999_999 * sign)).msecs == 999 * sign);\n            }\n        }\n    }\n\n\n    /++\n        The value of this $(D FracSec) as milliseconds.\n\n        Params:\n            milliseconds = The number of milliseconds passed the second.\n\n        Throws:\n            $(D TimeException) if the given value is not less than $(D 1) second\n            and greater than a $(D -1) seconds.\n      +/\n    @property void msecs(int milliseconds)\n    {\n        immutable hnsecs = cast(int)convert!(\"msecs\", \"hnsecs\")(milliseconds);\n        _enforceValid(hnsecs);\n        _hnsecs = hnsecs;\n    }\n\n    unittest\n    {\n        static void test(int msecs, FracSec expected = FracSec.init, size_t line = __LINE__)\n        {\n            FracSec fs;\n            fs.msecs = msecs;\n\n            if (fs != expected)\n                throw new AssertError(\"unittest failure\", __FILE__, line);\n        }\n\n        _assertThrown!TimeException(test(-1000));\n        _assertThrown!TimeException(test(1000));\n\n        test(0, FracSec(0));\n\n        foreach (sign; [1, -1])\n        {\n            test(1 * sign, FracSec(10_000 * sign));\n            test(999 * sign, FracSec(9_990_000 * sign));\n        }\n\n        foreach (F; _TypeTuple!(const FracSec, immutable FracSec))\n        {\n            F fs = FracSec(1234567);\n            static assert(!__traits(compiles, fs.msecs = 12), F.stringof);\n        }\n    }\n\n\n    /++\n        The value of this $(D FracSec) as microseconds.\n      +/\n    @property int usecs() const nothrow @nogc\n    {\n        return cast(int)convert!(\"hnsecs\", \"usecs\")(_hnsecs);\n    }\n\n    unittest\n    {\n        foreach (F; _TypeTuple!(FracSec, const FracSec, immutable FracSec))\n        {\n            assert(FracSec(0).usecs == 0);\n\n            foreach (sign; [1, -1])\n            {\n                assert((cast(F)FracSec(1 * sign)).usecs == 0);\n                assert((cast(F)FracSec(999 * sign)).usecs == 99 * sign);\n                assert((cast(F)FracSec(999_999 * sign)).usecs == 99_999 * sign);\n                assert((cast(F)FracSec(9_999_999 * sign)).usecs == 999_999 * sign);\n            }\n        }\n    }\n\n\n    /++\n        The value of this $(D FracSec) as microseconds.\n\n        Params:\n            microseconds = The number of microseconds passed the second.\n\n        Throws:\n            $(D TimeException) if the given value is not less than $(D 1) second\n            and greater than a $(D -1) seconds.\n      +/\n    @property void usecs(int microseconds)\n    {\n        immutable hnsecs = cast(int)convert!(\"usecs\", \"hnsecs\")(microseconds);\n        _enforceValid(hnsecs);\n        _hnsecs = hnsecs;\n    }\n\n    unittest\n    {\n        static void test(int usecs, FracSec expected = FracSec.init, size_t line = __LINE__)\n        {\n            FracSec fs;\n            fs.usecs = usecs;\n\n            if (fs != expected)\n                throw new AssertError(\"unittest failure\", __FILE__, line);\n        }\n\n        _assertThrown!TimeException(test(-1_000_000));\n        _assertThrown!TimeException(test(1_000_000));\n\n        test(0, FracSec(0));\n\n        foreach (sign; [1, -1])\n        {\n            test(1 * sign, FracSec(10 * sign));\n            test(999 * sign, FracSec(9990 * sign));\n            test(999_999 * sign, FracSec(9_999_990 * sign));\n        }\n\n        foreach (F; _TypeTuple!(const FracSec, immutable FracSec))\n        {\n            F fs = FracSec(1234567);\n            static assert(!__traits(compiles, fs.usecs = 12), F.stringof);\n        }\n    }\n\n\n    /++\n        The value of this $(D FracSec) as hnsecs.\n      +/\n    @property int hnsecs() const nothrow @nogc\n    {\n        return _hnsecs;\n    }\n\n    unittest\n    {\n        foreach (F; _TypeTuple!(FracSec, const FracSec, immutable FracSec))\n        {\n            assert(FracSec(0).hnsecs == 0);\n\n            foreach (sign; [1, -1])\n            {\n                assert((cast(F)FracSec(1 * sign)).hnsecs == 1 * sign);\n                assert((cast(F)FracSec(999 * sign)).hnsecs == 999 * sign);\n                assert((cast(F)FracSec(999_999 * sign)).hnsecs == 999_999 * sign);\n                assert((cast(F)FracSec(9_999_999 * sign)).hnsecs == 9_999_999 * sign);\n            }\n        }\n    }\n\n\n    /++\n        The value of this $(D FracSec) as hnsecs.\n\n        Params:\n            hnsecs = The number of hnsecs passed the second.\n\n        Throws:\n            $(D TimeException) if the given value is not less than $(D 1) second\n            and greater than a $(D -1) seconds.\n      +/\n    @property void hnsecs(int hnsecs)\n    {\n        _enforceValid(hnsecs);\n        _hnsecs = hnsecs;\n    }\n\n    unittest\n    {\n        static void test(int hnsecs, FracSec expected = FracSec.init, size_t line = __LINE__)\n        {\n            FracSec fs;\n            fs.hnsecs = hnsecs;\n\n            if (fs != expected)\n                throw new AssertError(\"unittest failure\", __FILE__, line);\n        }\n\n        _assertThrown!TimeException(test(-10_000_000));\n        _assertThrown!TimeException(test(10_000_000));\n\n        test(0, FracSec(0));\n\n        foreach (sign; [1, -1])\n        {\n            test(1 * sign, FracSec(1 * sign));\n            test(999 * sign, FracSec(999 * sign));\n            test(999_999 * sign, FracSec(999_999 * sign));\n            test(9_999_999 * sign, FracSec(9_999_999 * sign));\n        }\n\n        foreach (F; _TypeTuple!(const FracSec, immutable FracSec))\n        {\n            F fs = FracSec(1234567);\n            static assert(!__traits(compiles, fs.hnsecs = 12), F.stringof);\n        }\n    }\n\n\n    /++\n        The value of this $(D FracSec) as nsecs.\n\n        Note that this does not give you any greater precision\n        than getting the value of this $(D FracSec) as hnsecs.\n      +/\n    @property int nsecs() const nothrow @nogc\n    {\n        return cast(int)convert!(\"hnsecs\", \"nsecs\")(_hnsecs);\n    }\n\n    unittest\n    {\n        foreach (F; _TypeTuple!(FracSec, const FracSec, immutable FracSec))\n        {\n            assert(FracSec(0).nsecs == 0);\n\n            foreach (sign; [1, -1])\n            {\n                assert((cast(F)FracSec(1 * sign)).nsecs == 100 * sign);\n                assert((cast(F)FracSec(999 * sign)).nsecs == 99_900 * sign);\n                assert((cast(F)FracSec(999_999 * sign)).nsecs == 99_999_900 * sign);\n                assert((cast(F)FracSec(9_999_999 * sign)).nsecs == 999_999_900 * sign);\n            }\n        }\n    }\n\n\n    /++\n        The value of this $(D FracSec) as nsecs.\n\n        Note that this does not give you any greater precision\n        than setting the value of this $(D FracSec) as hnsecs.\n\n        Params:\n            nsecs = The number of nsecs passed the second.\n\n        Throws:\n            $(D TimeException) if the given value is not less than $(D 1) second\n            and greater than a $(D -1) seconds.\n      +/\n    @property void nsecs(long nsecs)\n    {\n        immutable hnsecs = cast(int)convert!(\"nsecs\", \"hnsecs\")(nsecs);\n        _enforceValid(hnsecs);\n        _hnsecs = hnsecs;\n    }\n\n    unittest\n    {\n        static void test(int nsecs, FracSec expected = FracSec.init, size_t line = __LINE__)\n        {\n            FracSec fs;\n            fs.nsecs = nsecs;\n\n            if (fs != expected)\n                throw new AssertError(\"unittest failure\", __FILE__, line);\n        }\n\n        _assertThrown!TimeException(test(-1_000_000_000));\n        _assertThrown!TimeException(test(1_000_000_000));\n\n        test(0, FracSec(0));\n\n        foreach (sign; [1, -1])\n        {\n            test(1 * sign, FracSec(0));\n            test(10 * sign, FracSec(0));\n            test(100 * sign, FracSec(1 * sign));\n            test(999 * sign, FracSec(9 * sign));\n            test(999_999 * sign, FracSec(9999 * sign));\n            test(9_999_999 * sign, FracSec(99_999 * sign));\n        }\n\n        foreach (F; _TypeTuple!(const FracSec, immutable FracSec))\n        {\n            F fs = FracSec(1234567);\n            static assert(!__traits(compiles, fs.nsecs = 12), F.stringof);\n        }\n    }\n\n\n    /+\n        Converts this $(D TickDuration) to a string.\n      +/\n    //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't\n    //have versions of toString() with extra modifiers, so we define one version\n    //with modifiers and one without.\n    string toString()\n    {\n        return _toStringImpl();\n    }\n\n\n    /++\n        Converts this $(D TickDuration) to a string.\n      +/\n    //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't\n    //have versions of toString() with extra modifiers, so we define one version\n    //with modifiers and one without.\n    string toString() const nothrow\n    {\n        return _toStringImpl();\n    }\n\n    unittest\n    {\n        auto fs = FracSec(12);\n        const cfs = FracSec(12);\n        immutable ifs = FracSec(12);\n        assert(fs.toString() == \"12 hnsecs\");\n        assert(cfs.toString() == \"12 hnsecs\");\n        assert(ifs.toString() == \"12 hnsecs\");\n    }\n\n\nprivate:\n\n    /+\n        Since we have two versions of $(D toString), we have $(D _toStringImpl)\n        so that they can share implementations.\n      +/\n    string _toStringImpl() const nothrow\n    {\n        long hnsecs = _hnsecs;\n\n        immutable milliseconds = splitUnitsFromHNSecs!\"msecs\"(hnsecs);\n        immutable microseconds = splitUnitsFromHNSecs!\"usecs\"(hnsecs);\n\n        if (hnsecs == 0)\n        {\n            if (microseconds == 0)\n            {\n                if (milliseconds == 0)\n                    return \"0 hnsecs\";\n                else\n                {\n                    if (milliseconds == 1)\n                        return \"1 ms\";\n                    else\n                    {\n                        auto r = signedToTempString(milliseconds, 10).idup;\n                        r ~= \" ms\";\n                        return r;\n                    }\n                }\n            }\n            else\n            {\n                immutable fullMicroseconds = getUnitsFromHNSecs!\"usecs\"(_hnsecs);\n\n                if (fullMicroseconds == 1)\n                    return \"1 μs\";\n                else\n                {\n                    auto r = signedToTempString(fullMicroseconds, 10).idup;\n                    r ~= \" μs\";\n                    return r;\n                }\n            }\n        }\n        else\n        {\n            if (_hnsecs == 1)\n                return \"1 hnsec\";\n            else\n            {\n                auto r = signedToTempString(_hnsecs, 10).idup;\n                r ~= \" hnsecs\";\n                return r;\n            }\n        }\n    }\n\n    unittest\n    {\n        foreach (sign; [1 , -1])\n        {\n            immutable signStr = sign == 1 ? \"\" : \"-\";\n\n            assert(FracSec.from!\"msecs\"(0 * sign).toString() == \"0 hnsecs\");\n            assert(FracSec.from!\"msecs\"(1 * sign).toString() == signStr ~ \"1 ms\");\n            assert(FracSec.from!\"msecs\"(2 * sign).toString() == signStr ~ \"2 ms\");\n            assert(FracSec.from!\"msecs\"(100 * sign).toString() == signStr ~ \"100 ms\");\n            assert(FracSec.from!\"msecs\"(999 * sign).toString() == signStr ~ \"999 ms\");\n\n            assert(FracSec.from!\"usecs\"(0* sign).toString() == \"0 hnsecs\");\n            assert(FracSec.from!\"usecs\"(1* sign).toString() == signStr ~ \"1 μs\");\n            assert(FracSec.from!\"usecs\"(2* sign).toString() == signStr ~ \"2 μs\");\n            assert(FracSec.from!\"usecs\"(100* sign).toString() == signStr ~ \"100 μs\");\n            assert(FracSec.from!\"usecs\"(999* sign).toString() == signStr ~ \"999 μs\");\n            assert(FracSec.from!\"usecs\"(1000* sign).toString() == signStr ~ \"1 ms\");\n            assert(FracSec.from!\"usecs\"(2000* sign).toString() == signStr ~ \"2 ms\");\n            assert(FracSec.from!\"usecs\"(9999* sign).toString() == signStr ~ \"9999 μs\");\n            assert(FracSec.from!\"usecs\"(10_000* sign).toString() == signStr ~ \"10 ms\");\n            assert(FracSec.from!\"usecs\"(20_000* sign).toString() == signStr ~ \"20 ms\");\n            assert(FracSec.from!\"usecs\"(100_000* sign).toString() == signStr ~ \"100 ms\");\n            assert(FracSec.from!\"usecs\"(100_001* sign).toString() == signStr ~ \"100001 μs\");\n            assert(FracSec.from!\"usecs\"(999_999* sign).toString() == signStr ~ \"999999 μs\");\n\n            assert(FracSec.from!\"hnsecs\"(0* sign).toString() == \"0 hnsecs\");\n            assert(FracSec.from!\"hnsecs\"(1* sign).toString() == (sign == 1 ? \"1 hnsec\" : \"-1 hnsecs\"));\n            assert(FracSec.from!\"hnsecs\"(2* sign).toString() == signStr ~ \"2 hnsecs\");\n            assert(FracSec.from!\"hnsecs\"(100* sign).toString() == signStr ~ \"10 μs\");\n            assert(FracSec.from!\"hnsecs\"(999* sign).toString() == signStr ~ \"999 hnsecs\");\n            assert(FracSec.from!\"hnsecs\"(1000* sign).toString() == signStr ~ \"100 μs\");\n            assert(FracSec.from!\"hnsecs\"(2000* sign).toString() == signStr ~ \"200 μs\");\n            assert(FracSec.from!\"hnsecs\"(9999* sign).toString() == signStr ~ \"9999 hnsecs\");\n            assert(FracSec.from!\"hnsecs\"(10_000* sign).toString() == signStr ~ \"1 ms\");\n            assert(FracSec.from!\"hnsecs\"(20_000* sign).toString() == signStr ~ \"2 ms\");\n            assert(FracSec.from!\"hnsecs\"(100_000* sign).toString() == signStr ~ \"10 ms\");\n            assert(FracSec.from!\"hnsecs\"(100_001* sign).toString() == signStr ~ \"100001 hnsecs\");\n            assert(FracSec.from!\"hnsecs\"(200_000* sign).toString() == signStr ~ \"20 ms\");\n            assert(FracSec.from!\"hnsecs\"(999_999* sign).toString() == signStr ~ \"999999 hnsecs\");\n            assert(FracSec.from!\"hnsecs\"(1_000_001* sign).toString() == signStr ~ \"1000001 hnsecs\");\n            assert(FracSec.from!\"hnsecs\"(9_999_999* sign).toString() == signStr ~ \"9999999 hnsecs\");\n        }\n    }\n\n\n    /+\n        Returns whether the given number of hnsecs fits within the range of\n        $(D FracSec).\n\n        Params:\n            hnsecs = The number of hnsecs.\n      +/\n    static bool _valid(int hnsecs) nothrow @nogc\n    {\n        immutable second = convert!(\"seconds\", \"hnsecs\")(1);\n        return hnsecs > -second && hnsecs < second;\n    }\n\n\n    /+\n        Throws:\n            $(D TimeException) if $(D valid(hnsecs)) is $(D false).\n      +/\n    static void _enforceValid(int hnsecs)\n    {\n        if (!_valid(hnsecs))\n            throw new TimeException(\"FracSec must be greater than equal to 0 and less than 1 second.\");\n    }\n\n\n    /+\n        Params:\n            hnsecs = The number of hnsecs passed the second.\n      +/\n    this(int hnsecs) nothrow @nogc\n    {\n        _hnsecs = hnsecs;\n    }\n\n\n    invariant()\n    {\n        if (!_valid(_hnsecs))\n            throw new AssertError(\"Invariant Failure: hnsecs [\" ~ signedToTempString(_hnsecs, 10).idup ~ \"]\", __FILE__, __LINE__);\n    }\n\n\n    int _hnsecs;\n}\n\n\n/++\n    Exception type used by core.time.\n  +/\nclass TimeException : Exception\n{\n    /++\n        Params:\n            msg  = The message for the exception.\n            file = The file where the exception occurred.\n            line = The line number where the exception occurred.\n            next = The previous exception in the chain of exceptions, if any.\n      +/\n    this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) @safe pure nothrow\n    {\n        super(msg, file, line, next);\n    }\n\n    /++\n        Params:\n            msg  = The message for the exception.\n            next = The previous exception in the chain of exceptions.\n            file = The file where the exception occurred.\n            line = The line number where the exception occurred.\n      +/\n    this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__) @safe pure nothrow\n    {\n        super(msg, file, line, next);\n    }\n}\n\nunittest\n{\n    {\n        auto e = new TimeException(\"hello\");\n        assert(e.msg == \"hello\");\n        assert(e.file == __FILE__);\n        assert(e.line == __LINE__ - 3);\n        assert(e.next is null);\n    }\n\n    {\n        auto next = new Exception(\"foo\");\n        auto e = new TimeException(\"goodbye\", next);\n        assert(e.msg == \"goodbye\");\n        assert(e.file == __FILE__);\n        assert(e.line == __LINE__ - 3);\n        assert(e.next is next);\n    }\n}\n\n\n\n/++\n    Returns the absolute value of a duration.\n  +/\nDuration abs(Duration duration) @safe pure nothrow @nogc\n{\n    return Duration(_abs(duration._hnsecs));\n}\n\n/++ Ditto +/\nTickDuration abs(TickDuration duration) @safe pure nothrow @nogc\n{\n    return TickDuration(_abs(duration.length));\n}\n\nunittest\n{\n    assert(abs(dur!\"msecs\"(5)) == dur!\"msecs\"(5));\n    assert(abs(dur!\"msecs\"(-5)) == dur!\"msecs\"(5));\n\n    assert(abs(TickDuration(17)) == TickDuration(17));\n    assert(abs(TickDuration(-17)) == TickDuration(17));\n}\n\n\n//==============================================================================\n// Private Section.\n//\n// Much of this is a copy or simplified copy of what's in std.datetime.\n//==============================================================================\nprivate:\n\n\n/+\n    Template to help with converting between time units.\n +/\ntemplate hnsecsPer(string units)\n    if (units == \"weeks\" ||\n       units == \"days\" ||\n       units == \"hours\" ||\n       units == \"minutes\" ||\n       units == \"seconds\" ||\n       units == \"msecs\" ||\n       units == \"usecs\" ||\n       units == \"hnsecs\")\n{\n    static if (units == \"hnsecs\")\n        enum hnsecsPer = 1L;\n    else static if (units == \"usecs\")\n        enum hnsecsPer = 10L;\n    else static if (units == \"msecs\")\n        enum hnsecsPer = 1000 * hnsecsPer!\"usecs\";\n    else static if (units == \"seconds\")\n        enum hnsecsPer = 1000 * hnsecsPer!\"msecs\";\n    else static if (units == \"minutes\")\n        enum hnsecsPer = 60 * hnsecsPer!\"seconds\";\n    else static if (units == \"hours\")\n        enum hnsecsPer = 60 * hnsecsPer!\"minutes\";\n    else static if (units == \"days\")\n        enum hnsecsPer = 24 * hnsecsPer!\"hours\";\n    else static if (units == \"weeks\")\n        enum hnsecsPer = 7 * hnsecsPer!\"days\";\n}\n\n/+\n    Splits out a particular unit from hnsecs and gives you the value for that\n    unit and the remaining hnsecs. It really shouldn't be used unless all units\n    larger than the given units have already been split out.\n\n    Params:\n        units  = The units to split out.\n        hnsecs = The current total hnsecs. Upon returning, it is the hnsecs left\n                 after splitting out the given units.\n\n    Returns:\n        The number of the given units from converting hnsecs to those units.\n  +/\nlong splitUnitsFromHNSecs(string units)(ref long hnsecs) @safe pure nothrow @nogc\n    if (units == \"weeks\" ||\n       units == \"days\" ||\n       units == \"hours\" ||\n       units == \"minutes\" ||\n       units == \"seconds\" ||\n       units == \"msecs\" ||\n       units == \"usecs\" ||\n       units == \"hnsecs\")\n{\n    immutable value = convert!(\"hnsecs\", units)(hnsecs);\n    hnsecs -= convert!(units, \"hnsecs\")(value);\n\n    return value;\n}\n\n///\nunittest\n{\n    auto hnsecs = 2595000000007L;\n    immutable days = splitUnitsFromHNSecs!\"days\"(hnsecs);\n    assert(days == 3);\n    assert(hnsecs == 3000000007);\n\n    immutable minutes = splitUnitsFromHNSecs!\"minutes\"(hnsecs);\n    assert(minutes == 5);\n    assert(hnsecs == 7);\n}\n\n\n/+\n    This function is used to split out the units without getting the remaining\n    hnsecs.\n\n    See_Also:\n        $(LREF splitUnitsFromHNSecs)\n\n    Params:\n        units  = The units to split out.\n        hnsecs = The current total hnsecs.\n\n    Returns:\n        The split out value.\n  +/\nlong getUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow @nogc\n    if (units == \"weeks\" ||\n       units == \"days\" ||\n       units == \"hours\" ||\n       units == \"minutes\" ||\n       units == \"seconds\" ||\n       units == \"msecs\" ||\n       units == \"usecs\" ||\n       units == \"hnsecs\")\n{\n    return convert!(\"hnsecs\", units)(hnsecs);\n}\n\n///\nunittest\n{\n    auto hnsecs = 2595000000007L;\n    immutable days = getUnitsFromHNSecs!\"days\"(hnsecs);\n    assert(days == 3);\n    assert(hnsecs == 2595000000007L);\n}\n\n\n/+\n    This function is used to split out the units without getting the units but\n    just the remaining hnsecs.\n\n    See_Also:\n        $(LREF splitUnitsFromHNSecs)\n\n    Params:\n        units  = The units to split out.\n        hnsecs = The current total hnsecs.\n\n    Returns:\n        The remaining hnsecs.\n  +/\nlong removeUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow @nogc\n    if (units == \"weeks\" ||\n       units == \"days\" ||\n       units == \"hours\" ||\n       units == \"minutes\" ||\n       units == \"seconds\" ||\n       units == \"msecs\" ||\n       units == \"usecs\" ||\n       units == \"hnsecs\")\n{\n    immutable value = convert!(\"hnsecs\", units)(hnsecs);\n\n    return hnsecs - convert!(units, \"hnsecs\")(value);\n}\n\n///\nunittest\n{\n    auto hnsecs = 2595000000007L;\n    auto returned = removeUnitsFromHNSecs!\"days\"(hnsecs);\n    assert(returned == 3000000007);\n    assert(hnsecs == 2595000000007L);\n}\n\n\n/+\n    Whether all of the given strings are among the accepted strings.\n  +/\nbool allAreAcceptedUnits(acceptedUnits...)(string[] units...)\n{\n    foreach (unit; units)\n    {\n        bool found = false;\n        foreach (acceptedUnit; acceptedUnits)\n        {\n            if (unit == acceptedUnit)\n            {\n                found = true;\n                break;\n            }\n        }\n        if (!found)\n            return false;\n    }\n    return true;\n}\n\nunittest\n{\n    assert(allAreAcceptedUnits!(\"hours\", \"seconds\")(\"seconds\", \"hours\"));\n    assert(!allAreAcceptedUnits!(\"hours\", \"seconds\")(\"minutes\", \"hours\"));\n    assert(!allAreAcceptedUnits!(\"hours\", \"seconds\")(\"seconds\", \"minutes\"));\n    assert(allAreAcceptedUnits!(\"days\", \"hours\", \"minutes\", \"seconds\", \"msecs\")(\"minutes\"));\n    assert(!allAreAcceptedUnits!(\"days\", \"hours\", \"minutes\", \"seconds\", \"msecs\")(\"usecs\"));\n    assert(!allAreAcceptedUnits!(\"days\", \"hours\", \"minutes\", \"seconds\", \"msecs\")(\"secs\"));\n}\n\n\n/+\n    Whether the given time unit strings are arranged in order from largest to\n    smallest.\n  +/\nbool unitsAreInDescendingOrder(string[] units...)\n{\n    if (units.length <= 1)\n        return true;\n\n    immutable string[] timeStrings = [\"nsecs\", \"hnsecs\", \"usecs\", \"msecs\", \"seconds\",\n                                      \"minutes\", \"hours\", \"days\", \"weeks\", \"months\", \"years\"];\n    size_t currIndex = 42;\n    foreach (i, timeStr; timeStrings)\n    {\n        if (units[0] == timeStr)\n        {\n            currIndex = i;\n            break;\n        }\n    }\n    assert(currIndex != 42);\n\n    foreach (unit; units[1 .. $])\n    {\n        size_t nextIndex = 42;\n        foreach (i, timeStr; timeStrings)\n        {\n            if (unit == timeStr)\n            {\n                nextIndex = i;\n                break;\n            }\n        }\n        assert(nextIndex != 42);\n\n        if (currIndex <= nextIndex)\n            return false;\n        currIndex = nextIndex;\n    }\n    return true;\n}\n\nunittest\n{\n    assert(unitsAreInDescendingOrder(\"years\", \"months\", \"weeks\", \"days\", \"hours\", \"minutes\",\n                                     \"seconds\", \"msecs\", \"usecs\", \"hnsecs\", \"nsecs\"));\n    assert(unitsAreInDescendingOrder(\"weeks\", \"hours\", \"msecs\"));\n    assert(unitsAreInDescendingOrder(\"days\", \"hours\", \"minutes\"));\n    assert(unitsAreInDescendingOrder(\"hnsecs\"));\n    assert(!unitsAreInDescendingOrder(\"days\", \"hours\", \"hours\"));\n    assert(!unitsAreInDescendingOrder(\"days\", \"hours\", \"days\"));\n}\n\n\n/+\n    The time units which are one step larger than the given units.\n  +/\ntemplate nextLargerTimeUnits(string units)\n    if (units == \"days\" ||\n       units == \"hours\" ||\n       units == \"minutes\" ||\n       units == \"seconds\" ||\n       units == \"msecs\" ||\n       units == \"usecs\" ||\n       units == \"hnsecs\" ||\n       units == \"nsecs\")\n{\n    static if (units == \"days\")\n        enum nextLargerTimeUnits = \"weeks\";\n    else static if (units == \"hours\")\n        enum nextLargerTimeUnits = \"days\";\n    else static if (units == \"minutes\")\n        enum nextLargerTimeUnits = \"hours\";\n    else static if (units == \"seconds\")\n        enum nextLargerTimeUnits = \"minutes\";\n    else static if (units == \"msecs\")\n        enum nextLargerTimeUnits = \"seconds\";\n    else static if (units == \"usecs\")\n        enum nextLargerTimeUnits = \"msecs\";\n    else static if (units == \"hnsecs\")\n        enum nextLargerTimeUnits = \"usecs\";\n    else static if (units == \"nsecs\")\n        enum nextLargerTimeUnits = \"hnsecs\";\n    else\n        static assert(0, \"Broken template constraint\");\n}\n\n///\nunittest\n{\n    assert(nextLargerTimeUnits!\"minutes\" == \"hours\");\n    assert(nextLargerTimeUnits!\"hnsecs\" == \"usecs\");\n}\n\nunittest\n{\n    assert(nextLargerTimeUnits!\"nsecs\" == \"hnsecs\");\n    assert(nextLargerTimeUnits!\"hnsecs\" == \"usecs\");\n    assert(nextLargerTimeUnits!\"usecs\" == \"msecs\");\n    assert(nextLargerTimeUnits!\"msecs\" == \"seconds\");\n    assert(nextLargerTimeUnits!\"seconds\" == \"minutes\");\n    assert(nextLargerTimeUnits!\"minutes\" == \"hours\");\n    assert(nextLargerTimeUnits!\"hours\" == \"days\");\n    assert(nextLargerTimeUnits!\"days\" == \"weeks\");\n\n    static assert(!__traits(compiles, nextLargerTimeUnits!\"weeks\"));\n    static assert(!__traits(compiles, nextLargerTimeUnits!\"months\"));\n    static assert(!__traits(compiles, nextLargerTimeUnits!\"years\"));\n}\n\nversion (Darwin)\nlong machTicksPerSecond()\n{\n    // Be optimistic that ticksPerSecond (1e9*denom/numer) is integral. So far\n    // so good on Darwin based platforms OS X, iOS.\n    import core.internal.abort : abort;\n    mach_timebase_info_data_t info;\n    if (mach_timebase_info(&info) != 0)\n        abort(\"Failed in mach_timebase_info().\");\n\n    long scaledDenom = 1_000_000_000L * info.denom;\n    if (scaledDenom % info.numer != 0)\n        abort(\"Non integral ticksPerSecond from mach_timebase_info.\");\n    return scaledDenom / info.numer;\n}\n\n/+\n    Local version of abs, since std.math.abs is in Phobos, not druntime.\n  +/\nlong _abs(long val) @safe pure nothrow @nogc\n{\n    return val >= 0 ? val : -val;\n}\n\ndouble _abs(double val) @safe pure nothrow @nogc\n{\n    return val >= 0.0 ? val : -val;\n}\n\n\nversion (unittest)\nstring doubleToString(double value) @safe pure nothrow\n{\n    string result;\n    if (value < 0 && cast(long)value == 0)\n        result = \"-0\";\n    else\n        result = signedToTempString(cast(long)value, 10).idup;\n    result ~= '.';\n    result ~= unsignedToTempString(cast(ulong)(_abs((value - cast(long)value) * 1_000_000) + .5), 10);\n\n    while (result[$-1] == '0')\n        result = result[0 .. $-1];\n    return result;\n}\n\nunittest\n{\n    auto a = 1.337;\n    auto aStr = doubleToString(a);\n    assert(aStr == \"1.337\", aStr);\n\n    a = 0.337;\n    aStr = doubleToString(a);\n    assert(aStr == \"0.337\", aStr);\n\n    a = -0.337;\n    aStr = doubleToString(a);\n    assert(aStr == \"-0.337\", aStr);\n}\n\nversion (unittest) const(char)* numToStringz()(long value) @trusted pure nothrow\n{\n    return (signedToTempString(value, 10) ~ \"\\0\").ptr;\n}\n\n\n/+ A copy of std.typecons.TypeTuple. +/\ntemplate _TypeTuple(TList...)\n{\n    alias TList _TypeTuple;\n}\n\n\n/+ An adjusted copy of std.exception.assertThrown. +/\nversion (unittest) void _assertThrown(T : Throwable = Exception, E)\n                                    (lazy E expression,\n                                     string msg = null,\n                                     string file = __FILE__,\n                                     size_t line = __LINE__)\n{\n    bool thrown = false;\n\n    try\n        expression();\n    catch (T t)\n        thrown = true;\n\n    if (!thrown)\n    {\n        immutable tail = msg.length == 0 ? \".\" : \": \" ~ msg;\n\n        throw new AssertError(\"assertThrown() failed: No \" ~ T.stringof ~ \" was thrown\" ~ tail, file, line);\n    }\n}\n\nunittest\n{\n\n    void throwEx(Throwable t)\n    {\n        throw t;\n    }\n\n    void nothrowEx()\n    {}\n\n    try\n        _assertThrown!Exception(throwEx(new Exception(\"It's an Exception\")));\n    catch (AssertError)\n        assert(0);\n\n    try\n        _assertThrown!Exception(throwEx(new Exception(\"It's an Exception\")), \"It's a message\");\n    catch (AssertError)\n        assert(0);\n\n    try\n        _assertThrown!AssertError(throwEx(new AssertError(\"It's an AssertError\", __FILE__, __LINE__)));\n    catch (AssertError)\n        assert(0);\n\n    try\n        _assertThrown!AssertError(throwEx(new AssertError(\"It's an AssertError\", __FILE__, __LINE__)), \"It's a message\");\n    catch (AssertError)\n        assert(0);\n\n\n    {\n        bool thrown = false;\n        try\n            _assertThrown!Exception(nothrowEx());\n        catch (AssertError)\n            thrown = true;\n\n        assert(thrown);\n    }\n\n    {\n        bool thrown = false;\n        try\n            _assertThrown!Exception(nothrowEx(), \"It's a message\");\n        catch (AssertError)\n            thrown = true;\n\n        assert(thrown);\n    }\n\n    {\n        bool thrown = false;\n        try\n            _assertThrown!AssertError(nothrowEx());\n        catch (AssertError)\n            thrown = true;\n\n        assert(thrown);\n    }\n\n    {\n        bool thrown = false;\n        try\n            _assertThrown!AssertError(nothrowEx(), \"It's a message\");\n        catch (AssertError)\n            thrown = true;\n\n        assert(thrown);\n    }\n}\n\n\nversion (unittest) void assertApprox(D, E)(D actual,\n                                          E lower,\n                                          E upper,\n                                          string msg = \"unittest failure\",\n                                          size_t line = __LINE__)\n    if (is(D : const Duration) && is(E : const Duration))\n{\n    if (actual < lower)\n        throw new AssertError(msg ~ \": lower: \" ~ actual.toString(), __FILE__, line);\n    if (actual > upper)\n        throw new AssertError(msg ~ \": upper: \" ~ actual.toString(), __FILE__, line);\n}\n\nversion (unittest) void assertApprox(D, E)(D actual,\n                                          E lower,\n                                          E upper,\n                                          string msg = \"unittest failure\",\n                                          size_t line = __LINE__)\n    if (is(D : const TickDuration) && is(E : const TickDuration))\n{\n    if (actual.length < lower.length || actual.length > upper.length)\n    {\n        throw new AssertError(msg ~ (\": [\" ~ signedToTempString(lower.length, 10) ~ \"] [\" ~\n                              signedToTempString(actual.length, 10) ~ \"] [\" ~\n                              signedToTempString(upper.length, 10) ~ \"]\").idup,\n                              __FILE__, line);\n    }\n}\n\nversion (unittest) void assertApprox(MT)(MT actual,\n                                        MT lower,\n                                        MT upper,\n                                        string msg = \"unittest failure\",\n                                        size_t line = __LINE__)\n    if (is(MT == MonoTimeImpl!type, ClockType type))\n{\n    assertApprox(actual._ticks, lower._ticks, upper._ticks, msg, line);\n}\n\nversion (unittest) void assertApprox()(long actual,\n                                      long lower,\n                                      long upper,\n                                      string msg = \"unittest failure\",\n                                      size_t line = __LINE__)\n{\n    if (actual < lower)\n        throw new AssertError(msg ~ \": lower: \" ~ signedToTempString(actual, 10).idup, __FILE__, line);\n    if (actual > upper)\n        throw new AssertError(msg ~ \": upper: \" ~ signedToTempString(actual, 10).idup, __FILE__, line);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/core/vararg.d",
    "content": "/**\n * The vararg module is intended to facilitate vararg manipulation in D.\n * It should be interface compatible with the C module \"stdarg,\" and the\n * two modules may share a common implementation if possible (as is done\n * here).\n * Copyright: Copyright Digital Mars 2000 - 2009.\n * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)\n * Authors:   Walter Bright, Hauke Duden\n * Source:    $(DRUNTIMESRC core/_vararg.d)\n */\n\n/*          Copyright Digital Mars 2000 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule core.vararg;\n\npublic import core.stdc.stdarg;\n"
  },
  {
    "path": "libphobos/libdruntime/gc/bits.d",
    "content": "/**\n * Contains a bitfield used by the GC.\n *\n * Copyright: Copyright Digital Mars 2005 - 2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, David Friedman, Sean Kelly\n */\n\n/*          Copyright Digital Mars 2005 - 2013.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule gc.bits;\n\n\nimport core.bitop;\nimport core.stdc.string;\nimport core.stdc.stdlib;\nimport core.exception : onOutOfMemoryError;\n\nstruct GCBits\n{\n    alias size_t wordtype;\n\n    enum BITS_PER_WORD = (wordtype.sizeof * 8);\n    enum BITS_SHIFT = (wordtype.sizeof == 8 ? 6 : 5);\n    enum BITS_MASK = (BITS_PER_WORD - 1);\n    enum BITS_1 = cast(wordtype)1;\n\n    wordtype* data;\n    size_t nbits;\n\n    void Dtor() nothrow\n    {\n        if (data)\n        {\n            free(data);\n            data = null;\n        }\n    }\n\n    void alloc(size_t nbits) nothrow\n    {\n        this.nbits = nbits;\n        data = cast(typeof(data[0])*)calloc(nwords, data[0].sizeof);\n        if (!data)\n            onOutOfMemoryError();\n    }\n\n    wordtype test(size_t i) const nothrow\n    in\n    {\n        assert(i < nbits);\n    }\n    do\n    {\n        return core.bitop.bt(data, i);\n    }\n\n    int set(size_t i) nothrow\n    in\n    {\n        assert(i < nbits);\n    }\n    do\n    {\n        return core.bitop.bts(data, i);\n    }\n\n    int clear(size_t i) nothrow\n    in\n    {\n        assert(i <= nbits);\n    }\n    do\n    {\n        return core.bitop.btr(data, i);\n    }\n\n    void zero() nothrow\n    {\n        memset(data, 0, nwords * wordtype.sizeof);\n    }\n\n    void copy(GCBits *f) nothrow\n    in\n    {\n        assert(nwords == f.nwords);\n    }\n    do\n    {\n        memcpy(data, f.data, nwords * wordtype.sizeof);\n    }\n\n    @property size_t nwords() const pure nothrow\n    {\n        return (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT;\n    }\n}\n\nunittest\n{\n    GCBits b;\n\n    b.alloc(786);\n    assert(!b.test(123));\n    assert(!b.clear(123));\n    assert(!b.set(123));\n    assert(b.test(123));\n    assert(b.clear(123));\n    assert(!b.test(123));\n\n    b.set(785);\n    b.set(0);\n    assert(b.test(785));\n    assert(b.test(0));\n    b.zero();\n    assert(!b.test(785));\n    assert(!b.test(0));\n\n    GCBits b2;\n    b2.alloc(786);\n    b2.set(38);\n    b.copy(&b2);\n    assert(b.test(38));\n    b2.Dtor();\n    b.Dtor();\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gc/config.d",
    "content": "/**\n* Contains the garbage collector configuration.\n*\n* Copyright: Copyright Digital Mars 2016\n* License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n*/\n\nmodule gc.config;\n\nimport core.stdc.stdio;\nimport core.internal.parseoptions;\n\n__gshared Config config;\n\nstruct Config\n{\n    bool disable;            // start disabled\n    ubyte profile;           // enable profiling with summary when terminating program\n    string gc = \"conservative\"; // select gc implementation conservative|manual\n\n    size_t initReserve;      // initial reserve (MB)\n    size_t minPoolSize = 1;  // initial and minimum pool size (MB)\n    size_t maxPoolSize = 64; // maximum pool size (MB)\n    size_t incPoolSize = 3;  // pool size increment (MB)\n    float heapSizeFactor = 2.0; // heap size to used memory ratio\n\n@nogc nothrow:\n\n    bool initialize()\n    {\n        return initConfigOptions(this, \"gcopt\");\n    }\n\n    void help() @nogc nothrow\n    {\n        string s = \"GC options are specified as whitespace separated assignments:\n    disable:0|1    - start disabled (%d)\n    profile:0|1|2  - enable profiling with summary when terminating program (%d)\n    gc:conservative|manual - select gc implementation (default = conservative)\n\n    initReserve:N  - initial memory to reserve in MB (%lld)\n    minPoolSize:N  - initial and minimum pool size in MB (%lld)\n    maxPoolSize:N  - maximum pool size in MB (%lld)\n    incPoolSize:N  - pool size increment MB (%lld)\n    heapSizeFactor:N - targeted heap size to used memory ratio (%g)\n\";\n        printf(s.ptr, disable, profile, cast(long)initReserve, cast(long)minPoolSize,\n               cast(long)maxPoolSize, cast(long)incPoolSize, heapSizeFactor);\n    }\n\n    string errorName() @nogc nothrow { return \"GC\"; }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gc/gcinterface.d",
    "content": "/**\n * Contains the internal GC interface.\n *\n * Copyright: Copyright Digital Mars 2016.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, Sean Kelly, Jeremy DeHaan\n */\n\n /*          Copyright Digital Mars 2016.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule gc.gcinterface;\n\nstatic import core.memory;\nalias BlkAttr = core.memory.GC.BlkAttr;\nalias BlkInfo = core.memory.GC.BlkInfo;\n\nalias RootIterator = int delegate(scope int delegate(ref Root) nothrow dg);\nalias RangeIterator = int delegate(scope int delegate(ref Range) nothrow dg);\n\n\nstruct Root\n{\n    void* proot;\n    alias proot this;\n}\n\nstruct Range\n{\n    void* pbot;\n    void* ptop;\n    TypeInfo ti; // should be tail const, but doesn't exist for references\n    alias pbot this; // only consider pbot for relative ordering (opCmp)\n}\n\ninterface GC\n{\n\n    /*\n     *\n     */\n    void Dtor();\n\n    /**\n     *\n     */\n    void enable();\n\n    /**\n     *\n     */\n    void disable();\n\n    /**\n     *\n     */\n    void collect() nothrow;\n\n    /**\n     *\n     */\n    void collectNoStack() nothrow;\n\n    /**\n     * minimize free space usage\n     */\n    void minimize() nothrow;\n\n    /**\n     *\n     */\n    uint getAttr(void* p) nothrow;\n\n    /**\n     *\n     */\n    uint setAttr(void* p, uint mask) nothrow;\n\n    /**\n     *\n     */\n    uint clrAttr(void* p, uint mask) nothrow;\n\n    /**\n     *\n     */\n    void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow;\n\n    /*\n     *\n     */\n    BlkInfo qalloc(size_t size, uint bits, const TypeInfo ti) nothrow;\n\n    /*\n     *\n     */\n    void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow;\n\n    /*\n     *\n     */\n    void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow;\n\n    /**\n     * Attempt to in-place enlarge the memory block pointed to by p by at least\n     * minsize bytes, up to a maximum of maxsize additional bytes.\n     * This does not attempt to move the memory block (like realloc() does).\n     *\n     * Returns:\n     *  0 if could not extend p,\n     *  total size of entire memory block if successful.\n     */\n    size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow;\n\n    /**\n     *\n     */\n    size_t reserve(size_t size) nothrow;\n\n    /**\n     *\n     */\n    void free(void* p) nothrow @nogc;\n\n    /**\n     * Determine the base address of the block containing p.  If p is not a gc\n     * allocated pointer, return null.\n     */\n    void* addrOf(void* p) nothrow @nogc;\n\n    /**\n     * Determine the allocated size of pointer p.  If p is an interior pointer\n     * or not a gc allocated pointer, return 0.\n     */\n    size_t sizeOf(void* p) nothrow @nogc;\n\n    /**\n     * Determine the base address of the block containing p.  If p is not a gc\n     * allocated pointer, return null.\n     */\n    BlkInfo query(void* p) nothrow;\n\n    /**\n     * Retrieve statistics about garbage collection.\n     * Useful for debugging and tuning.\n     */\n    core.memory.GC.Stats stats() nothrow;\n\n    /**\n     * add p to list of roots\n     */\n    void addRoot(void* p) nothrow @nogc;\n\n    /**\n     * remove p from list of roots\n     */\n    void removeRoot(void* p) nothrow @nogc;\n\n    /**\n     *\n     */\n    @property RootIterator rootIter() @nogc;\n\n    /**\n     * add range to scan for roots\n     */\n    void addRange(void* p, size_t sz, const TypeInfo ti) nothrow @nogc;\n\n    /**\n     * remove range\n     */\n    void removeRange(void* p) nothrow @nogc;\n\n    /**\n     *\n     */\n    @property RangeIterator rangeIter() @nogc;\n\n    /**\n     * run finalizers\n     */\n    void runFinalizers(in void[] segment) nothrow;\n\n    /*\n     *\n     */\n    bool inFinalizer() nothrow;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gc/impl/conservative/gc.d",
    "content": "/**\n * Contains the garbage collector implementation.\n *\n * Copyright: Copyright Digital Mars 2001 - 2016.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, David Friedman, Sean Kelly\n */\n\n/*          Copyright Digital Mars 2005 - 2016.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule gc.impl.conservative.gc;\n\n// D Programming Language Garbage Collector implementation\n\n/************** Debugging ***************************/\n\n//debug = PRINTF;               // turn on printf's\n//debug = COLLECT_PRINTF;       // turn on printf's\n//debug = PRINTF_TO_FILE;       // redirect printf's ouptut to file \"gcx.log\"\n//debug = LOGGING;              // log allocations / frees\n//debug = MEMSTOMP;             // stomp on memory\n//debug = SENTINEL;             // add underrun/overrrun protection\n                                // NOTE: this needs to be enabled globally in the makefiles\n                                // (-debug=SENTINEL) to pass druntime's unittests.\n//debug = PTRCHECK;             // more pointer checking\n//debug = PTRCHECK2;            // thorough but slow pointer checking\n//debug = INVARIANT;            // enable invariants\n//debug = PROFILE_API;          // profile API calls for config.profile > 1\n\n/*************** Configuration *********************/\n\nversion = STACKGROWSDOWN;       // growing the stack means subtracting from the stack pointer\n                                // (use for Intel X86 CPUs)\n                                // else growing the stack means adding to the stack pointer\n\n/***************************************************/\n\nimport gc.bits;\nimport gc.os;\nimport gc.config;\nimport gc.gcinterface;\n\nimport rt.util.container.treap;\n\nimport cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc;\nimport core.stdc.string : memcpy, memset, memmove;\nimport core.bitop;\nimport core.thread;\nstatic import core.memory;\n\nversion (GNU) import gcc.builtins;\n\ndebug (PRINTF_TO_FILE) import core.stdc.stdio : sprintf, fprintf, fopen, fflush, FILE;\nelse                   import core.stdc.stdio : sprintf, printf; // needed to output profiling results\n\nimport core.time;\nalias currTime = MonoTime.currTime;\n\ndebug(PRINTF_TO_FILE)\n{\n    private __gshared MonoTime gcStartTick;\n    private __gshared FILE* gcx_fh;\n\n    private int printf(ARGS...)(const char* fmt, ARGS args) nothrow\n    {\n        if (!gcx_fh)\n            gcx_fh = fopen(\"gcx.log\", \"w\");\n        if (!gcx_fh)\n            return 0;\n\n        int len;\n        if (MonoTime.ticksPerSecond == 0)\n        {\n            len = fprintf(gcx_fh, \"before init: \");\n        }\n        else\n        {\n            if (gcStartTick == MonoTime.init)\n                gcStartTick = MonoTime.currTime;\n            immutable timeElapsed = MonoTime.currTime - gcStartTick;\n            immutable secondsAsDouble = timeElapsed.total!\"hnsecs\" / cast(double)convert!(\"seconds\", \"hnsecs\")(1);\n            len = fprintf(gcx_fh, \"%10.6lf: \", secondsAsDouble);\n        }\n        len += fprintf(gcx_fh, fmt, args);\n        fflush(gcx_fh);\n        return len;\n    }\n}\n\ndebug(PRINTF) void printFreeInfo(Pool* pool) nothrow\n{\n    uint nReallyFree;\n    foreach (i; 0..pool.npages) {\n        if (pool.pagetable[i] >= B_FREE) nReallyFree++;\n    }\n\n    printf(\"Pool %p:  %d really free, %d supposedly free\\n\", pool, nReallyFree, pool.freepages);\n}\n\n// Track total time spent preparing for GC,\n// marking, sweeping and recovering pages.\n__gshared Duration prepTime;\n__gshared Duration markTime;\n__gshared Duration sweepTime;\n__gshared Duration recoverTime;\n__gshared Duration maxPauseTime;\n__gshared size_t numCollections;\n__gshared size_t maxPoolMemory;\n\n__gshared long numMallocs;\n__gshared long numFrees;\n__gshared long numReallocs;\n__gshared long numExtends;\n__gshared long numOthers;\n__gshared long mallocTime; // using ticks instead of MonoTime for better performance\n__gshared long freeTime;\n__gshared long reallocTime;\n__gshared long extendTime;\n__gshared long otherTime;\n__gshared long lockTime;\n\nprivate\n{\n    extern (C)\n    {\n        // to allow compilation of this module without access to the rt package,\n        //  make these functions available from rt.lifetime\n        void rt_finalizeFromGC(void* p, size_t size, uint attr) nothrow;\n        int rt_hasFinalizerInSegment(void* p, size_t size, uint attr, in void[] segment) nothrow;\n\n        // Declared as an extern instead of importing core.exception\n        // to avoid inlining - see issue 13725.\n        void onInvalidMemoryOperationError() @nogc nothrow;\n        void onOutOfMemoryErrorNoGC() @nogc nothrow;\n    }\n\n    enum\n    {\n        OPFAIL = ~cast(size_t)0\n    }\n}\n\n\nalias GC gc_t;\n\n\n/* ======================= Leak Detector =========================== */\n\n\ndebug (LOGGING)\n{\n    struct Log\n    {\n        void*  p;\n        size_t size;\n        size_t line;\n        char*  file;\n        void*  parent;\n\n        void print() nothrow\n        {\n            printf(\"    p = %p, size = %zd, parent = %p \", p, size, parent);\n            if (file)\n            {\n                printf(\"%s(%u)\", file, line);\n            }\n            printf(\"\\n\");\n        }\n    }\n\n\n    struct LogArray\n    {\n        size_t dim;\n        size_t allocdim;\n        Log *data;\n\n        void Dtor() nothrow\n        {\n            if (data)\n                cstdlib.free(data);\n            data = null;\n        }\n\n        void reserve(size_t nentries) nothrow\n        {\n            assert(dim <= allocdim);\n            if (allocdim - dim < nentries)\n            {\n                allocdim = (dim + nentries) * 2;\n                assert(dim + nentries <= allocdim);\n                if (!data)\n                {\n                    data = cast(Log*)cstdlib.malloc(allocdim * Log.sizeof);\n                    if (!data && allocdim)\n                        onOutOfMemoryErrorNoGC();\n                }\n                else\n                {   Log *newdata;\n\n                    newdata = cast(Log*)cstdlib.malloc(allocdim * Log.sizeof);\n                    if (!newdata && allocdim)\n                        onOutOfMemoryErrorNoGC();\n                    memcpy(newdata, data, dim * Log.sizeof);\n                    cstdlib.free(data);\n                    data = newdata;\n                }\n            }\n        }\n\n\n        void push(Log log) nothrow\n        {\n            reserve(1);\n            data[dim++] = log;\n        }\n\n        void remove(size_t i) nothrow\n        {\n            memmove(data + i, data + i + 1, (dim - i) * Log.sizeof);\n            dim--;\n        }\n\n\n        size_t find(void *p) nothrow\n        {\n            for (size_t i = 0; i < dim; i++)\n            {\n                if (data[i].p == p)\n                    return i;\n            }\n            return OPFAIL; // not found\n        }\n\n\n        void copy(LogArray *from) nothrow\n        {\n            reserve(from.dim - dim);\n            assert(from.dim <= allocdim);\n            memcpy(data, from.data, from.dim * Log.sizeof);\n            dim = from.dim;\n        }\n    }\n}\n\n\n/* ============================ GC =============================== */\n\nclass ConservativeGC : GC\n{\n    // For passing to debug code (not thread safe)\n    __gshared size_t line;\n    __gshared char*  file;\n\n    Gcx *gcx;                   // implementation\n\n    import core.internal.spinlock;\n    static gcLock = shared(AlignedSpinLock)(SpinLock.Contention.lengthy);\n    static bool _inFinalizer;\n\n    // lock GC, throw InvalidMemoryOperationError on recursive locking during finalization\n    static void lockNR() @nogc nothrow\n    {\n        if (_inFinalizer)\n            onInvalidMemoryOperationError();\n        gcLock.lock();\n    }\n\n\n    static void initialize(ref GC gc)\n    {\n        import core.stdc.string: memcpy;\n\n        if (config.gc != \"conservative\")\n              return;\n\n        auto p = cstdlib.malloc(__traits(classInstanceSize,ConservativeGC));\n\n        if (!p)\n            onOutOfMemoryErrorNoGC();\n\n        auto init = typeid(ConservativeGC).initializer();\n        assert(init.length == __traits(classInstanceSize, ConservativeGC));\n        auto instance = cast(ConservativeGC) memcpy(p, init.ptr, init.length);\n        instance.__ctor();\n\n        gc = instance;\n    }\n\n\n    static void finalize(ref GC gc)\n    {\n        if (config.gc != \"conservative\")\n              return;\n\n        auto instance = cast(ConservativeGC) gc;\n        instance.Dtor();\n        cstdlib.free(cast(void*)instance);\n    }\n\n\n    this()\n    {\n        //config is assumed to have already been initialized\n\n        gcx = cast(Gcx*)cstdlib.calloc(1, Gcx.sizeof);\n        if (!gcx)\n            onOutOfMemoryErrorNoGC();\n        gcx.initialize();\n\n        if (config.initReserve)\n            gcx.reserve(config.initReserve << 20);\n        if (config.disable)\n            gcx.disabled++;\n    }\n\n\n    void Dtor()\n    {\n        version (linux)\n        {\n            //debug(PRINTF) printf(\"Thread %x \", pthread_self());\n            //debug(PRINTF) printf(\"GC.Dtor()\\n\");\n        }\n\n        if (gcx)\n        {\n            gcx.Dtor();\n            cstdlib.free(gcx);\n            gcx = null;\n        }\n    }\n\n\n    void enable()\n    {\n        static void go(Gcx* gcx) nothrow\n        {\n            assert(gcx.disabled > 0);\n            gcx.disabled--;\n        }\n        runLocked!(go, otherTime, numOthers)(gcx);\n    }\n\n\n    void disable()\n    {\n        static void go(Gcx* gcx) nothrow\n        {\n            gcx.disabled++;\n        }\n        runLocked!(go, otherTime, numOthers)(gcx);\n    }\n\n\n    auto runLocked(alias func, Args...)(auto ref Args args)\n    {\n        debug(PROFILE_API) immutable tm = (config.profile > 1 ? currTime.ticks : 0);\n        lockNR();\n        scope (failure) gcLock.unlock();\n        debug(PROFILE_API) immutable tm2 = (config.profile > 1 ? currTime.ticks : 0);\n\n        static if (is(typeof(func(args)) == void))\n            func(args);\n        else\n            auto res = func(args);\n\n        debug(PROFILE_API) if (config.profile > 1)\n            lockTime += tm2 - tm;\n        gcLock.unlock();\n\n        static if (!is(typeof(func(args)) == void))\n            return res;\n    }\n\n\n    auto runLocked(alias func, alias time, alias count, Args...)(auto ref Args args)\n    {\n        debug(PROFILE_API) immutable tm = (config.profile > 1 ? currTime.ticks : 0);\n        lockNR();\n        scope (failure) gcLock.unlock();\n        debug(PROFILE_API) immutable tm2 = (config.profile > 1 ? currTime.ticks : 0);\n\n        static if (is(typeof(func(args)) == void))\n            func(args);\n        else\n            auto res = func(args);\n\n        debug(PROFILE_API) if (config.profile > 1)\n        {\n            count++;\n            immutable now = currTime.ticks;\n            lockTime += tm2 - tm;\n            time += now - tm2;\n        }\n        gcLock.unlock();\n\n        static if (!is(typeof(func(args)) == void))\n            return res;\n    }\n\n\n    uint getAttr(void* p) nothrow\n    {\n        if (!p)\n        {\n            return 0;\n        }\n\n        static uint go(Gcx* gcx, void* p) nothrow\n        {\n            Pool* pool = gcx.findPool(p);\n            uint  oldb = 0;\n\n            if (pool)\n            {\n                p = sentinel_sub(p);\n                auto biti = cast(size_t)(p - pool.baseAddr) >> pool.shiftBy;\n\n                oldb = pool.getBits(biti);\n            }\n            return oldb;\n        }\n\n        return runLocked!(go, otherTime, numOthers)(gcx, p);\n    }\n\n\n    uint setAttr(void* p, uint mask) nothrow\n    {\n        if (!p)\n        {\n            return 0;\n        }\n\n        static uint go(Gcx* gcx, void* p, uint mask) nothrow\n        {\n            Pool* pool = gcx.findPool(p);\n            uint  oldb = 0;\n\n            if (pool)\n            {\n                p = sentinel_sub(p);\n                auto biti = cast(size_t)(p - pool.baseAddr) >> pool.shiftBy;\n\n                oldb = pool.getBits(biti);\n                pool.setBits(biti, mask);\n            }\n            return oldb;\n        }\n\n        return runLocked!(go, otherTime, numOthers)(gcx, p, mask);\n    }\n\n\n    uint clrAttr(void* p, uint mask) nothrow\n    {\n        if (!p)\n        {\n            return 0;\n        }\n\n        static uint go(Gcx* gcx, void* p, uint mask) nothrow\n        {\n            Pool* pool = gcx.findPool(p);\n            uint  oldb = 0;\n\n            if (pool)\n            {\n                p = sentinel_sub(p);\n                auto biti = cast(size_t)(p - pool.baseAddr) >> pool.shiftBy;\n\n                oldb = pool.getBits(biti);\n                pool.clrBits(biti, mask);\n            }\n            return oldb;\n        }\n\n        return runLocked!(go, otherTime, numOthers)(gcx, p, mask);\n    }\n\n\n    void *malloc(size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n        if (!size)\n        {\n            return null;\n        }\n\n        size_t localAllocSize = void;\n\n        auto p = runLocked!(mallocNoSync, mallocTime, numMallocs)(size, bits, localAllocSize, ti);\n\n        if (!(bits & BlkAttr.NO_SCAN))\n        {\n            memset(p + size, 0, localAllocSize - size);\n        }\n\n        return p;\n    }\n\n\n    //\n    //\n    //\n    private void *mallocNoSync(size_t size, uint bits, ref size_t alloc_size, const TypeInfo ti = null) nothrow\n    {\n        assert(size != 0);\n\n        //debug(PRINTF) printf(\"GC::malloc(size = %d, gcx = %p)\\n\", size, gcx);\n        assert(gcx);\n        //debug(PRINTF) printf(\"gcx.self = %x, pthread_self() = %x\\n\", gcx.self, pthread_self());\n\n        auto p = gcx.alloc(size + SENTINEL_EXTRA, alloc_size, bits);\n        if (!p)\n            onOutOfMemoryErrorNoGC();\n\n        debug (SENTINEL)\n        {\n            p = sentinel_add(p);\n            sentinel_init(p, size);\n            alloc_size = size;\n        }\n        gcx.log_malloc(p, size);\n\n        return p;\n    }\n\n\n    BlkInfo qalloc( size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n\n        if (!size)\n        {\n            return BlkInfo.init;\n        }\n\n        BlkInfo retval;\n\n        retval.base = runLocked!(mallocNoSync, mallocTime, numMallocs)(size, bits, retval.size, ti);\n\n        if (!(bits & BlkAttr.NO_SCAN))\n        {\n            memset(retval.base + size, 0, retval.size - size);\n        }\n\n        retval.attr = bits;\n        return retval;\n    }\n\n\n    void *calloc(size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n        if (!size)\n        {\n            return null;\n        }\n\n        size_t localAllocSize = void;\n\n        auto p = runLocked!(mallocNoSync, mallocTime, numMallocs)(size, bits, localAllocSize, ti);\n\n        memset(p, 0, size);\n        if (!(bits & BlkAttr.NO_SCAN))\n        {\n            memset(p + size, 0, localAllocSize - size);\n        }\n\n        return p;\n    }\n\n\n    void *realloc(void *p, size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n        size_t localAllocSize = void;\n        auto oldp = p;\n\n        p = runLocked!(reallocNoSync, mallocTime, numMallocs)(p, size, bits, localAllocSize, ti);\n\n        if (p !is oldp && !(bits & BlkAttr.NO_SCAN))\n        {\n            memset(p + size, 0, localAllocSize - size);\n        }\n\n        return p;\n    }\n\n\n    //\n    // bits will be set to the resulting bits of the new block\n    //\n    private void *reallocNoSync(void *p, size_t size, ref uint bits, ref size_t alloc_size, const TypeInfo ti = null) nothrow\n    {\n        if (!size)\n        {   if (p)\n            {   freeNoSync(p);\n                p = null;\n            }\n            alloc_size = 0;\n        }\n        else if (!p)\n        {\n            p = mallocNoSync(size, bits, alloc_size, ti);\n        }\n        else\n        {   void *p2;\n            size_t psize;\n\n            //debug(PRINTF) printf(\"GC::realloc(p = %p, size = %zu)\\n\", p, size);\n            debug (SENTINEL)\n            {\n                sentinel_Invariant(p);\n                psize = *sentinel_size(p);\n                if (psize != size)\n                {\n                    if (psize)\n                    {\n                        Pool *pool = gcx.findPool(p);\n\n                        if (pool)\n                        {\n                            auto biti = cast(size_t)(sentinel_sub(p) - pool.baseAddr) >> pool.shiftBy;\n\n                            if (bits)\n                            {\n                                pool.clrBits(biti, ~BlkAttr.NONE);\n                                pool.setBits(biti, bits);\n                            }\n                            else\n                            {\n                                bits = pool.getBits(biti);\n                            }\n                        }\n                    }\n                    p2 = mallocNoSync(size, bits, alloc_size, ti);\n                    if (psize < size)\n                        size = psize;\n                    //debug(PRINTF) printf(\"\\tcopying %d bytes\\n\",size);\n                    memcpy(p2, p, size);\n                    p = p2;\n                }\n            }\n            else\n            {\n                auto pool = gcx.findPool(p);\n                if (pool.isLargeObject)\n                {\n                    auto lpool = cast(LargeObjectPool*) pool;\n                    psize = lpool.getSize(p);     // get allocated size\n\n                    if (size <= PAGESIZE / 2)\n                        goto Lmalloc; // switching from large object pool to small object pool\n\n                    auto psz = psize / PAGESIZE;\n                    auto newsz = (size + PAGESIZE - 1) / PAGESIZE;\n                    if (newsz == psz)\n                    {\n                        alloc_size = psize;\n                        return p;\n                    }\n\n                    auto pagenum = lpool.pagenumOf(p);\n\n                    if (newsz < psz)\n                    {   // Shrink in place\n                        debug (MEMSTOMP) memset(p + size, 0xF2, psize - size);\n                        lpool.freePages(pagenum + newsz, psz - newsz);\n                    }\n                    else if (pagenum + newsz <= pool.npages)\n                    {   // Attempt to expand in place\n                        foreach (binsz; lpool.pagetable[pagenum + psz .. pagenum + newsz])\n                            if (binsz != B_FREE)\n                                goto Lmalloc;\n\n                        debug (MEMSTOMP) memset(p + psize, 0xF0, size - psize);\n                        debug(PRINTF) printFreeInfo(pool);\n                        memset(&lpool.pagetable[pagenum + psz], B_PAGEPLUS, newsz - psz);\n                        gcx.usedLargePages += newsz - psz;\n                        lpool.freepages -= (newsz - psz);\n                        debug(PRINTF) printFreeInfo(pool);\n                    }\n                    else\n                        goto Lmalloc; // does not fit into current pool\n\n                    lpool.updateOffsets(pagenum);\n                    if (bits)\n                    {\n                        immutable biti = cast(size_t)(p - pool.baseAddr) >> pool.shiftBy;\n                        pool.clrBits(biti, ~BlkAttr.NONE);\n                        pool.setBits(biti, bits);\n                    }\n                    alloc_size = newsz * PAGESIZE;\n                    return p;\n                }\n\n                psize = (cast(SmallObjectPool*) pool).getSize(p);   // get allocated size\n                if (psize < size ||             // if new size is bigger\n                    psize > size * 2)           // or less than half\n                {\n                Lmalloc:\n                    if (psize && pool)\n                    {\n                        auto biti = cast(size_t)(p - pool.baseAddr) >> pool.shiftBy;\n\n                        if (bits)\n                        {\n                            pool.clrBits(biti, ~BlkAttr.NONE);\n                            pool.setBits(biti, bits);\n                        }\n                        else\n                        {\n                            bits = pool.getBits(biti);\n                        }\n                    }\n                    p2 = mallocNoSync(size, bits, alloc_size, ti);\n                    if (psize < size)\n                        size = psize;\n                    //debug(PRINTF) printf(\"\\tcopying %d bytes\\n\",size);\n                    memcpy(p2, p, size);\n                    p = p2;\n                }\n                else\n                    alloc_size = psize;\n            }\n        }\n        return p;\n    }\n\n\n    size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow\n    {\n        return runLocked!(extendNoSync, extendTime, numExtends)(p, minsize, maxsize, ti);\n    }\n\n\n    //\n    //\n    //\n    private size_t extendNoSync(void* p, size_t minsize, size_t maxsize, const TypeInfo ti = null) nothrow\n    in\n    {\n        assert(minsize <= maxsize);\n    }\n    do\n    {\n        //debug(PRINTF) printf(\"GC::extend(p = %p, minsize = %zu, maxsize = %zu)\\n\", p, minsize, maxsize);\n        debug (SENTINEL)\n        {\n            return 0;\n        }\n        else\n        {\n            auto pool = gcx.findPool(p);\n            if (!pool || !pool.isLargeObject)\n                return 0;\n\n            auto lpool = cast(LargeObjectPool*) pool;\n            auto psize = lpool.getSize(p);   // get allocated size\n            if (psize < PAGESIZE)\n                return 0;                   // cannot extend buckets\n\n            auto psz = psize / PAGESIZE;\n            auto minsz = (minsize + PAGESIZE - 1) / PAGESIZE;\n            auto maxsz = (maxsize + PAGESIZE - 1) / PAGESIZE;\n\n            auto pagenum = lpool.pagenumOf(p);\n\n            size_t sz;\n            for (sz = 0; sz < maxsz; sz++)\n            {\n                auto i = pagenum + psz + sz;\n                if (i == lpool.npages)\n                    break;\n                if (lpool.pagetable[i] != B_FREE)\n                {   if (sz < minsz)\n                        return 0;\n                    break;\n                }\n            }\n            if (sz < minsz)\n                return 0;\n            debug (MEMSTOMP) memset(pool.baseAddr + (pagenum + psz) * PAGESIZE, 0xF0, sz * PAGESIZE);\n            memset(lpool.pagetable + pagenum + psz, B_PAGEPLUS, sz);\n            lpool.updateOffsets(pagenum);\n            lpool.freepages -= sz;\n            gcx.usedLargePages += sz;\n            return (psz + sz) * PAGESIZE;\n        }\n    }\n\n\n    size_t reserve(size_t size) nothrow\n    {\n        if (!size)\n        {\n            return 0;\n        }\n\n        return runLocked!(reserveNoSync, otherTime, numOthers)(size);\n    }\n\n\n    //\n    //\n    //\n    private size_t reserveNoSync(size_t size) nothrow\n    {\n        assert(size != 0);\n        assert(gcx);\n\n        return gcx.reserve(size);\n    }\n\n\n    void free(void *p) nothrow @nogc\n    {\n        if (!p || _inFinalizer)\n        {\n            return;\n        }\n\n        return runLocked!(freeNoSync, freeTime, numFrees)(p);\n    }\n\n\n    //\n    //\n    //\n    private void freeNoSync(void *p) nothrow @nogc\n    {\n        debug(PRINTF) printf(\"Freeing %p\\n\", cast(size_t) p);\n        assert (p);\n\n        Pool*  pool;\n        size_t pagenum;\n        Bins   bin;\n        size_t biti;\n\n        // Find which page it is in\n        pool = gcx.findPool(p);\n        if (!pool)                              // if not one of ours\n            return;                             // ignore\n\n        pagenum = pool.pagenumOf(p);\n\n        debug(PRINTF) printf(\"pool base = %p, PAGENUM = %d of %d, bin = %d\\n\", pool.baseAddr, pagenum, pool.npages, pool.pagetable[pagenum]);\n        debug(PRINTF) if (pool.isLargeObject) printf(\"Block size = %d\\n\", pool.bPageOffsets[pagenum]);\n\n        bin = cast(Bins)pool.pagetable[pagenum];\n\n        // Verify that the pointer is at the beginning of a block,\n        //  no action should be taken if p is an interior pointer\n        if (bin > B_PAGE) // B_PAGEPLUS or B_FREE\n            return;\n        if ((sentinel_sub(p) - pool.baseAddr) & (binsize[bin] - 1))\n            return;\n\n        sentinel_Invariant(p);\n        p = sentinel_sub(p);\n        biti = cast(size_t)(p - pool.baseAddr) >> pool.shiftBy;\n\n        pool.clrBits(biti, ~BlkAttr.NONE);\n\n        if (pool.isLargeObject)              // if large alloc\n        {\n            assert(bin == B_PAGE);\n            auto lpool = cast(LargeObjectPool*) pool;\n\n            // Free pages\n            size_t npages = lpool.bPageOffsets[pagenum];\n            debug (MEMSTOMP) memset(p, 0xF2, npages * PAGESIZE);\n            lpool.freePages(pagenum, npages);\n        }\n        else\n        {   // Add to free list\n            List *list = cast(List*)p;\n\n            debug (MEMSTOMP) memset(p, 0xF2, binsize[bin]);\n\n            list.next = gcx.bucket[bin];\n            list.pool = pool;\n            gcx.bucket[bin] = list;\n        }\n\n        gcx.log_free(sentinel_add(p));\n    }\n\n\n    void* addrOf(void *p) nothrow @nogc\n    {\n        if (!p)\n        {\n            return null;\n        }\n\n        return runLocked!(addrOfNoSync, otherTime, numOthers)(p);\n    }\n\n\n    //\n    //\n    //\n    void* addrOfNoSync(void *p) nothrow @nogc\n    {\n        if (!p)\n        {\n            return null;\n        }\n\n        auto q = gcx.findBase(p);\n        if (q)\n            q = sentinel_add(q);\n        return q;\n    }\n\n\n    size_t sizeOf(void *p) nothrow @nogc\n    {\n        if (!p)\n        {\n            return 0;\n        }\n\n        return runLocked!(sizeOfNoSync, otherTime, numOthers)(p);\n    }\n\n\n    //\n    //\n    //\n    private size_t sizeOfNoSync(void *p) nothrow @nogc\n    {\n        assert (p);\n\n        debug (SENTINEL)\n        {\n            p = sentinel_sub(p);\n            size_t size = gcx.findSize(p);\n\n            // Check for interior pointer\n            // This depends on:\n            // 1) size is a power of 2 for less than PAGESIZE values\n            // 2) base of memory pool is aligned on PAGESIZE boundary\n            if (cast(size_t)p & (size - 1) & (PAGESIZE - 1))\n                size = 0;\n            return size ? size - SENTINEL_EXTRA : 0;\n        }\n        else\n        {\n            size_t size = gcx.findSize(p);\n\n            // Check for interior pointer\n            // This depends on:\n            // 1) size is a power of 2 for less than PAGESIZE values\n            // 2) base of memory pool is aligned on PAGESIZE boundary\n            if (cast(size_t)p & (size - 1) & (PAGESIZE - 1))\n                return 0;\n            return size;\n        }\n    }\n\n\n    BlkInfo query(void *p) nothrow\n    {\n        if (!p)\n        {\n            BlkInfo i;\n            return  i;\n        }\n\n        return runLocked!(queryNoSync, otherTime, numOthers)(p);\n    }\n\n    //\n    //\n    //\n    BlkInfo queryNoSync(void *p) nothrow\n    {\n        assert(p);\n\n        BlkInfo info = gcx.getInfo(p);\n        debug(SENTINEL)\n        {\n            if (info.base)\n            {\n                info.base = sentinel_add(info.base);\n                info.size = *sentinel_size(info.base);\n            }\n        }\n        return info;\n    }\n\n\n    /**\n     * Verify that pointer p:\n     *  1) belongs to this memory pool\n     *  2) points to the start of an allocated piece of memory\n     *  3) is not on a free list\n     */\n    void check(void *p) nothrow\n    {\n        if (!p)\n        {\n            return;\n        }\n\n        return runLocked!(checkNoSync, otherTime, numOthers)(p);\n    }\n\n\n    //\n    //\n    //\n    private void checkNoSync(void *p) nothrow\n    {\n        assert(p);\n\n        sentinel_Invariant(p);\n        debug (PTRCHECK)\n        {\n            Pool*  pool;\n            size_t pagenum;\n            Bins   bin;\n            size_t size;\n\n            p = sentinel_sub(p);\n            pool = gcx.findPool(p);\n            assert(pool);\n            pagenum = pool.pagenumOf(p);\n            bin = cast(Bins)pool.pagetable[pagenum];\n            assert(bin <= B_PAGE);\n            size = binsize[bin];\n            assert((cast(size_t)p & (size - 1)) == 0);\n\n            debug (PTRCHECK2)\n            {\n                if (bin < B_PAGE)\n                {\n                    // Check that p is not on a free list\n                    List *list;\n\n                    for (list = gcx.bucket[bin]; list; list = list.next)\n                    {\n                        assert(cast(void*)list != p);\n                    }\n                }\n            }\n        }\n    }\n\n\n    void addRoot(void *p) nothrow @nogc\n    {\n        if (!p)\n        {\n            return;\n        }\n\n        gcx.addRoot(p);\n    }\n\n\n    void removeRoot(void *p) nothrow @nogc\n    {\n        if (!p)\n        {\n            return;\n        }\n\n        gcx.removeRoot(p);\n    }\n\n\n    @property RootIterator rootIter() @nogc\n    {\n        return &gcx.rootsApply;\n    }\n\n\n    void addRange(void *p, size_t sz, const TypeInfo ti = null) nothrow @nogc\n    {\n        if (!p || !sz)\n        {\n            return;\n        }\n\n        gcx.addRange(p, p + sz, ti);\n    }\n\n\n    void removeRange(void *p) nothrow @nogc\n    {\n        if (!p)\n        {\n            return;\n        }\n\n        gcx.removeRange(p);\n    }\n\n\n    @property RangeIterator rangeIter() @nogc\n    {\n        return &gcx.rangesApply;\n    }\n\n\n    void runFinalizers(in void[] segment) nothrow\n    {\n        static void go(Gcx* gcx, in void[] segment) nothrow\n        {\n            gcx.runFinalizers(segment);\n        }\n        return runLocked!(go, otherTime, numOthers)(gcx, segment);\n    }\n\n\n    bool inFinalizer() nothrow\n    {\n        return _inFinalizer;\n    }\n\n\n    void collect() nothrow\n    {\n        fullCollect();\n    }\n\n\n    void collectNoStack() nothrow\n    {\n        fullCollectNoStack();\n    }\n\n\n    /**\n     * Do full garbage collection.\n     * Return number of pages free'd.\n     */\n    size_t fullCollect() nothrow\n    {\n        debug(PRINTF) printf(\"GC.fullCollect()\\n\");\n\n        // Since a finalizer could launch a new thread, we always need to lock\n        // when collecting.\n        static size_t go(Gcx* gcx) nothrow\n        {\n            return gcx.fullcollect();\n        }\n        immutable result = runLocked!go(gcx);\n\n        version (none)\n        {\n            GCStats stats;\n\n            getStats(stats);\n            debug(PRINTF) printf(\"heapSize = %zx, freeSize = %zx\\n\",\n                stats.heapSize, stats.freeSize);\n        }\n\n        gcx.log_collect();\n        return result;\n    }\n\n\n    /**\n     * do full garbage collection ignoring roots\n     */\n    void fullCollectNoStack() nothrow\n    {\n        // Since a finalizer could launch a new thread, we always need to lock\n        // when collecting.\n        static size_t go(Gcx* gcx) nothrow\n        {\n            return gcx.fullcollect(true);\n        }\n        runLocked!go(gcx);\n    }\n\n\n    void minimize() nothrow\n    {\n        static void go(Gcx* gcx) nothrow\n        {\n            gcx.minimize();\n        }\n        runLocked!(go, otherTime, numOthers)(gcx);\n    }\n\n\n    core.memory.GC.Stats stats() nothrow\n    {\n        typeof(return) ret;\n\n        runLocked!(getStatsNoSync, otherTime, numOthers)(ret);\n\n        return ret;\n    }\n\n\n    //\n    //\n    //\n    private void getStatsNoSync(out core.memory.GC.Stats stats) nothrow\n    {\n        foreach (pool; gcx.pooltable[0 .. gcx.npools])\n        {\n            foreach (bin; pool.pagetable[0 .. pool.npages])\n            {\n                if (bin == B_FREE)\n                    stats.freeSize += PAGESIZE;\n                else\n                    stats.usedSize += PAGESIZE;\n            }\n        }\n\n        size_t freeListSize;\n        foreach (n; 0 .. B_PAGE)\n        {\n            immutable sz = binsize[n];\n            for (List *list = gcx.bucket[n]; list; list = list.next)\n                freeListSize += sz;\n        }\n\n        stats.usedSize -= freeListSize;\n        stats.freeSize += freeListSize;\n    }\n}\n\n\n/* ============================ Gcx =============================== */\n\nenum\n{   PAGESIZE =    4096,\n    POOLSIZE =   (4096*256),\n}\n\n\nenum\n{\n    B_16,\n    B_32,\n    B_64,\n    B_128,\n    B_256,\n    B_512,\n    B_1024,\n    B_2048,\n    B_PAGE,             // start of large alloc\n    B_PAGEPLUS,         // continuation of large alloc\n    B_FREE,             // free page\n    B_MAX\n}\n\n\nalias ubyte Bins;\n\n\nstruct List\n{\n    List *next;\n    Pool *pool;\n}\n\n\nimmutable uint[B_MAX] binsize = [ 16,32,64,128,256,512,1024,2048,4096 ];\nimmutable size_t[B_MAX] notbinsize = [ ~(16-1),~(32-1),~(64-1),~(128-1),~(256-1),\n                                ~(512-1),~(1024-1),~(2048-1),~(4096-1) ];\n\nalias PageBits = GCBits.wordtype[PAGESIZE / 16 / GCBits.BITS_PER_WORD];\nstatic assert(PAGESIZE % (GCBits.BITS_PER_WORD * 16) == 0);\n\nprivate void set(ref PageBits bits, size_t i) @nogc pure nothrow\n{\n    assert(i < PageBits.sizeof * 8);\n    bts(bits.ptr, i);\n}\n\n/* ============================ Gcx =============================== */\n\nstruct Gcx\n{\n    import core.internal.spinlock;\n    auto rootsLock = shared(AlignedSpinLock)(SpinLock.Contention.brief);\n    auto rangesLock = shared(AlignedSpinLock)(SpinLock.Contention.brief);\n    Treap!Root roots;\n    Treap!Range ranges;\n\n    bool log; // turn on logging\n    debug(INVARIANT) bool initialized;\n    uint disabled; // turn off collections if >0\n\n    import gc.pooltable;\n    @property size_t npools() pure const nothrow { return pooltable.length; }\n    PoolTable!Pool pooltable;\n\n    List*[B_PAGE] bucket; // free list for each small size\n\n    // run a collection when reaching those thresholds (number of used pages)\n    float smallCollectThreshold, largeCollectThreshold;\n    uint usedSmallPages, usedLargePages;\n    // total number of mapped pages\n    uint mappedPages;\n\n    void initialize()\n    {\n        (cast(byte*)&this)[0 .. Gcx.sizeof] = 0;\n        log_init();\n        roots.initialize();\n        ranges.initialize();\n        smallCollectThreshold = largeCollectThreshold = 0.0f;\n        usedSmallPages = usedLargePages = 0;\n        mappedPages = 0;\n        //printf(\"gcx = %p, self = %x\\n\", &this, self);\n        debug(INVARIANT) initialized = true;\n    }\n\n\n    void Dtor()\n    {\n        if (config.profile)\n        {\n            printf(\"\\tNumber of collections:  %llu\\n\", cast(ulong)numCollections);\n            printf(\"\\tTotal GC prep time:  %lld milliseconds\\n\",\n                   prepTime.total!(\"msecs\"));\n            printf(\"\\tTotal mark time:  %lld milliseconds\\n\",\n                   markTime.total!(\"msecs\"));\n            printf(\"\\tTotal sweep time:  %lld milliseconds\\n\",\n                   sweepTime.total!(\"msecs\"));\n            printf(\"\\tTotal page recovery time:  %lld milliseconds\\n\",\n                   recoverTime.total!(\"msecs\"));\n            long maxPause = maxPauseTime.total!(\"msecs\");\n            printf(\"\\tMax Pause Time:  %lld milliseconds\\n\", maxPause);\n            long gcTime = (recoverTime + sweepTime + markTime + prepTime).total!(\"msecs\");\n            printf(\"\\tGrand total GC time:  %lld milliseconds\\n\", gcTime);\n            long pauseTime = (markTime + prepTime).total!(\"msecs\");\n\n            char[30] apitxt;\n            apitxt[0] = 0;\n            debug(PROFILE_API) if (config.profile > 1)\n            {\n                static Duration toDuration(long dur)\n                {\n                    return MonoTime(dur) - MonoTime(0);\n                }\n\n                printf(\"\\n\");\n                printf(\"\\tmalloc:  %llu calls, %lld ms\\n\", cast(ulong)numMallocs, toDuration(mallocTime).total!\"msecs\");\n                printf(\"\\trealloc: %llu calls, %lld ms\\n\", cast(ulong)numReallocs, toDuration(reallocTime).total!\"msecs\");\n                printf(\"\\tfree:    %llu calls, %lld ms\\n\", cast(ulong)numFrees, toDuration(freeTime).total!\"msecs\");\n                printf(\"\\textend:  %llu calls, %lld ms\\n\", cast(ulong)numExtends, toDuration(extendTime).total!\"msecs\");\n                printf(\"\\tother:   %llu calls, %lld ms\\n\", cast(ulong)numOthers, toDuration(otherTime).total!\"msecs\");\n                printf(\"\\tlock time: %lld ms\\n\", toDuration(lockTime).total!\"msecs\");\n\n                long apiTime = mallocTime + reallocTime + freeTime + extendTime + otherTime + lockTime;\n                printf(\"\\tGC API: %lld ms\\n\", toDuration(apiTime).total!\"msecs\");\n                sprintf(apitxt.ptr, \" API%5ld ms\", toDuration(apiTime).total!\"msecs\");\n            }\n\n            printf(\"GC summary:%5lld MB,%5lld GC%5lld ms, Pauses%5lld ms <%5lld ms%s\\n\",\n                   cast(long) maxPoolMemory >> 20, cast(ulong)numCollections, gcTime,\n                   pauseTime, maxPause, apitxt.ptr);\n        }\n\n        debug(INVARIANT) initialized = false;\n\n        for (size_t i = 0; i < npools; i++)\n        {\n            Pool *pool = pooltable[i];\n            mappedPages -= pool.npages;\n            pool.Dtor();\n            cstdlib.free(pool);\n        }\n        assert(!mappedPages);\n        pooltable.Dtor();\n\n        roots.removeAll();\n        ranges.removeAll();\n        toscan.reset();\n    }\n\n\n    void Invariant() const { }\n\n    debug(INVARIANT)\n    invariant()\n    {\n        if (initialized)\n        {\n            //printf(\"Gcx.invariant(): this = %p\\n\", &this);\n            pooltable.Invariant();\n\n            rangesLock.lock();\n            foreach (range; ranges)\n            {\n                assert(range.pbot);\n                assert(range.ptop);\n                assert(range.pbot <= range.ptop);\n            }\n            rangesLock.unlock();\n\n            for (size_t i = 0; i < B_PAGE; i++)\n            {\n                for (auto list = cast(List*)bucket[i]; list; list = list.next)\n                {\n                }\n            }\n        }\n    }\n\n\n    /**\n     *\n     */\n    void addRoot(void *p) nothrow @nogc\n    {\n        rootsLock.lock();\n        scope (failure) rootsLock.unlock();\n        roots.insert(Root(p));\n        rootsLock.unlock();\n    }\n\n\n    /**\n     *\n     */\n    void removeRoot(void *p) nothrow @nogc\n    {\n        rootsLock.lock();\n        scope (failure) rootsLock.unlock();\n        roots.remove(Root(p));\n        rootsLock.unlock();\n    }\n\n\n    /**\n     *\n     */\n    int rootsApply(scope int delegate(ref Root) nothrow dg) nothrow\n    {\n        rootsLock.lock();\n        scope (failure) rootsLock.unlock();\n        auto ret = roots.opApply(dg);\n        rootsLock.unlock();\n        return ret;\n    }\n\n\n    /**\n     *\n     */\n    void addRange(void *pbot, void *ptop, const TypeInfo ti) nothrow @nogc\n    {\n        //debug(PRINTF) printf(\"Thread %x \", pthread_self());\n        debug(PRINTF) printf(\"%p.Gcx::addRange(%p, %p)\\n\", &this, pbot, ptop);\n        rangesLock.lock();\n        scope (failure) rangesLock.unlock();\n        ranges.insert(Range(pbot, ptop));\n        rangesLock.unlock();\n    }\n\n\n    /**\n     *\n     */\n    void removeRange(void *pbot) nothrow @nogc\n    {\n        //debug(PRINTF) printf(\"Thread %x \", pthread_self());\n        debug(PRINTF) printf(\"Gcx.removeRange(%p)\\n\", pbot);\n        rangesLock.lock();\n        scope (failure) rangesLock.unlock();\n        ranges.remove(Range(pbot, pbot)); // only pbot is used, see Range.opCmp\n        rangesLock.unlock();\n\n        // debug(PRINTF) printf(\"Wrong thread\\n\");\n        // This is a fatal error, but ignore it.\n        // The problem is that we can get a Close() call on a thread\n        // other than the one the range was allocated on.\n        //assert(zero);\n    }\n\n    /**\n     *\n     */\n    int rangesApply(scope int delegate(ref Range) nothrow dg) nothrow\n    {\n        rangesLock.lock();\n        scope (failure) rangesLock.unlock();\n        auto ret = ranges.opApply(dg);\n        rangesLock.unlock();\n        return ret;\n    }\n\n\n    /**\n     *\n     */\n    void runFinalizers(in void[] segment) nothrow\n    {\n        ConservativeGC._inFinalizer = true;\n        scope (failure) ConservativeGC._inFinalizer = false;\n\n        foreach (pool; pooltable[0 .. npools])\n        {\n            if (!pool.finals.nbits) continue;\n\n            if (pool.isLargeObject)\n            {\n                auto lpool = cast(LargeObjectPool*) pool;\n                lpool.runFinalizers(segment);\n            }\n            else\n            {\n                auto spool = cast(SmallObjectPool*) pool;\n                spool.runFinalizers(segment);\n            }\n        }\n        ConservativeGC._inFinalizer = false;\n    }\n\n    Pool* findPool(void* p) pure nothrow @nogc\n    {\n        return pooltable.findPool(p);\n    }\n\n    /**\n     * Find base address of block containing pointer p.\n     * Returns null if not a gc'd pointer\n     */\n    void* findBase(void *p) nothrow @nogc\n    {\n        Pool *pool;\n\n        pool = findPool(p);\n        if (pool)\n        {\n            size_t offset = cast(size_t)(p - pool.baseAddr);\n            size_t pn = offset / PAGESIZE;\n            Bins   bin = cast(Bins)pool.pagetable[pn];\n\n            // Adjust bit to be at start of allocated memory block\n            if (bin <= B_PAGE)\n            {\n                return pool.baseAddr + (offset & notbinsize[bin]);\n            }\n            else if (bin == B_PAGEPLUS)\n            {\n                auto pageOffset = pool.bPageOffsets[pn];\n                offset -= pageOffset * PAGESIZE;\n                pn -= pageOffset;\n\n                return pool.baseAddr + (offset & (offset.max ^ (PAGESIZE-1)));\n            }\n            else\n            {\n                // we are in a B_FREE page\n                assert(bin == B_FREE);\n                return null;\n            }\n        }\n        return null;\n    }\n\n\n    /**\n     * Find size of pointer p.\n     * Returns 0 if not a gc'd pointer\n     */\n    size_t findSize(void *p) nothrow @nogc\n    {\n        Pool* pool = findPool(p);\n        if (pool)\n            return pool.slGetSize(p);\n        return 0;\n    }\n\n    /**\n     *\n     */\n    BlkInfo getInfo(void* p) nothrow\n    {\n        Pool* pool = findPool(p);\n        if (pool)\n            return pool.slGetInfo(p);\n        return BlkInfo();\n    }\n\n    /**\n     * Computes the bin table using CTFE.\n     */\n    static byte[2049] ctfeBins() nothrow\n    {\n        byte[2049] ret;\n        size_t p = 0;\n        for (Bins b = B_16; b <= B_2048; b++)\n            for ( ; p <= binsize[b]; p++)\n                ret[p] = b;\n\n        return ret;\n    }\n\n    static const byte[2049] binTable = ctfeBins();\n\n    /**\n     * Allocate a new pool of at least size bytes.\n     * Sort it into pooltable[].\n     * Mark all memory in the pool as B_FREE.\n     * Return the actual number of bytes reserved or 0 on error.\n     */\n    size_t reserve(size_t size) nothrow\n    {\n        size_t npages = (size + PAGESIZE - 1) / PAGESIZE;\n\n        // Assume reserve() is for small objects.\n        Pool*  pool = newPool(npages, false);\n\n        if (!pool)\n            return 0;\n        return pool.npages * PAGESIZE;\n    }\n\n    /**\n     * Update the thresholds for when to collect the next time\n     */\n    void updateCollectThresholds() nothrow\n    {\n        static float max(float a, float b) nothrow\n        {\n            return a >= b ? a : b;\n        }\n\n        // instantly increases, slowly decreases\n        static float smoothDecay(float oldVal, float newVal) nothrow\n        {\n            // decay to 63.2% of newVal over 5 collections\n            // http://en.wikipedia.org/wiki/Low-pass_filter#Simple_infinite_impulse_response_filter\n            enum alpha = 1.0 / (5 + 1);\n            immutable decay = (newVal - oldVal) * alpha + oldVal;\n            return max(newVal, decay);\n        }\n\n        immutable smTarget = usedSmallPages * config.heapSizeFactor;\n        smallCollectThreshold = smoothDecay(smallCollectThreshold, smTarget);\n        immutable lgTarget = usedLargePages * config.heapSizeFactor;\n        largeCollectThreshold = smoothDecay(largeCollectThreshold, lgTarget);\n    }\n\n    /**\n     * Minimizes physical memory usage by returning free pools to the OS.\n     */\n    void minimize() nothrow\n    {\n        debug(PRINTF) printf(\"Minimizing.\\n\");\n\n        foreach (pool; pooltable.minimize())\n        {\n            debug(PRINTF) printFreeInfo(pool);\n            mappedPages -= pool.npages;\n            pool.Dtor();\n            cstdlib.free(pool);\n        }\n\n        debug(PRINTF) printf(\"Done minimizing.\\n\");\n    }\n\n    private @property bool lowMem() const nothrow\n    {\n        return isLowOnMem(mappedPages * PAGESIZE);\n    }\n\n    void* alloc(size_t size, ref size_t alloc_size, uint bits) nothrow\n    {\n        return size <= 2048 ? smallAlloc(binTable[size], alloc_size, bits)\n                            : bigAlloc(size, alloc_size, bits);\n    }\n\n    void* smallAlloc(Bins bin, ref size_t alloc_size, uint bits) nothrow\n    {\n        alloc_size = binsize[bin];\n\n        void* p;\n        bool tryAlloc() nothrow\n        {\n            if (!bucket[bin])\n            {\n                bucket[bin] = allocPage(bin);\n                if (!bucket[bin])\n                    return false;\n            }\n            p = bucket[bin];\n            return true;\n        }\n\n        if (!tryAlloc())\n        {\n            if (!lowMem && (disabled || usedSmallPages < smallCollectThreshold))\n            {\n                // disabled or threshold not reached => allocate a new pool instead of collecting\n                if (!newPool(1, false))\n                {\n                    // out of memory => try to free some memory\n                    fullcollect();\n                    if (lowMem) minimize();\n                }\n            }\n            else\n            {\n                fullcollect();\n                if (lowMem) minimize();\n            }\n            // tryAlloc will succeed if a new pool was allocated above, if it fails allocate a new pool now\n            if (!tryAlloc() && (!newPool(1, false) || !tryAlloc()))\n                // out of luck or memory\n                onOutOfMemoryErrorNoGC();\n        }\n        assert(p !is null);\n\n        // Return next item from free list\n        bucket[bin] = (cast(List*)p).next;\n        auto pool = (cast(List*)p).pool;\n        if (bits)\n            pool.setBits((p - pool.baseAddr) >> pool.shiftBy, bits);\n        //debug(PRINTF) printf(\"\\tmalloc => %p\\n\", p);\n        debug (MEMSTOMP) memset(p, 0xF0, alloc_size);\n        return p;\n    }\n\n    /**\n     * Allocate a chunk of memory that is larger than a page.\n     * Return null if out of memory.\n     */\n    void* bigAlloc(size_t size, ref size_t alloc_size, uint bits, const TypeInfo ti = null) nothrow\n    {\n        debug(PRINTF) printf(\"In bigAlloc.  Size:  %d\\n\", size);\n\n        LargeObjectPool* pool;\n        size_t pn;\n        immutable npages = (size + PAGESIZE - 1) / PAGESIZE;\n        if (npages == 0)\n            onOutOfMemoryErrorNoGC(); // size just below size_t.max requested\n\n        bool tryAlloc() nothrow\n        {\n            foreach (p; pooltable[0 .. npools])\n            {\n                if (!p.isLargeObject || p.freepages < npages)\n                    continue;\n                auto lpool = cast(LargeObjectPool*) p;\n                if ((pn = lpool.allocPages(npages)) == OPFAIL)\n                    continue;\n                pool = lpool;\n                return true;\n            }\n            return false;\n        }\n\n        bool tryAllocNewPool() nothrow\n        {\n            pool = cast(LargeObjectPool*) newPool(npages, true);\n            if (!pool) return false;\n            pn = pool.allocPages(npages);\n            assert(pn != OPFAIL);\n            return true;\n        }\n\n        if (!tryAlloc())\n        {\n            if (!lowMem && (disabled || usedLargePages < largeCollectThreshold))\n            {\n                // disabled or threshold not reached => allocate a new pool instead of collecting\n                if (!tryAllocNewPool())\n                {\n                    // disabled but out of memory => try to free some memory\n                    fullcollect();\n                    minimize();\n                }\n            }\n            else\n            {\n                fullcollect();\n                minimize();\n            }\n            // If alloc didn't yet succeed retry now that we collected/minimized\n            if (!pool && !tryAlloc() && !tryAllocNewPool())\n                // out of luck or memory\n                return null;\n        }\n        assert(pool);\n\n        debug(PRINTF) printFreeInfo(&pool.base);\n        pool.pagetable[pn] = B_PAGE;\n        if (npages > 1)\n            memset(&pool.pagetable[pn + 1], B_PAGEPLUS, npages - 1);\n        pool.updateOffsets(pn);\n        usedLargePages += npages;\n        pool.freepages -= npages;\n\n        debug(PRINTF) printFreeInfo(&pool.base);\n\n        auto p = pool.baseAddr + pn * PAGESIZE;\n        debug(PRINTF) printf(\"Got large alloc:  %p, pt = %d, np = %d\\n\", p, pool.pagetable[pn], npages);\n        debug (MEMSTOMP) memset(p, 0xF1, size);\n        alloc_size = npages * PAGESIZE;\n        //debug(PRINTF) printf(\"\\tp = %p\\n\", p);\n\n        if (bits)\n            pool.setBits(pn, bits);\n        return p;\n    }\n\n\n    /**\n     * Allocate a new pool with at least npages in it.\n     * Sort it into pooltable[].\n     * Return null if failed.\n     */\n    Pool *newPool(size_t npages, bool isLargeObject) nothrow\n    {\n        //debug(PRINTF) printf(\"************Gcx::newPool(npages = %d)****************\\n\", npages);\n\n        // Minimum of POOLSIZE\n        size_t minPages = (config.minPoolSize << 20) / PAGESIZE;\n        if (npages < minPages)\n            npages = minPages;\n        else if (npages > minPages)\n        {   // Give us 150% of requested size, so there's room to extend\n            auto n = npages + (npages >> 1);\n            if (n < size_t.max/PAGESIZE)\n                npages = n;\n        }\n\n        // Allocate successively larger pools up to 8 megs\n        if (npools)\n        {   size_t n;\n\n            n = config.minPoolSize + config.incPoolSize * npools;\n            if (n > config.maxPoolSize)\n                n = config.maxPoolSize;                 // cap pool size\n            n *= (1 << 20) / PAGESIZE;                     // convert MB to pages\n            if (npages < n)\n                npages = n;\n        }\n\n        //printf(\"npages = %d\\n\", npages);\n\n        auto pool = cast(Pool *)cstdlib.calloc(1, isLargeObject ? LargeObjectPool.sizeof : SmallObjectPool.sizeof);\n        if (pool)\n        {\n            pool.initialize(npages, isLargeObject);\n            if (!pool.baseAddr || !pooltable.insert(pool))\n            {\n                pool.Dtor();\n                cstdlib.free(pool);\n                return null;\n            }\n        }\n\n        mappedPages += npages;\n\n        if (config.profile)\n        {\n            if (mappedPages * PAGESIZE > maxPoolMemory)\n                maxPoolMemory = mappedPages * PAGESIZE;\n        }\n        return pool;\n    }\n\n    /**\n    * Allocate a page of bin's.\n    * Returns:\n    *           head of a single linked list of new entries\n    */\n    List* allocPage(Bins bin) nothrow\n    {\n        //debug(PRINTF) printf(\"Gcx::allocPage(bin = %d)\\n\", bin);\n        for (size_t n = 0; n < npools; n++)\n        {\n            Pool* pool = pooltable[n];\n            if (pool.isLargeObject)\n                continue;\n            if (List* p = (cast(SmallObjectPool*)pool).allocPage(bin))\n            {\n                ++usedSmallPages;\n                return p;\n            }\n        }\n        return null;\n    }\n\n    static struct ScanRange\n    {\n        void* pbot;\n        void* ptop;\n    }\n\n    static struct ToScanStack\n    {\n    nothrow:\n        @disable this(this);\n\n        void reset()\n        {\n            _length = 0;\n            os_mem_unmap(_p, _cap * ScanRange.sizeof);\n            _p = null;\n            _cap = 0;\n        }\n\n        void push(ScanRange rng)\n        {\n            if (_length == _cap) grow();\n            _p[_length++] = rng;\n        }\n\n        ScanRange pop()\n        in { assert(!empty); }\n        do\n        {\n            return _p[--_length];\n        }\n\n        ref inout(ScanRange) opIndex(size_t idx) inout\n        in { assert(idx < _length); }\n        do\n        {\n            return _p[idx];\n        }\n\n        @property size_t length() const { return _length; }\n        @property bool empty() const { return !length; }\n\n    private:\n        void grow()\n        {\n            pragma(inline, false);\n\n            enum initSize = 64 * 1024; // Windows VirtualAlloc granularity\n            immutable ncap = _cap ? 2 * _cap : initSize / ScanRange.sizeof;\n            auto p = cast(ScanRange*)os_mem_map(ncap * ScanRange.sizeof);\n            if (p is null) onOutOfMemoryErrorNoGC();\n            if (_p !is null)\n            {\n                p[0 .. _length] = _p[0 .. _length];\n                os_mem_unmap(_p, _cap * ScanRange.sizeof);\n            }\n            _p = p;\n            _cap = ncap;\n        }\n\n        size_t _length;\n        ScanRange* _p;\n        size_t _cap;\n    }\n\n    ToScanStack toscan;\n\n    /**\n     * Search a range of memory values and mark any pointers into the GC pool.\n     */\n    void mark(void *pbot, void *ptop) scope nothrow\n    {\n        if (pbot >= ptop)\n            return;\n\n        void **p1 = cast(void **)pbot;\n        void **p2 = cast(void **)ptop;\n\n        // limit the amount of ranges added to the toscan stack\n        enum FANOUT_LIMIT = 32;\n        size_t stackPos;\n        ScanRange[FANOUT_LIMIT] stack = void;\n\n        size_t pcache = 0;\n\n        // let dmd allocate a register for this.pools\n        auto pools = pooltable.pools;\n        const highpool = pooltable.npools - 1;\n        const minAddr = pooltable.minAddr;\n        size_t memSize = pooltable.maxAddr - minAddr;\n\n        void* base = void;\n        void* top = void;\n\n        //printf(\"marking range: [%p..%p] (%#zx)\\n\", p1, p2, cast(size_t)p2 - cast(size_t)p1);\n        for (;;)\n        {\n            auto p = *p1;\n\n            //if (log) debug(PRINTF) printf(\"\\tmark %p\\n\", p);\n            if (cast(size_t)(p - minAddr) < memSize &&\n                (cast(size_t)p & ~cast(size_t)(PAGESIZE-1)) != pcache)\n            {\n                Pool* pool = void;\n                size_t low = 0;\n                size_t high = highpool;\n                while (true)\n                {\n                    size_t mid = (low + high) >> 1;\n                    pool = pools[mid];\n                    if (p < pool.baseAddr)\n                        high = mid - 1;\n                    else if (p >= pool.topAddr)\n                        low = mid + 1;\n                    else break;\n\n                    if (low > high)\n                        goto LnextPtr;\n                }\n                size_t offset = cast(size_t)(p - pool.baseAddr);\n                size_t biti = void;\n                size_t pn = offset / PAGESIZE;\n                size_t bin = pool.pagetable[pn]; // not Bins to avoid multiple size extension instructions\n\n                //debug(PRINTF) printf(\"\\t\\tfound pool %p, base=%p, pn = %zd, bin = %d, biti = x%x\\n\", pool, pool.baseAddr, pn, bin, biti);\n\n                // Adjust bit to be at start of allocated memory block\n                if (bin < B_PAGE)\n                {\n                    // We don't care abou setting pointsToBase correctly\n                    // because it's ignored for small object pools anyhow.\n                    auto offsetBase = offset & notbinsize[bin];\n                    biti = offsetBase >> Pool.ShiftBy.Small;\n                    //debug(PRINTF) printf(\"\\t\\tbiti = x%x\\n\", biti);\n\n                    if (!pool.mark.set(biti) && !pool.noscan.test(biti))\n                    {\n                        base = pool.baseAddr + offsetBase;\n                        top = base + binsize[bin];\n                        goto LaddRange;\n                    }\n                }\n                else if (bin == B_PAGE)\n                {\n                    biti = offset >> Pool.ShiftBy.Large;\n                    //debug(PRINTF) printf(\"\\t\\tbiti = x%x\\n\", biti);\n\n                    pcache = cast(size_t)p & ~cast(size_t)(PAGESIZE-1);\n                    base = cast(void*)pcache;\n\n                    // For the NO_INTERIOR attribute.  This tracks whether\n                    // the pointer is an interior pointer or points to the\n                    // base address of a block.\n                    if (base != sentinel_sub(p) && pool.nointerior.nbits && pool.nointerior.test(biti))\n                        goto LnextPtr;\n\n                    if (!pool.mark.set(biti) && !pool.noscan.test(biti))\n                    {\n                        top = base + pool.bPageOffsets[pn] * PAGESIZE;\n                        goto LaddRange;\n                    }\n                }\n                else if (bin == B_PAGEPLUS)\n                {\n                    pn -= pool.bPageOffsets[pn];\n                    biti = pn * (PAGESIZE >> Pool.ShiftBy.Large);\n\n                    pcache = cast(size_t)p & ~cast(size_t)(PAGESIZE-1);\n                    if (pool.nointerior.nbits && pool.nointerior.test(biti))\n                        goto LnextPtr;\n\n                    if (!pool.mark.set(biti) && !pool.noscan.test(biti))\n                    {\n                        base = pool.baseAddr + (pn * PAGESIZE);\n                        top = base + pool.bPageOffsets[pn] * PAGESIZE;\n                        goto LaddRange;\n                    }\n                }\n                else\n                {\n                    // Don't mark bits in B_FREE pages\n                    assert(bin == B_FREE);\n                }\n            }\n        LnextPtr:\n            if (++p1 < p2)\n                continue;\n\n            if (stackPos)\n            {\n                // pop range from local stack and recurse\n                auto next = &stack[--stackPos];\n                p1 = cast(void**)next.pbot;\n                p2 = cast(void**)next.ptop;\n            }\n            else if (!toscan.empty)\n            {\n                // pop range from global stack and recurse\n                auto next = toscan.pop();\n                p1 = cast(void**)next.pbot;\n                p2 = cast(void**)next.ptop;\n            }\n            else\n            {\n                // nothing more to do\n                break;\n            }\n            // printf(\"  pop [%p..%p] (%#zx)\\n\", p1, p2, cast(size_t)p2 - cast(size_t)p1);\n            pcache = 0;\n            continue;\n\n        LaddRange:\n            if (++p1 < p2)\n            {\n                if (stackPos < stack.length)\n                {\n                    stack[stackPos].pbot = base;\n                    stack[stackPos].ptop = top;\n                    stackPos++;\n                    continue;\n                }\n                toscan.push(ScanRange(p1, p2));\n                // reverse order for depth-first-order traversal\n                foreach_reverse (ref rng; stack)\n                    toscan.push(rng);\n                stackPos = 0;\n            }\n            // continue with last found range\n            p1 = cast(void**)base;\n            p2 = cast(void**)top;\n            pcache = 0;\n        }\n    }\n\n    // collection step 1: prepare freebits and mark bits\n    void prepare() nothrow\n    {\n        size_t n;\n        Pool*  pool;\n\n        for (n = 0; n < npools; n++)\n        {\n            pool = pooltable[n];\n            pool.mark.zero();\n            if (!pool.isLargeObject) pool.freebits.zero();\n        }\n\n        debug(COLLECT_PRINTF) printf(\"Set bits\\n\");\n\n        // Mark each free entry, so it doesn't get scanned\n        for (n = 0; n < B_PAGE; n++)\n        {\n            for (List *list = bucket[n]; list; list = list.next)\n            {\n                pool = list.pool;\n                assert(pool);\n                pool.freebits.set(cast(size_t)(cast(void*)list - pool.baseAddr) / 16);\n            }\n        }\n\n        debug(COLLECT_PRINTF) printf(\"Marked free entries.\\n\");\n\n        for (n = 0; n < npools; n++)\n        {\n            pool = pooltable[n];\n            if (!pool.isLargeObject)\n            {\n                pool.mark.copy(&pool.freebits);\n            }\n        }\n    }\n\n    // collection step 2: mark roots and heap\n    void markAll(bool nostack) nothrow\n    {\n        if (!nostack)\n        {\n            debug(COLLECT_PRINTF) printf(\"\\tscan stacks.\\n\");\n            // Scan stacks and registers for each paused thread\n            thread_scanAll(&mark);\n        }\n\n        // Scan roots[]\n        debug(COLLECT_PRINTF) printf(\"\\tscan roots[]\\n\");\n        foreach (root; roots)\n        {\n            mark(cast(void*)&root.proot, cast(void*)(&root.proot + 1));\n        }\n\n        // Scan ranges[]\n        debug(COLLECT_PRINTF) printf(\"\\tscan ranges[]\\n\");\n        //log++;\n        foreach (range; ranges)\n        {\n            debug(COLLECT_PRINTF) printf(\"\\t\\t%p .. %p\\n\", range.pbot, range.ptop);\n            mark(range.pbot, range.ptop);\n        }\n        //log--;\n    }\n\n    // collection step 3: free all unreferenced objects\n    size_t sweep() nothrow\n    {\n        // Free up everything not marked\n        debug(COLLECT_PRINTF) printf(\"\\tfree'ing\\n\");\n        size_t freedLargePages;\n        size_t freed;\n        for (size_t n = 0; n < npools; n++)\n        {\n            size_t pn;\n            Pool* pool = pooltable[n];\n\n            if (pool.isLargeObject)\n            {\n                for (pn = 0; pn < pool.npages; pn++)\n                {\n                    Bins bin = cast(Bins)pool.pagetable[pn];\n                    if (bin > B_PAGE) continue;\n                    size_t biti = pn;\n\n                    if (!pool.mark.test(biti))\n                    {\n                        void *p = pool.baseAddr + pn * PAGESIZE;\n                        void* q = sentinel_add(p);\n                        sentinel_Invariant(q);\n\n                        if (pool.finals.nbits && pool.finals.clear(biti))\n                        {\n                            size_t size = pool.bPageOffsets[pn] * PAGESIZE - SENTINEL_EXTRA;\n                            uint attr = pool.getBits(biti);\n                            rt_finalizeFromGC(q, size, attr);\n                        }\n\n                        pool.clrBits(biti, ~BlkAttr.NONE ^ BlkAttr.FINALIZE);\n\n                        debug(COLLECT_PRINTF) printf(\"\\tcollecting big %p\\n\", p);\n                        log_free(q);\n                        pool.pagetable[pn] = B_FREE;\n                        if (pn < pool.searchStart) pool.searchStart = pn;\n                        freedLargePages++;\n                        pool.freepages++;\n\n                        debug (MEMSTOMP) memset(p, 0xF3, PAGESIZE);\n                        while (pn + 1 < pool.npages && pool.pagetable[pn + 1] == B_PAGEPLUS)\n                        {\n                            pn++;\n                            pool.pagetable[pn] = B_FREE;\n\n                            // Don't need to update searchStart here because\n                            // pn is guaranteed to be greater than last time\n                            // we updated it.\n\n                            pool.freepages++;\n                            freedLargePages++;\n\n                            debug (MEMSTOMP)\n                            {   p += PAGESIZE;\n                                memset(p, 0xF3, PAGESIZE);\n                            }\n                        }\n                        pool.largestFree = pool.freepages; // invalidate\n                    }\n                }\n            }\n            else\n            {\n\n                for (pn = 0; pn < pool.npages; pn++)\n                {\n                    Bins bin = cast(Bins)pool.pagetable[pn];\n\n                    if (bin < B_PAGE)\n                    {\n                        immutable size = binsize[bin];\n                        void *p = pool.baseAddr + pn * PAGESIZE;\n                        void *ptop = p + PAGESIZE;\n                        immutable base = pn * (PAGESIZE/16);\n                        immutable bitstride = size / 16;\n\n                        bool freeBits;\n                        PageBits toFree;\n\n                        for (size_t i; p < ptop; p += size, i += bitstride)\n                        {\n                            immutable biti = base + i;\n\n                            if (!pool.mark.test(biti))\n                            {\n                                void* q = sentinel_add(p);\n                                sentinel_Invariant(q);\n\n                                if (pool.finals.nbits && pool.finals.test(biti))\n                                    rt_finalizeFromGC(q, size - SENTINEL_EXTRA, pool.getBits(biti));\n\n                                freeBits = true;\n                                toFree.set(i);\n\n                                debug(COLLECT_PRINTF) printf(\"\\tcollecting %p\\n\", p);\n                                log_free(sentinel_add(p));\n\n                                debug (MEMSTOMP) memset(p, 0xF3, size);\n\n                                freed += size;\n                            }\n                        }\n\n                        if (freeBits)\n                            pool.freePageBits(pn, toFree);\n                    }\n                }\n            }\n        }\n\n        assert(freedLargePages <= usedLargePages);\n        usedLargePages -= freedLargePages;\n        debug(COLLECT_PRINTF) printf(\"\\tfree'd %u bytes, %u pages from %u pools\\n\", freed, freedLargePages, npools);\n        return freedLargePages;\n    }\n\n    // collection step 4: recover pages with no live objects, rebuild free lists\n    size_t recover() nothrow\n    {\n        // init tail list\n        List**[B_PAGE] tail = void;\n        foreach (i, ref next; tail)\n            next = &bucket[i];\n\n        // Free complete pages, rebuild free list\n        debug(COLLECT_PRINTF) printf(\"\\tfree complete pages\\n\");\n        size_t freedSmallPages;\n        for (size_t n = 0; n < npools; n++)\n        {\n            size_t pn;\n            Pool* pool = pooltable[n];\n\n            if (pool.isLargeObject)\n                continue;\n\n            for (pn = 0; pn < pool.npages; pn++)\n            {\n                Bins   bin = cast(Bins)pool.pagetable[pn];\n                size_t biti;\n                size_t u;\n\n                if (bin < B_PAGE)\n                {\n                    size_t size = binsize[bin];\n                    size_t bitstride = size / 16;\n                    size_t bitbase = pn * (PAGESIZE / 16);\n                    size_t bittop = bitbase + (PAGESIZE / 16);\n                    void*  p;\n\n                    biti = bitbase;\n                    for (biti = bitbase; biti < bittop; biti += bitstride)\n                    {\n                        if (!pool.freebits.test(biti))\n                            goto Lnotfree;\n                    }\n                    pool.pagetable[pn] = B_FREE;\n                    if (pn < pool.searchStart) pool.searchStart = pn;\n                    pool.freepages++;\n                    freedSmallPages++;\n                    continue;\n\n                Lnotfree:\n                    p = pool.baseAddr + pn * PAGESIZE;\n                    for (u = 0; u < PAGESIZE; u += size)\n                    {\n                        biti = bitbase + u / 16;\n                        if (!pool.freebits.test(biti))\n                            continue;\n                        auto elem = cast(List *)(p + u);\n                        elem.pool = pool;\n                        *tail[bin] = elem;\n                        tail[bin] = &elem.next;\n                    }\n                }\n            }\n        }\n        // terminate tail list\n        foreach (ref next; tail)\n            *next = null;\n\n        assert(freedSmallPages <= usedSmallPages);\n        usedSmallPages -= freedSmallPages;\n        debug(COLLECT_PRINTF) printf(\"\\trecovered pages = %d\\n\", freedSmallPages);\n        return freedSmallPages;\n    }\n\n    /**\n     * Return number of full pages free'd.\n     */\n    size_t fullcollect(bool nostack = false) nothrow\n    {\n        // It is possible that `fullcollect` will be called from a thread which\n        // is not yet registered in runtime (because allocating `new Thread` is\n        // part of `thread_attachThis` implementation). In that case it is\n        // better not to try actually collecting anything\n\n        if (Thread.getThis() is null)\n            return 0;\n\n        MonoTime start, stop, begin;\n\n        if (config.profile)\n        {\n            begin = start = currTime;\n        }\n\n        debug(COLLECT_PRINTF) printf(\"Gcx.fullcollect()\\n\");\n        //printf(\"\\tpool address range = %p .. %p\\n\", minAddr, maxAddr);\n\n        {\n            // lock roots and ranges around suspending threads b/c they're not reentrant safe\n            rangesLock.lock();\n            rootsLock.lock();\n            scope (exit)\n            {\n                rangesLock.unlock();\n                rootsLock.unlock();\n            }\n            thread_suspendAll();\n\n            prepare();\n\n            if (config.profile)\n            {\n                stop = currTime;\n                prepTime += (stop - start);\n                start = stop;\n            }\n\n            markAll(nostack);\n\n            thread_processGCMarks(&isMarked);\n            thread_resumeAll();\n        }\n\n        if (config.profile)\n        {\n            stop = currTime;\n            markTime += (stop - start);\n            Duration pause = stop - begin;\n            if (pause > maxPauseTime)\n                maxPauseTime = pause;\n            start = stop;\n        }\n\n        ConservativeGC._inFinalizer = true;\n        size_t freedLargePages=void;\n        {\n            scope (failure) ConservativeGC._inFinalizer = false;\n            freedLargePages = sweep();\n            ConservativeGC._inFinalizer = false;\n        }\n\n        if (config.profile)\n        {\n            stop = currTime;\n            sweepTime += (stop - start);\n            start = stop;\n        }\n\n        immutable freedSmallPages = recover();\n\n        if (config.profile)\n        {\n            stop = currTime;\n            recoverTime += (stop - start);\n            ++numCollections;\n        }\n\n        updateCollectThresholds();\n\n        return freedLargePages + freedSmallPages;\n    }\n\n    /**\n     * Returns true if the addr lies within a marked block.\n     *\n     * Warning! This should only be called while the world is stopped inside\n     * the fullcollect function.\n     */\n    int isMarked(void *addr) scope nothrow\n    {\n        // first, we find the Pool this block is in, then check to see if the\n        // mark bit is clear.\n        auto pool = findPool(addr);\n        if (pool)\n        {\n            auto offset = cast(size_t)(addr - pool.baseAddr);\n            auto pn = offset / PAGESIZE;\n            auto bins = cast(Bins)pool.pagetable[pn];\n            size_t biti = void;\n            if (bins <= B_PAGE)\n            {\n                biti = (offset & notbinsize[bins]) >> pool.shiftBy;\n            }\n            else if (bins == B_PAGEPLUS)\n            {\n                pn -= pool.bPageOffsets[pn];\n                biti = pn * (PAGESIZE >> pool.ShiftBy.Large);\n            }\n            else // bins == B_FREE\n            {\n                assert(bins == B_FREE);\n                return IsMarked.no;\n            }\n            return pool.mark.test(biti) ? IsMarked.yes : IsMarked.no;\n        }\n        return IsMarked.unknown;\n    }\n\n\n    /***** Leak Detector ******/\n\n\n    debug (LOGGING)\n    {\n        LogArray current;\n        LogArray prev;\n\n\n        void log_init()\n        {\n            //debug(PRINTF) printf(\"+log_init()\\n\");\n            current.reserve(1000);\n            prev.reserve(1000);\n            //debug(PRINTF) printf(\"-log_init()\\n\");\n        }\n\n\n        void log_malloc(void *p, size_t size) nothrow\n        {\n            //debug(PRINTF) printf(\"+log_malloc(p = %p, size = %zd)\\n\", p, size);\n            Log log;\n\n            log.p = p;\n            log.size = size;\n            log.line = ConservativeGC.line;\n            log.file = ConservativeGC.file;\n            log.parent = null;\n\n            ConservativeGC.line = 0;\n            ConservativeGC.file = null;\n\n            current.push(log);\n            //debug(PRINTF) printf(\"-log_malloc()\\n\");\n        }\n\n\n        void log_free(void *p) nothrow @nogc\n        {\n            //debug(PRINTF) printf(\"+log_free(%p)\\n\", p);\n            auto i = current.find(p);\n            if (i == OPFAIL)\n            {\n                debug(PRINTF) printf(\"free'ing unallocated memory %p\\n\", p);\n            }\n            else\n                current.remove(i);\n            //debug(PRINTF) printf(\"-log_free()\\n\");\n        }\n\n\n        void log_collect() nothrow\n        {\n            //debug(PRINTF) printf(\"+log_collect()\\n\");\n            // Print everything in current that is not in prev\n\n            debug(PRINTF) printf(\"New pointers this cycle: --------------------------------\\n\");\n            size_t used = 0;\n            for (size_t i = 0; i < current.dim; i++)\n            {\n                auto j = prev.find(current.data[i].p);\n                if (j == OPFAIL)\n                    current.data[i].print();\n                else\n                    used++;\n            }\n\n            debug(PRINTF) printf(\"All roots this cycle: --------------------------------\\n\");\n            for (size_t i = 0; i < current.dim; i++)\n            {\n                void* p = current.data[i].p;\n                if (!findPool(current.data[i].parent))\n                {\n                    auto j = prev.find(current.data[i].p);\n                    debug(PRINTF) printf(j == OPFAIL ? \"N\" : \" \");\n                    current.data[i].print();\n                }\n            }\n\n            debug(PRINTF) printf(\"Used = %d-------------------------------------------------\\n\", used);\n            prev.copy(&current);\n\n            debug(PRINTF) printf(\"-log_collect()\\n\");\n        }\n\n\n        void log_parent(void *p, void *parent) nothrow\n        {\n            //debug(PRINTF) printf(\"+log_parent()\\n\");\n            auto i = current.find(p);\n            if (i == OPFAIL)\n            {\n                debug(PRINTF) printf(\"parent'ing unallocated memory %p, parent = %p\\n\", p, parent);\n                Pool *pool;\n                pool = findPool(p);\n                assert(pool);\n                size_t offset = cast(size_t)(p - pool.baseAddr);\n                size_t biti;\n                size_t pn = offset / PAGESIZE;\n                Bins bin = cast(Bins)pool.pagetable[pn];\n                biti = (offset & notbinsize[bin]);\n                debug(PRINTF) printf(\"\\tbin = %d, offset = x%x, biti = x%x\\n\", bin, offset, biti);\n            }\n            else\n            {\n                current.data[i].parent = parent;\n            }\n            //debug(PRINTF) printf(\"-log_parent()\\n\");\n        }\n\n    }\n    else\n    {\n        void log_init() nothrow { }\n        void log_malloc(void *p, size_t size) nothrow { }\n        void log_free(void *p) nothrow @nogc { }\n        void log_collect() nothrow { }\n        void log_parent(void *p, void *parent) nothrow { }\n    }\n}\n\n/* ============================ Pool  =============================== */\n\nstruct Pool\n{\n    void* baseAddr;\n    void* topAddr;\n    GCBits mark;        // entries already scanned, or should not be scanned\n    GCBits freebits;    // entries that are on the free list\n    GCBits finals;      // entries that need finalizer run on them\n    GCBits structFinals;// struct entries that need a finalzier run on them\n    GCBits noscan;      // entries that should not be scanned\n    GCBits appendable;  // entries that are appendable\n    GCBits nointerior;  // interior pointers should be ignored.\n                        // Only implemented for large object pools.\n    size_t npages;\n    size_t freepages;     // The number of pages not in use.\n    ubyte* pagetable;\n\n    bool isLargeObject;\n\n    enum ShiftBy\n    {\n        Small = 4,\n        Large = 12\n    }\n    ShiftBy shiftBy;    // shift count for the divisor used for determining bit indices.\n\n    // This tracks how far back we have to go to find the nearest B_PAGE at\n    // a smaller address than a B_PAGEPLUS.  To save space, we use a uint.\n    // This limits individual allocations to 16 terabytes, assuming a 4k\n    // pagesize.\n    uint* bPageOffsets;\n\n    // This variable tracks a conservative estimate of where the first free\n    // page in this pool is, so that if a lot of pages towards the beginning\n    // are occupied, we can bypass them in O(1).\n    size_t searchStart;\n    size_t largestFree; // upper limit for largest free chunk in large object pool\n\n    void initialize(size_t npages, bool isLargeObject) nothrow\n    {\n        this.isLargeObject = isLargeObject;\n        size_t poolsize;\n\n        shiftBy = isLargeObject ? ShiftBy.Large : ShiftBy.Small;\n\n        //debug(PRINTF) printf(\"Pool::Pool(%u)\\n\", npages);\n        poolsize = npages * PAGESIZE;\n        assert(poolsize >= POOLSIZE);\n        baseAddr = cast(byte *)os_mem_map(poolsize);\n\n        // Some of the code depends on page alignment of memory pools\n        assert((cast(size_t)baseAddr & (PAGESIZE - 1)) == 0);\n\n        if (!baseAddr)\n        {\n            //debug(PRINTF) printf(\"GC fail: poolsize = x%zx, errno = %d\\n\", poolsize, errno);\n            //debug(PRINTF) printf(\"message = '%s'\\n\", sys_errlist[errno]);\n\n            npages = 0;\n            poolsize = 0;\n        }\n        //assert(baseAddr);\n        topAddr = baseAddr + poolsize;\n        auto nbits = cast(size_t)poolsize >> shiftBy;\n\n        mark.alloc(nbits);\n\n        // pagetable already keeps track of what's free for the large object\n        // pool.\n        if (!isLargeObject)\n        {\n            freebits.alloc(nbits);\n        }\n\n        noscan.alloc(nbits);\n        appendable.alloc(nbits);\n\n        pagetable = cast(ubyte*)cstdlib.malloc(npages);\n        if (!pagetable)\n            onOutOfMemoryErrorNoGC();\n\n        if (isLargeObject)\n        {\n            bPageOffsets = cast(uint*)cstdlib.malloc(npages * uint.sizeof);\n            if (!bPageOffsets)\n                onOutOfMemoryErrorNoGC();\n        }\n\n        memset(pagetable, B_FREE, npages);\n\n        this.npages = npages;\n        this.freepages = npages;\n        this.searchStart = 0;\n        this.largestFree = npages;\n    }\n\n\n    void Dtor() nothrow\n    {\n        if (baseAddr)\n        {\n            int result;\n\n            if (npages)\n            {\n                result = os_mem_unmap(baseAddr, npages * PAGESIZE);\n                assert(result == 0);\n                npages = 0;\n            }\n\n            baseAddr = null;\n            topAddr = null;\n        }\n        if (pagetable)\n        {\n            cstdlib.free(pagetable);\n            pagetable = null;\n        }\n\n        if (bPageOffsets)\n            cstdlib.free(bPageOffsets);\n\n        mark.Dtor();\n        if (isLargeObject)\n        {\n            nointerior.Dtor();\n        }\n        else\n        {\n            freebits.Dtor();\n        }\n        finals.Dtor();\n        structFinals.Dtor();\n        noscan.Dtor();\n        appendable.Dtor();\n    }\n\n    /**\n    *\n    */\n    uint getBits(size_t biti) nothrow\n    {\n        uint bits;\n\n        if (finals.nbits && finals.test(biti))\n            bits |= BlkAttr.FINALIZE;\n        if (structFinals.nbits && structFinals.test(biti))\n            bits |= BlkAttr.STRUCTFINAL;\n        if (noscan.test(biti))\n            bits |= BlkAttr.NO_SCAN;\n        if (nointerior.nbits && nointerior.test(biti))\n            bits |= BlkAttr.NO_INTERIOR;\n        if (appendable.test(biti))\n            bits |= BlkAttr.APPENDABLE;\n        return bits;\n    }\n\n    /**\n     *\n     */\n    void clrBits(size_t biti, uint mask) nothrow @nogc\n    {\n        immutable dataIndex =  biti >> GCBits.BITS_SHIFT;\n        immutable bitOffset = biti & GCBits.BITS_MASK;\n        immutable keep = ~(GCBits.BITS_1 << bitOffset);\n\n        if (mask & BlkAttr.FINALIZE && finals.nbits)\n            finals.data[dataIndex] &= keep;\n\n        if (structFinals.nbits && (mask & BlkAttr.STRUCTFINAL))\n            structFinals.data[dataIndex] &= keep;\n\n        if (mask & BlkAttr.NO_SCAN)\n            noscan.data[dataIndex] &= keep;\n        if (mask & BlkAttr.APPENDABLE)\n            appendable.data[dataIndex] &= keep;\n        if (nointerior.nbits && (mask & BlkAttr.NO_INTERIOR))\n            nointerior.data[dataIndex] &= keep;\n    }\n\n    /**\n     *\n     */\n    void setBits(size_t biti, uint mask) nothrow\n    {\n        // Calculate the mask and bit offset once and then use it to\n        // set all of the bits we need to set.\n        immutable dataIndex = biti >> GCBits.BITS_SHIFT;\n        immutable bitOffset = biti & GCBits.BITS_MASK;\n        immutable orWith = GCBits.BITS_1 << bitOffset;\n\n        if (mask & BlkAttr.STRUCTFINAL)\n        {\n            if (!structFinals.nbits)\n                structFinals.alloc(mark.nbits);\n            structFinals.data[dataIndex] |= orWith;\n        }\n\n        if (mask & BlkAttr.FINALIZE)\n        {\n            if (!finals.nbits)\n                finals.alloc(mark.nbits);\n            finals.data[dataIndex] |= orWith;\n        }\n\n        if (mask & BlkAttr.NO_SCAN)\n        {\n            noscan.data[dataIndex] |= orWith;\n        }\n//        if (mask & BlkAttr.NO_MOVE)\n//        {\n//            if (!nomove.nbits)\n//                nomove.alloc(mark.nbits);\n//            nomove.data[dataIndex] |= orWith;\n//        }\n        if (mask & BlkAttr.APPENDABLE)\n        {\n            appendable.data[dataIndex] |= orWith;\n        }\n\n        if (isLargeObject && (mask & BlkAttr.NO_INTERIOR))\n        {\n            if (!nointerior.nbits)\n                nointerior.alloc(mark.nbits);\n            nointerior.data[dataIndex] |= orWith;\n        }\n    }\n\n    void freePageBits(size_t pagenum, in ref PageBits toFree) nothrow\n    {\n        assert(!isLargeObject);\n        assert(!nointerior.nbits); // only for large objects\n\n        import core.internal.traits : staticIota;\n        immutable beg = pagenum * (PAGESIZE / 16 / GCBits.BITS_PER_WORD);\n        foreach (i; staticIota!(0, PageBits.length))\n        {\n            immutable w = toFree[i];\n            if (!w) continue;\n\n            immutable wi = beg + i;\n            freebits.data[wi] |= w;\n            noscan.data[wi] &= ~w;\n            appendable.data[wi] &= ~w;\n        }\n\n        if (finals.nbits)\n        {\n            foreach (i; staticIota!(0, PageBits.length))\n                if (toFree[i])\n                    finals.data[beg + i] &= ~toFree[i];\n        }\n\n        if (structFinals.nbits)\n        {\n            foreach (i; staticIota!(0, PageBits.length))\n                if (toFree[i])\n                    structFinals.data[beg + i] &= ~toFree[i];\n        }\n    }\n\n    /**\n     * Given a pointer p in the p, return the pagenum.\n     */\n    size_t pagenumOf(void *p) const nothrow @nogc\n    in\n    {\n        assert(p >= baseAddr);\n        assert(p < topAddr);\n    }\n    do\n    {\n        return cast(size_t)(p - baseAddr) / PAGESIZE;\n    }\n\n    @property bool isFree() const pure nothrow\n    {\n        return npages == freepages;\n    }\n\n    size_t slGetSize(void* p) nothrow @nogc\n    {\n        if (isLargeObject)\n            return (cast(LargeObjectPool*)&this).getSize(p);\n        else\n            return (cast(SmallObjectPool*)&this).getSize(p);\n    }\n\n    BlkInfo slGetInfo(void* p) nothrow\n    {\n        if (isLargeObject)\n            return (cast(LargeObjectPool*)&this).getInfo(p);\n        else\n            return (cast(SmallObjectPool*)&this).getInfo(p);\n    }\n\n\n    void Invariant() const {}\n\n    debug(INVARIANT)\n    invariant()\n    {\n        //mark.Invariant();\n        //scan.Invariant();\n        //freebits.Invariant();\n        //finals.Invariant();\n        //structFinals.Invariant();\n        //noscan.Invariant();\n        //appendable.Invariant();\n        //nointerior.Invariant();\n\n        if (baseAddr)\n        {\n            //if (baseAddr + npages * PAGESIZE != topAddr)\n                //printf(\"baseAddr = %p, npages = %d, topAddr = %p\\n\", baseAddr, npages, topAddr);\n            assert(baseAddr + npages * PAGESIZE == topAddr);\n        }\n\n        if (pagetable !is null)\n        {\n            for (size_t i = 0; i < npages; i++)\n            {\n                Bins bin = cast(Bins)pagetable[i];\n                assert(bin < B_MAX);\n            }\n        }\n    }\n}\n\nstruct LargeObjectPool\n{\n    Pool base;\n    alias base this;\n\n    void updateOffsets(size_t fromWhere) nothrow\n    {\n        assert(pagetable[fromWhere] == B_PAGE);\n        size_t pn = fromWhere + 1;\n        for (uint offset = 1; pn < npages; pn++, offset++)\n        {\n            if (pagetable[pn] != B_PAGEPLUS) break;\n            bPageOffsets[pn] = offset;\n        }\n\n        // Store the size of the block in bPageOffsets[fromWhere].\n        bPageOffsets[fromWhere] = cast(uint) (pn - fromWhere);\n    }\n\n    /**\n     * Allocate n pages from Pool.\n     * Returns OPFAIL on failure.\n     */\n    size_t allocPages(size_t n) nothrow\n    {\n        if (largestFree < n || searchStart + n > npages)\n            return OPFAIL;\n\n        //debug(PRINTF) printf(\"Pool::allocPages(n = %d)\\n\", n);\n        size_t largest = 0;\n        if (pagetable[searchStart] == B_PAGEPLUS)\n        {\n            searchStart -= bPageOffsets[searchStart]; // jump to B_PAGE\n            searchStart += bPageOffsets[searchStart];\n        }\n        while (searchStart < npages && pagetable[searchStart] == B_PAGE)\n            searchStart += bPageOffsets[searchStart];\n\n        for (size_t i = searchStart; i < npages; )\n        {\n            assert(pagetable[i] == B_FREE);\n            size_t p = 1;\n            while (p < n && i + p < npages && pagetable[i + p] == B_FREE)\n                p++;\n\n            if (p == n)\n                return i;\n\n            if (p > largest)\n                largest = p;\n\n            i += p;\n            while (i < npages && pagetable[i] == B_PAGE)\n            {\n                // we have the size information, so we skip a whole bunch of pages.\n                i += bPageOffsets[i];\n            }\n        }\n\n        // not enough free pages found, remember largest free chunk\n        largestFree = largest;\n        return OPFAIL;\n    }\n\n    /**\n     * Free npages pages starting with pagenum.\n     */\n    void freePages(size_t pagenum, size_t npages) nothrow @nogc\n    {\n        //memset(&pagetable[pagenum], B_FREE, npages);\n        if (pagenum < searchStart)\n            searchStart = pagenum;\n\n        for (size_t i = pagenum; i < npages + pagenum; i++)\n        {\n            if (pagetable[i] < B_FREE)\n            {\n                freepages++;\n            }\n\n            pagetable[i] = B_FREE;\n        }\n        largestFree = freepages; // invalidate\n    }\n\n    /**\n     * Get size of pointer p in pool.\n     */\n    size_t getSize(void *p) const nothrow @nogc\n    in\n    {\n        assert(p >= baseAddr);\n        assert(p < topAddr);\n    }\n    do\n    {\n        size_t pagenum = pagenumOf(p);\n        Bins bin = cast(Bins)pagetable[pagenum];\n        assert(bin == B_PAGE);\n        return bPageOffsets[pagenum] * PAGESIZE;\n    }\n\n    /**\n    *\n    */\n    BlkInfo getInfo(void* p) nothrow\n    {\n        BlkInfo info;\n\n        size_t offset = cast(size_t)(p - baseAddr);\n        size_t pn = offset / PAGESIZE;\n        Bins bin = cast(Bins)pagetable[pn];\n\n        if (bin == B_PAGEPLUS)\n            pn -= bPageOffsets[pn];\n        else if (bin != B_PAGE)\n            return info;           // no info for free pages\n\n        info.base = baseAddr + pn * PAGESIZE;\n        info.size = bPageOffsets[pn] * PAGESIZE;\n\n        info.attr = getBits(pn);\n        return info;\n    }\n\n    void runFinalizers(in void[] segment) nothrow\n    {\n        foreach (pn; 0 .. npages)\n        {\n            Bins bin = cast(Bins)pagetable[pn];\n            if (bin > B_PAGE)\n                continue;\n            size_t biti = pn;\n\n            if (!finals.test(biti))\n                continue;\n\n            auto p = sentinel_add(baseAddr + pn * PAGESIZE);\n            size_t size = bPageOffsets[pn] * PAGESIZE - SENTINEL_EXTRA;\n            uint attr = getBits(biti);\n\n            if (!rt_hasFinalizerInSegment(p, size, attr, segment))\n                continue;\n\n            rt_finalizeFromGC(p, size, attr);\n\n            clrBits(biti, ~BlkAttr.NONE);\n\n            if (pn < searchStart)\n                searchStart = pn;\n\n            debug(COLLECT_PRINTF) printf(\"\\tcollecting big %p\\n\", p);\n            //log_free(sentinel_add(p));\n\n            size_t n = 1;\n            for (; pn + n < npages; ++n)\n                if (pagetable[pn + n] != B_PAGEPLUS)\n                    break;\n            debug (MEMSTOMP) memset(baseAddr + pn * PAGESIZE, 0xF3, n * PAGESIZE);\n            freePages(pn, n);\n        }\n    }\n}\n\n\nstruct SmallObjectPool\n{\n    Pool base;\n    alias base this;\n\n    /**\n    * Get size of pointer p in pool.\n    */\n    size_t getSize(void *p) const nothrow @nogc\n    in\n    {\n        assert(p >= baseAddr);\n        assert(p < topAddr);\n    }\n    do\n    {\n        size_t pagenum = pagenumOf(p);\n        Bins bin = cast(Bins)pagetable[pagenum];\n        assert(bin < B_PAGE);\n        return binsize[bin];\n    }\n\n    BlkInfo getInfo(void* p) nothrow\n    {\n        BlkInfo info;\n        size_t offset = cast(size_t)(p - baseAddr);\n        size_t pn = offset / PAGESIZE;\n        Bins   bin = cast(Bins)pagetable[pn];\n\n        if (bin >= B_PAGE)\n            return info;\n\n        info.base = cast(void*)((cast(size_t)p) & notbinsize[bin]);\n        info.size = binsize[bin];\n        offset = info.base - baseAddr;\n        info.attr = getBits(cast(size_t)(offset >> ShiftBy.Small));\n\n        return info;\n    }\n\n    void runFinalizers(in void[] segment) nothrow\n    {\n        foreach (pn; 0 .. npages)\n        {\n            Bins bin = cast(Bins)pagetable[pn];\n            if (bin >= B_PAGE)\n                continue;\n\n            immutable size = binsize[bin];\n            auto p = baseAddr + pn * PAGESIZE;\n            const ptop = p + PAGESIZE;\n            immutable base = pn * (PAGESIZE/16);\n            immutable bitstride = size / 16;\n\n            bool freeBits;\n            PageBits toFree;\n\n            for (size_t i; p < ptop; p += size, i += bitstride)\n            {\n                immutable biti = base + i;\n\n                if (!finals.test(biti))\n                    continue;\n\n                auto q = sentinel_add(p);\n                uint attr = getBits(biti);\n\n                if (!rt_hasFinalizerInSegment(q, size, attr, segment))\n                    continue;\n\n                rt_finalizeFromGC(q, size, attr);\n\n                freeBits = true;\n                toFree.set(i);\n\n                debug(COLLECT_PRINTF) printf(\"\\tcollecting %p\\n\", p);\n                //log_free(sentinel_add(p));\n\n                debug (MEMSTOMP) memset(p, 0xF3, size);\n            }\n\n            if (freeBits)\n                freePageBits(pn, toFree);\n        }\n    }\n\n    /**\n    * Allocate a page of bin's.\n    * Returns:\n    *           head of a single linked list of new entries\n    */\n    List* allocPage(Bins bin) nothrow\n    {\n        size_t pn;\n        for (pn = searchStart; pn < npages; pn++)\n            if (pagetable[pn] == B_FREE)\n                goto L1;\n\n        return null;\n\n    L1:\n        searchStart = pn + 1;\n        pagetable[pn] = cast(ubyte)bin;\n        freepages--;\n\n        // Convert page to free list\n        size_t size = binsize[bin];\n        void* p = baseAddr + pn * PAGESIZE;\n        void* ptop = p + PAGESIZE - size;\n        auto first = cast(List*) p;\n\n        for (; p < ptop; p += size)\n        {\n            (cast(List *)p).next = cast(List *)(p + size);\n            (cast(List *)p).pool = &base;\n        }\n        (cast(List *)p).next = null;\n        (cast(List *)p).pool = &base;\n        return first;\n    }\n}\n\nunittest // bugzilla 14467\n{\n    int[] arr = new int[10];\n    assert(arr.capacity);\n    arr = arr[$..$];\n    assert(arr.capacity);\n}\n\nunittest // bugzilla 15353\n{\n    import core.memory : GC;\n\n    static struct Foo\n    {\n        ~this()\n        {\n            GC.free(buf); // ignored in finalizer\n        }\n\n        void* buf;\n    }\n    new Foo(GC.malloc(10));\n    GC.collect();\n}\n\nunittest // bugzilla 15822\n{\n    import core.memory : GC;\n\n    __gshared ubyte[16] buf;\n    static struct Foo\n    {\n        ~this()\n        {\n            GC.removeRange(ptr);\n            GC.removeRoot(ptr);\n        }\n\n        ubyte* ptr;\n    }\n    GC.addRoot(buf.ptr);\n    GC.addRange(buf.ptr, buf.length);\n    new Foo(buf.ptr);\n    GC.collect();\n}\n\nunittest // bugzilla 1180\n{\n    import core.exception;\n    try\n    {\n        size_t x = size_t.max - 100;\n        byte[] big_buf = new byte[x];\n    }\n    catch (OutOfMemoryError)\n    {\n    }\n}\n\n/* ============================ SENTINEL =============================== */\n\n\ndebug (SENTINEL)\n{\n    const size_t SENTINEL_PRE = cast(size_t) 0xF4F4F4F4F4F4F4F4UL; // 32 or 64 bits\n    const ubyte SENTINEL_POST = 0xF5;           // 8 bits\n    const uint SENTINEL_EXTRA = 2 * size_t.sizeof + 1;\n\n\n    inout(size_t*) sentinel_size(inout void *p) nothrow { return &(cast(inout size_t *)p)[-2]; }\n    inout(size_t*) sentinel_pre(inout void *p)  nothrow { return &(cast(inout size_t *)p)[-1]; }\n    inout(ubyte*) sentinel_post(inout void *p)  nothrow { return &(cast(inout ubyte *)p)[*sentinel_size(p)]; }\n\n\n    void sentinel_init(void *p, size_t size) nothrow\n    {\n        *sentinel_size(p) = size;\n        *sentinel_pre(p) = SENTINEL_PRE;\n        *sentinel_post(p) = SENTINEL_POST;\n    }\n\n\n    void sentinel_Invariant(const void *p) nothrow @nogc\n    {\n        debug\n        {\n            assert(*sentinel_pre(p) == SENTINEL_PRE);\n            assert(*sentinel_post(p) == SENTINEL_POST);\n        }\n        else if (*sentinel_pre(p) != SENTINEL_PRE || *sentinel_post(p) != SENTINEL_POST)\n            onInvalidMemoryOperationError(); // also trigger in release build\n    }\n\n\n    void *sentinel_add(void *p) nothrow @nogc\n    {\n        return p + 2 * size_t.sizeof;\n    }\n\n\n    void *sentinel_sub(void *p) nothrow @nogc\n    {\n        return p - 2 * size_t.sizeof;\n    }\n}\nelse\n{\n    const uint SENTINEL_EXTRA = 0;\n\n\n    void sentinel_init(void *p, size_t size) nothrow\n    {\n    }\n\n\n    void sentinel_Invariant(const void *p) nothrow @nogc\n    {\n    }\n\n\n    void *sentinel_add(void *p) nothrow @nogc\n    {\n        return p;\n    }\n\n\n    void *sentinel_sub(void *p) nothrow @nogc\n    {\n        return p;\n    }\n}\n\ndebug (MEMSTOMP)\nunittest\n{\n    import core.memory;\n    auto p = cast(uint*)GC.malloc(uint.sizeof*3);\n    assert(*p == 0xF0F0F0F0);\n    p[2] = 0; // First two will be used for free list\n    GC.free(p);\n    assert(p[2] == 0xF2F2F2F2);\n}\n\ndebug (SENTINEL)\nunittest\n{\n    import core.memory;\n    auto p = cast(ubyte*)GC.malloc(1);\n    assert(p[-1] == 0xF4);\n    assert(p[ 1] == 0xF5);\n/*\n    p[1] = 0;\n    bool thrown;\n    try\n        GC.free(p);\n    catch (Error e)\n        thrown = true;\n    p[1] = 0xF5;\n    assert(thrown);\n*/\n}\n\nunittest\n{\n    import core.memory;\n\n    // https://issues.dlang.org/show_bug.cgi?id=9275\n    GC.removeRoot(null);\n    GC.removeRoot(cast(void*)13);\n}\n\n// improve predictability of coverage of code that is eventually not hit by other tests\nunittest\n{\n    import core.memory;\n    auto p = GC.malloc(260 << 20); // new pool has 390 MB\n    auto q = GC.malloc(65 << 20);  // next chunk (larger than 64MB to ensure the same pool is used)\n    auto r = GC.malloc(65 << 20);  // another chunk in same pool\n    assert(p + (260 << 20) == q);\n    assert(q + (65 << 20) == r);\n    GC.free(q);\n    // should trigger \"assert(bin == B_FREE);\" in mark due to dangling pointer q:\n    GC.collect();\n    // should trigger \"break;\" in extendNoSync:\n    size_t sz = GC.extend(p, 64 << 20, 66 << 20); // trigger size after p large enough (but limited)\n    assert(sz == 325 << 20);\n    GC.free(p);\n    GC.free(r);\n    r = q; // ensure q is not trashed before collection above\n\n    p = GC.malloc(70 << 20); // from the same pool\n    q = GC.malloc(70 << 20);\n    r = GC.malloc(70 << 20);\n    auto s = GC.malloc(70 << 20);\n    auto t = GC.malloc(70 << 20); // 350 MB of 390 MB used\n    assert(p + (70 << 20) == q);\n    assert(q + (70 << 20) == r);\n    assert(r + (70 << 20) == s);\n    assert(s + (70 << 20) == t);\n    GC.free(r); // ensure recalculation of largestFree in nxxt allocPages\n    auto z = GC.malloc(75 << 20); // needs new pool\n\n    GC.free(p);\n    GC.free(q);\n    GC.free(s);\n    GC.free(t);\n    GC.free(z);\n    GC.minimize(); // release huge pool\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/gc/impl/manual/gc.d",
    "content": "/**\n * This module contains a minimal garbage collector implementation according to\n * published requirements.  This library is mostly intended to serve as an\n * example, but it is usable in applications which do not rely on a garbage\n * collector to clean up memory (ie. when dynamic array resizing is not used,\n * and all memory allocated with 'new' is freed deterministically with\n * 'delete').\n *\n * Please note that block attribute data must be tracked, or at a minimum, the\n * FINALIZE bit must be tracked for any allocated memory block because calling\n * rt_finalize on a non-object block can result in an access violation.  In the\n * allocator below, this tracking is done via a leading uint bitmask.  A real\n * allocator may do better to store this data separately, similar to the basic\n * GC.\n *\n * Copyright: Copyright Sean Kelly 2005 - 2016.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Sean Kelly\n */\n\n/*          Copyright Sean Kelly 2005 - 2016.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule gc.impl.manual.gc;\n\nimport gc.config;\nimport gc.gcinterface;\n\nimport rt.util.container.array;\n\nimport cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc;\nstatic import core.memory;\n\nextern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */\n\nclass ManualGC : GC\n{\n    __gshared Array!Root roots;\n    __gshared Array!Range ranges;\n\n    static void initialize(ref GC gc)\n    {\n        import core.stdc.string;\n\n        if (config.gc != \"manual\")\n            return;\n\n        auto p = cstdlib.malloc(__traits(classInstanceSize, ManualGC));\n        if (!p)\n            onOutOfMemoryError();\n\n        auto init = typeid(ManualGC).initializer();\n        assert(init.length == __traits(classInstanceSize, ManualGC));\n        auto instance = cast(ManualGC) memcpy(p, init.ptr, init.length);\n        instance.__ctor();\n\n        gc = instance;\n    }\n\n    static void finalize(ref GC gc)\n    {\n        if (config.gc != \"manual\")\n            return;\n\n        auto instance = cast(ManualGC) gc;\n        instance.Dtor();\n        cstdlib.free(cast(void*) instance);\n    }\n\n    this()\n    {\n    }\n\n    void Dtor()\n    {\n    }\n\n    void enable()\n    {\n    }\n\n    void disable()\n    {\n    }\n\n    void collect() nothrow\n    {\n    }\n\n    void collectNoStack() nothrow\n    {\n    }\n\n    void minimize() nothrow\n    {\n    }\n\n    uint getAttr(void* p) nothrow\n    {\n        return 0;\n    }\n\n    uint setAttr(void* p, uint mask) nothrow\n    {\n        return 0;\n    }\n\n    uint clrAttr(void* p, uint mask) nothrow\n    {\n        return 0;\n    }\n\n    void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n        void* p = cstdlib.malloc(size);\n\n        if (size && p is null)\n            onOutOfMemoryError();\n        return p;\n    }\n\n    BlkInfo qalloc(size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n        BlkInfo retval;\n        retval.base = malloc(size, bits, ti);\n        retval.size = size;\n        retval.attr = bits;\n        return retval;\n    }\n\n    void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n        void* p = cstdlib.calloc(1, size);\n\n        if (size && p is null)\n            onOutOfMemoryError();\n        return p;\n    }\n\n    void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n        p = cstdlib.realloc(p, size);\n\n        if (size && p is null)\n            onOutOfMemoryError();\n        return p;\n    }\n\n    size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow\n    {\n        return 0;\n    }\n\n    size_t reserve(size_t size) nothrow\n    {\n        return 0;\n    }\n\n    void free(void* p) nothrow @nogc\n    {\n        cstdlib.free(p);\n    }\n\n    /**\n     * Determine the base address of the block containing p.  If p is not a gc\n     * allocated pointer, return null.\n     */\n    void* addrOf(void* p) nothrow @nogc\n    {\n        return null;\n    }\n\n    /**\n     * Determine the allocated size of pointer p.  If p is an interior pointer\n     * or not a gc allocated pointer, return 0.\n     */\n    size_t sizeOf(void* p) nothrow @nogc\n    {\n        return 0;\n    }\n\n    /**\n     * Determine the base address of the block containing p.  If p is not a gc\n     * allocated pointer, return null.\n     */\n    BlkInfo query(void* p) nothrow\n    {\n        return BlkInfo.init;\n    }\n\n    core.memory.GC.Stats stats() nothrow\n    {\n        return typeof(return).init;\n    }\n\n    void addRoot(void* p) nothrow @nogc\n    {\n        roots.insertBack(Root(p));\n    }\n\n    void removeRoot(void* p) nothrow @nogc\n    {\n        foreach (ref r; roots)\n        {\n            if (r is p)\n            {\n                r = roots.back;\n                roots.popBack();\n                return;\n            }\n        }\n        assert(false);\n    }\n\n    @property RootIterator rootIter() return @nogc\n    {\n        return &rootsApply;\n    }\n\n    private int rootsApply(scope int delegate(ref Root) nothrow dg)\n    {\n        foreach (ref r; roots)\n        {\n            if (auto result = dg(r))\n                return result;\n        }\n        return 0;\n    }\n\n    void addRange(void* p, size_t sz, const TypeInfo ti = null) nothrow @nogc\n    {\n        ranges.insertBack(Range(p, p + sz, cast() ti));\n    }\n\n    void removeRange(void* p) nothrow @nogc\n    {\n        foreach (ref r; ranges)\n        {\n            if (r.pbot is p)\n            {\n                r = ranges.back;\n                ranges.popBack();\n                return;\n            }\n        }\n        assert(false);\n    }\n\n    @property RangeIterator rangeIter() return @nogc\n    {\n        return &rangesApply;\n    }\n\n    private int rangesApply(scope int delegate(ref Range) nothrow dg)\n    {\n        foreach (ref r; ranges)\n        {\n            if (auto result = dg(r))\n                return result;\n        }\n        return 0;\n    }\n\n    void runFinalizers(in void[] segment) nothrow\n    {\n    }\n\n    bool inFinalizer() nothrow\n    {\n        return false;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gc/impl/proto/gc.d",
    "content": "\nmodule gc.impl.proto.gc;\n\nimport gc.config;\nimport gc.gcinterface;\n\nimport rt.util.container.array;\n\nimport cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc;\nstatic import core.memory;\n\nextern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */\n\nprivate\n{\n    extern (C) void gc_init_nothrow() nothrow @nogc;\n    extern (C) void gc_term();\n\n    extern (C) void gc_enable() nothrow;\n    extern (C) void gc_disable() nothrow;\n\n    extern (C) void*    gc_malloc( size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow;\n    extern (C) void*    gc_calloc( size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow;\n    extern (C) BlkInfo gc_qalloc( size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow;\n    extern (C) void*    gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow;\n    extern (C) size_t   gc_reserve( size_t sz ) nothrow;\n\n    extern (C) void gc_addRange( void* p, size_t sz, const TypeInfo ti = null ) nothrow @nogc;\n    extern (C) void gc_addRoot( void* p ) nothrow @nogc;\n}\n\nclass ProtoGC : GC\n{\n    Array!Root roots;\n    Array!Range ranges;\n\n    // Call this function when initializing the real GC\n    // upon ProtoGC term. This function should be called\n    // after the real GC is in place.\n    void term()\n    {\n        // Transfer all ranges\n        foreach (ref r; ranges)\n        {\n            // Range(p, p + sz, cast() ti)\n            gc_addRange(r.pbot, r.ptop - r.pbot, r.ti);\n        }\n\n        // Transfer all roots\n        foreach (ref r; roots)\n        {\n            gc_addRoot(r.proot);\n        }\n    }\n\n    this()\n    {\n    }\n\n    void Dtor()\n    {\n    }\n\n    void enable()\n    {\n        .gc_init_nothrow();\n        .gc_enable();\n    }\n\n    void disable()\n    {\n        .gc_init_nothrow();\n        .gc_disable();\n    }\n\n    void collect() nothrow\n    {\n    }\n\n    void collectNoStack() nothrow\n    {\n    }\n\n    void minimize() nothrow\n    {\n    }\n\n    uint getAttr(void* p) nothrow\n    {\n        return 0;\n    }\n\n    uint setAttr(void* p, uint mask) nothrow\n    {\n        return 0;\n    }\n\n    uint clrAttr(void* p, uint mask) nothrow\n    {\n        return 0;\n    }\n\n    void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n        .gc_init_nothrow();\n        return .gc_malloc(size, bits, ti);\n    }\n\n    BlkInfo qalloc(size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n        .gc_init_nothrow();\n        return .gc_qalloc(size, bits, ti);\n    }\n\n    void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n        .gc_init_nothrow();\n        return .gc_calloc(size, bits, ti);\n    }\n\n    void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow\n    {\n        .gc_init_nothrow();\n        return .gc_realloc(p, size, bits, ti);\n    }\n\n    size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow\n    {\n        return 0;\n    }\n\n    size_t reserve(size_t size) nothrow\n    {\n        .gc_init_nothrow();\n        return .gc_reserve(size);\n    }\n\n    void free(void* p) nothrow @nogc\n    {\n        if (p) assert(false, \"Invalid memory deallocation\");\n    }\n\n    void* addrOf(void* p) nothrow @nogc\n    {\n        return null;\n    }\n\n    size_t sizeOf(void* p) nothrow @nogc\n    {\n        return 0;\n    }\n\n    BlkInfo query(void* p) nothrow\n    {\n        return BlkInfo.init;\n    }\n\n    core.memory.GC.Stats stats() nothrow\n    {\n        return typeof(return).init;\n    }\n\n\n    void addRoot(void* p) nothrow @nogc\n    {\n        roots.insertBack(Root(p));\n    }\n\n    void removeRoot(void* p) nothrow @nogc\n    {\n        foreach (ref r; roots)\n        {\n            if (r is p)\n            {\n                r = roots.back;\n                roots.popBack();\n                return;\n            }\n        }\n    }\n\n    @property RootIterator rootIter() return @nogc\n    {\n        return &rootsApply;\n    }\n\n    private int rootsApply(scope int delegate(ref Root) nothrow dg)\n    {\n        foreach (ref r; roots)\n        {\n            if (auto result = dg(r))\n                return result;\n        }\n        return 0;\n    }\n\n    void addRange(void* p, size_t sz, const TypeInfo ti = null) nothrow @nogc\n    {\n        ranges.insertBack(Range(p, p + sz, cast() ti));\n    }\n\n    void removeRange(void* p) nothrow @nogc\n    {\n        foreach (ref r; ranges)\n        {\n            if (r.pbot is p)\n            {\n                r = ranges.back;\n                ranges.popBack();\n                return;\n            }\n        }\n    }\n\n    @property RangeIterator rangeIter() return @nogc\n    {\n        return &rangesApply;\n    }\n\n    private int rangesApply(scope int delegate(ref Range) nothrow dg)\n    {\n        foreach (ref r; ranges)\n        {\n            if (auto result = dg(r))\n                return result;\n        }\n        return 0;\n    }\n\n    void runFinalizers(in void[] segment) nothrow\n    {\n    }\n\n    bool inFinalizer() nothrow\n    {\n        return false;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gc/os.d",
    "content": "/**\n * Contains OS-level routines needed by the garbage collector.\n *\n * Copyright: Copyright Digital Mars 2005 - 2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, David Friedman, Sean Kelly, Leandro Lucarella\n */\n\n/*          Copyright Digital Mars 2005 - 2013.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule gc.os;\n\n\nversion (Windows)\n{\n    import core.sys.windows.windows;\n\n    alias int pthread_t;\n\n    pthread_t pthread_self() nothrow\n    {\n        return cast(pthread_t) GetCurrentThreadId();\n    }\n\n    //version = GC_Use_Alloc_Win32;\n}\nelse version (Posix)\n{\n    version (OSX)\n        version = Darwin;\n    else version (iOS)\n        version = Darwin;\n    else version (TVOS)\n        version = Darwin;\n    else version (WatchOS)\n        version = Darwin;\n\n    import core.sys.posix.sys.mman;\n    version (FreeBSD) import core.sys.freebsd.sys.mman : MAP_ANON;\n    version (DragonFlyBSD) import core.sys.dragonflybsd.sys.mman : MAP_ANON;\n    version (NetBSD) import core.sys.netbsd.sys.mman : MAP_ANON;\n    version (CRuntime_Glibc) import core.sys.linux.sys.mman : MAP_ANON;\n    version (Darwin) import core.sys.darwin.sys.mman : MAP_ANON;\n    version (CRuntime_UClibc) import core.sys.linux.sys.mman : MAP_ANON;\n    import core.stdc.stdlib;\n\n    //version = GC_Use_Alloc_MMap;\n}\nelse\n{\n    import core.stdc.stdlib;\n\n    //version = GC_Use_Alloc_Malloc;\n}\n\n/+\nstatic if (is(typeof(VirtualAlloc)))\n    version = GC_Use_Alloc_Win32;\nelse static if (is(typeof(mmap)))\n    version = GC_Use_Alloc_MMap;\nelse static if (is(typeof(valloc)))\n    version = GC_Use_Alloc_Valloc;\nelse static if (is(typeof(malloc)))\n    version = GC_Use_Alloc_Malloc;\nelse static assert(false, \"No supported allocation methods available.\");\n+/\n\nstatic if (is(typeof(VirtualAlloc))) // version (GC_Use_Alloc_Win32)\n{\n    /**\n     * Map memory.\n     */\n    void *os_mem_map(size_t nbytes) nothrow\n    {\n        return VirtualAlloc(null, nbytes, MEM_RESERVE | MEM_COMMIT,\n                PAGE_READWRITE);\n    }\n\n\n    /**\n     * Unmap memory allocated with os_mem_map().\n     * Returns:\n     *      0       success\n     *      !=0     failure\n     */\n    int os_mem_unmap(void *base, size_t nbytes) nothrow\n    {\n        return cast(int)(VirtualFree(base, 0, MEM_RELEASE) == 0);\n    }\n}\nelse static if (is(typeof(mmap)))  // else version (GC_Use_Alloc_MMap)\n{\n    void *os_mem_map(size_t nbytes) nothrow\n    {   void *p;\n\n        p = mmap(null, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);\n        return (p == MAP_FAILED) ? null : p;\n    }\n\n\n    int os_mem_unmap(void *base, size_t nbytes) nothrow\n    {\n        return munmap(base, nbytes);\n    }\n}\nelse static if (is(typeof(valloc))) // else version (GC_Use_Alloc_Valloc)\n{\n    void *os_mem_map(size_t nbytes) nothrow\n    {\n        return valloc(nbytes);\n    }\n\n\n    int os_mem_unmap(void *base, size_t nbytes) nothrow\n    {\n        free(base);\n        return 0;\n    }\n}\nelse static if (is(typeof(malloc))) // else version (GC_Use_Alloc_Malloc)\n{\n    // NOTE: This assumes malloc granularity is at least (void*).sizeof.  If\n    //       (req_size + PAGESIZE) is allocated, and the pointer is rounded up\n    //       to PAGESIZE alignment, there will be space for a void* at the end\n    //       after PAGESIZE bytes used by the GC.\n\n\n    import gc.gc;\n\n\n    const size_t PAGE_MASK = PAGESIZE - 1;\n\n\n    void *os_mem_map(size_t nbytes) nothrow\n    {   byte *p, q;\n        p = cast(byte *) malloc(nbytes + PAGESIZE);\n        q = p + ((PAGESIZE - ((cast(size_t) p & PAGE_MASK))) & PAGE_MASK);\n        * cast(void**)(q + nbytes) = p;\n        return q;\n    }\n\n\n    int os_mem_unmap(void *base, size_t nbytes) nothrow\n    {\n        free( *cast(void**)( cast(byte*) base + nbytes ) );\n        return 0;\n    }\n}\nelse\n{\n    static assert(false, \"No supported allocation methods available.\");\n}\n\n/**\n   Check for any kind of memory pressure.\n\n   Params:\n      mapped = the amount of memory mapped by the GC in bytes\n   Returns:\n       true if memory is scarce\n*/\n// TOOD: get virtual mem sizes and current usage from OS\n// TODO: compare current RSS and avail. physical memory\nversion (Windows)\n{\n    bool isLowOnMem(size_t mapped) nothrow @nogc\n    {\n        version (D_LP64)\n            return false;\n        else\n        {\n            import core.sys.windows.windows;\n            MEMORYSTATUS stat;\n            GlobalMemoryStatus(&stat);\n            // Less than 5 % of virtual address space available\n            return stat.dwAvailVirtual < stat.dwTotalVirtual / 20;\n        }\n    }\n}\nelse version (Darwin)\n{\n    bool isLowOnMem(size_t mapped) nothrow @nogc\n    {\n        enum GB = 2 ^^ 30;\n        version (D_LP64)\n            return false;\n        else\n        {\n            // 80 % of available 4GB is used for GC (excluding malloc and mmap)\n            enum size_t limit = 4UL * GB * 8 / 10;\n            return mapped > limit;\n        }\n    }\n}\nelse\n{\n    bool isLowOnMem(size_t mapped) nothrow @nogc\n    {\n        enum GB = 2 ^^ 30;\n        version (D_LP64)\n            return false;\n        else\n        {\n            // be conservative and assume 3GB\n            enum size_t limit = 3UL * GB * 8 / 10;\n            return mapped > limit;\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gc/pooltable.d",
    "content": "/**\n * A sorted array to quickly lookup pools.\n *\n * Copyright: Copyright Digital Mars 2001 -.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, David Friedman, Sean Kelly, Martin Nowak\n */\nmodule gc.pooltable;\n\nstatic import cstdlib=core.stdc.stdlib;\n\nstruct PoolTable(Pool)\n{\n    import core.stdc.string : memmove;\n\nnothrow:\n    void Dtor()\n    {\n        cstdlib.free(pools);\n        pools = null;\n        npools = 0;\n    }\n\n    bool insert(Pool* pool)\n    {\n        auto newpools = cast(Pool **)cstdlib.realloc(pools, (npools + 1) * pools[0].sizeof);\n        if (!newpools)\n            return false;\n\n        pools = newpools;\n\n        // Sort pool into newpooltable[]\n        size_t i;\n        for (; i < npools; ++i)\n        {\n            if (pool.baseAddr < pools[i].baseAddr)\n                break;\n        }\n        if (i != npools)\n            memmove(pools + i + 1, pools + i, (npools - i) * pools[0].sizeof);\n        pools[i] = pool;\n\n        ++npools;\n\n        _minAddr = pools[0].baseAddr;\n        _maxAddr = pools[npools - 1].topAddr;\n\n        return true;\n    }\n\n    @property size_t length() pure const\n    {\n        return npools;\n    }\n\n    ref inout(Pool*) opIndex(size_t idx) inout pure\n    in { assert(idx < length); }\n    do\n    {\n        return pools[idx];\n    }\n\n    inout(Pool*)[] opSlice(size_t a, size_t b) inout pure\n    in { assert(a <= length && b <= length); }\n    do\n    {\n        return pools[a .. b];\n    }\n\n    alias opDollar = length;\n\n    /**\n     * Find Pool that pointer is in.\n     * Return null if not in a Pool.\n     * Assume pooltable[] is sorted.\n     */\n    Pool *findPool(void *p) nothrow\n    {\n        if (p >= minAddr && p < maxAddr)\n        {\n            assert(npools);\n\n            // let dmd allocate a register for this.pools\n            auto pools = this.pools;\n\n            if (npools == 1)\n                return pools[0];\n\n            /* The pooltable[] is sorted by address, so do a binary search\n             */\n            size_t low = 0;\n            size_t high = npools - 1;\n            while (low <= high)\n            {\n                size_t mid = (low + high) >> 1;\n                auto pool = pools[mid];\n                if (p < pool.baseAddr)\n                    high = mid - 1;\n                else if (p >= pool.topAddr)\n                    low = mid + 1;\n                else\n                    return pool;\n            }\n        }\n        return null;\n    }\n\n    // semi-stable partition, returns right half for which pred is false\n    Pool*[] minimize() pure\n    {\n        static void swap(ref Pool* a, ref Pool* b)\n        {\n            auto c = a; a = b; b = c;\n        }\n\n        size_t i;\n        // find first bad entry\n        for (; i < npools; ++i)\n            if (pools[i].isFree) break;\n\n        // move good in front of bad entries\n        size_t j = i + 1;\n        for (; j < npools; ++j)\n        {\n            if (!pools[j].isFree) // keep\n                swap(pools[i++], pools[j]);\n        }\n        // npooltable[0 .. i]      => used pools\n        // npooltable[i .. npools] => free pools\n\n        if (i)\n        {\n            _minAddr = pools[0].baseAddr;\n            _maxAddr = pools[i - 1].topAddr;\n        }\n        else\n        {\n            _minAddr = _maxAddr = null;\n        }\n\n        immutable len = npools;\n        npools = i;\n        // return freed pools to the caller\n        return pools[npools .. len];\n    }\n\n    void Invariant() const\n    {\n        if (!npools) return;\n\n        foreach (i, pool; pools[0 .. npools - 1])\n            assert(pool.baseAddr < pools[i + 1].baseAddr);\n\n        assert(_minAddr == pools[0].baseAddr);\n        assert(_maxAddr == pools[npools - 1].topAddr);\n    }\n\n    @property const(void)* minAddr() pure const { return _minAddr; }\n    @property const(void)* maxAddr() pure const { return _maxAddr; }\n\npackage:\n    Pool** pools;\n    size_t npools;\n    void* _minAddr, _maxAddr;\n}\n\nunittest\n{\n    enum NPOOLS = 6;\n    enum NPAGES = 10;\n    enum PAGESIZE = 4096;\n\n    static struct MockPool\n    {\n        byte* baseAddr, topAddr;\n        size_t freepages, npages;\n        @property bool isFree() const pure nothrow { return freepages == npages; }\n    }\n    PoolTable!MockPool pooltable;\n\n    void reset()\n    {\n        foreach (ref pool; pooltable[0 .. $])\n            pool.freepages = pool.npages;\n        pooltable.minimize();\n        assert(pooltable.length == 0);\n\n        foreach (i; 0 .. NPOOLS)\n        {\n            auto pool = cast(MockPool*)cstdlib.malloc(MockPool.sizeof);\n            *pool = MockPool.init;\n            assert(pooltable.insert(pool));\n        }\n    }\n\n    void usePools()\n    {\n        foreach (pool; pooltable[0 .. $])\n        {\n            pool.npages = NPAGES;\n            pool.freepages = NPAGES / 2;\n        }\n    }\n\n    // all pools are free\n    reset();\n    assert(pooltable.length == NPOOLS);\n    auto freed = pooltable.minimize();\n    assert(freed.length == NPOOLS);\n    assert(pooltable.length == 0);\n\n    // all pools used\n    reset();\n    usePools();\n    assert(pooltable.length == NPOOLS);\n    freed = pooltable.minimize();\n    assert(freed.length == 0);\n    assert(pooltable.length == NPOOLS);\n\n    // preserves order of used pools\n    reset();\n    usePools();\n\n    {\n        MockPool*[NPOOLS] opools = pooltable[0 .. NPOOLS];\n        // make the 2nd pool free\n        pooltable[2].freepages = NPAGES;\n\n        pooltable.minimize();\n        assert(pooltable.length == NPOOLS - 1);\n        assert(pooltable[0] == opools[0]);\n        assert(pooltable[1] == opools[1]);\n        assert(pooltable[2] == opools[3]);\n    }\n\n    // test that PoolTable reduces min/max address span\n    reset();\n    usePools();\n\n    byte* base, top;\n\n    {\n        // fill with fake addresses\n        size_t i;\n        foreach (pool; pooltable[0 .. NPOOLS])\n        {\n            pool.baseAddr = cast(byte*)(i++ * NPAGES * PAGESIZE);\n            pool.topAddr = pool.baseAddr + NPAGES * PAGESIZE;\n        }\n        base = pooltable[0].baseAddr;\n        top = pooltable[NPOOLS - 1].topAddr;\n    }\n\n    freed = pooltable.minimize();\n    assert(freed.length == 0);\n    assert(pooltable.length == NPOOLS);\n    assert(pooltable.minAddr == base);\n    assert(pooltable.maxAddr == top);\n\n    pooltable[NPOOLS - 1].freepages = NPAGES;\n    pooltable[NPOOLS - 2].freepages = NPAGES;\n\n    freed = pooltable.minimize();\n    assert(freed.length == 2);\n    assert(pooltable.length == NPOOLS - 2);\n    assert(pooltable.minAddr == base);\n    assert(pooltable.maxAddr == pooltable[NPOOLS - 3].topAddr);\n\n    pooltable[0].freepages = NPAGES;\n\n    freed = pooltable.minimize();\n    assert(freed.length == 1);\n    assert(pooltable.length == NPOOLS - 3);\n    assert(pooltable.minAddr != base);\n    assert(pooltable.minAddr == pooltable[0].baseAddr);\n    assert(pooltable.maxAddr == pooltable[NPOOLS - 4].topAddr);\n\n    // free all\n    foreach (pool; pooltable[0 .. $])\n        pool.freepages = NPAGES;\n    freed = pooltable.minimize();\n    assert(freed.length == NPOOLS - 3);\n    assert(pooltable.length == 0);\n    pooltable.Dtor();\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gc/proxy.d",
    "content": "/**\n * Contains the external GC interface.\n *\n * Copyright: Copyright Digital Mars 2005 - 2016.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, Sean Kelly\n */\n\n/*          Copyright Digital Mars 2005 - 2016.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule gc.proxy;\n\nimport gc.impl.conservative.gc;\nimport gc.impl.manual.gc;\nimport gc.impl.proto.gc;\nimport gc.config;\nimport gc.gcinterface;\n\nstatic import core.memory;\n\nprivate\n{\n    static import core.memory;\n    alias BlkInfo = core.memory.GC.BlkInfo;\n\n    import core.internal.spinlock;\n    static SpinLock instanceLock;\n\n    __gshared bool isInstanceInit = false;\n    __gshared GC instance = new ProtoGC();\n    __gshared GC proxiedGC; // used to iterate roots of Windows DLLs\n}\n\nextern (C)\n{\n    void gc_init()\n    {\n        instanceLock.lock();\n        if (!isInstanceInit)\n        {\n            auto protoInstance = instance;\n            config.initialize();\n            ManualGC.initialize(instance);\n            ConservativeGC.initialize(instance);\n\n            if (instance is protoInstance)\n            {\n                import core.stdc.stdio : fprintf, stderr;\n                import core.stdc.stdlib : exit;\n\n                fprintf(stderr, \"No GC was initialized, please recheck the name of the selected GC ('%.*s').\\n\", cast(int)config.gc.length, config.gc.ptr);\n                instanceLock.unlock();\n                exit(1);\n\n                // Shouldn't get here.\n                assert(0);\n            }\n\n            // Transfer all ranges and roots to the real GC.\n            (cast(ProtoGC) protoInstance).term();\n            isInstanceInit = true;\n        }\n        instanceLock.unlock();\n    }\n\n    void gc_init_nothrow() nothrow\n    {\n        scope(failure)\n        {\n            import core.internal.abort;\n            abort(\"Cannot initialize the garbage collector.\\n\");\n            assert(0);\n        }\n        gc_init();\n    }\n\n    void gc_term()\n    {\n        // NOTE: There may be daemons threads still running when this routine is\n        //       called.  If so, cleaning memory out from under then is a good\n        //       way to make them crash horribly.  This probably doesn't matter\n        //       much since the app is supposed to be shutting down anyway, but\n        //       I'm disabling cleanup for now until I can think about it some\n        //       more.\n        //\n        // NOTE: Due to popular demand, this has been re-enabled.  It still has\n        //       the problems mentioned above though, so I guess we'll see.\n\n        if (isInstanceInit)\n        {\n            instance.collectNoStack();  // not really a 'collect all' -- still scans\n                                        // static data area, roots, and ranges.\n\n            ManualGC.finalize(instance);\n            ConservativeGC.finalize(instance);\n        }\n    }\n\n    void gc_enable()\n    {\n        instance.enable();\n    }\n\n    void gc_disable()\n    {\n        instance.disable();\n    }\n\n    void gc_collect() nothrow\n    {\n        instance.collect();\n    }\n\n    void gc_minimize() nothrow\n    {\n        instance.minimize();\n    }\n\n    uint gc_getAttr( void* p ) nothrow\n    {\n        return instance.getAttr(p);\n    }\n\n    uint gc_setAttr( void* p, uint a ) nothrow\n    {\n        return instance.setAttr(p, a);\n    }\n\n    uint gc_clrAttr( void* p, uint a ) nothrow\n    {\n        return instance.clrAttr(p, a);\n    }\n\n    void* gc_malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow\n    {\n        return instance.malloc(sz, ba, ti);\n    }\n\n    BlkInfo gc_qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow\n    {\n        return instance.qalloc( sz, ba, ti );\n    }\n\n    void* gc_calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow\n    {\n        return instance.calloc( sz, ba, ti );\n    }\n\n    void* gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow\n    {\n        return instance.realloc( p, sz, ba, ti );\n    }\n\n    size_t gc_extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) nothrow\n    {\n        return instance.extend( p, mx, sz,ti );\n    }\n\n    size_t gc_reserve( size_t sz ) nothrow\n    {\n        return instance.reserve( sz );\n    }\n\n    void gc_free( void* p ) nothrow @nogc\n    {\n        return instance.free( p );\n    }\n\n    void* gc_addrOf( void* p ) nothrow @nogc\n    {\n        return instance.addrOf( p );\n    }\n\n    size_t gc_sizeOf( void* p ) nothrow @nogc\n    {\n        return instance.sizeOf( p );\n    }\n\n    BlkInfo gc_query( void* p ) nothrow\n    {\n        return instance.query( p );\n    }\n\n    core.memory.GC.Stats gc_stats() nothrow\n    {\n        return instance.stats();\n    }\n\n    void gc_addRoot( void* p ) nothrow @nogc\n    {\n        return instance.addRoot( p );\n    }\n\n    void gc_addRange( void* p, size_t sz, const TypeInfo ti = null ) nothrow @nogc\n    {\n        return instance.addRange( p, sz, ti );\n    }\n\n    void gc_removeRoot( void* p ) nothrow\n    {\n        return instance.removeRoot( p );\n    }\n\n    void gc_removeRange( void* p ) nothrow\n    {\n        return instance.removeRange( p );\n    }\n\n    void gc_runFinalizers( in void[] segment ) nothrow\n    {\n        return instance.runFinalizers( segment );\n    }\n\n    bool gc_inFinalizer() nothrow\n    {\n        return instance.inFinalizer();\n    }\n\n    GC gc_getProxy() nothrow\n    {\n        return instance;\n    }\n\n    export\n    {\n        void gc_setProxy( GC proxy )\n        {\n            foreach (root; instance.rootIter)\n            {\n                proxy.addRoot(root);\n            }\n\n            foreach (range; instance.rangeIter)\n            {\n                proxy.addRange(range.pbot, range.ptop - range.pbot, range.ti);\n            }\n\n            proxiedGC = instance; // remember initial GC to later remove roots\n            instance = proxy;\n        }\n\n        void gc_clrProxy()\n        {\n            foreach (root; proxiedGC.rootIter)\n            {\n                instance.removeRoot(root);\n            }\n\n            foreach (range; proxiedGC.rangeIter)\n            {\n                instance.removeRange(range);\n            }\n\n            instance = proxiedGC;\n            proxiedGC = null;\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/attribute.d",
    "content": "// GNU D Compiler attribute support declarations.\n// Copyright (C) 2013-2018 Free Software Foundation, Inc.\n\n// GCC is free software; you can redistribute it and/or modify it under\n// the terms of the GNU General Public License as published by the Free\n// Software Foundation; either version 3, or (at your option) any later\n// version.\n\n// GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n// WARRANTY; without even the implied warranty of MERCHANTABILITY or\n// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n// for more details.\n\n// Under Section 7 of GPL version 3, you are granted additional\n// permissions described in the GCC Runtime Library Exception, version\n// 3.1, as published by the Free Software Foundation.\n\n// You should have received a copy of the GNU General Public License and\n// a copy of the GCC Runtime Library Exception along with this program;\n// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n// <http://www.gnu.org/licenses/>.\n\nmodule gcc.attribute;\n\nprivate struct Attribute(A...)\n{\n    A args;\n}\n\nauto attribute(A...)(A args) if (A.length > 0 && is(A[0] == string))\n{\n    return Attribute!A(args);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/backtrace.d",
    "content": "// GNU D Compiler routines for stack backtrace support.\n// Copyright (C) 2013-2018 Free Software Foundation, Inc.\n\n// GCC is free software; you can redistribute it and/or modify it under\n// the terms of the GNU General Public License as published by the Free\n// Software Foundation; either version 3, or (at your option) any later\n// version.\n\n// GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n// WARRANTY; without even the implied warranty of MERCHANTABILITY or\n// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n// for more details.\n\n// Under Section 7 of GPL version 3, you are granted additional\n// permissions described in the GCC Runtime Library Exception, version\n// 3.1, as published by the Free Software Foundation.\n\n// You should have received a copy of the GNU General Public License and\n// a copy of the GCC Runtime Library Exception along with this program;\n// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n// <http://www.gnu.org/licenses/>.\n\nmodule gcc.backtrace;\n\nimport gcc.libbacktrace;\n\nversion (Posix)\n{\n    // NOTE: The first 5 frames with the current implementation are\n    //       inside core.runtime and the object code, so eliminate\n    //       these for readability.  The alternative would be to\n    //       exclude the first N frames that are in a list of\n    //       mangled function names.\n    private enum FIRSTFRAME = 5;\n}\nelse\n{\n    // NOTE: On Windows, the number of frames to exclude is based on\n    //       whether the exception is user or system-generated, so\n    //       it may be necessary to exclude a list of function names\n    //       instead.\n    private enum FIRSTFRAME = 0;\n}\n\n// Max size per line of the traceback.\nprivate enum MAX_BUFSIZE = 1536;\n\nstatic if (BACKTRACE_SUPPORTED && !BACKTRACE_USES_MALLOC)\n{\n    import core.stdc.stdint, core.stdc.string, core.stdc.stdio;\n    private enum MAXFRAMES = 128;\n\n    extern(C) int simpleCallback(void* data, uintptr_t pc)\n    {\n        auto context = cast(LibBacktrace)data;\n\n        if (context.numPCs == MAXFRAMES)\n            return 1;\n\n        context.pcs[context.numPCs++] = pc;\n        return 0;\n    }\n\n    /*\n     * Used for backtrace_create_state and backtrace_simple\n     */\n    extern(C) void simpleErrorCallback(void* data, const(char)* msg, int errnum)\n    {\n        if (data) // context is not available in backtrace_create_state\n        {\n            auto context = cast(LibBacktrace)data;\n            strncpy(context.errorBuf.ptr, msg, context.errorBuf.length - 1);\n            context.error = errnum;\n        }\n    }\n\n    /*\n     * Used for backtrace_pcinfo\n     */\n    extern(C) int pcinfoCallback(void* data, uintptr_t pc, const(char)* filename,\n                                 int lineno, const(char)* func)\n    {\n        auto context = cast(SymbolCallbackInfo*)data;\n\n        // Try to get the function name via backtrace_syminfo\n        if (func is null)\n        {\n            SymbolCallbackInfo2 info;\n            info.base = context;\n            info.filename = filename;\n            info.lineno = lineno;\n            if (backtrace_syminfo(context.state, pc, &syminfoCallback2, null, &info) != 0)\n            {\n                return context.retval;\n            }\n        }\n\n        auto sym = SymbolOrError(0, SymbolInfo(func, filename, lineno, cast(void*)pc));\n        context.retval = context.applyCB(context.num, sym);\n        context.num++;\n\n        return context.retval;\n    }\n\n    /*\n     * Used for backtrace_pcinfo and backtrace_syminfo\n     */\n    extern(C) void pcinfoErrorCallback(void* data, const(char)* msg, int errnum)\n    {\n        auto context = cast(SymbolCallbackInfo*)data;\n\n        if (errnum == -1)\n        {\n            context.noInfo = true;\n            return;\n        }\n\n        SymbolOrError symError;\n        symError.errnum = errnum;\n        symError.msg = msg;\n\n        size_t i = 0;\n        context.retval = context.applyCB(i, symError);\n    }\n\n    /*\n     * Used for backtrace_syminfo (in opApply)\n     */\n    extern(C) void syminfoCallback(void* data, uintptr_t pc,\n                                   const(char)* symname, uintptr_t symval)\n    {\n        auto context = cast(SymbolCallbackInfo*)data;\n\n        auto sym = SymbolOrError(0, SymbolInfo(symname, null, 0, cast(void*)pc));\n        context.retval = context.applyCB(context.num, sym);\n\n        context.num++;\n    }\n\n    /*\n     * This callback is used if backtrace_syminfo is called from the pcinfoCallback\n     * callback. It merges it's information with the information from pcinfoCallback.\n     */\n    extern(C) void syminfoCallback2(void* data, uintptr_t pc,\n                                    const(char)* symname, uintptr_t symval)\n    {\n        auto context = cast(SymbolCallbackInfo2*)data;\n\n        auto sym = SymbolOrError(0, SymbolInfo(symname, context.filename, context.lineno,\n            cast(void*)pc));\n        context.base.retval = context.base.applyCB(context.base.num, sym);\n\n        context.base.num++;\n    }\n\n    /*\n     * The callback type used with the opApply overload which returns a SymbolOrError\n     */\n    private alias int delegate(ref size_t, ref SymbolOrError) ApplyCallback;\n\n    /*\n     * Passed to syminfoCallback, pcinfoCallback and pcinfoErrorCallback\n     */\n    struct SymbolCallbackInfo\n    {\n        bool noInfo = false;       // True if debug info / symbol table is not available\n        size_t num = 0;            // Counter for opApply\n        int retval;                // Value returned by applyCB\n        backtrace_state* state;\n\n        // info.fileName / funcName / errmsg may become invalid after this delegate returned\n        ApplyCallback applyCB;\n\n        void reset()\n        {\n            noInfo = false;\n            num = 0;\n        }\n    }\n\n    /*\n     * Passed to the syminfoCallback2 callback. That function merges it's\n     * funcName with this information and updates base as all other callbacks do.\n     */\n    struct SymbolCallbackInfo2\n    {\n        SymbolCallbackInfo* base;\n        const(char)* filename;\n        int lineno;\n    }\n\n    /*\n     * Contains a valid symbol or an error message if errnum is != 0.\n     */\n    struct SymbolOrError\n    {\n        int errnum; // == 0: No error\n        union\n        {\n            SymbolInfo symbol;\n            const(char)* msg;\n        }\n    }\n\n    // FIXME: state is never freed as libbacktrace doesn't provide a free function...\n    public class LibBacktrace : Throwable.TraceInfo\n    {\n        enum MaxAlignment = (void*).alignof;\n\n        static void initLibBacktrace()\n        {\n            if (!initialized)\n            {\n                state = backtrace_create_state(null, false, &simpleErrorCallback, null);\n                initialized = true;\n            }\n        }\n\n        this(int firstFrame = FIRSTFRAME)\n        {\n            _firstFrame = firstFrame;\n\n            initLibBacktrace();\n\n            if (state)\n            {\n                backtrace_simple(state, _firstFrame, &simpleCallback,\n                                 &simpleErrorCallback, cast(void*)this);\n            }\n        }\n\n        override int opApply(scope int delegate(ref const(char[])) dg) const\n        {\n            return opApply(\n                (ref size_t, ref const(char[]) buf)\n                {\n                    return dg(buf);\n                }\n            );\n        }\n\n        override int opApply(scope int delegate(ref size_t, ref const(char[])) dg) const\n        {\n            return opApply(\n                (ref size_t i, ref SymbolOrError sym)\n                {\n                    char[MAX_BUFSIZE] buffer = void;\n                    char[] msg;\n                    if (sym.errnum != 0)\n                    {\n                        auto retval = snprintf(buffer.ptr, buffer.length,\n                                               \"libbacktrace error: '%s' errno: %d\", sym.msg, sym.errnum);\n                        if (retval >= buffer.length)\n                            retval = buffer.length - 1; // Ignore zero terminator\n                        if (retval > 0)\n                            msg = buffer[0 .. retval];\n                        return dg(i, msg);\n                    }\n                    else\n                    {\n                        msg = formatLine(sym.symbol, buffer);\n                        int ret = dg(i, msg);\n\n                        if (!ret && sym.symbol.funcName && strcmp(sym.symbol.funcName, \"_Dmain\") == 0)\n                            return 1;\n                        return ret;\n                    }\n                }\n            );\n        }\n\n        int opApply(scope ApplyCallback dg) const\n        {\n            initLibBacktrace();\n\n            // If backtrace_simple produced an error report it and exit\n            if (!state || error != 0)\n            {\n                size_t pos = 0;\n                SymbolOrError symError;\n                if (!state)\n                {\n                    symError.msg = \"libbacktrace failed to initialize\\0\";\n                    symError.errnum = 1;\n                }\n                else\n                {\n                    symError.errnum = error;\n                    symError.msg = errorBuf.ptr;\n                }\n\n                return dg(pos, symError);\n            }\n\n            SymbolCallbackInfo cinfo;\n            cinfo.applyCB = dg;\n            cinfo.state = cast(backtrace_state*)state;\n\n            // Try using debug info first\n            foreach (i, pc; pcs[0 .. numPCs])\n            {\n                // FIXME: We may violate const guarantees here...\n                if (backtrace_pcinfo(cast(backtrace_state*)state, pc, &pcinfoCallback,\n                    &pcinfoErrorCallback, &cinfo) != 0)\n                {\n                    break; // User delegate requested abort or no debug info at all\n                }\n            }\n\n            // If no error or other error which has already been reported via callback\n            if (!cinfo.noInfo)\n                return cinfo.retval;\n\n            // Try using symbol table\n            cinfo.reset();\n            foreach (pc; pcs[0 .. numPCs])\n            {\n                if (backtrace_syminfo(cast(backtrace_state*)state, pc, &syminfoCallback,\n                    &pcinfoErrorCallback, &cinfo) == 0)\n                {\n                    break;\n                }\n            }\n\n            if (!cinfo.noInfo)\n                return cinfo.retval;\n\n            // No symbol table\n            foreach (i, pc; pcs[0 .. numPCs])\n            {\n                auto sym = SymbolOrError(0, SymbolInfo(null, null, 0, cast(void*)pc));\n                if (auto ret = dg(i, sym) != 0)\n                    return ret;\n            }\n\n            return 0;\n        }\n\n        override string toString() const\n        {\n            string buf;\n            foreach (i, const(char[]) line; this)\n                buf ~= i ? \"\\n\" ~ line : line;\n            return buf;\n        }\n\n    private:\n        static backtrace_state* state = null;\n        static bool initialized       = false;\n        size_t                 numPCs = 0;\n        uintptr_t[MAXFRAMES] pcs;\n\n        int       error = 0;\n        int _firstFrame = 0;\n        char[128] errorBuf = \"\\0\";\n    }\n}\nelse\n{\n    /*\n     * Our fallback backtrace implementation using libgcc's unwind\n     * and backtrace support. In theory libbacktrace should be available\n     * everywhere where this code works. We keep it anyway till libbacktrace\n     * is well-tested.\n     */\n    public class UnwindBacktrace : Throwable.TraceInfo\n    {\n        this(int firstFrame = FIRSTFRAME)\n        {\n            _firstFrame = firstFrame;\n            _callstack = getBacktrace();\n            _framelist = getBacktraceSymbols(_callstack);\n        }\n\n        override int opApply(scope int delegate(ref const(char[])) dg) const\n        {\n            return opApply(\n                (ref size_t, ref const(char[]) buf)\n                {\n                    return dg(buf);\n                }\n            );\n        }\n\n        override int opApply(scope int delegate(ref size_t, ref const(char[])) dg) const\n        {\n            char[MAX_BUFSIZE] buffer = void;\n            int ret = 0;\n\n            for (int i = _firstFrame; i < _framelist.entries; ++i)\n            {\n                auto pos = cast(size_t)(i - _firstFrame);\n                auto msg = formatLine(_framelist.symbols[i], buffer);\n                ret = dg(pos, msg);\n                if (ret)\n                    break;\n            }\n            return ret;\n        }\n\n        override string toString() const\n        {\n            string buf;\n            foreach (i, line; this)\n                buf ~= i ? \"\\n\" ~ line : line;\n            return buf;\n        }\n\n    private:\n        BTSymbolData     _framelist;\n        UnwindBacktraceData _callstack;\n        int              _firstFrame = 0;\n    }\n\n    // Implementation details\nprivate:\n    import gcc.unwind;\n\n    version (linux)\n        import core.sys.linux.dlfcn;\n    else version (OSX)\n        import core.sys.darwin.dlfcn;\n    else version (FreeBSD)\n        import core.sys.freebsd.dlfcn;\n    else version (NetBSD)\n        import core.sys.netbsd.dlfcn;\n    else version (Solaris)\n        import core.sys.netbsd.dlfcn;\n    else version (Posix)\n        import core.sys.posix.dlfcn;\n\n    private enum MAXFRAMES = 128;\n\n    struct UnwindBacktraceData\n    {\n        void*[MAXFRAMES] callstack;\n        int numframes = 0;\n    }\n\n    struct BTSymbolData\n    {\n        size_t entries;\n        SymbolInfo[MAXFRAMES] symbols;\n    }\n\n    static extern (C) _Unwind_Reason_Code unwindCB(_Unwind_Context *ctx, void *d)\n    {\n        UnwindBacktraceData* bt = cast(UnwindBacktraceData*)d;\n        if (bt.numframes >= MAXFRAMES)\n            return _URC_NO_REASON;\n\n        bt.callstack[bt.numframes] = cast(void*)_Unwind_GetIP(ctx);\n        bt.numframes++;\n        return _URC_NO_REASON;\n    }\n\n    UnwindBacktraceData getBacktrace()\n    {\n        UnwindBacktraceData stackframe;\n        _Unwind_Backtrace(&unwindCB, &stackframe);\n        return stackframe;\n    }\n\n    BTSymbolData getBacktraceSymbols(UnwindBacktraceData data)\n    {\n        BTSymbolData symData;\n\n        for (auto i = 0; i < data.numframes; i++)\n        {\n            static if ( __traits(compiles, Dl_info))\n            {\n                Dl_info funcInfo;\n\n                if (data.callstack[i] !is null && dladdr(data.callstack[i], &funcInfo) != 0)\n                {\n                    symData.symbols[symData.entries].funcName = funcInfo.dli_sname;\n\n                    symData.symbols[symData.entries].address = data.callstack[i];\n                    symData.entries++;\n                }\n                else\n                {\n                    symData.symbols[symData.entries].address = data.callstack[i];\n                    symData.entries++;\n                }\n            }\n            else\n            {\n                symData.symbols[symData.entries].address = data.callstack[i];\n                symData.entries++;\n            }\n        }\n\n        return symData;\n    }\n}\n\n/*\n * Struct representing a symbol (function) in the backtrace\n */\nstruct SymbolInfo\n{\n    const(char)* funcName, fileName;\n    size_t line;\n    const(void)* address;\n}\n\n/*\n * Format one output line for symbol sym.\n * Returns a slice of buffer.\n */\nchar[] formatLine(const SymbolInfo sym, return ref char[MAX_BUFSIZE] buffer)\n{\n    import core.demangle, core.stdc.config;\n    import core.stdc.stdio : snprintf, printf;\n    import core.stdc.string : strlen;\n\n    size_t bufferLength = 0;\n\n    void appendToBuffer(Args...)(const(char)* format, Args args)\n    {\n        const count = snprintf(buffer.ptr + bufferLength,\n                               buffer.length - bufferLength,\n                               format, args);\n        assert(count >= 0);\n        bufferLength += count;\n        if (bufferLength >= buffer.length)\n            bufferLength = buffer.length - 1;\n    }\n\n\n    if (sym.fileName is null)\n        appendToBuffer(\"??:? \");\n    else\n        appendToBuffer(\"%s:%d \", sym.fileName, sym.line);\n\n    if (sym.funcName is null)\n        appendToBuffer(\"???\");\n    else\n    {\n        char[1024] symbol = void;\n        auto demangled = demangle(sym.funcName[0 .. strlen(sym.funcName)], symbol);\n\n        if (demangled.length > 0)\n            appendToBuffer(\"%.*s \", cast(int) demangled.length, demangled.ptr);\n    }\n\n    version (D_LP64)\n        appendToBuffer(\"[0x%llx]\", cast(size_t)sym.address);\n    else\n        appendToBuffer(\"[0x%x]\", cast(size_t)sym.address);\n\n    return buffer[0 .. bufferLength];\n}\n\n\nunittest\n{\n    char[MAX_BUFSIZE] sbuf = '\\0';\n    char[] result;\n    string longString;\n    for (size_t i = 0; i < 60; i++)\n        longString ~= \"abcdefghij\";\n    longString ~= '\\0';\n\n    auto symbol = SymbolInfo(null, null, 0, null);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n\n    symbol = SymbolInfo(longString.ptr, null, 0, null);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n\n    symbol = SymbolInfo(\"func\", \"test.d\", 0, null);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n\n    symbol = SymbolInfo(\"func\", longString.ptr, 0, null);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n\n    symbol = SymbolInfo(longString.ptr, \"test.d\", 0, null);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n\n    symbol = SymbolInfo(longString.ptr, longString.ptr, 0, null);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n\n    symbol = SymbolInfo(\"func\", \"test.d\", 1000, null);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n\n    symbol = SymbolInfo(null, (longString[0..500] ~ '\\0').ptr, 100000000, null);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n\n    symbol = SymbolInfo(\"func\", \"test.d\", 0, cast(void*)0x100000);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n\n    symbol = SymbolInfo(\"func\", null, 0, cast(void*)0x100000);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n\n    symbol = SymbolInfo(null, \"test.d\", 0, cast(void*)0x100000);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n\n    symbol = SymbolInfo(longString.ptr, \"test.d\", 0, cast(void*)0x100000);\n    result = formatLine(symbol, sbuf);\n    assert(result.length < MAX_BUFSIZE && result.ptr[result.length] == '\\0' && sbuf[$-1] == '\\0');\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/builtins.d",
    "content": "/* GNU D Compiler bindings for built-in functions and types.\n   Copyright (C) 2006-2018 Free Software Foundation, Inc.\n\nGCC is free software; you can redistribute it and/or modify it under\nthe terms of the GNU General Public License as published by the Free\nSoftware Foundation; either version 3, or (at your option) any later\nversion.\n\nGCC is distributed in the hope that it will be useful, but WITHOUT ANY\nWARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nfor more details.\n\nUnder Section 7 of GPL version 3, you are granted additional\npermissions described in the GCC Runtime Library Exception, version\n3.1, as published by the Free Software Foundation.\n\nYou should have received a copy of the GNU General Public License and\na copy of the GCC Runtime Library Exception along with this program;\nsee the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n<http://www.gnu.org/licenses/>.  */\n\n/**\n  Declarations are automatically created by the compiler.  All\n  declarations start with \"__builtin_\". Refer to _builtins.def in the\n  GCC source for a list of functions.  Not all of the functions are\n  supported.\n\n  In addition to built-in functions, the following types are defined.\n\n  $(TABLE\n  $(TR $(TD ___builtin_va_list)      $(TD The target's va_list type ))\n  $(TR $(TD ___builtin_clong  )      $(TD The D equivalent of the target's\n                                       C \"long\" type ))\n  $(TR $(TD ___builtin_culong )      $(TD The D equivalent of the target's\n                                       C \"unsigned long\" type ))\n  $(TR $(TD ___builtin_machine_int ) $(TD Signed word-sized integer ))\n  $(TR $(TD ___builtin_machine_uint) $(TD Unsigned word-sized integer ))\n  $(TR $(TD ___builtin_pointer_int ) $(TD Signed pointer-sized integer ))\n  $(TR $(TD ___builtin_pointer_uint) $(TD Unsigned pointer-sized integer ))\n  )\n */\n\nmodule gcc.builtins;\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/config.d.in",
    "content": "// GNU D Compiler configure constants.\n// Copyright (C) 2015-2018 Free Software Foundation, Inc.\n\n// GCC is free software; you can redistribute it and/or modify it under\n// the terms of the GNU General Public License as published by the Free\n// Software Foundation; either version 3, or (at your option) any later\n// version.\n\n// GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n// WARRANTY; without even the implied warranty of MERCHANTABILITY or\n// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n// for more details.\n\n// Under Section 7 of GPL version 3, you are granted additional\n// permissions described in the GCC Runtime Library Exception, version\n// 3.1, as published by the Free Software Foundation.\n\n// You should have received a copy of the GNU General Public License and\n// a copy of the GCC Runtime Library Exception along with this program;\n// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n// <http://www.gnu.org/licenses/>.\n\nmodule gcc.config;\n\n// Does platform define __ARM_EABI_UNWINDER__\nenum GNU_ARM_EABI_Unwinder = @DCFG_ARM_EABI_UNWINDER@;\n\n// Map from thread model to thread interface.\nenum ThreadModel\n{\n    Single,\n    Posix,\n    Win32,\n}\n\nenum ThreadModel GNU_Thread_Model = ThreadModel.@DCFG_THREAD_MODEL@;\n\n// Whether the linker provides __start_minfo and __stop_minfo symbols\nenum Minfo_Bracketing = @DCFG_MINFO_BRACKETING@;\n\n// Whether target has support for builtin atomics.\nenum GNU_Have_Atomics = @DCFG_HAVE_ATOMIC_BUILTINS@;\n\n// Whether target has support for 64-bit builtin atomics.\nenum GNU_Have_64Bit_Atomics = @DCFG_HAVE_64BIT_ATOMICS@;\n\n// Do we have libatomic available\nenum GNU_Have_LibAtomic = @DCFG_HAVE_LIBATOMIC@;\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/deh.d",
    "content": "// GNU D Compiler exception personality routines.\n// Copyright (C) 2011-2018 Free Software Foundation, Inc.\n\n// GCC is free software; you can redistribute it and/or modify it under\n// the terms of the GNU General Public License as published by the Free\n// Software Foundation; either version 3, or (at your option) any later\n// version.\n\n// GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n// WARRANTY; without even the implied warranty of MERCHANTABILITY or\n// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n// for more details.\n\n// Under Section 7 of GPL version 3, you are granted additional\n// permissions described in the GCC Runtime Library Exception, version\n// 3.1, as published by the Free Software Foundation.\n\n// You should have received a copy of the GNU General Public License and\n// a copy of the GCC Runtime Library Exception along with this program;\n// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n// <http://www.gnu.org/licenses/>.\n\n// This code is based on the libstdc++ exception handling routines.\n\nmodule gcc.deh;\n\nimport gcc.unwind;\nimport gcc.unwind.pe;\nimport gcc.builtins;\nimport gcc.config;\n\nextern(C)\n{\n    int _d_isbaseof(ClassInfo, ClassInfo);\n    void _d_createTrace(Object, void*);\n    void _d_print_throwable(Throwable t);\n\n    // Not used in GDC but declaration required by rt/sections.d\n    struct FuncTable\n    {\n    }\n}\n\n/**\n * Declare all known and handled exception classes.\n * D exceptions -- \"GNUCD\\0\\0\\0\".\n * C++ exceptions -- \"GNUCC++\\0\"\n * C++ dependent exceptions -- \"GNUCC++\\x01\"\n */\nstatic if (GNU_ARM_EABI_Unwinder)\n{\n    enum _Unwind_Exception_Class gdcExceptionClass = \"GNUCD\\0\\0\\0\";\n    enum _Unwind_Exception_Class gxxExceptionClass = \"GNUCC++\\0\";\n    enum _Unwind_Exception_Class gxxDependentExceptionClass = \"GNUCC++\\x01\";\n}\nelse\n{\n    enum _Unwind_Exception_Class gdcExceptionClass =\n        (cast(_Unwind_Exception_Class)'G' << 56) |\n        (cast(_Unwind_Exception_Class)'N' << 48) |\n        (cast(_Unwind_Exception_Class)'U' << 40) |\n        (cast(_Unwind_Exception_Class)'C' << 32) |\n        (cast(_Unwind_Exception_Class)'D' << 24);\n\n    enum _Unwind_Exception_Class gxxExceptionClass =\n        (cast(_Unwind_Exception_Class)'G' << 56) |\n        (cast(_Unwind_Exception_Class)'N' << 48) |\n        (cast(_Unwind_Exception_Class)'U' << 40) |\n        (cast(_Unwind_Exception_Class)'C' << 32) |\n        (cast(_Unwind_Exception_Class)'C' << 24) |\n        (cast(_Unwind_Exception_Class)'+' << 16) |\n        (cast(_Unwind_Exception_Class)'+' <<  8) |\n        (cast(_Unwind_Exception_Class)0 <<  0);\n\n    enum _Unwind_Exception_Class gxxDependentExceptionClass =\n        gxxExceptionClass + 1;\n}\n\n/**\n * Checks for GDC exception class.\n */\nbool isGdcExceptionClass(_Unwind_Exception_Class c) @nogc\n{\n    static if (GNU_ARM_EABI_Unwinder)\n    {\n        return c[0] == gdcExceptionClass[0]\n            && c[1] == gdcExceptionClass[1]\n            && c[2] == gdcExceptionClass[2]\n            && c[3] == gdcExceptionClass[3]\n            && c[4] == gdcExceptionClass[4]\n            && c[5] == gdcExceptionClass[5]\n            && c[6] == gdcExceptionClass[6]\n            && c[7] == gdcExceptionClass[7];\n    }\n    else\n    {\n        return c == gdcExceptionClass;\n    }\n}\n\n/**\n * Checks for any C++ exception class.\n */\nbool isGxxExceptionClass(_Unwind_Exception_Class c) @nogc\n{\n    static if (GNU_ARM_EABI_Unwinder)\n    {\n        return c[0] == gxxExceptionClass[0]\n            && c[1] == gxxExceptionClass[1]\n            && c[2] == gxxExceptionClass[2]\n            && c[3] == gxxExceptionClass[3]\n            && c[4] == gxxExceptionClass[4]\n            && c[5] == gxxExceptionClass[5]\n            && c[6] == gxxExceptionClass[6]\n            && (c[7] == gxxExceptionClass[7]\n                || c[7] == gxxDependentExceptionClass[7]);\n    }\n    else\n    {\n        return c == gxxExceptionClass\n            || c == gxxDependentExceptionClass;\n    }\n}\n\n/**\n * Checks for primary or dependent, but not that it is a C++ exception.\n */\nbool isDependentException(_Unwind_Exception_Class c) @nogc\n{\n    static if (GNU_ARM_EABI_Unwinder)\n        return (c[7] == '\\x01');\n    else\n        return (c & 1);\n}\n\n/**\n * A D exception object consists of a header, which is a wrapper\n * around an unwind object header with additional D specific\n * information, prefixed by the exception object itself.\n */\nstruct ExceptionHeader\n{\n    // Because of a lack of __aligned__ style attribute, our object\n    // and the unwind object are the first two fields.\n    static if (Throwable.alignof < _Unwind_Exception.alignof)\n        ubyte[_Unwind_Exception.alignof - Throwable.alignof] pad;\n\n    // The object being thrown.  The compiled code expects this to\n    // be immediately before the generic exception header.\n    Throwable object;\n\n    // The generic exception header.\n    _Unwind_Exception unwindHeader;\n\n    static assert(unwindHeader.offsetof - object.offsetof == object.sizeof);\n\n    // Cache handler details between Phase 1 and Phase 2.\n    static if (GNU_ARM_EABI_Unwinder)\n    {\n        // Nothing here yet.\n    }\n    else\n    {\n        // Which catch was found.\n        int handler;\n\n        // Language Specific Data Area for function enclosing the handler.\n        const(ubyte)* languageSpecificData;\n\n        // Pointer to catch code.\n        _Unwind_Ptr landingPad;\n\n        // Canonical Frame Address (CFA) for the enclosing handler.\n        _Unwind_Word canonicalFrameAddress;\n    }\n\n    // Stack other thrown exceptions in current thread through here.\n    ExceptionHeader* next;\n\n    // Thread local stack of chained exceptions.\n    static ExceptionHeader* stack;\n\n    // Pre-allocate storage for 1 instance per thread.\n    // Use calloc/free for multiple exceptions in flight.\n    static ExceptionHeader ehstorage;\n\n    /**\n     * Allocate and initialize an ExceptionHeader.\n     */\n    static ExceptionHeader* create(Throwable o) @nogc\n    {\n        auto eh = &ehstorage;\n\n        // Check exception object in use.\n        if (eh.object)\n        {\n            eh = cast(ExceptionHeader*) __builtin_calloc(ExceptionHeader.sizeof, 1);\n            // Out of memory while throwing - not much else can be done.\n            if (!eh)\n                terminate(\"out of memory\", __LINE__);\n        }\n        eh.object = o;\n\n        eh.unwindHeader.exception_class = gdcExceptionClass;\n\n        return eh;\n    }\n\n    /**\n     * Free ExceptionHeader that was created by create().\n     */\n    static void free(ExceptionHeader* eh) @nogc\n    {\n        *eh = ExceptionHeader.init;\n        if (eh != &ehstorage)\n            __builtin_free(eh);\n    }\n\n    /**\n     * Push this onto stack of chained exceptions.\n     */\n    void push() @nogc\n    {\n        next = stack;\n        stack = &this;\n    }\n\n    /**\n     * Pop and return top of chained exception stack.\n     */\n    static ExceptionHeader* pop() @nogc\n    {\n        auto eh = stack;\n        stack = eh.next;\n        return eh;\n    }\n\n    /**\n     * Save stage1 handler information in the exception object.\n     */\n    static void save(_Unwind_Exception* unwindHeader,\n                     _Unwind_Word cfa, int handler,\n                     const(ubyte)* lsda, _Unwind_Ptr landingPad) @nogc\n    {\n        static if (GNU_ARM_EABI_Unwinder)\n        {\n            unwindHeader.barrier_cache.sp = cfa;\n            unwindHeader.barrier_cache.bitpattern[1] = cast(_uw)handler;\n            unwindHeader.barrier_cache.bitpattern[2] = cast(_uw)lsda;\n            unwindHeader.barrier_cache.bitpattern[3] = cast(_uw)landingPad;\n        }\n        else\n        {\n            ExceptionHeader* eh = toExceptionHeader(unwindHeader);\n            eh.canonicalFrameAddress = cfa;\n            eh.handler = handler;\n            eh.languageSpecificData = lsda;\n            eh.landingPad = landingPad;\n        }\n    }\n\n    /**\n     * Restore the catch handler data saved during phase1.\n     */\n    static void restore(_Unwind_Exception* unwindHeader, out int handler,\n                        out const(ubyte)* lsda, out _Unwind_Ptr landingPad,\n                        out _Unwind_Word cfa) @nogc\n    {\n        static if (GNU_ARM_EABI_Unwinder)\n        {\n            cfa = unwindHeader.barrier_cache.sp;\n            handler = cast(int)unwindHeader.barrier_cache.bitpattern[1];\n            lsda = cast(ubyte*)unwindHeader.barrier_cache.bitpattern[2];\n            landingPad = cast(_Unwind_Ptr)unwindHeader.barrier_cache.bitpattern[3];\n        }\n        else\n        {\n            ExceptionHeader* eh = toExceptionHeader(unwindHeader);\n            cfa = eh.canonicalFrameAddress;\n            handler = eh.handler;\n            lsda = eh.languageSpecificData;\n            landingPad = cast(_Unwind_Ptr)eh.landingPad;\n        }\n    }\n\n    /**\n     * Look at the chain of inflight exceptions and pick the class type that'll\n     * be looked for in catch clauses.\n     */\n    static ClassInfo getClassInfo(_Unwind_Exception* unwindHeader) @nogc\n    {\n        ExceptionHeader* eh = toExceptionHeader(unwindHeader);\n        // The first thrown Exception at the top of the stack takes precedence\n        // over others that are inflight, unless an Error was thrown, in which\n        // case, we search for error handlers instead.\n        Throwable ehobject = eh.object;\n        for (ExceptionHeader* ehn = eh.next; ehn; ehn = ehn.next)\n        {\n            Error e = cast(Error)ehobject;\n            if (e is null || (cast(Error)ehn.object) !is null)\n                ehobject = ehn.object;\n        }\n        return ehobject.classinfo;\n    }\n\n    /**\n     * Convert from pointer to unwindHeader to pointer to ExceptionHeader\n     * that it is embedded inside of.\n     */\n    static ExceptionHeader* toExceptionHeader(_Unwind_Exception* exc) @nogc\n    {\n        return cast(ExceptionHeader*)(cast(void*)exc - ExceptionHeader.unwindHeader.offsetof);\n    }\n}\n\n/**\n * Map to C++ std::type_info's virtual functions from D,\n * being careful to not require linking with libstdc++.\n * So it is given a different name.\n */\nextern(C++) interface CxxTypeInfo\n{\n    void dtor1();\n    void dtor2();\n    bool __is_pointer_p() const;\n    bool __is_function_p() const;\n    bool __do_catch(const CxxTypeInfo, void**, uint) const;\n    bool __do_upcast(const void*, void**) const;\n}\n\n/**\n * Structure of a C++ exception, represented as a C structure.\n * See unwind-cxx.h for the full definition.\n */\nstruct CxaExceptionHeader\n{\n    union\n    {\n        CxxTypeInfo exceptionType;\n        void* primaryException;\n    }\n    void function(void*) exceptionDestructor;\n    void function() unexpectedHandler;\n    void function() terminateHandler;\n    CxaExceptionHeader* nextException;\n    int handlerCount;\n\n    static if (GNU_ARM_EABI_Unwinder)\n    {\n        CxaExceptionHeader* nextPropagatingException;\n        int propagationCount;\n    }\n    else\n    {\n        int handlerSwitchValue;\n        const(ubyte)* actionRecord;\n        const(ubyte)* languageSpecificData;\n        _Unwind_Ptr catchTemp;\n        void* adjustedPtr;\n    }\n\n    _Unwind_Exception unwindHeader;\n\n    /**\n     * There's no saving between phases, so only cache pointer.\n     * __cxa_begin_catch expects this to be set.\n     */\n    static void save(_Unwind_Exception* unwindHeader, void* thrownPtr) @nogc\n    {\n        static if (GNU_ARM_EABI_Unwinder)\n            unwindHeader.barrier_cache.bitpattern[0] = cast(_uw) thrownPtr;\n        else\n        {\n            auto eh = toExceptionHeader(unwindHeader);\n            eh.adjustedPtr = thrownPtr;\n        }\n    }\n\n    /**\n     * Get pointer to the thrown object if the thrown object type behind the\n     * exception is implicitly convertible to the catch type.\n     */\n    static void* getAdjustedPtr(_Unwind_Exception* exc, CxxTypeInfo catchType)\n    {\n        void* thrownPtr;\n\n        // A dependent C++ exceptions is just a wrapper around the unwind header.\n        // A primary C++ exception has the thrown object located immediately after it.\n        if (isDependentException(exc.exception_class))\n            thrownPtr = toExceptionHeader(exc).primaryException;\n        else\n            thrownPtr = cast(void*)(exc + 1);\n\n        // Pointer types need to adjust the actual pointer, not the pointer that is\n        // the exception object.  This also has the effect of passing pointer types\n        // \"by value\" through the __cxa_begin_catch return value.\n        const throw_type = (cast(CxaExceptionHeader*)thrownPtr - 1).exceptionType;\n\n        if (throw_type.__is_pointer_p())\n            thrownPtr = *cast(void**)thrownPtr;\n\n        // Pointer adjustment may be necessary due to multiple inheritance\n        if (catchType is throw_type\n            || catchType.__do_catch(throw_type, &thrownPtr, 1))\n            return thrownPtr;\n\n        return null;\n    }\n\n    /**\n     * Convert from pointer to unwindHeader to pointer to CxaExceptionHeader\n     * that it is embedded inside of.\n     */\n    static CxaExceptionHeader* toExceptionHeader(_Unwind_Exception* exc) @nogc\n    {\n        return cast(CxaExceptionHeader*)(exc + 1) - 1;\n    }\n}\n\n/**\n * Called if exception handling must be abandoned for any reason.\n */\nprivate void terminate(string msg, uint line) @nogc\n{\n    import core.stdc.stdio;\n    import core.stdc.stdlib;\n\n    static bool terminating;\n    if (terminating)\n    {\n        fputs(\"terminate called recursively\\n\", stderr);\n        abort();\n    }\n    terminating = true;\n\n    fprintf(stderr, \"gcc.deh(%u): %.*s\\n\", line, cast(int)msg.length, msg.ptr);\n\n    abort();\n}\n\n/**\n * Called when fibers switch contexts.\n */\nextern(C) void* _d_eh_swapContext(void* newContext) nothrow @nogc\n{\n    auto old = ExceptionHeader.stack;\n    ExceptionHeader.stack = cast(ExceptionHeader*)newContext;\n    return old;\n}\n\n/**\n * Called before starting a catch.  Returns the exception object.\n */\nextern(C) void* __gdc_begin_catch(_Unwind_Exception* unwindHeader)\n{\n    ExceptionHeader* header = ExceptionHeader.toExceptionHeader(unwindHeader);\n\n    void* objectp = cast(void*)header.object;\n\n    // Something went wrong when stacking up chained headers...\n    if (header != ExceptionHeader.pop())\n        terminate(\"catch error\", __LINE__);\n\n    // Handling for this exception is complete.\n    _Unwind_DeleteException(&header.unwindHeader);\n\n    return objectp;\n}\n\n/**\n * Perform a throw, D style. Throw will unwind through this call,\n * so there better not be any handlers or exception thrown here.\n */\nextern(C) void _d_throw(Throwable object)\n{\n    // If possible, avoid always allocating new memory for exception headers.\n    ExceptionHeader *eh = ExceptionHeader.create(object);\n\n    // Add to thrown exception stack.\n    eh.push();\n\n    // Increment reference count if object is a refcounted Throwable.\n    auto refcount = object.refcount();\n    if (refcount)\n        object.refcount() = refcount + 1;\n\n    // Called by unwinder when exception object needs destruction by other than our code.\n    extern(C) void exception_cleanup(_Unwind_Reason_Code code, _Unwind_Exception* exc)\n    {\n        auto eh = ExceptionHeader.toExceptionHeader(exc);\n\n        // If we haven't been caught by a foreign handler, then this is\n        // some sort of unwind error.  In that case just die immediately.\n        // _Unwind_DeleteException in the HP-UX IA64 libunwind library\n        //  returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT\n        // like the GCC _Unwind_DeleteException function does.\n        if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON)\n            terminate(\"uncaught exception\", __LINE__);\n\n        ExceptionHeader.free(eh);\n    }\n\n    eh.unwindHeader.exception_cleanup = &exception_cleanup;\n\n    // Runtime now expects us to do this first before unwinding.\n    _d_createTrace(eh.object, null);\n\n    // We're happy with setjmp/longjmp exceptions or region-based\n    // exception handlers: entry points are provided here for both.\n    _Unwind_Reason_Code r = void;\n\n    version (GNU_SjLj_Exceptions)\n        r = _Unwind_SjLj_RaiseException(&eh.unwindHeader);\n    else\n        r = _Unwind_RaiseException(&eh.unwindHeader);\n\n    // If code == _URC_END_OF_STACK, then we reached top of stack without finding\n    // a handler for the exception.  Since each thread is run in a try/catch,\n    // this oughtn't happen.  If code is something else, we encountered some sort\n    // of heinous lossage from which we could not recover.  As is the way of such\n    // things, almost certainly we will have crashed before now, rather than\n    // actually being able to diagnose the problem.\n    if (r == _URC_END_OF_STACK)\n    {\n        __gdc_begin_catch(&eh.unwindHeader);\n        _d_print_throwable(object);\n        terminate(\"uncaught exception\", __LINE__);\n    }\n\n    terminate(\"unwind error\", __LINE__);\n}\n\n\n/**\n * Read and extract information from the LSDA (.gcc_except_table section).\n */\n_Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class exceptionClass,\n                             _Unwind_Action actions, _Unwind_Exception* unwindHeader,\n                             _Unwind_Context* context, _Unwind_Word cfa,\n                             out _Unwind_Ptr landingPad, out int handler)\n{\n    // If no LSDA, then there are no handlers or cleanups.\n    if (lsda is null)\n        return CONTINUE_UNWINDING(unwindHeader, context);\n\n    // Parse the LSDA header\n    auto p = lsda;\n\n    auto Start = (context ? _Unwind_GetRegionStart(context) : 0);\n\n    // Find @LPStart, the base to which landing pad offsets are relative.\n    ubyte LPStartEncoding = *p++;\n    _Unwind_Ptr LPStart = 0;\n\n    if (LPStartEncoding != DW_EH_PE_omit)\n        LPStart = read_encoded_value(context, LPStartEncoding, &p);\n    else\n        LPStart = Start;\n\n    // Find @TType, the base of the handler and exception spec type data.\n    ubyte TTypeEncoding = *p++;\n    const(ubyte)* TType = null;\n\n    if (TTypeEncoding != DW_EH_PE_omit)\n    {\n        static if (__traits(compiles, _TTYPE_ENCODING))\n        {\n            // Older ARM EABI toolchains set this value incorrectly, so use a\n            // hardcoded OS-specific format.\n            TTypeEncoding = _TTYPE_ENCODING;\n        }\n        auto TTbase = read_uleb128(&p);\n        TType = p + TTbase;\n    }\n\n    // The encoding and length of the call-site table; the action table\n    // immediately follows.\n    ubyte CSEncoding = *p++;\n    auto CSTableSize = read_uleb128(&p);\n    const(ubyte)* actionTable = p + CSTableSize;\n\n    auto TTypeBase = base_of_encoded_value(TTypeEncoding, context);\n\n    // Get instruction pointer (ip) at start of instruction that threw.\n    version (CRuntime_Glibc)\n    {\n        int ip_before_insn;\n        auto ip = _Unwind_GetIPInfo(context, &ip_before_insn);\n        if (!ip_before_insn)\n            --ip;\n    }\n    else\n    {\n        auto ip = _Unwind_GetIP(context);\n        --ip;\n    }\n\n    bool saw_cleanup = false;\n    bool saw_handler = false;\n    const(ubyte)* actionRecord = null;\n\n    version (GNU_SjLj_Exceptions)\n    {\n        // The given \"IP\" is an index into the call-site table, with two\n        // exceptions -- -1 means no-action, and 0 means terminate.\n        // But since we're using uleb128 values, we've not got random\n        // access to the array.\n        if (cast(int) ip <= 0)\n        {\n            return _URC_CONTINUE_UNWIND;\n        }\n        else\n        {\n            _uleb128_t CSLandingPad, CSAction;\n            do\n            {\n                CSLandingPad = read_uleb128(&p);\n                CSAction = read_uleb128(&p);\n            }\n            while (--ip);\n\n            // Can never have null landing pad for sjlj -- that would have\n            // been indicated by a -1 call site index.\n            landingPad = CSLandingPad + 1;\n            if (CSAction)\n                actionRecord = actionTable + CSAction - 1;\n        }\n    }\n    else\n    {\n        // Search the call-site table for the action associated with this IP.\n        while (p < actionTable)\n        {\n            // Note that all call-site encodings are \"absolute\" displacements.\n            auto CSStart = read_encoded_value(null, CSEncoding, &p);\n            auto CSLen = read_encoded_value(null, CSEncoding, &p);\n            auto CSLandingPad = read_encoded_value(null, CSEncoding, &p);\n            auto CSAction = read_uleb128(&p);\n\n            // The table is sorted, so if we've passed the ip, stop.\n            if (ip < Start + CSStart)\n                p = actionTable;\n            else if (ip < Start + CSStart + CSLen)\n            {\n                if (CSLandingPad)\n                    landingPad = LPStart + CSLandingPad;\n                if (CSAction)\n                    actionRecord = actionTable + CSAction - 1;\n                break;\n            }\n        }\n    }\n\n    if (landingPad == 0)\n    {\n        // IP is present, but has a null landing pad.\n        // No cleanups or handlers to be run.\n    }\n    else if (actionRecord is null)\n    {\n        // If ip is present, has a non-null landing pad, and a null\n        // action table offset, then there are only cleanups present.\n        // Cleanups use a zero switch value, as set above.\n        saw_cleanup = true;\n    }\n    else\n    {\n        // Otherwise we have a catch handler or exception specification.\n        handler = actionTableLookup(actions, unwindHeader, actionRecord,\n                                    exceptionClass, TTypeBase,\n                                    TType, TTypeEncoding,\n                                    saw_handler, saw_cleanup);\n    }\n\n    // IP is not in table.  No associated cleanups.\n    if (!saw_handler && !saw_cleanup)\n        return CONTINUE_UNWINDING(unwindHeader, context);\n\n    if (actions & _UA_SEARCH_PHASE)\n    {\n        if (!saw_handler)\n            return CONTINUE_UNWINDING(unwindHeader, context);\n\n        // For domestic exceptions, we cache data from phase 1 for phase 2.\n        if (isGdcExceptionClass(exceptionClass))\n            ExceptionHeader.save(unwindHeader, cfa, handler, lsda, landingPad);\n\n        return _URC_HANDLER_FOUND;\n    }\n\n    return 0;\n}\n\n/**\n * Look up and return the handler index of the classType in Action Table.\n */\nint actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader,\n                      const(ubyte)* actionRecord, _Unwind_Exception_Class exceptionClass,\n                      _Unwind_Ptr TTypeBase, const(ubyte)* TType,\n                      ubyte TTypeEncoding,\n                      out bool saw_handler, out bool saw_cleanup)\n{\n    ClassInfo thrownType;\n    if (isGdcExceptionClass(exceptionClass))\n    {\n        thrownType = ExceptionHeader.getClassInfo(unwindHeader);\n    }\n\n    while (1)\n    {\n        auto ap = actionRecord;\n        auto ARFilter = read_sleb128(&ap);\n        auto apn = ap;\n        auto ARDisp = read_sleb128(&ap);\n\n        if (ARFilter == 0)\n        {\n            // Zero filter values are cleanups.\n            saw_cleanup = true;\n        }\n        else if (actions & _UA_FORCE_UNWIND)\n        {\n            // During forced unwinding, we only run cleanups.\n        }\n        else if (ARFilter > 0)\n        {\n            // Positive filter values are handlers.\n            auto encodedSize = size_of_encoded_value(TTypeEncoding);\n\n            // ARFilter is the negative index from TType, which is where\n            // the ClassInfo is stored.\n            const(ubyte)* tp = TType - ARFilter * encodedSize;\n\n            auto entry = read_encoded_value_with_base(TTypeEncoding, TTypeBase, &tp);\n            ClassInfo ci = cast(ClassInfo)cast(void*)(entry);\n\n            // D does not have catch-all handlers, and so the following\n            // assumes that we will never handle a null value.\n            assert(ci !is null);\n\n            if (ci.classinfo is __cpp_type_info_ptr.classinfo\n                && isGxxExceptionClass(exceptionClass))\n            {\n                // catchType is the catch clause type_info.\n                auto catchType = cast(CxxTypeInfo)((cast(__cpp_type_info_ptr)cast(void*)ci).ptr);\n                auto thrownPtr = CxaExceptionHeader.getAdjustedPtr(unwindHeader, catchType);\n\n                if (thrownPtr !is null)\n                {\n                    if (actions & _UA_SEARCH_PHASE)\n                        CxaExceptionHeader.save(unwindHeader, thrownPtr);\n                    saw_handler = true;\n                    return cast(int)ARFilter;\n                }\n            }\n            else if (isGdcExceptionClass(exceptionClass)\n                     && _d_isbaseof(thrownType, ci))\n            {\n                saw_handler = true;\n                return cast(int)ARFilter;\n            }\n            else\n            {\n                // ??? What to do about other GNU language exceptions.\n            }\n        }\n        else\n        {\n            // Negative filter values are exception specifications,\n            // which D does not use.\n            break;\n        }\n\n        if (ARDisp == 0)\n            break;\n        actionRecord = apn + ARDisp;\n    }\n\n    return 0;\n}\n\n/**\n * Called when the personality function has found neither a cleanup or handler.\n * To support ARM EABI personality routines, that must also unwind the stack.\n */\n_Unwind_Reason_Code CONTINUE_UNWINDING(_Unwind_Exception* unwindHeader, _Unwind_Context* context)\n{\n    static if (GNU_ARM_EABI_Unwinder)\n    {\n        if (__gnu_unwind_frame(unwindHeader, context) != _URC_OK)\n            return _URC_FAILURE;\n    }\n    return _URC_CONTINUE_UNWIND;\n}\n\n/**\n * Using a different personality function name causes link failures\n * when trying to mix code using different exception handling models.\n */\nversion (GNU_SEH_Exceptions)\n{\n    enum PERSONALITY_FUNCTION = \"__gdc_personality_imp\";\n\n    extern(C) EXCEPTION_DISPOSITION __gdc_personality_seh0(void* ms_exc, void* this_frame,\n                                                           void* ms_orig_context, void* ms_disp)\n    {\n        return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,\n                                     ms_disp, &__gdc_personality_imp);\n    }\n}\nelse version (GNU_SjLj_Exceptions)\n{\n    enum PERSONALITY_FUNCTION = \"__gdc_personality_sj0\";\n\n    private int __builtin_eh_return_data_regno(int x) { return x; }\n}\nelse\n{\n    enum PERSONALITY_FUNCTION = \"__gdc_personality_v0\";\n}\n\n/**\n * The \"personality\" function, specific to each language.\n */\nstatic if (GNU_ARM_EABI_Unwinder)\n{\n    pragma(mangle, PERSONALITY_FUNCTION)\n    extern(C) _Unwind_Reason_Code gdc_personality(_Unwind_State state,\n                                                  _Unwind_Exception* unwindHeader,\n                                                  _Unwind_Context* context)\n    {\n        _Unwind_Action actions;\n\n        switch (state & _US_ACTION_MASK)\n        {\n            case _US_VIRTUAL_UNWIND_FRAME:\n                // If the unwind state pattern is (_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND)\n                // then we don't need to search for any handler as it is not a real exception.\n                // Just unwind the stack.\n                if (state & _US_FORCE_UNWIND)\n                    return CONTINUE_UNWINDING(unwindHeader, context);\n                actions = _UA_SEARCH_PHASE;\n                break;\n\n            case _US_UNWIND_FRAME_STARTING:\n                actions = _UA_CLEANUP_PHASE;\n                if (!(state & _US_FORCE_UNWIND)\n                    && unwindHeader.barrier_cache.sp == _Unwind_GetGR(context, UNWIND_STACK_REG))\n                    actions |= _UA_HANDLER_FRAME;\n                break;\n\n            case _US_UNWIND_FRAME_RESUME:\n                return CONTINUE_UNWINDING(unwindHeader, context);\n\n            default:\n                terminate(\"unwind error\", __LINE__);\n        }\n        actions |= state & _US_FORCE_UNWIND;\n\n        // The dwarf unwinder assumes the context structure holds things like\n        // the function and LSDA pointers.  The ARM implementation caches these\n        // in the exception header (UCB).  To avoid rewriting everything we make\n        // the virtual IP register point at the UCB.\n        _Unwind_SetGR(context, UNWIND_POINTER_REG, cast(_Unwind_Ptr)unwindHeader);\n\n        return __gdc_personality(actions, unwindHeader.exception_class,\n                                 unwindHeader, context);\n    }\n}\nelse\n{\n    pragma(mangle, PERSONALITY_FUNCTION)\n    extern(C) _Unwind_Reason_Code gdc_personality(int iversion,\n                                                  _Unwind_Action actions,\n                                                  _Unwind_Exception_Class exceptionClass,\n                                                  _Unwind_Exception* unwindHeader,\n                                                  _Unwind_Context* context)\n    {\n        // Interface version check.\n        if (iversion != 1)\n            return _URC_FATAL_PHASE1_ERROR;\n\n        return __gdc_personality(actions, exceptionClass, unwindHeader, context);\n    }\n}\n\nprivate _Unwind_Reason_Code __gdc_personality(_Unwind_Action actions,\n                                              _Unwind_Exception_Class exceptionClass,\n                                              _Unwind_Exception* unwindHeader,\n                                              _Unwind_Context* context)\n{\n    const(ubyte)* lsda;\n    _Unwind_Ptr landingPad;\n    _Unwind_Word cfa;\n    int handler;\n\n    // Shortcut for phase 2 found handler for domestic exception.\n    if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME)\n        && isGdcExceptionClass(exceptionClass))\n    {\n        ExceptionHeader.restore(unwindHeader, handler, lsda, landingPad, cfa);\n        // Shouldn't have cached a null landing pad in phase 1.\n        if (landingPad == 0)\n            terminate(\"unwind error\", __LINE__);\n    }\n    else\n    {\n        lsda = cast(ubyte*)_Unwind_GetLanguageSpecificData(context);\n\n        static if (GNU_ARM_EABI_Unwinder)\n            cfa = _Unwind_GetGR(context, UNWIND_STACK_REG);\n        else\n            cfa = _Unwind_GetCFA(context);\n\n        auto result = scanLSDA(lsda, exceptionClass, actions, unwindHeader,\n                               context, cfa, landingPad, handler);\n\n        // Positive on handler found in phase 1, continue unwinding, or failure.\n        if (result)\n            return result;\n    }\n\n    // Unexpected negative handler, call terminate directly.\n    if (handler < 0)\n        terminate(\"unwind error\", __LINE__);\n\n    // We can't use any of the deh routines with foreign exceptions,\n    // because they all expect unwindHeader to be an ExceptionHeader.\n    if (isGdcExceptionClass(exceptionClass))\n    {\n        // If there are any in-flight exceptions being thrown, chain our\n        // current object onto the end of the prevous object.\n        ExceptionHeader* eh = ExceptionHeader.toExceptionHeader(unwindHeader);\n        auto currentLsd = lsda;\n        auto currentCfa = cfa;\n        bool bypassed = false;\n\n        while (eh.next)\n        {\n            ExceptionHeader* ehn = eh.next;\n            const(ubyte)* nextLsd;\n            _Unwind_Ptr nextLandingPad;\n            _Unwind_Word nextCfa;\n            int nextHandler;\n\n            ExceptionHeader.restore(&ehn.unwindHeader, nextHandler, nextLsd, nextLandingPad, nextCfa);\n\n            Error e = cast(Error)eh.object;\n            if (e !is null && !cast(Error)ehn.object)\n            {\n                // We found an Error, bypass the exception chain.\n                currentLsd = nextLsd;\n                currentCfa = nextCfa;\n                eh = ehn;\n                bypassed = true;\n                continue;\n            }\n\n            // Don't combine when the exceptions are from different functions.\n            if (currentLsd != nextLsd && currentCfa != nextCfa)\n                break;\n\n            // Add our object onto the end of the existing chain and replace\n            // our exception object with in-flight one.\n            eh.object = Throwable.chainTogether(ehn.object, eh.object);\n\n            if (nextHandler != handler && !bypassed)\n            {\n                handler = nextHandler;\n                ExceptionHeader.save(unwindHeader, cfa, handler, lsda, landingPad);\n            }\n\n            // Exceptions chained, can now throw away the previous header.\n            eh.next = ehn.next;\n            _Unwind_DeleteException(&ehn.unwindHeader);\n        }\n\n        if (bypassed)\n        {\n            eh = ExceptionHeader.toExceptionHeader(unwindHeader);\n            Error e = cast(Error)eh.object;\n            auto ehn = eh.next;\n            e.bypassedException = ehn.object;\n            eh.next = ehn.next;\n            _Unwind_DeleteException(&ehn.unwindHeader);\n        }\n    }\n\n    // Set up registers and jump to cleanup or handler.\n    // For targets with pointers smaller than the word size, we must extend the\n    // pointer, and this extension is target dependent.\n    _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),\n                  cast(_Unwind_Ptr)unwindHeader);\n    _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), handler);\n    _Unwind_SetIP(context, landingPad);\n\n    return _URC_INSTALL_CONTEXT;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/libbacktrace.d.in",
    "content": "// GNU D Compiler bindings for the stack backtrace functions.\n// Copyright (C) 2013-2018 Free Software Foundation, Inc.\n\n// GCC is free software; you can redistribute it and/or modify it under\n// the terms of the GNU General Public License as published by the Free\n// Software Foundation; either version 3, or (at your option) any later\n// version.\n\n// GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n// WARRANTY; without even the implied warranty of MERCHANTABILITY or\n// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n// for more details.\n\n// Under Section 7 of GPL version 3, you are granted additional\n// permissions described in the GCC Runtime Library Exception, version\n// 3.1, as published by the Free Software Foundation.\n\n// You should have received a copy of the GNU General Public License and\n// a copy of the GCC Runtime Library Exception along with this program;\n// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n// <http://www.gnu.org/licenses/>.\n\nmodule gcc.libbacktrace;\n\n/*\n * Part of backtrace-supported.h: These are platform specific variables.\n * They are obtained via the configure script\n */\n\nenum BACKTRACE_SUPPORTED = @BACKTRACE_SUPPORTED@;\nenum BACKTRACE_USES_MALLOC = @BACKTRACE_USES_MALLOC@;\nenum BACKTRACE_SUPPORTS_THREADS = @BACKTRACE_SUPPORTS_THREADS@;\n\n/*\n * libbacktrace.h\n */\n\nstatic if (BACKTRACE_SUPPORTED)\n{\n    import core.stdc.stddef, core.stdc.stdio, core.stdc.stdint;\n\nextern(C):\n    struct backtrace_state {}\n\n    alias extern(C) void function(void* data, const(char)* msg, int errnum)\n        backtrace_error_callback;\n\n    backtrace_state* backtrace_create_state(const(char)* filename, int threaded,\n                                            backtrace_error_callback error_callback, void* data) nothrow;\n\n    alias extern(C) int function(void* data, uintptr_t pc, const(char)* filename, int lineno, const(char)* func)\n        backtrace_full_callback;\n\n    int backtrace_full(backtrace_state* state, int skip, backtrace_full_callback callback,\n                       backtrace_error_callback error_callback, void* data) nothrow;\n\n    alias extern(C) int function(void* data, uintptr_t pc)\n        backtrace_simple_callback;\n\n    int backtrace_simple(backtrace_state* state, int skip, backtrace_simple_callback callback,\n                         backtrace_error_callback error_callback, void* data) nothrow;\n\n    void backtrace_print(backtrace_state* state, int skip, FILE* file) nothrow;\n\n    int backtrace_pcinfo(backtrace_state* state, uintptr_t pc, backtrace_full_callback callback,\n                         backtrace_error_callback error_callback,    void* data) nothrow;\n\n    alias extern(C) void function(void* data, uintptr_t pc, const(char)* symname, uintptr_t symval)\n        backtrace_syminfo_callback;\n\n    int backtrace_syminfo(backtrace_state *state, uintptr_t pc, backtrace_syminfo_callback callback,\n                          backtrace_error_callback error_callback, void* data) nothrow;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/unwind/arm.d",
    "content": "// Exception handling and frame unwind runtime interface routines.\n// Copyright (C) 2011-2018 Free Software Foundation, Inc.\n\n// GCC is free software; you can redistribute it and/or modify it under\n// the terms of the GNU General Public License as published by the Free\n// Software Foundation; either version 3, or (at your option) any later\n// version.\n\n// GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n// WARRANTY; without even the implied warranty of MERCHANTABILITY or\n// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n// for more details.\n\n// Under Section 7 of GPL version 3, you are granted additional\n// permissions described in the GCC Runtime Library Exception, version\n// 3.1, as published by the Free Software Foundation.\n\n// You should have received a copy of the GNU General Public License and\n// a copy of the GCC Runtime Library Exception along with this program;\n// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n// <http://www.gnu.org/licenses/>.\n\n// extern(C) interface for the ARM EABI unwinder library.\n// This corresponds to unwind-arm.h\n\nmodule gcc.unwind.arm;\n\nimport gcc.config;\n\nversion (ARM):\nstatic if (GNU_ARM_EABI_Unwinder):\n\npublic import gcc.unwind.arm_common;\nimport gcc.unwind.pe;\n\nextern (C):\n@nogc:\n\nenum int UNWIND_STACK_REG = 13;\n// Use IP as a scratch register within the personality routine.\nenum int UNWIND_POINTER_REG = 12;\n\nversion (linux)\n    enum _TTYPE_ENCODING = (DW_EH_PE_pcrel | DW_EH_PE_indirect);\nelse version (NetBSD)\n    enum _TTYPE_ENCODING = (DW_EH_PE_pcrel | DW_EH_PE_indirect);\nelse version (FreeBSD)\n    enum _TTYPE_ENCODING = (DW_EH_PE_pcrel | DW_EH_PE_indirect);\nelse version (Symbian)\n    enum _TTYPE_ENCODING = (DW_EH_PE_absptr);\nelse version (uClinux)\n    enum _TTYPE_ENCODING = (DW_EH_PE_absptr);\nelse\n    enum _TTYPE_ENCODING = (DW_EH_PE_pcrel);\n\n// Return the address of the instruction, not the actual IP value.\n_Unwind_Word _Unwind_GetIP(_Unwind_Context* context)\n{\n    return _Unwind_GetGR(context, 15) & ~ cast(_Unwind_Word) 1;\n}\n\nvoid _Unwind_SetIP(_Unwind_Context* context, _Unwind_Word val)\n{\n    return _Unwind_SetGR(context, 15, val | (_Unwind_GetGR(context, 15) & 1));\n}\n\n_Unwind_Word _Unwind_GetIPInfo(_Unwind_Context* context, int* ip_before_insn)\n{\n    *ip_before_insn = 0;\n    return _Unwind_GetIP(context);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/unwind/arm_common.d",
    "content": "// Exception handling and frame unwind runtime interface routines.\n// Copyright (C) 2011-2017 Free Software Foundation, Inc.\n\n// GCC is free software; you can redistribute it and/or modify it under\n// the terms of the GNU General Public License as published by the Free\n// Software Foundation; either version 3, or (at your option) any later\n// version.\n\n// GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n// WARRANTY; without even the implied warranty of MERCHANTABILITY or\n// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n// for more details.\n\n// Under Section 7 of GPL version 3, you are granted additional\n// permissions described in the GCC Runtime Library Exception, version\n// 3.1, as published by the Free Software Foundation.\n\n// You should have received a copy of the GNU General Public License and\n// a copy of the GCC Runtime Library Exception along with this program;\n// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n// <http://www.gnu.org/licenses/>.\n\n// extern(C) interface for the ARM EABI and C6X unwinders.\n// This corresponds to unwind-arm-common.h\n\nmodule gcc.unwind.arm_common;\n\nimport gcc.config;\n\nstatic if (GNU_ARM_EABI_Unwinder):\n\nimport gcc.builtins;\n\nextern (C):\n\n// Placed outside @nogc in order to not constrain what the callback does.\n// ??? Does this really need to be extern(C) alias?\nextern(C) alias _Unwind_Exception_Cleanup_Fn\n    = void function(_Unwind_Reason_Code, _Unwind_Exception*);\n\nextern(C) alias personality_routine\n    = _Unwind_Reason_Code function(_Unwind_State,\n                                   _Unwind_Control_Block*,\n                                   _Unwind_Context*);\n\nextern(C) alias _Unwind_Stop_Fn\n    =_Unwind_Reason_Code function(int, _Unwind_Action,\n                                  _Unwind_Exception_Class,\n                                  _Unwind_Control_Block*,\n                                  _Unwind_Context*, void*);\n\nextern(C) alias _Unwind_Trace_Fn\n    = _Unwind_Reason_Code function(_Unwind_Context*, void*);\n\n@nogc:\n\nalias _Unwind_Word = __builtin_machine_uint;\nalias _Unwind_Sword = __builtin_machine_int;\nalias _Unwind_Ptr = __builtin_pointer_uint;\nalias _Unwind_Internal_Ptr =__builtin_pointer_uint;\nalias _uw = _Unwind_Word;\nalias _uw64 = ulong;\nalias _uw16 = ushort;\nalias _uw8 = ubyte;\n\nalias _Unwind_Reason_Code = uint;\nenum : _Unwind_Reason_Code\n{\n    _URC_OK = 0,        // operation completed successfully\n    _URC_FOREIGN_EXCEPTION_CAUGHT = 1,\n    _URC_END_OF_STACK = 5,\n    _URC_HANDLER_FOUND = 6,\n    _URC_INSTALL_CONTEXT = 7,\n    _URC_CONTINUE_UNWIND = 8,\n    _URC_FAILURE = 9    // unspecified failure of some kind\n}\n\nalias _Unwind_State = int;\nenum : _Unwind_State\n{\n    _US_VIRTUAL_UNWIND_FRAME = 0,\n    _US_UNWIND_FRAME_STARTING = 1,\n    _US_UNWIND_FRAME_RESUME = 2,\n    _US_ACTION_MASK = 3,\n    _US_FORCE_UNWIND = 8,\n    _US_END_OF_STACK = 16\n}\n\n// Provided only for for compatibility with existing code.\nalias _Unwind_Action = int;\nenum : _Unwind_Action\n{\n    _UA_SEARCH_PHASE = 1,\n    _UA_CLEANUP_PHASE = 2,\n    _UA_HANDLER_FRAME = 4,\n    _UA_FORCE_UNWIND = 8,\n    _UA_END_OF_STACK = 16,\n    _URC_NO_REASON = _URC_OK\n}\n\nstruct _Unwind_Context;\nalias _Unwind_EHT_Header = _uw;\n\nstruct _Unwind_Control_Block\n{\n    _Unwind_Exception_Class exception_class = '\\0';\n    _Unwind_Exception_Cleanup_Fn exception_cleanup;\n    // Unwinder cache, private fields for the unwinder's use\n    struct _unwinder_cache\n    {\n        _uw reserved1;  // Forced unwind stop fn, 0 if not forced\n        _uw reserved2;  // Personality routine address\n        _uw reserved3;  // Saved callsite address\n        _uw reserved4;  // Forced unwind stop arg\n        _uw reserved5;\n    }\n    _unwinder_cache unwinder_cache;\n    // Propagation barrier cache (valid after phase 1):\n    struct _barrier_cache\n    {\n        _uw sp;\n        _uw[5] bitpattern;\n    }\n    _barrier_cache barrier_cache;\n    // Cleanup cache (preserved over cleanup):\n    struct _cleanup_cache\n    {\n        _uw[4] bitpattern;\n    }\n    _cleanup_cache cleanup_cache;\n    // Pr cache (for pr's benefit):\n    struct _pr_cache\n    {\n        _uw fnstart;                // function start address */\n        _Unwind_EHT_Header* ehtp;   // pointer to EHT entry header word\n        _uw additional;             // additional data\n        _uw reserved1;\n    }\n    _pr_cache pr_cache;\n    long[0] _force_alignment;       // Force alignment to 8-byte boundary\n}\n\n// Virtual Register Set\nalias _Unwind_VRS_RegClass = int;\nenum : _Unwind_VRS_RegClass\n{\n    _UVRSC_CORE = 0,    // integer register\n    _UVRSC_VFP = 1,     // vfp\n    _UVRSC_FPA = 2,     // fpa\n    _UVRSC_WMMXD = 3,   // Intel WMMX data register\n    _UVRSC_WMMXC = 4    // Intel WMMX control register\n}\n\nalias _Unwind_VRS_DataRepresentation = int;\nenum : _Unwind_VRS_DataRepresentation\n{\n    _UVRSD_UINT32 = 0,\n    _UVRSD_VFPX = 1,\n    _UVRSD_FPAX = 2,\n    _UVRSD_UINT64 = 3,\n    _UVRSD_FLOAT = 4,\n    _UVRSD_DOUBLE = 5\n}\n\nalias _Unwind_VRS_Result = int;\nenum : _Unwind_VRS_Result\n{\n    _UVRSR_OK = 0,\n    _UVRSR_NOT_IMPLEMENTED = 1,\n    _UVRSR_FAILED = 2\n}\n\n// Frame unwinding state.\nstruct __gnu_unwind_state\n{\n    _uw data;           // The current word (bytes packed msb first).\n    _uw* next;          // Pointer to the next word of data.\n    _uw8 bytes_left;    // The number of bytes left in this word.\n    _uw8 words_left;    // The number of words pointed to by ptr.\n}\n\n_Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context*, _Unwind_VRS_RegClass,\n                                   _uw, _Unwind_VRS_DataRepresentation,\n                                   void*);\n\n_Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context*, _Unwind_VRS_RegClass,\n                                   _uw, _Unwind_VRS_DataRepresentation,\n                                   void*);\n\n_Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context*, _Unwind_VRS_RegClass,\n                                   _uw, _Unwind_VRS_DataRepresentation);\n\n\n// Support functions for the PR.\nalias _Unwind_Exception = _Unwind_Control_Block;\nalias _Unwind_Exception_Class = char[8];\n\nvoid* _Unwind_GetLanguageSpecificData(_Unwind_Context*);\n_Unwind_Ptr _Unwind_GetRegionStart(_Unwind_Context*);\n\n_Unwind_Ptr _Unwind_GetDataRelBase(_Unwind_Context*);\n// This should never be used.\n_Unwind_Ptr _Unwind_GetTextRelBase(_Unwind_Context*);\n\n// Interface functions:\n_Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block*);\nvoid _Unwind_Resume(_Unwind_Control_Block*);\n_Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Control_Block*);\n\n_Unwind_Reason_Code _Unwind_ForcedUnwind(_Unwind_Control_Block*,\n                                         _Unwind_Stop_Fn, void*);\n\n// @@@ Use unwind data to perform a stack backtrace.  The trace callback\n// is called for every stack frame in the call chain, but no cleanup\n// actions are performed.\n_Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void*);\n\n_Unwind_Word _Unwind_GetCFA(_Unwind_Context*);\nvoid _Unwind_Complete(_Unwind_Control_Block*);\nvoid _Unwind_DeleteException(_Unwind_Exception*);\n\n_Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Control_Block*,\n                                       _Unwind_Context*);\n_Unwind_Reason_Code __gnu_unwind_execute(_Unwind_Context*,\n                                         __gnu_unwind_state*);\n\n_Unwind_Word _Unwind_GetGR(_Unwind_Context* context, int regno)\n{\n    _uw val;\n    _Unwind_VRS_Get(context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val);\n    return val;\n}\n\nvoid _Unwind_SetGR(_Unwind_Context* context, int regno, _Unwind_Word val)\n{\n    _Unwind_VRS_Set(context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val);\n}\n\n// leb128 type numbers have a potentially unlimited size.\n// The target of the following definitions of _sleb128_t and _uleb128_t\n// is to have efficient data types large enough to hold the leb128 type\n// numbers used in the unwind code.\nalias _sleb128_t = __builtin_clong;\nalias _uleb128_t = __builtin_culong;\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/unwind/c6x.d",
    "content": "// Exception handling and frame unwind runtime interface routines.\n// Copyright (C) 2011-2018 Free Software Foundation, Inc.\n\n// GCC is free software; you can redistribute it and/or modify it under\n// the terms of the GNU General Public License as published by the Free\n// Software Foundation; either version 3, or (at your option) any later\n// version.\n\n// GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n// WARRANTY; without even the implied warranty of MERCHANTABILITY or\n// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n// for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with GCC; see the file COPYING3.  If not see\n// <http://www.gnu.org/licenses/>.\n\n// extern(C) interface for the C6X EABI unwinder library.\n// This corresponds to unwind-c6x.h\n\nmodule gcc.unwind.c6x;\n\nimport gcc.config;\n\nversion (TIC6X):\nstatic if (GNU_ARM_EABI_Unwinder):\n\n// Not really the ARM EABI, but pretty close.\npublic import gcc.unwind.arm_common;\n\nextern (C):\n@nogc:\n\nenum int UNWIND_STACK_REG = 31;\n// Use A0 as a scratch register within the personality routine.\nenum int UNWIND_POINTER_REG = 0;\n\n_Unwind_Word _Unwind_GetIP(_Unwind_Context* context)\n{\n    return _Unwind_GetGR(context, 33);\n}\n\nvoid _Unwind_SetIP(_Unwind_Context* context, _Unwind_Word val)\n{\n    return _Unwind_SetGR(context, 33, val);\n}\n\n_Unwind_Word _Unwind_GetIPInfo(_Unwind_Context* context, int* ip_before_insn)\n{\n    *ip_before_insn = 0;\n    return _Unwind_GetIP(context);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/unwind/generic.d",
    "content": "// Exception handling and frame unwind runtime interface routines.\n// Copyright (C) 2011-2018 Free Software Foundation, Inc.\n\n// GCC is free software; you can redistribute it and/or modify it under\n// the terms of the GNU General Public License as published by the Free\n// Software Foundation; either version 3, or (at your option) any later\n// version.\n\n// GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n// WARRANTY; without even the implied warranty of MERCHANTABILITY or\n// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n// for more details.\n\n// Under Section 7 of GPL version 3, you are granted additional\n// permissions described in the GCC Runtime Library Exception, version\n// 3.1, as published by the Free Software Foundation.\n\n// You should have received a copy of the GNU General Public License and\n// a copy of the GCC Runtime Library Exception along with this program;\n// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n// <http://www.gnu.org/licenses/>.\n\n// extern(C) interface for the generic unwinder library.\n// This corresponds to unwind-generic.h\n\nmodule gcc.unwind.generic;\n\nimport gcc.config;\n\nstatic if (!GNU_ARM_EABI_Unwinder):\n\nimport gcc.builtins;\n\n// This is derived from the C++ ABI for IA-64.  Where we diverge\n// for cross-architecture compatibility are noted with \"@@@\".\n\nextern (C):\n\n// Placed outside @nogc in order to not constrain what the callback does.\n// ??? Does this really need to be extern(C) alias?\n\nextern(C) alias _Unwind_Exception_Cleanup_Fn\n    = void function(_Unwind_Reason_Code, _Unwind_Exception*);\n\nextern(C) alias _Unwind_Stop_Fn\n    = _Unwind_Reason_Code function(int, _Unwind_Action,\n                                   _Unwind_Exception_Class,\n                                   _Unwind_Exception*,\n                                   _Unwind_Context*, void*);\n\nextern(C) alias _Unwind_Trace_Fn\n    = _Unwind_Reason_Code function(_Unwind_Context*, void*);\n\n// The personality routine is the function in the C++ (or other language)\n// runtime library which serves as an interface between the system unwind\n// library and language-specific exception handling semantics.  It is\n// specific to the code fragment described by an unwind info block, and\n// it is always referenced via the pointer in the unwind info block, and\n// hence it has no ABI-specified name.\n\n// Note that this implies that two different C++ implementations can\n// use different names, and have different contents in the language\n// specific data area.  Moreover, that the language specific data\n// area contains no version info because name of the function invoked\n// provides more effective versioning by detecting at link time the\n// lack of code to handle the different data format.\n\nextern(C) alias _Unwind_Personality_Fn\n    = _Unwind_Reason_Code function(int, _Unwind_Action,\n                                   _Unwind_Exception_Class,\n                                   _Unwind_Exception*,\n                                   _Unwind_Context*);\n\n@nogc:\n\n// Level 1: Base ABI\n\n// @@@ The IA-64 ABI uses uint64 throughout.\n// Most places this is inefficient for 32-bit and smaller machines.\nalias _Unwind_Word = __builtin_unwind_uint;\nalias _Unwind_Sword = __builtin_unwind_int;\nversion (IA64)\n{\n    version (HPUX)\n        alias _Unwind_Ptr = __builtin_machine_uint;\n    else\n        alias _Unwind_Ptr = __builtin_pointer_uint;\n}\nelse\n{\n    alias _Unwind_Ptr = __builtin_pointer_uint;\n}\nalias _Unwind_Internal_Ptr = __builtin_pointer_uint;\n\n// @@@ The IA-64 ABI uses a 64-bit word to identify the producer and\n// consumer of an exception.  We'll go along with this for now even on\n// 32-bit machines.  We'll need to provide some other option for\n// 16-bit machines and for machines with > 8 bits per byte.\nalias _Unwind_Exception_Class = ulong;\n\n// The unwind interface uses reason codes in several contexts to\n// identify the reasons for failures or other actions.\nalias _Unwind_Reason_Code = uint;\nenum : _Unwind_Reason_Code\n{\n    _URC_NO_REASON = 0,\n    _URC_FOREIGN_EXCEPTION_CAUGHT = 1,\n    _URC_FATAL_PHASE2_ERROR = 2,\n    _URC_FATAL_PHASE1_ERROR = 3,\n    _URC_NORMAL_STOP = 4,\n    _URC_END_OF_STACK = 5,\n    _URC_HANDLER_FOUND = 6,\n    _URC_INSTALL_CONTEXT = 7,\n    _URC_CONTINUE_UNWIND = 8\n}\n\n// The unwind interface uses a pointer to an exception header object\n// as its representation of an exception being thrown. In general, the\n// full representation of an exception object is language- and\n// implementation-specific, but it will be prefixed by a header\n// understood by the unwind interface.\n\n// @@@ The IA-64 ABI says that this structure must be double-word aligned.\n// Taking that literally does not make much sense generically.  Instead we\n// provide the maximum alignment required by any type for the machine.\nstruct _Unwind_Exception\n{\n    _Unwind_Exception_Class exception_class;\n    _Unwind_Exception_Cleanup_Fn exception_cleanup;\n    _Unwind_Word private_1;\n    _Unwind_Word private_2;\n}\n\n// The ACTIONS argument to the personality routine is a bitwise OR of one\n// or more of the following constants.\nalias _Unwind_Action = int;\nenum : _Unwind_Action\n{\n    _UA_SEARCH_PHASE = 1,\n    _UA_CLEANUP_PHASE = 2,\n    _UA_HANDLER_FRAME = 4,\n    _UA_FORCE_UNWIND = 8,\n    _UA_END_OF_STACK = 16\n}\n\n// This is an opaque type used to refer to a system-specific data\n// structure used by the system unwinder. This context is created and\n// destroyed by the system, and passed to the personality routine\n// during unwinding.\nstruct _Unwind_Context;\n\n// Raise an exception, passing along the given exception object.\n_Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*);\n\n// Raise an exception for forced unwinding.\n_Unwind_Reason_Code _Unwind_ForcedUnwind(_Unwind_Exception*, _Unwind_Stop_Fn, void*);\n\n// Helper to invoke the exception_cleanup routine.\nvoid _Unwind_DeleteException(_Unwind_Exception*);\n\n// Resume propagation of an existing exception.  This is used after\n// e.g. executing cleanup code, and not to implement rethrowing.\nvoid _Unwind_Resume(_Unwind_Exception*);\n\n// @@@ Resume propagation of an FORCE_UNWIND exception, or to rethrow\n// a normal exception that was handled.\n_Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Exception*);\n\n// @@@ Use unwind data to perform a stack backtrace.  The trace callback\n// is called for every stack frame in the call chain, but no cleanup\n// actions are performed.\n_Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void*);\n\n// These functions are used for communicating information about the unwind\n// context (i.e. the unwind descriptors and the user register state) between\n// the unwind library and the personality routine and landing pad.  Only\n// selected registers may be manipulated.\n\n_Unwind_Word _Unwind_GetGR(_Unwind_Context*, int);\nvoid _Unwind_SetGR(_Unwind_Context*, int, _Unwind_Word);\n\n_Unwind_Ptr _Unwind_GetIP(_Unwind_Context*);\n_Unwind_Ptr _Unwind_GetIPInfo(_Unwind_Context*, int*);\nvoid _Unwind_SetIP(_Unwind_Context*, _Unwind_Ptr);\n\n// @@@ Retrieve the CFA of the given context.\n_Unwind_Word _Unwind_GetCFA(_Unwind_Context*);\n\nvoid* _Unwind_GetLanguageSpecificData(_Unwind_Context*);\n\n_Unwind_Ptr _Unwind_GetRegionStart(_Unwind_Context*);\n\n\n// @@@ The following alternate entry points are for setjmp/longjmp\n// based unwinding.\n\nstruct SjLj_Function_Context;\nextern void _Unwind_SjLj_Register(SjLj_Function_Context*);\nextern void _Unwind_SjLj_Unregister(SjLj_Function_Context*);\n\n_Unwind_Reason_Code _Unwind_SjLj_RaiseException(_Unwind_Exception*);\n_Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(_Unwind_Exception*, _Unwind_Stop_Fn, void*);\nvoid _Unwind_SjLj_Resume(_Unwind_Exception*);\n_Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception*);\n\n// @@@ The following provide access to the base addresses for text\n// and data-relative addressing in the LDSA.  In order to stay link\n// compatible with the standard ABI for IA-64, we inline these.\n\nversion (IA64)\n{\n    _Unwind_Ptr _Unwind_GetDataRelBase(_Unwind_Context* _C)\n    {\n        // The GP is stored in R1.\n        return _Unwind_GetGR(_C, 1);\n    }\n\n    _Unwind_Ptr _Unwind_GetTextRelBase(_Unwind_Context*)\n    {\n        __builtin_abort();\n        return 0;\n    }\n\n    // @@@ Retrieve the Backing Store Pointer of the given context.\n    _Unwind_Word _Unwind_GetBSP(_Unwind_Context*);\n}\nelse\n{\n    _Unwind_Ptr _Unwind_GetDataRelBase(_Unwind_Context*);\n    _Unwind_Ptr _Unwind_GetTextRelBase(_Unwind_Context*);\n}\n\n// @@@ Given an address, return the entry point of the function that\n// contains it.\nextern void* _Unwind_FindEnclosingFunction(void* pc);\n\n\n// leb128 type numbers have a potentially unlimited size.\n// The target of the following definitions of _sleb128_t and _uleb128_t\n// is to have efficient data types large enough to hold the leb128 type\n// numbers used in the unwind code.\n// Mostly these types will simply be defined to long and unsigned long\n// except when a unsigned long data type on the target machine is not\n// capable of storing a pointer.\n\nstatic if (__builtin_clong.sizeof >= (void*).sizeof)\n{\n    alias _sleb128_t = __builtin_clong;\n    alias _uleb128_t = __builtin_culong;\n}\nelse static if (long.sizeof >= (void*).sizeof)\n{\n    alias _sleb128_t = long;\n    alias _uleb128_t = ulong;\n}\nelse\n{\n    static assert(false, \"What type shall we use for _sleb128_t?\");\n}\n\nversion (GNU_SEH_Exceptions)\n{\n    // We're lazy, exact definition in MinGW/winnt.h\n    enum EXCEPTION_DISPOSITION\n    {\n        ExceptionContinueExecution,\n        ExceptionContinueSearch,\n        ExceptionNestedException,\n        ExceptionCollidedUnwind\n    }\n\n    extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*,\n                                                          _Unwind_Personality_Fn);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/unwind/package.d",
    "content": "// Exception handling and frame unwind runtime interface routines.\n// Copyright (C) 2011-2018 Free Software Foundation, Inc.\n\n// GCC is free software; you can redistribute it and/or modify it under\n// the terms of the GNU General Public License as published by the Free\n// Software Foundation; either version 3, or (at your option) any later\n// version.\n\n// GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n// WARRANTY; without even the implied warranty of MERCHANTABILITY or\n// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n// for more details.\n\n// Under Section 7 of GPL version 3, you are granted additional\n// permissions described in the GCC Runtime Library Exception, version\n// 3.1, as published by the Free Software Foundation.\n\n// You should have received a copy of the GNU General Public License and\n// a copy of the GCC Runtime Library Exception along with this program;\n// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n// <http://www.gnu.org/licenses/>.\n\nmodule gcc.unwind;\n\nimport gcc.config;\n\nstatic if (GNU_ARM_EABI_Unwinder)\n{\n    version (ARM)\n        public import gcc.unwind.arm;\n    else version (TIC6X)\n        public import gcc.unwind.c6x;\n    else\n        static assert(false, \"Unsupported target for ARM_EABI_UNWINDER\");\n}\nelse\n    public import gcc.unwind.generic;\n"
  },
  {
    "path": "libphobos/libdruntime/gcc/unwind/pe.d",
    "content": "// Exception handling and frame unwind runtime interface routines.\n// Copyright (C) 2011-2018 Free Software Foundation, Inc.\n\n// GCC is free software; you can redistribute it and/or modify it under\n// the terms of the GNU General Public License as published by the Free\n// Software Foundation; either version 3, or (at your option) any later\n// version.\n\n// GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n// WARRANTY; without even the implied warranty of MERCHANTABILITY or\n// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n// for more details.\n\n// Under Section 7 of GPL version 3, you are granted additional\n// permissions described in the GCC Runtime Library Exception, version\n// 3.1, as published by the Free Software Foundation.\n\n// You should have received a copy of the GNU General Public License and\n// a copy of the GCC Runtime Library Exception along with this program;\n// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n// <http://www.gnu.org/licenses/>.\n\n// extern(C) interface for the GNU/GCC pointer encoding library.\n// This corresponds to unwind-pe.h\n\nmodule gcc.unwind.pe;\n\nimport gcc.unwind;\nimport gcc.builtins;\n\n@nogc:\n\n// Pointer encodings, from dwarf2.h.\nenum\n{\n    DW_EH_PE_absptr   = 0x00,\n    DW_EH_PE_omit     = 0xff,\n\n    DW_EH_PE_uleb128  = 0x01,\n    DW_EH_PE_udata2   = 0x02,\n    DW_EH_PE_udata4   = 0x03,\n    DW_EH_PE_udata8   = 0x04,\n    DW_EH_PE_sleb128  = 0x09,\n    DW_EH_PE_sdata2   = 0x0A,\n    DW_EH_PE_sdata4   = 0x0B,\n    DW_EH_PE_sdata8   = 0x0C,\n    DW_EH_PE_signed   = 0x08,\n\n    DW_EH_PE_pcrel    = 0x10,\n    DW_EH_PE_textrel  = 0x20,\n    DW_EH_PE_datarel  = 0x30,\n    DW_EH_PE_funcrel  = 0x40,\n    DW_EH_PE_aligned  = 0x50,\n\n    DW_EH_PE_indirect = 0x80\n}\n\n// Given an encoding, return the number of bytes the format occupies.\n// This is only defined for fixed-size encodings, and so does not\n// include leb128.\nuint size_of_encoded_value(ubyte encoding)\n{\n    if (encoding == DW_EH_PE_omit)\n        return 0;\n\n    final switch (encoding & 0x07)\n    {\n        case DW_EH_PE_absptr:\n            return (void*).sizeof;\n        case DW_EH_PE_udata2:\n            return 2;\n        case DW_EH_PE_udata4:\n            return 4;\n        case DW_EH_PE_udata8:\n            return 8;\n    }\n    assert(0);\n}\n\n// Given an encoding and an _Unwind_Context, return the base to which\n// the encoding is relative.  This base may then be passed to\n// read_encoded_value_with_base for use when the _Unwind_Context is\n// not available.\n_Unwind_Ptr base_of_encoded_value(ubyte encoding, _Unwind_Context* context)\n{\n    if (encoding == DW_EH_PE_omit)\n        return cast(_Unwind_Ptr) 0;\n\n    final switch (encoding & 0x70)\n    {\n        case DW_EH_PE_absptr:\n        case DW_EH_PE_pcrel:\n        case DW_EH_PE_aligned:\n            return cast(_Unwind_Ptr) 0;\n\n        case DW_EH_PE_textrel:\n            return _Unwind_GetTextRelBase(context);\n        case DW_EH_PE_datarel:\n            return _Unwind_GetDataRelBase(context);\n        case DW_EH_PE_funcrel:\n            return _Unwind_GetRegionStart(context);\n    }\n    assert(0);\n}\n\n// Read an unsigned leb128 value from P, *P is incremented past the value.\n// We assume that a word is large enough to hold any value so encoded;\n// if it is smaller than a pointer on some target, pointers should not be\n// leb128 encoded on that target.\n_uleb128_t read_uleb128(const(ubyte)** p)\n{\n    auto q = *p;\n    _uleb128_t result = 0;\n    uint shift = 0;\n\n    while (1)\n    {\n        ubyte b = *q++;\n        result |= cast(_uleb128_t)(b & 0x7F) << shift;\n        if ((b & 0x80) == 0)\n            break;\n        shift += 7;\n    }\n\n    *p = q;\n    return result;\n}\n\n// Similar, but read a signed leb128 value.\n_sleb128_t read_sleb128(const(ubyte)** p)\n{\n    auto q = *p;\n    _sleb128_t result = 0;\n    uint shift = 0;\n    ubyte b = void;\n\n    while (1)\n    {\n        b = *q++;\n        result |= cast(_sleb128_t)(b & 0x7F) << shift;\n        shift += 7;\n        if ((b & 0x80) == 0)\n            break;\n    }\n\n    // Sign-extend a negative value.\n    if (shift < result.sizeof * 8 && (b & 0x40))\n        result |= -(cast(_sleb128_t)1 << shift);\n\n    *p = q;\n    return result;\n}\n\n// Load an encoded value from memory at P.  The value is returned in VAL;\n// The function returns P incremented past the value.  BASE is as given\n// by base_of_encoded_value for this encoding in the appropriate context.\n_Unwind_Ptr read_encoded_value_with_base(ubyte encoding, _Unwind_Ptr base,\n                                         const(ubyte)** p)\n{\n    auto q = *p;\n    _Unwind_Internal_Ptr result;\n\n    if (encoding == DW_EH_PE_aligned)\n    {\n        _Unwind_Internal_Ptr a = cast(_Unwind_Internal_Ptr)q;\n        a = cast(_Unwind_Internal_Ptr)((a + (void*).sizeof - 1) & - (void*).sizeof);\n        result = *cast(_Unwind_Internal_Ptr*)a;\n        q = cast(ubyte*) cast(_Unwind_Internal_Ptr)(a + (void*).sizeof);\n    }\n    else\n    {\n        switch (encoding & 0x0f)\n        {\n            case DW_EH_PE_uleb128:\n                result = cast(_Unwind_Internal_Ptr)read_uleb128(&q);\n                break;\n\n            case DW_EH_PE_sleb128:\n                result = cast(_Unwind_Internal_Ptr)read_sleb128(&q);\n                break;\n\n            case DW_EH_PE_udata2:\n                result = cast(_Unwind_Internal_Ptr) *cast(ushort*)q;\n                q += 2;\n                break;\n            case DW_EH_PE_udata4:\n                result = cast(_Unwind_Internal_Ptr) *cast(uint*)q;\n                q += 4;\n                break;\n            case DW_EH_PE_udata8:\n                result = cast(_Unwind_Internal_Ptr) *cast(ulong*)q;\n                q += 8;\n                break;\n\n            case DW_EH_PE_sdata2:\n                result = cast(_Unwind_Internal_Ptr) *cast(short*)q;\n                q += 2;\n                break;\n            case DW_EH_PE_sdata4:\n                result = cast(_Unwind_Internal_Ptr) *cast(int*)q;\n                q += 4;\n                break;\n            case DW_EH_PE_sdata8:\n                result = cast(_Unwind_Internal_Ptr) *cast(long*)q;\n                q += 8;\n                break;\n\n            case DW_EH_PE_absptr:\n                if (size_t.sizeof == 8)\n                    goto case DW_EH_PE_udata8;\n                else\n                    goto case DW_EH_PE_udata4;\n\n            default:\n                __builtin_abort();\n        }\n\n        if (result != 0)\n        {\n            result += ((encoding & 0x70) == DW_EH_PE_pcrel\n                       ? cast(_Unwind_Internal_Ptr)*p : base);\n            if (encoding & DW_EH_PE_indirect)\n                result = *cast(_Unwind_Internal_Ptr*)result;\n        }\n    }\n\n    *p = q;\n    return result;\n}\n\n// Like read_encoded_value_with_base, but get the base from the context\n// rather than providing it directly.\n_Unwind_Ptr read_encoded_value(_Unwind_Context* context, ubyte encoding,\n                               const(ubyte)** p)\n{\n    auto base = base_of_encoded_value(encoding, context);\n    return read_encoded_value_with_base(encoding, base, p);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/object.d",
    "content": "/**\n * Forms the symbols available to all D programs. Includes Object, which is\n * the root of the class object hierarchy.  This module is implicitly\n * imported.\n *\n * Copyright: Copyright Digital Mars 2000 - 2011.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, Sean Kelly\n */\n\nmodule object;\n\n// NOTE: For some reason, this declaration method doesn't work\n//       in this particular file (and this file only).  It must\n//       be a DMD thing.\n//alias typeof(int.sizeof)                    size_t;\n//alias typeof(cast(void*)0 - cast(void*)0)   ptrdiff_t;\n\nversion (D_LP64)\n{\n    alias size_t = ulong;\n    alias ptrdiff_t = long;\n}\nelse\n{\n    alias size_t = uint;\n    alias ptrdiff_t = int;\n}\n\nalias sizediff_t = ptrdiff_t; //For backwards compatibility only.\n\nalias hash_t = size_t; //For backwards compatibility only.\nalias equals_t = bool; //For backwards compatibility only.\n\nalias string  = immutable(char)[];\nalias wstring = immutable(wchar)[];\nalias dstring = immutable(dchar)[];\n\nversion (D_ObjectiveC) public import core.attribute : selector;\n\nint __cmp(T)(const T[] lhs, const T[] rhs) @trusted\n    if (__traits(isScalar, T))\n{\n    // Compute U as the implementation type for T\n    static if (is(T == ubyte) || is(T == void) || is(T == bool))\n        alias U = char;\n    else static if (is(T == wchar))\n        alias U = ushort;\n    else static if (is(T == dchar))\n        alias U = uint;\n    else static if (is(T == ifloat))\n        alias U = float;\n    else static if (is(T == idouble))\n        alias U = double;\n    else static if (is(T == ireal))\n        alias U = real;\n    else\n        alias U = T;\n\n    static if (is(U == char))\n    {\n        import core.internal.string : dstrcmp;\n        return dstrcmp(cast(char[]) lhs, cast(char[]) rhs);\n    }\n    else static if (!is(U == T))\n    {\n        // Reuse another implementation\n        return __cmp(cast(U[]) lhs, cast(U[]) rhs);\n    }\n    else\n    {\n        immutable len = lhs.length <= rhs.length ? lhs.length : rhs.length;\n        foreach (const u; 0 .. len)\n        {\n            static if (__traits(isFloating, T))\n            {\n                immutable a = lhs.ptr[u], b = rhs.ptr[u];\n                static if (is(T == cfloat) || is(T == cdouble)\n                    || is(T == creal))\n                {\n                    // Use rt.cmath2._Ccmp instead ?\n                    auto r = (a.re > b.re) - (a.re < b.re);\n                    if (!r) r = (a.im > b.im) - (a.im < b.im);\n                }\n                else\n                {\n                    const r = (a > b) - (a < b);\n                }\n                if (r) return r;\n            }\n            else if (lhs.ptr[u] != rhs.ptr[u])\n                return lhs.ptr[u] < rhs.ptr[u] ? -1 : 1;\n        }\n        return lhs.length < rhs.length ? -1 : (lhs.length > rhs.length);\n    }\n}\n\n    // Compare class and interface objects for ordering.\n    private int __cmp(Obj)(Obj lhs, Obj rhs)\n    if (is(Obj : Object))\n    {\n        if (lhs is rhs)\n            return 0;\n        // Regard null references as always being \"less than\"\n        if (!lhs)\n            return -1;\n        if (!rhs)\n            return 1;\n        return lhs.opCmp(rhs);\n    }\n\n    // This function is called by the compiler when dealing with array\n    // comparisons in the semantic analysis phase of CmpExp. The ordering\n    // comparison is lowered to a call to this template.\n    int __cmp(T1, T2)(T1[] s1, T2[] s2)\n    if (!__traits(isScalar, T1) && !__traits(isScalar, T2))\n    {\n        import core.internal.traits : Unqual;\n        alias U1 = Unqual!T1;\n        alias U2 = Unqual!T2;\n\n        static if (is(U1 == void) && is(U2 == void))\n            static @trusted ref inout(ubyte) at(inout(void)[] r, size_t i) { return (cast(inout(ubyte)*) r.ptr)[i]; }\n        else\n            static @trusted ref R at(R)(R[] r, size_t i) { return r.ptr[i]; }\n\n        // All unsigned byte-wide types = > dstrcmp\n        immutable len = s1.length <= s2.length ? s1.length : s2.length;\n\n        foreach (const u; 0 .. len)\n        {\n            static if (__traits(compiles, __cmp(at(s1, u), at(s2, u))))\n            {\n                auto c = __cmp(at(s1, u), at(s2, u));\n                if (c != 0)\n                    return c;\n            }\n            else static if (__traits(compiles, at(s1, u).opCmp(at(s2, u))))\n            {\n                auto c = at(s1, u).opCmp(at(s2, u));\n                if (c != 0)\n                    return c;\n            }\n            else static if (__traits(compiles, at(s1, u) < at(s2, u)))\n            {\n                if (at(s1, u) != at(s2, u))\n                    return at(s1, u) < at(s2, u) ? -1 : 1;\n            }\n            else\n            {\n                // TODO: fix this legacy bad behavior, see\n                // https://issues.dlang.org/show_bug.cgi?id=17244\n                static assert(is(U1 == U2), \"Internal error.\");\n                import core.stdc.string : memcmp;\n                auto c = (() @trusted => memcmp(&at(s1, u), &at(s2, u), U1.sizeof))();\n                if (c != 0)\n                    return c;\n            }\n        }\n        return s1.length < s2.length ? -1 : (s1.length > s2.length);\n    }\n\n    // integral types\n    @safe unittest\n    {\n        void compareMinMax(T)()\n        {\n            T[2] a = [T.max, T.max];\n            T[2] b = [T.min, T.min];\n\n            assert(__cmp(a, b) > 0);\n            assert(__cmp(b, a) < 0);\n        }\n\n        compareMinMax!int;\n        compareMinMax!uint;\n        compareMinMax!long;\n        compareMinMax!ulong;\n        compareMinMax!short;\n        compareMinMax!ushort;\n        compareMinMax!byte;\n        compareMinMax!dchar;\n        compareMinMax!wchar;\n    }\n\n    // char types (dstrcmp)\n    @safe unittest\n    {\n        void compareMinMax(T)()\n        {\n            T[2] a = [T.max, T.max];\n            T[2] b = [T.min, T.min];\n\n            assert(__cmp(a, b) > 0);\n            assert(__cmp(b, a) < 0);\n        }\n\n        compareMinMax!ubyte;\n        compareMinMax!bool;\n        compareMinMax!char;\n        compareMinMax!(const char);\n\n        string s1 = \"aaaa\";\n        string s2 = \"bbbb\";\n        assert(__cmp(s2, s1) > 0);\n        assert(__cmp(s1, s2) < 0);\n    }\n\n    // fp types\n    @safe unittest\n    {\n        void compareMinMax(T)()\n        {\n            T[2] a = [T.max, T.max];\n            T[2] b = [T.min_normal, T.min_normal];\n            T[2] c = [T.max, T.min_normal];\n            T[1] d = [T.max];\n\n            assert(__cmp(a, b) > 0);\n            assert(__cmp(b, a) < 0);\n            assert(__cmp(a, c) > 0);\n            assert(__cmp(a, d) > 0);\n            assert(__cmp(d, c) < 0);\n            assert(__cmp(c, c) == 0);\n        }\n\n        compareMinMax!real;\n        compareMinMax!float;\n        compareMinMax!double;\n        compareMinMax!ireal;\n        compareMinMax!ifloat;\n        compareMinMax!idouble;\n        compareMinMax!creal;\n        //compareMinMax!cfloat;\n        compareMinMax!cdouble;\n\n        // qualifiers\n        compareMinMax!(const real);\n        compareMinMax!(immutable real);\n    }\n\n    // void[]\n    @safe unittest\n    {\n        void[] a;\n        const(void)[] b;\n\n        (() @trusted\n        {\n            a = cast(void[]) \"bb\";\n            b = cast(const(void)[]) \"aa\";\n        })();\n\n        assert(__cmp(a, b) > 0);\n        assert(__cmp(b, a) < 0);\n    }\n\n    // arrays of arrays with mixed modifiers\n    @safe unittest\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=17876\n        bool less1(immutable size_t[][] a, size_t[][] b) { return a < b; }\n        bool less2(const void[][] a, void[][] b) { return a < b; }\n        bool less3(inout size_t[][] a, size_t[][] b) { return a < b; }\n\n        immutable size_t[][] a = [[1, 2], [3, 4]];\n        size_t[][] b = [[1, 2], [3, 5]];\n        assert(less1(a, b));\n        assert(less3(a, b));\n\n        auto va = [cast(immutable void[])a[0], a[1]];\n        auto vb = [cast(void[])b[0], b[1]];\n        assert(less2(va, vb));\n    }\n\n    // objects\n    @safe unittest\n    {\n        class C\n        {\n            int i;\n            this(int i) { this.i = i; }\n\n            override int opCmp(Object c) const @safe\n            {\n                return i - (cast(C)c).i;\n            }\n        }\n\n        auto c1 = new C(1);\n        auto c2 = new C(2);\n        assert(__cmp(c1, null) > 0);\n        assert(__cmp(null, c1) < 0);\n        assert(__cmp(c1, c1) == 0);\n        assert(__cmp(c1, c2) < 0);\n        assert(__cmp(c2, c1) > 0);\n\n        assert(__cmp([c1, c1][], [c2, c2][]) < 0);\n        assert(__cmp([c2, c2], [c1, c1]) > 0);\n    }\n\n    // structs\n    @safe unittest\n    {\n        struct C\n        {\n            ubyte i;\n            this(ubyte i) { this.i = i; }\n        }\n\n        auto c1 = C(1);\n        auto c2 = C(2);\n\n        assert(__cmp([c1, c1][], [c2, c2][]) < 0);\n        assert(__cmp([c2, c2], [c1, c1]) > 0);\n        assert(__cmp([c2, c2], [c2, c1]) > 0);\n    }\n\n// `lhs == rhs` lowers to `__equals(lhs, rhs)` for dynamic arrays\nbool __equals(T1, T2)(T1[] lhs, T2[] rhs)\n{\n    import core.internal.traits : Unqual;\n    alias U1 = Unqual!T1;\n    alias U2 = Unqual!T2;\n\n    static @trusted ref R at(R)(R[] r, size_t i) { return r.ptr[i]; }\n    static @trusted R trustedCast(R, S)(S[] r) { return cast(R) r; }\n\n    if (lhs.length != rhs.length)\n        return false;\n\n    if (lhs.length == 0 && rhs.length == 0)\n        return true;\n\n    static if (is(U1 == void) && is(U2 == void))\n    {\n        return __equals(trustedCast!(ubyte[])(lhs), trustedCast!(ubyte[])(rhs));\n    }\n    else static if (is(U1 == void))\n    {\n        return __equals(trustedCast!(ubyte[])(lhs), rhs);\n    }\n    else static if (is(U2 == void))\n    {\n        return __equals(lhs, trustedCast!(ubyte[])(rhs));\n    }\n    else static if (!is(U1 == U2))\n    {\n        // This should replace src/object.d _ArrayEq which\n        // compares arrays of different types such as long & int,\n        // char & wchar.\n        // Compiler lowers to __ArrayEq in dmd/src/opover.d\n        foreach (const u; 0 .. lhs.length)\n        {\n            if (at(lhs, u) != at(rhs, u))\n                return false;\n        }\n        return true;\n    }\n    else static if (__traits(isIntegral, U1))\n    {\n\n        if (!__ctfe)\n        {\n            import core.stdc.string : memcmp;\n            return () @trusted { return memcmp(cast(void*)lhs.ptr, cast(void*)rhs.ptr, lhs.length * U1.sizeof) == 0; }();\n        }\n        else\n        {\n            foreach (const u; 0 .. lhs.length)\n            {\n                if (at(lhs, u) != at(rhs, u))\n                    return false;\n            }\n            return true;\n        }\n    }\n    else\n    {\n        foreach (const u; 0 .. lhs.length)\n        {\n            static if (__traits(compiles, __equals(at(lhs, u), at(rhs, u))))\n            {\n                if (!__equals(at(lhs, u), at(rhs, u)))\n                    return false;\n            }\n            else static if (__traits(isFloating, U1))\n            {\n                if (at(lhs, u) != at(rhs, u))\n                    return false;\n            }\n            else static if (is(U1 : Object) && is(U2 : Object))\n            {\n                if (!(cast(Object)at(lhs, u) is cast(Object)at(rhs, u)\n                    || at(lhs, u) && (cast(Object)at(lhs, u)).opEquals(cast(Object)at(rhs, u))))\n                    return false;\n            }\n            else static if (__traits(hasMember, U1, \"opEquals\"))\n            {\n                if (!at(lhs, u).opEquals(at(rhs, u)))\n                    return false;\n            }\n            else static if (is(U1 == delegate))\n            {\n                if (at(lhs, u) != at(rhs, u))\n                    return false;\n            }\n            else static if (is(U1 == U11*, U11))\n            {\n                if (at(lhs, u) != at(rhs, u))\n                    return false;\n            }\n            else static if (__traits(isAssociativeArray, U1))\n            {\n                if (at(lhs, u) != at(rhs, u))\n                    return false;\n            }\n            else\n            {\n                if (at(lhs, u).tupleof != at(rhs, u).tupleof)\n                    return false;\n            }\n        }\n\n        return true;\n    }\n}\n\nunittest {\n    assert(__equals([], []));\n    assert(!__equals([1, 2], [1, 2, 3]));\n}\n\nunittest\n{\n    struct A\n    {\n        int a;\n    }\n\n    auto arr1 = [A(0), A(2)];\n    auto arr2 = [A(0), A(1)];\n    auto arr3 = [A(0), A(1)];\n\n    assert(arr1 != arr2);\n    assert(arr2 == arr3);\n}\n\nunittest\n{\n    struct A\n    {\n        int a;\n        int b;\n\n        bool opEquals(const A other)\n        {\n            return this.a == other.b && this.b == other.a;\n        }\n    }\n\n    auto arr1 = [A(1, 0), A(0, 1)];\n    auto arr2 = [A(1, 0), A(0, 1)];\n    auto arr3 = [A(0, 1), A(1, 0)];\n\n    assert(arr1 != arr2);\n    assert(arr2 == arr3);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=18252\nunittest\n{\n    string[int][] a1, a2;\n    assert(__equals(a1, a2));\n    assert(a1 == a2);\n    a1 ~= [0: \"zero\"];\n    a2 ~= [0: \"zero\"];\n    assert(__equals(a1, a2));\n    assert(a1 == a2);\n    a2[0][1] = \"one\";\n    assert(!__equals(a1, a2));\n    assert(a1 != a2);\n}\n\n/**\nDestroys the given object and sets it back to its initial state. It's used to\n_destroy an object, calling its destructor or finalizer so it no longer\nreferences any other objects. It does $(I not) initiate a GC cycle or free\nany GC memory.\n*/\nvoid destroy(T)(ref T obj) if (is(T == struct))\n{\n    // We need to re-initialize `obj`.  Previously, the code\n    // `auto init = cast(ubyte[])typeid(T).initializer()` was used, but\n    // `typeid` is a runtime call and requires the `TypeInfo` object which is\n    // not usable when compiling with -betterC.  If we do `obj = T.init` then we\n    // end up needlessly calling postblits and destructors.  So, we create a\n    // static immutable lvalue that can be re-used with subsequent calls to `destroy`\n    shared static immutable T init = T.init;\n\n    _destructRecurse(obj);\n    () @trusted {\n        import core.stdc.string : memcpy;\n        auto dest = (cast(ubyte*) &obj)[0 .. T.sizeof];\n        auto src = (cast(ubyte*) &init)[0 .. T.sizeof];\n        memcpy(dest.ptr, src.ptr, T.sizeof);\n    } ();\n}\n\nprivate void _destructRecurse(S)(ref S s)\n    if (is(S == struct))\n{\n    static if (__traits(hasMember, S, \"__xdtor\") &&\n            // Bugzilla 14746: Check that it's the exact member of S.\n            __traits(isSame, S, __traits(parent, s.__xdtor)))\n        s.__xdtor();\n}\n\nnothrow @safe @nogc unittest\n{\n    {\n        struct A { string s = \"A\";  }\n        A a;\n        a.s = \"asd\";\n        destroy(a);\n        assert(a.s == \"A\");\n    }\n    {\n        static int destroyed = 0;\n        struct C\n        {\n            string s = \"C\";\n            ~this() nothrow @safe @nogc\n            {\n                destroyed ++;\n            }\n        }\n\n        struct B\n        {\n            C c;\n            string s = \"B\";\n            ~this() nothrow @safe @nogc\n            {\n                destroyed ++;\n            }\n        }\n        B a;\n        a.s = \"asd\";\n        a.c.s = \"jkl\";\n        destroy(a);\n        assert(destroyed == 2);\n        assert(a.s == \"B\");\n        assert(a.c.s == \"C\" );\n    }\n}\n\n\n    /// ditto\n    void destroy(T)(T obj) if (is(T == class))\n    {\n        static if (__traits(getLinkage, T) == \"C++\")\n        {\n            obj.__xdtor();\n\n            enum classSize = __traits(classInstanceSize, T);\n            (cast(void*)obj)[0 .. classSize] = typeid(T).initializer[];\n        }\n        else\n            rt_finalize(cast(void*)obj);\n    }\n\n    /// ditto\n    void destroy(T)(T obj) if (is(T == interface))\n    {\n        destroy(cast(Object)obj);\n    }\n\n    /// Reference type demonstration\n    unittest\n    {\n        class C\n        {\n            struct Agg\n            {\n                static int dtorCount;\n\n                int x = 10;\n                ~this() { dtorCount++; }\n            }\n\n            static int dtorCount;\n\n            string s = \"S\";\n            Agg a;\n            ~this() { dtorCount++; }\n        }\n\n        C c = new C();\n        assert(c.dtorCount == 0);   // destructor not yet called\n        assert(c.s == \"S\");         // initial state `c.s` is `\"S\"`\n        assert(c.a.dtorCount == 0); // destructor not yet called\n        assert(c.a.x == 10);        // initial state `c.a.x` is `10`\n        c.s = \"T\";\n        c.a.x = 30;\n        assert(c.s == \"T\");         // `c.s` is `\"T\"`\n        destroy(c);\n        assert(c.dtorCount == 1);   // `c`'s destructor was called\n        assert(c.s == \"S\");         // `c.s` is back to its inital state, `\"S\"`\n        assert(c.a.dtorCount == 1); // `c.a`'s destructor was called\n        assert(c.a.x == 10);        // `c.a.x` is back to its inital state, `10`\n\n        // check C++ classes work too!\n        extern (C++) class CPP\n        {\n            struct Agg\n            {\n                __gshared int dtorCount;\n\n                int x = 10;\n                ~this() { dtorCount++; }\n            }\n\n            __gshared int dtorCount;\n\n            string s = \"S\";\n            Agg a;\n            ~this() { dtorCount++; }\n        }\n\n        CPP cpp = new CPP();\n        assert(cpp.dtorCount == 0);   // destructor not yet called\n        assert(cpp.s == \"S\");         // initial state `cpp.s` is `\"S\"`\n        assert(cpp.a.dtorCount == 0); // destructor not yet called\n        assert(cpp.a.x == 10);        // initial state `cpp.a.x` is `10`\n        cpp.s = \"T\";\n        cpp.a.x = 30;\n        assert(cpp.s == \"T\");         // `cpp.s` is `\"T\"`\n        destroy(cpp);\n        assert(cpp.dtorCount == 1);   // `cpp`'s destructor was called\n        assert(cpp.s == \"S\");         // `cpp.s` is back to its inital state, `\"S\"`\n        assert(cpp.a.dtorCount == 1); // `cpp.a`'s destructor was called\n        assert(cpp.a.x == 10);        // `cpp.a.x` is back to its inital state, `10`\n    }\n\n    /// Value type demonstration\n    unittest\n    {\n        int i;\n        assert(i == 0);           // `i`'s initial state is `0`\n        i = 1;\n        assert(i == 1);           // `i` changed to `1`\n        destroy(i);\n        assert(i == 0);           // `i` is back to its initial state `0`\n    }\n\n    unittest\n    {\n        interface I { }\n        {\n            class A: I { string s = \"A\"; this() {} }\n            auto a = new A, b = new A;\n            a.s = b.s = \"asd\";\n            destroy(a);\n            assert(a.s == \"A\");\n\n            I i = b;\n            destroy(i);\n            assert(b.s == \"A\");\n        }\n        {\n            static bool destroyed = false;\n            class B: I\n            {\n                string s = \"B\";\n                this() {}\n                ~this()\n                {\n                    destroyed = true;\n                }\n            }\n            auto a = new B, b = new B;\n            a.s = b.s = \"asd\";\n            destroy(a);\n            assert(destroyed);\n            assert(a.s == \"B\");\n\n            destroyed = false;\n            I i = b;\n            destroy(i);\n            assert(destroyed);\n            assert(b.s == \"B\");\n        }\n        // this test is invalid now that the default ctor is not run after clearing\n        version (none)\n        {\n            class C\n            {\n                string s;\n                this()\n                {\n                    s = \"C\";\n                }\n            }\n            auto a = new C;\n            a.s = \"asd\";\n            destroy(a);\n            assert(a.s == \"C\");\n        }\n    }\n\n    nothrow @safe @nogc unittest\n    {\n        {\n            struct A { string s = \"A\";  }\n            A a;\n            a.s = \"asd\";\n            destroy(a);\n            assert(a.s == \"A\");\n        }\n        {\n            static int destroyed = 0;\n            struct C\n            {\n                string s = \"C\";\n                ~this() nothrow @safe @nogc\n                {\n                    destroyed ++;\n                }\n            }\n\n            struct B\n            {\n                C c;\n                string s = \"B\";\n                ~this() nothrow @safe @nogc\n                {\n                    destroyed ++;\n                }\n            }\n            B a;\n            a.s = \"asd\";\n            a.c.s = \"jkl\";\n            destroy(a);\n            assert(destroyed == 2);\n            assert(a.s == \"B\");\n            assert(a.c.s == \"C\" );\n        }\n    }\n\n    /// ditto\n    void destroy(T : U[n], U, size_t n)(ref T obj) if (!is(T == struct))\n    {\n        foreach_reverse (ref e; obj[])\n            destroy(e);\n    }\n\n    unittest\n    {\n        int[2] a;\n        a[0] = 1;\n        a[1] = 2;\n        destroy(a);\n        assert(a == [ 0, 0 ]);\n    }\n\n    unittest\n    {\n        static struct vec2f {\n            float[2] values;\n            alias values this;\n        }\n\n        vec2f v;\n        destroy!vec2f(v);\n    }\n\n    unittest\n    {\n        // Bugzilla 15009\n        static string op;\n        static struct S\n        {\n            int x;\n            this(int x) { op ~= \"C\" ~ cast(char)('0'+x); this.x = x; }\n            this(this)  { op ~= \"P\" ~ cast(char)('0'+x); }\n            ~this()     { op ~= \"D\" ~ cast(char)('0'+x); }\n        }\n\n        {\n            S[2] a1 = [S(1), S(2)];\n            op = \"\";\n        }\n        assert(op == \"D2D1\");   // built-in scope destruction\n        {\n            S[2] a1 = [S(1), S(2)];\n            op = \"\";\n            destroy(a1);\n            assert(op == \"D2D1\");   // consistent with built-in behavior\n        }\n\n        {\n            S[2][2] a2 = [[S(1), S(2)], [S(3), S(4)]];\n            op = \"\";\n        }\n        assert(op == \"D4D3D2D1\");\n        {\n            S[2][2] a2 = [[S(1), S(2)], [S(3), S(4)]];\n            op = \"\";\n            destroy(a2);\n            assert(op == \"D4D3D2D1\", op);\n        }\n    }\n\n    /// ditto\n    void destroy(T)(ref T obj)\n        if (!is(T == struct) && !is(T == interface) && !is(T == class) && !_isStaticArray!T)\n    {\n        obj = T.init;\n    }\n\n    template _isStaticArray(T : U[N], U, size_t N)\n    {\n        enum bool _isStaticArray = true;\n    }\n\n    template _isStaticArray(T)\n    {\n        enum bool _isStaticArray = false;\n    }\n\n    unittest\n    {\n        {\n            int a = 42;\n            destroy(a);\n            assert(a == 0);\n        }\n        {\n            float a = 42;\n            destroy(a);\n            assert(isnan(a));\n        }\n    }\n\n\nprivate\n{\n    extern (C) Object _d_newclass(const TypeInfo_Class ci);\n    extern (C) void rt_finalize(void *data, bool det=true);\n}\n\npublic @trusted @nogc nothrow pure extern (C) void _d_delThrowable(scope Throwable);\n\n/**\n * All D class objects inherit from Object.\n */\nclass Object\n{\n    /**\n     * Convert Object to a human readable string.\n     */\n    string toString()\n    {\n        return typeid(this).name;\n    }\n\n    /**\n     * Compute hash function for Object.\n     */\n    size_t toHash() @trusted nothrow\n    {\n        // BUG: this prevents a compacting GC from working, needs to be fixed\n        size_t addr = cast(size_t) cast(void*) this;\n        // The bottom log2((void*).alignof) bits of the address will always\n        // be 0. Moreover it is likely that each Object is allocated with a\n        // separate call to malloc. The alignment of malloc differs from\n        // platform to platform, but rather than having special cases for\n        // each platform it is safe to use a shift of 4. To minimize\n        // collisions in the low bits it is more important for the shift to\n        // not be too small than for the shift to not be too big.\n        return addr ^ (addr >>> 4);\n    }\n\n    /**\n     * Compare with another Object obj.\n     * Returns:\n     *  $(TABLE\n     *  $(TR $(TD this &lt; obj) $(TD &lt; 0))\n     *  $(TR $(TD this == obj) $(TD 0))\n     *  $(TR $(TD this &gt; obj) $(TD &gt; 0))\n     *  )\n     */\n    int opCmp(Object o)\n    {\n        // BUG: this prevents a compacting GC from working, needs to be fixed\n        //return cast(int)cast(void*)this - cast(int)cast(void*)o;\n\n        throw new Exception(\"need opCmp for class \" ~ typeid(this).name);\n        //return this !is o;\n    }\n\n    /**\n     * Test whether $(D this) is equal to $(D o).\n     * The default implementation only compares by identity (using the $(D is) operator).\n     * Generally, overrides for $(D opEquals) should attempt to compare objects by their contents.\n     */\n    bool opEquals(Object o)\n    {\n        return this is o;\n    }\n\n    interface Monitor\n    {\n        void lock();\n        void unlock();\n    }\n\n    /**\n     * Create instance of class specified by the fully qualified name\n     * classname.\n     * The class must either have no constructors or have\n     * a default constructor.\n     * Returns:\n     *   null if failed\n     * Example:\n     * ---\n     * module foo.bar;\n     *\n     * class C\n     * {\n     *     this() { x = 10; }\n     *     int x;\n     * }\n     *\n     * void main()\n     * {\n     *     auto c = cast(C)Object.factory(\"foo.bar.C\");\n     *     assert(c !is null && c.x == 10);\n     * }\n     * ---\n     */\n    static Object factory(string classname)\n    {\n        auto ci = TypeInfo_Class.find(classname);\n        if (ci)\n        {\n            return ci.create();\n        }\n        return null;\n    }\n}\n\nbool opEquals(Object lhs, Object rhs)\n{\n    // If aliased to the same object or both null => equal\n    if (lhs is rhs) return true;\n\n    // If either is null => non-equal\n    if (lhs is null || rhs is null) return false;\n\n    // If same exact type => one call to method opEquals\n    if (typeid(lhs) is typeid(rhs) ||\n        !__ctfe && typeid(lhs).opEquals(typeid(rhs)))\n            /* CTFE doesn't like typeid much. 'is' works, but opEquals doesn't\n            (issue 7147). But CTFE also guarantees that equal TypeInfos are\n            always identical. So, no opEquals needed during CTFE. */\n    {\n        return lhs.opEquals(rhs);\n    }\n\n    // General case => symmetric calls to method opEquals\n    return lhs.opEquals(rhs) && rhs.opEquals(lhs);\n}\n\n/************************\n* Returns true if lhs and rhs are equal.\n*/\nbool opEquals(const Object lhs, const Object rhs)\n{\n    // A hack for the moment.\n    return opEquals(cast()lhs, cast()rhs);\n}\n\nprivate extern(C) void _d_setSameMutex(shared Object ownee, shared Object owner) nothrow;\n\nvoid setSameMutex(shared Object ownee, shared Object owner)\n{\n    _d_setSameMutex(ownee, owner);\n}\n\n/**\n * Information about an interface.\n * When an object is accessed via an interface, an Interface* appears as the\n * first entry in its vtbl.\n */\nstruct Interface\n{\n    TypeInfo_Class   classinfo;  /// .classinfo for this interface (not for containing class)\n    void*[]     vtbl;\n    size_t      offset;     /// offset to Interface 'this' from Object 'this'\n}\n\n/**\n * Array of pairs giving the offset and type information for each\n * member in an aggregate.\n */\nstruct OffsetTypeInfo\n{\n    size_t   offset;    /// Offset of member from start of object\n    TypeInfo ti;        /// TypeInfo for this member\n}\n\n/**\n * Runtime type information about a type.\n * Can be retrieved for any type using a\n * $(GLINK2 expression,TypeidExpression, TypeidExpression).\n */\nclass TypeInfo\n{\n    override string toString() const pure @safe nothrow\n    {\n        return typeid(this).name;\n    }\n\n    override size_t toHash() @trusted const nothrow\n    {\n        return hashOf(this.toString());\n    }\n\n    override int opCmp(Object o)\n    {\n        import core.internal.string : dstrcmp;\n\n        if (this is o)\n            return 0;\n        TypeInfo ti = cast(TypeInfo)o;\n        if (ti is null)\n            return 1;\n        return dstrcmp(this.toString(), ti.toString());\n    }\n\n    override bool opEquals(Object o)\n    {\n        /* TypeInfo instances are singletons, but duplicates can exist\n         * across DLL's. Therefore, comparing for a name match is\n         * sufficient.\n         */\n        if (this is o)\n            return true;\n        auto ti = cast(const TypeInfo)o;\n        return ti && this.toString() == ti.toString();\n    }\n\n    /**\n     * Computes a hash of the instance of a type.\n     * Params:\n     *    p = pointer to start of instance of the type\n     * Returns:\n     *    the hash\n     * Bugs:\n     *    fix https://issues.dlang.org/show_bug.cgi?id=12516 e.g. by changing this to a truly safe interface.\n     */\n    size_t getHash(scope const void* p) @trusted nothrow const\n    {\n        return hashOf(p);\n    }\n\n    /// Compares two instances for equality.\n    bool equals(in void* p1, in void* p2) const { return p1 == p2; }\n\n    /// Compares two instances for &lt;, ==, or &gt;.\n    int compare(in void* p1, in void* p2) const { return _xopCmp(p1, p2); }\n\n    /// Returns size of the type.\n    @property size_t tsize() nothrow pure const @safe @nogc { return 0; }\n\n    /// Swaps two instances of the type.\n    void swap(void* p1, void* p2) const\n    {\n        immutable size_t n = tsize;\n        for (size_t i = 0; i < n; i++)\n        {\n            byte t = (cast(byte *)p1)[i];\n            (cast(byte*)p1)[i] = (cast(byte*)p2)[i];\n            (cast(byte*)p2)[i] = t;\n        }\n    }\n\n    /** Get TypeInfo for 'next' type, as defined by what kind of type this is,\n    null if none. */\n    @property inout(TypeInfo) next() nothrow pure inout @nogc { return null; }\n\n    /**\n     * Return default initializer.  If the type should be initialized to all\n     * zeros, an array with a null ptr and a length equal to the type size will\n     * be returned. For static arrays, this returns the default initializer for\n     * a single element of the array, use `tsize` to get the correct size.\n     */\n    abstract const(void)[] initializer() nothrow pure const @safe @nogc;\n\n    /** Get flags for type: 1 means GC should scan for pointers,\n    2 means arg of this type is passed in XMM register */\n    @property uint flags() nothrow pure const @safe @nogc { return 0; }\n\n    /// Get type information on the contents of the type; null if not available\n    const(OffsetTypeInfo)[] offTi() const { return null; }\n    /// Run the destructor on the object and all its sub-objects\n    void destroy(void* p) const {}\n    /// Run the postblit on the object and all its sub-objects\n    void postblit(void* p) const {}\n\n\n    /// Return alignment of type\n    @property size_t talign() nothrow pure const @safe @nogc { return tsize; }\n\n    /** Return internal info on arguments fitting into 8byte.\n     * See X86-64 ABI 3.2.3\n     */\n    version (X86_64) int argTypes(out TypeInfo arg1, out TypeInfo arg2) @safe nothrow\n    {\n        arg1 = this;\n        return 0;\n    }\n\n    /** Return info used by the garbage collector to do precise collection.\n     */\n    @property immutable(void)* rtInfo() nothrow pure const @safe @nogc { return null; }\n}\n\nclass TypeInfo_Enum : TypeInfo\n{\n    override string toString() const { return name; }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n        auto c = cast(const TypeInfo_Enum)o;\n        return c && this.name == c.name &&\n                    this.base == c.base;\n    }\n\n    override size_t getHash(scope const void* p) const { return base.getHash(p); }\n    override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }\n    override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }\n    override @property size_t tsize() nothrow pure const { return base.tsize; }\n    override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }\n\n    override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }\n    override @property uint flags() nothrow pure const { return base.flags; }\n\n    override const(void)[] initializer() const\n    {\n        return m_init.length ? m_init : base.initializer();\n    }\n\n    override @property size_t talign() nothrow pure const { return base.talign; }\n\n    version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n    {\n        return base.argTypes(arg1, arg2);\n    }\n\n    override @property immutable(void)* rtInfo() const { return base.rtInfo; }\n\n    TypeInfo base;\n    string   name;\n    void[]   m_init;\n}\n\nunittest // issue 12233\n{\n    static assert(is(typeof(TypeInfo.init) == TypeInfo));\n    assert(TypeInfo.init is null);\n}\n\n\n// Please make sure to keep this in sync with TypeInfo_P (src/rt/typeinfo/ti_ptr.d)\nclass TypeInfo_Pointer : TypeInfo\n{\n    override string toString() const { return m_next.toString() ~ \"*\"; }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n        auto c = cast(const TypeInfo_Pointer)o;\n        return c && this.m_next == c.m_next;\n    }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        size_t addr = cast(size_t) *cast(const void**)p;\n        return addr ^ (addr >> 4);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        return *cast(void**)p1 == *cast(void**)p2;\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        if (*cast(void**)p1 < *cast(void**)p2)\n            return -1;\n        else if (*cast(void**)p1 > *cast(void**)p2)\n            return 1;\n        else\n            return 0;\n    }\n\n    override @property size_t tsize() nothrow pure const\n    {\n        return (void*).sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. (void*).sizeof];\n    }\n\n    override void swap(void* p1, void* p2) const\n    {\n        void* tmp = *cast(void**)p1;\n        *cast(void**)p1 = *cast(void**)p2;\n        *cast(void**)p2 = tmp;\n    }\n\n    override @property inout(TypeInfo) next() nothrow pure inout { return m_next; }\n    override @property uint flags() nothrow pure const { return 1; }\n\n    TypeInfo m_next;\n}\n\nclass TypeInfo_Array : TypeInfo\n{\n    override string toString() const { return value.toString() ~ \"[]\"; }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n        auto c = cast(const TypeInfo_Array)o;\n        return c && this.value == c.value;\n    }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        void[] a = *cast(void[]*)p;\n        return getArrayHash(value, a.ptr, a.length);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        void[] a1 = *cast(void[]*)p1;\n        void[] a2 = *cast(void[]*)p2;\n        if (a1.length != a2.length)\n            return false;\n        size_t sz = value.tsize;\n        for (size_t i = 0; i < a1.length; i++)\n        {\n            if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz))\n                return false;\n        }\n        return true;\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        void[] a1 = *cast(void[]*)p1;\n        void[] a2 = *cast(void[]*)p2;\n        size_t sz = value.tsize;\n        size_t len = a1.length;\n\n        if (a2.length < len)\n            len = a2.length;\n        for (size_t u = 0; u < len; u++)\n        {\n            immutable int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz);\n            if (result)\n                return result;\n        }\n        return cast(int)a1.length - cast(int)a2.length;\n    }\n\n    override @property size_t tsize() nothrow pure const\n    {\n        return (void[]).sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. (void[]).sizeof];\n    }\n\n    override void swap(void* p1, void* p2) const\n    {\n        void[] tmp = *cast(void[]*)p1;\n        *cast(void[]*)p1 = *cast(void[]*)p2;\n        *cast(void[]*)p2 = tmp;\n    }\n\n    TypeInfo value;\n\n    override @property inout(TypeInfo) next() nothrow pure inout\n    {\n        return value;\n    }\n\n    override @property uint flags() nothrow pure const { return 1; }\n\n    override @property size_t talign() nothrow pure const\n    {\n        return (void[]).alignof;\n    }\n\n    version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n    {\n        arg1 = typeid(size_t);\n        arg2 = typeid(void*);\n        return 0;\n    }\n}\n\nclass TypeInfo_StaticArray : TypeInfo\n{\n    override string toString() const\n    {\n        import core.internal.string : unsignedToTempString;\n\n        char[20] tmpBuff = void;\n        return value.toString() ~ \"[\" ~ unsignedToTempString(len, tmpBuff, 10) ~ \"]\";\n    }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n        auto c = cast(const TypeInfo_StaticArray)o;\n        return c && this.len == c.len &&\n                    this.value == c.value;\n    }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        return getArrayHash(value, p, len);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        size_t sz = value.tsize;\n\n        for (size_t u = 0; u < len; u++)\n        {\n            if (!value.equals(p1 + u * sz, p2 + u * sz))\n                return false;\n        }\n        return true;\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        size_t sz = value.tsize;\n\n        for (size_t u = 0; u < len; u++)\n        {\n            immutable int result = value.compare(p1 + u * sz, p2 + u * sz);\n            if (result)\n                return result;\n        }\n        return 0;\n    }\n\n    override @property size_t tsize() nothrow pure const\n    {\n        return len * value.tsize;\n    }\n\n    override void swap(void* p1, void* p2) const\n    {\n        import core.memory;\n        import core.stdc.string : memcpy;\n\n        void* tmp;\n        size_t sz = value.tsize;\n        ubyte[16] buffer;\n        void* pbuffer;\n\n        if (sz < buffer.sizeof)\n            tmp = buffer.ptr;\n        else\n            tmp = pbuffer = (new void[sz]).ptr;\n\n        for (size_t u = 0; u < len; u += sz)\n        {\n            size_t o = u * sz;\n            memcpy(tmp, p1 + o, sz);\n            memcpy(p1 + o, p2 + o, sz);\n            memcpy(p2 + o, tmp, sz);\n        }\n        if (pbuffer)\n            GC.free(pbuffer);\n    }\n\n    override const(void)[] initializer() nothrow pure const\n    {\n        return value.initializer();\n    }\n\n    override @property inout(TypeInfo) next() nothrow pure inout { return value; }\n    override @property uint flags() nothrow pure const { return value.flags; }\n\n    override void destroy(void* p) const\n    {\n        immutable sz = value.tsize;\n        p += sz * len;\n        foreach (i; 0 .. len)\n        {\n            p -= sz;\n            value.destroy(p);\n        }\n    }\n\n    override void postblit(void* p) const\n    {\n        immutable sz = value.tsize;\n        foreach (i; 0 .. len)\n        {\n            value.postblit(p);\n            p += sz;\n        }\n    }\n\n    TypeInfo value;\n    size_t   len;\n\n    override @property size_t talign() nothrow pure const\n    {\n        return value.talign;\n    }\n\n    version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n    {\n        arg1 = typeid(void*);\n        return 0;\n    }\n}\n\nclass TypeInfo_AssociativeArray : TypeInfo\n{\n    override string toString() const\n    {\n        return value.toString() ~ \"[\" ~ key.toString() ~ \"]\";\n    }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n        auto c = cast(const TypeInfo_AssociativeArray)o;\n        return c && this.key == c.key &&\n                    this.value == c.value;\n    }\n\n    override bool equals(in void* p1, in void* p2) @trusted const\n    {\n        return !!_aaEqual(this, *cast(const void**) p1, *cast(const void**) p2);\n    }\n\n    override hash_t getHash(scope const void* p) nothrow @trusted const\n    {\n        return _aaGetHash(cast(void*)p, this);\n    }\n\n    // BUG: need to add the rest of the functions\n\n    override @property size_t tsize() nothrow pure const\n    {\n        return (char[int]).sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. (char[int]).sizeof];\n    }\n\n    override @property inout(TypeInfo) next() nothrow pure inout { return value; }\n    override @property uint flags() nothrow pure const { return 1; }\n\n    TypeInfo value;\n    TypeInfo key;\n\n    override @property size_t talign() nothrow pure const\n    {\n        return (char[int]).alignof;\n    }\n\n    version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n    {\n        arg1 = typeid(void*);\n        return 0;\n    }\n}\n\nclass TypeInfo_Vector : TypeInfo\n{\n    override string toString() const { return \"__vector(\" ~ base.toString() ~ \")\"; }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n        auto c = cast(const TypeInfo_Vector)o;\n        return c && this.base == c.base;\n    }\n\n    override size_t getHash(scope const void* p) const { return base.getHash(p); }\n    override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }\n    override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }\n    override @property size_t tsize() nothrow pure const { return base.tsize; }\n    override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }\n\n    override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }\n    override @property uint flags() nothrow pure const { return base.flags; }\n\n    override const(void)[] initializer() nothrow pure const\n    {\n        return base.initializer();\n    }\n\n    override @property size_t talign() nothrow pure const { return 16; }\n\n    version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n    {\n        return base.argTypes(arg1, arg2);\n    }\n\n    TypeInfo base;\n}\n\nclass TypeInfo_Function : TypeInfo\n{\n    override string toString() const\n    {\n        import core.demangle : demangleType;\n\n        alias SafeDemangleFunctionType = char[] function (const(char)[] buf, char[] dst = null) @safe nothrow pure;\n        SafeDemangleFunctionType demangle = ( () @trusted => cast(SafeDemangleFunctionType)(&demangleType) ) ();\n\n        return (() @trusted => cast(string)(demangle(deco))) ();\n    }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n        auto c = cast(const TypeInfo_Function)o;\n        return c && this.deco == c.deco;\n    }\n\n    // BUG: need to add the rest of the functions\n\n    override @property size_t tsize() nothrow pure const\n    {\n        return 0;       // no size for functions\n    }\n\n    override const(void)[] initializer() const @safe\n    {\n        return null;\n    }\n\n    TypeInfo next;\n\n    /**\n    * Mangled function type string\n    */\n    string deco;\n}\n\nunittest\n{\n    abstract class C\n    {\n       void func();\n       void func(int a);\n       int func(int a, int b);\n    }\n\n    alias functionTypes = typeof(__traits(getVirtualFunctions, C, \"func\"));\n    assert(typeid(functionTypes[0]).toString() == \"void function()\");\n    assert(typeid(functionTypes[1]).toString() == \"void function(int)\");\n    assert(typeid(functionTypes[2]).toString() == \"int function(int, int)\");\n}\n\nclass TypeInfo_Delegate : TypeInfo\n{\n    override string toString() const\n    {\n        return cast(string)(next.toString() ~ \" delegate()\");\n    }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n        auto c = cast(const TypeInfo_Delegate)o;\n        return c && this.deco == c.deco;\n    }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        return hashOf(*cast(void delegate()*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        auto dg1 = *cast(void delegate()*)p1;\n        auto dg2 = *cast(void delegate()*)p2;\n        return dg1 == dg2;\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        auto dg1 = *cast(void delegate()*)p1;\n        auto dg2 = *cast(void delegate()*)p2;\n\n        if (dg1 < dg2)\n            return -1;\n        else if (dg1 > dg2)\n            return 1;\n        else\n            return 0;\n    }\n\n    override @property size_t tsize() nothrow pure const\n    {\n        alias dg = int delegate();\n        return dg.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. (int delegate()).sizeof];\n    }\n\n    override @property uint flags() nothrow pure const { return 1; }\n\n    TypeInfo next;\n    string deco;\n\n    override @property size_t talign() nothrow pure const\n    {\n        alias dg = int delegate();\n        return dg.alignof;\n    }\n\n    version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n    {\n        arg1 = typeid(void*);\n        arg2 = typeid(void*);\n        return 0;\n    }\n}\n\n/**\n * Runtime type information about a class.\n * Can be retrieved from an object instance by using the\n * $(DDSUBLINK spec/property,classinfo, .classinfo) property.\n */\nclass TypeInfo_Class : TypeInfo\n{\n    override string toString() const { return info.name; }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n        auto c = cast(const TypeInfo_Class)o;\n        return c && this.info.name == c.info.name;\n    }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        auto o = *cast(Object*)p;\n        return o ? o.toHash() : 0;\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        Object o1 = *cast(Object*)p1;\n        Object o2 = *cast(Object*)p2;\n\n        return (o1 is o2) || (o1 && o1.opEquals(o2));\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        Object o1 = *cast(Object*)p1;\n        Object o2 = *cast(Object*)p2;\n        int c = 0;\n\n        // Regard null references as always being \"less than\"\n        if (o1 !is o2)\n        {\n            if (o1)\n            {\n                if (!o2)\n                    c = 1;\n                else\n                    c = o1.opCmp(o2);\n            }\n            else\n                c = -1;\n        }\n        return c;\n    }\n\n    override @property size_t tsize() nothrow pure const\n    {\n        return Object.sizeof;\n    }\n\n    override const(void)[] initializer() nothrow pure const @safe\n    {\n        return m_init;\n    }\n\n    override @property uint flags() nothrow pure const { return 1; }\n\n    override @property const(OffsetTypeInfo)[] offTi() nothrow pure const\n    {\n        return m_offTi;\n    }\n\n    @property auto info() @safe nothrow pure const { return this; }\n    @property auto typeinfo() @safe nothrow pure const { return this; }\n\n    byte[]      m_init;         /** class static initializer\n                                 * (init.length gives size in bytes of class)\n                                 */\n    string      name;           /// class name\n    void*[]     vtbl;           /// virtual function pointer table\n    Interface[] interfaces;     /// interfaces this class implements\n    TypeInfo_Class   base;           /// base class\n    void*       destructor;\n    void function(Object) classInvariant;\n    enum ClassFlags : uint\n    {\n        isCOMclass = 0x1,\n        noPointers = 0x2,\n        hasOffTi = 0x4,\n        hasCtor = 0x8,\n        hasGetMembers = 0x10,\n        hasTypeInfo = 0x20,\n        isAbstract = 0x40,\n        isCPPclass = 0x80,\n        hasDtor = 0x100,\n    }\n    ClassFlags m_flags;\n    void*       deallocator;\n    OffsetTypeInfo[] m_offTi;\n    void function(Object) defaultConstructor;   // default Constructor\n\n    immutable(void)* m_RTInfo;        // data for precise GC\n    override @property immutable(void)* rtInfo() const { return m_RTInfo; }\n\n    /**\n     * Search all modules for TypeInfo_Class corresponding to classname.\n     * Returns: null if not found\n     */\n    static const(TypeInfo_Class) find(in char[] classname)\n    {\n        foreach (m; ModuleInfo)\n        {\n            if (m)\n            {\n                //writefln(\"module %s, %d\", m.name, m.localClasses.length);\n                foreach (c; m.localClasses)\n                {\n                    if (c is null)\n                        continue;\n                    //writefln(\"\\tclass %s\", c.name);\n                    if (c.name == classname)\n                        return c;\n                }\n            }\n        }\n        return null;\n    }\n\n    /**\n     * Create instance of Object represented by 'this'.\n     */\n    Object create() const\n    {\n        if (m_flags & 8 && !defaultConstructor)\n            return null;\n        if (m_flags & 64) // abstract\n            return null;\n        Object o = _d_newclass(this);\n        if (m_flags & 8 && defaultConstructor)\n        {\n            defaultConstructor(o);\n        }\n        return o;\n    }\n}\n\nalias ClassInfo = TypeInfo_Class;\n\nunittest\n{\n    // Bugzilla 14401\n    static class X\n    {\n        int a;\n    }\n\n    assert(typeid(X).initializer is typeid(X).m_init);\n    assert(typeid(X).initializer.length == typeid(const(X)).initializer.length);\n    assert(typeid(X).initializer.length == typeid(shared(X)).initializer.length);\n    assert(typeid(X).initializer.length == typeid(immutable(X)).initializer.length);\n}\n\nclass TypeInfo_Interface : TypeInfo\n{\n    override string toString() const { return info.name; }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n        auto c = cast(const TypeInfo_Interface)o;\n        return c && this.info.name == typeid(c).name;\n    }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        if (!*cast(void**)p)\n        {\n            return 0;\n        }\n        Interface* pi = **cast(Interface ***)*cast(void**)p;\n        Object o = cast(Object)(*cast(void**)p - pi.offset);\n        assert(o);\n        return o.toHash();\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        Interface* pi = **cast(Interface ***)*cast(void**)p1;\n        Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);\n        pi = **cast(Interface ***)*cast(void**)p2;\n        Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);\n\n        return o1 == o2 || (o1 && o1.opCmp(o2) == 0);\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        Interface* pi = **cast(Interface ***)*cast(void**)p1;\n        Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);\n        pi = **cast(Interface ***)*cast(void**)p2;\n        Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);\n        int c = 0;\n\n        // Regard null references as always being \"less than\"\n        if (o1 != o2)\n        {\n            if (o1)\n            {\n                if (!o2)\n                    c = 1;\n                else\n                    c = o1.opCmp(o2);\n            }\n            else\n                c = -1;\n        }\n        return c;\n    }\n\n    override @property size_t tsize() nothrow pure const\n    {\n        return Object.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. Object.sizeof];\n    }\n\n    override @property uint flags() nothrow pure const { return 1; }\n\n    TypeInfo_Class info;\n}\n\nclass TypeInfo_Struct : TypeInfo\n{\n    override string toString() const { return name; }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n        auto s = cast(const TypeInfo_Struct)o;\n        return s && this.name == s.name &&\n                    this.initializer().length == s.initializer().length;\n    }\n\n    override size_t getHash(scope const void* p) @trusted pure nothrow const\n    {\n        assert(p);\n        if (xtoHash)\n        {\n            return (*xtoHash)(p);\n        }\n        else\n        {\n            return hashOf(p[0 .. initializer().length]);\n        }\n    }\n\n    override bool equals(in void* p1, in void* p2) @trusted pure nothrow const\n    {\n        import core.stdc.string : memcmp;\n\n        if (!p1 || !p2)\n            return false;\n        else if (xopEquals)\n        {\n            version (GNU)\n            {   // BUG: GDC and DMD use different calling conventions\n                return (*xopEquals)(p2, p1);\n            }\n            else\n                return (*xopEquals)(p1, p2);\n        }\n        else if (p1 == p2)\n            return true;\n        else\n            // BUG: relies on the GC not moving objects\n            return memcmp(p1, p2, initializer().length) == 0;\n    }\n\n    override int compare(in void* p1, in void* p2) @trusted pure nothrow const\n    {\n        import core.stdc.string : memcmp;\n\n        // Regard null references as always being \"less than\"\n        if (p1 != p2)\n        {\n            if (p1)\n            {\n                if (!p2)\n                    return true;\n                else if (xopCmp)\n                {\n                    version (GNU)\n                    {   // BUG: GDC and DMD use different calling conventions\n                        return (*xopCmp)(p1, p2);\n                    }\n                    else\n                        return (*xopCmp)(p2, p1);\n                }\n                else\n                    // BUG: relies on the GC not moving objects\n                    return memcmp(p1, p2, initializer().length);\n            }\n            else\n                return -1;\n        }\n        return 0;\n    }\n\n    override @property size_t tsize() nothrow pure const\n    {\n        return initializer().length;\n    }\n\n    override const(void)[] initializer() nothrow pure const @safe\n    {\n        return m_init;\n    }\n\n    override @property uint flags() nothrow pure const { return m_flags; }\n\n    override @property size_t talign() nothrow pure const { return m_align; }\n\n    final override void destroy(void* p) const\n    {\n        if (xdtor)\n        {\n            if (m_flags & StructFlags.isDynamicType)\n                (*xdtorti)(p, this);\n            else\n                (*xdtor)(p);\n        }\n    }\n\n    override void postblit(void* p) const\n    {\n        if (xpostblit)\n            (*xpostblit)(p);\n    }\n\n    string name;\n    void[] m_init;      // initializer; m_init.ptr == null if 0 initialize\n\n  @safe pure nothrow\n  {\n    size_t   function(in void*)           xtoHash;\n    bool     function(in void*, in void*) xopEquals;\n    int      function(in void*, in void*) xopCmp;\n    string   function(in void*)           xtoString;\n\n    enum StructFlags : uint\n    {\n        hasPointers = 0x1,\n        isDynamicType = 0x2, // built at runtime, needs type info in xdtor\n    }\n    StructFlags m_flags;\n  }\n    union\n    {\n        void function(void*)                xdtor;\n        void function(void*, const TypeInfo_Struct ti) xdtorti;\n    }\n    void function(void*)                    xpostblit;\n\n    uint m_align;\n\n    override @property immutable(void)* rtInfo() const { return m_RTInfo; }\n\n    version (X86_64)\n    {\n        override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n        {\n            arg1 = m_arg1;\n            arg2 = m_arg2;\n            return 0;\n        }\n        TypeInfo m_arg1;\n        TypeInfo m_arg2;\n    }\n    immutable(void)* m_RTInfo;                // data for precise GC\n}\n\nunittest\n{\n    struct S\n    {\n        bool opEquals(ref const S rhs) const\n        {\n            return false;\n        }\n    }\n    S s;\n    assert(!typeid(S).equals(&s, &s));\n}\n\nclass TypeInfo_Tuple : TypeInfo\n{\n    TypeInfo[] elements;\n\n    override string toString() const\n    {\n        string s = \"(\";\n        foreach (i, element; elements)\n        {\n            if (i)\n                s ~= ',';\n            s ~= element.toString();\n        }\n        s ~= \")\";\n        return s;\n    }\n\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n\n        auto t = cast(const TypeInfo_Tuple)o;\n        if (t && elements.length == t.elements.length)\n        {\n            for (size_t i = 0; i < elements.length; i++)\n            {\n                if (elements[i] != t.elements[i])\n                    return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    override size_t getHash(scope const void* p) const\n    {\n        assert(0);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        assert(0);\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        assert(0);\n    }\n\n    override @property size_t tsize() nothrow pure const\n    {\n        assert(0);\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        assert(0);\n    }\n\n    override void swap(void* p1, void* p2) const\n    {\n        assert(0);\n    }\n\n    override void destroy(void* p) const\n    {\n        assert(0);\n    }\n\n    override void postblit(void* p) const\n    {\n        assert(0);\n    }\n\n    override @property size_t talign() nothrow pure const\n    {\n        assert(0);\n    }\n\n    version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n    {\n        assert(0);\n    }\n}\n\nclass TypeInfo_Const : TypeInfo\n{\n    override string toString() const\n    {\n        return cast(string) (\"const(\" ~ base.toString() ~ \")\");\n    }\n\n    //override bool opEquals(Object o) { return base.opEquals(o); }\n    override bool opEquals(Object o)\n    {\n        if (this is o)\n            return true;\n\n        if (typeid(this) != typeid(o))\n            return false;\n\n        auto t = cast(TypeInfo_Const)o;\n        return base.opEquals(t.base);\n    }\n\n    override size_t getHash(scope const void *p) const { return base.getHash(p); }\n    override bool equals(in void *p1, in void *p2) const { return base.equals(p1, p2); }\n    override int compare(in void *p1, in void *p2) const { return base.compare(p1, p2); }\n    override @property size_t tsize() nothrow pure const { return base.tsize; }\n    override void swap(void *p1, void *p2) const { return base.swap(p1, p2); }\n\n    override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }\n    override @property uint flags() nothrow pure const { return base.flags; }\n\n    override const(void)[] initializer() nothrow pure const\n    {\n        return base.initializer();\n    }\n\n    override @property size_t talign() nothrow pure const { return base.talign; }\n\n    version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n    {\n        return base.argTypes(arg1, arg2);\n    }\n\n    TypeInfo base;\n}\n\nclass TypeInfo_Invariant : TypeInfo_Const\n{\n    override string toString() const\n    {\n        return cast(string) (\"immutable(\" ~ base.toString() ~ \")\");\n    }\n}\n\nclass TypeInfo_Shared : TypeInfo_Const\n{\n    override string toString() const\n    {\n        return cast(string) (\"shared(\" ~ base.toString() ~ \")\");\n    }\n}\n\nclass TypeInfo_Inout : TypeInfo_Const\n{\n    override string toString() const\n    {\n        return cast(string) (\"inout(\" ~ base.toString() ~ \")\");\n    }\n}\n\n// Contents of Moduleinfo._flags\nenum\n{\n    MIctorstart  = 0x1,   // we've started constructing it\n    MIctordone   = 0x2,   // finished construction\n    MIstandalone = 0x4,   // module ctor does not depend on other module\n                        // ctors being done first\n    MItlsctor    = 8,\n    MItlsdtor    = 0x10,\n    MIctor       = 0x20,\n    MIdtor       = 0x40,\n    MIxgetMembers = 0x80,\n    MIictor      = 0x100,\n    MIunitTest   = 0x200,\n    MIimportedModules = 0x400,\n    MIlocalClasses = 0x800,\n    MIname       = 0x1000,\n}\n\n/*****************************************\n * An instance of ModuleInfo is generated into the object file for each compiled module.\n *\n * It provides access to various aspects of the module.\n * It is not generated for betterC.\n */\nstruct ModuleInfo\n{\n    uint _flags; // MIxxxx\n    uint _index; // index into _moduleinfo_array[]\n\n    version (all)\n    {\n        deprecated(\"ModuleInfo cannot be copy-assigned because it is a variable-sized struct.\")\n        void opAssign(in ModuleInfo m) { _flags = m._flags; _index = m._index; }\n    }\n    else\n    {\n        @disable this();\n    }\n\nconst:\n    private void* addrOf(int flag) nothrow pure @nogc\n    in\n    {\n        assert(flag >= MItlsctor && flag <= MIname);\n        assert(!(flag & (flag - 1)) && !(flag & ~(flag - 1) << 1));\n    }\n    do\n    {\n        import core.stdc.string : strlen;\n\n        void* p = cast(void*)&this + ModuleInfo.sizeof;\n\n        if (flags & MItlsctor)\n        {\n            if (flag == MItlsctor) return p;\n            p += typeof(tlsctor).sizeof;\n        }\n        if (flags & MItlsdtor)\n        {\n            if (flag == MItlsdtor) return p;\n            p += typeof(tlsdtor).sizeof;\n        }\n        if (flags & MIctor)\n        {\n            if (flag == MIctor) return p;\n            p += typeof(ctor).sizeof;\n        }\n        if (flags & MIdtor)\n        {\n            if (flag == MIdtor) return p;\n            p += typeof(dtor).sizeof;\n        }\n        if (flags & MIxgetMembers)\n        {\n            if (flag == MIxgetMembers) return p;\n            p += typeof(xgetMembers).sizeof;\n        }\n        if (flags & MIictor)\n        {\n            if (flag == MIictor) return p;\n            p += typeof(ictor).sizeof;\n        }\n        if (flags & MIunitTest)\n        {\n            if (flag == MIunitTest) return p;\n            p += typeof(unitTest).sizeof;\n        }\n        if (flags & MIimportedModules)\n        {\n            if (flag == MIimportedModules) return p;\n            p += size_t.sizeof + *cast(size_t*)p * typeof(importedModules[0]).sizeof;\n        }\n        if (flags & MIlocalClasses)\n        {\n            if (flag == MIlocalClasses) return p;\n            p += size_t.sizeof + *cast(size_t*)p * typeof(localClasses[0]).sizeof;\n        }\n        if (true || flags & MIname) // always available for now\n        {\n            if (flag == MIname) return p;\n            p += strlen(cast(immutable char*)p);\n        }\n        assert(0);\n    }\n\n    @property uint index() nothrow pure @nogc { return _index; }\n\n    @property uint flags() nothrow pure @nogc { return _flags; }\n\n    /************************\n     * Returns:\n     *  module constructor for thread locals, `null` if there isn't one\n     */\n    @property void function() tlsctor() nothrow pure @nogc\n    {\n        return flags & MItlsctor ? *cast(typeof(return)*)addrOf(MItlsctor) : null;\n    }\n\n    /************************\n     * Returns:\n     *  module destructor for thread locals, `null` if there isn't one\n     */\n    @property void function() tlsdtor() nothrow pure @nogc\n    {\n        return flags & MItlsdtor ? *cast(typeof(return)*)addrOf(MItlsdtor) : null;\n    }\n\n    /*****************************\n     * Returns:\n     *  address of a module's `const(MemberInfo)[] getMembers(string)` function, `null` if there isn't one\n     */\n    @property void* xgetMembers() nothrow pure @nogc\n    {\n        return flags & MIxgetMembers ? *cast(typeof(return)*)addrOf(MIxgetMembers) : null;\n    }\n\n    /************************\n     * Returns:\n     *  module constructor, `null` if there isn't one\n     */\n    @property void function() ctor() nothrow pure @nogc\n    {\n        return flags & MIctor ? *cast(typeof(return)*)addrOf(MIctor) : null;\n    }\n\n    /************************\n     * Returns:\n     *  module destructor, `null` if there isn't one\n     */\n    @property void function() dtor() nothrow pure @nogc\n    {\n        return flags & MIdtor ? *cast(typeof(return)*)addrOf(MIdtor) : null;\n    }\n\n    /************************\n     * Returns:\n     *  module order independent constructor, `null` if there isn't one\n     */\n    @property void function() ictor() nothrow pure @nogc\n    {\n        return flags & MIictor ? *cast(typeof(return)*)addrOf(MIictor) : null;\n    }\n\n    /*************\n     * Returns:\n     *  address of function that runs the module's unittests, `null` if there isn't one\n     */\n    @property void function() unitTest() nothrow pure @nogc\n    {\n        return flags & MIunitTest ? *cast(typeof(return)*)addrOf(MIunitTest) : null;\n    }\n\n    /****************\n     * Returns:\n     *  array of pointers to the ModuleInfo's of modules imported by this one\n     */\n    @property immutable(ModuleInfo*)[] importedModules() nothrow pure @nogc\n    {\n        if (flags & MIimportedModules)\n        {\n            auto p = cast(size_t*)addrOf(MIimportedModules);\n            return (cast(immutable(ModuleInfo*)*)(p + 1))[0 .. *p];\n        }\n        return null;\n    }\n\n    /****************\n     * Returns:\n     *  array of TypeInfo_Class references for classes defined in this module\n     */\n    @property TypeInfo_Class[] localClasses() nothrow pure @nogc\n    {\n        if (flags & MIlocalClasses)\n        {\n            auto p = cast(size_t*)addrOf(MIlocalClasses);\n            return (cast(TypeInfo_Class*)(p + 1))[0 .. *p];\n        }\n        return null;\n    }\n\n    /********************\n     * Returns:\n     *  name of module, `null` if no name\n     */\n    @property string name() nothrow pure @nogc\n    {\n        if (true || flags & MIname) // always available for now\n        {\n            import core.stdc.string : strlen;\n\n            auto p = cast(immutable char*)addrOf(MIname);\n            return p[0 .. strlen(p)];\n        }\n        // return null;\n    }\n\n    static int opApply(scope int delegate(ModuleInfo*) dg)\n    {\n        import core.internal.traits : externDFunc;\n        alias moduleinfos_apply = externDFunc!(\"rt.minfo.moduleinfos_apply\",\n                                              int function(scope int delegate(immutable(ModuleInfo*))));\n        // Bugzilla 13084 - enforcing immutable ModuleInfo would break client code\n        return moduleinfos_apply(\n            (immutable(ModuleInfo*)m) => dg(cast(ModuleInfo*)m));\n    }\n}\n\nunittest\n{\n    ModuleInfo* m1;\n    foreach (m; ModuleInfo)\n    {\n        m1 = m;\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// Throwable\n///////////////////////////////////////////////////////////////////////////////\n\n\n/**\n * The base class of all thrown objects.\n *\n * All thrown objects must inherit from Throwable. Class $(D Exception), which\n * derives from this class, represents the category of thrown objects that are\n * safe to catch and handle. In principle, one should not catch Throwable\n * objects that are not derived from $(D Exception), as they represent\n * unrecoverable runtime errors. Certain runtime guarantees may fail to hold\n * when these errors are thrown, making it unsafe to continue execution after\n * catching them.\n */\nclass Throwable : Object\n{\n    interface TraceInfo\n    {\n        int opApply(scope int delegate(ref const(char[]))) const;\n        int opApply(scope int delegate(ref size_t, ref const(char[]))) const;\n        string toString() const;\n    }\n\n    string      msg;    /// A message describing the error.\n\n    /**\n     * The _file name of the D source code corresponding with\n     * where the error was thrown from.\n     */\n    string      file;\n    /**\n     * The _line number of the D source code corresponding with\n     * where the error was thrown from.\n     */\n    size_t      line;\n\n    /**\n     * The stack trace of where the error happened. This is an opaque object\n     * that can either be converted to $(D string), or iterated over with $(D\n     * foreach) to extract the items in the stack trace (as strings).\n     */\n    TraceInfo   info;\n\n    /**\n     * A reference to the _next error in the list. This is used when a new\n     * $(D Throwable) is thrown from inside a $(D catch) block. The originally\n     * caught $(D Exception) will be chained to the new $(D Throwable) via this\n     * field.\n     */\n    private Throwable   nextInChain;\n\n    private uint _refcount;     // 0 : allocated by GC\n                                // 1 : allocated by _d_newThrowable()\n                                // 2.. : reference count + 1\n\n    /**\n     * Returns:\n     * A reference to the _next error in the list. This is used when a new\n     * $(D Throwable) is thrown from inside a $(D catch) block. The originally\n     * caught $(D Exception) will be chained to the new $(D Throwable) via this\n     * field.\n     */\n    @property inout(Throwable) next() @safe inout return scope pure nothrow @nogc { return nextInChain; }\n\n    /**\n     * Replace next in chain with `tail`.\n     * Use `chainTogether` instead if at all possible.\n     */\n    @property void next(Throwable tail) @safe scope pure nothrow @nogc\n    {\n        if (tail && tail._refcount)\n            ++tail._refcount;           // increment the replacement *first*\n\n        auto n = nextInChain;\n        nextInChain = null;             // sever the tail before deleting it\n\n        if (n && n._refcount)\n            _d_delThrowable(n);         // now delete the old tail\n\n        nextInChain = tail;             // and set the new tail\n    }\n\n    /**\n     * Returns:\n     *  mutable reference to the reference count, which is\n     *  0 - allocated by the GC, 1 - allocated by _d_newThrowable(),\n     *  and >=2 which is the reference count + 1\n     */\n    @system @nogc final pure nothrow ref uint refcount() return scope { return _refcount; }\n\n    /**\n     * Loop over the chain of Throwables.\n     */\n    int opApply(scope int delegate(Throwable) dg)\n    {\n        int result = 0;\n        for (Throwable t = this; t; t = t.nextInChain)\n        {\n            result = dg(t);\n            if (result)\n                break;\n        }\n        return result;\n    }\n\n    /**\n     * Append `e2` to chain of exceptions that starts with `e1`.\n     * Params:\n     *  e1 = start of chain (can be null)\n     *  e2 = second part of chain (can be null)\n     * Returns:\n     *  Throwable that is at the start of the chain; null if both `e1` and `e2` are null\n     */\n    static @__future @system @nogc pure nothrow Throwable chainTogether(return scope Throwable e1, return scope Throwable e2)\n    {\n        if (e2 && e2.refcount())\n            ++e2.refcount();\n        if (!e1)\n            return e2;\n        if (!e2)\n            return e1;\n        for (auto e = e1; 1; e = e.nextInChain)\n        {\n            if (!e.nextInChain)\n            {\n                e.nextInChain = e2;\n                break;\n            }\n        }\n        return e1;\n    }\n\n    @nogc @safe pure nothrow this(string msg, Throwable nextInChain = null)\n    {\n        this.msg = msg;\n        this.nextInChain = nextInChain;\n        //this.info = _d_traceContext();\n    }\n\n    @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable nextInChain = null)\n    {\n        this(msg, nextInChain);\n        this.file = file;\n        this.line = line;\n        //this.info = _d_traceContext();\n    }\n\n    @trusted nothrow ~this()\n    {\n        if (nextInChain && nextInChain._refcount)\n            _d_delThrowable(nextInChain);\n    }\n\n    /**\n     * Overrides $(D Object.toString) and returns the error message.\n     * Internally this forwards to the $(D toString) overload that\n     * takes a $(D_PARAM sink) delegate.\n     */\n    override string toString()\n    {\n        string s;\n        toString((buf) { s ~= buf; });\n        return s;\n    }\n\n    /**\n     * The Throwable hierarchy uses a toString overload that takes a\n     * $(D_PARAM _sink) delegate to avoid GC allocations, which cannot be\n     * performed in certain error situations.  Override this $(D\n     * toString) method to customize the error message.\n     */\n    void toString(scope void delegate(in char[]) sink) const\n    {\n        import core.internal.string : unsignedToTempString;\n\n        char[20] tmpBuff = void;\n\n        sink(typeid(this).name);\n        sink(\"@\"); sink(file);\n        sink(\"(\"); sink(unsignedToTempString(line, tmpBuff, 10)); sink(\")\");\n\n        if (msg.length)\n        {\n            sink(\": \"); sink(msg);\n        }\n        if (info)\n        {\n            try\n            {\n                sink(\"\\n----------------\");\n                foreach (t; info)\n                {\n                    sink(\"\\n\"); sink(t);\n                }\n            }\n            catch (Throwable)\n            {\n                // ignore more errors\n            }\n        }\n    }\n\n    /**\n     * Get the message describing the error.\n     * Base behavior is to return the `Throwable.msg` field.\n     * Override to return some other error message.\n     *\n     * Returns:\n     *  Error message\n     */\n    @__future const(char)[] message() const\n    {\n        return this.msg;\n    }\n}\n\n\n/**\n * The base class of all errors that are safe to catch and handle.\n *\n * In principle, only thrown objects derived from this class are safe to catch\n * inside a $(D catch) block. Thrown objects not derived from Exception\n * represent runtime errors that should not be caught, as certain runtime\n * guarantees may not hold, making it unsafe to continue program execution.\n */\nclass Exception : Throwable\n{\n\n    /**\n     * Creates a new instance of Exception. The nextInChain parameter is used\n     * internally and should always be $(D null) when passed by user code.\n     * This constructor does not automatically throw the newly-created\n     * Exception; the $(D throw) statement should be used for that purpose.\n     */\n    @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null)\n    {\n        super(msg, file, line, nextInChain);\n    }\n\n    @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)\n    {\n        super(msg, file, line, nextInChain);\n    }\n}\n\nunittest\n{\n    {\n        auto e = new Exception(\"msg\");\n        assert(e.file == __FILE__);\n        assert(e.line == __LINE__ - 2);\n        assert(e.nextInChain is null);\n        assert(e.msg == \"msg\");\n    }\n\n    {\n        auto e = new Exception(\"msg\", new Exception(\"It's an Exception!\"), \"hello\", 42);\n        assert(e.file == \"hello\");\n        assert(e.line == 42);\n        assert(e.nextInChain !is null);\n        assert(e.msg == \"msg\");\n    }\n\n    {\n        auto e = new Exception(\"msg\", \"hello\", 42, new Exception(\"It's an Exception!\"));\n        assert(e.file == \"hello\");\n        assert(e.line == 42);\n        assert(e.nextInChain !is null);\n        assert(e.msg == \"msg\");\n    }\n\n    {\n        auto e = new Exception(\"message\");\n        assert(e.message == \"message\");\n    }\n}\n\n\n/**\n * The base class of all unrecoverable runtime errors.\n *\n * This represents the category of $(D Throwable) objects that are $(B not)\n * safe to catch and handle. In principle, one should not catch Error\n * objects, as they represent unrecoverable runtime errors.\n * Certain runtime guarantees may fail to hold when these errors are\n * thrown, making it unsafe to continue execution after catching them.\n */\nclass Error : Throwable\n{\n    /**\n     * Creates a new instance of Error. The nextInChain parameter is used\n     * internally and should always be $(D null) when passed by user code.\n     * This constructor does not automatically throw the newly-created\n     * Error; the $(D throw) statement should be used for that purpose.\n     */\n    @nogc @safe pure nothrow this(string msg, Throwable nextInChain = null)\n    {\n        super(msg, nextInChain);\n        bypassedException = null;\n    }\n\n    @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable nextInChain = null)\n    {\n        super(msg, file, line, nextInChain);\n        bypassedException = null;\n    }\n\n    /** The first $(D Exception) which was bypassed when this Error was thrown,\n    or $(D null) if no $(D Exception)s were pending. */\n    Throwable   bypassedException;\n}\n\nunittest\n{\n    {\n        auto e = new Error(\"msg\");\n        assert(e.file is null);\n        assert(e.line == 0);\n        assert(e.nextInChain is null);\n        assert(e.msg == \"msg\");\n        assert(e.bypassedException is null);\n    }\n\n    {\n        auto e = new Error(\"msg\", new Exception(\"It's an Exception!\"));\n        assert(e.file is null);\n        assert(e.line == 0);\n        assert(e.nextInChain !is null);\n        assert(e.msg == \"msg\");\n        assert(e.bypassedException is null);\n    }\n\n    {\n        auto e = new Error(\"msg\", \"hello\", 42, new Exception(\"It's an Exception!\"));\n        assert(e.file == \"hello\");\n        assert(e.line == 42);\n        assert(e.nextInChain !is null);\n        assert(e.msg == \"msg\");\n        assert(e.bypassedException is null);\n    }\n}\n\n/* Used in Exception Handling LSDA tables to 'wrap' C++ type info\n * so it can be distinguished from D TypeInfo\n */\nclass __cpp_type_info_ptr\n{\n    void* ptr;          // opaque pointer to C++ RTTI type info\n}\n\nextern (C)\n{\n    // from druntime/src/rt/aaA.d\n\n    // size_t _aaLen(in void* p) pure nothrow @nogc;\n    private void* _aaGetY(void** paa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey) pure nothrow;\n    private void* _aaGetX(void** paa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey, out bool found) pure nothrow;\n    // inout(void)* _aaGetRvalueX(inout void* p, in TypeInfo keyti, in size_t valuesize, in void* pkey);\n    inout(void)[] _aaValues(inout void* p, in size_t keysize, in size_t valuesize, const TypeInfo tiValArray) pure nothrow;\n    inout(void)[] _aaKeys(inout void* p, in size_t keysize, const TypeInfo tiKeyArray) pure nothrow;\n    void* _aaRehash(void** pp, in TypeInfo keyti) pure nothrow;\n    void _aaClear(void* p) pure nothrow;\n\n    // alias _dg_t = extern(D) int delegate(void*);\n    // int _aaApply(void* aa, size_t keysize, _dg_t dg);\n\n    // alias _dg2_t = extern(D) int delegate(void*, void*);\n    // int _aaApply2(void* aa, size_t keysize, _dg2_t dg);\n\n    private struct AARange { void* impl; size_t idx; }\n    AARange _aaRange(void* aa) pure nothrow @nogc @safe;\n    bool _aaRangeEmpty(AARange r) pure nothrow @nogc @safe;\n    void* _aaRangeFrontKey(AARange r) pure nothrow @nogc @safe;\n    void* _aaRangeFrontValue(AARange r) pure nothrow @nogc @safe;\n    void _aaRangePopFront(ref AARange r) pure nothrow @nogc @safe;\n\n    int _aaEqual(in TypeInfo tiRaw, in void* e1, in void* e2);\n    hash_t _aaGetHash(in void* aa, in TypeInfo tiRaw) nothrow;\n\n    /*\n        _d_assocarrayliteralTX marked as pure, because aaLiteral can be called from pure code.\n        This is a typesystem hole, however this is existing hole.\n        Early compiler didn't check purity of toHash or postblit functions, if key is a UDT thus\n        copiler allowed to create AA literal with keys, which have impure unsafe toHash methods.\n    */\n    void* _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, void[] keys, void[] values) pure;\n}\n\nvoid* aaLiteral(Key, Value)(Key[] keys, Value[] values) @trusted pure\n{\n    return _d_assocarrayliteralTX(typeid(Value[Key]), *cast(void[]*)&keys, *cast(void[]*)&values);\n}\n\nalias AssociativeArray(Key, Value) = Value[Key];\n\n/***********************************\n * Removes all remaining keys and values from an associative array.\n * Params:\n *      aa =     The associative array.\n */\nvoid clear(T : Value[Key], Value, Key)(T aa)\n{\n    _aaClear(*cast(void **) &aa);\n}\n\n/* ditto */\nvoid clear(T : Value[Key], Value, Key)(T* aa)\n{\n    _aaClear(*cast(void **) aa);\n}\n\n/***********************************\n * Reorganizes the associative array in place so that lookups are more\n * efficient.\n * Params:\n *      aa =     The associative array.\n * Returns:\n *      The rehashed associative array.\n */\nT rehash(T : Value[Key], Value, Key)(T aa)\n{\n    _aaRehash(cast(void**)&aa, typeid(Value[Key]));\n    return aa;\n}\n\n/* ditto */\nT rehash(T : Value[Key], Value, Key)(T* aa)\n{\n    _aaRehash(cast(void**)aa, typeid(Value[Key]));\n    return *aa;\n}\n\n/* ditto */\nT rehash(T : shared Value[Key], Value, Key)(T aa)\n{\n    _aaRehash(cast(void**)&aa, typeid(Value[Key]));\n    return aa;\n}\n\n/* ditto */\nT rehash(T : shared Value[Key], Value, Key)(T* aa)\n{\n    _aaRehash(cast(void**)aa, typeid(Value[Key]));\n    return *aa;\n}\n\n/***********************************\n * Create a new associative array of the same size and copy the contents of the\n * associative array into it.\n * Params:\n *      aa =     The associative array.\n */\nV[K] dup(T : V[K], K, V)(T aa)\n{\n    //pragma(msg, \"K = \", K, \", V = \", V);\n\n    // Bug10720 - check whether V is copyable\n    static assert(is(typeof({ V v = aa[K.init]; })),\n        \"cannot call \" ~ T.stringof ~ \".dup because \" ~ V.stringof ~ \" is not copyable\");\n\n    V[K] result;\n\n    //foreach (k, ref v; aa)\n    //    result[k] = v;  // Bug13701 - won't work if V is not mutable\n\n    ref V duplicateElem(ref K k, ref const V v) @trusted pure nothrow\n    {\n        import core.stdc.string : memcpy;\n\n        void* pv = _aaGetY(cast(void**)&result, typeid(V[K]), V.sizeof, &k);\n        memcpy(pv, &v, V.sizeof);\n        return *cast(V*)pv;\n    }\n\n    if (auto postblit = _getPostblit!V())\n    {\n        foreach (k, ref v; aa)\n            postblit(duplicateElem(k, v));\n    }\n    else\n    {\n        foreach (k, ref v; aa)\n            duplicateElem(k, v);\n    }\n\n    return result;\n}\n\n/* ditto */\nV[K] dup(T : V[K], K, V)(T* aa)\n{\n    return (*aa).dup;\n}\n\n// this should never be made public.\nprivate AARange _aaToRange(T: V[K], K, V)(ref T aa) pure nothrow @nogc @safe\n{\n    // ensure we are dealing with a genuine AA.\n    static if (is(const(V[K]) == const(T)))\n        alias realAA = aa;\n    else\n        const(V[K]) realAA = aa;\n    return _aaRange(() @trusted { return cast(void*)realAA; } ());\n}\n\n/***********************************\n * Returns a forward range over the keys of the associative array.\n * Params:\n *      aa =     The associative array.\n * Returns:\n *      A forward range.\n */\nauto byKey(T : V[K], K, V)(T aa) pure nothrow @nogc @safe\n{\n    import core.internal.traits : substInout;\n\n    static struct Result\n    {\n        AARange r;\n\n    pure nothrow @nogc:\n        @property bool empty()  @safe { return _aaRangeEmpty(r); }\n        @property ref front()\n        {\n            auto p = (() @trusted => cast(substInout!K*) _aaRangeFrontKey(r)) ();\n            return *p;\n        }\n        void popFront() @safe { _aaRangePopFront(r); }\n        @property Result save() { return this; }\n    }\n\n    return Result(_aaToRange(aa));\n}\n\n/* ditto */\nauto byKey(T : V[K], K, V)(T* aa) pure nothrow @nogc\n{\n    return (*aa).byKey();\n}\n\n/***********************************\n * Returns a forward range over the values of the associative array.\n * Params:\n *      aa =     The associative array.\n * Returns:\n *      A forward range.\n */\nauto byValue(T : V[K], K, V)(T aa) pure nothrow @nogc @safe\n{\n    import core.internal.traits : substInout;\n\n    static struct Result\n    {\n        AARange r;\n\n    pure nothrow @nogc:\n        @property bool empty() @safe { return _aaRangeEmpty(r); }\n        @property ref front()\n        {\n            auto p = (() @trusted => cast(substInout!V*) _aaRangeFrontValue(r)) ();\n            return *p;\n        }\n        void popFront() @safe { _aaRangePopFront(r); }\n        @property Result save() { return this; }\n    }\n\n    return Result(_aaToRange(aa));\n}\n\n/* ditto */\nauto byValue(T : V[K], K, V)(T* aa) pure nothrow @nogc\n{\n    return (*aa).byValue();\n}\n\n/***********************************\n * Returns a forward range over the key value pairs of the associative array.\n * Params:\n *      aa =     The associative array.\n * Returns:\n *      A forward range.\n */\nauto byKeyValue(T : V[K], K, V)(T aa) pure nothrow @nogc @safe\n{\n    import core.internal.traits : substInout;\n\n    static struct Result\n    {\n        AARange r;\n\n    pure nothrow @nogc:\n        @property bool empty() @safe { return _aaRangeEmpty(r); }\n        @property auto front()\n        {\n            static struct Pair\n            {\n                // We save the pointers here so that the Pair we return\n                // won't mutate when Result.popFront is called afterwards.\n                private void* keyp;\n                private void* valp;\n\n                @property ref key() inout\n                {\n                    auto p = (() @trusted => cast(substInout!K*) keyp) ();\n                    return *p;\n                }\n                @property ref value() inout\n                {\n                    auto p = (() @trusted => cast(substInout!V*) valp) ();\n                    return *p;\n                }\n            }\n            return Pair(_aaRangeFrontKey(r),\n                        _aaRangeFrontValue(r));\n        }\n        void popFront() @safe { return _aaRangePopFront(r); }\n        @property Result save() { return this; }\n    }\n\n    return Result(_aaToRange(aa));\n}\n\n/* ditto */\nauto byKeyValue(T : V[K], K, V)(T* aa) pure nothrow @nogc\n{\n    return (*aa).byKeyValue();\n}\n\n/***********************************\n * Returns a dynamic array, the elements of which are the keys in the\n * associative array.\n * Params:\n *      aa =     The associative array.\n * Returns:\n *      A dynamic array.\n */\nKey[] keys(T : Value[Key], Value, Key)(T aa) @property\n{\n    auto a = cast(void[])_aaKeys(cast(inout(void)*)aa, Key.sizeof, typeid(Key[]));\n    auto res = *cast(Key[]*)&a;\n    _doPostblit(res);\n    return res;\n}\n\n/* ditto */\nKey[] keys(T : Value[Key], Value, Key)(T *aa) @property\n{\n    return (*aa).keys;\n}\n\n/***********************************\n * Returns a dynamic array, the elements of which are the values in the\n * associative array.\n * Params:\n *      aa =     The associative array.\n * Returns:\n *      A dynamic array.\n */\nValue[] values(T : Value[Key], Value, Key)(T aa) @property\n{\n    auto a = cast(void[])_aaValues(cast(inout(void)*)aa, Key.sizeof, Value.sizeof, typeid(Value[]));\n    auto res = *cast(Value[]*)&a;\n    _doPostblit(res);\n    return res;\n}\n\n/* ditto */\nValue[] values(T : Value[Key], Value, Key)(T *aa) @property\n{\n    return (*aa).values;\n}\n\n/***********************************\n * Looks up key; if it exists returns corresponding value else evaluates and\n * returns defaultValue.\n * Params:\n *      aa =     The associative array.\n *      key =    The key.\n *      defaultValue = The default value.\n * Returns:\n *      The value.\n */\ninout(V) get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)\n{\n    auto p = key in aa;\n    return p ? *p : defaultValue;\n}\n\n/* ditto */\ninout(V) get(K, V)(inout(V[K])* aa, K key, lazy inout(V) defaultValue)\n{\n    return (*aa).get(key, defaultValue);\n}\n\n/***********************************\n * Looks up key; if it exists returns corresponding value else evaluates\n * value, adds it to the associative array and returns it.\n * Params:\n *      aa =     The associative array.\n *      key =    The key.\n *      value =  The required value.\n * Returns:\n *      The value.\n */\nref V require(K, V)(ref V[K] aa, K key, lazy V value = V.init)\n{\n    bool found;\n    auto p = cast(V*) _aaGetX(cast(void**)&aa, typeid(V[K]), V.sizeof, &key, found);\n    return found ? *p : (*p = value);\n}\n\n// Constraints for aa update. Delegates, Functions or Functors (classes that\n// provide opCall) are allowed. See unittest for an example.\nprivate\n{\n    template isCreateOperation(C, V)\n    {\n        static if (is(C : V delegate()) || is(C : V function()))\n            enum bool isCreateOperation = true;\n        else static if (isCreateOperation!(typeof(&C.opCall), V))\n            enum bool isCreateOperation = true;\n        else\n            enum bool isCreateOperation = false;\n    }\n\n    template isUpdateOperation(U, V)\n    {\n        static if (is(U : V delegate(ref V)) || is(U : V function(ref V)))\n            enum bool isUpdateOperation = true;\n        else static if (isUpdateOperation!(typeof(&U.opCall), V))\n            enum bool isUpdateOperation = true;\n        else\n            enum bool isUpdateOperation = false;\n    }\n}\n\n/***********************************\n * Looks up key; if it exists applies the update delegate else evaluates the\n * create delegate and adds it to the associative array\n * Params:\n *      aa =     The associative array.\n *      key =    The key.\n *      create = The delegate to apply on create.\n *      update = The delegate to apply on update.\n */\nvoid update(K, V, C, U)(ref V[K] aa, K key, scope C create, scope U update)\nif (isCreateOperation!(C, V) && isUpdateOperation!(U, V))\n{\n    bool found;\n    auto p = cast(V*) _aaGetX(cast(void**)&aa, typeid(V[K]), V.sizeof, &key, found);\n    if (!found)\n        *p = create();\n    else\n        *p = update(*p);\n}\n\nprivate void _destructRecurse(E, size_t n)(ref E[n] arr)\n{\n    import core.internal.traits : hasElaborateDestructor;\n\n    static if (hasElaborateDestructor!E)\n    {\n        foreach_reverse (ref elem; arr)\n            _destructRecurse(elem);\n    }\n}\n\n// Public and explicitly undocumented\nvoid _postblitRecurse(S)(ref S s)\n    if (is(S == struct))\n{\n    static if (__traits(hasMember, S, \"__xpostblit\") &&\n               // Bugzilla 14746: Check that it's the exact member of S.\n               __traits(isSame, S, __traits(parent, s.__xpostblit)))\n        s.__xpostblit();\n}\n\n// Ditto\nvoid _postblitRecurse(E, size_t n)(ref E[n] arr)\n{\n    import core.internal.traits : hasElaborateCopyConstructor;\n\n    static if (hasElaborateCopyConstructor!E)\n    {\n        size_t i;\n        scope(failure)\n        {\n            for (; i != 0; --i)\n            {\n                _destructRecurse(arr[i - 1]); // What to do if this throws?\n            }\n        }\n\n        for (i = 0; i < arr.length; ++i)\n            _postblitRecurse(arr[i]);\n    }\n}\n\n// Test destruction/postblit order\n@safe nothrow pure unittest\n{\n    string[] order;\n\n    struct InnerTop\n    {\n        ~this() @safe nothrow pure\n        {\n            order ~= \"destroy inner top\";\n        }\n\n        this(this) @safe nothrow pure\n        {\n            order ~= \"copy inner top\";\n        }\n    }\n\n    struct InnerMiddle {}\n\n    version (none) // https://issues.dlang.org/show_bug.cgi?id=14242\n    struct InnerElement\n    {\n        static char counter = '1';\n\n        ~this() @safe nothrow pure\n        {\n            order ~= \"destroy inner element #\" ~ counter++;\n        }\n\n        this(this) @safe nothrow pure\n        {\n            order ~= \"copy inner element #\" ~ counter++;\n        }\n    }\n\n    struct InnerBottom\n    {\n        ~this() @safe nothrow pure\n        {\n            order ~= \"destroy inner bottom\";\n        }\n\n        this(this) @safe nothrow pure\n        {\n            order ~= \"copy inner bottom\";\n        }\n    }\n\n    struct S\n    {\n        char[] s;\n        InnerTop top;\n        InnerMiddle middle;\n        version (none) InnerElement[3] array; // https://issues.dlang.org/show_bug.cgi?id=14242\n        int a;\n        InnerBottom bottom;\n        ~this() @safe nothrow pure { order ~= \"destroy outer\"; }\n        this(this) @safe nothrow pure { order ~= \"copy outer\"; }\n    }\n\n    string[] destructRecurseOrder;\n    {\n        S s;\n        _destructRecurse(s);\n        destructRecurseOrder = order;\n        order = null;\n    }\n\n    assert(order.length);\n    assert(destructRecurseOrder == order);\n    order = null;\n\n    S s;\n    _postblitRecurse(s);\n    assert(order.length);\n    auto postblitRecurseOrder = order;\n    order = null;\n    S s2 = s;\n    assert(order.length);\n    assert(postblitRecurseOrder == order);\n}\n\n// Test static struct\nnothrow @safe @nogc unittest\n{\n    static int i = 0;\n    static struct S { ~this() nothrow @safe @nogc { i = 42; } }\n    S s;\n    _destructRecurse(s);\n    assert(i == 42);\n}\n\nunittest\n{\n    // Bugzilla 14746\n    static struct HasDtor\n    {\n        ~this() { assert(0); }\n    }\n    static struct Owner\n    {\n        HasDtor* ptr;\n        alias ptr this;\n    }\n\n    Owner o;\n    assert(o.ptr is null);\n    destroy(o);     // must not reach in HasDtor.__dtor()\n}\n\nunittest\n{\n    // Bugzilla 14746\n    static struct HasPostblit\n    {\n        this(this) { assert(0); }\n    }\n    static struct Owner\n    {\n        HasPostblit* ptr;\n        alias ptr this;\n    }\n\n    Owner o;\n    assert(o.ptr is null);\n    _postblitRecurse(o);     // must not reach in HasPostblit.__postblit()\n}\n\n// Test handling of fixed-length arrays\n// Separate from first test because of https://issues.dlang.org/show_bug.cgi?id=14242\nunittest\n{\n    string[] order;\n\n    struct S\n    {\n        char id;\n\n        this(this)\n        {\n            order ~= \"copy #\" ~ id;\n        }\n\n        ~this()\n        {\n            order ~= \"destroy #\" ~ id;\n        }\n    }\n\n    string[] destructRecurseOrder;\n    {\n        S[3] arr = [S('1'), S('2'), S('3')];\n        _destructRecurse(arr);\n        destructRecurseOrder = order;\n        order = null;\n    }\n    assert(order.length);\n    assert(destructRecurseOrder == order);\n    order = null;\n\n    S[3] arr = [S('1'), S('2'), S('3')];\n    _postblitRecurse(arr);\n    assert(order.length);\n    auto postblitRecurseOrder = order;\n    order = null;\n\n    auto arrCopy = arr;\n    assert(order.length);\n    assert(postblitRecurseOrder == order);\n}\n\n// Test handling of failed postblit\n// Not nothrow or @safe because of https://issues.dlang.org/show_bug.cgi?id=14242\n/+ nothrow @safe +/ unittest\n{\n    static class FailedPostblitException : Exception { this() nothrow @safe { super(null); } }\n    static string[] order;\n    static struct Inner\n    {\n        char id;\n\n        @safe:\n        this(this)\n        {\n            order ~= \"copy inner #\" ~ id;\n            if (id == '2')\n                throw new FailedPostblitException();\n        }\n\n        ~this() nothrow\n        {\n            order ~= \"destroy inner #\" ~ id;\n        }\n    }\n\n    static struct Outer\n    {\n        Inner inner1, inner2, inner3;\n\n        nothrow @safe:\n        this(char first, char second, char third)\n        {\n            inner1 = Inner(first);\n            inner2 = Inner(second);\n            inner3 = Inner(third);\n        }\n\n        this(this)\n        {\n            order ~= \"copy outer\";\n        }\n\n        ~this()\n        {\n            order ~= \"destroy outer\";\n        }\n    }\n\n    auto outer = Outer('1', '2', '3');\n\n    try _postblitRecurse(outer);\n    catch (FailedPostblitException) {}\n    catch (Exception) assert(false);\n\n    auto postblitRecurseOrder = order;\n    order = null;\n\n    try auto copy = outer;\n    catch (FailedPostblitException) {}\n    catch (Exception) assert(false);\n\n    assert(postblitRecurseOrder == order);\n    order = null;\n\n    Outer[3] arr = [Outer('1', '1', '1'), Outer('1', '2', '3'), Outer('3', '3', '3')];\n\n    try _postblitRecurse(arr);\n    catch (FailedPostblitException) {}\n    catch (Exception) assert(false);\n\n    postblitRecurseOrder = order;\n    order = null;\n\n    try auto arrCopy = arr;\n    catch (FailedPostblitException) {}\n    catch (Exception) assert(false);\n\n    assert(postblitRecurseOrder == order);\n}\n\nversion (unittest)\n{\n    private bool isnan(float x)\n    {\n        return x != x;\n    }\n}\n\nprivate\n{\n    extern (C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) nothrow;\n    extern (C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void[]* arrptr) pure nothrow;\n}\n\n/**\n * (Property) Gets the current _capacity of a slice. The _capacity is the size\n * that the slice can grow to before the underlying array must be\n * reallocated or extended.\n *\n * If an append must reallocate a slice with no possibility of extension, then\n * `0` is returned. This happens when the slice references a static array, or\n * if another slice references elements past the end of the current slice.\n *\n * Note: The _capacity of a slice may be impacted by operations on other slices.\n */\n@property size_t capacity(T)(T[] arr) pure nothrow @trusted\n{\n    return _d_arraysetcapacity(typeid(T[]), 0, cast(void[]*)&arr);\n}\n///\n@safe unittest\n{\n    //Static array slice: no capacity\n    int[4] sarray = [1, 2, 3, 4];\n    int[]  slice  = sarray[];\n    assert(sarray.capacity == 0);\n    //Appending to slice will reallocate to a new array\n    slice ~= 5;\n    assert(slice.capacity >= 5);\n\n    //Dynamic array slices\n    int[] a = [1, 2, 3, 4];\n    int[] b = a[1 .. $];\n    int[] c = a[1 .. $ - 1];\n    debug(SENTINEL) {} else // non-zero capacity very much depends on the array and GC implementation\n    {\n        assert(a.capacity != 0);\n        assert(a.capacity == b.capacity + 1); //both a and b share the same tail\n    }\n    assert(c.capacity == 0);              //an append to c must relocate c.\n}\n\n/**\n * Reserves capacity for a slice. The capacity is the size\n * that the slice can grow to before the underlying array must be\n * reallocated or extended.\n *\n * Returns: The new capacity of the array (which may be larger than\n * the requested capacity).\n */\nsize_t reserve(T)(ref T[] arr, size_t newcapacity) pure nothrow @trusted\n{\n    return _d_arraysetcapacity(typeid(T[]), newcapacity, cast(void[]*)&arr);\n}\n///\nunittest\n{\n    //Static array slice: no capacity. Reserve relocates.\n    int[4] sarray = [1, 2, 3, 4];\n    int[]  slice  = sarray[];\n    auto u = slice.reserve(8);\n    assert(u >= 8);\n    assert(sarray.ptr !is slice.ptr);\n    assert(slice.capacity == u);\n\n    //Dynamic array slices\n    int[] a = [1, 2, 3, 4];\n    a.reserve(8); //prepare a for appending 4 more items\n    auto p = a.ptr;\n    u = a.capacity;\n    a ~= [5, 6, 7, 8];\n    assert(p == a.ptr);      //a should not have been reallocated\n    assert(u == a.capacity); //a should not have been extended\n}\n\n// Issue 6646: should be possible to use array.reserve from SafeD.\n@safe unittest\n{\n    int[] a;\n    a.reserve(10);\n}\n\n/**\n * Assume that it is safe to append to this array. Appends made to this array\n * after calling this function may append in place, even if the array was a\n * slice of a larger array to begin with.\n *\n * Use this only when it is certain there are no elements in use beyond the\n * array in the memory block.  If there are, those elements will be\n * overwritten by appending to this array.\n *\n * Warning: Calling this function, and then using references to data located after the\n * given array results in undefined behavior.\n *\n * Returns:\n *   The input is returned.\n */\nauto ref inout(T[]) assumeSafeAppend(T)(auto ref inout(T[]) arr) nothrow\n{\n    _d_arrayshrinkfit(typeid(T[]), *(cast(void[]*)&arr));\n    return arr;\n}\n///\nunittest\n{\n    int[] a = [1, 2, 3, 4];\n\n    // Without assumeSafeAppend. Appending relocates.\n    int[] b = a [0 .. 3];\n    b ~= 5;\n    assert(a.ptr != b.ptr);\n\n    debug(SENTINEL) {} else\n    {\n        // With assumeSafeAppend. Appending overwrites.\n        int[] c = a [0 .. 3];\n        c.assumeSafeAppend() ~= 5;\n        assert(a.ptr == c.ptr);\n    }\n}\n\nunittest\n{\n    int[] arr;\n    auto newcap = arr.reserve(2000);\n    assert(newcap >= 2000);\n    assert(newcap == arr.capacity);\n    auto ptr = arr.ptr;\n    foreach (i; 0..2000)\n        arr ~= i;\n    assert(ptr == arr.ptr);\n    arr = arr[0..1];\n    arr.assumeSafeAppend();\n    arr ~= 5;\n    assert(ptr == arr.ptr);\n}\n\nunittest\n{\n    int[] arr = [1, 2, 3];\n    void foo(ref int[] i)\n    {\n        i ~= 5;\n    }\n    arr = arr[0 .. 2];\n    foo(assumeSafeAppend(arr)); //pass by ref\n    assert(arr[]==[1, 2, 5]);\n    arr = arr[0 .. 1].assumeSafeAppend(); //pass by value\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=10574\nunittest\n{\n    int[] a;\n    immutable(int[]) b;\n    auto a2 = &assumeSafeAppend(a);\n    auto b2 = &assumeSafeAppend(b);\n    auto a3 = assumeSafeAppend(a[]);\n    auto b3 = assumeSafeAppend(b[]);\n    assert(is(typeof(*a2) == int[]));\n    assert(is(typeof(*b2) == immutable(int[])));\n    assert(is(typeof(a3) == int[]));\n    assert(is(typeof(b3) == immutable(int[])));\n}\n\nversion (none)\n{\n    // enforce() copied from Phobos std.contracts for destroy(), left out until\n    // we decide whether to use it.\n\n\n    T _enforce(T, string file = __FILE__, int line = __LINE__)\n        (T value, lazy const(char)[] msg = null)\n    {\n        if (!value) bailOut(file, line, msg);\n        return value;\n    }\n\n    T _enforce(T, string file = __FILE__, int line = __LINE__)\n        (T value, scope void delegate() dg)\n    {\n        if (!value) dg();\n        return value;\n    }\n\n    T _enforce(T)(T value, lazy Exception ex)\n    {\n        if (!value) throw ex();\n        return value;\n    }\n\n    private void _bailOut(string file, int line, in char[] msg)\n    {\n        char[21] buf;\n        throw new Exception(cast(string)(file ~ \"(\" ~ ulongToString(buf[], line) ~ \"): \" ~ (msg ? msg : \"Enforcement failed\")));\n    }\n}\n\nversion (D_Ddoc)\n{\n    // This lets DDoc produce better documentation.\n\n    /**\n    Calculates the hash value of `arg` with an optional `seed` initial value.\n    The result might not be equal to `typeid(T).getHash(&arg)`.\n\n    Params:\n        arg = argument to calculate the hash value of\n        seed = optional `seed` value (may be used for hash chaining)\n\n    Return: calculated hash value of `arg`\n    */\n    size_t hashOf(T)(auto ref T arg, size_t seed)\n    {\n        static import core.internal.hash;\n        return core.internal.hash.hashOf(arg, seed);\n    }\n    /// ditto\n    size_t hashOf(T)(auto ref T arg)\n    {\n        static import core.internal.hash;\n        return core.internal.hash.hashOf(arg);\n    }\n}\nelse\n{\n    public import core.internal.hash : hashOf;\n}\n\n///\n@system unittest\n{\n    class MyObject\n    {\n        size_t myMegaHash() const @safe pure nothrow\n        {\n            return 42;\n        }\n    }\n    struct Test\n    {\n        int a;\n        string b;\n        MyObject c;\n        size_t toHash() const pure nothrow\n        {\n            size_t hash = a.hashOf();\n            hash = b.hashOf(hash);\n            size_t h1 = c.myMegaHash();\n            hash = h1.hashOf(hash); //Mix two hash values\n            return hash;\n        }\n    }\n}\n\nbool _xopEquals(in void*, in void*)\n{\n    throw new Error(\"TypeInfo.equals is not implemented\");\n}\n\nbool _xopCmp(in void*, in void*)\n{\n    throw new Error(\"TypeInfo.compare is not implemented\");\n}\n\nvoid __ctfeWrite(scope const(char)[] s) @nogc @safe pure nothrow {}\n\n/******************************************\n * Create RTInfo for type T\n */\n\ntemplate RTInfo(T)\n{\n    enum RTInfo = null;\n}\n\n// Compiler hook into the runtime implementation of array (vector) operations.\ntemplate _arrayOp(Args...)\n{\n    import core.internal.arrayop;\n    alias _arrayOp = arrayOp!Args;\n}\n\n/*\n * Support for switch statements switching on strings.\n * Params:\n *      caseLabels = sorted array of strings generated by compiler. Note the\n                   strings are sorted by length first, and then lexicographically.\n *      condition = string to look up in table\n * Returns:\n *      index of match in caseLabels, a negative integer if not found\n*/\nint __switch(T, caseLabels...)(/*in*/ const scope T[] condition) pure nothrow @safe @nogc\n{\n    // This closes recursion for other cases.\n    static if (caseLabels.length == 0)\n    {\n        return int.min;\n    }\n    else static if (caseLabels.length == 1)\n    {\n        return __cmp(condition, caseLabels[0]) == 0 ? 0 : int.min;\n    }\n    // To be adjusted after measurements\n    // Compile-time inlined binary search.\n    else static if (caseLabels.length < 7)\n    {\n        int r = void;\n        enum mid = cast(int)caseLabels.length / 2;\n        if (condition.length == caseLabels[mid].length)\n        {\n            r = __cmp(condition, caseLabels[mid]);\n            if (r == 0) return mid;\n        }\n        else\n        {\n            // Equivalent to (but faster than) condition.length > caseLabels[$ / 2].length ? 1 : -1\n            r = ((condition.length > caseLabels[mid].length) << 1) - 1;\n        }\n\n        if (r < 0)\n        {\n            // Search the left side\n            return __switch!(T, caseLabels[0 .. mid])(condition);\n        }\n        else\n        {\n            // Search the right side\n            return __switch!(T, caseLabels[mid + 1 .. $])(condition) + mid + 1;\n        }\n    }\n    else\n    {\n        // Need immutable array to be accessible in pure code, but case labels are\n        // currently coerced to the switch condition type (e.g. const(char)[]).\n        static immutable T[][caseLabels.length] cases = {\n            auto res = new immutable(T)[][](caseLabels.length);\n            foreach (i, s; caseLabels)\n                res[i] = s.idup;\n            return res;\n        }();\n\n        // Run-time binary search in a static array of labels.\n        return __switchSearch!T(cases[], condition);\n    }\n}\n\n// binary search in sorted string cases, also see `__switch`.\nprivate int __switchSearch(T)(/*in*/ const scope T[][] cases, /*in*/ const scope T[] condition) pure nothrow @safe @nogc\n{\n    size_t low = 0;\n    size_t high = cases.length;\n\n    do\n    {\n        auto mid = (low + high) / 2;\n        int r = void;\n        if (condition.length == cases[mid].length)\n        {\n            r = __cmp(condition, cases[mid]);\n            if (r == 0) return cast(int) mid;\n        }\n        else\n        {\n            // Generates better code than \"expr ? 1 : -1\" on dmd and gdc, same with ldc\n            r = ((condition.length > cases[mid].length) << 1) - 1;\n        }\n\n        if (r > 0) low = mid + 1;\n        else high = mid;\n    }\n    while (low < high);\n\n    // Not found\n    return -1;\n}\n\nunittest\n{\n    static void testSwitch(T)()\n    {\n        switch (cast(T[]) \"c\")\n        {\n             case \"coo\":\n             default:\n                 break;\n        }\n\n        static int bug5381(immutable(T)[] s)\n        {\n            switch (s)\n            {\n                case \"unittest\":        return 1;\n                case \"D_Version2\":      return 2;\n                case \"nonenone\":        return 3;\n                case \"none\":            return 4;\n                case \"all\":             return 5;\n                default:                return 6;\n            }\n        }\n\n        int rc = bug5381(\"unittest\");\n        assert(rc == 1);\n\n        rc = bug5381(\"D_Version2\");\n        assert(rc == 2);\n\n        rc = bug5381(\"nonenone\");\n        assert(rc == 3);\n\n        rc = bug5381(\"none\");\n        assert(rc == 4);\n\n        rc = bug5381(\"all\");\n        assert(rc == 5);\n\n        rc = bug5381(\"nonerandom\");\n        assert(rc == 6);\n\n        static int binarySearch(immutable(T)[] s)\n        {\n            switch (s)\n            {\n                static foreach (i; 0 .. 16)\n                case i.stringof: return i;\n                default: return -1;\n            }\n        }\n        static foreach (i; 0 .. 16)\n            assert(binarySearch(i.stringof) == i);\n        assert(binarySearch(\"\") == -1);\n        assert(binarySearch(\"sth.\") == -1);\n        assert(binarySearch(null) == -1);\n\n        static int bug16739(immutable(T)[] s)\n        {\n            switch (s)\n            {\n                case \"\\u0100\": return 1;\n                case \"a\": return 2;\n                default: return 3;\n            }\n        }\n        assert(bug16739(\"\\u0100\") == 1);\n        assert(bug16739(\"a\") == 2);\n        assert(bug16739(\"foo\") == 3);\n    }\n    testSwitch!char;\n    testSwitch!wchar;\n    testSwitch!dchar;\n}\n\n// Compiler lowers final switch default case to this (which is a runtime error)\n// Old implementation is in core/exception.d\nvoid __switch_error()(string file = __FILE__, size_t line = __LINE__)\n{\n    import core.exception : __switch_errorT;\n    __switch_errorT(file, line);\n}\n\n// Helper functions\n\nprivate inout(TypeInfo) getElement(inout TypeInfo value) @trusted pure nothrow\n{\n    TypeInfo element = cast() value;\n    for (;;)\n    {\n        if (auto qualified = cast(TypeInfo_Const) element)\n            element = qualified.base;\n        else if (auto redefined = cast(TypeInfo_Enum) element)\n            element = redefined.base;\n        else if (auto staticArray = cast(TypeInfo_StaticArray) element)\n            element = staticArray.value;\n        else if (auto vector = cast(TypeInfo_Vector) element)\n            element = vector.base;\n        else\n            break;\n    }\n    return cast(inout) element;\n}\n\nprivate size_t getArrayHash(in TypeInfo element, in void* ptr, in size_t count) @trusted nothrow\n{\n    if (!count)\n        return 0;\n\n    const size_t elementSize = element.tsize;\n    if (!elementSize)\n        return 0;\n\n    static bool hasCustomToHash(in TypeInfo value) @trusted pure nothrow\n    {\n        const element = getElement(value);\n\n        if (const struct_ = cast(const TypeInfo_Struct) element)\n            return !!struct_.xtoHash;\n\n        return cast(const TypeInfo_Array) element\n            || cast(const TypeInfo_AssociativeArray) element\n            || cast(const ClassInfo) element\n            || cast(const TypeInfo_Interface) element;\n    }\n\n    import core.internal.traits : externDFunc;\n    if (!hasCustomToHash(element))\n        return hashOf(ptr[0 .. elementSize * count]);\n\n    size_t hash = 0;\n    foreach (size_t i; 0 .. count)\n        hash = hashOf(element.getHash(ptr + i * elementSize), hash);\n    return hash;\n}\n\n/// Provide the .dup array property.\n@property auto dup(T)(T[] a)\n    if (!is(const(T) : T))\n{\n    import core.internal.traits : Unconst;\n    static assert(is(T : Unconst!T), \"Cannot implicitly convert type \"~T.stringof~\n                  \" to \"~Unconst!T.stringof~\" in dup.\");\n\n    // wrap unsafe _dup in @trusted to preserve @safe postblit\n    static if (__traits(compiles, (T b) @safe { T a = b; }))\n        return _trustedDup!(T, Unconst!T)(a);\n    else\n        return _dup!(T, Unconst!T)(a);\n}\n\n/// ditto\n// const overload to support implicit conversion to immutable (unique result, see DIP29)\n@property T[] dup(T)(const(T)[] a)\n    if (is(const(T) : T))\n{\n    // wrap unsafe _dup in @trusted to preserve @safe postblit\n    static if (__traits(compiles, (T b) @safe { T a = b; }))\n        return _trustedDup!(const(T), T)(a);\n    else\n        return _dup!(const(T), T)(a);\n}\n\n\n/// Provide the .idup array property.\n@property immutable(T)[] idup(T)(T[] a)\n{\n    static assert(is(T : immutable(T)), \"Cannot implicitly convert type \"~T.stringof~\n                  \" to immutable in idup.\");\n\n    // wrap unsafe _dup in @trusted to preserve @safe postblit\n    static if (__traits(compiles, (T b) @safe { T a = b; }))\n        return _trustedDup!(T, immutable(T))(a);\n    else\n        return _dup!(T, immutable(T))(a);\n}\n\n/// ditto\n@property immutable(T)[] idup(T:void)(const(T)[] a)\n{\n    return a.dup;\n}\n\nprivate U[] _trustedDup(T, U)(T[] a) @trusted\n{\n    return _dup!(T, U)(a);\n}\n\nprivate U[] _dup(T, U)(T[] a) // pure nothrow depends on postblit\n{\n    if (__ctfe)\n    {\n        static if (is(T : void))\n            assert(0, \"Cannot dup a void[] array at compile time.\");\n        else\n        {\n            U[] res;\n            foreach (ref e; a)\n                res ~= e;\n            return res;\n        }\n    }\n\n    import core.stdc.string : memcpy;\n\n    void[] arr = _d_newarrayU(typeid(T[]), a.length);\n    memcpy(arr.ptr, cast(const(void)*)a.ptr, T.sizeof * a.length);\n    auto res = *cast(U[]*)&arr;\n\n    static if (!is(T : void))\n        _doPostblit(res);\n    return res;\n}\n\nprivate extern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow;\n\n\n/**************\n * Get the postblit for type T.\n * Returns:\n *      null if no postblit is necessary\n *      function pointer for struct postblits\n *      delegate for class postblits\n */\nprivate auto _getPostblit(T)() @trusted pure nothrow @nogc\n{\n    // infer static postblit type, run postblit if any\n    static if (is(T == struct))\n    {\n        import core.internal.traits : Unqual;\n        // use typeid(Unqual!T) here to skip TypeInfo_Const/Shared/...\n        alias _PostBlitType = typeof(function (ref T t){ T a = t; });\n        return cast(_PostBlitType)typeid(Unqual!T).xpostblit;\n    }\n    else if ((&typeid(T).postblit).funcptr !is &TypeInfo.postblit)\n    {\n        alias _PostBlitType = typeof(delegate (ref T t){ T a = t; });\n        return cast(_PostBlitType)&typeid(T).postblit;\n    }\n    else\n        return null;\n}\n\nprivate void _doPostblit(T)(T[] arr)\n{\n    // infer static postblit type, run postblit if any\n    if (auto postblit = _getPostblit!T())\n    {\n        foreach (ref elem; arr)\n            postblit(elem);\n    }\n}\n\nunittest\n{\n    static struct S1 { int* p; }\n    static struct S2 { @disable this(); }\n    static struct S3 { @disable this(this); }\n\n    int dg1() pure nothrow @safe\n    {\n        {\n           char[] m;\n           string i;\n           m = m.dup;\n           i = i.idup;\n           m = i.dup;\n           i = m.idup;\n        }\n        {\n           S1[] m;\n           immutable(S1)[] i;\n           m = m.dup;\n           i = i.idup;\n           static assert(!is(typeof(m.idup)));\n           static assert(!is(typeof(i.dup)));\n        }\n        {\n            S3[] m;\n            immutable(S3)[] i;\n            static assert(!is(typeof(m.dup)));\n            static assert(!is(typeof(i.idup)));\n        }\n        {\n            shared(S1)[] m;\n            m = m.dup;\n            static assert(!is(typeof(m.idup)));\n        }\n        {\n            int[] a = (inout(int)) { inout(const(int))[] a; return a.dup; }(0);\n        }\n        return 1;\n    }\n\n    int dg2() pure nothrow @safe\n    {\n        {\n           S2[] m = [S2.init, S2.init];\n           immutable(S2)[] i = [S2.init, S2.init];\n           m = m.dup;\n           m = i.dup;\n           i = m.idup;\n           i = i.idup;\n        }\n        return 2;\n    }\n\n    enum a = dg1();\n    enum b = dg2();\n    assert(dg1() == a);\n    assert(dg2() == b);\n}\n\nunittest\n{\n    static struct Sunpure { this(this) @safe nothrow {} }\n    static struct Sthrow { this(this) @safe pure {} }\n    static struct Sunsafe { this(this) @system pure nothrow {} }\n\n    static assert( __traits(compiles, ()         { [].dup!Sunpure; }));\n    static assert(!__traits(compiles, () pure    { [].dup!Sunpure; }));\n    static assert( __traits(compiles, ()         { [].dup!Sthrow; }));\n    static assert(!__traits(compiles, () nothrow { [].dup!Sthrow; }));\n    static assert( __traits(compiles, ()         { [].dup!Sunsafe; }));\n    static assert(!__traits(compiles, () @safe   { [].dup!Sunsafe; }));\n\n    static assert( __traits(compiles, ()         { [].idup!Sunpure; }));\n    static assert(!__traits(compiles, () pure    { [].idup!Sunpure; }));\n    static assert( __traits(compiles, ()         { [].idup!Sthrow; }));\n    static assert(!__traits(compiles, () nothrow { [].idup!Sthrow; }));\n    static assert( __traits(compiles, ()         { [].idup!Sunsafe; }));\n    static assert(!__traits(compiles, () @safe   { [].idup!Sunsafe; }));\n}\n\nunittest\n{\n    static int*[] pureFoo() pure { return null; }\n    { char[] s; immutable x = s.dup; }\n    { immutable x = (cast(int*[])null).dup; }\n    { immutable x = pureFoo(); }\n    { immutable x = pureFoo().dup; }\n}\n\nunittest\n{\n    auto a = [1, 2, 3];\n    auto b = a.dup;\n    debug(SENTINEL) {} else\n        assert(b.capacity >= 3);\n}\n\nunittest\n{\n    // Bugzilla 12580\n    void[] m = [0];\n    shared(void)[] s = [cast(shared)1];\n    immutable(void)[] i = [cast(immutable)2];\n\n    s = s.dup;\n    static assert(is(typeof(s.dup) == shared(void)[]));\n\n    m = i.dup;\n    i = m.dup;\n    i = i.idup;\n    i = m.idup;\n    i = s.idup;\n    i = s.dup;\n    static assert(!__traits(compiles, m = s.dup));\n}\n\nunittest\n{\n    // Bugzilla 13809\n    static struct S\n    {\n        this(this) {}\n        ~this() {}\n    }\n\n    S[] arr;\n    auto a = arr.dup;\n}\n\nunittest\n{\n    // Bugzilla 16504\n    static struct S\n    {\n        __gshared int* gp;\n        int* p;\n        // postblit and hence .dup could escape\n        this(this) { gp = p; }\n    }\n\n    int p;\n    scope S[1] arr = [S(&p)];\n    auto a = arr.dup; // dup does escape\n}\n\n// compiler frontend lowers dynamic array comparison to this\nbool __ArrayEq(T1, T2)(T1[] a, T2[] b)\n{\n    if (a.length != b.length)\n        return false;\n    foreach (size_t i; 0 .. a.length)\n    {\n        if (a[i] != b[i])\n            return false;\n    }\n    return true;\n}\n\n// compiler frontend lowers struct array postblitting to this\nvoid __ArrayPostblit(T)(T[] a)\n{\n    foreach (ref T e; a)\n        e.__xpostblit();\n}\n\n// compiler frontend lowers dynamic array deconstruction to this\nvoid __ArrayDtor(T)(T[] a)\n{\n    foreach_reverse (ref T e; a)\n        e.__xdtor();\n}\n\n/**\nUsed by `__ArrayCast` to emit a descriptive error message.\n\nIt is a template so it can be used by `__ArrayCast` in -betterC\nbuilds.  It is separate from `__ArrayCast` to minimize code\nbloat.\n\nParams:\n    fromType = name of the type being cast from\n    fromSize = total size in bytes of the array being cast from\n    toType   = name of the type being cast o\n    toSize   = total size in bytes of the array being cast to\n */\nprivate void onArrayCastError()(string fromType, size_t fromSize, string toType, size_t toSize) @trusted\n{\n    import core.internal.string : unsignedToTempString;\n    import core.stdc.stdlib : alloca;\n\n    const(char)[][8] msgComponents =\n    [\n        \"Cannot cast `\"\n        , fromType\n        , \"` to `\"\n        , toType\n        , \"`; an array of size \"\n        , unsignedToTempString(fromSize)\n        , \" does not align on an array of size \"\n        , unsignedToTempString(toSize)\n    ];\n\n    // convert discontiguous `msgComponents` to contiguous string on the stack\n    size_t length = 0;\n    foreach (m ; msgComponents)\n        length += m.length;\n\n    auto msg = (cast(char*)alloca(length))[0 .. length];\n\n    size_t index = 0;\n    foreach (m ; msgComponents)\n        foreach (c; m)\n            msg[index++] = c;\n\n    // first argument must evaluate to `false` at compile-time to maintain memory safety in release builds\n    assert(false, msg);\n}\n\n/**\nThe compiler lowers expressions of `cast(TTo[])TFrom[]` to\nthis implementation.\n\nParams:\n    from = the array to reinterpret-cast\n\nReturns:\n    `from` reinterpreted as `TTo[]`\n */\nTTo[] __ArrayCast(TFrom, TTo)(TFrom[] from) @nogc pure @trusted\n{\n    const fromSize = from.length * TFrom.sizeof;\n    const toLength = fromSize / TTo.sizeof;\n\n    if ((fromSize % TTo.sizeof) != 0)\n    {\n        onArrayCastError(TFrom.stringof, fromSize, TTo.stringof, toLength * TTo.sizeof);\n    }\n\n    struct Array\n    {\n        size_t length;\n        void* ptr;\n    }\n    auto a = cast(Array*)&from;\n    a.length = toLength; // jam new length\n    return *cast(TTo[]*)a;\n}\n\n@safe @nogc pure nothrow unittest\n{\n    byte[int.sizeof * 3] b = cast(byte) 0xab;\n    int[] i;\n    short[] s;\n\n    i = __ArrayCast!(byte, int)(b);\n    assert(i.length == 3);\n    foreach (v; i)\n        assert(v == cast(int) 0xabab_abab);\n\n    s = __ArrayCast!(byte, short)(b);\n    assert(s.length == 6);\n    foreach (v; s)\n        assert(v == cast(short) 0xabab);\n\n    s = __ArrayCast!(int, short)(i);\n    assert(s.length == 6);\n    foreach (v; s)\n        assert(v == cast(short) 0xabab);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/aApply.d",
    "content": "/**\n * This code handles decoding UTF strings for foreach loops.  There are 6\n * combinations of conversions between char, wchar, and dchar, and 2 of each\n * of those.\n *\n * Copyright: Copyright Digital Mars 2004 - 2010.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n * Source: $(DRUNTIMESRC rt/_aApply.d)\n */\nmodule rt.aApply;\n\nprivate import rt.util.utf : decode, toUTF8;\n\n/**********************************************/\n/* 1 argument versions */\n\n// dg is D, but _aApplycd() is C\nextern (D) alias int delegate(void *) dg_t;\n\nextern (C) int _aApplycd1(in char[] aa, dg_t dg)\n{\n    int result;\n    size_t len = aa.length;\n\n    debug(apply) printf(\"_aApplycd1(), len = %d\\n\", len);\n    for (size_t i = 0; i < len; )\n    {\n        dchar d = aa[i];\n        if (d & 0x80)\n            d = decode(aa, i);\n        else\n            ++i;\n        result = dg(cast(void *)&d);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplycd1.unittest\\n\");\n\n    auto s = \"hello\"c[];\n    int i;\n\n    foreach (dchar d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (dchar d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'a'); break;\n            case 1:     assert(d == '\\u1234'); break;\n            case 2:     assert(d == '\\U000A0456'); break;\n            case 3:     assert(d == 'b'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 4);\n}\n\n/*****************************/\n\nextern (C) int _aApplywd1(in wchar[] aa, dg_t dg)\n{\n    int result;\n    size_t len = aa.length;\n\n    debug(apply) printf(\"_aApplywd1(), len = %d\\n\", len);\n    for (size_t i = 0; i < len; )\n    {\n        dchar d = aa[i];\n        if (d >= 0xD800)\n            d = decode(aa, i);\n        else\n            ++i;\n        result = dg(cast(void *)&d);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplywd1.unittest\\n\");\n\n    auto s = \"hello\"w[];\n    int i;\n\n    foreach (dchar d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (dchar d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'a'); break;\n            case 1:     assert(d == '\\u1234'); break;\n            case 2:     assert(d == '\\U000A0456'); break;\n            case 3:     assert(d == 'b'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 4);\n}\n\n/*****************************/\n\nextern (C) int _aApplycw1(in char[] aa, dg_t dg)\n{\n    int result;\n    size_t len = aa.length;\n\n    debug(apply) printf(\"_aApplycw1(), len = %d\\n\", len);\n    for (size_t i = 0; i < len; )\n    {\n        wchar w = aa[i];\n        if (w & 0x80)\n        {\n            dchar d = decode(aa, i);\n            if (d <= 0xFFFF)\n                w = cast(wchar) d;\n            else\n            {\n                w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);\n                result = dg(cast(void *)&w);\n                if (result)\n                    break;\n                w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);\n            }\n        }\n        else\n            ++i;\n        result = dg(cast(void *)&w);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplycw1.unittest\\n\");\n\n    auto s = \"hello\"c[];\n    int i;\n\n    foreach (wchar d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (wchar d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'a'); break;\n            case 1:     assert(d == 0x1234); break;\n            case 2:     assert(d == 0xDA41); break;\n            case 3:     assert(d == 0xDC56); break;\n            case 4:     assert(d == 'b'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n}\n\n/*****************************/\n\nextern (C) int _aApplywc1(in wchar[] aa, dg_t dg)\n{\n    int result;\n    size_t len = aa.length;\n\n    debug(apply) printf(\"_aApplywc1(), len = %d\\n\", len);\n    for (size_t i = 0; i < len; )\n    {\n        wchar w = aa[i];\n        if (w & ~0x7F)\n        {\n            char[4] buf = void;\n\n            dchar d = decode(aa, i);\n            auto b = toUTF8(buf, d);\n            foreach (char c2; b)\n            {\n                result = dg(cast(void *)&c2);\n                if (result)\n                    return result;\n            }\n        }\n        else\n        {\n            char c = cast(char)w;\n            ++i;\n            result = dg(cast(void *)&c);\n            if (result)\n                break;\n        }\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplywc1.unittest\\n\");\n\n    auto s = \"hello\"w[];\n    int i;\n\n    foreach (char d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (char d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'a'); break;\n            case 1:     assert(d == 0xE1); break;\n            case 2:     assert(d == 0x88); break;\n            case 3:     assert(d == 0xB4); break;\n            case 4:     assert(d == 0xF2); break;\n            case 5:     assert(d == 0xA0); break;\n            case 6:     assert(d == 0x91); break;\n            case 7:     assert(d == 0x96); break;\n            case 8:     assert(d == 'b'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 9);\n}\n\n/*****************************/\n\nextern (C) int _aApplydc1(in dchar[] aa, dg_t dg)\n{\n    int result;\n\n    debug(apply) printf(\"_aApplydc1(), len = %d\\n\", aa.length);\n    foreach (dchar d; aa)\n    {\n        if (d & ~0x7F)\n        {\n            char[4] buf = void;\n\n            auto b = toUTF8(buf, d);\n            foreach (char c2; b)\n            {\n                result = dg(cast(void *)&c2);\n                if (result)\n                    return result;\n            }\n        }\n        else\n        {\n            char c = cast(char)d;\n            result = dg(cast(void *)&c);\n            if (result)\n                break;\n        }\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRdc1.unittest\\n\");\n\n    auto s = \"hello\"d[];\n    int i;\n\n    foreach (char d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (char d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'a'); break;\n            case 1:     assert(d == 0xE1); break;\n            case 2:     assert(d == 0x88); break;\n            case 3:     assert(d == 0xB4); break;\n            case 4:     assert(d == 0xF2); break;\n            case 5:     assert(d == 0xA0); break;\n            case 6:     assert(d == 0x91); break;\n            case 7:     assert(d == 0x96); break;\n            case 8:     assert(d == 'b'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 9);\n}\n\n/*****************************/\n\nextern (C) int _aApplydw1(in dchar[] aa, dg_t dg)\n{\n    int result;\n\n    debug(apply) printf(\"_aApplydw1(), len = %d\\n\", aa.length);\n    foreach (dchar d; aa)\n    {\n        wchar w;\n\n        if (d <= 0xFFFF)\n            w = cast(wchar) d;\n        else\n        {\n            w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);\n            result = dg(cast(void *)&w);\n            if (result)\n                break;\n            w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);\n        }\n        result = dg(cast(void *)&w);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplydw1.unittest\\n\");\n\n    auto s = \"hello\"d[];\n    int i;\n\n    foreach (wchar d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (wchar d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'a'); break;\n            case 1:     assert(d == 0x1234); break;\n            case 2:     assert(d == 0xDA41); break;\n            case 3:     assert(d == 0xDC56); break;\n            case 4:     assert(d == 'b'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n}\n\n\n/****************************************************************************/\n/* 2 argument versions */\n\n// dg is D, but _aApplycd2() is C\nextern (D) alias int delegate(void *, void *) dg2_t;\n\nextern (C) int _aApplycd2(in char[] aa, dg2_t dg)\n{\n    int result;\n    size_t len = aa.length;\n\n    debug(apply) printf(\"_aApplycd2(), len = %d\\n\", len);\n    size_t n;\n    for (size_t i = 0; i < len; i += n)\n    {\n        dchar d = aa[i];\n        if (d & 0x80)\n        {\n            n = i;\n            d = decode(aa, n);\n            n -= i;\n        }\n        else\n            n = 1;\n        result = dg(&i, cast(void *)&d);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplycd2.unittest\\n\");\n\n    auto s = \"hello\"c[];\n    int i;\n\n    foreach (k, dchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        assert(k == i);\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (k, dchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'a'); assert(k == 0); break;\n            case 1:     assert(d == '\\u1234'); assert(k == 1); break;\n            case 2:     assert(d == '\\U000A0456'); assert(k == 4); break;\n            case 3:     assert(d == 'b'); assert(k == 8); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 4);\n}\n\n/*****************************/\n\nextern (C) int _aApplywd2(in wchar[] aa, dg2_t dg)\n{\n    int result;\n    size_t len = aa.length;\n\n    debug(apply) printf(\"_aApplywd2(), len = %d\\n\", len);\n    size_t n;\n    for (size_t i = 0; i < len; i += n)\n    {\n        dchar d = aa[i];\n        if (d & ~0x7F)\n        {\n            n = i;\n            d = decode(aa, n);\n            n -= i;\n        }\n        else\n            n = 1;\n        result = dg(&i, cast(void *)&d);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplywd2.unittest\\n\");\n\n    auto s = \"hello\"w[];\n    int i;\n\n    foreach (k, dchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        assert(k == i);\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (k, dchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(k == 0); assert(d == 'a'); break;\n            case 1:     assert(k == 1); assert(d == '\\u1234'); break;\n            case 2:     assert(k == 2); assert(d == '\\U000A0456'); break;\n            case 3:     assert(k == 4); assert(d == 'b'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 4);\n}\n\n/*****************************/\n\nextern (C) int _aApplycw2(in char[] aa, dg2_t dg)\n{\n    int result;\n    size_t len = aa.length;\n\n    debug(apply) printf(\"_aApplycw2(), len = %d\\n\", len);\n    size_t n;\n    for (size_t i = 0; i < len; i += n)\n    {\n        wchar w = aa[i];\n        if (w & 0x80)\n        {\n            n = i;\n            dchar d = decode(aa, n);\n            n -= i;\n            if (d <= 0xFFFF)\n                w = cast(wchar) d;\n            else\n            {\n                w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);\n                result = dg(&i, cast(void *)&w);\n                if (result)\n                    break;\n                w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);\n            }\n        }\n        else\n            n = 1;\n        result = dg(&i, cast(void *)&w);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplycw2.unittest\\n\");\n\n    auto s = \"hello\"c[];\n    int i;\n\n    foreach (k, wchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        assert(k == i);\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (k, wchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(k == 0); assert(d == 'a'); break;\n            case 1:     assert(k == 1); assert(d == 0x1234); break;\n            case 2:     assert(k == 4); assert(d == 0xDA41); break;\n            case 3:     assert(k == 4); assert(d == 0xDC56); break;\n            case 4:     assert(k == 8); assert(d == 'b'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n}\n\n/*****************************/\n\nextern (C) int _aApplywc2(in wchar[] aa, dg2_t dg)\n{\n    int result;\n    size_t len = aa.length;\n\n    debug(apply) printf(\"_aApplywc2(), len = %d\\n\", len);\n    size_t n;\n    for (size_t i = 0; i < len; i += n)\n    {\n        wchar w = aa[i];\n        if (w & ~0x7F)\n        {\n            char[4] buf = void;\n\n            n = i;\n            dchar d = decode(aa, n);\n            n -= i;\n            auto b = toUTF8(buf, d);\n            foreach (char c2; b)\n            {\n                result = dg(&i, cast(void *)&c2);\n                if (result)\n                    return result;\n            }\n        }\n        else\n        {\n            char c = cast(char)w;\n            n = 1;\n            result = dg(&i, cast(void *)&c);\n            if (result)\n                break;\n        }\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplywc2.unittest\\n\");\n\n    auto s = \"hello\"w[];\n    int i;\n\n    foreach (k, char d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        assert(k == i);\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (k, char d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(k == 0); assert(d == 'a'); break;\n            case 1:     assert(k == 1); assert(d == 0xE1); break;\n            case 2:     assert(k == 1); assert(d == 0x88); break;\n            case 3:     assert(k == 1); assert(d == 0xB4); break;\n            case 4:     assert(k == 2); assert(d == 0xF2); break;\n            case 5:     assert(k == 2); assert(d == 0xA0); break;\n            case 6:     assert(k == 2); assert(d == 0x91); break;\n            case 7:     assert(k == 2); assert(d == 0x96); break;\n            case 8:     assert(k == 4); assert(d == 'b'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 9);\n}\n\n/*****************************/\n\nextern (C) int _aApplydc2(in dchar[] aa, dg2_t dg)\n{\n    int result;\n    size_t len = aa.length;\n\n    debug(apply) printf(\"_aApplydc2(), len = %d\\n\", len);\n    for (size_t i = 0; i < len; i++)\n    {\n        dchar d = aa[i];\n        if (d & ~0x7F)\n        {\n            char[4] buf = void;\n\n            auto b = toUTF8(buf, d);\n            foreach (char c2; b)\n            {\n                result = dg(&i, cast(void *)&c2);\n                if (result)\n                    return result;\n            }\n        }\n        else\n        {\n            char c = cast(char)d;\n            result = dg(&i, cast(void *)&c);\n            if (result)\n                break;\n        }\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplydc2.unittest\\n\");\n\n    auto s = \"hello\"d[];\n    int i;\n\n    foreach (k, char d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        assert(k == i);\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (k, char d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(k == 0); assert(d == 'a'); break;\n            case 1:     assert(k == 1); assert(d == 0xE1); break;\n            case 2:     assert(k == 1); assert(d == 0x88); break;\n            case 3:     assert(k == 1); assert(d == 0xB4); break;\n            case 4:     assert(k == 2); assert(d == 0xF2); break;\n            case 5:     assert(k == 2); assert(d == 0xA0); break;\n            case 6:     assert(k == 2); assert(d == 0x91); break;\n            case 7:     assert(k == 2); assert(d == 0x96); break;\n            case 8:     assert(k == 3); assert(d == 'b'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 9);\n}\n\n/*****************************/\n\nextern (C) int _aApplydw2(in dchar[] aa, dg2_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplydw2(), len = %d\\n\", aa.length);\n    foreach (size_t i, dchar d; aa)\n    {\n        wchar w;\n        auto j = i;\n\n        if (d <= 0xFFFF)\n            w = cast(wchar) d;\n        else\n        {\n            w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);\n            result = dg(&j, cast(void *)&w);\n            if (result)\n                break;\n            w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);\n        }\n        result = dg(&j, cast(void *)&w);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplydw2.unittest\\n\");\n\n    auto s = \"hello\"d[];\n    int i;\n\n    foreach (k, wchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        assert(k == i);\n        switch (i)\n        {\n            case 0:     assert(d == 'h'); break;\n            case 1:     assert(d == 'e'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'l'); break;\n            case 4:     assert(d == 'o'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach (k, wchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(k == 0); assert(d == 'a'); break;\n            case 1:     assert(k == 1); assert(d == 0x1234); break;\n            case 2:     assert(k == 2); assert(d == 0xDA41); break;\n            case 3:     assert(k == 2); assert(d == 0xDC56); break;\n            case 4:     assert(k == 3); assert(d == 'b'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/aApplyR.d",
    "content": "/**\n * This code handles decoding UTF strings for foreach_reverse loops.  There are\n * 6 combinations of conversions between char, wchar, and dchar, and 2 of each\n * of those.\n *\n * Copyright: Copyright Digital Mars 2004 - 2010.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, Sean Kelly\n */\n\n/*          Copyright Digital Mars 2004 - 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.aApplyR;\n\n/* This code handles decoding UTF strings for foreach_reverse loops.\n * There are 6 combinations of conversions between char, wchar,\n * and dchar, and 2 of each of those.\n */\n\nprivate import rt.util.utf;\n\n/**********************************************/\n/* 1 argument versions */\n\n// dg is D, but _aApplyRcd() is C\nextern (D) alias int delegate(void *) dg_t;\n\nextern (C) int _aApplyRcd1(in char[] aa, dg_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplyRcd1(), len = %d\\n\", aa.length);\n    for (size_t i = aa.length; i != 0; )\n    {   dchar d;\n\n        i--;\n        d = aa[i];\n        if (d & 0x80)\n        {   char c = cast(char)d;\n            uint j;\n            uint m = 0x3F;\n            d = 0;\n            while ((c & 0xC0) != 0xC0)\n            {   if (i == 0)\n                    onUnicodeError(\"Invalid UTF-8 sequence\", 0);\n                i--;\n                d |= (c & 0x3F) << j;\n                j += 6;\n                m >>= 1;\n                c = aa[i];\n            }\n            d |= (c & m) << j;\n        }\n        result = dg(cast(void *)&d);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRcd1.unittest\\n\");\n\n    auto s = \"hello\"c[];\n    int i;\n\n    foreach_reverse (dchar d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (dchar d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'b'); break;\n            case 1:     assert(d == '\\U000A0456'); break;\n            case 2:     assert(d == '\\u1234'); break;\n            case 3:     assert(d == 'a'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 4);\n}\n\n/*****************************/\n\nextern (C) int _aApplyRwd1(in wchar[] aa, dg_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplyRwd1(), len = %d\\n\", aa.length);\n    for (size_t i = aa.length; i != 0; )\n    {   dchar d;\n\n        i--;\n        d = aa[i];\n        if (d >= 0xDC00 && d <= 0xDFFF)\n        {   if (i == 0)\n                onUnicodeError(\"Invalid UTF-16 sequence\", 0);\n            i--;\n            d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);\n        }\n        result = dg(cast(void *)&d);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRwd1.unittest\\n\");\n\n    auto s = \"hello\"w[];\n    int i;\n\n    foreach_reverse (dchar d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (dchar d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'b'); break;\n            case 1:     assert(d == '\\U000A0456'); break;\n            case 2:     assert(d == '\\u1234'); break;\n            case 3:     assert(d == 'a'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 4);\n}\n\n/*****************************/\n\nextern (C) int _aApplyRcw1(in char[] aa, dg_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplyRcw1(), len = %d\\n\", aa.length);\n    for (size_t i = aa.length; i != 0; )\n    {   dchar d;\n        wchar w;\n\n        i--;\n        w = aa[i];\n        if (w & 0x80)\n        {   char c = cast(char)w;\n            uint j;\n            uint m = 0x3F;\n            d = 0;\n            while ((c & 0xC0) != 0xC0)\n            {   if (i == 0)\n                    onUnicodeError(\"Invalid UTF-8 sequence\", 0);\n                i--;\n                d |= (c & 0x3F) << j;\n                j += 6;\n                m >>= 1;\n                c = aa[i];\n            }\n            d |= (c & m) << j;\n\n            if (d <= 0xFFFF)\n                w = cast(wchar) d;\n            else\n            {\n                w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);\n                result = dg(cast(void *)&w);\n                if (result)\n                    break;\n                w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);\n            }\n        }\n        result = dg(cast(void *)&w);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRcw1.unittest\\n\");\n\n    auto s = \"hello\"c[];\n    int i;\n\n    foreach_reverse (wchar d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (wchar d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'b'); break;\n            case 1:     assert(d == 0xDA41); break;\n            case 2:     assert(d == 0xDC56); break;\n            case 3:     assert(d == 0x1234); break;\n            case 4:     assert(d == 'a'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n}\n\n/*****************************/\n\nextern (C) int _aApplyRwc1(in wchar[] aa, dg_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplyRwc1(), len = %d\\n\", aa.length);\n    for (size_t i = aa.length; i != 0; )\n    {   dchar d;\n        char c;\n\n        i--;\n        d = aa[i];\n        if (d >= 0xDC00 && d <= 0xDFFF)\n        {   if (i == 0)\n                onUnicodeError(\"Invalid UTF-16 sequence\", 0);\n            i--;\n            d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);\n        }\n\n        if (d & ~0x7F)\n        {\n            char[4] buf;\n\n            auto b = toUTF8(buf, d);\n            foreach (char c2; b)\n            {\n                result = dg(cast(void *)&c2);\n                if (result)\n                    return result;\n            }\n            continue;\n        }\n        c = cast(char)d;\n        result = dg(cast(void *)&c);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRwc1.unittest\\n\");\n\n    auto s = \"hello\"w[];\n    int i;\n\n    foreach_reverse (char d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (char d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'b'); break;\n            case 1:     assert(d == 0xF2); break;\n            case 2:     assert(d == 0xA0); break;\n            case 3:     assert(d == 0x91); break;\n            case 4:     assert(d == 0x96); break;\n            case 5:     assert(d == 0xE1); break;\n            case 6:     assert(d == 0x88); break;\n            case 7:     assert(d == 0xB4); break;\n            case 8:     assert(d == 'a'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 9);\n}\n\n/*****************************/\n\nextern (C) int _aApplyRdc1(in dchar[] aa, dg_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplyRdc1(), len = %d\\n\", aa.length);\n    for (size_t i = aa.length; i != 0;)\n    {   dchar d = aa[--i];\n        char c;\n\n        if (d & ~0x7F)\n        {\n            char[4] buf;\n\n            auto b = toUTF8(buf, d);\n            foreach (char c2; b)\n            {\n                result = dg(cast(void *)&c2);\n                if (result)\n                    return result;\n            }\n            continue;\n        }\n        else\n        {\n            c = cast(char)d;\n        }\n        result = dg(cast(void *)&c);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRdc1.unittest\\n\");\n\n    auto s = \"hello\"d[];\n    int i;\n\n    foreach_reverse (char d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (char d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'b'); break;\n            case 1:     assert(d == 0xF2); break;\n            case 2:     assert(d == 0xA0); break;\n            case 3:     assert(d == 0x91); break;\n            case 4:     assert(d == 0x96); break;\n            case 5:     assert(d == 0xE1); break;\n            case 6:     assert(d == 0x88); break;\n            case 7:     assert(d == 0xB4); break;\n            case 8:     assert(d == 'a'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 9);\n}\n\n/*****************************/\n\nextern (C) int _aApplyRdw1(in dchar[] aa, dg_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplyRdw1(), len = %d\\n\", aa.length);\n    for (size_t i = aa.length; i != 0; )\n    {   dchar d = aa[--i];\n        wchar w;\n\n        if (d <= 0xFFFF)\n            w = cast(wchar) d;\n        else\n        {\n            w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);\n            result = dg(cast(void *)&w);\n            if (result)\n                break;\n            w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);\n        }\n        result = dg(cast(void *)&w);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRdw1.unittest\\n\");\n\n    auto s = \"hello\"d[];\n    int i;\n\n    foreach_reverse (wchar d; s)\n    {\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (wchar d; s)\n    {\n        //printf(\"i = %d, d = %x\\n\", i, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'b'); break;\n            case 1:     assert(d == 0xDA41); break;\n            case 2:     assert(d == 0xDC56); break;\n            case 3:     assert(d == 0x1234); break;\n            case 4:     assert(d == 'a'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n}\n\n\n/****************************************************************************/\n/* 2 argument versions */\n\n// dg is D, but _aApplyRcd2() is C\nextern (D) alias int delegate(void *, void *) dg2_t;\n\nextern (C) int _aApplyRcd2(in char[] aa, dg2_t dg)\n{   int result;\n    size_t i;\n    size_t len = aa.length;\n\n    debug(apply) printf(\"_aApplyRcd2(), len = %d\\n\", len);\n    for (i = len; i != 0; )\n    {   dchar d;\n\n        i--;\n        d = aa[i];\n        if (d & 0x80)\n        {   char c = cast(char)d;\n            uint j;\n            uint m = 0x3F;\n            d = 0;\n            while ((c & 0xC0) != 0xC0)\n            {   if (i == 0)\n                    onUnicodeError(\"Invalid UTF-8 sequence\", 0);\n                i--;\n                d |= (c & 0x3F) << j;\n                j += 6;\n                m >>= 1;\n                c = aa[i];\n            }\n            d |= (c & m) << j;\n        }\n        result = dg(&i, cast(void *)&d);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRcd2.unittest\\n\");\n\n    auto s = \"hello\"c[];\n    int i;\n\n    foreach_reverse (k, dchar d; s)\n    {\n        assert(k == 4 - i);\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (k, dchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(d == 'b'); assert(k == 8); break;\n            case 1:     assert(d == '\\U000A0456'); assert(k == 4); break;\n            case 2:     assert(d == '\\u1234'); assert(k == 1); break;\n            case 3:     assert(d == 'a'); assert(k == 0); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 4);\n}\n\n/*****************************/\n\nextern (C) int _aApplyRwd2(in wchar[] aa, dg2_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplyRwd2(), len = %d\\n\", aa.length);\n    for (size_t i = aa.length; i != 0; )\n    {   dchar d;\n\n        i--;\n        d = aa[i];\n        if (d >= 0xDC00 && d <= 0xDFFF)\n        {   if (i == 0)\n                onUnicodeError(\"Invalid UTF-16 sequence\", 0);\n            i--;\n            d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);\n        }\n        result = dg(&i, cast(void *)&d);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRwd2.unittest\\n\");\n\n    auto s = \"hello\"w[];\n    int i;\n\n    foreach_reverse (k, dchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        assert(k == 4 - i);\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (k, dchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(k == 4); assert(d == 'b'); break;\n            case 1:     assert(k == 2); assert(d == '\\U000A0456'); break;\n            case 2:     assert(k == 1); assert(d == '\\u1234'); break;\n            case 3:     assert(k == 0); assert(d == 'a'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 4);\n}\n\n/*****************************/\n\nextern (C) int _aApplyRcw2(in char[] aa, dg2_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplyRcw2(), len = %d\\n\", aa.length);\n    for (size_t i = aa.length; i != 0; )\n    {   dchar d;\n        wchar w;\n\n        i--;\n        w = aa[i];\n        if (w & 0x80)\n        {   char c = cast(char)w;\n            uint j;\n            uint m = 0x3F;\n            d = 0;\n            while ((c & 0xC0) != 0xC0)\n            {   if (i == 0)\n                    onUnicodeError(\"Invalid UTF-8 sequence\", 0);\n                i--;\n                d |= (c & 0x3F) << j;\n                j += 6;\n                m >>= 1;\n                c = aa[i];\n            }\n            d |= (c & m) << j;\n\n            if (d <= 0xFFFF)\n                w = cast(wchar) d;\n            else\n            {\n                w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);\n                result = dg(&i, cast(void *)&w);\n                if (result)\n                    break;\n                w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);\n            }\n        }\n        result = dg(&i, cast(void *)&w);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRcw2.unittest\\n\");\n\n    auto s = \"hello\"c[];\n    int i;\n\n    foreach_reverse (k, wchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        assert(k == 4 - i);\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (k, wchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(k == 8); assert(d == 'b'); break;\n            case 1:     assert(k == 4); assert(d == 0xDA41); break;\n            case 2:     assert(k == 4); assert(d == 0xDC56); break;\n            case 3:     assert(k == 1); assert(d == 0x1234); break;\n            case 4:     assert(k == 0); assert(d == 'a'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n}\n\n/*****************************/\n\nextern (C) int _aApplyRwc2(in wchar[] aa, dg2_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplyRwc2(), len = %d\\n\", aa.length);\n    for (size_t i = aa.length; i != 0; )\n    {   dchar d;\n        char c;\n\n        i--;\n        d = aa[i];\n        if (d >= 0xDC00 && d <= 0xDFFF)\n        {   if (i == 0)\n                onUnicodeError(\"Invalid UTF-16 sequence\", 0);\n            i--;\n            d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);\n        }\n\n        if (d & ~0x7F)\n        {\n            char[4] buf;\n\n            auto b = toUTF8(buf, d);\n            foreach (char c2; b)\n            {\n                result = dg(&i, cast(void *)&c2);\n                if (result)\n                    return result;\n            }\n            continue;\n        }\n        c = cast(char)d;\n        result = dg(&i, cast(void *)&c);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRwc2.unittest\\n\");\n\n    auto s = \"hello\"w[];\n    int i;\n\n    foreach_reverse (k, char d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        assert(k == 4 - i);\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (k, char d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(k == 4); assert(d == 'b'); break;\n            case 1:     assert(k == 2); assert(d == 0xF2); break;\n            case 2:     assert(k == 2); assert(d == 0xA0); break;\n            case 3:     assert(k == 2); assert(d == 0x91); break;\n            case 4:     assert(k == 2); assert(d == 0x96); break;\n            case 5:     assert(k == 1); assert(d == 0xE1); break;\n            case 6:     assert(k == 1); assert(d == 0x88); break;\n            case 7:     assert(k == 1); assert(d == 0xB4); break;\n            case 8:     assert(k == 0); assert(d == 'a'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 9);\n}\n\n/*****************************/\n\nextern (C) int _aApplyRdc2(in dchar[] aa, dg2_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplyRdc2(), len = %d\\n\", aa.length);\n    for (size_t i = aa.length; i != 0; )\n    {   dchar d = aa[--i];\n        char c;\n\n        if (d & ~0x7F)\n        {\n            char[4] buf;\n\n            auto b = toUTF8(buf, d);\n            foreach (char c2; b)\n            {\n                result = dg(&i, cast(void *)&c2);\n                if (result)\n                    return result;\n            }\n            continue;\n        }\n        else\n        {   c = cast(char)d;\n        }\n        result = dg(&i, cast(void *)&c);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRdc2.unittest\\n\");\n\n    auto s = \"hello\"d[];\n    int i;\n\n    foreach_reverse (k, char d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        assert(k == 4 - i);\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (k, char d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(k == 3); assert(d == 'b'); break;\n            case 1:     assert(k == 2); assert(d == 0xF2); break;\n            case 2:     assert(k == 2); assert(d == 0xA0); break;\n            case 3:     assert(k == 2); assert(d == 0x91); break;\n            case 4:     assert(k == 2); assert(d == 0x96); break;\n            case 5:     assert(k == 1); assert(d == 0xE1); break;\n            case 6:     assert(k == 1); assert(d == 0x88); break;\n            case 7:     assert(k == 1); assert(d == 0xB4); break;\n            case 8:     assert(k == 0); assert(d == 'a'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 9);\n}\n\n/*****************************/\n\nextern (C) int _aApplyRdw2(in dchar[] aa, dg2_t dg)\n{   int result;\n\n    debug(apply) printf(\"_aApplyRdw2(), len = %d\\n\", aa.length);\n    for (size_t i = aa.length; i != 0; )\n    {   dchar d = aa[--i];\n        wchar w;\n\n        if (d <= 0xFFFF)\n            w = cast(wchar) d;\n        else\n        {\n            w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);\n            result = dg(&i, cast(void *)&w);\n            if (result)\n                break;\n            w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);\n        }\n        result = dg(&i, cast(void *)&w);\n        if (result)\n            break;\n    }\n    return result;\n}\n\nunittest\n{\n    debug(apply) printf(\"_aApplyRdw2.unittest\\n\");\n\n    auto s = \"hello\"d[];\n    int i;\n\n    foreach_reverse (k, wchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        assert(k == 4 - i);\n        switch (i)\n        {\n            case 0:     assert(d == 'o'); break;\n            case 1:     assert(d == 'l'); break;\n            case 2:     assert(d == 'l'); break;\n            case 3:     assert(d == 'e'); break;\n            case 4:     assert(d == 'h'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n\n    s = \"a\\u1234\\U000A0456b\";\n    i = 0;\n    foreach_reverse (k, wchar d; s)\n    {\n        //printf(\"i = %d, k = %d, d = %x\\n\", i, k, d);\n        switch (i)\n        {\n            case 0:     assert(k == 3); assert(d == 'b'); break;\n            case 1:     assert(k == 2); assert(d == 0xDA41); break;\n            case 2:     assert(k == 2); assert(d == 0xDC56); break;\n            case 3:     assert(k == 1); assert(d == 0x1234); break;\n            case 4:     assert(k == 0); assert(d == 'a'); break;\n            default:    assert(0);\n        }\n        i++;\n    }\n    assert(i == 5);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/aaA.d",
    "content": "/**\n * Implementation of associative arrays.\n *\n * Copyright: Copyright Digital Mars 2000 - 2015.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n */\nmodule rt.aaA;\n\n/// AA version for debuggers, bump whenever changing the layout\nextern (C) immutable int _aaVersion = 1;\n\nimport core.memory : GC;\n\n// grow threshold\nprivate enum GROW_NUM = 4;\nprivate enum GROW_DEN = 5;\n// shrink threshold\nprivate enum SHRINK_NUM = 1;\nprivate enum SHRINK_DEN = 8;\n// grow factor\nprivate enum GROW_FAC = 4;\n// growing the AA doubles it's size, so the shrink threshold must be\n// smaller than half the grow threshold to have a hysteresis\nstatic assert(GROW_FAC * SHRINK_NUM * GROW_DEN < GROW_NUM * SHRINK_DEN);\n// initial load factor (for literals), mean of both thresholds\nprivate enum INIT_NUM = (GROW_DEN * SHRINK_NUM + GROW_NUM * SHRINK_DEN) / 2;\nprivate enum INIT_DEN = SHRINK_DEN * GROW_DEN;\n\nprivate enum INIT_NUM_BUCKETS = 8;\n// magic hash constants to distinguish empty, deleted, and filled buckets\nprivate enum HASH_EMPTY = 0;\nprivate enum HASH_DELETED = 0x1;\nprivate enum HASH_FILLED_MARK = size_t(1) << 8 * size_t.sizeof - 1;\n\n/// Opaque AA wrapper\nstruct AA\n{\n    Impl* impl;\n    alias impl this;\n\n    private @property bool empty() const pure nothrow @nogc\n    {\n        return impl is null || !impl.length;\n    }\n}\n\nprivate struct Impl\n{\nprivate:\n    this(in TypeInfo_AssociativeArray ti, size_t sz = INIT_NUM_BUCKETS)\n    {\n        keysz = cast(uint) ti.key.tsize;\n        valsz = cast(uint) ti.value.tsize;\n        buckets = allocBuckets(sz);\n        firstUsed = cast(uint) buckets.length;\n        entryTI = fakeEntryTI(ti.key, ti.value);\n        valoff = cast(uint) talign(keysz, ti.value.talign);\n\n        import rt.lifetime : hasPostblit, unqualify;\n\n        if (hasPostblit(unqualify(ti.key)))\n            flags |= Flags.keyHasPostblit;\n        if ((ti.key.flags | ti.value.flags) & 1)\n            flags |= Flags.hasPointers;\n    }\n\n    Bucket[] buckets;\n    uint used;\n    uint deleted;\n    TypeInfo_Struct entryTI;\n    uint firstUsed;\n    immutable uint keysz;\n    immutable uint valsz;\n    immutable uint valoff;\n    Flags flags;\n\n    enum Flags : ubyte\n    {\n        none = 0x0,\n        keyHasPostblit = 0x1,\n        hasPointers = 0x2,\n    }\n\n    @property size_t length() const pure nothrow @nogc\n    {\n        assert(used >= deleted);\n        return used - deleted;\n    }\n\n    @property size_t dim() const pure nothrow @nogc @safe\n    {\n        return buckets.length;\n    }\n\n    @property size_t mask() const pure nothrow @nogc\n    {\n        return dim - 1;\n    }\n\n    // find the first slot to insert a value with hash\n    inout(Bucket)* findSlotInsert(size_t hash) inout pure nothrow @nogc\n    {\n        for (size_t i = hash & mask, j = 1;; ++j)\n        {\n            if (!buckets[i].filled)\n                return &buckets[i];\n            i = (i + j) & mask;\n        }\n    }\n\n    // lookup a key\n    inout(Bucket)* findSlotLookup(size_t hash, in void* pkey, in TypeInfo keyti) inout\n    {\n        for (size_t i = hash & mask, j = 1;; ++j)\n        {\n            if (buckets[i].hash == hash && keyti.equals(pkey, buckets[i].entry))\n                return &buckets[i];\n            else if (buckets[i].empty)\n                return null;\n            i = (i + j) & mask;\n        }\n    }\n\n    void grow(in TypeInfo keyti)\n    {\n        // If there are so many deleted entries, that growing would push us\n        // below the shrink threshold, we just purge deleted entries instead.\n        if (length * SHRINK_DEN < GROW_FAC * dim * SHRINK_NUM)\n            resize(dim);\n        else\n            resize(GROW_FAC * dim);\n    }\n\n    void shrink(in TypeInfo keyti)\n    {\n        if (dim > INIT_NUM_BUCKETS)\n            resize(dim / GROW_FAC);\n    }\n\n    void resize(size_t ndim) pure nothrow\n    {\n        auto obuckets = buckets;\n        buckets = allocBuckets(ndim);\n\n        foreach (ref b; obuckets[firstUsed .. $])\n            if (b.filled)\n                *findSlotInsert(b.hash) = b;\n\n        firstUsed = 0;\n        used -= deleted;\n        deleted = 0;\n        GC.free(obuckets.ptr); // safe to free b/c impossible to reference\n    }\n\n    void clear() pure nothrow\n    {\n        import core.stdc.string : memset;\n        // clear all data, but don't change bucket array length\n        memset(&buckets[firstUsed], 0, (buckets.length - firstUsed) * Bucket.sizeof);\n        deleted = used = 0;\n        firstUsed = cast(uint) dim;\n    }\n}\n\n//==============================================================================\n// Bucket\n//------------------------------------------------------------------------------\n\nprivate struct Bucket\n{\nprivate pure nothrow @nogc:\n    size_t hash;\n    void* entry;\n\n    @property bool empty() const\n    {\n        return hash == HASH_EMPTY;\n    }\n\n    @property bool deleted() const\n    {\n        return hash == HASH_DELETED;\n    }\n\n    @property bool filled() const @safe\n    {\n        return cast(ptrdiff_t) hash < 0;\n    }\n}\n\nBucket[] allocBuckets(size_t dim) @trusted pure nothrow\n{\n    enum attr = GC.BlkAttr.NO_INTERIOR;\n    immutable sz = dim * Bucket.sizeof;\n    return (cast(Bucket*) GC.calloc(sz, attr))[0 .. dim];\n}\n\n//==============================================================================\n// Entry\n//------------------------------------------------------------------------------\n\nprivate void* allocEntry(in Impl* aa, in void* pkey)\n{\n    import rt.lifetime : _d_newitemU;\n    import core.stdc.string : memcpy, memset;\n\n    immutable akeysz = aa.valoff;\n    void* res = void;\n    if (aa.entryTI)\n        res = _d_newitemU(aa.entryTI);\n    else\n    {\n        auto flags = (aa.flags & Impl.Flags.hasPointers) ? 0 : GC.BlkAttr.NO_SCAN;\n        res = GC.malloc(akeysz + aa.valsz, flags);\n    }\n\n    memcpy(res, pkey, aa.keysz); // copy key\n    memset(res + akeysz, 0, aa.valsz); // zero value\n\n    return res;\n}\n\npackage void entryDtor(void* p, const TypeInfo_Struct sti)\n{\n    // key and value type info stored after the TypeInfo_Struct by tiEntry()\n    auto sizeti = __traits(classInstanceSize, TypeInfo_Struct);\n    auto extra = cast(const(TypeInfo)*)(cast(void*) sti + sizeti);\n    extra[0].destroy(p);\n    extra[1].destroy(p + talign(extra[0].tsize, extra[1].talign));\n}\n\nprivate bool hasDtor(const TypeInfo ti)\n{\n    import rt.lifetime : unqualify;\n\n    if (typeid(ti) is typeid(TypeInfo_Struct))\n        if ((cast(TypeInfo_Struct) cast(void*) ti).xdtor)\n            return true;\n    if (typeid(ti) is typeid(TypeInfo_StaticArray))\n        return hasDtor(unqualify(ti.next));\n\n    return false;\n}\n\n// build type info for Entry with additional key and value fields\nTypeInfo_Struct fakeEntryTI(const TypeInfo keyti, const TypeInfo valti)\n{\n    import rt.lifetime : unqualify;\n\n    auto kti = unqualify(keyti);\n    auto vti = unqualify(valti);\n    if (!hasDtor(kti) && !hasDtor(vti))\n        return null;\n\n    // save kti and vti after type info for struct\n    enum sizeti = __traits(classInstanceSize, TypeInfo_Struct);\n    void* p = GC.malloc(sizeti + 2 * (void*).sizeof);\n    import core.stdc.string : memcpy;\n\n    memcpy(p, typeid(TypeInfo_Struct).initializer().ptr, sizeti);\n\n    auto ti = cast(TypeInfo_Struct) p;\n    auto extra = cast(TypeInfo*)(p + sizeti);\n    extra[0] = cast() kti;\n    extra[1] = cast() vti;\n\n    static immutable tiName = __MODULE__ ~ \".Entry!(...)\";\n    ti.name = tiName;\n\n    // we don't expect the Entry objects to be used outside of this module, so we have control\n    // over the non-usage of the callback methods and other entries and can keep these null\n    // xtoHash, xopEquals, xopCmp, xtoString and xpostblit\n    ti.m_RTInfo = null;\n    immutable entrySize = talign(kti.tsize, vti.talign) + vti.tsize;\n    ti.m_init = (cast(ubyte*) null)[0 .. entrySize]; // init length, but not ptr\n\n    // xdtor needs to be built from the dtors of key and value for the GC\n    ti.xdtorti = &entryDtor;\n\n    ti.m_flags = TypeInfo_Struct.StructFlags.isDynamicType;\n    ti.m_flags |= (keyti.flags | valti.flags) & TypeInfo_Struct.StructFlags.hasPointers;\n    ti.m_align = cast(uint) max(kti.talign, vti.talign);\n\n    return ti;\n}\n\n//==============================================================================\n// Helper functions\n//------------------------------------------------------------------------------\n\nprivate size_t talign(size_t tsize, size_t algn) @safe pure nothrow @nogc\n{\n    immutable mask = algn - 1;\n    assert(!(mask & algn));\n    return (tsize + mask) & ~mask;\n}\n\n// mix hash to \"fix\" bad hash functions\nprivate size_t mix(size_t h) @safe pure nothrow @nogc\n{\n    // final mix function of MurmurHash2\n    enum m = 0x5bd1e995;\n    h ^= h >> 13;\n    h *= m;\n    h ^= h >> 15;\n    return h;\n}\n\nprivate size_t calcHash(in void* pkey, in TypeInfo keyti)\n{\n    immutable hash = keyti.getHash(pkey);\n    // highest bit is set to distinguish empty/deleted from filled buckets\n    return mix(hash) | HASH_FILLED_MARK;\n}\n\nprivate size_t nextpow2(in size_t n) pure nothrow @nogc\n{\n    import core.bitop : bsr;\n\n    if (!n)\n        return 1;\n\n    const isPowerOf2 = !((n - 1) & n);\n    return 1 << (bsr(n) + !isPowerOf2);\n}\n\npure nothrow @nogc unittest\n{\n    //                            0, 1, 2, 3, 4, 5, 6, 7, 8,  9\n    foreach (const n, const pow2; [1, 1, 2, 4, 4, 8, 8, 8, 8, 16])\n        assert(nextpow2(n) == pow2);\n}\n\nprivate T min(T)(T a, T b) pure nothrow @nogc\n{\n    return a < b ? a : b;\n}\n\nprivate T max(T)(T a, T b) pure nothrow @nogc\n{\n    return b < a ? a : b;\n}\n\n//==============================================================================\n// API Implementation\n//------------------------------------------------------------------------------\n\n/// Determine number of entries in associative array.\nextern (C) size_t _aaLen(in AA aa) pure nothrow @nogc\n{\n    return aa ? aa.length : 0;\n}\n\n/******************************\n * Lookup *pkey in aa.\n * Called only from implementation of (aa[key]) expressions when value is mutable.\n * Params:\n *      aa = associative array opaque pointer\n *      ti = TypeInfo for the associative array\n *      valsz = ignored\n *      pkey = pointer to the key value\n * Returns:\n *      if key was in the aa, a mutable pointer to the existing value.\n *      If key was not in the aa, a mutable pointer to newly inserted value which\n *      is set to all zeros\n */\nextern (C) void* _aaGetY(AA* aa, const TypeInfo_AssociativeArray ti,\n    in size_t valsz, in void* pkey)\n{\n    bool found;\n    return _aaGetX(aa, ti, valsz, pkey, found);\n}\n\n/******************************\n * Lookup *pkey in aa.\n * Called only from implementation of require\n * Params:\n *      aa = associative array opaque pointer\n *      ti = TypeInfo for the associative array\n *      valsz = ignored\n *      pkey = pointer to the key value\n *      found = true if the value was found\n * Returns:\n *      if key was in the aa, a mutable pointer to the existing value.\n *      If key was not in the aa, a mutable pointer to newly inserted value which\n *      is set to all zeros\n */\nextern (C) void* _aaGetX(AA* aa, const TypeInfo_AssociativeArray ti,\n    in size_t valsz, in void* pkey, out bool found)\n{\n    // lazily alloc implementation\n    if (aa.impl is null)\n        aa.impl = new Impl(ti);\n\n    // get hash and bucket for key\n    immutable hash = calcHash(pkey, ti.key);\n\n    // found a value => return it\n    if (auto p = aa.findSlotLookup(hash, pkey, ti.key))\n    {\n        found = true;\n        return p.entry + aa.valoff;\n    }\n\n    auto p = aa.findSlotInsert(hash);\n    if (p.deleted)\n        --aa.deleted;\n    // check load factor and possibly grow\n    else if (++aa.used * GROW_DEN > aa.dim * GROW_NUM)\n    {\n        aa.grow(ti.key);\n        p = aa.findSlotInsert(hash);\n        assert(p.empty);\n    }\n\n    // update search cache and allocate entry\n    aa.firstUsed = min(aa.firstUsed, cast(uint)(p - aa.buckets.ptr));\n    p.hash = hash;\n    p.entry = allocEntry(aa.impl, pkey);\n    // postblit for key\n    if (aa.flags & Impl.Flags.keyHasPostblit)\n    {\n        import rt.lifetime : __doPostblit, unqualify;\n\n        __doPostblit(p.entry, aa.keysz, unqualify(ti.key));\n    }\n    // return pointer to value\n    return p.entry + aa.valoff;\n}\n\n/******************************\n * Lookup *pkey in aa.\n * Called only from implementation of (aa[key]) expressions when value is not mutable.\n * Params:\n *      aa = associative array opaque pointer\n *      keyti = TypeInfo for the key\n *      valsz = ignored\n *      pkey = pointer to the key value\n * Returns:\n *      pointer to value if present, null otherwise\n */\nextern (C) inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz,\n    in void* pkey)\n{\n    return _aaInX(aa, keyti, pkey);\n}\n\n/******************************\n * Lookup *pkey in aa.\n * Called only from implementation of (key in aa) expressions.\n * Params:\n *      aa = associative array opaque pointer\n *      keyti = TypeInfo for the key\n *      pkey = pointer to the key value\n * Returns:\n *      pointer to value if present, null otherwise\n */\nextern (C) inout(void)* _aaInX(inout AA aa, in TypeInfo keyti, in void* pkey)\n{\n    if (aa.empty)\n        return null;\n\n    immutable hash = calcHash(pkey, keyti);\n    if (auto p = aa.findSlotLookup(hash, pkey, keyti))\n        return p.entry + aa.valoff;\n    return null;\n}\n\n/// Delete entry in AA, return true if it was present\nextern (C) bool _aaDelX(AA aa, in TypeInfo keyti, in void* pkey)\n{\n    if (aa.empty)\n        return false;\n\n    immutable hash = calcHash(pkey, keyti);\n    if (auto p = aa.findSlotLookup(hash, pkey, keyti))\n    {\n        // clear entry\n        p.hash = HASH_DELETED;\n        p.entry = null;\n\n        ++aa.deleted;\n        if (aa.length * SHRINK_DEN < aa.dim * SHRINK_NUM)\n            aa.shrink(keyti);\n\n        return true;\n    }\n    return false;\n}\n\n/// Remove all elements from AA.\nextern (C) void _aaClear(AA aa) pure nothrow\n{\n    if (!aa.empty)\n    {\n        aa.impl.clear();\n    }\n}\n\n/// Rehash AA\nextern (C) void* _aaRehash(AA* paa, in TypeInfo keyti) pure nothrow\n{\n    if (!paa.empty)\n        paa.resize(nextpow2(INIT_DEN * paa.length / INIT_NUM));\n    return *paa;\n}\n\n/// Return a GC allocated array of all values\nextern (C) inout(void[]) _aaValues(inout AA aa, in size_t keysz, in size_t valsz,\n    const TypeInfo tiValueArray) pure nothrow\n{\n    if (aa.empty)\n        return null;\n\n    import rt.lifetime : _d_newarrayU;\n\n    auto res = _d_newarrayU(tiValueArray, aa.length).ptr;\n    auto pval = res;\n\n    immutable off = aa.valoff;\n    foreach (b; aa.buckets[aa.firstUsed .. $])\n    {\n        if (!b.filled)\n            continue;\n        pval[0 .. valsz] = b.entry[off .. valsz + off];\n        pval += valsz;\n    }\n    // postblit is done in object.values\n    return (cast(inout(void)*) res)[0 .. aa.length]; // fake length, return number of elements\n}\n\n/// Return a GC allocated array of all keys\nextern (C) inout(void[]) _aaKeys(inout AA aa, in size_t keysz, const TypeInfo tiKeyArray) pure nothrow\n{\n    if (aa.empty)\n        return null;\n\n    import rt.lifetime : _d_newarrayU;\n\n    auto res = _d_newarrayU(tiKeyArray, aa.length).ptr;\n    auto pkey = res;\n\n    foreach (b; aa.buckets[aa.firstUsed .. $])\n    {\n        if (!b.filled)\n            continue;\n        pkey[0 .. keysz] = b.entry[0 .. keysz];\n        pkey += keysz;\n    }\n    // postblit is done in object.keys\n    return (cast(inout(void)*) res)[0 .. aa.length]; // fake length, return number of elements\n}\n\n// opApply callbacks are extern(D)\nextern (D) alias dg_t = int delegate(void*);\nextern (D) alias dg2_t = int delegate(void*, void*);\n\n/// foreach opApply over all values\nextern (C) int _aaApply(AA aa, in size_t keysz, dg_t dg)\n{\n    if (aa.empty)\n        return 0;\n\n    immutable off = aa.valoff;\n    foreach (b; aa.buckets)\n    {\n        if (!b.filled)\n            continue;\n        if (auto res = dg(b.entry + off))\n            return res;\n    }\n    return 0;\n}\n\n/// foreach opApply over all key/value pairs\nextern (C) int _aaApply2(AA aa, in size_t keysz, dg2_t dg)\n{\n    if (aa.empty)\n        return 0;\n\n    immutable off = aa.valoff;\n    foreach (b; aa.buckets)\n    {\n        if (!b.filled)\n            continue;\n        if (auto res = dg(b.entry, b.entry + off))\n            return res;\n    }\n    return 0;\n}\n\n/// Construct an associative array of type ti from keys and value\nextern (C) Impl* _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, void[] keys,\n    void[] vals)\n{\n    assert(keys.length == vals.length);\n\n    immutable keysz = ti.key.tsize;\n    immutable valsz = ti.value.tsize;\n    immutable length = keys.length;\n\n    if (!length)\n        return null;\n\n    auto aa = new Impl(ti, nextpow2(INIT_DEN * length / INIT_NUM));\n\n    void* pkey = keys.ptr;\n    void* pval = vals.ptr;\n    immutable off = aa.valoff;\n    uint actualLength = 0;\n    foreach (_; 0 .. length)\n    {\n        immutable hash = calcHash(pkey, ti.key);\n\n        auto p = aa.findSlotLookup(hash, pkey, ti.key);\n        if (p is null)\n        {\n            p = aa.findSlotInsert(hash);\n            p.hash = hash;\n            p.entry = allocEntry(aa, pkey); // move key, no postblit\n            aa.firstUsed = min(aa.firstUsed, cast(uint)(p - aa.buckets.ptr));\n            actualLength++;\n        }\n        else if (aa.entryTI && hasDtor(ti.value))\n        {\n            // destroy existing value before overwriting it\n            ti.value.destroy(p.entry + off);\n        }\n        // set hash and blit value\n        auto pdst = p.entry + off;\n        pdst[0 .. valsz] = pval[0 .. valsz]; // move value, no postblit\n\n        pkey += keysz;\n        pval += valsz;\n    }\n    aa.used = actualLength;\n    return aa;\n}\n\n/// compares 2 AAs for equality\nextern (C) int _aaEqual(in TypeInfo tiRaw, in AA aa1, in AA aa2)\n{\n    if (aa1.impl is aa2.impl)\n        return true;\n\n    immutable len = _aaLen(aa1);\n    if (len != _aaLen(aa2))\n        return false;\n\n    if (!len) // both empty\n        return true;\n\n    import rt.lifetime : unqualify;\n\n    auto uti = unqualify(tiRaw);\n    auto ti = *cast(TypeInfo_AssociativeArray*)&uti;\n    // compare the entries\n    immutable off = aa1.valoff;\n    foreach (b1; aa1.buckets)\n    {\n        if (!b1.filled)\n            continue;\n        auto pb2 = aa2.findSlotLookup(b1.hash, b1.entry, ti.key);\n        if (pb2 is null || !ti.value.equals(b1.entry + off, pb2.entry + off))\n            return false;\n    }\n    return true;\n}\n\n/// compute a hash\nextern (C) hash_t _aaGetHash(in AA* aa, in TypeInfo tiRaw) nothrow\n{\n    if (aa.empty)\n        return 0;\n\n    import rt.lifetime : unqualify;\n\n    auto uti = unqualify(tiRaw);\n    auto ti = *cast(TypeInfo_AssociativeArray*)&uti;\n    immutable off = aa.valoff;\n    auto keyHash = &ti.key.getHash;\n    auto valHash = &ti.value.getHash;\n\n    size_t h;\n    import core.stdc.stdio;\n    foreach (b; aa.buckets)\n    {\n        if (!b.filled)\n            continue;\n        size_t[2] h2 = [keyHash(b.entry), valHash(b.entry + off)];\n        // use addition here, so that hash is independent of element order\n        h += hashOf(h2);\n    }\n\n    return h;\n}\n\n/**\n * _aaRange implements a ForwardRange\n */\nstruct Range\n{\n    Impl* impl;\n    size_t idx;\n    alias impl this;\n}\n\nextern (C) pure nothrow @nogc @safe\n{\n    Range _aaRange(AA aa)\n    {\n        if (!aa)\n            return Range();\n\n        foreach (i; aa.firstUsed .. aa.dim)\n        {\n            if (aa.buckets[i].filled)\n                return Range(aa.impl, i);\n        }\n        return Range(aa, aa.dim);\n    }\n\n    bool _aaRangeEmpty(Range r)\n    {\n        return r.impl is null || r.idx >= r.dim;\n    }\n\n    void* _aaRangeFrontKey(Range r)\n    {\n        assert(!_aaRangeEmpty(r));\n        if (r.idx >= r.dim)\n            return null;\n        return r.buckets[r.idx].entry;\n    }\n\n    void* _aaRangeFrontValue(Range r)\n    {\n        assert(!_aaRangeEmpty(r));\n        if (r.idx >= r.dim)\n            return null;\n\n        auto entry = r.buckets[r.idx].entry;\n        return entry is null ?\n            null :\n            (() @trusted { return entry + r.valoff; } ());\n    }\n\n    void _aaRangePopFront(ref Range r)\n    {\n        if (r.idx >= r.dim) return;\n        for (++r.idx; r.idx < r.dim; ++r.idx)\n        {\n            if (r.buckets[r.idx].filled)\n                break;\n        }\n    }\n}\n\n// Most tests are now in in test_aa.d\n\n// test postblit for AA literals\nunittest\n{\n    static struct T\n    {\n        ubyte field;\n        static size_t postblit, dtor;\n        this(this)\n        {\n            ++postblit;\n        }\n\n        ~this()\n        {\n            ++dtor;\n        }\n    }\n\n    T t;\n    auto aa1 = [0 : t, 1 : t];\n    assert(T.dtor == 0 && T.postblit == 2);\n    aa1[0] = t;\n    assert(T.dtor == 1 && T.postblit == 3);\n\n    T.dtor = 0;\n    T.postblit = 0;\n\n    auto aa2 = [0 : t, 1 : t, 0 : t]; // literal with duplicate key => value overwritten\n    assert(T.dtor == 1 && T.postblit == 3);\n\n    T.dtor = 0;\n    T.postblit = 0;\n\n    auto aa3 = [t : 0];\n    assert(T.dtor == 0 && T.postblit == 1);\n    aa3[t] = 1;\n    assert(T.dtor == 0 && T.postblit == 1);\n    aa3.remove(t);\n    assert(T.dtor == 0 && T.postblit == 1);\n    aa3[t] = 2;\n    assert(T.dtor == 0 && T.postblit == 2);\n\n    // dtor will be called by GC finalizers\n    aa1 = null;\n    aa2 = null;\n    aa3 = null;\n    GC.runFinalizers((cast(char*)(&entryDtor))[0 .. 1]);\n    assert(T.dtor == 6 && T.postblit == 2);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/adi.d",
    "content": "/**\n * Implementation of dynamic array property support routines.\n *\n * Copyright: Copyright Digital Mars 2000 - 2015.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Walter Bright\n * Source: $(DRUNTIMESRC rt/_adi.d)\n */\n\nmodule rt.adi;\n\n//debug=adi;            // uncomment to turn on debugging printf's\n\nprivate\n{\n    debug(adi) import core.stdc.stdio;\n    import core.stdc.string;\n    import core.stdc.stdlib;\n    import core.memory;\n    import rt.util.utf;\n\n    extern (C) void[] _adSort(void[] a, TypeInfo ti);\n}\n\nprivate dchar[] mallocUTF32(C)(in C[] s)\n{\n    size_t j = 0;\n    auto p = cast(dchar*)malloc(dchar.sizeof * s.length);\n    auto r = p[0..s.length]; // r[] will never be longer than s[]\n    foreach (dchar c; s)\n        r[j++] = c;\n    return r[0 .. j];\n}\n\n/**********************************************\n * Sort array of chars.\n */\n\nextern (C) char[] _adSortChar(char[] a)\n{\n    if (a.length > 1)\n    {\n        auto da = mallocUTF32(a);\n        _adSort(*cast(void[]*)&da, typeid(da[0]));\n        size_t i = 0;\n        foreach (dchar d; da)\n        {   char[4] buf;\n            auto t = toUTF8(buf, d);\n            a[i .. i + t.length] = t[];\n            i += t.length;\n        }\n        free(da.ptr);\n    }\n    return a;\n}\n\n/**********************************************\n * Sort array of wchars.\n */\n\nextern (C) wchar[] _adSortWchar(wchar[] a)\n{\n    if (a.length > 1)\n    {\n        auto da = mallocUTF32(a);\n        _adSort(*cast(void[]*)&da, typeid(da[0]));\n        size_t i = 0;\n        foreach (dchar d; da)\n        {   wchar[2] buf;\n            auto t = toUTF16(buf, d);\n            a[i .. i + t.length] = t[];\n            i += t.length;\n        }\n        free(da.ptr);\n    }\n    return a;\n}\n\n/***************************************\n * Support for array equality test.\n * Returns:\n *      1       equal\n *      0       not equal\n */\n\nextern (C) int _adEq(void[] a1, void[] a2, TypeInfo ti)\n{\n    debug(adi) printf(\"_adEq(a1.length = %d, a2.length = %d)\\n\", a1.length, a2.length);\n    if (a1.length != a2.length)\n        return 0; // not equal\n    auto sz = ti.tsize;\n    auto p1 = a1.ptr;\n    auto p2 = a2.ptr;\n\n    if (sz == 1)\n        // We should really have a ti.isPOD() check for this\n        return (memcmp(p1, p2, a1.length) == 0);\n\n    for (size_t i = 0; i < a1.length; i++)\n    {\n        if (!ti.equals(p1 + i * sz, p2 + i * sz))\n            return 0; // not equal\n    }\n    return 1; // equal\n}\n\nextern (C) int _adEq2(void[] a1, void[] a2, TypeInfo ti)\n{\n    debug(adi) printf(\"_adEq2(a1.length = %d, a2.length = %d)\\n\", a1.length, a2.length);\n    if (a1.length != a2.length)\n        return 0;               // not equal\n    if (!ti.equals(&a1, &a2))\n        return 0;\n    return 1;\n}\nunittest\n{\n    debug(adi) printf(\"array.Eq unittest\\n\");\n\n    auto a = \"hello\"c;\n\n    assert(a != \"hel\");\n    assert(a != \"helloo\");\n    assert(a != \"betty\");\n    assert(a == \"hello\");\n    assert(a != \"hxxxx\");\n\n    float[] fa = [float.nan];\n    assert(fa != fa);\n}\n\nunittest\n{\n    debug(adi) printf(\"array.Cmp unittest\\n\");\n\n    auto a = \"hello\"c;\n\n    assert(a >  \"hel\");\n    assert(a >= \"hel\");\n    assert(a <  \"helloo\");\n    assert(a <= \"helloo\");\n    assert(a >  \"betty\");\n    assert(a >= \"betty\");\n    assert(a == \"hello\");\n    assert(a <= \"hello\");\n    assert(a >= \"hello\");\n    assert(a <  \"я\");\n}\n\nunittest\n{\n    debug(adi) printf(\"array.CmpChar unittest\\n\");\n\n    auto a = \"hello\"c;\n\n    assert(a >  \"hel\");\n    assert(a >= \"hel\");\n    assert(a <  \"helloo\");\n    assert(a <= \"helloo\");\n    assert(a >  \"betty\");\n    assert(a >= \"betty\");\n    assert(a == \"hello\");\n    assert(a <= \"hello\");\n    assert(a >= \"hello\");\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/arrayassign.d",
    "content": "/**\n * Implementation of array assignment support routines.\n *\n *\n * Copyright: Copyright Digital Mars 2010 - 2016.\n * License:   Distributed under the\n *            $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n * Authors:   Walter Bright, Kenji Hara\n * Source:    $(DRUNTIMESRC rt/_arrayassign.d)\n */\n\nmodule rt.arrayassign;\n\nprivate\n{\n    import rt.util.array;\n    import core.stdc.string;\n    import core.stdc.stdlib;\n    debug(PRINTF) import core.stdc.stdio;\n}\n\n/**\n * Keep for backward binary compatibility. This function can be removed in the future.\n */\nextern (C) void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to)\n{\n    debug(PRINTF) printf(\"_d_arrayassign(from = %p,%d, to = %p,%d) size = %d\\n\", from.ptr, from.length, to.ptr, to.length, ti.tsize);\n\n    immutable elementSize = ti.tsize;\n\n    // Need a temporary buffer tmp[] big enough to hold one element\n    void[16] buf = void;\n    void* ptmp = (elementSize > buf.sizeof) ? alloca(elementSize) : buf.ptr;\n    return _d_arrayassign_l(ti, from, to, ptmp);\n}\n\n/**\n * Does array assignment (not construction) from another\n * lvalue array of the same element type.\n * Handles overlapping copies.\n * Input:\n *      ti      TypeInfo of the element type.\n *      dst     Points target memory. Its .length is equal to the element count, not byte length.\n *      src     Points source memory. Its .length is equal to the element count, not byte length.\n *      ptmp    Temporary memory for element swapping.\n */\nextern (C) void[] _d_arrayassign_l(TypeInfo ti, void[] src, void[] dst, void* ptmp)\n{\n    debug(PRINTF) printf(\"_d_arrayassign_l(src = %p,%d, dst = %p,%d) size = %d\\n\", src.ptr, src.length, dst.ptr, dst.length, ti.tsize);\n\n    immutable elementSize = ti.tsize;\n\n    enforceRawArraysConformable(\"copy\", elementSize, src, dst, true);\n\n    if (src.ptr < dst.ptr && dst.ptr < src.ptr + elementSize * src.length)\n    {\n        // If dst is in the middle of src memory, use reverse order.\n        for (auto i = dst.length; i--; )\n        {\n            void* pdst = dst.ptr + i * elementSize;\n            void* psrc = src.ptr + i * elementSize;\n            memcpy(ptmp, pdst, elementSize);\n            memcpy(pdst, psrc, elementSize);\n            ti.postblit(pdst);\n            ti.destroy(ptmp);\n        }\n    }\n    else\n    {\n        // Otherwise, use normal order.\n        foreach (i; 0 .. dst.length)\n        {\n            void* pdst = dst.ptr + i * elementSize;\n            void* psrc = src.ptr + i * elementSize;\n            memcpy(ptmp, pdst, elementSize);\n            memcpy(pdst, psrc, elementSize);\n            ti.postblit(pdst);\n            ti.destroy(ptmp);\n        }\n    }\n    return dst;\n}\n\nunittest    // Bugzilla 14024\n{\n    string op;\n\n    struct S\n    {\n        char x = 'x';\n        this(this) { op ~= x-0x20; }    // upper case\n        ~this()    { op ~= x; }         // lower case\n    }\n\n    S[4] mem;\n    ref S[2] slice(int a, int b) { return mem[a .. b][0 .. 2]; }\n\n    op = null;\n    mem[0].x = 'a';\n    mem[1].x = 'b';\n    mem[2].x = 'x';\n    mem[3].x = 'y';\n    slice(0, 2) = slice(2, 4);  // [ab] = [xy]\n    assert(op == \"XaYb\", op);\n\n    op = null;\n    mem[0].x = 'x';\n    mem[1].x = 'y';\n    mem[2].x = 'a';\n    mem[3].x = 'b';\n    slice(2, 4) = slice(0, 2);  // [ab] = [xy]\n    assert(op == \"XaYb\", op);\n\n    op = null;\n    mem[0].x = 'a';\n    mem[1].x = 'b';\n    mem[2].x = 'c';\n    slice(0, 2) = slice(1, 3);  // [ab] = [bc]\n    assert(op == \"BaCb\", op);\n\n    op = null;\n    mem[0].x = 'x';\n    mem[1].x = 'y';\n    mem[2].x = 'z';\n    slice(1, 3) = slice(0, 2);  // [yz] = [xy]\n    assert(op == \"YzXy\", op);\n}\n\n/**\n * Does array assignment (not construction) from another\n * rvalue array of the same element type.\n * Input:\n *      ti      TypeInfo of the element type.\n *      dst     Points target memory. Its .length is equal to the element count, not byte length.\n *      src     Points source memory. Its .length is equal to the element count, not byte length.\n *              It is always allocated on stack and never overlapping with dst.\n *      ptmp    Temporary memory for element swapping.\n */\nextern (C) void[] _d_arrayassign_r(TypeInfo ti, void[] src, void[] dst, void* ptmp)\n{\n    debug(PRINTF) printf(\"_d_arrayassign_r(src = %p,%d, dst = %p,%d) size = %d\\n\", src.ptr, src.length, dst.ptr, dst.length, ti.tsize);\n\n    immutable elementSize = ti.tsize;\n\n    enforceRawArraysConformable(\"copy\", elementSize, src, dst, false);\n\n    // Always use normal order, because we can assume that\n    // the rvalue src has no overlapping with dst.\n    foreach (i; 0 .. dst.length)\n    {\n        void* pdst = dst.ptr + i * elementSize;\n        void* psrc = src.ptr + i * elementSize;\n        memcpy(ptmp, pdst, elementSize);\n        memcpy(pdst, psrc, elementSize);\n        ti.destroy(ptmp);\n    }\n    return dst;\n}\n\n/**\n * Does array initialization (not assignment) from another\n * array of the same element type.\n * ti is the element type.\n */\nextern (C) void[] _d_arrayctor(TypeInfo ti, void[] from, void[] to)\n{\n    debug(PRINTF) printf(\"_d_arrayctor(from = %p,%d, to = %p,%d) size = %d\\n\", from.ptr, from.length, to.ptr, to.length, ti.tsize);\n\n\n    auto element_size = ti.tsize;\n\n    enforceRawArraysConformable(\"initialization\", element_size, from, to);\n\n    size_t i;\n    try\n    {\n        for (i = 0; i < to.length; i++)\n        {\n            // Copy construction is defined as bit copy followed by postblit.\n            memcpy(to.ptr + i * element_size, from.ptr + i * element_size, element_size);\n            ti.postblit(to.ptr + i * element_size);\n        }\n    }\n    catch (Throwable o)\n    {\n        /* Destroy, in reverse order, what we've constructed so far\n         */\n        while (i--)\n        {\n            ti.destroy(to.ptr + i * element_size);\n        }\n\n        throw o;\n    }\n    return to;\n}\n\n\n/**\n * Do assignment to an array.\n *      p[0 .. count] = value;\n */\nextern (C) void* _d_arraysetassign(void* p, void* value, int count, TypeInfo ti)\n{\n    void* pstart = p;\n\n    auto element_size = ti.tsize;\n\n    //Need a temporary buffer tmp[] big enough to hold one element\n    void[16] buf = void;\n    void[] tmp;\n    if (element_size > buf.sizeof)\n    {\n        tmp = alloca(element_size)[0 .. element_size];\n    }\n    else\n        tmp = buf[];\n\n    foreach (i; 0 .. count)\n    {\n        memcpy(tmp.ptr, p, element_size);\n        memcpy(p, value, element_size);\n        ti.postblit(p);\n        ti.destroy(tmp.ptr);\n        p += element_size;\n    }\n    return pstart;\n}\n\n/**\n * Do construction of an array.\n *      ti[count] p = value;\n */\nextern (C) void* _d_arraysetctor(void* p, void* value, int count, TypeInfo ti)\n{\n    void* pstart = p;\n    auto element_size = ti.tsize;\n\n    try\n    {\n        foreach (i; 0 .. count)\n        {\n            // Copy construction is defined as bit copy followed by postblit.\n            memcpy(p, value, element_size);\n            ti.postblit(p);\n            p += element_size;\n        }\n    }\n    catch (Throwable o)\n    {\n        // Destroy, in reverse order, what we've constructed so far\n        while (p > pstart)\n        {\n            p -= element_size;\n            ti.destroy(p);\n        }\n\n        throw o;\n    }\n    return pstart;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/arraycast.d",
    "content": "/**\n * Implementation of array cast support routines.\n *\n * Copyright: Copyright Digital Mars 2004 - 2016.\n * License:   Distributed under the\n *            $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n * Authors:   Walter Bright, Sean Kelly\n * Source:    $(DRUNTIMESRC rt/_arraycast.d)\n */\n\nmodule rt.arraycast;\n\n/******************************************\n * Runtime helper to convert dynamic array of one\n * type to dynamic array of another.\n * Adjusts the length of the array.\n * Throws an error if new length is not aligned.\n */\n\nextern (C)\n\n@trusted nothrow\nvoid[] _d_arraycast(size_t tsize, size_t fsize, void[] a)\n{\n    auto length = a.length;\n\n    auto nbytes = length * fsize;\n    if (nbytes % tsize != 0)\n    {\n        throw new Error(\"array cast misalignment\");\n    }\n    length = nbytes / tsize;\n    *cast(size_t *)&a = length; // jam new length\n    return a;\n}\n\nunittest\n{\n    byte[int.sizeof * 3] b;\n    int[] i;\n    short[] s;\n\n    i = cast(int[])b;\n    assert(i.length == 3);\n\n    s = cast(short[])b;\n    assert(s.length == 6);\n\n    s = cast(short[])i;\n    assert(s.length == 6);\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/rt/arraycat.d",
    "content": "/**\n * Implementation of array copy support routines.\n *\n * Copyright: Copyright Digital Mars 2004 - 2016.\n * License:   Distributed under the\n *            $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n * Authors:   Walter Bright, Sean Kelly\n * Source:    $(DRUNTIMESRC rt/_arraycat.d)\n */\n\nmodule rt.arraycat;\n\nprivate\n{\n    import core.stdc.string;\n    import rt.util.array;\n    debug(PRINTF) import core.stdc.stdio;\n}\n\nextern (C) @trusted nothrow:\n\nvoid[] _d_arraycopy(size_t size, void[] from, void[] to)\n{\n    debug(PRINTF) printf(\"f = %p,%d, t = %p,%d, size = %d\\n\",\n                 from.ptr, from.length, to.ptr, to.length, size);\n\n    enforceRawArraysConformable(\"copy\", size, from, to);\n    memcpy(to.ptr, from.ptr, to.length * size);\n    return to;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/cast_.d",
    "content": "/**\n * Implementation of array assignment support routines.\n *\n * Copyright: Copyright Digital Mars 2004 - 2010.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, Sean Kelly\n */\n\n/*          Copyright Digital Mars 2004 - 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.cast_;\n\nextern (C):\n\n/******************************************\n * Given a pointer:\n *      If it is an Object, return that Object.\n *      If it is an interface, return the Object implementing the interface.\n *      If it is null, return null.\n *      Else, undefined crash\n */\nObject _d_toObject(void* p)\n{\n    if (!p)\n        return null;\n\n    Object o = cast(Object) p;\n    ClassInfo oc = typeid(o);\n    Interface* pi = **cast(Interface***) p;\n\n    /* Interface.offset lines up with ClassInfo.name.ptr,\n     * so we rely on pointers never being less than 64K,\n     * and Objects never being greater.\n     */\n    if (pi.offset < 0x10000)\n    {\n        debug(cast_) printf(\"\\tpi.offset = %d\\n\", pi.offset);\n        return cast(Object)(p - pi.offset);\n    }\n    return o;\n}\n\n/*************************************\n * Attempts to cast Object o to class c.\n * Returns o if successful, null if not.\n */\nvoid* _d_interface_cast(void* p, ClassInfo c)\n{\n    debug(cast_) printf(\"_d_interface_cast(p = %p, c = '%.*s')\\n\", p, c.name);\n    if (!p)\n        return null;\n\n    Interface* pi = **cast(Interface***) p;\n\n    debug(cast_) printf(\"\\tpi.offset = %d\\n\", pi.offset);\n    return _d_dynamic_cast(cast(Object)(p - pi.offset), c);\n}\n\nvoid* _d_dynamic_cast(Object o, ClassInfo c)\n{\n    debug(cast_) printf(\"_d_dynamic_cast(o = %p, c = '%.*s')\\n\", o, c.name);\n\n    void* res = null;\n    size_t offset = 0;\n    if (o && _d_isbaseof2(typeid(o), c, offset))\n    {\n        debug(cast_) printf(\"\\toffset = %d\\n\", offset);\n        res = cast(void*) o + offset;\n    }\n    debug(cast_) printf(\"\\tresult = %p\\n\", res);\n    return res;\n}\n\nint _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset)\n{\n    if (oc is c)\n        return true;\n\n    do\n    {\n        if (oc.base is c)\n            return true;\n\n        // Bugzilla 2013: Use depth-first search to calculate offset\n        // from the derived (oc) to the base (c).\n        foreach (iface; oc.interfaces)\n        {\n            if (iface.classinfo is c || _d_isbaseof2(iface.classinfo, c, offset))\n            {\n                offset += iface.offset;\n                return true;\n            }\n        }\n\n        oc = oc.base;\n    } while (oc);\n\n    return false;\n}\n\nint _d_isbaseof(ClassInfo oc, ClassInfo c)\n{\n    if (oc is c)\n        return true;\n\n    do\n    {\n        if (oc.base is c)\n            return true;\n\n        foreach (iface; oc.interfaces)\n        {\n            if (iface.classinfo is c || _d_isbaseof(iface.classinfo, c))\n                return true;\n        }\n\n        oc = oc.base;\n    } while (oc);\n\n    return false;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/config.d",
    "content": "/**\nConfiguration options for druntime.\n\nThe default way to configure the runtime is by passing command line arguments\nstarting with `--DRT-` and followed by the option name, e.g. `--DRT-gcopt` to\nconfigure the GC.\nCommand line options starting with `--DRT-` are filtered out before calling main,\nso the program will not see them. They are still available via `rt_args()`.\n\nConfiguration via the command line can be disabled by declaring a variable for the\nlinker to pick up before using it's default from the runtime:\n\n---\nextern(C) __gshared bool rt_cmdline_enabled = false;\n---\n\nLikewise, declare a boolean rt_envvars_enabled to enable configuration via the\nenvironment variable `DRT_` followed by the option name, e.g. `DRT_GCOPT`:\n\n---\nextern(C) __gshared bool rt_envvars_enabled = true;\n---\n\nSetting default configuration properties in the executable can be done by specifying an\narray of options named `rt_options`:\n\n---\nextern(C) __gshared string[] rt_options = [ \"gcopt=precise:1 profile:1\"];\n---\n\nEvaluation order of options is `rt_options`, then environment variables, then command\nline arguments, i.e. if command line arguments are not disabled, they can override\noptions specified through the environment or embedded in the executable.\n\nCopyright: Copyright Digital Mars 2014.\nLicense: Distributed under the\n     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n   (See accompanying file LICENSE)\nAuthors:   Rainer Schuetze\nSource: $(DRUNTIMESRC rt/_config.d)\n*/\n\nmodule rt.config;\n\n// put each variable in its own COMDAT by making them template instances\ntemplate rt_envvars_enabled()\n{\n    extern(C) pragma(mangle, \"rt_envvars_enabled\") __gshared bool rt_envvars_enabled = false;\n}\ntemplate rt_cmdline_enabled()\n{\n    extern(C) pragma(mangle, \"rt_cmdline_enabled\") __gshared bool rt_cmdline_enabled = true;\n}\ntemplate rt_options()\n{\n    extern(C) pragma(mangle, \"rt_options\") __gshared string[] rt_options = [];\n}\n\nimport core.stdc.ctype : toupper;\nimport core.stdc.stdlib : getenv;\nimport core.stdc.string : strlen;\n\nextern extern(C) string[] rt_args() @nogc nothrow;\n\nalias rt_configCallBack = string delegate(string) @nogc nothrow;\n\n/**\n* get a druntime config option using standard configuration options\n*      opt             name of the option to retrieve\n*      dg              if non-null, passes the option through this\n*                      delegate and only returns its return value if non-null\n*      reverse         reverse the default processing order cmdline/envvar/rt_options\n*                      to allow overwriting settings in the delegate with values\n*                      from higher priority\n*\n* returns the options' value if\n*  - set on the command line as \"--DRT-<opt>=value\" (rt_cmdline_enabled enabled)\n*  - the environment variable \"DRT_<OPT>\" is set (rt_envvars_enabled enabled)\n*  - rt_options[] contains an entry \"<opt>=value\"\n*  - null otherwise\n*/\nstring rt_configOption(string opt, scope rt_configCallBack dg = null, bool reverse = false) @nogc nothrow\n{\n    if (!dg)\n        dg = (string s) => s;\n\n    string s = (reverse ? rt_linkOption(opt, dg) : rt_cmdlineOption(opt, dg));\n    if (s != null)\n        return s;\n    s = rt_envvarsOption(opt, dg);\n    if (s != null)\n        return s;\n    s = (reverse ? rt_cmdlineOption(opt, dg) : rt_linkOption(opt, dg));\n    return s;\n}\n\nstring rt_cmdlineOption(string opt, scope rt_configCallBack dg) @nogc nothrow\n{\n    if (rt_cmdline_enabled!())\n    {\n        foreach (a; rt_args)\n        {\n            if (a.length >= opt.length + 7 && a[0..6] == \"--DRT-\" &&\n                a[6 .. 6 + opt.length] == opt && a[6 + opt.length] == '=')\n            {\n                string s = dg(a[7 + opt.length .. $]);\n                if (s != null)\n                    return s;\n            }\n        }\n    }\n    return null;\n}\n\nstring rt_envvarsOption(string opt, scope rt_configCallBack dg) @nogc nothrow\n{\n    if (rt_envvars_enabled!())\n    {\n        if (opt.length >= 32)\n            assert(0);\n\n        char[40] var;\n        var[0 .. 4] = \"DRT_\";\n        foreach (i, c; opt)\n            var[4 + i] = cast(char) toupper(c);\n        var[4 + opt.length] = 0;\n\n        auto p = getenv(var.ptr);\n        if (p)\n        {\n            string s = dg(cast(string) p[0 .. strlen(p)]);\n            if (s != null)\n                return s;\n        }\n    }\n    return null;\n}\n\nstring rt_linkOption(string opt, scope rt_configCallBack dg) @nogc nothrow\n{\n    foreach (a; rt_options!())\n    {\n        if (a.length > opt.length && a[0..opt.length] == opt && a[opt.length] == '=')\n        {\n            string s = dg(a[opt.length + 1 .. $]);\n            if (s != null)\n                return s;\n        }\n    }\n    return null;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/critical_.d",
    "content": "/**\n * Implementation of support routines for synchronized blocks.\n *\n * Copyright: Copyright Digital Mars 2000 - 2011.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, Sean Kelly\n */\n\n/*          Copyright Digital Mars 2000 - 2011.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.critical_;\n\nnothrow:\n\nimport rt.monitor_, core.atomic;\n\nextern (C) void _d_critical_init()\n{\n    initMutex(cast(Mutex*)&gcs.mtx);\n    head = &gcs;\n}\n\nextern (C) void _d_critical_term()\n{\n    for (auto p = head; p; p = p.next)\n        destroyMutex(cast(Mutex*)&p.mtx);\n}\n\nextern (C) void _d_criticalenter(D_CRITICAL_SECTION* cs)\n{\n    ensureMutex(cast(shared(D_CRITICAL_SECTION*)) cs);\n    lockMutex(&cs.mtx);\n}\n\nextern (C) void _d_criticalexit(D_CRITICAL_SECTION* cs)\n{\n    unlockMutex(&cs.mtx);\n}\n\nprivate:\n\nshared D_CRITICAL_SECTION* head;\nshared D_CRITICAL_SECTION gcs;\n\nstruct D_CRITICAL_SECTION\n{\n    D_CRITICAL_SECTION* next;\n    Mutex mtx;\n}\n\nvoid ensureMutex(shared(D_CRITICAL_SECTION)* cs)\n{\n    if (atomicLoad!(MemoryOrder.acq)(cs.next) is null)\n    {\n        lockMutex(cast(Mutex*)&gcs.mtx);\n        if (atomicLoad!(MemoryOrder.raw)(cs.next) is null)\n        {\n            initMutex(cast(Mutex*)&cs.mtx);\n            auto ohead = head;\n            head = cs;\n            atomicStore!(MemoryOrder.rel)(cs.next, ohead);\n        }\n        unlockMutex(cast(Mutex*)&gcs.mtx);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/deh.d",
    "content": "/**\n * Implementation of exception handling support routines.\n *\n * Copyright: Copyright Digital Mars 1999 - 2013.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Walter Bright\n * Source: $(DRUNTIMESRC rt/deh.d)\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule rt.deh;\n\nextern (C)\n{\n    Throwable.TraceInfo _d_traceContext(void* ptr = null);\n    void _d_createTrace(Object o, void* context)\n    {\n        auto t = cast(Throwable) o;\n\n        if (t !is null && t.info is null &&\n            cast(byte*) t !is typeid(t).initializer.ptr)\n        {\n            t.info = _d_traceContext(context);\n        }\n    }\n}\n\nversion (GNU)\n    public import gcc.deh;\nelse version (Win32)\n    public import rt.deh_win32;\nelse version (Win64)\n    public import rt.deh_win64_posix;\nelse version (Posix)\n    public import rt.deh_win64_posix;\nelse\n    static assert (0, \"Unsupported architecture\");\n\n"
  },
  {
    "path": "libphobos/libdruntime/rt/dmain2.d",
    "content": "/**\n * Contains druntime startup and shutdown routines.\n *\n * Copyright: Copyright Digital Mars 2000 - 2013.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Walter Bright, Sean Kelly\n * Source: $(DRUNTIMESRC rt/_dmain2.d)\n */\n\nmodule rt.dmain2;\n\nprivate\n{\n    import rt.memory;\n    import rt.sections;\n    import core.atomic;\n    import core.stdc.stddef;\n    import core.stdc.stdlib;\n    import core.stdc.string;\n    import core.stdc.stdio;   // for printf()\n    import core.stdc.errno : errno;\n}\n\nversion (Windows)\n{\n    private import core.stdc.wchar_;\n    private import core.sys.windows.windows;\n\n    pragma(lib, \"shell32.lib\"); // needed for CommandLineToArgvW\n}\n\nversion (FreeBSD)\n{\n    import core.stdc.fenv;\n}\nversion (NetBSD)\n{\n    import core.stdc.fenv;\n}\nversion (DragonFlyBSD)\n{\n    import core.stdc.fenv;\n}\n\n// not sure why we can't define this in one place, but this is to keep this\n// module from importing core.runtime.\nstruct UnitTestResult\n{\n    size_t executed;\n    size_t passed;\n    bool runMain;\n    bool summarize;\n}\n\nextern (C) void _d_monitor_staticctor();\nextern (C) void _d_monitor_staticdtor();\nextern (C) void _d_critical_init();\nextern (C) void _d_critical_term();\nextern (C) void gc_init();\nextern (C) void gc_term();\nextern (C) void thread_init() @nogc;\nextern (C) void thread_term() @nogc;\nextern (C) void lifetime_init();\nextern (C) void rt_moduleCtor();\nextern (C) void rt_moduleTlsCtor();\nextern (C) void rt_moduleDtor();\nextern (C) void rt_moduleTlsDtor();\nextern (C) void thread_joinAll();\nextern (C) UnitTestResult runModuleUnitTests();\nextern (C) void _d_initMonoTime();\n\nversion (OSX)\n{\n    // The bottom of the stack\n    extern (C) __gshared void* __osx_stack_end = cast(void*)0xC0000000;\n}\n\nversion (CRuntime_Microsoft)\n{\n    extern(C) void init_msvc();\n}\n\n/***********************************\n * These are a temporary means of providing a GC hook for DLL use.  They may be\n * replaced with some other similar functionality later.\n */\nextern (C)\n{\n    void* gc_getProxy();\n    void  gc_setProxy(void* p);\n    void  gc_clrProxy();\n\n    alias void* function()      gcGetFn;\n    alias void  function(void*) gcSetFn;\n    alias void  function()      gcClrFn;\n}\n\nversion (Windows)\n{\n    /*******************************************\n     * Loads a DLL written in D with the name 'name'.\n     * Returns:\n     *      opaque handle to the DLL if successfully loaded\n     *      null if failure\n     */\n    extern (C) void* rt_loadLibrary(const char* name)\n    {\n        return initLibrary(.LoadLibraryA(name));\n    }\n\n    extern (C) void* rt_loadLibraryW(const wchar_t* name)\n    {\n        return initLibrary(.LoadLibraryW(name));\n    }\n\n    void* initLibrary(void* mod)\n    {\n        // BUG: LoadLibrary() call calls rt_init(), which fails if proxy is not set!\n        // (What? LoadLibrary() is a Windows API call, it shouldn't call rt_init().)\n        if (mod is null)\n            return mod;\n        gcSetFn gcSet = cast(gcSetFn) GetProcAddress(mod, \"gc_setProxy\");\n        if (gcSet !is null)\n        {   // BUG: Set proxy, but too late\n            gcSet(gc_getProxy());\n        }\n        return mod;\n    }\n\n    /*************************************\n     * Unloads DLL that was previously loaded by rt_loadLibrary().\n     * Input:\n     *      ptr     the handle returned by rt_loadLibrary()\n     * Returns:\n     *      1   succeeded\n     *      0   some failure happened\n     */\n    extern (C) int rt_unloadLibrary(void* ptr)\n    {\n        gcClrFn gcClr  = cast(gcClrFn) GetProcAddress(ptr, \"gc_clrProxy\");\n        if (gcClr !is null)\n            gcClr();\n        return FreeLibrary(ptr) != 0;\n    }\n}\n\n/* To get out-of-band access to the args[] passed to main().\n */\n\n__gshared string[] _d_args = null;\n\nextern (C) string[] rt_args()\n{\n    return _d_args;\n}\n\n// make arguments passed to main available for being filtered by runtime initializers\nextern(C) __gshared char[][] _d_main_args = null;\n\n// This variable is only ever set by a debugger on initialization so it should\n// be fine to leave it as __gshared.\nextern (C) __gshared bool rt_trapExceptions = true;\n\nalias void delegate(Throwable) ExceptionHandler;\n\n/**\n * Keep track of how often rt_init/rt_term were called.\n */\nshared size_t _initCount;\n\n/**********************************************\n * Initialize druntime.\n * If a C program wishes to call D code, and there's no D main(), then it\n * must call rt_init() and rt_term().\n */\nextern (C) int rt_init()\n{\n    /* @@BUG 11380 @@ Need to synchronize rt_init/rt_term calls for\n       version (Shared) druntime, because multiple C threads might\n       initialize different D libraries without knowing about the\n       shared druntime. Also we need to attach any thread that calls\n       rt_init. */\n    if (atomicOp!\"+=\"(_initCount, 1) > 1) return 1;\n\n    version (CRuntime_Microsoft)\n        init_msvc();\n\n    _d_monitor_staticctor();\n    _d_critical_init();\n\n    try\n    {\n        initSections();\n        // this initializes mono time before anything else to allow usage\n        // in other druntime systems.\n        _d_initMonoTime();\n        thread_init();\n        // TODO: fixme - calls GC.addRange -> Initializes GC\n        initStaticDataGC();\n        lifetime_init();\n        rt_moduleCtor();\n        rt_moduleTlsCtor();\n        return 1;\n    }\n    catch (Throwable t)\n    {\n        _initCount = 0;\n        _d_print_throwable(t);\n    }\n    _d_critical_term();\n    _d_monitor_staticdtor();\n    return 0;\n}\n\n/**********************************************\n * Terminate use of druntime.\n */\nextern (C) int rt_term()\n{\n    if (!_initCount) return 0; // was never initialized\n    if (atomicOp!\"-=\"(_initCount, 1)) return 1;\n\n    try\n    {\n        rt_moduleTlsDtor();\n        thread_joinAll();\n        rt_moduleDtor();\n        gc_term();\n        thread_term();\n        return 1;\n    }\n    catch (Throwable t)\n    {\n        _d_print_throwable(t);\n    }\n    finally\n    {\n        finiSections();\n        _d_critical_term();\n        _d_monitor_staticdtor();\n    }\n    return 0;\n}\n\n/**********************************************\n * Trace handler\n */\nalias Throwable.TraceInfo function(void* ptr) TraceHandler;\nprivate __gshared TraceHandler traceHandler = null;\n\n\n/**\n * Overrides the default trace hander with a user-supplied version.\n *\n * Params:\n *  h = The new trace handler.  Set to null to use the default handler.\n */\nextern (C) void  rt_setTraceHandler(TraceHandler h)\n{\n    traceHandler = h;\n}\n\n/**\n * Return the current trace handler\n */\nextern (C) TraceHandler rt_getTraceHandler()\n{\n    return traceHandler;\n}\n\n/**\n * This function will be called when an exception is constructed.  The\n * user-supplied trace handler will be called if one has been supplied,\n * otherwise no trace will be generated.\n *\n * Params:\n *  ptr = A pointer to the location from which to generate the trace, or null\n *        if the trace should be generated from within the trace handler\n *        itself.\n *\n * Returns:\n *  An object describing the current calling context or null if no handler is\n *  supplied.\n */\nextern (C) Throwable.TraceInfo _d_traceContext(void* ptr = null)\n{\n    if (traceHandler is null)\n        return null;\n    return traceHandler(ptr);\n}\n\n/***********************************\n * Provide out-of-band access to the original C argc/argv\n * passed to this program via main(argc,argv).\n */\n\nstruct CArgs\n{\n    int argc;\n    char** argv;\n}\n\n__gshared CArgs _cArgs;\n\nextern (C) CArgs rt_cArgs() @nogc\n{\n    return _cArgs;\n}\n\n/***********************************\n * Run the given main function.\n * Its purpose is to wrap the D main()\n * function and catch any unhandled exceptions.\n */\nprivate alias extern(C) int function(char[][] args) MainFunc;\n\nextern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)\n{\n    // Remember the original C argc/argv\n    _cArgs.argc = argc;\n    _cArgs.argv = argv;\n\n    int result;\n\n    version (OSX)\n    {   /* OSX does not provide a way to get at the top of the\n         * stack, except for the magic value 0xC0000000.\n         * But as far as the gc is concerned, argv is at the top\n         * of the main thread's stack, so save the address of that.\n         */\n        __osx_stack_end = cast(void*)&argv;\n    }\n\n    version (FreeBSD) version (D_InlineAsm_X86)\n    {\n        /*\n         * FreeBSD/i386 sets the FPU precision mode to 53 bit double.\n         * Make it 64 bit extended.\n         */\n        ushort fpucw;\n        asm\n        {\n            fstsw   fpucw;\n            or      fpucw, 0b11_00_111111; // 11: use 64 bit extended-precision\n                                           // 111111: mask all FP exceptions\n            fldcw   fpucw;\n        }\n    }\n    version (CRuntime_Microsoft)\n    {\n        // enable full precision for reals\n        version (Win64)\n            asm\n            {\n                push    RAX;\n                fstcw   word ptr [RSP];\n                or      [RSP], 0b11_00_111111; // 11: use 64 bit extended-precision\n                                               // 111111: mask all FP exceptions\n                fldcw   word ptr [RSP];\n                pop     RAX;\n            }\n        else version (Win32)\n        {\n            asm\n            {\n                push    EAX;\n                fstcw   word ptr [ESP];\n                or      [ESP], 0b11_00_111111; // 11: use 64 bit extended-precision\n                // 111111: mask all FP exceptions\n                fldcw   word ptr [ESP];\n                pop     EAX;\n            }\n        }\n    }\n\n    version (Windows)\n    {\n        /* Because we want args[] to be UTF-8, and Windows doesn't guarantee that,\n         * we ignore argc/argv and go get the Windows command line again as UTF-16.\n         * Then, reparse into wargc/wargs, and then use Windows API to convert\n         * to UTF-8.\n         */\n        const wchar_t* wCommandLine = GetCommandLineW();\n        immutable size_t wCommandLineLength = wcslen(wCommandLine);\n        int wargc;\n        wchar_t** wargs = CommandLineToArgvW(wCommandLine, &wargc);\n        // assert(wargc == argc); /* argc can be broken by Unicode arguments */\n\n        // Allocate args[] on the stack - use wargc\n        char[][] args = (cast(char[]*) alloca(wargc * (char[]).sizeof))[0 .. wargc];\n\n        // This is required because WideCharToMultiByte requires int as input.\n        assert(wCommandLineLength <= cast(size_t) int.max, \"Wide char command line length must not exceed int.max\");\n\n        immutable size_t totalArgsLength = WideCharToMultiByte(CP_UTF8, 0, wCommandLine, cast(int)wCommandLineLength, null, 0, null, null);\n        {\n            char* totalArgsBuff = cast(char*) alloca(totalArgsLength);\n            size_t j = 0;\n            foreach (i; 0 .. wargc)\n            {\n                immutable size_t wlen = wcslen(wargs[i]);\n                assert(wlen <= cast(size_t) int.max, \"wlen cannot exceed int.max\");\n                immutable int len = WideCharToMultiByte(CP_UTF8, 0, &wargs[i][0], cast(int) wlen, null, 0, null, null);\n                args[i] = totalArgsBuff[j .. j + len];\n                if (len == 0)\n                    continue;\n                j += len;\n                assert(j <= totalArgsLength);\n                WideCharToMultiByte(CP_UTF8, 0, &wargs[i][0], cast(int) wlen, &args[i][0], len, null, null);\n            }\n        }\n        LocalFree(wargs);\n        wargs = null;\n        wargc = 0;\n    }\n    else version (Posix)\n    {\n        // Allocate args[] on the stack\n        char[][] args = (cast(char[]*) alloca(argc * (char[]).sizeof))[0 .. argc];\n\n        size_t totalArgsLength = 0;\n        foreach (i, ref arg; args)\n        {\n            arg = argv[i][0 .. strlen(argv[i])];\n            totalArgsLength += arg.length;\n        }\n    }\n    else\n        static assert(0);\n\n    /* Create a copy of args[] on the stack to be used for main, so that rt_args()\n     * cannot be modified by the user.\n     * Note that when this function returns, _d_args will refer to garbage.\n     */\n    {\n        _d_args = cast(string[]) args;\n        auto buff = cast(char[]*) alloca(args.length * (char[]).sizeof + totalArgsLength);\n\n        char[][] argsCopy = buff[0 .. args.length];\n        auto argBuff = cast(char*) (buff + args.length);\n        size_t j = 0;\n        foreach (arg; args)\n        {\n            if (arg.length < 6 || arg[0..6] != \"--DRT-\") // skip D runtime options\n            {\n                argsCopy[j++] = (argBuff[0 .. arg.length] = arg[]);\n                argBuff += arg.length;\n            }\n        }\n        args = argsCopy[0..j];\n    }\n\n    auto useExceptionTrap = parseExceptionOptions();\n\n    version (Windows)\n    {\n        if (IsDebuggerPresent())\n            useExceptionTrap = false;\n    }\n\n    void tryExec(scope void delegate() dg)\n    {\n        if (useExceptionTrap)\n        {\n            try\n            {\n                dg();\n            }\n            catch (Throwable t)\n            {\n                _d_print_throwable(t);\n                result = EXIT_FAILURE;\n            }\n        }\n        else\n        {\n            dg();\n        }\n    }\n\n    // NOTE: The lifetime of a process is much like the lifetime of an object:\n    //       it is initialized, then used, then destroyed.  If initialization\n    //       fails, the successive two steps are never reached.  However, if\n    //       initialization succeeds, then cleanup will occur even if the use\n    //       step fails in some way.  Here, the use phase consists of running\n    //       the user's main function.  If main terminates with an exception,\n    //       the exception is handled and then cleanup begins.  An exception\n    //       thrown during cleanup, however, will abort the cleanup process.\n    void runAll()\n    {\n        if (rt_init())\n        {\n            auto utResult = runModuleUnitTests();\n            assert(utResult.passed <= utResult.executed);\n            if (utResult.passed == utResult.executed)\n            {\n                if (utResult.summarize)\n                {\n                    if (utResult.passed == 0)\n                        .fprintf(.stderr, \"No unittests run\\n\");\n                    else\n                        .fprintf(.stderr, \"%d unittests passed\\n\",\n                                 cast(int)utResult.passed);\n                }\n                if (utResult.runMain)\n                    tryExec({ result = mainFunc(args); });\n                else\n                    result = EXIT_SUCCESS;\n            }\n            else\n            {\n                if (utResult.summarize)\n                    .fprintf(.stderr, \"%d/%d unittests FAILED\\n\",\n                             cast(int)(utResult.executed - utResult.passed),\n                             cast(int)utResult.executed);\n                result = EXIT_FAILURE;\n            }\n        }\n        else\n            result = EXIT_FAILURE;\n\n        if (!rt_term())\n            result = (result == EXIT_SUCCESS) ? EXIT_FAILURE : result;\n    }\n\n    tryExec(&runAll);\n\n    // Issue 10344: flush stdout and return nonzero on failure\n    if (.fflush(.stdout) != 0)\n    {\n        .fprintf(.stderr, \"Failed to flush stdout: %s\\n\", .strerror(.errno));\n        if (result == 0)\n        {\n            result = EXIT_FAILURE;\n        }\n    }\n\n    return result;\n}\n\nprivate void formatThrowable(Throwable t, scope void delegate(in char[] s) nothrow sink)\n{\n    foreach (u; t)\n    {\n        u.toString(sink); sink(\"\\n\");\n\n        auto e = cast(Error)u;\n        if (e is null || e.bypassedException is null) continue;\n\n        sink(\"=== Bypassed ===\\n\");\n        foreach (t2; e.bypassedException)\n        {\n            t2.toString(sink); sink(\"\\n\");\n        }\n        sink(\"=== ~Bypassed ===\\n\");\n    }\n}\n\nprivate auto parseExceptionOptions()\n{\n    import rt.config : rt_configOption;\n    import core.internal.parseoptions : rt_parseOption;\n    const optName = \"trapExceptions\";\n    auto option = rt_configOption(optName);\n    auto trap = rt_trapExceptions;\n    if (option.length)\n        rt_parseOption(optName, option, trap, \"\");\n    return trap;\n}\n\nextern (C) void _d_print_throwable(Throwable t)\n{\n    // On Windows, a console may not be present to print the output to.\n    // Show a message box instead. If the console is present, convert to\n    // the correct encoding.\n    version (Windows)\n    {\n        static struct WSink\n        {\n            wchar_t* ptr; size_t len;\n\n            void sink(in char[] s) scope nothrow\n            {\n                if (!s.length) return;\n                int swlen = MultiByteToWideChar(\n                        CP_UTF8, 0, s.ptr, cast(int)s.length, null, 0);\n                if (!swlen) return;\n\n                auto newPtr = cast(wchar_t*)realloc(ptr,\n                        (this.len + swlen + 1) * wchar_t.sizeof);\n                if (!newPtr) return;\n                ptr = newPtr;\n                auto written = MultiByteToWideChar(\n                        CP_UTF8, 0, s.ptr, cast(int)s.length, ptr+len, swlen);\n                len += written;\n            }\n\n            wchar_t* get() { if (ptr) ptr[len] = 0; return ptr; }\n\n            void free() { .free(ptr); }\n        }\n\n        HANDLE windowsHandle(int fd)\n        {\n            version (CRuntime_Microsoft)\n                return cast(HANDLE)_get_osfhandle(fd);\n            else\n                return _fdToHandle(fd);\n        }\n\n        auto hStdErr = windowsHandle(fileno(stderr));\n        CONSOLE_SCREEN_BUFFER_INFO sbi;\n        bool isConsole = GetConsoleScreenBufferInfo(hStdErr, &sbi) != 0;\n\n        // ensure the exception is shown at the beginning of the line, while also\n        // checking whether stderr is a valid file\n        int written = fprintf(stderr, \"\\n\");\n        if (written <= 0)\n        {\n            WSink buf;\n            formatThrowable(t, &buf.sink);\n\n            if (buf.ptr)\n            {\n                WSink caption;\n                if (t)\n                    caption.sink(t.classinfo.name);\n\n                // Avoid static user32.dll dependency for console applications\n                // by loading it dynamically as needed\n                auto user32 = LoadLibraryW(\"user32.dll\");\n                if (user32)\n                {\n                    alias typeof(&MessageBoxW) PMessageBoxW;\n                    auto pMessageBoxW = cast(PMessageBoxW)\n                        GetProcAddress(user32, \"MessageBoxW\");\n                    if (pMessageBoxW)\n                        pMessageBoxW(null, buf.get(), caption.get(), MB_ICONERROR);\n                }\n                FreeLibrary(user32);\n                caption.free();\n                buf.free();\n            }\n            return;\n        }\n        else if (isConsole)\n        {\n            WSink buf;\n            formatThrowable(t, &buf.sink);\n\n            if (buf.ptr)\n            {\n                uint codepage = GetConsoleOutputCP();\n                int slen = WideCharToMultiByte(codepage, 0,\n                        buf.ptr, cast(int)buf.len, null, 0, null, null);\n                auto sptr = cast(char*)malloc(slen * char.sizeof);\n                if (sptr)\n                {\n                    WideCharToMultiByte(codepage, 0,\n                        buf.ptr, cast(int)buf.len, sptr, slen, null, null);\n                    WriteFile(hStdErr, sptr, slen, null, null);\n                    free(sptr);\n                }\n                buf.free();\n            }\n            return;\n        }\n    }\n\n    void sink(in char[] buf) scope nothrow\n    {\n        fprintf(stderr, \"%.*s\", cast(int)buf.length, buf.ptr);\n    }\n    formatThrowable(t, &sink);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/dylib_fixes.c",
    "content": "/**\n * OS X support for dynamic libraries.\n *\n * Copyright: Copyright Digital Mars 2010 - 2010.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2010 - 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nvoid* _Dmain __attribute__((weak));\n\nchar rt_init ();\nchar rt_term ();\n\n__attribute__((constructor)) static void initializer ()\n{\n    rt_init();\n}\n\n__attribute__((destructor)) static void finalizer ()\n{\n    rt_term();\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/rt/ehalloc.d",
    "content": "/**\n * Exception allocation, cloning, and release compiler support routines.\n *\n * Copyright: Copyright (c) 2017 by D Language Foundation\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors: Walter Bright\n * Source: $(DRUNTIMESRC rt/_dwarfeh.d)\n */\n\nmodule rt.ehalloc;\n\n//debug = PRINTF;\n\ndebug(PRINTF)\n{\n    import core.stdc.stdio;\n}\n\n/**********************************************\n * Allocate an exception of type `ci` from the exception pool.\n * It has the same interface as `rt.lifetime._d_newclass()`.\n * The class type must be Throwable or derived from it,\n * and cannot be a COM or C++ class. The compiler must enforce\n * this.\n * Returns:\n *      default initialized instance of the type\n */\n\nextern (C) Throwable _d_newThrowable(const TypeInfo_Class ci)\n{\n    debug(PRINTF) printf(\"_d_newThrowable(ci = %p, %s)\\n\", ci, cast(char *)ci.name);\n\n    assert(!(ci.m_flags & TypeInfo_Class.ClassFlags.isCOMclass));\n    assert(!(ci.m_flags & TypeInfo_Class.ClassFlags.isCPPclass));\n\n    import core.stdc.stdlib : malloc;\n    void* p = malloc(ci.initializer.length);\n    if (!p)\n    {\n        import core.exception : onOutOfMemoryError;\n        onOutOfMemoryError();\n    }\n\n    debug(PRINTF) printf(\" p = %p\\n\", p);\n\n    // initialize it\n    p[0 .. ci.initializer.length] = ci.initializer[];\n\n    if (!(ci.m_flags & TypeInfo_Class.ClassFlags.noPointers))\n    {\n        // Inform the GC about the pointers in the object instance\n        import core.memory : GC;\n\n        GC.addRange(p, ci.initializer.length, ci);\n    }\n\n    debug(PRINTF) printf(\"initialization done\\n\");\n    Throwable t = cast(Throwable)p;\n    t.refcount() = 1;\n    return t;\n}\n\n\n/********************************************\n * Delete exception instance `t` from the exception pool.\n * Must have been allocated with `_d_newThrowable()`.\n * This is meant to be called at the close of a catch block.\n * It's nothrow because otherwise any function with a catch block could\n * not be nothrow.\n * Input:\n *      t = Throwable\n */\n\nnothrow extern (C) void _d_delThrowable(Throwable t)\n{\n    if (t)\n    {\n        debug(PRINTF) printf(\"_d_delThrowable(%p)\\n\", t);\n\n        /* If allocated by the GC, don't free it.\n         * Let the GC handle it.\n         * Supporting this is necessary while transitioning\n         * to this new scheme for allocating exceptions.\n         */\n        auto refcount = t.refcount();\n        if (refcount == 0)\n            return;     // it was allocated by the GC\n\n        if (refcount == 1)\n            assert(0);  // no zombie objects\n\n        t.refcount() = --refcount;\n        if (refcount > 1)\n            return;\n\n        TypeInfo_Class **pc = cast(TypeInfo_Class **)t;\n        if (*pc)\n        {\n            TypeInfo_Class ci = **pc;\n\n            if (!(ci.m_flags & TypeInfo_Class.ClassFlags.noPointers))\n            {\n                // Inform the GC about the pointers in the object instance\n                import core.memory : GC;\n                GC.removeRange(cast(void*) t);\n            }\n        }\n\n        try\n        {\n            import rt.lifetime : rt_finalize;\n            rt_finalize(cast(void*) t);\n        }\n        catch (Throwable t)\n        {\n            assert(0);  // should never happen since Throwable.~this() is nothrow\n        }\n        import core.stdc.stdlib : free;\n        debug(PRINTF) printf(\"free(%p)\\n\", t);\n        free(cast(void*) t);\n    }\n}\n\n"
  },
  {
    "path": "libphobos/libdruntime/rt/invariant.d",
    "content": "/**\n * Implementation of invariant support routines.\n *\n * Copyright: Copyright Digital Mars 2007 - 2010.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2007 - 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\n\n\n/**\n *\n */\nvoid _d_invariant(Object o)\n{   ClassInfo c;\n\n    //printf(\"__d_invariant(%p)\\n\", o);\n\n    // BUG: needs to be filename/line of caller, not library routine\n    assert(o !is null); // just do null check, not invariant check\n\n    c = typeid(o);\n    do\n    {\n        if (c.classInvariant)\n        {\n            (*c.classInvariant)(o);\n        }\n        c = c.base;\n    } while (c);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/lifetime.d",
    "content": "/**\n * This module contains all functions related to an object's lifetime:\n * allocation, resizing, deallocation, and finalization.\n *\n * Copyright: Copyright Digital Mars 2000 - 2012.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Walter Bright, Sean Kelly, Steven Schveighoffer\n * Source: $(DRUNTIMESRC rt/_lifetime.d)\n */\n\nmodule rt.lifetime;\n\nimport core.memory;\ndebug(PRINTF) import core.stdc.stdio;\nstatic import rt.tlsgc;\n\nalias BlkInfo = GC.BlkInfo;\nalias BlkAttr = GC.BlkAttr;\n\nprivate\n{\n    alias bool function(Object) CollectHandler;\n    __gshared CollectHandler collectHandler = null;\n\n    extern (C) void _d_monitordelete(Object h, bool det);\n\n    enum : size_t\n    {\n        PAGESIZE = 4096,\n        BIGLENGTHMASK = ~(PAGESIZE - 1),\n        SMALLPAD = 1,\n        MEDPAD = ushort.sizeof,\n        LARGEPREFIX = 16, // 16 bytes padding at the front of the array\n        LARGEPAD = LARGEPREFIX + 1,\n        MAXSMALLSIZE = 256-SMALLPAD,\n        MAXMEDSIZE = (PAGESIZE / 2) - MEDPAD\n    }\n}\n\nprivate immutable bool callStructDtorsDuringGC;\n\nextern (C) void lifetime_init()\n{\n    // this is run before static ctors, so it is safe to modify immutables\n    import rt.config;\n    string s = rt_configOption(\"callStructDtorsDuringGC\");\n    if (s != null)\n        cast() callStructDtorsDuringGC = s[0] == '1' || s[0] == 'y' || s[0] == 'Y';\n    else\n        cast() callStructDtorsDuringGC = true;\n}\n\n/**\n *\n */\nextern (C) void* _d_allocmemory(size_t sz)\n{\n    return GC.malloc(sz);\n}\n\n/**\n *\n */\nextern (C) Object _d_newclass(const ClassInfo ci)\n{\n    import core.stdc.stdlib;\n    import core.exception : onOutOfMemoryError;\n    void* p;\n\n    debug(PRINTF) printf(\"_d_newclass(ci = %p, %s)\\n\", ci, cast(char *)ci.name);\n    if (ci.m_flags & TypeInfo_Class.ClassFlags.isCOMclass)\n    {   /* COM objects are not garbage collected, they are reference counted\n         * using AddRef() and Release().  They get free'd by C's free()\n         * function called by Release() when Release()'s reference count goes\n         * to zero.\n     */\n        p = malloc(ci.initializer.length);\n        if (!p)\n            onOutOfMemoryError();\n    }\n    else\n    {\n        // TODO: should this be + 1 to avoid having pointers to the next block?\n        BlkAttr attr = BlkAttr.NONE;\n        // extern(C++) classes don't have a classinfo pointer in their vtable so the GC can't finalize them\n        if (ci.m_flags & TypeInfo_Class.ClassFlags.hasDtor\n            && !(ci.m_flags & TypeInfo_Class.ClassFlags.isCPPclass))\n            attr |= BlkAttr.FINALIZE;\n        if (ci.m_flags & TypeInfo_Class.ClassFlags.noPointers)\n            attr |= BlkAttr.NO_SCAN;\n        p = GC.malloc(ci.initializer.length, attr, ci);\n        debug(PRINTF) printf(\" p = %p\\n\", p);\n    }\n\n    debug(PRINTF)\n    {\n        printf(\"p = %p\\n\", p);\n        printf(\"ci = %p, ci.init.ptr = %p, len = %llu\\n\", ci, ci.initializer.ptr, cast(ulong)ci.initializer.length);\n        printf(\"vptr = %p\\n\", *cast(void**) ci.initializer);\n        printf(\"vtbl[0] = %p\\n\", (*cast(void***) ci.initializer)[0]);\n        printf(\"vtbl[1] = %p\\n\", (*cast(void***) ci.initializer)[1]);\n        printf(\"init[0] = %x\\n\", (cast(uint*) ci.initializer)[0]);\n        printf(\"init[1] = %x\\n\", (cast(uint*) ci.initializer)[1]);\n        printf(\"init[2] = %x\\n\", (cast(uint*) ci.initializer)[2]);\n        printf(\"init[3] = %x\\n\", (cast(uint*) ci.initializer)[3]);\n        printf(\"init[4] = %x\\n\", (cast(uint*) ci.initializer)[4]);\n    }\n\n    // initialize it\n    p[0 .. ci.initializer.length] = ci.initializer[];\n\n    debug(PRINTF) printf(\"initialization done\\n\");\n    return cast(Object) p;\n}\n\n\n/**\n *\n */\nextern (C) void _d_delinterface(void** p)\n{\n    if (*p)\n    {\n        Interface* pi = **cast(Interface ***)*p;\n        Object     o  = cast(Object)(*p - pi.offset);\n\n        _d_delclass(&o);\n        *p = null;\n    }\n}\n\n\n// used for deletion\nprivate extern (D) alias void function (Object) fp_t;\n\n\n/**\n *\n */\nextern (C) void _d_delclass(Object* p)\n{\n    if (*p)\n    {\n        debug(PRINTF) printf(\"_d_delclass(%p)\\n\", *p);\n\n        ClassInfo **pc = cast(ClassInfo **)*p;\n        if (*pc)\n        {\n            ClassInfo c = **pc;\n\n            rt_finalize(cast(void*) *p);\n\n            if (c.deallocator)\n            {\n                fp_t fp = cast(fp_t)c.deallocator;\n                (*fp)(*p); // call deallocator\n                *p = null;\n                return;\n            }\n        }\n        else\n        {\n            rt_finalize(cast(void*) *p);\n        }\n        GC.free(cast(void*) *p);\n        *p = null;\n    }\n}\n\n/**\n * This is called for a delete statement where the value\n * being deleted is a pointer to a struct with a destructor\n * but doesn't have an overloaded delete operator.\n */\nextern (C) void _d_delstruct(void** p, TypeInfo_Struct inf)\n{\n    if (*p)\n    {\n        debug(PRINTF) printf(\"_d_delstruct(%p, %p)\\n\", *p, cast(void*)inf);\n\n        inf.destroy(*p);\n        GC.free(*p);\n        *p = null;\n    }\n}\n\n// strip const/immutable/shared/inout from type info\ninout(TypeInfo) unqualify(inout(TypeInfo) cti) pure nothrow @nogc\n{\n    TypeInfo ti = cast() cti;\n    while (ti)\n    {\n        // avoid dynamic type casts\n        auto tti = typeid(ti);\n        if (tti is typeid(TypeInfo_Const))\n            ti = (cast(TypeInfo_Const)cast(void*)ti).base;\n        else if (tti is typeid(TypeInfo_Invariant))\n            ti = (cast(TypeInfo_Invariant)cast(void*)ti).base;\n        else if (tti is typeid(TypeInfo_Shared))\n            ti = (cast(TypeInfo_Shared)cast(void*)ti).base;\n        else if (tti is typeid(TypeInfo_Inout))\n            ti = (cast(TypeInfo_Inout)cast(void*)ti).base;\n        else\n            break;\n    }\n    return ti;\n}\n\n// size used to store the TypeInfo at the end of an allocation for structs that have a destructor\nsize_t structTypeInfoSize(const TypeInfo ti) pure nothrow @nogc\n{\n    if (!callStructDtorsDuringGC)\n        return 0;\n\n    if (ti && typeid(ti) is typeid(TypeInfo_Struct)) // avoid a complete dynamic type cast\n    {\n        auto sti = cast(TypeInfo_Struct)cast(void*)ti;\n        if (sti.xdtor)\n            return size_t.sizeof;\n    }\n    return 0;\n}\n\n/** dummy class used to lock for shared array appending */\nprivate class ArrayAllocLengthLock\n{}\n\n\n/**\n  Set the allocated length of the array block.  This is called\n  any time an array is appended to or its length is set.\n\n  The allocated block looks like this for blocks < PAGESIZE:\n\n  |elem0|elem1|elem2|...|elemN-1|emptyspace|N*elemsize|\n\n\n  The size of the allocated length at the end depends on the block size:\n\n  a block of 16 to 256 bytes has an 8-bit length.\n\n  a block with 512 to pagesize/2 bytes has a 16-bit length.\n\n  For blocks >= pagesize, the length is a size_t and is at the beginning of the\n  block.  The reason we have to do this is because the block can extend into\n  more pages, so we cannot trust the block length if it sits at the end of the\n  block, because it might have just been extended.  If we can prove in the\n  future that the block is unshared, we may be able to change this, but I'm not\n  sure it's important.\n\n  In order to do put the length at the front, we have to provide 16 bytes\n  buffer space in case the block has to be aligned properly.  In x86, certain\n  SSE instructions will only work if the data is 16-byte aligned.  In addition,\n  we need the sentinel byte to prevent accidental pointers to the next block.\n  Because of the extra overhead, we only do this for page size and above, where\n  the overhead is minimal compared to the block size.\n\n  So for those blocks, it looks like:\n\n  |N*elemsize|padding|elem0|elem1|...|elemN-1|emptyspace|sentinelbyte|\n\n  where elem0 starts 16 bytes after the first byte.\n  */\nbool __setArrayAllocLength(ref BlkInfo info, size_t newlength, bool isshared, const TypeInfo tinext, size_t oldlength = ~0) pure nothrow\n{\n    import core.atomic;\n\n    size_t typeInfoSize = structTypeInfoSize(tinext);\n\n    if (info.size <= 256)\n    {\n        import core.checkedint;\n\n        bool overflow;\n        auto newlength_padded = addu(newlength,\n                                     addu(SMALLPAD, typeInfoSize, overflow),\n                                     overflow);\n\n        if (newlength_padded > info.size || overflow)\n            // new size does not fit inside block\n            return false;\n\n        auto length = cast(ubyte *)(info.base + info.size - typeInfoSize - SMALLPAD);\n        if (oldlength != ~0)\n        {\n            if (isshared)\n            {\n                return cas(cast(shared)length, cast(ubyte)oldlength, cast(ubyte)newlength);\n            }\n            else\n            {\n                if (*length == cast(ubyte)oldlength)\n                    *length = cast(ubyte)newlength;\n                else\n                    return false;\n            }\n        }\n        else\n        {\n            // setting the initial length, no cas needed\n            *length = cast(ubyte)newlength;\n        }\n        if (typeInfoSize)\n        {\n            auto typeInfo = cast(TypeInfo*)(info.base + info.size - size_t.sizeof);\n            *typeInfo = cast() tinext;\n        }\n    }\n    else if (info.size < PAGESIZE)\n    {\n        if (newlength + MEDPAD + typeInfoSize > info.size)\n            // new size does not fit inside block\n            return false;\n        auto length = cast(ushort *)(info.base + info.size - typeInfoSize - MEDPAD);\n        if (oldlength != ~0)\n        {\n            if (isshared)\n            {\n                return cas(cast(shared)length, cast(ushort)oldlength, cast(ushort)newlength);\n            }\n            else\n            {\n                if (*length == oldlength)\n                    *length = cast(ushort)newlength;\n                else\n                    return false;\n            }\n        }\n        else\n        {\n            // setting the initial length, no cas needed\n            *length = cast(ushort)newlength;\n        }\n        if (typeInfoSize)\n        {\n            auto typeInfo = cast(TypeInfo*)(info.base + info.size - size_t.sizeof);\n            *typeInfo = cast() tinext;\n        }\n    }\n    else\n    {\n        if (newlength + LARGEPAD > info.size)\n            // new size does not fit inside block\n            return false;\n        auto length = cast(size_t *)(info.base);\n        if (oldlength != ~0)\n        {\n            if (isshared)\n            {\n                return cas(cast(shared)length, cast(size_t)oldlength, cast(size_t)newlength);\n            }\n            else\n            {\n                if (*length == oldlength)\n                    *length = newlength;\n                else\n                    return false;\n            }\n        }\n        else\n        {\n            // setting the initial length, no cas needed\n            *length = newlength;\n        }\n        if (typeInfoSize)\n        {\n            auto typeInfo = cast(TypeInfo*)(info.base + size_t.sizeof);\n            *typeInfo = cast()tinext;\n        }\n    }\n    return true; // resize succeeded\n}\n\n/**\n  get the allocation size of the array for the given block (without padding or type info)\n  */\nsize_t __arrayAllocLength(ref BlkInfo info, const TypeInfo tinext) pure nothrow\n{\n    if (info.size <= 256)\n        return *cast(ubyte *)(info.base + info.size - structTypeInfoSize(tinext) - SMALLPAD);\n\n    if (info.size < PAGESIZE)\n        return *cast(ushort *)(info.base + info.size - structTypeInfoSize(tinext) - MEDPAD);\n\n    return *cast(size_t *)(info.base);\n}\n\n/**\n  get the start of the array for the given block\n  */\nvoid *__arrayStart(BlkInfo info) nothrow pure\n{\n    return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0);\n}\n\n/**\n  get the padding required to allocate size bytes.  Note that the padding is\n  NOT included in the passed in size.  Therefore, do NOT call this function\n  with the size of an allocated block.\n  */\nsize_t __arrayPad(size_t size, const TypeInfo tinext) nothrow pure @trusted\n{\n    return size > MAXMEDSIZE ? LARGEPAD : ((size > MAXSMALLSIZE ? MEDPAD : SMALLPAD) + structTypeInfoSize(tinext));\n}\n\n/**\n  allocate an array memory block by applying the proper padding and\n  assigning block attributes if not inherited from the existing block\n  */\nBlkInfo __arrayAlloc(size_t arrsize, const TypeInfo ti, const TypeInfo tinext) nothrow pure\n{\n    import core.checkedint;\n\n    size_t typeInfoSize = structTypeInfoSize(tinext);\n    size_t padsize = arrsize > MAXMEDSIZE ? LARGEPAD : ((arrsize > MAXSMALLSIZE ? MEDPAD : SMALLPAD) + typeInfoSize);\n\n    bool overflow;\n    auto padded_size = addu(arrsize, padsize, overflow);\n\n    if (overflow)\n        return BlkInfo();\n\n    uint attr = (!(tinext.flags & 1) ? BlkAttr.NO_SCAN : 0) | BlkAttr.APPENDABLE;\n    if (typeInfoSize)\n        attr |= BlkAttr.STRUCTFINAL | BlkAttr.FINALIZE;\n    return GC.qalloc(padded_size, attr, ti);\n}\n\nBlkInfo __arrayAlloc(size_t arrsize, ref BlkInfo info, const TypeInfo ti, const TypeInfo tinext)\n{\n    import core.checkedint;\n\n    if (!info.base)\n        return __arrayAlloc(arrsize, ti, tinext);\n\n    bool overflow;\n    auto padded_size = addu(arrsize, __arrayPad(arrsize, tinext), overflow);\n    if (overflow)\n    {\n        return BlkInfo();\n    }\n\n    return GC.qalloc(padded_size, info.attr, ti);\n}\n\n/**\n  cache for the lookup of the block info\n  */\nenum N_CACHE_BLOCKS=8;\n\n// note this is TLS, so no need to sync.\nBlkInfo *__blkcache_storage;\n\nstatic if (N_CACHE_BLOCKS==1)\n{\n    version=single_cache;\n}\nelse\n{\n    //version=simple_cache; // uncomment to test simple cache strategy\n    //version=random_cache; // uncomment to test random cache strategy\n\n    // ensure N_CACHE_BLOCKS is power of 2.\n    static assert(!((N_CACHE_BLOCKS - 1) & N_CACHE_BLOCKS));\n\n    version (random_cache)\n    {\n        int __nextRndNum = 0;\n    }\n    int __nextBlkIdx;\n}\n\n@property BlkInfo *__blkcache() nothrow\n{\n    if (!__blkcache_storage)\n    {\n        import core.stdc.stdlib;\n        import core.stdc.string;\n        // allocate the block cache for the first time\n        immutable size = BlkInfo.sizeof * N_CACHE_BLOCKS;\n        __blkcache_storage = cast(BlkInfo *)malloc(size);\n        memset(__blkcache_storage, 0, size);\n    }\n    return __blkcache_storage;\n}\n\n// called when thread is exiting.\nstatic ~this()\n{\n    // free the blkcache\n    if (__blkcache_storage)\n    {\n        import core.stdc.stdlib;\n        free(__blkcache_storage);\n        __blkcache_storage = null;\n    }\n}\n\n\n// we expect this to be called with the lock in place\nvoid processGCMarks(BlkInfo* cache, scope rt.tlsgc.IsMarkedDg isMarked) nothrow\n{\n    // called after the mark routine to eliminate block cache data when it\n    // might be ready to sweep\n\n    debug(PRINTF) printf(\"processing GC Marks, %x\\n\", cache);\n    if (cache)\n    {\n        debug(PRINTF) foreach (i; 0 .. N_CACHE_BLOCKS)\n        {\n            printf(\"cache entry %d has base ptr %x\\tsize %d\\tflags %x\\n\", i, cache[i].base, cache[i].size, cache[i].attr);\n        }\n        auto cache_end = cache + N_CACHE_BLOCKS;\n        for (;cache < cache_end; ++cache)\n        {\n            if (cache.base != null && !isMarked(cache.base))\n            {\n                debug(PRINTF) printf(\"clearing cache entry at %x\\n\", cache.base);\n                cache.base = null; // clear that data.\n            }\n        }\n    }\n}\n\nunittest\n{\n    // Bugzilla 10701 - segfault in GC\n    ubyte[] result; result.length = 4096;\n    GC.free(result.ptr);\n    GC.collect();\n}\n\n/**\n  Get the cached block info of an interior pointer.  Returns null if the\n  interior pointer's block is not cached.\n\n  NOTE: The base ptr in this struct can be cleared asynchronously by the GC,\n        so any use of the returned BlkInfo should copy it and then check the\n        base ptr of the copy before actually using it.\n\n  TODO: Change this function so the caller doesn't have to be aware of this\n        issue.  Either return by value and expect the caller to always check\n        the base ptr as an indication of whether the struct is valid, or set\n        the BlkInfo as a side-effect and return a bool to indicate success.\n  */\nBlkInfo *__getBlkInfo(void *interior) nothrow\n{\n    BlkInfo *ptr = __blkcache;\n    version (single_cache)\n    {\n        if (ptr.base && ptr.base <= interior && (interior - ptr.base) < ptr.size)\n            return ptr;\n        return null; // not in cache.\n    }\n    else version (simple_cache)\n    {\n        foreach (i; 0..N_CACHE_BLOCKS)\n        {\n            if (ptr.base && ptr.base <= interior && (interior - ptr.base) < ptr.size)\n                return ptr;\n            ptr++;\n        }\n    }\n    else\n    {\n        // try to do a smart lookup, using __nextBlkIdx as the \"head\"\n        auto curi = ptr + __nextBlkIdx;\n        for (auto i = curi; i >= ptr; --i)\n        {\n            if (i.base && i.base <= interior && cast(size_t)(interior - i.base) < i.size)\n                return i;\n        }\n\n        for (auto i = ptr + N_CACHE_BLOCKS - 1; i > curi; --i)\n        {\n            if (i.base && i.base <= interior && cast(size_t)(interior - i.base) < i.size)\n                return i;\n        }\n    }\n    return null; // not in cache.\n}\n\nvoid __insertBlkInfoCache(BlkInfo bi, BlkInfo *curpos) nothrow\n{\n    version (single_cache)\n    {\n        *__blkcache = bi;\n    }\n    else\n    {\n        version (simple_cache)\n        {\n            if (curpos)\n                *curpos = bi;\n            else\n            {\n                // note, this is a super-simple algorithm that does not care about\n                // most recently used.  It simply uses a round-robin technique to\n                // cache block info.  This means that the ordering of the cache\n                // doesn't mean anything.  Certain patterns of allocation may\n                // render the cache near-useless.\n                __blkcache[__nextBlkIdx] = bi;\n                __nextBlkIdx = (__nextBlkIdx+1) & (N_CACHE_BLOCKS - 1);\n            }\n        }\n        else version (random_cache)\n        {\n            // strategy: if the block currently is in the cache, move the\n            // current block index to the a random element and evict that\n            // element.\n            auto cache = __blkcache;\n            if (!curpos)\n            {\n                __nextBlkIdx = (__nextRndNum = 1664525 * __nextRndNum + 1013904223) & (N_CACHE_BLOCKS - 1);\n                curpos = cache + __nextBlkIdx;\n            }\n            else\n            {\n                __nextBlkIdx = curpos - cache;\n            }\n            *curpos = bi;\n        }\n        else\n        {\n            //\n            // strategy: If the block currently is in the cache, swap it with\n            // the head element.  Otherwise, move the head element up by one,\n            // and insert it there.\n            //\n            auto cache = __blkcache;\n            if (!curpos)\n            {\n                __nextBlkIdx = (__nextBlkIdx+1) & (N_CACHE_BLOCKS - 1);\n                curpos = cache + __nextBlkIdx;\n            }\n            else if (curpos !is cache + __nextBlkIdx)\n            {\n                *curpos = cache[__nextBlkIdx];\n                curpos = cache + __nextBlkIdx;\n            }\n            *curpos = bi;\n        }\n    }\n}\n\n/**\n * Shrink the \"allocated\" length of an array to be the exact size of the array.\n * It doesn't matter what the current allocated length of the array is, the\n * user is telling the runtime that he knows what he is doing.\n */\nextern(C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) /+nothrow+/\n{\n    // note, we do not care about shared.  We are setting the length no matter\n    // what, so no lock is required.\n    debug(PRINTF) printf(\"_d_arrayshrinkfit, elemsize = %d, arr.ptr = x%x arr.length = %d\\n\", ti.next.tsize, arr.ptr, arr.length);\n    auto tinext = unqualify(ti.next);\n    auto size = tinext.tsize;                  // array element size\n    auto cursize = arr.length * size;\n    auto isshared = typeid(ti) is typeid(TypeInfo_Shared);\n    auto bic = isshared ? null : __getBlkInfo(arr.ptr);\n    auto info = bic ? *bic : GC.query(arr.ptr);\n    if (info.base && (info.attr & BlkAttr.APPENDABLE))\n    {\n        auto newsize = (arr.ptr - __arrayStart(info)) + cursize;\n\n        debug(PRINTF) printf(\"setting allocated size to %d\\n\", (arr.ptr - info.base) + cursize);\n\n        // destroy structs that become unused memory when array size is shrinked\n        if (typeid(tinext) is typeid(TypeInfo_Struct)) // avoid a complete dynamic type cast\n        {\n            auto sti = cast(TypeInfo_Struct)cast(void*)tinext;\n            if (sti.xdtor)\n            {\n                auto oldsize = __arrayAllocLength(info, tinext);\n                if (oldsize > cursize)\n                    finalize_array(arr.ptr + cursize, oldsize - cursize, sti);\n            }\n        }\n        // Note: Since we \"assume\" the append is safe, it means it is not shared.\n        // Since it is not shared, we also know it won't throw (no lock).\n        if (!__setArrayAllocLength(info, newsize, false, tinext))\n        {\n            import core.exception : onInvalidMemoryOperationError;\n            onInvalidMemoryOperationError();\n        }\n\n        // cache the block if not already done.\n        if (!isshared && !bic)\n            __insertBlkInfoCache(info, null);\n    }\n}\n\npackage bool hasPostblit(in TypeInfo ti)\n{\n    return (&ti.postblit).funcptr !is &TypeInfo.postblit;\n}\n\nvoid __doPostblit(void *ptr, size_t len, const TypeInfo ti)\n{\n    if (!hasPostblit(ti))\n        return;\n\n    if (auto tis = cast(TypeInfo_Struct)ti)\n    {\n        // this is a struct, check the xpostblit member\n        auto pblit = tis.xpostblit;\n        if (!pblit)\n            // postblit not specified, no point in looping.\n            return;\n\n        // optimized for struct, call xpostblit directly for each element\n        immutable size = ti.tsize;\n        const eptr = ptr + len;\n        for (;ptr < eptr;ptr += size)\n            pblit(ptr);\n    }\n    else\n    {\n        // generic case, call the typeinfo's postblit function\n        immutable size = ti.tsize;\n        const eptr = ptr + len;\n        for (;ptr < eptr;ptr += size)\n            ti.postblit(ptr);\n    }\n}\n\n\n/**\n * set the array capacity.  If the array capacity isn't currently large enough\n * to hold the requested capacity (in number of elements), then the array is\n * resized/reallocated to the appropriate size.  Pass in a requested capacity\n * of 0 to get the current capacity.  Returns the number of elements that can\n * actually be stored once the resizing is done.\n */\nextern(C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void[]* p)\nin\n{\n    assert(ti);\n    assert(!(*p).length || (*p).ptr);\n}\ndo\n{\n    import core.stdc.string;\n    import core.exception : onOutOfMemoryError;\n\n    // step 1, get the block\n    auto isshared = typeid(ti) is typeid(TypeInfo_Shared);\n    auto bic = isshared ? null : __getBlkInfo((*p).ptr);\n    auto info = bic ? *bic : GC.query((*p).ptr);\n    auto tinext = unqualify(ti.next);\n    auto size = tinext.tsize;\n    version (D_InlineAsm_X86)\n    {\n        size_t reqsize = void;\n\n        asm\n        {\n            mov EAX, newcapacity;\n            mul EAX, size;\n            mov reqsize, EAX;\n            jnc  Lcontinue;\n        }\n    }\n    else version (D_InlineAsm_X86_64)\n    {\n        size_t reqsize = void;\n\n        asm\n        {\n            mov RAX, newcapacity;\n            mul RAX, size;\n            mov reqsize, RAX;\n            jnc  Lcontinue;\n        }\n    }\n    else\n    {\n        import core.checkedint : mulu;\n\n        bool overflow = false;\n        size_t reqsize = mulu(size, newcapacity, overflow);\n        if (!overflow)\n            goto Lcontinue;\n    }\nLoverflow:\n    onOutOfMemoryError();\n    assert(0);\nLcontinue:\n\n    // step 2, get the actual \"allocated\" size.  If the allocated size does not\n    // match what we expect, then we will need to reallocate anyways.\n\n    // TODO: this probably isn't correct for shared arrays\n    size_t curallocsize = void;\n    size_t curcapacity = void;\n    size_t offset = void;\n    size_t arraypad = void;\n    if (info.base && (info.attr & BlkAttr.APPENDABLE))\n    {\n        if (info.size <= 256)\n        {\n            arraypad = SMALLPAD + structTypeInfoSize(tinext);\n            curallocsize = *(cast(ubyte *)(info.base + info.size - arraypad));\n        }\n        else if (info.size < PAGESIZE)\n        {\n            arraypad = MEDPAD + structTypeInfoSize(tinext);\n            curallocsize = *(cast(ushort *)(info.base + info.size - arraypad));\n        }\n        else\n        {\n            curallocsize = *(cast(size_t *)(info.base));\n            arraypad = LARGEPAD;\n        }\n\n\n        offset = (*p).ptr - __arrayStart(info);\n        if (offset + (*p).length * size != curallocsize)\n        {\n            curcapacity = 0;\n        }\n        else\n        {\n            // figure out the current capacity of the block from the point\n            // of view of the array.\n            curcapacity = info.size - offset - arraypad;\n        }\n    }\n    else\n    {\n        curallocsize = curcapacity = offset = 0;\n    }\n    debug(PRINTF) printf(\"_d_arraysetcapacity, p = x%d,%d, newcapacity=%d, info.size=%d, reqsize=%d, curallocsize=%d, curcapacity=%d, offset=%d\\n\", (*p).ptr, (*p).length, newcapacity, info.size, reqsize, curallocsize, curcapacity, offset);\n\n    if (curcapacity >= reqsize)\n    {\n        // no problems, the current allocated size is large enough.\n        return curcapacity / size;\n    }\n\n    // step 3, try to extend the array in place.\n    if (info.size >= PAGESIZE && curcapacity != 0)\n    {\n        auto extendsize = reqsize + offset + LARGEPAD - info.size;\n        auto u = GC.extend(info.base, extendsize, extendsize);\n        if (u)\n        {\n            // extend worked, save the new current allocated size\n            if (bic)\n                bic.size = u; // update cache\n            curcapacity = u - offset - LARGEPAD;\n            return curcapacity / size;\n        }\n    }\n\n    // step 4, if extending doesn't work, allocate a new array with at least the requested allocated size.\n    auto datasize = (*p).length * size;\n    // copy attributes from original block, or from the typeinfo if the\n    // original block doesn't exist.\n    info = __arrayAlloc(reqsize, info, ti, tinext);\n    if (info.base is null)\n        goto Loverflow;\n    // copy the data over.\n    // note that malloc will have initialized the data we did not request to 0.\n    auto tgt = __arrayStart(info);\n    memcpy(tgt, (*p).ptr, datasize);\n\n    // handle postblit\n    __doPostblit(tgt, datasize, tinext);\n\n    if (!(info.attr & BlkAttr.NO_SCAN))\n    {\n        // need to memset the newly requested data, except for the data that\n        // malloc returned that we didn't request.\n        void *endptr = tgt + reqsize;\n        void *begptr = tgt + datasize;\n\n        // sanity check\n        assert(endptr >= begptr);\n        memset(begptr, 0, endptr - begptr);\n    }\n\n    // set up the correct length\n    __setArrayAllocLength(info, datasize, isshared, tinext);\n    if (!isshared)\n        __insertBlkInfoCache(info, bic);\n\n    *p = (cast(void*)tgt)[0 .. (*p).length];\n\n    // determine the padding.  This has to be done manually because __arrayPad\n    // assumes you are not counting the pad size, and info.size does include\n    // the pad.\n    if (info.size <= 256)\n        arraypad = SMALLPAD + structTypeInfoSize(tinext);\n    else if (info.size < PAGESIZE)\n        arraypad = MEDPAD + structTypeInfoSize(tinext);\n    else\n        arraypad = LARGEPAD;\n\n    curcapacity = info.size - arraypad;\n    return curcapacity / size;\n}\n\n/**\n * Allocate a new uninitialized array of length elements.\n * ti is the type of the resulting array, or pointer to element.\n */\nextern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow\n{\n    import core.exception : onOutOfMemoryError;\n\n    auto tinext = unqualify(ti.next);\n    auto size = tinext.tsize;\n\n    debug(PRINTF) printf(\"_d_newarrayU(length = x%x, size = %d)\\n\", length, size);\n    if (length == 0 || size == 0)\n        return null;\n\n    version (D_InlineAsm_X86)\n    {\n        asm pure nothrow @nogc\n        {\n            mov     EAX,size        ;\n            mul     EAX,length      ;\n            mov     size,EAX        ;\n            jnc     Lcontinue       ;\n        }\n    }\n    else version (D_InlineAsm_X86_64)\n    {\n        asm pure nothrow @nogc\n        {\n            mov     RAX,size        ;\n            mul     RAX,length      ;\n            mov     size,RAX        ;\n            jnc     Lcontinue       ;\n        }\n    }\n    else\n    {\n        import core.checkedint : mulu;\n\n        bool overflow = false;\n        size = mulu(size, length, overflow);\n        if (!overflow)\n            goto Lcontinue;\n    }\nLoverflow:\n    onOutOfMemoryError();\n    assert(0);\nLcontinue:\n\n    auto info = __arrayAlloc(size, ti, tinext);\n    if (!info.base)\n        goto Loverflow;\n    debug(PRINTF) printf(\" p = %p\\n\", info.base);\n    // update the length of the array\n    auto arrstart = __arrayStart(info);\n    auto isshared = typeid(ti) is typeid(TypeInfo_Shared);\n    __setArrayAllocLength(info, size, isshared, tinext);\n    return arrstart[0..length];\n}\n\n/**\n * Allocate a new array of length elements.\n * ti is the type of the resulting array, or pointer to element.\n * (For when the array is initialized to 0)\n */\nextern (C) void[] _d_newarrayT(const TypeInfo ti, size_t length) pure nothrow\n{\n    import core.stdc.string;\n\n    void[] result = _d_newarrayU(ti, length);\n    auto tinext = unqualify(ti.next);\n    auto size = tinext.tsize;\n\n    memset(result.ptr, 0, size * length);\n    return result;\n}\n\n/**\n * For when the array has a non-zero initializer.\n */\nextern (C) void[] _d_newarrayiT(const TypeInfo ti, size_t length) pure nothrow\n{\n    import core.internal.traits : TypeTuple;\n\n    void[] result = _d_newarrayU(ti, length);\n    auto tinext = unqualify(ti.next);\n    auto size = tinext.tsize;\n\n    auto init = tinext.initializer();\n\n    switch (init.length)\n    {\n    foreach (T; TypeTuple!(ubyte, ushort, uint, ulong))\n    {\n    case T.sizeof:\n        (cast(T*)result.ptr)[0 .. size * length / T.sizeof] = *cast(T*)init.ptr;\n        return result;\n    }\n\n    default:\n    {\n        import core.stdc.string;\n        immutable sz = init.length;\n        for (size_t u = 0; u < size * length; u += sz)\n            memcpy(result.ptr + u, init.ptr, sz);\n        return result;\n    }\n    }\n}\n\n\n/**\n *\n */\nvoid[] _d_newarrayOpT(alias op)(const TypeInfo ti, size_t[] dims)\n{\n    debug(PRINTF) printf(\"_d_newarrayOpT(ndims = %d)\\n\", dims.length);\n    if (dims.length == 0)\n        return null;\n\n    void[] foo(const TypeInfo ti, size_t[] dims)\n    {\n        auto tinext = unqualify(ti.next);\n        auto dim = dims[0];\n\n        debug(PRINTF) printf(\"foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\\n\", ti, ti.next, dim, dims.length);\n        if (dims.length == 1)\n        {\n            auto r = op(ti, dim);\n            return *cast(void[]*)(&r);\n        }\n\n        auto allocsize = (void[]).sizeof * dim;\n        auto info = __arrayAlloc(allocsize, ti, tinext);\n        auto isshared = typeid(ti) is typeid(TypeInfo_Shared);\n        __setArrayAllocLength(info, allocsize, isshared, tinext);\n        auto p = __arrayStart(info)[0 .. dim];\n\n        foreach (i; 0..dim)\n        {\n            (cast(void[]*)p.ptr)[i] = foo(tinext, dims[1..$]);\n        }\n        return p;\n    }\n\n    auto result = foo(ti, dims);\n    debug(PRINTF) printf(\"result = %llx\\n\", result.ptr);\n\n    return result;\n}\n\n\n/**\n *\n */\nextern (C) void[] _d_newarraymTX(const TypeInfo ti, size_t[] dims)\n{\n    debug(PRINTF) printf(\"_d_newarraymT(dims.length = %d)\\n\", dims.length);\n\n    if (dims.length == 0)\n        return null;\n    else\n    {\n        return _d_newarrayOpT!(_d_newarrayT)(ti, dims);\n    }\n}\n\n\n/**\n *\n */\nextern (C) void[] _d_newarraymiTX(const TypeInfo ti, size_t[] dims)\n{\n    debug(PRINTF) printf(\"_d_newarraymiT(dims.length = %d)\\n\", dims.length);\n\n    if (dims.length == 0)\n        return null;\n    else\n    {\n        return _d_newarrayOpT!(_d_newarrayiT)(ti, dims);\n    }\n}\n\n/**\n * Allocate an uninitialized non-array item.\n * This is an optimization to avoid things needed for arrays like the __arrayPad(size).\n */\nextern (C) void* _d_newitemU(in TypeInfo _ti)\n{\n    auto ti = unqualify(_ti);\n    auto flags = !(ti.flags & 1) ? BlkAttr.NO_SCAN : 0;\n    immutable tiSize = structTypeInfoSize(ti);\n    immutable size = ti.tsize + tiSize;\n    if (tiSize)\n        flags |= BlkAttr.STRUCTFINAL | BlkAttr.FINALIZE;\n\n    auto blkInf = GC.qalloc(size, flags, ti);\n    auto p = blkInf.base;\n\n    if (tiSize)\n        *cast(TypeInfo*)(p + blkInf.size - tiSize) = cast() ti;\n\n    return p;\n}\n\n/// Same as above, zero initializes the item.\nextern (C) void* _d_newitemT(in TypeInfo _ti)\n{\n    import core.stdc.string;\n    auto p = _d_newitemU(_ti);\n    memset(p, 0, _ti.tsize);\n    return p;\n}\n\n/// Same as above, for item with non-zero initializer.\nextern (C) void* _d_newitemiT(in TypeInfo _ti)\n{\n    import core.stdc.string;\n    auto p = _d_newitemU(_ti);\n    auto init = _ti.initializer();\n    assert(init.length <= _ti.tsize);\n    memcpy(p, init.ptr, init.length);\n    return p;\n}\n\n/**\n *\n */\nstruct Array\n{\n    size_t length;\n    byte*  data;\n}\n\ndebug(PRINTF)\n{\n    extern(C) void printArrayCache()\n    {\n        auto ptr = __blkcache;\n        printf(\"CACHE: \\n\");\n        foreach (i; 0 .. N_CACHE_BLOCKS)\n        {\n            printf(\"  %d\\taddr:% .8x\\tsize:% .10d\\tflags:% .8x\\n\", i, ptr[i].base, ptr[i].size, ptr[i].attr);\n        }\n    }\n}\n\n/**\n *\n */\nextern (C) void _d_delarray_t(void[]* p, const TypeInfo_Struct ti)\n{\n    if (p)\n    {\n        auto bic = __getBlkInfo(p.ptr);\n        auto info = bic ? *bic : GC.query(p.ptr);\n\n        if (info.base && (info.attr & BlkAttr.APPENDABLE))\n        {\n            if (ti) // ti non-null only if ti is a struct with dtor\n            {\n                void* start = __arrayStart(info);\n                size_t length = __arrayAllocLength(info, ti);\n                finalize_array(start, length, ti);\n            }\n\n            // if p is in the cache, clear it there as well\n            if (bic)\n                bic.base = null;\n\n            GC.free(info.base);\n            *p = null;\n        }\n    }\n}\n\nunittest\n{\n    __gshared size_t countDtor = 0;\n    struct S\n    {\n        int x;\n        ~this() { countDtor++; }\n    }\n    // destroy large array with x.ptr not base address of allocation\n    auto x = new S[10000];\n    void* p = x.ptr;\n    assert(GC.addrOf(p) != null);\n    delete x;\n    assert(GC.addrOf(p) == null);\n    assert(countDtor == 10000);\n\n    // destroy full array even if only slice passed\n    auto y = new S[400];\n    auto z = y[200 .. 300];\n    p = z.ptr;\n    assert(GC.addrOf(p) != null);\n    delete z;\n    assert(GC.addrOf(p) == null);\n    assert(countDtor == 10000 + 400);\n}\n\n/**\n *\n */\nextern (C) void _d_delmemory(void* *p)\n{\n    if (*p)\n    {\n        GC.free(*p);\n        *p = null;\n    }\n}\n\n\n/**\n *\n */\nextern (C) void _d_callinterfacefinalizer(void *p)\n{\n    if (p)\n    {\n        Interface *pi = **cast(Interface ***)p;\n        Object o = cast(Object)(p - pi.offset);\n        rt_finalize(cast(void*)o);\n    }\n}\n\n\n/**\n *\n */\nextern (C) void _d_callfinalizer(void* p)\n{\n    rt_finalize( p );\n}\n\n\n/**\n *\n */\nextern (C) void rt_setCollectHandler(CollectHandler h)\n{\n    collectHandler = h;\n}\n\n\n/**\n *\n */\nextern (C) CollectHandler rt_getCollectHandler()\n{\n    return collectHandler;\n}\n\n\n/**\n *\n */\nextern (C) int rt_hasFinalizerInSegment(void* p, size_t size, uint attr, in void[] segment) nothrow\n{\n    if (attr & BlkAttr.STRUCTFINAL)\n    {\n        if (attr & BlkAttr.APPENDABLE)\n            return hasArrayFinalizerInSegment(p, size, segment);\n        return hasStructFinalizerInSegment(p, size, segment);\n    }\n\n    // otherwise class\n    auto ppv = cast(void**) p;\n    if (!p || !*ppv)\n        return false;\n\n    auto c = *cast(ClassInfo*)*ppv;\n    do\n    {\n        auto pf = c.destructor;\n        if (cast(size_t)(pf - segment.ptr) < segment.length) return true;\n    }\n    while ((c = c.base) !is null);\n\n    return false;\n}\n\nint hasStructFinalizerInSegment(void* p, size_t size, in void[] segment) nothrow\n{\n    if (!p)\n        return false;\n\n    auto ti = *cast(TypeInfo_Struct*)(p + size - size_t.sizeof);\n    return cast(size_t)(cast(void*)ti.xdtor - segment.ptr) < segment.length;\n}\n\nint hasArrayFinalizerInSegment(void* p, size_t size, in void[] segment) nothrow\n{\n    if (!p)\n        return false;\n\n    TypeInfo_Struct si = void;\n    if (size < PAGESIZE)\n        si = *cast(TypeInfo_Struct*)(p + size - size_t.sizeof);\n    else\n        si = *cast(TypeInfo_Struct*)(p + size_t.sizeof);\n\n    return cast(size_t)(cast(void*)si.xdtor - segment.ptr) < segment.length;\n}\n\n// called by the GC\nvoid finalize_array2(void* p, size_t size) nothrow\n{\n    debug(PRINTF) printf(\"rt_finalize_array2(p = %p)\\n\", p);\n\n    TypeInfo_Struct si = void;\n    if (size <= 256)\n    {\n        si = *cast(TypeInfo_Struct*)(p + size - size_t.sizeof);\n        size = *cast(ubyte*)(p + size - size_t.sizeof - SMALLPAD);\n    }\n    else if (size < PAGESIZE)\n    {\n        si = *cast(TypeInfo_Struct*)(p + size - size_t.sizeof);\n        size = *cast(ushort*)(p + size - size_t.sizeof - MEDPAD);\n    }\n    else\n    {\n        si = *cast(TypeInfo_Struct*)(p + size_t.sizeof);\n        size = *cast(size_t*)p;\n        p += LARGEPREFIX;\n    }\n\n    try\n    {\n        finalize_array(p, size, si);\n    }\n    catch (Exception e)\n    {\n        import core.exception : onFinalizeError;\n        onFinalizeError(si, e);\n    }\n}\n\nvoid finalize_array(void* p, size_t size, const TypeInfo_Struct si)\n{\n    // Due to the fact that the delete operator calls destructors\n    // for arrays from the last element to the first, we maintain\n    // compatibility here by doing the same.\n    auto tsize = si.tsize;\n    for (auto curP = p + size - tsize; curP >= p; curP -= tsize)\n    {\n        // call destructor\n        si.destroy(curP);\n    }\n}\n\n// called by the GC\nvoid finalize_struct(void* p, size_t size) nothrow\n{\n    debug(PRINTF) printf(\"finalize_struct(p = %p)\\n\", p);\n\n    auto ti = *cast(TypeInfo_Struct*)(p + size - size_t.sizeof);\n    try\n    {\n        ti.destroy(p); // call destructor\n    }\n    catch (Exception e)\n    {\n        import core.exception : onFinalizeError;\n        onFinalizeError(ti, e);\n    }\n}\n\n/**\n *\n */\nextern (C) void rt_finalize2(void* p, bool det = true, bool resetMemory = true) nothrow\n{\n    debug(PRINTF) printf(\"rt_finalize2(p = %p)\\n\", p);\n\n    auto ppv = cast(void**) p;\n    if (!p || !*ppv)\n        return;\n\n    auto pc = cast(ClassInfo*) *ppv;\n    try\n    {\n        if (det || collectHandler is null || collectHandler(cast(Object) p))\n        {\n            auto c = *pc;\n            do\n            {\n                if (c.destructor)\n                    (cast(fp_t) c.destructor)(cast(Object) p); // call destructor\n            }\n            while ((c = c.base) !is null);\n        }\n\n        if (ppv[1]) // if monitor is not null\n            _d_monitordelete(cast(Object) p, det);\n\n        if (resetMemory)\n        {\n            auto w = (*pc).initializer;\n            p[0 .. w.length] = w[];\n        }\n    }\n    catch (Exception e)\n    {\n        import core.exception : onFinalizeError;\n        onFinalizeError(*pc, e);\n    }\n    finally\n    {\n        *ppv = null; // zero vptr even if `resetMemory` is false\n    }\n}\n\nextern (C) void rt_finalize(void* p, bool det = true)\n{\n    rt_finalize2(p, det, true);\n}\n\nextern (C) void rt_finalizeFromGC(void* p, size_t size, uint attr)\n{\n    // to verify: reset memory necessary?\n    if (!(attr & BlkAttr.STRUCTFINAL))\n        rt_finalize2(p, false, false); // class\n    else if (attr & BlkAttr.APPENDABLE)\n        finalize_array2(p, size); // array of structs\n    else\n        finalize_struct(p, size); // struct\n}\n\n\n/**\n * Resize dynamic arrays with 0 initializers.\n */\nextern (C) void[] _d_arraysetlengthT(const TypeInfo ti, size_t newlength, void[]* p)\nin\n{\n    assert(ti);\n    assert(!(*p).length || (*p).ptr);\n}\ndo\n{\n    import core.stdc.string;\n    import core.exception : onOutOfMemoryError;\n\n    debug(PRINTF)\n    {\n        //printf(\"_d_arraysetlengthT(p = %p, sizeelem = %d, newlength = %d)\\n\", p, sizeelem, newlength);\n        if (p)\n            printf(\"\\tp.ptr = %p, p.length = %d\\n\", (*p).ptr, (*p).length);\n    }\n\n    if (newlength <= (*p).length)\n    {\n        *p = (*p)[0 .. newlength];\n        void* newdata = (*p).ptr;\n        return newdata[0 .. newlength];\n    }\n    auto tinext = unqualify(ti.next);\n    size_t sizeelem = tinext.tsize;\n\n    /* Calculate: newsize = newlength * sizeelem\n     */\n    bool overflow = false;\n    version (D_InlineAsm_X86)\n    {\n        size_t newsize = void;\n\n        asm pure nothrow @nogc\n        {\n            mov EAX, newlength;\n            mul EAX, sizeelem;\n            mov newsize, EAX;\n            setc overflow;\n        }\n    }\n    else version (D_InlineAsm_X86_64)\n    {\n        size_t newsize = void;\n\n        asm pure nothrow @nogc\n        {\n            mov RAX, newlength;\n            mul RAX, sizeelem;\n            mov newsize, RAX;\n            setc overflow;\n        }\n    }\n    else\n    {\n        import core.checkedint : mulu;\n        const size_t newsize = mulu(sizeelem, newlength, overflow);\n    }\n    if (overflow)\n    {\n        onOutOfMemoryError();\n        assert(0);\n    }\n\n    debug(PRINTF) printf(\"newsize = %x, newlength = %x\\n\", newsize, newlength);\n\n    const isshared = typeid(ti) is typeid(TypeInfo_Shared);\n\n    if (!(*p).ptr)\n    {\n        // pointer was null, need to allocate\n        auto info = __arrayAlloc(newsize, ti, tinext);\n        if (info.base is null)\n        {\n            onOutOfMemoryError();\n            assert(0);\n        }\n        __setArrayAllocLength(info, newsize, isshared, tinext);\n        if (!isshared)\n            __insertBlkInfoCache(info, null);\n        void* newdata = cast(byte *)__arrayStart(info);\n        memset(newdata, 0, newsize);\n        *p = newdata[0 .. newlength];\n        return *p;\n    }\n\n    const size_t size = (*p).length * sizeelem;\n    auto   bic = isshared ? null : __getBlkInfo((*p).ptr);\n    auto   info = bic ? *bic : GC.query((*p).ptr);\n\n    /* Attempt to extend past the end of the existing array.\n     * If not possible, allocate new space for entire array and copy.\n     */\n    bool allocateAndCopy = false;\n    void* newdata = (*p).ptr;\n    if (info.base && (info.attr & BlkAttr.APPENDABLE))\n    {\n        // calculate the extent of the array given the base.\n        const size_t offset = (*p).ptr - __arrayStart(info);\n        if (info.size >= PAGESIZE)\n        {\n            // size of array is at the front of the block\n            if (!__setArrayAllocLength(info, newsize + offset, isshared, tinext, size + offset))\n            {\n                // check to see if it failed because there is not\n                // enough space\n                if (*(cast(size_t*)info.base) == size + offset)\n                {\n                    // not enough space, try extending\n                    auto extendsize = newsize + offset + LARGEPAD - info.size;\n                    auto u = GC.extend(info.base, extendsize, extendsize);\n                    if (u)\n                    {\n                        // extend worked, now try setting the length\n                        // again.\n                        info.size = u;\n                        if (__setArrayAllocLength(info, newsize + offset, isshared, tinext, size + offset))\n                        {\n                            if (!isshared)\n                                __insertBlkInfoCache(info, bic);\n                            memset(newdata + size, 0, newsize - size);\n                            *p = newdata[0 .. newlength];\n                            return *p;\n                        }\n                    }\n                }\n\n                // couldn't do it, reallocate\n                allocateAndCopy = true;\n            }\n            else if (!isshared && !bic)\n            {\n                // add this to the cache, it wasn't present previously.\n                __insertBlkInfoCache(info, null);\n            }\n        }\n        else if (!__setArrayAllocLength(info, newsize + offset, isshared, tinext, size + offset))\n        {\n            // could not resize in place\n            allocateAndCopy = true;\n        }\n        else if (!isshared && !bic)\n        {\n            // add this to the cache, it wasn't present previously.\n            __insertBlkInfoCache(info, null);\n        }\n    }\n    else\n        allocateAndCopy = true;\n\n    if (allocateAndCopy)\n    {\n        if (info.base)\n        {\n            if (bic)\n            {\n                // a chance that flags have changed since this was cached, we should fetch the most recent flags\n                info.attr = GC.getAttr(info.base) | BlkAttr.APPENDABLE;\n            }\n            info = __arrayAlloc(newsize, info, ti, tinext);\n        }\n        else\n        {\n            info = __arrayAlloc(newsize, ti, tinext);\n        }\n\n        if (info.base is null)\n        {\n            onOutOfMemoryError();\n            assert(0);\n        }\n\n        __setArrayAllocLength(info, newsize, isshared, tinext);\n        if (!isshared)\n            __insertBlkInfoCache(info, bic);\n        newdata = cast(byte *)__arrayStart(info);\n        newdata[0 .. size] = (*p).ptr[0 .. size];\n\n        /* Do postblit processing, as we are making a copy and the\n         * original array may have references.\n         * Note that this may throw.\n         */\n        __doPostblit(newdata, size, tinext);\n    }\n\n    // Zero the unused portion of the newly allocated space\n    memset(newdata + size, 0, newsize - size);\n\n    *p = newdata[0 .. newlength];\n    return *p;\n}\n\n\n/**\n * Resize arrays for non-zero initializers.\n *      p               pointer to array lvalue to be updated\n *      newlength       new .length property of array\n *      sizeelem        size of each element of array\n *      initsize        size of initializer\n *      ...             initializer\n */\nextern (C) void[] _d_arraysetlengthiT(const TypeInfo ti, size_t newlength, void[]* p)\nin\n{\n    assert(!(*p).length || (*p).ptr);\n}\ndo\n{\n    import core.stdc.string;\n    import core.exception : onOutOfMemoryError;\n\n    debug(PRINTF)\n    {\n        //printf(\"_d_arraysetlengthiT(p = %p, sizeelem = %d, newlength = %d)\\n\", p, sizeelem, newlength);\n        if (p)\n            printf(\"\\tp.ptr = %p, p.length = %d\\n\", (*p).ptr, (*p).length);\n    }\n\n    if (newlength <= (*p).length)\n    {\n        *p = (*p)[0 .. newlength];\n        void* newdata = (*p).ptr;\n        return newdata[0 .. newlength];\n    }\n    auto tinext = unqualify(ti.next);\n    size_t sizeelem = tinext.tsize;\n\n    /* Calculate: newsize = newlength * sizeelem\n     */\n    bool overflow = false;\n    version (D_InlineAsm_X86)\n    {\n        size_t newsize = void;\n\n        asm pure nothrow @nogc\n        {\n            mov EAX, newlength;\n            mul EAX, sizeelem;\n            mov newsize, EAX;\n            setc overflow;\n        }\n    }\n    else version (D_InlineAsm_X86_64)\n    {\n        size_t newsize = void;\n\n        asm pure nothrow @nogc\n        {\n            mov RAX, newlength;\n            mul RAX, sizeelem;\n            mov newsize, RAX;\n            setc overflow;\n        }\n    }\n    else\n    {\n        import core.checkedint : mulu;\n        const size_t newsize = mulu(sizeelem, newlength, overflow);\n    }\n    if (overflow)\n    {\n        onOutOfMemoryError();\n        assert(0);\n    }\n\n    debug(PRINTF) printf(\"newsize = %x, newlength = %x\\n\", newsize, newlength);\n\n    const isshared = typeid(ti) is typeid(TypeInfo_Shared);\n\n    static void doInitialize(void *start, void *end, const void[] initializer)\n    {\n        if (initializer.length == 1)\n        {\n            memset(start, *(cast(ubyte*)initializer.ptr), end - start);\n        }\n        else\n        {\n            auto q = initializer.ptr;\n            immutable initsize = initializer.length;\n            for (; start < end; start += initsize)\n            {\n                memcpy(start, q, initsize);\n            }\n        }\n    }\n\n    if (!(*p).ptr)\n    {\n        // pointer was null, need to allocate\n        auto info = __arrayAlloc(newsize, ti, tinext);\n        if (info.base is null)\n        {\n            onOutOfMemoryError();\n            assert(0);\n        }\n        __setArrayAllocLength(info, newsize, isshared, tinext);\n        if (!isshared)\n            __insertBlkInfoCache(info, null);\n        void* newdata = cast(byte *)__arrayStart(info);\n        doInitialize(newdata, newdata + newsize, tinext.initializer);\n        *p = newdata[0 .. newlength];\n        return *p;\n    }\n\n    const size_t size = (*p).length * sizeelem;\n    auto   bic = isshared ? null : __getBlkInfo((*p).ptr);\n    auto   info = bic ? *bic : GC.query((*p).ptr);\n\n    /* Attempt to extend past the end of the existing array.\n     * If not possible, allocate new space for entire array and copy.\n     */\n    bool allocateAndCopy = false;\n    void* newdata = (*p).ptr;\n\n    if (info.base && (info.attr & BlkAttr.APPENDABLE))\n    {\n        // calculate the extent of the array given the base.\n        const size_t offset = (*p).ptr - __arrayStart(info);\n        if (info.size >= PAGESIZE)\n        {\n            // size of array is at the front of the block\n            if (!__setArrayAllocLength(info, newsize + offset, isshared, tinext, size + offset))\n            {\n                // check to see if it failed because there is not\n                // enough space\n                if (*(cast(size_t*)info.base) == size + offset)\n                {\n                    // not enough space, try extending\n                    auto extendsize = newsize + offset + LARGEPAD - info.size;\n                    auto u = GC.extend(info.base, extendsize, extendsize);\n                    if (u)\n                    {\n                        // extend worked, now try setting the length\n                        // again.\n                        info.size = u;\n                        if (__setArrayAllocLength(info, newsize + offset, isshared, tinext, size + offset))\n                        {\n                            if (!isshared)\n                                __insertBlkInfoCache(info, bic);\n                            doInitialize(newdata + size, newdata + newsize, tinext.initializer);\n                            *p = newdata[0 .. newlength];\n                            return *p;\n                        }\n                    }\n                }\n\n                // couldn't do it, reallocate\n                allocateAndCopy = true;\n            }\n            else if (!isshared && !bic)\n            {\n                // add this to the cache, it wasn't present previously.\n                __insertBlkInfoCache(info, null);\n            }\n        }\n        else if (!__setArrayAllocLength(info, newsize + offset, isshared, tinext, size + offset))\n        {\n            // could not resize in place\n            allocateAndCopy = true;\n        }\n        else if (!isshared && !bic)\n        {\n            // add this to the cache, it wasn't present previously.\n            __insertBlkInfoCache(info, null);\n        }\n    }\n    else\n        allocateAndCopy = true;\n\n    if (allocateAndCopy)\n    {\n        if (info.base)\n        {\n            if (bic)\n            {\n                // a chance that flags have changed since this was cached, we should fetch the most recent flags\n                info.attr = GC.getAttr(info.base) | BlkAttr.APPENDABLE;\n            }\n            info = __arrayAlloc(newsize, info, ti, tinext);\n        }\n        else\n        {\n            info = __arrayAlloc(newsize, ti, tinext);\n        }\n\n        if (info.base is null)\n        {\n            onOutOfMemoryError();\n            assert(0);\n        }\n\n        __setArrayAllocLength(info, newsize, isshared, tinext);\n        if (!isshared)\n            __insertBlkInfoCache(info, bic);\n        newdata = cast(byte *)__arrayStart(info);\n        newdata[0 .. size] = (*p).ptr[0 .. size];\n\n        /* Do postblit processing, as we are making a copy and the\n         * original array may have references.\n         * Note that this may throw.\n         */\n        __doPostblit(newdata, size, tinext);\n    }\n\n    // Initialize the unused portion of the newly allocated space\n    doInitialize(newdata + size, newdata + newsize, tinext.initializer);\n    *p = newdata[0 .. newlength];\n    return *p;\n}\n\n/**\n * Append y[] to array x[]\n */\nextern (C) void[] _d_arrayappendT(const TypeInfo ti, ref byte[] x, byte[] y)\n{\n    import core.stdc.string;\n    auto length = x.length;\n    auto tinext = unqualify(ti.next);\n    auto sizeelem = tinext.tsize;              // array element size\n    _d_arrayappendcTX(ti, x, y.length);\n    memcpy(x.ptr + length * sizeelem, y.ptr, y.length * sizeelem);\n\n    // do postblit\n    __doPostblit(x.ptr + length * sizeelem, y.length * sizeelem, tinext);\n    return x;\n}\n\n\n/**\n *\n */\nsize_t newCapacity(size_t newlength, size_t size)\n{\n    version (none)\n    {\n        size_t newcap = newlength * size;\n    }\n    else\n    {\n        /*\n         * Better version by Dave Fladebo:\n         * This uses an inverse logorithmic algorithm to pre-allocate a bit more\n         * space for larger arrays.\n         * - Arrays smaller than PAGESIZE bytes are left as-is, so for the most\n         * common cases, memory allocation is 1 to 1. The small overhead added\n         * doesn't affect small array perf. (it's virtually the same as\n         * current).\n         * - Larger arrays have some space pre-allocated.\n         * - As the arrays grow, the relative pre-allocated space shrinks.\n         * - The logorithmic algorithm allocates relatively more space for\n         * mid-size arrays, making it very fast for medium arrays (for\n         * mid-to-large arrays, this turns out to be quite a bit faster than the\n         * equivalent realloc() code in C, on Linux at least. Small arrays are\n         * just as fast as GCC).\n         * - Perhaps most importantly, overall memory usage and stress on the GC\n         * is decreased significantly for demanding environments.\n         */\n        size_t newcap = newlength * size;\n        size_t newext = 0;\n\n        if (newcap > PAGESIZE)\n        {\n            //double mult2 = 1.0 + (size / log10(pow(newcap * 2.0,2.0)));\n\n            // redo above line using only integer math\n\n            /*static int log2plus1(size_t c)\n            {   int i;\n\n                if (c == 0)\n                    i = -1;\n                else\n                    for (i = 1; c >>= 1; i++)\n                    {\n                    }\n                return i;\n            }*/\n\n            /* The following setting for mult sets how much bigger\n             * the new size will be over what is actually needed.\n             * 100 means the same size, more means proportionally more.\n             * More means faster but more memory consumption.\n             */\n            //long mult = 100 + (1000L * size) / (6 * log2plus1(newcap));\n            //long mult = 100 + (1000L * size) / log2plus1(newcap);\n            import core.bitop;\n            long mult = 100 + (1000L) / (bsr(newcap) + 1);\n\n            // testing shows 1.02 for large arrays is about the point of diminishing return\n            //\n            // Commented out because the multipler will never be < 102.  In order for it to be < 2,\n            // then 1000L / (bsr(x) + 1) must be > 2.  The highest bsr(x) + 1\n            // could be is 65 (64th bit set), and 1000L / 64 is much larger\n            // than 2.  We need 500 bit integers for 101 to be achieved :)\n            /*if (mult < 102)\n                mult = 102;*/\n            /*newext = cast(size_t)((newcap * mult) / 100);\n            newext -= newext % size;*/\n            // This version rounds up to the next element, and avoids using\n            // mod.\n            newext = cast(size_t)((newlength * mult + 99) / 100) * size;\n            debug(PRINTF) printf(\"mult: %2.2f, alloc: %2.2f\\n\",mult/100.0,newext / cast(double)size);\n        }\n        newcap = newext > newcap ? newext : newcap;\n        debug(PRINTF) printf(\"newcap = %d, newlength = %d, size = %d\\n\", newcap, newlength, size);\n    }\n    return newcap;\n}\n\n\n/**************************************\n * Extend an array by n elements.\n * Caller must initialize those elements.\n */\nextern (C)\nbyte[] _d_arrayappendcTX(const TypeInfo ti, ref byte[] px, size_t n)\n{\n    import core.stdc.string;\n    // This is a cut&paste job from _d_arrayappendT(). Should be refactored.\n\n    // only optimize array append where ti is not a shared type\n    auto tinext = unqualify(ti.next);\n    auto sizeelem = tinext.tsize;              // array element size\n    auto isshared = typeid(ti) is typeid(TypeInfo_Shared);\n    auto bic = isshared ? null : __getBlkInfo(px.ptr);\n    auto info = bic ? *bic : GC.query(px.ptr);\n    auto length = px.length;\n    auto newlength = length + n;\n    auto newsize = newlength * sizeelem;\n    auto size = length * sizeelem;\n    size_t newcap = void; // for scratch space\n\n    // calculate the extent of the array given the base.\n    size_t offset = cast(void*)px.ptr - __arrayStart(info);\n    if (info.base && (info.attr & BlkAttr.APPENDABLE))\n    {\n        if (info.size >= PAGESIZE)\n        {\n            // size of array is at the front of the block\n            if (!__setArrayAllocLength(info, newsize + offset, isshared, tinext, size + offset))\n            {\n                // check to see if it failed because there is not\n                // enough space\n                newcap = newCapacity(newlength, sizeelem);\n                if (*(cast(size_t*)info.base) == size + offset)\n                {\n                    // not enough space, try extending\n                    auto extendoffset = offset + LARGEPAD - info.size;\n                    auto u = GC.extend(info.base, newsize + extendoffset, newcap + extendoffset);\n                    if (u)\n                    {\n                        // extend worked, now try setting the length\n                        // again.\n                        info.size = u;\n                        if (__setArrayAllocLength(info, newsize + offset, isshared, tinext, size + offset))\n                        {\n                            if (!isshared)\n                                __insertBlkInfoCache(info, bic);\n                            goto L1;\n                        }\n                    }\n                }\n\n                // couldn't do it, reallocate\n                goto L2;\n            }\n            else if (!isshared && !bic)\n            {\n                __insertBlkInfoCache(info, null);\n            }\n        }\n        else if (!__setArrayAllocLength(info, newsize + offset, isshared, tinext, size + offset))\n        {\n            // could not resize in place\n            newcap = newCapacity(newlength, sizeelem);\n            goto L2;\n        }\n        else if (!isshared && !bic)\n        {\n            __insertBlkInfoCache(info, null);\n        }\n    }\n    else\n    {\n        // not appendable or is null\n        newcap = newCapacity(newlength, sizeelem);\n        if (info.base)\n        {\n    L2:\n            if (bic)\n            {\n                // a chance that flags have changed since this was cached, we should fetch the most recent flags\n                info.attr = GC.getAttr(info.base) | BlkAttr.APPENDABLE;\n            }\n            info = __arrayAlloc(newcap, info, ti, tinext);\n        }\n        else\n        {\n            info = __arrayAlloc(newcap, ti, tinext);\n        }\n        __setArrayAllocLength(info, newsize, isshared, tinext);\n        if (!isshared)\n            __insertBlkInfoCache(info, bic);\n        auto newdata = cast(byte *)__arrayStart(info);\n        memcpy(newdata, px.ptr, length * sizeelem);\n        // do postblit processing\n        __doPostblit(newdata, length * sizeelem, tinext);\n        (cast(void **)(&px))[1] = newdata;\n    }\n\n  L1:\n    *cast(size_t *)&px = newlength;\n    return px;\n}\n\n\n/**\n * Append dchar to char[]\n */\nextern (C) void[] _d_arrayappendcd(ref byte[] x, dchar c)\n{\n    // c could encode into from 1 to 4 characters\n    char[4] buf = void;\n    byte[] appendthis; // passed to appendT\n    if (c <= 0x7F)\n    {\n        buf.ptr[0] = cast(char)c;\n        appendthis = (cast(byte *)buf.ptr)[0..1];\n    }\n    else if (c <= 0x7FF)\n    {\n        buf.ptr[0] = cast(char)(0xC0 | (c >> 6));\n        buf.ptr[1] = cast(char)(0x80 | (c & 0x3F));\n        appendthis = (cast(byte *)buf.ptr)[0..2];\n    }\n    else if (c <= 0xFFFF)\n    {\n        buf.ptr[0] = cast(char)(0xE0 | (c >> 12));\n        buf.ptr[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n        buf.ptr[2] = cast(char)(0x80 | (c & 0x3F));\n        appendthis = (cast(byte *)buf.ptr)[0..3];\n    }\n    else if (c <= 0x10FFFF)\n    {\n        buf.ptr[0] = cast(char)(0xF0 | (c >> 18));\n        buf.ptr[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));\n        buf.ptr[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n        buf.ptr[3] = cast(char)(0x80 | (c & 0x3F));\n        appendthis = (cast(byte *)buf.ptr)[0..4];\n    }\n    else\n    {\n        import core.exception : onUnicodeError;\n        onUnicodeError(\"Invalid UTF-8 sequence\", 0);      // invalid utf character\n    }\n\n    //\n    // TODO: This always assumes the array type is shared, because we do not\n    // get a typeinfo from the compiler.  Assuming shared is the safest option.\n    // Once the compiler is fixed, the proper typeinfo should be forwarded.\n    //\n    return _d_arrayappendT(typeid(shared char[]), x, appendthis);\n}\n\nunittest\n{\n    import core.exception : UnicodeException;\n\n    /* Using inline try {} catch {} blocks fails to catch the UnicodeException\n     * thrown.\n     * https://issues.dlang.org/show_bug.cgi?id=16799\n     */\n    static void assertThrown(T : Throwable = Exception, E)(lazy E expr, string msg)\n    {\n        try\n            expr;\n        catch (T e) {\n            assert(e.msg == msg);\n            return;\n        }\n    }\n\n    static void f()\n    {\n        string ret;\n        int i = -1;\n        ret ~= i;\n    }\n\n    assertThrown!UnicodeException(f(), \"Invalid UTF-8 sequence\");\n}\n\n\n/**\n * Append dchar to wchar[]\n */\nextern (C) void[] _d_arrayappendwd(ref byte[] x, dchar c)\n{\n    // c could encode into from 1 to 2 w characters\n    wchar[2] buf = void;\n    byte[] appendthis; // passed to appendT\n    if (c <= 0xFFFF)\n    {\n        buf.ptr[0] = cast(wchar) c;\n        // note that although we are passing only 1 byte here, appendT\n        // interprets this as being an array of wchar, making the necessary\n        // casts.\n        appendthis = (cast(byte *)buf.ptr)[0..1];\n    }\n    else\n    {\n        buf.ptr[0] = cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);\n        buf.ptr[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00);\n        // ditto from above.\n        appendthis = (cast(byte *)buf.ptr)[0..2];\n    }\n\n    //\n    // TODO: This always assumes the array type is shared, because we do not\n    // get a typeinfo from the compiler.  Assuming shared is the safest option.\n    // Once the compiler is fixed, the proper typeinfo should be forwarded.\n    //\n    return _d_arrayappendT(typeid(shared wchar[]), x, appendthis);\n}\n\n\n/**\n *\n */\nextern (C) byte[] _d_arraycatT(const TypeInfo ti, byte[] x, byte[] y)\nout (result)\n{\n    auto tinext = unqualify(ti.next);\n    auto sizeelem = tinext.tsize;              // array element size\n    debug(PRINTF) printf(\"_d_arraycatT(%d,%p ~ %d,%p sizeelem = %d => %d,%p)\\n\", x.length, x.ptr, y.length, y.ptr, sizeelem, result.length, result.ptr);\n    assert(result.length == x.length + y.length);\n\n    // If a postblit is involved, the contents of result might rightly differ\n    // from the bitwise concatenation of x and y.\n    if (!hasPostblit(tinext))\n    {\n        for (size_t i = 0; i < x.length * sizeelem; i++)\n            assert((cast(byte*)result)[i] == (cast(byte*)x)[i]);\n        for (size_t i = 0; i < y.length * sizeelem; i++)\n            assert((cast(byte*)result)[x.length * sizeelem + i] == (cast(byte*)y)[i]);\n    }\n\n    size_t cap = GC.sizeOf(result.ptr);\n    assert(!cap || cap > result.length * sizeelem);\n}\ndo\n{\n    import core.stdc.string;\n    version (none)\n    {\n        /* Cannot use this optimization because:\n         *  char[] a, b;\n         *  char c = 'a';\n         *  b = a ~ c;\n         *  c = 'b';\n         * will change the contents of b.\n         */\n        if (!y.length)\n            return x;\n        if (!x.length)\n            return y;\n    }\n\n    auto tinext = unqualify(ti.next);\n    auto sizeelem = tinext.tsize;              // array element size\n    debug(PRINTF) printf(\"_d_arraycatT(%d,%p ~ %d,%p sizeelem = %d)\\n\", x.length, x.ptr, y.length, y.ptr, sizeelem);\n    size_t xlen = x.length * sizeelem;\n    size_t ylen = y.length * sizeelem;\n    size_t len  = xlen + ylen;\n\n    if (!len)\n        return null;\n\n    auto info = __arrayAlloc(len, ti, tinext);\n    byte* p = cast(byte*)__arrayStart(info);\n    p[len] = 0; // guessing this is to optimize for null-terminated arrays?\n    memcpy(p, x.ptr, xlen);\n    memcpy(p + xlen, y.ptr, ylen);\n    // do postblit processing\n    __doPostblit(p, xlen + ylen, tinext);\n\n    auto isshared = typeid(ti) is typeid(TypeInfo_Shared);\n    __setArrayAllocLength(info, len, isshared, tinext);\n    return p[0 .. x.length + y.length];\n}\n\n\n/**\n *\n */\nextern (C) void[] _d_arraycatnTX(const TypeInfo ti, byte[][] arrs)\n{\n    import core.stdc.string;\n\n    size_t length;\n    auto tinext = unqualify(ti.next);\n    auto size = tinext.tsize;   // array element size\n\n    foreach (b; arrs)\n        length += b.length;\n\n    if (!length)\n        return null;\n\n    auto allocsize = length * size;\n    auto info = __arrayAlloc(allocsize, ti, tinext);\n    auto isshared = typeid(ti) is typeid(TypeInfo_Shared);\n    __setArrayAllocLength(info, allocsize, isshared, tinext);\n    void *a = __arrayStart (info);\n\n    size_t j = 0;\n    foreach (b; arrs)\n    {\n        if (b.length)\n        {\n            memcpy(a + j, b.ptr, b.length * size);\n            j += b.length * size;\n        }\n    }\n\n    // do postblit processing\n    __doPostblit(a, j, tinext);\n\n    return a[0..length];\n}\n\n\n/**\n * Allocate the array, rely on the caller to do the initialization of the array.\n */\nextern (C)\nvoid* _d_arrayliteralTX(const TypeInfo ti, size_t length)\n{\n    auto tinext = unqualify(ti.next);\n    auto sizeelem = tinext.tsize;              // array element size\n    void* result;\n\n    debug(PRINTF) printf(\"_d_arrayliteralTX(sizeelem = %d, length = %d)\\n\", sizeelem, length);\n    if (length == 0 || sizeelem == 0)\n        result = null;\n    else\n    {\n        auto allocsize = length * sizeelem;\n        auto info = __arrayAlloc(allocsize, ti, tinext);\n        auto isshared = typeid(ti) is typeid(TypeInfo_Shared);\n        __setArrayAllocLength(info, allocsize, isshared, tinext);\n        result = __arrayStart(info);\n    }\n    return result;\n}\n\n\nunittest\n{\n    int[] a;\n    int[] b;\n    int i;\n\n    a = new int[3];\n    a[0] = 1; a[1] = 2; a[2] = 3;\n    b = a.dup;\n    assert(b.length == 3);\n    for (i = 0; i < 3; i++)\n        assert(b[i] == i + 1);\n\n    // test slice appending\n    b = a[0..1];\n    b ~= 4;\n    for (i = 0; i < 3; i++)\n        assert(a[i] == i + 1);\n\n    // test reserving\n    char[] arr = new char[4093];\n    for (i = 0; i < arr.length; i++)\n        arr[i] = cast(char)(i % 256);\n\n    // note that these two commands used to cause corruption, which may not be\n    // detected.\n    arr.reserve(4094);\n    auto arr2 = arr ~ \"123\";\n    assert(arr2[0..arr.length] == arr);\n    assert(arr2[arr.length..$] == \"123\");\n\n    // test postblit on array concat, append, length, etc.\n    static struct S\n    {\n        int x;\n        int pad;\n        this(this)\n        {\n            ++x;\n        }\n    }\n    void testPostBlit(T)()\n    {\n        auto sarr = new T[1];\n        debug(SENTINEL) {} else\n            assert(sarr.capacity == 1);\n\n        // length extend\n        auto sarr2 = sarr;\n        assert(sarr[0].x == 0);\n        sarr2.length += 1;\n        assert(sarr2[0].x == 1);\n        assert(sarr[0].x == 0);\n\n        // append\n        T s;\n        sarr2 = sarr;\n        sarr2 ~= s;\n        assert(sarr2[0].x == 1);\n        assert(sarr2[1].x == 1);\n        assert(sarr[0].x == 0);\n        assert(s.x == 0);\n\n        // concat\n        sarr2 = sarr ~ sarr;\n        assert(sarr2[0].x == 1);\n        assert(sarr2[1].x == 1);\n        assert(sarr[0].x == 0);\n\n        // concat multiple (calls different method)\n        sarr2 = sarr ~ sarr ~ sarr;\n        assert(sarr2[0].x == 1);\n        assert(sarr2[1].x == 1);\n        assert(sarr2[2].x == 1);\n        assert(sarr[0].x == 0);\n\n        // reserve capacity\n        sarr2 = sarr;\n        sarr2.reserve(2);\n        assert(sarr2[0].x == 1);\n        assert(sarr[0].x == 0);\n    }\n    testPostBlit!(S)();\n    testPostBlit!(const(S))();\n}\n\n// cannot define structs inside unit test block, or they become nested structs.\nversion (unittest)\n{\n    struct S1\n    {\n        int x = 5;\n    }\n    struct S2\n    {\n        int x;\n        this(int x) {this.x = x;}\n    }\n    struct S3\n    {\n        int[4] x;\n        this(int x)\n        {this.x[] = x;}\n    }\n    struct S4\n    {\n        int *x;\n    }\n\n}\n\nunittest\n{\n    auto s1 = new S1;\n    assert(s1.x == 5);\n    assert(GC.getAttr(s1) == BlkAttr.NO_SCAN);\n\n    auto s2 = new S2(3);\n    assert(s2.x == 3);\n    assert(GC.getAttr(s2) == BlkAttr.NO_SCAN);\n\n    auto s3 = new S3(1);\n    assert(s3.x == [1,1,1,1]);\n    assert(GC.getAttr(s3) == BlkAttr.NO_SCAN);\n    debug(SENTINEL) {} else\n        assert(GC.sizeOf(s3) == 16);\n\n    auto s4 = new S4;\n    assert(s4.x == null);\n    assert(GC.getAttr(s4) == 0);\n}\n\nunittest\n{\n    // Bugzilla 3454 - Inconsistent flag setting in GC.realloc()\n    static void test(size_t multiplier)\n    {\n        auto p = GC.malloc(8 * multiplier, BlkAttr.NO_SCAN);\n        assert(GC.getAttr(p) == BlkAttr.NO_SCAN);\n        p = GC.realloc(p, 2 * multiplier, BlkAttr.NO_SCAN);\n        assert(GC.getAttr(p) == BlkAttr.NO_SCAN);\n    }\n    test(1);\n    test(1024 * 1024);\n}\n\nunittest\n{\n    import core.exception;\n    try\n    {\n        size_t x = size_t.max;\n        byte[] big_buf = new byte[x];\n    }\n    catch (OutOfMemoryError)\n    {\n    }\n}\n\nunittest\n{\n    // bugzilla 13854\n    auto arr = new ubyte[PAGESIZE]; // ensure page size\n    auto info1 = GC.query(arr.ptr);\n    assert(info1.base !is arr.ptr); // offset is required for page size or larger\n\n    auto arr2 = arr[0..1];\n    assert(arr2.capacity == 0); // cannot append\n    arr2 ~= 0; // add a byte\n    assert(arr2.ptr !is arr.ptr); // reallocated\n    auto info2 = GC.query(arr2.ptr);\n    assert(info2.base is arr2.ptr); // no offset, the capacity is small.\n\n    // do the same via setting length\n    arr2 = arr[0..1];\n    assert(arr2.capacity == 0);\n    arr2.length += 1;\n    assert(arr2.ptr !is arr.ptr); // reallocated\n    info2 = GC.query(arr2.ptr);\n    assert(info2.base is arr2.ptr); // no offset, the capacity is small.\n\n    // do the same for char[] since we need a type with an initializer to test certain runtime functions\n    auto carr = new char[PAGESIZE];\n    info1 = GC.query(carr.ptr);\n    assert(info1.base !is carr.ptr); // offset is required for page size or larger\n\n    auto carr2 = carr[0..1];\n    assert(carr2.capacity == 0); // cannot append\n    carr2 ~= 0; // add a byte\n    assert(carr2.ptr !is carr.ptr); // reallocated\n    info2 = GC.query(carr2.ptr);\n    assert(info2.base is carr2.ptr); // no offset, the capacity is small.\n\n    // do the same via setting length\n    carr2 = carr[0..1];\n    assert(carr2.capacity == 0);\n    carr2.length += 1;\n    assert(carr2.ptr !is carr.ptr); // reallocated\n    info2 = GC.query(carr2.ptr);\n    assert(info2.base is carr2.ptr); // no offset, the capacity is small.\n}\n\nunittest\n{\n    // bugzilla 13878\n    auto arr = new ubyte[1];\n    auto info = GC.query(arr.ptr);\n    assert(info.attr & BlkAttr.NO_SCAN); // should be NO_SCAN\n    arr ~= 0; // ensure array is inserted into cache\n    debug(SENTINEL) {} else\n        assert(arr.ptr is info.base);\n    GC.clrAttr(arr.ptr, BlkAttr.NO_SCAN); // remove the attribute\n    auto arr2 = arr[0..1];\n    assert(arr2.capacity == 0); // cannot append\n    arr2 ~= 0;\n    assert(arr2.ptr !is arr.ptr);\n    info = GC.query(arr2.ptr);\n    assert(!(info.attr & BlkAttr.NO_SCAN)); // ensure attribute sticks\n\n    // do the same via setting length\n    arr = new ubyte[1];\n    arr ~= 0; // ensure array is inserted into cache\n    GC.clrAttr(arr.ptr, BlkAttr.NO_SCAN); // remove the attribute\n    arr2 = arr[0..1];\n    assert(arr2.capacity == 0);\n    arr2.length += 1;\n    assert(arr2.ptr !is arr.ptr); // reallocated\n    info = GC.query(arr2.ptr);\n    assert(!(info.attr & BlkAttr.NO_SCAN)); // ensure attribute sticks\n\n    // do the same for char[] since we need a type with an initializer to test certain runtime functions\n    auto carr = new char[1];\n    info = GC.query(carr.ptr);\n    assert(info.attr & BlkAttr.NO_SCAN); // should be NO_SCAN\n    carr ~= 0; // ensure array is inserted into cache\n    debug(SENTINEL) {} else\n        assert(carr.ptr is info.base);\n    GC.clrAttr(carr.ptr, BlkAttr.NO_SCAN); // remove the attribute\n    auto carr2 = carr[0..1];\n    assert(carr2.capacity == 0); // cannot append\n    carr2 ~= 0;\n    assert(carr2.ptr !is carr.ptr);\n    info = GC.query(carr2.ptr);\n    assert(!(info.attr & BlkAttr.NO_SCAN)); // ensure attribute sticks\n\n    // do the same via setting length\n    carr = new char[1];\n    carr ~= 0; // ensure array is inserted into cache\n    GC.clrAttr(carr.ptr, BlkAttr.NO_SCAN); // remove the attribute\n    carr2 = carr[0..1];\n    assert(carr2.capacity == 0);\n    carr2.length += 1;\n    assert(carr2.ptr !is carr.ptr); // reallocated\n    info = GC.query(carr2.ptr);\n    assert(!(info.attr & BlkAttr.NO_SCAN)); // ensure attribute sticks\n}\n\n// test struct finalizers\ndebug(SENTINEL) {} else\nunittest\n{\n    __gshared int dtorCount;\n    static struct S1\n    {\n        int x;\n\n        ~this()\n        {\n            dtorCount++;\n        }\n    }\n\n    dtorCount = 0;\n    S1* s1 = new S1;\n    delete s1;\n    assert(dtorCount == 1);\n\n    dtorCount = 0;\n    S1[] arr1 = new S1[7];\n    delete arr1;\n    assert(dtorCount == 7);\n\n    if (callStructDtorsDuringGC)\n    {\n        dtorCount = 0;\n        S1* s2 = new S1;\n        GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);\n        assert(dtorCount == 1);\n        GC.free(s2);\n\n        dtorCount = 0;\n        const(S1)* s3 = new const(S1);\n        GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);\n        assert(dtorCount == 1);\n        GC.free(cast(void*)s3);\n\n        dtorCount = 0;\n        shared(S1)* s4 = new shared(S1);\n        GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);\n        assert(dtorCount == 1);\n        GC.free(cast(void*)s4);\n\n        dtorCount = 0;\n        const(S1)[] carr1 = new const(S1)[5];\n        BlkInfo blkinf1 = GC.query(carr1.ptr);\n        GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);\n        assert(dtorCount == 5);\n        GC.free(blkinf1.base);\n    }\n\n    dtorCount = 0;\n    S1[] arr2 = new S1[10];\n    arr2.length = 6;\n    arr2.assumeSafeAppend;\n    assert(dtorCount == 4); // destructors run explicitely?\n\n    if (callStructDtorsDuringGC)\n    {\n        dtorCount = 0;\n        BlkInfo blkinf = GC.query(arr2.ptr);\n        GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);\n        assert(dtorCount == 6);\n        GC.free(blkinf.base);\n    }\n\n    // associative arrays\n    import rt.aaA : entryDtor;\n    // throw away all existing AA entries with dtor\n    GC.runFinalizers((cast(char*)(&entryDtor))[0..1]);\n\n    S1[int] aa1;\n    aa1[0] = S1(0);\n    aa1[1] = S1(1);\n    if (callStructDtorsDuringGC)\n    {\n        dtorCount = 0;\n        aa1 = null;\n        GC.runFinalizers((cast(char*)(&entryDtor))[0..1]);\n        assert(dtorCount == 2);\n    }\n\n    int[S1] aa2;\n    aa2[S1(0)] = 0;\n    aa2[S1(1)] = 1;\n    aa2[S1(2)] = 2;\n    if (callStructDtorsDuringGC)\n    {\n        dtorCount = 0;\n        aa2 = null;\n        GC.runFinalizers((cast(char*)(&entryDtor))[0..1]);\n        assert(dtorCount == 3);\n    }\n\n    S1[2][int] aa3;\n    aa3[0] = [S1(0),S1(2)];\n    aa3[1] = [S1(1),S1(3)];\n    if (callStructDtorsDuringGC)\n    {\n        dtorCount = 0;\n        aa3 = null;\n        GC.runFinalizers((cast(char*)(&entryDtor))[0..1]);\n        assert(dtorCount == 4);\n    }\n}\n\n// test class finalizers exception handling\nunittest\n{\n    bool test(E)()\n    {\n        import core.exception;\n        static class C1\n        {\n            E exc;\n            this(E exc) { this.exc = exc; }\n            ~this() { throw exc; }\n        }\n\n        bool caught = false;\n        C1 c = new C1(new E(\"test onFinalizeError\"));\n        try\n        {\n            GC.runFinalizers((cast(uint*)&C1.__dtor)[0..1]);\n        }\n        catch (FinalizeError err)\n        {\n            caught = true;\n        }\n        catch (E)\n        {\n        }\n        GC.free(cast(void*)c);\n        return caught;\n    }\n\n    assert( test!Exception);\n    import core.exception : InvalidMemoryOperationError;\n    assert(!test!InvalidMemoryOperationError);\n}\n\n// test struct finalizers exception handling\ndebug(SENTINEL) {} else\nunittest\n{\n    if (!callStructDtorsDuringGC)\n        return;\n\n    bool test(E)()\n    {\n        import core.exception;\n        static struct S1\n        {\n            E exc;\n            ~this() { throw exc; }\n        }\n\n        bool caught = false;\n        S1* s = new S1(new E(\"test onFinalizeError\"));\n        try\n        {\n            GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);\n        }\n        catch (FinalizeError err)\n        {\n            caught = true;\n        }\n        catch (E)\n        {\n        }\n        GC.free(s);\n        return caught;\n    }\n\n    assert( test!Exception);\n    import core.exception : InvalidMemoryOperationError;\n    assert(!test!InvalidMemoryOperationError);\n}\n\n// test bug 14126\nunittest\n{\n    static struct S\n    {\n        S* thisptr;\n        ~this() { assert(&this == thisptr); thisptr = null;}\n    }\n\n    S[] test14126 = new S[2048]; // make sure we allocate at least a PAGE\n    foreach (ref s; test14126)\n    {\n        s.thisptr = &s;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/memory.d",
    "content": "/**\n * This module tells the garbage collector about the static data and bss segments,\n * so the GC can scan them for roots. It does not deal with thread local static data.\n *\n * Copyright: Copyright Digital Mars 2000 - 2012.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Walter Bright, Sean Kelly\n * Source: $(DRUNTIMESRC rt/_memory.d)\n */\n\nmodule rt.memory;\n\n\nimport core.memory;\nimport rt.sections;\n\nvoid initStaticDataGC()\n{\n    foreach (ref sg; SectionGroup)\n    {\n        foreach (rng; sg.gcRanges)\n            GC.addRange(rng.ptr, rng.length);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/minfo.d",
    "content": "/**\n * Written in the D programming language.\n * Module initialization routines.\n *\n * Copyright: Copyright Digital Mars 2000 - 2013.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Walter Bright, Sean Kelly\n * Source: $(DRUNTIMESRC rt/_minfo.d)\n */\n\nmodule rt.minfo;\n\nimport core.stdc.stdlib;  // alloca\nimport core.stdc.string;  // memcpy\nimport rt.sections;\n\nenum\n{\n    MIctorstart  = 0x1,   // we've started constructing it\n    MIctordone   = 0x2,   // finished construction\n    MIstandalone = 0x4,   // module ctor does not depend on other module\n                        // ctors being done first\n    MItlsctor    = 8,\n    MItlsdtor    = 0x10,\n    MIctor       = 0x20,\n    MIdtor       = 0x40,\n    MIxgetMembers = 0x80,\n    MIictor      = 0x100,\n    MIunitTest   = 0x200,\n    MIimportedModules = 0x400,\n    MIlocalClasses = 0x800,\n    MIname       = 0x1000,\n}\n\n/*****\n * A ModuleGroup is an unordered collection of modules.\n * There is exactly one for:\n *  1. all statically linked in D modules, either directely or as shared libraries\n *  2. each call to rt_loadLibrary()\n */\n\nstruct ModuleGroup\n{\n    this(immutable(ModuleInfo*)[] modules) nothrow @nogc\n    {\n        _modules = modules;\n    }\n\n    @property immutable(ModuleInfo*)[] modules() const nothrow @nogc\n    {\n        return _modules;\n    }\n\n    // this function initializes the bookeeping necessary to create the\n    // cycle path, and then creates it. It is a precondition that src and\n    // target modules are involved in a cycle.\n    //\n    // The return value is malloc'd using C, so it must be freed after use.\n    private size_t[] genCyclePath(size_t srcidx, size_t targetidx, int[][] edges)\n    {\n        import core.bitop : bt, btc, bts;\n\n        // set up all the arrays.\n        size_t[] cyclePath = (cast(size_t*)malloc(size_t.sizeof * _modules.length * 2))[0 .. _modules.length * 2];\n        size_t totalMods;\n        int[] distance = (cast(int*)malloc(int.sizeof * _modules.length))[0 .. _modules.length];\n        scope(exit)\n            .free(distance.ptr);\n\n        // determine the shortest path between two modules. Uses dijkstra\n        // without a priority queue. (we can be a bit slow here, in order to\n        // get a better printout).\n        void shortest(size_t start, size_t target)\n        {\n            // initial setup\n            distance[] = int.max;\n            int curdist = 0;\n            distance[start] = 0;\n            while (true)\n            {\n                bool done = true;\n                foreach (i, x; distance)\n                {\n                    if (x == curdist)\n                    {\n                        if (i == target)\n                        {\n                            done = true;\n                            break;\n                        }\n                        foreach (n; edges[i])\n                        {\n                            if (distance[n] == int.max)\n                            {\n                                distance[n] = curdist + 1;\n                                done = false;\n                            }\n                        }\n                    }\n                }\n                if (done)\n                    break;\n                ++curdist;\n            }\n            // it should be impossible to not get to target, this is just a\n            // sanity check. Not an assert, because druntime is compiled in\n            // release mode.\n            if (distance[target] != curdist)\n            {\n                throw new Error(\"internal error printing module cycle\");\n            }\n\n            // determine the path. This is tricky, because we have to\n            // follow the edges in reverse to get back to the original. We\n            // don't have a reverse mapping, so it takes a bit of looping.\n            totalMods += curdist;\n            auto subpath = cyclePath[totalMods - curdist .. totalMods];\n            while (true)\n            {\n                --curdist;\n                subpath[curdist] = target;\n                if (curdist == 0)\n                    break;\n            distloop:\n                // search for next (previous) module in cycle.\n                foreach (int m, d; distance)\n                {\n                    if (d == curdist)\n                    {\n                        // determine if m can reach target\n                        foreach (e; edges[m])\n                        {\n                            if (e == target)\n                            {\n                                // recurse\n                                target = m;\n                                break distloop;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // first get to the target\n        shortest(srcidx, targetidx);\n        // now get back.\n        shortest(targetidx, srcidx);\n\n        return cyclePath[0 .. totalMods];\n    }\n\n    /******************************\n     * Allocate and fill in _ctors[] and _tlsctors[].\n     * Modules are inserted into the arrays in the order in which the constructors\n     * need to be run.\n     *\n     * Params:\n     *  cycleHandling - string indicating option for cycle handling\n     * Throws:\n     *  Exception if it fails.\n     */\n    void sortCtors(string cycleHandling)\n    {\n        import core.bitop : bts, btr, bt, BitRange;\n        import rt.util.container.hashtab;\n\n        enum OnCycle\n        {\n            deprecate,\n            abort,\n            print,\n            ignore\n        }\n\n        auto onCycle = OnCycle.abort;\n\n        switch (cycleHandling) with(OnCycle)\n        {\n        case \"deprecate\":\n            onCycle = deprecate;\n            break;\n        case \"abort\":\n            onCycle = abort;\n            break;\n        case \"print\":\n            onCycle = print;\n            break;\n        case \"ignore\":\n            onCycle = ignore;\n            break;\n        case \"\":\n            // no option passed\n            break;\n        default:\n            // invalid cycle handling option.\n            throw new Error(\"DRT invalid cycle handling option: \" ~ cycleHandling);\n        }\n\n        debug (printModuleDependencies)\n        {\n            import core.stdc.stdio : printf;\n\n            foreach (_m; _modules)\n            {\n                printf(\"%s%s%s:\", _m.name.ptr, (_m.flags & MIstandalone)\n                        ? \"+\".ptr : \"\".ptr, (_m.flags & (MIctor | MIdtor)) ? \"*\".ptr : \"\".ptr);\n                foreach (_i; _m.importedModules)\n                    printf(\" %s\", _i.name.ptr);\n                printf(\"\\n\");\n            }\n        }\n\n        immutable uint len = cast(uint) _modules.length;\n        if (!len)\n            return; // nothing to do.\n\n        // allocate some stack arrays that will be used throughout the process.\n        immutable nwords = (len + 8 * size_t.sizeof - 1) / (8 * size_t.sizeof);\n        immutable flagbytes = nwords * size_t.sizeof;\n        auto ctorstart = cast(size_t*) malloc(flagbytes); // ctor/dtor seen\n        auto ctordone = cast(size_t*) malloc(flagbytes); // ctor/dtor processed\n        auto relevant = cast(size_t*) malloc(flagbytes); // has ctors/dtors\n        scope (exit)\n        {\n            .free(ctorstart);\n            .free(ctordone);\n            .free(relevant);\n        }\n\n        void clearFlags(size_t* flags)\n        {\n            memset(flags, 0, flagbytes);\n        }\n\n\n        // build the edges between each module. We may need this for printing,\n        // and also allows avoiding keeping a hash around for module lookups.\n        int[][] edges = (cast(int[]*)malloc((int[]).sizeof * _modules.length))[0 .. _modules.length];\n        {\n            HashTab!(immutable(ModuleInfo)*, int) modIndexes;\n            foreach (i, m; _modules)\n                modIndexes[m] = cast(int) i;\n\n            auto reachable = cast(size_t*) malloc(flagbytes);\n            scope(exit)\n                .free(reachable);\n\n            foreach (i, m; _modules)\n            {\n                // use bit array to prevent duplicates\n                // https://issues.dlang.org/show_bug.cgi?id=16208\n                clearFlags(reachable);\n                // preallocate enough space to store all the indexes\n                int *edge = cast(int*)malloc(int.sizeof * _modules.length);\n                size_t nEdges = 0;\n                foreach (imp; m.importedModules)\n                {\n                    if (imp is m) // self-import\n                        continue;\n                    if (auto impidx = imp in modIndexes)\n                    {\n                        if (!bts(reachable, *impidx))\n                            edge[nEdges++] = *impidx;\n                    }\n                }\n                // trim space to what is needed.\n                edges[i] = (cast(int*)realloc(edge, int.sizeof * nEdges))[0 .. nEdges];\n            }\n        }\n\n        // free all the edges after we are done\n        scope(exit)\n        {\n            foreach (e; edges)\n                if (e.ptr)\n                    .free(e.ptr);\n            .free(edges.ptr);\n        }\n\n        void buildCycleMessage(size_t sourceIdx, size_t cycleIdx, scope void delegate(string) sink)\n        {\n            version (Windows)\n                enum EOL = \"\\r\\n\";\n            else\n                enum EOL = \"\\n\";\n\n            sink(\"Cyclic dependency between module \");\n            sink(_modules[sourceIdx].name);\n            sink(\" and \");\n            sink(_modules[cycleIdx].name);\n            sink(EOL);\n            auto cyclePath = genCyclePath(sourceIdx, cycleIdx, edges);\n            scope(exit) .free(cyclePath.ptr);\n\n            sink(_modules[sourceIdx].name);\n            sink(\"* ->\" ~ EOL);\n            foreach (x; cyclePath[0 .. $ - 1])\n            {\n                sink(_modules[x].name);\n                sink(bt(relevant, x) ? \"* ->\" ~ EOL : \" ->\" ~ EOL);\n            }\n            sink(_modules[sourceIdx].name);\n            sink(\"*\" ~ EOL);\n        }\n\n        // find all the non-trivial dependencies (that is, dependencies that have a\n        // ctor or dtor) of a given module.  Doing this, we can 'skip over' the\n        // trivial modules to get at the non-trivial ones.\n        //\n        // If a cycle is detected, returns the index of the module that completes the cycle.\n        // Returns: true for success, false for a deprecated cycle error\n        bool findDeps(size_t idx, size_t* reachable)\n        {\n            static struct stackFrame\n            {\n                size_t curMod;\n                size_t curDep;\n            }\n\n            // initialize \"stack\"\n            auto stack = cast(stackFrame*) malloc(stackFrame.sizeof * len);\n            scope (exit)\n                .free(stack);\n            auto stacktop = stack + len;\n            auto sp = stack;\n            sp.curMod = cast(int) idx;\n            sp.curDep = 0;\n\n            // initialize reachable by flagging source module\n            clearFlags(reachable);\n            bts(reachable, idx);\n\n            for (;;)\n            {\n                auto m = _modules[sp.curMod];\n                if (sp.curDep >= edges[sp.curMod].length)\n                {\n                    // return\n                    if (sp == stack) // finished the algorithm\n                        break;\n                    --sp;\n                }\n                else\n                {\n                    auto midx = edges[sp.curMod][sp.curDep];\n                    if (!bts(reachable, midx))\n                    {\n                        if (bt(relevant, midx))\n                        {\n                            // need to process this node, don't recurse.\n                            if (bt(ctorstart, midx))\n                            {\n                                // was already started, this is a cycle.\n                                final switch (onCycle) with(OnCycle)\n                                {\n                                case deprecate:\n                                    // check with old algorithm\n                                    if (sortCtorsOld(edges))\n                                    {\n                                        // unwind to print deprecation message.\n                                        return false;   // deprecated cycle error\n                                    }\n                                    goto case abort; // fall through\n                                case abort:\n\n                                    string errmsg = \"\";\n                                    buildCycleMessage(idx, midx, (string x) {errmsg ~= x;});\n                                    throw new Error(errmsg, __FILE__, __LINE__);\n                                case ignore:\n                                    break;\n                                case print:\n                                    // print the message\n                                    buildCycleMessage(idx, midx, (string x) {\n                                                      import core.stdc.stdio : fprintf, stderr;\n                                                      fprintf(stderr, \"%.*s\", cast(int) x.length, x.ptr);\n                                                      });\n                                    // continue on as if this is correct.\n                                    break;\n                                }\n                            }\n                        }\n                        else if (!bt(ctordone, midx))\n                        {\n                            // non-relevant, and hasn't been exhaustively processed, recurse.\n                            if (++sp >= stacktop)\n                            {\n                                // stack overflow, this shouldn't happen.\n                                import core.internal.abort : abort;\n\n                                abort(\"stack overflow on dependency search\");\n                            }\n                            sp.curMod = midx;\n                            sp.curDep = 0;\n                            continue;\n                        }\n                    }\n                }\n\n                // next dependency\n                ++sp.curDep;\n            }\n            return true; // success\n        }\n\n        // The list of constructors that will be returned by the sorting.\n        immutable(ModuleInfo)** ctors;\n        // current element being inserted into ctors list.\n        size_t ctoridx = 0;\n\n        // This function will determine the order of construction/destruction and\n        // check for cycles. If a cycle is found, the cycle path is transformed\n        // into a string and thrown as an error.\n        //\n        // Each call into this function is given a module that has static\n        // ctor/dtors that must be dealt with. It recurses only when it finds\n        // dependencies that also have static ctor/dtors.\n        // Returns: true for success, false for a deprecated cycle error\n        bool processMod(size_t curidx)\n        {\n            immutable ModuleInfo* current = _modules[curidx];\n\n            // First, determine what modules are reachable.\n            auto reachable = cast(size_t*) malloc(flagbytes);\n            scope (exit)\n                .free(reachable);\n            if (!findDeps(curidx, reachable))\n                return false;   // deprecated cycle error\n\n            // process the dependencies. First, we process all relevant ones\n            bts(ctorstart, curidx);\n            auto brange = BitRange(reachable, len);\n            foreach (i; brange)\n            {\n                // note, don't check for cycles here, because the config could have been set to ignore cycles.\n                // however, don't recurse if there is one, so still check for started ctor.\n                if (i != curidx && bt(relevant, i) && !bt(ctordone, i) && !bt(ctorstart, i))\n                {\n                    if (!processMod(i))\n                        return false; // deprecated cycle error\n                }\n            }\n\n            // now mark this node, and all nodes reachable from this module as done.\n            bts(ctordone, curidx);\n            btr(ctorstart, curidx);\n            foreach (i; brange)\n            {\n                // Since relevant dependencies are already marked as done\n                // from recursion above (or are going to be handled up the call\n                // stack), no reason to check for relevance, that is a wasted\n                // op.\n                bts(ctordone, i);\n            }\n\n            // add this module to the construction order list\n            ctors[ctoridx++] = current;\n            return true;\n        }\n\n        // returns `false` if deprecated cycle error otherwise set `result`.\n        bool doSort(size_t relevantFlags, ref immutable(ModuleInfo)*[] result)\n        {\n            clearFlags(relevant);\n            clearFlags(ctorstart);\n            clearFlags(ctordone);\n\n            // pre-allocate enough space to hold all modules.\n            ctors = (cast(immutable(ModuleInfo)**).malloc(len * (void*).sizeof));\n            ctoridx = 0;\n            foreach (int idx, m; _modules)\n            {\n                if (m.flags & relevantFlags)\n                {\n                    if (m.flags & MIstandalone)\n                    {\n                        // can run at any time. Just run it first.\n                        ctors[ctoridx++] = m;\n                    }\n                    else\n                    {\n                        bts(relevant, idx);\n                    }\n                }\n            }\n\n            // now run the algorithm in the relevant ones\n            foreach (idx; BitRange(relevant, len))\n            {\n                if (!bt(ctordone, idx))\n                {\n                    if (!processMod(idx))\n                        return false;\n                }\n            }\n\n            if (ctoridx == 0)\n            {\n                // no ctors in the list.\n                .free(ctors);\n            }\n            else\n            {\n                ctors = cast(immutable(ModuleInfo)**).realloc(ctors, ctoridx * (void*).sizeof);\n                if (ctors is null)\n                    assert(0);\n                result = ctors[0 .. ctoridx];\n            }\n            return true;\n        }\n\n        // finally, do the sorting for both shared and tls ctors. If either returns false,\n        // print the deprecation warning.\n        if (!doSort(MIctor | MIdtor, _ctors) ||\n            !doSort(MItlsctor | MItlsdtor, _tlsctors))\n        {\n            // print a warning\n            import core.stdc.stdio : fprintf, stderr;\n            fprintf(stderr, \"Deprecation 16211 warning:\\n\"\n                ~ \"A cycle has been detected in your program that was undetected prior to DMD\\n\"\n                ~ \"2.072. This program will continue, but will not operate when using DMD 2.074\\n\"\n                ~ \"to compile. Use runtime option --DRT-oncycle=print to see the cycle details.\\n\");\n\n        }\n    }\n\n    /// ditto\n    void sortCtors()\n    {\n        import rt.config : rt_configOption;\n        sortCtors(rt_configOption(\"oncycle\"));\n    }\n\n    /******************************\n     * This is the old ctor sorting algorithm that does not find all cycles.\n     *\n     * It is here to allow the deprecated behavior from the original algorithm\n     * until people have fixed their code.\n     *\n     * If no cycles are found, the _ctors and _tlsctors are replaced with the\n     * ones generated by this algorithm to preserve the old incorrect ordering\n     * behavior.\n     *\n     * Params:\n     *   edges = The module edges as found in the `importedModules` member of\n     *          each ModuleInfo. Generated in sortCtors.\n     * Returns:\n     *   true if no cycle is found, false if one was.\n     */\n    bool sortCtorsOld(int[][] edges)\n    {\n        immutable len = edges.length;\n        assert(len == _modules.length);\n\n        static struct StackRec\n        {\n            @property int mod()\n            {\n                return _mods[_idx];\n            }\n\n            int[] _mods;\n            size_t         _idx;\n        }\n\n        auto stack = (cast(StackRec*).calloc(len, StackRec.sizeof))[0 .. len];\n        // TODO: reuse GCBits by moving it to rt.util.container or core.internal\n        immutable nwords = (len + 8 * size_t.sizeof - 1) / (8 * size_t.sizeof);\n        auto ctorstart = cast(size_t*).malloc(nwords * size_t.sizeof);\n        auto ctordone = cast(size_t*).malloc(nwords * size_t.sizeof);\n        int[] initialEdges = (cast(int *)malloc(int.sizeof * len))[0 .. len];\n        if (!stack.ptr || ctorstart is null || ctordone is null || !initialEdges.ptr)\n            assert(0);\n        scope (exit)\n        {\n            .free(stack.ptr);\n            .free(ctorstart);\n            .free(ctordone);\n            .free(initialEdges.ptr);\n        }\n\n        // initialize the initial edges\n        foreach (int i, ref v; initialEdges)\n            v = i;\n\n        bool sort(ref immutable(ModuleInfo)*[] ctors, uint mask)\n        {\n            import core.bitop;\n\n            ctors = (cast(immutable(ModuleInfo)**).malloc(len * size_t.sizeof))[0 .. len];\n            if (!ctors.ptr)\n                assert(0);\n\n            // clean flags\n            memset(ctorstart, 0, nwords * size_t.sizeof);\n            memset(ctordone, 0, nwords * size_t.sizeof);\n            size_t stackidx = 0;\n            size_t cidx;\n\n            int[] mods = initialEdges;\n\n            size_t idx;\n            while (true)\n            {\n                while (idx < mods.length)\n                {\n                    auto m = mods[idx];\n\n                    if (bt(ctordone, m))\n                    {\n                        // this module has already been processed, skip\n                        ++idx;\n                        continue;\n                    }\n                    else if (bt(ctorstart, m))\n                    {\n                        /* Trace back to the begin of the cycle.\n                         */\n                        bool ctorInCycle;\n                        size_t start = stackidx;\n                        while (start--)\n                        {\n                            auto sm = stack[start].mod;\n                            if (sm == m)\n                                break;\n                            assert(sm >= 0);\n                            if (bt(ctorstart, sm))\n                                ctorInCycle = true;\n                        }\n                        assert(stack[start].mod == m);\n                        if (ctorInCycle)\n                        {\n                            return false;\n                        }\n                        else\n                        {\n                            /* This is also a cycle, but the import chain does not constrain\n                             * the order of initialization, either because the imported\n                             * modules have no ctors or the ctors are standalone.\n                             */\n                            ++idx;\n                        }\n                    }\n                    else\n                    {\n                        auto curmod = _modules[m];\n                        if (curmod.flags & mask)\n                        {\n                            if (curmod.flags & MIstandalone || !edges[m].length)\n                            {   // trivial ctor => sort in\n                                ctors[cidx++] = curmod;\n                                bts(ctordone, m);\n                            }\n                            else\n                            {   // non-trivial ctor => defer\n                                bts(ctorstart, m);\n                            }\n                        }\n                        else    // no ctor => mark as visited\n                        {\n                            bts(ctordone, m);\n                        }\n\n                        if (edges[m].length)\n                        {\n                            /* Internal runtime error, recursion exceeds number of modules.\n                             */\n                            (stackidx < len) || assert(0);\n\n                            // recurse\n                            stack[stackidx++] = StackRec(mods, idx);\n                            idx  = 0;\n                            mods = edges[m];\n                        }\n                    }\n                }\n\n                if (stackidx)\n                {   // pop old value from stack\n                    --stackidx;\n                    mods    = stack[stackidx]._mods;\n                    idx     = stack[stackidx]._idx;\n                    auto m  = mods[idx++];\n                    if (bt(ctorstart, m) && !bts(ctordone, m))\n                        ctors[cidx++] = _modules[m];\n                }\n                else // done\n                    break;\n            }\n            // store final number and shrink array\n            ctors = (cast(immutable(ModuleInfo)**).realloc(ctors.ptr, cidx * size_t.sizeof))[0 .. cidx];\n            return true;\n        }\n\n        /* Do two passes: ctor/dtor, tlsctor/tlsdtor\n         */\n        immutable(ModuleInfo)*[] _ctors2;\n        immutable(ModuleInfo)*[] _tlsctors2;\n        auto result = sort(_ctors2, MIctor | MIdtor) && sort(_tlsctors2, MItlsctor | MItlsdtor);\n        if (result) // no cycle\n        {\n            // fall back to original ordering as part of the deprecation.\n            if (_ctors.ptr)\n                .free(_ctors.ptr);\n            _ctors = _ctors2;\n            if (_tlsctors.ptr)\n                .free(_tlsctors.ptr);\n            _tlsctors = _tlsctors2;\n        }\n        else\n        {\n            // free any allocated memory that will be forgotten\n            if (_ctors2.ptr)\n                .free(_ctors2.ptr);\n            if (_tlsctors2.ptr)\n                .free(_tlsctors2.ptr);\n        }\n        return result;\n    }\n\n    void runCtors()\n    {\n        // run independent ctors\n        runModuleFuncs!(m => m.ictor)(_modules);\n        // sorted module ctors\n        runModuleFuncs!(m => m.ctor)(_ctors);\n    }\n\n    void runTlsCtors()\n    {\n        runModuleFuncs!(m => m.tlsctor)(_tlsctors);\n    }\n\n    void runTlsDtors()\n    {\n        runModuleFuncsRev!(m => m.tlsdtor)(_tlsctors);\n    }\n\n    void runDtors()\n    {\n        runModuleFuncsRev!(m => m.dtor)(_ctors);\n    }\n\n    void free()\n    {\n        if (_ctors.ptr)\n            .free(_ctors.ptr);\n        _ctors = null;\n        if (_tlsctors.ptr)\n            .free(_tlsctors.ptr);\n        _tlsctors = null;\n        // _modules = null; // let the owner free it\n    }\n\nprivate:\n    immutable(ModuleInfo*)[]  _modules;\n    immutable(ModuleInfo)*[]    _ctors;\n    immutable(ModuleInfo)*[] _tlsctors;\n}\n\n\n/********************************************\n * Iterate over all module infos.\n */\n\nint moduleinfos_apply(scope int delegate(immutable(ModuleInfo*)) dg)\n{\n    foreach (ref sg; SectionGroup)\n    {\n        foreach (m; sg.modules)\n        {\n            // TODO: Should null ModuleInfo be allowed?\n            if (m !is null)\n            {\n                if (auto res = dg(m))\n                    return res;\n            }\n        }\n    }\n    return 0;\n}\n\n/********************************************\n * Module constructor and destructor routines.\n */\n\nextern (C)\n{\nvoid rt_moduleCtor()\n{\n    foreach (ref sg; SectionGroup)\n    {\n        sg.moduleGroup.sortCtors();\n        sg.moduleGroup.runCtors();\n    }\n}\n\nvoid rt_moduleTlsCtor()\n{\n    foreach (ref sg; SectionGroup)\n    {\n        sg.moduleGroup.runTlsCtors();\n    }\n}\n\nvoid rt_moduleTlsDtor()\n{\n    foreach_reverse (ref sg; SectionGroup)\n    {\n        sg.moduleGroup.runTlsDtors();\n    }\n}\n\nvoid rt_moduleDtor()\n{\n    foreach_reverse (ref sg; SectionGroup)\n    {\n        sg.moduleGroup.runDtors();\n        sg.moduleGroup.free();\n    }\n}\n\nversion (Win32)\n{\n    // Alternate names for backwards compatibility with older DLL code\n    void _moduleCtor()\n    {\n        rt_moduleCtor();\n    }\n\n    void _moduleDtor()\n    {\n        rt_moduleDtor();\n    }\n\n    void _moduleTlsCtor()\n    {\n        rt_moduleTlsCtor();\n    }\n\n    void _moduleTlsDtor()\n    {\n        rt_moduleTlsDtor();\n    }\n}\n}\n\n/********************************************\n */\n\nvoid runModuleFuncs(alias getfp)(const(immutable(ModuleInfo)*)[] modules)\n{\n    foreach (m; modules)\n    {\n        if (auto fp = getfp(m))\n            (*fp)();\n    }\n}\n\nvoid runModuleFuncsRev(alias getfp)(const(immutable(ModuleInfo)*)[] modules)\n{\n    foreach_reverse (m; modules)\n    {\n        if (auto fp = getfp(m))\n            (*fp)();\n    }\n}\n\nunittest\n{\n    static void assertThrown(T : Throwable, E)(lazy E expr, string msg)\n    {\n        try\n            expr;\n        catch (T)\n            return;\n        assert(0, msg);\n    }\n\n    static void stub()\n    {\n    }\n\n    static struct UTModuleInfo\n    {\n        this(uint flags)\n        {\n            mi._flags = flags;\n        }\n\n        void setImports(immutable(ModuleInfo)*[] imports...)\n        {\n            import core.bitop;\n            assert(flags & MIimportedModules);\n\n            immutable nfuncs = popcnt(flags & (MItlsctor|MItlsdtor|MIctor|MIdtor|MIictor));\n            immutable size = nfuncs * (void function()).sizeof +\n                size_t.sizeof + imports.length * (ModuleInfo*).sizeof;\n            assert(size <= pad.sizeof);\n\n            pad[nfuncs] = imports.length;\n            .memcpy(&pad[nfuncs+1], imports.ptr, imports.length * imports[0].sizeof);\n        }\n\n        immutable ModuleInfo mi;\n        size_t[8] pad;\n        alias mi this;\n    }\n\n    static UTModuleInfo mockMI(uint flags)\n    {\n        auto mi = UTModuleInfo(flags | MIimportedModules);\n        auto p = cast(void function()*)&mi.pad;\n        if (flags & MItlsctor) *p++ = &stub;\n        if (flags & MItlsdtor) *p++ = &stub;\n        if (flags & MIctor) *p++ = &stub;\n        if (flags & MIdtor) *p++ = &stub;\n        if (flags & MIictor) *p++ = &stub;\n        *cast(size_t*)p++ = 0; // number of imported modules\n        assert(cast(void*)p <= &mi + 1);\n        return mi;\n    }\n\n    static void checkExp2(string testname, bool shouldThrow, string oncycle,\n        immutable(ModuleInfo*)[] modules,\n        immutable(ModuleInfo*)[] dtors=null,\n        immutable(ModuleInfo*)[] tlsdtors=null)\n    {\n        auto mgroup = ModuleGroup(modules);\n        mgroup.sortCtors(oncycle);\n\n        // if we are expecting sort to throw, don't throw because of unexpected\n        // success!\n        if (!shouldThrow)\n        {\n            foreach (m; mgroup._modules)\n                assert(!(m.flags & (MIctorstart | MIctordone)), testname);\n            assert(mgroup._ctors    == dtors, testname);\n            assert(mgroup._tlsctors == tlsdtors, testname);\n        }\n    }\n\n    static void checkExp(string testname, bool shouldThrow,\n        immutable(ModuleInfo*)[] modules,\n        immutable(ModuleInfo*)[] dtors=null,\n        immutable(ModuleInfo*)[] tlsdtors=null)\n    {\n        checkExp2(testname, shouldThrow, \"abort\", modules, dtors, tlsdtors);\n    }\n\n\n    {\n        auto m0 = mockMI(0);\n        auto m1 = mockMI(0);\n        auto m2 = mockMI(0);\n        checkExp(\"no ctors\", false, [&m0.mi, &m1.mi, &m2.mi]);\n    }\n\n    {\n        auto m0 = mockMI(MIictor);\n        auto m1 = mockMI(0);\n        auto m2 = mockMI(MIictor);\n        auto mgroup = ModuleGroup([&m0.mi, &m1.mi, &m2.mi]);\n        checkExp(\"independent ctors\", false, [&m0.mi, &m1.mi, &m2.mi]);\n    }\n\n    {\n        auto m0 = mockMI(MIstandalone | MIctor);\n        auto m1 = mockMI(0);\n        auto m2 = mockMI(0);\n        auto mgroup = ModuleGroup([&m0.mi, &m1.mi, &m2.mi]);\n        checkExp(\"standalone ctor\", false, [&m0.mi, &m1.mi, &m2.mi], [&m0.mi]);\n    }\n\n    {\n        auto m0 = mockMI(MIstandalone | MIctor);\n        auto m1 = mockMI(MIstandalone | MIctor);\n        auto m2 = mockMI(0);\n        m1.setImports(&m0.mi);\n        checkExp(\"imported standalone => no dependency\", false,\n                 [&m0.mi, &m1.mi, &m2.mi], [&m0.mi, &m1.mi]);\n    }\n\n    {\n        auto m0 = mockMI(MIstandalone | MIctor);\n        auto m1 = mockMI(MIstandalone | MIctor);\n        auto m2 = mockMI(0);\n        m0.setImports(&m1.mi);\n        checkExp(\"imported standalone => no dependency (2)\", false,\n                [&m0.mi, &m1.mi, &m2.mi], [&m0.mi, &m1.mi]);\n    }\n\n    {\n        auto m0 = mockMI(MIstandalone | MIctor);\n        auto m1 = mockMI(MIstandalone | MIctor);\n        auto m2 = mockMI(0);\n        m0.setImports(&m1.mi);\n        m1.setImports(&m0.mi);\n        checkExp(\"standalone may have cycle\", false,\n                [&m0.mi, &m1.mi, &m2.mi], [&m0.mi, &m1.mi]);\n    }\n\n    {\n        auto m0 = mockMI(MIctor);\n        auto m1 = mockMI(MIctor);\n        auto m2 = mockMI(0);\n        m1.setImports(&m0.mi);\n        checkExp(\"imported ctor => ordered ctors\", false,\n                [&m0.mi, &m1.mi, &m2.mi], [&m0.mi, &m1.mi], []);\n    }\n\n    {\n        auto m0 = mockMI(MIctor);\n        auto m1 = mockMI(MIctor);\n        auto m2 = mockMI(0);\n        m0.setImports(&m1.mi);\n        checkExp(\"imported ctor => ordered ctors (2)\", false,\n                [&m0.mi, &m1.mi, &m2.mi], [&m1.mi, &m0.mi], []);\n    }\n\n    {\n        auto m0 = mockMI(MIctor);\n        auto m1 = mockMI(MIctor);\n        auto m2 = mockMI(0);\n        m0.setImports(&m1.mi);\n        m1.setImports(&m0.mi);\n        assertThrown!Throwable(checkExp(\"\", true, [&m0.mi, &m1.mi, &m2.mi]),\n                \"detects ctors cycles\");\n        assertThrown!Throwable(checkExp2(\"\", true, \"deprecate\",\n                                        [&m0.mi, &m1.mi, &m2.mi]),\n                \"detects ctors cycles (dep)\");\n    }\n\n    {\n        auto m0 = mockMI(MIctor);\n        auto m1 = mockMI(MIctor);\n        auto m2 = mockMI(0);\n        m0.setImports(&m2.mi);\n        m1.setImports(&m2.mi);\n        m2.setImports(&m0.mi, &m1.mi);\n        assertThrown!Throwable(checkExp(\"\", true, [&m0.mi, &m1.mi, &m2.mi]),\n                \"detects cycle with repeats\");\n    }\n\n    {\n        auto m0 = mockMI(MIctor);\n        auto m1 = mockMI(MIctor);\n        auto m2 = mockMI(MItlsctor);\n        m0.setImports(&m1.mi, &m2.mi);\n        checkExp(\"imported ctor/tlsctor => ordered ctors/tlsctors\", false,\n                [&m0.mi, &m1.mi, &m2.mi], [&m1.mi, &m0.mi], [&m2.mi]);\n    }\n\n    {\n        auto m0 = mockMI(MIctor | MItlsctor);\n        auto m1 = mockMI(MIctor);\n        auto m2 = mockMI(MItlsctor);\n        m0.setImports(&m1.mi, &m2.mi);\n        checkExp(\"imported ctor/tlsctor => ordered ctors/tlsctors (2)\", false,\n                [&m0.mi, &m1.mi, &m2.mi], [&m1.mi, &m0.mi], [&m2.mi, &m0.mi]);\n    }\n\n    {\n        auto m0 = mockMI(MIctor);\n        auto m1 = mockMI(MIctor);\n        auto m2 = mockMI(MItlsctor);\n        m0.setImports(&m1.mi, &m2.mi);\n        m2.setImports(&m0.mi);\n        checkExp(\"no cycle between ctors/tlsctors\", false,\n                [&m0.mi, &m1.mi, &m2.mi], [&m1.mi, &m0.mi], [&m2.mi]);\n    }\n\n    {\n        auto m0 = mockMI(MItlsctor);\n        auto m1 = mockMI(MIctor);\n        auto m2 = mockMI(MItlsctor);\n        m0.setImports(&m2.mi);\n        m2.setImports(&m0.mi);\n        assertThrown!Throwable(checkExp(\"\", true, [&m0.mi, &m1.mi, &m2.mi]),\n                \"detects tlsctors cycle\");\n        assertThrown!Throwable(checkExp2(\"\", true, \"deprecate\",\n                                         [&m0.mi, &m1.mi, &m2.mi]),\n                \"detects tlsctors cycle (dep)\");\n    }\n\n    {\n        auto m0 = mockMI(MItlsctor);\n        auto m1 = mockMI(MIctor);\n        auto m2 = mockMI(MItlsctor);\n        m0.setImports(&m1.mi);\n        m1.setImports(&m0.mi, &m2.mi);\n        m2.setImports(&m1.mi);\n        assertThrown!Throwable(checkExp(\"\", true, [&m0.mi, &m1.mi, &m2.mi]),\n                \"detects tlsctors cycle with repeats\");\n    }\n\n    {\n        auto m0 = mockMI(MIctor);\n        auto m1 = mockMI(MIstandalone | MIctor);\n        auto m2 = mockMI(MIstandalone | MIctor);\n        m0.setImports(&m1.mi);\n        m1.setImports(&m2.mi);\n        m2.setImports(&m0.mi);\n        // NOTE: this is implementation dependent, sorted order shouldn't be tested.\n        checkExp(\"closed ctors cycle\", false, [&m0.mi, &m1.mi, &m2.mi],\n                [&m1.mi, &m2.mi, &m0.mi]);\n        //checkExp(\"closed ctors cycle\", false, [&m0.mi, &m1.mi, &m2.mi], [&m0.mi, &m1.mi, &m2.mi]);\n    }\n}\n\nversion (CRuntime_Microsoft)\n{\n    // Dummy so Win32 code can still call it\n    extern(C) void _minit() { }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/monitor_.d",
    "content": "/**\n * Contains the implementation for object monitors.\n *\n * Copyright: Copyright Digital Mars 2000 - 2015.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, Sean Kelly, Martin Nowak\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule rt.monitor_;\n\nimport core.atomic, core.stdc.stdlib, core.stdc.string;\n\n// NOTE: The dtor callback feature is only supported for monitors that are not\n//       supplied by the user.  The assumption is that any object with a user-\n//       supplied monitor may have special storage or lifetime requirements and\n//       that as a result, storing references to local objects within Monitor\n//       may not be safe or desirable.  Thus, devt is only valid if impl is\n//       null.\n\nextern (C) void _d_setSameMutex(shared Object ownee, shared Object owner) nothrow\nin\n{\n    assert(ownee.__monitor is null);\n}\ndo\n{\n    auto m = ensureMonitor(cast(Object) owner);\n    auto i = m.impl;\n    if (i is null)\n    {\n        atomicOp!(\"+=\")(m.refs, cast(size_t) 1);\n        ownee.__monitor = owner.__monitor;\n        return;\n    }\n    // If m.impl is set (ie. if this is a user-created monitor), assume\n    // the monitor is garbage collected and simply copy the reference.\n    ownee.__monitor = owner.__monitor;\n}\n\nextern (C) void _d_monitordelete(Object h, bool det)\n{\n    auto m = getMonitor(h);\n    if (m is null)\n        return;\n\n    if (m.impl)\n    {\n        // let the GC collect the monitor\n        setMonitor(h, null);\n    }\n    else if (!atomicOp!(\"-=\")(m.refs, cast(size_t) 1))\n    {\n        // refcount == 0 means unshared => no synchronization required\n        disposeEvent(cast(Monitor*) m, h);\n        deleteMonitor(cast(Monitor*) m);\n        setMonitor(h, null);\n    }\n}\n\n// does not call dispose events, for internal use only\nextern (C) void _d_monitordelete_nogc(Object h) @nogc\n{\n    auto m = getMonitor(h);\n    if (m is null)\n        return;\n\n    if (m.impl)\n    {\n        // let the GC collect the monitor\n        setMonitor(h, null);\n    }\n    else if (!atomicOp!(\"-=\")(m.refs, cast(size_t) 1))\n    {\n        // refcount == 0 means unshared => no synchronization required\n        deleteMonitor(cast(Monitor*) m);\n        setMonitor(h, null);\n    }\n}\n\nextern (C) void _d_monitorenter(Object h)\nin\n{\n    assert(h !is null, \"Synchronized object must not be null.\");\n}\ndo\n{\n    auto m = cast(Monitor*) ensureMonitor(h);\n    auto i = m.impl;\n    if (i is null)\n        lockMutex(&m.mtx);\n    else\n        i.lock();\n}\n\nextern (C) void _d_monitorexit(Object h)\n{\n    auto m = cast(Monitor*) getMonitor(h);\n    auto i = m.impl;\n    if (i is null)\n        unlockMutex(&m.mtx);\n    else\n        i.unlock();\n}\n\nextern (C) void rt_attachDisposeEvent(Object h, DEvent e)\n{\n    synchronized (h)\n    {\n        auto m = cast(Monitor*) getMonitor(h);\n        assert(m.impl is null);\n\n        foreach (ref v; m.devt)\n        {\n            if (v is null || v == e)\n            {\n                v = e;\n                return;\n            }\n        }\n\n        auto len = m.devt.length + 4; // grow by 4 elements\n        auto pos = m.devt.length; // insert position\n        auto p = realloc(m.devt.ptr, DEvent.sizeof * len);\n        import core.exception : onOutOfMemoryError;\n\n        if (!p)\n            onOutOfMemoryError();\n        m.devt = (cast(DEvent*) p)[0 .. len];\n        m.devt[pos + 1 .. len] = null;\n        m.devt[pos] = e;\n    }\n}\n\nextern (C) void rt_detachDisposeEvent(Object h, DEvent e)\n{\n    synchronized (h)\n    {\n        auto m = cast(Monitor*) getMonitor(h);\n        assert(m.impl is null);\n\n        foreach (p, v; m.devt)\n        {\n            if (v == e)\n            {\n                memmove(&m.devt[p], &m.devt[p + 1], (m.devt.length - p - 1) * DEvent.sizeof);\n                m.devt[$ - 1] = null;\n                return;\n            }\n        }\n    }\n}\n\nnothrow:\n\nextern (C) void _d_monitor_staticctor()\n{\n    version (Posix)\n    {\n        pthread_mutexattr_init(&gattr);\n        pthread_mutexattr_settype(&gattr, PTHREAD_MUTEX_RECURSIVE);\n    }\n    initMutex(&gmtx);\n}\n\nextern (C) void _d_monitor_staticdtor()\n{\n    destroyMutex(&gmtx);\n    version (Posix)\n        pthread_mutexattr_destroy(&gattr);\n}\n\npackage:\n\n// This is what the monitor reference in Object points to\nalias IMonitor = Object.Monitor;\nalias DEvent = void delegate(Object);\n\nversion (GNU)\n{\n    import gcc.config;\n    static if (GNU_Thread_Model == ThreadModel.Single)\n        version = SingleThreaded;\n    // Ignore ThreadModel, we don't want posix threads on windows and\n    // will always use native threading instead.\n}\n\nversion (SingleThreaded)\n{\n@nogc:\n    alias Mutex = int;\n\n    void initMutex(Mutex* mtx)\n    {\n    }\n\n    void destroyMutex(Mutex* mtx)\n    {\n    }\n\n    void lockMutex(Mutex* mtx)\n    {\n    }\n\n    void unlockMutex(Mutex* mtx)\n    {\n    }\n}\nelse version (Windows)\n{\n    version (CRuntime_DigitalMars)\n    {\n        pragma(lib, \"snn.lib\");\n    }\n    import core.sys.windows.windows;\n\n    alias Mutex = CRITICAL_SECTION;\n\n    alias initMutex = InitializeCriticalSection;\n    alias destroyMutex = DeleteCriticalSection;\n    alias lockMutex = EnterCriticalSection;\n    alias unlockMutex = LeaveCriticalSection;\n}\nelse version (Posix)\n{\n    import core.sys.posix.pthread;\n\n@nogc:\n    alias Mutex = pthread_mutex_t;\n    __gshared pthread_mutexattr_t gattr;\n\n    void initMutex(pthread_mutex_t* mtx)\n    {\n        pthread_mutex_init(mtx, &gattr) && assert(0);\n    }\n\n    void destroyMutex(pthread_mutex_t* mtx)\n    {\n        pthread_mutex_destroy(mtx) && assert(0);\n    }\n\n    void lockMutex(pthread_mutex_t* mtx)\n    {\n        pthread_mutex_lock(mtx) && assert(0);\n    }\n\n    void unlockMutex(pthread_mutex_t* mtx)\n    {\n        pthread_mutex_unlock(mtx) && assert(0);\n    }\n}\nelse\n{\n    static assert(0, \"Unsupported platform\");\n}\n\nstruct Monitor\n{\n    IMonitor impl; // for user-level monitors\n    DEvent[] devt; // for internal monitors\n    size_t refs; // reference count\n    Mutex mtx;\n}\n\nprivate:\n\n@property ref shared(Monitor*) monitor(Object h) pure nothrow @nogc\n{\n    return *cast(shared Monitor**)&h.__monitor;\n}\n\nprivate shared(Monitor)* getMonitor(Object h) pure @nogc\n{\n    return atomicLoad!(MemoryOrder.acq)(h.monitor);\n}\n\nvoid setMonitor(Object h, shared(Monitor)* m) pure @nogc\n{\n    atomicStore!(MemoryOrder.rel)(h.monitor, m);\n}\n\n__gshared Mutex gmtx;\n\nshared(Monitor)* ensureMonitor(Object h)\n{\n    if (auto m = getMonitor(h))\n        return m;\n\n    auto m = cast(Monitor*) calloc(Monitor.sizeof, 1);\n    assert(m);\n    initMutex(&m.mtx);\n\n    bool success;\n    lockMutex(&gmtx);\n    if (getMonitor(h) is null)\n    {\n        m.refs = 1;\n        setMonitor(h, cast(shared) m);\n        success = true;\n    }\n    unlockMutex(&gmtx);\n\n    if (success)\n    {\n        // Set the finalize bit so that the monitor gets collected (Bugzilla 14573)\n        import core.memory : GC;\n\n        if (!(typeid(h).m_flags & TypeInfo_Class.ClassFlags.hasDtor))\n            GC.setAttr(cast(void*) h, GC.BlkAttr.FINALIZE);\n        return cast(shared(Monitor)*) m;\n    }\n    else // another thread succeeded instead\n    {\n        deleteMonitor(m);\n        return getMonitor(h);\n    }\n}\n\nvoid deleteMonitor(Monitor* m) @nogc\n{\n    destroyMutex(&m.mtx);\n    free(m);\n}\n\nvoid disposeEvent(Monitor* m, Object h)\n{\n    foreach (v; m.devt)\n    {\n        if (v)\n            v(h);\n    }\n    if (m.devt.ptr)\n        free(m.devt.ptr);\n}\n\n// Bugzilla 14573\nunittest\n{\n    import core.memory : GC;\n\n    auto obj = new Object;\n    assert(!(GC.getAttr(cast(void*) obj) & GC.BlkAttr.FINALIZE));\n    ensureMonitor(obj);\n    assert(getMonitor(obj) !is null);\n    assert(GC.getAttr(cast(void*) obj) & GC.BlkAttr.FINALIZE);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/obj.d",
    "content": "/**\n * Contains object comparator functions called by generated code.\n *\n * Copyright: Copyright Digital Mars 2002 - 2010.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2000 - 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.obj;\n\nextern (C):\n\n/********************************\n * Compiler helper for operator == for class objects.\n */\n\nint _d_obj_eq(Object o1, Object o2)\n{\n    return o1 is o2 || (o1 && o1.opEquals(o2));\n}\n\n\n/********************************\n * Compiler helper for operator <, <=, >, >= for class objects.\n */\n\nint _d_obj_cmp(Object o1, Object o2)\n{\n    return o1.opCmp(o2);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/qsort.d",
    "content": "/**\n * This is a public domain version of qsort.d.  All it does is call C's\n * qsort().\n *\n * Copyright: Copyright Digital Mars 2000 - 2010.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, Martin Nowak\n */\n\n/*          Copyright Digital Mars 2000 - 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.qsort;\n\n//debug=qsort;\n\nprivate import core.stdc.stdlib;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (CRuntime_Glibc)\n{\n    alias extern (C) int function(scope const void *, scope const void *, scope void *) Cmp;\n    extern (C) void qsort_r(scope void *base, size_t nmemb, size_t size, Cmp cmp, scope void *arg);\n\n    extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)\n    {\n        extern (C) int cmp(scope const void* p1, scope const void* p2, scope void* ti)\n        {\n            return (cast(TypeInfo)ti).compare(p1, p2);\n        }\n        qsort_r(a.ptr, a.length, ti.tsize, &cmp, cast(void*)ti);\n        return a;\n    }\n}\nelse version (FreeBSD)\n{\n    alias extern (C) int function(scope void *, scope const void *, scope const void *) Cmp;\n    extern (C) void qsort_r(scope void *base, size_t nmemb, size_t size, scope void *thunk, Cmp cmp);\n\n    extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)\n    {\n        extern (C) int cmp(scope void* ti, scope const void* p1, scope const void* p2)\n        {\n            return (cast(TypeInfo)ti).compare(p1, p2);\n        }\n        qsort_r(a.ptr, a.length, ti.tsize, cast(void*)ti, &cmp);\n        return a;\n    }\n}\nelse version (DragonFlyBSD)\n{\n    alias extern (C) int function(scope void *, scope const void *, scope const void *) Cmp;\n    extern (C) void qsort_r(scope void *base, size_t nmemb, size_t size, scope void *thunk, Cmp cmp);\n\n    extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)\n    {\n        extern (C) int cmp(scope void* ti, scope const void* p1, scope const void* p2)\n        {\n            return (cast(TypeInfo)ti).compare(p1, p2);\n        }\n        qsort_r(a.ptr, a.length, ti.tsize, cast(void*)ti, &cmp);\n        return a;\n    }\n}\nelse version (Darwin)\n{\n    alias extern (C) int function(scope void *, scope const void *, scope const void *) Cmp;\n    extern (C) void qsort_r(scope void *base, size_t nmemb, size_t size, scope void *thunk, Cmp cmp);\n\n    extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)\n    {\n        extern (C) int cmp(scope void* ti, scope const void* p1, scope const void* p2)\n        {\n            return (cast(TypeInfo)ti).compare(p1, p2);\n        }\n        qsort_r(a.ptr, a.length, ti.tsize, cast(void*)ti, &cmp);\n        return a;\n    }\n}\nelse version (CRuntime_UClibc)\n{\n    alias extern (C) int function(scope const void *, scope const void *, scope void *) __compar_d_fn_t;\n    extern (C) void qsort_r(scope void *base, size_t nmemb, size_t size, __compar_d_fn_t cmp, scope void *arg);\n\n    extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)\n    {\n        extern (C) int cmp(scope const void* p1, scope const void* p2, scope void* ti)\n        {\n            return (cast(TypeInfo)ti).compare(p1, p2);\n        }\n        qsort_r(a.ptr, a.length, ti.tsize, &cmp, cast(void*)ti);\n        return a;\n    }\n}\nelse\n{\n    private TypeInfo tiglobal;\n\n    extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)\n    {\n        extern (C) int cmp(scope const void* p1, scope const void* p2)\n        {\n            return tiglobal.compare(p1, p2);\n        }\n        tiglobal = ti;\n        qsort(a.ptr, a.length, ti.tsize, &cmp);\n        return a;\n    }\n}\n\n\n\nunittest\n{\n    debug(qsort) printf(\"array.sort.unittest()\\n\");\n\n    int[] a = new int[10];\n\n    a[0] = 23;\n    a[1] = 1;\n    a[2] = 64;\n    a[3] = 5;\n    a[4] = 6;\n    a[5] = 5;\n    a[6] = 17;\n    a[7] = 3;\n    a[8] = 0;\n    a[9] = -1;\n\n    _adSort(*cast(void[]*)&a, typeid(a[0]));\n\n    for (int i = 0; i < a.length - 1; i++)\n    {\n        //printf(\"i = %d\", i);\n        //printf(\" %d %d\\n\", a[i], a[i + 1]);\n        assert(a[i] <= a[i + 1]);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/sections.d",
    "content": "/**\n *\n * Copyright: Copyright Digital Mars 2000 - 2012.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Walter Bright, Sean Kelly, Martin Nowak\n * Source: $(DRUNTIMESRC rt/_sections.d)\n */\n\nmodule rt.sections;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (CRuntime_Glibc)\n    public import rt.sections_elf_shared;\nelse version (CRuntime_Musl)\n    public import rt.sections_elf_shared;\nelse version (FreeBSD)\n    public import rt.sections_elf_shared;\nelse version (NetBSD)\n    public import rt.sections_elf_shared;\nelse version (DragonFlyBSD)\n    public import rt.sections_elf_shared;\nelse version (Solaris)\n    public import rt.sections_solaris;\nelse version (Darwin)\n{\n    version (X86_64)\n        public import rt.sections_osx_x86_64;\n    else version (X86)\n        public import rt.sections_osx_x86;\n    else\n        static assert(0, \"unimplemented\");\n}\nelse version (CRuntime_DigitalMars)\n    public import rt.sections_win32;\nelse version (CRuntime_Microsoft)\n    public import rt.sections_win64;\nelse version (CRuntime_Bionic)\n    public import rt.sections_android;\nelse version (CRuntime_UClibc)\n    public import rt.sections_elf_shared;\nelse\n    static assert(0, \"unimplemented\");\n\nimport rt.deh, rt.minfo;\n\ntemplate isSectionGroup(T)\n{\n    enum isSectionGroup =\n        is(typeof(T.init.modules) == immutable(ModuleInfo*)[]) &&\n        is(typeof(T.init.moduleGroup) == ModuleGroup) &&\n        (!is(typeof(T.init.ehTables)) || is(typeof(T.init.ehTables) == immutable(FuncTable)[])) &&\n        is(typeof(T.init.gcRanges) == void[][]) &&\n        is(typeof({ foreach (ref T; T) {}})) &&\n        is(typeof({ foreach_reverse (ref T; T) {}}));\n}\nstatic assert(isSectionGroup!(SectionGroup));\nstatic assert(is(typeof(&initSections) == void function() nothrow @nogc));\nstatic assert(is(typeof(&finiSections) == void function() nothrow @nogc));\nstatic assert(is(typeof(&initTLSRanges) RT == return) &&\n              is(typeof(&initTLSRanges) == RT function() nothrow @nogc) &&\n              is(typeof(&finiTLSRanges) == void function(RT) nothrow @nogc) &&\n              is(typeof(&scanTLSRanges) == void function(RT, scope void delegate(void*, void*) nothrow) nothrow));\n\nversion (Shared)\n{\n    static assert(is(typeof(&pinLoadedLibraries) == void* function() nothrow @nogc));\n    static assert(is(typeof(&unpinLoadedLibraries) == void function(void*) nothrow @nogc));\n    static assert(is(typeof(&inheritLoadedLibraries) == void function(void*) nothrow @nogc));\n    static assert(is(typeof(&cleanupLoadedLibraries) == void function() nothrow @nogc));\n}\n\nbool scanDataSegPrecisely() nothrow @nogc\n{\n    import rt.config;\n    string opt = rt_configOption(\"scanDataSeg\");\n    switch (opt)\n    {\n        case \"\":\n        case \"conservative\":\n            return false;\n        case \"precise\":\n            return true;\n        default:\n            __gshared err = new Error(\"DRT invalid scanDataSeg option, must be 'precise' or 'conservative'\");\n            throw err;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/sections_android.d",
    "content": "/**\n * Written in the D programming language.\n * This module provides bionic-specific support for sections.\n *\n * Copyright: Copyright Martin Nowak 2012-2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n * Source: $(DRUNTIMESRC rt/_sections_android.d)\n */\n\nmodule rt.sections_android;\n\nversion (CRuntime_Bionic):\n\n// debug = PRINTF;\ndebug(PRINTF) import core.stdc.stdio;\nimport core.stdc.stdlib : malloc, free;\nimport rt.deh, rt.minfo;\nimport core.sys.posix.pthread;\nimport core.stdc.stdlib : calloc;\nimport core.stdc.string : memcpy;\n\nstruct SectionGroup\n{\n    static int opApply(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    static int opApplyReverse(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    @property immutable(ModuleInfo*)[] modules() const nothrow @nogc\n    {\n        return _moduleGroup.modules;\n    }\n\n    @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc\n    {\n        return _moduleGroup;\n    }\n\n    @property immutable(FuncTable)[] ehTables() const nothrow @nogc\n    {\n        auto pbeg = cast(immutable(FuncTable)*)&__start_deh;\n        auto pend = cast(immutable(FuncTable)*)&__stop_deh;\n        return pbeg[0 .. pend - pbeg];\n    }\n\n    @property inout(void[])[] gcRanges() inout nothrow @nogc\n    {\n        return _gcRanges[];\n    }\n\nprivate:\n    ModuleGroup _moduleGroup;\n    void[][1] _gcRanges;\n}\n\nvoid initSections() nothrow @nogc\n{\n    pthread_key_create(&_tlsKey, null);\n\n    auto mbeg = cast(immutable ModuleInfo**)&__start_minfo;\n    auto mend = cast(immutable ModuleInfo**)&__stop_minfo;\n    _sections.moduleGroup = ModuleGroup(mbeg[0 .. mend - mbeg]);\n\n    auto pbeg = cast(void*)&_tlsend;\n    auto pend = cast(void*)&__bss_end__;\n    // _tlsend is a 32-bit int and may not be 64-bit void*-aligned, so align pbeg.\n    version (D_LP64) pbeg = cast(void*)(cast(size_t)(pbeg + 7) & ~cast(size_t)7);\n    _sections._gcRanges[0] = pbeg[0 .. pend - pbeg];\n}\n\nvoid finiSections() nothrow @nogc\n{\n    pthread_key_delete(_tlsKey);\n}\n\nvoid[]* initTLSRanges() nothrow @nogc\n{\n    return &getTLSBlock();\n}\n\nvoid finiTLSRanges(void[]* rng) nothrow @nogc\n{\n    .free(rng.ptr);\n    .free(rng);\n}\n\nvoid scanTLSRanges(void[]* rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow\n{\n    dg(rng.ptr, rng.ptr + rng.length);\n}\n\n/* NOTE: The Bionic C library ignores thread-local data stored in the normal\n *       .tbss/.tdata ELF sections, which are marked with the SHF_TLS/STT_TLS\n *       flags.  So instead we roll our own by keeping TLS data in the\n *       .tdata/.tbss sections but removing the SHF_TLS/STT_TLS flags, and\n *       access the TLS data using this function and the _tlsstart/_tlsend\n *       symbols as delimiters.\n *\n *       This function is called by the code emitted by the compiler.  It\n *       is expected to translate an address in the TLS static data to\n *       the corresponding address in the TLS dynamic per-thread data.\n */\n\nversion (X86)\n{\n    // NB: the compiler mangles this function as '___tls_get_addr'\n    // even though it is extern(D)\n    extern(D) void* ___tls_get_addr( void* p ) nothrow @nogc\n    {\n        debug(PRINTF) printf(\"  ___tls_get_addr input - %p\\n\", p);\n        immutable offset = cast(size_t)(p - cast(void*)&_tlsstart);\n        auto tls = getTLSBlockAlloc();\n        assert(offset < tls.length);\n        return tls.ptr + offset;\n    }\n}\nelse version (ARM)\n{\n    extern(C) void* __tls_get_addr( void** p ) nothrow @nogc\n    {\n        debug(PRINTF) printf(\"  __tls_get_addr input - %p\\n\", *p);\n        immutable offset = cast(size_t)(*p - cast(void*)&_tlsstart);\n        auto tls = getTLSBlockAlloc();\n        assert(offset < tls.length);\n        return tls.ptr + offset;\n    }\n}\nelse version (AArch64)\n{\n    extern(C) void* __tls_get_addr( void* p ) nothrow @nogc\n    {\n        debug(PRINTF) printf(\"  __tls_get_addr input - %p\\n\", p);\n        immutable offset = cast(size_t)(p - cast(void*)&_tlsstart);\n        auto tls = getTLSBlockAlloc();\n        assert(offset < tls.length);\n        return tls.ptr + offset;\n    }\n}\nelse\n    static assert( false, \"Android architecture not supported.\" );\n\nprivate:\n\n__gshared pthread_key_t _tlsKey;\n\nref void[] getTLSBlock() nothrow @nogc\n{\n    auto pary = cast(void[]*)pthread_getspecific(_tlsKey);\n    if (pary is null)\n    {\n        pary = cast(void[]*).calloc(1, (void[]).sizeof);\n        if (pthread_setspecific(_tlsKey, pary) != 0)\n        {\n            import core.stdc.stdio;\n            perror(\"pthread_setspecific failed with\");\n            assert(0);\n        }\n    }\n    return *pary;\n}\n\nref void[] getTLSBlockAlloc() nothrow @nogc\n{\n    auto pary = &getTLSBlock();\n    if (!pary.length)\n    {\n        auto pbeg = cast(void*)&_tlsstart;\n        auto pend = cast(void*)&_tlsend;\n        auto p = .malloc(pend - pbeg);\n        memcpy(p, pbeg, pend - pbeg);\n        *pary = p[0 .. pend - pbeg];\n    }\n    return *pary;\n}\n\n__gshared SectionGroup _sections;\n\nextern(C)\n{\n    /* Symbols created by the compiler/linker and inserted into the\n     * object file that 'bracket' sections.\n     */\n    extern __gshared\n    {\n        void* __start_deh;\n        void* __stop_deh;\n        void* __start_minfo;\n        void* __stop_minfo;\n\n        size_t __bss_end__;\n\n        int _tlsstart;\n        int _tlsend;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/sections_elf_shared.d",
    "content": "/**\n * Written in the D programming language.\n * This module provides ELF-specific support for sections with shared libraries.\n *\n * Copyright: Copyright Martin Nowak 2012-2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n * Source: $(DRUNTIMESRC rt/_sections_linux.d)\n */\n\nmodule rt.sections_elf_shared;\n\nversion (CRuntime_Glibc) enum SharedELF = true;\nelse version (CRuntime_Musl) enum SharedELF = true;\nelse version (FreeBSD) enum SharedELF = true;\nelse version (NetBSD) enum SharedELF = true;\nelse version (DragonFlyBSD) enum SharedELF = true;\nelse version (CRuntime_UClibc) enum SharedELF = true;\nelse enum SharedELF = false;\nstatic if (SharedELF):\n\n// debug = PRINTF;\nimport core.memory;\nimport core.stdc.stdio;\nimport core.stdc.stdlib : calloc, exit, free, malloc, EXIT_FAILURE;\nimport core.stdc.string : strlen;\nversion (linux)\n{\n    import core.sys.linux.dlfcn;\n    import core.sys.linux.elf;\n    import core.sys.linux.link;\n}\nelse version (FreeBSD)\n{\n    import core.sys.freebsd.dlfcn;\n    import core.sys.freebsd.sys.elf;\n    import core.sys.freebsd.sys.link_elf;\n}\nelse version (NetBSD)\n{\n    import core.sys.netbsd.dlfcn;\n    import core.sys.netbsd.sys.elf;\n    import core.sys.netbsd.sys.link_elf;\n}\nelse version (DragonFlyBSD)\n{\n    import core.sys.dragonflybsd.dlfcn;\n    import core.sys.dragonflybsd.sys.elf;\n    import core.sys.dragonflybsd.sys.link_elf;\n}\nelse\n{\n    static assert(0, \"unimplemented\");\n}\nimport core.sys.posix.pthread;\nimport rt.deh;\nimport rt.dmain2;\nimport rt.minfo;\nimport rt.util.container.array;\nimport rt.util.container.hashtab;\n\n/****\n * Asserts the specified condition, independent from -release, by abort()ing.\n * Regular assertions throw an AssertError and thus require an initialized\n * GC, which isn't the case (yet or anymore) for the startup/shutdown code in\n * this module (called by CRT ctors/dtors etc.).\n */\nprivate void safeAssert(bool condition, scope string msg, size_t line = __LINE__) @nogc nothrow @safe\n{\n    import core.internal.abort;\n    condition || abort(msg, __FILE__, line);\n}\n\nalias DSO SectionGroup;\nstruct DSO\n{\n    static int opApply(scope int delegate(ref DSO) dg)\n    {\n        foreach (dso; _loadedDSOs)\n        {\n            if (auto res = dg(*dso))\n                return res;\n        }\n        return 0;\n    }\n\n    static int opApplyReverse(scope int delegate(ref DSO) dg)\n    {\n        foreach_reverse (dso; _loadedDSOs)\n        {\n            if (auto res = dg(*dso))\n                return res;\n        }\n        return 0;\n    }\n\n    @property immutable(ModuleInfo*)[] modules() const nothrow @nogc\n    {\n        return _moduleGroup.modules;\n    }\n\n    @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc\n    {\n        return _moduleGroup;\n    }\n\n    @property immutable(FuncTable)[] ehTables() const nothrow @nogc\n    {\n        return null;\n    }\n\n    @property inout(void[])[] gcRanges() inout nothrow @nogc\n    {\n        return _gcRanges[];\n    }\n\nprivate:\n\n    invariant()\n    {\n        safeAssert(_moduleGroup.modules.length > 0, \"No modules for DSO.\");\n        version (CRuntime_UClibc) {} else\n        safeAssert(_tlsMod || !_tlsSize, \"Inconsistent TLS fields for DSO.\");\n    }\n\n    ModuleGroup _moduleGroup;\n    Array!(void[]) _gcRanges;\n    size_t _tlsMod;\n    size_t _tlsSize;\n\n    version (Shared)\n    {\n        Array!(void[]) _codeSegments; // array of code segments\n        Array!(DSO*) _deps; // D libraries needed by this DSO\n        void* _handle; // corresponding handle\n    }\n\n    // get the TLS range for the executing thread\n    void[] tlsRange() const nothrow @nogc\n    {\n        return getTLSRange(_tlsMod, _tlsSize);\n    }\n}\n\n/****\n * Boolean flag set to true while the runtime is initialized.\n */\n__gshared bool _isRuntimeInitialized;\n\n\nversion (FreeBSD) private __gshared void* dummy_ref;\nversion (DragonFlyBSD) private __gshared void* dummy_ref;\nversion (NetBSD) private __gshared void* dummy_ref;\n\n/****\n * Gets called on program startup just before GC is initialized.\n */\nvoid initSections() nothrow @nogc\n{\n    _isRuntimeInitialized = true;\n    // reference symbol to support weak linkage\n    version (FreeBSD) dummy_ref = &_d_dso_registry;\n    version (DragonFlyBSD) dummy_ref = &_d_dso_registry;\n    version (NetBSD) dummy_ref = &_d_dso_registry;\n}\n\n\n/***\n * Gets called on program shutdown just after GC is terminated.\n */\nvoid finiSections() nothrow @nogc\n{\n    _isRuntimeInitialized = false;\n}\n\nalias ScanDG = void delegate(void* pbeg, void* pend) nothrow;\n\nversion (Shared)\n{\n    /***\n     * Called once per thread; returns array of thread local storage ranges\n     */\n    Array!(ThreadDSO)* initTLSRanges() @nogc nothrow\n    {\n        return &_loadedDSOs;\n    }\n\n    void finiTLSRanges(Array!(ThreadDSO)* tdsos) @nogc nothrow\n    {\n        // Nothing to do here. tdsos used to point to the _loadedDSOs instance\n        // in the dying thread's TLS segment and as such is not valid anymore.\n        // The memory for the array contents was already reclaimed in\n        // cleanupLoadedLibraries().\n    }\n\n    void scanTLSRanges(Array!(ThreadDSO)* tdsos, scope ScanDG dg) nothrow\n    {\n        foreach (ref tdso; *tdsos)\n            dg(tdso._tlsRange.ptr, tdso._tlsRange.ptr + tdso._tlsRange.length);\n    }\n\n    // interface for core.thread to inherit loaded libraries\n    void* pinLoadedLibraries() nothrow @nogc\n    {\n        auto res = cast(Array!(ThreadDSO)*)calloc(1, Array!(ThreadDSO).sizeof);\n        res.length = _loadedDSOs.length;\n        foreach (i, ref tdso; _loadedDSOs)\n        {\n            (*res)[i] = tdso;\n            if (tdso._addCnt)\n            {\n                // Increment the dlopen ref for explicitly loaded libraries to pin them.\n                const success = .dlopen(linkMapForHandle(tdso._pdso._handle).l_name, RTLD_LAZY) !is null;\n                safeAssert(success, \"Failed to increment dlopen ref.\");\n                (*res)[i]._addCnt = 1; // new array takes over the additional ref count\n            }\n        }\n        return res;\n    }\n\n    void unpinLoadedLibraries(void* p) nothrow @nogc\n    {\n        auto pary = cast(Array!(ThreadDSO)*)p;\n        // In case something failed we need to undo the pinning.\n        foreach (ref tdso; *pary)\n        {\n            if (tdso._addCnt)\n            {\n                auto handle = tdso._pdso._handle;\n                safeAssert(handle !is null, \"Invalid library handle.\");\n                .dlclose(handle);\n            }\n        }\n        pary.reset();\n        .free(pary);\n    }\n\n    // Called before TLS ctors are ran, copy over the loaded libraries\n    // of the parent thread.\n    void inheritLoadedLibraries(void* p) nothrow @nogc\n    {\n        safeAssert(_loadedDSOs.empty, \"DSOs have already been registered for this thread.\");\n        _loadedDSOs.swap(*cast(Array!(ThreadDSO)*)p);\n        .free(p);\n        foreach (ref dso; _loadedDSOs)\n        {\n            // the copied _tlsRange corresponds to parent thread\n            dso.updateTLSRange();\n        }\n    }\n\n    // Called after all TLS dtors ran, decrements all remaining dlopen refs.\n    void cleanupLoadedLibraries() nothrow @nogc\n    {\n        foreach (ref tdso; _loadedDSOs)\n        {\n            if (tdso._addCnt == 0) continue;\n\n            auto handle = tdso._pdso._handle;\n            safeAssert(handle !is null, \"Invalid DSO handle.\");\n            for (; tdso._addCnt > 0; --tdso._addCnt)\n                .dlclose(handle);\n        }\n\n        // Free the memory for the array contents.\n        _loadedDSOs.reset();\n    }\n}\nelse\n{\n    /***\n     * Called once per thread; returns array of thread local storage ranges\n     */\n    Array!(void[])* initTLSRanges() nothrow @nogc\n    {\n        return &_tlsRanges;\n    }\n\n    void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc\n    {\n        rngs.reset();\n    }\n\n    void scanTLSRanges(Array!(void[])* rngs, scope ScanDG dg) nothrow\n    {\n        foreach (rng; *rngs)\n            dg(rng.ptr, rng.ptr + rng.length);\n    }\n}\n\nprivate:\n\n// start of linked list for ModuleInfo references\nversion (FreeBSD) deprecated extern (C) __gshared void* _Dmodule_ref;\nversion (DragonFlyBSD) deprecated extern (C) __gshared void* _Dmodule_ref;\nversion (NetBSD) deprecated extern (C) __gshared void* _Dmodule_ref;\n\nversion (Shared)\n{\n    /*\n     * Array of thread local DSO metadata for all libraries loaded and\n     * initialized in this thread.\n     *\n     * Note:\n     *     A newly spawned thread will inherit these libraries.\n     * Note:\n     *     We use an array here to preserve the order of\n     *     initialization.  If that became a performance issue, we\n     *     could use a hash table and enumerate the DSOs during\n     *     loading so that the hash table values could be sorted when\n     *     necessary.\n     */\n    struct ThreadDSO\n    {\n        DSO* _pdso;\n        static if (_pdso.sizeof == 8) uint _refCnt, _addCnt;\n        else static if (_pdso.sizeof == 4) ushort _refCnt, _addCnt;\n        else static assert(0, \"unimplemented\");\n        void[] _tlsRange;\n        alias _pdso this;\n        // update the _tlsRange for the executing thread\n        void updateTLSRange() nothrow @nogc\n        {\n            _tlsRange = _pdso.tlsRange();\n        }\n    }\n    Array!(ThreadDSO) _loadedDSOs;\n\n    /*\n     * Set to true during rt_loadLibrary/rt_unloadLibrary calls.\n     */\n    bool _rtLoading;\n\n    /*\n     * Hash table to map link_map* to corresponding DSO*.\n     * The hash table is protected by a Mutex.\n     */\n    __gshared pthread_mutex_t _handleToDSOMutex;\n    __gshared HashTab!(void*, DSO*) _handleToDSO;\n\n    /*\n     * Section in executable that contains copy relocations.\n     * Might be null when druntime is dynamically loaded by a C host.\n     */\n    __gshared const(void)[] _copyRelocSection;\n}\nelse\n{\n    /*\n     * Static DSOs loaded by the runtime linker. This includes the\n     * executable. These can't be unloaded.\n     */\n    __gshared Array!(DSO*) _loadedDSOs;\n\n    /*\n     * Thread local array that contains TLS memory ranges for each\n     * library initialized in this thread.\n     */\n    Array!(void[]) _tlsRanges;\n\n    enum _rtLoading = false;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// Compiler to runtime interface.\n///////////////////////////////////////////////////////////////////////////////\n\n\n/*\n * This data structure is generated by the compiler, and then passed to\n * _d_dso_registry().\n */\nstruct CompilerDSOData\n{\n    size_t _version;                                       // currently 1\n    void** _slot;                                          // can be used to store runtime data\n    immutable(object.ModuleInfo*)* _minfo_beg, _minfo_end; // array of modules in this object file\n}\n\nT[] toRange(T)(T* beg, T* end) { return beg[0 .. end - beg]; }\n\n/* For each shared library and executable, the compiler generates code that\n * sets up CompilerDSOData and calls _d_dso_registry().\n * A pointer to that code is inserted into both the .ctors and .dtors\n * segment so it gets called by the loader on startup and shutdown.\n */\nextern(C) void _d_dso_registry(CompilerDSOData* data)\n{\n    // only one supported currently\n    safeAssert(data._version >= 1, \"Incompatible compiler-generated DSO data version.\");\n\n    // no backlink => register\n    if (*data._slot is null)\n    {\n        immutable firstDSO = _loadedDSOs.empty;\n        if (firstDSO) initLocks();\n\n        DSO* pdso = cast(DSO*).calloc(1, DSO.sizeof);\n        assert(typeid(DSO).initializer().ptr is null);\n        *data._slot = pdso; // store backlink in library record\n\n        pdso._moduleGroup = ModuleGroup(toRange(data._minfo_beg, data._minfo_end));\n\n        dl_phdr_info info = void;\n        const headerFound = findDSOInfoForAddr(data._slot, &info);\n        safeAssert(headerFound, \"Failed to find image header.\");\n\n        scanSegments(info, pdso);\n\n        version (Shared)\n        {\n            auto handle = handleForAddr(data._slot);\n\n            getDependencies(info, pdso._deps);\n            pdso._handle = handle;\n            setDSOForHandle(pdso, pdso._handle);\n\n            if (!_rtLoading)\n            {\n                /* This DSO was not loaded by rt_loadLibrary which\n                 * happens for all dependencies of an executable or\n                 * the first dlopen call from a C program.\n                 * In this case we add the DSO to the _loadedDSOs of this\n                 * thread with a refCnt of 1 and call the TlsCtors.\n                 */\n                immutable ushort refCnt = 1, addCnt = 0;\n                _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt, pdso.tlsRange()));\n            }\n        }\n        else\n        {\n            foreach (p; _loadedDSOs)\n                safeAssert(p !is pdso, \"DSO already registered.\");\n            _loadedDSOs.insertBack(pdso);\n            _tlsRanges.insertBack(pdso.tlsRange());\n        }\n\n        // don't initialize modules before rt_init was called (see Bugzilla 11378)\n        if (_isRuntimeInitialized)\n        {\n            registerGCRanges(pdso);\n            // rt_loadLibrary will run tls ctors, so do this only for dlopen\n            immutable runTlsCtors = !_rtLoading;\n            runModuleConstructors(pdso, runTlsCtors);\n        }\n    }\n    // has backlink => unregister\n    else\n    {\n        DSO* pdso = cast(DSO*)*data._slot;\n        *data._slot = null;\n\n        // don't finalizes modules after rt_term was called (see Bugzilla 11378)\n        if (_isRuntimeInitialized)\n        {\n            // rt_unloadLibrary already ran tls dtors, so do this only for dlclose\n            immutable runTlsDtors = !_rtLoading;\n            runModuleDestructors(pdso, runTlsDtors);\n            unregisterGCRanges(pdso);\n            // run finalizers after module dtors (same order as in rt_term)\n            version (Shared) runFinalizers(pdso);\n        }\n\n        version (Shared)\n        {\n            if (!_rtLoading)\n            {\n                /* This DSO was not unloaded by rt_unloadLibrary so we\n                 * have to remove it from _loadedDSOs here.\n                 */\n                foreach (i, ref tdso; _loadedDSOs)\n                {\n                    if (tdso._pdso == pdso)\n                    {\n                        _loadedDSOs.remove(i);\n                        break;\n                    }\n                }\n            }\n\n            unsetDSOForHandle(pdso, pdso._handle);\n        }\n        else\n        {\n            // static DSOs are unloaded in reverse order\n            safeAssert(pdso == _loadedDSOs.back, \"DSO being unregistered isn't current last one.\");\n            _loadedDSOs.popBack();\n        }\n\n        freeDSO(pdso);\n\n        // last DSO being unloaded => shutdown registry\n        if (_loadedDSOs.empty)\n        {\n            version (Shared)\n            {\n                safeAssert(_handleToDSO.empty, \"_handleToDSO not in sync with _loadedDSOs.\");\n                _handleToDSO.reset();\n            }\n            finiLocks();\n        }\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// dynamic loading\n///////////////////////////////////////////////////////////////////////////////\n\n// Shared D libraries are only supported when linking against a shared druntime library.\n\nversion (Shared)\n{\n    ThreadDSO* findThreadDSO(DSO* pdso) nothrow @nogc\n    {\n        foreach (ref tdata; _loadedDSOs)\n            if (tdata._pdso == pdso) return &tdata;\n        return null;\n    }\n\n    void incThreadRef(DSO* pdso, bool incAdd)\n    {\n        if (auto tdata = findThreadDSO(pdso)) // already initialized\n        {\n            if (incAdd && ++tdata._addCnt > 1) return;\n            ++tdata._refCnt;\n        }\n        else\n        {\n            foreach (dep; pdso._deps)\n                incThreadRef(dep, false);\n            immutable ushort refCnt = 1, addCnt = incAdd ? 1 : 0;\n            _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt, pdso.tlsRange()));\n            pdso._moduleGroup.runTlsCtors();\n        }\n    }\n\n    void decThreadRef(DSO* pdso, bool decAdd)\n    {\n        auto tdata = findThreadDSO(pdso);\n        safeAssert(tdata !is null, \"Failed to find thread DSO.\");\n        safeAssert(!decAdd || tdata._addCnt > 0, \"Mismatching rt_unloadLibrary call.\");\n\n        if (decAdd && --tdata._addCnt > 0) return;\n        if (--tdata._refCnt > 0) return;\n\n        pdso._moduleGroup.runTlsDtors();\n        foreach (i, ref td; _loadedDSOs)\n            if (td._pdso == pdso) _loadedDSOs.remove(i);\n        foreach (dep; pdso._deps)\n            decThreadRef(dep, false);\n    }\n\n    extern(C) void* rt_loadLibrary(const char* name)\n    {\n        immutable save = _rtLoading;\n        _rtLoading = true;\n        scope (exit) _rtLoading = save;\n\n        auto handle = .dlopen(name, RTLD_LAZY);\n        if (handle is null) return null;\n\n        // if it's a D library\n        if (auto pdso = dsoForHandle(handle))\n            incThreadRef(pdso, true);\n        return handle;\n    }\n\n    extern(C) int rt_unloadLibrary(void* handle)\n    {\n        if (handle is null) return false;\n\n        immutable save = _rtLoading;\n        _rtLoading = true;\n        scope (exit) _rtLoading = save;\n\n        // if it's a D library\n        if (auto pdso = dsoForHandle(handle))\n            decThreadRef(pdso, true);\n        return .dlclose(handle) == 0;\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// helper functions\n///////////////////////////////////////////////////////////////////////////////\n\nvoid initLocks() nothrow @nogc\n{\n    version (Shared)\n        !pthread_mutex_init(&_handleToDSOMutex, null) || assert(0);\n}\n\nvoid finiLocks() nothrow @nogc\n{\n    version (Shared)\n        !pthread_mutex_destroy(&_handleToDSOMutex) || assert(0);\n}\n\nvoid runModuleConstructors(DSO* pdso, bool runTlsCtors)\n{\n    pdso._moduleGroup.sortCtors();\n    pdso._moduleGroup.runCtors();\n    if (runTlsCtors) pdso._moduleGroup.runTlsCtors();\n}\n\nvoid runModuleDestructors(DSO* pdso, bool runTlsDtors)\n{\n    if (runTlsDtors) pdso._moduleGroup.runTlsDtors();\n    pdso._moduleGroup.runDtors();\n}\n\nvoid registerGCRanges(DSO* pdso) nothrow @nogc\n{\n    foreach (rng; pdso._gcRanges)\n        GC.addRange(rng.ptr, rng.length);\n}\n\nvoid unregisterGCRanges(DSO* pdso) nothrow @nogc\n{\n    foreach (rng; pdso._gcRanges)\n        GC.removeRange(rng.ptr);\n}\n\nversion (Shared) void runFinalizers(DSO* pdso)\n{\n    foreach (seg; pdso._codeSegments)\n        GC.runFinalizers(seg);\n}\n\nvoid freeDSO(DSO* pdso) nothrow @nogc\n{\n    pdso._gcRanges.reset();\n    version (Shared)\n    {\n        pdso._codeSegments.reset();\n        pdso._deps.reset();\n        pdso._handle = null;\n    }\n    .free(pdso);\n}\n\nversion (Shared)\n{\n@nogc nothrow:\n    link_map* linkMapForHandle(void* handle)\n    {\n        link_map* map;\n        const success = dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0;\n        safeAssert(success, \"Failed to get DSO info.\");\n        return map;\n    }\n\n     link_map* exeLinkMap(link_map* map)\n     {\n         safeAssert(map !is null, \"Invalid link_map.\");\n         while (map.l_prev !is null)\n             map = map.l_prev;\n         return map;\n     }\n\n    DSO* dsoForHandle(void* handle)\n    {\n        DSO* pdso;\n        !pthread_mutex_lock(&_handleToDSOMutex) || assert(0);\n        if (auto ppdso = handle in _handleToDSO)\n            pdso = *ppdso;\n        !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0);\n        return pdso;\n    }\n\n    void setDSOForHandle(DSO* pdso, void* handle)\n    {\n        !pthread_mutex_lock(&_handleToDSOMutex) || assert(0);\n        safeAssert(handle !in _handleToDSO, \"DSO already registered.\");\n        _handleToDSO[handle] = pdso;\n        !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0);\n    }\n\n    void unsetDSOForHandle(DSO* pdso, void* handle)\n    {\n        !pthread_mutex_lock(&_handleToDSOMutex) || assert(0);\n        safeAssert(_handleToDSO[handle] == pdso, \"Handle doesn't match registered DSO.\");\n        _handleToDSO.remove(handle);\n        !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0);\n    }\n\n    void getDependencies(in ref dl_phdr_info info, ref Array!(DSO*) deps)\n    {\n        // get the entries of the .dynamic section\n        ElfW!\"Dyn\"[] dyns;\n        foreach (ref phdr; info.dlpi_phdr[0 .. info.dlpi_phnum])\n        {\n            if (phdr.p_type == PT_DYNAMIC)\n            {\n                auto p = cast(ElfW!\"Dyn\"*)(info.dlpi_addr + (phdr.p_vaddr & ~(size_t.sizeof - 1)));\n                dyns = p[0 .. phdr.p_memsz / ElfW!\"Dyn\".sizeof];\n                break;\n            }\n        }\n        // find the string table which contains the sonames\n        const(char)* strtab;\n        foreach (dyn; dyns)\n        {\n            if (dyn.d_tag == DT_STRTAB)\n            {\n                version (CRuntime_Musl)\n                    strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate\n                else version (linux)\n                    strtab = cast(const(char)*)dyn.d_un.d_ptr;\n                else version (FreeBSD)\n                    strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate\n                else version (NetBSD)\n                    strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate\n                else version (DragonFlyBSD)\n                    strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate\n                else\n                    static assert(0, \"unimplemented\");\n                break;\n            }\n        }\n        foreach (dyn; dyns)\n        {\n            immutable tag = dyn.d_tag;\n            if (!(tag == DT_NEEDED || tag == DT_AUXILIARY || tag == DT_FILTER))\n                continue;\n\n            // soname of the dependency\n            auto name = strtab + dyn.d_un.d_val;\n            // get handle without loading the library\n            auto handle = handleForName(name);\n            // the runtime linker has already loaded all dependencies\n            safeAssert(handle !is null, \"Failed to get library handle.\");\n            // if it's a D library\n            if (auto pdso = dsoForHandle(handle))\n                deps.insertBack(pdso); // append it to the dependencies\n        }\n    }\n\n    void* handleForName(const char* name)\n    {\n        auto handle = .dlopen(name, RTLD_NOLOAD | RTLD_LAZY);\n        if (handle !is null) .dlclose(handle); // drop reference count\n        return handle;\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// Elf program header iteration\n///////////////////////////////////////////////////////////////////////////////\n\n/************\n * Scan segments in Linux dl_phdr_info struct and store\n * the TLS and writeable data segments in *pdso.\n */\nvoid scanSegments(in ref dl_phdr_info info, DSO* pdso) nothrow @nogc\n{\n    foreach (ref phdr; info.dlpi_phdr[0 .. info.dlpi_phnum])\n    {\n        switch (phdr.p_type)\n        {\n        case PT_LOAD:\n            if (phdr.p_flags & PF_W) // writeable data segment\n            {\n                auto beg = cast(void*)(info.dlpi_addr + (phdr.p_vaddr & ~(size_t.sizeof - 1)));\n                pdso._gcRanges.insertBack(beg[0 .. phdr.p_memsz]);\n            }\n            version (Shared) if (phdr.p_flags & PF_X) // code segment\n            {\n                auto beg = cast(void*)(info.dlpi_addr + (phdr.p_vaddr & ~(size_t.sizeof - 1)));\n                pdso._codeSegments.insertBack(beg[0 .. phdr.p_memsz]);\n            }\n            break;\n\n        case PT_TLS: // TLS segment\n            safeAssert(!pdso._tlsSize, \"Multiple TLS segments in image header.\");\n            version (CRuntime_UClibc)\n            {\n                // uClibc doesn't provide a 'dlpi_tls_modid' definition\n            }\n            else\n                pdso._tlsMod = info.dlpi_tls_modid;\n            pdso._tlsSize = phdr.p_memsz;\n            break;\n\n        default:\n            break;\n        }\n    }\n}\n\n/**************************\n * Input:\n *      result  where the output is to be written; dl_phdr_info is an OS struct\n * Returns:\n *      true if found, and *result is filled in\n * References:\n *      http://linux.die.net/man/3/dl_iterate_phdr\n */\nbool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc\n{\n    version (linux)       enum IterateManually = true;\n    else version (NetBSD) enum IterateManually = true;\n    else                  enum IterateManually = false;\n\n    static if (IterateManually)\n    {\n        static struct DG { const(void)* addr; dl_phdr_info* result; }\n\n        extern(C) int callback(dl_phdr_info* info, size_t sz, void* arg) nothrow @nogc\n        {\n            auto p = cast(DG*)arg;\n            if (findSegmentForAddr(*info, p.addr))\n            {\n                if (p.result !is null) *p.result = *info;\n                return 1; // break;\n            }\n            return 0; // continue iteration\n        }\n\n        auto dg = DG(addr, result);\n\n        /* OS function that walks through the list of an application's shared objects and\n         * calls 'callback' once for each object, until either all shared objects\n         * have been processed or 'callback' returns a nonzero value.\n         */\n        return dl_iterate_phdr(&callback, &dg) != 0;\n    }\n    else version (FreeBSD)\n    {\n        return !!_rtld_addr_phdr(addr, result);\n    }\n    else version (DragonFlyBSD)\n    {\n        return !!_rtld_addr_phdr(addr, result);\n    }\n    else\n        static assert(0, \"unimplemented\");\n}\n\n/*********************************\n * Determine if 'addr' lies within shared object 'info'.\n * If so, return true and fill in 'result' with the corresponding ELF program header.\n */\nbool findSegmentForAddr(in ref dl_phdr_info info, in void* addr, ElfW!\"Phdr\"* result=null) nothrow @nogc\n{\n    if (addr < cast(void*)info.dlpi_addr) // less than base address of object means quick reject\n        return false;\n\n    foreach (ref phdr; info.dlpi_phdr[0 .. info.dlpi_phnum])\n    {\n        auto beg = cast(void*)(info.dlpi_addr + phdr.p_vaddr);\n        if (cast(size_t)(addr - beg) < phdr.p_memsz)\n        {\n            if (result !is null) *result = phdr;\n            return true;\n        }\n    }\n    return false;\n}\n\nversion (linux) import core.sys.linux.errno : program_invocation_name;\n// should be in core.sys.freebsd.stdlib\nversion (FreeBSD) extern(C) const(char)* getprogname() nothrow @nogc;\nversion (DragonFlyBSD) extern(C) const(char)* getprogname() nothrow @nogc;\nversion (NetBSD) extern(C) const(char)* getprogname() nothrow @nogc;\n\n@property const(char)* progname() nothrow @nogc\n{\n    version (linux) return program_invocation_name;\n    version (FreeBSD) return getprogname();\n    version (DragonFlyBSD) return getprogname();\n    version (NetBSD) return getprogname();\n}\n\nconst(char)[] dsoName(const char* dlpi_name) nothrow @nogc\n{\n    // the main executable doesn't have a name in its dlpi_name field\n    const char* p = dlpi_name[0] != 0 ? dlpi_name : progname;\n    return p[0 .. strlen(p)];\n}\n\n/**************************\n * Input:\n *      addr  an internal address of a DSO\n * Returns:\n *      the dlopen handle for that DSO or null if addr is not within a loaded DSO\n */\nversion (Shared) void* handleForAddr(void* addr) nothrow @nogc\n{\n    Dl_info info = void;\n    if (dladdr(addr, &info) != 0)\n        return handleForName(info.dli_fname);\n    return null;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// TLS module helper\n///////////////////////////////////////////////////////////////////////////////\n\n\n/*\n * Returns: the TLS memory range for a given module and the calling\n * thread or null if that module has no TLS.\n *\n * Note: This will cause the TLS memory to be eagerly allocated.\n */\nstruct tls_index\n{\n    size_t ti_module;\n    size_t ti_offset;\n}\n\nextern(C) void* __tls_get_addr(tls_index* ti) nothrow @nogc;\n\n/* The dynamic thread vector (DTV) pointers may point 0x8000 past the start of\n * each TLS block. This is at least true for PowerPC and Mips platforms.\n * See: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/dl-tls.h;h=f7cf6f96ebfb505abfd2f02be0ad0e833107c0cd;hb=HEAD#l34\n *      https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/mips/dl-tls.h;h=93a6dc050cb144b9f68b96fb3199c60f5b1fcd18;hb=HEAD#l32\n */\nversion (X86)\n    enum TLS_DTV_OFFSET = 0x0;\nelse version (X86_64)\n    enum TLS_DTV_OFFSET = 0x0;\nelse version (ARM)\n    enum TLS_DTV_OFFSET = 0x0;\nelse version (AArch64)\n    enum TLS_DTV_OFFSET = 0x0;\nelse version (SPARC)\n    enum TLS_DTV_OFFSET = 0x0;\nelse version (SPARC64)\n    enum TLS_DTV_OFFSET = 0x0;\nelse version (PPC)\n    enum TLS_DTV_OFFSET = 0x8000;\nelse version (PPC64)\n    enum TLS_DTV_OFFSET = 0x8000;\nelse version (MIPS32)\n    enum TLS_DTV_OFFSET = 0x8000;\nelse version (MIPS64)\n    enum TLS_DTV_OFFSET = 0x8000;\nelse\n    static assert( false, \"Platform not supported.\" );\n\nvoid[] getTLSRange(size_t mod, size_t sz) nothrow @nogc\n{\n    if (mod == 0)\n        return null;\n\n    // base offset\n    auto ti = tls_index(mod, 0);\n    return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz];\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/sections_osx_x86.d",
    "content": "/**\n * Written in the D programming language.\n * This module provides OS X x86 specific support for sections.\n *\n * Copyright: Copyright Digital Mars 2008 - 2016.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors: Walter Bright, Sean Kelly, Martin Nowak, Jacob Carlborg\n * Source: $(DRUNTIMESRC rt/_sections_osx_x86.d)\n */\nmodule rt.sections_osx_x86;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nversion (X86):\n\n// debug = PRINTF;\nimport core.stdc.stdio;\nimport core.stdc.string, core.stdc.stdlib;\nimport core.sys.posix.pthread;\nimport core.sys.darwin.mach.dyld;\nimport core.sys.darwin.mach.getsect;\nimport rt.deh, rt.minfo;\nimport rt.util.container.array;\n\nstruct SectionGroup\n{\n    static int opApply(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    static int opApplyReverse(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    @property immutable(ModuleInfo*)[] modules() const\n    {\n        return _moduleGroup.modules;\n    }\n\n    @property ref inout(ModuleGroup) moduleGroup() inout\n    {\n        return _moduleGroup;\n    }\n\n    @property inout(void[])[] gcRanges() inout\n    {\n        return _gcRanges[];\n    }\n\n    @property immutable(FuncTable)[] ehTables() const\n    {\n        return _ehTables[];\n    }\n\nprivate:\n    immutable(FuncTable)[] _ehTables;\n    ModuleGroup _moduleGroup;\n    Array!(void[]) _gcRanges;\n    immutable(void)[][2] _tlsImage;\n}\n\n/****\n * Boolean flag set to true while the runtime is initialized.\n */\n__gshared bool _isRuntimeInitialized;\n\n/****\n * Gets called on program startup just before GC is initialized.\n */\nvoid initSections() nothrow @nogc\n{\n    pthread_key_create(&_tlsKey, null);\n    _dyld_register_func_for_add_image(&sections_osx_onAddImage);\n    _isRuntimeInitialized = true;\n}\n\n/***\n * Gets called on program shutdown just after GC is terminated.\n */\nvoid finiSections() nothrow @nogc\n{\n    _sections._gcRanges.reset();\n    pthread_key_delete(_tlsKey);\n    _isRuntimeInitialized = false;\n}\n\nvoid[]* initTLSRanges() nothrow @nogc\n{\n    return &getTLSBlock();\n}\n\nvoid finiTLSRanges(void[]* rng) nothrow @nogc\n{\n    .free(rng.ptr);\n    .free(rng);\n}\n\nvoid scanTLSRanges(void[]* rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow\n{\n    dg(rng.ptr, rng.ptr + rng.length);\n}\n\n// NOTE: The Mach-O object file format does not allow for thread local\n//       storage declarations. So instead we roll our own by putting tls\n//       into the __tls_data and the __tlscoal_nt sections.\n//\n//       This function is called by the code emitted by the compiler.  It\n//       is expected to translate an address into the TLS static data to\n//       the corresponding address in the TLS dynamic per-thread data.\n\n// NB: the compiler mangles this function as '___tls_get_addr' even though it is extern(D)\nextern(D) void* ___tls_get_addr( void* p )\n{\n    immutable off = tlsOffset(p);\n    auto tls = getTLSBlockAlloc();\n    assert(off < tls.length);\n    return tls.ptr + off;\n}\n\nprivate:\n\n__gshared pthread_key_t _tlsKey;\n\nsize_t tlsOffset(void* p)\nin\n{\n    assert(_sections._tlsImage[0].ptr !is null ||\n           _sections._tlsImage[1].ptr !is null);\n}\ndo\n{\n    // NOTE: p is an address in the TLS static data emitted by the\n    //       compiler.  If it isn't, something is disastrously wrong.\n    immutable off0 = cast(size_t)(p - _sections._tlsImage[0].ptr);\n    if (off0 < _sections._tlsImage[0].length)\n    {\n        return off0;\n    }\n    immutable off1 = cast(size_t)(p - _sections._tlsImage[1].ptr);\n    if (off1 < _sections._tlsImage[1].length)\n    {\n        size_t sz = (_sections._tlsImage[0].length + 15) & ~cast(size_t)15;\n        return sz + off1;\n    }\n    assert(0);\n}\n\nref void[] getTLSBlock() nothrow @nogc\n{\n    auto pary = cast(void[]*)pthread_getspecific(_tlsKey);\n    if (pary is null)\n    {\n        pary = cast(void[]*).calloc(1, (void[]).sizeof);\n        if (pthread_setspecific(_tlsKey, pary) != 0)\n        {\n            import core.stdc.stdio;\n            perror(\"pthread_setspecific failed with\");\n            assert(0);\n        }\n    }\n    return *pary;\n}\n\nref void[] getTLSBlockAlloc()\n{\n    auto pary = &getTLSBlock();\n    if (!pary.length)\n    {\n        auto imgs = _sections._tlsImage;\n        immutable sz0 = (imgs[0].length + 15) & ~cast(size_t)15;\n        immutable sz2 = sz0 + imgs[1].length;\n        auto p = .malloc(sz2);\n        memcpy(p, imgs[0].ptr, imgs[0].length);\n        memcpy(p + sz0, imgs[1].ptr, imgs[1].length);\n        *pary = p[0 .. sz2];\n    }\n    return *pary;\n}\n\n__gshared SectionGroup _sections;\n\nextern (C) void sections_osx_onAddImage(in mach_header* h, intptr_t slide)\n{\n    foreach (e; dataSegs)\n    {\n        auto sect = getSection(h, slide, e.seg.ptr, e.sect.ptr);\n        if (sect != null)\n            _sections._gcRanges.insertBack((cast(void*)sect.ptr)[0 .. sect.length]);\n    }\n\n    auto minfosect = getSection(h, slide, \"__DATA\", \"__minfodata\");\n    if (minfosect != null)\n    {\n        // no support for multiple images yet\n        // take the sections from the last static image which is the executable\n        if (_isRuntimeInitialized)\n        {\n            fprintf(stderr, \"Loading shared libraries isn't yet supported on Darwin.\\n\");\n            return;\n        }\n        else if (_sections.modules.ptr !is null)\n        {\n            fprintf(stderr, \"Shared libraries are not yet supported on Darwin.\\n\");\n        }\n\n        debug(PRINTF) printf(\"  minfodata\\n\");\n        auto p = cast(immutable(ModuleInfo*)*)minfosect.ptr;\n        immutable len = minfosect.length / (*p).sizeof;\n\n        _sections._moduleGroup = ModuleGroup(p[0 .. len]);\n    }\n\n    auto ehsect = getSection(h, slide, \"__DATA\", \"__deh_eh\");\n    if (ehsect != null)\n    {\n        debug(PRINTF) printf(\"  deh_eh\\n\");\n        auto p = cast(immutable(FuncTable)*)ehsect.ptr;\n        immutable len = ehsect.length / (*p).sizeof;\n\n        _sections._ehTables = p[0 .. len];\n    }\n\n    auto tlssect = getSection(h, slide, \"__DATA\", \"__tls_data\");\n    if (tlssect != null)\n    {\n        debug(PRINTF) printf(\"  tls_data %p %p\\n\", tlssect.ptr, tlssect.ptr + tlssect.length);\n        _sections._tlsImage[0] = (cast(immutable(void)*)tlssect.ptr)[0 .. tlssect.length];\n    }\n\n    auto tlssect2 = getSection(h, slide, \"__DATA\", \"__tlscoal_nt\");\n    if (tlssect2 != null)\n    {\n        debug(PRINTF) printf(\"  tlscoal_nt %p %p\\n\", tlssect2.ptr, tlssect2.ptr + tlssect2.length);\n        _sections._tlsImage[1] = (cast(immutable(void)*)tlssect2.ptr)[0 .. tlssect2.length];\n    }\n}\n\nstruct SegRef\n{\n    string seg;\n    string sect;\n}\n\n\nstatic immutable SegRef[] dataSegs = [{SEG_DATA, SECT_DATA},\n                                      {SEG_DATA, SECT_BSS},\n                                      {SEG_DATA, SECT_COMMON}];\n\n\nubyte[] getSection(in mach_header* header, intptr_t slide,\n                   in char* segmentName, in char* sectionName)\n{\n    assert(header.magic == MH_MAGIC);\n    auto sect = getsectbynamefromheader(header, segmentName, sectionName);\n\n    if (sect !is null && sect.size > 0)\n        return (cast(ubyte*)sect.addr + slide)[0 .. cast(size_t)sect.size];\n    return null;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/sections_osx_x86_64.d",
    "content": "/**\n * Written in the D programming language.\n * This module provides OS X x86-64 specific support for sections.\n *\n * Copyright: Copyright Digital Mars 2016.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors: Walter Bright, Sean Kelly, Martin Nowak, Jacob Carlborg\n * Source: $(DRUNTIMESRC rt/_sections_osx_x86_64.d)\n */\nmodule rt.sections_osx_x86_64;\n\nversion (OSX)\n    version = Darwin;\nelse version (iOS)\n    version = Darwin;\nelse version (TVOS)\n    version = Darwin;\nelse version (WatchOS)\n    version = Darwin;\n\nversion (Darwin):\nversion (X86_64):\n\n// debug = PRINTF;\nimport core.stdc.stdio;\nimport core.stdc.string, core.stdc.stdlib;\nimport core.sys.posix.pthread;\nimport core.sys.osx.mach.dyld;\nimport core.sys.osx.mach.getsect;\nimport rt.deh, rt.minfo;\nimport rt.util.container.array;\n\nstruct SectionGroup\n{\n    static int opApply(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    static int opApplyReverse(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    @property immutable(ModuleInfo*)[] modules() const\n    {\n        return _moduleGroup.modules;\n    }\n\n    @property ref inout(ModuleGroup) moduleGroup() inout\n    {\n        return _moduleGroup;\n    }\n\n    @property inout(void[])[] gcRanges() inout\n    {\n        return _gcRanges[];\n    }\n\n    @property immutable(FuncTable)[] ehTables() const\n    {\n        return _ehTables[];\n    }\n\nprivate:\n    immutable(FuncTable)[] _ehTables;\n    ModuleGroup _moduleGroup;\n    Array!(void[]) _gcRanges;\n}\n\n/****\n * Boolean flag set to true while the runtime is initialized.\n */\n__gshared bool _isRuntimeInitialized;\n\n/****\n * Gets called on program startup just before GC is initialized.\n */\nvoid initSections() nothrow @nogc\n{\n    _dyld_register_func_for_add_image(&sections_osx_onAddImage);\n    _isRuntimeInitialized = true;\n}\n\n/***\n * Gets called on program shutdown just after GC is terminated.\n */\nvoid finiSections() nothrow @nogc\n{\n    _sections._gcRanges.reset();\n    _isRuntimeInitialized = false;\n}\n\nvoid[] initTLSRanges() nothrow @nogc\n{\n    void* start = null;\n    size_t size = 0;\n    _d_dyld_getTLSRange(&dummyTlsSymbol, &start, &size);\n    assert(start && size, \"Could not determine TLS range.\");\n    return start[0 .. size];\n}\n\nvoid finiTLSRanges(void[] rng) nothrow @nogc\n{\n\n}\n\nvoid scanTLSRanges(void[] rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow\n{\n    dg(rng.ptr, rng.ptr + rng.length);\n}\n\nprivate:\n\nextern(C) void _d_dyld_getTLSRange(void*, void**, size_t*) nothrow @nogc;\n\n__gshared SectionGroup _sections;\nubyte dummyTlsSymbol;\n\nextern (C) void sections_osx_onAddImage(in mach_header* h, intptr_t slide)\n{\n    foreach (e; dataSegs)\n    {\n        auto sect = getSection(h, slide, e.seg.ptr, e.sect.ptr);\n        if (sect != null)\n            _sections._gcRanges.insertBack((cast(void*)sect.ptr)[0 .. sect.length]);\n    }\n\n    auto minfosect = getSection(h, slide, \"__DATA\", \"__minfodata\");\n    if (minfosect != null)\n    {\n        // no support for multiple images yet\n        // take the sections from the last static image which is the executable\n        if (_isRuntimeInitialized)\n        {\n            fprintf(stderr, \"Loading shared libraries isn't yet supported on OSX.\\n\");\n            return;\n        }\n        else if (_sections.modules.ptr !is null)\n        {\n            fprintf(stderr, \"Shared libraries are not yet supported on OSX.\\n\");\n        }\n\n        debug(PRINTF) printf(\"  minfodata\\n\");\n        auto p = cast(immutable(ModuleInfo*)*)minfosect.ptr;\n        immutable len = minfosect.length / (*p).sizeof;\n\n        _sections._moduleGroup = ModuleGroup(p[0 .. len]);\n    }\n\n    auto ehsect = getSection(h, slide, \"__DATA\", \"__deh_eh\");\n    if (ehsect != null)\n    {\n        debug(PRINTF) printf(\"  deh_eh\\n\");\n        auto p = cast(immutable(FuncTable)*)ehsect.ptr;\n        immutable len = ehsect.length / (*p).sizeof;\n\n        _sections._ehTables = p[0 .. len];\n    }\n}\n\nstruct SegRef\n{\n    string seg;\n    string sect;\n}\n\nstatic immutable SegRef[] dataSegs = [{SEG_DATA, SECT_DATA},\n                                      {SEG_DATA, SECT_BSS},\n                                      {SEG_DATA, SECT_COMMON}];\n\nubyte[] getSection(in mach_header* header, intptr_t slide,\n                   in char* segmentName, in char* sectionName)\n{\n    assert(header.magic == MH_MAGIC_64);\n    auto sect = getsectbynamefromheader_64(cast(mach_header_64*)header,\n                                        segmentName,\n                                        sectionName);\n\n    if (sect !is null && sect.size > 0)\n        return (cast(ubyte*)sect.addr + slide)[0 .. cast(size_t)sect.size];\n    return null;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/sections_solaris.d",
    "content": "/**\n * Written in the D programming language.\n * This module provides Solaris-specific support for sections.\n *\n * Copyright: Copyright Martin Nowak 2012-2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n * Source: $(DRUNTIMESRC rt/_sections_solaris.d)\n */\n\nmodule rt.sections_solaris;\n\nversion (Solaris):\n\n// debug = PRINTF;\ndebug(PRINTF) import core.stdc.stdio;\nimport core.stdc.stdlib : malloc, free;\nimport rt.deh, rt.minfo;\n\nstruct SectionGroup\n{\n    static int opApply(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    static int opApplyReverse(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    @property immutable(ModuleInfo*)[] modules() const\n    {\n        return _moduleGroup.modules;\n    }\n\n    @property ref inout(ModuleGroup) moduleGroup() inout\n    {\n        return _moduleGroup;\n    }\n\n    @property immutable(FuncTable)[] ehTables() const\n    {\n        auto pbeg = cast(immutable(FuncTable)*)&__start_deh;\n        auto pend = cast(immutable(FuncTable)*)&__stop_deh;\n        return pbeg[0 .. pend - pbeg];\n    }\n\n    @property inout(void[])[] gcRanges() inout\n    {\n        return _gcRanges[];\n    }\n\nprivate:\n    ModuleGroup _moduleGroup;\n    void[][1] _gcRanges;\n}\n\nvoid initSections() nothrow @nogc\n{\n    auto mbeg = cast(immutable ModuleInfo**)&__start_minfo;\n    auto mend = cast(immutable ModuleInfo**)&__stop_minfo;\n    _sections.moduleGroup = ModuleGroup(mbeg[0 .. mend - mbeg]);\n\n    auto pbeg = cast(void*)&__dso_handle;\n    auto pend = cast(void*)&_end;\n    _sections._gcRanges[0] = pbeg[0 .. pend - pbeg];\n}\n\nvoid finiSections() nothrow @nogc\n{\n}\n\nvoid[] initTLSRanges() nothrow @nogc\n{\n    auto pbeg = cast(void*)&_tlsstart;\n    auto pend = cast(void*)&_tlsend;\n    return pbeg[0 .. pend - pbeg];\n}\n\nvoid finiTLSRanges(void[] rng) nothrow @nogc\n{\n}\n\nvoid scanTLSRanges(void[] rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow\n{\n    dg(rng.ptr, rng.ptr + rng.length);\n}\n\nprivate:\n\n__gshared SectionGroup _sections;\n\nextern(C)\n{\n    /* Symbols created by the compiler/linker and inserted into the\n     * object file that 'bracket' sections.\n     */\n    extern __gshared\n    {\n        void* __start_deh;\n        void* __stop_deh;\n        void* __start_minfo;\n        void* __stop_minfo;\n        int __dso_handle;\n        int _end;\n    }\n\n    extern\n    {\n        void* _tlsstart;\n        void* _tlsend;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/sections_win32.d",
    "content": "/**\n * Written in the D programming language.\n * This module provides Win32-specific support for sections.\n *\n * Copyright: Copyright Digital Mars 2008 - 2012.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Walter Bright, Sean Kelly, Martin Nowak\n * Source: $(DRUNTIMESRC rt/_sections_win32.d)\n */\n\nmodule rt.sections_win32;\n\nversion (CRuntime_DigitalMars):\n\n// debug = PRINTF;\ndebug(PRINTF) import core.stdc.stdio;\nimport rt.minfo;\nimport core.stdc.stdlib : malloc, free;\n\nstruct SectionGroup\n{\n    static int opApply(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    static int opApplyReverse(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    @property immutable(ModuleInfo*)[] modules() const\n    {\n        return _moduleGroup.modules;\n    }\n\n    @property ref inout(ModuleGroup) moduleGroup() inout\n    {\n        return _moduleGroup;\n    }\n\n    @property inout(void[])[] gcRanges() inout\n    {\n        return _gcRanges[];\n    }\n\nprivate:\n    ModuleGroup _moduleGroup;\n    void[][] _gcRanges;\n}\n\nshared(bool) conservative;\n\nvoid initSections() nothrow @nogc\n{\n    _sections._moduleGroup = ModuleGroup(getModuleInfos());\n\n    import rt.sections;\n    conservative = !scanDataSegPrecisely();\n\n    if (conservative)\n    {\n        _sections._gcRanges = (cast(void[]*) malloc(2 * (void[]).sizeof))[0..2];\n\n        auto databeg = cast(void*)&_xi_a;\n        auto dataend = cast(void*)_moduleinfo_array.ptr;\n        _sections._gcRanges[0] = databeg[0 .. dataend - databeg];\n\n        // skip module info and CONST segment\n        auto bssbeg = cast(void*)&_edata;\n        auto bssend = cast(void*)&_end;\n        _sections._gcRanges[1] = bssbeg[0 .. bssend - bssbeg];\n    }\n    else\n    {\n        size_t count = &_DPend - &_DPbegin;\n        auto ranges = cast(void[]*) malloc(count * (void[]).sizeof);\n        size_t r = 0;\n        void* prev = null;\n        for (size_t i = 0; i < count; i++)\n        {\n            void* addr = (&_DPbegin)[i];\n            if (prev + (void*).sizeof == addr)\n                ranges[r-1] = ranges[r-1].ptr[0 .. ranges[r-1].length + (void*).sizeof];\n            else\n                ranges[r++] = (cast(void**)addr)[0..1];\n            prev = addr;\n        }\n        _sections._gcRanges = ranges[0..r];\n    }\n}\n\nvoid finiSections() nothrow @nogc\n{\n    free(_sections._gcRanges.ptr);\n}\n\nvoid[] initTLSRanges() nothrow @nogc\n{\n    auto pbeg = cast(void*)&_tlsstart;\n    auto pend = cast(void*)&_tlsend;\n    return pbeg[0 .. pend - pbeg];\n}\n\nvoid finiTLSRanges(void[] rng) nothrow @nogc\n{\n}\n\nvoid scanTLSRanges(void[] rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow\n{\n    if (conservative)\n    {\n        dg(rng.ptr, rng.ptr + rng.length);\n    }\n    else\n    {\n        for (auto p = &_TPbegin; p < &_TPend; )\n        {\n            uint beg = *p++;\n            uint end = beg + cast(uint)((void*).sizeof);\n            while (p < &_TPend && *p == end)\n            {\n                end += (void*).sizeof;\n                p++;\n            }\n            dg(rng.ptr + beg, rng.ptr + end);\n        }\n    }\n}\n\nprivate:\n\n__gshared SectionGroup _sections;\n\n// Windows: this gets initialized by minit.asm\nextern(C) __gshared immutable(ModuleInfo*)[] _moduleinfo_array;\nextern(C) void _minit() nothrow @nogc;\n\nimmutable(ModuleInfo*)[] getModuleInfos() nothrow @nogc\nout (result)\n{\n    foreach (m; result)\n        assert(m !is null);\n}\ndo\n{\n    // _minit directly alters the global _moduleinfo_array\n    _minit();\n    return _moduleinfo_array;\n}\n\nextern(C)\n{\n    extern __gshared\n    {\n        int _xi_a;      // &_xi_a just happens to be start of data segment\n        int _edata;     // &_edata is start of BSS segment\n        int _end;       // &_end is past end of BSS\n\n        void* _DPbegin; // first entry in the array of pointers addresses\n        void* _DPend;   // &_DPend points after last entry of array\n        uint _TPbegin;  // first entry in the array of TLS offsets of pointers\n        uint _TPend;    // &_DPend points after last entry of array\n    }\n\n    extern\n    {\n        int _tlsstart;\n        int _tlsend;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/sections_win64.d",
    "content": "/**\n * Written in the D programming language.\n * This module provides Win32-specific support for sections.\n *\n * Copyright: Copyright Digital Mars 2008 - 2012.\n * License: Distributed under the\n *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).\n *    (See accompanying file LICENSE)\n * Authors:   Walter Bright, Sean Kelly, Martin Nowak\n * Source: $(DRUNTIMESRC rt/_sections_win64.d)\n */\n\nmodule rt.sections_win64;\n\nversion (CRuntime_Microsoft):\n\n// debug = PRINTF;\ndebug(PRINTF) import core.stdc.stdio;\nimport core.stdc.stdlib : malloc, free;\nimport rt.deh, rt.minfo;\n\nstruct SectionGroup\n{\n    static int opApply(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    static int opApplyReverse(scope int delegate(ref SectionGroup) dg)\n    {\n        return dg(_sections);\n    }\n\n    @property immutable(ModuleInfo*)[] modules() const nothrow @nogc\n    {\n        return _moduleGroup.modules;\n    }\n\n    @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc\n    {\n        return _moduleGroup;\n    }\n\n    version (Win64)\n    @property immutable(FuncTable)[] ehTables() const\n    {\n        auto pbeg = cast(immutable(FuncTable)*)&_deh_beg;\n        auto pend = cast(immutable(FuncTable)*)&_deh_end;\n        return pbeg[0 .. pend - pbeg];\n    }\n\n    @property inout(void[])[] gcRanges() inout nothrow @nogc\n    {\n        return _gcRanges[];\n    }\n\nprivate:\n    ModuleGroup _moduleGroup;\n    void[][] _gcRanges;\n}\n\nshared(bool) conservative;\n\nvoid initSections() nothrow @nogc\n{\n    _sections._moduleGroup = ModuleGroup(getModuleInfos());\n\n    // the \".data\" image section includes both object file sections \".data\" and \".bss\"\n    void[] dataSection = findImageSection(\".data\");\n    debug(PRINTF) printf(\"found .data section: [%p,+%llx]\\n\", dataSection.ptr,\n                         cast(ulong)dataSection.length);\n\n    import rt.sections;\n    conservative = !scanDataSegPrecisely();\n\n    if (conservative)\n    {\n        _sections._gcRanges = (cast(void[]*) malloc((void[]).sizeof))[0..1];\n        _sections._gcRanges[0] = dataSection;\n    }\n    else\n    {\n        size_t count = &_DP_end - &_DP_beg;\n        auto ranges = cast(void[]*) malloc(count * (void[]).sizeof);\n        size_t r = 0;\n        void* prev = null;\n        for (size_t i = 0; i < count; i++)\n        {\n            auto off = (&_DP_beg)[i];\n            if (off == 0) // skip zero entries added by incremental linking\n                continue; // assumes there is no D-pointer at the very beginning of .data\n            void* addr = dataSection.ptr + off;\n            debug(PRINTF) printf(\"  scan %p\\n\", addr);\n            // combine consecutive pointers into single range\n            if (prev + (void*).sizeof == addr)\n                ranges[r-1] = ranges[r-1].ptr[0 .. ranges[r-1].length + (void*).sizeof];\n            else\n                ranges[r++] = (cast(void**)addr)[0..1];\n            prev = addr;\n        }\n        _sections._gcRanges = ranges[0..r];\n    }\n}\n\nvoid finiSections() nothrow @nogc\n{\n    .free(cast(void*)_sections.modules.ptr);\n    .free(_sections._gcRanges.ptr);\n}\n\nvoid[] initTLSRanges() nothrow @nogc\n{\n    void* pbeg;\n    void* pend;\n    // with VS2017 15.3.1, the linker no longer puts TLS segments into a\n    //  separate image section. That way _tls_start and _tls_end no\n    //  longer generate offsets into .tls, but DATA.\n    // Use the TEB entry to find the start of TLS instead and read the\n    //  length from the TLS directory\n    version (D_InlineAsm_X86)\n    {\n        asm @nogc nothrow\n        {\n            mov EAX, _tls_index;\n            mov ECX, FS:[0x2C];     // _tls_array\n            mov EAX, [ECX+4*EAX];\n            mov pbeg, EAX;\n            add EAX, [_tls_used+4]; // end\n            sub EAX, [_tls_used+0]; // start\n            mov pend, EAX;\n        }\n    }\n    else version (D_InlineAsm_X86_64)\n    {\n        asm @nogc nothrow\n        {\n            xor RAX, RAX;\n            mov EAX, _tls_index;\n            mov RCX, 0x58;\n            mov RCX, GS:[RCX];      // _tls_array (immediate value causes fixup)\n            mov RAX, [RCX+8*RAX];\n            mov pbeg, RAX;\n            add RAX, [_tls_used+8]; // end\n            sub RAX, [_tls_used+0]; // start\n            mov pend, RAX;\n        }\n    }\n    else\n        static assert(false, \"Architecture not supported.\");\n\n    return pbeg[0 .. pend - pbeg];\n}\n\nvoid finiTLSRanges(void[] rng) nothrow @nogc\n{\n}\n\nvoid scanTLSRanges(void[] rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow\n{\n    if (conservative)\n    {\n        dg(rng.ptr, rng.ptr + rng.length);\n    }\n    else\n    {\n        for (auto p = &_TP_beg; p < &_TP_end; )\n        {\n            uint beg = *p++;\n            uint end = beg + cast(uint)((void*).sizeof);\n            while (p < &_TP_end && *p == end)\n            {\n                end += (void*).sizeof;\n                p++;\n            }\n            dg(rng.ptr + beg, rng.ptr + end);\n        }\n    }\n}\n\nprivate:\n__gshared SectionGroup _sections;\n\nextern(C)\n{\n    extern __gshared void* _minfo_beg;\n    extern __gshared void* _minfo_end;\n}\n\nimmutable(ModuleInfo*)[] getModuleInfos() nothrow @nogc\nout (result)\n{\n    foreach (m; result)\n        assert(m !is null);\n}\ndo\n{\n    auto m = (cast(immutable(ModuleInfo*)*)&_minfo_beg)[1 .. &_minfo_end - &_minfo_beg];\n    /* Because of alignment inserted by the linker, various null pointers\n     * are there. We need to filter them out.\n     */\n    auto p = m.ptr;\n    auto pend = m.ptr + m.length;\n\n    // count non-null pointers\n    size_t cnt;\n    for (; p < pend; ++p)\n    {\n        if (*p !is null) ++cnt;\n    }\n\n    auto result = (cast(immutable(ModuleInfo)**).malloc(cnt * size_t.sizeof))[0 .. cnt];\n\n    p = m.ptr;\n    cnt = 0;\n    for (; p < pend; ++p)\n        if (*p !is null) result[cnt++] = *p;\n\n    return cast(immutable)result;\n}\n\nextern(C)\n{\n    /* Symbols created by the compiler/linker and inserted into the\n     * object file that 'bracket' sections.\n     */\n    extern __gshared\n    {\n        void* __ImageBase;\n\n        void* _deh_beg;\n        void* _deh_end;\n\n        uint _DP_beg;\n        uint _DP_end;\n        uint _TP_beg;\n        uint _TP_end;\n\n        void*[2] _tls_used; // start, end\n        int _tls_index;\n    }\n}\n\n/////////////////////////////////////////////////////////////////////\n\nenum IMAGE_DOS_SIGNATURE = 0x5A4D;      // MZ\n\nstruct IMAGE_DOS_HEADER // DOS .EXE header\n{\n    ushort   e_magic;    // Magic number\n    ushort[29] e_res2;   // Reserved ushorts\n    int      e_lfanew;   // File address of new exe header\n}\n\nstruct IMAGE_FILE_HEADER\n{\n    ushort Machine;\n    ushort NumberOfSections;\n    uint   TimeDateStamp;\n    uint   PointerToSymbolTable;\n    uint   NumberOfSymbols;\n    ushort SizeOfOptionalHeader;\n    ushort Characteristics;\n}\n\nstruct IMAGE_NT_HEADERS\n{\n    uint Signature;\n    IMAGE_FILE_HEADER FileHeader;\n    // optional header follows\n}\n\nstruct IMAGE_SECTION_HEADER\n{\n    char[8] Name;\n    union {\n        uint   PhysicalAddress;\n        uint   VirtualSize;\n    }\n    uint   VirtualAddress;\n    uint   SizeOfRawData;\n    uint   PointerToRawData;\n    uint   PointerToRelocations;\n    uint   PointerToLinenumbers;\n    ushort NumberOfRelocations;\n    ushort NumberOfLinenumbers;\n    uint   Characteristics;\n}\n\nbool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow @nogc\n{\n    if (name[] != section.Name[0 .. name.length])\n        return false;\n    return name.length == 8 || section.Name[name.length] == 0;\n}\n\nvoid[] findImageSection(string name) nothrow @nogc\n{\n    if (name.length > 8) // section name from string table not supported\n        return null;\n    IMAGE_DOS_HEADER* doshdr = cast(IMAGE_DOS_HEADER*) &__ImageBase;\n    if (doshdr.e_magic != IMAGE_DOS_SIGNATURE)\n        return null;\n\n    auto nthdr = cast(IMAGE_NT_HEADERS*)(cast(void*)doshdr + doshdr.e_lfanew);\n    auto sections = cast(IMAGE_SECTION_HEADER*)(cast(void*)nthdr + IMAGE_NT_HEADERS.sizeof + nthdr.FileHeader.SizeOfOptionalHeader);\n    for (ushort i = 0; i < nthdr.FileHeader.NumberOfSections; i++)\n        if (compareSectionName (sections[i], name))\n            return (cast(void*)&__ImageBase + sections[i].VirtualAddress)[0 .. sections[i].VirtualSize];\n\n    return null;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/tlsgc.d",
    "content": "/**\n *\n * Copyright: Copyright Digital Mars 2011 - 2012.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n */\n\n/*          Copyright Digital Mars 2011.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.tlsgc;\n\nimport core.stdc.stdlib;\n\nstatic import rt.lifetime, rt.sections;\n\n/**\n * Per thread record to store thread associated data for garbage collection.\n */\nstruct Data\n{\n    typeof(rt.sections.initTLSRanges()) tlsRanges;\n    rt.lifetime.BlkInfo** blockInfoCache;\n}\n\n/**\n * Initialization hook, called FROM each thread. No assumptions about\n * module initialization state should be made.\n */\nvoid* init() nothrow @nogc\n{\n    auto data = cast(Data*).malloc(Data.sizeof);\n    import core.exception;\n    if ( data is null ) core.exception.onOutOfMemoryError();\n    *data = Data.init;\n\n    // do module specific initialization\n    data.tlsRanges = rt.sections.initTLSRanges();\n    data.blockInfoCache = &rt.lifetime.__blkcache_storage;\n\n    return data;\n}\n\n/**\n * Finalization hook, called FOR each thread. No assumptions about\n * module initialization state should be made.\n */\nvoid destroy(void* data) nothrow @nogc\n{\n    // do module specific finalization\n    rt.sections.finiTLSRanges((cast(Data*)data).tlsRanges);\n\n    .free(data);\n}\n\nalias void delegate(void* pstart, void* pend) nothrow ScanDg;\n\n/**\n * GC scan hook, called FOR each thread. Can be used to scan\n * additional thread local memory.\n */\nvoid scan(void* data, scope ScanDg dg) nothrow\n{\n    // do module specific marking\n    rt.sections.scanTLSRanges((cast(Data*)data).tlsRanges, dg);\n}\n\nalias int delegate(void* addr) nothrow IsMarkedDg;\n\n/**\n * GC sweep hook, called FOR each thread. Can be used to free\n * additional thread local memory or associated data structures. Note\n * that only memory allocated from the GC can have marks.\n */\nvoid processGCMarks(void* data, scope IsMarkedDg dg) nothrow\n{\n    // do module specific sweeping\n    rt.lifetime.processGCMarks(*(cast(Data*)data).blockInfoCache, dg);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_Acdouble.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_Acdouble;\n\nprivate import rt.util.typeinfo;\n\n// cdouble[]\n\nclass TypeInfo_Ar : TypeInfo_Array\n{\n    alias F = cdouble;\n\n    override bool opEquals(Object o) { return TypeInfo.opEquals(o); }\n\n    override string toString() const { return (F[]).stringof; }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        return Array!F.hashOf(*cast(F[]*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(F);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_Acfloat.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_Acfloat;\n\nprivate import rt.util.typeinfo;\n\n// cfloat[]\n\nclass TypeInfo_Aq : TypeInfo_Array\n{\n    alias F = cfloat;\n\n    override bool opEquals(Object o) { return TypeInfo.opEquals(o); }\n\n    override string toString() const { return (F[]).stringof; }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        return Array!F.hashOf(*cast(F[]*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(F);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_Acreal.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_Acreal;\n\nprivate import rt.util.typeinfo;\n\n// creal[]\n\nclass TypeInfo_Ac : TypeInfo_Array\n{\n    alias F = creal;\n\n    override bool opEquals(Object o) { return TypeInfo.opEquals(o); }\n\n    override string toString() const { return (F[]).stringof; }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        return Array!F.hashOf(*cast(F[]*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(F);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_Adouble.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_Adouble;\n\nprivate import rt.util.typeinfo;\n\n// double[]\n\nclass TypeInfo_Ad : TypeInfo_Array\n{\n    alias F = double;\n\n    override bool opEquals(Object o) { return TypeInfo.opEquals(o); }\n\n    override string toString() const { return (F[]).stringof; }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        return Array!F.hashOf(*cast(F[]*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(F);\n    }\n}\n\n// idouble[]\n\nclass TypeInfo_Ap : TypeInfo_Ad\n{\n    alias F = idouble;\n\n    override string toString() const { return (F[]).stringof; }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(F);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_Afloat.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_Afloat;\n\nprivate import rt.util.typeinfo;\n\n// float[]\n\nclass TypeInfo_Af : TypeInfo_Array\n{\n    alias F = float;\n\n    override bool opEquals(Object o) { return TypeInfo.opEquals(o); }\n\n    override string toString() const { return (F[]).stringof; }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        return Array!F.hashOf(*cast(F[]*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(F);\n    }\n}\n\n// ifloat[]\n\nclass TypeInfo_Ao : TypeInfo_Af\n{\n    alias F = ifloat;\n\n    override string toString() const { return (F[]).stringof; }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(F);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_Ag.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_Ag;\n\nprivate import core.stdc.string;\nprivate import core.internal.string;\n\n// byte[]\n\nclass TypeInfo_Ag : TypeInfo_Array\n{\n    override bool opEquals(Object o) { return TypeInfo.opEquals(o); }\n\n    override string toString() const { return \"byte[]\"; }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        const s = *cast(const void[]*)p;\n        return hashOf(s);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        byte[] s1 = *cast(byte[]*)p1;\n        byte[] s2 = *cast(byte[]*)p2;\n\n        return s1.length == s2.length &&\n               memcmp(cast(byte *)s1, cast(byte *)s2, s1.length) == 0;\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        byte[] s1 = *cast(byte[]*)p1;\n        byte[] s2 = *cast(byte[]*)p2;\n        size_t len = s1.length;\n\n        if (s2.length < len)\n            len = s2.length;\n        for (size_t u = 0; u < len; u++)\n        {\n            int result = s1[u] - s2[u];\n            if (result)\n                return result;\n        }\n        if (s1.length < s2.length)\n            return -1;\n        else if (s1.length > s2.length)\n            return 1;\n        return 0;\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(byte);\n    }\n}\n\n\n// ubyte[]\n\nclass TypeInfo_Ah : TypeInfo_Ag\n{\n    override string toString() const { return \"ubyte[]\"; }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        char[] s1 = *cast(char[]*)p1;\n        char[] s2 = *cast(char[]*)p2;\n\n        return dstrcmp(s1, s2);\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(ubyte);\n    }\n}\n\n// void[]\n\nclass TypeInfo_Av : TypeInfo_Ah\n{\n    override string toString() const { return \"void[]\"; }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(void);\n    }\n}\n\n// bool[]\n\nclass TypeInfo_Ab : TypeInfo_Ah\n{\n    override string toString() const { return \"bool[]\"; }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(bool);\n    }\n}\n\n// char[]\n\nclass TypeInfo_Aa : TypeInfo_Ah\n{\n    override string toString() const { return \"char[]\"; }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        char[] s = *cast(char[]*)p;\n        return hashOf(s);\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(char);\n    }\n}\n\n// string\n\nclass TypeInfo_Aya : TypeInfo_Aa\n{\n    override string toString() const { return \"immutable(char)[]\"; }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(immutable(char));\n    }\n}\n\n// const(char)[]\n\nclass TypeInfo_Axa : TypeInfo_Aa\n{\n    override string toString() const { return \"const(char)[]\"; }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(const(char));\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_Aint.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_Aint;\n\nprivate import core.stdc.string;\n\nextern (C) void[] _adSort(void[] a, TypeInfo ti);\n\n// int[]\n\nclass TypeInfo_Ai : TypeInfo_Array\n{\n    override bool opEquals(Object o) { return TypeInfo.opEquals(o); }\n\n    override string toString() const { return \"int[]\"; }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        // Hash as if unsigned.\n        const s = *cast(const uint[]*)p;\n        return hashOf(s);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        int[] s1 = *cast(int[]*)p1;\n        int[] s2 = *cast(int[]*)p2;\n\n        return s1.length == s2.length &&\n               memcmp(cast(void *)s1, cast(void *)s2, s1.length * int.sizeof) == 0;\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        int[] s1 = *cast(int[]*)p1;\n        int[] s2 = *cast(int[]*)p2;\n        size_t len = s1.length;\n\n        if (s2.length < len)\n            len = s2.length;\n        for (size_t u = 0; u < len; u++)\n        {\n            if (s1[u] < s2[u])\n                return -1;\n            else if (s1[u] > s2[u])\n                return 1;\n        }\n        if (s1.length < s2.length)\n            return -1;\n        else if (s1.length > s2.length)\n            return 1;\n        return 0;\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(int);\n    }\n}\n\nunittest\n{\n    int[][] a = [[5,3,8,7], [2,5,3,8,7]];\n    _adSort(*cast(void[]*)&a, typeid(a[0]));\n    assert(a == [[2,5,3,8,7], [5,3,8,7]]);\n\n    a = [[5,3,8,7], [5,3,8]];\n    _adSort(*cast(void[]*)&a, typeid(a[0]));\n    assert(a == [[5,3,8], [5,3,8,7]]);\n}\n\nunittest\n{\n    // Issue 13073: original code uses int subtraction which is susceptible to\n    // integer overflow, causing the following case to fail.\n    int[] a = [int.max, int.max];\n    int[] b = [int.min, int.min];\n    assert(a > b);\n    assert(b < a);\n}\n\n// uint[]\n\nclass TypeInfo_Ak : TypeInfo_Ai\n{\n    override string toString() const { return \"uint[]\"; }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        uint[] s1 = *cast(uint[]*)p1;\n        uint[] s2 = *cast(uint[]*)p2;\n        size_t len = s1.length;\n\n        if (s2.length < len)\n            len = s2.length;\n        for (size_t u = 0; u < len; u++)\n        {\n            if (s1[u] < s2[u])\n                return -1;\n            else if (s1[u] > s2[u])\n                return 1;\n        }\n        if (s1.length < s2.length)\n            return -1;\n        else if (s1.length > s2.length)\n            return 1;\n        return 0;\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(uint);\n    }\n}\n\nunittest\n{\n    // Original test case from issue 13073\n    uint x = 0x22_DF_FF_FF;\n    uint y = 0xA2_DF_FF_FF;\n    assert(!(x < y && y < x));\n    uint[] a = [x];\n    uint[] b = [y];\n    assert(!(a < b && b < a)); // Original failing case\n    uint[1] a1 = [x];\n    uint[1] b1 = [y];\n    assert(!(a1 < b1 && b1 < a1)); // Original failing case\n}\n\n// dchar[]\n\nclass TypeInfo_Aw : TypeInfo_Ak\n{\n    override string toString() const { return \"dchar[]\"; }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(dchar);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_Along.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_Along;\n\nprivate import core.stdc.string;\n\n// long[]\n\nclass TypeInfo_Al : TypeInfo_Array\n{\n    override bool opEquals(Object o) { return TypeInfo.opEquals(o); }\n\n    override string toString() const { return \"long[]\"; }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        // Hash as if unsigned.\n        const s = *cast(const ulong[]*)p;\n        return hashOf(s);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        long[] s1 = *cast(long[]*)p1;\n        long[] s2 = *cast(long[]*)p2;\n\n        return s1.length == s2.length &&\n               memcmp(cast(void *)s1, cast(void *)s2, s1.length * long.sizeof) == 0;\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        long[] s1 = *cast(long[]*)p1;\n        long[] s2 = *cast(long[]*)p2;\n        size_t len = s1.length;\n\n        if (s2.length < len)\n            len = s2.length;\n        for (size_t u = 0; u < len; u++)\n        {\n            if (s1[u] < s2[u])\n                return -1;\n            else if (s1[u] > s2[u])\n                return 1;\n        }\n        if (s1.length < s2.length)\n            return -1;\n        else if (s1.length > s2.length)\n            return 1;\n        return 0;\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(long);\n    }\n}\n\n\n// ulong[]\n\nclass TypeInfo_Am : TypeInfo_Al\n{\n    override string toString() const { return \"ulong[]\"; }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        ulong[] s1 = *cast(ulong[]*)p1;\n        ulong[] s2 = *cast(ulong[]*)p2;\n        size_t len = s1.length;\n\n        if (s2.length < len)\n            len = s2.length;\n        for (size_t u = 0; u < len; u++)\n        {\n            if (s1[u] < s2[u])\n                return -1;\n            else if (s1[u] > s2[u])\n                return 1;\n        }\n        if (s1.length < s2.length)\n            return -1;\n        else if (s1.length > s2.length)\n            return 1;\n        return 0;\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(ulong);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_Areal.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_Areal;\n\nprivate import rt.util.typeinfo;\n\n// real[]\n\nclass TypeInfo_Ae : TypeInfo_Array\n{\n    alias F = real;\n\n    override bool opEquals(Object o) { return TypeInfo.opEquals(o); }\n\n    override string toString() const { return (F[]).stringof; }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        return Array!F.hashOf(*cast(F[]*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(F);\n    }\n}\n\n// ireal[]\n\nclass TypeInfo_Aj : TypeInfo_Ae\n{\n    alias F = ireal;\n\n    override string toString() const { return (F[]).stringof; }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(F);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_Ashort.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_Ashort;\n\nprivate import core.stdc.string;\n\n// short[]\n\nclass TypeInfo_As : TypeInfo_Array\n{\n    override bool opEquals(Object o) { return TypeInfo.opEquals(o); }\n\n    override string toString() const { return \"short[]\"; }\n\n    override size_t getHash(scope const void* p) @trusted const\n    {\n        // Hash as if unsigned.\n        const s = *cast(const ushort[]*)p;\n        return hashOf(s);\n    }\n\n    override bool equals(in void* p1, in void* p2) const\n    {\n        short[] s1 = *cast(short[]*)p1;\n        short[] s2 = *cast(short[]*)p2;\n\n        return s1.length == s2.length &&\n               memcmp(cast(void *)s1, cast(void *)s2, s1.length * short.sizeof) == 0;\n    }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        short[] s1 = *cast(short[]*)p1;\n        short[] s2 = *cast(short[]*)p2;\n        size_t len = s1.length;\n\n        if (s2.length < len)\n            len = s2.length;\n        for (size_t u = 0; u < len; u++)\n        {\n            int result = s1[u] - s2[u];\n            if (result)\n                return result;\n        }\n        if (s1.length < s2.length)\n            return -1;\n        else if (s1.length > s2.length)\n            return 1;\n        return 0;\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(short);\n    }\n}\n\n\n// ushort[]\n\nclass TypeInfo_At : TypeInfo_As\n{\n    override string toString() const { return \"ushort[]\"; }\n\n    override int compare(in void* p1, in void* p2) const\n    {\n        ushort[] s1 = *cast(ushort[]*)p1;\n        ushort[] s2 = *cast(ushort[]*)p2;\n        size_t len = s1.length;\n\n        if (s2.length < len)\n            len = s2.length;\n        for (size_t u = 0; u < len; u++)\n        {\n            int result = s1[u] - s2[u];\n            if (result)\n                return result;\n        }\n        if (s1.length < s2.length)\n            return -1;\n        else if (s1.length > s2.length)\n            return 1;\n        return 0;\n    }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(ushort);\n    }\n}\n\n// wchar[]\n\nclass TypeInfo_Au : TypeInfo_At\n{\n    override string toString() const { return \"wchar[]\"; }\n\n    override @property inout(TypeInfo) next() inout\n    {\n        return cast(inout)typeid(wchar);\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_C.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_C;\n\n// Object\n\nclass TypeInfo_C : TypeInfo\n{\n    @trusted:\n    const:\n    //pure:\n    //nothrow:\n\n    override size_t getHash(scope const void* p)\n    {\n        Object o = *cast(Object*)p;\n        return o ? o.toHash() : 0;\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        Object o1 = *cast(Object*)p1;\n        Object o2 = *cast(Object*)p2;\n\n        return o1 == o2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        Object o1 = *cast(Object*)p1;\n        Object o2 = *cast(Object*)p2;\n        int c = 0;\n\n        // Regard null references as always being \"less than\"\n        if (!(o1 is o2))\n        {\n            if (o1)\n            {\n                if (!o2)\n                    c = 1;\n                else\n                    c = o1.opCmp(o2);\n            }\n            else\n                c = -1;\n        }\n        return c;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return Object.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. Object.sizeof];\n    }\n\n    override @property uint flags() nothrow pure\n    {\n        return 1;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_byte.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_byte;\n\n// byte\n\nclass TypeInfo_g : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"byte\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        // Hash as if unsigned.\n        return *cast(const ubyte *)p;\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(byte *)p1 == *cast(byte *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        return *cast(byte *)p1 - *cast(byte *)p2;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return byte.sizeof;\n    }\n\n    override const(void)[] initializer() @trusted\n    {\n        return (cast(void *)null)[0 .. byte.sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        byte t;\n\n        t = *cast(byte *)p1;\n        *cast(byte *)p1 = *cast(byte *)p2;\n        *cast(byte *)p2 = t;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_cdouble.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_cdouble;\n\nprivate import rt.util.typeinfo;\n\n// cdouble\n\nclass TypeInfo_r : TypeInfo\n{\n  pure:\n  nothrow:\n  @safe:\n\n    alias F = cdouble;\n\n    override string toString() const { return F.stringof; }\n\n    override size_t getHash(scope const void* p) const @trusted\n    {\n        return Floating!F.hashOf(*cast(F*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override @property size_t tsize() const\n    {\n        return F.sizeof;\n    }\n\n    override void swap(void *p1, void *p2) const @trusted\n    {\n        F t = *cast(F*)p1;\n        *cast(F*)p1 = *cast(F*)p2;\n        *cast(F*)p2 = t;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        static immutable F r;\n        return (&r)[0 .. 1];\n    }\n\n    override @property size_t talign() const\n    {\n        return F.alignof;\n    }\n\n    version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n    {\n        arg1 = typeid(double);\n        arg2 = typeid(double);\n        return 0;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_cent.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2015.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2015.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_cent;\n\nstatic if (is(cent)):\n\n// cent\n\nclass TypeInfo_zi : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"cent\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        // Hash as if unsigned.\n        return hashOf(*cast(const ucent*) p);\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(cent *)p1 == *cast(cent *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        if (*cast(cent *)p1 < *cast(cent *)p2)\n            return -1;\n        else if (*cast(cent *)p1 > *cast(cent *)p2)\n            return 1;\n        return 0;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return cent.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. cent.sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        cent t;\n\n        t = *cast(cent *)p1;\n        *cast(cent *)p1 = *cast(cent *)p2;\n        *cast(cent *)p2 = t;\n    }\n\n    override @property size_t talign() nothrow pure\n    {\n        return cent.alignof;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_cfloat.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_cfloat;\n\nprivate import rt.util.typeinfo;\n\n// cfloat\n\nclass TypeInfo_q : TypeInfo\n{\n  pure:\n  nothrow:\n  @safe:\n\n    alias F = cfloat;\n\n    override string toString() const { return F.stringof; }\n\n    override size_t getHash(scope const void* p) const @trusted\n    {\n        return Floating!F.hashOf(*cast(F*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override @property size_t tsize() const\n    {\n        return F.sizeof;\n    }\n\n    override void swap(void *p1, void *p2) const @trusted\n    {\n        F t = *cast(F*)p1;\n        *cast(F*)p1 = *cast(F*)p2;\n        *cast(F*)p2 = t;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        static immutable F r;\n        return (&r)[0 .. 1];\n    }\n\n    override @property size_t talign() const\n    {\n        return F.alignof;\n    }\n\n    version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n    {\n        arg1 = typeid(double);\n        return 0;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_char.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_char;\n\n// char\n\nclass TypeInfo_a : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"char\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        return *cast(const char *)p;\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(char *)p1 == *cast(char *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        return *cast(char *)p1 - *cast(char *)p2;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return char.sizeof;\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        char t;\n\n        t = *cast(char *)p1;\n        *cast(char *)p1 = *cast(char *)p2;\n        *cast(char *)p2 = t;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        static immutable char c;\n\n        return (&c)[0 .. 1];\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_creal.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_creal;\n\nprivate import rt.util.typeinfo;\n\n// creal\n\nclass TypeInfo_c : TypeInfo\n{\n  pure:\n  nothrow:\n  @safe:\n\n    alias F = creal;\n\n    override string toString() const { return F.stringof; }\n\n    override size_t getHash(scope const void* p) const @trusted\n    {\n        return Floating!F.hashOf(*cast(F*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override @property size_t tsize() const\n    {\n        return F.sizeof;\n    }\n\n    override void swap(void *p1, void *p2) const @trusted\n    {\n        F t = *cast(F*)p1;\n        *cast(F*)p1 = *cast(F*)p2;\n        *cast(F*)p2 = t;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        static immutable F r;\n        return (&r)[0 .. 1];\n    }\n\n    override @property size_t talign() const\n    {\n        return F.alignof;\n    }\n\n    version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)\n    {\n        arg1 = typeid(real);\n        arg2 = typeid(real);\n        return 0;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_dchar.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_dchar;\n\n// dchar\n\nclass TypeInfo_w : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"dchar\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        return *cast(const dchar *)p;\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(dchar *)p1 == *cast(dchar *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        return *cast(dchar *)p1 - *cast(dchar *)p2;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return dchar.sizeof;\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        dchar t;\n\n        t = *cast(dchar *)p1;\n        *cast(dchar *)p1 = *cast(dchar *)p2;\n        *cast(dchar *)p2 = t;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        static immutable dchar c;\n\n        return (&c)[0 .. 1];\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_delegate.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_delegate;\n\n\n// delegate\n\nalias void delegate(int) dg;\n\nclass TypeInfo_D : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override size_t getHash(scope const void* p)\n    {\n        return hashOf(*cast(dg*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(dg *)p1 == *cast(dg *)p2;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return dg.sizeof;\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        dg t;\n\n        t = *cast(dg *)p1;\n        *cast(dg *)p1 = *cast(dg *)p2;\n        *cast(dg *)p2 = t;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        static immutable dg d;\n\n        return (cast(void *)null)[0 .. dg.sizeof];\n    }\n\n    override @property uint flags() nothrow pure\n    {\n        return 1;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_double.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_double;\n\nprivate import rt.util.typeinfo;\n\n// double\n\nclass TypeInfo_d : TypeInfo\n{\n  pure:\n  nothrow:\n  @safe:\n\n    alias F = double;\n\n    override string toString() const { return F.stringof; }\n\n    override size_t getHash(scope const void* p) const @trusted\n    {\n        return Floating!F.hashOf(*cast(F*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override @property size_t tsize() const\n    {\n        return F.sizeof;\n    }\n\n    override void swap(void *p1, void *p2) const @trusted\n    {\n        F t = *cast(F*)p1;\n        *cast(F*)p1 = *cast(F*)p2;\n        *cast(F*)p2 = t;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        static immutable F r;\n        return (&r)[0 .. 1];\n    }\n\n    override @property size_t talign() const\n    {\n        return F.alignof;\n    }\n\n    version (Windows)\n    {\n    }\n    else version (X86_64)\n    {\n        // 2 means arg to function is passed in XMM registers\n        override @property uint flags() const { return 2; }\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_float.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_float;\n\nprivate import rt.util.typeinfo;\n\n// float\n\nclass TypeInfo_f : TypeInfo\n{\n  pure:\n  nothrow:\n  @safe:\n\n    alias F = float;\n\n    override string toString() const { return F.stringof; }\n\n    override size_t getHash(scope const void* p) const @trusted\n    {\n        return Floating!F.hashOf(*cast(F*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override @property size_t tsize() const\n    {\n        return F.sizeof;\n    }\n\n    override void swap(void *p1, void *p2) const @trusted\n    {\n        F t = *cast(F*)p1;\n        *cast(F*)p1 = *cast(F*)p2;\n        *cast(F*)p2 = t;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        static immutable F r;\n        return (&r)[0 .. 1];\n    }\n\n    version (Windows)\n    {\n    }\n    else version (X86_64)\n    {\n        // 2 means arg to function is passed in XMM registers\n        override @property uint flags() const { return 2; }\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_idouble.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_idouble;\n\nprivate import rt.typeinfo.ti_double;\n\n// idouble\n\nclass TypeInfo_p : TypeInfo_d\n{\n  pure:\n  nothrow:\n  @safe:\n\n    override string toString() const { return idouble.stringof; }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_ifloat.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_ifloat;\n\nprivate import rt.typeinfo.ti_float;\n\n// ifloat\n\nclass TypeInfo_o : TypeInfo_f\n{\n  pure:\n  nothrow:\n  @safe:\n\n    override string toString() const { return ifloat.stringof; }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_int.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_int;\n\n// int\n\nclass TypeInfo_i : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"int\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        // Hash as if unsigned.\n        return *cast(const uint *)p;\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(uint *)p1 == *cast(uint *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        if (*cast(int*) p1 < *cast(int*) p2)\n            return -1;\n        else if (*cast(int*) p1 > *cast(int*) p2)\n            return 1;\n        return 0;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return int.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. int.sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        int t;\n\n        t = *cast(int *)p1;\n        *cast(int *)p1 = *cast(int *)p2;\n        *cast(int *)p2 = t;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_ireal.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_ireal;\n\nprivate import rt.typeinfo.ti_real;\n\n// ireal\n\nclass TypeInfo_j : TypeInfo_e\n{\n  pure:\n  nothrow:\n  @safe:\n\n    override string toString() const { return ireal.stringof; }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_long.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_long;\n\n// long\n\nclass TypeInfo_l : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"long\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        // Hash as if unsigned.\n        static if (ulong.sizeof <= size_t.sizeof)\n            return *cast(const ulong*)p;\n        else\n            return hashOf(*cast(const ulong*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(long *)p1 == *cast(long *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        if (*cast(long *)p1 < *cast(long *)p2)\n            return -1;\n        else if (*cast(long *)p1 > *cast(long *)p2)\n            return 1;\n        return 0;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return long.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. long.sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        long t;\n\n        t = *cast(long *)p1;\n        *cast(long *)p1 = *cast(long *)p2;\n        *cast(long *)p2 = t;\n    }\n\n    override @property size_t talign() nothrow pure\n    {\n        return long.alignof;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_n.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2016.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Kenji Hara\n */\n\n/*          Copyright Digital Mars 2016.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_n;\n\n// typeof(null)\n\nclass TypeInfo_n : TypeInfo\n{\n    override string toString() const @safe { return \"typeof(null)\"; }\n\n    override size_t getHash(scope const void* p) const\n    {\n        return 0;\n    }\n\n    override bool equals(in void* p1, in void* p2) const @trusted\n    {\n        //return *cast(typeof(null)*)p1 is *cast(typeof(null)*)p2;\n        return true;\n    }\n\n    override int compare(in void* p1, in void* p2) const @trusted\n    {\n        //if (*cast(int*) p1 < *cast(int*) p2)\n        //    return -1;\n        //else if (*cast(int*) p1 > *cast(int*) p2)\n        //    return 1;\n        return 0;\n    }\n\n    override @property size_t tsize() const\n    {\n        return typeof(null).sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void*)null)[0 .. typeof(null).sizeof];\n    }\n\n    override void swap(void *p1, void *p2) const @trusted\n    {\n        //auto t = *cast(typeof(null)*)p1;\n        //*cast(typeof(null)*)p1 = *cast(typeof(null)*)p2;\n        //*cast(typeof(null)*)p2 = t;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_ptr.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_ptr;\n\n// internal typeinfo for any pointer type\n// please keep in sync with TypeInfo_Pointer\n\nclass TypeInfo_P : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override size_t getHash(scope const void* p)\n    {\n        size_t addr = cast(size_t) *cast(const void**)p;\n        return addr ^ (addr >> 4);\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(void**)p1 == *cast(void**)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        if (*cast(void**)p1 < *cast(void**)p2)\n            return -1;\n        else if (*cast(void**)p1 > *cast(void**)p2)\n            return 1;\n        else\n            return 0;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return (void*).sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. (void*).sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        void* tmp = *cast(void**)p1;\n        *cast(void**)p1 = *cast(void**)p2;\n        *cast(void**)p2 = tmp;\n    }\n\n    override @property uint flags() nothrow pure const { return 1; }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_real.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_real;\n\nprivate import rt.util.typeinfo;\n\n// real\n\nclass TypeInfo_e : TypeInfo\n{\n  pure:\n  nothrow:\n  @safe:\n\n    alias F = real;\n\n    override string toString() const { return F.stringof; }\n\n    override size_t getHash(scope const void* p) const @trusted\n    {\n        return Floating!F.hashOf(*cast(F*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override int compare(in void* p1, in void* p2) const @trusted\n    {\n        return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);\n    }\n\n    override @property size_t tsize() const\n    {\n        return F.sizeof;\n    }\n\n    override void swap(void *p1, void *p2) const @trusted\n    {\n        F t = *cast(F*)p1;\n        *cast(F*)p1 = *cast(F*)p2;\n        *cast(F*)p2 = t;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        static immutable F r;\n        return (&r)[0 .. 1];\n    }\n\n    override @property size_t talign() const\n    {\n        return F.alignof;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_short.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_short;\n\n// short\n\nclass TypeInfo_s : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"short\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        // Hash as if unsigned.\n        return *cast(const ushort *)p;\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(short *)p1 == *cast(short *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        return *cast(short *)p1 - *cast(short *)p2;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return short.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. short.sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        short t;\n\n        t = *cast(short *)p1;\n        *cast(short *)p1 = *cast(short *)p2;\n        *cast(short *)p2 = t;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_ubyte.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_ubyte;\n\n// ubyte\n\nclass TypeInfo_h : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"ubyte\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        return *cast(const ubyte *)p;\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(ubyte *)p1 == *cast(ubyte *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        return *cast(ubyte *)p1 - *cast(ubyte *)p2;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return ubyte.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. ubyte.sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        ubyte t;\n\n        t = *cast(ubyte *)p1;\n        *cast(ubyte *)p1 = *cast(ubyte *)p2;\n        *cast(ubyte *)p2 = t;\n    }\n}\n\nclass TypeInfo_b : TypeInfo_h\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"bool\"; }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_ucent.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2015.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2015.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_ucent;\n\nstatic if (is(ucent)):\n\n// ucent\n\nclass TypeInfo_zk : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"ucent\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        return hashOf(*cast(const ucent*) p);\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(ucent *)p1 == *cast(ucent *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        if (*cast(ucent *)p1 < *cast(ucent *)p2)\n            return -1;\n        else if (*cast(ucent *)p1 > *cast(ucent *)p2)\n            return 1;\n        return 0;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return ucent.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. ucent.sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        ucent t;\n\n        t = *cast(ucent *)p1;\n        *cast(ucent *)p1 = *cast(ucent *)p2;\n        *cast(ucent *)p2 = t;\n    }\n\n    override @property size_t talign() nothrow pure\n    {\n        return ucent.alignof;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_uint.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_uint;\n\n// uint\n\nclass TypeInfo_k : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"uint\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        return *cast(const uint *)p;\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(uint *)p1 == *cast(uint *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        if (*cast(uint*) p1 < *cast(uint*) p2)\n            return -1;\n        else if (*cast(uint*) p1 > *cast(uint*) p2)\n            return 1;\n        return 0;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return uint.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. uint.sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        int t;\n\n        t = *cast(uint *)p1;\n        *cast(uint *)p1 = *cast(uint *)p2;\n        *cast(uint *)p2 = t;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_ulong.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_ulong;\n\n\n// ulong\n\nclass TypeInfo_m : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"ulong\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        static if (ulong.sizeof <= size_t.sizeof)\n            return *cast(const ulong*)p;\n        else\n            return hashOf(*cast(const ulong*)p);\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(ulong *)p1 == *cast(ulong *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        if (*cast(ulong *)p1 < *cast(ulong *)p2)\n            return -1;\n        else if (*cast(ulong *)p1 > *cast(ulong *)p2)\n            return 1;\n        return 0;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return ulong.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. ulong.sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        ulong t;\n\n        t = *cast(ulong *)p1;\n        *cast(ulong *)p1 = *cast(ulong *)p2;\n        *cast(ulong *)p2 = t;\n    }\n\n    override @property size_t talign() nothrow pure\n    {\n        return ulong.alignof;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_ushort.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_ushort;\n\n// ushort\n\nclass TypeInfo_t : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"ushort\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        return *cast(const ushort *)p;\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(ushort *)p1 == *cast(ushort *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        return *cast(ushort *)p1 - *cast(ushort *)p2;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return ushort.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. ushort.sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        ushort t;\n\n        t = *cast(ushort *)p1;\n        *cast(ushort *)p1 = *cast(ushort *)p2;\n        *cast(ushort *)p2 = t;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_void.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_void;\n\n// void\n\nclass TypeInfo_v : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() const pure nothrow @safe { return \"void\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        assert(0);\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(byte *)p1 == *cast(byte *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        return *cast(byte *)p1 - *cast(byte *)p2;\n    }\n\n    override @property size_t tsize() nothrow pure\n    {\n        return void.sizeof;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        return (cast(void *)null)[0 .. void.sizeof];\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        byte t;\n\n        t = *cast(byte *)p1;\n        *cast(byte *)p1 = *cast(byte *)p2;\n        *cast(byte *)p2 = t;\n    }\n\n    override @property uint flags() nothrow pure\n    {\n        return 1;\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/typeinfo/ti_wchar.d",
    "content": "/**\n * TypeInfo support code.\n *\n * Copyright: Copyright Digital Mars 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright\n */\n\n/*          Copyright Digital Mars 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule rt.typeinfo.ti_wchar;\n\n// wchar\n\nclass TypeInfo_u : TypeInfo\n{\n    @trusted:\n    const:\n    pure:\n    nothrow:\n\n    override string toString() { return \"wchar\"; }\n\n    override size_t getHash(scope const void* p)\n    {\n        return *cast(const wchar *)p;\n    }\n\n    override bool equals(in void* p1, in void* p2)\n    {\n        return *cast(wchar *)p1 == *cast(wchar *)p2;\n    }\n\n    override int compare(in void* p1, in void* p2)\n    {\n        return *cast(wchar *)p1 - *cast(wchar *)p2;\n    }\n\n    override @property size_t tsize()\n    {\n        return wchar.sizeof;\n    }\n\n    override void swap(void *p1, void *p2)\n    {\n        wchar t;\n\n        t = *cast(wchar *)p1;\n        *cast(wchar *)p1 = *cast(wchar *)p2;\n        *cast(wchar *)p2 = t;\n    }\n\n    override const(void)[] initializer() const @trusted\n    {\n        static immutable wchar c;\n\n        return (&c)[0 .. 1];\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/util/array.d",
    "content": "/**\nArray utilities.\n\nCopyright: Denis Shelomovskij 2013\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors: Denis Shelomovskij\nSource: $(DRUNTIMESRC rt/util/_array.d)\n*/\nmodule rt.util.array;\n\n\nimport core.internal.string;\nimport core.stdc.stdint;\n\n\n@safe /* pure dmd @@@BUG11461@@@ */ nothrow:\n\nvoid enforceTypedArraysConformable(T)(const char[] action,\n    const T[] a1, const T[] a2, in bool allowOverlap = false)\n{\n    _enforceSameLength(action, a1.length, a2.length);\n    if (!allowOverlap)\n        _enforceNoOverlap(action, arrayToPtr(a1), arrayToPtr(a2), T.sizeof * a1.length);\n}\n\nvoid enforceRawArraysConformable(const char[] action, in size_t elementSize,\n    const void[] a1, const void[] a2, in bool allowOverlap = false)\n{\n    _enforceSameLength(action, a1.length, a2.length);\n    if (!allowOverlap)\n        _enforceNoOverlap(action, arrayToPtr(a1), arrayToPtr(a2), elementSize * a1.length);\n}\n\nprivate void _enforceSameLength(const char[] action,\n    in size_t length1, in size_t length2)\n{\n    if (length1 == length2)\n        return;\n\n    UnsignedStringBuf tmpBuff = void;\n    string msg = \"Array lengths don't match for \";\n    msg ~= action;\n    msg ~= \": \";\n    msg ~= length1.unsignedToTempString(tmpBuff, 10);\n    msg ~= \" != \";\n    msg ~= length2.unsignedToTempString(tmpBuff, 10);\n    throw new Error(msg);\n}\n\nprivate void _enforceNoOverlap(const char[] action,\n    uintptr_t ptr1, uintptr_t ptr2, in size_t bytes)\n{\n    const d = ptr1 > ptr2 ? ptr1 - ptr2 : ptr2 - ptr1;\n    if (d >= bytes)\n        return;\n    const overlappedBytes = bytes - d;\n\n    UnsignedStringBuf tmpBuff = void;\n    string msg = \"Overlapping arrays in \";\n    msg ~= action;\n    msg ~= \": \";\n    msg ~= overlappedBytes.unsignedToTempString(tmpBuff, 10);\n    msg ~= \" byte(s) overlap of \";\n    msg ~= bytes.unsignedToTempString(tmpBuff, 10);\n    throw new Error(msg);\n}\n\nprivate uintptr_t arrayToPtr(const void[] array) @trusted\n{\n    // Ok because the user will never dereference the pointer\n    return cast(uintptr_t)array.ptr;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/util/container/array.d",
    "content": "/**\n * Array container for internal usage.\n *\n * Copyright: Copyright Martin Nowak 2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n */\nmodule rt.util.container.array;\n\nstatic import common = rt.util.container.common;\n\nimport core.exception : onOutOfMemoryErrorNoGC;\n\nstruct Array(T)\n{\nnothrow:\n    @disable this(this);\n\n    ~this()\n    {\n        reset();\n    }\n\n    void reset()\n    {\n        length = 0;\n    }\n\n    @property size_t length() const\n    {\n        return _length;\n    }\n\n    @property void length(size_t nlength)\n    {\n        import core.checkedint : mulu;\n\n        bool overflow = false;\n        size_t reqsize = mulu(T.sizeof, nlength, overflow);\n        if (!overflow)\n        {\n            if (nlength < _length)\n                foreach (ref val; _ptr[nlength .. _length]) common.destroy(val);\n            _ptr = cast(T*)common.xrealloc(_ptr, reqsize);\n            if (nlength > _length)\n                foreach (ref val; _ptr[_length .. nlength]) common.initialize(val);\n            _length = nlength;\n        }\n        else\n            onOutOfMemoryErrorNoGC();\n\n    }\n\n    @property bool empty() const\n    {\n        return !length;\n    }\n\n    @property ref inout(T) front() inout\n    in { assert(!empty); }\n    do\n    {\n        return _ptr[0];\n    }\n\n    @property ref inout(T) back() inout\n    in { assert(!empty); }\n    do\n    {\n        return _ptr[_length - 1];\n    }\n\n    ref inout(T) opIndex(size_t idx) inout\n    in { assert(idx < length); }\n    do\n    {\n        return _ptr[idx];\n    }\n\n    inout(T)[] opSlice() inout\n    {\n        return _ptr[0 .. _length];\n    }\n\n    inout(T)[] opSlice(size_t a, size_t b) inout\n    in { assert(a < b && b <= length); }\n    do\n    {\n        return _ptr[a .. b];\n    }\n\n    alias length opDollar;\n\n    void insertBack()(auto ref T val)\n    {\n        import core.checkedint : addu;\n\n        bool overflow = false;\n        size_t newlength = addu(length, 1, overflow);\n        if (!overflow)\n        {\n            length = newlength;\n            back = val;\n        }\n        else\n            onOutOfMemoryErrorNoGC();\n    }\n\n    void popBack()\n    {\n        length = length - 1;\n    }\n\n    void remove(size_t idx)\n    in { assert(idx < length); }\n    do\n    {\n        foreach (i; idx .. length - 1)\n            _ptr[i] = _ptr[i+1];\n        popBack();\n    }\n\n    void swap(ref Array other)\n    {\n        auto ptr = _ptr;\n        _ptr = other._ptr;\n        other._ptr = ptr;\n        immutable len = _length;\n        _length = other._length;\n        other._length = len;\n    }\n\n    invariant\n    {\n        assert(!_ptr == !_length);\n    }\n\nprivate:\n    T* _ptr;\n    size_t _length;\n}\n\nunittest\n{\n    Array!size_t ary;\n\n    assert(ary[] == []);\n    ary.insertBack(5);\n    assert(ary[] == [5]);\n    assert(ary[$-1] == 5);\n    ary.popBack();\n    assert(ary[] == []);\n    ary.insertBack(0);\n    ary.insertBack(1);\n    assert(ary[] == [0, 1]);\n    assert(ary[0 .. 1] == [0]);\n    assert(ary[1 .. 2] == [1]);\n    assert(ary[$ - 2 .. $] == [0, 1]);\n    size_t idx;\n    foreach (val; ary) assert(idx++ == val);\n    foreach_reverse (val; ary) assert(--idx == val);\n    foreach (i, val; ary) assert(i == val);\n    foreach_reverse (i, val; ary) assert(i == val);\n\n    ary.insertBack(2);\n    ary.remove(1);\n    assert(ary[] == [0, 2]);\n\n    assert(!ary.empty);\n    ary.reset();\n    assert(ary.empty);\n    ary.insertBack(0);\n    assert(!ary.empty);\n    destroy(ary);\n    assert(ary.empty);\n\n    // not copyable\n    static assert(!__traits(compiles, { Array!size_t ary2 = ary; }));\n    Array!size_t ary2;\n    static assert(!__traits(compiles, ary = ary2));\n    static void foo(Array!size_t copy) {}\n    static assert(!__traits(compiles, foo(ary)));\n\n    ary2.insertBack(0);\n    assert(ary.empty);\n    assert(ary2[] == [0]);\n    ary.swap(ary2);\n    assert(ary[] == [0]);\n    assert(ary2.empty);\n}\n\nunittest\n{\n    alias RC = common.RC;\n    Array!RC ary;\n\n    size_t cnt;\n    assert(cnt == 0);\n    ary.insertBack(RC(&cnt));\n    assert(cnt == 1);\n    ary.insertBack(RC(&cnt));\n    assert(cnt == 2);\n    ary.back = ary.front;\n    assert(cnt == 2);\n    ary.popBack();\n    assert(cnt == 1);\n    ary.popBack();\n    assert(cnt == 0);\n}\n\nunittest\n{\n    import core.exception;\n    try\n    {\n        // Overflow ary.length.\n        auto ary = Array!size_t(cast(size_t*)0xdeadbeef, -1);\n        ary.insertBack(0);\n    }\n    catch (OutOfMemoryError)\n    {\n    }\n    try\n    {\n        // Overflow requested memory size for common.xrealloc().\n        auto ary = Array!size_t(cast(size_t*)0xdeadbeef, -2);\n        ary.insertBack(0);\n    }\n    catch (OutOfMemoryError)\n    {\n    }\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/util/container/common.d",
    "content": "/**\n * Common code for writing containers.\n *\n * Copyright: Copyright Martin Nowak 2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n */\nmodule rt.util.container.common;\n\nimport core.stdc.stdlib : malloc, realloc;\npublic import core.stdc.stdlib : free;\nimport core.internal.traits : dtorIsNothrow;\nnothrow:\n\nvoid* xrealloc(void* ptr, size_t sz) nothrow @nogc\n{\n    import core.exception;\n\n    if (!sz) { .free(ptr); return null; }\n    if (auto nptr = .realloc(ptr, sz)) return nptr;\n    .free(ptr); onOutOfMemoryErrorNoGC();\n    assert(0);\n}\n\nvoid* xmalloc(size_t sz) nothrow @nogc\n{\n    import core.exception;\n    if (auto nptr = .malloc(sz))\n        return nptr;\n    onOutOfMemoryErrorNoGC();\n    assert(0);\n}\n\nvoid destroy(T)(ref T t) if (is(T == struct) && dtorIsNothrow!T)\n{\n    scope (failure) assert(0); // nothrow hack\n    object.destroy(t);\n}\n\nvoid destroy(T)(ref T t) if (!is(T == struct))\n{\n    t = T.init;\n}\n\nvoid initialize(T)(ref T t) if (is(T == struct))\n{\n    import core.stdc.string;\n    if (auto p = typeid(T).initializer().ptr)\n        memcpy(&t, p, T.sizeof);\n    else\n        memset(&t, 0, T.sizeof);\n}\n\nvoid initialize(T)(ref T t) if (!is(T == struct))\n{\n    t = T.init;\n}\n\nversion (unittest) struct RC\n{\nnothrow:\n    this(size_t* cnt) { ++*(_cnt = cnt); }\n    ~this() { if (_cnt) --*_cnt; }\n    this(this) { if (_cnt) ++*_cnt; }\n    size_t* _cnt;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/util/container/hashtab.d",
    "content": "/**\n * HashTab container for internal usage.\n *\n * Copyright: Copyright Martin Nowak 2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Martin Nowak\n */\nmodule rt.util.container.hashtab;\n\nimport rt.util.container.array;\nstatic import common = rt.util.container.common;\n\nstruct HashTab(Key, Value)\n{\n    static struct Node\n    {\n        Key _key;\n        Value _value;\n        Node* _next;\n    }\n\n    @disable this(this);\n\n    ~this()\n    {\n        reset();\n    }\n\n    void reset()\n    {\n        foreach (p; _buckets)\n        {\n            while (p !is null)\n            {\n                auto pn = p._next;\n                common.destroy(*p);\n                common.free(p);\n                p = pn;\n            }\n        }\n        _buckets.reset();\n        _length = 0;\n    }\n\n    @property size_t length() const\n    {\n        return _length;\n    }\n\n    @property bool empty() const\n    {\n        return !_length;\n    }\n\n    void remove(in Key key)\n    in { assert(key in this); }\n    do\n    {\n        ensureNotInOpApply();\n\n        immutable hash = hashOf(key) & mask;\n        auto pp = &_buckets[hash];\n        while (*pp)\n        {\n            auto p = *pp;\n            if (p._key == key)\n            {\n                *pp = p._next;\n                common.destroy(*p);\n                common.free(p);\n                if (--_length < _buckets.length && _length >= 4)\n                    shrink();\n                return;\n            }\n            else\n            {\n                pp = &p._next;\n            }\n        }\n        assert(0);\n    }\n\n    ref inout(Value) opIndex(Key key) inout\n    {\n        return *opIn_r(key);\n    }\n\n    void opIndexAssign(Value value, Key key)\n    {\n        *get(key) = value;\n    }\n\n    inout(Value)* opIn_r(in Key key) inout\n    {\n        if (_buckets.length)\n        {\n            immutable hash = hashOf(key) & mask;\n            for (inout(Node)* p = _buckets[hash]; p !is null; p = p._next)\n            {\n                if (p._key == key)\n                    return &p._value;\n            }\n        }\n        return null;\n    }\n\n    int opApply(scope int delegate(ref Key, ref Value) dg)\n    {\n        immutable save = _inOpApply;\n        _inOpApply = true;\n        scope (exit) _inOpApply = save;\n        foreach (p; _buckets)\n        {\n            while (p !is null)\n            {\n                if (auto res = dg(p._key, p._value))\n                    return res;\n                p = p._next;\n            }\n        }\n        return 0;\n    }\n\nprivate:\n\n    Value* get(Key key)\n    {\n        if (auto p = opIn_r(key))\n            return p;\n\n        ensureNotInOpApply();\n\n        if (!_buckets.length)\n            _buckets.length = 4;\n\n        immutable hash = hashOf(key) & mask;\n        auto p = cast(Node*)common.xmalloc(Node.sizeof);\n        common.initialize(*p);\n        p._key = key;\n        p._next = _buckets[hash];\n        _buckets[hash] = p;\n        if (++_length >= 2 * _buckets.length)\n            grow();\n        return &p._value;\n    }\n\n    static hash_t hashOf(in ref Key key) @trusted\n    {\n        static if (is(Key U : U[]))\n            return .hashOf(key, 0);\n        else\n            return .hashOf((&key)[0 .. 1], 0);\n    }\n\n    @property hash_t mask() const\n    {\n        return _buckets.length - 1;\n    }\n\n    void grow()\n    in\n    {\n        assert(_buckets.length);\n    }\n    do\n    {\n        immutable ocnt = _buckets.length;\n        immutable nmask = 2 * ocnt - 1;\n        _buckets.length = 2 * ocnt;\n        for (size_t i = 0; i < ocnt; ++i)\n        {\n            auto pp = &_buckets[i];\n            while (*pp)\n            {\n                auto p = *pp;\n\n                immutable nidx = hashOf(p._key) & nmask;\n                if (nidx != i)\n                {\n                    *pp = p._next;\n                    p._next = _buckets[nidx];\n                    _buckets[nidx] = p;\n                }\n                else\n                {\n                    pp = &p._next;\n                }\n            }\n        }\n    }\n\n    void shrink()\n    in\n    {\n        assert(_buckets.length >= 2);\n    }\n    do\n    {\n        immutable ocnt = _buckets.length;\n        immutable ncnt = ocnt >> 1;\n        immutable nmask = ncnt - 1;\n\n        for (size_t i = ncnt; i < ocnt; ++i)\n        {\n            if (auto tail = _buckets[i])\n            {\n                immutable nidx = i & nmask;\n                auto pp = &_buckets[nidx];\n                while (*pp)\n                    pp = &(*pp)._next;\n                *pp = tail;\n                _buckets[i] = null;\n            }\n        }\n        _buckets.length = ncnt;\n    }\n\n    void ensureNotInOpApply()\n    {\n        if (_inOpApply)\n            assert(0, \"Invalid HashTab manipulation during opApply iteration.\");\n    }\n\n    Array!(Node*) _buckets;\n    size_t _length;\n    bool _inOpApply;\n}\n\nunittest\n{\n    HashTab!(int, int) tab;\n\n    foreach (i; 0 .. 100)\n        tab[i] = 100 - i;\n\n    foreach (i; 0 .. 100)\n        assert(tab[i] == 100 - i);\n\n    foreach (k, v; tab)\n        assert(v == 100 - k);\n\n    foreach (i; 0 .. 50)\n        tab.remove(2 * i);\n\n    assert(tab.length == 50);\n\n    foreach (i; 0 .. 50)\n        assert(tab[2 * i + 1] == 100 - 2 * i - 1);\n\n    assert(tab.length == 50);\n\n    tab.reset();\n    assert(tab.empty);\n    tab[0] = 0;\n    assert(!tab.empty);\n    destroy(tab);\n    assert(tab.empty);\n\n    // not copyable\n    static assert(!__traits(compiles, { HashTab!(int, int) tab2 = tab; }));\n    HashTab!(int, int) tab2;\n    static assert(!__traits(compiles, tab = tab2));\n    static void foo(HashTab!(int, int) copy) {}\n    static assert(!__traits(compiles, foo(tab)));\n}\n\nunittest\n{\n    HashTab!(string, size_t) tab;\n\n    tab[\"foo\"] = 0;\n    assert(tab[\"foo\"] == 0);\n    ++tab[\"foo\"];\n    assert(tab[\"foo\"] == 1);\n    tab[\"foo\"]++;\n    assert(tab[\"foo\"] == 2);\n\n    auto s = \"fo\";\n    s ~= \"o\";\n    assert(tab[s] == 2);\n    assert(tab.length == 1);\n    tab[s] -= 2;\n    assert(tab[s] == 0);\n    tab[\"foo\"] = 12;\n    assert(tab[s] == 12);\n\n    tab.remove(\"foo\");\n    assert(tab.empty);\n}\n\nunittest\n{\n    alias RC = common.RC;\n    HashTab!(size_t, RC) tab;\n\n    size_t cnt;\n    assert(cnt == 0);\n    tab[0] = RC(&cnt);\n    assert(cnt == 1);\n    tab[1] = tab[0];\n    assert(cnt == 2);\n    tab.remove(0);\n    assert(cnt == 1);\n    tab.remove(1);\n    assert(cnt == 0);\n}\n\nunittest\n{\n    import core.exception;\n\n    HashTab!(uint, uint) tab;\n    foreach (i; 0 .. 5)\n        tab[i] = i;\n    bool thrown;\n    foreach (k, v; tab)\n    {\n        try\n        {\n            if (k == 3) tab.remove(k);\n        }\n        catch (AssertError e)\n        {\n            thrown = true;\n        }\n    }\n    assert(thrown);\n    assert(tab[3] == 3);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/util/container/treap.d",
    "content": "/**\n * Treap container for internal usage.\n *\n * Copyright: Copyright Digital Mars 2014 - 2014.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n */\nmodule rt.util.container.treap;\n\nstatic import common = rt.util.container.common;\nimport rt.util.random;\nimport rt.qsort;\n\nstruct Treap(E)\n{\nnothrow:\n    static struct Node\n    {\n        Node* left, right;\n        E element;\n        uint priority;\n    }\n\n    @disable this(this);\n\n    ~this()\n    {\n        removeAll();\n    }\n\n    void initialize()\n    {\n        rand48.defaultSeed();\n    }\n\n    void insert(E element) @nogc\n    {\n        root = insert(root, element);\n    }\n\n    void remove(E element)\n    {\n        remove(&root, element);\n    }\n\n    int opApply(scope int delegate(ref E) nothrow dg)\n    {\n        return (cast(const)&this).opApply((ref const E e) => dg(*cast(E*)&e));\n    }\n\n    int opApply(scope int delegate(ref const E) nothrow dg) const\n    {\n        return opApplyHelper(root, dg);\n    }\n\n    version (unittest)\n    bool opEquals(E[] elements)\n    {\n        size_t i;\n        foreach (e; this)\n        {\n            if (i >= elements.length)\n                return false;\n            if (e != elements[i++])\n                return false;\n        }\n        return i == elements.length;\n    }\n\n    void removeAll()\n    {\n        removeAll(root);\n        root = null;\n    }\n\n    version (unittest)\n    bool valid()\n    {\n        return valid(root);\n    }\n\n\n    version (none)\n    uint height()\n    {\n        static uint height(Node* node)\n        {\n            if (!node)\n                return 0;\n            auto left = height(node.left);\n            auto right = height(node.right);\n            return 1 + (left > right ? left : right);\n        }\n        return height(root);\n    }\n\n    version (none)\n    size_t count()\n    {\n        static size_t count(Node* node)\n        {\n            if (!node)\n                return 0;\n            return count(node.left) + count(node.right) + 1;\n        }\n        return count(root);\n    }\n\n\nprivate:\n    Node* root;\n    Rand48 rand48;\n\n    Node* allocNode(E element) @nogc\n    {\n        Node* node = cast(Node*)common.xmalloc(Node.sizeof);\n        node.left = node.right = null;\n        node.priority = rand48();\n        node.element = element;\n        return node;\n    }\n\n    Node* insert(Node* node, E element) @nogc\n    {\n        if (!node)\n            return allocNode(element);\n        else if (element < node.element)\n        {\n            node.left = insert(node.left, element);\n            if (node.left.priority < node.priority)\n                node = rotateR(node);\n        }\n        else if (element > node.element)\n        {\n            node.right = insert(node.right, element);\n            if (node.right.priority < node.priority)\n                node = rotateL(node);\n        }\n        else\n        {} // ignore duplicate\n\n        return node;\n    }\n\nstatic:\n\n    void freeNode(Node* node)\n    {\n        common.free(node);\n    }\n\n    Node* rotateL(Node* root)\n    {\n        auto pivot = root.right;\n        root.right = pivot.left;\n        pivot.left = root;\n        return pivot;\n    }\n\n    Node* rotateR(Node* root)\n    {\n        auto pivot = root.left;\n        root.left = pivot.right;\n        pivot.right = root;\n        return pivot;\n    }\n\n    void remove(Node** ppnode, E element)\n    {\n        Node* node = *ppnode;\n        if (!node)\n            return; // element not in treap\n\n        if (element < node.element)\n        {\n            remove(&node.left, element);\n        }\n        else if (element > node.element)\n        {\n            remove(&node.right, element);\n        }\n        else\n        {\n            while (node.left && node.right)\n            {\n                if (node.left.priority < node.right.priority)\n                {\n                    *ppnode = rotateR(node);\n                    ppnode = &(*ppnode).right;\n                }\n                else\n                {\n                    *ppnode = rotateL(node);\n                    ppnode = &(*ppnode).left;\n                }\n            }\n            if (!node.left)\n                *ppnode = node.right;\n            else\n                *ppnode = node.left;\n            freeNode(node);\n        }\n    }\n\n    void removeAll(Node* node)\n    {\n        if (!node)\n            return;\n        removeAll(node.left);\n        removeAll(node.right);\n        freeNode(node);\n    }\n\n    int opApplyHelper(const Node* node, scope int delegate(ref const E) nothrow dg)\n    {\n        if (!node)\n            return 0;\n\n        int result = opApplyHelper(node.left, dg);\n        if (result)\n            return result;\n        result = dg(node.element);\n        if (result)\n            return result;\n        return opApplyHelper(node.right, dg);\n    }\n\n    version (unittest)\n    bool valid(Node* node)\n    {\n        if (!node)\n            return true;\n\n        if (node.left)\n        {\n            if (node.left.priority < node.priority)\n                return false;\n            if (node.left.element > node.element)\n                return false;\n        }\n        if (node.right)\n        {\n            if (node.right.priority < node.priority)\n                return false;\n            if (node.right.element < node.element)\n                return false;\n        }\n        return valid(node.left) && valid(node.right);\n    }\n}\n\nunittest\n{\n    // randomized unittest for randomized data structure\n    import /*cstdlib = */core.stdc.stdlib : rand, srand;\n    import /*ctime = */core.stdc.time : time;\n\n    enum OP { add, remove }\n    enum initialSize = 1000;\n    enum randOps = 1000;\n\n    Treap!uint treap;\n    OP[] ops;\n    uint[] opdata;\n\n    treap.initialize();\n    srand(cast(uint)time(null));\n\n    uint[] data;\ninitialLoop:\n    foreach (i; 0 .. initialSize)\n    {\n        data ~= rand();\n        treap.insert(data[$-1]);\n        foreach (e; data[0..$-1])\n            if (e == data[$-1])\n            {\n                data = data[0..$-1];\n                continue initialLoop;\n            }\n    }\n    _adSort(*cast(void[]*)&data, typeid(data[0]));\n    assert(treap == data);\n    assert(treap.valid());\n\n    for (int i = randOps; i > 0; --i)\n    {\n        ops ~= cast(OP)(rand() < uint.max / 2 ? OP.add: OP.remove);\n        opdata ~= rand();\n    }\n\n    foreach (op; ops)\n    {\n        if (op == OP.add)\n        {\n            treap.insert(opdata[0]);\n\n            size_t i;\n            for (i = 0; i < data.length; ++i)\n                if (data[i] >= opdata[0])\n                    break;\n\n            if (i == data.length || data[i] != opdata[0])\n            {    // not a duplicate\n                data.length++;\n                uint tmp = opdata[0];\n                for (; i < data.length; ++i)\n                {\n                    uint tmp2 = data[i];\n                    data[i] = tmp;\n                    tmp = tmp2;\n                }\n            }\n        }\n        else if (!data.length)    // nothing to remove\n        {\n            opdata = opdata[1..$];\n            continue;\n        }\n        else\n        {\n            uint tmp = data[opdata[0]%data.length];\n            treap.remove(tmp);\n            size_t i;\n            for (i = 0; data[i] < tmp; ++i)\n            {}\n            for (; i < data.length-1; ++i)\n                data[i] = data[i+1];\n            data.length--;\n        }\n        assert(treap.valid());\n        assert(treap == data);\n        opdata = opdata[1..$];\n    }\n\n    treap.removeAll();\n    data.length = 0;\n    assert(treap == data);\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/util/random.d",
    "content": "/**\n * Random number generators for internal usage.\n *\n * Copyright: Copyright Digital Mars 2014.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n */\nmodule rt.util.random;\n\nstruct Rand48\n{\n    private ulong rng_state;\n\n@safe @nogc nothrow:\n\n    void defaultSeed() @trusted\n    {\n        version (D_InlineAsm_X86_64)\n        {\n            // RDTSC takes around 22 clock cycles.\n            ulong result = void; // Workaround for LDC issue #950, cannot access struct members in DMD asm.\n            asm @nogc nothrow\n            {\n                rdtsc;\n                // RAX: low 32 bits are low bits of timestamp, high 32 bits are 0.\n                // RDX: low 32 bits are high bits of timestamp, high 32 bits are 0.\n                // We combine these into a 48 bit value instead of a full 64 bits\n                // because `front` and `popFront` only make use of the bottom 48\n                // bits of `rng_state`.\n                shl RDX, 16;\n                xor RDX, RAX;\n                mov result, RDX;\n            }\n            rng_state = result;\n            popFront();\n        }\n        //else version (D_InlineAsm_X86)\n        //{\n        //    // We don't use `rdtsc` with version (D_InlineAsm_X86) because\n        //    // some x86 processors don't support `rdtsc` and because on\n        //    // x86 (but not x86-64) Linux `prctl` can disable a process's\n        //    // ability to use `rdtsc`.\n        //    static assert(0);\n        //}\n        else version (Windows)\n        {\n            // QueryPerformanceCounter takes about 1/4 the time of ctime.time.\n            import core.sys.windows.winbase : QueryPerformanceCounter;\n            QueryPerformanceCounter(cast(long*) &rng_state);\n            popFront();\n        }\n        else version (OSX)\n        {\n            // mach_absolute_time is much faster than ctime.time.\n            import core.time : mach_absolute_time;\n            rng_state = mach_absolute_time();\n            popFront();\n        }\n        else\n        {\n            // Fallback to libc timestamp in seconds.\n            import ctime = core.stdc.time : time;\n            seed((cast(uint) ctime.time(null)));\n        }\n    }\n\npure:\n\n    void seed(uint seedval)\n    {\n        rng_state = cast(ulong)seedval << 16 | 0x330e;\n        popFront();\n    }\n\n    auto opCall()\n    {\n        auto result = front;\n        popFront();\n        return result;\n    }\n\n    @property uint front()\n    {\n        return cast(uint)(rng_state >> 16);\n    }\n\n    void popFront()\n    {\n        immutable ulong a = 25214903917;\n        immutable ulong c = 11;\n        immutable ulong m_mask = (1uL << 48uL) - 1;\n        rng_state = (a*rng_state+c) & m_mask;\n    }\n\n    enum empty = false;\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/util/typeinfo.d",
    "content": "/**\n * This module contains utilities for TypeInfo implementation.\n *\n * Copyright: Copyright Kenji Hara 2014-.\n * License:   <a href=\"http://www.boost.org/LICENSE_1_0.txt\">Boost License 1.0</a>.\n * Authors:   Kenji Hara\n */\nmodule rt.util.typeinfo;\nstatic import core.internal.hash;\n\ntemplate Floating(T)\nif (is(T == float) || is(T == double) || is(T == real))\n{\n  pure nothrow @safe:\n\n    bool equals(T f1, T f2)\n    {\n        return f1 == f2;\n    }\n\n    int compare(T d1, T d2)\n    {\n        if (d1 != d1 || d2 != d2) // if either are NaN\n        {\n            if (d1 != d1)\n            {\n                if (d2 != d2)\n                    return 0;\n                return -1;\n            }\n            return 1;\n        }\n        return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);\n    }\n\n    public alias hashOf = core.internal.hash.hashOf;\n}\ntemplate Floating(T)\nif (is(T == cfloat) || is(T == cdouble) || is(T == creal))\n{\n  pure nothrow @safe:\n\n    bool equals(T f1, T f2)\n    {\n        return f1 == f2;\n    }\n\n    int compare(T f1, T f2)\n    {\n        int result;\n\n        if (f1.re < f2.re)\n            result = -1;\n        else if (f1.re > f2.re)\n            result = 1;\n        else if (f1.im < f2.im)\n            result = -1;\n        else if (f1.im > f2.im)\n            result = 1;\n        else\n            result = 0;\n        return result;\n    }\n\n    public alias hashOf = core.internal.hash.hashOf;\n}\n\ntemplate Array(T)\nif (is(T ==  float) || is(T ==  double) || is(T ==  real) ||\n    is(T == cfloat) || is(T == cdouble) || is(T == creal))\n{\n  pure nothrow @safe:\n\n    bool equals(T[] s1, T[] s2)\n    {\n        size_t len = s1.length;\n        if (len != s2.length)\n            return false;\n        for (size_t u = 0; u < len; u++)\n        {\n            if (!Floating!T.equals(s1[u], s2[u]))\n                return false;\n        }\n        return true;\n    }\n\n    int compare(T[] s1, T[] s2)\n    {\n        size_t len = s1.length;\n        if (s2.length < len)\n            len = s2.length;\n        for (size_t u = 0; u < len; u++)\n        {\n            if (int c = Floating!T.compare(s1[u], s2[u]))\n                return c;\n        }\n        if (s1.length < s2.length)\n            return -1;\n        else if (s1.length > s2.length)\n            return 1;\n        return 0;\n    }\n\n    public alias hashOf = core.internal.hash.hashOf;\n}\n\nversion (unittest)\n{\n    alias TypeTuple(T...) = T;\n}\nunittest\n{\n    // Bugzilla 13052\n\n    static struct SX(F) { F f; }\n    TypeInfo ti;\n\n    // real types\n    foreach (F; TypeTuple!(float, double, real))\n    (){ // workaround #2396\n        alias S = SX!F;\n        F f1 = +0.0,\n          f2 = -0.0;\n\n        assert(f1  == f2);\n        assert(f1 !is f2);\n        ti = typeid(F);\n        assert(ti.getHash(&f1) == ti.getHash(&f2));\n\n        F[] a1 = [f1, f1, f1];\n        F[] a2 = [f2, f2, f2];\n        assert(a1  == a2);\n        assert(a1 !is a2);\n        ti = typeid(F[]);\n        assert(ti.getHash(&a1) == ti.getHash(&a2));\n\n        F[][] aa1 = [a1, a1, a1];\n        F[][] aa2 = [a2, a2, a2];\n        assert(aa1  == aa2);\n        assert(aa1 !is aa2);\n        ti = typeid(F[][]);\n        assert(ti.getHash(&aa1) == ti.getHash(&aa2));\n\n        S s1 = {f1},\n          s2 = {f2};\n        assert(s1  == s2);\n        assert(s1 !is s2);\n        ti = typeid(S);\n        assert(ti.getHash(&s1) == ti.getHash(&s2));\n\n        S[] da1 = [S(f1), S(f1), S(f1)],\n            da2 = [S(f2), S(f2), S(f2)];\n        assert(da1  == da2);\n        assert(da1 !is da2);\n        ti = typeid(S[]);\n        assert(ti.getHash(&da1) == ti.getHash(&da2));\n\n        S[3] sa1 = {f1},\n             sa2 = {f2};\n        assert(sa1  == sa2);\n        assert(sa1[] !is sa2[]);\n        ti = typeid(S[3]);\n        assert(ti.getHash(&sa1) == ti.getHash(&sa2));\n    }();\n\n    // imaginary types\n    foreach (F; TypeTuple!(ifloat, idouble, ireal))\n    (){ // workaround #2396\n        alias S = SX!F;\n        F f1 = +0.0i,\n          f2 = -0.0i;\n\n        assert(f1  == f2);\n        assert(f1 !is f2);\n        ti = typeid(F);\n        assert(ti.getHash(&f1) == ti.getHash(&f2));\n\n        F[] a1 = [f1, f1, f1];\n        F[] a2 = [f2, f2, f2];\n        assert(a1  == a2);\n        assert(a1 !is a2);\n        ti = typeid(F[]);\n        assert(ti.getHash(&a1) == ti.getHash(&a2));\n\n        F[][] aa1 = [a1, a1, a1];\n        F[][] aa2 = [a2, a2, a2];\n        assert(aa1  == aa2);\n        assert(aa1 !is aa2);\n        ti = typeid(F[][]);\n        assert(ti.getHash(&aa1) == ti.getHash(&aa2));\n\n        S s1 = {f1},\n          s2 = {f2};\n        assert(s1  == s2);\n        assert(s1 !is s2);\n        ti = typeid(S);\n        assert(ti.getHash(&s1) == ti.getHash(&s2));\n\n        S[] da1 = [S(f1), S(f1), S(f1)],\n            da2 = [S(f2), S(f2), S(f2)];\n        assert(da1  == da2);\n        assert(da1 !is da2);\n        ti = typeid(S[]);\n        assert(ti.getHash(&da1) == ti.getHash(&da2));\n\n        S[3] sa1 = {f1},\n             sa2 = {f2};\n        assert(sa1  == sa2);\n        assert(sa1[] !is sa2[]);\n        ti = typeid(S[3]);\n        assert(ti.getHash(&sa1) == ti.getHash(&sa2));\n    }();\n\n    // complex types\n    foreach (F; TypeTuple!(cfloat, cdouble, creal))\n    (){ // workaround #2396\n        alias S = SX!F;\n        F[4] f = [+0.0 + 0.0i,\n                  +0.0 - 0.0i,\n                  -0.0 + 0.0i,\n                  -0.0 - 0.0i];\n\n        foreach (i, f1; f) foreach (j, f2; f) if (i != j)\n        {\n            assert(f1 == 0 + 0i);\n\n            assert(f1 == f2);\n            assert(f1 !is f2);\n            ti = typeid(F);\n            assert(ti.getHash(&f1) == ti.getHash(&f2));\n\n            F[] a1 = [f1, f1, f1];\n            F[] a2 = [f2, f2, f2];\n            assert(a1  == a2);\n            assert(a1 !is a2);\n            ti = typeid(F[]);\n            assert(ti.getHash(&a1) == ti.getHash(&a2));\n\n            F[][] aa1 = [a1, a1, a1];\n            F[][] aa2 = [a2, a2, a2];\n            assert(aa1  == aa2);\n            assert(aa1 !is aa2);\n            ti = typeid(F[][]);\n            assert(ti.getHash(&aa1) == ti.getHash(&aa2));\n\n            S s1 = {f1},\n              s2 = {f2};\n            assert(s1  == s2);\n            assert(s1 !is s2);\n            ti = typeid(S);\n            assert(ti.getHash(&s1) == ti.getHash(&s2));\n\n            S[] da1 = [S(f1), S(f1), S(f1)],\n                da2 = [S(f2), S(f2), S(f2)];\n            assert(da1  == da2);\n            assert(da1 !is da2);\n            ti = typeid(S[]);\n            assert(ti.getHash(&da1) == ti.getHash(&da2));\n\n            S[3] sa1 = {f1},\n                 sa2 = {f2};\n            assert(sa1  == sa2);\n            assert(sa1[] !is sa2[]);\n            ti = typeid(S[3]);\n            assert(ti.getHash(&sa1) == ti.getHash(&sa2));\n        }\n    }();\n}\n"
  },
  {
    "path": "libphobos/libdruntime/rt/util/utf.d",
    "content": "/********************************************\n * Encode and decode UTF-8, UTF-16 and UTF-32 strings.\n *\n * For Win32 systems, the C wchar_t type is UTF-16 and corresponds to the D\n * wchar type.\n * For Posix systems, the C wchar_t type is UTF-32 and corresponds to\n * the D utf.dchar type.\n *\n * UTF character support is restricted to (\\u0000 &lt;= character &lt;= \\U0010FFFF).\n *\n * See_Also:\n *      $(LINK2 http://en.wikipedia.org/wiki/Unicode, Wikipedia)<br>\n *      $(LINK http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8)<br>\n *      $(LINK http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335)\n *\n * Copyright: Copyright Digital Mars 2003 - 2016.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Walter Bright, Sean Kelly\n * Source:    $(DRUNTIMESRC rt/util/_utf.d)\n */\n\nmodule rt.util.utf;\n\nextern (C) void onUnicodeError( string msg, size_t idx, string file = __FILE__, size_t line = __LINE__ ) @safe pure;\n\n/*******************************\n * Test if c is a valid UTF-32 character.\n *\n * \\uFFFE and \\uFFFF are considered valid by this function,\n * as they are permitted for internal use by an application,\n * but they are not allowed for interchange by the Unicode standard.\n *\n * Returns: true if it is, false if not.\n */\n\n@safe @nogc pure nothrow\nbool isValidDchar(dchar c)\n{\n    /* Note: FFFE and FFFF are specifically permitted by the\n     * Unicode standard for application internal use, but are not\n     * allowed for interchange.\n     * (thanks to Arcane Jill)\n     */\n\n    return c < 0xD800 ||\n        (c > 0xDFFF && c <= 0x10FFFF /*&& c != 0xFFFE && c != 0xFFFF*/);\n}\n\nunittest\n{\n    debug(utf) printf(\"utf.isValidDchar.unittest\\n\");\n    assert(isValidDchar(cast(dchar)'a') == true);\n    assert(isValidDchar(cast(dchar)0x1FFFFF) == false);\n}\n\n\n\nstatic immutable UTF8stride =\n[\n    cast(ubyte)\n    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,\n    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,\n    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,\n    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,\n    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,\n    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,\n    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,\n    4,4,4,4,4,4,4,4,5,5,5,5,6,6,0xFF,0xFF,\n];\n\n/**\n * stride() returns the length of a UTF-8 sequence starting at index i\n * in string s.\n * Returns:\n *      The number of bytes in the UTF-8 sequence or\n *      0xFF meaning s[i] is not the start of of UTF-8 sequence.\n */\n@safe @nogc pure nothrow\nuint stride(in char[] s, size_t i)\n{\n    return UTF8stride[s[i]];\n}\n\n/**\n * stride() returns the length of a UTF-16 sequence starting at index i\n * in string s.\n */\n@safe @nogc pure nothrow\nuint stride(in wchar[] s, size_t i)\n{   uint u = s[i];\n    return 1 + (u >= 0xD800 && u <= 0xDBFF);\n}\n\n/**\n * stride() returns the length of a UTF-32 sequence starting at index i\n * in string s.\n * Returns: The return value will always be 1.\n */\n@safe @nogc pure nothrow\nuint stride(in dchar[] s, size_t i)\n{\n    return 1;\n}\n\n/*******************************************\n * Given an index i into an array of characters s[],\n * and assuming that index i is at the start of a UTF character,\n * determine the number of UCS characters up to that index i.\n */\n@safe pure\nsize_t toUCSindex(in char[] s, size_t i)\n{\n    size_t n;\n    size_t j;\n\n    for (j = 0; j < i; )\n    {\n        j += stride(s, j);\n        n++;\n    }\n    if (j > i)\n    {\n        onUnicodeError(\"invalid UTF-8 sequence\", j);\n    }\n    return n;\n}\n\n/** ditto */\n@safe pure\nsize_t toUCSindex(in wchar[] s, size_t i)\n{\n    size_t n;\n    size_t j;\n\n    for (j = 0; j < i; )\n    {\n        j += stride(s, j);\n        n++;\n    }\n    if (j > i)\n    {\n        onUnicodeError(\"invalid UTF-16 sequence\", j);\n    }\n    return n;\n}\n\n/** ditto */\n@safe @nogc pure nothrow\nsize_t toUCSindex(in dchar[] s, size_t i)\n{\n    return i;\n}\n\n/******************************************\n * Given a UCS index n into an array of characters s[], return the UTF index.\n */\n@safe pure\nsize_t toUTFindex(in char[] s, size_t n)\n{\n    size_t i;\n\n    while (n--)\n    {\n        uint j = UTF8stride[s[i]];\n        if (j == 0xFF)\n            onUnicodeError(\"invalid UTF-8 sequence\", i);\n        i += j;\n    }\n    return i;\n}\n\n/** ditto */\n@safe @nogc pure nothrow\nsize_t toUTFindex(in wchar[] s, size_t n)\n{\n    size_t i;\n\n    while (n--)\n    {   wchar u = s[i];\n\n        i += 1 + (u >= 0xD800 && u <= 0xDBFF);\n    }\n    return i;\n}\n\n/** ditto */\n@safe @nogc pure nothrow\nsize_t toUTFindex(in dchar[] s, size_t n)\n{\n    return n;\n}\n\n/* =================== Decode ======================= */\n\n/***************\n * Decodes and returns character starting at s[idx]. idx is advanced past the\n * decoded character. If the character is not well formed, a UtfException is\n * thrown and idx remains unchanged.\n */\n@safe pure\ndchar decode(in char[] s, ref size_t idx)\n    in\n    {\n        assert(idx >= 0 && idx < s.length);\n    }\n    out (result)\n    {\n        assert(isValidDchar(result));\n    }\n    do\n    {\n        size_t len = s.length;\n        dchar V;\n        size_t i = idx;\n        char u = s[i];\n\n        if (u & 0x80)\n        {   uint n;\n            char u2;\n\n            /* The following encodings are valid, except for the 5 and 6 byte\n             * combinations:\n             *  0xxxxxxx\n             *  110xxxxx 10xxxxxx\n             *  1110xxxx 10xxxxxx 10xxxxxx\n             *  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n             *  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n             *  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n             */\n            for (n = 1; ; n++)\n            {\n                if (n > 4)\n                    goto Lerr;          // only do the first 4 of 6 encodings\n                if (((u << n) & 0x80) == 0)\n                {\n                    if (n == 1)\n                        goto Lerr;\n                    break;\n                }\n            }\n\n            // Pick off (7 - n) significant bits of B from first byte of octet\n            V = cast(dchar)(u & ((1 << (7 - n)) - 1));\n\n            if (i + (n - 1) >= len)\n                goto Lerr;                      // off end of string\n\n            /* The following combinations are overlong, and illegal:\n             *  1100000x (10xxxxxx)\n             *  11100000 100xxxxx (10xxxxxx)\n             *  11110000 1000xxxx (10xxxxxx 10xxxxxx)\n             *  11111000 10000xxx (10xxxxxx 10xxxxxx 10xxxxxx)\n             *  11111100 100000xx (10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx)\n             */\n            u2 = s[i + 1];\n            if ((u & 0xFE) == 0xC0 ||\n                (u == 0xE0 && (u2 & 0xE0) == 0x80) ||\n                (u == 0xF0 && (u2 & 0xF0) == 0x80) ||\n                (u == 0xF8 && (u2 & 0xF8) == 0x80) ||\n                (u == 0xFC && (u2 & 0xFC) == 0x80))\n                goto Lerr;                      // overlong combination\n\n            for (uint j = 1; j != n; j++)\n            {\n                u = s[i + j];\n                if ((u & 0xC0) != 0x80)\n                    goto Lerr;                  // trailing bytes are 10xxxxxx\n                V = (V << 6) | (u & 0x3F);\n            }\n            if (!isValidDchar(V))\n                goto Lerr;\n            i += n;\n        }\n        else\n        {\n            V = cast(dchar) u;\n            i++;\n        }\n\n        idx = i;\n        return V;\n\n      Lerr:\n      onUnicodeError(\"invalid UTF-8 sequence\", i);\n    return V; // dummy return\n    }\n\nunittest\n{   size_t i;\n    dchar c;\n\n    debug(utf) printf(\"utf.decode.unittest\\n\");\n\n    static s1 = \"abcd\"c;\n    i = 0;\n    c = decode(s1, i);\n    assert(c == cast(dchar)'a');\n    assert(i == 1);\n    c = decode(s1, i);\n    assert(c == cast(dchar)'b');\n    assert(i == 2);\n\n    static s2 = \"\\xC2\\xA9\"c;\n    i = 0;\n    c = decode(s2, i);\n    assert(c == cast(dchar)'\\u00A9');\n    assert(i == 2);\n\n    static s3 = \"\\xE2\\x89\\xA0\"c;\n    i = 0;\n    c = decode(s3, i);\n    assert(c == cast(dchar)'\\u2260');\n    assert(i == 3);\n\n    static s4 =\n    [   \"\\xE2\\x89\"c[],          // too short\n        \"\\xC0\\x8A\",\n        \"\\xE0\\x80\\x8A\",\n        \"\\xF0\\x80\\x80\\x8A\",\n        \"\\xF8\\x80\\x80\\x80\\x8A\",\n        \"\\xFC\\x80\\x80\\x80\\x80\\x8A\",\n    ];\n\n    for (int j = 0; j < s4.length; j++)\n    {\n        try\n        {\n            i = 0;\n            c = decode(s4[j], i);\n            assert(0);\n        }\n        catch (Throwable o)\n        {\n            i = 23;\n        }\n        assert(i == 23);\n    }\n}\n\n/** ditto */\n@safe pure\ndchar decode(in wchar[] s, ref size_t idx)\n    in\n    {\n        assert(idx >= 0 && idx < s.length);\n    }\n    out (result)\n    {\n        assert(isValidDchar(result));\n    }\n    do\n    {\n        string msg;\n        dchar V;\n        size_t i = idx;\n        uint u = s[i];\n\n        if (u & ~0x7F)\n        {   if (u >= 0xD800 && u <= 0xDBFF)\n            {   uint u2;\n\n                if (i + 1 == s.length)\n                {   msg = \"surrogate UTF-16 high value past end of string\";\n                    goto Lerr;\n                }\n                u2 = s[i + 1];\n                if (u2 < 0xDC00 || u2 > 0xDFFF)\n                {   msg = \"surrogate UTF-16 low value out of range\";\n                    goto Lerr;\n                }\n                u = ((u - 0xD7C0) << 10) + (u2 - 0xDC00);\n                i += 2;\n            }\n            else if (u >= 0xDC00 && u <= 0xDFFF)\n            {   msg = \"unpaired surrogate UTF-16 value\";\n                goto Lerr;\n            }\n            else if (u == 0xFFFE || u == 0xFFFF)\n            {   msg = \"illegal UTF-16 value\";\n                goto Lerr;\n            }\n            else\n                i++;\n        }\n        else\n        {\n            i++;\n        }\n\n        idx = i;\n        return cast(dchar)u;\n\n      Lerr:\n          onUnicodeError(msg, i);\n        return cast(dchar)u; // dummy return\n    }\n\n/** ditto */\n@safe pure\ndchar decode(in dchar[] s, ref size_t idx)\n    in\n    {\n        assert(idx >= 0 && idx < s.length);\n    }\n    do\n    {\n        size_t i = idx;\n        dchar c = s[i];\n\n        if (!isValidDchar(c))\n            goto Lerr;\n        idx = i + 1;\n        return c;\n\n      Lerr:\n          onUnicodeError(\"invalid UTF-32 value\", i);\n        return c; // dummy return\n    }\n\n\n/* =================== Encode ======================= */\n\n/*******************************\n * Encodes character c and appends it to array s[].\n */\n@safe pure nothrow\nvoid encode(ref char[] s, dchar c)\n    in\n    {\n        assert(isValidDchar(c));\n    }\n    do\n    {\n        char[] r = s;\n\n        if (c <= 0x7F)\n        {\n            r ~= cast(char) c;\n        }\n        else\n        {\n            char[4] buf;\n            uint L;\n\n            if (c <= 0x7FF)\n            {\n                buf[0] = cast(char)(0xC0 | (c >> 6));\n                buf[1] = cast(char)(0x80 | (c & 0x3F));\n                L = 2;\n            }\n            else if (c <= 0xFFFF)\n            {\n                buf[0] = cast(char)(0xE0 | (c >> 12));\n                buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n                buf[2] = cast(char)(0x80 | (c & 0x3F));\n                L = 3;\n            }\n            else if (c <= 0x10FFFF)\n            {\n                buf[0] = cast(char)(0xF0 | (c >> 18));\n                buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));\n                buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n                buf[3] = cast(char)(0x80 | (c & 0x3F));\n                L = 4;\n            }\n            else\n            {\n                assert(0);\n            }\n            r ~= buf[0 .. L];\n        }\n        s = r;\n    }\n\nunittest\n{\n    debug(utf) printf(\"utf.encode.unittest\\n\");\n\n    char[] s = \"abcd\".dup;\n    encode(s, cast(dchar)'a');\n    assert(s.length == 5);\n    assert(s == \"abcda\");\n\n    encode(s, cast(dchar)'\\u00A9');\n    assert(s.length == 7);\n    assert(s == \"abcda\\xC2\\xA9\");\n    //assert(s == \"abcda\\u00A9\");       // BUG: fix compiler\n\n    encode(s, cast(dchar)'\\u2260');\n    assert(s.length == 10);\n    assert(s == \"abcda\\xC2\\xA9\\xE2\\x89\\xA0\");\n}\n\n/** ditto */\n@safe pure nothrow\nvoid encode(ref wchar[] s, dchar c)\n    in\n    {\n        assert(isValidDchar(c));\n    }\n    do\n    {\n        wchar[] r = s;\n\n        if (c <= 0xFFFF)\n        {\n            r ~= cast(wchar) c;\n        }\n        else\n        {\n            wchar[2] buf;\n\n            buf[0] = cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);\n            buf[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00);\n            r ~= buf;\n        }\n        s = r;\n    }\n\n/** ditto */\n@safe pure nothrow\nvoid encode(ref dchar[] s, dchar c)\n    in\n    {\n        assert(isValidDchar(c));\n    }\n    do\n    {\n        s ~= c;\n    }\n\n/**\nReturns the code length of $(D c) in the encoding using $(D C) as a\ncode point. The code is returned in character count, not in bytes.\n */\n@safe pure nothrow @nogc\nubyte codeLength(C)(dchar c)\n{\n    static if (C.sizeof == 1)\n    {\n        if (c <= 0x7F) return 1;\n        if (c <= 0x7FF) return 2;\n        if (c <= 0xFFFF) return 3;\n        if (c <= 0x10FFFF) return 4;\n        assert(false);\n    }\n    else static if (C.sizeof == 2)\n    {\n        return c <= 0xFFFF ? 1 : 2;\n    }\n    else\n    {\n        static assert(C.sizeof == 4);\n        return 1;\n    }\n}\n\n/* =================== Validation ======================= */\n\n/***********************************\nChecks to see if string is well formed or not. $(D S) can be an array\n of $(D char), $(D wchar), or $(D dchar). Throws a $(D UtfException)\n if it is not. Use to check all untrusted input for correctness.\n */\n@safe pure\nvoid validate(S)(in S s)\n{\n    auto len = s.length;\n    for (size_t i = 0; i < len; )\n    {\n        decode(s, i);\n    }\n}\n\n/* =================== Conversion to UTF8 ======================= */\n\n@safe pure nothrow @nogc\nchar[] toUTF8(char[] buf, dchar c)\n    in\n    {\n        assert(isValidDchar(c));\n    }\n    do\n    {\n        if (c <= 0x7F)\n        {\n            buf[0] = cast(char) c;\n            return buf[0 .. 1];\n        }\n        else if (c <= 0x7FF)\n        {\n            buf[0] = cast(char)(0xC0 | (c >> 6));\n            buf[1] = cast(char)(0x80 | (c & 0x3F));\n            return buf[0 .. 2];\n        }\n        else if (c <= 0xFFFF)\n        {\n            buf[0] = cast(char)(0xE0 | (c >> 12));\n            buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n            buf[2] = cast(char)(0x80 | (c & 0x3F));\n            return buf[0 .. 3];\n        }\n        else if (c <= 0x10FFFF)\n        {\n            buf[0] = cast(char)(0xF0 | (c >> 18));\n            buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));\n            buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n            buf[3] = cast(char)(0x80 | (c & 0x3F));\n            return buf[0 .. 4];\n        }\n        assert(0);\n    }\n\n/*******************\n * Encodes string s into UTF-8 and returns the encoded string.\n */\n@safe pure nothrow\nstring toUTF8(string s)\n    in\n    {\n        validate(s);\n    }\n    do\n    {\n        return s;\n    }\n\n/** ditto */\n@trusted pure\nstring toUTF8(in wchar[] s)\n{\n    char[] r;\n    size_t i;\n    size_t slen = s.length;\n\n    r.length = slen;\n\n    for (i = 0; i < slen; i++)\n    {   wchar c = s[i];\n\n        if (c <= 0x7F)\n            r[i] = cast(char)c;         // fast path for ascii\n        else\n        {\n            r.length = i;\n            foreach (dchar c; s[i .. slen])\n            {\n                encode(r, c);\n            }\n            break;\n        }\n    }\n    return cast(string)r;\n}\n\n/** ditto */\n@trusted pure\nstring toUTF8(in dchar[] s)\n{\n    char[] r;\n    size_t i;\n    size_t slen = s.length;\n\n    r.length = slen;\n\n    for (i = 0; i < slen; i++)\n    {   dchar c = s[i];\n\n        if (c <= 0x7F)\n            r[i] = cast(char)c;         // fast path for ascii\n        else\n        {\n            r.length = i;\n            foreach (dchar d; s[i .. slen])\n            {\n                encode(r, d);\n            }\n            break;\n        }\n    }\n    return cast(string)r;\n}\n\n/* =================== Conversion to UTF16 ======================= */\n\n@safe pure nothrow @nogc\nwchar[] toUTF16(wchar[] buf, dchar c)\n    in\n    {\n        assert(isValidDchar(c));\n    }\n    do\n    {\n        if (c <= 0xFFFF)\n        {\n            buf[0] = cast(wchar) c;\n            return buf[0 .. 1];\n        }\n        else\n        {\n            buf[0] = cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);\n            buf[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00);\n            return buf[0 .. 2];\n        }\n    }\n\n/****************\n * Encodes string s into UTF-16 and returns the encoded string.\n * toUTF16z() is suitable for calling the 'W' functions in the Win32 API that take\n * an LPWSTR or LPCWSTR argument.\n */\n@trusted pure\nwstring toUTF16(in char[] s)\n{\n    wchar[] r;\n    size_t slen = s.length;\n\n    if (!__ctfe)\n    {\n        // Reserve still does a lot if slen is zero.\n        // Return early for that case.\n        if (0 == slen)\n            return \"\"w;\n        r.reserve(slen);\n    }\n    for (size_t i = 0; i < slen; )\n    {\n        dchar c = s[i];\n        if (c <= 0x7F)\n        {\n            i++;\n            r ~= cast(wchar)c;\n        }\n        else\n        {\n            c = decode(s, i);\n            encode(r, c);\n        }\n    }\n    return cast(wstring)r;\n}\n\nalias const(wchar)* wptr;\n/** ditto */\n@safe pure\nwptr toUTF16z(in char[] s)\n{\n    wchar[] r;\n    size_t slen = s.length;\n\n    if (!__ctfe)\n    {\n        // Reserve still does a lot if slen is zero.\n        // Return early for that case.\n        if (0 == slen)\n            return &\"\\0\"w[0];\n        r.reserve(slen + 1);\n    }\n    for (size_t i = 0; i < slen; )\n    {\n        dchar c = s[i];\n        if (c <= 0x7F)\n        {\n            i++;\n            r ~= cast(wchar)c;\n        }\n        else\n        {\n            c = decode(s, i);\n            encode(r, c);\n        }\n    }\n    r ~= '\\000';\n    return &r[0];\n}\n\n/** ditto */\n@safe pure nothrow\nwstring toUTF16(wstring s)\n    in\n    {\n        validate(s);\n    }\n    do\n    {\n        return s;\n    }\n\n/** ditto */\n@trusted pure nothrow\nwstring toUTF16(in dchar[] s)\n{\n    wchar[] r;\n    size_t slen = s.length;\n\n    if (!__ctfe)\n    {\n        // Reserve still does a lot if slen is zero.\n        // Return early for that case.\n        if (0 == slen)\n            return \"\"w;\n        r.reserve(slen);\n    }\n    for (size_t i = 0; i < slen; i++)\n    {\n        encode(r, s[i]);\n    }\n    return cast(wstring)r;\n}\n\n/* =================== Conversion to UTF32 ======================= */\n\n/*****\n * Encodes string s into UTF-32 and returns the encoded string.\n */\n@trusted pure\ndstring toUTF32(in char[] s)\n{\n    dchar[] r;\n    size_t slen = s.length;\n    size_t j = 0;\n\n    r.length = slen;            // r[] will never be longer than s[]\n    for (size_t i = 0; i < slen; )\n    {\n        dchar c = s[i];\n        if (c >= 0x80)\n            c = decode(s, i);\n        else\n            i++;                // c is ascii, no need for decode\n        r[j++] = c;\n    }\n    return cast(dstring)r[0 .. j];\n}\n\n/** ditto */\n@trusted pure\ndstring toUTF32(in wchar[] s)\n{\n    dchar[] r;\n    size_t slen = s.length;\n    size_t j = 0;\n\n    r.length = slen;            // r[] will never be longer than s[]\n    for (size_t i = 0; i < slen; )\n    {\n        dchar c = s[i];\n        if (c >= 0x80)\n            c = decode(s, i);\n        else\n            i++;                // c is ascii, no need for decode\n        r[j++] = c;\n    }\n    return cast(dstring)r[0 .. j];\n}\n\n/** ditto */\n@safe pure nothrow\ndstring toUTF32(dstring s)\n    in\n    {\n        validate(s);\n    }\n    do\n    {\n        return s;\n    }\n\n/* ================================ tests ================================== */\n\nunittest\n{\n    debug(utf) printf(\"utf.toUTF.unittest\\n\");\n\n    auto c = \"hello\"c[];\n    auto w = toUTF16(c);\n    assert(w == \"hello\");\n    auto d = toUTF32(c);\n    assert(d == \"hello\");\n\n    c = toUTF8(w);\n    assert(c == \"hello\");\n    d = toUTF32(w);\n    assert(d == \"hello\");\n\n    c = toUTF8(d);\n    assert(c == \"hello\");\n    w = toUTF16(d);\n    assert(w == \"hello\");\n\n\n    c = \"hel\\u1234o\";\n    w = toUTF16(c);\n    assert(w == \"hel\\u1234o\");\n    d = toUTF32(c);\n    assert(d == \"hel\\u1234o\");\n\n    c = toUTF8(w);\n    assert(c == \"hel\\u1234o\");\n    d = toUTF32(w);\n    assert(d == \"hel\\u1234o\");\n\n    c = toUTF8(d);\n    assert(c == \"hel\\u1234o\");\n    w = toUTF16(d);\n    assert(w == \"hel\\u1234o\");\n\n\n    c = \"he\\U000BAAAAllo\";\n    w = toUTF16(c);\n    //foreach (wchar c; w) printf(\"c = x%x\\n\", c);\n    //foreach (wchar c; cast(wstring)\"he\\U000BAAAAllo\") printf(\"c = x%x\\n\", c);\n    assert(w == \"he\\U000BAAAAllo\");\n    d = toUTF32(c);\n    assert(d == \"he\\U000BAAAAllo\");\n\n    c = toUTF8(w);\n    assert(c == \"he\\U000BAAAAllo\");\n    d = toUTF32(w);\n    assert(d == \"he\\U000BAAAAllo\");\n\n    c = toUTF8(d);\n    assert(c == \"he\\U000BAAAAllo\");\n    w = toUTF16(d);\n    assert(w == \"he\\U000BAAAAllo\");\n\n    wchar[2] buf;\n    auto ret = toUTF16(buf, '\\U000BAAAA');\n    assert(ret == \"\\U000BAAAA\");\n}\n"
  },
  {
    "path": "libphobos/m4/autoconf.m4",
    "content": "#\n# Minimal autoconf support for the D language.\n# Adapted from the Go language support files.\n#\n\n# ------------------- #\n# Language selection.\n# ------------------- #\n\n# AC_LANG(D)\n# -----------\nAC_LANG_DEFINE([D], [d], [GDC], [],\n[ac_ext=d\nac_compile='$GDC -c $GDCFLAGS conftest.$ac_ext >&AS_MESSAGE_LOG_FD'\nac_link='$GDC -o conftest$ac_exeext $GDCFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&AS_MESSAGE_LOG_FD'\nac_compiler_gnu=yes\n])\n\n# AC_LANG_D\n# ----------\nAU_DEFUN([AC_LANG_D], [AC_LANG(D)])\n\n# ------------------- #\n# Producing programs.\n# ------------------- #\n\n# AC_LANG_PROGRAM(D)([PROLOGUE], [BODY])\n# ---------------------------------------\nm4_define([AC_LANG_PROGRAM(D)],\n[module mod;\n$1\n\nextern(C) int main() {\n  $2\n}])\n\n# _AC_LANG_IO_PROGRAM(D)\n# -----------------------\n# Produce source that performs I/O.\nm4_define([_AC_LANG_IO_PROGRAM(D)],\n[AC_LANG_PROGRAM([import core.stdc.stdio;],\n[FILE *f = fopen (\"conftest.out\", \"w\");\n return ferror (f) || fclose (f) != 0;\n])])\n\n# AC_LANG_CALL(D)(PROLOGUE, FUNCTION)\n# ------------------------------------\n# TODO: Avoid conflicting decl of main?\n# Used by AC_SEARCH_LIBS.\nm4_define([AC_LANG_CALL(D)],\n[AC_LANG_PROGRAM([$1 extern(C) int $2();], [$2(); return 0;])])\n\n# AC_LANG_FUNC_LINK_TRY(D)(FUNCTION)\n# -----------------------------------\n# Try to link a program which calls FUNCTION.\n# This only works for extern(C) functions.\nm4_define([AC_LANG_FUNC_LINK_TRY(D)],\n[AC_LANG_PROGRAM([extern(C) int $1();], [return $1();])])\n\n# AC_LANG_BOOL_COMPILE_TRY(D)(PROLOGUE, EXPRESSION)\n# --------------------------------------------------\n# Return a program which is valid if EXPRESSION is nonzero.\n# Probably not that useful for D, we can extract any information\n# we need using CTFE.\nm4_define([AC_LANG_BOOL_COMPILE_TRY(D)],\n[AC_LANG_PROGRAM([$1],\n[static assert($2); return 0;])])\n\n# AC_LANG_INT_SAVE(D)(PROLOGUE, EXPRESSION)\n# ------------------------------------------\nm4_define([AC_LANG_INT_SAVE(D)],\n[AC_LANG_PROGRAM([$1\nimport core.stdc.stdio, core.stdc.stdlib;\n],\n[\n  FILE *f = fopen (\"conftest.val\", \"w\");\n  if (! f)\n    return 1;\n  if (($2) < 0)\n    {\n      fprintf (f, \"%ld\", $2);\n    }\n  else\n    {\n      fprintf (f, \"%lu\", $2);\n    }\n  /* Do not output a trailing newline, as this causes \\r\\n confusion\n     on some platforms.  */\n  return ferror (f) || fclose (f) != 0;\n])])\n\n# ---------------------- #\n# Looking for compilers. #\n# ---------------------- #\n\n# AC_LANG_COMPILER(D)\n# --------------------\nAC_DEFUN([AC_LANG_COMPILER(D)],\n[AC_REQUIRE([AC_PROG_GDC])])\n\n# AC_PROG_GDC\n# ----------\nAN_MAKEVAR([GDC], [AC_PROG_GDC])\nAN_PROGRAM([gdc], [AC_PROG_GDC])\nAC_DEFUN([AC_PROG_GDC],\n[AC_LANG_PUSH(D)dnl\nAC_ARG_VAR([GDC],     [D compiler command])dnl\nAC_ARG_VAR([GDCFLAGS],  [D compiler flags])dnl\n_AC_ARG_VAR_LDFLAGS()dnl\nm4_ifval([$1],\n      [AC_CHECK_TOOLS(GDC, [$1])],\n[AC_CHECK_TOOL(GDC, gdc)\nif test -z \"$GDC\"; then\n  if test -n \"$ac_tool_prefix\"; then\n    AC_CHECK_PROG(GDC, [${ac_tool_prefix}gdc], [$ac_tool_prefix}gdc])\n  fi\nfi\nif test -z \"$GDC\"; then\n  AC_CHECK_PROG(GDC, gdc, gdc, , , false)\nfi\n])\n\n# Provide some information about the compiler.\n_AS_ECHO_LOG([checking for _AC_LANG compiler version])\nset X $ac_compile\nac_compiler=$[2]\n_AC_DO_LIMIT([$ac_compiler --version >&AS_MESSAGE_LOG_FD])\nm4_expand_once([_AC_COMPILER_EXEEXT])[]dnl\nm4_expand_once([_AC_COMPILER_OBJEXT])[]dnl\nAC_LANG_POP(D)dnl\n])# AC_PROG_D\n\n"
  },
  {
    "path": "libphobos/m4/druntime/cpu.m4",
    "content": "#\n# Contains macros to detect CPU features.\n#\n\n\n# DRUNTIME_ENABLE_ATOMIC_BUILTINS\n# -------------------------\n# Check support for atomic builtins up to 64 bit.\nAC_DEFUN([DRUNTIME_ENABLE_ATOMIC_BUILTINS],\n[\n  # This checks to see if the host supports the compiler-generated builtins\n  # for atomic operations for various integral sizes. Note, this is intended\n  # to be an all-or-nothing switch, so all the atomic operations that are\n  # used should be checked.\n  AC_MSG_CHECKING([for atomic builtins for byte])\n  AC_CACHE_VAL(druntime_cv_atomic_byte, [\n    AC_TRY_LINK(\n      [import gcc.builtins;], [\n      shared(byte) c1;\n       byte c2, c3;\n       __atomic_compare_exchange_1(&c1, &c2, c3, false, 5, 5);\n       __atomic_load_1(&c1, 5);\n       __atomic_store_1(&c1, c2, 5);\n       return 0;\n      ],\n      [druntime_cv_atomic_byte=yes],\n      [druntime_cv_atomic_byte=no])\n  ])\n  AC_MSG_RESULT($druntime_cv_atomic_byte)\n\n  AC_MSG_CHECKING([for atomic builtins for short])\n  AC_CACHE_VAL(druntime_cv_atomic_short, [\n    AC_TRY_LINK(\n      [import gcc.builtins;], [\n      shared(short) c1;\n       short c2, c3;\n       __atomic_compare_exchange_2(&c1, &c2, c3, false, 5, 5);\n       __atomic_load_2(&c1, 5);\n       __atomic_store_2(&c1, c2, 5);\n       return 0;\n      ],\n      [druntime_cv_atomic_short=yes],\n      [druntime_cv_atomic_short=no])\n  ])\n  AC_MSG_RESULT($druntime_cv_atomic_short)\n\n  AC_MSG_CHECKING([for atomic builtins for int])\n  AC_CACHE_VAL(druntime_cv_atomic_int, [\n    AC_TRY_LINK(\n      [import gcc.builtins;], [\n      shared(int) c1;\n       int c2, c3;\n       __atomic_compare_exchange_4(&c1, &c2, c3, false, 5, 5);\n       __atomic_load_4(&c1, 5);\n       __atomic_store_4(&c1, c2, 5);\n       return 0;\n      ],\n      [druntime_cv_atomic_int=yes],\n      [druntime_cv_atomic_int=no])\n  ])\n  AC_MSG_RESULT($druntime_cv_atomic_int)\n\n  AC_MSG_CHECKING([for atomic builtins for long])\n  AC_CACHE_VAL(druntime_cv_atomic_long, [\n    AC_TRY_LINK(\n      [import gcc.builtins;], [\n       shared(long) c1;\n       long c2, c3;\n       __atomic_compare_exchange_8(&c1, &c2, c3, false, 5, 5);\n       __atomic_load_8(&c1, 5);\n       __atomic_store_8(&c1, c2, 5);\n       return 0;\n      ],\n      [druntime_cv_atomic_long=yes],\n      [druntime_cv_atomic_long=no])\n  ])\n  AC_MSG_RESULT($druntime_cv_atomic_long)\n\n  # Have atomic builtin support if all but the long test above passes.\n  DCFG_HAVE_ATOMIC_BUILTINS=false\n  if test \"$druntime_cv_atomic_byte\" = yes \\\n     && test \"$druntime_cv_atomic_short\" = yes \\\n     && test \"$druntime_cv_atomic_int\" = yes; then \\\n    DCFG_HAVE_ATOMIC_BUILTINS=true\n  fi\n\n  # Have 64-bit atomic support if the long test above passes.\n  DCFG_HAVE_64BIT_ATOMICS=false\n  if test \"$druntime_cv_atomic_long\" = yes; then\n    DCFG_HAVE_64BIT_ATOMICS=true\n  fi\n\n  AC_SUBST(DCFG_HAVE_ATOMIC_BUILTINS)\n  AC_SUBST(DCFG_HAVE_64BIT_ATOMICS)\n])\n"
  },
  {
    "path": "libphobos/m4/druntime/libraries.m4",
    "content": "#\n# Contains macros to handle library dependencies.\n#\n\n\n# DRUNTIME_LIBRARIES_THREAD\n# -------------------------\n# Allow specifying the thread library to link with or autodetect\n# Add thread library to LIBS if necessary.\nAC_DEFUN([DRUNTIME_LIBRARIES_THREAD],\n[\n  enable_thread_lib=yes\n  AC_ARG_ENABLE(thread-lib,\n    AC_HELP_STRING([--enable-thread-lib=<arg>],\n                   [specify linker option for the system thread library (default: autodetect)]))\n\n  AS_IF([test \"x$enable_thread_lib\" = \"xyes\"], [\n    AC_SEARCH_LIBS([pthread_create], [pthread])\n  ], [\n    AS_IF([test \"x$enable_thread_lib\" = \"xno\"], [\n      AC_MSG_CHECKING([for thread library])\n      AC_MSG_RESULT([disabled])\n    ], [\n      AC_CHECK_LIB([$enable_thread_lib], [pthread_create], [], [\n        AC_MSG_ERROR([Thread library not found])\n      ])\n    ])\n  ])\n])\n\n\n# DRUNTIME_LIBRARIES_DLOPEN\n# -----------------------\n# Autodetect and add dl library to LIBS if necessary.\nAC_DEFUN([DRUNTIME_LIBRARIES_DLOPEN],\n[\n  # Libtool has already checked this, so re-use the inferred dlopen lib.\n  AS_IF([test \"x$enable_dlopen\" = \"xyes\" && test -n \"$lt_cv_dlopen_libs\"], [\n    LIBS=\"$LIBS $lt_cv_dlopen_libs\"\n  ], [\n  ])\n])\n\n\n# DRUNTIME_LIBRARIES_ZLIB\n# -----------------------\n# Allow specifying whether to use the system zlib or\n# compiling the zlib included in GCC. Define\n# DRUNTIME_ZLIB_SYSTEM conditional and add zlib to\n# LIBS if necessary.\nAC_DEFUN([DRUNTIME_LIBRARIES_ZLIB],\n[\n  AC_ARG_WITH(target-system-zlib,\n    AS_HELP_STRING([--with-target-system-zlib],\n                   [use installed libz (default: no)]))\n\n  system_zlib=false\n  AS_IF([test \"x$with_target_system_zlib\" = \"xyes\"], [\n    AC_CHECK_LIB([z], [deflate], [\n      system_zlib=yes\n    ], [\n      AC_MSG_ERROR([System zlib not found])\n    ])\n  ], [\n    AC_MSG_CHECKING([for zlib])\n    AC_MSG_RESULT([just compiled])\n  ])\n\n  AM_CONDITIONAL([DRUNTIME_ZLIB_SYSTEM], [test \"$with_target_system_zlib\" = yes])\n])\n\n# DRUNTIME_LIBRARIES_ATOMIC\n# -------------------------\n# Allow specifying whether to use libatomic for atomic support.\nAC_DEFUN([DRUNTIME_LIBRARIES_ATOMIC],\n[\n  AC_ARG_WITH(libatomic,\n    AS_HELP_STRING([--without-libatomic],\n                   [Do not use libatomic in core.atomic (default: auto)]))\n\n  DCFG_HAVE_LIBATOMIC=false\n  LIBATOMIC=\n  AS_IF([test \"x$with_libatomic\" != \"xno\"], [\n    DCFG_HAVE_LIBATOMIC=true\n    LIBATOMIC=../../libatomic/libatomic_convenience.la\n  ], [\n    AC_MSG_CHECKING([for libatomic])\n    AC_MSG_RESULT([disabled])\n  ])\n\n  AC_SUBST(DCFG_HAVE_LIBATOMIC)\n  AC_SUBST(LIBATOMIC)\n])\n\n# DRUNTIME_LIBRARIES_BACKTRACE\n# ---------------------------\n# Allow specifying whether to use libbacktrace for backtrace support.\n# Adds subsitute for BACKTRACE_SUPPORTED, BACKTRACE_USES_MALLOC,\n# and BACKTRACE_SUPPORTS_THREADS.\nAC_DEFUN([DRUNTIME_LIBRARIES_BACKTRACE],\n[\n  AC_LANG_PUSH([C])\n  BACKTRACE_SUPPORTED=false\n  BACKTRACE_USES_MALLOC=false\n  BACKTRACE_SUPPORTS_THREADS=false\n  LIBBACKTRACE=\"\"\n\n  AC_ARG_WITH(libbacktrace,\n    AS_HELP_STRING([--without-libbacktrace],\n                   [Do not use libbacktrace in core.runtime (default: auto)]))\n\n  AS_IF([test \"x$with_libbacktrace\" != \"xno\"], [\n    LIBBACKTRACE=../../libbacktrace/libbacktrace.la\n\n    gdc_save_CPPFLAGS=$CPPFLAGS\n    CPPFLAGS+=\" -I../libbacktrace \"\n\n    AC_CHECK_HEADER(backtrace-supported.h, have_libbacktrace_h=true,\n      have_libbacktrace_h=false)\n\n    if $have_libbacktrace_h; then\n      AC_MSG_CHECKING([libbacktrace: BACKTRACE_SUPPORTED])\n      AC_EGREP_CPP(FOUND_LIBBACKTRACE_RESULT_GDC,\n      [\n      #include <backtrace-supported.h>\n      #if BACKTRACE_SUPPORTED\n        FOUND_LIBBACKTRACE_RESULT_GDC\n      #endif\n      ], BACKTRACE_SUPPORTED=true, BACKTRACE_SUPPORTED=false)\n      AC_MSG_RESULT($BACKTRACE_SUPPORTED)\n\n      AC_MSG_CHECKING([libbacktrace: BACKTRACE_USES_MALLOC])\n      AC_EGREP_CPP(FOUND_LIBBACKTRACE_RESULT_GDC,\n      [\n      #include <backtrace-supported.h>\n      #if BACKTRACE_USES_MALLOC\n        FOUND_LIBBACKTRACE_RESULT_GDC\n      #endif\n      ], BACKTRACE_USES_MALLOC=true, BACKTRACE_USES_MALLOC=false)\n      AC_MSG_RESULT($BACKTRACE_USES_MALLOC)\n\n      AC_MSG_CHECKING([libbacktrace: BACKTRACE_SUPPORTS_THREADS])\n      AC_EGREP_CPP(FOUND_LIBBACKTRACE_RESULT_GDC,\n      [\n      #include <backtrace-supported.h>\n      #if BACKTRACE_SUPPORTS_THREADS\n        FOUND_LIBBACKTRACE_RESULT_GDC\n      #endif\n      ], BACKTRACE_SUPPORTS_THREADS=true, BACKTRACE_SUPPORTS_THREADS=false)\n      AC_MSG_RESULT($BACKTRACE_SUPPORTS_THREADS)\n    fi\n    CPPFLAGS=$gdc_save_CPPFLAGS\n  ], [\n    AC_MSG_CHECKING([for libbacktrace])\n    AC_MSG_RESULT([disabled])\n  ])\n\n  AC_SUBST(LIBBACKTRACE)\n  AC_SUBST(BACKTRACE_SUPPORTED)\n  AC_SUBST(BACKTRACE_USES_MALLOC)\n  AC_SUBST(BACKTRACE_SUPPORTS_THREADS)\n  AC_LANG_POP([C])\n])\n"
  },
  {
    "path": "libphobos/m4/druntime/os.m4",
    "content": "#\n# Contains macros to detect OS features.\n#\n\n\n# DRUNTIME_OS_THREAD_MODEL\n# ------------------------\n# Detect thread model and substitute DCFG_THREAD_MODEL\nAC_DEFUN([DRUNTIME_OS_THREAD_MODEL],\n[\n  AC_REQUIRE([AC_PROG_GDC])\n  AC_MSG_CHECKING([for thread model used by GDC])\n  d_thread_model=`$GDC -v 2>&1 | sed -n 's/^Thread model: //p'`\n  AC_MSG_RESULT([$d_thread_model])\n\n  # Map from thread model to thread interface.\n  DRUNTIME_CONFIGURE_THREADS([$d_thread_model])\n])\n\n\n# DRUNTIME_CONFIGURE_THREADS(thread_model)\n# ----------------------------------------\n# Map target os to D version identifier\nAC_DEFUN([DRUNTIME_CONFIGURE_THREADS],\n[\ncase $1 in\n    aix)    DCFG_THREAD_MODEL=\"Posix\" ;;\n    lynx)   DCFG_THREAD_MODEL=\"Posix\" ;;\n    posix)  DCFG_THREAD_MODEL=\"Posix\" ;;\n    single) DCFG_THREAD_MODEL=\"Single\" ;;\n    win32)  DCFG_THREAD_MODEL=\"Win32\" ;;\n    # TODO: These targets need porting.\n    dce|mipssde|rtems|tpf|vxworks)\n\t    DCFG_THREAD_MODEL=\"Single\" ;;\n    *)\t    as_fn_error \"Thread implementation '$1' not recognised\" \"$LINENO\" 5 ;;\nesac\nAC_SUBST(DCFG_THREAD_MODEL)\n])\n\n\n# DRUNTIME_OS_DETECT\n# ------------------\n# Set the druntime_cv_target_os variable\nAC_DEFUN([DRUNTIME_OS_DETECT],\n[\n  AC_CACHE_CHECK([[for target OS]],\n    [[druntime_cv_target_os]],\n    [[druntime_cv_target_os=`echo $target_os | sed 's/^\\([A-Za-z_]+\\)/\\1/'`]])\n    AS_IF([[test -z \"$druntime_cv_target_os\"]],\n      [AC_MSG_ERROR([[can't detect target OS]])],\n      [])\n])\n\n\n# DRUNTIME_OS_UNIX\n# ----------------\n# Add --enable-unix option or autodetects if system is unix\n# and create the DRUNTIME_OS_UNIX conditional.\nAC_DEFUN([DRUNTIME_OS_UNIX],\n[\n  AC_REQUIRE([DRUNTIME_OS_DETECT])\n  AC_ARG_ENABLE(unix,\n    AC_HELP_STRING([--enable-unix],\n                   [enables Unix runtime (default: yes, for Unix targets)]),\n    :,[enable_unix=auto])\n\n  case \"$druntime_cv_target_os\" in\n    aix*|*bsd*|cygwin*|darwin*|gnu*|linux*|skyos*|*solaris*|sysv*) d_have_unix=1 ;;\n  esac\n  if test -n \"$d_have_unix\" && test \"$enable_unix\" = auto ; then\n    enable_unix=yes\n  fi\n  AM_CONDITIONAL([DRUNTIME_OS_UNIX], [test \"$enable_unix\" = \"yes\"])\n])\n\n\n# DRUNTIME_OS_SOURCES\n# -------------------\n# Detect target OS and add DRUNTIME_OS_AIX DRUNTIME_OS_DARWIN\n# DRUNTIME_OS_DRAGONFLYBSD DRUNTIME_OS_FREEBSD DRUNTIME_OS_LINUX\n# DRUNTIME_OS_MINGW DRUNTIME_OS_SOLARIS DRUNTIME_OS_OPENBSD conditionals.\nAC_DEFUN([DRUNTIME_OS_SOURCES],\n[\n  AC_REQUIRE([DRUNTIME_OS_DETECT])\n\n  druntime_target_os_parsed=\"\"\n  case \"$druntime_cv_target_os\" in\n      aix*)    druntime_target_os_parsed=\"aix\"\n               ;;\n      *android*)\n               druntime_target_os_parsed=\"android\"\n               ;;\n      darwin*) druntime_target_os_parsed=\"darwin\"\n               ;;\n      dragonfly*) druntime_target_os_parsed=\"dragonfly\"\n               ;;\n      freebsd*|k*bsd*-gnu)\n               druntime_target_os_parsed=\"freebsd\"\n               ;;\n      openbsd*)\n               druntime_target_os_parsed=\"openbsd\"\n               ;;\n      netbsd*)\n               druntime_target_os_parsed=\"netbsd\"\n               ;;\n      linux*)  druntime_target_os_parsed=\"linux\"\n               ;;\n      mingw*)  druntime_target_os_parsed=\"mingw\"\n             ;;\n      *solaris*) druntime_target_os_parsed=\"solaris\"\n  esac\n  AM_CONDITIONAL([DRUNTIME_OS_AIX], [test \"$druntime_target_os_parsed\" = \"aix\"])\n  AM_CONDITIONAL([DRUNTIME_OS_ANDROID], [test \"$druntime_target_os_parsed\" = \"android\"])\n  AM_CONDITIONAL([DRUNTIME_OS_DARWIN], [test \"$druntime_target_os_parsed\" = \"darwin\"])\n  AM_CONDITIONAL([DRUNTIME_OS_DRAGONFLYBSD], [test \"$druntime_target_os_parsed\" = \"dragonfly\"])\n  AM_CONDITIONAL([DRUNTIME_OS_FREEBSD], [test \"$druntime_target_os_parsed\" = \"freebsd\"])\n  AM_CONDITIONAL([DRUNTIME_OS_NETBSD], [test \"$druntime_target_os_parsed\" = \"netbsd\"])\n  AM_CONDITIONAL([DRUNTIME_OS_OPENBSD], [test \"$druntime_target_os_parsed\" = \"openbsd\"])\n  AM_CONDITIONAL([DRUNTIME_OS_LINUX], [test \"$druntime_target_os_parsed\" = \"linux\"])\n  AM_CONDITIONAL([DRUNTIME_OS_MINGW], [test \"$druntime_target_os_parsed\" = \"mingw\"])\n  AM_CONDITIONAL([DRUNTIME_OS_SOLARIS], [test \"$druntime_target_os_parsed\" = \"solaris\"])\n])\n\n\n# DRUNTIME_OS_ARM_EABI_UNWINDER\n# ------------------------\n# Check if using ARM unwinder and substitute DCFG_ARM_EABI_UNWINDER\n# and set DRUNTIME_OS_ARM_EABI_UNWINDER conditional.\nAC_DEFUN([DRUNTIME_OS_ARM_EABI_UNWINDER],\n[\n  AC_LANG_PUSH([C])\n  AC_MSG_CHECKING([for ARM unwinder])\n  AC_TRY_COMPILE([#include <unwind.h>],[\n  #if __ARM_EABI_UNWINDER__\n  #error Yes, it is.\n  #endif\n  ],\n    [AC_MSG_RESULT([no])\n     DCFG_ARM_EABI_UNWINDER=false],\n    [AC_MSG_RESULT([yes])\n     DCFG_ARM_EABI_UNWINDER=true])\n  AC_SUBST(DCFG_ARM_EABI_UNWINDER)\n  AM_CONDITIONAL([DRUNTIME_OS_ARM_EABI_UNWINDER], [test \"$DCFG_ARM_EABI_UNWINDER\" = \"true\"])\n  AC_LANG_POP([C])\n])\n\n\n# DRUNTIME_OS_MINFO_BRACKETING\n# ----------------------------\n# Check if the linker provides __start_minfo and __stop_minfo symbols and\n# substitute DCFG_MINFO_BRACKETING.\nAC_DEFUN([DRUNTIME_OS_MINFO_BRACKETING],\n[\n  AC_LANG_PUSH([C])\n  AC_MSG_CHECKING([for minfo section bracketing])\n  AC_LINK_IFELSE([\n    void* module_info_ptr __attribute__((section (\"minfo\")));\n    extern void* __start_minfo __attribute__((visibility (\"hidden\")));\n    extern void* __stop_minfo __attribute__((visibility (\"hidden\")));\n\n    int main()\n    {\n        // Never run, just to prevent compiler from optimizing access\n        return &__start_minfo == &__stop_minfo;\n    }\n  ],\n    [AC_MSG_RESULT([yes])\n     DCFG_MINFO_BRACKETING=true],\n    [AC_MSG_RESULT([no])\n     DCFG_MINFO_BRACKETING=false])\n  AC_SUBST(DCFG_MINFO_BRACKETING)\n  AC_LANG_POP([C])\n])\n"
  },
  {
    "path": "libphobos/m4/druntime.m4",
    "content": "#\n# Contains some unsorted druntime utility macros.\n#\n\n\n# DRUNTIME_WERROR\n# ---------------\n# Check to see if -Werror is enabled.\nAC_DEFUN([DRUNTIME_WERROR],\n[\n  AC_ARG_ENABLE(werror, [AS_HELP_STRING([--enable-werror],\n                                        [turns on -Werror @<:@default=no@:>@])])\n  WERROR_FLAG=\"\"\n  if test \"x$enable_werror\" = \"xyes\"; then\n      WERROR_FLAG=\"-Werror\"\n  fi\n])\n\n\n# DRUNTIME_CONFIGURE\n# ------------------\n# Substitute absolute paths for srcdir and builddir.\nAC_DEFUN([DRUNTIME_CONFIGURE],\n[\n  # These need to be absolute paths, yet at the same time need to\n  # canonicalize only relative paths, because then amd will not unmount\n  # drives. Thus the use of PWDCMD: set it to 'pawd' or 'amq -w' if using amd.\n  libphobos_builddir=`${PWDCMD-pwd}`\n  case $srcdir in\n    [\\\\/$]* | ?:[\\\\/]*) libphobos_srcdir=${srcdir} ;;\n    *) libphobos_srcdir=`cd \"$srcdir\" && ${PWDCMD-pwd} || echo \"$srcdir\"` ;;\n  esac\n  AC_SUBST(libphobos_builddir)\n  AC_SUBST(libphobos_srcdir)\n])\n\n# DRUNTIME_MULTILIB\n# -----------------\n# Prepare the multilib_arg variable\nAC_DEFUN([DRUNTIME_MULTILIB],\n[\n  if test ${multilib} = yes; then\n    multilib_arg=\"--enable-multilib\"\n  else\n    multilib_arg=\n  fi\n])\n\n\n# DRUNTIME_INSTALL_DIRECTORIES\n# ----------------------------\n# Setup various install directories for headers.\n# Add the cross-host option and substitute the toolexecdir\n# toolexeclibdir and gdc_include_dir variables.\nAC_DEFUN([DRUNTIME_INSTALL_DIRECTORIES],\n[\n  AC_REQUIRE([AC_PROG_GDC])\n\n  AC_MSG_CHECKING([D GCC version])\n  gcc_version=`eval $get_gcc_base_ver $srcdir/../gcc/BASE-VER`\n  AC_MSG_RESULT($gcc_version)\n  AC_SUBST(gcc_version)\n\n  AC_ARG_WITH([cross-host],\n    AC_HELP_STRING([--with-cross-host=HOST],\n                   [configuring with a cross compiler]))\n\n  toolexecdir=no\n  toolexeclibdir=no\n\n  version_specific_libs=no\n\n  # Version-specific runtime libs processing.\n  if test $version_specific_libs = yes; then\n      toolexecdir='${libdir}/gcc/${host_alias}'\n      toolexeclibdir='${toolexecdir}/${gcc_version}$(MULTISUBDIR)'\n  else\n      # Calculate toolexecdir, toolexeclibdir\n      # Install a library built with a cross compiler in tooldir, not libdir.\n      if test -n \"$with_cross_host\" && test x\"$with_cross_host\" != x\"no\"; then\n          toolexecdir='${exec_prefix}/${host_alias}'\n          toolexeclibdir='${toolexecdir}/lib'\n      else\n          toolexecdir='${libdir}/gcc/${host_alias}'\n          toolexeclibdir='${libdir}'\n      fi\n      multi_os_directory=`$GDC -print-multi-os-directory`\n      case $multi_os_directory in\n          .) ;; # Avoid trailing /.\n          *) toolexeclibdir=${toolexeclibdir}/${multi_os_directory} ;;\n      esac\n  fi\n  AC_SUBST(toolexecdir)\n  AC_SUBST(toolexeclibdir)\n\n  # Default case for install directory for D sources files.\n  gdc_include_dir='$(libdir)/gcc/${target_alias}/${gcc_version}/include/d'\n  AC_SUBST(gdc_include_dir)\n])\n\n\n# DRUNTIME_GC\n# -----------\n# Add the --enable-druntime-gc option and create the\n# DRUNTIME_GC_ENABLE conditional\nAC_DEFUN([DRUNTIME_GC],\n[\n  dnl switch between gc and gcstub\n  AC_ARG_ENABLE(druntime-gc,\n    AC_HELP_STRING([--enable-druntime-gc],\n                   [enable D runtime garbage collector (default: yes)]),\n    [enable_druntime_gc=no],[enable_druntime_gc=yes])\n\n  AM_CONDITIONAL([DRUNTIME_GC_ENABLE], [test \"$enable_druntime_gc\" = \"yes\"])\n])\n"
  },
  {
    "path": "libphobos/m4/gcc_support.m4",
    "content": "#\n# Contains macros to allow building libphobos as part of GCC.\n# This includes macros to locate directories and do configure checks\n# without an installed libdruntime.\n#\n\n\n# PHOBOS_ABS_SRCDIR\n# -----------------\n# Find absolute top level source directory and set phobos_cv_abs_srcdir\nAC_DEFUN([PHOBOS_ABS_SRCDIR], [\n  dnl Not sure if 100% portable, but we need the absolute dir as the _LT_COMPILER_C_O\n  dnl test changes the directory\n  AC_CACHE_CHECK([[for absolute libphobos source path]],\n    [[phobos_cv_abs_srcdir]],\n    [[phobos_cv_abs_srcdir=`cd $srcdir && pwd`]])\n    AS_IF([[test -d \"$phobos_cv_abs_srcdir\"]],\n      [],\n      [AC_MSG_ERROR([[can't find absolute libphobos source path]])])\n])\n\n\n# WITH_LOCAL_DRUNTIME(CALL, EXTRAFLAGS)\n# -------------------------------------\n# Execute CALL with GDCFLAGS adjusted to use the local druntime includes.\n# Flags contains extra arguments to append to GDCFLAGS (e.g. -nophoboslib).\nAC_DEFUN([WITH_LOCAL_DRUNTIME], [\n  AC_REQUIRE([PHOBOS_ABS_SRCDIR])\n  gdc_save_DFLAGS=$GDCFLAGS\n  GDCFLAGS=\"-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $2 $GDCFLAGS\"\n  $1\n  GDCFLAGS=$gdc_save_DFLAGS\n])\n"
  },
  {
    "path": "libphobos/m4/gdc.m4",
    "content": "#\n# GDC feature checking and sanity check macros\n#\n\n\n# GDC_CHECK_COMPILE\n# -----------------\n# Check if compiler can compile D code\nAC_DEFUN([GDC_CHECK_COMPILE],\n[\n  AC_LANG_PUSH(D)\n    AC_MSG_CHECKING([[If $GDC can compile D sources]])\n    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[return 0;]])],\n      [AC_MSG_RESULT([[yes]])],\n      [AC_MSG_RESULT([[no]])\n       AC_MSG_ERROR([[can't compile D sources!]])])\n  AC_LANG_POP(D)\n])\n"
  },
  {
    "path": "libphobos/m4/libtool.m4",
    "content": "#\n# Minimal libtool support for the D language.\n# Adapted from the Go language support files.\n#\n\n# _LT_LANG_D_CONFIG([TAG])\n# --------------------------\n# Ensure that the configuration variables for the GNU D compiler\n# are suitably defined.  These variables are subsequently used by _LT_CONFIG\n# to write the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_D_CONFIG],\n[AC_REQUIRE([AC_PROG_GDC])dnl\nAC_LANG_SAVE\n\n# Source file extension for D test sources.\nac_ext=d\n\n# Object file extension for compiled D test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# Code to be used in simple compile tests\nlt_simple_compile_test_code=\"module mod; extern(C) int main() { return 0; }\"\n\n# Code to be used in simple link tests\nlt_simple_link_test_code='module mod; extern(C) int main() { return 0; }'\n\n# ltmain only uses $CC for tagged configurations so make sure $CC is set.\n_LT_TAG_COMPILER\n\n# save warnings/boilerplate of simple test code\n_LT_COMPILER_BOILERPLATE\n_LT_LINKER_BOILERPLATE\n\n# Allow CC to be a program name with arguments.\nlt_save_CC=$CC\nlt_save_CFLAGS=$CFLAGS\nlt_save_DFLAGS=$GDCFLAGS\nlt_save_GCC=$GCC\nGCC=yes\nCC=${GDC-\"gdc\"}\n# Need to specify location for object.d\nGDCFLAGS=\"-nophoboslib $GDCFLAGS\"\nCFLAGS=$GDCFLAGS\ncompiler=$CC\n_LT_TAGVAR(compiler, $1)=$CC\n_LT_TAGVAR(LD, $1)=$CC\n_LT_CC_BASENAME([$compiler])\n\n# GDC did not exist at the time GCC didn't implicitly link libc in.\n_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n\n_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds\n_LT_TAGVAR(reload_flag, $1)=$reload_flag\n_LT_TAGVAR(reload_cmds, $1)=$reload_cmds\n\n## CAVEAT EMPTOR:\n## There is no encapsulation within the following macros, do not change\n## the running order or otherwise move them around unless you know exactly\n## what you are doing...\nif test -n \"$compiler\"; then\n  _LT_COMPILER_NO_RTTI($1)\n  _LT_COMPILER_PIC($1)\n  _LT_COMPILER_C_O($1)\n  _LT_COMPILER_FILE_LOCKS($1)\n  _LT_LINKER_SHLIBS($1)\n  _LT_LINKER_HARDCODE_LIBPATH($1)\n\n  _LT_CONFIG($1)\nfi\n\nAC_LANG_RESTORE\n\nGCC=$lt_save_GCC\nCC=$lt_save_CC\nCFLAGS=$lt_save_CFLAGS\nGDCFLAGS=$lt_save_DFLAGS\n])# _LT_LANG_D_CONFIG\n"
  },
  {
    "path": "libphobos/src/LICENSE_1_0.txt",
    "content": "Boost Software License - Version 1.0 - August 17th, 2003\n\nPermission is hereby granted, free of charge, to any person or organization\nobtaining a copy of the software and accompanying documentation covered by\nthis license (the \"Software\") to use, reproduce, display, distribute,\nexecute, and transmit the Software, and to prepare derivative works of the\nSoftware, and to permit third-parties to whom the Software is furnished to\ndo so, all subject to the following:\n\nThe copyright notices in the Software and this entire statement, including\nthe above license grant, this restriction and the following disclaimer,\nmust be included in all copies of the Software, in whole or in part, and\nall derivative works of the Software, unless such copies or derivative\nworks are solely in the form of machine-executable object code generated by\na source language processor.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "libphobos/src/MERGE",
    "content": "f961aa86863938c964baea345684309b85021000\n\nThe first line of this file holds the git revision number of the last\nmerge done from the dlang/phobos repository.\n"
  },
  {
    "path": "libphobos/src/Makefile.am",
    "content": "## Makefile for the Phobos standard library.\n## Copyright (C) 2012-2018 Free Software Foundation, Inc.\n##\n## GCC is free software; you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation; either version 3, or (at your option)\n## any later version.\n##\n## GCC is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License\n## along with GCC; see the file COPYING3.  If not see\n## <http://www.gnu.org/licenses/>.\n\n# Include D build rules\ninclude $(top_srcdir)/d_rules.am\n\n# Make sure GDC can find libdruntime and libphobos include files\nD_EXTRA_DFLAGS=-nostdinc -I $(srcdir) \\\n\t-I $(top_srcdir)/libdruntime -I ../libdruntime -I .\n\n# C flags for zlib compilation\nAM_CFLAGS=@DEFS@ -I. -I$(srcdir)/../libdruntime/gcc -I$(top_srcdir)/../zlib\n\n# D flags for compilation\nAM_DFLAGS=$(phobos_compiler_pic_flag)\n\n# Install all D files\nALL_PHOBOS_INSTALL_DSOURCES = $(PHOBOS_DSOURCES)\n\n# Setup source files depending on configure\nALL_PHOBOS_COMPILE_DSOURCES = $(PHOBOS_DSOURCES)\n\nALL_PHOBOS_SOURCES = $(ALL_PHOBOS_COMPILE_DSOURCES)\nPHOBOS_TEST_LOBJECTS = $(ALL_PHOBOS_COMPILE_DSOURCES:.d=.t.lo)\nPHOBOS_TEST_OBJECTS = $(ALL_PHOBOS_COMPILE_DSOURCES:.d=.t.o)\n\n# Main library build definitions\nif DRUNTIME_ZLIB_SYSTEM\n    ZLIB_SRC =\nelse\n    ZLIB_SRC = $(ZLIB_CSOURCES)\nendif\ncheck_PROGRAMS =\nif ENABLE_SHARED\n    check_LTLIBRARIES = libgphobos_t.la\n    check_PROGRAMS += unittest\nendif\nif ENABLE_STATIC\n    check_PROGRAMS += unittest_static\nendif\n\ntoolexeclib_DATA = libgphobos.spec\ntoolexeclib_LTLIBRARIES = libgphobos.la\nlibgphobos_la_SOURCES = $(ALL_PHOBOS_SOURCES) $(ZLIB_SRC)\nlibgphobos_la_LIBTOOLFLAGS =\nlibgphobos_la_LDFLAGS = -Xcompiler -nophoboslib -version-info $(PHOBOS_SOVERSION)\nlibgphobos_la_LIBADD = ../libdruntime/libgdruntime.la\nlibgphobos_la_DEPENDENCIES = libgphobos.spec\n\n# For static unittest, link objects directly\nunittest_static_SOURCES = ../testsuite/test_runner.d $(ZLIB_SRC)\nunittest_static_LIBTOOLFLAGS =\nunittest_static_LDFLAGS = -Xcompiler -nophoboslib -static-libtool-libs\nunittest_static_LDADD = $(PHOBOS_TEST_OBJECTS) \\\n    ../libdruntime/libgdruntime.la\nEXTRA_unittest_static_DEPENDENCIES = $(PHOBOS_TEST_OBJECTS)\n\n# For unittest with dynamic library\nlibgphobos_t_la_SOURCES = $(ZLIB_SRC)\nlibgphobos_t_la_LIBTOOLFLAGS =\nlibgphobos_t_la_LDFLAGS = -Xcompiler -nophoboslib -rpath /foo -shared\nlibgphobos_t_la_LIBADD = $(PHOBOS_TEST_LOBJECTS) \\\n    ../libdruntime/libgdruntime.la\nEXTRA_libgphobos_t_la_DEPENDENCIES = $(PHOBOS_TEST_LOBJECTS)\n\n# For unittest\nunittest_SOURCES = ../testsuite/test_runner.d\nunittest_LIBTOOLFLAGS =\nunittest_LDFLAGS = -Xcompiler -nophoboslib -shared\nunittest_LDADD = libgphobos_t.la ../libdruntime/libgdruntime.la\n\n# Extra install and clean rules.\n# This does not delete the .libs/.t.o files, but deleting\n# the .lo is good enough to rerun the rules\nclean-local:\n\trm -f $(PHOBOS_TEST_LOBJECTS)\n\trm -f $(PHOBOS_TEST_OBJECTS)\n\n# Handles generated files as well\ninstall-data-local:\n\tfor file in $(ALL_PHOBOS_INSTALL_DSOURCES); do \\\n\t  if test -f $$file; then \\\n\t    $(INSTALL_HEADER) -D $$file $(DESTDIR)$(gdc_include_dir)/$$file ; \\\n\t  else \\\n\t    $(INSTALL_HEADER) -D $(srcdir)/$$file \\\n\t      $(DESTDIR)$(gdc_include_dir)/$$file ; \\\n\t  fi ; \\\n\tdone\n\n# Zlib sources when not using system libz\nZLIB_CSOURCES=$(top_srcdir)/../zlib/adler32.c $(top_srcdir)/../zlib/compress.c \\\n\t$(top_srcdir)/../zlib/crc32.c $(top_srcdir)/../zlib/deflate.c \\\n\t$(top_srcdir)/../zlib/gzclose.c $(top_srcdir)/../zlib/gzlib.c \\\n\t$(top_srcdir)/../zlib/gzread.c $(top_srcdir)/../zlib/gzwrite.c \\\n\t$(top_srcdir)/../zlib/infback.c $(top_srcdir)/../zlib/inffast.c \\\n\t$(top_srcdir)/../zlib/inflate.c $(top_srcdir)/../zlib/inftrees.c \\\n\t$(top_srcdir)/../zlib/trees.c $(top_srcdir)/../zlib/uncompr.c \\\n\t$(top_srcdir)/../zlib/zutil.c\n\n# Source file definitions. Boring stuff, auto-generated with\n# https://gist.github.com/jpf91/8744acebc9dcf1e9d1a35cdff20afbb2\n# Can't use wildcards here:\n# https://www.gnu.org/software/automake/manual/html_node/Wildcards.html\nPHOBOS_DSOURCES = etc/c/curl.d etc/c/sqlite3.d etc/c/zlib.d \\\n\tstd/algorithm/comparison.d std/algorithm/internal.d \\\n\tstd/algorithm/iteration.d std/algorithm/mutation.d \\\n\tstd/algorithm/package.d std/algorithm/searching.d \\\n\tstd/algorithm/setops.d std/algorithm/sorting.d std/array.d std/ascii.d \\\n\tstd/base64.d std/bigint.d std/bitmanip.d std/compiler.d std/complex.d \\\n\tstd/concurrency.d std/container/array.d std/container/binaryheap.d \\\n\tstd/container/dlist.d std/container/package.d std/container/rbtree.d \\\n\tstd/container/slist.d std/container/util.d std/conv.d std/csv.d \\\n\tstd/datetime/date.d std/datetime/interval.d std/datetime/package.d \\\n\tstd/datetime/stopwatch.d std/datetime/systime.d \\\n\tstd/datetime/timezone.d std/demangle.d std/digest/crc.d \\\n\tstd/digest/digest.d std/digest/hmac.d std/digest/md.d \\\n\tstd/digest/murmurhash.d std/digest/package.d std/digest/ripemd.d \\\n\tstd/digest/sha.d std/encoding.d std/exception.d std/experimental/all.d \\\n\tstd/experimental/allocator/building_blocks/affix_allocator.d \\\n\tstd/experimental/allocator/building_blocks/aligned_block_list.d \\\n\tstd/experimental/allocator/building_blocks/allocator_list.d \\\n\tstd/experimental/allocator/building_blocks/ascending_page_allocator.d \\\n\tstd/experimental/allocator/building_blocks/bitmapped_block.d \\\n\tstd/experimental/allocator/building_blocks/bucketizer.d \\\n\tstd/experimental/allocator/building_blocks/fallback_allocator.d \\\n\tstd/experimental/allocator/building_blocks/free_list.d \\\n\tstd/experimental/allocator/building_blocks/free_tree.d \\\n\tstd/experimental/allocator/building_blocks/kernighan_ritchie.d \\\n\tstd/experimental/allocator/building_blocks/null_allocator.d \\\n\tstd/experimental/allocator/building_blocks/package.d \\\n\tstd/experimental/allocator/building_blocks/quantizer.d \\\n\tstd/experimental/allocator/building_blocks/region.d \\\n\tstd/experimental/allocator/building_blocks/scoped_allocator.d \\\n\tstd/experimental/allocator/building_blocks/segregator.d \\\n\tstd/experimental/allocator/building_blocks/stats_collector.d \\\n\tstd/experimental/allocator/common.d \\\n\tstd/experimental/allocator/gc_allocator.d \\\n\tstd/experimental/allocator/mallocator.d \\\n\tstd/experimental/allocator/mmap_allocator.d \\\n\tstd/experimental/allocator/package.d \\\n\tstd/experimental/allocator/showcase.d \\\n\tstd/experimental/allocator/typed.d std/experimental/checkedint.d \\\n\tstd/experimental/logger/core.d std/experimental/logger/filelogger.d \\\n\tstd/experimental/logger/multilogger.d \\\n\tstd/experimental/logger/nulllogger.d std/experimental/logger/package.d \\\n\tstd/experimental/typecons.d std/file.d std/format.d std/functional.d \\\n\tstd/getopt.d std/internal/attributes.d std/internal/cstring.d \\\n\tstd/internal/math/biguintcore.d std/internal/math/biguintnoasm.d \\\n\tstd/internal/math/errorfunction.d std/internal/math/gammafunction.d \\\n\tstd/internal/scopebuffer.d std/internal/test/dummyrange.d \\\n\tstd/internal/test/range.d std/internal/test/uda.d \\\n\tstd/internal/unicode_comp.d std/internal/unicode_decomp.d \\\n\tstd/internal/unicode_grapheme.d std/internal/unicode_norm.d \\\n\tstd/internal/unicode_tables.d std/internal/windows/advapi32.d \\\n\tstd/json.d std/math.d std/mathspecial.d std/meta.d std/mmfile.d \\\n\tstd/net/curl.d std/net/isemail.d std/numeric.d std/outbuffer.d \\\n\tstd/parallelism.d std/path.d std/process.d std/random.d \\\n\tstd/range/interfaces.d std/range/package.d std/range/primitives.d \\\n\tstd/regex/internal/backtracking.d std/regex/internal/generator.d \\\n\tstd/regex/internal/ir.d std/regex/internal/kickstart.d \\\n\tstd/regex/internal/parser.d std/regex/internal/tests.d \\\n\tstd/regex/internal/tests2.d std/regex/internal/thompson.d \\\n\tstd/regex/package.d std/signals.d std/socket.d std/stdint.d \\\n\tstd/stdio.d std/string.d std/system.d std/traits.d std/typecons.d \\\n\tstd/typetuple.d std/uni.d std/uri.d std/utf.d std/uuid.d std/variant.d \\\n\tstd/windows/charset.d std/windows/registry.d std/windows/syserror.d \\\n\tstd/xml.d std/zip.d std/zlib.d\n"
  },
  {
    "path": "libphobos/src/Makefile.in",
    "content": "# Makefile.in generated by automake 1.11.6 from Makefile.am.\n# @configure_input@\n\n# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,\n# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software\n# Foundation, Inc.\n# This Makefile.in is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY, to the extent permitted by law; without\n# even the implied warranty of MERCHANTABILITY or FITNESS FOR A\n# PARTICULAR PURPOSE.\n\n@SET_MAKE@\n\n\nVPATH = @srcdir@\nam__make_dryrun = \\\n  { \\\n    am__dry=no; \\\n    case $$MAKEFLAGS in \\\n      *\\\\[\\ \\\t]*) \\\n        echo 'am--echo: ; @echo \"AM\"  OK' | $(MAKE) -f - 2>/dev/null \\\n          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \\\n      *) \\\n        for am__flg in $$MAKEFLAGS; do \\\n          case $$am__flg in \\\n            *=*|--*) ;; \\\n            *n*) am__dry=yes; break;; \\\n          esac; \\\n        done;; \\\n    esac; \\\n    test $$am__dry = yes; \\\n  }\npkgdatadir = $(datadir)/@PACKAGE@\npkgincludedir = $(includedir)/@PACKAGE@\npkglibdir = $(libdir)/@PACKAGE@\npkglibexecdir = $(libexecdir)/@PACKAGE@\nam__cd = CDPATH=\"$${ZSH_VERSION+.}$(PATH_SEPARATOR)\" && cd\ninstall_sh_DATA = $(install_sh) -c -m 644\ninstall_sh_PROGRAM = $(install_sh) -c\ninstall_sh_SCRIPT = $(install_sh) -c\nINSTALL_HEADER = $(INSTALL_DATA)\ntransform = $(program_transform_name)\nNORMAL_INSTALL = :\nPRE_INSTALL = :\nPOST_INSTALL = :\nNORMAL_UNINSTALL = :\nPRE_UNINSTALL = :\nPOST_UNINSTALL = :\nbuild_triplet = @build@\nhost_triplet = @host@\ntarget_triplet = @target@\nDIST_COMMON = $(top_srcdir)/d_rules.am $(srcdir)/Makefile.in \\\n\t$(srcdir)/Makefile.am $(srcdir)/libgphobos.spec.in\ncheck_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)\n@ENABLE_SHARED_TRUE@am__append_1 = unittest\n@ENABLE_STATIC_TRUE@am__append_2 = unittest_static\nsubdir = src\nACLOCAL_M4 = $(top_srcdir)/aclocal.m4\nam__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \\\n\t$(top_srcdir)/../config/lead-dot.m4 \\\n\t$(top_srcdir)/../config/multi.m4 \\\n\t$(top_srcdir)/../config/override.m4 \\\n\t$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \\\n\t$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \\\n\t$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \\\n\t$(top_srcdir)/m4/gcc_support.m4 $(top_srcdir)/m4/autoconf.m4 \\\n\t$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/gdc.m4 \\\n\t$(top_srcdir)/m4/druntime.m4 $(top_srcdir)/m4/druntime/cpu.m4 \\\n\t$(top_srcdir)/m4/druntime/os.m4 \\\n\t$(top_srcdir)/m4/druntime/libraries.m4 \\\n\t$(top_srcdir)/configure.ac\nam__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \\\n\t$(ACLOCAL_M4)\nmkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs\nCONFIG_HEADER = $(top_builddir)/config.h\nCONFIG_CLEAN_FILES = libgphobos.spec\nCONFIG_CLEAN_VPATH_FILES =\nam__vpath_adj_setup = srcdirstrip=`echo \"$(srcdir)\" | sed 's|.|.|g'`;\nam__vpath_adj = case $$p in \\\n    $(srcdir)/*) f=`echo \"$$p\" | sed \"s|^$$srcdirstrip/||\"`;; \\\n    *) f=$$p;; \\\n  esac;\nam__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;\nam__install_max = 40\nam__nobase_strip_setup = \\\n  srcdirstrip=`echo \"$(srcdir)\" | sed 's/[].[^$$\\\\*|]/\\\\\\\\&/g'`\nam__nobase_strip = \\\n  for p in $$list; do echo \"$$p\"; done | sed -e \"s|$$srcdirstrip/||\"\nam__nobase_list = $(am__nobase_strip_setup); \\\n  for p in $$list; do echo \"$$p $$p\"; done | \\\n  sed \"s| $$srcdirstrip/| |;\"' / .*\\//!s/ .*/ ./; s,\\( .*\\)/[^/]*$$,\\1,' | \\\n  $(AWK) 'BEGIN { files[\".\"] = \"\" } { files[$$2] = files[$$2] \" \" $$1; \\\n    if (++n[$$2] == $(am__install_max)) \\\n      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = \"\" } } \\\n    END { for (dir in files) print dir, files[dir] }'\nam__base_list = \\\n  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\\n/ /g' | \\\n  sed '$$!N;$$!N;$$!N;$$!N;s/\\n/ /g'\nam__uninstall_files_from_dir = { \\\n  test -z \"$$files\" \\\n    || { test ! -d \"$$dir\" && test ! -f \"$$dir\" && test ! -r \"$$dir\"; } \\\n    || { echo \" ( cd '$$dir' && rm -f\" $$files \")\"; \\\n         $(am__cd) \"$$dir\" && rm -f $$files; }; \\\n  }\nam__installdirs = \"$(DESTDIR)$(toolexeclibdir)\" \\\n\t\"$(DESTDIR)$(toolexeclibdir)\"\nLTLIBRARIES = $(toolexeclib_LTLIBRARIES)\nam__dirstamp = $(am__leading_dot)dirstamp\nam__objects_1 = etc/c/curl.lo etc/c/sqlite3.lo etc/c/zlib.lo \\\n\tstd/algorithm/comparison.lo std/algorithm/internal.lo \\\n\tstd/algorithm/iteration.lo std/algorithm/mutation.lo \\\n\tstd/algorithm/package.lo std/algorithm/searching.lo \\\n\tstd/algorithm/setops.lo std/algorithm/sorting.lo std/array.lo \\\n\tstd/ascii.lo std/base64.lo std/bigint.lo std/bitmanip.lo \\\n\tstd/compiler.lo std/complex.lo std/concurrency.lo \\\n\tstd/container/array.lo std/container/binaryheap.lo \\\n\tstd/container/dlist.lo std/container/package.lo \\\n\tstd/container/rbtree.lo std/container/slist.lo \\\n\tstd/container/util.lo std/conv.lo std/csv.lo \\\n\tstd/datetime/date.lo std/datetime/interval.lo \\\n\tstd/datetime/package.lo std/datetime/stopwatch.lo \\\n\tstd/datetime/systime.lo std/datetime/timezone.lo \\\n\tstd/demangle.lo std/digest/crc.lo std/digest/digest.lo \\\n\tstd/digest/hmac.lo std/digest/md.lo std/digest/murmurhash.lo \\\n\tstd/digest/package.lo std/digest/ripemd.lo std/digest/sha.lo \\\n\tstd/encoding.lo std/exception.lo std/experimental/all.lo \\\n\tstd/experimental/allocator/building_blocks/affix_allocator.lo \\\n\tstd/experimental/allocator/building_blocks/aligned_block_list.lo \\\n\tstd/experimental/allocator/building_blocks/allocator_list.lo \\\n\tstd/experimental/allocator/building_blocks/ascending_page_allocator.lo \\\n\tstd/experimental/allocator/building_blocks/bitmapped_block.lo \\\n\tstd/experimental/allocator/building_blocks/bucketizer.lo \\\n\tstd/experimental/allocator/building_blocks/fallback_allocator.lo \\\n\tstd/experimental/allocator/building_blocks/free_list.lo \\\n\tstd/experimental/allocator/building_blocks/free_tree.lo \\\n\tstd/experimental/allocator/building_blocks/kernighan_ritchie.lo \\\n\tstd/experimental/allocator/building_blocks/null_allocator.lo \\\n\tstd/experimental/allocator/building_blocks/package.lo \\\n\tstd/experimental/allocator/building_blocks/quantizer.lo \\\n\tstd/experimental/allocator/building_blocks/region.lo \\\n\tstd/experimental/allocator/building_blocks/scoped_allocator.lo \\\n\tstd/experimental/allocator/building_blocks/segregator.lo \\\n\tstd/experimental/allocator/building_blocks/stats_collector.lo \\\n\tstd/experimental/allocator/common.lo \\\n\tstd/experimental/allocator/gc_allocator.lo \\\n\tstd/experimental/allocator/mallocator.lo \\\n\tstd/experimental/allocator/mmap_allocator.lo \\\n\tstd/experimental/allocator/package.lo \\\n\tstd/experimental/allocator/showcase.lo \\\n\tstd/experimental/allocator/typed.lo \\\n\tstd/experimental/checkedint.lo std/experimental/logger/core.lo \\\n\tstd/experimental/logger/filelogger.lo \\\n\tstd/experimental/logger/multilogger.lo \\\n\tstd/experimental/logger/nulllogger.lo \\\n\tstd/experimental/logger/package.lo \\\n\tstd/experimental/typecons.lo std/file.lo std/format.lo \\\n\tstd/functional.lo std/getopt.lo std/internal/attributes.lo \\\n\tstd/internal/cstring.lo std/internal/math/biguintcore.lo \\\n\tstd/internal/math/biguintnoasm.lo \\\n\tstd/internal/math/errorfunction.lo \\\n\tstd/internal/math/gammafunction.lo std/internal/scopebuffer.lo \\\n\tstd/internal/test/dummyrange.lo std/internal/test/range.lo \\\n\tstd/internal/test/uda.lo std/internal/unicode_comp.lo \\\n\tstd/internal/unicode_decomp.lo \\\n\tstd/internal/unicode_grapheme.lo std/internal/unicode_norm.lo \\\n\tstd/internal/unicode_tables.lo \\\n\tstd/internal/windows/advapi32.lo std/json.lo std/math.lo \\\n\tstd/mathspecial.lo std/meta.lo std/mmfile.lo std/net/curl.lo \\\n\tstd/net/isemail.lo std/numeric.lo std/outbuffer.lo \\\n\tstd/parallelism.lo std/path.lo std/process.lo std/random.lo \\\n\tstd/range/interfaces.lo std/range/package.lo \\\n\tstd/range/primitives.lo std/regex/internal/backtracking.lo \\\n\tstd/regex/internal/generator.lo std/regex/internal/ir.lo \\\n\tstd/regex/internal/kickstart.lo std/regex/internal/parser.lo \\\n\tstd/regex/internal/tests.lo std/regex/internal/tests2.lo \\\n\tstd/regex/internal/thompson.lo std/regex/package.lo \\\n\tstd/signals.lo std/socket.lo std/stdint.lo std/stdio.lo \\\n\tstd/string.lo std/system.lo std/traits.lo std/typecons.lo \\\n\tstd/typetuple.lo std/uni.lo std/uri.lo std/utf.lo std/uuid.lo \\\n\tstd/variant.lo std/windows/charset.lo std/windows/registry.lo \\\n\tstd/windows/syserror.lo std/xml.lo std/zip.lo std/zlib.lo\nam__objects_2 = $(am__objects_1)\nam__objects_3 = $(am__objects_2)\nam__objects_4 = libgphobos_la-adler32.lo libgphobos_la-compress.lo \\\n\tlibgphobos_la-crc32.lo libgphobos_la-deflate.lo \\\n\tlibgphobos_la-gzclose.lo libgphobos_la-gzlib.lo \\\n\tlibgphobos_la-gzread.lo libgphobos_la-gzwrite.lo \\\n\tlibgphobos_la-infback.lo libgphobos_la-inffast.lo \\\n\tlibgphobos_la-inflate.lo libgphobos_la-inftrees.lo \\\n\tlibgphobos_la-trees.lo libgphobos_la-uncompr.lo \\\n\tlibgphobos_la-zutil.lo\n@DRUNTIME_ZLIB_SYSTEM_FALSE@am__objects_5 = $(am__objects_4)\nam_libgphobos_la_OBJECTS = $(am__objects_3) $(am__objects_5)\nlibgphobos_la_OBJECTS = $(am_libgphobos_la_OBJECTS)\nam__DEPENDENCIES_1 = etc/c/curl.t.lo etc/c/sqlite3.t.lo \\\n\tetc/c/zlib.t.lo std/algorithm/comparison.t.lo \\\n\tstd/algorithm/internal.t.lo std/algorithm/iteration.t.lo \\\n\tstd/algorithm/mutation.t.lo std/algorithm/package.t.lo \\\n\tstd/algorithm/searching.t.lo std/algorithm/setops.t.lo \\\n\tstd/algorithm/sorting.t.lo std/array.t.lo std/ascii.t.lo \\\n\tstd/base64.t.lo std/bigint.t.lo std/bitmanip.t.lo \\\n\tstd/compiler.t.lo std/complex.t.lo std/concurrency.t.lo \\\n\tstd/container/array.t.lo std/container/binaryheap.t.lo \\\n\tstd/container/dlist.t.lo std/container/package.t.lo \\\n\tstd/container/rbtree.t.lo std/container/slist.t.lo \\\n\tstd/container/util.t.lo std/conv.t.lo std/csv.t.lo \\\n\tstd/datetime/date.t.lo std/datetime/interval.t.lo \\\n\tstd/datetime/package.t.lo std/datetime/stopwatch.t.lo \\\n\tstd/datetime/systime.t.lo std/datetime/timezone.t.lo \\\n\tstd/demangle.t.lo std/digest/crc.t.lo std/digest/digest.t.lo \\\n\tstd/digest/hmac.t.lo std/digest/md.t.lo \\\n\tstd/digest/murmurhash.t.lo std/digest/package.t.lo \\\n\tstd/digest/ripemd.t.lo std/digest/sha.t.lo std/encoding.t.lo \\\n\tstd/exception.t.lo std/experimental/all.t.lo \\\n\tstd/experimental/allocator/building_blocks/affix_allocator.t.lo \\\n\tstd/experimental/allocator/building_blocks/aligned_block_list.t.lo \\\n\tstd/experimental/allocator/building_blocks/allocator_list.t.lo \\\n\tstd/experimental/allocator/building_blocks/ascending_page_allocator.t.lo \\\n\tstd/experimental/allocator/building_blocks/bitmapped_block.t.lo \\\n\tstd/experimental/allocator/building_blocks/bucketizer.t.lo \\\n\tstd/experimental/allocator/building_blocks/fallback_allocator.t.lo \\\n\tstd/experimental/allocator/building_blocks/free_list.t.lo \\\n\tstd/experimental/allocator/building_blocks/free_tree.t.lo \\\n\tstd/experimental/allocator/building_blocks/kernighan_ritchie.t.lo \\\n\tstd/experimental/allocator/building_blocks/null_allocator.t.lo \\\n\tstd/experimental/allocator/building_blocks/package.t.lo \\\n\tstd/experimental/allocator/building_blocks/quantizer.t.lo \\\n\tstd/experimental/allocator/building_blocks/region.t.lo \\\n\tstd/experimental/allocator/building_blocks/scoped_allocator.t.lo \\\n\tstd/experimental/allocator/building_blocks/segregator.t.lo \\\n\tstd/experimental/allocator/building_blocks/stats_collector.t.lo \\\n\tstd/experimental/allocator/common.t.lo \\\n\tstd/experimental/allocator/gc_allocator.t.lo \\\n\tstd/experimental/allocator/mallocator.t.lo \\\n\tstd/experimental/allocator/mmap_allocator.t.lo \\\n\tstd/experimental/allocator/package.t.lo \\\n\tstd/experimental/allocator/showcase.t.lo \\\n\tstd/experimental/allocator/typed.t.lo \\\n\tstd/experimental/checkedint.t.lo \\\n\tstd/experimental/logger/core.t.lo \\\n\tstd/experimental/logger/filelogger.t.lo \\\n\tstd/experimental/logger/multilogger.t.lo \\\n\tstd/experimental/logger/nulllogger.t.lo \\\n\tstd/experimental/logger/package.t.lo \\\n\tstd/experimental/typecons.t.lo std/file.t.lo std/format.t.lo \\\n\tstd/functional.t.lo std/getopt.t.lo \\\n\tstd/internal/attributes.t.lo std/internal/cstring.t.lo \\\n\tstd/internal/math/biguintcore.t.lo \\\n\tstd/internal/math/biguintnoasm.t.lo \\\n\tstd/internal/math/errorfunction.t.lo \\\n\tstd/internal/math/gammafunction.t.lo \\\n\tstd/internal/scopebuffer.t.lo \\\n\tstd/internal/test/dummyrange.t.lo std/internal/test/range.t.lo \\\n\tstd/internal/test/uda.t.lo std/internal/unicode_comp.t.lo \\\n\tstd/internal/unicode_decomp.t.lo \\\n\tstd/internal/unicode_grapheme.t.lo \\\n\tstd/internal/unicode_norm.t.lo \\\n\tstd/internal/unicode_tables.t.lo \\\n\tstd/internal/windows/advapi32.t.lo std/json.t.lo std/math.t.lo \\\n\tstd/mathspecial.t.lo std/meta.t.lo std/mmfile.t.lo \\\n\tstd/net/curl.t.lo std/net/isemail.t.lo std/numeric.t.lo \\\n\tstd/outbuffer.t.lo std/parallelism.t.lo std/path.t.lo \\\n\tstd/process.t.lo std/random.t.lo std/range/interfaces.t.lo \\\n\tstd/range/package.t.lo std/range/primitives.t.lo \\\n\tstd/regex/internal/backtracking.t.lo \\\n\tstd/regex/internal/generator.t.lo std/regex/internal/ir.t.lo \\\n\tstd/regex/internal/kickstart.t.lo \\\n\tstd/regex/internal/parser.t.lo std/regex/internal/tests.t.lo \\\n\tstd/regex/internal/tests2.t.lo \\\n\tstd/regex/internal/thompson.t.lo std/regex/package.t.lo \\\n\tstd/signals.t.lo std/socket.t.lo std/stdint.t.lo \\\n\tstd/stdio.t.lo std/string.t.lo std/system.t.lo std/traits.t.lo \\\n\tstd/typecons.t.lo std/typetuple.t.lo std/uni.t.lo std/uri.t.lo \\\n\tstd/utf.t.lo std/uuid.t.lo std/variant.t.lo \\\n\tstd/windows/charset.t.lo std/windows/registry.t.lo \\\n\tstd/windows/syserror.t.lo std/xml.t.lo std/zip.t.lo \\\n\tstd/zlib.t.lo\nam__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)\nam__DEPENDENCIES_3 = $(am__DEPENDENCIES_2)\nlibgphobos_t_la_DEPENDENCIES = $(am__DEPENDENCIES_3) \\\n\t../libdruntime/libgdruntime.la\nam__objects_6 = libgphobos_t_la-adler32.lo libgphobos_t_la-compress.lo \\\n\tlibgphobos_t_la-crc32.lo libgphobos_t_la-deflate.lo \\\n\tlibgphobos_t_la-gzclose.lo libgphobos_t_la-gzlib.lo \\\n\tlibgphobos_t_la-gzread.lo libgphobos_t_la-gzwrite.lo \\\n\tlibgphobos_t_la-infback.lo libgphobos_t_la-inffast.lo \\\n\tlibgphobos_t_la-inflate.lo libgphobos_t_la-inftrees.lo \\\n\tlibgphobos_t_la-trees.lo libgphobos_t_la-uncompr.lo \\\n\tlibgphobos_t_la-zutil.lo\n@DRUNTIME_ZLIB_SYSTEM_FALSE@am__objects_7 = $(am__objects_6)\nam_libgphobos_t_la_OBJECTS = $(am__objects_7)\nlibgphobos_t_la_OBJECTS = $(am_libgphobos_t_la_OBJECTS)\n@ENABLE_SHARED_TRUE@am_libgphobos_t_la_rpath =\n@ENABLE_SHARED_TRUE@am__EXEEXT_1 = unittest$(EXEEXT)\n@ENABLE_STATIC_TRUE@am__EXEEXT_2 = unittest_static$(EXEEXT)\nam_unittest_OBJECTS = ../testsuite/test_runner.$(OBJEXT)\nunittest_OBJECTS = $(am_unittest_OBJECTS)\nunittest_DEPENDENCIES = libgphobos_t.la ../libdruntime/libgdruntime.la\nam__objects_8 = adler32.$(OBJEXT) compress.$(OBJEXT) crc32.$(OBJEXT) \\\n\tdeflate.$(OBJEXT) gzclose.$(OBJEXT) gzlib.$(OBJEXT) \\\n\tgzread.$(OBJEXT) gzwrite.$(OBJEXT) infback.$(OBJEXT) \\\n\tinffast.$(OBJEXT) inflate.$(OBJEXT) inftrees.$(OBJEXT) \\\n\ttrees.$(OBJEXT) uncompr.$(OBJEXT) zutil.$(OBJEXT)\n@DRUNTIME_ZLIB_SYSTEM_FALSE@am__objects_9 = $(am__objects_8)\nam_unittest_static_OBJECTS = ../testsuite/test_runner.$(OBJEXT) \\\n\t$(am__objects_9)\nunittest_static_OBJECTS = $(am_unittest_static_OBJECTS)\nam__DEPENDENCIES_4 = etc/c/curl.t.o etc/c/sqlite3.t.o etc/c/zlib.t.o \\\n\tstd/algorithm/comparison.t.o std/algorithm/internal.t.o \\\n\tstd/algorithm/iteration.t.o std/algorithm/mutation.t.o \\\n\tstd/algorithm/package.t.o std/algorithm/searching.t.o \\\n\tstd/algorithm/setops.t.o std/algorithm/sorting.t.o \\\n\tstd/array.t.o std/ascii.t.o std/base64.t.o std/bigint.t.o \\\n\tstd/bitmanip.t.o std/compiler.t.o std/complex.t.o \\\n\tstd/concurrency.t.o std/container/array.t.o \\\n\tstd/container/binaryheap.t.o std/container/dlist.t.o \\\n\tstd/container/package.t.o std/container/rbtree.t.o \\\n\tstd/container/slist.t.o std/container/util.t.o std/conv.t.o \\\n\tstd/csv.t.o std/datetime/date.t.o std/datetime/interval.t.o \\\n\tstd/datetime/package.t.o std/datetime/stopwatch.t.o \\\n\tstd/datetime/systime.t.o std/datetime/timezone.t.o \\\n\tstd/demangle.t.o std/digest/crc.t.o std/digest/digest.t.o \\\n\tstd/digest/hmac.t.o std/digest/md.t.o \\\n\tstd/digest/murmurhash.t.o std/digest/package.t.o \\\n\tstd/digest/ripemd.t.o std/digest/sha.t.o std/encoding.t.o \\\n\tstd/exception.t.o std/experimental/all.t.o \\\n\tstd/experimental/allocator/building_blocks/affix_allocator.t.o \\\n\tstd/experimental/allocator/building_blocks/aligned_block_list.t.o \\\n\tstd/experimental/allocator/building_blocks/allocator_list.t.o \\\n\tstd/experimental/allocator/building_blocks/ascending_page_allocator.t.o \\\n\tstd/experimental/allocator/building_blocks/bitmapped_block.t.o \\\n\tstd/experimental/allocator/building_blocks/bucketizer.t.o \\\n\tstd/experimental/allocator/building_blocks/fallback_allocator.t.o \\\n\tstd/experimental/allocator/building_blocks/free_list.t.o \\\n\tstd/experimental/allocator/building_blocks/free_tree.t.o \\\n\tstd/experimental/allocator/building_blocks/kernighan_ritchie.t.o \\\n\tstd/experimental/allocator/building_blocks/null_allocator.t.o \\\n\tstd/experimental/allocator/building_blocks/package.t.o \\\n\tstd/experimental/allocator/building_blocks/quantizer.t.o \\\n\tstd/experimental/allocator/building_blocks/region.t.o \\\n\tstd/experimental/allocator/building_blocks/scoped_allocator.t.o \\\n\tstd/experimental/allocator/building_blocks/segregator.t.o \\\n\tstd/experimental/allocator/building_blocks/stats_collector.t.o \\\n\tstd/experimental/allocator/common.t.o \\\n\tstd/experimental/allocator/gc_allocator.t.o \\\n\tstd/experimental/allocator/mallocator.t.o \\\n\tstd/experimental/allocator/mmap_allocator.t.o \\\n\tstd/experimental/allocator/package.t.o \\\n\tstd/experimental/allocator/showcase.t.o \\\n\tstd/experimental/allocator/typed.t.o \\\n\tstd/experimental/checkedint.t.o \\\n\tstd/experimental/logger/core.t.o \\\n\tstd/experimental/logger/filelogger.t.o \\\n\tstd/experimental/logger/multilogger.t.o \\\n\tstd/experimental/logger/nulllogger.t.o \\\n\tstd/experimental/logger/package.t.o \\\n\tstd/experimental/typecons.t.o std/file.t.o std/format.t.o \\\n\tstd/functional.t.o std/getopt.t.o std/internal/attributes.t.o \\\n\tstd/internal/cstring.t.o std/internal/math/biguintcore.t.o \\\n\tstd/internal/math/biguintnoasm.t.o \\\n\tstd/internal/math/errorfunction.t.o \\\n\tstd/internal/math/gammafunction.t.o \\\n\tstd/internal/scopebuffer.t.o std/internal/test/dummyrange.t.o \\\n\tstd/internal/test/range.t.o std/internal/test/uda.t.o \\\n\tstd/internal/unicode_comp.t.o std/internal/unicode_decomp.t.o \\\n\tstd/internal/unicode_grapheme.t.o \\\n\tstd/internal/unicode_norm.t.o std/internal/unicode_tables.t.o \\\n\tstd/internal/windows/advapi32.t.o std/json.t.o std/math.t.o \\\n\tstd/mathspecial.t.o std/meta.t.o std/mmfile.t.o \\\n\tstd/net/curl.t.o std/net/isemail.t.o std/numeric.t.o \\\n\tstd/outbuffer.t.o std/parallelism.t.o std/path.t.o \\\n\tstd/process.t.o std/random.t.o std/range/interfaces.t.o \\\n\tstd/range/package.t.o std/range/primitives.t.o \\\n\tstd/regex/internal/backtracking.t.o \\\n\tstd/regex/internal/generator.t.o std/regex/internal/ir.t.o \\\n\tstd/regex/internal/kickstart.t.o std/regex/internal/parser.t.o \\\n\tstd/regex/internal/tests.t.o std/regex/internal/tests2.t.o \\\n\tstd/regex/internal/thompson.t.o std/regex/package.t.o \\\n\tstd/signals.t.o std/socket.t.o std/stdint.t.o std/stdio.t.o \\\n\tstd/string.t.o std/system.t.o std/traits.t.o std/typecons.t.o \\\n\tstd/typetuple.t.o std/uni.t.o std/uri.t.o std/utf.t.o \\\n\tstd/uuid.t.o std/variant.t.o std/windows/charset.t.o \\\n\tstd/windows/registry.t.o std/windows/syserror.t.o std/xml.t.o \\\n\tstd/zip.t.o std/zlib.t.o\nam__DEPENDENCIES_5 = $(am__DEPENDENCIES_4)\nam__DEPENDENCIES_6 = $(am__DEPENDENCIES_5)\nunittest_static_DEPENDENCIES = $(am__DEPENDENCIES_6) \\\n\t../libdruntime/libgdruntime.la\nDEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)\ndepcomp =\nam__depfiles_maybe =\nCOMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \\\n\t$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)\nLTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \\\n\t--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \\\n\t$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)\nLINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \\\n\t--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\nSOURCES = $(libgphobos_la_SOURCES) $(libgphobos_t_la_SOURCES) \\\n\t$(unittest_SOURCES) $(unittest_static_SOURCES)\nam__can_run_installinfo = \\\n  case $$AM_UPDATE_INFO_DIR in \\\n    n|no|NO) false;; \\\n    *) (install-info --version) >/dev/null 2>&1;; \\\n  esac\nDATA = $(toolexeclib_DATA)\nETAGS = etags\nCTAGS = ctags\nACLOCAL = @ACLOCAL@\nAMTAR = @AMTAR@\nAR = @AR@\nAUTOCONF = @AUTOCONF@\nAUTOHEADER = @AUTOHEADER@\nAUTOMAKE = @AUTOMAKE@\nAWK = @AWK@\nBACKTRACE_SUPPORTED = @BACKTRACE_SUPPORTED@\nBACKTRACE_SUPPORTS_THREADS = @BACKTRACE_SUPPORTS_THREADS@\nBACKTRACE_USES_MALLOC = @BACKTRACE_USES_MALLOC@\nCC = @CC@\nCCAS = @CCAS@\nCCASFLAGS = @CCASFLAGS@\nCC_FOR_BUILD = @CC_FOR_BUILD@\nCFLAGS = @CFLAGS@\nCFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@\nCPP = @CPP@\nCPPFLAGS = @CPPFLAGS@\nCYGPATH_W = @CYGPATH_W@\nDCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@\nDCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@\nDCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@\nDCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@\nDCFG_MINFO_BRACKETING = @DCFG_MINFO_BRACKETING@\nDCFG_THREAD_MODEL = @DCFG_THREAD_MODEL@\nDEFS = @DEFS@\nDRUNTIME_SOVERSION = @DRUNTIME_SOVERSION@\nDSYMUTIL = @DSYMUTIL@\nDUMPBIN = @DUMPBIN@\nECHO_C = @ECHO_C@\nECHO_N = @ECHO_N@\nECHO_T = @ECHO_T@\nEGREP = @EGREP@\nEXEEXT = @EXEEXT@\nFGREP = @FGREP@\nGDC = @GDC@\nGDCFLAGS = @GDCFLAGS@\nGDCFLAGSX = @GDCFLAGSX@\nGREP = @GREP@\nINSTALL = @INSTALL@\nINSTALL_DATA = @INSTALL_DATA@\nINSTALL_PROGRAM = @INSTALL_PROGRAM@\nINSTALL_SCRIPT = @INSTALL_SCRIPT@\nINSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@\nLD = @LD@\nLDFLAGS = @LDFLAGS@\nLIBATOMIC = @LIBATOMIC@\nLIBBACKTRACE = @LIBBACKTRACE@\nLIBOBJS = @LIBOBJS@\nLIBS = @LIBS@\nLIBTOOL = @LIBTOOL@\nLIPO = @LIPO@\nLN_S = @LN_S@\nLTLIBOBJS = @LTLIBOBJS@\nMAINT = @MAINT@\nMAKEINFO = @MAKEINFO@\nMKDIR_P = @MKDIR_P@\nNM = @NM@\nNMEDIT = @NMEDIT@\nOBJDUMP = @OBJDUMP@\nOBJEXT = @OBJEXT@\nOTOOL = @OTOOL@\nOTOOL64 = @OTOOL64@\nPACKAGE = @PACKAGE@\nPACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@\nPACKAGE_NAME = @PACKAGE_NAME@\nPACKAGE_STRING = @PACKAGE_STRING@\nPACKAGE_TARNAME = @PACKAGE_TARNAME@\nPACKAGE_URL = @PACKAGE_URL@\nPACKAGE_VERSION = @PACKAGE_VERSION@\nPATH_SEPARATOR = @PATH_SEPARATOR@\nPHOBOS_SOVERSION = @PHOBOS_SOVERSION@\nRANLIB = @RANLIB@\nSED = @SED@\nSET_MAKE = @SET_MAKE@\nSHELL = @SHELL@\nSPEC_PHOBOS_DEPS = @SPEC_PHOBOS_DEPS@\nSTRIP = @STRIP@\nVERSION = @VERSION@\nabs_builddir = @abs_builddir@\nabs_srcdir = @abs_srcdir@\nabs_top_builddir = @abs_top_builddir@\nabs_top_srcdir = @abs_top_srcdir@\nac_ct_CC = @ac_ct_CC@\nac_ct_DUMPBIN = @ac_ct_DUMPBIN@\nam__leading_dot = @am__leading_dot@\nam__tar = @am__tar@\nam__untar = @am__untar@\nbindir = @bindir@\nbuild = @build@\nbuild_alias = @build_alias@\nbuild_cpu = @build_cpu@\nbuild_os = @build_os@\nbuild_vendor = @build_vendor@\nbuilddir = @builddir@\ndatadir = @datadir@\ndatarootdir = @datarootdir@\ndocdir = @docdir@\ndvidir = @dvidir@\nexec_prefix = @exec_prefix@\ngcc_version = @gcc_version@\ngdc_include_dir = @gdc_include_dir@\nget_gcc_base_ver = @get_gcc_base_ver@\nhost = @host@\nhost_alias = @host_alias@\nhost_cpu = @host_cpu@\nhost_os = @host_os@\nhost_vendor = @host_vendor@\nhtmldir = @htmldir@\nincludedir = @includedir@\ninfodir = @infodir@\ninstall_sh = @install_sh@\nlibdir = @libdir@\nlibexecdir = @libexecdir@\nlibphobos_builddir = @libphobos_builddir@\nlibphobos_srcdir = @libphobos_srcdir@\nlocaledir = @localedir@\nlocalstatedir = @localstatedir@\nmandir = @mandir@\nmkdir_p = @mkdir_p@\nmulti_basedir = @multi_basedir@\noldincludedir = @oldincludedir@\npdfdir = @pdfdir@\nphobos_compiler_pic_flag = @phobos_compiler_pic_flag@\nphobos_compiler_shared_flag = @phobos_compiler_shared_flag@\nprefix = @prefix@\nprogram_transform_name = @program_transform_name@\npsdir = @psdir@\nsbindir = @sbindir@\nsharedstatedir = @sharedstatedir@\nsrcdir = @srcdir@\nsysconfdir = @sysconfdir@\ntarget = @target@\ntarget_alias = @target_alias@\ntarget_cpu = @target_cpu@\ntarget_os = @target_os@\ntarget_vendor = @target_vendor@\ntoolexecdir = @toolexecdir@\ntoolexeclibdir = @toolexeclibdir@\ntop_build_prefix = @top_build_prefix@\ntop_builddir = @top_builddir@\ntop_srcdir = @top_srcdir@\n\n# If there are no sources with known extension (i.e. only D sources)\n# automake forgets to set this\nCCLD = $(CC)\nLTDCOMPILE = $(LIBTOOL) --tag=D $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \\\n\t--mode=compile $(GDC) $(AM_DFLAGS)\n\n\n# Override executable linking commands: We have to use GDC for linking\n# to make sure we link pthreads and other dependencies\nunittest_static_LINK = $(LIBTOOL) --tag=D \\\n\t$(unittest_static_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \\\n\t$(GDC) $(AM_CFLAGS) $(CFLAGS) $(unittest_static_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\n\nunittest_LINK = $(LIBTOOL) --tag=D \\\n\t$(unittest_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \\\n\t$(GDC) $(AM_CFLAGS) $(CFLAGS) $(unittest_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\n\n\n# Also override library link commands: This is not strictly\n# required, but we want to record additional dependencies such\n# as pthread in the library\nlibgdruntime_la_LINK = $(LIBTOOL) --tag=D $(AM_LIBTOOLFLAGS) \\\n\t$(LIBTOOLFLAGS) --mode=link $(GDC) $(AM_CFLAGS) $(CFLAGS) \\\n\t$(libgdruntime_la_LDFLAGS) $(LDFLAGS) -o $@\n\nlibgdruntime_t_la_LINK = $(LIBTOOL) --tag=D $(AM_LIBTOOLFLAGS) \\\n\t$(LIBTOOLFLAGS) --mode=link $(GDC) $(AM_CFLAGS) $(CFLAGS) \\\n\t$(libgdruntime_t_la_LDFLAGS) $(LDFLAGS) -o $@\n\nlibgphobos_la_LINK = $(LIBTOOL) --tag=D $(libgphobos_la_LIBTOOLFLAGS) \\\n\t$(LIBTOOLFLAGS) --mode=link $(GDC) $(AM_CFLAGS) $(CFLAGS) \\\n\t$(libgphobos_la_LDFLAGS) $(LDFLAGS) -o $@\n\nlibgphobos_t_la_LINK = $(LIBTOOL) --tag=D \\\n\t$(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \\\n\t$(GDC) $(AM_CFLAGS) $(CFLAGS) $(libgphobos_t_la_LDFLAGS) \\\n\t$(LDFLAGS) -o $@\n\n\n# Include D build rules\n\n# Make sure GDC can find libdruntime and libphobos include files\nD_EXTRA_DFLAGS = -nostdinc -I $(srcdir) \\\n\t-I $(top_srcdir)/libdruntime -I ../libdruntime -I .\n\n\n# C flags for zlib compilation\nAM_CFLAGS = @DEFS@ -I. -I$(srcdir)/../libdruntime/gcc -I$(top_srcdir)/../zlib\n\n# D flags for compilation\nAM_DFLAGS = $(phobos_compiler_pic_flag)\n\n# Install all D files\nALL_PHOBOS_INSTALL_DSOURCES = $(PHOBOS_DSOURCES)\n\n# Setup source files depending on configure\nALL_PHOBOS_COMPILE_DSOURCES = $(PHOBOS_DSOURCES)\nALL_PHOBOS_SOURCES = $(ALL_PHOBOS_COMPILE_DSOURCES)\nPHOBOS_TEST_LOBJECTS = $(ALL_PHOBOS_COMPILE_DSOURCES:.d=.t.lo)\nPHOBOS_TEST_OBJECTS = $(ALL_PHOBOS_COMPILE_DSOURCES:.d=.t.o)\n@DRUNTIME_ZLIB_SYSTEM_FALSE@ZLIB_SRC = $(ZLIB_CSOURCES)\n\n# Main library build definitions\n@DRUNTIME_ZLIB_SYSTEM_TRUE@ZLIB_SRC = \n@ENABLE_SHARED_TRUE@check_LTLIBRARIES = libgphobos_t.la\ntoolexeclib_DATA = libgphobos.spec\ntoolexeclib_LTLIBRARIES = libgphobos.la\nlibgphobos_la_SOURCES = $(ALL_PHOBOS_SOURCES) $(ZLIB_SRC)\nlibgphobos_la_LIBTOOLFLAGS = \nlibgphobos_la_LDFLAGS = -Xcompiler -nophoboslib -version-info $(PHOBOS_SOVERSION)\nlibgphobos_la_LIBADD = ../libdruntime/libgdruntime.la\nlibgphobos_la_DEPENDENCIES = libgphobos.spec\n\n# For static unittest, link objects directly\nunittest_static_SOURCES = ../testsuite/test_runner.d $(ZLIB_SRC)\nunittest_static_LIBTOOLFLAGS = \nunittest_static_LDFLAGS = -Xcompiler -nophoboslib -static-libtool-libs\nunittest_static_LDADD = $(PHOBOS_TEST_OBJECTS) \\\n    ../libdruntime/libgdruntime.la\n\nEXTRA_unittest_static_DEPENDENCIES = $(PHOBOS_TEST_OBJECTS)\n\n# For unittest with dynamic library\nlibgphobos_t_la_SOURCES = $(ZLIB_SRC)\nlibgphobos_t_la_LIBTOOLFLAGS = \nlibgphobos_t_la_LDFLAGS = -Xcompiler -nophoboslib -rpath /foo -shared\nlibgphobos_t_la_LIBADD = $(PHOBOS_TEST_LOBJECTS) \\\n    ../libdruntime/libgdruntime.la\n\nEXTRA_libgphobos_t_la_DEPENDENCIES = $(PHOBOS_TEST_LOBJECTS)\n\n# For unittest\nunittest_SOURCES = ../testsuite/test_runner.d\nunittest_LIBTOOLFLAGS = \nunittest_LDFLAGS = -Xcompiler -nophoboslib -shared\nunittest_LDADD = libgphobos_t.la ../libdruntime/libgdruntime.la\n\n# Zlib sources when not using system libz\nZLIB_CSOURCES = $(top_srcdir)/../zlib/adler32.c $(top_srcdir)/../zlib/compress.c \\\n\t$(top_srcdir)/../zlib/crc32.c $(top_srcdir)/../zlib/deflate.c \\\n\t$(top_srcdir)/../zlib/gzclose.c $(top_srcdir)/../zlib/gzlib.c \\\n\t$(top_srcdir)/../zlib/gzread.c $(top_srcdir)/../zlib/gzwrite.c \\\n\t$(top_srcdir)/../zlib/infback.c $(top_srcdir)/../zlib/inffast.c \\\n\t$(top_srcdir)/../zlib/inflate.c $(top_srcdir)/../zlib/inftrees.c \\\n\t$(top_srcdir)/../zlib/trees.c $(top_srcdir)/../zlib/uncompr.c \\\n\t$(top_srcdir)/../zlib/zutil.c\n\n\n# Source file definitions. Boring stuff, auto-generated with\n# https://gist.github.com/jpf91/8744acebc9dcf1e9d1a35cdff20afbb2\n# Can't use wildcards here:\n# https://www.gnu.org/software/automake/manual/html_node/Wildcards.html\nPHOBOS_DSOURCES = etc/c/curl.d etc/c/sqlite3.d etc/c/zlib.d \\\n\tstd/algorithm/comparison.d std/algorithm/internal.d \\\n\tstd/algorithm/iteration.d std/algorithm/mutation.d \\\n\tstd/algorithm/package.d std/algorithm/searching.d \\\n\tstd/algorithm/setops.d std/algorithm/sorting.d std/array.d std/ascii.d \\\n\tstd/base64.d std/bigint.d std/bitmanip.d std/compiler.d std/complex.d \\\n\tstd/concurrency.d std/container/array.d std/container/binaryheap.d \\\n\tstd/container/dlist.d std/container/package.d std/container/rbtree.d \\\n\tstd/container/slist.d std/container/util.d std/conv.d std/csv.d \\\n\tstd/datetime/date.d std/datetime/interval.d std/datetime/package.d \\\n\tstd/datetime/stopwatch.d std/datetime/systime.d \\\n\tstd/datetime/timezone.d std/demangle.d std/digest/crc.d \\\n\tstd/digest/digest.d std/digest/hmac.d std/digest/md.d \\\n\tstd/digest/murmurhash.d std/digest/package.d std/digest/ripemd.d \\\n\tstd/digest/sha.d std/encoding.d std/exception.d std/experimental/all.d \\\n\tstd/experimental/allocator/building_blocks/affix_allocator.d \\\n\tstd/experimental/allocator/building_blocks/aligned_block_list.d \\\n\tstd/experimental/allocator/building_blocks/allocator_list.d \\\n\tstd/experimental/allocator/building_blocks/ascending_page_allocator.d \\\n\tstd/experimental/allocator/building_blocks/bitmapped_block.d \\\n\tstd/experimental/allocator/building_blocks/bucketizer.d \\\n\tstd/experimental/allocator/building_blocks/fallback_allocator.d \\\n\tstd/experimental/allocator/building_blocks/free_list.d \\\n\tstd/experimental/allocator/building_blocks/free_tree.d \\\n\tstd/experimental/allocator/building_blocks/kernighan_ritchie.d \\\n\tstd/experimental/allocator/building_blocks/null_allocator.d \\\n\tstd/experimental/allocator/building_blocks/package.d \\\n\tstd/experimental/allocator/building_blocks/quantizer.d \\\n\tstd/experimental/allocator/building_blocks/region.d \\\n\tstd/experimental/allocator/building_blocks/scoped_allocator.d \\\n\tstd/experimental/allocator/building_blocks/segregator.d \\\n\tstd/experimental/allocator/building_blocks/stats_collector.d \\\n\tstd/experimental/allocator/common.d \\\n\tstd/experimental/allocator/gc_allocator.d \\\n\tstd/experimental/allocator/mallocator.d \\\n\tstd/experimental/allocator/mmap_allocator.d \\\n\tstd/experimental/allocator/package.d \\\n\tstd/experimental/allocator/showcase.d \\\n\tstd/experimental/allocator/typed.d std/experimental/checkedint.d \\\n\tstd/experimental/logger/core.d std/experimental/logger/filelogger.d \\\n\tstd/experimental/logger/multilogger.d \\\n\tstd/experimental/logger/nulllogger.d std/experimental/logger/package.d \\\n\tstd/experimental/typecons.d std/file.d std/format.d std/functional.d \\\n\tstd/getopt.d std/internal/attributes.d std/internal/cstring.d \\\n\tstd/internal/math/biguintcore.d std/internal/math/biguintnoasm.d \\\n\tstd/internal/math/errorfunction.d std/internal/math/gammafunction.d \\\n\tstd/internal/scopebuffer.d std/internal/test/dummyrange.d \\\n\tstd/internal/test/range.d std/internal/test/uda.d \\\n\tstd/internal/unicode_comp.d std/internal/unicode_decomp.d \\\n\tstd/internal/unicode_grapheme.d std/internal/unicode_norm.d \\\n\tstd/internal/unicode_tables.d std/internal/windows/advapi32.d \\\n\tstd/json.d std/math.d std/mathspecial.d std/meta.d std/mmfile.d \\\n\tstd/net/curl.d std/net/isemail.d std/numeric.d std/outbuffer.d \\\n\tstd/parallelism.d std/path.d std/process.d std/random.d \\\n\tstd/range/interfaces.d std/range/package.d std/range/primitives.d \\\n\tstd/regex/internal/backtracking.d std/regex/internal/generator.d \\\n\tstd/regex/internal/ir.d std/regex/internal/kickstart.d \\\n\tstd/regex/internal/parser.d std/regex/internal/tests.d \\\n\tstd/regex/internal/tests2.d std/regex/internal/thompson.d \\\n\tstd/regex/package.d std/signals.d std/socket.d std/stdint.d \\\n\tstd/stdio.d std/string.d std/system.d std/traits.d std/typecons.d \\\n\tstd/typetuple.d std/uni.d std/uri.d std/utf.d std/uuid.d std/variant.d \\\n\tstd/windows/charset.d std/windows/registry.d std/windows/syserror.d \\\n\tstd/xml.d std/zip.d std/zlib.d\n\nall: all-am\n\n.SUFFIXES:\n.SUFFIXES: .c .d .lo .o .obj\n$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/d_rules.am $(am__configure_deps)\n\t@for dep in $?; do \\\n\t  case '$(am__configure_deps)' in \\\n\t    *$$dep*) \\\n\t      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \\\n\t        && { if test -f $@; then exit 0; else break; fi; }; \\\n\t      exit 1;; \\\n\t  esac; \\\n\tdone; \\\n\techo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps src/Makefile'; \\\n\t$(am__cd) $(top_srcdir) && \\\n\t  $(AUTOMAKE) --foreign --ignore-deps src/Makefile\n.PRECIOUS: Makefile\nMakefile: $(srcdir)/Makefile.in $(top_builddir)/config.status\n\t@case '$?' in \\\n\t  *config.status*) \\\n\t    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \\\n\t  *) \\\n\t    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \\\n\t    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \\\n\tesac;\n$(top_srcdir)/d_rules.am:\n\n$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)\n\tcd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh\n\n$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)\n\tcd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh\n$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)\n\tcd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh\n$(am__aclocal_m4_deps):\nlibgphobos.spec: $(top_builddir)/config.status $(srcdir)/libgphobos.spec.in\n\tcd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@\n\nclean-checkLTLIBRARIES:\n\t-test -z \"$(check_LTLIBRARIES)\" || rm -f $(check_LTLIBRARIES)\n\t@list='$(check_LTLIBRARIES)'; for p in $$list; do \\\n\t  dir=\"`echo $$p | sed -e 's|/[^/]*$$||'`\"; \\\n\t  test \"$$dir\" != \"$$p\" || dir=.; \\\n\t  echo \"rm -f \\\"$${dir}/so_locations\\\"\"; \\\n\t  rm -f \"$${dir}/so_locations\"; \\\n\tdone\ninstall-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)\n\t@$(NORMAL_INSTALL)\n\t@list='$(toolexeclib_LTLIBRARIES)'; test -n \"$(toolexeclibdir)\" || list=; \\\n\tlist2=; for p in $$list; do \\\n\t  if test -f $$p; then \\\n\t    list2=\"$$list2 $$p\"; \\\n\t  else :; fi; \\\n\tdone; \\\n\ttest -z \"$$list2\" || { \\\n\t  echo \" $(MKDIR_P) '$(DESTDIR)$(toolexeclibdir)'\"; \\\n\t  $(MKDIR_P) \"$(DESTDIR)$(toolexeclibdir)\" || exit 1; \\\n\t  echo \" $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'\"; \\\n\t  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 \"$(DESTDIR)$(toolexeclibdir)\"; \\\n\t}\n\nuninstall-toolexeclibLTLIBRARIES:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(toolexeclib_LTLIBRARIES)'; test -n \"$(toolexeclibdir)\" || list=; \\\n\tfor p in $$list; do \\\n\t  $(am__strip_dir) \\\n\t  echo \" $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$f'\"; \\\n\t  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f \"$(DESTDIR)$(toolexeclibdir)/$$f\"; \\\n\tdone\n\nclean-toolexeclibLTLIBRARIES:\n\t-test -z \"$(toolexeclib_LTLIBRARIES)\" || rm -f $(toolexeclib_LTLIBRARIES)\n\t@list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \\\n\t  dir=\"`echo $$p | sed -e 's|/[^/]*$$||'`\"; \\\n\t  test \"$$dir\" != \"$$p\" || dir=.; \\\n\t  echo \"rm -f \\\"$${dir}/so_locations\\\"\"; \\\n\t  rm -f \"$${dir}/so_locations\"; \\\n\tdone\netc/c/$(am__dirstamp):\n\t@$(MKDIR_P) etc/c\n\t@: > etc/c/$(am__dirstamp)\netc/c/curl.lo: etc/c/$(am__dirstamp)\netc/c/sqlite3.lo: etc/c/$(am__dirstamp)\netc/c/zlib.lo: etc/c/$(am__dirstamp)\nstd/algorithm/$(am__dirstamp):\n\t@$(MKDIR_P) std/algorithm\n\t@: > std/algorithm/$(am__dirstamp)\nstd/algorithm/comparison.lo: std/algorithm/$(am__dirstamp)\nstd/algorithm/internal.lo: std/algorithm/$(am__dirstamp)\nstd/algorithm/iteration.lo: std/algorithm/$(am__dirstamp)\nstd/algorithm/mutation.lo: std/algorithm/$(am__dirstamp)\nstd/algorithm/package.lo: std/algorithm/$(am__dirstamp)\nstd/algorithm/searching.lo: std/algorithm/$(am__dirstamp)\nstd/algorithm/setops.lo: std/algorithm/$(am__dirstamp)\nstd/algorithm/sorting.lo: std/algorithm/$(am__dirstamp)\nstd/$(am__dirstamp):\n\t@$(MKDIR_P) std\n\t@: > std/$(am__dirstamp)\nstd/array.lo: std/$(am__dirstamp)\nstd/ascii.lo: std/$(am__dirstamp)\nstd/base64.lo: std/$(am__dirstamp)\nstd/bigint.lo: std/$(am__dirstamp)\nstd/bitmanip.lo: std/$(am__dirstamp)\nstd/compiler.lo: std/$(am__dirstamp)\nstd/complex.lo: std/$(am__dirstamp)\nstd/concurrency.lo: std/$(am__dirstamp)\nstd/container/$(am__dirstamp):\n\t@$(MKDIR_P) std/container\n\t@: > std/container/$(am__dirstamp)\nstd/container/array.lo: std/container/$(am__dirstamp)\nstd/container/binaryheap.lo: std/container/$(am__dirstamp)\nstd/container/dlist.lo: std/container/$(am__dirstamp)\nstd/container/package.lo: std/container/$(am__dirstamp)\nstd/container/rbtree.lo: std/container/$(am__dirstamp)\nstd/container/slist.lo: std/container/$(am__dirstamp)\nstd/container/util.lo: std/container/$(am__dirstamp)\nstd/conv.lo: std/$(am__dirstamp)\nstd/csv.lo: std/$(am__dirstamp)\nstd/datetime/$(am__dirstamp):\n\t@$(MKDIR_P) std/datetime\n\t@: > std/datetime/$(am__dirstamp)\nstd/datetime/date.lo: std/datetime/$(am__dirstamp)\nstd/datetime/interval.lo: std/datetime/$(am__dirstamp)\nstd/datetime/package.lo: std/datetime/$(am__dirstamp)\nstd/datetime/stopwatch.lo: std/datetime/$(am__dirstamp)\nstd/datetime/systime.lo: std/datetime/$(am__dirstamp)\nstd/datetime/timezone.lo: std/datetime/$(am__dirstamp)\nstd/demangle.lo: std/$(am__dirstamp)\nstd/digest/$(am__dirstamp):\n\t@$(MKDIR_P) std/digest\n\t@: > std/digest/$(am__dirstamp)\nstd/digest/crc.lo: std/digest/$(am__dirstamp)\nstd/digest/digest.lo: std/digest/$(am__dirstamp)\nstd/digest/hmac.lo: std/digest/$(am__dirstamp)\nstd/digest/md.lo: std/digest/$(am__dirstamp)\nstd/digest/murmurhash.lo: std/digest/$(am__dirstamp)\nstd/digest/package.lo: std/digest/$(am__dirstamp)\nstd/digest/ripemd.lo: std/digest/$(am__dirstamp)\nstd/digest/sha.lo: std/digest/$(am__dirstamp)\nstd/encoding.lo: std/$(am__dirstamp)\nstd/exception.lo: std/$(am__dirstamp)\nstd/experimental/$(am__dirstamp):\n\t@$(MKDIR_P) std/experimental\n\t@: > std/experimental/$(am__dirstamp)\nstd/experimental/all.lo: std/experimental/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/$(am__dirstamp):\n\t@$(MKDIR_P) std/experimental/allocator/building_blocks\n\t@: > std/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/affix_allocator.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/aligned_block_list.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/allocator_list.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/ascending_page_allocator.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/bitmapped_block.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/bucketizer.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/fallback_allocator.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/free_list.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/free_tree.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/kernighan_ritchie.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/null_allocator.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/package.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/quantizer.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/region.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/scoped_allocator.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/segregator.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/building_blocks/stats_collector.lo:  \\\n\tstd/experimental/allocator/building_blocks/$(am__dirstamp)\nstd/experimental/allocator/$(am__dirstamp):\n\t@$(MKDIR_P) std/experimental/allocator\n\t@: > std/experimental/allocator/$(am__dirstamp)\nstd/experimental/allocator/common.lo:  \\\n\tstd/experimental/allocator/$(am__dirstamp)\nstd/experimental/allocator/gc_allocator.lo:  \\\n\tstd/experimental/allocator/$(am__dirstamp)\nstd/experimental/allocator/mallocator.lo:  \\\n\tstd/experimental/allocator/$(am__dirstamp)\nstd/experimental/allocator/mmap_allocator.lo:  \\\n\tstd/experimental/allocator/$(am__dirstamp)\nstd/experimental/allocator/package.lo:  \\\n\tstd/experimental/allocator/$(am__dirstamp)\nstd/experimental/allocator/showcase.lo:  \\\n\tstd/experimental/allocator/$(am__dirstamp)\nstd/experimental/allocator/typed.lo:  \\\n\tstd/experimental/allocator/$(am__dirstamp)\nstd/experimental/checkedint.lo: std/experimental/$(am__dirstamp)\nstd/experimental/logger/$(am__dirstamp):\n\t@$(MKDIR_P) std/experimental/logger\n\t@: > std/experimental/logger/$(am__dirstamp)\nstd/experimental/logger/core.lo:  \\\n\tstd/experimental/logger/$(am__dirstamp)\nstd/experimental/logger/filelogger.lo:  \\\n\tstd/experimental/logger/$(am__dirstamp)\nstd/experimental/logger/multilogger.lo:  \\\n\tstd/experimental/logger/$(am__dirstamp)\nstd/experimental/logger/nulllogger.lo:  \\\n\tstd/experimental/logger/$(am__dirstamp)\nstd/experimental/logger/package.lo:  \\\n\tstd/experimental/logger/$(am__dirstamp)\nstd/experimental/typecons.lo: std/experimental/$(am__dirstamp)\nstd/file.lo: std/$(am__dirstamp)\nstd/format.lo: std/$(am__dirstamp)\nstd/functional.lo: std/$(am__dirstamp)\nstd/getopt.lo: std/$(am__dirstamp)\nstd/internal/$(am__dirstamp):\n\t@$(MKDIR_P) std/internal\n\t@: > std/internal/$(am__dirstamp)\nstd/internal/attributes.lo: std/internal/$(am__dirstamp)\nstd/internal/cstring.lo: std/internal/$(am__dirstamp)\nstd/internal/math/$(am__dirstamp):\n\t@$(MKDIR_P) std/internal/math\n\t@: > std/internal/math/$(am__dirstamp)\nstd/internal/math/biguintcore.lo: std/internal/math/$(am__dirstamp)\nstd/internal/math/biguintnoasm.lo: std/internal/math/$(am__dirstamp)\nstd/internal/math/errorfunction.lo: std/internal/math/$(am__dirstamp)\nstd/internal/math/gammafunction.lo: std/internal/math/$(am__dirstamp)\nstd/internal/scopebuffer.lo: std/internal/$(am__dirstamp)\nstd/internal/test/$(am__dirstamp):\n\t@$(MKDIR_P) std/internal/test\n\t@: > std/internal/test/$(am__dirstamp)\nstd/internal/test/dummyrange.lo: std/internal/test/$(am__dirstamp)\nstd/internal/test/range.lo: std/internal/test/$(am__dirstamp)\nstd/internal/test/uda.lo: std/internal/test/$(am__dirstamp)\nstd/internal/unicode_comp.lo: std/internal/$(am__dirstamp)\nstd/internal/unicode_decomp.lo: std/internal/$(am__dirstamp)\nstd/internal/unicode_grapheme.lo: std/internal/$(am__dirstamp)\nstd/internal/unicode_norm.lo: std/internal/$(am__dirstamp)\nstd/internal/unicode_tables.lo: std/internal/$(am__dirstamp)\nstd/internal/windows/$(am__dirstamp):\n\t@$(MKDIR_P) std/internal/windows\n\t@: > std/internal/windows/$(am__dirstamp)\nstd/internal/windows/advapi32.lo:  \\\n\tstd/internal/windows/$(am__dirstamp)\nstd/json.lo: std/$(am__dirstamp)\nstd/math.lo: std/$(am__dirstamp)\nstd/mathspecial.lo: std/$(am__dirstamp)\nstd/meta.lo: std/$(am__dirstamp)\nstd/mmfile.lo: std/$(am__dirstamp)\nstd/net/$(am__dirstamp):\n\t@$(MKDIR_P) std/net\n\t@: > std/net/$(am__dirstamp)\nstd/net/curl.lo: std/net/$(am__dirstamp)\nstd/net/isemail.lo: std/net/$(am__dirstamp)\nstd/numeric.lo: std/$(am__dirstamp)\nstd/outbuffer.lo: std/$(am__dirstamp)\nstd/parallelism.lo: std/$(am__dirstamp)\nstd/path.lo: std/$(am__dirstamp)\nstd/process.lo: std/$(am__dirstamp)\nstd/random.lo: std/$(am__dirstamp)\nstd/range/$(am__dirstamp):\n\t@$(MKDIR_P) std/range\n\t@: > std/range/$(am__dirstamp)\nstd/range/interfaces.lo: std/range/$(am__dirstamp)\nstd/range/package.lo: std/range/$(am__dirstamp)\nstd/range/primitives.lo: std/range/$(am__dirstamp)\nstd/regex/internal/$(am__dirstamp):\n\t@$(MKDIR_P) std/regex/internal\n\t@: > std/regex/internal/$(am__dirstamp)\nstd/regex/internal/backtracking.lo:  \\\n\tstd/regex/internal/$(am__dirstamp)\nstd/regex/internal/generator.lo: std/regex/internal/$(am__dirstamp)\nstd/regex/internal/ir.lo: std/regex/internal/$(am__dirstamp)\nstd/regex/internal/kickstart.lo: std/regex/internal/$(am__dirstamp)\nstd/regex/internal/parser.lo: std/regex/internal/$(am__dirstamp)\nstd/regex/internal/tests.lo: std/regex/internal/$(am__dirstamp)\nstd/regex/internal/tests2.lo: std/regex/internal/$(am__dirstamp)\nstd/regex/internal/thompson.lo: std/regex/internal/$(am__dirstamp)\nstd/regex/$(am__dirstamp):\n\t@$(MKDIR_P) std/regex\n\t@: > std/regex/$(am__dirstamp)\nstd/regex/package.lo: std/regex/$(am__dirstamp)\nstd/signals.lo: std/$(am__dirstamp)\nstd/socket.lo: std/$(am__dirstamp)\nstd/stdint.lo: std/$(am__dirstamp)\nstd/stdio.lo: std/$(am__dirstamp)\nstd/string.lo: std/$(am__dirstamp)\nstd/system.lo: std/$(am__dirstamp)\nstd/traits.lo: std/$(am__dirstamp)\nstd/typecons.lo: std/$(am__dirstamp)\nstd/typetuple.lo: std/$(am__dirstamp)\nstd/uni.lo: std/$(am__dirstamp)\nstd/uri.lo: std/$(am__dirstamp)\nstd/utf.lo: std/$(am__dirstamp)\nstd/uuid.lo: std/$(am__dirstamp)\nstd/variant.lo: std/$(am__dirstamp)\nstd/windows/$(am__dirstamp):\n\t@$(MKDIR_P) std/windows\n\t@: > std/windows/$(am__dirstamp)\nstd/windows/charset.lo: std/windows/$(am__dirstamp)\nstd/windows/registry.lo: std/windows/$(am__dirstamp)\nstd/windows/syserror.lo: std/windows/$(am__dirstamp)\nstd/xml.lo: std/$(am__dirstamp)\nstd/zip.lo: std/$(am__dirstamp)\nstd/zlib.lo: std/$(am__dirstamp)\nlibgphobos.la: $(libgphobos_la_OBJECTS) $(libgphobos_la_DEPENDENCIES) $(EXTRA_libgphobos_la_DEPENDENCIES) \n\t$(libgphobos_la_LINK) -rpath $(toolexeclibdir) $(libgphobos_la_OBJECTS) $(libgphobos_la_LIBADD) $(LIBS)\nlibgphobos_t.la: $(libgphobos_t_la_OBJECTS) $(libgphobos_t_la_DEPENDENCIES) $(EXTRA_libgphobos_t_la_DEPENDENCIES) \n\t$(libgphobos_t_la_LINK) $(am_libgphobos_t_la_rpath) $(libgphobos_t_la_OBJECTS) $(libgphobos_t_la_LIBADD) $(LIBS)\n\nclean-checkPROGRAMS:\n\t@list='$(check_PROGRAMS)'; test -n \"$$list\" || exit 0; \\\n\techo \" rm -f\" $$list; \\\n\trm -f $$list || exit $$?; \\\n\ttest -n \"$(EXEEXT)\" || exit 0; \\\n\tlist=`for p in $$list; do echo \"$$p\"; done | sed 's/$(EXEEXT)$$//'`; \\\n\techo \" rm -f\" $$list; \\\n\trm -f $$list\n../testsuite/$(am__dirstamp):\n\t@$(MKDIR_P) ../testsuite\n\t@: > ../testsuite/$(am__dirstamp)\n../testsuite/test_runner.$(OBJEXT): ../testsuite/$(am__dirstamp)\nunittest$(EXEEXT): $(unittest_OBJECTS) $(unittest_DEPENDENCIES) $(EXTRA_unittest_DEPENDENCIES) \n\t@rm -f unittest$(EXEEXT)\n\t$(unittest_LINK) $(unittest_OBJECTS) $(unittest_LDADD) $(LIBS)\nunittest_static$(EXEEXT): $(unittest_static_OBJECTS) $(unittest_static_DEPENDENCIES) $(EXTRA_unittest_static_DEPENDENCIES) \n\t@rm -f unittest_static$(EXEEXT)\n\t$(unittest_static_LINK) $(unittest_static_OBJECTS) $(unittest_static_LDADD) $(LIBS)\n\nmostlyclean-compile:\n\t-rm -f *.$(OBJEXT)\n\t-rm -f ../testsuite/test_runner.$(OBJEXT)\n\t-rm -f etc/c/curl.$(OBJEXT)\n\t-rm -f etc/c/curl.lo\n\t-rm -f etc/c/sqlite3.$(OBJEXT)\n\t-rm -f etc/c/sqlite3.lo\n\t-rm -f etc/c/zlib.$(OBJEXT)\n\t-rm -f etc/c/zlib.lo\n\t-rm -f std/algorithm/comparison.$(OBJEXT)\n\t-rm -f std/algorithm/comparison.lo\n\t-rm -f std/algorithm/internal.$(OBJEXT)\n\t-rm -f std/algorithm/internal.lo\n\t-rm -f std/algorithm/iteration.$(OBJEXT)\n\t-rm -f std/algorithm/iteration.lo\n\t-rm -f std/algorithm/mutation.$(OBJEXT)\n\t-rm -f std/algorithm/mutation.lo\n\t-rm -f std/algorithm/package.$(OBJEXT)\n\t-rm -f std/algorithm/package.lo\n\t-rm -f std/algorithm/searching.$(OBJEXT)\n\t-rm -f std/algorithm/searching.lo\n\t-rm -f std/algorithm/setops.$(OBJEXT)\n\t-rm -f std/algorithm/setops.lo\n\t-rm -f std/algorithm/sorting.$(OBJEXT)\n\t-rm -f std/algorithm/sorting.lo\n\t-rm -f std/array.$(OBJEXT)\n\t-rm -f std/array.lo\n\t-rm -f std/ascii.$(OBJEXT)\n\t-rm -f std/ascii.lo\n\t-rm -f std/base64.$(OBJEXT)\n\t-rm -f std/base64.lo\n\t-rm -f std/bigint.$(OBJEXT)\n\t-rm -f std/bigint.lo\n\t-rm -f std/bitmanip.$(OBJEXT)\n\t-rm -f std/bitmanip.lo\n\t-rm -f std/compiler.$(OBJEXT)\n\t-rm -f std/compiler.lo\n\t-rm -f std/complex.$(OBJEXT)\n\t-rm -f std/complex.lo\n\t-rm -f std/concurrency.$(OBJEXT)\n\t-rm -f std/concurrency.lo\n\t-rm -f std/container/array.$(OBJEXT)\n\t-rm -f std/container/array.lo\n\t-rm -f std/container/binaryheap.$(OBJEXT)\n\t-rm -f std/container/binaryheap.lo\n\t-rm -f std/container/dlist.$(OBJEXT)\n\t-rm -f std/container/dlist.lo\n\t-rm -f std/container/package.$(OBJEXT)\n\t-rm -f std/container/package.lo\n\t-rm -f std/container/rbtree.$(OBJEXT)\n\t-rm -f std/container/rbtree.lo\n\t-rm -f std/container/slist.$(OBJEXT)\n\t-rm -f std/container/slist.lo\n\t-rm -f std/container/util.$(OBJEXT)\n\t-rm -f std/container/util.lo\n\t-rm -f std/conv.$(OBJEXT)\n\t-rm -f std/conv.lo\n\t-rm -f std/csv.$(OBJEXT)\n\t-rm -f std/csv.lo\n\t-rm -f std/datetime/date.$(OBJEXT)\n\t-rm -f std/datetime/date.lo\n\t-rm -f std/datetime/interval.$(OBJEXT)\n\t-rm -f std/datetime/interval.lo\n\t-rm -f std/datetime/package.$(OBJEXT)\n\t-rm -f std/datetime/package.lo\n\t-rm -f std/datetime/stopwatch.$(OBJEXT)\n\t-rm -f std/datetime/stopwatch.lo\n\t-rm -f std/datetime/systime.$(OBJEXT)\n\t-rm -f std/datetime/systime.lo\n\t-rm -f std/datetime/timezone.$(OBJEXT)\n\t-rm -f std/datetime/timezone.lo\n\t-rm -f std/demangle.$(OBJEXT)\n\t-rm -f std/demangle.lo\n\t-rm -f std/digest/crc.$(OBJEXT)\n\t-rm -f std/digest/crc.lo\n\t-rm -f std/digest/digest.$(OBJEXT)\n\t-rm -f std/digest/digest.lo\n\t-rm -f std/digest/hmac.$(OBJEXT)\n\t-rm -f std/digest/hmac.lo\n\t-rm -f std/digest/md.$(OBJEXT)\n\t-rm -f std/digest/md.lo\n\t-rm -f std/digest/murmurhash.$(OBJEXT)\n\t-rm -f std/digest/murmurhash.lo\n\t-rm -f std/digest/package.$(OBJEXT)\n\t-rm -f std/digest/package.lo\n\t-rm -f std/digest/ripemd.$(OBJEXT)\n\t-rm -f std/digest/ripemd.lo\n\t-rm -f std/digest/sha.$(OBJEXT)\n\t-rm -f std/digest/sha.lo\n\t-rm -f std/encoding.$(OBJEXT)\n\t-rm -f std/encoding.lo\n\t-rm -f std/exception.$(OBJEXT)\n\t-rm -f std/exception.lo\n\t-rm -f std/experimental/all.$(OBJEXT)\n\t-rm -f std/experimental/all.lo\n\t-rm -f std/experimental/allocator/building_blocks/affix_allocator.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/affix_allocator.lo\n\t-rm -f std/experimental/allocator/building_blocks/aligned_block_list.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/aligned_block_list.lo\n\t-rm -f std/experimental/allocator/building_blocks/allocator_list.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/allocator_list.lo\n\t-rm -f std/experimental/allocator/building_blocks/ascending_page_allocator.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/ascending_page_allocator.lo\n\t-rm -f std/experimental/allocator/building_blocks/bitmapped_block.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/bitmapped_block.lo\n\t-rm -f std/experimental/allocator/building_blocks/bucketizer.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/bucketizer.lo\n\t-rm -f std/experimental/allocator/building_blocks/fallback_allocator.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/fallback_allocator.lo\n\t-rm -f std/experimental/allocator/building_blocks/free_list.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/free_list.lo\n\t-rm -f std/experimental/allocator/building_blocks/free_tree.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/free_tree.lo\n\t-rm -f std/experimental/allocator/building_blocks/kernighan_ritchie.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/kernighan_ritchie.lo\n\t-rm -f std/experimental/allocator/building_blocks/null_allocator.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/null_allocator.lo\n\t-rm -f std/experimental/allocator/building_blocks/package.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/package.lo\n\t-rm -f std/experimental/allocator/building_blocks/quantizer.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/quantizer.lo\n\t-rm -f std/experimental/allocator/building_blocks/region.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/region.lo\n\t-rm -f std/experimental/allocator/building_blocks/scoped_allocator.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/scoped_allocator.lo\n\t-rm -f std/experimental/allocator/building_blocks/segregator.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/segregator.lo\n\t-rm -f std/experimental/allocator/building_blocks/stats_collector.$(OBJEXT)\n\t-rm -f std/experimental/allocator/building_blocks/stats_collector.lo\n\t-rm -f std/experimental/allocator/common.$(OBJEXT)\n\t-rm -f std/experimental/allocator/common.lo\n\t-rm -f std/experimental/allocator/gc_allocator.$(OBJEXT)\n\t-rm -f std/experimental/allocator/gc_allocator.lo\n\t-rm -f std/experimental/allocator/mallocator.$(OBJEXT)\n\t-rm -f std/experimental/allocator/mallocator.lo\n\t-rm -f std/experimental/allocator/mmap_allocator.$(OBJEXT)\n\t-rm -f std/experimental/allocator/mmap_allocator.lo\n\t-rm -f std/experimental/allocator/package.$(OBJEXT)\n\t-rm -f std/experimental/allocator/package.lo\n\t-rm -f std/experimental/allocator/showcase.$(OBJEXT)\n\t-rm -f std/experimental/allocator/showcase.lo\n\t-rm -f std/experimental/allocator/typed.$(OBJEXT)\n\t-rm -f std/experimental/allocator/typed.lo\n\t-rm -f std/experimental/checkedint.$(OBJEXT)\n\t-rm -f std/experimental/checkedint.lo\n\t-rm -f std/experimental/logger/core.$(OBJEXT)\n\t-rm -f std/experimental/logger/core.lo\n\t-rm -f std/experimental/logger/filelogger.$(OBJEXT)\n\t-rm -f std/experimental/logger/filelogger.lo\n\t-rm -f std/experimental/logger/multilogger.$(OBJEXT)\n\t-rm -f std/experimental/logger/multilogger.lo\n\t-rm -f std/experimental/logger/nulllogger.$(OBJEXT)\n\t-rm -f std/experimental/logger/nulllogger.lo\n\t-rm -f std/experimental/logger/package.$(OBJEXT)\n\t-rm -f std/experimental/logger/package.lo\n\t-rm -f std/experimental/typecons.$(OBJEXT)\n\t-rm -f std/experimental/typecons.lo\n\t-rm -f std/file.$(OBJEXT)\n\t-rm -f std/file.lo\n\t-rm -f std/format.$(OBJEXT)\n\t-rm -f std/format.lo\n\t-rm -f std/functional.$(OBJEXT)\n\t-rm -f std/functional.lo\n\t-rm -f std/getopt.$(OBJEXT)\n\t-rm -f std/getopt.lo\n\t-rm -f std/internal/attributes.$(OBJEXT)\n\t-rm -f std/internal/attributes.lo\n\t-rm -f std/internal/cstring.$(OBJEXT)\n\t-rm -f std/internal/cstring.lo\n\t-rm -f std/internal/math/biguintcore.$(OBJEXT)\n\t-rm -f std/internal/math/biguintcore.lo\n\t-rm -f std/internal/math/biguintnoasm.$(OBJEXT)\n\t-rm -f std/internal/math/biguintnoasm.lo\n\t-rm -f std/internal/math/errorfunction.$(OBJEXT)\n\t-rm -f std/internal/math/errorfunction.lo\n\t-rm -f std/internal/math/gammafunction.$(OBJEXT)\n\t-rm -f std/internal/math/gammafunction.lo\n\t-rm -f std/internal/scopebuffer.$(OBJEXT)\n\t-rm -f std/internal/scopebuffer.lo\n\t-rm -f std/internal/test/dummyrange.$(OBJEXT)\n\t-rm -f std/internal/test/dummyrange.lo\n\t-rm -f std/internal/test/range.$(OBJEXT)\n\t-rm -f std/internal/test/range.lo\n\t-rm -f std/internal/test/uda.$(OBJEXT)\n\t-rm -f std/internal/test/uda.lo\n\t-rm -f std/internal/unicode_comp.$(OBJEXT)\n\t-rm -f std/internal/unicode_comp.lo\n\t-rm -f std/internal/unicode_decomp.$(OBJEXT)\n\t-rm -f std/internal/unicode_decomp.lo\n\t-rm -f std/internal/unicode_grapheme.$(OBJEXT)\n\t-rm -f std/internal/unicode_grapheme.lo\n\t-rm -f std/internal/unicode_norm.$(OBJEXT)\n\t-rm -f std/internal/unicode_norm.lo\n\t-rm -f std/internal/unicode_tables.$(OBJEXT)\n\t-rm -f std/internal/unicode_tables.lo\n\t-rm -f std/internal/windows/advapi32.$(OBJEXT)\n\t-rm -f std/internal/windows/advapi32.lo\n\t-rm -f std/json.$(OBJEXT)\n\t-rm -f std/json.lo\n\t-rm -f std/math.$(OBJEXT)\n\t-rm -f std/math.lo\n\t-rm -f std/mathspecial.$(OBJEXT)\n\t-rm -f std/mathspecial.lo\n\t-rm -f std/meta.$(OBJEXT)\n\t-rm -f std/meta.lo\n\t-rm -f std/mmfile.$(OBJEXT)\n\t-rm -f std/mmfile.lo\n\t-rm -f std/net/curl.$(OBJEXT)\n\t-rm -f std/net/curl.lo\n\t-rm -f std/net/isemail.$(OBJEXT)\n\t-rm -f std/net/isemail.lo\n\t-rm -f std/numeric.$(OBJEXT)\n\t-rm -f std/numeric.lo\n\t-rm -f std/outbuffer.$(OBJEXT)\n\t-rm -f std/outbuffer.lo\n\t-rm -f std/parallelism.$(OBJEXT)\n\t-rm -f std/parallelism.lo\n\t-rm -f std/path.$(OBJEXT)\n\t-rm -f std/path.lo\n\t-rm -f std/process.$(OBJEXT)\n\t-rm -f std/process.lo\n\t-rm -f std/random.$(OBJEXT)\n\t-rm -f std/random.lo\n\t-rm -f std/range/interfaces.$(OBJEXT)\n\t-rm -f std/range/interfaces.lo\n\t-rm -f std/range/package.$(OBJEXT)\n\t-rm -f std/range/package.lo\n\t-rm -f std/range/primitives.$(OBJEXT)\n\t-rm -f std/range/primitives.lo\n\t-rm -f std/regex/internal/backtracking.$(OBJEXT)\n\t-rm -f std/regex/internal/backtracking.lo\n\t-rm -f std/regex/internal/generator.$(OBJEXT)\n\t-rm -f std/regex/internal/generator.lo\n\t-rm -f std/regex/internal/ir.$(OBJEXT)\n\t-rm -f std/regex/internal/ir.lo\n\t-rm -f std/regex/internal/kickstart.$(OBJEXT)\n\t-rm -f std/regex/internal/kickstart.lo\n\t-rm -f std/regex/internal/parser.$(OBJEXT)\n\t-rm -f std/regex/internal/parser.lo\n\t-rm -f std/regex/internal/tests.$(OBJEXT)\n\t-rm -f std/regex/internal/tests.lo\n\t-rm -f std/regex/internal/tests2.$(OBJEXT)\n\t-rm -f std/regex/internal/tests2.lo\n\t-rm -f std/regex/internal/thompson.$(OBJEXT)\n\t-rm -f std/regex/internal/thompson.lo\n\t-rm -f std/regex/package.$(OBJEXT)\n\t-rm -f std/regex/package.lo\n\t-rm -f std/signals.$(OBJEXT)\n\t-rm -f std/signals.lo\n\t-rm -f std/socket.$(OBJEXT)\n\t-rm -f std/socket.lo\n\t-rm -f std/stdint.$(OBJEXT)\n\t-rm -f std/stdint.lo\n\t-rm -f std/stdio.$(OBJEXT)\n\t-rm -f std/stdio.lo\n\t-rm -f std/string.$(OBJEXT)\n\t-rm -f std/string.lo\n\t-rm -f std/system.$(OBJEXT)\n\t-rm -f std/system.lo\n\t-rm -f std/traits.$(OBJEXT)\n\t-rm -f std/traits.lo\n\t-rm -f std/typecons.$(OBJEXT)\n\t-rm -f std/typecons.lo\n\t-rm -f std/typetuple.$(OBJEXT)\n\t-rm -f std/typetuple.lo\n\t-rm -f std/uni.$(OBJEXT)\n\t-rm -f std/uni.lo\n\t-rm -f std/uri.$(OBJEXT)\n\t-rm -f std/uri.lo\n\t-rm -f std/utf.$(OBJEXT)\n\t-rm -f std/utf.lo\n\t-rm -f std/uuid.$(OBJEXT)\n\t-rm -f std/uuid.lo\n\t-rm -f std/variant.$(OBJEXT)\n\t-rm -f std/variant.lo\n\t-rm -f std/windows/charset.$(OBJEXT)\n\t-rm -f std/windows/charset.lo\n\t-rm -f std/windows/registry.$(OBJEXT)\n\t-rm -f std/windows/registry.lo\n\t-rm -f std/windows/syserror.$(OBJEXT)\n\t-rm -f std/windows/syserror.lo\n\t-rm -f std/xml.$(OBJEXT)\n\t-rm -f std/xml.lo\n\t-rm -f std/zip.$(OBJEXT)\n\t-rm -f std/zip.lo\n\t-rm -f std/zlib.$(OBJEXT)\n\t-rm -f std/zlib.lo\n\ndistclean-compile:\n\t-rm -f *.tab.c\n\n.c.o:\n\t$(COMPILE) -c $<\n\n.c.obj:\n\t$(COMPILE) -c `$(CYGPATH_W) '$<'`\n\n.c.lo:\n\t$(LTCOMPILE) -c -o $@ $<\n\nlibgphobos_la-adler32.lo: $(top_srcdir)/../zlib/adler32.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-adler32.lo `test -f '$(top_srcdir)/../zlib/adler32.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/adler32.c\n\nlibgphobos_la-compress.lo: $(top_srcdir)/../zlib/compress.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-compress.lo `test -f '$(top_srcdir)/../zlib/compress.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/compress.c\n\nlibgphobos_la-crc32.lo: $(top_srcdir)/../zlib/crc32.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-crc32.lo `test -f '$(top_srcdir)/../zlib/crc32.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/crc32.c\n\nlibgphobos_la-deflate.lo: $(top_srcdir)/../zlib/deflate.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-deflate.lo `test -f '$(top_srcdir)/../zlib/deflate.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/deflate.c\n\nlibgphobos_la-gzclose.lo: $(top_srcdir)/../zlib/gzclose.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-gzclose.lo `test -f '$(top_srcdir)/../zlib/gzclose.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzclose.c\n\nlibgphobos_la-gzlib.lo: $(top_srcdir)/../zlib/gzlib.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-gzlib.lo `test -f '$(top_srcdir)/../zlib/gzlib.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzlib.c\n\nlibgphobos_la-gzread.lo: $(top_srcdir)/../zlib/gzread.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-gzread.lo `test -f '$(top_srcdir)/../zlib/gzread.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzread.c\n\nlibgphobos_la-gzwrite.lo: $(top_srcdir)/../zlib/gzwrite.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-gzwrite.lo `test -f '$(top_srcdir)/../zlib/gzwrite.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzwrite.c\n\nlibgphobos_la-infback.lo: $(top_srcdir)/../zlib/infback.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-infback.lo `test -f '$(top_srcdir)/../zlib/infback.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/infback.c\n\nlibgphobos_la-inffast.lo: $(top_srcdir)/../zlib/inffast.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-inffast.lo `test -f '$(top_srcdir)/../zlib/inffast.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/inffast.c\n\nlibgphobos_la-inflate.lo: $(top_srcdir)/../zlib/inflate.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-inflate.lo `test -f '$(top_srcdir)/../zlib/inflate.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/inflate.c\n\nlibgphobos_la-inftrees.lo: $(top_srcdir)/../zlib/inftrees.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-inftrees.lo `test -f '$(top_srcdir)/../zlib/inftrees.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/inftrees.c\n\nlibgphobos_la-trees.lo: $(top_srcdir)/../zlib/trees.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-trees.lo `test -f '$(top_srcdir)/../zlib/trees.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/trees.c\n\nlibgphobos_la-uncompr.lo: $(top_srcdir)/../zlib/uncompr.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-uncompr.lo `test -f '$(top_srcdir)/../zlib/uncompr.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/uncompr.c\n\nlibgphobos_la-zutil.lo: $(top_srcdir)/../zlib/zutil.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_la-zutil.lo `test -f '$(top_srcdir)/../zlib/zutil.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/zutil.c\n\nlibgphobos_t_la-adler32.lo: $(top_srcdir)/../zlib/adler32.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-adler32.lo `test -f '$(top_srcdir)/../zlib/adler32.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/adler32.c\n\nlibgphobos_t_la-compress.lo: $(top_srcdir)/../zlib/compress.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-compress.lo `test -f '$(top_srcdir)/../zlib/compress.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/compress.c\n\nlibgphobos_t_la-crc32.lo: $(top_srcdir)/../zlib/crc32.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-crc32.lo `test -f '$(top_srcdir)/../zlib/crc32.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/crc32.c\n\nlibgphobos_t_la-deflate.lo: $(top_srcdir)/../zlib/deflate.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-deflate.lo `test -f '$(top_srcdir)/../zlib/deflate.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/deflate.c\n\nlibgphobos_t_la-gzclose.lo: $(top_srcdir)/../zlib/gzclose.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-gzclose.lo `test -f '$(top_srcdir)/../zlib/gzclose.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzclose.c\n\nlibgphobos_t_la-gzlib.lo: $(top_srcdir)/../zlib/gzlib.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-gzlib.lo `test -f '$(top_srcdir)/../zlib/gzlib.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzlib.c\n\nlibgphobos_t_la-gzread.lo: $(top_srcdir)/../zlib/gzread.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-gzread.lo `test -f '$(top_srcdir)/../zlib/gzread.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzread.c\n\nlibgphobos_t_la-gzwrite.lo: $(top_srcdir)/../zlib/gzwrite.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-gzwrite.lo `test -f '$(top_srcdir)/../zlib/gzwrite.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzwrite.c\n\nlibgphobos_t_la-infback.lo: $(top_srcdir)/../zlib/infback.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-infback.lo `test -f '$(top_srcdir)/../zlib/infback.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/infback.c\n\nlibgphobos_t_la-inffast.lo: $(top_srcdir)/../zlib/inffast.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-inffast.lo `test -f '$(top_srcdir)/../zlib/inffast.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/inffast.c\n\nlibgphobos_t_la-inflate.lo: $(top_srcdir)/../zlib/inflate.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-inflate.lo `test -f '$(top_srcdir)/../zlib/inflate.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/inflate.c\n\nlibgphobos_t_la-inftrees.lo: $(top_srcdir)/../zlib/inftrees.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-inftrees.lo `test -f '$(top_srcdir)/../zlib/inftrees.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/inftrees.c\n\nlibgphobos_t_la-trees.lo: $(top_srcdir)/../zlib/trees.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-trees.lo `test -f '$(top_srcdir)/../zlib/trees.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/trees.c\n\nlibgphobos_t_la-uncompr.lo: $(top_srcdir)/../zlib/uncompr.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-uncompr.lo `test -f '$(top_srcdir)/../zlib/uncompr.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/uncompr.c\n\nlibgphobos_t_la-zutil.lo: $(top_srcdir)/../zlib/zutil.c\n\t$(LIBTOOL)  --tag=CC $(libgphobos_t_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgphobos_t_la-zutil.lo `test -f '$(top_srcdir)/../zlib/zutil.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/zutil.c\n\nadler32.o: $(top_srcdir)/../zlib/adler32.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o adler32.o `test -f '$(top_srcdir)/../zlib/adler32.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/adler32.c\n\nadler32.obj: $(top_srcdir)/../zlib/adler32.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o adler32.obj `if test -f '$(top_srcdir)/../zlib/adler32.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/adler32.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/adler32.c'; fi`\n\ncompress.o: $(top_srcdir)/../zlib/compress.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o compress.o `test -f '$(top_srcdir)/../zlib/compress.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/compress.c\n\ncompress.obj: $(top_srcdir)/../zlib/compress.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o compress.obj `if test -f '$(top_srcdir)/../zlib/compress.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/compress.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/compress.c'; fi`\n\ncrc32.o: $(top_srcdir)/../zlib/crc32.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crc32.o `test -f '$(top_srcdir)/../zlib/crc32.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/crc32.c\n\ncrc32.obj: $(top_srcdir)/../zlib/crc32.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crc32.obj `if test -f '$(top_srcdir)/../zlib/crc32.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/crc32.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/crc32.c'; fi`\n\ndeflate.o: $(top_srcdir)/../zlib/deflate.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o deflate.o `test -f '$(top_srcdir)/../zlib/deflate.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/deflate.c\n\ndeflate.obj: $(top_srcdir)/../zlib/deflate.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o deflate.obj `if test -f '$(top_srcdir)/../zlib/deflate.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/deflate.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/deflate.c'; fi`\n\ngzclose.o: $(top_srcdir)/../zlib/gzclose.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gzclose.o `test -f '$(top_srcdir)/../zlib/gzclose.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzclose.c\n\ngzclose.obj: $(top_srcdir)/../zlib/gzclose.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gzclose.obj `if test -f '$(top_srcdir)/../zlib/gzclose.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/gzclose.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/gzclose.c'; fi`\n\ngzlib.o: $(top_srcdir)/../zlib/gzlib.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gzlib.o `test -f '$(top_srcdir)/../zlib/gzlib.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzlib.c\n\ngzlib.obj: $(top_srcdir)/../zlib/gzlib.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gzlib.obj `if test -f '$(top_srcdir)/../zlib/gzlib.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/gzlib.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/gzlib.c'; fi`\n\ngzread.o: $(top_srcdir)/../zlib/gzread.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gzread.o `test -f '$(top_srcdir)/../zlib/gzread.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzread.c\n\ngzread.obj: $(top_srcdir)/../zlib/gzread.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gzread.obj `if test -f '$(top_srcdir)/../zlib/gzread.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/gzread.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/gzread.c'; fi`\n\ngzwrite.o: $(top_srcdir)/../zlib/gzwrite.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gzwrite.o `test -f '$(top_srcdir)/../zlib/gzwrite.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/gzwrite.c\n\ngzwrite.obj: $(top_srcdir)/../zlib/gzwrite.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gzwrite.obj `if test -f '$(top_srcdir)/../zlib/gzwrite.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/gzwrite.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/gzwrite.c'; fi`\n\ninfback.o: $(top_srcdir)/../zlib/infback.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o infback.o `test -f '$(top_srcdir)/../zlib/infback.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/infback.c\n\ninfback.obj: $(top_srcdir)/../zlib/infback.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o infback.obj `if test -f '$(top_srcdir)/../zlib/infback.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/infback.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/infback.c'; fi`\n\ninffast.o: $(top_srcdir)/../zlib/inffast.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o inffast.o `test -f '$(top_srcdir)/../zlib/inffast.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/inffast.c\n\ninffast.obj: $(top_srcdir)/../zlib/inffast.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o inffast.obj `if test -f '$(top_srcdir)/../zlib/inffast.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/inffast.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/inffast.c'; fi`\n\ninflate.o: $(top_srcdir)/../zlib/inflate.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o inflate.o `test -f '$(top_srcdir)/../zlib/inflate.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/inflate.c\n\ninflate.obj: $(top_srcdir)/../zlib/inflate.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o inflate.obj `if test -f '$(top_srcdir)/../zlib/inflate.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/inflate.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/inflate.c'; fi`\n\ninftrees.o: $(top_srcdir)/../zlib/inftrees.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o inftrees.o `test -f '$(top_srcdir)/../zlib/inftrees.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/inftrees.c\n\ninftrees.obj: $(top_srcdir)/../zlib/inftrees.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o inftrees.obj `if test -f '$(top_srcdir)/../zlib/inftrees.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/inftrees.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/inftrees.c'; fi`\n\ntrees.o: $(top_srcdir)/../zlib/trees.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o trees.o `test -f '$(top_srcdir)/../zlib/trees.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/trees.c\n\ntrees.obj: $(top_srcdir)/../zlib/trees.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o trees.obj `if test -f '$(top_srcdir)/../zlib/trees.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/trees.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/trees.c'; fi`\n\nuncompr.o: $(top_srcdir)/../zlib/uncompr.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o uncompr.o `test -f '$(top_srcdir)/../zlib/uncompr.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/uncompr.c\n\nuncompr.obj: $(top_srcdir)/../zlib/uncompr.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o uncompr.obj `if test -f '$(top_srcdir)/../zlib/uncompr.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/uncompr.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/uncompr.c'; fi`\n\nzutil.o: $(top_srcdir)/../zlib/zutil.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o zutil.o `test -f '$(top_srcdir)/../zlib/zutil.c' || echo '$(srcdir)/'`$(top_srcdir)/../zlib/zutil.c\n\nzutil.obj: $(top_srcdir)/../zlib/zutil.c\n\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o zutil.obj `if test -f '$(top_srcdir)/../zlib/zutil.c'; then $(CYGPATH_W) '$(top_srcdir)/../zlib/zutil.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/../zlib/zutil.c'; fi`\n\nmostlyclean-libtool:\n\t-rm -f *.lo\n\nclean-libtool:\n\t-rm -rf .libs _libs\n\t-rm -rf etc/c/.libs etc/c/_libs\n\t-rm -rf std/.libs std/_libs\n\t-rm -rf std/algorithm/.libs std/algorithm/_libs\n\t-rm -rf std/container/.libs std/container/_libs\n\t-rm -rf std/datetime/.libs std/datetime/_libs\n\t-rm -rf std/digest/.libs std/digest/_libs\n\t-rm -rf std/experimental/.libs std/experimental/_libs\n\t-rm -rf std/experimental/allocator/.libs std/experimental/allocator/_libs\n\t-rm -rf std/experimental/allocator/building_blocks/.libs std/experimental/allocator/building_blocks/_libs\n\t-rm -rf std/experimental/logger/.libs std/experimental/logger/_libs\n\t-rm -rf std/internal/.libs std/internal/_libs\n\t-rm -rf std/internal/math/.libs std/internal/math/_libs\n\t-rm -rf std/internal/test/.libs std/internal/test/_libs\n\t-rm -rf std/internal/windows/.libs std/internal/windows/_libs\n\t-rm -rf std/net/.libs std/net/_libs\n\t-rm -rf std/range/.libs std/range/_libs\n\t-rm -rf std/regex/.libs std/regex/_libs\n\t-rm -rf std/regex/internal/.libs std/regex/internal/_libs\n\t-rm -rf std/windows/.libs std/windows/_libs\ninstall-toolexeclibDATA: $(toolexeclib_DATA)\n\t@$(NORMAL_INSTALL)\n\t@list='$(toolexeclib_DATA)'; test -n \"$(toolexeclibdir)\" || list=; \\\n\tif test -n \"$$list\"; then \\\n\t  echo \" $(MKDIR_P) '$(DESTDIR)$(toolexeclibdir)'\"; \\\n\t  $(MKDIR_P) \"$(DESTDIR)$(toolexeclibdir)\" || exit 1; \\\n\tfi; \\\n\tfor p in $$list; do \\\n\t  if test -f \"$$p\"; then d=; else d=\"$(srcdir)/\"; fi; \\\n\t  echo \"$$d$$p\"; \\\n\tdone | $(am__base_list) | \\\n\twhile read files; do \\\n\t  echo \" $(INSTALL_DATA) $$files '$(DESTDIR)$(toolexeclibdir)'\"; \\\n\t  $(INSTALL_DATA) $$files \"$(DESTDIR)$(toolexeclibdir)\" || exit $$?; \\\n\tdone\n\nuninstall-toolexeclibDATA:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(toolexeclib_DATA)'; test -n \"$(toolexeclibdir)\" || list=; \\\n\tfiles=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \\\n\tdir='$(DESTDIR)$(toolexeclibdir)'; $(am__uninstall_files_from_dir)\n\nID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)\n\tlist='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\tmkid -fID $$unique\ntags: TAGS\n\nTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \\\n\t\t$(TAGS_FILES) $(LISP)\n\tset x; \\\n\there=`pwd`; \\\n\tlist='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\tshift; \\\n\tif test -z \"$(ETAGS_ARGS)$$*$$unique\"; then :; else \\\n\t  test -n \"$$unique\" || unique=$$empty_fix; \\\n\t  if test $$# -gt 0; then \\\n\t    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \\\n\t      \"$$@\" $$unique; \\\n\t  else \\\n\t    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \\\n\t      $$unique; \\\n\t  fi; \\\n\tfi\nctags: CTAGS\nCTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \\\n\t\t$(TAGS_FILES) $(LISP)\n\tlist='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \\\n\t      END { if (nonempty) { for (i in files) print i; }; }'`; \\\n\ttest -z \"$(CTAGS_ARGS)$$unique\" \\\n\t  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \\\n\t     $$unique\n\nGTAGS:\n\there=`$(am__cd) $(top_builddir) && pwd` \\\n\t  && $(am__cd) $(top_srcdir) \\\n\t  && gtags -i $(GTAGS_ARGS) \"$$here\"\n\ndistclean-tags:\n\t-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags\ncheck-am: all-am\n\t$(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS)\ncheck: check-am\nall-am: Makefile $(LTLIBRARIES) $(DATA)\ninstalldirs:\n\tfor dir in \"$(DESTDIR)$(toolexeclibdir)\" \"$(DESTDIR)$(toolexeclibdir)\"; do \\\n\t  test -z \"$$dir\" || $(MKDIR_P) \"$$dir\"; \\\n\tdone\ninstall: install-am\ninstall-exec: install-exec-am\ninstall-data: install-data-am\nuninstall: uninstall-am\n\ninstall-am: all-am\n\t@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am\n\ninstallcheck: installcheck-am\ninstall-strip:\n\tif test -z '$(STRIP)'; then \\\n\t  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" \\\n\t    install_sh_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" INSTALL_STRIP_FLAG=-s \\\n\t      install; \\\n\telse \\\n\t  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" \\\n\t    install_sh_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" INSTALL_STRIP_FLAG=-s \\\n\t    \"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'\" install; \\\n\tfi\nmostlyclean-generic:\n\nclean-generic:\n\ndistclean-generic:\n\t-test -z \"$(CONFIG_CLEAN_FILES)\" || rm -f $(CONFIG_CLEAN_FILES)\n\t-test . = \"$(srcdir)\" || test -z \"$(CONFIG_CLEAN_VPATH_FILES)\" || rm -f $(CONFIG_CLEAN_VPATH_FILES)\n\t-rm -f ../testsuite/$(am__dirstamp)\n\t-rm -f etc/c/$(am__dirstamp)\n\t-rm -f std/$(am__dirstamp)\n\t-rm -f std/algorithm/$(am__dirstamp)\n\t-rm -f std/container/$(am__dirstamp)\n\t-rm -f std/datetime/$(am__dirstamp)\n\t-rm -f std/digest/$(am__dirstamp)\n\t-rm -f std/experimental/$(am__dirstamp)\n\t-rm -f std/experimental/allocator/$(am__dirstamp)\n\t-rm -f std/experimental/allocator/building_blocks/$(am__dirstamp)\n\t-rm -f std/experimental/logger/$(am__dirstamp)\n\t-rm -f std/internal/$(am__dirstamp)\n\t-rm -f std/internal/math/$(am__dirstamp)\n\t-rm -f std/internal/test/$(am__dirstamp)\n\t-rm -f std/internal/windows/$(am__dirstamp)\n\t-rm -f std/net/$(am__dirstamp)\n\t-rm -f std/range/$(am__dirstamp)\n\t-rm -f std/regex/$(am__dirstamp)\n\t-rm -f std/regex/internal/$(am__dirstamp)\n\t-rm -f std/windows/$(am__dirstamp)\n\nmaintainer-clean-generic:\n\t@echo \"This command is intended for maintainers to use\"\n\t@echo \"it deletes files that may require special tools to rebuild.\"\nclean: clean-am\n\nclean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \\\n\tclean-libtool clean-local clean-toolexeclibLTLIBRARIES \\\n\tmostlyclean-am\n\ndistclean: distclean-am\n\t-rm -f Makefile\ndistclean-am: clean-am distclean-compile distclean-generic \\\n\tdistclean-tags\n\ndvi: dvi-am\n\ndvi-am:\n\nhtml: html-am\n\nhtml-am:\n\ninfo: info-am\n\ninfo-am:\n\ninstall-data-am: install-data-local\n\ninstall-dvi: install-dvi-am\n\ninstall-dvi-am:\n\ninstall-exec-am: install-toolexeclibDATA \\\n\tinstall-toolexeclibLTLIBRARIES\n\ninstall-html: install-html-am\n\ninstall-html-am:\n\ninstall-info: install-info-am\n\ninstall-info-am:\n\ninstall-man:\n\ninstall-pdf: install-pdf-am\n\ninstall-pdf-am:\n\ninstall-ps: install-ps-am\n\ninstall-ps-am:\n\ninstallcheck-am:\n\nmaintainer-clean: maintainer-clean-am\n\t-rm -f Makefile\nmaintainer-clean-am: distclean-am maintainer-clean-generic\n\nmostlyclean: mostlyclean-am\n\nmostlyclean-am: mostlyclean-compile mostlyclean-generic \\\n\tmostlyclean-libtool\n\npdf: pdf-am\n\npdf-am:\n\nps: ps-am\n\nps-am:\n\nuninstall-am: uninstall-toolexeclibDATA \\\n\tuninstall-toolexeclibLTLIBRARIES\n\n.MAKE: check-am install-am install-strip\n\n.PHONY: CTAGS GTAGS all all-am check check-am clean \\\n\tclean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \\\n\tclean-libtool clean-local clean-toolexeclibLTLIBRARIES ctags \\\n\tdistclean distclean-compile distclean-generic \\\n\tdistclean-libtool distclean-tags dvi dvi-am html html-am info \\\n\tinfo-am install install-am install-data install-data-am \\\n\tinstall-data-local install-dvi install-dvi-am install-exec \\\n\tinstall-exec-am install-html install-html-am install-info \\\n\tinstall-info-am install-man install-pdf install-pdf-am \\\n\tinstall-ps install-ps-am install-strip install-toolexeclibDATA \\\n\tinstall-toolexeclibLTLIBRARIES installcheck installcheck-am \\\n\tinstalldirs maintainer-clean maintainer-clean-generic \\\n\tmostlyclean mostlyclean-compile mostlyclean-generic \\\n\tmostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \\\n\tuninstall-am uninstall-toolexeclibDATA \\\n\tuninstall-toolexeclibLTLIBRARIES\n\n\n# Compile D into normal object files\n.d.o:\n\t$(GDC) $(GDCFLAGS) $(MULTIFLAGS) $(D_EXTRA_DFLAGS) -c -o $@ $<\n\n# Compile D sources with libtool\n.d.lo:\n\t$(LTDCOMPILE) $(GDCFLAGS) $(MULTIFLAGS) $(D_EXTRA_DFLAGS) -c -o $@ $<\n\n# Unittest rules. Unfortunately we can't use _DFLAGS in automake without\n# explicit D support, so use this hack.\n# Compile D sources with libtool and test flags\n%.t.lo : %.d\n\t$(LTDCOMPILE) $(GDCFLAGSX) $(MULTIFLAGS) $(D_EXTRA_DFLAGS) -c -o $@ $<\n\n# Compile objects for static linking with test flags\n# Automake breaks empty rules, so use the shell NOP :\n%.t.o : %.t.lo\n\t@:\n\n# Extra install and clean rules.\n# This does not delete the .libs/.t.o files, but deleting\n# the .lo is good enough to rerun the rules\nclean-local:\n\trm -f $(PHOBOS_TEST_LOBJECTS)\n\trm -f $(PHOBOS_TEST_OBJECTS)\n\n# Handles generated files as well\ninstall-data-local:\n\tfor file in $(ALL_PHOBOS_INSTALL_DSOURCES); do \\\n\t  if test -f $$file; then \\\n\t    $(INSTALL_HEADER) -D $$file $(DESTDIR)$(gdc_include_dir)/$$file ; \\\n\t  else \\\n\t    $(INSTALL_HEADER) -D $(srcdir)/$$file \\\n\t      $(DESTDIR)$(gdc_include_dir)/$$file ; \\\n\t  fi ; \\\n\tdone\n\n# Tell versions [3.59,3.63) of GNU make to not export all variables.\n# Otherwise a system limit (for SysV at least) may be exceeded.\n.NOEXPORT:\n"
  },
  {
    "path": "libphobos/src/etc/c/curl.d",
    "content": "/**\n   This is an interface to the libcurl library.\n\n   Converted to D from curl headers by $(LINK2 http://www.digitalmars.com/d/2.0/htod.html, htod) and\n   cleaned up by Jonas Drewsen (jdrewsen)\n\n   Windows x86 note:\n   A DMD compatible libcurl static library can be downloaded from the dlang.org\n   $(LINK2 http://dlang.org/download.html, download page).\n*/\n\n/* **************************************************************************\n *                                  _   _ ____  _\n *  Project                     ___| | | |  _ \\| |\n *                             / __| | | | |_) | |\n *                            | (__| |_| |  _ <| |___\n *                             \\___|\\___/|_| \\_\\_____|\n */\n\n/**\n * Copyright (C) 1998 - 2010, Daniel Stenberg, &lt;daniel@haxx.se&gt;, et al.\n *\n * This software is licensed as described in the file COPYING, which\n * you should have received as part of this distribution. The terms\n * are also available at $(LINK http://curl.haxx.se/docs/copyright.html).\n *\n * You may opt to use, copy, modify, merge, publish, distribute and/or sell\n * copies of the Software, and permit persons to whom the Software is\n * furnished to do so, under the terms of the COPYING file.\n *\n * This software is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF ANY\n * KIND, either express or implied.\n *\n ***************************************************************************/\n\nmodule etc.c.curl;\n\nimport core.stdc.config;\nimport core.stdc.time;\nimport std.socket;\n\n// linux\nimport core.sys.posix.sys.socket;\n\n//\n// LICENSE FROM CURL HEADERS\n//\n\n/** This is the global package copyright */\nenum LIBCURL_COPYRIGHT = \"1996 - 2010 Daniel Stenberg, <daniel@haxx.se>.\";\n\n/** This is the version number of the libcurl package from which this header\n   file origins: */\nenum LIBCURL_VERSION = \"7.21.4\";\n\n/** The numeric version number is also available \"in parts\" by using these\n   constants */\nenum LIBCURL_VERSION_MAJOR = 7;\n/// ditto\nenum LIBCURL_VERSION_MINOR = 21;\n/// ditto\nenum LIBCURL_VERSION_PATCH = 4;\n\n/** This is the numeric version of the libcurl version number, meant for easier\n   parsing and comparions by programs. The LIBCURL_VERSION_NUM define will\n   always follow this syntax:\n\n         0xXXYYZZ\n\n   Where XX, YY and ZZ are the main version, release and patch numbers in\n   hexadecimal (using 8 bits each). All three numbers are always represented\n   using two digits.  1.2 would appear as \"0x010200\" while version 9.11.7\n   appears as \"0x090b07\".\n\n   This 6-digit (24 bits) hexadecimal number does not show pre-release number,\n   and it is always a greater number in a more recent release. It makes\n   comparisons with greater than and less than work.\n*/\n\nenum LIBCURL_VERSION_NUM = 0x071504;\n\n/**\n * This is the date and time when the full source package was created. The\n * timestamp is not stored in git, as the timestamp is properly set in the\n * tarballs by the maketgz script.\n *\n * The format of the date should follow this template:\n *\n * \"Mon Feb 12 11:35:33 UTC 2007\"\n */\nenum LIBCURL_TIMESTAMP = \"Thu Feb 17 12:19:40 UTC 2011\";\n\n/** Data type definition of curl_off_t.\n *\n * jdrewsen - Always 64bit signed and that is what long is in D.\n *\n * Comment below is from curlbuild.h:\n *\n * NOTE 2:\n *\n * For any given platform/compiler curl_off_t must be typedef'ed to a\n * 64-bit wide signed integral data type. The width of this data type\n * must remain constant and independent of any possible large file\n * support settings.\n *\n * As an exception to the above, curl_off_t shall be typedef'ed to a\n * 32-bit wide signed integral data type if there is no 64-bit type.\n */\nalias curl_off_t = long;\n\n///\nalias CURL = void;\n\n/// jdrewsen - Get socket alias from std.socket\nalias curl_socket_t = socket_t;\n\n/// jdrewsen - Would like to get socket error constant from std.socket by it is private atm.\nversion (Windows)\n{\n  import core.sys.windows.windows, core.sys.windows.winsock2;\n  enum CURL_SOCKET_BAD = SOCKET_ERROR;\n}\nversion (Posix) enum CURL_SOCKET_BAD = -1;\n\n///\nextern (C) struct curl_httppost\n{\n    curl_httppost *next;        /** next entry in the list */\n    char *name;                 /** pointer to allocated name */\n    c_long namelength;          /** length of name length */\n    char *contents;             /** pointer to allocated data contents */\n    c_long contentslength;      /** length of contents field */\n    char *buffer;               /** pointer to allocated buffer contents */\n    c_long bufferlength;        /** length of buffer field */\n    char *contenttype;          /** Content-Type */\n    curl_slist *contentheader;  /** list of extra headers for this form */\n    curl_httppost *more;        /** if one field name has more than one\n                                    file, this link should link to following\n                                    files */\n    c_long flags;               /** as defined below */\n    char *showfilename;         /** The file name to show. If not set, the\n                                    actual file name will be used (if this\n                                    is a file part) */\n    void *userp;                /** custom pointer used for\n                                    HTTPPOST_CALLBACK posts */\n}\n\nenum HTTPPOST_FILENAME    = 1;  /** specified content is a file name */\nenum HTTPPOST_READFILE    = 2;  /** specified content is a file name */\nenum HTTPPOST_PTRNAME     = 4;  /** name is only stored pointer\n                                    do not free in formfree */\nenum HTTPPOST_PTRCONTENTS = 8;  /** contents is only stored pointer\n                                    do not free in formfree */\nenum HTTPPOST_BUFFER      = 16; /** upload file from buffer */\nenum HTTPPOST_PTRBUFFER   = 32; /** upload file from pointer contents */\nenum HTTPPOST_CALLBACK    = 64; /** upload file contents by using the\n                                    regular read callback to get the data\n                                    and pass the given pointer as custom\n                                    pointer */\n\n///\nalias curl_progress_callback = int function(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);\n\n/** Tests have proven that 20K is a very bad buffer size for uploads on\n   Windows, while 16K for some odd reason performed a lot better.\n   We do the ifndef check to allow this value to easier be changed at build\n   time for those who feel adventurous. The practical minimum is about\n   400 bytes since libcurl uses a buffer of this size as a scratch area\n   (unrelated to network send operations). */\nenum CURL_MAX_WRITE_SIZE = 16_384;\n\n/** The only reason to have a max limit for this is to avoid the risk of a bad\n   server feeding libcurl with a never-ending header that will cause reallocs\n   infinitely */\nenum CURL_MAX_HTTP_HEADER = (100*1024);\n\n\n/** This is a magic return code for the write callback that, when returned,\n   will signal libcurl to pause receiving on the current transfer. */\nenum CURL_WRITEFUNC_PAUSE = 0x10000001;\n\n///\nalias curl_write_callback = size_t function(char *buffer, size_t size, size_t nitems, void *outstream);\n\n/** enumeration of file types */\nenum CurlFileType {\n    file,       ///\n    directory,  ///\n    symlink,    ///\n    device_block, ///\n    device_char, ///\n    namedpipe,  ///\n    socket,     ///\n    door,       ///\n    unknown /** is possible only on Sun Solaris now */\n}\n\n///\nalias curlfiletype = int;\n\n///\nenum CurlFInfoFlagKnown {\n  filename    = 1,      ///\n  filetype    = 2,      ///\n  time        = 4,      ///\n  perm        = 8,      ///\n  uid         = 16,     ///\n  gid         = 32,     ///\n  size        = 64,     ///\n  hlinkcount  = 128     ///\n}\n\n/** Content of this structure depends on information which is known and is\n   achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man\n   page for callbacks returning this structure -- some fields are mandatory,\n   some others are optional. The FLAG field has special meaning. */\n\n\n/** If some of these fields is not NULL, it is a pointer to b_data. */\nextern (C) struct _N2\n{\n    char *time;   ///\n    char *perm;   ///\n    char *user;   ///\n    char *group;  ///\n    char *target; /** pointer to the target filename of a symlink */\n}\n\n/** Content of this structure depends on information which is known and is\n   achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man\n   page for callbacks returning this structure -- some fields are mandatory,\n   some others are optional. The FLAG field has special meaning. */\nextern (C) struct curl_fileinfo\n{\n    char *filename;             ///\n    curlfiletype filetype;      ///\n    time_t time;                ///\n    uint perm;                  ///\n    int uid;                    ///\n    int gid;                    ///\n    curl_off_t size;            ///\n    c_long hardlinks;           ///\n    _N2 strings;                ///\n    uint flags;                 ///\n    char *b_data;               ///\n    size_t b_size;              ///\n    size_t b_used;              ///\n}\n\n/** return codes for CURLOPT_CHUNK_BGN_FUNCTION */\nenum CurlChunkBgnFunc {\n  ok = 0,   ///\n  fail = 1, /** tell the lib to end the task */\n  skip = 2 /** skip this chunk over */\n}\n\n/** if splitting of data transfer is enabled, this callback is called before\n   download of an individual chunk started. Note that parameter \"remains\" works\n   only for FTP wildcard downloading (for now), otherwise is not used */\nalias curl_chunk_bgn_callback = c_long function(const(void) *transfer_info, void *ptr, int remains);\n\n/** return codes for CURLOPT_CHUNK_END_FUNCTION */\nenum CurlChunkEndFunc {\n  ok = 0,       ///\n  fail = 1,     ///\n}\n/** If splitting of data transfer is enabled this callback is called after\n   download of an individual chunk finished.\n   Note! After this callback was set then it have to be called FOR ALL chunks.\n   Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC.\n   This is the reason why we don't need \"transfer_info\" parameter in this\n   callback and we are not interested in \"remains\" parameter too. */\nalias curl_chunk_end_callback = c_long function(void *ptr);\n\n/** return codes for FNMATCHFUNCTION */\nenum CurlFnMAtchFunc {\n  match = 0,    ///\n  nomatch = 1,  ///\n  fail = 2      ///\n}\n\n/** callback type for wildcard downloading pattern matching. If the\n   string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */\nalias curl_fnmatch_callback = int function(void *ptr, in const(char) *pattern, in const(char) *string);\n\n/// seek whence...\nenum CurlSeekPos {\n  set,          ///\n  current,      ///\n  end           ///\n}\n\n/** These are the return codes for the seek callbacks */\nenum CurlSeek {\n  ok,       ///\n  fail,     /** fail the entire transfer */\n  cantseek  /** tell libcurl seeking can't be done, so\n               libcurl might try other means instead */\n}\n\n///\nalias curl_seek_callback = int function(void *instream, curl_off_t offset, int origin);\n\n///\nenum CurlReadFunc {\n  /** This is a return code for the read callback that, when returned, will\n     signal libcurl to immediately abort the current transfer. */\n  abort = 0x10000000,\n\n  /** This is a return code for the read callback that, when returned,\n     will const signal libcurl to pause sending data on the current\n     transfer. */\n  pause = 0x10000001\n}\n\n///\nalias curl_read_callback = size_t function(char *buffer, size_t size, size_t nitems, void *instream);\n\n///\nenum CurlSockType {\n    ipcxn, /** socket created for a specific IP connection */\n    last   /** never use */\n}\n///\nalias curlsocktype = int;\n\n///\nalias curl_sockopt_callback = int function(void *clientp, curl_socket_t curlfd, curlsocktype purpose);\n\n/** addrlen was a socklen_t type before 7.18.0 but it turned really\n   ugly and painful on the systems that lack this type */\nextern (C) struct curl_sockaddr\n{\n    int family;   ///\n    int socktype; ///\n    int protocol; ///\n    uint addrlen; /** addrlen was a socklen_t type before 7.18.0 but it\n                     turned really ugly and painful on the systems that\n                     lack this type */\n    sockaddr addr; ///\n}\n\n///\nalias curl_opensocket_callback = curl_socket_t function(void *clientp, curlsocktype purpose, curl_sockaddr *address);\n\n///\nenum CurlIoError\n{\n    ok,            /** I/O operation successful */\n    unknowncmd,    /** command was unknown to callback */\n    failrestart,   /** failed to restart the read */\n    last           /** never use */\n}\n///\nalias curlioerr = int;\n\n///\nenum CurlIoCmd {\n    nop,         /** command was unknown to callback */\n    restartread, /** failed to restart the read */\n    last,        /** never use */\n}\n///\nalias curliocmd = int;\n\n///\nalias curl_ioctl_callback = curlioerr function(CURL *handle, int cmd, void *clientp);\n\n/**\n * The following typedef's are signatures of malloc, free, realloc, strdup and\n * calloc respectively.  Function pointers of these types can be passed to the\n * curl_global_init_mem() function to set user defined memory management\n * callback routines.\n */\nalias curl_malloc_callback = void* function(size_t size);\n/// ditto\nalias curl_free_callback = void function(void *ptr);\n/// ditto\nalias curl_realloc_callback = void* function(void *ptr, size_t size);\n/// ditto\nalias curl_strdup_callback = char * function(in const(char) *str);\n/// ditto\nalias curl_calloc_callback = void* function(size_t nmemb, size_t size);\n\n/** the kind of data that is passed to information_callback*/\nenum CurlCallbackInfo {\n    text,       ///\n    header_in,  ///\n    header_out, ///\n    data_in,    ///\n    data_out,   ///\n    ssl_data_in, ///\n    ssl_data_out, ///\n    end         ///\n}\n///\nalias curl_infotype = int;\n\n///\nalias curl_debug_callback =\n        int function(CURL *handle,        /** the handle/transfer this concerns */\n                     curl_infotype type,  /** what kind of data */\n                     char *data,          /** points to the data */\n                     size_t size,         /** size of the data pointed to */\n                     void *userptr        /** whatever the user please */\n                    );\n\n/** All possible error codes from all sorts of curl functions. Future versions\n   may return other values, stay prepared.\n\n   Always add new return codes last. Never *EVER* remove any. The return\n   codes must remain the same!\n */\nenum CurlError\n{\n    ok,                          ///\n    unsupported_protocol,        /** 1 */\n    failed_init,                 /** 2 */\n    url_malformat,               /** 3 */\n    not_built_in,                /** 4 - [was obsoleted in August 2007 for\n                                    7.17.0, reused in April 2011 for 7.21.5] */\n    couldnt_resolve_proxy,       /** 5 */\n    couldnt_resolve_host,        /** 6 */\n    couldnt_connect,             /** 7 */\n    ftp_weird_server_reply,      /** 8 */\n    remote_access_denied,        /** 9 a service was denied by the server\n                                    due to lack of access - when login fails\n                                    this is not returned. */\n    obsolete10,                  /** 10 - NOT USED */\n    ftp_weird_pass_reply,        /** 11 */\n    obsolete12,                  /** 12 - NOT USED */\n    ftp_weird_pasv_reply,        /** 13 */\n    ftp_weird_227_format,        /** 14 */\n    ftp_cant_get_host,           /** 15 */\n    obsolete16,                  /** 16 - NOT USED */\n    ftp_couldnt_set_type,        /** 17 */\n    partial_file,                /** 18 */\n    ftp_couldnt_retr_file,       /** 19 */\n    obsolete20,                  /** 20 - NOT USED */\n    quote_error,                 /** 21 - quote command failure */\n    http_returned_error,         /** 22 */\n    write_error,                 /** 23 */\n    obsolete24,                  /** 24 - NOT USED */\n    upload_failed,               /** 25 - failed upload \"command\" */\n    read_error,                  /** 26 - couldn't open/read from file */\n    out_of_memory,               /** 27 */\n    /** Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error\n             instead of a memory allocation error if CURL_DOES_CONVERSIONS\n             is defined\n    */\n    operation_timedout,          /** 28 - the timeout time was reached */\n    obsolete29,                  /** 29 - NOT USED */\n    ftp_port_failed,             /** 30 - FTP PORT operation failed */\n    ftp_couldnt_use_rest,        /** 31 - the REST command failed */\n    obsolete32,                  /** 32 - NOT USED */\n    range_error,                 /** 33 - RANGE \"command\" didn't work */\n    http_post_error,             /** 34 */\n    ssl_connect_error,           /** 35 - wrong when connecting with SSL */\n    bad_download_resume,         /** 36 - couldn't resume download */\n    file_couldnt_read_file,      /** 37 */\n    ldap_cannot_bind,            /** 38 */\n    ldap_search_failed,          /** 39 */\n    obsolete40,                  /** 40 - NOT USED */\n    function_not_found,          /** 41 */\n    aborted_by_callback,         /** 42 */\n    bad_function_argument,       /** 43 */\n    obsolete44,                  /** 44 - NOT USED */\n    interface_failed,            /** 45 - CURLOPT_INTERFACE failed */\n    obsolete46,                  /** 46 - NOT USED */\n    too_many_redirects,          /** 47 - catch endless re-direct loops */\n    unknown_option,              /** 48 - User specified an unknown option */\n    telnet_option_syntax,        /** 49 - Malformed telnet option */\n    obsolete50,                  /** 50 - NOT USED */\n    peer_failed_verification,    /** 51 - peer's certificate or fingerprint\n                                         wasn't verified fine */\n    got_nothing,                 /** 52 - when this is a specific error */\n    ssl_engine_notfound,         /** 53 - SSL crypto engine not found */\n    ssl_engine_setfailed,        /** 54 - can not set SSL crypto engine as default */\n    send_error,                  /** 55 - failed sending network data */\n    recv_error,                  /** 56 - failure in receiving network data */\n    obsolete57,                  /** 57 - NOT IN USE */\n    ssl_certproblem,             /** 58 - problem with the local certificate */\n    ssl_cipher,                  /** 59 - couldn't use specified cipher */\n    ssl_cacert,                  /** 60 - problem with the CA cert (path?) */\n    bad_content_encoding,        /** 61 - Unrecognized transfer encoding */\n    ldap_invalid_url,            /** 62 - Invalid LDAP URL */\n    filesize_exceeded,           /** 63 - Maximum file size exceeded */\n    use_ssl_failed,              /** 64 - Requested FTP SSL level failed */\n    send_fail_rewind,            /** 65 - Sending the data requires a rewind that failed */\n    ssl_engine_initfailed,       /** 66 - failed to initialise ENGINE */\n    login_denied,                /** 67 - user, password or similar was not accepted and we failed to login */\n    tftp_notfound,               /** 68 - file not found on server */\n    tftp_perm,                   /** 69 - permission problem on server */\n    remote_disk_full,            /** 70 - out of disk space on server */\n    tftp_illegal,                /** 71 - Illegal TFTP operation */\n    tftp_unknownid,              /** 72 - Unknown transfer ID */\n    remote_file_exists,          /** 73 - File already exists */\n    tftp_nosuchuser,             /** 74 - No such user */\n    conv_failed,                 /** 75 - conversion failed */\n    conv_reqd,                   /** 76 - caller must register conversion\n                                    callbacks using curl_easy_setopt options\n                                    CURLOPT_CONV_FROM_NETWORK_FUNCTION,\n                                    CURLOPT_CONV_TO_NETWORK_FUNCTION, and\n                                    CURLOPT_CONV_FROM_UTF8_FUNCTION */\n    ssl_cacert_badfile,          /** 77 - could not load CACERT file, missing  or wrong format */\n    remote_file_not_found,       /** 78 - remote file not found */\n    ssh,                         /** 79 - error from the SSH layer, somewhat\n                                    generic so the error message will be of\n                                    interest when this has happened */\n    ssl_shutdown_failed,         /** 80 - Failed to shut down the SSL connection */\n    again,                       /** 81 - socket is not ready for send/recv,\n                                    wait till it's ready and try again (Added\n                                    in 7.18.2) */\n    ssl_crl_badfile,             /** 82 - could not load CRL file, missing or wrong format (Added in 7.19.0) */\n    ssl_issuer_error,            /** 83 - Issuer check failed.  (Added in 7.19.0) */\n    ftp_pret_failed,             /** 84 - a PRET command failed */\n    rtsp_cseq_error,             /** 85 - mismatch of RTSP CSeq numbers */\n    rtsp_session_error,          /** 86 - mismatch of RTSP Session Identifiers */\n    ftp_bad_file_list,           /** 87 - unable to parse FTP file list */\n    chunk_failed,                /** 88 - chunk callback reported error */\n    curl_last                    /** never use! */\n}\n///\nalias CURLcode = int;\n\n/** This prototype applies to all conversion callbacks */\nalias curl_conv_callback = CURLcode function(char *buffer, size_t length);\n\n/** actually an OpenSSL SSL_CTX */\nalias curl_ssl_ctx_callback =\n        CURLcode function(CURL *curl,    /** easy handle */\n                          void *ssl_ctx, /** actually an OpenSSL SSL_CTX */\n                          void *userptr\n                         );\n\n///\nenum CurlProxy {\n    http,         /** added in 7.10, new in 7.19.4 default is to use CONNECT HTTP/1.1 */\n    http_1_0,     /** added in 7.19.4, force to use CONNECT HTTP/1.0  */\n    socks4 = 4,   /** support added in 7.15.2, enum existed already in 7.10 */\n    socks5 = 5,   /** added in 7.10 */\n    socks4a = 6,  /** added in 7.18.0 */\n    socks5_hostname =7   /** Use the SOCKS5 protocol but pass along the\n                         host name rather than the IP address. added\n                         in 7.18.0 */\n}\n///\nalias curl_proxytype = int;\n\n///\nenum CurlAuth : long {\n  none =         0,\n  basic =        1,  /** Basic (default) */\n  digest =       2,  /** Digest */\n  gssnegotiate = 4,  /** GSS-Negotiate */\n  ntlm =         8,  /** NTLM */\n  digest_ie =    16, /** Digest with IE flavour */\n  only =         2_147_483_648, /** used together with a single other\n                                type to force no auth or just that\n                                single type */\n  any = -17,     /* (~CURLAUTH_DIGEST_IE) */  /** all fine types set */\n  anysafe = -18  /* (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) */ ///\n}\n\n///\nenum CurlSshAuth {\n  any       = -1,     /** all types supported by the server */\n  none      = 0,      /** none allowed, silly but complete */\n  publickey = 1, /** public/private key files */\n  password  = 2, /** password */\n  host      = 4, /** host key files */\n  keyboard  = 8, /** keyboard interactive */\n  default_  = -1 // CURLSSH_AUTH_ANY;\n}\n///\nenum CURL_ERROR_SIZE = 256;\n/** points to a zero-terminated string encoded with base64\n   if len is zero, otherwise to the \"raw\" data */\nenum CurlKHType\n{\n    unknown,    ///\n    rsa1,       ///\n    rsa,        ///\n    dss         ///\n}\n///\nextern (C) struct curl_khkey\n{\n    const(char) *key; /** points to a zero-terminated string encoded with base64\n                         if len is zero, otherwise to the \"raw\" data */\n    size_t len; ///\n    CurlKHType keytype; ///\n}\n\n/** this is the set of return values expected from the curl_sshkeycallback\n   callback */\nenum CurlKHStat {\n    fine_add_to_file, ///\n    fine,       ///\n    reject,  /** reject the connection, return an error */\n    defer,   /** do not accept it, but we can't answer right now so\n                this causes a CURLE_DEFER error but otherwise the\n                connection will be left intact etc */\n    last     /** not for use, only a marker for last-in-list */\n}\n\n/** this is the set of status codes pass in to the callback */\nenum CurlKHMatch {\n    ok,       /** match */\n    mismatch, /** host found, key mismatch! */\n    missing,  /** no matching host/key found */\n    last      /** not for use, only a marker for last-in-list */\n}\n\n///\nalias curl_sshkeycallback =\n        int function(CURL *easy,            /** easy handle */\n                     const(curl_khkey) *knownkey,  /** known */\n                     const(curl_khkey) *foundkey,  /** found */\n                     CurlKHMatch m,         /** libcurl's view on the keys */\n                     void *clientp          /** custom pointer passed from app */\n                    );\n\n/** parameter for the CURLOPT_USE_SSL option */\nenum CurlUseSSL {\n    none,     /** do not attempt to use SSL */\n    tryssl,   /** try using SSL, proceed anyway otherwise */\n    control,  /** SSL for the control connection or fail */\n    all,      /** SSL for all communication or fail */\n    last      /** not an option, never use */\n}\n///\nalias curl_usessl = int;\n\n/** parameter for the CURLOPT_FTP_SSL_CCC option */\nenum CurlFtpSSL {\n    ccc_none,     /** do not send CCC */\n    ccc_passive,  /** Let the server initiate the shutdown */\n    ccc_active,   /** Initiate the shutdown */\n    ccc_last      /** not an option, never use */\n}\n///\nalias curl_ftpccc = int;\n\n/** parameter for the CURLOPT_FTPSSLAUTH option */\nenum CurlFtpAuth {\n    defaultauth, /** let libcurl decide */\n    ssl,         /** use \"AUTH SSL\" */\n    tls,         /** use \"AUTH TLS\" */\n    last         /** not an option, never use */\n}\n///\nalias curl_ftpauth = int;\n\n/** parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */\nenum CurlFtp {\n    create_dir_none,   /** do NOT create missing dirs! */\n    create_dir,        /** (FTP/SFTP) if CWD fails, try MKD and then CWD again if MKD\n                          succeeded, for SFTP this does similar magic */\n    create_dir_retry,  /** (FTP only) if CWD fails, try MKD and then CWD again even if MKD\n                          failed! */\n    create_dir_last    /** not an option, never use */\n}\n///\nalias curl_ftpcreatedir = int;\n\n/** parameter for the CURLOPT_FTP_FILEMETHOD option */\nenum CurlFtpMethod {\n    defaultmethod,    /** let libcurl pick */\n    multicwd,         /** single CWD operation for each path part */\n    nocwd,            /** no CWD at all */\n    singlecwd,        /** one CWD to full dir, then work on file */\n    last              /** not an option, never use */\n}\n///\nalias curl_ftpmethod = int;\n\n/** CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */\nenum CurlProto {\n  http   = 1,   ///\n  https  = 2,   ///\n  ftp    = 4,   ///\n  ftps   = 8,   ///\n  scp    = 16,  ///\n  sftp   = 32,  ///\n  telnet = 64,  ///\n  ldap   = 128, ///\n  ldaps  = 256, ///\n  dict   = 512, ///\n  file   = 1024,        ///\n  tftp   = 2048,        ///\n  imap   = 4096,        ///\n  imaps  = 8192,        ///\n  pop3   = 16_384,       ///\n  pop3s  = 32_768,       ///\n  smtp   = 65_536,       ///\n  smtps  = 131_072,      ///\n  rtsp   = 262_144,      ///\n  rtmp   = 524_288,      ///\n  rtmpt  = 1_048_576,     ///\n  rtmpe  = 2_097_152,     ///\n  rtmpte = 4_194_304,     ///\n  rtmps  = 8_388_608,     ///\n  rtmpts = 16_777_216,    ///\n  gopher = 33_554_432,    ///\n  all    = -1 /** enable everything */\n}\n\n/** long may be 32 or 64 bits, but we should never depend on anything else\n   but 32 */\nenum CURLOPTTYPE_LONG = 0;\n/// ditto\nenum CURLOPTTYPE_OBJECTPOINT = 10_000;\n/// ditto\nenum CURLOPTTYPE_FUNCTIONPOINT = 20_000;\n\n/// ditto\nenum CURLOPTTYPE_OFF_T = 30_000;\n/** name is uppercase CURLOPT_$(LT)name$(GT),\n   type is one of the defined CURLOPTTYPE_$(LT)type$(GT)\n   number is unique identifier */\n\n/** The macro \"##\" is ISO C, we assume pre-ISO C doesn't support it. */\nalias LONG = CURLOPTTYPE_LONG;\n/// ditto\nalias OBJECTPOINT = CURLOPTTYPE_OBJECTPOINT;\n/// ditto\nalias FUNCTIONPOINT = CURLOPTTYPE_FUNCTIONPOINT;\n\n/// ditto\nalias OFF_T = CURLOPTTYPE_OFF_T;\n\n///\nenum CurlOption {\n  /** This is the FILE * or void * the regular output should be written to. */\n  file = 10_001,\n  /** The full URL to get/put */\n  url,\n  /** Port number to connect to, if other than default. */\n  port = 3,\n  /** Name of proxy to use. */\n  proxy = 10_004,\n  /** \"name:password\" to use when fetching. */\n  userpwd,\n  /** \"name:password\" to use with proxy. */\n  proxyuserpwd,\n  /** Range to get, specified as an ASCII string. */\n  range,\n  /** not used */\n\n  /** Specified file stream to upload from (use as input): */\n  infile = 10_009,\n  /** Buffer to receive error messages in, must be at least CURL_ERROR_SIZE\n   * bytes big. If this is not used, error messages go to stderr instead: */\n  errorbuffer,\n  /** Function that will be called to store the output (instead of fwrite). The\n   * parameters will use fwrite() syntax, make sure to follow them. */\n  writefunction = 20_011,\n  /** Function that will be called to read the input (instead of fread). The\n   * parameters will use fread() syntax, make sure to follow them. */\n  readfunction,\n  /** Time-out the read operation after this amount of seconds */\n  timeout = 13,\n  /** If the CURLOPT_INFILE is used, this can be used to inform libcurl about\n   * how large the file being sent really is. That allows better error\n   * checking and better verifies that the upload was successful. -1 means\n   * unknown size.\n   *\n   * For large file support, there is also a _LARGE version of the key\n   * which takes an off_t type, allowing platforms with larger off_t\n   * sizes to handle larger files.  See below for INFILESIZE_LARGE.\n   */\n  infilesize,\n  /** POST static input fields. */\n  postfields = 10_015,\n  /** Set the referrer page (needed by some CGIs) */\n  referer,\n  /** Set the FTP PORT string (interface name, named or numerical IP address)\n     Use i.e '-' to use default address. */\n  ftpport,\n  /** Set the User-Agent string (examined by some CGIs) */\n  useragent,\n  /** If the download receives less than \"low speed limit\" bytes/second\n   * during \"low speed time\" seconds, the operations is aborted.\n   * You could i.e if you have a pretty high speed connection, abort if\n   * it is less than 2000 bytes/sec during 20 seconds.\n   */\n\n  /** Set the \"low speed limit\" */\n  low_speed_limit = 19,\n  /** Set the \"low speed time\" */\n  low_speed_time,\n  /** Set the continuation offset.\n   *\n   * Note there is also a _LARGE version of this key which uses\n   * off_t types, allowing for large file offsets on platforms which\n   * use larger-than-32-bit off_t's.  Look below for RESUME_FROM_LARGE.\n   */\n  resume_from,\n  /** Set cookie in request: */\n  cookie = 10_022,\n  /** This points to a linked list of headers, struct curl_slist kind */\n  httpheader,\n  /** This points to a linked list of post entries, struct curl_httppost */\n  httppost,\n  /** name of the file keeping your private SSL-certificate */\n  sslcert,\n  /** password for the SSL or SSH private key */\n  keypasswd,\n  /** send TYPE parameter? */\n  crlf = 27,\n  /** send linked-list of QUOTE commands */\n  quote = 10_028,\n  /** send FILE * or void * to store headers to, if you use a callback it\n     is simply passed to the callback unmodified */\n  writeheader,\n  /** point to a file to read the initial cookies from, also enables\n     \"cookie awareness\" */\n  cookiefile = 10_031,\n  /** What version to specifically try to use.\n     See CURL_SSLVERSION defines below. */\n  sslversion = 32,\n  /** What kind of HTTP time condition to use, see defines */\n  timecondition,\n  /** Time to use with the above condition. Specified in number of seconds\n     since 1 Jan 1970 */\n  timevalue,\n  /* 35 = OBSOLETE */\n\n  /** Custom request, for customizing the get command like\n     HTTP: DELETE, TRACE and others\n     FTP: to use a different list command\n     */\n  customrequest = 10_036,\n  /** HTTP request, for odd commands like DELETE, TRACE and others */\n  stderr,\n  /* 38 is not used */\n\n  /** send linked-list of post-transfer QUOTE commands */\n  postquote = 10_039,\n  /** Pass a pointer to string of the output using full variable-replacement\n     as described elsewhere. */\n  writeinfo,\n  verbose = 41,       /** talk a lot */\n  header,             /** throw the header out too */\n  noprogress,         /** shut off the progress meter */\n  nobody,             /** use HEAD to get http document */\n  failonerror,        /** no output on http error codes >= 300 */\n  upload,             /** this is an upload */\n  post,               /** HTTP POST method */\n  dirlistonly,        /** return bare names when listing directories */\n  append = 50,        /** Append instead of overwrite on upload! */\n  /** Specify whether to read the user+password from the .netrc or the URL.\n   * This must be one of the CURL_NETRC_* enums below. */\n  netrc,\n  followlocation, /** use Location: Luke! */\n  transfertext,  /** transfer data in text/ASCII format */\n  put,           /** HTTP PUT */\n  /* 55 = OBSOLETE */\n\n  /** Function that will be called instead of the internal progress display\n   * function. This function should be defined as the curl_progress_callback\n   * prototype defines. */\n  progressfunction = 20_056,\n  /** Data passed to the progress callback */\n  progressdata = 10_057,\n  /** We want the referrer field set automatically when following locations */\n  autoreferer = 58,\n  /** Port of the proxy, can be set in the proxy string as well with:\n     \"[host]:[port]\" */\n  proxyport,\n  /** size of the POST input data, if strlen() is not good to use */\n  postfieldsize,\n  /** tunnel non-http operations through a HTTP proxy */\n  httpproxytunnel,\n  /** Set the interface string to use as outgoing network interface */\n  intrface = 10_062,\n  /** Set the krb4/5 security level, this also enables krb4/5 awareness.  This\n   * is a string, 'clear', 'safe', 'confidential' or 'private'.  If the string\n   * is set but doesn't match one of these, 'private' will be used.  */\n  krblevel,\n  /** Set if we should verify the peer in ssl handshake, set 1 to verify. */\n  ssl_verifypeer = 64,\n  /** The CApath or CAfile used to validate the peer certificate\n     this option is used only if SSL_VERIFYPEER is true */\n  cainfo = 10_065,\n  /* 66 = OBSOLETE */\n  /* 67 = OBSOLETE */\n\n  /** Maximum number of http redirects to follow */\n  maxredirs = 68,\n  /** Pass a long set to 1 to get the date of the requested document (if\n     possible)! Pass a zero to shut it off. */\n  filetime,\n  /** This points to a linked list of telnet options */\n  telnetoptions = 10_070,\n  /** Max amount of cached alive connections */\n  maxconnects = 71,\n  /** What policy to use when closing connections when the cache is filled\n     up */\n  closepolicy,\n  /* 73 = OBSOLETE */\n\n  /** Set to explicitly use a new connection for the upcoming transfer.\n     Do not use this unless you're absolutely sure of this, as it makes the\n     operation slower and is less friendly for the network. */\n  fresh_connect = 74,\n  /** Set to explicitly forbid the upcoming transfer's connection to be re-used\n     when done. Do not use this unless you're absolutely sure of this, as it\n     makes the operation slower and is less friendly for the network. */\n  forbid_reuse,\n  /** Set to a file name that contains random data for libcurl to use to\n     seed the random engine when doing SSL connects. */\n  random_file = 10_076,\n  /** Set to the Entropy Gathering Daemon socket pathname */\n  egdsocket,\n  /** Time-out connect operations after this amount of seconds, if connects\n     are OK within this time, then fine... This only aborts the connect\n     phase. [Only works on unix-style/SIGALRM operating systems] */\n  connecttimeout = 78,\n  /** Function that will be called to store headers (instead of fwrite). The\n   * parameters will use fwrite() syntax, make sure to follow them. */\n  headerfunction = 20_079,\n  /** Set this to force the HTTP request to get back to GET. Only really usable\n     if POST, PUT or a custom request have been used first.\n   */\n  httpget = 80,\n  /** Set if we should verify the Common name from the peer certificate in ssl\n   * handshake, set 1 to check existence, 2 to ensure that it matches the\n   * provided hostname. */\n  ssl_verifyhost,\n  /** Specify which file name to write all known cookies in after completed\n     operation. Set file name to \"-\" (dash) to make it go to stdout. */\n  cookiejar = 10_082,\n  /** Specify which SSL ciphers to use */\n  ssl_cipher_list,\n  /** Specify which HTTP version to use! This must be set to one of the\n     CURL_HTTP_VERSION* enums set below. */\n  http_version = 84,\n  /** Specifically switch on or off the FTP engine's use of the EPSV command. By\n     default, that one will always be attempted before the more traditional\n     PASV command. */\n  ftp_use_epsv,\n  /** type of the file keeping your SSL-certificate (\"DER\", \"PEM\", \"ENG\") */\n  sslcerttype = 10_086,\n  /** name of the file keeping your private SSL-key */\n  sslkey,\n  /** type of the file keeping your private SSL-key (\"DER\", \"PEM\", \"ENG\") */\n  sslkeytype,\n  /** crypto engine for the SSL-sub system */\n  sslengine,\n  /** set the crypto engine for the SSL-sub system as default\n     the param has no meaning...\n   */\n  sslengine_default = 90,\n  /** Non-zero value means to use the global dns cache */\n  dns_use_global_cache,\n  /** DNS cache timeout */\n  dns_cache_timeout,\n  /** send linked-list of pre-transfer QUOTE commands */\n  prequote = 10_093,\n  /** set the debug function */\n  debugfunction = 20_094,\n  /** set the data for the debug function */\n  debugdata = 10_095,\n  /** mark this as start of a cookie session */\n  cookiesession = 96,\n  /** The CApath directory used to validate the peer certificate\n     this option is used only if SSL_VERIFYPEER is true */\n  capath = 10_097,\n  /** Instruct libcurl to use a smaller receive buffer */\n  buffersize = 98,\n  /** Instruct libcurl to not use any signal/alarm handlers, even when using\n     timeouts. This option is useful for multi-threaded applications.\n     See libcurl-the-guide for more background information. */\n  nosignal,\n  /** Provide a CURLShare for mutexing non-ts data */\n  share = 10_100,\n  /** indicates type of proxy. accepted values are CURLPROXY_HTTP (default),\n     CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */\n  proxytype = 101,\n  /** Set the Accept-Encoding string. Use this to tell a server you would like\n     the response to be compressed. */\n  encoding = 10_102,\n  /** Set pointer to private data */\n  private_opt,\n  /** Set aliases for HTTP 200 in the HTTP Response header */\n  http200aliases,\n  /** Continue to send authentication (user+password) when following locations,\n     even when hostname changed. This can potentially send off the name\n     and password to whatever host the server decides. */\n  unrestricted_auth = 105,\n  /** Specifically switch on or off the FTP engine's use of the EPRT command ( it\n     also disables the LPRT attempt). By default, those ones will always be\n     attempted before the good old traditional PORT command. */\n  ftp_use_eprt,\n  /** Set this to a bitmask value to enable the particular authentications\n     methods you like. Use this in combination with CURLOPT_USERPWD.\n     Note that setting multiple bits may cause extra network round-trips. */\n  httpauth,\n  /** Set the ssl context callback function, currently only for OpenSSL ssl_ctx\n     in second argument. The function must be matching the\n     curl_ssl_ctx_callback proto. */\n  ssl_ctx_function = 20_108,\n  /** Set the userdata for the ssl context callback function's third\n     argument */\n  ssl_ctx_data = 10_109,\n  /** FTP Option that causes missing dirs to be created on the remote server.\n     In 7.19.4 we introduced the convenience enums for this option using the\n     CURLFTP_CREATE_DIR prefix.\n  */\n  ftp_create_missing_dirs = 110,\n  /** Set this to a bitmask value to enable the particular authentications\n     methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.\n     Note that setting multiple bits may cause extra network round-trips. */\n  proxyauth,\n  /** FTP option that changes the timeout, in seconds, associated with\n     getting a response.  This is different from transfer timeout time and\n     essentially places a demand on the FTP server to acknowledge commands\n     in a timely manner. */\n  ftp_response_timeout,\n  /** Set this option to one of the CURL_IPRESOLVE_* defines (see below) to\n     tell libcurl to resolve names to those IP versions only. This only has\n     affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */\n  ipresolve,\n  /** Set this option to limit the size of a file that will be downloaded from\n     an HTTP or FTP server.\n\n     Note there is also _LARGE version which adds large file support for\n     platforms which have larger off_t sizes.  See MAXFILESIZE_LARGE below. */\n  maxfilesize,\n  /** See the comment for INFILESIZE above, but in short, specifies\n   * the size of the file being uploaded.  -1 means unknown.\n   */\n  infilesize_large = 30_115,\n  /** Sets the continuation offset.  There is also a LONG version of this;\n   * look above for RESUME_FROM.\n   */\n  resume_from_large,\n  /** Sets the maximum size of data that will be downloaded from\n   * an HTTP or FTP server.  See MAXFILESIZE above for the LONG version.\n   */\n  maxfilesize_large,\n  /** Set this option to the file name of your .netrc file you want libcurl\n     to parse (using the CURLOPT_NETRC option). If not set, libcurl will do\n     a poor attempt to find the user's home directory and check for a .netrc\n     file in there. */\n  netrc_file = 10_118,\n  /** Enable SSL/TLS for FTP, pick one of:\n     CURLFTPSSL_TRY     - try using SSL, proceed anyway otherwise\n     CURLFTPSSL_CONTROL - SSL for the control connection or fail\n     CURLFTPSSL_ALL     - SSL for all communication or fail\n  */\n  use_ssl = 119,\n  /** The _LARGE version of the standard POSTFIELDSIZE option */\n  postfieldsize_large = 30_120,\n  /** Enable/disable the TCP Nagle algorithm */\n  tcp_nodelay = 121,\n  /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */\n  /* 123 OBSOLETE. Gone in 7.16.0 */\n  /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */\n  /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */\n  /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */\n  /* 127 OBSOLETE. Gone in 7.16.0 */\n  /* 128 OBSOLETE. Gone in 7.16.0 */\n\n  /** When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option\n     can be used to change libcurl's default action which is to first try\n     \"AUTH SSL\" and then \"AUTH TLS\" in this order, and proceed when a OK\n     response has been received.\n\n     Available parameters are:\n     CURLFTPAUTH_DEFAULT - let libcurl decide\n     CURLFTPAUTH_SSL     - try \"AUTH SSL\" first, then TLS\n     CURLFTPAUTH_TLS     - try \"AUTH TLS\" first, then SSL\n  */\n  ftpsslauth = 129,\n  ioctlfunction = 20_130,        ///\n  ioctldata = 10_131,            ///\n  /* 132 OBSOLETE. Gone in 7.16.0 */\n  /* 133 OBSOLETE. Gone in 7.16.0 */\n\n  /** zero terminated string for pass on to the FTP server when asked for\n     \"account\" info */\n  ftp_account = 10_134,\n  /** feed cookies into cookie engine */\n  cookielist,\n  /** ignore Content-Length */\n  ignore_content_length = 136,\n  /** Set to non-zero to skip the IP address received in a 227 PASV FTP server\n     response. Typically used for FTP-SSL purposes but is not restricted to\n     that. libcurl will then instead use the same IP address it used for the\n     control connection. */\n  ftp_skip_pasv_ip,\n  /** Select \"file method\" to use when doing FTP, see the curl_ftpmethod\n     above. */\n  ftp_filemethod,\n  /** Local port number to bind the socket to */\n  localport,\n  /** Number of ports to try, including the first one set with LOCALPORT.\n     Thus, setting it to 1 will make no additional attempts but the first.\n  */\n  localportrange,\n  /** no transfer, set up connection and let application use the socket by\n     extracting it with CURLINFO_LASTSOCKET */\n  connect_only,\n  /** Function that will be called to convert from the\n     network encoding (instead of using the iconv calls in libcurl) */\n  conv_from_network_function = 20_142,\n  /** Function that will be called to convert to the\n     network encoding (instead of using the iconv calls in libcurl) */\n  conv_to_network_function,\n  /** Function that will be called to convert from UTF8\n     (instead of using the iconv calls in libcurl)\n     Note that this is used only for SSL certificate processing */\n  conv_from_utf8_function,\n  /** If the connection proceeds too quickly then need to slow it down */\n  /** */\n  /** limit-rate: maximum number of bytes per second to send or receive */\n  max_send_speed_large = 30_145,\n  max_recv_speed_large, /// ditto\n  /** Pointer to command string to send if USER/PASS fails. */\n  ftp_alternative_to_user = 10_147,\n  /** callback function for setting socket options */\n  sockoptfunction = 20_148,\n  sockoptdata = 10_149,\n  /** set to 0 to disable session ID re-use for this transfer, default is\n     enabled (== 1) */\n  ssl_sessionid_cache = 150,\n  /** allowed SSH authentication methods */\n  ssh_auth_types,\n  /** Used by scp/sftp to do public/private key authentication */\n  ssh_public_keyfile = 10_152,\n  ssh_private_keyfile,\n  /** Send CCC (Clear Command Channel) after authentication */\n  ftp_ssl_ccc = 154,\n  /** Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */\n  timeout_ms,\n  connecttimeout_ms, /// ditto\n  /** set to zero to disable the libcurl's decoding and thus pass the raw body\n     data to the application even when it is encoded/compressed */\n  http_transfer_decoding,\n  http_content_decoding,        /// ditto\n  /** Permission used when creating new files and directories on the remote\n     server for protocols that support it, SFTP/SCP/FILE */\n  new_file_perms,\n  new_directory_perms,          /// ditto\n  /** Set the behaviour of POST when redirecting. Values must be set to one\n     of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */\n  postredir,\n  /** used by scp/sftp to verify the host's public key */\n  ssh_host_public_key_md5 = 10_162,\n  /** Callback function for opening socket (instead of socket(2)). Optionally,\n     callback is able change the address or refuse to connect returning\n     CURL_SOCKET_BAD.  The callback should have type\n     curl_opensocket_callback */\n  opensocketfunction = 20_163,\n  opensocketdata = 10_164,       /// ditto\n  /** POST volatile input fields. */\n  copypostfields,\n  /** set transfer mode (;type=$(LT)a|i$(GT)) when doing FTP via an HTTP proxy */\n  proxy_transfer_mode = 166,\n  /** Callback function for seeking in the input stream */\n  seekfunction = 20_167,\n  seekdata = 10_168,     /// ditto\n  /** CRL file */\n  crlfile,\n  /** Issuer certificate */\n  issuercert,\n  /** (IPv6) Address scope */\n  address_scope = 171,\n  /** Collect certificate chain info and allow it to get retrievable with\n     CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only\n     working with OpenSSL-powered builds. */\n  certinfo,\n  /** \"name\" and \"pwd\" to use when fetching. */\n  username = 10_173,\n  password,     /// ditto\n  /** \"name\" and \"pwd\" to use with Proxy when fetching. */\n  proxyusername,\n  proxypassword,        /// ditto\n  /** Comma separated list of hostnames defining no-proxy zones. These should\n     match both hostnames directly, and hostnames within a domain. For\n     example, local.com will match local.com and www.local.com, but NOT\n     notlocal.com or www.notlocal.com. For compatibility with other\n     implementations of this, .local.com will be considered to be the same as\n     local.com. A single * is the only valid wildcard, and effectively\n     disables the use of proxy. */\n  noproxy,\n  /** block size for TFTP transfers */\n  tftp_blksize = 178,\n  /** Socks Service */\n  socks5_gssapi_service = 10_179,\n  /** Socks Service */\n  socks5_gssapi_nec = 180,\n  /** set the bitmask for the protocols that are allowed to be used for the\n     transfer, which thus helps the app which takes URLs from users or other\n     external inputs and want to restrict what protocol(s) to deal\n     with. Defaults to CURLPROTO_ALL. */\n  protocols,\n  /** set the bitmask for the protocols that libcurl is allowed to follow to,\n     as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs\n     to be set in both bitmasks to be allowed to get redirected to. Defaults\n     to all protocols except FILE and SCP. */\n  redir_protocols,\n  /** set the SSH knownhost file name to use */\n  ssh_knownhosts = 10_183,\n  /** set the SSH host key callback, must point to a curl_sshkeycallback\n     function */\n  ssh_keyfunction = 20_184,\n  /** set the SSH host key callback custom pointer */\n  ssh_keydata = 10_185,\n  /** set the SMTP mail originator */\n  mail_from,\n  /** set the SMTP mail receiver(s) */\n  mail_rcpt,\n  /** FTP: send PRET before PASV */\n  ftp_use_pret = 188,\n  /** RTSP request method (OPTIONS, SETUP, PLAY, etc...) */\n  rtsp_request,\n  /** The RTSP session identifier */\n  rtsp_session_id = 10_190,\n  /** The RTSP stream URI */\n  rtsp_stream_uri,\n  /** The Transport: header to use in RTSP requests */\n  rtsp_transport,\n  /** Manually initialize the client RTSP CSeq for this handle */\n  rtsp_client_cseq = 193,\n  /** Manually initialize the server RTSP CSeq for this handle */\n  rtsp_server_cseq,\n  /** The stream to pass to INTERLEAVEFUNCTION. */\n  interleavedata = 10_195,\n  /** Let the application define a custom write method for RTP data */\n  interleavefunction = 20_196,\n  /** Turn on wildcard matching */\n  wildcardmatch = 197,\n  /** Directory matching callback called before downloading of an\n     individual file (chunk) started */\n  chunk_bgn_function = 20_198,\n  /** Directory matching callback called after the file (chunk)\n     was downloaded, or skipped */\n  chunk_end_function,\n  /** Change match (fnmatch-like) callback for wildcard matching */\n  fnmatch_function,\n  /** Let the application define custom chunk data pointer */\n  chunk_data = 10_201,\n  /** FNMATCH_FUNCTION user pointer */\n  fnmatch_data,\n  /** send linked-list of name:port:address sets */\n  resolve,\n  /** Set a username for authenticated TLS */\n  tlsauth_username,\n  /** Set a password for authenticated TLS */\n  tlsauth_password,\n  /** Set authentication type for authenticated TLS */\n  tlsauth_type,\n  /** the last unused */\n  lastentry,\n\n  writedata = file, /// convenient alias\n  readdata = infile, /// ditto\n  headerdata = writeheader, /// ditto\n  rtspheader = httpheader, /// ditto\n}\n///\nalias CURLoption = int;\n///\nenum CURLOPT_SERVER_RESPONSE_TIMEOUT = CurlOption.ftp_response_timeout;\n\n/** Below here follows defines for the CURLOPT_IPRESOLVE option. If a host\n   name resolves addresses using more than one IP protocol version, this\n   option might be handy to force libcurl to use a specific IP version. */\nenum CurlIpResolve {\n  whatever = 0, /** default, resolves addresses to all IP versions that your system allows */\n  v4 = 1,       /** resolve to ipv4 addresses */\n  v6 = 2        /** resolve to ipv6 addresses */\n}\n\n/** three convenient \"aliases\" that follow the name scheme better */\nenum CURLOPT_WRITEDATA = CurlOption.file;\n/// ditto\nenum CURLOPT_READDATA = CurlOption.infile;\n/// ditto\nenum CURLOPT_HEADERDATA = CurlOption.writeheader;\n/// ditto\nenum CURLOPT_RTSPHEADER = CurlOption.httpheader;\n\n/** These enums are for use with the CURLOPT_HTTP_VERSION option. */\nenum CurlHttpVersion {\n    none, /** setting this means we don't care, and that we'd\n             like the library to choose the best possible\n             for us! */\n    v1_0, /** please use HTTP 1.0 in the request */\n    v1_1, /** please use HTTP 1.1 in the request */\n    last  /** *ILLEGAL* http version */\n}\n\n/**\n * Public API enums for RTSP requests\n */\nenum CurlRtspReq {\n    none,       ///\n    options,    ///\n    describe,   ///\n    announce,   ///\n    setup,      ///\n    play,       ///\n    pause,      ///\n    teardown,   ///\n    get_parameter,      ///\n    set_parameter,      ///\n    record,     ///\n    receive,    ///\n    last        ///\n}\n\n /** These enums are for use with the CURLOPT_NETRC option. */\nenum CurlNetRcOption {\n    ignored,  /** The .netrc will never be read. This is the default. */\n    optional  /** A user:password in the URL will be preferred to one in the .netrc. */,\n    required, /** A user:password in the URL will be ignored.\n               * Unless one is set programmatically, the .netrc\n               * will be queried. */\n    last        ///\n}\n\n///\nenum CurlSslVersion {\n    default_version,    ///\n    tlsv1,      ///\n    sslv2,      ///\n    sslv3,      ///\n    last /** never use */\n}\n\n///\nenum CurlTlsAuth {\n    none,       ///\n    srp,        ///\n    last /** never use */\n}\n\n/** symbols to use with CURLOPT_POSTREDIR.\n   CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that\n   CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */\nenum CurlRedir {\n  get_all = 0,  ///\n  post_301 = 1, ///\n  post_302 = 2, ///\n  ///\n  post_all = (1 | 2) // (CURL_REDIR_POST_301|CURL_REDIR_POST_302);\n}\n///\nenum CurlTimeCond {\n    none,       ///\n    ifmodsince, ///\n    ifunmodsince,       ///\n    lastmod,    ///\n    last        ///\n}\n///\nalias curl_TimeCond = int;\n\n\n/** curl_strequal() and curl_strnequal() are subject for removal in a future\n   libcurl, see lib/README.curlx for details */\nextern (C) {\nint  curl_strequal(in const(char) *s1, in const(char) *s2);\n/// ditto\nint  curl_strnequal(in const(char) *s1, in const(char) *s2, size_t n);\n}\nenum CurlForm {\n    nothing, /********** the first one is unused ************/\n    copyname,\n    ptrname,\n    namelength,\n    copycontents,\n    ptrcontents,\n    contentslength,\n    filecontent,\n    array,\n    obsolete,\n    file,\n    buffer,\n    bufferptr,\n    bufferlength,\n    contenttype,\n    contentheader,\n    filename,\n    end,\n    obsolete2,\n    stream,\n    lastentry /** the last unused */\n}\nalias CURLformoption = int;\n\n\n/** structure to be used as parameter for CURLFORM_ARRAY */\nextern (C) struct curl_forms\n{\n    CURLformoption option;      ///\n    const(char) *value;        ///\n}\n\n/** Use this for multipart formpost building\n *\n * Returns code for curl_formadd()\n *\n * Returns:\n *\n * $(UL\n * $(LI CURL_FORMADD_OK             on success )\n * $(LI CURL_FORMADD_MEMORY         if the FormInfo allocation fails )\n * $(LI CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form )\n * $(LI CURL_FORMADD_NULL           if a null pointer was given for a char )\n * $(LI CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed )\n * $(LI CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used )\n * $(LI CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error) )\n * $(LI CURL_FORMADD_MEMORY         if a curl_httppost struct cannot be allocated )\n * $(LI CURL_FORMADD_MEMORY         if some allocation for string copying failed. )\n * $(LI CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array )\n * )\n *\n ***************************************************************************/\nenum CurlFormAdd {\n    ok, /** first, no error */\n    memory,     ///\n    option_twice,       ///\n    null_ptr,   ///\n    unknown_option,     ///\n    incomplete, ///\n    illegal_array,      ///\n    disabled,  /** libcurl was built with this disabled */\n    last        ///\n}\n///\nalias CURLFORMcode = int;\n\nextern (C) {\n\n/**\n * Name: curl_formadd()\n *\n * Description:\n *\n * Pretty advanced function for building multi-part formposts. Each invoke\n * adds one part that together construct a full post. Then use\n * CURLOPT_HTTPPOST to send it off to libcurl.\n */\nCURLFORMcode  curl_formadd(curl_httppost **httppost, curl_httppost **last_post,...);\n\n/**\n * callback function for curl_formget()\n * The void *arg pointer will be the one passed as second argument to\n *   curl_formget().\n * The character buffer passed to it must not be freed.\n * Should return the buffer length passed to it as the argument \"len\" on\n *   success.\n */\nalias curl_formget_callback = size_t function(void *arg, in const(char) *buf, size_t len);\n\n/**\n * Name: curl_formget()\n *\n * Description:\n *\n * Serialize a curl_httppost struct built with curl_formadd().\n * Accepts a void pointer as second argument which will be passed to\n * the curl_formget_callback function.\n * Returns 0 on success.\n */\nint  curl_formget(curl_httppost *form, void *arg, curl_formget_callback append);\n/**\n * Name: curl_formfree()\n *\n * Description:\n *\n * Free a multipart formpost previously built with curl_formadd().\n */\nvoid  curl_formfree(curl_httppost *form);\n\n/**\n * Name: curl_getenv()\n *\n * Description:\n *\n * Returns a malloc()'ed string that MUST be curl_free()ed after usage is\n * complete. DEPRECATED - see lib/README.curlx\n */\nchar * curl_getenv(in const(char) *variable);\n\n/**\n * Name: curl_version()\n *\n * Description:\n *\n * Returns a static ascii string of the libcurl version.\n */\nchar * curl_version();\n\n/**\n * Name: curl_easy_escape()\n *\n * Description:\n *\n * Escapes URL strings (converts all letters consider illegal in URLs to their\n * %XX versions). This function returns a new allocated string or NULL if an\n * error occurred.\n */\nchar * curl_easy_escape(CURL *handle, in const(char) *string, int length);\n\n/** the previous version: */\nchar * curl_escape(in const(char) *string, int length);\n\n\n/**\n * Name: curl_easy_unescape()\n *\n * Description:\n *\n * Unescapes URL encoding in strings (converts all %XX codes to their 8bit\n * versions). This function returns a new allocated string or NULL if an error\n * occurred.\n * Conversion Note: On non-ASCII platforms the ASCII %XX codes are\n * converted into the host encoding.\n */\nchar * curl_easy_unescape(CURL *handle, in const(char) *string, int length, int *outlength);\n\n/** the previous version */\nchar * curl_unescape(in const(char) *string, int length);\n\n/**\n * Name: curl_free()\n *\n * Description:\n *\n * Provided for de-allocation in the same translation unit that did the\n * allocation. Added in libcurl 7.10\n */\nvoid  curl_free(void *p);\n\n/**\n * Name: curl_global_init()\n *\n * Description:\n *\n * curl_global_init() should be invoked exactly once for each application that\n * uses libcurl and before any call of other libcurl functions.\n *\n * This function is not thread-safe!\n */\nCURLcode  curl_global_init(c_long flags);\n\n/**\n * Name: curl_global_init_mem()\n *\n * Description:\n *\n * curl_global_init() or curl_global_init_mem() should be invoked exactly once\n * for each application that uses libcurl.  This function can be used to\n * initialize libcurl and set user defined memory management callback\n * functions.  Users can implement memory management routines to check for\n * memory leaks, check for mis-use of the curl library etc.  User registered\n * callback routines with be invoked by this library instead of the system\n * memory management routines like malloc, free etc.\n */\nCURLcode  curl_global_init_mem(\n  c_long flags,\n  curl_malloc_callback m,\n  curl_free_callback f,\n  curl_realloc_callback r,\n  curl_strdup_callback s,\n  curl_calloc_callback c\n);\n\n/**\n * Name: curl_global_cleanup()\n *\n * Description:\n *\n * curl_global_cleanup() should be invoked exactly once for each application\n * that uses libcurl\n */\nvoid  curl_global_cleanup();\n}\n\n/** linked-list structure for the CURLOPT_QUOTE option (and other) */\nextern (C) {\n\nstruct curl_slist\n{\n    char *data;\n    curl_slist *next;\n}\n\n/**\n * Name: curl_slist_append()\n *\n * Description:\n *\n * Appends a string to a linked list. If no list exists, it will be created\n * first. Returns the new list, after appending.\n */\ncurl_slist * curl_slist_append(curl_slist *, in const(char) *);\n\n/**\n * Name: curl_slist_free_all()\n *\n * Description:\n *\n * free a previously built curl_slist.\n */\nvoid  curl_slist_free_all(curl_slist *);\n\n/**\n * Name: curl_getdate()\n *\n * Description:\n *\n * Returns the time, in seconds since 1 Jan 1970 of the time string given in\n * the first argument. The time argument in the second parameter is unused\n * and should be set to NULL.\n */\ntime_t  curl_getdate(const(char) *p, const(time_t) *unused);\n\n/** info about the certificate chain, only for OpenSSL builds. Asked\n   for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */\nstruct curl_certinfo\n{\n    int num_of_certs;      /** number of certificates with information */\n    curl_slist **certinfo; /** for each index in this array, there's a\n                              linked list with textual information in the\n                              format \"name: value\" */\n}\n\n} // extern (C) end\n\n///\nenum CURLINFO_STRING = 0x100000;\n///\nenum CURLINFO_LONG = 0x200000;\n///\nenum CURLINFO_DOUBLE = 0x300000;\n///\nenum CURLINFO_SLIST = 0x400000;\n///\nenum CURLINFO_MASK = 0x0fffff;\n\n///\nenum CURLINFO_TYPEMASK = 0xf00000;\n\n///\nenum CurlInfo {\n    none,       ///\n    effective_url = 1_048_577,    ///\n    response_code = 2_097_154,    ///\n    total_time = 3_145_731,       ///\n    namelookup_time,    ///\n    connect_time,       ///\n    pretransfer_time,   ///\n    size_upload,        ///\n    size_download,      ///\n    speed_download,     ///\n    speed_upload,       ///\n    header_size = 2_097_163,      ///\n    request_size,       ///\n    ssl_verifyresult,   ///\n    filetime,   ///\n    content_length_download = 3_145_743,  ///\n    content_length_upload,      ///\n    starttransfer_time, ///\n    content_type = 1_048_594,     ///\n    redirect_time = 3_145_747,    ///\n    redirect_count = 2_097_172,   ///\n    private_info = 1_048_597,     ///\n    http_connectcode = 2_097_174, ///\n    httpauth_avail,     ///\n    proxyauth_avail,    ///\n    os_errno,   ///\n    num_connects,       ///\n    ssl_engines = 4_194_331,      ///\n    cookielist, ///\n    lastsocket = 2_097_181,       ///\n    ftp_entry_path = 1_048_606,   ///\n    redirect_url,       ///\n    primary_ip, ///\n    appconnect_time = 3_145_761,  ///\n    certinfo = 4_194_338, ///\n    condition_unmet = 2_097_187,  ///\n    rtsp_session_id = 1_048_612,  ///\n    rtsp_client_cseq = 2_097_189, ///\n    rtsp_server_cseq,   ///\n    rtsp_cseq_recv,     ///\n    primary_port,       ///\n    local_ip = 1_048_617, ///\n    local_port = 2_097_194,       ///\n    /** Fill in new entries below here! */\n    lastone = 42\n}\n///\nalias CURLINFO = int;\n\n/** CURLINFO_RESPONSE_CODE is the new name for the option previously known as\n   CURLINFO_HTTP_CODE */\nenum CURLINFO_HTTP_CODE = CurlInfo.response_code;\n\n///\nenum CurlClosePolicy {\n    none,       ///\n    oldest,     ///\n    least_recently_used,        ///\n    least_traffic,      ///\n    slowest,    ///\n    callback,   ///\n    last        ///\n}\n///\nalias curl_closepolicy = int;\n\n///\nenum CurlGlobal {\n  ssl = 1,      ///\n  win32 = 2,    ///\n  ///\n  all = (1 | 2), // (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32);\n  nothing = 0,  ///\n  default_ = (1 | 2) /// all\n}\n\n/******************************************************************************\n * Setup defines, protos etc for the sharing stuff.\n */\n\n/** Different data locks for a single share */\nenum CurlLockData {\n    none,       ///\n    /**  CURL_LOCK_DATA_SHARE is used internally to say that\n     *  the locking is just made to change the internal state of the share\n     *  itself.\n     */\n    share,\n    cookie,     ///\n    dns,        ///\n    ssl_session,        ///\n    connect,    ///\n    last        ///\n}\n///\nalias curl_lock_data = int;\n\n/** Different lock access types */\nenum CurlLockAccess {\n    none,            /** unspecified action */\n    shared_access,   /** for read perhaps */\n    single,          /** for write perhaps */\n    last             /** never use */\n}\n///\nalias curl_lock_access = int;\n\n///\nalias curl_lock_function = void function(CURL *handle, curl_lock_data data, curl_lock_access locktype, void *userptr);\n///\nalias curl_unlock_function = void function(CURL *handle, curl_lock_data data, void *userptr);\n\n///\nalias CURLSH = void;\n\n///\nenum CurlShError {\n    ok,          /** all is fine */\n    bad_option,  /** 1 */\n    in_use,      /** 2 */\n    invalid,     /** 3 */\n    nomem,       /** out of memory */\n    last         /** never use */\n}\n///\nalias CURLSHcode = int;\n\n/** pass in a user data pointer used in the lock/unlock callback\n   functions */\nenum CurlShOption {\n    none,         /** don't use */\n    share,        /** specify a data type to share */\n    unshare,      /** specify which data type to stop sharing */\n    lockfunc,     /** pass in a 'curl_lock_function' pointer */\n    unlockfunc,   /** pass in a 'curl_unlock_function' pointer */\n    userdata,     /** pass in a user data pointer used in the lock/unlock\n                     callback functions */\n    last          /** never use */\n}\n///\nalias CURLSHoption = int;\n\nextern (C) {\n///\nCURLSH * curl_share_init();\n///\nCURLSHcode  curl_share_setopt(CURLSH *, CURLSHoption option,...);\n///\nCURLSHcode  curl_share_cleanup(CURLSH *);\n}\n\n/*****************************************************************************\n * Structures for querying information about the curl library at runtime.\n */\n\n// CURLVERSION_*\nenum CurlVer {\n    first,      ///\n    second,     ///\n    third,      ///\n    fourth,     ///\n    last        ///\n}\n///\nalias CURLversion = int;\n\n/** The 'CURLVERSION_NOW' is the symbolic name meant to be used by\n   basically all programs ever that want to get version information. It is\n   meant to be a built-in version number for what kind of struct the caller\n   expects. If the struct ever changes, we redefine the NOW to another enum\n   from above. */\nenum CURLVERSION_NOW = CurlVer.fourth;\n\n///\nextern (C) struct _N28\n{\n  CURLversion age;     /** age of the returned struct */\n  const(char) *version_;      /** LIBCURL_VERSION */\n  uint version_num;    /** LIBCURL_VERSION_NUM */\n  const(char) *host;          /** OS/host/cpu/machine when configured */\n  int features;        /** bitmask, see defines below */\n  const(char) *ssl_version;   /** human readable string */\n  c_long ssl_version_num; /** not used anymore, always 0 */\n  const(char) *libz_version;     /** human readable string */\n  /** protocols is terminated by an entry with a NULL protoname */\n  const(char) **protocols;\n  /** The fields below this were added in CURLVERSION_SECOND */\n  const(char) *ares;\n  int ares_num;\n  /** This field was added in CURLVERSION_THIRD */\n  const(char) *libidn;\n  /** These field were added in CURLVERSION_FOURTH. */\n  /** Same as '_libiconv_version' if built with HAVE_ICONV */\n  int iconv_ver_num;\n  const(char) *libssh_version;  /** human readable string */\n}\n///\nalias curl_version_info_data = _N28;\n\n///\n// CURL_VERSION_*\nenum CurlVersion {\n  ipv6         = 1,     /** IPv6-enabled */\n  kerberos4    = 2,     /** kerberos auth is supported */\n  ssl          = 4,     /** SSL options are present */\n  libz         = 8,     /** libz features are present */\n  ntlm         = 16,    /** NTLM auth is supported */\n  gssnegotiate = 32,    /** Negotiate auth support */\n  dbg          = 64,    /** built with debug capabilities */\n  asynchdns    = 128,   /** asynchronous dns resolves */\n  spnego       = 256,   /** SPNEGO auth */\n  largefile    = 512,   /** supports files bigger than 2GB */\n  idn          = 1024,  /** International Domain Names support */\n  sspi         = 2048,  /** SSPI is supported */\n  conv         = 4096,  /** character conversions supported */\n  curldebug    = 8192,  /** debug memory tracking supported */\n  tlsauth_srp  = 16_384  /** TLS-SRP auth is supported */\n}\n\nextern (C) {\n/**\n * Name: curl_version_info()\n *\n * Description:\n *\n * This function returns a pointer to a static copy of the version info\n * struct. See above.\n */\ncurl_version_info_data * curl_version_info(CURLversion );\n\n/**\n * Name: curl_easy_strerror()\n *\n * Description:\n *\n * The curl_easy_strerror function may be used to turn a CURLcode value\n * into the equivalent human readable error string.  This is useful\n * for printing meaningful error messages.\n */\nconst(char)* curl_easy_strerror(CURLcode );\n\n/**\n * Name: curl_share_strerror()\n *\n * Description:\n *\n * The curl_share_strerror function may be used to turn a CURLSHcode value\n * into the equivalent human readable error string.  This is useful\n * for printing meaningful error messages.\n */\nconst(char)* curl_share_strerror(CURLSHcode );\n\n/**\n * Name: curl_easy_pause()\n *\n * Description:\n *\n * The curl_easy_pause function pauses or unpauses transfers. Select the new\n * state by setting the bitmask, use the convenience defines below.\n *\n */\nCURLcode  curl_easy_pause(CURL *handle, int bitmask);\n}\n\n\n///\nenum CurlPause {\n  recv      = 1,        ///\n  recv_cont = 0,        ///\n  send      = 4,        ///\n  send_cont = 0,        ///\n  ///\n  all       = (1 | 4), // CURLPAUSE_RECV | CURLPAUSE_SEND\n  ///\n  cont      = (0 | 0), // CURLPAUSE_RECV_CONT | CURLPAUSE_SEND_CONT\n}\n\n/* unfortunately, the easy.h and multi.h include files need options and info\n  stuff before they can be included! */\n/* ***************************************************************************\n *                                  _   _ ____  _\n *  Project                     ___| | | |  _ \\| |\n *                             / __| | | | |_) | |\n *                            | (__| |_| |  _ <| |___\n *                             \\___|\\___/|_| \\_\\_____|\n *\n * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.\n *\n * This software is licensed as described in the file COPYING, which\n * you should have received as part of this distribution. The terms\n * are also available at http://curl.haxx.se/docs/copyright.html.\n *\n * You may opt to use, copy, modify, merge, publish, distribute and/or sell\n * copies of the Software, and permit persons to whom the Software is\n * furnished to do so, under the terms of the COPYING file.\n *\n * This software is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF ANY\n * KIND, either express or implied.\n *\n ***************************************************************************/\n\nextern (C) {\n  ///\n  CURL * curl_easy_init();\n  ///\n  CURLcode  curl_easy_setopt(CURL *curl, CURLoption option,...);\n  ///\n  CURLcode  curl_easy_perform(CURL *curl);\n  ///\n  void  curl_easy_cleanup(CURL *curl);\n}\n\n/**\n * Name: curl_easy_getinfo()\n *\n * Description:\n *\n * Request internal information from the curl session with this function.  The\n * third argument MUST be a pointer to a long, a pointer to a char * or a\n * pointer to a double (as the documentation describes elsewhere).  The data\n * pointed to will be filled in accordingly and can be relied upon only if the\n * function returns CURLE_OK.  This function is intended to get used *AFTER* a\n * performed transfer, all results from this function are undefined until the\n * transfer is completed.\n */\nextern (C) CURLcode  curl_easy_getinfo(CURL *curl, CURLINFO info,...);\n\n\n/**\n * Name: curl_easy_duphandle()\n *\n * Description:\n *\n * Creates a new curl session handle with the same options set for the handle\n * passed in. Duplicating a handle could only be a matter of cloning data and\n * options, internal state info and things like persistant connections cannot\n * be transfered. It is useful in multithreaded applications when you can run\n * curl_easy_duphandle() for each new thread to avoid a series of identical\n * curl_easy_setopt() invokes in every thread.\n */\nextern (C) CURL * curl_easy_duphandle(CURL *curl);\n\n/**\n * Name: curl_easy_reset()\n *\n * Description:\n *\n * Re-initializes a CURL handle to the default values. This puts back the\n * handle to the same state as it was in when it was just created.\n *\n * It does keep: live connections, the Session ID cache, the DNS cache and the\n * cookies.\n */\nextern (C) void  curl_easy_reset(CURL *curl);\n\n/**\n * Name: curl_easy_recv()\n *\n * Description:\n *\n * Receives data from the connected socket. Use after successful\n * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.\n */\nextern (C) CURLcode  curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n);\n\n/**\n * Name: curl_easy_send()\n *\n * Description:\n *\n * Sends data over the connected socket. Use after successful\n * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.\n */\nextern (C) CURLcode  curl_easy_send(CURL *curl, void *buffer, size_t buflen, size_t *n);\n\n\n/*\n * This header file should not really need to include \"curl.h\" since curl.h\n * itself includes this file and we expect user applications to do #include\n * <curl/curl.h> without the need for especially including multi.h.\n *\n * For some reason we added this include here at one point, and rather than to\n * break existing (wrongly written) libcurl applications, we leave it as-is\n * but with this warning attached.\n */\n/* ***************************************************************************\n *                                  _   _ ____  _\n *  Project                     ___| | | |  _ \\| |\n *                             / __| | | | |_) | |\n *                            | (__| |_| |  _ <| |___\n *                             \\___|\\___/|_| \\_\\_____|\n *\n * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.\n *\n * This software is licensed as described in the file COPYING, which\n * you should have received as part of this distribution. The terms\n * are also available at http://curl.haxx.se/docs/copyright.html.\n *\n * You may opt to use, copy, modify, merge, publish, distribute and/or sell\n * copies of the Software, and permit persons to whom the Software is\n * furnished to do so, under the terms of the COPYING file.\n *\n * This software is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF ANY\n * KIND, either express or implied.\n *\n ***************************************************************************/\n\n///\nalias CURLM = void;\n\n///\nenum CurlM {\n    call_multi_perform = -1, /** please call curl_multi_perform() or curl_multi_socket*() soon */\n    ok, ///\n    bad_handle,              /** the passed-in handle is not a valid CURLM handle */\n    bad_easy_handle,       /** an easy handle was not good/valid */\n    out_of_memory,         /** if you ever get this, you're in deep sh*t */\n    internal_error,        /** this is a libcurl bug */\n    bad_socket,            /** the passed in socket argument did not match */\n    unknown_option,        /** curl_multi_setopt() with unsupported option */\n    last,       ///\n}\n///\nalias CURLMcode = int;\n\n/** just to make code nicer when using curl_multi_socket() you can now check\n   for CURLM_CALL_MULTI_SOCKET too in the same style it works for\n   curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */\nenum CURLM_CALL_MULTI_SOCKET = CurlM.call_multi_perform;\n\n///\nenum CurlMsg\n{\n    none,       ///\n    done, /** This easy handle has completed. 'result' contains\n             the CURLcode of the transfer */\n    last, /** no used */\n}\n///\nalias CURLMSG = int;\n\n///\nextern (C) union _N31\n{\n    void *whatever;  /** message-specific data */\n    CURLcode result; /** return code for transfer */\n}\n\n///\nextern (C) struct CURLMsg\n{\n    CURLMSG msg;        /** what this message means */\n    CURL *easy_handle;  /** the handle it concerns */\n    _N31 data;  ///\n}\n\n/**\n * Name:    curl_multi_init()\n *\n * Desc:    inititalize multi-style curl usage\n *\n * Returns: a new CURLM handle to use in all 'curl_multi' functions.\n */\nextern (C) CURLM * curl_multi_init();\n\n/**\n * Name:    curl_multi_add_handle()\n *\n * Desc:    add a standard curl handle to the multi stack\n *\n * Returns: CURLMcode type, general multi error code.\n */\nextern (C) CURLMcode  curl_multi_add_handle(CURLM *multi_handle, CURL *curl_handle);\n\n /**\n  * Name:    curl_multi_remove_handle()\n  *\n  * Desc:    removes a curl handle from the multi stack again\n  *\n  * Returns: CURLMcode type, general multi error code.\n  */\nextern (C) CURLMcode  curl_multi_remove_handle(CURLM *multi_handle, CURL *curl_handle);\n\n /**\n  * Name:    curl_multi_fdset()\n  *\n  * Desc:    Ask curl for its fd_set sets. The app can use these to select() or\n  *          poll() on. We want curl_multi_perform() called as soon as one of\n  *          them are ready.\n  *\n  * Returns: CURLMcode type, general multi error code.\n  */\n\n/** tmp decl */\nalias fd_set = int;\n///\nextern (C) CURLMcode  curl_multi_fdset(\n  CURLM *multi_handle,\n  fd_set *read_fd_set,\n  fd_set *write_fd_set,\n  fd_set *exc_fd_set,\n  int *max_fd\n);\n\n /**\n  * Name:    curl_multi_perform()\n  *\n  * Desc:    When the app thinks there's data available for curl it calls this\n  *          function to read/write whatever there is right now. This returns\n  *          as soon as the reads and writes are done. This function does not\n  *          require that there actually is data available for reading or that\n  *          data can be written, it can be called just in case. It returns\n  *          the number of handles that still transfer data in the second\n  *          argument's integer-pointer.\n  *\n  * Returns: CURLMcode type, general multi error code. *NOTE* that this only\n  *          returns errors etc regarding the whole multi stack. There might\n  *          still have occurred problems on invidual transfers even when this\n  *          returns OK.\n  */\nextern (C) CURLMcode  curl_multi_perform(CURLM *multi_handle, int *running_handles);\n\n /**\n  * Name:    curl_multi_cleanup()\n  *\n  * Desc:    Cleans up and removes a whole multi stack. It does not free or\n  *          touch any individual easy handles in any way. We need to define\n  *          in what state those handles will be if this function is called\n  *          in the middle of a transfer.\n  *\n  * Returns: CURLMcode type, general multi error code.\n  */\nextern (C) CURLMcode  curl_multi_cleanup(CURLM *multi_handle);\n\n/**\n * Name:    curl_multi_info_read()\n *\n * Desc:    Ask the multi handle if there's any messages/informationals from\n *          the individual transfers. Messages include informationals such as\n *          error code from the transfer or just the fact that a transfer is\n *          completed. More details on these should be written down as well.\n *\n *          Repeated calls to this function will return a new struct each\n *          time, until a special \"end of msgs\" struct is returned as a signal\n *          that there is no more to get at this point.\n *\n *          The data the returned pointer points to will not survive calling\n *          curl_multi_cleanup().\n *\n *          The 'CURLMsg' struct is meant to be very simple and only contain\n *          very basic informations. If more involved information is wanted,\n *          we will provide the particular \"transfer handle\" in that struct\n *          and that should/could/would be used in subsequent\n *          curl_easy_getinfo() calls (or similar). The point being that we\n *          must never expose complex structs to applications, as then we'll\n *          undoubtably get backwards compatibility problems in the future.\n *\n * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out\n *          of structs. It also writes the number of messages left in the\n *          queue (after this read) in the integer the second argument points\n *          to.\n */\nextern (C) CURLMsg * curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue);\n\n/**\n * Name:    curl_multi_strerror()\n *\n * Desc:    The curl_multi_strerror function may be used to turn a CURLMcode\n *          value into the equivalent human readable error string.  This is\n *          useful for printing meaningful error messages.\n *\n * Returns: A pointer to a zero-terminated error message.\n */\nextern (C) const(char)* curl_multi_strerror(CURLMcode );\n\n/**\n * Name:    curl_multi_socket() and\n *          curl_multi_socket_all()\n *\n * Desc:    An alternative version of curl_multi_perform() that allows the\n *          application to pass in one of the file descriptors that have been\n *          detected to have \"action\" on them and let libcurl perform.\n *          See man page for details.\n */\nenum CurlPoll {\n  none_ = 0,   /** jdrewsen - underscored in order not to clash with reserved D symbols */\n  in_ = 1,      ///\n  out_ = 2,     ///\n  inout_ = 3,   ///\n  remove_ = 4   ///\n}\n\n///\nalias CURL_SOCKET_TIMEOUT = CURL_SOCKET_BAD;\n\n///\nenum CurlCSelect {\n  in_ = 0x01,  /** jdrewsen - underscored in order not to clash with reserved D symbols */\n  out_ = 0x02,  ///\n  err_ = 0x04   ///\n}\n\nextern (C) {\n  ///\n  alias curl_socket_callback =\n        int function(CURL *easy,            /** easy handle */\n                     curl_socket_t s,       /** socket */\n                     int what,              /** see above */\n                     void *userp,           /** private callback pointer */\n                     void *socketp);        /** private socket pointer */\n}\n\n/**\n * Name:    curl_multi_timer_callback\n *\n * Desc:    Called by libcurl whenever the library detects a change in the\n *          maximum number of milliseconds the app is allowed to wait before\n *          curl_multi_socket() or curl_multi_perform() must be called\n *          (to allow libcurl's timed events to take place).\n *\n * Returns: The callback should return zero.\n */\n\nextern (C) {\n  alias curl_multi_timer_callback =\n        int function(CURLM *multi,          /** multi handle */\n                     c_long timeout_ms,     /** see above */\n                     void *userp);          /** private callback pointer */\n  /// ditto\n  CURLMcode  curl_multi_socket(CURLM *multi_handle, curl_socket_t s, int *running_handles);\n  /// ditto\n  CURLMcode  curl_multi_socket_action(CURLM *multi_handle, curl_socket_t s, int ev_bitmask, int *running_handles);\n  /// ditto\n  CURLMcode  curl_multi_socket_all(CURLM *multi_handle, int *running_handles);\n}\n\n/** This macro below was added in 7.16.3 to push users who recompile to use\n   the new curl_multi_socket_action() instead of the old curl_multi_socket()\n*/\n\n/**\n * Name:    curl_multi_timeout()\n *\n * Desc:    Returns the maximum number of milliseconds the app is allowed to\n *          wait before curl_multi_socket() or curl_multi_perform() must be\n *          called (to allow libcurl's timed events to take place).\n *\n * Returns: CURLM error code.\n */\nextern (C) CURLMcode  curl_multi_timeout(CURLM *multi_handle, c_long *milliseconds);\n\n///\nenum CurlMOption {\n    socketfunction = 20_001,    /** This is the socket callback function pointer */\n    socketdata = 10_002,        /** This is the argument passed to the socket callback */\n    pipelining = 3,             /** set to 1 to enable pipelining for this multi handle */\n    timerfunction = 20_004,     /** This is the timer callback function pointer */\n    timerdata = 10_005,          /** This is the argument passed to the timer callback */\n    maxconnects = 6,            /** maximum number of entries in the connection cache */\n    lastentry   ///\n}\n///\nalias CURLMoption = int;\n\n/**\n * Name:    curl_multi_setopt()\n *\n * Desc:    Sets options for the multi handle.\n *\n * Returns: CURLM error code.\n */\nextern (C) CURLMcode  curl_multi_setopt(CURLM *multi_handle, CURLMoption option,...);\n\n/**\n * Name:    curl_multi_assign()\n *\n * Desc:    This function sets an association in the multi handle between the\n *          given socket and a private pointer of the application. This is\n *          (only) useful for curl_multi_socket uses.\n *\n * Returns: CURLM error code.\n */\nextern (C) CURLMcode  curl_multi_assign(CURLM *multi_handle, curl_socket_t sockfd, void *sockp);\n"
  },
  {
    "path": "libphobos/src/etc/c/sqlite3.d",
    "content": "module etc.c.sqlite3;\n/*\n** 2001 September 15\n**\n** The author disclaims copyright to this source code.  In place of\n** a legal notice, here is a blessing:\n**\n**    May you do good and not evil.\n**    May you find forgiveness for yourself and forgive others.\n**    May you share freely, never taking more than you give.\n**\n*************************************************************************\n** This header file defines the interface that the SQLite library\n** presents to client programs.  If a C-function, structure, datatype,\n** or constant definition does not appear in this file, then it is\n** not a published API of SQLite, is subject to change without\n** notice, and should not be referenced by programs that use SQLite.\n**\n** Some of the definitions that are in this file are marked as\n** \"experimental\".  Experimental interfaces are normally new\n** features recently added to SQLite.  We do not anticipate changes\n** to experimental interfaces but reserve the right to make minor changes\n** if experience from use \"in the wild\" suggest such changes are prudent.\n**\n** The official C-language API documentation for SQLite is derived\n** from comments in this file.  This file is the authoritative source\n** on how SQLite interfaces are suppose to operate.\n**\n** The name of this file under configuration management is \"sqlite.h.in\".\n** The makefile makes some minor changes to this file (such as inserting\n** the version number) and changes its name to \"sqlite3.h\" as\n** part of the build process.\n*/\n\nimport core.stdc.stdarg : va_list;\n\nextern (C) __gshared nothrow:\n\n/**\n** CAPI3REF: Compile-Time Library Version Numbers\n*/\nenum SQLITE_VERSION = \"3.10.2\";\n/// Ditto\nenum SQLITE_VERSION_NUMBER = 3_010_002;\n/// Ditto\nenum SQLITE_SOURCE_ID = \"2016-01-20 15:27:19 17efb4209f97fb4971656086b138599a91a75ff9\";\n\n/**\n** CAPI3REF: Run-Time Library Version Numbers\n*/\nextern immutable(char)* sqlite3_version;\n/// Ditto\nimmutable(char)* sqlite3_libversion();\n/// Ditto\nimmutable(char)* sqlite3_sourceid();\n/// Ditto\nint sqlite3_libversion_number();\n\n/**\n** CAPI3REF: Run-Time Library Compilation Options Diagnostics\n*/\nint sqlite3_compileoption_used(const char *zOptName);\n/// Ditto\nimmutable(char)* sqlite3_compileoption_get(int N);\n\n/**\n** CAPI3REF: Test To See If The Library Is Threadsafe\n*/\nint sqlite3_threadsafe();\n\n/**\n** CAPI3REF: Database Connection Handle\n*/\nstruct sqlite3;\n\n///\nalias sqlite3_int64 = long;\n///\nalias sqlite3_uint64 = ulong;\n\n/**\n** CAPI3REF: Closing A Database Connection\n**\n*/\nint sqlite3_close(sqlite3 *);\nint sqlite3_close_v2(sqlite3*);\n\n/**\n** The type for a callback function.\n** This is legacy and deprecated.  It is included for historical\n** compatibility and is not documented.\n*/\nalias sqlite3_callback = int function (void*,int,char**, char**);\n\n/**\n** CAPI3REF: One-Step Query Execution Interface\n*/\nint sqlite3_exec(\n    sqlite3*,                                         /** An open database */\n    const(char)*sql,                                  /** SQL to be evaluated */\n    int function (void*,int,char**,char**) callback,  /** Callback function */\n    void *,                                           /** 1st argument to callback */\n    char **errmsg                                     /** Error msg written here */\n);\n\n/**\n** CAPI3REF: Result Codes\n*/\nenum\n{\n    SQLITE_OK          = 0,    /** Successful result */\n/* beginning-of-error-codes */\n/// Ditto\n    SQLITE_ERROR       = 1,    /** SQL error or missing database */\n    SQLITE_INTERNAL    = 2,    /** Internal logic error in SQLite */\n    SQLITE_PERM        = 3,    /** Access permission denied */\n    SQLITE_ABORT       = 4,    /** Callback routine requested an abort */\n    SQLITE_BUSY        = 5,    /** The database file is locked */\n    SQLITE_LOCKED      = 6,    /** A table in the database is locked */\n    SQLITE_NOMEM       = 7,    /** A malloc() failed */\n    SQLITE_READONLY    = 8,    /** Attempt to write a readonly database */\n    SQLITE_INTERRUPT   = 9,    /** Operation terminated by sqlite3_interrupt()*/\n    SQLITE_IOERR       = 10,   /** Some kind of disk I/O error occurred */\n    SQLITE_CORRUPT     = 11,   /** The database disk image is malformed */\n    SQLITE_NOTFOUND    = 12,   /** Unknown opcode in sqlite3_file_control() */\n    SQLITE_FULL        = 13,   /** Insertion failed because database is full */\n    SQLITE_CANTOPEN    = 14,   /** Unable to open the database file */\n    SQLITE_PROTOCOL    = 15,   /** Database lock protocol error */\n    SQLITE_EMPTY       = 16,   /** Database is empty */\n    SQLITE_SCHEMA      = 17,   /** The database schema changed */\n    SQLITE_TOOBIG      = 18,   /** String or BLOB exceeds size limit */\n    SQLITE_CONSTRAINT  = 19,   /** Abort due to constraint violation */\n    SQLITE_MISMATCH    = 20,   /** Data type mismatch */\n    SQLITE_MISUSE      = 21,   /** Library used incorrectly */\n    SQLITE_NOLFS       = 22,   /** Uses OS features not supported on host */\n    SQLITE_AUTH        = 23,   /** Authorization denied */\n    SQLITE_FORMAT      = 24,   /** Auxiliary database format error */\n    SQLITE_RANGE       = 25,   /** 2nd parameter to sqlite3_bind out of range */\n    SQLITE_NOTADB      = 26,   /** File opened that is not a database file */\n    SQLITE_NOTICE      = 27,\n    SQLITE_WARNING     = 28,\n    SQLITE_ROW         = 100,  /** sqlite3_step() has another row ready */\n    SQLITE_DONE        = 101  /** sqlite3_step() has finished executing */\n}\n/* end-of-error-codes */\n\n/**\n** CAPI3REF: Extended Result Codes\n*/\nenum\n{\n    SQLITE_IOERR_READ              = (SQLITE_IOERR | (1 << 8)),\n    SQLITE_IOERR_SHORT_READ        = (SQLITE_IOERR | (2 << 8)),\n    SQLITE_IOERR_WRITE             = (SQLITE_IOERR | (3 << 8)),\n    SQLITE_IOERR_FSYNC             = (SQLITE_IOERR | (4 << 8)),\n    SQLITE_IOERR_DIR_FSYNC         = (SQLITE_IOERR | (5 << 8)),\n    SQLITE_IOERR_TRUNCATE          = (SQLITE_IOERR | (6 << 8)),\n    SQLITE_IOERR_FSTAT             = (SQLITE_IOERR | (7 << 8)),\n    SQLITE_IOERR_UNLOCK            = (SQLITE_IOERR | (8 << 8)),\n    SQLITE_IOERR_RDLOCK            = (SQLITE_IOERR | (9 << 8)),\n    SQLITE_IOERR_DELETE            = (SQLITE_IOERR | (10 << 8)),\n    SQLITE_IOERR_BLOCKED           = (SQLITE_IOERR | (11 << 8)),\n    SQLITE_IOERR_NOMEM             = (SQLITE_IOERR | (12 << 8)),\n    SQLITE_IOERR_ACCESS            = (SQLITE_IOERR | (13 << 8)),\n    SQLITE_IOERR_CHECKRESERVEDLOCK = (SQLITE_IOERR | (14 << 8)),\n    SQLITE_IOERR_LOCK              = (SQLITE_IOERR | (15 << 8)),\n    SQLITE_IOERR_CLOSE             = (SQLITE_IOERR | (16 << 8)),\n    SQLITE_IOERR_DIR_CLOSE         = (SQLITE_IOERR | (17 << 8)),\n    SQLITE_IOERR_SHMOPEN           = (SQLITE_IOERR | (18 << 8)),\n    SQLITE_IOERR_SHMSIZE           = (SQLITE_IOERR | (19 << 8)),\n    SQLITE_IOERR_SHMLOCK           = (SQLITE_IOERR | (20 << 8)),\n    SQLITE_IOERR_SHMMAP            = (SQLITE_IOERR | (21 << 8)),\n    SQLITE_IOERR_SEEK              = (SQLITE_IOERR | (22 << 8)),\n    SQLITE_IOERR_DELETE_NOENT      = (SQLITE_IOERR | (23 << 8)),\n    SQLITE_IOERR_MMAP              = (SQLITE_IOERR | (24 << 8)),\n    SQLITE_LOCKED_SHAREDCACHE      = (SQLITE_LOCKED |  (1 << 8)),\n    SQLITE_BUSY_RECOVERY           = (SQLITE_BUSY   |  (1 << 8)),\n    SQLITE_CANTOPEN_NOTEMPDIR      = (SQLITE_CANTOPEN | (1 << 8)),\n    SQLITE_IOERR_GETTEMPPATH       = (SQLITE_IOERR | (25 << 8)),\n    SQLITE_IOERR_CONVPATH          = (SQLITE_IOERR | (26 << 8)),\n    SQLITE_BUSY_SNAPSHOT           = (SQLITE_BUSY   |  (2 << 8)),\n    SQLITE_CANTOPEN_ISDIR          = (SQLITE_CANTOPEN | (2 << 8)),\n    SQLITE_CANTOPEN_FULLPATH       = (SQLITE_CANTOPEN | (3 << 8)),\n    SQLITE_CANTOPEN_CONVPATH       = (SQLITE_CANTOPEN | (4 << 8)),\n    SQLITE_CORRUPT_VTAB            = (SQLITE_CORRUPT | (1 << 8)),\n    SQLITE_READONLY_RECOVERY       = (SQLITE_READONLY | (1 << 8)),\n    SQLITE_READONLY_CANTLOCK       = (SQLITE_READONLY | (2 << 8)),\n    SQLITE_READONLY_ROLLBACK       = (SQLITE_READONLY | (3 << 8)),\n    SQLITE_READONLY_DBMOVED        = (SQLITE_READONLY | (4 << 8)),\n    SQLITE_ABORT_ROLLBACK          = (SQLITE_ABORT | (2 << 8)),\n    SQLITE_CONSTRAINT_CHECK        = (SQLITE_CONSTRAINT | (1 << 8)),\n    SQLITE_CONSTRAINT_COMMITHOOK   = (SQLITE_CONSTRAINT | (2 << 8)),\n    SQLITE_CONSTRAINT_FOREIGNKEY   = (SQLITE_CONSTRAINT | (3 << 8)),\n    SQLITE_CONSTRAINT_FUNCTION     = (SQLITE_CONSTRAINT | (4 << 8)),\n    SQLITE_CONSTRAINT_NOTNULL      = (SQLITE_CONSTRAINT | (5 << 8)),\n    SQLITE_CONSTRAINT_PRIMARYKEY   = (SQLITE_CONSTRAINT | (6 << 8)),\n    SQLITE_CONSTRAINT_TRIGGER      = (SQLITE_CONSTRAINT | (7 << 8)),\n    SQLITE_CONSTRAINT_UNIQUE       = (SQLITE_CONSTRAINT | (8 << 8)),\n    SQLITE_CONSTRAINT_VTAB         = (SQLITE_CONSTRAINT | (9 << 8)),\n    SQLITE_CONSTRAINT_ROWID        = (SQLITE_CONSTRAINT |(10 << 8)),\n    SQLITE_NOTICE_RECOVER_WAL      = (SQLITE_NOTICE | (1 << 8)),\n    SQLITE_NOTICE_RECOVER_ROLLBACK = (SQLITE_NOTICE | (2 << 8)),\n    SQLITE_WARNING_AUTOINDEX       = (SQLITE_WARNING | (1 << 8)),\n    SQLITE_AUTH_USER               = (SQLITE_AUTH | (1 << 8))\n}\n\n/**\n** CAPI3REF: Flags For File Open Operations\n*/\nenum\n{\n    SQLITE_OPEN_READONLY         = 0x00000001,  /** Ok for sqlite3_open_v2() */\n    SQLITE_OPEN_READWRITE        = 0x00000002,  /** Ok for sqlite3_open_v2() */\n    SQLITE_OPEN_CREATE           = 0x00000004,  /** Ok for sqlite3_open_v2() */\n    SQLITE_OPEN_DELETEONCLOSE    = 0x00000008,  /** VFS only */\n    SQLITE_OPEN_EXCLUSIVE        = 0x00000010,  /** VFS only */\n    SQLITE_OPEN_AUTOPROXY        = 0x00000020,  /** VFS only */\n    SQLITE_OPEN_URI              = 0x00000040,  /** Ok for sqlite3_open_v2() */\n    SQLITE_OPEN_MEMORY           = 0x00000080,  /** Ok for sqlite3_open_v2() */\n    SQLITE_OPEN_MAIN_DB          = 0x00000100,  /** VFS only */\n    SQLITE_OPEN_TEMP_DB          = 0x00000200,  /** VFS only */\n    SQLITE_OPEN_TRANSIENT_DB     = 0x00000400,  /** VFS only */\n    SQLITE_OPEN_MAIN_JOURNAL     = 0x00000800,  /** VFS only */\n    SQLITE_OPEN_TEMP_JOURNAL     = 0x00001000,  /** VFS only */\n    SQLITE_OPEN_SUBJOURNAL       = 0x00002000,  /** VFS only */\n    SQLITE_OPEN_MASTER_JOURNAL   = 0x00004000,  /** VFS only */\n    SQLITE_OPEN_NOMUTEX          = 0x00008000,  /** Ok for sqlite3_open_v2() */\n    SQLITE_OPEN_FULLMUTEX        = 0x00010000,  /** Ok for sqlite3_open_v2() */\n    SQLITE_OPEN_SHAREDCACHE      = 0x00020000,  /** Ok for sqlite3_open_v2() */\n    SQLITE_OPEN_PRIVATECACHE     = 0x00040000,  /** Ok for sqlite3_open_v2() */\n    SQLITE_OPEN_WAL              = 0x00080000  /** VFS only */\n}\n\n/**\n** CAPI3REF: Device Characteristics\n*/\nenum\n{\n    SQLITE_IOCAP_ATOMIC                 = 0x00000001,\n    SQLITE_IOCAP_ATOMIC512              = 0x00000002,\n    SQLITE_IOCAP_ATOMIC1K               = 0x00000004,\n    SQLITE_IOCAP_ATOMIC2K               = 0x00000008,\n    SQLITE_IOCAP_ATOMIC4K               = 0x00000010,\n    SQLITE_IOCAP_ATOMIC8K               = 0x00000020,\n    SQLITE_IOCAP_ATOMIC16K              = 0x00000040,\n    SQLITE_IOCAP_ATOMIC32K              = 0x00000080,\n    SQLITE_IOCAP_ATOMIC64K              = 0x00000100,\n    SQLITE_IOCAP_SAFE_APPEND            = 0x00000200,\n    SQLITE_IOCAP_SEQUENTIAL             = 0x00000400,\n    SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN  = 0x00000800,\n    SQLITE_IOCAP_POWERSAFE_OVERWRITE    = 0x00001000,\n    SQLITE_IOCAP_IMMUTABLE              = 0x00002000\n}\n\n/**\n** CAPI3REF: File Locking Levels\n*/\nenum\n{\n    SQLITE_LOCK_NONE          = 0,\n    SQLITE_LOCK_SHARED        = 1,\n    SQLITE_LOCK_RESERVED      = 2,\n    SQLITE_LOCK_PENDING       = 3,\n    SQLITE_LOCK_EXCLUSIVE     = 4\n}\n\n/**\n** CAPI3REF: Synchronization Type Flags\n*/\nenum\n{\n    SQLITE_SYNC_NORMAL        = 0x00002,\n    SQLITE_SYNC_FULL          = 0x00003,\n    SQLITE_SYNC_DATAONLY      = 0x00010\n}\n\n/**\n** CAPI3REF: OS Interface Open File Handle\n*/\nstruct sqlite3_file\n{\n    const(sqlite3_io_methods)*pMethods;  /* Methods for an open file */\n}\n\n/**\n** CAPI3REF: OS Interface File Virtual Methods Object\n*/\n\nstruct sqlite3_io_methods\n{\n    int iVersion;\n    int  function (sqlite3_file*) xClose;\n    int  function (sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst) xRead;\n    int  function (sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst) xWrite;\n    int  function (sqlite3_file*, sqlite3_int64 size) xTruncate;\n    int  function (sqlite3_file*, int flags) xSync;\n    int  function (sqlite3_file*, sqlite3_int64 *pSize) xFileSize;\n    int  function (sqlite3_file*, int) xLock;\n    int  function (sqlite3_file*, int) xUnlock;\n    int  function (sqlite3_file*, int *pResOut) xCheckReservedLock;\n    int  function (sqlite3_file*, int op, void *pArg) xFileControl;\n    int  function (sqlite3_file*) xSectorSize;\n    int  function (sqlite3_file*) xDeviceCharacteristics;\n    /* Methods above are valid for version 1 */\n    int  function (sqlite3_file*, int iPg, int pgsz, int, void **) xShmMap;\n    int  function (sqlite3_file*, int offset, int n, int flags) xShmLock;\n    void  function (sqlite3_file*) xShmBarrier;\n    int  function (sqlite3_file*, int deleteFlag) xShmUnmap;\n    /* Methods above are valid for version 2 */\n    /* Additional methods may be added in future releases */\n    int function (sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp) xFetch;\n    int function (sqlite3_file*, sqlite3_int64 iOfst, void *p) xUnfetch;\n}\n\n/**\n** CAPI3REF: Standard File Control Opcodes\n*/\nenum\n{\n    SQLITE_FCNTL_LOCKSTATE           = 1,\n    SQLITE_GET_LOCKPROXYFILE         = 2,\n    SQLITE_SET_LOCKPROXYFILE         = 3,\n    SQLITE_LAST_ERRNO                = 4,\n    SQLITE_FCNTL_SIZE_HINT           = 5,\n    SQLITE_FCNTL_CHUNK_SIZE          = 6,\n    SQLITE_FCNTL_FILE_POINTER        = 7,\n    SQLITE_FCNTL_SYNC_OMITTED        = 8,\n    SQLITE_FCNTL_WIN32_AV_RETRY      = 9,\n    SQLITE_FCNTL_PERSIST_WAL         = 10,\n    SQLITE_FCNTL_OVERWRITE           = 11,\n    SQLITE_FCNTL_VFSNAME             = 12,\n    SQLITE_FCNTL_POWERSAFE_OVERWRITE = 13,\n    SQLITE_FCNTL_PRAGMA              = 14,\n    SQLITE_FCNTL_BUSYHANDLER         = 15,\n    SQLITE_FCNTL_TEMPFILENAME        = 16,\n    SQLITE_FCNTL_MMAP_SIZE           = 18,\n    SQLITE_FCNTL_TRACE               = 19,\n    SQLITE_FCNTL_HAS_MOVED           = 20,\n    SQLITE_FCNTL_SYNC                = 21,\n    SQLITE_FCNTL_COMMIT_PHASETWO     = 22,\n    SQLITE_FCNTL_WIN32_SET_HANDLE    = 23,\n    SQLITE_FCNTL_WAL_BLOCK           = 24,\n    SQLITE_FCNTL_ZIPVFS              = 25,\n    SQLITE_FCNTL_RBU                 = 26,\n    SQLITE_FCNTL_VFS_POINTER         = 27,\n}\n\n/**\n** CAPI3REF: Mutex Handle\n*/\nstruct sqlite3_mutex;\n\n/**\n** CAPI3REF: OS Interface Object\n*/\n\nalias xDlSymReturn = void * function();\n/// Ditto\nalias sqlite3_syscall_ptr = void function();\n\nstruct sqlite3_vfs\n{\n    int iVersion;            /** Structure version number (currently 2) */\n    int szOsFile;            /** Size of subclassed sqlite3_file */\n    int mxPathname;          /** Maximum file pathname length */\n    sqlite3_vfs *pNext;      /** Next registered VFS */\n    const(char)*zName;       /** Name of this virtual file system */\n    void *pAppData;          /** Pointer to application-specific data */\n    int function (sqlite3_vfs*, const char *zName, sqlite3_file*,\n               int flags, int *pOutFlags) xOpen;\n    int  function (sqlite3_vfs*, const char *zName, int syncDir) xDelete;\n    int  function (sqlite3_vfs*, const char *zName, int flags, int *pResOut) xAccess;\n    int  function (sqlite3_vfs*, const char *zName, int nOut, char *zOut) xFullPathname;\n    void* function (sqlite3_vfs*, const char *zFilename) xDlOpen;\n    void  function (sqlite3_vfs*, int nByte, char *zErrMsg) xDlError;\n    xDlSymReturn function (sqlite3_vfs*,void*, const char *zSymbol) *xDlSym;\n    void  function (sqlite3_vfs*, void*) xDlClose;\n    int  function (sqlite3_vfs*, int nByte, char *zOut) xRandomness;\n    int  function (sqlite3_vfs*, int microseconds) xSleep;\n    int  function (sqlite3_vfs*, double*) xCurrentTime;\n    int  function (sqlite3_vfs*, int, char *) xGetLastError;\n    /*\n    ** The methods above are in version 1 of the sqlite_vfs object\n    ** definition.  Those that follow are added in version 2 or later\n    */\n    int  function (sqlite3_vfs*, sqlite3_int64*) xCurrentTimeInt64;\n    /*\n    ** The methods above are in versions 1 and 2 of the sqlite_vfs object.\n    ** Those below are for version 3 and greater.\n    */\n    int function(sqlite3_vfs*, const char * zName, sqlite3_syscall_ptr) xSetSystemCall;\n    sqlite3_syscall_ptr function(sqlite3_vfs*, const char * zName) xGetSystemCall;\n    const(char)* function(sqlite3_vfs*, const char * zName) xNextSystemCall;\n    /*\n    ** The methods above are in versions 1 through 3 of the sqlite_vfs object.\n    ** New fields may be appended in figure versions.  The iVersion\n    ** value will increment whenever this happens.\n    */\n}\n\n/**\n** CAPI3REF: Flags for the xAccess VFS method\n*/\nenum\n{\n    SQLITE_ACCESS_EXISTS    = 0,\n\n    SQLITE_ACCESS_READWRITE = 1,   /** Used by PRAGMA temp_store_directory */\n    SQLITE_ACCESS_READ      = 2   /** Unused */\n}\n\n/**\n** CAPI3REF: Flags for the xShmLock VFS method\n*/\nenum\n{\n    SQLITE_SHM_UNLOCK       = 1,\n    SQLITE_SHM_LOCK         = 2,\n    SQLITE_SHM_SHARED       = 4,\n    SQLITE_SHM_EXCLUSIVE    = 8\n}\n\n/**\n** CAPI3REF: Maximum xShmLock index\n*/\nenum SQLITE_SHM_NLOCK        = 8;\n\n\n/**\n** CAPI3REF: Initialize The SQLite Library\n*/\nint sqlite3_initialize();\n/// Ditto\nint sqlite3_shutdown();\n/// Ditto\nint sqlite3_os_init();\n/// Ditto\nint sqlite3_os_end();\n\n/**\n** CAPI3REF: Configuring The SQLite Library\n*/\nint sqlite3_config(int, ...);\n\n/**\n** CAPI3REF: Configure database connections\n*/\nint sqlite3_db_config(sqlite3*, int op, ...);\n\n/**\n** CAPI3REF: Memory Allocation Routines\n*/\nstruct sqlite3_mem_methods\n{\n    void* function (int) xMalloc;         /** Memory allocation function */\n    void function (void*) xFree;          /** Free a prior allocation */\n    void* function (void*,int) xRealloc;  /** Resize an allocation */\n    int function (void*) xSize;           /** Return the size of an allocation */\n    int function (int) xRoundup;          /** Round up request size to allocation size */\n    int function (void*) xInit;           /** Initialize the memory allocator */\n    void function (void*) xShutdown;      /** Deinitialize the memory allocator */\n    void *pAppData;                       /** Argument to xInit() and xShutdown() */\n}\n\n/**\n** CAPI3REF: Configuration Options\n*/\nenum\n{\n    SQLITE_CONFIG_SINGLETHREAD         = 1,  /** nil */\n    SQLITE_CONFIG_MULTITHREAD          = 2,  /** nil */\n    SQLITE_CONFIG_SERIALIZED           = 3,  /** nil */\n    SQLITE_CONFIG_MALLOC               = 4,  /** sqlite3_mem_methods* */\n    SQLITE_CONFIG_GETMALLOC            = 5,  /** sqlite3_mem_methods* */\n    SQLITE_CONFIG_SCRATCH              = 6,  /** void*, int sz, int N */\n    SQLITE_CONFIG_PAGECACHE            = 7,  /** void*, int sz, int N */\n    SQLITE_CONFIG_HEAP                 = 8,  /** void*, int nByte, int min */\n    SQLITE_CONFIG_MEMSTATUS            = 9,  /** boolean */\n    SQLITE_CONFIG_MUTEX                = 10,  /** sqlite3_mutex_methods* */\n    SQLITE_CONFIG_GETMUTEX             = 11,  /** sqlite3_mutex_methods* */\n/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */\n    SQLITE_CONFIG_LOOKASIDE            = 13,  /** int int */\n    SQLITE_CONFIG_PCACHE               = 14,  /** sqlite3_pcache_methods* */\n    SQLITE_CONFIG_GETPCACHE            = 15,  /** sqlite3_pcache_methods* */\n    SQLITE_CONFIG_LOG                  = 16,  /** xFunc, void* */\n    SQLITE_CONFIG_URI                  = 17,\n    SQLITE_CONFIG_PCACHE2              = 18,\n    SQLITE_CONFIG_GETPCACHE2           = 19,\n    SQLITE_CONFIG_COVERING_INDEX_SCAN  = 20,\n    SQLITE_CONFIG_SQLLOG               = 21,\n    SQLITE_CONFIG_MMAP_SIZE            = 22,\n    SQLITE_CONFIG_WIN32_HEAPSIZE       = 23,\n    SQLITE_CONFIG_PCACHE_HDRSZ         = 24,\n    SQLITE_CONFIG_PMASZ                = 25,\n}\n\n/**\n** CAPI3REF: Database Connection Configuration Options\n*/\nenum\n{\n    SQLITE_DBCONFIG_LOOKASIDE      = 1001,  /** void* int int */\n    SQLITE_DBCONFIG_ENABLE_FKEY    = 1002,  /** int int* */\n    SQLITE_DBCONFIG_ENABLE_TRIGGER = 1003  /** int int* */\n}\n\n\n/**\n** CAPI3REF: Enable Or Disable Extended Result Codes\n*/\nint sqlite3_extended_result_codes(sqlite3*, int onoff);\n\n/**\n** CAPI3REF: Last Insert Rowid\n*/\nsqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);\n\n/**\n** CAPI3REF: Count The Number Of Rows Modified\n*/\nint sqlite3_changes(sqlite3*);\n\n/**\n** CAPI3REF: Total Number Of Rows Modified\n*/\nint sqlite3_total_changes(sqlite3*);\n\n/**\n** CAPI3REF: Interrupt A Long-Running Query\n*/\nvoid sqlite3_interrupt(sqlite3*);\n\n/**\n** CAPI3REF: Determine If An SQL Statement Is Complete\n*/\nint sqlite3_complete(const char *sql);\n/// Ditto\nint sqlite3_complete16(const void *sql);\n\n/**\n** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors\n*/\nint sqlite3_busy_handler(sqlite3*, int function (void*,int), void*);\n\n/**\n** CAPI3REF: Set A Busy Timeout\n*/\nint sqlite3_busy_timeout(sqlite3*, int ms);\n\n/**\n** CAPI3REF: Convenience Routines For Running Queries\n*/\nint sqlite3_get_table(\n    sqlite3 *db,          /** An open database */\n    const(char)*zSql,     /** SQL to be evaluated */\n    char ***pazResult,    /** Results of the query */\n    int *pnRow,           /** Number of result rows written here */\n    int *pnColumn,        /** Number of result columns written here */\n    char **pzErrmsg       /** Error msg written here */\n);\n///\nvoid sqlite3_free_table(char **result);\n\n/**\n** CAPI3REF: Formatted String Printing Functions\n*/\nchar *sqlite3_mprintf(const char*,...);\nchar *sqlite3_vmprintf(const char*, va_list);\nchar *sqlite3_snprintf(int,char*,const char*, ...);\nchar *sqlite3_vsnprintf(int,char*,const char*, va_list);\n\n/**\n** CAPI3REF: Memory Allocation Subsystem\n*/\nvoid *sqlite3_malloc(int);\n/// Ditto\nvoid *sqlite3_malloc64(sqlite3_uint64);\n/// Ditto\nvoid *sqlite3_realloc(void*, int);\n/// Ditto\nvoid *sqlite3_realloc64(void*, sqlite3_uint64);\n/// Ditto\nvoid sqlite3_free(void*);\n/// Ditto\nsqlite3_uint64 sqlite3_msize(void*);\n\n/**\n** CAPI3REF: Memory Allocator Statistics\n*/\nsqlite3_int64 sqlite3_memory_used();\nsqlite3_int64 sqlite3_memory_highwater(int resetFlag);\n\n/**\n** CAPI3REF: Pseudo-Random Number Generator\n*/\nvoid sqlite3_randomness(int N, void *P);\n\n/**\n** CAPI3REF: Compile-Time Authorization Callbacks\n*/\nint sqlite3_set_authorizer(\n    sqlite3*,\n    int function (void*,int,const char*,const char*,const char*,const char*) xAuth,\n    void *pUserData\n);\n\n/**\n** CAPI3REF: Authorizer Return Codes\n*/\nenum\n{\n    SQLITE_DENY   = 1,   /** Abort the SQL statement with an error */\n    SQLITE_IGNORE = 2   /** Don't allow access, but don't generate an error */\n}\n\n/**\n** CAPI3REF: Authorizer Action Codes\n*/\n/******************************************* 3rd ************ 4th ***********/\nenum\n{\n    SQLITE_CREATE_INDEX         =  1,   /** Index Name      Table Name      */\n    SQLITE_CREATE_TABLE         =  2,   /** Table Name      NULL            */\n    SQLITE_CREATE_TEMP_INDEX    =  3,   /** Index Name      Table Name      */\n    SQLITE_CREATE_TEMP_TABLE    =  4,   /** Table Name      NULL            */\n    SQLITE_CREATE_TEMP_TRIGGER  =  5,   /** Trigger Name    Table Name      */\n    SQLITE_CREATE_TEMP_VIEW     =  6,   /** View Name       NULL            */\n    SQLITE_CREATE_TRIGGER       =  7,   /** Trigger Name    Table Name      */\n    SQLITE_CREATE_VIEW          =  8,   /** View Name       NULL            */\n    SQLITE_DELETE               =  9,   /** Table Name      NULL            */\n    SQLITE_DROP_INDEX           = 10,   /** Index Name      Table Name      */\n    SQLITE_DROP_TABLE           = 11,   /** Table Name      NULL            */\n    SQLITE_DROP_TEMP_INDEX      = 12,   /** Index Name      Table Name      */\n    SQLITE_DROP_TEMP_TABLE      = 13,   /** Table Name      NULL            */\n    SQLITE_DROP_TEMP_TRIGGER    = 14,   /** Trigger Name    Table Name      */\n    SQLITE_DROP_TEMP_VIEW       = 15,   /** View Name       NULL            */\n    SQLITE_DROP_TRIGGER         = 16,   /** Trigger Name    Table Name      */\n    SQLITE_DROP_VIEW            = 17,   /** View Name       NULL            */\n    SQLITE_INSERT               = 18,   /** Table Name      NULL            */\n    SQLITE_PRAGMA               = 19,   /** Pragma Name     1st arg or NULL */\n    SQLITE_READ                 = 20,   /** Table Name      Column Name     */\n    SQLITE_SELECT               = 21,   /** NULL            NULL            */\n    SQLITE_TRANSACTION          = 22,   /** Operation       NULL            */\n    SQLITE_UPDATE               = 23,   /** Table Name      Column Name     */\n    SQLITE_ATTACH               = 24,   /** Filename        NULL            */\n    SQLITE_DETACH               = 25,   /** Database Name   NULL            */\n    SQLITE_ALTER_TABLE          = 26,   /** Database Name   Table Name      */\n    SQLITE_REINDEX              = 27,   /** Index Name      NULL            */\n    SQLITE_ANALYZE              = 28,   /** Table Name      NULL            */\n    SQLITE_CREATE_VTABLE        = 29,   /** Table Name      Module Name     */\n    SQLITE_DROP_VTABLE          = 30,   /** Table Name      Module Name     */\n    SQLITE_FUNCTION             = 31,   /** NULL            Function Name   */\n    SQLITE_SAVEPOINT            = 32,   /** Operation       Savepoint Name  */\n    SQLITE_COPY                 =  0,   /** No longer used */\n    SQLITE_RECURSIVE            = 33\n}\n\n/**\n** CAPI3REF: Tracing And Profiling Functions\n*/\nvoid *sqlite3_trace(sqlite3*, void function (void*,const char*) xTrace, void*);\n/// Ditto\nvoid *sqlite3_profile(sqlite3*, void function (void*,const char*,sqlite3_uint64) xProfile, void*);\n\n/**\n** CAPI3REF: Query Progress Callbacks\n*/\nvoid sqlite3_progress_handler(sqlite3*, int, int function (void*), void*);\n\n/**\n** CAPI3REF: Opening A New Database Connection\n*/\nint sqlite3_open(\n    const(char)*filename,   /** Database filename (UTF-8) */\n    sqlite3 **ppDb          /** OUT: SQLite db handle */\n);\n/// Ditto\nint sqlite3_open16(\n    const(void)*filename,   /** Database filename (UTF-16) */\n    sqlite3 **ppDb          /** OUT: SQLite db handle */\n);\n/// Ditto\nint sqlite3_open_v2(\n    const(char)*filename,   /** Database filename (UTF-8) */\n    sqlite3 **ppDb,         /** OUT: SQLite db handle */\n    int flags,              /** Flags */\n    const(char)*zVfs        /** Name of VFS module to use */\n);\n\n/*\n** CAPI3REF: Obtain Values For URI Parameters\n*/\nconst(char)* sqlite3_uri_parameter(const(char)* zFilename, const(char)* zParam);\n/// Ditto\nint sqlite3_uri_boolean(const(char)* zFile, const(char)* zParam, int bDefault);\n/// Ditto\nsqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);\n\n/**\n** CAPI3REF: Error Codes And Messages\n*/\nint sqlite3_errcode(sqlite3 *db);\n/// Ditto\nint sqlite3_extended_errcode(sqlite3 *db);\n/// Ditto\nconst(char)* sqlite3_errmsg(sqlite3*);\n/// Ditto\nconst(void)* sqlite3_errmsg16(sqlite3*);\n/// Ditto\nconst(char)* sqlite3_errstr(int);\n\n/**\n** CAPI3REF: SQL Statement Object\n*/\nstruct sqlite3_stmt;\n\n/**\n** CAPI3REF: Run-time Limits\n*/\nint sqlite3_limit(sqlite3*, int id, int newVal);\n\n/**\n** CAPI3REF: Run-Time Limit Categories\n*/\nenum\n{\n    SQLITE_LIMIT_LENGTH                    = 0,\n    SQLITE_LIMIT_SQL_LENGTH                = 1,\n    SQLITE_LIMIT_COLUMN                    = 2,\n    SQLITE_LIMIT_EXPR_DEPTH                = 3,\n    SQLITE_LIMIT_COMPOUND_SELECT           = 4,\n    SQLITE_LIMIT_VDBE_OP                   = 5,\n    SQLITE_LIMIT_FUNCTION_ARG              = 6,\n    SQLITE_LIMIT_ATTACHED                  = 7,\n    SQLITE_LIMIT_LIKE_PATTERN_LENGTH       = 8,\n    SQLITE_LIMIT_VARIABLE_NUMBER           = 9,\n    SQLITE_LIMIT_TRIGGER_DEPTH             = 10,\n    SQLITE_LIMIT_WORKER_THREADS            = 11,\n}\n\n/**\n** CAPI3REF: Compiling An SQL Statement\n*/\nint sqlite3_prepare(\n    sqlite3 *db,            /** Database handle */\n    const(char)*zSql,       /** SQL statement, UTF-8 encoded */\n    int nByte,              /** Maximum length of zSql in bytes. */\n    sqlite3_stmt **ppStmt,  /** OUT: Statement handle */\n    const(char*)*pzTail     /** OUT: Pointer to unused portion of zSql */\n);\n/// Ditto\nint sqlite3_prepare_v2(\n    sqlite3 *db,            /** Database handle */\n    const(char)*zSql,       /** SQL statement, UTF-8 encoded */\n    int nByte,              /** Maximum length of zSql in bytes. */\n    sqlite3_stmt **ppStmt,  /** OUT: Statement handle */\n    const(char*)*pzTail     /** OUT: Pointer to unused portion of zSql */\n);\n/// Ditto\nint sqlite3_prepare16(\n    sqlite3 *db,            /** Database handle */\n    const(void)*zSql,       /** SQL statement, UTF-16 encoded */\n    int nByte,              /** Maximum length of zSql in bytes. */\n    sqlite3_stmt **ppStmt,  /** OUT: Statement handle */\n    const(void*)*pzTail     /** OUT: Pointer to unused portion of zSql */\n);\n/// Ditto\nint sqlite3_prepare16_v2(\n    sqlite3 *db,            /** Database handle */\n    const(void)*zSql,       /** SQL statement, UTF-16 encoded */\n    int nByte,              /** Maximum length of zSql in bytes. */\n    sqlite3_stmt **ppStmt,  /** OUT: Statement handle */\n    const(void*)*pzTail     /** OUT: Pointer to unused portion of zSql */\n);\n\n/**\n** CAPI3REF: Retrieving Statement SQL\n*/\nconst(char)* sqlite3_sql(sqlite3_stmt *pStmt);\n\n/*\n** CAPI3REF: Determine If An SQL Statement Writes The Database\n*/\nint sqlite3_stmt_readonly(sqlite3_stmt *pStmt);\n\n/**\n** CAPI3REF: Determine If A Prepared Statement Has Been Reset\n*/\nint sqlite3_stmt_busy(sqlite3_stmt*);\n\n\n/**\n** CAPI3REF: Dynamically Typed Value Object\n*/\nstruct sqlite3_value;\n\n/**\n** CAPI3REF: SQL Function Context Object\n*/\nstruct sqlite3_context;\n\n/**\n** CAPI3REF: Binding Values To Prepared Statements\n*/\nint sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void function (void*));\n/// Ditto\nint sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,void function (void*));\n/// Ditto\nint sqlite3_bind_double(sqlite3_stmt*, int, double);\n/// Ditto\nint sqlite3_bind_int(sqlite3_stmt*, int, int);\n/// Ditto\nint sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);\n/// Ditto\nint sqlite3_bind_null(sqlite3_stmt*, int);\n/// Ditto\nint sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void function (void*));\n/// Ditto\nint sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void function (void*));\n/// Ditto\nint sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,void function (void*), ubyte encoding);\n/// Ditto\nint sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);\n/// Ditto\nint sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);\n/// Ditto\nint sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64 n);\n\n/**\n** CAPI3REF: Number Of SQL Parameters\n*/\nint sqlite3_bind_parameter_count(sqlite3_stmt*);\n\n/**\n** CAPI3REF: Name Of A Host Parameter\n*/\nconst(char)* sqlite3_bind_parameter_name(sqlite3_stmt*, int);\n\n/**\n** CAPI3REF: Index Of A Parameter With A Given Name\n*/\nint sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);\n\n/**\n** CAPI3REF: Reset All Bindings On A Prepared Statement\n*/\nint sqlite3_clear_bindings(sqlite3_stmt*);\n\n/**\n** CAPI3REF: Number Of Columns In A Result Set\n*/\nint sqlite3_column_count(sqlite3_stmt *pStmt);\n\n/**\n** CAPI3REF: Column Names In A Result Set\n*/\nconst(char)* sqlite3_column_name(sqlite3_stmt*, int N);\n/// Ditto\nconst(void)* sqlite3_column_name16(sqlite3_stmt*, int N);\n\n/**\n** CAPI3REF: Source Of Data In A Query Result\n*/\nconst(char)* sqlite3_column_database_name(sqlite3_stmt*,int);\n/// Ditto\nconst(void)* sqlite3_column_database_name16(sqlite3_stmt*,int);\n/// Ditto\nconst(char)* sqlite3_column_table_name(sqlite3_stmt*,int);\n/// Ditto\nconst (void)* sqlite3_column_table_name16(sqlite3_stmt*,int);\n/// Ditto\nconst (char)* sqlite3_column_origin_name(sqlite3_stmt*,int);\n/// Ditto\nconst (void)* sqlite3_column_origin_name16(sqlite3_stmt*,int);\n\n/**\n** CAPI3REF: Declared Datatype Of A Query Result\n*/\nconst (char)* sqlite3_column_decltype(sqlite3_stmt*,int);\n/// Ditto\nconst (void)* sqlite3_column_decltype16(sqlite3_stmt*,int);\n\n/**\n** CAPI3REF: Evaluate An SQL Statement\n*/\nint sqlite3_step(sqlite3_stmt*);\n\n/**\n** CAPI3REF: Number of columns in a result set\n*/\nint sqlite3_data_count(sqlite3_stmt *pStmt);\n\n/**\n** CAPI3REF: Fundamental Datatypes\n*/\nenum\n{\n    SQLITE_INTEGER  = 1,\n    SQLITE_FLOAT    = 2,\n    SQLITE_BLOB     = 4,\n    SQLITE_NULL     = 5,\n    SQLITE3_TEXT    = 3\n}\n\n/**\n** CAPI3REF: Result Values From A Query\n*/\nconst (void)* sqlite3_column_blob(sqlite3_stmt*, int iCol);\n/// Ditto\nint sqlite3_column_bytes(sqlite3_stmt*, int iCol);\n/// Ditto\nint sqlite3_column_bytes16(sqlite3_stmt*, int iCol);\n/// Ditto\ndouble sqlite3_column_double(sqlite3_stmt*, int iCol);\n/// Ditto\nint sqlite3_column_int(sqlite3_stmt*, int iCol);\n/// Ditto\nsqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);\n/// Ditto\nconst (char)* sqlite3_column_text(sqlite3_stmt*, int iCol);\n/// Ditto\nconst (void)* sqlite3_column_text16(sqlite3_stmt*, int iCol);\n/// Ditto\nint sqlite3_column_type(sqlite3_stmt*, int iCol);\n/// Ditto\nsqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);\n\n/**\n** CAPI3REF: Destroy A Prepared Statement Object\n*/\nint sqlite3_finalize(sqlite3_stmt *pStmt);\n\n/**\n** CAPI3REF: Reset A Prepared Statement Object\n*/\nint sqlite3_reset(sqlite3_stmt *pStmt);\n\n/**\n** CAPI3REF: Create Or Redefine SQL Functions\n*/\nint sqlite3_create_function(\n    sqlite3 *db,\n    const(char)*zFunctionName,\n    int nArg,\n    int eTextRep,\n    void *pApp,\n    void function (sqlite3_context*,int,sqlite3_value**) xFunc,\n    void function (sqlite3_context*,int,sqlite3_value**) xStep,\n    void function (sqlite3_context*) xFinal\n);\n/// Ditto\nint sqlite3_create_function16(\n    sqlite3 *db,\n    const(void)*zFunctionName,\n    int nArg,\n    int eTextRep,\n    void *pApp,\n    void function (sqlite3_context*,int,sqlite3_value**) xFunc,\n    void function (sqlite3_context*,int,sqlite3_value**) xStep,\n    void function (sqlite3_context*) xFinal\n);\n/// Ditto\nint sqlite3_create_function_v2(\n    sqlite3 *db,\n    const(char)*zFunctionName,\n    int nArg,\n    int eTextRep,\n    void *pApp,\n    void function (sqlite3_context*,int,sqlite3_value**) xFunc,\n    void function (sqlite3_context*,int,sqlite3_value**) xStep,\n    void function (sqlite3_context*) xFinal,\n    void function (void*) xDestroy\n);\n\n/**\n** CAPI3REF: Text Encodings\n**\n** These constant define integer codes that represent the various\n** text encodings supported by SQLite.\n*/\nenum\n{\n    SQLITE_UTF8           = 1,\n    SQLITE_UTF16LE        = 2,\n    SQLITE_UTF16BE        = 3\n}\n/// Ditto\nenum\n{\n    SQLITE_UTF16          = 4,    /** Use native byte order */\n    SQLITE_ANY            = 5,    /** sqlite3_create_function only */\n    SQLITE_UTF16_ALIGNED  = 8    /** sqlite3_create_collation only */\n}\n\n/**\n** CAPI3REF: Function Flags\n*/\nenum SQLITE_DETERMINISTIC = 0x800;\n\n/**\n** CAPI3REF: Deprecated Functions\n*/\ndeprecated int sqlite3_aggregate_count(sqlite3_context*);\ndeprecated int sqlite3_expired(sqlite3_stmt*);\ndeprecated int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);\ndeprecated int sqlite3_global_recover();\ndeprecated void sqlite3_thread_cleanup();\ndeprecated int sqlite3_memory_alarm(void function(void*,sqlite3_int64,int),void*,sqlite3_int64);\n\n/**\n** CAPI3REF: Obtaining SQL Function Parameter Values\n*/\nconst (void)* sqlite3_value_blob(sqlite3_value*);\n/// Ditto\nint sqlite3_value_bytes(sqlite3_value*);\n/// Ditto\nint sqlite3_value_bytes16(sqlite3_value*);\n/// Ditto\ndouble sqlite3_value_double(sqlite3_value*);\n/// Ditto\nint sqlite3_value_int(sqlite3_value*);\n/// Ditto\nsqlite3_int64 sqlite3_value_int64(sqlite3_value*);\n/// Ditto\nconst (char)* sqlite3_value_text(sqlite3_value*);\n/// Ditto\nconst (void)* sqlite3_value_text16(sqlite3_value*);\n/// Ditto\nconst (void)* sqlite3_value_text16le(sqlite3_value*);\n/// Ditto\nconst (void)* sqlite3_value_text16be(sqlite3_value*);\n/// Ditto\nint sqlite3_value_type(sqlite3_value*);\n/// Ditto\nint sqlite3_value_numeric_type(sqlite3_value*);\n\n/*\n** CAPI3REF: Finding The Subtype Of SQL Values\n*/\nuint sqlite3_value_subtype(sqlite3_value*);\n\n/*\n** CAPI3REF: Copy And Free SQL Values\n*/\nsqlite3_value* sqlite3_value_dup(const sqlite3_value*);\nvoid sqlite3_value_free(sqlite3_value*);\n\n/**\n** CAPI3REF: Obtain Aggregate Function Context\n*/\nvoid *sqlite3_aggregate_context(sqlite3_context*, int nBytes);\n\n/**\n** CAPI3REF: User Data For Functions\n*/\nvoid *sqlite3_user_data(sqlite3_context*);\n\n/**\n** CAPI3REF: Database Connection For Functions\n*/\nsqlite3 *sqlite3_context_db_handle(sqlite3_context*);\n\n/**\n** CAPI3REF: Function Auxiliary Data\n*/\nvoid *sqlite3_get_auxdata(sqlite3_context*, int N);\n/// Ditto\nvoid sqlite3_set_auxdata(sqlite3_context*, int N, void*, void function (void*));\n\n\n/**\n** CAPI3REF: Constants Defining Special Destructor Behavior\n*/\nalias sqlite3_destructor_type = void function (void*);\n/// Ditto\nenum\n{\n    SQLITE_STATIC      = (cast(sqlite3_destructor_type) 0),\n    SQLITE_TRANSIENT   = (cast (sqlite3_destructor_type) -1)\n}\n\n/**\n** CAPI3REF: Setting The Result Of An SQL Function\n*/\nvoid sqlite3_result_blob(sqlite3_context*, const void*, int, void function(void*));\n/// Ditto\nvoid sqlite3_result_blob64(sqlite3_context*,const void*,sqlite3_uint64,void function(void*));\n/// Ditto\nvoid sqlite3_result_double(sqlite3_context*, double);\n/// Ditto\nvoid sqlite3_result_error(sqlite3_context*, const char*, int);\n/// Ditto\nvoid sqlite3_result_error16(sqlite3_context*, const void*, int);\n/// Ditto\nvoid sqlite3_result_error_toobig(sqlite3_context*);\n/// Ditto\nvoid sqlite3_result_error_nomem(sqlite3_context*);\n/// Ditto\nvoid sqlite3_result_error_code(sqlite3_context*, int);\n/// Ditto\nvoid sqlite3_result_int(sqlite3_context*, int);\n/// Ditto\nvoid sqlite3_result_int64(sqlite3_context*, sqlite3_int64);\n/// Ditto\nvoid sqlite3_result_null(sqlite3_context*);\n/// Ditto\nvoid sqlite3_result_text(sqlite3_context*, const char*, int, void function(void*));\n/// Ditto\nvoid sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,void function(void*), ubyte encoding);\n/// Ditto\nvoid sqlite3_result_text16(sqlite3_context*, const void*, int, void function(void*));\n/// Ditto\nvoid sqlite3_result_text16le(sqlite3_context*, const void*, int, void function(void*));\n/// Ditto\nvoid sqlite3_result_text16be(sqlite3_context*, const void*, int, void function(void*));\n/// Ditto\nvoid sqlite3_result_value(sqlite3_context*, sqlite3_value*);\n/// Ditto\nvoid sqlite3_result_zeroblob(sqlite3_context*, int n);\n/// Ditto\nint sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);\n\n/*\n** CAPI3REF: Setting The Subtype Of An SQL Function\n*/\nvoid sqlite3_result_subtype(sqlite3_context*,uint);\n\n/**\n** CAPI3REF: Define New Collating Sequences\n*/\nint sqlite3_create_collation(\n    sqlite3*,\n    const(char)*zName,\n    int eTextRep,\n    void *pArg,\n    int function (void*,int,const void*,int,const void*) xCompare\n);\n/// Ditto\nint sqlite3_create_collation_v2(\n    sqlite3*,\n    const(char)*zName,\n    int eTextRep,\n    void *pArg,\n    int function (void*,int,const void*,int,const void*) xCompare,\n    void function (void*) xDestroy\n);\n/// Ditto\nint sqlite3_create_collation16(\n    sqlite3*,\n    const(void)*zName,\n    int eTextRep,\n    void *pArg,\n    int function (void*,int,const void*,int,const void*) xCompare\n);\n\n/**\n** CAPI3REF: Collation Needed Callbacks\n*/\nint sqlite3_collation_needed(\n    sqlite3*,\n    void*,\n    void function (void*,sqlite3*,int eTextRep,const char*)\n);\n/// Ditto\nint sqlite3_collation_needed16(\n    sqlite3*,\n    void*,\n    void function (void*,sqlite3*,int eTextRep,const void*)\n);\n\n///\nint sqlite3_key(\n    sqlite3 *db,                   /** Database to be rekeyed */\n    const(void)*pKey, int nKey     /** The key */\n);\n/// Ditto\nint sqlite3_key_v2(\n    sqlite3 *db,                   /* Database to be rekeyed */\n    const(char)* zDbName,           /* Name of the database */\n    const(void)* pKey, int nKey     /* The key */\n);\n\n/**\n** Change the key on an open database.  If the current database is not\n** encrypted, this routine will encrypt it.  If pNew == 0 or nNew == 0, the\n** database is decrypted.\n**\n** The code to implement this API is not available in the public release\n** of SQLite.\n*/\nint sqlite3_rekey(\n    sqlite3 *db,                   /** Database to be rekeyed */\n    const(void)*pKey, int nKey     /** The new key */\n);\nint sqlite3_rekey_v2(\n    sqlite3 *db,                   /* Database to be rekeyed */\n    const(char)* zDbName,           /* Name of the database */\n    const(void)* pKey, int nKey     /* The new key */\n);\n\n/**\n** Specify the activation key for a SEE database.  Unless\n** activated, none of the SEE routines will work.\n*/\nvoid sqlite3_activate_see(\n    const(char)*zPassPhrase        /** Activation phrase */\n);\n\n/**\n** Specify the activation key for a CEROD database.  Unless\n** activated, none of the CEROD routines will work.\n*/\nvoid sqlite3_activate_cerod(\n    const(char)*zPassPhrase        /** Activation phrase */\n);\n\n/**\n** CAPI3REF: Suspend Execution For A Short Time\n*/\nint sqlite3_sleep(int);\n\n/**\n** CAPI3REF: Name Of The Folder Holding Temporary Files\n*/\nextern char *sqlite3_temp_directory;\n\n/**\n** CAPI3REF: Name Of The Folder Holding Database Files\n*/\nextern char *sqlite3_data_directory;\n\n/**\n** CAPI3REF: Test For Auto-Commit Mode\n*/\nint sqlite3_get_autocommit(sqlite3*);\n\n/**\n** CAPI3REF: Find The Database Handle Of A Prepared Statement\n*/\nsqlite3 *sqlite3_db_handle(sqlite3_stmt*);\n\n/**\n** CAPI3REF: Return The Filename For A Database Connection\n*/\nconst(char)* sqlite3_db_filename(sqlite3 *db, const char* zDbName);\n\n/**\n** CAPI3REF: Determine if a database is read-only\n*/\nint sqlite3_db_readonly(sqlite3 *db, const char * zDbName);\n\n/*\n** CAPI3REF: Find the next prepared statement\n*/\nsqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);\n\n/**\n** CAPI3REF: Commit And Rollback Notification Callbacks\n*/\nvoid *sqlite3_commit_hook(sqlite3*, int function (void*), void*);\n/// Ditto\nvoid *sqlite3_rollback_hook(sqlite3*, void function (void *), void*);\n\n/**\n** CAPI3REF: Data Change Notification Callbacks\n*/\nvoid *sqlite3_update_hook(\n    sqlite3*,\n    void function (void *,int ,char *, char *, sqlite3_int64),\n    void*\n);\n\n/**\n** CAPI3REF: Enable Or Disable Shared Pager Cache\n*/\nint sqlite3_enable_shared_cache(int);\n\n/**\n** CAPI3REF: Attempt To Free Heap Memory\n*/\nint sqlite3_release_memory(int);\n\n/**\n** CAPI3REF: Free Memory Used By A Database Connection\n*/\nint sqlite3_db_release_memory(sqlite3*);\n\n/*\n** CAPI3REF: Impose A Limit On Heap Size\n*/\nsqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);\n\n/**\n** CAPI3REF: Deprecated Soft Heap Limit Interface\n*/\ndeprecated void sqlite3_soft_heap_limit(int N);\n\n/**\n** CAPI3REF: Extract Metadata About A Column Of A Table\n*/\nint sqlite3_table_column_metadata(\n    sqlite3 *db,                /** Connection handle */\n    const(char)*zDbName,        /** Database name or NULL */\n    const(char)*zTableName,     /** Table name */\n    const(char)*zColumnName,    /** Column name */\n    char **pzDataType,    /** OUTPUT: Declared data type */\n    char **pzCollSeq,     /** OUTPUT: Collation sequence name */\n    int *pNotNull,              /** OUTPUT: True if NOT NULL constraint exists */\n    int *pPrimaryKey,           /** OUTPUT: True if column part of PK */\n    int *pAutoinc               /** OUTPUT: True if column is auto-increment */\n);\n\n/**\n** CAPI3REF: Load An Extension\n*/\nint sqlite3_load_extension(\n    sqlite3 *db,          /** Load the extension into this database connection */\n    const(char)*zFile,    /** Name of the shared library containing extension */\n    const(char)*zProc,    /** Entry point.  Derived from zFile if 0 */\n    char **pzErrMsg       /** Put error message here if not 0 */\n);\n\n/**\n** CAPI3REF: Enable Or Disable Extension Loading\n*/\nint sqlite3_enable_load_extension(sqlite3 *db, int onoff);\n\n/**\n** CAPI3REF: Automatically Load Statically Linked Extensions\n*/\nint sqlite3_auto_extension(void function () xEntryPoint);\n\n/**\n** CAPI3REF: Cancel Automatic Extension Loading\n*/\nint sqlite3_cancel_auto_extension(void function() xEntryPoint);\n\n/**\n** CAPI3REF: Reset Automatic Extension Loading\n*/\nvoid sqlite3_reset_auto_extension();\n\n/**\n** The interface to the virtual-table mechanism is currently considered\n** to be experimental.  The interface might change in incompatible ways.\n** If this is a problem for you, do not use the interface at this time.\n**\n** When the virtual-table mechanism stabilizes, we will declare the\n** interface fixed, support it indefinitely, and remove this comment.\n*/\n\n/**\n** CAPI3REF: Virtual Table Object\n*/\n\nalias mapFunction = void function (sqlite3_context*,int,sqlite3_value**);\n\n/// Ditto\nstruct sqlite3_module\n{\n    int iVersion;\n    int function (sqlite3*, void *pAux,\n               int argc, const char **argv,\n               sqlite3_vtab **ppVTab, char**) xCreate;\n    int function (sqlite3*, void *pAux,\n               int argc, const char **argv,\n               sqlite3_vtab **ppVTab, char**) xConnect;\n    int function (sqlite3_vtab *pVTab, sqlite3_index_info*) xBestIndex;\n    int function (sqlite3_vtab *pVTab) xDisconnect;\n    int function (sqlite3_vtab *pVTab) xDestroy;\n    int function (sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) xOpen;\n    int function (sqlite3_vtab_cursor*) xClose;\n    int function (sqlite3_vtab_cursor*, int idxNum, const char *idxStr,\n                int argc, sqlite3_value **argv) xFilter;\n    int function (sqlite3_vtab_cursor*) xNext;\n    int function (sqlite3_vtab_cursor*) xEof;\n    int function (sqlite3_vtab_cursor*, sqlite3_context*, int) xColumn;\n    int function (sqlite3_vtab_cursor*, sqlite3_int64 *pRowid) xRowid;\n    int function (sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *) xUpdate;\n    int function (sqlite3_vtab *pVTab) xBegin;\n    int function (sqlite3_vtab *pVTab) xSync;\n    int function (sqlite3_vtab *pVTab) xCommit;\n    int function (sqlite3_vtab *pVTab) xRollback;\n    int function (sqlite3_vtab *pVtab, int nArg, const char *zName,\n                       mapFunction*,\n                       void **ppArg) xFindFunction;\n    int function (sqlite3_vtab *pVtab, const char *zNew) xRename;\n    int function (sqlite3_vtab *pVTab, int) xSavepoint;\n    int function (sqlite3_vtab *pVTab, int) xRelease;\n    int function (sqlite3_vtab *pVTab, int) xRollbackTo;\n}\n\n/**\n** CAPI3REF: Virtual Table Indexing Information\n*/\nstruct sqlite3_index_info\n{\n    struct sqlite3_index_constraint\n    {\n        int iColumn;            /** Column on left-hand side of constraint */\n        char op;                /** Constraint operator */\n        char usable;            /** True if this constraint is usable */\n        int iTermOffset;        /** Used internally - xBestIndex should ignore */\n    }\n    struct sqlite3_index_orderby\n    {\n        int iColumn;            /** Column number */\n        char desc;              /** True for DESC.  False for ASC. */\n    }\n    struct sqlite3_index_constraint_usage\n    {\n        int argvIndex;           /** if >0, constraint is part of argv to xFilter */\n        char omit;               /** Do not code a test for this constraint */\n    }\n    /* Inputs */\n    int nConstraint;           /** Number of entries in aConstraint */\n    sqlite3_index_constraint* aConstraint;  /** Table of WHERE clause constraints */\n    int nOrderBy;              /** Number of terms in the ORDER BY clause */\n    sqlite3_index_orderby *aOrderBy; /** The ORDER BY clause */\n    /* Outputs */\n    sqlite3_index_constraint_usage *aConstraintUsage;\n    int idxNum;                /** Number used to identify the index */\n    char *idxStr;              /** String, possibly obtained from sqlite3_malloc */\n    int needToFreeIdxStr;      /** Free idxStr using sqlite3_free() if true */\n    int orderByConsumed;       /** True if output is already ordered */\n    double estimatedCost;      /** Estimated cost of using this index */\n    sqlite3_int64 estimatedRows;\n    int idxFlags;\n    sqlite3_uint64 colUsed;\n}\n\n/**\n** CAPI3REF: Virtual Table Constraint Operator Codes\n*/\nenum\n{\n    SQLITE_INDEX_SCAN_UNIQUE       = 1,\n    SQLITE_INDEX_CONSTRAINT_EQ     = 2,\n    SQLITE_INDEX_CONSTRAINT_GT     = 4,\n    SQLITE_INDEX_CONSTRAINT_LE     = 8,\n    SQLITE_INDEX_CONSTRAINT_LT     = 16,\n    SQLITE_INDEX_CONSTRAINT_GE     = 32,\n    SQLITE_INDEX_CONSTRAINT_MATCH  = 64,\n    SQLITE_INDEX_CONSTRAINT_LIKE   = 65,\n    SQLITE_INDEX_CONSTRAINT_GLOB   = 66,\n    SQLITE_INDEX_CONSTRAINT_REGEXP = 67,\n}\n\n/**\n** CAPI3REF: Register A Virtual Table Implementation\n*/\nint sqlite3_create_module(\n    sqlite3 *db,                    /* SQLite connection to register module with */\n    const(char)*zName,              /* Name of the module */\n    const(sqlite3_module)*p,        /* Methods for the module */\n    void *pClientData               /* Client data for xCreate/xConnect */\n);\n/// Ditto\nint sqlite3_create_module_v2(\n    sqlite3 *db,                    /* SQLite connection to register module with */\n    const(char)*zName,              /* Name of the module */\n    const(sqlite3_module)*p,        /* Methods for the module */\n    void *pClientData,              /* Client data for xCreate/xConnect */\n    void function (void*) xDestroy  /* Module destructor function */\n);\n\n/**\n** CAPI3REF: Virtual Table Instance Object\n*/\nstruct sqlite3_vtab\n{\n    const(sqlite3_module)*pModule;  /** The module for this virtual table */\n    int nRef;                       /** NO LONGER USED */\n    char *zErrMsg;                  /** Error message from sqlite3_mprintf() */\n    /* Virtual table implementations will typically add additional fields */\n}\n\n/**\n** CAPI3REF: Virtual Table Cursor Object\n*/\nstruct sqlite3_vtab_cursor\n{\n    sqlite3_vtab *pVtab;      /** Virtual table of this cursor */\n    /* Virtual table implementations will typically add additional fields */\n}\n\n/**\n** CAPI3REF: Declare The Schema Of A Virtual Table\n*/\nint sqlite3_declare_vtab(sqlite3*, const char *zSQL);\n\n/**\n** CAPI3REF: Overload A Function For A Virtual Table\n*/\nint sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);\n\n/**\n** The interface to the virtual-table mechanism defined above (back up\n** to a comment remarkably similar to this one) is currently considered\n** to be experimental.  The interface might change in incompatible ways.\n** If this is a problem for you, do not use the interface at this time.\n**\n** When the virtual-table mechanism stabilizes, we will declare the\n** interface fixed, support it indefinitely, and remove this comment.\n*/\n\n/*\n** CAPI3REF: A Handle To An Open BLOB\n*/\nstruct sqlite3_blob;\n\n/**\n** CAPI3REF: Open A BLOB For Incremental I/O\n*/\nint sqlite3_blob_open(\n    sqlite3*,\n    const(char)* zDb,\n    const(char)* zTable,\n    const(char)* zColumn,\n    sqlite3_int64 iRow,\n    int flags,\n    sqlite3_blob **ppBlob\n);\n\n/**\n** CAPI3REF: Move a BLOB Handle to a New Row\n*/\nint sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);\n\n/**\n** CAPI3REF: Close A BLOB Handle\n*/\nint sqlite3_blob_close(sqlite3_blob *);\n\n/**\n** CAPI3REF: Return The Size Of An Open BLOB\n*/\nint sqlite3_blob_bytes(sqlite3_blob *);\n\n/**\n** CAPI3REF: Read Data From A BLOB Incrementally\n*/\nint sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);\n\n/**\n** CAPI3REF: Write Data Into A BLOB Incrementally\n*/\nint sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);\n\n/**\n** CAPI3REF: Virtual File System Objects\n*/\nsqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);\n/// Ditto\nint sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);\n/// Ditto\nint sqlite3_vfs_unregister(sqlite3_vfs*);\n\n/**\n** CAPI3REF: Mutexes\n*/\nsqlite3_mutex *sqlite3_mutex_alloc(int);\n/// Ditto\nvoid sqlite3_mutex_free(sqlite3_mutex*);\n/// Ditto\nvoid sqlite3_mutex_enter(sqlite3_mutex*);\n/// Ditto\nint sqlite3_mutex_try(sqlite3_mutex*);\n/// Ditto\nvoid sqlite3_mutex_leave(sqlite3_mutex*);\n\n/**\n** CAPI3REF: Mutex Methods Object\n*/\nstruct sqlite3_mutex_methods\n{\n    int  function () xMutexInit;\n    int  function () xMutexEnd;\n    sqlite3_mutex* function (int) xMutexAlloc;\n    void  function (sqlite3_mutex *) xMutexFree;\n    void  function (sqlite3_mutex *) xMutexEnter;\n    int  function (sqlite3_mutex *) xMutexTry;\n    void  function (sqlite3_mutex *) xMutexLeave;\n    int  function (sqlite3_mutex *) xMutexHeld;\n    int  function (sqlite3_mutex *) xMutexNotheld;\n}\n\n/**\n** CAPI3REF: Mutex Verification Routines\n*/\n\n//#ifndef NDEBUG\nint sqlite3_mutex_held(sqlite3_mutex*);\n/// Ditto\nint sqlite3_mutex_notheld(sqlite3_mutex*);\n//#endif\n\n/**\n** CAPI3REF: Mutex Types\n*/\nenum\n{\n    SQLITE_MUTEX_FAST             = 0,\n    SQLITE_MUTEX_RECURSIVE        = 1,\n    SQLITE_MUTEX_STATIC_MASTER    = 2,\n    SQLITE_MUTEX_STATIC_MEM       = 3,  /** sqlite3_malloc() */\n    SQLITE_MUTEX_STATIC_MEM2      = 4,  /** NOT USED */\n    SQLITE_MUTEX_STATIC_OPEN      = 4,  /** sqlite3BtreeOpen() */\n    SQLITE_MUTEX_STATIC_PRNG      = 5,  /** sqlite3_random() */\n    SQLITE_MUTEX_STATIC_LRU       = 6,  /** lru page list */\n    SQLITE_MUTEX_STATIC_LRU2      = 7,  /** NOT USED */\n    SQLITE_MUTEX_STATIC_PMEM      = 7,  /** sqlite3PageMalloc() */\n    SQLITE_MUTEX_STATIC_APP1      = 8,  /** For use by application */\n    SQLITE_MUTEX_STATIC_APP2      = 9,  /** For use by application */\n    SQLITE_MUTEX_STATIC_APP3      = 10, /** For use by application */\n    SQLITE_MUTEX_STATIC_VFS1      = 11, /** For use by built-in VFS */\n    SQLITE_MUTEX_STATIC_VFS2      = 12, /** For use by extension VFS */\n    SQLITE_MUTEX_STATIC_VFS3      = 13, /** For use by application VFS */\n}\n\n/**\n** CAPI3REF: Retrieve the mutex for a database connection\n*/\nsqlite3_mutex *sqlite3_db_mutex(sqlite3*);\n\n/**\n** CAPI3REF: Low-Level Control Of Database Files\n*/\nint sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);\n\n/**\n** CAPI3REF: Testing Interface\n*/\nint sqlite3_test_control(int op, ...);\n\n/**\n** CAPI3REF: Testing Interface Operation Codes\n*/\nenum\n{\n    SQLITE_TESTCTRL_FIRST                   = 5,\n    SQLITE_TESTCTRL_PRNG_SAVE               = 5,\n    SQLITE_TESTCTRL_PRNG_RESTORE            = 6,\n    SQLITE_TESTCTRL_PRNG_RESET              = 7,\n    SQLITE_TESTCTRL_BITVEC_TEST             = 8,\n    SQLITE_TESTCTRL_FAULT_INSTALL           = 9,\n    SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     = 10,\n    SQLITE_TESTCTRL_PENDING_BYTE            = 11,\n    SQLITE_TESTCTRL_ASSERT                  = 12,\n    SQLITE_TESTCTRL_ALWAYS                  = 13,\n    SQLITE_TESTCTRL_RESERVE                 = 14,\n    SQLITE_TESTCTRL_OPTIMIZATIONS           = 15,\n    SQLITE_TESTCTRL_ISKEYWORD               = 16,\n    SQLITE_TESTCTRL_SCRATCHMALLOC           = 17,\n    SQLITE_TESTCTRL_LOCALTIME_FAULT         = 18,\n    SQLITE_TESTCTRL_EXPLAIN_STMT            = 19,\n    SQLITE_TESTCTRL_NEVER_CORRUPT           = 20,\n    SQLITE_TESTCTRL_VDBE_COVERAGE           = 21,\n    SQLITE_TESTCTRL_BYTEORDER               = 22,\n    SQLITE_TESTCTRL_ISINIT                  = 23,\n    SQLITE_TESTCTRL_SORTER_MMAP             = 24,\n    SQLITE_TESTCTRL_IMPOSTER                = 25,\n    SQLITE_TESTCTRL_LAST                    = 25,\n}\n\n/**\n** CAPI3REF: SQLite Runtime Status\n*/\nint sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);\n/// Ditto\nint  sqlite3_status64(int op, long *pCurrent, long *pHighwater, int resetFlag);\n\n/**\n** CAPI3REF: Status Parameters\n*/\nenum\n{\n    SQLITE_STATUS_MEMORY_USED          = 0,\n    SQLITE_STATUS_PAGECACHE_USED       = 1,\n    SQLITE_STATUS_PAGECACHE_OVERFLOW   = 2,\n    SQLITE_STATUS_SCRATCH_USED         = 3,\n    SQLITE_STATUS_SCRATCH_OVERFLOW     = 4,\n    SQLITE_STATUS_MALLOC_SIZE          = 5,\n    SQLITE_STATUS_PARSER_STACK         = 6,\n    SQLITE_STATUS_PAGECACHE_SIZE       = 7,\n    SQLITE_STATUS_SCRATCH_SIZE         = 8,\n    SQLITE_STATUS_MALLOC_COUNT         = 9\n}\n\n/**\n** CAPI3REF: Database Connection Status\n*/\nint sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);\n\n/**\n** CAPI3REF: Status Parameters for database connections\n*/\nenum\n{\n    SQLITE_DBSTATUS_LOOKASIDE_USED      = 0,\n    SQLITE_DBSTATUS_CACHE_USED          = 1,\n    SQLITE_DBSTATUS_SCHEMA_USED         = 2,\n    SQLITE_DBSTATUS_STMT_USED           = 3,\n    SQLITE_DBSTATUS_LOOKASIDE_HIT       = 4,\n    SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE = 5,\n    SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL = 6,\n    SQLITE_DBSTATUS_CACHE_HIT           = 7,\n    SQLITE_DBSTATUS_CACHE_MISS          = 8,\n    SQLITE_DBSTATUS_CACHE_WRITE         = 9,\n    SQLITE_DBSTATUS_DEFERRED_FKS        = 10,\n    SQLITE_DBSTATUS_MAX                 = 10   /** Largest defined DBSTATUS */\n}\n\n/**\n** CAPI3REF: Prepared Statement Status\n*/\nint sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);\n\n/**\n** CAPI3REF: Status Parameters for prepared statements\n*/\nenum\n{\n    SQLITE_STMTSTATUS_FULLSCAN_STEP     = 1,\n    SQLITE_STMTSTATUS_SORT              = 2,\n    SQLITE_STMTSTATUS_AUTOINDEX         = 3,\n    SQLITE_STMTSTATUS_VM_STEP           = 4\n}\n\n/**\n** CAPI3REF: Custom Page Cache Object\n*/\nstruct sqlite3_pcache;\n\n/**\n** CAPI3REF: Custom Page Cache Object\n*/\nstruct sqlite3_pcache_page\n{\n    void *pBuf;        /* The content of the page */\n    void *pExtra;      /* Extra information associated with the page */\n}\n\n/**\n** CAPI3REF: Application Defined Page Cache.\n*/\nstruct sqlite3_pcache_methods2\n{\n    int iVersion;\n    void *pArg;\n    int function(void*) xInit;\n    void function(void*) xShutdown;\n    sqlite3_pcache * function(int szPage, int szExtra, int bPurgeable) xCreate;\n    void function(sqlite3_pcache*, int nCachesize) xCachesize;\n    int function(sqlite3_pcache*) xPagecount;\n    sqlite3_pcache_page * function(sqlite3_pcache*, uint key, int createFlag) xFetch;\n    void function(sqlite3_pcache*, sqlite3_pcache_page*, int discard) xUnpin;\n    void function(sqlite3_pcache*, sqlite3_pcache_page*,\n     uint oldKey, uint newKey) xRekey;\n    void function(sqlite3_pcache*, uint iLimit) xTruncate;\n    void function(sqlite3_pcache*) xDestroy;\n    void function(sqlite3_pcache*) xShrink;\n}\n\nstruct sqlite3_pcache_methods\n{\n    void *pArg;\n    int  function (void*) xInit;\n    void  function (void*) xShutdown;\n    sqlite3_pcache* function (int szPage, int bPurgeable) xCreate;\n    void  function (sqlite3_pcache*, int nCachesize) xCachesize;\n    int  function (sqlite3_pcache*) xPagecount;\n    void* function (sqlite3_pcache*, uint key, int createFlag) xFetch;\n    void  function (sqlite3_pcache*, void*, int discard) xUnpin;\n    void  function (sqlite3_pcache*, void*, uint oldKey, uint newKey) xRekey;\n    void  function (sqlite3_pcache*, uint iLimit) xTruncate;\n    void  function (sqlite3_pcache*) xDestroy;\n}\n\n/**\n** CAPI3REF: Online Backup Object\n*/\nstruct sqlite3_backup;\n\n/**\n** CAPI3REF: Online Backup API.\n*/\nsqlite3_backup *sqlite3_backup_init(\n    sqlite3 *pDest,                        /** Destination database handle */\n    const(char)*zDestName,                 /** Destination database name */\n    sqlite3 *pSource,                      /** Source database handle */\n    const(char)*zSourceName                /** Source database name */\n);\n/// Ditto\nint sqlite3_backup_step(sqlite3_backup *p, int nPage);\n/// Ditto\nint sqlite3_backup_finish(sqlite3_backup *p);\n/// Ditto\nint sqlite3_backup_remaining(sqlite3_backup *p);\n/// Ditto\nint sqlite3_backup_pagecount(sqlite3_backup *p);\n\n/**\n** CAPI3REF: Unlock Notification\n*/\nint sqlite3_unlock_notify(\n    sqlite3 *pBlocked,                               /** Waiting connection */\n    void function (void **apArg, int nArg) xNotify,  /** Callback function to invoke */\n    void *pNotifyArg                                 /** Argument to pass to xNotify */\n);\n\n/**\n** CAPI3REF: String Comparison\n*/\nint sqlite3_stricmp(const char * , const char * );\nint sqlite3_strnicmp(const char * , const char * , int);\n\n/*\n** CAPI3REF: String Globbing\n*\n*/\nint sqlite3_strglob(const(char)* zGlob, const(char)* zStr);\n\n/*\n** CAPI3REF: String LIKE Matching\n*/\nint sqlite3_strlike(const(char)* zGlob, const(char)* zStr, uint cEsc);\n\n/**\n** CAPI3REF: Error Logging Interface\n*/\nvoid sqlite3_log(int iErrCode, const char *zFormat, ...);\n\n/**\n** CAPI3REF: Write-Ahead Log Commit Hook\n*/\nvoid *sqlite3_wal_hook(\n    sqlite3*,\n    int function (void *,sqlite3*,const char*,int),\n    void*\n);\n\n/**\n** CAPI3REF: Configure an auto-checkpoint\n*/\nint sqlite3_wal_autocheckpoint(sqlite3 *db, int N);\n\n/**\n** CAPI3REF: Checkpoint a database\n*/\nint sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);\n\n/**\n** CAPI3REF: Checkpoint a database\n*/\nint sqlite3_wal_checkpoint_v2(\n    sqlite3 *db,                    /** Database handle */\n    const(char)*zDb,                /** Name of attached database (or NULL) */\n    int eMode,                      /** SQLITE_CHECKPOINT_* value */\n    int *pnLog,                     /** OUT: Size of WAL log in frames */\n    int *pnCkpt                     /** OUT: Total number of frames checkpointed */\n);\n\n/**\n** CAPI3REF: Checkpoint operation parameters\n*/\nenum\n{\n    SQLITE_CHECKPOINT_PASSIVE  = 0,\n    SQLITE_CHECKPOINT_FULL     = 1,\n    SQLITE_CHECKPOINT_RESTART  = 2,\n    SQLITE_CHECKPOINT_TRUNCATE = 3,\n}\n\n/*\n** CAPI3REF: Virtual Table Interface Configuration\n*/\nint sqlite3_vtab_config(sqlite3*, int op, ...);\n\n/**\n** CAPI3REF: Virtual Table Configuration Options\n*/\nenum SQLITE_VTAB_CONSTRAINT_SUPPORT = 1;\n\n/*\n** 2010 August 30\n**\n** The author disclaims copyright to this source code.  In place of\n** a legal notice, here is a blessing:\n**\n**    May you do good and not evil.\n**    May you find forgiveness for yourself and forgive others.\n**    May you share freely, never taking more than you give.\n**\n*************************************************************************\n*/\n\n//#ifndef _SQLITE3RTREE_H_\n//#define _SQLITE3RTREE_H_\n\n\n/*\n** CAPI3REF: Determine The Virtual Table Conflict Policy\n*/\nint sqlite3_vtab_on_conflict(sqlite3 *);\n\n/*\n** CAPI3REF: Conflict resolution modes\n*/\nenum\n{\n    SQLITE_ROLLBACK = 1,\n    SQLITE_FAIL     = 3,\n    SQLITE_REPLACE  = 5\n}\n\n/*\n** CAPI3REF: Prepared Statement Scan Status Opcodes\n*/\nenum\n{\n    SQLITE_SCANSTAT_NLOOP    = 0,\n    SQLITE_SCANSTAT_NVISIT   = 1,\n    SQLITE_SCANSTAT_EST      = 2,\n    SQLITE_SCANSTAT_NAME     = 3,\n    SQLITE_SCANSTAT_EXPLAIN  = 4,\n    SQLITE_SCANSTAT_SELECTID = 5,\n}\n\n/*\n** CAPI3REF: Prepared Statement Scan Status\n*/\nint sqlite3_stmt_scanstatus(sqlite3_stmt *pStmt, int idx, int iScanStatusOp, void *pOut);\n\n/*\n** CAPI3REF: Zero Scan-Status Counters\n*/\nvoid sqlite3_stmt_scanstatus_reset(sqlite3_stmt *);\n\n/*\n** CAPI3REF: Flush caches to disk mid-transaction\n*/\nint sqlite3_db_cacheflush(sqlite3 *);\n\nstruct sqlite3_snapshot;\n\n/*\n** CAPI3REF: Record A Database Snapshot\n*/\nint sqlite3_snapshot_get(sqlite3 *db, char *zSchema, sqlite3_snapshot **ppSnapshot);\n\n/*\n** CAPI3REF: Start a read transaction on an historical snapshot\n*/\nint sqlite3_snapshot_open(sqlite3 *db, char *zSchema, sqlite3_snapshot *pSnapshot);\n\n/*\n** CAPI3REF: Destroy a snapshot\n*/\nvoid sqlite3_snapshot_free(sqlite3_snapshot *);\n\n/**\n** Register a geometry callback named zGeom that can be used as part of an\n** R-Tree geometry query as follows:\n**\n**   SELECT ... FROM $(LT)rtree$(GT) WHERE $(LT)rtree col$(GT) MATCH $zGeom(... params ...)\n*/\nint sqlite3_rtree_geometry_callback(\n    sqlite3 *db,\n    const(char)*zGeom,\n    int function (sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes) xGeom,\n    void *pContext\n);\n\n/**\n** A pointer to a structure of the following type is passed as the first\n** argument to callbacks registered using rtree_geometry_callback().\n*/\nstruct sqlite3_rtree_geometry\n{\n    void *pContext;                   /** Copy of pContext passed to s_r_g_c() */\n    int nParam;                       /** Size of array aParam[] */\n    double *aParam;                   /** Parameters passed to SQL geom function */\n    void *pUser;                      /** Callback implementation user data */\n    void function (void *) xDelUser;  /** Called by SQLite to clean up pUser */\n}\n\nint sqlite3_rtree_query_callback(\n    sqlite3 *db,\n    const(char)* zQueryFunc,\n    int function(sqlite3_rtree_query_info*) xQueryFunc,\n    void *pContext,\n    void function(void*) xDestructor\n);\n\nstruct sqlite3_rtree_query_info\n{\n    void *pContext;                   /* pContext from when function registered */\n    int nParam;                       /* Number of function parameters */\n    double*aParam;        /* value of function parameters */\n    void *pUser;                      /* callback can use this, if desired */\n    void function(void*) xDelUser;          /* function to free pUser */\n    double*aCoord;        /* Coordinates of node or entry to check */\n    uint *anQueue;            /* Number of pending entries in the queue */\n    int nCoord;                       /* Number of coordinates */\n    int iLevel;                       /* Level of current node or entry */\n    int mxLevel;                      /* The largest iLevel value in the tree */\n    sqlite3_int64 iRowid;             /* Rowid for current entry */\n    double rParentScore;   /* Score of parent node */\n    int eParentWithin;                /* Visibility of parent node */\n    int eWithin;                      /* OUT: Visiblity */\n    double rScore;         /* OUT: Write the score here */\n    sqlite3_value **apSqlParam;       /* Original SQL values of parameters */\n}\n\nenum\n{\n    NOT_WITHIN    = 0,\n    PARTLY_WITHIN = 1,\n    FULLY_WITHIN  = 2\n}\n\n/******************************************************************************\n** Interfaces to extend FTS5.\n*/\nstruct Fts5Context;\n/// Ditto\nalias fts5_extension_function = void function(\n    const Fts5ExtensionApi *pApi,\n    Fts5Context *pFts,\n    sqlite3_context *pCtx,\n    int nVal,\n    sqlite3_value **apVal\n);\n/// Ditto\nstruct Fts5PhraseIter\n{\n    const(ubyte) *a;\n    const(ubyte) *b;\n}\n/// Ditto\nstruct Fts5ExtensionApi\n{\n    int iVersion;\n    void* function(Fts5Context*) xUserData;\n    int function(Fts5Context*) xColumnCount;\n    int function(Fts5Context*, sqlite3_int64 *pnRow) xRowCount;\n    int function(Fts5Context*, int iCol, sqlite3_int64 *pnToken) xColumnTotalSize;\n    int function(Fts5Context*,\n        const char *pText, int nText,\n        void *pCtx,\n        int function(void*, int, const char*, int, int, int) xToken\n    ) xTokenize;\n    int function(Fts5Context*) xPhraseCount;\n    int function(Fts5Context*, int iPhrase) xPhraseSize;\n    int function(Fts5Context*, int *pnInst) xInstCount;\n    int function(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff) xInst;\n    sqlite3_int64 function(Fts5Context*) xRowid;\n    int function(Fts5Context*, int iCol, const char **pz, int *pn) xColumnText;\n    int function(Fts5Context*, int iCol, int *pnToken) xColumnSize;\n    int function(Fts5Context*, int iPhrase, void *pUserData,\n        int function(const Fts5ExtensionApi*,Fts5Context*,void*)\n    ) xQueryPhrase;\n    int function(Fts5Context*, void *pAux, void function(void*) xDelete) xSetAuxdata;\n    void* function(Fts5Context*, int bClear) xGetAuxdata;\n    void function(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*) xPhraseFirst;\n    void function(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff) xPhraseNext;\n}\n/// Ditto\nstruct Fts5Tokenizer;\nstruct fts5_tokenizer\n{\n    int function(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut) xCreate;\n    void function(Fts5Tokenizer*) xDelete;\n    int function(Fts5Tokenizer*,\n        void *pCtx,\n        int flags,\n        const char *pText, int nText,\n        int function(\n            void *pCtx,\n            int tflags,\n            const char *pToken,\n            int nToken,\n            int iStart,\n            int iEnd\n        ) xToken\n    ) xTokenize;\n}\n/// Ditto\nenum FTS5_TOKENIZE_QUERY     = 0x0001;\n/// Ditto\nenum FTS5_TOKENIZE_PREFIX    = 0x0002;\n/// Ditto\nenum FTS5_TOKENIZE_DOCUMENT  = 0x0004;\n/// Ditto\nenum FTS5_TOKENIZE_AUX       = 0x0008;\n/// Ditto\nenum FTS5_TOKEN_COLOCATED    = 0x0001;\n/// Ditto\nstruct fts5_api\n{\n    int iVersion;\n\n    int function(\n        fts5_api *pApi,\n        const char *zName,\n        void *pContext,\n        fts5_tokenizer *pTokenizer,\n        void function(void*) xDestroy\n    ) xCreateTokenizer;\n\n    int function(\n        fts5_api *pApi,\n        const char *zName,\n        void **ppContext,\n        fts5_tokenizer *pTokenizer\n    ) xFindTokenizer;\n\n    int function(\n        fts5_api *pApi,\n        const char *zName,\n        void *pContext,\n        fts5_extension_function xFunction,\n        void function(void*) xDestroy\n    ) xCreateFunction;\n}\n"
  },
  {
    "path": "libphobos/src/etc/c/zlib.d",
    "content": "/* zlib.d: modified from zlib.h by Walter Bright */\n/* updated from 1.2.1 to 1.2.3 by Thomas Kuehne */\n/* updated from 1.2.3 to 1.2.8 by Dmitry Atamanov */\n/* updated from 1.2.8 to 1.2.11 by Iain Buclaw */\n\nmodule etc.c.zlib;\n\nimport core.stdc.config;\n\n/* zlib.h -- interface of the 'zlib' general purpose compression library\n  version 1.2.11, January 15th, 2017\n\n  Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Jean-loup Gailly        Mark Adler\n  jloup@gzip.org          madler@alumni.caltech.edu\n\n\n  The data format used by the zlib library is described by RFCs (Request for\n  Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950\n  (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).\n*/\n\nnothrow:\nextern (C):\n\n// Those are extern(D) as they should be mangled\nextern(D) immutable string ZLIB_VERSION = \"1.2.11\";\nextern(D) immutable ZLIB_VERNUM = 0x12b0;\n\n/*\n    The 'zlib' compression library provides in-memory compression and\n  decompression functions, including integrity checks of the uncompressed data.\n  This version of the library supports only one compression method (deflation)\n  but other algorithms will be added later and will have the same stream\n  interface.\n\n    Compression can be done in a single step if the buffers are large enough,\n  or can be done by repeated calls of the compression function.  In the latter\n  case, the application must provide more input and/or consume the output\n  (providing more output space) before each call.\n\n    The compressed data format used by default by the in-memory functions is\n  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped\n  around a deflate stream, which is itself documented in RFC 1951.\n\n    The library also supports reading and writing files in gzip (.gz) format\n  with an interface similar to that of stdio using the functions that start\n  with \"gz\".  The gzip format is different from the zlib format.  gzip is a\n  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.\n\n    This library can optionally read and write gzip and raw deflate streams in\n  memory as well.\n\n    The zlib format was designed to be compact and fast for use in memory\n  and on communications channels.  The gzip format was designed for single-\n  file compression on file systems, has a larger header than zlib to maintain\n  directory information, and uses a different, slower check method than zlib.\n\n    The library does not install any signal handler.  The decoder checks\n  the consistency of the compressed data, so the library should never crash\n  even in the case of corrupted input.\n*/\n\nalias alloc_func = void* function (void* opaque, uint items, uint size);\nalias free_func = void  function (void* opaque, void* address);\n\nstruct z_stream\n{\n    const(ubyte)*   next_in;  /* next input byte */\n    uint     avail_in;  /* number of bytes available at next_in */\n    c_ulong  total_in;  /* total nb of input bytes read so far */\n\n    ubyte*   next_out;  /* next output byte will go here */\n    uint     avail_out; /* remaining free space at next_out */\n    c_ulong  total_out; /* total nb of bytes output so far */\n\n    const(char)*    msg;      /* last error message, NULL if no error */\n    void*    state;     /* not visible by applications */\n\n    alloc_func zalloc;  /* used to allocate the internal state */\n    free_func  zfree;   /* used to free the internal state */\n    void*      opaque;  /* private data object passed to zalloc and zfree */\n\n    int     data_type;  /* best guess about the data type: binary or text\n                           for deflate, or the decoding state for inflate */\n    c_ulong adler;      /* Adler-32 or CRC-32 value of the uncompressed data */\n    c_ulong reserved;   /* reserved for future use */\n}\n\nalias z_streamp = z_stream*;\n\n/*\n     gzip header information passed to and from zlib routines.  See RFC 1952\n  for more details on the meanings of these fields.\n*/\nstruct gz_header\n{\n    int     text;       /* true if compressed data believed to be text */\n    c_ulong time;       /* modification time */\n    int     xflags;     /* extra flags (not used when writing a gzip file) */\n    int     os;         /* operating system */\n    byte    *extra;     /* pointer to extra field or Z_NULL if none */\n    uint    extra_len;  /* extra field length (valid if extra != Z_NULL) */\n    uint    extra_max;  /* space at extra (only when reading header) */\n    byte*   name;      /* pointer to zero-terminated file name or Z_NULL */\n    uint    name_max;   /* space at name (only when reading header) */\n    byte*   comment;   /* pointer to zero-terminated comment or Z_NULL */\n    uint    comm_max;   /* space at comment (only when reading header) */\n    int     hcrc;       /* true if there was or will be a header crc */\n    int     done;       /* true when done reading gzip header (not used\n                           when writing a gzip file) */\n}\n\nalias gz_headerp = gz_header*;\n\n/*\n     The application must update next_in and avail_in when avail_in has dropped\n   to zero.  It must update next_out and avail_out when avail_out has dropped\n   to zero.  The application must initialize zalloc, zfree and opaque before\n   calling the init function.  All other fields are set by the compression\n   library and must not be updated by the application.\n\n     The opaque value provided by the application will be passed as the first\n   parameter for calls of zalloc and zfree.  This can be useful for custom\n   memory management.  The compression library attaches no meaning to the\n   opaque value.\n\n     zalloc must return Z_NULL if there is not enough memory for the object.\n   If zlib is used in a multi-threaded application, zalloc and zfree must be\n   thread safe.  In that case, zlib is thread-safe.  When zalloc and zfree are\n   Z_NULL on entry to the initialization function, they are set to internal\n   routines that use the standard library functions malloc() and free().\n\n     On 16-bit systems, the functions zalloc and zfree must be able to allocate\n   exactly 65536 bytes, but will not be required to allocate more than this if\n   the symbol MAXSEG_64K is defined (see zconf.h).  WARNING: On MSDOS, pointers\n   returned by zalloc for objects of exactly 65536 bytes *must* have their\n   offset normalized to zero.  The default allocation function provided by this\n   library ensures this (see zutil.c).  To reduce memory requirements and avoid\n   any allocation of 64K objects, at the expense of compression ratio, compile\n   the library with -DMAX_WBITS=14 (see zconf.h).\n\n     The fields total_in and total_out can be used for statistics or progress\n   reports.  After compression, total_in holds the total size of the\n   uncompressed data and may be saved for use by the decompressor (particularly\n   if the decompressor wants to decompress everything in a single step).\n*/\n\n                        /* constants */\n\nenum\n{\n        Z_NO_FLUSH      = 0,\n        Z_PARTIAL_FLUSH = 1, /* will be removed, use Z_SYNC_FLUSH instead */\n        Z_SYNC_FLUSH    = 2,\n        Z_FULL_FLUSH    = 3,\n        Z_FINISH        = 4,\n        Z_BLOCK         = 5,\n        Z_TREES         = 6,\n}\n/* Allowed flush values; see deflate() and inflate() below for details */\n\nenum\n{\n        Z_OK            = 0,\n        Z_STREAM_END    = 1,\n        Z_NEED_DICT     = 2,\n        Z_ERRNO         = -1,\n        Z_STREAM_ERROR  = -2,\n        Z_DATA_ERROR    = -3,\n        Z_MEM_ERROR     = -4,\n        Z_BUF_ERROR     = -5,\n        Z_VERSION_ERROR = -6,\n}\n/* Return codes for the compression/decompression functions. Negative\n * values are errors, positive values are used for special but normal events.\n */\n\nenum\n{\n        Z_NO_COMPRESSION         = 0,\n        Z_BEST_SPEED             = 1,\n        Z_BEST_COMPRESSION       = 9,\n        Z_DEFAULT_COMPRESSION    = -1,\n}\n/* compression levels */\n\nenum\n{\n        Z_FILTERED            = 1,\n        Z_HUFFMAN_ONLY        = 2,\n        Z_RLE                 = 3,\n        Z_FIXED               = 4,\n        Z_DEFAULT_STRATEGY    = 0,\n}\n/* compression strategy; see deflateInit2() below for details */\n\nenum\n{\n        Z_BINARY   = 0,\n        Z_TEXT     = 1,\n        Z_UNKNOWN  = 2,\n\n        Z_ASCII    = Z_TEXT\n}\n/* Possible values of the data_type field for deflate() */\n\nenum\n{\n        Z_DEFLATED   = 8,\n}\n/* The deflate compression method (the only one supported in this version) */\n\n/// for initializing zalloc, zfree, opaque (extern(D) for mangling)\nextern(D) immutable void* Z_NULL = null;\n\n                        /* basic functions */\n\nconst(char)* zlibVersion();\n/* The application can compare zlibVersion and ZLIB_VERSION for consistency.\n   If the first character differs, the library code actually used is not\n   compatible with the zlib.h header file used by the application.  This check\n   is automatically made by deflateInit and inflateInit.\n */\n\nint deflateInit(z_streamp strm, int level)\n{\n    return deflateInit_(strm, level, ZLIB_VERSION.ptr, z_stream.sizeof);\n}\n/*\n     Initializes the internal stream state for compression.  The fields\n   zalloc, zfree and opaque must be initialized before by the caller.  If\n   zalloc and zfree are set to Z_NULL, deflateInit updates them to use default\n   allocation functions.\n\n     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:\n   1 gives best speed, 9 gives best compression, 0 gives no compression at all\n   (the input data is simply copied a block at a time).  Z_DEFAULT_COMPRESSION\n   requests a default compromise between speed and compression (currently\n   equivalent to level 6).\n\n     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_STREAM_ERROR if level is not a valid compression level, or\n   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible\n   with the version assumed by the caller (ZLIB_VERSION).  msg is set to null\n   if there is no error message.  deflateInit does not perform any compression:\n   this will be done by deflate().\n*/\n\n\nint deflate(z_streamp strm, int flush);\n/*\n    deflate compresses as much data as possible, and stops when the input\n  buffer becomes empty or the output buffer becomes full.  It may introduce\n  some output latency (reading input without producing any output) except when\n  forced to flush.\n\n    The detailed semantics are as follows.  deflate performs one or both of the\n  following actions:\n\n  - Compress more input starting at next_in and update next_in and avail_in\n    accordingly.  If not all input can be processed (because there is not\n    enough room in the output buffer), next_in and avail_in are updated and\n    processing will resume at this point for the next call of deflate().\n\n  - Generate more output starting at next_out and update next_out and avail_out\n    accordingly.  This action is forced if the parameter flush is non zero.\n    Forcing flush frequently degrades the compression ratio, so this parameter\n    should be set only when necessary.  Some output may be provided even if\n    flush is zero.\n\n    Before the call of deflate(), the application should ensure that at least\n  one of the actions is possible, by providing more input and/or consuming more\n  output, and updating avail_in or avail_out accordingly; avail_out should\n  never be zero before the call.  The application can consume the compressed\n  output when it wants, for example when the output buffer is full (avail_out\n  == 0), or after each call of deflate().  If deflate returns Z_OK and with\n  zero avail_out, it must be called again after making room in the output\n  buffer because there might be more output pending. See deflatePending(),\n  which can be used if desired to determine whether or not there is more ouput\n  in that case.\n\n    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to\n  decide how much data to accumulate before producing output, in order to\n  maximize compression.\n\n    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is\n  flushed to the output buffer and the output is aligned on a byte boundary, so\n  that the decompressor can get all input data available so far.  (In\n  particular avail_in is zero after the call if enough output space has been\n  provided before the call.) Flushing may degrade compression for some\n  compression algorithms and so it should be used only when necessary.  This\n  completes the current deflate block and follows it with an empty stored block\n  that is three bits plus filler bits to the next byte, followed by four bytes\n  (00 00 ff ff).\n\n    If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the\n  output buffer, but the output is not aligned to a byte boundary.  All of the\n  input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.\n  This completes the current deflate block and follows it with an empty fixed\n  codes block that is 10 bits long.  This assures that enough bytes are output\n  in order for the decompressor to finish the block before the empty fixed\n  codes block.\n\n    If flush is set to Z_BLOCK, a deflate block is completed and emitted, as\n  for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to\n  seven bits of the current block are held to be written as the next byte after\n  the next deflate block is completed.  In this case, the decompressor may not\n  be provided enough bits at this point in order to complete decompression of\n  the data provided so far to the compressor.  It may need to wait for the next\n  block to be emitted.  This is for advanced applications that need to control\n  the emission of deflate blocks.\n\n    If flush is set to Z_FULL_FLUSH, all output is flushed as with\n  Z_SYNC_FLUSH, and the compression state is reset so that decompression can\n  restart from this point if previous compressed data has been damaged or if\n  random access is desired.  Using Z_FULL_FLUSH too often can seriously degrade\n  compression.\n\n    If deflate returns with avail_out == 0, this function must be called again\n  with the same value of the flush parameter and more output space (updated\n  avail_out), until the flush is complete (deflate returns with non-zero\n  avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that\n  avail_out is greater than six to avoid repeated flush markers due to\n  avail_out == 0 on return.\n\n    If the parameter flush is set to Z_FINISH, pending input is processed,\n  pending output is flushed and deflate returns with Z_STREAM_END if there was\n  enough output space.  If deflate returns with Z_OK or Z_BUF_ERROR, this\n  function must be called again with Z_FINISH and more output space (updated\n  avail_out) but no more input data, until it returns with Z_STREAM_END or an\n  error.  After deflate has returned Z_STREAM_END, the only possible operations\n  on the stream are deflateReset or deflateEnd.\n\n    Z_FINISH can be used in the first deflate call after deflateInit if all the\n  compression is to be done in a single step.  In order to complete in one\n  call, avail_out must be at least the value returned by deflateBound (see\n  below).  Then deflate is guaranteed to return Z_STREAM_END.  If not enough\n  output space is provided, deflate will not return Z_STREAM_END, and it must\n  be called again as described above.\n\n    deflate() sets strm->adler to the Adler-32 checksum of all input read\n  so far (that is, total_in bytes).  If a gzip stream is being generated, then\n  strm->adler will be the CRC-32 checksum of the input read so far.  (See\n  deflateInit2 below.)\n\n    deflate() may update strm->data_type if it can make a good guess about\n  the input data type (Z_BINARY or Z_TEXT).  If in doubt, the data is\n  considered binary.  This field is only for information purposes and does not\n  affect the compression algorithm in any manner.\n\n    deflate() returns Z_OK if some progress has been made (more input\n  processed or more output produced), Z_STREAM_END if all input has been\n  consumed and all output has been produced (only when flush is set to\n  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example\n  if next_in or next_out was Z_NULL or the state was inadvertently written over\n  by the application), or Z_BUF_ERROR if no progress is possible (for example\n  avail_in or avail_out was zero).  Note that Z_BUF_ERROR is not fatal, and\n  deflate() can be called again with more input and more output space to\n  continue compressing.\n*/\n\n\nint deflateEnd(z_streamp strm);\n/*\n     All dynamically allocated data structures for this stream are freed.\n   This function discards any unprocessed input and does not flush any pending\n   output.\n\n     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the\n   stream state was inconsistent, Z_DATA_ERROR if the stream was freed\n   prematurely (some input or output was discarded).  In the error case, msg\n   may be set but then points to a static string (which must not be\n   deallocated).\n*/\n\n\nint inflateInit(z_streamp strm)\n{\n    return inflateInit_(strm, ZLIB_VERSION.ptr, z_stream.sizeof);\n}\n/*\n     Initializes the internal stream state for decompression.  The fields\n   next_in, avail_in, zalloc, zfree and opaque must be initialized before by\n   the caller.  In the current version of inflate, the provided input is not\n   read or consumed.  The allocation of a sliding window will be deferred to\n   the first call of inflate (if the decompression does not complete on the\n   first call).  If zalloc and zfree are set to Z_NULL, inflateInit updates\n   them to use default allocation functions.\n\n     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the\n   version assumed by the caller, or Z_STREAM_ERROR if the parameters are\n   invalid, such as a null pointer to the structure.  msg is set to null if\n   there is no error message.  inflateInit does not perform any decompression.\n   Actual decompression will be done by inflate().  So next_in, and avail_in,\n   next_out, and avail_out are unused and unchanged.  The current\n   implementation of inflateInit() does not process any header information --\n   that is deferred until inflate() is called.\n*/\n\n\nint inflate(z_streamp strm, int flush);\n/*\n    inflate decompresses as much data as possible, and stops when the input\n  buffer becomes empty or the output buffer becomes full.  It may introduce\n  some output latency (reading input without producing any output) except when\n  forced to flush.\n\n  The detailed semantics are as follows.  inflate performs one or both of the\n  following actions:\n\n  - Decompress more input starting at next_in and update next_in and avail_in\n    accordingly.  If not all input can be processed (because there is not\n    enough room in the output buffer), then next_in and avail_in are updated\n    accordingly, and processing will resume at this point for the next call of\n    inflate().\n\n  - Generate more output starting at next_out and update next_out and avail_out\n    accordingly.  inflate() provides as much output as possible, until there is\n    no more input data or no more space in the output buffer (see below about\n    the flush parameter).\n\n    Before the call of inflate(), the application should ensure that at least\n  one of the actions is possible, by providing more input and/or consuming more\n  output, and updating the next_* and avail_* values accordingly.  If the\n  caller of inflate() does not provide both available input and available\n  output space, it is possible that there will be no progress made.  The\n  application can consume the uncompressed output when it wants, for example\n  when the output buffer is full (avail_out == 0), or after each call of\n  inflate().  If inflate returns Z_OK and with zero avail_out, it must be\n  called again after making room in the output buffer because there might be\n  more output pending.\n\n    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,\n  Z_BLOCK, or Z_TREES.  Z_SYNC_FLUSH requests that inflate() flush as much\n  output as possible to the output buffer.  Z_BLOCK requests that inflate()\n  stop if and when it gets to the next deflate block boundary.  When decoding\n  the zlib or gzip format, this will cause inflate() to return immediately\n  after the header and before the first block.  When doing a raw inflate,\n  inflate() will go ahead and process the first block, and will return when it\n  gets to the end of that block, or when it runs out of data.\n\n    The Z_BLOCK option assists in appending to or combining deflate streams.\n  To assist in this, on return inflate() always sets strm->data_type to the\n  number of unused bits in the last byte taken from strm->next_in, plus 64 if\n  inflate() is currently decoding the last block in the deflate stream, plus\n  128 if inflate() returned immediately after decoding an end-of-block code or\n  decoding the complete header up to just before the first byte of the deflate\n  stream.  The end-of-block will not be indicated until all of the uncompressed\n  data from that block has been written to strm->next_out.  The number of\n  unused bits may in general be greater than seven, except when bit 7 of\n  data_type is set, in which case the number of unused bits will be less than\n  eight.  data_type is set as noted here every time inflate() returns for all\n  flush options, and so can be used to determine the amount of currently\n  consumed input in bits.\n\n    The Z_TREES option behaves as Z_BLOCK does, but it also returns when the\n  end of each deflate block header is reached, before any actual data in that\n  block is decoded.  This allows the caller to determine the length of the\n  deflate block header for later use in random access within a deflate block.\n  256 is added to the value of strm->data_type when inflate() returns\n  immediately after reaching the end of the deflate block header.\n\n    inflate() should normally be called until it returns Z_STREAM_END or an\n  error.  However if all decompression is to be performed in a single step (a\n  single call of inflate), the parameter flush should be set to Z_FINISH.  In\n  this case all pending input is processed and all pending output is flushed;\n  avail_out must be large enough to hold all of the uncompressed data for the\n  operation to complete.  (The size of the uncompressed data may have been\n  saved by the compressor for this purpose.)  The use of Z_FINISH is not\n  required to perform an inflation in one step.  However it may be used to\n  inform inflate that a faster approach can be used for the single inflate()\n  call.  Z_FINISH also informs inflate to not maintain a sliding window if the\n  stream completes, which reduces inflate's memory footprint.  If the stream\n  does not complete, either because not all of the stream is provided or not\n  enough output space is provided, then a sliding window will be allocated and\n  inflate() can be called again to continue the operation as if Z_NO_FLUSH had\n  been used.\n\n     In this implementation, inflate() always flushes as much output as\n  possible to the output buffer, and always uses the faster approach on the\n  first call.  So the effects of the flush parameter in this implementation are\n  on the return value of inflate() as noted below, when inflate() returns early\n  when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of\n  memory for a sliding window when Z_FINISH is used.\n\n     If a preset dictionary is needed after this call (see inflateSetDictionary\n  below), inflate sets strm->adler to the Adler-32 checksum of the dictionary\n  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets\n  strm->adler to the Adler-32 checksum of all output produced so far (that is,\n  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described\n  below.  At the end of the stream, inflate() checks that its computed Adler-32\n  checksum is equal to that saved by the compressor and returns Z_STREAM_END\n  only if the checksum is correct.\n\n    inflate() can decompress and check either zlib-wrapped or gzip-wrapped\n  deflate data.  The header type is detected automatically, if requested when\n  initializing with inflateInit2().  Any information contained in the gzip\n  header is not retained unless inflateGetHeader() is used.  When processing\n  gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output\n  produced so far.  The CRC-32 is checked against the gzip trailer, as is the\n  uncompressed length, modulo 2^32.\n\n    inflate() returns Z_OK if some progress has been made (more input processed\n  or more output produced), Z_STREAM_END if the end of the compressed data has\n  been reached and all uncompressed output has been produced, Z_NEED_DICT if a\n  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was\n  corrupted (input stream not conforming to the zlib format or incorrect check\n  value, in which case strm->msg points to a string with a more specific\n  error), Z_STREAM_ERROR if the stream structure was inconsistent (for example\n  next_in or next_out was Z_NULL, or the state was inadvertently written over\n  by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR\n  if no progress was possible or if there was not enough room in the output\n  buffer when Z_FINISH is used.  Note that Z_BUF_ERROR is not fatal, and\n  inflate() can be called again with more input and more output space to\n  continue decompressing.  If Z_DATA_ERROR is returned, the application may\n  then call inflateSync() to look for a good compression block if a partial\n  recovery of the data is to be attempted.\n*/\n\n\nint inflateEnd(z_streamp strm);\n/*\n     All dynamically allocated data structures for this stream are freed.\n   This function discards any unprocessed input and does not flush any pending\n   output.\n\n     inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state\n   was inconsistent.\n*/\n\n                        /* Advanced functions */\n\n/*\n    The following functions are needed only in some special applications.\n*/\n\nint deflateInit2(z_streamp strm,\n                 int  level,\n                 int  method,\n                 int  windowBits,\n                 int  memLevel,\n                 int  strategy)\n{\n    return deflateInit2_(strm, level, method, windowBits, memLevel,\n                         strategy, ZLIB_VERSION.ptr, z_stream.sizeof);\n}\n/*\n     This is another version of deflateInit with more compression options.  The\n   fields next_in, zalloc, zfree and opaque must be initialized before by the\n   caller.\n\n     The method parameter is the compression method.  It must be Z_DEFLATED in\n   this version of the library.\n\n     The windowBits parameter is the base two logarithm of the window size\n   (the size of the history buffer).  It should be in the range 8 .. 15 for this\n   version of the library.  Larger values of this parameter result in better\n   compression at the expense of memory usage.  The default value is 15 if\n   deflateInit is used instead.\n\n     For the current implementation of deflate(), a windowBits value of 8 (a\n   window size of 256 bytes) is not supported.  As a result, a request for 8\n   will result in 9 (a 512-byte window).  In that case, providing 8 to\n   inflateInit2() will result in an error when the zlib header with 9 is\n   checked against the initialization of inflate().  The remedy is to not use 8\n   with deflateInit2() with this initialization, or at least in that case use 9\n   with inflateInit2().\n\n     windowBits can also be -8..-15 for raw deflate.  In this case, -windowBits\n   determines the window size.  deflate() will then generate raw deflate data\n   with no zlib header or trailer, and will not compute a check value.\n\n     windowBits can also be greater than 15 for optional gzip encoding.  Add\n   16 to windowBits to write a simple gzip header and trailer around the\n   compressed data instead of a zlib wrapper.  The gzip header will have no\n   file name, no extra data, no comment, no modification time (set to zero), no\n   header crc, and the operating system will be set to the appropriate value,\n   if the operating system was determined at compile time.  If a gzip stream is\n   being written, strm->adler is a CRC-32 instead of an Adler-32.\n\n     For raw deflate or gzip encoding, a request for a 256-byte window is\n   rejected as invalid, since only the zlib header provides a means of\n   transmitting the window size to the decompressor.\n\n     The memLevel parameter specifies how much memory should be allocated\n   for the internal compression state.  memLevel=1 uses minimum memory but is\n   slow and reduces compression ratio; memLevel=9 uses maximum memory for\n   optimal speed.  The default value is 8.  See zconf.h for total memory usage\n   as a function of windowBits and memLevel.\n\n     The strategy parameter is used to tune the compression algorithm.  Use the\n   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a\n   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no\n   string match), or Z_RLE to limit match distances to one (run-length\n   encoding).  Filtered data consists mostly of small values with a somewhat\n   random distribution.  In this case, the compression algorithm is tuned to\n   compress them better.  The effect of Z_FILTERED is to force more Huffman\n   coding and less string matching; it is somewhat intermediate between\n   Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY.  Z_RLE is designed to be almost as\n   fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data.  The\n   strategy parameter only affects the compression ratio but not the\n   correctness of the compressed output even if it is not set appropriately.\n   Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler\n   decoder for special applications.\n\n     deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid\n   method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is\n   incompatible with the version assumed by the caller (ZLIB_VERSION).  msg is\n   set to null if there is no error message.  deflateInit2 does not perform any\n   compression: this will be done by deflate().\n*/\n\nint deflateSetDictionary(z_streamp strm, const(ubyte)* dictionary, uint  dictLength);\n/*\n     Initializes the compression dictionary from the given byte sequence\n   without producing any compressed output.  When using the zlib format, this\n   function must be called immediately after deflateInit, deflateInit2 or\n   deflateReset, and before any call of deflate.  When doing raw deflate, this\n   function must be called either before any call of deflate, or immediately\n   after the completion of a deflate block, i.e. after all input has been\n   consumed and all output has been delivered when using any of the flush\n   options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH.  The\n   compressor and decompressor must use exactly the same dictionary (see\n   inflateSetDictionary).\n\n     The dictionary should consist of strings (byte sequences) that are likely\n   to be encountered later in the data to be compressed, with the most commonly\n   used strings preferably put towards the end of the dictionary.  Using a\n   dictionary is most useful when the data to be compressed is short and can be\n   predicted with good accuracy; the data can then be compressed better than\n   with the default empty dictionary.\n\n     Depending on the size of the compression data structures selected by\n   deflateInit or deflateInit2, a part of the dictionary may in effect be\n   discarded, for example if the dictionary is larger than the window size\n   provided in deflateInit or deflateInit2.  Thus the strings most likely to be\n   useful should be put at the end of the dictionary, not at the front.  In\n   addition, the current implementation of deflate will use at most the window\n   size minus 262 bytes of the provided dictionary.\n\n     Upon return of this function, strm->adler is set to the Adler-32 value\n   of the dictionary; the decompressor may later use this value to determine\n   which dictionary has been used by the compressor.  (The Adler-32 value\n   applies to the whole dictionary even if only a subset of the dictionary is\n   actually used by the compressor.) If a raw deflate was requested, then the\n   Adler-32 value is not computed and strm->adler is not set.\n\n     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a\n   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is\n   inconsistent (for example if deflate has already been called for this stream\n   or if not at a block boundary for raw deflate).  deflateSetDictionary does\n   not perform any compression: this will be done by deflate().\n*/\n\nint deflateGetDictionary(z_streamp strm, ubyte *dictionary, uint  dictLength);\n/*\n     Returns the sliding dictionary being maintained by deflate.  dictLength is\n   set to the number of bytes in the dictionary, and that many bytes are copied\n   to dictionary.  dictionary must have enough space, where 32768 bytes is\n   always enough.  If deflateGetDictionary() is called with dictionary equal to\n   Z_NULL, then only the dictionary length is returned, and nothing is copied.\n   Similary, if dictLength is Z_NULL, then it is not set.\n\n     deflateGetDictionary() may return a length less than the window size, even\n   when more than the window size in input has been provided. It may return up\n   to 258 bytes less in that case, due to how zlib's implementation of deflate\n   manages the sliding window and lookahead for matches, where matches can be\n   up to 258 bytes long. If the application needs the last window-size bytes of\n   input, then that would need to be saved by the application outside of zlib.\n\n     deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the\n   stream state is inconsistent.\n*/\n\nint deflateCopy(z_streamp dest, z_streamp source);\n/*\n     Sets the destination stream as a complete copy of the source stream.\n\n     This function can be useful when several compression strategies will be\n   tried, for example when there are several ways of pre-processing the input\n   data with a filter.  The streams that will be discarded should then be freed\n   by calling deflateEnd.  Note that deflateCopy duplicates the internal\n   compression state which can be quite large, so this strategy is slow and can\n   consume lots of memory.\n\n     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent\n   (such as zalloc being Z_NULL).  msg is left unchanged in both source and\n   destination.\n*/\n\nint deflateReset(z_streamp strm);\n/*\n     This function is equivalent to deflateEnd followed by deflateInit, but\n   does not free and reallocate the internal compression state.  The stream\n   will leave the compression level and any other attributes that may have been\n   set unchanged.\n\n     deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent (such as zalloc or state being Z_NULL).\n*/\n\nint deflateParams(z_streamp strm, int level, int strategy);\n/*\n     Dynamically update the compression level and compression strategy.  The\n   interpretation of level and strategy is as in deflateInit2().  This can be\n   used to switch between compression and straight copy of the input data, or\n   to switch to a different kind of input data requiring a different strategy.\n   If the compression approach (which is a function of the level) or the\n   strategy is changed, and if any input has been consumed in a previous\n   deflate() call, then the input available so far is compressed with the old\n   level and strategy using deflate(strm, Z_BLOCK).  There are three approaches\n   for the compression levels 0, 1 .. 3, and 4 .. 9 respectively.  The new level\n   and strategy will take effect at the next call of deflate().\n\n     If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does\n   not have enough output space to complete, then the parameter change will not\n   take effect.  In this case, deflateParams() can be called again with the\n   same parameters and more output space to try again.\n\n     In order to assure a change in the parameters on the first try, the\n   deflate stream should be flushed using deflate() with Z_BLOCK or other flush\n   request until strm.avail_out is not zero, before calling deflateParams().\n   Then no more input data should be provided before the deflateParams() call.\n   If this is done, the old level and strategy will be applied to the data\n   compressed before deflateParams(), and the new level and strategy will be\n   applied to the the data compressed after deflateParams().\n\n     deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream\n   state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if\n   there was not enough output space to complete the compression of the\n   available input data before a change in the strategy or approach.  Note that\n   in the case of a Z_BUF_ERROR, the parameters are not changed.  A return\n   value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be\n   retried with more output space.\n*/\n\nint deflateTune(z_streamp strm, int good_length, int max_lazy, int nice_length,\n        int max_chain);\n/*\n     Fine tune deflate's internal compression parameters.  This should only be\n   used by someone who understands the algorithm used by zlib's deflate for\n   searching for the best matching string, and even then only by the most\n   fanatic optimizer trying to squeeze out the last compressed bit for their\n   specific input data.  Read the deflate.c source code for the meaning of the\n   max_lazy, good_length, nice_length, and max_chain parameters.\n\n     deflateTune() can be called after deflateInit() or deflateInit2(), and\n   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.\n */\n\nsize_t deflateBound(z_streamp strm, size_t sourceLen);\n/*\n     deflateBound() returns an upper bound on the compressed size after\n   deflation of sourceLen bytes.  It must be called after deflateInit() or\n   deflateInit2(), and after deflateSetHeader(), if used.  This would be used\n   to allocate an output buffer for deflation in a single pass, and so would be\n   called before deflate().  If that first deflate() call is provided the\n   sourceLen input bytes, an output buffer allocated to the size returned by\n   deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed\n   to return Z_STREAM_END.  Note that it is possible for the compressed size to\n   be larger than the value returned by deflateBound() if flush options other\n   than Z_FINISH or Z_NO_FLUSH are used.\n*/\n\nint deflatePending(z_streamp strm, uint* pending, int* bits);\n/*\n     deflatePending() returns the number of bytes and bits of output that have\n   been generated, but not yet provided in the available output.  The bytes not\n   provided would be due to the available output space having being consumed.\n   The number of bits of output not provided are between 0 and 7, where they\n   await more bits to join them in order to fill out a full byte.  If pending\n   or bits are Z_NULL, then those values are not set.\n\n     deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.\n */\n\nint deflatePrime(z_streamp strm, int bits, int value);\n/*\n     deflatePrime() inserts bits in the deflate output stream.  The intent\n   is that this function is used to start off the deflate output with the bits\n   leftover from a previous deflate stream when appending to it.  As such, this\n   function can only be used for raw deflate, and must be used before the first\n   deflate() call after a deflateInit2() or deflateReset().  bits must be less\n   than or equal to 16, and that many of the least significant bits of value\n   will be inserted in the output.\n\n     deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough\n   room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the\n   source stream state was inconsistent.\n*/\n\nint deflateSetHeader(z_streamp strm, gz_headerp head);\n/*\n     deflateSetHeader() provides gzip header information for when a gzip\n   stream is requested by deflateInit2().  deflateSetHeader() may be called\n   after deflateInit2() or deflateReset() and before the first call of\n   deflate().  The text, time, os, extra field, name, and comment information\n   in the provided gz_header structure are written to the gzip header (xflag is\n   ignored -- the extra flags are set according to the compression level).  The\n   caller must assure that, if not Z_NULL, name and comment are terminated with\n   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are\n   available there.  If hcrc is true, a gzip header crc is included.  Note that\n   the current versions of the command-line version of gzip (up through version\n   1.3.x) do not support header crc's, and will report that it is a \"multi-part\n   gzip file\" and give up.\n\n     If deflateSetHeader is not used, the default gzip header has text false,\n   the time set to zero, and os set to 255, with no extra, name, or comment\n   fields.  The gzip header is returned to the default state by deflateReset().\n\n     deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.\n*/\n\nint inflateInit2(z_streamp strm, int windowBits)\n{\n    return inflateInit2_(strm, windowBits, ZLIB_VERSION.ptr, z_stream.sizeof);\n}\n/*\n     This is another version of inflateInit with an extra parameter.  The\n   fields next_in, avail_in, zalloc, zfree and opaque must be initialized\n   before by the caller.\n\n     The windowBits parameter is the base two logarithm of the maximum window\n   size (the size of the history buffer).  It should be in the range 8 .. 15 for\n   this version of the library.  The default value is 15 if inflateInit is used\n   instead.  windowBits must be greater than or equal to the windowBits value\n   provided to deflateInit2() while compressing, or it must be equal to 15 if\n   deflateInit2() was not used.  If a compressed stream with a larger window\n   size is given as input, inflate() will return with the error code\n   Z_DATA_ERROR instead of trying to allocate a larger window.\n\n     windowBits can also be zero to request that inflate use the window size in\n   the zlib header of the compressed stream.\n\n     windowBits can also be -8..-15 for raw inflate.  In this case, -windowBits\n   determines the window size.  inflate() will then process raw deflate data,\n   not looking for a zlib or gzip header, not generating a check value, and not\n   looking for any check values for comparison at the end of the stream.  This\n   is for use with other formats that use the deflate compressed data format\n   such as zip.  Those formats provide their own check values.  If a custom\n   format is developed using the raw deflate format for compressed data, it is\n   recommended that a check value such as an Adler-32 or a CRC-32 be applied to\n   the uncompressed data as is done in the zlib, gzip, and zip formats.  For\n   most applications, the zlib format should be used as is.  Note that comments\n   above on the use in deflateInit2() applies to the magnitude of windowBits.\n\n     windowBits can also be greater than 15 for optional gzip decoding.  Add\n   32 to windowBits to enable zlib and gzip decoding with automatic header\n   detection, or add 16 to decode only the gzip format (the zlib format will\n   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is a\n   CRC-32 instead of an Adler-32.  Unlike the gunzip utility and gzread() (see\n   below), inflate() will not automatically decode concatenated gzip streams.\n   inflate() will return Z_STREAM_END at the end of the gzip stream.  The state\n   would need to be reset to continue decoding a subsequent gzip stream.\n\n     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the\n   version assumed by the caller, or Z_STREAM_ERROR if the parameters are\n   invalid, such as a null pointer to the structure.  msg is set to null if\n   there is no error message.  inflateInit2 does not perform any decompression\n   apart from possibly reading the zlib header if present: actual decompression\n   will be done by inflate().  (So next_in and avail_in may be modified, but\n   next_out and avail_out are unused and unchanged.) The current implementation\n   of inflateInit2() does not process any header information -- that is\n   deferred until inflate() is called.\n*/\n\nint inflateSetDictionary(z_streamp strm, const(ubyte)* dictionary, uint  dictLength);\n/*\n     Initializes the decompression dictionary from the given uncompressed byte\n   sequence.  This function must be called immediately after a call of inflate,\n   if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor\n   can be determined from the Adler-32 value returned by that call of inflate.\n   The compressor and decompressor must use exactly the same dictionary (see\n   deflateSetDictionary).  For raw inflate, this function can be called at any\n   time to set the dictionary.  If the provided dictionary is smaller than the\n   window and there is already data in the window, then the provided dictionary\n   will amend what's there.  The application must insure that the dictionary\n   that was used for compression is provided.\n\n     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a\n   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is\n   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the\n   expected one (incorrect Adler-32 value).  inflateSetDictionary does not\n   perform any decompression: this will be done by subsequent calls of\n   inflate().\n*/\n\nint inflateGetDictionary(z_streamp strm, ubyte* dictionary, uint* dictLength);\n/*\n     Returns the sliding dictionary being maintained by inflate.  dictLength is\n   set to the number of bytes in the dictionary, and that many bytes are copied\n   to dictionary.  dictionary must have enough space, where 32768 bytes is\n   always enough.  If inflateGetDictionary() is called with dictionary equal to\n   Z_NULL, then only the dictionary length is returned, and nothing is copied.\n   Similary, if dictLength is Z_NULL, then it is not set.\n\n     inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the\n   stream state is inconsistent.\n*/\n\nint inflateSync(z_streamp strm);\n/*\n     Skips invalid compressed data until a possible full flush point (see above\n   for the description of deflate with Z_FULL_FLUSH) can be found, or until all\n   available input is skipped.  No output is provided.\n\n     inflateSync searches for a 00 00 FF FF pattern in the compressed data.\n   All full flush points have this pattern, but not all occurrences of this\n   pattern are full flush points.\n\n     inflateSync returns Z_OK if a possible full flush point has been found,\n   Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point\n   has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.\n   In the success case, the application may save the current current value of\n   total_in which indicates where valid compressed data was found.  In the\n   error case, the application may repeatedly call inflateSync, providing more\n   input each time, until success or end of the input data.\n*/\n\nint inflateCopy(z_streamp dest, z_streamp source);\n/*\n     Sets the destination stream as a complete copy of the source stream.\n\n     This function can be useful when randomly accessing a large stream.  The\n   first pass through the stream can periodically record the inflate state,\n   allowing restarting inflate at those points when randomly accessing the\n   stream.\n\n     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent\n   (such as zalloc being Z_NULL).  msg is left unchanged in both source and\n   destination.\n*/\n\nint inflateReset(z_streamp strm);\n/*\n     This function is equivalent to inflateEnd followed by inflateInit,\n   but does not free and reallocate the internal decompression state.  The\n   stream will keep attributes that may have been set by inflateInit2.\n\n     inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent (such as zalloc or state being Z_NULL).\n*/\n\nint inflateReset2(z_streamp strm, int windowBits);\n/*\n     This function is the same as inflateReset, but it also permits changing\n   the wrap and window size requests.  The windowBits parameter is interpreted\n   the same as it is for inflateInit2.  If the window size is changed, then the\n   memory allocated for the window is freed, and the window will be reallocated\n   by inflate() if needed.\n\n     inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent (such as zalloc or state being Z_NULL), or if\n   the windowBits parameter is invalid.\n*/\n\nint inflatePrime(z_streamp strm, int bits, int value);\n/*\n     This function inserts bits in the inflate input stream.  The intent is\n   that this function is used to start inflating at a bit position in the\n   middle of a byte.  The provided bits will be used before any bytes are used\n   from next_in.  This function should only be used with raw inflate, and\n   should be used before the first inflate() call after inflateInit2() or\n   inflateReset().  bits must be less than or equal to 16, and that many of the\n   least significant bits of value will be inserted in the input.\n\n     If bits is negative, then the input stream bit buffer is emptied.  Then\n   inflatePrime() can be called again to put bits in the buffer.  This is used\n   to clear out bits leftover after feeding inflate a block description prior\n   to feeding inflate codes.\n\n     inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.\n*/\n\nc_long inflateMark(z_streamp strm);\n/*\n     This function returns two values, one in the lower 16 bits of the return\n   value, and the other in the remaining upper bits, obtained by shifting the\n   return value down 16 bits.  If the upper value is -1 and the lower value is\n   zero, then inflate() is currently decoding information outside of a block.\n   If the upper value is -1 and the lower value is non-zero, then inflate is in\n   the middle of a stored block, with the lower value equaling the number of\n   bytes from the input remaining to copy.  If the upper value is not -1, then\n   it is the number of bits back from the current bit position in the input of\n   the code (literal or length/distance pair) currently being processed.  In\n   that case the lower value is the number of bytes already emitted for that\n   code.\n\n     A code is being processed if inflate is waiting for more input to complete\n   decoding of the code, or if it has completed decoding but is waiting for\n   more output space to write the literal or match data.\n\n     inflateMark() is used to mark locations in the input data for random\n   access, which may be at bit positions, and to note those cases where the\n   output of a code may span boundaries of random access blocks.  The current\n   location in the input stream can be determined from avail_in and data_type\n   as noted in the description for the Z_BLOCK flush parameter for inflate.\n\n     inflateMark returns the value noted above, or -65536 if the provided\n   source stream state was inconsistent.\n*/\n\nint inflateGetHeader(z_streamp strm, gz_headerp head);\n/*\n     inflateGetHeader() requests that gzip header information be stored in the\n   provided gz_header structure.  inflateGetHeader() may be called after\n   inflateInit2() or inflateReset(), and before the first call of inflate().\n   As inflate() processes the gzip stream, head->done is zero until the header\n   is completed, at which time head->done is set to one.  If a zlib stream is\n   being decoded, then head->done is set to -1 to indicate that there will be\n   no gzip header information forthcoming.  Note that Z_BLOCK or Z_TREES can be\n   used to force inflate() to return immediately after header processing is\n   complete and before any actual data is decompressed.\n\n     The text, time, xflags, and os fields are filled in with the gzip header\n   contents.  hcrc is set to true if there is a header CRC.  (The header CRC\n   was valid if done is set to one.) If extra is not Z_NULL, then extra_max\n   contains the maximum number of bytes to write to extra.  Once done is true,\n   extra_len contains the actual extra field length, and extra contains the\n   extra field, or that field truncated if extra_max is less than extra_len.\n   If name is not Z_NULL, then up to name_max characters are written there,\n   terminated with a zero unless the length is greater than name_max.  If\n   comment is not Z_NULL, then up to comm_max characters are written there,\n   terminated with a zero unless the length is greater than comm_max.  When any\n   of extra, name, or comment are not Z_NULL and the respective field is not\n   present in the header, then that field is set to Z_NULL to signal its\n   absence.  This allows the use of deflateSetHeader() with the returned\n   structure to duplicate the header.  However if those fields are set to\n   allocated memory, then the application will need to save those pointers\n   elsewhere so that they can be eventually freed.\n\n     If inflateGetHeader is not used, then the header information is simply\n   discarded.  The header is always checked for validity, including the header\n   CRC if present.  inflateReset() will reset the process to discard the header\n   information.  The application would need to call inflateGetHeader() again to\n   retrieve the header from the next gzip stream.\n\n     inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.\n*/\n\n\nint inflateBackInit(z_stream* strm, int windowBits, ubyte* window)\n{\n    return inflateBackInit_(strm, windowBits, window, ZLIB_VERSION.ptr, z_stream.sizeof);\n}\n/*\n     Initialize the internal stream state for decompression using inflateBack()\n   calls.  The fields zalloc, zfree and opaque in strm must be initialized\n   before the call.  If zalloc and zfree are Z_NULL, then the default library-\n   derived memory allocation routines are used.  windowBits is the base two\n   logarithm of the window size, in the range 8 .. 15.  window is a caller\n   supplied buffer of that size.  Except for special applications where it is\n   assured that deflate was used with small window sizes, windowBits must be 15\n   and a 32K byte window must be supplied to be able to decompress general\n   deflate streams.\n\n     See inflateBack() for the usage of these routines.\n\n     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of\n   the parameters are invalid, Z_MEM_ERROR if the internal state could not be\n   allocated, or Z_VERSION_ERROR if the version of the library does not match\n   the version of the header file.\n*/\n\nalias in_func = uint function(void*, ubyte**);\nalias out_func = int function(void*, ubyte*, uint);\n\nint inflateBack(z_stream* strm,\n                in_func f_in,\n                void* in_desc,\n                out_func f_out,\n                void* out_desc);\n/*\n     inflateBack() does a raw inflate with a single call using a call-back\n   interface for input and output.  This is potentially more efficient than\n   inflate() for file i/o applications, in that it avoids copying between the\n   output and the sliding window by simply making the window itself the output\n   buffer.  inflate() can be faster on modern CPUs when used with large\n   buffers.  inflateBack() trusts the application to not change the output\n   buffer passed by the output function, at least until inflateBack() returns.\n\n     inflateBackInit() must be called first to allocate the internal state\n   and to initialize the state with the user-provided window buffer.\n   inflateBack() may then be used multiple times to inflate a complete, raw\n   deflate stream with each call.  inflateBackEnd() is then called to free the\n   allocated state.\n\n     A raw deflate stream is one with no zlib or gzip header or trailer.\n   This routine would normally be used in a utility that reads zip or gzip\n   files and writes out uncompressed files.  The utility would decode the\n   header and process the trailer on its own, hence this routine expects only\n   the raw deflate stream to decompress.  This is different from the default\n   behavior of inflate(), which expects a zlib header and trailer around the\n   deflate stream.\n\n     inflateBack() uses two subroutines supplied by the caller that are then\n   called by inflateBack() for input and output.  inflateBack() calls those\n   routines until it reads a complete deflate stream and writes out all of the\n   uncompressed data, or until it encounters an error.  The function's\n   parameters and return types are defined above in the in_func and out_func\n   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the\n   number of bytes of provided input, and a pointer to that input in buf.  If\n   there is no input available, in() must return zero -- buf is ignored in that\n   case -- and inflateBack() will return a buffer error.  inflateBack() will\n   call out(out_desc, buf, len) to write the uncompressed data buf[0 .. len-1].\n   out() should return zero on success, or non-zero on failure.  If out()\n   returns non-zero, inflateBack() will return with an error.  Neither in() nor\n   out() are permitted to change the contents of the window provided to\n   inflateBackInit(), which is also the buffer that out() uses to write from.\n   The length written by out() will be at most the window size.  Any non-zero\n   amount of input may be provided by in().\n\n     For convenience, inflateBack() can be provided input on the first call by\n   setting strm->next_in and strm->avail_in.  If that input is exhausted, then\n   in() will be called.  Therefore strm->next_in must be initialized before\n   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called\n   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in\n   must also be initialized, and then if strm->avail_in is not zero, input will\n   initially be taken from strm->next_in[0 ..  strm->avail_in - 1].\n\n     The in_desc and out_desc parameters of inflateBack() is passed as the\n   first parameter of in() and out() respectively when they are called.  These\n   descriptors can be optionally used to pass any information that the caller-\n   supplied in() and out() functions need to do their job.\n\n     On return, inflateBack() will set strm->next_in and strm->avail_in to\n   pass back any unused input that was provided by the last in() call.  The\n   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR\n   if in() or out() returned an error, Z_DATA_ERROR if there was a format error\n   in the deflate stream (in which case strm->msg is set to indicate the nature\n   of the error), or Z_STREAM_ERROR if the stream was not properly initialized.\n   In the case of Z_BUF_ERROR, an input or output error can be distinguished\n   using strm->next_in which will be Z_NULL only if in() returned an error.  If\n   strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning\n   non-zero.  (in() will always be called before out(), so strm->next_in is\n   assured to be defined if out() returns non-zero.)  Note that inflateBack()\n   cannot return Z_OK.\n*/\n\nint inflateBackEnd(z_stream* strm);\n/*\n     All memory allocated by inflateBackInit() is freed.\n\n     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream\n   state was inconsistent.\n*/\n\nuint zlibCompileFlags();\n/* Return flags indicating compile-time options.\n\n    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:\n     1.0: size of uInt\n     3.2: size of uLong\n     5.4: size of voidpf (pointer)\n     7.6: size of z_off_t\n\n    Compiler, assembler, and debug options:\n     8: ZLIB_DEBUG\n     9: ASMV or ASMINF -- use ASM code\n     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention\n     11: 0 (reserved)\n\n    One-time table building (smaller code, but not thread-safe if true):\n     12: BUILDFIXED -- build static block decoding tables when needed\n     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed\n     14,15: 0 (reserved)\n\n    Library content (indicates missing functionality):\n     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking\n                          deflate code when not needed)\n     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect\n                    and decode gzip streams (to avoid linking crc code)\n     18-19: 0 (reserved)\n\n    Operation variations (changes in library functionality):\n     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate\n     21: FASTEST -- deflate algorithm with only one, lowest compression level\n     22,23: 0 (reserved)\n\n    The sprintf variant used by gzprintf (zero is best):\n     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format\n     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!\n     26: 0 = returns value, 1 = void -- 1 means inferred string length returned\n\n    Remainder:\n     27-31: 0 (reserved)\n */\n\n                        /* utility functions */\n\n/*\n     The following utility functions are implemented on top of the basic\n   stream-oriented functions.  To simplify the interface, some default options\n   are assumed (compression level and memory usage, standard memory allocation\n   functions).  The source code of these utility functions can be modified if\n   you need special options.\n*/\n\nint compress(ubyte* dest,\n             size_t* destLen,\n             const(ubyte)* source,\n             size_t sourceLen);\n/*\n     Compresses the source buffer into the destination buffer.  sourceLen is\n   the byte length of the source buffer.  Upon entry, destLen is the total size\n   of the destination buffer, which must be at least the value returned by\n   compressBound(sourceLen).  Upon exit, destLen is the actual size of the\n   compressed data.  compress() is equivalent to compress2() with a level\n   parameter of Z_DEFAULT_COMPRESSION.\n\n     compress returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_BUF_ERROR if there was not enough room in the output\n   buffer.\n*/\n\nint compress2(ubyte* dest,\n              size_t* destLen,\n              const(ubyte)* source,\n              size_t sourceLen,\n              int level);\n/*\n     Compresses the source buffer into the destination buffer.  The level\n   parameter has the same meaning as in deflateInit.  sourceLen is the byte\n   length of the source buffer.  Upon entry, destLen is the total size of the\n   destination buffer, which must be at least the value returned by\n   compressBound(sourceLen).  Upon exit, destLen is the actual size of the\n   compressed data.\n\n     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_BUF_ERROR if there was not enough room in the output buffer,\n   Z_STREAM_ERROR if the level parameter is invalid.\n*/\n\nsize_t compressBound(size_t sourceLen);\n/*\n     compressBound() returns an upper bound on the compressed size after\n   compress() or compress2() on sourceLen bytes.  It would be used before a\n   compress() or compress2() call to allocate the destination buffer.\n*/\n\nint uncompress(ubyte* dest,\n               size_t* destLen,\n               const(ubyte)* source,\n               size_t sourceLen);\n/*\n     Decompresses the source buffer into the destination buffer.  sourceLen is\n   the byte length of the source buffer.  Upon entry, destLen is the total size\n   of the destination buffer, which must be large enough to hold the entire\n   uncompressed data.  (The size of the uncompressed data must have been saved\n   previously by the compressor and transmitted to the decompressor by some\n   mechanism outside the scope of this compression library.) Upon exit, destLen\n   is the actual size of the uncompressed data.\n\n     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_BUF_ERROR if there was not enough room in the output\n   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.  In\n   the case where there is not enough room, uncompress() will fill the output\n   buffer with the uncompressed data up to that point.\n*/\n\nint uncompress2(ubyte* dest,\n                size_t* destLen,\n                const(ubyte)* source,\n                size_t* sourceLen);\n/*\n     Same as uncompress, except that sourceLen is a pointer, where the\n   length of the source is *sourceLen.  On return, *sourceLen is the number of\n   source bytes consumed.\n*/\n\n                        /* gzip file access functions */\n\n/*\n     This library supports reading and writing files in gzip (.gz) format with\n   an interface similar to that of stdio, using the functions that start with\n   \"gz\".  The gzip format is different from the zlib format.  gzip is a gzip\n   wrapper, documented in RFC 1952, wrapped around a deflate stream.\n*/\n\nalias gzFile = void*;\nalias z_off_t = int;              // file offset\nalias z_size_t = size_t;\n\ngzFile gzopen(const(char)* path, const(char)* mode);\n/*\n     Opens a gzip (.gz) file for reading or writing.  The mode parameter is as\n   in fopen (\"rb\" or \"wb\") but can also include a compression level (\"wb9\") or\n   a strategy: 'f' for filtered data as in \"wb6f\", 'h' for Huffman-only\n   compression as in \"wb1h\", 'R' for run-length encoding as in \"wb1R\", or 'F'\n   for fixed code compression as in \"wb9F\".  (See the description of\n   deflateInit2 for more information about the strategy parameter.)  'T' will\n   request transparent writing or appending with no compression and not using\n   the gzip format.\n\n     \"a\" can be used instead of \"w\" to request that the gzip stream that will\n   be written be appended to the file.  \"+\" will result in an error, since\n   reading and writing to the same gzip file is not supported.  The addition of\n   \"x\" when writing will create the file exclusively, which fails if the file\n   already exists.  On systems that support it, the addition of \"e\" when\n   reading or writing will set the flag to close the file on an execve() call.\n\n     These functions, as well as gzip, will read and decode a sequence of gzip\n   streams in a file.  The append function of gzopen() can be used to create\n   such a file.  (Also see gzflush() for another way to do this.)  When\n   appending, gzopen does not test whether the file begins with a gzip stream,\n   nor does it look for the end of the gzip streams to begin appending.  gzopen\n   will simply append a gzip stream to the existing file.\n\n     gzopen can be used to read a file which is not in gzip format; in this\n   case gzread will directly read from the file without decompression.  When\n   reading, this will be detected automatically by looking for the magic two-\n   byte gzip header.\n\n     gzopen returns NULL if the file could not be opened, if there was\n   insufficient memory to allocate the gzFile state, or if an invalid mode was\n   specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).\n   errno can be checked to determine if the reason gzopen failed was that the\n   file could not be opened.\n*/\n\ngzFile gzdopen(int fd, const(char)* mode);\n/*\n     gzdopen associates a gzFile with the file descriptor fd.  File descriptors\n   are obtained from calls like open, dup, creat, pipe or fileno (if the file\n   has been previously opened with fopen).  The mode parameter is as in gzopen.\n\n     The next call of gzclose on the returned gzFile will also close the file\n   descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor\n   fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,\n   mode);.  The duplicated descriptor should be saved to avoid a leak, since\n   gzdopen does not close fd if it fails.  If you are using fileno() to get the\n   file descriptor from a FILE *, then you will have to use dup() to avoid\n   double-close()ing the file descriptor.  Both gzclose() and fclose() will\n   close the associated file descriptor, so they need to have different file\n   descriptors.\n\n     gzdopen returns NULL if there was insufficient memory to allocate the\n   gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not\n   provided, or '+' was provided), or if fd is -1.  The file descriptor is not\n   used until the next gz* read, write, seek, or close operation, so gzdopen\n   will not detect if fd is invalid (unless fd is -1).\n*/\n\nint gzbuffer(gzFile file, uint size);\n/*\n     Set the internal buffer size used by this library's functions.  The\n   default buffer size is 8192 bytes.  This function must be called after\n   gzopen() or gzdopen(), and before any other calls that read or write the\n   file.  The buffer memory allocation is always deferred to the first read or\n   write.  Three times that size in buffer space is allocated.  A larger buffer\n   size of, for example, 64K or 128K bytes will noticeably increase the speed\n   of decompression (reading).\n\n     The new buffer size also affects the maximum length for gzprintf().\n\n     gzbuffer() returns 0 on success, or -1 on failure, such as being called\n   too late.\n*/\n\nint gzsetparams(gzFile file, int level, int strategy);\n/*\n     Dynamically update the compression level or strategy.  See the description\n   of deflateInit2 for the meaning of these parameters.  Previously provided\n   data is flushed before the parameter change.\n\n     gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not\n   opened for writing, Z_ERRNO if there is an error writing the flushed data,\n   or Z_MEM_ERROR if there is a memory allocation error.\n*/\n\nint gzread(gzFile file, void* buf, uint len);\n/*\n     Reads the given number of uncompressed bytes from the compressed file.  If\n   the input file is not in gzip format, gzread copies the given number of\n   bytes into the buffer directly from the file.\n\n     After reaching the end of a gzip stream in the input, gzread will continue\n   to read, looking for another gzip stream.  Any number of gzip streams may be\n   concatenated in the input file, and will all be decompressed by gzread().\n   If something other than a gzip stream is encountered after a gzip stream,\n   that remaining trailing garbage is ignored (and no error is returned).\n\n     gzread can be used to read a gzip file that is being concurrently written.\n   Upon reaching the end of the input, gzread will return with the available\n   data.  If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then\n   gzclearerr can be used to clear the end of file indicator in order to permit\n   gzread to be tried again.  Z_OK indicates that a gzip stream was completed\n   on the last gzread.  Z_BUF_ERROR indicates that the input file ended in the\n   middle of a gzip stream.  Note that gzread does not return -1 in the event\n   of an incomplete gzip stream.  This error is deferred until gzclose(), which\n   will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip\n   stream.  Alternatively, gzerror can be used before gzclose to detect this\n   case.\n\n     gzread returns the number of uncompressed bytes actually read, less than\n   len for end of file, or -1 for error.  If len is too large to fit in an int,\n   then nothing is read, -1 is returned, and the error state is set to\n   Z_STREAM_ERROR.\n*/\n\nz_size_t gzfread(void* buf, z_size_t size, z_size_t nitems, gzFile file);\n/*\n     Read up to nitems items of size size from file to buf, otherwise operating\n   as gzread() does.  This duplicates the interface of stdio's fread(), with\n   size_t request and return types.  If the library defines size_t, then\n   z_size_t is identical to size_t.  If not, then z_size_t is an unsigned\n   integer type that can contain a pointer.\n\n     gzfread() returns the number of full items read of size size, or zero if\n   the end of the file was reached and a full item could not be read, or if\n   there was an error.  gzerror() must be consulted if zero is returned in\n   order to determine if there was an error.  If the multiplication of size and\n   nitems overflows, i.e. the product does not fit in a z_size_t, then nothing\n   is read, zero is returned, and the error state is set to Z_STREAM_ERROR.\n\n     In the event that the end of file is reached and only a partial item is\n   available at the end, i.e. the remaining uncompressed data length is not a\n   multiple of size, then the final partial item is nevetheless read into buf\n   and the end-of-file flag is set.  The length of the partial item read is not\n   provided, but could be inferred from the result of gztell().  This behavior\n   is the same as the behavior of fread() implementations in common libraries,\n   but it prevents the direct use of gzfread() to read a concurrently written\n   file, reseting and retrying on end-of-file, when size is not 1.\n*/\n\nint gzwrite(gzFile file, void* buf, uint len);\n/*\n     Writes the given number of uncompressed bytes into the compressed file.\n   gzwrite returns the number of uncompressed bytes written or 0 in case of\n   error.\n*/\n\nz_size_t gzfwrite(void* buf, z_size_t size, z_size_t nitems, gzFile file);\n/*\n     gzfwrite() writes nitems items of size size from buf to file, duplicating\n   the interface of stdio's fwrite(), with size_t request and return types.  If\n   the library defines size_t, then z_size_t is identical to size_t.  If not,\n   then z_size_t is an unsigned integer type that can contain a pointer.\n\n     gzfwrite() returns the number of full items written of size size, or zero\n   if there was an error.  If the multiplication of size and nitems overflows,\n   i.e. the product does not fit in a z_size_t, then nothing is written, zero\n   is returned, and the error state is set to Z_STREAM_ERROR.\n*/\n\nint gzprintf(gzFile file, const(char)* format, ...);\n/*\n     Converts, formats, and writes the arguments to the compressed file under\n   control of the format string, as in fprintf.  gzprintf returns the number of\n   uncompressed bytes actually written, or a negative zlib error code in case\n   of error.  The number of uncompressed bytes written is limited to 8191, or\n   one less than the buffer size given to gzbuffer().  The caller should assure\n   that this limit is not exceeded.  If it is exceeded, then gzprintf() will\n   return an error (0) with nothing written.  In this case, there may also be a\n   buffer overflow with unpredictable consequences, which is possible only if\n   zlib was compiled with the insecure functions sprintf() or vsprintf()\n   because the secure snprintf() or vsnprintf() functions were not available.\n   This can be determined using zlibCompileFlags().\n*/\n\nint gzputs(gzFile file, const(char)* s);\n/*\n     Writes the given null-terminated string to the compressed file, excluding\n   the terminating null character.\n\n     gzputs returns the number of characters written, or -1 in case of error.\n*/\n\nconst(char)* gzgets(gzFile file, const(char)* buf, int len);\n/*\n     Reads bytes from the compressed file until len-1 characters are read, or a\n   newline character is read and transferred to buf, or an end-of-file\n   condition is encountered.  If any characters are read or if len == 1, the\n   string is terminated with a null character.  If no characters are read due\n   to an end-of-file or len < 1, then the buffer is left untouched.\n\n     gzgets returns buf which is a null-terminated string, or it returns NULL\n   for end-of-file or in case of error.  If there was an error, the contents at\n   buf are indeterminate.\n*/\n\nint gzputc(gzFile file, int c);\n/*\n     Writes c, converted to an unsigned char, into the compressed file.  gzputc\n   returns the value that was written, or -1 in case of error.\n*/\n\nint gzgetc(gzFile file);\n/*\n     Reads one byte from the compressed file.  gzgetc returns this byte or -1\n   in case of end of file or error.  This is implemented as a macro for speed.\n   As such, it does not do all of the checking the other functions do.  I.e.\n   it does not check to see if file is NULL, nor whether the structure file\n   points to has been clobbered or not.\n*/\n\nint gzungetc(int c, gzFile file);\n/*\n     Push one character back onto the stream to be read as the first character\n   on the next read.  At least one character of push-back is allowed.\n   gzungetc() returns the character pushed, or -1 on failure.  gzungetc() will\n   fail if c is -1, and may fail if a character has been pushed but not read\n   yet.  If gzungetc is used immediately after gzopen or gzdopen, at least the\n   output buffer size of pushed characters is allowed.  (See gzbuffer above.)\n   The pushed character will be discarded if the stream is repositioned with\n   gzseek() or gzrewind().\n*/\n\nint gzflush(gzFile file, int flush);\n/*\n     Flushes all pending output into the compressed file.  The parameter flush\n   is as in the deflate() function.  The return value is the zlib error number\n   (see function gzerror below).  gzflush is only permitted when writing.\n\n     If the flush parameter is Z_FINISH, the remaining data is written and the\n   gzip stream is completed in the output.  If gzwrite() is called again, a new\n   gzip stream will be started in the output.  gzread() is able to read such\n   concatenated gzip streams.\n\n     gzflush should be called only when strictly necessary because it will\n   degrade compression if called too often.\n*/\n\nz_off_t gzseek(gzFile file, z_off_t offset, int whence);\n/*\n     Sets the starting position for the next gzread or gzwrite on the given\n   compressed file.  The offset represents a number of bytes in the\n   uncompressed data stream.  The whence parameter is defined as in lseek(2);\n   the value SEEK_END is not supported.\n\n     If the file is opened for reading, this function is emulated but can be\n   extremely slow.  If the file is opened for writing, only forward seeks are\n   supported; gzseek then compresses a sequence of zeroes up to the new\n   starting position.\n\n     gzseek returns the resulting offset location as measured in bytes from\n   the beginning of the uncompressed stream, or -1 in case of error, in\n   particular if the file is opened for writing and the new starting position\n   would be before the current position.\n*/\n\nint gzrewind(gzFile file);\n/*\n     Rewinds the given file. This function is supported only for reading.\n\n     gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)\n*/\n\nz_off_t gztell(gzFile file);\n/*\n     Returns the starting position for the next gzread or gzwrite on the given\n   compressed file.  This position represents a number of bytes in the\n   uncompressed data stream, and is zero when starting, even if appending or\n   reading a gzip stream from the middle of a file using gzdopen().\n\n     gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)\n*/\n\nz_off_t gzoffset(gzFile file);\n/*\n     Returns the current offset in the file being read or written.  This offset\n   includes the count of bytes that precede the gzip stream, for example when\n   appending or when using gzdopen() for reading.  When reading, the offset\n   does not include as yet unused buffered input.  This information can be used\n   for a progress indicator.  On error, gzoffset() returns -1.\n*/\n\nint gzeof(gzFile file);\n/*\n     Returns true (1) if the end-of-file indicator has been set while reading,\n   false (0) otherwise.  Note that the end-of-file indicator is set only if the\n   read tried to go past the end of the input, but came up short.  Therefore,\n   just like feof(), gzeof() may return false even if there is no more data to\n   read, in the event that the last read request was for the exact number of\n   bytes remaining in the input file.  This will happen if the input file size\n   is an exact multiple of the buffer size.\n\n     If gzeof() returns true, then the read functions will return no more data,\n   unless the end-of-file indicator is reset by gzclearerr() and the input file\n   has grown since the previous end of file was detected.\n*/\n\nint gzdirect(gzFile file);\n/*\n     Returns true (1) if file is being copied directly while reading, or false\n   (0) if file is a gzip stream being decompressed.\n\n     If the input file is empty, gzdirect() will return true, since the input\n   does not contain a gzip stream.\n\n     If gzdirect() is used immediately after gzopen() or gzdopen() it will\n   cause buffers to be allocated to allow reading the file to determine if it\n   is a gzip file.  Therefore if gzbuffer() is used, it should be called before\n   gzdirect().\n\n     When writing, gzdirect() returns true (1) if transparent writing was\n   requested (\"wT\" for the gzopen() mode), or false (0) otherwise.  (Note:\n   gzdirect() is not needed when writing.  Transparent writing must be\n   explicitly requested, so the application already knows the answer.  When\n   linking statically, using gzdirect() will include all of the zlib code for\n   gzip file reading and decompression, which may not be desired.)\n*/\n\nint gzclose(gzFile file);\n/*\n     Flushes all pending output if necessary, closes the compressed file and\n   deallocates the (de)compression state.  Note that once file is closed, you\n   cannot call gzerror with file, since its structures have been deallocated.\n   gzclose must not be called more than once on the same file, just as free\n   must not be called more than once on the same allocation.\n\n     gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a\n   file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the\n   last read ended in the middle of a gzip stream, or Z_OK on success.\n*/\n\nint gzclose_r(gzFile file);\nint gzclose_w(gzFile file);\n/*\n     Same as gzclose(), but gzclose_r() is only for use when reading, and\n   gzclose_w() is only for use when writing or appending.  The advantage to\n   using these instead of gzclose() is that they avoid linking in zlib\n   compression or decompression code that is not used when only reading or only\n   writing respectively.  If gzclose() is used, then both compression and\n   decompression code will be included the application when linking to a static\n   zlib library.\n*/\n\nconst(char)* gzerror(gzFile file, int* errnum);\n/*\n     Returns the error message for the last error which occurred on the given\n   compressed file.  errnum is set to zlib error number.  If an error occurred\n   in the file system and not in the compression library, errnum is set to\n   Z_ERRNO and the application may consult errno to get the exact error code.\n\n     The application must not modify the returned string.  Future calls to\n   this function may invalidate the previously returned string.  If file is\n   closed, then the string previously returned by gzerror will no longer be\n   available.\n\n     gzerror() should be used to distinguish errors from end-of-file for those\n   functions above that do not distinguish those cases in their return values.\n*/\n\nvoid gzclearerr(gzFile file);\n/*\n     Clears the error and end-of-file flags for file.  This is analogous to the\n   clearerr() function in stdio.  This is useful for continuing to read a gzip\n   file that is being written concurrently.\n*/\n\n                        /* checksum functions */\n\n/*\n     These functions are not related to compression but are exported\n   anyway because they might be useful in applications using the compression\n   library.\n*/\n\nuint adler32(uint adler, const(ubyte)* buf, uint len);\n/*\n     Update a running Adler-32 checksum with the bytes buf[0 .. len-1] and\n   return the updated checksum.  If buf is Z_NULL, this function returns the\n   required initial value for the checksum.\n\n     An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed\n   much faster.\n\n   Usage example:\n\n     uLong adler = adler32(0L, Z_NULL, 0);\n\n     while (read_buffer(buffer, length) != EOF)\n       adler = adler32(adler, buffer, length);\n\n     if (adler != original_adler) error();\n*/\n\nuint adler32_z (uint adler, const(ubyte)* buf, z_size_t len);\n/*\n     Same as adler32(), but with a size_t length.\n*/\n\nuint adler32_combine(uint adler1, uint adler2, z_off_t len2);\n/*\n     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1\n   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for\n   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of\n   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.  Note\n   that the z_off_t type (like off_t) is a signed integer.  If len2 is\n   negative, the result has no meaning or utility.\n*/\n\nuint crc32(uint crc, const(ubyte)* buf, uint len);\n/*\n     Update a running CRC-32 with the bytes buf[0 .. len-1] and return the\n   updated CRC-32.  If buf is Z_NULL, this function returns the required\n   initial value for the crc.  Pre- and post-conditioning (one's complement) is\n   performed within this function so it shouldn't be done by the application.\n\n   Usage example:\n\n     uLong crc = crc32(0L, Z_NULL, 0);\n\n     while (read_buffer(buffer, length) != EOF)\n       crc = crc32(crc, buffer, length);\n\n     if (crc != original_crc) error();\n*/\n\nuint crc32_z(uint adler, const(ubyte)* buf, z_size_t len);\n/*\n     Same as crc32(), but with a size_t length.\n*/\n\nuint crc32_combine(uint crc1, uint crc2, z_off_t len2);\n\n/*\n     Combine two CRC-32 check values into one.  For two sequences of bytes,\n   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were\n   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32\n   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and\n   len2.\n*/\n\n\n                        /* various hacks, don't look :) */\n\n/* deflateInit and inflateInit are macros to allow checking the zlib version\n * and the compiler's view of z_stream:\n */\nint deflateInit_(z_streamp strm,\n                 int level,\n                 const(char)* versionx,\n                 int stream_size);\n\nint inflateInit_(z_streamp strm,\n                 const(char)* versionx,\n                 int stream_size);\n\nint deflateInit2_(z_streamp strm,\n                  int level,\n                  int method,\n                  int windowBits,\n                  int memLevel,\n                  int strategy,\n                  const(char)* versionx,\n                  int stream_size);\n\nint inflateBackInit_(z_stream* strm,\n                     int windowBits,\n                     ubyte* window,\n                     const(char)* z_version,\n                     int stream_size);\n\nint inflateInit2_(z_streamp strm,\n                  int windowBits,\n                  const(char)* versionx,\n                  int stream_size);\n\nconst(char)* zError(int err);\nint inflateSyncPoint(z_streamp z);\nconst(uint)* get_crc_table();\n"
  },
  {
    "path": "libphobos/src/index.d",
    "content": "Ddoc\n\n$(P Phobos is the standard runtime library that comes with the D language\ncompiler.)\n\n$(P Generally, the `std` namespace is used for the main modules in the\nPhobos standard library. The `etc` namespace is used for external C/C++\nlibrary bindings. The `core` namespace is used for low-level D runtime\nfunctions.)\n\n$(P The following table is a quick reference guide for which Phobos modules to\nuse for a given category of functionality. Note that some modules may appear in\nmore than one category, as some Phobos modules are quite generic and can be\napplied in a variety of situations.)\n\n$(BOOKTABLE ,\n    $(TR\n        $(TH Modules)\n        $(TH Description)\n    )\n    $(LEADINGROW Algorithms &amp; ranges)\n    $(TR\n        $(TDNW\n            $(MREF std,algorithm)$(BR)\n            $(MREF std,range)$(BR)\n            $(MREF std,range,primitives)$(BR)\n            $(MREF std,range,interfaces)$(BR)\n        )\n        $(TD Generic algorithms that work with $(MREF_ALTTEXT ranges, std,range)\n            of any type, including strings, arrays, and other kinds of\n            sequentially-accessed data. Algorithms include searching,\n            comparison, iteration, sorting, set operations, and mutation.\n        )\n    )\n    $(LEADINGROW Array manipulation)\n    $(TR\n        $(TDNW\n            $(MREF std,array)$(BR)\n            $(MREF std,algorithm)$(BR)\n        )\n        $(TD Convenient operations commonly used with built-in arrays.\n            Note that many common array operations are subsets of more generic\n            algorithms that work with arbitrary ranges, so they are found in\n            `std.algorithm`.\n        )\n    )\n    $(LEADINGROW Containers)\n    $(TR\n        $(TDNW\n            $(MREF std,container,array)$(BR)\n            $(MREF std,container,binaryheap)$(BR)\n            $(MREF std,container,dlist)$(BR)\n            $(MREF std,container,rbtree)$(BR)\n            $(MREF std,container,slist)$(BR)\n        )\n        $(TD See $(MREF_ALTTEXT std.container.*, std,container) for an\n            overview.\n        )\n    )\n    $(LEADINGROW Data formats)\n    $(TR\n        $(TDNW $(MREF std,base64))\n        $(TD Encoding / decoding Base64 format.)\n    )\n    $(TR\n        $(TDNW $(MREF std,csv))\n        $(TD Read Comma Separated Values and its variants from an input range of $(CODE dchar).)\n    )\n    $(TR\n        $(TDNW $(MREF std,json))\n        $(TD Read/write data in JSON format.)\n    )\n    $(TR\n        $(TDNW $(MREF std,xml))\n        $(TD Read/write data in XML format.)\n    )\n    $(TR\n        $(TDNW $(MREF std,zip))\n        $(TD Read/write data in the ZIP archive format.)\n    )\n    $(TR\n        $(TDNW $(MREF std,zlib))\n        $(TD Compress/decompress data using the zlib library.)\n    )\n    $(LEADINGROW Data integrity)\n    $(TR\n        $(TDNW $(MREF std,experimental,checkedint))\n        $(TD Checked integral types.)\n    )\n    $(TR\n        $(TDNW $(MREF std,digest))\n        $(TD Compute digests such as md5, sha1 and crc32.)\n    )\n    $(TR\n        $(TDNW $(MREF std,digest,crc))\n        $(TD Cyclic Redundancy Check (32-bit) implementation.)\n    )\n    $(TR\n        $(TDNW $(MREF std,digest,hmac))\n        $(TD Compute HMAC digests of arbitrary data.)\n    )\n    $(TR\n        $(TDNW $(MREF std,digest,md))\n        $(TD Compute MD5 hash of arbitrary data.)\n    )\n    $(TR\n        $(TDNW $(MREF std,digest,murmurhash))\n        $(TD Compute MurmurHash of arbitrary data.)\n    )\n    $(TR\n        $(TDNW $(MREF std,digest,ripemd))\n        $(TD Compute RIPEMD-160 hash of arbitrary data.)\n    )\n    $(TR\n        $(TDNW $(MREF std,digest,sha))\n        $(TD Compute SHA1 and SHA2 hashes of arbitrary data.)\n    )\n    $(LEADINGROW Date &amp; time)\n    $(TR\n        $(TDNW $(MREF std,datetime))\n        $(TD Provides convenient access to date and time representations.)\n    )\n    $(TR\n        $(TDNW $(MREF core,time))\n        $(TD Implements low-level time primitives.)\n    )\n    $(LEADINGROW Exception handling)\n    $(TR\n        $(TDNW $(MREF std,exception))\n        $(TD Implements routines related to exceptions.)\n    )\n    $(TR\n        $(TDNW $(MREF core,exception))\n        $(TD Defines built-in exception types and low-level\n            language hooks required by the compiler.)\n    )\n    $(LEADINGROW External library bindings)\n    $(TR\n        $(TDNW $(MREF etc,c,curl))\n        $(TD Interface to libcurl C library.)\n    )\n    $(TR\n        $(TDNW $(MREF etc,c,odbc,sql))\n        $(TD Interface to ODBC C library.)\n    )\n    $(TR\n        $(TDNW $(MREF etc,c,odbc,sqlext))\n    )\n    $(TR\n        $(TDNW $(MREF etc,c,odbc,sqltypes))\n    )\n    $(TR\n        $(TDNW $(MREF etc,c,odbc,sqlucode))\n    )\n    $(TR\n        $(TDNW $(MREF etc,c,sqlite3))\n        $(TD Interface to SQLite C library.)\n    )\n    $(TR\n        $(TDNW $(MREF etc,c,zlib))\n        $(TD Interface to zlib C library.)\n    )\n    $(LEADINGROW I/O &amp; File system)\n    $(TR\n        $(TDNW $(MREF std,file))\n        $(TD Manipulate files and directories.)\n    )\n    $(TR\n        $(TDNW $(MREF std,path))\n        $(TD Manipulate strings that represent filesystem paths.)\n    )\n    $(TR\n        $(TDNW $(MREF std,stdio))\n        $(TD Perform buffered I/O.)\n    )\n    $(LEADINGROW Interoperability)\n    $(TR\n        $(TDNW\n            $(MREF core,stdc,complex)$(BR)\n            $(MREF core,stdc,ctype)$(BR)\n            $(MREF core,stdc,errno)$(BR)\n            $(MREF core,stdc,fenv)$(BR)\n            $(MREF core,stdc,float_)$(BR)\n            $(MREF core,stdc,inttypes)$(BR)\n            $(MREF core,stdc,limits)$(BR)\n            $(MREF core,stdc,locale)$(BR)\n            $(MREF core,stdc,math)$(BR)\n            $(MREF core,stdc,signal)$(BR)\n            $(MREF core,stdc,stdarg)$(BR)\n            $(MREF core,stdc,stddef)$(BR)\n            $(MREF core,stdc,stdint)$(BR)\n            $(MREF core,stdc,stdio)$(BR)\n            $(MREF core,stdc,stdlib)$(BR)\n            $(MREF core,stdc,string)$(BR)\n            $(MREF core,stdc,tgmath)$(BR)\n            $(MREF core,stdc,time)$(BR)\n            $(MREF core,stdc,wchar_)$(BR)\n            $(MREF core,stdc,wctype)$(BR)\n        )\n        $(TD\n            D bindings for standard C headers.$(BR)$(BR)\n            These are mostly undocumented, as documentation\n            for the functions these declarations provide\n            bindings to can be found on external resources.\n        )\n    )\n    $(LEADINGROW Memory management)\n    $(TR\n        $(TDNW $(MREF core,memory))\n        $(TD Control the built-in garbage collector.)\n    )\n    $(TR\n        $(TDNW $(MREF std,typecons))\n        $(TD Build scoped variables and reference-counted types.)\n    )\n    $(LEADINGROW Metaprogramming)\n    $(TR\n        $(TDNW $(MREF core,attribute))\n        $(TD Definitions of special attributes recognized by the compiler.)\n    )\n    $(TR\n        $(TDNW $(MREF core,demangle))\n        $(TD Convert $(I mangled) D symbol identifiers to source representation.)\n    )\n    $(TR\n        $(TDNW $(MREF std,demangle))\n        $(TD A simple wrapper around core.demangle.)\n    )\n    $(TR\n        $(TDNW $(MREF std,meta))\n        $(TD Construct and manipulate template argument lists (aka type lists).)\n    )\n    $(TR\n        $(TDNW $(MREF std,traits))\n        $(TD Extract information about types and symbols at compile time.)\n    )\n    $(TR\n        $(TDNW $(MREF std,typecons))\n        $(TD Construct new, useful general purpose types.)\n    )\n    $(LEADINGROW Multitasking)\n    $(TR\n        $(TDNW $(MREF std,concurrency))\n        $(TD Low level messaging API for threads.)\n    )\n    $(TR\n        $(TDNW $(MREF std,parallelism))\n        $(TD High level primitives for SMP parallelism.)\n    )\n    $(TR\n        $(TDNW $(MREF std,process))\n        $(TD Starting and manipulating processes.)\n    )\n    $(TR\n        $(TDNW $(MREF core,atomic))\n        $(TD Basic support for lock-free concurrent programming.)\n    )\n    $(TR\n        $(TDNW $(MREF core,sync,barrier))\n        $(TD Synchronize the progress of a group of threads.)\n    )\n    $(TR\n        $(TDNW $(MREF core,sync,condition))\n        $(TD Synchronized condition checking.)\n    )\n    $(TR\n        $(TDNW $(MREF core,sync,exception))\n        $(TD Base class for synchronization exceptions.)\n    )\n    $(TR\n        $(TDNW $(MREF core,sync,mutex))\n        $(TD Mutex for mutually exclusive access.)\n    )\n    $(TR\n        $(TDNW $(MREF core,sync,rwmutex))\n        $(TD Shared read access and mutually exclusive write access.)\n    )\n    $(TR\n        $(TDNW $(MREF core,sync,semaphore))\n        $(TD General use synchronization semaphore.)\n    )\n    $(TR\n        $(TDNW $(MREF core,thread))\n        $(TD Thread creation and management.)\n    )\n    $(LEADINGROW Networking)\n    $(TR\n        $(TDNW $(MREF std,socket))\n        $(TD Socket primitives.)\n    )\n    $(TR\n        $(TDNW $(MREF std,net,curl))\n        $(TD Networking client functionality as provided by libcurl.)\n    )\n    $(TR\n        $(TDNW $(MREF std,net,isemail))\n        $(TD Validates an email address according to RFCs 5321, 5322 and others.)\n    )\n    $(TR\n        $(TDNW $(MREF std,uri))\n        $(TD Encode and decode Uniform Resource Identifiers (URIs).)\n    )\n    $(TR\n        $(TDNW $(MREF std,uuid))\n        $(TD Universally-unique identifiers for resources in distributed\n        systems.)\n    )\n    $(LEADINGROW Numeric)\n    $(TR\n        $(TDNW $(MREF std,bigint))\n        $(TD An arbitrary-precision integer type.)\n    )\n    $(TR\n        $(TDNW $(MREF std,complex))\n        $(TD A complex number type.)\n    )\n    $(TR\n        $(TDNW $(MREF std,math))\n        $(TD Elementary mathematical functions (powers, roots, trigonometry).)\n    )\n    $(TR\n        $(TDNW $(MREF std,mathspecial))\n        $(TD Families of transcendental functions.)\n    )\n    $(TR\n        $(TDNW $(MREF std,numeric))\n        $(TD Floating point numerics functions.)\n    )\n    $(TR\n        $(TDNW $(MREF std,random))\n        $(TD Pseudo-random number generators.)\n    )\n    $(TR\n        $(TDNW $(MREF core,checkedint))\n        $(TD Range-checking integral arithmetic primitives.)\n    )\n    $(TR\n        $(TDNW $(MREF core,math))\n        $(TD Built-in mathematical intrinsics.)\n    )\n    $(LEADINGROW Paradigms)\n    $(TR\n        $(TDNW $(MREF std,functional))\n        $(TD Functions that manipulate other functions.)\n    )\n    $(TR\n        $(TDNW $(MREF std,algorithm))\n        $(TD Generic algorithms for processing sequences.)\n    )\n    $(TR\n        $(TDNW $(MREF std,signals))\n        $(TD Signal-and-slots framework for event-driven programming.)\n    )\n    $(LEADINGROW Runtime utilities)\n    $(TR\n        $(TDNW $(MREF1 object))\n        $(TD Core language definitions. Automatically imported.)\n    )\n    $(TR\n        $(TDNW $(MREF std,getopt))\n        $(TD Parsing of command-line arguments.)\n    )\n    $(TR\n        $(TDNW $(MREF std,compiler))\n        $(TD Host compiler vendor string and language version.)\n    )\n    $(TR\n        $(TDNW $(MREF std,system))\n        $(TD Runtime environment, such as OS type and endianness.)\n    )\n    $(TR\n        $(TDNW $(MREF core,cpuid))\n        $(TD Capabilities of the CPU the program is running on.)\n    )\n    $(TR\n        $(TDNW $(MREF core,memory))\n        $(TD Control the built-in garbage collector.)\n    )\n    $(TR\n        $(TDNW $(MREF core,runtime))\n        $(TD Control and configure the D runtime.)\n    )\n    $(LEADINGROW String manipulation)\n    $(TR\n        $(TDNW $(MREF std,string))\n        $(TD Algorithms that work specifically with strings.)\n    )\n    $(TR\n        $(TDNW $(MREF std,array))\n        $(TD Manipulate builtin arrays.)\n    )\n    $(TR\n        $(TDNW $(MREF std,algorithm))\n        $(TD Generic algorithms for processing sequences.)\n    )\n    $(TR\n        $(TDNW $(MREF std,uni))\n        $(TD Fundamental Unicode algorithms and data structures.)\n    )\n    $(TR\n        $(TDNW $(MREF std,utf))\n        $(TD Encode and decode UTF-8, UTF-16 and UTF-32 strings.)\n    )\n    $(TR\n        $(TDNW $(MREF std,format))\n        $(TD Format data into strings.)\n    )\n    $(TR\n        $(TDNW $(MREF std,path))\n        $(TD Manipulate strings that represent filesystem paths.)\n    )\n    $(TR\n        $(TDNW $(MREF std,regex))\n        $(TD Regular expressions.)\n    )\n    $(TR\n        $(TDNW $(MREF std,ascii))\n        $(TD Routines specific to the ASCII subset of Unicode.)\n    )\n    $(TR\n        $(TDNW $(MREF std,encoding))\n        $(TD Handle and transcode between various text encodings.)\n    )\n    $(TR\n        $(TDNW $(MREF std,windows,charset))\n        $(TD Windows specific character set support.)\n    )\n    $(TR\n        $(TDNW $(MREF std,outbuffer))\n        $(TD Serialize data to $(CODE ubyte) arrays.)\n    )\n    $(LEADINGROW Type manipulations)\n    $(TR\n        $(TDNW $(MREF std,conv))\n        $(TD Convert types from one type to another.)\n    )\n    $(TR\n        $(TDNW $(MREF std,typecons))\n        $(TD Type constructors for scoped variables, ref counted types, etc.)\n    )\n    $(TR\n        $(TDNW $(MREF std,bitmanip))\n        $(TD High level bit level manipulation, bit arrays, bit fields.)\n    )\n    $(TR\n        $(TDNW $(MREF std,variant))\n        $(TD Discriminated unions and algebraic types.)\n    )\n    $(TR\n        $(TDNW $(MREF core,bitop))\n        $(TD Low level bit manipulation.)\n    )\n    $(LEADINGROW Vector programming)\n    $(TR\n        $(TDNW $(MREF core,simd))\n        $(TD SIMD intrinsics)\n    )\n\n$(COMMENT\n    $(LEADINGROW Undocumented modules (intentionally omitted).)\n    $(TR\n        $(TDNW\n            $(MREF core,sync,config)$(BR)\n            $(MREF std,container,util)$(BR)\n            $(MREF std,regex,internal,backtracking)$(BR)\n            $(MREF std,regex,internal,generator)$(BR)\n            $(MREF std,regex,internal,ir)$(BR)\n            $(MREF std,regex,internal,kickstart)$(BR)\n            $(MREF std,regex,internal,parser)$(BR)\n            $(MREF std,regex,internal,tests)$(BR)\n            $(MREF std,regex,internal,thompson)$(BR)\n        )\n        $(TD\n             Internal modules.\n        )\n    )\n    $(TR\n        $(TDNW\n            $(MREF core,vararg)$(BR)\n            $(MREF std,c,fenv)$(BR)\n            $(MREF std,c,linux,linux)$(BR)\n            $(MREF std,c,linux,socket)$(BR)\n            $(MREF std,c,locale)$(BR)\n            $(MREF std,c,math)$(BR)\n            $(MREF std,c,process)$(BR)\n            $(MREF std,c,stdarg)$(BR)\n            $(MREF std,c,stddef)$(BR)\n            $(MREF std,c,stdio)$(BR)\n            $(MREF std,c,stdlib)$(BR)\n            $(MREF std,c,string)$(BR)\n            $(MREF std,c,time)$(BR)\n            $(MREF std,c,wcharh)$(BR)\n            $(MREF std,stdint)$(BR)\n        )\n        $(TDN\n             Redirect modules.\n        )\n    )\n    $(TR\n        $(TDNW\n            $(MREF std,mmfile)$(BR)\n            $(MREF std,typetuple)$(BR)\n        )\n        $(TD\n             Deprecated modules.\n        )\n    )\n    $(TR\n        $(TDNW\n            $(MREF std,experimental,logger)$(BR)\n            $(MREF std,experimental,logger,core)$(BR)\n            $(MREF std,experimental,logger,filelogger)$(BR)\n            $(MREF std,experimental,logger,multilogger)$(BR)\n            $(MREF std,experimental,logger,nulllogger)$(BR)\n        )\n        $(TD\n             Experimental modules.\n        )\n    )\n)\n)\n\nMacros:\n        TITLE=Phobos Runtime Library\n        DDOC_BLANKLINE=\n        _=\n"
  },
  {
    "path": "libphobos/src/libgphobos.spec.in",
    "content": "#\n# This spec file is read by gdc when linking.\n# It is used to specify the libraries we need to link in, in the right\n# order.\n#\n\n%rename lib liborig_gdc_renamed\n*lib: @SPEC_PHOBOS_DEPS@ %(liborig_gdc_renamed)\n"
  },
  {
    "path": "libphobos/src/std/algorithm/comparison.d",
    "content": "// Written in the D programming language.\n/**\nThis is a submodule of $(MREF std, algorithm).\nIt contains generic comparison algorithms.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE Cheat Sheet,\n$(TR $(TH Function Name) $(TH Description))\n$(T2 among,\n        Checks if a value is among a set of values, e.g.\n        `if (v.among(1, 2, 3)) // `v` is 1, 2 or 3`)\n$(T2 castSwitch,\n        `(new A()).castSwitch((A a)=>1,(B b)=>2)` returns `1`.)\n$(T2 clamp,\n        `clamp(1, 3, 6)` returns `3`. `clamp(4, 3, 6)` returns `4`.)\n$(T2 cmp,\n        `cmp(\"abc\", \"abcd\")` is `-1`, `cmp(\"abc\", \"aba\")` is `1`,\n        and `cmp(\"abc\", \"abc\")` is `0`.)\n$(T2 either,\n        Return first parameter `p` that passes an `if (p)` test, e.g.\n        `either(0, 42, 43)` returns `42`.)\n$(T2 equal,\n        Compares ranges for element-by-element equality, e.g.\n        `equal([1, 2, 3], [1.0, 2.0, 3.0])` returns `true`.)\n$(T2 isPermutation,\n        `isPermutation([1, 2], [2, 1])` returns `true`.)\n$(T2 isSameLength,\n        `isSameLength([1, 2, 3], [4, 5, 6])` returns `true`.)\n$(T2 levenshteinDistance,\n        `levenshteinDistance(\"kitten\", \"sitting\")` returns `3` by using\n        the $(LINK2 https://en.wikipedia.org/wiki/Levenshtein_distance,\n        Levenshtein distance algorithm).)\n$(T2 levenshteinDistanceAndPath,\n        `levenshteinDistanceAndPath(\"kitten\", \"sitting\")` returns\n        `tuple(3, \"snnnsni\")` by using the\n        $(LINK2 https://en.wikipedia.org/wiki/Levenshtein_distance,\n        Levenshtein distance algorithm).)\n$(T2 max,\n        `max(3, 4, 2)` returns `4`.)\n$(T2 min,\n        `min(3, 4, 2)` returns `2`.)\n$(T2 mismatch,\n        `mismatch(\"oh hi\", \"ohayo\")` returns `tuple(\" hi\", \"ayo\")`.)\n$(T2 predSwitch,\n        `2.predSwitch(1, \"one\", 2, \"two\", 3, \"three\")` returns `\"two\"`.)\n)\n\nCopyright: Andrei Alexandrescu 2008-.\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n\nSource: $(PHOBOSSRC std/algorithm/comparison.d)\n\nMacros:\nT2=$(TR $(TDNW $(LREF $1)) $(TD $+))\n */\nmodule std.algorithm.comparison;\n\n// FIXME\nimport std.functional; // : unaryFun, binaryFun;\nimport std.range.primitives;\nimport std.traits;\n// FIXME\nimport std.meta : allSatisfy;\nimport std.typecons; // : tuple, Tuple, Flag, Yes;\n\nimport std.internal.attributes : betterC;\n\n/**\nFind `value` _among `values`, returning the 1-based index\nof the first matching value in `values`, or `0` if `value`\nis not _among `values`. The predicate `pred` is used to\ncompare values, and uses equality by default.\n\nParams:\n    pred = The predicate used to compare the values.\n    value = The value to search for.\n    values = The values to compare the value to.\n\nReturns:\n    0 if value was not found among the values, otherwise the index of the\n    found value plus one is returned.\n\nSee_Also:\n$(REF_ALTTEXT find, find, std,algorithm,searching) and $(REF_ALTTEXT canFind, canFind, std,algorithm,searching) for finding a value in a\nrange.\n*/\nuint among(alias pred = (a, b) => a == b, Value, Values...)\n    (Value value, Values values)\nif (Values.length != 0)\n{\n    foreach (uint i, ref v; values)\n    {\n        import std.functional : binaryFun;\n        if (binaryFun!pred(value, v)) return i + 1;\n    }\n    return 0;\n}\n\n/// Ditto\ntemplate among(values...)\nif (isExpressionTuple!values)\n{\n    uint among(Value)(Value value)\n        if (!is(CommonType!(Value, values) == void))\n    {\n        switch (value)\n        {\n            foreach (uint i, v; values)\n                case v:\n                    return i + 1;\n            default:\n                return 0;\n        }\n    }\n}\n\n///\n@safe @betterC unittest\n{\n    assert(3.among(1, 42, 24, 3, 2));\n\n    if (auto pos = \"bar\".among(\"foo\", \"bar\", \"baz\"))\n        assert(pos == 2);\n    else\n        assert(false);\n\n    // 42 is larger than 24\n    assert(42.among!((lhs, rhs) => lhs > rhs)(43, 24, 100) == 2);\n}\n\n/**\nAlternatively, `values` can be passed at compile-time, allowing for a more\nefficient search, but one that only supports matching on equality:\n*/\n@safe @betterC unittest\n{\n    assert(3.among!(2, 3, 4));\n    assert(\"bar\".among!(\"foo\", \"bar\", \"baz\") == 2);\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n\n    if (auto pos = 3.among(1, 2, 3))\n        assert(pos == 3);\n    else\n        assert(false);\n    assert(!4.among(1, 2, 3));\n\n    auto position = \"hello\".among(\"hello\", \"world\");\n    assert(position);\n    assert(position == 1);\n\n    alias values = AliasSeq!(\"foo\", \"bar\", \"baz\");\n    auto arr = [values];\n    assert(arr[0 .. \"foo\".among(values)] == [\"foo\"]);\n    assert(arr[0 .. \"bar\".among(values)] == [\"foo\", \"bar\"]);\n    assert(arr[0 .. \"baz\".among(values)] == arr);\n    assert(\"foobar\".among(values) == 0);\n\n    if (auto pos = 3.among!(1, 2, 3))\n        assert(pos == 3);\n    else\n        assert(false);\n    assert(!4.among!(1, 2, 3));\n\n    position = \"hello\".among!(\"hello\", \"world\");\n    assert(position);\n    assert(position == 1);\n\n    static assert(!__traits(compiles, \"a\".among!(\"a\", 42)));\n    static assert(!__traits(compiles, (Object.init).among!(42, \"a\")));\n}\n\n// Used in castSwitch to find the first choice that overshadows the last choice\n// in a tuple.\nprivate template indexOfFirstOvershadowingChoiceOnLast(choices...)\n{\n    alias firstParameterTypes = Parameters!(choices[0]);\n    alias lastParameterTypes = Parameters!(choices[$ - 1]);\n\n    static if (lastParameterTypes.length == 0)\n    {\n        // If the last is null-typed choice, check if the first is null-typed.\n        enum isOvershadowing = firstParameterTypes.length == 0;\n    }\n    else static if (firstParameterTypes.length == 1)\n    {\n        // If the both first and last are not null-typed, check for overshadowing.\n        enum isOvershadowing =\n            is(firstParameterTypes[0] == Object) // Object overshadows all other classes!(this is needed for interfaces)\n            || is(lastParameterTypes[0] : firstParameterTypes[0]);\n    }\n    else\n    {\n        // If the first is null typed and the last is not - the is no overshadowing.\n        enum isOvershadowing = false;\n    }\n\n    static if (isOvershadowing)\n    {\n        enum indexOfFirstOvershadowingChoiceOnLast = 0;\n    }\n    else\n    {\n        enum indexOfFirstOvershadowingChoiceOnLast =\n            1 + indexOfFirstOvershadowingChoiceOnLast!(choices[1..$]);\n    }\n}\n\n/**\nExecutes and returns one of a collection of handlers based on the type of the\nswitch object.\n\nThe first choice that `switchObject` can be casted to the type\nof argument it accepts will be called with `switchObject` casted to that\ntype, and the value it'll return will be returned by `castSwitch`.\n\nIf a choice's return type is void, the choice must throw an exception, unless\nall the choices are void. In that case, castSwitch itself will return void.\n\nThrows: If none of the choice matches, a `SwitchError` will be thrown.  $(D\nSwitchError) will also be thrown if not all the choices are void and a void\nchoice was executed without throwing anything.\n\nParams:\n    choices = The `choices` needs to be composed of function or delegate\n        handlers that accept one argument. There can also be a choice that\n        accepts zero arguments. That choice will be invoked if the $(D\n        switchObject) is null.\n    switchObject = the object against which the tests are being made.\n\nReturns:\n    The value of the selected choice.\n\nNote: `castSwitch` can only be used with object types.\n*/\nauto castSwitch(choices...)(Object switchObject)\n{\n    import core.exception : SwitchError;\n    import std.format : format;\n\n    // Check to see if all handlers return void.\n    enum areAllHandlersVoidResult = {\n        bool result = true;\n        foreach (index, choice; choices)\n        {\n            result &= is(ReturnType!choice == void);\n        }\n        return result;\n    }();\n\n    if (switchObject !is null)\n    {\n\n        // Checking for exact matches:\n        const classInfo = typeid(switchObject);\n        foreach (index, choice; choices)\n        {\n            static assert(isCallable!choice,\n                    \"A choice handler must be callable\");\n\n            alias choiceParameterTypes = Parameters!choice;\n            static assert(choiceParameterTypes.length <= 1,\n                    \"A choice handler can not have more than one argument.\");\n\n            static if (choiceParameterTypes.length == 1)\n            {\n                alias CastClass = choiceParameterTypes[0];\n                static assert(is(CastClass == class) || is(CastClass == interface),\n                        \"A choice handler can have only class or interface typed argument.\");\n\n                // Check for overshadowing:\n                immutable indexOfOvershadowingChoice =\n                    indexOfFirstOvershadowingChoiceOnLast!(choices[0 .. index + 1]);\n                static assert(indexOfOvershadowingChoice == index,\n                        \"choice number %d(type %s) is overshadowed by choice number %d(type %s)\".format(\n                            index + 1, CastClass.stringof, indexOfOvershadowingChoice + 1,\n                            Parameters!(choices[indexOfOvershadowingChoice])[0].stringof));\n\n                if (classInfo == typeid(CastClass))\n                {\n                    static if (is(ReturnType!(choice) == void))\n                    {\n                        choice(cast(CastClass) switchObject);\n                        static if (areAllHandlersVoidResult)\n                        {\n                            return;\n                        }\n                        else\n                        {\n                            throw new SwitchError(\"Handlers that return void should throw\");\n                        }\n                    }\n                    else\n                    {\n                        return choice(cast(CastClass) switchObject);\n                    }\n                }\n            }\n        }\n\n        // Checking for derived matches:\n        foreach (choice; choices)\n        {\n            alias choiceParameterTypes = Parameters!choice;\n            static if (choiceParameterTypes.length == 1)\n            {\n                if (auto castedObject = cast(choiceParameterTypes[0]) switchObject)\n                {\n                    static if (is(ReturnType!(choice) == void))\n                    {\n                        choice(castedObject);\n                        static if (areAllHandlersVoidResult)\n                        {\n                            return;\n                        }\n                        else\n                        {\n                            throw new SwitchError(\"Handlers that return void should throw\");\n                        }\n                    }\n                    else\n                    {\n                        return choice(castedObject);\n                    }\n                }\n            }\n        }\n    }\n    else // If switchObject is null:\n    {\n        // Checking for null matches:\n        foreach (index, choice; choices)\n        {\n            static if (Parameters!(choice).length == 0)\n            {\n                immutable indexOfOvershadowingChoice =\n                    indexOfFirstOvershadowingChoiceOnLast!(choices[0 .. index + 1]);\n\n                // Check for overshadowing:\n                static assert(indexOfOvershadowingChoice == index,\n                        \"choice number %d(null reference) is overshadowed by choice number %d(null reference)\".format(\n                            index + 1, indexOfOvershadowingChoice + 1));\n\n                if (switchObject is null)\n                {\n                    static if (is(ReturnType!(choice) == void))\n                    {\n                        choice();\n                        static if (areAllHandlersVoidResult)\n                        {\n                            return;\n                        }\n                        else\n                        {\n                            throw new SwitchError(\"Handlers that return void should throw\");\n                        }\n                    }\n                    else\n                    {\n                        return choice();\n                    }\n                }\n            }\n        }\n    }\n\n    // In case nothing matched:\n    throw new SwitchError(\"Input not matched by any choice\");\n}\n\n///\n@system unittest\n{\n    import std.algorithm.iteration : map;\n    import std.format : format;\n\n    class A\n    {\n        int a;\n        this(int a) {this.a = a;}\n        @property int i() { return a; }\n    }\n    interface I { }\n    class B : I { }\n\n    Object[] arr = [new A(1), new B(), null];\n\n    auto results = arr.map!(castSwitch!(\n                                (A a) => \"A with a value of %d\".format(a.a),\n                                (I i) => \"derived from I\",\n                                ()    => \"null reference\",\n                            ))();\n\n    // A is handled directly:\n    assert(results[0] == \"A with a value of 1\");\n    // B has no handler - it is handled by the handler of I:\n    assert(results[1] == \"derived from I\");\n    // null is handled by the null handler:\n    assert(results[2] == \"null reference\");\n}\n\n/// Using with void handlers:\n@system unittest\n{\n    import std.exception : assertThrown;\n\n    class A { }\n    class B { }\n    // Void handlers are allowed if they throw:\n    assertThrown!Exception(\n        new B().castSwitch!(\n            (A a) => 1,\n            (B d)    { throw new Exception(\"B is not allowed!\"); }\n        )()\n    );\n\n    // Void handlers are also allowed if all the handlers are void:\n    new A().castSwitch!(\n        (A a) { },\n        (B b) { assert(false); },\n    )();\n}\n\n@system unittest\n{\n    import core.exception : SwitchError;\n    import std.exception : assertThrown;\n\n    interface I { }\n    class A : I { }\n    class B { }\n\n    // Nothing matches:\n    assertThrown!SwitchError((new A()).castSwitch!(\n                                 (B b) => 1,\n                                 () => 2,\n                             )());\n\n    // Choices with multiple arguments are not allowed:\n    static assert(!__traits(compiles,\n                            (new A()).castSwitch!(\n                                (A a, B b) => 0,\n                            )()));\n\n    // Only callable handlers allowed:\n    static assert(!__traits(compiles,\n                            (new A()).castSwitch!(\n                                1234,\n                            )()));\n\n    // Only object arguments allowed:\n    static assert(!__traits(compiles,\n                            (new A()).castSwitch!(\n                                (int x) => 0,\n                            )()));\n\n    // Object overshadows regular classes:\n    static assert(!__traits(compiles,\n                            (new A()).castSwitch!(\n                                (Object o) => 0,\n                                (A a) => 1,\n                            )()));\n\n    // Object overshadows interfaces:\n    static assert(!__traits(compiles,\n                            (new A()).castSwitch!(\n                                (Object o) => 0,\n                                (I i) => 1,\n                            )()));\n\n    // No multiple null handlers allowed:\n    static assert(!__traits(compiles,\n                            (new A()).castSwitch!(\n                                () => 0,\n                                () => 1,\n                            )()));\n\n    // No non-throwing void handlers allowed(when there are non-void handlers):\n    assertThrown!SwitchError((new A()).castSwitch!(\n                                 (A a)    {},\n                                 (B b) => 2,\n                             )());\n\n    // All-void handlers work for the null case:\n    null.castSwitch!(\n        (Object o) { assert(false); },\n        ()         { },\n    )();\n\n    // Throwing void handlers work for the null case:\n    assertThrown!Exception(null.castSwitch!(\n                               (Object o) => 1,\n                               ()            { throw new Exception(\"null\"); },\n                           )());\n}\n\n@system unittest\n{\n    interface I { }\n    class B : I { }\n    class C : I { }\n\n    assert((new B()).castSwitch!(\n            (B b) => \"class B\",\n            (I i) => \"derived from I\",\n    ) == \"class B\");\n\n    assert((new C()).castSwitch!(\n            (B b) => \"class B\",\n            (I i) => \"derived from I\",\n    ) == \"derived from I\");\n}\n\n/** Clamps a value into the given bounds.\n\nThis functions is equivalent to `max(lower, min(upper,val))`.\n\nParams:\n    val = The value to _clamp.\n    lower = The _lower bound of the _clamp.\n    upper = The _upper bound of the _clamp.\n\nReturns:\n    Returns `val`, if it is between `lower` and `upper`.\n    Otherwise returns the nearest of the two.\n\n*/\nauto clamp(T1, T2, T3)(T1 val, T2 lower, T3 upper)\nin\n{\n    import std.functional : greaterThan;\n    assert(!lower.greaterThan(upper), \"Lower can't be greater than upper.\");\n}\ndo\n{\n    return max(lower, min(upper, val));\n}\n\n///\n@safe @betterC unittest\n{\n    assert(clamp(2, 1, 3) == 2);\n    assert(clamp(0, 1, 3) == 1);\n    assert(clamp(4, 1, 3) == 3);\n\n    assert(clamp(1, 1, 1) == 1);\n\n    assert(clamp(5, -1, 2u) == 2);\n}\n\n@safe unittest\n{\n    int a = 1;\n    short b = 6;\n    double c = 2;\n    static assert(is(typeof(clamp(c,a,b)) == double));\n    assert(clamp(c,   a, b) == c);\n    assert(clamp(a-c, a, b) == a);\n    assert(clamp(b+c, a, b) == b);\n    // mixed sign\n    a = -5;\n    uint f = 5;\n    static assert(is(typeof(clamp(f, a, b)) == int));\n    assert(clamp(f, a, b) == f);\n    // similar type deduction for (u)long\n    static assert(is(typeof(clamp(-1L, -2L, 2UL)) == long));\n\n    // user-defined types\n    import std.datetime : Date;\n    assert(clamp(Date(1982, 1, 4), Date(1012, 12, 21), Date(2012, 12, 21)) == Date(1982, 1, 4));\n    assert(clamp(Date(1982, 1, 4), Date.min, Date.max) == Date(1982, 1, 4));\n    // UFCS style\n    assert(Date(1982, 1, 4).clamp(Date.min, Date.max) == Date(1982, 1, 4));\n\n}\n\n// cmp\n/**********************************\nPerforms a lexicographical comparison on two\n$(REF_ALTTEXT input ranges, isInputRange, std,range,primitives).\nIterating `r1` and `r2` in lockstep, `cmp` compares each element\n`e1` of `r1` with the corresponding element `e2` in `r2`. If one\nof the ranges has been finished, `cmp` returns a negative value\nif `r1` has fewer elements than `r2`, a positive value if `r1`\nhas more elements than `r2`, and `0` if the ranges have the same\nnumber of elements.\n\nIf the ranges are strings, `cmp` performs UTF decoding\nappropriately and compares the ranges one code point at a time.\n\nA custom predicate may be specified, in which case `cmp` performs\na three-way lexicographical comparison using `pred`. Otherwise\nthe elements are compared using `opCmp`.\n\nParams:\n    pred = Predicate used for comparison. Without a predicate\n        specified the ordering implied by `opCmp` is used.\n    r1 = The first range.\n    r2 = The second range.\n\nReturns:\n    `0` if the ranges compare equal. A negative value if `r1` is a prefix of `r2` or\n    the first differing element of `r1` is less than the corresponding element of `r2`\n    according to `pred`. A positive value if `r2` is a prefix of `r1` or the first\n    differing element of `r2` is less than the corresponding element of `r1`\n    according to `pred`.\n\nNote:\n    An earlier version of the documentation incorrectly stated that `-1` is the\n    only negative value returned and `1` is the only positive value returned.\n    Whether that is true depends on the types being compared.\n*/\nauto cmp(R1, R2)(R1 r1, R2 r2)\nif (isInputRange!R1 && isInputRange!R2)\n{\n    static if (!(isSomeString!R1 && isSomeString!R2))\n    {\n        for (;; r1.popFront(), r2.popFront())\n        {\n            static if (is(typeof(r1.front.opCmp(r2.front)) R))\n                alias Result = R;\n            else\n                alias Result = int;\n            if (r2.empty) return Result(!r1.empty);\n            if (r1.empty) return Result(-1);\n            static if (is(typeof(r1.front.opCmp(r2.front))))\n            {\n                auto c = r1.front.opCmp(r2.front);\n                if (c != 0) return c;\n            }\n            else\n            {\n                auto a = r1.front, b = r2.front;\n                if (a < b) return -1;\n                if (b < a) return 1;\n            }\n        }\n    }\n    else\n    {\n        import core.stdc.string : memcmp;\n        import std.utf : decode;\n\n        // For speed only\n        static int threeWay(size_t a, size_t b)\n        {\n            static if (size_t.sizeof == int.sizeof)\n                return a - b;\n            else\n                // Faster than return b < a ? 1 : a < b ? -1 : 0;\n                return (a > b) - (a < b);\n        }\n        // For speed only\n        // @@@BUG@@@ overloading should be allowed for nested functions\n        static int threeWayInt(int a, int b)\n        {\n            return a - b;\n        }\n\n        static if (typeof(r1[0]).sizeof == typeof(r2[0]).sizeof)\n        {\n            static if (typeof(r1[0]).sizeof == 1)\n            {\n                immutable len = min(r1.length, r2.length);\n                int result = __ctfe ?\n                    {\n                        foreach (i; 0 .. len)\n                        {\n                            if (r1[i] != r2[i])\n                                return threeWayInt(r1[i], r2[i]);\n                        }\n                        return 0;\n                    }()\n                    : () @trusted { return memcmp(r1.ptr, r2.ptr, len); }();\n                if (result) return result;\n                return threeWay(r1.length, r2.length);\n            }\n            else\n            {\n                return () @trusted\n                {\n                    auto p1 = r1.ptr, p2 = r2.ptr,\n                        pEnd = p1 + min(r1.length, r2.length);\n                    for (; p1 != pEnd; ++p1, ++p2)\n                    {\n                        if (*p1 != *p2) return threeWayInt(int(*p1), int(*p2));\n                    }\n                    return threeWay(r1.length, r2.length);\n                }();\n            }\n        }\n        else\n        {\n            for (size_t i1, i2;;)\n            {\n                if (i1 == r1.length) return threeWay(i2, r2.length);\n                if (i2 == r2.length) return threeWay(r1.length, i1);\n                immutable c1 = decode(r1, i1),\n                    c2 = decode(r2, i2);\n                if (c1 != c2) return threeWayInt(int(c1), int(c2));\n            }\n        }\n    }\n}\n\n/// ditto\nint cmp(alias pred, R1, R2)(R1 r1, R2 r2)\nif (isInputRange!R1 && isInputRange!R2)\n{\n    static if (!(isSomeString!R1 && isSomeString!R2))\n    {\n        for (;; r1.popFront(), r2.popFront())\n        {\n            if (r2.empty) return !r1.empty;\n            if (r1.empty) return -1;\n            auto a = r1.front, b = r2.front;\n            if (binaryFun!pred(a, b)) return -1;\n            if (binaryFun!pred(b, a)) return 1;\n        }\n    }\n    else\n    {\n        import std.utf : decode;\n\n        // For speed only\n        static int threeWayCompareLength(size_t a, size_t b)\n        {\n            static if (size_t.sizeof == int.sizeof)\n                return a - b;\n            else\n                // Faster than return b < a ? 1 : a < b ? -1 : 0;\n                return (a > b) - (a < b);\n        }\n\n        for (size_t i1, i2;;)\n        {\n            if (i1 == r1.length) return threeWayCompareLength(i2, r2.length);\n            if (i2 == r2.length) return threeWayCompareLength(r1.length, i1);\n            immutable c1 = decode(r1, i1),\n                c2 = decode(r2, i2);\n            if (c1 != c2)\n            {\n                if (binaryFun!pred(c2, c1)) return 1;\n                if (binaryFun!pred(c1, c2)) return -1;\n            }\n        }\n    }\n}\n\n///\npure @safe unittest\n{\n    int result;\n\n    result = cmp(\"abc\", \"abc\");\n    assert(result == 0);\n    result = cmp(\"\", \"\");\n    assert(result == 0);\n    result = cmp(\"abc\", \"abcd\");\n    assert(result < 0);\n    result = cmp(\"abcd\", \"abc\");\n    assert(result > 0);\n    result = cmp(\"abc\"d, \"abd\");\n    assert(result < 0);\n    result = cmp(\"bbc\", \"abc\"w);\n    assert(result > 0);\n    result = cmp(\"aaa\", \"aaaa\"d);\n    assert(result < 0);\n    result = cmp(\"aaaa\", \"aaa\"d);\n    assert(result > 0);\n    result = cmp(\"aaa\", \"aaa\"d);\n    assert(result == 0);\n    result = cmp(\"aaa\"d, \"aaa\"d);\n    assert(result == 0);\n    result = cmp(cast(int[])[], cast(int[])[]);\n    assert(result == 0);\n    result = cmp([1, 2, 3], [1, 2, 3]);\n    assert(result == 0);\n    result = cmp([1, 3, 2], [1, 2, 3]);\n    assert(result > 0);\n    result = cmp([1, 2, 3], [1L, 2, 3, 4]);\n    assert(result < 0);\n    result = cmp([1L, 2, 3], [1, 2]);\n    assert(result > 0);\n}\n\n/// Example predicate that compares individual elements in reverse lexical order\npure @safe unittest\n{\n    int result;\n\n    result = cmp!\"a > b\"(\"abc\", \"abc\");\n    assert(result == 0);\n    result = cmp!\"a > b\"(\"\", \"\");\n    assert(result == 0);\n    result = cmp!\"a > b\"(\"abc\", \"abcd\");\n    assert(result < 0);\n    result = cmp!\"a > b\"(\"abcd\", \"abc\");\n    assert(result > 0);\n    result = cmp!\"a > b\"(\"abc\"d, \"abd\");\n    assert(result > 0);\n    result = cmp!\"a > b\"(\"bbc\", \"abc\"w);\n    assert(result < 0);\n    result = cmp!\"a > b\"(\"aaa\", \"aaaa\"d);\n    assert(result < 0);\n    result = cmp!\"a > b\"(\"aaaa\", \"aaa\"d);\n    assert(result > 0);\n    result = cmp!\"a > b\"(\"aaa\", \"aaa\"d);\n    assert(result == 0);\n    result = cmp(\"aaa\"d, \"aaa\"d);\n    assert(result == 0);\n    result = cmp!\"a > b\"(cast(int[])[], cast(int[])[]);\n    assert(result == 0);\n    result = cmp!\"a > b\"([1, 2, 3], [1, 2, 3]);\n    assert(result == 0);\n    result = cmp!\"a > b\"([1, 3, 2], [1, 2, 3]);\n    assert(result < 0);\n    result = cmp!\"a > b\"([1, 2, 3], [1L, 2, 3, 4]);\n    assert(result < 0);\n    result = cmp!\"a > b\"([1L, 2, 3], [1, 2]);\n    assert(result > 0);\n}\n\n@nogc nothrow pure @safe unittest\n{\n    // Issue 18286: cmp for string with custom predicate fails if distinct chars can compare equal\n    static bool ltCi(dchar a, dchar b)// less than, case insensitive\n    {\n        import std.ascii : toUpper;\n        return toUpper(a) < toUpper(b);\n    }\n    static assert(cmp!ltCi(\"apple2\", \"APPLE1\") > 0);\n    static assert(cmp!ltCi(\"apple1\", \"APPLE2\") < 0);\n    static assert(cmp!ltCi(\"apple\", \"APPLE1\") < 0);\n    static assert(cmp!ltCi(\"APPLE\", \"apple1\") < 0);\n    static assert(cmp!ltCi(\"apple\", \"APPLE\") == 0);\n}\n\n@nogc nothrow @safe unittest\n{\n    // Issue 18280: for non-string ranges check that opCmp is evaluated only once per pair.\n    static int ctr = 0;\n    struct S\n    {\n        int opCmp(ref const S rhs) const\n        {\n            ++ctr;\n            return 0;\n        }\n        bool opEquals(T)(T o) const { return false; }\n        size_t toHash() const { return 0; }\n    }\n    immutable S[4] a;\n    immutable S[4] b;\n    immutable result = cmp(a[], b[]);\n    assert(result == 0, \"neither should compare greater than the other!\");\n    assert(ctr == a.length, \"opCmp should be called exactly once per pair of items!\");\n}\n\nnothrow pure @safe unittest\n{\n    // Test cmp when opCmp returns float.\n    struct F\n    {\n        float value;\n        float opCmp(const ref F rhs) const\n        {\n            return value - rhs.value;\n        }\n        bool opEquals(T)(T o) const { return false; }\n        size_t toHash() const { return 0; }\n    }\n    auto result = cmp([F(1), F(2), F(3)], [F(1), F(2), F(3)]);\n    assert(result == 0);\n    assert(is(typeof(result) == float));\n    result = cmp([F(1), F(3), F(2)], [F(1), F(2), F(3)]);\n    assert(result > 0);\n    result = cmp([F(1), F(2), F(3)], [F(1), F(2), F(3), F(4)]);\n    assert(result < 0);\n    result = cmp([F(1), F(2), F(3)], [F(1), F(2)]);\n    assert(result > 0);\n}\n\nnothrow pure @safe unittest\n{\n    // Parallelism (was broken by inferred return type \"immutable int\")\n    import std.parallelism : task;\n    auto t = task!cmp(\"foo\", \"bar\");\n}\n\n// equal\n/**\nCompares two ranges for equality, as defined by predicate `pred`\n(which is `==` by default).\n*/\ntemplate equal(alias pred = \"a == b\")\n{\n    enum isEmptyRange(R) =\n        isInputRange!R && __traits(compiles, {static assert(R.empty, \"\");});\n\n    enum hasFixedLength(T) = hasLength!T || isNarrowString!T;\n\n    /++\n    Compares two ranges for equality. The ranges may have\n    different element types, as long as `pred(r1.front, r2.front)`\n    evaluates to `bool`.\n    Performs $(BIGOH min(r1.length, r2.length)) evaluations of `pred`.\n\n    Params:\n        r1 = The first range to be compared.\n        r2 = The second range to be compared.\n\n    Returns:\n        `true` if and only if the two ranges compare _equal element\n        for element, according to binary predicate `pred`.\n    +/\n    bool equal(Range1, Range2)(Range1 r1, Range2 r2)\n    if (isInputRange!Range1 && isInputRange!Range2 &&\n        is(typeof(binaryFun!pred(r1.front, r2.front))))\n    {\n        static assert(!(isInfinite!Range1 && isInfinite!Range2),\n            \"Both ranges are known to be infinite\");\n\n        //No pred calls necessary\n        static if (isEmptyRange!Range1 || isEmptyRange!Range2)\n        {\n            return r1.empty && r2.empty;\n        }\n        else static if ((isInfinite!Range1 && hasFixedLength!Range2) ||\n            (hasFixedLength!Range1 && isInfinite!Range2))\n        {\n            return false;\n        }\n        //Detect default pred and compatible dynamic array\n        else static if (is(typeof(pred) == string) && pred == \"a == b\" &&\n            isArray!Range1 && isArray!Range2 && is(typeof(r1 == r2)))\n        {\n            return r1 == r2;\n        }\n        // if one of the arguments is a string and the other isn't, then auto-decoding\n        // can be avoided if they have the same ElementEncodingType\n        else static if (is(typeof(pred) == string) && pred == \"a == b\" &&\n            isAutodecodableString!Range1 != isAutodecodableString!Range2 &&\n            is(ElementEncodingType!Range1 == ElementEncodingType!Range2))\n        {\n            import std.utf : byCodeUnit;\n\n            static if (isAutodecodableString!Range1)\n            {\n                return equal(r1.byCodeUnit, r2);\n            }\n            else\n            {\n                return equal(r2.byCodeUnit, r1);\n            }\n        }\n        //Try a fast implementation when the ranges have comparable lengths\n        else static if (hasLength!Range1 && hasLength!Range2 && is(typeof(r1.length == r2.length)))\n        {\n            immutable len1 = r1.length;\n            immutable len2 = r2.length;\n            if (len1 != len2) return false; //Short circuit return\n\n            //Lengths are the same, so we need to do an actual comparison\n            //Good news is we can squeeze out a bit of performance by not checking if r2 is empty\n            for (; !r1.empty; r1.popFront(), r2.popFront())\n            {\n                if (!binaryFun!(pred)(r1.front, r2.front)) return false;\n            }\n            return true;\n        }\n        else\n        {\n            //Generic case, we have to walk both ranges making sure neither is empty\n            for (; !r1.empty; r1.popFront(), r2.popFront())\n            {\n                if (r2.empty) return false;\n                if (!binaryFun!(pred)(r1.front, r2.front)) return false;\n            }\n            static if (!isInfinite!Range1)\n                return r2.empty;\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.math : approxEqual;\n\n    int[] a = [ 1, 2, 4, 3 ];\n    assert(!equal(a, a[1..$]));\n    assert(equal(a, a));\n    assert(equal!((a, b) => a == b)(a, a));\n\n    // different types\n    double[] b = [ 1.0, 2, 4, 3];\n    assert(!equal(a, b[1..$]));\n    assert(equal(a, b));\n\n    // predicated: ensure that two vectors are approximately equal\n    double[] c = [ 1.005, 2, 4, 3];\n    assert(equal!approxEqual(b, c));\n}\n\n/++\nTip: `equal` can itself be used as a predicate to other functions.\nThis can be very useful when the element type of a range is itself a\nrange. In particular, `equal` can be its own predicate, allowing\nrange of range (of range...) comparisons.\n +/\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota, chunks;\n    assert(equal!(equal!equal)(\n        [[[0, 1], [2, 3]], [[4, 5], [6, 7]]],\n        iota(0, 8).chunks(2).chunks(2)\n    ));\n}\n\n@safe unittest\n{\n    import std.algorithm.iteration : map;\n    import std.internal.test.dummyrange : ReferenceForwardRange,\n        ReferenceInputRange, ReferenceInfiniteForwardRange;\n    import std.math : approxEqual;\n\n    // various strings\n    assert(equal(\"æøå\", \"æøå\")); //UTF8 vs UTF8\n    assert(!equal(\"???\", \"æøå\")); //UTF8 vs UTF8\n    assert(equal(\"æøå\"w, \"æøå\"d)); //UTF16 vs UTF32\n    assert(!equal(\"???\"w, \"æøå\"d));//UTF16 vs UTF32\n    assert(equal(\"æøå\"d, \"æøå\"d)); //UTF32 vs UTF32\n    assert(!equal(\"???\"d, \"æøå\"d));//UTF32 vs UTF32\n    assert(!equal(\"hello\", \"world\"));\n\n    // same strings, but \"explicit non default\" comparison (to test the non optimized array comparison)\n    assert( equal!(\"a == b\")(\"æøå\", \"æøå\")); //UTF8 vs UTF8\n    assert(!equal!(\"a == b\")(\"???\", \"æøå\")); //UTF8 vs UTF8\n    assert( equal!(\"a == b\")(\"æøå\"w, \"æøå\"d)); //UTF16 vs UTF32\n    assert(!equal!(\"a == b\")(\"???\"w, \"æøå\"d));//UTF16 vs UTF32\n    assert( equal!(\"a == b\")(\"æøå\"d, \"æøå\"d)); //UTF32 vs UTF32\n    assert(!equal!(\"a == b\")(\"???\"d, \"æøå\"d));//UTF32 vs UTF32\n    assert(!equal!(\"a == b\")(\"hello\", \"world\"));\n\n    //Array of string\n    assert(equal([\"hello\", \"world\"], [\"hello\", \"world\"]));\n    assert(!equal([\"hello\", \"world\"], [\"hello\"]));\n    assert(!equal([\"hello\", \"world\"], [\"hello\", \"Bob!\"]));\n\n    //Should not compile, because \"string == dstring\" is illegal\n    static assert(!is(typeof(equal([\"hello\", \"world\"], [\"hello\"d, \"world\"d]))));\n    //However, arrays of non-matching string can be compared using equal!equal. Neat-o!\n    equal!equal([\"hello\", \"world\"], [\"hello\"d, \"world\"d]);\n\n    //Tests, with more fancy map ranges\n    int[] a = [ 1, 2, 4, 3 ];\n    assert(equal([2, 4, 8, 6], map!\"a*2\"(a)));\n    double[] b = [ 1.0, 2, 4, 3];\n    double[] c = [ 1.005, 2, 4, 3];\n    assert(equal!approxEqual(map!\"a*2\"(b), map!\"a*2\"(c)));\n    assert(!equal([2, 4, 1, 3], map!\"a*2\"(a)));\n    assert(!equal([2, 4, 1], map!\"a*2\"(a)));\n    assert(!equal!approxEqual(map!\"a*3\"(b), map!\"a*2\"(c)));\n\n    //Tests with some fancy reference ranges.\n    ReferenceInputRange!int cir = new ReferenceInputRange!int([1, 2, 4, 3]);\n    ReferenceForwardRange!int cfr = new ReferenceForwardRange!int([1, 2, 4, 3]);\n    assert(equal(cir, a));\n    cir = new ReferenceInputRange!int([1, 2, 4, 3]);\n    assert(equal(cir, cfr.save));\n    assert(equal(cfr.save, cfr.save));\n    cir = new ReferenceInputRange!int([1, 2, 8, 1]);\n    assert(!equal(cir, cfr));\n\n    //Test with an infinite range\n    auto ifr = new ReferenceInfiniteForwardRange!int;\n    assert(!equal(a, ifr));\n    assert(!equal(ifr, a));\n    //Test InputRange without length\n    assert(!equal(ifr, cir));\n    assert(!equal(cir, ifr));\n}\n\n@safe pure unittest\n{\n    import std.utf : byChar, byWchar, byDchar;\n\n    assert(equal(\"æøå\".byChar, \"æøå\"));\n    assert(equal(\"æøå\", \"æøå\".byChar));\n    assert(equal(\"æøå\".byWchar, \"æøå\"w));\n    assert(equal(\"æøå\"w, \"æøå\".byWchar));\n    assert(equal(\"æøå\".byDchar, \"æøå\"d));\n    assert(equal(\"æøå\"d, \"æøå\".byDchar));\n}\n\n@safe pure unittest\n{\n    struct R(bool _empty) {\n        enum empty = _empty;\n        @property char front(){assert(0);}\n        void popFront(){assert(0);}\n    }\n    alias I = R!false;\n    static assert(!__traits(compiles, I().equal(I())));\n    // strings have fixed length so don't need to compare elements\n    assert(!I().equal(\"foo\"));\n    assert(!\"bar\".equal(I()));\n\n    alias E = R!true;\n    assert(E().equal(E()));\n    assert(E().equal(\"\"));\n    assert(\"\".equal(E()));\n    assert(!E().equal(\"foo\"));\n    assert(!\"bar\".equal(E()));\n}\n\n// MaxType\nprivate template MaxType(T...)\nif (T.length >= 1)\n{\n    static if (T.length == 1)\n    {\n        alias MaxType = T[0];\n    }\n    else static if (T.length == 2)\n    {\n        static if (!is(typeof(T[0].min)))\n            alias MaxType = CommonType!T;\n        else static if (T[1].max > T[0].max)\n            alias MaxType = T[1];\n        else\n            alias MaxType = T[0];\n    }\n    else\n    {\n        alias MaxType = MaxType!(MaxType!(T[0 .. ($+1)/2]), MaxType!(T[($+1)/2 .. $]));\n    }\n}\n\n// levenshteinDistance\n/**\nEncodes $(HTTP realityinteractive.com/rgrzywinski/archives/000249.html,\nedit operations) necessary to transform one sequence into\nanother. Given sequences `s` (source) and `t` (target), a\nsequence of `EditOp` encodes the steps that need to be taken to\nconvert `s` into `t`. For example, if `s = \"cat\"` and $(D\n\"cars\"), the minimal sequence that transforms `s` into `t` is:\nskip two characters, replace 't' with 'r', and insert an 's'. Working\nwith edit operations is useful in applications such as spell-checkers\n(to find the closest word to a given misspelled word), approximate\nsearches, diff-style programs that compute the difference between\nfiles, efficient encoding of patches, DNA sequence analysis, and\nplagiarism detection.\n*/\n\nenum EditOp : char\n{\n    /** Current items are equal; no editing is necessary. */\n    none = 'n',\n    /** Substitute current item in target with current item in source. */\n    substitute = 's',\n    /** Insert current item from the source into the target. */\n    insert = 'i',\n    /** Remove current item from the target. */\n    remove = 'r'\n}\n\n///\n@safe unittest\n{\n    with(EditOp)\n    {\n        assert(levenshteinDistanceAndPath(\"foo\", \"foobar\")[1] == [none, none, none, insert, insert, insert]);\n        assert(levenshteinDistanceAndPath(\"banana\", \"fazan\")[1] == [substitute, none, substitute, none, none, remove]);\n    }\n}\n\nprivate struct Levenshtein(Range, alias equals, CostType = size_t)\n{\n    EditOp[] path()\n    {\n        import std.algorithm.mutation : reverse;\n\n        EditOp[] result;\n        size_t i = rows - 1, j = cols - 1;\n        // restore the path\n        while (i || j)\n        {\n            auto cIns = j == 0 ? CostType.max : matrix(i,j - 1);\n            auto cDel = i == 0 ? CostType.max : matrix(i - 1,j);\n            auto cSub = i == 0 || j == 0\n                ? CostType.max\n                : matrix(i - 1,j - 1);\n            switch (min_index(cSub, cIns, cDel))\n            {\n            case 0:\n                result ~= matrix(i - 1,j - 1) == matrix(i,j)\n                    ? EditOp.none\n                    : EditOp.substitute;\n                --i;\n                --j;\n                break;\n            case 1:\n                result ~= EditOp.insert;\n                --j;\n                break;\n            default:\n                result ~= EditOp.remove;\n                --i;\n                break;\n            }\n        }\n        reverse(result);\n        return result;\n    }\n\n    ~this() {\n        FreeMatrix();\n    }\n\nprivate:\n    CostType _deletionIncrement = 1,\n        _insertionIncrement = 1,\n        _substitutionIncrement = 1;\n    CostType[] _matrix;\n    size_t rows, cols;\n\n    // Treat _matrix as a rectangular array\n    ref CostType matrix(size_t row, size_t col) { return _matrix[row * cols + col]; }\n\n    void AllocMatrix(size_t r, size_t c) @trusted {\n        import core.checkedint : mulu;\n        bool overflow;\n        const rc = mulu(r, c, overflow);\n        if (overflow) assert(0);\n        rows = r;\n        cols = c;\n        if (_matrix.length < rc)\n        {\n            import core.exception : onOutOfMemoryError;\n            import core.stdc.stdlib : realloc;\n            const nbytes = mulu(rc, _matrix[0].sizeof, overflow);\n            if (overflow) assert(0);\n            auto m = cast(CostType *) realloc(_matrix.ptr, nbytes);\n            if (!m)\n                onOutOfMemoryError();\n            _matrix = m[0 .. r * c];\n            InitMatrix();\n        }\n    }\n\n    void FreeMatrix() @trusted {\n        import core.stdc.stdlib : free;\n\n        free(_matrix.ptr);\n        _matrix = null;\n    }\n\n    void InitMatrix() {\n        foreach (r; 0 .. rows)\n            matrix(r,0) = r * _deletionIncrement;\n        foreach (c; 0 .. cols)\n            matrix(0,c) = c * _insertionIncrement;\n    }\n\n    static uint min_index(CostType i0, CostType i1, CostType i2)\n    {\n        if (i0 <= i1)\n        {\n            return i0 <= i2 ? 0 : 2;\n        }\n        else\n        {\n            return i1 <= i2 ? 1 : 2;\n        }\n    }\n\n    CostType distanceWithPath(Range s, Range t)\n    {\n        auto slen = walkLength(s.save), tlen = walkLength(t.save);\n        AllocMatrix(slen + 1, tlen + 1);\n        foreach (i; 1 .. rows)\n        {\n            auto sfront = s.front;\n            auto tt = t.save;\n            foreach (j; 1 .. cols)\n            {\n                auto cSub = matrix(i - 1,j - 1)\n                    + (equals(sfront, tt.front) ? 0 : _substitutionIncrement);\n                tt.popFront();\n                auto cIns = matrix(i,j - 1) + _insertionIncrement;\n                auto cDel = matrix(i - 1,j) + _deletionIncrement;\n                switch (min_index(cSub, cIns, cDel))\n                {\n                case 0:\n                    matrix(i,j) = cSub;\n                    break;\n                case 1:\n                    matrix(i,j) = cIns;\n                    break;\n                default:\n                    matrix(i,j) = cDel;\n                    break;\n                }\n            }\n            s.popFront();\n        }\n        return matrix(slen,tlen);\n    }\n\n    CostType distanceLowMem(Range s, Range t, CostType slen, CostType tlen)\n    {\n        CostType lastdiag, olddiag;\n        AllocMatrix(slen + 1, 1);\n        foreach (y; 1 .. slen + 1)\n        {\n            _matrix[y] = y;\n        }\n        foreach (x; 1 .. tlen + 1)\n        {\n            auto tfront = t.front;\n            auto ss = s.save;\n            _matrix[0] = x;\n            lastdiag = x - 1;\n            foreach (y; 1 .. rows)\n            {\n                olddiag = _matrix[y];\n                auto cSub = lastdiag + (equals(ss.front, tfront) ? 0 : _substitutionIncrement);\n                ss.popFront();\n                auto cIns = _matrix[y - 1] + _insertionIncrement;\n                auto cDel = _matrix[y] + _deletionIncrement;\n                switch (min_index(cSub, cIns, cDel))\n                {\n                case 0:\n                    _matrix[y] = cSub;\n                    break;\n                case 1:\n                    _matrix[y] = cIns;\n                    break;\n                default:\n                    _matrix[y] = cDel;\n                    break;\n                }\n                lastdiag = olddiag;\n            }\n            t.popFront();\n        }\n        return _matrix[slen];\n    }\n}\n\n/**\nReturns the $(HTTP wikipedia.org/wiki/Levenshtein_distance, Levenshtein\ndistance) between `s` and `t`. The Levenshtein distance computes\nthe minimal amount of edit operations necessary to transform `s`\ninto `t`.  Performs $(BIGOH s.length * t.length) evaluations of $(D\nequals) and occupies $(BIGOH s.length * t.length) storage.\n\nParams:\n    equals = The binary predicate to compare the elements of the two ranges.\n    s = The original range.\n    t = The transformation target\n\nReturns:\n    The minimal number of edits to transform s into t.\n\nDoes not allocate GC memory.\n*/\nsize_t levenshteinDistance(alias equals = (a,b) => a == b, Range1, Range2)\n    (Range1 s, Range2 t)\nif (isForwardRange!(Range1) && isForwardRange!(Range2))\n{\n    alias eq = binaryFun!(equals);\n\n    for (;;)\n    {\n        if (s.empty) return t.walkLength;\n        if (t.empty) return s.walkLength;\n        if (eq(s.front, t.front))\n        {\n            s.popFront();\n            t.popFront();\n            continue;\n        }\n        static if (isBidirectionalRange!(Range1) && isBidirectionalRange!(Range2))\n        {\n            if (eq(s.back, t.back))\n            {\n                s.popBack();\n                t.popBack();\n                continue;\n            }\n        }\n        break;\n    }\n\n    auto slen = walkLength(s.save);\n    auto tlen = walkLength(t.save);\n\n    if (slen == 1 && tlen == 1)\n    {\n        return eq(s.front, t.front) ? 0 : 1;\n    }\n\n    if (slen > tlen)\n    {\n        Levenshtein!(Range1, eq, size_t) lev;\n        return lev.distanceLowMem(s, t, slen, tlen);\n    }\n    else\n    {\n        Levenshtein!(Range2, eq, size_t) lev;\n        return lev.distanceLowMem(t, s, tlen, slen);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.iteration : filter;\n    import std.uni : toUpper;\n\n    assert(levenshteinDistance(\"cat\", \"rat\") == 1);\n    assert(levenshteinDistance(\"parks\", \"spark\") == 2);\n    assert(levenshteinDistance(\"abcde\", \"abcde\") == 0);\n    assert(levenshteinDistance(\"abcde\", \"abCde\") == 1);\n    assert(levenshteinDistance(\"kitten\", \"sitting\") == 3);\n    assert(levenshteinDistance!((a, b) => toUpper(a) == toUpper(b))\n        (\"parks\", \"SPARK\") == 2);\n    assert(levenshteinDistance(\"parks\".filter!\"true\", \"spark\".filter!\"true\") == 2);\n    assert(levenshteinDistance(\"ID\", \"I♥D\") == 1);\n}\n\n@safe @nogc nothrow unittest\n{\n    assert(levenshteinDistance(\"cat\"d, \"rat\"d) == 1);\n}\n\n/// ditto\nsize_t levenshteinDistance(alias equals = (a,b) => a == b, Range1, Range2)\n    (auto ref Range1 s, auto ref Range2 t)\nif (isConvertibleToString!Range1 || isConvertibleToString!Range2)\n{\n    import std.meta : staticMap;\n    alias Types = staticMap!(convertToString, Range1, Range2);\n    return levenshteinDistance!(equals, Types)(s, t);\n}\n\n@safe unittest\n{\n    static struct S { string s; alias s this; }\n    assert(levenshteinDistance(S(\"cat\"), S(\"rat\")) == 1);\n    assert(levenshteinDistance(\"cat\", S(\"rat\")) == 1);\n    assert(levenshteinDistance(S(\"cat\"), \"rat\") == 1);\n}\n\n@safe @nogc nothrow unittest\n{\n    static struct S { dstring s; alias s this; }\n    assert(levenshteinDistance(S(\"cat\"d), S(\"rat\"d)) == 1);\n    assert(levenshteinDistance(\"cat\"d, S(\"rat\"d)) == 1);\n    assert(levenshteinDistance(S(\"cat\"d), \"rat\"d) == 1);\n}\n\n/**\nReturns the Levenshtein distance and the edit path between `s` and\n`t`.\n\nParams:\n    equals = The binary predicate to compare the elements of the two ranges.\n    s = The original range.\n    t = The transformation target\n\nReturns:\n    Tuple with the first element being the minimal amount of edits to transform s into t and\n    the second element being the sequence of edits to effect this transformation.\n\nAllocates GC memory for the returned EditOp[] array.\n*/\nTuple!(size_t, EditOp[])\nlevenshteinDistanceAndPath(alias equals = (a,b) => a == b, Range1, Range2)\n    (Range1 s, Range2 t)\nif (isForwardRange!(Range1) && isForwardRange!(Range2))\n{\n    Levenshtein!(Range1, binaryFun!(equals)) lev;\n    auto d = lev.distanceWithPath(s, t);\n    return tuple(d, lev.path());\n}\n\n///\n@safe unittest\n{\n    string a = \"Saturday\", b = \"Sundays\";\n    auto p = levenshteinDistanceAndPath(a, b);\n    assert(p[0] == 4);\n    assert(equal(p[1], \"nrrnsnnni\"));\n}\n\n@safe unittest\n{\n    assert(levenshteinDistance(\"a\", \"a\") == 0);\n    assert(levenshteinDistance(\"a\", \"b\") == 1);\n    assert(levenshteinDistance(\"aa\", \"ab\") == 1);\n    assert(levenshteinDistance(\"aa\", \"abc\") == 2);\n    assert(levenshteinDistance(\"Saturday\", \"Sunday\") == 3);\n    assert(levenshteinDistance(\"kitten\", \"sitting\") == 3);\n}\n\n/// ditto\nTuple!(size_t, EditOp[])\nlevenshteinDistanceAndPath(alias equals = (a,b) => a == b, Range1, Range2)\n    (auto ref Range1 s, auto ref Range2 t)\nif (isConvertibleToString!Range1 || isConvertibleToString!Range2)\n{\n    import std.meta : staticMap;\n    alias Types = staticMap!(convertToString, Range1, Range2);\n    return levenshteinDistanceAndPath!(equals, Types)(s, t);\n}\n\n@safe unittest\n{\n    static struct S { string s; alias s this; }\n    assert(levenshteinDistanceAndPath(S(\"cat\"), S(\"rat\"))[0] == 1);\n    assert(levenshteinDistanceAndPath(\"cat\", S(\"rat\"))[0] == 1);\n    assert(levenshteinDistanceAndPath(S(\"cat\"), \"rat\")[0] == 1);\n}\n\n// max\n/**\nIterates the passed arguments and return the maximum value.\n\nParams:\n    args = The values to select the maximum from. At least two arguments must\n    be passed.\n\nReturns:\n    The maximum of the passed-in args. The type of the returned value is\n    the type among the passed arguments that is able to store the largest value.\n\nSee_Also:\n    $(REF maxElement, std,algorithm,searching)\n*/\nMaxType!T max(T...)(T args)\nif (T.length >= 2)\n{\n    //Get \"a\"\n    static if (T.length <= 2)\n        alias a = args[0];\n    else\n        auto a = max(args[0 .. ($+1)/2]);\n    alias T0 = typeof(a);\n\n    //Get \"b\"\n    static if (T.length <= 3)\n        alias b = args[$-1];\n    else\n        auto b = max(args[($+1)/2 .. $]);\n    alias T1 = typeof(b);\n\n    import std.algorithm.internal : algoFormat;\n    static assert(is(typeof(a < b)),\n        algoFormat(\"Invalid arguments: Cannot compare types %s and %s.\", T0.stringof, T1.stringof));\n\n    //Do the \"max\" proper with a and b\n    import std.functional : lessThan;\n    immutable chooseB = lessThan!(T0, T1)(a, b);\n    return cast(typeof(return)) (chooseB ? b : a);\n}\n\n///\n@safe @betterC unittest\n{\n    int a = 5;\n    short b = 6;\n    double c = 2;\n    auto d = max(a, b);\n    assert(is(typeof(d) == int));\n    assert(d == 6);\n    auto e = min(a, b, c);\n    assert(is(typeof(e) == double));\n    assert(e == 2);\n}\n\n@safe unittest\n{\n    int a = 5;\n    short b = 6;\n    double c = 2;\n    auto d = max(a, b);\n    static assert(is(typeof(d) == int));\n    assert(d == 6);\n    auto e = max(a, b, c);\n    static assert(is(typeof(e) == double));\n    assert(e == 6);\n    // mixed sign\n    a = -5;\n    uint f = 5;\n    static assert(is(typeof(max(a, f)) == uint));\n    assert(max(a, f) == 5);\n\n    //Test user-defined types\n    import std.datetime : Date;\n    assert(max(Date(2012, 12, 21), Date(1982, 1, 4)) == Date(2012, 12, 21));\n    assert(max(Date(1982, 1, 4), Date(2012, 12, 21)) == Date(2012, 12, 21));\n    assert(max(Date(1982, 1, 4), Date.min) == Date(1982, 1, 4));\n    assert(max(Date.min, Date(1982, 1, 4)) == Date(1982, 1, 4));\n    assert(max(Date(1982, 1, 4), Date.max) == Date.max);\n    assert(max(Date.max, Date(1982, 1, 4)) == Date.max);\n    assert(max(Date.min, Date.max) == Date.max);\n    assert(max(Date.max, Date.min) == Date.max);\n}\n\n// MinType\nprivate template MinType(T...)\nif (T.length >= 1)\n{\n    static if (T.length == 1)\n    {\n        alias MinType = T[0];\n    }\n    else static if (T.length == 2)\n    {\n        static if (!is(typeof(T[0].min)))\n            alias MinType = CommonType!T;\n        else\n        {\n            enum hasMostNegative = is(typeof(mostNegative!(T[0]))) &&\n                                   is(typeof(mostNegative!(T[1])));\n            static if (hasMostNegative && mostNegative!(T[1]) < mostNegative!(T[0]))\n                alias MinType = T[1];\n            else static if (hasMostNegative && mostNegative!(T[1]) > mostNegative!(T[0]))\n                alias MinType = T[0];\n            else static if (T[1].max < T[0].max)\n                alias MinType = T[1];\n            else\n                alias MinType = T[0];\n        }\n    }\n    else\n    {\n        alias MinType = MinType!(MinType!(T[0 .. ($+1)/2]), MinType!(T[($+1)/2 .. $]));\n    }\n}\n\n// min\n/**\nIterates the passed arguments and returns the minimum value.\n\nParams: args = The values to select the minimum from. At least two arguments\n    must be passed, and they must be comparable with `<`.\nReturns: The minimum of the passed-in values.\nSee_Also:\n    $(REF minElement, std,algorithm,searching)\n*/\nMinType!T min(T...)(T args)\nif (T.length >= 2)\n{\n    //Get \"a\"\n    static if (T.length <= 2)\n        alias a = args[0];\n    else\n        auto a = min(args[0 .. ($+1)/2]);\n    alias T0 = typeof(a);\n\n    //Get \"b\"\n    static if (T.length <= 3)\n        alias b = args[$-1];\n    else\n        auto b = min(args[($+1)/2 .. $]);\n    alias T1 = typeof(b);\n\n    import std.algorithm.internal : algoFormat;\n    static assert(is(typeof(a < b)),\n        algoFormat(\"Invalid arguments: Cannot compare types %s and %s.\", T0.stringof, T1.stringof));\n\n    //Do the \"min\" proper with a and b\n    import std.functional : lessThan;\n    immutable chooseA = lessThan!(T0, T1)(a, b);\n    return cast(typeof(return)) (chooseA ? a : b);\n}\n\n///\n@safe @betterC unittest\n{\n    int a = 5;\n    short b = 6;\n    double c = 2;\n    auto d = min(a, b);\n    static assert(is(typeof(d) == int));\n    assert(d == 5);\n    auto e = min(a, b, c);\n    static assert(is(typeof(e) == double));\n    assert(e == 2);\n}\n\n/**\nWith arguments of mixed signedness, the return type is the one that can\nstore the lowest values.\n*/\n@safe @betterC unittest\n{\n    int a = -10;\n    uint f = 10;\n    static assert(is(typeof(min(a, f)) == int));\n    assert(min(a, f) == -10);\n}\n\n/// User-defined types that support comparison with < are supported.\n@safe unittest\n{\n    import std.datetime;\n    assert(min(Date(2012, 12, 21), Date(1982, 1, 4)) == Date(1982, 1, 4));\n    assert(min(Date(1982, 1, 4), Date(2012, 12, 21)) == Date(1982, 1, 4));\n    assert(min(Date(1982, 1, 4), Date.min) == Date.min);\n    assert(min(Date.min, Date(1982, 1, 4)) == Date.min);\n    assert(min(Date(1982, 1, 4), Date.max) == Date(1982, 1, 4));\n    assert(min(Date.max, Date(1982, 1, 4)) == Date(1982, 1, 4));\n    assert(min(Date.min, Date.max) == Date.min);\n    assert(min(Date.max, Date.min) == Date.min);\n}\n\n// mismatch\n/**\nSequentially compares elements in `r1` and `r2` in lockstep, and\nstops at the first mismatch (according to `pred`, by default\nequality). Returns a tuple with the reduced ranges that start with the\ntwo mismatched values. Performs $(BIGOH min(r1.length, r2.length))\nevaluations of `pred`.\n*/\nTuple!(Range1, Range2)\nmismatch(alias pred = \"a == b\", Range1, Range2)(Range1 r1, Range2 r2)\nif (isInputRange!(Range1) && isInputRange!(Range2))\n{\n    for (; !r1.empty && !r2.empty; r1.popFront(), r2.popFront())\n    {\n        if (!binaryFun!(pred)(r1.front, r2.front)) break;\n    }\n    return tuple(r1, r2);\n}\n\n///\n@safe unittest\n{\n    int[]    x = [ 1,  5, 2, 7,   4, 3 ];\n    double[] y = [ 1.0, 5, 2, 7.3, 4, 8 ];\n    auto m = mismatch(x, y);\n    assert(m[0] == x[3 .. $]);\n    assert(m[1] == y[3 .. $]);\n}\n\n@safe unittest\n{\n    int[] a = [ 1, 2, 3 ];\n    int[] b = [ 1, 2, 4, 5 ];\n    auto mm = mismatch(a, b);\n    assert(mm[0] == [3]);\n    assert(mm[1] == [4, 5]);\n}\n\n/**\nReturns one of a collection of expressions based on the value of the switch\nexpression.\n\n`choices` needs to be composed of pairs of test expressions and return\nexpressions. Each test-expression is compared with `switchExpression` using\n`pred`(`switchExpression` is the first argument) and if that yields true\n- the return expression is returned.\n\nBoth the test and the return expressions are lazily evaluated.\n\nParams:\n\nswitchExpression = The first argument for the predicate.\n\nchoices = Pairs of test expressions and return expressions. The test\nexpressions will be the second argument for the predicate, and the return\nexpression will be returned if the predicate yields true with $(D\nswitchExpression) and the test expression as arguments.  May also have a\ndefault return expression, that needs to be the last expression without a test\nexpression before it. A return expression may be of void type only if it\nalways throws.\n\nReturns: The return expression associated with the first test expression that\nmade the predicate yield true, or the default return expression if no test\nexpression matched.\n\nThrows: If there is no default return expression and the predicate does not\nyield true with any test expression - `SwitchError` is thrown. $(D\nSwitchError) is also thrown if a void return expression was executed without\nthrowing anything.\n*/\nauto predSwitch(alias pred = \"a == b\", T, R ...)(T switchExpression, lazy R choices)\n{\n    import core.exception : SwitchError;\n    alias predicate = binaryFun!(pred);\n\n    foreach (index, ChoiceType; R)\n    {\n        //The even places in `choices` are for the predicate.\n        static if (index % 2 == 1)\n        {\n            if (predicate(switchExpression, choices[index - 1]()))\n            {\n                static if (is(typeof(choices[index]()) == void))\n                {\n                    choices[index]();\n                    throw new SwitchError(\"Choices that return void should throw\");\n                }\n                else\n                {\n                    return choices[index]();\n                }\n            }\n        }\n    }\n\n    //In case nothing matched:\n    static if (R.length % 2 == 1) //If there is a default return expression:\n    {\n        static if (is(typeof(choices[$ - 1]()) == void))\n        {\n            choices[$ - 1]();\n            throw new SwitchError(\"Choices that return void should throw\");\n        }\n        else\n        {\n            return choices[$ - 1]();\n        }\n    }\n    else //If there is no default return expression:\n    {\n        throw new SwitchError(\"Input not matched by any pattern\");\n    }\n}\n\n///\n@safe unittest\n{\n    string res = 2.predSwitch!\"a < b\"(\n        1, \"less than 1\",\n        5, \"less than 5\",\n        10, \"less than 10\",\n        \"greater or equal to 10\");\n\n    assert(res == \"less than 5\");\n\n    //The arguments are lazy, which allows us to use predSwitch to create\n    //recursive functions:\n    int factorial(int n)\n    {\n        return n.predSwitch!\"a <= b\"(\n            -1, {throw new Exception(\"Can not calculate n! for n < 0\");}(),\n            0, 1, // 0! = 1\n            n * factorial(n - 1) // n! = n * (n - 1)! for n >= 0\n            );\n    }\n    assert(factorial(3) == 6);\n\n    //Void return expressions are allowed if they always throw:\n    import std.exception : assertThrown;\n    assertThrown!Exception(factorial(-9));\n}\n\n@system unittest\n{\n    import core.exception : SwitchError;\n    import std.exception : assertThrown;\n\n    //Nothing matches - with default return expression:\n    assert(20.predSwitch!\"a < b\"(\n        1, \"less than 1\",\n        5, \"less than 5\",\n        10, \"less than 10\",\n        \"greater or equal to 10\") == \"greater or equal to 10\");\n\n    //Nothing matches - without default return expression:\n    assertThrown!SwitchError(20.predSwitch!\"a < b\"(\n        1, \"less than 1\",\n        5, \"less than 5\",\n        10, \"less than 10\",\n        ));\n\n    //Using the default predicate:\n    assert(2.predSwitch(\n                1, \"one\",\n                2, \"two\",\n                3, \"three\",\n                ) == \"two\");\n\n    //Void return expressions must always throw:\n    assertThrown!SwitchError(1.predSwitch(\n                0, \"zero\",\n                1, {}(), //A void return expression that doesn't throw\n                2, \"two\",\n                ));\n}\n\n/**\nChecks if the two ranges have the same number of elements. This function is\noptimized to always take advantage of the `length` member of either range\nif it exists.\n\nIf both ranges have a length member, this function is $(BIGOH 1). Otherwise,\nthis function is $(BIGOH min(r1.length, r2.length)).\n\nParams:\n    r1 = a finite $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    r2 = a finite $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n\nReturns:\n    `true` if both ranges have the same length, `false` otherwise.\n*/\nbool isSameLength(Range1, Range2)(Range1 r1, Range2 r2)\nif (isInputRange!Range1 &&\n    isInputRange!Range2 &&\n    !isInfinite!Range1 &&\n    !isInfinite!Range2)\n{\n    static if (hasLength!(Range1) && hasLength!(Range2))\n    {\n        return r1.length == r2.length;\n    }\n    else static if (hasLength!(Range1) && !hasLength!(Range2))\n    {\n        size_t length;\n\n        while (!r2.empty)\n        {\n            r2.popFront;\n\n            if (++length > r1.length)\n            {\n                return false;\n            }\n        }\n\n        return !(length < r1.length);\n    }\n    else static if (!hasLength!(Range1) && hasLength!(Range2))\n    {\n        size_t length;\n\n        while (!r1.empty)\n        {\n            r1.popFront;\n\n            if (++length > r2.length)\n            {\n                return false;\n            }\n        }\n\n        return !(length < r2.length);\n    }\n    else\n    {\n        while (!r1.empty)\n        {\n           if (r2.empty)\n           {\n              return false;\n           }\n\n           r1.popFront;\n           r2.popFront;\n        }\n\n        return r2.empty;\n    }\n}\n\n///\n@safe nothrow pure unittest\n{\n    assert(isSameLength([1, 2, 3], [4, 5, 6]));\n    assert(isSameLength([0.3, 90.4, 23.7, 119.2], [42.6, 23.6, 95.5, 6.3]));\n    assert(isSameLength(\"abc\", \"xyz\"));\n\n    int[] a;\n    int[] b;\n    assert(isSameLength(a, b));\n\n    assert(!isSameLength([1, 2, 3], [4, 5]));\n    assert(!isSameLength([0.3, 90.4, 23.7], [42.6, 23.6, 95.5, 6.3]));\n    assert(!isSameLength(\"abcd\", \"xyz\"));\n}\n\n// Test CTFE\n@safe pure @betterC unittest\n{\n    enum result1 = isSameLength([1, 2, 3], [4, 5, 6]);\n    static assert(result1);\n\n    enum result2 = isSameLength([0.3, 90.4, 23.7], [42.6, 23.6, 95.5, 6.3]);\n    static assert(!result2);\n}\n\n@safe nothrow pure unittest\n{\n    import std.internal.test.dummyrange;\n\n    auto r1 = new ReferenceInputRange!int([1, 2, 3]);\n    auto r2 = new ReferenceInputRange!int([4, 5, 6]);\n    assert(isSameLength(r1, r2));\n\n    auto r3 = new ReferenceInputRange!int([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Input) r4;\n    assert(isSameLength(r3, r4));\n\n    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Input) r5;\n    auto r6 = new ReferenceInputRange!int([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n    assert(isSameLength(r5, r6));\n\n    auto r7 = new ReferenceInputRange!int([1, 2]);\n    auto r8 = new ReferenceInputRange!int([4, 5, 6]);\n    assert(!isSameLength(r7, r8));\n\n    auto r9 = new ReferenceInputRange!int([1, 2, 3, 4, 5, 6, 7, 8]);\n    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Input) r10;\n    assert(!isSameLength(r9, r10));\n\n    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Input) r11;\n    auto r12 = new ReferenceInputRange!int([1, 2, 3, 4, 5, 6, 7, 8]);\n    assert(!isSameLength(r11, r12));\n}\n\n/// For convenience\nalias AllocateGC = Flag!\"allocateGC\";\n\n/**\nChecks if both ranges are permutations of each other.\n\nThis function can allocate if the `Yes.allocateGC` flag is passed. This has\nthe benefit of have better complexity than the `Yes.allocateGC` option. However,\nthis option is only available for ranges whose equality can be determined via each\nelement's `toHash` method. If customized equality is needed, then the `pred`\ntemplate parameter can be passed, and the function will automatically switch to\nthe non-allocating algorithm. See $(REF binaryFun, std,functional) for more details on\nhow to define `pred`.\n\nNon-allocating forward range option: $(BIGOH n^2)\nNon-allocating forward range option with custom `pred`: $(BIGOH n^2)\nAllocating forward range option: amortized $(BIGOH r1.length) + $(BIGOH r2.length)\n\nParams:\n    pred = an optional parameter to change how equality is defined\n    allocate_gc = `Yes.allocateGC`/`No.allocateGC`\n    r1 = A finite $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n    r2 = A finite $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n\nReturns:\n    `true` if all of the elements in `r1` appear the same number of times in `r2`.\n    Otherwise, returns `false`.\n*/\n\nbool isPermutation(AllocateGC allocate_gc, Range1, Range2)\n(Range1 r1, Range2 r2)\nif (allocate_gc == Yes.allocateGC &&\n    isForwardRange!Range1 &&\n    isForwardRange!Range2 &&\n    !isInfinite!Range1 &&\n    !isInfinite!Range2)\n{\n    alias E1 = Unqual!(ElementType!Range1);\n    alias E2 = Unqual!(ElementType!Range2);\n\n    if (!isSameLength(r1.save, r2.save))\n    {\n        return false;\n    }\n\n    // Skip the elements at the beginning where r1.front == r2.front,\n    // they are in the same order and don't need to be counted.\n    while (!r1.empty && !r2.empty && r1.front == r2.front)\n    {\n        r1.popFront();\n        r2.popFront();\n    }\n\n    if (r1.empty && r2.empty)\n    {\n        return true;\n    }\n\n    int[CommonType!(E1, E2)] counts;\n\n    foreach (item; r1)\n    {\n        ++counts[item];\n    }\n\n    foreach (item; r2)\n    {\n        if (--counts[item] < 0)\n        {\n            return false;\n        }\n    }\n\n    return true;\n}\n\n/// ditto\nbool isPermutation(alias pred = \"a == b\", Range1, Range2)\n(Range1 r1, Range2 r2)\nif (is(typeof(binaryFun!(pred))) &&\n    isForwardRange!Range1 &&\n    isForwardRange!Range2 &&\n    !isInfinite!Range1 &&\n    !isInfinite!Range2)\n{\n    import std.algorithm.searching : count;\n\n    alias predEquals = binaryFun!(pred);\n    alias E1 = Unqual!(ElementType!Range1);\n    alias E2 = Unqual!(ElementType!Range2);\n\n    if (!isSameLength(r1.save, r2.save))\n    {\n        return false;\n    }\n\n    // Skip the elements at the beginning where r1.front == r2.front,\n    // they are in the same order and don't need to be counted.\n    while (!r1.empty && !r2.empty && predEquals(r1.front, r2.front))\n    {\n        r1.popFront();\n        r2.popFront();\n    }\n\n    if (r1.empty && r2.empty)\n    {\n        return true;\n    }\n\n    size_t r1_count;\n    size_t r2_count;\n\n    // At each element item, when computing the count of item, scan it while\n    // also keeping track of the scanning index. If the first occurrence\n    // of item in the scanning loop has an index smaller than the current index,\n    // then you know that the element has been seen before\n    size_t index;\n    outloop: for (auto r1s1 = r1.save; !r1s1.empty; r1s1.popFront, index++)\n    {\n        auto item = r1s1.front;\n        r1_count = 0;\n        r2_count = 0;\n\n        size_t i;\n        for (auto r1s2 = r1.save; !r1s2.empty; r1s2.popFront, i++)\n        {\n            auto e = r1s2.front;\n            if (predEquals(e, item) && i < index)\n            {\n                 continue outloop;\n            }\n            else if (predEquals(e, item))\n            {\n                ++r1_count;\n            }\n        }\n\n        r2_count = r2.save.count!pred(item);\n\n        if (r1_count != r2_count)\n        {\n            return false;\n        }\n    }\n\n    return true;\n}\n\n///\n@safe pure unittest\n{\n    import std.typecons : Yes;\n\n    assert(isPermutation([1, 2, 3], [3, 2, 1]));\n    assert(isPermutation([1.1, 2.3, 3.5], [2.3, 3.5, 1.1]));\n    assert(isPermutation(\"abc\", \"bca\"));\n\n    assert(!isPermutation([1, 2], [3, 4]));\n    assert(!isPermutation([1, 1, 2, 3], [1, 2, 2, 3]));\n    assert(!isPermutation([1, 1], [1, 1, 1]));\n\n    // Faster, but allocates GC handled memory\n    assert(isPermutation!(Yes.allocateGC)([1.1, 2.3, 3.5], [2.3, 3.5, 1.1]));\n    assert(!isPermutation!(Yes.allocateGC)([1, 2], [3, 4]));\n}\n\n// Test @nogc inference\n@safe @nogc pure unittest\n{\n    static immutable arr1 = [1, 2, 3];\n    static immutable arr2 = [3, 2, 1];\n    assert(isPermutation(arr1, arr2));\n\n    static immutable arr3 = [1, 1, 2, 3];\n    static immutable arr4 = [1, 2, 2, 3];\n    assert(!isPermutation(arr3, arr4));\n}\n\n@safe pure unittest\n{\n    import std.internal.test.dummyrange;\n\n    auto r1 = new ReferenceForwardRange!int([1, 2, 3, 4]);\n    auto r2 = new ReferenceForwardRange!int([1, 2, 4, 3]);\n    assert(isPermutation(r1, r2));\n\n    auto r3 = new ReferenceForwardRange!int([1, 2, 3, 4]);\n    auto r4 = new ReferenceForwardRange!int([4, 2, 1, 3]);\n    assert(isPermutation!(Yes.allocateGC)(r3, r4));\n\n    auto r5 = new ReferenceForwardRange!int([1, 2, 3]);\n    auto r6 = new ReferenceForwardRange!int([4, 2, 1, 3]);\n    assert(!isPermutation(r5, r6));\n\n    auto r7 = new ReferenceForwardRange!int([4, 2, 1, 3]);\n    auto r8 = new ReferenceForwardRange!int([1, 2, 3]);\n    assert(!isPermutation!(Yes.allocateGC)(r7, r8));\n\n    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random) r9;\n    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random) r10;\n    assert(isPermutation(r9, r10));\n\n    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random) r11;\n    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random) r12;\n    assert(isPermutation!(Yes.allocateGC)(r11, r12));\n\n    alias mytuple = Tuple!(int, int);\n\n    assert(isPermutation!\"a[0] == b[0]\"(\n        [mytuple(1, 4), mytuple(2, 5)],\n        [mytuple(2, 3), mytuple(1, 2)]\n    ));\n}\n\n/**\nGet the _first argument `a` that passes an `if (unaryFun!pred(a))` test.  If\nno argument passes the test, return the last argument.\n\nSimilar to behaviour of the `or` operator in dynamic languages such as Lisp's\n`(or ...)` and Python's `a or b or ...` except that the last argument is\nreturned upon no match.\n\nSimplifies logic, for instance, in parsing rules where a set of alternative\nmatchers are tried. The _first one that matches returns it match result,\ntypically as an abstract syntax tree (AST).\n\nBugs:\nLazy parameters are currently, too restrictively, inferred by DMD to\nalways throw even though they don't need to be. This makes it impossible to\ncurrently mark `either` as `nothrow`. See issue at $(BUGZILLA 12647).\n\nReturns:\n    The _first argument that passes the test `pred`.\n*/\nCommonType!(T, Ts) either(alias pred = a => a, T, Ts...)(T first, lazy Ts alternatives)\nif (alternatives.length >= 1 &&\n    !is(CommonType!(T, Ts) == void) &&\n    allSatisfy!(ifTestable, T, Ts))\n{\n    alias predFun = unaryFun!pred;\n\n    if (predFun(first)) return first;\n\n    foreach (e; alternatives[0 .. $ - 1])\n        if (predFun(e)) return e;\n\n    return alternatives[$ - 1];\n}\n\n///\n@safe pure @betterC unittest\n{\n    const a = 1;\n    const b = 2;\n    auto ab = either(a, b);\n    static assert(is(typeof(ab) == const(int)));\n    assert(ab == a);\n\n    auto c = 2;\n    const d = 3;\n    auto cd = either!(a => a == 3)(c, d); // use predicate\n    static assert(is(typeof(cd) == int));\n    assert(cd == d);\n\n    auto e = 0;\n    const f = 2;\n    auto ef = either(e, f);\n    static assert(is(typeof(ef) == int));\n    assert(ef == f);\n}\n\n///\n@safe pure unittest\n{\n    immutable p = 1;\n    immutable q = 2;\n    auto pq = either(p, q);\n    static assert(is(typeof(pq) == immutable(int)));\n    assert(pq == p);\n\n    assert(either(3, 4) == 3);\n    assert(either(0, 4) == 4);\n    assert(either(0, 0) == 0);\n    assert(either(\"\", \"a\") == \"\");\n}\n\n///\n@safe pure unittest\n{\n    string r = null;\n    assert(either(r, \"a\") == \"a\");\n    assert(either(\"a\", \"\") == \"a\");\n\n    immutable s = [1, 2];\n    assert(either(s, s) == s);\n\n    assert(either([0, 1], [1, 2]) == [0, 1]);\n    assert(either([0, 1], [1]) == [0, 1]);\n    assert(either(\"a\", \"b\") == \"a\");\n\n    static assert(!__traits(compiles, either(1, \"a\")));\n    static assert(!__traits(compiles, either(1.0, \"a\")));\n    static assert(!__traits(compiles, either('a', \"a\")));\n}\n"
  },
  {
    "path": "libphobos/src/std/algorithm/internal.d",
    "content": "// Written in the D programming language.\n\n/// Helper functions for std.algorithm package.\nmodule std.algorithm.internal;\n\n\n// Same as std.string.format, but \"self-importing\".\n// Helps reduce code and imports, particularly in static asserts.\n// Also helps with missing imports errors.\npackage template algoFormat()\n{\n    import std.format : format;\n    alias algoFormat = format;\n}\n\n// Internal random array generators\nversion (unittest)\n{\n    package enum size_t maxArraySize = 50;\n    package enum size_t minArraySize = maxArraySize - 1;\n\n    package string[] rndstuff(T : string)()\n    {\n        import std.random : Random = Xorshift, uniform;\n\n        static Random rnd;\n        static bool first = true;\n        if (first)\n        {\n            rnd.seed(234_567_891);\n            first = false;\n        }\n        string[] result =\n            new string[uniform(minArraySize, maxArraySize, rnd)];\n        string alpha = \"abcdefghijABCDEFGHIJ\";\n        foreach (ref s; result)\n        {\n            foreach (i; 0 .. uniform(0u, 20u, rnd))\n            {\n                auto j = uniform(0, alpha.length - 1, rnd);\n                s ~= alpha[j];\n            }\n        }\n        return result;\n    }\n\n    package int[] rndstuff(T : int)()\n    {\n        import std.random : Random = Xorshift, uniform;\n\n        static Random rnd;\n        static bool first = true;\n        if (first)\n        {\n            rnd = Random(345_678_912);\n            first = false;\n        }\n        int[] result = new int[uniform(minArraySize, maxArraySize, rnd)];\n        foreach (ref i; result)\n        {\n            i = uniform(-100, 100, rnd);\n        }\n        return result;\n    }\n\n    package double[] rndstuff(T : double)()\n    {\n        double[] result;\n        foreach (i; rndstuff!(int)())\n        {\n            result ~= i / 50.0;\n        }\n        return result;\n    }\n}\n\npackage(std) T* addressOf(T)(ref T val) { return &val; }\n"
  },
  {
    "path": "libphobos/src/std/algorithm/iteration.d",
    "content": "// Written in the D programming language.\n/**\nThis is a submodule of $(MREF std, algorithm).\nIt contains generic iteration algorithms.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE Cheat Sheet,\n$(TR $(TH Function Name) $(TH Description))\n$(T2 cache,\n        Eagerly evaluates and caches another range's `front`.)\n$(T2 cacheBidirectional,\n        As above, but also provides `back` and `popBack`.)\n$(T2 chunkBy,\n        `chunkBy!((a,b) => a[1] == b[1])([[1, 1], [1, 2], [2, 2], [2, 1]])`\n        returns a range containing 3 subranges: the first with just\n        `[1, 1]`; the second with the elements `[1, 2]` and `[2, 2]`;\n        and the third with just `[2, 1]`.)\n$(T2 cumulativeFold,\n        `cumulativeFold!((a, b) => a + b)([1, 2, 3, 4])` returns a\n        lazily-evaluated range containing the successive reduced values `1`,\n        `3`, `6`, `10`.)\n$(T2 each,\n        `each!writeln([1, 2, 3])` eagerly prints the numbers `1`, `2`\n        and `3` on their own lines.)\n$(T2 filter,\n        `filter!(a => a > 0)([1, -1, 2, 0, -3])` iterates over elements `1`\n        and `2`.)\n$(T2 filterBidirectional,\n        Similar to `filter`, but also provides `back` and `popBack` at\n        a small increase in cost.)\n$(T2 fold,\n        `fold!((a, b) => a + b)([1, 2, 3, 4])` returns `10`.)\n$(T2 group,\n        `group([5, 2, 2, 3, 3])` returns a range containing the tuples\n        `tuple(5, 1)`, `tuple(2, 2)`, and `tuple(3, 2)`.)\n$(T2 joiner,\n        `joiner([\"hello\", \"world!\"], \"; \")` returns a range that iterates\n        over the characters `\"hello; world!\"`. No new string is created -\n        the existing inputs are iterated.)\n$(T2 map,\n        `map!(a => a * 2)([1, 2, 3])` lazily returns a range with the numbers\n        `2`, `4`, `6`.)\n$(T2 mean,\n        Colloquially known as the average, `mean([1, 2, 3])` returns `2`.)\n$(T2 permutations,\n        Lazily computes all permutations using Heap's algorithm.)\n$(T2 reduce,\n        `reduce!((a, b) => a + b)([1, 2, 3, 4])` returns `10`.\n        This is the old implementation of `fold`.)\n$(T2 splitter,\n        Lazily splits a range by a separator.)\n$(T2 substitute,\n        `[1, 2].substitute(1, 0.1)` returns `[0.1, 2]`.)\n$(T2 sum,\n        Same as `fold`, but specialized for accurate summation.)\n$(T2 uniq,\n        Iterates over the unique elements in a range, which is assumed sorted.)\n)\n\nCopyright: Andrei Alexandrescu 2008-.\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n\nSource: $(PHOBOSSRC std/algorithm/iteration.d)\n\nMacros:\nT2=$(TR $(TDNW $(LREF $1)) $(TD $+))\n */\nmodule std.algorithm.iteration;\n\n// FIXME\nimport std.functional; // : unaryFun, binaryFun;\nimport std.range.primitives;\nimport std.traits;\nimport std.typecons : Flag;\n\nprivate template aggregate(fun...)\nif (fun.length >= 1)\n{\n    /* --Intentionally not ddoc--\n     * Aggregates elements in each subrange of the given range of ranges using\n     * the given aggregating function(s).\n     * Params:\n     *  fun = One or more aggregating functions (binary functions that return a\n     *      single _aggregate value of their arguments).\n     *  ror = A range of ranges to be aggregated.\n     *\n     * Returns:\n     * A range representing the aggregated value(s) of each subrange\n     * of the original range. If only one aggregating function is specified,\n     * each element will be the aggregated value itself; if multiple functions\n     * are specified, each element will be a tuple of the aggregated values of\n     * each respective function.\n     */\n    auto aggregate(RoR)(RoR ror)\n        if (isInputRange!RoR && isIterable!(ElementType!RoR))\n    {\n        return ror.map!(reduce!fun);\n    }\n\n    @safe unittest\n    {\n        import std.algorithm.comparison : equal, max, min;\n\n        auto data = [[4, 2, 1, 3], [4, 9, -1, 3, 2], [3]];\n\n        // Single aggregating function\n        auto agg1 = data.aggregate!max;\n        assert(agg1.equal([4, 9, 3]));\n\n        // Multiple aggregating functions\n        import std.typecons : tuple;\n        auto agg2 = data.aggregate!(max, min);\n        assert(agg2.equal([\n            tuple(4, 1),\n            tuple(9, -1),\n            tuple(3, 3)\n        ]));\n    }\n}\n\n/++\n`cache` eagerly evaluates $(REF_ALTTEXT front, front, std,range,primitives) of `range`\non each construction or call to $(REF_ALTTEXT popFront, popFront, std,range,primitives),\nto store the result in a _cache.\nThe result is then directly returned when $(REF_ALTTEXT front, front, std,range,primitives) is called,\nrather than re-evaluated.\n\nThis can be a useful function to place in a chain, after functions\nthat have expensive evaluation, as a lazy alternative to $(REF array, std,array).\nIn particular, it can be placed after a call to $(LREF map), or before a call\n$(REF filter, std,range) or $(REF tee, std,range)\n\n`cache` may provide\n$(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives)\niteration if needed, but since this comes at an increased cost, it must be explicitly requested via the\ncall to `cacheBidirectional`. Furthermore, a bidirectional _cache will\nevaluate the \"center\" element twice, when there is only one element left in\nthe range.\n\n`cache` does not provide random access primitives,\nas `cache` would be unable to _cache the random accesses.\nIf `Range` provides slicing primitives,\nthen `cache` will provide the same slicing primitives,\nbut `hasSlicing!Cache` will not yield true (as the $(REF hasSlicing, std,range,primitives)\ntrait also checks for random access).\n\nParams:\n    range = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n\nReturns:\n    An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) with the cached values of range\n+/\nauto cache(Range)(Range range)\nif (isInputRange!Range)\n{\n    return _Cache!(Range, false)(range);\n}\n\n/// ditto\nauto cacheBidirectional(Range)(Range range)\nif (isBidirectionalRange!Range)\n{\n    return _Cache!(Range, true)(range);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range, std.stdio;\n    import std.typecons : tuple;\n\n    ulong counter = 0;\n    double fun(int x)\n    {\n        ++counter;\n        // http://en.wikipedia.org/wiki/Quartic_function\n        return ( (x + 4.0) * (x + 1.0) * (x - 1.0) * (x - 3.0) ) / 14.0 + 0.5;\n    }\n    // Without cache, with array (greedy)\n    auto result1 = iota(-4, 5).map!(a =>tuple(a, fun(a)))()\n                             .filter!(a => a[1] < 0)()\n                             .map!(a => a[0])()\n                             .array();\n\n    // the values of x that have a negative y are:\n    assert(equal(result1, [-3, -2, 2]));\n\n    // Check how many times fun was evaluated.\n    // As many times as the number of items in both source and result.\n    assert(counter == iota(-4, 5).length + result1.length);\n\n    counter = 0;\n    // Without array, with cache (lazy)\n    auto result2 = iota(-4, 5).map!(a =>tuple(a, fun(a)))()\n                             .cache()\n                             .filter!(a => a[1] < 0)()\n                             .map!(a => a[0])();\n\n    // the values of x that have a negative y are:\n    assert(equal(result2, [-3, -2, 2]));\n\n    // Check how many times fun was evaluated.\n    // Only as many times as the number of items in source.\n    assert(counter == iota(-4, 5).length);\n}\n\n/++\nTip: `cache` is eager when evaluating elements. If calling front on the\nunderlying range has a side effect, it will be observable before calling\nfront on the actual cached range.\n\nFurthermore, care should be taken composing `cache` with $(REF take, std,range).\nBy placing `take` before `cache`, then `cache` will be \"aware\"\nof when the range ends, and correctly stop caching elements when needed.\nIf calling front has no side effect though, placing `take` after `cache`\nmay yield a faster range.\n\nEither way, the resulting ranges will be equivalent, but maybe not at the\nsame cost or side effects.\n+/\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range;\n    int i = 0;\n\n    auto r = iota(0, 4).tee!((a){i = a;}, No.pipeOnPop);\n    auto r1 = r.take(3).cache();\n    auto r2 = r.cache().take(3);\n\n    assert(equal(r1, [0, 1, 2]));\n    assert(i == 2); //The last \"seen\" element was 2. The data in cache has been cleared.\n\n    assert(equal(r2, [0, 1, 2]));\n    assert(i == 3); //cache has accessed 3. It is still stored internally by cache.\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range;\n    auto a = [1, 2, 3, 4];\n    assert(equal(a.map!(a => (a - 1) * a)().cache(),                      [ 0, 2, 6, 12]));\n    assert(equal(a.map!(a => (a - 1) * a)().cacheBidirectional().retro(), [12, 6, 2,  0]));\n    auto r1 = [1, 2, 3, 4].cache()             [1 .. $];\n    auto r2 = [1, 2, 3, 4].cacheBidirectional()[1 .. $];\n    assert(equal(r1, [2, 3, 4]));\n    assert(equal(r2, [2, 3, 4]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    //immutable test\n    static struct S\n    {\n        int i;\n        this(int i)\n        {\n            //this.i = i;\n        }\n    }\n    immutable(S)[] s = [S(1), S(2), S(3)];\n    assert(equal(s.cache(),              s));\n    assert(equal(s.cacheBidirectional(), s));\n}\n\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    //safety etc\n    auto a = [1, 2, 3, 4];\n    assert(equal(a.cache(),              a));\n    assert(equal(a.cacheBidirectional(), a));\n}\n\n@safe unittest\n{\n    char[][] stringbufs = [\"hello\".dup, \"world\".dup];\n    auto strings = stringbufs.map!((a)=>a.idup)().cache();\n    assert(strings.front is strings.front);\n}\n\n@safe unittest\n{\n    import std.range : cycle;\n    import std.algorithm.comparison : equal;\n\n    auto c = [1, 2, 3].cycle().cache();\n    c = c[1 .. $];\n    auto d = c[0 .. 1];\n    assert(d.equal([2]));\n}\n\n@safe unittest\n{\n    static struct Range\n    {\n        bool initialized = false;\n        bool front() @property {return initialized = true;}\n        void popFront() {initialized = false;}\n        enum empty = false;\n    }\n    auto r = Range().cache();\n    assert(r.source.initialized == true);\n}\n\nprivate struct _Cache(R, bool bidir)\n{\n    import core.exception : RangeError;\n\n    private\n    {\n        import std.algorithm.internal : algoFormat;\n        import std.meta : AliasSeq;\n\n        alias E  = ElementType!R;\n        alias UE = Unqual!E;\n\n        R source;\n\n        static if (bidir) alias CacheTypes = AliasSeq!(UE, UE);\n        else              alias CacheTypes = AliasSeq!UE;\n        CacheTypes caches;\n\n        static assert(isAssignable!(UE, E) && is(UE : E),\n            algoFormat(\n                \"Cannot instantiate range with %s because %s elements are not assignable to %s.\",\n                R.stringof,\n                E.stringof,\n                UE.stringof\n            )\n        );\n    }\n\n    this(R range)\n    {\n        source = range;\n        if (!range.empty)\n        {\n             caches[0] = source.front;\n             static if (bidir)\n                 caches[1] = source.back;\n        }\n    }\n\n    static if (isInfinite!R)\n        enum empty = false;\n    else\n        bool empty() @property\n        {\n            return source.empty;\n        }\n\n    static if (hasLength!R) auto length() @property\n    {\n        return source.length;\n    }\n\n    E front() @property\n    {\n        version (assert) if (empty) throw new RangeError();\n        return caches[0];\n    }\n    static if (bidir) E back() @property\n    {\n        version (assert) if (empty) throw new RangeError();\n        return caches[1];\n    }\n\n    void popFront()\n    {\n        version (assert) if (empty) throw new RangeError();\n        source.popFront();\n        if (!source.empty)\n            caches[0] = source.front;\n        else\n            caches = CacheTypes.init;\n    }\n    static if (bidir) void popBack()\n    {\n        version (assert) if (empty) throw new RangeError();\n        source.popBack();\n        if (!source.empty)\n            caches[1] = source.back;\n        else\n            caches = CacheTypes.init;\n    }\n\n    static if (isForwardRange!R)\n    {\n        private this(R source, ref CacheTypes caches)\n        {\n            this.source = source;\n            this.caches = caches;\n        }\n        typeof(this) save() @property\n        {\n            return typeof(this)(source.save, caches);\n        }\n    }\n\n    static if (hasSlicing!R)\n    {\n        enum hasEndSlicing = is(typeof(source[size_t.max .. $]));\n\n        static if (hasEndSlicing)\n        {\n            private static struct DollarToken{}\n            enum opDollar = DollarToken.init;\n\n            auto opSlice(size_t low, DollarToken)\n            {\n                return typeof(this)(source[low .. $]);\n            }\n        }\n\n        static if (!isInfinite!R)\n        {\n            typeof(this) opSlice(size_t low, size_t high)\n            {\n                return typeof(this)(source[low .. high]);\n            }\n        }\n        else static if (hasEndSlicing)\n        {\n            auto opSlice(size_t low, size_t high)\n            in\n            {\n                assert(low <= high, \"Bounds error when slicing cache.\");\n            }\n            do\n            {\n                import std.range : takeExactly;\n                return this[low .. $].takeExactly(high - low);\n            }\n        }\n    }\n}\n\n/**\nImplements the homonym function (also known as `transform`) present\nin many languages of functional flavor. The call `map!(fun)(range)`\nreturns a range of which elements are obtained by applying `fun(a)`\nleft to right for all elements `a` in `range`. The original ranges are\nnot changed. Evaluation is done lazily.\n\nParams:\n    fun = one or more transformation functions\n\nSee_Also:\n    $(HTTP en.wikipedia.org/wiki/Map_(higher-order_function), Map (higher-order function))\n*/\ntemplate map(fun...)\nif (fun.length >= 1)\n{\n    /**\n    Params:\n        r = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    Returns:\n        A range with each fun applied to all the elements. If there is more than one\n        fun, the element type will be `Tuple` containing one element for each fun.\n     */\n    auto map(Range)(Range r) if (isInputRange!(Unqual!Range))\n    {\n        import std.meta : AliasSeq, staticMap;\n\n        alias RE = ElementType!(Range);\n        static if (fun.length > 1)\n        {\n            import std.functional : adjoin;\n            import std.meta : staticIndexOf;\n\n            alias _funs = staticMap!(unaryFun, fun);\n            alias _fun = adjoin!_funs;\n\n            // Once DMD issue #5710 is fixed, this validation loop can be moved into a template.\n            foreach (f; _funs)\n            {\n                static assert(!is(typeof(f(RE.init)) == void),\n                    \"Mapping function(s) must not return void: \" ~ _funs.stringof);\n            }\n        }\n        else\n        {\n            alias _fun = unaryFun!fun;\n            alias _funs = AliasSeq!(_fun);\n\n            // Do the validation separately for single parameters due to DMD issue #15777.\n            static assert(!is(typeof(_fun(RE.init)) == void),\n                \"Mapping function(s) must not return void: \" ~ _funs.stringof);\n        }\n\n        return MapResult!(_fun, Range)(r);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : chain;\n    int[] arr1 = [ 1, 2, 3, 4 ];\n    int[] arr2 = [ 5, 6 ];\n    auto squares = map!(a => a * a)(chain(arr1, arr2));\n    assert(equal(squares, [ 1, 4, 9, 16, 25, 36 ]));\n}\n\n/**\nMultiple functions can be passed to `map`. In that case, the\nelement type of `map` is a tuple containing one element for each\nfunction.\n*/\n@safe unittest\n{\n    auto sums = [2, 4, 6, 8];\n    auto products = [1, 4, 9, 16];\n\n    size_t i = 0;\n    foreach (result; [ 1, 2, 3, 4 ].map!(\"a + a\", \"a * a\"))\n    {\n        assert(result[0] == sums[i]);\n        assert(result[1] == products[i]);\n        ++i;\n    }\n}\n\n/**\nYou may alias `map` with some function(s) to a symbol and use\nit separately:\n*/\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : to;\n\n    alias stringize = map!(to!string);\n    assert(equal(stringize([ 1, 2, 3, 4 ]), [ \"1\", \"2\", \"3\", \"4\" ]));\n}\n\n@safe unittest\n{\n    // Verify workaround for DMD #15777\n\n    import std.algorithm.mutation, std.string;\n    auto foo(string[] args)\n    {\n        return args.map!strip;\n    }\n}\n\nprivate struct MapResult(alias fun, Range)\n{\n    alias R = Unqual!Range;\n    R _input;\n\n    static if (isBidirectionalRange!R)\n    {\n        @property auto ref back()()\n        {\n            assert(!empty, \"Attempting to fetch the back of an empty map.\");\n            return fun(_input.back);\n        }\n\n        void popBack()()\n        {\n            assert(!empty, \"Attempting to popBack an empty map.\");\n            _input.popBack();\n        }\n    }\n\n    this(R input)\n    {\n        _input = input;\n    }\n\n    static if (isInfinite!R)\n    {\n        // Propagate infinite-ness.\n        enum bool empty = false;\n    }\n    else\n    {\n        @property bool empty()\n        {\n            return _input.empty;\n        }\n    }\n\n    void popFront()\n    {\n        assert(!empty, \"Attempting to popFront an empty map.\");\n        _input.popFront();\n    }\n\n    @property auto ref front()\n    {\n        assert(!empty, \"Attempting to fetch the front of an empty map.\");\n        return fun(_input.front);\n    }\n\n    static if (isRandomAccessRange!R)\n    {\n        static if (is(typeof(_input[ulong.max])))\n            private alias opIndex_t = ulong;\n        else\n            private alias opIndex_t = uint;\n\n        auto ref opIndex(opIndex_t index)\n        {\n            return fun(_input[index]);\n        }\n    }\n\n    static if (hasLength!R)\n    {\n        @property auto length()\n        {\n            return _input.length;\n        }\n\n        alias opDollar = length;\n    }\n\n    static if (hasSlicing!R)\n    {\n        static if (is(typeof(_input[ulong.max .. ulong.max])))\n            private alias opSlice_t = ulong;\n        else\n            private alias opSlice_t = uint;\n\n        static if (hasLength!R)\n        {\n            auto opSlice(opSlice_t low, opSlice_t high)\n            {\n                return typeof(this)(_input[low .. high]);\n            }\n        }\n        else static if (is(typeof(_input[opSlice_t.max .. $])))\n        {\n            struct DollarToken{}\n            enum opDollar = DollarToken.init;\n            auto opSlice(opSlice_t low, DollarToken)\n            {\n                return typeof(this)(_input[low .. $]);\n            }\n\n            auto opSlice(opSlice_t low, opSlice_t high)\n            {\n                import std.range : takeExactly;\n                return this[low .. $].takeExactly(high - low);\n            }\n        }\n    }\n\n    static if (isForwardRange!R)\n    {\n        @property auto save()\n        {\n            return typeof(this)(_input.save);\n        }\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : to;\n    import std.functional : adjoin;\n\n    alias stringize = map!(to!string);\n    assert(equal(stringize([ 1, 2, 3, 4 ]), [ \"1\", \"2\", \"3\", \"4\" ]));\n\n    uint counter;\n    alias count = map!((a) { return counter++; });\n    assert(equal(count([ 10, 2, 30, 4 ]), [ 0, 1, 2, 3 ]));\n\n    counter = 0;\n    adjoin!((a) { return counter++; }, (a) { return counter++; })(1);\n    alias countAndSquare = map!((a) { return counter++; }, (a) { return counter++; });\n    //assert(equal(countAndSquare([ 10, 2 ]), [ tuple(0u, 100), tuple(1u, 4) ]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.ascii : toUpper;\n    import std.internal.test.dummyrange;\n    import std.range;\n    import std.typecons : tuple;\n    import std.random : uniform, Random = Xorshift;\n\n    int[] arr1 = [ 1, 2, 3, 4 ];\n    const int[] arr1Const = arr1;\n    int[] arr2 = [ 5, 6 ];\n    auto squares = map!(\"a * a\")(arr1Const);\n    assert(squares[$ - 1] == 16);\n    assert(equal(squares, [ 1, 4, 9, 16 ][]));\n    assert(equal(map!(\"a * a\")(chain(arr1, arr2)), [ 1, 4, 9, 16, 25, 36 ][]));\n\n    // Test the caching stuff.\n    assert(squares.back == 16);\n    auto squares2 = squares.save;\n    assert(squares2.back == 16);\n\n    assert(squares2.front == 1);\n    squares2.popFront();\n    assert(squares2.front == 4);\n    squares2.popBack();\n    assert(squares2.front == 4);\n    assert(squares2.back == 9);\n\n    assert(equal(map!(\"a * a\")(chain(arr1, arr2)), [ 1, 4, 9, 16, 25, 36 ][]));\n\n    uint i;\n    foreach (e; map!(\"a\", \"a * a\")(arr1))\n    {\n        assert(e[0] == ++i);\n        assert(e[1] == i * i);\n    }\n\n    // Test length.\n    assert(squares.length == 4);\n    assert(map!\"a * a\"(chain(arr1, arr2)).length == 6);\n\n    // Test indexing.\n    assert(squares[0] == 1);\n    assert(squares[1] == 4);\n    assert(squares[2] == 9);\n    assert(squares[3] == 16);\n\n    // Test slicing.\n    auto squareSlice = squares[1 .. squares.length - 1];\n    assert(equal(squareSlice, [4, 9][]));\n    assert(squareSlice.back == 9);\n    assert(squareSlice[1] == 9);\n\n    // Test on a forward range to make sure it compiles when all the fancy\n    // stuff is disabled.\n    auto fibsSquares = map!\"a * a\"(recurrence!(\"a[n-1] + a[n-2]\")(1, 1));\n    assert(fibsSquares.front == 1);\n    fibsSquares.popFront();\n    fibsSquares.popFront();\n    assert(fibsSquares.front == 4);\n    fibsSquares.popFront();\n    assert(fibsSquares.front == 9);\n\n    auto repeatMap = map!\"a\"(repeat(1));\n    auto gen = Random(123_456_789);\n    auto index = uniform(0, 1024, gen);\n    static assert(isInfinite!(typeof(repeatMap)));\n    assert(repeatMap[index] == 1);\n\n    auto intRange = map!\"a\"([1,2,3]);\n    static assert(isRandomAccessRange!(typeof(intRange)));\n    assert(equal(intRange, [1, 2, 3]));\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType d;\n        auto m = map!\"a * a\"(d);\n\n        static assert(propagatesRangeType!(typeof(m), DummyType));\n        assert(equal(m, [1,4,9,16,25,36,49,64,81,100]));\n    }\n\n    //Test string access\n    string  s1 = \"hello world!\";\n    dstring s2 = \"日本語\";\n    dstring s3 = \"hello world!\"d;\n    auto ms1 = map!(std.ascii.toUpper)(s1);\n    auto ms2 = map!(std.ascii.toUpper)(s2);\n    auto ms3 = map!(std.ascii.toUpper)(s3);\n    static assert(!is(ms1[0])); //narrow strings can't be indexed\n    assert(ms2[0] == '日');\n    assert(ms3[0] == 'H');\n    static assert(!is(ms1[0 .. 1])); //narrow strings can't be sliced\n    assert(equal(ms2[0 .. 2], \"日本\"w));\n    assert(equal(ms3[0 .. 2], \"HE\"));\n\n    // Issue 5753\n    static void voidFun(int) {}\n    static int nonvoidFun(int) { return 0; }\n    static assert(!__traits(compiles, map!voidFun([1])));\n    static assert(!__traits(compiles, map!(voidFun, voidFun)([1])));\n    static assert(!__traits(compiles, map!(nonvoidFun, voidFun)([1])));\n    static assert(!__traits(compiles, map!(voidFun, nonvoidFun)([1])));\n    static assert(!__traits(compiles, map!(a => voidFun(a))([1])));\n\n    // Phobos issue #15480\n    auto dd = map!(z => z * z, c => c * c * c)([ 1, 2, 3, 4 ]);\n    assert(dd[0] == tuple(1, 1));\n    assert(dd[1] == tuple(4, 8));\n    assert(dd[2] == tuple(9, 27));\n    assert(dd[3] == tuple(16, 64));\n    assert(dd.length == 4);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range;\n    auto LL = iota(1L, 4L);\n    auto m = map!\"a*a\"(LL);\n    assert(equal(m, [1L, 4L, 9L]));\n}\n\n@safe unittest\n{\n    import std.range : iota;\n\n    // Issue #10130 - map of iota with const step.\n    const step = 2;\n    assert(map!(i => i)(iota(0, 10, step)).walkLength == 5);\n\n    // Need these to all by const to repro the float case, due to the\n    // CommonType template used in the float specialization of iota.\n    const floatBegin = 0.0;\n    const floatEnd = 1.0;\n    const floatStep = 0.02;\n    assert(map!(i => i)(iota(floatBegin, floatEnd, floatStep)).walkLength == 50);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range;\n    //slicing infinites\n    auto rr = iota(0, 5).cycle().map!\"a * a\"();\n    alias RR = typeof(rr);\n    static assert(hasSlicing!RR);\n    rr = rr[6 .. $]; //Advances 1 cycle and 1 unit\n    assert(equal(rr[0 .. 5], [1, 4, 9, 16, 0]));\n}\n\n@safe unittest\n{\n    import std.range;\n    struct S {int* p;}\n    auto m = immutable(S).init.repeat().map!\"a\".save;\n    assert(m.front == immutable(S)(null));\n}\n\n// each\n/**\nEagerly iterates over `r` and calls `fun` over _each element.\n\nIf no function to call is specified, `each` defaults to doing nothing but\nconsuming the entire range. `r.front` will be evaluated, but that can be avoided\nby specifying a lambda with a `lazy` parameter.\n\n`each` also supports `opApply`-based types, so it works with e.g. $(REF\nparallel, std,parallelism).\n\nNormally the entire range is iterated. If partial iteration (early stopping) is\ndesired, `fun` needs to return a value of type $(REF Flag,\nstd.typecons)`!\"each\"` (`Yes.each` to continue iteration, or `No.each` to stop\niteration).\n\nParams:\n    fun = function to apply to _each element of the range\n    r = range or iterable over which `each` iterates\n\nReturns: `Yes.each` if the entire range was iterated, `No.each` in case of early\nstopping.\n\nSee_Also: $(REF tee, std,range)\n */\ntemplate each(alias fun = \"a\")\n{\n    import std.meta : AliasSeq;\n    import std.traits : Parameters;\n    import std.typecons : Flag, Yes, No;\n\nprivate:\n    alias BinaryArgs = AliasSeq!(fun, \"i\", \"a\");\n\n    enum isRangeUnaryIterable(R) =\n        is(typeof(unaryFun!fun(R.init.front)));\n\n    enum isRangeBinaryIterable(R) =\n        is(typeof(binaryFun!BinaryArgs(0, R.init.front)));\n\n    enum isRangeIterable(R) =\n        isInputRange!R &&\n        (isRangeUnaryIterable!R || isRangeBinaryIterable!R);\n\n    enum isForeachUnaryIterable(R) =\n        is(typeof((R r) {\n            foreach (ref a; r)\n                cast(void) unaryFun!fun(a);\n        }));\n\n    enum isForeachUnaryWithIndexIterable(R) =\n        is(typeof((R r) {\n            foreach (i, ref a; r)\n                cast(void) binaryFun!BinaryArgs(i, a);\n        }));\n\n    enum isForeachBinaryIterable(R) =\n        is(typeof((R r) {\n            foreach (ref a, ref b; r)\n                cast(void) binaryFun!fun(a, b);\n        }));\n\n    enum isForeachIterable(R) =\n        (!isForwardRange!R || isDynamicArray!R) &&\n        (isForeachUnaryIterable!R || isForeachBinaryIterable!R ||\n         isForeachUnaryWithIndexIterable!R);\n\npublic:\n    /**\n    Params:\n        r = range or iterable over which each iterates\n     */\n    Flag!\"each\" each(Range)(Range r)\n    if (!isForeachIterable!Range && (\n        isRangeIterable!Range ||\n        __traits(compiles, typeof(r.front).length)))\n    {\n        static if (isRangeIterable!Range)\n        {\n            debug(each) pragma(msg, \"Using while for \", Range.stringof);\n            static if (isRangeUnaryIterable!Range)\n            {\n                while (!r.empty)\n                {\n                    static if (!is(typeof(unaryFun!fun(r.front)) == Flag!\"each\"))\n                    {\n                        cast(void) unaryFun!fun(r.front);\n                    }\n                    else\n                    {\n                        if (unaryFun!fun(r.front) == No.each) return No.each;\n                    }\n\n                    r.popFront();\n                }\n            }\n            else // if (isRangeBinaryIterable!Range)\n            {\n                size_t i = 0;\n                while (!r.empty)\n                {\n                    static if (!is(typeof(binaryFun!BinaryArgs(i, r.front)) == Flag!\"each\"))\n                    {\n                        cast(void) binaryFun!BinaryArgs(i, r.front);\n                    }\n                    else\n                    {\n                        if (binaryFun!BinaryArgs(i, r.front) == No.each) return No.each;\n                    }\n                    r.popFront();\n                    i++;\n                }\n            }\n        }\n        else\n        {\n            // range interface with >2 parameters.\n            for (auto range = r; !range.empty; range.popFront())\n            {\n                static if (!is(typeof(fun(r.front.expand)) == Flag!\"each\"))\n                {\n                    cast(void) fun(range.front.expand);\n                }\n                else\n                {\n                    if (fun(range.front.expand)) return No.each;\n                }\n            }\n        }\n        return Yes.each;\n    }\n\n    /// ditto\n    Flag!\"each\" each(Iterable)(auto ref Iterable r)\n    if (isForeachIterable!Iterable ||\n        __traits(compiles, Parameters!(Parameters!(r.opApply))))\n    {\n        static if (isForeachIterable!Iterable)\n        {\n            static if (isForeachUnaryIterable!Iterable)\n            {\n                debug(each) pragma(msg, \"Using foreach UNARY for \", Iterable.stringof);\n                {\n                    foreach (ref e; r)\n                    {\n                        static if (!is(typeof(unaryFun!fun(e)) == Flag!\"each\"))\n                        {\n                            cast(void) unaryFun!fun(e);\n                        }\n                        else\n                        {\n                            if (unaryFun!fun(e) == No.each) return No.each;\n                        }\n                    }\n                }\n            }\n            else static if (isForeachBinaryIterable!Iterable)\n            {\n                debug(each) pragma(msg, \"Using foreach BINARY for \", Iterable.stringof);\n                foreach (ref a, ref b; r)\n                {\n                    static if (!is(typeof(binaryFun!fun(a, b)) == Flag!\"each\"))\n                    {\n                        cast(void) binaryFun!fun(a, b);\n                    }\n                    else\n                    {\n                        if (binaryFun!fun(a, b) == No.each) return No.each;\n                    }\n                }\n            }\n            else static if (isForeachUnaryWithIndexIterable!Iterable)\n            {\n                debug(each) pragma(msg, \"Using foreach INDEX for \", Iterable.stringof);\n                foreach (i, ref e; r)\n                {\n                    static if (!is(typeof(binaryFun!BinaryArgs(i, e)) == Flag!\"each\"))\n                    {\n                        cast(void) binaryFun!BinaryArgs(i, e);\n                    }\n                    else\n                    {\n                        if (binaryFun!BinaryArgs(i, e) == No.each) return No.each;\n                    }\n                }\n            }\n            else\n            {\n                static assert(0, \"Invalid foreach iteratable type \" ~ Iterable.stringof ~ \" met.\");\n            }\n            return Yes.each;\n        }\n        else\n        {\n            // opApply with >2 parameters. count the delegate args.\n            // only works if it is not templated (otherwise we cannot count the args)\n            auto result = Yes.each;\n            auto dg(Parameters!(Parameters!(r.opApply)) params)\n            {\n                static if (!is(typeof(binaryFun!BinaryArgs(i, e)) == Flag!\"each\"))\n                {\n                    fun(params);\n                    return 0; // tells opApply to continue iteration\n                }\n                else\n                {\n                    result = fun(params);\n                    return result == Yes.each ? 0 : -1;\n                }\n            }\n            r.opApply(&dg);\n            return result;\n        }\n    }\n}\n\n///\n@system unittest\n{\n    import std.range : iota;\n    import std.typecons : Flag, Yes, No;\n\n    long[] arr;\n    iota(5).each!(n => arr ~= n);\n    assert(arr == [0, 1, 2, 3, 4]);\n    iota(5).each!((n) { arr ~= n; return No.each; });\n    assert(arr == [0, 1, 2, 3, 4, 0]);\n\n    // If the range supports it, the value can be mutated in place\n    arr.each!((ref n) => n++);\n    assert(arr == [1, 2, 3, 4, 5, 1]);\n\n    arr.each!\"a++\";\n    assert(arr == [2, 3, 4, 5, 6, 2]);\n\n    // by-ref lambdas are not allowed for non-ref ranges\n    static assert(!is(typeof(arr.map!(n => n).each!((ref n) => n++))));\n\n    // The default predicate consumes the range\n    auto m = arr.map!(n => n);\n    (&m).each();\n    assert(m.empty);\n\n    // Indexes are also available for in-place mutations\n    arr[] = 0;\n    arr.each!\"a=i\"();\n    assert(arr == [0, 1, 2, 3, 4, 5]);\n\n    // opApply iterators work as well\n    static class S\n    {\n        int x;\n        int opApply(scope int delegate(ref int _x) dg) { return dg(x); }\n    }\n\n    auto s = new S;\n    s.each!\"a++\";\n    assert(s.x == 1);\n}\n\n// binary foreach with two ref args\n@system unittest\n{\n    import std.range : lockstep;\n\n    auto a = [ 1, 2, 3 ];\n    auto b = [ 2, 3, 4 ];\n\n    a.lockstep(b).each!((ref x, ref y) { ++x; ++y; });\n\n    assert(a == [ 2, 3, 4 ]);\n    assert(b == [ 3, 4, 5 ]);\n}\n\n// #15358: application of `each` with >2 args (opApply)\n@system unittest\n{\n    import std.range : lockstep;\n    auto a = [0,1,2];\n    auto b = [3,4,5];\n    auto c = [6,7,8];\n\n    lockstep(a, b, c).each!((ref x, ref y, ref z) { ++x; ++y; ++z; });\n\n    assert(a == [1,2,3]);\n    assert(b == [4,5,6]);\n    assert(c == [7,8,9]);\n}\n\n// #15358: application of `each` with >2 args (range interface)\n@safe unittest\n{\n    import std.range : zip;\n    auto a = [0,1,2];\n    auto b = [3,4,5];\n    auto c = [6,7,8];\n\n    int[] res;\n\n    zip(a, b, c).each!((x, y, z) { res ~= x + y + z; });\n\n    assert(res == [9, 12, 15]);\n}\n\n// #16255: `each` on opApply doesn't support ref\n@safe unittest\n{\n    int[] dynamicArray = [1, 2, 3, 4, 5];\n    int[5] staticArray = [1, 2, 3, 4, 5];\n\n    dynamicArray.each!((ref x) => x++);\n    assert(dynamicArray == [2, 3, 4, 5, 6]);\n\n    staticArray.each!((ref x) => x++);\n    assert(staticArray == [2, 3, 4, 5, 6]);\n\n    staticArray[].each!((ref x) => x++);\n    assert(staticArray == [3, 4, 5, 6, 7]);\n}\n\n// #16255: `each` on opApply doesn't support ref\n@system unittest\n{\n    struct S\n    {\n       int x;\n       int opApply(int delegate(ref int _x) dg) { return dg(x); }\n    }\n\n    S s;\n    foreach (ref a; s) ++a;\n    assert(s.x == 1);\n    s.each!\"++a\";\n    assert(s.x == 2);\n}\n\n// #15357: `each` should behave similar to foreach\n/// `each` works with iterable objects which provide an index variable, along with each element\n@safe unittest\n{\n    import std.range : iota, lockstep;\n\n    auto arr = [1, 2, 3, 4];\n\n    // 1 ref parameter\n    arr.each!((ref e) => e = 0);\n    assert(arr.sum == 0);\n\n    // 1 ref parameter and index\n    arr.each!((i, ref e) => e = cast(int) i);\n    assert(arr.sum == 4.iota.sum);\n}\n\n// #15357: `each` should behave similar to foreach\n@system unittest\n{\n    import std.range : iota, lockstep;\n\n    // 2 ref parameters and index\n    auto arrA = [1, 2, 3, 4];\n    auto arrB = [5, 6, 7, 8];\n    lockstep(arrA, arrB).each!((ref a, ref b) {\n        a = 0;\n        b = 1;\n    });\n    assert(arrA.sum == 0);\n    assert(arrB.sum == 4);\n\n    // 3 ref parameters\n    auto arrC = [3, 3, 3, 3];\n    lockstep(arrA, arrB, arrC).each!((ref a, ref b, ref c) {\n        a = 1;\n        b = 2;\n        c = 3;\n    });\n    assert(arrA.sum == 4);\n    assert(arrB.sum == 8);\n    assert(arrC.sum == 12);\n}\n\n// #15357: `each` should behave similar to foreach\n@system unittest\n{\n    import std.range : lockstep;\n    import std.typecons : Tuple;\n\n    auto a = \"abc\";\n    auto b = \"def\";\n\n    // print each character with an index\n    {\n        alias Element = Tuple!(size_t, \"index\", dchar, \"value\");\n        Element[] rForeach, rEach;\n        foreach (i, c ; a) rForeach ~= Element(i, c);\n        a.each!((i, c) => rEach ~= Element(i, c));\n        assert(rForeach == rEach);\n        assert(rForeach == [Element(0, 'a'), Element(1, 'b'), Element(2, 'c')]);\n    }\n\n    // print pairs of characters\n    {\n        alias Element = Tuple!(dchar, \"a\", dchar, \"b\");\n        Element[] rForeach, rEach;\n        foreach (c1, c2 ; a.lockstep(b)) rForeach ~= Element(c1, c2);\n        a.lockstep(b).each!((c1, c2) => rEach ~= Element(c1, c2));\n        assert(rForeach == rEach);\n        assert(rForeach == [Element('a', 'd'), Element('b', 'e'), Element('c', 'f')]);\n    }\n}\n\n// filter\n/**\nImplements the higher order filter function. The predicate is passed to\n$(REF unaryFun, std,functional), and can either accept a string, or any callable\nthat can be executed via `pred(element)`.\n\nParams:\n    predicate = Function to apply to each element of range\n\nReturns:\n    `filter!(predicate)(range)` returns a new range containing only elements `x` in `range` for\n    which `predicate(x)` returns `true`.\n\nSee_Also:\n    $(HTTP en.wikipedia.org/wiki/Filter_(higher-order_function), Filter (higher-order function))\n */\ntemplate filter(alias predicate)\nif (is(typeof(unaryFun!predicate)))\n{\n    /**\n    Params:\n        range = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n        of elements\n    Returns:\n        A range containing only elements `x` in `range` for\n        which `predicate(x)` returns `true`.\n     */\n    auto filter(Range)(Range range) if (isInputRange!(Unqual!Range))\n    {\n        return FilterResult!(unaryFun!predicate, Range)(range);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.math : approxEqual;\n    import std.range;\n\n    int[] arr = [ 1, 2, 3, 4, 5 ];\n\n    // Filter below 3\n    auto small = filter!(a => a < 3)(arr);\n    assert(equal(small, [ 1, 2 ]));\n\n    // Filter again, but with Uniform Function Call Syntax (UFCS)\n    auto sum = arr.filter!(a => a < 3);\n    assert(equal(sum, [ 1, 2 ]));\n\n    // In combination with chain() to span multiple ranges\n    int[] a = [ 3, -2, 400 ];\n    int[] b = [ 100, -101, 102 ];\n    auto r = chain(a, b).filter!(a => a > 0);\n    assert(equal(r, [ 3, 400, 100, 102 ]));\n\n    // Mixing convertible types is fair game, too\n    double[] c = [ 2.5, 3.0 ];\n    auto r1 = chain(c, a, b).filter!(a => cast(int) a != a);\n    assert(approxEqual(r1, [ 2.5 ]));\n}\n\nprivate struct FilterResult(alias pred, Range)\n{\n    alias R = Unqual!Range;\n    R _input;\n    private bool _primed;\n\n    private void prime()\n    {\n        if (_primed) return;\n        while (!_input.empty && !pred(_input.front))\n        {\n            _input.popFront();\n        }\n        _primed = true;\n    }\n\n    this(R r)\n    {\n        _input = r;\n    }\n\n    private this(R r, bool primed)\n    {\n        _input = r;\n        _primed = primed;\n    }\n\n    auto opSlice() { return this; }\n\n    static if (isInfinite!Range)\n    {\n        enum bool empty = false;\n    }\n    else\n    {\n        @property bool empty() { prime; return _input.empty; }\n    }\n\n    void popFront()\n    {\n        do\n        {\n            _input.popFront();\n        } while (!_input.empty && !pred(_input.front));\n        _primed = true;\n    }\n\n    @property auto ref front()\n    {\n        prime;\n        assert(!empty, \"Attempting to fetch the front of an empty filter.\");\n        return _input.front;\n    }\n\n    static if (isForwardRange!R)\n    {\n        @property auto save()\n        {\n            return typeof(this)(_input.save, _primed);\n        }\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange;\n    import std.range;\n\n    auto shouldNotLoop4ever = repeat(1).filter!(x => x % 2 == 0);\n    static assert(isInfinite!(typeof(shouldNotLoop4ever)));\n    assert(!shouldNotLoop4ever.empty);\n\n    int[] a = [ 3, 4, 2 ];\n    auto r = filter!(\"a > 3\")(a);\n    static assert(isForwardRange!(typeof(r)));\n    assert(equal(r, [ 4 ][]));\n\n    a = [ 1, 22, 3, 42, 5 ];\n    auto under10 = filter!(\"a < 10\")(a);\n    assert(equal(under10, [1, 3, 5][]));\n    static assert(isForwardRange!(typeof(under10)));\n    under10.front = 4;\n    assert(equal(under10, [4, 3, 5][]));\n    under10.front = 40;\n    assert(equal(under10, [40, 3, 5][]));\n    under10.front = 1;\n\n    auto infinite = filter!\"a > 2\"(repeat(3));\n    static assert(isInfinite!(typeof(infinite)));\n    static assert(isForwardRange!(typeof(infinite)));\n    assert(infinite.front == 3);\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType d;\n        auto f = filter!\"a & 1\"(d);\n        assert(equal(f, [1,3,5,7,9]));\n\n        static if (isForwardRange!DummyType)\n        {\n            static assert(isForwardRange!(typeof(f)));\n        }\n    }\n\n    // With delegates\n    int x = 10;\n    int overX(int a) { return a > x; }\n    typeof(filter!overX(a)) getFilter()\n    {\n        return filter!overX(a);\n    }\n    auto r1 = getFilter();\n    assert(equal(r1, [22, 42]));\n\n    // With chain\n    auto nums = [0,1,2,3,4];\n    assert(equal(filter!overX(chain(a, nums)), [22, 42]));\n\n    // With copying of inner struct Filter to Map\n    auto arr = [1,2,3,4,5];\n    auto m = map!\"a + 1\"(filter!\"a < 4\"(arr));\n    assert(equal(m, [2, 3, 4]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[] a = [ 3, 4 ];\n    const aConst = a;\n    auto r = filter!(\"a > 3\")(aConst);\n    assert(equal(r, [ 4 ][]));\n\n    a = [ 1, 22, 3, 42, 5 ];\n    auto under10 = filter!(\"a < 10\")(a);\n    assert(equal(under10, [1, 3, 5][]));\n    assert(equal(under10.save, [1, 3, 5][]));\n    assert(equal(under10.save, under10));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.functional : compose, pipe;\n\n    assert(equal(compose!(map!\"2 * a\", filter!\"a & 1\")([1,2,3,4,5]),\n                    [2,6,10]));\n    assert(equal(pipe!(filter!\"a & 1\", map!\"2 * a\")([1,2,3,4,5]),\n            [2,6,10]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int x = 10;\n    int underX(int a) { return a < x; }\n    const(int)[] list = [ 1, 2, 10, 11, 3, 4 ];\n    assert(equal(filter!underX(list), [ 1, 2, 3, 4 ]));\n}\n\n/**\n * Similar to `filter`, except it defines a\n * $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives).\n * There is a speed disadvantage - the constructor spends time\n * finding the last element in the range that satisfies the filtering\n * condition (in addition to finding the first one). The advantage is\n * that the filtered range can be spanned from both directions. Also,\n * $(REF retro, std,range) can be applied against the filtered range.\n *\n * The predicate is passed to $(REF unaryFun, std,functional), and can either\n * accept a string, or any callable that can be executed via `pred(element)`.\n *\n * Params:\n *     pred = Function to apply to each element of range\n */\ntemplate filterBidirectional(alias pred)\n{\n    /**\n    Params:\n        r = Bidirectional range of elements\n    Returns:\n        A range containing only the elements in `r` for which `pred` returns `true`.\n     */\n    auto filterBidirectional(Range)(Range r) if (isBidirectionalRange!(Unqual!Range))\n    {\n        return FilterBidiResult!(unaryFun!pred, Range)(r);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range;\n\n    int[] arr = [ 1, 2, 3, 4, 5 ];\n    auto small = filterBidirectional!(\"a < 3\")(arr);\n    static assert(isBidirectionalRange!(typeof(small)));\n    assert(small.back == 2);\n    assert(equal(small, [ 1, 2 ]));\n    assert(equal(retro(small), [ 2, 1 ]));\n    // In combination with chain() to span multiple ranges\n    int[] a = [ 3, -2, 400 ];\n    int[] b = [ 100, -101, 102 ];\n    auto r = filterBidirectional!(\"a > 0\")(chain(a, b));\n    assert(r.back == 102);\n}\n\nprivate struct FilterBidiResult(alias pred, Range)\n{\n    alias R = Unqual!Range;\n    R _input;\n\n    this(R r)\n    {\n        _input = r;\n        while (!_input.empty && !pred(_input.front)) _input.popFront();\n        while (!_input.empty && !pred(_input.back)) _input.popBack();\n    }\n\n    @property bool empty() { return _input.empty; }\n\n    void popFront()\n    {\n        do\n        {\n            _input.popFront();\n        } while (!_input.empty && !pred(_input.front));\n    }\n\n    @property auto ref front()\n    {\n        assert(!empty, \"Attempting to fetch the front of an empty filterBidirectional.\");\n        return _input.front;\n    }\n\n    void popBack()\n    {\n        do\n        {\n            _input.popBack();\n        } while (!_input.empty && !pred(_input.back));\n    }\n\n    @property auto ref back()\n    {\n        assert(!empty, \"Attempting to fetch the back of an empty filterBidirectional.\");\n        return _input.back;\n    }\n\n    @property auto save()\n    {\n        return typeof(this)(_input.save);\n    }\n}\n\n/**\nGroups consecutively equivalent elements into a single tuple of the element and\nthe number of its repetitions.\n\nSimilarly to `uniq`, `group` produces a range that iterates over unique\nconsecutive elements of the given range. Each element of this range is a tuple\nof the element and the number of times it is repeated in the original range.\nEquivalence of elements is assessed by using the predicate `pred`, which\ndefaults to `\"a == b\"`.  The predicate is passed to $(REF binaryFun, std,functional),\nand can either accept a string, or any callable that can be executed via\n`pred(element, element)`.\n\nParams:\n    pred = Binary predicate for determining equivalence of two elements.\n    R = The range type\n    r = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to\n        iterate over.\n\nReturns: A range of elements of type `Tuple!(ElementType!R, uint)`,\nrepresenting each consecutively unique element and its respective number of\noccurrences in that run.  This will be an input range if `R` is an input\nrange, and a forward range in all other cases.\n\nSee_Also: $(LREF chunkBy), which chunks an input range into subranges\n    of equivalent adjacent elements.\n*/\nGroup!(pred, Range) group(alias pred = \"a == b\", Range)(Range r)\n{\n    return typeof(return)(r);\n}\n\n/// ditto\nstruct Group(alias pred, R)\nif (isInputRange!R)\n{\n    import std.typecons : Rebindable, tuple, Tuple;\n\n    private alias comp = binaryFun!pred;\n\n    private alias E = ElementType!R;\n    static if ((is(E == class) || is(E == interface)) &&\n               (is(E == const) || is(E == immutable)))\n    {\n        private alias MutableE = Rebindable!E;\n    }\n    else static if (is(E : Unqual!E))\n    {\n        private alias MutableE = Unqual!E;\n    }\n    else\n    {\n        private alias MutableE = E;\n    }\n\n    private R _input;\n    private Tuple!(MutableE, uint) _current;\n\n    ///\n    this(R input)\n    {\n        _input = input;\n        if (!_input.empty) popFront();\n    }\n\n    ///\n    void popFront()\n    {\n        if (_input.empty)\n        {\n            _current[1] = 0;\n        }\n        else\n        {\n            _current = tuple(_input.front, 1u);\n            _input.popFront();\n            while (!_input.empty && comp(_current[0], _input.front))\n            {\n                ++_current[1];\n                _input.popFront();\n            }\n        }\n    }\n\n    static if (isInfinite!R)\n    {\n        ///\n        enum bool empty = false;  // Propagate infiniteness.\n    }\n    else\n    {\n        ///\n        @property bool empty()\n        {\n            return _current[1] == 0;\n        }\n    }\n\n    /// Returns: the front of the range\n    @property auto ref front()\n    {\n        assert(!empty, \"Attempting to fetch the front of an empty Group.\");\n        return _current;\n    }\n\n    static if (isForwardRange!R)\n    {\n        ///\n        @property typeof(this) save() {\n            typeof(this) ret = this;\n            ret._input = this._input.save;\n            ret._current = this._current;\n            return ret;\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : tuple, Tuple;\n\n    int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];\n    assert(equal(group(arr), [ tuple(1, 1u), tuple(2, 4u), tuple(3, 1u),\n        tuple(4, 3u), tuple(5, 1u) ][]));\n}\n\n/**\n * Using group, an associative array can be easily generated with the count of each\n * unique element in the range.\n */\n@safe unittest\n{\n    import std.algorithm.sorting : sort;\n    import std.array : assocArray;\n\n    uint[string] result;\n    auto range = [\"a\", \"b\", \"a\", \"c\", \"b\", \"c\", \"c\", \"d\", \"e\"];\n    result = range.sort!((a, b) => a < b)\n        .group\n        .assocArray;\n\n    assert(result == [\"a\": 2U, \"b\": 2U, \"c\": 3U, \"d\": 1U, \"e\": 1U]);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange;\n    import std.typecons : tuple, Tuple;\n\n    int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];\n    assert(equal(group(arr), [ tuple(1, 1u), tuple(2, 4u), tuple(3, 1u),\n                            tuple(4, 3u), tuple(5, 1u) ][]));\n    static assert(isForwardRange!(typeof(group(arr))));\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType d;\n        auto g = group(d);\n\n        static assert(d.rt == RangeType.Input || isForwardRange!(typeof(g)));\n\n        assert(equal(g, [tuple(1, 1u), tuple(2, 1u), tuple(3, 1u), tuple(4, 1u),\n            tuple(5, 1u), tuple(6, 1u), tuple(7, 1u), tuple(8, 1u),\n            tuple(9, 1u), tuple(10, 1u)]));\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : tuple;\n\n    // Issue 13857\n    immutable(int)[] a1 = [1,1,2,2,2,3,4,4,5,6,6,7,8,9,9,9];\n    auto g1 = group(a1);\n    assert(equal(g1, [ tuple(1, 2u), tuple(2, 3u), tuple(3, 1u),\n                       tuple(4, 2u), tuple(5, 1u), tuple(6, 2u),\n                       tuple(7, 1u), tuple(8, 1u), tuple(9, 3u)\n                     ]));\n\n    // Issue 13162\n    immutable(ubyte)[] a2 = [1, 1, 1, 0, 0, 0];\n    auto g2 = a2.group;\n    assert(equal(g2, [ tuple(1, 3u), tuple(0, 3u) ]));\n\n    // Issue 10104\n    const a3 = [1, 1, 2, 2];\n    auto g3 = a3.group;\n    assert(equal(g3, [ tuple(1, 2u), tuple(2, 2u) ]));\n\n    interface I {}\n    class C : I {}\n    const C[] a4 = [new const C()];\n    auto g4 = a4.group!\"a is b\";\n    assert(g4.front[1] == 1);\n\n    immutable I[] a5 = [new immutable C()];\n    auto g5 = a5.group!\"a is b\";\n    assert(g5.front[1] == 1);\n\n    const(int[][]) a6 = [[1], [1]];\n    auto g6 = a6.group;\n    assert(equal(g6.front[0], [1]));\n}\n\n// Used by implementation of chunkBy for non-forward input ranges.\nprivate struct ChunkByChunkImpl(alias pred, Range)\nif (isInputRange!Range && !isForwardRange!Range)\n{\n    alias fun = binaryFun!pred;\n\n    private Range r;\n    private ElementType!Range prev;\n\n    this(Range range, ElementType!Range _prev)\n    {\n        r = range;\n        prev = _prev;\n    }\n\n    @property bool empty()\n    {\n        return r.empty || !fun(prev, r.front);\n    }\n\n    @property ElementType!Range front() { return r.front; }\n    void popFront() { r.popFront(); }\n}\n\nprivate template ChunkByImplIsUnary(alias pred, Range)\n{\n    static if (is(typeof(binaryFun!pred(ElementType!Range.init,\n                                        ElementType!Range.init)) : bool))\n        enum ChunkByImplIsUnary = false;\n    else static if (is(typeof(\n            unaryFun!pred(ElementType!Range.init) ==\n            unaryFun!pred(ElementType!Range.init))))\n        enum ChunkByImplIsUnary = true;\n    else\n        static assert(0, \"chunkBy expects either a binary predicate or \"~\n                         \"a unary predicate on range elements of type: \"~\n                         ElementType!Range.stringof);\n}\n\n// Implementation of chunkBy for non-forward input ranges.\nprivate struct ChunkByImpl(alias pred, Range)\nif (isInputRange!Range && !isForwardRange!Range)\n{\n    enum bool isUnary = ChunkByImplIsUnary!(pred, Range);\n\n    static if (isUnary)\n        alias eq = binaryFun!((a, b) => unaryFun!pred(a) == unaryFun!pred(b));\n    else\n        alias eq = binaryFun!pred;\n\n    private Range r;\n    private ElementType!Range _prev;\n\n    this(Range _r)\n    {\n        r = _r;\n        if (!empty)\n        {\n            // Check reflexivity if predicate is claimed to be an equivalence\n            // relation.\n            assert(eq(r.front, r.front),\n                   \"predicate is not reflexive\");\n\n            // _prev's type may be a nested struct, so must be initialized\n            // directly in the constructor (cannot call savePred()).\n            _prev = r.front;\n        }\n        else\n        {\n            // We won't use _prev, but must be initialized.\n            _prev = typeof(_prev).init;\n        }\n    }\n    @property bool empty() { return r.empty; }\n\n    @property auto front()\n    {\n        static if (isUnary)\n        {\n            import std.typecons : tuple;\n            return tuple(unaryFun!pred(_prev),\n                         ChunkByChunkImpl!(eq, Range)(r, _prev));\n        }\n        else\n        {\n            return ChunkByChunkImpl!(eq, Range)(r, _prev);\n        }\n    }\n\n    void popFront()\n    {\n        while (!r.empty)\n        {\n            if (!eq(_prev, r.front))\n            {\n                _prev = r.front;\n                break;\n            }\n            r.popFront();\n        }\n    }\n}\n\n// Single-pass implementation of chunkBy for forward ranges.\nprivate struct ChunkByImpl(alias pred, Range)\nif (isForwardRange!Range)\n{\n    import std.typecons : RefCounted;\n\n    enum bool isUnary = ChunkByImplIsUnary!(pred, Range);\n\n    static if (isUnary)\n        alias eq = binaryFun!((a, b) => unaryFun!pred(a) == unaryFun!pred(b));\n    else\n        alias eq = binaryFun!pred;\n\n    // Outer range\n    static struct Impl\n    {\n        size_t groupNum;\n        Range  current;\n        Range  next;\n    }\n\n    // Inner range\n    static struct Group\n    {\n        private size_t groupNum;\n        private Range  start;\n        private Range  current;\n\n        private RefCounted!Impl mothership;\n\n        this(RefCounted!Impl origin)\n        {\n            groupNum = origin.groupNum;\n\n            start = origin.current.save;\n            current = origin.current.save;\n            assert(!start.empty);\n\n            mothership = origin;\n\n            // Note: this requires reflexivity.\n            assert(eq(start.front, current.front),\n                   \"predicate is not reflexive\");\n        }\n\n        @property bool empty() { return groupNum == size_t.max; }\n        @property auto ref front() { return current.front; }\n\n        void popFront()\n        {\n            current.popFront();\n\n            // Note: this requires transitivity.\n            if (current.empty || !eq(start.front, current.front))\n            {\n                if (groupNum == mothership.groupNum)\n                {\n                    // If parent range hasn't moved on yet, help it along by\n                    // saving location of start of next Group.\n                    mothership.next = current.save;\n                }\n\n                groupNum = size_t.max;\n            }\n        }\n\n        @property auto save()\n        {\n            auto copy = this;\n            copy.current = current.save;\n            return copy;\n        }\n    }\n    static assert(isForwardRange!Group);\n\n    private RefCounted!Impl impl;\n\n    this(Range r)\n    {\n        impl = RefCounted!Impl(0, r, r.save);\n    }\n\n    @property bool empty() { return impl.current.empty; }\n\n    @property auto front()\n    {\n        static if (isUnary)\n        {\n            import std.typecons : tuple;\n            return tuple(unaryFun!pred(impl.current.front), Group(impl));\n        }\n        else\n        {\n            return Group(impl);\n        }\n    }\n\n    void popFront()\n    {\n        // Scan for next group. If we're lucky, one of our Groups would have\n        // already set .next to the start of the next group, in which case the\n        // loop is skipped.\n        while (!impl.next.empty && eq(impl.current.front, impl.next.front))\n        {\n            impl.next.popFront();\n        }\n\n        impl.current = impl.next.save;\n\n        // Indicate to any remaining Groups that we have moved on.\n        impl.groupNum++;\n    }\n\n    @property auto save()\n    {\n        // Note: the new copy of the range will be detached from any existing\n        // satellite Groups, and will not benefit from the .next acceleration.\n        return typeof(this)(impl.current.save);\n    }\n\n    static assert(isForwardRange!(typeof(this)));\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    size_t popCount = 0;\n    class RefFwdRange\n    {\n        int[]  impl;\n\n        @safe nothrow:\n\n        this(int[] data) { impl = data; }\n        @property bool empty() { return impl.empty; }\n        @property auto ref front() { return impl.front; }\n        void popFront()\n        {\n            impl.popFront();\n            popCount++;\n        }\n        @property auto save() { return new RefFwdRange(impl); }\n    }\n    static assert(isForwardRange!RefFwdRange);\n\n    auto testdata = new RefFwdRange([1, 3, 5, 2, 4, 7, 6, 8, 9]);\n    auto groups = testdata.chunkBy!((a,b) => (a % 2) == (b % 2));\n    auto outerSave1 = groups.save;\n\n    // Sanity test\n    assert(groups.equal!equal([[1, 3, 5], [2, 4], [7], [6, 8], [9]]));\n    assert(groups.empty);\n\n    // Performance test for single-traversal use case: popFront should not have\n    // been called more times than there are elements if we traversed the\n    // segmented range exactly once.\n    assert(popCount == 9);\n\n    // Outer range .save test\n    groups = outerSave1.save;\n    assert(!groups.empty);\n\n    // Inner range .save test\n    auto grp1 = groups.front.save;\n    auto grp1b = grp1.save;\n    assert(grp1b.equal([1, 3, 5]));\n    assert(grp1.save.equal([1, 3, 5]));\n\n    // Inner range should remain consistent after outer range has moved on.\n    groups.popFront();\n    assert(grp1.save.equal([1, 3, 5]));\n\n    // Inner range should not be affected by subsequent inner ranges.\n    assert(groups.front.equal([2, 4]));\n    assert(grp1.save.equal([1, 3, 5]));\n}\n\n/**\n * Chunks an input range into subranges of equivalent adjacent elements.\n * In other languages this is often called `partitionBy`, `groupBy`\n * or `sliceWhen`.\n *\n * Equivalence is defined by the predicate `pred`, which can be either\n * binary, which is passed to $(REF binaryFun, std,functional), or unary, which is\n * passed to $(REF unaryFun, std,functional). In the binary form, two range elements\n * `a` and `b` are considered equivalent if `pred(a,b)` is true. In\n * unary form, two elements are considered equivalent if `pred(a) == pred(b)`\n * is true.\n *\n * This predicate must be an equivalence relation, that is, it must be\n * reflexive (`pred(x,x)` is always true), symmetric\n * (`pred(x,y) == pred(y,x)`), and transitive (`pred(x,y) && pred(y,z)`\n * implies `pred(x,z)`). If this is not the case, the range returned by\n * chunkBy may assert at runtime or behave erratically.\n *\n * Params:\n *  pred = Predicate for determining equivalence.\n *  r = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to be chunked.\n *\n * Returns: With a binary predicate, a range of ranges is returned in which\n * all elements in a given subrange are equivalent under the given predicate.\n * With a unary predicate, a range of tuples is returned, with the tuple\n * consisting of the result of the unary predicate for each subrange, and the\n * subrange itself.\n *\n * Notes:\n *\n * Equivalent elements separated by an intervening non-equivalent element will\n * appear in separate subranges; this function only considers adjacent\n * equivalence. Elements in the subranges will always appear in the same order\n * they appear in the original range.\n *\n * See_also:\n * $(LREF group), which collapses adjacent equivalent elements into a single\n * element.\n */\nauto chunkBy(alias pred, Range)(Range r)\nif (isInputRange!Range)\n{\n    return ChunkByImpl!(pred, Range)(r);\n}\n\n/// Showing usage with binary predicate:\n/*FIXME: @safe*/ @system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // Grouping by particular attribute of each element:\n    auto data = [\n        [1, 1],\n        [1, 2],\n        [2, 2],\n        [2, 3]\n    ];\n\n    auto r1 = data.chunkBy!((a,b) => a[0] == b[0]);\n    assert(r1.equal!equal([\n        [[1, 1], [1, 2]],\n        [[2, 2], [2, 3]]\n    ]));\n\n    auto r2 = data.chunkBy!((a,b) => a[1] == b[1]);\n    assert(r2.equal!equal([\n        [[1, 1]],\n        [[1, 2], [2, 2]],\n        [[2, 3]]\n    ]));\n}\n\nversion (none) // this example requires support for non-equivalence relations\n@safe unittest\n{\n    // Grouping by maximum adjacent difference:\n    import std.math : abs;\n    auto r3 = [1, 3, 2, 5, 4, 9, 10].chunkBy!((a, b) => abs(a-b) < 3);\n    assert(r3.equal!equal([\n        [1, 3, 2],\n        [5, 4],\n        [9, 10]\n    ]));\n\n}\n\n/// Showing usage with unary predicate:\n/* FIXME: pure @safe nothrow*/ @system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range.primitives;\n    import std.typecons : tuple;\n\n    // Grouping by particular attribute of each element:\n    auto range =\n    [\n        [1, 1],\n        [1, 1],\n        [1, 2],\n        [2, 2],\n        [2, 3],\n        [2, 3],\n        [3, 3]\n    ];\n\n    auto byX = chunkBy!(a => a[0])(range);\n    auto expected1 =\n    [\n        tuple(1, [[1, 1], [1, 1], [1, 2]]),\n        tuple(2, [[2, 2], [2, 3], [2, 3]]),\n        tuple(3, [[3, 3]])\n    ];\n    foreach (e; byX)\n    {\n        assert(!expected1.empty);\n        assert(e[0] == expected1.front[0]);\n        assert(e[1].equal(expected1.front[1]));\n        expected1.popFront();\n    }\n\n    auto byY = chunkBy!(a => a[1])(range);\n    auto expected2 =\n    [\n        tuple(1, [[1, 1], [1, 1]]),\n        tuple(2, [[1, 2], [2, 2]]),\n        tuple(3, [[2, 3], [2, 3], [3, 3]])\n    ];\n    foreach (e; byY)\n    {\n        assert(!expected2.empty);\n        assert(e[0] == expected2.front[0]);\n        assert(e[1].equal(expected2.front[1]));\n        expected2.popFront();\n    }\n}\n\n/*FIXME: pure @safe nothrow*/ @system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : tuple;\n\n    struct Item { int x, y; }\n\n    // Force R to have only an input range API with reference semantics, so\n    // that we're not unknowingly making use of array semantics outside of the\n    // range API.\n    class RefInputRange(R)\n    {\n        R data;\n        this(R _data) pure @safe nothrow { data = _data; }\n        @property bool empty() pure @safe nothrow { return data.empty; }\n        @property auto front() pure @safe nothrow { return data.front; }\n        void popFront() pure @safe nothrow { data.popFront(); }\n    }\n    auto refInputRange(R)(R range) { return new RefInputRange!R(range); }\n\n    {\n        auto arr = [ Item(1,2), Item(1,3), Item(2,3) ];\n        static assert(isForwardRange!(typeof(arr)));\n\n        auto byX = chunkBy!(a => a.x)(arr);\n        static assert(isForwardRange!(typeof(byX)));\n\n        auto byX_subrange1 = byX.front[1].save;\n        auto byX_subrange2 = byX.front[1].save;\n        static assert(isForwardRange!(typeof(byX_subrange1)));\n        static assert(isForwardRange!(typeof(byX_subrange2)));\n\n        byX.popFront();\n        assert(byX_subrange1.equal([ Item(1,2), Item(1,3) ]));\n        byX_subrange1.popFront();\n        assert(byX_subrange1.equal([ Item(1,3) ]));\n        assert(byX_subrange2.equal([ Item(1,2), Item(1,3) ]));\n\n        auto byY = chunkBy!(a => a.y)(arr);\n        static assert(isForwardRange!(typeof(byY)));\n\n        auto byY2 = byY.save;\n        static assert(is(typeof(byY) == typeof(byY2)));\n        byY.popFront();\n        assert(byY.front[0] == 3);\n        assert(byY.front[1].equal([ Item(1,3), Item(2,3) ]));\n        assert(byY2.front[0] == 2);\n        assert(byY2.front[1].equal([ Item(1,2) ]));\n    }\n\n    // Test non-forward input ranges.\n    {\n        auto range = refInputRange([ Item(1,1), Item(1,2), Item(2,2) ]);\n        auto byX = chunkBy!(a => a.x)(range);\n        assert(byX.front[0] == 1);\n        assert(byX.front[1].equal([ Item(1,1), Item(1,2) ]));\n        byX.popFront();\n        assert(byX.front[0] == 2);\n        assert(byX.front[1].equal([ Item(2,2) ]));\n        byX.popFront();\n        assert(byX.empty);\n        assert(range.empty);\n\n        range = refInputRange([ Item(1,1), Item(1,2), Item(2,2) ]);\n        auto byY = chunkBy!(a => a.y)(range);\n        assert(byY.front[0] == 1);\n        assert(byY.front[1].equal([ Item(1,1) ]));\n        byY.popFront();\n        assert(byY.front[0] == 2);\n        assert(byY.front[1].equal([ Item(1,2), Item(2,2) ]));\n        byY.popFront();\n        assert(byY.empty);\n        assert(range.empty);\n    }\n}\n\n// Issue 13595\nversion (none) // This requires support for non-equivalence relations\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    auto r = [1, 2, 3, 4, 5, 6, 7, 8, 9].chunkBy!((x, y) => ((x*y) % 3) == 0);\n    assert(r.equal!equal([\n        [1],\n        [2, 3, 4],\n        [5, 6, 7],\n        [8, 9]\n    ]));\n}\n\n// Issue 13805\n@system unittest\n{\n    [\"\"].map!((s) => s).chunkBy!((x, y) => true);\n}\n\n// joiner\n/**\nLazily joins a range of ranges with a separator. The separator itself\nis a range. If a separator is not provided, then the ranges are\njoined directly without anything in between them (often called `flatten`\nin other languages).\n\nParams:\n    r = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of input\n        ranges to be joined.\n    sep = A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) of\n        element(s) to serve as separators in the joined range.\n\nReturns:\nA range of elements in the joined range. This will be a forward range if\nboth outer and inner ranges of `RoR` are forward ranges; otherwise it will\nbe only an input range. The\n$(REF_ALTTEXT range bidirectionality, isBidirectionalRange, std,range,primitives)\nis propagated if no separator is specified.\n\nSee_also:\n$(REF chain, std,range), which chains a sequence of ranges with compatible elements\ninto a single range.\n */\nauto joiner(RoR, Separator)(RoR r, Separator sep)\nif (isInputRange!RoR && isInputRange!(ElementType!RoR)\n        && isForwardRange!Separator\n        && is(ElementType!Separator : ElementType!(ElementType!RoR)))\n{\n    static struct Result\n    {\n        private RoR _items;\n        private ElementType!RoR _current;\n        static if (isRandomAccessRange!Separator)\n        {\n            static struct CurrentSep\n            {\n                private Separator _sep;\n                private size_t sepIndex;\n                private size_t sepLength; // cache the length for performance\n                auto front() { return _sep[sepIndex]; }\n                void popFront() { sepIndex++; }\n                auto empty() { return sepIndex >= sepLength; }\n                auto save()\n                {\n                    auto copy = this;\n                    copy._sep = _sep;\n                    return copy;\n                }\n                void reset()\n                {\n                    sepIndex = 0;\n                }\n\n                void initialize(Separator sep)\n                {\n                    _sep = sep;\n                    sepIndex = sepLength = _sep.length;\n                }\n            }\n        }\n        else\n        {\n            static struct CurrentSep\n            {\n                private Separator _sep;\n                Separator payload;\n\n                alias payload this;\n\n                auto save()\n                {\n                    auto copy = this;\n                    copy._sep = _sep;\n                    return copy;\n                }\n\n                void reset()\n                {\n                    payload = _sep.save;\n                }\n\n                void initialize(Separator sep)\n                {\n                    _sep = sep;\n                }\n            }\n        }\n\n        private CurrentSep _currentSep;\n\n        private void setItem()\n        {\n            if (!_items.empty)\n            {\n                // If we're exporting .save, we must not consume any of the\n                // subranges, since RoR.save does not guarantee that the states\n                // of the subranges are also saved.\n                static if (isForwardRange!RoR &&\n                           isForwardRange!(ElementType!RoR))\n                    _current = _items.front.save;\n                else\n                    _current = _items.front;\n            }\n        }\n\n        private void useSeparator()\n        {\n            // Separator must always come after an item.\n            assert(_currentSep.empty && !_items.empty,\n                    \"joiner: internal error\");\n            _items.popFront();\n\n            // If there are no more items, we're done, since separators are not\n            // terminators.\n            if (_items.empty) return;\n\n            if (_currentSep._sep.empty)\n            {\n                // Advance to the next range in the\n                // input\n                while (_items.front.empty)\n                {\n                    _items.popFront();\n                    if (_items.empty) return;\n                }\n                setItem;\n            }\n            else\n            {\n                _currentSep.reset;\n                assert(!_currentSep.empty);\n            }\n        }\n\n        this(RoR items, Separator sep)\n        {\n            _items = items;\n            _currentSep.initialize(sep);\n\n            //mixin(useItem); // _current should be initialized in place\n            if (_items.empty)\n                _current = _current.init;   // set invalid state\n            else\n            {\n                // If we're exporting .save, we must not consume any of the\n                // subranges, since RoR.save does not guarantee that the states\n                // of the subranges are also saved.\n                static if (isForwardRange!RoR &&\n                           isForwardRange!(ElementType!RoR))\n                    _current = _items.front.save;\n                else\n                    _current = _items.front;\n\n                if (_current.empty)\n                {\n                    // No data in the current item - toggle to use the separator\n                    useSeparator();\n                }\n            }\n        }\n\n        @property auto empty()\n        {\n            return _items.empty;\n        }\n\n        @property ElementType!(ElementType!RoR) front()\n        {\n            if (!_currentSep.empty) return _currentSep.front;\n            assert(!_current.empty, \"Attempting to fetch the front of an empty joiner.\");\n            return _current.front;\n        }\n\n        void popFront()\n        {\n            assert(!_items.empty, \"Attempting to popFront an empty joiner.\");\n            // Using separator?\n            if (!_currentSep.empty)\n            {\n                _currentSep.popFront();\n                if (_currentSep.empty && !_items.empty)\n                {\n                    setItem;\n                    if (_current.empty)\n                    {\n                        // No data in the current item - toggle to use the separator\n                        useSeparator();\n                    }\n                }\n            }\n            else\n            {\n                // we're using the range\n                _current.popFront();\n                if (_current.empty)\n                    useSeparator();\n            }\n        }\n\n        static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))\n        {\n            @property auto save()\n            {\n                Result copy = this;\n                copy._items = _items.save;\n                copy._current = _current.save;\n                copy._currentSep = _currentSep.save;\n                return copy;\n            }\n        }\n    }\n    return Result(r, sep);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : text;\n\n    assert([\"abc\", \"def\"].joiner.equal(\"abcdef\"));\n    assert([\"Mary\", \"has\", \"a\", \"little\", \"lamb\"]\n        .joiner(\"...\")\n        .equal(\"Mary...has...a...little...lamb\"));\n    assert([\"\", \"abc\"].joiner(\"xyz\").equal(\"xyzabc\"));\n    assert([\"\"].joiner(\"xyz\").equal(\"\"));\n    assert([\"\", \"\"].joiner(\"xyz\").equal(\"xyz\"));\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range.interfaces;\n    import std.range.primitives;\n    // joiner() should work for non-forward ranges too.\n    auto r = inputRangeObject([\"abc\", \"def\"]);\n    assert(equal(joiner(r, \"xyz\"), \"abcxyzdef\"));\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range;\n\n    // Related to issue 8061\n    auto r = joiner([\n        inputRangeObject(\"abc\"),\n        inputRangeObject(\"def\"),\n    ], \"-*-\");\n\n    assert(equal(r, \"abc-*-def\"));\n\n    // Test case where separator is specified but is empty.\n    auto s = joiner([\n        inputRangeObject(\"abc\"),\n        inputRangeObject(\"def\"),\n    ], \"\");\n\n    assert(equal(s, \"abcdef\"));\n\n    // Test empty separator with some empty elements\n    auto t = joiner([\n        inputRangeObject(\"abc\"),\n        inputRangeObject(\"\"),\n        inputRangeObject(\"def\"),\n        inputRangeObject(\"\"),\n    ], \"\");\n\n    assert(equal(t, \"abcdef\"));\n\n    // Test empty elements with non-empty separator\n    auto u = joiner([\n        inputRangeObject(\"\"),\n        inputRangeObject(\"abc\"),\n        inputRangeObject(\"\"),\n        inputRangeObject(\"def\"),\n        inputRangeObject(\"\"),\n    ], \"+-\");\n\n    assert(equal(u, \"+-abc+-+-def+-\"));\n\n    // Issue 13441: only(x) as separator\n    string[][] lines = [null];\n    lines\n        .joiner(only(\"b\"))\n        .array();\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // Transience correctness test\n    struct TransientRange\n    {\n    @safe:\n        int[][] src;\n        int[] buf;\n\n        this(int[][] _src)\n        {\n            src = _src;\n            buf.length = 100;\n        }\n        @property bool empty() { return src.empty; }\n        @property int[] front()\n        {\n            assert(src.front.length <= buf.length);\n            buf[0 .. src.front.length] = src.front[0..$];\n            return buf[0 .. src.front.length];\n        }\n        void popFront() { src.popFront(); }\n    }\n\n    // Test embedded empty elements\n    auto tr1 = TransientRange([[], [1,2,3], [], [4]]);\n    assert(equal(joiner(tr1, [0]), [0,1,2,3,0,0,4]));\n\n    // Test trailing empty elements\n    auto tr2 = TransientRange([[], [1,2,3], []]);\n    assert(equal(joiner(tr2, [0]), [0,1,2,3,0]));\n\n    // Test no empty elements\n    auto tr3 = TransientRange([[1,2], [3,4]]);\n    assert(equal(joiner(tr3, [0,1]), [1,2,0,1,3,4]));\n\n    // Test consecutive empty elements\n    auto tr4 = TransientRange([[1,2], [], [], [], [3,4]]);\n    assert(equal(joiner(tr4, [0,1]), [1,2,0,1,0,1,0,1,0,1,3,4]));\n\n    // Test consecutive trailing empty elements\n    auto tr5 = TransientRange([[1,2], [3,4], [], []]);\n    assert(equal(joiner(tr5, [0,1]), [1,2,0,1,3,4,0,1,0,1]));\n}\n\n@safe unittest\n{\n    static assert(isInputRange!(typeof(joiner([\"\"], \"\"))));\n    static assert(isForwardRange!(typeof(joiner([\"\"], \"\"))));\n}\n\n/// Ditto\nauto joiner(RoR)(RoR r)\nif (isInputRange!RoR && isInputRange!(ElementType!RoR))\n{\n    static struct Result\n    {\n    private:\n        RoR _items;\n        ElementType!RoR _current;\n        enum isBidirectional = isForwardRange!RoR && isForwardRange!(ElementType!RoR) &&\n                               isBidirectionalRange!RoR && isBidirectionalRange!(ElementType!RoR);\n        static if (isBidirectional)\n        {\n            ElementType!RoR _currentBack;\n            bool reachedFinalElement;\n        }\n\n        this(RoR items, ElementType!RoR current)\n        {\n            _items = items;\n            _current = current;\n            static if (isBidirectional && hasNested!Result)\n                _currentBack = typeof(_currentBack).init;\n        }\n\n    public:\n        this(RoR r)\n        {\n            _items = r;\n\n            static if (isBidirectional && hasNested!Result)\n                _currentBack = typeof(_currentBack).init;\n            // field _current must be initialized in constructor, because it is nested struct\n            mixin(popFrontEmptyElements);\n            static if (isBidirectional)\n                mixin(popBackEmptyElements);\n        }\n        static if (isInfinite!RoR)\n        {\n            enum bool empty = false;\n        }\n        else\n        {\n            @property auto empty()\n            {\n                return _items.empty;\n            }\n        }\n        @property auto ref front()\n        {\n            assert(!empty, \"Attempting to fetch the front of an empty joiner.\");\n            return _current.front;\n        }\n        void popFront()\n        {\n            assert(!_current.empty, \"Attempting to popFront an empty joiner.\");\n            _current.popFront();\n            if (_current.empty)\n            {\n                assert(!_items.empty, \"Attempting to popFront an empty joiner.\");\n                _items.popFront();\n                mixin(popFrontEmptyElements);\n            }\n        }\n\n        private enum popFrontEmptyElements = q{\n            // Skip over empty subranges.\n            if (_items.empty) goto end;\n            while (_items.front.empty)\n            {\n                _items.popFront();\n                if (_items.empty) goto end;\n            }\n            // We cannot export .save method unless we ensure subranges are not\n            // consumed when a .save'd copy of ourselves is iterated over. So\n            // we need to .save each subrange we traverse.\n            static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))\n                _current = _items.front.save;\n            else\n                _current = _items.front;\n        end:\n            assert(1); // required to avoid 'EOF instead of statement' error\n        };\n\n        static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))\n        {\n            @property auto save()\n            {\n                auto r = Result(_items.save, _current.save);\n                static if (isBidirectional)\n                    r._currentBack = _currentBack.save;\n                return r;\n            }\n        }\n\n        static if (hasAssignableElements!(ElementType!RoR))\n        {\n            @property void front(ElementType!(ElementType!RoR) element)\n            {\n                assert(!empty, \"Attempting to assign to front of an empty joiner.\");\n                _current.front = element;\n            }\n\n            @property void front(ref ElementType!(ElementType!RoR) element)\n            {\n                assert(!empty, \"Attempting to assign to front of an empty joiner.\");\n                _current.front = element;\n            }\n        }\n\n        static if (isBidirectional)\n        {\n            bool checkFinalElement()\n            {\n                import std.range : dropOne;\n\n                if (reachedFinalElement)\n                    return true;\n\n                static if (hasLength!(typeof(_items)))\n                {\n                    if (_items.length == 1)\n                        reachedFinalElement = true;\n                }\n                else\n                {\n                    if (_items.save.dropOne.empty)\n                        reachedFinalElement = true;\n                }\n\n                return false;\n            }\n\n            @property auto ref back()\n            {\n                assert(!empty, \"Attempting to fetch the back of an empty joiner.\");\n                if (reachedFinalElement)\n                    return _current.back;\n                else\n                    return _currentBack.back;\n            }\n\n            void popBack()\n            {\n                assert(!_current.empty, \"Attempting to popBack an empty joiner.\");\n                if (checkFinalElement)\n                    _current.popBack();\n                else\n                    _currentBack.popBack();\n\n                bool isEmpty = reachedFinalElement ? _current.empty : _currentBack.empty;\n                if (isEmpty)\n                {\n                    assert(!_items.empty, \"Attempting to popBack an empty joiner.\");\n                    _items.popBack();\n                    mixin(popBackEmptyElements);\n                }\n            }\n\n            private enum popBackEmptyElements = q{\n                // Skip over empty subranges.\n                if (_items.empty) goto end2;\n                while (_items.back.empty)\n                {\n                    _items.popBack();\n                    if (_items.empty) goto end2;\n                }\n                checkFinalElement;\n                // We cannot export .save method unless we ensure subranges are not\n                // consumed when a .save'd copy of ourselves is iterated over. So\n                // we need to .save each subrange we traverse.\n                static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))\n                {\n                    if (reachedFinalElement)\n                        _current = _items.back.save;\n                    else\n                        _currentBack = _items.back.save;\n                }\n                else\n                {\n                    if (reachedFinalElement)\n                        _current = _items.back;\n                    else\n                        _currentBack = _items.back;\n                }\n            end2:\n                assert(1);\n            };\n\n            static if (hasAssignableElements!(ElementType!RoR))\n            {\n                @property void back(ElementType!(ElementType!RoR) element)\n                {\n                    assert(!empty, \"Attempting to assign to back of an empty joiner.\");\n                    if (reachedFinalElement)\n                        _current.back = element;\n                    else\n                        _currentBack.back = element;\n                }\n\n                @property void back(ref ElementType!(ElementType!RoR) element)\n                {\n                    assert(!empty, \"Attempting to assign to back of an empty joiner.\");\n                    if (reachedFinalElement)\n                        _current.back = element;\n                    else\n                        _currentBack.back = element;\n                }\n            }\n        }\n    }\n    return Result(r);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : repeat;\n\n    assert([\"\"].joiner.equal(\"\"));\n    assert([\"\", \"\"].joiner.equal(\"\"));\n    assert([\"\", \"abc\"].joiner.equal(\"abc\"));\n    assert([\"abc\", \"\"].joiner.equal(\"abc\"));\n    assert([\"abc\", \"def\"].joiner.equal(\"abcdef\"));\n    assert([\"Mary\", \"has\", \"a\", \"little\", \"lamb\"].joiner.equal(\"Maryhasalittlelamb\"));\n    assert(\"abc\".repeat(3).joiner.equal(\"abcabcabc\"));\n}\n\n/// joiner allows in-place mutation!\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto a = [ [1, 2, 3], [42, 43] ];\n    auto j = joiner(a);\n    j.front = 44;\n    assert(a == [ [44, 2, 3], [42, 43] ]);\n    assert(equal(j, [44, 2, 3, 42, 43]));\n}\n\n/// insert characters fully lazily into a string\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : chain, cycle, iota, only, retro, take, zip;\n    import std.format : format;\n\n    static immutable number = \"12345678\";\n    static immutable delimiter = \",\";\n    auto formatted = number.retro\n        .zip(3.iota.cycle.take(number.length))\n        .map!(z => chain(z[0].only, z[1] == 2 ? delimiter : null))\n        .joiner\n        .retro;\n    static immutable expected = \"12,345,678\";\n    assert(formatted.equal(expected));\n}\n\n@safe unittest\n{\n    import std.range.interfaces : inputRangeObject;\n    static assert(isInputRange!(typeof(joiner([\"\"]))));\n    static assert(isForwardRange!(typeof(joiner([\"\"]))));\n}\n\n@safe unittest\n{\n    // Initial version of PR #6115 caused a compilation failure for\n    // https://github.com/BlackEdder/ggplotd/blob/d4428c08db5ffdc05dfd29690bf7da9073ea1dc5/source/ggplotd/stat.d#L562-L583\n    import std.range : zip;\n    int[] xCoords = [1, 2, 3];\n    int[] yCoords = [4, 5, 6];\n    auto coords = zip(xCoords, xCoords[1..$]).map!( (xr) {\n            return zip(yCoords, yCoords[1..$]).map!( (yr) {\n                    return [\n                    [[xr[0], xr[0], xr[1]],\n                     [yr[0], yr[1], yr[1]]],\n                    [[xr[0], xr[1], xr[1]],\n                     [yr[0], yr[0], yr[1]]]\n                     ];\n            }).joiner;\n    }).joiner;\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range.interfaces : inputRangeObject;\n    import std.range : retro;\n\n    // bugzilla 8240\n    assert(equal(joiner([inputRangeObject(\"\")]), \"\"));\n    assert(equal(joiner([inputRangeObject(\"\")]).retro, \"\"));\n\n    // issue 8792\n    auto b = [[1], [2], [3]];\n    auto jb = joiner(b);\n    auto js = jb.save;\n    assert(equal(jb, js));\n\n    auto js2 = jb.save;\n    jb.popFront();\n    assert(!equal(jb, js));\n    assert(equal(js2, js));\n    js.popFront();\n    assert(equal(jb, js));\n    assert(!equal(js2, js));\n}\n\n/// joiner can be bidirectional\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : retro;\n\n    auto a = [[1, 2, 3], [4, 5]];\n    auto j = a.joiner;\n    j.back = 44;\n    assert(a == [[1, 2, 3], [4, 44]]);\n    assert(equal(j.retro, [44, 4, 3, 2, 1]));\n}\n\n// bidirectional joiner: test for filtering empty elements\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : retro;\n\n    alias El = (e) => new int(e);\n    auto a = [null, [null, El(1), null, El(2), null, El(3), null], null, [null, El(4), null, El(5), null]];\n    auto j = a.joiner;\n\n    alias deref = a => a is null ? -1 : *a;\n    auto expected = [-1, 5, -1, 4, -1, -1, 3, -1, 2, -1, 1, -1];\n    // works with .save.\n    assert(j.save.retro.map!deref.equal(expected));\n    // and without .save\n    assert(j.retro.map!deref.equal(expected));\n    assert(j.retro.map!deref.equal(expected));\n}\n\n// bidirectional joiner is @nogc\n@safe @nogc unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota, only, retro;\n\n    auto a = only(iota(1, 4), iota(4, 6));\n    auto j = a.joiner;\n    static immutable expected = [5 , 4, 3, 2, 1];\n    assert(equal(j.retro, expected));\n}\n\n// bidirectional joiner supports assignment to the back\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : popBackN;\n\n    auto a = [[1, 2, 3], [4, 5]];\n    auto j = a.joiner;\n    j.back = 55;\n    assert(a == [[1, 2, 3], [4, 55]]);\n    j.popBackN(2);\n    j.back = 33;\n    assert(a == [[1, 2, 33], [4, 55]]);\n}\n\n// bidirectional joiner works with auto-decoding\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : retro;\n\n    auto a = [\"😀😐\", \"😠\"];\n    auto j = a.joiner;\n    assert(j.retro.equal(\"😠😐😀\"));\n}\n\n// test two-side iteration\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : popBackN;\n\n    auto arrs = [\n        [[1], [2], [3], [4], [5]],\n        [[1], [2, 3, 4], [5]],\n        [[1, 2, 3, 4, 5]],\n    ];\n    foreach (arr; arrs)\n    {\n        auto a = arr.joiner;\n        assert(a.front == 1);\n        assert(a.back == 5);\n        a.popFront;\n        assert(a.front == 2);\n        assert(a.back == 5);\n        a.popBack;\n        assert(a.front == 2);\n        assert(a.back == 4);\n        a.popFront;\n        assert(a.front == 3);\n        assert(a.back == 4);\n        a.popBack;\n        assert(a.front == 3);\n        assert(a.back == 3);\n        a.popBack;\n        assert(a.empty);\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    struct TransientRange\n    {\n    @safe:\n        int[] _buf;\n        int[][] _values;\n        this(int[][] values)\n        {\n            _values = values;\n            _buf = new int[128];\n        }\n        @property bool empty()\n        {\n            return _values.length == 0;\n        }\n        @property auto front()\n        {\n            foreach (i; 0 .. _values.front.length)\n            {\n                _buf[i] = _values[0][i];\n            }\n            return _buf[0 .. _values.front.length];\n        }\n        void popFront()\n        {\n            _values = _values[1 .. $];\n        }\n    }\n\n    auto rr = TransientRange([[1,2], [3,4,5], [], [6,7]]);\n\n    // Can't use array() or equal() directly because they fail with transient\n    // .front.\n    int[] result;\n    foreach (c; rr.joiner())\n    {\n        result ~= c;\n    }\n\n    assert(equal(result, [1,2,3,4,5,6,7]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.internal : algoFormat;\n\n    struct TransientRange\n    {\n    @safe:\n        dchar[] _buf;\n        dstring[] _values;\n        this(dstring[] values)\n        {\n            _buf.length = 128;\n            _values = values;\n        }\n        @property bool empty()\n        {\n            return _values.length == 0;\n        }\n        @property auto front()\n        {\n            foreach (i; 0 .. _values.front.length)\n            {\n                _buf[i] = _values[0][i];\n            }\n            return _buf[0 .. _values.front.length];\n        }\n        void popFront()\n        {\n            _values = _values[1 .. $];\n        }\n    }\n\n    auto rr = TransientRange([\"abc\"d, \"12\"d, \"def\"d, \"34\"d]);\n\n    // Can't use array() or equal() directly because they fail with transient\n    // .front.\n    dchar[] result;\n    foreach (c; rr.joiner())\n    {\n        result ~= c;\n    }\n\n    import std.conv : to;\n    assert(equal(result, \"abc12def34\"d),\n        //Convert to string for assert's message\n        to!string(\"Unexpected result: '%s'\"d.algoFormat(result)));\n}\n\n// Issue 8061\n@system unittest\n{\n    import std.conv : to;\n    import std.range.interfaces;\n\n    auto r = joiner([inputRangeObject(\"ab\"), inputRangeObject(\"cd\")]);\n    assert(isForwardRange!(typeof(r)));\n\n    auto str = to!string(r);\n    assert(str == \"abcd\");\n}\n\n@safe unittest\n{\n    import std.range : repeat;\n\n    class AssignableRange\n    {\n    @safe:\n        int element;\n        @property int front()\n        {\n            return element;\n        }\n        alias back = front;\n\n        enum empty = false;\n\n        auto save()\n        {\n            return this;\n        }\n\n        void popFront() {}\n        alias popBack = popFront;\n\n        @property void front(int newValue)\n        {\n            element = newValue;\n        }\n        alias back = front;\n    }\n\n    static assert(isInputRange!AssignableRange);\n    static assert(is(ElementType!AssignableRange == int));\n    static assert(hasAssignableElements!AssignableRange);\n    static assert(!hasLvalueElements!AssignableRange);\n\n    auto range = new AssignableRange();\n    assert(range.element == 0);\n    {\n        auto joined = joiner(repeat(range));\n        joined.front = 5;\n        assert(range.element == 5);\n        assert(joined.front == 5);\n\n        joined.popFront;\n        int byRef = 7;\n        joined.front = byRef;\n        assert(range.element == byRef);\n        assert(joined.front == byRef);\n    }\n    {\n        auto joined = joiner(repeat(range));\n        joined.back = 5;\n        assert(range.element == 5);\n        assert(joined.back == 5);\n\n        joined.popBack;\n        int byRef = 7;\n        joined.back = byRef;\n        assert(range.element == byRef);\n        assert(joined.back == byRef);\n    }\n}\n\n/++\nImplements the homonym function (also known as `accumulate`, $(D\ncompress), `inject`, or `foldl`) present in various programming\nlanguages of functional flavor. There is also $(LREF fold) which does\nthe same thing but with the opposite parameter order.\nThe call `reduce!(fun)(seed, range)` first assigns `seed` to\nan internal variable `result`, also called the accumulator.\nThen, for each element `x` in `range`, `result = fun(result, x)`\ngets evaluated. Finally, `result` is returned.\nThe one-argument version `reduce!(fun)(range)`\nworks similarly, but it uses the first element of the range as the\nseed (the range must be non-empty).\n\nReturns:\n    the accumulated `result`\n\nParams:\n    fun = one or more functions\n\nSee_Also:\n    $(HTTP en.wikipedia.org/wiki/Fold_(higher-order_function), Fold (higher-order function))\n\n    $(LREF fold) is functionally equivalent to $(LREF _reduce) with the argument\n    order reversed, and without the need to use $(REF_ALTTEXT `tuple`,tuple,std,typecons)\n    for multiple seeds. This makes it easier to use in UFCS chains.\n\n    $(LREF sum) is similar to `reduce!((a, b) => a + b)` that offers\n    pairwise summing of floating point numbers.\n+/\ntemplate reduce(fun...)\nif (fun.length >= 1)\n{\n    import std.meta : staticMap;\n\n    alias binfuns = staticMap!(binaryFun, fun);\n    static if (fun.length > 1)\n        import std.typecons : tuple, isTuple;\n\n    /++\n    No-seed version. The first element of `r` is used as the seed's value.\n\n    For each function `f` in `fun`, the corresponding\n    seed type `S` is `Unqual!(typeof(f(e, e)))`, where `e` is an\n    element of `r`: `ElementType!R` for ranges,\n    and `ForeachType!R` otherwise.\n\n    Once S has been determined, then `S s = e;` and `s = f(s, e);`\n    must both be legal.\n\n    Params:\n        r = an iterable value as defined by `isIterable`\n\n    Returns:\n        the final result of the accumulator applied to the iterable\n\n    Throws: `Exception` if `r` is empty\n    +/\n    auto reduce(R)(R r)\n    if (isIterable!R)\n    {\n        import std.exception : enforce;\n        alias E = Select!(isInputRange!R, ElementType!R, ForeachType!R);\n        alias Args = staticMap!(ReduceSeedType!E, binfuns);\n\n        static if (isInputRange!R)\n        {\n            // no need to throw if range is statically known to be non-empty\n            static if (!__traits(compiles,\n            {\n                static assert(r.length > 0);\n            }))\n                enforce(!r.empty, \"Cannot reduce an empty input range w/o an explicit seed value.\");\n\n            Args result = r.front;\n            r.popFront();\n            return reduceImpl!false(r, result);\n        }\n        else\n        {\n            auto result = Args.init;\n            return reduceImpl!true(r, result);\n        }\n    }\n\n    /++\n    Seed version. The seed should be a single value if `fun` is a\n    single function. If `fun` is multiple functions, then `seed`\n    should be a $(REF Tuple, std,typecons), with one field per function in `f`.\n\n    For convenience, if the seed is const, or has qualified fields, then\n    `reduce` will operate on an unqualified copy. If this happens\n    then the returned type will not perfectly match `S`.\n\n    Use `fold` instead of `reduce` to use the seed version in a UFCS chain.\n\n    Params:\n        seed = the initial value of the accumulator\n        r = an iterable value as defined by `isIterable`\n\n    Returns:\n        the final result of the accumulator applied to the iterable\n    +/\n    auto reduce(S, R)(S seed, R r)\n    if (isIterable!R)\n    {\n        static if (fun.length == 1)\n            return reducePreImpl(r, seed);\n        else\n        {\n            import std.algorithm.internal : algoFormat;\n            static assert(isTuple!S, algoFormat(\"Seed %s should be a Tuple\", S.stringof));\n            return reducePreImpl(r, seed.expand);\n        }\n    }\n\n    private auto reducePreImpl(R, Args...)(R r, ref Args args)\n    {\n        alias Result = staticMap!(Unqual, Args);\n        static if (is(Result == Args))\n            alias result = args;\n        else\n            Result result = args;\n        return reduceImpl!false(r, result);\n    }\n\n    private auto reduceImpl(bool mustInitialize, R, Args...)(R r, ref Args args)\n    if (isIterable!R)\n    {\n        import std.algorithm.internal : algoFormat;\n        static assert(Args.length == fun.length,\n            algoFormat(\"Seed %s does not have the correct amount of fields (should be %s)\", Args.stringof, fun.length));\n        alias E = Select!(isInputRange!R, ElementType!R, ForeachType!R);\n\n        static if (mustInitialize) bool initialized = false;\n        foreach (/+auto ref+/ E e; r) // @@@4707@@@\n        {\n            foreach (i, f; binfuns)\n            {\n                static assert(!is(typeof(f(args[i], e))) || is(typeof(args[i] = f(args[i], e))),\n                    algoFormat(\n                        \"Incompatible function/seed/element: %s/%s/%s\",\n                        fullyQualifiedName!f,\n                        Args[i].stringof,\n                        E.stringof\n                    )\n                );\n            }\n\n            static if (mustInitialize) if (initialized == false)\n            {\n                import std.conv : emplaceRef;\n                foreach (i, f; binfuns)\n                    emplaceRef!(Args[i])(args[i], e);\n                initialized = true;\n                continue;\n            }\n\n            foreach (i, f; binfuns)\n                args[i] = f(args[i], e);\n        }\n        static if (mustInitialize)\n        // no need to throw if range is statically known to be non-empty\n        static if (!__traits(compiles,\n        {\n            static assert(r.length > 0);\n        }))\n        {\n            if (!initialized)\n                throw new Exception(\"Cannot reduce an empty iterable w/o an explicit seed value.\");\n        }\n\n        static if (Args.length == 1)\n            return args[0];\n        else\n            return tuple(args);\n    }\n}\n\n/**\nMany aggregate range operations turn out to be solved with `reduce`\nquickly and easily. The example below illustrates `reduce`'s\nremarkable power and flexibility.\n*/\n@safe unittest\n{\n    import std.algorithm.comparison : max, min;\n    import std.math : approxEqual;\n    import std.range;\n\n    int[] arr = [ 1, 2, 3, 4, 5 ];\n    // Sum all elements\n    auto sum = reduce!((a,b) => a + b)(0, arr);\n    assert(sum == 15);\n\n    // Sum again, using a string predicate with \"a\" and \"b\"\n    sum = reduce!\"a + b\"(0, arr);\n    assert(sum == 15);\n\n    // Compute the maximum of all elements\n    auto largest = reduce!(max)(arr);\n    assert(largest == 5);\n\n    // Max again, but with Uniform Function Call Syntax (UFCS)\n    largest = arr.reduce!(max);\n    assert(largest == 5);\n\n    // Compute the number of odd elements\n    auto odds = reduce!((a,b) => a + (b & 1))(0, arr);\n    assert(odds == 3);\n\n    // Compute the sum of squares\n    auto ssquares = reduce!((a,b) => a + b * b)(0, arr);\n    assert(ssquares == 55);\n\n    // Chain multiple ranges into seed\n    int[] a = [ 3, 4 ];\n    int[] b = [ 100 ];\n    auto r = reduce!(\"a + b\")(chain(a, b));\n    assert(r == 107);\n\n    // Mixing convertible types is fair game, too\n    double[] c = [ 2.5, 3.0 ];\n    auto r1 = reduce!(\"a + b\")(chain(a, b, c));\n    assert(approxEqual(r1, 112.5));\n\n    // To minimize nesting of parentheses, Uniform Function Call Syntax can be used\n    auto r2 = chain(a, b, c).reduce!(\"a + b\");\n    assert(approxEqual(r2, 112.5));\n}\n\n/**\nSometimes it is very useful to compute multiple aggregates in one pass.\nOne advantage is that the computation is faster because the looping overhead\nis shared. That's why `reduce` accepts multiple functions.\nIf two or more functions are passed, `reduce` returns a\n$(REF Tuple, std,typecons) object with one member per passed-in function.\nThe number of seeds must be correspondingly increased.\n*/\n@safe unittest\n{\n    import std.algorithm.comparison : max, min;\n    import std.math : approxEqual, sqrt;\n    import std.typecons : tuple, Tuple;\n\n    double[] a = [ 3.0, 4, 7, 11, 3, 2, 5 ];\n    // Compute minimum and maximum in one pass\n    auto r = reduce!(min, max)(a);\n    // The type of r is Tuple!(int, int)\n    assert(approxEqual(r[0], 2));  // minimum\n    assert(approxEqual(r[1], 11)); // maximum\n\n    // Compute sum and sum of squares in one pass\n    r = reduce!(\"a + b\", \"a + b * b\")(tuple(0.0, 0.0), a);\n    assert(approxEqual(r[0], 35));  // sum\n    assert(approxEqual(r[1], 233)); // sum of squares\n    // Compute average and standard deviation from the above\n    auto avg = r[0] / a.length;\n    assert(avg == 5);\n    auto stdev = sqrt(r[1] / a.length - avg * avg);\n    assert(cast(int) stdev == 2);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : max, min;\n    import std.range : chain;\n    import std.typecons : tuple, Tuple;\n\n    double[] a = [ 3, 4 ];\n    auto r = reduce!(\"a + b\")(0.0, a);\n    assert(r == 7);\n    r = reduce!(\"a + b\")(a);\n    assert(r == 7);\n    r = reduce!(min)(a);\n    assert(r == 3);\n    double[] b = [ 100 ];\n    auto r1 = reduce!(\"a + b\")(chain(a, b));\n    assert(r1 == 107);\n\n    // two funs\n    auto r2 = reduce!(\"a + b\", \"a - b\")(tuple(0.0, 0.0), a);\n    assert(r2[0] == 7 && r2[1] == -7);\n    auto r3 = reduce!(\"a + b\", \"a - b\")(a);\n    assert(r3[0] == 7 && r3[1] == -1);\n\n    a = [ 1, 2, 3, 4, 5 ];\n    // Stringize with commas\n    string rep = reduce!(\"a ~ `, ` ~ to!(string)(b)\")(\"\", a);\n    assert(rep[2 .. $] == \"1, 2, 3, 4, 5\", \"[\"~rep[2 .. $]~\"]\");\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : max, min;\n    import std.exception : assertThrown;\n    import std.range : iota;\n    import std.typecons : tuple, Tuple;\n\n    // Test the opApply case.\n    static struct OpApply\n    {\n        bool actEmpty;\n\n        int opApply(scope int delegate(ref int) @safe dg)\n        {\n            int res;\n            if (actEmpty) return res;\n\n            foreach (i; 0 .. 100)\n            {\n                res = dg(i);\n                if (res) break;\n            }\n            return res;\n        }\n    }\n\n    OpApply oa;\n    auto hundredSum = reduce!\"a + b\"(iota(100));\n    assert(reduce!\"a + b\"(5, oa) == hundredSum + 5);\n    assert(reduce!\"a + b\"(oa) == hundredSum);\n    assert(reduce!(\"a + b\", max)(oa) == tuple(hundredSum, 99));\n    assert(reduce!(\"a + b\", max)(tuple(5, 0), oa) == tuple(hundredSum + 5, 99));\n\n    // Test for throwing on empty range plus no seed.\n    assertThrown(reduce!\"a + b\"([1, 2][0 .. 0]));\n\n    oa.actEmpty = true;\n    assertThrown(reduce!\"a + b\"(oa));\n}\n\n@safe unittest\n{\n    const float a = 0.0;\n    const float[] b = [ 1.2, 3, 3.3 ];\n    float[] c = [ 1.2, 3, 3.3 ];\n    auto r = reduce!\"a + b\"(a, b);\n    r = reduce!\"a + b\"(a, c);\n    assert(r == 7.5);\n}\n\n@safe unittest\n{\n    // Issue #10408 - Two-function reduce of a const array.\n    import std.algorithm.comparison : max, min;\n    import std.typecons : tuple, Tuple;\n\n    const numbers = [10, 30, 20];\n    immutable m = reduce!(min)(numbers);\n    assert(m == 10);\n    immutable minmax = reduce!(min, max)(numbers);\n    assert(minmax == tuple(10, 30));\n}\n\n@safe unittest\n{\n    //10709\n    import std.typecons : tuple, Tuple;\n\n    enum foo = \"a + 0.5 * b\";\n    auto r = [0, 1, 2, 3];\n    auto r1 = reduce!foo(r);\n    auto r2 = reduce!(foo, foo)(r);\n    assert(r1 == 3);\n    assert(r2 == tuple(3, 3));\n}\n\n@safe unittest\n{\n    static struct OpApply\n    {\n        int opApply(int delegate(ref int) @safe dg)\n        {\n            int[] a = [1, 2, 3];\n\n            int res = 0;\n            foreach (ref e; a)\n            {\n                res = dg(e);\n                if (res) break;\n            }\n            return res;\n        }\n    }\n    //test CTFE and functions with context\n    int fun(int a, int b) @safe {return a + b + 1;}\n    auto foo()\n    {\n        import std.algorithm.comparison : max;\n        import std.typecons : tuple, Tuple;\n\n        auto a = reduce!(fun)([1, 2, 3]);\n        auto b = reduce!(fun, fun)([1, 2, 3]);\n        auto c = reduce!(fun)(0, [1, 2, 3]);\n        auto d = reduce!(fun, fun)(tuple(0, 0), [1, 2, 3]);\n        auto e = reduce!(fun)(0, OpApply());\n        auto f = reduce!(fun, fun)(tuple(0, 0), OpApply());\n\n        return max(a, b.expand, c, d.expand, e, f.expand);\n    }\n    auto a = foo();\n    assert(a == 9);\n    enum b = foo();\n    assert(b == 9);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : max, min;\n    import std.typecons : tuple, Tuple;\n\n    //http://forum.dlang.org/post/oghtttkopzjshsuflelk@forum.dlang.org\n    //Seed is tuple of const.\n    static auto minmaxElement(alias F = min, alias G = max, R)(in R range)\n    @safe pure nothrow\n    if (isInputRange!R)\n    {\n        return reduce!(F, G)(tuple(ElementType!R.max,\n                                   ElementType!R.min), range);\n    }\n    assert(minmaxElement([1, 2, 3]) == tuple(1, 3));\n}\n\n@safe unittest //12569\n{\n    import std.algorithm.comparison : max, min;\n    import std.typecons : tuple;\n    dchar c = 'a';\n    reduce!(min, max)(tuple(c, c), \"hello\"); // OK\n    static assert(!is(typeof(reduce!(min, max)(tuple(c), \"hello\"))));\n    static assert(!is(typeof(reduce!(min, max)(tuple(c, c, c), \"hello\"))));\n\n\n    //\"Seed dchar should be a Tuple\"\n    static assert(!is(typeof(reduce!(min, max)(c, \"hello\"))));\n    //\"Seed (dchar) does not have the correct amount of fields (should be 2)\"\n    static assert(!is(typeof(reduce!(min, max)(tuple(c), \"hello\"))));\n    //\"Seed (dchar, dchar, dchar) does not have the correct amount of fields (should be 2)\"\n    static assert(!is(typeof(reduce!(min, max)(tuple(c, c, c), \"hello\"))));\n    //\"Incompatable function/seed/element: all(alias pred = \"a\")/int/dchar\"\n    static assert(!is(typeof(reduce!all(1, \"hello\"))));\n    static assert(!is(typeof(reduce!(all, all)(tuple(1, 1), \"hello\"))));\n}\n\n@safe unittest //13304\n{\n    int[] data;\n    static assert(is(typeof(reduce!((a, b) => a + b)(data))));\n    assert(data.length == 0);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=13880\n// reduce shouldn't throw if the length is statically known\npure nothrow @safe @nogc unittest\n{\n    import std.algorithm.comparison : min;\n    int[5] arr;\n    arr[2] = -1;\n    assert(arr.reduce!min == -1);\n\n    int[0] arr0;\n    assert(reduce!min(42, arr0) == 42);\n}\n\n//Helper for Reduce\nprivate template ReduceSeedType(E)\n{\n    static template ReduceSeedType(alias fun)\n    {\n        import std.algorithm.internal : algoFormat;\n\n        alias ReduceSeedType = Unqual!(typeof(fun(lvalueOf!E, lvalueOf!E)));\n\n        //Check the Seed type is useable.\n        ReduceSeedType s = ReduceSeedType.init;\n        static assert(is(typeof({ReduceSeedType s = lvalueOf!E;})) &&\n            is(typeof(lvalueOf!ReduceSeedType = fun(lvalueOf!ReduceSeedType, lvalueOf!E))),\n            algoFormat(\n                \"Unable to deduce an acceptable seed type for %s with element type %s.\",\n                fullyQualifiedName!fun,\n                E.stringof\n            )\n        );\n    }\n}\n\n\n/++\nImplements the homonym function (also known as `accumulate`, $(D\ncompress), `inject`, or `foldl`) present in various programming\nlanguages of functional flavor. The call `fold!(fun)(range, seed)`\nfirst assigns `seed` to an internal variable `result`,\nalso called the accumulator. Then, for each element `x` in $(D\nrange), `result = fun(result, x)` gets evaluated. Finally, $(D\nresult) is returned. The one-argument version `fold!(fun)(range)`\nworks similarly, but it uses the first element of the range as the\nseed (the range must be non-empty).\n\nParams:\n    fun = the predicate function(s) to apply to the elements\n\nSee_Also:\n    $(HTTP en.wikipedia.org/wiki/Fold_(higher-order_function), Fold (higher-order function))\n\n    $(LREF sum) is similar to `fold!((a, b) => a + b)` that offers\n    precise summing of floating point numbers.\n\n    This is functionally equivalent to $(LREF reduce) with the argument order\n    reversed, and without the need to use $(REF_ALTTEXT `tuple`,tuple,std,typecons)\n    for multiple seeds.\n+/\ntemplate fold(fun...)\nif (fun.length >= 1)\n{\n    /**\n    Params:\n        r = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to fold\n        seed = the initial value of the accumulator\n    Returns:\n        the accumulated `result`\n     */\n    auto fold(R, S...)(R r, S seed)\n    {\n        static if (S.length < 2)\n        {\n            return reduce!fun(seed, r);\n        }\n        else\n        {\n            import std.typecons : tuple;\n            return reduce!fun(tuple(seed), r);\n        }\n    }\n}\n\n///\n@safe pure unittest\n{\n    immutable arr = [1, 2, 3, 4, 5];\n\n    // Sum all elements\n    assert(arr.fold!((a, b) => a + b) == 15);\n\n    // Sum all elements with explicit seed\n    assert(arr.fold!((a, b) => a + b)(6) == 21);\n\n    import std.algorithm.comparison : min, max;\n    import std.typecons : tuple;\n\n    // Compute minimum and maximum at the same time\n    assert(arr.fold!(min, max) == tuple(1, 5));\n\n    // Compute minimum and maximum at the same time with seeds\n    assert(arr.fold!(min, max)(0, 7) == tuple(0, 7));\n\n    // Can be used in a UFCS chain\n    assert(arr.map!(a => a + 1).fold!((a, b) => a + b) == 20);\n\n    // Return the last element of any range\n    assert(arr.fold!((a, b) => b) == 5);\n}\n\n@safe @nogc pure nothrow unittest\n{\n    int[1] arr;\n    static assert(!is(typeof(arr.fold!())));\n    static assert(!is(typeof(arr.fold!(a => a))));\n    static assert(is(typeof(arr.fold!((a, b) => a))));\n    static assert(is(typeof(arr.fold!((a, b) => a)(1))));\n    assert(arr.length == 1);\n}\n\n/++\nSimilar to `fold`, but returns a range containing the successive reduced values.\nThe call `cumulativeFold!(fun)(range, seed)` first assigns `seed` to an\ninternal variable `result`, also called the accumulator.\nThe returned range contains the values `result = fun(result, x)` lazily\nevaluated for each element `x` in `range`. Finally, the last element has the\nsame value as `fold!(fun)(seed, range)`.\nThe one-argument version `cumulativeFold!(fun)(range)` works similarly, but\nit returns the first element unchanged and uses it as seed for the next\nelements.\nThis function is also known as\n    $(HTTP en.cppreference.com/w/cpp/algorithm/partial_sum, partial_sum),\n    $(HTTP docs.python.org/3/library/itertools.html#itertools.accumulate, accumulate),\n    $(HTTP hackage.haskell.org/package/base-4.8.2.0/docs/Prelude.html#v:scanl, scan),\n    $(HTTP mathworld.wolfram.com/CumulativeSum.html, Cumulative Sum).\n\nParams:\n    fun = one or more functions to use as fold operation\n\nReturns:\n    The function returns a range containing the consecutive reduced values. If\n    there is more than one `fun`, the element type will be $(REF Tuple,\n    std,typecons) containing one element for each `fun`.\n\nSee_Also:\n    $(HTTP en.wikipedia.org/wiki/Prefix_sum, Prefix Sum)\n\nNote:\n\n    In functional programming languages this is typically called `scan`, `scanl`,\n    `scanLeft` or `reductions`.\n+/\ntemplate cumulativeFold(fun...)\nif (fun.length >= 1)\n{\n    import std.meta : staticMap;\n    private alias binfuns = staticMap!(binaryFun, fun);\n\n    /++\n    No-seed version. The first element of `r` is used as the seed's value.\n    For each function `f` in `fun`, the corresponding seed type `S` is\n    `Unqual!(typeof(f(e, e)))`, where `e` is an element of `r`:\n    `ElementType!R`.\n    Once `S` has been determined, then `S s = e;` and `s = f(s, e);` must\n    both be legal.\n\n    Params:\n        range = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    Returns:\n        a range containing the consecutive reduced values.\n    +/\n    auto cumulativeFold(R)(R range)\n    if (isInputRange!(Unqual!R))\n    {\n        return cumulativeFoldImpl(range);\n    }\n\n    /++\n    Seed version. The seed should be a single value if `fun` is a single\n    function. If `fun` is multiple functions, then `seed` should be a\n    $(REF Tuple, std,typecons), with one field per function in `f`.\n    For convenience, if the seed is `const`, or has qualified fields, then\n    `cumulativeFold` will operate on an unqualified copy. If this happens\n    then the returned type will not perfectly match `S`.\n\n    Params:\n        range = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n        seed = the initial value of the accumulator\n    Returns:\n        a range containing the consecutive reduced values.\n    +/\n    auto cumulativeFold(R, S)(R range, S seed)\n    if (isInputRange!(Unqual!R))\n    {\n        static if (fun.length == 1)\n            return cumulativeFoldImpl(range, seed);\n        else\n            return cumulativeFoldImpl(range, seed.expand);\n    }\n\n    private auto cumulativeFoldImpl(R, Args...)(R range, ref Args args)\n    {\n        import std.algorithm.internal : algoFormat;\n\n        static assert(Args.length == 0 || Args.length == fun.length,\n            algoFormat(\"Seed %s does not have the correct amount of fields (should be %s)\",\n                Args.stringof, fun.length));\n\n        static if (args.length)\n            alias State = staticMap!(Unqual, Args);\n        else\n            alias State = staticMap!(ReduceSeedType!(ElementType!R), binfuns);\n\n        foreach (i, f; binfuns)\n        {\n            static assert(!__traits(compiles, f(args[i], e)) || __traits(compiles,\n                    { args[i] = f(args[i], e); }()),\n                algoFormat(\"Incompatible function/seed/element: %s/%s/%s\",\n                    fullyQualifiedName!f, Args[i].stringof, E.stringof));\n        }\n\n        static struct Result\n        {\n        private:\n            R source;\n            State state;\n\n            this(R range, ref Args args)\n            {\n                source = range;\n                if (source.empty)\n                    return;\n\n                foreach (i, f; binfuns)\n                {\n                    static if (args.length)\n                        state[i] = f(args[i], source.front);\n                    else\n                        state[i] = source.front;\n                }\n            }\n\n        public:\n            @property bool empty()\n            {\n                return source.empty;\n            }\n\n            @property auto front()\n            {\n                assert(!empty, \"Attempting to fetch the front of an empty cumulativeFold.\");\n                static if (fun.length > 1)\n                {\n                    import std.typecons : tuple;\n                    return tuple(state);\n                }\n                else\n                {\n                    return state[0];\n                }\n            }\n\n            void popFront()\n            {\n                assert(!empty, \"Attempting to popFront an empty cumulativeFold.\");\n                source.popFront;\n\n                if (source.empty)\n                    return;\n\n                foreach (i, f; binfuns)\n                    state[i] = f(state[i], source.front);\n            }\n\n            static if (isForwardRange!R)\n            {\n                @property auto save()\n                {\n                    auto result = this;\n                    result.source = source.save;\n                    return result;\n                }\n            }\n\n            static if (hasLength!R)\n            {\n                @property size_t length()\n                {\n                    return source.length;\n                }\n            }\n        }\n\n        return Result(range, args);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : max, min;\n    import std.array : array;\n    import std.math : approxEqual;\n    import std.range : chain;\n\n    int[] arr = [1, 2, 3, 4, 5];\n    // Partial sum of all elements\n    auto sum = cumulativeFold!((a, b) => a + b)(arr, 0);\n    assert(sum.array == [1, 3, 6, 10, 15]);\n\n    // Partial sum again, using a string predicate with \"a\" and \"b\"\n    auto sum2 = cumulativeFold!\"a + b\"(arr, 0);\n    assert(sum2.array == [1, 3, 6, 10, 15]);\n\n    // Compute the partial maximum of all elements\n    auto largest = cumulativeFold!max(arr);\n    assert(largest.array == [1, 2, 3, 4, 5]);\n\n    // Partial max again, but with Uniform Function Call Syntax (UFCS)\n    largest = arr.cumulativeFold!max;\n    assert(largest.array == [1, 2, 3, 4, 5]);\n\n    // Partial count of odd elements\n    auto odds = arr.cumulativeFold!((a, b) => a + (b & 1))(0);\n    assert(odds.array == [1, 1, 2, 2, 3]);\n\n    // Compute the partial sum of squares\n    auto ssquares = arr.cumulativeFold!((a, b) => a + b * b)(0);\n    assert(ssquares.array == [1, 5, 14, 30, 55]);\n\n    // Chain multiple ranges into seed\n    int[] a = [3, 4];\n    int[] b = [100];\n    auto r = cumulativeFold!\"a + b\"(chain(a, b));\n    assert(r.array == [3, 7, 107]);\n\n    // Mixing convertible types is fair game, too\n    double[] c = [2.5, 3.0];\n    auto r1 = cumulativeFold!\"a + b\"(chain(a, b, c));\n    assert(approxEqual(r1, [3, 7, 107, 109.5, 112.5]));\n\n    // To minimize nesting of parentheses, Uniform Function Call Syntax can be used\n    auto r2 = chain(a, b, c).cumulativeFold!\"a + b\";\n    assert(approxEqual(r2, [3, 7, 107, 109.5, 112.5]));\n}\n\n/**\nSometimes it is very useful to compute multiple aggregates in one pass.\nOne advantage is that the computation is faster because the looping overhead\nis shared. That's why `cumulativeFold` accepts multiple functions.\nIf two or more functions are passed, `cumulativeFold` returns a $(REF Tuple,\nstd,typecons) object with one member per passed-in function.\nThe number of seeds must be correspondingly increased.\n*/\n@safe unittest\n{\n    import std.algorithm.comparison : max, min;\n    import std.algorithm.iteration : map;\n    import std.math : approxEqual;\n    import std.typecons : tuple;\n\n    double[] a = [3.0, 4, 7, 11, 3, 2, 5];\n    // Compute minimum and maximum in one pass\n    auto r = a.cumulativeFold!(min, max);\n    // The type of r is Tuple!(int, int)\n    assert(approxEqual(r.map!\"a[0]\", [3, 3, 3, 3, 3, 2, 2]));     // minimum\n    assert(approxEqual(r.map!\"a[1]\", [3, 4, 7, 11, 11, 11, 11])); // maximum\n\n    // Compute sum and sum of squares in one pass\n    auto r2 = a.cumulativeFold!(\"a + b\", \"a + b * b\")(tuple(0.0, 0.0));\n    assert(approxEqual(r2.map!\"a[0]\", [3, 7, 14, 25, 28, 30, 35]));      // sum\n    assert(approxEqual(r2.map!\"a[1]\", [9, 25, 74, 195, 204, 208, 233])); // sum of squares\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal, max, min;\n    import std.conv : to;\n    import std.range : chain;\n    import std.typecons : tuple;\n\n    double[] a = [3, 4];\n    auto r = a.cumulativeFold!(\"a + b\")(0.0);\n    assert(r.equal([3, 7]));\n    auto r2 = cumulativeFold!(\"a + b\")(a);\n    assert(r2.equal([3, 7]));\n    auto r3 = cumulativeFold!(min)(a);\n    assert(r3.equal([3, 3]));\n    double[] b = [100];\n    auto r4 = cumulativeFold!(\"a + b\")(chain(a, b));\n    assert(r4.equal([3, 7, 107]));\n\n    // two funs\n    auto r5 = cumulativeFold!(\"a + b\", \"a - b\")(a, tuple(0.0, 0.0));\n    assert(r5.equal([tuple(3, -3), tuple(7, -7)]));\n    auto r6 = cumulativeFold!(\"a + b\", \"a - b\")(a);\n    assert(r6.equal([tuple(3, 3), tuple(7, -1)]));\n\n    a = [1, 2, 3, 4, 5];\n    // Stringize with commas\n    auto rep = cumulativeFold!(\"a ~ `, ` ~ to!string(b)\")(a, \"\");\n    assert(rep.map!\"a[2 .. $]\".equal([\"1\", \"1, 2\", \"1, 2, 3\", \"1, 2, 3, 4\", \"1, 2, 3, 4, 5\"]));\n\n    // Test for empty range\n    a = [];\n    assert(a.cumulativeFold!\"a + b\".empty);\n    assert(a.cumulativeFold!\"a + b\"(2.0).empty);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : max, min;\n    import std.array : array;\n    import std.math : approxEqual;\n    import std.typecons : tuple;\n\n    const float a = 0.0;\n    const float[] b = [1.2, 3, 3.3];\n    float[] c = [1.2, 3, 3.3];\n\n    auto r = cumulativeFold!\"a + b\"(b, a);\n    assert(approxEqual(r, [1.2, 4.2, 7.5]));\n\n    auto r2 = cumulativeFold!\"a + b\"(c, a);\n    assert(approxEqual(r2, [1.2, 4.2, 7.5]));\n\n    const numbers = [10, 30, 20];\n    enum m = numbers.cumulativeFold!(min).array;\n    assert(m == [10, 10, 10]);\n    enum minmax = numbers.cumulativeFold!(min, max).array;\n    assert(minmax == [tuple(10, 10), tuple(10, 30), tuple(10, 30)]);\n}\n\n@safe unittest\n{\n    import std.math : approxEqual;\n    import std.typecons : tuple;\n\n    enum foo = \"a + 0.5 * b\";\n    auto r = [0, 1, 2, 3];\n    auto r1 = r.cumulativeFold!foo;\n    auto r2 = r.cumulativeFold!(foo, foo);\n    assert(approxEqual(r1, [0, 0.5, 1.5, 3]));\n    assert(approxEqual(r2.map!\"a[0]\", [0, 0.5, 1.5, 3]));\n    assert(approxEqual(r2.map!\"a[1]\", [0, 0.5, 1.5, 3]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal, max, min;\n    import std.array : array;\n    import std.typecons : tuple;\n\n    //Seed is tuple of const.\n    static auto minmaxElement(alias F = min, alias G = max, R)(in R range)\n    @safe pure nothrow\n    if (isInputRange!R)\n    {\n        return range.cumulativeFold!(F, G)(tuple(ElementType!R.max, ElementType!R.min));\n    }\n\n    assert(minmaxElement([1, 2, 3]).equal([tuple(1, 1), tuple(1, 2), tuple(1, 3)]));\n}\n\n@safe unittest //12569\n{\n    import std.algorithm.comparison : equal, max, min;\n    import std.typecons : tuple;\n\n    dchar c = 'a';\n\n    assert(cumulativeFold!(min, max)(\"hello\", tuple(c, c)).equal([tuple('a', 'h'),\n        tuple('a', 'h'), tuple('a', 'l'), tuple('a', 'l'), tuple('a', 'o')]));\n    static assert(!__traits(compiles, cumulativeFold!(min, max)(\"hello\", tuple(c))));\n    static assert(!__traits(compiles, cumulativeFold!(min, max)(\"hello\", tuple(c, c, c))));\n\n    //\"Seed dchar should be a Tuple\"\n    static assert(!__traits(compiles, cumulativeFold!(min, max)(\"hello\", c)));\n    //\"Seed (dchar) does not have the correct amount of fields (should be 2)\"\n    static assert(!__traits(compiles, cumulativeFold!(min, max)(\"hello\", tuple(c))));\n    //\"Seed (dchar, dchar, dchar) does not have the correct amount of fields (should be 2)\"\n    static assert(!__traits(compiles, cumulativeFold!(min, max)(\"hello\", tuple(c, c, c))));\n    //\"Incompatable function/seed/element: all(alias pred = \"a\")/int/dchar\"\n    static assert(!__traits(compiles, cumulativeFold!all(\"hello\", 1)));\n    static assert(!__traits(compiles, cumulativeFold!(all, all)(\"hello\", tuple(1, 1))));\n}\n\n@safe unittest //13304\n{\n    int[] data;\n    assert(data.cumulativeFold!((a, b) => a + b).empty);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges, propagatesLength,\n        propagatesRangeType, RangeType;\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType d;\n        auto m = d.cumulativeFold!\"a * b\";\n\n        static assert(propagatesLength!(typeof(m), DummyType));\n        static if (DummyType.rt <= RangeType.Forward)\n            static assert(propagatesRangeType!(typeof(m), DummyType));\n\n        assert(m.equal([1, 2, 6, 24, 120, 720, 5040, 40_320, 362_880, 3_628_800]));\n    }\n}\n\n// splitter\n/**\nLazily splits a range using an element or range as a separator.\nSeparator ranges can be any narrow string type or sliceable range type.\n\nTwo adjacent separators are considered to surround an empty element in\nthe split range. Use `filter!(a => !a.empty)` on the result to compress\nempty elements.\n\nThe predicate is passed to $(REF binaryFun, std,functional) and accepts\nany callable function that can be executed via `pred(element, s)`.\n\nNotes:\n    If splitting a string on whitespace and token compression is desired,\n    consider using `splitter` without specifying a separator.\n\n    If no separator is passed, the $(REF_ALTTEXT, unary, unaryFun, std,functional)\n    predicate `isTerminator` decides whether to accept an element of `r`.\n\nParams:\n    pred = The predicate for comparing each element with the separator,\n        defaulting to `\"a == b\"`.\n    r = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to be\n        split. Must support slicing and `.length` or be a narrow string type.\n    s = The element (or range) to be treated as the separator\n        between range segments to be split.\n    isTerminator = The predicate for deciding where to split the range when no separator is passed\n\nConstraints:\n    The predicate `pred` needs to accept an element of `r` and the\n    separator `s`.\n\nReturns:\n    An input range of the subranges of elements between separators. If `r`\n    is a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n    or $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives),\n    the returned range will be likewise.\n    When a range is used a separator, bidirectionality isn't possible.\n\n    If an empty range is given, the result is an empty range. If a range with\n    one separator is given, the result is a range with two empty elements.\n\nSee_Also:\n $(REF _splitter, std,regex) for a version that splits using a regular\nexpression defined separator and\n $(REF _split, std,array) for a version that splits eagerly.\n*/\nauto splitter(alias pred = \"a == b\", Range, Separator)(Range r, Separator s)\nif (is(typeof(binaryFun!pred(r.front, s)) : bool)\n        && ((hasSlicing!Range && hasLength!Range) || isNarrowString!Range))\n{\n    import std.algorithm.searching : find;\n    import std.conv : unsigned;\n\n    struct Result\n    {\n    private:\n        Range _input;\n        Separator _separator;\n        // Do we need hasLength!Range? popFront uses _input.length...\n        enum size_t _unComputed = size_t.max - 1, _atEnd = size_t.max;\n        size_t _frontLength = _unComputed;\n        size_t _backLength = _unComputed;\n\n        static if (isNarrowString!Range)\n        {\n            size_t _separatorLength;\n        }\n        else\n        {\n            enum _separatorLength = 1;\n        }\n\n        static if (isBidirectionalRange!Range)\n        {\n            size_t lastIndexOf(Range haystack, Separator needle)\n            {\n                import std.range : retro;\n                auto r = haystack.retro().find!pred(needle);\n                return r.retro().length - 1;\n            }\n        }\n\n    public:\n        this(Range input, Separator separator)\n        {\n            _input = input;\n            _separator = separator;\n\n            static if (isNarrowString!Range)\n            {\n                import std.utf : codeLength;\n\n                _separatorLength = codeLength!(ElementEncodingType!Range)(separator);\n            }\n            if (_input.empty)\n                _frontLength = _atEnd;\n        }\n\n        static if (isInfinite!Range)\n        {\n            enum bool empty = false;\n        }\n        else\n        {\n            @property bool empty()\n            {\n                return _frontLength == _atEnd;\n            }\n        }\n\n        @property Range front()\n        {\n            assert(!empty, \"Attempting to fetch the front of an empty splitter.\");\n            if (_frontLength == _unComputed)\n            {\n                auto r = _input.find!pred(_separator);\n                _frontLength = _input.length - r.length;\n            }\n            return _input[0 .. _frontLength];\n        }\n\n        void popFront()\n        {\n            assert(!empty, \"Attempting to popFront an empty splitter.\");\n            if (_frontLength == _unComputed)\n            {\n                front;\n            }\n            assert(_frontLength <= _input.length);\n            if (_frontLength == _input.length)\n            {\n                // no more input and need to fetch => done\n                _frontLength = _atEnd;\n\n                // Probably don't need this, but just for consistency:\n                _backLength = _atEnd;\n            }\n            else\n            {\n                _input = _input[_frontLength + _separatorLength .. _input.length];\n                _frontLength = _unComputed;\n            }\n        }\n\n        static if (isForwardRange!Range)\n        {\n            @property typeof(this) save()\n            {\n                auto ret = this;\n                ret._input = _input.save;\n                return ret;\n            }\n        }\n\n        static if (isBidirectionalRange!Range)\n        {\n            @property Range back()\n            {\n                assert(!empty, \"Attempting to fetch the back of an empty splitter.\");\n                if (_backLength == _unComputed)\n                {\n                    immutable lastIndex = lastIndexOf(_input, _separator);\n                    if (lastIndex == -1)\n                    {\n                        _backLength = _input.length;\n                    }\n                    else\n                    {\n                        _backLength = _input.length - lastIndex - 1;\n                    }\n                }\n                return _input[_input.length - _backLength .. _input.length];\n            }\n\n            void popBack()\n            {\n                assert(!empty, \"Attempting to popBack an empty splitter.\");\n                if (_backLength == _unComputed)\n                {\n                    // evaluate back to make sure it's computed\n                    back;\n                }\n                assert(_backLength <= _input.length);\n                if (_backLength == _input.length)\n                {\n                    // no more input and need to fetch => done\n                    _frontLength = _atEnd;\n                    _backLength = _atEnd;\n                }\n                else\n                {\n                    _input = _input[0 .. _input.length - _backLength - _separatorLength];\n                    _backLength = _unComputed;\n                }\n            }\n        }\n    }\n\n    return Result(r, s);\n}\n\n/// Basic splitting with characters and numbers.\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(\"a|bc|def\".splitter('|').equal([ \"a\", \"bc\", \"def\" ]));\n\n    int[] a = [1, 0, 2, 3, 0, 4, 5, 6];\n    int[][] w = [ [1], [2, 3], [4, 5, 6] ];\n    assert(a.splitter(0).equal(w));\n}\n\n/// Adjacent separators.\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(\"|ab|\".splitter('|').equal([ \"\", \"ab\", \"\" ]));\n    assert(\"ab\".splitter('|').equal([ \"ab\" ]));\n\n    assert(\"a|b||c\".splitter('|').equal([ \"a\", \"b\", \"\", \"c\" ]));\n    assert(\"hello  world\".splitter(' ').equal([ \"hello\", \"\", \"world\" ]));\n\n    auto a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];\n    auto w = [ [1, 2], [], [3], [4, 5], [] ];\n    assert(a.splitter(0).equal(w));\n}\n\n/// Empty and separator-only ranges.\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : empty;\n\n    assert(\"\".splitter('|').empty);\n    assert(\"|\".splitter('|').equal([ \"\", \"\" ]));\n    assert(\"||\".splitter('|').equal([ \"\", \"\", \"\" ]));\n}\n\n/// Use a range for splitting\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(\"a=>bc=>def\".splitter(\"=>\").equal([ \"a\", \"bc\", \"def\" ]));\n    assert(\"a|b||c\".splitter(\"||\").equal([ \"a|b\", \"c\" ]));\n    assert(\"hello  world\".splitter(\"  \").equal([ \"hello\", \"world\" ]));\n\n    int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];\n    int[][] w = [ [1, 2], [3, 0, 4, 5, 0] ];\n    assert(a.splitter([0, 0]).equal(w));\n\n    a = [ 0, 0 ];\n    assert(a.splitter([0, 0]).equal([ (int[]).init, (int[]).init ]));\n\n    a = [ 0, 0, 1 ];\n    assert(a.splitter([0, 0]).equal([ [], [1] ]));\n}\n\n/// Custom predicate functions.\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.ascii : toLower;\n\n    assert(\"abXcdxef\".splitter!\"a.toLower == b\"('x').equal(\n                 [ \"ab\", \"cd\", \"ef\" ]));\n\n    auto w = [ [0], [1], [2] ];\n    assert(w.splitter!\"a.front == b\"(1).equal([ [[0]], [[2]] ]));\n}\n\n/// Use splitter without a separator\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range.primitives : front;\n\n    assert(equal(splitter!(a => a == '|')(\"a|bc|def\"), [ \"a\", \"bc\", \"def\" ]));\n    assert(equal(splitter!(a => a == ' ')(\"hello  world\"), [ \"hello\", \"\", \"world\" ]));\n\n    int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];\n    int[][] w = [ [1, 2], [], [3], [4, 5], [] ];\n    assert(equal(splitter!(a => a == 0)(a), w));\n\n    a = [ 0 ];\n    assert(equal(splitter!(a => a == 0)(a), [ (int[]).init, (int[]).init ]));\n\n    a = [ 0, 1 ];\n    assert(equal(splitter!(a => a == 0)(a), [ [], [1] ]));\n\n    w = [ [0], [1], [2] ];\n    assert(equal(splitter!(a => a.front == 1)(w), [ [[0]], [[2]] ]));\n}\n\n/// Leading separators, trailing separators, or no separators.\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(\"|ab|\".splitter('|').equal([ \"\", \"ab\", \"\" ]));\n    assert(\"ab\".splitter('|').equal([ \"ab\" ]));\n}\n\n/// Splitter returns bidirectional ranges if the delimiter is a single element\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : retro;\n    assert(\"a|bc|def\".splitter('|').retro.equal([ \"def\", \"bc\", \"a\" ]));\n}\n\n/// Splitting by word lazily\n@safe unittest\n{\n    import std.ascii : isWhite;\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : splitter;\n\n    string str = \"Hello World!\";\n    assert(str.splitter!(isWhite).equal([\"Hello\", \"World!\"]));\n}\n\n@safe unittest\n{\n    import std.algorithm;\n    import std.array : array;\n    import std.internal.test.dummyrange;\n    import std.range : retro;\n\n    assert(equal(splitter(\"hello  world\", ' '), [ \"hello\", \"\", \"world\" ]));\n    assert(equal(splitter(\"žlutoučkýřkůň\", 'ř'), [ \"žlutoučký\", \"kůň\" ]));\n    int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];\n    int[][] w = [ [1, 2], [], [3], [4, 5], [] ];\n    static assert(isForwardRange!(typeof(splitter(a, 0))));\n\n    assert(equal(splitter(a, 0), w));\n    a = null;\n    assert(equal(splitter(a, 0),  (int[][]).init));\n    a = [ 0 ];\n    assert(equal(splitter(a, 0), [ (int[]).init, (int[]).init ][]));\n    a = [ 0, 1 ];\n    assert(equal(splitter(a, 0), [ [], [1] ]));\n    assert(equal(splitter(a, 0), [ [], [1] ][]));\n\n    // Thoroughly exercise the bidirectional stuff.\n    auto str = \"abc abcd abcde ab abcdefg abcdefghij ab ac ar an at ada\";\n    assert(equal(\n        retro(splitter(str, 'a')),\n        retro(array(splitter(str, 'a')))\n    ));\n\n    // Test interleaving front and back.\n    auto split = splitter(str, 'a');\n    assert(split.front == \"\");\n    assert(split.back == \"\");\n    split.popBack();\n    assert(split.back == \"d\");\n    split.popFront();\n    assert(split.front == \"bc \");\n    assert(split.back == \"d\");\n    split.popFront();\n    split.popBack();\n    assert(split.back == \"t \");\n    split.popBack();\n    split.popBack();\n    split.popFront();\n    split.popFront();\n    assert(split.front == \"b \");\n    assert(split.back == \"r \");\n\n    foreach (DummyType; AllDummyRanges) {  // Bug 4408\n        static if (isRandomAccessRange!DummyType)\n        {\n            static assert(isBidirectionalRange!DummyType);\n            DummyType d;\n            auto s = splitter(d, 5);\n            assert(equal(s.front, [1,2,3,4]));\n            assert(equal(s.back, [6,7,8,9,10]));\n\n            auto s2 = splitter(d, [4, 5]);\n            assert(equal(s2.front, [1,2,3]));\n        }\n    }\n}\n@safe unittest\n{\n    import std.algorithm;\n    import std.range;\n    auto L = retro(iota(1L, 10L));\n    auto s = splitter(L, 5L);\n    assert(equal(s.front, [9L, 8L, 7L, 6L]));\n    s.popFront();\n    assert(equal(s.front, [4L, 3L, 2L, 1L]));\n    s.popFront();\n    assert(s.empty);\n}\n\n@safe unittest // issue 18470\n{\n    import std.algorithm.comparison : equal;\n\n    const w = [[0], [1], [2]];\n    assert(w.splitter!((a, b) => a.front() == b)(1).equal([[[0]], [[2]]]));\n}\n\n@safe unittest // issue 18470\n{\n    import std.algorithm.comparison : equal;\n    import std.ascii : toLower;\n\n    assert(\"abXcdxef\".splitter!\"a.toLower == b\"('x').equal([\"ab\", \"cd\", \"ef\"]));\n    assert(\"abXcdxef\".splitter!((a, b) => a.toLower == b)('x').equal([\"ab\", \"cd\", \"ef\"]));\n}\n\n/// ditto\nauto splitter(alias pred = \"a == b\", Range, Separator)(Range r, Separator s)\nif (is(typeof(binaryFun!pred(r.front, s.front)) : bool)\n        && (hasSlicing!Range || isNarrowString!Range)\n        && isForwardRange!Separator\n        && (hasLength!Separator || isNarrowString!Separator))\n{\n    import std.algorithm.searching : find;\n    import std.conv : unsigned;\n\n    static struct Result\n    {\n    private:\n        Range _input;\n        Separator _separator;\n        // _frontLength == size_t.max means empty\n        size_t _frontLength = size_t.max;\n\n        @property auto separatorLength() { return _separator.length; }\n\n        void ensureFrontLength()\n        {\n            if (_frontLength != _frontLength.max) return;\n            assert(!_input.empty);\n            // compute front length\n            _frontLength = (_separator.empty) ? 1 :\n                           _input.length - find!pred(_input, _separator).length;\n        }\n\n    public:\n        this(Range input, Separator separator)\n        {\n            _input = input;\n            _separator = separator;\n        }\n\n        @property Range front()\n        {\n            assert(!empty, \"Attempting to fetch the front of an empty splitter.\");\n            ensureFrontLength();\n            return _input[0 .. _frontLength];\n        }\n\n        static if (isInfinite!Range)\n        {\n            enum bool empty = false;  // Propagate infiniteness\n        }\n        else\n        {\n            @property bool empty()\n            {\n                return _frontLength == size_t.max && _input.empty;\n            }\n        }\n\n        void popFront()\n        {\n            assert(!empty, \"Attempting to popFront an empty splitter.\");\n            ensureFrontLength();\n            if (_frontLength == _input.length)\n            {\n                // done, there's no separator in sight\n                _input = _input[_frontLength .. _frontLength];\n                _frontLength = _frontLength.max;\n                return;\n            }\n            if (_frontLength + separatorLength == _input.length)\n            {\n                // Special case: popping the first-to-last item; there is\n                // an empty item right after this.\n                _input = _input[_input.length .. _input.length];\n                _frontLength = 0;\n                return;\n            }\n            // Normal case, pop one item and the separator, get ready for\n            // reading the next item\n            _input = _input[_frontLength + separatorLength .. _input.length];\n            // mark _frontLength as uninitialized\n            _frontLength = _frontLength.max;\n        }\n\n        static if (isForwardRange!Range)\n        {\n            @property typeof(this) save()\n            {\n                auto ret = this;\n                ret._input = _input.save;\n                return ret;\n            }\n        }\n    }\n\n    return Result(r, s);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : Tuple;\n\n    alias C = Tuple!(int, \"x\", int, \"y\");\n    auto a = [C(1,0), C(2,0), C(3,1), C(4,0)];\n    assert(equal(splitter!\"a.x == b\"(a, [2, 3]), [ [C(1,0)], [C(4,0)] ]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.array : split;\n    import std.conv : text;\n\n    auto s = \",abc, de, fg,hi,\";\n    auto sp0 = splitter(s, ',');\n    assert(equal(sp0, [\"\", \"abc\", \" de\", \" fg\", \"hi\", \"\"][]));\n\n    auto s1 = \", abc, de,  fg, hi, \";\n    auto sp1 = splitter(s1, \", \");\n    assert(equal(sp1, [\"\", \"abc\", \"de\", \" fg\", \"hi\", \"\"][]));\n    static assert(isForwardRange!(typeof(sp1)));\n\n    int[] a = [ 1, 2, 0, 3, 0, 4, 5, 0 ];\n    int[][] w = [ [1, 2], [3], [4, 5], [] ];\n    uint i;\n    foreach (e; splitter(a, 0))\n    {\n        assert(i < w.length);\n        assert(e == w[i++]);\n    }\n    assert(i == w.length);\n\n    wstring names = \",peter,paul,jerry,\";\n    auto words = split(names, \",\");\n    assert(walkLength(words) == 5, text(walkLength(words)));\n}\n\n@safe unittest\n{\n    int[][] a = [ [1], [2], [0], [3], [0], [4], [5], [0] ];\n    int[][][] w = [ [[1], [2]], [[3]], [[4], [5]], [] ];\n    uint i;\n    foreach (e; splitter!\"a.front == 0\"(a, 0))\n    {\n        assert(i < w.length);\n        assert(e == w[i++]);\n    }\n    assert(i == w.length);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto s6 = \",\";\n    auto sp6 = splitter(s6, ',');\n    foreach (e; sp6) {}\n    assert(equal(sp6, [\"\", \"\"][]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // Issue 10773\n    auto s = splitter(\"abc\", \"\");\n    assert(s.equal([\"a\", \"b\", \"c\"]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // Test by-reference separator\n    class RefSep {\n    @safe:\n        string _impl;\n        this(string s) { _impl = s; }\n        @property empty() { return _impl.empty; }\n        @property auto front() { return _impl.front; }\n        void popFront() { _impl = _impl[1..$]; }\n        @property RefSep save() scope { return new RefSep(_impl); }\n        @property auto length() { return _impl.length; }\n    }\n    auto sep = new RefSep(\"->\");\n    auto data = \"i->am->pointing\";\n    auto words = splitter(data, sep);\n    assert(words.equal([ \"i\", \"am\", \"pointing\" ]));\n}\n\n/// ditto\nauto splitter(alias isTerminator, Range)(Range r)\nif (isForwardRange!Range && is(typeof(unaryFun!isTerminator(r.front))))\n{\n    return SplitterResult!(unaryFun!isTerminator, Range)(r);\n}\n\nprivate struct SplitterResult(alias isTerminator, Range)\n{\n    import std.algorithm.searching : find;\n    enum fullSlicing = (hasLength!Range && hasSlicing!Range) || isSomeString!Range;\n\n    private Range _input;\n    private size_t _end = 0;\n    static if (!fullSlicing)\n        private Range _next;\n\n    private void findTerminator()\n    {\n        static if (fullSlicing)\n        {\n            auto r = find!isTerminator(_input.save);\n            _end = _input.length - r.length;\n        }\n        else\n            for ( _end = 0; !_next.empty ; _next.popFront)\n            {\n                if (isTerminator(_next.front))\n                    break;\n                ++_end;\n            }\n    }\n\n    this(Range input)\n    {\n        _input = input;\n        static if (!fullSlicing)\n            _next = _input.save;\n\n        if (!_input.empty)\n            findTerminator();\n        else\n            _end = size_t.max;\n    }\n\n    static if (isInfinite!Range)\n    {\n        enum bool empty = false;  // Propagate infiniteness.\n    }\n    else\n    {\n        @property bool empty()\n        {\n            return _end == size_t.max;\n        }\n    }\n\n    @property auto front()\n    {\n        version (assert)\n        {\n            import core.exception : RangeError;\n            if (empty)\n                throw new RangeError();\n        }\n        static if (fullSlicing)\n            return _input[0 .. _end];\n        else\n        {\n            import std.range : takeExactly;\n            return _input.takeExactly(_end);\n        }\n    }\n\n    void popFront()\n    {\n        version (assert)\n        {\n            import core.exception : RangeError;\n            if (empty)\n                throw new RangeError();\n        }\n\n        static if (fullSlicing)\n        {\n            _input = _input[_end .. _input.length];\n            if (_input.empty)\n            {\n                _end = size_t.max;\n                return;\n            }\n            _input.popFront();\n        }\n        else\n        {\n            if (_next.empty)\n            {\n                _input = _next;\n                _end = size_t.max;\n                return;\n            }\n            _next.popFront();\n            _input = _next.save;\n        }\n        findTerminator();\n    }\n\n    @property typeof(this) save()\n    {\n        auto ret = this;\n        ret._input = _input.save;\n        static if (!fullSlicing)\n            ret._next = _next.save;\n        return ret;\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota;\n\n    auto L = iota(1L, 10L);\n    auto s = splitter(L, [5L, 6L]);\n    assert(equal(s.front, [1L, 2L, 3L, 4L]));\n    s.popFront();\n    assert(equal(s.front, [7L, 8L, 9L]));\n    s.popFront();\n    assert(s.empty);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.internal : algoFormat;\n    import std.internal.test.dummyrange;\n\n    void compare(string sentence, string[] witness)\n    {\n        auto r = splitter!\"a == ' '\"(sentence);\n        assert(equal(r.save, witness), algoFormat(\"got: %(%s, %) expected: %(%s, %)\", r, witness));\n    }\n\n    compare(\" Mary  has a little lamb.   \",\n            [\"\", \"Mary\", \"\", \"has\", \"a\", \"little\", \"lamb.\", \"\", \"\", \"\"]);\n    compare(\"Mary  has a little lamb.   \",\n            [\"Mary\", \"\", \"has\", \"a\", \"little\", \"lamb.\", \"\", \"\", \"\"]);\n    compare(\"Mary  has a little lamb.\",\n            [\"Mary\", \"\", \"has\", \"a\", \"little\", \"lamb.\"]);\n    compare(\"\", (string[]).init);\n    compare(\" \", [\"\", \"\"]);\n\n    static assert(isForwardRange!(typeof(splitter!\"a == ' '\"(\"ABC\"))));\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        static if (isRandomAccessRange!DummyType)\n        {\n            auto rangeSplit = splitter!\"a == 5\"(DummyType.init);\n            assert(equal(rangeSplit.front, [1,2,3,4]));\n            rangeSplit.popFront();\n            assert(equal(rangeSplit.front, [6,7,8,9,10]));\n        }\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.internal : algoFormat;\n    import std.range;\n\n    struct Entry\n    {\n        int low;\n        int high;\n        int[][] result;\n    }\n    Entry[] entries = [\n        Entry(0, 0, []),\n        Entry(0, 1, [[0]]),\n        Entry(1, 2, [[], []]),\n        Entry(2, 7, [[2], [4], [6]]),\n        Entry(1, 8, [[], [2], [4], [6], []]),\n    ];\n    foreach ( entry ; entries )\n    {\n        auto a = iota(entry.low, entry.high).filter!\"true\"();\n        auto b = splitter!\"a%2\"(a);\n        assert(equal!equal(b.save, entry.result), algoFormat(\"got: %(%s, %) expected: %(%s, %)\", b, entry.result));\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.uni : isWhite;\n\n    //@@@6791@@@\n    assert(equal(\n        splitter(\"là dove terminava quella valle\"),\n        [\"là\", \"dove\", \"terminava\", \"quella\", \"valle\"]\n    ));\n    assert(equal(\n        splitter!(std.uni.isWhite)(\"là dove terminava quella valle\"),\n        [\"là\", \"dove\", \"terminava\", \"quella\", \"valle\"]\n    ));\n    assert(equal(splitter!\"a=='本'\"(\"日本語\"), [\"日\", \"語\"]));\n}\n\n/++\nLazily splits the character-based range `s` into words, using whitespace as the\ndelimiter.\n\nThis function is character-range specific and, contrary to\n`splitter!(std.uni.isWhite)`, runs of whitespace will be merged together\n(no empty tokens will be produced).\n\nParams:\n    s = The character-based range to be split. Must be a string, or a\n    random-access range of character types.\n\nReturns:\n    An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of slices of\n    the original range split by whitespace.\n +/\nauto splitter(Range)(Range s)\nif (isSomeString!Range ||\n    isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range &&\n    !isConvertibleToString!Range &&\n    isSomeChar!(ElementEncodingType!Range))\n{\n    import std.algorithm.searching : find;\n    static struct Result\n    {\n    private:\n        import core.exception : RangeError;\n        Range _s;\n        size_t _frontLength;\n\n        void getFirst()\n        {\n            import std.uni : isWhite;\n            import std.traits : Unqual;\n\n            static if (is(Unqual!(ElementEncodingType!Range) == wchar) &&\n                       is(Unqual!(ElementType!Range) == dchar))\n            {\n                // all unicode whitespace characters fit into a wchar. However,\n                // this range is a wchar array, so we will treat it like a\n                // wchar array instead of decoding each code point.\n                _frontLength = _s.length; // default condition, no spaces\n                foreach (i; 0 .. _s.length)\n                    if (isWhite(_s[i]))\n                    {\n                        _frontLength = i;\n                        break;\n                    }\n            }\n            else static if (is(Unqual!(ElementType!Range) == dchar) ||\n                            is(Unqual!(ElementType!Range) == wchar))\n            {\n                // dchar or wchar range, we can just use find.\n                auto r = find!(isWhite)(_s.save);\n                _frontLength = _s.length - r.length;\n            }\n            else\n            {\n                // need to decode the characters until we find a space. This is\n                // ported from std.string.stripLeft.\n                static import std.ascii;\n                static import std.uni;\n                import std.utf : decodeFront;\n\n                auto input = _s.save;\n                size_t iLength = input.length;\n\n                while (!input.empty)\n                {\n                    auto c = input.front;\n                    if (std.ascii.isASCII(c))\n                    {\n                        if (std.ascii.isWhite(c))\n                            break;\n                        input.popFront();\n                        --iLength;\n                    }\n                    else\n                    {\n                        auto dc = decodeFront(input);\n                        if (std.uni.isWhite(dc))\n                            break;\n                        iLength = input.length;\n                    }\n                }\n\n                // sanity check\n                assert(iLength <= _s.length);\n\n                _frontLength = _s.length - iLength;\n            }\n        }\n\n    public:\n        this(Range s)\n        {\n            import std.string : stripLeft;\n            _s = s.stripLeft();\n            getFirst();\n        }\n\n        @property auto front()\n        {\n            version (assert) if (empty) throw new RangeError();\n            return _s[0 .. _frontLength];\n        }\n\n        void popFront()\n        {\n            import std.string : stripLeft;\n            version (assert) if (empty) throw new RangeError();\n            _s = _s[_frontLength .. $].stripLeft();\n            getFirst();\n        }\n\n        @property bool empty() const\n        {\n            return _s.empty;\n        }\n\n        @property inout(Result) save() inout @safe pure nothrow\n        {\n            return this;\n        }\n    }\n    return Result(s);\n}\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    auto a = \" a     bcd   ef gh \";\n    assert(equal(splitter(a), [\"a\", \"bcd\", \"ef\", \"gh\"][]));\n}\n\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.meta : AliasSeq;\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        import std.conv : to;\n        S a = \" a  \\u2028   bcd   ef gh \";\n        assert(equal(splitter(a), [to!S(\"a\"), to!S(\"bcd\"), to!S(\"ef\"), to!S(\"gh\")]));\n        a = \"\";\n        assert(splitter(a).empty);\n    }}\n\n    immutable string s = \" a     bcd   ef gh \";\n    assert(equal(splitter(s), [\"a\", \"bcd\", \"ef\", \"gh\"][]));\n}\n\n@safe unittest\n{\n    import std.conv : to;\n    import std.string : strip;\n\n    // TDPL example, page 8\n    uint[string] dictionary;\n    char[][3] lines;\n    lines[0] = \"line one\".dup;\n    lines[1] = \"line \\ttwo\".dup;\n    lines[2] = \"yah            last   line\\ryah\".dup;\n    foreach (line; lines)\n    {\n       foreach (word; splitter(strip(line)))\n       {\n            if (word in dictionary) continue; // Nothing to do\n            auto newID = dictionary.length;\n            dictionary[to!string(word)] = cast(uint) newID;\n        }\n    }\n    assert(dictionary.length == 5);\n    assert(dictionary[\"line\"]== 0);\n    assert(dictionary[\"one\"]== 1);\n    assert(dictionary[\"two\"]== 2);\n    assert(dictionary[\"yah\"]== 3);\n    assert(dictionary[\"last\"]== 4);\n\n}\n\n@safe unittest\n{\n    // do it with byCodeUnit\n    import std.conv : to;\n    import std.string : strip;\n    import std.utf : byCodeUnit;\n\n    alias BCU = typeof(\"abc\".byCodeUnit());\n\n    // TDPL example, page 8\n    uint[BCU] dictionary;\n    BCU[3] lines;\n    lines[0] = \"line one\".byCodeUnit;\n    lines[1] = \"line \\ttwo\".byCodeUnit;\n    lines[2] = \"yah            last   line\\ryah\".byCodeUnit;\n    foreach (line; lines)\n    {\n       foreach (word; splitter(strip(line)))\n       {\n           static assert(is(typeof(word) == BCU));\n            if (word in dictionary) continue; // Nothing to do\n            auto newID = dictionary.length;\n            dictionary[word] = cast(uint) newID;\n        }\n    }\n    assert(dictionary.length == 5);\n    assert(dictionary[\"line\".byCodeUnit]== 0);\n    assert(dictionary[\"one\".byCodeUnit]== 1);\n    assert(dictionary[\"two\".byCodeUnit]== 2);\n    assert(dictionary[\"yah\".byCodeUnit]== 3);\n    assert(dictionary[\"last\".byCodeUnit]== 4);\n}\n\n@safe pure unittest\n{\n    // issue 19238\n    import std.utf : byCodeUnit;\n    import std.algorithm.comparison : equal;\n    auto range = \"hello    world\".byCodeUnit.splitter;\n    static assert(is(typeof(range.front()) == typeof(\"hello\".byCodeUnit())));\n    assert(range.equal([\"hello\".byCodeUnit, \"world\".byCodeUnit]));\n\n    // test other space types, including unicode\n    auto u = \" a\\t\\v\\r bcd\\u3000 \\u2028\\t\\nef\\U00010001 gh\";\n    assert(equal(splitter(u), [\"a\", \"bcd\", \"ef\\U00010001\", \"gh\"][]));\n    assert(equal(splitter(u.byCodeUnit), [\"a\".byCodeUnit, \"bcd\".byCodeUnit,\n                 \"ef\\U00010001\".byCodeUnit, \"gh\".byCodeUnit][]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.internal : algoFormat;\n    import std.array : split;\n    import std.conv : text;\n\n    // Check consistency:\n    // All flavors of split should produce the same results\n    foreach (input; [(int[]).init,\n                     [0],\n                     [0, 1, 0],\n                     [1, 1, 0, 0, 1, 1],\n                    ])\n    {\n        foreach (s; [0, 1])\n        {\n            auto result = split(input, s);\n\n            assert(equal(result, split(input, [s])), algoFormat(`\"[%(%s,%)]\"`, split(input, [s])));\n            //assert(equal(result, split(input, [s].filter!\"true\"())));                          //Not yet implemented\n            assert(equal(result, split!((a) => a == s)(input)), text(split!((a) => a == s)(input)));\n\n            //assert(equal!equal(result, split(input.filter!\"true\"(), s)));                      //Not yet implemented\n            //assert(equal!equal(result, split(input.filter!\"true\"(), [s])));                    //Not yet implemented\n            //assert(equal!equal(result, split(input.filter!\"true\"(), [s].filter!\"true\"())));    //Not yet implemented\n            assert(equal!equal(result, split!((a) => a == s)(input.filter!\"true\"())));\n\n            assert(equal(result, splitter(input, s)));\n            assert(equal(result, splitter(input, [s])));\n            //assert(equal(result, splitter(input, [s].filter!\"true\"())));                       //Not yet implemented\n            assert(equal(result, splitter!((a) => a == s)(input)));\n\n            //assert(equal!equal(result, splitter(input.filter!\"true\"(), s)));                   //Not yet implemented\n            //assert(equal!equal(result, splitter(input.filter!\"true\"(), [s])));                 //Not yet implemented\n            //assert(equal!equal(result, splitter(input.filter!\"true\"(), [s].filter!\"true\"()))); //Not yet implemented\n            assert(equal!equal(result, splitter!((a) => a == s)(input.filter!\"true\"())));\n        }\n    }\n    foreach (input; [string.init,\n                     \" \",\n                     \"  hello \",\n                     \"hello   hello\",\n                     \" hello   what heck   this ?  \"\n                    ])\n    {\n        foreach (s; [' ', 'h'])\n        {\n            auto result = split(input, s);\n\n            assert(equal(result, split(input, [s])));\n            //assert(equal(result, split(input, [s].filter!\"true\"())));                          //Not yet implemented\n            assert(equal(result, split!((a) => a == s)(input)));\n\n            //assert(equal!equal(result, split(input.filter!\"true\"(), s)));                      //Not yet implemented\n            //assert(equal!equal(result, split(input.filter!\"true\"(), [s])));                    //Not yet implemented\n            //assert(equal!equal(result, split(input.filter!\"true\"(), [s].filter!\"true\"())));    //Not yet implemented\n            assert(equal!equal(result, split!((a) => a == s)(input.filter!\"true\"())));\n\n            assert(equal(result, splitter(input, s)));\n            assert(equal(result, splitter(input, [s])));\n            //assert(equal(result, splitter(input, [s].filter!\"true\"())));                       //Not yet implemented\n            assert(equal(result, splitter!((a) => a == s)(input)));\n\n            //assert(equal!equal(result, splitter(input.filter!\"true\"(), s)));                   //Not yet implemented\n            //assert(equal!equal(result, splitter(input.filter!\"true\"(), [s])));                 //Not yet implemented\n            //assert(equal!equal(result, splitter(input.filter!\"true\"(), [s].filter!\"true\"()))); //Not yet implemented\n            assert(equal!equal(result, splitter!((a) => a == s)(input.filter!\"true\"())));\n        }\n    }\n}\n\n// In same combinations substitute needs to calculate the auto-decoded length\n// of its needles\nprivate template hasDifferentAutodecoding(Range, Needles...)\n{\n    import std.meta : anySatisfy;\n    /* iff\n       - the needles needs auto-decoding, but the incoming range doesn't (or vice versa)\n       - both (range, needle) need auto-decoding and don't share the same common type\n    */\n    enum needlesAreNarrow = anySatisfy!(isNarrowString, Needles);\n    enum sourceIsNarrow = isNarrowString!Range;\n    enum hasDifferentAutodecoding = sourceIsNarrow != needlesAreNarrow ||\n                                    (sourceIsNarrow && needlesAreNarrow &&\n                                    is(CommonType!(Range, Needles) == void));\n}\n\n@safe nothrow @nogc pure unittest\n{\n    import std.meta : AliasSeq; // used for better clarity\n\n    static assert(!hasDifferentAutodecoding!(string, AliasSeq!(string, string)));\n    static assert(!hasDifferentAutodecoding!(wstring, AliasSeq!(wstring, wstring)));\n    static assert(!hasDifferentAutodecoding!(dstring, AliasSeq!(dstring, dstring)));\n\n    // the needles needs auto-decoding, but the incoming range doesn't (or vice versa)\n    static assert(hasDifferentAutodecoding!(string, AliasSeq!(wstring, wstring)));\n    static assert(hasDifferentAutodecoding!(string, AliasSeq!(dstring, dstring)));\n    static assert(hasDifferentAutodecoding!(wstring, AliasSeq!(string, string)));\n    static assert(hasDifferentAutodecoding!(wstring, AliasSeq!(dstring, dstring)));\n    static assert(hasDifferentAutodecoding!(dstring, AliasSeq!(string, string)));\n    static assert(hasDifferentAutodecoding!(dstring, AliasSeq!(wstring, wstring)));\n\n    // both (range, needle) need auto-decoding and don't share the same common type\n    static foreach (T; AliasSeq!(string, wstring, dstring))\n    {\n        static assert(hasDifferentAutodecoding!(T, AliasSeq!(wstring, string)));\n        static assert(hasDifferentAutodecoding!(T, AliasSeq!(dstring, string)));\n        static assert(hasDifferentAutodecoding!(T, AliasSeq!(wstring, dstring)));\n    }\n}\n\n// substitute\n/**\nReturns a range with all occurrences of `substs` in `r`.\nreplaced with their substitution.\n\nSingle value replacements (`'ö'.substitute!('ä', 'a', 'ö', 'o', 'ü', 'u)`) are\nsupported as well and in $(BIGOH 1).\n\nParams:\n    r = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    value = a single value which can be substituted in $(BIGOH 1)\n    substs = a set of replacements/substitutions\n    pred = the equality function to test if element(s) are equal to\n    a substitution\n\nReturns: a range with the substitutions replaced.\n\nSee_Also:\n$(REF replace, std, array) for an eager replace algorithm or\n$(REF translate, std, string), and $(REF tr, std, string)\nfor string algorithms with translation tables.\n*/\ntemplate substitute(substs...)\nif (substs.length >= 2 && isExpressions!substs)\n{\n    import std.range.primitives : ElementType;\n    import std.traits : CommonType;\n\n    static assert(!(substs.length & 1), \"The number of substitution parameters must be even\");\n\n    /**\n      Substitute single values with compile-time substitution mappings.\n      Complexity: $(BIGOH 1) due to D's `switch` guaranteeing $(BIGOH 1);\n    */\n    auto substitute(Value)(Value value)\n    if (isInputRange!Value || !is(CommonType!(Value, typeof(substs[0])) == void))\n    {\n        static if (isInputRange!Value)\n        {\n            static if (!is(CommonType!(ElementType!Value, typeof(substs[0])) == void))\n            {\n                // Substitute single range elements with compile-time substitution mappings\n                return value.map!(a => substitute(a));\n            }\n            else static if (isInputRange!Value &&\n                    !is(CommonType!(ElementType!Value, ElementType!(typeof(substs[0]))) == void))\n            {\n                // not implemented yet, fallback to runtime variant for now\n                return .substitute(value, substs);\n            }\n            else\n            {\n                static assert(0, `Compile-time substitutions must be elements or ranges of the same type of ` ~\n                    Value.stringof ~ `.`);\n            }\n        }\n        // Substitute single values with compile-time substitution mappings.\n        else // static if (!is(CommonType!(Value, typeof(substs[0])) == void))\n        {\n            switch (value)\n            {\n                static foreach (i; 0 .. substs.length / 2)\n                    case substs[2 * i]:\n                        return substs[2 * i + 1];\n\n                default: return value;\n            }\n        }\n    }\n}\n\n/// ditto\nauto substitute(alias pred = (a, b) => a == b, R, Substs...)(R r, Substs substs)\nif (isInputRange!R && Substs.length >= 2 && !is(CommonType!(Substs) == void))\n{\n    import std.range.primitives : ElementType;\n    import std.meta : allSatisfy;\n    import std.traits : CommonType;\n\n    static assert(!(Substs.length & 1), \"The number of substitution parameters must be even\");\n\n    enum n = Substs.length / 2;\n\n    // Substitute individual elements\n    static if (!is(CommonType!(ElementType!R, Substs) == void))\n    {\n        import std.functional : binaryFun;\n\n        // Imitate a value closure to be @nogc\n        static struct ReplaceElement\n        {\n            private Substs substs;\n\n            this(Substs substs)\n            {\n                this.substs = substs;\n            }\n\n            auto opCall(E)(E e)\n            {\n                static foreach (i; 0 .. n)\n                    if (binaryFun!pred(e, substs[2 * i]))\n                        return substs[2 * i + 1];\n\n                return e;\n            }\n        }\n        auto er = ReplaceElement(substs);\n        return r.map!er;\n    }\n    // Substitute subranges\n    else static if (!is(CommonType!(ElementType!R, ElementType!(Substs[0])) == void)  &&\n                        allSatisfy!(isForwardRange, Substs))\n    {\n        import std.range : choose, take;\n        import std.meta : Stride;\n\n        auto replaceElement(E)(E e)\n        {\n            alias ReturnA = typeof(e[0]);\n            alias ReturnB = typeof(substs[0 .. 1].take(1));\n\n            // 1-based index\n            const auto hitNr = e[1];\n            switch (hitNr)\n            {\n                // no hit\n                case 0:\n                    // use choose trick for non-common range\n                    static if (is(CommonType!(ReturnA, ReturnB) == void))\n                        return choose(1, e[0], ReturnB.init);\n                    else\n                        return e[0];\n\n                // all replacements\n                static foreach (i; 0 .. n)\n                    case i + 1:\n                        // use choose trick for non-common ranges\n                        static if (is(CommonType!(ReturnA, ReturnB) == void))\n                            return choose(0, e[0], substs[2 * i + 1].take(size_t.max));\n                        else\n                            return substs[2 * i + 1].take(size_t.max);\n                default:\n                    assert(0, \"hitNr should always be found.\");\n            }\n        }\n\n        alias Ins = Stride!(2, Substs);\n\n        static struct SubstituteSplitter\n        {\n            import std.range : drop;\n            import std.typecons : Tuple;\n\n            private\n            {\n                typeof(R.init.drop(0)) rest;\n                Ins needles;\n\n                typeof(R.init.take(0)) skip; // skip before next hit\n                alias Hit = size_t; // 0 iff no hit, otherwise hit in needles[index-1]\n                alias E = Tuple!(typeof(skip), Hit);\n                Hit hitNr; // hit number: 0 means no hit, otherwise index+1 to needles that matched\n                bool hasHit; // is there a replacement hit which should be printed?\n\n                enum hasDifferentAutodecoding = .hasDifferentAutodecoding!(typeof(rest), Ins);\n\n                // calculating the needle length for narrow strings might be expensive -> cache it\n                 static if (hasDifferentAutodecoding)\n                     ptrdiff_t[n] needleLengths = -1;\n            }\n\n            this(R haystack, Ins needles)\n            {\n                hasHit = !haystack.empty;\n                this.rest = haystack.drop(0);\n                this.needles = needles;\n                popFront;\n                static if (hasNested!(typeof(skip)))\n                    skip = rest.take(0);\n            }\n\n            /*  If `skip` is non-empty, it's returned as (skip, 0) tuple\n                otherwise a similar (<empty>, hitNr) tuple is returned.\n                `replaceElement` maps based on the second item (`hitNr`).\n            */\n            @property auto ref front()\n            {\n                assert(!empty, \"Attempting to fetch the front of an empty substitute.\");\n                return !skip.empty ? E(skip, 0) : E(typeof(skip).init, hitNr);\n            }\n\n            static if (isInfinite!R)\n                enum empty = false; // propagate infiniteness\n            else\n                @property bool empty()\n                {\n                    return skip.empty && !hasHit;\n                }\n\n            /* If currently in a skipping phase => reset.\n               Otherwise try to find the next occurrence of `needles`\n                  If valid match\n                    - if there are elements before the match, set skip with these elements\n                      (on the next popFront, the range will be in the skip state once)\n                    - `rest`: advance to the end of the match\n                    - set hasHit\n               Otherwise skip to the end\n            */\n            void popFront()\n            {\n                assert(!empty, \"Attempting to popFront an empty substitute.\");\n                if (!skip.empty)\n                {\n                    skip = typeof(skip).init; // jump over skip\n                }\n                else\n                {\n                    import std.algorithm.searching : countUntil, find;\n\n                    auto match = rest.find!pred(needles);\n\n                    static if (needles.length >= 2) // variadic version of find (returns a tuple)\n                    {\n                        // find with variadic needles returns a (range, needleNr) tuple\n                        // needleNr is a 1-based index\n                        auto hitValue = match[0];\n                        hitNr = match[1];\n                    }\n                    else\n                    {\n                        // find with one needle returns the range\n                        auto hitValue = match;\n                        hitNr = match.empty ? 0 : 1;\n                    }\n\n                    if (hitNr == 0) // no more hits\n                    {\n                        skip = rest.take(size_t.max);\n                        hasHit = false;\n                        rest = typeof(rest).init;\n                    }\n                    else\n                    {\n                        auto hitLength = size_t.max;\n                        switchL: switch (hitNr - 1)\n                        {\n                            static foreach (i; 0 .. n)\n                            {\n                                case i:\n                                    static if (hasDifferentAutodecoding)\n                                    {\n                                        import std.utf : codeLength;\n\n                                        // cache calculated needle length\n                                        if (needleLengths[i] != -1)\n                                            hitLength = needleLengths[i];\n                                        else\n                                            hitLength = needleLengths[i] = codeLength!dchar(needles[i]);\n                                    }\n                                    else\n                                    {\n                                        hitLength = needles[i].length;\n                                    }\n                                    break switchL;\n                            }\n                            default:\n                                assert(0, \"hitNr should always be found\");\n                        }\n\n                        const pos = rest.countUntil(hitValue);\n                        if (pos > 0) // match not at start of rest\n                            skip = rest.take(pos);\n\n                        hasHit = true;\n\n                        // iff the source range and the substitutions are narrow strings,\n                        // we can avoid calling the auto-decoding `popFront` (via drop)\n                        static if (isNarrowString!(typeof(hitValue)) && !hasDifferentAutodecoding)\n                            rest = hitValue[hitLength .. $];\n                        else\n                            rest = hitValue.drop(hitLength);\n                    }\n                }\n            }\n        }\n\n        // extract inputs\n        Ins ins;\n        static foreach (i; 0 .. n)\n            ins[i] = substs[2 * i];\n\n        return SubstituteSplitter(r, ins)\n                .map!(a => replaceElement(a))\n                .joiner;\n    }\n    else\n    {\n        static assert(0, \"The substitutions must either substitute a single element or a save-able subrange.\");\n    }\n}\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // substitute single elements\n    assert(\"do_it\".substitute('_', ' ').equal(\"do it\"));\n\n    // substitute multiple, single elements\n    assert(\"do_it\".substitute('_', ' ',\n                               'd', 'g',\n                               'i', 't',\n                               't', 'o')\n                  .equal(\"go to\"));\n\n    // substitute subranges\n    assert(\"do_it\".substitute(\"_\", \" \",\n                              \"do\", \"done\")\n                  .equal(\"done it\"));\n\n    // substitution works for any ElementType\n    int[] x = [1, 2, 3];\n    auto y = x.substitute(1, 0.1);\n    assert(y.equal([0.1, 2, 3]));\n    static assert(is(typeof(y.front) == double));\n\n    import std.range : retro;\n    assert([1, 2, 3].substitute(1, 0.1).retro.equal([3, 2, 0.1]));\n}\n\n/// Use the faster compile-time overload\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // substitute subranges of a range\n    assert(\"apple_tree\".substitute!(\"apple\", \"banana\",\n                                    \"tree\", \"shrub\").equal(\"banana_shrub\"));\n\n    // substitute subranges of a range\n    assert(\"apple_tree\".substitute!('a', 'b',\n                                    't', 'f').equal(\"bpple_free\"));\n\n    // substitute values\n    assert('a'.substitute!('a', 'b', 't', 'f') == 'b');\n}\n\n/// Multiple substitutes\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range.primitives : ElementType;\n\n    int[3] x = [1, 2, 3];\n    auto y = x[].substitute(1, 0.1)\n                .substitute(0.1, 0.2);\n    static assert(is(typeof(y.front) == double));\n    assert(y.equal([0.2, 2, 3]));\n\n    auto z = \"42\".substitute('2', '3')\n                 .substitute('3', '1');\n    static assert(is(ElementType!(typeof(z)) == dchar));\n    assert(equal(z, \"41\"));\n}\n\n// Test the first example with compile-time overloads\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // substitute single elements\n    assert(\"do_it\".substitute!('_', ' ').equal(\"do it\"));\n\n    // substitute multiple, single elements\n    assert(\"do_it\".substitute!('_', ' ',\n                               'd', 'g',\n                               'i', 't',\n                               't', 'o')\n                  .equal(`go to`));\n\n    // substitute subranges\n    assert(\"do_it\".substitute!(\"_\", \" \",\n                               \"do\", \"done\")\n                  .equal(\"done it\"));\n\n    // substitution works for any ElementType\n    int[3] x = [1, 2, 3];\n    auto y = x[].substitute!(1, 0.1);\n    assert(y.equal([0.1, 2, 3]));\n    static assert(is(typeof(y.front) == double));\n\n    import std.range : retro;\n    assert([1, 2, 3].substitute!(1, 0.1).retro.equal([3, 2, 0.1]));\n}\n\n// test infinite ranges\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : cycle, take;\n\n    int[] x = [1, 2, 3];\n    assert(x.cycle.substitute!(1, 0.1).take(4).equal([0.1, 2, 3, 0.1]));\n    assert(x.cycle.substitute(1, 0.1).take(4).equal([0.1, 2, 3, 0.1]));\n}\n\n// test infinite ranges\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges;\n\n    foreach (R; AllDummyRanges)\n    {\n        assert(R.init\n                .substitute!(2, 22, 3, 33, 5, 55, 9, 99)\n                .equal([1, 22, 33, 4, 55, 6, 7, 8, 99, 10]));\n\n        assert(R.init\n                .substitute(2, 22, 3, 33, 5, 55, 9, 99)\n                .equal([1, 22, 33, 4, 55, 6, 7, 8, 99, 10]));\n    }\n}\n\n// test multiple replacements\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(\"alpha.beta.gamma\"\n            .substitute(\"alpha\", \"1\",\n                        \"gamma\", \"3\",\n                        \"beta\", \"2\").equal(\"1.2.3\"));\n\n    assert(\"alpha.beta.gamma.\"\n            .substitute(\"alpha\", \"1\",\n                        \"gamma\", \"3\",\n                        \"beta\", \"2\").equal(\"1.2.3.\"));\n\n    assert(\"beta.beta.beta\"\n            .substitute(\"alpha\", \"1\",\n                        \"gamma\", \"3\",\n                        \"beta\", \"2\").equal(\"2.2.2\"));\n\n    assert(\"alpha.alpha.alpha\"\n            .substitute(\"alpha\", \"1\",\n                        \"gamma\", \"3\",\n                        \"beta\", \"2\").equal(\"1.1.1\"));\n}\n\n// test combination of subrange + element replacement\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert((\"abcDe\".substitute(\"a\", \"AA\",\n                               \"b\", \"DD\")\n                   .substitute('A', 'y',\n                               'D', 'x',\n                               'e', '1'))\n           .equal(\"yyxxcx1\"));\n}\n\n// test const + immutable storage groups\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto xyz_abc(T)(T value)\n    {\n        immutable a = \"a\";\n        const b = \"b\";\n        auto c = \"c\";\n        return value.substitute!(\"x\", a,\n                                 \"y\", b,\n                                 \"z\", c);\n    }\n    assert(xyz_abc(\"_x\").equal(\"_a\"));\n    assert(xyz_abc(\".y.\").equal(\".b.\"));\n    assert(xyz_abc(\"z\").equal(\"c\"));\n    assert(xyz_abc(\"w\").equal(\"w\"));\n}\n\n// test with narrow strings (auto-decoding) and subranges\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(\"äöü€\".substitute(\"ä\", \"b\", \"ü\", \"u\").equal(\"böu€\"));\n    assert(\"äöü€\".substitute!(\"ä\", \"b\", \"ü\", \"u\").equal(\"böu€\"));\n    assert(\"ä...öü€\".substitute(\"ä\", \"b\", \"ü\", \"u\").equal(\"b...öu€\"));\n\n    auto expected = \"emoticons😄😅.😇😈Rock\";\n    assert(\"emoticons😄😅😆😇😈rock\"\n            .substitute(\"r\", \"R\", \"😆\", \".\").equal(expected));\n    assert(\"emoticons😄😅😆😇😈rock\"\n            .substitute!(\"r\", \"R\", \"😆\", \".\").equal(expected));\n}\n\n// test with narrow strings (auto-decoding) and single elements\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(\"äöü€\".substitute('ä', 'b', 'ü', 'u').equal(\"böu€\"));\n    assert(\"äöü€\".substitute!('ä', 'b', 'ü', 'u').equal(\"böu€\"));\n\n    auto expected = \"emoticons😄😅.😇😈Rock\";\n    assert(\"emoticons😄😅😆😇😈rock\"\n            .substitute('r', 'R', '😆', '.').equal(expected));\n    assert(\"emoticons😄😅😆😇😈rock\"\n            .substitute!('r', 'R', '😆', '.').equal(expected));\n}\n\n// test auto-decoding {n,w,d} strings X {n,w,d} strings\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(\"ääöü€\".substitute(\"ä\", \"b\", \"ü\", \"u\").equal(\"bböu€\"));\n    assert(\"ääöü€\".substitute(\"ä\"w, \"b\"w, \"ü\"w, \"u\"w).equal(\"bböu€\"));\n    assert(\"ääöü€\".substitute(\"ä\"d, \"b\"d, \"ü\"d, \"u\"d).equal(\"bböu€\"));\n\n    assert(\"ääöü€\"w.substitute(\"ä\", \"b\", \"ü\", \"u\").equal(\"bböu€\"));\n    assert(\"ääöü€\"w.substitute(\"ä\"w, \"b\"w, \"ü\"w, \"u\"w).equal(\"bböu€\"));\n    assert(\"ääöü€\"w.substitute(\"ä\"d, \"b\"d, \"ü\"d, \"u\"d).equal(\"bböu€\"));\n\n    assert(\"ääöü€\"d.substitute(\"ä\", \"b\", \"ü\", \"u\").equal(\"bböu€\"));\n    assert(\"ääöü€\"d.substitute(\"ä\"w, \"b\"w, \"ü\"w, \"u\"w).equal(\"bböu€\"));\n    assert(\"ääöü€\"d.substitute(\"ä\"d, \"b\"d, \"ü\"d, \"u\"d).equal(\"bböu€\"));\n\n    // auto-decoding is done before by a different range\n    assert(\"ääöü€\".filter!(a => true).substitute(\"ä\", \"b\", \"ü\", \"u\").equal(\"bböu€\"));\n    assert(\"ääöü€\".filter!(a => true).substitute(\"ä\"w, \"b\"w, \"ü\"w, \"u\"w).equal(\"bböu€\"));\n    assert(\"ääöü€\".filter!(a => true).substitute(\"ä\"d, \"b\"d, \"ü\"d, \"u\"d).equal(\"bböu€\"));\n}\n\n// test repeated replacement\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert([1, 2, 3, 1, 1, 2].substitute(1, 0).equal([0, 2, 3, 0, 0, 2]));\n    assert([1, 2, 3, 1, 1, 2].substitute!(1, 0).equal([0, 2, 3, 0, 0, 2]));\n    assert([1, 2, 3, 1, 1, 2].substitute(1, 2, 2, 9).equal([2, 9, 3, 2, 2, 9]));\n}\n\n// test @nogc for single element replacements\n@safe @nogc unittest\n{\n    import std.algorithm.comparison : equal;\n\n    static immutable arr = [1, 2, 3, 1, 1, 2];\n    static immutable expected = [0, 2, 3, 0, 0, 2];\n\n    assert(arr.substitute!(1, 0).equal(expected));\n    assert(arr.substitute(1, 0).equal(expected));\n}\n\n// test different range types\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges;\n\n    static foreach (DummyType; AllDummyRanges)\n    {{\n        DummyType dummyRange;\n\n        // single substitution\n        dummyRange.substitute (2, 22).equal([1, 22, 3, 4, 5, 6, 7, 8, 9, 10]);\n        dummyRange.substitute!(2, 22).equal([1, 22, 3, 4, 5, 6, 7, 8, 9, 10]);\n\n        // multiple substitution\n        dummyRange.substitute (2, 22, 5, 55, 7, 77).equal([1, 22, 3, 4, 55, 6, 77, 8, 9, 10]);\n        dummyRange.substitute!(2, 22, 5, 55, 7, 77).equal([1, 22, 3, 4, 55, 6, 77, 8, 9, 10]);\n    }}\n}\n\n// issue 19207\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    assert([1, 2, 3, 4].substitute([1], [7]).equal([7, 2, 3, 4]));\n    assert([1, 2, 3, 4].substitute([2], [7]).equal([1, 7, 3, 4]));\n    assert([1, 2, 3, 4].substitute([4], [7]).equal([1, 2, 3, 7]));\n    assert([1, 2, 3, 4].substitute([2, 3], [7]).equal([1, 7, 4]));\n    assert([1, 2, 3, 4].substitute([3, 4], [7, 8]).equal([1, 2, 7, 8]));\n}\n\n// sum\n/**\nSums elements of `r`, which must be a finite\n$(REF_ALTTEXT input range, isInputRange, std,range,primitives). Although\nconceptually `sum(r)` is equivalent to $(LREF fold)!((a, b) => a +\nb)(r, 0), `sum` uses specialized algorithms to maximize accuracy,\nas follows.\n\n$(UL\n$(LI If `$(REF ElementType, std,range,primitives)!R` is a floating-point\ntype and `R` is a\n$(REF_ALTTEXT random-access range, isRandomAccessRange, std,range,primitives) with\nlength and slicing, then `sum` uses the\n$(HTTP en.wikipedia.org/wiki/Pairwise_summation, pairwise summation)\nalgorithm.)\n$(LI If `ElementType!R` is a floating-point type and `R` is a\nfinite input range (but not a random-access range with slicing), then\n`sum` uses the $(HTTP en.wikipedia.org/wiki/Kahan_summation,\nKahan summation) algorithm.)\n$(LI In all other cases, a simple element by element addition is done.)\n)\n\nFor floating point inputs, calculations are made in\n$(DDLINK spec/type, Types, `real`)\nprecision for `real` inputs and in `double` precision otherwise\n(Note this is a special case that deviates from `fold`'s behavior,\nwhich would have kept `float` precision for a `float` range).\nFor all other types, the calculations are done in the same type obtained\nfrom from adding two elements of the range, which may be a different\ntype from the elements themselves (for example, in case of\n$(DDSUBLINK spec/type,integer-promotions, integral promotion)).\n\nA seed may be passed to `sum`. Not only will this seed be used as an initial\nvalue, but its type will override all the above, and determine the algorithm\nand precision used for summation.\n\nNote that these specialized summing algorithms execute more primitive operations\nthan vanilla summation. Therefore, if in certain cases maximum speed is required\nat expense of precision, one can use `fold!((a, b) => a + b)(r, 0)`, which\nis not specialized for summation.\n\nParams:\n    seed = the initial value of the summation\n    r = a finite input range\n\nReturns:\n    The sum of all the elements in the range r.\n */\nauto sum(R)(R r)\nif (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front)))\n{\n    alias E = Unqual!(ElementType!R);\n    static if (isFloatingPoint!E)\n        alias Seed = typeof(E.init  + 0.0); //biggest of double/real\n    else\n        alias Seed = typeof(r.front + r.front);\n    return sum(r, Unqual!Seed(0));\n}\n/// ditto\nauto sum(R, E)(R r, E seed)\nif (isInputRange!R && !isInfinite!R && is(typeof(seed = seed + r.front)))\n{\n    static if (isFloatingPoint!E)\n    {\n        static if (hasLength!R && hasSlicing!R)\n        {\n            if (r.empty) return seed;\n            return seed + sumPairwise!E(r);\n        }\n        else\n            return sumKahan!E(seed, r);\n    }\n    else\n    {\n        return reduce!\"a + b\"(seed, r);\n    }\n}\n\n/// Ditto\n@safe pure nothrow unittest\n{\n    import std.range;\n\n    //simple integral sumation\n    assert(sum([ 1, 2, 3, 4]) == 10);\n\n    //with integral promotion\n    assert(sum([false, true, true, false, true]) == 3);\n    assert(sum(ubyte.max.repeat(100)) == 25500);\n\n    //The result may overflow\n    assert(uint.max.repeat(3).sum()           ==  4294967293U );\n    //But a seed can be used to change the sumation primitive\n    assert(uint.max.repeat(3).sum(ulong.init) == 12884901885UL);\n\n    //Floating point sumation\n    assert(sum([1.0, 2.0, 3.0, 4.0]) == 10);\n\n    //Floating point operations have double precision minimum\n    static assert(is(typeof(sum([1F, 2F, 3F, 4F])) == double));\n    assert(sum([1F, 2, 3, 4]) == 10);\n\n    //Force pair-wise floating point sumation on large integers\n    import std.math : approxEqual;\n    assert(iota(ulong.max / 2, ulong.max / 2 + 4096).sum(0.0)\n               .approxEqual((ulong.max / 2) * 4096.0 + 4096^^2 / 2));\n}\n\n// Pairwise summation http://en.wikipedia.org/wiki/Pairwise_summation\nprivate auto sumPairwise(F, R)(R data)\nif (isInputRange!R && !isInfinite!R)\n{\n    import core.bitop : bsf;\n    // Works for r with at least length < 2^^(64 + log2(16)), in keeping with the use of size_t\n    // elsewhere in std.algorithm and std.range on 64 bit platforms. The 16 in log2(16) comes\n    // from the manual unrolling in sumPairWise16\n    F[64] store = void;\n    size_t idx = 0;\n\n    void collapseStore(T)(T k)\n    {\n        auto lastToKeep = idx - cast(uint) bsf(k+1);\n        while (idx > lastToKeep)\n        {\n            store[idx - 1] += store[idx];\n            --idx;\n        }\n    }\n\n    static if (hasLength!R)\n    {\n        foreach (k; 0 .. data.length / 16)\n        {\n            static if (isRandomAccessRange!R && hasSlicing!R)\n            {\n                store[idx] = sumPairwise16!F(data);\n                data = data[16 .. data.length];\n            }\n            else store[idx] = sumPairwiseN!(16, false, F)(data);\n\n            collapseStore(k);\n            ++idx;\n        }\n\n        size_t i = 0;\n        foreach (el; data)\n        {\n            store[idx] = el;\n            collapseStore(i);\n            ++idx;\n            ++i;\n        }\n    }\n    else\n    {\n        size_t k = 0;\n        while (!data.empty)\n        {\n            store[idx] = sumPairwiseN!(16, true, F)(data);\n            collapseStore(k);\n            ++idx;\n            ++k;\n        }\n    }\n\n    F s = store[idx - 1];\n    foreach_reverse (j; 0 .. idx - 1)\n        s += store[j];\n\n    return s;\n}\n\nprivate auto sumPairwise16(F, R)(R r)\nif (isRandomAccessRange!R)\n{\n    return (((cast(F) r[ 0] + r[ 1]) + (cast(F) r[ 2] + r[ 3]))\n          + ((cast(F) r[ 4] + r[ 5]) + (cast(F) r[ 6] + r[ 7])))\n         + (((cast(F) r[ 8] + r[ 9]) + (cast(F) r[10] + r[11]))\n          + ((cast(F) r[12] + r[13]) + (cast(F) r[14] + r[15])));\n}\n\nprivate auto sumPair(bool needEmptyChecks, F, R)(ref R r)\nif (isForwardRange!R && !isRandomAccessRange!R)\n{\n    static if (needEmptyChecks) if (r.empty) return F(0);\n    F s0 = r.front;\n    r.popFront();\n    static if (needEmptyChecks) if (r.empty) return s0;\n    s0 += r.front;\n    r.popFront();\n    return s0;\n}\n\nprivate auto sumPairwiseN(size_t N, bool needEmptyChecks, F, R)(ref R r)\nif (isForwardRange!R && !isRandomAccessRange!R)\n{\n    import std.math : isPowerOf2;\n    static assert(isPowerOf2(N));\n    static if (N == 2) return sumPair!(needEmptyChecks, F)(r);\n    else return sumPairwiseN!(N/2, needEmptyChecks, F)(r)\n        + sumPairwiseN!(N/2, needEmptyChecks, F)(r);\n}\n\n// Kahan algo http://en.wikipedia.org/wiki/Kahan_summation_algorithm\nprivate auto sumKahan(Result, R)(Result result, R r)\n{\n    static assert(isFloatingPoint!Result && isMutable!Result);\n    Result c = 0;\n    for (; !r.empty; r.popFront())\n    {\n        immutable y = r.front - c;\n        immutable t = result + y;\n        c = (t - result) - y;\n        result = t;\n    }\n    return result;\n}\n\n@safe pure nothrow unittest\n{\n    static assert(is(typeof(sum([cast( byte) 1])) ==  int));\n    static assert(is(typeof(sum([cast(ubyte) 1])) ==  int));\n    static assert(is(typeof(sum([  1,   2,   3,   4])) ==  int));\n    static assert(is(typeof(sum([ 1U,  2U,  3U,  4U])) == uint));\n    static assert(is(typeof(sum([ 1L,  2L,  3L,  4L])) ==  long));\n    static assert(is(typeof(sum([1UL, 2UL, 3UL, 4UL])) == ulong));\n\n    int[] empty;\n    assert(sum(empty) == 0);\n    assert(sum([42]) == 42);\n    assert(sum([42, 43]) == 42 + 43);\n    assert(sum([42, 43, 44]) == 42 + 43 + 44);\n    assert(sum([42, 43, 44, 45]) == 42 + 43 + 44 + 45);\n}\n\n@safe pure nothrow unittest\n{\n    static assert(is(typeof(sum([1.0, 2.0, 3.0, 4.0])) == double));\n    static assert(is(typeof(sum([ 1F,  2F,  3F,  4F])) == double));\n    const(float[]) a = [1F, 2F, 3F, 4F];\n    assert(sum(a) == 10F);\n    static assert(is(typeof(sum(a)) == double));\n\n    double[] empty;\n    assert(sum(empty) == 0);\n    assert(sum([42.]) == 42);\n    assert(sum([42., 43.]) == 42 + 43);\n    assert(sum([42., 43., 44.]) == 42 + 43 + 44);\n    assert(sum([42., 43., 44., 45.5]) == 42 + 43 + 44 + 45.5);\n}\n\n@safe pure nothrow unittest\n{\n    import std.container;\n    static assert(is(typeof(sum(SList!float()[])) == double));\n    static assert(is(typeof(sum(SList!double()[])) == double));\n    static assert(is(typeof(sum(SList!real()[])) == real));\n\n    assert(sum(SList!double()[]) == 0);\n    assert(sum(SList!double(1)[]) == 1);\n    assert(sum(SList!double(1, 2)[]) == 1 + 2);\n    assert(sum(SList!double(1, 2, 3)[]) == 1 + 2 + 3);\n    assert(sum(SList!double(1, 2, 3, 4)[]) == 10);\n}\n\n@safe pure nothrow unittest // 12434\n{\n    immutable a = [10, 20];\n    auto s1 = sum(a);\n    assert(s1 == 30);\n    auto s2 = a.map!(x => x).sum;\n    assert(s2 == 30);\n}\n\n@system unittest\n{\n    import std.bigint;\n    import std.range;\n\n    immutable BigInt[] a = BigInt(\"1_000_000_000_000_000_000\").repeat(10).array();\n    immutable ulong[]  b = (ulong.max/2).repeat(10).array();\n    auto sa = a.sum();\n    auto sb = b.sum(BigInt(0)); //reduce ulongs into bigint\n    assert(sa == BigInt(\"10_000_000_000_000_000_000\"));\n    assert(sb == (BigInt(ulong.max/2) * 10));\n}\n\n@safe pure nothrow @nogc unittest\n{\n    import std.range;\n    foreach (n; iota(50))\n        assert(repeat(1.0, n).sum == n);\n}\n\n/**\nFinds the mean (colloquially known as the average) of a range.\n\nFor built-in numerical types, accurate Knuth & Welford mean calculation\nis used. For user-defined types, element by element summation is used.\nAdditionally an extra parameter `seed` is needed in order to correctly\nseed the summation with the equivalent to `0`.\n\nThe first overload of this function will return `T.init` if the range\nis empty. However, the second overload will return `seed` on empty ranges.\n\nThis function is $(BIGOH r.length).\n\nParams:\n    T = The type of the return value.\n    r = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    seed = For user defined types. Should be equivalent to `0`.\n\nReturns:\n    The mean of `r` when `r` is non-empty.\n*/\nT mean(T = double, R)(R r)\nif (isInputRange!R &&\n    isNumeric!(ElementType!R) &&\n    !isInfinite!R)\n{\n    if (r.empty)\n        return T.init;\n\n    Unqual!T meanRes = 0;\n    size_t i = 1;\n\n    // Knuth & Welford mean calculation\n    // division per element is slower, but more accurate\n    for (; !r.empty; r.popFront())\n    {\n        T delta = r.front - meanRes;\n        meanRes += delta / i++;\n    }\n\n    return meanRes;\n}\n\n/// ditto\nauto mean(R, T)(R r, T seed)\nif (isInputRange!R &&\n    !isNumeric!(ElementType!R) &&\n    is(typeof(r.front + seed)) &&\n    is(typeof(r.front / size_t(1))) &&\n    !isInfinite!R)\n{\n    import std.algorithm.iteration : sum, reduce;\n\n    // per item division vis-a-vis the previous overload is too\n    // inaccurate for integer division, which the user defined\n    // types might be representing\n    static if (hasLength!R)\n    {\n        if (r.length == 0)\n            return seed;\n\n        return sum(r, seed) / r.length;\n    }\n    else\n    {\n        import std.typecons : tuple;\n\n        if (r.empty)\n            return seed;\n\n        auto pair = reduce!((a, b) => tuple(a[0] + 1, a[1] + b))\n            (tuple(size_t(0), seed), r);\n        return pair[1] / pair[0];\n    }\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    import std.math : approxEqual, isNaN;\n\n    static immutable arr1 = [1, 2, 3];\n    static immutable arr2 = [1.5, 2.5, 12.5];\n\n    assert(arr1.mean.approxEqual(2));\n    assert(arr2.mean.approxEqual(5.5));\n\n    assert(arr1[0 .. 0].mean.isNaN);\n}\n\n@safe pure nothrow unittest\n{\n    import std.internal.test.dummyrange : ReferenceInputRange;\n    import std.math : approxEqual;\n\n    auto r1 = new ReferenceInputRange!int([1, 2, 3]);\n    assert(r1.mean.approxEqual(2));\n\n    auto r2 = new ReferenceInputRange!double([1.5, 2.5, 12.5]);\n    assert(r2.mean.approxEqual(5.5));\n}\n\n// Test user defined types\n@system pure unittest\n{\n    import std.bigint : BigInt;\n    import std.internal.test.dummyrange : ReferenceInputRange;\n    import std.math : approxEqual;\n\n    auto bigint_arr = [BigInt(\"1\"), BigInt(\"2\"), BigInt(\"3\"), BigInt(\"6\")];\n    auto bigint_arr2 = new ReferenceInputRange!BigInt([\n        BigInt(\"1\"), BigInt(\"2\"), BigInt(\"3\"), BigInt(\"6\")\n    ]);\n    assert(bigint_arr.mean(BigInt(0)) == BigInt(\"3\"));\n    assert(bigint_arr2.mean(BigInt(0)) == BigInt(\"3\"));\n\n    BigInt[] bigint_arr3 = [];\n    assert(bigint_arr3.mean(BigInt(0)) == BigInt(0));\n\n    struct MyFancyDouble\n    {\n       double v;\n       alias v this;\n    }\n\n    // both overloads\n    auto d_arr = [MyFancyDouble(10), MyFancyDouble(15), MyFancyDouble(30)];\n    assert(mean!(double)(cast(double[]) d_arr).approxEqual(18.333));\n    assert(mean(d_arr, MyFancyDouble(0)).approxEqual(18.333));\n}\n\n// uniq\n/**\nLazily iterates unique consecutive elements of the given range (functionality\nakin to the $(HTTP wikipedia.org/wiki/_Uniq, _uniq) system\nutility). Equivalence of elements is assessed by using the predicate\n`pred`, by default `\"a == b\"`. The predicate is passed to\n$(REF binaryFun, std,functional), and can either accept a string, or any callable\nthat can be executed via `pred(element, element)`. If the given range is\nbidirectional, `uniq` also yields a\n$(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives).\n\nParams:\n    pred = Predicate for determining equivalence between range elements.\n    r = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of\n        elements to filter.\n\nReturns:\n    An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of\n    consecutively unique elements in the original range. If `r` is also a\n    forward range or bidirectional range, the returned range will be likewise.\n*/\nauto uniq(alias pred = \"a == b\", Range)(Range r)\nif (isInputRange!Range && is(typeof(binaryFun!pred(r.front, r.front)) == bool))\n{\n    return UniqResult!(binaryFun!pred, Range)(r);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.mutation : copy;\n\n    int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];\n    assert(equal(uniq(arr), [ 1, 2, 3, 4, 5 ][]));\n\n    // Filter duplicates in-place using copy\n    arr.length -= arr.uniq().copy(arr).length;\n    assert(arr == [ 1, 2, 3, 4, 5 ]);\n\n    // Note that uniqueness is only determined consecutively; duplicated\n    // elements separated by an intervening different element will not be\n    // eliminated:\n    assert(equal(uniq([ 1, 1, 2, 1, 1, 3, 1]), [1, 2, 1, 3, 1]));\n}\n\nprivate struct UniqResult(alias pred, Range)\n{\n    Range _input;\n\n    this(Range input)\n    {\n        _input = input;\n    }\n\n    auto opSlice()\n    {\n        return this;\n    }\n\n    void popFront()\n    {\n        assert(!empty, \"Attempting to popFront an empty uniq.\");\n        auto last = _input.front;\n        do\n        {\n            _input.popFront();\n        }\n        while (!_input.empty && pred(last, _input.front));\n    }\n\n    @property ElementType!Range front()\n    {\n        assert(!empty, \"Attempting to fetch the front of an empty uniq.\");\n        return _input.front;\n    }\n\n    static if (isBidirectionalRange!Range)\n    {\n        void popBack()\n        {\n            assert(!empty, \"Attempting to popBack an empty uniq.\");\n            auto last = _input.back;\n            do\n            {\n                _input.popBack();\n            }\n            while (!_input.empty && pred(last, _input.back));\n        }\n\n        @property ElementType!Range back()\n        {\n            assert(!empty, \"Attempting to fetch the back of an empty uniq.\");\n            return _input.back;\n        }\n    }\n\n    static if (isInfinite!Range)\n    {\n        enum bool empty = false;  // Propagate infiniteness.\n    }\n    else\n    {\n        @property bool empty() { return _input.empty; }\n    }\n\n    static if (isForwardRange!Range)\n    {\n        @property typeof(this) save() {\n            return typeof(this)(_input.save);\n        }\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange;\n    import std.range;\n\n    int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];\n    auto r = uniq(arr);\n    static assert(isForwardRange!(typeof(r)));\n\n    assert(equal(r, [ 1, 2, 3, 4, 5 ][]));\n    assert(equal(retro(r), retro([ 1, 2, 3, 4, 5 ][])));\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType d;\n        auto u = uniq(d);\n        assert(equal(u, [1,2,3,4,5,6,7,8,9,10]));\n\n        static assert(d.rt == RangeType.Input || isForwardRange!(typeof(u)));\n\n        static if (d.rt >= RangeType.Bidirectional)\n        {\n            assert(equal(retro(u), [10,9,8,7,6,5,4,3,2,1]));\n        }\n    }\n}\n\n@safe unittest // https://issues.dlang.org/show_bug.cgi?id=17264\n{\n    import std.algorithm.comparison : equal;\n\n    const(int)[] var = [0, 1, 1, 2];\n    assert(var.uniq.equal([0, 1, 2]));\n}\n\n/**\nLazily computes all _permutations of `r` using $(HTTP\nen.wikipedia.org/wiki/Heap%27s_algorithm, Heap's algorithm).\n\nParams:\n    Range = the range type\n    r = the $(REF_ALTTEXT random access range, isRandomAccessRange, std,range,primitives)\n    to find the permutations for.\nReturns:\n    A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n    of elements of which are an $(REF indexed, std,range) view into `r`.\n\nSee_Also:\n$(REF nextPermutation, std,algorithm,sorting).\n*/\nPermutations!Range permutations(Range)(Range r)\nif (isRandomAccessRange!Range && hasLength!Range)\n{\n    return typeof(return)(r);\n}\n\n/// ditto\nstruct Permutations(Range)\nif (isRandomAccessRange!Range && hasLength!Range)\n{\n    private size_t[] _indices, _state;\n    private Range _r;\n    private bool _empty;\n\n    ///\n    this(Range r)\n    {\n        import std.array : array;\n        import std.range : iota;\n\n        this._r = r;\n        _state = r.length ? new size_t[r.length-1] : null;\n        _indices = iota(size_t(r.length)).array;\n        _empty = r.length == 0;\n    }\n\n    /// Returns: `true` if the range is empty, `false` otherwise.\n    @property bool empty() const pure nothrow @safe @nogc\n    {\n        return _empty;\n    }\n\n    /// Returns: the front of the range\n    @property auto front()\n    {\n        import std.range : indexed;\n        return _r.indexed(_indices);\n    }\n\n    ///\n    void popFront()\n    {\n        void next(int n)\n        {\n            import std.algorithm.mutation : swap;\n\n            if (n > _indices.length)\n            {\n                _empty = true;\n                return;\n            }\n\n            if (n % 2 == 1)\n                swap(_indices[0], _indices[n-1]);\n            else\n                swap(_indices[_state[n-2]], _indices[n-1]);\n\n            if (++_state[n-2] == n)\n            {\n                _state[n-2] = 0;\n                next(n+1);\n            }\n        }\n\n        next(2);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota;\n    assert(equal!equal(iota(3).permutations,\n        [[0, 1, 2],\n         [1, 0, 2],\n         [2, 0, 1],\n         [0, 2, 1],\n         [1, 2, 0],\n         [2, 1, 0]]));\n}\n"
  },
  {
    "path": "libphobos/src/std/algorithm/mutation.d",
    "content": "// Written in the D programming language.\n/**\nThis is a submodule of $(MREF std, algorithm).\nIt contains generic mutation algorithms.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE Cheat Sheet,\n$(TR $(TH Function Name) $(TH Description))\n$(T2 bringToFront,\n        If `a = [1, 2, 3]` and `b = [4, 5, 6, 7]`,\n        `bringToFront(a, b)` leaves `a = [4, 5, 6]` and\n        `b = [7, 1, 2, 3]`.)\n$(T2 copy,\n        Copies a range to another. If\n        `a = [1, 2, 3]` and `b = new int[5]`, then `copy(a, b)`\n        leaves `b = [1, 2, 3, 0, 0]` and returns `b[3 .. $]`.)\n$(T2 fill,\n        Fills a range with a pattern,\n        e.g., if `a = new int[3]`, then `fill(a, 4)`\n        leaves `a = [4, 4, 4]` and `fill(a, [3, 4])` leaves\n        `a = [3, 4, 3]`.)\n$(T2 initializeAll,\n        If `a = [1.2, 3.4]`, then `initializeAll(a)` leaves\n        `a = [double.init, double.init]`.)\n$(T2 move,\n        `move(a, b)` moves `a` into `b`. `move(a)` reads `a`\n        destructively when necessary.)\n$(T2 moveEmplace,\n        Similar to `move` but assumes `target` is uninitialized.)\n$(T2 moveAll,\n        Moves all elements from one range to another.)\n$(T2 moveEmplaceAll,\n        Similar to `moveAll` but assumes all elements in `target` are uninitialized.)\n$(T2 moveSome,\n        Moves as many elements as possible from one range to another.)\n$(T2 moveEmplaceSome,\n        Similar to `moveSome` but assumes all elements in `target` are uninitialized.)\n$(T2 remove,\n        Removes elements from a range in-place, and returns the shortened\n        range.)\n$(T2 reverse,\n        If `a = [1, 2, 3]`, `reverse(a)` changes it to `[3, 2, 1]`.)\n$(T2 strip,\n        Strips all leading and trailing elements equal to a value, or that\n        satisfy a predicate.\n        If `a = [1, 1, 0, 1, 1]`, then `strip(a, 1)` and\n        `strip!(e => e == 1)(a)` returns `[0]`.)\n$(T2 stripLeft,\n        Strips all leading elements equal to a value, or that satisfy a\n        predicate.  If `a = [1, 1, 0, 1, 1]`, then `stripLeft(a, 1)` and\n        `stripLeft!(e => e == 1)(a)` returns `[0, 1, 1]`.)\n$(T2 stripRight,\n        Strips all trailing elements equal to a value, or that satisfy a\n        predicate.\n        If `a = [1, 1, 0, 1, 1]`, then `stripRight(a, 1)` and\n        `stripRight!(e => e == 1)(a)` returns `[1, 1, 0]`.)\n$(T2 swap,\n        Swaps two values.)\n$(T2 swapAt,\n        Swaps two values by indices.)\n$(T2 swapRanges,\n        Swaps all elements of two ranges.)\n$(T2 uninitializedFill,\n        Fills a range (assumed uninitialized) with a value.)\n)\n\nCopyright: Andrei Alexandrescu 2008-.\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n\nSource: $(PHOBOSSRC std/algorithm/mutation.d)\n\nMacros:\nT2=$(TR $(TDNW $(LREF $1)) $(TD $+))\n */\nmodule std.algorithm.mutation;\n\nimport std.range.primitives;\nimport std.traits : isArray, isAssignable, isBlitAssignable, isNarrowString,\n       Unqual, isSomeChar, isMutable;\nimport std.meta : allSatisfy;\n// FIXME\nimport std.typecons; // : tuple, Tuple;\n\n// bringToFront\n/**\n`bringToFront` takes two ranges `front` and `back`, which may\nbe of different types. Considering the concatenation of `front` and\n`back` one unified range, `bringToFront` rotates that unified\nrange such that all elements in `back` are brought to the beginning\nof the unified range. The relative ordering of elements in `front`\nand `back`, respectively, remains unchanged.\n\nThe `bringToFront` function treats strings at the code unit\nlevel and it is not concerned with Unicode character integrity.\n`bringToFront` is designed as a function for moving elements\nin ranges, not as a string function.\n\nPerforms $(BIGOH max(front.length, back.length)) evaluations of $(D\nswap).\n\nThe `bringToFront` function can rotate elements in one buffer left or right, swap\nbuffers of equal length, and even move elements across disjoint\nbuffers of different types and different lengths.\n\nPreconditions:\n\nEither `front` and `back` are disjoint, or `back` is\nreachable from `front` and `front` is not reachable from $(D\nback).\n\nParams:\n    front = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    back = a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n\nReturns:\n    The number of elements brought to the front, i.e., the length of `back`.\n\nSee_Also:\n    $(LINK2 http://en.cppreference.com/w/cpp/algorithm/rotate, STL's `rotate`)\n*/\nsize_t bringToFront(InputRange, ForwardRange)(InputRange front, ForwardRange back)\nif (isInputRange!InputRange && isForwardRange!ForwardRange)\n{\n    import std.string : representation;\n\n    static if (isNarrowString!InputRange)\n    {\n        auto frontW = representation(front);\n    }\n    else\n    {\n        alias frontW = front;\n    }\n    static if (isNarrowString!ForwardRange)\n    {\n        auto backW = representation(back);\n    }\n    else\n    {\n        alias backW = back;\n    }\n\n    return bringToFrontImpl(frontW, backW);\n}\n\n/**\nThe simplest use of `bringToFront` is for rotating elements in a\nbuffer. For example:\n*/\n@safe unittest\n{\n    auto arr = [4, 5, 6, 7, 1, 2, 3];\n    auto p = bringToFront(arr[0 .. 4], arr[4 .. $]);\n    assert(p == arr.length - 4);\n    assert(arr == [ 1, 2, 3, 4, 5, 6, 7 ]);\n}\n\n/**\nThe `front` range may actually \"step over\" the `back`\nrange. This is very useful with forward ranges that cannot compute\ncomfortably right-bounded subranges like `arr[0 .. 4]` above. In\nthe example below, `r2` is a right subrange of `r1`.\n*/\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container : SList;\n    import std.range.primitives : popFrontN;\n\n    auto list = SList!(int)(4, 5, 6, 7, 1, 2, 3);\n    auto r1 = list[];\n    auto r2 = list[]; popFrontN(r2, 4);\n    assert(equal(r2, [ 1, 2, 3 ]));\n    bringToFront(r1, r2);\n    assert(equal(list[], [ 1, 2, 3, 4, 5, 6, 7 ]));\n}\n\n/**\nElements can be swapped across ranges of different types:\n*/\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container : SList;\n\n    auto list = SList!(int)(4, 5, 6, 7);\n    auto vec = [ 1, 2, 3 ];\n    bringToFront(list[], vec);\n    assert(equal(list[], [ 1, 2, 3, 4 ]));\n    assert(equal(vec, [ 5, 6, 7 ]));\n}\n\n/**\nUnicode integrity is not preserved:\n*/\n@safe unittest\n{\n    import std.string : representation;\n    auto ar = representation(\"a\".dup);\n    auto br = representation(\"ç\".dup);\n\n    bringToFront(ar, br);\n\n    auto a = cast(char[]) ar;\n    auto b = cast(char[]) br;\n\n    // Illegal UTF-8\n    assert(a == \"\\303\");\n    // Illegal UTF-8\n    assert(b == \"\\247a\");\n}\n\nprivate size_t bringToFrontImpl(InputRange, ForwardRange)(InputRange front, ForwardRange back)\nif (isInputRange!InputRange && isForwardRange!ForwardRange)\n{\n    import std.array : sameHead;\n    import std.range : take, Take;\n    enum bool sameHeadExists = is(typeof(front.sameHead(back)));\n    size_t result;\n\n    for (bool semidone; !front.empty && !back.empty; )\n    {\n        static if (sameHeadExists)\n        {\n            if (front.sameHead(back)) break; // shortcut\n        }\n        // Swap elements until front and/or back ends.\n        auto back0 = back.save;\n        size_t nswaps;\n        do\n        {\n            static if (sameHeadExists)\n            {\n                // Detect the stepping-over condition.\n                if (front.sameHead(back0)) back0 = back.save;\n            }\n            swapFront(front, back);\n            ++nswaps;\n            front.popFront();\n            back.popFront();\n        }\n        while (!front.empty && !back.empty);\n\n        if (!semidone) result += nswaps;\n\n        // Now deal with the remaining elements.\n        if (back.empty)\n        {\n            if (front.empty) break;\n            // Right side was shorter, which means that we've brought\n            // all the back elements to the front.\n            semidone = true;\n            // Next pass: bringToFront(front, back0) to adjust the rest.\n            back = back0;\n        }\n        else\n        {\n            assert(front.empty, \"Expected front to be empty\");\n            // Left side was shorter. Let's step into the back.\n            static if (is(InputRange == Take!ForwardRange))\n            {\n                front = take(back0, nswaps);\n            }\n            else\n            {\n                immutable subresult = bringToFront(take(back0, nswaps),\n                                                   back);\n                if (!semidone) result += subresult;\n                break; // done\n            }\n        }\n    }\n    return result;\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : text;\n    import std.random : Random = Xorshift, uniform;\n\n    // a more elaborate test\n    {\n        auto rnd = Random(123_456_789);\n        int[] a = new int[uniform(100, 200, rnd)];\n        int[] b = new int[uniform(100, 200, rnd)];\n        foreach (ref e; a) e = uniform(-100, 100, rnd);\n        foreach (ref e; b) e = uniform(-100, 100, rnd);\n        int[] c = a ~ b;\n        // writeln(\"a= \", a);\n        // writeln(\"b= \", b);\n        auto n = bringToFront(c[0 .. a.length], c[a.length .. $]);\n        //writeln(\"c= \", c);\n        assert(n == b.length);\n        assert(c == b ~ a, text(c, \"\\n\", a, \"\\n\", b));\n    }\n    // different types, moveFront, no sameHead\n    {\n        static struct R(T)\n        {\n            T[] data;\n            size_t i;\n            @property\n            {\n                R save() { return this; }\n                bool empty() { return i >= data.length; }\n                T front() { return data[i]; }\n                T front(real e) { return data[i] = cast(T) e; }\n            }\n            void popFront() { ++i; }\n        }\n        auto a = R!int([1, 2, 3, 4, 5]);\n        auto b = R!real([6, 7, 8, 9]);\n        auto n = bringToFront(a, b);\n        assert(n == 4);\n        assert(a.data == [6, 7, 8, 9, 1]);\n        assert(b.data == [2, 3, 4, 5]);\n    }\n    // front steps over back\n    {\n        int[] arr, r1, r2;\n\n        // back is shorter\n        arr = [4, 5, 6, 7, 1, 2, 3];\n        r1 = arr;\n        r2 = arr[4 .. $];\n        bringToFront(r1, r2) == 3 || assert(0);\n        assert(equal(arr, [1, 2, 3, 4, 5, 6, 7]));\n\n        // front is shorter\n        arr = [5, 6, 7, 1, 2, 3, 4];\n        r1 = arr;\n        r2 = arr[3 .. $];\n        bringToFront(r1, r2) == 4 || assert(0);\n        assert(equal(arr, [1, 2, 3, 4, 5, 6, 7]));\n    }\n\n    // Bugzilla 16959\n    auto arr = ['4', '5', '6', '7', '1', '2', '3'];\n    auto p = bringToFront(arr[0 .. 4], arr[4 .. $]);\n\n    assert(p == arr.length - 4);\n    assert(arr == ['1', '2', '3', '4', '5', '6', '7']);\n}\n\n// Tests if types are arrays and support slice assign.\nprivate enum bool areCopyCompatibleArrays(T1, T2) =\n    isArray!T1 && isArray!T2 && is(typeof(T2.init[] = T1.init[]));\n\n// copy\n/**\nCopies the content of `source` into `target` and returns the\nremaining (unfilled) part of `target`.\n\nPreconditions: `target` shall have enough room to accommodate\nthe entirety of `source`.\n\nParams:\n    source = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    target = an output range\n\nReturns:\n    The unfilled part of target\n */\nTargetRange copy(SourceRange, TargetRange)(SourceRange source, TargetRange target)\nif (areCopyCompatibleArrays!(SourceRange, TargetRange))\n{\n    const tlen = target.length;\n    const slen = source.length;\n    assert(tlen >= slen,\n            \"Cannot copy a source range into a smaller target range.\");\n\n    immutable overlaps = __ctfe || () @trusted {\n        return source.ptr < target.ptr + tlen &&\n               target.ptr < source.ptr + slen; }();\n\n    if (overlaps)\n    {\n        foreach (idx; 0 .. slen)\n            target[idx] = source[idx];\n        return target[slen .. tlen];\n    }\n    else\n    {\n        // Array specialization.  This uses optimized memory copying\n        // routines under the hood and is about 10-20x faster than the\n        // generic implementation.\n        target[0 .. slen] = source[];\n        return target[slen .. $];\n    }\n}\n\n/// ditto\nTargetRange copy(SourceRange, TargetRange)(SourceRange source, TargetRange target)\nif (!areCopyCompatibleArrays!(SourceRange, TargetRange) &&\n    isInputRange!SourceRange &&\n    isOutputRange!(TargetRange, ElementType!SourceRange))\n{\n    // Specialize for 2 random access ranges.\n    // Typically 2 random access ranges are faster iterated by common\n    // index than by x.popFront(), y.popFront() pair\n    static if (isRandomAccessRange!SourceRange &&\n               hasLength!SourceRange &&\n               hasSlicing!TargetRange &&\n               isRandomAccessRange!TargetRange &&\n               hasLength!TargetRange)\n    {\n        auto len = source.length;\n        foreach (idx; 0 .. len)\n            target[idx] = source[idx];\n        return target[len .. target.length];\n    }\n    else\n    {\n        foreach (element; source)\n            put(target, element);\n        return target;\n    }\n}\n\n///\n@safe unittest\n{\n    int[] a = [ 1, 5 ];\n    int[] b = [ 9, 8 ];\n    int[] buf = new int[](a.length + b.length + 10);\n    auto rem = a.copy(buf);    // copy a into buf\n    rem = b.copy(rem);         // copy b into remainder of buf\n    assert(buf[0 .. a.length + b.length] == [1, 5, 9, 8]);\n    assert(rem.length == 10);   // unused slots in buf\n}\n\n/**\nAs long as the target range elements support assignment from source\nrange elements, different types of ranges are accepted:\n*/\n@safe unittest\n{\n    float[] src = [ 1.0f, 5 ];\n    double[] dest = new double[src.length];\n    src.copy(dest);\n}\n\n/**\nTo _copy at most `n` elements from a range, you may want to use\n$(REF take, std,range):\n*/\n@safe unittest\n{\n    import std.range;\n    int[] src = [ 1, 5, 8, 9, 10 ];\n    auto dest = new int[](3);\n    src.take(dest.length).copy(dest);\n    assert(dest == [ 1, 5, 8 ]);\n}\n\n/**\nTo _copy just those elements from a range that satisfy a predicate,\nuse $(LREF filter):\n*/\n@safe unittest\n{\n    import std.algorithm.iteration : filter;\n    int[] src = [ 1, 5, 8, 9, 10, 1, 2, 0 ];\n    auto dest = new int[src.length];\n    auto rem = src\n        .filter!(a => (a & 1) == 1)\n        .copy(dest);\n    assert(dest[0 .. $ - rem.length] == [ 1, 5, 9, 1 ]);\n}\n\n/**\n$(REF retro, std,range) can be used to achieve behavior similar to\n$(LINK2 http://en.cppreference.com/w/cpp/algorithm/copy_backward, STL's `copy_backward`'):\n*/\n@safe unittest\n{\n    import std.algorithm, std.range;\n    int[] src = [1, 2, 4];\n    int[] dest = [0, 0, 0, 0, 0];\n    src.retro.copy(dest.retro);\n    assert(dest == [0, 0, 1, 2, 4]);\n}\n\n// Test CTFE copy.\n@safe unittest\n{\n    enum c = copy([1,2,3], [4,5,6,7]);\n    assert(c == [7]);\n}\n\n\n@safe unittest\n{\n    import std.algorithm.iteration : filter;\n\n    {\n        int[] a = [ 1, 5 ];\n        int[] b = [ 9, 8 ];\n        auto e = copy(filter!(\"a > 1\")(a), b);\n        assert(b[0] == 5 && e.length == 1);\n    }\n\n    {\n        int[] a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n        copy(a[5 .. 10], a[4 .. 9]);\n        assert(a[4 .. 9] == [6, 7, 8, 9, 10]);\n    }\n\n    {   // Test for bug 7898\n        enum v =\n        {\n            import std.algorithm;\n            int[] arr1 = [10, 20, 30, 40, 50];\n            int[] arr2 = arr1.dup;\n            copy(arr1, arr2);\n            return 35;\n        }();\n        assert(v == 35);\n    }\n}\n\n@safe unittest\n{\n    // Issue 13650\n    import std.meta : AliasSeq;\n    static foreach (Char; AliasSeq!(char, wchar, dchar))\n    {{\n        Char[3] a1 = \"123\";\n        Char[6] a2 = \"456789\";\n        assert(copy(a1[], a2[]) is a2[3..$]);\n        assert(a1[] == \"123\");\n        assert(a2[] == \"123789\");\n    }}\n}\n\n@safe unittest // issue 18804\n{\n    static struct NullSink\n    {\n        void put(E)(E) {}\n    }\n    int line = 0;\n    struct R\n    {\n        int front;\n        @property bool empty() { return line == 1; }\n        void popFront() { line = 1; }\n    }\n    R r;\n    copy(r, NullSink());\n    assert(line == 1);\n}\n\n/**\nAssigns `value` to each element of input range `range`.\n\nAlternatively, instead of using a single `value` to fill the `range`,\na `filter` $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\ncan be provided. The length of `filler` and `range` do not need to match, but\n`filler` must not be empty.\n\nParams:\n        range = An\n                $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n                that exposes references to its elements and has assignable\n                elements\n        value = Assigned to each element of range\n        filler = A\n                $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n                representing the _fill pattern.\n\nThrows: If `filler` is empty.\n\nSee_Also:\n        $(LREF uninitializedFill)\n        $(LREF initializeAll)\n */\nvoid fill(Range, Value)(auto ref Range range, auto ref Value value)\nif ((isInputRange!Range && is(typeof(range.front = value)) ||\n    isSomeChar!Value && is(typeof(range[] = value))))\n{\n    alias T = ElementType!Range;\n\n    static if (is(typeof(range[] = value)))\n    {\n        range[] = value;\n    }\n    else static if (is(typeof(range[] = T(value))))\n    {\n        range[] = T(value);\n    }\n    else\n    {\n        for ( ; !range.empty; range.popFront() )\n        {\n            range.front = value;\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    int[] a = [ 1, 2, 3, 4 ];\n    fill(a, 5);\n    assert(a == [ 5, 5, 5, 5 ]);\n}\n\n// issue 16342, test fallback on mutable narrow strings\n@safe unittest\n{\n    char[] chars = ['a', 'b'];\n    fill(chars, 'c');\n    assert(chars == \"cc\");\n\n    char[2] chars2 = ['a', 'b'];\n    fill(chars2, 'c');\n    assert(chars2 == \"cc\");\n\n    wchar[] wchars = ['a', 'b'];\n    fill(wchars, wchar('c'));\n    assert(wchars == \"cc\"w);\n\n    dchar[] dchars = ['a', 'b'];\n    fill(dchars, dchar('c'));\n    assert(dchars == \"cc\"d);\n}\n\n@nogc @safe unittest\n{\n    const(char)[] chars;\n    assert(chars.length == 0);\n    static assert(!__traits(compiles, fill(chars, 'c')));\n    wstring wchars;\n    assert(wchars.length == 0);\n    static assert(!__traits(compiles, fill(wchars, wchar('c'))));\n}\n\n@nogc @safe unittest\n{\n    char[] chars;\n    fill(chars, 'c');\n    assert(chars == \"\"c);\n}\n\n@safe unittest\n{\n    shared(char)[] chrs = ['r'];\n    fill(chrs, 'c');\n    assert(chrs == [shared(char)('c')]);\n}\n\n@nogc @safe unittest\n{\n    struct Str(size_t len)\n    {\n        private char[len] _data;\n        void opIndexAssign(char value) @safe @nogc\n        {_data[] = value;}\n    }\n    Str!2 str;\n    str.fill(':');\n    assert(str._data == \"::\");\n}\n\n@safe unittest\n{\n    char[] chars = ['a','b','c','d'];\n    chars[1 .. 3].fill(':');\n    assert(chars == \"a::d\");\n}\n// end issue 16342\n\n@safe unittest\n{\n    import std.conv : text;\n    import std.internal.test.dummyrange;\n\n    int[] a = [ 1, 2, 3 ];\n    fill(a, 6);\n    assert(a == [ 6, 6, 6 ], text(a));\n\n    void fun0()\n    {\n        foreach (i; 0 .. 1000)\n        {\n            foreach (ref e; a) e = 6;\n        }\n    }\n    void fun1() { foreach (i; 0 .. 1000) fill(a, 6); }\n\n    // fill should accept InputRange\n    alias InputRange = DummyRange!(ReturnBy.Reference, Length.No, RangeType.Input);\n    enum filler = uint.max;\n    InputRange range;\n    fill(range, filler);\n    foreach (value; range.arr)\n        assert(value == filler);\n}\n\n@safe unittest\n{\n    //ER8638_1 IS_NOT self assignable\n    static struct ER8638_1\n    {\n        void opAssign(int){}\n    }\n\n    //ER8638_1 IS self assignable\n    static struct ER8638_2\n    {\n        void opAssign(ER8638_2){}\n        void opAssign(int){}\n    }\n\n    auto er8638_1 = new ER8638_1[](10);\n    auto er8638_2 = new ER8638_2[](10);\n    er8638_1.fill(5); //generic case\n    er8638_2.fill(5); //opSlice(T.init) case\n}\n\n@safe unittest\n{\n    {\n        int[] a = [1, 2, 3];\n        immutable(int) b = 0;\n        a.fill(b);\n        assert(a == [0, 0, 0]);\n    }\n    {\n        double[] a = [1, 2, 3];\n        immutable(int) b = 0;\n        a.fill(b);\n        assert(a == [0, 0, 0]);\n    }\n}\n\n/// ditto\nvoid fill(InputRange, ForwardRange)(InputRange range, ForwardRange filler)\nif (isInputRange!InputRange\n    && (isForwardRange!ForwardRange\n    || (isInputRange!ForwardRange && isInfinite!ForwardRange))\n    && is(typeof(InputRange.init.front = ForwardRange.init.front)))\n{\n    static if (isInfinite!ForwardRange)\n    {\n        //ForwardRange is infinite, no need for bounds checking or saving\n        static if (hasSlicing!ForwardRange && hasLength!InputRange\n            && is(typeof(filler[0 .. range.length])))\n        {\n            copy(filler[0 .. range.length], range);\n        }\n        else\n        {\n            //manual feed\n            for ( ; !range.empty; range.popFront(), filler.popFront())\n            {\n                range.front = filler.front;\n            }\n        }\n    }\n    else\n    {\n        import std.exception : enforce;\n\n        enforce(!filler.empty, \"Cannot fill range with an empty filler\");\n\n        static if (hasLength!InputRange && hasLength!ForwardRange\n            && is(typeof(range.length > filler.length)))\n        {\n            //Case we have access to length\n            immutable len = filler.length;\n            //Start by bulk copies\n            while (range.length > len)\n            {\n                range = copy(filler.save, range);\n            }\n\n            //and finally fill the partial range. No need to save here.\n            static if (hasSlicing!ForwardRange && is(typeof(filler[0 .. range.length])))\n            {\n                //use a quick copy\n                auto len2 = range.length;\n                range = copy(filler[0 .. len2], range);\n            }\n            else\n            {\n                //iterate. No need to check filler, it's length is longer than range's\n                for (; !range.empty; range.popFront(), filler.popFront())\n                {\n                    range.front = filler.front;\n                }\n            }\n        }\n        else\n        {\n            //Most basic case.\n            auto bck = filler.save;\n            for (; !range.empty; range.popFront(), filler.popFront())\n            {\n                if (filler.empty) filler = bck.save;\n                range.front = filler.front;\n            }\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    int[] a = [ 1, 2, 3, 4, 5 ];\n    int[] b = [ 8, 9 ];\n    fill(a, b);\n    assert(a == [ 8, 9, 8, 9, 8 ]);\n}\n\n@safe unittest\n{\n    import std.exception : assertThrown;\n    import std.internal.test.dummyrange;\n\n    int[] a = [ 1, 2, 3, 4, 5 ];\n    int[] b = [1, 2];\n    fill(a, b);\n    assert(a == [ 1, 2, 1, 2, 1 ]);\n\n    // fill should accept InputRange\n    alias InputRange = DummyRange!(ReturnBy.Reference, Length.No, RangeType.Input);\n    InputRange range;\n    fill(range,[1,2]);\n    foreach (i,value;range.arr)\n    assert(value == (i%2 == 0?1:2));\n\n    //test with a input being a \"reference forward\" range\n    fill(a, new ReferenceForwardRange!int([8, 9]));\n    assert(a == [8, 9, 8, 9, 8]);\n\n    //test with a input being an \"infinite input\" range\n    fill(a, new ReferenceInfiniteInputRange!int());\n    assert(a == [0, 1, 2, 3, 4]);\n\n    //empty filler test\n    assertThrown(fill(a, a[$..$]));\n}\n\n/**\nInitializes all elements of `range` with their `.init` value.\nAssumes that the elements of the range are uninitialized.\n\nParams:\n        range = An\n                $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n                that exposes references to its elements and has assignable\n                elements\n\nSee_Also:\n        $(LREF fill)\n        $(LREF uninitializeFill)\n */\nvoid initializeAll(Range)(Range range)\nif (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range)\n{\n    import core.stdc.string : memset, memcpy;\n    import std.traits : hasElaborateAssign, isDynamicArray;\n\n    alias T = ElementType!Range;\n    static if (hasElaborateAssign!T)\n    {\n        import std.algorithm.internal : addressOf;\n        //Elaborate opAssign. Must go the memcpy road.\n        //We avoid calling emplace here, because our goal is to initialize to\n        //the static state of T.init,\n        //So we want to avoid any un-necassarilly CC'ing of T.init\n        static if (!__traits(isZeroInit, T))\n        {\n            auto p = typeid(T).initializer();\n            for ( ; !range.empty ; range.popFront() )\n            {\n                static if (__traits(isStaticArray, T))\n                {\n                    // static array initializer only contains initialization\n                    // for one element of the static array.\n                    auto elemp = cast(void *) addressOf(range.front);\n                    auto endp = elemp + T.sizeof;\n                    while (elemp < endp)\n                    {\n                        memcpy(elemp, p.ptr, p.length);\n                        elemp += p.length;\n                    }\n                }\n                else\n                {\n                    memcpy(addressOf(range.front), p.ptr, T.sizeof);\n                }\n            }\n        }\n        else\n            static if (isDynamicArray!Range)\n                memset(range.ptr, 0, range.length * T.sizeof);\n            else\n                for ( ; !range.empty ; range.popFront() )\n                    memset(addressOf(range.front), 0, T.sizeof);\n    }\n    else\n        fill(range, T.init);\n}\n\n/// ditto\nvoid initializeAll(Range)(Range range)\nif (is(Range == char[]) || is(Range == wchar[]))\n{\n    alias T = ElementEncodingType!Range;\n    range[] = T.init;\n}\n\n///\n@system unittest\n{\n    import core.stdc.stdlib : malloc, free;\n\n    struct S\n    {\n        int a = 10;\n    }\n\n    auto s = (cast(S*) malloc(5 * S.sizeof))[0 .. 5];\n    initializeAll(s);\n    assert(s == [S(10), S(10), S(10), S(10), S(10)]);\n\n    scope(exit) free(s.ptr);\n}\n\n@system unittest\n{\n    import std.algorithm.iteration : filter;\n    import std.meta : AliasSeq;\n    import std.traits : hasElaborateAssign;\n\n    //Test strings:\n    //Must work on narrow strings.\n    //Must reject const\n    char[3] a = void;\n    a[].initializeAll();\n    assert(a[] == [char.init, char.init, char.init]);\n    string s;\n    assert(!__traits(compiles, s.initializeAll()));\n    assert(!__traits(compiles, s.initializeAll()));\n    assert(s.empty);\n\n    //Note: Cannot call uninitializedFill on narrow strings\n\n    enum e {e1, e2}\n    e[3] b1 = void;\n    b1[].initializeAll();\n    assert(b1[] == [e.e1, e.e1, e.e1]);\n    e[3] b2 = void;\n    b2[].uninitializedFill(e.e2);\n    assert(b2[] == [e.e2, e.e2, e.e2]);\n\n    static struct S1\n    {\n        int i;\n    }\n    static struct S2\n    {\n        int i = 1;\n    }\n    static struct S3\n    {\n        int i;\n        this(this){}\n    }\n    static struct S4\n    {\n        int i = 1;\n        this(this){}\n    }\n    static assert(!hasElaborateAssign!S1);\n    static assert(!hasElaborateAssign!S2);\n    static assert( hasElaborateAssign!S3);\n    static assert( hasElaborateAssign!S4);\n    assert(!typeid(S1).initializer().ptr);\n    assert( typeid(S2).initializer().ptr);\n    assert(!typeid(S3).initializer().ptr);\n    assert( typeid(S4).initializer().ptr);\n\n    static foreach (S; AliasSeq!(S1, S2, S3, S4))\n    {\n        //initializeAll\n        {\n            //Array\n            S[3] ss1 = void;\n            ss1[].initializeAll();\n            assert(ss1[] == [S.init, S.init, S.init]);\n\n            //Not array\n            S[3] ss2 = void;\n            auto sf = ss2[].filter!\"true\"();\n\n            sf.initializeAll();\n            assert(ss2[] == [S.init, S.init, S.init]);\n        }\n        //uninitializedFill\n        {\n            //Array\n            S[3] ss1 = void;\n            ss1[].uninitializedFill(S(2));\n            assert(ss1[] == [S(2), S(2), S(2)]);\n\n            //Not array\n            S[3] ss2 = void;\n            auto sf = ss2[].filter!\"true\"();\n            sf.uninitializedFill(S(2));\n            assert(ss2[] == [S(2), S(2), S(2)]);\n        }\n    }\n}\n\n// test that initializeAll works for arrays of static arrays of structs with\n// elaborate assigns.\n@system unittest\n{\n    struct Int {\n        ~this() {}\n        int x = 3;\n    }\n    Int[2] xs = [Int(1), Int(2)];\n    struct R {\n        bool done;\n        bool empty() { return done; }\n        ref Int[2] front() { return xs; }\n        void popFront() { done = true; }\n    }\n    initializeAll(R());\n    assert(xs[0].x == 3);\n    assert(xs[1].x == 3);\n}\n\n// move\n/**\nMoves `source` into `target`, via a destructive copy when necessary.\n\nIf `T` is a struct with a destructor or postblit defined, source is reset\nto its `.init` value after it is moved into target, otherwise it is\nleft unchanged.\n\nPreconditions:\nIf source has internal pointers that point to itself, it cannot be moved, and\nwill trigger an assertion failure.\n\nParams:\n    source = Data to copy.\n    target = Where to copy into. The destructor, if any, is invoked before the\n        copy is performed.\n*/\nvoid move(T)(ref T source, ref T target)\n{\n    // test @safe destructible\n    static if (__traits(compiles, (T t) @safe {}))\n        trustedMoveImpl(source, target);\n    else\n        moveImpl(source, target);\n}\n\n/// For non-struct types, `move` just performs `target = source`:\n@safe unittest\n{\n    Object obj1 = new Object;\n    Object obj2 = obj1;\n    Object obj3;\n\n    move(obj2, obj3);\n    assert(obj3 is obj1);\n    // obj2 unchanged\n    assert(obj2 is obj1);\n}\n\n///\npure nothrow @safe @nogc unittest\n{\n    // Structs without destructors are simply copied\n    struct S1\n    {\n        int a = 1;\n        int b = 2;\n    }\n    S1 s11 = { 10, 11 };\n    S1 s12;\n\n    move(s11, s12);\n\n    assert(s12 == S1(10, 11));\n    assert(s11 == s12);\n\n    // But structs with destructors or postblits are reset to their .init value\n    // after copying to the target.\n    struct S2\n    {\n        int a = 1;\n        int b = 2;\n\n        ~this() pure nothrow @safe @nogc { }\n    }\n    S2 s21 = { 3, 4 };\n    S2 s22;\n\n    move(s21, s22);\n\n    assert(s21 == S2(1, 2));\n    assert(s22 == S2(3, 4));\n}\n\n@safe unittest\n{\n    import std.exception : assertCTFEable;\n    import std.traits;\n\n    assertCTFEable!((){\n        Object obj1 = new Object;\n        Object obj2 = obj1;\n        Object obj3;\n        move(obj2, obj3);\n        assert(obj3 is obj1);\n\n        static struct S1 { int a = 1, b = 2; }\n        S1 s11 = { 10, 11 };\n        S1 s12;\n        move(s11, s12);\n        assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);\n\n        static struct S2 { int a = 1; int * b; }\n        S2 s21 = { 10, null };\n        s21.b = new int;\n        S2 s22;\n        move(s21, s22);\n        assert(s21 == s22);\n    });\n    // Issue 5661 test(1)\n    static struct S3\n    {\n        static struct X { int n = 0; ~this(){n = 0;} }\n        X x;\n    }\n    static assert(hasElaborateDestructor!S3);\n    S3 s31, s32;\n    s31.x.n = 1;\n    move(s31, s32);\n    assert(s31.x.n == 0);\n    assert(s32.x.n == 1);\n\n    // Issue 5661 test(2)\n    static struct S4\n    {\n        static struct X { int n = 0; this(this){n = 0;} }\n        X x;\n    }\n    static assert(hasElaborateCopyConstructor!S4);\n    S4 s41, s42;\n    s41.x.n = 1;\n    move(s41, s42);\n    assert(s41.x.n == 0);\n    assert(s42.x.n == 1);\n\n    // Issue 13990 test\n    class S5;\n\n    S5 s51;\n    S5 s52 = s51;\n    S5 s53;\n    move(s52, s53);\n    assert(s53 is s51);\n}\n\n/// Ditto\nT move(T)(return scope ref T source)\n{\n    // test @safe destructible\n    static if (__traits(compiles, (T t) @safe {}))\n        return trustedMoveImpl(source);\n    else\n        return moveImpl(source);\n}\n\n/// Non-copyable structs can still be moved:\npure nothrow @safe @nogc unittest\n{\n    struct S\n    {\n        int a = 1;\n        @disable this(this);\n        ~this() pure nothrow @safe @nogc {}\n    }\n    S s1;\n    s1.a = 2;\n    S s2 = move(s1);\n    assert(s1.a == 1);\n    assert(s2.a == 2);\n}\n\nprivate void trustedMoveImpl(T)(ref T source, ref T target) @trusted\n{\n    moveImpl(source, target);\n}\n\nprivate void moveImpl(T)(ref T source, ref T target)\n{\n    import std.traits : hasElaborateDestructor;\n\n    static if (is(T == struct))\n    {\n        if (&source == &target) return;\n        // Destroy target before overwriting it\n        static if (hasElaborateDestructor!T) target.__xdtor();\n    }\n    // move and emplace source into target\n    moveEmplace(source, target);\n}\n\nprivate T trustedMoveImpl(T)(ref T source) @trusted\n{\n    return moveImpl(source);\n}\n\nprivate T moveImpl(T)(ref T source)\n{\n    T result = void;\n    moveEmplace(source, result);\n    return result;\n}\n\n@safe unittest\n{\n    import std.exception : assertCTFEable;\n    import std.traits;\n\n    assertCTFEable!((){\n        Object obj1 = new Object;\n        Object obj2 = obj1;\n        Object obj3 = move(obj2);\n        assert(obj3 is obj1);\n\n        static struct S1 { int a = 1, b = 2; }\n        S1 s11 = { 10, 11 };\n        S1 s12 = move(s11);\n        assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);\n\n        static struct S2 { int a = 1; int * b; }\n        S2 s21 = { 10, null };\n        s21.b = new int;\n        S2 s22 = move(s21);\n        assert(s21 == s22);\n    });\n\n    // Issue 5661 test(1)\n    static struct S3\n    {\n        static struct X { int n = 0; ~this(){n = 0;} }\n        X x;\n    }\n    static assert(hasElaborateDestructor!S3);\n    S3 s31;\n    s31.x.n = 1;\n    S3 s32 = move(s31);\n    assert(s31.x.n == 0);\n    assert(s32.x.n == 1);\n\n    // Issue 5661 test(2)\n    static struct S4\n    {\n        static struct X { int n = 0; this(this){n = 0;} }\n        X x;\n    }\n    static assert(hasElaborateCopyConstructor!S4);\n    S4 s41;\n    s41.x.n = 1;\n    S4 s42 = move(s41);\n    assert(s41.x.n == 0);\n    assert(s42.x.n == 1);\n\n    // Issue 13990 test\n    class S5;\n\n    S5 s51;\n    S5 s52 = s51;\n    S5 s53;\n    s53 = move(s52);\n    assert(s53 is s51);\n}\n\n@system unittest\n{\n    static struct S { int n = 0; ~this() @system { n = 0; } }\n    S a, b;\n    static assert(!__traits(compiles, () @safe { move(a, b); }));\n    static assert(!__traits(compiles, () @safe { move(a); }));\n    a.n = 1;\n    () @trusted { move(a, b); }();\n    assert(a.n == 0);\n    a.n = 1;\n    () @trusted { move(a); }();\n    assert(a.n == 0);\n}\n\n@safe unittest//Issue 6217\n{\n    import std.algorithm.iteration : map;\n    auto x = map!\"a\"([1,2,3]);\n    x = move(x);\n}\n\n@safe unittest// Issue 8055\n{\n    static struct S\n    {\n        int x;\n        ~this()\n        {\n            assert(x == 0);\n        }\n    }\n    S foo(S s)\n    {\n        return move(s);\n    }\n    S a;\n    a.x = 0;\n    auto b = foo(a);\n    assert(b.x == 0);\n}\n\n@system unittest// Issue 8057\n{\n    int n = 10;\n    struct S\n    {\n        int x;\n        ~this()\n        {\n            // Access to enclosing scope\n            assert(n == 10);\n        }\n    }\n    S foo(S s)\n    {\n        // Move nested struct\n        return move(s);\n    }\n    S a;\n    a.x = 1;\n    auto b = foo(a);\n    assert(b.x == 1);\n\n    // Regression 8171\n    static struct Array(T)\n    {\n        // nested struct has no member\n        struct Payload\n        {\n            ~this() {}\n        }\n    }\n    Array!int.Payload x = void;\n    move(x);\n    move(x, x);\n}\n\n/**\n * Similar to $(LREF move) but assumes `target` is uninitialized. This\n * is more efficient because `source` can be blitted over `target`\n * without destroying or initializing it first.\n *\n * Params:\n *   source = value to be moved into target\n *   target = uninitialized value to be filled by source\n */\nvoid moveEmplace(T)(ref T source, ref T target) @system\n{\n    import core.stdc.string : memcpy, memset;\n    import std.traits : hasAliasing, hasElaborateAssign,\n                        hasElaborateCopyConstructor, hasElaborateDestructor,\n                        isAssignable;\n\n    static if (!is(T == class) && hasAliasing!T) if (!__ctfe)\n    {\n        import std.exception : doesPointTo;\n        assert(!doesPointTo(source, source), \"Cannot move object with internal pointer.\");\n    }\n\n    static if (is(T == struct))\n    {\n        assert(&source !is &target, \"source and target must not be identical\");\n\n        static if (hasElaborateAssign!T || !isAssignable!T)\n            memcpy(&target, &source, T.sizeof);\n        else\n            target = source;\n\n        // If the source defines a destructor or a postblit hook, we must obliterate the\n        // object in order to avoid double freeing and undue aliasing\n        static if (hasElaborateDestructor!T || hasElaborateCopyConstructor!T)\n        {\n            // If T is nested struct, keep original context pointer\n            static if (__traits(isNested, T))\n                enum sz = T.sizeof - (void*).sizeof;\n            else\n                enum sz = T.sizeof;\n\n            static if (__traits(isZeroInit, T))\n                memset(&source, 0, sz);\n            else\n            {\n                auto init = typeid(T).initializer();\n                memcpy(&source, init.ptr, sz);\n            }\n        }\n    }\n    else\n    {\n        // Primitive data (including pointers and arrays) or class -\n        // assignment works great\n        target = source;\n    }\n}\n\n///\npure nothrow @nogc @system unittest\n{\n    static struct Foo\n    {\n    pure nothrow @nogc:\n        this(int* ptr) { _ptr = ptr; }\n        ~this() { if (_ptr) ++*_ptr; }\n        int* _ptr;\n    }\n\n    int val;\n    Foo foo1 = void; // uninitialized\n    auto foo2 = Foo(&val); // initialized\n    assert(foo2._ptr is &val);\n\n    // Using `move(foo2, foo1)` would have an undefined effect because it would destroy\n    // the uninitialized foo1.\n    // moveEmplace directly overwrites foo1 without destroying or initializing it first.\n    moveEmplace(foo2, foo1);\n    assert(foo1._ptr is &val);\n    assert(foo2._ptr is null);\n    assert(val == 0);\n}\n\n// moveAll\n/**\nCalls `move(a, b)` for each element `a` in `src` and the corresponding\nelement `b` in `tgt`, in increasing order.\n\nPreconditions:\n`walkLength(src) <= walkLength(tgt)`.\nThis precondition will be asserted. If you cannot ensure there is enough room in\n`tgt` to accommodate all of `src` use $(LREF moveSome) instead.\n\nParams:\n    src = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) with\n        movable elements.\n    tgt = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) with\n        elements that elements from `src` can be moved into.\n\nReturns: The leftover portion of `tgt` after all elements from `src` have\nbeen moved.\n */\nInputRange2 moveAll(InputRange1, InputRange2)(InputRange1 src, InputRange2 tgt)\nif (isInputRange!InputRange1 && isInputRange!InputRange2\n        && is(typeof(move(src.front, tgt.front))))\n{\n    return moveAllImpl!move(src, tgt);\n}\n\n///\npure nothrow @safe @nogc unittest\n{\n    int[3] a = [ 1, 2, 3 ];\n    int[5] b;\n    assert(moveAll(a[], b[]) is b[3 .. $]);\n    assert(a[] == b[0 .. 3]);\n    int[3] cmp = [ 1, 2, 3 ];\n    assert(a[] == cmp[]);\n}\n\n/**\n * Similar to $(LREF moveAll) but assumes all elements in `tgt` are\n * uninitialized. Uses $(LREF moveEmplace) to move elements from\n * `src` over elements from `tgt`.\n */\nInputRange2 moveEmplaceAll(InputRange1, InputRange2)(InputRange1 src, InputRange2 tgt) @system\nif (isInputRange!InputRange1 && isInputRange!InputRange2\n        && is(typeof(moveEmplace(src.front, tgt.front))))\n{\n    return moveAllImpl!moveEmplace(src, tgt);\n}\n\n///\npure nothrow @nogc @system unittest\n{\n    static struct Foo\n    {\n        ~this() pure nothrow @nogc { if (_ptr) ++*_ptr; }\n        int* _ptr;\n    }\n    int[3] refs = [0, 1, 2];\n    Foo[3] src = [Foo(&refs[0]), Foo(&refs[1]), Foo(&refs[2])];\n    Foo[5] dst = void;\n\n    auto tail = moveEmplaceAll(src[], dst[]); // move 3 value from src over dst\n    assert(tail.length == 2); // returns remaining uninitialized values\n    initializeAll(tail);\n\n    import std.algorithm.searching : all;\n    assert(src[].all!(e => e._ptr is null));\n    assert(dst[0 .. 3].all!(e => e._ptr !is null));\n}\n\n@system unittest\n{\n    struct InputRange\n    {\n        ref int front() { return data[0]; }\n        void popFront() { data.popFront; }\n        bool empty() { return data.empty; }\n        int[] data;\n    }\n    auto a = InputRange([ 1, 2, 3 ]);\n    auto b = InputRange(new int[5]);\n    moveAll(a, b);\n    assert(a.data == b.data[0 .. 3]);\n    assert(a.data == [ 1, 2, 3 ]);\n}\n\nprivate InputRange2 moveAllImpl(alias moveOp, InputRange1, InputRange2)(\n    ref InputRange1 src, ref InputRange2 tgt)\n{\n    import std.exception : enforce;\n\n    static if (isRandomAccessRange!InputRange1 && hasLength!InputRange1 && hasLength!InputRange2\n         && hasSlicing!InputRange2 && isRandomAccessRange!InputRange2)\n    {\n        auto toMove = src.length;\n        assert(toMove <= tgt.length, \"Source buffer needs to be smaller or equal to the target buffer.\");\n        foreach (idx; 0 .. toMove)\n            moveOp(src[idx], tgt[idx]);\n        return tgt[toMove .. tgt.length];\n    }\n    else\n    {\n        for (; !src.empty; src.popFront(), tgt.popFront())\n        {\n            assert(!tgt.empty, \"Source buffer needs to be smaller or equal to the target buffer.\");\n            moveOp(src.front, tgt.front);\n        }\n        return tgt;\n    }\n}\n\n// moveSome\n/**\nCalls `move(a, b)` for each element `a` in `src` and the corresponding\nelement `b` in `tgt`, in increasing order, stopping when either range has been\nexhausted.\n\nParams:\n    src = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) with\n        movable elements.\n    tgt = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) with\n        elements that elements from `src` can be moved into.\n\nReturns: The leftover portions of the two ranges after one or the other of the\nranges have been exhausted.\n */\nTuple!(InputRange1, InputRange2) moveSome(InputRange1, InputRange2)(InputRange1 src, InputRange2 tgt)\nif (isInputRange!InputRange1 && isInputRange!InputRange2\n        && is(typeof(move(src.front, tgt.front))))\n{\n    return moveSomeImpl!move(src, tgt);\n}\n\n///\npure nothrow @safe @nogc unittest\n{\n    int[5] a = [ 1, 2, 3, 4, 5 ];\n    int[3] b;\n    assert(moveSome(a[], b[])[0] is a[3 .. $]);\n    assert(a[0 .. 3] == b);\n    assert(a == [ 1, 2, 3, 4, 5 ]);\n}\n\n/**\n * Same as $(LREF moveSome) but assumes all elements in `tgt` are\n * uninitialized. Uses $(LREF moveEmplace) to move elements from\n * `src` over elements from `tgt`.\n */\nTuple!(InputRange1, InputRange2) moveEmplaceSome(InputRange1, InputRange2)(InputRange1 src, InputRange2 tgt) @system\nif (isInputRange!InputRange1 && isInputRange!InputRange2\n        && is(typeof(move(src.front, tgt.front))))\n{\n    return moveSomeImpl!moveEmplace(src, tgt);\n}\n\n///\npure nothrow @nogc @system unittest\n{\n    static struct Foo\n    {\n        ~this() pure nothrow @nogc { if (_ptr) ++*_ptr; }\n        int* _ptr;\n    }\n    int[4] refs = [0, 1, 2, 3];\n    Foo[4] src = [Foo(&refs[0]), Foo(&refs[1]), Foo(&refs[2]), Foo(&refs[3])];\n    Foo[3] dst = void;\n\n    auto res = moveEmplaceSome(src[], dst[]);\n    assert(res.length == 2);\n\n    import std.algorithm.searching : all;\n    assert(src[0 .. 3].all!(e => e._ptr is null));\n    assert(src[3]._ptr !is null);\n    assert(dst[].all!(e => e._ptr !is null));\n}\n\nprivate Tuple!(InputRange1, InputRange2) moveSomeImpl(alias moveOp, InputRange1, InputRange2)(\n    ref InputRange1 src, ref InputRange2 tgt)\n{\n    for (; !src.empty && !tgt.empty; src.popFront(), tgt.popFront())\n        moveOp(src.front, tgt.front);\n    return tuple(src, tgt);\n }\n\n\n// SwapStrategy\n/**\nDefines the swapping strategy for algorithms that need to swap\nelements in a range (such as partition and sort). The strategy\nconcerns the swapping of elements that are not the core concern of the\nalgorithm. For example, consider an algorithm that sorts $(D [ \"abc\",\n\"b\", \"aBc\" ]) according to `toUpper(a) < toUpper(b)`. That\nalgorithm might choose to swap the two equivalent strings `\"abc\"`\nand `\"aBc\"`. That does not affect the sorting since both\n`[\"abc\", \"aBc\", \"b\" ]` and `[ \"aBc\", \"abc\", \"b\" ]` are valid\noutcomes.\n\nSome situations require that the algorithm must NOT ever change the\nrelative ordering of equivalent elements (in the example above, only\n`[ \"abc\", \"aBc\", \"b\" ]` would be the correct result). Such\nalgorithms are called $(B stable). If the ordering algorithm may swap\nequivalent elements discretionarily, the ordering is called $(B\nunstable).\n\nYet another class of algorithms may choose an intermediate tradeoff by\nbeing stable only on a well-defined subrange of the range. There is no\nestablished terminology for such behavior; this library calls it $(B\nsemistable).\n\nGenerally, the `stable` ordering strategy may be more costly in\ntime and/or space than the other two because it imposes additional\nconstraints. Similarly, `semistable` may be costlier than $(D\nunstable). As (semi-)stability is not needed very often, the ordering\nalgorithms in this module parameterized by `SwapStrategy` all\nchoose `SwapStrategy.unstable` as the default.\n*/\n\nenum SwapStrategy\n{\n    /**\n       Allows freely swapping of elements as long as the output\n       satisfies the algorithm's requirements.\n    */\n    unstable,\n    /**\n       In algorithms partitioning ranges in two, preserve relative\n       ordering of elements only to the left of the partition point.\n    */\n    semistable,\n    /**\n       Preserve the relative ordering of elements to the largest\n       extent allowed by the algorithm's requirements.\n    */\n    stable,\n}\n\n///\n@safe unittest\n{\n    int[] a = [0, 1, 2, 3];\n    assert(remove!(SwapStrategy.stable)(a, 1) == [0, 2, 3]);\n    a = [0, 1, 2, 3];\n    assert(remove!(SwapStrategy.unstable)(a, 1) == [0, 3, 2]);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.sorting : partition;\n\n    // Put stuff greater than 3 on the left\n    auto arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    assert(partition!(a => a > 3, SwapStrategy.stable)(arr) == [1, 2, 3]);\n    assert(arr == [4, 5, 6, 7, 8, 9, 10, 1, 2, 3]);\n\n    arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    assert(partition!(a => a > 3, SwapStrategy.semistable)(arr) == [2, 3, 1]);\n    assert(arr == [4, 5, 6, 7, 8, 9, 10, 2, 3, 1]);\n\n    arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    assert(partition!(a => a > 3, SwapStrategy.unstable)(arr) == [3, 2, 1]);\n    assert(arr == [10, 9, 8, 4, 5, 6, 7, 3, 2, 1]);\n}\n\nprivate template isValidIntegralTuple(T)\n{\n    import std.traits : isIntegral;\n    import std.typecons : isTuple;\n    static if (isTuple!T)\n    {\n        enum isValidIntegralTuple = T.length == 2 &&\n                isIntegral!(typeof(T.init[0])) && isIntegral!(typeof(T.init[0]));\n    }\n    else\n    {\n        enum isValidIntegralTuple = isIntegral!T;\n    }\n}\n\n\n/**\nEliminates elements at given offsets from `range` and returns the shortened\nrange.\n\nFor example, here is how to remove a single element from an array:\n\n----\nstring[] a = [ \"a\", \"b\", \"c\", \"d\" ];\na = a.remove(1); // remove element at offset 1\nassert(a == [ \"a\", \"c\", \"d\"]);\n----\n\nNote that `remove` does not change the length of the original range directly;\ninstead, it returns the shortened range. If its return value is not assigned to\nthe original range, the original range will retain its original length, though\nits contents will have changed:\n\n----\nint[] a = [ 3, 5, 7, 8 ];\nassert(remove(a, 1) == [ 3, 7, 8 ]);\nassert(a == [ 3, 7, 8, 8 ]);\n----\n\nThe element at offset `1` has been removed and the rest of the elements have\nshifted up to fill its place, however, the original array remains of the same\nlength. This is because all functions in `std.algorithm` only change $(I\ncontent), not $(I topology). The value `8` is repeated because $(LREF move) was\ninvoked to rearrange elements, and on integers `move` simply copies the source\nto the destination.  To replace `a` with the effect of the removal, simply\nassign the slice returned by `remove` to it, as shown in the first example.\n\nMultiple indices can be passed into `remove`. In that case,\nelements at the respective indices are all removed. The indices must\nbe passed in increasing order, otherwise an exception occurs.\n\n----\nint[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\nassert(remove(a, 1, 3, 5) ==\n    [ 0, 2, 4, 6, 7, 8, 9, 10 ]);\n----\n\n(Note that all indices refer to slots in the $(I original) array, not\nin the array as it is being progressively shortened.)\n\nTuples of two integral offsets can be used to remove an indices range:\n\n----\nint[] a = [ 3, 4, 5, 6, 7];\nassert(remove(a, 1, tuple(1, 3), 9) == [ 3, 6, 7 ]);\n----\n\nThe tuple passes in a range closed to the left and open to\nthe right (consistent with built-in slices), e.g. `tuple(1, 3)`\nmeans indices `1` and `2` but not `3`.\n\nFinally, any combination of integral offsets and tuples composed of two integral\noffsets can be passed in:\n\n----\nint[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\nassert(remove(a, 1, tuple(3, 5), 9) == [ 0, 2, 5, 6, 7, 8, 10 ]);\n----\n\nIn this case, the slots at positions 1, 3, 4, and 9 are removed from\nthe array.\n\nIf the need is to remove some elements in the range but the order of\nthe remaining elements does not have to be preserved, you may want to\npass `SwapStrategy.unstable` to `remove`.\n\n----\nint[] a = [ 0, 1, 2, 3 ];\nassert(remove!(SwapStrategy.unstable)(a, 1) == [ 0, 3, 2 ]);\n----\n\nIn the case above, the element at slot `1` is removed, but replaced\nwith the last element of the range. Taking advantage of the relaxation\nof the stability requirement, `remove` moved elements from the end\nof the array over the slots to be removed. This way there is less data\nmovement to be done which improves the execution time of the function.\n\nThe function `remove` works on bidirectional ranges that have assignable\nlvalue elements. The moving strategy is (listed from fastest to slowest):\n\n$(UL\n        $(LI If $(D s == SwapStrategy.unstable && isRandomAccessRange!Range &&\nhasLength!Range && hasLvalueElements!Range), then elements are moved from the\nend of the range into the slots to be filled. In this case, the absolute\nminimum of moves is performed.)\n        $(LI Otherwise, if $(D s ==\nSwapStrategy.unstable && isBidirectionalRange!Range && hasLength!Range\n&& hasLvalueElements!Range), then elements are still moved from the\nend of the range, but time is spent on advancing between slots by repeated\ncalls to `range.popFront`.)\n        $(LI Otherwise, elements are moved\nincrementally towards the front of `range`; a given element is never\nmoved several times, but more elements are moved than in the previous\ncases.)\n)\n\nParams:\n    s = a SwapStrategy to determine if the original order needs to be preserved\n    range = a $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives)\n    with a length member\n    offset = which element(s) to remove\n\nReturns:\n    A range containing all of the elements of range with offset removed.\n*/\nRange remove\n(SwapStrategy s = SwapStrategy.stable, Range, Offset ...)\n(Range range, Offset offset)\nif (Offset.length >= 1 && allSatisfy!(isValidIntegralTuple, Offset))\n{\n    // Activate this check when the deprecation of non-integral tuples is over\n    //import std.traits : isIntegral;\n    //import std.typecons : isTuple;\n    //static foreach (T; Offset)\n    //{\n        //static if (isTuple!T)\n        //{\n            //static assert(T.length == 2 &&\n                    //isIntegral!(typeof(T.init[0])) && isIntegral!(typeof(T.init[0])),\n                //\"Each offset must be an integral or a tuple of two integrals.\" ~\n                //\"Use `arr.remove(pos1, pos2)` or `arr.remove(tuple(start, begin))`\");\n        //}\n        //else\n        //{\n            //static assert(isIntegral!T,\n                //\"Each offset must be an integral or a tuple of two integrals.\" ~\n                //\"Use `arr.remove(pos1, pos2)` or `arr.remove(tuple(start, begin))`\");\n        //}\n    //}\n    return removeImpl!s(range, offset);\n}\n\ndeprecated(\"Use of non-integral tuples is deprecated. Use remove(tuple(start, end).\")\nRange remove\n(SwapStrategy s = SwapStrategy.stable, Range, Offset ...)\n(Range range, Offset offset)\nif (Offset.length >= 1 && !allSatisfy!(isValidIntegralTuple, Offset))\n{\n    return removeImpl!s(range, offset);\n}\n\n///\n@safe pure unittest\n{\n    import std.typecons : tuple;\n\n    auto a = [ 0, 1, 2, 3, 4, 5 ];\n    assert(remove!(SwapStrategy.stable)(a, 1) == [ 0, 2, 3, 4, 5 ]);\n    a = [ 0, 1, 2, 3, 4, 5 ];\n    assert(remove!(SwapStrategy.stable)(a, 1, 3) == [ 0, 2, 4, 5] );\n    a = [ 0, 1, 2, 3, 4, 5 ];\n    assert(remove!(SwapStrategy.stable)(a, 1, tuple(3, 6)) == [ 0, 2 ]);\n\n    a = [ 0, 1, 2, 3, 4, 5 ];\n    assert(remove!(SwapStrategy.unstable)(a, 1) == [0, 5, 2, 3, 4]);\n    a = [ 0, 1, 2, 3, 4, 5 ];\n    assert(remove!(SwapStrategy.unstable)(a, tuple(1, 4)) == [0, 5, 4]);\n}\n\n///\n@safe pure unittest\n{\n    import std.typecons : tuple;\n\n    // Delete an index\n    assert([4, 5, 6].remove(1) == [4, 6]);\n\n    // Delete multiple indices\n    assert([4, 5, 6, 7, 8].remove(1, 3) == [4, 6, 8]);\n\n    // Use an indices range\n    assert([4, 5, 6, 7, 8].remove(tuple(1, 3)) == [4, 7, 8]);\n\n    // Use an indices range and individual indices\n    assert([4, 5, 6, 7, 8].remove(0, tuple(1, 3), 4) == [7]);\n}\n\n/// `SwapStrategy.unstable` is faster, but doesn't guarantee the same order of the original array\n@safe pure unittest\n{\n    assert([5, 6, 7, 8].remove!(SwapStrategy.stable)(1) == [5, 7, 8]);\n    assert([5, 6, 7, 8].remove!(SwapStrategy.unstable)(1) == [5, 8, 7]);\n}\n\nprivate auto removeImpl(SwapStrategy s, Range, Offset...)(Range range, Offset offset)\n{\n    static if (isNarrowString!Range)\n    {\n        static assert(isMutable!(typeof(range[0])),\n                \"Elements must be mutable to remove\");\n        static assert(s == SwapStrategy.stable,\n                \"Only stable removing can be done for character arrays\");\n        return removeStableString(range, offset);\n    }\n    else\n    {\n        static assert(isBidirectionalRange!Range,\n                \"Range must be bidirectional\");\n        static assert(hasLvalueElements!Range,\n                \"Range must have Lvalue elements (see std.range.hasLvalueElements)\");\n\n        static if (s == SwapStrategy.unstable)\n        {\n            static assert(hasLength!Range,\n                    \"Range must have `length` for unstable remove\");\n            return removeUnstable(range, offset);\n        }\n        else static if (s == SwapStrategy.stable)\n            return removeStable(range, offset);\n        else\n            static assert(false,\n                    \"Only SwapStrategy.stable and SwapStrategy.unstable are supported\");\n    }\n}\n\n@safe unittest\n{\n    import std.exception : assertThrown;\n    import std.range;\n\n    // http://d.puremagic.com/issues/show_bug.cgi?id=10173\n    int[] test = iota(0, 10).array();\n    assertThrown(remove!(SwapStrategy.stable)(test, tuple(2, 4), tuple(1, 3)));\n    assertThrown(remove!(SwapStrategy.unstable)(test, tuple(2, 4), tuple(1, 3)));\n    assertThrown(remove!(SwapStrategy.stable)(test, 2, 4, 1, 3));\n    assertThrown(remove!(SwapStrategy.unstable)(test, 2, 4, 1, 3));\n}\n\n@safe unittest\n{\n    import std.range;\n    int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\n    a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\n    assert(remove!(SwapStrategy.stable)(a, 1) ==\n        [ 0, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]);\n\n    a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\n    assert(remove!(SwapStrategy.unstable)(a, 0, 10) ==\n           [ 9, 1, 2, 3, 4, 5, 6, 7, 8 ]);\n\n    a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\n    assert(remove!(SwapStrategy.unstable)(a, 0, tuple(9, 11)) ==\n            [ 8, 1, 2, 3, 4, 5, 6, 7 ]);\n    // http://d.puremagic.com/issues/show_bug.cgi?id=5224\n    a = [ 1, 2, 3, 4 ];\n    assert(remove!(SwapStrategy.unstable)(a, 2) ==\n           [ 1, 2, 4 ]);\n\n    a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\n    assert(remove!(SwapStrategy.stable)(a, 1, 5) ==\n        [ 0, 2, 3, 4, 6, 7, 8, 9, 10 ]);\n\n    a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\n    assert(remove!(SwapStrategy.stable)(a, 1, 3, 5)\n            == [ 0, 2, 4, 6, 7, 8, 9, 10]);\n    a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\n    assert(remove!(SwapStrategy.stable)(a, 1, tuple(3, 5))\n            == [ 0, 2, 5, 6, 7, 8, 9, 10]);\n\n    a = iota(0, 10).array();\n    assert(remove!(SwapStrategy.unstable)(a, tuple(1, 4), tuple(6, 7))\n            == [0, 9, 8, 7, 4, 5]);\n}\n\n@safe unittest\n{\n    // Issue 11576\n    auto arr = [1,2,3];\n    arr = arr.remove!(SwapStrategy.unstable)(2);\n    assert(arr == [1,2]);\n\n}\n\n@safe unittest\n{\n    import std.range;\n    // Bug# 12889\n    int[1][] arr = [[0], [1], [2], [3], [4], [5], [6]];\n    auto orig = arr.dup;\n    foreach (i; iota(arr.length))\n    {\n        assert(orig == arr.remove!(SwapStrategy.unstable)(tuple(i,i)));\n        assert(orig == arr.remove!(SwapStrategy.stable)(tuple(i,i)));\n    }\n}\n\n@safe unittest\n{\n    char[] chars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];\n    remove(chars, 4);\n    assert(chars == ['a', 'b', 'c', 'd', 'f', 'g', 'h', 'h']);\n\n    char[] bigChars = \"∑œ∆¬é˚˙ƒé∂ß¡¡\".dup;\n    assert(remove(bigChars, tuple(4, 6), 8) == (\"∑œ∆¬˙ƒ∂ß¡¡\"));\n\n    import std.exception : assertThrown;\n    assertThrown(remove(bigChars.dup, 1, 0));\n    assertThrown(remove(bigChars.dup, tuple(4, 3)));\n}\n\nprivate Range removeUnstable(Range, Offset...)(Range range, Offset offset)\n{\n    Tuple!(size_t, \"pos\", size_t, \"len\")[offset.length] blackouts;\n    foreach (i, v; offset)\n    {\n        static if (is(typeof(v[0]) : size_t) && is(typeof(v[1]) : size_t))\n        {\n            blackouts[i].pos = v[0];\n            blackouts[i].len = v[1] - v[0];\n        }\n        else\n        {\n            static assert(is(typeof(v) : size_t), typeof(v).stringof);\n            blackouts[i].pos = v;\n            blackouts[i].len = 1;\n        }\n        static if (i > 0)\n        {\n            import std.exception : enforce;\n\n            enforce(blackouts[i - 1].pos + blackouts[i - 1].len\n                    <= blackouts[i].pos,\n                \"remove(): incorrect ordering of elements to remove\");\n        }\n    }\n\n    size_t left = 0, right = offset.length - 1;\n    auto tgt = range.save;\n    size_t tgtPos = 0;\n\n    while (left <= right)\n    {\n        // Look for a blackout on the right\n        if (blackouts[right].pos + blackouts[right].len >= range.length)\n        {\n            range.popBackExactly(blackouts[right].len);\n\n            // Since right is unsigned, we must check for this case, otherwise\n            // we might turn it into size_t.max and the loop condition will not\n            // fail when it should.\n            if (right > 0)\n            {\n                --right;\n                continue;\n            }\n            else\n                break;\n        }\n        // Advance to next blackout on the left\n        assert(blackouts[left].pos >= tgtPos, \"Next blackout on the left shouldn't appear before the target.\");\n        tgt.popFrontExactly(blackouts[left].pos - tgtPos);\n        tgtPos = blackouts[left].pos;\n\n        // Number of elements to the right of blackouts[right]\n        immutable tailLen = range.length - (blackouts[right].pos + blackouts[right].len);\n        size_t toMove = void;\n        if (tailLen < blackouts[left].len)\n        {\n            toMove = tailLen;\n            blackouts[left].pos += toMove;\n            blackouts[left].len -= toMove;\n        }\n        else\n        {\n            toMove = blackouts[left].len;\n            ++left;\n        }\n        tgtPos += toMove;\n        foreach (i; 0 .. toMove)\n        {\n            move(range.back, tgt.front);\n            range.popBack();\n            tgt.popFront();\n        }\n    }\n\n    return range;\n}\n\nprivate Range removeStable(Range, Offset...)(Range range, Offset offset)\n{\n    auto result = range;\n    auto src = range, tgt = range;\n    size_t pos;\n    foreach (pass, i; offset)\n    {\n        static if (is(typeof(i[0])) && is(typeof(i[1])))\n        {\n            auto from = i[0], delta = i[1] - i[0];\n        }\n        else\n        {\n            auto from = i;\n            enum delta = 1;\n        }\n\n        static if (pass > 0)\n        {\n            import std.exception : enforce;\n            enforce(pos <= from,\n                    \"remove(): incorrect ordering of elements to remove\");\n\n            for (; pos < from; ++pos, src.popFront(), tgt.popFront())\n            {\n                move(src.front, tgt.front);\n            }\n        }\n        else\n        {\n            src.popFrontExactly(from);\n            tgt.popFrontExactly(from);\n            pos = from;\n        }\n        // now skip source to the \"to\" position\n        src.popFrontExactly(delta);\n        result.popBackExactly(delta);\n        pos += delta;\n    }\n    // leftover move\n    moveAll(src, tgt);\n    return result;\n}\n\nprivate Range removeStableString(Range, Offset...)(Range range, Offset offsets)\n{\n    import std.utf : stride;\n    size_t charIdx = 0;\n    size_t dcharIdx = 0;\n    size_t charShift = 0;\n\n    void skipOne()\n    {\n        charIdx += stride(range[charIdx .. $]);\n        ++dcharIdx;\n    }\n\n    void copyBackOne()\n    {\n        auto encodedLen = stride(range[charIdx .. $]);\n        foreach (j; charIdx .. charIdx + encodedLen)\n            range[j - charShift] = range[j];\n        charIdx += encodedLen;\n        ++dcharIdx;\n    }\n\n    foreach (pass, i; offsets)\n    {\n        static if (is(typeof(i[0])) && is(typeof(i[1])))\n        {\n            auto from = i[0];\n            auto delta = i[1] - i[0];\n        }\n        else\n        {\n            auto from = i;\n            enum delta = 1;\n        }\n\n        import std.exception : enforce;\n        enforce(dcharIdx <= from && delta >= 0,\n                \"remove(): incorrect ordering of elements to remove\");\n\n        while (dcharIdx < from)\n            static if (pass == 0)\n                skipOne();\n            else\n                copyBackOne();\n\n        auto mark = charIdx;\n        while (dcharIdx < from + delta)\n            skipOne();\n        charShift += charIdx - mark;\n    }\n\n    foreach (i; charIdx .. range.length)\n        range[i - charShift] = range[i];\n\n    return range[0 .. $ - charShift];\n}\n\n// Use of dynamic arrays as offsets is too error-prone\n// https://issues.dlang.org/show_bug.cgi?id=12086\n// Activate these tests once the deprecation period of remove with non-integral tuples is over\n@safe unittest\n{\n    //static assert(!__traits(compiles, [0, 1, 2, 3, 4].remove([1, 3]) == [0, 3, 4]));\n    static assert(__traits(compiles, [0, 1, 2, 3, 4].remove(1, 3) == [0, 2, 4]));\n    //static assert(!__traits(compiles, assert([0, 1, 2, 3, 4].remove([1, 3, 4]) == [0, 3, 4])));\n    //static assert(!__traits(compiles, assert([0, 1, 2, 3, 4].remove(tuple(1, 3, 4)) == [0, 3, 4])));\n\n    import std.range : only;\n    //static assert(!__traits(compiles, assert([0, 1, 2, 3, 4].remove(only(1, 3)) == [0, 3, 4])));\n    static assert(__traits(compiles, assert([0, 1, 2, 3, 4].remove(1, 3) == [0, 2, 4])));\n}\n\n/**\nReduces the length of the\n$(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives) `range` by removing\nelements that satisfy `pred`. If `s = SwapStrategy.unstable`,\nelements are moved from the right end of the range over the elements\nto eliminate. If `s = SwapStrategy.stable` (the default),\nelements are moved progressively to front such that their relative\norder is preserved. Returns the filtered range.\n\nParams:\n    range = a bidirectional ranges with lvalue elements\n        or mutable character arrays\n\nReturns:\n    the range with all of the elements where `pred` is `true`\n    removed\n*/\nRange remove(alias pred, SwapStrategy s = SwapStrategy.stable, Range)(Range range)\n{\n    import std.functional : unaryFun;\n    alias pred_ = unaryFun!pred;\n    static if (isNarrowString!Range)\n    {\n        static assert(isMutable!(typeof(range[0])),\n                \"Elements must be mutable to remove\");\n        static assert(s == SwapStrategy.stable,\n                \"Only stable removing can be done for character arrays\");\n        return removePredString!pred_(range);\n    }\n    else\n    {\n        static assert(isBidirectionalRange!Range,\n                \"Range must be bidirectional\");\n        static assert(hasLvalueElements!Range,\n                \"Range must have Lvalue elements (see std.range.hasLvalueElements)\");\n        static if (s == SwapStrategy.unstable)\n            return removePredUnstable!pred_(range);\n        else static if (s == SwapStrategy.stable)\n            return removePredStable!pred_(range);\n        else\n            static assert(false,\n                    \"Only SwapStrategy.stable and SwapStrategy.unstable are supported\");\n    }\n}\n\n///\n@safe unittest\n{\n    static immutable base = [1, 2, 3, 2, 4, 2, 5, 2];\n\n    int[] arr = base[].dup;\n\n    // using a string-based predicate\n    assert(remove!(\"a == 2\")(arr) == [ 1, 3, 4, 5 ]);\n\n    // The original array contents have been modified,\n    // so we need to reset it to its original state.\n    // The length is unmodified however.\n    arr[] = base[];\n\n    // using a lambda predicate\n    assert(remove!(a => a == 2)(arr) == [ 1, 3, 4, 5 ]);\n}\n\n@safe unittest\n{\n    int[] a = [ 1, 2, 3, 2, 3, 4, 5, 2, 5, 6 ];\n    assert(remove!(\"a == 2\", SwapStrategy.unstable)(a) ==\n            [ 1, 6, 3, 5, 3, 4, 5 ]);\n    a = [ 1, 2, 3, 2, 3, 4, 5, 2, 5, 6 ];\n    assert(remove!(\"a == 2\", SwapStrategy.stable)(a) ==\n            [ 1, 3, 3, 4, 5, 5, 6 ]);\n}\n\n@nogc @safe unittest\n{\n    // @nogc test\n    int[10] arr = [0,1,2,3,4,5,6,7,8,9];\n    alias pred = e => e < 5;\n\n    auto r = arr[].remove!(SwapStrategy.unstable)(0);\n    r = r.remove!(SwapStrategy.stable)(0);\n    r = r.remove!(pred, SwapStrategy.unstable);\n    r = r.remove!(pred, SwapStrategy.stable);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : min;\n    import std.algorithm.searching : all, any;\n    import std.algorithm.sorting : isStrictlyMonotonic;\n    import std.array : array;\n    import std.meta : AliasSeq;\n    import std.range : iota, only;\n    import std.typecons : Tuple;\n    alias E = Tuple!(int, int);\n    alias S = Tuple!(E);\n    S[] soffsets;\n    foreach (start; 0 .. 5)\n    foreach (end; min(start+1,5) .. 5)\n          soffsets ~= S(E(start,end));\n    alias D = Tuple!(E, E);\n    D[] doffsets;\n    foreach (start1; 0 .. 10)\n    foreach (end1; min(start1+1,10) .. 10)\n    foreach (start2; end1 .. 10)\n    foreach (end2; min(start2+1,10) .. 10)\n          doffsets ~= D(E(start1,end1),E(start2,end2));\n    alias T = Tuple!(E, E, E);\n    T[] toffsets;\n    foreach (start1; 0 .. 15)\n    foreach (end1; min(start1+1,15) .. 15)\n    foreach (start2; end1 .. 15)\n    foreach (end2; min(start2+1,15) .. 15)\n    foreach (start3; end2 .. 15)\n    foreach (end3; min(start3+1,15) .. 15)\n            toffsets ~= T(E(start1,end1),E(start2,end2),E(start3,end3));\n\n    static void verify(O...)(int[] r, int len, int removed, bool stable, O offsets)\n    {\n        assert(r.length == len - removed);\n        assert(!stable || r.isStrictlyMonotonic);\n        assert(r.all!(e => all!(o => e < o[0] || e >= o[1])(offsets.only)));\n    }\n\n    static foreach (offsets; AliasSeq!(soffsets,doffsets,toffsets))\n    foreach (os; offsets)\n    {\n        int len = 5*os.length;\n        auto w = iota(0, len).array;\n        auto x = w.dup;\n        auto y = w.dup;\n        auto z = w.dup;\n        alias pred = e => any!(o => o[0] <= e && e < o[1])(only(os.expand));\n        w = w.remove!(SwapStrategy.unstable)(os.expand);\n        x = x.remove!(SwapStrategy.stable)(os.expand);\n        y = y.remove!(pred, SwapStrategy.unstable);\n        z = z.remove!(pred, SwapStrategy.stable);\n        int removed;\n        foreach (o; os)\n            removed += o[1] - o[0];\n        verify(w, len, removed, false, os[]);\n        verify(x, len, removed, true, os[]);\n        verify(y, len, removed, false, os[]);\n        verify(z, len, removed, true, os[]);\n        assert(w == y);\n        assert(x == z);\n    }\n}\n\n@safe unittest\n{\n    char[] chars = \"abcdefg\".dup;\n    assert(chars.remove!(dc => dc == 'c' || dc == 'f') == \"abdeg\");\n    assert(chars == \"abdegfg\");\n\n    assert(chars.remove!\"a == 'd'\" == \"abegfg\");\n\n    char[] bigChars = \"¥^¨^©é√∆π\".dup;\n    assert(bigChars.remove!(dc => dc == \"¨\"d[0] || dc == \"é\"d[0]) ==  \"¥^^©√∆π\");\n}\n\nprivate Range removePredUnstable(alias pred, Range)(Range range)\n{\n    auto result = range;\n    for (;!range.empty;)\n    {\n        if (!pred(range.front))\n        {\n            range.popFront();\n            continue;\n        }\n        move(range.back, range.front);\n        range.popBack();\n        result.popBack();\n    }\n    return result;\n}\n\nprivate Range removePredStable(alias pred, Range)(Range range)\n{\n    auto result = range;\n    auto tgt = range;\n    for (; !range.empty; range.popFront())\n    {\n        if (pred(range.front))\n        {\n            // yank this guy\n            result.popBack();\n            continue;\n        }\n        // keep this guy\n        move(range.front, tgt.front);\n        tgt.popFront();\n    }\n    return result;\n}\n\nprivate Range removePredString(alias pred, SwapStrategy s = SwapStrategy.stable, Range)\n(Range range)\n{\n    import std.utf : decode;\n    import std.functional : unaryFun;\n\n    alias pred_ = unaryFun!pred;\n\n    size_t charIdx = 0;\n    size_t charShift = 0;\n    while (charIdx < range.length)\n    {\n        size_t start = charIdx;\n        if (pred_(decode(range, charIdx)))\n        {\n            charShift += charIdx - start;\n            break;\n        }\n    }\n    while (charIdx < range.length)\n    {\n        size_t start = charIdx;\n        auto doRemove = pred_(decode(range, charIdx));\n        auto encodedLen = charIdx - start;\n        if (doRemove)\n            charShift += encodedLen;\n        else\n            foreach (i; start .. charIdx)\n                range[i - charShift] = range[i];\n    }\n\n    return range[0 .. $ - charShift];\n}\n\n// reverse\n/**\nReverses `r` in-place.  Performs `r.length / 2` evaluations of `swap`.\nUTF sequences consisting of multiple code units are preserved properly.\n\nParams:\n    r = a $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives)\n        with either swappable elements, a random access range with a length member,\n        or a narrow string\n\nReturns: `r`\n\nNote:\n    When passing a string with unicode modifiers on characters, such as `\\u0301`,\n    this function will not properly keep the position of the modifier. For example,\n    reversing `ba\\u0301d` (\"bád\") will result in d\\u0301ab (\"d́ab\") instead of\n    `da\\u0301b` (\"dáb\").\n\nSee_Also: $(REF retro, std,range) for a lazy reverse without changing `r`\n*/\nRange reverse(Range)(Range r)\nif (isBidirectionalRange!Range &&\n        (hasSwappableElements!Range ||\n         (hasAssignableElements!Range && hasLength!Range && isRandomAccessRange!Range) ||\n         (isNarrowString!Range && isAssignable!(ElementType!Range))))\n{\n    static if (isRandomAccessRange!Range && hasLength!Range)\n    {\n        //swapAt is in fact the only way to swap non lvalue ranges\n        immutable last = r.length - 1;\n        immutable steps = r.length / 2;\n        for (size_t i = 0; i < steps; i++)\n        {\n            r.swapAt(i, last - i);\n        }\n        return r;\n    }\n    else static if (isNarrowString!Range && isAssignable!(ElementType!Range))\n    {\n        import std.string : representation;\n        import std.utf : stride;\n\n        auto raw = representation(r);\n        for (size_t i = 0; i < r.length;)\n        {\n            immutable step = stride(r, i);\n            if (step > 1)\n            {\n                .reverse(raw[i .. i + step]);\n                i += step;\n            }\n            else\n            {\n                ++i;\n            }\n        }\n        reverse(raw);\n        return r;\n    }\n    else\n    {\n        while (!r.empty)\n        {\n            swap(r.front, r.back);\n            r.popFront();\n            if (r.empty) break;\n            r.popBack();\n        }\n        return r;\n    }\n}\n\n///\n@safe unittest\n{\n    int[] arr = [ 1, 2, 3 ];\n    assert(arr.reverse == [ 3, 2, 1 ]);\n}\n\n@safe unittest\n{\n    int[] range = null;\n    reverse(range);\n    range = [ 1 ];\n    reverse(range);\n    assert(range == [1]);\n    range = [1, 2];\n    reverse(range);\n    assert(range == [2, 1]);\n    range = [1, 2, 3];\n    assert(range.reverse == [3, 2, 1]);\n}\n\n///\n@safe unittest\n{\n    char[] arr = \"hello\\U00010143\\u0100\\U00010143\".dup;\n    assert(arr.reverse == \"\\U00010143\\u0100\\U00010143olleh\");\n}\n\n@safe unittest\n{\n    void test(string a, string b)\n    {\n        auto c = a.dup;\n        reverse(c);\n        assert(c == b, c ~ \" != \" ~ b);\n    }\n\n    test(\"a\", \"a\");\n    test(\" \", \" \");\n    test(\"\\u2029\", \"\\u2029\");\n    test(\"\\u0100\", \"\\u0100\");\n    test(\"\\u0430\", \"\\u0430\");\n    test(\"\\U00010143\", \"\\U00010143\");\n    test(\"abcdefcdef\", \"fedcfedcba\");\n    test(\"hello\\U00010143\\u0100\\U00010143\", \"\\U00010143\\u0100\\U00010143olleh\");\n}\n\n/**\n    The strip group of functions allow stripping of either leading, trailing,\n    or both leading and trailing elements.\n\n    The `stripLeft` function will strip the `front` of the range,\n    the `stripRight` function will strip the `back` of the range,\n    while the `strip` function will strip both the `front` and `back`\n    of the range.\n\n    Note that the `strip` and `stripRight` functions require the range to\n    be a $(LREF BidirectionalRange) range.\n\n    All of these functions come in two varieties: one takes a target element,\n    where the range will be stripped as long as this element can be found.\n    The other takes a lambda predicate, where the range will be stripped as\n    long as the predicate returns true.\n\n    Params:\n        range = a $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives)\n        or $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n        element = the elements to remove\n\n    Returns:\n        a Range with all of range except element at the start and end\n*/\nRange strip(Range, E)(Range range, E element)\nif (isBidirectionalRange!Range && is(typeof(range.front == element) : bool))\n{\n    return range.stripLeft(element).stripRight(element);\n}\n\n/// ditto\nRange strip(alias pred, Range)(Range range)\nif (isBidirectionalRange!Range && is(typeof(pred(range.back)) : bool))\n{\n    return range.stripLeft!pred().stripRight!pred();\n}\n\n/// ditto\nRange stripLeft(Range, E)(Range range, E element)\nif (isInputRange!Range && is(typeof(range.front == element) : bool))\n{\n    import std.algorithm.searching : find;\n    return find!((auto ref a) => a != element)(range);\n}\n\n/// ditto\nRange stripLeft(alias pred, Range)(Range range)\nif (isInputRange!Range && is(typeof(pred(range.front)) : bool))\n{\n    import std.algorithm.searching : find;\n    import std.functional : not;\n\n    return find!(not!pred)(range);\n}\n\n/// ditto\nRange stripRight(Range, E)(Range range, E element)\nif (isBidirectionalRange!Range && is(typeof(range.back == element) : bool))\n{\n    for (; !range.empty; range.popBack())\n    {\n        if (range.back != element)\n            break;\n    }\n    return range;\n}\n\n/// ditto\nRange stripRight(alias pred, Range)(Range range)\nif (isBidirectionalRange!Range && is(typeof(pred(range.back)) : bool))\n{\n    for (; !range.empty; range.popBack())\n    {\n        if (!pred(range.back))\n            break;\n    }\n    return range;\n}\n\n/// Strip leading and trailing elements equal to the target element.\n@safe pure unittest\n{\n    assert(\"  foobar  \".strip(' ') == \"foobar\");\n    assert(\"00223.444500\".strip('0') == \"223.4445\");\n    assert(\"ëëêéüŗōpéêëë\".strip('ë') == \"êéüŗōpéê\");\n    assert([1, 1, 0, 1, 1].strip(1) == [0]);\n    assert([0.0, 0.01, 0.01, 0.0].strip(0).length == 2);\n}\n\n/// Strip leading and trailing elements while the predicate returns true.\n@safe pure unittest\n{\n    assert(\"  foobar  \".strip!(a => a == ' ')() == \"foobar\");\n    assert(\"00223.444500\".strip!(a => a == '0')() == \"223.4445\");\n    assert(\"ëëêéüŗōpéêëë\".strip!(a => a == 'ë')() == \"êéüŗōpéê\");\n    assert([1, 1, 0, 1, 1].strip!(a => a == 1)() == [0]);\n    assert([0.0, 0.01, 0.5, 0.6, 0.01, 0.0].strip!(a => a < 0.4)().length == 2);\n}\n\n/// Strip leading elements equal to the target element.\n@safe pure unittest\n{\n    assert(\"  foobar  \".stripLeft(' ') == \"foobar  \");\n    assert(\"00223.444500\".stripLeft('0') == \"223.444500\");\n    assert(\"ůůűniçodêéé\".stripLeft('ů') == \"űniçodêéé\");\n    assert([1, 1, 0, 1, 1].stripLeft(1) == [0, 1, 1]);\n    assert([0.0, 0.01, 0.01, 0.0].stripLeft(0).length == 3);\n}\n\n/// Strip leading elements while the predicate returns true.\n@safe pure unittest\n{\n    assert(\"  foobar  \".stripLeft!(a => a == ' ')() == \"foobar  \");\n    assert(\"00223.444500\".stripLeft!(a => a == '0')() == \"223.444500\");\n    assert(\"ůůűniçodêéé\".stripLeft!(a => a == 'ů')() == \"űniçodêéé\");\n    assert([1, 1, 0, 1, 1].stripLeft!(a => a == 1)() == [0, 1, 1]);\n    assert([0.0, 0.01, 0.10, 0.5, 0.6].stripLeft!(a => a < 0.4)().length == 2);\n}\n\n/// Strip trailing elements equal to the target element.\n@safe pure unittest\n{\n    assert(\"  foobar  \".stripRight(' ') == \"  foobar\");\n    assert(\"00223.444500\".stripRight('0') == \"00223.4445\");\n    assert(\"ùniçodêéé\".stripRight('é') == \"ùniçodê\");\n    assert([1, 1, 0, 1, 1].stripRight(1) == [1, 1, 0]);\n    assert([0.0, 0.01, 0.01, 0.0].stripRight(0).length == 3);\n}\n\n/// Strip trailing elements while the predicate returns true.\n@safe pure unittest\n{\n    assert(\"  foobar  \".stripRight!(a => a == ' ')() == \"  foobar\");\n    assert(\"00223.444500\".stripRight!(a => a == '0')() == \"00223.4445\");\n    assert(\"ùniçodêéé\".stripRight!(a => a == 'é')() == \"ùniçodê\");\n    assert([1, 1, 0, 1, 1].stripRight!(a => a == 1)() == [1, 1, 0]);\n    assert([0.0, 0.01, 0.10, 0.5, 0.6].stripRight!(a => a > 0.4)().length == 3);\n}\n\n// swap\n/**\nSwaps `lhs` and `rhs`. The instances `lhs` and `rhs` are moved in\nmemory, without ever calling `opAssign`, nor any other function. `T`\nneed not be assignable at all to be swapped.\n\nIf `lhs` and `rhs` reference the same instance, then nothing is done.\n\n`lhs` and `rhs` must be mutable. If `T` is a struct or union, then\nits fields must also all be (recursively) mutable.\n\nParams:\n    lhs = Data to be swapped with `rhs`.\n    rhs = Data to be swapped with `lhs`.\n*/\nvoid swap(T)(ref T lhs, ref T rhs) @trusted pure nothrow @nogc\nif (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs))))\n{\n    import std.traits : hasAliasing, hasElaborateAssign, isAssignable,\n                        isStaticArray;\n    static if (hasAliasing!T) if (!__ctfe)\n    {\n        import std.exception : doesPointTo;\n        assert(!doesPointTo(lhs, lhs), \"Swap: lhs internal pointer.\");\n        assert(!doesPointTo(rhs, rhs), \"Swap: rhs internal pointer.\");\n        assert(!doesPointTo(lhs, rhs), \"Swap: lhs points to rhs.\");\n        assert(!doesPointTo(rhs, lhs), \"Swap: rhs points to lhs.\");\n    }\n\n    static if (hasElaborateAssign!T || !isAssignable!T)\n    {\n        if (&lhs != &rhs)\n        {\n            // For structs with non-trivial assignment, move memory directly\n            ubyte[T.sizeof] t = void;\n            auto a = (cast(ubyte*) &lhs)[0 .. T.sizeof];\n            auto b = (cast(ubyte*) &rhs)[0 .. T.sizeof];\n            t[] = a[];\n            a[] = b[];\n            b[] = t[];\n        }\n    }\n    else\n    {\n        //Avoid assigning overlapping arrays. Dynamic arrays are fine, because\n        //it's their ptr and length properties which get assigned rather\n        //than their elements when assigning them, but static arrays are value\n        //types and therefore all of their elements get copied as part of\n        //assigning them, which would be assigning overlapping arrays if lhs\n        //and rhs were the same array.\n        static if (isStaticArray!T)\n        {\n            if (lhs.ptr == rhs.ptr)\n                return;\n        }\n\n        // For non-struct types, suffice to do the classic swap\n        auto tmp = lhs;\n        lhs = rhs;\n        rhs = tmp;\n    }\n}\n\n///\n@safe unittest\n{\n    // Swapping POD (plain old data) types:\n    int a = 42, b = 34;\n    swap(a, b);\n    assert(a == 34 && b == 42);\n\n    // Swapping structs with indirection:\n    static struct S { int x; char c; int[] y; }\n    S s1 = { 0, 'z', [ 1, 2 ] };\n    S s2 = { 42, 'a', [ 4, 6 ] };\n    swap(s1, s2);\n    assert(s1.x == 42);\n    assert(s1.c == 'a');\n    assert(s1.y == [ 4, 6 ]);\n\n    assert(s2.x == 0);\n    assert(s2.c == 'z');\n    assert(s2.y == [ 1, 2 ]);\n\n    // Immutables cannot be swapped:\n    immutable int imm1 = 1, imm2 = 2;\n    static assert(!__traits(compiles, swap(imm1, imm2)));\n\n    int c = imm1 + 0;\n    int d = imm2 + 0;\n    swap(c, d);\n    assert(c == 2);\n    assert(d == 1);\n}\n\n///\n@safe unittest\n{\n    // Non-copyable types can still be swapped.\n    static struct NoCopy\n    {\n        this(this) { assert(0); }\n        int n;\n        string s;\n    }\n    NoCopy nc1, nc2;\n    nc1.n = 127; nc1.s = \"abc\";\n    nc2.n = 513; nc2.s = \"uvwxyz\";\n\n    swap(nc1, nc2);\n    assert(nc1.n == 513 && nc1.s == \"uvwxyz\");\n    assert(nc2.n == 127 && nc2.s == \"abc\");\n\n    swap(nc1, nc1);\n    swap(nc2, nc2);\n    assert(nc1.n == 513 && nc1.s == \"uvwxyz\");\n    assert(nc2.n == 127 && nc2.s == \"abc\");\n\n    // Types containing non-copyable fields can also be swapped.\n    static struct NoCopyHolder\n    {\n        NoCopy noCopy;\n    }\n    NoCopyHolder h1, h2;\n    h1.noCopy.n = 31; h1.noCopy.s = \"abc\";\n    h2.noCopy.n = 65; h2.noCopy.s = null;\n\n    swap(h1, h2);\n    assert(h1.noCopy.n == 65 && h1.noCopy.s == null);\n    assert(h2.noCopy.n == 31 && h2.noCopy.s == \"abc\");\n\n    swap(h1, h1);\n    swap(h2, h2);\n    assert(h1.noCopy.n == 65 && h1.noCopy.s == null);\n    assert(h2.noCopy.n == 31 && h2.noCopy.s == \"abc\");\n\n    // Const types cannot be swapped.\n    const NoCopy const1, const2;\n    assert(const1.n == 0 && const2.n == 0);\n    static assert(!__traits(compiles, swap(const1, const2)));\n}\n\n@safe unittest\n{\n    //Bug# 4789\n    int[1] s = [1];\n    swap(s, s);\n\n    int[3] a = [1, 2, 3];\n    swap(a[1], a[2]);\n    assert(a == [1, 3, 2]);\n}\n\n@safe unittest\n{\n    static struct NoAssign\n    {\n        int i;\n        void opAssign(NoAssign) @disable;\n    }\n    auto s1 = NoAssign(1);\n    auto s2 = NoAssign(2);\n    swap(s1, s2);\n    assert(s1.i == 2);\n    assert(s2.i == 1);\n}\n\n@safe unittest\n{\n    struct S\n    {\n        const int i;\n        int i2 = 2;\n        int i3 = 3;\n    }\n    S s;\n    static assert(!__traits(compiles, swap(s, s)));\n    swap(s.i2, s.i3);\n    assert(s.i2 == 3);\n    assert(s.i3 == 2);\n}\n\n@safe unittest\n{\n    //11853\n    import std.traits : isAssignable;\n    alias T = Tuple!(int, double);\n    static assert(isAssignable!T);\n}\n\n@safe unittest\n{\n    // 12024\n    import std.datetime;\n    SysTime a, b;\n    swap(a, b);\n}\n\n@system unittest // 9975\n{\n    import std.exception : doesPointTo, mayPointTo;\n    static struct S2\n    {\n        union\n        {\n            size_t sz;\n            string s;\n        }\n    }\n    S2 a , b;\n    a.sz = -1;\n    assert(!doesPointTo(a, b));\n    assert( mayPointTo(a, b));\n    swap(a, b);\n\n    //Note: we can catch an error here, because there is no RAII in this test\n    import std.exception : assertThrown;\n    void* p, pp;\n    p = &p;\n    assertThrown!Error(move(p));\n    assertThrown!Error(move(p, pp));\n    assertThrown!Error(swap(p, pp));\n}\n\n@system unittest\n{\n    static struct A\n    {\n        int* x;\n        this(this) { x = new int; }\n    }\n    A a1, a2;\n    swap(a1, a2);\n\n    static struct B\n    {\n        int* x;\n        void opAssign(B) { x = new int; }\n    }\n    B b1, b2;\n    swap(b1, b2);\n}\n\n/// ditto\nvoid swap(T)(ref T lhs, ref T rhs)\nif (is(typeof(lhs.proxySwap(rhs))))\n{\n    lhs.proxySwap(rhs);\n}\n\n/**\nSwaps two elements in-place of a range `r`,\nspecified by their indices `i1` and `i2`.\n\nParams:\n    r  = a range with swappable elements\n    i1 = first index\n    i2 = second index\n*/\nvoid swapAt(R)(auto ref R r, size_t i1, size_t i2)\n{\n    static if (is(typeof(&r.swapAt)))\n    {\n        r.swapAt(i1, i2);\n    }\n    else static if (is(typeof(&r[i1])))\n    {\n        swap(r[i1], r[i2]);\n    }\n    else\n    {\n        if (i1 == i2) return;\n        auto t1 = r.moveAt(i1);\n        auto t2 = r.moveAt(i2);\n        r[i2] = t1;\n        r[i1] = t2;\n    }\n}\n\n///\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    auto a = [1, 2, 3];\n    a.swapAt(1, 2);\n    assert(a.equal([1, 3, 2]));\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    auto a = [4, 5, 6];\n    a.swapAt(1, 1);\n    assert(a.equal([4, 5, 6]));\n}\n\npure @safe nothrow unittest\n{\n    // test non random access ranges\n    import std.algorithm.comparison : equal;\n    import std.array : array;\n\n    char[] b = ['a', 'b', 'c'];\n    b.swapAt(1, 2);\n    assert(b.equal(['a', 'c', 'b']));\n\n    int[3] c = [1, 2, 3];\n    c.swapAt(1, 2);\n    assert(c.array.equal([1, 3, 2]));\n\n    // opIndex returns lvalue\n    struct RandomIndexType(T)\n    {\n        T payload;\n\n        @property ref auto opIndex(size_t i)\n        {\n           return payload[i];\n        }\n\n    }\n    auto d = RandomIndexType!(int[])([4, 5, 6]);\n    d.swapAt(1, 2);\n    assert(d.payload.equal([4, 6, 5]));\n\n    // custom moveAt and opIndexAssign\n    struct RandomMoveAtType(T)\n    {\n        T payload;\n\n        ElementType!T moveAt(size_t i)\n        {\n           return payload.moveAt(i);\n        }\n\n        void opIndexAssign(ElementType!T val, size_t idx)\n        {\n            payload[idx] = val;\n        }\n    }\n    auto e = RandomMoveAtType!(int[])([7, 8, 9]);\n    e.swapAt(1, 2);\n    assert(e.payload.equal([7, 9, 8]));\n\n\n    // custom swapAt\n    struct RandomSwapAtType(T)\n    {\n        T payload;\n\n        void swapAt(size_t i)\n        {\n           return payload.swapAt(i);\n        }\n    }\n    auto f = RandomMoveAtType!(int[])([10, 11, 12]);\n    swapAt(f, 1, 2);\n    assert(f.payload.equal([10, 12, 11]));\n}\n\nprivate void swapFront(R1, R2)(R1 r1, R2 r2)\nif (isInputRange!R1 && isInputRange!R2)\n{\n    static if (is(typeof(swap(r1.front, r2.front))))\n    {\n        swap(r1.front, r2.front);\n    }\n    else\n    {\n        auto t1 = moveFront(r1), t2 = moveFront(r2);\n        r1.front = move(t2);\n        r2.front = move(t1);\n    }\n}\n\n// swapRanges\n/**\nSwaps all elements of `r1` with successive elements in `r2`.\nReturns a tuple containing the remainder portions of `r1` and $(D\nr2) that were not swapped (one of them will be empty). The ranges may\nbe of different types but must have the same element type and support\nswapping.\n\nParams:\n    r1 = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n         with swappable elements\n    r2 = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n         with swappable elements\n\nReturns:\n    Tuple containing the remainder portions of r1 and r2 that were not swapped\n*/\nTuple!(InputRange1, InputRange2)\nswapRanges(InputRange1, InputRange2)(InputRange1 r1, InputRange2 r2)\nif (hasSwappableElements!InputRange1 && hasSwappableElements!InputRange2\n    && is(ElementType!InputRange1 == ElementType!InputRange2))\n{\n    for (; !r1.empty && !r2.empty; r1.popFront(), r2.popFront())\n    {\n        swap(r1.front, r2.front);\n    }\n    return tuple(r1, r2);\n}\n\n///\n@safe unittest\n{\n    import std.range : empty;\n    int[] a = [ 100, 101, 102, 103 ];\n    int[] b = [ 0, 1, 2, 3 ];\n    auto c = swapRanges(a[1 .. 3], b[2 .. 4]);\n    assert(c[0].empty && c[1].empty);\n    assert(a == [ 100, 2, 3, 103 ]);\n    assert(b == [ 0, 1, 101, 102 ]);\n}\n\n/**\nInitializes each element of `range` with `value`.\nAssumes that the elements of the range are uninitialized.\nThis is of interest for structs that\ndefine copy constructors (for all other types, $(LREF fill) and\nuninitializedFill are equivalent).\n\nParams:\n        range = An\n                $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n                that exposes references to its elements and has assignable\n                elements\n        value = Assigned to each element of range\n\nSee_Also:\n        $(LREF fill)\n        $(LREF initializeAll)\n */\nvoid uninitializedFill(Range, Value)(Range range, Value value)\nif (isInputRange!Range && hasLvalueElements!Range && is(typeof(range.front = value)))\n{\n    import std.traits : hasElaborateAssign;\n\n    alias T = ElementType!Range;\n    static if (hasElaborateAssign!T)\n    {\n        import std.conv : emplaceRef;\n\n        // Must construct stuff by the book\n        for (; !range.empty; range.popFront())\n            emplaceRef!T(range.front, value);\n    }\n    else\n        // Doesn't matter whether fill is initialized or not\n        return fill(range, value);\n}\n\n///\nnothrow @system unittest\n{\n    import core.stdc.stdlib : malloc, free;\n\n    auto s = (cast(int*) malloc(5 * int.sizeof))[0 .. 5];\n    uninitializedFill(s, 42);\n    assert(s == [ 42, 42, 42, 42, 42 ]);\n\n    scope(exit) free(s.ptr);\n}\n"
  },
  {
    "path": "libphobos/src/std/algorithm/package.d",
    "content": "// Written in the D programming language.\n\n/**\nThis package implements generic algorithms oriented towards the processing of\nsequences. Sequences processed by these functions define range-based\ninterfaces.  See also $(MREF_ALTTEXT Reference on ranges, std, range) and\n$(HTTP ddili.org/ders/d.en/ranges.html, tutorial on ranges).\n\n$(SCRIPT inhibitQuickIndex = 1;)\n\nAlgorithms are categorized into the following submodules:\n\n$(DIVC quickindex,\n$(BOOKTABLE ,\n$(TR $(TH Submodule) $(TH Functions)\n)\n$(TR\n     $(TDNW $(SUBMODULE Searching, searching))\n     $(TD\n        $(SUBREF searching, all)\n        $(SUBREF searching, any)\n        $(SUBREF searching, balancedParens)\n        $(SUBREF searching, boyerMooreFinder)\n        $(SUBREF searching, canFind)\n        $(SUBREF searching, commonPrefix)\n        $(SUBREF searching, count)\n        $(SUBREF searching, countUntil)\n        $(SUBREF searching, endsWith)\n        $(SUBREF searching, find)\n        $(SUBREF searching, findAdjacent)\n        $(SUBREF searching, findAmong)\n        $(SUBREF searching, findSkip)\n        $(SUBREF searching, findSplit)\n        $(SUBREF searching, findSplitAfter)\n        $(SUBREF searching, findSplitBefore)\n        $(SUBREF searching, minCount)\n        $(SUBREF searching, maxCount)\n        $(SUBREF searching, minElement)\n        $(SUBREF searching, maxElement)\n        $(SUBREF searching, minIndex)\n        $(SUBREF searching, maxIndex)\n        $(SUBREF searching, minPos)\n        $(SUBREF searching, maxPos)\n        $(SUBREF searching, skipOver)\n        $(SUBREF searching, startsWith)\n        $(SUBREF searching, until)\n    )\n)\n$(TR\n    $(TDNW $(SUBMODULE Comparison, comparison))\n    $(TD\n        $(SUBREF comparison, among)\n        $(SUBREF comparison, castSwitch)\n        $(SUBREF comparison, clamp)\n        $(SUBREF comparison, cmp)\n        $(SUBREF comparison, either)\n        $(SUBREF comparison, equal)\n        $(SUBREF comparison, isPermutation)\n        $(SUBREF comparison, isSameLength)\n        $(SUBREF comparison, levenshteinDistance)\n        $(SUBREF comparison, levenshteinDistanceAndPath)\n        $(SUBREF comparison, max)\n        $(SUBREF comparison, min)\n        $(SUBREF comparison, mismatch)\n        $(SUBREF comparison, predSwitch)\n    )\n)\n$(TR\n    $(TDNW $(SUBMODULE Iteration, iteration))\n    $(TD\n        $(SUBREF iteration, cache)\n        $(SUBREF iteration, cacheBidirectional)\n        $(SUBREF iteration, chunkBy)\n        $(SUBREF iteration, cumulativeFold)\n        $(SUBREF iteration, each)\n        $(SUBREF iteration, filter)\n        $(SUBREF iteration, filterBidirectional)\n        $(SUBREF iteration, fold)\n        $(SUBREF iteration, group)\n        $(SUBREF iteration, joiner)\n        $(SUBREF iteration, map)\n        $(SUBREF iteration, mean)\n        $(SUBREF iteration, permutations)\n        $(SUBREF iteration, reduce)\n        $(SUBREF iteration, splitter)\n        $(SUBREF iteration, substitute)\n        $(SUBREF iteration, sum)\n        $(SUBREF iteration, uniq)\n    )\n)\n$(TR\n    $(TDNW $(SUBMODULE Sorting, sorting))\n    $(TD\n        $(SUBREF sorting, completeSort)\n        $(SUBREF sorting, isPartitioned)\n        $(SUBREF sorting, isSorted)\n        $(SUBREF sorting, isStrictlyMonotonic)\n        $(SUBREF sorting, ordered)\n        $(SUBREF sorting, strictlyOrdered)\n        $(SUBREF sorting, makeIndex)\n        $(SUBREF sorting, merge)\n        $(SUBREF sorting, multiSort)\n        $(SUBREF sorting, nextEvenPermutation)\n        $(SUBREF sorting, nextPermutation)\n        $(SUBREF sorting, partialSort)\n        $(SUBREF sorting, partition)\n        $(SUBREF sorting, partition3)\n        $(SUBREF sorting, schwartzSort)\n        $(SUBREF sorting, sort)\n        $(SUBREF sorting, topN)\n        $(SUBREF sorting, topNCopy)\n        $(SUBREF sorting, topNIndex)\n    )\n)\n$(TR\n    $(TDNW Set operations $(BR)($(SUBMODULE setops, setops)))\n    $(TD\n        $(SUBREF setops, cartesianProduct)\n        $(SUBREF setops, largestPartialIntersection)\n        $(SUBREF setops, largestPartialIntersectionWeighted)\n        $(SUBREF setops, multiwayMerge)\n        $(SUBREF setops, multiwayUnion)\n        $(SUBREF setops, setDifference)\n        $(SUBREF setops, setIntersection)\n        $(SUBREF setops, setSymmetricDifference)\n    )\n)\n$(TR\n    $(TDNW $(SUBMODULE Mutation, mutation))\n    $(TD\n        $(SUBREF mutation, bringToFront)\n        $(SUBREF mutation, copy)\n        $(SUBREF mutation, fill)\n        $(SUBREF mutation, initializeAll)\n        $(SUBREF mutation, move)\n        $(SUBREF mutation, moveAll)\n        $(SUBREF mutation, moveSome)\n        $(SUBREF mutation, moveEmplace)\n        $(SUBREF mutation, moveEmplaceAll)\n        $(SUBREF mutation, moveEmplaceSome)\n        $(SUBREF mutation, remove)\n        $(SUBREF mutation, reverse)\n        $(SUBREF mutation, strip)\n        $(SUBREF mutation, stripLeft)\n        $(SUBREF mutation, stripRight)\n        $(SUBREF mutation, swap)\n        $(SUBREF mutation, swapRanges)\n        $(SUBREF mutation, uninitializedFill)\n    )\n)\n))\n\nMany functions in this package are parameterized with a $(GLOSSARY predicate).\nThe predicate may be any suitable callable type\n(a function, a delegate, a $(GLOSSARY functor), or a lambda), or a\ncompile-time string. The string may consist of $(B any) legal D\nexpression that uses the symbol `a` (for unary functions) or the\nsymbols `a` and `b` (for binary functions). These names will NOT\ninterfere with other homonym symbols in user code because they are\nevaluated in a different context. The default for all binary\ncomparison predicates is `\"a == b\"` for unordered operations and\n`\"a < b\"` for ordered operations.\n\nExample:\n\n----\nint[] a = ...;\nstatic bool greater(int a, int b)\n{\n    return a > b;\n}\nsort!greater(a);           // predicate as alias\nsort!((a, b) => a > b)(a); // predicate as a lambda.\nsort!\"a > b\"(a);           // predicate as string\n                           // (no ambiguity with array name)\nsort(a);                   // no predicate, \"a < b\" is implicit\n----\n\nMacros:\nSUBMODULE = $(MREF_ALTTEXT $1, std, algorithm, $2)\nSUBREF = $(REF_ALTTEXT $(TT $2), $2, std, algorithm, $1)$(NBSP)\n\nCopyright: Andrei Alexandrescu 2008-.\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n\nSource: $(PHOBOSSRC std/algorithm/package.d)\n */\nmodule std.algorithm;\n\npublic import std.algorithm.comparison;\npublic import std.algorithm.iteration;\npublic import std.algorithm.mutation;\npublic import std.algorithm.searching;\npublic import std.algorithm.setops;\npublic import std.algorithm.sorting;\n\nstatic import std.functional;\n"
  },
  {
    "path": "libphobos/src/std/algorithm/searching.d",
    "content": "// Written in the D programming language.\n/**\nThis is a submodule of $(MREF std, algorithm).\nIt contains generic searching algorithms.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE Cheat Sheet,\n$(TR $(TH Function Name) $(TH Description))\n$(T2 all,\n        `all!\"a > 0\"([1, 2, 3, 4])` returns `true` because all elements\n        are positive)\n$(T2 any,\n        `any!\"a > 0\"([1, 2, -3, -4])` returns `true` because at least one\n        element is positive)\n$(T2 balancedParens,\n        `balancedParens(\"((1 + 1) / 2)\")` returns `true` because the\n        string has balanced parentheses.)\n$(T2 boyerMooreFinder,\n        `find(\"hello world\", boyerMooreFinder(\"or\"))` returns `\"orld\"`\n        using the $(LINK2 https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm,\n        Boyer-Moore _algorithm).)\n$(T2 canFind,\n        `canFind(\"hello world\", \"or\")` returns `true`.)\n$(T2 count,\n        Counts elements that are equal to a specified value or satisfy a\n        predicate.  `count([1, 2, 1], 1)` returns `2` and\n        `count!\"a < 0\"([1, -3, 0])` returns `1`.)\n$(T2 countUntil,\n        `countUntil(a, b)` returns the number of steps taken in `a` to\n        reach `b`; for example, `countUntil(\"hello!\", \"o\")` returns\n        `4`.)\n$(T2 commonPrefix,\n        `commonPrefix(\"parakeet\", \"parachute\")` returns `\"para\"`.)\n$(T2 endsWith,\n        `endsWith(\"rocks\", \"ks\")` returns `true`.)\n$(T2 find,\n        `find(\"hello world\", \"or\")` returns `\"orld\"` using linear search.\n        (For binary search refer to $(REF SortedRange, std,range).))\n$(T2 findAdjacent,\n        `findAdjacent([1, 2, 3, 3, 4])` returns the subrange starting with\n        two equal adjacent elements, i.e. `[3, 3, 4]`.)\n$(T2 findAmong,\n        `findAmong(\"abcd\", \"qcx\")` returns `\"cd\"` because `'c'` is\n        among `\"qcx\"`.)\n$(T2 findSkip,\n        If `a = \"abcde\"`, then `findSkip(a, \"x\")` returns `false` and\n        leaves `a` unchanged, whereas `findSkip(a, \"c\")` advances `a`\n        to `\"de\"` and returns `true`.)\n$(T2 findSplit,\n        `findSplit(\"abcdefg\", \"de\")` returns the three ranges `\"abc\"`,\n        `\"de\"`, and `\"fg\"`.)\n$(T2 findSplitAfter,\n        `findSplitAfter(\"abcdefg\", \"de\")` returns the two ranges\n        `\"abcde\"` and `\"fg\"`.)\n$(T2 findSplitBefore,\n        `findSplitBefore(\"abcdefg\", \"de\")` returns the two ranges `\"abc\"`\n        and `\"defg\"`.)\n$(T2 minCount,\n        `minCount([2, 1, 1, 4, 1])` returns `tuple(1, 3)`.)\n$(T2 maxCount,\n        `maxCount([2, 4, 1, 4, 1])` returns `tuple(4, 2)`.)\n$(T2 minElement,\n        Selects the minimal element of a range.\n        `minElement([3, 4, 1, 2])` returns `1`.)\n$(T2 maxElement,\n        Selects the maximal element of a range.\n        `maxElement([3, 4, 1, 2])` returns `4`.)\n$(T2 minIndex,\n        Index of the minimal element of a range.\n        `minElement([3, 4, 1, 2])` returns `2`.)\n$(T2 maxIndex,\n        Index of the maximal element of a range.\n        `maxElement([3, 4, 1, 2])` returns `1`.)\n$(T2 minPos,\n        `minPos([2, 3, 1, 3, 4, 1])` returns the subrange `[1, 3, 4, 1]`,\n        i.e., positions the range at the first occurrence of its minimal\n        element.)\n$(T2 maxPos,\n        `maxPos([2, 3, 1, 3, 4, 1])` returns the subrange `[4, 1]`,\n        i.e., positions the range at the first occurrence of its maximal\n        element.)\n$(T2 skipOver,\n        Assume `a = \"blah\"`. Then `skipOver(a, \"bi\")` leaves `a`\n        unchanged and returns `false`, whereas `skipOver(a, \"bl\")`\n        advances `a` to refer to `\"ah\"` and returns `true`.)\n$(T2 startsWith,\n        `startsWith(\"hello, world\", \"hello\")` returns `true`.)\n$(T2 until,\n        Lazily iterates a range until a specific value is found.)\n)\n\nCopyright: Andrei Alexandrescu 2008-.\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n\nSource: $(PHOBOSSRC std/algorithm/searching.d)\n\nMacros:\nT2=$(TR $(TDNW $(LREF $1)) $(TD $+))\n */\nmodule std.algorithm.searching;\n\n// FIXME\nimport std.functional; // : unaryFun, binaryFun;\nimport std.range.primitives;\nimport std.traits;\n// FIXME\nimport std.typecons; // : Tuple, Flag, Yes, No;\n\n/++\nChecks if $(I _all) of the elements verify `pred`.\n +/\ntemplate all(alias pred = \"a\")\n{\n    /++\n    Returns `true` if and only if $(I _all) values `v` found in the\n    input range `range` satisfy the predicate `pred`.\n    Performs (at most) $(BIGOH range.length) evaluations of `pred`.\n     +/\n    bool all(Range)(Range range)\n    if (isInputRange!Range && is(typeof(unaryFun!pred(range.front))))\n    {\n        import std.functional : not;\n\n        return find!(not!(unaryFun!pred))(range).empty;\n    }\n}\n\n///\n@safe unittest\n{\n    assert( all!\"a & 1\"([1, 3, 5, 7, 9]));\n    assert(!all!\"a & 1\"([1, 2, 3, 5, 7, 9]));\n}\n\n/++\n`all` can also be used without a predicate, if its items can be\nevaluated to true or false in a conditional statement. This can be a\nconvenient way to quickly evaluate that $(I _all) of the elements of a range\nare true.\n +/\n@safe unittest\n{\n    int[3] vals = [5, 3, 18];\n    assert( all(vals[]));\n}\n\n@safe unittest\n{\n    int x = 1;\n    assert(all!(a => a > x)([2, 3]));\n}\n\n/++\nChecks if $(I _any) of the elements verifies `pred`.\n`!any` can be used to verify that $(I none) of the elements verify\n`pred`.\nThis is sometimes called `exists` in other languages.\n +/\ntemplate any(alias pred = \"a\")\n{\n    /++\n    Returns `true` if and only if $(I _any) value `v` found in the\n    input range `range` satisfies the predicate `pred`.\n    Performs (at most) $(BIGOH range.length) evaluations of `pred`.\n     +/\n    bool any(Range)(Range range)\n    if (isInputRange!Range && is(typeof(unaryFun!pred(range.front))))\n    {\n        return !find!pred(range).empty;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.ascii : isWhite;\n    assert( all!(any!isWhite)([\"a a\", \"b b\"]));\n    assert(!any!(all!isWhite)([\"a a\", \"b b\"]));\n}\n\n/++\n`any` can also be used without a predicate, if its items can be\nevaluated to true or false in a conditional statement. `!any` can be a\nconvenient way to quickly test that $(I none) of the elements of a range\nevaluate to true.\n +/\n@safe unittest\n{\n    int[3] vals1 = [0, 0, 0];\n    assert(!any(vals1[])); //none of vals1 evaluate to true\n\n    int[3] vals2 = [2, 0, 2];\n    assert( any(vals2[]));\n    assert(!all(vals2[]));\n\n    int[3] vals3 = [3, 3, 3];\n    assert( any(vals3[]));\n    assert( all(vals3[]));\n}\n\n@safe unittest\n{\n    auto a = [ 1, 2, 0, 4 ];\n    assert(any!\"a == 2\"(a));\n}\n\n// balancedParens\n/**\nChecks whether `r` has \"balanced parentheses\", i.e. all instances\nof `lPar` are closed by corresponding instances of `rPar`. The\nparameter `maxNestingLevel` controls the nesting level allowed. The\nmost common uses are the default or `0`. In the latter case, no\nnesting is allowed.\n\nParams:\n    r = The range to check.\n    lPar = The element corresponding with a left (opening) parenthesis.\n    rPar = The element corresponding with a right (closing) parenthesis.\n    maxNestingLevel = The maximum allowed nesting level.\n\nReturns:\n    true if the given range has balanced parenthesis within the given maximum\n    nesting level; false otherwise.\n*/\nbool balancedParens(Range, E)(Range r, E lPar, E rPar,\n        size_t maxNestingLevel = size_t.max)\nif (isInputRange!(Range) && is(typeof(r.front == lPar)))\n{\n    size_t count;\n\n    static if (is(Unqual!(ElementEncodingType!Range) == Unqual!E) && isNarrowString!Range)\n    {\n        import std.utf : byCodeUnit;\n        auto rn = r.byCodeUnit;\n    }\n    else\n    {\n        alias rn = r;\n    }\n\n    for (; !rn.empty; rn.popFront())\n    {\n        if (rn.front == lPar)\n        {\n            if (count > maxNestingLevel) return false;\n            ++count;\n        }\n        else if (rn.front == rPar)\n        {\n            if (!count) return false;\n            --count;\n        }\n    }\n    return count == 0;\n}\n\n///\n@safe pure unittest\n{\n    auto s = \"1 + (2 * (3 + 1 / 2)\";\n    assert(!balancedParens(s, '(', ')'));\n    s = \"1 + (2 * (3 + 1) / 2)\";\n    assert(balancedParens(s, '(', ')'));\n    s = \"1 + (2 * (3 + 1) / 2)\";\n    assert(!balancedParens(s, '(', ')', 0));\n    s = \"1 + (2 * 3 + 1) / (2 - 5)\";\n    assert(balancedParens(s, '(', ')', 0));\n    s = \"f(x) = ⌈x⌉\";\n    assert(balancedParens(s, '⌈', '⌉'));\n}\n\n/**\n * Sets up Boyer-Moore matching for use with `find` below.\n * By default, elements are compared for equality.\n *\n * `BoyerMooreFinder` allocates GC memory.\n *\n * Params:\n * pred = Predicate used to compare elements.\n * needle = A random-access range with length and slicing.\n *\n * Returns:\n * An instance of `BoyerMooreFinder` that can be used with `find()` to\n * invoke the Boyer-Moore matching algorithm for finding of `needle` in a\n * given haystack.\n */\nstruct BoyerMooreFinder(alias pred, Range)\n{\nprivate:\n    size_t[] skip;                              // GC allocated\n    ptrdiff_t[ElementType!(Range)] occ;         // GC allocated\n    Range needle;\n\n    ptrdiff_t occurrence(ElementType!(Range) c) scope\n    {\n        auto p = c in occ;\n        return p ? *p : -1;\n    }\n\n/*\nThis helper function checks whether the last \"portion\" bytes of\n\"needle\" (which is \"nlen\" bytes long) exist within the \"needle\" at\noffset \"offset\" (counted from the end of the string), and whether the\ncharacter preceding \"offset\" is not a match.  Notice that the range\nbeing checked may reach beyond the beginning of the string. Such range\nis ignored.\n */\n    static bool needlematch(R)(R needle,\n                              size_t portion, size_t offset)\n    {\n        import std.algorithm.comparison : equal;\n        ptrdiff_t virtual_begin = needle.length - offset - portion;\n        ptrdiff_t ignore = 0;\n        if (virtual_begin < 0)\n        {\n            ignore = -virtual_begin;\n            virtual_begin = 0;\n        }\n        if (virtual_begin > 0\n            && needle[virtual_begin - 1] == needle[$ - portion - 1])\n            return 0;\n\n        immutable delta = portion - ignore;\n        return equal(needle[needle.length - delta .. needle.length],\n                needle[virtual_begin .. virtual_begin + delta]);\n    }\n\npublic:\n    ///\n    this(Range needle)\n    {\n        if (!needle.length) return;\n        this.needle = needle;\n        /* Populate table with the analysis of the needle */\n        /* But ignoring the last letter */\n        foreach (i, n ; needle[0 .. $ - 1])\n        {\n            this.occ[n] = i;\n        }\n        /* Preprocess #2: init skip[] */\n        /* Note: This step could be made a lot faster.\n         * A simple implementation is shown here. */\n        this.skip = new size_t[needle.length];\n        foreach (a; 0 .. needle.length)\n        {\n            size_t value = 0;\n            while (value < needle.length\n                   && !needlematch(needle, a, value))\n            {\n                ++value;\n            }\n            this.skip[needle.length - a - 1] = value;\n        }\n    }\n\n    ///\n    Range beFound(Range haystack) scope\n    {\n        import std.algorithm.comparison : max;\n\n        if (!needle.length) return haystack;\n        if (needle.length > haystack.length) return haystack[$ .. $];\n        /* Search: */\n        immutable limit = haystack.length - needle.length;\n        for (size_t hpos = 0; hpos <= limit; )\n        {\n            size_t npos = needle.length - 1;\n            while (pred(needle[npos], haystack[npos+hpos]))\n            {\n                if (npos == 0) return haystack[hpos .. $];\n                --npos;\n            }\n            hpos += max(skip[npos], cast(sizediff_t) npos - occurrence(haystack[npos+hpos]));\n        }\n        return haystack[$ .. $];\n    }\n\n    ///\n    @property size_t length()\n    {\n        return needle.length;\n    }\n\n    ///\n    alias opDollar = length;\n}\n\n/// Ditto\nBoyerMooreFinder!(binaryFun!(pred), Range) boyerMooreFinder\n(alias pred = \"a == b\", Range)\n(Range needle)\nif ((isRandomAccessRange!(Range) && hasSlicing!Range) || isSomeString!Range)\n{\n    return typeof(return)(needle);\n}\n\n///\n@safe pure nothrow unittest\n{\n    auto bmFinder = boyerMooreFinder(\"TG\");\n\n    string r = \"TAGTGCCTGA\";\n    // search for the first match in the haystack r\n    r = bmFinder.beFound(r);\n    assert(r == \"TGCCTGA\");\n\n    // continue search in haystack\n    r = bmFinder.beFound(r[2 .. $]);\n    assert(r == \"TGA\");\n}\n\n/**\nReturns the common prefix of two ranges.\n\nParams:\n    pred = The predicate to use in comparing elements for commonality. Defaults\n        to equality `\"a == b\"`.\n\n    r1 = A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) of\n        elements.\n\n    r2 = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of\n        elements.\n\nReturns:\nA slice of `r1` which contains the characters that both ranges start with,\nif the first argument is a string; otherwise, the same as the result of\n`takeExactly(r1, n)`, where `n` is the number of elements in the common\nprefix of both ranges.\n\nSee_Also:\n    $(REF takeExactly, std,range)\n */\nauto commonPrefix(alias pred = \"a == b\", R1, R2)(R1 r1, R2 r2)\nif (isForwardRange!R1 && isInputRange!R2 &&\n    !isNarrowString!R1 &&\n    is(typeof(binaryFun!pred(r1.front, r2.front))))\n{\n    import std.algorithm.comparison : min;\n    static if (isRandomAccessRange!R1 && isRandomAccessRange!R2 &&\n               hasLength!R1 && hasLength!R2 &&\n               hasSlicing!R1)\n    {\n        immutable limit = min(r1.length, r2.length);\n        foreach (i; 0 .. limit)\n        {\n            if (!binaryFun!pred(r1[i], r2[i]))\n            {\n                return r1[0 .. i];\n            }\n        }\n        return r1[0 .. limit];\n    }\n    else\n    {\n        import std.range : takeExactly;\n        auto result = r1.save;\n        size_t i = 0;\n        for (;\n             !r1.empty && !r2.empty && binaryFun!pred(r1.front, r2.front);\n             ++i, r1.popFront(), r2.popFront())\n        {}\n        return takeExactly(result, i);\n    }\n}\n\n///\n@safe unittest\n{\n    assert(commonPrefix(\"hello, world\", \"hello, there\") == \"hello, \");\n}\n\n/// ditto\nauto commonPrefix(alias pred, R1, R2)(R1 r1, R2 r2)\nif (isNarrowString!R1 && isInputRange!R2 &&\n    is(typeof(binaryFun!pred(r1.front, r2.front))))\n{\n    import std.utf : decode;\n\n    auto result = r1.save;\n    immutable len = r1.length;\n    size_t i = 0;\n\n    for (size_t j = 0; i < len && !r2.empty; r2.popFront(), i = j)\n    {\n        immutable f = decode(r1, j);\n        if (!binaryFun!pred(f, r2.front))\n            break;\n    }\n\n    return result[0 .. i];\n}\n\n/// ditto\nauto commonPrefix(R1, R2)(R1 r1, R2 r2)\nif (isNarrowString!R1 && isInputRange!R2 && !isNarrowString!R2 &&\n    is(typeof(r1.front == r2.front)))\n{\n    return commonPrefix!\"a == b\"(r1, r2);\n}\n\n/// ditto\nauto commonPrefix(R1, R2)(R1 r1, R2 r2)\nif (isNarrowString!R1 && isNarrowString!R2)\n{\n    import std.algorithm.comparison : min;\n\n    static if (ElementEncodingType!R1.sizeof == ElementEncodingType!R2.sizeof)\n    {\n        import std.utf : stride, UTFException;\n\n        immutable limit = min(r1.length, r2.length);\n        for (size_t i = 0; i < limit;)\n        {\n            immutable codeLen = stride(r1, i);\n            size_t j = 0;\n\n            for (; j < codeLen && i < limit; ++i, ++j)\n            {\n                if (r1[i] != r2[i])\n                    return r1[0 .. i - j];\n            }\n\n            if (i == limit && j < codeLen)\n                throw new UTFException(\"Invalid UTF-8 sequence\", i);\n        }\n        return r1[0 .. limit];\n    }\n    else\n        return commonPrefix!\"a == b\"(r1, r2);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter;\n    import std.conv : to;\n    import std.exception : assertThrown;\n    import std.meta : AliasSeq;\n    import std.range;\n    import std.utf : UTFException;\n\n    assert(commonPrefix([1, 2, 3], [1, 2, 3, 4, 5]) == [1, 2, 3]);\n    assert(commonPrefix([1, 2, 3, 4, 5], [1, 2, 3]) == [1, 2, 3]);\n    assert(commonPrefix([1, 2, 3, 4], [1, 2, 3, 4]) == [1, 2, 3, 4]);\n    assert(commonPrefix([1, 2, 3], [7, 2, 3, 4, 5]).empty);\n    assert(commonPrefix([7, 2, 3, 4, 5], [1, 2, 3]).empty);\n    assert(commonPrefix([1, 2, 3], cast(int[]) null).empty);\n    assert(commonPrefix(cast(int[]) null, [1, 2, 3]).empty);\n    assert(commonPrefix(cast(int[]) null, cast(int[]) null).empty);\n\n    static foreach (S; AliasSeq!(char[], const(char)[], string,\n                          wchar[], const(wchar)[], wstring,\n                          dchar[], const(dchar)[], dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {\n            assert(commonPrefix(to!S(\"\"), to!T(\"\")).empty);\n            assert(commonPrefix(to!S(\"\"), to!T(\"hello\")).empty);\n            assert(commonPrefix(to!S(\"hello\"), to!T(\"\")).empty);\n            assert(commonPrefix(to!S(\"hello, world\"), to!T(\"hello, there\")) == to!S(\"hello, \"));\n            assert(commonPrefix(to!S(\"hello, there\"), to!T(\"hello, world\")) == to!S(\"hello, \"));\n            assert(commonPrefix(to!S(\"hello, \"), to!T(\"hello, world\")) == to!S(\"hello, \"));\n            assert(commonPrefix(to!S(\"hello, world\"), to!T(\"hello, \")) == to!S(\"hello, \"));\n            assert(commonPrefix(to!S(\"hello, world\"), to!T(\"hello, world\")) == to!S(\"hello, world\"));\n\n            //Bug# 8890\n            assert(commonPrefix(to!S(\"Пиво\"), to!T(\"Пони\"))== to!S(\"П\"));\n            assert(commonPrefix(to!S(\"Пони\"), to!T(\"Пиво\"))== to!S(\"П\"));\n            assert(commonPrefix(to!S(\"Пиво\"), to!T(\"Пиво\"))== to!S(\"Пиво\"));\n            assert(commonPrefix(to!S(\"\\U0010FFFF\\U0010FFFB\\U0010FFFE\"),\n                                to!T(\"\\U0010FFFF\\U0010FFFB\\U0010FFFC\")) == to!S(\"\\U0010FFFF\\U0010FFFB\"));\n            assert(commonPrefix(to!S(\"\\U0010FFFF\\U0010FFFB\\U0010FFFC\"),\n                                to!T(\"\\U0010FFFF\\U0010FFFB\\U0010FFFE\")) == to!S(\"\\U0010FFFF\\U0010FFFB\"));\n            assert(commonPrefix!\"a != b\"(to!S(\"Пиво\"), to!T(\"онво\")) == to!S(\"Пи\"));\n            assert(commonPrefix!\"a != b\"(to!S(\"онво\"), to!T(\"Пиво\")) == to!S(\"он\"));\n        }\n\n        static assert(is(typeof(commonPrefix(to!S(\"Пиво\"), filter!\"true\"(\"Пони\"))) == S));\n        assert(equal(commonPrefix(to!S(\"Пиво\"), filter!\"true\"(\"Пони\")), to!S(\"П\")));\n\n        static assert(is(typeof(commonPrefix(filter!\"true\"(\"Пиво\"), to!S(\"Пони\"))) ==\n                      typeof(takeExactly(filter!\"true\"(\"П\"), 1))));\n        assert(equal(commonPrefix(filter!\"true\"(\"Пиво\"), to!S(\"Пони\")), takeExactly(filter!\"true\"(\"П\"), 1)));\n    }\n\n    assertThrown!UTFException(commonPrefix(\"\\U0010FFFF\\U0010FFFB\", \"\\U0010FFFF\\U0010FFFB\"[0 .. $ - 1]));\n\n    assert(commonPrefix(\"12345\"d, [49, 50, 51, 60, 60]) == \"123\"d);\n    assert(commonPrefix([49, 50, 51, 60, 60], \"12345\" ) == [49, 50, 51]);\n    assert(commonPrefix([49, 50, 51, 60, 60], \"12345\"d) == [49, 50, 51]);\n\n    assert(commonPrefix!\"a == ('0' + b)\"(\"12345\" , [1, 2, 3, 9, 9]) == \"123\");\n    assert(commonPrefix!\"a == ('0' + b)\"(\"12345\"d, [1, 2, 3, 9, 9]) == \"123\"d);\n    assert(commonPrefix!\"('0' + a) == b\"([1, 2, 3, 9, 9], \"12345\" ) == [1, 2, 3]);\n    assert(commonPrefix!\"('0' + a) == b\"([1, 2, 3, 9, 9], \"12345\"d) == [1, 2, 3]);\n}\n\n// count\n/**\nThe first version counts the number of elements `x` in `r` for\nwhich `pred(x, value)` is `true`. `pred` defaults to\nequality. Performs $(BIGOH haystack.length) evaluations of `pred`.\n\nThe second version returns the number of times `needle` occurs in\n`haystack`. Throws an exception if `needle.empty`, as the _count\nof the empty range in any range would be infinite. Overlapped counts\nare not considered, for example `count(\"aaa\", \"aa\")` is `1`, not\n`2`.\n\nThe third version counts the elements for which `pred(x)` is $(D\ntrue). Performs $(BIGOH haystack.length) evaluations of `pred`.\n\nThe fourth version counts the number of elements in a range. It is\nan optimization for the third version: if the given range has the\n`length` property the count is returned right away, otherwise\nperforms $(BIGOH haystack.length) to walk the range.\n\nNote: Regardless of the overload, `count` will not accept\ninfinite ranges for `haystack`.\n\nParams:\n    pred = The predicate to evaluate.\n    haystack = The range to _count.\n    needle = The element or sub-range to _count in the `haystack`.\n\nReturns:\n    The number of positions in the `haystack` for which `pred` returned true.\n*/\nsize_t count(alias pred = \"a == b\", Range, E)(Range haystack, E needle)\nif (isInputRange!Range && !isInfinite!Range &&\n    is(typeof(binaryFun!pred(haystack.front, needle)) : bool))\n{\n    bool pred2(ElementType!Range a) { return binaryFun!pred(a, needle); }\n    return count!pred2(haystack);\n}\n\n///\n@safe unittest\n{\n    import std.uni : toLower;\n\n    // count elements in range\n    int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];\n    assert(count(a) == 9);\n    assert(count(a, 2) == 3);\n    assert(count!(\"a > b\")(a, 2) == 5);\n    // count range in range\n    assert(count(\"abcadfabf\", \"ab\") == 2);\n    assert(count(\"ababab\", \"abab\") == 1);\n    assert(count(\"ababab\", \"abx\") == 0);\n    // fuzzy count range in range\n    assert(count!((a, b) => toLower(a) == toLower(b))(\"AbcAdFaBf\", \"ab\") == 2);\n    // count predicate in range\n    assert(count!(\"a > 1\")(a) == 8);\n}\n\n@safe unittest\n{\n    import std.conv : text;\n\n    int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];\n    assert(count(a, 2) == 3, text(count(a, 2)));\n    assert(count!(\"a > b\")(a, 2) == 5, text(count!(\"a > b\")(a, 2)));\n\n    // check strings\n    assert(count(\"日本語\")  == 3);\n    assert(count(\"日本語\"w) == 3);\n    assert(count(\"日本語\"d) == 3);\n\n    assert(count!(\"a == '日'\")(\"日本語\")  == 1);\n    assert(count!(\"a == '本'\")(\"日本語\"w) == 1);\n    assert(count!(\"a == '語'\")(\"日本語\"d) == 1);\n}\n\n@safe unittest\n{\n    string s = \"This is a fofofof list\";\n    string sub = \"fof\";\n    assert(count(s, sub) == 2);\n}\n\n/// Ditto\nsize_t count(alias pred = \"a == b\", R1, R2)(R1 haystack, R2 needle)\nif (isForwardRange!R1 && !isInfinite!R1 &&\n    isForwardRange!R2 &&\n    is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool))\n{\n    assert(!needle.empty, \"Cannot count occurrences of an empty range\");\n\n    static if (isInfinite!R2)\n    {\n        //Note: This is the special case of looking for an infinite inside a finite...\n        //\"How many instances of the Fibonacci sequence can you count in [1, 2, 3]?\" - \"None.\"\n        return 0;\n    }\n    else\n    {\n        size_t result;\n        //Note: haystack is not saved, because findskip is designed to modify it\n        for ( ; findSkip!pred(haystack, needle.save) ; ++result)\n        {}\n        return result;\n    }\n}\n\n/// Ditto\nsize_t count(alias pred, R)(R haystack)\nif (isInputRange!R && !isInfinite!R &&\n    is(typeof(unaryFun!pred(haystack.front)) : bool))\n{\n    size_t result;\n    alias T = ElementType!R; //For narrow strings forces dchar iteration\n    foreach (T elem; haystack)\n        if (unaryFun!pred(elem)) ++result;\n    return result;\n}\n\n/// Ditto\nsize_t count(R)(R haystack)\nif (isInputRange!R && !isInfinite!R)\n{\n    return walkLength(haystack);\n}\n\n@safe unittest\n{\n    int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];\n    assert(count!(\"a == 3\")(a) == 2);\n    assert(count(\"日本語\") == 3);\n}\n\n// Issue 11253\n@safe nothrow unittest\n{\n    assert([1, 2, 3].count([2, 3]) == 1);\n}\n\n/++\n    Counts elements in the given\n    $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n    until the given predicate is true for one of the given `needles`.\n\n    Params:\n        pred = The predicate for determining when to stop counting.\n        haystack = The\n            $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to be\n            counted.\n        needles = Either a single element, or a\n            $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n            of elements, to be evaluated in turn against each\n            element in `haystack` under the given predicate.\n\n    Returns: The number of elements which must be popped from the front of\n    `haystack` before reaching an element for which\n    `startsWith!pred(haystack, needles)` is `true`. If\n    `startsWith!pred(haystack, needles)` is not `true` for any element in\n    `haystack`, then `-1` is returned. If only `pred` is provided,\n    `pred(haystack)` is tested for each element.\n\n    See_Also: $(REF indexOf, std,string)\n  +/\nptrdiff_t countUntil(alias pred = \"a == b\", R, Rs...)(R haystack, Rs needles)\nif (isForwardRange!R\n    && Rs.length > 0\n    && isForwardRange!(Rs[0]) == isInputRange!(Rs[0])\n    && is(typeof(startsWith!pred(haystack, needles[0])))\n    && (Rs.length == 1\n    || is(typeof(countUntil!pred(haystack, needles[1 .. $])))))\n{\n    typeof(return) result;\n\n    static if (needles.length == 1)\n    {\n        static if (hasLength!R) //Note: Narrow strings don't have length.\n        {\n            //We delegate to find because find is very efficient.\n            //We store the length of the haystack so we don't have to save it.\n            auto len = haystack.length;\n            auto r2 = find!pred(haystack, needles[0]);\n            if (!r2.empty)\n              return cast(typeof(return)) (len - r2.length);\n        }\n        else\n        {\n            import std.range : dropOne;\n\n            if (needles[0].empty)\n              return 0;\n\n            //Default case, slower route doing startsWith iteration\n            for ( ; !haystack.empty ; ++result )\n            {\n                //We compare the first elements of the ranges here before\n                //forwarding to startsWith. This avoids making useless saves to\n                //haystack/needle if they aren't even going to be mutated anyways.\n                //It also cuts down on the amount of pops on haystack.\n                if (binaryFun!pred(haystack.front, needles[0].front))\n                {\n                    //Here, we need to save the needle before popping it.\n                    //haystack we pop in all paths, so we do that, and then save.\n                    haystack.popFront();\n                    if (startsWith!pred(haystack.save, needles[0].save.dropOne()))\n                      return result;\n                }\n                else\n                  haystack.popFront();\n            }\n        }\n    }\n    else\n    {\n        foreach (i, Ri; Rs)\n        {\n            static if (isForwardRange!Ri)\n            {\n                if (needles[i].empty)\n                  return 0;\n            }\n        }\n        Tuple!Rs t;\n        foreach (i, Ri; Rs)\n        {\n            static if (!isForwardRange!Ri)\n            {\n                t[i] = needles[i];\n            }\n        }\n        for (; !haystack.empty ; ++result, haystack.popFront())\n        {\n            foreach (i, Ri; Rs)\n            {\n                static if (isForwardRange!Ri)\n                {\n                    t[i] = needles[i].save;\n                }\n            }\n            if (startsWith!pred(haystack.save, t.expand))\n            {\n                return result;\n            }\n        }\n    }\n\n    //Because of @@@8804@@@: Avoids both \"unreachable code\" or \"no return statement\"\n    static if (isInfinite!R) assert(0);\n    else return -1;\n}\n\n/// ditto\nptrdiff_t countUntil(alias pred = \"a == b\", R, N)(R haystack, N needle)\nif (isInputRange!R &&\n    is(typeof(binaryFun!pred(haystack.front, needle)) : bool))\n{\n    bool pred2(ElementType!R a) { return binaryFun!pred(a, needle); }\n    return countUntil!pred2(haystack);\n}\n\n///\n@safe unittest\n{\n    assert(countUntil(\"hello world\", \"world\") == 6);\n    assert(countUntil(\"hello world\", 'r') == 8);\n    assert(countUntil(\"hello world\", \"programming\") == -1);\n    assert(countUntil(\"日本語\", \"本語\") == 1);\n    assert(countUntil(\"日本語\", '語')   == 2);\n    assert(countUntil(\"日本語\", \"五\") == -1);\n    assert(countUntil(\"日本語\", '五') == -1);\n    assert(countUntil([0, 7, 12, 22, 9], [12, 22]) == 2);\n    assert(countUntil([0, 7, 12, 22, 9], 9) == 4);\n    assert(countUntil!\"a > b\"([0, 7, 12, 22, 9], 20) == 3);\n}\n\n@safe unittest\n{\n    import std.algorithm.iteration : filter;\n    import std.internal.test.dummyrange;\n\n    assert(countUntil(\"日本語\", \"\") == 0);\n    assert(countUntil(\"日本語\"d, \"\") == 0);\n\n    assert(countUntil(\"\", \"\") == 0);\n    assert(countUntil(\"\".filter!\"true\"(), \"\") == 0);\n\n    auto rf = [0, 20, 12, 22, 9].filter!\"true\"();\n    assert(rf.countUntil!\"a > b\"((int[]).init) == 0);\n    assert(rf.countUntil!\"a > b\"(20) == 3);\n    assert(rf.countUntil!\"a > b\"([20, 8]) == 3);\n    assert(rf.countUntil!\"a > b\"([20, 10]) == -1);\n    assert(rf.countUntil!\"a > b\"([20, 8, 0]) == -1);\n\n    auto r = new ReferenceForwardRange!int([0, 1, 2, 3, 4, 5, 6]);\n    auto r2 = new ReferenceForwardRange!int([3, 4]);\n    auto r3 = new ReferenceForwardRange!int([3, 5]);\n    assert(r.save.countUntil(3)  == 3);\n    assert(r.save.countUntil(r2) == 3);\n    assert(r.save.countUntil(7)  == -1);\n    assert(r.save.countUntil(r3) == -1);\n}\n\n@safe unittest\n{\n    assert(countUntil(\"hello world\", \"world\", \"asd\") == 6);\n    assert(countUntil(\"hello world\", \"world\", \"ello\") == 1);\n    assert(countUntil(\"hello world\", \"world\", \"\") == 0);\n    assert(countUntil(\"hello world\", \"world\", 'l') == 2);\n}\n\n/// ditto\nptrdiff_t countUntil(alias pred, R)(R haystack)\nif (isInputRange!R &&\n    is(typeof(unaryFun!pred(haystack.front)) : bool))\n{\n    typeof(return) i;\n    static if (isRandomAccessRange!R)\n    {\n        //Optimized RA implementation. Since we want to count *and* iterate at\n        //the same time, it is more efficient this way.\n        static if (hasLength!R)\n        {\n            immutable len = cast(typeof(return)) haystack.length;\n            for ( ; i < len ; ++i )\n                if (unaryFun!pred(haystack[i])) return i;\n        }\n        else //if (isInfinite!R)\n        {\n            for ( ;  ; ++i )\n                if (unaryFun!pred(haystack[i])) return i;\n        }\n    }\n    else static if (hasLength!R)\n    {\n        //For those odd ranges that have a length, but aren't RA.\n        //It is faster to quick find, and then compare the lengths\n        auto r2 = find!pred(haystack.save);\n        if (!r2.empty) return cast(typeof(return)) (haystack.length - r2.length);\n    }\n    else //Everything else\n    {\n        alias T = ElementType!R; //For narrow strings forces dchar iteration\n        foreach (T elem; haystack)\n        {\n            if (unaryFun!pred(elem)) return i;\n            ++i;\n        }\n    }\n\n    //Because of @@@8804@@@: Avoids both \"unreachable code\" or \"no return statement\"\n    static if (isInfinite!R) assert(0);\n    else return -1;\n}\n\n///\n@safe unittest\n{\n    import std.ascii : isDigit;\n    import std.uni : isWhite;\n\n    assert(countUntil!(std.uni.isWhite)(\"hello world\") == 5);\n    assert(countUntil!(std.ascii.isDigit)(\"hello world\") == -1);\n    assert(countUntil!\"a > 20\"([0, 7, 12, 22, 9]) == 3);\n}\n\n@safe unittest\n{\n    import std.internal.test.dummyrange;\n\n    // References\n    {\n        // input\n        ReferenceInputRange!int r;\n        r = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6]);\n        assert(r.countUntil(3) == 3);\n        r = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6]);\n        assert(r.countUntil(7) == -1);\n    }\n    {\n        // forward\n        auto r = new ReferenceForwardRange!int([0, 1, 2, 3, 4, 5, 6]);\n        assert(r.save.countUntil([3, 4]) == 3);\n        assert(r.save.countUntil(3) == 3);\n        assert(r.save.countUntil([3, 7]) == -1);\n        assert(r.save.countUntil(7) == -1);\n    }\n    {\n        // infinite forward\n        auto r = new ReferenceInfiniteForwardRange!int(0);\n        assert(r.save.countUntil([3, 4]) == 3);\n        assert(r.save.countUntil(3) == 3);\n    }\n}\n\n/**\nChecks if the given range ends with (one of) the given needle(s).\nThe reciprocal of `startsWith`.\n\nParams:\n    pred = The predicate to use for comparing elements between the range and\n        the needle(s).\n\n    doesThisEnd = The\n        $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives)\n        to check.\n\n    withOneOfThese = The needles to check against, which may be single\n        elements, or bidirectional ranges of elements.\n\n    withThis = The single element to check.\n\nReturns:\n0 if the needle(s) do not occur at the end of the given range;\notherwise the position of the matching needle, that is, 1 if the range ends\nwith `withOneOfThese[0]`, 2 if it ends with `withOneOfThese[1]`, and so\non.\n\nIn the case when no needle parameters are given, return `true` iff back of\n`doesThisStart` fulfils predicate `pred`.\n*/\nuint endsWith(alias pred = \"a == b\", Range, Needles...)(Range doesThisEnd, Needles withOneOfThese)\nif (isBidirectionalRange!Range && Needles.length > 1 &&\n    is(typeof(.endsWith!pred(doesThisEnd, withOneOfThese[0])) : bool) &&\n    is(typeof(.endsWith!pred(doesThisEnd, withOneOfThese[1 .. $])) : uint))\n{\n    alias haystack = doesThisEnd;\n    alias needles  = withOneOfThese;\n\n    // Make one pass looking for empty ranges in needles\n    foreach (i, Unused; Needles)\n    {\n        // Empty range matches everything\n        static if (!is(typeof(binaryFun!pred(haystack.back, needles[i])) : bool))\n        {\n            if (needles[i].empty) return i + 1;\n        }\n    }\n\n    for (; !haystack.empty; haystack.popBack())\n    {\n        foreach (i, Unused; Needles)\n        {\n            static if (is(typeof(binaryFun!pred(haystack.back, needles[i])) : bool))\n            {\n                // Single-element\n                if (binaryFun!pred(haystack.back, needles[i]))\n                {\n                    // found, but continue to account for one-element\n                    // range matches (consider endsWith(\"ab\", \"b\",\n                    // 'b') should return 1, not 2).\n                    continue;\n                }\n            }\n            else\n            {\n                if (binaryFun!pred(haystack.back, needles[i].back))\n                    continue;\n            }\n\n            // This code executed on failure to match\n            // Out with this guy, check for the others\n            uint result = endsWith!pred(haystack, needles[0 .. i], needles[i + 1 .. $]);\n            if (result > i) ++result;\n            return result;\n        }\n\n        // If execution reaches this point, then the back matches for all\n        // needles ranges. What we need to do now is to lop off the back of\n        // all ranges involved and recurse.\n        foreach (i, Unused; Needles)\n        {\n            static if (is(typeof(binaryFun!pred(haystack.back, needles[i])) : bool))\n            {\n                // Test has passed in the previous loop\n                return i + 1;\n            }\n            else\n            {\n                needles[i].popBack();\n                if (needles[i].empty) return i + 1;\n            }\n        }\n    }\n    return 0;\n}\n\n/// Ditto\nbool endsWith(alias pred = \"a == b\", R1, R2)(R1 doesThisEnd, R2 withThis)\nif (isBidirectionalRange!R1 &&\n    isBidirectionalRange!R2 &&\n    is(typeof(binaryFun!pred(doesThisEnd.back, withThis.back)) : bool))\n{\n    alias haystack = doesThisEnd;\n    alias needle   = withThis;\n\n    static if (is(typeof(pred) : string))\n        enum isDefaultPred = pred == \"a == b\";\n    else\n        enum isDefaultPred = false;\n\n    static if (isDefaultPred && isArray!R1 && isArray!R2 &&\n               is(Unqual!(ElementEncodingType!R1) == Unqual!(ElementEncodingType!R2)))\n    {\n        if (haystack.length < needle.length) return false;\n\n        return haystack[$ - needle.length .. $] == needle;\n    }\n    else\n    {\n        import std.range : retro;\n        return startsWith!pred(retro(doesThisEnd), retro(withThis));\n    }\n}\n\n/// Ditto\nbool endsWith(alias pred = \"a == b\", R, E)(R doesThisEnd, E withThis)\nif (isBidirectionalRange!R &&\n    is(typeof(binaryFun!pred(doesThisEnd.back, withThis)) : bool))\n{\n    if (doesThisEnd.empty)\n        return false;\n\n    static if (is(typeof(pred) : string))\n        enum isDefaultPred = pred == \"a == b\";\n    else\n        enum isDefaultPred = false;\n\n    alias predFunc = binaryFun!pred;\n\n    // auto-decoding special case\n    static if (isNarrowString!R)\n    {\n        // statically determine decoding is unnecessary to evaluate pred\n        static if (isDefaultPred && isSomeChar!E && E.sizeof <= ElementEncodingType!R.sizeof)\n            return doesThisEnd[$ - 1] == withThis;\n        // specialize for ASCII as to not change previous behavior\n        else\n        {\n            if (withThis <= 0x7F)\n                return predFunc(doesThisEnd[$ - 1], withThis);\n            else\n                return predFunc(doesThisEnd.back, withThis);\n        }\n    }\n    else\n    {\n        return predFunc(doesThisEnd.back, withThis);\n    }\n}\n\n/// Ditto\nbool endsWith(alias pred, R)(R doesThisEnd)\nif (isInputRange!R &&\n    ifTestable!(typeof(doesThisEnd.front), unaryFun!pred))\n{\n    return !doesThisEnd.empty && unaryFun!pred(doesThisEnd.back);\n}\n\n///\n@safe unittest\n{\n    import std.ascii : isAlpha;\n    assert(\"abc\".endsWith!(a => a.isAlpha));\n    assert(\"abc\".endsWith!isAlpha);\n\n    assert(!\"ab1\".endsWith!(a => a.isAlpha));\n\n    assert(!\"ab1\".endsWith!isAlpha);\n    assert(!\"\".endsWith!(a => a.isAlpha));\n\n    import std.algorithm.comparison : among;\n    assert(\"abc\".endsWith!(a => a.among('c', 'd') != 0));\n    assert(!\"abc\".endsWith!(a => a.among('a', 'b') != 0));\n\n    assert(endsWith(\"abc\", \"\"));\n    assert(!endsWith(\"abc\", \"b\"));\n    assert(endsWith(\"abc\", \"a\", 'c') == 2);\n    assert(endsWith(\"abc\", \"c\", \"a\") == 1);\n    assert(endsWith(\"abc\", \"c\", \"c\") == 1);\n    assert(endsWith(\"abc\", \"bc\", \"c\") == 2);\n    assert(endsWith(\"abc\", \"x\", \"c\", \"b\") == 2);\n    assert(endsWith(\"abc\", \"x\", \"aa\", \"bc\") == 3);\n    assert(endsWith(\"abc\", \"x\", \"aaa\", \"sab\") == 0);\n    assert(endsWith(\"abc\", \"x\", \"aaa\", 'c', \"sab\") == 3);\n}\n\n@safe unittest\n{\n    import std.algorithm.iteration : filterBidirectional;\n    import std.conv : to;\n    import std.meta : AliasSeq;\n\n    static foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n    {\n        assert(!endsWith(to!S(\"abc\"), 'a'));\n        assert(endsWith(to!S(\"abc\"), 'a', 'c') == 2);\n        assert(!endsWith(to!S(\"abc\"), 'x', 'n', 'b'));\n        assert(endsWith(to!S(\"abc\"), 'x', 'n', 'c') == 3);\n        assert(endsWith(to!S(\"abc\\uFF28\"), 'a', '\\uFF28', 'c') == 2);\n\n        static foreach (T; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n        {\n            //Lots of strings\n            assert(endsWith(to!S(\"abc\"), to!T(\"\")));\n            assert(!endsWith(to!S(\"abc\"), to!T(\"a\")));\n            assert(!endsWith(to!S(\"abc\"), to!T(\"b\")));\n            assert(endsWith(to!S(\"abc\"), to!T(\"bc\"), 'c') == 2);\n            assert(endsWith(to!S(\"abc\"), to!T(\"a\"), \"c\") == 2);\n            assert(endsWith(to!S(\"abc\"), to!T(\"c\"), \"a\") == 1);\n            assert(endsWith(to!S(\"abc\"), to!T(\"c\"), \"c\") == 1);\n            assert(endsWith(to!S(\"abc\"), to!T(\"x\"), 'c', \"b\") == 2);\n            assert(endsWith(to!S(\"abc\"), 'x', to!T(\"aa\"), \"bc\") == 3);\n            assert(endsWith(to!S(\"abc\"), to!T(\"x\"), \"aaa\", \"sab\") == 0);\n            assert(endsWith(to!S(\"abc\"), to!T(\"x\"), \"aaa\", \"c\", \"sab\") == 3);\n            assert(endsWith(to!S(\"\\uFF28el\\uFF4co\"), to!T(\"l\\uFF4co\")));\n            assert(endsWith(to!S(\"\\uFF28el\\uFF4co\"), to!T(\"lo\"), to!T(\"l\\uFF4co\")) == 2);\n\n            //Unicode\n            assert(endsWith(to!S(\"\\uFF28el\\uFF4co\"), to!T(\"l\\uFF4co\")));\n            assert(endsWith(to!S(\"\\uFF28el\\uFF4co\"), to!T(\"lo\"), to!T(\"l\\uFF4co\")) == 2);\n            assert(endsWith(to!S(\"日本語\"), to!T(\"本語\")));\n            assert(endsWith(to!S(\"日本語\"), to!T(\"日本語\")));\n            assert(!endsWith(to!S(\"本語\"), to!T(\"日本語\")));\n\n            //Empty\n            assert(endsWith(to!S(\"\"),  T.init));\n            assert(!endsWith(to!S(\"\"), 'a'));\n            assert(endsWith(to!S(\"a\"), T.init));\n            assert(endsWith(to!S(\"a\"), T.init, \"\") == 1);\n            assert(endsWith(to!S(\"a\"), T.init, 'a') == 1);\n            assert(endsWith(to!S(\"a\"), 'a', T.init) == 2);\n        }\n    }\n\n    static foreach (T; AliasSeq!(int, short))\n    {{\n        immutable arr = cast(T[])[0, 1, 2, 3, 4, 5];\n\n        //RA range\n        assert(endsWith(arr, cast(int[]) null));\n        assert(!endsWith(arr, 0));\n        assert(!endsWith(arr, 4));\n        assert(endsWith(arr, 5));\n        assert(endsWith(arr, 0, 4, 5) == 3);\n        assert(endsWith(arr, [5]));\n        assert(endsWith(arr, [4, 5]));\n        assert(endsWith(arr, [4, 5], 7) == 1);\n        assert(!endsWith(arr, [2, 4, 5]));\n        assert(endsWith(arr, [2, 4, 5], [3, 4, 5]) == 2);\n\n        //Normal input range\n        assert(!endsWith(filterBidirectional!\"true\"(arr), 4));\n        assert(endsWith(filterBidirectional!\"true\"(arr), 5));\n        assert(endsWith(filterBidirectional!\"true\"(arr), [5]));\n        assert(endsWith(filterBidirectional!\"true\"(arr), [4, 5]));\n        assert(endsWith(filterBidirectional!\"true\"(arr), [4, 5], 7) == 1);\n        assert(!endsWith(filterBidirectional!\"true\"(arr), [2, 4, 5]));\n        assert(endsWith(filterBidirectional!\"true\"(arr), [2, 4, 5], [3, 4, 5]) == 2);\n        assert(endsWith(arr, filterBidirectional!\"true\"([4, 5])));\n        assert(endsWith(arr, filterBidirectional!\"true\"([4, 5]), 7) == 1);\n        assert(!endsWith(arr, filterBidirectional!\"true\"([2, 4, 5])));\n        assert(endsWith(arr, [2, 4, 5], filterBidirectional!\"true\"([3, 4, 5])) == 2);\n\n        //Non-default pred\n        assert(endsWith!(\"a%10 == b%10\")(arr, [14, 15]));\n        assert(!endsWith!(\"a%10 == b%10\")(arr, [15, 14]));\n    }}\n}\n\n// Rebindable doesn't work with structs\n// see: https://github.com/dlang/phobos/pull/6136\nprivate template RebindableOrUnqual(T)\n{\n    static if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T)\n        alias RebindableOrUnqual = Rebindable!T;\n    else\n        alias RebindableOrUnqual = Unqual!T;\n}\n\n/**\nIterates the passed range and selects the extreme element with `less`.\nIf the extreme element occurs multiple time, the first occurrence will be\nreturned.\n\nParams:\n    map = custom accessor for the comparison key\n    selector = custom mapping for the extrema selection\n    seed = custom seed to use as initial element\n    r = Range from which the extreme value will be selected\n\nReturns:\n    The extreme value according to `map` and `selector` of the passed-in values.\n*/\nprivate auto extremum(alias map, alias selector = \"a < b\", Range)(Range r)\nif (isInputRange!Range && !isInfinite!Range &&\n    is(typeof(unaryFun!map(ElementType!(Range).init))))\nin\n{\n    assert(!r.empty, \"r is an empty range\");\n}\ndo\n{\n    alias Element = ElementType!Range;\n    RebindableOrUnqual!Element seed = r.front;\n    r.popFront();\n    return extremum!(map, selector)(r, seed);\n}\n\nprivate auto extremum(alias map, alias selector = \"a < b\", Range,\n                      RangeElementType = ElementType!Range)\n                     (Range r, RangeElementType seedElement)\nif (isInputRange!Range && !isInfinite!Range &&\n    !is(CommonType!(ElementType!Range, RangeElementType) == void) &&\n     is(typeof(unaryFun!map(ElementType!(Range).init))))\n{\n    alias mapFun = unaryFun!map;\n    alias selectorFun = binaryFun!selector;\n\n    alias Element = ElementType!Range;\n    alias CommonElement = CommonType!(Element, RangeElementType);\n    RebindableOrUnqual!CommonElement extremeElement = seedElement;\n\n\n    // if we only have one statement in the loop, it can be optimized a lot better\n    static if (__traits(isSame, map, a => a))\n    {\n\n        // direct access via a random access range is faster\n        static if (isRandomAccessRange!Range)\n        {\n            foreach (const i; 0 .. r.length)\n            {\n                if (selectorFun(r[i], extremeElement))\n                {\n                    extremeElement = r[i];\n                }\n            }\n        }\n        else\n        {\n            while (!r.empty)\n            {\n                if (selectorFun(r.front, extremeElement))\n                {\n                    extremeElement = r.front;\n                }\n                r.popFront();\n            }\n        }\n    }\n    else\n    {\n        alias MapType = Unqual!(typeof(mapFun(CommonElement.init)));\n        MapType extremeElementMapped = mapFun(extremeElement);\n\n        // direct access via a random access range is faster\n        static if (isRandomAccessRange!Range)\n        {\n            foreach (const i; 0 .. r.length)\n            {\n                MapType mapElement = mapFun(r[i]);\n                if (selectorFun(mapElement, extremeElementMapped))\n                {\n                    extremeElement = r[i];\n                    extremeElementMapped = mapElement;\n                }\n            }\n        }\n        else\n        {\n            while (!r.empty)\n            {\n                MapType mapElement = mapFun(r.front);\n                if (selectorFun(mapElement, extremeElementMapped))\n                {\n                    extremeElement = r.front;\n                    extremeElementMapped = mapElement;\n                }\n                r.popFront();\n            }\n        }\n    }\n    return extremeElement;\n}\n\nprivate auto extremum(alias selector = \"a < b\", Range)(Range r)\nif (isInputRange!Range && !isInfinite!Range &&\n    !is(typeof(unaryFun!selector(ElementType!(Range).init))))\n{\n    return extremum!(a => a, selector)(r);\n}\n\n// if we only have one statement in the loop it can be optimized a lot better\nprivate auto extremum(alias selector = \"a < b\", Range,\n                      RangeElementType = ElementType!Range)\n                     (Range r, RangeElementType seedElement)\nif (isInputRange!Range && !isInfinite!Range &&\n    !is(CommonType!(ElementType!Range, RangeElementType) == void) &&\n    !is(typeof(unaryFun!selector(ElementType!(Range).init))))\n{\n    return extremum!(a => a, selector)(r, seedElement);\n}\n\n@safe pure unittest\n{\n    // allows a custom map to select the extremum\n    assert([[0, 4], [1, 2]].extremum!\"a[0]\" == [0, 4]);\n    assert([[0, 4], [1, 2]].extremum!\"a[1]\" == [1, 2]);\n\n    // allows a custom selector for comparison\n    assert([[0, 4], [1, 2]].extremum!(\"a[0]\", \"a > b\") == [1, 2]);\n    assert([[0, 4], [1, 2]].extremum!(\"a[1]\", \"a > b\") == [0, 4]);\n\n    // use a custom comparator\n    import std.math : cmp;\n    assert([-2., 0, 5].extremum!cmp == 5.0);\n    assert([-2., 0, 2].extremum!`cmp(a, b) < 0` == -2.0);\n\n    // combine with map\n    import std.range : enumerate;\n    assert([-3., 0, 5].enumerate.extremum!(`a.value`, cmp) == tuple(2, 5.0));\n    assert([-2., 0, 2].enumerate.extremum!(`a.value`, `cmp(a, b) < 0`) == tuple(0, -2.0));\n\n    // seed with a custom value\n    int[] arr;\n    assert(arr.extremum(1) == 1);\n}\n\n@safe pure nothrow unittest\n{\n    // 2d seeds\n    int[][] arr2d;\n    assert(arr2d.extremum([1]) == [1]);\n\n    // allow seeds of different types (implicit casting)\n    assert(extremum([2, 3, 4], 1.5) == 1.5);\n}\n\n@safe pure unittest\n{\n    import std.range : enumerate, iota;\n\n    // forward ranges\n    assert(iota(1, 5).extremum() == 1);\n    assert(iota(2, 5).enumerate.extremum!\"a.value\" == tuple(0, 2));\n\n    // should work with const\n    const(int)[] immArr = [2, 1, 3];\n    assert(immArr.extremum == 1);\n\n    // should work with immutable\n    immutable(int)[] immArr2 = [2, 1, 3];\n    assert(immArr2.extremum == 1);\n\n    // with strings\n    assert([\"b\", \"a\", \"c\"].extremum == \"a\");\n\n    // with all dummy ranges\n    import std.internal.test.dummyrange;\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType d;\n        assert(d.extremum == 1);\n        assert(d.extremum!(a => a)  == 1);\n        assert(d.extremum!`a > b` == 10);\n        assert(d.extremum!(a => a, `a > b`) == 10);\n    }\n}\n\n@nogc @safe nothrow pure unittest\n{\n    static immutable arr = [7, 3, 4, 2, 1, 8];\n    assert(arr.extremum == 1);\n\n    static immutable arr2d = [[1, 9], [3, 1], [4, 2]];\n    assert(arr2d.extremum!\"a[1]\" == arr2d[1]);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17982\n@safe unittest\n{\n    class B\n    {\n        int val;\n        this(int val){ this.val = val; }\n    }\n\n    const(B) doStuff(const(B)[] v)\n    {\n        return v.extremum!\"a.val\";\n    }\n    assert(doStuff([new B(1), new B(0), new B(2)]).val == 0);\n\n    const(B)[] arr = [new B(0), new B(1)];\n    // can't compare directly - https://issues.dlang.org/show_bug.cgi?id=1824\n    assert(arr.extremum!\"a.val\".val == 0);\n}\n\n// find\n/**\nFinds an individual element in an $(REF_ALTTEXT input range, isInputRange, std,range,primitives).\nElements of `haystack` are compared with `needle` by using predicate\n`pred` with `pred(haystack.front, needle)`.\n`find` performs $(BIGOH walkLength(haystack)) evaluations of `pred`.\n\nThe predicate is passed to $(REF binaryFun, std, functional), and can either accept a\nstring, or any callable that can be executed via `pred(element, element)`.\n\nTo _find the last occurrence of `needle` in a\n$(REF_ALTTEXT bidirectional, isBidirectionalRange, std,range,primitives) `haystack`,\ncall `find(retro(haystack), needle)`. See $(REF retro, std,range).\n\nIf no `needle` is provided, `pred(haystack.front)` will be evaluated on each\nelement of the input range.\n\nIf `input` is a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives),\n`needle` can be a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) too.\nIn this case `startsWith!pred(haystack, needle)` is evaluated on each evaluation.\n\nNote:\n    `find` behaves similar to `dropWhile` in other languages.\n\nComplexity:\n    `find` performs $(BIGOH walkLength(haystack)) evaluations of `pred`.\n    There are specializations that improve performance by taking\n    advantage of $(REF_ALTTEXT bidirectional, isBidirectionalRange, std,range,primitives)\n    or $(REF_ALTTEXT random access, isRandomAccess, std,range,primitives)\n    ranges (where possible).\n\nParams:\n\n    pred = The predicate for comparing each element with the needle, defaulting to equality `\"a == b\"`.\n           The negated predicate `\"a != b\"` can be used to search instead for the first\n           element $(I not) matching the needle.\n\n    haystack = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n               searched in.\n\n    needle = The element searched for.\n\nReturns:\n\n    `haystack` advanced such that the front element is the one searched for;\n    that is, until `binaryFun!pred(haystack.front, needle)` is `true`. If no\n    such position exists, returns an empty `haystack`.\n\nSee_ALso: $(LREF findAdjacent), $(LREF findAmong), $(LREF findSkip), $(LREF findSplit), $(LREF startsWith)\n*/\nInputRange find(alias pred = \"a == b\", InputRange, Element)(InputRange haystack, scope Element needle)\nif (isInputRange!InputRange &&\n    is (typeof(binaryFun!pred(haystack.front, needle)) : bool))\n{\n    alias R = InputRange;\n    alias E = Element;\n    alias predFun = binaryFun!pred;\n    static if (is(typeof(pred == \"a == b\")))\n        enum isDefaultPred = pred == \"a == b\";\n    else\n        enum isDefaultPred = false;\n    enum  isIntegralNeedle = isSomeChar!E || isIntegral!E || isBoolean!E;\n\n    alias EType  = ElementType!R;\n\n    // If the haystack is a SortedRange we can use binary search to find the needle.\n    // Works only for the default find predicate and any SortedRange predicate.\n    // 8829 enhancement\n    import std.range : SortedRange;\n    static if (is(InputRange : SortedRange!TT, TT) && isDefaultPred)\n    {\n        auto lb = haystack.lowerBound(needle);\n        if (lb.length == haystack.length || haystack[lb.length] != needle)\n            return haystack[$ .. $];\n\n        return haystack[lb.length .. $];\n    }\n    else static if (isNarrowString!R)\n    {\n        alias EEType = ElementEncodingType!R;\n        alias UEEType = Unqual!EEType;\n\n        //These are two special cases which can search without decoding the UTF stream.\n        static if (isDefaultPred && isIntegralNeedle)\n        {\n            import std.utf : canSearchInCodeUnits;\n\n            //This special case deals with UTF8 search, when the needle\n            //is represented by a single code point.\n            //Note: \"needle <= 0x7F\" properly handles sign via unsigned promotion\n            static if (is(UEEType == char))\n            {\n                if (!__ctfe && canSearchInCodeUnits!char(needle))\n                {\n                    static R trustedMemchr(ref R haystack, ref E needle) @trusted nothrow pure\n                    {\n                        import core.stdc.string : memchr;\n                        auto ptr = memchr(haystack.ptr, needle, haystack.length);\n                        return ptr ?\n                             haystack[cast(char*) ptr - haystack.ptr .. $] :\n                             haystack[$ .. $];\n                    }\n                    return trustedMemchr(haystack, needle);\n                }\n            }\n\n            //Ditto, but for UTF16\n            static if (is(UEEType == wchar))\n            {\n                if (canSearchInCodeUnits!wchar(needle))\n                {\n                    foreach (i, ref EEType e; haystack)\n                    {\n                        if (e == needle)\n                            return haystack[i .. $];\n                    }\n                    return haystack[$ .. $];\n                }\n            }\n        }\n\n        //Previous conditional optimizations did not succeed. Fallback to\n        //unconditional implementations\n        static if (isDefaultPred)\n        {\n            import std.utf : encode;\n\n            //In case of default pred, it is faster to do string/string search.\n            UEEType[is(UEEType == char) ? 4 : 2] buf;\n\n            size_t len = encode(buf, needle);\n            return find(haystack, buf[0 .. len]);\n        }\n        else\n        {\n            import std.utf : decode;\n\n            //Explicit pred: we must test each character by the book.\n            //We choose a manual decoding approach, because it is faster than\n            //the built-in foreach, or doing a front/popFront for-loop.\n            immutable len = haystack.length;\n            size_t i = 0, next = 0;\n            while (next < len)\n            {\n                if (predFun(decode(haystack, next), needle))\n                    return haystack[i .. $];\n                i = next;\n            }\n            return haystack[$ .. $];\n        }\n    }\n    else static if (isArray!R)\n    {\n        //10403 optimization\n        static if (isDefaultPred && isIntegral!EType && EType.sizeof == 1 && isIntegralNeedle)\n        {\n            import std.algorithm.comparison : max, min;\n\n            R findHelper(ref R haystack, ref E needle) @trusted nothrow pure\n            {\n                import core.stdc.string : memchr;\n\n                EType* ptr = null;\n                //Note: we use \"min/max\" to handle sign mismatch.\n                if (min(EType.min, needle) == EType.min &&\n                    max(EType.max, needle) == EType.max)\n                {\n                    ptr = cast(EType*) memchr(haystack.ptr, needle,\n                        haystack.length);\n                }\n\n                return ptr ?\n                    haystack[ptr - haystack.ptr .. $] :\n                    haystack[$ .. $];\n            }\n\n            if (!__ctfe)\n                return findHelper(haystack, needle);\n        }\n\n        //Default implementation.\n        foreach (i, ref e; haystack)\n            if (predFun(e, needle))\n                return haystack[i .. $];\n        return haystack[$ .. $];\n    }\n    else\n    {\n        //Everything else. Walk.\n        for ( ; !haystack.empty; haystack.popFront() )\n        {\n            if (predFun(haystack.front, needle))\n                break;\n        }\n        return haystack;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.range.primitives;\n\n    auto arr = [1, 2, 4, 4, 4, 4, 5, 6, 9];\n    assert(arr.find(4) == [4, 4, 4, 4, 5, 6, 9]);\n    assert(arr.find(1) == arr);\n    assert(arr.find(9) == [9]);\n    assert(arr.find!((a, b) => a > b)(4) == [5, 6, 9]);\n    assert(arr.find!((a, b) => a < b)(4) == arr);\n    assert(arr.find(0).empty);\n    assert(arr.find(10).empty);\n    assert(arr.find(8).empty);\n\n    assert(find(\"hello, world\", ',') == \", world\");\n}\n\n/// Case-insensitive find of a string\n@safe unittest\n{\n    import std.range.primitives;\n    import std.uni : toLower;\n\n    string[] s = [\"Hello\", \"world\", \"!\"];\n    assert(s.find!((a, b) => toLower(a) == b)(\"hello\") == s);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container : SList;\n\n    auto lst = SList!int(1, 2, 5, 7, 3);\n    assert(lst.front == 1);\n    auto r = find(lst[], 5);\n    assert(equal(r, SList!int(5, 7, 3)[]));\n    assert(find([1, 2, 3, 5], 4).empty);\n    assert(equal(find!\"a > b\"(\"hello\", 'k'), \"llo\"));\n}\n\n@safe pure nothrow unittest\n{\n    assert(!find              ([1, 2, 3], 2).empty);\n    assert(!find!((a,b)=>a == b)([1, 2, 3], 2).empty);\n    assert(!find              ([1, 2, 3], 2).empty);\n    assert(!find!((a,b)=>a == b)([1, 2, 3], 2).empty);\n}\n\n@safe pure unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (R; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (E; AliasSeq!(char, wchar, dchar))\n        {\n            assert(find              (\"hello world\", 'w') == \"world\");\n            assert(find!((a,b)=>a == b)(\"hello world\", 'w') == \"world\");\n            assert(find              (\"日c語\", 'c') == \"c語\");\n            assert(find!((a,b)=>a == b)(\"日c語\", 'c') == \"c語\");\n            assert(find              (\"0123456789\", 'A').empty);\n            static if (E.sizeof >= 2)\n            {\n                assert(find              (\"日本語\", '本') == \"本語\");\n                assert(find!((a,b)=>a == b)(\"日本語\", '本') == \"本語\");\n            }\n        }\n    }\n}\n\n@safe unittest\n{\n    //CTFE\n    static assert(find(\"abc\", 'b') == \"bc\");\n    static assert(find(\"日b語\", 'b') == \"b語\");\n    static assert(find(\"日本語\", '本') == \"本語\");\n    static assert(find([1, 2, 3], 2)  == [2, 3]);\n\n    static assert(find              ([1, 2, 3], 2));\n    static assert(find!((a,b)=>a == b)([1, 2, 3], 2));\n    static assert(find              ([1, 2, 3], 2));\n    static assert(find!((a,b)=>a == b)([1, 2, 3], 2));\n}\n\n@safe unittest\n{\n    import std.exception : assertCTFEable;\n    import std.meta : AliasSeq;\n\n    void dg() @safe pure nothrow\n    {\n        byte[]  sarr = [1, 2, 3, 4];\n        ubyte[] uarr = [1, 2, 3, 4];\n        static foreach (arr; AliasSeq!(sarr, uarr))\n        {\n            static foreach (T; AliasSeq!(byte, ubyte, int, uint))\n            {\n                assert(find(arr, cast(T) 3) == arr[2 .. $]);\n                assert(find(arr, cast(T) 9) == arr[$ .. $]);\n            }\n            assert(find(arr, 256) == arr[$ .. $]);\n        }\n    }\n    dg();\n    assertCTFEable!dg;\n}\n\n@safe unittest\n{\n    // Bugzilla 11603\n    enum Foo : ubyte { A }\n    assert([Foo.A].find(Foo.A).empty == false);\n\n    ubyte x = 0;\n    assert([x].find(x).empty == false);\n}\n\n/// ditto\nInputRange find(alias pred, InputRange)(InputRange haystack)\nif (isInputRange!InputRange)\n{\n    alias R = InputRange;\n    alias predFun = unaryFun!pred;\n    static if (isNarrowString!R)\n    {\n        import std.utf : decode;\n\n        immutable len = haystack.length;\n        size_t i = 0, next = 0;\n        while (next < len)\n        {\n            if (predFun(decode(haystack, next)))\n                return haystack[i .. $];\n            i = next;\n        }\n        return haystack[$ .. $];\n    }\n    else\n    {\n        //standard range\n        for ( ; !haystack.empty; haystack.popFront() )\n        {\n            if (predFun(haystack.front))\n                break;\n        }\n        return haystack;\n    }\n}\n\n///\n@safe unittest\n{\n    auto arr = [ 1, 2, 3, 4, 1 ];\n    assert(find!(\"a > 2\")(arr) == [ 3, 4, 1 ]);\n\n    // with predicate alias\n    bool pred(int x) { return x + 1 > 1.5; }\n    assert(find!(pred)(arr) == arr);\n}\n\n@safe pure unittest\n{\n    int[] r = [ 1, 2, 3 ];\n    assert(find!(a=>a > 2)(r) == [3]);\n    bool pred(int x) { return x + 1 > 1.5; }\n    assert(find!(pred)(r) == r);\n\n    assert(find!(a=>a > 'v')(\"hello world\") == \"world\");\n    assert(find!(a=>a%4 == 0)(\"日本語\") == \"本語\");\n}\n\n/// ditto\nR1 find(alias pred = \"a == b\", R1, R2)(R1 haystack, scope R2 needle)\nif (isForwardRange!R1 && isForwardRange!R2\n        && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool))\n{\n    static if (!isRandomAccessRange!R1)\n    {\n        static if (is(typeof(pred == \"a == b\")) && pred == \"a == b\" && isSomeString!R1 && isSomeString!R2\n                && haystack[0].sizeof == needle[0].sizeof)\n        {\n            // return cast(R1) find(representation(haystack), representation(needle));\n            // Specialization for simple string search\n            alias Representation =\n                Select!(haystack[0].sizeof == 1, ubyte[],\n                    Select!(haystack[0].sizeof == 2, ushort[], uint[]));\n            // Will use the array specialization\n            static TO force(TO, T)(inout T r) @trusted { return cast(TO) r; }\n            return force!R1(.find!(pred, Representation, Representation)\n                (force!Representation(haystack), force!Representation(needle)));\n        }\n        else\n        {\n            return simpleMindedFind!pred(haystack, needle);\n        }\n    }\n    else static if (!isBidirectionalRange!R2 || !hasSlicing!R1)\n    {\n        static if (!is(ElementType!R1 == ElementType!R2))\n        {\n            return simpleMindedFind!pred(haystack, needle);\n        }\n        else\n        {\n            // Prepare the search with needle's first element\n            if (needle.empty)\n                return haystack;\n\n            haystack = .find!pred(haystack, needle.front);\n\n            static if (hasLength!R1 && hasLength!R2 && is(typeof(takeNone(haystack)) == R1))\n            {\n                if (needle.length > haystack.length)\n                    return takeNone(haystack);\n            }\n            else\n            {\n                if (haystack.empty)\n                    return haystack;\n            }\n\n            needle.popFront();\n            size_t matchLen = 1;\n\n            // Loop invariant: haystack[0 .. matchLen] matches everything in\n            // the initial needle that was popped out of needle.\n            for (;;)\n            {\n                // Extend matchLength as much as possible\n                for (;;)\n                {\n                    import std.range : takeNone;\n\n                    if (needle.empty || haystack.empty)\n                        return haystack;\n\n                    static if (hasLength!R1 && is(typeof(takeNone(haystack)) == R1))\n                    {\n                        if (matchLen == haystack.length)\n                            return takeNone(haystack);\n                    }\n\n                    if (!binaryFun!pred(haystack[matchLen], needle.front))\n                        break;\n\n                    ++matchLen;\n                    needle.popFront();\n                }\n\n                auto bestMatch = haystack[0 .. matchLen];\n                haystack.popFront();\n                haystack = .find!pred(haystack, bestMatch);\n            }\n        }\n    }\n    else // static if (hasSlicing!R1 && isBidirectionalRange!R2)\n    {\n        if (needle.empty) return haystack;\n\n        static if (hasLength!R2)\n        {\n            immutable needleLength = needle.length;\n        }\n        else\n        {\n            immutable needleLength = walkLength(needle.save);\n        }\n        if (needleLength > haystack.length)\n        {\n            return haystack[haystack.length .. haystack.length];\n        }\n        // Optimization in case the ranges are both SortedRanges.\n        // Binary search can be used to find the first occurence\n        // of the first element of the needle in haystack.\n        // When it is found O(walklength(needle)) steps are performed.\n        // 8829 enhancement\n        import std.algorithm.comparison : mismatch;\n        import std.range : SortedRange;\n        static if (is(R1 == R2)\n                && is(R1 : SortedRange!TT, TT)\n                && pred == \"a == b\")\n        {\n            auto needleFirstElem = needle[0];\n            auto partitions      = haystack.trisect(needleFirstElem);\n            auto firstElemLen    = partitions[1].length;\n            size_t count         = 0;\n\n            if (firstElemLen == 0)\n                return haystack[$ .. $];\n\n            while (needle.front() == needleFirstElem)\n            {\n                needle.popFront();\n                ++count;\n\n                if (count > firstElemLen)\n                    return haystack[$ .. $];\n            }\n\n            auto m = mismatch(partitions[2], needle);\n\n            if (m[1].empty)\n                return haystack[partitions[0].length + partitions[1].length - count .. $];\n        }\n        else static if (isRandomAccessRange!R2)\n        {\n            immutable lastIndex = needleLength - 1;\n            auto last = needle[lastIndex];\n            size_t j = lastIndex, skip = 0;\n            for (; j < haystack.length;)\n            {\n                if (!binaryFun!pred(haystack[j], last))\n                {\n                    ++j;\n                    continue;\n                }\n                immutable k = j - lastIndex;\n                // last elements match\n                for (size_t i = 0;; ++i)\n                {\n                    if (i == lastIndex)\n                        return haystack[k .. haystack.length];\n                    if (!binaryFun!pred(haystack[k + i], needle[i]))\n                        break;\n                }\n                if (skip == 0)\n                {\n                    skip = 1;\n                    while (skip < needleLength && needle[needleLength - 1 - skip] != needle[needleLength - 1])\n                    {\n                        ++skip;\n                    }\n                }\n                j += skip;\n            }\n        }\n        else\n        {\n            // @@@BUG@@@\n            // auto needleBack = moveBack(needle);\n            // Stage 1: find the step\n            size_t step = 1;\n            auto needleBack = needle.back;\n            needle.popBack();\n            for (auto i = needle.save; !i.empty && i.back != needleBack;\n                    i.popBack(), ++step)\n            {\n            }\n            // Stage 2: linear find\n            size_t scout = needleLength - 1;\n            for (;;)\n            {\n                if (scout >= haystack.length)\n                    break;\n                if (!binaryFun!pred(haystack[scout], needleBack))\n                {\n                    ++scout;\n                    continue;\n                }\n                // Found a match with the last element in the needle\n                auto cand = haystack[scout + 1 - needleLength .. haystack.length];\n                if (startsWith!pred(cand, needle))\n                {\n                    // found\n                    return cand;\n                }\n                scout += step;\n            }\n        }\n        return haystack[haystack.length .. haystack.length];\n    }\n}\n\n///\n@safe unittest\n{\n    import std.container : SList;\n    import std.range.primitives : empty;\n    import std.typecons : Tuple;\n\n    assert(find(\"hello, world\", \"World\").empty);\n    assert(find(\"hello, world\", \"wo\") == \"world\");\n    assert([1, 2, 3, 4].find(SList!int(2, 3)[]) == [2, 3, 4]);\n    alias C = Tuple!(int, \"x\", int, \"y\");\n    auto a = [C(1,0), C(2,0), C(3,1), C(4,0)];\n    assert(a.find!\"a.x == b\"([2, 3]) == [C(2,0), C(3,1), C(4,0)]);\n    assert(a[1 .. $].find!\"a.x == b\"([2, 3]) == [C(2,0), C(3,1), C(4,0)]);\n}\n\n@safe unittest\n{\n    import std.container : SList;\n    alias C = Tuple!(int, \"x\", int, \"y\");\n    assert([C(1,0), C(2,0), C(3,1), C(4,0)].find!\"a.x == b\"(SList!int(2, 3)[]) == [C(2,0), C(3,1), C(4,0)]);\n}\n\n@safe unittest // issue 12470\n{\n    import std.array : replace;\n    inout(char)[] sanitize(inout(char)[] p)\n    {\n        return p.replace(\"\\0\", \" \");\n    }\n    assert(sanitize(\"O\\x00o\") == \"O o\");\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container : SList;\n\n    auto lst = SList!int(1, 2, 5, 7, 3);\n    static assert(isForwardRange!(int[]));\n    static assert(isForwardRange!(typeof(lst[])));\n    auto r = find(lst[], [2, 5]);\n    assert(equal(r, SList!int(2, 5, 7, 3)[]));\n}\n\n@safe unittest\n{\n    import std.range : assumeSorted;\n\n    auto r1 = assumeSorted([1, 2, 3, 3, 3, 4, 5, 6, 7, 8, 8, 8, 10]);\n    auto r2 = assumeSorted([3, 3, 4, 5, 6, 7, 8, 8]);\n    auto r3 = assumeSorted([3, 4, 5, 6, 7, 8]);\n    auto r4 = assumeSorted([4, 5, 6]);\n    auto r5 = assumeSorted([12, 13]);\n    auto r6 = assumeSorted([8, 8, 10, 11]);\n    auto r7 = assumeSorted([3, 3, 3, 3, 3, 3, 3]);\n\n    assert(find(r1, r2) == assumeSorted([3, 3, 4, 5, 6, 7, 8, 8, 8, 10]));\n    assert(find(r1, r3) == assumeSorted([3, 4, 5, 6, 7, 8, 8, 8, 10]));\n    assert(find(r1, r4) == assumeSorted([4, 5, 6, 7, 8, 8, 8, 10]));\n    assert(find(r1, r5).empty());\n    assert(find(r1, r6).empty());\n    assert(find(r1, r7).empty());\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    // @@@BUG@@@ removing static below makes unittest fail\n    static struct BiRange\n    {\n        int[] payload;\n        @property bool empty() { return payload.empty; }\n        @property BiRange save() { return this; }\n        @property ref int front() { return payload[0]; }\n        @property ref int back() { return payload[$ - 1]; }\n        void popFront() { return payload.popFront(); }\n        void popBack() { return payload.popBack(); }\n    }\n    auto r = BiRange([1, 2, 3, 10, 11, 4]);\n    assert(equal(find(r, [10, 11]), [10, 11, 4]));\n}\n\n@safe unittest\n{\n    import std.container : SList;\n\n    assert(find([ 1, 2, 3 ], SList!int(2, 3)[]) == [ 2, 3 ]);\n    assert(find([ 1, 2, 1, 2, 3, 3 ], SList!int(2, 3)[]) == [ 2, 3, 3 ]);\n}\n\n//Bug# 8334\n@safe unittest\n{\n    import std.algorithm.iteration : filter;\n    import std.range;\n\n    auto haystack = [1, 2, 3, 4, 1, 9, 12, 42];\n    auto needle = [12, 42, 27];\n\n    //different overload of find, but it's the base case.\n    assert(find(haystack, needle).empty);\n\n    assert(find(haystack, takeExactly(filter!\"true\"(needle), 3)).empty);\n    assert(find(haystack, filter!\"true\"(needle)).empty);\n}\n\n// Internally used by some find() overloads above\nprivate R1 simpleMindedFind(alias pred, R1, R2)(R1 haystack, scope R2 needle)\n{\n    enum estimateNeedleLength = hasLength!R1 && !hasLength!R2;\n\n    static if (hasLength!R1)\n    {\n        static if (!hasLength!R2)\n            size_t estimatedNeedleLength = 0;\n        else\n            immutable size_t estimatedNeedleLength = needle.length;\n    }\n\n    bool haystackTooShort()\n    {\n        static if (estimateNeedleLength)\n        {\n            return haystack.length < estimatedNeedleLength;\n        }\n        else\n        {\n            return haystack.empty;\n        }\n    }\n\n  searching:\n    for (;; haystack.popFront())\n    {\n        if (haystackTooShort())\n        {\n            // Failed search\n            static if (hasLength!R1)\n            {\n                static if (is(typeof(haystack[haystack.length ..\n                                                haystack.length]) : R1))\n                    return haystack[haystack.length .. haystack.length];\n                else\n                    return R1.init;\n            }\n            else\n            {\n                assert(haystack.empty);\n                return haystack;\n            }\n        }\n        static if (estimateNeedleLength)\n            size_t matchLength = 0;\n        for (auto h = haystack.save, n = needle.save;\n             !n.empty;\n             h.popFront(), n.popFront())\n        {\n            if (h.empty || !binaryFun!pred(h.front, n.front))\n            {\n                // Failed searching n in h\n                static if (estimateNeedleLength)\n                {\n                    if (estimatedNeedleLength < matchLength)\n                        estimatedNeedleLength = matchLength;\n                }\n                continue searching;\n            }\n            static if (estimateNeedleLength)\n                ++matchLength;\n        }\n        break;\n    }\n    return haystack;\n}\n\n@safe unittest\n{\n    // Test simpleMindedFind for the case where both haystack and needle have\n    // length.\n    struct CustomString\n    {\n    @safe:\n        string _impl;\n\n        // This is what triggers issue 7992.\n        @property size_t length() const { return _impl.length; }\n        @property void length(size_t len) { _impl.length = len; }\n\n        // This is for conformance to the forward range API (we deliberately\n        // make it non-random access so that we will end up in\n        // simpleMindedFind).\n        @property bool empty() const { return _impl.empty; }\n        @property dchar front() const { return _impl.front; }\n        void popFront() { _impl.popFront(); }\n        @property CustomString save() { return this; }\n    }\n\n    // If issue 7992 occurs, this will throw an exception from calling\n    // popFront() on an empty range.\n    auto r = find(CustomString(\"a\"), CustomString(\"b\"));\n    assert(r.empty);\n}\n\n/**\nFinds two or more `needles` into a `haystack`. The predicate $(D\npred) is used throughout to compare elements. By default, elements are\ncompared for equality.\n\nParams:\n\npred = The predicate to use for comparing elements.\n\nhaystack = The target of the search. Must be an input range.\nIf any of `needles` is a range with elements comparable to\nelements in `haystack`, then `haystack` must be a\n$(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\nsuch that the search can backtrack.\n\nneedles = One or more items to search for. Each of `needles` must\nbe either comparable to one element in `haystack`, or be itself a\nforward range with elements comparable with elements in\n`haystack`.\n\nReturns:\n\nA tuple containing `haystack` positioned to match one of the\nneedles and also the 1-based index of the matching element in $(D\nneedles) (0 if none of `needles` matched, 1 if `needles[0]`\nmatched, 2 if `needles[1]` matched...). The first needle to be found\nwill be the one that matches. If multiple needles are found at the\nsame spot in the range, then the shortest one is the one which matches\n(if multiple needles of the same length are found at the same spot (e.g\n`\"a\"` and `'a'`), then the left-most of them in the argument list\nmatches).\n\nThe relationship between `haystack` and `needles` simply means\nthat one can e.g. search for individual `int`s or arrays of $(D\nint)s in an array of `int`s. In addition, if elements are\nindividually comparable, searches of heterogeneous types are allowed\nas well: a `double[]` can be searched for an `int` or a $(D\nshort[]), and conversely a `long` can be searched for a `float`\nor a `double[]`. This makes for efficient searches without the need\nto coerce one side of the comparison into the other's side type.\n\nThe complexity of the search is $(BIGOH haystack.length *\nmax(needles.length)). (For needles that are individual items, length\nis considered to be 1.) The strategy used in searching several\nsubranges at once maximizes cache usage by moving in `haystack` as\nfew times as possible.\n */\nTuple!(Range, size_t) find(alias pred = \"a == b\", Range, Ranges...)\n(Range haystack, Ranges needles)\nif (Ranges.length > 1 && is(typeof(startsWith!pred(haystack, needles))))\n{\n    for (;; haystack.popFront())\n    {\n        size_t r = startsWith!pred(haystack, needles);\n        if (r || haystack.empty)\n        {\n            return tuple(haystack, r);\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    import std.typecons : tuple;\n    int[] a = [ 1, 4, 2, 3 ];\n    assert(find(a, 4) == [ 4, 2, 3 ]);\n    assert(find(a, [ 1, 4 ]) == [ 1, 4, 2, 3 ]);\n    assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));\n    // Mixed types allowed if comparable\n    assert(find(a, 5, [ 1.2, 3.5 ], 2.0) == tuple([ 2, 3 ], 3));\n}\n\n@safe unittest\n{\n    auto s1 = \"Mary has a little lamb\";\n    assert(find(s1, \"has a\", \"has an\") == tuple(\"has a little lamb\", 1));\n    assert(find(s1, 't', \"has a\", \"has an\") == tuple(\"has a little lamb\", 2));\n    assert(find(s1, 't', \"has a\", 'y', \"has an\") == tuple(\"y has a little lamb\", 3));\n    assert(find(\"abc\", \"bc\").length == 2);\n}\n\n@safe unittest\n{\n    import std.algorithm.internal : rndstuff;\n    import std.meta : AliasSeq;\n    import std.uni : toUpper;\n\n    int[] a = [ 1, 2, 3 ];\n    assert(find(a, 5).empty);\n    assert(find(a, 2) == [2, 3]);\n\n    foreach (T; AliasSeq!(int, double))\n    {\n        auto b = rndstuff!(T)();\n        if (!b.length) continue;\n        b[$ / 2] = 200;\n        b[$ / 4] = 200;\n        assert(find(b, 200).length == b.length - b.length / 4);\n    }\n\n    // Case-insensitive find of a string\n    string[] s = [ \"Hello\", \"world\", \"!\" ];\n    assert(find!(\"toUpper(a) == toUpper(b)\")(s, \"hello\").length == 3);\n\n    static bool f(string a, string b) { return toUpper(a) == toUpper(b); }\n    assert(find!(f)(s, \"hello\").length == 3);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.internal : rndstuff;\n    import std.meta : AliasSeq;\n    import std.range : retro;\n\n    int[] a = [ 1, 2, 3, 2, 6 ];\n    assert(find(retro(a), 5).empty);\n    assert(equal(find(retro(a), 2), [ 2, 3, 2, 1 ][]));\n\n    foreach (T; AliasSeq!(int, double))\n    {\n        auto b = rndstuff!(T)();\n        if (!b.length) continue;\n        b[$ / 2] = 200;\n        b[$ / 4] = 200;\n        assert(find(retro(b), 200).length ==\n                b.length - (b.length - 1) / 2);\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange;\n\n    int[] a = [ -1, 0, 1, 2, 3, 4, 5 ];\n    int[] b = [ 1, 2, 3 ];\n    assert(find(a, b) == [ 1, 2, 3, 4, 5 ]);\n    assert(find(b, a).empty);\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType d;\n        auto findRes = find(d, 5);\n        assert(equal(findRes, [5,6,7,8,9,10]));\n    }\n}\n\n/**\n * Finds `needle` in `haystack` efficiently using the\n * $(LINK2 https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm,\n * Boyer-Moore) method.\n *\n * Params:\n * haystack = A random-access range with length and slicing.\n * needle = A $(LREF BoyerMooreFinder).\n *\n * Returns:\n * `haystack` advanced such that `needle` is a prefix of it (if no\n * such position exists, returns `haystack` advanced to termination).\n */\nRandomAccessRange find(RandomAccessRange, alias pred, InputRange)(\n    RandomAccessRange haystack, scope BoyerMooreFinder!(pred, InputRange) needle)\n{\n    return needle.beFound(haystack);\n}\n\n@safe unittest\n{\n    string h = \"/homes/aalexand/d/dmd/bin/../lib/libphobos.a(dmain2.o)\"~\n        \"(.gnu.linkonce.tmain+0x74): In function `main' undefined reference\"~\n        \" to `_Dmain':\";\n    string[] ns = [\"libphobos\", \"function\", \" undefined\", \"`\", \":\"];\n    foreach (n ; ns)\n    {\n        auto p = find(h, boyerMooreFinder(n));\n        assert(!p.empty);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.range.primitives : empty;\n    int[] a = [ -1, 0, 1, 2, 3, 4, 5 ];\n    int[] b = [ 1, 2, 3 ];\n\n    assert(find(a, boyerMooreFinder(b)) == [ 1, 2, 3, 4, 5 ]);\n    assert(find(b, boyerMooreFinder(a)).empty);\n}\n\n@safe unittest\n{\n    auto bm = boyerMooreFinder(\"for\");\n    auto match = find(\"Moor\", bm);\n    assert(match.empty);\n}\n\n// canFind\n/++\nConvenience function. Like find, but only returns whether or not the search\nwas successful.\n\nSee_Also:\n$(REF among, std,algorithm,comparison) for checking a value against multiple possibilities.\n +/\ntemplate canFind(alias pred=\"a == b\")\n{\n    import std.meta : allSatisfy;\n\n    /++\n    Returns `true` if and only if any value `v` found in the\n    input range `range` satisfies the predicate `pred`.\n    Performs (at most) $(BIGOH haystack.length) evaluations of `pred`.\n     +/\n    bool canFind(Range)(Range haystack)\n    if (is(typeof(find!pred(haystack))))\n    {\n        return any!pred(haystack);\n    }\n\n    /++\n    Returns `true` if and only if `needle` can be found in $(D\n    range). Performs $(BIGOH haystack.length) evaluations of `pred`.\n     +/\n    bool canFind(Range, Element)(Range haystack, scope Element needle)\n    if (is(typeof(find!pred(haystack, needle))))\n    {\n        return !find!pred(haystack, needle).empty;\n    }\n\n    /++\n    Returns the 1-based index of the first needle found in `haystack`. If no\n    needle is found, then `0` is returned.\n\n    So, if used directly in the condition of an if statement or loop, the result\n    will be `true` if one of the needles is found and `false` if none are\n    found, whereas if the result is used elsewhere, it can either be cast to\n    `bool` for the same effect or used to get which needle was found first\n    without having to deal with the tuple that `LREF find` returns for the\n    same operation.\n     +/\n    size_t canFind(Range, Ranges...)(Range haystack, scope Ranges needles)\n    if (Ranges.length > 1 &&\n        allSatisfy!(isForwardRange, Ranges) &&\n        is(typeof(find!pred(haystack, needles))))\n    {\n        return find!pred(haystack, needles)[1];\n    }\n}\n\n///\n@safe unittest\n{\n    assert(canFind([0, 1, 2, 3], 2) == true);\n    assert(canFind([0, 1, 2, 3], [1, 2], [2, 3]));\n    assert(canFind([0, 1, 2, 3], [1, 2], [2, 3]) == 1);\n    assert(canFind([0, 1, 2, 3], [1, 7], [2, 3]));\n    assert(canFind([0, 1, 2, 3], [1, 7], [2, 3]) == 2);\n\n    assert(canFind([0, 1, 2, 3], 4) == false);\n    assert(!canFind([0, 1, 2, 3], [1, 3], [2, 4]));\n    assert(canFind([0, 1, 2, 3], [1, 3], [2, 4]) == 0);\n}\n\n/**\n * Example using a custom predicate.\n * Note that the needle appears as the second argument of the predicate.\n */\n@safe unittest\n{\n    auto words = [\n        \"apple\",\n        \"beeswax\",\n        \"cardboard\"\n    ];\n    assert(!canFind(words, \"bees\"));\n    assert( canFind!((string a, string b) => a.startsWith(b))(words, \"bees\"));\n}\n\n@safe unittest\n{\n    import std.algorithm.internal : rndstuff;\n\n    auto a = rndstuff!(int)();\n    if (a.length)\n    {\n        auto b = a[a.length / 2];\n        assert(canFind(a, b));\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    assert(equal!(canFind!\"a < b\")([[1, 2, 3], [7, 8, 9]], [2, 8]));\n}\n\n// findAdjacent\n/**\nAdvances `r` until it finds the first two adjacent elements `a`,\n`b` that satisfy `pred(a, b)`. Performs $(BIGOH r.length)\nevaluations of `pred`.\n\nParams:\n    pred = The predicate to satisfy.\n    r = A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to\n        search in.\n\nReturns:\n`r` advanced to the first occurrence of two adjacent elements that satisfy\nthe given predicate. If there are no such two elements, returns `r` advanced\nuntil empty.\n\nSee_Also:\n     $(LINK2 http://en.cppreference.com/w/cpp/algorithm/adjacent_find, STL's `adjacent_find`)\n*/\nRange findAdjacent(alias pred = \"a == b\", Range)(Range r)\nif (isForwardRange!(Range))\n{\n    auto ahead = r.save;\n    if (!ahead.empty)\n    {\n        for (ahead.popFront(); !ahead.empty; r.popFront(), ahead.popFront())\n        {\n            if (binaryFun!(pred)(r.front, ahead.front)) return r;\n        }\n    }\n    static if (!isInfinite!Range)\n        return ahead;\n}\n\n///\n@safe unittest\n{\n    int[] a = [ 11, 10, 10, 9, 8, 8, 7, 8, 9 ];\n    auto r = findAdjacent(a);\n    assert(r == [ 10, 10, 9, 8, 8, 7, 8, 9 ]);\n    auto p = findAdjacent!(\"a < b\")(a);\n    assert(p == [ 7, 8, 9 ]);\n\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange;\n    import std.range;\n\n    int[] a = [ 11, 10, 10, 9, 8, 8, 7, 8, 9 ];\n    auto p = findAdjacent(a);\n    assert(p == [10, 10, 9, 8, 8, 7, 8, 9 ]);\n    p = findAdjacent!(\"a < b\")(a);\n    assert(p == [7, 8, 9]);\n    // empty\n    a = [];\n    p = findAdjacent(a);\n    assert(p.empty);\n    // not found\n    a = [ 1, 2, 3, 4, 5 ];\n    p = findAdjacent(a);\n    assert(p.empty);\n    p = findAdjacent!\"a > b\"(a);\n    assert(p.empty);\n    ReferenceForwardRange!int rfr = new ReferenceForwardRange!int([1, 2, 3, 2, 2, 3]);\n    assert(equal(findAdjacent(rfr), [2, 2, 3]));\n\n    // Issue 9350\n    assert(!repeat(1).findAdjacent().empty);\n}\n\n// findAmong\n/**\nSearches the given range for an element that matches one of the given choices.\n\nAdvances `seq` by calling `seq.popFront` until either\n`find!(pred)(choices, seq.front)` is `true`, or `seq` becomes empty.\nPerforms $(BIGOH seq.length * choices.length) evaluations of `pred`.\n\nParams:\n    pred = The predicate to use for determining a match.\n    seq = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to\n        search.\n    choices = A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n        of possible choices.\n\nReturns:\n`seq` advanced to the first matching element, or until empty if there are no\nmatching elements.\n\nSee_Also: $(LREF find), $(REF std,algorithm,comparison,among)\n*/\nInputRange findAmong(alias pred = \"a == b\", InputRange, ForwardRange)(\n    InputRange seq, ForwardRange choices)\nif (isInputRange!InputRange && isForwardRange!ForwardRange)\n{\n    for (; !seq.empty && find!pred(choices, seq.front).empty; seq.popFront())\n    {\n    }\n    return seq;\n}\n\n///\n@safe unittest\n{\n    int[] a = [ -1, 0, 1, 2, 3, 4, 5 ];\n    int[] b = [ 3, 1, 2 ];\n    assert(findAmong(a, b) == a[2 .. $]);\n}\n\n@safe unittest\n{\n    int[] a = [ -1, 0, 2, 1, 2, 3, 4, 5 ];\n    int[] b = [ 1, 2, 3 ];\n    assert(findAmong(a, b) == [2, 1, 2, 3, 4, 5 ]);\n    assert(findAmong(b, [ 4, 6, 7 ][]).empty);\n    assert(findAmong!(\"a == b\")(a, b).length == a.length - 2);\n    assert(findAmong!(\"a == b\")(b, [ 4, 6, 7 ][]).empty);\n}\n\n// findSkip\n/**\n * Finds `needle` in `haystack` and positions `haystack`\n * right after the first occurrence of `needle`.\n *\n * If no needle is provided, the `haystack` is advanced as long as `pred`\n * evaluates to `true`.\n * Similarly, the haystack is positioned so as `pred` evaluates to `false` for\n * `haystack.front`.\n *\n * Params:\n *  haystack = The\n *   $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to search\n *   in.\n *  needle = The\n *   $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to search\n *   for.\n *  pred = Custom predicate for comparison of haystack and needle\n *\n * Returns: `true` if the needle was found, in which case `haystack` is\n * positioned after the end of the first occurrence of `needle`; otherwise\n * `false`, leaving `haystack` untouched. If no needle is provided, it returns\n *  the number of times `pred(haystack.front)` returned true.\n *\n * See_Also: $(LREF find)\n */\nbool findSkip(alias pred = \"a == b\", R1, R2)(ref R1 haystack, R2 needle)\nif (isForwardRange!R1 && isForwardRange!R2\n        && is(typeof(binaryFun!pred(haystack.front, needle.front))))\n{\n    auto parts = findSplit!pred(haystack, needle);\n    if (parts[1].empty) return false;\n    // found\n    haystack = parts[2];\n    return true;\n}\n\n///\n@safe unittest\n{\n    import std.range.primitives : empty;\n    // Needle is found; s is replaced by the substring following the first\n    // occurrence of the needle.\n    string s = \"abcdef\";\n    assert(findSkip(s, \"cd\") && s == \"ef\");\n\n    // Needle is not found; s is left untouched.\n    s = \"abcdef\";\n    assert(!findSkip(s, \"cxd\") && s == \"abcdef\");\n\n    // If the needle occurs at the end of the range, the range is left empty.\n    s = \"abcdef\";\n    assert(findSkip(s, \"def\") && s.empty);\n}\n\n@safe unittest // issue 19020\n{\n    static struct WrapperRange\n    {\n        string _r;\n        @property auto empty() { return _r.empty(); }\n        @property auto front() { return _r.front(); }\n        auto popFront() { return _r.popFront(); }\n        @property auto save() { return WrapperRange(_r.save); }\n    }\n    auto tmp = WrapperRange(\"there is a bug here: *\");\n    assert(!tmp.findSkip(\"*/\"));\n    assert(tmp._r == \"there is a bug here: *\");\n}\n\n/// ditto\nsize_t findSkip(alias pred, R1)(ref R1 haystack)\nif (isForwardRange!R1 && ifTestable!(typeof(haystack.front), unaryFun!pred))\n{\n    size_t result;\n    while (!haystack.empty && unaryFun!pred(haystack.front))\n    {\n        result++;\n        haystack.popFront;\n    }\n    return result;\n}\n\n///\n@safe unittest\n{\n    import std.ascii : isWhite;\n    string s = \"    abc\";\n    assert(findSkip!isWhite(s) && s == \"abc\");\n    assert(!findSkip!isWhite(s) && s == \"abc\");\n\n    s = \"  \";\n    assert(findSkip!isWhite(s) == 2);\n}\n\n@safe unittest\n{\n    import std.ascii : isWhite;\n\n    auto s = \"  \";\n    assert(findSkip!isWhite(s) == 2);\n}\n\n/**\nThese functions find the first occurrence of `needle` in `haystack` and then\nsplit `haystack` as follows.\n\n`findSplit` returns a tuple `result` containing $(I three) ranges. `result[0]`\nis the portion of `haystack` before `needle`, `result[1]` is the portion of\n`haystack` that matches `needle`, and `result[2]` is the portion of `haystack`\nafter the match. If `needle` was not found, `result[0]` comprehends `haystack`\nentirely and `result[1]` and `result[2]` are empty.\n\n`findSplitBefore` returns a tuple `result` containing two ranges. `result[0]` is\nthe portion of `haystack` before `needle`, and `result[1]` is the balance of\n`haystack` starting with the match. If `needle` was not found, `result[0]`\ncomprehends `haystack` entirely and `result[1]` is empty.\n\n`findSplitAfter` returns a tuple `result` containing two ranges.\n`result[0]` is the portion of `haystack` up to and including the\nmatch, and `result[1]` is the balance of `haystack` starting\nafter the match. If `needle` was not found, `result[0]` is empty\nand `result[1]` is `haystack`.\n\nIn all cases, the concatenation of the returned ranges spans the\nentire `haystack`.\n\nIf `haystack` is a random-access range, all three components of the tuple have\nthe same type as `haystack`. Otherwise, `haystack` must be a\n$(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) and\nthe type of `result[0]` and `result[1]` is the same as $(REF takeExactly,\nstd,range).\n\nParams:\n    pred = Predicate to use for comparing needle against haystack.\n    haystack = The range to search.\n    needle = What to look for.\n\nReturns:\n\nA sub-type of `Tuple!()` of the split portions of `haystack` (see above for\ndetails).  This sub-type of `Tuple!()` has `opCast` defined for `bool`.  This\n`opCast` returns `true` when the separating `needle` was found\nand `false` otherwise.\n\nSee_Also: $(LREF find)\n */\nauto findSplit(alias pred = \"a == b\", R1, R2)(R1 haystack, R2 needle)\nif (isForwardRange!R1 && isForwardRange!R2)\n{\n    static struct Result(S1, S2) if (isForwardRange!S1 &&\n                                     isForwardRange!S2)\n    {\n        this(S1 pre, S1 separator, S2 post)\n        {\n            asTuple = typeof(asTuple)(pre, separator, post);\n        }\n        void opAssign(typeof(asTuple) rhs)\n        {\n            asTuple = rhs;\n        }\n        Tuple!(S1, S1, S2) asTuple;\n        bool opCast(T : bool)()\n        {\n            return !asTuple[1].empty;\n        }\n        alias asTuple this;\n    }\n\n    static if (isSomeString!R1 && isSomeString!R2\n            || (isRandomAccessRange!R1 && hasSlicing!R1 && hasLength!R1 && hasLength!R2))\n    {\n        auto balance = find!pred(haystack, needle);\n        immutable pos1 = haystack.length - balance.length;\n        immutable pos2 = balance.empty ? pos1 : pos1 + needle.length;\n        return Result!(typeof(haystack[0 .. pos1]),\n                       typeof(haystack[pos2 .. haystack.length]))(haystack[0 .. pos1],\n                                                                  haystack[pos1 .. pos2],\n                                                                  haystack[pos2 .. haystack.length]);\n    }\n    else\n    {\n        import std.range : takeExactly;\n        auto original = haystack.save;\n        auto h = haystack.save;\n        auto n = needle.save;\n        size_t pos1, pos2;\n        while (!n.empty && !h.empty)\n        {\n            if (binaryFun!pred(h.front, n.front))\n            {\n                h.popFront();\n                n.popFront();\n                ++pos2;\n            }\n            else\n            {\n                haystack.popFront();\n                n = needle.save;\n                h = haystack.save;\n                pos2 = ++pos1;\n            }\n        }\n        if (!n.empty) // incomplete match at the end of haystack\n        {\n            pos1 = pos2;\n        }\n        return Result!(typeof(takeExactly(original, pos1)),\n                       typeof(h))(takeExactly(original, pos1),\n                                  takeExactly(haystack, pos2 - pos1),\n                                  h);\n    }\n}\n\n/// Ditto\nauto findSplitBefore(alias pred = \"a == b\", R1, R2)(R1 haystack, R2 needle)\nif (isForwardRange!R1 && isForwardRange!R2)\n{\n    static struct Result(S1, S2) if (isForwardRange!S1 &&\n                                     isForwardRange!S2)\n    {\n        this(S1 pre, S2 post)\n        {\n            asTuple = typeof(asTuple)(pre, post);\n        }\n        void opAssign(typeof(asTuple) rhs)\n        {\n            asTuple = rhs;\n        }\n        Tuple!(S1, S2) asTuple;\n        bool opCast(T : bool)()\n        {\n            return !asTuple[1].empty;\n        }\n        alias asTuple this;\n    }\n\n    static if (isSomeString!R1 && isSomeString!R2\n            || (isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && hasLength!R2))\n    {\n        auto balance = find!pred(haystack, needle);\n        immutable pos = haystack.length - balance.length;\n        return Result!(typeof(haystack[0 .. pos]),\n                       typeof(haystack[pos .. haystack.length]))(haystack[0 .. pos],\n                                                                 haystack[pos .. haystack.length]);\n    }\n    else\n    {\n        import std.range : takeExactly;\n        auto original = haystack.save;\n        auto h = haystack.save;\n        auto n = needle.save;\n        size_t pos1, pos2;\n        while (!n.empty && !h.empty)\n        {\n            if (binaryFun!pred(h.front, n.front))\n            {\n                h.popFront();\n                n.popFront();\n                ++pos2;\n            }\n            else\n            {\n                haystack.popFront();\n                n = needle.save;\n                h = haystack.save;\n                pos2 = ++pos1;\n            }\n        }\n        if (!n.empty) // incomplete match at the end of haystack\n        {\n            pos1 = pos2;\n            haystack = h;\n        }\n        return Result!(typeof(takeExactly(original, pos1)),\n                       typeof(haystack))(takeExactly(original, pos1),\n                                         haystack);\n    }\n}\n\n/// Ditto\nauto findSplitAfter(alias pred = \"a == b\", R1, R2)(R1 haystack, R2 needle)\nif (isForwardRange!R1 && isForwardRange!R2)\n{\n    static struct Result(S1, S2) if (isForwardRange!S1 &&\n                                     isForwardRange!S2)\n    {\n        this(S1 pre, S2 post)\n        {\n            asTuple = typeof(asTuple)(pre, post);\n        }\n        void opAssign(typeof(asTuple) rhs)\n        {\n            asTuple = rhs;\n        }\n        Tuple!(S1, S2) asTuple;\n        bool opCast(T : bool)()\n        {\n            return !asTuple[0].empty;\n        }\n        alias asTuple this;\n    }\n\n    static if (isSomeString!R1 && isSomeString!R2\n            || isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && hasLength!R2)\n    {\n        auto balance = find!pred(haystack, needle);\n        immutable pos = balance.empty ? 0 : haystack.length - balance.length + needle.length;\n        return Result!(typeof(haystack[0 .. pos]),\n                       typeof(haystack[pos .. haystack.length]))(haystack[0 .. pos],\n                                                                 haystack[pos .. haystack.length]);\n    }\n    else\n    {\n        import std.range : takeExactly;\n        auto original = haystack.save;\n        auto h = haystack.save;\n        auto n = needle.save;\n        size_t pos1, pos2;\n        while (!n.empty)\n        {\n            if (h.empty)\n            {\n                // Failed search\n                return Result!(typeof(takeExactly(original, 0)),\n                               typeof(original))(takeExactly(original, 0),\n                                                 original);\n            }\n            if (binaryFun!pred(h.front, n.front))\n            {\n                h.popFront();\n                n.popFront();\n                ++pos2;\n            }\n            else\n            {\n                haystack.popFront();\n                n = needle.save;\n                h = haystack.save;\n                pos2 = ++pos1;\n            }\n        }\n        return Result!(typeof(takeExactly(original, pos2)),\n                       typeof(h))(takeExactly(original, pos2),\n                                  h);\n    }\n}\n\n/// Returning a subtype of $(REF Tuple, std,typecons) enables\n/// the following convenient idiom:\n@safe pure nothrow unittest\n{\n    // findSplit returns a triplet\n    if (auto split = \"dlang-rocks\".findSplit(\"-\"))\n        assert(split[2] == \"rocks\");\n}\n\n///\n@safe pure nothrow unittest\n{\n    import std.range.primitives : empty;\n\n    auto a = \"Carl Sagan Memorial Station\";\n    auto r = findSplit(a, \"Velikovsky\");\n    import std.typecons : isTuple;\n    static assert(isTuple!(typeof(r.asTuple)));\n    static assert(isTuple!(typeof(r)));\n    assert(!r);\n    assert(r[0] == a);\n    assert(r[1].empty);\n    assert(r[2].empty);\n    r = findSplit(a, \" \");\n    assert(r[0] == \"Carl\");\n    assert(r[1] == \" \");\n    assert(r[2] == \"Sagan Memorial Station\");\n    auto r1 = findSplitBefore(a, \"Sagan\");\n    assert(r1);\n    assert(r1[0] == \"Carl \");\n    assert(r1[1] == \"Sagan Memorial Station\");\n    auto r2 = findSplitAfter(a, \"Sagan\");\n    assert(r2);\n    assert(r2[0] == \"Carl Sagan\");\n    assert(r2[1] == \" Memorial Station\");\n}\n\n/// Use $(REF only, std,range) to find single elements:\n@safe pure nothrow unittest\n{\n    import std.range : only;\n    assert([1, 2, 3, 4].findSplitBefore(only(3))[0] == [1, 2]);\n}\n\n@safe pure nothrow unittest\n{\n    import std.range.primitives : empty;\n\n    auto a = [ 1, 2, 3, 4, 5, 6, 7, 8 ];\n    auto r = findSplit(a, [9, 1]);\n    assert(!r);\n    assert(r[0] == a);\n    assert(r[1].empty);\n    assert(r[2].empty);\n    r = findSplit(a, [3]);\n    assert(r);\n    assert(r[0] == a[0 .. 2]);\n    assert(r[1] == a[2 .. 3]);\n    assert(r[2] == a[3 .. $]);\n\n    auto r1 = findSplitBefore(a, [9, 1]);\n    assert(!r1);\n    assert(r1[0] == a);\n    assert(r1[1].empty);\n    r1 = findSplitBefore(a, [3, 4]);\n    assert(r1);\n    assert(r1[0] == a[0 .. 2]);\n    assert(r1[1] == a[2 .. $]);\n\n    auto r2 = findSplitAfter(a, [9, 1]);\n    assert(!r2);\n    assert(r2[0].empty);\n    assert(r2[1] == a);\n    r2 = findSplitAfter(a, [3, 4]);\n    assert(r2);\n    assert(r2[0] == a[0 .. 4]);\n    assert(r2[1] == a[4 .. $]);\n}\n\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter;\n\n    auto a = [ 1, 2, 3, 4, 5, 6, 7, 8 ];\n    auto fwd = filter!\"a > 0\"(a);\n    auto r = findSplit(fwd, [9, 1]);\n    assert(!r);\n    assert(equal(r[0], a));\n    assert(r[1].empty);\n    assert(r[2].empty);\n    r = findSplit(fwd, [3]);\n    assert(r);\n    assert(equal(r[0],  a[0 .. 2]));\n    assert(equal(r[1], a[2 .. 3]));\n    assert(equal(r[2], a[3 .. $]));\n    r = findSplit(fwd, [8, 9]);\n    assert(!r);\n    assert(equal(r[0], a));\n    assert(r[1].empty);\n    assert(r[2].empty);\n\n    auto r1 = findSplitBefore(fwd, [9, 1]);\n    assert(!r1);\n    assert(equal(r1[0], a));\n    assert(r1[1].empty);\n    r1 = findSplitBefore(fwd, [3, 4]);\n    assert(r1);\n    assert(equal(r1[0], a[0 .. 2]));\n    assert(equal(r1[1], a[2 .. $]));\n    r1 = findSplitBefore(fwd, [8, 9]);\n    assert(!r1);\n    assert(equal(r1[0], a));\n    assert(r1[1].empty);\n\n    auto r2 = findSplitAfter(fwd, [9, 1]);\n    assert(!r2);\n    assert(r2[0].empty);\n    assert(equal(r2[1], a));\n    r2 = findSplitAfter(fwd, [3, 4]);\n    assert(r2);\n    assert(equal(r2[0], a[0 .. 4]));\n    assert(equal(r2[1], a[4 .. $]));\n    r2 = findSplitAfter(fwd, [8, 9]);\n    assert(!r2);\n    assert(r2[0].empty);\n    assert(equal(r2[1], a));\n}\n\n@safe pure nothrow @nogc unittest\n{\n    auto str = \"sep,one,sep,two\";\n\n    auto split = str.findSplitAfter(\",\");\n    assert(split[0] == \"sep,\");\n\n    split = split[1].findSplitAfter(\",\");\n    assert(split[0] == \"one,\");\n\n    split = split[1].findSplitBefore(\",\");\n    assert(split[0] == \"sep\");\n}\n\n@safe pure nothrow @nogc unittest\n{\n    auto str = \"sep,one,sep,two\";\n\n    auto split = str.findSplitBefore(\",two\");\n    assert(split[0] == \"sep,one,sep\");\n    assert(split[1] == \",two\");\n\n    split = split[0].findSplitBefore(\",sep\");\n    assert(split[0] == \"sep,one\");\n    assert(split[1] == \",sep\");\n\n    split = split[0].findSplitAfter(\",\");\n    assert(split[0] == \"sep,\");\n    assert(split[1] == \"one\");\n}\n\n// minCount\n/**\n\nComputes the minimum (respectively maximum) of `range` along with its number of\noccurrences. Formally, the minimum is a value `x` in `range` such that $(D\npred(a, x)) is `false` for all values `a` in `range`. Conversely, the maximum is\na value `x` in `range` such that `pred(x, a)` is `false` for all values `a`\nin `range` (note the swapped arguments to `pred`).\n\nThese functions may be used for computing arbitrary extrema by choosing `pred`\nappropriately. For corrrect functioning, `pred` must be a strict partial order,\ni.e. transitive (if `pred(a, b) && pred(b, c)` then `pred(a, c)`) and\nirreflexive (`pred(a, a)` is `false`). The $(LUCKY trichotomy property of\ninequality) is not required: these algoritms consider elements `a` and `b` equal\n(for the purpose of counting) if `pred` puts them in the same equivalence class,\ni.e. `!pred(a, b) && !pred(b, a)`.\n\nParams:\n    pred = The ordering predicate to use to determine the extremum (minimum\n        or maximum).\n    range = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to count.\n\nReturns: The minimum, respectively maximum element of a range together with the\nnumber it occurs in the range.\n\nThrows: `Exception` if `range.empty`.\n\nSee_Also: $(REF min, std,algorithm,comparison), $(LREF minIndex), $(LREF minElement), $(LREF minPos)\n */\nTuple!(ElementType!Range, size_t)\nminCount(alias pred = \"a < b\", Range)(Range range)\nif (isInputRange!Range && !isInfinite!Range &&\n    is(typeof(binaryFun!pred(range.front, range.front))))\n{\n    import std.algorithm.internal : algoFormat;\n    import std.exception : enforce;\n\n    alias T  = ElementType!Range;\n    alias UT = Unqual!T;\n    alias RetType = Tuple!(T, size_t);\n\n    static assert(is(typeof(RetType(range.front, 1))),\n        algoFormat(\"Error: Cannot call minCount on a %s, because it is not possible \"~\n               \"to copy the result value (a %s) into a Tuple.\", Range.stringof, T.stringof));\n\n    enforce(!range.empty, \"Can't count elements from an empty range\");\n    size_t occurrences = 1;\n\n    static if (isForwardRange!Range)\n    {\n        Range least = range.save;\n        for (range.popFront(); !range.empty; range.popFront())\n        {\n            if (binaryFun!pred(least.front, range.front))\n            {\n                assert(!binaryFun!pred(range.front, least.front),\n                    \"min/maxPos: predicate must be a strict partial order.\");\n                continue;\n            }\n            if (binaryFun!pred(range.front, least.front))\n            {\n                // change the min\n                least = range.save;\n                occurrences = 1;\n            }\n            else\n                ++occurrences;\n        }\n        return RetType(least.front, occurrences);\n    }\n    else static if (isAssignable!(UT, T) || (!hasElaborateAssign!UT && isAssignable!UT))\n    {\n        UT v = UT.init;\n        static if (isAssignable!(UT, T)) v = range.front;\n        else                             v = cast(UT) range.front;\n\n        for (range.popFront(); !range.empty; range.popFront())\n        {\n            if (binaryFun!pred(*cast(T*)&v, range.front)) continue;\n            if (binaryFun!pred(range.front, *cast(T*)&v))\n            {\n                // change the min\n                static if (isAssignable!(UT, T)) v = range.front;\n                else                             v = cast(UT) range.front; //Safe because !hasElaborateAssign!UT\n                occurrences = 1;\n            }\n            else\n                ++occurrences;\n        }\n        return RetType(*cast(T*)&v, occurrences);\n    }\n    else static if (hasLvalueElements!Range)\n    {\n        import std.algorithm.internal : addressOf;\n        T* p = addressOf(range.front);\n        for (range.popFront(); !range.empty; range.popFront())\n        {\n            if (binaryFun!pred(*p, range.front)) continue;\n            if (binaryFun!pred(range.front, *p))\n            {\n                // change the min\n                p = addressOf(range.front);\n                occurrences = 1;\n            }\n            else\n                ++occurrences;\n        }\n        return RetType(*p, occurrences);\n    }\n    else\n        static assert(false,\n            algoFormat(\"Sorry, can't find the minCount of a %s: Don't know how \"~\n                   \"to keep track of the smallest %s element.\", Range.stringof, T.stringof));\n}\n\n/// Ditto\nTuple!(ElementType!Range, size_t)\nmaxCount(alias pred = \"a < b\", Range)(Range range)\nif (isInputRange!Range && !isInfinite!Range &&\n    is(typeof(binaryFun!pred(range.front, range.front))))\n{\n    return range.minCount!((a, b) => binaryFun!pred(b, a));\n}\n\n///\n@safe unittest\n{\n    import std.conv : text;\n    import std.typecons : tuple;\n\n    int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];\n    // Minimum is 1 and occurs 3 times\n    assert(a.minCount == tuple(1, 3));\n    // Maximum is 4 and occurs 2 times\n    assert(a.maxCount == tuple(4, 2));\n}\n\n@system unittest\n{\n    import std.conv : text;\n    import std.exception : assertThrown;\n    import std.internal.test.dummyrange;\n\n    int[][] b = [ [4], [2, 4], [4], [4] ];\n    auto c = minCount!(\"a[0] < b[0]\")(b);\n    assert(c == tuple([2, 4], 1), text(c[0]));\n\n    //Test empty range\n    assertThrown(minCount(b[$..$]));\n\n    //test with reference ranges. Test both input and forward.\n    assert(minCount(new ReferenceInputRange!int([1, 2, 1, 0, 2, 0])) == tuple(0, 2));\n    assert(minCount(new ReferenceForwardRange!int([1, 2, 1, 0, 2, 0])) == tuple(0, 2));\n}\n\n@system unittest\n{\n    import std.conv : text;\n    import std.meta : AliasSeq;\n\n    static struct R(T) //input range\n    {\n        T[] arr;\n        alias arr this;\n    }\n\n    immutable         a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];\n    R!(immutable int) b = R!(immutable int)(a);\n\n    assert(minCount(a) == tuple(1, 3));\n    assert(minCount(b) == tuple(1, 3));\n    assert(minCount!((ref immutable int a, ref immutable int b) => (a > b))(a) == tuple(4, 2));\n    assert(minCount!((ref immutable int a, ref immutable int b) => (a > b))(b) == tuple(4, 2));\n\n    immutable(int[])[] c = [ [4], [2, 4], [4], [4] ];\n    assert(minCount!(\"a[0] < b[0]\")(c) == tuple([2, 4], 1), text(c[0]));\n\n    static struct S1\n    {\n        int i;\n    }\n    alias IS1 = immutable(S1);\n    static assert( isAssignable!S1);\n    static assert( isAssignable!(S1, IS1));\n\n    static struct S2\n    {\n        int* p;\n        this(ref immutable int i) immutable {p = &i;}\n        this(ref int i) {p = &i;}\n        @property ref inout(int) i() inout {return *p;}\n        bool opEquals(const S2 other) const {return i == other.i;}\n    }\n    alias IS2 = immutable(S2);\n    static assert( isAssignable!S2);\n    static assert(!isAssignable!(S2, IS2));\n    static assert(!hasElaborateAssign!S2);\n\n    static struct S3\n    {\n        int i;\n        void opAssign(ref S3 other) @disable;\n    }\n    static assert(!isAssignable!S3);\n\n    static foreach (Type; AliasSeq!(S1, IS1, S2, IS2, S3))\n    {{\n        static if (is(Type == immutable)) alias V = immutable int;\n        else                              alias V = int;\n        V one = 1, two = 2;\n        auto r1 = [Type(two), Type(one), Type(one)];\n        auto r2 = R!Type(r1);\n        assert(minCount!\"a.i < b.i\"(r1) == tuple(Type(one), 2));\n        assert(minCount!\"a.i < b.i\"(r2) == tuple(Type(one), 2));\n        assert(one == 1 && two == 2);\n    }}\n}\n\n/**\nIterates the passed range and returns the minimal element.\nA custom mapping function can be passed to `map`.\nIn other languages this is sometimes called `argmin`.\n\nComplexity: O(n)\n    Exactly `n - 1` comparisons are needed.\n\nParams:\n    map = custom accessor for the comparison key\n    r = range from which the minimal element will be selected\n    seed = custom seed to use as initial element\n\nReturns: The minimal element of the passed-in range.\n\nSee_Also:\n\n    $(LREF maxElement), $(REF min, std,algorithm,comparison), $(LREF minCount),\n    $(LREF minIndex), $(LREF minPos)\n*/\nauto minElement(alias map = (a => a), Range)(Range r)\nif (isInputRange!Range && !isInfinite!Range)\n{\n    return extremum!map(r);\n}\n\n/// ditto\nauto minElement(alias map = (a => a), Range, RangeElementType = ElementType!Range)\n               (Range r, RangeElementType seed)\nif (isInputRange!Range && !isInfinite!Range &&\n    !is(CommonType!(ElementType!Range, RangeElementType) == void))\n{\n    return extremum!map(r, seed);\n}\n\n///\n@safe pure unittest\n{\n    import std.range : enumerate;\n    import std.typecons : tuple;\n\n    assert([2, 7, 1, 3].minElement == 1);\n\n    // allows to get the index of an element too\n    assert([5, 3, 7, 9].enumerate.minElement!\"a.value\" == tuple(1, 3));\n\n    // any custom accessor can be passed\n    assert([[0, 4], [1, 2]].minElement!\"a[1]\" == [1, 2]);\n\n    // can be seeded\n    int[] arr;\n    assert(arr.minElement(1) == 1);\n}\n\n@safe pure unittest\n{\n    import std.range : enumerate, iota;\n    // supports mapping\n    assert([3, 4, 5, 1, 2].enumerate.minElement!\"a.value\" == tuple(3, 1));\n    assert([5, 2, 4].enumerate.minElement!\"a.value\" == tuple(1, 2));\n\n    // forward ranges\n    assert(iota(1, 5).minElement() == 1);\n    assert(iota(2, 5).enumerate.minElement!\"a.value\" == tuple(0, 2));\n\n    // should work with const\n    const(int)[] immArr = [2, 1, 3];\n    assert(immArr.minElement == 1);\n\n    // should work with immutable\n    immutable(int)[] immArr2 = [2, 1, 3];\n    assert(immArr2.minElement == 1);\n\n    // with strings\n    assert([\"b\", \"a\", \"c\"].minElement == \"a\");\n\n    // with all dummy ranges\n    import std.internal.test.dummyrange;\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType d;\n        assert(d.minElement == 1);\n        assert(d.minElement!(a => a) == 1);\n        assert(d.minElement!(a => -a) == 10);\n    }\n\n    // with empty, but seeded ranges\n    int[] arr;\n    assert(arr.minElement(42) == 42);\n    assert(arr.minElement!(a => a)(42) == 42);\n}\n\n@nogc @safe nothrow pure unittest\n{\n    static immutable arr = [7, 3, 4, 2, 1, 8];\n    assert(arr.minElement == 1);\n\n    static immutable arr2d = [[1, 9], [3, 1], [4, 2]];\n    assert(arr2d.minElement!\"a[1]\" == arr2d[1]);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17982\n@safe unittest\n{\n    struct A\n    {\n      int val;\n    }\n\n    const(A)[] v = [A(0)];\n    assert(v.minElement!\"a.val\" == A(0));\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17982\n@safe unittest\n{\n    class B\n    {\n        int val;\n        this(int val){ this.val = val; }\n    }\n\n    const(B) doStuff(const(B)[] v)\n    {\n        return v.minElement!\"a.val\";\n    }\n    assert(doStuff([new B(1), new B(0), new B(2)]).val == 0);\n\n    const(B)[] arr = [new B(0), new B(1)];\n    // can't compare directly - https://issues.dlang.org/show_bug.cgi?id=1824\n    assert(arr.minElement!\"a.val\".val == 0);\n}\n\n/**\nIterates the passed range and returns the maximal element.\nA custom mapping function can be passed to `map`.\nIn other languages this is sometimes called `argmax`.\n\nComplexity:\n    Exactly `n - 1` comparisons are needed.\n\nParams:\n    map = custom accessor for the comparison key\n    r = range from which the maximum will be selected\n    seed = custom seed to use as initial element\n\nReturns: The maximal element of the passed-in range.\n\n\nSee_Also:\n\n    $(LREF minElement), $(REF max, std,algorithm,comparison), $(LREF maxCount),\n    $(LREF maxIndex), $(LREF maxPos)\n*/\nauto maxElement(alias map = (a => a), Range)(Range r)\nif (isInputRange!Range && !isInfinite!Range)\n{\n    return extremum!(map, \"a > b\")(r);\n}\n\n/// ditto\nauto maxElement(alias map = (a => a), Range, RangeElementType = ElementType!Range)\n               (Range r, RangeElementType seed)\nif (isInputRange!Range && !isInfinite!Range &&\n    !is(CommonType!(ElementType!Range, RangeElementType) == void))\n{\n    return extremum!(map, \"a > b\")(r, seed);\n}\n\n///\n@safe pure unittest\n{\n    import std.range : enumerate;\n    import std.typecons : tuple;\n    assert([2, 1, 4, 3].maxElement == 4);\n\n    // allows to get the index of an element too\n    assert([2, 1, 4, 3].enumerate.maxElement!\"a.value\" == tuple(2, 4));\n\n    // any custom accessor can be passed\n    assert([[0, 4], [1, 2]].maxElement!\"a[1]\" == [0, 4]);\n\n    // can be seeded\n    int[] arr;\n    assert(arr.minElement(1) == 1);\n}\n\n@safe pure unittest\n{\n    import std.range : enumerate, iota;\n\n    // supports mapping\n    assert([3, 4, 5, 1, 2].enumerate.maxElement!\"a.value\" == tuple(2, 5));\n    assert([5, 2, 4].enumerate.maxElement!\"a.value\" == tuple(0, 5));\n\n    // forward ranges\n    assert(iota(1, 5).maxElement() == 4);\n    assert(iota(2, 5).enumerate.maxElement!\"a.value\" == tuple(2, 4));\n    assert(iota(4, 14).enumerate.maxElement!\"a.value\" == tuple(9, 13));\n\n    // should work with const\n    const(int)[] immArr = [2, 3, 1];\n    assert(immArr.maxElement == 3);\n\n    // should work with immutable\n    immutable(int)[] immArr2 = [2, 3, 1];\n    assert(immArr2.maxElement == 3);\n\n    // with strings\n    assert([\"a\", \"c\", \"b\"].maxElement == \"c\");\n\n    // with all dummy ranges\n    import std.internal.test.dummyrange;\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType d;\n        assert(d.maxElement == 10);\n        assert(d.maxElement!(a => a) == 10);\n        assert(d.maxElement!(a => -a) == 1);\n    }\n\n    // with empty, but seeded ranges\n    int[] arr;\n    assert(arr.maxElement(42) == 42);\n    assert(arr.maxElement!(a => a)(42) == 42);\n\n}\n\n@nogc @safe nothrow pure unittest\n{\n    static immutable arr = [7, 3, 8, 2, 1, 4];\n    assert(arr.maxElement == 8);\n\n    static immutable arr2d = [[1, 3], [3, 9], [4, 2]];\n    assert(arr2d.maxElement!\"a[1]\" == arr2d[1]);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17982\n@safe unittest\n{\n    class B\n    {\n        int val;\n        this(int val){ this.val = val; }\n    }\n\n    const(B) doStuff(const(B)[] v)\n    {\n        return v.maxElement!\"a.val\";\n    }\n    assert(doStuff([new B(1), new B(0), new B(2)]).val == 2);\n\n    const(B)[] arr = [new B(0), new B(1)];\n    // can't compare directly - https://issues.dlang.org/show_bug.cgi?id=1824\n    assert(arr.maxElement!\"a.val\".val == 1);\n}\n\n// minPos\n/**\nComputes a subrange of `range` starting at the first occurrence of `range`'s\nminimum (respectively maximum) and with the same ending as `range`, or the\nempty range if `range` itself is empty.\n\nFormally, the minimum is a value `x` in `range` such that `pred(a, x)` is\n`false` for all values `a` in `range`. Conversely, the maximum is a value `x` in\n`range` such that `pred(x, a)` is `false` for all values `a` in `range` (note\nthe swapped arguments to `pred`).\n\nThese functions may be used for computing arbitrary extrema by choosing `pred`\nappropriately. For corrrect functioning, `pred` must be a strict partial order,\ni.e. transitive (if `pred(a, b) && pred(b, c)` then `pred(a, c)`) and\nirreflexive (`pred(a, a)` is `false`).\n\nParams:\n    pred = The ordering predicate to use to determine the extremum (minimum or\n        maximum) element.\n    range = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to search.\n\nReturns: The position of the minimum (respectively maximum) element of forward\nrange `range`, i.e. a subrange of `range` starting at the position of  its\nsmallest (respectively largest) element and with the same ending as `range`.\n\nSee_Also:\n    $(REF max, std,algorithm,comparison), $(LREF minCount), $(LREF minIndex), $(LREF minElement)\n*/\nRange minPos(alias pred = \"a < b\", Range)(Range range)\nif (isForwardRange!Range && !isInfinite!Range &&\n    is(typeof(binaryFun!pred(range.front, range.front))))\n{\n    static if (hasSlicing!Range && isRandomAccessRange!Range && hasLength!Range)\n    {\n        // Prefer index-based access\n        size_t pos = 0;\n        foreach (i; 1 .. range.length)\n        {\n            if (binaryFun!pred(range[i], range[pos]))\n            {\n                pos = i;\n            }\n        }\n        return range[pos .. range.length];\n    }\n    else\n    {\n        auto result = range.save;\n        if (range.empty) return result;\n        for (range.popFront(); !range.empty; range.popFront())\n        {\n            // Note: Unlike minCount, we do not care to find equivalence, so a\n            // single pred call is enough.\n            if (binaryFun!pred(range.front, result.front))\n            {\n                // change the min\n                result = range.save;\n            }\n        }\n        return result;\n    }\n}\n\n/// Ditto\nRange maxPos(alias pred = \"a < b\", Range)(Range range)\nif (isForwardRange!Range && !isInfinite!Range &&\n    is(typeof(binaryFun!pred(range.front, range.front))))\n{\n    return range.minPos!((a, b) => binaryFun!pred(b, a));\n}\n\n///\n@safe unittest\n{\n    int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];\n    // Minimum is 1 and first occurs in position 3\n    assert(a.minPos == [ 1, 2, 4, 1, 1, 2 ]);\n    // Maximum is 4 and first occurs in position 2\n    assert(a.maxPos == [ 4, 1, 2, 4, 1, 1, 2 ]);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange;\n\n    int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];\n    //Test that an empty range works\n    int[] b = a[$..$];\n    assert(equal(minPos(b), b));\n\n    //test with reference range.\n    assert( equal( minPos(new ReferenceForwardRange!int([1, 2, 1, 0, 2, 0])), [0, 2, 0] ) );\n}\n\n@system unittest\n{\n    //Rvalue range\n    import std.algorithm.comparison : equal;\n    import std.container : Array;\n\n    assert(Array!int(2, 3, 4, 1, 2, 4, 1, 1, 2)\n               []\n               .minPos()\n               .equal([ 1, 2, 4, 1, 1, 2 ]));\n}\n\n@safe unittest\n{\n    //BUG 9299\n    immutable a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];\n    // Minimum is 1 and first occurs in position 3\n    assert(minPos(a) == [ 1, 2, 4, 1, 1, 2 ]);\n    // Maximum is 4 and first occurs in position 5\n    assert(minPos!(\"a > b\")(a) == [ 4, 1, 2, 4, 1, 1, 2 ]);\n\n    immutable(int[])[] b = [ [4], [2, 4], [4], [4] ];\n    assert(minPos!(\"a[0] < b[0]\")(b) == [ [2, 4], [4], [4] ]);\n}\n\n/**\nComputes the index of the first occurrence of `range`'s minimum element.\n\nParams:\n    pred = The ordering predicate to use to determine the minimum element.\n    range = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    to search.\n\nComplexity: $(BIGOH range.length)\n    Exactly `range.length - 1` comparisons are needed.\n\nReturns:\n    The index of the first encounter of the minimum element in `range`. If the\n    `range` is empty, -1 is returned.\n\nSee_Also:\n    $(LREF maxIndex), $(REF min, std,algorithm,comparison), $(LREF minCount), $(LREF minElement), $(LREF minPos)\n */\nsizediff_t minIndex(alias pred = \"a < b\", Range)(Range range)\nif (isForwardRange!Range && !isInfinite!Range &&\n    is(typeof(binaryFun!pred(range.front, range.front))))\n{\n    if (range.empty) return -1;\n\n    sizediff_t minPos = 0;\n\n    static if (isRandomAccessRange!Range && hasLength!Range)\n    {\n        foreach (i; 1 .. range.length)\n        {\n            if (binaryFun!pred(range[i], range[minPos]))\n            {\n                minPos = i;\n            }\n        }\n    }\n    else\n    {\n        sizediff_t curPos = 0;\n        Unqual!(typeof(range.front)) min = range.front;\n        for (range.popFront(); !range.empty; range.popFront())\n        {\n            ++curPos;\n            if (binaryFun!pred(range.front, min))\n            {\n                min = range.front;\n                minPos = curPos;\n            }\n        }\n    }\n    return minPos;\n}\n\n///\n@safe pure nothrow unittest\n{\n    int[] a = [2, 3, 4, 1, 2, 4, 1, 1, 2];\n\n    // Minimum is 1 and first occurs in position 3\n    assert(a.minIndex == 3);\n    // Get maximum index with minIndex\n    assert(a.minIndex!\"a > b\" == 2);\n\n    // Range is empty, so return value is -1\n    int[] b;\n    assert(b.minIndex == -1);\n\n    // Works with more custom types\n    struct Dog { int age; }\n    Dog[] dogs = [Dog(10), Dog(5), Dog(15)];\n    assert(dogs.minIndex!\"a.age < b.age\" == 1);\n}\n\n@safe pure unittest\n{\n    // should work with const\n    const(int)[] immArr = [2, 1, 3];\n    assert(immArr.minIndex == 1);\n\n    // Works for const ranges too\n    const int[] c = [2, 5, 4, 1, 2, 3];\n    assert(c.minIndex == 3);\n\n    // should work with immutable\n    immutable(int)[] immArr2 = [2, 1, 3];\n    assert(immArr2.minIndex == 1);\n\n    // with strings\n    assert([\"b\", \"a\", \"c\"].minIndex == 1);\n\n    // infinite range\n    import std.range : cycle;\n    static assert(!__traits(compiles, cycle([1]).minIndex));\n\n    // with all dummy ranges\n    import std.internal.test.dummyrange : AllDummyRanges;\n    foreach (DummyType; AllDummyRanges)\n    {\n        static if (isForwardRange!DummyType && !isInfinite!DummyType)\n        {\n            DummyType d;\n            d.arr = [5, 3, 7, 2, 1, 4];\n            assert(d.minIndex == 4);\n\n            d.arr = [];\n            assert(d.minIndex == -1);\n        }\n    }\n}\n\n@nogc @safe nothrow pure unittest\n{\n    static immutable arr = [7, 3, 8, 2, 1, 4];\n    assert(arr.minIndex == 4);\n\n    static immutable arr2d = [[1, 3], [3, 9], [4, 2]];\n    assert(arr2d.minIndex!\"a[1] < b[1]\" == 2);\n}\n\n/**\nComputes the index of the first occurrence of `range`'s maximum element.\n\nComplexity: $(BIGOH range)\n    Exactly `range.length - 1` comparisons are needed.\n\nParams:\n    pred = The ordering predicate to use to determine the maximum element.\n    range = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to search.\n\nReturns:\n    The index of the first encounter of the maximum in `range`. If the\n    `range` is empty, -1 is returned.\n\nSee_Also:\n    $(LREF minIndex), $(REF max, std,algorithm,comparison), $(LREF maxCount), $(LREF maxElement), $(LREF maxPos)\n */\nsizediff_t maxIndex(alias pred = \"a < b\", Range)(Range range)\nif (isInputRange!Range && !isInfinite!Range &&\n    is(typeof(binaryFun!pred(range.front, range.front))))\n{\n    return range.minIndex!((a, b) => binaryFun!pred(b, a));\n}\n\n///\n@safe pure nothrow unittest\n{\n    // Maximum is 4 and first occurs in position 2\n    int[] a = [2, 3, 4, 1, 2, 4, 1, 1, 2];\n    assert(a.maxIndex == 2);\n\n    // Empty range\n    int[] b;\n    assert(b.maxIndex == -1);\n\n    // Works with more custom types\n    struct Dog { int age; }\n    Dog[] dogs = [Dog(10), Dog(15), Dog(5)];\n    assert(dogs.maxIndex!\"a.age < b.age\" == 1);\n}\n\n@safe pure unittest\n{\n    // should work with const\n    const(int)[] immArr = [5, 1, 3];\n    assert(immArr.maxIndex == 0);\n\n    // Works for const ranges too\n    const int[] c = [2, 5, 4, 1, 2, 3];\n    assert(c.maxIndex == 1);\n\n\n    // should work with immutable\n    immutable(int)[] immArr2 = [2, 1, 3];\n    assert(immArr2.maxIndex == 2);\n\n    // with strings\n    assert([\"b\", \"a\", \"c\"].maxIndex == 2);\n\n    // infinite range\n    import std.range : cycle;\n    static assert(!__traits(compiles, cycle([1]).maxIndex));\n\n    // with all dummy ranges\n    import std.internal.test.dummyrange : AllDummyRanges;\n    foreach (DummyType; AllDummyRanges)\n    {\n        static if (isForwardRange!DummyType && !isInfinite!DummyType)\n        {\n            DummyType d;\n\n            d.arr = [5, 3, 7, 2, 1, 4];\n            assert(d.maxIndex == 2);\n\n            d.arr = [];\n            assert(d.maxIndex == -1);\n        }\n    }\n}\n\n@nogc @safe nothrow pure unittest\n{\n    static immutable arr = [7, 3, 8, 2, 1, 4];\n    assert(arr.maxIndex == 2);\n\n    static immutable arr2d = [[1, 3], [3, 9], [4, 2]];\n    assert(arr2d.maxIndex!\"a[1] < b[1]\" == 1);\n}\n\n/**\nSkip over the initial portion of the first given range (`haystack`) that matches\nany of the additionally given ranges (`needles`) fully, or\nif no second range is given skip over the elements that fulfill pred.\nDo nothing if there is no match.\n\nParams:\n    pred = The predicate that determines whether elements from each respective\n        range match. Defaults to equality `\"a == b\"`.\n*/\ntemplate skipOver(alias pred = (a, b) => a == b)\n{\n    import std.meta : allSatisfy;\n\n    enum bool isPredComparable(T) = ifTestable!(T, binaryFun!pred);\n\n    /**\n    Params:\n        haystack = The $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to\n                   move forward.\n        needles = The $(REF_ALTTEXT input ranges, isInputRange, std,range,primitives)\n                  representing the prefix of `r1` to skip over.\n        es = The element to match.\n\n    Returns:\n        `true` if the prefix of `haystack` matches any range of `needles` fully\n        or `pred` evaluates to true, and `haystack` has been advanced to the point past this segment;\n        otherwise false, and `haystack` is left in its original position.\n\n    Note:\n        By definition, empty ranges are matched fully and if `needles` contains an empty range,\n        `skipOver` will return `true`.\n    */\n    bool skipOver(Haystack, Needles...)(ref Haystack haystack, Needles needles)\n    if (is(typeof(binaryFun!pred(haystack.front, needles[0].front))) &&\n        isForwardRange!Haystack &&\n        allSatisfy!(isInputRange, Needles) &&\n        !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, Needles))) == void))\n    {\n        static if (__traits(isSame, pred, (a, b) => a == b)\n                && is(typeof(haystack[0 .. $] == needles[0]) : bool)\n                && is(typeof(haystack = haystack[0 .. $]))\n                && hasLength!Haystack && allSatisfy!(hasLength, Needles))\n        {\n            ptrdiff_t longestMatch = -1;\n            static foreach (r2; needles)\n            {\n                if (r2.length <= haystack.length && longestMatch < ptrdiff_t(r2.length)\n                        && (haystack[0 .. r2.length] == r2 || r2.length == 0))\n                    longestMatch = r2.length;\n            }\n            if (longestMatch >= 0)\n            {\n                if (longestMatch > 0)\n                    haystack = haystack[longestMatch .. $];\n\n                return true;\n            }\n            return false;\n        }\n        else\n        {\n            import std.algorithm.comparison : min;\n            auto r = haystack.save;\n\n            static if (hasLength!Haystack && allSatisfy!(hasLength, Needles))\n            {\n                import std.algorithm.iteration : map;\n                import std.algorithm.searching : minElement;\n                import std.range : only;\n                // Shortcut opportunity!\n                if (needles.only.map!(a => a.length).minElement > haystack.length)\n                    return false;\n            }\n\n            // compatibility: return true if any range was empty\n            bool hasEmptyRanges;\n            static foreach (i, r2; needles)\n            {\n                if (r2.empty)\n                    hasEmptyRanges = true;\n            }\n\n            bool hasNeedleMatch;\n            size_t inactiveNeedlesLen;\n            bool[Needles.length] inactiveNeedles;\n            for (; !r.empty; r.popFront)\n            {\n                static foreach (i, r2; needles)\n                {\n                    if (!r2.empty && !inactiveNeedles[i])\n                    {\n                        if (binaryFun!pred(r.front, r2.front))\n                        {\n                            r2.popFront;\n                            if (r2.empty)\n                            {\n                                // we skipped over a new match\n                                hasNeedleMatch = true;\n                                inactiveNeedlesLen++;\n                                // skip over haystack\n                                haystack = r;\n                            }\n                        }\n                        else\n                        {\n                            inactiveNeedles[i] = true;\n                            inactiveNeedlesLen++;\n                        }\n                    }\n                }\n\n                // are we done?\n                if (inactiveNeedlesLen == needles.length)\n                    break;\n            }\n\n            if (hasNeedleMatch)\n                haystack.popFront;\n\n            return hasNeedleMatch || hasEmptyRanges;\n        }\n    }\n\n    /// Ditto\n    bool skipOver(R)(ref R r1)\n    if (isForwardRange!R &&\n        ifTestable!(typeof(r1.front), unaryFun!pred))\n    {\n        if (r1.empty || !unaryFun!pred(r1.front))\n            return false;\n\n        do\n            r1.popFront();\n        while (!r1.empty && unaryFun!pred(r1.front));\n        return true;\n    }\n\n    /// Ditto\n    bool skipOver(R, Es...)(ref R r, Es es)\n    if (isInputRange!R && is(typeof(binaryFun!pred(r.front, es[0]))))\n    {\n        if (r.empty)\n            return false;\n\n        static foreach (e; es)\n        {\n            if (binaryFun!pred(r.front, e))\n            {\n                r.popFront();\n                return true;\n            }\n        }\n        return false;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto s1 = \"Hello world\";\n    assert(!skipOver(s1, \"Ha\"));\n    assert(s1 == \"Hello world\");\n    assert(skipOver(s1, \"Hell\") && s1 == \"o world\", s1);\n\n    string[]  r1 = [\"abc\", \"def\", \"hij\"];\n    dstring[] r2 = [\"abc\"d];\n    assert(!skipOver!((a, b) => a.equal(b))(r1, [\"def\"d]), r1[0]);\n    assert(r1 == [\"abc\", \"def\", \"hij\"]);\n    assert(skipOver!((a, b) => a.equal(b))(r1, r2));\n    assert(r1 == [\"def\", \"hij\"]);\n}\n\n///\n@safe unittest\n{\n    import std.ascii : isWhite;\n    import std.range.primitives : empty;\n\n    auto s2 = \"\\t\\tvalue\";\n    auto s3 = \"\";\n    auto s4 = \"\\t\\t\\t\";\n    assert(s2.skipOver!isWhite && s2 == \"value\");\n    assert(!s3.skipOver!isWhite);\n    assert(s4.skipOver!isWhite && s3.empty);\n}\n\n/// Variadic skipOver\n@safe unittest\n{\n    auto s = \"Hello world\";\n    assert(!skipOver(s, \"hello\", \"HellO\"));\n    assert(s == \"Hello world\");\n\n    // the range is skipped over the longest matching needle is skipped\n    assert(skipOver(s, \"foo\", \"hell\", \"Hello \"));\n    assert(s == \"world\");\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto s1 = \"Hello world\";\n    assert(!skipOver(s1, 'a'));\n    assert(s1 == \"Hello world\");\n    assert(skipOver(s1, 'H') && s1 == \"ello world\");\n\n    string[] r = [\"abc\", \"def\", \"hij\"];\n    dstring e = \"abc\"d;\n    assert(!skipOver!((a, b) => a.equal(b))(r, \"def\"d));\n    assert(r == [\"abc\", \"def\", \"hij\"]);\n    assert(skipOver!((a, b) => a.equal(b))(r, e));\n    assert(r == [\"def\", \"hij\"]);\n\n    auto s2 = \"\";\n    assert(!s2.skipOver('a'));\n}\n\n/// Partial instantiation\n@safe unittest\n{\n    import std.ascii : isWhite;\n    import std.range.primitives : empty;\n\n    alias whitespaceSkiper = skipOver!isWhite;\n\n    auto s2 = \"\\t\\tvalue\";\n    auto s3 = \"\";\n    auto s4 = \"\\t\\t\\t\";\n    assert(whitespaceSkiper(s2) && s2 == \"value\");\n    assert(!whitespaceSkiper(s2));\n    assert(whitespaceSkiper(s4) && s3.empty);\n}\n\n// variadic skipOver\n@safe unittest\n{\n    auto s = \"DLang.rocks\";\n    assert(!s.skipOver(\"dlang\", \"DLF\", \"DLang \"));\n    assert(s == \"DLang.rocks\");\n\n    assert(s.skipOver(\"dlang\", \"DLANG\", \"DLF\", \"D\", \"DL\", \"DLanpp\"));\n    assert(s == \"ang.rocks\");\n    s = \"DLang.rocks\";\n\n    assert(s.skipOver(\"DLang\", \"DLANG\", \"DLF\", \"D\", \"DL\", \"DLang \"));\n    assert(s == \".rocks\");\n    s = \"DLang.rocks\";\n\n    assert(s.skipOver(\"dlang\", \"DLANG\", \"DLF\", \"D\", \"DL\", \"DLang.\"));\n    assert(s == \"rocks\");\n}\n\n// variadic with custom pred\n@safe unittest\n{\n    import std.ascii : toLower;\n\n    auto s = \"DLang.rocks\";\n    assert(!s.skipOver(\"dlang\", \"DLF\", \"DLang \"));\n    assert(s == \"DLang.rocks\");\n\n    assert(s.skipOver!((a, b) => a.toLower == b.toLower)(\"dlang\", \"DLF\", \"DLang \"));\n    assert(s == \".rocks\");\n}\n\n// variadic skipOver with mixed needles\n@safe unittest\n{\n    auto s = \"DLang.rocks\";\n    assert(!s.skipOver(\"dlang\"d, \"DLF\", \"DLang \"w));\n    assert(s == \"DLang.rocks\");\n\n    assert(s.skipOver(\"dlang\", \"DLANG\"d, \"DLF\"w, \"D\"d, \"DL\", \"DLanp\"));\n    assert(s == \"ang.rocks\");\n    s = \"DLang.rocks\";\n\n    assert(s.skipOver(\"DLang\", \"DLANG\"w, \"DLF\"d, \"D\"d, \"DL\", \"DLang \"));\n    assert(s == \".rocks\");\n    s = \"DLang.rocks\";\n\n    assert(s.skipOver(\"dlang\", \"DLANG\"w, \"DLF\", \"D\"d, \"DL\"w, \"DLang.\"d));\n    assert(s == \"rocks\");\n\n    import std.algorithm.iteration : filter;\n    s = \"DLang.rocks\";\n    assert(s.skipOver(\"dlang\", \"DLang\".filter!(a => true)));\n    assert(s == \".rocks\");\n}\n\n// variadic skipOver with auto-decoding\n@safe unittest\n{\n    auto s = \"☢☣☠.☺\";\n    assert(s.skipOver(\"a\", \"☢\", \"☢☣☠\"));\n    assert(s == \".☺\");\n}\n\n// skipOver with @nogc\n@safe @nogc pure nothrow unittest\n{\n    static immutable s = [0, 1, 2];\n    immutable(int)[] s2 = s[];\n\n    static immutable skip1 = [0, 2];\n    static immutable skip2 = [0, 1];\n    assert(s2.skipOver(skip1, skip2));\n    assert(s2 == s[2 .. $]);\n}\n\n// variadic skipOver with single elements\n@safe unittest\n{\n    auto s = \"DLang.rocks\";\n    assert(!s.skipOver('a', 'd', 'e'));\n    assert(s == \"DLang.rocks\");\n\n    assert(s.skipOver('a', 'D', 'd', 'D'));\n    assert(s == \"Lang.rocks\");\n    s = \"DLang.rocks\";\n\n    assert(s.skipOver(wchar('a'), dchar('D'), 'd'));\n    assert(s == \"Lang.rocks\");\n\n    dstring dstr = \"+Foo\";\n    assert(!dstr.skipOver('.', '-'));\n    assert(dstr == \"+Foo\");\n\n    assert(dstr.skipOver('+', '-'));\n    assert(dstr == \"Foo\");\n}\n\n// skipOver with empty ranges must return true (compatibility)\n@safe unittest\n{\n    auto s = \"DLang.rocks\";\n    assert(s.skipOver(\"\"));\n    assert(s.skipOver(\"\", \"\"));\n    assert(s.skipOver(\"\", \"foo\"));\n\n    auto s2 = \"DLang.rocks\"d;\n    assert(s2.skipOver(\"\"));\n    assert(s2.skipOver(\"\", \"\"));\n    assert(s2.skipOver(\"\", \"foo\"));\n}\n\n// dxml regression\n@safe unittest\n{\n    import std.utf : byCodeUnit;\n    import std.algorithm.comparison : equal;\n\n    bool stripStartsWith(Text)(ref Text text, string needle)\n    {\n        return text.skipOver(needle.byCodeUnit());\n    }\n    auto text = \"<xml></xml>\"d.byCodeUnit;\n    assert(stripStartsWith(text, \"<xml>\"));\n    assert(text.equal(\"</xml>\"));\n}\n\n/**\nChecks whether the given\n$(REF_ALTTEXT input range, isInputRange, std,range,primitives) starts with (one\nof) the given needle(s) or, if no needles are given,\nif its front element fulfils predicate `pred`.\n\nParams:\n\n    pred = Predicate to use in comparing the elements of the haystack and the\n        needle(s). Mandatory if no needles are given.\n\n    doesThisStart = The input range to check.\n\n    withOneOfThese = The needles against which the range is to be checked,\n        which may be individual elements or input ranges of elements.\n\n    withThis = The single needle to check, which may be either a single element\n        or an input range of elements.\n\nReturns:\n\n0 if the needle(s) do not occur at the beginning of the given range;\notherwise the position of the matching needle, that is, 1 if the range starts\nwith `withOneOfThese[0]`, 2 if it starts with `withOneOfThese[1]`, and so\non.\n\nIn the case where `doesThisStart` starts with multiple of the ranges or\nelements in `withOneOfThese`, then the shortest one matches (if there are\ntwo which match which are of the same length (e.g. `\"a\"` and `'a'`), then\nthe left-most of them in the argument\nlist matches).\n\nIn the case when no needle parameters are given, return `true` iff front of\n`doesThisStart` fulfils predicate `pred`.\n */\nuint startsWith(alias pred = (a, b) => a == b, Range, Needles...)(Range doesThisStart, Needles withOneOfThese)\nif (isInputRange!Range && Needles.length > 1 &&\n    is(typeof(.startsWith!pred(doesThisStart, withOneOfThese[0])) : bool ) &&\n    is(typeof(.startsWith!pred(doesThisStart, withOneOfThese[1 .. $])) : uint))\n{\n    import std.meta : allSatisfy;\n\n    template checkType(T)\n    {\n        enum checkType = is(Unqual!(ElementEncodingType!Range) == Unqual!T);\n    }\n\n    // auto-decoding special case\n    static if (__traits(isSame, binaryFun!pred, (a, b) => a == b) &&\n        isNarrowString!Range && allSatisfy!(checkType, Needles))\n    {\n        import std.utf : byCodeUnit;\n        auto haystack = doesThisStart.byCodeUnit;\n    }\n    else\n    {\n        alias haystack = doesThisStart;\n    }\n    alias needles  = withOneOfThese;\n\n    // Make one pass looking for empty ranges in needles\n    foreach (i, Unused; Needles)\n    {\n        // Empty range matches everything\n        static if (!is(typeof(binaryFun!pred(haystack.front, needles[i])) : bool))\n        {\n            if (needles[i].empty) return i + 1;\n        }\n    }\n\n    for (; !haystack.empty; haystack.popFront())\n    {\n        foreach (i, Unused; Needles)\n        {\n            static if (is(typeof(binaryFun!pred(haystack.front, needles[i])) : bool))\n            {\n                // Single-element\n                if (binaryFun!pred(haystack.front, needles[i]))\n                {\n                    // found, but instead of returning, we just stop searching.\n                    // This is to account for one-element\n                    // range matches (consider startsWith(\"ab\", \"a\",\n                    // 'a') should return 1, not 2).\n                    break;\n                }\n            }\n            else\n            {\n                if (binaryFun!pred(haystack.front, needles[i].front))\n                {\n                    continue;\n                }\n            }\n\n            // This code executed on failure to match\n            // Out with this guy, check for the others\n            uint result = startsWith!pred(haystack, needles[0 .. i], needles[i + 1 .. $]);\n            if (result > i) ++result;\n            return result;\n        }\n\n        // If execution reaches this point, then the front matches for all\n        // needle ranges, or a needle element has been matched.\n        // What we need to do now is iterate, lopping off the front of\n        // the range and checking if the result is empty, or finding an\n        // element needle and returning.\n        // If neither happens, we drop to the end and loop.\n        foreach (i, Unused; Needles)\n        {\n            static if (is(typeof(binaryFun!pred(haystack.front, needles[i])) : bool))\n            {\n                // Test has passed in the previous loop\n                return i + 1;\n            }\n            else\n            {\n                needles[i].popFront();\n                if (needles[i].empty) return i + 1;\n            }\n        }\n    }\n    return 0;\n}\n\n/// Ditto\nbool startsWith(alias pred = \"a == b\", R1, R2)(R1 doesThisStart, R2 withThis)\nif (isInputRange!R1 &&\n    isInputRange!R2 &&\n    is(typeof(binaryFun!pred(doesThisStart.front, withThis.front)) : bool))\n{\n    alias haystack = doesThisStart;\n    alias needle   = withThis;\n\n    static if (is(typeof(pred) : string))\n        enum isDefaultPred = pred == \"a == b\";\n    else\n        enum isDefaultPred = false;\n\n    // Note: Although narrow strings don't have a \"true\" length, for a narrow string to start with another\n    // narrow string, it must have *at least* as many code units.\n    static if ((hasLength!R1 && hasLength!R2) ||\n        ((hasLength!R1 || isNarrowString!R1) && (hasLength!R2 || isNarrowString!R2)\n            && (ElementEncodingType!R1.sizeof <= ElementEncodingType!R2.sizeof)))\n    {\n        if (haystack.length < needle.length)\n            return false;\n    }\n\n    static if (isDefaultPred && isArray!R1 && isArray!R2 &&\n               is(Unqual!(ElementEncodingType!R1) == Unqual!(ElementEncodingType!R2)))\n    {\n        //Array slice comparison mode\n        return haystack[0 .. needle.length] == needle;\n    }\n    else static if (isRandomAccessRange!R1 && isRandomAccessRange!R2 && hasLength!R2)\n    {\n        //RA dual indexing mode\n        foreach (j; 0 .. needle.length)\n        {\n            if (!binaryFun!pred(haystack[j], needle[j]))\n                // not found\n                return false;\n        }\n        // found!\n        return true;\n    }\n    else\n    {\n        //Standard input range mode\n        if (needle.empty) return true;\n        static if (hasLength!R1 && hasLength!R2)\n        {\n            //We have previously checked that haystack.length > needle.length,\n            //So no need to check haystack.empty during iteration\n            for ( ; ; haystack.popFront() )\n            {\n                if (!binaryFun!pred(haystack.front, needle.front)) break;\n                needle.popFront();\n                if (needle.empty) return true;\n            }\n        }\n        else\n        {\n            for ( ; !haystack.empty ; haystack.popFront() )\n            {\n                if (!binaryFun!pred(haystack.front, needle.front)) break;\n                needle.popFront();\n                if (needle.empty) return true;\n            }\n        }\n        return false;\n    }\n}\n\n/// Ditto\nbool startsWith(alias pred = \"a == b\", R, E)(R doesThisStart, E withThis)\nif (isInputRange!R &&\n    is(typeof(binaryFun!pred(doesThisStart.front, withThis)) : bool))\n{\n    if (doesThisStart.empty)\n        return false;\n\n    static if (is(typeof(pred) : string))\n        enum isDefaultPred = pred == \"a == b\";\n    else\n        enum isDefaultPred = false;\n\n    alias predFunc = binaryFun!pred;\n\n    // auto-decoding special case\n    static if (isNarrowString!R)\n    {\n        // statically determine decoding is unnecessary to evaluate pred\n        static if (isDefaultPred && isSomeChar!E && E.sizeof <= ElementEncodingType!R.sizeof)\n            return doesThisStart[0] == withThis;\n        // specialize for ASCII as to not change previous behavior\n        else\n        {\n            if (withThis <= 0x7F)\n                return predFunc(doesThisStart[0], withThis);\n            else\n                return predFunc(doesThisStart.front, withThis);\n        }\n    }\n    else\n    {\n        return predFunc(doesThisStart.front, withThis);\n    }\n}\n\n/// Ditto\nbool startsWith(alias pred, R)(R doesThisStart)\nif (isInputRange!R &&\n    ifTestable!(typeof(doesThisStart.front), unaryFun!pred))\n{\n    return !doesThisStart.empty && unaryFun!pred(doesThisStart.front);\n}\n\n///\n@safe unittest\n{\n    import std.ascii : isAlpha;\n\n    assert(\"abc\".startsWith!(a => a.isAlpha));\n    assert(\"abc\".startsWith!isAlpha);\n    assert(!\"1ab\".startsWith!(a => a.isAlpha));\n    assert(!\"\".startsWith!(a => a.isAlpha));\n\n    import std.algorithm.comparison : among;\n    assert(\"abc\".startsWith!(a => a.among('a', 'b') != 0));\n    assert(!\"abc\".startsWith!(a => a.among('b', 'c') != 0));\n\n    assert(startsWith(\"abc\", \"\"));\n    assert(startsWith(\"abc\", \"a\"));\n    assert(!startsWith(\"abc\", \"b\"));\n    assert(startsWith(\"abc\", 'a', \"b\") == 1);\n    assert(startsWith(\"abc\", \"b\", \"a\") == 2);\n    assert(startsWith(\"abc\", \"a\", \"a\") == 1);\n    assert(startsWith(\"abc\", \"ab\", \"a\") == 2);\n    assert(startsWith(\"abc\", \"x\", \"a\", \"b\") == 2);\n    assert(startsWith(\"abc\", \"x\", \"aa\", \"ab\") == 3);\n    assert(startsWith(\"abc\", \"x\", \"aaa\", \"sab\") == 0);\n    assert(startsWith(\"abc\", \"x\", \"aaa\", \"a\", \"sab\") == 3);\n\n    import std.typecons : Tuple;\n    alias C = Tuple!(int, \"x\", int, \"y\");\n    assert(startsWith!\"a.x == b\"([ C(1,1), C(1,2), C(2,2) ], [1, 1]));\n    assert(startsWith!\"a.x == b\"([ C(1,1), C(2,1), C(2,2) ], [1, 1], [1, 2], [1, 3]) == 2);\n}\n\n@safe unittest\n{\n    import std.algorithm.iteration : filter;\n    import std.conv : to;\n    import std.meta : AliasSeq;\n    import std.range;\n\n    static foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n    {\n        assert(!startsWith(to!S(\"abc\"), 'c'));\n        assert(startsWith(to!S(\"abc\"), 'a', 'c') == 1);\n        assert(!startsWith(to!S(\"abc\"), 'x', 'n', 'b'));\n        assert(startsWith(to!S(\"abc\"), 'x', 'n', 'a') == 3);\n        assert(startsWith(to!S(\"\\uFF28abc\"), 'a', '\\uFF28', 'c') == 2);\n\n        static foreach (T; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n        {\n            //Lots of strings\n            assert(startsWith(to!S(\"abc\"), to!T(\"\")));\n            assert(startsWith(to!S(\"ab\"), to!T(\"a\")));\n            assert(startsWith(to!S(\"abc\"), to!T(\"a\")));\n            assert(!startsWith(to!S(\"abc\"), to!T(\"b\")));\n            assert(!startsWith(to!S(\"abc\"), to!T(\"b\"), \"bc\", \"abcd\", \"xyz\"));\n            assert(startsWith(to!S(\"abc\"), to!T(\"ab\"), 'a') == 2);\n            assert(startsWith(to!S(\"abc\"), to!T(\"a\"), \"b\") == 1);\n            assert(startsWith(to!S(\"abc\"), to!T(\"b\"), \"a\") == 2);\n            assert(startsWith(to!S(\"abc\"), to!T(\"a\"), 'a') == 1);\n            assert(startsWith(to!S(\"abc\"), 'a', to!T(\"a\")) == 1);\n            assert(startsWith(to!S(\"abc\"), to!T(\"x\"), \"a\", \"b\") == 2);\n            assert(startsWith(to!S(\"abc\"), to!T(\"x\"), \"aa\", \"ab\") == 3);\n            assert(startsWith(to!S(\"abc\"), to!T(\"x\"), \"aaa\", \"sab\") == 0);\n            assert(startsWith(to!S(\"abc\"), 'a'));\n            assert(!startsWith(to!S(\"abc\"), to!T(\"sab\")));\n            assert(startsWith(to!S(\"abc\"), 'x', to!T(\"aaa\"), 'a', \"sab\") == 3);\n\n            //Unicode\n            assert(startsWith(to!S(\"\\uFF28el\\uFF4co\"), to!T(\"\\uFF28el\")));\n            assert(startsWith(to!S(\"\\uFF28el\\uFF4co\"), to!T(\"Hel\"), to!T(\"\\uFF28el\")) == 2);\n            assert(startsWith(to!S(\"日本語\"), to!T(\"日本\")));\n            assert(startsWith(to!S(\"日本語\"), to!T(\"日本語\")));\n            assert(!startsWith(to!S(\"日本\"), to!T(\"日本語\")));\n\n            //Empty\n            assert(startsWith(to!S(\"\"),  T.init));\n            assert(!startsWith(to!S(\"\"), 'a'));\n            assert(startsWith(to!S(\"a\"), T.init));\n            assert(startsWith(to!S(\"a\"), T.init, \"\") == 1);\n            assert(startsWith(to!S(\"a\"), T.init, 'a') == 1);\n            assert(startsWith(to!S(\"a\"), 'a', T.init) == 2);\n        }\n    }\n\n    //Length but no RA\n    assert(!startsWith(\"abc\".takeExactly(3), \"abcd\".takeExactly(4)));\n    assert(startsWith(\"abc\".takeExactly(3), \"abcd\".takeExactly(3)));\n    assert(startsWith(\"abc\".takeExactly(3), \"abcd\".takeExactly(1)));\n\n    static foreach (T; AliasSeq!(int, short))\n    {{\n        immutable arr = cast(T[])[0, 1, 2, 3, 4, 5];\n\n        //RA range\n        assert(startsWith(arr, cast(int[]) null));\n        assert(!startsWith(arr, 5));\n        assert(!startsWith(arr, 1));\n        assert(startsWith(arr, 0));\n        assert(startsWith(arr, 5, 0, 1) == 2);\n        assert(startsWith(arr, [0]));\n        assert(startsWith(arr, [0, 1]));\n        assert(startsWith(arr, [0, 1], 7) == 1);\n        assert(!startsWith(arr, [0, 1, 7]));\n        assert(startsWith(arr, [0, 1, 7], [0, 1, 2]) == 2);\n\n        //Normal input range\n        assert(!startsWith(filter!\"true\"(arr), 1));\n        assert(startsWith(filter!\"true\"(arr), 0));\n        assert(startsWith(filter!\"true\"(arr), [0]));\n        assert(startsWith(filter!\"true\"(arr), [0, 1]));\n        assert(startsWith(filter!\"true\"(arr), [0, 1], 7) == 1);\n        assert(!startsWith(filter!\"true\"(arr), [0, 1, 7]));\n        assert(startsWith(filter!\"true\"(arr), [0, 1, 7], [0, 1, 2]) == 2);\n        assert(startsWith(arr, filter!\"true\"([0, 1])));\n        assert(startsWith(arr, filter!\"true\"([0, 1]), 7) == 1);\n        assert(!startsWith(arr, filter!\"true\"([0, 1, 7])));\n        assert(startsWith(arr, [0, 1, 7], filter!\"true\"([0, 1, 2])) == 2);\n\n        //Non-default pred\n        assert(startsWith!(\"a%10 == b%10\")(arr, [10, 11]));\n        assert(!startsWith!(\"a%10 == b%10\")(arr, [10, 12]));\n    }}\n}\n\n/* (Not yet documented.)\nConsume all elements from `r` that are equal to one of the elements\n`es`.\n */\nprivate void skipAll(alias pred = \"a == b\", R, Es...)(ref R r, Es es)\n//if (is(typeof(binaryFun!pred(r1.front, es[0]))))\n{\n  loop:\n    for (; !r.empty; r.popFront())\n    {\n        foreach (i, E; Es)\n        {\n            if (binaryFun!pred(r.front, es[i]))\n            {\n                continue loop;\n            }\n        }\n        break;\n    }\n}\n\n@safe unittest\n{\n    auto s1 = \"Hello world\";\n    skipAll(s1, 'H', 'e');\n    assert(s1 == \"llo world\");\n}\n\n/**\nInterval option specifier for `until` (below) and others.\n\nIf set to `OpenRight.yes`, then the interval is open to the right\n(last element is not included).\n\nOtherwise if set to `OpenRight.no`, then the interval is closed to the right\n(last element included).\n */\nalias OpenRight = Flag!\"openRight\";\n\n/**\nLazily iterates `range` _until the element `e` for which\n`pred(e, sentinel)` is true.\n\nThis is similar to `takeWhile` in other languages.\n\nParams:\n    pred = Predicate to determine when to stop.\n    range = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    to iterate over.\n    sentinel = The element to stop at.\n    openRight = Determines whether the element for which the given predicate is\n        true should be included in the resulting range (`No.openRight`), or\n        not (`Yes.openRight`).\n\nReturns:\n    An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) that\n    iterates over the original range's elements, but ends when the specified\n    predicate becomes true. If the original range is a\n    $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) or\n    higher, this range will be a forward range.\n */\nUntil!(pred, Range, Sentinel)\nuntil(alias pred = \"a == b\", Range, Sentinel)\n(Range range, Sentinel sentinel, OpenRight openRight = Yes.openRight)\nif (!is(Sentinel == OpenRight))\n{\n    return typeof(return)(range, sentinel, openRight);\n}\n\n/// Ditto\nUntil!(pred, Range, void)\nuntil(alias pred, Range)\n(Range range, OpenRight openRight = Yes.openRight)\n{\n    return typeof(return)(range, openRight);\n}\n\n/// ditto\nstruct Until(alias pred, Range, Sentinel)\nif (isInputRange!Range)\n{\n    private Range _input;\n    static if (!is(Sentinel == void))\n        private Sentinel _sentinel;\n    private OpenRight _openRight;\n    private bool _done;\n\n    static if (!is(Sentinel == void))\n        ///\n        this(Range input, Sentinel sentinel,\n                OpenRight openRight = Yes.openRight)\n        {\n            _input = input;\n            _sentinel = sentinel;\n            _openRight = openRight;\n            _done = _input.empty || openRight && predSatisfied();\n        }\n    else\n        ///\n        this(Range input, OpenRight openRight = Yes.openRight)\n        {\n            _input = input;\n            _openRight = openRight;\n            _done = _input.empty || openRight && predSatisfied();\n        }\n\n    ///\n    @property bool empty()\n    {\n        return _done;\n    }\n\n    ///\n    @property auto ref front()\n    {\n        assert(!empty);\n        return _input.front;\n    }\n\n    private bool predSatisfied()\n    {\n        static if (is(Sentinel == void))\n            return cast(bool) unaryFun!pred(_input.front);\n        else\n            return cast(bool) startsWith!pred(_input, _sentinel);\n    }\n\n    ///\n    void popFront()\n    {\n        assert(!empty);\n        if (!_openRight)\n        {\n            _done = predSatisfied();\n            _input.popFront();\n            _done = _done || _input.empty;\n        }\n        else\n        {\n            _input.popFront();\n            _done = _input.empty || predSatisfied();\n        }\n    }\n\n    static if (isForwardRange!Range)\n    {\n        static if (!is(Sentinel == void))\n            ///\n            @property Until save()\n            {\n                Until result = this;\n                result._input     = _input.save;\n                result._sentinel  = _sentinel;\n                result._openRight = _openRight;\n                result._done      = _done;\n                return result;\n            }\n        else\n            ///\n            @property Until save()\n            {\n                Until result = this;\n                result._input     = _input.save;\n                result._openRight = _openRight;\n                result._done      = _done;\n                return result;\n            }\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : No;\n    int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5];\n    assert(equal(a.until(7), [1, 2, 4]));\n    assert(equal(a.until(7, No.openRight), [1, 2, 4, 7]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5];\n\n    static assert(isForwardRange!(typeof(a.until(7))));\n    static assert(isForwardRange!(typeof(until!\"a == 2\"(a, No.openRight))));\n\n    assert(equal(a.until(7), [1, 2, 4]));\n    assert(equal(a.until([7, 2]), [1, 2, 4, 7]));\n    assert(equal(a.until(7, No.openRight), [1, 2, 4, 7]));\n    assert(equal(until!\"a == 2\"(a, No.openRight), [1, 2]));\n}\n\n@system unittest // bugzilla 13171\n{\n    import std.algorithm.comparison : equal;\n    import std.range;\n    auto a = [1, 2, 3, 4];\n    assert(equal(refRange(&a).until(3, No.openRight), [1, 2, 3]));\n    assert(a == [4]);\n}\n\n@safe unittest // Issue 10460\n{\n    import std.algorithm.comparison : equal;\n    auto a = [1, 2, 3, 4];\n    foreach (ref e; a.until(3))\n        e = 0;\n    assert(equal(a, [0, 0, 3, 4]));\n}\n\n@safe unittest // Issue 13124\n{\n    import std.algorithm.comparison : among, equal;\n    auto s = \"hello how\\nare you\";\n    assert(equal(s.until!(c => c.among!('\\n', '\\r')), \"hello how\"));\n}\n"
  },
  {
    "path": "libphobos/src/std/algorithm/setops.d",
    "content": "// Written in the D programming language.\n/**\nThis is a submodule of $(MREF std, algorithm).\nIt contains generic algorithms that implement set operations.\n\nThe functions $(LREF multiwayMerge), $(LREF multiwayUnion), $(LREF setDifference),\n$(LREF setIntersection), $(LREF setSymmetricDifference) expect a range of sorted\nranges as input.\n\nAll algorithms are generalized to accept as input not only sets but also\n$(HTTP https://en.wikipedia.org/wiki/Multiset, multisets). Each algorithm\ndocuments behaviour in the presence of duplicated inputs.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE Cheat Sheet,\n$(TR $(TH Function Name) $(TH Description))\n$(T2 cartesianProduct,\n        Computes Cartesian product of two ranges.)\n$(T2 largestPartialIntersection,\n        Copies out the values that occur most frequently in a range of ranges.)\n$(T2 largestPartialIntersectionWeighted,\n        Copies out the values that occur most frequently (multiplied by\n        per-value weights) in a range of ranges.)\n$(T2 multiwayMerge,\n        Merges a range of sorted ranges.)\n$(T2 multiwayUnion,\n        Computes the union of a range of sorted ranges.)\n$(T2 setDifference,\n        Lazily computes the set difference of two or more sorted ranges.)\n$(T2 setIntersection,\n        Lazily computes the intersection of two or more sorted ranges.)\n$(T2 setSymmetricDifference,\n        Lazily computes the symmetric set difference of two or more sorted\n        ranges.)\n)\n\nCopyright: Andrei Alexandrescu 2008-.\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n\nSource: $(PHOBOSSRC std/algorithm/setops.d)\n\nMacros:\nT2=$(TR $(TDNW $(LREF $1)) $(TD $+))\n */\nmodule std.algorithm.setops;\n\nimport std.range.primitives;\n\n// FIXME\nimport std.functional; // : unaryFun, binaryFun;\nimport std.traits;\n// FIXME\nimport std.meta; // : AliasSeq, staticMap, allSatisfy, anySatisfy;\n\nimport std.algorithm.sorting; // : Merge;\nimport std.typecons : No;\n\n// cartesianProduct\n/**\nLazily computes the Cartesian product of two or more ranges. The product is a\nrange of tuples of elements from each respective range.\n\nThe conditions for the two-range case are as follows:\n\nIf both ranges are finite, then one must be (at least) a\n$(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) and the\nother an $(REF_ALTTEXT input range, isInputRange, std,range,primitives).\n\nIf one range is infinite and the other finite, then the finite range must\nbe a forward range, and the infinite range can be an input range.\n\nIf both ranges are infinite, then both must be forward ranges.\n\nWhen there are more than two ranges, the above conditions apply to each\nadjacent pair of ranges.\n\nParams:\n    range1 = The first range\n    range2 = The second range\n    ranges = Two or more non-infinite forward ranges\n    otherRanges = Zero or more non-infinite forward ranges\n\nReturns:\n    A forward range of $(REF Tuple, std,typecons) representing elements of the\n    cartesian product of the given ranges.\n*/\nauto cartesianProduct(R1, R2)(R1 range1, R2 range2)\nif (!allSatisfy!(isForwardRange, R1, R2) ||\n    anySatisfy!(isInfinite, R1, R2))\n{\n    import std.algorithm.iteration : map, joiner;\n\n    static if (isInfinite!R1 && isInfinite!R2)\n    {\n        static if (isForwardRange!R1 && isForwardRange!R2)\n        {\n            import std.range : zip, repeat, take, chain, sequence;\n\n            // This algorithm traverses the cartesian product by alternately\n            // covering the right and bottom edges of an increasing square area\n            // over the infinite table of combinations. This schedule allows us\n            // to require only forward ranges.\n            return zip(sequence!\"n\"(cast(size_t) 0), range1.save, range2.save,\n                       repeat(range1), repeat(range2))\n                .map!(function(a) => chain(\n                    zip(repeat(a[1]), take(a[4].save, a[0])),\n                    zip(take(a[3].save, a[0]+1), repeat(a[2]))\n                ))()\n                .joiner();\n        }\n        else static assert(0, \"cartesianProduct of infinite ranges requires \"~\n                              \"forward ranges\");\n    }\n    else static if (isInputRange!R1 && isForwardRange!R2 && !isInfinite!R2)\n    {\n        import std.range : zip, repeat;\n        return joiner(map!((ElementType!R1 a) => zip(repeat(a), range2.save))\n                          (range1));\n    }\n    else static if (isInputRange!R2 && isForwardRange!R1 && !isInfinite!R1)\n    {\n        import std.range : zip, repeat;\n        return joiner(map!((ElementType!R2 a) => zip(range1.save, repeat(a)))\n                          (range2));\n    }\n    else static assert(0, \"cartesianProduct involving finite ranges must \"~\n                          \"have at least one finite forward range\");\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.searching : canFind;\n    import std.range;\n    import std.typecons : tuple;\n\n    auto N = sequence!\"n\"(0);         // the range of natural numbers\n    auto N2 = cartesianProduct(N, N); // the range of all pairs of natural numbers\n\n    // Various arbitrary number pairs can be found in the range in finite time.\n    assert(canFind(N2, tuple(0, 0)));\n    assert(canFind(N2, tuple(123, 321)));\n    assert(canFind(N2, tuple(11, 35)));\n    assert(canFind(N2, tuple(279, 172)));\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.searching : canFind;\n    import std.typecons : tuple;\n\n    auto B = [ 1, 2, 3 ];\n    auto C = [ 4, 5, 6 ];\n    auto BC = cartesianProduct(B, C);\n\n    foreach (n; [[1, 4], [2, 4], [3, 4], [1, 5], [2, 5], [3, 5], [1, 6],\n                 [2, 6], [3, 6]])\n    {\n        assert(canFind(BC, tuple(n[0], n[1])));\n    }\n}\n\n@safe unittest\n{\n    // Test cartesian product of two infinite ranges\n    import std.algorithm.searching : canFind;\n    import std.range;\n    import std.typecons : tuple;\n\n    auto Even = sequence!\"2*n\"(0);\n    auto Odd = sequence!\"2*n+1\"(0);\n    auto EvenOdd = cartesianProduct(Even, Odd);\n\n    foreach (pair; [[0, 1], [2, 1], [0, 3], [2, 3], [4, 1], [4, 3], [0, 5],\n                    [2, 5], [4, 5], [6, 1], [6, 3], [6, 5]])\n    {\n        assert(canFind(EvenOdd, tuple(pair[0], pair[1])));\n    }\n\n    // This should terminate in finite time\n    assert(canFind(EvenOdd, tuple(124, 73)));\n    assert(canFind(EvenOdd, tuple(0, 97)));\n    assert(canFind(EvenOdd, tuple(42, 1)));\n}\n\n@safe unittest\n{\n    // Test cartesian product of an infinite input range and a finite forward\n    // range.\n    import std.algorithm.searching : canFind;\n    import std.range;\n    import std.typecons : tuple;\n\n    auto N = sequence!\"n\"(0);\n    auto M = [100, 200, 300];\n    auto NM = cartesianProduct(N,M);\n\n    foreach (pair; [[0, 100], [0, 200], [0, 300], [1, 100], [1, 200], [1, 300],\n                    [2, 100], [2, 200], [2, 300], [3, 100], [3, 200],\n                    [3, 300]])\n    {\n        assert(canFind(NM, tuple(pair[0], pair[1])));\n    }\n\n    // We can't solve the halting problem, so we can only check a finite\n    // initial segment here.\n    assert(!canFind(NM.take(100), tuple(100, 0)));\n    assert(!canFind(NM.take(100), tuple(1, 1)));\n    assert(!canFind(NM.take(100), tuple(100, 200)));\n\n    auto MN = cartesianProduct(M,N);\n    foreach (pair; [[100, 0], [200, 0], [300, 0], [100, 1], [200, 1], [300, 1],\n                    [100, 2], [200, 2], [300, 2], [100, 3], [200, 3],\n                    [300, 3]])\n    {\n        assert(canFind(MN, tuple(pair[0], pair[1])));\n    }\n\n    // We can't solve the halting problem, so we can only check a finite\n    // initial segment here.\n    assert(!canFind(MN.take(100), tuple(0, 100)));\n    assert(!canFind(MN.take(100), tuple(0, 1)));\n    assert(!canFind(MN.take(100), tuple(100, 200)));\n}\n\n@safe unittest\n{\n    import std.algorithm.searching : canFind;\n    import std.typecons : tuple;\n\n    // Test cartesian product of two finite ranges.\n    auto X = [1, 2, 3];\n    auto Y = [4, 5, 6];\n    auto XY = cartesianProduct(X, Y);\n    auto Expected = [[1, 4], [1, 5], [1, 6], [2, 4], [2, 5], [2, 6], [3, 4],\n                     [3, 5], [3, 6]];\n\n    // Verify Expected ⊆ XY\n    foreach (pair; Expected)\n    {\n        assert(canFind(XY, tuple(pair[0], pair[1])));\n    }\n\n    // Verify XY ⊆ Expected\n    foreach (pair; XY)\n    {\n        assert(canFind(Expected, [pair[0], pair[1]]));\n    }\n\n    // And therefore, by set comprehension, XY == Expected\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    import std.algorithm.searching : canFind;\n    import std.typecons : tuple;\n\n    import std.range;\n    auto N = sequence!\"n\"(0);\n\n    // To force the template to fall to the second case, we wrap N in a struct\n    // that doesn't allow bidirectional access.\n    struct FwdRangeWrapper(R)\n    {\n        R impl;\n\n        // Input range API\n        @property auto front() { return impl.front; }\n        void popFront() { impl.popFront(); }\n        static if (isInfinite!R)\n            enum empty = false;\n        else\n            @property bool empty() { return impl.empty; }\n\n        // Forward range API\n        @property auto save() { return typeof(this)(impl.save); }\n    }\n    auto fwdWrap(R)(R range) { return FwdRangeWrapper!R(range); }\n\n    // General test: two infinite bidirectional ranges\n    auto N2 = cartesianProduct(N, N);\n\n    assert(canFind(N2, tuple(0, 0)));\n    assert(canFind(N2, tuple(123, 321)));\n    assert(canFind(N2, tuple(11, 35)));\n    assert(canFind(N2, tuple(279, 172)));\n\n    // Test first case: forward range with bidirectional range\n    auto fwdN = fwdWrap(N);\n    auto N2_a = cartesianProduct(fwdN, N);\n\n    assert(canFind(N2_a, tuple(0, 0)));\n    assert(canFind(N2_a, tuple(123, 321)));\n    assert(canFind(N2_a, tuple(11, 35)));\n    assert(canFind(N2_a, tuple(279, 172)));\n\n    // Test second case: bidirectional range with forward range\n    auto N2_b = cartesianProduct(N, fwdN);\n\n    assert(canFind(N2_b, tuple(0, 0)));\n    assert(canFind(N2_b, tuple(123, 321)));\n    assert(canFind(N2_b, tuple(11, 35)));\n    assert(canFind(N2_b, tuple(279, 172)));\n\n    // Test third case: finite forward range with (infinite) input range\n    static struct InpRangeWrapper(R)\n    {\n        R impl;\n\n        // Input range API\n        @property auto front() { return impl.front; }\n        void popFront() { impl.popFront(); }\n        static if (isInfinite!R)\n            enum empty = false;\n        else\n            @property bool empty() { return impl.empty; }\n    }\n    auto inpWrap(R)(R r) { return InpRangeWrapper!R(r); }\n\n    auto inpN = inpWrap(N);\n    auto B = [ 1, 2, 3 ];\n    auto fwdB = fwdWrap(B);\n    auto BN = cartesianProduct(fwdB, inpN);\n\n    assert(equal(map!\"[a[0],a[1]]\"(BN.take(10)), [[1, 0], [2, 0], [3, 0],\n                 [1, 1], [2, 1], [3, 1], [1, 2], [2, 2], [3, 2], [1, 3]]));\n\n    // Test fourth case: (infinite) input range with finite forward range\n    auto NB = cartesianProduct(inpN, fwdB);\n\n    assert(equal(map!\"[a[0],a[1]]\"(NB.take(10)), [[0, 1], [0, 2], [0, 3],\n                 [1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1]]));\n\n    // General finite range case\n    auto C = [ 4, 5, 6 ];\n    auto BC = cartesianProduct(B, C);\n\n    foreach (n; [[1, 4], [2, 4], [3, 4], [1, 5], [2, 5], [3, 5], [1, 6],\n                 [2, 6], [3, 6]])\n    {\n        assert(canFind(BC, tuple(n[0], n[1])));\n    }\n}\n\n// Issue 13091\npure nothrow @safe @nogc unittest\n{\n    int[1] a = [1];\n    foreach (t; cartesianProduct(a[], a[])) {}\n}\n\n/// ditto\nauto cartesianProduct(RR...)(RR ranges)\nif (ranges.length >= 2 &&\n    allSatisfy!(isForwardRange, RR) &&\n    !anySatisfy!(isInfinite, RR))\n{\n    // This overload uses a much less template-heavy implementation when\n    // all ranges are finite forward ranges, which is the most common use\n    // case, so that we don't run out of resources too quickly.\n    //\n    // For infinite ranges or non-forward ranges, we fall back to the old\n    // implementation which expands an exponential number of templates.\n    import std.typecons : tuple;\n\n    static struct Result\n    {\n        RR ranges;\n        RR current;\n        bool empty = true;\n\n        this(RR _ranges)\n        {\n            ranges = _ranges;\n            empty = false;\n            foreach (i, r; ranges)\n            {\n                current[i] = r.save;\n                if (current[i].empty)\n                    empty = true;\n            }\n        }\n        @property auto front()\n        {\n            import std.algorithm.internal : algoFormat;\n            import std.range : iota;\n            return mixin(algoFormat(\"tuple(%(current[%d].front%|,%))\",\n                                    iota(0, current.length)));\n        }\n        void popFront()\n        {\n            foreach_reverse (i, ref r; current)\n            {\n                r.popFront();\n                if (!r.empty) break;\n\n                static if (i == 0)\n                    empty = true;\n                else\n                    r = ranges[i].save; // rollover\n            }\n        }\n        @property Result save()\n        {\n            Result copy = this;\n            foreach (i, r; ranges)\n            {\n                copy.ranges[i] = r.save;\n                copy.current[i] = current[i].save;\n            }\n            return copy;\n        }\n    }\n    static assert(isForwardRange!Result);\n\n    return Result(ranges);\n}\n\n@safe unittest\n{\n    // Issue 10693: cartesian product of empty ranges should be empty.\n    int[] a, b, c, d, e;\n    auto cprod = cartesianProduct(a,b,c,d,e);\n    assert(cprod.empty);\n    foreach (_; cprod) {} // should not crash\n\n    // Test case where only one of the ranges is empty: the result should still\n    // be empty.\n    int[] p=[1], q=[];\n    auto cprod2 = cartesianProduct(p,p,p,q,p);\n    assert(cprod2.empty);\n    foreach (_; cprod2) {} // should not crash\n}\n\n@safe unittest\n{\n    // .init value of cartesianProduct should be empty\n    auto cprod = cartesianProduct([0,0], [1,1], [2,2]);\n    assert(!cprod.empty);\n    assert(cprod.init.empty);\n}\n\n@safe unittest\n{\n    // Issue 13393\n    assert(!cartesianProduct([0],[0],[0]).save.empty);\n}\n\n/// ditto\nauto cartesianProduct(R1, R2, RR...)(R1 range1, R2 range2, RR otherRanges)\nif (!allSatisfy!(isForwardRange, R1, R2, RR) ||\n    anySatisfy!(isInfinite, R1, R2, RR))\n{\n    /* We implement the n-ary cartesian product by recursively invoking the\n     * binary cartesian product. To make the resulting range nicer, we denest\n     * one level of tuples so that a ternary cartesian product, for example,\n     * returns 3-element tuples instead of nested 2-element tuples.\n     */\n    import std.algorithm.internal : algoFormat;\n    import std.algorithm.iteration : map;\n    import std.range : iota;\n\n    enum string denest = algoFormat(\"tuple(a[0], %(a[1][%d]%|,%))\",\n                                iota(0, otherRanges.length+1));\n    return map!denest(\n        cartesianProduct(range1, cartesianProduct(range2, otherRanges))\n    );\n}\n\n@safe unittest\n{\n    import std.algorithm.searching : canFind;\n    import std.range;\n    import std.typecons : tuple, Tuple;\n\n    auto N = sequence!\"n\"(0);\n    auto N3 = cartesianProduct(N, N, N);\n\n    // Check that tuples are properly denested\n    assert(is(ElementType!(typeof(N3)) == Tuple!(size_t,size_t,size_t)));\n\n    assert(canFind(N3, tuple(0, 27, 7)));\n    assert(canFind(N3, tuple(50, 23, 71)));\n    assert(canFind(N3, tuple(9, 3, 0)));\n}\n\n@safe unittest\n{\n    import std.algorithm.searching : canFind;\n    import std.range;\n    import std.typecons : tuple, Tuple;\n\n    auto N = sequence!\"n\"(0);\n    auto N4 = cartesianProduct(N, N, N, N);\n\n    // Check that tuples are properly denested\n    assert(is(ElementType!(typeof(N4)) == Tuple!(size_t,size_t,size_t,size_t)));\n\n    assert(canFind(N4, tuple(1, 2, 3, 4)));\n    assert(canFind(N4, tuple(4, 3, 2, 1)));\n    assert(canFind(N4, tuple(10, 3, 7, 2)));\n}\n\n// Issue 9878\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : tuple;\n\n    auto A = [ 1, 2, 3 ];\n    auto B = [ 'a', 'b', 'c' ];\n    auto C = [ \"x\", \"y\", \"z\" ];\n    auto ABC = cartesianProduct(A, B, C);\n\n    assert(ABC.equal([\n        tuple(1, 'a', \"x\"), tuple(1, 'a', \"y\"), tuple(1, 'a', \"z\"),\n        tuple(1, 'b', \"x\"), tuple(1, 'b', \"y\"), tuple(1, 'b', \"z\"),\n        tuple(1, 'c', \"x\"), tuple(1, 'c', \"y\"), tuple(1, 'c', \"z\"),\n        tuple(2, 'a', \"x\"), tuple(2, 'a', \"y\"), tuple(2, 'a', \"z\"),\n        tuple(2, 'b', \"x\"), tuple(2, 'b', \"y\"), tuple(2, 'b', \"z\"),\n        tuple(2, 'c', \"x\"), tuple(2, 'c', \"y\"), tuple(2, 'c', \"z\"),\n        tuple(3, 'a', \"x\"), tuple(3, 'a', \"y\"), tuple(3, 'a', \"z\"),\n        tuple(3, 'b', \"x\"), tuple(3, 'b', \"y\"), tuple(3, 'b', \"z\"),\n        tuple(3, 'c', \"x\"), tuple(3, 'c', \"y\"), tuple(3, 'c', \"z\")\n    ]));\n}\n\npure @safe nothrow @nogc unittest\n{\n    import std.range.primitives : isForwardRange;\n    int[2] A = [1,2];\n    auto C = cartesianProduct(A[], A[], A[]);\n    assert(isForwardRange!(typeof(C)));\n\n    C.popFront();\n    auto front1 = C.front;\n    auto D = C.save;\n    C.popFront();\n    assert(D.front == front1);\n}\n\n// Issue 13935\n@safe unittest\n{\n    import std.algorithm.iteration : map;\n    auto seq = [1, 2].map!(x => x);\n    foreach (pair; cartesianProduct(seq, seq)) {}\n}\n\n// largestPartialIntersection\n/**\nGiven a range of sorted $(REF_ALTTEXT forward ranges, isForwardRange, std,range,primitives)\n`ror`, copies to `tgt` the elements that are common to most ranges, along with their number\nof occurrences. All ranges in `ror` are assumed to be sorted by $(D\nless). Only the most frequent `tgt.length` elements are returned.\n\nParams:\n    less = The predicate the ranges are sorted by.\n    ror = A range of forward ranges sorted by `less`.\n    tgt = The target range to copy common elements to.\n    sorted = Whether the elements copied should be in sorted order.\n\nThe function `largestPartialIntersection` is useful for\ne.g. searching an $(LINK2 https://en.wikipedia.org/wiki/Inverted_index,\ninverted index) for the documents most\nlikely to contain some terms of interest. The complexity of the search\nis $(BIGOH n * log(tgt.length)), where `n` is the sum of lengths of\nall input ranges. This approach is faster than keeping an associative\narray of the occurrences and then selecting its top items, and also\nrequires less memory (`largestPartialIntersection` builds its\nresult directly in `tgt` and requires no extra memory).\n\nIf at least one of the ranges is a multiset, then all occurences\nof a duplicate element are taken into account. The result is\nequivalent to merging all ranges and picking the most frequent\n`tgt.length` elements.\n\nWarning: Because `largestPartialIntersection` does not allocate\nextra memory, it will leave `ror` modified. Namely, $(D\nlargestPartialIntersection) assumes ownership of `ror` and\ndiscretionarily swaps and advances elements of it. If you want $(D\nror) to preserve its contents after the call, you may want to pass a\nduplicate to `largestPartialIntersection` (and perhaps cache the\nduplicate in between calls).\n */\nvoid largestPartialIntersection\n(alias less = \"a < b\", RangeOfRanges, Range)\n(RangeOfRanges ror, Range tgt, SortOutput sorted = No.sortOutput)\n{\n    struct UnitWeights\n    {\n        static int opIndex(ElementType!(ElementType!RangeOfRanges)) { return 1; }\n    }\n    return largestPartialIntersectionWeighted!less(ror, tgt, UnitWeights(),\n            sorted);\n}\n\n///\n@system unittest\n{\n    import std.typecons : tuple, Tuple;\n\n    // Figure which number can be found in most arrays of the set of\n    // arrays below.\n    double[][] a =\n    [\n        [ 1, 4, 7, 8 ],\n        [ 1, 7 ],\n        [ 1, 7, 8],\n        [ 4 ],\n        [ 7 ],\n    ];\n    auto b = new Tuple!(double, uint)[1];\n    // it will modify the input range, hence we need to create a duplicate\n    largestPartialIntersection(a.dup, b);\n    // First member is the item, second is the occurrence count\n    assert(b[0] == tuple(7.0, 4u));\n    // 7.0 occurs in 4 out of 5 inputs, more than any other number\n\n    // If more of the top-frequent numbers are needed, just create a larger\n    // tgt range\n    auto c = new Tuple!(double, uint)[2];\n    largestPartialIntersection(a, c);\n    assert(c[0] == tuple(1.0, 3u));\n    // 1.0 occurs in 3 inputs\n\n    // multiset\n    double[][] x =\n    [\n        [1, 1, 1, 1, 4, 7, 8],\n        [1, 7],\n        [1, 7, 8],\n        [4, 7],\n        [7]\n    ];\n    auto y = new Tuple!(double, uint)[2];\n    largestPartialIntersection(x.dup, y);\n    // 7.0 occurs 5 times\n    assert(y[0] == tuple(7.0, 5u));\n    // 1.0 occurs 6 times\n    assert(y[1] == tuple(1.0, 6u));\n}\n\nimport std.algorithm.sorting : SortOutput; // FIXME\n\n// largestPartialIntersectionWeighted\n/**\nSimilar to `largestPartialIntersection`, but associates a weight\nwith each distinct element in the intersection.\n\nIf at least one of the ranges is a multiset, then all occurences\nof a duplicate element are taken into account. The result\nis equivalent to merging all input ranges and picking the highest\n`tgt.length`, weight-based ranking elements.\n\nParams:\n    less = The predicate the ranges are sorted by.\n    ror = A range of $(REF_ALTTEXT forward ranges, isForwardRange, std,range,primitives)\n    sorted by `less`.\n    tgt = The target range to copy common elements to.\n    weights = An associative array mapping elements to weights.\n    sorted = Whether the elements copied should be in sorted order.\n\n*/\nvoid largestPartialIntersectionWeighted\n(alias less = \"a < b\", RangeOfRanges, Range, WeightsAA)\n(RangeOfRanges ror, Range tgt, WeightsAA weights, SortOutput sorted = No.sortOutput)\n{\n    import std.algorithm.iteration : group;\n    import std.algorithm.sorting : topNCopy;\n\n    if (tgt.empty) return;\n    alias InfoType = ElementType!Range;\n    bool heapComp(InfoType a, InfoType b)\n    {\n        return weights[a[0]] * a[1] > weights[b[0]] * b[1];\n    }\n    topNCopy!heapComp(group(multiwayMerge!less(ror)), tgt, sorted);\n}\n\n///\n@system unittest\n{\n    import std.typecons : tuple, Tuple;\n\n    // Figure which number can be found in most arrays of the set of\n    // arrays below, with specific per-element weights\n    double[][] a =\n    [\n        [ 1, 4, 7, 8 ],\n        [ 1, 7 ],\n        [ 1, 7, 8],\n        [ 4 ],\n        [ 7 ],\n    ];\n    auto b = new Tuple!(double, uint)[1];\n    double[double] weights = [ 1:1.2, 4:2.3, 7:1.1, 8:1.1 ];\n    largestPartialIntersectionWeighted(a, b, weights);\n    // First member is the item, second is the occurrence count\n    assert(b[0] == tuple(4.0, 2u));\n    // 4.0 occurs 2 times -> 4.6 (2 * 2.3)\n    // 7.0 occurs 3 times -> 4.4 (3 * 1.1)\n\n   // multiset\n    double[][] x =\n    [\n        [ 1, 1, 1, 4, 7, 8 ],\n        [ 1, 7 ],\n        [ 1, 7, 8],\n        [ 4 ],\n        [ 7 ],\n    ];\n    auto y = new Tuple!(double, uint)[1];\n    largestPartialIntersectionWeighted(x, y, weights);\n    assert(y[0] == tuple(1.0, 5u));\n    // 1.0 occurs 5 times -> 1.2 * 5 = 6\n}\n\n@system unittest\n{\n    import std.conv : text;\n    import std.typecons : tuple, Tuple, Yes;\n\n    double[][] a =\n        [\n            [ 1, 4, 7, 8 ],\n            [ 1, 7 ],\n            [ 1, 7, 8],\n            [ 4 ],\n            [ 7 ],\n        ];\n    auto b = new Tuple!(double, uint)[2];\n    largestPartialIntersection(a, b, Yes.sortOutput);\n    assert(b == [ tuple(7.0, 4u), tuple(1.0, 3u) ][], text(b));\n    assert(a[0].empty);\n}\n\n@system unittest\n{\n    import std.conv : text;\n    import std.typecons : tuple, Tuple, Yes;\n\n    string[][] a =\n        [\n            [ \"1\", \"4\", \"7\", \"8\" ],\n            [ \"1\", \"7\" ],\n            [ \"1\", \"7\", \"8\"],\n            [ \"4\" ],\n            [ \"7\" ],\n        ];\n    auto b = new Tuple!(string, uint)[2];\n    largestPartialIntersection(a, b, Yes.sortOutput);\n    assert(b == [ tuple(\"7\", 4u), tuple(\"1\", 3u) ][], text(b));\n}\n\n@system unittest\n{\n    import std.typecons : tuple, Tuple;\n\n    // Figure which number can be found in most arrays of the set of\n    // arrays below, with specific per-element weights\n    double[][] a =\n        [\n            [ 1, 4, 7, 8 ],\n            [ 1, 7 ],\n            [ 1, 7, 8],\n            [ 4 ],\n            [ 7 ],\n            ];\n    auto b = new Tuple!(double, uint)[1];\n    double[double] weights = [ 1:1.2, 4:2.3, 7:1.1, 8:1.1 ];\n    largestPartialIntersectionWeighted(a, b, weights);\n    // First member is the item, second is the occurrence count\n    assert(b[0] == tuple(4.0, 2u));\n}\n\n@system unittest\n{\n    import std.container : Array;\n    import std.typecons : Tuple;\n\n    alias T = Tuple!(uint, uint);\n    const Array!T arrayOne = Array!T( [ T(1,2), T(3,4) ] );\n    const Array!T arrayTwo = Array!T([ T(1,2), T(3,4) ] );\n\n    assert(arrayOne == arrayTwo);\n}\n\n// MultiwayMerge\n/**\nMerges multiple sets. The input sets are passed as a\nrange of ranges and each is assumed to be sorted by $(D\nless). Computation is done lazily, one union element at a time. The\ncomplexity of one `popFront` operation is $(BIGOH\nlog(ror.length)). However, the length of `ror` decreases as ranges\nin it are exhausted, so the complexity of a full pass through $(D\nMultiwayMerge) is dependent on the distribution of the lengths of ranges\ncontained within `ror`. If all ranges have the same length `n`\n(worst case scenario), the complexity of a full pass through $(D\nMultiwayMerge) is $(BIGOH n * ror.length * log(ror.length)), i.e., $(D\nlog(ror.length)) times worse than just spanning all ranges in\nturn. The output comes sorted (unstably) by `less`.\n\nThe length of the resulting range is the sum of all lengths of\nthe ranges passed as input. This means that all elements (duplicates\nincluded) are transferred to the resulting range.\n\nFor backward compatibility, `multiwayMerge` is available under\nthe name `nWayUnion` and `MultiwayMerge` under the name of `NWayUnion` .\nFuture code should use `multiwayMerge` and `MultiwayMerge` as `nWayUnion`\nand `NWayUnion` will be deprecated.\n\nParams:\n    less = Predicate the given ranges are sorted by.\n    ror = A range of ranges sorted by `less` to compute the union for.\n\nReturns:\n    A range of the union of the ranges in `ror`.\n\nWarning: Because `MultiwayMerge` does not allocate extra memory, it\nwill leave `ror` modified. Namely, `MultiwayMerge` assumes ownership\nof `ror` and discretionarily swaps and advances elements of it. If\nyou want `ror` to preserve its contents after the call, you may\nwant to pass a duplicate to `MultiwayMerge` (and perhaps cache the\nduplicate in between calls).\n */\nstruct MultiwayMerge(alias less, RangeOfRanges)\n{\n    import std.container : BinaryHeap;\n\n    private alias ElementType = .ElementType!(.ElementType!RangeOfRanges);\n    private alias comp = binaryFun!less;\n    private RangeOfRanges _ror;\n\n    ///\n    static bool compFront(.ElementType!RangeOfRanges a,\n            .ElementType!RangeOfRanges b)\n    {\n        // revert comparison order so we get the smallest elements first\n        return comp(b.front, a.front);\n    }\n    private BinaryHeap!(RangeOfRanges, compFront) _heap;\n\n    ///\n    this(RangeOfRanges ror)\n    {\n        import std.algorithm.mutation : remove, SwapStrategy;\n\n        // Preemptively get rid of all empty ranges in the input\n        // No need for stability either\n        _ror = remove!(\"a.empty\", SwapStrategy.unstable)(ror);\n        //Build the heap across the range\n        _heap.acquire(_ror);\n    }\n\n    ///\n    @property bool empty() { return _ror.empty; }\n\n    ///\n    @property auto ref front()\n    {\n        return _heap.front.front;\n    }\n\n    ///\n    void popFront()\n    {\n        _heap.removeFront();\n        // let's look at the guy just popped\n        _ror.back.popFront();\n        if (_ror.back.empty)\n        {\n            _ror.popBack();\n            // nothing else to do: the empty range is not in the\n            // heap and not in _ror\n            return;\n        }\n        // Put the popped range back in the heap\n        _heap.conditionalInsert(_ror.back) || assert(false);\n    }\n}\n\n/// Ditto\nMultiwayMerge!(less, RangeOfRanges) multiwayMerge\n(alias less = \"a < b\", RangeOfRanges)\n(RangeOfRanges ror)\n{\n    return typeof(return)(ror);\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    double[][] a =\n    [\n        [ 1, 4, 7, 8 ],\n        [ 1, 7 ],\n        [ 1, 7, 8],\n        [ 4 ],\n        [ 7 ],\n    ];\n    auto witness = [\n        1, 1, 1, 4, 4, 7, 7, 7, 7, 8, 8\n    ];\n    assert(equal(multiwayMerge(a), witness));\n\n    double[][] b =\n    [\n        // range with duplicates\n        [ 1, 1, 4, 7, 8 ],\n        [ 7 ],\n        [ 1, 7, 8],\n        [ 4 ],\n        [ 7 ],\n    ];\n    // duplicates are propagated to the resulting range\n    assert(equal(multiwayMerge(b), witness));\n}\n\nalias nWayUnion = multiwayMerge;\nalias NWayUnion = MultiwayMerge;\n\n/**\nComputes the union of multiple ranges. The\n$(REF_ALTTEXT input ranges, isInputRange, std,range,primitives) are passed\nas a range of ranges and each is assumed to be sorted by $(D\nless). Computation is done lazily, one union element at a time.\n`multiwayUnion(ror)` is functionally equivalent to `multiwayMerge(ror).uniq`.\n\n\"The output of multiwayUnion has no duplicates even when its inputs contain duplicates.\"\n\nParams:\n    less = Predicate the given ranges are sorted by.\n    ror = A range of ranges sorted by `less` to compute the intersection for.\n\nReturns:\n    A range of the union of the ranges in `ror`.\n\nSee also: $(LREF multiwayMerge)\n */\nauto multiwayUnion(alias less = \"a < b\", RangeOfRanges)(RangeOfRanges ror)\n{\n    import std.algorithm.iteration : uniq;\n    import std.functional : not;\n    return ror.multiwayMerge!(less).uniq!(not!less);\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // sets\n    double[][] a =\n    [\n        [ 1, 4, 7, 8 ],\n        [ 1, 7 ],\n        [ 1, 7, 8],\n        [ 4 ],\n        [ 7 ],\n    ];\n\n    auto witness = [1, 4, 7, 8];\n    assert(equal(multiwayUnion(a), witness));\n\n    // multisets\n    double[][] b =\n    [\n        [ 1, 1, 1, 4, 7, 8 ],\n        [ 1, 7 ],\n        [ 1, 7, 7, 8],\n        [ 4 ],\n        [ 7 ],\n    ];\n    assert(equal(multiwayUnion(b), witness));\n\n    double[][] c =\n    [\n        [9, 8, 8, 8, 7, 6],\n        [9, 8, 6],\n        [9, 8, 5]\n    ];\n    auto witness2 = [9, 8, 7, 6, 5];\n    assert(equal(multiwayUnion!\"a > b\"(c), witness2));\n}\n\n/**\nLazily computes the difference of `r1` and `r2`. The two ranges\nare assumed to be sorted by `less`. The element types of the two\nranges must have a common type.\n\n\nIn the case of multisets, considering that element `a` appears `x`\ntimes in `r1` and `y` times and `r2`, the number of occurences\nof `a` in the resulting range is going to be `x-y` if x > y or 0 othwerise.\n\nParams:\n    less = Predicate the given ranges are sorted by.\n    r1 = The first range.\n    r2 = The range to subtract from `r1`.\n\nReturns:\n    A range of the difference of `r1` and `r2`.\n\nSee_also: $(LREF setSymmetricDifference)\n */\nstruct SetDifference(alias less = \"a < b\", R1, R2)\nif (isInputRange!(R1) && isInputRange!(R2))\n{\nprivate:\n    R1 r1;\n    R2 r2;\n    alias comp = binaryFun!(less);\n\n    void adjustPosition()\n    {\n        while (!r1.empty)\n        {\n            if (r2.empty || comp(r1.front, r2.front)) break;\n            if (comp(r2.front, r1.front))\n            {\n                r2.popFront();\n            }\n            else\n            {\n                // both are equal\n                r1.popFront();\n                r2.popFront();\n            }\n        }\n    }\n\npublic:\n    ///\n    this(R1 r1, R2 r2)\n    {\n        this.r1 = r1;\n        this.r2 = r2;\n        // position to the first element\n        adjustPosition();\n    }\n\n    ///\n    void popFront()\n    {\n        r1.popFront();\n        adjustPosition();\n    }\n\n    ///\n    @property auto ref front()\n    {\n        assert(!empty);\n        return r1.front;\n    }\n\n    static if (isForwardRange!R1 && isForwardRange!R2)\n    {\n        ///\n        @property typeof(this) save()\n        {\n            auto ret = this;\n            ret.r1 = r1.save;\n            ret.r2 = r2.save;\n            return ret;\n        }\n    }\n\n    ///\n    @property bool empty() { return r1.empty; }\n}\n\n/// Ditto\nSetDifference!(less, R1, R2) setDifference(alias less = \"a < b\", R1, R2)\n(R1 r1, R2 r2)\n{\n    return typeof(return)(r1, r2);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range.primitives : isForwardRange;\n\n    //sets\n    int[] a = [ 1, 2, 4, 5, 7, 9 ];\n    int[] b = [ 0, 1, 2, 4, 7, 8 ];\n    assert(equal(setDifference(a, b), [5, 9]));\n    static assert(isForwardRange!(typeof(setDifference(a, b))));\n\n    // multisets\n    int[] x = [1, 1, 1, 2, 3];\n    int[] y = [1, 1, 2, 4, 5];\n    auto r = setDifference(x, y);\n    assert(equal(r, [1, 3]));\n    assert(setDifference(r, x).empty);\n}\n\n@safe unittest // Issue 10460\n{\n    import std.algorithm.comparison : equal;\n\n    int[] a = [1, 2, 3, 4, 5];\n    int[] b = [2, 4];\n    foreach (ref e; setDifference(a, b))\n        e = 0;\n    assert(equal(a, [0, 2, 0, 4, 0]));\n}\n\n/**\nLazily computes the intersection of two or more\n$(REF_ALTTEXT input ranges, isInputRange, std,range,primitives)\n`ranges`. The ranges are assumed to be sorted by `less`. The element\ntypes of the ranges must have a common type.\n\nIn the case of multisets, the range with the minimum number of\noccurences of a given element, propagates the number of\noccurences of this element to the resulting range.\n\nParams:\n    less = Predicate the given ranges are sorted by.\n    ranges = The ranges to compute the intersection for.\n\nReturns:\n    A range containing the intersection of the given ranges.\n */\nstruct SetIntersection(alias less = \"a < b\", Rs...)\nif (Rs.length >= 2 && allSatisfy!(isInputRange, Rs) &&\n    !is(CommonType!(staticMap!(ElementType, Rs)) == void))\n{\nprivate:\n    Rs _input;\n    alias comp = binaryFun!less;\n    alias ElementType = CommonType!(staticMap!(.ElementType, Rs));\n\n    // Positions to the first elements that are all equal\n    void adjustPosition()\n    {\n        if (empty) return;\n\n        size_t done = Rs.length;\n        static if (Rs.length > 1) while (true)\n        {\n            foreach (i, ref r; _input)\n            {\n                alias next = _input[(i + 1) % Rs.length];\n\n                if (comp(next.front, r.front))\n                {\n                    do\n                    {\n                        next.popFront();\n                        if (next.empty) return;\n                    } while (comp(next.front, r.front));\n                    done = Rs.length;\n                }\n                if (--done == 0) return;\n            }\n        }\n    }\n\npublic:\n    ///\n    this(Rs input)\n    {\n        this._input = input;\n        // position to the first element\n        adjustPosition();\n    }\n\n    ///\n    @property bool empty()\n    {\n        foreach (ref r; _input)\n        {\n            if (r.empty) return true;\n        }\n        return false;\n    }\n\n    ///\n    void popFront()\n    {\n        assert(!empty);\n        static if (Rs.length > 1) foreach (i, ref r; _input)\n        {\n            alias next = _input[(i + 1) % Rs.length];\n            assert(!comp(r.front, next.front));\n        }\n\n        foreach (ref r; _input)\n        {\n            r.popFront();\n        }\n        adjustPosition();\n    }\n\n    ///\n    @property ElementType front()\n    {\n        assert(!empty);\n        return _input[0].front;\n    }\n\n    static if (allSatisfy!(isForwardRange, Rs))\n    {\n        ///\n        @property SetIntersection save()\n        {\n            auto ret = this;\n            foreach (i, ref r; _input)\n            {\n                ret._input[i] = r.save;\n            }\n            return ret;\n        }\n    }\n}\n\n/// Ditto\nSetIntersection!(less, Rs) setIntersection(alias less = \"a < b\", Rs...)(Rs ranges)\nif (Rs.length >= 2 && allSatisfy!(isInputRange, Rs) &&\n    !is(CommonType!(staticMap!(ElementType, Rs)) == void))\n{\n    return typeof(return)(ranges);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // sets\n    int[] a = [ 1, 2, 4, 5, 7, 9 ];\n    int[] b = [ 0, 1, 2, 4, 7, 8 ];\n    int[] c = [ 0, 1, 4, 5, 7, 8 ];\n    assert(equal(setIntersection(a, a), a));\n    assert(equal(setIntersection(a, b), [1, 2, 4, 7]));\n    assert(equal(setIntersection(a, b, c), [1, 4, 7]));\n\n    // multisets\n    int[] d = [ 1, 1, 2, 2, 7, 7 ];\n    int[] e = [ 1, 1, 1, 7];\n    assert(equal(setIntersection(a, d), [1, 2, 7]));\n    assert(equal(setIntersection(d, e), [1, 1, 7]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter;\n\n    int[] a = [ 1, 2, 4, 5, 7, 9 ];\n    int[] b = [ 0, 1, 2, 4, 7, 8 ];\n    int[] c = [ 0, 1, 4, 5, 7, 8 ];\n    int[] d = [ 1, 3, 4 ];\n    int[] e = [ 4, 5 ];\n\n    assert(equal(setIntersection(a, a), a));\n    assert(equal(setIntersection(a, a, a), a));\n    assert(equal(setIntersection(a, b), [1, 2, 4, 7]));\n    assert(equal(setIntersection(a, b, c), [1, 4, 7]));\n    assert(equal(setIntersection(a, b, c, d), [1, 4]));\n    assert(equal(setIntersection(a, b, c, d, e), [4]));\n\n    auto inpA = a.filter!(_ => true), inpB = b.filter!(_ => true);\n    auto inpC = c.filter!(_ => true), inpD = d.filter!(_ => true);\n    assert(equal(setIntersection(inpA, inpB, inpC, inpD), [1, 4]));\n\n    assert(equal(setIntersection(a, b, b, a), [1, 2, 4, 7]));\n    assert(equal(setIntersection(a, c, b), [1, 4, 7]));\n    assert(equal(setIntersection(b, a, c), [1, 4, 7]));\n    assert(equal(setIntersection(b, c, a), [1, 4, 7]));\n    assert(equal(setIntersection(c, a, b), [1, 4, 7]));\n    assert(equal(setIntersection(c, b, a), [1, 4, 7]));\n}\n\n/**\nLazily computes the symmetric difference of `r1` and `r2`,\ni.e. the elements that are present in exactly one of `r1` and $(D\nr2). The two ranges are assumed to be sorted by `less`, and the\noutput is also sorted by `less`. The element types of the two\nranges must have a common type.\n\nIf both ranges are sets (without duplicated elements), the resulting\nrange is going to be a set. If at least one of the ranges is a multiset,\nthe number of occurences of an element `x` in the resulting range is `abs(a-b)`\nwhere `a` is the number of occurences of `x` in `r1`, `b` is the number of\noccurences of `x` in `r2`, and `abs` is the absolute value.\n\nIf both arguments are ranges of L-values of the same type then\n`SetSymmetricDifference` will also be a range of L-values of\nthat type.\n\nParams:\n    less = Predicate the given ranges are sorted by.\n    r1 = The first range.\n    r2 = The second range.\n\nReturns:\n    A range of the symmetric difference between `r1` and `r2`.\n\nSee_also: $(LREF setDifference)\n */\nstruct SetSymmetricDifference(alias less = \"a < b\", R1, R2)\nif (isInputRange!(R1) && isInputRange!(R2))\n{\nprivate:\n    R1 r1;\n    R2 r2;\n    //bool usingR2;\n    alias comp = binaryFun!(less);\n\n    void adjustPosition()\n    {\n        while (!r1.empty && !r2.empty)\n        {\n            if (comp(r1.front, r2.front) || comp(r2.front, r1.front))\n            {\n                break;\n            }\n            // equal, pop both\n            r1.popFront();\n            r2.popFront();\n        }\n    }\n\npublic:\n    ///\n    this(R1 r1, R2 r2)\n    {\n        this.r1 = r1;\n        this.r2 = r2;\n        // position to the first element\n        adjustPosition();\n    }\n\n    ///\n    void popFront()\n    {\n        assert(!empty);\n        if (r1.empty) r2.popFront();\n        else if (r2.empty) r1.popFront();\n        else\n        {\n            // neither is empty\n            if (comp(r1.front, r2.front))\n            {\n                r1.popFront();\n            }\n            else\n            {\n                assert(comp(r2.front, r1.front));\n                r2.popFront();\n            }\n        }\n        adjustPosition();\n    }\n\n    ///\n    @property auto ref front()\n    {\n        assert(!empty);\n        immutable chooseR1 = r2.empty || !r1.empty && comp(r1.front, r2.front);\n        assert(chooseR1 || r1.empty || comp(r2.front, r1.front));\n        return chooseR1 ? r1.front : r2.front;\n    }\n\n    static if (isForwardRange!R1 && isForwardRange!R2)\n    {\n        ///\n        @property typeof(this) save()\n        {\n            auto ret = this;\n            ret.r1 = r1.save;\n            ret.r2 = r2.save;\n            return ret;\n        }\n    }\n\n    ///\n    ref auto opSlice() { return this; }\n\n    ///\n    @property bool empty() { return r1.empty && r2.empty; }\n}\n\n/// Ditto\nSetSymmetricDifference!(less, R1, R2)\nsetSymmetricDifference(alias less = \"a < b\", R1, R2)\n(R1 r1, R2 r2)\n{\n    return typeof(return)(r1, r2);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range.primitives : isForwardRange;\n\n    // sets\n    int[] a = [ 1, 2, 4, 5, 7, 9 ];\n    int[] b = [ 0, 1, 2, 4, 7, 8 ];\n    assert(equal(setSymmetricDifference(a, b), [0, 5, 8, 9][]));\n    static assert(isForwardRange!(typeof(setSymmetricDifference(a, b))));\n\n    //mutisets\n    int[] c = [1, 1, 1, 1, 2, 2, 2, 4, 5, 6];\n    int[] d = [1, 1, 2, 2, 2, 2, 4, 7, 9];\n    assert(equal(setSymmetricDifference(c, d), setSymmetricDifference(d, c)));\n    assert(equal(setSymmetricDifference(c, d), [1, 1, 2, 5, 6, 7, 9]));\n}\n\n@safe unittest // Issue 10460\n{\n    import std.algorithm.comparison : equal;\n\n    int[] a = [1, 2];\n    double[] b = [2.0, 3.0];\n    int[] c = [2, 3];\n\n    alias R1 = typeof(setSymmetricDifference(a, b));\n    static assert(is(ElementType!R1 == double));\n    static assert(!hasLvalueElements!R1);\n\n    alias R2 = typeof(setSymmetricDifference(a, c));\n    static assert(is(ElementType!R2 == int));\n    static assert(hasLvalueElements!R2);\n\n    assert(equal(setSymmetricDifference(a, b), [1.0, 3.0]));\n    assert(equal(setSymmetricDifference(a, c), [1, 3]));\n}\n\n/++\nTODO: once SetUnion got deprecated we can provide the usual definition\n(= merge + filter after uniqs)\nSee: https://github.com/dlang/phobos/pull/4249\n/**\nLazily computes the union of two or more ranges `rs`. The ranges\nare assumed to be sorted by `less`. Elements in the output are\nunique. The element types of all ranges must have a common type.\n\nParams:\n    less = Predicate the given ranges are sorted by.\n    rs = The ranges to compute the union for.\n\nReturns:\n    A range containing the unique union of the given ranges.\n\nSee_Also:\n   $(REF merge, std,algorithm,sorting)\n */\nauto setUnion(alias less = \"a < b\", Rs...)\n(Rs rs)\n{\n    import std.algorithm.iteration : uniq;\n    import std.algorithm.sorting : merge;\n    return merge!(less, Rs)(rs).uniq;\n}\n\n///\n@safe pure nothrow unittest\n    ///\n{\n    import std.algorithm.comparison : equal;\n\n    int[] a = [1, 3, 5];\n    int[] b = [2, 3, 4];\n    assert(a.setUnion(b).equal([1, 2, 3, 4, 5]));\n}\n\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[] a = [ 1, 2, 4, 5, 7, 9 ];\n    int[] b = [ 0, 1, 2, 4, 7, 8 ];\n    double[] c = [ 10.5 ];\n\n    assert(equal(setUnion(a, b), [0, 1, 2, 4, 5, 7, 8, 9][]));\n    assert(equal(setUnion(a, c, b),\n                    [0, 1, 2, 4, 5, 7, 8, 9, 10.5][]));\n}\n\n@safe unittest\n{\n    // save\n    import std.range : dropOne;\n    int[] a = [0, 1, 2];\n    int[] b = [0, 3];\n    auto arr = a.setUnion(b);\n    assert(arr.front == 0);\n    assert(arr.save.dropOne.front == 1);\n    assert(arr.front == 0);\n}\n\n@nogc @safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    static immutable a = [1, 3, 5];\n    static immutable b = [2, 4];\n    static immutable r = [1, 2, 3, 4, 5];\n    assert(a.setUnion(b).equal(r));\n}\n\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange;\n    import std.range : iota;\n\n    auto dummyResult1 = [1, 1.5, 2, 3, 4, 5, 5.5, 6, 7, 8, 9, 10];\n    auto dummyResult2 = iota(1, 11);\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType d;\n        assert(d.setUnion([1, 1.5, 5.5]).equal(dummyResult1));\n        assert(d.setUnion(d).equal(dummyResult2));\n    }\n}\n++/\n"
  },
  {
    "path": "libphobos/src/std/algorithm/sorting.d",
    "content": "// Written in the D programming language.\n/**\nThis is a submodule of $(MREF std, algorithm).\nIt contains generic sorting algorithms.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE Cheat Sheet,\n$(TR $(TH Function Name) $(TH Description))\n$(T2 completeSort,\n        If `a = [10, 20, 30]` and `b = [40, 6, 15]`, then\n        `completeSort(a, b)` leaves `a = [6, 10, 15]` and `b = [20, 30, 40]`.\n        The range `a` must be sorted prior to the call, and as a result the\n        combination `$(REF chain, std,range)(a, b)` is sorted.)\n$(T2 isPartitioned,\n        `isPartitioned!\"a < 0\"([-1, -2, 1, 0, 2])` returns `true` because\n        the predicate is `true` for a portion of the range and `false`\n        afterwards.)\n$(T2 isSorted,\n        `isSorted([1, 1, 2, 3])` returns `true`.)\n$(T2 isStrictlyMonotonic,\n        `isStrictlyMonotonic([1, 1, 2, 3])` returns `false`.)\n$(T2 ordered,\n        `ordered(1, 1, 2, 3)` returns `true`.)\n$(T2 strictlyOrdered,\n        `strictlyOrdered(1, 1, 2, 3)` returns `false`.)\n$(T2 makeIndex,\n        Creates a separate index for a range.)\n$(T2 merge,\n        Lazily merges two or more sorted ranges.)\n$(T2 multiSort,\n        Sorts by multiple keys.)\n$(T2 nextEvenPermutation,\n        Computes the next lexicographically greater even permutation of a range\n        in-place.)\n$(T2 nextPermutation,\n        Computes the next lexicographically greater permutation of a range\n        in-place.)\n$(T2 partialSort,\n        If `a = [5, 4, 3, 2, 1]`, then `partialSort(a, 3)` leaves\n        `a[0 .. 3] = [1, 2, 3]`.\n        The other elements of `a` are left in an unspecified order.)\n$(T2 partition,\n        Partitions a range according to a unary predicate.)\n$(T2 partition3,\n        Partitions a range according to a binary predicate in three parts (less\n        than, equal, greater than the given pivot). Pivot is not given as an\n        index, but instead as an element independent from the range's content.)\n$(T2 pivotPartition,\n        Partitions a range according to a binary predicate in two parts: less\n        than or equal, and greater than or equal to the given pivot, passed as\n        an index in the range.)\n$(T2 schwartzSort,\n        Sorts with the help of the $(LINK2 https://en.wikipedia.org/wiki/Schwartzian_transform, Schwartzian transform).)\n$(T2 sort,\n        Sorts.)\n$(T2 topN,\n        Separates the top elements in a range.)\n$(T2 topNCopy,\n        Copies out the top elements of a range.)\n$(T2 topNIndex,\n        Builds an index of the top elements of a range.)\n)\n\nCopyright: Andrei Alexandrescu 2008-.\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n\nSource: $(PHOBOSSRC std/algorithm/sorting.d)\n\nMacros:\nT2=$(TR $(TDNW $(LREF $1)) $(TD $+))\n */\nmodule std.algorithm.sorting;\n\nimport std.algorithm.mutation : SwapStrategy;\nimport std.functional; // : unaryFun, binaryFun;\nimport std.range.primitives;\nimport std.typecons : Flag;\n// FIXME\nimport std.meta; // : allSatisfy;\nimport std.range; // : SortedRange;\nimport std.traits;\n\n/**\nSpecifies whether the output of certain algorithm is desired in sorted\nformat.\n\nIf set to `SortOutput.no`, the output should not be sorted.\n\nOtherwise if set to `SortOutput.yes`, the output should be sorted.\n */\nalias SortOutput = Flag!\"sortOutput\";\n\n// completeSort\n/**\nSorts the random-access range `chain(lhs, rhs)` according to\npredicate `less`. The left-hand side of the range `lhs` is\nassumed to be already sorted; `rhs` is assumed to be unsorted. The\nexact strategy chosen depends on the relative sizes of `lhs` and\n`rhs`.  Performs $(BIGOH lhs.length + rhs.length * log(rhs.length))\n(best case) to $(BIGOH (lhs.length + rhs.length) * log(lhs.length +\nrhs.length)) (worst-case) evaluations of `swap`.\n\nParams:\n    less = The predicate to sort by.\n    ss = The swapping strategy to use.\n    lhs = The sorted, left-hand side of the random access range to be sorted.\n    rhs = The unsorted, right-hand side of the random access range to be\n        sorted.\n*/\nvoid completeSort(alias less = \"a < b\", SwapStrategy ss = SwapStrategy.unstable,\n        Lhs , Rhs)(SortedRange!(Lhs, less) lhs, Rhs rhs)\nif (hasLength!(Rhs) && hasSlicing!(Rhs)\n        && hasSwappableElements!Lhs && hasSwappableElements!Rhs)\n{\n    import std.algorithm.mutation : bringToFront;\n    import std.range : chain, assumeSorted;\n    // Probably this algorithm can be optimized by using in-place\n    // merge\n    auto lhsOriginal = lhs.release();\n    foreach (i; 0 .. rhs.length)\n    {\n        auto sortedSoFar = chain(lhsOriginal, rhs[0 .. i]);\n        auto ub = assumeSorted!less(sortedSoFar).upperBound(rhs[i]);\n        if (!ub.length) continue;\n        bringToFront(ub.release(), rhs[i .. i + 1]);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.range : assumeSorted;\n    int[] a = [ 1, 2, 3 ];\n    int[] b = [ 4, 0, 6, 5 ];\n    completeSort(assumeSorted(a), b);\n    assert(a == [ 0, 1, 2 ]);\n    assert(b == [ 3, 4, 5, 6 ]);\n}\n\n// isSorted\n/**\nChecks whether a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\nis sorted according to the comparison operation `less`. Performs $(BIGOH r.length)\nevaluations of `less`.\n\nUnlike `isSorted`, `isStrictlyMonotonic` does not allow for equal values,\ni.e. values for which both `less(a, b)` and `less(b, a)` are false.\n\nWith either function, the predicate must be a strict ordering just like with\n`isSorted`. For example, using `\"a <= b\"` instead of `\"a < b\"` is\nincorrect and will cause failed assertions.\n\nParams:\n    less = Predicate the range should be sorted by.\n    r = Forward range to check for sortedness.\n\nReturns:\n    `true` if the range is sorted, false otherwise. `isSorted` allows\n    duplicates, `isStrictlyMonotonic` not.\n*/\nbool isSorted(alias less = \"a < b\", Range)(Range r)\nif (isForwardRange!(Range))\n{\n    if (r.empty) return true;\n\n    static if (isRandomAccessRange!Range && hasLength!Range)\n    {\n        immutable limit = r.length - 1;\n        foreach (i; 0 .. limit)\n        {\n            if (!binaryFun!less(r[i + 1], r[i])) continue;\n            assert(\n                !binaryFun!less(r[i], r[i + 1]),\n                \"Predicate for isSorted is not antisymmetric. Both\" ~\n                        \" pred(a, b) and pred(b, a) are true for certain values.\");\n            return false;\n        }\n    }\n    else\n    {\n        auto ahead = r.save;\n        ahead.popFront();\n        size_t i;\n\n        for (; !ahead.empty; ahead.popFront(), r.popFront(), ++i)\n        {\n            if (!binaryFun!less(ahead.front, r.front)) continue;\n            // Check for antisymmetric predicate\n            assert(\n                !binaryFun!less(r.front, ahead.front),\n                \"Predicate for isSorted is not antisymmetric. Both\" ~\n                        \" pred(a, b) and pred(b, a) are true for certain values.\");\n            return false;\n        }\n    }\n    return true;\n}\n\n///\n@safe unittest\n{\n    assert([1, 1, 2].isSorted);\n    // strictly monotonic doesn't allow duplicates\n    assert(![1, 1, 2].isStrictlyMonotonic);\n\n    int[] arr = [4, 3, 2, 1];\n    assert(!isSorted(arr));\n    assert(!isStrictlyMonotonic(arr));\n\n    assert(isSorted!\"a > b\"(arr));\n    assert(isStrictlyMonotonic!\"a > b\"(arr));\n\n    sort(arr);\n    assert(isSorted(arr));\n    assert(isStrictlyMonotonic(arr));\n}\n\n@safe unittest\n{\n    import std.conv : to;\n\n    // Issue 9457\n    auto x = \"abcd\";\n    assert(isSorted(x));\n    auto y = \"acbd\";\n    assert(!isSorted(y));\n\n    int[] a = [1, 2, 3];\n    assert(isSorted(a));\n    int[] b = [1, 3, 2];\n    assert(!isSorted(b));\n\n    // ignores duplicates\n    int[] c = [1, 1, 2];\n    assert(isSorted(c));\n\n    dchar[] ds = \"コーヒーが好きです\"d.dup;\n    sort(ds);\n    string s = to!string(ds);\n    assert(isSorted(ds));  // random-access\n    assert(isSorted(s));   // bidirectional\n}\n\n@nogc @safe nothrow pure unittest\n{\n    static immutable a = [1, 2, 3];\n    assert(a.isSorted);\n}\n\n/// ditto\nbool isStrictlyMonotonic(alias less = \"a < b\", Range)(Range r)\nif (isForwardRange!Range)\n{\n    import std.algorithm.searching : findAdjacent;\n    return findAdjacent!((a,b) => !binaryFun!less(a,b))(r).empty;\n}\n\n@safe unittest\n{\n    import std.conv : to;\n\n    assert(\"abcd\".isStrictlyMonotonic);\n    assert(!\"aacd\".isStrictlyMonotonic);\n    assert(!\"acb\".isStrictlyMonotonic);\n\n    assert([1, 2, 3].isStrictlyMonotonic);\n    assert(![1, 3, 2].isStrictlyMonotonic);\n    assert(![1, 1, 2].isStrictlyMonotonic);\n\n    // ー occurs twice -> can't be strict\n    dchar[] ds = \"コーヒーが好きです\"d.dup;\n    sort(ds);\n    string s = to!string(ds);\n    assert(!isStrictlyMonotonic(ds));  // random-access\n    assert(!isStrictlyMonotonic(s));   // bidirectional\n\n    dchar[] ds2 = \"コーヒが好きです\"d.dup;\n    sort(ds2);\n    string s2 = to!string(ds2);\n    assert(isStrictlyMonotonic(ds2));  // random-access\n    assert(isStrictlyMonotonic(s2));   // bidirectional\n}\n\n@nogc @safe nothrow pure unittest\n{\n    static immutable a = [1, 2, 3];\n    assert(a.isStrictlyMonotonic);\n}\n\n/**\nLike `isSorted`, returns `true` if the given `values` are ordered\naccording to the comparison operation `less`. Unlike `isSorted`, takes values\ndirectly instead of structured in a range.\n\n`ordered` allows repeated values, e.g. `ordered(1, 1, 2)` is `true`. To verify\nthat the values are ordered strictly monotonically, use `strictlyOrdered`;\n`strictlyOrdered(1, 1, 2)` is `false`.\n\nWith either function, the predicate must be a strict ordering. For example,\nusing `\"a <= b\"` instead of `\"a < b\"` is incorrect and will cause failed\nassertions.\n\nParams:\n    values = The tested value\n    less = The comparison predicate\n\nReturns:\n    `true` if the values are ordered; `ordered` allows for duplicates,\n    `strictlyOrdered` does not.\n*/\n\nbool ordered(alias less = \"a < b\", T...)(T values)\nif ((T.length == 2 && is(typeof(binaryFun!less(values[1], values[0])) : bool))\n    ||\n    (T.length > 2 && is(typeof(ordered!less(values[0 .. 1 + $ / 2])))\n        && is(typeof(ordered!less(values[$ / 2 .. $]))))\n    )\n{\n    foreach (i, _; T[0 .. $ - 1])\n    {\n        if (binaryFun!less(values[i + 1], values[i]))\n        {\n            assert(!binaryFun!less(values[i], values[i + 1]),\n                __FUNCTION__ ~ \": incorrect non-strict predicate.\");\n            return false;\n        }\n    }\n    return true;\n}\n\n/// ditto\nbool strictlyOrdered(alias less = \"a < b\", T...)(T values)\nif (is(typeof(ordered!less(values))))\n{\n    foreach (i, _; T[0 .. $ - 1])\n    {\n        if (!binaryFun!less(values[i], values[i + 1]))\n        {\n            return false;\n        }\n        assert(!binaryFun!less(values[i + 1], values[i]),\n            __FUNCTION__ ~ \": incorrect non-strict predicate.\");\n    }\n    return true;\n}\n\n///\n@safe unittest\n{\n    assert(ordered(42, 42, 43));\n    assert(!strictlyOrdered(43, 42, 45));\n    assert(ordered(42, 42, 43));\n    assert(!strictlyOrdered(42, 42, 43));\n    assert(!ordered(43, 42, 45));\n    // Ordered lexicographically\n    assert(ordered(\"Jane\", \"Jim\", \"Joe\"));\n    assert(strictlyOrdered(\"Jane\", \"Jim\", \"Joe\"));\n    // Incidentally also ordered by length decreasing\n    assert(ordered!((a, b) => a.length > b.length)(\"Jane\", \"Jim\", \"Joe\"));\n    // ... but not strictly so: \"Jim\" and \"Joe\" have the same length\n    assert(!strictlyOrdered!((a, b) => a.length > b.length)(\"Jane\", \"Jim\", \"Joe\"));\n}\n\n// partition\n/**\nPartitions a range in two using the given `predicate`.\nSpecifically, reorders the range `r = [left, right$(RPAREN)` using `swap`\nsuch that all elements `i` for which `predicate(i)` is `true` come\nbefore all elements `j` for which `predicate(j)` returns `false`.\n\nPerforms $(BIGOH r.length) (if unstable or semistable) or $(BIGOH\nr.length * log(r.length)) (if stable) evaluations of `less` and $(D\nswap). The unstable version computes the minimum possible evaluations\nof `swap` (roughly half of those performed by the semistable\nversion).\n\nParams:\n    predicate = The predicate to partition by.\n    ss = The swapping strategy to employ.\n    r = The random-access range to partition.\n\nReturns:\n\nThe right part of `r` after partitioning.\n\nIf `ss == SwapStrategy.stable`, `partition` preserves the relative\nordering of all elements `a`, `b` in `r` for which\n`predicate(a) == predicate(b)`.\nIf `ss == SwapStrategy.semistable`, `partition` preserves\nthe relative ordering of all elements `a`, `b` in the left part of `r`\nfor which `predicate(a) == predicate(b)`.\n*/\nRange partition(alias predicate, SwapStrategy ss, Range)(Range r)\nif (ss == SwapStrategy.stable && isRandomAccessRange!(Range) && hasLength!Range &&\n        hasSlicing!Range && hasSwappableElements!Range)\n{\n    import std.algorithm.mutation : bringToFront;\n\n    alias pred = unaryFun!(predicate);\n    if (r.empty) return r;\n\n    if (r.length == 1)\n    {\n        if (pred(r.front)) r.popFront();\n        return r;\n    }\n    const middle = r.length / 2;\n    alias recurse = .partition!(pred, ss, Range);\n    auto lower = recurse(r[0 .. middle]);\n    auto upper = recurse(r[middle .. r.length]);\n    bringToFront(lower, r[middle .. r.length - upper.length]);\n    return r[r.length - lower.length - upper.length .. r.length];\n}\n\n///ditto\nRange partition(alias predicate, SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)\nif (ss != SwapStrategy.stable && isInputRange!Range && hasSwappableElements!Range)\n{\n    import std.algorithm.mutation : swap;\n    alias pred = unaryFun!(predicate);\n\n    static if (ss == SwapStrategy.semistable)\n    {\n        if (r.empty) return r;\n\n        for (; !r.empty; r.popFront())\n        {\n            // skip the initial portion of \"correct\" elements\n            if (pred(r.front)) continue;\n            // hit the first \"bad\" element\n            auto result = r;\n            for (r.popFront(); !r.empty; r.popFront())\n            {\n                if (!pred(r.front)) continue;\n                swap(result.front, r.front);\n                result.popFront();\n            }\n            return result;\n        }\n\n        return r;\n    }\n    else\n    {\n        // Inspired from www.stepanovpapers.com/PAM3-partition_notes.pdf,\n        // section \"Bidirectional Partition Algorithm (Hoare)\"\n        static if (isDynamicArray!Range)\n        {\n            import std.algorithm.mutation : swapAt;\n            // For dynamic arrays prefer index-based manipulation\n            if (!r.length) return r;\n            size_t lo = 0, hi = r.length - 1;\n            for (;;)\n            {\n                for (;;)\n                {\n                    if (lo > hi) return r[lo .. r.length];\n                    if (!pred(r[lo])) break;\n                    ++lo;\n                }\n                // found the left bound\n                assert(lo <= hi);\n                for (;;)\n                {\n                    if (lo == hi) return r[lo .. r.length];\n                    if (pred(r[hi])) break;\n                    --hi;\n                }\n                // found the right bound, swap & make progress\n                r.swapAt(lo++, hi--);\n            }\n        }\n        else\n        {\n            import std.algorithm.mutation : swap;\n            auto result = r;\n            for (;;)\n            {\n                for (;;)\n                {\n                    if (r.empty) return result;\n                    if (!pred(r.front)) break;\n                    r.popFront();\n                    result.popFront();\n                }\n                // found the left bound\n                assert(!r.empty);\n                for (;;)\n                {\n                    if (pred(r.back)) break;\n                    r.popBack();\n                    if (r.empty) return result;\n                }\n                // found the right bound, swap & make progress\n                static if (is(typeof(swap(r.front, r.back))))\n                {\n                    swap(r.front, r.back);\n                }\n                else\n                {\n                    auto t1 = r.moveFront(), t2 = r.moveBack();\n                    r.front = t2;\n                    r.back = t1;\n                }\n                r.popFront();\n                result.popFront();\n                r.popBack();\n            }\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.mutation : SwapStrategy;\n    import std.algorithm.searching : count, find;\n    import std.conv : text;\n    import std.range.primitives : empty;\n\n    auto Arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    auto arr = Arr.dup;\n    static bool even(int a) { return (a & 1) == 0; }\n    // Partition arr such that even numbers come first\n    auto r = partition!(even)(arr);\n    // Now arr is separated in evens and odds.\n    // Numbers may have become shuffled due to instability\n    assert(r == arr[5 .. $]);\n    assert(count!(even)(arr[0 .. 5]) == 5);\n    assert(find!(even)(r).empty);\n\n    // Can also specify the predicate as a string.\n    // Use 'a' as the predicate argument name\n    arr[] = Arr[];\n    r = partition!(q{(a & 1) == 0})(arr);\n    assert(r == arr[5 .. $]);\n\n    // Now for a stable partition:\n    arr[] = Arr[];\n    r = partition!(q{(a & 1) == 0}, SwapStrategy.stable)(arr);\n    // Now arr is [2 4 6 8 10 1 3 5 7 9], and r points to 1\n    assert(arr == [2, 4, 6, 8, 10, 1, 3, 5, 7, 9] && r == arr[5 .. $]);\n\n    // In case the predicate needs to hold its own state, use a delegate:\n    arr[] = Arr[];\n    int x = 3;\n    // Put stuff greater than 3 on the left\n    bool fun(int a) { return a > x; }\n    r = partition!(fun, SwapStrategy.semistable)(arr);\n    // Now arr is [4 5 6 7 8 9 10 2 3 1] and r points to 2\n    assert(arr == [4, 5, 6, 7, 8, 9, 10, 2, 3, 1] && r == arr[7 .. $]);\n}\n\n@safe unittest\n{\n    import std.algorithm.internal : rndstuff;\n    static bool even(int a) { return (a & 1) == 0; }\n\n    // test with random data\n    auto a = rndstuff!int();\n    partition!even(a);\n    assert(isPartitioned!even(a));\n    auto b = rndstuff!string();\n    partition!`a.length < 5`(b);\n    assert(isPartitioned!`a.length < 5`(b));\n}\n\n// pivotPartition\n/**\n\nPartitions `r` around `pivot` using comparison function `less`, algorithm akin\nto $(LINK2 https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme,\nHoare partition). Specifically, permutes elements of `r` and returns\nan index `k < r.length` such that:\n\n$(UL\n\n$(LI `r[pivot]` is swapped to `r[k]`)\n\n$(LI All elements `e` in subrange `r[0 .. k]` satisfy `!less(r[k], e)`\n(i.e. `r[k]` is greater than or equal to each element to its left according to\npredicate `less`))\n\n$(LI All elements `e` in subrange `r[k .. $]` satisfy `!less(e, r[k])`\n(i.e. `r[k]` is less than or equal to each element to its right\naccording to predicate `less`)))\n\nIf `r` contains equivalent elements, multiple permutations of `r` satisfy these\nconstraints. In such cases, `pivotPartition` attempts to distribute equivalent\nelements fairly to the left and right of `k` such that `k` stays close to  $(D\nr.length / 2).\n\nParams:\nless = The predicate used for comparison, modeled as a\n        $(LINK2 https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings,\n        strict weak ordering) (irreflexive, antisymmetric, transitive, and implying a transitive\n        equivalence)\nr = The range being partitioned\npivot = The index of the pivot for partitioning, must be less than `r.length` or\n`0` is `r.length` is `0`\n\nReturns:\nThe new position of the pivot\n\nSee_Also:\n$(HTTP jgrcs.info/index.php/jgrcs/article/view/142, Engineering of a Quicksort\nPartitioning Algorithm), D. Abhyankar, Journal of Global Research in Computer\nScience, February 2011. $(HTTPS youtube.com/watch?v=AxnotgLql0k, ACCU 2016\nKeynote), Andrei Alexandrescu.\n*/\nsize_t pivotPartition(alias less = \"a < b\", Range)\n(Range r, size_t pivot)\nif (isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && hasAssignableElements!Range)\n{\n    assert(pivot < r.length || r.length == 0 && pivot == 0);\n    if (r.length <= 1) return 0;\n    import std.algorithm.mutation : swapAt, move;\n    alias lt = binaryFun!less;\n\n    // Pivot at the front\n    r.swapAt(pivot, 0);\n\n    // Fork implementation depending on nothrow copy, assignment, and\n    // comparison. If all of these are nothrow, use the specialized\n    // implementation discussed at https://youtube.com/watch?v=AxnotgLql0k.\n    static if (is(typeof(\n            () nothrow { auto x = r.front; x = r.front; return lt(x, x); }\n        )))\n    {\n        auto p = r[0];\n        // Plant the pivot in the end as well as a sentinel\n        size_t lo = 0, hi = r.length - 1;\n        auto save = r.moveAt(hi);\n        r[hi] = p; // Vacancy is in r[$ - 1] now\n        // Start process\n        for (;;)\n        {\n            // Loop invariant\n            version (unittest)\n            {\n                // this used to import std.algorithm.all, but we want to save\n                // imports when unittests are enabled if possible.\n                foreach (x; r[0 .. lo])\n                    assert(!lt(p, x));\n                foreach (x; r[hi+1 .. r.length])\n                    assert(!lt(x, p));\n            }\n            do ++lo; while (lt(r[lo], p));\n            r[hi] = r[lo];\n            // Vacancy is now in r[lo]\n            do --hi; while (lt(p, r[hi]));\n            if (lo >= hi) break;\n            r[lo] = r[hi];\n            // Vacancy is not in r[hi]\n        }\n        // Fixup\n        assert(lo - hi <= 2);\n        assert(!lt(p, r[hi]));\n        if (lo == hi + 2)\n        {\n            assert(!lt(r[hi + 1], p));\n            r[lo] = r[hi + 1];\n            --lo;\n        }\n        r[lo] = save;\n        if (lt(p, save)) --lo;\n        assert(!lt(p, r[lo]));\n    }\n    else\n    {\n        size_t lo = 1, hi = r.length - 1;\n        loop: for (;; lo++, hi--)\n        {\n            for (;; ++lo)\n            {\n                if (lo > hi) break loop;\n                if (!lt(r[lo], r[0])) break;\n            }\n            // found the left bound:  r[lo] >= r[0]\n            assert(lo <= hi);\n            for (;; --hi)\n            {\n                if (lo >= hi) break loop;\n                if (!lt(r[0], r[hi])) break;\n            }\n            // found the right bound: r[hi] <= r[0], swap & make progress\n            assert(!lt(r[lo], r[hi]));\n            r.swapAt(lo, hi);\n        }\n        --lo;\n    }\n    r.swapAt(lo, 0);\n    return lo;\n}\n\n///\n@safe nothrow unittest\n{\n    int[] a = [5, 3, 2, 6, 4, 1, 3, 7];\n    size_t pivot = pivotPartition(a, a.length / 2);\n    import std.algorithm.searching : all;\n    assert(a[0 .. pivot].all!(x => x <= a[pivot]));\n    assert(a[pivot .. $].all!(x => x >= a[pivot]));\n}\n\n@safe unittest\n{\n    void test(alias less)()\n    {\n        int[] a;\n        size_t pivot;\n\n        a = [-9, -4, -2, -2, 9];\n        pivot = pivotPartition!less(a, a.length / 2);\n        import std.algorithm.searching : all;\n        assert(a[0 .. pivot].all!(x => x <= a[pivot]));\n        assert(a[pivot .. $].all!(x => x >= a[pivot]));\n\n        a = [9, 2, 8, -5, 5, 4, -8, -4, 9];\n        pivot = pivotPartition!less(a, a.length / 2);\n        assert(a[0 .. pivot].all!(x => x <= a[pivot]));\n        assert(a[pivot .. $].all!(x => x >= a[pivot]));\n\n        a = [ 42 ];\n        pivot = pivotPartition!less(a, a.length / 2);\n        assert(pivot == 0);\n        assert(a == [ 42 ]);\n\n        a = [ 43, 42 ];\n        pivot = pivotPartition!less(a, 0);\n        assert(pivot == 1);\n        assert(a == [ 42, 43 ]);\n\n        a = [ 43, 42 ];\n        pivot = pivotPartition!less(a, 1);\n        assert(pivot == 0);\n        assert(a == [ 42, 43 ]);\n\n        a = [ 42, 42 ];\n        pivot = pivotPartition!less(a, 0);\n        assert(pivot == 0 || pivot == 1);\n        assert(a == [ 42, 42 ]);\n        pivot = pivotPartition!less(a, 1);\n        assert(pivot == 0 || pivot == 1);\n        assert(a == [ 42, 42 ]);\n\n        import std.algorithm.iteration : map;\n        import std.format : format;\n        import std.random;\n        auto s = 123_456_789;\n        auto g = Xorshift(s);\n        a = iota(0, uniform(1, 1000, g))\n            .map!(_ => uniform(-1000, 1000, g))\n            .array;\n        pivot = pivotPartition!less(a, a.length / 2);\n        assert(a[0 .. pivot].all!(x => x <= a[pivot]), \"RNG seed: %d\".format(s));\n        assert(a[pivot .. $].all!(x => x >= a[pivot]), \"RNG seed: %d\".format(s));\n    }\n    test!\"a < b\";\n    static bool myLess(int a, int b)\n    {\n        static bool bogus;\n        if (bogus) throw new Exception(\"\"); // just to make it no-nothrow\n        return a < b;\n    }\n    test!myLess;\n}\n\n/**\nParams:\n    pred = The predicate that the range should be partitioned by.\n    r = The range to check.\nReturns: `true` if `r` is partitioned according to predicate `pred`.\n */\nbool isPartitioned(alias pred, Range)(Range r)\nif (isForwardRange!(Range))\n{\n    for (; !r.empty; r.popFront())\n    {\n        if (unaryFun!(pred)(r.front)) continue;\n        for (r.popFront(); !r.empty; r.popFront())\n        {\n            if (unaryFun!(pred)(r.front)) return false;\n        }\n        break;\n    }\n    return true;\n}\n\n///\n@safe unittest\n{\n    int[] r = [ 1, 3, 5, 7, 8, 2, 4, ];\n    assert(isPartitioned!\"a & 1\"(r));\n}\n\n// partition3\n/**\nRearranges elements in `r` in three adjacent ranges and returns\nthem. The first and leftmost range only contains elements in `r`\nless than `pivot`. The second and middle range only contains\nelements in `r` that are equal to `pivot`. Finally, the third\nand rightmost range only contains elements in `r` that are greater\nthan `pivot`. The less-than test is defined by the binary function\n`less`.\n\nParams:\n    less = The predicate to use for the rearrangement.\n    ss = The swapping strategy to use.\n    r = The random-access range to rearrange.\n    pivot = The pivot element.\n\nReturns:\n    A $(REF Tuple, std,typecons) of the three resulting ranges. These ranges are\n    slices of the original range.\n\nBUGS: stable `partition3` has not been implemented yet.\n */\nauto partition3(alias less = \"a < b\", SwapStrategy ss = SwapStrategy.unstable, Range, E)\n(Range r, E pivot)\nif (ss == SwapStrategy.unstable && isRandomAccessRange!Range\n        && hasSwappableElements!Range && hasLength!Range && hasSlicing!Range\n        && is(typeof(binaryFun!less(r.front, pivot)) == bool)\n        && is(typeof(binaryFun!less(pivot, r.front)) == bool)\n        && is(typeof(binaryFun!less(r.front, r.front)) == bool))\n{\n    // The algorithm is described in \"Engineering a sort function\" by\n    // Jon Bentley et al, pp 1257.\n\n    import std.algorithm.comparison : min;\n    import std.algorithm.mutation : swap, swapAt, swapRanges;\n    import std.typecons : tuple;\n\n    alias lessFun = binaryFun!less;\n    size_t i, j, k = r.length, l = k;\n\n bigloop:\n    for (;;)\n    {\n        for (;; ++j)\n        {\n            if (j == k) break bigloop;\n            assert(j < r.length);\n            if (lessFun(r[j], pivot)) continue;\n            if (lessFun(pivot, r[j])) break;\n            r.swapAt(i++, j);\n        }\n        assert(j < k);\n        for (;;)\n        {\n            assert(k > 0);\n            if (!lessFun(pivot, r[--k]))\n            {\n                if (lessFun(r[k], pivot)) break;\n                r.swapAt(k, --l);\n            }\n            if (j == k) break bigloop;\n        }\n        // Here we know r[j] > pivot && r[k] < pivot\n        r.swapAt(j++, k);\n    }\n\n    // Swap the equal ranges from the extremes into the middle\n    auto strictlyLess = j - i, strictlyGreater = l - k;\n    auto swapLen = min(i, strictlyLess);\n    swapRanges(r[0 .. swapLen], r[j - swapLen .. j]);\n    swapLen = min(r.length - l, strictlyGreater);\n    swapRanges(r[k .. k + swapLen], r[r.length - swapLen .. r.length]);\n    return tuple(r[0 .. strictlyLess],\n            r[strictlyLess .. r.length - strictlyGreater],\n            r[r.length - strictlyGreater .. r.length]);\n}\n\n///\n@safe unittest\n{\n    auto a = [ 8, 3, 4, 1, 4, 7, 4 ];\n    auto pieces = partition3(a, 4);\n    assert(pieces[0] == [ 1, 3 ]);\n    assert(pieces[1] == [ 4, 4, 4 ]);\n    assert(pieces[2] == [ 8, 7 ]);\n}\n\n@safe unittest\n{\n    import std.random : Random = Xorshift, uniform;\n\n    immutable uint[] seeds = [3923355730, 1927035882];\n    foreach (s; seeds)\n    {\n        auto r = Random(s);\n        auto a = new int[](uniform(0, 100, r));\n        foreach (ref e; a)\n        {\n            e = uniform(0, 50, r);\n        }\n        auto pieces = partition3(a, 25);\n        assert(pieces[0].length + pieces[1].length + pieces[2].length == a.length);\n        foreach (e; pieces[0])\n        {\n            assert(e < 25);\n        }\n        foreach (e; pieces[1])\n        {\n            assert(e == 25);\n        }\n        foreach (e; pieces[2])\n        {\n            assert(e > 25);\n        }\n    }\n}\n\n// makeIndex\n/**\nComputes an index for `r` based on the comparison `less`. The\nindex is a sorted array of pointers or indices into the original\nrange. This technique is similar to sorting, but it is more flexible\nbecause (1) it allows \"sorting\" of immutable collections, (2) allows\nbinary search even if the original collection does not offer random\naccess, (3) allows multiple indexes, each on a different predicate,\nand (4) may be faster when dealing with large objects. However, using\nan index may also be slower under certain circumstances due to the\nextra indirection, and is always larger than a sorting-based solution\nbecause it needs space for the index in addition to the original\ncollection. The complexity is the same as `sort`'s.\n\nThe first overload of `makeIndex` writes to a range containing\npointers, and the second writes to a range containing offsets. The\nfirst overload requires `Range` to be a\n$(REF_ALTTEXT forward range, isForwardRange, std,range,primitives), and the\nlatter requires it to be a random-access range.\n\n`makeIndex` overwrites its second argument with the result, but\nnever reallocates it.\n\nParams:\n    less = The comparison to use.\n    ss = The swapping strategy.\n    r = The range to index.\n    index = The resulting index.\n\nReturns: The pointer-based version returns a `SortedRange` wrapper\nover index, of type\n`SortedRange!(RangeIndex, (a, b) => binaryFun!less(*a, *b))`\nthus reflecting the ordering of the\nindex. The index-based version returns `void` because the ordering\nrelation involves not only `index` but also `r`.\n\nThrows: If the second argument's length is less than that of the range\nindexed, an exception is thrown.\n*/\nSortedRange!(RangeIndex, (a, b) => binaryFun!less(*a, *b))\nmakeIndex(\n    alias less = \"a < b\",\n    SwapStrategy ss = SwapStrategy.unstable,\n    Range,\n    RangeIndex)\n(Range r, RangeIndex index)\nif (isForwardRange!(Range) && isRandomAccessRange!(RangeIndex)\n    && is(ElementType!(RangeIndex) : ElementType!(Range)*) && hasAssignableElements!RangeIndex)\n{\n    import std.algorithm.internal : addressOf;\n    import std.exception : enforce;\n\n    // assume collection already ordered\n    size_t i;\n    for (; !r.empty; r.popFront(), ++i)\n        index[i] = addressOf(r.front);\n    enforce(index.length == i);\n    // sort the index\n    sort!((a, b) => binaryFun!less(*a, *b), ss)(index);\n    return typeof(return)(index);\n}\n\n/// Ditto\nvoid makeIndex(\n    alias less = \"a < b\",\n    SwapStrategy ss = SwapStrategy.unstable,\n    Range,\n    RangeIndex)\n(Range r, RangeIndex index)\nif (isRandomAccessRange!Range && !isInfinite!Range &&\n    isRandomAccessRange!RangeIndex && !isInfinite!RangeIndex &&\n    isIntegral!(ElementType!RangeIndex) && hasAssignableElements!RangeIndex)\n{\n    import std.conv : to;\n    import std.exception : enforce;\n\n    alias IndexType = Unqual!(ElementType!RangeIndex);\n    enforce(r.length == index.length,\n        \"r and index must be same length for makeIndex.\");\n    static if (IndexType.sizeof < size_t.sizeof)\n    {\n        enforce(r.length <= size_t(1) + IndexType.max, \"Cannot create an index with \" ~\n            \"element type \" ~ IndexType.stringof ~ \" with length \" ~\n            to!string(r.length) ~ \".\");\n    }\n\n    // Use size_t as loop index to avoid overflow on ++i,\n    // e.g. when squeezing 256 elements into a ubyte index.\n    foreach (size_t i; 0 .. r.length)\n        index[i] = cast(IndexType) i;\n\n    // sort the index\n    sort!((a, b) => binaryFun!less(r[cast(size_t) a], r[cast(size_t) b]), ss)\n      (index);\n}\n\n///\n@system unittest\n{\n    immutable(int[]) arr = [ 2, 3, 1, 5, 0 ];\n    // index using pointers\n    auto index1 = new immutable(int)*[arr.length];\n    makeIndex!(\"a < b\")(arr, index1);\n    assert(isSorted!(\"*a < *b\")(index1));\n    // index using offsets\n    auto index2 = new size_t[arr.length];\n    makeIndex!(\"a < b\")(arr, index2);\n    assert(isSorted!\n        ((size_t a, size_t b){ return arr[a] < arr[b];})\n        (index2));\n}\n\n@system unittest\n{\n    immutable(int)[] arr = [ 2, 3, 1, 5, 0 ];\n    // index using pointers\n    auto index1 = new immutable(int)*[arr.length];\n    alias ImmRange = typeof(arr);\n    alias ImmIndex = typeof(index1);\n    static assert(isForwardRange!(ImmRange));\n    static assert(isRandomAccessRange!(ImmIndex));\n    static assert(!isIntegral!(ElementType!(ImmIndex)));\n    static assert(is(ElementType!(ImmIndex) : ElementType!(ImmRange)*));\n    makeIndex!(\"a < b\")(arr, index1);\n    assert(isSorted!(\"*a < *b\")(index1));\n\n    // index using offsets\n    auto index2 = new long[arr.length];\n    makeIndex(arr, index2);\n    assert(isSorted!\n            ((long a, long b){\n                return arr[cast(size_t) a] < arr[cast(size_t) b];\n            })(index2));\n\n    // index strings using offsets\n    string[] arr1 = [\"I\", \"have\", \"no\", \"chocolate\"];\n    auto index3 = new byte[arr1.length];\n    makeIndex(arr1, index3);\n    assert(isSorted!\n            ((byte a, byte b){ return arr1[a] < arr1[b];})\n            (index3));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    ubyte[256] index = void;\n    iota(256).makeIndex(index[]);\n    assert(index[].equal(iota(256)));\n    byte[128] sindex = void;\n    iota(128).makeIndex(sindex[]);\n    assert(sindex[].equal(iota(128)));\n\n    auto index2 = new uint[10];\n    10.iota.makeIndex(index2);\n    assert(index2.equal(10.iota));\n}\n\nstruct Merge(alias less = \"a < b\", Rs...)\nif (Rs.length >= 2 &&\n    allSatisfy!(isInputRange, Rs) &&\n    !is(CommonType!(staticMap!(ElementType, Rs)) == void))\n{\n    public Rs source;\n    private size_t _lastFrontIndex = size_t.max;\n    static if (isBidirectional)\n    {\n        private size_t _lastBackIndex = size_t.max; // `size_t.max` means uninitialized,\n    }\n\n    import std.functional : binaryFun;\n    import std.traits : isCopyable;\n    import std.typetuple : anySatisfy;\n\n    private alias comp = binaryFun!less;\n    private alias ElementType = CommonType!(staticMap!(.ElementType, Rs));\n    private enum isBidirectional = allSatisfy!(isBidirectionalRange, staticMap!(Unqual, Rs));\n\n    debug private enum canCheckSortedness = isCopyable!ElementType && !hasAliasing!ElementType;\n\n    this(Rs source)\n    {\n        this.source = source;\n        this._lastFrontIndex = frontIndex;\n    }\n\n    static if (anySatisfy!(isInfinite, Rs))\n    {\n        enum bool empty = false; // propagate infiniteness\n    }\n    else\n    {\n        @property bool empty()\n        {\n            return _lastFrontIndex == size_t.max;\n        }\n    }\n\n    @property auto ref front()\n    {\n        final switch (_lastFrontIndex)\n        {\n            foreach (i, _; Rs)\n            {\n            case i:\n                assert(!source[i].empty);\n                return source[i].front;\n            }\n        }\n    }\n\n    private size_t frontIndex()\n    {\n        size_t bestIndex = size_t.max; // indicate undefined\n        Unqual!ElementType bestElement;\n        foreach (i, _; Rs)\n        {\n            if (source[i].empty) continue;\n            if (bestIndex == size_t.max || // either this is the first or\n                comp(source[i].front, bestElement))\n            {\n                bestIndex = i;\n                bestElement = source[i].front;\n            }\n        }\n        return bestIndex;\n    }\n\n    void popFront()\n    {\n        sw: final switch (_lastFrontIndex)\n        {\n            foreach (i, R; Rs)\n            {\n            case i:\n                debug static if (canCheckSortedness)\n                {\n                    ElementType previousFront = source[i].front();\n                }\n                source[i].popFront();\n                debug static if (canCheckSortedness)\n                {\n                    if (!source[i].empty)\n                    {\n                        assert(previousFront == source[i].front ||\n                               comp(previousFront, source[i].front),\n                               \"Input \" ~ i.stringof ~ \" is unsorted\"); // @nogc\n                    }\n                }\n                break sw;\n            }\n        }\n        _lastFrontIndex = frontIndex;\n    }\n\n    static if (isBidirectional)\n    {\n        @property auto ref back()\n        {\n            if (_lastBackIndex == size_t.max)\n            {\n                this._lastBackIndex = backIndex; // lazy initialization\n            }\n            final switch (_lastBackIndex)\n            {\n                foreach (i, _; Rs)\n                {\n                case i:\n                    assert(!source[i].empty);\n                    return source[i].back;\n                }\n            }\n        }\n\n        private size_t backIndex()\n        {\n            size_t bestIndex = size_t.max; // indicate undefined\n            Unqual!ElementType bestElement;\n            foreach (i, _; Rs)\n            {\n                if (source[i].empty) continue;\n                if (bestIndex == size_t.max || // either this is the first or\n                    comp(bestElement, source[i].back))\n                {\n                    bestIndex = i;\n                    bestElement = source[i].back;\n                }\n            }\n            return bestIndex;\n        }\n\n        void popBack()\n        {\n            if (_lastBackIndex == size_t.max)\n            {\n                this._lastBackIndex = backIndex; // lazy initialization\n            }\n            sw: final switch (_lastBackIndex)\n            {\n                foreach (i, R; Rs)\n                {\n                case i:\n                    debug static if (canCheckSortedness)\n                    {\n                        ElementType previousBack = source[i].back();\n                    }\n                    source[i].popBack();\n                    debug static if (canCheckSortedness)\n                    {\n                        if (!source[i].empty)\n                        {\n                            assert(previousBack == source[i].back ||\n                                   comp(source[i].back, previousBack),\n                                   \"Input \" ~ i.stringof ~ \" is unsorted\"); // @nogc\n                        }\n                    }\n                    break sw;\n                }\n            }\n            _lastBackIndex = backIndex;\n            if (_lastBackIndex == size_t.max) // if emptied\n            {\n                _lastFrontIndex = size_t.max;\n            }\n        }\n    }\n\n    static if (allSatisfy!(isForwardRange, staticMap!(Unqual, Rs)))\n    {\n        @property auto save()\n        {\n            auto result = this;\n            foreach (i, _; Rs)\n            {\n                result.source[i] = result.source[i].save;\n            }\n            return result;\n        }\n    }\n\n    static if (allSatisfy!(hasLength, Rs))\n    {\n        @property size_t length()\n        {\n            size_t result;\n            foreach (i, _; Rs)\n            {\n                result += source[i].length;\n            }\n            return result;\n        }\n\n        alias opDollar = length;\n    }\n}\n\n/**\n   Merge multiple sorted ranges `rs` with less-than predicate function `pred`\n   into one single sorted output range containing the sorted union of the\n   elements of inputs. Duplicates are not eliminated, meaning that the total\n   number of elements in the output is the sum of all elements in the ranges\n   passed to it; the `length` member is offered if all inputs also have\n   `length`. The element types of all the inputs must have a common type\n   `CommonType`.\n\nParams:\n    less = Predicate the given ranges are sorted by.\n    rs = The ranges to compute the union for.\n\nReturns:\n    A range containing the union of the given ranges.\n\nDetails:\n\nAll of its inputs are assumed to be sorted. This can mean that inputs are\n   instances of $(REF SortedRange, std,range). Use the result of $(REF sort,\n   std,algorithm,sorting), or $(REF assumeSorted, std,range) to merge ranges\n   known to be sorted (show in the example below). Note that there is currently\n   no way of ensuring that two or more instances of $(REF SortedRange,\n   std,range) are sorted using a specific comparison function `pred`. Therefore\n   no checking is done here to assure that all inputs `rs` are instances of\n   $(REF SortedRange, std,range).\n\n   This algorithm is lazy, doing work progressively as elements are pulled off\n   the result.\n\n   Time complexity is proportional to the sum of element counts over all inputs.\n\n   If all inputs have the same element type and offer it by `ref`, output\n   becomes a range with mutable `front` (and `back` where appropriate) that\n   reflects in the original inputs.\n\n   If any of the inputs `rs` is infinite so is the result (`empty` being always\n   `false`).\n*/\nMerge!(less, Rs) merge(alias less = \"a < b\", Rs...)(Rs rs)\nif (Rs.length >= 2 &&\n    allSatisfy!(isInputRange, Rs) &&\n    !is(CommonType!(staticMap!(ElementType, Rs)) == void))\n{\n    return typeof(return)(rs);\n}\n\n///\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : retro;\n\n    int[] a = [1, 3, 5];\n    int[] b = [2, 3, 4];\n\n    assert(a.merge(b).equal([1, 2, 3, 3, 4, 5]));\n    assert(a.merge(b).retro.equal([5, 4, 3, 3, 2, 1]));\n}\n\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[] a = [ 1, 2, 4, 5, 7, 9 ];\n    int[] b = [ 0, 1, 2, 4, 7, 8 ];\n    double[] c = [ 10.5 ];\n\n    assert(merge(a, b).length == a.length + b.length);\n    assert(equal(merge(a, b), [0, 1, 1, 2, 2, 4, 4, 5, 7, 7, 8, 9][]));\n    assert(equal(merge(a, c, b),\n                    [0, 1, 1, 2, 2, 4, 4, 5, 7, 7, 8, 9, 10.5][]));\n    auto u = merge(a, b);\n    u.front--;\n    assert(equal(u, [-1, 1, 1, 2, 2, 4, 4, 5, 7, 7, 8, 9][]));\n}\n\n@safe pure nothrow unittest\n{\n    // save\n    import std.range : dropOne;\n    int[] a = [1, 2];\n    int[] b = [0, 3];\n    auto arr = a.merge(b);\n    assert(arr.front == 0);\n    assert(arr.save.dropOne.front == 1);\n    assert(arr.front == 0);\n}\n\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange;\n\n    auto dummyResult1 = [1, 1, 1.5, 2, 3, 4, 5, 5.5, 6, 7, 8, 9, 10];\n    auto dummyResult2 = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5,\n                         6, 6, 7, 7, 8, 8, 9, 9, 10, 10];\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType d;\n        assert(d.merge([1, 1.5, 5.5]).equal(dummyResult1));\n        assert(d.merge(d).equal(dummyResult2));\n    }\n}\n\n@nogc @safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    static immutable a = [1, 3, 5];\n    static immutable b = [2, 3, 4];\n    static immutable r = [1, 2, 3, 3, 4, 5];\n    assert(a.merge(b).equal(r));\n}\n\n/// test bi-directional access and common type\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : retro;\n    import std.traits : CommonType;\n\n    alias S = short;\n    alias I = int;\n    alias D = double;\n\n    S[] a = [1, 2, 3];\n    I[] b = [50, 60];\n    D[] c = [10, 20, 30, 40];\n\n    auto m = merge(a, b, c);\n\n    static assert(is(typeof(m.front) == CommonType!(S, I, D)));\n\n    assert(equal(m, [1, 2, 3, 10, 20, 30, 40, 50, 60]));\n    assert(equal(m.retro, [60, 50, 40, 30, 20, 10, 3, 2, 1]));\n\n    m.popFront();\n    assert(equal(m, [2, 3, 10, 20, 30, 40, 50, 60]));\n    m.popBack();\n    assert(equal(m, [2, 3, 10, 20, 30, 40, 50]));\n    m.popFront();\n    assert(equal(m, [3, 10, 20, 30, 40, 50]));\n    m.popBack();\n    assert(equal(m, [3, 10, 20, 30, 40]));\n    m.popFront();\n    assert(equal(m, [10, 20, 30, 40]));\n    m.popBack();\n    assert(equal(m, [10, 20, 30]));\n    m.popFront();\n    assert(equal(m, [20, 30]));\n    m.popBack();\n    assert(equal(m, [20]));\n    m.popFront();\n    assert(m.empty);\n}\n\nprivate template validPredicates(E, less...)\n{\n    static if (less.length == 0)\n        enum validPredicates = true;\n    else static if (less.length == 1 && is(typeof(less[0]) == SwapStrategy))\n        enum validPredicates = true;\n    else\n        enum validPredicates =\n            is(typeof((E a, E b){ bool r = binaryFun!(less[0])(a, b); }))\n            && validPredicates!(E, less[1 .. $]);\n}\n\n/**\nSorts a range by multiple keys. The call $(D multiSort!(\"a.id < b.id\",\n\"a.date > b.date\")(r)) sorts the range `r` by `id` ascending,\nand sorts elements that have the same `id` by `date`\ndescending. Such a call is equivalent to $(D sort!\"a.id != b.id ? a.id\n< b.id : a.date > b.date\"(r)), but `multiSort` is faster because it\ndoes fewer comparisons (in addition to being more convenient).\n\nReturns:\n    The initial range wrapped as a `SortedRange` with its predicates\n    converted to an equivalent single predicate.\n */\ntemplate multiSort(less...) //if (less.length > 1)\n{\n    auto multiSort(Range)(Range r)\n    if (validPredicates!(ElementType!Range, less) && hasSwappableElements!Range)\n    {\n        import std.meta : AliasSeq;\n        import std.range : assumeSorted;\n        static if (is(typeof(less[$ - 1]) == SwapStrategy))\n        {\n            enum ss = less[$ - 1];\n            alias funs = less[0 .. $ - 1];\n        }\n        else\n        {\n            enum ss = SwapStrategy.unstable;\n            alias funs = less;\n        }\n\n        static if (funs.length == 0)\n            static assert(false, \"No sorting predicate provided for multiSort\");\n        else\n        static if (funs.length == 1)\n            return sort!(funs[0], ss, Range)(r);\n        else\n        {\n            multiSortImpl!(Range, ss, funs)(r);\n            return assumeSorted!(multiSortPredFun!(Range, funs))(r);\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.mutation : SwapStrategy;\n    static struct Point { int x, y; }\n    auto pts1 = [ Point(0, 0), Point(5, 5), Point(0, 1), Point(0, 2) ];\n    auto pts2 = [ Point(0, 0), Point(0, 1), Point(0, 2), Point(5, 5) ];\n    multiSort!(\"a.x < b.x\", \"a.y < b.y\", SwapStrategy.unstable)(pts1);\n    assert(pts1 == pts2);\n}\n\nprivate bool multiSortPredFun(Range, funs...)(ElementType!Range a, ElementType!Range b)\n{\n    foreach (f; funs)\n    {\n        alias lessFun = binaryFun!(f);\n        if (lessFun(a, b)) return true;\n        if (lessFun(b, a)) return false;\n    }\n    return false;\n}\n\nprivate void multiSortImpl(Range, SwapStrategy ss, funs...)(Range r)\n{\n    alias lessFun = binaryFun!(funs[0]);\n\n    static if (funs.length > 1)\n    {\n        while (r.length > 1)\n        {\n            auto p = getPivot!lessFun(r);\n            auto t = partition3!(funs[0], ss)(r, r[p]);\n            if (t[0].length <= t[2].length)\n            {\n                multiSortImpl!(Range, ss, funs)(t[0]);\n                multiSortImpl!(Range, ss, funs[1 .. $])(t[1]);\n                r = t[2];\n            }\n            else\n            {\n                multiSortImpl!(Range, ss, funs[1 .. $])(t[1]);\n                multiSortImpl!(Range, ss, funs)(t[2]);\n                r = t[0];\n            }\n        }\n    }\n    else\n    {\n        sort!(lessFun, ss)(r);\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range;\n\n    static struct Point { int x, y; }\n    auto pts1 = [ Point(5, 6), Point(1, 0), Point(5, 7), Point(1, 1), Point(1, 2), Point(0, 1) ];\n    auto pts2 = [ Point(0, 1), Point(1, 0), Point(1, 1), Point(1, 2), Point(5, 6), Point(5, 7) ];\n    static assert(validPredicates!(Point, \"a.x < b.x\", \"a.y < b.y\"));\n    multiSort!(\"a.x < b.x\", \"a.y < b.y\", SwapStrategy.unstable)(pts1);\n    assert(pts1 == pts2);\n\n    auto pts3 = indexed(pts1, iota(pts1.length));\n    assert(pts3.multiSort!(\"a.x < b.x\", \"a.y < b.y\", SwapStrategy.unstable).release.equal(pts2));\n\n    auto pts4 = iota(10).array;\n    assert(pts4.multiSort!(\"a > b\").release.equal(iota(10).retro));\n}\n\n@safe unittest //issue 9160 (L-value only comparators)\n{\n    static struct A\n    {\n        int x;\n        int y;\n    }\n\n    static bool byX(const ref A lhs, const ref A rhs)\n    {\n        return lhs.x < rhs.x;\n    }\n\n    static bool byY(const ref A lhs, const ref A rhs)\n    {\n        return lhs.y < rhs.y;\n    }\n\n    auto points = [ A(4, 1), A(2, 4)];\n    multiSort!(byX, byY)(points);\n    assert(points[0] == A(2, 4));\n    assert(points[1] == A(4, 1));\n}\n\n@safe unittest // issue 16179 (cannot access frame of function)\n{\n    auto arr = [[1, 2], [2, 0], [1, 0], [1, 1]];\n    int c = 3;\n\n    arr.multiSort!(\n        (a, b) => a[0] < b[0],\n        (a, b) => c*a[1] < c*b[1]\n    );\n    assert(arr == [[1, 0], [1, 1], [1, 2], [2, 0]]);\n}\n\n@safe unittest //Issue 16413 - @system comparison function\n{\n    bool lt(int a, int b) { return a < b; } static @system\n    auto a = [2, 1];\n    a.multiSort!(lt, lt);\n    assert(a == [1, 2]);\n}\n\nprivate size_t getPivot(alias less, Range)(Range r)\n{\n    auto mid = r.length / 2;\n    if (r.length < 512)\n    {\n        if (r.length >= 32)\n            medianOf!less(r, size_t(0), mid, r.length - 1);\n        return mid;\n    }\n\n    // The plan here is to take the median of five by taking five elements in\n    // the array, segregate around their median, and return the position of the\n    // third. We choose first, mid, last, and two more in between those.\n\n    auto quarter = r.length / 4;\n    medianOf!less(r,\n        size_t(0), mid - quarter, mid, mid + quarter, r.length - 1);\n    return mid;\n}\n\n/*\nSorting routine that is optimized for short ranges. Note: uses insertion sort\ngoing downward. Benchmarked a similar routine that goes upward, for some reason\nit's slower.\n*/\nprivate void shortSort(alias less, Range)(Range r)\n{\n    import std.algorithm.mutation : swapAt;\n    alias pred = binaryFun!(less);\n\n    switch (r.length)\n    {\n        case 0: case 1:\n            return;\n        case 2:\n            if (pred(r[1], r[0])) r.swapAt(0, 1);\n            return;\n        case 3:\n            if (pred(r[2], r[0]))\n            {\n                if (pred(r[0], r[1]))\n                {\n                    r.swapAt(0, 1);\n                    r.swapAt(0, 2);\n                }\n                else\n                {\n                    r.swapAt(0, 2);\n                    if (pred(r[1], r[0])) r.swapAt(0, 1);\n                }\n            }\n            else\n            {\n                if (pred(r[1], r[0]))\n                {\n                    r.swapAt(0, 1);\n                }\n                else\n                {\n                    if (pred(r[2], r[1])) r.swapAt(1, 2);\n                }\n            }\n            return;\n        case 4:\n            if (pred(r[1], r[0])) r.swapAt(0, 1);\n            if (pred(r[3], r[2])) r.swapAt(2, 3);\n            if (pred(r[2], r[0])) r.swapAt(0, 2);\n            if (pred(r[3], r[1])) r.swapAt(1, 3);\n            if (pred(r[2], r[1])) r.swapAt(1, 2);\n            return;\n        default:\n            sort5!pred(r[r.length - 5 .. r.length]);\n            if (r.length == 5) return;\n            break;\n    }\n\n    assert(r.length >= 6);\n    /* The last 5 elements of the range are sorted. Proceed with expanding the\n    sorted portion downward. */\n    immutable maxJ = r.length - 2;\n    for (size_t i = r.length - 6; ; --i)\n    {\n        static if (is(typeof(() nothrow\n            {\n                auto t = r[0]; if (pred(t, r[0])) r[0] = r[0];\n            }))) // Can we afford to temporarily invalidate the array?\n        {\n            size_t j = i + 1;\n            auto temp = r[i];\n            if (pred(r[j], temp))\n            {\n                do\n                {\n                    r[j - 1] = r[j];\n                    ++j;\n                }\n                while (j < r.length && pred(r[j], temp));\n                r[j - 1] = temp;\n            }\n        }\n        else\n        {\n            size_t j = i;\n            while (pred(r[j + 1], r[j]))\n            {\n                r.swapAt(j, j + 1);\n                if (j == maxJ) break;\n                ++j;\n            }\n        }\n        if (i == 0) break;\n    }\n}\n\n@safe unittest\n{\n    import std.random : Random = Xorshift, uniform;\n\n    auto rnd = Random(1);\n    auto a = new int[uniform(100, 200, rnd)];\n    foreach (ref e; a)\n    {\n        e = uniform(-100, 100, rnd);\n    }\n\n    shortSort!(binaryFun!(\"a < b\"), int[])(a);\n    assert(isSorted(a));\n}\n\n/*\nSorts the first 5 elements exactly of range r.\n*/\nprivate void sort5(alias lt, Range)(Range r)\n{\n    assert(r.length >= 5);\n\n    import std.algorithm.mutation : swapAt;\n\n    // 1. Sort first two pairs\n    if (lt(r[1], r[0])) r.swapAt(0, 1);\n    if (lt(r[3], r[2])) r.swapAt(2, 3);\n\n    // 2. Arrange first two pairs by the largest element\n    if (lt(r[3], r[1]))\n    {\n        r.swapAt(0, 2);\n        r.swapAt(1, 3);\n    }\n    assert(!lt(r[1], r[0]) && !lt(r[3], r[1]) && !lt(r[3], r[2]));\n\n    // 3. Insert 4 into [0, 1, 3]\n    if (lt(r[4], r[1]))\n    {\n        r.swapAt(3, 4);\n        r.swapAt(1, 3);\n        if (lt(r[1], r[0]))\n        {\n            r.swapAt(0, 1);\n        }\n    }\n    else if (lt(r[4], r[3]))\n    {\n        r.swapAt(3, 4);\n    }\n    assert(!lt(r[1], r[0]) && !lt(r[3], r[1]) && !lt(r[4], r[3]));\n\n    // 4. Insert 2 into [0, 1, 3, 4] (note: we already know the last is greater)\n    assert(!lt(r[4], r[2]));\n    if (lt(r[2], r[1]))\n    {\n        r.swapAt(1, 2);\n        if (lt(r[1], r[0]))\n        {\n            r.swapAt(0, 1);\n        }\n    }\n    else if (lt(r[3], r[2]))\n    {\n        r.swapAt(2, 3);\n    }\n    // 7 comparisons, 0-9 swaps\n}\n\n@safe unittest\n{\n    import std.algorithm.iteration : permutations;\n    import std.algorithm.mutation : copy;\n\n    int[5] buf;\n    foreach (per; iota(5).permutations)\n    {\n        per.copy(buf[]);\n        sort5!((a, b) => a < b)(buf[]);\n        assert(buf[].isSorted);\n    }\n}\n\n// sort\n/**\nSorts a random-access range according to the predicate `less`. Performs\n$(BIGOH r.length * log(r.length)) evaluations of `less`. If `less` involves\nexpensive computations on the _sort key, it may be worthwhile to use\n$(LREF schwartzSort) instead.\n\nStable sorting requires `hasAssignableElements!Range` to be true.\n\n`sort` returns a $(REF SortedRange, std,range) over the original range,\nallowing functions that can take advantage of sorted data to know that the\nrange is sorted and adjust accordingly. The $(REF SortedRange, std,range) is a\nwrapper around the original range, so both it and the original range are sorted.\nOther functions can't know that the original range has been sorted, but\nthey $(I can) know that $(REF SortedRange, std,range) has been sorted.\n\nPreconditions:\n\nThe predicate is expected to satisfy certain rules in order for `sort` to\nbehave as expected - otherwise, the program may fail on certain inputs (but not\nothers) when not compiled in release mode, due to the cursory `assumeSorted`\ncheck. Specifically, `sort` expects `less(a,b) && less(b,c)` to imply\n`less(a,c)` (transitivity), and, conversely, `!less(a,b) && !less(b,c)` to\nimply `!less(a,c)`. Note that the default predicate (`\"a < b\"`) does not\nalways satisfy these conditions for floating point types, because the expression\nwill always be `false` when either `a` or `b` is NaN.\nUse $(REF cmp, std,math) instead.\n\nParams:\n    less = The predicate to sort by.\n    ss = The swapping strategy to use.\n    r = The range to sort.\n\nReturns: The initial range wrapped as a `SortedRange` with the predicate\n`binaryFun!less`.\n\nAlgorithms: $(HTTP en.wikipedia.org/wiki/Introsort, Introsort) is used for unstable sorting and\n$(HTTP en.wikipedia.org/wiki/Timsort, Timsort) is used for stable sorting.\nEach algorithm has benefits beyond stability. Introsort is generally faster but\nTimsort may achieve greater speeds on data with low entropy or if predicate calls\nare expensive. Introsort performs no allocations whereas Timsort will perform one\nor more allocations per call. Both algorithms have $(BIGOH n log n) worst-case\ntime complexity.\n\nSee_Also:\n    $(REF assumeSorted, std,range)$(BR)\n    $(REF SortedRange, std,range)$(BR)\n    $(REF SwapStrategy, std,algorithm,mutation)$(BR)\n    $(REF binaryFun, std,functional)\n*/\nSortedRange!(Range, less)\nsort(alias less = \"a < b\", SwapStrategy ss = SwapStrategy.unstable,\n        Range)(Range r)\nif (((ss == SwapStrategy.unstable && (hasSwappableElements!Range ||\n    hasAssignableElements!Range)) ||\n    (ss != SwapStrategy.unstable && hasAssignableElements!Range)) &&\n    isRandomAccessRange!Range &&\n    hasSlicing!Range &&\n    hasLength!Range)\n    /+ Unstable sorting uses the quicksort algorithm, which uses swapAt,\n       which either uses swap(...), requiring swappable elements, or just\n       swaps using assignment.\n       Stable sorting uses TimSort, which needs to copy elements into a buffer,\n       requiring assignable elements. +/\n{\n    import std.range : assumeSorted;\n    alias lessFun = binaryFun!(less);\n    alias LessRet = typeof(lessFun(r.front, r.front));    // instantiate lessFun\n    static if (is(LessRet == bool))\n    {\n        static if (ss == SwapStrategy.unstable)\n            quickSortImpl!(lessFun)(r, r.length);\n        else //use Tim Sort for semistable & stable\n            TimSortImpl!(lessFun, Range).sort(r, null);\n\n        assert(isSorted!lessFun(r), \"Failed to sort range of type \" ~ Range.stringof);\n    }\n    else\n    {\n        static assert(false, \"Invalid predicate passed to sort: \" ~ less.stringof);\n    }\n    return assumeSorted!less(r);\n}\n\n///\n@safe pure nothrow unittest\n{\n    int[] array = [ 1, 2, 3, 4 ];\n\n    // sort in descending order\n    array.sort!(\"a > b\");\n    assert(array == [ 4, 3, 2, 1 ]);\n\n    // sort in ascending order\n    array.sort();\n    assert(array == [ 1, 2, 3, 4 ]);\n\n    // sort with reusable comparator and chain\n    alias myComp = (x, y) => x > y;\n    assert(array.sort!(myComp).release == [ 4, 3, 2, 1 ]);\n}\n\n///\n@safe unittest\n{\n    // Showcase stable sorting\n    import std.algorithm.mutation : SwapStrategy;\n    string[] words = [ \"aBc\", \"a\", \"abc\", \"b\", \"ABC\", \"c\" ];\n    sort!(\"toUpper(a) < toUpper(b)\", SwapStrategy.stable)(words);\n    assert(words == [ \"a\", \"aBc\", \"abc\", \"ABC\", \"b\", \"c\" ]);\n}\n\n///\n@safe unittest\n{\n    // Sorting floating-point numbers in presence of NaN\n    double[] numbers = [-0.0, 3.0, -2.0, double.nan, 0.0, -double.nan];\n\n    import std.algorithm.comparison : equal;\n    import std.math : cmp, isIdentical;\n\n    sort!((a, b) => cmp(a, b) < 0)(numbers);\n\n    double[] sorted = [-double.nan, -2.0, -0.0, 0.0, 3.0, double.nan];\n    assert(numbers.equal!isIdentical(sorted));\n}\n\n@safe unittest\n{\n    // Simple regression benchmark\n    import std.algorithm.iteration, std.algorithm.mutation, std.random;\n    Random rng;\n    int[] a = iota(20148).map!(_ => uniform(-1000, 1000, rng)).array;\n    static uint comps;\n    static bool less(int a, int b) { ++comps; return a < b; }\n    sort!less(a); // random numbers\n    sort!less(a); // sorted ascending\n    a.reverse();\n    sort!less(a); // sorted descending\n    a[] = 0;\n    sort!less(a); // all equal\n\n    // This should get smaller with time. On occasion it may go larger, but only\n    // if there's thorough justification.\n    debug enum uint watermark = 1676280;\n    else enum uint watermark = 1676220;\n\n    import std.conv;\n    assert(comps <= watermark, text(\"You seem to have pessimized sort! \",\n        watermark, \" < \", comps));\n    assert(comps >= watermark, text(\"You seem to have improved sort!\",\n        \" Please update watermark from \", watermark, \" to \", comps));\n}\n\n@safe unittest\n{\n    import std.algorithm.internal : rndstuff;\n    import std.algorithm.mutation : swapRanges;\n    import std.random : Random = Xorshift, uniform;\n    import std.uni : toUpper;\n\n    // sort using delegate\n    auto a = new int[100];\n    auto rnd = Random(123_456_789);\n    foreach (ref e; a)\n    {\n        e = uniform(-100, 100, rnd);\n    }\n\n    int i = 0;\n    bool greater2(int a, int b) @safe { return a + i > b + i; }\n    auto greater = &greater2;\n    sort!(greater)(a);\n    assert(isSorted!(greater)(a));\n\n    // sort using string\n    sort!(\"a < b\")(a);\n    assert(isSorted!(\"a < b\")(a));\n\n    // sort using function; all elements equal\n    foreach (ref e; a)\n    {\n        e = 5;\n    }\n    static bool less(int a, int b) { return a < b; }\n    sort!(less)(a);\n    assert(isSorted!(less)(a));\n\n    string[] words = [ \"aBc\", \"a\", \"abc\", \"b\", \"ABC\", \"c\" ];\n    bool lessi(string a, string b) { return toUpper(a) < toUpper(b); }\n    sort!(lessi, SwapStrategy.stable)(words);\n    assert(words == [ \"a\", \"aBc\", \"abc\", \"ABC\", \"b\", \"c\" ]);\n\n    // sort using ternary predicate\n    //sort!(\"b - a\")(a);\n    //assert(isSorted!(less)(a));\n\n    a = rndstuff!(int)();\n    sort(a);\n    assert(isSorted(a));\n    auto b = rndstuff!(string)();\n    sort!(\"toLower(a) < toLower(b)\")(b);\n    assert(isSorted!(\"toUpper(a) < toUpper(b)\")(b));\n\n    {\n        // Issue 10317\n        enum E_10317 { a, b }\n        auto a_10317 = new E_10317[10];\n        sort(a_10317);\n    }\n\n    {\n        // Issue 7767\n        // Unstable sort should complete without an excessive number of predicate calls\n        // This would suggest it's running in quadratic time\n\n        // Compilation error if predicate is not static, i.e. a nested function\n        static uint comp;\n        static bool pred(size_t a, size_t b)\n        {\n            ++comp;\n            return a < b;\n        }\n\n        size_t[] arr;\n        arr.length = 1024;\n\n        foreach (k; 0 .. arr.length) arr[k] = k;\n        swapRanges(arr[0..$/2], arr[$/2..$]);\n\n        sort!(pred, SwapStrategy.unstable)(arr);\n        assert(comp < 25_000);\n    }\n\n    {\n        import std.algorithm.mutation : swap;\n\n        bool proxySwapCalled;\n        struct S\n        {\n            int i;\n            alias i this;\n            void proxySwap(ref S other) { swap(i, other.i); proxySwapCalled = true; }\n            @disable void opAssign(S value);\n        }\n\n        alias R = S[];\n        R r = [S(3), S(2), S(1)];\n        static assert(hasSwappableElements!R);\n        static assert(!hasAssignableElements!R);\n        r.sort();\n        assert(proxySwapCalled);\n    }\n}\n\nprivate void quickSortImpl(alias less, Range)(Range r, size_t depth)\n{\n    import std.algorithm.comparison : min, max;\n    import std.algorithm.mutation : swap, swapAt;\n\n    alias Elem = ElementType!(Range);\n    enum size_t shortSortGetsBetter = max(32, 1024 / Elem.sizeof);\n    static assert(shortSortGetsBetter >= 1);\n\n    // partition\n    while (r.length > shortSortGetsBetter)\n    {\n        if (depth == 0)\n        {\n            HeapOps!(less, Range).heapSort(r);\n            return;\n        }\n        depth = depth >= depth.max / 2 ? (depth / 3) * 2 : (depth * 2) / 3;\n\n        const pivotIdx = getPivot!(less)(r);\n        auto pivot = r[pivotIdx];\n\n        // partition\n        r.swapAt(pivotIdx, r.length - 1);\n        size_t lessI = size_t.max, greaterI = r.length - 1;\n\n        outer: for (;;)\n        {\n            alias pred = binaryFun!less;\n            while (pred(r[++lessI], pivot)) {}\n            assert(lessI <= greaterI, \"sort: invalid comparison function.\");\n            for (;;)\n            {\n                if (greaterI == lessI) break outer;\n                if (!pred(pivot, r[--greaterI])) break;\n            }\n            assert(lessI <= greaterI, \"sort: invalid comparison function.\");\n            if (lessI == greaterI) break;\n            r.swapAt(lessI, greaterI);\n        }\n\n        r.swapAt(r.length - 1, lessI);\n        auto left = r[0 .. lessI], right = r[lessI + 1 .. r.length];\n        if (right.length > left.length)\n        {\n            swap(left, right);\n        }\n        .quickSortImpl!(less, Range)(right, depth);\n        r = left;\n    }\n    // residual sort\n    static if (shortSortGetsBetter > 1)\n    {\n        shortSort!(less, Range)(r);\n    }\n}\n\n// Heap operations for random-access ranges\npackage(std) template HeapOps(alias less, Range)\n{\n    import std.algorithm.mutation : swapAt;\n\n    static assert(isRandomAccessRange!Range);\n    static assert(hasLength!Range);\n    static assert(hasSwappableElements!Range || hasAssignableElements!Range);\n\n    alias lessFun = binaryFun!less;\n\n    //template because of @@@12410@@@\n    void heapSort()(Range r)\n    {\n        // If true, there is nothing to do\n        if (r.length < 2) return;\n        // Build Heap\n        buildHeap(r);\n        // Sort\n        for (size_t i = r.length - 1; i > 0; --i)\n        {\n            r.swapAt(0, i);\n            percolate(r, 0, i);\n        }\n    }\n\n    //template because of @@@12410@@@\n    void buildHeap()(Range r)\n    {\n        immutable n = r.length;\n        for (size_t i = n / 2; i-- > 0; )\n        {\n            siftDown(r, i, n);\n        }\n        assert(isHeap(r));\n    }\n\n    bool isHeap()(Range r)\n    {\n        size_t parent = 0;\n        foreach (child; 1 .. r.length)\n        {\n            if (lessFun(r[parent], r[child])) return false;\n            // Increment parent every other pass\n            parent += !(child & 1);\n        }\n        return true;\n    }\n\n    // Sifts down r[parent] (which is initially assumed to be messed up) so the\n    // heap property is restored for r[parent .. end].\n    // template because of @@@12410@@@\n    void siftDown()(Range r, size_t parent, immutable size_t end)\n    {\n        for (;;)\n        {\n            auto child = (parent + 1) * 2;\n            if (child >= end)\n            {\n                // Leftover left child?\n                if (child == end && lessFun(r[parent], r[--child]))\n                    r.swapAt(parent, child);\n                break;\n            }\n            auto leftChild = child - 1;\n            if (lessFun(r[child], r[leftChild])) child = leftChild;\n            if (!lessFun(r[parent], r[child])) break;\n            r.swapAt(parent, child);\n            parent = child;\n        }\n    }\n\n    // Alternate version of siftDown that performs fewer comparisons, see\n    // https://en.wikipedia.org/wiki/Heapsort#Bottom-up_heapsort. The percolate\n    // process first sifts the parent all the way down (without comparing it\n    // against the leaves), and then a bit up until the heap property is\n    // restored. So there are more swaps but fewer comparisons. Gains are made\n    // when the final position is likely to end toward the bottom of the heap,\n    // so not a lot of sifts back are performed.\n    //template because of @@@12410@@@\n    void percolate()(Range r, size_t parent, immutable size_t end)\n    {\n        immutable root = parent;\n\n        // Sift down\n        for (;;)\n        {\n            auto child = (parent + 1) * 2;\n\n            if (child >= end)\n            {\n                if (child == end)\n                {\n                    // Leftover left node.\n                    --child;\n                    r.swapAt(parent, child);\n                    parent = child;\n                }\n                break;\n            }\n\n            auto leftChild = child - 1;\n            if (lessFun(r[child], r[leftChild])) child = leftChild;\n            r.swapAt(parent, child);\n            parent = child;\n        }\n\n        // Sift up\n        for (auto child = parent; child > root; child = parent)\n        {\n            parent = (child - 1) / 2;\n            if (!lessFun(r[parent], r[child])) break;\n            r.swapAt(parent, child);\n        }\n    }\n}\n\n// Tim Sort implementation\nprivate template TimSortImpl(alias pred, R)\n{\n    import core.bitop : bsr;\n    import std.array : uninitializedArray;\n\n    static assert(isRandomAccessRange!R);\n    static assert(hasLength!R);\n    static assert(hasSlicing!R);\n    static assert(hasAssignableElements!R);\n\n    alias T = ElementType!R;\n\n    alias less = binaryFun!pred;\n    alias greater = (a, b) => less(b, a);\n    alias greaterEqual = (a, b) => !less(a, b);\n    alias lessEqual = (a, b) => !less(b, a);\n\n    enum minimalMerge = 128;\n    enum minimalGallop = 7;\n    enum minimalStorage = 256;\n    enum stackSize = 40;\n\n    struct Slice{ size_t base, length; }\n\n    // Entry point for tim sort\n    void sort()(R range, T[] temp)\n    {\n        import std.algorithm.comparison : min;\n\n        // Do insertion sort on small range\n        if (range.length <= minimalMerge)\n        {\n            binaryInsertionSort(range);\n            return;\n        }\n\n        immutable minRun = minRunLength(range.length);\n        immutable minTemp = min(range.length / 2, minimalStorage);\n        size_t minGallop = minimalGallop;\n        Slice[stackSize] stack = void;\n        size_t stackLen = 0;\n\n        // Allocate temporary memory if not provided by user\n        if (temp.length < minTemp) temp = () @trusted { return uninitializedArray!(T[])(minTemp); }();\n\n        for (size_t i = 0; i < range.length; )\n        {\n            // Find length of first run in list\n            size_t runLen = firstRun(range[i .. range.length]);\n\n            // If run has less than minRun elements, extend using insertion sort\n            if (runLen < minRun)\n            {\n                // Do not run farther than the length of the range\n                immutable force = range.length - i > minRun ? minRun : range.length - i;\n                binaryInsertionSort(range[i .. i + force], runLen);\n                runLen = force;\n            }\n\n            // Push run onto stack\n            stack[stackLen++] = Slice(i, runLen);\n            i += runLen;\n\n            // Collapse stack so that (e1 > e2 + e3 && e2 > e3)\n            // STACK is | ... e1 e2 e3 >\n            while (stackLen > 1)\n            {\n                immutable run4 = stackLen - 1;\n                immutable run3 = stackLen - 2;\n                immutable run2 = stackLen - 3;\n                immutable run1 = stackLen - 4;\n\n                if ( (stackLen > 2 && stack[run2].length <= stack[run3].length + stack[run4].length) ||\n                     (stackLen > 3 && stack[run1].length <= stack[run3].length + stack[run2].length) )\n                {\n                    immutable at = stack[run2].length < stack[run4].length ? run2 : run3;\n                    mergeAt(range, stack[0 .. stackLen], at, minGallop, temp);\n                }\n                else if (stack[run3].length > stack[run4].length) break;\n                else mergeAt(range, stack[0 .. stackLen], run3, minGallop, temp);\n\n                stackLen -= 1;\n            }\n\n            // Assert that the code above established the invariant correctly\n            version (assert)\n            {\n                if (stackLen == 2) assert(stack[0].length > stack[1].length);\n                else if (stackLen > 2)\n                {\n                    foreach (k; 2 .. stackLen)\n                    {\n                        assert(stack[k - 2].length > stack[k - 1].length + stack[k].length);\n                        assert(stack[k - 1].length > stack[k].length);\n                    }\n                }\n            }\n        }\n\n        // Force collapse stack until there is only one run left\n        while (stackLen > 1)\n        {\n            immutable run3 = stackLen - 1;\n            immutable run2 = stackLen - 2;\n            immutable run1 = stackLen - 3;\n            immutable at = stackLen >= 3 && stack[run1].length <= stack[run3].length\n                ? run1 : run2;\n            mergeAt(range, stack[0 .. stackLen], at, minGallop, temp);\n            --stackLen;\n        }\n    }\n\n    // Calculates optimal value for minRun:\n    // take first 6 bits of n and add 1 if any lower bits are set\n    size_t minRunLength()(size_t n)\n    {\n        immutable shift = bsr(n)-5;\n        auto result = (n >> shift) + !!(n & ~((1 << shift)-1));\n        return result;\n    }\n\n    // Returns length of first run in range\n    size_t firstRun()(R range)\n    out(ret)\n    {\n        assert(ret <= range.length);\n    }\n    do\n    {\n        import std.algorithm.mutation : reverse;\n\n        if (range.length < 2) return range.length;\n\n        size_t i = 2;\n        if (lessEqual(range[0], range[1]))\n        {\n            while (i < range.length && lessEqual(range[i-1], range[i])) ++i;\n        }\n        else\n        {\n            while (i < range.length && greater(range[i-1], range[i])) ++i;\n            reverse(range[0 .. i]);\n        }\n        return i;\n    }\n\n    // A binary insertion sort for building runs up to minRun length\n    void binaryInsertionSort()(R range, size_t sortedLen = 1)\n    out\n    {\n        if (!__ctfe) assert(isSorted!pred(range));\n    }\n    do\n    {\n        import std.algorithm.mutation : move;\n\n        for (; sortedLen < range.length; ++sortedLen)\n        {\n            T item = range.moveAt(sortedLen);\n            size_t lower = 0;\n            size_t upper = sortedLen;\n            while (upper != lower)\n            {\n                size_t center = (lower + upper) / 2;\n                if (less(item, range[center])) upper = center;\n                else lower = center + 1;\n            }\n            //Currently (DMD 2.061) moveAll+retro is slightly less\n            //efficient then stright 'for' loop\n            //11 instructions vs 7 in the innermost loop [checked on Win32]\n            //moveAll(retro(range[lower .. sortedLen]),\n            //            retro(range[lower+1 .. sortedLen+1]));\n            for (upper=sortedLen; upper > lower; upper--)\n                range[upper] = range.moveAt(upper - 1);\n            range[lower] = move(item);\n        }\n    }\n\n    // Merge two runs in stack (at, at + 1)\n    void mergeAt()(R range, Slice[] stack, immutable size_t at, ref size_t minGallop, ref T[] temp)\n    in\n    {\n        assert(stack.length >= 2);\n        assert(stack.length - at == 2 || stack.length - at == 3);\n    }\n    do\n    {\n        immutable base = stack[at].base;\n        immutable mid  = stack[at].length;\n        immutable len  = stack[at + 1].length + mid;\n\n        // Pop run from stack\n        stack[at] = Slice(base, len);\n        if (stack.length - at == 3) stack[$ - 2] = stack[$ - 1];\n\n        // Merge runs (at, at + 1)\n        return merge(range[base .. base + len], mid, minGallop, temp);\n    }\n\n    // Merge two runs in a range. Mid is the starting index of the second run.\n    // minGallop and temp are references; The calling function must receive the updated values.\n    void merge()(R range, size_t mid, ref size_t minGallop, ref T[] temp)\n    in\n    {\n        if (!__ctfe)\n        {\n            assert(isSorted!pred(range[0 .. mid]));\n            assert(isSorted!pred(range[mid .. range.length]));\n        }\n    }\n    do\n    {\n        assert(mid < range.length);\n\n        // Reduce range of elements\n        immutable firstElement = gallopForwardUpper(range[0 .. mid], range[mid]);\n        immutable lastElement  = gallopReverseLower(range[mid .. range.length], range[mid - 1]) + mid;\n        range = range[firstElement .. lastElement];\n        mid -= firstElement;\n\n        if (mid == 0 || mid == range.length) return;\n\n        // Call function which will copy smaller run into temporary memory\n        if (mid <= range.length / 2)\n        {\n            temp = ensureCapacity(mid, temp);\n            minGallop = mergeLo(range, mid, minGallop, temp);\n        }\n        else\n        {\n            temp = ensureCapacity(range.length - mid, temp);\n            minGallop = mergeHi(range, mid, minGallop, temp);\n        }\n    }\n\n    // Enlarge size of temporary memory if needed\n    T[] ensureCapacity()(size_t minCapacity, T[] temp)\n    out(ret)\n    {\n        assert(ret.length >= minCapacity);\n    }\n    do\n    {\n        if (temp.length < minCapacity)\n        {\n            size_t newSize = 1<<(bsr(minCapacity)+1);\n            //Test for overflow\n            if (newSize < minCapacity) newSize = minCapacity;\n\n            if (__ctfe) temp.length = newSize;\n            else temp = () @trusted { return uninitializedArray!(T[])(newSize); }();\n        }\n        return temp;\n    }\n\n    // Merge front to back. Returns new value of minGallop.\n    // temp must be large enough to store range[0 .. mid]\n    size_t mergeLo()(R range, immutable size_t mid, size_t minGallop, T[] temp)\n    out\n    {\n        if (!__ctfe) assert(isSorted!pred(range));\n    }\n    do\n    {\n        import std.algorithm.mutation : copy;\n\n        assert(mid <= range.length);\n        assert(temp.length >= mid);\n\n        // Copy run into temporary memory\n        temp = temp[0 .. mid];\n        copy(range[0 .. mid], temp);\n\n        // Move first element into place\n        range[0] = range[mid];\n\n        size_t i = 1, lef = 0, rig = mid + 1;\n        size_t count_lef, count_rig;\n        immutable lef_end = temp.length - 1;\n\n        if (lef < lef_end && rig < range.length)\n        outer: while (true)\n        {\n            count_lef = 0;\n            count_rig = 0;\n\n            // Linear merge\n            while ((count_lef | count_rig) < minGallop)\n            {\n                if (lessEqual(temp[lef], range[rig]))\n                {\n                    range[i++] = temp[lef++];\n                    if (lef >= lef_end) break outer;\n                    ++count_lef;\n                    count_rig = 0;\n                }\n                else\n                {\n                    range[i++] = range[rig++];\n                    if (rig >= range.length) break outer;\n                    count_lef = 0;\n                    ++count_rig;\n                }\n            }\n\n            // Gallop merge\n            do\n            {\n                count_lef = gallopForwardUpper(temp[lef .. $], range[rig]);\n                foreach (j; 0 .. count_lef) range[i++] = temp[lef++];\n                if (lef >= temp.length) break outer;\n\n                count_rig = gallopForwardLower(range[rig .. range.length], temp[lef]);\n                foreach (j; 0 .. count_rig) range[i++] = range[rig++];\n                if (rig >= range.length) while (true)\n                {\n                    range[i++] = temp[lef++];\n                    if (lef >= temp.length) break outer;\n                }\n\n                if (minGallop > 0) --minGallop;\n            }\n            while (count_lef >= minimalGallop || count_rig >= minimalGallop);\n\n            minGallop += 2;\n        }\n\n        // Move remaining elements from right\n        while (rig < range.length)\n            range[i++] = range[rig++];\n\n        // Move remaining elements from left\n        while (lef < temp.length)\n            range[i++] = temp[lef++];\n\n        return minGallop > 0 ? minGallop : 1;\n    }\n\n    // Merge back to front. Returns new value of minGallop.\n    // temp must be large enough to store range[mid .. range.length]\n    size_t mergeHi()(R range, immutable size_t mid, size_t minGallop, T[] temp)\n    out\n    {\n        if (!__ctfe) assert(isSorted!pred(range));\n    }\n    do\n    {\n        import std.algorithm.mutation : copy;\n\n        assert(mid <= range.length);\n        assert(temp.length >= range.length - mid);\n\n        // Copy run into temporary memory\n        temp = temp[0 .. range.length - mid];\n        copy(range[mid .. range.length], temp);\n\n        // Move first element into place\n        range[range.length - 1] = range[mid - 1];\n\n        size_t i = range.length - 2, lef = mid - 2, rig = temp.length - 1;\n        size_t count_lef, count_rig;\n\n        outer:\n        while (true)\n        {\n            count_lef = 0;\n            count_rig = 0;\n\n            // Linear merge\n            while ((count_lef | count_rig) < minGallop)\n            {\n                if (greaterEqual(temp[rig], range[lef]))\n                {\n                    range[i--] = temp[rig];\n                    if (rig == 1)\n                    {\n                        // Move remaining elements from left\n                        while (true)\n                        {\n                            range[i--] = range[lef];\n                            if (lef == 0) break;\n                            --lef;\n                        }\n\n                        // Move last element into place\n                        range[i] = temp[0];\n\n                        break outer;\n                    }\n                    --rig;\n                    count_lef = 0;\n                    ++count_rig;\n                }\n                else\n                {\n                    range[i--] = range[lef];\n                    if (lef == 0) while (true)\n                    {\n                        range[i--] = temp[rig];\n                        if (rig == 0) break outer;\n                        --rig;\n                    }\n                    --lef;\n                    ++count_lef;\n                    count_rig = 0;\n                }\n            }\n\n            // Gallop merge\n            do\n            {\n                count_rig = rig - gallopReverseLower(temp[0 .. rig], range[lef]);\n                foreach (j; 0 .. count_rig)\n                {\n                    range[i--] = temp[rig];\n                    if (rig == 0) break outer;\n                    --rig;\n                }\n\n                count_lef = lef - gallopReverseUpper(range[0 .. lef], temp[rig]);\n                foreach (j; 0 .. count_lef)\n                {\n                    range[i--] = range[lef];\n                    if (lef == 0) while (true)\n                    {\n                        range[i--] = temp[rig];\n                        if (rig == 0) break outer;\n                        --rig;\n                    }\n                    --lef;\n                }\n\n                if (minGallop > 0) --minGallop;\n            }\n            while (count_lef >= minimalGallop || count_rig >= minimalGallop);\n\n            minGallop += 2;\n        }\n\n        return minGallop > 0 ? minGallop : 1;\n    }\n\n    // false = forward / lower, true = reverse / upper\n    template gallopSearch(bool forwardReverse, bool lowerUpper)\n    {\n        // Gallop search on range according to attributes forwardReverse and lowerUpper\n        size_t gallopSearch(R)(R range, T value)\n        out(ret)\n        {\n            assert(ret <= range.length);\n        }\n        do\n        {\n            size_t lower = 0, center = 1, upper = range.length;\n            alias gap = center;\n\n            static if (forwardReverse)\n            {\n                static if (!lowerUpper) alias comp = lessEqual; // reverse lower\n                static if (lowerUpper)  alias comp = less;      // reverse upper\n\n                // Gallop Search Reverse\n                while (gap <= upper)\n                {\n                    if (comp(value, range[upper - gap]))\n                    {\n                        upper -= gap;\n                        gap *= 2;\n                    }\n                    else\n                    {\n                        lower = upper - gap;\n                        break;\n                    }\n                }\n\n                // Binary Search Reverse\n                while (upper != lower)\n                {\n                    center = lower + (upper - lower) / 2;\n                    if (comp(value, range[center])) upper = center;\n                    else lower = center + 1;\n                }\n            }\n            else\n            {\n                static if (!lowerUpper) alias comp = greater;      // forward lower\n                static if (lowerUpper)  alias comp = greaterEqual; // forward upper\n\n                // Gallop Search Forward\n                while (lower + gap < upper)\n                {\n                    if (comp(value, range[lower + gap]))\n                    {\n                        lower += gap;\n                        gap *= 2;\n                    }\n                    else\n                    {\n                        upper = lower + gap;\n                        break;\n                    }\n                }\n\n                // Binary Search Forward\n                while (lower != upper)\n                {\n                    center = lower + (upper - lower) / 2;\n                    if (comp(value, range[center])) lower = center + 1;\n                    else upper = center;\n                }\n            }\n\n            return lower;\n        }\n    }\n\n    alias gallopForwardLower = gallopSearch!(false, false);\n    alias gallopForwardUpper = gallopSearch!(false,  true);\n    alias gallopReverseLower = gallopSearch!( true, false);\n    alias gallopReverseUpper = gallopSearch!( true,  true);\n}\n\n@safe unittest\n{\n    import std.random : Random, uniform, randomShuffle;\n\n    // Element type with two fields\n    static struct E\n    {\n        size_t value, index;\n    }\n\n    // Generates data especially for testing sorting with Timsort\n    static E[] genSampleData(uint seed) @safe\n    {\n        import std.algorithm.mutation : swap, swapRanges;\n\n        auto rnd = Random(seed);\n\n        E[] arr;\n        arr.length = 64 * 64;\n\n        // We want duplicate values for testing stability\n        foreach (i, ref v; arr) v.value = i / 64;\n\n        // Swap ranges at random middle point (test large merge operation)\n        immutable mid = uniform(arr.length / 4, arr.length / 4 * 3, rnd);\n        swapRanges(arr[0 .. mid], arr[mid .. $]);\n\n        // Shuffle last 1/8 of the array (test insertion sort and linear merge)\n        randomShuffle(arr[$ / 8 * 7 .. $], rnd);\n\n        // Swap few random elements (test galloping mode)\n        foreach (i; 0 .. arr.length / 64)\n        {\n            immutable a = uniform(0, arr.length, rnd), b = uniform(0, arr.length, rnd);\n            swap(arr[a], arr[b]);\n        }\n\n        // Now that our test array is prepped, store original index value\n        // This will allow us to confirm the array was sorted stably\n        foreach (i, ref v; arr) v.index = i;\n\n        return arr;\n    }\n\n    // Tests the Timsort function for correctness and stability\n    static bool testSort(uint seed)\n    {\n        auto arr = genSampleData(seed);\n\n        // Now sort the array!\n        static bool comp(E a, E b)\n        {\n            return a.value < b.value;\n        }\n\n        sort!(comp, SwapStrategy.stable)(arr);\n\n        // Test that the array was sorted correctly\n        assert(isSorted!comp(arr));\n\n        // Test that the array was sorted stably\n        foreach (i; 0 .. arr.length - 1)\n        {\n            if (arr[i].value == arr[i + 1].value) assert(arr[i].index < arr[i + 1].index);\n        }\n\n        return true;\n    }\n\n    enum seed = 310614065;\n    testSort(seed);\n\n    enum result = testSort(seed);\n    assert(result == true);\n}\n\n@safe unittest\n{//bugzilla 4584\n    assert(isSorted!\"a < b\"(sort!(\"a < b\", SwapStrategy.stable)(\n       [83, 42, 85, 86, 87, 22, 89, 30, 91, 46, 93, 94, 95, 6,\n         97, 14, 33, 10, 101, 102, 103, 26, 105, 106, 107, 6]\n    )));\n\n}\n\n@safe unittest\n{\n    //test stable sort + zip\n    import std.range;\n    auto x = [10, 50, 60, 60, 20];\n    dchar[] y = \"abcde\"d.dup;\n\n    sort!(\"a[0] < b[0]\", SwapStrategy.stable)(zip(x, y));\n    assert(x == [10, 20, 50, 60, 60]);\n    assert(y == \"aebcd\"d);\n}\n\n@safe unittest\n{\n    // Issue 14223\n    import std.array, std.range;\n    auto arr = chain(iota(0, 384), iota(0, 256), iota(0, 80), iota(0, 64), iota(0, 96)).array;\n    sort!(\"a < b\", SwapStrategy.stable)(arr);\n}\n\n// schwartzSort\n/**\nAlternative sorting method that should be used when comparing keys involves an\nexpensive computation. Instead of using `less(a, b)` for comparing elements,\n`schwartzSort` uses `less(transform(a), transform(b))`. The values of the\n`transform` function are precomputed in a temporary array, thus saving on\nrepeatedly computing it. Conversely, if the cost of `transform` is small\ncompared to the cost of allocating and filling the precomputed array, `sort`\nmay be faster and therefore preferable.\n\nThis approach to sorting is akin to the $(HTTP\nwikipedia.org/wiki/Schwartzian_transform, Schwartzian transform), also known as\nthe decorate-sort-undecorate pattern in Python and Lisp. The complexity is the\nsame as that of the corresponding `sort`, but `schwartzSort` evaluates\n`transform` only `r.length` times (less than half when compared to regular\nsorting). The usage can be best illustrated with an example.\n\nExample:\n----\nuint hashFun(string) { ... expensive computation ... }\nstring[] array = ...;\n// Sort strings by hash, slow\nsort!((a, b) => hashFun(a) < hashFun(b))(array);\n// Sort strings by hash, fast (only computes arr.length hashes):\nschwartzSort!(hashFun, \"a < b\")(array);\n----\n\nThe `schwartzSort` function might require less temporary data and\nbe faster than the Perl idiom or the decorate-sort-undecorate idiom\npresent in Python and Lisp. This is because sorting is done in-place\nand only minimal extra data (one array of transformed elements) is\ncreated.\n\nTo check whether an array was sorted and benefit of the speedup of\nSchwartz sorting, a function `schwartzIsSorted` is not provided\nbecause the effect can be achieved by calling $(D\nisSorted!less(map!transform(r))).\n\nParams:\n    transform = The transformation to apply.\n    less = The predicate to sort by.\n    ss = The swapping strategy to use.\n    r = The range to sort.\n\nReturns: The initial range wrapped as a `SortedRange` with the\npredicate `(a, b) => binaryFun!less(transform(a), transform(b))`.\n */\nSortedRange!(R, ((a, b) => binaryFun!less(unaryFun!transform(a),\n                                          unaryFun!transform(b))))\nschwartzSort(alias transform, alias less = \"a < b\",\n        SwapStrategy ss = SwapStrategy.unstable, R)(R r)\nif (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)\n{\n    import std.conv : emplace;\n    import std.range : zip, SortedRange;\n    import std.string : representation;\n\n    alias T = typeof(unaryFun!transform(r.front));\n    static trustedMalloc(size_t len) @trusted\n    {\n        import core.checkedint : mulu;\n        import core.stdc.stdlib : malloc;\n        bool overflow;\n        const nbytes = mulu(len, T.sizeof, overflow);\n        if (overflow) assert(0);\n        return (cast(T*) malloc(nbytes))[0 .. len];\n    }\n    auto xform1 = trustedMalloc(r.length);\n\n    size_t length;\n    scope(exit)\n    {\n        static if (hasElaborateDestructor!T)\n        {\n            foreach (i; 0 .. length) collectException(destroy(xform1[i]));\n        }\n        static void trustedFree(T[] p) @trusted\n        {\n            import core.stdc.stdlib : free;\n            free(p.ptr);\n        }\n        trustedFree(xform1);\n    }\n    for (; length != r.length; ++length)\n    {\n        emplace(&xform1[length], unaryFun!transform(r[length]));\n    }\n    // Make sure we use ubyte[] and ushort[], not char[] and wchar[]\n    // for the intermediate array, lest zip gets confused.\n    static if (isNarrowString!(typeof(xform1)))\n    {\n        auto xform = xform1.representation();\n    }\n    else\n    {\n        alias xform = xform1;\n    }\n    zip(xform, r).sort!((a, b) => binaryFun!less(a[0], b[0]), ss)();\n    return typeof(return)(r);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.iteration : map;\n    import std.numeric : entropy;\n\n    auto lowEnt = [ 1.0, 0, 0 ],\n         midEnt = [ 0.1, 0.1, 0.8 ],\n        highEnt = [ 0.31, 0.29, 0.4 ];\n    auto arr = new double[][3];\n    arr[0] = midEnt;\n    arr[1] = lowEnt;\n    arr[2] = highEnt;\n\n    schwartzSort!(entropy, \"a > b\")(arr);\n\n    assert(arr[0] == highEnt);\n    assert(arr[1] == midEnt);\n    assert(arr[2] == lowEnt);\n    assert(isSorted!(\"a > b\")(map!(entropy)(arr)));\n}\n\n@safe unittest\n{\n    import std.algorithm.iteration : map;\n    import std.numeric : entropy;\n\n    auto lowEnt = [ 1.0, 0, 0 ],\n        midEnt = [ 0.1, 0.1, 0.8 ],\n        highEnt = [ 0.31, 0.29, 0.4 ];\n    auto arr = new double[][3];\n    arr[0] = midEnt;\n    arr[1] = lowEnt;\n    arr[2] = highEnt;\n\n    schwartzSort!(entropy, \"a < b\")(arr);\n\n    assert(arr[0] == lowEnt);\n    assert(arr[1] == midEnt);\n    assert(arr[2] == highEnt);\n    assert(isSorted!(\"a < b\")(map!(entropy)(arr)));\n}\n\n@safe unittest\n{\n    // issue 4909\n    import std.typecons : Tuple;\n    Tuple!(char)[] chars;\n    schwartzSort!\"a[0]\"(chars);\n}\n\n@safe unittest\n{\n    // issue 5924\n    import std.typecons : Tuple;\n    Tuple!(char)[] chars;\n    schwartzSort!((Tuple!(char) c){ return c[0]; })(chars);\n}\n\n// partialSort\n/**\nReorders the random-access range `r` such that the range `r[0 .. mid]`\nis the same as if the entire `r` were sorted, and leaves\nthe range `r[mid .. r.length]` in no particular order. Performs\n$(BIGOH r.length * log(mid)) evaluations of `pred`. The\nimplementation simply calls `topN!(less, ss)(r, n)` and then $(D\nsort!(less, ss)(r[0 .. n])).\n\nParams:\n    less = The predicate to sort by.\n    ss = The swapping strategy to use.\n    r = The random-access range to reorder.\n    n = The length of the initial segment of `r` to sort.\n*/\nvoid partialSort(alias less = \"a < b\", SwapStrategy ss = SwapStrategy.unstable,\n    Range)(Range r, size_t n)\nif (isRandomAccessRange!(Range) && hasLength!(Range) && hasSlicing!(Range))\n{\n    partialSort!(less, ss)(r[0 .. n], r[n .. $]);\n}\n\n///\n@system unittest\n{\n    int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ];\n    partialSort(a, 5);\n    assert(a[0 .. 5] == [ 0, 1, 2, 3, 4 ]);\n}\n\n/**\nStores the smallest elements of the two ranges in the left-hand range in sorted order.\n\nParams:\n    less = The predicate to sort by.\n    ss = The swapping strategy to use.\n    r1 = The first range.\n    r2 = The second range.\n */\n\nvoid partialSort(alias less = \"a < b\", SwapStrategy ss = SwapStrategy.unstable,\n    Range1, Range2)(Range1 r1, Range2 r2)\nif (isRandomAccessRange!(Range1) && hasLength!Range1 &&\n    isInputRange!Range2 && is(ElementType!Range1 == ElementType!Range2) &&\n    hasLvalueElements!Range1 && hasLvalueElements!Range2)\n{\n    topN!(less, ss)(r1, r2);\n    sort!(less, ss)(r1);\n}\n///\n@system unittest\n{\n    int[] a = [5, 7, 2, 6, 7];\n    int[] b = [2, 1, 5, 6, 7, 3, 0];\n\n    partialSort(a, b);\n    assert(a == [0, 1, 2, 2, 3]);\n}\n\n// topN\n/**\nReorders the range `r` using `swap` such that `r[nth]` refers\nto the element that would fall there if the range were fully\nsorted. In addition, it also partitions `r` such that all elements\n`e1` from `r[0]` to `r[nth]` satisfy `!less(r[nth], e1)`,\nand all elements `e2` from `r[nth]` to `r[r.length]` satisfy\n`!less(e2, r[nth])`. Effectively, it finds the nth smallest\n(according to `less`) elements in `r`. Performs an expected\n$(BIGOH r.length) (if unstable) or $(BIGOH r.length * log(r.length))\n(if stable) evaluations of `less` and `swap`.\n\nIf `n >= r.length`, the algorithm has no effect and returns\n`r[0 .. r.length]`.\n\nParams:\n    less = The predicate to sort by.\n    ss = The swapping strategy to use.\n    r = The random-access range to reorder.\n    nth = The index of the element that should be in sorted position after the\n        function is done.\n\nSee_Also:\n    $(LREF topNIndex),\n\nBUGS:\n\nStable topN has not been implemented yet.\n*/\nauto topN(alias less = \"a < b\",\n        SwapStrategy ss = SwapStrategy.unstable,\n        Range)(Range r, size_t nth)\nif (isRandomAccessRange!(Range) && hasLength!Range &&\n    hasSlicing!Range && hasAssignableElements!Range)\n{\n    static assert(ss == SwapStrategy.unstable,\n            \"Stable topN not yet implemented\");\n    if (nth >= r.length) return r[0 .. r.length];\n    auto ret = r[0 .. nth];\n    if (false)\n    {\n        // Workaround for https://issues.dlang.org/show_bug.cgi?id=16528\n        // Safety checks: enumerate all potentially unsafe generic primitives\n        // then use a @trusted implementation.\n        cast(void) binaryFun!less(r[0], r[r.length - 1]);\n        import std.algorithm.mutation : swapAt;\n        r.swapAt(size_t(0), size_t(0));\n        static assert(is(typeof(r.length) == size_t));\n        pivotPartition!less(r, 0);\n    }\n    bool useSampling = true;\n    topNImpl!(binaryFun!less)(r, nth, useSampling);\n    return ret;\n}\n\n///\n@safe unittest\n{\n    int[] v = [ 25, 7, 9, 2, 0, 5, 21 ];\n    topN!\"a < b\"(v, 100);\n    assert(v == [ 25, 7, 9, 2, 0, 5, 21 ]);\n    auto n = 4;\n    topN!((a, b) => a < b)(v, n);\n    assert(v[n] == 9);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=8341\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : tuple;\n    auto a = [10, 30, 20];\n    auto b = [\"c\", \"b\", \"a\"];\n    assert(topN!\"a[0] > b[0]\"(zip(a, b), 2).equal([tuple(20, \"a\"), tuple(30, \"b\")]));\n}\n\nprivate @trusted\nvoid topNImpl(alias less, R)(R r, size_t n, ref bool useSampling)\n{\n    for (;;)\n    {\n        import std.algorithm.mutation : swapAt;\n        assert(n < r.length);\n        size_t pivot = void;\n\n        // Decide strategy for partitioning\n        if (n == 0)\n        {\n            pivot = 0;\n            foreach (i; 1 .. r.length)\n                if (less(r[i], r[pivot])) pivot = i;\n            r.swapAt(n, pivot);\n            return;\n        }\n        if (n + 1 == r.length)\n        {\n            pivot = 0;\n            foreach (i; 1 .. r.length)\n                if (less(r[pivot], r[i])) pivot = i;\n            r.swapAt(n, pivot);\n            return;\n        }\n        if (r.length <= 12)\n        {\n            pivot = pivotPartition!less(r, r.length / 2);\n        }\n        else if (n * 16 <= (r.length - 1) * 7)\n        {\n            pivot = topNPartitionOffMedian!(less, No.leanRight)\n                (r, n, useSampling);\n            // Quality check\n            if (useSampling)\n            {\n                if (pivot < n)\n                {\n                    if (pivot * 4 < r.length)\n                    {\n                        useSampling = false;\n                    }\n                }\n                else if ((r.length - pivot) * 8 < r.length * 3)\n                {\n                    useSampling = false;\n                }\n            }\n        }\n        else if (n * 16 >= (r.length - 1) * 9)\n        {\n            pivot = topNPartitionOffMedian!(less, Yes.leanRight)\n                (r, n, useSampling);\n            // Quality check\n            if (useSampling)\n            {\n                if (pivot < n)\n                {\n                    if (pivot * 8 < r.length * 3)\n                    {\n                        useSampling = false;\n                    }\n                }\n                else if ((r.length - pivot) * 4 < r.length)\n                {\n                    useSampling = false;\n                }\n            }\n        }\n        else\n        {\n            pivot = topNPartition!less(r, n, useSampling);\n            // Quality check\n            if (useSampling &&\n                (pivot * 9 < r.length * 2 || pivot * 9 > r.length * 7))\n            {\n                // Failed - abort sampling going forward\n                useSampling = false;\n            }\n        }\n\n        assert(pivot != size_t.max);\n        // See how the pivot fares\n        if (pivot == n)\n        {\n            return;\n        }\n        if (pivot > n)\n        {\n            r = r[0 .. pivot];\n        }\n        else\n        {\n            n -= pivot + 1;\n            r = r[pivot + 1 .. r.length];\n        }\n    }\n}\n\nprivate size_t topNPartition(alias lp, R)(R r, size_t n, bool useSampling)\n{\n    assert(r.length >= 9 && n < r.length);\n    immutable ninth = r.length / 9;\n    auto pivot = ninth / 2;\n    // Position subrange r[lo .. hi] to have length equal to ninth and its upper\n    // median r[lo .. hi][$ / 2] in exactly the same place as the upper median\n    // of the entire range r[$ / 2]. This is to improve behavior for searching\n    // the median in already sorted ranges.\n    immutable lo = r.length / 2 - pivot, hi = lo + ninth;\n    // We have either one straggler on the left, one on the right, or none.\n    assert(lo - (r.length - hi) <= 1 || (r.length - hi) - lo <= 1);\n    assert(lo >= ninth * 4);\n    assert(r.length - hi >= ninth * 4);\n\n    // Partition in groups of 3, and the mid tertile again in groups of 3\n    if (!useSampling)\n        p3!lp(r, lo - ninth, hi + ninth);\n    p3!lp(r, lo, hi);\n\n    // Get the median of medians of medians\n    // Map the full interval of n to the full interval of the ninth\n    pivot = (n * (ninth - 1)) / (r.length - 1);\n    topNImpl!lp(r[lo .. hi], pivot, useSampling);\n    return expandPartition!lp(r, lo, pivot + lo, hi);\n}\n\nprivate void p3(alias less, Range)(Range r, size_t lo, immutable size_t hi)\n{\n    assert(lo <= hi && hi < r.length);\n    immutable ln = hi - lo;\n    for (; lo < hi; ++lo)\n    {\n        assert(lo >= ln);\n        assert(lo + ln < r.length);\n        medianOf!less(r, lo - ln, lo, lo + ln);\n    }\n}\n\nprivate void p4(alias less, Flag!\"leanRight\" f, Range)\n    (Range r, size_t lo, immutable size_t hi)\n{\n    assert(lo <= hi && hi < r.length);\n    immutable ln = hi - lo, _2ln = ln * 2;\n    for (; lo < hi; ++lo)\n    {\n        assert(lo >= ln);\n        assert(lo + ln < r.length);\n        static if (f == Yes.leanRight)\n            medianOf!(less, f)(r, lo - _2ln, lo - ln, lo, lo + ln);\n        else\n            medianOf!(less, f)(r, lo - ln, lo, lo + ln, lo + _2ln);\n    }\n}\n\nprivate size_t topNPartitionOffMedian(alias lp, Flag!\"leanRight\" f, R)\n    (R r, size_t n, bool useSampling)\n{\n    assert(r.length >= 12);\n    assert(n < r.length);\n    immutable _4 = r.length / 4;\n    static if (f == Yes.leanRight)\n        immutable leftLimit = 2 * _4;\n    else\n        immutable leftLimit = _4;\n    // Partition in groups of 4, and the left quartile again in groups of 3\n    if (!useSampling)\n    {\n        p4!(lp, f)(r, leftLimit, leftLimit + _4);\n    }\n    immutable _12 = _4 / 3;\n    immutable lo = leftLimit + _12, hi = lo + _12;\n    p3!lp(r, lo, hi);\n\n    // Get the median of medians of medians\n    // Map the full interval of n to the full interval of the ninth\n    immutable pivot = (n * (_12 - 1)) / (r.length - 1);\n    topNImpl!lp(r[lo .. hi], pivot, useSampling);\n    return expandPartition!lp(r, lo, pivot + lo, hi);\n}\n\n/*\nParams:\nless = predicate\nr = range to partition\npivot = pivot to partition around\nlo = value such that r[lo .. pivot] already less than r[pivot]\nhi = value such that r[pivot .. hi] already greater than r[pivot]\n\nReturns: new position of pivot\n*/\nprivate\nsize_t expandPartition(alias lp, R)(R r, size_t lo, size_t pivot, size_t hi)\nin\n{\n    import std.algorithm.searching : all;\n    assert(lo <= pivot);\n    assert(pivot < hi);\n    assert(hi <= r.length);\n    assert(r[lo .. pivot + 1].all!(x => !lp(r[pivot], x)));\n    assert(r[pivot + 1 .. hi].all!(x => !lp(x, r[pivot])));\n    }\nout\n{\n    import std.algorithm.searching : all;\n    assert(r[0 .. pivot + 1].all!(x => !lp(r[pivot], x)));\n    assert(r[pivot + 1 .. r.length].all!(x => !lp(x, r[pivot])));\n}\ndo\n{\n    import std.algorithm.mutation : swapAt;\n    import std.algorithm.searching : all;\n    // We work with closed intervals!\n    --hi;\n\n    size_t left = 0, rite = r.length - 1;\n    loop: for (;; ++left, --rite)\n    {\n        for (;; ++left)\n        {\n            if (left == lo) break loop;\n            if (!lp(r[left], r[pivot])) break;\n        }\n        for (;; --rite)\n        {\n            if (rite == hi) break loop;\n            if (!lp(r[pivot], r[rite])) break;\n        }\n        r.swapAt(left, rite);\n    }\n\n    assert(r[lo .. pivot + 1].all!(x => !lp(r[pivot], x)));\n    assert(r[pivot + 1 .. hi + 1].all!(x => !lp(x, r[pivot])));\n    assert(r[0 .. left].all!(x => !lp(r[pivot], x)));\n    assert(r[rite + 1 .. r.length].all!(x => !lp(x, r[pivot])));\n\n    immutable oldPivot = pivot;\n\n    if (left < lo)\n    {\n        // First loop: spend r[lo .. pivot]\n        for (; lo < pivot; ++left)\n        {\n            if (left == lo) goto done;\n            if (!lp(r[oldPivot], r[left])) continue;\n            --pivot;\n            assert(!lp(r[oldPivot], r[pivot]));\n            r.swapAt(left, pivot);\n        }\n        // Second loop: make left and pivot meet\n        for (;; ++left)\n        {\n            if (left == pivot) goto done;\n            if (!lp(r[oldPivot], r[left])) continue;\n            for (;;)\n            {\n                if (left == pivot) goto done;\n                --pivot;\n                if (lp(r[pivot], r[oldPivot]))\n                {\n                    r.swapAt(left, pivot);\n                    break;\n                }\n            }\n        }\n    }\n\n    // First loop: spend r[lo .. pivot]\n    for (; hi != pivot; --rite)\n    {\n        if (rite == hi) goto done;\n        if (!lp(r[rite], r[oldPivot])) continue;\n        ++pivot;\n        assert(!lp(r[pivot], r[oldPivot]));\n        r.swapAt(rite, pivot);\n    }\n    // Second loop: make left and pivot meet\n    for (; rite > pivot; --rite)\n    {\n        if (!lp(r[rite], r[oldPivot])) continue;\n        while (rite > pivot)\n        {\n            ++pivot;\n            if (lp(r[oldPivot], r[pivot]))\n            {\n                r.swapAt(rite, pivot);\n                break;\n            }\n        }\n    }\n\ndone:\n    r.swapAt(oldPivot, pivot);\n    return pivot;\n}\n\n@safe unittest\n{\n    auto a = [ 10, 5, 3, 4, 8,  11,  13, 3, 9, 4, 10 ];\n    assert(expandPartition!((a, b) => a < b)(a, 4, 5, 6) == 9);\n\n    import std.algorithm.iteration : map;\n    import std.random : uniform;\n    auto size = uniform(1, 1000);\n    a = iota(0, size).map!(_ => uniform(0, 1000)).array;\n    if (a.length == 0) return;\n    expandPartition!((a, b) => a < b)(a, a.length / 2, a.length / 2,\n        a.length / 2 + 1);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : max, min;\n    import std.algorithm.iteration : reduce;\n\n    int[] v = [ 7, 6, 5, 4, 3, 2, 1, 0 ];\n    ptrdiff_t n = 3;\n    topN!(\"a < b\")(v, n);\n    assert(reduce!max(v[0 .. n]) <= v[n]);\n    assert(reduce!min(v[n + 1 .. $]) >= v[n]);\n    //\n    v = [3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5];\n    n = 3;\n    topN(v, n);\n    assert(reduce!max(v[0 .. n]) <= v[n]);\n    assert(reduce!min(v[n + 1 .. $]) >= v[n]);\n    //\n    v = [3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5];\n    n = 1;\n    topN(v, n);\n    assert(reduce!max(v[0 .. n]) <= v[n]);\n    assert(reduce!min(v[n + 1 .. $]) >= v[n]);\n    //\n    v = [3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5];\n    n = v.length - 1;\n    topN(v, n);\n    assert(v[n] == 7);\n    //\n    v = [3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5];\n    n = 0;\n    topN(v, n);\n    assert(v[n] == 1);\n\n    double[][] v1 = [[-10, -5], [-10, -3], [-10, -5], [-10, -4],\n            [-10, -5], [-9, -5], [-9, -3], [-9, -5],];\n\n    // double[][] v1 = [ [-10, -5], [-10, -4], [-9, -5], [-9, -5],\n    //         [-10, -5], [-10, -3], [-10, -5], [-9, -3],];\n    double[]*[] idx = [ &v1[0], &v1[1], &v1[2], &v1[3], &v1[4], &v1[5], &v1[6],\n            &v1[7], ];\n\n    auto mid = v1.length / 2;\n    topN!((a, b){ return (*a)[1] < (*b)[1]; })(idx, mid);\n    foreach (e; idx[0 .. mid]) assert((*e)[1] <= (*idx[mid])[1]);\n    foreach (e; idx[mid .. $]) assert((*e)[1] >= (*idx[mid])[1]);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : max, min;\n    import std.algorithm.iteration : reduce;\n    import std.random : Random = Xorshift, uniform;\n\n    immutable uint[] seeds = [90027751, 2709791795, 1374631933, 995751648, 3541495258, 984840953];\n    foreach (s; seeds)\n    {\n        auto r = Random(s);\n\n        int[] a = new int[uniform(1, 10000, r)];\n        foreach (ref e; a) e = uniform(-1000, 1000, r);\n\n        auto k = uniform(0, a.length, r);\n        topN(a, k);\n        if (k > 0)\n        {\n            auto left = reduce!max(a[0 .. k]);\n            assert(left <= a[k]);\n        }\n        if (k + 1 < a.length)\n        {\n            auto right = reduce!min(a[k + 1 .. $]);\n            assert(right >= a[k]);\n        }\n    }\n}\n\n// bug 12987\n@safe unittest\n{\n    int[] a = [ 25, 7, 9, 2, 0, 5, 21 ];\n    auto n = 4;\n    auto t = topN(a, n);\n    sort(t);\n    assert(t == [0, 2, 5, 7]);\n}\n\n/**\nStores the smallest elements of the two ranges in the left-hand range.\n\nParams:\n    less = The predicate to sort by.\n    ss = The swapping strategy to use.\n    r1 = The first range.\n    r2 = The second range.\n */\nauto topN(alias less = \"a < b\",\n        SwapStrategy ss = SwapStrategy.unstable,\n        Range1, Range2)(Range1 r1, Range2 r2)\nif (isRandomAccessRange!(Range1) && hasLength!Range1 &&\n    isInputRange!Range2 && is(ElementType!Range1 == ElementType!Range2) &&\n    hasLvalueElements!Range1 && hasLvalueElements!Range2)\n{\n    import std.container : BinaryHeap;\n\n    static assert(ss == SwapStrategy.unstable,\n            \"Stable topN not yet implemented\");\n\n    auto heap = BinaryHeap!(Range1, less)(r1);\n    foreach (ref e; r2)\n    {\n        heap.conditionalSwap(e);\n    }\n\n    return r1;\n}\n\n///\n@system unittest\n{\n    int[] a = [ 5, 7, 2, 6, 7 ];\n    int[] b = [ 2, 1, 5, 6, 7, 3, 0 ];\n    topN(a, b);\n    sort(a);\n    assert(a == [0, 1, 2, 2, 3]);\n}\n\n// bug 15421\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange;\n    import std.meta : AliasSeq;\n\n    alias RandomRanges = AliasSeq!(\n        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random)\n    );\n\n    alias ReferenceRanges = AliasSeq!(\n        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Forward),\n        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Bidirectional),\n        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random),\n        DummyRange!(ReturnBy.Reference, Length.No, RangeType.Forward),\n        DummyRange!(ReturnBy.Reference, Length.No, RangeType.Bidirectional));\n\n    foreach (T1; RandomRanges)\n    {\n        foreach (T2; ReferenceRanges)\n        {\n            import std.array;\n\n            T1 A;\n            T2 B;\n\n            A.reinit();\n            B.reinit();\n\n            topN(A, B);\n\n            // BUG(?): sort doesn't accept DummyRanges (needs Slicing and Length)\n            auto a = array(A);\n            auto b = array(B);\n            sort(a);\n            sort(b);\n\n            assert(equal(a, [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 ]));\n            assert(equal(b, [ 6, 6, 7, 7, 8, 8, 9, 9, 10, 10 ]));\n        }\n    }\n}\n\n// bug 15421\n@system unittest\n{\n    auto a = [ 9, 8, 0, 3, 5, 25, 43, 4, 2, 0, 7 ];\n    auto b = [ 9, 8, 0, 3, 5, 25, 43, 4, 2, 0, 7 ];\n\n    topN(a, 4);\n    topN(b[0 .. 4], b[4 .. $]);\n\n    sort(a[0 .. 4]);\n    sort(a[4 .. $]);\n    sort(b[0 .. 4]);\n    sort(b[4 .. $]);\n\n    assert(a[0 .. 4] == b[0 .. 4]);\n    assert(a[4 .. $] == b[4 .. $]);\n    assert(a == b);\n}\n\n// bug 12987\n@system unittest\n{\n    int[] a = [ 5, 7, 2, 6, 7 ];\n    int[] b = [ 2, 1, 5, 6, 7, 3, 0 ];\n    auto t = topN(a, b);\n    sort(t);\n    assert(t == [ 0, 1, 2, 2, 3 ]);\n}\n\n// bug 15420\n@system unittest\n{\n    int[] a = [ 5, 7, 2, 6, 7 ];\n    int[] b = [ 2, 1, 5, 6, 7, 3, 0 ];\n    topN!\"a > b\"(a, b);\n    sort!\"a > b\"(a);\n    assert(a == [ 7, 7, 7, 6, 6 ]);\n}\n\n/**\nCopies the top `n` elements of the\n$(REF_ALTTEXT input range, isInputRange, std,range,primitives) `source` into the\nrandom-access range `target`, where `n = target.length`.\nElements of `source` are not touched. If $(D\nsorted) is `true`, the target is sorted. Otherwise, the target\nrespects the $(HTTP en.wikipedia.org/wiki/Binary_heap, heap property).\n\nParams:\n    less = The predicate to sort by.\n    source = The source range.\n    target = The target range.\n    sorted = Whether to sort the elements copied into `target`.\n\nReturns: The slice of `target` containing the copied elements.\n */\nTRange topNCopy(alias less = \"a < b\", SRange, TRange)\n    (SRange source, TRange target, SortOutput sorted = No.sortOutput)\nif (isInputRange!(SRange) && isRandomAccessRange!(TRange)\n    && hasLength!(TRange) && hasSlicing!(TRange))\n{\n    import std.container : BinaryHeap;\n\n    if (target.empty) return target;\n    auto heap = BinaryHeap!(TRange, less)(target, 0);\n    foreach (e; source) heap.conditionalInsert(e);\n    auto result = target[0 .. heap.length];\n    if (sorted == Yes.sortOutput)\n    {\n        while (!heap.empty) heap.removeFront();\n    }\n    return result;\n}\n\n///\n@system unittest\n{\n    import std.typecons : Yes;\n\n    int[] a = [ 10, 16, 2, 3, 1, 5, 0 ];\n    int[] b = new int[3];\n    topNCopy(a, b, Yes.sortOutput);\n    assert(b == [ 0, 1, 2 ]);\n}\n\n@system unittest\n{\n    import std.random : Random = Xorshift, uniform, randomShuffle;\n    import std.typecons : Yes;\n\n    auto r = Random(123_456_789);\n    ptrdiff_t[] a = new ptrdiff_t[uniform(1, 1000, r)];\n    foreach (i, ref e; a) e = i;\n    randomShuffle(a, r);\n    auto n = uniform(0, a.length, r);\n    ptrdiff_t[] b = new ptrdiff_t[n];\n    topNCopy!(binaryFun!(\"a < b\"))(a, b, Yes.sortOutput);\n    assert(isSorted!(binaryFun!(\"a < b\"))(b));\n}\n\n/**\nGiven a range of elements, constructs an index of its top $(I n) elements\n(i.e., the first $(I n) elements if the range were sorted).\n\nSimilar to $(LREF topN), except that the range is not modified.\n\nParams:\n    less = A binary predicate that defines the ordering of range elements.\n        Defaults to `a < b`.\n    ss = $(RED (Not implemented yet.)) Specify the swapping strategy.\n    r = A\n        $(REF_ALTTEXT random-access range, isRandomAccessRange, std,range,primitives)\n        of elements to make an index for.\n    index = A\n        $(REF_ALTTEXT random-access range, isRandomAccessRange, std,range,primitives)\n        with assignable elements to build the index in. The length of this range\n        determines how many top elements to index in `r`.\n\n        This index range can either have integral elements, in which case the\n        constructed index will consist of zero-based numerical indices into\n        `r`; or it can have pointers to the element type of `r`, in which\n        case the constructed index will be pointers to the top elements in\n        `r`.\n    sorted = Determines whether to sort the index by the elements they refer\n        to.\n\nSee_also: $(LREF topN), $(LREF topNCopy).\n\nBUGS:\nThe swapping strategy parameter is not implemented yet; currently it is\nignored.\n*/\nvoid topNIndex(alias less = \"a < b\", SwapStrategy ss = SwapStrategy.unstable,\n               Range, RangeIndex)\n              (Range r, RangeIndex index, SortOutput sorted = No.sortOutput)\nif (isRandomAccessRange!Range &&\n    isRandomAccessRange!RangeIndex &&\n    hasAssignableElements!RangeIndex)\n{\n    static assert(ss == SwapStrategy.unstable,\n                  \"Stable swap strategy not implemented yet.\");\n\n    import std.container.binaryheap : BinaryHeap;\n    if (index.empty) return;\n\n    static if (isIntegral!(ElementType!(RangeIndex)))\n    {\n        import std.exception : enforce;\n\n        enforce(ElementType!(RangeIndex).max >= index.length,\n                \"Index type too small\");\n        bool indirectLess(ElementType!(RangeIndex) a, ElementType!(RangeIndex) b)\n        {\n            return binaryFun!(less)(r[a], r[b]);\n        }\n        auto heap = BinaryHeap!(RangeIndex, indirectLess)(index, 0);\n        foreach (i; 0 .. r.length)\n        {\n            heap.conditionalInsert(cast(ElementType!RangeIndex) i);\n        }\n\n    }\n    else static if (is(ElementType!(RangeIndex) == ElementType!(Range)*))\n    {\n        static bool indirectLess(const ElementType!(RangeIndex) a,\n                                 const ElementType!(RangeIndex) b)\n        {\n            return binaryFun!less(*a, *b);\n        }\n        auto heap = BinaryHeap!(RangeIndex, indirectLess)(index, 0);\n        foreach (i; 0 .. r.length)\n        {\n            heap.conditionalInsert(&r[i]);\n        }\n    }\n    else static assert(0, \"Invalid ElementType\");\n\n    if (sorted == Yes.sortOutput)\n    {\n        while (!heap.empty) heap.removeFront();\n    }\n}\n\n///\n@system unittest\n{\n    import std.typecons : Yes;\n\n    // Construct index to top 3 elements using numerical indices:\n    int[] a = [ 10, 2, 7, 5, 8, 1 ];\n    int[] index = new int[3];\n    topNIndex(a, index, Yes.sortOutput);\n    assert(index == [5, 1, 3]); // because a[5]==1, a[1]==2, a[3]==5\n\n    // Construct index to top 3 elements using pointer indices:\n    int*[] ptrIndex = new int*[3];\n    topNIndex(a, ptrIndex, Yes.sortOutput);\n    assert(ptrIndex == [ &a[5], &a[1], &a[3] ]);\n}\n\n@system unittest\n{\n    import std.conv : text;\n\n    {\n        int[] a = [ 10, 8, 9, 2, 4, 6, 7, 1, 3, 5 ];\n        int*[] b = new int*[5];\n        topNIndex!(\"a > b\")(a, b, Yes.sortOutput);\n        assert(b == [ &a[0], &a[2], &a[1], &a[6], &a[5]]);\n    }\n    {\n        int[] a = [ 10, 8, 9, 2, 4, 6, 7, 1, 3, 5 ];\n        auto b = new ubyte[5];\n        topNIndex!(\"a > b\")(a, b, Yes.sortOutput);\n        assert(b == [ cast(ubyte) 0, cast(ubyte) 2, cast(ubyte) 1, cast(ubyte) 6, cast(ubyte) 5], text(b));\n    }\n}\n\n// medianOf\n/*\nPrivate for the time being.\n\nComputes the median of 2 to 5 arbitrary indexes in random-access range `r`\nusing hand-written specialized algorithms. The indexes must be distinct (if not,\nbehavior is implementation-defined). The function also partitions the elements\ninvolved around the median, e.g. `medianOf(r, a, b, c)` not only fills `r[b]`\nwith the median of `r[a]`, `r[b]`, and `r[c]`, but also puts the minimum in\n`r[a]` and the maximum in `r[c]`.\n\nParams:\nless = The comparison predicate used, modeled as a\n    $(LINK2 https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings, strict weak ordering)\n    (irreflexive, antisymmetric, transitive, and implying a transitive equivalence).\nflag = Used only for even values of `T.length`. If `No.leanRight`, the median\n\"leans left\", meaning `medianOf(r, a, b, c, d)` puts the lower median of the\nfour in `r[b]`, the minimum in `r[a]`, and the two others in `r[c]` and `r[d]`.\nConversely, `median!(\"a < b\", Yes.leanRight)(r, a, b, c, d)` puts the upper\nmedian of the four in `r[c]`, the maximum in `r[d]`, and the two others in\n`r[a]` and `r[b]`.\nr = The range containing the indexes.\ni = Two to five indexes inside `r`.\n*/\nprivate void medianOf(\n        alias less = \"a < b\",\n        Flag!\"leanRight\" flag = No.leanRight,\n        Range,\n        Indexes...)\n    (Range r, Indexes i)\nif (isRandomAccessRange!Range && hasLength!Range &&\n    Indexes.length >= 2 && Indexes.length <= 5 &&\n    allSatisfy!(isUnsigned, Indexes))\n{\n    assert(r.length >= Indexes.length);\n    import std.functional : binaryFun;\n    alias lt = binaryFun!less;\n    enum k = Indexes.length;\n    import std.algorithm.mutation : swapAt;\n\n    alias a = i[0];\n    static assert(is(typeof(a) == size_t));\n    static if (k >= 2)\n    {\n        alias b = i[1];\n        static assert(is(typeof(b) == size_t));\n        assert(a != b);\n    }\n    static if (k >= 3)\n    {\n        alias c = i[2];\n        static assert(is(typeof(c) == size_t));\n        assert(a != c && b != c);\n    }\n    static if (k >= 4)\n    {\n        alias d = i[3];\n        static assert(is(typeof(d) == size_t));\n        assert(a != d && b != d && c != d);\n    }\n    static if (k >= 5)\n    {\n        alias e = i[4];\n        static assert(is(typeof(e) == size_t));\n        assert(a != e && b != e && c != e && d != e);\n    }\n\n    static if (k == 2)\n    {\n        if (lt(r[b], r[a])) r.swapAt(a, b);\n    }\n    else static if (k == 3)\n    {\n        if (lt(r[c], r[a])) // c < a\n        {\n            if (lt(r[a], r[b])) // c < a < b\n            {\n                r.swapAt(a, b);\n                r.swapAt(a, c);\n            }\n            else // c < a, b <= a\n            {\n                r.swapAt(a, c);\n                if (lt(r[b], r[a])) r.swapAt(a, b);\n            }\n        }\n        else // a <= c\n        {\n            if (lt(r[b], r[a])) // b < a <= c\n            {\n                r.swapAt(a, b);\n            }\n            else // a <= c, a <= b\n            {\n                if (lt(r[c], r[b])) r.swapAt(b, c);\n            }\n        }\n        assert(!lt(r[b], r[a]));\n        assert(!lt(r[c], r[b]));\n    }\n    else static if (k == 4)\n    {\n        static if (flag == No.leanRight)\n        {\n            // Eliminate the rightmost from the competition\n            if (lt(r[d], r[c])) r.swapAt(c, d); // c <= d\n            if (lt(r[d], r[b])) r.swapAt(b, d); // b <= d\n            medianOf!lt(r, a, b, c);\n        }\n        else\n        {\n            // Eliminate the leftmost from the competition\n            if (lt(r[b], r[a])) r.swapAt(a, b); // a <= b\n            if (lt(r[c], r[a])) r.swapAt(a, c); // a <= c\n            medianOf!lt(r, b, c, d);\n        }\n    }\n    else static if (k == 5)\n    {\n        // Credit: Teppo Niinimäki\n        version (unittest) scope(success)\n        {\n            assert(!lt(r[c], r[a]));\n            assert(!lt(r[c], r[b]));\n            assert(!lt(r[d], r[c]));\n            assert(!lt(r[e], r[c]));\n        }\n\n        if (lt(r[c], r[a])) r.swapAt(a, c);\n        if (lt(r[d], r[b])) r.swapAt(b, d);\n        if (lt(r[d], r[c]))\n        {\n            r.swapAt(c, d);\n            r.swapAt(a, b);\n        }\n        if (lt(r[e], r[b])) r.swapAt(b, e);\n        if (lt(r[e], r[c]))\n        {\n            r.swapAt(c, e);\n            if (lt(r[c], r[a])) r.swapAt(a, c);\n        }\n        else\n        {\n            if (lt(r[c], r[b])) r.swapAt(b, c);\n        }\n    }\n}\n\n@safe unittest\n{\n    // Verify medianOf for all permutations of [1, 2, 2, 3, 4].\n    int[5] data = [1, 2, 2, 3, 4];\n    do\n    {\n        int[5] a = data;\n        medianOf(a[], size_t(0), size_t(1));\n        assert(a[0] <= a[1]);\n\n        a[] = data[];\n        medianOf(a[], size_t(0), size_t(1), size_t(2));\n        assert(ordered(a[0], a[1], a[2]));\n\n        a[] = data[];\n        medianOf(a[], size_t(0), size_t(1), size_t(2), size_t(3));\n        assert(a[0] <= a[1] && a[1] <= a[2] && a[1] <= a[3]);\n\n        a[] = data[];\n        medianOf!(\"a < b\", Yes.leanRight)(a[], size_t(0), size_t(1),\n            size_t(2), size_t(3));\n        assert(a[0] <= a[2] && a[1] <= a[2] && a[2] <= a[3]);\n\n        a[] = data[];\n        medianOf(a[], size_t(0), size_t(1), size_t(2), size_t(3), size_t(4));\n        assert(a[0] <= a[2] && a[1] <= a[2] && a[2] <= a[3] && a[2] <= a[4]);\n    }\n    while (nextPermutation(data[]));\n}\n\n// nextPermutation\n/**\n * Permutes `range` in-place to the next lexicographically greater\n * permutation.\n *\n * The predicate `less` defines the lexicographical ordering to be used on\n * the range.\n *\n * If the range is currently the lexicographically greatest permutation, it is\n * permuted back to the least permutation and false is returned.  Otherwise,\n * true is returned. One can thus generate all permutations of a range by\n * sorting it according to `less`, which produces the lexicographically\n * least permutation, and then calling nextPermutation until it returns false.\n * This is guaranteed to generate all distinct permutations of the range\n * exactly once.  If there are $(I N) elements in the range and all of them are\n * unique, then $(I N)! permutations will be generated. Otherwise, if there are\n * some duplicated elements, fewer permutations will be produced.\n----\n// Enumerate all permutations\nint[] a = [1,2,3,4,5];\ndo\n{\n    // use the current permutation and\n    // proceed to the next permutation of the array.\n} while (nextPermutation(a));\n----\n * Params:\n *  less = The ordering to be used to determine lexicographical ordering of the\n *      permutations.\n *  range = The range to permute.\n *\n * Returns: false if the range was lexicographically the greatest, in which\n * case the range is reversed back to the lexicographically smallest\n * permutation; otherwise returns true.\n * See_Also:\n * $(REF permutations, std,algorithm,iteration).\n */\nbool nextPermutation(alias less=\"a < b\", BidirectionalRange)\n                    (BidirectionalRange range)\nif (isBidirectionalRange!BidirectionalRange &&\n    hasSwappableElements!BidirectionalRange)\n{\n    import std.algorithm.mutation : reverse, swap;\n    import std.algorithm.searching : find;\n    import std.range : retro, takeExactly;\n    // Ranges of 0 or 1 element have no distinct permutations.\n    if (range.empty) return false;\n\n    auto i = retro(range);\n    auto last = i.save;\n\n    // Find last occurring increasing pair of elements\n    size_t n = 1;\n    for (i.popFront(); !i.empty; i.popFront(), last.popFront(), n++)\n    {\n        if (binaryFun!less(i.front, last.front))\n            break;\n    }\n\n    if (i.empty)\n    {\n        // Entire range is decreasing: it's lexicographically the greatest. So\n        // wrap it around.\n        range.reverse();\n        return false;\n    }\n\n    // Find last element greater than i.front.\n    auto j = find!((a) => binaryFun!less(i.front, a))(\n                   takeExactly(retro(range), n));\n\n    assert(!j.empty);   // shouldn't happen since i.front < last.front\n    swap(i.front, j.front);\n    reverse(takeExactly(retro(range), n));\n\n    return true;\n}\n\n///\n@safe unittest\n{\n    // Step through all permutations of a sorted array in lexicographic order\n    int[] a = [1,2,3];\n    assert(nextPermutation(a) == true);\n    assert(a == [1,3,2]);\n    assert(nextPermutation(a) == true);\n    assert(a == [2,1,3]);\n    assert(nextPermutation(a) == true);\n    assert(a == [2,3,1]);\n    assert(nextPermutation(a) == true);\n    assert(a == [3,1,2]);\n    assert(nextPermutation(a) == true);\n    assert(a == [3,2,1]);\n    assert(nextPermutation(a) == false);\n    assert(a == [1,2,3]);\n}\n\n///\n@safe unittest\n{\n    // Step through permutations of an array containing duplicate elements:\n    int[] a = [1,1,2];\n    assert(nextPermutation(a) == true);\n    assert(a == [1,2,1]);\n    assert(nextPermutation(a) == true);\n    assert(a == [2,1,1]);\n    assert(nextPermutation(a) == false);\n    assert(a == [1,1,2]);\n}\n\n@safe unittest\n{\n    // Boundary cases: arrays of 0 or 1 element.\n    int[] a1 = [];\n    assert(!nextPermutation(a1));\n    assert(a1 == []);\n\n    int[] a2 = [1];\n    assert(!nextPermutation(a2));\n    assert(a2 == [1]);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto a1 = [1, 2, 3, 4];\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [1, 2, 4, 3]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [1, 3, 2, 4]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [1, 3, 4, 2]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [1, 4, 2, 3]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [1, 4, 3, 2]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [2, 1, 3, 4]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [2, 1, 4, 3]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [2, 3, 1, 4]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [2, 3, 4, 1]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [2, 4, 1, 3]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [2, 4, 3, 1]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [3, 1, 2, 4]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [3, 1, 4, 2]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [3, 2, 1, 4]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [3, 2, 4, 1]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [3, 4, 1, 2]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [3, 4, 2, 1]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [4, 1, 2, 3]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [4, 1, 3, 2]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [4, 2, 1, 3]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [4, 2, 3, 1]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [4, 3, 1, 2]));\n\n    assert(nextPermutation(a1));\n    assert(equal(a1, [4, 3, 2, 1]));\n\n    assert(!nextPermutation(a1));\n    assert(equal(a1, [1, 2, 3, 4]));\n}\n\n@safe unittest\n{\n    // Test with non-default sorting order\n    int[] a = [3,2,1];\n    assert(nextPermutation!\"a > b\"(a) == true);\n    assert(a == [3,1,2]);\n    assert(nextPermutation!\"a > b\"(a) == true);\n    assert(a == [2,3,1]);\n    assert(nextPermutation!\"a > b\"(a) == true);\n    assert(a == [2,1,3]);\n    assert(nextPermutation!\"a > b\"(a) == true);\n    assert(a == [1,3,2]);\n    assert(nextPermutation!\"a > b\"(a) == true);\n    assert(a == [1,2,3]);\n    assert(nextPermutation!\"a > b\"(a) == false);\n    assert(a == [3,2,1]);\n}\n\n// Issue 13594\n@safe unittest\n{\n    int[3] a = [1,2,3];\n    assert(nextPermutation(a[]));\n    assert(a == [1,3,2]);\n}\n\n// nextEvenPermutation\n/**\n * Permutes `range` in-place to the next lexicographically greater $(I even)\n * permutation.\n *\n * The predicate `less` defines the lexicographical ordering to be used on\n * the range.\n *\n * An even permutation is one which is produced by swapping an even number of\n * pairs of elements in the original range. The set of $(I even) permutations\n * is distinct from the set of $(I all) permutations only when there are no\n * duplicate elements in the range. If the range has $(I N) unique elements,\n * then there are exactly $(I N)!/2 even permutations.\n *\n * If the range is already the lexicographically greatest even permutation, it\n * is permuted back to the least even permutation and false is returned.\n * Otherwise, true is returned, and the range is modified in-place to be the\n * lexicographically next even permutation.\n *\n * One can thus generate the even permutations of a range with unique elements\n * by starting with the lexicographically smallest permutation, and repeatedly\n * calling nextEvenPermutation until it returns false.\n----\n// Enumerate even permutations\nint[] a = [1,2,3,4,5];\ndo\n{\n    // use the current permutation and\n    // proceed to the next even permutation of the array.\n} while (nextEvenPermutation(a));\n----\n * One can also generate the $(I odd) permutations of a range by noting that\n * permutations obey the rule that even + even = even, and odd + even = odd.\n * Thus, by swapping the last two elements of a lexicographically least range,\n * it is turned into the first odd permutation. Then calling\n * nextEvenPermutation on this first odd permutation will generate the next\n * even permutation relative to this odd permutation, which is actually the\n * next odd permutation of the original range. Thus, by repeatedly calling\n * nextEvenPermutation until it returns false, one enumerates the odd\n * permutations of the original range.\n----\n// Enumerate odd permutations\nint[] a = [1,2,3,4,5];\nswap(a[$-2], a[$-1]);    // a is now the first odd permutation of [1,2,3,4,5]\ndo\n{\n    // use the current permutation and\n    // proceed to the next odd permutation of the original array\n    // (which is an even permutation of the first odd permutation).\n} while (nextEvenPermutation(a));\n----\n *\n * Warning: Since even permutations are only distinct from all permutations\n * when the range elements are unique, this function assumes that there are no\n * duplicate elements under the specified ordering. If this is not _true, some\n * permutations may fail to be generated. When the range has non-unique\n * elements, you should use $(MYREF nextPermutation) instead.\n *\n * Params:\n *  less = The ordering to be used to determine lexicographical ordering of the\n *      permutations.\n *  range = The range to permute.\n *\n * Returns: false if the range was lexicographically the greatest, in which\n * case the range is reversed back to the lexicographically smallest\n * permutation; otherwise returns true.\n */\nbool nextEvenPermutation(alias less=\"a < b\", BidirectionalRange)\n                        (BidirectionalRange range)\nif (isBidirectionalRange!BidirectionalRange &&\n    hasSwappableElements!BidirectionalRange)\n{\n    import std.algorithm.mutation : reverse, swap;\n    import std.algorithm.searching : find;\n    import std.range : retro, takeExactly;\n    // Ranges of 0 or 1 element have no distinct permutations.\n    if (range.empty) return false;\n\n    bool oddParity = false;\n    bool ret = true;\n    do\n    {\n        auto i = retro(range);\n        auto last = i.save;\n\n        // Find last occurring increasing pair of elements\n        size_t n = 1;\n        for (i.popFront(); !i.empty;\n            i.popFront(), last.popFront(), n++)\n        {\n            if (binaryFun!less(i.front, last.front))\n                break;\n        }\n\n        if (!i.empty)\n        {\n            // Find last element greater than i.front.\n            auto j = find!((a) => binaryFun!less(i.front, a))(\n                           takeExactly(retro(range), n));\n\n            // shouldn't happen since i.front < last.front\n            assert(!j.empty);\n\n            swap(i.front, j.front);\n            oddParity = !oddParity;\n        }\n        else\n        {\n            // Entire range is decreasing: it's lexicographically\n            // the greatest.\n            ret = false;\n        }\n\n        reverse(takeExactly(retro(range), n));\n        if ((n / 2) % 2 == 1)\n            oddParity = !oddParity;\n    } while (oddParity);\n\n    return ret;\n}\n\n///\n@safe unittest\n{\n    // Step through even permutations of a sorted array in lexicographic order\n    int[] a = [1,2,3];\n    assert(nextEvenPermutation(a) == true);\n    assert(a == [2,3,1]);\n    assert(nextEvenPermutation(a) == true);\n    assert(a == [3,1,2]);\n    assert(nextEvenPermutation(a) == false);\n    assert(a == [1,2,3]);\n}\n\n@safe unittest\n{\n    auto a3 = [ 1, 2, 3, 4 ];\n    int count = 1;\n    while (nextEvenPermutation(a3)) count++;\n    assert(count == 12);\n}\n\n@safe unittest\n{\n    // Test with non-default sorting order\n    auto a = [ 3, 2, 1 ];\n\n    assert(nextEvenPermutation!\"a > b\"(a) == true);\n    assert(a == [ 2, 1, 3 ]);\n    assert(nextEvenPermutation!\"a > b\"(a) == true);\n    assert(a == [ 1, 3, 2 ]);\n    assert(nextEvenPermutation!\"a > b\"(a) == false);\n    assert(a == [ 3, 2, 1 ]);\n}\n\n@safe unittest\n{\n    // Test various cases of rollover\n    auto a = [ 3, 1, 2 ];\n    assert(nextEvenPermutation(a) == false);\n    assert(a == [ 1, 2, 3 ]);\n\n    auto b = [ 3, 2, 1 ];\n    assert(nextEvenPermutation(b) == false);\n    assert(b == [ 1, 3, 2 ]);\n}\n\n@safe unittest\n{\n    // Issue 13594\n    int[3] a = [1,2,3];\n    assert(nextEvenPermutation(a[]));\n    assert(a == [2,3,1]);\n}\n\n/**\nEven permutations are useful for generating coordinates of certain geometric\nshapes. Here's a non-trivial example:\n*/\n@safe unittest\n{\n    import std.math : sqrt;\n\n    // Print the 60 vertices of a uniform truncated icosahedron (soccer ball)\n    enum real Phi = (1.0 + sqrt(5.0)) / 2.0;    // Golden ratio\n    real[][] seeds = [\n        [0.0, 1.0, 3.0*Phi],\n        [1.0, 2.0+Phi, 2.0*Phi],\n        [Phi, 2.0, Phi^^3]\n    ];\n    size_t n;\n    foreach (seed; seeds)\n    {\n        // Loop over even permutations of each seed\n        do\n        {\n            // Loop over all sign changes of each permutation\n            size_t i;\n            do\n            {\n                // Generate all possible sign changes\n                for (i=0; i < seed.length; i++)\n                {\n                    if (seed[i] != 0.0)\n                    {\n                        seed[i] = -seed[i];\n                        if (seed[i] < 0.0)\n                            break;\n                    }\n                }\n                n++;\n            } while (i < seed.length);\n        } while (nextEvenPermutation(seed));\n    }\n    assert(n == 60);\n}\n"
  },
  {
    "path": "libphobos/src/std/array.d",
    "content": "// Written in the D programming language.\n/**\nFunctions and types that manipulate built-in arrays and associative arrays.\n\nThis module provides all kinds of functions to create, manipulate or convert arrays:\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE ,\n$(TR $(TH Function Name) $(TH Description)\n)\n    $(TR $(TD $(LREF array))\n        $(TD Returns a copy of the input in a newly allocated dynamic array.\n    ))\n    $(TR $(TD $(LREF appender))\n        $(TD Returns a new $(LREF Appender) or $(LREF RefAppender) initialized with a given array.\n    ))\n    $(TR $(TD $(LREF assocArray))\n        $(TD Returns a newly allocated associative array from a range of key/value tuples.\n    ))\n    $(TR $(TD $(LREF byPair))\n        $(TD Construct a range iterating over an associative array by key/value tuples.\n    ))\n    $(TR $(TD $(LREF insertInPlace))\n        $(TD Inserts into an existing array at a given position.\n    ))\n    $(TR $(TD $(LREF join))\n        $(TD Concatenates a range of ranges into one array.\n    ))\n    $(TR $(TD $(LREF minimallyInitializedArray))\n        $(TD Returns a new array of type `T`.\n    ))\n    $(TR $(TD $(LREF replace))\n        $(TD Returns a new array with all occurrences of a certain subrange replaced.\n    ))\n    $(TR $(TD $(LREF replaceFirst))\n        $(TD Returns a new array with the first occurrence of a certain subrange replaced.\n    ))\n    $(TR $(TD $(LREF replaceInPlace))\n        $(TD Replaces all occurrences of a certain subrange and puts the result into a given array.\n    ))\n    $(TR $(TD $(LREF replaceInto))\n        $(TD Replaces all occurrences of a certain subrange and puts the result into an output range.\n    ))\n    $(TR $(TD $(LREF replaceLast))\n        $(TD Returns a new array with the last occurrence of a certain subrange replaced.\n    ))\n    $(TR $(TD $(LREF replaceSlice))\n        $(TD Returns a new array with a given slice replaced.\n    ))\n    $(TR $(TD $(LREF replicate))\n        $(TD Creates a new array out of several copies of an input array or range.\n    ))\n    $(TR $(TD $(LREF sameHead))\n        $(TD Checks if the initial segments of two arrays refer to the same\n        place in memory.\n    ))\n    $(TR $(TD $(LREF sameTail))\n        $(TD Checks if the final segments of two arrays refer to the same place\n        in memory.\n    ))\n    $(TR $(TD $(LREF split))\n        $(TD Eagerly split a range or string into an array.\n    ))\n    $(TR $(TD $(LREF uninitializedArray))\n        $(TD Returns a new array of type `T` without initializing its elements.\n    ))\n)\n\nCopyright: Copyright Andrei Alexandrescu 2008- and Jonathan M Davis 2011-.\n\nLicense:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors:   $(HTTP erdani.org, Andrei Alexandrescu) and\n           $(HTTP jmdavisprog.com, Jonathan M Davis)\n\nSource: $(PHOBOSSRC std/array.d)\n*/\nmodule std.array;\n\nimport std.functional;\nimport std.meta;\nimport std.traits;\n\nimport std.range.primitives;\npublic import std.range.primitives : save, empty, popFront, popBack, front, back;\n\n/**\n * Allocates an array and initializes it with copies of the elements\n * of range `r`.\n *\n * Narrow strings are handled as a special case in an overload.\n *\n * Params:\n *      r = range (or aggregate with `opApply` function) whose elements are copied into the allocated array\n * Returns:\n *      allocated and initialized array\n */\nForeachType!Range[] array(Range)(Range r)\nif (isIterable!Range && !isNarrowString!Range && !isInfinite!Range)\n{\n    if (__ctfe)\n    {\n        // Compile-time version to avoid memcpy calls.\n        // Also used to infer attributes of array().\n        typeof(return) result;\n        foreach (e; r)\n            result ~= e;\n        return result;\n    }\n\n    alias E = ForeachType!Range;\n    static if (hasLength!Range)\n    {\n        auto length = r.length;\n        if (length == 0)\n            return null;\n\n        import std.conv : emplaceRef;\n\n        auto result = (() @trusted => uninitializedArray!(Unqual!E[])(length))();\n\n        // Every element of the uninitialized array must be initialized\n        size_t i;\n        foreach (e; r)\n        {\n            emplaceRef!E(result[i], e);\n            ++i;\n        }\n        return (() @trusted => cast(E[]) result)();\n    }\n    else\n    {\n        auto a = appender!(E[])();\n        foreach (e; r)\n        {\n            a.put(e);\n        }\n        return a.data;\n    }\n}\n\n/// ditto\nForeachType!(PointerTarget!Range)[] array(Range)(Range r)\nif (isPointer!Range && isIterable!(PointerTarget!Range) && !isNarrowString!Range && !isInfinite!Range)\n{\n    return array(*r);\n}\n\n///\n@safe pure nothrow unittest\n{\n    auto a = array([1, 2, 3, 4, 5][]);\n    assert(a == [ 1, 2, 3, 4, 5 ]);\n}\n\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    struct Foo\n    {\n        int a;\n    }\n    auto a = array([Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)][]);\n    assert(equal(a, [Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)]));\n}\n\n@safe pure nothrow unittest\n{\n    struct MyRange\n    {\n        enum front = 123;\n        enum empty = true;\n        void popFront() {}\n    }\n\n    auto arr = (new MyRange).array;\n    assert(arr.empty);\n}\n\n@system pure nothrow unittest\n{\n    immutable int[] a = [1, 2, 3, 4];\n    auto b = (&a).array;\n    assert(b == a);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    struct Foo\n    {\n        int a;\n        void opAssign(Foo)\n        {\n            assert(0);\n        }\n        auto opEquals(Foo foo)\n        {\n            return a == foo.a;\n        }\n    }\n    auto a = array([Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)][]);\n    assert(equal(a, [Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)]));\n}\n\n@safe unittest\n{\n    // Issue 12315\n    static struct Bug12315 { immutable int i; }\n    enum bug12315 = [Bug12315(123456789)].array();\n    static assert(bug12315[0].i == 123456789);\n}\n\n@safe unittest\n{\n    import std.range;\n    static struct S{int* p;}\n    auto a = array(immutable(S).init.repeat(5));\n    assert(a.length == 5);\n}\n\nversion (unittest)\n    private extern(C) void _d_delarray_t(void[] *p, TypeInfo_Struct ti);\n\n@system unittest\n{\n    // Issue 18995\n    int nAlive = 0;\n    struct S\n    {\n        bool alive;\n        this(int) { alive = true; ++nAlive; }\n        this(this) { nAlive += alive; }\n        ~this() { nAlive -= alive; alive = false; }\n    }\n\n    import std.algorithm.iteration : map;\n    import std.range : iota;\n\n    auto arr = iota(3).map!(a => S(a)).array;\n    assert(nAlive == 3);\n\n    // No good way to ensure the GC frees this, just call the lifetime function\n    // directly. If delete wasn't deprecated, this is what delete would do.\n    _d_delarray_t(cast(void[]*)&arr, typeid(S));\n\n    assert(nAlive == 0);\n}\n\n/**\nConvert a narrow string to an array type that fully supports random access.\nThis is handled as a special case and always returns an array of `dchar`\n\nParams:\n    str = `isNarrowString` to be converted to an array of `dchar`\nReturns:\n    a `dchar[]`, `const(dchar)[]`, or `immutable(dchar)[]` depending on the constness of\n    the input.\n*/\nElementType!String[] array(String)(scope String str)\nif (isNarrowString!String)\n{\n    import std.utf : toUTF32;\n    auto temp = str.toUTF32;\n    /* Unsafe cast. Allowed because toUTF32 makes a new array\n       and copies all the elements.\n     */\n    return () @trusted { return cast(ElementType!String[]) temp; } ();\n}\n\n///\n@safe unittest\n{\n    import std.range.primitives : isRandomAccessRange;\n\n    assert(\"Hello D\".array == \"Hello D\"d);\n    static assert(isRandomAccessRange!string == false);\n\n    assert(\"Hello D\"w.array == \"Hello D\"d);\n    static assert(isRandomAccessRange!dstring == true);\n}\n\n@safe unittest\n{\n    import std.conv : to;\n\n    static struct TestArray { int x; string toString() @safe { return to!string(x); } }\n\n    static struct OpAssign\n    {\n        uint num;\n        this(uint num) { this.num = num; }\n\n        // Templating opAssign to make sure the bugs with opAssign being\n        // templated are fixed.\n        void opAssign(T)(T rhs) { this.num = rhs.num; }\n    }\n\n    static struct OpApply\n    {\n        int opApply(scope int delegate(ref int) @safe dg)\n        {\n            int res;\n            foreach (i; 0 .. 10)\n            {\n                res = dg(i);\n                if (res) break;\n            }\n\n            return res;\n        }\n    }\n\n    auto a = array([1, 2, 3, 4, 5][]);\n    assert(a == [ 1, 2, 3, 4, 5 ]);\n\n    auto b = array([TestArray(1), TestArray(2)][]);\n    assert(b == [TestArray(1), TestArray(2)]);\n\n    class C\n    {\n        int x;\n        this(int y) { x = y; }\n        override string toString() const @safe { return to!string(x); }\n    }\n    auto c = array([new C(1), new C(2)][]);\n    assert(c[0].x == 1);\n    assert(c[1].x == 2);\n\n    auto d = array([1.0, 2.2, 3][]);\n    assert(is(typeof(d) == double[]));\n    assert(d == [1.0, 2.2, 3]);\n\n    auto e = [OpAssign(1), OpAssign(2)];\n    auto f = array(e);\n    assert(e == f);\n\n    assert(array(OpApply.init) == [0,1,2,3,4,5,6,7,8,9]);\n    assert(array(\"ABC\") == \"ABC\"d);\n    assert(array(\"ABC\".dup) == \"ABC\"d.dup);\n}\n\n//Bug# 8233\n@safe unittest\n{\n    assert(array(\"hello world\"d) == \"hello world\"d);\n    immutable a = [1, 2, 3, 4, 5];\n    assert(array(a) == a);\n    const b = a;\n    assert(array(b) == a);\n\n    //To verify that the opAssign branch doesn't get screwed up by using Unqual.\n    //EDIT: array no longer calls opAssign.\n    struct S\n    {\n        ref S opAssign(S)(const ref S rhs)\n        {\n            assert(0);\n        }\n\n        int i;\n    }\n\n    static foreach (T; AliasSeq!(S, const S, immutable S))\n    {{\n        auto arr = [T(1), T(2), T(3), T(4)];\n        assert(array(arr) == arr);\n    }}\n}\n\n@safe unittest\n{\n    //9824\n    static struct S\n    {\n        @disable void opAssign(S);\n        int i;\n    }\n    auto arr = [S(0), S(1), S(2)];\n    arr.array();\n}\n\n// Bugzilla 10220\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.exception;\n    import std.range : repeat;\n\n    static struct S\n    {\n        int val;\n\n        @disable this();\n        this(int v) { val = v; }\n    }\n    assertCTFEable!(\n    {\n        auto r = S(1).repeat(2).array();\n        assert(equal(r, [S(1), S(1)]));\n    });\n}\n\n@safe unittest\n{\n    //Turn down infinity:\n    static assert(!is(typeof(\n        repeat(1).array()\n    )));\n}\n\n/**\nReturns a newly allocated associative array from a range of key/value tuples\nor from a range of keys and a range of values.\n\nParams:\n    r = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    of tuples of keys and values.\n    keys = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of keys\n    values = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of values\n\nReturns:\n\n    A newly allocated associative array out of elements of the input\n    range, which must be a range of tuples (Key, Value) or\n    a range of keys and a range of values. If given two ranges of unequal\n    lengths after the elements of the shorter are exhausted the remaining\n    elements of the longer will not be considered.\n    Returns a null associative array reference when given an empty range.\n    Duplicates: Associative arrays have unique keys. If r contains duplicate keys,\n    then the result will contain the value of the last pair for that key in r.\n\nSee_Also: $(REF Tuple, std,typecons), $(REF zip, std,range)\n */\n\nauto assocArray(Range)(Range r)\nif (isInputRange!Range)\n{\n    import std.typecons : isTuple;\n\n    alias E = ElementType!Range;\n    static assert(isTuple!E, \"assocArray: argument must be a range of tuples\");\n    static assert(E.length == 2, \"assocArray: tuple dimension must be 2\");\n    alias KeyType = E.Types[0];\n    alias ValueType = E.Types[1];\n    static assert(isMutable!ValueType, \"assocArray: value type must be mutable\");\n\n    ValueType[KeyType] aa;\n    foreach (t; r)\n        aa[t[0]] = t[1];\n    return aa;\n}\n\n/// ditto\nauto assocArray(Keys, Values)(Keys keys, Values values)\nif (isInputRange!Values && isInputRange!Keys)\n{\n    static if (isDynamicArray!Keys && isDynamicArray!Values\n        && !isNarrowString!Keys && !isNarrowString!Values)\n    {\n        void* aa;\n        {\n            // aaLiteral is nothrow when the destructors don't throw\n            static if (is(typeof(() nothrow\n            {\n                import std.range : ElementType;\n                import std.traits : hasElaborateDestructor;\n                alias KeyElement = ElementType!Keys;\n                static if (hasElaborateDestructor!KeyElement)\n                    KeyElement.init.__xdtor();\n\n                alias ValueElement = ElementType!Values;\n                static if (hasElaborateDestructor!ValueElement)\n                    ValueElement.init.__xdtor();\n            })))\n            {\n                scope(failure) assert(0);\n            }\n            if (values.length > keys.length)\n                values = values[0 .. keys.length];\n            else if (keys.length > values.length)\n                keys = keys[0 .. values.length];\n            aa = aaLiteral(keys, values);\n        }\n        alias Key = typeof(keys[0]);\n        alias Value = typeof(values[0]);\n        return (() @trusted => cast(Value[Key]) aa)();\n    }\n    else\n    {\n        // zip is not always able to infer nothrow\n        alias Key = ElementType!Keys;\n        alias Value = ElementType!Values;\n        static assert(isMutable!Value, \"assocArray: value type must be mutable\");\n        Value[Key] aa;\n        foreach (key; keys)\n        {\n            if (values.empty) break;\n\n            // aa[key] is incorrectly not @safe if the destructor throws\n            // https://issues.dlang.org/show_bug.cgi?id=18592\n            static if (is(typeof(() @safe\n            {\n                import std.range : ElementType;\n                import std.traits : hasElaborateDestructor;\n                alias KeyElement = ElementType!Keys;\n                static if (hasElaborateDestructor!KeyElement)\n                    KeyElement.init.__xdtor();\n\n                alias ValueElement = ElementType!Values;\n                static if (hasElaborateDestructor!ValueElement)\n                    ValueElement.init.__xdtor();\n            })))\n            {\n                () @trusted {\n                    aa[key] = values.front;\n                }();\n            }\n            else\n            {\n                aa[key] = values.front;\n            }\n            values.popFront();\n        }\n        return aa;\n    }\n}\n\n///\n@safe pure /*nothrow*/ unittest\n{\n    import std.range : repeat, zip;\n    import std.typecons : tuple;\n    auto a = assocArray(zip([0, 1, 2], [\"a\", \"b\", \"c\"])); // aka zipMap\n    static assert(is(typeof(a) == string[int]));\n    assert(a == [0:\"a\", 1:\"b\", 2:\"c\"]);\n\n    auto b = assocArray([ tuple(\"foo\", \"bar\"), tuple(\"baz\", \"quux\") ]);\n    static assert(is(typeof(b) == string[string]));\n    assert(b == [\"foo\":\"bar\", \"baz\":\"quux\"]);\n\n    auto c = assocArray(\"ABCD\", true.repeat);\n    static assert(is(typeof(c) == bool[dchar]));\n    bool[dchar] expected = ['D':true, 'A':true, 'B':true, 'C':true];\n    assert(c == expected);\n}\n\n// @@@11053@@@ - Cannot be version (unittest) - recursive instantiation error\n@safe unittest\n{\n    import std.typecons;\n    static assert(!__traits(compiles, [ tuple(\"foo\", \"bar\", \"baz\") ].assocArray()));\n    static assert(!__traits(compiles, [ tuple(\"foo\") ].assocArray()));\n    assert([ tuple(\"foo\", \"bar\") ].assocArray() == [\"foo\": \"bar\"]);\n}\n\n// Issue 13909\n@safe unittest\n{\n    import std.typecons;\n    auto a = [tuple!(const string, string)(\"foo\", \"bar\")];\n    auto b = [tuple!(string, const string)(\"foo\", \"bar\")];\n    assert(a == b);\n    assert(assocArray(a) == [cast(const(string)) \"foo\": \"bar\"]);\n    static assert(!__traits(compiles, assocArray(b)));\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=5502\n@safe unittest\n{\n    auto a = assocArray([0, 1, 2], [\"a\", \"b\", \"c\"]);\n    static assert(is(typeof(a) == string[int]));\n    assert(a == [0:\"a\", 1:\"b\", 2:\"c\"]);\n\n    auto b = assocArray([0, 1, 2], [3L, 4, 5]);\n    static assert(is(typeof(b) == long[int]));\n    assert(b == [0: 3L, 1: 4, 2: 5]);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=5502\n@safe unittest\n{\n    import std.algorithm.iteration : filter, map;\n    import std.range : enumerate;\n\n    auto r = \"abcde\".enumerate.filter!(a => a.index == 2);\n    auto a = assocArray(r.map!(a => a.value), r.map!(a => a.index));\n    assert(is(typeof(a) == size_t[dchar]));\n    assert(a == [dchar('c'): size_t(2)]);\n}\n\n@safe nothrow pure unittest\n{\n    import std.range : iota;\n    auto b = assocArray(3.iota, 3.iota(6));\n    static assert(is(typeof(b) == int[int]));\n    assert(b == [0: 3, 1: 4, 2: 5]);\n\n    b = assocArray([0, 1, 2], [3, 4, 5]);\n    assert(b == [0: 3, 1: 4, 2: 5]);\n}\n\n@safe unittest\n{\n    struct ThrowingElement\n    {\n        int i;\n        static bool b;\n        ~this(){\n            if (b)\n                throw new Exception(\"\");\n        }\n    }\n    static assert(!__traits(compiles, () nothrow { assocArray([ThrowingElement()], [0]);}));\n    assert(assocArray([ThrowingElement()], [0]) == [ThrowingElement(): 0]);\n\n    static assert(!__traits(compiles, () nothrow { assocArray([0], [ThrowingElement()]);}));\n    assert(assocArray([0], [ThrowingElement()]) == [0: ThrowingElement()]);\n\n    import std.range : iota;\n    static assert(!__traits(compiles, () nothrow { assocArray(1.iota, [ThrowingElement()]);}));\n    assert(assocArray(1.iota, [ThrowingElement()]) == [0: ThrowingElement()]);\n}\n\n@system unittest\n{\n    import std.range : iota;\n    struct UnsafeElement\n    {\n        int i;\n        static bool b;\n        ~this(){\n            int[] arr;\n            void* p = arr.ptr + 1; // unsafe\n        }\n    }\n    static assert(!__traits(compiles, () @safe { assocArray(1.iota, [UnsafeElement()]);}));\n    assert(assocArray(1.iota, [UnsafeElement()]) == [0: UnsafeElement()]);\n}\n\n/**\nConstruct a range iterating over an associative array by key/value tuples.\n\nParams:\n    aa = The associative array to iterate over.\n\nReturns: A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\nof Tuple's of key and value pairs from the given associative array. The members\nof each pair can be accessed by name (`.key` and `.value`). or by integer\nindex (0 and 1 respectively).\n*/\nauto byPair(AA)(AA aa)\nif (isAssociativeArray!AA)\n{\n    import std.algorithm.iteration : map;\n    import std.typecons : tuple;\n\n    return aa.byKeyValue\n        .map!(pair => tuple!(\"key\", \"value\")(pair.key, pair.value));\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.sorting : sort;\n    import std.typecons : tuple, Tuple;\n\n    auto aa = [\"a\": 1, \"b\": 2, \"c\": 3];\n    Tuple!(string, int)[] pairs;\n\n    // Iteration over key/value pairs.\n    foreach (pair; aa.byPair)\n    {\n        if (pair.key == \"b\")\n            pairs ~= tuple(\"B\", pair.value);\n        else\n            pairs ~= pair;\n    }\n\n    // Iteration order is implementation-dependent, so we should sort it to get\n    // a fixed order.\n    pairs.sort();\n    assert(pairs == [\n        tuple(\"B\", 2),\n        tuple(\"a\", 1),\n        tuple(\"c\", 3)\n    ]);\n}\n\n@safe unittest\n{\n    import std.typecons : tuple, Tuple;\n    import std.meta : AliasSeq;\n\n    auto aa = [\"a\":2];\n    auto pairs = aa.byPair();\n\n    alias PT = typeof(pairs.front);\n    static assert(is(PT : Tuple!(string,int)));\n    static assert(PT.fieldNames == AliasSeq!(\"key\", \"value\"));\n    static assert(isForwardRange!(typeof(pairs)));\n\n    assert(!pairs.empty);\n    assert(pairs.front == tuple(\"a\", 2));\n\n    auto savedPairs = pairs.save;\n\n    pairs.popFront();\n    assert(pairs.empty);\n    assert(!savedPairs.empty);\n    assert(savedPairs.front == tuple(\"a\", 2));\n}\n\n// Issue 17711\n@safe unittest\n{\n    const(int[string]) aa = [ \"abc\": 123 ];\n\n    // Ensure that byKeyValue is usable with a const AA.\n    auto kv = aa.byKeyValue;\n    assert(!kv.empty);\n    assert(kv.front.key == \"abc\" && kv.front.value == 123);\n    kv.popFront();\n    assert(kv.empty);\n\n    // Ensure byPair is instantiable with const AA.\n    auto r = aa.byPair;\n    static assert(isInputRange!(typeof(r)));\n    assert(!r.empty && r.front[0] == \"abc\" && r.front[1] == 123);\n    r.popFront();\n    assert(r.empty);\n}\n\nprivate template blockAttribute(T)\n{\n    import core.memory;\n    static if (hasIndirections!(T) || is(T == void))\n    {\n        enum blockAttribute = 0;\n    }\n    else\n    {\n        enum blockAttribute = GC.BlkAttr.NO_SCAN;\n    }\n}\n\n@safe unittest\n{\n    import core.memory : UGC = GC;\n    static assert(!(blockAttribute!void & UGC.BlkAttr.NO_SCAN));\n}\n\n// Returns the number of dimensions in an array T.\nprivate template nDimensions(T)\n{\n    static if (isArray!T)\n    {\n        enum nDimensions = 1 + nDimensions!(typeof(T.init[0]));\n    }\n    else\n    {\n        enum nDimensions = 0;\n    }\n}\n\n@safe unittest\n{\n    static assert(nDimensions!(uint[]) == 1);\n    static assert(nDimensions!(float[][]) == 2);\n}\n\n/++\nReturns a new array of type `T` allocated on the garbage collected heap\nwithout initializing its elements. This can be a useful optimization if every\nelement will be immediately initialized. `T` may be a multidimensional\narray. In this case sizes may be specified for any number of dimensions from 0\nto the number in `T`.\n\nuninitializedArray is `nothrow` and weakly `pure`.\n\nuninitializedArray is `@system` if the uninitialized element type has pointers.\n\nParams:\n    T = The type of the resulting array elements\n    sizes = The length dimension(s) of the resulting array\nReturns:\n    An array of `T` with `I.length` dimensions.\n+/\nauto uninitializedArray(T, I...)(I sizes) nothrow @system\nif (isDynamicArray!T && allSatisfy!(isIntegral, I) && hasIndirections!(ElementEncodingType!T))\n{\n    enum isSize_t(E) = is (E : size_t);\n    alias toSize_t(E) = size_t;\n\n    static assert(allSatisfy!(isSize_t, I),\n        \"Argument types in \"~I.stringof~\" are not all convertible to size_t: \"\n        ~Filter!(templateNot!(isSize_t), I).stringof);\n\n    //Eagerlly transform non-size_t into size_t to avoid template bloat\n    alias ST = staticMap!(toSize_t, I);\n\n    return arrayAllocImpl!(false, T, ST)(sizes);\n}\n\n/// ditto\nauto uninitializedArray(T, I...)(I sizes) nothrow @trusted\nif (isDynamicArray!T && allSatisfy!(isIntegral, I) && !hasIndirections!(ElementEncodingType!T))\n{\n    enum isSize_t(E) = is (E : size_t);\n    alias toSize_t(E) = size_t;\n\n    static assert(allSatisfy!(isSize_t, I),\n        \"Argument types in \"~I.stringof~\" are not all convertible to size_t: \"\n        ~Filter!(templateNot!(isSize_t), I).stringof);\n\n    //Eagerlly transform non-size_t into size_t to avoid template bloat\n    alias ST = staticMap!(toSize_t, I);\n\n    return arrayAllocImpl!(false, T, ST)(sizes);\n}\n///\n@system nothrow pure unittest\n{\n    double[] arr = uninitializedArray!(double[])(100);\n    assert(arr.length == 100);\n\n    double[][] matrix = uninitializedArray!(double[][])(42, 31);\n    assert(matrix.length == 42);\n    assert(matrix[0].length == 31);\n\n    char*[] ptrs = uninitializedArray!(char*[])(100);\n    assert(ptrs.length == 100);\n}\n\n/++\nReturns a new array of type `T` allocated on the garbage collected heap.\n\nPartial initialization is done for types with indirections, for preservation\nof memory safety. Note that elements will only be initialized to 0, but not\nnecessarily the element type's `.init`.\n\nminimallyInitializedArray is `nothrow` and weakly `pure`.\n\nParams:\n    T = The type of the array elements\n    sizes = The length dimension(s) of the resulting array\nReturns:\n    An array of `T` with `I.length` dimensions.\n+/\nauto minimallyInitializedArray(T, I...)(I sizes) nothrow @trusted\nif (isDynamicArray!T && allSatisfy!(isIntegral, I))\n{\n    enum isSize_t(E) = is (E : size_t);\n    alias toSize_t(E) = size_t;\n\n    static assert(allSatisfy!(isSize_t, I),\n        \"Argument types in \"~I.stringof~\" are not all convertible to size_t: \"\n        ~Filter!(templateNot!(isSize_t), I).stringof);\n    //Eagerlly transform non-size_t into size_t to avoid template bloat\n    alias ST = staticMap!(toSize_t, I);\n\n    return arrayAllocImpl!(true, T, ST)(sizes);\n}\n\n///\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : repeat;\n\n    auto arr = minimallyInitializedArray!(int[])(42);\n    assert(arr.length == 42);\n\n    // Elements aren't necessarily initialized to 0, so don't do this:\n    // assert(arr.equal(0.repeat(42)));\n    // If that is needed, initialize the array normally instead:\n    auto arr2 = new int[42];\n    assert(arr2.equal(0.repeat(42)));\n}\n\n@safe pure nothrow unittest\n{\n    cast(void) minimallyInitializedArray!(int[][][][][])();\n    double[] arr = minimallyInitializedArray!(double[])(100);\n    assert(arr.length == 100);\n\n    double[][] matrix = minimallyInitializedArray!(double[][])(42);\n    assert(matrix.length == 42);\n    foreach (elem; matrix)\n    {\n        assert(elem.ptr is null);\n    }\n}\n\n// from rt/lifetime.d\nprivate extern(C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow;\n\nprivate auto arrayAllocImpl(bool minimallyInitialized, T, I...)(I sizes) nothrow\n{\n    static assert(I.length <= nDimensions!T,\n        I.length.stringof~\"dimensions specified for a \"~nDimensions!T.stringof~\" dimensional array.\");\n\n    alias E = ElementEncodingType!T;\n\n    E[] ret;\n\n    static if (I.length != 0)\n    {\n        static assert(is(I[0] == size_t));\n        alias size = sizes[0];\n    }\n\n    static if (I.length == 1)\n    {\n        if (__ctfe)\n        {\n            static if (__traits(compiles, new E[](size)))\n                ret = new E[](size);\n            else static if (__traits(compiles, ret ~= E.init))\n            {\n                try\n                {\n                    //Issue: if E has an impure postblit, then all of arrayAllocImpl\n                    //Will be impure, even during non CTFE.\n                    foreach (i; 0 .. size)\n                        ret ~= E.init;\n                }\n                catch (Exception e)\n                    throw new Error(e.msg);\n            }\n            else\n                assert(0, \"No postblit nor default init on \" ~ E.stringof ~\n                    \": At least one is required for CTFE.\");\n        }\n        else\n        {\n            import core.stdc.string : memset;\n\n            /+\n              NOTES:\n              _d_newarrayU is part of druntime, and creates an uninitialized\n              block, just like GC.malloc. However, it also sets the appropriate\n              bits, and sets up the block as an appendable array of type E[],\n              which will inform the GC how to destroy the items in the block\n              when it gets collected.\n\n              _d_newarrayU returns a void[], but with the length set according\n              to E.sizeof.\n            +/\n            *(cast(void[]*)&ret) = _d_newarrayU(typeid(E[]), size);\n            static if (minimallyInitialized && hasIndirections!E)\n                // _d_newarrayU would have asserted if the multiplication below\n                // had overflowed, so we don't have to check it again.\n                memset(ret.ptr, 0, E.sizeof * ret.length);\n        }\n    }\n    else static if (I.length > 1)\n    {\n        ret = arrayAllocImpl!(false, E[])(size);\n        foreach (ref elem; ret)\n            elem = arrayAllocImpl!(minimallyInitialized, E)(sizes[1..$]);\n    }\n\n    return ret;\n}\n\n@safe nothrow pure unittest\n{\n    auto s1 = uninitializedArray!(int[])();\n    auto s2 = minimallyInitializedArray!(int[])();\n    assert(s1.length == 0);\n    assert(s2.length == 0);\n}\n\n@safe nothrow pure unittest //@@@9803@@@\n{\n    auto a = minimallyInitializedArray!(int*[])(1);\n    assert(a[0] == null);\n    auto b = minimallyInitializedArray!(int[][])(1);\n    assert(b[0].empty);\n    auto c = minimallyInitializedArray!(int*[][])(1, 1);\n    assert(c[0][0] == null);\n}\n\n@safe unittest //@@@10637@@@\n{\n    static struct S\n    {\n        static struct I{int i; alias i this;}\n        int* p;\n        this() @disable;\n        this(int i)\n        {\n            p = &(new I(i)).i;\n        }\n        this(this)\n        {\n            p = &(new I(*p)).i;\n        }\n        ~this()\n        {\n            // note, this assert is invalid -- a struct should always be able\n            // to run its dtor on the .init value, I'm leaving it here\n            // commented out because the original test case had it. I'm not\n            // sure what it's trying to prove.\n            //\n            // What happens now that minimallyInitializedArray adds the\n            // destructor run to the GC, is that this assert would fire in the\n            // GC, which triggers an invalid memory operation.\n            //assert(p != null);\n        }\n    }\n    auto a = minimallyInitializedArray!(S[])(1);\n    assert(a[0].p == null);\n    enum b = minimallyInitializedArray!(S[])(1);\n    assert(b[0].p == null);\n}\n\n@safe nothrow unittest\n{\n    static struct S1\n    {\n        this() @disable;\n        this(this) @disable;\n    }\n    auto a1 = minimallyInitializedArray!(S1[][])(2, 2);\n    assert(a1);\n    static struct S2\n    {\n        this() @disable;\n        //this(this) @disable;\n    }\n    auto a2 = minimallyInitializedArray!(S2[][])(2, 2);\n    assert(a2);\n    enum b2 = minimallyInitializedArray!(S2[][])(2, 2);\n    assert(b2);\n    static struct S3\n    {\n        //this() @disable;\n        this(this) @disable;\n    }\n    auto a3 = minimallyInitializedArray!(S3[][])(2, 2);\n    assert(a3);\n    enum b3 = minimallyInitializedArray!(S3[][])(2, 2);\n    assert(b3);\n}\n\n/++\nReturns the overlapping portion, if any, of two arrays. Unlike `equal`,\n`overlap` only compares the pointers and lengths in the\nranges, not the values referred by them. If `r1` and `r2` have an\noverlapping slice, returns that slice. Otherwise, returns the null\nslice.\n\nParams:\n    a = The first array to compare\n    b = The second array to compare\nReturns:\n    The overlapping portion of the two arrays.\n+/\nCommonType!(T[], U[]) overlap(T, U)(T[] a, U[] b) @trusted\nif (is(typeof(a.ptr < b.ptr) == bool))\n{\n    import std.algorithm.comparison : min;\n\n    auto end = min(a.ptr + a.length, b.ptr + b.length);\n    // CTFE requires pairing pointer comparisons, which forces a\n    // slightly inefficient implementation.\n    if (a.ptr <= b.ptr && b.ptr < a.ptr + a.length)\n    {\n        return b.ptr[0 .. end - b.ptr];\n    }\n\n    if (b.ptr <= a.ptr && a.ptr < b.ptr + b.length)\n    {\n        return a.ptr[0 .. end - a.ptr];\n    }\n\n    return null;\n}\n\n///\n@safe pure nothrow unittest\n{\n    int[] a = [ 10, 11, 12, 13, 14 ];\n    int[] b = a[1 .. 3];\n    assert(overlap(a, b) == [ 11, 12 ]);\n    b = b.dup;\n    // overlap disappears even though the content is the same\n    assert(overlap(a, b).empty);\n\n    static test()() @nogc\n    {\n        auto a = \"It's three o'clock\"d;\n        auto b = a[5 .. 10];\n        return b.overlap(a);\n    }\n\n    //works at compile-time\n    static assert(test == \"three\"d);\n}\n\n@safe nothrow unittest\n{\n    static void test(L, R)(L l, R r)\n    {\n        assert(overlap(l, r) == [ 100, 12 ]);\n\n        assert(overlap(l, l[0 .. 2]) is l[0 .. 2]);\n        assert(overlap(l, l[3 .. 5]) is l[3 .. 5]);\n        assert(overlap(l[0 .. 2], l) is l[0 .. 2]);\n        assert(overlap(l[3 .. 5], l) is l[3 .. 5]);\n    }\n\n    int[] a = [ 10, 11, 12, 13, 14 ];\n    int[] b = a[1 .. 3];\n    a[1] = 100;\n\n    immutable int[] c = a.idup;\n    immutable int[] d = c[1 .. 3];\n\n    test(a, b);\n    assert(overlap(a, b.dup).empty);\n    test(c, d);\n    assert(overlap(c, d.idup).empty);\n}\n\n@safe pure nothrow unittest // bugzilla 9836\n{\n    // range primitives for array should work with alias this types\n    struct Wrapper\n    {\n        int[] data;\n        alias data this;\n\n        @property Wrapper save() { return this; }\n    }\n    auto w = Wrapper([1,2,3,4]);\n    std.array.popFront(w); // should work\n\n    static assert(isInputRange!Wrapper);\n    static assert(isForwardRange!Wrapper);\n    static assert(isBidirectionalRange!Wrapper);\n    static assert(isRandomAccessRange!Wrapper);\n}\n\nprivate void copyBackwards(T)(T[] src, T[] dest)\n{\n    import core.stdc.string : memmove;\n\n    assert(src.length == dest.length);\n\n    if (!__ctfe || hasElaborateCopyConstructor!T)\n    {\n        /* insertInPlace relies on dest being uninitialized, so no postblits allowed,\n         * as this is a MOVE that overwrites the destination, not a COPY.\n         * BUG: insertInPlace will not work with ctfe and postblits\n         */\n        memmove(dest.ptr, src.ptr, src.length * T.sizeof);\n    }\n    else\n    {\n        immutable len = src.length;\n        for (size_t i = len; i-- > 0;)\n        {\n            dest[i] = src[i];\n        }\n    }\n}\n\n/++\n    Inserts `stuff` (which must be an input range or any number of\n    implicitly convertible items) in `array` at position `pos`.\n\n    Params:\n        array = The array that `stuff` will be inserted into.\n        pos   = The position in `array` to insert the `stuff`.\n        stuff = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives),\n        or any number of implicitly convertible items to insert into `array`.\n +/\nvoid insertInPlace(T, U...)(ref T[] array, size_t pos, U stuff)\nif (!isSomeString!(T[])\n    && allSatisfy!(isInputRangeOrConvertible!T, U) && U.length > 0)\n{\n    static if (allSatisfy!(isInputRangeWithLengthOrConvertible!T, U))\n    {\n        import std.conv : emplaceRef;\n\n        immutable oldLen = array.length;\n\n        size_t to_insert = 0;\n        foreach (i, E; U)\n        {\n            static if (is(E : T)) //a single convertible value, not a range\n                to_insert += 1;\n            else\n                to_insert += stuff[i].length;\n        }\n        if (to_insert)\n        {\n            array.length += to_insert;\n\n            // Takes arguments array, pos, stuff\n            // Spread apart array[] at pos by moving elements\n            (() @trusted { copyBackwards(array[pos .. oldLen], array[pos+to_insert..$]); })();\n\n            // Initialize array[pos .. pos+to_insert] with stuff[]\n            auto j = 0;\n            foreach (i, E; U)\n            {\n                static if (is(E : T))\n                {\n                    emplaceRef!T(array[pos + j++], stuff[i]);\n                }\n                else\n                {\n                    foreach (v; stuff[i])\n                    {\n                        emplaceRef!T(array[pos + j++], v);\n                    }\n                }\n            }\n        }\n    }\n    else\n    {\n        // stuff has some InputRanges in it that don't have length\n        // assume that stuff to be inserted is typically shorter\n        // then the array that can be arbitrary big\n        // TODO: needs a better implementation as there is no need to build an _array_\n        // a singly-linked list of memory blocks (rope, etc.) will do\n        auto app = appender!(T[])();\n        foreach (i, E; U)\n            app.put(stuff[i]);\n        insertInPlace(array, pos, app.data);\n    }\n}\n\n/// Ditto\nvoid insertInPlace(T, U...)(ref T[] array, size_t pos, U stuff)\nif (isSomeString!(T[]) && allSatisfy!(isCharOrStringOrDcharRange, U))\n{\n    static if (is(Unqual!T == T)\n        && allSatisfy!(isInputRangeWithLengthOrConvertible!dchar, U))\n    {\n        import std.utf : codeLength;\n        // mutable, can do in place\n        //helper function: re-encode dchar to Ts and store at *ptr\n        static T* putDChar(T* ptr, dchar ch)\n        {\n            static if (is(T == dchar))\n            {\n                *ptr++ = ch;\n                return ptr;\n            }\n            else\n            {\n                import std.utf : encode;\n                T[dchar.sizeof/T.sizeof] buf;\n                immutable len = encode(buf, ch);\n                final switch (len)\n                {\n                    static if (T.sizeof == char.sizeof)\n                    {\n                case 4:\n                        ptr[3] = buf[3];\n                        goto case;\n                case 3:\n                        ptr[2] = buf[2];\n                        goto case;\n                    }\n                case 2:\n                    ptr[1] = buf[1];\n                    goto case;\n                case 1:\n                    ptr[0] = buf[0];\n                }\n                ptr += len;\n                return ptr;\n            }\n        }\n        size_t to_insert = 0;\n        //count up the number of *codeunits* to insert\n        foreach (i, E; U)\n            to_insert += codeLength!T(stuff[i]);\n        array.length += to_insert;\n\n        @trusted static void moveToRight(T[] arr, size_t gap)\n        {\n            static assert(!hasElaborateCopyConstructor!T);\n            import core.stdc.string : memmove;\n            if (__ctfe)\n            {\n                for (size_t i = arr.length - gap; i; --i)\n                    arr[gap + i - 1] = arr[i - 1];\n            }\n            else\n                memmove(arr.ptr + gap, arr.ptr, (arr.length - gap) * T.sizeof);\n        }\n        moveToRight(array[pos .. $], to_insert);\n        auto ptr = array.ptr + pos;\n        foreach (i, E; U)\n        {\n            static if (is(E : dchar))\n            {\n                ptr = putDChar(ptr, stuff[i]);\n            }\n            else\n            {\n                foreach (dchar ch; stuff[i])\n                    ptr = putDChar(ptr, ch);\n            }\n        }\n        assert(ptr == array.ptr + pos + to_insert, \"(ptr == array.ptr + pos + to_insert) is false\");\n    }\n    else\n    {\n        // immutable/const, just construct a new array\n        auto app = appender!(T[])();\n        app.put(array[0 .. pos]);\n        foreach (i, E; U)\n            app.put(stuff[i]);\n        app.put(array[pos..$]);\n        array = app.data;\n    }\n}\n\n///\n@safe pure unittest\n{\n    int[] a = [ 1, 2, 3, 4 ];\n    a.insertInPlace(2, [ 1, 2 ]);\n    assert(a == [ 1, 2, 1, 2, 3, 4 ]);\n    a.insertInPlace(3, 10u, 11);\n    assert(a == [ 1, 2, 1, 10, 11, 2, 3, 4]);\n}\n\n//constraint helpers\nprivate template isInputRangeWithLengthOrConvertible(E)\n{\n    template isInputRangeWithLengthOrConvertible(R)\n    {\n        //hasLength not defined for char[], wchar[] and dchar[]\n        enum isInputRangeWithLengthOrConvertible =\n            (isInputRange!R && is(typeof(R.init.length))\n                && is(ElementType!R : E))  || is(R : E);\n    }\n}\n\n//ditto\nprivate template isCharOrStringOrDcharRange(T)\n{\n    enum isCharOrStringOrDcharRange = isSomeString!T || isSomeChar!T ||\n        (isInputRange!T && is(ElementType!T : dchar));\n}\n\n//ditto\nprivate template isInputRangeOrConvertible(E)\n{\n    template isInputRangeOrConvertible(R)\n    {\n        enum isInputRangeOrConvertible =\n            (isInputRange!R && is(ElementType!R : E))  || is(R : E);\n    }\n}\n\n@system unittest\n{\n    // @system due to insertInPlace\n    import core.exception;\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter;\n    import std.conv : to;\n    import std.exception;\n\n\n    bool test(T, U, V)(T orig, size_t pos, U toInsert, V result)\n    {\n        {\n            static if (is(T == typeof(T.init.dup)))\n                auto a = orig.dup;\n            else\n                auto a = orig.idup;\n\n            a.insertInPlace(pos, toInsert);\n            if (!equal(a, result))\n                return false;\n        }\n\n        static if (isInputRange!U)\n        {\n            orig.insertInPlace(pos, filter!\"true\"(toInsert));\n            return equal(orig, result);\n        }\n        else\n            return true;\n    }\n\n\n    assert(test([1, 2, 3, 4], 0, [6, 7], [6, 7, 1, 2, 3, 4]));\n    assert(test([1, 2, 3, 4], 2, [8, 9], [1, 2, 8, 9, 3, 4]));\n    assert(test([1, 2, 3, 4], 4, [10, 11], [1, 2, 3, 4, 10, 11]));\n\n    assert(test([1, 2, 3, 4], 0, 22, [22, 1, 2, 3, 4]));\n    assert(test([1, 2, 3, 4], 2, 23, [1, 2, 23, 3, 4]));\n    assert(test([1, 2, 3, 4], 4, 24, [1, 2, 3, 4, 24]));\n\n    void testStr(T, U)(string file = __FILE__, size_t line = __LINE__)\n    {\n\n        auto l = to!T(\"hello\");\n        auto r = to!U(\" વિશ્વ\");\n\n        enforce(test(l, 0, r, \" વિશ્વhello\"),\n                new AssertError(\"testStr failure 1\", file, line));\n        enforce(test(l, 3, r, \"hel વિશ્વlo\"),\n                new AssertError(\"testStr failure 2\", file, line));\n        enforce(test(l, l.length, r, \"hello વિશ્વ\"),\n                new AssertError(\"testStr failure 3\", file, line));\n    }\n\n    static foreach (T; AliasSeq!(char, wchar, dchar,\n        immutable(char), immutable(wchar), immutable(dchar)))\n    {\n        static foreach (U; AliasSeq!(char, wchar, dchar,\n            immutable(char), immutable(wchar), immutable(dchar)))\n        {\n            testStr!(T[], U[])();\n        }\n\n    }\n\n    // variadic version\n    bool testVar(T, U...)(T orig, size_t pos, U args)\n    {\n        static if (is(T == typeof(T.init.dup)))\n            auto a = orig.dup;\n        else\n            auto a = orig.idup;\n        auto result = args[$-1];\n\n        a.insertInPlace(pos, args[0..$-1]);\n        if (!equal(a, result))\n            return false;\n        return true;\n    }\n    assert(testVar([1, 2, 3, 4], 0, 6, 7u, [6, 7, 1, 2, 3, 4]));\n    assert(testVar([1L, 2, 3, 4], 2, 8, 9L, [1, 2, 8, 9, 3, 4]));\n    assert(testVar([1L, 2, 3, 4], 4, 10L, 11, [1, 2, 3, 4, 10, 11]));\n    assert(testVar([1L, 2, 3, 4], 4, [10, 11], 40L, 42L,\n                    [1, 2, 3, 4, 10, 11, 40, 42]));\n    assert(testVar([1L, 2, 3, 4], 4, 10, 11, [40L, 42],\n                    [1, 2, 3, 4, 10, 11, 40, 42]));\n    assert(testVar(\"t\".idup, 1, 'e', 's', 't', \"test\"));\n    assert(testVar(\"!!\"w.idup, 1, \"\\u00e9ll\\u00f4\", 'x', \"TTT\"w, 'y',\n                    \"!\\u00e9ll\\u00f4xTTTy!\"));\n    assert(testVar(\"flipflop\"d.idup, 4, '_',\n                    \"xyz\"w, '\\U00010143', '_', \"abc\"d, \"__\",\n                    \"flip_xyz\\U00010143_abc__flop\"));\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    // insertInPlace interop with postblit\n    static struct Int\n    {\n        int* payload;\n        this(int k)\n        {\n            payload = new int;\n            *payload = k;\n        }\n        this(this)\n        {\n            int* np = new int;\n            *np = *payload;\n            payload = np;\n        }\n        ~this()\n        {\n            if (payload)\n                *payload = 0; //'destroy' it\n        }\n        @property int getPayload(){ return *payload; }\n        alias getPayload this;\n    }\n\n    Int[] arr = [Int(1), Int(4), Int(5)];\n    assert(arr[0] == 1);\n    insertInPlace(arr, 1, Int(2), Int(3));\n    assert(equal(arr, [1, 2, 3, 4, 5]));  //check it works with postblit\n}\n\n@safe unittest\n{\n    import std.exception;\n    assertCTFEable!(\n    {\n        int[] a = [1, 2];\n        a.insertInPlace(2, 3);\n        a.insertInPlace(0, -1, 0);\n        return a == [-1, 0, 1, 2, 3];\n    });\n}\n\n@system unittest // bugzilla 6874\n{\n    import core.memory;\n    // allocate some space\n    byte[] a;\n    a.length = 1;\n\n    // fill it\n    a.length = a.capacity;\n\n    // write beyond\n    byte[] b = a[$ .. $];\n    b.insertInPlace(0, a);\n\n    // make sure that reallocation has happened\n    assert(GC.addrOf(&b[0]) == GC.addrOf(&b[$-1]));\n}\n\n\n/++\n    Returns whether the `front`s of `lhs` and `rhs` both refer to the\n    same place in memory, making one of the arrays a slice of the other which\n    starts at index `0`.\n\n    Params:\n        lhs = the first array to compare\n        rhs = the second array to compare\n    Returns:\n        `true` if $(D lhs.ptr == rhs.ptr), `false` otherwise.\n  +/\n@safe\npure nothrow bool sameHead(T)(in T[] lhs, in T[] rhs)\n{\n    return lhs.ptr == rhs.ptr;\n}\n\n///\n@safe pure nothrow unittest\n{\n    auto a = [1, 2, 3, 4, 5];\n    auto b = a[0 .. 2];\n\n    assert(a.sameHead(b));\n}\n\n\n/++\n    Returns whether the `back`s of `lhs` and `rhs` both refer to the\n    same place in memory, making one of the arrays a slice of the other which\n    end at index `$`.\n\n    Params:\n        lhs = the first array to compare\n        rhs = the second array to compare\n    Returns:\n        `true` if both arrays are the same length and $(D lhs.ptr == rhs.ptr),\n        `false` otherwise.\n  +/\n@trusted\npure nothrow bool sameTail(T)(in T[] lhs, in T[] rhs)\n{\n    return lhs.ptr + lhs.length == rhs.ptr + rhs.length;\n}\n\n///\n@safe pure nothrow unittest\n{\n    auto a = [1, 2, 3, 4, 5];\n    auto b = a[3..$];\n\n    assert(a.sameTail(b));\n}\n\n@safe pure nothrow unittest\n{\n    static foreach (T; AliasSeq!(int[], const(int)[], immutable(int)[], const int[], immutable int[]))\n    {{\n        T a = [1, 2, 3, 4, 5];\n        T b = a;\n        T c = a[1 .. $];\n        T d = a[0 .. 1];\n        T e = null;\n\n        assert(sameHead(a, a));\n        assert(sameHead(a, b));\n        assert(!sameHead(a, c));\n        assert(sameHead(a, d));\n        assert(!sameHead(a, e));\n\n        assert(sameTail(a, a));\n        assert(sameTail(a, b));\n        assert(sameTail(a, c));\n        assert(!sameTail(a, d));\n        assert(!sameTail(a, e));\n\n        //verifies R-value compatibilty\n        assert(a.sameHead(a[0 .. 0]));\n        assert(a.sameTail(a[$ .. $]));\n    }}\n}\n\n/**\nParams:\n    s = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    or a dynamic array\n    n = number of times to repeat `s`\n\nReturns:\n    An array that consists of `s` repeated `n` times. This function allocates, fills, and\n    returns a new array.\n\nSee_Also:\n    For a lazy version, refer to $(REF repeat, std,range).\n */\nElementEncodingType!S[] replicate(S)(S s, size_t n)\nif (isDynamicArray!S)\n{\n    alias RetType = ElementEncodingType!S[];\n\n    // Optimization for return join(std.range.repeat(s, n));\n    if (n == 0)\n        return RetType.init;\n    if (n == 1)\n        return cast(RetType) s;\n    auto r = new Unqual!(typeof(s[0]))[n * s.length];\n    if (s.length == 1)\n        r[] = s[0];\n    else\n    {\n        immutable len = s.length, nlen = n * len;\n        for (size_t i = 0; i < nlen; i += len)\n        {\n            r[i .. i + len] = s[];\n        }\n    }\n    return r;\n}\n\n/// ditto\nElementType!S[] replicate(S)(S s, size_t n)\nif (isInputRange!S && !isDynamicArray!S)\n{\n    import std.range : repeat;\n    return join(std.range.repeat(s, n));\n}\n\n\n///\n@safe unittest\n{\n    auto a = \"abc\";\n    auto s = replicate(a, 3);\n\n    assert(s == \"abcabcabc\");\n\n    auto b = [1, 2, 3];\n    auto c = replicate(b, 3);\n\n    assert(c == [1, 2, 3, 1, 2, 3, 1, 2, 3]);\n\n    auto d = replicate(b, 0);\n\n    assert(d == []);\n}\n\n@safe unittest\n{\n    import std.conv : to;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[]))\n    {{\n        immutable S t = \"abc\";\n\n        assert(replicate(to!S(\"1234\"), 0) is null);\n        assert(replicate(to!S(\"1234\"), 0) is null);\n        assert(replicate(to!S(\"1234\"), 1) == \"1234\");\n        assert(replicate(to!S(\"1234\"), 2) == \"12341234\");\n        assert(replicate(to!S(\"1\"), 4) == \"1111\");\n        assert(replicate(t, 3) == \"abcabcabc\");\n        assert(replicate(cast(S) null, 4) is null);\n    }}\n}\n\n/++\nEagerly splits `range` into an array, using `sep` as the delimiter.\n\nWhen no delimiter is provided, strings are split into an array of words,\nusing whitespace as delimiter.\nRuns of whitespace are merged together (no empty words are produced).\n\nThe `range` must be a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives).\nThe separator can be a value of the same type as the elements in `range`\nor it can be another forward `range`.\n\nParams:\n    s = the string to split by word if no separator is given\n    range = the range to split\n    sep = a value of the same type as the elements of `range` or another\n    isTerminator = a predicate that splits the range when it returns `true`.\n\nReturns:\n    An array containing the divided parts of `range` (or the words of `s`).\n\nSee_Also:\n$(REF splitter, std,algorithm,iteration) for a lazy version without allocating memory.\n\n$(REF splitter, std,regex) for a version that splits using a regular\nexpression defined separator.\n+/\nS[] split(S)(S s) @safe pure\nif (isSomeString!S)\n{\n    size_t istart;\n    bool inword = false;\n    auto result = appender!(S[]);\n\n    foreach (i, dchar c ; s)\n    {\n        import std.uni : isWhite;\n        if (isWhite(c))\n        {\n            if (inword)\n            {\n                put(result, s[istart .. i]);\n                inword = false;\n            }\n        }\n        else\n        {\n            if (!inword)\n            {\n                istart = i;\n                inword = true;\n            }\n        }\n    }\n    if (inword)\n        put(result, s[istart .. $]);\n    return result.data;\n}\n\n///\n@safe unittest\n{\n    import std.uni : isWhite;\n    assert(\"Learning,D,is,fun\".split(\",\") == [\"Learning\", \"D\", \"is\", \"fun\"]);\n    assert(\"Learning D is fun\".split!isWhite == [\"Learning\", \"D\", \"is\", \"fun\"]);\n    assert(\"Learning D is fun\".split(\" D \") == [\"Learning\", \"is fun\"]);\n}\n\n///\n@safe unittest\n{\n    string str = \"Hello World!\";\n    assert(str.split == [\"Hello\", \"World!\"]);\n\n    string str2 = \"Hello\\t\\tWorld\\t!\";\n    assert(str2.split == [\"Hello\", \"World\", \"!\"]);\n}\n\n@safe unittest\n{\n    import std.conv : to;\n    import std.format;\n    import std.typecons;\n\n    static auto makeEntry(S)(string l, string[] r)\n    {return tuple(l.to!S(), r.to!(S[])());}\n\n    static foreach (S; AliasSeq!(string, wstring, dstring,))\n    {{\n        auto entries =\n        [\n            makeEntry!S(\"\", []),\n            makeEntry!S(\" \", []),\n            makeEntry!S(\"hello\", [\"hello\"]),\n            makeEntry!S(\" hello \", [\"hello\"]),\n            makeEntry!S(\"  h  e  l  l  o \", [\"h\", \"e\", \"l\", \"l\", \"o\"]),\n            makeEntry!S(\"peter\\t\\npaul\\rjerry\", [\"peter\", \"paul\", \"jerry\"]),\n            makeEntry!S(\" \\t\\npeter paul\\tjerry \\n\", [\"peter\", \"paul\", \"jerry\"]),\n            makeEntry!S(\"\\u2000日\\u202F本\\u205F語\\u3000\", [\"日\", \"本\", \"語\"]),\n            makeEntry!S(\"　　哈・郎博尔德｝　　　　___一个\", [\"哈・郎博尔德｝\", \"___一个\"])\n        ];\n        foreach (entry; entries)\n            assert(entry[0].split() == entry[1], format(\"got: %s, expected: %s.\", entry[0].split(), entry[1]));\n    }}\n\n    //Just to test that an immutable is split-able\n    immutable string s = \" \\t\\npeter paul\\tjerry \\n\";\n    assert(split(s) == [\"peter\", \"paul\", \"jerry\"]);\n}\n\n@safe unittest //purity, ctfe ...\n{\n    import std.exception;\n    void dg() @safe pure {\n        assert(split(\"hello world\"c) == [\"hello\"c, \"world\"c]);\n        assert(split(\"hello world\"w) == [\"hello\"w, \"world\"w]);\n        assert(split(\"hello world\"d) == [\"hello\"d, \"world\"d]);\n    }\n    dg();\n    assertCTFEable!dg;\n}\n\n///\n@safe unittest\n{\n    assert(split(\"hello world\") == [\"hello\",\"world\"]);\n    assert(split(\"192.168.0.1\", \".\") == [\"192\", \"168\", \"0\", \"1\"]);\n\n    auto a = split([1, 2, 3, 4, 5, 1, 2, 3, 4, 5], [2, 3]);\n    assert(a == [[1], [4, 5, 1], [4, 5]]);\n}\n\n///ditto\nauto split(Range, Separator)(Range range, Separator sep)\nif (isForwardRange!Range && (\n    is(typeof(ElementType!Range.init == Separator.init)) ||\n    is(typeof(ElementType!Range.init == ElementType!Separator.init)) && isForwardRange!Separator\n    ))\n{\n    import std.algorithm.iteration : splitter;\n    return range.splitter(sep).array;\n}\n///ditto\nauto split(alias isTerminator, Range)(Range range)\nif (isForwardRange!Range && is(typeof(unaryFun!isTerminator(range.front))))\n{\n    import std.algorithm.iteration : splitter;\n    return range.splitter!isTerminator.array;\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : cmp;\n    import std.conv;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring,\n                    immutable(string), immutable(wstring), immutable(dstring),\n                    char[], wchar[], dchar[],\n                    const(char)[], const(wchar)[], const(dchar)[],\n                    const(char[]), immutable(char[])))\n    {{\n        S s = to!S(\",peter,paul,jerry,\");\n\n        auto words = split(s, \",\");\n        assert(words.length == 5, text(words.length));\n        assert(cmp(words[0], \"\") == 0);\n        assert(cmp(words[1], \"peter\") == 0);\n        assert(cmp(words[2], \"paul\") == 0);\n        assert(cmp(words[3], \"jerry\") == 0);\n        assert(cmp(words[4], \"\") == 0);\n\n        auto s1 = s[0 .. s.length - 1];   // lop off trailing ','\n        words = split(s1, \",\");\n        assert(words.length == 4);\n        assert(cmp(words[3], \"jerry\") == 0);\n\n        auto s2 = s1[1 .. s1.length];   // lop off leading ','\n        words = split(s2, \",\");\n        assert(words.length == 3);\n        assert(cmp(words[0], \"peter\") == 0);\n\n        auto s3 = to!S(\",,peter,,paul,,jerry,,\");\n\n        words = split(s3, \",,\");\n        assert(words.length == 5);\n        assert(cmp(words[0], \"\") == 0);\n        assert(cmp(words[1], \"peter\") == 0);\n        assert(cmp(words[2], \"paul\") == 0);\n        assert(cmp(words[3], \"jerry\") == 0);\n        assert(cmp(words[4], \"\") == 0);\n\n        auto s4 = s3[0 .. s3.length - 2];    // lop off trailing ',,'\n        words = split(s4, \",,\");\n        assert(words.length == 4);\n        assert(cmp(words[3], \"jerry\") == 0);\n\n        auto s5 = s4[2 .. s4.length];    // lop off leading ',,'\n        words = split(s5, \",,\");\n        assert(words.length == 3);\n        assert(cmp(words[0], \"peter\") == 0);\n    }}\n}\n\n/+\n   Conservative heuristic to determine if a range can be iterated cheaply.\n   Used by `join` in decision to do an extra iteration of the range to\n   compute the resultant length. If iteration is not cheap then precomputing\n   length could be more expensive than using `Appender`.\n\n   For now, we only assume arrays are cheap to iterate.\n +/\nprivate enum bool hasCheapIteration(R) = isArray!R;\n\n/++\n   Eagerly concatenates all of the ranges in `ror` together (with the GC)\n   into one array using `sep` as the separator if present.\n\n   Params:\n        ror = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n        of input ranges\n        sep = An input range, or a single element, to join the ranges on\n\n   Returns:\n        An array of elements\n\n   See_Also:\n        For a lazy version, see $(REF joiner, std,algorithm,iteration)\n  +/\nElementEncodingType!(ElementType!RoR)[] join(RoR, R)(RoR ror, scope R sep)\nif (isInputRange!RoR &&\n    isInputRange!(Unqual!(ElementType!RoR)) &&\n    isInputRange!R &&\n    is(Unqual!(ElementType!(ElementType!RoR)) == Unqual!(ElementType!R)))\n{\n    alias RetType = typeof(return);\n    alias RetTypeElement = Unqual!(ElementEncodingType!RetType);\n    alias RoRElem = ElementType!RoR;\n\n    if (ror.empty)\n        return RetType.init;\n\n    // Constraint only requires input range for sep.\n    // This converts sep to an array (forward range) if it isn't one,\n    // and makes sure it has the same string encoding for string types.\n    static if (isSomeString!RetType &&\n               !is(RetTypeElement == Unqual!(ElementEncodingType!R)))\n    {\n        import std.conv : to;\n        auto sepArr = to!RetType(sep);\n    }\n    else static if (!isArray!R)\n        auto sepArr = array(sep);\n    else\n        alias sepArr = sep;\n\n    static if (hasCheapIteration!RoR && (hasLength!RoRElem || isNarrowString!RoRElem))\n    {\n        import std.conv : emplaceRef;\n        size_t length;          // length of result array\n        size_t rorLength;       // length of range ror\n        foreach (r; ror.save)\n        {\n            length += r.length;\n            ++rorLength;\n        }\n        if (!rorLength)\n            return null;\n        length += (rorLength - 1) * sepArr.length;\n\n        auto result = (() @trusted => uninitializedArray!(RetTypeElement[])(length))();\n        size_t len;\n        foreach (e; ror.front)\n            emplaceRef(result[len++], e);\n        ror.popFront();\n        foreach (r; ror)\n        {\n            foreach (e; sepArr)\n                emplaceRef(result[len++], e);\n            foreach (e; r)\n                emplaceRef(result[len++], e);\n        }\n        assert(len == result.length);\n        return (() @trusted => cast(RetType) result)();\n    }\n    else\n    {\n        auto result = appender!RetType();\n        put(result, ror.front);\n        ror.popFront();\n        for (; !ror.empty; ror.popFront())\n        {\n            put(result, sep);\n            put(result, ror.front);\n        }\n        return result.data;\n    }\n}\n\n@safe unittest // Issue 14230\n{\n   string[] ary = [\"\",\"aa\",\"bb\",\"cc\"]; // leaded by _empty_ element\n   assert(ary.join(\" @\") == \" @aa @bb @cc\"); // OK in 2.067b1 and olders\n}\n\n/// Ditto\nElementEncodingType!(ElementType!RoR)[] join(RoR, E)(RoR ror, scope E sep)\nif (isInputRange!RoR &&\n    isInputRange!(Unqual!(ElementType!RoR)) &&\n    is(E : ElementType!(ElementType!RoR)))\n{\n    alias RetType = typeof(return);\n    alias RetTypeElement = Unqual!(ElementEncodingType!RetType);\n    alias RoRElem = ElementType!RoR;\n\n    if (ror.empty)\n        return RetType.init;\n\n    static if (hasCheapIteration!RoR && (hasLength!RoRElem || isNarrowString!RoRElem))\n    {\n        static if (isSomeChar!E && isSomeChar!RetTypeElement && E.sizeof > RetTypeElement.sizeof)\n        {\n            import std.utf : encode;\n            RetTypeElement[4 / RetTypeElement.sizeof] encodeSpace;\n            immutable size_t sepArrLength = encode(encodeSpace, sep);\n            return join(ror, encodeSpace[0 .. sepArrLength]);\n        }\n        else\n        {\n            import std.conv : emplaceRef;\n            size_t length;\n            size_t rorLength;\n            foreach (r; ror.save)\n            {\n                length += r.length;\n                ++rorLength;\n            }\n            if (!rorLength)\n                return null;\n            length += rorLength - 1;\n            auto result = uninitializedArray!(RetTypeElement[])(length);\n\n\n            size_t len;\n            foreach (e; ror.front)\n                emplaceRef(result[len++], e);\n            ror.popFront();\n            foreach (r; ror)\n            {\n                emplaceRef(result[len++], sep);\n                foreach (e; r)\n                    emplaceRef(result[len++], e);\n            }\n            assert(len == result.length);\n            return (() @trusted => cast(RetType) result)();\n        }\n    }\n    else\n    {\n        auto result = appender!RetType();\n        put(result, ror.front);\n        ror.popFront();\n        for (; !ror.empty; ror.popFront())\n        {\n            put(result, sep);\n            put(result, ror.front);\n        }\n        return result.data;\n    }\n}\n\n@safe unittest // Issue 10895\n{\n    class A\n    {\n        string name;\n        alias name this;\n        this(string name) { this.name = name; }\n    }\n    auto a = [new A(`foo`)];\n    assert(a[0].length == 3);\n    auto temp = join(a, \" \");\n    assert(a[0].length == 3);\n    assert(temp.length == 3);\n}\n\n@safe unittest // Issue 14230\n{\n   string[] ary = [\"\",\"aa\",\"bb\",\"cc\"];\n   assert(ary.join('@') == \"@aa@bb@cc\");\n}\n\n/// Ditto\nElementEncodingType!(ElementType!RoR)[] join(RoR)(RoR ror)\nif (isInputRange!RoR &&\n    isInputRange!(Unqual!(ElementType!RoR)))\n{\n    alias RetType = typeof(return);\n    alias ConstRetTypeElement = ElementEncodingType!RetType;\n    static if (isAssignable!(Unqual!ConstRetTypeElement, ConstRetTypeElement))\n    {\n        alias RetTypeElement = Unqual!ConstRetTypeElement;\n    }\n    else\n    {\n        alias RetTypeElement = ConstRetTypeElement;\n    }\n    alias RoRElem = ElementType!RoR;\n\n    if (ror.empty)\n        return RetType.init;\n\n    static if (hasCheapIteration!RoR && (hasLength!RoRElem || isNarrowString!RoRElem))\n    {\n        import std.conv : emplaceRef;\n        size_t length;\n        foreach (r; ror.save)\n            length += r.length;\n\n        auto result = (() @trusted => uninitializedArray!(RetTypeElement[])(length))();\n        size_t len;\n        foreach (r; ror)\n            foreach (e; r)\n                emplaceRef!RetTypeElement(result[len++], e);\n        assert(len == result.length);\n        return (() @trusted => cast(RetType) result)();\n    }\n    else\n    {\n        auto result = appender!RetType();\n        for (; !ror.empty; ror.popFront())\n            put(result, ror.front);\n        return result.data;\n    }\n}\n\n///\n@safe pure nothrow unittest\n{\n    assert(join([\"hello\", \"silly\", \"world\"], \" \") == \"hello silly world\");\n    assert(join([\"hello\", \"silly\", \"world\"]) == \"hellosillyworld\");\n\n    assert(join([[1, 2, 3], [4, 5]], [72, 73]) == [1, 2, 3, 72, 73, 4, 5]);\n    assert(join([[1, 2, 3], [4, 5]]) == [1, 2, 3, 4, 5]);\n\n    const string[] arr = [\"apple\", \"banana\"];\n    assert(arr.join(\",\") == \"apple,banana\");\n    assert(arr.join() == \"applebanana\");\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n\n    static foreach (T; AliasSeq!(string,wstring,dstring))\n    {{\n        auto arr2 = \"Здравствуй Мир Unicode\".to!(T);\n        auto arr = [\"Здравствуй\", \"Мир\", \"Unicode\"].to!(T[]);\n        assert(join(arr) == \"ЗдравствуйМирUnicode\");\n        static foreach (S; AliasSeq!(char,wchar,dchar))\n        {{\n            auto jarr = arr.join(to!S(' '));\n            static assert(is(typeof(jarr) == T));\n            assert(jarr == arr2);\n        }}\n        static foreach (S; AliasSeq!(string,wstring,dstring))\n        {{\n            auto jarr = arr.join(to!S(\" \"));\n            static assert(is(typeof(jarr) == T));\n            assert(jarr == arr2);\n        }}\n    }}\n\n    static foreach (T; AliasSeq!(string,wstring,dstring))\n    {{\n        auto arr2 = \"Здравствуй\\u047CМир\\u047CUnicode\".to!(T);\n        auto arr = [\"Здравствуй\", \"Мир\", \"Unicode\"].to!(T[]);\n        static foreach (S; AliasSeq!(wchar,dchar))\n        {{\n            auto jarr = arr.join(to!S('\\u047C'));\n            static assert(is(typeof(jarr) == T));\n            assert(jarr == arr2);\n        }}\n    }}\n\n    const string[] arr = [\"apple\", \"banana\"];\n    assert(arr.join(',') == \"apple,banana\");\n}\n\n@safe unittest\n{\n    class A { }\n\n    const A[][] array;\n    auto result = array.join; // can't remove constness, so don't try\n\n    static assert(is(typeof(result) == const(A)[]));\n}\n\n@safe unittest\n{\n    import std.algorithm;\n    import std.conv : to;\n    import std.range;\n\n    static foreach (R; AliasSeq!(string, wstring, dstring))\n    {{\n        R word1 = \"日本語\";\n        R word2 = \"paul\";\n        R word3 = \"jerry\";\n        R[] words = [word1, word2, word3];\n\n        auto filteredWord1    = filter!\"true\"(word1);\n        auto filteredLenWord1 = takeExactly(filteredWord1, word1.walkLength());\n        auto filteredWord2    = filter!\"true\"(word2);\n        auto filteredLenWord2 = takeExactly(filteredWord2, word2.walkLength());\n        auto filteredWord3    = filter!\"true\"(word3);\n        auto filteredLenWord3 = takeExactly(filteredWord3, word3.walkLength());\n        auto filteredWordsArr = [filteredWord1, filteredWord2, filteredWord3];\n        auto filteredLenWordsArr = [filteredLenWord1, filteredLenWord2, filteredLenWord3];\n        auto filteredWords    = filter!\"true\"(filteredWordsArr);\n\n        static foreach (S; AliasSeq!(string, wstring, dstring))\n        {{\n            assert(join(filteredWords, to!S(\", \")) == \"日本語, paul, jerry\");\n            assert(join(filteredWords, to!(ElementType!S)(',')) == \"日本語,paul,jerry\");\n            assert(join(filteredWordsArr, to!(ElementType!(S))(',')) == \"日本語,paul,jerry\");\n            assert(join(filteredWordsArr, to!S(\", \")) == \"日本語, paul, jerry\");\n            assert(join(filteredWordsArr, to!(ElementType!(S))(',')) == \"日本語,paul,jerry\");\n            assert(join(filteredLenWordsArr, to!S(\", \")) == \"日本語, paul, jerry\");\n            assert(join(filter!\"true\"(words), to!S(\", \")) == \"日本語, paul, jerry\");\n            assert(join(words, to!S(\", \")) == \"日本語, paul, jerry\");\n\n            assert(join(filteredWords, to!S(\"\")) == \"日本語pauljerry\");\n            assert(join(filteredWordsArr, to!S(\"\")) == \"日本語pauljerry\");\n            assert(join(filteredLenWordsArr, to!S(\"\")) == \"日本語pauljerry\");\n            assert(join(filter!\"true\"(words), to!S(\"\")) == \"日本語pauljerry\");\n            assert(join(words, to!S(\"\")) == \"日本語pauljerry\");\n\n            assert(join(filter!\"true\"([word1]), to!S(\", \")) == \"日本語\");\n            assert(join([filteredWord1], to!S(\", \")) == \"日本語\");\n            assert(join([filteredLenWord1], to!S(\", \")) == \"日本語\");\n            assert(join(filter!\"true\"([filteredWord1]), to!S(\", \")) == \"日本語\");\n            assert(join([word1], to!S(\", \")) == \"日本語\");\n\n            assert(join(filteredWords, to!S(word1)) == \"日本語日本語paul日本語jerry\");\n            assert(join(filteredWordsArr, to!S(word1)) == \"日本語日本語paul日本語jerry\");\n            assert(join(filteredLenWordsArr, to!S(word1)) == \"日本語日本語paul日本語jerry\");\n            assert(join(filter!\"true\"(words), to!S(word1)) == \"日本語日本語paul日本語jerry\");\n            assert(join(words, to!S(word1)) == \"日本語日本語paul日本語jerry\");\n\n            auto filterComma = filter!\"true\"(to!S(\", \"));\n            assert(join(filteredWords, filterComma) == \"日本語, paul, jerry\");\n            assert(join(filteredWordsArr, filterComma) == \"日本語, paul, jerry\");\n            assert(join(filteredLenWordsArr, filterComma) == \"日本語, paul, jerry\");\n            assert(join(filter!\"true\"(words), filterComma) == \"日本語, paul, jerry\");\n            assert(join(words, filterComma) == \"日本語, paul, jerry\");\n        }}\n\n        assert(join(filteredWords) == \"日本語pauljerry\");\n        assert(join(filteredWordsArr) == \"日本語pauljerry\");\n        assert(join(filteredLenWordsArr) == \"日本語pauljerry\");\n        assert(join(filter!\"true\"(words)) == \"日本語pauljerry\");\n        assert(join(words) == \"日本語pauljerry\");\n\n        assert(join(filteredWords, filter!\"true\"(\", \")) == \"日本語, paul, jerry\");\n        assert(join(filteredWordsArr, filter!\"true\"(\", \")) == \"日本語, paul, jerry\");\n        assert(join(filteredLenWordsArr, filter!\"true\"(\", \")) == \"日本語, paul, jerry\");\n        assert(join(filter!\"true\"(words), filter!\"true\"(\", \")) == \"日本語, paul, jerry\");\n        assert(join(words, filter!\"true\"(\", \")) == \"日本語, paul, jerry\");\n\n        assert(join(filter!\"true\"(cast(typeof(filteredWordsArr))[]), \", \").empty);\n        assert(join(cast(typeof(filteredWordsArr))[], \", \").empty);\n        assert(join(cast(typeof(filteredLenWordsArr))[], \", \").empty);\n        assert(join(filter!\"true\"(cast(R[])[]), \", \").empty);\n        assert(join(cast(R[])[], \", \").empty);\n\n        assert(join(filter!\"true\"(cast(typeof(filteredWordsArr))[])).empty);\n        assert(join(cast(typeof(filteredWordsArr))[]).empty);\n        assert(join(cast(typeof(filteredLenWordsArr))[]).empty);\n\n        assert(join(filter!\"true\"(cast(R[])[])).empty);\n        assert(join(cast(R[])[]).empty);\n    }}\n\n    assert(join([[1, 2], [41, 42]], [5, 6]) == [1, 2, 5, 6, 41, 42]);\n    assert(join([[1, 2], [41, 42]], cast(int[])[]) == [1, 2, 41, 42]);\n    assert(join([[1, 2]], [5, 6]) == [1, 2]);\n    assert(join(cast(int[][])[], [5, 6]).empty);\n\n    assert(join([[1, 2], [41, 42]]) == [1, 2, 41, 42]);\n    assert(join(cast(int[][])[]).empty);\n\n    alias f = filter!\"true\";\n    assert(join([[1, 2], [41, 42]],          [5, 6]) == [1, 2, 5, 6, 41, 42]);\n    assert(join(f([[1, 2], [41, 42]]),       [5, 6]) == [1, 2, 5, 6, 41, 42]);\n    assert(join([f([1, 2]), f([41, 42])],    [5, 6]) == [1, 2, 5, 6, 41, 42]);\n    assert(join(f([f([1, 2]), f([41, 42])]), [5, 6]) == [1, 2, 5, 6, 41, 42]);\n    assert(join([[1, 2], [41, 42]],          f([5, 6])) == [1, 2, 5, 6, 41, 42]);\n    assert(join(f([[1, 2], [41, 42]]),       f([5, 6])) == [1, 2, 5, 6, 41, 42]);\n    assert(join([f([1, 2]), f([41, 42])],    f([5, 6])) == [1, 2, 5, 6, 41, 42]);\n    assert(join(f([f([1, 2]), f([41, 42])]), f([5, 6])) == [1, 2, 5, 6, 41, 42]);\n}\n\n// Issue 10683\n@safe unittest\n{\n    import std.range : join;\n    import std.typecons : tuple;\n    assert([[tuple(1)]].join == [tuple(1)]);\n    assert([[tuple(\"x\")]].join == [tuple(\"x\")]);\n}\n\n// Issue 13877\n@safe unittest\n{\n    // Test that the range is iterated only once.\n    import std.algorithm.iteration : map;\n    int c = 0;\n    auto j1 = [1, 2, 3].map!(_ => [c++]).join;\n    assert(c == 3);\n    assert(j1 == [0, 1, 2]);\n\n    c = 0;\n    auto j2 = [1, 2, 3].map!(_ => [c++]).join(9);\n    assert(c == 3);\n    assert(j2 == [0, 9, 1, 9, 2]);\n\n    c = 0;\n    auto j3 = [1, 2, 3].map!(_ => [c++]).join([9]);\n    assert(c == 3);\n    assert(j3 == [0, 9, 1, 9, 2]);\n}\n\n\n/++\n    Replace occurrences of `from` with `to` in `subject` in a new array.\n\n    Params:\n        subject = the array to scan\n        from = the item to replace\n        to = the item to replace all instances of `from` with\n\n    Returns:\n        A new array without changing the contents of `subject`, or the original\n        array if no match is found.\n\n    See_Also:\n        $(REF substitute, std,algorithm,iteration) for a lazy replace.\n +/\nE[] replace(E, R1, R2)(E[] subject, R1 from, R2 to)\nif (isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2\n        && (hasLength!R2 || isSomeString!R2))\n{\n    import std.algorithm.searching : find;\n    import std.range : dropOne;\n\n    if (from.empty) return subject;\n\n    auto balance = find(subject, from.save);\n    if (balance.empty)\n        return subject;\n\n    auto app = appender!(E[])();\n    app.put(subject[0 .. subject.length - balance.length]);\n    app.put(to.save);\n    // replacing an element in an array is different to a range replacement\n    static if (is(Unqual!E : Unqual!R1))\n        replaceInto(app, balance.dropOne, from, to);\n    else\n        replaceInto(app, balance[from.length .. $], from, to);\n\n    return app.data;\n}\n\n///\n@safe unittest\n{\n    assert(\"Hello Wörld\".replace(\"o Wö\", \"o Wo\") == \"Hello World\");\n    assert(\"Hello Wörld\".replace(\"l\", \"h\") == \"Hehho Wörhd\");\n}\n\n@safe unittest\n{\n    assert([1, 2, 3, 4, 2].replace([2], [5]) == [1, 5, 3, 4, 5]);\n    assert([3, 3, 3].replace([3], [0]) == [0, 0, 0]);\n    assert([3, 3, 4, 3].replace([3, 3], [1, 1, 1]) == [1, 1, 1, 4, 3]);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=18215\n@safe unittest\n{\n    auto arr = [\"aaa.dd\", \"b\"];\n    arr = arr.replace(\"aaa.dd\", \".\");\n    assert(arr == [\".\", \"b\"]);\n\n    arr = [\"_\", \"_\", \"aaa.dd\", \"b\", \"c\", \"aaa.dd\", \"e\"];\n    arr = arr.replace(\"aaa.dd\", \".\");\n    assert(arr == [\"_\", \"_\", \".\", \"b\", \"c\", \".\", \"e\"]);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=18215\n@safe unittest\n{\n    assert([[0], [1, 2], [0], [3]].replace([0], [4]) == [[4], [1, 2], [4], [3]]);\n    assert([[0], [1, 2], [0], [3], [1, 2]]\n            .replace([1, 2], [0]) == [[0], [0], [0], [3], [0]]);\n    assert([[0], [1, 2], [0], [3], [1, 2], [0], [1, 2]]\n            .replace([[0], [1, 2]], [[4]]) == [[4], [0], [3], [1, 2], [4]]);\n}\n\n/++\n    Replace occurrences of `from` with `to` in `subject` and output the result into\n    `sink`.\n\n    Params:\n        sink = an $(REF_ALTTEXT output range, isOutputRange, std,range,primitives)\n        subject = the array to scan\n        from = the item to replace\n        to = the item to replace all instances of `from` with\n\n    See_Also:\n        $(REF substitute, std,algorithm,iteration) for a lazy replace.\n +/\nvoid replaceInto(E, Sink, R1, R2)(Sink sink, E[] subject, R1 from, R2 to)\nif (isOutputRange!(Sink, E) && isDynamicArray!(E[])\n    && isForwardRange!R1 && isForwardRange!R2\n    && (hasLength!R2 || isSomeString!R2))\n{\n    import std.algorithm.searching : find;\n    import std.range : dropOne;\n\n    if (from.empty)\n    {\n        sink.put(subject);\n        return;\n    }\n    for (;;)\n    {\n        auto balance = find(subject, from.save);\n        if (balance.empty)\n        {\n            sink.put(subject);\n            break;\n        }\n        sink.put(subject[0 .. subject.length - balance.length]);\n        sink.put(to.save);\n        // replacing an element in an array is different to a range replacement\n        static if (is(Unqual!E : Unqual!R1))\n            subject = balance.dropOne;\n        else\n            subject = balance[from.length .. $];\n    }\n}\n\n///\n@safe unittest\n{\n    auto arr = [1, 2, 3, 4, 5];\n    auto from = [2, 3];\n    auto to = [4, 6];\n    auto sink = appender!(int[])();\n\n    replaceInto(sink, arr, from, to);\n\n    assert(sink.data == [1, 4, 6, 4, 5]);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : cmp;\n    import std.conv : to;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[]))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[]))\n        {{\n            auto s = to!S(\"This is a foo foo list\");\n            auto from = to!T(\"foo\");\n            auto into = to!S(\"silly\");\n            S r;\n            int i;\n\n            r = replace(s, from, into);\n            i = cmp(r, \"This is a silly silly list\");\n            assert(i == 0);\n\n            r = replace(s, to!S(\"\"), into);\n            i = cmp(r, \"This is a foo foo list\");\n            assert(i == 0);\n\n            assert(replace(r, to!S(\"won't find this\"), to!S(\"whatever\")) is r);\n        }}\n    }\n\n    immutable s = \"This is a foo foo list\";\n    assert(replace(s, \"foo\", \"silly\") == \"This is a silly silly list\");\n}\n\n@safe unittest\n{\n    import std.algorithm.searching : skipOver;\n    import std.conv : to;\n\n    struct CheckOutput(C)\n    {\n        C[] desired;\n        this(C[] arr){ desired = arr; }\n        void put(C[] part){ assert(skipOver(desired, part)); }\n    }\n    static foreach (S; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[]))\n    {{\n        alias Char = ElementEncodingType!S;\n        S s = to!S(\"yet another dummy text, yet another ...\");\n        S from = to!S(\"yet another\");\n        S into = to!S(\"some\");\n        replaceInto(CheckOutput!(Char)(to!S(\"some dummy text, some ...\"))\n                    , s, from, into);\n    }}\n}\n\n/++\n    Replaces elements from `array` with indices ranging from `from`\n    (inclusive) to `to` (exclusive) with the range `stuff`.\n\n    Params:\n        subject = the array to scan\n        from = the starting index\n        to = the ending index\n        stuff = the items to replace in-between `from` and `to`\n\n    Returns:\n        A new array without changing the contents of `subject`.\n\n    See_Also:\n        $(REF substitute, std,algorithm,iteration) for a lazy replace.\n +/\nT[] replace(T, Range)(T[] subject, size_t from, size_t to, Range stuff)\nif (isInputRange!Range &&\n    (is(ElementType!Range : T) ||\n    isSomeString!(T[]) && is(ElementType!Range : dchar)))\n{\n    static if (hasLength!Range && is(ElementEncodingType!Range : T))\n    {\n        import std.algorithm.mutation : copy;\n        assert(from <= to);\n        immutable sliceLen = to - from;\n        auto retval = new Unqual!(T)[](subject.length - sliceLen + stuff.length);\n        retval[0 .. from] = subject[0 .. from];\n\n        if (!stuff.empty)\n            copy(stuff, retval[from .. from + stuff.length]);\n\n        retval[from + stuff.length .. $] = subject[to .. $];\n        static if (is(T == const) || is(T == immutable))\n        {\n            return () @trusted { return cast(T[]) retval; } ();\n        }\n        else\n        {\n            return cast(T[]) retval;\n        }\n    }\n    else\n    {\n        auto app = appender!(T[])();\n        app.put(subject[0 .. from]);\n        app.put(stuff);\n        app.put(subject[to .. $]);\n        return app.data;\n    }\n}\n\n///\n@safe unittest\n{\n    auto a = [ 1, 2, 3, 4 ];\n    auto b = a.replace(1, 3, [ 9, 9, 9 ]);\n    assert(a == [ 1, 2, 3, 4 ]);\n    assert(b == [ 1, 9, 9, 9, 4 ]);\n}\n\n@system unittest\n{\n    import core.exception;\n    import std.algorithm.iteration : filter;\n    import std.conv : to;\n    import std.exception;\n\n\n    auto a = [ 1, 2, 3, 4 ];\n    assert(replace(a, 0, 0, [5, 6, 7]) == [5, 6, 7, 1, 2, 3, 4]);\n    assert(replace(a, 0, 2, cast(int[])[]) == [3, 4]);\n    assert(replace(a, 0, 4, [5, 6, 7]) == [5, 6, 7]);\n    assert(replace(a, 0, 2, [5, 6, 7]) == [5, 6, 7, 3, 4]);\n    assert(replace(a, 2, 4, [5, 6, 7]) == [1, 2, 5, 6, 7]);\n\n    assert(replace(a, 0, 0, filter!\"true\"([5, 6, 7])) == [5, 6, 7, 1, 2, 3, 4]);\n    assert(replace(a, 0, 2, filter!\"true\"(cast(int[])[])) == [3, 4]);\n    assert(replace(a, 0, 4, filter!\"true\"([5, 6, 7])) == [5, 6, 7]);\n    assert(replace(a, 0, 2, filter!\"true\"([5, 6, 7])) == [5, 6, 7, 3, 4]);\n    assert(replace(a, 2, 4, filter!\"true\"([5, 6, 7])) == [1, 2, 5, 6, 7]);\n    assert(a == [ 1, 2, 3, 4 ]);\n\n    void testStr(T, U)(string file = __FILE__, size_t line = __LINE__)\n    {\n\n        auto l = to!T(\"hello\");\n        auto r = to!U(\" world\");\n\n        enforce(replace(l, 0, 0, r) == \" worldhello\",\n                new AssertError(\"testStr failure 1\", file, line));\n        enforce(replace(l, 0, 3, r) == \" worldlo\",\n                new AssertError(\"testStr failure 2\", file, line));\n        enforce(replace(l, 3, l.length, r) == \"hel world\",\n                new AssertError(\"testStr failure 3\", file, line));\n        enforce(replace(l, 0, l.length, r) == \" world\",\n                new AssertError(\"testStr failure 4\", file, line));\n        enforce(replace(l, l.length, l.length, r) == \"hello world\",\n                new AssertError(\"testStr failure 5\", file, line));\n    }\n\n    testStr!(string, string)();\n    testStr!(string, wstring)();\n    testStr!(string, dstring)();\n    testStr!(wstring, string)();\n    testStr!(wstring, wstring)();\n    testStr!(wstring, dstring)();\n    testStr!(dstring, string)();\n    testStr!(dstring, wstring)();\n    testStr!(dstring, dstring)();\n\n    enum s = \"0123456789\";\n    enum w = \"⁰¹²³⁴⁵⁶⁷⁸⁹\"w;\n    enum d = \"⁰¹²³⁴⁵⁶⁷⁸⁹\"d;\n\n    assert(replace(s, 0, 0, \"***\") == \"***0123456789\");\n    assert(replace(s, 10, 10, \"***\") == \"0123456789***\");\n    assert(replace(s, 3, 8, \"1012\") == \"012101289\");\n    assert(replace(s, 0, 5, \"43210\") == \"4321056789\");\n    assert(replace(s, 5, 10, \"43210\") == \"0123443210\");\n\n    assert(replace(w, 0, 0, \"***\"w) == \"***⁰¹²³⁴⁵⁶⁷⁸⁹\"w);\n    assert(replace(w, 10, 10, \"***\"w) == \"⁰¹²³⁴⁵⁶⁷⁸⁹***\"w);\n    assert(replace(w, 3, 8, \"¹⁰¹²\"w) == \"⁰¹²¹⁰¹²⁸⁹\"w);\n    assert(replace(w, 0, 5, \"⁴³²¹⁰\"w) == \"⁴³²¹⁰⁵⁶⁷⁸⁹\"w);\n    assert(replace(w, 5, 10, \"⁴³²¹⁰\"w) == \"⁰¹²³⁴⁴³²¹⁰\"w);\n\n    assert(replace(d, 0, 0, \"***\"d) == \"***⁰¹²³⁴⁵⁶⁷⁸⁹\"d);\n    assert(replace(d, 10, 10, \"***\"d) == \"⁰¹²³⁴⁵⁶⁷⁸⁹***\"d);\n    assert(replace(d, 3, 8, \"¹⁰¹²\"d) == \"⁰¹²¹⁰¹²⁸⁹\"d);\n    assert(replace(d, 0, 5, \"⁴³²¹⁰\"d) == \"⁴³²¹⁰⁵⁶⁷⁸⁹\"d);\n    assert(replace(d, 5, 10, \"⁴³²¹⁰\"d) == \"⁰¹²³⁴⁴³²¹⁰\"d);\n}\n\n// Issue 18166\n@safe pure unittest\n{\n    auto str = replace(\"aaaaa\"d, 1, 4, \"***\"d);\n    assert(str == \"a***a\");\n}\n\n/++\n    Replaces elements from `array` with indices ranging from `from`\n    (inclusive) to `to` (exclusive) with the range `stuff`. Expands or\n    shrinks the array as needed.\n\n    Params:\n        array = the array to scan\n        from = the starting index\n        to = the ending index\n        stuff = the items to replace in-between `from` and `to`\n +/\nvoid replaceInPlace(T, Range)(ref T[] array, size_t from, size_t to, Range stuff)\nif (is(typeof(replace(array, from, to, stuff))))\n{\n    static if (isDynamicArray!Range &&\n              is(Unqual!(ElementEncodingType!Range) == T) &&\n              !isNarrowString!(T[]))\n    {\n        // optimized for homogeneous arrays that can be overwritten.\n        import std.algorithm.mutation : remove;\n        import std.typecons : tuple;\n\n        if (overlap(array, stuff).length)\n        {\n            // use slower/conservative method\n            array = array[0 .. from] ~ stuff ~ array[to .. $];\n        }\n        else if (stuff.length <= to - from)\n        {\n            // replacement reduces length\n            immutable stuffEnd = from + stuff.length;\n            array[from .. stuffEnd] = stuff[];\n            if (stuffEnd < to)\n                array = remove(array, tuple(stuffEnd, to));\n        }\n        else\n        {\n            // replacement increases length\n            // @@@TODO@@@: optimize this\n            immutable replaceLen = to - from;\n            array[from .. to] = stuff[0 .. replaceLen];\n            insertInPlace(array, to, stuff[replaceLen .. $]);\n        }\n    }\n    else\n    {\n        // default implementation, just do what replace does.\n        array = replace(array, from, to, stuff);\n    }\n}\n\n///\n@safe unittest\n{\n    int[] a = [1, 4, 5];\n    replaceInPlace(a, 1u, 2u, [2, 3, 4]);\n    assert(a == [1, 2, 3, 4, 5]);\n    replaceInPlace(a, 1u, 2u, cast(int[])[]);\n    assert(a == [1, 3, 4, 5]);\n    replaceInPlace(a, 1u, 3u, a[2 .. 4]);\n    assert(a == [1, 4, 5, 5]);\n}\n\n@safe unittest\n{\n    // Bug# 12889\n    int[1][] arr = [[0], [1], [2], [3], [4], [5], [6]];\n    int[1][] stuff = [[0], [1]];\n    replaceInPlace(arr, 4, 6, stuff);\n    assert(arr == [[0], [1], [2], [3], [0], [1], [6]]);\n}\n\n@system unittest\n{\n    // Bug# 14925\n    char[] a = \"mon texte 1\".dup;\n    char[] b = \"abc\".dup;\n    replaceInPlace(a, 4, 9, b);\n    assert(a == \"mon abc 1\");\n\n    // ensure we can replace in place with different encodings\n    string unicoded = \"\\U00010437\";\n    string unicodedLong = \"\\U00010437aaaaa\";\n    string base = \"abcXXXxyz\";\n    string result = \"abc\\U00010437xyz\";\n    string resultLong = \"abc\\U00010437aaaaaxyz\";\n    size_t repstart = 3;\n    size_t repend = 3 + 3;\n\n    void testStringReplaceInPlace(T, U)()\n    {\n        import std.algorithm.comparison : equal;\n        import std.conv;\n        auto a = unicoded.to!(U[]);\n        auto b = unicodedLong.to!(U[]);\n\n        auto test = base.to!(T[]);\n\n        test.replaceInPlace(repstart, repend, a);\n        assert(equal(test, result), \"Failed for types \" ~ T.stringof ~ \" and \" ~ U.stringof);\n\n        test = base.to!(T[]);\n\n        test.replaceInPlace(repstart, repend, b);\n        assert(equal(test, resultLong), \"Failed for types \" ~ T.stringof ~ \" and \" ~ U.stringof);\n    }\n\n    import std.meta : AliasSeq;\n    alias allChars = AliasSeq!(char, immutable(char), const(char),\n                         wchar, immutable(wchar), const(wchar),\n                         dchar, immutable(dchar), const(dchar));\n    foreach (T; allChars)\n        foreach (U; allChars)\n            testStringReplaceInPlace!(T, U)();\n\n    void testInout(inout(int)[] a)\n    {\n        // will be transferred to the 'replace' function\n        replaceInPlace(a, 1, 2, [1,2,3]);\n    }\n}\n\n@safe unittest\n{\n    // the constraint for the first overload used to match this, which wouldn't compile.\n    import std.algorithm.comparison : equal;\n    long[] a = [1L, 2, 3];\n    int[] b = [4, 5, 6];\n    a.replaceInPlace(1, 2, b);\n    assert(equal(a, [1L, 4, 5, 6, 3]));\n}\n\n@system unittest\n{\n    import core.exception;\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter;\n    import std.conv : to;\n    import std.exception;\n\n\n    bool test(T, U, V)(T orig, size_t from, size_t to, U toReplace, V result)\n    {\n        {\n            static if (is(T == typeof(T.init.dup)))\n                auto a = orig.dup;\n            else\n                auto a = orig.idup;\n\n            a.replaceInPlace(from, to, toReplace);\n            if (!equal(a, result))\n                return false;\n        }\n\n        static if (isInputRange!U)\n        {\n            orig.replaceInPlace(from, to, filter!\"true\"(toReplace));\n            return equal(orig, result);\n        }\n        else\n            return true;\n    }\n\n    assert(test([1, 2, 3, 4], 0, 0, [5, 6, 7], [5, 6, 7, 1, 2, 3, 4]));\n    assert(test([1, 2, 3, 4], 0, 2, cast(int[])[], [3, 4]));\n    assert(test([1, 2, 3, 4], 0, 4, [5, 6, 7], [5, 6, 7]));\n    assert(test([1, 2, 3, 4], 0, 2, [5, 6, 7], [5, 6, 7, 3, 4]));\n    assert(test([1, 2, 3, 4], 2, 4, [5, 6, 7], [1, 2, 5, 6, 7]));\n\n    assert(test([1, 2, 3, 4], 0, 0, filter!\"true\"([5, 6, 7]), [5, 6, 7, 1, 2, 3, 4]));\n    assert(test([1, 2, 3, 4], 0, 2, filter!\"true\"(cast(int[])[]), [3, 4]));\n    assert(test([1, 2, 3, 4], 0, 4, filter!\"true\"([5, 6, 7]), [5, 6, 7]));\n    assert(test([1, 2, 3, 4], 0, 2, filter!\"true\"([5, 6, 7]), [5, 6, 7, 3, 4]));\n    assert(test([1, 2, 3, 4], 2, 4, filter!\"true\"([5, 6, 7]), [1, 2, 5, 6, 7]));\n\n    void testStr(T, U)(string file = __FILE__, size_t line = __LINE__)\n    {\n\n        auto l = to!T(\"hello\");\n        auto r = to!U(\" world\");\n\n        enforce(test(l, 0, 0, r, \" worldhello\"),\n                new AssertError(\"testStr failure 1\", file, line));\n        enforce(test(l, 0, 3, r, \" worldlo\"),\n                new AssertError(\"testStr failure 2\", file, line));\n        enforce(test(l, 3, l.length, r, \"hel world\"),\n                new AssertError(\"testStr failure 3\", file, line));\n        enforce(test(l, 0, l.length, r, \" world\"),\n                new AssertError(\"testStr failure 4\", file, line));\n        enforce(test(l, l.length, l.length, r, \"hello world\"),\n                new AssertError(\"testStr failure 5\", file, line));\n    }\n\n    testStr!(string, string)();\n    testStr!(string, wstring)();\n    testStr!(string, dstring)();\n    testStr!(wstring, string)();\n    testStr!(wstring, wstring)();\n    testStr!(wstring, dstring)();\n    testStr!(dstring, string)();\n    testStr!(dstring, wstring)();\n    testStr!(dstring, dstring)();\n}\n\n/++\n    Replaces the first occurrence of `from` with `to` in `subject`.\n\n    Params:\n        subject = the array to scan\n        from = the item to replace\n        to = the item to replace `from` with\n\n    Returns:\n        A new array without changing the contents of `subject`, or the original\n        array if no match is found.\n +/\nE[] replaceFirst(E, R1, R2)(E[] subject, R1 from, R2 to)\nif (isDynamicArray!(E[]) &&\n    isForwardRange!R1 && is(typeof(appender!(E[])().put(from[0 .. 1]))) &&\n    isForwardRange!R2 && is(typeof(appender!(E[])().put(to[0 .. 1]))))\n{\n    if (from.empty) return subject;\n    static if (isSomeString!(E[]))\n    {\n        import std.string : indexOf;\n        immutable idx = subject.indexOf(from);\n    }\n    else\n    {\n        import std.algorithm.searching : countUntil;\n        immutable idx = subject.countUntil(from);\n    }\n    if (idx == -1)\n        return subject;\n\n    auto app = appender!(E[])();\n    app.put(subject[0 .. idx]);\n    app.put(to);\n\n    static if (isSomeString!(E[]) && isSomeString!R1)\n    {\n        import std.utf : codeLength;\n        immutable fromLength = codeLength!(Unqual!E, R1)(from);\n    }\n    else\n        immutable fromLength = from.length;\n\n    app.put(subject[idx + fromLength .. $]);\n\n    return app.data;\n}\n\n///\n@safe unittest\n{\n    auto a = [1, 2, 2, 3, 4, 5];\n    auto b = a.replaceFirst([2], [1337]);\n    assert(b == [1, 1337, 2, 3, 4, 5]);\n\n    auto s = \"This is a foo foo list\";\n    auto r = s.replaceFirst(\"foo\", \"silly\");\n    assert(r == \"This is a silly foo list\");\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : cmp;\n    import std.conv : to;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[],\n                          const(char[]), immutable(char[])))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[],\n                              const(char[]), immutable(char[])))\n        {{\n            auto s = to!S(\"This is a foo foo list\");\n            auto s2 = to!S(\"Thüs is a ßöö foo list\");\n            auto from = to!T(\"foo\");\n            auto from2 = to!T(\"ßöö\");\n            auto into = to!T(\"silly\");\n            auto into2 = to!T(\"sälly\");\n\n            S r1 = replaceFirst(s, from, into);\n            assert(cmp(r1, \"This is a silly foo list\") == 0);\n\n            S r11 = replaceFirst(s2, from2, into2);\n            assert(cmp(r11, \"Thüs is a sälly foo list\") == 0,\n                to!string(r11) ~ \" : \" ~ S.stringof ~ \" \" ~ T.stringof);\n\n            S r2 = replaceFirst(r1, from, into);\n            assert(cmp(r2, \"This is a silly silly list\") == 0);\n\n            S r3 = replaceFirst(s, to!T(\"\"), into);\n            assert(cmp(r3, \"This is a foo foo list\") == 0);\n\n            assert(replaceFirst(r3, to!T(\"won't find\"), to!T(\"whatever\")) is r3);\n        }}\n    }\n}\n\n//Bug# 8187\n@safe unittest\n{\n    auto res = [\"a\", \"a\"];\n    assert(replace(res, \"a\", \"b\") == [\"b\", \"b\"]);\n    assert(replaceFirst(res, \"a\", \"b\") == [\"b\", \"a\"]);\n}\n\n/++\n    Replaces the last occurrence of `from` with `to` in `subject`.\n\n    Params:\n        subject = the array to scan\n        from = the item to replace\n        to = the item to replace `from` with\n\n    Returns:\n        A new array without changing the contents of `subject`, or the original\n        array if no match is found.\n +/\nE[] replaceLast(E, R1, R2)(E[] subject, R1 from , R2 to)\nif (isDynamicArray!(E[]) &&\n    isForwardRange!R1 && is(typeof(appender!(E[])().put(from[0 .. 1]))) &&\n    isForwardRange!R2 && is(typeof(appender!(E[])().put(to[0 .. 1]))))\n{\n    import std.range : retro;\n    if (from.empty) return subject;\n    static if (isSomeString!(E[]))\n    {\n        import std.string : lastIndexOf;\n        auto idx = subject.lastIndexOf(from);\n    }\n    else\n    {\n        import std.algorithm.searching : countUntil;\n        auto idx = retro(subject).countUntil(retro(from));\n    }\n\n    if (idx == -1)\n        return subject;\n\n    static if (isSomeString!(E[]) && isSomeString!R1)\n    {\n        import std.utf : codeLength;\n        auto fromLength = codeLength!(Unqual!E, R1)(from);\n    }\n    else\n        auto fromLength = from.length;\n\n    auto app = appender!(E[])();\n    static if (isSomeString!(E[]))\n        app.put(subject[0 .. idx]);\n    else\n        app.put(subject[0 .. $ - idx - fromLength]);\n\n    app.put(to);\n\n    static if (isSomeString!(E[]))\n        app.put(subject[idx+fromLength .. $]);\n    else\n        app.put(subject[$ - idx .. $]);\n\n    return app.data;\n}\n\n///\n@safe unittest\n{\n    auto a = [1, 2, 2, 3, 4, 5];\n    auto b = a.replaceLast([2], [1337]);\n    assert(b == [1, 2, 1337, 3, 4, 5]);\n\n    auto s = \"This is a foo foo list\";\n    auto r = s.replaceLast(\"foo\", \"silly\");\n    assert(r == \"This is a foo silly list\", r);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : cmp;\n    import std.conv : to;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[],\n                          const(char[]), immutable(char[])))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[],\n                              const(char[]), immutable(char[])))\n        {{\n            auto s = to!S(\"This is a foo foo list\");\n            auto s2 = to!S(\"Thüs is a ßöö ßöö list\");\n            auto from = to!T(\"foo\");\n            auto from2 = to!T(\"ßöö\");\n            auto into = to!T(\"silly\");\n            auto into2 = to!T(\"sälly\");\n\n            S r1 = replaceLast(s, from, into);\n            assert(cmp(r1, \"This is a foo silly list\") == 0, to!string(r1));\n\n            S r11 = replaceLast(s2, from2, into2);\n            assert(cmp(r11, \"Thüs is a ßöö sälly list\") == 0,\n                to!string(r11) ~ \" : \" ~ S.stringof ~ \" \" ~ T.stringof);\n\n            S r2 = replaceLast(r1, from, into);\n            assert(cmp(r2, \"This is a silly silly list\") == 0);\n\n            S r3 = replaceLast(s, to!T(\"\"), into);\n            assert(cmp(r3, \"This is a foo foo list\") == 0);\n\n            assert(replaceLast(r3, to!T(\"won't find\"), to!T(\"whatever\")) is r3);\n        }}\n    }\n}\n\n/++\n    Creates a new array such that the items in `slice` are replaced with the\n    items in `replacement`. `slice` and `replacement` do not need to be the\n    same length. The result will grow or shrink based on the items given.\n\n    Params:\n        s = the base of the new array\n        slice = the slice of `s` to be replaced\n        replacement = the items to replace `slice` with\n\n    Returns:\n        A new array that is `s` with `slice` replaced by\n        `replacement[]`.\n\n    See_Also:\n        $(REF substitute, std,algorithm,iteration) for a lazy replace.\n +/\ninout(T)[] replaceSlice(T)(inout(T)[] s, in T[] slice, in T[] replacement)\nin\n{\n    // Verify that slice[] really is a slice of s[]\n    assert(overlap(s, slice) is slice);\n}\ndo\n{\n    auto result = new T[s.length - slice.length + replacement.length];\n    immutable so = &slice[0] - &s[0];\n    result[0 .. so] = s[0 .. so];\n    result[so .. so + replacement.length] = replacement[];\n    result[so + replacement.length .. result.length] =\n        s[so + slice.length .. s.length];\n\n    return () @trusted inout {\n        return cast(inout(T)[]) result;\n    }();\n}\n\n///\n@safe unittest\n{\n    auto a = [1, 2, 3, 4, 5];\n    auto b = replaceSlice(a, a[1 .. 4], [0, 0, 0]);\n\n    assert(b == [1, 0, 0, 0, 5]);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : cmp;\n\n    string s = \"hello\";\n    string slice = s[2 .. 4];\n\n    auto r = replaceSlice(s, slice, \"bar\");\n    int i;\n    i = cmp(r, \"hebaro\");\n    assert(i == 0);\n}\n\n/**\nImplements an output range that appends data to an array. This is\nrecommended over $(D array ~= data) when appending many elements because it is more\nefficient. `Appender` maintains its own array metadata locally, so it can avoid\nglobal locking for each append where $(LREF capacity) is non-zero.\n\nParams:\n    A = the array type to simulate.\n\nSee_Also: $(LREF appender)\n */\nstruct Appender(A)\nif (isDynamicArray!A)\n{\n    import core.memory : GC;\n    import std.format : FormatSpec;\n\n    private alias T = ElementEncodingType!A;\n\n    private struct Data\n    {\n        size_t capacity;\n        Unqual!T[] arr;\n        bool canExtend = false;\n    }\n\n    private Data* _data;\n\n    /**\n     * Constructs an `Appender` with a given array.  Note that this does not copy the\n     * data.  If the array has a larger capacity as determined by `arr.capacity`,\n     * it will be used by the appender.  After initializing an appender on an array,\n     * appending to the original array will reallocate.\n     */\n    this(A arr) @trusted pure nothrow\n    {\n        // initialize to a given array.\n        _data = new Data;\n        _data.arr = cast(Unqual!T[]) arr; //trusted\n\n        if (__ctfe)\n            return;\n\n        // We want to use up as much of the block the array is in as possible.\n        // if we consume all the block that we can, then array appending is\n        // safe WRT built-in append, and we can use the entire block.\n        // We only do this for mutable types that can be extended.\n        static if (isMutable!T && is(typeof(arr.length = size_t.max)))\n        {\n            immutable cap = arr.capacity; //trusted\n            // Replace with \"GC.setAttr( Not Appendable )\" once pure (and fixed)\n            if (cap > arr.length)\n                arr.length = cap;\n        }\n        _data.capacity = arr.length;\n    }\n\n    /**\n     * Reserve at least newCapacity elements for appending.  Note that more elements\n     * may be reserved than requested. If `newCapacity <= capacity`, then nothing is\n     * done.\n     *\n     * Params:\n     *     newCapacity = the capacity the `Appender` should have\n     */\n    void reserve(size_t newCapacity) @safe pure nothrow\n    {\n        if (_data)\n        {\n            if (newCapacity > _data.capacity)\n                ensureAddable(newCapacity - _data.arr.length);\n        }\n        else\n        {\n            ensureAddable(newCapacity);\n        }\n    }\n\n    /**\n     * Returns: the capacity of the array (the maximum number of elements the\n     * managed array can accommodate before triggering a reallocation). If any\n     * appending will reallocate, `0` will be returned.\n     */\n    @property size_t capacity() const @safe pure nothrow\n    {\n        return _data ? _data.capacity : 0;\n    }\n\n    /**\n     * Returns: The managed array.\n     */\n    @property inout(ElementEncodingType!A)[] data() inout @trusted pure nothrow\n    {\n        /* @trusted operation:\n         * casting Unqual!T[] to inout(T)[]\n         */\n        return cast(typeof(return))(_data ? _data.arr : null);\n    }\n\n    // ensure we can add nelems elements, resizing as necessary\n    private void ensureAddable(size_t nelems) @trusted pure nothrow\n    {\n        if (!_data)\n            _data = new Data;\n        immutable len = _data.arr.length;\n        immutable reqlen = len + nelems;\n\n        if (_data.capacity >= reqlen)\n            return;\n\n        // need to increase capacity\n        if (__ctfe)\n        {\n            static if (__traits(compiles, new Unqual!T[1]))\n            {\n                _data.arr.length = reqlen;\n            }\n            else\n            {\n                // avoid restriction of @disable this()\n                _data.arr = _data.arr[0 .. _data.capacity];\n                foreach (i; _data.capacity .. reqlen)\n                    _data.arr ~= Unqual!T.init;\n            }\n            _data.arr = _data.arr[0 .. len];\n            _data.capacity = reqlen;\n        }\n        else\n        {\n            // Time to reallocate.\n            // We need to almost duplicate what's in druntime, except we\n            // have better access to the capacity field.\n            auto newlen = appenderNewCapacity!(T.sizeof)(_data.capacity, reqlen);\n            // first, try extending the current block\n            if (_data.canExtend)\n            {\n                immutable u = GC.extend(_data.arr.ptr, nelems * T.sizeof, (newlen - len) * T.sizeof);\n                if (u)\n                {\n                    // extend worked, update the capacity\n                    _data.capacity = u / T.sizeof;\n                    return;\n                }\n            }\n\n\n            // didn't work, must reallocate\n            import core.checkedint : mulu;\n            bool overflow;\n            const nbytes = mulu(newlen, T.sizeof, overflow);\n            if (overflow) assert(0);\n\n            auto bi = GC.qalloc(nbytes, blockAttribute!T);\n            _data.capacity = bi.size / T.sizeof;\n            import core.stdc.string : memcpy;\n            if (len)\n                memcpy(bi.base, _data.arr.ptr, len * T.sizeof);\n            _data.arr = (cast(Unqual!T*) bi.base)[0 .. len];\n            _data.canExtend = true;\n            // leave the old data, for safety reasons\n        }\n    }\n\n    private template canPutItem(U)\n    {\n        enum bool canPutItem =\n            isImplicitlyConvertible!(U, T) ||\n            isSomeChar!T && isSomeChar!U;\n    }\n    private template canPutConstRange(Range)\n    {\n        enum bool canPutConstRange =\n            isInputRange!(Unqual!Range) &&\n            !isInputRange!Range &&\n            is(typeof(Appender.init.put(Range.init.front)));\n    }\n    private template canPutRange(Range)\n    {\n        enum bool canPutRange =\n            isInputRange!Range &&\n            is(typeof(Appender.init.put(Range.init.front)));\n    }\n\n    /**\n     * Appends `item` to the managed array. Performs encoding for\n     * `char` types if `A` is a differently typed `char` array.\n     *\n     * Params:\n     *     item = the single item to append\n     */\n    void put(U)(U item) if (canPutItem!U)\n    {\n        static if (isSomeChar!T && isSomeChar!U && T.sizeof < U.sizeof)\n        {\n            /* may throwable operation:\n             * - std.utf.encode\n             */\n            // must do some transcoding around here\n            import std.utf : encode;\n            Unqual!T[T.sizeof == 1 ? 4 : 2] encoded;\n            auto len = encode(encoded, item);\n            put(encoded[0 .. len]);\n        }\n        else\n        {\n            import std.conv : emplaceRef;\n\n            ensureAddable(1);\n            immutable len = _data.arr.length;\n\n            auto bigData = (() @trusted => _data.arr.ptr[0 .. len + 1])();\n            emplaceRef!(Unqual!T)(bigData[len], cast(Unqual!T) item);\n            //We do this at the end, in case of exceptions\n            _data.arr = bigData;\n        }\n    }\n\n    // Const fixing hack.\n    void put(Range)(Range items) if (canPutConstRange!Range)\n    {\n        alias p = put!(Unqual!Range);\n        p(items);\n    }\n\n    /**\n     * Appends an entire range to the managed array. Performs encoding for\n     * `char` elements if `A` is a differently typed `char` array.\n     *\n     * Params:\n     *     items = the range of items to append\n     */\n    void put(Range)(Range items) if (canPutRange!Range)\n    {\n        // note, we disable this branch for appending one type of char to\n        // another because we can't trust the length portion.\n        static if (!(isSomeChar!T && isSomeChar!(ElementType!Range) &&\n                     !is(immutable Range == immutable T[])) &&\n                    is(typeof(items.length) == size_t))\n        {\n            // optimization -- if this type is something other than a string,\n            // and we are adding exactly one element, call the version for one\n            // element.\n            static if (!isSomeChar!T)\n            {\n                if (items.length == 1)\n                {\n                    put(items.front);\n                    return;\n                }\n            }\n\n            // make sure we have enough space, then add the items\n            @trusted auto bigDataFun(size_t extra)\n            {\n                ensureAddable(extra);\n                return _data.arr.ptr[0 .. _data.arr.length + extra];\n            }\n            auto bigData = bigDataFun(items.length);\n\n            immutable len = _data.arr.length;\n            immutable newlen = bigData.length;\n\n            alias UT = Unqual!T;\n\n            static if (is(typeof(_data.arr[] = items[])) &&\n                !hasElaborateAssign!UT && isAssignable!(UT, ElementEncodingType!Range))\n            {\n                bigData[len .. newlen] = items[];\n            }\n            else\n            {\n                import std.conv : emplaceRef;\n                foreach (ref it ; bigData[len .. newlen])\n                {\n                    emplaceRef!T(it, items.front);\n                    items.popFront();\n                }\n            }\n\n            //We do this at the end, in case of exceptions\n            _data.arr = bigData;\n        }\n        else\n        {\n            //pragma(msg, Range.stringof);\n            // Generic input range\n            for (; !items.empty; items.popFront())\n            {\n                put(items.front);\n            }\n        }\n    }\n\n    /**\n     * Appends `rhs` to the managed array.\n     * Params:\n     *     op = the assignment operator `~`\n     *     rhs = Element or range.\n     */\n    void opOpAssign(string op : \"~\", U)(U rhs)\n    if (__traits(compiles, put(rhs)))\n    {\n        put(rhs);\n    }\n\n    // only allow overwriting data on non-immutable and non-const data\n    static if (isMutable!T)\n    {\n        /**\n         * Clears the managed array.  This allows the elements of the array to be reused\n         * for appending.\n         *\n         * Note: clear is disabled for immutable or const element types, due to the\n         * possibility that `Appender` might overwrite immutable data.\n         */\n        void clear() @trusted pure nothrow\n        {\n            if (_data)\n            {\n                _data.arr = _data.arr.ptr[0 .. 0];\n            }\n        }\n\n        /**\n         * Shrinks the managed array to the given length.\n         *\n         * Throws: `Exception` if newlength is greater than the current array length.\n         * Note: shrinkTo is disabled for immutable or const element types.\n         */\n        void shrinkTo(size_t newlength) @trusted pure\n        {\n            import std.exception : enforce;\n            if (_data)\n            {\n                enforce(newlength <= _data.arr.length, \"Attempting to shrink Appender with newlength > length\");\n                _data.arr = _data.arr.ptr[0 .. newlength];\n            }\n            else\n                enforce(newlength == 0, \"Attempting to shrink empty Appender with non-zero newlength\");\n        }\n    }\n\n    /**\n     * Gives a string in the form of `Appender!(A)(data)`.\n     *\n     * Params:\n     *     w = A `char` accepting\n     *     $(REF_ALTTEXT output range, isOutputRange, std, range, primitives).\n     *     fmt = A $(REF FormatSpec, std, format) which controls how the array\n     *     is formatted.\n     * Returns:\n     *     A `string` if `writer` is not set; `void` otherwise.\n     */\n    string toString() const\n    {\n        import std.format : singleSpec;\n\n        auto app = appender!string();\n        auto spec = singleSpec(\"%s\");\n        // different reserve lengths because each element in a\n        // non-string-like array uses two extra characters for `, `.\n        static if (isSomeString!A)\n        {\n            app.reserve(_data.arr.length + 25);\n        }\n        else\n        {\n            // Multiplying by three is a very conservative estimate of\n            // length, as it assumes each element is only one char\n            app.reserve((_data.arr.length * 3) + 25);\n        }\n        toString(app, spec);\n        return app.data;\n    }\n\n    /// ditto\n    void toString(Writer)(ref Writer w, const ref FormatSpec!char fmt) const\n    if (isOutputRange!(Writer, char))\n    {\n        import std.format : formatValue;\n        import std.range.primitives : put;\n        put(w, Unqual!(typeof(this)).stringof);\n        put(w, '(');\n        formatValue(w, data, fmt);\n        put(w, ')');\n    }\n\n    // @@@DEPRECATED_2.089@@@\n    deprecated(\"To be removed after 2.089. Please use the output range overload.\")\n    void toString(Writer)(scope Writer w)\n    if (isCallable!Writer)\n    {\n        import std.format : formattedWrite;\n        w.formattedWrite(typeof(this).stringof ~ \"(%s)\", data);\n    }\n}\n\n///\n@safe unittest\n{\n    auto app = appender!string();\n    string b = \"abcdefg\";\n    foreach (char c; b)\n        app.put(c);\n    assert(app.data == \"abcdefg\");\n\n    int[] a = [ 1, 2 ];\n    auto app2 = appender(a);\n    app2.put(3);\n    app2.put([ 4, 5, 6 ]);\n    assert(app2.data == [ 1, 2, 3, 4, 5, 6 ]);\n}\n\n@safe pure unittest\n{\n    import std.format : format, singleSpec;\n\n    auto app = appender!(int[])();\n    app.put(1);\n    app.put(2);\n    app.put(3);\n    assert(\"%s\".format(app) == \"Appender!(int[])(%s)\".format([1,2,3]));\n\n    auto app2 = appender!string();\n    auto spec = singleSpec(\"%s\");\n    app.toString(app2, spec);\n    assert(app2.data == \"Appender!(int[])([1, 2, 3])\");\n\n    auto app3 = appender!string();\n    spec = singleSpec(\"%(%04d, %)\");\n    app.toString(app3, spec);\n    assert(app3.data == \"Appender!(int[])(0001, 0002, 0003)\");\n}\n\n@safe unittest // issue 17251\n{\n    static struct R\n    {\n        int front() const { return 0; }\n        bool empty() const { return true; }\n        void popFront() {}\n    }\n\n    auto app = appender!(R[]);\n    const(R)[1] r;\n    app.put(r[0]);\n    app.put(r[]);\n}\n\n//Calculates an efficient growth scheme based on the old capacity\n//of data, and the minimum requested capacity.\n//arg curLen: The current length\n//arg reqLen: The length as requested by the user\n//ret sugLen: A suggested growth.\nprivate size_t appenderNewCapacity(size_t TSizeOf)(size_t curLen, size_t reqLen) @safe pure nothrow\n{\n    import core.bitop : bsr;\n    import std.algorithm.comparison : max;\n    if (curLen == 0)\n        return max(reqLen,8);\n    ulong mult = 100 + (1000UL) / (bsr(curLen * TSizeOf) + 1);\n    // limit to doubling the length, we don't want to grow too much\n    if (mult > 200)\n        mult = 200;\n    auto sugLen = cast(size_t)((curLen * mult + 99) / 100);\n    return max(reqLen, sugLen);\n}\n\n/**\n * A version of $(LREF Appender) that can update an array in-place.\n * It forwards all calls to an underlying appender implementation.\n * Any calls made to the appender also update the pointer to the\n * original array passed in.\n *\n * Tip: Use the `arrayPtr` overload of $(LREF appender) for construction with type-inference.\n *\n * Params:\n *     A = The array type to simulate\n */\nstruct RefAppender(A)\nif (isDynamicArray!A)\n{\n    private\n    {\n        Appender!A impl;\n        A* arr;\n    }\n\n    /**\n     * Constructs a `RefAppender` with a given array reference.  This does not copy the\n     * data.  If the array has a larger capacity as determined by `arr.capacity`, it\n     * will be used by the appender.\n     *\n     * Note: Do not use built-in appending (i.e. `~=`) on the original array\n     * until you are done with the appender, because subsequent calls to the appender\n     * will reallocate the array data without those appends.\n     *\n     * Params:\n     * arr = Pointer to an array. Must not be _null.\n     */\n    this(A* arr)\n    {\n        impl = Appender!A(*arr);\n        this.arr = arr;\n    }\n\n    /** Wraps remaining `Appender` methods such as $(LREF put).\n     * Params:\n     * fn = Method name to call.\n     * args = Arguments to pass to the method.\n     */\n    void opDispatch(string fn, Args...)(Args args)\n    if (__traits(compiles, (Appender!A a) => mixin(\"a.\" ~ fn ~ \"(args)\")))\n    {\n        // we do it this way because we can't cache a void return\n        scope(exit) *this.arr = impl.data;\n        mixin(\"return impl.\" ~ fn ~ \"(args);\");\n    }\n\n    /**\n     * Appends `rhs` to the managed array.\n     * Params:\n     * rhs = Element or range.\n     */\n    void opOpAssign(string op : \"~\", U)(U rhs)\n    if (__traits(compiles, (Appender!A a){ a.put(rhs); }))\n    {\n        scope(exit) *this.arr = impl.data;\n        impl.put(rhs);\n    }\n\n    /**\n     * Returns the capacity of the array (the maximum number of elements the\n     * managed array can accommodate before triggering a reallocation).  If any\n     * appending will reallocate, `capacity` returns `0`.\n     */\n    @property size_t capacity() const\n    {\n        return impl.capacity;\n    }\n\n    /**\n     * Returns the managed array.\n     */\n    @property inout(ElementEncodingType!A)[] data() inout\n    {\n        return impl.data;\n    }\n}\n\n///\n@system pure nothrow\nunittest\n{\n    int[] a = [1, 2];\n    auto app2 = appender(&a);\n    assert(app2.data == [1, 2]);\n    assert(a == [1, 2]);\n    app2 ~= 3;\n    app2 ~= [4, 5, 6];\n    assert(app2.data == [1, 2, 3, 4, 5, 6]);\n    assert(a == [1, 2, 3, 4, 5, 6]);\n\n    app2.reserve(5);\n    assert(app2.capacity >= 5);\n}\n\n/++\n    Convenience function that returns an $(LREF Appender) instance,\n    optionally initialized with `array`.\n +/\nAppender!A appender(A)()\nif (isDynamicArray!A)\n{\n    return Appender!A(null);\n}\n/// ditto\nAppender!(E[]) appender(A : E[], E)(auto ref A array)\n{\n    static assert(!isStaticArray!A || __traits(isRef, array),\n        \"Cannot create Appender from an rvalue static array\");\n\n    return Appender!(E[])(array);\n}\n\n@safe pure nothrow unittest\n{\n    import std.exception;\n    {\n        auto app = appender!(char[])();\n        string b = \"abcdefg\";\n        foreach (char c; b) app.put(c);\n        assert(app.data == \"abcdefg\");\n    }\n    {\n        auto app = appender!(char[])();\n        string b = \"abcdefg\";\n        foreach (char c; b) app ~= c;\n        assert(app.data == \"abcdefg\");\n    }\n    {\n        int[] a = [ 1, 2 ];\n        auto app2 = appender(a);\n        assert(app2.data == [ 1, 2 ]);\n        app2.put(3);\n        app2.put([ 4, 5, 6 ][]);\n        assert(app2.data == [ 1, 2, 3, 4, 5, 6 ]);\n        app2.put([ 7 ]);\n        assert(app2.data == [ 1, 2, 3, 4, 5, 6, 7 ]);\n    }\n\n    int[] a = [ 1, 2 ];\n    auto app2 = appender(a);\n    assert(app2.data == [ 1, 2 ]);\n    app2 ~= 3;\n    app2 ~= [ 4, 5, 6 ][];\n    assert(app2.data == [ 1, 2, 3, 4, 5, 6 ]);\n    app2 ~= [ 7 ];\n    assert(app2.data == [ 1, 2, 3, 4, 5, 6, 7 ]);\n\n    app2.reserve(5);\n    assert(app2.capacity >= 5);\n\n    try // shrinkTo may throw\n    {\n        app2.shrinkTo(3);\n    }\n    catch (Exception) assert(0);\n    assert(app2.data == [ 1, 2, 3 ]);\n    assertThrown(app2.shrinkTo(5));\n\n    const app3 = app2;\n    assert(app3.capacity >= 3);\n    assert(app3.data == [1, 2, 3]);\n\n    auto app4 = appender([]);\n    try // shrinkTo may throw\n    {\n        app4.shrinkTo(0);\n    }\n    catch (Exception) assert(0);\n\n    // Issue 5663 & 9725 tests\n    static foreach (S; AliasSeq!(char[], const(char)[], string))\n    {\n        {\n            Appender!S app5663i;\n            assertNotThrown(app5663i.put(\"\\xE3\"));\n            assert(app5663i.data == \"\\xE3\");\n\n            Appender!S app5663c;\n            assertNotThrown(app5663c.put(cast(const(char)[])\"\\xE3\"));\n            assert(app5663c.data == \"\\xE3\");\n\n            Appender!S app5663m;\n            assertNotThrown(app5663m.put(\"\\xE3\".dup));\n            assert(app5663m.data == \"\\xE3\");\n        }\n        // ditto for ~=\n        {\n            Appender!S app5663i;\n            assertNotThrown(app5663i ~= \"\\xE3\");\n            assert(app5663i.data == \"\\xE3\");\n\n            Appender!S app5663c;\n            assertNotThrown(app5663c ~= cast(const(char)[])\"\\xE3\");\n            assert(app5663c.data == \"\\xE3\");\n\n            Appender!S app5663m;\n            assertNotThrown(app5663m ~= \"\\xE3\".dup);\n            assert(app5663m.data == \"\\xE3\");\n        }\n    }\n\n    static struct S10122\n    {\n        int val;\n\n        @disable this();\n        this(int v) @safe pure nothrow { val = v; }\n    }\n    assertCTFEable!(\n    {\n        auto w = appender!(S10122[])();\n        w.put(S10122(1));\n        assert(w.data.length == 1 && w.data[0].val == 1);\n    });\n}\n\n///\n@safe pure nothrow\nunittest\n{\n    auto w = appender!string;\n    // pre-allocate space for at least 10 elements (this avoids costly reallocations)\n    w.reserve(10);\n    assert(w.capacity >= 10);\n\n    w.put('a'); // single elements\n    w.put(\"bc\"); // multiple elements\n\n    // use the append syntax\n    w ~= 'd';\n    w ~= \"ef\";\n\n    assert(w.data == \"abcdef\");\n}\n\n@safe pure nothrow unittest\n{\n    {\n        auto w = appender!string();\n        w.reserve(4);\n        cast(void) w.capacity;\n        cast(void) w.data;\n        try\n        {\n            wchar wc = 'a';\n            dchar dc = 'a';\n            w.put(wc);    // decoding may throw\n            w.put(dc);    // decoding may throw\n        }\n        catch (Exception) assert(0);\n    }\n    {\n        auto w = appender!(int[])();\n        w.reserve(4);\n        cast(void) w.capacity;\n        cast(void) w.data;\n        w.put(10);\n        w.put([10]);\n        w.clear();\n        try\n        {\n            w.shrinkTo(0);\n        }\n        catch (Exception) assert(0);\n\n        struct N\n        {\n            int payload;\n            alias payload this;\n        }\n        w.put(N(1));\n        w.put([N(2)]);\n\n        struct S(T)\n        {\n            @property bool empty() { return true; }\n            @property T front() { return T.init; }\n            void popFront() {}\n        }\n        S!int r;\n        w.put(r);\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm;\n    import std.typecons;\n    //10690\n    [tuple(1)].filter!(t => true).array; // No error\n    [tuple(\"A\")].filter!(t => true).array; // error\n}\n\n@safe unittest\n{\n    import std.range;\n    //Coverage for put(Range)\n    struct S1\n    {\n    }\n    struct S2\n    {\n        void opAssign(S2){}\n    }\n    auto a1 = Appender!(S1[])();\n    auto a2 = Appender!(S2[])();\n    auto au1 = Appender!(const(S1)[])();\n    a1.put(S1().repeat().take(10));\n    a2.put(S2().repeat().take(10));\n    auto sc1 = const(S1)();\n    au1.put(sc1.repeat().take(10));\n}\n\n@system unittest\n{\n    import std.range;\n    struct S2\n    {\n        void opAssign(S2){}\n    }\n    auto au2 = Appender!(const(S2)[])();\n    auto sc2 = const(S2)();\n    au2.put(sc2.repeat().take(10));\n}\n\n@system unittest\n{\n    struct S\n    {\n        int* p;\n    }\n\n    auto a0 = Appender!(S[])();\n    auto a1 = Appender!(const(S)[])();\n    auto a2 = Appender!(immutable(S)[])();\n    auto s0 = S(null);\n    auto s1 = const(S)(null);\n    auto s2 = immutable(S)(null);\n    a1.put(s0);\n    a1.put(s1);\n    a1.put(s2);\n    a1.put([s0]);\n    a1.put([s1]);\n    a1.put([s2]);\n    a0.put(s0);\n    static assert(!is(typeof(a0.put(a1))));\n    static assert(!is(typeof(a0.put(a2))));\n    a0.put([s0]);\n    static assert(!is(typeof(a0.put([a1]))));\n    static assert(!is(typeof(a0.put([a2]))));\n    static assert(!is(typeof(a2.put(a0))));\n    static assert(!is(typeof(a2.put(a1))));\n    a2.put(s2);\n    static assert(!is(typeof(a2.put([a0]))));\n    static assert(!is(typeof(a2.put([a1]))));\n    a2.put([s2]);\n}\n\n@safe unittest\n{\n    //9528\n    const(E)[] fastCopy(E)(E[] src) {\n            auto app = appender!(const(E)[])();\n            foreach (i, e; src)\n                    app.put(e);\n            return app.data;\n    }\n\n    class C {}\n    struct S { const(C) c; }\n    S[] s = [ S(new C) ];\n\n    auto t = fastCopy(s); // Does not compile\n    assert(t.length == 1);\n}\n\n@safe unittest\n{\n    import std.algorithm.iteration : map;\n    //10753\n    struct Foo {\n       immutable dchar d;\n    }\n    struct Bar {\n       immutable int x;\n    }\n    \"12\".map!Foo.array;\n    [1, 2].map!Bar.array;\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    //New appender signature tests\n    alias mutARR = int[];\n    alias conARR = const(int)[];\n    alias immARR = immutable(int)[];\n\n    mutARR mut;\n    conARR con;\n    immARR imm;\n\n    auto app1 = Appender!mutARR(mut);                //Always worked. Should work. Should not create a warning.\n    app1.put(7);\n    assert(equal(app1.data, [7]));\n    static assert(!is(typeof(Appender!mutARR(con)))); //Never worked.  Should not work.\n    static assert(!is(typeof(Appender!mutARR(imm)))); //Never worked.  Should not work.\n\n    auto app2 = Appender!conARR(mut); //Always worked. Should work. Should not create a warning.\n    app2.put(7);\n    assert(equal(app2.data, [7]));\n    auto app3 = Appender!conARR(con); //Didn't work.   Now works.   Should not create a warning.\n    app3.put(7);\n    assert(equal(app3.data, [7]));\n    auto app4 = Appender!conARR(imm); //Didn't work.   Now works.   Should not create a warning.\n    app4.put(7);\n    assert(equal(app4.data, [7]));\n\n    //{auto app = Appender!immARR(mut);}                //Worked. Will cease to work. Creates warning.\n    //static assert(!is(typeof(Appender!immARR(mut)))); //Worked. Will cease to work. Uncomment me after full deprecation.\n    static assert(!is(typeof(Appender!immARR(con))));   //Never worked. Should not work.\n    auto app5 = Appender!immARR(imm);                  //Didn't work.  Now works. Should not create a warning.\n    app5.put(7);\n    assert(equal(app5.data, [7]));\n\n    //Deprecated. Please uncomment and make sure this doesn't work:\n    //char[] cc;\n    //static assert(!is(typeof(Appender!string(cc))));\n\n    //This should always work:\n    auto app6 = appender!string(null);\n    assert(app6.data == null);\n    auto app7 = appender!(const(char)[])(null);\n    assert(app7.data == null);\n    auto app8 = appender!(char[])(null);\n    assert(app8.data == null);\n}\n\n@safe unittest //Test large allocations (for GC.extend)\n{\n    import std.algorithm.comparison : equal;\n    import std.range;\n    Appender!(char[]) app;\n    app.reserve(1); //cover reserve on non-initialized\n    foreach (_; 0 .. 100_000)\n        app.put('a');\n    assert(equal(app.data, 'a'.repeat(100_000)));\n}\n\n@safe unittest\n{\n    auto reference = new ubyte[](2048 + 1); //a number big enough to have a full page (EG: the GC extends)\n    auto arr = reference.dup;\n    auto app = appender(arr[0 .. 0]);\n    app.reserve(1); //This should not trigger a call to extend\n    app.put(ubyte(1)); //Don't clobber arr\n    assert(reference[] == arr[]);\n}\n\n@safe unittest // clear method is supported only for mutable element types\n{\n    Appender!string app;\n    app.put(\"foo\");\n    static assert(!__traits(compiles, app.clear()));\n    assert(app.data == \"foo\");\n}\n\n@safe unittest\n{\n    static struct D//dynamic\n    {\n        int[] i;\n        alias i this;\n    }\n    static struct S//static\n    {\n        int[5] i;\n        alias i this;\n    }\n    static assert(!is(Appender!(char[5])));\n    static assert(!is(Appender!D));\n    static assert(!is(Appender!S));\n\n    enum int[5] a = [];\n    int[5] b;\n    D d;\n    S s;\n    int[5] foo(){return a;}\n\n    static assert(!is(typeof(appender(a))));\n    static assert( is(typeof(appender(b))));\n    static assert( is(typeof(appender(d))));\n    static assert( is(typeof(appender(s))));\n    static assert(!is(typeof(appender(foo()))));\n}\n\n@system unittest\n{\n    // Issue 13077\n    static class A {}\n\n    // reduced case\n    auto w = appender!(shared(A)[])();\n    w.put(new shared A());\n\n    // original case\n    import std.range;\n    InputRange!(shared A) foo()\n    {\n        return [new shared A].inputRangeObject;\n    }\n    auto res = foo.array;\n    assert(res.length == 1);\n}\n\n/++\n    Convenience function that returns a $(LREF RefAppender) instance initialized\n    with `arrayPtr`. Don't use null for the array pointer, use the other\n    version of `appender` instead.\n +/\nRefAppender!(E[]) appender(P : E[]*, E)(P arrayPtr)\n{\n    return RefAppender!(E[])(arrayPtr);\n}\n\n///\n@system pure nothrow\nunittest\n{\n    int[] a = [1, 2];\n    auto app2 = appender(&a);\n    assert(app2.data == [1, 2]);\n    assert(a == [1, 2]);\n    app2 ~= 3;\n    app2 ~= [4, 5, 6];\n    assert(app2.data == [1, 2, 3, 4, 5, 6]);\n    assert(a == [1, 2, 3, 4, 5, 6]);\n\n    app2.reserve(5);\n    assert(app2.capacity >= 5);\n}\n\n@system unittest\n{\n    import std.exception;\n    {\n        auto arr = new char[0];\n        auto app = appender(&arr);\n        string b = \"abcdefg\";\n        foreach (char c; b) app.put(c);\n        assert(app.data == \"abcdefg\");\n        assert(arr == \"abcdefg\");\n    }\n    {\n        auto arr = new char[0];\n        auto app = appender(&arr);\n        string b = \"abcdefg\";\n        foreach (char c; b) app ~= c;\n        assert(app.data == \"abcdefg\");\n        assert(arr == \"abcdefg\");\n    }\n    {\n        int[] a = [ 1, 2 ];\n        auto app2 = appender(&a);\n        assert(app2.data == [ 1, 2 ]);\n        assert(a == [ 1, 2 ]);\n        app2.put(3);\n        app2.put([ 4, 5, 6 ][]);\n        assert(app2.data == [ 1, 2, 3, 4, 5, 6 ]);\n        assert(a == [ 1, 2, 3, 4, 5, 6 ]);\n    }\n\n    int[] a = [ 1, 2 ];\n    auto app2 = appender(&a);\n    assert(app2.data == [ 1, 2 ]);\n    assert(a == [ 1, 2 ]);\n    app2 ~= 3;\n    app2 ~= [ 4, 5, 6 ][];\n    assert(app2.data == [ 1, 2, 3, 4, 5, 6 ]);\n    assert(a == [ 1, 2, 3, 4, 5, 6 ]);\n\n    app2.reserve(5);\n    assert(app2.capacity >= 5);\n\n    try // shrinkTo may throw\n    {\n        app2.shrinkTo(3);\n    }\n    catch (Exception) assert(0);\n    assert(app2.data == [ 1, 2, 3 ]);\n    assertThrown(app2.shrinkTo(5));\n\n    const app3 = app2;\n    assert(app3.capacity >= 3);\n    assert(app3.data == [1, 2, 3]);\n}\n\n@safe unittest // issue 14605\n{\n    static assert(isOutputRange!(Appender!(int[]), int));\n    static assert(isOutputRange!(RefAppender!(int[]), int));\n}\n\n@safe unittest\n{\n    Appender!(int[]) app;\n    short[] range = [1, 2, 3];\n    app.put(range);\n    assert(app.data == [1, 2, 3]);\n}\n\n@safe unittest\n{\n    string s = \"hello\".idup;\n    char[] a = \"hello\".dup;\n    auto appS = appender(s);\n    auto appA = appender(a);\n    put(appS, 'w');\n    put(appA, 'w');\n    s ~= 'a'; //Clobbers here?\n    a ~= 'a'; //Clobbers here?\n    assert(appS.data == \"hellow\");\n    assert(appA.data == \"hellow\");\n}\n\n/++\nConstructs a static array from `a`.\nThe type of elements can be specified implicitly so that $(D [1, 2].staticArray) results in `int[2]`,\nor explicitly, e.g. $(D [1, 2].staticArray!float) returns `float[2]`.\nWhen `a` is a range whose length is not known at compile time, the number of elements must be\ngiven as template argument (e.g. `myrange.staticArray!2`).\nSize and type can be combined, if the source range elements are implicitly\nconvertible to the requested element type (eg: `2.iota.staticArray!(long[2])`).\nWhen the range `a` is known at compile time, it can also be specified as a\ntemplate argument to avoid having to specify the number of elements\n(e.g.: `staticArray!(2.iota)` or `staticArray!(double, 2.iota)`).\n\nNote: `staticArray` returns by value, so expressions involving large arrays may be inefficient.\n\nParams:\n    a = The input elements. If there are less elements than the specified length of the static array,\n    the rest of it is default-initialized. If there are more than specified, the first elements\n    up to the specified length are used.\n    rangeLength = outputs the number of elements used from `a` to it. Optional.\n\nReturns: A static array constructed from `a`.\n+/\npragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a)\n{\n    return a;\n}\n\n/// static array from array literal\nnothrow pure @safe unittest\n{\n    auto a = [0, 1].staticArray;\n    static assert(is(typeof(a) == int[2]));\n    assert(a == [0, 1]);\n}\n\npragma(inline, true) U[n] staticArray(U, T, size_t n)(auto ref T[n] a)\nif (!is(T == U) && is(T : U))\n{\n    return a[].staticArray!(U[n]);\n}\n\n/// static array from array with implicit casting of elements\nnothrow pure @safe unittest\n{\n    auto b = [0, 1].staticArray!long;\n    static assert(is(typeof(b) == long[2]));\n    assert(b == [0, 1]);\n}\n\nnothrow pure @safe unittest\n{\n    int val = 3;\n    static immutable gold = [1, 2, 3];\n    [1, 2, val].staticArray.checkStaticArray!int([1, 2, 3]);\n\n    @nogc void checkNogc()\n    {\n        [1, 2, val].staticArray.checkStaticArray!int(gold);\n    }\n\n    checkNogc();\n\n    [1, 2, val].staticArray!double.checkStaticArray!double(gold);\n    [1, 2, 3].staticArray!int.checkStaticArray!int(gold);\n\n    [1, 2, 3].staticArray!(const(int)).checkStaticArray!(const(int))(gold);\n    [1, 2, 3].staticArray!(const(double)).checkStaticArray!(const(double))(gold);\n    {\n        const(int)[3] a2 = [1, 2, 3].staticArray;\n    }\n\n    [cast(byte) 1, cast(byte) 129].staticArray.checkStaticArray!byte([1, -127]);\n}\n\n/// ditto\nauto staticArray(size_t n, T)(scope T a)\nif (isInputRange!T)\n{\n    alias U = ElementType!T;\n    return staticArray!(U[n], U, n)(a);\n}\n\n/// ditto\nauto staticArray(size_t n, T)(scope T a, out size_t rangeLength)\nif (isInputRange!T)\n{\n    alias U = ElementType!T;\n    return staticArray!(U[n], U, n)(a, rangeLength);\n}\n\n/// ditto\nauto staticArray(Un : U[n], U, size_t n, T)(scope T a)\nif (isInputRange!T && is(ElementType!T : U))\n{\n    size_t extraStackSpace;\n    return staticArray!(Un, U, n)(a, extraStackSpace);\n}\n\n/// ditto\nauto staticArray(Un : U[n], U, size_t n, T)(scope T a, out size_t rangeLength)\nif (isInputRange!T && is(ElementType!T : U))\n{\n    import std.algorithm.mutation : uninitializedFill;\n    import std.range : take;\n    import std.conv : emplaceRef;\n\n    if (__ctfe)\n    {\n        size_t i;\n        // Compile-time version to avoid unchecked memory access.\n        Unqual!U[n] ret;\n        for (auto iter = a.take(n); !iter.empty; iter.popFront())\n        {\n            ret[i] = iter.front;\n            i++;\n        }\n\n        rangeLength = i;\n        return (() @trusted => cast(U[n]) ret)();\n    }\n\n    auto ret = (() @trusted\n    {\n        Unqual!U[n] theArray = void;\n        return theArray;\n    }());\n\n    size_t i;\n    if (true)\n    {\n        // ret was void-initialized so let's initialize the unfilled part manually.\n        // also prevents destructors to be called on uninitialized memory if\n        // an exception is thrown\n        scope (exit) ret[i .. $].uninitializedFill(U.init);\n\n        for (auto iter = a.take(n); !iter.empty; iter.popFront())\n        {\n            emplaceRef!U(ret[i++], iter.front);\n        }\n    }\n\n    rangeLength = i;\n    return (() @trusted => cast(U[n]) ret)();\n}\n\n/// static array from range + size\nnothrow pure @safe unittest\n{\n    import std.range : iota;\n\n    auto input = 3.iota;\n    auto a = input.staticArray!2;\n    static assert(is(typeof(a) == int[2]));\n    assert(a == [0, 1]);\n    auto b = input.staticArray!(long[4]);\n    static assert(is(typeof(b) == long[4]));\n    assert(b == [0, 1, 2, 0]);\n}\n\n// Tests that code compiles when there is an elaborate destructor and exceptions\n// are thrown. Unfortunately can't test that memory is initialized\n// before having a destructor called on it.\n// @system required because of issue 18872.\n@system nothrow unittest\n{\n    // exists only to allow doing something in the destructor. Not tested\n    // at the end because value appears to depend on implementation of the.\n    // function.\n    static int preventersDestroyed = 0;\n\n    static struct CopyPreventer\n    {\n        bool on = false;\n        this(this)\n        {\n            if (on) throw new Exception(\"Thou shalt not copy past me!\");\n        }\n\n        ~this()\n        {\n            preventersDestroyed++;\n        }\n    }\n    auto normalArray =\n    [\n        CopyPreventer(false),\n        CopyPreventer(false),\n        CopyPreventer(true),\n        CopyPreventer(false),\n        CopyPreventer(true),\n    ];\n\n    try\n    {\n        auto staticArray = normalArray.staticArray!5;\n        assert(false);\n    }\n    catch (Exception e){}\n}\n\n\nnothrow pure @safe unittest\n{\n    auto a = [1, 2].staticArray;\n    assert(is(typeof(a) == int[2]) && a == [1, 2]);\n\n    import std.range : iota;\n\n    2.iota.staticArray!2.checkStaticArray!int([0, 1]);\n    2.iota.staticArray!(double[2]).checkStaticArray!double([0, 1]);\n    2.iota.staticArray!(long[2]).checkStaticArray!long([0, 1]);\n}\n\nnothrow pure @system unittest\n{\n    import std.range : iota;\n    size_t copiedAmount;\n    2.iota.staticArray!1(copiedAmount);\n    assert(copiedAmount == 1);\n    2.iota.staticArray!3(copiedAmount);\n    assert(copiedAmount == 2);\n}\n\n/// ditto\nauto staticArray(alias a)()\nif (isInputRange!(typeof(a)))\n{\n    return .staticArray!(size_t(a.length))(a);\n}\n\n/// ditto\nauto staticArray(U, alias a)()\nif (isInputRange!(typeof(a)))\n{\n    return .staticArray!(U[size_t(a.length)])(a);\n}\n\n/// static array from CT range\nnothrow pure @safe unittest\n{\n    import std.range : iota;\n\n    enum a = staticArray!(2.iota);\n    static assert(is(typeof(a) == int[2]));\n    assert(a == [0, 1]);\n\n    enum b = staticArray!(long, 2.iota);\n    static assert(is(typeof(b) == long[2]));\n    assert(b == [0, 1]);\n}\n\nnothrow pure @safe unittest\n{\n    import std.range : iota;\n\n    enum a = staticArray!(2.iota);\n    staticArray!(2.iota).checkStaticArray!int([0, 1]);\n    staticArray!(double, 2.iota).checkStaticArray!double([0, 1]);\n    staticArray!(long, 2.iota).checkStaticArray!long([0, 1]);\n}\n\nversion (unittest) private void checkStaticArray(T, T1, T2)(T1 a, T2 b) nothrow @safe pure @nogc\n{\n    static assert(is(T1 == T[T1.length]));\n    assert(a == b);\n}\n"
  },
  {
    "path": "libphobos/src/std/ascii.d",
    "content": "// Written in the D programming language.\n\n/++\n    Functions which operate on ASCII characters.\n\n    All of the functions in std.ascii accept Unicode characters but\n    effectively ignore them if they're not ASCII. All `isX` functions return\n    `false` for non-ASCII characters, and all `toX` functions do nothing\n    to non-ASCII characters.\n\n    For functions which operate on Unicode characters, see\n    $(MREF std, uni).\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(DIVC quickindex,\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Validation) $(TD\n        $(LREF isAlpha)\n        $(LREF isAlphaNum)\n        $(LREF isASCII)\n        $(LREF isControl)\n        $(LREF isDigit)\n        $(LREF isGraphical)\n        $(LREF isHexDigit)\n        $(LREF isOctalDigit)\n        $(LREF isPrintable)\n        $(LREF isPunctuation)\n        $(LREF isUpper)\n        $(LREF isWhite)\n))\n$(TR $(TD Conversions) $(TD\n        $(LREF toLower)\n        $(LREF toUpper)\n))\n$(TR $(TD Constants) $(TD\n        $(LREF digits)\n        $(LREF fullHexDigits)\n        $(LREF hexDigits)\n        $(LREF letters)\n        $(LREF lowercase)\n        $(LREF lowerHexDigits)\n        $(LREF newline)\n        $(LREF octalDigits)\n        $(LREF uppercase)\n        $(LREF whitespace)\n))\n$(TR $(TD Enums) $(TD\n        $(LREF LetterCase)\n))\n))\n    References:\n        $(LINK2 http://www.digitalmars.com/d/ascii-table.html, ASCII Table),\n        $(HTTP en.wikipedia.org/wiki/Ascii, Wikipedia)\n\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP digitalmars.com, Walter Bright) and\n               $(HTTP jmdavisprog.com, Jonathan M Davis)\n    Source:    $(PHOBOSSRC std/ascii.d)\n  +/\nmodule std.ascii;\n\nimmutable fullHexDigits  = \"0123456789ABCDEFabcdef\";     /// 0 .. 9A .. Fa .. f\nimmutable hexDigits      = fullHexDigits[0 .. 16];         /// 0 .. 9A .. F\nimmutable lowerHexDigits = \"0123456789abcdef\";           /// 0 .. 9a .. f\nimmutable digits         = hexDigits[0 .. 10];             /// 0 .. 9\nimmutable octalDigits    = digits[0 .. 8];                 /// 0 .. 7\nimmutable letters        = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"; /// A .. Za .. z\nimmutable uppercase      = letters[0 .. 26];               /// A .. Z\nimmutable lowercase      = letters[26 .. 52];              /// a .. z\nimmutable whitespace     = \" \\t\\v\\r\\n\\f\";                /// ASCII _whitespace\n\n/++\n    Letter case specifier.\n  +/\nenum LetterCase : bool\n{\n    upper, /// Upper case letters\n    lower  /// Lower case letters\n}\n\n///\n@safe unittest\n{\n    import std.conv : to;\n\n    assert(42.to!string(16, LetterCase.upper) == \"2A\");\n    assert(42.to!string(16, LetterCase.lower) == \"2a\");\n}\n\n///\n@safe unittest\n{\n    import std.digest.hmac : hmac;\n    import std.digest : toHexString;\n    import std.digest.sha : SHA1;\n    import std.string : representation;\n\n    const sha1HMAC = \"A very long phrase\".representation\n        .hmac!SHA1(\"secret\".representation)\n        .toHexString!(LetterCase.lower);\n    assert(sha1HMAC == \"49f2073c7bf58577e8c9ae59fe8cfd37c9ab94e5\");\n}\n\n/// Newline sequence for this system.\nversion (Windows)\n    immutable newline = \"\\r\\n\";\nelse version (Posix)\n    immutable newline = \"\\n\";\nelse\n    static assert(0, \"Unsupported OS\");\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether `c` is a letter or a number (0 .. 9, a .. z, A .. Z).\n  +/\nbool isAlphaNum(dchar c) @safe pure nothrow @nogc\n{\n    return c <= 'z' && c >= '0' && (c <= '9' || c >= 'a' || (c >= 'A' && c <= 'Z'));\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isAlphaNum('A'));\n    assert( isAlphaNum('1'));\n    assert(!isAlphaNum('#'));\n\n    // N.B.: does not return true for non-ASCII Unicode alphanumerics:\n    assert(!isAlphaNum('á'));\n}\n\n@safe unittest\n{\n    import std.range;\n    foreach (c; chain(digits, octalDigits, fullHexDigits, letters, lowercase, uppercase))\n        assert(isAlphaNum(c));\n\n    foreach (c; whitespace)\n        assert(!isAlphaNum(c));\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether `c` is an ASCII letter (A .. Z, a .. z).\n  +/\nbool isAlpha(dchar c) @safe pure nothrow @nogc\n{\n    // Optimizer can turn this into a bitmask operation on 64 bit code\n    return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isAlpha('A'));\n    assert(!isAlpha('1'));\n    assert(!isAlpha('#'));\n\n    // N.B.: does not return true for non-ASCII Unicode alphabetic characters:\n    assert(!isAlpha('á'));\n}\n\n@safe unittest\n{\n    import std.range;\n    foreach (c; chain(letters, lowercase, uppercase))\n        assert(isAlpha(c));\n\n    foreach (c; chain(digits, octalDigits, whitespace))\n        assert(!isAlpha(c));\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether `c` is a lowercase ASCII letter (a .. z).\n  +/\nbool isLower(dchar c) @safe pure nothrow @nogc\n{\n    return c >= 'a' && c <= 'z';\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isLower('a'));\n    assert(!isLower('A'));\n    assert(!isLower('#'));\n\n    // N.B.: does not return true for non-ASCII Unicode lowercase letters\n    assert(!isLower('á'));\n    assert(!isLower('Á'));\n}\n\n@safe unittest\n{\n    import std.range;\n    foreach (c; lowercase)\n        assert(isLower(c));\n\n    foreach (c; chain(digits, uppercase, whitespace))\n        assert(!isLower(c));\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether `c` is an uppercase ASCII letter (A .. Z).\n  +/\nbool isUpper(dchar c) @safe pure nothrow @nogc\n{\n    return c <= 'Z' && 'A' <= c;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isUpper('A'));\n    assert(!isUpper('a'));\n    assert(!isUpper('#'));\n\n    // N.B.: does not return true for non-ASCII Unicode uppercase letters\n    assert(!isUpper('á'));\n    assert(!isUpper('Á'));\n}\n\n@safe unittest\n{\n    import std.range;\n    foreach (c; uppercase)\n        assert(isUpper(c));\n\n    foreach (c; chain(digits, lowercase, whitespace))\n        assert(!isUpper(c));\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether `c` is a digit (0 .. 9).\n  +/\nbool isDigit(dchar c) @safe pure nothrow @nogc\n{\n    return '0' <= c && c <= '9';\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isDigit('3'));\n    assert( isDigit('8'));\n    assert(!isDigit('B'));\n    assert(!isDigit('#'));\n\n    // N.B.: does not return true for non-ASCII Unicode numbers\n    assert(!isDigit('０')); // full-width digit zero (U+FF10)\n    assert(!isDigit('４')); // full-width digit four (U+FF14)\n}\n\n@safe unittest\n{\n    import std.range;\n    foreach (c; digits)\n        assert(isDigit(c));\n\n    foreach (c; chain(letters, whitespace))\n        assert(!isDigit(c));\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether `c` is a digit in base 8 (0 .. 7).\n  +/\nbool isOctalDigit(dchar c) @safe pure nothrow @nogc\n{\n    return c >= '0' && c <= '7';\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isOctalDigit('0'));\n    assert( isOctalDigit('7'));\n    assert(!isOctalDigit('8'));\n    assert(!isOctalDigit('A'));\n    assert(!isOctalDigit('#'));\n}\n\n@safe unittest\n{\n    import std.range;\n    foreach (c; octalDigits)\n        assert(isOctalDigit(c));\n\n    foreach (c; chain(letters, ['8', '9'], whitespace))\n        assert(!isOctalDigit(c));\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether `c` is a digit in base 16 (0 .. 9, A .. F, a .. f).\n  +/\nbool isHexDigit(dchar c) @safe pure nothrow @nogc\n{\n    return c <= 'f' && c >= '0' && (c <= '9' || c >= 'a' || (c >= 'A' && c <= 'F'));\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isHexDigit('0'));\n    assert( isHexDigit('A'));\n    assert( isHexDigit('f')); // lowercase hex digits are accepted\n    assert(!isHexDigit('g'));\n    assert(!isHexDigit('G'));\n    assert(!isHexDigit('#'));\n}\n\n@safe unittest\n{\n    import std.range;\n    foreach (c; fullHexDigits)\n        assert(isHexDigit(c));\n\n    foreach (c; chain(lowercase[6 .. $], uppercase[6 .. $], whitespace))\n        assert(!isHexDigit(c));\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether or not `c` is a whitespace character. That includes the\n    space, tab, vertical tab, form feed, carriage return, and linefeed\n    characters.\n  +/\nbool isWhite(dchar c) @safe pure nothrow @nogc\n{\n    return c == ' ' || (c >= 0x09 && c <= 0x0D);\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isWhite(' '));\n    assert( isWhite('\\t'));\n    assert( isWhite('\\n'));\n    assert(!isWhite('1'));\n    assert(!isWhite('a'));\n    assert(!isWhite('#'));\n\n    // N.B.: Does not return true for non-ASCII Unicode whitespace characters.\n    static import std.uni;\n    assert(std.uni.isWhite('\\u00A0'));\n    assert(!isWhite('\\u00A0')); // std.ascii.isWhite\n}\n\n@safe unittest\n{\n    import std.range;\n    foreach (c; whitespace)\n        assert(isWhite(c));\n\n    foreach (c; chain(digits, letters))\n        assert(!isWhite(c));\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether `c` is a control character.\n  +/\nbool isControl(dchar c) @safe pure nothrow @nogc\n{\n    return c < 0x20 || c == 0x7F;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isControl('\\0'));\n    assert( isControl('\\022'));\n    assert( isControl('\\n')); // newline is both whitespace and control\n    assert(!isControl(' '));\n    assert(!isControl('1'));\n    assert(!isControl('a'));\n    assert(!isControl('#'));\n\n    // N.B.: non-ASCII Unicode control characters are not recognized:\n    assert(!isControl('\\u0080'));\n    assert(!isControl('\\u2028'));\n    assert(!isControl('\\u2029'));\n}\n\n@safe unittest\n{\n    import std.range;\n    foreach (dchar c; 0 .. 32)\n        assert(isControl(c));\n    assert(isControl(127));\n\n    foreach (c; chain(digits, letters, [' ']))\n        assert(!isControl(c));\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether or not `c` is a punctuation character. That includes\n    all ASCII characters which are not control characters, letters, digits, or\n    whitespace.\n  +/\nbool isPunctuation(dchar c) @safe pure nothrow @nogc\n{\n    return c <= '~' && c >= '!' && !isAlphaNum(c);\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isPunctuation('.'));\n    assert( isPunctuation(','));\n    assert( isPunctuation(':'));\n    assert( isPunctuation('!'));\n    assert( isPunctuation('#'));\n    assert( isPunctuation('~'));\n    assert( isPunctuation('+'));\n    assert( isPunctuation('_'));\n\n    assert(!isPunctuation('1'));\n    assert(!isPunctuation('a'));\n    assert(!isPunctuation(' '));\n    assert(!isPunctuation('\\n'));\n    assert(!isPunctuation('\\0'));\n\n    // N.B.: Non-ASCII Unicode punctuation characters are not recognized.\n    assert(!isPunctuation('\\u2012')); // (U+2012 = en-dash)\n}\n\n@safe unittest\n{\n    foreach (dchar c; 0 .. 128)\n    {\n        if (isControl(c) || isAlphaNum(c) || c == ' ')\n            assert(!isPunctuation(c));\n        else\n            assert(isPunctuation(c));\n    }\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether or not `c` is a printable character other than the\n    space character.\n  +/\nbool isGraphical(dchar c) @safe pure nothrow @nogc\n{\n    return '!' <= c && c <= '~';\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isGraphical('1'));\n    assert( isGraphical('a'));\n    assert( isGraphical('#'));\n    assert(!isGraphical(' ')); // whitespace is not graphical\n    assert(!isGraphical('\\n'));\n    assert(!isGraphical('\\0'));\n\n    // N.B.: Unicode graphical characters are not regarded as such.\n    assert(!isGraphical('á'));\n}\n\n@safe unittest\n{\n    foreach (dchar c; 0 .. 128)\n    {\n        if (isControl(c) || c == ' ')\n            assert(!isGraphical(c));\n        else\n            assert(isGraphical(c));\n    }\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether or not `c` is a printable character - including the\n    space character.\n  +/\nbool isPrintable(dchar c) @safe pure nothrow @nogc\n{\n    return c >= ' ' && c <= '~';\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isPrintable(' '));  // whitespace is printable\n    assert( isPrintable('1'));\n    assert( isPrintable('a'));\n    assert( isPrintable('#'));\n    assert(!isPrintable('\\0')); // control characters are not printable\n\n    // N.B.: Printable non-ASCII Unicode characters are not recognized.\n    assert(!isPrintable('á'));\n}\n\n@safe unittest\n{\n    foreach (dchar c; 0 .. 128)\n    {\n        if (isControl(c))\n            assert(!isPrintable(c));\n        else\n            assert(isPrintable(c));\n    }\n}\n\n\n/++\n    Params: c = The character to test.\n    Returns: Whether or not `c` is in the ASCII character set - i.e. in the\n    range 0 .. 0x7F.\n  +/\npragma(inline, true)\nbool isASCII(dchar c) @safe pure nothrow @nogc\n{\n    return c <= 0x7F;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isASCII('a'));\n    assert(!isASCII('á'));\n}\n\n@safe unittest\n{\n    foreach (dchar c; 0 .. 128)\n        assert(isASCII(c));\n\n    assert(!isASCII(128));\n}\n\n\n/++\n    Converts an ASCII letter to lowercase.\n\n    Params: c = A character of any type that implicitly converts to `dchar`.\n    In the case where it's a built-in type, or an enum of a built-in type,\n    `Unqual!(OriginalType!C)` is returned, whereas if it's a user-defined\n    type, `dchar` is returned.\n\n    Returns: The corresponding lowercase letter, if `c` is an uppercase\n    ASCII character, otherwise `c` itself.\n  +/\nauto toLower(C)(C c)\nif (is(C : dchar))\n{\n    import std.traits : isAggregateType, OriginalType, Unqual;\n\n    alias OC = OriginalType!C;\n    static if (isAggregateType!OC)\n        alias R = dchar;\n    else\n        alias R = Unqual!OC;\n\n    return isUpper(c) ? cast(R)(cast(R) c + 'a' - 'A') : cast(R) c;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(toLower('a') == 'a');\n    assert(toLower('A') == 'a');\n    assert(toLower('#') == '#');\n\n    // N.B.: Non-ASCII Unicode uppercase letters are not converted.\n    assert(toLower('Á') == 'Á');\n}\n\n@safe pure nothrow unittest\n{\n\n    import std.meta;\n    static foreach (C; AliasSeq!(char, wchar, dchar, immutable char, ubyte))\n    {\n        foreach (i, c; uppercase)\n            assert(toLower(cast(C) c) == lowercase[i]);\n\n        foreach (C c; 0 .. 128)\n        {\n            if (c < 'A' || c > 'Z')\n                assert(toLower(c) == c);\n            else\n                assert(toLower(c) != c);\n        }\n\n        foreach (C c; 128 .. C.max)\n            assert(toLower(c) == c);\n\n        //CTFE\n        static assert(toLower(cast(C)'a') == 'a');\n        static assert(toLower(cast(C)'A') == 'a');\n    }\n}\n\n\n/++\n    Converts an ASCII letter to uppercase.\n\n    Params: c = Any type which implicitly converts to `dchar`. In the case\n    where it's a built-in type, or an enum of a built-in type,\n    `Unqual!(OriginalType!C)` is returned, whereas if it's a user-defined\n    type, `dchar` is returned.\n\n    Returns: The corresponding uppercase letter, if `c` is a lowercase ASCII\n    character, otherwise `c` itself.\n  +/\nauto toUpper(C)(C c)\nif (is(C : dchar))\n{\n    import std.traits : isAggregateType, OriginalType, Unqual;\n\n    alias OC = OriginalType!C;\n    static if (isAggregateType!OC)\n        alias R = dchar;\n    else\n        alias R = Unqual!OC;\n\n    return isLower(c) ? cast(R)(cast(R) c - ('a' - 'A')) : cast(R) c;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(toUpper('a') == 'A');\n    assert(toUpper('A') == 'A');\n    assert(toUpper('#') == '#');\n\n    // N.B.: Non-ASCII Unicode lowercase letters are not converted.\n    assert(toUpper('á') == 'á');\n}\n\n@safe pure nothrow unittest\n{\n    import std.meta;\n    static foreach (C; AliasSeq!(char, wchar, dchar, immutable char, ubyte))\n    {\n        foreach (i, c; lowercase)\n            assert(toUpper(cast(C) c) == uppercase[i]);\n\n        foreach (C c; 0 .. 128)\n        {\n            if (c < 'a' || c > 'z')\n                assert(toUpper(c) == c);\n            else\n                assert(toUpper(c) != c);\n        }\n\n        foreach (C c; 128 .. C.max)\n            assert(toUpper(c) == c);\n\n        //CTFE\n        static assert(toUpper(cast(C)'a') == 'A');\n        static assert(toUpper(cast(C)'A') == 'A');\n    }\n}\n\n\n@safe unittest //Test both toUpper and toLower with non-builtin\n{\n    import std.meta;\n    import std.traits;\n\n    //User Defined [Char|Wchar|Dchar]\n    static struct UDC {  char c; alias c this; }\n    static struct UDW { wchar c; alias c this; }\n    static struct UDD { dchar c; alias c this; }\n    //[Char|Wchar|Dchar] Enum\n    enum CE :  char {a = 'a', A = 'A'}\n    enum WE : wchar {a = 'a', A = 'A'}\n    enum DE : dchar {a = 'a', A = 'A'}\n    //User Defined [Char|Wchar|Dchar] Enum\n    enum UDCE : UDC {a = UDC('a'), A = UDC('A')}\n    enum UDWE : UDW {a = UDW('a'), A = UDW('A')}\n    enum UDDE : UDD {a = UDD('a'), A = UDD('A')}\n\n    //User defined types with implicit cast to dchar test.\n    static foreach (Char; AliasSeq!(UDC, UDW, UDD))\n    {\n        assert(toLower(Char('a')) == 'a');\n        assert(toLower(Char('A')) == 'a');\n        static assert(toLower(Char('a')) == 'a');\n        static assert(toLower(Char('A')) == 'a');\n        static assert(toUpper(Char('a')) == 'A');\n        static assert(toUpper(Char('A')) == 'A');\n    }\n\n    //Various enum tests.\n    static foreach (Enum; AliasSeq!(CE, WE, DE, UDCE, UDWE, UDDE))\n    {\n        assert(toLower(Enum.a) == 'a');\n        assert(toLower(Enum.A) == 'a');\n        assert(toUpper(Enum.a) == 'A');\n        assert(toUpper(Enum.A) == 'A');\n        static assert(toLower(Enum.a) == 'a');\n        static assert(toLower(Enum.A) == 'a');\n        static assert(toUpper(Enum.a) == 'A');\n        static assert(toUpper(Enum.A) == 'A');\n    }\n\n    //Return value type tests for enum of non-UDT. These should be the original type.\n    static foreach (T; AliasSeq!(CE, WE, DE))\n    {{\n        alias C = OriginalType!T;\n        static assert(is(typeof(toLower(T.init)) == C));\n        static assert(is(typeof(toUpper(T.init)) == C));\n    }}\n\n    //Return value tests for UDT and enum of UDT. These should be dchar\n    static foreach (T; AliasSeq!(UDC, UDW, UDD, UDCE, UDWE, UDDE))\n    {\n        static assert(is(typeof(toLower(T.init)) == dchar));\n        static assert(is(typeof(toUpper(T.init)) == dchar));\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/base64.d",
    "content": "// Written in the D programming language.\n\n/**\n * Support for Base64 encoding and decoding.\n *\n * This module provides two default implementations of Base64 encoding,\n * $(LREF Base64) with a standard encoding alphabet, and a variant\n * $(LREF Base64URL) that has a modified encoding alphabet designed to be\n * safe for embedding in URLs and filenames.\n *\n * Both variants are implemented as instantiations of the template\n * $(LREF Base64Impl). Most users will not need to use this template\n * directly; however, it can be used to create customized Base64 encodings,\n * such as one that omits padding characters, or one that is safe to embed\n * inside a regular expression.\n *\n * Example:\n * -----\n * ubyte[] data = [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e];\n *\n * const(char)[] encoded = Base64.encode(data);\n * assert(encoded == \"FPucA9l+\");\n *\n * ubyte[] decoded = Base64.decode(\"FPucA9l+\");\n * assert(decoded == [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]);\n * -----\n *\n * The range API is supported for both encoding and decoding:\n *\n * Example:\n * -----\n * // Create MIME Base64 with CRLF, per line 76.\n * File f = File(\"./text.txt\", \"r\");\n * scope(exit) f.close();\n *\n * Appender!string mime64 = appender!string;\n *\n * foreach (encoded; Base64.encoder(f.byChunk(57)))\n * {\n *     mime64.put(encoded);\n *     mime64.put(\"\\r\\n\");\n * }\n *\n * writeln(mime64.data);\n * -----\n *\n * References:\n * $(LINK2 https://tools.ietf.org/html/rfc4648, RFC 4648 - The Base16, Base32, and Base64\n * Data Encodings)\n *\n * Copyright: Masahiro Nakagawa 2010-.\n * License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Masahiro Nakagawa, Daniel Murphy (Single value Encoder and Decoder)\n * Source:    $(PHOBOSSRC std/base64.d)\n * Macros:\n *      LREF2=<a href=\"#$1\">`$2`</a>\n */\nmodule std.base64;\n\nimport std.exception;  // enforce\nimport std.range.primitives;      // isInputRange, isOutputRange, isForwardRange, ElementType, hasLength\nimport std.traits;     // isArray\n\n// Make sure module header code examples work correctly.\n@safe unittest\n{\n    ubyte[] data = [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e];\n\n    const(char)[] encoded = Base64.encode(data);\n    assert(encoded == \"FPucA9l+\");\n\n    ubyte[] decoded = Base64.decode(\"FPucA9l+\");\n    assert(decoded == [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]);\n}\n\n/**\n * Implementation of standard _Base64 encoding.\n *\n * See $(LREF Base64Impl) for a description of available methods.\n */\nalias Base64 = Base64Impl!('+', '/');\n\n///\n@safe unittest\n{\n    ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];\n    assert(Base64.encode(data) == \"g9cwegE/\");\n    assert(Base64.decode(\"g9cwegE/\") == data);\n}\n\n\n/**\n * Variation of Base64 encoding that is safe for use in URLs and filenames.\n *\n * See $(LREF Base64Impl) for a description of available methods.\n */\nalias Base64URL = Base64Impl!('-', '_');\n\n///\n@safe unittest\n{\n    ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];\n    assert(Base64URL.encode(data) == \"g9cwegE_\");\n    assert(Base64URL.decode(\"g9cwegE_\") == data);\n}\n\n/**\n * Unpadded variation of Base64 encoding that is safe for use in URLs and\n * filenames, as used in RFCs 4648 and 7515 (JWS/JWT/JWE).\n *\n * See $(LREF Base64Impl) for a description of available methods.\n */\nalias Base64URLNoPadding = Base64Impl!('-', '_', Base64.NoPadding);\n\n///\n@safe unittest\n{\n    ubyte[] data = [0x83, 0xd7, 0x30, 0x7b, 0xef];\n    assert(Base64URLNoPadding.encode(data) == \"g9cwe-8\");\n    assert(Base64URLNoPadding.decode(\"g9cwe-8\") == data);\n}\n\n/**\n * Template for implementing Base64 encoding and decoding.\n *\n * For most purposes, direct usage of this template is not necessary; instead,\n * this module provides default implementations: $(LREF Base64), implementing\n * basic Base64 encoding, and $(LREF Base64URL) and $(LREF Base64URLNoPadding),\n * that implement the Base64 variant for use in URLs and filenames, with\n * and without padding, respectively.\n *\n * Customized Base64 encoding schemes can be implemented by instantiating this\n * template with the appropriate arguments. For example:\n *\n * -----\n * // Non-standard Base64 format for embedding in regular expressions.\n * alias Base64Re = Base64Impl!('!', '=', Base64.NoPadding);\n * -----\n *\n * NOTE:\n * Encoded strings will not have any padding if the `Padding` parameter is\n * set to `NoPadding`.\n */\ntemplate Base64Impl(char Map62th, char Map63th, char Padding = '=')\n{\n    enum NoPadding = '\\0';  /// represents no-padding encoding\n\n\n    // Verify Base64 characters\n    static assert(Map62th < 'A' || Map62th > 'Z', \"Character '\" ~ Map62th ~ \"' cannot be used twice\");\n    static assert(Map63th < 'A' || Map63th > 'Z', \"Character '\" ~ Map63th ~ \"' cannot be used twice\");\n    static assert(Padding < 'A' || Padding > 'Z', \"Character '\" ~ Padding ~ \"' cannot be used twice\");\n    static assert(Map62th < 'a' || Map62th > 'z', \"Character '\" ~ Map62th ~ \"' cannot be used twice\");\n    static assert(Map63th < 'a' || Map63th > 'z', \"Character '\" ~ Map63th ~ \"' cannot be used twice\");\n    static assert(Padding < 'a' || Padding > 'z', \"Character '\" ~ Padding ~ \"' cannot be used twice\");\n    static assert(Map62th < '0' || Map62th > '9', \"Character '\" ~ Map62th ~ \"' cannot be used twice\");\n    static assert(Map63th < '0' || Map63th > '9', \"Character '\" ~ Map63th ~ \"' cannot be used twice\");\n    static assert(Padding < '0' || Padding > '9', \"Character '\" ~ Padding ~ \"' cannot be used twice\");\n    static assert(Map62th != Map63th, \"Character '\" ~ Map63th ~ \"' cannot be used twice\");\n    static assert(Map62th != Padding, \"Character '\" ~ Padding ~ \"' cannot be used twice\");\n    static assert(Map63th != Padding, \"Character '\" ~ Padding ~ \"' cannot be used twice\");\n    static assert(Map62th != NoPadding, \"'\\\\0' is not a valid Base64character\");\n    static assert(Map63th != NoPadding, \"'\\\\0' is not a valid Base64character\");\n\n\n    /* Encode functions */\n\n\n    private immutable EncodeMap = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\" ~ Map62th ~ Map63th;\n\n\n    /**\n     * Calculates the length needed to store the encoded string corresponding\n     * to an input of the given length.\n     *\n     * Params:\n     *  sourceLength = Length of the source array.\n     *\n     * Returns:\n     *  The length of a Base64 encoding of an array of the given length.\n     */\n    @safe\n    pure nothrow size_t encodeLength(in size_t sourceLength)\n    {\n        static if (Padding == NoPadding)\n            return (sourceLength / 3) * 4 + (sourceLength % 3 == 0 ? 0 : sourceLength % 3 == 1 ? 2 : 3);\n        else\n            return (sourceLength / 3 + (sourceLength % 3 ? 1 : 0)) * 4;\n    }\n\n    ///\n    @safe unittest\n    {\n        ubyte[] data = [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e];\n\n        // Allocate a buffer large enough to hold the encoded string.\n        auto buf = new char[Base64.encodeLength(data.length)];\n\n        Base64.encode(data, buf);\n        assert(buf == \"Gis8TV1u\");\n    }\n\n\n    // ubyte[] to char[]\n\n\n    /**\n     * Encode $(D_PARAM source) into a `char[]` buffer using Base64\n     * encoding.\n     *\n     * Params:\n     *  source = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     *           to _encode.\n     *  buffer = The `char[]` buffer to store the encoded result.\n     *\n     * Returns:\n     *  The slice of $(D_PARAM buffer) that contains the encoded string.\n     */\n    @trusted\n    pure char[] encode(R1, R2)(in R1 source, R2 buffer) if (isArray!R1 && is(ElementType!R1 : ubyte) &&\n                                                            is(R2 == char[]))\n    in\n    {\n        assert(buffer.length >= encodeLength(source.length), \"Insufficient buffer for encoding\");\n    }\n    out(result)\n    {\n        assert(result.length == encodeLength(source.length), \"The length of result is different from Base64\");\n    }\n    do\n    {\n        immutable srcLen = source.length;\n        if (srcLen == 0)\n            return [];\n\n        immutable blocks = srcLen / 3;\n        immutable remain = srcLen % 3;\n        auto      bufptr = buffer.ptr;\n        auto      srcptr = source.ptr;\n\n        foreach (Unused; 0 .. blocks)\n        {\n            immutable val = srcptr[0] << 16 | srcptr[1] << 8 | srcptr[2];\n            *bufptr++ = EncodeMap[val >> 18       ];\n            *bufptr++ = EncodeMap[val >> 12 & 0x3f];\n            *bufptr++ = EncodeMap[val >>  6 & 0x3f];\n            *bufptr++ = EncodeMap[val       & 0x3f];\n            srcptr += 3;\n        }\n\n        if (remain)\n        {\n            immutable val = srcptr[0] << 16 | (remain == 2 ? srcptr[1] << 8 : 0);\n            *bufptr++ = EncodeMap[val >> 18       ];\n            *bufptr++ = EncodeMap[val >> 12 & 0x3f];\n\n            final switch (remain)\n            {\n            case 2:\n                *bufptr++ = EncodeMap[val >> 6 & 0x3f];\n                static if (Padding != NoPadding)\n                    *bufptr++ = Padding;\n                break;\n            case 1:\n                static if (Padding != NoPadding)\n                {\n                    *bufptr++ = Padding;\n                    *bufptr++ = Padding;\n                }\n                break;\n            }\n        }\n\n        // encode method can't assume buffer length. So, slice needed.\n        return buffer[0 .. bufptr - buffer.ptr];\n    }\n\n    ///\n    @safe unittest\n    {\n        ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];\n        char[32] buffer;    // much bigger than necessary\n\n        // Just to be sure...\n        auto encodedLength = Base64.encodeLength(data.length);\n        assert(buffer.length >= encodedLength);\n\n        // encode() returns a slice to the provided buffer.\n        auto encoded = Base64.encode(data, buffer[]);\n        assert(encoded is buffer[0 .. encodedLength]);\n        assert(encoded == \"g9cwegE/\");\n    }\n\n\n    // InputRange to char[]\n\n\n    /**\n     * ditto\n     */\n    char[] encode(R1, R2)(R1 source, R2 buffer) if (!isArray!R1 && isInputRange!R1 &&\n                                                    is(ElementType!R1 : ubyte) && hasLength!R1 &&\n                                                    is(R2 == char[]))\n    in\n    {\n        assert(buffer.length >= encodeLength(source.length), \"Insufficient buffer for encoding\");\n    }\n    out(result)\n    {\n        // @@@BUG@@@ D's DbC can't caputre an argument of function and store the result of precondition.\n        //assert(result.length == encodeLength(source.length), \"The length of result is different from Base64\");\n    }\n    do\n    {\n        immutable srcLen = source.length;\n        if (srcLen == 0)\n            return [];\n\n        immutable blocks = srcLen / 3;\n        immutable remain = srcLen % 3;\n        auto      bufptr = buffer.ptr;\n\n        foreach (Unused; 0 .. blocks)\n        {\n            immutable v1 = source.front; source.popFront();\n            immutable v2 = source.front; source.popFront();\n            immutable v3 = source.front; source.popFront();\n            immutable val = v1 << 16 | v2 << 8 | v3;\n            *bufptr++ = EncodeMap[val >> 18       ];\n            *bufptr++ = EncodeMap[val >> 12 & 0x3f];\n            *bufptr++ = EncodeMap[val >>  6 & 0x3f];\n            *bufptr++ = EncodeMap[val       & 0x3f];\n        }\n\n        if (remain)\n        {\n            size_t val = source.front << 16;\n            if (remain == 2)\n            {\n                source.popFront();\n                val |= source.front << 8;\n            }\n\n            *bufptr++ = EncodeMap[val >> 18       ];\n            *bufptr++ = EncodeMap[val >> 12 & 0x3f];\n\n            final switch (remain)\n            {\n            case 2:\n                *bufptr++ = EncodeMap[val >> 6 & 0x3f];\n                static if (Padding != NoPadding)\n                    *bufptr++ = Padding;\n                break;\n            case 1:\n                static if (Padding != NoPadding)\n                {\n                    *bufptr++ = Padding;\n                    *bufptr++ = Padding;\n                }\n                break;\n            }\n        }\n\n        // @@@BUG@@@ Workaround for DbC problem. See comment on 'out'.\n        version (unittest)\n            assert(\n                bufptr - buffer.ptr == encodeLength(srcLen),\n                \"The length of result is different from Base64\"\n            );\n\n        // encode method can't assume buffer length. So, slice needed.\n        return buffer[0 .. bufptr - buffer.ptr];\n    }\n\n\n    // ubyte[] to OutputRange\n\n\n    /**\n     * Encodes $(D_PARAM source) into an\n     * $(REF_ALTTEXT output range, isOutputRange, std,range,primitives) using\n     * Base64 encoding.\n     *\n     * Params:\n     *  source = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     *           to _encode.\n     *  range  = The $(REF_ALTTEXT output range, isOutputRange, std,range,primitives)\n     *           to store the encoded result.\n     *\n     * Returns:\n     *  The number of times the output range's `put` method was invoked.\n     */\n    size_t encode(E, R)(scope const(E)[] source, auto ref R range)\n    if (is(E : ubyte) && isOutputRange!(R, char) && !is(R == char[]))\n    out(result)\n    {\n        assert(result == encodeLength(source.length), \"The number of put is different from the length of Base64\");\n    }\n    do\n    {\n        immutable srcLen = source.length;\n        if (srcLen == 0)\n            return 0;\n\n        immutable blocks = srcLen / 3;\n        immutable remain = srcLen % 3;\n        auto s = source; // copy for out contract length check\n        size_t pcount;\n\n        foreach (Unused; 0 .. blocks)\n        {\n            immutable val = s[0] << 16 | s[1] << 8 | s[2];\n            put(range, EncodeMap[val >> 18       ]);\n            put(range, EncodeMap[val >> 12 & 0x3f]);\n            put(range, EncodeMap[val >>  6 & 0x3f]);\n            put(range, EncodeMap[val       & 0x3f]);\n            s = s[3 .. $];\n            pcount += 4;\n        }\n\n        if (remain)\n        {\n            immutable val = s[0] << 16 | (remain == 2 ? s[1] << 8 : 0);\n            put(range, EncodeMap[val >> 18       ]);\n            put(range, EncodeMap[val >> 12 & 0x3f]);\n            pcount += 2;\n\n            final switch (remain)\n            {\n            case 2:\n                put(range, EncodeMap[val >> 6 & 0x3f]);\n                pcount++;\n\n                static if (Padding != NoPadding)\n                {\n                    put(range, Padding);\n                    pcount++;\n                }\n                break;\n            case 1:\n                static if (Padding != NoPadding)\n                {\n                    put(range, Padding);\n                    put(range, Padding);\n                    pcount += 2;\n                }\n                break;\n            }\n        }\n\n        return pcount;\n    }\n\n    ///\n    @safe pure nothrow unittest\n    {\n        import std.array : appender;\n\n        auto output = appender!string();\n        ubyte[] data = [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e];\n\n        // This overload of encode() returns the number of calls to the output\n        // range's put method.\n        assert(Base64.encode(data, output) == 8);\n        assert(output.data == \"Gis8TV1u\");\n    }\n\n\n    // InputRange to OutputRange\n\n\n    /**\n     * ditto\n     */\n    size_t encode(R1, R2)(R1 source, auto ref R2 range)\n        if (!isArray!R1 && isInputRange!R1 && is(ElementType!R1 : ubyte) &&\n            hasLength!R1 && !is(R2 == char[]) && isOutputRange!(R2, char))\n    out(result)\n    {\n        // @@@BUG@@@ Workaround for DbC problem.\n        //assert(result == encodeLength(source.length), \"The number of put is different from the length of Base64\");\n    }\n    do\n    {\n        immutable srcLen = source.length;\n        if (srcLen == 0)\n            return 0;\n\n        immutable blocks = srcLen / 3;\n        immutable remain = srcLen % 3;\n        size_t    pcount;\n\n        foreach (Unused; 0 .. blocks)\n        {\n            immutable v1 = source.front; source.popFront();\n            immutable v2 = source.front; source.popFront();\n            immutable v3 = source.front; source.popFront();\n            immutable val = v1 << 16 | v2 << 8 | v3;\n            put(range, EncodeMap[val >> 18       ]);\n            put(range, EncodeMap[val >> 12 & 0x3f]);\n            put(range, EncodeMap[val >>  6 & 0x3f]);\n            put(range, EncodeMap[val       & 0x3f]);\n            pcount += 4;\n        }\n\n        if (remain)\n        {\n            size_t val = source.front << 16;\n            if (remain == 2)\n            {\n                source.popFront();\n                val |= source.front << 8;\n            }\n\n            put(range, EncodeMap[val >> 18       ]);\n            put(range, EncodeMap[val >> 12 & 0x3f]);\n            pcount += 2;\n\n            final switch (remain)\n            {\n            case 2:\n                put(range, EncodeMap[val >> 6 & 0x3f]);\n                pcount++;\n\n                static if (Padding != NoPadding)\n                {\n                    put(range, Padding);\n                    pcount++;\n                }\n                break;\n            case 1:\n                static if (Padding != NoPadding)\n                {\n                    put(range, Padding);\n                    put(range, Padding);\n                    pcount += 2;\n                }\n                break;\n            }\n        }\n\n        // @@@BUG@@@ Workaround for DbC problem.\n        version (unittest)\n            assert(\n                pcount == encodeLength(srcLen),\n                \"The number of put is different from the length of Base64\"\n            );\n\n        return pcount;\n    }\n\n\n    /**\n     * Encodes $(D_PARAM source) to newly-allocated buffer.\n     *\n     * This convenience method alleviates the need to manually manage output\n     * buffers.\n     *\n     * Params:\n     *  source = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     *           to _encode.\n     *\n     * Returns:\n     *  A newly-allocated `char[]` buffer containing the encoded string.\n     */\n    @safe\n    pure char[] encode(Range)(Range source) if (isArray!Range && is(ElementType!Range : ubyte))\n    {\n        return encode(source, new char[encodeLength(source.length)]);\n    }\n\n    ///\n    @safe unittest\n    {\n        ubyte[] data = [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e];\n        assert(Base64.encode(data) == \"Gis8TV1u\");\n    }\n\n\n    /**\n     * ditto\n     */\n    char[] encode(Range)(Range source) if (!isArray!Range && isInputRange!Range &&\n                                           is(ElementType!Range : ubyte) && hasLength!Range)\n    {\n        return encode(source, new char[encodeLength(source.length)]);\n    }\n\n\n    /**\n     * An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) that\n     * iterates over the respective Base64 encodings of a range of data items.\n     *\n     * This range will be a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n     * if the underlying data source is at least a forward range.\n     *\n     * Note: This struct is not intended to be created in user code directly;\n     * use the $(LREF encoder) function instead.\n     */\n    struct Encoder(Range) if (isInputRange!Range && (is(ElementType!Range : const(ubyte)[]) ||\n                                                     is(ElementType!Range : const(char)[])))\n    {\n      private:\n        Range  range_;\n        char[] buffer_, encoded_;\n\n\n      public:\n        this(Range range)\n        {\n            range_ = range;\n            doEncoding();\n        }\n\n\n        /**\n         * Returns:\n         *  true if there is no more encoded data left.\n         */\n        @property @trusted\n        bool empty()\n        {\n            return range_.empty;\n        }\n\n\n        /**\n         * Returns: The current chunk of encoded data.\n         */\n        @property @safe\n        nothrow char[] front()\n        {\n            return encoded_;\n        }\n\n\n        /**\n         * Advance the range to the next chunk of encoded data.\n         *\n         * Throws:\n         *  `Base64Exception` If invoked when\n         *  $(LREF2 .Base64Impl.Encoder.empty, empty) returns `true`.\n         */\n        void popFront()\n        {\n            enforce(!empty, new Base64Exception(\"Cannot call popFront on Encoder with no data remaining\"));\n\n            range_.popFront();\n\n            /*\n             * This check is very ugly. I think this is a Range's flaw.\n             * I very strongly want the Range guideline for unified implementation.\n             *\n             * In this case, Encoder becomes a beautiful implementation if 'front' performs Base64 encoding.\n             */\n            if (!empty)\n                doEncoding();\n        }\n\n\n        static if (isForwardRange!Range)\n        {\n            /**\n             * Save the current iteration state of the range.\n             *\n             * This method is only available if the underlying range is a\n             * $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives).\n             *\n             * Returns:\n             *  A copy of `this`.\n             */\n            @property\n            typeof(this) save()\n            {\n                typeof(return) encoder;\n\n                encoder.range_   = range_.save;\n                encoder.buffer_  = buffer_.dup;\n                encoder.encoded_ = encoder.buffer_[0 .. encoded_.length];\n\n                return encoder;\n            }\n        }\n\n\n      private:\n        void doEncoding()\n        {\n            auto data = cast(const(ubyte)[])range_.front;\n            auto size = encodeLength(data.length);\n            if (size > buffer_.length)\n                buffer_.length = size;\n\n            encoded_ = encode(data, buffer_);\n        }\n    }\n\n\n    /**\n     * An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) that\n     * iterates over the encoded bytes of the given source data.\n     *\n     * It will be a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n     * if the underlying data source is at least a forward range.\n     *\n     * Note: This struct is not intended to be created in user code directly;\n     * use the $(LREF encoder) function instead.\n     */\n    struct Encoder(Range) if (isInputRange!Range && is(ElementType!Range : ubyte))\n    {\n      private:\n        Range range_;\n        ubyte first;\n        int   pos, padding;\n\n\n      public:\n        this(Range range)\n        {\n            range_ = range;\n            static if (isForwardRange!Range)\n                range_ = range_.save;\n\n            if (range_.empty)\n                pos = -1;\n            else\n                popFront();\n        }\n\n\n        /**\n         * Returns:\n         *  true if there are no more encoded characters to be iterated.\n         */\n        @property @safe\n        nothrow bool empty() const\n        {\n            static if (Padding == NoPadding)\n                return pos < 0;\n            else\n                return pos < 0 && !padding;\n        }\n\n\n        /**\n         * Returns: The current encoded character.\n         */\n        @property @safe\n        nothrow ubyte front()\n        {\n            return first;\n        }\n\n\n        /**\n         * Advance to the next encoded character.\n         *\n         * Throws:\n         *  `Base64Exception` If invoked when $(LREF2 .Base64Impl.Encoder.empty.2,\n         *  empty) returns `true`.\n         */\n        void popFront()\n        {\n            enforce(!empty, new Base64Exception(\"Cannot call popFront on Encoder with no data remaining\"));\n\n            static if (Padding != NoPadding)\n                if (padding)\n                {\n                    first = Padding;\n                    pos   = -1;\n                    padding--;\n                    return;\n                }\n\n            if (range_.empty)\n            {\n                pos = -1;\n                return;\n            }\n\n            final switch (pos)\n            {\n            case 0:\n                first = EncodeMap[range_.front >> 2];\n                break;\n            case 1:\n                immutable t = (range_.front & 0b11) << 4;\n                range_.popFront();\n\n                if (range_.empty)\n                {\n                    first   = EncodeMap[t];\n                    padding = 3;\n                }\n                else\n                {\n                    first = EncodeMap[t | (range_.front >> 4)];\n                }\n                break;\n            case 2:\n                immutable t = (range_.front & 0b1111) << 2;\n                range_.popFront();\n\n                if (range_.empty)\n                {\n                    first   = EncodeMap[t];\n                    padding = 2;\n                }\n                else\n                {\n                    first = EncodeMap[t | (range_.front >> 6)];\n                }\n                break;\n            case 3:\n                first = EncodeMap[range_.front & 0b111111];\n                range_.popFront();\n                break;\n            }\n\n            ++pos %= 4;\n        }\n\n\n        static if (isForwardRange!Range)\n        {\n            /**\n             * Save the current iteration state of the range.\n             *\n             * This method is only available if the underlying range is a\n             * $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives).\n             *\n             * Returns:\n             *  A copy of `this`.\n             */\n            @property\n            typeof(this) save()\n            {\n                auto encoder = this;\n                encoder.range_ = encoder.range_.save;\n                return encoder;\n            }\n        }\n    }\n\n\n    /**\n     * Construct an `Encoder` that iterates over the Base64 encoding of the\n     * given $(REF_ALTTEXT input range, isInputRange, std,range,primitives).\n     *\n     * Params:\n     *  range = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     *          over the data to be encoded.\n     *\n     * Returns:\n     *  If $(D_PARAM range) is a range of bytes, an `Encoder` that iterates\n     *  over the bytes of the corresponding Base64 encoding.\n     *\n     *  If $(D_PARAM range) is a range of ranges of bytes, an `Encoder` that\n     *  iterates over the Base64 encoded strings of each element of the range.\n     *\n     *  In both cases, the returned `Encoder` will be a\n     *  $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) if the\n     *  given `range` is at least a forward range, otherwise it will be only\n     *  an input range.\n     *\n     * Example:\n     * This example encodes the input one line at a time.\n     * -----\n     * File f = File(\"text.txt\", \"r\");\n     * scope(exit) f.close();\n     *\n     * uint line = 0;\n     * foreach (encoded; Base64.encoder(f.byLine()))\n     * {\n     *     writeln(++line, \". \", encoded);\n     * }\n     * -----\n     *\n     * Example:\n     * This example encodes the input data one byte at a time.\n     * -----\n     * ubyte[] data = cast(ubyte[]) \"0123456789\";\n     *\n     * // The ElementType of data is not aggregation type\n     * foreach (encoded; Base64.encoder(data))\n     * {\n     *     writeln(encoded);\n     * }\n     * -----\n     */\n    Encoder!(Range) encoder(Range)(Range range) if (isInputRange!Range)\n    {\n        return typeof(return)(range);\n    }\n\n\n    /* Decode functions */\n\n\n    private immutable int[char.max + 1] DecodeMap = [\n        'A':0b000000, 'B':0b000001, 'C':0b000010, 'D':0b000011, 'E':0b000100,\n        'F':0b000101, 'G':0b000110, 'H':0b000111, 'I':0b001000, 'J':0b001001,\n        'K':0b001010, 'L':0b001011, 'M':0b001100, 'N':0b001101, 'O':0b001110,\n        'P':0b001111, 'Q':0b010000, 'R':0b010001, 'S':0b010010, 'T':0b010011,\n        'U':0b010100, 'V':0b010101, 'W':0b010110, 'X':0b010111, 'Y':0b011000,\n        'Z':0b011001, 'a':0b011010, 'b':0b011011, 'c':0b011100, 'd':0b011101,\n        'e':0b011110, 'f':0b011111, 'g':0b100000, 'h':0b100001, 'i':0b100010,\n        'j':0b100011, 'k':0b100100, 'l':0b100101, 'm':0b100110, 'n':0b100111,\n        'o':0b101000, 'p':0b101001, 'q':0b101010, 'r':0b101011, 's':0b101100,\n        't':0b101101, 'u':0b101110, 'v':0b101111, 'w':0b110000, 'x':0b110001,\n        'y':0b110010, 'z':0b110011, '0':0b110100, '1':0b110101, '2':0b110110,\n        '3':0b110111, '4':0b111000, '5':0b111001, '6':0b111010, '7':0b111011,\n        '8':0b111100, '9':0b111101, Map62th:0b111110, Map63th:0b111111, Padding:-1\n    ];\n\n\n    /**\n     * Given a Base64 encoded string, calculates the length of the decoded\n     * string.\n     *\n     * Params:\n     *  sourceLength = The length of the Base64 encoding.\n     *\n     * Returns:\n     *  The length of the decoded string corresponding to a Base64 encoding of\n     *  length $(D_PARAM sourceLength).\n     */\n    @safe\n    pure nothrow size_t decodeLength(in size_t sourceLength)\n    {\n        static if (Padding == NoPadding)\n            return (sourceLength / 4) * 3 + (sourceLength % 4 < 2 ? 0 : sourceLength % 4 == 2 ? 1 : 2);\n        else\n            return (sourceLength / 4) * 3;\n    }\n\n    ///\n    @safe unittest\n    {\n        auto encoded = \"Gis8TV1u\";\n\n        // Allocate a sufficiently large buffer to hold to decoded result.\n        auto buffer = new ubyte[Base64.decodeLength(encoded.length)];\n\n        Base64.decode(encoded, buffer);\n        assert(buffer == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);\n    }\n\n\n    // Used in decode contracts. Calculates the actual size the decoded\n    // result should have, taking into account trailing padding.\n    @safe\n    pure nothrow private size_t realDecodeLength(R)(R source)\n    {\n        auto expect = decodeLength(source.length);\n        static if (Padding != NoPadding)\n        {\n            if (source.length % 4 == 0)\n            {\n                expect -= source.length == 0       ? 0 :\n                          source[$ - 2] == Padding ? 2 :\n                          source[$ - 1] == Padding ? 1 : 0;\n            }\n        }\n        return expect;\n    }\n\n\n    // char[] to ubyte[]\n\n\n    /**\n     * Decodes $(D_PARAM source) into the given buffer.\n     *\n     * Params:\n     *  source = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     *           to _decode.\n     *  buffer = The buffer to store decoded result.\n     *\n     * Returns:\n     *  The slice of $(D_PARAM buffer) containing the decoded result.\n     *\n     * Throws:\n     *  `Base64Exception` if $(D_PARAM source) contains characters outside the\n     *  base alphabet of the current Base64 encoding scheme.\n     */\n    @trusted\n    pure ubyte[] decode(R1, R2)(in R1 source, R2 buffer) if (isArray!R1 && is(ElementType!R1 : dchar) &&\n                                                             is(R2 == ubyte[]) && isOutputRange!(R2, ubyte))\n    in\n    {\n        assert(buffer.length >= realDecodeLength(source), \"Insufficient buffer for decoding\");\n    }\n    out(result)\n    {\n        immutable expect = realDecodeLength(source);\n        assert(result.length == expect, \"The length of result is different from the expected length\");\n    }\n    do\n    {\n        immutable srcLen = source.length;\n        if (srcLen == 0)\n            return [];\n        static if (Padding != NoPadding)\n            enforce(srcLen % 4 == 0, new Base64Exception(\"Invalid length of encoded data\"));\n\n        immutable blocks = srcLen / 4;\n        auto      srcptr = source.ptr;\n        auto      bufptr = buffer.ptr;\n\n        foreach (Unused; 0 .. blocks)\n        {\n            immutable v1 = decodeChar(*srcptr++);\n            immutable v2 = decodeChar(*srcptr++);\n\n            *bufptr++ = cast(ubyte)(v1 << 2 | v2 >> 4);\n\n            immutable v3 = decodeChar(*srcptr++);\n            if (v3 == -1)\n                break;\n\n            *bufptr++ = cast(ubyte)((v2 << 4 | v3 >> 2) & 0xff);\n\n            immutable v4 = decodeChar(*srcptr++);\n            if (v4 == -1)\n                break;\n\n            *bufptr++ = cast(ubyte)((v3 << 6 | v4) & 0xff);\n        }\n\n        static if (Padding == NoPadding)\n        {\n            immutable remain = srcLen % 4;\n\n            if (remain)\n            {\n                immutable v1 = decodeChar(*srcptr++);\n                immutable v2 = decodeChar(*srcptr++);\n\n                *bufptr++ = cast(ubyte)(v1 << 2 | v2 >> 4);\n\n                if (remain == 3)\n                    *bufptr++ = cast(ubyte)((v2 << 4 | decodeChar(*srcptr++) >> 2) & 0xff);\n            }\n        }\n\n        return buffer[0 .. bufptr - buffer.ptr];\n    }\n\n    ///\n    @safe unittest\n    {\n        auto encoded = \"Gis8TV1u\";\n        ubyte[32] buffer;   // much bigger than necessary\n\n        // Just to be sure...\n        auto decodedLength = Base64.decodeLength(encoded.length);\n        assert(buffer.length >= decodedLength);\n\n        // decode() returns a slice of the given buffer.\n        auto decoded = Base64.decode(encoded, buffer[]);\n        assert(decoded is buffer[0 .. decodedLength]);\n        assert(decoded == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);\n    }\n\n    // InputRange to ubyte[]\n\n\n    /**\n     * ditto\n     */\n    ubyte[] decode(R1, R2)(R1 source, R2 buffer) if (!isArray!R1 && isInputRange!R1 &&\n                                                     is(ElementType!R1 : dchar) && hasLength!R1 &&\n                                                     is(R2 == ubyte[]) && isOutputRange!(R2, ubyte))\n    in\n    {\n        assert(buffer.length >= decodeLength(source.length), \"Insufficient buffer for decoding\");\n    }\n    out(result)\n    {\n        // @@@BUG@@@ Workaround for DbC problem.\n        //immutable expect = decodeLength(source.length) - 2;\n        //assert(result.length >= expect, \"The length of result is smaller than expected length\");\n    }\n    do\n    {\n        immutable srcLen = source.length;\n        if (srcLen == 0)\n            return [];\n        static if (Padding != NoPadding)\n            enforce(srcLen % 4 == 0, new Base64Exception(\"Invalid length of encoded data\"));\n\n        immutable blocks = srcLen / 4;\n        auto      bufptr = buffer.ptr;\n\n        foreach (Unused; 0 .. blocks)\n        {\n            immutable v1 = decodeChar(source.front); source.popFront();\n            immutable v2 = decodeChar(source.front); source.popFront();\n\n            *bufptr++ = cast(ubyte)(v1 << 2 | v2 >> 4);\n\n            immutable v3 = decodeChar(source.front);\n            if (v3 == -1)\n                break;\n\n            *bufptr++ = cast(ubyte)((v2 << 4 | v3 >> 2) & 0xff);\n            source.popFront();\n\n            immutable v4 = decodeChar(source.front);\n            if (v4 == -1)\n                break;\n\n            *bufptr++ = cast(ubyte)((v3 << 6 | v4) & 0xff);\n            source.popFront();\n        }\n\n        static if (Padding == NoPadding)\n        {\n            immutable remain = srcLen % 4;\n\n            if (remain)\n            {\n                immutable v1 = decodeChar(source.front); source.popFront();\n                immutable v2 = decodeChar(source.front);\n\n                *bufptr++ = cast(ubyte)(v1 << 2 | v2 >> 4);\n\n                if (remain == 3)\n                {\n                    source.popFront();\n                    *bufptr++ = cast(ubyte)((v2 << 4 | decodeChar(source.front) >> 2) & 0xff);\n                }\n            }\n        }\n\n        // @@@BUG@@@ Workaround for DbC problem.\n        version (unittest)\n            assert(\n                (bufptr - buffer.ptr) >= (decodeLength(srcLen) - 2),\n                \"The length of result is smaller than expected length\"\n            );\n\n        return buffer[0 .. bufptr - buffer.ptr];\n    }\n\n\n    // char[] to OutputRange\n\n\n    /**\n     * Decodes $(D_PARAM source) into a given\n     * $(REF_ALTTEXT output range, isOutputRange, std,range,primitives).\n     *\n     * Params:\n     *  source = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     *           to _decode.\n     *  range  = The $(REF_ALTTEXT output range, isOutputRange, std,range,primitives)\n     *           to store the decoded result.\n     *\n     * Returns:\n     *  The number of times the output range's `put` method was invoked.\n     *\n     * Throws:\n     *  `Base64Exception` if $(D_PARAM source) contains characters outside the\n     *  base alphabet of the current Base64 encoding scheme.\n     */\n    size_t decode(R1, R2)(in R1 source, auto ref R2 range)\n        if (isArray!R1 && is(ElementType!R1 : dchar) &&\n            !is(R2 == ubyte[]) && isOutputRange!(R2, ubyte))\n    out(result)\n    {\n        immutable expect = realDecodeLength(source);\n        assert(result == expect, \"The result of decode is different from the expected\");\n    }\n    do\n    {\n        immutable srcLen = source.length;\n        if (srcLen == 0)\n            return 0;\n        static if (Padding != NoPadding)\n            enforce(srcLen % 4 == 0, new Base64Exception(\"Invalid length of encoded data\"));\n\n        immutable blocks = srcLen / 4;\n        auto      srcptr = source.ptr;\n        size_t    pcount;\n\n        foreach (Unused; 0 .. blocks)\n        {\n            immutable v1 = decodeChar(*srcptr++);\n            immutable v2 = decodeChar(*srcptr++);\n\n            put(range, cast(ubyte)(v1 << 2 | v2 >> 4));\n            pcount++;\n\n            immutable v3 = decodeChar(*srcptr++);\n            if (v3 == -1)\n                break;\n\n            put(range, cast(ubyte)((v2 << 4 | v3 >> 2) & 0xff));\n            pcount++;\n\n            immutable v4 = decodeChar(*srcptr++);\n            if (v4 == -1)\n                break;\n\n            put(range, cast(ubyte)((v3 << 6 | v4) & 0xff));\n            pcount++;\n        }\n\n        static if (Padding == NoPadding)\n        {\n            immutable remain = srcLen % 4;\n\n            if (remain)\n            {\n                immutable v1 = decodeChar(*srcptr++);\n                immutable v2 = decodeChar(*srcptr++);\n\n                put(range, cast(ubyte)(v1 << 2 | v2 >> 4));\n                pcount++;\n\n                if (remain == 3)\n                {\n                    put(range, cast(ubyte)((v2 << 4 | decodeChar(*srcptr++) >> 2) & 0xff));\n                    pcount++;\n                }\n            }\n        }\n\n        return pcount;\n    }\n\n    ///\n    @system unittest\n    {\n        struct OutputRange\n        {\n            ubyte[] result;\n            void put(ubyte b) { result ~= b; }\n        }\n        OutputRange output;\n\n        // This overload of decode() returns the number of calls to put().\n        assert(Base64.decode(\"Gis8TV1u\", output) == 6);\n        assert(output.result == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);\n    }\n\n\n    // InputRange to OutputRange\n\n\n    /**\n     * ditto\n     */\n    size_t decode(R1, R2)(R1 source, auto ref R2 range)\n        if (!isArray!R1 && isInputRange!R1 && is(ElementType!R1 : dchar) &&\n            hasLength!R1 && !is(R2 == ubyte[]) && isOutputRange!(R2, ubyte))\n    out(result)\n    {\n        // @@@BUG@@@ Workaround for DbC problem.\n        //immutable expect = decodeLength(source.length) - 2;\n        //assert(result >= expect, \"The length of result is smaller than expected length\");\n    }\n    do\n    {\n        immutable srcLen = source.length;\n        if (srcLen == 0)\n            return 0;\n        static if (Padding != NoPadding)\n            enforce(srcLen % 4 == 0, new Base64Exception(\"Invalid length of encoded data\"));\n\n        immutable blocks = srcLen / 4;\n        size_t    pcount;\n\n        foreach (Unused; 0 .. blocks)\n        {\n            immutable v1 = decodeChar(source.front); source.popFront();\n            immutable v2 = decodeChar(source.front); source.popFront();\n\n            put(range, cast(ubyte)(v1 << 2 | v2 >> 4));\n            pcount++;\n\n            immutable v3 = decodeChar(source.front);\n            if (v3 == -1)\n                break;\n\n            put(range, cast(ubyte)((v2 << 4 | v3 >> 2) & 0xff));\n            source.popFront();\n            pcount++;\n\n            immutable v4 = decodeChar(source.front);\n            if (v4 == -1)\n                break;\n\n            put(range, cast(ubyte)((v3 << 6 | v4) & 0xff));\n            source.popFront();\n            pcount++;\n        }\n\n        static if (Padding == NoPadding)\n        {\n            immutable remain = srcLen % 4;\n\n            if (remain)\n            {\n                immutable v1 = decodeChar(source.front); source.popFront();\n                immutable v2 = decodeChar(source.front);\n\n                put(range, cast(ubyte)(v1 << 2 | v2 >> 4));\n                pcount++;\n\n                if (remain == 3)\n                {\n                    source.popFront();\n                    put(range, cast(ubyte)((v2 << 4 | decodeChar(source.front) >> 2) & 0xff));\n                    pcount++;\n                }\n            }\n        }\n\n        // @@@BUG@@@ Workaround for DbC problem.\n        version (unittest)\n            assert(\n                pcount >= (decodeLength(srcLen) - 2),\n                \"The length of result is smaller than expected length\"\n            );\n\n        return pcount;\n    }\n\n\n    /**\n     * Decodes $(D_PARAM source) into newly-allocated buffer.\n     *\n     * This convenience method alleviates the need to manually manage decoding\n     * buffers.\n     *\n     * Params:\n     *  source = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     *           to _decode.\n     *\n     * Returns:\n     *  A newly-allocated `ubyte[]` buffer containing the decoded string.\n     */\n    @safe\n    pure ubyte[] decode(Range)(Range source) if (isArray!Range && is(ElementType!Range : dchar))\n    {\n        return decode(source, new ubyte[decodeLength(source.length)]);\n    }\n\n    ///\n    @safe unittest\n    {\n        auto data = \"Gis8TV1u\";\n        assert(Base64.decode(data) == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);\n    }\n\n\n    /**\n     * ditto\n     */\n    ubyte[] decode(Range)(Range source) if (!isArray!Range && isInputRange!Range &&\n                                            is(ElementType!Range : dchar) && hasLength!Range)\n    {\n        return decode(source, new ubyte[decodeLength(source.length)]);\n    }\n\n\n    /**\n     * An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) that\n     * iterates over the decoded data of a range of Base64 encodings.\n     *\n     * This range will be a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n     * if the underlying data source is at least a forward range.\n     *\n     * Note: This struct is not intended to be created in user code directly;\n     * use the $(LREF decoder) function instead.\n     */\n    struct Decoder(Range) if (isInputRange!Range && (is(ElementType!Range : const(char)[]) ||\n                                                     is(ElementType!Range : const(ubyte)[])))\n    {\n      private:\n        Range   range_;\n        ubyte[] buffer_, decoded_;\n\n\n      public:\n        this(Range range)\n        {\n            range_ = range;\n            doDecoding();\n        }\n\n\n        /**\n         * Returns:\n         *  true if there are no more elements to be iterated.\n         */\n        @property @trusted\n        bool empty()\n        {\n            return range_.empty;\n        }\n\n\n        /**\n         * Returns: The decoding of the current element in the input.\n         */\n        @property @safe\n        nothrow ubyte[] front()\n        {\n            return decoded_;\n        }\n\n\n        /**\n         * Advance to the next element in the input to be decoded.\n         *\n         * Throws:\n         *  `Base64Exception` if invoked when $(LREF2 .Base64Impl.Decoder.empty,\n         *  empty) returns `true`.\n         */\n        void popFront()\n        {\n            enforce(!empty, new Base64Exception(\"Cannot call popFront on Decoder with no data remaining.\"));\n\n            range_.popFront();\n\n            /*\n             * I mentioned Encoder's popFront.\n             */\n            if (!empty)\n                doDecoding();\n        }\n\n\n        static if (isForwardRange!Range)\n        {\n            /**\n             * Saves the current iteration state.\n             *\n             * This method is only available if the underlying range is a\n             * $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n             *\n             * Returns: A copy of `this`.\n             */\n            @property\n            typeof(this) save()\n            {\n                typeof(return) decoder;\n\n                decoder.range_   = range_.save;\n                decoder.buffer_  = buffer_.dup;\n                decoder.decoded_ = decoder.buffer_[0 .. decoded_.length];\n\n                return decoder;\n            }\n        }\n\n\n      private:\n        void doDecoding()\n        {\n            auto data = cast(const(char)[])range_.front;\n\n            static if (Padding == NoPadding)\n            {\n                while (data.length % 4 == 1)\n                {\n                    range_.popFront();\n                    data ~= cast(const(char)[])range_.front;\n                }\n            }\n            else\n            {\n                while (data.length % 4 != 0)\n                {\n                    range_.popFront();\n                    data ~= cast(const(char)[])range_.front;\n                }\n            }\n\n            auto size = decodeLength(data.length);\n            if (size > buffer_.length)\n                buffer_.length = size;\n\n            decoded_ = decode(data, buffer_);\n        }\n    }\n\n\n    /**\n     * An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) that\n     * iterates over the bytes of data decoded from a Base64 encoded string.\n     *\n     * This range will be a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n     * if the underlying data source is at least a forward range.\n     *\n     * Note: This struct is not intended to be created in user code directly;\n     * use the $(LREF decoder) function instead.\n     */\n    struct Decoder(Range) if (isInputRange!Range && is(ElementType!Range : char))\n    {\n      private:\n        Range range_;\n        ubyte first;\n        int   pos;\n\n\n      public:\n        this(Range range)\n        {\n            range_ = range;\n            static if (isForwardRange!Range)\n                range_ = range_.save;\n\n            static if (Padding != NoPadding && hasLength!Range)\n                enforce(range_.length % 4 == 0, new Base64Exception(\"Invalid length of encoded data\"));\n\n            if (range_.empty)\n                pos = -1;\n            else\n                popFront();\n        }\n\n\n        /**\n         * Returns:\n         *  true if there are no more elements to be iterated.\n         */\n        @property @safe\n        nothrow bool empty() const\n        {\n            return pos < 0;\n        }\n\n\n        /**\n         * Returns: The current decoded byte.\n         */\n        @property @safe\n        nothrow ubyte front()\n        {\n            return first;\n        }\n\n\n        /**\n         * Advance to the next decoded byte.\n         *\n         * Throws:\n         *  `Base64Exception` if invoked when $(LREF2 .Base64Impl.Decoder.empty,\n         *  empty) returns `true`.\n         */\n        void popFront()\n        {\n            enforce(!empty, new Base64Exception(\"Cannot call popFront on Decoder with no data remaining\"));\n\n            static if (Padding == NoPadding)\n            {\n                bool endCondition()\n                {\n                    return range_.empty;\n                }\n            }\n            else\n            {\n                bool endCondition()\n                {\n                    enforce(!range_.empty, new Base64Exception(\"Missing padding\"));\n                    return range_.front == Padding;\n                }\n            }\n\n            if (range_.empty || range_.front == Padding)\n            {\n                pos = -1;\n                return;\n            }\n\n            final switch (pos)\n            {\n            case 0:\n                enforce(!endCondition(), new Base64Exception(\"Premature end of data found\"));\n\n                immutable t = DecodeMap[range_.front] << 2;\n                range_.popFront();\n\n                enforce(!endCondition(), new Base64Exception(\"Premature end of data found\"));\n                first = cast(ubyte)(t | (DecodeMap[range_.front] >> 4));\n                break;\n            case 1:\n                immutable t = (DecodeMap[range_.front] & 0b1111) << 4;\n                range_.popFront();\n\n                if (endCondition())\n                {\n                    pos = -1;\n                    return;\n                }\n                else\n                {\n                    first = cast(ubyte)(t | (DecodeMap[range_.front] >> 2));\n                }\n                break;\n            case 2:\n                immutable t = (DecodeMap[range_.front] & 0b11) << 6;\n                range_.popFront();\n\n                if (endCondition())\n                {\n                    pos = -1;\n                    return;\n                }\n                else\n                {\n                    first = cast(ubyte)(t | DecodeMap[range_.front]);\n                }\n\n                range_.popFront();\n                break;\n            }\n\n            ++pos %= 3;\n        }\n\n\n        static if (isForwardRange!Range)\n        {\n            /**\n             * Saves the current iteration state.\n             *\n             * This method is only available if the underlying range is a\n             * $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n             *\n             * Returns: A copy of `this`.\n             */\n            @property\n            typeof(this) save()\n            {\n                auto decoder = this;\n                decoder.range_ = decoder.range_.save;\n                return decoder;\n            }\n        }\n    }\n\n\n    /**\n     * Construct a `Decoder` that iterates over the decoding of the given\n     * Base64 encoded data.\n     *\n     * Params:\n     *  range = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     *      over the data to be decoded.\n     *\n     * Returns:\n     *  If $(D_PARAM range) is a range of characters, a `Decoder` that\n     *  iterates over the bytes of the corresponding Base64 decoding.\n     *\n     *  If $(D_PARAM range) is a range of ranges of characters, a `Decoder`\n     *  that iterates over the decoded strings corresponding to each element of\n     *  the range. In this case, the length of each subrange must be a multiple\n     *  of 4; the returned _decoder does not keep track of Base64 decoding\n     *  state across subrange boundaries.\n     *\n     *  In both cases, the returned `Decoder` will be a\n     * $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) if the\n     *  given `range` is at least a forward range, otherwise it will be only\n     *  an input range.\n     *\n     * If the input data contains characters not found in the base alphabet of\n     * the current Base64 encoding scheme, the returned range may throw a\n     * `Base64Exception`.\n     *\n     * Example:\n     * This example shows decoding over a range of input data lines.\n     * -----\n     * foreach (decoded; Base64.decoder(stdin.byLine()))\n     * {\n     *     writeln(decoded);\n     * }\n     * -----\n     *\n     * Example:\n     * This example shows decoding one byte at a time.\n     * -----\n     * auto encoded = Base64.encoder(cast(ubyte[])\"0123456789\");\n     * foreach (n; map!q{a - '0'}(Base64.decoder(encoded)))\n     * {\n     *     writeln(n);\n     * }\n     * -----\n     */\n    Decoder!(Range) decoder(Range)(Range range) if (isInputRange!Range)\n    {\n        return typeof(return)(range);\n    }\n\n\n  private:\n    @safe\n    pure int decodeChar()(char chr)\n    {\n        immutable val = DecodeMap[chr];\n\n        // enforce can't be a pure function, so I use trivial check.\n        if (val == 0 && chr != 'A')\n            throw new Base64Exception(\"Invalid character: \" ~ chr);\n\n        return val;\n    }\n\n\n    @safe\n    pure int decodeChar()(dchar chr)\n    {\n        // See above comment.\n        if (chr > 0x7f)\n            throw new Base64Exception(\"Base64-encoded character must be a single byte\");\n\n        return decodeChar(cast(char) chr);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.string : representation;\n\n    // pre-defined: alias Base64 = Base64Impl!('+', '/');\n    ubyte[] emptyArr;\n    assert(Base64.encode(emptyArr) == \"\");\n    assert(Base64.encode(\"f\".representation) == \"Zg==\");\n    assert(Base64.encode(\"foo\".representation) == \"Zm9v\");\n\n    alias Base64Re = Base64Impl!('!', '=', Base64.NoPadding);\n    assert(Base64Re.encode(\"f\".representation) == \"Zg\");\n    assert(Base64Re.encode(\"foo\".representation) == \"Zm9v\");\n}\n\n/**\n * Exception thrown upon encountering Base64 encoding or decoding errors.\n */\nclass Base64Exception : Exception\n{\n    @safe pure nothrow\n    this(string s, string fn = __FILE__, size_t ln = __LINE__)\n    {\n        super(s, fn, ln);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    assertThrown!Base64Exception(Base64.decode(\"ab|c\"));\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.sorting : sort;\n    import std.conv;\n    import std.file;\n    import std.stdio;\n\n    alias Base64Re = Base64Impl!('!', '=', Base64.NoPadding);\n\n    // Test vectors from RFC 4648\n    ubyte[][string] tv = [\n         \"\"      :cast(ubyte[])\"\",\n         \"f\"     :cast(ubyte[])\"f\",\n         \"fo\"    :cast(ubyte[])\"fo\",\n         \"foo\"   :cast(ubyte[])\"foo\",\n         \"foob\"  :cast(ubyte[])\"foob\",\n         \"fooba\" :cast(ubyte[])\"fooba\",\n         \"foobar\":cast(ubyte[])\"foobar\"\n    ];\n\n    { // Base64\n        // encode\n        assert(Base64.encodeLength(tv[\"\"].length)       == 0);\n        assert(Base64.encodeLength(tv[\"f\"].length)      == 4);\n        assert(Base64.encodeLength(tv[\"fo\"].length)     == 4);\n        assert(Base64.encodeLength(tv[\"foo\"].length)    == 4);\n        assert(Base64.encodeLength(tv[\"foob\"].length)   == 8);\n        assert(Base64.encodeLength(tv[\"fooba\"].length)  == 8);\n        assert(Base64.encodeLength(tv[\"foobar\"].length) == 8);\n\n        assert(Base64.encode(tv[\"\"])       == \"\");\n        assert(Base64.encode(tv[\"f\"])      == \"Zg==\");\n        assert(Base64.encode(tv[\"fo\"])     == \"Zm8=\");\n        assert(Base64.encode(tv[\"foo\"])    == \"Zm9v\");\n        assert(Base64.encode(tv[\"foob\"])   == \"Zm9vYg==\");\n        assert(Base64.encode(tv[\"fooba\"])  == \"Zm9vYmE=\");\n        assert(Base64.encode(tv[\"foobar\"]) == \"Zm9vYmFy\");\n\n        // decode\n        assert(Base64.decodeLength(Base64.encode(tv[\"\"]).length)       == 0);\n        assert(Base64.decodeLength(Base64.encode(tv[\"f\"]).length)      == 3);\n        assert(Base64.decodeLength(Base64.encode(tv[\"fo\"]).length)     == 3);\n        assert(Base64.decodeLength(Base64.encode(tv[\"foo\"]).length)    == 3);\n        assert(Base64.decodeLength(Base64.encode(tv[\"foob\"]).length)   == 6);\n        assert(Base64.decodeLength(Base64.encode(tv[\"fooba\"]).length)  == 6);\n        assert(Base64.decodeLength(Base64.encode(tv[\"foobar\"]).length) == 6);\n\n        assert(Base64.decode(Base64.encode(tv[\"\"]))       == tv[\"\"]);\n        assert(Base64.decode(Base64.encode(tv[\"f\"]))      == tv[\"f\"]);\n        assert(Base64.decode(Base64.encode(tv[\"fo\"]))     == tv[\"fo\"]);\n        assert(Base64.decode(Base64.encode(tv[\"foo\"]))    == tv[\"foo\"]);\n        assert(Base64.decode(Base64.encode(tv[\"foob\"]))   == tv[\"foob\"]);\n        assert(Base64.decode(Base64.encode(tv[\"fooba\"]))  == tv[\"fooba\"]);\n        assert(Base64.decode(Base64.encode(tv[\"foobar\"])) == tv[\"foobar\"]);\n\n        assertThrown!Base64Exception(Base64.decode(\"ab|c\"));\n\n        // Test decoding incomplete strings. RFC does not specify the correct\n        // behavior, but the code should never throw Errors on invalid input.\n\n        // decodeLength is nothrow\n        assert(Base64.decodeLength(1) == 0);\n        assert(Base64.decodeLength(2) <= 1);\n        assert(Base64.decodeLength(3) <= 2);\n\n        // may throw Exceptions, may not throw Errors\n        assertThrown!Base64Exception(Base64.decode(\"Zg\"));\n        assertThrown!Base64Exception(Base64.decode(\"Zg=\"));\n        assertThrown!Base64Exception(Base64.decode(\"Zm8\"));\n        assertThrown!Base64Exception(Base64.decode(\"Zg==;\"));\n    }\n\n    { // No padding\n        // encode\n        assert(Base64Re.encodeLength(tv[\"\"].length)       == 0);\n        assert(Base64Re.encodeLength(tv[\"f\"].length)      == 2);\n        assert(Base64Re.encodeLength(tv[\"fo\"].length)     == 3);\n        assert(Base64Re.encodeLength(tv[\"foo\"].length)    == 4);\n        assert(Base64Re.encodeLength(tv[\"foob\"].length)   == 6);\n        assert(Base64Re.encodeLength(tv[\"fooba\"].length)  == 7);\n        assert(Base64Re.encodeLength(tv[\"foobar\"].length) == 8);\n\n        assert(Base64Re.encode(tv[\"\"])       == \"\");\n        assert(Base64Re.encode(tv[\"f\"])      == \"Zg\");\n        assert(Base64Re.encode(tv[\"fo\"])     == \"Zm8\");\n        assert(Base64Re.encode(tv[\"foo\"])    == \"Zm9v\");\n        assert(Base64Re.encode(tv[\"foob\"])   == \"Zm9vYg\");\n        assert(Base64Re.encode(tv[\"fooba\"])  == \"Zm9vYmE\");\n        assert(Base64Re.encode(tv[\"foobar\"]) == \"Zm9vYmFy\");\n\n        // decode\n        assert(Base64Re.decodeLength(Base64Re.encode(tv[\"\"]).length)       == 0);\n        assert(Base64Re.decodeLength(Base64Re.encode(tv[\"f\"]).length)      == 1);\n        assert(Base64Re.decodeLength(Base64Re.encode(tv[\"fo\"]).length)     == 2);\n        assert(Base64Re.decodeLength(Base64Re.encode(tv[\"foo\"]).length)    == 3);\n        assert(Base64Re.decodeLength(Base64Re.encode(tv[\"foob\"]).length)   == 4);\n        assert(Base64Re.decodeLength(Base64Re.encode(tv[\"fooba\"]).length)  == 5);\n        assert(Base64Re.decodeLength(Base64Re.encode(tv[\"foobar\"]).length) == 6);\n\n        assert(Base64Re.decode(Base64Re.encode(tv[\"\"]))       == tv[\"\"]);\n        assert(Base64Re.decode(Base64Re.encode(tv[\"f\"]))      == tv[\"f\"]);\n        assert(Base64Re.decode(Base64Re.encode(tv[\"fo\"]))     == tv[\"fo\"]);\n        assert(Base64Re.decode(Base64Re.encode(tv[\"foo\"]))    == tv[\"foo\"]);\n        assert(Base64Re.decode(Base64Re.encode(tv[\"foob\"]))   == tv[\"foob\"]);\n        assert(Base64Re.decode(Base64Re.encode(tv[\"fooba\"]))  == tv[\"fooba\"]);\n        assert(Base64Re.decode(Base64Re.encode(tv[\"foobar\"])) == tv[\"foobar\"]);\n\n        // decodeLength is nothrow\n        assert(Base64.decodeLength(1) == 0);\n    }\n\n    { // with OutputRange\n        import std.array;\n\n        auto a = Appender!(char[])([]);\n        auto b = Appender!(ubyte[])([]);\n\n        assert(Base64.encode(tv[\"\"], a) == 0);\n        assert(Base64.decode(a.data, b) == 0);\n        assert(tv[\"\"] == b.data); a.clear(); b.clear();\n\n        assert(Base64.encode(tv[\"f\"], a) == 4);\n        assert(Base64.decode(a.data,  b) == 1);\n        assert(tv[\"f\"] == b.data); a.clear(); b.clear();\n\n        assert(Base64.encode(tv[\"fo\"], a) == 4);\n        assert(Base64.decode(a.data,   b) == 2);\n        assert(tv[\"fo\"] == b.data); a.clear(); b.clear();\n\n        assert(Base64.encode(tv[\"foo\"], a) == 4);\n        assert(Base64.decode(a.data,    b) == 3);\n        assert(tv[\"foo\"] == b.data); a.clear(); b.clear();\n\n        assert(Base64.encode(tv[\"foob\"], a) == 8);\n        assert(Base64.decode(a.data,     b) == 4);\n        assert(tv[\"foob\"] == b.data); a.clear(); b.clear();\n\n        assert(Base64.encode(tv[\"fooba\"], a) == 8);\n        assert(Base64.decode(a.data, b)      == 5);\n        assert(tv[\"fooba\"] == b.data); a.clear(); b.clear();\n\n        assert(Base64.encode(tv[\"foobar\"], a) == 8);\n        assert(Base64.decode(a.data, b)       == 6);\n        assert(tv[\"foobar\"] == b.data); a.clear(); b.clear();\n    }\n\n    // @@@9543@@@ These tests were disabled because they actually relied on the input range having length.\n    // The implementation (currently) doesn't support encoding/decoding from a length-less source.\n    version (none)\n    { // with InputRange\n        // InputRange to ubyte[] or char[]\n        auto encoded = Base64.encode(map!(to!(ubyte))([\"20\", \"251\", \"156\", \"3\", \"217\", \"126\"]));\n        assert(encoded == \"FPucA9l+\");\n        assert(Base64.decode(map!q{a}(encoded)) == [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]);\n\n        // InputRange to OutputRange\n        auto a = Appender!(char[])([]);\n        auto b = Appender!(ubyte[])([]);\n        assert(Base64.encode(map!(to!(ubyte))([\"20\", \"251\", \"156\", \"3\", \"217\", \"126\"]), a) == 8);\n        assert(a.data == \"FPucA9l+\");\n        assert(Base64.decode(map!q{a}(a.data), b) == 6);\n        assert(b.data == [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]);\n    }\n\n    { // Encoder and Decoder\n        {\n            string encode_file = std.file.deleteme ~ \"-testingEncoder\";\n            std.file.write(encode_file, \"\\nf\\nfo\\nfoo\\nfoob\\nfooba\\nfoobar\");\n\n            auto witness = [\"\", \"Zg==\", \"Zm8=\", \"Zm9v\", \"Zm9vYg==\", \"Zm9vYmE=\", \"Zm9vYmFy\"];\n            auto f = File(encode_file);\n            scope(exit)\n            {\n                f.close();\n                assert(!f.isOpen);\n                std.file.remove(encode_file);\n            }\n\n            size_t i;\n            foreach (encoded; Base64.encoder(f.byLine()))\n                assert(encoded == witness[i++]);\n\n            assert(i == witness.length);\n        }\n\n        {\n            string decode_file = std.file.deleteme ~ \"-testingDecoder\";\n            std.file.write(decode_file, \"\\nZg==\\nZm8=\\nZm9v\\nZm9vYg==\\nZm9vYmE=\\nZm9vYmFy\");\n\n            auto witness = sort(tv.keys);\n            auto f = File(decode_file);\n            scope(exit)\n            {\n                f.close();\n                assert(!f.isOpen);\n                std.file.remove(decode_file);\n            }\n\n            size_t i;\n            foreach (decoded; Base64.decoder(f.byLine()))\n                assert(decoded == witness[i++]);\n\n            assert(i == witness.length);\n        }\n\n        { // ForwardRange\n            {\n                auto encoder = Base64.encoder(sort(tv.values));\n                auto witness = [\"\", \"Zg==\", \"Zm8=\", \"Zm9v\", \"Zm9vYg==\", \"Zm9vYmE=\", \"Zm9vYmFy\"];\n                size_t i;\n\n                assert(encoder.front == witness[i++]); encoder.popFront();\n                assert(encoder.front == witness[i++]); encoder.popFront();\n                assert(encoder.front == witness[i++]); encoder.popFront();\n\n                foreach (encoded; encoder.save)\n                    assert(encoded == witness[i++]);\n            }\n\n            {\n                auto decoder = Base64.decoder([\"\", \"Zg==\", \"Zm8=\", \"Zm9v\", \"Zm9vYg==\", \"Zm9vYmE=\", \"Zm9vYmFy\"]);\n                auto witness = sort(tv.values);\n                size_t i;\n\n                assert(decoder.front == witness[i++]); decoder.popFront();\n                assert(decoder.front == witness[i++]); decoder.popFront();\n                assert(decoder.front == witness[i++]); decoder.popFront();\n\n                foreach (decoded; decoder.save)\n                    assert(decoded == witness[i++]);\n            }\n        }\n    }\n\n    { // Encoder and Decoder for single character encoding and decoding\n        alias Base64NoPadding = Base64Impl!('+', '/', Base64.NoPadding);\n\n        auto tests = [\n            \"\"       : [\"\", \"\", \"\", \"\"],\n            \"f\"      : [\"Zg==\", \"Zg==\", \"Zg\", \"Zg\"],\n            \"fo\"     : [\"Zm8=\", \"Zm8=\", \"Zm8\", \"Zm8\"],\n            \"foo\"    : [\"Zm9v\", \"Zm9v\", \"Zm9v\", \"Zm9v\"],\n            \"foob\"   : [\"Zm9vYg==\", \"Zm9vYg==\", \"Zm9vYg\", \"Zm9vYg\"],\n            \"fooba\"  : [\"Zm9vYmE=\", \"Zm9vYmE=\", \"Zm9vYmE\", \"Zm9vYmE\"],\n            \"foobar\" : [\"Zm9vYmFy\", \"Zm9vYmFy\", \"Zm9vYmFy\", \"Zm9vYmFy\"],\n        ];\n\n        foreach (u, e; tests)\n        {\n            assert(equal(Base64.encoder(cast(ubyte[]) u), e[0]));\n            assert(equal(Base64.decoder(Base64.encoder(cast(ubyte[]) u)), u));\n\n            assert(equal(Base64URL.encoder(cast(ubyte[]) u), e[1]));\n            assert(equal(Base64URL.decoder(Base64URL.encoder(cast(ubyte[]) u)), u));\n\n            assert(equal(Base64NoPadding.encoder(cast(ubyte[]) u), e[2]));\n            assert(equal(Base64NoPadding.decoder(Base64NoPadding.encoder(cast(ubyte[]) u)), u));\n\n            assert(equal(Base64Re.encoder(cast(ubyte[]) u), e[3]));\n            assert(equal(Base64Re.decoder(Base64Re.encoder(cast(ubyte[]) u)), u));\n        }\n    }\n}\n\n// Regression control for the output range ref bug in encode.\n@safe unittest\n{\n    struct InputRange\n    {\n        ubyte[] impl = [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e];\n        @property bool empty() { return impl.length == 0; }\n        @property ubyte front() { return impl[0]; }\n        void popFront() { impl = impl[1 .. $]; }\n        @property size_t length() { return impl.length; }\n    }\n\n    struct OutputRange\n    {\n        char[] result;\n        void put(char b) { result ~= b; }\n    }\n\n    InputRange ir;\n    OutputRange or;\n    assert(Base64.encode(ir, or) == 8);\n    assert(or.result == \"Gis8TV1u\");\n\n    // Verify that any existing workaround that uses & still works.\n    InputRange ir2;\n    OutputRange or2;\n    () @trusted {\n        assert(Base64.encode(ir2, &or2) == 8);\n    }();\n    assert(or2.result == \"Gis8TV1u\");\n}\n\n// Regression control for the output range ref bug in decode.\n@safe unittest\n{\n    struct InputRange\n    {\n        const(char)[] impl = \"Gis8TV1u\";\n        @property bool empty() { return impl.length == 0; }\n        @property dchar front() { return impl[0]; }\n        void popFront() { impl = impl[1 .. $]; }\n        @property size_t length() { return impl.length; }\n    }\n\n    struct OutputRange\n    {\n        ubyte[] result;\n        void put(ubyte b) { result ~= b; }\n    }\n\n    InputRange ir;\n    OutputRange or;\n    assert(Base64.decode(ir, or) == 6);\n    assert(or.result == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);\n\n    // Verify that any existing workaround that uses & still works.\n    InputRange ir2;\n    OutputRange or2;\n    () @trusted {\n        assert(Base64.decode(ir2, &or2) == 6);\n    }();\n    assert(or2.result == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);\n}\n"
  },
  {
    "path": "libphobos/src/std/bigint.d",
    "content": "/** Arbitrary-precision ('bignum') arithmetic.\n *\n * Performance is optimized for numbers below ~1000 decimal digits.\n * For X86 machines, highly optimised assembly routines are used.\n *\n * The following algorithms are currently implemented:\n * $(UL\n * $(LI Karatsuba multiplication)\n * $(LI Squaring is optimized independently of multiplication)\n * $(LI Divide-and-conquer division)\n * $(LI Binary exponentiation)\n * )\n *\n * For very large numbers, consider using the $(HTTP gmplib.org, GMP library) instead.\n *\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Don Clugston\n * Source: $(PHOBOSSRC std/bigint.d)\n */\n/*          Copyright Don Clugston 2008 - 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\n\nmodule std.bigint;\n\nimport std.conv : ConvException;\n\nimport std.format : FormatSpec, FormatException;\nimport std.internal.math.biguintcore;\nimport std.range.primitives;\nimport std.traits;\n\n/** A struct representing an arbitrary precision integer.\n *\n * All arithmetic operations are supported, except unsigned shift right (`>>>`).\n * Bitwise operations (`|`, `&`, `^`, `~`) are supported, and behave as if BigInt was\n * an infinite length 2's complement number.\n *\n * BigInt implements value semantics using copy-on-write. This means that\n * assignment is cheap, but operations such as x++ will cause heap\n * allocation. (But note that for most bigint operations, heap allocation is\n * inevitable anyway.)\n */\nstruct BigInt\n{\nprivate:\n    BigUint data;     // BigInt adds signed arithmetic to BigUint.\n    bool sign = false;\npublic:\n    /**\n     * Construct a `BigInt` from a decimal or hexadecimal string. The number must\n     * be in the form of a decimal or hex literal. It may have a leading `+`\n     * or `-` sign, followed by `0x` or `0X` if hexadecimal. Underscores are\n     * permitted in any location after the `0x` and/or the sign of the number.\n     *\n     * Params:\n     *     s = a finite bidirectional range of any character type\n     *\n     * Throws:\n     *     $(REF ConvException, std,conv) if the string doesn't represent a valid number\n     */\n    this(Range)(Range s) if (\n        isBidirectionalRange!Range &&\n        isSomeChar!(ElementType!Range) &&\n        !isInfinite!Range &&\n        !isSomeString!Range)\n    {\n        import std.algorithm.iteration : filterBidirectional;\n        import std.algorithm.searching : startsWith;\n        import std.conv : ConvException;\n        import std.exception : enforce;\n        import std.utf : byChar;\n\n        enforce!ConvException(!s.empty, \"Can't initialize BigInt with an empty range\");\n\n        bool neg = false;\n        bool ok;\n\n        data = 0UL;\n\n        // check for signs and if the string is a hex value\n        if (s.front == '+')\n        {\n            s.popFront(); // skip '+'\n        }\n        else if (s.front == '-')\n        {\n            neg = true;\n            s.popFront();\n        }\n\n        if (s.save.startsWith(\"0x\".byChar) ||\n            s.save.startsWith(\"0X\".byChar))\n        {\n            s.popFront;\n            s.popFront;\n\n            if (!s.empty)\n                ok = data.fromHexString(s.filterBidirectional!(a => a != '_'));\n            else\n                ok = false;\n        }\n        else\n        {\n            ok = data.fromDecimalString(s.filterBidirectional!(a => a != '_'));\n        }\n\n        enforce!ConvException(ok, \"Not a valid numerical string\");\n\n        if (isZero())\n            neg = false;\n\n        sign = neg;\n    }\n\n    /// ditto\n    this(Range)(Range s) pure if (isSomeString!Range)\n    {\n        import std.utf : byCodeUnit;\n        this(s.byCodeUnit);\n    }\n\n    @system unittest\n    {\n        // system because of the dummy ranges eventually call std.array!string\n        import std.exception : assertThrown;\n        import std.internal.test.dummyrange;\n\n        auto r1 = new ReferenceBidirectionalRange!dchar(\"101\");\n        auto big1 = BigInt(r1);\n        assert(big1 == BigInt(101));\n\n        auto r2 = new ReferenceBidirectionalRange!dchar(\"1_000\");\n        auto big2 = BigInt(r2);\n        assert(big2 == BigInt(1000));\n\n        auto r3 = new ReferenceBidirectionalRange!dchar(\"0x0\");\n        auto big3 = BigInt(r3);\n        assert(big3 == BigInt(0));\n\n        auto r4 = new ReferenceBidirectionalRange!dchar(\"0x\");\n        assertThrown!ConvException(BigInt(r4));\n    }\n\n    /// Construct a `BigInt` from a built-in integral type.\n    this(T)(T x) pure nothrow if (isIntegral!T)\n    {\n        data = data.init; // @@@: Workaround for compiler bug\n        opAssign(x);\n    }\n\n    ///\n    @system unittest\n    {\n        // @system due to failure in FreeBSD32\n        ulong data = 1_000_000_000_000;\n        auto bigData = BigInt(data);\n        assert(bigData == BigInt(\"1_000_000_000_000\"));\n    }\n\n    /// Construct a `BigInt` from another `BigInt`.\n    this(T)(T x) pure nothrow if (is(Unqual!T == BigInt))\n    {\n        opAssign(x);\n    }\n\n    ///\n    @system unittest\n    {\n        const(BigInt) b1 = BigInt(\"1_234_567_890\");\n        BigInt b2 = BigInt(b1);\n        assert(b2 == BigInt(\"1_234_567_890\"));\n    }\n\n    /// Assignment from built-in integer types.\n    BigInt opAssign(T)(T x) pure nothrow if (isIntegral!T)\n    {\n        data = cast(ulong) absUnsign(x);\n        sign = (x < 0);\n        return this;\n    }\n\n    ///\n    @system unittest\n    {\n        auto b = BigInt(\"123\");\n        b = 456;\n        assert(b == BigInt(\"456\"));\n    }\n\n    /// Assignment from another BigInt.\n    BigInt opAssign(T:BigInt)(T x) pure @nogc\n    {\n        data = x.data;\n        sign = x.sign;\n        return this;\n    }\n\n    ///\n    @system unittest\n    {\n        auto b1 = BigInt(\"123\");\n        auto b2 = BigInt(\"456\");\n        b2 = b1;\n        assert(b2 == BigInt(\"123\"));\n    }\n\n    /**\n     * Implements assignment operators from built-in integers of the form\n     * `BigInt op= integer`.\n     */\n    BigInt opOpAssign(string op, T)(T y) pure nothrow\n        if ((op==\"+\" || op==\"-\" || op==\"*\" || op==\"/\" || op==\"%\"\n          || op==\">>\" || op==\"<<\" || op==\"^^\" || op==\"|\" || op==\"&\" || op==\"^\") && isIntegral!T)\n    {\n        ulong u = absUnsign(y);\n\n        static if (op==\"+\")\n        {\n            data = BigUint.addOrSubInt(data, u, sign != (y<0), sign);\n        }\n        else static if (op==\"-\")\n        {\n            data = BigUint.addOrSubInt(data, u, sign == (y<0), sign);\n        }\n        else static if (op==\"*\")\n        {\n            if (y == 0)\n            {\n                sign = false;\n                data = 0UL;\n            }\n            else\n            {\n                sign = ( sign != (y<0) );\n                data = BigUint.mulInt(data, u);\n            }\n        }\n        else static if (op==\"/\")\n        {\n            assert(y != 0, \"Division by zero\");\n            static if (T.sizeof <= uint.sizeof)\n            {\n                data = BigUint.divInt(data, cast(uint) u);\n            }\n            else\n            {\n                data = BigUint.divInt(data, u);\n            }\n            sign = data.isZero() ? false : sign ^ (y < 0);\n        }\n        else static if (op==\"%\")\n        {\n            assert(y != 0, \"Division by zero\");\n            static if (is(immutable(T) == immutable(long)) || is( immutable(T) == immutable(ulong) ))\n            {\n                this %= BigInt(y);\n            }\n            else\n            {\n                data = cast(ulong) BigUint.modInt(data, cast(uint) u);\n                if (data.isZero())\n                    sign = false;\n            }\n            // x%y always has the same sign as x.\n            // This is not the same as mathematical mod.\n        }\n        else static if (op==\">>\" || op==\"<<\")\n        {\n            // Do a left shift if y>0 and <<, or\n            // if y<0 and >>; else do a right shift.\n            if (y == 0)\n                return this;\n            else if ((y > 0) == (op==\"<<\"))\n            {\n                // Sign never changes during left shift\n                data = data.opShl(u);\n            } else\n            {\n                data = data.opShr(u);\n                if (data.isZero())\n                    sign = false;\n            }\n        }\n        else static if (op==\"^^\")\n        {\n            sign = (y & 1) ? sign : false;\n            data = BigUint.pow(data, u);\n        }\n        else static if (op==\"|\" || op==\"&\" || op==\"^\")\n        {\n            BigInt b = y;\n            opOpAssign!op(b);\n        }\n        else static assert(0, \"BigInt \" ~ op[0..$-1] ~ \"= \" ~ T.stringof ~ \" is not supported\");\n        return this;\n    }\n\n    ///\n    @system unittest\n    {\n        //@system because opOpAssign is @system\n        auto b = BigInt(\"1_000_000_000\");\n\n        b += 12345;\n        assert(b == BigInt(\"1_000_012_345\"));\n\n        b /= 5;\n        assert(b == BigInt(\"200_002_469\"));\n    }\n\n    // Issue 16264\n    @system unittest\n    {\n        auto a = BigInt(\n    `335690982744637013564796917901053301979460129353374296317539383938630086938` ~\n    `465898213033510992292836631752875403891802201862860531801760096359705447768` ~\n    `957432600293361240407059207520920532482429912948952142341440301429494694368` ~\n    `264560802292927144211230021750155988283029753927847924288850436812178022006` ~\n    `408597793414273953252832688620479083497367463977081627995406363446761896298` ~\n    `967177607401918269561385622811274398143647535024987050366350585544531063531` ~\n    `7118554808325723941557169427279911052268935775`);\n\n        auto b = BigInt(\n    `207672245542926038535480439528441949928508406405023044025560363701392340829` ~\n    `852529131306106648201340460604257466180580583656068555417076345439694125326` ~\n    `843947164365500055567495554645796102453565953360564114634705366335703491527` ~\n    `429426780005741168078089657359833601261803592920462081364401456331489106355` ~\n    `199133982282631108670436696758342051198891939367812305559960349479160308314` ~\n    `068518200681530999860641597181672463704794566473241690395901768680673716414` ~\n    `243691584391572899147223065906633310537507956952626106509069491302359792769` ~\n    `378934570685117202046921464019396759638376362935855896435623442486036961070` ~\n    `534574698959398017332214518246531363445309522357827985468581166065335726996` ~\n    `711467464306784543112544076165391268106101754253962102479935962248302404638` ~\n    `21737237102628470475027851189594709504`);\n\n        BigInt c = a * b;  // Crashes\n\n        assert(c == BigInt(\n    `697137001950904057507249234183127244116872349433141878383548259425589716813` ~\n    `135440660252012378417669596912108637127036044977634382385990472429604619344` ~\n    `738746224291111527200379708978133071390303850450970292020176369525401803474` ~\n    `998613408923490273129022167907826017408385746675184651576154302536663744109` ~\n    `111018961065316024005076097634601030334948684412785487182572502394847587887` ~\n    `507385831062796361152176364659197432600147716058873232435238712648552844428` ~\n    `058885217631715287816333209463171932255049134340904981280717725999710525214` ~\n    `161541960645335744430049558161514565159449390036287489478108344584188898872` ~\n    `434914159748515512161981956372737022393466624249130107254611846175580584736` ~\n    `276213025837422102290580044755202968610542057651282410252208599309841499843` ~\n    `672251048622223867183370008181364966502137725166782667358559333222947265344` ~\n    `524195551978394625568228658697170315141077913403482061673401937141405425042` ~\n    `283546509102861986303306729882186190883772633960389974665467972016939172303` ~\n    `653623175801495207204880400522581834672918935651426160175413277309985678579` ~\n    `830872397214091472424064274864210953551447463312267310436493480881235642109` ~\n    `668498742629676513172286703948381906930297135997498416573231570483993847269` ~\n    `479552708416124555462530834668011570929850407031109157206202741051573633443` ~\n    `58105600`\n        ));\n    }\n\n    /**\n     * Implements assignment operators of the form `BigInt op= BigInt`.\n     */\n    BigInt opOpAssign(string op, T)(T y) pure nothrow\n        if ((op==\"+\" || op== \"-\" || op==\"*\" || op==\"|\" || op==\"&\" || op==\"^\" || op==\"/\" || op==\"%\")\n            && is (T: BigInt))\n    {\n        static if (op == \"+\")\n        {\n            data = BigUint.addOrSub(data, y.data, sign != y.sign, &sign);\n        }\n        else static if (op == \"-\")\n        {\n            data = BigUint.addOrSub(data, y.data, sign == y.sign, &sign);\n        }\n        else static if (op == \"*\")\n        {\n            data = BigUint.mul(data, y.data);\n            sign = isZero() ? false : sign ^ y.sign;\n        }\n        else static if (op == \"/\")\n        {\n            y.checkDivByZero();\n            if (!isZero())\n            {\n                data = BigUint.div(data, y.data);\n                sign = isZero() ? false : sign ^ y.sign;\n            }\n        }\n        else static if (op == \"%\")\n        {\n            y.checkDivByZero();\n            if (!isZero())\n            {\n                data = BigUint.mod(data, y.data);\n                // x%y always has the same sign as x.\n                if (isZero())\n                    sign = false;\n            }\n        }\n        else static if (op == \"|\" || op == \"&\" || op == \"^\")\n        {\n            data = BigUint.bitwiseOp!op(data, y.data, sign, y.sign, sign);\n        }\n        else static assert(0, \"BigInt \" ~ op[0..$-1] ~ \"= \" ~\n            T.stringof ~ \" is not supported\");\n        return this;\n    }\n\n    ///\n    @system unittest\n    {\n        // @system because opOpAssign is @system\n        auto x = BigInt(\"123\");\n        auto y = BigInt(\"321\");\n        x += y;\n        assert(x == BigInt(\"444\"));\n    }\n\n    /**\n     * Implements binary operators between `BigInt`s.\n     */\n    BigInt opBinary(string op, T)(T y) pure nothrow const\n        if ((op==\"+\" || op == \"*\" || op==\"-\" || op==\"|\" || op==\"&\" || op==\"^\" ||\n            op==\"/\" || op==\"%\")\n            && is (T: BigInt))\n    {\n        BigInt r = this;\n        return r.opOpAssign!(op)(y);\n    }\n\n    ///\n    @system unittest\n    {\n        auto x = BigInt(\"123\");\n        auto y = BigInt(\"456\");\n        BigInt z = x * y;\n        assert(z == BigInt(\"56088\"));\n    }\n\n    /**\n     * Implements binary operators between `BigInt`'s and built-in integers.\n     */\n    BigInt opBinary(string op, T)(T y) pure nothrow const\n        if ((op==\"+\" || op == \"*\" || op==\"-\" || op==\"/\" || op==\"|\" || op==\"&\" ||\n            op==\"^\"|| op==\">>\" || op==\"<<\" || op==\"^^\")\n            && isIntegral!T)\n    {\n        BigInt r = this;\n        return r.opOpAssign!(op)(y);\n    }\n\n    ///\n    @system unittest\n    {\n        auto x = BigInt(\"123\");\n        x *= 300;\n        assert(x == BigInt(\"36900\"));\n    }\n\n    /**\n        Implements a narrowing remainder operation with built-in integer types.\n\n        This binary operator returns a narrower, built-in integer type\n        where applicable, according to the following table.\n\n        $(TABLE ,\n        $(TR $(TD `BigInt`) $(TD $(CODE_PERCENT)) $(TD `uint`) $(TD $(RARR)) $(TD `long`))\n        $(TR $(TD `BigInt`) $(TD $(CODE_PERCENT)) $(TD `long`) $(TD $(RARR)) $(TD `long`))\n        $(TR $(TD `BigInt`) $(TD $(CODE_PERCENT)) $(TD `ulong`) $(TD $(RARR)) $(TD `BigInt`))\n        $(TR $(TD `BigInt`) $(TD $(CODE_PERCENT)) $(TD other type) $(TD $(RARR)) $(TD `int`))\n        )\n     */\n    auto opBinary(string op, T)(T y) pure nothrow const\n        if (op == \"%\" && isIntegral!T)\n    {\n        assert(y != 0);\n\n        // BigInt % uint => long\n        // BigInt % long => long\n        // BigInt % ulong => BigInt\n        // BigInt % other_type => int\n        static if (is(Unqual!T == long) || is(Unqual!T == ulong))\n        {\n            auto r = this % BigInt(y);\n\n            static if (is(Unqual!T == long))\n            {\n                return r.toLong();\n            }\n            else\n            {\n                // return as-is to avoid overflow\n                return r;\n            }\n        }\n        else\n        {\n            immutable uint u = absUnsign(y);\n            static if (is(Unqual!T == uint))\n               alias R = long;\n            else\n               alias R = int;\n            R rem = BigUint.modInt(data, u);\n            // x%y always has the same sign as x.\n            // This is not the same as mathematical mod.\n            return sign ? -rem : rem;\n        }\n    }\n\n    ///\n    @system unittest\n    {\n        auto  x  = BigInt(\"1_000_000_500\");\n        long  l  = 1_000_000L;\n        ulong ul = 2_000_000UL;\n        int   i  = 500_000;\n        short s  = 30_000;\n\n        assert(is(typeof(x % l)  == long)   && x % l  == 500L);\n        assert(is(typeof(x % ul) == BigInt) && x % ul == BigInt(500));\n        assert(is(typeof(x % i)  == int)    && x % i  == 500);\n        assert(is(typeof(x % s)  == int)    && x % s  == 10500);\n    }\n\n    /**\n        Implements operators with built-in integers on the left-hand side and\n        `BigInt` on the right-hand side.\n     */\n    BigInt opBinaryRight(string op, T)(T y) pure nothrow const\n        if ((op==\"+\" || op==\"*\" || op==\"|\" || op==\"&\" || op==\"^\") && isIntegral!T)\n    {\n        return opBinary!(op)(y);\n    }\n\n    ///\n    @system unittest\n    {\n        auto x = BigInt(\"100\");\n        BigInt y = 123 + x;\n        assert(y == BigInt(\"223\"));\n\n        BigInt z = 123 - x;\n        assert(z == BigInt(\"23\"));\n\n        // Dividing a built-in integer type by BigInt always results in\n        // something that fits in a built-in type, so the built-in type is\n        // returned, not BigInt.\n        assert(is(typeof(1000 / x) == int));\n        assert(1000 / x == 10);\n    }\n\n    //  BigInt = integer op BigInt\n    /// ditto\n    BigInt opBinaryRight(string op, T)(T y) pure nothrow const\n        if (op == \"-\" && isIntegral!T)\n    {\n        ulong u = absUnsign(y);\n        BigInt r;\n        static if (op == \"-\")\n        {\n            r.sign = sign;\n            r.data = BigUint.addOrSubInt(data, u, sign == (y<0), r.sign);\n            r.negate();\n        }\n        return r;\n    }\n\n    //  integer = integer op BigInt\n    /// ditto\n    T opBinaryRight(string op, T)(T x) pure nothrow const\n        if ((op==\"%\" || op==\"/\") && isIntegral!T)\n    {\n        checkDivByZero();\n\n        static if (op == \"%\")\n        {\n            // x%y always has the same sign as x.\n            if (data.ulongLength > 1)\n                return x;\n            immutable u = absUnsign(x);\n            immutable rem = u % data.peekUlong(0);\n            // x%y always has the same sign as x.\n            return cast(T)((x<0) ? -rem : rem);\n        }\n        else static if (op == \"/\")\n        {\n            if (data.ulongLength > 1)\n                return 0;\n            return cast(T)(x / data.peekUlong(0));\n        }\n    }\n\n    // const unary operations\n    /**\n        Implements `BigInt` unary operators.\n     */\n    BigInt opUnary(string op)() pure nothrow const if (op==\"+\" || op==\"-\" || op==\"~\")\n    {\n       static if (op==\"-\")\n       {\n            BigInt r = this;\n            r.negate();\n            return r;\n        }\n        else static if (op==\"~\")\n        {\n            return -(this+1);\n        }\n        else static if (op==\"+\")\n           return this;\n    }\n\n    // non-const unary operations\n    /// ditto\n    BigInt opUnary(string op)() pure nothrow if (op==\"++\" || op==\"--\")\n    {\n        static if (op==\"++\")\n        {\n            data = BigUint.addOrSubInt(data, 1UL, sign, sign);\n            return this;\n        }\n        else static if (op==\"--\")\n        {\n            data = BigUint.addOrSubInt(data, 1UL, !sign, sign);\n            return this;\n        }\n    }\n\n    ///\n    @system unittest\n    {\n        auto x = BigInt(\"1234\");\n        assert(-x == BigInt(\"-1234\"));\n\n        ++x;\n        assert(x == BigInt(\"1235\"));\n    }\n\n    /**\n        Implements `BigInt` equality test with other `BigInt`'s and built-in\n        integer types.\n     */\n    bool opEquals()(auto ref const BigInt y) const pure @nogc\n    {\n       return sign == y.sign && y.data == data;\n    }\n\n    /// ditto\n    bool opEquals(T)(T y) const pure nothrow @nogc if (isIntegral!T)\n    {\n        if (sign != (y<0))\n            return 0;\n        return data.opEquals(cast(ulong) absUnsign(y));\n    }\n\n    ///\n    @system unittest\n    {\n        auto x = BigInt(\"12345\");\n        auto y = BigInt(\"12340\");\n        int z = 12345;\n        int w = 54321;\n\n        assert(x == x);\n        assert(x != y);\n        assert(x == y + 5);\n        assert(x == z);\n        assert(x != w);\n    }\n\n    /**\n        Implements casting to `bool`.\n     */\n    T opCast(T:bool)() pure nothrow @nogc const\n    {\n        return !isZero();\n    }\n\n    ///\n    @system unittest\n    {\n        // Non-zero values are regarded as true\n        auto x = BigInt(\"1\");\n        auto y = BigInt(\"10\");\n        assert(x);\n        assert(y);\n\n        // Zero value is regarded as false\n        auto z = BigInt(\"0\");\n        assert(!z);\n    }\n\n    /**\n        Implements casting to integer types.\n\n        Throws: $(REF ConvOverflowException, std,conv) if the number exceeds\n        the target type's range.\n     */\n    T opCast(T:ulong)() pure const\n    {\n        if (isUnsigned!T && sign)\n            { /* throw */ }\n        else\n        if (data.ulongLength == 1)\n        {\n            ulong l = data.peekUlong(0);\n            if (isUnsigned!T || !sign)\n            {\n                if (l <= T.max)\n                    return cast(T) l;\n            }\n            else\n            {\n                if (l <= ulong(T.max)+1)\n                    return cast(T)-long(l); // -long.min == long.min\n            }\n        }\n\n        import std.conv : ConvOverflowException;\n        import std.string : format;\n        throw new ConvOverflowException(\n            \"BigInt(%s) cannot be represented as a %s\"\n            .format(this.toDecimalString, T.stringof));\n    }\n\n    ///\n    @system unittest\n    {\n        import std.conv : to, ConvOverflowException;\n        import std.exception : assertThrown;\n\n        assert(BigInt(\"0\").to!int == 0);\n\n        assert(BigInt(\"0\").to!ubyte == 0);\n        assert(BigInt(\"255\").to!ubyte == 255);\n        assertThrown!ConvOverflowException(BigInt(\"256\").to!ubyte);\n        assertThrown!ConvOverflowException(BigInt(\"-1\").to!ubyte);\n    }\n\n    @system unittest\n    {\n        import std.conv : to, ConvOverflowException;\n        import std.exception : assertThrown;\n\n        assert(BigInt(\"-1\").to!byte == -1);\n        assert(BigInt(\"-128\").to!byte == -128);\n        assert(BigInt(\"127\").to!byte == 127);\n        assertThrown!ConvOverflowException(BigInt(\"-129\").to!byte);\n        assertThrown!ConvOverflowException(BigInt(\"128\").to!byte);\n\n        assert(BigInt(\"0\").to!uint == 0);\n        assert(BigInt(\"4294967295\").to!uint == uint.max);\n        assertThrown!ConvOverflowException(BigInt(\"4294967296\").to!uint);\n        assertThrown!ConvOverflowException(BigInt(\"-1\").to!uint);\n\n        assert(BigInt(\"-1\").to!int == -1);\n        assert(BigInt(\"-2147483648\").to!int == int.min);\n        assert(BigInt(\"2147483647\").to!int == int.max);\n        assertThrown!ConvOverflowException(BigInt(\"-2147483649\").to!int);\n        assertThrown!ConvOverflowException(BigInt(\"2147483648\").to!int);\n\n        assert(BigInt(\"0\").to!ulong == 0);\n        assert(BigInt(\"18446744073709551615\").to!ulong == ulong.max);\n        assertThrown!ConvOverflowException(BigInt(\"18446744073709551616\").to!ulong);\n        assertThrown!ConvOverflowException(BigInt(\"-1\").to!ulong);\n\n        assert(BigInt(\"-1\").to!long == -1);\n        assert(BigInt(\"-9223372036854775808\").to!long == long.min);\n        assert(BigInt(\"9223372036854775807\").to!long == long.max);\n        assertThrown!ConvOverflowException(BigInt(\"-9223372036854775809\").to!long);\n        assertThrown!ConvOverflowException(BigInt(\"9223372036854775808\").to!long);\n    }\n\n    /**\n        Implements casting to/from qualified `BigInt`'s.\n\n        Warning: Casting to/from `const` or `immutable` may break type\n        system guarantees. Use with care.\n     */\n    T opCast(T)() pure nothrow @nogc const\n    if (is(Unqual!T == BigInt))\n    {\n        return this;\n    }\n\n    ///\n    @system unittest\n    {\n        const(BigInt) x = BigInt(\"123\");\n        BigInt y = cast() x;    // cast away const\n        assert(y == x);\n    }\n\n    // Hack to make BigInt's typeinfo.compare work properly.\n    // Note that this must appear before the other opCmp overloads, otherwise\n    // DMD won't find it.\n    /**\n        Implements 3-way comparisons of `BigInt` with `BigInt` or `BigInt` with\n        built-in integers.\n     */\n    int opCmp(ref const BigInt y) pure nothrow @nogc const\n    {\n        // Simply redirect to the \"real\" opCmp implementation.\n        return this.opCmp!BigInt(y);\n    }\n\n    /// ditto\n    int opCmp(T)(T y) pure nothrow @nogc const if (isIntegral!T)\n    {\n        if (sign != (y<0) )\n            return sign ? -1 : 1;\n        int cmp = data.opCmp(cast(ulong) absUnsign(y));\n        return sign? -cmp: cmp;\n    }\n    /// ditto\n    int opCmp(T:BigInt)(const T y) pure nothrow @nogc const\n    {\n        if (sign != y.sign)\n            return sign ? -1 : 1;\n        immutable cmp = data.opCmp(y.data);\n        return sign? -cmp: cmp;\n    }\n\n    ///\n    @system unittest\n    {\n        auto x = BigInt(\"100\");\n        auto y = BigInt(\"10\");\n        int z = 50;\n        const int w = 200;\n\n        assert(y < x);\n        assert(x > z);\n        assert(z > y);\n        assert(x < w);\n    }\n\n    /**\n        Returns: The value of this `BigInt` as a `long`, or `long.max`/`long.min`\n        if outside the representable range.\n     */\n    long toLong() @safe pure nothrow const @nogc\n    {\n        return (sign ? -1 : 1) *\n          (data.ulongLength == 1  && (data.peekUlong(0) <= sign+cast(ulong)(long.max)) // 1+long.max = |long.min|\n          ? cast(long)(data.peekUlong(0))\n          : long.max);\n    }\n\n    ///\n    @system unittest\n    {\n        auto b = BigInt(\"12345\");\n        long l = b.toLong();\n        assert(l == 12345);\n    }\n\n    /**\n        Returns: The value of this `BigInt` as an `int`, or `int.max`/`int.min` if outside\n        the representable range.\n     */\n    int toInt() @safe pure nothrow @nogc const\n    {\n        return (sign ? -1 : 1) *\n          (data.uintLength == 1  && (data.peekUint(0) <= sign+cast(uint)(int.max)) // 1+int.max = |int.min|\n          ? cast(int)(data.peekUint(0))\n          : int.max);\n    }\n\n    ///\n    @system unittest\n    {\n        auto big = BigInt(\"5_000_000\");\n        auto i = big.toInt();\n        assert(i == 5_000_000);\n\n        // Numbers that are too big to fit into an int will be clamped to int.max.\n        auto tooBig = BigInt(\"5_000_000_000\");\n        i = tooBig.toInt();\n        assert(i == int.max);\n    }\n\n    /// Number of significant `uint`s which are used in storing this number.\n    /// The absolute value of this `BigInt` is always &lt; 2$(SUPERSCRIPT 32*uintLength)\n    @property size_t uintLength() @safe pure nothrow @nogc const\n    {\n        return data.uintLength;\n    }\n\n    /// Number of significant `ulong`s which are used in storing this number.\n    /// The absolute value of this `BigInt` is always &lt; 2$(SUPERSCRIPT 64*ulongLength)\n    @property size_t ulongLength() @safe pure nothrow @nogc const\n    {\n        return data.ulongLength;\n    }\n\n    /** Convert the `BigInt` to `string`, passing it to the given sink.\n     *\n     * Params:\n     *  sink = A delegate for accepting possibly piecewise segments of the\n     *      formatted string.\n     *  formatString = A format string specifying the output format.\n     *\n     * $(TABLE  Available output formats:,\n     * $(TR $(TD \"d\") $(TD  Decimal))\n     * $(TR $(TD \"o\") $(TD  Octal))\n     * $(TR $(TD \"x\") $(TD  Hexadecimal, lower case))\n     * $(TR $(TD \"X\") $(TD  Hexadecimal, upper case))\n     * $(TR $(TD \"s\") $(TD  Default formatting (same as \"d\") ))\n     * $(TR $(TD null) $(TD Default formatting (same as \"d\") ))\n     * )\n     */\n    void toString(scope void delegate(const (char)[]) sink, string formatString) const\n    {\n        auto f = FormatSpec!char(formatString);\n        f.writeUpToNextSpec(sink);\n        toString(sink, f);\n    }\n\n    /// ditto\n    void toString(scope void delegate(const(char)[]) sink, const ref FormatSpec!char f) const\n    {\n        immutable hex = (f.spec == 'x' || f.spec == 'X');\n        if (!(f.spec == 's' || f.spec == 'd' || f.spec =='o' || hex))\n            throw new FormatException(\"Format specifier not understood: %\" ~ f.spec);\n\n        char[] buff;\n        if (f.spec == 'X')\n        {\n            buff = data.toHexString(0, '_', 0, f.flZero ? '0' : ' ', LetterCase.upper);\n        }\n        else if (f.spec == 'x')\n        {\n            buff = data.toHexString(0, '_', 0, f.flZero ? '0' : ' ', LetterCase.lower);\n        }\n        else if (f.spec == 'o')\n        {\n            buff = data.toOctalString();\n        }\n        else\n        {\n            buff = data.toDecimalString(0);\n        }\n        assert(buff.length > 0);\n\n        char signChar = isNegative() ? '-' : 0;\n        auto minw = buff.length + (signChar ? 1 : 0);\n\n        if (!hex && !signChar && (f.width == 0 || minw < f.width))\n        {\n            if (f.flPlus)\n            {\n                signChar = '+';\n                ++minw;\n            }\n            else if (f.flSpace)\n            {\n                signChar = ' ';\n                ++minw;\n            }\n        }\n\n        immutable maxw = minw < f.width ? f.width : minw;\n        immutable difw = maxw - minw;\n\n        if (!f.flDash && !f.flZero)\n            foreach (i; 0 .. difw)\n                sink(\" \");\n\n        if (signChar)\n            sink((&signChar)[0 .. 1]);\n\n        if (!f.flDash && f.flZero)\n            foreach (i; 0 .. difw)\n                sink(\"0\");\n\n        sink(buff);\n\n        if (f.flDash)\n            foreach (i; 0 .. difw)\n                sink(\" \");\n    }\n\n    /**\n        `toString` is rarely directly invoked; the usual way of using it is via\n        $(REF format, std, format):\n     */\n    @system unittest\n    {\n        import std.format : format;\n\n        auto x = BigInt(\"1_000_000\");\n        x *= 12345;\n\n        assert(format(\"%d\", x) == \"12345000000\");\n        assert(format(\"%x\", x) == \"2_dfd1c040\");\n        assert(format(\"%X\", x) == \"2_DFD1C040\");\n        assert(format(\"%o\", x) == \"133764340100\");\n    }\n\n    // Implement toHash so that BigInt works properly as an AA key.\n    /**\n        Returns: A unique hash of the `BigInt`'s value suitable for use in a hash\n        table.\n     */\n    size_t toHash() const @safe nothrow\n    {\n        return data.toHash() + sign;\n    }\n\n    /**\n        `toHash` is rarely directly invoked; it is implicitly used when\n        BigInt is used as the key of an associative array.\n     */\n    @safe unittest\n    {\n        string[BigInt] aa;\n        aa[BigInt(123)] = \"abc\";\n        aa[BigInt(456)] = \"def\";\n\n        assert(aa[BigInt(123)] == \"abc\");\n        assert(aa[BigInt(456)] == \"def\");\n    }\n\n    /**\n     * Gets the nth number in the underlying representation that makes up the whole\n     * `BigInt`.\n     *\n     * Params:\n     *     T = the type to view the underlying representation as\n     *     n = The nth number to retrieve. Must be less than $(LREF ulongLength) or\n     *     $(LREF uintLength) with respect to `T`.\n     * Returns:\n     *     The nth `ulong` in the representation of this `BigInt`.\n     */\n    T getDigit(T = ulong)(size_t n) const\n    if (is(T == ulong) || is(T == uint))\n    {\n        static if (is(T == ulong))\n        {\n            assert(n < ulongLength(), \"getDigit index out of bounds\");\n            return data.peekUlong(n);\n        }\n        else\n        {\n            assert(n < uintLength(), \"getDigit index out of bounds\");\n            return data.peekUint(n);\n        }\n    }\n\n    ///\n    @system pure unittest\n    {\n        auto a = BigInt(\"1000\");\n        assert(a.ulongLength() == 1);\n        assert(a.getDigit(0) == 1000);\n\n        assert(a.uintLength() == 1);\n        assert(a.getDigit!uint(0) == 1000);\n\n        auto b = BigInt(\"2_000_000_000_000_000_000_000_000_000\");\n        assert(b.ulongLength() == 2);\n        assert(b.getDigit(0) == 4584946418820579328);\n        assert(b.getDigit(1) == 108420217);\n\n        assert(b.uintLength() == 3);\n        assert(b.getDigit!uint(0) == 3489660928);\n        assert(b.getDigit!uint(1) == 1067516025);\n        assert(b.getDigit!uint(2) == 108420217);\n    }\n\nprivate:\n    void negate() @safe pure nothrow @nogc\n    {\n        if (!data.isZero())\n            sign = !sign;\n    }\n    bool isZero() pure const nothrow @nogc @safe\n    {\n        return data.isZero();\n    }\n    bool isNegative() pure const nothrow @nogc @safe\n    {\n        return sign;\n    }\n\n    // Generate a runtime error if division by zero occurs\n    void checkDivByZero() pure const nothrow @safe\n    {\n        if (isZero())\n            throw new Error(\"BigInt division by zero\");\n    }\n}\n\n///\n@system unittest\n{\n    BigInt a = \"9588669891916142\";\n    BigInt b = \"7452469135154800\";\n    auto c = a * b;\n    assert(c == BigInt(\"71459266416693160362545788781600\"));\n    auto d = b * a;\n    assert(d == BigInt(\"71459266416693160362545788781600\"));\n    assert(d == c);\n    d = c * BigInt(\"794628672112\");\n    assert(d == BigInt(\"56783581982794522489042432639320434378739200\"));\n    auto e = c + d;\n    assert(e == BigInt(\"56783581982865981755459125799682980167520800\"));\n    auto f = d + c;\n    assert(f == e);\n    auto g = f - c;\n    assert(g == d);\n    g = f - d;\n    assert(g == c);\n    e = 12345678;\n    g = c + e;\n    auto h = g / b;\n    auto i = g % b;\n    assert(h == a);\n    assert(i == e);\n    BigInt j = \"-0x9A56_57f4_7B83_AB78\";\n    BigInt k = j;\n    j ^^= 11;\n    assert(k ^^ 11 == j);\n}\n\n/**\nParams:\n    x = The `BigInt` to convert to a decimal `string`.\n\nReturns:\n    A `string` that represents the `BigInt` as a decimal number.\n\n*/\nstring toDecimalString(const(BigInt) x) pure nothrow\n{\n    auto buff = x.data.toDecimalString(x.isNegative ? 1 : 0);\n    if (x.isNegative)\n        buff[0] = '-';\n    return buff;\n}\n\n///\n@system pure unittest\n{\n    auto x = BigInt(\"123\");\n    x *= 1000;\n    x += 456;\n\n    auto xstr = x.toDecimalString();\n    assert(xstr == \"123456\");\n}\n\n/**\nParams:\n    x = The `BigInt` to convert to a hexadecimal `string`.\n\nReturns:\n    A `string` that represents the `BigInt` as a hexadecimal (base 16)\n    number in upper case.\n\n*/\nstring toHex(const(BigInt) x)\n{\n    string outbuff=\"\";\n    void sink(const(char)[] s) { outbuff ~= s; }\n    x.toString(&sink, \"%X\");\n    return outbuff;\n}\n\n///\n@system unittest\n{\n    auto x = BigInt(\"123\");\n    x *= 1000;\n    x += 456;\n\n    auto xstr = x.toHex();\n    assert(xstr == \"1E240\");\n}\n\n/** Returns the absolute value of x converted to the corresponding unsigned\ntype.\n\nParams:\n    x = The integral value to return the absolute value of.\n\nReturns:\n    The absolute value of x.\n\n*/\nUnsigned!T absUnsign(T)(T x)\nif (isIntegral!T)\n{\n    static if (isSigned!T)\n    {\n        import std.conv : unsigned;\n        /* This returns the correct result even when x = T.min\n         * on two's complement machines because unsigned(T.min) = |T.min|\n         * even though -T.min = T.min.\n         */\n        return unsigned((x < 0) ? cast(T)(0-x) : x);\n    }\n    else\n    {\n        return x;\n    }\n}\n\n///\nnothrow pure @system\nunittest\n{\n    assert((-1).absUnsign == 1);\n    assert(1.absUnsign == 1);\n}\n\nnothrow pure @system\nunittest\n{\n    BigInt a, b;\n    a = 1;\n    b = 2;\n    auto c = a + b;\n    assert(c == 3);\n}\n\nnothrow pure @system\nunittest\n{\n    long a;\n    BigInt b;\n    auto c = a + b;\n    assert(c == 0);\n    auto d = b + a;\n    assert(d == 0);\n}\n\nnothrow pure @system\nunittest\n{\n    BigInt x = 1, y = 2;\n    assert(x <  y);\n    assert(x <= y);\n    assert(y >= x);\n    assert(y >  x);\n    assert(x != y);\n\n    long r1 = x.toLong;\n    assert(r1 == 1);\n\n    BigInt r2 = 10 % x;\n    assert(r2 == 0);\n\n    BigInt r3 = 10 / y;\n    assert(r3 == 5);\n\n    BigInt[] arr = [BigInt(1)];\n    auto incr = arr[0]++;\n    assert(arr == [BigInt(2)]);\n    assert(incr == BigInt(1));\n}\n\n@system unittest\n{\n    // Radix conversion\n    assert( toDecimalString(BigInt(\"-1_234_567_890_123_456_789\"))\n        == \"-1234567890123456789\");\n    assert( toHex(BigInt(\"0x1234567890123456789\")) == \"123_45678901_23456789\");\n    assert( toHex(BigInt(\"0x00000000000000000000000000000000000A234567890123456789\"))\n        == \"A23_45678901_23456789\");\n    assert( toHex(BigInt(\"0x000_00_000000_000_000_000000000000_000000_\")) == \"0\");\n\n    assert(BigInt(-0x12345678).toInt() == -0x12345678);\n    assert(BigInt(-0x12345678).toLong() == -0x12345678);\n    assert(BigInt(0x1234_5678_9ABC_5A5AL).ulongLength == 1);\n    assert(BigInt(0x1234_5678_9ABC_5A5AL).toLong() == 0x1234_5678_9ABC_5A5AL);\n    assert(BigInt(-0x1234_5678_9ABC_5A5AL).toLong() == -0x1234_5678_9ABC_5A5AL);\n    assert(BigInt(0xF234_5678_9ABC_5A5AL).toLong() == long.max);\n    assert(BigInt(-0x123456789ABCL).toInt() == -int.max);\n    char[] s1 = \"123\".dup; // bug 8164\n    assert(BigInt(s1) == 123);\n    char[] s2 = \"0xABC\".dup;\n    assert(BigInt(s2) == 2748);\n\n    assert((BigInt(-2) + BigInt(1)) == BigInt(-1));\n    BigInt a = ulong.max - 5;\n    auto b = -long.max % a;\n    assert( b == -long.max % (ulong.max - 5));\n    b = long.max / a;\n    assert( b == long.max /(ulong.max - 5));\n    assert(BigInt(1) - 1 == 0);\n    assert((-4) % BigInt(5) == -4); // bug 5928\n    assert(BigInt(-4) % BigInt(5) == -4);\n    assert(BigInt(2)/BigInt(-3) == BigInt(0)); // bug 8022\n    assert(BigInt(\"-1\") > long.min); // bug 9548\n\n    assert(toDecimalString(BigInt(\"0000000000000000000000000000000000000000001234567\"))\n        == \"1234567\");\n}\n\n@system unittest // Minimum signed value bug tests.\n{\n    assert(BigInt(\"-0x8000000000000000\") == BigInt(long.min));\n    assert(BigInt(\"-0x8000000000000000\")+1 > BigInt(long.min));\n    assert(BigInt(\"-0x80000000\") == BigInt(int.min));\n    assert(BigInt(\"-0x80000000\")+1 > BigInt(int.min));\n    assert(BigInt(long.min).toLong() == long.min); // lossy toLong bug for long.min\n    assert(BigInt(int.min).toInt() == int.min); // lossy toInt bug for int.min\n    assert(BigInt(long.min).ulongLength == 1);\n    assert(BigInt(int.min).uintLength == 1); // cast/sign extend bug in opAssign\n    BigInt a;\n    a += int.min;\n    assert(a == BigInt(int.min));\n    a = int.min - BigInt(int.min);\n    assert(a == 0);\n    a = int.min;\n    assert(a == BigInt(int.min));\n    assert(int.min % (BigInt(int.min)-1) == int.min);\n    assert((BigInt(int.min)-1)%int.min == -1);\n}\n\n@system unittest // Recursive division, bug 5568\n{\n    enum Z = 4843;\n    BigInt m = (BigInt(1) << (Z*8) ) - 1;\n    m -= (BigInt(1) << (Z*6)) - 1;\n    BigInt oldm = m;\n\n    BigInt a = (BigInt(1) << (Z*4) )-1;\n    BigInt b = m % a;\n    m /= a;\n    m *= a;\n    assert( m + b == oldm);\n\n    m = (BigInt(1) << (4846 + 4843) ) - 1;\n    a = (BigInt(1) << 4846 ) - 1;\n    b = (BigInt(1) << (4846*2 + 4843)) - 1;\n    BigInt c = (BigInt(1) << (4846*2 + 4843*2)) - 1;\n    BigInt w =  c - b + a;\n    assert(w % m == 0);\n\n    // Bug 6819. ^^\n    BigInt z1 = BigInt(10)^^64;\n    BigInt w1 = BigInt(10)^^128;\n    assert(z1^^2 == w1);\n    BigInt z2 = BigInt(1)<<64;\n    BigInt w2 = BigInt(1)<<128;\n    assert(z2^^2 == w2);\n    // Bug 7993\n    BigInt n7793 = 10;\n    assert( n7793 / 1 == 10);\n    // Bug 7973\n    auto a7973 = 10_000_000_000_000_000;\n    const c7973 = 10_000_000_000_000_000;\n    immutable i7973 = 10_000_000_000_000_000;\n    BigInt v7973 = 2551700137;\n    v7973 %= a7973;\n    assert(v7973 == 2551700137);\n    v7973 %= c7973;\n    assert(v7973 == 2551700137);\n    v7973 %= i7973;\n    assert(v7973 == 2551700137);\n    // 8165\n    BigInt[2] a8165;\n    a8165[0] = a8165[1] = 1;\n}\n\n@system unittest\n{\n    import std.array;\n    import std.format;\n\n    immutable string[][] table = [\n    /*  fmt,        +10     -10 */\n        [\"%d\",      \"10\",   \"-10\"],\n        [\"%+d\",     \"+10\",  \"-10\"],\n        [\"%-d\",     \"10\",   \"-10\"],\n        [\"%+-d\",    \"+10\",  \"-10\"],\n\n        [\"%4d\",     \"  10\", \" -10\"],\n        [\"%+4d\",    \" +10\", \" -10\"],\n        [\"%-4d\",    \"10  \", \"-10 \"],\n        [\"%+-4d\",   \"+10 \", \"-10 \"],\n\n        [\"%04d\",    \"0010\", \"-010\"],\n        [\"%+04d\",   \"+010\", \"-010\"],\n        [\"%-04d\",   \"10  \", \"-10 \"],\n        [\"%+-04d\",  \"+10 \", \"-10 \"],\n\n        [\"% 04d\",   \" 010\", \"-010\"],\n        [\"%+ 04d\",  \"+010\", \"-010\"],\n        [\"%- 04d\",  \" 10 \", \"-10 \"],\n        [\"%+- 04d\", \"+10 \", \"-10 \"],\n    ];\n\n    auto w1 = appender!(char[])();\n    auto w2 = appender!(char[])();\n\n    foreach (entry; table)\n    {\n        immutable fmt = entry[0];\n\n        formattedWrite(w1, fmt, BigInt(10));\n        formattedWrite(w2, fmt, 10);\n        assert(w1.data == w2.data);\n        assert(w1.data == entry[1]);\n        w1.clear();\n        w2.clear();\n\n        formattedWrite(w1, fmt, BigInt(-10));\n        formattedWrite(w2, fmt, -10);\n        assert(w1.data == w2.data);\n        assert(w1.data == entry[2]);\n        w1.clear();\n        w2.clear();\n    }\n}\n\n@system unittest\n{\n    import std.array;\n    import std.format;\n\n    immutable string[][] table = [\n    /*  fmt,        +10     -10 */\n        [\"%x\",      \"a\",    \"-a\"],\n        [\"%+x\",     \"a\",    \"-a\"],\n        [\"%-x\",     \"a\",    \"-a\"],\n        [\"%+-x\",    \"a\",    \"-a\"],\n\n        [\"%4x\",     \"   a\", \"  -a\"],\n        [\"%+4x\",    \"   a\", \"  -a\"],\n        [\"%-4x\",    \"a   \", \"-a  \"],\n        [\"%+-4x\",   \"a   \", \"-a  \"],\n\n        [\"%04x\",    \"000a\", \"-00a\"],\n        [\"%+04x\",   \"000a\", \"-00a\"],\n        [\"%-04x\",   \"a   \", \"-a  \"],\n        [\"%+-04x\",  \"a   \", \"-a  \"],\n\n        [\"% 04x\",   \"000a\", \"-00a\"],\n        [\"%+ 04x\",  \"000a\", \"-00a\"],\n        [\"%- 04x\",  \"a   \", \"-a  \"],\n        [\"%+- 04x\", \"a   \", \"-a  \"],\n    ];\n\n    auto w1 = appender!(char[])();\n    auto w2 = appender!(char[])();\n\n    foreach (entry; table)\n    {\n        immutable fmt = entry[0];\n\n        formattedWrite(w1, fmt, BigInt(10));\n        formattedWrite(w2, fmt, 10);\n        assert(w1.data == w2.data);     // Equal only positive BigInt\n        assert(w1.data == entry[1]);\n        w1.clear();\n        w2.clear();\n\n        formattedWrite(w1, fmt, BigInt(-10));\n        //formattedWrite(w2, fmt, -10);\n        //assert(w1.data == w2.data);\n        assert(w1.data == entry[2]);\n        w1.clear();\n        //w2.clear();\n    }\n}\n\n@system unittest\n{\n    import std.array;\n    import std.format;\n\n    immutable string[][] table = [\n    /*  fmt,        +10     -10 */\n        [\"%X\",      \"A\",    \"-A\"],\n        [\"%+X\",     \"A\",    \"-A\"],\n        [\"%-X\",     \"A\",    \"-A\"],\n        [\"%+-X\",    \"A\",    \"-A\"],\n\n        [\"%4X\",     \"   A\", \"  -A\"],\n        [\"%+4X\",    \"   A\", \"  -A\"],\n        [\"%-4X\",    \"A   \", \"-A  \"],\n        [\"%+-4X\",   \"A   \", \"-A  \"],\n\n        [\"%04X\",    \"000A\", \"-00A\"],\n        [\"%+04X\",   \"000A\", \"-00A\"],\n        [\"%-04X\",   \"A   \", \"-A  \"],\n        [\"%+-04X\",  \"A   \", \"-A  \"],\n\n        [\"% 04X\",   \"000A\", \"-00A\"],\n        [\"%+ 04X\",  \"000A\", \"-00A\"],\n        [\"%- 04X\",  \"A   \", \"-A  \"],\n        [\"%+- 04X\", \"A   \", \"-A  \"],\n    ];\n\n    auto w1 = appender!(char[])();\n    auto w2 = appender!(char[])();\n\n    foreach (entry; table)\n    {\n        immutable fmt = entry[0];\n\n        formattedWrite(w1, fmt, BigInt(10));\n        formattedWrite(w2, fmt, 10);\n        assert(w1.data == w2.data);     // Equal only positive BigInt\n        assert(w1.data == entry[1]);\n        w1.clear();\n        w2.clear();\n\n        formattedWrite(w1, fmt, BigInt(-10));\n        //formattedWrite(w2, fmt, -10);\n        //assert(w1.data == w2.data);\n        assert(w1.data == entry[2]);\n        w1.clear();\n        //w2.clear();\n    }\n}\n\n// 6448\n@system unittest\n{\n    import std.array;\n    import std.format;\n\n    auto w1 = appender!string();\n    auto w2 = appender!string();\n\n    int x = 100;\n    formattedWrite(w1, \"%010d\", x);\n    BigInt bx = x;\n    formattedWrite(w2, \"%010d\", bx);\n    assert(w1.data == w2.data);\n    //8011\n    BigInt y = -3;\n    ++y;\n    assert(y.toLong() == -2);\n    y = 1;\n    --y;\n    assert(y.toLong() == 0);\n    --y;\n    assert(y.toLong() == -1);\n    --y;\n    assert(y.toLong() == -2);\n}\n\n@safe unittest\n{\n    import std.math : abs;\n    auto r = abs(BigInt(-1000)); // 6486\n    assert(r == 1000);\n\n    auto r2 = abs(const(BigInt)(-500)); // 11188\n    assert(r2 == 500);\n    auto r3 = abs(immutable(BigInt)(-733)); // 11188\n    assert(r3 == 733);\n\n    // opCast!bool\n    BigInt one = 1, zero;\n    assert(one && !zero);\n}\n\n@system unittest // 6850\n{\n    pure long pureTest() {\n        BigInt a = 1;\n        BigInt b = 1336;\n        a += b;\n        return a.toLong();\n    }\n\n    assert(pureTest() == 1337);\n}\n\n@system unittest // 8435 & 10118\n{\n    auto i = BigInt(100);\n    auto j = BigInt(100);\n\n    // Two separate BigInt instances representing same value should have same\n    // hash.\n    assert(typeid(i).getHash(&i) == typeid(j).getHash(&j));\n    assert(typeid(i).compare(&i, &j) == 0);\n\n    // BigInt AA keys should behave consistently.\n    int[BigInt] aa;\n    aa[BigInt(123)] = 123;\n    assert(BigInt(123) in aa);\n\n    aa[BigInt(123)] = 321;\n    assert(aa[BigInt(123)] == 321);\n\n    auto keys = aa.byKey;\n    assert(keys.front == BigInt(123));\n    keys.popFront();\n    assert(keys.empty);\n}\n\n@system unittest // 11148\n{\n    void foo(BigInt) {}\n    const BigInt cbi = 3;\n    immutable BigInt ibi = 3;\n\n    foo(cbi);\n    foo(ibi);\n\n    import std.conv : to;\n    import std.meta : AliasSeq;\n\n    static foreach (T1; AliasSeq!(BigInt, const(BigInt), immutable(BigInt)))\n    {\n        static foreach (T2; AliasSeq!(BigInt, const(BigInt), immutable(BigInt)))\n        {{\n            T1 t1 = 2;\n            T2 t2 = t1;\n\n            T2 t2_1 = to!T2(t1);\n            T2 t2_2 = cast(T2) t1;\n\n            assert(t2 == t1);\n            assert(t2 == 2);\n\n            assert(t2_1 == t1);\n            assert(t2_1 == 2);\n\n            assert(t2_2 == t1);\n            assert(t2_2 == 2);\n        }}\n    }\n\n    BigInt n = 2;\n    n *= 2;\n    assert(n == 4);\n}\n\n@safe unittest // 8167\n{\n    BigInt a = BigInt(3);\n    BigInt b = BigInt(a);\n    assert(b == 3);\n}\n\n@safe unittest // 9061\n{\n    long l1 = 0x12345678_90ABCDEF;\n    long l2 = 0xFEDCBA09_87654321;\n    long l3 = l1 | l2;\n    long l4 = l1 & l2;\n    long l5 = l1 ^ l2;\n\n    BigInt b1 = l1;\n    BigInt b2 = l2;\n    BigInt b3 = b1 | b2;\n    BigInt b4 = b1 & b2;\n    BigInt b5 = b1 ^ b2;\n\n    assert(l3 == b3);\n    assert(l4 == b4);\n    assert(l5 == b5);\n}\n\n@system unittest // 11600\n{\n    import std.conv;\n    import std.exception : assertThrown;\n\n    // Original bug report\n    assertThrown!ConvException(to!BigInt(\"avadakedavra\"));\n\n    // Digit string lookalikes that are actually invalid\n    assertThrown!ConvException(to!BigInt(\"0123hellothere\"));\n    assertThrown!ConvException(to!BigInt(\"-hihomarylowe\"));\n    assertThrown!ConvException(to!BigInt(\"__reallynow__\"));\n    assertThrown!ConvException(to!BigInt(\"-123four\"));\n}\n\n@safe unittest // 11583\n{\n    BigInt x = 0;\n    assert((x > 0) == false);\n}\n\n@system unittest // 13391\n{\n    BigInt x1 = \"123456789\";\n    BigInt x2 = \"123456789123456789\";\n    BigInt x3 = \"123456789123456789123456789\";\n\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))\n    {\n        assert((x1 * T.max) / T.max == x1);\n        assert((x2 * T.max) / T.max == x2);\n        assert((x3 * T.max) / T.max == x3);\n    }\n\n    assert(x1 / -123456789 == -1);\n    assert(x1 / 123456789U == 1);\n    assert(x1 / -123456789L == -1);\n    assert(x1 / 123456789UL == 1);\n    assert(x2 / -123456789123456789L == -1);\n    assert(x2 / 123456789123456789UL == 1);\n\n    assert(x1 / uint.max == 0);\n    assert(x1 / ulong.max == 0);\n    assert(x2 / ulong.max == 0);\n\n    x1 /= 123456789UL;\n    assert(x1 == 1);\n    x2 /= 123456789123456789UL;\n    assert(x2 == 1);\n}\n\n@system unittest // 13963\n{\n    BigInt x = 1;\n    import std.meta : AliasSeq;\n    static foreach (Int; AliasSeq!(byte, ubyte, short, ushort, int))\n    {\n        assert(is(typeof(x % Int(1)) == int));\n    }\n    assert(is(typeof(x % 1U) == long));\n    assert(is(typeof(x % 1L) == long));\n    assert(is(typeof(x % 1UL) == BigInt));\n\n    auto x0 = BigInt(uint.max - 1);\n    auto x1 = BigInt(8);\n    assert(x1 / x == x1);\n    auto x2 = -BigInt(long.min) + 1;\n\n    // uint\n    assert( x0 % uint.max ==  x0 % BigInt(uint.max));\n    assert(-x0 % uint.max == -x0 % BigInt(uint.max));\n    assert( x0 % uint.max ==  long(uint.max - 1));\n    assert(-x0 % uint.max == -long(uint.max - 1));\n\n    // long\n    assert(x1 % 2L == 0L);\n    assert(-x1 % 2L == 0L);\n\n    assert(x1 % 3L == 2L);\n    assert(x1 % -3L == 2L);\n    assert(-x1 % 3L == -2L);\n    assert(-x1 % -3L == -2L);\n\n    assert(x1 % 11L == 8L);\n    assert(x1 % -11L == 8L);\n    assert(-x1 % 11L == -8L);\n    assert(-x1 % -11L == -8L);\n\n    // ulong\n    assert(x1 % 2UL == BigInt(0));\n    assert(-x1 % 2UL == BigInt(0));\n\n    assert(x1 % 3UL == BigInt(2));\n    assert(-x1 % 3UL == -BigInt(2));\n\n    assert(x1 % 11UL == BigInt(8));\n    assert(-x1 % 11UL == -BigInt(8));\n\n    assert(x2 % ulong.max == x2);\n    assert(-x2 % ulong.max == -x2);\n}\n\n@system unittest // 14124\n{\n    auto x = BigInt(-3);\n    x %= 3;\n    assert(!x.isNegative());\n    assert(x.isZero());\n\n    x = BigInt(-3);\n    x %= cast(ushort) 3;\n    assert(!x.isNegative());\n    assert(x.isZero());\n\n    x = BigInt(-3);\n    x %= 3L;\n    assert(!x.isNegative());\n    assert(x.isZero());\n\n    x = BigInt(3);\n    x %= -3;\n    assert(!x.isNegative());\n    assert(x.isZero());\n}\n\n// issue 15678\n@system unittest\n{\n    import std.exception : assertThrown;\n    assertThrown!ConvException(BigInt(\"\"));\n    assertThrown!ConvException(BigInt(\"0x1234BARF\"));\n    assertThrown!ConvException(BigInt(\"1234PUKE\"));\n}\n\n// Issue 6447\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota;\n\n    auto s = BigInt(1_000_000_000_000);\n    auto e = BigInt(1_000_000_000_003);\n    auto r = iota(s, e);\n    assert(r.equal([\n        BigInt(1_000_000_000_000),\n        BigInt(1_000_000_000_001),\n        BigInt(1_000_000_000_002)\n    ]));\n}\n\n// Issue 17330\n@system unittest\n{\n    auto b = immutable BigInt(\"123\");\n    assert(b == 123);\n}\n\n@system pure unittest // issue 14767\n{\n    static immutable a = BigInt(\"340282366920938463463374607431768211455\");\n    assert(a == BigInt(\"340282366920938463463374607431768211455\"));\n\n    BigInt plusTwo(in BigInt n)\n    {\n        return n + 2;\n    }\n\n    enum BigInt test1 = BigInt(123);\n    enum BigInt test2 = plusTwo(test1);\n    assert(test2 == 125);\n}\n\n/**\n * Finds the quotient and remainder for the given dividend and divisor in one operation.\n *\n * Params:\n *     dividend = the $(LREF BigInt) to divide\n *     divisor = the $(LREF BigInt) to divide the dividend by\n *     quotient = is set to the result of the division\n *     remainder = is set to the remainder of the division\n */\nvoid divMod(const BigInt dividend, const BigInt divisor, out BigInt quotient, out BigInt remainder) pure nothrow\n{\n    BigUint q, r;\n    BigUint.divMod(dividend.data, divisor.data, q, r);\n    quotient.sign = dividend.sign != divisor.sign;\n    quotient.data = q;\n    remainder.sign = dividend.sign;\n    remainder.data = r;\n}\n\n///\n@system pure nothrow unittest\n{\n    auto a = BigInt(123);\n    auto b = BigInt(25);\n    BigInt q, r;\n\n    divMod(a, b, q, r);\n\n    assert(q == 4);\n    assert(r == 23);\n    assert(q * b + r == a);\n}\n\n// Issue 18086\n@system pure nothrow unittest\n{\n    BigInt q = 1;\n    BigInt r = 1;\n    BigInt c = 1024;\n    BigInt d = 100;\n\n    divMod(c, d, q, r);\n    assert(q ==  10);\n    assert(r ==  24);\n    assert((q * d + r) == c);\n\n    divMod(c, -d, q, r);\n    assert(q == -10);\n    assert(r ==  24);\n    assert(q * -d + r == c);\n\n    divMod(-c, -d, q, r);\n    assert(q ==  10);\n    assert(r == -24);\n    assert(q * -d + r == -c);\n\n    divMod(-c, d, q, r);\n    assert(q == -10);\n    assert(r == -24);\n    assert(q * d + r == -c);\n}\n"
  },
  {
    "path": "libphobos/src/std/bitmanip.d",
    "content": "// Written in the D programming language.\n\n/**\nBit-level manipulation facilities.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Bit constructs) $(TD\n    $(LREF BitArray)\n    $(LREF bitfields)\n    $(LREF bitsSet)\n))\n$(TR $(TD Endianness conversion) $(TD\n    $(LREF bigEndianToNative)\n    $(LREF littleEndianToNative)\n    $(LREF nativeToBigEndian)\n    $(LREF nativeToLittleEndian)\n    $(LREF swapEndian)\n))\n$(TR $(TD Integral ranges) $(TD\n    $(LREF append)\n    $(LREF peek)\n    $(LREF read)\n    $(LREF write)\n))\n$(TR $(TD Floating-Point manipulation) $(TD\n    $(LREF DoubleRep)\n    $(LREF FloatRep)\n))\n$(TR $(TD Tagging) $(TD\n    $(LREF taggedClassRef)\n    $(LREF taggedPointer)\n))\n)\n\nCopyright: Copyright The D Language Foundation 2007 - 2011.\nLicense:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   $(HTTP digitalmars.com, Walter Bright),\n           $(HTTP erdani.org, Andrei Alexandrescu),\n           $(HTTP jmdavisprog.com, Jonathan M Davis),\n           Alex Rønne Petersen,\n           Damian Ziemba,\n           Amaury SECHET\nSource: $(PHOBOSSRC std/bitmanip.d)\n*/\n/*\n         Copyright The D Language Foundation 2007 - 2012.\nDistributed under the Boost Software License, Version 1.0.\n   (See accompanying file LICENSE_1_0.txt or copy at\n         http://www.boost.org/LICENSE_1_0.txt)\n*/\nmodule std.bitmanip;\n\nimport std.range.primitives;\npublic import std.system : Endian;\nimport std.traits;\n\nprivate string myToString(ulong n)\n{\n    import core.internal.string : UnsignedStringBuf, unsignedToTempString;\n    UnsignedStringBuf buf;\n    auto s = unsignedToTempString(n, buf);\n    return cast(string) s ~ (n > uint.max ? \"UL\" : \"U\");\n}\n\nprivate template createAccessors(\n    string store, T, string name, size_t len, size_t offset)\n{\n    static if (!name.length)\n    {\n        // No need to create any accessor\n        enum result = \"\";\n    }\n    else static if (len == 0)\n    {\n        // Fields of length 0 are always zero\n        enum result = \"enum \"~T.stringof~\" \"~name~\" = 0;\\n\";\n    }\n    else\n    {\n        enum ulong\n            maskAllElse = ((~0uL) >> (64 - len)) << offset,\n            signBitCheck = 1uL << (len - 1);\n\n        static if (T.min < 0)\n        {\n            enum long minVal = -(1uL << (len - 1));\n            enum ulong maxVal = (1uL << (len - 1)) - 1;\n            alias UT = Unsigned!(T);\n            enum UT extendSign = cast(UT)~((~0uL) >> (64 - len));\n        }\n        else\n        {\n            enum ulong minVal = 0;\n            enum ulong maxVal = (~0uL) >> (64 - len);\n            enum extendSign = 0;\n        }\n\n        static if (is(T == bool))\n        {\n            static assert(len == 1, \"`\" ~ name ~\n                    \"` definition problem: type `bool` is only allowed for single-bit fields\");\n            enum result =\n            // getter\n                \"@property bool \" ~ name ~ \"() @safe pure nothrow @nogc const { return \"\n                ~\"(\"~store~\" & \"~myToString(maskAllElse)~\") != 0;}\\n\"\n            // setter\n                ~\"@property void \" ~ name ~ \"(bool v) @safe pure nothrow @nogc { \"\n                ~\"if (v) \"~store~\" |= \"~myToString(maskAllElse)~\";\"\n                ~\"else \"~store~\" &= cast(typeof(\"~store~\"))(-1-cast(typeof(\"~store~\"))\"~myToString(maskAllElse)~\");}\\n\";\n        }\n        else\n        {\n            // getter\n            enum result = \"@property \"~T.stringof~\" \"~name~\"() @safe pure nothrow @nogc const { auto result = \"\n                ~\"(\"~store~\" & \"\n                ~ myToString(maskAllElse) ~ \") >>\"\n                ~ myToString(offset) ~ \";\"\n                ~ (T.min < 0\n                   ? \"if (result >= \" ~ myToString(signBitCheck)\n                   ~ \") result |= \" ~ myToString(extendSign) ~ \";\"\n                   : \"\")\n                ~ \" return cast(\"~T.stringof~\") result;}\\n\"\n            // setter\n                ~\"@property void \"~name~\"(\"~T.stringof~\" v) @safe pure nothrow @nogc { \"\n                ~\"assert(v >= \"~name~`_min, \"Value is smaller than the minimum value of bitfield '`~name~`'\"); `\n                ~\"assert(v <= \"~name~`_max, \"Value is greater than the maximum value of bitfield '`~name~`'\"); `\n                ~store~\" = cast(typeof(\"~store~\"))\"\n                ~\" ((\"~store~\" & (-1-cast(typeof(\"~store~\"))\"~myToString(maskAllElse)~\"))\"\n                ~\" | ((cast(typeof(\"~store~\")) v << \"~myToString(offset)~\")\"\n                ~\" & \"~myToString(maskAllElse)~\"));}\\n\"\n            // constants\n                ~\"enum \"~T.stringof~\" \"~name~\"_min = cast(\"~T.stringof~\")\"\n                ~myToString(minVal)~\"; \"\n                ~\" enum \"~T.stringof~\" \"~name~\"_max = cast(\"~T.stringof~\")\"\n                ~myToString(maxVal)~\"; \";\n        }\n    }\n}\n\nprivate template createStoreName(Ts...)\n{\n    static if (Ts.length < 2)\n        enum createStoreName = \"\";\n    else\n        enum createStoreName = \"_\" ~ Ts[1] ~ createStoreName!(Ts[3 .. $]);\n}\n\nprivate template createStorageAndFields(Ts...)\n{\n    enum Name = createStoreName!Ts;\n    enum Size = sizeOfBitField!Ts;\n    static if (Size == ubyte.sizeof * 8)\n        alias StoreType = ubyte;\n    else static if (Size == ushort.sizeof * 8)\n        alias StoreType = ushort;\n    else static if (Size == uint.sizeof * 8)\n        alias StoreType = uint;\n    else static if (Size == ulong.sizeof * 8)\n        alias StoreType = ulong;\n    else\n    {\n        static assert(false, \"Field widths must sum to 8, 16, 32, or 64\");\n        alias StoreType = ulong; // just to avoid another error msg\n    }\n    enum result\n        = \"private \" ~ StoreType.stringof ~ \" \" ~ Name ~ \";\"\n        ~ createFields!(Name, 0, Ts).result;\n}\n\nprivate template createFields(string store, size_t offset, Ts...)\n{\n    static if (Ts.length > 0)\n        enum result\n            = createAccessors!(store, Ts[0], Ts[1], Ts[2], offset).result\n            ~ createFields!(store, offset + Ts[2], Ts[3 .. $]).result;\n    else\n        enum result = \"\";\n}\n\nprivate ulong getBitsForAlign(ulong a)\n{\n    ulong bits = 0;\n    while ((a & 0x01) == 0)\n    {\n        bits++;\n        a >>= 1;\n    }\n\n    assert(a == 1, \"alignment is not a power of 2\");\n    return bits;\n}\n\nprivate template createReferenceAccessor(string store, T, ulong bits, string name)\n{\n    enum storage = \"private void* \" ~ store ~ \"_ptr;\\n\";\n    enum storage_accessor = \"@property ref size_t \" ~ store ~ \"() return @trusted pure nothrow @nogc const { \"\n        ~ \"return *cast(size_t*) &\" ~ store ~ \"_ptr;}\\n\"\n        ~ \"@property void \" ~ store ~ \"(size_t v) @trusted pure nothrow @nogc { \"\n        ~ \"\" ~ store ~ \"_ptr = cast(void*) v;}\\n\";\n\n    enum mask = (1UL << bits) - 1;\n    // getter\n    enum ref_accessor = \"@property \"~T.stringof~\" \"~name~\"() @trusted pure nothrow @nogc const { auto result = \"\n        ~ \"(\"~store~\" & \"~myToString(~mask)~\"); \"\n        ~ \"return cast(\"~T.stringof~\") cast(void*) result;}\\n\"\n    // setter\n        ~\"@property void \"~name~\"(\"~T.stringof~\" v) @trusted pure nothrow @nogc { \"\n        ~\"assert(((cast(typeof(\"~store~\")) cast(void*) v) & \"~myToString(mask)\n        ~`) == 0, \"Value not properly aligned for '`~name~`'\"); `\n        ~store~\" = cast(typeof(\"~store~\"))\"\n        ~\" ((\"~store~\" & (cast(typeof(\"~store~\")) \"~myToString(mask)~\"))\"\n        ~\" | ((cast(typeof(\"~store~\")) cast(void*) v) & (cast(typeof(\"~store~\")) \"~myToString(~mask)~\")));}\\n\";\n\n    enum result = storage ~ storage_accessor ~ ref_accessor;\n}\n\nprivate template sizeOfBitField(T...)\n{\n    static if (T.length < 2)\n        enum sizeOfBitField = 0;\n    else\n        enum sizeOfBitField = T[2] + sizeOfBitField!(T[3 .. $]);\n}\n\nprivate template createTaggedReference(T, ulong a, string name, Ts...)\n{\n    static assert(\n        sizeOfBitField!Ts <= getBitsForAlign(a),\n        \"Fields must fit in the bits know to be zero because of alignment.\"\n    );\n    enum StoreName = createStoreName!(T, name, 0, Ts);\n    enum result\n        = createReferenceAccessor!(StoreName, T, sizeOfBitField!Ts, name).result\n        ~ createFields!(StoreName, 0, Ts, size_t, \"\", T.sizeof * 8 - sizeOfBitField!Ts).result;\n}\n\n/**\nAllows creating bit fields inside $(D_PARAM struct)s and $(D_PARAM\nclass)es.\n\nThe type of a bit field can be any integral type or enumerated\ntype. The most efficient type to store in bitfields is $(D_PARAM\nbool), followed by unsigned types, followed by signed types.\n\nSee_Also: $(REF BitFlags, std,typecons)\n*/\n\ntemplate bitfields(T...)\n{\n    enum { bitfields = createStorageAndFields!T.result }\n}\n\n/**\nCreate a bitfield pack of eight bits, which fit in\none $(D_PARAM ubyte). The bitfields are allocated starting from the\nleast significant bit, i.e. x occupies the two least significant bits\nof the bitfields storage.\n*/\n@safe unittest\n{\n    struct A\n    {\n        int a;\n        mixin(bitfields!(\n            uint, \"x\",    2,\n            int,  \"y\",    3,\n            uint, \"z\",    2,\n            bool, \"flag\", 1));\n    }\n\n    A obj;\n    obj.x = 2;\n    obj.z = obj.x;\n\n    assert(obj.x == 2);\n    assert(obj.y == 0);\n    assert(obj.z == 2);\n}\n\n/**\nThe sum of all bit lengths in one $(D_PARAM bitfield) instantiation\nmust be exactly 8, 16, 32, or 64. If padding is needed, just allocate\none bitfield with an empty name.\n*/\n@safe unittest\n{\n    struct A\n    {\n        mixin(bitfields!(\n            bool, \"flag1\",    1,\n            bool, \"flag2\",    1,\n            uint, \"\",         6));\n    }\n\n}\n\n/// enums can be used too\n@safe unittest\n{\n    enum ABC { A, B, C }\n    struct EnumTest\n    {\n        mixin(bitfields!(\n                  ABC, \"x\", 2,\n                  bool, \"y\", 1,\n                  ubyte, \"z\", 5));\n    }\n}\n\n/**\nCreates a bitfield pack of eight bits, which fit in\none `ubyte`. The bitfields are allocated starting from the\nleast significant bit, i.e. x occupies the two least significant bits\nof the bitfields storage.\n*/\n@safe unittest\n{\n    struct A\n    {\n        int a;\n        mixin(bitfields!(\n            uint, \"x\",    2,\n            int,  \"y\",    3,\n            uint, \"z\",    2,\n            bool, \"flag\", 1));\n    }\n    A obj;\n    obj.x = 2;\n    obj.z = obj.x;\n\n    assert(obj.x == 2);\n    assert(obj.y == 0);\n    assert(obj.z == 2);\n    assert(obj.flag == false);\n}\n\n/// Add empty fields for padding to have a total bit length of 8, 16, 32, or 64\n@safe unittest\n{\n    struct A\n    {\n        mixin(bitfields!(\n            bool, \"flag1\",    1,\n            bool, \"flag2\",    1,\n            uint, \"\",         6));\n    }\n    A a;\n    assert(a.flag1 == 0);\n    a.flag1 = 1;\n    assert(a.flag1 == 1);\n    a.flag1 = 0;\n    assert(a.flag1 == 0);\n}\n\n/**\nThis string mixin generator allows one to create tagged pointers inside $(D_PARAM struct)s and $(D_PARAM class)es.\n\nA tagged pointer uses the bits known to be zero in a normal pointer or class reference to store extra information.\nFor example, a pointer to an integer must be 4-byte aligned, so there are 2 bits that are always known to be zero.\nOne can store a 2-bit integer there.\n\nThe example above creates a tagged pointer in the struct A. The pointer is of type\n`uint*` as specified by the first argument, and is named x, as specified by the second\nargument.\n\nFollowing arguments works the same way as `bitfield`'s. The bitfield must fit into the\nbits known to be zero because of the pointer alignment.\n*/\n\ntemplate taggedPointer(T : T*, string name, Ts...) {\n    enum taggedPointer = createTaggedReference!(T*, T.alignof, name, Ts).result;\n}\n\n///\n@safe unittest\n{\n    struct A\n    {\n        int a;\n        mixin(taggedPointer!(\n            uint*, \"x\",\n            bool, \"b1\", 1,\n            bool, \"b2\", 1));\n    }\n    A obj;\n    obj.x = new uint;\n    obj.b1 = true;\n    obj.b2 = false;\n}\n\n/**\nThis string mixin generator allows one to create tagged class reference inside $(D_PARAM struct)s and $(D_PARAM class)es.\n\nA tagged class reference uses the bits known to be zero in a normal class reference to store extra information.\nFor example, a pointer to an integer must be 4-byte aligned, so there are 2 bits that are always known to be zero.\nOne can store a 2-bit integer there.\n\nThe example above creates a tagged reference to an Object in the struct A. This expects the same parameters\nas `taggedPointer`, except the first argument which must be a class type instead of a pointer type.\n*/\n\ntemplate taggedClassRef(T, string name, Ts...)\nif (is(T == class))\n{\n    enum taggedClassRef = createTaggedReference!(T, 8, name, Ts).result;\n}\n\n///\n@safe unittest\n{\n    struct A\n    {\n        int a;\n        mixin(taggedClassRef!(\n            Object, \"o\",\n            uint, \"i\", 2));\n    }\n    A obj;\n    obj.o = new Object();\n    obj.i = 3;\n}\n\n@safe pure nothrow @nogc\nunittest\n{\n    // Degenerate bitfields (#8474 / #11160) tests mixed with range tests\n    struct Test1\n    {\n        mixin(bitfields!(uint, \"a\", 32,\n                        uint, \"b\", 4,\n                        uint, \"c\", 4,\n                        uint, \"d\", 8,\n                        uint, \"e\", 16,));\n\n        static assert(Test1.b_min == 0);\n        static assert(Test1.b_max == 15);\n    }\n\n    struct Test2\n    {\n        mixin(bitfields!(bool, \"a\", 0,\n                        ulong, \"b\", 64));\n\n        static assert(Test2.b_min == ulong.min);\n        static assert(Test2.b_max == ulong.max);\n    }\n\n    struct Test1b\n    {\n        mixin(bitfields!(bool, \"a\", 0,\n                        int, \"b\", 8));\n    }\n\n    struct Test2b\n    {\n        mixin(bitfields!(int, \"a\", 32,\n                        int, \"b\", 4,\n                        int, \"c\", 4,\n                        int, \"d\", 8,\n                        int, \"e\", 16,));\n\n        static assert(Test2b.b_min == -8);\n        static assert(Test2b.b_max == 7);\n    }\n\n    struct Test3b\n    {\n        mixin(bitfields!(bool, \"a\", 0,\n                        long, \"b\", 64));\n\n        static assert(Test3b.b_min == long.min);\n        static assert(Test3b.b_max == long.max);\n    }\n\n    struct Test4b\n    {\n        mixin(bitfields!(long, \"a\", 32,\n                        int, \"b\", 32));\n    }\n\n    // Sign extension tests\n    Test2b t2b;\n    Test4b t4b;\n    t2b.b = -5; assert(t2b.b == -5);\n    t2b.d = -5; assert(t2b.d == -5);\n    t2b.e = -5; assert(t2b.e == -5);\n    t4b.a = -5; assert(t4b.a == -5L);\n}\n\n@system unittest\n{\n    struct Test5\n    {\n        mixin(taggedPointer!(\n            int*, \"a\",\n            uint, \"b\", 2));\n    }\n\n    Test5 t5;\n    t5.a = null;\n    t5.b = 3;\n    assert(t5.a is null);\n    assert(t5.b == 3);\n\n    int myint = 42;\n    t5.a = &myint;\n    assert(t5.a is &myint);\n    assert(t5.b == 3);\n\n    struct Test6\n    {\n        mixin(taggedClassRef!(\n            Object, \"o\",\n            bool, \"b\", 1));\n    }\n\n    Test6 t6;\n    t6.o = null;\n    t6.b = false;\n    assert(t6.o is null);\n    assert(t6.b == false);\n\n    auto o = new Object();\n    t6.o = o;\n    t6.b = true;\n    assert(t6.o is o);\n    assert(t6.b == true);\n}\n\n@safe unittest\n{\n    static assert(!__traits(compiles,\n        taggedPointer!(\n            int*, \"a\",\n            uint, \"b\", 3)));\n\n    static assert(!__traits(compiles,\n        taggedClassRef!(\n            Object, \"a\",\n            uint, \"b\", 4)));\n\n    struct S {\n        mixin(taggedClassRef!(\n            Object, \"a\",\n            bool, \"b\", 1));\n    }\n\n    const S s;\n    void bar(S s) {}\n\n    static assert(!__traits(compiles, bar(s)));\n}\n\n@safe unittest\n{\n    // Bug #6686\n    union  S {\n        ulong bits = ulong.max;\n        mixin (bitfields!(\n            ulong, \"back\",  31,\n            ulong, \"front\", 33)\n        );\n    }\n    S num;\n\n    num.bits = ulong.max;\n    num.back = 1;\n    assert(num.bits == 0xFFFF_FFFF_8000_0001uL);\n}\n\n@safe unittest\n{\n    // Bug #5942\n    struct S\n    {\n        mixin(bitfields!(\n            int, \"a\" , 32,\n            int, \"b\" , 32\n        ));\n    }\n\n    S data;\n    data.b = 42;\n    data.a = 1;\n    assert(data.b == 42);\n}\n\n@safe unittest\n{\n    struct Test\n    {\n        mixin(bitfields!(bool, \"a\", 1,\n                         uint, \"b\", 3,\n                         short, \"c\", 4));\n    }\n\n    @safe void test() pure nothrow\n    {\n        Test t;\n\n        t.a = true;\n        t.b = 5;\n        t.c = 2;\n\n        assert(t.a);\n        assert(t.b == 5);\n        assert(t.c == 2);\n    }\n\n    test();\n}\n\n@safe unittest\n{\n    {\n        static struct Integrals {\n            bool checkExpectations(bool eb, int ei, short es) { return b == eb && i == ei && s == es; }\n\n            mixin(bitfields!(\n                      bool, \"b\", 1,\n                      uint, \"i\", 3,\n                      short, \"s\", 4));\n        }\n        Integrals i;\n        assert(i.checkExpectations(false, 0, 0));\n        i.b = true;\n        assert(i.checkExpectations(true, 0, 0));\n        i.i = 7;\n        assert(i.checkExpectations(true, 7, 0));\n        i.s = -8;\n        assert(i.checkExpectations(true, 7, -8));\n        i.s = 7;\n        assert(i.checkExpectations(true, 7, 7));\n    }\n\n    //Bug# 8876\n    {\n        struct MoreIntegrals {\n            bool checkExpectations(uint eu, ushort es, uint ei) { return u == eu && s == es && i == ei; }\n\n            mixin(bitfields!(\n                  uint, \"u\", 24,\n                  short, \"s\", 16,\n                  int, \"i\", 24));\n        }\n\n        MoreIntegrals i;\n        assert(i.checkExpectations(0, 0, 0));\n        i.s = 20;\n        assert(i.checkExpectations(0, 20, 0));\n        i.i = 72;\n        assert(i.checkExpectations(0, 20, 72));\n        i.u = 8;\n        assert(i.checkExpectations(8, 20, 72));\n        i.s = 7;\n        assert(i.checkExpectations(8, 7, 72));\n    }\n\n    enum A { True, False }\n    enum B { One, Two, Three, Four }\n    static struct Enums {\n        bool checkExpectations(A ea, B eb) { return a == ea && b == eb; }\n\n        mixin(bitfields!(\n                  A, \"a\", 1,\n                  B, \"b\", 2,\n                  uint, \"\", 5));\n    }\n    Enums e;\n    assert(e.checkExpectations(A.True, B.One));\n    e.a = A.False;\n    assert(e.checkExpectations(A.False, B.One));\n    e.b = B.Three;\n    assert(e.checkExpectations(A.False, B.Three));\n\n    static struct SingleMember {\n        bool checkExpectations(bool eb) { return b == eb; }\n\n        mixin(bitfields!(\n                  bool, \"b\", 1,\n                  uint, \"\", 7));\n    }\n    SingleMember f;\n    assert(f.checkExpectations(false));\n    f.b = true;\n    assert(f.checkExpectations(true));\n}\n\n// Issue 12477\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.algorithm.searching : canFind;\n    import std.bitmanip : bitfields;\n\n    static struct S\n    {\n        mixin(bitfields!(\n            uint, \"a\", 6,\n            int, \"b\", 2));\n    }\n\n    S s;\n\n    try { s.a = uint.max; assert(0); }\n    catch (AssertError ae)\n    { assert(ae.msg.canFind(\"Value is greater than the maximum value of bitfield 'a'\"), ae.msg); }\n\n    try { s.b = int.min;  assert(0); }\n    catch (AssertError ae)\n    { assert(ae.msg.canFind(\"Value is smaller than the minimum value of bitfield 'b'\"), ae.msg); }\n}\n\n/**\n   Allows manipulating the fraction, exponent, and sign parts of a\n   $(D_PARAM float) separately. The definition is:\n\n----\nstruct FloatRep\n{\n    union\n    {\n        float value;\n        mixin(bitfields!(\n                  uint,  \"fraction\", 23,\n                  ubyte, \"exponent\",  8,\n                  bool,  \"sign\",      1));\n    }\n    enum uint bias = 127, fractionBits = 23, exponentBits = 8, signBits = 1;\n}\n----\n*/\nstruct FloatRep\n{\n    union\n    {\n        float value;\n        mixin(bitfields!(\n                  uint,  \"fraction\", 23,\n                  ubyte, \"exponent\",  8,\n                  bool,  \"sign\",      1));\n    }\n    enum uint bias = 127, fractionBits = 23, exponentBits = 8, signBits = 1;\n}\n\n///\n@safe unittest\n{\n    FloatRep rep = {value: 0};\n    assert(rep.fraction == 0);\n    assert(rep.exponent == 0);\n    assert(!rep.sign);\n\n    rep.value = 42;\n    assert(rep.fraction == 2621440);\n    assert(rep.exponent == 132);\n    assert(!rep.sign);\n\n    rep.value = 10;\n    assert(rep.fraction == 2097152);\n    assert(rep.exponent == 130);\n}\n\n///\n@safe unittest\n{\n    FloatRep rep = {value: 1};\n    assert(rep.fraction == 0);\n    assert(rep.exponent == 127);\n    assert(!rep.sign);\n\n    rep.exponent = 126;\n    assert(rep.value == 0.5);\n\n    rep.exponent = 130;\n    assert(rep.value == 8);\n}\n\n///\n@safe unittest\n{\n    FloatRep rep = {value: 1};\n    rep.value = -0.5;\n    assert(rep.fraction == 0);\n    assert(rep.exponent == 126);\n    assert(rep.sign);\n\n    rep.value = -1. / 3;\n    assert(rep.fraction == 2796203);\n    assert(rep.exponent == 125);\n    assert(rep.sign);\n}\n\n/**\n   Allows manipulating the fraction, exponent, and sign parts of a\n   $(D_PARAM double) separately. The definition is:\n\n----\nstruct DoubleRep\n{\n    union\n    {\n        double value;\n        mixin(bitfields!(\n                  ulong,   \"fraction\", 52,\n                  ushort,  \"exponent\", 11,\n                  bool,    \"sign\",      1));\n    }\n    enum uint bias = 1023, signBits = 1, fractionBits = 52, exponentBits = 11;\n}\n----\n*/\n\nstruct DoubleRep\n{\n    union\n    {\n        double value;\n        mixin(bitfields!(\n                  ulong,  \"fraction\", 52,\n                  ushort, \"exponent\", 11,\n                  bool,   \"sign\",      1));\n    }\n    enum uint bias = 1023, signBits = 1, fractionBits = 52, exponentBits = 11;\n}\n\n///\n@safe unittest\n{\n    DoubleRep rep = {value: 0};\n    assert(rep.fraction == 0);\n    assert(rep.exponent == 0);\n    assert(!rep.sign);\n\n    rep.value = 42;\n    assert(rep.fraction == 1407374883553280);\n    assert(rep.exponent == 1028);\n    assert(!rep.sign);\n\n    rep.value = 10;\n    assert(rep.fraction == 1125899906842624);\n    assert(rep.exponent == 1026);\n}\n\n///\n@safe unittest\n{\n    DoubleRep rep = {value: 1};\n    assert(rep.fraction == 0);\n    assert(rep.exponent == 1023);\n    assert(!rep.sign);\n\n    rep.exponent = 1022;\n    assert(rep.value == 0.5);\n\n    rep.exponent = 1026;\n    assert(rep.value == 8);\n}\n\n///\n@safe unittest\n{\n    DoubleRep rep = {value: 1};\n    rep.value = -0.5;\n    assert(rep.fraction == 0);\n    assert(rep.exponent == 1022);\n    assert(rep.sign);\n\n    rep.value = -1. / 3;\n    assert(rep.fraction == 1501199875790165);\n    assert(rep.exponent == 1021);\n    assert(rep.sign);\n}\n\n/// Reading\n@safe unittest\n{\n    DoubleRep x;\n    x.value = 1.0;\n    assert(x.fraction == 0 && x.exponent == 1023 && !x.sign);\n    x.value = -0.5;\n    assert(x.fraction == 0 && x.exponent == 1022 && x.sign);\n    x.value = 0.5;\n    assert(x.fraction == 0 && x.exponent == 1022 && !x.sign);\n}\n\n/// Writing\n@safe unittest\n{\n    DoubleRep x;\n    x.fraction = 1125899906842624;\n    x.exponent = 1025;\n    x.sign = true;\n    assert(x.value == -5.0);\n}\n\n@safe unittest\n{\n    // Issue #15305\n    struct S {\n            mixin(bitfields!(\n                    bool, \"alice\", 1,\n                    ulong, \"bob\", 63,\n            ));\n    }\n\n    S s;\n    s.bob = long.max - 1;\n    s.alice = false;\n    assert(s.bob == long.max - 1);\n}\n\n/**\nA dynamic array of bits. Each bit in a `BitArray` can be manipulated individually\nor by the standard bitwise operators `&`, `|`, `^`, `~`, `>>`, `<<` and also by\nother effective member functions; most of them work relative to the `BitArray`'s\ndimension (see $(LREF dim)), instead of its $(LREF length).\n*/\nstruct BitArray\n{\nprivate:\n\n    import core.bitop : btc, bts, btr, bsf, bt;\n    import std.format : FormatSpec;\n\n    size_t _len;\n    size_t* _ptr;\n    enum bitsPerSizeT = size_t.sizeof * 8;\n\n    @property size_t fullWords() const @nogc pure nothrow\n    {\n        return _len / bitsPerSizeT;\n    }\n    // Number of bits after the last full word\n    @property size_t endBits() const @nogc pure nothrow\n    {\n        return _len % bitsPerSizeT;\n    }\n    // Bit mask to extract the bits after the last full word\n    @property size_t endMask() const @nogc pure nothrow\n    {\n        return (size_t(1) << endBits) - 1;\n    }\n    static size_t lenToDim(size_t len) @nogc pure nothrow @safe\n    {\n        return (len + (bitsPerSizeT-1)) / bitsPerSizeT;\n    }\n\npublic:\n    /**\n    Creates a `BitArray` from a `bool` array, such that `bool` values read\n    from left to right correspond to subsequent bits in the `BitArray`.\n\n    Params: ba = Source array of `bool` values.\n    */\n    this(in bool[] ba) nothrow pure\n    {\n        length = ba.length;\n        foreach (i, b; ba)\n        {\n            this[i] = b;\n        }\n    }\n\n    ///\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n\n        bool[] input = [true, false, false, true, true];\n        auto a = BitArray(input);\n        assert(a.length == 5);\n        assert(a.bitsSet.equal([0, 3, 4]));\n\n        // This also works because an implicit cast to bool[] occurs for this array.\n        auto b = BitArray([0, 0, 1]);\n        assert(b.length == 3);\n        assert(b.bitsSet.equal([2]));\n    }\n\n    ///\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.array : array;\n        import std.range : iota, repeat;\n\n        BitArray a = true.repeat(70).array;\n        assert(a.length == 70);\n        assert(a.bitsSet.equal(iota(0, 70)));\n    }\n\n    /**\n    Creates a `BitArray` from the raw contents of the source array. The\n    source array is not copied but simply acts as the underlying array\n    of bits, which stores data as `size_t` units.\n\n    That means a particular care should be taken when passing an array\n    of a type different than `size_t`, firstly because its length should\n    be a multiple of `size_t.sizeof`, and secondly because how the bits\n    are mapped:\n    ---\n    size_t[] source = [1, 2, 3, 3424234, 724398, 230947, 389492];\n    enum sbits = size_t.sizeof * 8;\n    auto ba = BitArray(source, source.length * sbits);\n    foreach (n; 0 .. source.length * sbits)\n    {\n        auto nth_bit = cast(bool) (source[n / sbits] & (1L << (n % sbits)));\n        assert(ba[n] == nth_bit);\n    }\n    ---\n    The least significant bit in any `size_t` unit is the starting bit of this\n    unit, and the most significant bit is the last bit of this unit. Therefore,\n    passing e.g. an array of `int`s may result in a different `BitArray`\n    depending on the processor's endianness.\n\n    This constructor is the inverse of $(LREF opCast).\n\n    $(RED Warning: All unmapped bits in the final word will be set to 0.)\n\n    Params:\n        v = Source array. `v.length` must be a multple of `size_t.sizeof`.\n        numbits = Number of bits to be mapped from the source array, i.e.\n                  length of the created `BitArray`.\n    */\n    this(void[] v, size_t numbits) @nogc nothrow pure\n    in\n    {\n        assert(numbits <= v.length * 8);\n        assert(v.length % size_t.sizeof == 0);\n    }\n    do\n    {\n        _ptr = cast(size_t*) v.ptr;\n        _len = numbits;\n        if (endBits)\n        {\n            // Need to mask away extraneous bits from v.\n            _ptr[dim - 1] &= endMask;\n        }\n    }\n\n    ///\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n\n        auto a = BitArray([1, 0, 0, 1, 1]);\n\n        // Inverse of the cast.\n        auto v = cast(void[]) a;\n        auto b = BitArray(v, a.length);\n\n        assert(b.length == 5);\n        assert(b.bitsSet.equal([0, 3, 4]));\n\n        // a and b share the underlying data.\n        a[0] = 0;\n        assert(b[0] == 0);\n        assert(a == b);\n    }\n\n    ///\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n\n        size_t[] source = [0b1100, 0b0011];\n        enum sbits = size_t.sizeof * 8;\n        auto ba = BitArray(source, source.length * sbits);\n        // The least significant bit in each unit is this unit's starting bit.\n        assert(ba.bitsSet.equal([2, 3, sbits, sbits + 1]));\n    }\n\n    ///\n    @system unittest\n    {\n        // Example from the doc for this constructor.\n        size_t[] source = [1, 0b101, 3, 3424234, 724398, 230947, 389492];\n        enum sbits = size_t.sizeof * 8;\n        auto ba = BitArray(source, source.length * sbits);\n        foreach (n; 0 .. source.length * sbits)\n        {\n            auto nth_bit = cast(bool) (source[n / sbits] & (1L << (n % sbits)));\n            assert(ba[n] == nth_bit);\n        }\n\n        // Example of mapping only part of the array.\n        import std.algorithm.comparison : equal;\n\n        auto bc = BitArray(source, sbits + 1);\n        assert(bc.bitsSet.equal([0, sbits]));\n        // The unmapped bits from the final word have been cleared.\n        assert(source[1] == 1);\n    }\n\n    // Deliberately undocumented: raw initialization of bit array.\n    this(size_t len, size_t* ptr) @nogc nothrow pure\n    {\n        _len = len;\n        _ptr = ptr;\n    }\n\n    /**\n    Returns: Dimension i.e. the number of native words backing this `BitArray`.\n\n    Technically, this is the length of the underlying array storing bits, which\n    is equal to `ceil(length / (size_t.sizeof * 8))`, as bits are packed into\n    `size_t` units.\n    */\n    @property size_t dim() const @nogc nothrow pure @safe\n    {\n        return lenToDim(_len);\n    }\n\n    /**\n    Returns: Number of bits in the `BitArray`.\n    */\n    @property size_t length() const @nogc nothrow pure @safe\n    {\n        return _len;\n    }\n\n    /**********************************************\n     * Sets the amount of bits in the `BitArray`.\n     * $(RED Warning: increasing length may overwrite bits in\n     * final word up to the next word boundary. i.e. D dynamic\n     * array extension semantics are not followed.)\n     */\n    @property size_t length(size_t newlen) pure nothrow @system\n    {\n        if (newlen != _len)\n        {\n            size_t olddim = dim;\n            immutable newdim = lenToDim(newlen);\n\n            if (newdim != olddim)\n            {\n                // Create a fake array so we can use D's realloc machinery\n                auto b = _ptr[0 .. olddim];\n                b.length = newdim;                // realloc\n                _ptr = b.ptr;\n            }\n\n            _len = newlen;\n        }\n        return _len;\n    }\n\n    /**********************************************\n     * Gets the `i`'th bit in the `BitArray`.\n     */\n    bool opIndex(size_t i) const @nogc pure nothrow\n    in\n    {\n        assert(i < _len);\n    }\n    do\n    {\n        return cast(bool) bt(_ptr, i);\n    }\n\n    ///\n    @system unittest\n    {\n        static void fun(const BitArray arr)\n        {\n            auto x = arr[0];\n            assert(x == 1);\n        }\n        BitArray a;\n        a.length = 3;\n        a[0] = 1;\n        fun(a);\n    }\n\n    /**********************************************\n     * Sets the `i`'th bit in the `BitArray`.\n     */\n    bool opIndexAssign(bool b, size_t i) @nogc pure nothrow\n    in\n    {\n        assert(i < _len);\n    }\n    do\n    {\n        if (b)\n            bts(_ptr, i);\n        else\n            btr(_ptr, i);\n        return b;\n    }\n\n    /**\n      Sets all the values in the `BitArray` to the\n      value specified by `val`.\n     */\n    void opSliceAssign(bool val)\n    {\n        _ptr[0 .. fullWords] = val ? ~size_t(0) : 0;\n        if (endBits)\n        {\n            if (val)\n                _ptr[fullWords] |= endMask;\n            else\n                _ptr[fullWords] &= ~endMask;\n        }\n    }\n\n    ///\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n\n        auto b = BitArray([1, 0, 1, 0, 1, 1]);\n\n        b[] = true;\n        // all bits are set\n        assert(b.bitsSet.equal([0, 1, 2, 3, 4, 5]));\n\n        b[] = false;\n        // none of the bits are set\n        assert(b.bitsSet.empty);\n    }\n\n    /**\n      Sets the bits of a slice of `BitArray` starting\n      at index `start` and ends at index ($D end - 1)\n      with the values specified by `val`.\n     */\n    void opSliceAssign(bool val, size_t start, size_t end)\n    in\n    {\n        assert(start <= end);\n        assert(end <= length);\n    }\n    do\n    {\n        size_t startBlock = start / bitsPerSizeT;\n        size_t endBlock = end / bitsPerSizeT;\n        size_t startOffset = start % bitsPerSizeT;\n        size_t endOffset = end % bitsPerSizeT;\n\n        if (startBlock == endBlock)\n        {\n            size_t startBlockMask = ~((size_t(1) << startOffset) - 1);\n            size_t endBlockMask = (size_t(1) << endOffset) - 1;\n            size_t joinMask = startBlockMask & endBlockMask;\n            if (val)\n                _ptr[startBlock] |= joinMask;\n            else\n                _ptr[startBlock] &= ~joinMask;\n            return;\n        }\n\n        if (startOffset != 0)\n        {\n            size_t startBlockMask = ~((size_t(1) << startOffset) - 1);\n            if (val)\n                _ptr[startBlock] |= startBlockMask;\n            else\n                _ptr[startBlock] &= ~startBlockMask;\n            ++startBlock;\n        }\n        if (endOffset != 0)\n        {\n            size_t endBlockMask = (size_t(1) << endOffset) - 1;\n            if (val)\n                _ptr[endBlock] |= endBlockMask;\n            else\n                _ptr[endBlock] &= ~endBlockMask;\n        }\n        _ptr[startBlock .. endBlock] = size_t(0) - size_t(val);\n    }\n\n    ///\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.range : iota;\n        import std.stdio;\n\n        auto b = BitArray([1, 0, 0, 0, 1, 1, 0]);\n        b[1 .. 3] = true;\n        assert(b.bitsSet.equal([0, 1, 2, 4, 5]));\n\n        bool[72] bitArray;\n        auto b1 = BitArray(bitArray);\n        b1[63 .. 67] = true;\n        assert(b1.bitsSet.equal([63, 64, 65, 66]));\n        b1[63 .. 67] = false;\n        assert(b1.bitsSet.empty);\n        b1[0 .. 64] = true;\n        assert(b1.bitsSet.equal(iota(0, 64)));\n        b1[0 .. 64] = false;\n        assert(b1.bitsSet.empty);\n\n        bool[256] bitArray2;\n        auto b2 = BitArray(bitArray2);\n        b2[3 .. 245] = true;\n        assert(b2.bitsSet.equal(iota(3, 245)));\n        b2[3 .. 245] = false;\n        assert(b2.bitsSet.empty);\n    }\n\n    /**\n      Flips all the bits in the `BitArray`\n     */\n    void flip()\n    {\n        foreach (i; 0 .. fullWords)\n            _ptr[i] = ~_ptr[i];\n\n        if (endBits)\n            _ptr[fullWords] = (~_ptr[fullWords]) & endMask;\n    }\n\n    ///\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.range : iota;\n\n        // positions 0, 2, 4 are set\n        auto b = BitArray([1, 0, 1, 0, 1, 0]);\n        b.flip();\n        // after flipping, positions 1, 3, 5 are set\n        assert(b.bitsSet.equal([1, 3, 5]));\n\n        bool[270] bits;\n        auto b1 = BitArray(bits);\n        b1.flip();\n        assert(b1.bitsSet.equal(iota(0, 270)));\n    }\n\n    /**\n      Flips a single bit, specified by `pos`\n     */\n    void flip(size_t i)\n    {\n        bt(_ptr, i) ? btr(_ptr, i) : bts(_ptr, i);\n    }\n\n    ///\n    @system unittest\n    {\n        auto ax = BitArray([1, 0, 0, 1]);\n        ax.flip(0);\n        assert(ax[0] == 0);\n\n        bool[200] y;\n        y[90 .. 130] = true;\n        auto ay = BitArray(y);\n        ay.flip(100);\n        assert(ay[100] == 0);\n    }\n\n    /**********************************************\n     * Counts all the set bits in the `BitArray`\n     */\n    size_t count()\n    {\n        if (_ptr)\n        {\n            size_t bitCount;\n            foreach (i; 0 .. fullWords)\n                bitCount += countBitsSet(_ptr[i]);\n            bitCount += countBitsSet(_ptr[fullWords] & endMask);\n            return bitCount;\n        }\n        else\n        {\n            return 0;\n        }\n    }\n\n    ///\n    @system unittest\n    {\n        auto a = BitArray([0, 1, 1, 0, 0, 1, 1]);\n        assert(a.count == 4);\n\n        BitArray b;\n        assert(b.count == 0);\n\n        bool[200] boolArray;\n        boolArray[45 .. 130] = true;\n        auto c = BitArray(boolArray);\n        assert(c.count == 85);\n    }\n\n    /**********************************************\n     * Duplicates the `BitArray` and its contents.\n     */\n    @property BitArray dup() const pure nothrow\n    {\n        BitArray ba;\n\n        auto b = _ptr[0 .. dim].dup;\n        ba._len = _len;\n        ba._ptr = b.ptr;\n        return ba;\n    }\n\n    ///\n    @system unittest\n    {\n        BitArray a;\n        BitArray b;\n\n        a.length = 3;\n        a[0] = 1; a[1] = 0; a[2] = 1;\n        b = a.dup;\n        assert(b.length == 3);\n        foreach (i; 0 .. 3)\n            assert(b[i] == (((i ^ 1) & 1) ? true : false));\n    }\n\n    /**********************************************\n     * Support for `foreach` loops for `BitArray`.\n     */\n    int opApply(scope int delegate(ref bool) dg)\n    {\n        int result;\n\n        foreach (i; 0 .. _len)\n        {\n            bool b = opIndex(i);\n            result = dg(b);\n            this[i] = b;\n            if (result)\n                break;\n        }\n        return result;\n    }\n\n    /** ditto */\n    int opApply(scope int delegate(bool) dg) const\n    {\n        int result;\n\n        foreach (i; 0 .. _len)\n        {\n            immutable b = opIndex(i);\n            result = dg(b);\n            if (result)\n                break;\n        }\n        return result;\n    }\n\n    /** ditto */\n    int opApply(scope int delegate(size_t, ref bool) dg)\n    {\n        int result;\n\n        foreach (i; 0 .. _len)\n        {\n            bool b = opIndex(i);\n            result = dg(i, b);\n            this[i] = b;\n            if (result)\n                break;\n        }\n        return result;\n    }\n\n    /** ditto */\n    int opApply(scope int delegate(size_t, bool) dg) const\n    {\n        int result;\n\n        foreach (i; 0 .. _len)\n        {\n            immutable b = opIndex(i);\n            result = dg(i, b);\n            if (result)\n                break;\n        }\n        return result;\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1];\n\n        auto a = BitArray(ba);\n\n        int i;\n        foreach (b;a)\n        {\n            switch (i)\n            {\n                case 0: assert(b == true); break;\n                case 1: assert(b == false); break;\n                case 2: assert(b == true); break;\n                default: assert(0);\n            }\n            i++;\n        }\n\n        foreach (j,b;a)\n        {\n            switch (j)\n            {\n                case 0: assert(b == true); break;\n                case 1: assert(b == false); break;\n                case 2: assert(b == true); break;\n                default: assert(0);\n            }\n        }\n    }\n\n\n    /**********************************************\n     * Reverses the bits of the `BitArray`.\n     */\n    @property BitArray reverse() @nogc pure nothrow\n    out (result)\n    {\n        assert(result == this);\n    }\n    do\n    {\n        if (_len >= 2)\n        {\n            bool t;\n            size_t lo, hi;\n\n            lo = 0;\n            hi = _len - 1;\n            for (; lo < hi; lo++, hi--)\n            {\n                t = this[lo];\n                this[lo] = this[hi];\n                this[hi] = t;\n            }\n        }\n        return this;\n    }\n\n    ///\n    @system unittest\n    {\n        BitArray b;\n        bool[5] data = [1,0,1,1,0];\n\n        b = BitArray(data);\n        b.reverse;\n        foreach (i; 0 .. data.length)\n            assert(b[i] == data[4 - i]);\n    }\n\n\n    /**********************************************\n     * Sorts the `BitArray`'s elements.\n     */\n    @property BitArray sort() @nogc pure nothrow\n    out (result)\n    {\n        assert(result == this);\n    }\n    do\n    {\n        if (_len >= 2)\n        {\n            size_t lo, hi;\n\n            lo = 0;\n            hi = _len - 1;\n            while (1)\n            {\n                while (1)\n                {\n                    if (lo >= hi)\n                        goto Ldone;\n                    if (this[lo] == true)\n                        break;\n                    lo++;\n                }\n\n                while (1)\n                {\n                    if (lo >= hi)\n                        goto Ldone;\n                    if (this[hi] == false)\n                        break;\n                    hi--;\n                }\n\n                this[lo] = false;\n                this[hi] = true;\n\n                lo++;\n                hi--;\n            }\n        }\n    Ldone:\n        return this;\n    }\n\n    ///\n    @system unittest\n    {\n        size_t x = 0b1100011000;\n        auto ba = BitArray(10, &x);\n        ba.sort;\n        foreach (i; 0 .. 6)\n            assert(ba[i] == false);\n        foreach (i; 6 .. 10)\n            assert(ba[i] == true);\n    }\n\n\n    /***************************************\n     * Support for operators == and != for `BitArray`.\n     */\n    bool opEquals(const ref BitArray a2) const @nogc pure nothrow\n    {\n        if (this.length != a2.length)\n            return false;\n        auto p1 = this._ptr;\n        auto p2 = a2._ptr;\n\n        if (p1[0 .. fullWords] != p2[0 .. fullWords])\n            return false;\n\n        if (!endBits)\n            return true;\n\n        auto i = fullWords;\n        return (p1[i] & endMask) == (p2[i] & endMask);\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1];\n        bool[] bb = [1,0,1];\n        bool[] bc = [1,0,1,0,1,0,1];\n        bool[] bd = [1,0,1,1,1];\n        bool[] be = [1,0,1,0,1];\n        bool[] bf = [1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];\n        bool[] bg = [1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n        auto c = BitArray(bc);\n        auto d = BitArray(bd);\n        auto e = BitArray(be);\n        auto f = BitArray(bf);\n        auto g = BitArray(bg);\n\n        assert(a != b);\n        assert(a != c);\n        assert(a != d);\n        assert(a == e);\n        assert(f != g);\n    }\n\n    /***************************************\n     * Supports comparison operators for `BitArray`.\n     */\n    int opCmp(BitArray a2) const @nogc pure nothrow\n    {\n        const lesser = this.length < a2.length ? &this : &a2;\n        immutable fullWords = lesser.fullWords;\n        immutable endBits = lesser.endBits;\n        auto p1 = this._ptr;\n        auto p2 = a2._ptr;\n\n        foreach (i; 0 .. fullWords)\n        {\n            if (p1[i] != p2[i])\n            {\n                return p1[i] & (size_t(1) << bsf(p1[i] ^ p2[i])) ? 1 : -1;\n            }\n        }\n\n        if (endBits)\n        {\n            immutable i = fullWords;\n            immutable diff = p1[i] ^ p2[i];\n            if (diff)\n            {\n                immutable index = bsf(diff);\n                if (index < endBits)\n                {\n                    return p1[i] & (size_t(1) << index) ? 1 : -1;\n                }\n            }\n        }\n\n        // Standard:\n        // A bool value can be implicitly converted to any integral type,\n        // with false becoming 0 and true becoming 1\n        return (this.length > a2.length) - (this.length < a2.length);\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1];\n        bool[] bb = [1,0,1];\n        bool[] bc = [1,0,1,0,1,0,1];\n        bool[] bd = [1,0,1,1,1];\n        bool[] be = [1,0,1,0,1];\n        bool[] bf = [1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1];\n        bool[] bg = [1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n        auto c = BitArray(bc);\n        auto d = BitArray(bd);\n        auto e = BitArray(be);\n        auto f = BitArray(bf);\n        auto g = BitArray(bg);\n\n        assert(a >  b);\n        assert(a >= b);\n        assert(a <  c);\n        assert(a <= c);\n        assert(a <  d);\n        assert(a <= d);\n        assert(a == e);\n        assert(a <= e);\n        assert(a >= e);\n        assert(f <  g);\n        assert(g <= g);\n    }\n\n    @system unittest\n    {\n        bool[] v;\n        foreach  (i; 1 .. 256)\n        {\n            v.length = i;\n            v[] = false;\n            auto x = BitArray(v);\n            v[i-1] = true;\n            auto y = BitArray(v);\n            assert(x < y);\n            assert(x <= y);\n        }\n\n        BitArray a1, a2;\n\n        for (size_t len = 4; len <= 256; len <<= 1)\n        {\n            a1.length = a2.length = len;\n            a1[len-2] = a2[len-1] = true;\n            assert(a1 > a2);\n            a1[len-2] = a2[len-1] = false;\n        }\n\n        foreach (j; 1 .. a1.length)\n        {\n            a1[j-1] = a2[j] = true;\n            assert(a1 > a2);\n            a1[j-1] = a2[j] = false;\n        }\n    }\n\n    /***************************************\n     * Support for hashing for `BitArray`.\n     */\n    size_t toHash() const @nogc pure nothrow\n    {\n        size_t hash = 3557;\n        auto fullBytes = _len / 8;\n        foreach (i; 0 .. fullBytes)\n        {\n            hash *= 3559;\n            hash += (cast(byte*) this._ptr)[i];\n        }\n        foreach (i; 8*fullBytes .. _len)\n        {\n            hash *= 3571;\n            hash += this[i];\n        }\n        return hash;\n    }\n\n    /***************************************\n     * Convert to `void[]`.\n     */\n    void[] opCast(T : void[])() @nogc pure nothrow\n    {\n        return cast(void[])_ptr[0 .. dim];\n    }\n\n    /***************************************\n     * Convert to `size_t[]`.\n     */\n    size_t[] opCast(T : size_t[])() @nogc pure nothrow\n    {\n        return _ptr[0 .. dim];\n    }\n\n    ///\n    @system unittest\n    {\n        import std.array : array;\n        import std.range : repeat, take;\n\n        // bit array with 300 elements\n        auto a = BitArray(true.repeat.take(300).array);\n        size_t[] v = cast(size_t[]) a;\n        const blockSize = size_t.sizeof * 8;\n        assert(v.length == (a.length + blockSize - 1) / blockSize);\n    }\n\n    /***************************************\n     * Support for unary operator ~ for `BitArray`.\n     */\n    BitArray opCom() const pure nothrow\n    {\n        auto dim = this.dim;\n\n        BitArray result;\n        result.length = _len;\n\n        result._ptr[0 .. dim] = ~this._ptr[0 .. dim];\n\n        // Avoid putting garbage in extra bits\n        // Remove once we zero on length extension\n        if (endBits)\n            result._ptr[dim - 1] &= endMask;\n\n        return result;\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1];\n\n        auto a = BitArray(ba);\n        BitArray b = ~a;\n\n        assert(b[0] == 0);\n        assert(b[1] == 1);\n        assert(b[2] == 0);\n        assert(b[3] == 1);\n        assert(b[4] == 0);\n    }\n\n\n    /***************************************\n     * Support for binary bitwise operators for `BitArray`.\n     */\n    BitArray opBinary(string op)(const BitArray e2) const pure nothrow\n        if (op == \"-\" || op == \"&\" || op == \"|\" || op == \"^\")\n    in\n    {\n        assert(_len == e2.length);\n    }\n    do\n    {\n        auto dim = this.dim;\n\n        BitArray result;\n        result.length = _len;\n\n        static if (op == \"-\")\n            result._ptr[0 .. dim] = this._ptr[0 .. dim] & ~e2._ptr[0 .. dim];\n        else\n            mixin(\"result._ptr[0 .. dim] = this._ptr[0 .. dim]\"~op~\" e2._ptr[0 .. dim];\");\n\n        // Avoid putting garbage in extra bits\n        // Remove once we zero on length extension\n        if (endBits)\n            result._ptr[dim - 1] &= endMask;\n\n        return result;\n    }\n\n    ///\n    @system unittest\n    {\n        static bool[] ba = [1,0,1,0,1];\n        static bool[] bb = [1,0,1,1,0];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n\n        BitArray c = a & b;\n\n        assert(c[0] == 1);\n        assert(c[1] == 0);\n        assert(c[2] == 1);\n        assert(c[3] == 0);\n        assert(c[4] == 0);\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1];\n        bool[] bb = [1,0,1,1,0];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n\n        BitArray c = a | b;\n\n        assert(c[0] == 1);\n        assert(c[1] == 0);\n        assert(c[2] == 1);\n        assert(c[3] == 1);\n        assert(c[4] == 1);\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1];\n        bool[] bb = [1,0,1,1,0];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n\n        BitArray c = a ^ b;\n\n        assert(c[0] == 0);\n        assert(c[1] == 0);\n        assert(c[2] == 0);\n        assert(c[3] == 1);\n        assert(c[4] == 1);\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1];\n        bool[] bb = [1,0,1,1,0];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n\n        BitArray c = a - b;\n\n        assert(c[0] == 0);\n        assert(c[1] == 0);\n        assert(c[2] == 0);\n        assert(c[3] == 0);\n        assert(c[4] == 1);\n    }\n\n\n    /***************************************\n     * Support for operator op= for `BitArray`.\n     */\n    BitArray opOpAssign(string op)(const BitArray e2) @nogc pure nothrow\n        if (op == \"-\" || op == \"&\" || op == \"|\" || op == \"^\")\n    in\n    {\n        assert(_len == e2.length);\n    }\n    do\n    {\n        foreach (i; 0 .. fullWords)\n        {\n            static if (op == \"-\")\n                _ptr[i] &= ~e2._ptr[i];\n            else\n                mixin(\"_ptr[i] \"~op~\"= e2._ptr[i];\");\n        }\n        if (!endBits)\n            return this;\n\n        size_t i = fullWords;\n        size_t endWord = _ptr[i];\n        static if (op == \"-\")\n            endWord &= ~e2._ptr[i];\n        else\n            mixin(\"endWord \"~op~\"= e2._ptr[i];\");\n        _ptr[i] = (_ptr[i] & ~endMask) | (endWord & endMask);\n\n        return this;\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1,1,0,1,0,1];\n        bool[] bb = [1,0,1,1,0];\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n        BitArray c = a;\n        c.length = 5;\n        c &= b;\n        assert(a[5] == 1);\n        assert(a[6] == 0);\n        assert(a[7] == 1);\n        assert(a[8] == 0);\n        assert(a[9] == 1);\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1];\n        bool[] bb = [1,0,1,1,0];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n\n        a &= b;\n        assert(a[0] == 1);\n        assert(a[1] == 0);\n        assert(a[2] == 1);\n        assert(a[3] == 0);\n        assert(a[4] == 0);\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1];\n        bool[] bb = [1,0,1,1,0];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n\n        a |= b;\n        assert(a[0] == 1);\n        assert(a[1] == 0);\n        assert(a[2] == 1);\n        assert(a[3] == 1);\n        assert(a[4] == 1);\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1];\n        bool[] bb = [1,0,1,1,0];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n\n        a ^= b;\n        assert(a[0] == 0);\n        assert(a[1] == 0);\n        assert(a[2] == 0);\n        assert(a[3] == 1);\n        assert(a[4] == 1);\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1];\n        bool[] bb = [1,0,1,1,0];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n\n        a -= b;\n        assert(a[0] == 0);\n        assert(a[1] == 0);\n        assert(a[2] == 0);\n        assert(a[3] == 0);\n        assert(a[4] == 1);\n    }\n\n    /***************************************\n     * Support for operator ~= for `BitArray`.\n     * $(RED Warning: This will overwrite a bit in the final word\n     * of the current underlying data regardless of whether it is\n     * shared between BitArray objects. i.e. D dynamic array\n     * concatenation semantics are not followed)\n     */\n\n    BitArray opCatAssign(bool b) pure nothrow\n    {\n        length = _len + 1;\n        this[_len - 1] = b;\n        return this;\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0,1,0,1];\n\n        auto a = BitArray(ba);\n        BitArray b;\n\n        b = (a ~= true);\n        assert(a[0] == 1);\n        assert(a[1] == 0);\n        assert(a[2] == 1);\n        assert(a[3] == 0);\n        assert(a[4] == 1);\n        assert(a[5] == 1);\n\n        assert(b == a);\n    }\n\n    /***************************************\n     * ditto\n     */\n\n    BitArray opCatAssign(BitArray b) pure nothrow\n    {\n        auto istart = _len;\n        length = _len + b.length;\n        for (auto i = istart; i < _len; i++)\n            this[i] = b[i - istart];\n        return this;\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0];\n        bool[] bb = [0,1,0];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n        BitArray c;\n\n        c = (a ~= b);\n        assert(a.length == 5);\n        assert(a[0] == 1);\n        assert(a[1] == 0);\n        assert(a[2] == 0);\n        assert(a[3] == 1);\n        assert(a[4] == 0);\n\n        assert(c == a);\n    }\n\n    /***************************************\n     * Support for binary operator ~ for `BitArray`.\n     */\n    BitArray opCat(bool b) const pure nothrow\n    {\n        BitArray r;\n\n        r = this.dup;\n        r.length = _len + 1;\n        r[_len] = b;\n        return r;\n    }\n\n    /** ditto */\n    BitArray opCat_r(bool b) const pure nothrow\n    {\n        BitArray r;\n\n        r.length = _len + 1;\n        r[0] = b;\n        foreach (i; 0 .. _len)\n            r[1 + i] = this[i];\n        return r;\n    }\n\n    /** ditto */\n    BitArray opCat(BitArray b) const pure nothrow\n    {\n        BitArray r;\n\n        r = this.dup;\n        r ~= b;\n        return r;\n    }\n\n    ///\n    @system unittest\n    {\n        bool[] ba = [1,0];\n        bool[] bb = [0,1,0];\n\n        auto a = BitArray(ba);\n        auto b = BitArray(bb);\n        BitArray c;\n\n        c = (a ~ b);\n        assert(c.length == 5);\n        assert(c[0] == 1);\n        assert(c[1] == 0);\n        assert(c[2] == 0);\n        assert(c[3] == 1);\n        assert(c[4] == 0);\n\n        c = (a ~ true);\n        assert(c.length == 3);\n        assert(c[0] == 1);\n        assert(c[1] == 0);\n        assert(c[2] == 1);\n\n        c = (false ~ a);\n        assert(c.length == 3);\n        assert(c[0] == 0);\n        assert(c[1] == 1);\n        assert(c[2] == 0);\n    }\n\n    // Rolls double word (upper, lower) to the right by n bits and returns the\n    // lower word of the result.\n    private static size_t rollRight()(size_t upper, size_t lower, size_t nbits)\n        pure @safe nothrow @nogc\n    in\n    {\n        assert(nbits < bitsPerSizeT);\n    }\n    do\n    {\n        if (nbits == 0)\n            return lower;\n        return (upper << (bitsPerSizeT - nbits)) | (lower >> nbits);\n    }\n\n    @safe unittest\n    {\n        static if (size_t.sizeof == 8)\n        {\n            size_t x = 0x12345678_90ABCDEF;\n            size_t y = 0xFEDBCA09_87654321;\n\n            assert(rollRight(x, y, 32) == 0x90ABCDEF_FEDBCA09);\n            assert(rollRight(y, x, 4) == 0x11234567_890ABCDE);\n        }\n        else static if (size_t.sizeof == 4)\n        {\n            size_t x = 0x12345678;\n            size_t y = 0x90ABCDEF;\n\n            assert(rollRight(x, y, 16) == 0x567890AB);\n            assert(rollRight(y, x, 4) == 0xF1234567);\n        }\n        else\n            static assert(0, \"Unsupported size_t width\");\n    }\n\n    // Rolls double word (upper, lower) to the left by n bits and returns the\n    // upper word of the result.\n    private static size_t rollLeft()(size_t upper, size_t lower, size_t nbits)\n        pure @safe nothrow @nogc\n    in\n    {\n        assert(nbits < bitsPerSizeT);\n    }\n    do\n    {\n        if (nbits == 0)\n            return upper;\n        return (upper << nbits) | (lower >> (bitsPerSizeT - nbits));\n    }\n\n    @safe unittest\n    {\n        static if (size_t.sizeof == 8)\n        {\n            size_t x = 0x12345678_90ABCDEF;\n            size_t y = 0xFEDBCA09_87654321;\n\n            assert(rollLeft(x, y, 32) == 0x90ABCDEF_FEDBCA09);\n            assert(rollLeft(y, x, 4) == 0xEDBCA098_76543211);\n        }\n        else static if (size_t.sizeof == 4)\n        {\n            size_t x = 0x12345678;\n            size_t y = 0x90ABCDEF;\n\n            assert(rollLeft(x, y, 16) == 0x567890AB);\n            assert(rollLeft(y, x, 4) == 0x0ABCDEF1);\n        }\n    }\n\n    /**\n     * Operator `<<=` support.\n     *\n     * Shifts all the bits in the array to the left by the given number of\n     * bits.  The leftmost bits are dropped, and 0's are appended to the end\n     * to fill up the vacant bits.\n     *\n     * $(RED Warning: unused bits in the final word up to the next word\n     * boundary may be overwritten by this operation. It does not attempt to\n     * preserve bits past the end of the array.)\n     */\n    void opOpAssign(string op)(size_t nbits) @nogc pure nothrow\n        if (op == \"<<\")\n    {\n        size_t wordsToShift = nbits / bitsPerSizeT;\n        size_t bitsToShift = nbits % bitsPerSizeT;\n\n        if (wordsToShift < dim)\n        {\n            foreach_reverse (i; 1 .. dim - wordsToShift)\n            {\n                _ptr[i + wordsToShift] = rollLeft(_ptr[i], _ptr[i-1],\n                                                 bitsToShift);\n            }\n            _ptr[wordsToShift] = rollLeft(_ptr[0], 0, bitsToShift);\n        }\n\n        import std.algorithm.comparison : min;\n        foreach (i; 0 .. min(wordsToShift, dim))\n        {\n            _ptr[i] = 0;\n        }\n    }\n\n    /**\n     * Operator `>>=` support.\n     *\n     * Shifts all the bits in the array to the right by the given number of\n     * bits.  The rightmost bits are dropped, and 0's are inserted at the back\n     * to fill up the vacant bits.\n     *\n     * $(RED Warning: unused bits in the final word up to the next word\n     * boundary may be overwritten by this operation. It does not attempt to\n     * preserve bits past the end of the array.)\n     */\n    void opOpAssign(string op)(size_t nbits) @nogc pure nothrow\n        if (op == \">>\")\n    {\n        size_t wordsToShift = nbits / bitsPerSizeT;\n        size_t bitsToShift = nbits % bitsPerSizeT;\n\n        if (wordsToShift + 1 < dim)\n        {\n            foreach (i; 0 .. dim - wordsToShift - 1)\n            {\n                _ptr[i] = rollRight(_ptr[i + wordsToShift + 1],\n                                   _ptr[i + wordsToShift], bitsToShift);\n            }\n        }\n\n        // The last word needs some care, as it must shift in 0's from past the\n        // end of the array.\n        if (wordsToShift < dim)\n        {\n            if (bitsToShift == 0)\n                _ptr[dim - wordsToShift - 1] = _ptr[dim - 1];\n            else\n            {\n                // Special case: if endBits == 0, then also endMask == 0.\n                size_t lastWord = (endBits ? (_ptr[fullWords] & endMask) : _ptr[fullWords - 1]);\n                _ptr[dim - wordsToShift - 1] = rollRight(0, lastWord, bitsToShift);\n            }\n        }\n\n        import std.algorithm.comparison : min;\n        foreach (i; 0 .. min(wordsToShift, dim))\n        {\n            _ptr[dim - i - 1] = 0;\n        }\n    }\n\n    // Issue 17467\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.range : iota;\n\n        bool[] buf = new bool[64*3];\n        buf[0 .. 64] = true;\n        BitArray b = BitArray(buf);\n        assert(equal(b.bitsSet, iota(0, 64)));\n        b <<= 64;\n        assert(equal(b.bitsSet, iota(64, 128)));\n\n        buf = new bool[64*3];\n        buf[64*2 .. 64*3] = true;\n        b = BitArray(buf);\n        assert(equal(b.bitsSet, iota(64*2, 64*3)));\n        b >>= 64;\n        assert(equal(b.bitsSet, iota(64, 128)));\n    }\n\n    // Issue 18134 - shifting right when length is a multiple of 8 * size_t.sizeof.\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.array : array;\n        import std.range : repeat, iota;\n\n        immutable r = size_t.sizeof * 8;\n\n        BitArray a = true.repeat(r / 2).array;\n        a >>= 0;\n        assert(a.bitsSet.equal(iota(0, r / 2)));\n        a >>= 1;\n        assert(a.bitsSet.equal(iota(0, r / 2 - 1)));\n\n        BitArray b = true.repeat(r).array;\n        b >>= 0;\n        assert(b.bitsSet.equal(iota(0, r)));\n        b >>= 1;\n        assert(b.bitsSet.equal(iota(0, r - 1)));\n\n        BitArray c = true.repeat(2 * r).array;\n        c >>= 0;\n        assert(c.bitsSet.equal(iota(0, 2 * r)));\n        c >>= 10;\n        assert(c.bitsSet.equal(iota(0, 2 * r - 10)));\n    }\n\n    ///\n    @system unittest\n    {\n        import std.format : format;\n\n        auto b = BitArray([1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1]);\n\n        b <<= 1;\n        assert(format(\"%b\", b) == \"01100_10101101\");\n\n        b >>= 1;\n        assert(format(\"%b\", b) == \"11001_01011010\");\n\n        b <<= 4;\n        assert(format(\"%b\", b) == \"00001_10010101\");\n\n        b >>= 5;\n        assert(format(\"%b\", b) == \"10010_10100000\");\n\n        b <<= 13;\n        assert(format(\"%b\", b) == \"00000_00000000\");\n\n        b = BitArray([1, 0, 1, 1, 0, 1, 1, 1]);\n        b >>= 8;\n        assert(format(\"%b\", b) == \"00000000\");\n\n    }\n\n    // Test multi-word case\n    @system unittest\n    {\n        import std.format : format;\n\n        // This has to be long enough to occupy more than one size_t. On 64-bit\n        // machines, this would be at least 64 bits.\n        auto b = BitArray([\n            1, 0, 0, 0, 0, 0, 0, 0,  1, 1, 0, 0, 0, 0, 0, 0,\n            1, 1, 1, 0, 0, 0, 0, 0,  1, 1, 1, 1, 0, 0, 0, 0,\n            1, 1, 1, 1, 1, 0, 0, 0,  1, 1, 1, 1, 1, 1, 0, 0,\n            1, 1, 1, 1, 1, 1, 1, 0,  1, 1, 1, 1, 1, 1, 1, 1,\n            1, 0, 1, 0, 1, 0, 1, 0,  0, 1, 0, 1, 0, 1, 0, 1,\n        ]);\n        b <<= 8;\n        assert(format(\"%b\", b) ==\n               \"00000000_10000000_\"~\n               \"11000000_11100000_\"~\n               \"11110000_11111000_\"~\n               \"11111100_11111110_\"~\n               \"11111111_10101010\");\n\n        // Test right shift of more than one size_t's worth of bits\n        b <<= 68;\n        assert(format(\"%b\", b) ==\n               \"00000000_00000000_\"~\n               \"00000000_00000000_\"~\n               \"00000000_00000000_\"~\n               \"00000000_00000000_\"~\n               \"00000000_00001000\");\n\n        b = BitArray([\n            1, 0, 0, 0, 0, 0, 0, 0,  1, 1, 0, 0, 0, 0, 0, 0,\n            1, 1, 1, 0, 0, 0, 0, 0,  1, 1, 1, 1, 0, 0, 0, 0,\n            1, 1, 1, 1, 1, 0, 0, 0,  1, 1, 1, 1, 1, 1, 0, 0,\n            1, 1, 1, 1, 1, 1, 1, 0,  1, 1, 1, 1, 1, 1, 1, 1,\n            1, 0, 1, 0, 1, 0, 1, 0,  0, 1, 0, 1, 0, 1, 0, 1,\n        ]);\n        b >>= 8;\n        assert(format(\"%b\", b) ==\n               \"11000000_11100000_\"~\n               \"11110000_11111000_\"~\n               \"11111100_11111110_\"~\n               \"11111111_10101010_\"~\n               \"01010101_00000000\");\n\n        // Test left shift of more than 1 size_t's worth of bits\n        b >>= 68;\n        assert(format(\"%b\", b) ==\n               \"01010000_00000000_\"~\n               \"00000000_00000000_\"~\n               \"00000000_00000000_\"~\n               \"00000000_00000000_\"~\n               \"00000000_00000000\");\n    }\n\n    /***************************************\n     * Return a string representation of this BitArray.\n     *\n     * Two format specifiers are supported:\n     * $(LI $(B %s) which prints the bits as an array, and)\n     * $(LI $(B %b) which prints the bits as 8-bit byte packets)\n     * separated with an underscore.\n     *\n     * Params:\n     *     sink = A `char` accepting\n     *     $(REF_ALTTEXT output range, isOutputRange, std, range, primitives).\n     *     fmt = A $(REF FormatSpec, std,format) which controls how the data\n     *     is displayed.\n     */\n    void toString(W)(ref W sink, const ref FormatSpec!char fmt) const\n    if (isOutputRange!(W, char))\n    {\n        switch (fmt.spec)\n        {\n            case 'b':\n                return formatBitString(sink);\n            case 's':\n                return formatBitArray(sink);\n            default:\n                throw new Exception(\"Unknown format specifier: %\" ~ fmt.spec);\n        }\n    }\n\n    // @@@DEPRECATED_2.089@@@\n    deprecated(\"To be removed by 2.089. Please use the writer overload instead.\")\n    void toString(scope void delegate(const(char)[]) sink, const ref FormatSpec!char fmt) const\n    {\n        switch (fmt.spec)\n        {\n            case 'b':\n                return formatBitString(sink);\n            case 's':\n                return formatBitArray(sink);\n            default:\n                throw new Exception(\"Unknown format specifier: %\" ~ fmt.spec);\n        }\n    }\n\n    ///\n    @system pure unittest\n    {\n        import std.format : format;\n\n        auto b = BitArray([0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]);\n\n        auto s1 = format(\"%s\", b);\n        assert(s1 == \"[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]\");\n\n        auto s2 = format(\"%b\", b);\n        assert(s2 == \"00001111_00001111\");\n    }\n\n    /***************************************\n     * Return a lazy range of the indices of set bits.\n     */\n    @property auto bitsSet() const nothrow\n    {\n        import std.algorithm.iteration : filter, map, joiner;\n        import std.range : iota;\n\n        return iota(dim).\n               filter!(i => _ptr[i])().\n               map!(i => BitsSet!size_t(_ptr[i], i * bitsPerSizeT))().\n               joiner();\n    }\n\n    ///\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n\n        auto b1 = BitArray([0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]);\n        assert(b1.bitsSet.equal([4, 5, 6, 7, 12, 13, 14, 15]));\n\n        BitArray b2;\n        b2.length = 1000;\n        b2[333] = true;\n        b2[666] = true;\n        b2[999] = true;\n        assert(b2.bitsSet.equal([333, 666, 999]));\n    }\n\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.range : iota;\n\n        BitArray b;\n        enum wordBits = size_t.sizeof * 8;\n        b = BitArray([size_t.max], 0);\n        assert(b.bitsSet.empty);\n        b = BitArray([size_t.max], 1);\n        assert(b.bitsSet.equal([0]));\n        b = BitArray([size_t.max], wordBits);\n        assert(b.bitsSet.equal(iota(wordBits)));\n        b = BitArray([size_t.max, size_t.max], wordBits);\n        assert(b.bitsSet.equal(iota(wordBits)));\n        b = BitArray([size_t.max, size_t.max], wordBits + 1);\n        assert(b.bitsSet.equal(iota(wordBits + 1)));\n        b = BitArray([size_t.max, size_t.max], wordBits * 2);\n        assert(b.bitsSet.equal(iota(wordBits * 2)));\n    }\n\n    private void formatBitString(Writer)(auto ref Writer sink) const\n    {\n        if (!length)\n            return;\n\n        auto leftover = _len % 8;\n        foreach (idx; 0 .. leftover)\n        {\n            put(sink, cast(char)(this[idx] + '0'));\n        }\n\n        if (leftover && _len > 8)\n            put(sink, \"_\");\n\n        size_t count;\n        foreach (idx; leftover .. _len)\n        {\n            put(sink, cast(char)(this[idx] + '0'));\n            if (++count == 8 && idx != _len - 1)\n            {\n                put(sink, \"_\");\n                count = 0;\n            }\n        }\n    }\n\n    private void formatBitArray(Writer)(auto ref Writer sink) const\n    {\n        put(sink, \"[\");\n        foreach (idx; 0 .. _len)\n        {\n            put(sink, cast(char)(this[idx] + '0'));\n            if (idx + 1 < _len)\n                put(sink, \", \");\n        }\n        put(sink, \"]\");\n    }\n}\n\n/// Slicing & bitsSet\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota;\n\n    bool[] buf = new bool[64 * 3];\n    buf[0 .. 64] = true;\n    BitArray b = BitArray(buf);\n    assert(b.bitsSet.equal(iota(0, 64)));\n    b <<= 64;\n    assert(b.bitsSet.equal(iota(64, 128)));\n}\n\n/// Concatenation and appending\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto b = BitArray([1, 0]);\n    b ~= true;\n    assert(b[2] == 1);\n    b ~= BitArray([0, 1]);\n    auto c = BitArray([1, 0, 1, 0, 1]);\n    assert(b == c);\n    assert(b.bitsSet.equal([0, 2, 4]));\n}\n\n/// Bit flipping\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto b = BitArray([1, 1, 0, 1]);\n    b &= BitArray([0, 1, 1, 0]);\n    assert(b.bitsSet.equal([1]));\n    b.flip;\n    assert(b.bitsSet.equal([0, 2, 3]));\n}\n\n/// String format of bitarrays\n@system unittest\n{\n    import std.format : format;\n    auto b = BitArray([1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]);\n    assert(format(\"%b\", b) == \"1_00001111_00001111\");\n}\n\n///\n@system unittest\n{\n    import std.format : format;\n\n    BitArray b;\n\n    b = BitArray([]);\n    assert(format(\"%s\", b) == \"[]\");\n    assert(format(\"%b\", b) is null);\n\n    b = BitArray([1]);\n    assert(format(\"%s\", b) == \"[1]\");\n    assert(format(\"%b\", b) == \"1\");\n\n    b = BitArray([0, 0, 0, 0]);\n    assert(format(\"%b\", b) == \"0000\");\n\n    b = BitArray([0, 0, 0, 0, 1, 1, 1, 1]);\n    assert(format(\"%s\", b) == \"[0, 0, 0, 0, 1, 1, 1, 1]\");\n    assert(format(\"%b\", b) == \"00001111\");\n\n    b = BitArray([0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]);\n    assert(format(\"%s\", b) == \"[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]\");\n    assert(format(\"%b\", b) == \"00001111_00001111\");\n\n    b = BitArray([1, 0, 0, 0, 0, 1, 1, 1, 1]);\n    assert(format(\"%b\", b) == \"1_00001111\");\n\n    b = BitArray([1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]);\n    assert(format(\"%b\", b) == \"1_00001111_00001111\");\n}\n\n/++\n    Swaps the endianness of the given integral value or character.\n  +/\nT swapEndian(T)(T val) @safe pure nothrow @nogc\nif (isIntegral!T || isSomeChar!T || isBoolean!T)\n{\n    static if (val.sizeof == 1)\n        return val;\n    else static if (isUnsigned!T)\n        return swapEndianImpl(val);\n    else static if (isIntegral!T)\n        return cast(T) swapEndianImpl(cast(Unsigned!T) val);\n    else static if (is(Unqual!T == wchar))\n        return cast(T) swapEndian(cast(ushort) val);\n    else static if (is(Unqual!T == dchar))\n        return cast(T) swapEndian(cast(uint) val);\n    else\n        static assert(0, T.stringof ~ \" unsupported by swapEndian.\");\n}\n\n///\n@safe unittest\n{\n    assert(42.swapEndian == 704643072);\n    assert(42.swapEndian.swapEndian == 42); // reflexive\n    assert(1.swapEndian == 16777216);\n\n    assert(true.swapEndian == true);\n    assert(byte(10).swapEndian == 10);\n    assert(char(10).swapEndian == 10);\n\n    assert(ushort(10).swapEndian == 2560);\n    assert(long(10).swapEndian == 720575940379279360);\n    assert(ulong(10).swapEndian == 720575940379279360);\n}\n\nprivate ushort swapEndianImpl(ushort val) @safe pure nothrow @nogc\n{\n    return ((val & 0xff00U) >> 8) |\n           ((val & 0x00ffU) << 8);\n}\n\nprivate uint swapEndianImpl(uint val) @trusted pure nothrow @nogc\n{\n    import core.bitop : bswap;\n    return bswap(val);\n}\n\nprivate ulong swapEndianImpl(ulong val) @trusted pure nothrow @nogc\n{\n    import core.bitop : bswap;\n    immutable ulong res = bswap(cast(uint) val);\n    return res << 32 | bswap(cast(uint)(val >> 32));\n}\n\n@safe unittest\n{\n    import std.meta;\n    import std.stdio;\n    static foreach (T; AliasSeq!(bool, byte, ubyte, short, ushort, int, uint, long, ulong, char, wchar, dchar))\n    {{\n        scope(failure) writeln(\"Failed type: \", T.stringof);\n        T val;\n        const T cval;\n        immutable T ival;\n\n        assert(swapEndian(swapEndian(val)) == val);\n        assert(swapEndian(swapEndian(cval)) == cval);\n        assert(swapEndian(swapEndian(ival)) == ival);\n        assert(swapEndian(swapEndian(T.min)) == T.min);\n        assert(swapEndian(swapEndian(T.max)) == T.max);\n\n        foreach (i; 2 .. 10)\n        {\n            immutable T maxI = cast(T)(T.max / i);\n            immutable T minI = cast(T)(T.min / i);\n\n            assert(swapEndian(swapEndian(maxI)) == maxI);\n\n            static if (isSigned!T)\n                assert(swapEndian(swapEndian(minI)) == minI);\n        }\n\n        static if (isSigned!T)\n            assert(swapEndian(swapEndian(cast(T) 0)) == 0);\n\n        // used to trigger BUG6354\n        static if (T.sizeof > 1 && isUnsigned!T)\n        {\n            T left = 0xffU;\n            left <<= (T.sizeof - 1) * 8;\n            T right = 0xffU;\n\n            for (size_t i = 1; i < T.sizeof; ++i)\n            {\n                assert(swapEndian(left) == right);\n                assert(swapEndian(right) == left);\n                left >>= 8;\n                right <<= 8;\n            }\n        }\n    }}\n}\n\n\nprivate union EndianSwapper(T)\nif (canSwapEndianness!T)\n{\n    Unqual!T value;\n    ubyte[T.sizeof] array;\n\n    static if (is(FloatingPointTypeOf!(Unqual!T) == float))\n        uint  intValue;\n    else static if (is(FloatingPointTypeOf!(Unqual!T) == double))\n        ulong intValue;\n\n}\n\n\n/++\n    Converts the given value from the native endianness to big endian and\n    returns it as a `ubyte[n]` where `n` is the size of the given type.\n\n    Returning a `ubyte[n]` helps prevent accidentally using a swapped value\n    as a regular one (and in the case of floating point values, it's necessary,\n    because the FPU will mess up any swapped floating point values. So, you\n    can't actually have swapped floating point values as floating point values).\n\n    `real` is not supported, because its size is implementation-dependent\n    and therefore could vary from machine to machine (which could make it\n    unusable if you tried to transfer it to another machine).\n  +/\nauto nativeToBigEndian(T)(T val) @safe pure nothrow @nogc\nif (canSwapEndianness!T)\n{\n    return nativeToBigEndianImpl(val);\n}\n\n///\n@safe unittest\n{\n    int i = 12345;\n    ubyte[4] swappedI = nativeToBigEndian(i);\n    assert(i == bigEndianToNative!int(swappedI));\n\n    float f = 123.45f;\n    ubyte[4] swappedF = nativeToBigEndian(f);\n    assert(f == bigEndianToNative!float(swappedF));\n\n    const float cf = 123.45f;\n    ubyte[4] swappedCF = nativeToBigEndian(cf);\n    assert(cf == bigEndianToNative!float(swappedCF));\n\n    double d = 123.45;\n    ubyte[8] swappedD = nativeToBigEndian(d);\n    assert(d == bigEndianToNative!double(swappedD));\n\n    const double cd = 123.45;\n    ubyte[8] swappedCD = nativeToBigEndian(cd);\n    assert(cd == bigEndianToNative!double(swappedCD));\n}\n\nprivate auto nativeToBigEndianImpl(T)(T val) @safe pure nothrow @nogc\nif (isIntegral!T || isSomeChar!T || isBoolean!T)\n{\n    EndianSwapper!T es = void;\n\n    version (LittleEndian)\n        es.value = swapEndian(val);\n    else\n        es.value = val;\n\n    return es.array;\n}\n\nprivate auto nativeToBigEndianImpl(T)(T val) @safe pure nothrow @nogc\nif (isFloatOrDouble!T)\n{\n    version (LittleEndian)\n        return floatEndianImpl!(T, true)(val);\n    else\n        return floatEndianImpl!(T, false)(val);\n}\n\n@safe unittest\n{\n    import std.meta;\n    import std.stdio;\n    static foreach (T; AliasSeq!(bool, byte, ubyte, short, ushort, int, uint, long, ulong,\n                         char, wchar, dchar\n        /* The trouble here is with floats and doubles being compared against nan\n         * using a bit compare. There are two kinds of nans, quiet and signaling.\n         * When a nan passes through the x87, it converts signaling to quiet.\n         * When a nan passes through the XMM, it does not convert signaling to quiet.\n         * float.init is a signaling nan.\n         * The binary API sometimes passes the data through the XMM, sometimes through\n         * the x87, meaning these will fail the 'is' bit compare under some circumstances.\n         * I cannot think of a fix for this that makes consistent sense.\n         */\n                          /*,float, double*/))\n    {{\n        scope(failure) writeln(\"Failed type: \", T.stringof);\n        T val;\n        const T cval;\n        immutable T ival;\n\n        //is instead of == because of NaN for floating point values.\n        assert(bigEndianToNative!T(nativeToBigEndian(val)) is val);\n        assert(bigEndianToNative!T(nativeToBigEndian(cval)) is cval);\n        assert(bigEndianToNative!T(nativeToBigEndian(ival)) is ival);\n        assert(bigEndianToNative!T(nativeToBigEndian(T.min)) == T.min);\n        assert(bigEndianToNative!T(nativeToBigEndian(T.max)) == T.max);\n\n        static if (isSigned!T)\n            assert(bigEndianToNative!T(nativeToBigEndian(cast(T) 0)) == 0);\n\n        static if (!is(T == bool))\n        {\n            foreach (i; [2, 4, 6, 7, 9, 11])\n            {\n                immutable T maxI = cast(T)(T.max / i);\n                immutable T minI = cast(T)(T.min / i);\n\n                assert(bigEndianToNative!T(nativeToBigEndian(maxI)) == maxI);\n\n                static if (T.sizeof > 1)\n                    assert(nativeToBigEndian(maxI) != nativeToLittleEndian(maxI));\n                else\n                    assert(nativeToBigEndian(maxI) == nativeToLittleEndian(maxI));\n\n                static if (isSigned!T)\n                {\n                    assert(bigEndianToNative!T(nativeToBigEndian(minI)) == minI);\n\n                    static if (T.sizeof > 1)\n                        assert(nativeToBigEndian(minI) != nativeToLittleEndian(minI));\n                    else\n                        assert(nativeToBigEndian(minI) == nativeToLittleEndian(minI));\n                }\n            }\n        }\n\n        static if (isUnsigned!T || T.sizeof == 1 || is(T == wchar))\n            assert(nativeToBigEndian(T.max) == nativeToLittleEndian(T.max));\n        else\n            assert(nativeToBigEndian(T.max) != nativeToLittleEndian(T.max));\n\n        static if (isUnsigned!T || T.sizeof == 1 || isSomeChar!T)\n            assert(nativeToBigEndian(T.min) == nativeToLittleEndian(T.min));\n        else\n            assert(nativeToBigEndian(T.min) != nativeToLittleEndian(T.min));\n    }}\n}\n\n\n/++\n    Converts the given value from big endian to the native endianness and\n    returns it. The value is given as a `ubyte[n]` where `n` is the size\n    of the target type. You must give the target type as a template argument,\n    because there are multiple types with the same size and so the type of the\n    argument is not enough to determine the return type.\n\n    Taking a `ubyte[n]` helps prevent accidentally using a swapped value\n    as a regular one (and in the case of floating point values, it's necessary,\n    because the FPU will mess up any swapped floating point values. So, you\n    can't actually have swapped floating point values as floating point values).\n  +/\nT bigEndianToNative(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc\nif (canSwapEndianness!T && n == T.sizeof)\n{\n    return bigEndianToNativeImpl!(T, n)(val);\n}\n\n///\n@safe unittest\n{\n    ushort i = 12345;\n    ubyte[2] swappedI = nativeToBigEndian(i);\n    assert(i == bigEndianToNative!ushort(swappedI));\n\n    dchar c = 'D';\n    ubyte[4] swappedC = nativeToBigEndian(c);\n    assert(c == bigEndianToNative!dchar(swappedC));\n}\n\nprivate T bigEndianToNativeImpl(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc\nif ((isIntegral!T || isSomeChar!T || isBoolean!T) &&\n    n == T.sizeof)\n{\n    EndianSwapper!T es = void;\n    es.array = val;\n\n    version (LittleEndian)\n        immutable retval = swapEndian(es.value);\n    else\n        immutable retval = es.value;\n\n    return retval;\n}\n\nprivate T bigEndianToNativeImpl(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc\nif (isFloatOrDouble!T && n == T.sizeof)\n{\n    version (LittleEndian)\n        return cast(T) floatEndianImpl!(n, true)(val);\n    else\n        return cast(T) floatEndianImpl!(n, false)(val);\n}\n\n\n/++\n    Converts the given value from the native endianness to little endian and\n    returns it as a `ubyte[n]` where `n` is the size of the given type.\n\n    Returning a `ubyte[n]` helps prevent accidentally using a swapped value\n    as a regular one (and in the case of floating point values, it's necessary,\n    because the FPU will mess up any swapped floating point values. So, you\n    can't actually have swapped floating point values as floating point values).\n  +/\nauto nativeToLittleEndian(T)(T val) @safe pure nothrow @nogc\nif (canSwapEndianness!T)\n{\n    return nativeToLittleEndianImpl(val);\n}\n\n///\n@safe unittest\n{\n    int i = 12345;\n    ubyte[4] swappedI = nativeToLittleEndian(i);\n    assert(i == littleEndianToNative!int(swappedI));\n\n    double d = 123.45;\n    ubyte[8] swappedD = nativeToLittleEndian(d);\n    assert(d == littleEndianToNative!double(swappedD));\n}\n\nprivate auto nativeToLittleEndianImpl(T)(T val) @safe pure nothrow @nogc\nif (isIntegral!T || isSomeChar!T || isBoolean!T)\n{\n    EndianSwapper!T es = void;\n\n    version (BigEndian)\n        es.value = swapEndian(val);\n    else\n        es.value = val;\n\n    return es.array;\n}\n\nprivate auto nativeToLittleEndianImpl(T)(T val) @safe pure nothrow @nogc\nif (isFloatOrDouble!T)\n{\n    version (BigEndian)\n        return floatEndianImpl!(T, true)(val);\n    else\n        return floatEndianImpl!(T, false)(val);\n}\n\n@safe unittest\n{\n    import std.meta;\n    import std.stdio;\n    static foreach (T; AliasSeq!(bool, byte, ubyte, short, ushort, int, uint, long, ulong,\n                         char, wchar, dchar/*,\n                         float, double*/))\n    {{\n        scope(failure) writeln(\"Failed type: \", T.stringof);\n        T val;\n        const T cval;\n        immutable T ival;\n\n        //is instead of == because of NaN for floating point values.\n        assert(littleEndianToNative!T(nativeToLittleEndian(val)) is val);\n        assert(littleEndianToNative!T(nativeToLittleEndian(cval)) is cval);\n        assert(littleEndianToNative!T(nativeToLittleEndian(ival)) is ival);\n        assert(littleEndianToNative!T(nativeToLittleEndian(T.min)) == T.min);\n        assert(littleEndianToNative!T(nativeToLittleEndian(T.max)) == T.max);\n\n        static if (isSigned!T)\n            assert(littleEndianToNative!T(nativeToLittleEndian(cast(T) 0)) == 0);\n\n        static if (!is(T == bool))\n        {\n            foreach (i; 2 .. 10)\n            {\n                immutable T maxI = cast(T)(T.max / i);\n                immutable T minI = cast(T)(T.min / i);\n\n                assert(littleEndianToNative!T(nativeToLittleEndian(maxI)) == maxI);\n\n                static if (isSigned!T)\n                    assert(littleEndianToNative!T(nativeToLittleEndian(minI)) == minI);\n            }\n        }\n    }}\n}\n\n\n/++\n    Converts the given value from little endian to the native endianness and\n    returns it. The value is given as a `ubyte[n]` where `n` is the size\n    of the target type. You must give the target type as a template argument,\n    because there are multiple types with the same size and so the type of the\n    argument is not enough to determine the return type.\n\n    Taking a `ubyte[n]` helps prevent accidentally using a swapped value\n    as a regular one (and in the case of floating point values, it's necessary,\n    because the FPU will mess up any swapped floating point values. So, you\n    can't actually have swapped floating point values as floating point values).\n\n    `real` is not supported, because its size is implementation-dependent\n    and therefore could vary from machine to machine (which could make it\n    unusable if you tried to transfer it to another machine).\n  +/\nT littleEndianToNative(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc\nif (canSwapEndianness!T && n == T.sizeof)\n{\n    return littleEndianToNativeImpl!T(val);\n}\n\n///\n@safe unittest\n{\n    ushort i = 12345;\n    ubyte[2] swappedI = nativeToLittleEndian(i);\n    assert(i == littleEndianToNative!ushort(swappedI));\n\n    dchar c = 'D';\n    ubyte[4] swappedC = nativeToLittleEndian(c);\n    assert(c == littleEndianToNative!dchar(swappedC));\n}\n\nprivate T littleEndianToNativeImpl(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc\nif ((isIntegral!T || isSomeChar!T || isBoolean!T) &&\n    n == T.sizeof)\n{\n    EndianSwapper!T es = void;\n    es.array = val;\n\n    version (BigEndian)\n        immutable retval = swapEndian(es.value);\n    else\n        immutable retval = es.value;\n\n    return retval;\n}\n\nprivate T littleEndianToNativeImpl(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc\nif (((isFloatOrDouble!T) &&\n    n == T.sizeof))\n{\n    version (BigEndian)\n        return floatEndianImpl!(n, true)(val);\n    else\n        return floatEndianImpl!(n, false)(val);\n}\n\nprivate auto floatEndianImpl(T, bool swap)(T val) @safe pure nothrow @nogc\nif (isFloatOrDouble!T)\n{\n    EndianSwapper!T es = void;\n    es.value = val;\n\n    static if (swap)\n        es.intValue = swapEndian(es.intValue);\n\n    return es.array;\n}\n\nprivate auto floatEndianImpl(size_t n, bool swap)(ubyte[n] val) @safe pure nothrow @nogc\nif (n == 4 || n == 8)\n{\n    static if (n == 4)       EndianSwapper!float es = void;\n    else static if (n == 8)  EndianSwapper!double es = void;\n\n    es.array = val;\n\n    static if (swap)\n        es.intValue = swapEndian(es.intValue);\n\n    return es.value;\n}\n\nprivate template isFloatOrDouble(T)\n{\n    enum isFloatOrDouble = isFloatingPoint!T &&\n                           !is(Unqual!(FloatingPointTypeOf!T) == real);\n}\n\n@safe unittest\n{\n    import std.meta;\n    static foreach (T; AliasSeq!(float, double))\n    {\n        static assert(isFloatOrDouble!(T));\n        static assert(isFloatOrDouble!(const T));\n        static assert(isFloatOrDouble!(immutable T));\n        static assert(isFloatOrDouble!(shared T));\n        static assert(isFloatOrDouble!(shared(const T)));\n        static assert(isFloatOrDouble!(shared(immutable T)));\n    }\n\n    static assert(!isFloatOrDouble!(real));\n    static assert(!isFloatOrDouble!(const real));\n    static assert(!isFloatOrDouble!(immutable real));\n    static assert(!isFloatOrDouble!(shared real));\n    static assert(!isFloatOrDouble!(shared(const real)));\n    static assert(!isFloatOrDouble!(shared(immutable real)));\n}\n\nprivate template canSwapEndianness(T)\n{\n    enum canSwapEndianness = isIntegral!T ||\n                             isSomeChar!T ||\n                             isBoolean!T ||\n                             isFloatOrDouble!T;\n}\n\n@safe unittest\n{\n    import std.meta;\n    static foreach (T; AliasSeq!(bool, ubyte, byte, ushort, short, uint, int, ulong,\n                         long, char, wchar, dchar, float, double))\n    {\n        static assert(canSwapEndianness!(T));\n        static assert(canSwapEndianness!(const T));\n        static assert(canSwapEndianness!(immutable T));\n        static assert(canSwapEndianness!(shared(T)));\n        static assert(canSwapEndianness!(shared(const T)));\n        static assert(canSwapEndianness!(shared(immutable T)));\n    }\n\n    //!\n    static foreach (T; AliasSeq!(real, string, wstring, dstring))\n    {\n        static assert(!canSwapEndianness!(T));\n        static assert(!canSwapEndianness!(const T));\n        static assert(!canSwapEndianness!(immutable T));\n        static assert(!canSwapEndianness!(shared(T)));\n        static assert(!canSwapEndianness!(shared(const T)));\n        static assert(!canSwapEndianness!(shared(immutable T)));\n    }\n}\n\n/++\n    Takes a range of `ubyte`s and converts the first `T.sizeof` bytes to\n    `T`. The value returned is converted from the given endianness to the\n    native endianness. The range is not consumed.\n\n    Params:\n        T     = The integral type to convert the first `T.sizeof` bytes to.\n        endianness = The endianness that the bytes are assumed to be in.\n        range = The range to read from.\n        index = The index to start reading from (instead of starting at the\n                front). If index is a pointer, then it is updated to the index\n                after the bytes read. The overloads with index are only\n                available if `hasSlicing!R` is `true`.\n  +/\n\nT peek(T, Endian endianness = Endian.bigEndian, R)(R range)\nif (canSwapEndianness!T &&\n    isForwardRange!R &&\n    is(ElementType!R : const ubyte))\n{\n    static if (hasSlicing!R)\n        const ubyte[T.sizeof] bytes = range[0 .. T.sizeof];\n    else\n    {\n        ubyte[T.sizeof] bytes;\n        //Make sure that range is not consumed, even if it's a class.\n        range = range.save;\n\n        foreach (ref e; bytes)\n        {\n            e = range.front;\n            range.popFront();\n        }\n    }\n\n    static if (endianness == Endian.bigEndian)\n        return bigEndianToNative!T(bytes);\n    else\n        return littleEndianToNative!T(bytes);\n}\n\n/++ Ditto +/\nT peek(T, Endian endianness = Endian.bigEndian, R)(R range, size_t index)\nif (canSwapEndianness!T &&\n    isForwardRange!R &&\n    hasSlicing!R &&\n    is(ElementType!R : const ubyte))\n{\n    return peek!(T, endianness)(range, &index);\n}\n\n/++ Ditto +/\nT peek(T, Endian endianness = Endian.bigEndian, R)(R range, size_t* index)\nif (canSwapEndianness!T &&\n    isForwardRange!R &&\n    hasSlicing!R &&\n    is(ElementType!R : const ubyte))\n{\n    assert(index);\n\n    immutable begin = *index;\n    immutable end = begin + T.sizeof;\n    const ubyte[T.sizeof] bytes = range[begin .. end];\n    *index = end;\n\n    static if (endianness == Endian.bigEndian)\n        return bigEndianToNative!T(bytes);\n    else\n        return littleEndianToNative!T(bytes);\n}\n\n///\n@system unittest\n{\n    ubyte[] buffer = [1, 5, 22, 9, 44, 255, 8];\n    assert(buffer.peek!uint() == 17110537);\n    assert(buffer.peek!ushort() == 261);\n    assert(buffer.peek!ubyte() == 1);\n\n    assert(buffer.peek!uint(2) == 369700095);\n    assert(buffer.peek!ushort(2) == 5641);\n    assert(buffer.peek!ubyte(2) == 22);\n\n    size_t index = 0;\n    assert(buffer.peek!ushort(&index) == 261);\n    assert(index == 2);\n\n    assert(buffer.peek!uint(&index) == 369700095);\n    assert(index == 6);\n\n    assert(buffer.peek!ubyte(&index) == 8);\n    assert(index == 7);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.iteration : filter;\n    ubyte[] buffer = [1, 5, 22, 9, 44, 255, 7];\n    auto range = filter!\"true\"(buffer);\n    assert(range.peek!uint() == 17110537);\n    assert(range.peek!ushort() == 261);\n    assert(range.peek!ubyte() == 1);\n}\n\n@system unittest\n{\n    {\n        //bool\n        ubyte[] buffer = [0, 1];\n        assert(buffer.peek!bool() == false);\n        assert(buffer.peek!bool(1) == true);\n\n        size_t index = 0;\n        assert(buffer.peek!bool(&index) == false);\n        assert(index == 1);\n\n        assert(buffer.peek!bool(&index) == true);\n        assert(index == 2);\n    }\n\n    {\n        //char (8bit)\n        ubyte[] buffer = [97, 98, 99, 100];\n        assert(buffer.peek!char() == 'a');\n        assert(buffer.peek!char(1) == 'b');\n\n        size_t index = 0;\n        assert(buffer.peek!char(&index) == 'a');\n        assert(index == 1);\n\n        assert(buffer.peek!char(&index) == 'b');\n        assert(index == 2);\n    }\n\n    {\n        //wchar (16bit - 2x ubyte)\n        ubyte[] buffer = [1, 5, 32, 29, 1, 7];\n        assert(buffer.peek!wchar() == 'ą');\n        assert(buffer.peek!wchar(2) == '”');\n        assert(buffer.peek!wchar(4) == 'ć');\n\n        size_t index = 0;\n        assert(buffer.peek!wchar(&index) == 'ą');\n        assert(index == 2);\n\n        assert(buffer.peek!wchar(&index) == '”');\n        assert(index == 4);\n\n        assert(buffer.peek!wchar(&index) == 'ć');\n        assert(index == 6);\n    }\n\n    {\n        //dchar (32bit - 4x ubyte)\n        ubyte[] buffer = [0, 0, 1, 5, 0, 0, 32, 29, 0, 0, 1, 7];\n        assert(buffer.peek!dchar() == 'ą');\n        assert(buffer.peek!dchar(4) == '”');\n        assert(buffer.peek!dchar(8) == 'ć');\n\n        size_t index = 0;\n        assert(buffer.peek!dchar(&index) == 'ą');\n        assert(index == 4);\n\n        assert(buffer.peek!dchar(&index) == '”');\n        assert(index == 8);\n\n        assert(buffer.peek!dchar(&index) == 'ć');\n        assert(index == 12);\n    }\n\n    {\n        //float (32bit - 4x ubyte)\n        ubyte[] buffer = [66, 0, 0, 0, 65, 200, 0, 0];\n        assert(buffer.peek!float()== 32.0);\n        assert(buffer.peek!float(4) == 25.0f);\n\n        size_t index = 0;\n        assert(buffer.peek!float(&index) == 32.0f);\n        assert(index == 4);\n\n        assert(buffer.peek!float(&index) == 25.0f);\n        assert(index == 8);\n    }\n\n    {\n        //double (64bit - 8x ubyte)\n        ubyte[] buffer = [64, 64, 0, 0, 0, 0, 0, 0, 64, 57, 0, 0, 0, 0, 0, 0];\n        assert(buffer.peek!double() == 32.0);\n        assert(buffer.peek!double(8) == 25.0);\n\n        size_t index = 0;\n        assert(buffer.peek!double(&index) == 32.0);\n        assert(index == 8);\n\n        assert(buffer.peek!double(&index) == 25.0);\n        assert(index == 16);\n    }\n\n    {\n        //enum\n        ubyte[] buffer = [0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30];\n\n        enum Foo\n        {\n            one = 10,\n            two = 20,\n            three = 30\n        }\n\n        assert(buffer.peek!Foo() == Foo.one);\n        assert(buffer.peek!Foo(0) == Foo.one);\n        assert(buffer.peek!Foo(4) == Foo.two);\n        assert(buffer.peek!Foo(8) == Foo.three);\n\n        size_t index = 0;\n        assert(buffer.peek!Foo(&index) == Foo.one);\n        assert(index == 4);\n\n        assert(buffer.peek!Foo(&index) == Foo.two);\n        assert(index == 8);\n\n        assert(buffer.peek!Foo(&index) == Foo.three);\n        assert(index == 12);\n    }\n\n    {\n        //enum - bool\n        ubyte[] buffer = [0, 1];\n\n        enum Bool: bool\n        {\n            bfalse = false,\n            btrue = true,\n        }\n\n        assert(buffer.peek!Bool() == Bool.bfalse);\n        assert(buffer.peek!Bool(0) == Bool.bfalse);\n        assert(buffer.peek!Bool(1) == Bool.btrue);\n\n        size_t index = 0;\n        assert(buffer.peek!Bool(&index) == Bool.bfalse);\n        assert(index == 1);\n\n        assert(buffer.peek!Bool(&index) == Bool.btrue);\n        assert(index == 2);\n    }\n\n    {\n        //enum - float\n        ubyte[] buffer = [66, 0, 0, 0, 65, 200, 0, 0];\n\n        enum Float: float\n        {\n            one = 32.0f,\n            two = 25.0f\n        }\n\n        assert(buffer.peek!Float() == Float.one);\n        assert(buffer.peek!Float(0) == Float.one);\n        assert(buffer.peek!Float(4) == Float.two);\n\n        size_t index = 0;\n        assert(buffer.peek!Float(&index) == Float.one);\n        assert(index == 4);\n\n        assert(buffer.peek!Float(&index) == Float.two);\n        assert(index == 8);\n    }\n\n    {\n        //enum - double\n        ubyte[] buffer = [64, 64, 0, 0, 0, 0, 0, 0, 64, 57, 0, 0, 0, 0, 0, 0];\n\n        enum Double: double\n        {\n            one = 32.0,\n            two = 25.0\n        }\n\n        assert(buffer.peek!Double() == Double.one);\n        assert(buffer.peek!Double(0) == Double.one);\n        assert(buffer.peek!Double(8) == Double.two);\n\n        size_t index = 0;\n        assert(buffer.peek!Double(&index) == Double.one);\n        assert(index == 8);\n\n        assert(buffer.peek!Double(&index) == Double.two);\n        assert(index == 16);\n    }\n\n    {\n        //enum - real\n        ubyte[] buffer = [64, 64, 0, 0, 0, 0, 0, 0, 64, 57, 0, 0, 0, 0, 0, 0];\n\n        enum Real: real\n        {\n            one = 32.0,\n            two = 25.0\n        }\n\n        static assert(!__traits(compiles, buffer.peek!Real()));\n    }\n}\n\n/++\n    Takes a range of `ubyte`s and converts the first `T.sizeof` bytes to\n    `T`. The value returned is converted from the given endianness to the\n    native endianness. The `T.sizeof` bytes which are read are consumed from\n    the range.\n\n    Params:\n        T     = The integral type to convert the first `T.sizeof` bytes to.\n        endianness = The endianness that the bytes are assumed to be in.\n        range = The range to read from.\n  +/\nT read(T, Endian endianness = Endian.bigEndian, R)(ref R range)\nif (canSwapEndianness!T && isInputRange!R && is(ElementType!R : const ubyte))\n{\n    static if (hasSlicing!R && is(typeof(R.init[0 .. 0]) : const(ubyte)[]))\n    {\n        const ubyte[T.sizeof] bytes = range[0 .. T.sizeof];\n        range.popFrontN(T.sizeof);\n    }\n    else\n    {\n        ubyte[T.sizeof] bytes;\n\n        foreach (ref e; bytes)\n        {\n            e = range.front;\n            range.popFront();\n        }\n    }\n\n    static if (endianness == Endian.bigEndian)\n        return bigEndianToNative!T(bytes);\n    else\n        return littleEndianToNative!T(bytes);\n}\n\n///\n@safe unittest\n{\n    import std.range.primitives : empty;\n    ubyte[] buffer = [1, 5, 22, 9, 44, 255, 8];\n    assert(buffer.length == 7);\n\n    assert(buffer.read!ushort() == 261);\n    assert(buffer.length == 5);\n\n    assert(buffer.read!uint() == 369700095);\n    assert(buffer.length == 1);\n\n    assert(buffer.read!ubyte() == 8);\n    assert(buffer.empty);\n}\n\n@safe unittest\n{\n    {\n        //bool\n        ubyte[] buffer = [0, 1];\n        assert(buffer.length == 2);\n\n        assert(buffer.read!bool() == false);\n        assert(buffer.length == 1);\n\n        assert(buffer.read!bool() == true);\n        assert(buffer.empty);\n    }\n\n    {\n        //char (8bit)\n        ubyte[] buffer = [97, 98, 99];\n        assert(buffer.length == 3);\n\n        assert(buffer.read!char() == 'a');\n        assert(buffer.length == 2);\n\n        assert(buffer.read!char() == 'b');\n        assert(buffer.length == 1);\n\n        assert(buffer.read!char() == 'c');\n        assert(buffer.empty);\n    }\n\n    {\n        //wchar (16bit - 2x ubyte)\n        ubyte[] buffer = [1, 5, 32, 29, 1, 7];\n        assert(buffer.length == 6);\n\n        assert(buffer.read!wchar() == 'ą');\n        assert(buffer.length == 4);\n\n        assert(buffer.read!wchar() == '”');\n        assert(buffer.length == 2);\n\n        assert(buffer.read!wchar() == 'ć');\n        assert(buffer.empty);\n    }\n\n    {\n        //dchar (32bit - 4x ubyte)\n        ubyte[] buffer = [0, 0, 1, 5, 0, 0, 32, 29, 0, 0, 1, 7];\n        assert(buffer.length == 12);\n\n        assert(buffer.read!dchar() == 'ą');\n        assert(buffer.length == 8);\n\n        assert(buffer.read!dchar() == '”');\n        assert(buffer.length == 4);\n\n        assert(buffer.read!dchar() == 'ć');\n        assert(buffer.empty);\n    }\n\n    {\n        //float (32bit - 4x ubyte)\n        ubyte[] buffer = [66, 0, 0, 0, 65, 200, 0, 0];\n        assert(buffer.length == 8);\n\n        assert(buffer.read!float()== 32.0);\n        assert(buffer.length == 4);\n\n        assert(buffer.read!float() == 25.0f);\n        assert(buffer.empty);\n    }\n\n    {\n        //double (64bit - 8x ubyte)\n        ubyte[] buffer = [64, 64, 0, 0, 0, 0, 0, 0, 64, 57, 0, 0, 0, 0, 0, 0];\n        assert(buffer.length == 16);\n\n        assert(buffer.read!double() == 32.0);\n        assert(buffer.length == 8);\n\n        assert(buffer.read!double() == 25.0);\n        assert(buffer.empty);\n    }\n\n    {\n        //enum - uint\n        ubyte[] buffer = [0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30];\n        assert(buffer.length == 12);\n\n        enum Foo\n        {\n            one = 10,\n            two = 20,\n            three = 30\n        }\n\n        assert(buffer.read!Foo() == Foo.one);\n        assert(buffer.length == 8);\n\n        assert(buffer.read!Foo() == Foo.two);\n        assert(buffer.length == 4);\n\n        assert(buffer.read!Foo() == Foo.three);\n        assert(buffer.empty);\n    }\n\n    {\n        //enum - bool\n        ubyte[] buffer = [0, 1];\n        assert(buffer.length == 2);\n\n        enum Bool: bool\n        {\n            bfalse = false,\n            btrue = true,\n        }\n\n        assert(buffer.read!Bool() == Bool.bfalse);\n        assert(buffer.length == 1);\n\n        assert(buffer.read!Bool() == Bool.btrue);\n        assert(buffer.empty);\n    }\n\n    {\n        //enum - float\n        ubyte[] buffer = [66, 0, 0, 0, 65, 200, 0, 0];\n        assert(buffer.length == 8);\n\n        enum Float: float\n        {\n            one = 32.0f,\n            two = 25.0f\n        }\n\n        assert(buffer.read!Float() == Float.one);\n        assert(buffer.length == 4);\n\n        assert(buffer.read!Float() == Float.two);\n        assert(buffer.empty);\n    }\n\n    {\n        //enum - double\n        ubyte[] buffer = [64, 64, 0, 0, 0, 0, 0, 0, 64, 57, 0, 0, 0, 0, 0, 0];\n        assert(buffer.length == 16);\n\n        enum Double: double\n        {\n            one = 32.0,\n            two = 25.0\n        }\n\n        assert(buffer.read!Double() == Double.one);\n        assert(buffer.length == 8);\n\n        assert(buffer.read!Double() == Double.two);\n        assert(buffer.empty);\n    }\n\n    {\n        //enum - real\n        ubyte[] buffer = [64, 64, 0, 0, 0, 0, 0, 0, 64, 57, 0, 0, 0, 0, 0, 0];\n\n        enum Real: real\n        {\n            one = 32.0,\n            two = 25.0\n        }\n\n        static assert(!__traits(compiles, buffer.read!Real()));\n    }\n}\n\n// issue 17247\n@safe unittest\n{\n    struct UbyteRange\n    {\n        ubyte[] impl;\n        @property bool empty() { return impl.empty; }\n        @property ubyte front() { return impl.front; }\n        void popFront() { impl.popFront(); }\n        @property UbyteRange save() { return this; }\n\n        // N.B. support slicing but do not return ubyte[] slices.\n        UbyteRange opSlice(size_t start, size_t end)\n        {\n            return UbyteRange(impl[start .. end]);\n        }\n        @property size_t length() { return impl.length; }\n        size_t opDollar() { return impl.length; }\n    }\n    static assert(hasSlicing!UbyteRange);\n\n    auto r = UbyteRange([0x01, 0x00, 0x00, 0x00]);\n    int x = r.read!(int, Endian.littleEndian)();\n    assert(x == 1);\n}\n\n\n/++\n    Takes an integral value, converts it to the given endianness, and writes it\n    to the given range of `ubyte`s as a sequence of `T.sizeof` `ubyte`s\n    starting at index. `hasSlicing!R` must be `true`.\n\n    Params:\n        T     = The integral type to convert the first `T.sizeof` bytes to.\n        endianness = The endianness to _write the bytes in.\n        range = The range to _write to.\n        value = The value to _write.\n        index = The index to start writing to. If index is a pointer, then it\n                is updated to the index after the bytes read.\n  +/\nvoid write(T, Endian endianness = Endian.bigEndian, R)(R range, T value, size_t index)\nif (canSwapEndianness!T &&\n    isForwardRange!R &&\n    hasSlicing!R &&\n    is(ElementType!R : ubyte))\n{\n    write!(T, endianness)(range, value, &index);\n}\n\n/++ Ditto +/\nvoid write(T, Endian endianness = Endian.bigEndian, R)(R range, T value, size_t* index)\nif (canSwapEndianness!T &&\n    isForwardRange!R &&\n    hasSlicing!R &&\n    is(ElementType!R : ubyte))\n{\n    assert(index);\n\n    static if (endianness == Endian.bigEndian)\n        immutable bytes = nativeToBigEndian!T(value);\n    else\n        immutable bytes = nativeToLittleEndian!T(value);\n\n    immutable begin = *index;\n    immutable end = begin + T.sizeof;\n    *index = end;\n    range[begin .. end] = bytes[0 .. T.sizeof];\n}\n\n///\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0, 0, 0, 0, 0, 0];\n    buffer.write!uint(29110231u, 0);\n    assert(buffer == [1, 188, 47, 215, 0, 0, 0, 0]);\n\n    buffer.write!ushort(927, 0);\n    assert(buffer == [3, 159, 47, 215, 0, 0, 0, 0]);\n\n    buffer.write!ubyte(42, 0);\n    assert(buffer == [42, 159, 47, 215, 0, 0, 0, 0]);\n}\n\n///\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0, 0, 0, 0, 0, 0, 0];\n    buffer.write!uint(142700095u, 2);\n    assert(buffer == [0, 0, 8, 129, 110, 63, 0, 0, 0]);\n\n    buffer.write!ushort(19839, 2);\n    assert(buffer == [0, 0, 77, 127, 110, 63, 0, 0, 0]);\n\n    buffer.write!ubyte(132, 2);\n    assert(buffer == [0, 0, 132, 127, 110, 63, 0, 0, 0]);\n}\n\n///\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0, 0, 0, 0, 0, 0];\n    size_t index = 0;\n    buffer.write!ushort(261, &index);\n    assert(buffer == [1, 5, 0, 0, 0, 0, 0, 0]);\n    assert(index == 2);\n\n    buffer.write!uint(369700095u, &index);\n    assert(buffer == [1, 5, 22, 9, 44, 255, 0, 0]);\n    assert(index == 6);\n\n    buffer.write!ubyte(8, &index);\n    assert(buffer == [1, 5, 22, 9, 44, 255, 8, 0]);\n    assert(index == 7);\n}\n\n/// bool\n@system unittest\n{\n    ubyte[] buffer = [0, 0];\n    buffer.write!bool(false, 0);\n    assert(buffer == [0, 0]);\n\n    buffer.write!bool(true, 0);\n    assert(buffer == [1, 0]);\n\n    buffer.write!bool(true, 1);\n    assert(buffer == [1, 1]);\n\n    buffer.write!bool(false, 1);\n    assert(buffer == [1, 0]);\n\n    size_t index = 0;\n    buffer.write!bool(false, &index);\n    assert(buffer == [0, 0]);\n    assert(index == 1);\n\n    buffer.write!bool(true, &index);\n    assert(buffer == [0, 1]);\n    assert(index == 2);\n}\n\n/// char(8-bit)\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0];\n\n    buffer.write!char('a', 0);\n    assert(buffer == [97, 0, 0]);\n\n    buffer.write!char('b', 1);\n    assert(buffer == [97, 98, 0]);\n\n    size_t index = 0;\n    buffer.write!char('a', &index);\n    assert(buffer == [97, 98, 0]);\n    assert(index == 1);\n\n    buffer.write!char('b', &index);\n    assert(buffer == [97, 98, 0]);\n    assert(index == 2);\n\n    buffer.write!char('c', &index);\n    assert(buffer == [97, 98, 99]);\n    assert(index == 3);\n}\n\n/// wchar (16bit - 2x ubyte)\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0, 0];\n\n    buffer.write!wchar('ą', 0);\n    assert(buffer == [1, 5, 0, 0]);\n\n    buffer.write!wchar('”', 2);\n    assert(buffer == [1, 5, 32, 29]);\n\n    size_t index = 0;\n    buffer.write!wchar('ć', &index);\n    assert(buffer == [1, 7, 32, 29]);\n    assert(index == 2);\n\n    buffer.write!wchar('ą', &index);\n    assert(buffer == [1, 7, 1, 5]);\n    assert(index == 4);\n}\n\n/// dchar (32bit - 4x ubyte)\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0, 0, 0, 0, 0, 0];\n\n    buffer.write!dchar('ą', 0);\n    assert(buffer == [0, 0, 1, 5, 0, 0, 0, 0]);\n\n    buffer.write!dchar('”', 4);\n    assert(buffer == [0, 0, 1, 5, 0, 0, 32, 29]);\n\n    size_t index = 0;\n    buffer.write!dchar('ć', &index);\n    assert(buffer == [0, 0, 1, 7, 0, 0, 32, 29]);\n    assert(index == 4);\n\n    buffer.write!dchar('ą', &index);\n    assert(buffer == [0, 0, 1, 7, 0, 0, 1, 5]);\n    assert(index == 8);\n}\n\n/// float (32bit - 4x ubyte)\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0, 0, 0, 0, 0, 0];\n\n    buffer.write!float(32.0f, 0);\n    assert(buffer == [66, 0, 0, 0, 0, 0, 0, 0]);\n\n    buffer.write!float(25.0f, 4);\n    assert(buffer == [66, 0, 0, 0, 65, 200, 0, 0]);\n\n    size_t index = 0;\n    buffer.write!float(25.0f, &index);\n    assert(buffer == [65, 200, 0, 0, 65, 200, 0, 0]);\n    assert(index == 4);\n\n    buffer.write!float(32.0f, &index);\n    assert(buffer == [65, 200, 0, 0, 66, 0, 0, 0]);\n    assert(index == 8);\n}\n\n/// double (64bit - 8x ubyte)\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n\n    buffer.write!double(32.0, 0);\n    assert(buffer == [64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n\n    buffer.write!double(25.0, 8);\n    assert(buffer == [64, 64, 0, 0, 0, 0, 0, 0, 64, 57, 0, 0, 0, 0, 0, 0]);\n\n    size_t index = 0;\n    buffer.write!double(25.0, &index);\n    assert(buffer == [64, 57, 0, 0, 0, 0, 0, 0, 64, 57, 0, 0, 0, 0, 0, 0]);\n    assert(index == 8);\n\n    buffer.write!double(32.0, &index);\n    assert(buffer == [64, 57, 0, 0, 0, 0, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0]);\n    assert(index == 16);\n}\n\n/// enum\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n\n    enum Foo\n    {\n        one = 10,\n        two = 20,\n        three = 30\n    }\n\n    buffer.write!Foo(Foo.one, 0);\n    assert(buffer == [0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0]);\n\n    buffer.write!Foo(Foo.two, 4);\n    assert(buffer == [0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 0]);\n\n    buffer.write!Foo(Foo.three, 8);\n    assert(buffer == [0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30]);\n\n    size_t index = 0;\n    buffer.write!Foo(Foo.three, &index);\n    assert(buffer == [0, 0, 0, 30, 0, 0, 0, 20, 0, 0, 0, 30]);\n    assert(index == 4);\n\n    buffer.write!Foo(Foo.one, &index);\n    assert(buffer == [0, 0, 0, 30, 0, 0, 0, 10, 0, 0, 0, 30]);\n    assert(index == 8);\n\n    buffer.write!Foo(Foo.two, &index);\n    assert(buffer == [0, 0, 0, 30, 0, 0, 0, 10, 0, 0, 0, 20]);\n    assert(index == 12);\n}\n\n// enum - bool\n@system unittest\n{\n    ubyte[] buffer = [0, 0];\n\n    enum Bool: bool\n    {\n        bfalse = false,\n        btrue = true,\n    }\n\n    buffer.write!Bool(Bool.btrue, 0);\n    assert(buffer == [1, 0]);\n\n    buffer.write!Bool(Bool.btrue, 1);\n    assert(buffer == [1, 1]);\n\n    size_t index = 0;\n    buffer.write!Bool(Bool.bfalse, &index);\n    assert(buffer == [0, 1]);\n    assert(index == 1);\n\n    buffer.write!Bool(Bool.bfalse, &index);\n    assert(buffer == [0, 0]);\n    assert(index == 2);\n}\n\n/// enum - float\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0, 0, 0, 0, 0, 0];\n\n    enum Float: float\n    {\n        one = 32.0f,\n        two = 25.0f\n    }\n\n    buffer.write!Float(Float.one, 0);\n    assert(buffer == [66, 0, 0, 0, 0, 0, 0, 0]);\n\n    buffer.write!Float(Float.two, 4);\n    assert(buffer == [66, 0, 0, 0, 65, 200, 0, 0]);\n\n    size_t index = 0;\n    buffer.write!Float(Float.two, &index);\n    assert(buffer == [65, 200, 0, 0, 65, 200, 0, 0]);\n    assert(index == 4);\n\n    buffer.write!Float(Float.one, &index);\n    assert(buffer == [65, 200, 0, 0, 66, 0, 0, 0]);\n    assert(index == 8);\n}\n\n/// enum - double\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n\n    enum Double: double\n    {\n        one = 32.0,\n        two = 25.0\n    }\n\n    buffer.write!Double(Double.one, 0);\n    assert(buffer == [64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n\n    buffer.write!Double(Double.two, 8);\n    assert(buffer == [64, 64, 0, 0, 0, 0, 0, 0, 64, 57, 0, 0, 0, 0, 0, 0]);\n\n    size_t index = 0;\n    buffer.write!Double(Double.two, &index);\n    assert(buffer == [64, 57, 0, 0, 0, 0, 0, 0, 64, 57, 0, 0, 0, 0, 0, 0]);\n    assert(index == 8);\n\n    buffer.write!Double(Double.one, &index);\n    assert(buffer == [64, 57, 0, 0, 0, 0, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0]);\n    assert(index == 16);\n}\n\n/// enum - real\n@system unittest\n{\n    ubyte[] buffer = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n\n    enum Real: real\n    {\n        one = 32.0,\n        two = 25.0\n    }\n\n    static assert(!__traits(compiles, buffer.write!Real(Real.one)));\n}\n\n\n/++\n    Takes an integral value, converts it to the given endianness, and appends\n    it to the given range of `ubyte`s (using `put`) as a sequence of\n    `T.sizeof` `ubyte`s starting at index. `hasSlicing!R` must be\n    `true`.\n\n    Params:\n        T     = The integral type to convert the first `T.sizeof` bytes to.\n        endianness = The endianness to write the bytes in.\n        range = The range to _append to.\n        value = The value to _append.\n  +/\nvoid append(T, Endian endianness = Endian.bigEndian, R)(R range, T value)\nif (canSwapEndianness!T && isOutputRange!(R, ubyte))\n{\n    static if (endianness == Endian.bigEndian)\n        immutable bytes = nativeToBigEndian!T(value);\n    else\n        immutable bytes = nativeToLittleEndian!T(value);\n\n    put(range, bytes[]);\n}\n\n///\n@safe unittest\n{\n    import std.array;\n    auto buffer = appender!(const ubyte[])();\n    buffer.append!ushort(261);\n    assert(buffer.data == [1, 5]);\n\n    buffer.append!uint(369700095u);\n    assert(buffer.data == [1, 5, 22, 9, 44, 255]);\n\n    buffer.append!ubyte(8);\n    assert(buffer.data == [1, 5, 22, 9, 44, 255, 8]);\n}\n\n/// bool\n@safe unittest\n{\n    import std.array : appender;\n    auto buffer = appender!(const ubyte[])();\n\n    buffer.append!bool(true);\n    assert(buffer.data == [1]);\n\n    buffer.append!bool(false);\n    assert(buffer.data == [1, 0]);\n}\n\n/// char wchar dchar\n@safe unittest\n{\n    import std.array : appender;\n    auto buffer = appender!(const ubyte[])();\n\n    buffer.append!char('a');\n    assert(buffer.data == [97]);\n\n    buffer.append!char('b');\n    assert(buffer.data == [97, 98]);\n\n    buffer.append!wchar('ą');\n    assert(buffer.data == [97, 98, 1, 5]);\n\n    buffer.append!dchar('ą');\n        assert(buffer.data == [97, 98, 1, 5, 0, 0, 1, 5]);\n}\n\n/// float double\n@safe unittest\n{\n    import std.array : appender;\n    auto buffer = appender!(const ubyte[])();\n\n    buffer.append!float(32.0f);\n    assert(buffer.data == [66, 0, 0, 0]);\n\n    buffer.append!double(32.0);\n    assert(buffer.data == [66, 0, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0]);\n}\n\n/// enum\n@safe unittest\n{\n    import std.array : appender;\n    auto buffer = appender!(const ubyte[])();\n\n    enum Foo\n    {\n        one = 10,\n        two = 20,\n        three = 30\n    }\n\n    buffer.append!Foo(Foo.one);\n    assert(buffer.data == [0, 0, 0, 10]);\n\n    buffer.append!Foo(Foo.two);\n    assert(buffer.data == [0, 0, 0, 10, 0, 0, 0, 20]);\n\n    buffer.append!Foo(Foo.three);\n    assert(buffer.data == [0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 30]);\n}\n\n/// enum - bool\n@safe unittest\n{\n    import std.array : appender;\n    auto buffer = appender!(const ubyte[])();\n\n    enum Bool: bool\n    {\n        bfalse = false,\n        btrue = true,\n    }\n\n    buffer.append!Bool(Bool.btrue);\n    assert(buffer.data == [1]);\n\n    buffer.append!Bool(Bool.bfalse);\n    assert(buffer.data == [1, 0]);\n\n    buffer.append!Bool(Bool.btrue);\n    assert(buffer.data == [1, 0, 1]);\n}\n\n/// enum - float\n@safe unittest\n{\n    import std.array : appender;\n    auto buffer = appender!(const ubyte[])();\n\n    enum Float: float\n    {\n        one = 32.0f,\n        two = 25.0f\n    }\n\n    buffer.append!Float(Float.one);\n    assert(buffer.data == [66, 0, 0, 0]);\n\n    buffer.append!Float(Float.two);\n    assert(buffer.data == [66, 0, 0, 0, 65, 200, 0, 0]);\n}\n\n/// enum - double\n@safe unittest\n{\n    import std.array : appender;\n    auto buffer = appender!(const ubyte[])();\n\n    enum Double: double\n    {\n        one = 32.0,\n        two = 25.0\n    }\n\n    buffer.append!Double(Double.one);\n    assert(buffer.data == [64, 64, 0, 0, 0, 0, 0, 0]);\n\n    buffer.append!Double(Double.two);\n    assert(buffer.data == [64, 64, 0, 0, 0, 0, 0, 0, 64, 57, 0, 0, 0, 0, 0, 0]);\n}\n\n/// enum - real\n@safe unittest\n{\n    import std.array : appender;\n    auto buffer = appender!(const ubyte[])();\n\n    enum Real: real\n    {\n        one = 32.0,\n        two = 25.0\n    }\n\n    static assert(!__traits(compiles, buffer.append!Real(Real.one)));\n}\n\n@system unittest\n{\n    import std.array;\n    import std.format : format;\n    import std.meta : AliasSeq;\n    static foreach (endianness; [Endian.bigEndian, Endian.littleEndian])\n    {{\n        auto toWrite = appender!(ubyte[])();\n        alias Types = AliasSeq!(uint, int, long, ulong, short, ubyte, ushort, byte, uint);\n        ulong[] values = [42, -11, long.max, 1098911981329L, 16, 255, 19012, 2, 17];\n        assert(Types.length == values.length);\n\n        size_t index = 0;\n        size_t length = 0;\n        static foreach (T; Types)\n        {\n            toWrite.append!(T, endianness)(cast(T) values[index++]);\n            length += T.sizeof;\n        }\n\n        auto toRead = toWrite.data;\n        assert(toRead.length == length);\n\n        index = 0;\n        static foreach (T; Types)\n        {\n            assert(toRead.peek!(T, endianness)() == values[index], format(\"Failed Index: %s\", index));\n            assert(toRead.peek!(T, endianness)(0) == values[index], format(\"Failed Index: %s\", index));\n            assert(toRead.length == length,\n                   format(\"Failed Index [%s], Actual Length: %s\", index, toRead.length));\n            assert(toRead.read!(T, endianness)() == values[index], format(\"Failed Index: %s\", index));\n            length -= T.sizeof;\n            assert(toRead.length == length,\n                   format(\"Failed Index [%s], Actual Length: %s\", index, toRead.length));\n            ++index;\n        }\n        assert(toRead.empty);\n    }}\n}\n\n/**\nCounts the number of set bits in the binary representation of `value`.\nFor signed integers, the sign bit is included in the count.\n*/\nprivate uint countBitsSet(T)(T value) @nogc pure nothrow\nif (isIntegral!T)\n{\n    // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel\n    static if (T.sizeof == 8)\n    {\n        T c = value - ((value >> 1) & 0x55555555_55555555);\n        c = ((c >> 2) & 0x33333333_33333333) + (c & 0x33333333_33333333);\n        c = ((c >> 4) + c) & 0x0F0F0F0F_0F0F0F0F;\n        c = ((c >> 8) + c) & 0x00FF00FF_00FF00FF;\n        c = ((c >> 16) + c) & 0x0000FFFF_0000FFFF;\n        c = ((c >> 32) + c) & 0x00000000_FFFFFFFF;\n    }\n    else static if (T.sizeof == 4)\n    {\n        T c = value - ((value >> 1) & 0x55555555);\n        c = ((c >> 2) & 0x33333333) + (c & 0x33333333);\n        c = ((c >> 4) + c) & 0x0F0F0F0F;\n        c = ((c >> 8) + c) & 0x00FF00FF;\n        c = ((c >> 16) + c) & 0x0000FFFF;\n    }\n    else static if (T.sizeof == 2)\n    {\n        uint c = value - ((value >> 1) & 0x5555);\n        c = ((c >> 2) & 0x3333) + (c & 0X3333);\n        c = ((c >> 4) + c) & 0x0F0F;\n        c = ((c >> 8) + c) & 0x00FF;\n    }\n    else static if (T.sizeof == 1)\n    {\n        uint c = value - ((value >> 1) & 0x55);\n        c = ((c >> 2) & 0x33) + (c & 0X33);\n        c = ((c >> 4) + c) & 0x0F;\n    }\n    else\n    {\n        static assert(false, \"countBitsSet only supports 1, 2, 4, or 8 byte sized integers.\");\n    }\n    return cast(uint) c;\n}\n\n@safe unittest\n{\n    assert(countBitsSet(1) == 1);\n    assert(countBitsSet(0) == 0);\n    assert(countBitsSet(int.min) == 1);\n    assert(countBitsSet(uint.max) == 32);\n}\n\n@safe unittest\n{\n    import std.meta;\n    static foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))\n    {\n        assert(countBitsSet(cast(T) 0) == 0);\n        assert(countBitsSet(cast(T) 1) == 1);\n        assert(countBitsSet(cast(T) 2) == 1);\n        assert(countBitsSet(cast(T) 3) == 2);\n        assert(countBitsSet(cast(T) 4) == 1);\n        assert(countBitsSet(cast(T) 5) == 2);\n        assert(countBitsSet(cast(T) 127) == 7);\n        static if (isSigned!T)\n        {\n            assert(countBitsSet(cast(T)-1) == 8 * T.sizeof);\n            assert(countBitsSet(T.min) == 1);\n        }\n        else\n        {\n            assert(countBitsSet(T.max) == 8 * T.sizeof);\n        }\n    }\n    assert(countBitsSet(1_000_000) == 7);\n    foreach (i; 0 .. 63)\n        assert(countBitsSet(1UL << i) == 1);\n}\n\nprivate struct BitsSet(T)\n{\n    static assert(T.sizeof <= 8, \"bitsSet assumes T is no more than 64-bit.\");\n\n@nogc pure nothrow:\n\n    this(T value, size_t startIndex = 0)\n    {\n        _value = value;\n        // Further calculation is only valid and needed when the range is non-empty.\n        if (!_value)\n            return;\n\n        import core.bitop : bsf;\n        immutable trailingZerosCount = bsf(value);\n        _value >>>= trailingZerosCount;\n        _index = startIndex + trailingZerosCount;\n    }\n\n    @property size_t front()\n    {\n        return _index;\n    }\n\n    @property bool empty() const\n    {\n        return !_value;\n    }\n\n    void popFront()\n    {\n        assert(_value, \"Cannot call popFront on empty range.\");\n\n        _value >>>= 1;\n        // Further calculation is only valid and needed when the range is non-empty.\n        if (!_value)\n            return;\n\n        import core.bitop : bsf;\n        immutable trailingZerosCount = bsf(_value);\n        _value >>>= trailingZerosCount;\n        _index += trailingZerosCount + 1;\n    }\n\n    @property auto save()\n    {\n        return this;\n    }\n\n    @property size_t length()\n    {\n        return countBitsSet(_value);\n    }\n\n    private T _value;\n    private size_t _index;\n}\n\n/**\nRange that iterates the indices of the set bits in `value`.\nIndex 0 corresponds to the least significant bit.\nFor signed integers, the highest index corresponds to the sign bit.\n*/\nauto bitsSet(T)(T value) @nogc pure nothrow\nif (isIntegral!T)\n{\n    return BitsSet!T(value);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota;\n\n    assert(bitsSet(1).equal([0]));\n    assert(bitsSet(5).equal([0, 2]));\n    assert(bitsSet(-1).equal(iota(32)));\n    assert(bitsSet(int.min).equal([31]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota;\n\n    import std.meta;\n    static foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))\n    {\n        assert(bitsSet(cast(T) 0).empty);\n        assert(bitsSet(cast(T) 1).equal([0]));\n        assert(bitsSet(cast(T) 2).equal([1]));\n        assert(bitsSet(cast(T) 3).equal([0, 1]));\n        assert(bitsSet(cast(T) 4).equal([2]));\n        assert(bitsSet(cast(T) 5).equal([0, 2]));\n        assert(bitsSet(cast(T) 127).equal(iota(7)));\n        static if (isSigned!T)\n        {\n            assert(bitsSet(cast(T)-1).equal(iota(8 * T.sizeof)));\n            assert(bitsSet(T.min).equal([8 * T.sizeof - 1]));\n        }\n        else\n        {\n            assert(bitsSet(T.max).equal(iota(8 * T.sizeof)));\n        }\n    }\n    assert(bitsSet(1_000_000).equal([6, 9, 14, 16, 17, 18, 19]));\n    foreach (i; 0 .. 63)\n        assert(bitsSet(1UL << i).equal([i]));\n}\n"
  },
  {
    "path": "libphobos/src/std/compiler.d",
    "content": "// Written in the D programming language.\n\n/**\n * Identify the compiler used and its various features.\n *\n * Copyright: Copyright The D Language Foundation 2000 - 2011.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright), Alex Rønne Petersen\n * Source:    $(PHOBOSSRC std/compiler.d)\n */\n/*          Copyright The D Language Foundation 2000 - 2011.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.compiler;\n\nimmutable\n{\n    /// Vendor specific string naming the compiler, for example: \"Digital Mars D\".\n    string name = __VENDOR__;\n\n    /// Master list of D compiler vendors.\n    enum Vendor\n    {\n        unknown = 0,     /// Compiler vendor could not be detected\n        digitalMars = 1, /// Digital Mars D (DMD)\n        gnu = 2,         /// GNU D Compiler (GDC)\n        llvm = 3,        /// LLVM D Compiler (LDC)\n        dotNET = 4,      /// D.NET\n        sdc = 5,         /// Stupid D Compiler (SDC)\n    }\n\n    /// Which vendor produced this compiler.\n    version (StdDdoc)          Vendor vendor;\n    else version (DigitalMars) Vendor vendor = Vendor.digitalMars;\n    else version (GNU)         Vendor vendor = Vendor.gnu;\n    else version (LDC)         Vendor vendor = Vendor.llvm;\n    else version (D_NET)       Vendor vendor = Vendor.dotNET;\n    else version (SDC)         Vendor vendor = Vendor.sdc;\n    else                      Vendor vendor = Vendor.unknown;\n\n\n    /**\n     * The vendor specific version number, as in\n     * version_major.version_minor\n     */\n    uint version_major = __VERSION__ / 1000;\n    uint version_minor = __VERSION__ % 1000;    /// ditto\n\n\n    /**\n     * The version of the D Programming Language Specification\n     * supported by the compiler.\n     */\n    uint D_major = 2;\n    uint D_minor = 0;\n}\n"
  },
  {
    "path": "libphobos/src/std/complex.d",
    "content": "// Written in the D programming language.\n\n/** This module contains the $(LREF Complex) type, which is used to represent\n    complex numbers, along with related mathematical operations and functions.\n\n    $(LREF Complex) will eventually\n    $(DDLINK deprecate, Deprecated Features, replace)\n    the built-in types `cfloat`, `cdouble`, `creal`, `ifloat`,\n    `idouble`, and `ireal`.\n\n    Authors:    Lars Tandle Kyllingstad, Don Clugston\n    Copyright:  Copyright (c) 2010, Lars T. Kyllingstad.\n    License:    $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)\n    Source:     $(PHOBOSSRC std/complex.d)\n*/\nmodule std.complex;\n\nimport std.traits;\n\n/** Helper function that returns a complex number with the specified\n    real and imaginary parts.\n\n    Params:\n        R = (template parameter) type of real part of complex number\n        I = (template parameter) type of imaginary part of complex number\n\n        re = real part of complex number to be constructed\n        im = (optional) imaginary part of complex number, 0 if omitted.\n\n    Returns:\n        `Complex` instance with real and imaginary parts set\n        to the values provided as input.  If neither `re` nor\n        `im` are floating-point numbers, the return type will\n        be `Complex!double`.  Otherwise, the return type is\n        deduced using $(D std.traits.CommonType!(R, I)).\n*/\nauto complex(R)(const R re)  @safe pure nothrow @nogc\nif (is(R : double))\n{\n    static if (isFloatingPoint!R)\n        return Complex!R(re, 0);\n    else\n        return Complex!double(re, 0);\n}\n\n/// ditto\nauto complex(R, I)(const R re, const I im)  @safe pure nothrow @nogc\nif (is(R : double) && is(I : double))\n{\n    static if (isFloatingPoint!R || isFloatingPoint!I)\n        return Complex!(CommonType!(R, I))(re, im);\n    else\n        return Complex!double(re, im);\n}\n\n///\n@safe pure nothrow unittest\n{\n    auto a = complex(1.0);\n    static assert(is(typeof(a) == Complex!double));\n    assert(a.re == 1.0);\n    assert(a.im == 0.0);\n\n    auto b = complex(2.0L);\n    static assert(is(typeof(b) == Complex!real));\n    assert(b.re == 2.0L);\n    assert(b.im == 0.0L);\n\n    auto c = complex(1.0, 2.0);\n    static assert(is(typeof(c) == Complex!double));\n    assert(c.re == 1.0);\n    assert(c.im == 2.0);\n\n    auto d = complex(3.0, 4.0L);\n    static assert(is(typeof(d) == Complex!real));\n    assert(d.re == 3.0);\n    assert(d.im == 4.0L);\n\n    auto e = complex(1);\n    static assert(is(typeof(e) == Complex!double));\n    assert(e.re == 1);\n    assert(e.im == 0);\n\n    auto f = complex(1L, 2);\n    static assert(is(typeof(f) == Complex!double));\n    assert(f.re == 1L);\n    assert(f.im == 2);\n\n    auto g = complex(3, 4.0L);\n    static assert(is(typeof(g) == Complex!real));\n    assert(g.re == 3);\n    assert(g.im == 4.0L);\n}\n\n\n/** A complex number parametrised by a type `T`, which must be either\n    `float`, `double` or `real`.\n*/\nstruct Complex(T)\nif (isFloatingPoint!T)\n{\n    import std.format : FormatSpec;\n    import std.range.primitives : isOutputRange;\n\n    /** The real part of the number. */\n    T re;\n\n    /** The imaginary part of the number. */\n    T im;\n\n    /** Converts the complex number to a string representation.\n\n    The second form of this function is usually not called directly;\n    instead, it is used via $(REF format, std,string), as shown in the examples\n    below.  Supported format characters are 'e', 'f', 'g', 'a', and 's'.\n\n    See the $(MREF std, format) and $(REF format, std,string)\n    documentation for more information.\n    */\n    string toString() const @safe /* TODO: pure nothrow */\n    {\n        import std.exception : assumeUnique;\n        char[] buf;\n        buf.reserve(100);\n        auto fmt = FormatSpec!char(\"%s\");\n        toString((const(char)[] s) { buf ~= s; }, fmt);\n        static trustedAssumeUnique(T)(T t) @trusted { return assumeUnique(t); }\n        return trustedAssumeUnique(buf);\n    }\n\n    static if (is(T == double))\n    ///\n    @safe unittest\n    {\n        auto c = complex(1.2, 3.4);\n\n        // Vanilla toString formatting:\n        assert(c.toString() == \"1.2+3.4i\");\n\n        // Formatting with std.string.format specs: the precision and width\n        // specifiers apply to both the real and imaginary parts of the\n        // complex number.\n        import std.format : format;\n        assert(format(\"%.2f\", c)  == \"1.20+3.40i\");\n        assert(format(\"%4.1f\", c) == \" 1.2+ 3.4i\");\n    }\n\n    /// ditto\n    void toString(Writer, Char)(scope Writer w, const ref FormatSpec!Char formatSpec) const\n        if (isOutputRange!(Writer, const(Char)[]))\n    {\n        import std.format : formatValue;\n        import std.math : signbit;\n        import std.range.primitives : put;\n        formatValue(w, re, formatSpec);\n        if (signbit(im) == 0)\n           put(w, \"+\");\n        formatValue(w, im, formatSpec);\n        put(w, \"i\");\n    }\n\n@safe pure nothrow @nogc:\n\n    /** Construct a complex number with the specified real and\n    imaginary parts. In the case where a single argument is passed\n    that is not complex, the imaginary part of the result will be\n    zero.\n    */\n    this(R : T)(Complex!R z)\n    {\n        re = z.re;\n        im = z.im;\n    }\n\n    /// ditto\n    this(Rx : T, Ry : T)(const Rx x, const Ry y)\n    {\n        re = x;\n        im = y;\n    }\n\n    /// ditto\n    this(R : T)(const R r)\n    {\n        re = r;\n        im = 0;\n    }\n\n    // ASSIGNMENT OPERATORS\n\n    // this = complex\n    ref Complex opAssign(R : T)(Complex!R z)\n    {\n        re = z.re;\n        im = z.im;\n        return this;\n    }\n\n    // this = numeric\n    ref Complex opAssign(R : T)(const R r)\n    {\n        re = r;\n        im = 0;\n        return this;\n    }\n\n    // COMPARISON OPERATORS\n\n    // this == complex\n    bool opEquals(R : T)(Complex!R z) const\n    {\n        return re == z.re && im == z.im;\n    }\n\n    // this == numeric\n    bool opEquals(R : T)(const R r) const\n    {\n        return re == r && im == 0;\n    }\n\n    // UNARY OPERATORS\n\n    // +complex\n    Complex opUnary(string op)() const\n        if (op == \"+\")\n    {\n        return this;\n    }\n\n    // -complex\n    Complex opUnary(string op)() const\n        if (op == \"-\")\n    {\n        return Complex(-re, -im);\n    }\n\n    // BINARY OPERATORS\n\n    // complex op complex\n    Complex!(CommonType!(T,R)) opBinary(string op, R)(Complex!R z) const\n    {\n        alias C = typeof(return);\n        auto w = C(this.re, this.im);\n        return w.opOpAssign!(op)(z);\n    }\n\n    // complex op numeric\n    Complex!(CommonType!(T,R)) opBinary(string op, R)(const R r) const\n        if (isNumeric!R)\n    {\n        alias C = typeof(return);\n        auto w = C(this.re, this.im);\n        return w.opOpAssign!(op)(r);\n    }\n\n    // numeric + complex,  numeric * complex\n    Complex!(CommonType!(T, R)) opBinaryRight(string op, R)(const R r) const\n        if ((op == \"+\" || op == \"*\") && (isNumeric!R))\n    {\n        return opBinary!(op)(r);\n    }\n\n    // numeric - complex\n    Complex!(CommonType!(T, R)) opBinaryRight(string op, R)(const R r) const\n        if (op == \"-\" && isNumeric!R)\n    {\n        return Complex(r - re, -im);\n    }\n\n    // numeric / complex\n    Complex!(CommonType!(T, R)) opBinaryRight(string op, R)(const R r) const\n        if (op == \"/\" && isNumeric!R)\n    {\n        import std.math : fabs;\n        typeof(return) w = void;\n        if (fabs(re) < fabs(im))\n        {\n            immutable ratio = re/im;\n            immutable rdivd = r/(re*ratio + im);\n\n            w.re = rdivd*ratio;\n            w.im = -rdivd;\n        }\n        else\n        {\n            immutable ratio = im/re;\n            immutable rdivd = r/(re + im*ratio);\n\n            w.re = rdivd;\n            w.im = -rdivd*ratio;\n        }\n\n        return w;\n    }\n\n    // numeric ^^ complex\n    Complex!(CommonType!(T, R)) opBinaryRight(string op, R)(const R lhs) const\n        if (op == \"^^\" && isNumeric!R)\n    {\n        import std.math : cos, exp, log, sin, PI;\n        Unqual!(CommonType!(T, R)) ab = void, ar = void;\n\n        if (lhs >= 0)\n        {\n            // r = lhs\n            // theta = 0\n            ab = lhs ^^ this.re;\n            ar = log(lhs) * this.im;\n        }\n        else\n        {\n            // r = -lhs\n            // theta = PI\n            ab = (-lhs) ^^ this.re * exp(-PI * this.im);\n            ar = PI * this.re + log(-lhs) * this.im;\n        }\n\n        return typeof(return)(ab * cos(ar), ab * sin(ar));\n    }\n\n    // OP-ASSIGN OPERATORS\n\n    // complex += complex,  complex -= complex\n    ref Complex opOpAssign(string op, C)(const C z)\n        if ((op == \"+\" || op == \"-\") && is(C R == Complex!R))\n    {\n        mixin (\"re \"~op~\"= z.re;\");\n        mixin (\"im \"~op~\"= z.im;\");\n        return this;\n    }\n\n    // complex *= complex\n    ref Complex opOpAssign(string op, C)(const C z)\n        if (op == \"*\" && is(C R == Complex!R))\n    {\n        auto temp = re*z.re - im*z.im;\n        im = im*z.re + re*z.im;\n        re = temp;\n        return this;\n    }\n\n    // complex /= complex\n    ref Complex opOpAssign(string op, C)(const C z)\n        if (op == \"/\" && is(C R == Complex!R))\n    {\n        import std.math : fabs;\n        if (fabs(z.re) < fabs(z.im))\n        {\n            immutable ratio = z.re/z.im;\n            immutable denom = z.re*ratio + z.im;\n\n            immutable temp = (re*ratio + im)/denom;\n            im = (im*ratio - re)/denom;\n            re = temp;\n        }\n        else\n        {\n            immutable ratio = z.im/z.re;\n            immutable denom = z.re + z.im*ratio;\n\n            immutable temp = (re + im*ratio)/denom;\n            im = (im - re*ratio)/denom;\n            re = temp;\n        }\n        return this;\n    }\n\n    // complex ^^= complex\n    ref Complex opOpAssign(string op, C)(const C z)\n        if (op == \"^^\" && is(C R == Complex!R))\n    {\n        import std.math : exp, log, cos, sin;\n        immutable r = abs(this);\n        immutable t = arg(this);\n        immutable ab = r^^z.re * exp(-t*z.im);\n        immutable ar = t*z.re + log(r)*z.im;\n\n        re = ab*cos(ar);\n        im = ab*sin(ar);\n        return this;\n    }\n\n    // complex += numeric,  complex -= numeric\n    ref Complex opOpAssign(string op, U : T)(const U a)\n        if (op == \"+\" || op == \"-\")\n    {\n        mixin (\"re \"~op~\"= a;\");\n        return this;\n    }\n\n    // complex *= numeric,  complex /= numeric\n    ref Complex opOpAssign(string op, U : T)(const U a)\n        if (op == \"*\" || op == \"/\")\n    {\n        mixin (\"re \"~op~\"= a;\");\n        mixin (\"im \"~op~\"= a;\");\n        return this;\n    }\n\n    // complex ^^= real\n    ref Complex opOpAssign(string op, R)(const R r)\n        if (op == \"^^\" && isFloatingPoint!R)\n    {\n        import std.math : cos, sin;\n        immutable ab = abs(this)^^r;\n        immutable ar = arg(this)*r;\n        re = ab*cos(ar);\n        im = ab*sin(ar);\n        return this;\n    }\n\n    // complex ^^= int\n    ref Complex opOpAssign(string op, U)(const U i)\n        if (op == \"^^\" && isIntegral!U)\n    {\n        switch (i)\n        {\n        case 0:\n            re = 1.0;\n            im = 0.0;\n            break;\n        case 1:\n            // identity; do nothing\n            break;\n        case 2:\n            this *= this;\n            break;\n        case 3:\n            auto z = this;\n            this *= z;\n            this *= z;\n            break;\n        default:\n            this ^^= cast(real) i;\n        }\n        return this;\n    }\n}\n\n@safe pure nothrow unittest\n{\n    import std.complex;\n    import std.math;\n\n    enum EPS = double.epsilon;\n    auto c1 = complex(1.0, 1.0);\n\n    // Check unary operations.\n    auto c2 = Complex!double(0.5, 2.0);\n\n    assert(c2 == +c2);\n\n    assert((-c2).re == -(c2.re));\n    assert((-c2).im == -(c2.im));\n    assert(c2 == -(-c2));\n\n    // Check complex-complex operations.\n    auto cpc = c1 + c2;\n    assert(cpc.re == c1.re + c2.re);\n    assert(cpc.im == c1.im + c2.im);\n\n    auto cmc = c1 - c2;\n    assert(cmc.re == c1.re - c2.re);\n    assert(cmc.im == c1.im - c2.im);\n\n    auto ctc = c1 * c2;\n    assert(approxEqual(abs(ctc), abs(c1)*abs(c2), EPS));\n    assert(approxEqual(arg(ctc), arg(c1)+arg(c2), EPS));\n\n    auto cdc = c1 / c2;\n    assert(approxEqual(abs(cdc), abs(c1)/abs(c2), EPS));\n    assert(approxEqual(arg(cdc), arg(c1)-arg(c2), EPS));\n\n    auto cec = c1^^c2;\n    assert(approxEqual(cec.re, 0.11524131979943839881, EPS));\n    assert(approxEqual(cec.im, 0.21870790452746026696, EPS));\n\n    // Check complex-real operations.\n    double a = 123.456;\n\n    auto cpr = c1 + a;\n    assert(cpr.re == c1.re + a);\n    assert(cpr.im == c1.im);\n\n    auto cmr = c1 - a;\n    assert(cmr.re == c1.re - a);\n    assert(cmr.im == c1.im);\n\n    auto ctr = c1 * a;\n    assert(ctr.re == c1.re*a);\n    assert(ctr.im == c1.im*a);\n\n    auto cdr = c1 / a;\n    assert(approxEqual(abs(cdr), abs(c1)/a, EPS));\n    assert(approxEqual(arg(cdr), arg(c1), EPS));\n\n    auto cer = c1^^3.0;\n    assert(approxEqual(abs(cer), abs(c1)^^3, EPS));\n    assert(approxEqual(arg(cer), arg(c1)*3, EPS));\n\n    auto rpc = a + c1;\n    assert(rpc == cpr);\n\n    auto rmc = a - c1;\n    assert(rmc.re == a-c1.re);\n    assert(rmc.im == -c1.im);\n\n    auto rtc = a * c1;\n    assert(rtc == ctr);\n\n    auto rdc = a / c1;\n    assert(approxEqual(abs(rdc), a/abs(c1), EPS));\n    assert(approxEqual(arg(rdc), -arg(c1), EPS));\n\n    rdc = a / c2;\n    assert(approxEqual(abs(rdc), a/abs(c2), EPS));\n    assert(approxEqual(arg(rdc), -arg(c2), EPS));\n\n    auto rec1a = 1.0 ^^ c1;\n    assert(rec1a.re == 1.0);\n    assert(rec1a.im == 0.0);\n\n    auto rec2a = 1.0 ^^ c2;\n    assert(rec2a.re == 1.0);\n    assert(rec2a.im == 0.0);\n\n    auto rec1b = (-1.0) ^^ c1;\n    assert(approxEqual(abs(rec1b), std.math.exp(-PI * c1.im), EPS));\n    auto arg1b = arg(rec1b);\n    /* The argument _should_ be PI, but floating-point rounding error\n     * means that in fact the imaginary part is very slightly negative.\n     */\n    assert(approxEqual(arg1b, PI, EPS) || approxEqual(arg1b, -PI, EPS));\n\n    auto rec2b = (-1.0) ^^ c2;\n    assert(approxEqual(abs(rec2b), std.math.exp(-2 * PI), EPS));\n    assert(approxEqual(arg(rec2b), PI_2, EPS));\n\n    auto rec3a = 0.79 ^^ complex(6.8, 5.7);\n    auto rec3b = complex(0.79, 0.0) ^^ complex(6.8, 5.7);\n    assert(approxEqual(rec3a.re, rec3b.re, EPS));\n    assert(approxEqual(rec3a.im, rec3b.im, EPS));\n\n    auto rec4a = (-0.79) ^^ complex(6.8, 5.7);\n    auto rec4b = complex(-0.79, 0.0) ^^ complex(6.8, 5.7);\n    assert(approxEqual(rec4a.re, rec4b.re, EPS));\n    assert(approxEqual(rec4a.im, rec4b.im, EPS));\n\n    auto rer = a ^^ complex(2.0, 0.0);\n    auto rcheck = a ^^ 2.0;\n    static assert(is(typeof(rcheck) == double));\n    assert(feqrel(rer.re, rcheck) == double.mant_dig);\n    assert(isIdentical(rer.re, rcheck));\n    assert(rer.im == 0.0);\n\n    auto rer2 = (-a) ^^ complex(2.0, 0.0);\n    rcheck = (-a) ^^ 2.0;\n    assert(feqrel(rer2.re, rcheck) == double.mant_dig);\n    assert(isIdentical(rer2.re, rcheck));\n    assert(approxEqual(rer2.im, 0.0, EPS));\n\n    auto rer3 = (-a) ^^ complex(-2.0, 0.0);\n    rcheck = (-a) ^^ (-2.0);\n    assert(feqrel(rer3.re, rcheck) == double.mant_dig);\n    assert(isIdentical(rer3.re, rcheck));\n    assert(approxEqual(rer3.im, 0.0, EPS));\n\n    auto rer4 = a ^^ complex(-2.0, 0.0);\n    rcheck = a ^^ (-2.0);\n    assert(feqrel(rer4.re, rcheck) == double.mant_dig);\n    assert(isIdentical(rer4.re, rcheck));\n    assert(rer4.im == 0.0);\n\n    // Check Complex-int operations.\n    foreach (i; 0 .. 6)\n    {\n        auto cei = c1^^i;\n        assert(approxEqual(abs(cei), abs(c1)^^i, EPS));\n        // Use cos() here to deal with arguments that go outside\n        // the (-pi,pi] interval (only an issue for i>3).\n        assert(approxEqual(std.math.cos(arg(cei)), std.math.cos(arg(c1)*i), EPS));\n    }\n\n    // Check operations between different complex types.\n    auto cf = Complex!float(1.0, 1.0);\n    auto cr = Complex!real(1.0, 1.0);\n    auto c1pcf = c1 + cf;\n    auto c1pcr = c1 + cr;\n    static assert(is(typeof(c1pcf) == Complex!double));\n    static assert(is(typeof(c1pcr) == Complex!real));\n    assert(c1pcf.re == c1pcr.re);\n    assert(c1pcf.im == c1pcr.im);\n\n    auto c1c = c1;\n    auto c2c = c2;\n\n    c1c /= c1;\n    assert(approxEqual(c1c.re, 1.0, EPS));\n    assert(approxEqual(c1c.im, 0.0, EPS));\n\n    c1c = c1;\n    c1c /= c2;\n    assert(approxEqual(c1c.re, 0.588235, EPS));\n    assert(approxEqual(c1c.im, -0.352941, EPS));\n\n    c2c /= c1;\n    assert(approxEqual(c2c.re, 1.25, EPS));\n    assert(approxEqual(c2c.im, 0.75, EPS));\n\n    c2c = c2;\n    c2c /= c2;\n    assert(approxEqual(c2c.re, 1.0, EPS));\n    assert(approxEqual(c2c.im, 0.0, EPS));\n}\n\n@safe pure nothrow unittest\n{\n    // Initialization\n    Complex!double a = 1;\n    assert(a.re == 1 && a.im == 0);\n    Complex!double b = 1.0;\n    assert(b.re == 1.0 && b.im == 0);\n    Complex!double c = Complex!real(1.0, 2);\n    assert(c.re == 1.0 && c.im == 2);\n}\n\n@safe pure nothrow unittest\n{\n    // Assignments and comparisons\n    Complex!double z;\n\n    z = 1;\n    assert(z == 1);\n    assert(z.re == 1.0  &&  z.im == 0.0);\n\n    z = 2.0;\n    assert(z == 2.0);\n    assert(z.re == 2.0  &&  z.im == 0.0);\n\n    z = 1.0L;\n    assert(z == 1.0L);\n    assert(z.re == 1.0  &&  z.im == 0.0);\n\n    auto w = Complex!real(1.0, 1.0);\n    z = w;\n    assert(z == w);\n    assert(z.re == 1.0  &&  z.im == 1.0);\n\n    auto c = Complex!float(2.0, 2.0);\n    z = c;\n    assert(z == c);\n    assert(z.re == 2.0  &&  z.im == 2.0);\n}\n\n\n/*  Makes Complex!(Complex!T) fold to Complex!T.\n\n    The rationale for this is that just like the real line is a\n    subspace of the complex plane, the complex plane is a subspace\n    of itself.  Example of usage:\n    ---\n    Complex!T addI(T)(T x)\n    {\n        return x + Complex!T(0.0, 1.0);\n    }\n    ---\n    The above will work if T is both real and complex.\n*/\ntemplate Complex(T)\nif (is(T R == Complex!R))\n{\n    alias Complex = T;\n}\n\n@safe pure nothrow unittest\n{\n    static assert(is(Complex!(Complex!real) == Complex!real));\n\n    Complex!T addI(T)(T x)\n    {\n        return x + Complex!T(0.0, 1.0);\n    }\n\n    auto z1 = addI(1.0);\n    assert(z1.re == 1.0 && z1.im == 1.0);\n\n    enum one = Complex!double(1.0, 0.0);\n    auto z2 = addI(one);\n    assert(z1 == z2);\n}\n\n\n/**\n   Params: z = A complex number.\n   Returns: The absolute value (or modulus) of `z`.\n*/\nT abs(T)(Complex!T z) @safe pure nothrow @nogc\n{\n    import std.math : hypot;\n    return hypot(z.re, z.im);\n}\n\n///\n@safe pure nothrow unittest\n{\n    static import std.math;\n    assert(abs(complex(1.0)) == 1.0);\n    assert(abs(complex(0.0, 1.0)) == 1.0);\n    assert(abs(complex(1.0L, -2.0L)) == std.math.sqrt(5.0L));\n}\n\n\n/++\n   Params:\n    z = A complex number.\n    x = A real number.\n   Returns: The squared modulus of `z`.\n   For genericity, if called on a real number, returns its square.\n+/\nT sqAbs(T)(Complex!T z) @safe pure nothrow @nogc\n{\n    return z.re*z.re + z.im*z.im;\n}\n\n///\n@safe pure nothrow unittest\n{\n    import std.math;\n    assert(sqAbs(complex(0.0)) == 0.0);\n    assert(sqAbs(complex(1.0)) == 1.0);\n    assert(sqAbs(complex(0.0, 1.0)) == 1.0);\n    assert(approxEqual(sqAbs(complex(1.0L, -2.0L)), 5.0L));\n    assert(approxEqual(sqAbs(complex(-3.0L, 1.0L)), 10.0L));\n    assert(approxEqual(sqAbs(complex(1.0f,-1.0f)), 2.0f));\n}\n\n/// ditto\nT sqAbs(T)(const T x) @safe pure nothrow @nogc\nif (isFloatingPoint!T)\n{\n    return x*x;\n}\n\n@safe pure nothrow unittest\n{\n    import std.math;\n    assert(sqAbs(0.0) == 0.0);\n    assert(sqAbs(-1.0) == 1.0);\n    assert(approxEqual(sqAbs(-3.0L), 9.0L));\n    assert(approxEqual(sqAbs(-5.0f), 25.0f));\n}\n\n\n/**\n Params: z = A complex number.\n Returns: The argument (or phase) of `z`.\n */\nT arg(T)(Complex!T z) @safe pure nothrow @nogc\n{\n    import std.math : atan2;\n    return atan2(z.im, z.re);\n}\n\n///\n@safe pure nothrow unittest\n{\n    import std.math;\n    assert(arg(complex(1.0)) == 0.0);\n    assert(arg(complex(0.0L, 1.0L)) == PI_2);\n    assert(arg(complex(1.0L, 1.0L)) == PI_4);\n}\n\n\n/**\n  Params: z = A complex number.\n  Returns: The complex conjugate of `z`.\n*/\nComplex!T conj(T)(Complex!T z) @safe pure nothrow @nogc\n{\n    return Complex!T(z.re, -z.im);\n}\n\n///\n@safe pure nothrow unittest\n{\n    assert(conj(complex(1.0)) == complex(1.0));\n    assert(conj(complex(1.0, 2.0)) == complex(1.0, -2.0));\n}\n\n\n/**\n  Constructs a complex number given its absolute value and argument.\n  Params:\n    modulus = The modulus\n    argument = The argument\n  Returns: The complex number with the given modulus and argument.\n*/\nComplex!(CommonType!(T, U)) fromPolar(T, U)(const T modulus, const U argument)\n    @safe pure nothrow @nogc\n{\n    import std.math : sin, cos;\n    return Complex!(CommonType!(T,U))\n        (modulus*cos(argument), modulus*sin(argument));\n}\n\n///\n@safe pure nothrow unittest\n{\n    import std.math;\n    auto z = fromPolar(std.math.sqrt(2.0), PI_4);\n    assert(approxEqual(z.re, 1.0L, real.epsilon));\n    assert(approxEqual(z.im, 1.0L, real.epsilon));\n}\n\n\n/**\n    Trigonometric functions on complex numbers.\n\n    Params: z = A complex number.\n    Returns: The sine and cosine of `z`, respectively.\n*/\nComplex!T sin(T)(Complex!T z)  @safe pure nothrow @nogc\n{\n    auto cs = expi(z.re);\n    auto csh = coshisinh(z.im);\n    return typeof(return)(cs.im * csh.re, cs.re * csh.im);\n}\n\n///\n@safe pure nothrow unittest\n{\n    static import std.math;\n    assert(sin(complex(0.0)) == 0.0);\n    assert(sin(complex(2.0L, 0)) == std.math.sin(2.0L));\n}\n\n\n/// ditto\nComplex!T cos(T)(Complex!T z)  @safe pure nothrow @nogc\n{\n    auto cs = expi(z.re);\n    auto csh = coshisinh(z.im);\n    return typeof(return)(cs.re * csh.re, - cs.im * csh.im);\n}\n\n///\n@safe pure nothrow unittest\n{\n    import std.complex;\n    assert(cos(complex(0.0)) == 1.0);\n}\n\ndeprecated\n@safe pure nothrow unittest\n{\n    import std.math;\n    auto c1 = cos(complex(0, 5.2L));\n    auto c2 = cosh(5.2L);\n    assert(feqrel(c1.re, c2.re) >= real.mant_dig - 1 &&\n        feqrel(c1.im, c2.im) >= real.mant_dig - 1);\n    assert(cos(complex(1.3L)) == std.math.cos(1.3L));\n}\n\n/**\n    Params: y = A real number.\n    Returns: The value of cos(y) + i sin(y).\n\n    Note:\n    `expi` is included here for convenience and for easy migration of code\n    that uses $(REF _expi, std,math).  Unlike $(REF _expi, std,math), which uses the\n    x87 $(I fsincos) instruction when possible, this function is no faster\n    than calculating cos(y) and sin(y) separately.\n*/\nComplex!real expi(real y)  @trusted pure nothrow @nogc\n{\n    import std.math : cos, sin;\n    return Complex!real(cos(y), sin(y));\n}\n\n///\n@safe pure nothrow unittest\n{\n    import std.math : cos, sin;\n    assert(expi(0.0L) == 1.0L);\n    assert(expi(1.3e5L) == complex(cos(1.3e5L), sin(1.3e5L)));\n}\n\ndeprecated\n@safe pure nothrow unittest\n{\n    static import std.math;\n\n    assert(expi(1.3e5L) == complex(std.math.cos(1.3e5L), std.math.sin(1.3e5L)));\n    auto z1 = expi(1.234);\n    auto z2 = std.math.expi(1.234);\n    assert(z1.re == z2.re && z1.im == z2.im);\n}\n\n/**\n    Params: y = A real number.\n    Returns: The value of cosh(y) + i sinh(y)\n\n    Note:\n    `coshisinh` is included here for convenience and for easy migration of code\n    that uses $(REF _coshisinh, std,math).\n*/\nComplex!real coshisinh(real y) @safe pure nothrow @nogc\n{\n    static import std.math;\n    if (std.math.fabs(y) <= 0.5)\n        return Complex!real(std.math.cosh(y), std.math.sinh(y));\n    else\n    {\n        auto z = std.math.exp(y);\n        auto zi = 0.5 / z;\n        z = 0.5 * z;\n        return Complex!real(z + zi, z - zi);\n    }\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    import std.math : cosh, sinh;\n    assert(coshisinh(3.0L) == complex(cosh(3.0L), sinh(3.0L)));\n}\n\ndeprecated\n@safe pure nothrow @nogc unittest\n{\n    static import std.math;\n    assert(coshisinh(3.0L) == complex(std.math.cosh(3.0L), std.math.sinh(3.0L)));\n    auto z1 = coshisinh(1.234);\n    auto z2 = std.math.coshisinh(1.234);\n    static if (real.mant_dig == 53)\n    {\n        assert(std.math.feqrel(z1.re, z2.re) >= real.mant_dig - 1 &&\n               std.math.feqrel(z1.im, z2.im) >= real.mant_dig - 1);\n    }\n    else\n    {\n        assert(z1.re == z2.re && z1.im == z2.im);\n    }\n}\n\n/**\n    Params: z = A complex number.\n    Returns: The square root of `z`.\n*/\nComplex!T sqrt(T)(Complex!T z)  @safe pure nothrow @nogc\n{\n    static import std.math;\n    typeof(return) c;\n    real x,y,w,r;\n\n    if (z == 0)\n    {\n        c = typeof(return)(0, 0);\n    }\n    else\n    {\n        real z_re = z.re;\n        real z_im = z.im;\n\n        x = std.math.fabs(z_re);\n        y = std.math.fabs(z_im);\n        if (x >= y)\n        {\n            r = y / x;\n            w = std.math.sqrt(x)\n                * std.math.sqrt(0.5 * (1 + std.math.sqrt(1 + r * r)));\n        }\n        else\n        {\n            r = x / y;\n            w = std.math.sqrt(y)\n                * std.math.sqrt(0.5 * (r + std.math.sqrt(1 + r * r)));\n        }\n\n        if (z_re >= 0)\n        {\n            c = typeof(return)(w, z_im / (w + w));\n        }\n        else\n        {\n            if (z_im < 0)\n                w = -w;\n            c = typeof(return)(z_im / (w + w), w);\n        }\n    }\n    return c;\n}\n\n///\n@safe pure nothrow unittest\n{\n    static import std.math;\n    assert(sqrt(complex(0.0)) == 0.0);\n    assert(sqrt(complex(1.0L, 0)) == std.math.sqrt(1.0L));\n    assert(sqrt(complex(-1.0L, 0)) == complex(0, 1.0L));\n}\n\n@safe pure nothrow unittest\n{\n    import std.math : approxEqual;\n\n    auto c1 = complex(1.0, 1.0);\n    auto c2 = Complex!double(0.5, 2.0);\n\n    auto c1s = sqrt(c1);\n    assert(approxEqual(c1s.re, 1.09868411));\n    assert(approxEqual(c1s.im, 0.45508986));\n\n    auto c2s = sqrt(c2);\n    assert(approxEqual(c2s.re, 1.1317134));\n    assert(approxEqual(c2s.im, 0.8836155));\n}\n\n// Issue 10881: support %f formatting of complex numbers\n@safe unittest\n{\n    import std.format : format;\n\n    auto x = complex(1.2, 3.4);\n    assert(format(\"%.2f\", x) == \"1.20+3.40i\");\n\n    auto y = complex(1.2, -3.4);\n    assert(format(\"%.2f\", y) == \"1.20-3.40i\");\n}\n\n@safe unittest\n{\n    // Test wide string formatting\n    import std.format;\n    wstring wformat(T)(string format, Complex!T c)\n    {\n        import std.array : appender;\n        auto w = appender!wstring();\n        auto n = formattedWrite(w, format, c);\n        return w.data;\n    }\n\n    auto x = complex(1.2, 3.4);\n    assert(wformat(\"%.2f\", x) == \"1.20+3.40i\"w);\n}\n\n@safe unittest\n{\n    // Test ease of use (vanilla toString() should be supported)\n    assert(complex(1.2, 3.4).toString() == \"1.2+3.4i\");\n}\n"
  },
  {
    "path": "libphobos/src/std/concurrency.d",
    "content": "/**\n * This is a low-level messaging API upon which more structured or restrictive\n * APIs may be built.  The general idea is that every messageable entity is\n * represented by a common handle type called a Tid, which allows messages to\n * be sent to logical threads that are executing in both the current process\n * and in external processes using the same interface.  This is an important\n * aspect of scalability because it allows the components of a program to be\n * spread across available resources with few to no changes to the actual\n * implementation.\n *\n * A logical thread is an execution context that has its own stack and which\n * runs asynchronously to other logical threads.  These may be preemptively\n * scheduled kernel threads, fibers (cooperative user-space threads), or some\n * other concept with similar behavior.\n *\n * The type of concurrency used when logical threads are created is determined\n * by the Scheduler selected at initialization time.  The default behavior is\n * currently to create a new kernel thread per call to spawn, but other\n * schedulers are available that multiplex fibers across the main thread or\n * use some combination of the two approaches.\n *\n * Copyright: Copyright Sean Kelly 2009 - 2014.\n * License:   <a href=\"http://www.boost.org/LICENSE_1_0.txt\">Boost License 1.0</a>.\n * Authors:   Sean Kelly, Alex Rønne Petersen, Martin Nowak\n * Source:    $(PHOBOSSRC std/concurrency.d)\n */\n/*          Copyright Sean Kelly 2009 - 2014.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.concurrency;\n\npublic import std.variant;\n\nimport core.atomic;\nimport core.sync.condition;\nimport core.sync.mutex;\nimport core.thread;\nimport std.range.primitives;\nimport std.range.interfaces : InputRange;\nimport std.traits;\n\n///\n@system unittest\n{\n    __gshared string received;\n    static void spawnedFunc(Tid ownerTid)\n    {\n        import std.conv : text;\n        // Receive a message from the owner thread.\n        receive((int i){\n            received = text(\"Received the number \", i);\n\n            // Send a message back to the owner thread\n            // indicating success.\n            send(ownerTid, true);\n        });\n    }\n\n    // Start spawnedFunc in a new thread.\n    auto childTid = spawn(&spawnedFunc, thisTid);\n\n    // Send the number 42 to this new thread.\n    send(childTid, 42);\n\n    // Receive the result code.\n    auto wasSuccessful = receiveOnly!(bool);\n    assert(wasSuccessful);\n    assert(received == \"Received the number 42\");\n}\n\nprivate\n{\n    bool hasLocalAliasing(Types...)()\n    {\n        // Works around \"statement is not reachable\"\n        bool doesIt = false;\n        static foreach (T; Types)\n        {\n            static if (is(T == Tid))\n            { /* Allowed */ }\n            else static if (is(T == struct))\n                doesIt |= hasLocalAliasing!(typeof(T.tupleof));\n            else\n                doesIt |= std.traits.hasUnsharedAliasing!(T);\n        }\n        return doesIt;\n    }\n\n    @safe unittest\n    {\n        static struct Container { Tid t; }\n        static assert(!hasLocalAliasing!(Tid, Container, int));\n    }\n\n    enum MsgType\n    {\n        standard,\n        priority,\n        linkDead,\n    }\n\n    struct Message\n    {\n        MsgType type;\n        Variant data;\n\n        this(T...)(MsgType t, T vals) if (T.length > 0)\n        {\n            static if (T.length == 1)\n            {\n                type = t;\n                data = vals[0];\n            }\n            else\n            {\n                import std.typecons : Tuple;\n\n                type = t;\n                data = Tuple!(T)(vals);\n            }\n        }\n\n        @property auto convertsTo(T...)()\n        {\n            static if (T.length == 1)\n            {\n                return is(T[0] == Variant) || data.convertsTo!(T);\n            }\n            else\n            {\n                import std.typecons : Tuple;\n                return data.convertsTo!(Tuple!(T));\n            }\n        }\n\n        @property auto get(T...)()\n        {\n            static if (T.length == 1)\n            {\n                static if (is(T[0] == Variant))\n                    return data;\n                else\n                    return data.get!(T);\n            }\n            else\n            {\n                import std.typecons : Tuple;\n                return data.get!(Tuple!(T));\n            }\n        }\n\n        auto map(Op)(Op op)\n        {\n            alias Args = Parameters!(Op);\n\n            static if (Args.length == 1)\n            {\n                static if (is(Args[0] == Variant))\n                    return op(data);\n                else\n                    return op(data.get!(Args));\n            }\n            else\n            {\n                import std.typecons : Tuple;\n                return op(data.get!(Tuple!(Args)).expand);\n            }\n        }\n    }\n\n    void checkops(T...)(T ops)\n    {\n        foreach (i, t1; T)\n        {\n            static assert(isFunctionPointer!t1 || isDelegate!t1);\n            alias a1 = Parameters!(t1);\n            alias r1 = ReturnType!(t1);\n\n            static if (i < T.length - 1 && is(r1 == void))\n            {\n                static assert(a1.length != 1 || !is(a1[0] == Variant),\n                              \"function with arguments \" ~ a1.stringof ~\n                              \" occludes successive function\");\n\n                foreach (t2; T[i + 1 .. $])\n                {\n                    static assert(isFunctionPointer!t2 || isDelegate!t2);\n                    alias a2 = Parameters!(t2);\n\n                    static assert(!is(a1 == a2),\n                        \"function with arguments \" ~ a1.stringof ~ \" occludes successive function\");\n                }\n            }\n        }\n    }\n\n    @property ref ThreadInfo thisInfo() nothrow\n    {\n        if (scheduler is null)\n            return ThreadInfo.thisInfo;\n        return scheduler.thisInfo;\n    }\n}\n\nstatic ~this()\n{\n    thisInfo.cleanup();\n}\n\n// Exceptions\n\n/**\n * Thrown on calls to `receiveOnly` if a message other than the type\n * the receiving thread expected is sent.\n */\nclass MessageMismatch : Exception\n{\n    ///\n    this(string msg = \"Unexpected message type\") @safe pure nothrow @nogc\n    {\n        super(msg);\n    }\n}\n\n/**\n * Thrown on calls to `receive` if the thread that spawned the receiving\n * thread has terminated and no more messages exist.\n */\nclass OwnerTerminated : Exception\n{\n    ///\n    this(Tid t, string msg = \"Owner terminated\") @safe pure nothrow @nogc\n    {\n        super(msg);\n        tid = t;\n    }\n\n    Tid tid;\n}\n\n/**\n * Thrown if a linked thread has terminated.\n */\nclass LinkTerminated : Exception\n{\n    ///\n    this(Tid t, string msg = \"Link terminated\") @safe pure nothrow @nogc\n    {\n        super(msg);\n        tid = t;\n    }\n\n    Tid tid;\n}\n\n/**\n * Thrown if a message was sent to a thread via\n * $(REF prioritySend, std,concurrency) and the receiver does not have a handler\n * for a message of this type.\n */\nclass PriorityMessageException : Exception\n{\n    ///\n    this(Variant vals)\n    {\n        super(\"Priority message\");\n        message = vals;\n    }\n\n    /**\n     * The message that was sent.\n     */\n    Variant message;\n}\n\n/**\n * Thrown on mailbox crowding if the mailbox is configured with\n * `OnCrowding.throwException`.\n */\nclass MailboxFull : Exception\n{\n    ///\n    this(Tid t, string msg = \"Mailbox full\") @safe pure nothrow @nogc\n    {\n        super(msg);\n        tid = t;\n    }\n\n    Tid tid;\n}\n\n/**\n * Thrown when a Tid is missing, e.g. when `ownerTid` doesn't\n * find an owner thread.\n */\nclass TidMissingException : Exception\n{\n    import std.exception : basicExceptionCtors;\n    ///\n    mixin basicExceptionCtors;\n}\n\n\n// Thread ID\n\n\n/**\n * An opaque type used to represent a logical thread.\n */\nstruct Tid\n{\nprivate:\n    this(MessageBox m) @safe pure nothrow @nogc\n    {\n        mbox = m;\n    }\n\n    MessageBox mbox;\n\npublic:\n\n    /**\n     * Generate a convenient string for identifying this Tid.  This is only\n     * useful to see if Tid's that are currently executing are the same or\n     * different, e.g. for logging and debugging.  It is potentially possible\n     * that a Tid executed in the future will have the same toString() output\n     * as another Tid that has already terminated.\n     */\n    void toString(scope void delegate(const(char)[]) sink)\n    {\n        import std.format : formattedWrite;\n        formattedWrite(sink, \"Tid(%x)\", cast(void*) mbox);\n    }\n\n}\n\n@system unittest\n{\n    // text!Tid is @system\n    import std.conv : text;\n    Tid tid;\n    assert(text(tid) == \"Tid(0)\");\n    auto tid2 = thisTid;\n    assert(text(tid2) != \"Tid(0)\");\n    auto tid3 = tid2;\n    assert(text(tid2) == text(tid3));\n}\n\n/**\n * Returns: The $(LREF Tid) of the caller's thread.\n */\n@property Tid thisTid() @safe\n{\n    // TODO: remove when concurrency is safe\n    static auto trus() @trusted\n    {\n        if (thisInfo.ident != Tid.init)\n            return thisInfo.ident;\n        thisInfo.ident = Tid(new MessageBox);\n        return thisInfo.ident;\n    }\n\n    return trus();\n}\n\n/**\n * Return the Tid of the thread which spawned the caller's thread.\n *\n * Throws: A `TidMissingException` exception if\n * there is no owner thread.\n */\n@property Tid ownerTid()\n{\n    import std.exception : enforce;\n\n    enforce!TidMissingException(thisInfo.owner.mbox !is null, \"Error: Thread has no owner thread.\");\n    return thisInfo.owner;\n}\n\n@system unittest\n{\n    import std.exception : assertThrown;\n\n    static void fun()\n    {\n        string res = receiveOnly!string();\n        assert(res == \"Main calling\");\n        ownerTid.send(\"Child responding\");\n    }\n\n    assertThrown!TidMissingException(ownerTid);\n    auto child = spawn(&fun);\n    child.send(\"Main calling\");\n    string res = receiveOnly!string();\n    assert(res == \"Child responding\");\n}\n\n// Thread Creation\n\nprivate template isSpawnable(F, T...)\n{\n    template isParamsImplicitlyConvertible(F1, F2, int i = 0)\n    {\n        alias param1 = Parameters!F1;\n        alias param2 = Parameters!F2;\n        static if (param1.length != param2.length)\n            enum isParamsImplicitlyConvertible = false;\n        else static if (param1.length == i)\n            enum isParamsImplicitlyConvertible = true;\n        else static if (isImplicitlyConvertible!(param2[i], param1[i]))\n            enum isParamsImplicitlyConvertible = isParamsImplicitlyConvertible!(F1,\n                    F2, i + 1);\n        else\n            enum isParamsImplicitlyConvertible = false;\n    }\n\n    enum isSpawnable = isCallable!F && is(ReturnType!F == void)\n            && isParamsImplicitlyConvertible!(F, void function(T))\n            && (isFunctionPointer!F || !hasUnsharedAliasing!F);\n}\n\n/**\n * Starts fn(args) in a new logical thread.\n *\n * Executes the supplied function in a new logical thread represented by\n * `Tid`.  The calling thread is designated as the owner of the new thread.\n * When the owner thread terminates an `OwnerTerminated` message will be\n * sent to the new thread, causing an `OwnerTerminated` exception to be\n * thrown on `receive()`.\n *\n * Params:\n *  fn   = The function to execute.\n *  args = Arguments to the function.\n *\n * Returns:\n *  A Tid representing the new logical thread.\n *\n * Notes:\n *  `args` must not have unshared aliasing.  In other words, all arguments\n *  to `fn` must either be `shared` or `immutable` or have no\n *  pointer indirection.  This is necessary for enforcing isolation among\n *  threads.\n */\nTid spawn(F, T...)(F fn, T args)\nif (isSpawnable!(F, T))\n{\n    static assert(!hasLocalAliasing!(T), \"Aliases to mutable thread-local data not allowed.\");\n    return _spawn(false, fn, args);\n}\n\n///\n@system unittest\n{\n    static void f(string msg)\n    {\n        assert(msg == \"Hello World\");\n    }\n\n    auto tid = spawn(&f, \"Hello World\");\n}\n\n/// Fails: char[] has mutable aliasing.\n@system unittest\n{\n    string msg = \"Hello, World!\";\n\n    static void f1(string msg) {}\n    static assert(!__traits(compiles, spawn(&f1, msg.dup)));\n    static assert( __traits(compiles, spawn(&f1, msg.idup)));\n\n    static void f2(char[] msg) {}\n    static assert(!__traits(compiles, spawn(&f2, msg.dup)));\n    static assert(!__traits(compiles, spawn(&f2, msg.idup)));\n}\n\n/// New thread with anonymous function\n@system unittest\n{\n    spawn({\n        ownerTid.send(\"This is so great!\");\n    });\n    assert(receiveOnly!string == \"This is so great!\");\n}\n\n@system unittest\n{\n    import core.thread : thread_joinAll;\n\n    __gshared string receivedMessage;\n    static void f1(string msg)\n    {\n        receivedMessage = msg;\n    }\n\n    auto tid1 = spawn(&f1, \"Hello World\");\n    thread_joinAll;\n    assert(receivedMessage == \"Hello World\");\n}\n\n/**\n * Starts fn(args) in a logical thread and will receive a LinkTerminated\n * message when the operation terminates.\n *\n * Executes the supplied function in a new logical thread represented by\n * Tid.  This new thread is linked to the calling thread so that if either\n * it or the calling thread terminates a LinkTerminated message will be sent\n * to the other, causing a LinkTerminated exception to be thrown on receive().\n * The owner relationship from spawn() is preserved as well, so if the link\n * between threads is broken, owner termination will still result in an\n * OwnerTerminated exception to be thrown on receive().\n *\n * Params:\n *  fn   = The function to execute.\n *  args = Arguments to the function.\n *\n * Returns:\n *  A Tid representing the new thread.\n */\nTid spawnLinked(F, T...)(F fn, T args)\nif (isSpawnable!(F, T))\n{\n    static assert(!hasLocalAliasing!(T), \"Aliases to mutable thread-local data not allowed.\");\n    return _spawn(true, fn, args);\n}\n\n/*\n *\n */\nprivate Tid _spawn(F, T...)(bool linked, F fn, T args)\nif (isSpawnable!(F, T))\n{\n    // TODO: MessageList and &exec should be shared.\n    auto spawnTid = Tid(new MessageBox);\n    auto ownerTid = thisTid;\n\n    void exec()\n    {\n        thisInfo.ident = spawnTid;\n        thisInfo.owner = ownerTid;\n        fn(args);\n    }\n\n    // TODO: MessageList and &exec should be shared.\n    if (scheduler !is null)\n        scheduler.spawn(&exec);\n    else\n    {\n        auto t = new Thread(&exec);\n        t.start();\n    }\n    thisInfo.links[spawnTid] = linked;\n    return spawnTid;\n}\n\n@system unittest\n{\n    void function() fn1;\n    void function(int) fn2;\n    static assert(__traits(compiles, spawn(fn1)));\n    static assert(__traits(compiles, spawn(fn2, 2)));\n    static assert(!__traits(compiles, spawn(fn1, 1)));\n    static assert(!__traits(compiles, spawn(fn2)));\n\n    void delegate(int) shared dg1;\n    shared(void delegate(int)) dg2;\n    shared(void delegate(long) shared) dg3;\n    shared(void delegate(real, int, long) shared) dg4;\n    void delegate(int) immutable dg5;\n    void delegate(int) dg6;\n    static assert(__traits(compiles, spawn(dg1, 1)));\n    static assert(__traits(compiles, spawn(dg2, 2)));\n    static assert(__traits(compiles, spawn(dg3, 3)));\n    static assert(__traits(compiles, spawn(dg4, 4, 4, 4)));\n    static assert(__traits(compiles, spawn(dg5, 5)));\n    static assert(!__traits(compiles, spawn(dg6, 6)));\n\n    auto callable1  = new class{ void opCall(int) shared {} };\n    auto callable2  = cast(shared) new class{ void opCall(int) shared {} };\n    auto callable3  = new class{ void opCall(int) immutable {} };\n    auto callable4  = cast(immutable) new class{ void opCall(int) immutable {} };\n    auto callable5  = new class{ void opCall(int) {} };\n    auto callable6  = cast(shared) new class{ void opCall(int) immutable {} };\n    auto callable7  = cast(immutable) new class{ void opCall(int) shared {} };\n    auto callable8  = cast(shared) new class{ void opCall(int) const shared {} };\n    auto callable9  = cast(const shared) new class{ void opCall(int) shared {} };\n    auto callable10 = cast(const shared) new class{ void opCall(int) const shared {} };\n    auto callable11 = cast(immutable) new class{ void opCall(int) const shared {} };\n    static assert(!__traits(compiles, spawn(callable1,  1)));\n    static assert( __traits(compiles, spawn(callable2,  2)));\n    static assert(!__traits(compiles, spawn(callable3,  3)));\n    static assert( __traits(compiles, spawn(callable4,  4)));\n    static assert(!__traits(compiles, spawn(callable5,  5)));\n    static assert(!__traits(compiles, spawn(callable6,  6)));\n    static assert(!__traits(compiles, spawn(callable7,  7)));\n    static assert( __traits(compiles, spawn(callable8,  8)));\n    static assert(!__traits(compiles, spawn(callable9,  9)));\n    static assert( __traits(compiles, spawn(callable10, 10)));\n    static assert( __traits(compiles, spawn(callable11, 11)));\n}\n\n/**\n * Places the values as a message at the back of tid's message queue.\n *\n * Sends the supplied value to the thread represented by tid.  As with\n * $(REF spawn, std,concurrency), `T` must not have unshared aliasing.\n */\nvoid send(T...)(Tid tid, T vals)\n{\n    static assert(!hasLocalAliasing!(T), \"Aliases to mutable thread-local data not allowed.\");\n    _send(tid, vals);\n}\n\n/**\n * Places the values as a message on the front of tid's message queue.\n *\n * Send a message to `tid` but place it at the front of `tid`'s message\n * queue instead of at the back.  This function is typically used for\n * out-of-band communication, to signal exceptional conditions, etc.\n */\nvoid prioritySend(T...)(Tid tid, T vals)\n{\n    static assert(!hasLocalAliasing!(T), \"Aliases to mutable thread-local data not allowed.\");\n    _send(MsgType.priority, tid, vals);\n}\n\n/*\n * ditto\n */\nprivate void _send(T...)(Tid tid, T vals)\n{\n    _send(MsgType.standard, tid, vals);\n}\n\n/*\n * Implementation of send.  This allows parameter checking to be different for\n * both Tid.send() and .send().\n */\nprivate void _send(T...)(MsgType type, Tid tid, T vals)\n{\n    auto msg = Message(type, vals);\n    tid.mbox.put(msg);\n}\n\n/**\n * Receives a message from another thread.\n *\n * Receive a message from another thread, or block if no messages of the\n * specified types are available.  This function works by pattern matching\n * a message against a set of delegates and executing the first match found.\n *\n * If a delegate that accepts a $(REF Variant, std,variant) is included as\n * the last argument to `receive`, it will match any message that was not\n * matched by an earlier delegate.  If more than one argument is sent,\n * the `Variant` will contain a $(REF Tuple, std,typecons) of all values\n * sent.\n */\nvoid receive(T...)( T ops )\nin\n{\n    assert(thisInfo.ident.mbox !is null,\n           \"Cannot receive a message until a thread was spawned \"\n           ~ \"or thisTid was passed to a running thread.\");\n}\ndo\n{\n    checkops( ops );\n\n    thisInfo.ident.mbox.get( ops );\n}\n\n///\n@system unittest\n{\n    import std.variant : Variant;\n\n    auto process = ()\n    {\n        receive(\n            (int i) { ownerTid.send(1); },\n            (double f) { ownerTid.send(2); },\n            (Variant v) { ownerTid.send(3); }\n        );\n    };\n\n    {\n        auto tid = spawn(process);\n        send(tid, 42);\n        assert(receiveOnly!int == 1);\n    }\n\n    {\n        auto tid = spawn(process);\n        send(tid, 3.14);\n        assert(receiveOnly!int == 2);\n    }\n\n    {\n        auto tid = spawn(process);\n        send(tid, \"something else\");\n        assert(receiveOnly!int == 3);\n    }\n}\n\n@safe unittest\n{\n    static assert( __traits( compiles,\n                      {\n                          receive( (Variant x) {} );\n                          receive( (int x) {}, (Variant x) {} );\n                      } ) );\n\n    static assert( !__traits( compiles,\n                       {\n                           receive( (Variant x) {}, (int x) {} );\n                       } ) );\n\n    static assert( !__traits( compiles,\n                       {\n                           receive( (int x) {}, (int x) {} );\n                       } ) );\n}\n\n// Make sure receive() works with free functions as well.\nversion (unittest)\n{\n    private void receiveFunction(int x) {}\n}\n@safe unittest\n{\n    static assert( __traits( compiles,\n                      {\n                          receive( &receiveFunction );\n                          receive( &receiveFunction, (Variant x) {} );\n                      } ) );\n}\n\n\nprivate template receiveOnlyRet(T...)\n{\n    static if ( T.length == 1 )\n    {\n        alias receiveOnlyRet = T[0];\n    }\n    else\n    {\n        import std.typecons : Tuple;\n        alias receiveOnlyRet = Tuple!(T);\n    }\n}\n\n/**\n * Receives only messages with arguments of types `T`.\n *\n * Throws:  `MessageMismatch` if a message of types other than `T`\n *          is received.\n *\n * Returns: The received message.  If `T.length` is greater than one,\n *          the message will be packed into a $(REF Tuple, std,typecons).\n */\nreceiveOnlyRet!(T) receiveOnly(T...)()\nin\n{\n    assert(thisInfo.ident.mbox !is null,\n        \"Cannot receive a message until a thread was spawned or thisTid was passed to a running thread.\");\n}\ndo\n{\n    import std.format : format;\n    import std.typecons : Tuple;\n\n    Tuple!(T) ret;\n\n    thisInfo.ident.mbox.get((T val) {\n        static if (T.length)\n            ret.field = val;\n    },\n    (LinkTerminated e) { throw e; },\n    (OwnerTerminated e) { throw e; },\n    (Variant val) {\n        static if (T.length > 1)\n            string exp = T.stringof;\n        else\n            string exp = T[0].stringof;\n\n        throw new MessageMismatch(\n            format(\"Unexpected message type: expected '%s', got '%s'\", exp, val.type.toString()));\n    });\n    static if (T.length == 1)\n        return ret[0];\n    else\n        return ret;\n}\n\n///\n@system unittest\n{\n    auto tid = spawn(\n    {\n        assert(receiveOnly!int == 42);\n    });\n    send(tid, 42);\n}\n\n///\n@system unittest\n{\n    auto tid = spawn(\n    {\n        assert(receiveOnly!string == \"text\");\n    });\n    send(tid, \"text\");\n}\n\n///\n@system unittest\n{\n    struct Record { string name; int age; }\n\n    auto tid = spawn(\n    {\n        auto msg = receiveOnly!(double, Record);\n        assert(msg[0] == 0.5);\n        assert(msg[1].name == \"Alice\");\n        assert(msg[1].age == 31);\n    });\n\n    send(tid, 0.5, Record(\"Alice\", 31));\n}\n\n@system unittest\n{\n    static void t1(Tid mainTid)\n    {\n        try\n        {\n            receiveOnly!string();\n            mainTid.send(\"\");\n        }\n        catch (Throwable th)\n        {\n            mainTid.send(th.msg);\n        }\n    }\n\n    auto tid = spawn(&t1, thisTid);\n    tid.send(1);\n    string result = receiveOnly!string();\n    assert(result == \"Unexpected message type: expected 'string', got 'int'\");\n}\n\n/**\n * Tries to receive but will give up if no matches arrive within duration.\n * Won't wait at all if provided $(REF Duration, core,time) is negative.\n *\n * Same as `receive` except that rather than wait forever for a message,\n * it waits until either it receives a message or the given\n * $(REF Duration, core,time) has passed. It returns `true` if it received a\n * message and `false` if it timed out waiting for one.\n */\nbool receiveTimeout(T...)(Duration duration, T ops)\nin\n{\n    assert(thisInfo.ident.mbox !is null,\n        \"Cannot receive a message until a thread was spawned or thisTid was passed to a running thread.\");\n}\ndo\n{\n    checkops(ops);\n\n    return thisInfo.ident.mbox.get(duration, ops);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, {\n        receiveTimeout(msecs(0), (Variant x) {});\n        receiveTimeout(msecs(0), (int x) {}, (Variant x) {});\n    }));\n\n    static assert(!__traits(compiles, {\n        receiveTimeout(msecs(0), (Variant x) {}, (int x) {});\n    }));\n\n    static assert(!__traits(compiles, {\n        receiveTimeout(msecs(0), (int x) {}, (int x) {});\n    }));\n\n    static assert(__traits(compiles, {\n        receiveTimeout(msecs(10), (int x) {}, (Variant x) {});\n    }));\n}\n\n// MessageBox Limits\n\n/**\n * These behaviors may be specified when a mailbox is full.\n */\nenum OnCrowding\n{\n    block, /// Wait until room is available.\n    throwException, /// Throw a MailboxFull exception.\n    ignore /// Abort the send and return.\n}\n\nprivate\n{\n    bool onCrowdingBlock(Tid tid) @safe pure nothrow @nogc\n    {\n        return true;\n    }\n\n    bool onCrowdingThrow(Tid tid) @safe pure\n    {\n        throw new MailboxFull(tid);\n    }\n\n    bool onCrowdingIgnore(Tid tid) @safe pure nothrow @nogc\n    {\n        return false;\n    }\n}\n\n/**\n * Sets a maximum mailbox size.\n *\n * Sets a limit on the maximum number of user messages allowed in the mailbox.\n * If this limit is reached, the caller attempting to add a new message will\n * execute the behavior specified by doThis.  If messages is zero, the mailbox\n * is unbounded.\n *\n * Params:\n *  tid      = The Tid of the thread for which this limit should be set.\n *  messages = The maximum number of messages or zero if no limit.\n *  doThis   = The behavior executed when a message is sent to a full\n *             mailbox.\n */\nvoid setMaxMailboxSize(Tid tid, size_t messages, OnCrowding doThis) @safe pure\n{\n    final switch (doThis)\n    {\n    case OnCrowding.block:\n        return tid.mbox.setMaxMsgs(messages, &onCrowdingBlock);\n    case OnCrowding.throwException:\n        return tid.mbox.setMaxMsgs(messages, &onCrowdingThrow);\n    case OnCrowding.ignore:\n        return tid.mbox.setMaxMsgs(messages, &onCrowdingIgnore);\n    }\n}\n\n/**\n * Sets a maximum mailbox size.\n *\n * Sets a limit on the maximum number of user messages allowed in the mailbox.\n * If this limit is reached, the caller attempting to add a new message will\n * execute onCrowdingDoThis.  If messages is zero, the mailbox is unbounded.\n *\n * Params:\n *  tid      = The Tid of the thread for which this limit should be set.\n *  messages = The maximum number of messages or zero if no limit.\n *  onCrowdingDoThis = The routine called when a message is sent to a full\n *                     mailbox.\n */\nvoid setMaxMailboxSize(Tid tid, size_t messages, bool function(Tid) onCrowdingDoThis)\n{\n    tid.mbox.setMaxMsgs(messages, onCrowdingDoThis);\n}\n\nprivate\n{\n    __gshared Tid[string] tidByName;\n    __gshared string[][Tid] namesByTid;\n}\n\nprivate @property Mutex registryLock()\n{\n    __gshared Mutex impl;\n    initOnce!impl(new Mutex);\n    return impl;\n}\n\nprivate void unregisterMe()\n{\n    auto me = thisInfo.ident;\n    if (thisInfo.ident != Tid.init)\n    {\n        synchronized (registryLock)\n        {\n            if (auto allNames = me in namesByTid)\n            {\n                foreach (name; *allNames)\n                    tidByName.remove(name);\n                namesByTid.remove(me);\n            }\n        }\n    }\n}\n\n/**\n * Associates name with tid.\n *\n * Associates name with tid in a process-local map.  When the thread\n * represented by tid terminates, any names associated with it will be\n * automatically unregistered.\n *\n * Params:\n *  name = The name to associate with tid.\n *  tid  = The tid register by name.\n *\n * Returns:\n *  true if the name is available and tid is not known to represent a\n *  defunct thread.\n */\nbool register(string name, Tid tid)\n{\n    synchronized (registryLock)\n    {\n        if (name in tidByName)\n            return false;\n        if (tid.mbox.isClosed)\n            return false;\n        namesByTid[tid] ~= name;\n        tidByName[name] = tid;\n        return true;\n    }\n}\n\n/**\n * Removes the registered name associated with a tid.\n *\n * Params:\n *  name = The name to unregister.\n *\n * Returns:\n *  true if the name is registered, false if not.\n */\nbool unregister(string name)\n{\n    import std.algorithm.mutation : remove, SwapStrategy;\n    import std.algorithm.searching : countUntil;\n\n    synchronized (registryLock)\n    {\n        if (auto tid = name in tidByName)\n        {\n            auto allNames = *tid in namesByTid;\n            auto pos = countUntil(*allNames, name);\n            remove!(SwapStrategy.unstable)(*allNames, pos);\n            tidByName.remove(name);\n            return true;\n        }\n        return false;\n    }\n}\n\n/**\n * Gets the Tid associated with name.\n *\n * Params:\n *  name = The name to locate within the registry.\n *\n * Returns:\n *  The associated Tid or Tid.init if name is not registered.\n */\nTid locate(string name)\n{\n    synchronized (registryLock)\n    {\n        if (auto tid = name in tidByName)\n            return *tid;\n        return Tid.init;\n    }\n}\n\n/**\n * Encapsulates all implementation-level data needed for scheduling.\n *\n * When defining a Scheduler, an instance of this struct must be associated\n * with each logical thread.  It contains all implementation-level information\n * needed by the internal API.\n */\nstruct ThreadInfo\n{\n    Tid ident;\n    bool[Tid] links;\n    Tid owner;\n\n    /**\n     * Gets a thread-local instance of ThreadInfo.\n     *\n     * Gets a thread-local instance of ThreadInfo, which should be used as the\n     * default instance when info is requested for a thread not created by the\n     * Scheduler.\n     */\n    static @property ref thisInfo() nothrow\n    {\n        static ThreadInfo val;\n        return val;\n    }\n\n    /**\n     * Cleans up this ThreadInfo.\n     *\n     * This must be called when a scheduled thread terminates.  It tears down\n     * the messaging system for the thread and notifies interested parties of\n     * the thread's termination.\n     */\n    void cleanup()\n    {\n        if (ident.mbox !is null)\n            ident.mbox.close();\n        foreach (tid; links.keys)\n            _send(MsgType.linkDead, tid, ident);\n        if (owner != Tid.init)\n            _send(MsgType.linkDead, owner, ident);\n        unregisterMe(); // clean up registry entries\n    }\n}\n\n/**\n * A Scheduler controls how threading is performed by spawn.\n *\n * Implementing a Scheduler allows the concurrency mechanism used by this\n * module to be customized according to different needs.  By default, a call\n * to spawn will create a new kernel thread that executes the supplied routine\n * and terminates when finished.  But it is possible to create Schedulers that\n * reuse threads, that multiplex Fibers (coroutines) across a single thread,\n * or any number of other approaches.  By making the choice of Scheduler a\n * user-level option, std.concurrency may be used for far more types of\n * application than if this behavior were predefined.\n *\n * Example:\n * ---\n * import std.concurrency;\n * import std.stdio;\n *\n * void main()\n * {\n *     scheduler = new FiberScheduler;\n *     scheduler.start(\n *     {\n *         writeln(\"the rest of main goes here\");\n *     });\n * }\n * ---\n *\n * Some schedulers have a dispatching loop that must run if they are to work\n * properly, so for the sake of consistency, when using a scheduler, start()\n * must be called within main().  This yields control to the scheduler and\n * will ensure that any spawned threads are executed in an expected manner.\n */\ninterface Scheduler\n{\n    /**\n     * Spawns the supplied op and starts the Scheduler.\n     *\n     * This is intended to be called at the start of the program to yield all\n     * scheduling to the active Scheduler instance.  This is necessary for\n     * schedulers that explicitly dispatch threads rather than simply relying\n     * on the operating system to do so, and so start should always be called\n     * within main() to begin normal program execution.\n     *\n     * Params:\n     *  op = A wrapper for whatever the main thread would have done in the\n     *       absence of a custom scheduler.  It will be automatically executed\n     *       via a call to spawn by the Scheduler.\n     */\n    void start(void delegate() op);\n\n    /**\n     * Assigns a logical thread to execute the supplied op.\n     *\n     * This routine is called by spawn.  It is expected to instantiate a new\n     * logical thread and run the supplied operation.  This thread must call\n     * thisInfo.cleanup() when the thread terminates if the scheduled thread\n     * is not a kernel thread--all kernel threads will have their ThreadInfo\n     * cleaned up automatically by a thread-local destructor.\n     *\n     * Params:\n     *  op = The function to execute.  This may be the actual function passed\n     *       by the user to spawn itself, or may be a wrapper function.\n     */\n    void spawn(void delegate() op);\n\n    /**\n     * Yields execution to another logical thread.\n     *\n     * This routine is called at various points within concurrency-aware APIs\n     * to provide a scheduler a chance to yield execution when using some sort\n     * of cooperative multithreading model.  If this is not appropriate, such\n     * as when each logical thread is backed by a dedicated kernel thread,\n     * this routine may be a no-op.\n     */\n    void yield() nothrow;\n\n    /**\n     * Returns an appropriate ThreadInfo instance.\n     *\n     * Returns an instance of ThreadInfo specific to the logical thread that\n     * is calling this routine or, if the calling thread was not create by\n     * this scheduler, returns ThreadInfo.thisInfo instead.\n     */\n    @property ref ThreadInfo thisInfo() nothrow;\n\n    /**\n     * Creates a Condition variable analog for signaling.\n     *\n     * Creates a new Condition variable analog which is used to check for and\n     * to signal the addition of messages to a thread's message queue.  Like\n     * yield, some schedulers may need to define custom behavior so that calls\n     * to Condition.wait() yield to another thread when no new messages are\n     * available instead of blocking.\n     *\n     * Params:\n     *  m = The Mutex that will be associated with this condition.  It will be\n     *      locked prior to any operation on the condition, and so in some\n     *      cases a Scheduler may need to hold this reference and unlock the\n     *      mutex before yielding execution to another logical thread.\n     */\n    Condition newCondition(Mutex m) nothrow;\n}\n\n/**\n * An example Scheduler using kernel threads.\n *\n * This is an example Scheduler that mirrors the default scheduling behavior\n * of creating one kernel thread per call to spawn.  It is fully functional\n * and may be instantiated and used, but is not a necessary part of the\n * default functioning of this module.\n */\nclass ThreadScheduler : Scheduler\n{\n    /**\n     * This simply runs op directly, since no real scheduling is needed by\n     * this approach.\n     */\n    void start(void delegate() op)\n    {\n        op();\n    }\n\n    /**\n     * Creates a new kernel thread and assigns it to run the supplied op.\n     */\n    void spawn(void delegate() op)\n    {\n        auto t = new Thread(op);\n        t.start();\n    }\n\n    /**\n     * This scheduler does no explicit multiplexing, so this is a no-op.\n     */\n    void yield() nothrow\n    {\n        // no explicit yield needed\n    }\n\n    /**\n     * Returns ThreadInfo.thisInfo, since it is a thread-local instance of\n     * ThreadInfo, which is the correct behavior for this scheduler.\n     */\n    @property ref ThreadInfo thisInfo() nothrow\n    {\n        return ThreadInfo.thisInfo;\n    }\n\n    /**\n     * Creates a new Condition variable.  No custom behavior is needed here.\n     */\n    Condition newCondition(Mutex m) nothrow\n    {\n        return new Condition(m);\n    }\n}\n\n/**\n * An example Scheduler using Fibers.\n *\n * This is an example scheduler that creates a new Fiber per call to spawn\n * and multiplexes the execution of all fibers within the main thread.\n */\nclass FiberScheduler : Scheduler\n{\n    /**\n     * This creates a new Fiber for the supplied op and then starts the\n     * dispatcher.\n     */\n    void start(void delegate() op)\n    {\n        create(op);\n        dispatch();\n    }\n\n    /**\n     * This created a new Fiber for the supplied op and adds it to the\n     * dispatch list.\n     */\n    void spawn(void delegate() op) nothrow\n    {\n        create(op);\n        yield();\n    }\n\n    /**\n     * If the caller is a scheduled Fiber, this yields execution to another\n     * scheduled Fiber.\n     */\n    void yield() nothrow\n    {\n        // NOTE: It's possible that we should test whether the calling Fiber\n        //       is an InfoFiber before yielding, but I think it's reasonable\n        //       that any (non-Generator) fiber should yield here.\n        if (Fiber.getThis())\n            Fiber.yield();\n    }\n\n    /**\n     * Returns an appropriate ThreadInfo instance.\n     *\n     * Returns a ThreadInfo instance specific to the calling Fiber if the\n     * Fiber was created by this dispatcher, otherwise it returns\n     * ThreadInfo.thisInfo.\n     */\n    @property ref ThreadInfo thisInfo() nothrow\n    {\n        auto f = cast(InfoFiber) Fiber.getThis();\n\n        if (f !is null)\n            return f.info;\n        return ThreadInfo.thisInfo;\n    }\n\n    /**\n     * Returns a Condition analog that yields when wait or notify is called.\n     */\n    Condition newCondition(Mutex m) nothrow\n    {\n        return new FiberCondition(m);\n    }\n\nprivate:\n    static class InfoFiber : Fiber\n    {\n        ThreadInfo info;\n\n        this(void delegate() op) nothrow\n        {\n            super(op);\n        }\n    }\n\n    class FiberCondition : Condition\n    {\n        this(Mutex m) nothrow\n        {\n            super(m);\n            notified = false;\n        }\n\n        override void wait() nothrow\n        {\n            scope (exit) notified = false;\n\n            while (!notified)\n                switchContext();\n        }\n\n        override bool wait(Duration period) nothrow\n        {\n            import core.time : MonoTime;\n\n            scope (exit) notified = false;\n\n            for (auto limit = MonoTime.currTime + period;\n                 !notified && !period.isNegative;\n                 period = limit - MonoTime.currTime)\n            {\n                yield();\n            }\n            return notified;\n        }\n\n        override void notify() nothrow\n        {\n            notified = true;\n            switchContext();\n        }\n\n        override void notifyAll() nothrow\n        {\n            notified = true;\n            switchContext();\n        }\n\n    private:\n        void switchContext() nothrow\n        {\n            mutex_nothrow.unlock_nothrow();\n            scope (exit) mutex_nothrow.lock_nothrow();\n            yield();\n        }\n\n        private bool notified;\n    }\n\nprivate:\n    void dispatch()\n    {\n        import std.algorithm.mutation : remove;\n\n        while (m_fibers.length > 0)\n        {\n            auto t = m_fibers[m_pos].call(Fiber.Rethrow.no);\n            if (t !is null && !(cast(OwnerTerminated) t))\n            {\n                throw t;\n            }\n            if (m_fibers[m_pos].state == Fiber.State.TERM)\n            {\n                if (m_pos >= (m_fibers = remove(m_fibers, m_pos)).length)\n                    m_pos = 0;\n            }\n            else if (m_pos++ >= m_fibers.length - 1)\n            {\n                m_pos = 0;\n            }\n        }\n    }\n\n    void create(void delegate() op) nothrow\n    {\n        void wrap()\n        {\n            scope (exit)\n            {\n                thisInfo.cleanup();\n            }\n            op();\n        }\n\n        m_fibers ~= new InfoFiber(&wrap);\n    }\n\nprivate:\n    Fiber[] m_fibers;\n    size_t m_pos;\n}\n\n@system unittest\n{\n    static void receive(Condition cond, ref size_t received)\n    {\n        while (true)\n        {\n            synchronized (cond.mutex)\n            {\n                cond.wait();\n                ++received;\n            }\n        }\n    }\n\n    static void send(Condition cond, ref size_t sent)\n    {\n        while (true)\n        {\n            synchronized (cond.mutex)\n            {\n                ++sent;\n                cond.notify();\n            }\n        }\n    }\n\n    auto fs = new FiberScheduler;\n    auto mtx = new Mutex;\n    auto cond = fs.newCondition(mtx);\n\n    size_t received, sent;\n    auto waiter = new Fiber({ receive(cond, received); }), notifier = new Fiber({ send(cond, sent); });\n    waiter.call();\n    assert(received == 0);\n    notifier.call();\n    assert(sent == 1);\n    assert(received == 0);\n    waiter.call();\n    assert(received == 1);\n    waiter.call();\n    assert(received == 1);\n}\n\n/**\n * Sets the Scheduler behavior within the program.\n *\n * This variable sets the Scheduler behavior within this program.  Typically,\n * when setting a Scheduler, scheduler.start() should be called in main.  This\n * routine will not return until program execution is complete.\n */\n__gshared Scheduler scheduler;\n\n// Generator\n\n/**\n * If the caller is a Fiber and is not a Generator, this function will call\n * scheduler.yield() or Fiber.yield(), as appropriate.\n */\nvoid yield() nothrow\n{\n    auto fiber = Fiber.getThis();\n    if (!(cast(IsGenerator) fiber))\n    {\n        if (scheduler is null)\n        {\n            if (fiber)\n                return Fiber.yield();\n        }\n        else\n            scheduler.yield();\n    }\n}\n\n/// Used to determine whether a Generator is running.\nprivate interface IsGenerator {}\n\n\n/**\n * A Generator is a Fiber that periodically returns values of type T to the\n * caller via yield.  This is represented as an InputRange.\n */\nclass Generator(T) :\n    Fiber, IsGenerator, InputRange!T\n{\n    /**\n     * Initializes a generator object which is associated with a static\n     * D function.  The function will be called once to prepare the range\n     * for iteration.\n     *\n     * Params:\n     *  fn = The fiber function.\n     *\n     * In:\n     *  fn must not be null.\n     */\n    this(void function() fn)\n    {\n        super(fn);\n        call();\n    }\n\n    /**\n     * Initializes a generator object which is associated with a static\n     * D function.  The function will be called once to prepare the range\n     * for iteration.\n     *\n     * Params:\n     *  fn = The fiber function.\n     *  sz = The stack size for this fiber.\n     *\n     * In:\n     *  fn must not be null.\n     */\n    this(void function() fn, size_t sz)\n    {\n        super(fn, sz);\n        call();\n    }\n\n    /**\n     * Initializes a generator object which is associated with a static\n     * D function.  The function will be called once to prepare the range\n     * for iteration.\n     *\n     * Params:\n     *  fn = The fiber function.\n     *  sz = The stack size for this fiber.\n     *  guardPageSize = size of the guard page to trap fiber's stack\n     *                  overflows. Refer to $(REF Fiber, core,thread)'s\n     *                  documentation for more details.\n     *\n     * In:\n     *  fn must not be null.\n     */\n    this(void function() fn, size_t sz, size_t guardPageSize)\n    {\n        super(fn, sz, guardPageSize);\n        call();\n    }\n\n    /**\n     * Initializes a generator object which is associated with a dynamic\n     * D function.  The function will be called once to prepare the range\n     * for iteration.\n     *\n     * Params:\n     *  dg = The fiber function.\n     *\n     * In:\n     *  dg must not be null.\n     */\n    this(void delegate() dg)\n    {\n        super(dg);\n        call();\n    }\n\n    /**\n     * Initializes a generator object which is associated with a dynamic\n     * D function.  The function will be called once to prepare the range\n     * for iteration.\n     *\n     * Params:\n     *  dg = The fiber function.\n     *  sz = The stack size for this fiber.\n     *\n     * In:\n     *  dg must not be null.\n     */\n    this(void delegate() dg, size_t sz)\n    {\n        super(dg, sz);\n        call();\n    }\n\n    /**\n     * Initializes a generator object which is associated with a dynamic\n     * D function.  The function will be called once to prepare the range\n     * for iteration.\n     *\n     * Params:\n     *  dg = The fiber function.\n     *  sz = The stack size for this fiber.\n     *  guardPageSize = size of the guard page to trap fiber's stack\n     *                  overflows. Refer to $(REF Fiber, core,thread)'s\n     *                  documentation for more details.\n     *\n     * In:\n     *  dg must not be null.\n     */\n    this(void delegate() dg, size_t sz, size_t guardPageSize)\n    {\n        super(dg, sz, guardPageSize);\n        call();\n    }\n\n    /**\n     * Returns true if the generator is empty.\n     */\n    final bool empty() @property\n    {\n        return m_value is null || state == State.TERM;\n    }\n\n    /**\n     * Obtains the next value from the underlying function.\n     */\n    final void popFront()\n    {\n        call();\n    }\n\n    /**\n     * Returns the most recently generated value by shallow copy.\n     */\n    final T front() @property\n    {\n        return *m_value;\n    }\n\n    /**\n     * Returns the most recently generated value without executing a\n     * copy contructor. Will not compile for element types defining a\n     * postblit, because Generator does not return by reference.\n     */\n    final T moveFront()\n    {\n        static if (!hasElaborateCopyConstructor!T)\n        {\n            return front;\n        }\n        else\n        {\n            static assert(0,\n                    \"Fiber front is always rvalue and thus cannot be moved since it defines a postblit.\");\n        }\n    }\n\n    final int opApply(scope int delegate(T) loopBody)\n    {\n        int broken;\n        for (; !empty; popFront())\n        {\n            broken = loopBody(front);\n            if (broken) break;\n        }\n        return broken;\n    }\n\n    final int opApply(scope int delegate(size_t, T) loopBody)\n    {\n        int broken;\n        for (size_t i; !empty; ++i, popFront())\n        {\n            broken = loopBody(i, front);\n            if (broken) break;\n        }\n        return broken;\n    }\nprivate:\n    T* m_value;\n}\n\n///\n@system unittest\n{\n    auto tid = spawn({\n        int i;\n        while (i < 9)\n            i = receiveOnly!int;\n\n        ownerTid.send(i * 2);\n    });\n\n    auto r = new Generator!int({\n        foreach (i; 1 .. 10)\n            yield(i);\n    });\n\n    foreach (e; r)\n        tid.send(e);\n\n    assert(receiveOnly!int == 18);\n}\n\n/**\n * Yields a value of type T to the caller of the currently executing\n * generator.\n *\n * Params:\n *  value = The value to yield.\n */\nvoid yield(T)(ref T value)\n{\n    Generator!T cur = cast(Generator!T) Fiber.getThis();\n    if (cur !is null && cur.state == Fiber.State.EXEC)\n    {\n        cur.m_value = &value;\n        return Fiber.yield();\n    }\n    throw new Exception(\"yield(T) called with no active generator for the supplied type\");\n}\n\n/// ditto\nvoid yield(T)(T value)\n{\n    yield(value);\n}\n\n@system unittest\n{\n    import core.exception;\n    import std.exception;\n\n    static void testScheduler(Scheduler s)\n    {\n        scheduler = s;\n        scheduler.start({\n            auto tid = spawn({\n                int i;\n\n                try\n                {\n                    for (i = 1; i < 10; i++)\n                    {\n                        assertNotThrown!AssertError(assert(receiveOnly!int() == i));\n                    }\n                }\n                catch (OwnerTerminated e)\n                {\n\n                }\n\n                // i will advance 1 past the last value expected\n                assert(i == 4);\n            });\n\n            auto r = new Generator!int({\n                assertThrown!Exception(yield(2.0));\n                yield(); // ensure this is a no-op\n                yield(1);\n                yield(); // also once something has been yielded\n                yield(2);\n                yield(3);\n            });\n\n            foreach (e; r)\n            {\n                tid.send(e);\n            }\n        });\n        scheduler = null;\n    }\n\n    testScheduler(new ThreadScheduler);\n    testScheduler(new FiberScheduler);\n}\n///\n@system unittest\n{\n    import std.range;\n\n    InputRange!int myIota = iota(10).inputRangeObject;\n\n    myIota.popFront();\n    myIota.popFront();\n    assert(myIota.moveFront == 2);\n    assert(myIota.front == 2);\n    myIota.popFront();\n    assert(myIota.front == 3);\n\n    //can be assigned to std.range.interfaces.InputRange directly\n    myIota = new Generator!int(\n    {\n        foreach (i; 0 .. 10) yield(i);\n    });\n\n    myIota.popFront();\n    myIota.popFront();\n    assert(myIota.moveFront == 2);\n    assert(myIota.front == 2);\n    myIota.popFront();\n    assert(myIota.front == 3);\n\n    size_t[2] counter = [0, 0];\n    foreach (i, unused; myIota) counter[] += [1, i];\n\n    assert(myIota.empty);\n    assert(counter == [7, 21]);\n}\n\nprivate\n{\n    /*\n     * A MessageBox is a message queue for one thread.  Other threads may send\n     * messages to this owner by calling put(), and the owner receives them by\n     * calling get().  The put() call is therefore effectively shared and the\n     * get() call is effectively local.  setMaxMsgs may be used by any thread\n     * to limit the size of the message queue.\n     */\n    class MessageBox\n    {\n        this() @trusted nothrow /* TODO: make @safe after relevant druntime PR gets merged */\n        {\n            m_lock = new Mutex;\n            m_closed = false;\n\n            if (scheduler is null)\n            {\n                m_putMsg = new Condition(m_lock);\n                m_notFull = new Condition(m_lock);\n            }\n            else\n            {\n                m_putMsg = scheduler.newCondition(m_lock);\n                m_notFull = scheduler.newCondition(m_lock);\n            }\n        }\n\n        ///\n        final @property bool isClosed() @safe @nogc pure\n        {\n            synchronized (m_lock)\n            {\n                return m_closed;\n            }\n        }\n\n        /*\n         * Sets a limit on the maximum number of user messages allowed in the\n         * mailbox.  If this limit is reached, the caller attempting to add\n         * a new message will execute call.  If num is zero, there is no limit\n         * on the message queue.\n         *\n         * Params:\n         *  num  = The maximum size of the queue or zero if the queue is\n         *         unbounded.\n         *  call = The routine to call when the queue is full.\n         */\n        final void setMaxMsgs(size_t num, bool function(Tid) call) @safe @nogc pure\n        {\n            synchronized (m_lock)\n            {\n                m_maxMsgs = num;\n                m_onMaxMsgs = call;\n            }\n        }\n\n        /*\n         * If maxMsgs is not set, the message is added to the queue and the\n         * owner is notified.  If the queue is full, the message will still be\n         * accepted if it is a control message, otherwise onCrowdingDoThis is\n         * called.  If the routine returns true, this call will block until\n         * the owner has made space available in the queue.  If it returns\n         * false, this call will abort.\n         *\n         * Params:\n         *  msg = The message to put in the queue.\n         *\n         * Throws:\n         *  An exception if the queue is full and onCrowdingDoThis throws.\n         */\n        final void put(ref Message msg)\n        {\n            synchronized (m_lock)\n            {\n                // TODO: Generate an error here if m_closed is true, or maybe\n                //       put a message in the caller's queue?\n                if (!m_closed)\n                {\n                    while (true)\n                    {\n                        if (isPriorityMsg(msg))\n                        {\n                            m_sharedPty.put(msg);\n                            m_putMsg.notify();\n                            return;\n                        }\n                        if (!mboxFull() || isControlMsg(msg))\n                        {\n                            m_sharedBox.put(msg);\n                            m_putMsg.notify();\n                            return;\n                        }\n                        if (m_onMaxMsgs !is null && !m_onMaxMsgs(thisTid))\n                        {\n                            return;\n                        }\n                        m_putQueue++;\n                        m_notFull.wait();\n                        m_putQueue--;\n                    }\n                }\n            }\n        }\n\n        /*\n         * Matches ops against each message in turn until a match is found.\n         *\n         * Params:\n         *  ops = The operations to match.  Each may return a bool to indicate\n         *        whether a message with a matching type is truly a match.\n         *\n         * Returns:\n         *  true if a message was retrieved and false if not (such as if a\n         *  timeout occurred).\n         *\n         * Throws:\n         *  LinkTerminated if a linked thread terminated, or OwnerTerminated\n         * if the owner thread terminates and no existing messages match the\n         * supplied ops.\n         */\n        bool get(T...)(scope T vals)\n        {\n            import std.meta : AliasSeq;\n\n            static assert(T.length);\n\n            static if (isImplicitlyConvertible!(T[0], Duration))\n            {\n                alias Ops = AliasSeq!(T[1 .. $]);\n                alias ops = vals[1 .. $];\n                enum timedWait = true;\n                Duration period = vals[0];\n            }\n            else\n            {\n                alias Ops = AliasSeq!(T);\n                alias ops = vals[0 .. $];\n                enum timedWait = false;\n            }\n\n            bool onStandardMsg(ref Message msg)\n            {\n                foreach (i, t; Ops)\n                {\n                    alias Args = Parameters!(t);\n                    auto op = ops[i];\n\n                    if (msg.convertsTo!(Args))\n                    {\n                        static if (is(ReturnType!(t) == bool))\n                        {\n                            return msg.map(op);\n                        }\n                        else\n                        {\n                            msg.map(op);\n                            return true;\n                        }\n                    }\n                }\n                return false;\n            }\n\n            bool onLinkDeadMsg(ref Message msg)\n            {\n                assert(msg.convertsTo!(Tid));\n                auto tid = msg.get!(Tid);\n\n                if (bool* pDepends = tid in thisInfo.links)\n                {\n                    auto depends = *pDepends;\n                    thisInfo.links.remove(tid);\n                    // Give the owner relationship precedence.\n                    if (depends && tid != thisInfo.owner)\n                    {\n                        auto e = new LinkTerminated(tid);\n                        auto m = Message(MsgType.standard, e);\n                        if (onStandardMsg(m))\n                            return true;\n                        throw e;\n                    }\n                }\n                if (tid == thisInfo.owner)\n                {\n                    thisInfo.owner = Tid.init;\n                    auto e = new OwnerTerminated(tid);\n                    auto m = Message(MsgType.standard, e);\n                    if (onStandardMsg(m))\n                        return true;\n                    throw e;\n                }\n                return false;\n            }\n\n            bool onControlMsg(ref Message msg)\n            {\n                switch (msg.type)\n                {\n                case MsgType.linkDead:\n                    return onLinkDeadMsg(msg);\n                default:\n                    return false;\n                }\n            }\n\n            bool scan(ref ListT list)\n            {\n                for (auto range = list[]; !range.empty;)\n                {\n                    // Only the message handler will throw, so if this occurs\n                    // we can be certain that the message was handled.\n                    scope (failure)\n                        list.removeAt(range);\n\n                    if (isControlMsg(range.front))\n                    {\n                        if (onControlMsg(range.front))\n                        {\n                            // Although the linkDead message is a control message,\n                            // it can be handled by the user.  Since the linkDead\n                            // message throws if not handled, if we get here then\n                            // it has been handled and we can return from receive.\n                            // This is a weird special case that will have to be\n                            // handled in a more general way if more are added.\n                            if (!isLinkDeadMsg(range.front))\n                            {\n                                list.removeAt(range);\n                                continue;\n                            }\n                            list.removeAt(range);\n                            return true;\n                        }\n                        range.popFront();\n                        continue;\n                    }\n                    else\n                    {\n                        if (onStandardMsg(range.front))\n                        {\n                            list.removeAt(range);\n                            return true;\n                        }\n                        range.popFront();\n                        continue;\n                    }\n                }\n                return false;\n            }\n\n            bool pty(ref ListT list)\n            {\n                if (!list.empty)\n                {\n                    auto range = list[];\n\n                    if (onStandardMsg(range.front))\n                    {\n                        list.removeAt(range);\n                        return true;\n                    }\n                    if (range.front.convertsTo!(Throwable))\n                        throw range.front.get!(Throwable);\n                    else if (range.front.convertsTo!(shared(Throwable)))\n                        throw range.front.get!(shared(Throwable));\n                    else\n                        throw new PriorityMessageException(range.front.data);\n                }\n                return false;\n            }\n\n            static if (timedWait)\n            {\n                import core.time : MonoTime;\n                auto limit = MonoTime.currTime + period;\n            }\n\n            while (true)\n            {\n                ListT arrived;\n\n                if (pty(m_localPty) || scan(m_localBox))\n                {\n                    return true;\n                }\n                yield();\n                synchronized (m_lock)\n                {\n                    updateMsgCount();\n                    while (m_sharedPty.empty && m_sharedBox.empty)\n                    {\n                        // NOTE: We're notifying all waiters here instead of just\n                        //       a few because the onCrowding behavior may have\n                        //       changed and we don't want to block sender threads\n                        //       unnecessarily if the new behavior is not to block.\n                        //       This will admittedly result in spurious wakeups\n                        //       in other situations, but what can you do?\n                        if (m_putQueue && !mboxFull())\n                            m_notFull.notifyAll();\n                        static if (timedWait)\n                        {\n                            if (period <= Duration.zero || !m_putMsg.wait(period))\n                                return false;\n                        }\n                        else\n                        {\n                            m_putMsg.wait();\n                        }\n                    }\n                    m_localPty.put(m_sharedPty);\n                    arrived.put(m_sharedBox);\n                }\n                if (m_localPty.empty)\n                {\n                    scope (exit) m_localBox.put(arrived);\n                    if (scan(arrived))\n                    {\n                        return true;\n                    }\n                    else\n                    {\n                        static if (timedWait)\n                        {\n                            period = limit - MonoTime.currTime;\n                        }\n                        continue;\n                    }\n                }\n                m_localBox.put(arrived);\n                pty(m_localPty);\n                return true;\n            }\n        }\n\n        /*\n         * Called on thread termination.  This routine processes any remaining\n         * control messages, clears out message queues, and sets a flag to\n         * reject any future messages.\n         */\n        final void close()\n        {\n            static void onLinkDeadMsg(ref Message msg)\n            {\n                assert(msg.convertsTo!(Tid));\n                auto tid = msg.get!(Tid);\n\n                thisInfo.links.remove(tid);\n                if (tid == thisInfo.owner)\n                    thisInfo.owner = Tid.init;\n            }\n\n            static void sweep(ref ListT list)\n            {\n                for (auto range = list[]; !range.empty; range.popFront())\n                {\n                    if (range.front.type == MsgType.linkDead)\n                        onLinkDeadMsg(range.front);\n                }\n            }\n\n            ListT arrived;\n\n            sweep(m_localBox);\n            synchronized (m_lock)\n            {\n                arrived.put(m_sharedBox);\n                m_closed = true;\n            }\n            m_localBox.clear();\n            sweep(arrived);\n        }\n\n    private:\n        // Routines involving local data only, no lock needed.\n\n        bool mboxFull() @safe @nogc pure nothrow\n        {\n            return m_maxMsgs && m_maxMsgs <= m_localMsgs + m_sharedBox.length;\n        }\n\n        void updateMsgCount() @safe @nogc pure nothrow\n        {\n            m_localMsgs = m_localBox.length;\n        }\n\n        bool isControlMsg(ref Message msg) @safe @nogc pure nothrow\n        {\n            return msg.type != MsgType.standard && msg.type != MsgType.priority;\n        }\n\n        bool isPriorityMsg(ref Message msg) @safe @nogc pure nothrow\n        {\n            return msg.type == MsgType.priority;\n        }\n\n        bool isLinkDeadMsg(ref Message msg) @safe @nogc pure nothrow\n        {\n            return msg.type == MsgType.linkDead;\n        }\n\n        alias OnMaxFn = bool function(Tid);\n        alias ListT = List!(Message);\n\n        ListT m_localBox;\n        ListT m_localPty;\n\n        Mutex m_lock;\n        Condition m_putMsg;\n        Condition m_notFull;\n        size_t m_putQueue;\n        ListT m_sharedBox;\n        ListT m_sharedPty;\n        OnMaxFn m_onMaxMsgs;\n        size_t m_localMsgs;\n        size_t m_maxMsgs;\n        bool m_closed;\n    }\n\n    /*\n     *\n     */\n    struct List(T)\n    {\n        struct Range\n        {\n            import std.exception : enforce;\n\n            @property bool empty() const\n            {\n                return !m_prev.next;\n            }\n\n            @property ref T front()\n            {\n                enforce(m_prev.next, \"invalid list node\");\n                return m_prev.next.val;\n            }\n\n            @property void front(T val)\n            {\n                enforce(m_prev.next, \"invalid list node\");\n                m_prev.next.val = val;\n            }\n\n            void popFront()\n            {\n                enforce(m_prev.next, \"invalid list node\");\n                m_prev = m_prev.next;\n            }\n\n            private this(Node* p)\n            {\n                m_prev = p;\n            }\n\n            private Node* m_prev;\n        }\n\n        void put(T val)\n        {\n            put(newNode(val));\n        }\n\n        void put(ref List!(T) rhs)\n        {\n            if (!rhs.empty)\n            {\n                put(rhs.m_first);\n                while (m_last.next !is null)\n                {\n                    m_last = m_last.next;\n                    m_count++;\n                }\n                rhs.m_first = null;\n                rhs.m_last = null;\n                rhs.m_count = 0;\n            }\n        }\n\n        Range opSlice()\n        {\n            return Range(cast(Node*)&m_first);\n        }\n\n        void removeAt(Range r)\n        {\n            import std.exception : enforce;\n\n            assert(m_count);\n            Node* n = r.m_prev;\n            enforce(n && n.next, \"attempting to remove invalid list node\");\n\n            if (m_last is m_first)\n                m_last = null;\n            else if (m_last is n.next)\n                m_last = n; // nocoverage\n            Node* to_free = n.next;\n            n.next = n.next.next;\n            freeNode(to_free);\n            m_count--;\n        }\n\n        @property size_t length()\n        {\n            return m_count;\n        }\n\n        void clear()\n        {\n            m_first = m_last = null;\n            m_count = 0;\n        }\n\n        @property bool empty()\n        {\n            return m_first is null;\n        }\n\n    private:\n        struct Node\n        {\n            Node* next;\n            T val;\n\n            this(T v)\n            {\n                val = v;\n            }\n        }\n\n        static shared struct SpinLock\n        {\n            void lock() { while (!cas(&locked, false, true)) { Thread.yield(); } }\n            void unlock() { atomicStore!(MemoryOrder.rel)(locked, false); }\n            bool locked;\n        }\n\n        static shared SpinLock sm_lock;\n        static shared Node* sm_head;\n\n        Node* newNode(T v)\n        {\n            Node* n;\n            {\n                sm_lock.lock();\n                scope (exit) sm_lock.unlock();\n\n                if (sm_head)\n                {\n                    n = cast(Node*) sm_head;\n                    sm_head = sm_head.next;\n                }\n            }\n            if (n)\n            {\n                import std.conv : emplace;\n                emplace!Node(n, v);\n            }\n            else\n            {\n                n = new Node(v);\n            }\n            return n;\n        }\n\n        void freeNode(Node* n)\n        {\n            // destroy val to free any owned GC memory\n            destroy(n.val);\n\n            sm_lock.lock();\n            scope (exit) sm_lock.unlock();\n\n            auto sn = cast(shared(Node)*) n;\n            sn.next = sm_head;\n            sm_head = sn;\n        }\n\n        void put(Node* n)\n        {\n            m_count++;\n            if (!empty)\n            {\n                m_last.next = n;\n                m_last = n;\n                return;\n            }\n            m_first = n;\n            m_last = n;\n        }\n\n        Node* m_first;\n        Node* m_last;\n        size_t m_count;\n    }\n}\n\n@system unittest\n{\n    import std.typecons : tuple, Tuple;\n\n    static void testfn(Tid tid)\n    {\n        receive((float val) { assert(0); }, (int val, int val2) {\n            assert(val == 42 && val2 == 86);\n        });\n        receive((Tuple!(int, int) val) { assert(val[0] == 42 && val[1] == 86); });\n        receive((Variant val) {  });\n        receive((string val) {\n            if (\"the quick brown fox\" != val)\n                return false;\n            return true;\n        }, (string val) { assert(false); });\n        prioritySend(tid, \"done\");\n    }\n\n    static void runTest(Tid tid)\n    {\n        send(tid, 42, 86);\n        send(tid, tuple(42, 86));\n        send(tid, \"hello\", \"there\");\n        send(tid, \"the quick brown fox\");\n        receive((string val) { assert(val == \"done\"); });\n    }\n\n    static void simpleTest()\n    {\n        auto tid = spawn(&testfn, thisTid);\n        runTest(tid);\n\n        // Run the test again with a limited mailbox size.\n        tid = spawn(&testfn, thisTid);\n        setMaxMailboxSize(tid, 2, OnCrowding.block);\n        runTest(tid);\n    }\n\n    simpleTest();\n\n    scheduler = new ThreadScheduler;\n    simpleTest();\n    scheduler = null;\n}\n\nprivate @property shared(Mutex) initOnceLock()\n{\n    static shared Mutex lock;\n    if (auto mtx = atomicLoad!(MemoryOrder.acq)(lock))\n        return mtx;\n    auto mtx = new shared Mutex;\n    if (cas(&lock, cast(shared) null, mtx))\n        return mtx;\n    return atomicLoad!(MemoryOrder.acq)(lock);\n}\n\n/**\n * Initializes $(D_PARAM var) with the lazy $(D_PARAM init) value in a\n * thread-safe manner.\n *\n * The implementation guarantees that all threads simultaneously calling\n * initOnce with the same $(D_PARAM var) argument block until $(D_PARAM var) is\n * fully initialized. All side-effects of $(D_PARAM init) are globally visible\n * afterwards.\n *\n * Params:\n *   var = The variable to initialize\n *   init = The lazy initializer value\n *\n * Returns:\n *   A reference to the initialized variable\n */\nauto ref initOnce(alias var)(lazy typeof(var) init)\n{\n    return initOnce!var(init, initOnceLock);\n}\n\n/// A typical use-case is to perform lazy but thread-safe initialization.\n@system unittest\n{\n    static class MySingleton\n    {\n        static MySingleton instance()\n        {\n            __gshared MySingleton inst;\n            return initOnce!inst(new MySingleton);\n        }\n    }\n\n    assert(MySingleton.instance !is null);\n}\n\n@system unittest\n{\n    static class MySingleton\n    {\n        static MySingleton instance()\n        {\n            __gshared MySingleton inst;\n            return initOnce!inst(new MySingleton);\n        }\n\n    private:\n        this() { val = ++cnt; }\n        size_t val;\n        __gshared size_t cnt;\n    }\n\n    foreach (_; 0 .. 10)\n        spawn({ ownerTid.send(MySingleton.instance.val); });\n    foreach (_; 0 .. 10)\n        assert(receiveOnly!size_t == MySingleton.instance.val);\n    assert(MySingleton.cnt == 1);\n}\n\n/**\n * Same as above, but takes a separate mutex instead of sharing one among\n * all initOnce instances.\n *\n * This should be used to avoid dead-locks when the $(D_PARAM init)\n * expression waits for the result of another thread that might also\n * call initOnce. Use with care.\n *\n * Params:\n *   var = The variable to initialize\n *   init = The lazy initializer value\n *   mutex = A mutex to prevent race conditions\n *\n * Returns:\n *   A reference to the initialized variable\n */\nauto ref initOnce(alias var)(lazy typeof(var) init, shared Mutex mutex)\n{\n    // check that var is global, can't take address of a TLS variable\n    static assert(is(typeof({ __gshared p = &var; })),\n        \"var must be 'static shared' or '__gshared'.\");\n    import core.atomic : atomicLoad, MemoryOrder, atomicStore;\n\n    static shared bool flag;\n    if (!atomicLoad!(MemoryOrder.acq)(flag))\n    {\n        synchronized (mutex)\n        {\n            if (!atomicLoad!(MemoryOrder.raw)(flag))\n            {\n                var = init;\n                atomicStore!(MemoryOrder.rel)(flag, true);\n            }\n        }\n    }\n    return var;\n}\n\n/// ditto\nauto ref initOnce(alias var)(lazy typeof(var) init, Mutex mutex)\n{\n    return initOnce!var(init, cast(shared) mutex);\n}\n\n/// Use a separate mutex when init blocks on another thread that might also call initOnce.\n@system unittest\n{\n    import core.sync.mutex : Mutex;\n\n    static shared bool varA, varB;\n    static shared Mutex m;\n    m = new shared Mutex;\n\n    spawn({\n        // use a different mutex for varB to avoid a dead-lock\n        initOnce!varB(true, m);\n        ownerTid.send(true);\n    });\n    // init depends on the result of the spawned thread\n    initOnce!varA(receiveOnly!bool);\n    assert(varA == true);\n    assert(varB == true);\n}\n\n@system unittest\n{\n    static shared bool a;\n    __gshared bool b;\n    static bool c;\n    bool d;\n    initOnce!a(true);\n    initOnce!b(true);\n    static assert(!__traits(compiles, initOnce!c(true))); // TLS\n    static assert(!__traits(compiles, initOnce!d(true))); // local variable\n}\n\n// test ability to send shared arrays\n@system unittest\n{\n    static shared int[] x = new shared(int)[1];\n    auto tid = spawn({\n        auto arr = receiveOnly!(shared(int)[]);\n        arr[0] = 5;\n        ownerTid.send(true);\n    });\n    tid.send(x);\n    receiveOnly!(bool);\n    assert(x[0] == 5);\n}\n"
  },
  {
    "path": "libphobos/src/std/container/array.d",
    "content": "/**\n * This module provides an `Array` type with deterministic memory usage not\n * reliant on the GC, as an alternative to the built-in arrays.\n *\n * This module is a submodule of $(MREF std, container).\n *\n * Source: $(PHOBOSSRC std/container/array.d)\n *\n * Copyright: 2010- Andrei Alexandrescu. All rights reserved by the respective holders.\n *\n * License: Distributed under the Boost Software License, Version 1.0.\n * (See accompanying file LICENSE_1_0.txt or copy at $(HTTP\n * boost.org/LICENSE_1_0.txt)).\n *\n * Authors: $(HTTP erdani.com, Andrei Alexandrescu)\n *\n * $(SCRIPT inhibitQuickIndex = 1;)\n */\nmodule std.container.array;\n\nimport core.exception : RangeError;\nimport std.range.primitives;\nimport std.traits;\n\npublic import std.container.util;\n\n///\npure @system unittest\n{\n    auto arr = Array!int(0, 2, 3);\n    assert(arr[0] == 0);\n    assert(arr.front == 0);\n    assert(arr.back == 3);\n\n    // reserve space\n    arr.reserve(1000);\n    assert(arr.length == 3);\n    assert(arr.capacity >= 1000);\n\n    // insertion\n    arr.insertBefore(arr[1..$], 1);\n    assert(arr.front == 0);\n    assert(arr.length == 4);\n\n    arr.insertBack(4);\n    assert(arr.back == 4);\n    assert(arr.length == 5);\n\n    // set elements\n    arr[1] *= 42;\n    assert(arr[1] == 42);\n}\n\n///\npure @system unittest\n{\n    import std.algorithm.comparison : equal;\n    auto arr = Array!int(1, 2, 3);\n\n    // concat\n    auto b = Array!int(11, 12, 13);\n    arr ~= b;\n    assert(arr.length == 6);\n\n    // slicing\n    assert(arr[1 .. 3].equal([2, 3]));\n\n    // remove\n    arr.linearRemove(arr[1 .. 3]);\n    assert(arr[0 .. 2].equal([1, 11]));\n}\n\n/// `Array!bool` packs together values efficiently by allocating one bit per element\npure @system unittest\n{\n    Array!bool arr;\n    arr.insert([true, true, false, true, false]);\n    assert(arr.length == 5);\n}\n\nprivate struct RangeT(A)\n{\n    /* Workaround for Issue 13629 at https://issues.dlang.org/show_bug.cgi?id=13629\n       See also: http://forum.dlang.org/post/vbmwhzvawhnkoxrhbnyb@forum.dlang.org\n    */\n    private A[1] _outer_;\n    private @property ref inout(A) _outer() inout { return _outer_[0]; }\n\n    private size_t _a, _b;\n\n    /* E is different from T when A is more restrictively qualified than T:\n       immutable(Array!int) => T == int, E = immutable(int) */\n    alias E = typeof(_outer_[0]._data._payload[0]);\n\n    private this(ref A data, size_t a, size_t b)\n    {\n        _outer_ = data;\n        _a = a;\n        _b = b;\n    }\n\n    @property RangeT save()\n    {\n        return this;\n    }\n\n    @property bool empty() @safe pure nothrow const\n    {\n        return _a >= _b;\n    }\n\n    @property size_t length() @safe pure nothrow const\n    {\n        return _b - _a;\n    }\n    alias opDollar = length;\n\n    @property ref inout(E) front() inout\n    {\n        assert(!empty, \"Attempting to access the front of an empty Array\");\n        return _outer[_a];\n    }\n    @property ref inout(E) back() inout\n    {\n        assert(!empty, \"Attempting to access the back of an empty Array\");\n        return _outer[_b - 1];\n    }\n\n    void popFront() @safe @nogc pure nothrow\n    {\n        assert(!empty, \"Attempting to popFront an empty Array\");\n        ++_a;\n    }\n\n    void popBack() @safe @nogc pure nothrow\n    {\n        assert(!empty, \"Attempting to popBack an empty Array\");\n        --_b;\n    }\n\n    static if (isMutable!A)\n    {\n        import std.algorithm.mutation : move;\n\n        E moveFront()\n        {\n            assert(!empty && _a < _outer.length);\n            return move(_outer._data._payload[_a]);\n        }\n\n        E moveBack()\n        {\n            assert(!empty && _b  <= _outer.length);\n            return move(_outer._data._payload[_b - 1]);\n        }\n\n        E moveAt(size_t i)\n        {\n            assert(_a + i < _b && _a + i < _outer.length);\n            return move(_outer._data._payload[_a + i]);\n        }\n    }\n\n    ref inout(E) opIndex(size_t i) inout\n    {\n        assert(_a + i < _b);\n        return _outer[_a + i];\n    }\n\n    RangeT opSlice()\n    {\n        return typeof(return)(_outer, _a, _b);\n    }\n\n    RangeT opSlice(size_t i, size_t j)\n    {\n        assert(i <= j && _a + j <= _b);\n        return typeof(return)(_outer, _a + i, _a + j);\n    }\n\n    RangeT!(const(A)) opSlice() const\n    {\n        return typeof(return)(_outer, _a, _b);\n    }\n\n    RangeT!(const(A)) opSlice(size_t i, size_t j) const\n    {\n        assert(i <= j && _a + j <= _b);\n        return typeof(return)(_outer, _a + i, _a + j);\n    }\n\n    static if (isMutable!A)\n    {\n        void opSliceAssign(E value)\n        {\n            assert(_b <= _outer.length);\n            _outer[_a .. _b] = value;\n        }\n\n        void opSliceAssign(E value, size_t i, size_t j)\n        {\n            assert(_a + j <= _b);\n            _outer[_a + i .. _a + j] = value;\n        }\n\n        void opSliceUnary(string op)()\n        if (op == \"++\" || op == \"--\")\n        {\n            assert(_b <= _outer.length);\n            mixin(op~\"_outer[_a .. _b];\");\n        }\n\n        void opSliceUnary(string op)(size_t i, size_t j)\n        if (op == \"++\" || op == \"--\")\n        {\n            assert(_a + j <= _b);\n            mixin(op~\"_outer[_a + i .. _a + j];\");\n        }\n\n        void opSliceOpAssign(string op)(E value)\n        {\n            assert(_b <= _outer.length);\n            mixin(\"_outer[_a .. _b] \"~op~\"= value;\");\n        }\n\n        void opSliceOpAssign(string op)(E value, size_t i, size_t j)\n        {\n            assert(_a + j <= _b);\n            mixin(\"_outer[_a + i .. _a + j] \"~op~\"= value;\");\n        }\n    }\n}\n\n/**\n * _Array type with deterministic control of memory. The memory allocated\n * for the array is reclaimed as soon as possible; there is no reliance\n * on the garbage collector. `Array` uses `malloc`, `realloc` and `free`\n * for managing its own memory.\n *\n * This means that pointers to elements of an `Array` will become\n * dangling as soon as the element is removed from the `Array`. On the other hand\n * the memory allocated by an `Array` will be scanned by the GC and\n * GC managed objects referenced from an `Array` will be kept alive.\n *\n * Note:\n *\n * When using `Array` with range-based functions like those in `std.algorithm`,\n * `Array` must be sliced to get a range (for example, use `array[].map!`\n * instead of `array.map!`). The container itself is not a range.\n */\nstruct Array(T)\nif (!is(Unqual!T == bool))\n{\n    import core.memory : pureMalloc, pureRealloc, pureFree;\n    private alias malloc = pureMalloc;\n    private alias realloc = pureRealloc;\n    private alias free = pureFree;\n    import core.stdc.string : memcpy, memmove, memset;\n\n    import core.memory : GC;\n\n    import std.exception : enforce;\n    import std.typecons : RefCounted, RefCountedAutoInitialize;\n\n    // This structure is not copyable.\n    private struct Payload\n    {\n        size_t _capacity;\n        T[] _payload;\n\n        this(T[] p) { _capacity = p.length; _payload = p; }\n\n        // Destructor releases array memory\n        ~this()\n        {\n            // Warning: destroy would destroy also class instances.\n            // The hasElaborateDestructor protects us here.\n            static if (hasElaborateDestructor!T)\n                foreach (ref e; _payload)\n                    .destroy(e);\n\n            static if (hasIndirections!T)\n                GC.removeRange(_payload.ptr);\n\n            free(_payload.ptr);\n        }\n\n        this(this) @disable;\n\n        void opAssign(Payload rhs) @disable;\n\n        @property size_t length() const\n        {\n            return _payload.length;\n        }\n\n        @property void length(size_t newLength)\n        {\n            import std.algorithm.mutation : initializeAll;\n\n            if (length >= newLength)\n            {\n                // shorten\n                static if (hasElaborateDestructor!T)\n                    foreach (ref e; _payload.ptr[newLength .. _payload.length])\n                        .destroy(e);\n\n                _payload = _payload.ptr[0 .. newLength];\n                return;\n            }\n            immutable startEmplace = length;\n            if (_capacity < newLength)\n            {\n                // enlarge\n                import core.checkedint : mulu;\n\n                bool overflow;\n                const nbytes = mulu(newLength, T.sizeof, overflow);\n                if (overflow)\n                    assert(0);\n\n                static if (hasIndirections!T)\n                {\n                    auto newPayloadPtr = cast(T*) malloc(nbytes);\n                    newPayloadPtr || assert(false, \"std.container.Array.length failed to allocate memory.\");\n                    auto newPayload = newPayloadPtr[0 .. newLength];\n                    memcpy(newPayload.ptr, _payload.ptr, startEmplace * T.sizeof);\n                    memset(newPayload.ptr + startEmplace, 0,\n                            (newLength - startEmplace) * T.sizeof);\n                    GC.addRange(newPayload.ptr, nbytes);\n                    GC.removeRange(_payload.ptr);\n                    free(_payload.ptr);\n                    _payload = newPayload;\n                }\n                else\n                {\n                    _payload = (cast(T*) realloc(_payload.ptr,\n                            nbytes))[0 .. newLength];\n                }\n                _capacity = newLength;\n            }\n            else\n            {\n                _payload = _payload.ptr[0 .. newLength];\n            }\n            initializeAll(_payload.ptr[startEmplace .. newLength]);\n        }\n\n        @property size_t capacity() const\n        {\n            return _capacity;\n        }\n\n        void reserve(size_t elements)\n        {\n            if (elements <= capacity) return;\n            import core.checkedint : mulu;\n            bool overflow;\n            const sz = mulu(elements, T.sizeof, overflow);\n            if (overflow)\n                assert(0);\n            static if (hasIndirections!T)\n            {\n                /* Because of the transactional nature of this\n                 * relative to the garbage collector, ensure no\n                 * threading bugs by using malloc/copy/free rather\n                 * than realloc.\n                 */\n                immutable oldLength = length;\n\n                auto newPayloadPtr = cast(T*) malloc(sz);\n                newPayloadPtr || assert(false, \"std.container.Array.reserve failed to allocate memory\");\n                auto newPayload = newPayloadPtr[0 .. oldLength];\n\n                // copy old data over to new array\n                memcpy(newPayload.ptr, _payload.ptr, T.sizeof * oldLength);\n                // Zero out unused capacity to prevent gc from seeing false pointers\n                memset(newPayload.ptr + oldLength,\n                        0,\n                        (elements - oldLength) * T.sizeof);\n                GC.addRange(newPayload.ptr, sz);\n                GC.removeRange(_payload.ptr);\n                free(_payload.ptr);\n                _payload = newPayload;\n            }\n            else\n            {\n                // These can't have pointers, so no need to zero unused region\n                auto newPayloadPtr = cast(T*) realloc(_payload.ptr, sz);\n                newPayloadPtr || assert(false, \"std.container.Array.reserve failed to allocate memory\");\n                auto newPayload = newPayloadPtr[0 .. length];\n                _payload = newPayload;\n            }\n            _capacity = elements;\n        }\n\n        // Insert one item\n        size_t insertBack(Elem)(Elem elem)\n        if (isImplicitlyConvertible!(Elem, T))\n        {\n            import std.conv : emplace;\n            if (_capacity == length)\n            {\n                reserve(1 + capacity * 3 / 2);\n            }\n            assert(capacity > length && _payload.ptr);\n            emplace(_payload.ptr + _payload.length, elem);\n            _payload = _payload.ptr[0 .. _payload.length + 1];\n            return 1;\n        }\n\n        // Insert a range of items\n        size_t insertBack(Range)(Range r)\n        if (isInputRange!Range && isImplicitlyConvertible!(ElementType!Range, T))\n        {\n            static if (hasLength!Range)\n            {\n                immutable oldLength = length;\n                reserve(oldLength + r.length);\n            }\n            size_t result;\n            foreach (item; r)\n            {\n                insertBack(item);\n                ++result;\n            }\n            static if (hasLength!Range)\n            {\n                assert(length == oldLength + r.length);\n            }\n            return result;\n        }\n    }\n    private alias Data = RefCounted!(Payload, RefCountedAutoInitialize.no);\n    private Data _data;\n\n    /**\n     * Constructor taking a number of items.\n     */\n    this(U)(U[] values...)\n    if (isImplicitlyConvertible!(U, T))\n    {\n        import core.checkedint : mulu;\n        import std.conv : emplace;\n        bool overflow;\n        const nbytes = mulu(values.length, T.sizeof, overflow);\n        if (overflow) assert(0);\n        auto p = cast(T*) malloc(nbytes);\n        static if (hasIndirections!T)\n        {\n            if (p)\n                GC.addRange(p, T.sizeof * values.length);\n        }\n\n        foreach (i, e; values)\n        {\n            emplace(p + i, e);\n        }\n        _data = Data(p[0 .. values.length]);\n    }\n\n    /**\n     * Constructor taking an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     */\n    this(Range)(Range r)\n    if (isInputRange!Range && isImplicitlyConvertible!(ElementType!Range, T) && !is(Range == T[]))\n    {\n        insertBack(r);\n    }\n\n    /**\n     * Comparison for equality.\n     */\n    bool opEquals(const Array rhs) const\n    {\n        return opEquals(rhs);\n    }\n\n    /// ditto\n    bool opEquals(ref const Array rhs) const\n    {\n        if (empty) return rhs.empty;\n        if (rhs.empty) return false;\n        return _data._payload == rhs._data._payload;\n    }\n\n    /**\n     *  Defines the array's primary range, which is a random-access range.\n     *\n     *  `ConstRange` is a variant with `const` elements.\n     *  `ImmutableRange` is a variant with `immutable` elements.\n     */\n    alias Range = RangeT!Array;\n\n    /// ditto\n    alias ConstRange = RangeT!(const Array);\n\n    /// ditto\n    alias ImmutableRange = RangeT!(immutable Array);\n\n    /**\n     * Duplicates the array. The elements themselves are not transitively\n     * duplicated.\n     *\n     * Complexity: $(BIGOH length).\n     */\n    @property Array dup()\n    {\n        if (!_data.refCountedStore.isInitialized) return this;\n        return Array(_data._payload);\n    }\n\n    /**\n     * Returns: `true` if and only if the array has no elements.\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    @property bool empty() const\n    {\n        return !_data.refCountedStore.isInitialized || _data._payload.empty;\n    }\n\n    /**\n     * Returns: The number of elements in the array.\n     *\n     * Complexity: $(BIGOH 1).\n     */\n    @property size_t length() const\n    {\n        return _data.refCountedStore.isInitialized ? _data._payload.length : 0;\n    }\n\n    /// ditto\n    size_t opDollar() const\n    {\n        return length;\n    }\n\n    /**\n     * Returns: The maximum number of elements the array can store without\n     * reallocating memory and invalidating iterators upon insertion.\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    @property size_t capacity()\n    {\n        return _data.refCountedStore.isInitialized ? _data._capacity : 0;\n    }\n\n    /**\n     * Ensures sufficient capacity to accommodate `e` _elements.\n     * If `e < capacity`, this method does nothing.\n     *\n     * Postcondition: `capacity >= e`\n     *\n     * Note: If the capacity is increased, one should assume that all\n     * iterators to the elements are invalidated.\n     *\n     * Complexity: at most $(BIGOH length) if `e > capacity`, otherwise $(BIGOH 1).\n     */\n    void reserve(size_t elements)\n    {\n        if (!_data.refCountedStore.isInitialized)\n        {\n            if (!elements) return;\n            import core.checkedint : mulu;\n            bool overflow;\n            const sz = mulu(elements, T.sizeof, overflow);\n            if (overflow) assert(0);\n            auto p = malloc(sz);\n            p || assert(false, \"std.container.Array.reserve failed to allocate memory\");\n            static if (hasIndirections!T)\n            {\n                GC.addRange(p, sz);\n            }\n            _data = Data(cast(T[]) p[0 .. 0]);\n            _data._capacity = elements;\n        }\n        else\n        {\n            _data.reserve(elements);\n        }\n    }\n\n    /**\n     * Returns: A range that iterates over elements of the array in\n     * forward order.\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    Range opSlice()\n    {\n        return typeof(return)(this, 0, length);\n    }\n\n    ConstRange opSlice() const\n    {\n        return typeof(return)(this, 0, length);\n    }\n\n    ImmutableRange opSlice() immutable\n    {\n        return typeof(return)(this, 0, length);\n    }\n\n    /**\n     * Returns: A range that iterates over elements of the array from\n     * index `i` up to (excluding) index `j`.\n     *\n     * Precondition: `i <= j && j <= length`\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    Range opSlice(size_t i, size_t j)\n    {\n        assert(i <= j && j <= length);\n        return typeof(return)(this, i, j);\n    }\n\n    ConstRange opSlice(size_t i, size_t j) const\n    {\n        assert(i <= j && j <= length);\n        return typeof(return)(this, i, j);\n    }\n\n    ImmutableRange opSlice(size_t i, size_t j) immutable\n    {\n        assert(i <= j && j <= length);\n        return typeof(return)(this, i, j);\n    }\n\n    /**\n     * Returns: The first element of the array.\n     *\n     * Precondition: `empty == false`\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    @property ref inout(T) front() inout\n    {\n        assert(_data.refCountedStore.isInitialized);\n        return _data._payload[0];\n    }\n\n    /**\n     * Returns: The last element of the array.\n     *\n     * Precondition: `empty == false`\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    @property ref inout(T) back() inout\n    {\n        assert(_data.refCountedStore.isInitialized);\n        return _data._payload[$ - 1];\n    }\n\n    /**\n     * Returns: The element or a reference to the element at the specified index.\n     *\n     * Precondition: `i < length`\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    ref inout(T) opIndex(size_t i) inout\n    {\n        assert(_data.refCountedStore.isInitialized);\n        return _data._payload[i];\n    }\n\n    /**\n     * Slicing operators executing the specified operation on the entire slice.\n     *\n     * Precondition: `i < j && j < length`\n     *\n     * Complexity: $(BIGOH slice.length)\n     */\n    void opSliceAssign(T value)\n    {\n        if (!_data.refCountedStore.isInitialized) return;\n        _data._payload[] = value;\n    }\n\n    /// ditto\n    void opSliceAssign(T value, size_t i, size_t j)\n    {\n        auto slice = _data.refCountedStore.isInitialized ?\n            _data._payload :\n            T[].init;\n        slice[i .. j] = value;\n    }\n\n    /// ditto\n    void opSliceUnary(string op)()\n    if (op == \"++\" || op == \"--\")\n    {\n        if (!_data.refCountedStore.isInitialized) return;\n        mixin(op~\"_data._payload[];\");\n    }\n\n    /// ditto\n    void opSliceUnary(string op)(size_t i, size_t j)\n    if (op == \"++\" || op == \"--\")\n    {\n        auto slice = _data.refCountedStore.isInitialized ? _data._payload : T[].init;\n        mixin(op~\"slice[i .. j];\");\n    }\n\n    /// ditto\n    void opSliceOpAssign(string op)(T value)\n    {\n        if (!_data.refCountedStore.isInitialized) return;\n        mixin(\"_data._payload[] \"~op~\"= value;\");\n    }\n\n    /// ditto\n    void opSliceOpAssign(string op)(T value, size_t i, size_t j)\n    {\n        auto slice = _data.refCountedStore.isInitialized ? _data._payload : T[].init;\n        mixin(\"slice[i .. j] \"~op~\"= value;\");\n    }\n\n    private enum hasSliceWithLength(T) = is(typeof({ T t = T.init; t[].length; }));\n\n    /**\n     * Returns: A new array which is a concatenation of `this` and its argument.\n     *\n     * Complexity:\n     * $(BIGOH length + m), where `m` is the number of elements in `stuff`.\n     */\n    Array opBinary(string op, Stuff)(Stuff stuff)\n    if (op == \"~\")\n    {\n        Array result;\n\n        static if (hasLength!Stuff || isNarrowString!Stuff)\n            result.reserve(length + stuff.length);\n        else static if (hasSliceWithLength!Stuff)\n            result.reserve(length + stuff[].length);\n        else static if (isImplicitlyConvertible!(Stuff, T))\n            result.reserve(length + 1);\n\n        result.insertBack(this[]);\n        result ~= stuff;\n        return result;\n    }\n\n    /**\n     * Forwards to `insertBack`.\n     */\n    void opOpAssign(string op, Stuff)(auto ref Stuff stuff)\n    if (op == \"~\")\n    {\n        static if (is(typeof(stuff[])) && isImplicitlyConvertible!(typeof(stuff[0]), T))\n        {\n            insertBack(stuff[]);\n        }\n        else\n        {\n            insertBack(stuff);\n        }\n    }\n\n    /**\n     * Removes all the elements from the array and releases allocated memory.\n     *\n     * Postcondition: `empty == true && capacity == 0`\n     *\n     * Complexity: $(BIGOH length)\n     */\n    void clear()\n    {\n        _data = Data.init;\n    }\n\n    /**\n     * Sets the number of elements in the array to `newLength`. If `newLength`\n     * is greater than `length`, the new elements are added to the end of the\n     * array and initialized with `T.init`.\n     *\n     * Complexity:\n     * Guaranteed $(BIGOH abs(length - newLength)) if `capacity >= newLength`.\n     * If `capacity < newLength` the worst case is $(BIGOH newLength).\n     *\n     * Postcondition: `length == newLength`\n     */\n    @property void length(size_t newLength)\n    {\n        _data.refCountedStore.ensureInitialized();\n        _data.length = newLength;\n    }\n\n    /**\n     * Removes the last element from the array and returns it.\n     * Both stable and non-stable versions behave the same and guarantee\n     * that ranges iterating over the array are never invalidated.\n     *\n     * Precondition: `empty == false`\n     *\n     * Returns: The element removed.\n     *\n     * Complexity: $(BIGOH 1).\n     *\n     * Throws: `Exception` if the array is empty.\n     */\n    T removeAny()\n    {\n        auto result = back;\n        removeBack();\n        return result;\n    }\n\n    /// ditto\n    alias stableRemoveAny = removeAny;\n\n    /**\n     * Inserts the specified elements at the back of the array. `stuff` can be\n     * a value convertible to `T` or a range of objects convertible to `T`.\n     *\n     * Returns: The number of elements inserted.\n     *\n     * Complexity:\n     * $(BIGOH length + m) if reallocation takes place, otherwise $(BIGOH m),\n     * where `m` is the number of elements in `stuff`.\n     */\n    size_t insertBack(Stuff)(Stuff stuff)\n    if (isImplicitlyConvertible!(Stuff, T) ||\n            isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T))\n    {\n        _data.refCountedStore.ensureInitialized();\n        return _data.insertBack(stuff);\n    }\n\n    /// ditto\n    alias insert = insertBack;\n\n    /**\n     * Removes the value from the back of the array. Both stable and non-stable\n     * versions behave the same and guarantee that ranges iterating over the\n     * array are never invalidated.\n     *\n     * Precondition: `empty == false`\n     *\n     * Complexity: $(BIGOH 1).\n     *\n     * Throws: `Exception` if the array is empty.\n     */\n    void removeBack()\n    {\n        enforce(!empty);\n        static if (hasElaborateDestructor!T)\n            .destroy(_data._payload[$ - 1]);\n\n        _data._payload = _data._payload[0 .. $ - 1];\n    }\n\n    /// ditto\n    alias stableRemoveBack = removeBack;\n\n    /**\n     * Removes `howMany` values from the back of the array.\n     * Unlike the unparameterized versions above, these functions\n     * do not throw if they could not remove `howMany` elements. Instead,\n     * if `howMany > n`, all elements are removed. The returned value is\n     * the effective number of elements removed. Both stable and non-stable\n     * versions behave the same and guarantee that ranges iterating over\n     * the array are never invalidated.\n     *\n     * Returns: The number of elements removed.\n     *\n     * Complexity: $(BIGOH howMany).\n     */\n    size_t removeBack(size_t howMany)\n    {\n        if (howMany > length) howMany = length;\n        static if (hasElaborateDestructor!T)\n            foreach (ref e; _data._payload[$ - howMany .. $])\n                .destroy(e);\n\n        _data._payload = _data._payload[0 .. $ - howMany];\n        return howMany;\n    }\n\n    /// ditto\n    alias stableRemoveBack = removeBack;\n\n    /**\n     * Inserts `stuff` before, after, or instead range `r`, which must\n     * be a valid range previously extracted from this array. `stuff`\n     * can be a value convertible to `T` or a range of objects convertible\n     * to `T`. Both stable and non-stable version behave the same and\n     * guarantee that ranges iterating over the array are never invalidated.\n     *\n     * Returns: The number of values inserted.\n     *\n     * Complexity: $(BIGOH length + m), where `m` is the length of `stuff`.\n     *\n     * Throws: `Exception` if `r` is not a range extracted from this array.\n     */\n    size_t insertBefore(Stuff)(Range r, Stuff stuff)\n    if (isImplicitlyConvertible!(Stuff, T))\n    {\n        import std.conv : emplace;\n        enforce(r._outer._data is _data && r._a <= length);\n        reserve(length + 1);\n        assert(_data.refCountedStore.isInitialized);\n        // Move elements over by one slot\n        memmove(_data._payload.ptr + r._a + 1,\n                _data._payload.ptr + r._a,\n                T.sizeof * (length - r._a));\n        emplace(_data._payload.ptr + r._a, stuff);\n        _data._payload = _data._payload.ptr[0 .. _data._payload.length + 1];\n        return 1;\n    }\n\n    /// ditto\n    size_t insertBefore(Stuff)(Range r, Stuff stuff)\n    if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T))\n    {\n        import std.conv : emplace;\n        enforce(r._outer._data is _data && r._a <= length);\n        static if (isForwardRange!Stuff)\n        {\n            // Can find the length in advance\n            auto extra = walkLength(stuff);\n            if (!extra) return 0;\n            reserve(length + extra);\n            assert(_data.refCountedStore.isInitialized);\n            // Move elements over by extra slots\n            memmove(_data._payload.ptr + r._a + extra,\n                    _data._payload.ptr + r._a,\n                    T.sizeof * (length - r._a));\n            foreach (p; _data._payload.ptr + r._a ..\n                    _data._payload.ptr + r._a + extra)\n            {\n                emplace(p, stuff.front);\n                stuff.popFront();\n            }\n            _data._payload =\n                _data._payload.ptr[0 .. _data._payload.length + extra];\n            return extra;\n        }\n        else\n        {\n            import std.algorithm.mutation : bringToFront;\n            enforce(_data);\n            immutable offset = r._a;\n            enforce(offset <= length);\n            auto result = insertBack(stuff);\n            bringToFront(this[offset .. length - result],\n                    this[length - result .. length]);\n            return result;\n        }\n    }\n\n    /// ditto\n    alias stableInsertBefore = insertBefore;\n\n    /// ditto\n    size_t insertAfter(Stuff)(Range r, Stuff stuff)\n    {\n        import std.algorithm.mutation : bringToFront;\n        enforce(r._outer._data is _data);\n        // TODO: optimize\n        immutable offset = r._b;\n        enforce(offset <= length);\n        auto result = insertBack(stuff);\n        bringToFront(this[offset .. length - result],\n                this[length - result .. length]);\n        return result;\n    }\n\n    /// ditto\n    size_t replace(Stuff)(Range r, Stuff stuff)\n    if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T))\n    {\n        enforce(r._outer._data is _data);\n        size_t result;\n        for (; !stuff.empty; stuff.popFront())\n        {\n            if (r.empty)\n            {\n                // insert the rest\n                return result + insertBefore(r, stuff);\n            }\n            r.front = stuff.front;\n            r.popFront();\n            ++result;\n        }\n        // Remove remaining stuff in r\n        linearRemove(r);\n        return result;\n    }\n\n    /// ditto\n    size_t replace(Stuff)(Range r, Stuff stuff)\n    if (isImplicitlyConvertible!(Stuff, T))\n    {\n        enforce(r._outer._data is _data);\n        if (r.empty)\n        {\n            insertBefore(r, stuff);\n        }\n        else\n        {\n            r.front = stuff;\n            r.popFront();\n            linearRemove(r);\n        }\n        return 1;\n    }\n\n    /**\n     * Removes all elements belonging to `r`, which must be a range\n     * obtained originally from this array.\n     *\n     * Returns: A range spanning the remaining elements in the array that\n     * initially were right after `r`.\n     *\n     * Complexity: $(BIGOH length)\n     *\n     * Throws: `Exception` if `r` is not a valid range extracted from this array.\n     */\n    Range linearRemove(Range r)\n    {\n        import std.algorithm.mutation : copy;\n\n        enforce(r._outer._data is _data);\n        enforce(_data.refCountedStore.isInitialized);\n        enforce(r._a <= r._b && r._b <= length);\n        immutable offset1 = r._a;\n        immutable offset2 = r._b;\n        immutable tailLength = length - offset2;\n        // Use copy here, not a[] = b[] because the ranges may overlap\n        copy(this[offset2 .. length], this[offset1 .. offset1 + tailLength]);\n        length = offset1 + tailLength;\n        return this[length - tailLength .. length];\n    }\n}\n\n@system unittest\n{\n    Array!int a;\n    assert(a.empty);\n}\n\n@system unittest\n{\n    Array!int a;\n    a.length = 10;\n    assert(a.length == 10);\n    assert(a.capacity >= a.length);\n}\n\n@system unittest\n{\n    struct Dumb { int x = 5; }\n    Array!Dumb a;\n    a.length = 10;\n    assert(a.length == 10);\n    assert(a.capacity >= a.length);\n    immutable cap = a.capacity;\n    foreach (ref e; a)\n        e.x = 10;\n    a.length = 5;\n    assert(a.length == 5);\n    // do not realloc if length decreases\n    assert(a.capacity == cap);\n    foreach (ref e; a)\n        assert(e.x == 10);\n\n    a.length = 8;\n    assert(a.length == 8);\n    // do not realloc if capacity sufficient\n    assert(a.capacity == cap);\n    assert(Dumb.init.x == 5);\n    foreach (i; 0 .. 5)\n        assert(a[i].x == 10);\n    foreach (i; 5 .. a.length)\n        assert(a[i].x == Dumb.init.x);\n\n    // realloc required, check if values properly copied\n    a[] = Dumb(1);\n    a.length = 20;\n    assert(a.capacity >= 20);\n    foreach (i; 0 .. 8)\n        assert(a[i].x == 1);\n    foreach (i; 8 .. a.length)\n        assert(a[i].x == Dumb.init.x);\n\n    // check if overlapping elements properly initialized\n    a.length = 1;\n    a.length = 20;\n    assert(a[0].x == 1);\n    foreach (e; a[1 .. $])\n        assert(e.x == Dumb.init.x);\n}\n\n@system unittest\n{\n    Array!int a = Array!int(1, 2, 3);\n    //a._data._refCountedDebug = true;\n    auto b = a.dup;\n    assert(b == Array!int(1, 2, 3));\n    b.front = 42;\n    assert(b == Array!int(42, 2, 3));\n    assert(a == Array!int(1, 2, 3));\n}\n\n@system unittest\n{\n    auto a = Array!int(1, 2, 3);\n    assert(a.length == 3);\n}\n\n@system unittest\n{\n    const Array!int a = [1, 2];\n\n    assert(a[0] == 1);\n    assert(a.front == 1);\n    assert(a.back == 2);\n\n    static assert(!__traits(compiles, { a[0] = 1; }));\n    static assert(!__traits(compiles, { a.front = 1; }));\n    static assert(!__traits(compiles, { a.back = 1; }));\n\n    auto r = a[];\n    size_t i;\n    foreach (e; r)\n    {\n        assert(e == i + 1);\n        i++;\n    }\n}\n\n@safe unittest\n{\n    // https://issues.dlang.org/show_bug.cgi?id=13621\n    import std.container : Array, BinaryHeap;\n    alias Heap = BinaryHeap!(Array!int);\n}\n\n@system unittest\n{\n    // https://issues.dlang.org/show_bug.cgi?id=18800\n    static struct S { void* p; }\n    Array!S a;\n    a.length = 10;\n}\n\n@system unittest\n{\n    Array!int a;\n    a.reserve(1000);\n    assert(a.length == 0);\n    assert(a.empty);\n    assert(a.capacity >= 1000);\n    auto p = a._data._payload.ptr;\n    foreach (i; 0 .. 1000)\n    {\n        a.insertBack(i);\n    }\n    assert(p == a._data._payload.ptr);\n}\n\n@system unittest\n{\n    auto a = Array!int(1, 2, 3);\n    a[1] *= 42;\n    assert(a[1] == 84);\n}\n\n@system unittest\n{\n    auto a = Array!int(1, 2, 3);\n    auto b = Array!int(11, 12, 13);\n    auto c = a ~ b;\n    assert(c == Array!int(1, 2, 3, 11, 12, 13));\n    assert(a ~ b[] == Array!int(1, 2, 3, 11, 12, 13));\n    assert(a ~ [4,5] == Array!int(1,2,3,4,5));\n}\n\n@system unittest\n{\n    auto a = Array!int(1, 2, 3);\n    auto b = Array!int(11, 12, 13);\n    a ~= b;\n    assert(a == Array!int(1, 2, 3, 11, 12, 13));\n}\n\n@system unittest\n{\n    auto a = Array!int(1, 2, 3, 4);\n    assert(a.removeAny() == 4);\n    assert(a == Array!int(1, 2, 3));\n}\n\n@system unittest\n{\n    auto a = Array!int(1, 2, 3, 4, 5);\n    auto r = a[2 .. a.length];\n    assert(a.insertBefore(r, 42) == 1);\n    assert(a == Array!int(1, 2, 42, 3, 4, 5));\n    r = a[2 .. 2];\n    assert(a.insertBefore(r, [8, 9]) == 2);\n    assert(a == Array!int(1, 2, 8, 9, 42, 3, 4, 5));\n}\n\n@system unittest\n{\n    auto a = Array!int(0, 1, 2, 3, 4, 5, 6, 7, 8);\n    a.linearRemove(a[4 .. 6]);\n    assert(a == Array!int(0, 1, 2, 3, 6, 7, 8));\n}\n\n// Give the Range object some testing.\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : retro;\n    auto a = Array!int(0, 1, 2, 3, 4, 5, 6)[];\n    auto b = Array!int(6, 5, 4, 3, 2, 1, 0)[];\n    alias A = typeof(a);\n\n    static assert(isRandomAccessRange!A);\n    static assert(hasSlicing!A);\n    static assert(hasAssignableElements!A);\n    static assert(hasMobileElements!A);\n\n    assert(equal(retro(b), a));\n    assert(a.length == 7);\n    assert(equal(a[1 .. 4], [1, 2, 3]));\n}\n// Test issue 5920\n@system unittest\n{\n    struct structBug5920\n    {\n        int order;\n        uint* pDestructionMask;\n        ~this()\n        {\n            if (pDestructionMask)\n                *pDestructionMask += 1 << order;\n        }\n    }\n\n    alias S = structBug5920;\n    uint dMask;\n\n    auto arr = Array!S(cast(S[])[]);\n    foreach (i; 0 .. 8)\n        arr.insertBack(S(i, &dMask));\n    // don't check dMask now as S may be copied multiple times (it's ok?)\n    {\n        assert(arr.length == 8);\n        dMask = 0;\n        arr.length = 6;\n        assert(arr.length == 6);    // make sure shrinking calls the d'tor\n        assert(dMask == 0b1100_0000);\n        arr.removeBack();\n        assert(arr.length == 5);    // make sure removeBack() calls the d'tor\n        assert(dMask == 0b1110_0000);\n        arr.removeBack(3);\n        assert(arr.length == 2);    // ditto\n        assert(dMask == 0b1111_1100);\n        arr.clear();\n        assert(arr.length == 0);    // make sure clear() calls the d'tor\n        assert(dMask == 0b1111_1111);\n    }\n    assert(dMask == 0b1111_1111);   // make sure the d'tor is called once only.\n}\n// Test issue 5792 (mainly just to check if this piece of code is compilable)\n@system unittest\n{\n    auto a = Array!(int[])([[1,2],[3,4]]);\n    a.reserve(4);\n    assert(a.capacity >= 4);\n    assert(a.length == 2);\n    assert(a[0] == [1,2]);\n    assert(a[1] == [3,4]);\n    a.reserve(16);\n    assert(a.capacity >= 16);\n    assert(a.length == 2);\n    assert(a[0] == [1,2]);\n    assert(a[1] == [3,4]);\n}\n\n// test replace!Stuff with range Stuff\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    auto a = Array!int([1, 42, 5]);\n    a.replace(a[1 .. 2], [2, 3, 4]);\n    assert(equal(a[], [1, 2, 3, 4, 5]));\n}\n\n// test insertBefore and replace with empty Arrays\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    auto a = Array!int();\n    a.insertBefore(a[], 1);\n    assert(equal(a[], [1]));\n}\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    auto a = Array!int();\n    a.insertBefore(a[], [1, 2]);\n    assert(equal(a[], [1, 2]));\n}\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    auto a = Array!int();\n    a.replace(a[], [1, 2]);\n    assert(equal(a[], [1, 2]));\n}\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    auto a = Array!int();\n    a.replace(a[], 1);\n    assert(equal(a[], [1]));\n}\n// make sure that Array instances refuse ranges that don't belong to them\n@system unittest\n{\n    import std.exception : assertThrown;\n\n    Array!int a = [1, 2, 3];\n    auto r = a.dup[];\n    assertThrown(a.insertBefore(r, 42));\n    assertThrown(a.insertBefore(r, [42]));\n    assertThrown(a.insertAfter(r, 42));\n    assertThrown(a.replace(r, 42));\n    assertThrown(a.replace(r, [42]));\n    assertThrown(a.linearRemove(r));\n}\n@system unittest\n{\n    auto a = Array!int([1, 1]);\n    a[1]  = 0; //Check Array.opIndexAssign\n    assert(a[1] == 0);\n    a[1] += 1; //Check Array.opIndexOpAssign\n    assert(a[1] == 1);\n\n    //Check Array.opIndexUnary\n    ++a[0];\n    //a[0]++ //op++ doesn't return, so this shouldn't work, even with 5044 fixed\n    assert(a[0] == 2);\n    assert(+a[0] == +2);\n    assert(-a[0] == -2);\n    assert(~a[0] == ~2);\n\n    auto r = a[];\n    r[1]  = 0; //Check Array.Range.opIndexAssign\n    assert(r[1] == 0);\n    r[1] += 1; //Check Array.Range.opIndexOpAssign\n    assert(r[1] == 1);\n\n    //Check Array.Range.opIndexUnary\n    ++r[0];\n    //r[0]++ //op++ doesn't return, so this shouldn't work, even with 5044 fixed\n    assert(r[0] == 3);\n    assert(+r[0] == +3);\n    assert(-r[0] == -3);\n    assert(~r[0] == ~3);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    //Test \"array-wide\" operations\n    auto a = Array!int([0, 1, 2]); //Array\n    a[] += 5;\n    assert(a[].equal([5, 6, 7]));\n    ++a[];\n    assert(a[].equal([6, 7, 8]));\n    a[1 .. 3] *= 5;\n    assert(a[].equal([6, 35, 40]));\n    a[0 .. 2] = 0;\n    assert(a[].equal([0, 0, 40]));\n\n    //Test empty array\n    auto a2 = Array!int.init;\n    ++a2[];\n    ++a2[0 .. 0];\n    a2[] = 0;\n    a2[0 .. 0] = 0;\n    a2[] += 0;\n    a2[0 .. 0] += 0;\n\n    //Test \"range-wide\" operations\n    auto r = Array!int([0, 1, 2])[]; //Array.Range\n    r[] += 5;\n    assert(r.equal([5, 6, 7]));\n    ++r[];\n    assert(r.equal([6, 7, 8]));\n    r[1 .. 3] *= 5;\n    assert(r.equal([6, 35, 40]));\n    r[0 .. 2] = 0;\n    assert(r.equal([0, 0, 40]));\n\n    //Test empty Range\n    auto r2 = Array!int.init[];\n    ++r2[];\n    ++r2[0 .. 0];\n    r2[] = 0;\n    r2[0 .. 0] = 0;\n    r2[] += 0;\n    r2[0 .. 0] += 0;\n}\n\n// Test issue 11194\n@system unittest\n{\n    static struct S {\n        int i = 1337;\n        void* p;\n        this(this) { assert(i == 1337); }\n        ~this() { assert(i == 1337); }\n    }\n    Array!S arr;\n    S s;\n    arr ~= s;\n    arr ~= s;\n}\n\n@safe unittest //11459\n{\n    static struct S\n    {\n        bool b;\n        alias b this;\n    }\n    alias A = Array!S;\n    alias B = Array!(shared bool);\n}\n\n@system unittest //11884\n{\n    import std.algorithm.iteration : filter;\n    auto a = Array!int([1, 2, 2].filter!\"true\"());\n}\n\n@safe unittest //8282\n{\n    auto arr = new Array!int;\n}\n\n@system unittest //6998\n{\n    static int i = 0;\n    class C\n    {\n        int dummy = 1;\n        this(){++i;}\n        ~this(){--i;}\n    }\n\n    assert(i == 0);\n    auto c = new C();\n    assert(i == 1);\n\n    //scope\n    {\n        auto arr = Array!C(c);\n        assert(i == 1);\n    }\n    //Array should not have destroyed the class instance\n    assert(i == 1);\n\n    //Just to make sure the GC doesn't collect before the above test.\n    assert(c.dummy == 1);\n}\n@system unittest //6998-2\n{\n    static class C {int i;}\n    auto c = new C;\n    c.i = 42;\n    Array!C a;\n    a ~= c;\n    a.clear;\n    assert(c.i == 42); //fails\n}\n\n@safe unittest\n{\n    static assert(is(Array!int.Range));\n    static assert(is(Array!int.ConstRange));\n}\n\n@system unittest // const/immutable Array and Ranges\n{\n    static void test(A, R, E, S)()\n    {\n        A a;\n        R r = a[];\n        assert(r.empty);\n        assert(r.length == 0);\n        static assert(is(typeof(r.front) == E));\n        static assert(is(typeof(r.back) == E));\n        static assert(is(typeof(r[0]) == E));\n        static assert(is(typeof(r[]) == S));\n        static assert(is(typeof(r[0 .. 0]) == S));\n    }\n\n    alias A = Array!int;\n\n    test!(A, A.Range, int, A.Range);\n    test!(A, const A.Range, const int, A.ConstRange);\n\n    test!(const A, A.ConstRange, const int, A.ConstRange);\n    test!(const A, const A.ConstRange, const int, A.ConstRange);\n\n    test!(immutable A, A.ImmutableRange, immutable int, A.ImmutableRange);\n    test!(immutable A, const A.ImmutableRange, immutable int, A.ImmutableRange);\n    test!(immutable A, immutable A.ImmutableRange, immutable int,\n        A.ImmutableRange);\n}\n\n// ensure @nogc\n@nogc @system unittest\n{\n    Array!int ai;\n    ai ~= 1;\n    assert(ai.front == 1);\n\n    ai.reserve(10);\n    assert(ai.capacity == 10);\n\n    static immutable arr = [1, 2, 3];\n    ai.insertBack(arr);\n}\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Array!bool\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * _Array specialized for `bool`. Packs together values efficiently by\n * allocating one bit per element.\n */\nstruct Array(T)\nif (is(Unqual!T == bool))\n{\n    import std.exception : enforce;\n    import std.typecons : RefCounted, RefCountedAutoInitialize;\n\n    static immutable uint bitsPerWord = size_t.sizeof * 8;\n    private static struct Data\n    {\n        Array!size_t.Payload _backend;\n        size_t _length;\n    }\n    private RefCounted!(Data, RefCountedAutoInitialize.no) _store;\n\n    private @property ref size_t[] data()\n    {\n        assert(_store.refCountedStore.isInitialized);\n        return _store._backend._payload;\n    }\n\n    /**\n     * Defines the array's primary range.\n     */\n    struct Range\n    {\n        private Array _outer;\n        private size_t _a, _b;\n        /// Range primitives\n        @property Range save()\n        {\n            version (bug4437)\n            {\n                return this;\n            }\n            else\n            {\n                auto copy = this;\n                return copy;\n            }\n        }\n        /// Ditto\n        @property bool empty()\n        {\n            return _a >= _b || _outer.length < _b;\n        }\n        /// Ditto\n        @property T front()\n        {\n            enforce(!empty, \"Attempting to access the front of an empty Array\");\n            return _outer[_a];\n        }\n        /// Ditto\n        @property void front(bool value)\n        {\n            enforce(!empty, \"Attempting to set the front of an empty Array\");\n            _outer[_a] = value;\n        }\n        /// Ditto\n        T moveFront()\n        {\n            enforce(!empty, \"Attempting to move the front of an empty Array\");\n            return _outer.moveAt(_a);\n        }\n        /// Ditto\n        void popFront()\n        {\n            enforce(!empty, \"Attempting to popFront an empty Array\");\n            ++_a;\n        }\n        /// Ditto\n        @property T back()\n        {\n            enforce(!empty, \"Attempting to access the back of an empty Array\");\n            return _outer[_b - 1];\n        }\n        /// Ditto\n        @property void back(bool value)\n        {\n            enforce(!empty, \"Attempting to set the back of an empty Array\");\n            _outer[_b - 1] = value;\n        }\n        /// Ditto\n        T moveBack()\n        {\n            enforce(!empty, \"Attempting to move the back of an empty Array\");\n            return _outer.moveAt(_b - 1);\n        }\n        /// Ditto\n        void popBack()\n        {\n            enforce(!empty, \"Attempting to popBack an empty Array\");\n            --_b;\n        }\n        /// Ditto\n        T opIndex(size_t i)\n        {\n            return _outer[_a + i];\n        }\n        /// Ditto\n        void opIndexAssign(T value, size_t i)\n        {\n            _outer[_a + i] = value;\n        }\n        /// Ditto\n        T moveAt(size_t i)\n        {\n            return _outer.moveAt(_a + i);\n        }\n        /// Ditto\n        @property size_t length() const\n        {\n            assert(_a <= _b);\n            return _b - _a;\n        }\n        alias opDollar = length;\n        /// ditto\n        Range opSlice(size_t low, size_t high)\n        {\n            // Note: indexes start at 0, which is equivalent to _a\n            assert(\n                low <= high && high <= (_b - _a),\n                \"Using out of bounds indexes on an Array\"\n            );\n            return Range(_outer, _a + low, _a + high);\n        }\n    }\n\n    /**\n     * Property returning `true` if and only if the array has\n     * no elements.\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    @property bool empty()\n    {\n        return !length;\n    }\n\n    /**\n     * Returns: A duplicate of the array.\n     *\n     * Complexity: $(BIGOH length).\n     */\n    @property Array dup()\n    {\n        Array result;\n        result.insertBack(this[]);\n        return result;\n    }\n\n    /**\n     * Returns the number of elements in the array.\n     *\n     * Complexity: $(BIGOH 1).\n     */\n    @property size_t length() const\n    {\n        return _store.refCountedStore.isInitialized ? _store._length : 0;\n    }\n    size_t opDollar() const\n    {\n        return length;\n    }\n\n    /**\n     * Returns: The maximum number of elements the array can store without\n     * reallocating memory and invalidating iterators upon insertion.\n     *\n     * Complexity: $(BIGOH 1).\n     */\n    @property size_t capacity()\n    {\n        return _store.refCountedStore.isInitialized\n            ? cast(size_t) bitsPerWord * _store._backend.capacity\n            : 0;\n    }\n\n    /**\n     * Ensures sufficient capacity to accommodate `e` _elements.\n     * If `e < capacity`, this method does nothing.\n     *\n     * Postcondition: `capacity >= e`\n     *\n     * Note: If the capacity is increased, one should assume that all\n     * iterators to the elements are invalidated.\n     *\n     * Complexity: at most $(BIGOH length) if `e > capacity`, otherwise $(BIGOH 1).\n     */\n    void reserve(size_t e)\n    {\n        import std.conv : to;\n        _store.refCountedStore.ensureInitialized();\n        _store._backend.reserve(to!size_t((e + bitsPerWord - 1) / bitsPerWord));\n    }\n\n    /**\n     * Returns: A range that iterates over all elements of the array in forward order.\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    Range opSlice()\n    {\n        return Range(this, 0, length);\n    }\n\n\n    /**\n     * Returns: A range that iterates the array between two specified positions.\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    Range opSlice(size_t a, size_t b)\n    {\n        enforce(a <= b && b <= length);\n        return Range(this, a, b);\n    }\n\n    /**\n     * Returns: The first element of the array.\n     *\n     * Precondition: `empty == false`\n     *\n     * Complexity: $(BIGOH 1)\n     *\n     * Throws: `Exception` if the array is empty.\n     */\n    @property bool front()\n    {\n        enforce(!empty);\n        return data.ptr[0] & 1;\n    }\n\n    /// Ditto\n    @property void front(bool value)\n    {\n        enforce(!empty);\n        if (value) data.ptr[0] |= 1;\n        else data.ptr[0] &= ~cast(size_t) 1;\n    }\n\n    /**\n     * Returns: The last element of the array.\n     *\n     * Precondition: `empty == false`\n     *\n     * Complexity: $(BIGOH 1)\n     *\n     * Throws: `Exception` if the array is empty.\n     */\n    @property bool back()\n    {\n        enforce(!empty);\n        return cast(bool)(data.back & (cast(size_t) 1 << ((_store._length - 1) % bitsPerWord)));\n    }\n\n    /// Ditto\n    @property void back(bool value)\n    {\n        enforce(!empty);\n        if (value)\n        {\n            data.back |= (cast(size_t) 1 << ((_store._length - 1) % bitsPerWord));\n        }\n        else\n        {\n            data.back &=\n                ~(cast(size_t) 1 << ((_store._length - 1) % bitsPerWord));\n        }\n    }\n\n    /**\n     * Indexing operators yielding or modifyng the value at the specified index.\n     *\n     * Precondition: `i < length`\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    bool opIndex(size_t i)\n    {\n        auto div = cast(size_t) (i / bitsPerWord);\n        auto rem = i % bitsPerWord;\n        enforce(div < data.length);\n        return cast(bool)(data.ptr[div] & (cast(size_t) 1 << rem));\n    }\n\n    /// ditto\n    void opIndexAssign(bool value, size_t i)\n    {\n        auto div = cast(size_t) (i / bitsPerWord);\n        auto rem = i % bitsPerWord;\n        enforce(div < data.length);\n        if (value) data.ptr[div] |= (cast(size_t) 1 << rem);\n        else data.ptr[div] &= ~(cast(size_t) 1 << rem);\n    }\n\n    /// ditto\n    void opIndexOpAssign(string op)(bool value, size_t i)\n    {\n        auto div = cast(size_t) (i / bitsPerWord);\n        auto rem = i % bitsPerWord;\n        enforce(div < data.length);\n        auto oldValue = cast(bool) (data.ptr[div] & (cast(size_t) 1 << rem));\n        // Do the deed\n        auto newValue = mixin(\"oldValue \"~op~\" value\");\n        // Write back the value\n        if (newValue != oldValue)\n        {\n            if (newValue) data.ptr[div] |= (cast(size_t) 1 << rem);\n            else data.ptr[div] &= ~(cast(size_t) 1 << rem);\n        }\n    }\n\n    /// Ditto\n    T moveAt(size_t i)\n    {\n        return this[i];\n    }\n\n    /**\n     * Returns: A new array which is a concatenation of `this` and its argument.\n     *\n     * Complexity:\n     * $(BIGOH length + m), where `m` is the number of elements in `stuff`.\n     */\n    Array!bool opBinary(string op, Stuff)(Stuff rhs)\n    if (op == \"~\")\n    {\n        Array!bool result;\n\n        static if (hasLength!Stuff)\n            result.reserve(length + rhs.length);\n        else static if (is(typeof(rhs[])) && hasLength!(typeof(rhs[])))\n            result.reserve(length + rhs[].length);\n        else static if (isImplicitlyConvertible!(Stuff, bool))\n            result.reserve(length + 1);\n\n        result.insertBack(this[]);\n        result ~= rhs;\n        return result;\n    }\n\n    /**\n     * Forwards to `insertBack`.\n     */\n    Array!bool opOpAssign(string op, Stuff)(Stuff stuff)\n    if (op == \"~\")\n    {\n        static if (is(typeof(stuff[]))) insertBack(stuff[]);\n        else insertBack(stuff);\n        return this;\n    }\n\n    /**\n     * Removes all the elements from the array and releases allocated memory.\n     *\n     * Postcondition: `empty == true && capacity == 0`\n     *\n     * Complexity: $(BIGOH length)\n     */\n    void clear()\n    {\n        this = Array();\n    }\n\n    /**\n     * Sets the number of elements in the array to `newLength`. If `newLength`\n     * is greater than `length`, the new elements are added to the end of the\n     * array and initialized with `false`.\n     *\n     * Complexity:\n     * Guaranteed $(BIGOH abs(length - newLength)) if `capacity >= newLength`.\n     * If `capacity < newLength` the worst case is $(BIGOH newLength).\n     *\n     * Postcondition: `length == newLength`\n     */\n    @property void length(size_t newLength)\n    {\n        import std.conv : to;\n        _store.refCountedStore.ensureInitialized();\n        auto newDataLength =\n            to!size_t((newLength + bitsPerWord - 1) / bitsPerWord);\n        _store._backend.length = newDataLength;\n        _store._length = newLength;\n    }\n\n    /**\n     * Removes the last element from the array and returns it.\n     * Both stable and non-stable versions behave the same and guarantee\n     * that ranges iterating over the array are never invalidated.\n     *\n     * Precondition: `empty == false`\n     *\n     * Returns: The element removed.\n     *\n     * Complexity: $(BIGOH 1).\n     *\n     * Throws: `Exception` if the array is empty.\n     */\n    T removeAny()\n    {\n        auto result = back;\n        removeBack();\n        return result;\n    }\n\n    /// ditto\n    alias stableRemoveAny = removeAny;\n\n    /**\n     * Inserts the specified elements at the back of the array. `stuff` can be\n     * a value convertible to `bool` or a range of objects convertible to `bool`.\n     *\n     * Returns: The number of elements inserted.\n     *\n     * Complexity:\n     * $(BIGOH length + m) if reallocation takes place, otherwise $(BIGOH m),\n     * where `m` is the number of elements in `stuff`.\n     */\n    size_t insertBack(Stuff)(Stuff stuff)\n    if (is(Stuff : bool))\n    {\n        _store.refCountedStore.ensureInitialized();\n        auto rem = _store._length % bitsPerWord;\n        if (rem)\n        {\n            // Fits within the current array\n            if (stuff)\n            {\n                data[$ - 1] |= (cast(size_t) 1 << rem);\n            }\n            else\n            {\n                data[$ - 1] &= ~(cast(size_t) 1 << rem);\n            }\n        }\n        else\n        {\n            // Need to add more data\n            _store._backend.insertBack(stuff);\n        }\n        ++_store._length;\n        return 1;\n    }\n\n    /// ditto\n    size_t insertBack(Stuff)(Stuff stuff)\n    if (isInputRange!Stuff && is(ElementType!Stuff : bool))\n    {\n        static if (!hasLength!Stuff) size_t result;\n        for (; !stuff.empty; stuff.popFront())\n        {\n            insertBack(stuff.front);\n            static if (!hasLength!Stuff) ++result;\n        }\n        static if (!hasLength!Stuff) return result;\n        else return stuff.length;\n    }\n\n    /// ditto\n    alias stableInsertBack = insertBack;\n\n    /// ditto\n    alias insert = insertBack;\n\n    /// ditto\n    alias stableInsert = insertBack;\n\n    /// ditto\n    alias linearInsert = insertBack;\n\n    /// ditto\n    alias stableLinearInsert = insertBack;\n\n    /**\n     * Removes the value from the back of the array. Both stable and non-stable\n     * versions behave the same and guarantee that ranges iterating over the\n     * array are never invalidated.\n     *\n     * Precondition: `empty == false`\n     *\n     * Complexity: $(BIGOH 1).\n     *\n     * Throws: `Exception` if the array is empty.\n     */\n    void removeBack()\n    {\n        enforce(_store._length);\n        if (_store._length % bitsPerWord)\n        {\n            // Cool, just decrease the length\n            --_store._length;\n        }\n        else\n        {\n            // Reduce the allocated space\n            --_store._length;\n            _store._backend.length = _store._backend.length - 1;\n        }\n    }\n\n    /// ditto\n    alias stableRemoveBack = removeBack;\n\n    /**\n     * Removes `howMany` values from the back of the array. Unlike the\n     * unparameterized versions above, these functions do not throw if\n     * they could not remove `howMany` elements. Instead, if `howMany > n`,\n     * all elements are removed. The returned value is the effective number\n     * of elements removed. Both stable and non-stable versions behave the same\n     * and guarantee that ranges iterating over the array are never invalidated.\n     *\n     * Returns: The number of elements removed.\n     *\n     * Complexity: $(BIGOH howMany).\n     */\n    size_t removeBack(size_t howMany)\n    {\n        if (howMany >= length)\n        {\n            howMany = length;\n            clear();\n        }\n        else\n        {\n            length = length - howMany;\n        }\n        return howMany;\n    }\n\n    /// ditto\n    alias stableRemoveBack = removeBack;\n\n    /**\n     * Inserts `stuff` before, after, or instead range `r`, which must\n     * be a valid range previously extracted from this array. `stuff`\n     * can be a value convertible to `bool` or a range of objects convertible\n     * to `bool`. Both stable and non-stable version behave the same and\n     * guarantee that ranges iterating over the array are never invalidated.\n     *\n     * Returns: The number of values inserted.\n     *\n     * Complexity: $(BIGOH length + m), where `m` is the length of `stuff`.\n     */\n    size_t insertBefore(Stuff)(Range r, Stuff stuff)\n    {\n        import std.algorithm.mutation : bringToFront;\n        // TODO: make this faster, it moves one bit at a time\n        immutable inserted = stableInsertBack(stuff);\n        immutable tailLength = length - inserted;\n        bringToFront(\n            this[r._a .. tailLength],\n            this[tailLength .. length]);\n        return inserted;\n    }\n\n    /// ditto\n    alias stableInsertBefore = insertBefore;\n\n    /// ditto\n    size_t insertAfter(Stuff)(Range r, Stuff stuff)\n    {\n        import std.algorithm.mutation : bringToFront;\n        // TODO: make this faster, it moves one bit at a time\n        immutable inserted = stableInsertBack(stuff);\n        immutable tailLength = length - inserted;\n        bringToFront(\n            this[r._b .. tailLength],\n            this[tailLength .. length]);\n        return inserted;\n    }\n\n    /// ditto\n    alias stableInsertAfter = insertAfter;\n\n    /// ditto\n    size_t replace(Stuff)(Range r, Stuff stuff)\n    if (is(Stuff : bool))\n    {\n        if (!r.empty)\n        {\n            // There is room\n            r.front = stuff;\n            r.popFront();\n            linearRemove(r);\n        }\n        else\n        {\n            // No room, must insert\n            insertBefore(r, stuff);\n        }\n        return 1;\n    }\n\n    /// ditto\n    alias stableReplace = replace;\n\n    /**\n     * Removes all elements belonging to `r`, which must be a range\n     * obtained originally from this array.\n     *\n     * Returns: A range spanning the remaining elements in the array that\n     * initially were right after `r`.\n     *\n     * Complexity: $(BIGOH length)\n     */\n    Range linearRemove(Range r)\n    {\n        import std.algorithm.mutation : copy;\n        copy(this[r._b .. length], this[r._a .. length]);\n        length = length - r.length;\n        return this[r._a .. length];\n    }\n}\n\n@system unittest\n{\n    Array!bool a;\n    assert(a.empty);\n}\n\n@system unittest\n{\n    Array!bool arr;\n    arr.insert([false, false, false, false]);\n    assert(arr.front == false);\n    assert(arr.back == false);\n    assert(arr[1] == false);\n    auto slice = arr[];\n    slice = arr[0 .. $];\n    slice = slice[1 .. $];\n    slice.front = true;\n    slice.back = true;\n    slice[1] = true;\n    slice = slice[0 .. $]; // bug 19171\n    assert(slice.front == true);\n    assert(slice.back == true);\n    assert(slice[1] == true);\n    assert(slice.moveFront == true);\n    assert(slice.moveBack == true);\n    assert(slice.moveAt(1) == true);\n}\n\n// issue 16331 - uncomparable values are valid values for an array\n@system unittest\n{\n    double[] values = [double.nan, double.nan];\n    auto arr = Array!double(values);\n}\n\n@nogc @system unittest\n{\n    auto a = Array!int(0, 1, 2);\n    int[3] b = [3, 4, 5];\n    short[3] ci = [0, 1, 0];\n    auto c = Array!short(ci);\n    assert(Array!int(0, 1, 2, 0, 1, 2) == a ~ a);\n    assert(Array!int(0, 1, 2, 3, 4, 5) == a ~ b);\n    assert(Array!int(0, 1, 2, 3) == a ~ 3);\n    assert(Array!int(0, 1, 2, 0, 1, 0) == a ~ c);\n}\n\n@nogc @system unittest\n{\n    auto a = Array!char('a', 'b');\n    assert(Array!char(\"abc\") == a ~ 'c');\n    import std.utf : byCodeUnit;\n    assert(Array!char(\"abcd\") == a ~ \"cd\".byCodeUnit);\n}\n\n@nogc @system unittest\n{\n    auto a = Array!dchar(\"ąćę\"d);\n    assert(Array!dchar(\"ąćęϢϖ\"d) == a ~ \"Ϣϖ\"d);\n    wchar x = 'Ϣ';\n    assert(Array!dchar(\"ąćęϢz\"d) == a ~ x ~ 'z');\n}\n\n@system unittest\n{\n    Array!bool a;\n    assert(a.empty);\n    a.insertBack(false);\n    assert(!a.empty);\n}\n\n@system unittest\n{\n    Array!bool a;\n    assert(a.empty);\n    auto b = a.dup;\n    assert(b.empty);\n    a.insertBack(true);\n    assert(b.empty);\n}\n\n@system unittest\n{\n    import std.conv : to;\n    Array!bool a;\n    assert(a.length == 0);\n    a.insert(true);\n    assert(a.length == 1, to!string(a.length));\n}\n\n@system unittest\n{\n    import std.conv : to;\n    Array!bool a;\n    assert(a.capacity == 0);\n    foreach (i; 0 .. 100)\n    {\n        a.insert(true);\n        assert(a.capacity >= a.length, to!string(a.capacity));\n    }\n}\n\n@system unittest\n{\n    Array!bool a;\n    assert(a.capacity == 0);\n    a.reserve(15657);\n    assert(a.capacity >= 15657);\n    a.reserve(100);\n    assert(a.capacity >= 15657);\n}\n\n@system unittest\n{\n    Array!bool a;\n    a.insertBack([true, false, true, true]);\n    assert(a[0 .. 2].length == 2);\n}\n\n@system unittest\n{\n    Array!bool a;\n    a.insertBack([true, false, true, true]);\n    assert(a[].length == 4);\n}\n\n@system unittest\n{\n    Array!bool a;\n    a.insertBack([true, false, true, true]);\n    assert(a.front);\n    a.front = false;\n    assert(!a.front);\n}\n\n@system unittest\n{\n    Array!bool a;\n    a.insertBack([true, false, true, true]);\n    assert(a[].length == 4);\n}\n\n@system unittest\n{\n    Array!bool a;\n    a.insertBack([true, false, true, true]);\n    assert(a.back);\n    a.back = false;\n    assert(!a.back);\n}\n\n@system unittest\n{\n    Array!bool a;\n    a.insertBack([true, false, true, true]);\n    assert(a[0] && !a[1]);\n    a[0] &= a[1];\n    assert(!a[0]);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    Array!bool a;\n    a.insertBack([true, false, true, true]);\n    Array!bool b;\n    b.insertBack([true, true, false, true]);\n    assert(equal((a ~ b)[],\n                    [true, false, true, true, true, true, false, true]));\n    assert((a ~ [true, false])[].equal([true, false, true, true, true, false]));\n    Array!bool c;\n    c.insertBack(true);\n    assert((c ~ false)[].equal([true, false]));\n}\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    Array!bool a;\n    a.insertBack([true, false, true, true]);\n    Array!bool b;\n    a.insertBack([false, true, false, true, true]);\n    a ~= b;\n    assert(equal(\n                a[],\n                [true, false, true, true, false, true, false, true, true]));\n}\n\n@system unittest\n{\n    Array!bool a;\n    a.insertBack([true, false, true, true]);\n    a.clear();\n    assert(a.capacity == 0);\n}\n\n@system unittest\n{\n    Array!bool a;\n    a.length = 1057;\n    assert(a.length == 1057);\n    assert(a.capacity >= a.length);\n    foreach (e; a)\n    {\n        assert(!e);\n    }\n    immutable cap = a.capacity;\n    a.length = 100;\n    assert(a.length == 100);\n    // do not realloc if length decreases\n    assert(a.capacity == cap);\n}\n\n@system unittest\n{\n    Array!bool a;\n    a.length = 1057;\n    assert(!a.removeAny());\n    assert(a.length == 1056);\n    foreach (e; a)\n    {\n        assert(!e);\n    }\n}\n\n@system unittest\n{\n    Array!bool a;\n    for (int i = 0; i < 100; ++i)\n        a.insertBack(true);\n    foreach (e; a)\n        assert(e);\n}\n\n@system unittest\n{\n    Array!bool a;\n    a.length = 1057;\n    assert(a.removeBack(1000) == 1000);\n    assert(a.length == 57);\n    foreach (e; a)\n    {\n        assert(!e);\n    }\n}\n\n@system unittest\n{\n    import std.conv : to;\n    Array!bool a;\n    version (bugxxxx)\n    {\n        a._store.refCountedDebug = true;\n    }\n    a.insertBefore(a[], true);\n    assert(a.length == 1, to!string(a.length));\n    a.insertBefore(a[], false);\n    assert(a.length == 2, to!string(a.length));\n    a.insertBefore(a[1 .. $], true);\n    import std.algorithm.comparison : equal;\n    assert(a[].equal([false, true, true]));\n}\n\n@system unittest\n{\n    import std.conv : to;\n    Array!bool a;\n    a.length = 10;\n    a.insertAfter(a[0 .. 5], true);\n    assert(a.length == 11, to!string(a.length));\n    assert(a[5]);\n}\n@system unittest\n{\n    alias V3 = int[3];\n    V3 v = [1, 2, 3];\n    Array!V3 arr;\n    arr ~= v;\n    assert(arr[0] == [1, 2, 3]);\n}\n@system unittest\n{\n    alias V3 = int[3];\n    V3[2] v = [[1, 2, 3], [4, 5, 6]];\n    Array!V3 arr;\n    arr ~= v;\n    assert(arr[0] == [1, 2, 3]);\n    assert(arr[1] == [4, 5, 6]);\n}\n\n// Issue 13642 - Change of length reallocates without calling GC.\n@system unittest\n{\n    import core.memory;\n    class ABC { void func() { int x = 5; } }\n\n    Array!ABC arr;\n    // Length only allocates if capacity is too low.\n    arr.reserve(4);\n    assert(arr.capacity == 4);\n\n    void func() @nogc\n    {\n        arr.length = 5;\n    }\n    func();\n\n    foreach (ref b; arr) b = new ABC;\n    GC.collect();\n    arr[1].func();\n}\n"
  },
  {
    "path": "libphobos/src/std/container/binaryheap.d",
    "content": "/**\nThis module provides a `BinaryHeap` (aka priority queue)\nadaptor that makes a binary heap out of any user-provided random-access range.\n\nThis module is a submodule of $(MREF std, container).\n\nSource: $(PHOBOSSRC std/container/binaryheap.d)\n\nCopyright: 2010- Andrei Alexandrescu. All rights reserved by the respective holders.\n\nLicense: Distributed under the Boost Software License, Version 1.0.\n(See accompanying file LICENSE_1_0.txt or copy at $(HTTP\nboost.org/LICENSE_1_0.txt)).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n*/\nmodule std.container.binaryheap;\n\nimport std.range.primitives;\nimport std.traits;\n\npublic import std.container.util;\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : take;\n    auto maxHeap = heapify([4, 7, 3, 1, 5]);\n    assert(maxHeap.take(3).equal([7, 5, 4]));\n\n    auto minHeap = heapify!\"a > b\"([4, 7, 3, 1, 5]);\n    assert(minHeap.take(3).equal([1, 3, 4]));\n}\n\n// BinaryHeap\n/**\nImplements a $(HTTP en.wikipedia.org/wiki/Binary_heap, binary heap)\ncontainer on top of a given random-access range type (usually $(D\nT[])) or a random-access container type (usually `Array!T`). The\ndocumentation of `BinaryHeap` will refer to the underlying range or\ncontainer as the $(I store) of the heap.\n\nThe binary heap induces structure over the underlying store such that\naccessing the largest element (by using the `front` property) is a\n$(BIGOH 1) operation and extracting it (by using the $(D\nremoveFront()) method) is done fast in $(BIGOH log n) time.\n\nIf `less` is the less-than operator, which is the default option,\nthen `BinaryHeap` defines a so-called max-heap that optimizes\nextraction of the $(I largest) elements. To define a min-heap,\ninstantiate BinaryHeap with $(D \"a > b\") as its predicate.\n\nSimply extracting elements from a `BinaryHeap` container is\ntantamount to lazily fetching elements of `Store` in descending\norder. Extracting elements from the `BinaryHeap` to completion\nleaves the underlying store sorted in ascending order but, again,\nyields elements in descending order.\n\nIf `Store` is a range, the `BinaryHeap` cannot grow beyond the\nsize of that range. If `Store` is a container that supports $(D\ninsertBack), the `BinaryHeap` may grow by adding elements to the\ncontainer.\n     */\nstruct BinaryHeap(Store, alias less = \"a < b\")\nif (isRandomAccessRange!(Store) || isRandomAccessRange!(typeof(Store.init[])))\n{\n    import std.algorithm.comparison : min;\n    import std.algorithm.mutation : move, swapAt;\n    import std.algorithm.sorting : HeapOps;\n    import std.exception : enforce;\n    import std.functional : binaryFun;\n    import std.typecons : RefCounted, RefCountedAutoInitialize;\n\n    static if (isRandomAccessRange!Store)\n        alias Range = Store;\n    else\n        alias Range = typeof(Store.init[]);\n    alias percolate = HeapOps!(less, Range).percolate;\n    alias buildHeap = HeapOps!(less, Range).buildHeap;\n\n// Really weird @@BUG@@: if you comment out the \"private:\" label below,\n// std.algorithm can't unittest anymore\n//private:\n\n    // The payload includes the support store and the effective length\n    private static struct Data\n    {\n        Store _store;\n        size_t _length;\n    }\n    private RefCounted!(Data, RefCountedAutoInitialize.no) _payload;\n    // Comparison predicate\n    private alias comp = binaryFun!(less);\n    // Convenience accessors\n    private @property ref Store _store()\n    {\n        assert(_payload.refCountedStore.isInitialized);\n        return _payload._store;\n    }\n    private @property ref size_t _length()\n    {\n        assert(_payload.refCountedStore.isInitialized);\n        return _payload._length;\n    }\n\n    // Asserts that the heap property is respected.\n    private void assertValid()\n    {\n        debug\n        {\n            import std.conv : to;\n            if (!_payload.refCountedStore.isInitialized) return;\n            if (_length < 2) return;\n            for (size_t n = _length - 1; n >= 1; --n)\n            {\n                auto parentIdx = (n - 1) / 2;\n                assert(!comp(_store[parentIdx], _store[n]), to!string(n));\n            }\n        }\n    }\n\n    // @@@BUG@@@: add private here, std.algorithm doesn't unittest anymore\n    /*private*/ void pop(Store store)\n    {\n        assert(!store.empty, \"Cannot pop an empty store.\");\n        if (store.length == 1) return;\n        auto t1 = store[].moveFront();\n        auto t2 = store[].moveBack();\n        store.front = move(t2);\n        store.back = move(t1);\n        percolate(store[], 0, store.length - 1);\n    }\n\npublic:\n\n    /**\n       Converts the store `s` into a heap. If `initialSize` is\n       specified, only the first `initialSize` elements in `s`\n       are transformed into a heap, after which the heap can grow up\n       to `r.length` (if `Store` is a range) or indefinitely (if\n       `Store` is a container with `insertBack`). Performs\n       $(BIGOH min(r.length, initialSize)) evaluations of `less`.\n     */\n    this(Store s, size_t initialSize = size_t.max)\n    {\n        acquire(s, initialSize);\n    }\n\n/**\nTakes ownership of a store. After this, manipulating `s` may make\nthe heap work incorrectly.\n     */\n    void acquire(Store s, size_t initialSize = size_t.max)\n    {\n        _payload.refCountedStore.ensureInitialized();\n        _store = move(s);\n        _length = min(_store.length, initialSize);\n        if (_length < 2) return;\n        buildHeap(_store[]);\n        assertValid();\n    }\n\n/**\nTakes ownership of a store assuming it already was organized as a\nheap.\n     */\n    void assume(Store s, size_t initialSize = size_t.max)\n    {\n        _payload.refCountedStore.ensureInitialized();\n        _store = s;\n        _length = min(_store.length, initialSize);\n        assertValid();\n    }\n\n/**\nClears the heap. Returns the portion of the store from `0` up to\n`length`, which satisfies the $(LINK2 https://en.wikipedia.org/wiki/Heap_(data_structure),\nheap property).\n     */\n    auto release()\n    {\n        if (!_payload.refCountedStore.isInitialized)\n        {\n            return typeof(_store[0 .. _length]).init;\n        }\n        assertValid();\n        auto result = _store[0 .. _length];\n        _payload = _payload.init;\n        return result;\n    }\n\n/**\nReturns `true` if the heap is _empty, `false` otherwise.\n     */\n    @property bool empty()\n    {\n        return !length;\n    }\n\n/**\nReturns a duplicate of the heap. The `dup` method is available only if the\nunderlying store supports it.\n     */\n    static if (is(typeof((Store s) { return s.dup; }(Store.init)) == Store))\n    {\n        @property BinaryHeap dup()\n        {\n            BinaryHeap result;\n            if (!_payload.refCountedStore.isInitialized) return result;\n            result.assume(_store.dup, length);\n            return result;\n        }\n    }\n\n/**\nReturns the _length of the heap.\n     */\n    @property size_t length()\n    {\n        return _payload.refCountedStore.isInitialized ? _length : 0;\n    }\n\n/**\nReturns the _capacity of the heap, which is the length of the\nunderlying store (if the store is a range) or the _capacity of the\nunderlying store (if the store is a container).\n     */\n    @property size_t capacity()\n    {\n        if (!_payload.refCountedStore.isInitialized) return 0;\n        static if (is(typeof(_store.capacity) : size_t))\n        {\n            return _store.capacity;\n        }\n        else\n        {\n            return _store.length;\n        }\n    }\n\n/**\nReturns a copy of the _front of the heap, which is the largest element\naccording to `less`.\n     */\n    @property ElementType!Store front()\n    {\n        enforce(!empty, \"Cannot call front on an empty heap.\");\n        return _store.front;\n    }\n\n/**\nClears the heap by detaching it from the underlying store.\n     */\n    void clear()\n    {\n        _payload = _payload.init;\n    }\n\n/**\nInserts `value` into the store. If the underlying store is a range\nand $(D length == capacity), throws an exception.\n     */\n    size_t insert(ElementType!Store value)\n    {\n        static if (is(typeof(_store.insertBack(value))))\n        {\n            _payload.refCountedStore.ensureInitialized();\n            if (length == _store.length)\n            {\n                // reallocate\n                _store.insertBack(value);\n            }\n            else\n            {\n                // no reallocation\n                _store[_length] = value;\n            }\n        }\n        else\n        {\n            import std.traits : isDynamicArray;\n            static if (isDynamicArray!Store)\n            {\n                if (length == _store.length)\n                    _store.length = (length < 6 ? 8 : length * 3 / 2);\n                _store[_length] = value;\n            }\n            else\n            {\n                // can't grow\n                enforce(length < _store.length,\n                        \"Cannot grow a heap created over a range\");\n            }\n        }\n\n        // sink down the element\n        for (size_t n = _length; n; )\n        {\n            auto parentIdx = (n - 1) / 2;\n            if (!comp(_store[parentIdx], _store[n])) break; // done!\n            // must swap and continue\n            _store.swapAt(parentIdx, n);\n            n = parentIdx;\n        }\n        ++_length;\n        debug(BinaryHeap) assertValid();\n        return 1;\n    }\n\n/**\nRemoves the largest element from the heap.\n     */\n    void removeFront()\n    {\n        enforce(!empty, \"Cannot call removeFront on an empty heap.\");\n        if (_length > 1)\n        {\n            auto t1 = _store[].moveFront();\n            auto t2 = _store[].moveAt(_length - 1);\n            _store.front = move(t2);\n            _store[_length - 1] = move(t1);\n        }\n        --_length;\n        percolate(_store[], 0, _length);\n    }\n\n    /// ditto\n    alias popFront = removeFront;\n\n/**\nRemoves the largest element from the heap and returns a copy of\nit. The element still resides in the heap's store. For performance\nreasons you may want to use `removeFront` with heaps of objects\nthat are expensive to copy.\n     */\n    ElementType!Store removeAny()\n    {\n        removeFront();\n        return _store[_length];\n    }\n\n/**\nReplaces the largest element in the store with `value`.\n     */\n    void replaceFront(ElementType!Store value)\n    {\n        // must replace the top\n        assert(!empty, \"Cannot call replaceFront on an empty heap.\");\n        _store.front = value;\n        percolate(_store[], 0, _length);\n        debug(BinaryHeap) assertValid();\n    }\n\n/**\nIf the heap has room to grow, inserts `value` into the store and\nreturns `true`. Otherwise, if $(D less(value, front)), calls $(D\nreplaceFront(value)) and returns again `true`. Otherwise, leaves\nthe heap unaffected and returns `false`. This method is useful in\nscenarios where the smallest `k` elements of a set of candidates\nmust be collected.\n     */\n    bool conditionalInsert(ElementType!Store value)\n    {\n        _payload.refCountedStore.ensureInitialized();\n        if (_length < _store.length)\n        {\n            insert(value);\n            return true;\n        }\n\n        assert(!_store.empty, \"Cannot replace front of an empty heap.\");\n        if (!comp(value, _store.front)) return false; // value >= largest\n        _store.front = value;\n\n        percolate(_store[], 0, _length);\n        debug(BinaryHeap) assertValid();\n        return true;\n    }\n\n/**\nSwapping is allowed if the heap is full. If $(D less(value, front)), the\nmethod exchanges store.front and value and returns `true`. Otherwise, it\nleaves the heap unaffected and returns `false`.\n     */\n    bool conditionalSwap(ref ElementType!Store value)\n    {\n        _payload.refCountedStore.ensureInitialized();\n        assert(_length == _store.length);\n        assert(!_store.empty, \"Cannot swap front of an empty heap.\");\n\n        if (!comp(value, _store.front)) return false; // value >= largest\n\n        import std.algorithm.mutation : swap;\n        swap(_store.front, value);\n\n        percolate(_store[], 0, _length);\n        debug(BinaryHeap) assertValid();\n\n        return true;\n    }\n}\n\n/// Example from \"Introduction to Algorithms\" Cormen et al, p 146\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    int[] a = [ 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 ];\n    auto h = heapify(a);\n    // largest element\n    assert(h.front == 16);\n    // a has the heap property\n    assert(equal(a, [ 16, 14, 10, 8, 7, 9, 3, 2, 4, 1 ]));\n}\n\n/// `BinaryHeap` implements the standard input range interface, allowing\n/// lazy iteration of the underlying range in descending order.\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : take;\n    int[] a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7];\n    auto top5 = heapify(a).take(5);\n    assert(top5.equal([16, 14, 10, 9, 8]));\n}\n\n/**\nConvenience function that returns a `BinaryHeap!Store` object\ninitialized with `s` and `initialSize`.\n */\nBinaryHeap!(Store, less) heapify(alias less = \"a < b\", Store)(Store s,\n        size_t initialSize = size_t.max)\n{\n\n    return BinaryHeap!(Store, less)(s, initialSize);\n}\n\n///\n@system unittest\n{\n    import std.conv : to;\n    import std.range.primitives;\n    {\n        // example from \"Introduction to Algorithms\" Cormen et al., p 146\n        int[] a = [ 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 ];\n        auto h = heapify(a);\n        h = heapify!\"a < b\"(a);\n        assert(h.front == 16);\n        assert(a == [ 16, 14, 10, 8, 7, 9, 3, 2, 4, 1 ]);\n        auto witness = [ 16, 14, 10, 9, 8, 7, 4, 3, 2, 1 ];\n        for (; !h.empty; h.removeFront(), witness.popFront())\n        {\n            assert(!witness.empty);\n            assert(witness.front == h.front);\n        }\n        assert(witness.empty);\n    }\n    {\n        int[] a = [ 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 ];\n        int[] b = new int[a.length];\n        BinaryHeap!(int[]) h = BinaryHeap!(int[])(b, 0);\n        foreach (e; a)\n        {\n            h.insert(e);\n        }\n        assert(b == [ 16, 14, 10, 8, 7, 3, 9, 1, 4, 2 ], to!string(b));\n    }\n}\n\n@system unittest\n{\n    // Test range interface.\n    import std.algorithm.comparison : equal;\n    int[] a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7];\n    auto h = heapify(a);\n    static assert(isInputRange!(typeof(h)));\n    assert(h.equal([16, 14, 10, 9, 8, 7, 4, 3, 2, 1]));\n}\n\n@system unittest // 15675\n{\n    import std.container.array : Array;\n\n    Array!int elements = [1, 2, 10, 12];\n    auto heap = heapify(elements);\n    assert(heap.front == 12);\n}\n\n@system unittest // 16072\n{\n    auto q = heapify!\"a > b\"([2, 4, 5]);\n    q.insert(1);\n    q.insert(6);\n    assert(q.front == 1);\n\n    // test more multiple grows\n    int[] arr;\n    auto r = heapify!\"a < b\"(arr);\n    foreach (i; 0 .. 100)\n        r.insert(i);\n\n    assert(r.front == 99);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    int[] a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7];\n    auto heap = heapify(a);\n    auto dup = heap.dup();\n    assert(dup.equal([16, 14, 10, 9, 8, 7, 4, 3, 2, 1]));\n}\n\n@safe unittest\n{\n    static struct StructWithoutDup\n    {\n        int[] a;\n        @disable StructWithoutDup dup()\n        {\n            StructWithoutDup d;\n            return d;\n        }\n        alias a this;\n    }\n\n    // Assert Binary heap can be created when Store doesn't have dup\n    // if dup is not used.\n    assert(__traits(compiles, ()\n        {\n            auto s = StructWithoutDup([1,2]);\n            auto h = heapify(s);\n        }));\n\n    // Assert dup can't be used on BinaryHeaps when Store doesn't have dup\n    assert(!__traits(compiles, ()\n        {\n            auto s = StructWithoutDup([1,2]);\n            auto h = heapify(s);\n            h.dup();\n        }));\n}\n\n@safe unittest\n{\n    static struct StructWithDup\n    {\n        int[] a;\n        StructWithDup dup()\n        {\n            StructWithDup d;\n            return d;\n        }\n        alias a this;\n    }\n\n    // Assert dup can be used on BinaryHeaps when Store has dup\n    assert(__traits(compiles, ()\n        {\n            auto s = StructWithDup([1, 2]);\n            auto h = heapify(s);\n            h.dup();\n        }));\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange;\n\n    alias RefRange = DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random);\n\n    RefRange a;\n    RefRange b;\n    a.reinit();\n    b.reinit();\n\n    auto heap = heapify(a);\n    foreach (ref elem; b)\n    {\n        heap.conditionalSwap(elem);\n    }\n\n    assert(equal(heap, [ 5, 5, 4, 4, 3, 3, 2, 2, 1, 1]));\n    assert(equal(b, [10, 9, 8, 7, 6, 6, 7, 8, 9, 10]));\n}\n\n@system unittest // Issue 17314\n{\n    import std.algorithm.comparison : equal;\n    int[] a = [5];\n    auto heap = heapify(a);\n    heap.insert(6);\n    assert(equal(heap, [6, 5]));\n}\n"
  },
  {
    "path": "libphobos/src/std/container/dlist.d",
    "content": "/**\nThis module implements a generic doubly-linked list container.\nIt can be used as a queue, dequeue or stack.\n\nThis module is a submodule of $(MREF std, container).\n\nSource: $(PHOBOSSRC std/container/dlist.d)\n\nCopyright: 2010- Andrei Alexandrescu. All rights reserved by the respective holders.\n\nLicense: Distributed under the Boost Software License, Version 1.0.\n(See accompanying file LICENSE_1_0.txt or copy at $(HTTP\nboost.org/LICENSE_1_0.txt)).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n\n$(SCRIPT inhibitQuickIndex = 1;)\n*/\nmodule std.container.dlist;\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container : DList;\n\n    auto s = DList!int(1, 2, 3);\n    assert(equal(s[], [1, 2, 3]));\n\n    s.removeFront();\n    assert(equal(s[], [2, 3]));\n    s.removeBack();\n    assert(equal(s[], [2]));\n\n    s.insertFront([4, 5]);\n    assert(equal(s[], [4, 5, 2]));\n    s.insertBack([6, 7]);\n    assert(equal(s[], [4, 5, 2, 6, 7]));\n\n    // If you want to apply range operations, simply slice it.\n    import std.algorithm.searching : countUntil;\n    import std.range : popFrontN, popBackN, walkLength;\n\n    auto sl = DList!int([1, 2, 3, 4, 5]);\n    assert(countUntil(sl[], 2) == 1);\n\n    auto r = sl[];\n    popFrontN(r, 2);\n    popBackN(r, 2);\n    assert(r.equal([3]));\n    assert(walkLength(r) == 1);\n\n    // DList.Range can be used to remove elements from the list it spans\n    auto nl = DList!int([1, 2, 3, 4, 5]);\n    for (auto rn = nl[]; !rn.empty;)\n        if (rn.front % 2 == 0)\n            nl.popFirstOf(rn);\n        else\n            rn.popFront();\n    assert(equal(nl[], [1, 3, 5]));\n    auto rs = nl[];\n    rs.popFront();\n    nl.remove(rs);\n    assert(equal(nl[], [1]));\n}\n\nimport std.range.primitives;\nimport std.traits;\n\npublic import std.container.util;\n\n/+\nA DList Node without payload. Used to handle the sentinel node (henceforth \"sentinode\").\n\nAlso used for parts of the code that don't depend on the payload type.\n +/\nprivate struct BaseNode\n{\n    private BaseNode* _prev = null;\n    private BaseNode* _next = null;\n\n    /+\n    Gets the payload associated with this node.\n    This is trusted because all nodes are associated with a payload, even\n    the sentinel node.\n    It is also not possible to mix Nodes in DLists of different types.\n    This function is implemented as a member function here, as UFCS does not\n    work with pointers.\n    +/\n    ref inout(T) getPayload(T)() inout @trusted\n    {\n        return (cast(inout(DList!T.PayNode)*)&this)._payload;\n    }\n\n    // Helper: Given nodes p and n, connects them.\n    static void connect(BaseNode* p, BaseNode* n) @safe nothrow pure\n    {\n        p._next = n;\n        n._prev = p;\n    }\n}\n\n/+\nThe base DList Range. Contains Range primitives that don't depend on payload type.\n +/\nprivate struct DRange\n{\n    @safe unittest\n    {\n        static assert(isBidirectionalRange!DRange);\n        static assert(is(ElementType!DRange == BaseNode*));\n    }\n\nnothrow @safe pure:\n    private BaseNode* _first;\n    private BaseNode* _last;\n\n    private this(BaseNode* first, BaseNode* last)\n    {\n        assert((first is null) == (last is null), \"Dlist.Range.this: Invalid arguments\");\n        _first = first;\n        _last = last;\n    }\n    private this(BaseNode* n)\n    {\n        this(n, n);\n    }\n\n    @property\n    bool empty() const\n    {\n        assert((_first is null) == (_last is null), \"DList.Range: Invalidated state\");\n        return !_first;\n    }\n\n    @property BaseNode* front()\n    {\n        assert(!empty, \"DList.Range.front: Range is empty\");\n        return _first;\n    }\n\n    void popFront()\n    {\n        assert(!empty, \"DList.Range.popFront: Range is empty\");\n        if (_first is _last)\n        {\n            _first = _last = null;\n        }\n        else\n        {\n            assert(_first._next && _first is _first._next._prev, \"DList.Range: Invalidated state\");\n            _first = _first._next;\n        }\n    }\n\n    @property BaseNode* back()\n    {\n        assert(!empty, \"DList.Range.front: Range is empty\");\n        return _last;\n    }\n\n    void popBack()\n    {\n        assert(!empty, \"DList.Range.popBack: Range is empty\");\n        if (_first is _last)\n        {\n            _first = _last = null;\n        }\n        else\n        {\n            assert(_last._prev && _last is _last._prev._next, \"DList.Range: Invalidated state\");\n            _last = _last._prev;\n        }\n    }\n\n    /// Forward range primitive.\n    @property DRange save() { return this; }\n}\n\n/**\nImplements a doubly-linked list.\n\n`DList` uses reference semantics.\n */\nstruct DList(T)\n{\n    import std.range : Take;\n\n    /*\n    A Node with a Payload. A PayNode.\n     */\n    struct PayNode\n    {\n        BaseNode _base;\n        alias _base this;\n\n        T _payload = T.init;\n\n        inout(BaseNode)* asBaseNode() inout @trusted\n        {\n            return &_base;\n        }\n    }\n\n    //The sentinel node\n    private BaseNode* _root;\n\n  private\n  {\n    //Construct as new PayNode, and returns it as a BaseNode.\n    static BaseNode* createNode(Stuff)(auto ref Stuff arg, BaseNode* prev = null, BaseNode* next = null)\n    {\n        return (new PayNode(BaseNode(prev, next), arg)).asBaseNode();\n    }\n\n    void initialize() nothrow @safe pure\n    {\n        if (_root) return;\n        //Note: We allocate a PayNode for safety reasons.\n        _root = (new PayNode()).asBaseNode();\n        _root._next = _root._prev = _root;\n    }\n    ref inout(BaseNode*) _first() @property @safe nothrow pure inout\n    {\n        assert(_root);\n        return _root._next;\n    }\n    ref inout(BaseNode*) _last() @property @safe nothrow pure inout\n    {\n        assert(_root);\n        return _root._prev;\n    }\n  } //end private\n\n/**\nConstructor taking a number of nodes\n     */\n    this(U)(U[] values...) if (isImplicitlyConvertible!(U, T))\n    {\n        insertBack(values);\n    }\n\n/**\nConstructor taking an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     */\n    this(Stuff)(Stuff stuff)\n    if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T))\n    {\n        insertBack(stuff);\n    }\n\n/**\nComparison for equality.\n\nComplexity: $(BIGOH min(n, n1)) where `n1` is the number of\nelements in `rhs`.\n     */\n    bool opEquals()(ref const DList rhs) const\n    if (is(typeof(front == front)))\n    {\n        const lhs = this;\n        const lroot = lhs._root;\n        const rroot = rhs._root;\n\n        if (lroot is rroot) return true;\n        if (lroot is null) return rroot is rroot._next;\n        if (rroot is null) return lroot is lroot._next;\n\n        const(BaseNode)* pl = lhs._first;\n        const(BaseNode)* pr = rhs._first;\n        while (true)\n        {\n            if (pl is lroot) return pr is rroot;\n            if (pr is rroot) return false;\n\n            // !== because of NaN\n            if (!(pl.getPayload!T() == pr.getPayload!T())) return false;\n\n            pl = pl._next;\n            pr = pr._next;\n        }\n    }\n\n    /**\n    Defines the container's primary range, which embodies a bidirectional range.\n     */\n    struct Range\n    {\n        static assert(isBidirectionalRange!Range);\n\n        DRange _base;\n        alias _base this;\n\n        private this(BaseNode* first, BaseNode* last)\n        {\n            _base = DRange(first, last);\n        }\n        private this(BaseNode* n)\n        {\n            this(n, n);\n        }\n\n        @property ref T front()\n        {\n            return _base.front.getPayload!T();\n        }\n\n        @property ref T back()\n        {\n            return _base.back.getPayload!T();\n        }\n\n        //Note: shadows base DRange.save.\n        //Necessary for static covariance.\n        @property Range save() { return this; }\n    }\n\n/**\nProperty returning `true` if and only if the container has no\nelements.\n\nComplexity: $(BIGOH 1)\n     */\n    bool empty() @property const nothrow\n    {\n        return _root is null || _root is _first;\n    }\n\n/**\nRemoves all contents from the `DList`.\n\nPostcondition: `empty`\n\nComplexity: $(BIGOH 1)\n     */\n    void clear()\n    {\n        //remove actual elements.\n        remove(this[]);\n    }\n\n/**\nDuplicates the container. The elements themselves are not transitively\nduplicated.\n\nComplexity: $(BIGOH n).\n     */\n    @property DList dup()\n    {\n        return DList(this[]);\n    }\n\n/**\nReturns a range that iterates over all elements of the container, in\nforward order.\n\nComplexity: $(BIGOH 1)\n     */\n    Range opSlice()\n    {\n        if (empty)\n            return Range(null, null);\n        else\n            return Range(_first, _last);\n    }\n\n/**\nForward to `opSlice().front`.\n\nComplexity: $(BIGOH 1)\n     */\n    @property ref inout(T) front() inout\n    {\n        assert(!empty, \"DList.front: List is empty\");\n        return _first.getPayload!T();\n    }\n\n/**\nForward to `opSlice().back`.\n\nComplexity: $(BIGOH 1)\n     */\n    @property ref inout(T) back() inout\n    {\n        assert(!empty, \"DList.back: List is empty\");\n        return _last.getPayload!T();\n    }\n\n/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/\n/+                        BEGIN CONCAT FUNCTIONS HERE                         +/\n/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/\n\n/**\nReturns a new `DList` that's the concatenation of `this` and its\nargument `rhs`.\n     */\n    DList opBinary(string op, Stuff)(Stuff rhs)\n    if (op == \"~\" && is(typeof(insertBack(rhs))))\n    {\n        auto ret = this.dup;\n        ret.insertBack(rhs);\n        return ret;\n    }\n\n/**\nReturns a new `DList` that's the concatenation of the argument `lhs`\nand `this`.\n     */\n    DList opBinaryRight(string op, Stuff)(Stuff lhs)\n    if (op == \"~\" && is(typeof(insertFront(lhs))))\n    {\n        auto ret = this.dup;\n        ret.insertFront(lhs);\n        return ret;\n    }\n\n/**\nAppends the contents of the argument `rhs` into `this`.\n     */\n    DList opOpAssign(string op, Stuff)(Stuff rhs)\n    if (op == \"~\" && is(typeof(insertBack(rhs))))\n    {\n        insertBack(rhs);\n        return this;\n    }\n\n/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/\n/+                        BEGIN INSERT FUNCTIONS HERE                         +/\n/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/\n\n/**\nInserts `stuff` to the front/back of the container. `stuff` can be a\nvalue convertible to `T` or a range of objects convertible to $(D\nT). The stable version behaves the same, but guarantees that ranges\niterating over the container are never invalidated.\n\nReturns: The number of elements inserted\n\nComplexity: $(BIGOH log(n))\n     */\n    size_t insertFront(Stuff)(Stuff stuff)\n    {\n        initialize();\n        return insertAfterNode(_root, stuff);\n    }\n\n    /// ditto\n    size_t insertBack(Stuff)(Stuff stuff)\n    {\n        initialize();\n        return insertBeforeNode(_root, stuff);\n    }\n\n    /// ditto\n    alias insert = insertBack;\n\n    /// ditto\n    alias stableInsert = insert;\n\n    /// ditto\n    alias stableInsertFront = insertFront;\n\n    /// ditto\n    alias stableInsertBack = insertBack;\n\n/**\nInserts `stuff` after range `r`, which must be a non-empty range\npreviously extracted from this container.\n\n`stuff` can be a value convertible to `T` or a range of objects\nconvertible to `T`. The stable version behaves the same, but\nguarantees that ranges iterating over the container are never\ninvalidated.\n\nReturns: The number of values inserted.\n\nComplexity: $(BIGOH k + m), where `k` is the number of elements in\n`r` and `m` is the length of `stuff`.\n     */\n    size_t insertBefore(Stuff)(Range r, Stuff stuff)\n    {\n        if (r._first)\n            return insertBeforeNode(r._first, stuff);\n        else\n        {\n            initialize();\n            return insertAfterNode(_root, stuff);\n        }\n    }\n\n    /// ditto\n    alias stableInsertBefore = insertBefore;\n\n    /// ditto\n    size_t insertAfter(Stuff)(Range r, Stuff stuff)\n    {\n        if (r._last)\n            return insertAfterNode(r._last, stuff);\n        else\n        {\n            initialize();\n            return insertBeforeNode(_root, stuff);\n        }\n    }\n\n    /// ditto\n    alias stableInsertAfter = insertAfter;\n\n/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/\n/+                        BEGIN REMOVE FUNCTIONS HERE                         +/\n/+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/\n\n/**\nPicks one value in an unspecified position in the container, removes\nit from the container, and returns it. The stable version behaves the same,\nbut guarantees that ranges iterating over the container are never invalidated.\n\nPrecondition: `!empty`\n\nReturns: The element removed.\n\nComplexity: $(BIGOH 1).\n     */\n    T removeAny()\n    {\n        import std.algorithm.mutation : move;\n\n        assert(!empty, \"DList.removeAny: List is empty\");\n        auto result = move(back);\n        removeBack();\n        return result;\n    }\n    /// ditto\n    alias stableRemoveAny = removeAny;\n\n/**\nRemoves the value at the front/back of the container. The stable version\nbehaves the same, but guarantees that ranges iterating over the\ncontainer are never invalidated.\n\nPrecondition: `!empty`\n\nComplexity: $(BIGOH 1).\n     */\n    void removeFront()\n    {\n        assert(!empty, \"DList.removeFront: List is empty\");\n        assert(_root is _first._prev, \"DList: Inconsistent state\");\n        BaseNode.connect(_root, _first._next);\n    }\n\n    /// ditto\n    alias stableRemoveFront = removeFront;\n\n    /// ditto\n    void removeBack()\n    {\n        assert(!empty, \"DList.removeBack: List is empty\");\n        assert(_last._next is _root, \"DList: Inconsistent state\");\n        BaseNode.connect(_last._prev, _root);\n    }\n\n    /// ditto\n    alias stableRemoveBack = removeBack;\n\n/**\nRemoves `howMany` values at the front or back of the\ncontainer. Unlike the unparameterized versions above, these functions\ndo not throw if they could not remove `howMany` elements. Instead,\nif $(D howMany > n), all elements are removed. The returned value is\nthe effective number of elements removed. The stable version behaves\nthe same, but guarantees that ranges iterating over the container are\nnever invalidated.\n\nReturns: The number of elements removed\n\nComplexity: $(BIGOH howMany).\n     */\n    size_t removeFront(size_t howMany)\n    {\n        if (!_root) return 0;\n        size_t result;\n        auto p = _first;\n        while (p !is _root && result < howMany)\n        {\n            p = p._next;\n            ++result;\n        }\n        BaseNode.connect(_root, p);\n        return result;\n    }\n\n    /// ditto\n    alias stableRemoveFront = removeFront;\n\n    /// ditto\n    size_t removeBack(size_t howMany)\n    {\n        if (!_root) return 0;\n        size_t result;\n        auto p = _last;\n        while (p !is _root && result < howMany)\n        {\n            p = p._prev;\n            ++result;\n        }\n        BaseNode.connect(p, _root);\n        return result;\n    }\n\n    /// ditto\n    alias stableRemoveBack = removeBack;\n\n/**\nRemoves all elements belonging to `r`, which must be a range\nobtained originally from this container.\n\nReturns: A range spanning the remaining elements in the container that\ninitially were right after `r`.\n\nComplexity: $(BIGOH 1)\n     */\n    Range remove(Range r)\n    {\n        if (r.empty)\n            return r;\n\n        assert(_root !is null, \"Cannot remove from an un-initialized List\");\n        assert(r._first, \"Remove: Range is empty\");\n\n        BaseNode.connect(r._first._prev, r._last._next);\n        auto after = r._last._next;\n        if (after is _root)\n            return Range(null, null);\n        else\n            return Range(after, _last);\n    }\n\n    /// ditto\n    Range linearRemove(Range r)\n    {\n        return remove(r);\n    }\n\n/**\nRemoves first element of `r`, wich must be a range obtained originally\nfrom this container, from both DList instance and range `r`.\n\nCompexity: $(BIGOH 1)\n     */\n    void popFirstOf(ref Range r)\n    {\n        assert(_root !is null, \"Cannot remove from an un-initialized List\");\n        assert(r._first, \"popFirstOf: Range is empty\");\n        auto prev = r._first._prev;\n        auto next = r._first._next;\n        r.popFront();\n        BaseNode.connect(prev, next);\n    }\n\n/**\nRemoves last element of `r`, wich must be a range obtained originally\nfrom this container, from both DList instance and range `r`.\n\nCompexity: $(BIGOH 1)\n     */\n    void popLastOf(ref Range r)\n    {\n        assert(_root !is null, \"Cannot remove from an un-initialized List\");\n        assert(r._first, \"popLastOf: Range is empty\");\n        auto prev = r._last._prev;\n        auto next = r._last._next;\n        r.popBack();\n        BaseNode.connect(prev, next);\n    }\n\n/**\n`linearRemove` functions as `remove`, but also accepts ranges that are\nresult the of a `take` operation. This is a convenient way to remove a\nfixed amount of elements from the range.\n\nComplexity: $(BIGOH r.walkLength)\n     */\n    Range linearRemove(Take!Range r)\n    {\n        assert(_root !is null, \"Cannot remove from an un-initialized List\");\n        assert(r.source._first, \"Remove: Range is empty\");\n\n        BaseNode* first = r.source._first;\n        BaseNode* last = null;\n        do\n        {\n            last = r.source._first;\n            r.popFront();\n        } while ( !r.empty );\n\n        return remove(Range(first, last));\n    }\n\n    /// ditto\n    alias stableRemove = remove;\n    /// ditto\n    alias stableLinearRemove = linearRemove;\n\n/**\nRemoves the first occurence of an element from the list in linear time.\n\nReturns: True if the element existed and was successfully removed, false otherwise.\n\nParams:\n    value = value of the node to be removed\n\nComplexity: $(BIGOH n)\n     */\n    bool linearRemoveElement(T value)\n    {\n        auto n1 = findNodeByValue(_root, value);\n        if (n1)\n        {\n            auto n2 = n1._next._next;\n            BaseNode.connect(n1, n2);\n            return true;\n        }\n\n        return false;\n    }\n\n\nprivate:\n\n    BaseNode* findNodeByValue(BaseNode* n, T value)\n    {\n        if (!n) return null;\n        auto ahead = n._next;\n        while (ahead && ahead.getPayload!T() != value)\n        {\n            n = ahead;\n            ahead = n._next;\n            if (ahead == _last._next) return null;\n        }\n        return n;\n    }\n\n    // Helper: Inserts stuff before the node n.\n    size_t insertBeforeNode(Stuff)(BaseNode* n, ref Stuff stuff)\n    if (isImplicitlyConvertible!(Stuff, T))\n    {\n        auto p = createNode(stuff, n._prev, n);\n        n._prev._next = p;\n        n._prev = p;\n        return 1;\n    }\n    // ditto\n    size_t insertBeforeNode(Stuff)(BaseNode* n, ref Stuff stuff)\n    if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T))\n    {\n        if (stuff.empty) return 0;\n        size_t result;\n        Range r = createRange(stuff, result);\n        BaseNode.connect(n._prev, r._first);\n        BaseNode.connect(r._last, n);\n        return result;\n    }\n\n    // Helper: Inserts stuff after the node n.\n    size_t insertAfterNode(Stuff)(BaseNode* n, ref Stuff stuff)\n    if (isImplicitlyConvertible!(Stuff, T))\n    {\n        auto p = createNode(stuff, n, n._next);\n        n._next._prev = p;\n        n._next = p;\n        return 1;\n    }\n    // ditto\n    size_t insertAfterNode(Stuff)(BaseNode* n, ref Stuff stuff)\n    if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T))\n    {\n        if (stuff.empty) return 0;\n        size_t result;\n        Range r = createRange(stuff, result);\n        BaseNode.connect(r._last, n._next);\n        BaseNode.connect(n, r._first);\n        return result;\n    }\n\n    // Helper: Creates a chain of nodes from the range stuff.\n    Range createRange(Stuff)(ref Stuff stuff, ref size_t result)\n    {\n        BaseNode* first = createNode(stuff.front);\n        BaseNode* last = first;\n        ++result;\n        for ( stuff.popFront() ; !stuff.empty ; stuff.popFront() )\n        {\n            auto p = createNode(stuff.front, last);\n            last = last._next = p;\n            ++result;\n        }\n        return Range(first, last);\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto e = DList!int();\n    auto b = e.linearRemoveElement(1);\n    assert(b == false);\n    assert(e.empty());\n    auto a = DList!int(-1, 1, 2, 1, 3, 4);\n    b = a.linearRemoveElement(1);\n    assert(equal(a[], [-1, 2, 1, 3, 4]));\n    assert(b == true);\n    b = a.linearRemoveElement(-1);\n    assert(b == true);\n    assert(equal(a[], [2, 1, 3, 4]));\n    b = a.linearRemoveElement(1);\n    assert(b == true);\n    assert(equal(a[], [2, 3, 4]));\n    b = a.linearRemoveElement(2);\n    assert(b == true);\n    b = a.linearRemoveElement(20);\n    assert(b == false);\n    assert(equal(a[], [3, 4]));\n    b = a.linearRemoveElement(4);\n    assert(b == true);\n    assert(equal(a[], [3]));\n    b = a.linearRemoveElement(3);\n    assert(b == true);\n    assert(a.empty());\n    a.linearRemoveElement(3);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    //Tests construction signatures\n    alias IntList = DList!int;\n    auto a0 = IntList();\n    auto a1 = IntList(0);\n    auto a2 = IntList(0, 1);\n    auto a3 = IntList([0]);\n    auto a4 = IntList([0, 1]);\n\n    assert(a0[].empty);\n    assert(equal(a1[], [0]));\n    assert(equal(a2[], [0, 1]));\n    assert(equal(a3[], [0]));\n    assert(equal(a4[], [0, 1]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    alias IntList = DList!int;\n    IntList list = IntList([0,1,2,3]);\n    assert(equal(list[],[0,1,2,3]));\n    list.insertBack([4,5,6,7]);\n    assert(equal(list[],[0,1,2,3,4,5,6,7]));\n\n    list = IntList();\n    list.insertFront([0,1,2,3]);\n    assert(equal(list[],[0,1,2,3]));\n    list.insertFront([4,5,6,7]);\n    assert(equal(list[],[4,5,6,7,0,1,2,3]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : take;\n\n    alias IntList = DList!int;\n    IntList list = IntList([0,1,2,3]);\n    auto range = list[];\n    for ( ; !range.empty; range.popFront())\n    {\n        int item = range.front;\n        if (item == 2)\n        {\n            list.stableLinearRemove(take(range, 1));\n            break;\n        }\n    }\n    assert(equal(list[],[0,1,3]));\n\n    list = IntList([0,1,2,3]);\n    range = list[];\n    for ( ; !range.empty; range.popFront())\n    {\n        int item = range.front;\n        if (item == 2)\n        {\n            list.stableLinearRemove(take(range,2));\n            break;\n        }\n    }\n    assert(equal(list[],[0,1]));\n\n    list = IntList([0,1,2,3]);\n    range = list[];\n    for ( ; !range.empty; range.popFront())\n    {\n        int item = range.front;\n        if (item == 0)\n        {\n            list.stableLinearRemove(take(range,2));\n            break;\n        }\n    }\n    assert(equal(list[],[2,3]));\n\n    list = IntList([0,1,2,3]);\n    range = list[];\n    for ( ; !range.empty; range.popFront())\n    {\n        int item = range.front;\n        if (item == 1)\n        {\n            list.stableLinearRemove(take(range,2));\n            break;\n        }\n    }\n    assert(equal(list[],[0,3]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto dl = DList!int([1, 2, 3, 4, 5]);\n    auto r = dl[];\n    r.popFront();\n    dl.popFirstOf(r);\n    assert(equal(dl[], [1, 3, 4, 5]));\n    assert(equal(r, [3, 4, 5]));\n    r.popBack();\n    dl.popLastOf(r);\n    assert(equal(dl[], [1, 3, 5]));\n    assert(equal(r, [3]));\n    dl = DList!int([0]);\n    r = dl[];\n    dl.popFirstOf(r);\n    assert(dl.empty);\n    dl = DList!int([0]);\n    r = dl[];\n    dl.popLastOf(r);\n    assert(dl.empty);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto dl = DList!string([\"a\", \"b\", \"d\"]);\n    dl.insertAfter(dl[], \"e\"); // insert at the end\n    assert(equal(dl[], [\"a\", \"b\", \"d\", \"e\"]));\n    auto dlr = dl[];\n    dlr.popBack(); dlr.popBack();\n    dl.insertAfter(dlr, \"c\"); // insert after \"b\"\n    assert(equal(dl[], [\"a\", \"b\", \"c\", \"d\", \"e\"]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto dl = DList!string([\"a\", \"b\", \"d\"]);\n    dl.insertBefore(dl[], \"e\"); // insert at the front\n    assert(equal(dl[], [\"e\", \"a\", \"b\", \"d\"]));\n    auto dlr = dl[];\n    dlr.popFront(); dlr.popFront();\n    dl.insertBefore(dlr, \"c\"); // insert before \"b\"\n    assert(equal(dl[], [\"e\", \"a\", \"c\", \"b\", \"d\"]));\n}\n\n@safe unittest\n{\n    auto d = DList!int([1, 2, 3]);\n    d.front = 5; //test frontAssign\n    assert(d.front == 5);\n    auto r = d[];\n    r.back = 1;\n    assert(r.back == 1);\n}\n\n// Issue 8895\n@safe unittest\n{\n    auto a = make!(DList!int)(1,2,3,4);\n    auto b = make!(DList!int)(1,2,3,4);\n    auto c = make!(DList!int)(1,2,3,5);\n    auto d = make!(DList!int)(1,2,3,4,5);\n    assert(a == b); // this better terminate!\n    assert(!(a == c));\n    assert(!(a == d));\n}\n\n@safe unittest\n{\n    auto d = DList!int([1, 2, 3]);\n    d.front = 5; //test frontAssign\n    assert(d.front == 5);\n    auto r = d[];\n    r.back = 1;\n    assert(r.back == 1);\n}\n\n@safe unittest\n{\n    auto a = DList!int();\n    assert(a.removeFront(10) == 0);\n    a.insert([1, 2, 3]);\n    assert(a.removeFront(10) == 3);\n    assert(a[].empty);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    //Verify all flavors of ~\n    auto a = DList!int();\n    auto b = DList!int();\n    auto c = DList!int([1, 2, 3]);\n    auto d = DList!int([4, 5, 6]);\n\n    assert((a ~ b[])[].empty);\n    assert((c ~ d[])[].equal([1, 2, 3, 4, 5, 6]));\n    assert(c[].equal([1, 2, 3]));\n    assert(d[].equal([4, 5, 6]));\n\n    assert((c[] ~ d)[].equal([1, 2, 3, 4, 5, 6]));\n    assert(c[].equal([1, 2, 3]));\n    assert(d[].equal([4, 5, 6]));\n\n    a~=c[];\n    assert(a[].equal([1, 2, 3]));\n    assert(c[].equal([1, 2, 3]));\n\n    a~=d[];\n    assert(a[].equal([1, 2, 3, 4, 5, 6]));\n    assert(d[].equal([4, 5, 6]));\n\n    a~=[7, 8, 9];\n    assert(a[].equal([1, 2, 3, 4, 5, 6, 7, 8, 9]));\n\n    //trick test:\n    auto r = c[];\n    c.removeFront();\n    c.removeBack();\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    //8905\n    auto a = DList!int([1, 2, 3, 4]);\n    auto r = a[];\n    a.stableRemoveBack();\n    a.stableInsertBack(7);\n    assert(a[].equal([1, 2, 3, 7]));\n}\n\n@safe unittest //12566\n{\n    auto dl2 = DList!int([2,7]);\n    dl2.removeFront();\n    assert(dl2[].walkLength == 1);\n    dl2.removeBack();\n    assert(dl2.empty, \"not empty?!\");\n}\n\n@safe unittest //13076\n{\n    DList!int list;\n    assert(list.empty);\n    list.clear();\n}\n\n@safe unittest //13425\n{\n    import std.range : drop, take;\n    auto list = DList!int([1,2,3,4,5]);\n    auto r = list[].drop(4); // r is a view of the last element of list\n    assert(r.front == 5 && r.walkLength == 1);\n    r = list.linearRemove(r.take(1));\n    assert(r.empty); // fails\n}\n\n@safe unittest //14300\n{\n    interface ITest {}\n    static class Test : ITest {}\n\n    DList!ITest().insertBack(new Test());\n}\n\n@safe unittest //15263\n{\n    import std.range : iota;\n    auto a = DList!int();\n    a.insertFront(iota(0, 5)); // can insert range with non-ref front\n    assert(a.front == 0 && a.back == 4);\n}\n"
  },
  {
    "path": "libphobos/src/std/container/package.d",
    "content": "// Written in the D programming language.\n\n/**\nThis module defines generic containers.\n\nConstruction:\n\nTo implement the different containers both struct and class based\napproaches have been used. $(REF make, std,container,util) allows for\nuniform construction with either approach.\n\n---\nimport std.container;\n// Construct a red-black tree and an array both containing the values 1, 2, 3.\n// RedBlackTree should typically be allocated using `new`\nRedBlackTree!int rbTree = new RedBlackTree!int(1, 2, 3);\n// But `new` should not be used with Array\nArray!int array = Array!int(1, 2, 3);\n// `make` hides the differences\nRedBlackTree!int rbTree2 = make!(RedBlackTree!int)(1, 2, 3);\nArray!int array2 = make!(Array!int)(1, 2, 3);\n---\n\nNote that `make` can infer the element type from the given arguments.\n\n---\nimport std.container;\nauto rbTree = make!RedBlackTree(1, 2, 3); // RedBlackTree!int\nauto array = make!Array(\"1\", \"2\", \"3\"); // Array!string\n---\n\nReference_semantics:\n\nAll containers have reference semantics, which means that after\nassignment both variables refer to the same underlying data.\n\nTo make a copy of a container, use the `c._dup` container primitive.\n---\nimport std.container, std.range;\nArray!int originalArray = make!(Array!int)(1, 2, 3);\nArray!int secondArray = originalArray;\nassert(equal(originalArray[], secondArray[]));\n\n// changing one instance changes the other one as well!\noriginalArray[0] = 12;\nassert(secondArray[0] == 12);\n\n// secondArray now refers to an independent copy of originalArray\nsecondArray = originalArray.dup;\nsecondArray[0] = 1;\n// assert that originalArray has not been affected\nassert(originalArray[0] == 12);\n---\n\n$(B Attention:) If the container is implemented as a class, using an\nuninitialized instance can cause a null pointer dereference.\n\n---\nimport std.container;\n\nRedBlackTree!int rbTree;\nrbTree.insert(5); // null pointer dereference\n---\n\nUsing an uninitialized struct-based container will work, because the struct\nintializes itself upon use; however, up to this point the container will not\nhave an identity and assignment does not create two references to the same\ndata.\n\n---\nimport std.container;\n\n// create an uninitialized array\nArray!int array1;\n// array2 does _not_ refer to array1\nArray!int array2 = array1;\narray2.insertBack(42);\n// thus array1 will not be affected\nassert(array1.empty);\n\n// after initialization reference semantics work as expected\narray1 = array2;\n// now affects array2 as well\narray1.removeBack();\nassert(array2.empty);\n---\nIt is therefore recommended to always construct containers using\n$(REF make, std,container,util).\n\nThis is in fact necessary to put containers into another container.\nFor example, to construct an `Array` of ten empty `Array`s, use\nthe following that calls `make` ten times.\n\n---\nimport std.container, std.range;\n\nauto arrOfArrs = make!Array(generate!(() => make!(Array!int)).take(10));\n---\n\nSubmodules:\n\nThis module consists of the following submodules:\n\n$(UL\n    $(LI\n        The $(MREF std, container, array) module provides\n        an array type with deterministic control of memory, not reliant on\n        the GC unlike built-in arrays.\n    )\n    $(LI\n        The $(MREF std, container, binaryheap) module\n        provides a binary heap implementation that can be applied to any\n        user-provided random-access range.\n    )\n    $(LI\n        The $(MREF std, container, dlist) module provides\n        a doubly-linked list implementation.\n    )\n    $(LI\n        The $(MREF std, container, rbtree) module\n        implements red-black trees.\n    )\n    $(LI\n        The $(MREF std, container, slist) module\n        implements singly-linked lists.\n    )\n    $(LI\n        The $(MREF std, container, util) module contains\n        some generic tools commonly used by container implementations.\n    )\n)\n\nThe_primary_range_of_a_container:\n\nWhile some containers offer direct access to their elements e.g. via\n`opIndex`, `c.front` or `c.back`, access\nand modification of a container's contents is generally done through\nits primary $(MREF_ALTTEXT range, std, range) type,\nwhich is aliased as `C.Range`. For example, the primary range type of\n`Array!int` is `Array!int.Range`.\n\nIf the documentation of a member function of a container takes\na parameter of type `Range`, then it refers to the primary range type of\nthis container. Oftentimes `Take!Range` will be used, in which case\nthe range refers to a span of the elements in the container. Arguments to\nthese parameters $(B must) be obtained from the same container instance\nas the one being worked with. It is important to note that many generic range\nalgorithms return the same range type as their input range.\n\n---\nimport std.algorithm.comparison : equal;\nimport std.algorithm.iteration : find;\nimport std.container;\nimport std.range : take;\n\nauto array = make!Array(1, 2, 3);\n\n// `find` returns an Array!int.Range advanced to the element \"2\"\narray.linearRemove(array[].find(2));\n\nassert(array[].equal([1]));\n\narray = make!Array(1, 2, 3);\n\n// the range given to `linearRemove` is a Take!(Array!int.Range)\n// spanning just the element \"2\"\narray.linearRemove(array[].find(2).take(1));\n\nassert(array[].equal([1, 3]));\n---\n\nWhen any $(MREF_ALTTEXT range, std, range) can be passed as an argument to\na member function, the documention usually refers to the parameter's templated\ntype as `Stuff`.\n\n---\nimport std.algorithm.comparison : equal;\nimport std.container;\nimport std.range : iota;\n\nauto array = make!Array(1, 2);\n\n// the range type returned by `iota` is completely unrelated to Array,\n// which is fine for Array.insertBack:\narray.insertBack(iota(3, 10));\n\nassert(array[].equal([1, 2, 3, 4, 5, 6, 7, 8, 9]));\n---\n\nContainer_primitives:\n\nContainers do not form a class hierarchy, instead they implement a\ncommon set of primitives (see table below). These primitives each guarantee\na specific worst case complexity and thus allow generic code to be written\nindependently of the container implementation.\n\nFor example the primitives `c.remove(r)` and `c.linearRemove(r)` both\nremove the sequence of elements in range `r` from the container `c`.\nThe primitive `c.remove(r)` guarantees\n$(BIGOH n$(SUBSCRIPT r) log n$(SUBSCRIPT c)) complexity in the worst case and\n`c.linearRemove(r)` relaxes this guarantee to $(BIGOH n$(SUBSCRIPT c)).\n\nSince a sequence of elements can be removed from a $(MREF_ALTTEXT doubly linked list,std,container,dlist)\nin constant time, `DList` provides the primitive `c.remove(r)`\nas well as `c.linearRemove(r)`. On the other hand\n$(MREF_ALTTEXT Array, std,container, array) only offers `c.linearRemove(r)`.\n\nThe following table describes the common set of primitives that containers\nimplement.  A container need not implement all primitives, but if a\nprimitive is implemented, it must support the syntax described in the $(B\nsyntax) column with the semantics described in the $(B description) column, and\nit must not have a worst-case complexity worse than denoted in big-O notation in\nthe $(BIGOH &middot;) column.  Below, `C` means a container type, `c` is\na value of container type, $(D n$(SUBSCRIPT x)) represents the effective length of\nvalue `x`, which could be a single element (in which case $(D n$(SUBSCRIPT x)) is\n`1`), a container, or a range.\n\n$(BOOKTABLE Container primitives,\n$(TR\n    $(TH Syntax)\n    $(TH $(BIGOH &middot;))\n    $(TH Description)\n)\n$(TR\n    $(TDNW `C(x)`)\n    $(TDNW $(D n$(SUBSCRIPT x)))\n    $(TD Creates a container of type `C` from either another container or a range.\n    The created container must not be a null reference even if x is empty.)\n)\n$(TR\n    $(TDNW `c.dup`)\n    $(TDNW $(D n$(SUBSCRIPT c)))\n    $(TD Returns a duplicate of the container.)\n)\n$(TR\n    $(TDNW $(D c ~ x))\n    $(TDNW $(D n$(SUBSCRIPT c) + n$(SUBSCRIPT x)))\n    $(TD Returns the concatenation of `c` and `r`. `x` may be a single\n        element or an input range.)\n)\n$(TR\n    $(TDNW $(D x ~ c))\n    $(TDNW $(D n$(SUBSCRIPT c) + n$(SUBSCRIPT x)))\n    $(TD Returns the concatenation of `x` and `c`.  `x` may be a\n        single element or an input range type.)\n)\n$(LEADINGROWN 3, Iteration\n)\n$(TR\n    $(TD `c.Range`)\n    $(TD)\n    $(TD The primary range type associated with the container.)\n)\n$(TR\n    $(TD `c[]`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Returns a range\n         iterating over the entire container, in a container-defined order.)\n)\n$(TR\n    $(TDNW $(D c[a .. b]))\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Fetches a portion of the container from key `a` to key `b`.)\n)\n$(LEADINGROWN 3, Capacity\n)\n$(TR\n    $(TD `c.empty`)\n    $(TD `1`)\n    $(TD Returns `true` if the container has no elements, `false` otherwise.)\n)\n$(TR\n    $(TD `c.length`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Returns the number of elements in the container.)\n)\n$(TR\n    $(TDNW $(D c.length = n))\n    $(TDNW $(D n$(SUBSCRIPT c) + n))\n    $(TD Forces the number of elements in the container to `n`.\n        If the container ends up growing, the added elements are initialized\n        in a container-dependent manner (usually with `T.init`).)\n)\n$(TR\n    $(TD `c.capacity`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Returns the maximum number of elements that can be stored in the\n    container without triggering a reallocation.)\n)\n$(TR\n    $(TD `c.reserve(x)`)\n    $(TD $(D n$(SUBSCRIPT c)))\n    $(TD Forces `capacity` to at least `x` without reducing it.)\n)\n$(LEADINGROWN 3, Access\n)\n$(TR\n    $(TDNW `c.front`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Returns the first element of the container, in a container-defined order.)\n)\n$(TR\n    $(TDNW `c.moveFront`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Destructively reads and returns the first element of the\n         container. The slot is not removed from the container; it is left\n         initialized with `T.init`. This routine need not be defined if $(D\n         front) returns a `ref`.)\n)\n$(TR\n    $(TDNW $(D c.front = v))\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Assigns `v` to the first element of the container.)\n)\n$(TR\n    $(TDNW `c.back`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Returns the last element of the container, in a container-defined order.)\n)\n$(TR\n    $(TDNW `c.moveBack`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Destructively reads and returns the last element of the\n         container. The slot is not removed from the container; it is left\n         initialized with `T.init`. This routine need not be defined if $(D\n         front) returns a `ref`.)\n)\n$(TR\n    $(TDNW $(D c.back = v))\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Assigns `v` to the last element of the container.)\n)\n$(TR\n    $(TDNW `c[x]`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Provides indexed access into the container. The index type is\n         container-defined. A container may define several index types (and\n         consequently overloaded indexing).)\n)\n$(TR\n    $(TDNW `c.moveAt(x)`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Destructively reads and returns the value at position `x`. The slot\n         is not removed from the container; it is left initialized with $(D\n         T.init).)\n)\n$(TR\n    $(TDNW $(D c[x] = v))\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Sets element at specified index into the container.)\n)\n$(TR\n    $(TDNW $(D c[x] $(I op)= v))\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Performs read-modify-write operation at specified index into the\n        container.)\n)\n$(LEADINGROWN 3, Operations\n)\n$(TR\n    $(TDNW $(D e in c))\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Returns nonzero if e is found in `c`.)\n)\n$(TR\n    $(TDNW `c.lowerBound(v)`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Returns a range of all elements strictly less than `v`.)\n)\n$(TR\n    $(TDNW `c.upperBound(v)`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Returns a range of all elements strictly greater than `v`.)\n)\n$(TR\n    $(TDNW `c.equalRange(v)`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Returns a range of all elements in `c` that are equal to `v`.)\n)\n$(LEADINGROWN 3, Modifiers\n)\n$(TR\n    $(TDNW $(D c ~= x))\n    $(TDNW $(D n$(SUBSCRIPT c) + n$(SUBSCRIPT x)))\n    $(TD Appends `x` to `c`. `x` may be a single element or an input range type.)\n)\n$(TR\n    $(TDNW `c.clear()`)\n    $(TDNW $(D n$(SUBSCRIPT c)))\n    $(TD Removes all elements in `c`.)\n)\n$(TR\n    $(TDNW `c.insert(x)`)\n    $(TDNW $(D n$(SUBSCRIPT x) * log n$(SUBSCRIPT c)))\n    $(TD Inserts `x` in `c` at a position (or positions) chosen by `c`.)\n)\n$(TR\n    $(TDNW `c.stableInsert(x)`)\n    $(TDNW $(D n$(SUBSCRIPT x) * log n$(SUBSCRIPT c)))\n    $(TD Same as `c.insert(x)`, but is guaranteed to not invalidate any ranges.)\n)\n$(TR\n    $(TDNW `c.linearInsert(v)`)\n    $(TDNW $(D n$(SUBSCRIPT c)))\n    $(TD Same as `c.insert(v)` but relaxes complexity to linear.)\n)\n$(TR\n    $(TDNW `c.stableLinearInsert(v)`)\n    $(TDNW $(D n$(SUBSCRIPT c)))\n    $(TD Same as `c.stableInsert(v)` but relaxes complexity to linear.)\n)\n$(TR\n    $(TDNW `c.removeAny()`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Removes some element from `c` and returns it.)\n)\n$(TR\n    $(TDNW `c.stableRemoveAny()`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Same as `c.removeAny()`, but is guaranteed to not invalidate any\n         iterators.)\n)\n$(TR\n    $(TDNW `c.insertFront(v)`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Inserts `v` at the front of `c`.)\n)\n$(TR\n    $(TDNW `c.stableInsertFront(v)`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Same as `c.insertFront(v)`, but guarantees no ranges will be\n         invalidated.)\n)\n$(TR\n    $(TDNW `c.insertBack(v)`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Inserts `v` at the back of `c`.)\n)\n$(TR\n    $(TDNW `c.stableInsertBack(v)`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Same as `c.insertBack(v)`, but guarantees no ranges will be\n         invalidated.)\n)\n$(TR\n    $(TDNW `c.removeFront()`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Removes the element at the front of `c`.)\n)\n$(TR\n    $(TDNW `c.stableRemoveFront()`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Same as `c.removeFront()`, but guarantees no ranges will be\n         invalidated.)\n)\n$(TR\n    $(TDNW `c.removeBack()`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Removes the value at the back of `c`.)\n)\n$(TR\n    $(TDNW `c.stableRemoveBack()`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Same as `c.removeBack()`, but guarantees no ranges will be\n         invalidated.)\n)\n$(TR\n    $(TDNW `c.remove(r)`)\n    $(TDNW $(D n$(SUBSCRIPT r) * log n$(SUBSCRIPT c)))\n    $(TD Removes range `r` from `c`.)\n)\n$(TR\n    $(TDNW `c.stableRemove(r)`)\n    $(TDNW $(D n$(SUBSCRIPT r) * log n$(SUBSCRIPT c)))\n    $(TD Same as `c.remove(r)`, but guarantees iterators are not\n         invalidated.)\n)\n$(TR\n    $(TDNW `c.linearRemove(r)`)\n    $(TDNW $(D n$(SUBSCRIPT c)))\n    $(TD Removes range `r` from `c`.)\n)\n$(TR\n    $(TDNW `c.stableLinearRemove(r)`)\n    $(TDNW $(D n$(SUBSCRIPT c)))\n    $(TD Same as `c.linearRemove(r)`, but guarantees iterators are not\n         invalidated.)\n)\n$(TR\n    $(TDNW `c.removeKey(k)`)\n    $(TDNW $(D log n$(SUBSCRIPT c)))\n    $(TD Removes an element from `c` by using its key `k`.\n         The key's type is defined by the container.)\n)\n)\n\nSource: $(PHOBOSSRC std/container/package.d)\n\nCopyright: Red-black tree code copyright (C) 2008- by Steven Schveighoffer. Other code\ncopyright 2010- Andrei Alexandrescu. All rights reserved by the respective holders.\n\nLicense: Distributed under the Boost Software License, Version 1.0.\n(See accompanying file LICENSE_1_0.txt or copy at $(HTTP\nboost.org/LICENSE_1_0.txt)).\n\nAuthors: Steven Schveighoffer, $(HTTP erdani.com, Andrei Alexandrescu)\n */\n\nmodule std.container;\n\npublic import std.container.array;\npublic import std.container.binaryheap;\npublic import std.container.dlist;\npublic import std.container.rbtree;\npublic import std.container.slist;\n\nimport std.meta;\n\n\n/* The following documentation and type `TotalContainer` are\nintended for developers only.\n\n`TotalContainer` is an unimplemented container that illustrates a\nhost of primitives that a container may define. It is to some extent\nthe bottom of the conceptual container hierarchy. A given container\nmost often will choose to only implement a subset of these primitives,\nand define its own additional ones. Adhering to the standard primitive\nnames below allows generic code to work independently of containers.\n\nThings to remember: any container must be a reference type, whether\nimplemented as a `class` or `struct`. No primitive below\nrequires the container to escape addresses of elements, which means\nthat compliant containers can be defined to use reference counting or\nother deterministic memory management techniques.\n\nA container may choose to define additional specific operations. The\nonly requirement is that those operations bear different names than\nthe ones below, lest user code gets confused.\n\nComplexity of operations should be interpreted as \"at least as good\nas\". If an operation is required to have $(BIGOH n) complexity, it\ncould have anything lower than that, e.g. $(BIGOH log(n)). Unless\nspecified otherwise, `n` inside a $(BIGOH) expression stands for\nthe number of elements in the container.\n */\nstruct TotalContainer(T)\n{\n/**\nIf the container has a notion of key-value mapping, `KeyType`\ndefines the type of the key of the container.\n */\n    alias KeyType = T;\n\n/**\nIf the container has a notion of multikey-value mapping, $(D\nKeyTypes[k]), where `k` is a zero-based unsigned number, defines\nthe type of the `k`th key of the container.\n\nA container may define both `KeyType` and `KeyTypes`, e.g. in\nthe case it has the notion of primary/preferred key.\n */\n    alias KeyTypes = AliasSeq!T;\n\n/**\nIf the container has a notion of key-value mapping, `ValueType`\ndefines the type of the value of the container. Typically, a map-style\ncontainer mapping values of type `K` to values of type `V`\ndefines `KeyType` to be `K` and `ValueType` to be `V`.\n */\n    alias ValueType = T;\n\n/**\nDefines the container's primary range, which embodies one of the\nranges defined in $(MREF std,range).\n\nGenerally a container may define several types of ranges.\n */\n    struct Range\n    {\n        /++\n        Range primitives.\n        +/\n        @property bool empty()\n        {\n            assert(0);\n        }\n        /// Ditto\n        @property ref T front() //ref return optional\n        {\n            assert(0);\n        }\n        /// Ditto\n        @property void front(T value) //Only when front does not return by ref\n        {\n            assert(0);\n        }\n        /// Ditto\n        T moveFront()\n        {\n            assert(0);\n        }\n        /// Ditto\n        void popFront()\n        {\n            assert(0);\n        }\n        /// Ditto\n        @property ref T back() //ref return optional\n        {\n            assert(0);\n        }\n        /// Ditto\n        @property void back(T value) //Only when front does not return by ref\n        {\n            assert(0);\n        }\n        /// Ditto\n        T moveBack()\n        {\n            assert(0);\n        }\n        /// Ditto\n        void popBack()\n        {\n            assert(0);\n        }\n        /// Ditto\n        T opIndex(size_t i) //ref return optional\n        {\n            assert(0);\n        }\n        /// Ditto\n        void opIndexAssign(size_t i, T value) //Only when front does not return by ref\n        {\n            assert(0);\n        }\n        /// Ditto\n        T opIndexUnary(string op)(size_t i) //Only when front does not return by ref\n        {\n            assert(0);\n        }\n        /// Ditto\n        void opIndexOpAssign(string op)(size_t i, T value) //Only when front does not return by ref\n        {\n            assert(0);\n        }\n        /// Ditto\n        T moveAt(size_t i)\n        {\n            assert(0);\n        }\n        /// Ditto\n        @property size_t length()\n        {\n            assert(0);\n        }\n    }\n\n/**\nProperty returning `true` if and only if the container has no\nelements.\n\nComplexity: $(BIGOH 1)\n */\n    @property bool empty()\n    {\n        assert(0);\n    }\n\n/**\nReturns a duplicate of the container. The elements themselves are not\ntransitively duplicated.\n\nComplexity: $(BIGOH n).\n */\n    @property TotalContainer dup()\n    {\n        assert(0);\n    }\n\n/**\nReturns the number of elements in the container.\n\nComplexity: $(BIGOH log(n)).\n*/\n    @property size_t length()\n    {\n        assert(0);\n    }\n\n/**\nReturns the maximum number of elements the container can store without\n(a) allocating memory, (b) invalidating iterators upon insertion.\n\nComplexity: $(BIGOH log(n)).\n */\n    @property size_t capacity()\n    {\n        assert(0);\n    }\n\n/**\nEnsures sufficient capacity to accommodate `n` elements.\n\nPostcondition: $(D capacity >= n)\n\nComplexity: $(BIGOH log(e - capacity)) if $(D e > capacity), otherwise\n$(BIGOH 1).\n */\n    void reserve(size_t e)\n    {\n        assert(0);\n    }\n\n/**\nReturns a range that iterates over all elements of the container, in a\ncontainer-defined order. The container should choose the most\nconvenient and fast method of iteration for `opSlice()`.\n\nComplexity: $(BIGOH log(n))\n */\n    Range opSlice()\n    {\n        assert(0);\n    }\n\n    /**\n       Returns a range that iterates the container between two\n       specified positions.\n\n       Complexity: $(BIGOH log(n))\n     */\n    Range opSlice(size_t a, size_t b)\n    {\n        assert(0);\n    }\n\n/**\nForward to `opSlice().front` and `opSlice().back`, respectively.\n\nComplexity: $(BIGOH log(n))\n */\n    @property ref T front() //ref return optional\n    {\n        assert(0);\n    }\n    /// Ditto\n    @property void front(T value) //Only when front does not return by ref\n    {\n        assert(0);\n    }\n    /// Ditto\n    T moveFront()\n    {\n        assert(0);\n    }\n    /// Ditto\n    @property ref T back() //ref return optional\n    {\n        assert(0);\n    }\n    /// Ditto\n    @property void back(T value) //Only when front does not return by ref\n    {\n        assert(0);\n    }\n    /// Ditto\n    T moveBack()\n    {\n        assert(0);\n    }\n\n/**\nIndexing operators yield or modify the value at a specified index.\n */\n    ref T opIndex(KeyType) //ref return optional\n    {\n        assert(0);\n    }\n    /// ditto\n    void opIndexAssign(KeyType i, T value) //Only when front does not return by ref\n    {\n        assert(0);\n    }\n    /// ditto\n    T opIndexUnary(string op)(KeyType i) //Only when front does not return by ref\n    {\n        assert(0);\n    }\n    /// ditto\n    void opIndexOpAssign(string op)(KeyType i, T value) //Only when front does not return by ref\n    {\n        assert(0);\n    }\n    /// ditto\n    T moveAt(KeyType i)\n    {\n        assert(0);\n    }\n\n/**\n$(D k in container) returns true if the given key is in the container.\n */\n    bool opBinaryRight(string op)(KeyType k) if (op == \"in\")\n    {\n        assert(0);\n    }\n\n/**\nReturns a range of all elements containing `k` (could be empty or a\nsingleton range).\n */\n    Range equalRange(KeyType k)\n    {\n        assert(0);\n    }\n\n/**\nReturns a range of all elements with keys less than `k` (could be\nempty or a singleton range). Only defined by containers that store\ndata sorted at all times.\n */\n    Range lowerBound(KeyType k)\n    {\n        assert(0);\n    }\n\n/**\nReturns a range of all elements with keys larger than `k` (could be\nempty or a singleton range).  Only defined by containers that store\ndata sorted at all times.\n */\n    Range upperBound(KeyType k)\n    {\n        assert(0);\n    }\n\n/**\nReturns a new container that's the concatenation of `this` and its\nargument. `opBinaryRight` is only defined if `Stuff` does not\ndefine `opBinary`.\n\nComplexity: $(BIGOH n + m), where m is the number of elements in $(D\nstuff)\n */\n    TotalContainer opBinary(string op)(Stuff rhs) if (op == \"~\")\n    {\n        assert(0);\n    }\n\n    /// ditto\n    TotalContainer opBinaryRight(string op)(Stuff lhs) if (op == \"~\")\n    {\n        assert(0);\n    }\n\n/**\nForwards to $(D insertAfter(this[], stuff)).\n */\n    void opOpAssign(string op)(Stuff stuff) if (op == \"~\")\n    {\n        assert(0);\n    }\n\n/**\nRemoves all contents from the container. The container decides how $(D\ncapacity) is affected.\n\nPostcondition: `empty`\n\nComplexity: $(BIGOH n)\n */\n    void clear()\n    {\n        assert(0);\n    }\n\n/**\nSets the number of elements in the container to `newSize`. If $(D\nnewSize) is greater than `length`, the added elements are added to\nunspecified positions in the container and initialized with $(D\n.init).\n\nComplexity: $(BIGOH abs(n - newLength))\n\nPostcondition: $(D _length == newLength)\n */\n    @property void length(size_t newLength)\n    {\n        assert(0);\n    }\n\n/**\nInserts `stuff` in an unspecified position in the\ncontainer. Implementations should choose whichever insertion means is\nthe most advantageous for the container, but document the exact\nbehavior. `stuff` can be a value convertible to the element type of\nthe container, or a range of values convertible to it.\n\nThe `stable` version guarantees that ranges iterating over the\ncontainer are never invalidated. Client code that counts on\nnon-invalidating insertion should use `stableInsert`. Such code would\nnot compile against containers that don't support it.\n\nReturns: The number of elements added.\n\nComplexity: $(BIGOH m * log(n)), where `m` is the number of\nelements in `stuff`\n */\n    size_t insert(Stuff)(Stuff stuff)\n    {\n        assert(0);\n    }\n    ///ditto\n    size_t stableInsert(Stuff)(Stuff stuff)\n    {\n        assert(0);\n    }\n\n/**\nSame as `insert(stuff)` and `stableInsert(stuff)` respectively,\nbut relax the complexity constraint to linear.\n */\n    size_t linearInsert(Stuff)(Stuff stuff)\n    {\n        assert(0);\n    }\n    ///ditto\n    size_t stableLinearInsert(Stuff)(Stuff stuff)\n    {\n        assert(0);\n    }\n\n/**\nPicks one value in an unspecified position in the container, removes\nit from the container, and returns it. Implementations should pick the\nvalue that's the most advantageous for the container. The stable version\nbehaves the same, but guarantees that ranges iterating over the container\nare never invalidated.\n\nPrecondition: `!empty`\n\nReturns: The element removed.\n\nComplexity: $(BIGOH log(n)).\n */\n    T removeAny()\n    {\n        assert(0);\n    }\n    /// ditto\n    T stableRemoveAny()\n    {\n        assert(0);\n    }\n\n/**\nInserts `value` to the front or back of the container. `stuff`\ncan be a value convertible to the container's element type or a range\nof values convertible to it. The stable version behaves the same, but\nguarantees that ranges iterating over the container are never\ninvalidated.\n\nReturns: The number of elements inserted\n\nComplexity: $(BIGOH log(n)).\n */\n    size_t insertFront(Stuff)(Stuff stuff)\n    {\n        assert(0);\n    }\n    /// ditto\n    size_t stableInsertFront(Stuff)(Stuff stuff)\n    {\n        assert(0);\n    }\n    /// ditto\n    size_t insertBack(Stuff)(Stuff stuff)\n    {\n        assert(0);\n    }\n    /// ditto\n    size_t stableInsertBack(T value)\n    {\n        assert(0);\n    }\n\n/**\nRemoves the value at the front or back of the container. The stable\nversion behaves the same, but guarantees that ranges iterating over\nthe container are never invalidated. The optional parameter $(D\nhowMany) instructs removal of that many elements. If $(D howMany > n),\nall elements are removed and no exception is thrown.\n\nPrecondition: `!empty`\n\nComplexity: $(BIGOH log(n)).\n */\n    void removeFront()\n    {\n        assert(0);\n    }\n    /// ditto\n    void stableRemoveFront()\n    {\n        assert(0);\n    }\n    /// ditto\n    void removeBack()\n    {\n        assert(0);\n    }\n    /// ditto\n    void stableRemoveBack()\n    {\n        assert(0);\n    }\n\n/**\nRemoves `howMany` values at the front or back of the\ncontainer. Unlike the unparameterized versions above, these functions\ndo not throw if they could not remove `howMany` elements. Instead,\nif $(D howMany > n), all elements are removed. The returned value is\nthe effective number of elements removed. The stable version behaves\nthe same, but guarantees that ranges iterating over the container are\nnever invalidated.\n\nReturns: The number of elements removed\n\nComplexity: $(BIGOH howMany * log(n)).\n */\n    size_t removeFront(size_t howMany)\n    {\n        assert(0);\n    }\n    /// ditto\n    size_t stableRemoveFront(size_t howMany)\n    {\n        assert(0);\n    }\n    /// ditto\n    size_t removeBack(size_t howMany)\n    {\n        assert(0);\n    }\n    /// ditto\n    size_t stableRemoveBack(size_t howMany)\n    {\n        assert(0);\n    }\n\n/**\nRemoves all values corresponding to key `k`.\n\nComplexity: $(BIGOH m * log(n)), where `m` is the number of\nelements with the same key.\n\nReturns: The number of elements removed.\n */\n    size_t removeKey(KeyType k)\n    {\n        assert(0);\n    }\n\n/**\nInserts `stuff` before, after, or instead range `r`, which must\nbe a valid range previously extracted from this container. `stuff`\ncan be a value convertible to the container's element type or a range\nof objects convertible to it. The stable version behaves the same, but\nguarantees that ranges iterating over the container are never\ninvalidated.\n\nReturns: The number of values inserted.\n\nComplexity: $(BIGOH n + m), where `m` is the length of `stuff`\n */\n    size_t insertBefore(Stuff)(Range r, Stuff stuff)\n    {\n        assert(0);\n    }\n    /// ditto\n    size_t stableInsertBefore(Stuff)(Range r, Stuff stuff)\n    {\n        assert(0);\n    }\n    /// ditto\n    size_t insertAfter(Stuff)(Range r, Stuff stuff)\n    {\n        assert(0);\n    }\n    /// ditto\n    size_t stableInsertAfter(Stuff)(Range r, Stuff stuff)\n    {\n        assert(0);\n    }\n    /// ditto\n    size_t replace(Stuff)(Range r, Stuff stuff)\n    {\n        assert(0);\n    }\n    /// ditto\n    size_t stableReplace(Stuff)(Range r, Stuff stuff)\n    {\n        assert(0);\n    }\n\n/**\nRemoves all elements belonging to `r`, which must be a range\nobtained originally from this container. The stable version behaves the\nsame, but guarantees that ranges iterating over the container are\nnever invalidated.\n\nReturns: A range spanning the remaining elements in the container that\ninitially were right after `r`.\n\nComplexity: $(BIGOH m * log(n)), where `m` is the number of\nelements in `r`\n */\n    Range remove(Range r)\n    {\n        assert(0);\n    }\n    /// ditto\n    Range stableRemove(Range r)\n    {\n        assert(0);\n    }\n\n/**\nSame as `remove` above, but has complexity relaxed to linear.\n\nReturns: A range spanning the remaining elements in the container that\ninitially were right after `r`.\n\nComplexity: $(BIGOH n)\n */\n    Range linearRemove(Range r)\n    {\n        assert(0);\n    }\n    /// ditto\n    Range stableLinearRemove(Range r)\n    {\n        assert(0);\n    }\n}\n\n@safe unittest\n{\n    TotalContainer!int test;\n}\n"
  },
  {
    "path": "libphobos/src/std/container/rbtree.d",
    "content": "/**\nThis module implements a red-black tree container.\n\nThis module is a submodule of $(MREF std, container).\n\nSource: $(PHOBOSSRC std/container/rbtree.d)\n\nCopyright: Red-black tree code copyright (C) 2008- by Steven Schveighoffer. Other code\ncopyright 2010- Andrei Alexandrescu. All rights reserved by the respective holders.\n\nLicense: Distributed under the Boost Software License, Version 1.0.\n(See accompanying file LICENSE_1_0.txt or copy at $(HTTP\nboost.org/LICENSE_1_0.txt)).\n\nAuthors: Steven Schveighoffer, $(HTTP erdani.com, Andrei Alexandrescu)\n*/\nmodule std.container.rbtree;\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container.rbtree;\n\n    auto rbt = redBlackTree(3, 1, 4, 2, 5);\n    assert(rbt.front == 1);\n    assert(equal(rbt[], [1, 2, 3, 4, 5]));\n\n    rbt.removeKey(1, 4);\n    assert(equal(rbt[], [2, 3, 5]));\n\n    rbt.removeFront();\n    assert(equal(rbt[], [3, 5]));\n\n    rbt.insert([1, 2, 4]);\n    assert(equal(rbt[], [1, 2, 3, 4, 5]));\n\n    // Query bounds in O(log(n))\n    assert(rbt.lowerBound(3).equal([1, 2]));\n    assert(rbt.equalRange(3).equal([3]));\n    assert(rbt.upperBound(3).equal([4, 5]));\n\n    // A Red Black tree with the highest element at front:\n    import std.range : iota;\n    auto maxTree = redBlackTree!\"a > b\"(iota(5));\n    assert(equal(maxTree[], [4, 3, 2, 1, 0]));\n\n    // adding duplicates will not add them, but return 0\n    auto rbt2 = redBlackTree(1, 3);\n    assert(rbt2.insert(1) == 0);\n    assert(equal(rbt2[], [1, 3]));\n    assert(rbt2.insert(2) == 1);\n\n    // however you can allow duplicates\n    auto ubt = redBlackTree!true([0, 1, 0, 1]);\n    assert(equal(ubt[], [0, 0, 1, 1]));\n}\n\nimport std.format;\nimport std.functional : binaryFun;\n\npublic import std.container.util;\n\nversion (unittest) debug = RBDoChecks;\n\n//debug = RBDoChecks;\n\n/*\n * Implementation for a Red Black node for use in a Red Black Tree (see below)\n *\n * this implementation assumes we have a marker Node that is the parent of the\n * root Node.  This marker Node is not a valid Node, but marks the end of the\n * collection.  The root is the left child of the marker Node, so it is always\n * last in the collection.  The marker Node is passed in to the setColor\n * function, and the Node which has this Node as its parent is assumed to be\n * the root Node.\n *\n * A Red Black tree should have O(lg(n)) insertion, removal, and search time.\n */\nstruct RBNode(V)\n{\n    /*\n     * Convenience alias\n     */\n    alias Node = RBNode*;\n\n    private Node _left;\n    private Node _right;\n    private Node _parent;\n\n    /**\n     * The value held by this node\n     */\n    V value;\n\n    /**\n     * Enumeration determining what color the node is.  Null nodes are assumed\n     * to be black.\n     */\n    enum Color : byte\n    {\n        Red,\n        Black\n    }\n\n    /**\n     * The color of the node.\n     */\n    Color color;\n\n    /**\n     * Get the left child\n     */\n    @property inout(RBNode)* left() inout\n    {\n        return _left;\n    }\n\n    /**\n     * Get the right child\n     */\n    @property inout(RBNode)* right() inout\n    {\n        return _right;\n    }\n\n    /**\n     * Get the parent\n     */\n    @property inout(RBNode)* parent() inout\n    {\n        return _parent;\n    }\n\n    /**\n     * Set the left child.  Also updates the new child's parent node.  This\n     * does not update the previous child.\n     *\n     * Returns newNode\n     */\n    @property Node left(Node newNode)\n    {\n        _left = newNode;\n        if (newNode !is null)\n            newNode._parent = &this;\n        return newNode;\n    }\n\n    /**\n     * Set the right child.  Also updates the new child's parent node.  This\n     * does not update the previous child.\n     *\n     * Returns newNode\n     */\n    @property Node right(Node newNode)\n    {\n        _right = newNode;\n        if (newNode !is null)\n            newNode._parent = &this;\n        return newNode;\n    }\n\n    // assume _left is not null\n    //\n    // performs rotate-right operation, where this is T, _right is R, _left is\n    // L, _parent is P:\n    //\n    //      P         P\n    //      |   ->    |\n    //      T         L\n    //     / \\       / \\\n    //    L   R     a   T\n    //   / \\           / \\\n    //  a   b         b   R\n    //\n    /**\n     * Rotate right.  This performs the following operations:\n     *  - The left child becomes the parent of this node.\n     *  - This node becomes the new parent's right child.\n     *  - The old right child of the new parent becomes the left child of this\n     *    node.\n     */\n    Node rotateR()\n    in\n    {\n        assert(_left !is null);\n    }\n    do\n    {\n        // sets _left._parent also\n        if (isLeftNode)\n            parent.left = _left;\n        else\n            parent.right = _left;\n        Node tmp = _left._right;\n\n        // sets _parent also\n        _left.right = &this;\n\n        // sets tmp._parent also\n        left = tmp;\n\n        return &this;\n    }\n\n    // assumes _right is non null\n    //\n    // performs rotate-left operation, where this is T, _right is R, _left is\n    // L, _parent is P:\n    //\n    //      P           P\n    //      |    ->     |\n    //      T           R\n    //     / \\         / \\\n    //    L   R       T   b\n    //       / \\     / \\\n    //      a   b   L   a\n    //\n    /**\n     * Rotate left.  This performs the following operations:\n     *  - The right child becomes the parent of this node.\n     *  - This node becomes the new parent's left child.\n     *  - The old left child of the new parent becomes the right child of this\n     *    node.\n     */\n    Node rotateL()\n    in\n    {\n        assert(_right !is null);\n    }\n    do\n    {\n        // sets _right._parent also\n        if (isLeftNode)\n            parent.left = _right;\n        else\n            parent.right = _right;\n        Node tmp = _right._left;\n\n        // sets _parent also\n        _right.left = &this;\n\n        // sets tmp._parent also\n        right = tmp;\n        return &this;\n    }\n\n\n    /**\n     * Returns true if this node is a left child.\n     *\n     * Note that this should always return a value because the root has a\n     * parent which is the marker node.\n     */\n    @property bool isLeftNode() const\n    in\n    {\n        assert(_parent !is null);\n    }\n    do\n    {\n        return _parent._left is &this;\n    }\n\n    /**\n     * Set the color of the node after it is inserted.  This performs an\n     * update to the whole tree, possibly rotating nodes to keep the Red-Black\n     * properties correct.  This is an O(lg(n)) operation, where n is the\n     * number of nodes in the tree.\n     *\n     * end is the marker node, which is the parent of the topmost valid node.\n     */\n    void setColor(Node end)\n    {\n        // test against the marker node\n        if (_parent !is end)\n        {\n            if (_parent.color == Color.Red)\n            {\n                Node cur = &this;\n                while (true)\n                {\n                    // because root is always black, _parent._parent always exists\n                    if (cur._parent.isLeftNode)\n                    {\n                        // parent is left node, y is 'uncle', could be null\n                        Node y = cur._parent._parent._right;\n                        if (y !is null && y.color == Color.Red)\n                        {\n                            cur._parent.color = Color.Black;\n                            y.color = Color.Black;\n                            cur = cur._parent._parent;\n                            if (cur._parent is end)\n                            {\n                                // root node\n                                cur.color = Color.Black;\n                                break;\n                            }\n                            else\n                            {\n                                // not root node\n                                cur.color = Color.Red;\n                                if (cur._parent.color == Color.Black)\n                                    // satisfied, exit the loop\n                                    break;\n                            }\n                        }\n                        else\n                        {\n                            if (!cur.isLeftNode)\n                                cur = cur._parent.rotateL();\n                            cur._parent.color = Color.Black;\n                            cur = cur._parent._parent.rotateR();\n                            cur.color = Color.Red;\n                            // tree should be satisfied now\n                            break;\n                        }\n                    }\n                    else\n                    {\n                        // parent is right node, y is 'uncle'\n                        Node y = cur._parent._parent._left;\n                        if (y !is null && y.color == Color.Red)\n                        {\n                            cur._parent.color = Color.Black;\n                            y.color = Color.Black;\n                            cur = cur._parent._parent;\n                            if (cur._parent is end)\n                            {\n                                // root node\n                                cur.color = Color.Black;\n                                break;\n                            }\n                            else\n                            {\n                                // not root node\n                                cur.color = Color.Red;\n                                if (cur._parent.color == Color.Black)\n                                    // satisfied, exit the loop\n                                    break;\n                            }\n                        }\n                        else\n                        {\n                            if (cur.isLeftNode)\n                                cur = cur._parent.rotateR();\n                            cur._parent.color = Color.Black;\n                            cur = cur._parent._parent.rotateL();\n                            cur.color = Color.Red;\n                            // tree should be satisfied now\n                            break;\n                        }\n                    }\n                }\n\n            }\n        }\n        else\n        {\n            //\n            // this is the root node, color it black\n            //\n            color = Color.Black;\n        }\n    }\n\n    /**\n     * Remove this node from the tree.  The 'end' node is used as the marker\n     * which is root's parent.  Note that this cannot be null!\n     *\n     * Returns the next highest valued node in the tree after this one, or end\n     * if this was the highest-valued node.\n     */\n    Node remove(Node end)\n    {\n        //\n        // remove this node from the tree, fixing the color if necessary.\n        //\n        Node x;\n        Node ret = next;\n\n        // if this node has 2 children\n        if (_left !is null && _right !is null)\n        {\n            //\n            // normally, we can just swap this node's and y's value, but\n            // because an iterator could be pointing to y and we don't want to\n            // disturb it, we swap this node and y's structure instead.  This\n            // can also be a benefit if the value of the tree is a large\n            // struct, which takes a long time to copy.\n            //\n            Node yp, yl, yr;\n            Node y = ret; // y = next\n            yp = y._parent;\n            yl = y._left;\n            yr = y._right;\n            auto yc = y.color;\n            auto isyleft = y.isLeftNode;\n\n            //\n            // replace y's structure with structure of this node.\n            //\n            if (isLeftNode)\n                _parent.left = y;\n            else\n                _parent.right = y;\n            //\n            // need special case so y doesn't point back to itself\n            //\n            y.left = _left;\n            if (_right is y)\n                y.right = &this;\n            else\n                y.right = _right;\n            y.color = color;\n\n            //\n            // replace this node's structure with structure of y.\n            //\n            left = yl;\n            right = yr;\n            if (_parent !is y)\n            {\n                if (isyleft)\n                    yp.left = &this;\n                else\n                    yp.right = &this;\n            }\n            color = yc;\n        }\n\n        // if this has less than 2 children, remove it\n        if (_left !is null)\n            x = _left;\n        else\n            x = _right;\n\n        bool deferedUnlink = false;\n        if (x is null)\n        {\n            // pretend this is a null node, defer unlinking the node\n            x = &this;\n            deferedUnlink = true;\n        }\n        else if (isLeftNode)\n            _parent.left = x;\n        else\n            _parent.right = x;\n\n        // if the color of this is black, then it needs to be fixed\n        if (color == color.Black)\n        {\n            // need to recolor the tree.\n            while (x._parent !is end && x.color == Node.Color.Black)\n            {\n                if (x.isLeftNode)\n                {\n                    // left node\n                    Node w = x._parent._right;\n                    if (w.color == Node.Color.Red)\n                    {\n                        w.color = Node.Color.Black;\n                        x._parent.color = Node.Color.Red;\n                        x._parent.rotateL();\n                        w = x._parent._right;\n                    }\n                    Node wl = w.left;\n                    Node wr = w.right;\n                    if ((wl is null || wl.color == Node.Color.Black) &&\n                            (wr is null || wr.color == Node.Color.Black))\n                    {\n                        w.color = Node.Color.Red;\n                        x = x._parent;\n                    }\n                    else\n                    {\n                        if (wr is null || wr.color == Node.Color.Black)\n                        {\n                            // wl cannot be null here\n                            wl.color = Node.Color.Black;\n                            w.color = Node.Color.Red;\n                            w.rotateR();\n                            w = x._parent._right;\n                        }\n\n                        w.color = x._parent.color;\n                        x._parent.color = Node.Color.Black;\n                        w._right.color = Node.Color.Black;\n                        x._parent.rotateL();\n                        x = end.left; // x = root\n                    }\n                }\n                else\n                {\n                    // right node\n                    Node w = x._parent._left;\n                    if (w.color == Node.Color.Red)\n                    {\n                        w.color = Node.Color.Black;\n                        x._parent.color = Node.Color.Red;\n                        x._parent.rotateR();\n                        w = x._parent._left;\n                    }\n                    Node wl = w.left;\n                    Node wr = w.right;\n                    if ((wl is null || wl.color == Node.Color.Black) &&\n                            (wr is null || wr.color == Node.Color.Black))\n                    {\n                        w.color = Node.Color.Red;\n                        x = x._parent;\n                    }\n                    else\n                    {\n                        if (wl is null || wl.color == Node.Color.Black)\n                        {\n                            // wr cannot be null here\n                            wr.color = Node.Color.Black;\n                            w.color = Node.Color.Red;\n                            w.rotateL();\n                            w = x._parent._left;\n                        }\n\n                        w.color = x._parent.color;\n                        x._parent.color = Node.Color.Black;\n                        w._left.color = Node.Color.Black;\n                        x._parent.rotateR();\n                        x = end.left; // x = root\n                    }\n                }\n            }\n            x.color = Node.Color.Black;\n        }\n\n        if (deferedUnlink)\n        {\n            //\n            // unlink this node from the tree\n            //\n            if (isLeftNode)\n                _parent.left = null;\n            else\n                _parent.right = null;\n        }\n\n        // clean references to help GC - Bugzilla 12915\n        _left = _right = _parent = null;\n\n        return ret;\n    }\n\n    /**\n     * Return the leftmost descendant of this node.\n     */\n    @property inout(RBNode)* leftmost() inout\n    {\n        inout(RBNode)* result = &this;\n        while (result._left !is null)\n            result = result._left;\n        return result;\n    }\n\n    /**\n     * Return the rightmost descendant of this node\n     */\n    @property inout(RBNode)* rightmost() inout\n    {\n        inout(RBNode)* result = &this;\n        while (result._right !is null)\n            result = result._right;\n        return result;\n    }\n\n    /**\n     * Returns the next valued node in the tree.\n     *\n     * You should never call this on the marker node, as it is assumed that\n     * there is a valid next node.\n     */\n    @property inout(RBNode)* next() inout\n    {\n        inout(RBNode)* n = &this;\n        if (n.right is null)\n        {\n            while (!n.isLeftNode)\n                n = n._parent;\n            return n._parent;\n        }\n        else\n            return n.right.leftmost;\n    }\n\n    /**\n     * Returns the previous valued node in the tree.\n     *\n     * You should never call this on the leftmost node of the tree as it is\n     * assumed that there is a valid previous node.\n     */\n    @property inout(RBNode)* prev() inout\n    {\n        inout(RBNode)* n = &this;\n        if (n.left is null)\n        {\n            while (n.isLeftNode)\n                n = n._parent;\n            return n._parent;\n        }\n        else\n            return n.left.rightmost;\n    }\n\n    Node dup(scope Node delegate(V v) alloc)\n    {\n        //\n        // duplicate this and all child nodes\n        //\n        // The recursion should be lg(n), so we shouldn't have to worry about\n        // stack size.\n        //\n        Node copy = alloc(value);\n        copy.color = color;\n        if (_left !is null)\n            copy.left = _left.dup(alloc);\n        if (_right !is null)\n            copy.right = _right.dup(alloc);\n        return copy;\n    }\n\n    Node dup()\n    {\n        Node copy = new RBNode!V(null, null, null, value);\n        copy.color = color;\n        if (_left !is null)\n            copy.left = _left.dup();\n        if (_right !is null)\n            copy.right = _right.dup();\n        return copy;\n    }\n}\n\n//constness checks\n@safe pure unittest\n{\n    const RBNode!int n;\n    static assert(is(typeof(n.leftmost)));\n    static assert(is(typeof(n.rightmost)));\n    static assert(is(typeof(n.next)));\n    static assert(is(typeof(n.prev)));\n}\n\nprivate struct RBRange(N)\n{\n    alias Node = N;\n    alias Elem = typeof(Node.value);\n\n    private Node _begin;\n    private Node _end;\n\n    private this(Node b, Node e)\n    {\n        _begin = b;\n        _end = e;\n    }\n\n    /**\n     * Returns `true` if the range is _empty\n     */\n    @property bool empty() const\n    {\n        return _begin is _end;\n    }\n\n    /**\n     * Returns the first element in the range\n     */\n    @property Elem front()\n    {\n        return _begin.value;\n    }\n\n    /**\n     * Returns the last element in the range\n     */\n    @property Elem back()\n    {\n        return _end.prev.value;\n    }\n\n    /**\n     * pop the front element from the range\n     *\n     * Complexity: amortized $(BIGOH 1)\n     */\n    void popFront()\n    {\n        _begin = _begin.next;\n    }\n\n    /**\n     * pop the back element from the range\n     *\n     * Complexity: amortized $(BIGOH 1)\n     */\n    void popBack()\n    {\n        _end = _end.prev;\n    }\n\n    /**\n     * Trivial _save implementation, needed for `isForwardRange`.\n     */\n    @property RBRange save()\n    {\n        return this;\n    }\n}\n\n/**\n * Implementation of a $(LINK2 https://en.wikipedia.org/wiki/Red%E2%80%93black_tree,\n * red-black tree) container.\n *\n * All inserts, removes, searches, and any function in general has complexity\n * of $(BIGOH lg(n)).\n *\n * To use a different comparison than $(D \"a < b\"), pass a different operator string\n * that can be used by $(REF binaryFun, std,functional), or pass in a\n * function, delegate, functor, or any type where $(D less(a, b)) results in a `bool`\n * value.\n *\n * Note that less should produce a strict ordering.  That is, for two unequal\n * elements `a` and `b`, $(D less(a, b) == !less(b, a)). $(D less(a, a)) should\n * always equal `false`.\n *\n * If `allowDuplicates` is set to `true`, then inserting the same element more than\n * once continues to add more elements.  If it is `false`, duplicate elements are\n * ignored on insertion.  If duplicates are allowed, then new elements are\n * inserted after all existing duplicate elements.\n */\nfinal class RedBlackTree(T, alias less = \"a < b\", bool allowDuplicates = false)\nif (is(typeof(binaryFun!less(T.init, T.init))))\n{\n    import std.meta : allSatisfy;\n    import std.range : Take;\n    import std.range.primitives : isInputRange, walkLength;\n    import std.traits : isIntegral, isDynamicArray, isImplicitlyConvertible;\n\n    alias _less = binaryFun!less;\n\n    version (unittest)\n    {\n        static if (is(typeof(less) == string))\n        {\n            private enum doUnittest = isIntegral!T && (less == \"a < b\" || less == \"a > b\");\n        }\n        else\n            enum doUnittest = false;\n\n        // note, this must be final so it does not affect the vtable layout\n        bool arrayEqual(T[] arr)\n        {\n            if (walkLength(this[]) == arr.length)\n            {\n                foreach (v; arr)\n                {\n                    if (!(v in this))\n                        return false;\n                }\n                return true;\n            }\n            return false;\n        }\n    }\n    else\n    {\n        private enum doUnittest = false;\n    }\n\n    /**\n      * Element type for the tree\n      */\n    alias Elem = T;\n\n    // used for convenience\n    private alias RBNode = .RBNode!Elem;\n    private alias Node = RBNode.Node;\n\n    private Node   _end;\n    private Node   _begin;\n    private size_t _length;\n\n    private void _setup()\n    {\n        assert(!_end); //Make sure that _setup isn't run more than once.\n        _begin = _end = allocate();\n    }\n\n    static private Node allocate()\n    {\n        return new RBNode;\n    }\n\n    static private Node allocate(Elem v)\n    {\n        return new RBNode(null, null, null, v);\n    }\n\n    /**\n     * The range types for `RedBlackTree`\n     */\n    alias Range = RBRange!(RBNode*);\n    alias ConstRange = RBRange!(const(RBNode)*); /// Ditto\n    alias ImmutableRange = RBRange!(immutable(RBNode)*); /// Ditto\n\n    static if (doUnittest) @safe pure unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.range.primitives;\n        auto ts = new RedBlackTree(1, 2, 3, 4, 5);\n        assert(ts.length == 5);\n        auto r = ts[];\n\n        static if (less == \"a < b\")\n            auto vals = [1, 2, 3, 4, 5];\n        else\n            auto vals = [5, 4, 3, 2, 1];\n        assert(equal(r, vals));\n\n        assert(r.front == vals.front);\n        assert(r.back != r.front);\n        auto oldfront = r.front;\n        auto oldback = r.back;\n        r.popFront();\n        r.popBack();\n        assert(r.front != r.back);\n        assert(r.front != oldfront);\n        assert(r.back != oldback);\n        assert(ts.length == 5);\n    }\n\n    // find a node based on an element value\n    private inout(RBNode)* _find(Elem e) inout\n    {\n        static if (allowDuplicates)\n        {\n            inout(RBNode)* cur = _end.left;\n            inout(RBNode)* result = null;\n            while (cur)\n            {\n                if (_less(cur.value, e))\n                    cur = cur.right;\n                else if (_less(e, cur.value))\n                    cur = cur.left;\n                else\n                {\n                    // want to find the left-most element\n                    result = cur;\n                    cur = cur.left;\n                }\n            }\n            return result;\n        }\n        else\n        {\n            inout(RBNode)* cur = _end.left;\n            while (cur)\n            {\n                if (_less(cur.value, e))\n                    cur = cur.right;\n                else if (_less(e, cur.value))\n                    cur = cur.left;\n                else\n                    return cur;\n            }\n            return null;\n        }\n    }\n\n    // add an element to the tree, returns the node added, or the existing node\n    // if it has already been added and allowDuplicates is false\n    private auto _add(Elem n)\n    {\n        Node result;\n        static if (!allowDuplicates)\n            bool added = true;\n\n        if (!_end.left)\n        {\n            _end.left = _begin = result = allocate(n);\n        }\n        else\n        {\n            Node newParent = _end.left;\n            Node nxt;\n            while (true)\n            {\n                if (_less(n, newParent.value))\n                {\n                    nxt = newParent.left;\n                    if (nxt is null)\n                    {\n                        //\n                        // add to right of new parent\n                        //\n                        newParent.left = result = allocate(n);\n                        break;\n                    }\n                }\n                else\n                {\n                    static if (!allowDuplicates)\n                    {\n                        if (!_less(newParent.value, n))\n                        {\n                            result = newParent;\n                            added = false;\n                            break;\n                        }\n                    }\n                    nxt = newParent.right;\n                    if (nxt is null)\n                    {\n                        //\n                        // add to right of new parent\n                        //\n                        newParent.right = result = allocate(n);\n                        break;\n                    }\n                }\n                newParent = nxt;\n            }\n            if (_begin.left)\n                _begin = _begin.left;\n        }\n\n        static if (allowDuplicates)\n        {\n            result.setColor(_end);\n            debug(RBDoChecks)\n                check();\n            ++_length;\n            return result;\n        }\n        else\n        {\n            import std.typecons : Tuple;\n\n            if (added)\n            {\n                ++_length;\n                result.setColor(_end);\n            }\n            debug(RBDoChecks)\n                check();\n            return Tuple!(bool, \"added\", Node, \"n\")(added, result);\n        }\n    }\n\n\n    /**\n     * Check if any elements exist in the container.  Returns `false` if at least\n     * one element exists.\n     */\n    @property bool empty()\n    {\n        return _end.left is null;\n    }\n\n    /++\n        Returns the number of elements in the container.\n\n        Complexity: $(BIGOH 1).\n    +/\n    @property size_t length() const\n    {\n        return _length;\n    }\n\n    /**\n     * Duplicate this container.  The resulting container contains a shallow\n     * copy of the elements.\n     *\n     * Complexity: $(BIGOH n)\n     */\n    @property RedBlackTree dup()\n    {\n        return new RedBlackTree(_end.dup(), _length);\n    }\n\n    static if (doUnittest) @safe pure unittest\n    {\n        import std.algorithm.comparison : equal;\n        auto ts = new RedBlackTree(1, 2, 3, 4, 5);\n        assert(ts.length == 5);\n        auto ts2 = ts.dup;\n        assert(ts2.length == 5);\n        assert(equal(ts[], ts2[]));\n        ts2.insert(cast(Elem) 6);\n        assert(!equal(ts[], ts2[]));\n        assert(ts.length == 5 && ts2.length == 6);\n    }\n\n    /**\n     * Fetch a range that spans all the elements in the container.\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    Range opSlice()\n    {\n        return Range(_begin, _end);\n    }\n\n    /// Ditto\n    ConstRange opSlice() const\n    {\n        return ConstRange(_begin, _end);\n    }\n\n    /// Ditto\n    ImmutableRange opSlice() immutable\n    {\n        return ImmutableRange(_begin, _end);\n    }\n\n    /**\n     * The front element in the container\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    Elem front()\n    {\n        return _begin.value;\n    }\n\n    /**\n     * The last element in the container\n     *\n     * Complexity: $(BIGOH log(n))\n     */\n    Elem back()\n    {\n        return _end.prev.value;\n    }\n\n    /++\n        `in` operator. Check to see if the given element exists in the\n        container.\n\n       Complexity: $(BIGOH log(n))\n     +/\n    bool opBinaryRight(string op)(Elem e) const if (op == \"in\")\n    {\n        return _find(e) !is null;\n    }\n\n    static if (doUnittest) @safe pure unittest\n    {\n        auto ts = new RedBlackTree(1, 2, 3, 4, 5);\n        assert(cast(Elem) 3 in ts);\n        assert(cast(Elem) 6 !in ts);\n    }\n\n    /**\n     * Compares two trees for equality.\n     *\n     * Complexity: $(BIGOH n)\n     */\n    override bool opEquals(Object rhs)\n    {\n        import std.algorithm.comparison : equal;\n\n        RedBlackTree that = cast(RedBlackTree) rhs;\n        if (that is null) return false;\n\n        // If there aren't the same number of nodes, we can't be equal.\n        if (this._length != that._length) return false;\n\n        auto thisRange = this[];\n        auto thatRange = that[];\n        return equal!((Elem a, Elem b) => !_less(a,b) && !_less(b,a))\n                     (thisRange, thatRange);\n    }\n\n    static if (doUnittest) @system unittest\n    {\n        auto t1 = new RedBlackTree(1,2,3,4);\n        auto t2 = new RedBlackTree(1,2,3,4);\n        auto t3 = new RedBlackTree(1,2,3,5);\n        auto t4 = new RedBlackTree(1,2,3,4,5);\n        auto o = new Object();\n\n        assert(t1 == t1);\n        assert(t1 == t2);\n        assert(t1 != t3);\n        assert(t1 != t4);\n        assert(t1 != o);  // pathological case, must not crash\n    }\n\n    /**\n     * Generates a hash for the tree. Note that with a custom comparison function\n     * it may not hold that if two rbtrees are equal, the hashes of the trees\n     * will be equal.\n     */\n    override size_t toHash() nothrow @safe\n    {\n        size_t hash = cast(size_t) 0x6b63_616c_4264_6552UL;\n        foreach (ref e; this[])\n            // As in boost::hash_combine\n            // https://www.boost.org/doc/libs/1_55_0/doc/html/hash/reference.html#boost.hash_combine\n            hash += .hashOf(e) + 0x9e3779b9 + (hash << 6) + (hash >>> 2);\n        return hash;\n    }\n\n    static if (doUnittest) @system unittest\n    {\n        auto t1 = new RedBlackTree(1,2,3,4);\n        auto t2 = new RedBlackTree(1,2,3,4);\n        auto t3 = new RedBlackTree(1,2,3,5);\n        auto t4 = new RedBlackTree(1,2,3,4,5);\n\n        assert(t1.toHash() == t2.toHash);\n\n        assert(t1.toHash() != t3.toHash);\n        assert(t2.toHash() != t3.toHash);\n\n        assert(t3.toHash() != t4.toHash);\n        assert(t1.toHash() != t4.toHash);\n\n        // empty tree\n        auto t5 = new RedBlackTree();\n        auto t6 = new RedBlackTree();\n\n        assert(t5.toHash() == t6.toHash());\n\n        auto t7 = new RedBlackTree!string(\"red\", \"black\");\n        auto t8 = new RedBlackTree!string(\"white\", \"black\");\n        auto t9 = new RedBlackTree!string(\"red\", \"black\");\n\n        assert(t7.toHash() == t9.toHash());\n        assert(t7.toHash() != t8.toHash());\n\n        static struct MyInt\n        {\n            int x;\n\n            this(int init_x)\n            {\n                x = init_x;\n            }\n\n            size_t toHash() const @safe nothrow\n            {\n                return typeid(x).getHash(&x) ^ 0xF0F0_F0F0;\n            }\n\n            int opCmp(const MyInt that) const\n            {\n                return (x > that.x) - (x < that.x);\n            }\n\n            bool opEquals(const MyInt that) const\n            {\n                return (this.x == that.x);\n            }\n        }\n\n        auto rbt1 = new RedBlackTree!MyInt(MyInt(1), MyInt(2), MyInt(3), MyInt(4));\n        auto rbt2 = new RedBlackTree!MyInt(MyInt(1), MyInt(2), MyInt(3), MyInt(4));\n\n        assert(rbt1.toHash() == rbt2.toHash());\n        assert(rbt1.toHash() != t1.toHash());\n\n        auto rbt3 = new RedBlackTree!MyInt(MyInt(4), MyInt(2), MyInt(3), MyInt(4));\n\n        assert(rbt1.toHash() != rbt3.toHash());\n\n        class MyInt2\n        {\n            int x;\n\n            this(int init_x)\n            {\n                x = init_x;\n            }\n\n            override size_t toHash() const @safe nothrow\n            {\n                return typeid(x).getHash(&x) ^ 0xF0F0_F0F0;\n            }\n\n            int opCmp(const MyInt2 that) const\n            {\n                return (x > that.x) - (x < that.x);\n            }\n\n            bool opEquals(const MyInt2 that) const\n            {\n                return (this.x == that.x);\n            }\n        }\n\n        static bool nullSafeLess(scope const MyInt2 a, scope const MyInt2 b)\n        {\n            return a is null ? b !is null : (b !is null && a < b);\n        }\n\n        auto rbt4 = new RedBlackTree!MyInt2(new MyInt2(1), new MyInt2(9), new MyInt2(3), new MyInt2(42));\n        auto rbt5 = new RedBlackTree!MyInt2(new MyInt2(1), new MyInt2(9), new MyInt2(3), new MyInt2(42));\n        auto rbt6 = new RedBlackTree!(MyInt2, nullSafeLess)(new MyInt2(9), new MyInt2(3), new MyInt2(42));\n        auto rbt7 = new RedBlackTree!(MyInt2, nullSafeLess)(null);\n\n        assert(rbt6.toHash() != rbt5.toHash());\n        assert(rbt6.toHash() != rbt4.toHash());\n        assert(rbt6.toHash() != rbt7.toHash());\n        assert(rbt4.toHash() == rbt5.toHash());\n\n        auto rbt8 = new RedBlackTree!(MyInt2, nullSafeLess)(null, new MyInt2(9), null, new MyInt2(42));\n        auto rbt9 = new RedBlackTree!(MyInt2, nullSafeLess)(null, new MyInt2(9), null, new MyInt2(42));\n        auto rbt10 = new RedBlackTree!(MyInt2, nullSafeLess)(new MyInt2(94), null, new MyInt2(147));\n\n        assert(rbt8.toHash() == rbt9.toHash());\n        assert(rbt8.toHash() != rbt10.toHash());\n    }\n\n    /**\n     * Removes all elements from the container.\n     *\n     * Complexity: $(BIGOH 1)\n     */\n    void clear()\n    {\n        _end.left = null;\n        _begin = _end;\n        _length = 0;\n    }\n\n    static if (doUnittest) @safe pure unittest\n    {\n        auto ts = new RedBlackTree(1,2,3,4,5);\n        assert(ts.length == 5);\n        ts.clear();\n        assert(ts.empty && ts.length == 0);\n    }\n\n    /**\n     * Insert a single element in the container.  Note that this does not\n     * invalidate any ranges currently iterating the container.\n     *\n     * Returns: The number of elements inserted.\n     *\n     * Complexity: $(BIGOH log(n))\n     */\n    size_t stableInsert(Stuff)(Stuff stuff) if (isImplicitlyConvertible!(Stuff, Elem))\n    {\n        static if (allowDuplicates)\n        {\n            _add(stuff);\n            return 1;\n        }\n        else\n        {\n            return(_add(stuff).added ? 1 : 0);\n        }\n    }\n\n    /**\n     * Insert a range of elements in the container.  Note that this does not\n     * invalidate any ranges currently iterating the container.\n     *\n     * Returns: The number of elements inserted.\n     *\n     * Complexity: $(BIGOH m * log(n))\n     */\n    size_t stableInsert(Stuff)(Stuff stuff) if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, Elem))\n    {\n        size_t result = 0;\n        static if (allowDuplicates)\n        {\n            foreach (e; stuff)\n            {\n                ++result;\n                _add(e);\n            }\n        }\n        else\n        {\n            foreach (e; stuff)\n            {\n                if (_add(e).added)\n                    ++result;\n            }\n        }\n        return result;\n    }\n\n    /// ditto\n    alias insert = stableInsert;\n\n    static if (doUnittest) @safe pure unittest\n    {\n        auto ts = new RedBlackTree(2,1,3,4,5,2,5);\n        static if (allowDuplicates)\n        {\n            assert(ts.length == 7);\n            assert(ts.stableInsert(cast(Elem[])[7, 8, 6, 9, 10, 8]) == 6);\n            assert(ts.length == 13);\n            assert(ts.stableInsert(cast(Elem) 11) == 1 && ts.length == 14);\n            assert(ts.stableInsert(cast(Elem) 7) == 1 && ts.length == 15);\n\n            static if (less == \"a < b\")\n                assert(ts.arrayEqual([1,2,2,3,4,5,5,6,7,7,8,8,9,10,11]));\n            else\n                assert(ts.arrayEqual([11,10,9,8,8,7,7,6,5,5,4,3,2,2,1]));\n        }\n        else\n        {\n            assert(ts.length == 5);\n            Elem[] elems = [7, 8, 6, 9, 10, 8];\n            assert(ts.stableInsert(elems) == 5);\n            assert(ts.length == 10);\n            assert(ts.stableInsert(cast(Elem) 11) == 1 && ts.length == 11);\n            assert(ts.stableInsert(cast(Elem) 7) == 0 && ts.length == 11);\n\n            static if (less == \"a < b\")\n                assert(ts.arrayEqual([1,2,3,4,5,6,7,8,9,10,11]));\n            else\n                assert(ts.arrayEqual([11,10,9,8,7,6,5,4,3,2,1]));\n        }\n    }\n\n    /**\n     * Remove an element from the container and return its value.\n     *\n     * Complexity: $(BIGOH log(n))\n     */\n    Elem removeAny()\n    {\n        scope(success)\n            --_length;\n        auto n = _begin;\n        auto result = n.value;\n        _begin = n.remove(_end);\n        debug(RBDoChecks)\n            check();\n        return result;\n    }\n\n    static if (doUnittest) @safe pure unittest\n    {\n        auto ts = new RedBlackTree(1,2,3,4,5);\n        assert(ts.length == 5);\n        auto x = ts.removeAny();\n        assert(ts.length == 4);\n        Elem[] arr;\n        foreach (Elem i; 1 .. 6)\n            if (i != x) arr ~= i;\n        assert(ts.arrayEqual(arr));\n    }\n\n    /**\n     * Remove the front element from the container.\n     *\n     * Complexity: $(BIGOH log(n))\n     */\n    void removeFront()\n    {\n        scope(success)\n            --_length;\n        _begin = _begin.remove(_end);\n        debug(RBDoChecks)\n            check();\n    }\n\n    /**\n     * Remove the back element from the container.\n     *\n     * Complexity: $(BIGOH log(n))\n     */\n    void removeBack()\n    {\n        scope(success)\n            --_length;\n        auto lastnode = _end.prev;\n        if (lastnode is _begin)\n            _begin = _begin.remove(_end);\n        else\n            lastnode.remove(_end);\n        debug(RBDoChecks)\n            check();\n    }\n\n    static if (doUnittest) @safe pure unittest\n    {\n        auto ts = new RedBlackTree(1,2,3,4,5);\n        assert(ts.length == 5);\n        ts.removeBack();\n        assert(ts.length == 4);\n\n        static if (less == \"a < b\")\n            assert(ts.arrayEqual([1,2,3,4]));\n        else\n            assert(ts.arrayEqual([2,3,4,5]));\n\n        ts.removeFront();\n        assert(ts.arrayEqual([2,3,4]) && ts.length == 3);\n    }\n\n    /++\n        Removes the given range from the container.\n\n        Returns: A range containing all of the elements that were after the\n                 given range.\n\n        Complexity: $(BIGOH m * log(n)) (where m is the number of elements in\n                    the range)\n     +/\n    Range remove(Range r)\n    {\n        auto b = r._begin;\n        auto e = r._end;\n        if (_begin is b)\n            _begin = e;\n        while (b !is e)\n        {\n            b = b.remove(_end);\n            --_length;\n        }\n        debug(RBDoChecks)\n            check();\n        return Range(e, _end);\n    }\n\n    static if (doUnittest) @safe pure unittest\n    {\n        import std.algorithm.comparison : equal;\n        auto ts = new RedBlackTree(1,2,3,4,5);\n        assert(ts.length == 5);\n        auto r = ts[];\n        r.popFront();\n        r.popBack();\n        assert(ts.length == 5);\n        auto r2 = ts.remove(r);\n        assert(ts.length == 2);\n        assert(ts.arrayEqual([1,5]));\n\n        static if (less == \"a < b\")\n            assert(equal(r2, [5]));\n        else\n            assert(equal(r2, [1]));\n    }\n\n    /++\n        Removes the given `Take!Range` from the container\n\n        Returns: A range containing all of the elements that were after the\n                 given range.\n\n        Complexity: $(BIGOH m * log(n)) (where m is the number of elements in\n                    the range)\n     +/\n    Range remove(Take!Range r)\n    {\n        immutable isBegin = (r.source._begin is _begin);\n        auto b = r.source._begin;\n\n        while (!r.empty)\n        {\n            r.popFront();\n            b = b.remove(_end);\n            --_length;\n        }\n\n        if (isBegin)\n            _begin = b;\n\n        return Range(b, _end);\n    }\n\n    static if (doUnittest) @safe pure unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.range : take;\n        auto ts = new RedBlackTree(1,2,3,4,5);\n        auto r = ts[];\n        r.popFront();\n        assert(ts.length == 5);\n        auto r2 = ts.remove(take(r, 0));\n\n        static if (less == \"a < b\")\n        {\n            assert(equal(r2, [2,3,4,5]));\n            auto r3 = ts.remove(take(r, 2));\n            assert(ts.arrayEqual([1,4,5]) && ts.length == 3);\n            assert(equal(r3, [4,5]));\n        }\n        else\n        {\n            assert(equal(r2, [4,3,2,1]));\n            auto r3 = ts.remove(take(r, 2));\n            assert(ts.arrayEqual([5,2,1]) && ts.length == 3);\n            assert(equal(r3, [2,1]));\n        }\n    }\n\n    /++\n       Removes elements from the container that are equal to the given values\n       according to the less comparator. One element is removed for each value\n       given which is in the container. If `allowDuplicates` is true,\n       duplicates are removed only if duplicate values are given.\n\n       Returns: The number of elements removed.\n\n       Complexity: $(BIGOH m log(n)) (where m is the number of elements to remove)\n\n       Example:\n--------------------\nauto rbt = redBlackTree!true(0, 1, 1, 1, 4, 5, 7);\nrbt.removeKey(1, 4, 7);\nassert(equal(rbt[], [0, 1, 1, 5]));\nrbt.removeKey(1, 1, 0);\nassert(equal(rbt[], [5]));\n--------------------\n      +/\n    size_t removeKey(U...)(U elems)\n        if (allSatisfy!(isImplicitlyConvertibleToElem, U))\n    {\n        Elem[U.length] toRemove = [elems];\n        return removeKey(toRemove[]);\n    }\n\n    /++ Ditto +/\n    size_t removeKey(U)(U[] elems)\n        if (isImplicitlyConvertible!(U, Elem))\n    {\n        immutable lenBefore = length;\n\n        foreach (e; elems)\n        {\n            auto beg = _firstGreaterEqual(e);\n            if (beg is _end || _less(e, beg.value))\n                // no values are equal\n                continue;\n            immutable isBegin = (beg is _begin);\n            beg = beg.remove(_end);\n            if (isBegin)\n                _begin = beg;\n            --_length;\n        }\n\n        return lenBefore - length;\n    }\n\n    /++ Ditto +/\n    size_t removeKey(Stuff)(Stuff stuff)\n        if (isInputRange!Stuff &&\n           isImplicitlyConvertible!(ElementType!Stuff, Elem) &&\n           !isDynamicArray!Stuff)\n    {\n        import std.array : array;\n        //We use array in case stuff is a Range from this RedBlackTree - either\n        //directly or indirectly.\n        return removeKey(array(stuff));\n    }\n\n    //Helper for removeKey.\n    private template isImplicitlyConvertibleToElem(U)\n    {\n        enum isImplicitlyConvertibleToElem = isImplicitlyConvertible!(U, Elem);\n    }\n\n    static if (doUnittest) @safe pure unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.range : take;\n        auto rbt = new RedBlackTree(5, 4, 3, 7, 2, 1, 7, 6, 2, 19, 45);\n\n        //The cast(Elem) is because these tests are instantiated with a variety\n        //of numeric types, and the literals are all int, which is not always\n        //implicitly convertible to Elem (e.g. short).\n        static if (allowDuplicates)\n        {\n            assert(rbt.length == 11);\n            assert(rbt.removeKey(cast(Elem) 4) == 1 && rbt.length == 10);\n            assert(rbt.arrayEqual([1,2,2,3,5,6,7,7,19,45]) && rbt.length == 10);\n\n            assert(rbt.removeKey(cast(Elem) 6, cast(Elem) 2, cast(Elem) 1) == 3);\n            assert(rbt.arrayEqual([2,3,5,7,7,19,45]) && rbt.length == 7);\n\n            assert(rbt.removeKey(cast(Elem)(42)) == 0 && rbt.length == 7);\n            assert(rbt.removeKey(take(rbt[], 3)) == 3 && rbt.length == 4);\n\n            static if (less == \"a < b\")\n                assert(equal(rbt[], [7,7,19,45]));\n            else\n                assert(equal(rbt[], [7,5,3,2]));\n        }\n        else\n        {\n            assert(rbt.length == 9);\n            assert(rbt.removeKey(cast(Elem) 4) == 1 && rbt.length == 8);\n            assert(rbt.arrayEqual([1,2,3,5,6,7,19,45]));\n\n            assert(rbt.removeKey(cast(Elem) 6, cast(Elem) 2, cast(Elem) 1) == 3);\n            assert(rbt.arrayEqual([3,5,7,19,45]) && rbt.length == 5);\n\n            assert(rbt.removeKey(cast(Elem)(42)) == 0 && rbt.length == 5);\n            assert(rbt.removeKey(take(rbt[], 3)) == 3 && rbt.length == 2);\n\n            static if (less == \"a < b\")\n                assert(equal(rbt[], [19,45]));\n            else\n                assert(equal(rbt[], [5,3]));\n        }\n    }\n\n    // find the first node where the value is > e\n    private inout(RBNode)* _firstGreater(Elem e) inout\n    {\n        // can't use _find, because we cannot return null\n        auto cur = _end.left;\n        inout(RBNode)* result = _end;\n        while (cur)\n        {\n            if (_less(e, cur.value))\n            {\n                result = cur;\n                cur = cur.left;\n            }\n            else\n                cur = cur.right;\n        }\n        return result;\n    }\n\n    // find the first node where the value is >= e\n    private inout(RBNode)* _firstGreaterEqual(Elem e) inout\n    {\n        // can't use _find, because we cannot return null.\n        auto cur = _end.left;\n        inout(RBNode)* result = _end;\n        while (cur)\n        {\n            if (_less(cur.value, e))\n                cur = cur.right;\n            else\n            {\n                result = cur;\n                cur = cur.left;\n            }\n\n        }\n        return result;\n    }\n\n    /**\n     * Get a range from the container with all elements that are > e according\n     * to the less comparator\n     *\n     * Complexity: $(BIGOH log(n))\n     */\n    Range upperBound(Elem e)\n    {\n        return Range(_firstGreater(e), _end);\n    }\n\n    /// Ditto\n    ConstRange upperBound(Elem e) const\n    {\n        return ConstRange(_firstGreater(e), _end);\n    }\n\n    /// Ditto\n    ImmutableRange upperBound(Elem e) immutable\n    {\n        return ImmutableRange(_firstGreater(e), _end);\n    }\n\n    /**\n     * Get a range from the container with all elements that are < e according\n     * to the less comparator\n     *\n     * Complexity: $(BIGOH log(n))\n     */\n    Range lowerBound(Elem e)\n    {\n        return Range(_begin, _firstGreaterEqual(e));\n    }\n\n    /// Ditto\n    ConstRange lowerBound(Elem e) const\n    {\n        return ConstRange(_begin, _firstGreaterEqual(e));\n    }\n\n    /// Ditto\n    ImmutableRange lowerBound(Elem e) immutable\n    {\n        return ImmutableRange(_begin, _firstGreaterEqual(e));\n    }\n\n    /**\n     * Get a range from the container with all elements that are == e according\n     * to the less comparator\n     *\n     * Complexity: $(BIGOH log(n))\n     */\n    auto equalRange(this This)(Elem e)\n    {\n        auto beg = _firstGreaterEqual(e);\n        alias RangeType = RBRange!(typeof(beg));\n        if (beg is _end || _less(e, beg.value))\n            // no values are equal\n            return RangeType(beg, beg);\n        static if (allowDuplicates)\n        {\n            return RangeType(beg, _firstGreater(e));\n        }\n        else\n        {\n            // no sense in doing a full search, no duplicates are allowed,\n            // so we just get the next node.\n            return RangeType(beg, beg.next);\n        }\n    }\n\n    static if (doUnittest) @safe pure unittest\n    {\n        import std.algorithm.comparison : equal;\n        auto ts = new RedBlackTree(1, 2, 3, 4, 5);\n        auto rl = ts.lowerBound(3);\n        auto ru = ts.upperBound(3);\n        auto re = ts.equalRange(3);\n\n        static if (less == \"a < b\")\n        {\n            assert(equal(rl, [1,2]));\n            assert(equal(ru, [4,5]));\n        }\n        else\n        {\n            assert(equal(rl, [5,4]));\n            assert(equal(ru, [2,1]));\n        }\n\n        assert(equal(re, [3]));\n    }\n\n    debug(RBDoChecks)\n    {\n        /*\n         * Print the tree.  This prints a sideways view of the tree in ASCII form,\n         * with the number of indentations representing the level of the nodes.\n         * It does not print values, only the tree structure and color of nodes.\n         */\n        void printTree(Node n, int indent = 0)\n        {\n            import std.stdio : write, writeln;\n            if (n !is null)\n            {\n                printTree(n.right, indent + 2);\n                for (int i = 0; i < indent; i++)\n                    write(\".\");\n                writeln(n.color == n.color.Black ? \"B\" : \"R\");\n                printTree(n.left, indent + 2);\n            }\n            else\n            {\n                for (int i = 0; i < indent; i++)\n                    write(\".\");\n                writeln(\"N\");\n            }\n            if (indent is 0)\n                writeln();\n        }\n\n        /*\n         * Check the tree for validity.  This is called after every add or remove.\n         * This should only be enabled to debug the implementation of the RB Tree.\n         */\n        void check()\n        {\n            //\n            // check implementation of the tree\n            //\n            int recurse(Node n, string path)\n            {\n                import std.stdio : writeln;\n                if (n is null)\n                    return 1;\n                if (n.parent.left !is n && n.parent.right !is n)\n                    throw new Exception(\"Node at path \" ~ path ~ \" has inconsistent pointers\");\n                Node next = n.next;\n                static if (allowDuplicates)\n                {\n                    if (next !is _end && _less(next.value, n.value))\n                        throw new Exception(\"ordering invalid at path \" ~ path);\n                }\n                else\n                {\n                    if (next !is _end && !_less(n.value, next.value))\n                        throw new Exception(\"ordering invalid at path \" ~ path);\n                }\n                if (n.color == n.color.Red)\n                {\n                    if ((n.left !is null && n.left.color == n.color.Red) ||\n                            (n.right !is null && n.right.color == n.color.Red))\n                        throw new Exception(\"Node at path \" ~ path ~ \" is red with a red child\");\n                }\n\n                int l = recurse(n.left, path ~ \"L\");\n                int r = recurse(n.right, path ~ \"R\");\n                if (l != r)\n                {\n                    writeln(\"bad tree at:\");\n                    debug printTree(n);\n                    throw new Exception(\n                        \"Node at path \" ~ path ~ \" has different number of black nodes on left and right paths\"\n                    );\n                }\n                return l + (n.color == n.color.Black ? 1 : 0);\n            }\n\n            try\n            {\n                recurse(_end.left, \"\");\n            }\n            catch (Exception e)\n            {\n                debug printTree(_end.left, 0);\n                throw e;\n            }\n        }\n    }\n\n    /**\n      Formats the RedBlackTree into a sink function. For more info see $(D\n      std.format.formatValue). Note that this only is available when the\n      element type can be formatted. Otherwise, the default toString from\n      Object is used.\n     */\n    static if (is(typeof((){FormatSpec!(char) fmt; formatValue((const(char)[]) {}, ConstRange.init, fmt);})))\n    {\n        void toString(scope void delegate(const(char)[]) sink, const ref FormatSpec!char fmt) const\n        {\n            sink(\"RedBlackTree(\");\n            sink.formatValue(this[], fmt);\n            sink(\")\");\n        }\n    }\n\n    /**\n     * Constructor. Pass in an array of elements, or individual elements to\n     * initialize the tree with.\n     */\n    this(Elem[] elems...)\n    {\n        _setup();\n        stableInsert(elems);\n    }\n\n    /**\n     * Constructor. Pass in a range of elements to initialize the tree with.\n     */\n    this(Stuff)(Stuff stuff) if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, Elem))\n    {\n        _setup();\n        stableInsert(stuff);\n    }\n\n    ///\n    this()\n    {\n        _setup();\n    }\n\n    private this(Node end, size_t length)\n    {\n        _end = end;\n        _begin = end.leftmost;\n        _length = length;\n    }\n}\n\n//Verify Example for removeKey.\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    auto rbt = redBlackTree!true(0, 1, 1, 1, 4, 5, 7);\n    rbt.removeKey(1, 4, 7);\n    assert(equal(rbt[], [0, 1, 1, 5]));\n    rbt.removeKey(1, 1, 0);\n    assert(equal(rbt[], [5]));\n}\n\n//Tests for removeKey\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    {\n        auto rbt = redBlackTree([\"hello\", \"world\", \"foo\", \"bar\"]);\n        assert(equal(rbt[], [\"bar\", \"foo\", \"hello\", \"world\"]));\n        assert(rbt.removeKey(\"hello\") == 1);\n        assert(equal(rbt[], [\"bar\", \"foo\", \"world\"]));\n        assert(rbt.removeKey(\"hello\") == 0);\n        assert(equal(rbt[], [\"bar\", \"foo\", \"world\"]));\n        assert(rbt.removeKey(\"hello\", \"foo\", \"bar\") == 2);\n        assert(equal(rbt[], [\"world\"]));\n        assert(rbt.removeKey([\"\", \"world\", \"hello\"]) == 1);\n        assert(rbt.empty);\n    }\n\n    {\n        auto rbt = redBlackTree([1, 2, 12, 27, 4, 500]);\n        assert(equal(rbt[], [1, 2, 4, 12, 27, 500]));\n        assert(rbt.removeKey(1u) == 1);\n        assert(equal(rbt[], [2, 4, 12, 27, 500]));\n        assert(rbt.removeKey(cast(byte) 1) == 0);\n        assert(equal(rbt[], [2, 4, 12, 27, 500]));\n        assert(rbt.removeKey(1, 12u, cast(byte) 27) == 2);\n        assert(equal(rbt[], [2, 4, 500]));\n        assert(rbt.removeKey([cast(short) 0, cast(short) 500, cast(short) 1]) == 1);\n        assert(equal(rbt[], [2, 4]));\n    }\n}\n\n@safe pure unittest\n{\n    void test(T)()\n    {\n        auto rt1 = new RedBlackTree!(T, \"a < b\", false)();\n        auto rt2 = new RedBlackTree!(T, \"a < b\", true)();\n        auto rt3 = new RedBlackTree!(T, \"a > b\", false)();\n        auto rt4 = new RedBlackTree!(T, \"a > b\", true)();\n    }\n\n    test!long();\n    test!ulong();\n    test!int();\n    test!uint();\n    test!short();\n    test!ushort();\n    test!byte();\n    test!byte();\n}\n\nimport std.range.primitives : isInputRange, ElementType;\nimport std.traits : isArray, isSomeString;\n\n/++\n    Convenience function for creating a `RedBlackTree!E` from a list of\n    values.\n\n    Params:\n        allowDuplicates =  Whether duplicates should be allowed (optional, default: false)\n        less = predicate to sort by (optional)\n        elems = elements to insert into the rbtree (variadic arguments)\n        range = range elements to insert into the rbtree (alternative to elems)\n  +/\nauto redBlackTree(E)(E[] elems...)\n{\n    return new RedBlackTree!E(elems);\n}\n\n/++ Ditto +/\nauto redBlackTree(bool allowDuplicates, E)(E[] elems...)\n{\n    return new RedBlackTree!(E, \"a < b\", allowDuplicates)(elems);\n}\n\n/++ Ditto +/\nauto redBlackTree(alias less, E)(E[] elems...)\nif (is(typeof(binaryFun!less(E.init, E.init))))\n{\n    return new RedBlackTree!(E, less)(elems);\n}\n\n/++ Ditto +/\nauto redBlackTree(alias less, bool allowDuplicates, E)(E[] elems...)\nif (is(typeof(binaryFun!less(E.init, E.init))))\n{\n    //We shouldn't need to instantiate less here, but for some reason,\n    //dmd can't handle it if we don't (even though the template which\n    //takes less but not allowDuplicates works just fine).\n    return new RedBlackTree!(E, binaryFun!less, allowDuplicates)(elems);\n}\n\n/++ Ditto +/\nauto redBlackTree(Stuff)(Stuff range)\nif (isInputRange!Stuff && !isArray!(Stuff))\n{\n    return new RedBlackTree!(ElementType!Stuff)(range);\n}\n\n/++ Ditto +/\nauto redBlackTree(bool allowDuplicates, Stuff)(Stuff range)\nif (isInputRange!Stuff && !isArray!(Stuff))\n{\n    return new RedBlackTree!(ElementType!Stuff, \"a < b\", allowDuplicates)(range);\n}\n\n/++ Ditto +/\nauto redBlackTree(alias less, Stuff)(Stuff range)\nif ( is(typeof(binaryFun!less((ElementType!Stuff).init, (ElementType!Stuff).init)))\n    && isInputRange!Stuff && !isArray!(Stuff))\n{\n    return new RedBlackTree!(ElementType!Stuff, less)(range);\n}\n\n/++ Ditto +/\nauto redBlackTree(alias less, bool allowDuplicates, Stuff)(Stuff range)\nif ( is(typeof(binaryFun!less((ElementType!Stuff).init, (ElementType!Stuff).init)))\n    && isInputRange!Stuff && !isArray!(Stuff))\n{\n    //We shouldn't need to instantiate less here, but for some reason,\n    //dmd can't handle it if we don't (even though the template which\n    //takes less but not allowDuplicates works just fine).\n    return new RedBlackTree!(ElementType!Stuff, binaryFun!less, allowDuplicates)(range);\n}\n\n///\n@safe pure unittest\n{\n    import std.range : iota;\n\n    auto rbt1 = redBlackTree(0, 1, 5, 7);\n    auto rbt2 = redBlackTree!string(\"hello\", \"world\");\n    auto rbt3 = redBlackTree!true(0, 1, 5, 7, 5);\n    auto rbt4 = redBlackTree!\"a > b\"(0, 1, 5, 7);\n    auto rbt5 = redBlackTree!(\"a > b\", true)(0.1, 1.3, 5.9, 7.2, 5.9);\n\n    // also works with ranges\n    auto rbt6 = redBlackTree(iota(3));\n    auto rbt7 = redBlackTree!true(iota(3));\n    auto rbt8 = redBlackTree!\"a > b\"(iota(3));\n    auto rbt9 = redBlackTree!(\"a > b\", true)(iota(3));\n}\n\n//Combinations not in examples.\n@safe pure unittest\n{\n    auto rbt1 = redBlackTree!(true, string)(\"hello\", \"hello\");\n    auto rbt2 = redBlackTree!((a, b){return a < b;}, double)(5.1, 2.3);\n    auto rbt3 = redBlackTree!(\"a > b\", true, string)(\"hello\", \"world\");\n}\n\n//Range construction.\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota;\n    auto rbt = new RedBlackTree!(int, \"a > b\")(iota(5));\n    assert(equal(rbt[], [4, 3, 2, 1, 0]));\n}\n\n\n// construction with arrays\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto rbt = redBlackTree!\"a > b\"([0, 1, 2, 3, 4]);\n    assert(equal(rbt[], [4, 3, 2, 1, 0]));\n\n    auto rbt2 = redBlackTree!\"a > b\"([\"a\", \"b\"]);\n    assert(equal(rbt2[], [\"b\", \"a\"]));\n\n    auto rbt3 = redBlackTree!\"a > b\"([1, 2]);\n    assert(equal(rbt3[], [2, 1]));\n\n    auto rbt4 = redBlackTree([0, 1, 7, 5]);\n    assert(equal(rbt4[], [0, 1, 5, 7]));\n\n    auto rbt5 = redBlackTree([\"hello\", \"world\"]);\n    assert(equal(rbt5[], [\"hello\", \"world\"]));\n\n    auto rbt6 = redBlackTree!true([0, 1, 5, 7, 5]);\n    assert(equal(rbt6[], [0, 1, 5, 5, 7]));\n\n    auto rbt7 = redBlackTree!\"a > b\"([0, 1, 5, 7]);\n    assert(equal(rbt7[], [7, 5, 1, 0]));\n\n    auto rbt8 = redBlackTree!(\"a > b\", true)([0.1, 1.3, 5.9, 7.2, 5.9]);\n    assert(equal(rbt8[], [7.2, 5.9, 5.9, 1.3, 0.1]));\n}\n\n// convenience wrapper range construction\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : chain, iota;\n\n    auto rbt = redBlackTree(iota(3));\n    assert(equal(rbt[], [0, 1, 2]));\n\n    auto rbt2 = redBlackTree!\"a > b\"(iota(2));\n    assert(equal(rbt2[], [1, 0]));\n\n    auto rbt3 = redBlackTree(chain([0, 1], [7, 5]));\n    assert(equal(rbt3[], [0, 1, 5, 7]));\n\n    auto rbt4 = redBlackTree(chain([\"hello\"], [\"world\"]));\n    assert(equal(rbt4[], [\"hello\", \"world\"]));\n\n    auto rbt5 = redBlackTree!true(chain([0, 1], [5, 7, 5]));\n    assert(equal(rbt5[], [0, 1, 5, 5, 7]));\n\n    auto rbt6 = redBlackTree!(\"a > b\", true)(chain([0.1, 1.3], [5.9, 7.2, 5.9]));\n    assert(equal(rbt6[], [7.2, 5.9, 5.9, 1.3, 0.1]));\n}\n\n@safe pure unittest\n{\n    import std.array : array;\n\n    auto rt1 = redBlackTree(5, 4, 3, 2, 1);\n    assert(rt1.length == 5);\n    assert(array(rt1[]) == [1, 2, 3, 4, 5]);\n\n    auto rt2 = redBlackTree!\"a > b\"(1.1, 2.1);\n    assert(rt2.length == 2);\n    assert(array(rt2[]) == [2.1, 1.1]);\n\n    auto rt3 = redBlackTree!true(5, 5, 4);\n    assert(rt3.length == 3);\n    assert(array(rt3[]) == [4, 5, 5]);\n\n    auto rt4 = redBlackTree!string(\"hello\", \"hello\");\n    assert(rt4.length == 1);\n    assert(array(rt4[]) == [\"hello\"]);\n}\n\n@system unittest\n{\n    import std.conv : to;\n\n    auto rt1 = redBlackTree!string();\n    assert(rt1.to!string == \"RedBlackTree([])\");\n\n    auto rt2 = redBlackTree!string(\"hello\");\n    assert(rt2.to!string == \"RedBlackTree([\\\"hello\\\"])\");\n\n    auto rt3 = redBlackTree!string(\"hello\", \"world\", \"!\");\n    assert(rt3.to!string == \"RedBlackTree([\\\"!\\\", \\\"hello\\\", \\\"world\\\"])\");\n\n    // type deduction can be done automatically\n    auto rt4 = redBlackTree([\"hello\"]);\n    assert(rt4.to!string == \"RedBlackTree([\\\"hello\\\"])\");\n}\n\n//constness checks\n@safe pure unittest\n{\n    const rt1 = redBlackTree(5,4,3,2,1);\n    static assert(is(typeof(rt1.length)));\n    static assert(is(typeof(5 in rt1)));\n\n    static assert(is(typeof(rt1.upperBound(3).front) == const(int)));\n    import std.algorithm.comparison : equal;\n    assert(rt1.upperBound(3).equal([4, 5]));\n    assert(rt1.lowerBound(3).equal([1, 2]));\n    assert(rt1.equalRange(3).equal([3]));\n    assert(rt1[].equal([1, 2, 3, 4, 5]));\n}\n\n//immutable checks\n@safe pure unittest\n{\n    immutable rt1 = redBlackTree(5,4,3,2,1);\n    static assert(is(typeof(rt1.length)));\n\n    static assert(is(typeof(rt1.upperBound(3).front) == immutable(int)));\n    import std.algorithm.comparison : equal;\n    assert(rt1.upperBound(2).equal([3, 4, 5]));\n}\n\n// issue 15941\n@safe pure unittest\n{\n    class C {}\n    RedBlackTree!(C, \"cast(void*)a < cast(void*) b\") tree;\n}\n\n@safe pure unittest // const/immutable elements (issue 17519)\n{\n    RedBlackTree!(immutable int) t1;\n    RedBlackTree!(const int) t2;\n\n    import std.algorithm.iteration : map;\n    static struct S { int* p; }\n    auto t3 = new RedBlackTree!(immutable S, (a, b) => *a.p < *b.p);\n    t3.insert([1, 2, 3].map!(x => immutable S(new int(x))));\n    static assert(!__traits(compiles, *t3.front.p = 4));\n    assert(*t3.front.p == 1);\n}\n\n// make sure the comparator can be a delegate\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto t = new RedBlackTree!(int, delegate(a, b) => a > b);\n    t.insert([1, 3, 5, 4, 2]);\n    assert(t[].equal([5, 4, 3, 2, 1]));\n}\n"
  },
  {
    "path": "libphobos/src/std/container/slist.d",
    "content": "/**\nThis module implements a singly-linked list container.\nIt can be used as a stack.\n\nThis module is a submodule of $(MREF std, container).\n\nSource: $(PHOBOSSRC std/container/slist.d)\n\nCopyright: 2010- Andrei Alexandrescu. All rights reserved by the respective holders.\n\nLicense: Distributed under the Boost Software License, Version 1.0.\n(See accompanying file LICENSE_1_0.txt or copy at $(HTTP\nboost.org/LICENSE_1_0.txt)).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n\n$(SCRIPT inhibitQuickIndex = 1;)\n*/\nmodule std.container.slist;\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container : SList;\n\n    auto s = SList!int(1, 2, 3);\n    assert(equal(s[], [1, 2, 3]));\n\n    s.removeFront();\n    assert(equal(s[], [2, 3]));\n\n    s.insertFront([5, 6]);\n    assert(equal(s[], [5, 6, 2, 3]));\n\n    // If you want to apply range operations, simply slice it.\n    import std.algorithm.searching : countUntil;\n    import std.range : popFrontN, walkLength;\n\n    auto sl = SList!int(1, 2, 3, 4, 5);\n    assert(countUntil(sl[], 2) == 1);\n\n    auto r = sl[];\n    popFrontN(r, 2);\n    assert(walkLength(r) == 3);\n}\n\npublic import std.container.util;\n\n/**\n   Implements a simple and fast singly-linked list.\n   It can be used as a stack.\n\n   `SList` uses reference semantics.\n */\nstruct SList(T)\nif (!is(T == shared))\n{\n    import std.exception : enforce;\n    import std.range : Take;\n    import std.range.primitives : isInputRange, isForwardRange, ElementType;\n    import std.traits : isImplicitlyConvertible;\n\n    private struct Node\n    {\n        Node * _next;\n        T _payload;\n    }\n    private struct NodeWithoutPayload\n    {\n        Node* _next;\n    }\n    static assert(NodeWithoutPayload._next.offsetof == Node._next.offsetof);\n\n    private Node * _root;\n\n    private void initialize() @trusted nothrow pure\n    {\n        if (_root) return;\n        _root = cast (Node*) new NodeWithoutPayload();\n    }\n\n    private ref inout(Node*) _first() @property @safe nothrow pure inout\n    {\n        assert(_root);\n        return _root._next;\n    }\n\n    private static Node * findLastNode(Node * n)\n    {\n        assert(n);\n        auto ahead = n._next;\n        while (ahead)\n        {\n            n = ahead;\n            ahead = n._next;\n        }\n        return n;\n    }\n\n    private static Node * findLastNode(Node * n, size_t limit)\n    {\n        assert(n && limit);\n        auto ahead = n._next;\n        while (ahead)\n        {\n            if (!--limit) break;\n            n = ahead;\n            ahead = n._next;\n        }\n        return n;\n    }\n\n    private static Node * findNode(Node * n, Node * findMe)\n    {\n        assert(n);\n        auto ahead = n._next;\n        while (ahead != findMe)\n        {\n            n = ahead;\n            enforce(n);\n            ahead = n._next;\n        }\n        return n;\n    }\n\n    private static Node* findNodeByValue(Node* n, T value)\n    {\n        if (!n) return null;\n        auto ahead = n._next;\n        while (ahead && ahead._payload != value)\n        {\n            n = ahead;\n            ahead = n._next;\n        }\n        return n;\n    }\n\n    private static auto createNodeChain(Stuff)(Stuff stuff)\n    if (isImplicitlyConvertible!(Stuff, T))\n    {\n        import std.range : only;\n        return createNodeChain(only(stuff));\n    }\n\n    private static auto createNodeChain(Stuff)(Stuff stuff)\n    if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, T))\n    {\n        static struct Chain\n        {\n            Node* first;\n            Node* last;\n            size_t length;\n        }\n\n        Chain ch;\n\n        foreach (item; stuff)\n        {\n            auto newNode = new Node(null, item);\n            (ch.first ? ch.last._next : ch.first) = newNode;\n            ch.last = newNode;\n            ++ch.length;\n        }\n\n        return ch;\n    }\n\n    private static size_t insertAfterNode(Stuff)(Node* n, Stuff stuff)\n    {\n        auto ch = createNodeChain(stuff);\n\n        if (!ch.length) return 0;\n\n        ch.last._next = n._next;\n        n._next = ch.first;\n\n        return ch.length;\n    }\n\n/**\nConstructor taking a number of nodes\n     */\n    this(U)(U[] values...) if (isImplicitlyConvertible!(U, T))\n    {\n        insertFront(values);\n    }\n\n/**\nConstructor taking an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     */\n    this(Stuff)(Stuff stuff)\n    if (isInputRange!Stuff\n            && isImplicitlyConvertible!(ElementType!Stuff, T)\n            && !is(Stuff == T[]))\n    {\n        insertFront(stuff);\n    }\n\n/**\nComparison for equality.\n\nComplexity: $(BIGOH min(n, n1)) where `n1` is the number of\nelements in `rhs`.\n     */\n    bool opEquals(const SList rhs) const\n    {\n        return opEquals(rhs);\n    }\n\n    /// ditto\n    bool opEquals(ref const SList rhs) const\n    {\n        if (_root is rhs._root) return true;\n        if (_root is null) return rhs._root is null || rhs._first is null;\n        if (rhs._root is null) return _root is null || _first is null;\n\n        const(Node) * n1 = _first, n2 = rhs._first;\n\n        for (;; n1 = n1._next, n2 = n2._next)\n        {\n            if (!n1) return !n2;\n            if (!n2 || n1._payload != n2._payload) return false;\n        }\n    }\n\n/**\nDefines the container's primary range, which embodies a forward range.\n     */\n    struct Range\n    {\n        private Node * _head;\n        private this(Node * p) { _head = p; }\n\n        /// Input range primitives.\n        @property bool empty() const { return !_head; }\n\n        /// ditto\n        @property ref T front()\n        {\n            assert(!empty, \"SList.Range.front: Range is empty\");\n            return _head._payload;\n        }\n\n        /// ditto\n        void popFront()\n        {\n            assert(!empty, \"SList.Range.popFront: Range is empty\");\n            _head = _head._next;\n        }\n\n        /// Forward range primitive.\n        @property Range save() { return this; }\n\n        T moveFront()\n        {\n            import std.algorithm.mutation : move;\n\n            assert(!empty, \"SList.Range.moveFront: Range is empty\");\n            return move(_head._payload);\n        }\n\n        bool sameHead(Range rhs)\n        {\n            return _head && _head == rhs._head;\n        }\n    }\n\n    @safe unittest\n    {\n        static assert(isForwardRange!Range);\n    }\n\n/**\nProperty returning `true` if and only if the container has no\nelements.\n\nComplexity: $(BIGOH 1)\n     */\n    @property bool empty() const\n    {\n        return _root is null || _first is null;\n    }\n\n/**\nDuplicates the container. The elements themselves are not transitively\nduplicated.\n\nComplexity: $(BIGOH n).\n     */\n    @property SList dup()\n    {\n        return SList(this[]);\n    }\n\n/**\nReturns a range that iterates over all elements of the container, in\nforward order.\n\nComplexity: $(BIGOH 1)\n     */\n    Range opSlice()\n    {\n        if (empty)\n            return Range(null);\n        else\n            return Range(_first);\n    }\n\n/**\nForward to `opSlice().front`.\n\nComplexity: $(BIGOH 1)\n     */\n    @property ref T front()\n    {\n        assert(!empty, \"SList.front: List is empty\");\n        return _first._payload;\n    }\n\n    @safe unittest\n    {\n        auto s = SList!int(1, 2, 3);\n        s.front = 42;\n        assert(s == SList!int(42, 2, 3));\n    }\n\n/**\nReturns a new `SList` that's the concatenation of `this` and its\nargument. `opBinaryRight` is only defined if `Stuff` does not\ndefine `opBinary`.\n     */\n    SList opBinary(string op, Stuff)(Stuff rhs)\n    if (op == \"~\" && is(typeof(SList(rhs))))\n    {\n        import std.range : chain, only;\n\n        static if (isInputRange!Stuff)\n            alias r = rhs;\n        else\n            auto r = only(rhs);\n\n        return SList(this[].chain(r));\n    }\n\n    /// ditto\n    SList opBinaryRight(string op, Stuff)(Stuff lhs)\n    if (op == \"~\" && !is(typeof(lhs.opBinary!\"~\"(this))) && is(typeof(SList(lhs))))\n    {\n        import std.range : chain, only;\n\n        static if (isInputRange!Stuff)\n            alias r = lhs;\n        else\n            auto r = only(lhs);\n\n        return SList(r.chain(this[]));\n    }\n\n/**\nRemoves all contents from the `SList`.\n\nPostcondition: `empty`\n\nComplexity: $(BIGOH 1)\n     */\n    void clear()\n    {\n        if (_root)\n            _first = null;\n    }\n\n/**\nReverses SList in-place. Performs no memory allocation.\n\nComplexity: $(BIGOH n)\n     */\n    void reverse()\n    {\n        if (!empty)\n        {\n            Node* prev;\n            while (_first)\n            {\n                auto next = _first._next;\n                _first._next = prev;\n                prev = _first;\n                _first = next;\n            }\n            _first = prev;\n        }\n    }\n\n/**\nInserts `stuff` to the front of the container. `stuff` can be a\nvalue convertible to `T` or a range of objects convertible to $(D\nT). The stable version behaves the same, but guarantees that ranges\niterating over the container are never invalidated.\n\nReturns: The number of elements inserted\n\nComplexity: $(BIGOH m), where `m` is the length of `stuff`\n     */\n    size_t insertFront(Stuff)(Stuff stuff)\n    if (isInputRange!Stuff || isImplicitlyConvertible!(Stuff, T))\n    {\n        initialize();\n        return insertAfterNode(_root, stuff);\n    }\n\n    /// ditto\n    alias insert = insertFront;\n\n    /// ditto\n    alias stableInsert = insert;\n\n    /// ditto\n    alias stableInsertFront = insertFront;\n\n/**\nPicks one value in an unspecified position in the container, removes\nit from the container, and returns it. The stable version behaves the same,\nbut guarantees that ranges iterating over the container are never invalidated.\n\nPrecondition: `!empty`\n\nReturns: The element removed.\n\nComplexity: $(BIGOH 1).\n     */\n    T removeAny()\n    {\n        import std.algorithm.mutation : move;\n\n        assert(!empty, \"SList.removeAny: List is empty\");\n        auto result = move(_first._payload);\n        _first = _first._next;\n        return result;\n    }\n    /// ditto\n    alias stableRemoveAny = removeAny;\n\n/**\nRemoves the value at the front of the container. The stable version\nbehaves the same, but guarantees that ranges iterating over the\ncontainer are never invalidated.\n\nPrecondition: `!empty`\n\nComplexity: $(BIGOH 1).\n     */\n    void removeFront()\n    {\n        assert(!empty, \"SList.removeFront: List is empty\");\n        _first = _first._next;\n    }\n\n    /// ditto\n    alias stableRemoveFront = removeFront;\n\n/**\nRemoves `howMany` values at the front or back of the\ncontainer. Unlike the unparameterized versions above, these functions\ndo not throw if they could not remove `howMany` elements. Instead,\nif $(D howMany > n), all elements are removed. The returned value is\nthe effective number of elements removed. The stable version behaves\nthe same, but guarantees that ranges iterating over the container are\nnever invalidated.\n\nReturns: The number of elements removed\n\nComplexity: $(BIGOH howMany * log(n)).\n     */\n    size_t removeFront(size_t howMany)\n    {\n        size_t result;\n        while (_first && result < howMany)\n        {\n            _first = _first._next;\n            ++result;\n        }\n        return result;\n    }\n\n    /// ditto\n    alias stableRemoveFront = removeFront;\n\n/**\nInserts `stuff` after range `r`, which must be a range\npreviously extracted from this container. Given that all ranges for a\nlist end at the end of the list, this function essentially appends to\nthe list and uses `r` as a potentially fast way to reach the last\nnode in the list. Ideally `r` is positioned near or at the last\nelement of the list.\n\n`stuff` can be a value convertible to `T` or a range of objects\nconvertible to `T`. The stable version behaves the same, but\nguarantees that ranges iterating over the container are never\ninvalidated.\n\nReturns: The number of values inserted.\n\nComplexity: $(BIGOH k + m), where `k` is the number of elements in\n`r` and `m` is the length of `stuff`.\n\nExample:\n--------------------\nauto sl = SList!string([\"a\", \"b\", \"d\"]);\nsl.insertAfter(sl[], \"e\"); // insert at the end (slowest)\nassert(std.algorithm.equal(sl[], [\"a\", \"b\", \"d\", \"e\"]));\nsl.insertAfter(std.range.take(sl[], 2), \"c\"); // insert after \"b\"\nassert(std.algorithm.equal(sl[], [\"a\", \"b\", \"c\", \"d\", \"e\"]));\n--------------------\n     */\n\n    size_t insertAfter(Stuff)(Range r, Stuff stuff)\n    if (isInputRange!Stuff || isImplicitlyConvertible!(Stuff, T))\n    {\n        initialize();\n        if (!_first)\n        {\n            enforce(!r._head);\n            return insertFront(stuff);\n        }\n        enforce(r._head);\n        auto n = findLastNode(r._head);\n        return insertAfterNode(n, stuff);\n    }\n\n/**\nSimilar to `insertAfter` above, but accepts a range bounded in\ncount. This is important for ensuring fast insertions in the middle of\nthe list.  For fast insertions after a specified position `r`, use\n$(D insertAfter(take(r, 1), stuff)). The complexity of that operation\nonly depends on the number of elements in `stuff`.\n\nPrecondition: $(D r.original.empty || r.maxLength > 0)\n\nReturns: The number of values inserted.\n\nComplexity: $(BIGOH k + m), where `k` is the number of elements in\n`r` and `m` is the length of `stuff`.\n     */\n    size_t insertAfter(Stuff)(Take!Range r, Stuff stuff)\n    if (isInputRange!Stuff || isImplicitlyConvertible!(Stuff, T))\n    {\n        auto orig = r.source;\n        if (!orig._head)\n        {\n            // Inserting after a null range counts as insertion to the\n            // front\n            return insertFront(stuff);\n        }\n        enforce(!r.empty);\n        // Find the last valid element in the range\n        foreach (i; 1 .. r.maxLength)\n        {\n            if (!orig._head._next) break;\n            orig.popFront();\n        }\n        // insert here\n        return insertAfterNode(orig._head, stuff);\n    }\n\n/// ditto\n    alias stableInsertAfter = insertAfter;\n\n/**\nRemoves a range from the list in linear time.\n\nReturns: An empty range.\n\nComplexity: $(BIGOH n)\n     */\n    Range linearRemove(Range r)\n    {\n        if (!_first)\n        {\n            enforce(!r._head);\n            return this[];\n        }\n        auto n = findNode(_root, r._head);\n        n._next = null;\n        return Range(null);\n    }\n\n/**\nRemoves a `Take!Range` from the list in linear time.\n\nReturns: A range comprehending the elements after the removed range.\n\nComplexity: $(BIGOH n)\n     */\n    Range linearRemove(Take!Range r)\n    {\n        auto orig = r.source;\n        // We have something to remove here\n        if (orig._head == _first)\n        {\n            // remove straight from the head of the list\n            for (; !r.empty; r.popFront())\n            {\n                removeFront();\n            }\n            return this[];\n        }\n        if (!r.maxLength)\n        {\n            // Nothing to remove, return the range itself\n            return orig;\n        }\n        // Remove from somewhere in the middle of the list\n        enforce(_first);\n        auto n1 = findNode(_root, orig._head);\n        auto n2 = findLastNode(orig._head, r.maxLength);\n        n1._next = n2._next;\n        return Range(n1._next);\n    }\n\n/// ditto\n    alias stableLinearRemove = linearRemove;\n\n/**\nRemoves the first occurence of an element from the list in linear time.\n\nReturns: True if the element existed and was successfully removed, false otherwise.\n\nParams:\n    value = value of the node to be removed\n\nComplexity: $(BIGOH n)\n     */\n    bool linearRemoveElement(T value)\n    {\n        auto n1 = findNodeByValue(_root, value);\n\n        if (n1 && n1._next)\n        {\n            n1._next = n1._next._next;\n            return true;\n        }\n\n        return false;\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto e = SList!int();\n    auto b = e.linearRemoveElement(2);\n    assert(b == false);\n    assert(e.empty());\n    auto a = SList!int(-1, 1, 2, 1, 3, 4);\n    b = a.linearRemoveElement(1);\n    assert(equal(a[], [-1, 2, 1, 3, 4]));\n    assert(b == true);\n    b = a.linearRemoveElement(-1);\n    assert(b == true);\n    assert(equal(a[], [2, 1, 3, 4]));\n    b = a.linearRemoveElement(1);\n    assert(b == true);\n    assert(equal(a[], [2, 3, 4]));\n    b = a.linearRemoveElement(2);\n    assert(b == true);\n    b = a.linearRemoveElement(20);\n    assert(b == false);\n    assert(equal(a[], [3, 4]));\n    b = a.linearRemoveElement(4);\n    assert(b == true);\n    assert(equal(a[], [3]));\n    b = a.linearRemoveElement(3);\n    assert(b == true);\n    assert(a.empty());\n    a.linearRemoveElement(3);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto a = SList!int(5);\n    auto b = a;\n    auto r = a[];\n    a.insertFront(1);\n    b.insertFront(2);\n    assert(equal(a[], [2, 1, 5]));\n    assert(equal(b[], [2, 1, 5]));\n    r.front = 9;\n    assert(equal(a[], [2, 1, 9]));\n    assert(equal(b[], [2, 1, 9]));\n}\n\n@safe unittest\n{\n    auto s = SList!int(1, 2, 3);\n    auto n = s.findLastNode(s._root);\n    assert(n && n._payload == 3);\n}\n\n@safe unittest\n{\n    import std.range.primitives;\n    auto s = SList!int(1, 2, 5, 10);\n    assert(walkLength(s[]) == 4);\n}\n\n@safe unittest\n{\n    import std.range : take;\n    auto src = take([0, 1, 2, 3], 3);\n    auto s = SList!int(src);\n    assert(s == SList!int(0, 1, 2));\n}\n\n@safe unittest\n{\n    auto a = SList!int();\n    auto b = SList!int();\n    auto c = a ~ b[];\n    assert(c.empty);\n}\n\n@safe unittest\n{\n    auto a = SList!int(1, 2, 3);\n    auto b = SList!int(4, 5, 6);\n    auto c = a ~ b[];\n    assert(c == SList!int(1, 2, 3, 4, 5, 6));\n}\n\n@safe unittest\n{\n    auto a = SList!int(1, 2, 3);\n    auto b = [4, 5, 6];\n    auto c = a ~ b;\n    assert(c == SList!int(1, 2, 3, 4, 5, 6));\n}\n\n@safe unittest\n{\n    auto a = SList!int(1, 2, 3);\n    auto c = a ~ 4;\n    assert(c == SList!int(1, 2, 3, 4));\n}\n\n@safe unittest\n{\n    auto a = SList!int(2, 3, 4);\n    auto b = 1 ~ a;\n    assert(b == SList!int(1, 2, 3, 4));\n}\n\n@safe unittest\n{\n    auto a = [1, 2, 3];\n    auto b = SList!int(4, 5, 6);\n    auto c = a ~ b;\n    assert(c == SList!int(1, 2, 3, 4, 5, 6));\n}\n\n@safe unittest\n{\n    auto s = SList!int(1, 2, 3, 4);\n    s.insertFront([ 42, 43 ]);\n    assert(s == SList!int(42, 43, 1, 2, 3, 4));\n}\n\n@safe unittest\n{\n    auto s = SList!int(1, 2, 3);\n    assert(s.removeAny() == 1);\n    assert(s == SList!int(2, 3));\n    assert(s.stableRemoveAny() == 2);\n    assert(s == SList!int(3));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto s = SList!int(1, 2, 3);\n    s.removeFront();\n    assert(equal(s[], [2, 3]));\n    s.stableRemoveFront();\n    assert(equal(s[], [3]));\n}\n\n@safe unittest\n{\n    auto s = SList!int(1, 2, 3, 4, 5, 6, 7);\n    assert(s.removeFront(3) == 3);\n    assert(s == SList!int(4, 5, 6, 7));\n}\n\n@safe unittest\n{\n    auto a = SList!int(1, 2, 3);\n    auto b = SList!int(1, 2, 3);\n    assert(a.insertAfter(a[], b[]) == 3);\n}\n\n@safe unittest\n{\n    import std.range : take;\n    auto s = SList!int(1, 2, 3, 4);\n    auto r = take(s[], 2);\n    assert(s.insertAfter(r, 5) == 1);\n    assert(s == SList!int(1, 2, 5, 3, 4));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : take;\n\n    // insertAfter documentation example\n    auto sl = SList!string([\"a\", \"b\", \"d\"]);\n    sl.insertAfter(sl[], \"e\"); // insert at the end (slowest)\n    assert(equal(sl[], [\"a\", \"b\", \"d\", \"e\"]));\n    sl.insertAfter(take(sl[], 2), \"c\"); // insert after \"b\"\n    assert(equal(sl[], [\"a\", \"b\", \"c\", \"d\", \"e\"]));\n}\n\n@safe unittest\n{\n    import std.range.primitives;\n    auto s = SList!int(1, 2, 3, 4, 5);\n    auto r = s[];\n    popFrontN(r, 3);\n    auto r1 = s.linearRemove(r);\n    assert(s == SList!int(1, 2, 3));\n    assert(r1.empty);\n}\n\n@safe unittest\n{\n    auto s = SList!int(1, 2, 3, 4, 5);\n    auto r = s[];\n    auto r1 = s.linearRemove(r);\n    assert(s == SList!int());\n    assert(r1.empty);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range;\n\n    auto s = SList!int(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n    auto r = s[];\n    popFrontN(r, 3);\n    auto r1 = take(r, 4);\n    assert(equal(r1, [4, 5, 6, 7]));\n    auto r2 = s.linearRemove(r1);\n    assert(s == SList!int(1, 2, 3, 8, 9, 10));\n    assert(equal(r2, [8, 9, 10]));\n}\n\n@safe unittest\n{\n    import std.range.primitives;\n    auto lst = SList!int(1, 5, 42, 9);\n    assert(!lst.empty);\n    assert(lst.front == 1);\n    assert(walkLength(lst[]) == 4);\n\n    auto lst2 = lst ~ [ 1, 2, 3 ];\n    assert(walkLength(lst2[]) == 7);\n\n    auto lst3 = lst ~ [ 7 ];\n    assert(walkLength(lst3[]) == 5);\n}\n\n@safe unittest\n{\n    auto s = make!(SList!int)(1, 2, 3);\n}\n\n@safe unittest\n{\n    // 5193\n    static struct Data\n    {\n        const int val;\n    }\n    SList!Data list;\n}\n\n@safe unittest\n{\n    auto s = SList!int([1, 2, 3]);\n    s.front = 5; //test frontAssign\n    assert(s.front == 5);\n    auto r = s[];\n    r.front = 1; //test frontAssign\n    assert(r.front == 1);\n}\n\n@safe unittest\n{\n    // issue 14920\n    SList!int s;\n    s.insertAfter(s[], 1);\n    assert(s.front == 1);\n}\n\n@safe unittest\n{\n    // issue 15659\n    SList!int s;\n    s.clear();\n}\n\n@safe unittest\n{\n    SList!int s;\n    s.reverse();\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto s = SList!int([1, 2, 3]);\n    assert(s[].equal([1, 2, 3]));\n\n    s.reverse();\n    assert(s[].equal([3, 2, 1]));\n}\n\n@safe unittest\n{\n    auto s = SList!int([4, 6, 8, 12, 16]);\n    auto d = s.dup;\n    assert(d !is s);\n    assert(d == s);\n}\n"
  },
  {
    "path": "libphobos/src/std/container/util.d",
    "content": "/**\nThis module contains some common utilities used by containers.\n\nThis module is a submodule of $(MREF std, container).\n\nSource: $(PHOBOSSRC std/container/util.d)\n\nCopyright: 2010- Andrei Alexandrescu. All rights reserved by the respective holders.\n\nLicense: Distributed under the Boost Software License, Version 1.0.\n(See accompanying file LICENSE_1_0.txt or copy at $(HTTP\nboost.org/LICENSE_1_0.txt)).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n\n$(SCRIPT inhibitQuickIndex = 1;)\n*/\nmodule std.container.util;\n\n/**\nReturns an initialized object. This function is mainly for eliminating\nconstruction differences between structs and classes. It allows code to not\nworry about whether the type it's constructing is a struct or a class.\n */\ntemplate make(T)\nif (is(T == struct) || is(T == class))\n{\n    T make(Args...)(Args arguments)\n    if (is(T == struct) && __traits(compiles, T(arguments)))\n    {\n        // constructing an std.container.Array without arguments,\n        // does not initialize its payload and is equivalent\n        // to a null reference. We therefore construct an empty container\n        // by passing an empty array to its constructor.\n        // Issue #13872.\n        static if (arguments.length == 0)\n        {\n            import std.range.primitives : ElementType;\n            alias ET = ElementType!(T.Range);\n            return T(ET[].init);\n        }\n        else\n            return T(arguments);\n    }\n\n    T make(Args...)(Args arguments)\n    if (is(T == class) && __traits(compiles, new T(arguments)))\n    {\n        return new T(arguments);\n    }\n}\n\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container;\n\n    auto arr = make!(Array!int)([4, 2, 3, 1]);\n    assert(equal(arr[], [4, 2, 3, 1]));\n\n    auto rbt = make!(RedBlackTree!(int, \"a > b\"))([4, 2, 3, 1]);\n    assert(equal(rbt[], [4, 3, 2, 1]));\n\n    alias makeList = make!(SList!int);\n    auto slist = makeList(1, 2, 3);\n    assert(equal(slist[], [1, 2, 3]));\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container;\n\n    auto arr1 = make!(Array!dchar)();\n    assert(arr1.empty);\n    auto arr2 = make!(Array!dchar)(\"hello\"d);\n    assert(equal(arr2[], \"hello\"d));\n\n    auto rtb1 = make!(RedBlackTree!dchar)();\n    assert(rtb1.empty);\n    auto rtb2 = make!(RedBlackTree!dchar)('h', 'e', 'l', 'l', 'o');\n    assert(equal(rtb2[], \"ehlo\"d));\n}\n\n// Issue 8895\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container;\n\n    auto a = make!(DList!int)(1,2,3,4);\n    auto b = make!(DList!int)(1,2,3,4);\n    auto c = make!(DList!int)(1,2,3,5);\n    auto d = make!(DList!int)(1,2,3,4,5);\n    assert(a == b); // this better terminate!\n    assert(a != c);\n    assert(a != d);\n}\n\n/**\n * Convenience function for constructing a generic container.\n */\ntemplate make(alias Container, Args...)\nif (!is(Container))\n{\n    import std.range : isInputRange, isInfinite;\n    import std.traits : isDynamicArray;\n\n    auto make(Range)(Range range)\n        if (!isDynamicArray!Range && isInputRange!Range && !isInfinite!Range)\n    {\n        import std.range : ElementType;\n        return .make!(Container!(ElementType!Range, Args))(range);\n    }\n\n    auto make(T)(T[] items...)\n        if (!isInfinite!T)\n    {\n        return .make!(Container!(T, Args))(items);\n    }\n}\n\n/// forbid construction from infinite range\n@safe unittest\n{\n    import std.container.array : Array;\n    import std.range : only, repeat;\n    import std.range.primitives : isInfinite;\n    static assert(__traits(compiles, { auto arr = make!Array(only(5)); }));\n    static assert(!__traits(compiles, { auto arr = make!Array(repeat(5)); }));\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container.array, std.container.rbtree, std.container.slist;\n    import std.range : iota;\n\n    auto arr = make!Array(iota(5));\n    assert(equal(arr[], [0, 1, 2, 3, 4]));\n\n    auto rbtmax = make!(RedBlackTree, \"a > b\")(iota(5));\n    assert(equal(rbtmax[], [4, 3, 2, 1, 0]));\n\n    auto rbtmin = make!RedBlackTree(4, 1, 3, 2);\n    assert(equal(rbtmin[], [1, 2, 3, 4]));\n\n    alias makeList = make!SList;\n    auto list = makeList(1, 7, 42);\n    assert(equal(list[], [1, 7, 42]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container.rbtree;\n\n    auto rbtmin = make!(RedBlackTree, \"a < b\", false)(3, 2, 2, 1);\n    assert(equal(rbtmin[], [1, 2, 3]));\n}\n\n// Issue 13872\n@system unittest\n{\n    import std.container;\n\n    auto tree1 = make!(RedBlackTree!int)();\n    auto refToTree1 = tree1;\n    refToTree1.insert(1);\n    assert(1 in tree1);\n\n    auto array1 = make!(Array!int)();\n    auto refToArray1 = array1;\n    refToArray1.insertBack(1);\n    assert(!array1.empty);\n\n    auto slist = make!(SList!int)();\n    auto refToSlist = slist;\n    refToSlist.insert(1);\n    assert(!slist.empty);\n\n    auto dlist = make!(DList!int)();\n    auto refToDList = dlist;\n    refToDList.insert(1);\n    assert(!dlist.empty);\n}\n"
  },
  {
    "path": "libphobos/src/std/conv.d",
    "content": "// Written in the D programming language.\n\n/**\nA one-stop shop for converting values from one type to another.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Generic) $(TD\n        $(LREF asOriginalType)\n        $(LREF castFrom)\n        $(LREF emplace)\n        $(LREF parse)\n        $(LREF to)\n        $(LREF toChars)\n))\n$(TR $(TD Strings) $(TD\n        $(LREF text)\n        $(LREF wtext)\n        $(LREF dtext)\n        $(LREF hexString)\n))\n$(TR $(TD Numeric) $(TD\n        $(LREF octal)\n        $(LREF roundTo)\n        $(LREF signed)\n        $(LREF unsigned)\n))\n$(TR $(TD Exceptions) $(TD\n        $(LREF ConvException)\n        $(LREF ConvOverflowException)\n))\n)\n\nCopyright: Copyright The D Language Foundation 2007-.\n\nLicense:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors:   $(HTTP digitalmars.com, Walter Bright),\n           $(HTTP erdani.org, Andrei Alexandrescu),\n           Shin Fujishiro,\n           Adam D. Ruppe,\n           Kenji Hara\n\nSource:    $(PHOBOSSRC std/conv.d)\n\n*/\nmodule std.conv;\n\npublic import std.ascii : LetterCase;\n\nimport std.meta;\nimport std.range.primitives;\nimport std.traits;\n\n// Same as std.string.format, but \"self-importing\".\n// Helps reduce code and imports, particularly in static asserts.\n// Also helps with missing imports errors.\npackage template convFormat()\n{\n    import std.format : format;\n    alias convFormat = format;\n}\n\n/* ************* Exceptions *************** */\n\n/**\n * Thrown on conversion errors.\n */\nclass ConvException : Exception\n{\n    import std.exception : basicExceptionCtors;\n    ///\n    mixin basicExceptionCtors;\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    assertThrown!ConvException(to!int(\"abc\"));\n}\n\nprivate auto convError(S, T)(S source, string fn = __FILE__, size_t ln = __LINE__)\n{\n    string msg;\n\n    if (source.empty)\n        msg = \"Unexpected end of input when converting from type \" ~ S.stringof ~ \" to type \" ~ T.stringof;\n    else\n    {\n        ElementType!S el = source.front;\n\n        if (el == '\\n')\n            msg = text(\"Unexpected '\\\\n' when converting from type \" ~ S.stringof ~ \" to type \" ~ T.stringof);\n        else\n            msg =  text(\"Unexpected '\", el,\n                 \"' when converting from type \" ~ S.stringof ~ \" to type \" ~ T.stringof);\n    }\n\n    return new ConvException(msg, fn, ln);\n}\n\nprivate auto convError(S, T)(S source, int radix, string fn = __FILE__, size_t ln = __LINE__)\n{\n    string msg;\n\n    if (source.empty)\n        msg = text(\"Unexpected end of input when converting from type \" ~ S.stringof ~ \" base \", radix,\n                \" to type \" ~ T.stringof);\n    else\n        msg = text(\"Unexpected '\", source.front,\n            \"' when converting from type \" ~ S.stringof ~ \" base \", radix,\n            \" to type \" ~ T.stringof);\n\n    return new ConvException(msg, fn, ln);\n}\n\n@safe pure/* nothrow*/  // lazy parameter bug\nprivate auto parseError(lazy string msg, string fn = __FILE__, size_t ln = __LINE__)\n{\n    return new ConvException(text(\"Can't parse string: \", msg), fn, ln);\n}\n\nprivate void parseCheck(alias source)(dchar c, string fn = __FILE__, size_t ln = __LINE__)\n{\n    if (source.empty)\n        throw parseError(text(\"unexpected end of input when expecting\", \"\\\"\", c, \"\\\"\"));\n    if (source.front != c)\n        throw parseError(text(\"\\\"\", c, \"\\\" is missing\"), fn, ln);\n    source.popFront();\n}\n\nprivate\n{\n    T toStr(T, S)(S src)\n    if (isSomeString!T)\n    {\n        // workaround for Bugzilla 14198\n        static if (is(S == bool) && is(typeof({ T s = \"string\"; })))\n        {\n            return src ? \"true\" : \"false\";\n        }\n        else\n        {\n            import std.array : appender;\n            import std.format : FormatSpec, formatValue;\n\n            auto w = appender!T();\n            FormatSpec!(ElementEncodingType!T) f;\n            formatValue(w, src, f);\n            return w.data;\n        }\n    }\n\n    template isExactSomeString(T)\n    {\n        enum isExactSomeString = isSomeString!T && !is(T == enum);\n    }\n\n    template isEnumStrToStr(S, T)\n    {\n        enum isEnumStrToStr = isImplicitlyConvertible!(S, T) &&\n                              is(S == enum) && isExactSomeString!T;\n    }\n    template isNullToStr(S, T)\n    {\n        enum isNullToStr = isImplicitlyConvertible!(S, T) &&\n                           (is(Unqual!S == typeof(null))) && isExactSomeString!T;\n    }\n}\n\n/**\n * Thrown on conversion overflow errors.\n */\nclass ConvOverflowException : ConvException\n{\n    @safe pure nothrow\n    this(string s, string fn = __FILE__, size_t ln = __LINE__)\n    {\n        super(s, fn, ln);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    assertThrown!ConvOverflowException(to!ubyte(1_000_000));\n}\n\n/**\nThe `to` template converts a value from one type _to another.\nThe source type is deduced and the target type must be specified, for example the\nexpression `to!int(42.0)` converts the number 42 from\n`double` _to `int`. The conversion is \"safe\", i.e.,\nit checks for overflow; `to!int(4.2e10)` would throw the\n`ConvOverflowException` exception. Overflow checks are only\ninserted when necessary, e.g., `to!double(42)` does not do\nany checking because any `int` fits in a `double`.\n\nConversions from string _to numeric types differ from the C equivalents\n`atoi()` and `atol()` by checking for overflow and not allowing whitespace.\n\nFor conversion of strings _to signed types, the grammar recognized is:\n$(PRE $(I Integer): $(I Sign UnsignedInteger)\n$(I UnsignedInteger)\n$(I Sign):\n    $(B +)\n    $(B -))\n\nFor conversion _to unsigned types, the grammar recognized is:\n$(PRE $(I UnsignedInteger):\n    $(I DecimalDigit)\n    $(I DecimalDigit) $(I UnsignedInteger))\n */\ntemplate to(T)\n{\n    T to(A...)(A args)\n        if (A.length > 0)\n    {\n        return toImpl!T(args);\n    }\n\n    // Fix issue 6175\n    T to(S)(ref S arg)\n        if (isStaticArray!S)\n    {\n        return toImpl!T(arg);\n    }\n\n    // Fix issue 16108\n    T to(S)(ref S arg)\n        if (isAggregateType!S && !isCopyable!S)\n    {\n        return toImpl!T(arg);\n    }\n}\n\n/**\n * Converting a value _to its own type (useful mostly for generic code)\n * simply returns its argument.\n */\n@safe pure unittest\n{\n    int a = 42;\n    int b = to!int(a);\n    double c = to!double(3.14); // c is double with value 3.14\n}\n\n/**\n * Converting among numeric types is a safe way _to cast them around.\n *\n * Conversions from floating-point types _to integral types allow loss of\n * precision (the fractional part of a floating-point number). The\n * conversion is truncating towards zero, the same way a cast would\n * truncate. (_To round a floating point value when casting _to an\n * integral, use `roundTo`.)\n */\n@safe pure unittest\n{\n    import std.exception : assertThrown;\n\n    int a = 420;\n    assert(to!long(a) == a);\n    assertThrown!ConvOverflowException(to!byte(a));\n\n    assert(to!int(4.2e6) == 4200000);\n    assertThrown!ConvOverflowException(to!uint(-3.14));\n    assert(to!uint(3.14) == 3);\n    assert(to!uint(3.99) == 3);\n    assert(to!int(-3.99) == -3);\n}\n\n/**\n * When converting strings _to numeric types, note that the D hexadecimal and binary\n * literals are not handled. Neither the prefixes that indicate the base, nor the\n * horizontal bar used _to separate groups of digits are recognized. This also\n * applies to the suffixes that indicate the type.\n *\n * _To work around this, you can specify a radix for conversions involving numbers.\n */\n@safe pure unittest\n{\n    auto str = to!string(42, 16);\n    assert(str == \"2A\");\n    auto i = to!int(str, 16);\n    assert(i == 42);\n}\n\n/**\n * Conversions from integral types _to floating-point types always\n * succeed, but might lose accuracy. The largest integers with a\n * predecessor representable in floating-point format are `2^24-1` for\n * `float`, `2^53-1` for `double`, and `2^64-1` for `real` (when\n * `real` is 80-bit, e.g. on Intel machines).\n */\n@safe pure unittest\n{\n    // 2^24 - 1, largest proper integer representable as float\n    int a = 16_777_215;\n    assert(to!int(to!float(a)) == a);\n    assert(to!int(to!float(-a)) == -a);\n}\n\n/**\n   Conversion from string types to char types enforces the input\n   to consist of a single code point, and said code point must\n   fit in the target type. Otherwise, $(LREF ConvException) is thrown.\n */\n@safe pure unittest\n{\n    import std.exception : assertThrown;\n\n    assert(to!char(\"a\") == 'a');\n    assertThrown(to!char(\"ñ\")); // 'ñ' does not fit into a char\n    assert(to!wchar(\"ñ\") == 'ñ');\n    assertThrown(to!wchar(\"😃\")); // '😃' does not fit into a wchar\n    assert(to!dchar(\"😃\") == '😃');\n\n    // Using wstring or dstring as source type does not affect the result\n    assert(to!char(\"a\"w) == 'a');\n    assert(to!char(\"a\"d) == 'a');\n\n    // Two code points cannot be converted to a single one\n    assertThrown(to!char(\"ab\"));\n}\n\n/**\n * Converting an array _to another array type works by converting each\n * element in turn. Associative arrays can be converted _to associative\n * arrays as long as keys and values can in turn be converted.\n */\n@safe pure unittest\n{\n    import std.string : split;\n\n    int[] a = [1, 2, 3];\n    auto b = to!(float[])(a);\n    assert(b == [1.0f, 2, 3]);\n    string str = \"1 2 3 4 5 6\";\n    auto numbers = to!(double[])(split(str));\n    assert(numbers == [1.0, 2, 3, 4, 5, 6]);\n    int[string] c;\n    c[\"a\"] = 1;\n    c[\"b\"] = 2;\n    auto d = to!(double[wstring])(c);\n    assert(d[\"a\"w] == 1 && d[\"b\"w] == 2);\n}\n\n/**\n * Conversions operate transitively, meaning that they work on arrays and\n * associative arrays of any complexity.\n *\n * This conversion works because `to!short` applies _to an `int`, `to!wstring`\n * applies _to a `string`, `to!string` applies _to a `double`, and\n * `to!(double[])` applies _to an `int[]`. The conversion might throw an\n * exception because `to!short` might fail the range check.\n */\n@safe unittest\n{\n    int[string][double[int[]]] a;\n    auto b = to!(short[wstring][string[double[]]])(a);\n}\n\n/**\n * Object-to-object conversions by dynamic casting throw exception when\n * the source is non-null and the target is null.\n */\n@safe pure unittest\n{\n    import std.exception : assertThrown;\n    // Testing object conversions\n    class A {}\n    class B : A {}\n    class C : A {}\n    A a1 = new A, a2 = new B, a3 = new C;\n    assert(to!B(a2) is a2);\n    assert(to!C(a3) is a3);\n    assertThrown!ConvException(to!B(a3));\n}\n\n/**\n * Stringize conversion from all types is supported.\n * $(UL\n *   $(LI String _to string conversion works for any two string types having\n *        (`char`, `wchar`, `dchar`) character widths and any\n *        combination of qualifiers (mutable, `const`, or `immutable`).)\n *   $(LI Converts array (other than strings) _to string.\n *        Each element is converted by calling `to!T`.)\n *   $(LI Associative array _to string conversion.\n *        Each element is printed by calling `to!T`.)\n *   $(LI Object _to string conversion calls `toString` against the object or\n *        returns `\"null\"` if the object is null.)\n *   $(LI Struct _to string conversion calls `toString` against the struct if\n *        it is defined.)\n *   $(LI For structs that do not define `toString`, the conversion _to string\n *        produces the list of fields.)\n *   $(LI Enumerated types are converted _to strings as their symbolic names.)\n *   $(LI Boolean values are printed as `\"true\"` or `\"false\"`.)\n *   $(LI `char`, `wchar`, `dchar` _to a string type.)\n *   $(LI Unsigned or signed integers _to strings.\n *        $(DL $(DT [special case])\n *             $(DD Convert integral value _to string in $(D_PARAM radix) radix.\n *             radix must be a value from 2 to 36.\n *             value is treated as a signed value only if radix is 10.\n *             The characters A through Z are used to represent values 10 through 36\n *             and their case is determined by the $(D_PARAM letterCase) parameter.)))\n *   $(LI All floating point types _to all string types.)\n *   $(LI Pointer to string conversions prints the pointer as a `size_t` value.\n *        If pointer is `char*`, treat it as C-style strings.\n *        In that case, this function is `@system`.))\n */\n@system pure unittest // @system due to cast and ptr\n{\n    // Conversion representing dynamic/static array with string\n    long[] a = [ 1, 3, 5 ];\n    assert(to!string(a) == \"[1, 3, 5]\");\n\n    // Conversion representing associative array with string\n    int[string] associativeArray = [\"0\":1, \"1\":2];\n    assert(to!string(associativeArray) == `[\"0\":1, \"1\":2]` ||\n           to!string(associativeArray) == `[\"1\":2, \"0\":1]`);\n\n    // char* to string conversion\n    assert(to!string(cast(char*) null) == \"\");\n    assert(to!string(\"foo\\0\".ptr) == \"foo\");\n\n    // Conversion reinterpreting void array to string\n    auto w = \"abcx\"w;\n    const(void)[] b = w;\n    assert(b.length == 8);\n\n    auto c = to!(wchar[])(b);\n    assert(c == \"abcx\");\n}\n\n// Tests for issue 6175\n@safe pure nothrow unittest\n{\n    char[9] sarr = \"blablabla\";\n    auto darr = to!(char[])(sarr);\n    assert(sarr.ptr == darr.ptr);\n    assert(sarr.length == darr.length);\n}\n\n// Tests for issue 7348\n@safe pure /+nothrow+/ unittest\n{\n    assert(to!string(null) == \"null\");\n    assert(text(null) == \"null\");\n}\n\n// Tests for issue 11390\n@safe pure /+nothrow+/ unittest\n{\n    const(typeof(null)) ctn;\n    immutable(typeof(null)) itn;\n    assert(to!string(ctn) == \"null\");\n    assert(to!string(itn) == \"null\");\n}\n\n// Tests for issue 8729: do NOT skip leading WS\n@safe pure unittest\n{\n    import std.exception;\n    static foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))\n    {\n        assertThrown!ConvException(to!T(\" 0\"));\n        assertThrown!ConvException(to!T(\" 0\", 8));\n    }\n    static foreach (T; AliasSeq!(float, double, real))\n    {\n        assertThrown!ConvException(to!T(\" 0\"));\n    }\n\n    assertThrown!ConvException(to!bool(\" true\"));\n\n    alias NullType = typeof(null);\n    assertThrown!ConvException(to!NullType(\" null\"));\n\n    alias ARR = int[];\n    assertThrown!ConvException(to!ARR(\" [1]\"));\n\n    alias AA = int[int];\n    assertThrown!ConvException(to!AA(\" [1:1]\"));\n}\n\n/**\nIf the source type is implicitly convertible to the target type, $(D\nto) simply performs the implicit conversion.\n */\nprivate T toImpl(T, S)(S value)\nif (isImplicitlyConvertible!(S, T) &&\n    !isEnumStrToStr!(S, T) && !isNullToStr!(S, T))\n{\n    template isSignedInt(T)\n    {\n        enum isSignedInt = isIntegral!T && isSigned!T;\n    }\n    alias isUnsignedInt = isUnsigned;\n\n    // Conversion from integer to integer, and changing its sign\n    static if (isUnsignedInt!S && isSignedInt!T && S.sizeof == T.sizeof)\n    {   // unsigned to signed & same size\n        import std.exception : enforce;\n        enforce(value <= cast(S) T.max,\n                new ConvOverflowException(\"Conversion positive overflow\"));\n    }\n    else static if (isSignedInt!S && isUnsignedInt!T)\n    {   // signed to unsigned\n        import std.exception : enforce;\n        enforce(0 <= value,\n                new ConvOverflowException(\"Conversion negative overflow\"));\n    }\n\n    return value;\n}\n\n@safe pure nothrow unittest\n{\n    enum E { a }  // Issue 9523 - Allow identity enum conversion\n    auto e = to!E(E.a);\n    assert(e == E.a);\n}\n\n@safe pure nothrow unittest\n{\n    int a = 42;\n    auto b = to!long(a);\n    assert(a == b);\n}\n\n// Tests for issue 6377\n@safe pure unittest\n{\n    import std.exception;\n    // Conversion between same size\n    static foreach (S; AliasSeq!(byte, short, int, long))\n    {{\n        alias U = Unsigned!S;\n\n        static foreach (Sint; AliasSeq!(S, const S, immutable S))\n        static foreach (Uint; AliasSeq!(U, const U, immutable U))\n        {{\n            // positive overflow\n            Uint un = Uint.max;\n            assertThrown!ConvOverflowException(to!Sint(un),\n                text(Sint.stringof, ' ', Uint.stringof, ' ', un));\n\n            // negative overflow\n            Sint sn = -1;\n            assertThrown!ConvOverflowException(to!Uint(sn),\n                text(Sint.stringof, ' ', Uint.stringof, ' ', un));\n        }}\n    }}\n\n    // Conversion between different size\n    static foreach (i, S1; AliasSeq!(byte, short, int, long))\n    static foreach (   S2; AliasSeq!(byte, short, int, long)[i+1..$])\n    {{\n        alias U1 = Unsigned!S1;\n        alias U2 = Unsigned!S2;\n\n        static assert(U1.sizeof < S2.sizeof);\n\n        // small unsigned to big signed\n        static foreach (Uint; AliasSeq!(U1, const U1, immutable U1))\n        static foreach (Sint; AliasSeq!(S2, const S2, immutable S2))\n        {{\n            Uint un = Uint.max;\n            assertNotThrown(to!Sint(un));\n            assert(to!Sint(un) == un);\n        }}\n\n        // big unsigned to small signed\n        static foreach (Uint; AliasSeq!(U2, const U2, immutable U2))\n        static foreach (Sint; AliasSeq!(S1, const S1, immutable S1))\n        {{\n            Uint un = Uint.max;\n            assertThrown(to!Sint(un));\n        }}\n\n        static assert(S1.sizeof < U2.sizeof);\n\n        // small signed to big unsigned\n        static foreach (Sint; AliasSeq!(S1, const S1, immutable S1))\n        static foreach (Uint; AliasSeq!(U2, const U2, immutable U2))\n        {{\n            Sint sn = -1;\n            assertThrown!ConvOverflowException(to!Uint(sn));\n        }}\n\n        // big signed to small unsigned\n        static foreach (Sint; AliasSeq!(S2, const S2, immutable S2))\n        static foreach (Uint; AliasSeq!(U1, const U1, immutable U1))\n        {{\n            Sint sn = -1;\n            assertThrown!ConvOverflowException(to!Uint(sn));\n        }}\n    }}\n}\n\n/*\n  Converting static arrays forwards to their dynamic counterparts.\n */\nprivate T toImpl(T, S)(ref S s)\nif (isStaticArray!S)\n{\n    return toImpl!(T, typeof(s[0])[])(s);\n}\n\n@safe pure nothrow unittest\n{\n    char[4] test = ['a', 'b', 'c', 'd'];\n    static assert(!isInputRange!(Unqual!(char[4])));\n    assert(to!string(test) == test);\n}\n\n/**\nWhen source type supports member template function opCast, it is used.\n*/\nprivate T toImpl(T, S)(S value)\nif (!isImplicitlyConvertible!(S, T) &&\n    is(typeof(S.init.opCast!T()) : T) &&\n    !isExactSomeString!T &&\n    !is(typeof(T(value))))\n{\n    return value.opCast!T();\n}\n\n@safe pure unittest\n{\n    static struct Test\n    {\n        struct T\n        {\n            this(S s) @safe pure { }\n        }\n        struct S\n        {\n            T opCast(U)() @safe pure { assert(false); }\n        }\n    }\n    cast(void) to!(Test.T)(Test.S());\n\n    // make sure std.conv.to is doing the same thing as initialization\n    Test.S s;\n    Test.T t = s;\n}\n\n@safe pure unittest\n{\n    class B\n    {\n        T opCast(T)() { return 43; }\n    }\n    auto b = new B;\n    assert(to!int(b) == 43);\n\n    struct S\n    {\n        T opCast(T)() { return 43; }\n    }\n    auto s = S();\n    assert(to!int(s) == 43);\n}\n\n/**\nWhen target type supports 'converting construction', it is used.\n$(UL $(LI If target type is struct, `T(value)` is used.)\n     $(LI If target type is class, $(D new T(value)) is used.))\n*/\nprivate T toImpl(T, S)(S value)\nif (!isImplicitlyConvertible!(S, T) &&\n    is(T == struct) && is(typeof(T(value))))\n{\n    return T(value);\n}\n\n// Bugzilla 3961\n@safe pure unittest\n{\n    struct Int\n    {\n        int x;\n    }\n    Int i = to!Int(1);\n\n    static struct Int2\n    {\n        int x;\n        this(int x) @safe pure { this.x = x; }\n    }\n    Int2 i2 = to!Int2(1);\n\n    static struct Int3\n    {\n        int x;\n        static Int3 opCall(int x) @safe pure\n        {\n            Int3 i;\n            i.x = x;\n            return i;\n        }\n    }\n    Int3 i3 = to!Int3(1);\n}\n\n// Bugzilla 6808\n@safe pure unittest\n{\n    static struct FakeBigInt\n    {\n        this(string s) @safe pure {}\n    }\n\n    string s = \"101\";\n    auto i3 = to!FakeBigInt(s);\n}\n\n/// ditto\nprivate T toImpl(T, S)(S value)\nif (!isImplicitlyConvertible!(S, T) &&\n    is(T == class) && is(typeof(new T(value))))\n{\n    return new T(value);\n}\n\n@safe pure unittest\n{\n    static struct S\n    {\n        int x;\n    }\n    static class C\n    {\n        int x;\n        this(int x) @safe pure { this.x = x; }\n    }\n\n    static class B\n    {\n        int value;\n        this(S src) @safe pure { value = src.x; }\n        this(C src) @safe pure { value = src.x; }\n    }\n\n    S s = S(1);\n    auto b1 = to!B(s);  // == new B(s)\n    assert(b1.value == 1);\n\n    C c = new C(2);\n    auto b2 = to!B(c);  // == new B(c)\n    assert(b2.value == 2);\n\n    auto c2 = to!C(3);   // == new C(3)\n    assert(c2.x == 3);\n}\n\n@safe pure unittest\n{\n    struct S\n    {\n        class A\n        {\n            this(B b) @safe pure {}\n        }\n        class B : A\n        {\n            this() @safe pure { super(this); }\n        }\n    }\n\n    S.B b = new S.B();\n    S.A a = to!(S.A)(b);      // == cast(S.A) b\n                              // (do not run construction conversion like new S.A(b))\n    assert(b is a);\n\n    static class C : Object\n    {\n        this() @safe pure {}\n        this(Object o) @safe pure {}\n    }\n\n    Object oc = new C();\n    C a2 = to!C(oc);    // == new C(a)\n                        // Construction conversion overrides down-casting conversion\n    assert(a2 !is a);   //\n}\n\n/**\nObject-to-object conversions by dynamic casting throw exception when the source is\nnon-null and the target is null.\n */\nprivate T toImpl(T, S)(S value)\nif (!isImplicitlyConvertible!(S, T) &&\n    (is(S == class) || is(S == interface)) && !is(typeof(value.opCast!T()) : T) &&\n    (is(T == class) || is(T == interface)) && !is(typeof(new T(value))))\n{\n    static if (is(T == immutable))\n    {\n            // immutable <- immutable\n            enum isModConvertible = is(S == immutable);\n    }\n    else static if (is(T == const))\n    {\n        static if (is(T == shared))\n        {\n            // shared const <- shared\n            // shared const <- shared const\n            // shared const <- immutable\n            enum isModConvertible = is(S == shared) || is(S == immutable);\n        }\n        else\n        {\n            // const <- mutable\n            // const <- immutable\n            enum isModConvertible = !is(S == shared);\n        }\n    }\n    else\n    {\n        static if (is(T == shared))\n        {\n            // shared <- shared mutable\n            enum isModConvertible = is(S == shared) && !is(S == const);\n        }\n        else\n        {\n            // (mutable) <- (mutable)\n            enum isModConvertible = is(Unqual!S == S);\n        }\n    }\n    static assert(isModConvertible, \"Bad modifier conversion: \"~S.stringof~\" to \"~T.stringof);\n\n    auto result = ()@trusted{ return cast(T) value; }();\n    if (!result && value)\n    {\n        throw new ConvException(\"Cannot convert object of static type \"\n                ~S.classinfo.name~\" and dynamic type \"~value.classinfo.name\n                ~\" to type \"~T.classinfo.name);\n    }\n    return result;\n}\n\n// Unittest for 6288\n@safe pure unittest\n{\n    import std.exception;\n\n    alias Identity(T)      =              T;\n    alias toConst(T)       =        const T;\n    alias toShared(T)      =       shared T;\n    alias toSharedConst(T) = shared const T;\n    alias toImmutable(T)   =    immutable T;\n    template AddModifier(int n)\n    if (0 <= n && n < 5)\n    {\n             static if (n == 0) alias AddModifier = Identity;\n        else static if (n == 1) alias AddModifier = toConst;\n        else static if (n == 2) alias AddModifier = toShared;\n        else static if (n == 3) alias AddModifier = toSharedConst;\n        else static if (n == 4) alias AddModifier = toImmutable;\n    }\n\n    interface I {}\n    interface J {}\n\n    class A {}\n    class B : A {}\n    class C : B, I, J {}\n    class D : I {}\n\n    static foreach (m1; 0 .. 5) // enumerate modifiers\n    static foreach (m2; 0 .. 5) // ditto\n    {{\n        alias srcmod = AddModifier!m1;\n        alias tgtmod = AddModifier!m2;\n\n        // Compile time convertible equals to modifier convertible.\n        static if (isImplicitlyConvertible!(srcmod!Object, tgtmod!Object))\n        {\n            // Test runtime conversions: class to class, class to interface,\n            // interface to class, and interface to interface\n\n            // Check that the runtime conversion to succeed\n            srcmod!A ac = new srcmod!C();\n            srcmod!I ic = new srcmod!C();\n            assert(to!(tgtmod!C)(ac) !is null); // A(c) to C\n            assert(to!(tgtmod!I)(ac) !is null); // A(c) to I\n            assert(to!(tgtmod!C)(ic) !is null); // I(c) to C\n            assert(to!(tgtmod!J)(ic) !is null); // I(c) to J\n\n            // Check that the runtime conversion fails\n            srcmod!A ab = new srcmod!B();\n            srcmod!I id = new srcmod!D();\n            assertThrown(to!(tgtmod!C)(ab));    // A(b) to C\n            assertThrown(to!(tgtmod!I)(ab));    // A(b) to I\n            assertThrown(to!(tgtmod!C)(id));    // I(d) to C\n            assertThrown(to!(tgtmod!J)(id));    // I(d) to J\n        }\n        else\n        {\n            // Check that the conversion is rejected statically\n            static assert(!is(typeof(to!(tgtmod!C)(srcmod!A.init))));   // A to C\n            static assert(!is(typeof(to!(tgtmod!I)(srcmod!A.init))));   // A to I\n            static assert(!is(typeof(to!(tgtmod!C)(srcmod!I.init))));   // I to C\n            static assert(!is(typeof(to!(tgtmod!J)(srcmod!I.init))));   // I to J\n        }\n    }}\n}\n\n/**\nHandles type _to string conversions\n*/\nprivate T toImpl(T, S)(S value)\nif (!(isImplicitlyConvertible!(S, T) &&\n    !isEnumStrToStr!(S, T) && !isNullToStr!(S, T)) &&\n    !isInfinite!S && isExactSomeString!T)\n{\n    static if (isExactSomeString!S && value[0].sizeof == ElementEncodingType!T.sizeof)\n    {\n        // string-to-string with incompatible qualifier conversion\n        static if (is(ElementEncodingType!T == immutable))\n        {\n            // conversion (mutable|const) -> immutable\n            return value.idup;\n        }\n        else\n        {\n            // conversion (immutable|const) -> mutable\n            return value.dup;\n        }\n    }\n    else static if (isExactSomeString!S)\n    {\n        import std.array : appender;\n        // other string-to-string\n        //Use Appender directly instead of toStr, which also uses a formatedWrite\n        auto w = appender!T();\n        w.put(value);\n        return w.data;\n    }\n    else static if (isIntegral!S && !is(S == enum))\n    {\n        // other integral-to-string conversions with default radix\n        return toImpl!(T, S)(value, 10);\n    }\n    else static if (is(S == void[]) || is(S == const(void)[]) || is(S == immutable(void)[]))\n    {\n        import core.stdc.string : memcpy;\n        import std.exception : enforce;\n        // Converting void array to string\n        alias Char = Unqual!(ElementEncodingType!T);\n        auto raw = cast(const(ubyte)[]) value;\n        enforce(raw.length % Char.sizeof == 0,\n                new ConvException(\"Alignment mismatch in converting a \"\n                        ~ S.stringof ~ \" to a \"\n                        ~ T.stringof));\n        auto result = new Char[raw.length / Char.sizeof];\n        ()@trusted{ memcpy(result.ptr, value.ptr, value.length); }();\n        return cast(T) result;\n    }\n    else static if (isPointer!S && isSomeChar!(PointerTarget!S))\n    {\n        // This is unsafe because we cannot guarantee that the pointer is null terminated.\n        return () @system {\n            static if (is(S : const(char)*))\n                import core.stdc.string : strlen;\n            else\n                size_t strlen(S s) nothrow\n                {\n                    S p = s;\n                    while (*p++) {}\n                    return p-s-1;\n                }\n            return toImpl!T(value ? value[0 .. strlen(value)].dup : null);\n        }();\n    }\n    else static if (isSomeString!T && is(S == enum))\n    {\n        static if (isSwitchable!(OriginalType!S) && EnumMembers!S.length <= 50)\n        {\n            switch (value)\n            {\n                foreach (member; NoDuplicates!(EnumMembers!S))\n                {\n                    case member:\n                        return to!T(enumRep!(immutable(T), S, member));\n                }\n                default:\n            }\n        }\n        else\n        {\n            foreach (member; EnumMembers!S)\n            {\n                if (value == member)\n                    return to!T(enumRep!(immutable(T), S, member));\n            }\n        }\n\n        import std.array : appender;\n        import std.format : FormatSpec, formatValue;\n\n        //Default case, delegate to format\n        //Note: we don't call toStr directly, to avoid duplicate work.\n        auto app = appender!T();\n        app.put(\"cast(\" ~ S.stringof ~ \")\");\n        FormatSpec!char f;\n        formatValue(app, cast(OriginalType!S) value, f);\n        return app.data;\n    }\n    else\n    {\n        // other non-string values runs formatting\n        return toStr!T(value);\n    }\n}\n\n// Bugzilla 14042\n@system unittest\n{\n    immutable(char)* ptr = \"hello\".ptr;\n    auto result = ptr.to!(char[]);\n}\n// Bugzilla 8384\n@system unittest\n{\n    void test1(T)(T lp, string cmp)\n    {\n        static foreach (e; AliasSeq!(char, wchar, dchar))\n        {\n            test2!(e[])(lp, cmp);\n            test2!(const(e)[])(lp, cmp);\n            test2!(immutable(e)[])(lp, cmp);\n        }\n    }\n\n    void test2(D, S)(S lp, string cmp)\n    {\n        assert(to!string(to!D(lp)) == cmp);\n    }\n\n    static foreach (e; AliasSeq!(\"Hello, world!\", \"Hello, world!\"w, \"Hello, world!\"d))\n    {\n        test1(e, \"Hello, world!\");\n        test1(e.ptr, \"Hello, world!\");\n    }\n    static foreach (e; AliasSeq!(\"\", \"\"w, \"\"d))\n    {\n        test1(e, \"\");\n        test1(e.ptr, \"\");\n    }\n}\n\n/*\n    To string conversion for non copy-able structs\n */\nprivate T toImpl(T, S)(ref S value)\nif (!(isImplicitlyConvertible!(S, T) &&\n    !isEnumStrToStr!(S, T) && !isNullToStr!(S, T)) &&\n    !isInfinite!S && isExactSomeString!T && !isCopyable!S)\n{\n    import std.array : appender;\n    import std.format : FormatSpec, formatValue;\n\n    auto w = appender!T();\n    FormatSpec!(ElementEncodingType!T) f;\n    formatValue(w, value, f);\n    return w.data;\n}\n\n// Bugzilla 16108\n@system unittest\n{\n    static struct A\n    {\n        int val;\n        bool flag;\n\n        string toString() { return text(val, \":\", flag); }\n\n        @disable this(this);\n    }\n\n    auto a = A();\n    assert(to!string(a) == \"0:false\");\n\n    static struct B\n    {\n        int val;\n        bool flag;\n\n        @disable this(this);\n    }\n\n    auto b = B();\n    assert(to!string(b) == \"B(0, false)\");\n}\n\n/*\n    Check whether type `T` can be used in a switch statement.\n    This is useful for compile-time generation of switch case statements.\n*/\nprivate template isSwitchable(E)\n{\n    enum bool isSwitchable = is(typeof({\n        switch (E.init) { default: }\n    }));\n}\n\n//\n@safe unittest\n{\n    static assert(isSwitchable!int);\n    static assert(!isSwitchable!double);\n    static assert(!isSwitchable!real);\n}\n\n//Static representation of the index I of the enum S,\n//In representation T.\n//T must be an immutable string (avoids un-necessary initializations).\nprivate template enumRep(T, S, S value)\nif (is (T == immutable) && isExactSomeString!T && is(S == enum))\n{\n    static T enumRep = toStr!T(value);\n}\n\n@safe pure unittest\n{\n    import std.exception;\n    void dg()\n    {\n        // string to string conversion\n        alias Chars = AliasSeq!(char, wchar, dchar);\n        foreach (LhsC; Chars)\n        {\n            alias LhStrings = AliasSeq!(LhsC[], const(LhsC)[], immutable(LhsC)[]);\n            foreach (Lhs; LhStrings)\n            {\n                foreach (RhsC; Chars)\n                {\n                    alias RhStrings = AliasSeq!(RhsC[], const(RhsC)[], immutable(RhsC)[]);\n                    foreach (Rhs; RhStrings)\n                    {\n                        Lhs s1 = to!Lhs(\"wyda\");\n                        Rhs s2 = to!Rhs(s1);\n                        //writeln(Lhs.stringof, \" -> \", Rhs.stringof);\n                        assert(s1 == to!Lhs(s2));\n                    }\n                }\n            }\n        }\n\n        foreach (T; Chars)\n        {\n            foreach (U; Chars)\n            {\n                T[] s1 = to!(T[])(\"Hello, world!\");\n                auto s2 = to!(U[])(s1);\n                assert(s1 == to!(T[])(s2));\n                auto s3 = to!(const(U)[])(s1);\n                assert(s1 == to!(T[])(s3));\n                auto s4 = to!(immutable(U)[])(s1);\n                assert(s1 == to!(T[])(s4));\n            }\n        }\n    }\n    dg();\n    assertCTFEable!dg;\n}\n\n@safe pure unittest\n{\n    // Conversion representing bool value with string\n    bool b;\n    assert(to!string(b) == \"false\");\n    b = true;\n    assert(to!string(b) == \"true\");\n}\n\n@safe pure unittest\n{\n    // Conversion representing character value with string\n    alias AllChars =\n        AliasSeq!( char, const( char), immutable( char),\n                  wchar, const(wchar), immutable(wchar),\n                  dchar, const(dchar), immutable(dchar));\n    foreach (Char1; AllChars)\n    {\n        foreach (Char2; AllChars)\n        {\n            Char1 c = 'a';\n            assert(to!(Char2[])(c)[0] == c);\n        }\n        uint x = 4;\n        assert(to!(Char1[])(x) == \"4\");\n    }\n\n    string s = \"foo\";\n    string s2;\n    foreach (char c; s)\n    {\n        s2 ~= to!string(c);\n    }\n    assert(s2 == \"foo\");\n}\n\n@safe pure nothrow unittest\n{\n    import std.exception;\n    // Conversion representing integer values with string\n\n    static foreach (Int; AliasSeq!(ubyte, ushort, uint, ulong))\n    {\n        assert(to!string(Int(0)) == \"0\");\n        assert(to!string(Int(9)) == \"9\");\n        assert(to!string(Int(123)) == \"123\");\n    }\n\n    static foreach (Int; AliasSeq!(byte, short, int, long))\n    {\n        assert(to!string(Int(0)) == \"0\");\n        assert(to!string(Int(9)) == \"9\");\n        assert(to!string(Int(123)) == \"123\");\n        assert(to!string(Int(-0)) == \"0\");\n        assert(to!string(Int(-9)) == \"-9\");\n        assert(to!string(Int(-123)) == \"-123\");\n        assert(to!string(const(Int)(6)) == \"6\");\n    }\n\n    assert(wtext(int.max) == \"2147483647\"w);\n    assert(wtext(int.min) == \"-2147483648\"w);\n    assert(to!string(0L) == \"0\");\n\n    assertCTFEable!(\n    {\n        assert(to!string(1uL << 62) == \"4611686018427387904\");\n        assert(to!string(0x100000000) == \"4294967296\");\n        assert(to!string(-138L) == \"-138\");\n    });\n}\n\n@safe unittest // sprintf issue\n{\n    double[2] a = [ 1.5, 2.5 ];\n    assert(to!string(a) == \"[1.5, 2.5]\");\n}\n\n@system unittest\n{\n    // Conversion representing class object with string\n    class A\n    {\n        override string toString() const { return \"an A\"; }\n    }\n    A a;\n    assert(to!string(a) == \"null\");\n    a = new A;\n    assert(to!string(a) == \"an A\");\n\n    // Bug 7660\n    class C { override string toString() const { return \"C\"; } }\n    struct S { C c; alias c this; }\n    S s; s.c = new C();\n    assert(to!string(s) == \"C\");\n}\n\n@safe unittest\n{\n    // Conversion representing struct object with string\n    struct S1\n    {\n        string toString() { return \"wyda\"; }\n    }\n    assert(to!string(S1()) == \"wyda\");\n\n    struct S2\n    {\n        int a = 42;\n        float b = 43.5;\n    }\n    S2 s2;\n    assert(to!string(s2) == \"S2(42, 43.5)\");\n\n    // Test for issue 8080\n    struct S8080\n    {\n        short[4] data;\n        alias data this;\n        string toString() { return \"<S>\"; }\n    }\n    S8080 s8080;\n    assert(to!string(s8080) == \"<S>\");\n}\n\n@safe unittest\n{\n    // Conversion representing enum value with string\n    enum EB : bool { a = true }\n    enum EU : uint { a = 0, b = 1, c = 2 }  // base type is unsigned\n    enum EI : int { a = -1, b = 0, c = 1 }  // base type is signed (bug 7909)\n    enum EF : real { a = 1.414, b = 1.732, c = 2.236 }\n    enum EC : char { a = 'x', b = 'y' }\n    enum ES : string { a = \"aaa\", b = \"bbb\" }\n\n    static foreach (E; AliasSeq!(EB, EU, EI, EF, EC, ES))\n    {\n        assert(to! string(E.a) == \"a\"c);\n        assert(to!wstring(E.a) == \"a\"w);\n        assert(to!dstring(E.a) == \"a\"d);\n    }\n\n    // Test an value not corresponding to an enum member.\n    auto o = cast(EU) 5;\n    assert(to! string(o) == \"cast(EU)5\"c);\n    assert(to!wstring(o) == \"cast(EU)5\"w);\n    assert(to!dstring(o) == \"cast(EU)5\"d);\n}\n\n@safe unittest\n{\n    enum E\n    {\n        foo,\n        doo = foo, // check duplicate switch statements\n        bar,\n    }\n\n    //Test regression 12494\n    assert(to!string(E.foo) == \"foo\");\n    assert(to!string(E.doo) == \"foo\");\n    assert(to!string(E.bar) == \"bar\");\n\n    static foreach (S; AliasSeq!(string, wstring, dstring, const(char[]), const(wchar[]), const(dchar[])))\n    {{\n        auto s1 = to!S(E.foo);\n        auto s2 = to!S(E.foo);\n        assert(s1 == s2);\n        // ensure we don't allocate when it's unnecessary\n        assert(s1 is s2);\n    }}\n\n    static foreach (S; AliasSeq!(char[], wchar[], dchar[]))\n    {{\n        auto s1 = to!S(E.foo);\n        auto s2 = to!S(E.foo);\n        assert(s1 == s2);\n        // ensure each mutable array is unique\n        assert(s1 !is s2);\n    }}\n}\n\n// ditto\n@trusted pure private T toImpl(T, S)(S value, uint radix, LetterCase letterCase = LetterCase.upper)\nif (isIntegral!S &&\n    isExactSomeString!T)\nin\n{\n    assert(radix >= 2 && radix <= 36);\n}\ndo\n{\n    alias EEType = Unqual!(ElementEncodingType!T);\n\n    T toStringRadixConvert(size_t bufLen)(uint runtimeRadix = 0)\n    {\n        Unsigned!(Unqual!S) div = void, mValue = unsigned(value);\n\n        size_t index = bufLen;\n        EEType[bufLen] buffer = void;\n        char baseChar = letterCase == LetterCase.lower ? 'a' : 'A';\n        char mod = void;\n\n        do\n        {\n            div = cast(S)(mValue / runtimeRadix );\n            mod = cast(ubyte)(mValue % runtimeRadix);\n            mod += mod < 10 ? '0' : baseChar - 10;\n            buffer[--index] = cast(char) mod;\n            mValue = div;\n        } while (mValue);\n\n        return cast(T) buffer[index .. $].dup;\n    }\n\n    import std.array : array;\n    switch (radix)\n    {\n        case 10:\n            // The (value+0) is so integral promotions happen to the type\n            return toChars!(10, EEType)(value + 0).array;\n        case 16:\n            // The unsigned(unsigned(value)+0) is so unsigned integral promotions happen to the type\n            if (letterCase == letterCase.upper)\n                return toChars!(16, EEType, LetterCase.upper)(unsigned(unsigned(value) + 0)).array;\n            else\n                return toChars!(16, EEType, LetterCase.lower)(unsigned(unsigned(value) + 0)).array;\n        case 2:\n            return toChars!(2, EEType)(unsigned(unsigned(value) + 0)).array;\n        case 8:\n            return toChars!(8, EEType)(unsigned(unsigned(value) + 0)).array;\n\n        default:\n            return toStringRadixConvert!(S.sizeof * 6)(radix);\n    }\n}\n\n@safe pure nothrow unittest\n{\n    static foreach (Int; AliasSeq!(uint, ulong))\n    {\n        assert(to!string(Int(16), 16) == \"10\");\n        assert(to!string(Int(15), 2u) == \"1111\");\n        assert(to!string(Int(1), 2u) == \"1\");\n        assert(to!string(Int(0x1234AF), 16u) == \"1234AF\");\n        assert(to!string(Int(0x1234BCD), 16u, LetterCase.upper) == \"1234BCD\");\n        assert(to!string(Int(0x1234AF), 16u, LetterCase.lower) == \"1234af\");\n    }\n\n    static foreach (Int; AliasSeq!(int, long))\n    {\n        assert(to!string(Int(-10), 10u) == \"-10\");\n    }\n\n    assert(to!string(byte(-10), 16) == \"F6\");\n    assert(to!string(long.min) == \"-9223372036854775808\");\n    assert(to!string(long.max) == \"9223372036854775807\");\n}\n\n/**\nNarrowing numeric-numeric conversions throw when the value does not\nfit in the narrower type.\n */\nprivate T toImpl(T, S)(S value)\nif (!isImplicitlyConvertible!(S, T) &&\n    (isNumeric!S || isSomeChar!S || isBoolean!S) &&\n    (isNumeric!T || isSomeChar!T || isBoolean!T) && !is(T == enum))\n{\n    enum sSmallest = mostNegative!S;\n    enum tSmallest = mostNegative!T;\n    static if (sSmallest < 0)\n    {\n        // possible underflow converting from a signed\n        static if (tSmallest == 0)\n        {\n            immutable good = value >= 0;\n        }\n        else\n        {\n            static assert(tSmallest < 0);\n            immutable good = value >= tSmallest;\n        }\n        if (!good)\n            throw new ConvOverflowException(\"Conversion negative overflow\");\n    }\n    static if (S.max > T.max)\n    {\n        // possible overflow\n        if (value > T.max)\n            throw new ConvOverflowException(\"Conversion positive overflow\");\n    }\n    return (ref value)@trusted{ return cast(T) value; }(value);\n}\n\n@safe pure unittest\n{\n    import std.exception;\n\n    dchar a = ' ';\n    assert(to!char(a) == ' ');\n    a = 300;\n    assert(collectException(to!char(a)));\n\n    dchar from0 = 'A';\n    char to0 = to!char(from0);\n\n    wchar from1 = 'A';\n    char to1 = to!char(from1);\n\n    char from2 = 'A';\n    char to2 = to!char(from2);\n\n    char from3 = 'A';\n    wchar to3 = to!wchar(from3);\n\n    char from4 = 'A';\n    dchar to4 = to!dchar(from4);\n}\n\n@safe unittest\n{\n    import std.exception;\n\n    // Narrowing conversions from enum -> integral should be allowed, but they\n    // should throw at runtime if the enum value doesn't fit in the target\n    // type.\n    enum E1 : ulong { A = 1, B = 1UL << 48, C = 0 }\n    assert(to!int(E1.A) == 1);\n    assert(to!bool(E1.A) == true);\n    assertThrown!ConvOverflowException(to!int(E1.B)); // E1.B overflows int\n    assertThrown!ConvOverflowException(to!bool(E1.B)); // E1.B overflows bool\n    assert(to!bool(E1.C) == false);\n\n    enum E2 : long { A = -1L << 48, B = -1 << 31, C = 1 << 31 }\n    assertThrown!ConvOverflowException(to!int(E2.A)); // E2.A overflows int\n    assertThrown!ConvOverflowException(to!uint(E2.B)); // E2.B overflows uint\n    assert(to!int(E2.B) == -1 << 31); // but does not overflow int\n    assert(to!int(E2.C) == 1 << 31);  // E2.C does not overflow int\n\n    enum E3 : int { A = -1, B = 1, C = 255, D = 0 }\n    assertThrown!ConvOverflowException(to!ubyte(E3.A));\n    assertThrown!ConvOverflowException(to!bool(E3.A));\n    assert(to!byte(E3.A) == -1);\n    assert(to!byte(E3.B) == 1);\n    assert(to!ubyte(E3.C) == 255);\n    assert(to!bool(E3.B) == true);\n    assertThrown!ConvOverflowException(to!byte(E3.C));\n    assertThrown!ConvOverflowException(to!bool(E3.C));\n    assert(to!bool(E3.D) == false);\n\n}\n\n/**\nArray-to-array conversion (except when target is a string type)\nconverts each element in turn by using `to`.\n */\nprivate T toImpl(T, S)(S value)\nif (!isImplicitlyConvertible!(S, T) &&\n    !isSomeString!S && isDynamicArray!S &&\n    !isExactSomeString!T && isArray!T)\n{\n    alias E = typeof(T.init[0]);\n\n    static if (isStaticArray!T)\n    {\n        import std.exception : enforce;\n        auto res = to!(E[])(value);\n        enforce!ConvException(T.length == res.length,\n            convFormat(\"Length mismatch when converting to static array: %s vs %s\", T.length, res.length));\n        return res[0 .. T.length];\n    }\n    else\n    {\n        import std.array : appender;\n        auto w = appender!(E[])();\n        w.reserve(value.length);\n        foreach (ref e; value)\n        {\n            w.put(to!E(e));\n        }\n        return w.data;\n    }\n}\n\n@safe pure unittest\n{\n    import std.exception;\n\n    // array to array conversions\n    uint[] a = [ 1u, 2, 3 ];\n    auto b = to!(float[])(a);\n    assert(b == [ 1.0f, 2, 3 ]);\n\n    immutable(int)[3] d = [ 1, 2, 3 ];\n    b = to!(float[])(d);\n    assert(b == [ 1.0f, 2, 3 ]);\n\n    uint[][] e = [ a, a ];\n    auto f = to!(float[][])(e);\n    assert(f[0] == b && f[1] == b);\n\n    // Test for bug 8264\n    struct Wrap\n    {\n        string wrap;\n        alias wrap this;\n    }\n    Wrap[] warr = to!(Wrap[])([\"foo\", \"bar\"]);  // should work\n\n    // Issue 12633\n    import std.conv : to;\n    const s2 = [\"10\", \"20\"];\n\n    immutable int[2] a3 = s2.to!(int[2]);\n    assert(a3 == [10, 20]);\n\n    // verify length mismatches are caught\n    immutable s4 = [1, 2, 3, 4];\n    foreach (i; [1, 4])\n    {\n        auto ex = collectException(s4[0 .. i].to!(int[2]));\n            assert(ex && ex.msg == \"Length mismatch when converting to static array: 2 vs \" ~ [cast(char)(i + '0')],\n                ex ? ex.msg : \"Exception was not thrown!\");\n    }\n}\n\n@safe unittest\n{\n    auto b = [ 1.0f, 2, 3 ];\n\n    auto c = to!(string[])(b);\n    assert(c[0] == \"1\" && c[1] == \"2\" && c[2] == \"3\");\n}\n\n/**\nAssociative array to associative array conversion converts each key\nand each value in turn.\n */\nprivate T toImpl(T, S)(S value)\nif (!isImplicitlyConvertible!(S, T) && isAssociativeArray!S &&\n    isAssociativeArray!T && !is(T == enum))\n{\n    /* This code is potentially unsafe.\n     */\n    alias K2 = KeyType!T;\n    alias V2 = ValueType!T;\n\n    // While we are \"building\" the AA, we need to unqualify its values, and only re-qualify at the end\n    Unqual!V2[K2] result;\n\n    foreach (k1, v1; value)\n    {\n        // Cast values temporarily to Unqual!V2 to store them to result variable\n        result[to!K2(k1)] = cast(Unqual!V2) to!V2(v1);\n    }\n    // Cast back to original type\n    return cast(T) result;\n}\n\n@safe unittest\n{\n    // hash to hash conversions\n    int[string] a;\n    a[\"0\"] = 1;\n    a[\"1\"] = 2;\n    auto b = to!(double[dstring])(a);\n    assert(b[\"0\"d] == 1 && b[\"1\"d] == 2);\n}\n@safe unittest // Bugzilla 8705, from doc\n{\n    import std.exception;\n    int[string][double[int[]]] a;\n    auto b = to!(short[wstring][string[double[]]])(a);\n    a = [null:[\"hello\":int.max]];\n    assertThrown!ConvOverflowException(to!(short[wstring][string[double[]]])(a));\n}\n@system unittest // Extra cases for AA with qualifiers conversion\n{\n    int[][int[]] a;// = [[], []];\n    auto b = to!(immutable(short[])[immutable short[]])(a);\n\n    double[dstring][int[long[]]] c;\n    auto d = to!(immutable(short[immutable wstring])[immutable string[double[]]])(c);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.array : byPair;\n\n    int[int] a;\n    assert(a.to!(int[int]) == a);\n    assert(a.to!(const(int)[int]).byPair.equal(a.byPair));\n}\n\nversion (unittest)\nprivate void testIntegralToFloating(Integral, Floating)()\n{\n    Integral a = 42;\n    auto b = to!Floating(a);\n    assert(a == b);\n    assert(a == to!Integral(b));\n}\n\nversion (unittest)\nprivate void testFloatingToIntegral(Floating, Integral)()\n{\n    bool convFails(Source, Target, E)(Source src)\n    {\n        try\n            cast(void) to!Target(src);\n        catch (E)\n            return true;\n        return false;\n    }\n\n    // convert some value\n    Floating a = 4.2e1;\n    auto b = to!Integral(a);\n    assert(is(typeof(b) == Integral) && b == 42);\n    // convert some negative value (if applicable)\n    a = -4.2e1;\n    static if (Integral.min < 0)\n    {\n        b = to!Integral(a);\n        assert(is(typeof(b) == Integral) && b == -42);\n    }\n    else\n    {\n        // no go for unsigned types\n        assert(convFails!(Floating, Integral, ConvOverflowException)(a));\n    }\n    // convert to the smallest integral value\n    a = 0.0 + Integral.min;\n    static if (Integral.min < 0)\n    {\n        a = -a; // -Integral.min not representable as an Integral\n        assert(convFails!(Floating, Integral, ConvOverflowException)(a)\n                || Floating.sizeof <= Integral.sizeof);\n    }\n    a = 0.0 + Integral.min;\n    assert(to!Integral(a) == Integral.min);\n    --a; // no more representable as an Integral\n    assert(convFails!(Floating, Integral, ConvOverflowException)(a)\n            || Floating.sizeof <= Integral.sizeof);\n    a = 0.0 + Integral.max;\n    assert(to!Integral(a) == Integral.max || Floating.sizeof <= Integral.sizeof);\n    ++a; // no more representable as an Integral\n    assert(convFails!(Floating, Integral, ConvOverflowException)(a)\n            || Floating.sizeof <= Integral.sizeof);\n    // convert a value with a fractional part\n    a = 3.14;\n    assert(to!Integral(a) == 3);\n    a = 3.99;\n    assert(to!Integral(a) == 3);\n    static if (Integral.min < 0)\n    {\n        a = -3.14;\n        assert(to!Integral(a) == -3);\n        a = -3.99;\n        assert(to!Integral(a) == -3);\n    }\n}\n\n@safe pure unittest\n{\n    alias AllInts = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong);\n    alias AllFloats = AliasSeq!(float, double, real);\n    alias AllNumerics = AliasSeq!(AllInts, AllFloats);\n    // test with same type\n    {\n        foreach (T; AllNumerics)\n        {\n            T a = 42;\n            auto b = to!T(a);\n            assert(is(typeof(a) == typeof(b)) && a == b);\n        }\n    }\n    // test that floating-point numbers convert properly to largest ints\n    // see http://oregonstate.edu/~peterseb/mth351/docs/351s2001_fp80x87.html\n    // look for \"largest fp integer with a predecessor\"\n    {\n        // float\n        int a = 16_777_215; // 2^24 - 1\n        assert(to!int(to!float(a)) == a);\n        assert(to!int(to!float(-a)) == -a);\n        // double\n        long b = 9_007_199_254_740_991; // 2^53 - 1\n        assert(to!long(to!double(b)) == b);\n        assert(to!long(to!double(-b)) == -b);\n        // real\n        static if (real.mant_dig >= 64)\n        {\n            ulong c = 18_446_744_073_709_551_615UL; // 2^64 - 1\n            assert(to!ulong(to!real(c)) == c);\n        }\n    }\n    // test conversions floating => integral\n    {\n        // AllInts[0 .. $ - 1] should be AllInts\n        // @@@ BUG IN COMPILER @@@\n        foreach (Integral; AllInts[0 .. $ - 1])\n        {\n            foreach (Floating; AllFloats)\n            {\n                testFloatingToIntegral!(Floating, Integral)();\n            }\n        }\n    }\n    // test conversion integral => floating\n    {\n        foreach (Integral; AllInts[0 .. $ - 1])\n        {\n            foreach (Floating; AllFloats)\n            {\n                testIntegralToFloating!(Integral, Floating)();\n            }\n        }\n    }\n    // test parsing\n    {\n        foreach (T; AllNumerics)\n        {\n            // from type immutable(char)[2]\n            auto a = to!T(\"42\");\n            assert(a == 42);\n            // from type char[]\n            char[] s1 = \"42\".dup;\n            a = to!T(s1);\n            assert(a == 42);\n            // from type char[2]\n            char[2] s2;\n            s2[] = \"42\";\n            a = to!T(s2);\n            assert(a == 42);\n            // from type immutable(wchar)[2]\n            a = to!T(\"42\"w);\n            assert(a == 42);\n        }\n    }\n}\n\n@safe unittest\n{\n    alias AllInts = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong);\n    alias AllFloats = AliasSeq!(float, double, real);\n    alias AllNumerics = AliasSeq!(AllInts, AllFloats);\n    // test conversions to string\n    {\n        foreach (T; AllNumerics)\n        {\n            T a = 42;\n            assert(to!string(a) == \"42\");\n            assert(to!wstring(a) == \"42\"w);\n            assert(to!dstring(a) == \"42\"d);\n            // array test\n            T[] b = new T[2];\n            b[0] = 42;\n            b[1] = 33;\n            assert(to!string(b) == \"[42, 33]\");\n        }\n    }\n    // test array to string conversion\n    foreach (T ; AllNumerics)\n    {\n        auto a = [to!T(1), 2, 3];\n        assert(to!string(a) == \"[1, 2, 3]\");\n    }\n    // test enum to int conversion\n    enum Testing { Test1, Test2 }\n    Testing t;\n    auto a = to!string(t);\n    assert(a == \"Test1\");\n}\n\n\n/**\nString, or string-like input range, to non-string conversion runs parsing.\n$(UL\n  $(LI When the source is a wide string, it is first converted to a narrow\n       string and then parsed.)\n  $(LI When the source is a narrow string, normal text parsing occurs.))\n*/\nprivate T toImpl(T, S)(S value)\nif (isInputRange!S && isSomeChar!(ElementEncodingType!S) &&\n    !isExactSomeString!T && is(typeof(parse!T(value))))\n{\n    scope(success)\n    {\n        if (!value.empty)\n        {\n            throw convError!(S, T)(value);\n        }\n    }\n    return parse!T(value);\n}\n\n/// ditto\nprivate T toImpl(T, S)(S value, uint radix)\nif (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S) &&\n    isIntegral!T && is(typeof(parse!T(value, radix))))\n{\n    scope(success)\n    {\n        if (!value.empty)\n        {\n            throw convError!(S, T)(value);\n        }\n    }\n    return parse!T(value, radix);\n}\n\n@safe pure unittest\n{\n    // Issue 6668 - ensure no collaterals thrown\n    try { to!uint(\"-1\"); }\n    catch (ConvException e) { assert(e.next is null); }\n}\n\n@safe pure unittest\n{\n    static foreach (Str; AliasSeq!(string, wstring, dstring))\n    {{\n        Str a = \"123\";\n        assert(to!int(a) == 123);\n        assert(to!double(a) == 123);\n    }}\n\n    // 6255\n    auto n = to!int(\"FF\", 16);\n    assert(n == 255);\n}\n\n// bugzilla 15800\n@safe unittest\n{\n    import std.utf : byCodeUnit, byChar, byWchar, byDchar;\n\n    assert(to!int(byCodeUnit(\"10\")) == 10);\n    assert(to!int(byCodeUnit(\"10\"), 10) == 10);\n    assert(to!int(byCodeUnit(\"10\"w)) == 10);\n    assert(to!int(byCodeUnit(\"10\"w), 10) == 10);\n\n    assert(to!int(byChar(\"10\")) == 10);\n    assert(to!int(byChar(\"10\"), 10) == 10);\n    assert(to!int(byWchar(\"10\")) == 10);\n    assert(to!int(byWchar(\"10\"), 10) == 10);\n    assert(to!int(byDchar(\"10\")) == 10);\n    assert(to!int(byDchar(\"10\"), 10) == 10);\n}\n\n/**\nString, or string-like input range, to char type not directly\nsupported by parse parses the first dchar of the source.\n\nReturns: the first code point of the input range, converted\n         to type T.\n\nThrows: ConvException if the input range contains more than\n        a single code point, or if the code point does not\n        fit into a code unit of type T.\n*/\nprivate T toImpl(T, S)(S value)\nif (isSomeChar!T && !is(typeof(parse!T(value))) &&\n    is(typeof(parse!dchar(value))))\n{\n    import std.utf : encode;\n\n    immutable dchar codepoint = parse!dchar(value);\n    if (!value.empty)\n        throw new ConvException(convFormat(\"Cannot convert \\\"%s\\\" to %s because it \" ~\n                                           \"contains more than a single code point.\",\n                                           value, T.stringof));\n    T[dchar.sizeof / T.sizeof] decodedCodepoint;\n    if (encode(decodedCodepoint, codepoint) != 1)\n        throw new ConvException(convFormat(\"First code point '%s' of \\\"%s\\\" does not fit into a \" ~\n                                           \"single %s code unit\", codepoint, value, T.stringof));\n    return decodedCodepoint[0];\n}\n\n@safe pure unittest\n{\n    import std.exception : assertThrown;\n\n    assert(toImpl!wchar(\"a\") == 'a');\n\n    assert(toImpl!char(\"a\"d) == 'a');\n    assert(toImpl!char(\"a\"w) == 'a');\n    assert(toImpl!wchar(\"a\"d) == 'a');\n\n    assertThrown!ConvException(toImpl!wchar(\"ab\"));\n    assertThrown!ConvException(toImpl!char(\"😃\"d));\n}\n\n/**\nConvert a value that is implicitly convertible to the enum base type\ninto an Enum value. If the value does not match any enum member values\na ConvException is thrown.\nEnums with floating-point or string base types are not supported.\n*/\nprivate T toImpl(T, S)(S value)\nif (is(T == enum) && !is(S == enum)\n    && is(typeof(value == OriginalType!T.init))\n    && !isFloatingPoint!(OriginalType!T) && !isSomeString!(OriginalType!T))\n{\n    foreach (Member; EnumMembers!T)\n    {\n        if (Member == value)\n            return Member;\n    }\n    throw new ConvException(convFormat(\"Value (%s) does not match any member value of enum '%s'\", value, T.stringof));\n}\n\n@safe pure unittest\n{\n    import std.exception;\n    enum En8143 : int { A = 10, B = 20, C = 30, D = 20 }\n    enum En8143[][] m3 = to!(En8143[][])([[10, 30], [30, 10]]);\n    static assert(m3 == [[En8143.A, En8143.C], [En8143.C, En8143.A]]);\n\n    En8143 en1 = to!En8143(10);\n    assert(en1 == En8143.A);\n    assertThrown!ConvException(to!En8143(5));   // matches none\n    En8143[][] m1 = to!(En8143[][])([[10, 30], [30, 10]]);\n    assert(m1 == [[En8143.A, En8143.C], [En8143.C, En8143.A]]);\n}\n\n/***************************************************************\n Rounded conversion from floating point to integral.\n\nRounded conversions do not work with non-integral target types.\n */\n\ntemplate roundTo(Target)\n{\n    Target roundTo(Source)(Source value)\n    {\n        import std.math : trunc;\n\n        static assert(isFloatingPoint!Source);\n        static assert(isIntegral!Target);\n        return to!Target(trunc(value + (value < 0 ? -0.5L : 0.5L)));\n    }\n}\n\n///\n@safe unittest\n{\n    assert(roundTo!int(3.14) == 3);\n    assert(roundTo!int(3.49) == 3);\n    assert(roundTo!int(3.5) == 4);\n    assert(roundTo!int(3.999) == 4);\n    assert(roundTo!int(-3.14) == -3);\n    assert(roundTo!int(-3.49) == -3);\n    assert(roundTo!int(-3.5) == -4);\n    assert(roundTo!int(-3.999) == -4);\n    assert(roundTo!(const int)(to!(const double)(-3.999)) == -4);\n}\n\n@safe unittest\n{\n    import std.exception;\n    // boundary values\n    static foreach (Int; AliasSeq!(byte, ubyte, short, ushort, int, uint))\n    {\n        assert(roundTo!Int(Int.min - 0.4L) == Int.min);\n        assert(roundTo!Int(Int.max + 0.4L) == Int.max);\n        assertThrown!ConvOverflowException(roundTo!Int(Int.min - 0.5L));\n        assertThrown!ConvOverflowException(roundTo!Int(Int.max + 0.5L));\n    }\n}\n\n/**\nThe `parse` family of functions works quite like the `to`\nfamily, except that:\n$(OL\n    $(LI It only works with character ranges as input.)\n    $(LI It takes the input by reference. (This means that rvalues - such\n    as string literals - are not accepted: use `to` instead.))\n    $(LI It advances the input to the position following the conversion.)\n    $(LI It does not throw if it could not convert the entire input.))\n\nThis overload converts a character input range to a `bool`.\n\nParams:\n    Target = the type to convert to\n    source = the lvalue of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n\nReturns:\n    A `bool`\n\nThrows:\n    A $(LREF ConvException) if the range does not represent a `bool`.\n\nNote:\n    All character input range conversions using $(LREF to) are forwarded\n    to `parse` and do not require lvalues.\n*/\nTarget parse(Target, Source)(ref Source source)\nif (isInputRange!Source &&\n    isSomeChar!(ElementType!Source) &&\n    is(Unqual!Target == bool))\n{\n    import std.ascii : toLower;\n\n    static if (isNarrowString!Source)\n    {\n        import std.string : representation;\n        auto s = source.representation;\n    }\n    else\n    {\n        alias s = source;\n    }\n\n    if (!s.empty)\n    {\n        auto c1 = toLower(s.front);\n        bool result = c1 == 't';\n        if (result || c1 == 'f')\n        {\n            s.popFront();\n            foreach (c; result ? \"rue\" : \"alse\")\n            {\n                if (s.empty || toLower(s.front) != c)\n                    goto Lerr;\n                s.popFront();\n            }\n\n            static if (isNarrowString!Source)\n                source = cast(Source) s;\n\n            return result;\n        }\n    }\nLerr:\n    throw parseError(\"bool should be case-insensitive 'true' or 'false'\");\n}\n\n///\n@safe unittest\n{\n    auto s = \"true\";\n    bool b = parse!bool(s);\n    assert(b);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.exception;\n    struct InputString\n    {\n        string _s;\n        @property auto front() { return _s.front; }\n        @property bool empty() { return _s.empty; }\n        void popFront() { _s.popFront(); }\n    }\n\n    auto s = InputString(\"trueFALSETrueFalsetRUEfALSE\");\n    assert(parse!bool(s) == true);\n    assert(s.equal(\"FALSETrueFalsetRUEfALSE\"));\n    assert(parse!bool(s) == false);\n    assert(s.equal(\"TrueFalsetRUEfALSE\"));\n    assert(parse!bool(s) == true);\n    assert(s.equal(\"FalsetRUEfALSE\"));\n    assert(parse!bool(s) == false);\n    assert(s.equal(\"tRUEfALSE\"));\n    assert(parse!bool(s) == true);\n    assert(s.equal(\"fALSE\"));\n    assert(parse!bool(s) == false);\n    assert(s.empty);\n\n    foreach (ss; [\"tfalse\", \"ftrue\", \"t\", \"f\", \"tru\", \"fals\", \"\"])\n    {\n        s = InputString(ss);\n        assertThrown!ConvException(parse!bool(s));\n    }\n}\n\n/**\nParses a character $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\nto an integral value.\n\nParams:\n    Target = the integral type to convert to\n    s = the lvalue of an input range\n\nReturns:\n    A number of type `Target`\n\nThrows:\n    A $(LREF ConvException) If an overflow occurred during conversion or\n    if no character of the input was meaningfully converted.\n*/\nTarget parse(Target, Source)(ref Source s)\nif (isSomeChar!(ElementType!Source) &&\n    isIntegral!Target && !is(Target == enum))\n{\n    static if (Target.sizeof < int.sizeof)\n    {\n        // smaller types are handled like integers\n        auto v = .parse!(Select!(Target.min < 0, int, uint))(s);\n        auto result = ()@trusted{ return cast(Target) v; }();\n        if (result == v)\n            return result;\n        throw new ConvOverflowException(\"Overflow in integral conversion\");\n    }\n    else\n    {\n        // int or larger types\n\n        static if (Target.min < 0)\n            bool sign = false;\n        else\n            enum bool sign = false;\n\n        enum char maxLastDigit = Target.min < 0 ? 7 : 5;\n        uint c;\n\n        static if (isNarrowString!Source)\n        {\n            import std.string : representation;\n            auto source = s.representation;\n        }\n        else\n        {\n            alias source = s;\n        }\n\n        if (source.empty)\n            goto Lerr;\n\n        c = source.front;\n\n        static if (Target.min < 0)\n        {\n            switch (c)\n            {\n                case '-':\n                    sign = true;\n                    goto case '+';\n                case '+':\n                    source.popFront();\n\n                    if (source.empty)\n                        goto Lerr;\n\n                    c = source.front;\n\n                    break;\n\n                default:\n                    break;\n            }\n        }\n        c -= '0';\n        if (c <= 9)\n        {\n            Target v = cast(Target) c;\n\n            source.popFront();\n\n            while (!source.empty)\n            {\n                c = cast(typeof(c)) (source.front - '0');\n\n                if (c > 9)\n                    break;\n\n                if (v >= 0 && (v < Target.max/10 ||\n                    (v == Target.max/10 && c <= maxLastDigit + sign)))\n                {\n                    // Note: `v` can become negative here in case of parsing\n                    // the most negative value:\n                    v = cast(Target) (v * 10 + c);\n\n                    source.popFront();\n                }\n                else\n                    throw new ConvOverflowException(\"Overflow in integral conversion\");\n            }\n\n            if (sign)\n                v = -v;\n\n            static if (isNarrowString!Source)\n                s = cast(Source) source;\n\n            return v;\n        }\nLerr:\n        static if (isNarrowString!Source)\n            throw convError!(Source, Target)(cast(Source) source);\n        else\n            throw convError!(Source, Target)(source);\n    }\n}\n\n///\n@safe pure unittest\n{\n    string s = \"123\";\n    auto a = parse!int(s);\n    assert(a == 123);\n\n    // parse only accepts lvalues\n    static assert(!__traits(compiles, parse!int(\"123\")));\n}\n\n///\n@safe pure unittest\n{\n    import std.string : tr;\n    string test = \"123 \\t  76.14\";\n    auto a = parse!uint(test);\n    assert(a == 123);\n    assert(test == \" \\t  76.14\"); // parse bumps string\n    test = tr(test, \" \\t\\n\\r\", \"\", \"d\"); // skip ws\n    assert(test == \"76.14\");\n    auto b = parse!double(test);\n    assert(b == 76.14);\n    assert(test == \"\");\n}\n\n@safe pure unittest\n{\n    static foreach (Int; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))\n    {\n        {\n            assert(to!Int(\"0\") == 0);\n\n            static if (isSigned!Int)\n            {\n                assert(to!Int(\"+0\") == 0);\n                assert(to!Int(\"-0\") == 0);\n            }\n        }\n\n        static if (Int.sizeof >= byte.sizeof)\n        {\n                assert(to!Int(\"6\") == 6);\n                assert(to!Int(\"23\") == 23);\n                assert(to!Int(\"68\") == 68);\n                assert(to!Int(\"127\") == 0x7F);\n\n            static if (isUnsigned!Int)\n            {\n                assert(to!Int(\"255\") == 0xFF);\n            }\n            static if (isSigned!Int)\n            {\n                assert(to!Int(\"+6\") == 6);\n                assert(to!Int(\"+23\") == 23);\n                assert(to!Int(\"+68\") == 68);\n                assert(to!Int(\"+127\") == 0x7F);\n\n                assert(to!Int(\"-6\") == -6);\n                assert(to!Int(\"-23\") == -23);\n                assert(to!Int(\"-68\") == -68);\n                assert(to!Int(\"-128\") == -128);\n            }\n        }\n\n        static if (Int.sizeof >= short.sizeof)\n        {\n                assert(to!Int(\"468\") == 468);\n                assert(to!Int(\"32767\") == 0x7FFF);\n\n            static if (isUnsigned!Int)\n            {\n                assert(to!Int(\"65535\") == 0xFFFF);\n            }\n            static if (isSigned!Int)\n            {\n                assert(to!Int(\"+468\") == 468);\n                assert(to!Int(\"+32767\") == 0x7FFF);\n\n                assert(to!Int(\"-468\") == -468);\n                assert(to!Int(\"-32768\") == -32768);\n            }\n        }\n\n        static if (Int.sizeof >= int.sizeof)\n        {\n                assert(to!Int(\"2147483647\") == 0x7FFFFFFF);\n\n            static if (isUnsigned!Int)\n            {\n                assert(to!Int(\"4294967295\") == 0xFFFFFFFF);\n            }\n\n            static if (isSigned!Int)\n            {\n                assert(to!Int(\"+2147483647\") == 0x7FFFFFFF);\n\n                assert(to!Int(\"-2147483648\") == -2147483648);\n            }\n        }\n\n        static if (Int.sizeof >= long.sizeof)\n        {\n                assert(to!Int(\"9223372036854775807\") == 0x7FFFFFFFFFFFFFFF);\n\n            static if (isUnsigned!Int)\n            {\n                assert(to!Int(\"18446744073709551615\") == 0xFFFFFFFFFFFFFFFF);\n            }\n\n            static if (isSigned!Int)\n            {\n                assert(to!Int(\"+9223372036854775807\") == 0x7FFFFFFFFFFFFFFF);\n\n                assert(to!Int(\"-9223372036854775808\") == 0x8000000000000000);\n            }\n        }\n    }\n}\n\n@safe pure unittest\n{\n    import std.exception;\n\n    immutable string[] errors =\n    [\n        \"\",\n        \"-\",\n        \"+\",\n        \"-+\",\n        \" \",\n        \" 0\",\n        \"0 \",\n        \"- 0\",\n        \"1-\",\n        \"xx\",\n        \"123h\",\n        \"-+1\",\n        \"--1\",\n        \"+-1\",\n        \"++1\",\n    ];\n\n    immutable string[] unsignedErrors =\n    [\n        \"+5\",\n        \"-78\",\n    ];\n\n    // parsing error check\n    static foreach (Int; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))\n    {\n        foreach (j, s; errors)\n            assertThrown!ConvException(to!Int(s));\n\n        // parse!SomeUnsigned cannot parse head sign.\n        static if (isUnsigned!Int)\n        {\n            foreach (j, s; unsignedErrors)\n                assertThrown!ConvException(to!Int(s));\n        }\n    }\n\n    immutable string[] positiveOverflowErrors =\n    [\n        \"128\",                  // > byte.max\n        \"256\",                  // > ubyte.max\n        \"32768\",                // > short.max\n        \"65536\",                // > ushort.max\n        \"2147483648\",           // > int.max\n        \"4294967296\",           // > uint.max\n        \"9223372036854775808\",  // > long.max\n        \"18446744073709551616\", // > ulong.max\n    ];\n    // positive overflow check\n    static foreach (i, Int; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))\n    {\n        foreach (j, s; positiveOverflowErrors[i..$])\n            assertThrown!ConvOverflowException(to!Int(s));\n    }\n\n    immutable string[] negativeOverflowErrors =\n    [\n        \"-129\",                 // < byte.min\n        \"-32769\",               // < short.min\n        \"-2147483649\",          // < int.min\n        \"-9223372036854775809\", // < long.min\n    ];\n    // negative overflow check\n    static foreach (i, Int; AliasSeq!(byte, short, int, long))\n    {\n        foreach (j, s; negativeOverflowErrors[i..$])\n            assertThrown!ConvOverflowException(to!Int(s));\n    }\n}\n\n@safe pure unittest\n{\n    void checkErrMsg(string input, dchar charInMsg, dchar charNotInMsg)\n    {\n        try\n        {\n            int x = input.to!int();\n            assert(false, \"Invalid conversion did not throw\");\n        }\n        catch (ConvException e)\n        {\n            // Ensure error message contains failing character, not the character\n            // beyond.\n            import std.algorithm.searching : canFind;\n            assert( e.msg.canFind(charInMsg) &&\n                   !e.msg.canFind(charNotInMsg));\n        }\n        catch (Exception e)\n        {\n            assert(false, \"Did not throw ConvException\");\n        }\n    }\n    checkErrMsg(\"@$\", '@', '$');\n    checkErrMsg(\"@$123\", '@', '$');\n    checkErrMsg(\"1@$23\", '@', '$');\n    checkErrMsg(\"1@$\", '@', '$');\n    checkErrMsg(\"1@$2\", '@', '$');\n    checkErrMsg(\"12@$\", '@', '$');\n}\n\n@safe pure unittest\n{\n    import std.exception;\n    assertCTFEable!({ string s =  \"1234abc\"; assert(parse! int(s) ==  1234 && s == \"abc\"); });\n    assertCTFEable!({ string s = \"-1234abc\"; assert(parse! int(s) == -1234 && s == \"abc\"); });\n    assertCTFEable!({ string s =  \"1234abc\"; assert(parse!uint(s) ==  1234 && s == \"abc\"); });\n}\n\n// Issue 13931\n@safe pure unittest\n{\n    import std.exception;\n\n    assertThrown!ConvOverflowException(\"-21474836480\".to!int());\n    assertThrown!ConvOverflowException(\"-92233720368547758080\".to!long());\n}\n\n// Issue 14396\n@safe pure unittest\n{\n    struct StrInputRange\n    {\n        this (string s) { str = s; }\n        char front() const @property { return str[front_index]; }\n        char popFront() { return str[front_index++]; }\n        bool empty() const @property { return str.length <= front_index; }\n        string str;\n        size_t front_index = 0;\n    }\n    auto input = StrInputRange(\"777\");\n    assert(parse!int(input) == 777);\n}\n\n/// ditto\nTarget parse(Target, Source)(ref Source source, uint radix)\nif (isSomeChar!(ElementType!Source) &&\n    isIntegral!Target && !is(Target == enum))\nin\n{\n    assert(radix >= 2 && radix <= 36);\n}\ndo\n{\n    import core.checkedint : mulu, addu;\n    import std.exception : enforce;\n\n    if (radix == 10)\n        return parse!Target(source);\n\n    enforce!ConvException(!source.empty, \"s must not be empty in integral parse\");\n\n    immutable uint beyond = (radix < 10 ? '0' : 'a'-10) + radix;\n    Target v = 0;\n\n    static if (isNarrowString!Source)\n    {\n        import std.string : representation;\n        auto s = source.representation;\n    }\n    else\n    {\n        alias s = source;\n    }\n\n    do\n    {\n        uint c = s.front;\n        if (c < '0')\n            break;\n        if (radix < 10)\n        {\n            if (c >= beyond)\n                break;\n        }\n        else\n        {\n            if (c > '9')\n            {\n                c |= 0x20;//poorman's tolower\n                if (c < 'a' || c >= beyond)\n                    break;\n                c -= 'a'-10-'0';\n            }\n        }\n\n        bool overflow = false;\n        auto nextv = v.mulu(radix, overflow).addu(c - '0', overflow);\n        enforce!ConvOverflowException(!overflow && nextv <= Target.max, \"Overflow in integral conversion\");\n        v = cast(Target) nextv;\n        s.popFront();\n    } while (!s.empty);\n\n    static if (isNarrowString!Source)\n        source = cast(Source) s;\n\n    return v;\n}\n\n@safe pure unittest\n{\n    string s; // parse doesn't accept rvalues\n    foreach (i; 2 .. 37)\n    {\n        assert(parse!int(s = \"0\", i) == 0);\n        assert(parse!int(s = \"1\", i) == 1);\n        assert(parse!byte(s = \"10\", i) == i);\n    }\n\n    assert(parse!int(s = \"0011001101101\", 2) == 0b0011001101101);\n    assert(parse!int(s = \"765\", 8) == octal!765);\n    assert(parse!int(s = \"fCDe\", 16) == 0xfcde);\n\n    // 6609\n    assert(parse!int(s = \"-42\", 10) == -42);\n\n    assert(parse!ubyte(s = \"ff\", 16) == 0xFF);\n}\n\n@safe pure unittest // bugzilla 7302\n{\n    import std.range : cycle;\n    auto r = cycle(\"2A!\");\n    auto u = parse!uint(r, 16);\n    assert(u == 42);\n    assert(r.front == '!');\n}\n\n@safe pure unittest // bugzilla 13163\n{\n    import std.exception;\n    foreach (s; [\"fff\", \"123\"])\n        assertThrown!ConvOverflowException(s.parse!ubyte(16));\n}\n\n@safe pure unittest // bugzilla 17282\n{\n    auto str = \"0=\\x00\\x02\\x55\\x40&\\xff\\xf0\\n\\x00\\x04\\x55\\x40\\xff\\xf0~4+10\\n\";\n    assert(parse!uint(str) == 0);\n}\n\n/**\n * Takes a string representing an `enum` type and returns that type.\n *\n * Params:\n *     Target = the `enum` type to convert to\n *     s = the lvalue of the range to _parse\n *\n * Returns:\n *     An `enum` of type `Target`\n *\n * Throws:\n *     A $(LREF ConvException) if type `Target` does not have a member\n *     represented by `s`.\n */\nTarget parse(Target, Source)(ref Source s)\nif (isSomeString!Source && !is(Source == enum) &&\n    is(Target == enum))\n{\n    import std.algorithm.searching : startsWith;\n    Target result;\n    size_t longest_match = 0;\n\n    foreach (i, e; EnumMembers!Target)\n    {\n        auto ident = __traits(allMembers, Target)[i];\n        if (longest_match < ident.length && s.startsWith(ident))\n        {\n            result = e;\n            longest_match = ident.length ;\n        }\n    }\n\n    if (longest_match > 0)\n    {\n        s = s[longest_match .. $];\n        return result ;\n    }\n\n    throw new ConvException(\n        Target.stringof ~ \" does not have a member named '\"\n        ~ to!string(s) ~ \"'\");\n}\n\n///\n@safe unittest\n{\n    enum EnumType : bool { a = true, b = false, c = a }\n\n    auto str = \"a\";\n    assert(parse!EnumType(str) == EnumType.a);\n}\n\n@safe unittest\n{\n    import std.exception;\n\n    enum EB : bool { a = true, b = false, c = a }\n    enum EU { a, b, c }\n    enum EI { a = -1, b = 0, c = 1 }\n    enum EF : real { a = 1.414, b = 1.732, c = 2.236 }\n    enum EC : char { a = 'a', b = 'b', c = 'c' }\n    enum ES : string { a = \"aaa\", b = \"bbb\", c = \"ccc\" }\n\n    static foreach (E; AliasSeq!(EB, EU, EI, EF, EC, ES))\n    {\n        assert(to!E(\"a\"c) == E.a);\n        assert(to!E(\"b\"w) == E.b);\n        assert(to!E(\"c\"d) == E.c);\n\n        assertThrown!ConvException(to!E(\"d\"));\n    }\n}\n\n@safe pure unittest // bugzilla 4744\n{\n    enum A { member1, member11, member111 }\n    assert(to!A(\"member1\"  ) == A.member1  );\n    assert(to!A(\"member11\" ) == A.member11 );\n    assert(to!A(\"member111\") == A.member111);\n    auto s = \"member1111\";\n    assert(parse!A(s) == A.member111 && s == \"1\");\n}\n\n/**\n * Parses a character range to a floating point number.\n *\n * Params:\n *     Target = a floating point type\n *     source = the lvalue of the range to _parse\n *\n * Returns:\n *     A floating point number of type `Target`\n *\n * Throws:\n *     A $(LREF ConvException) if `source` is empty, if no number could be\n *     parsed, or if an overflow occurred.\n */\nTarget parse(Target, Source)(ref Source source)\nif (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&\n    isFloatingPoint!Target && !is(Target == enum))\n{\n    import std.ascii : isDigit, isAlpha, toLower, toUpper, isHexDigit;\n    import std.exception : enforce;\n\n    static if (isNarrowString!Source)\n    {\n        import std.string : representation;\n        auto p = source.representation;\n    }\n    else\n    {\n        alias p = source;\n    }\n\n    static immutable real[14] negtab =\n        [ 1e-4096L,1e-2048L,1e-1024L,1e-512L,1e-256L,1e-128L,1e-64L,1e-32L,\n                1e-16L,1e-8L,1e-4L,1e-2L,1e-1L,1.0L ];\n    static immutable real[13] postab =\n        [ 1e+4096L,1e+2048L,1e+1024L,1e+512L,1e+256L,1e+128L,1e+64L,1e+32L,\n                1e+16L,1e+8L,1e+4L,1e+2L,1e+1L ];\n\n    ConvException bailOut()(string msg = null, string fn = __FILE__, size_t ln = __LINE__)\n    {\n        if (msg == null)\n            msg = \"Floating point conversion error\";\n        return new ConvException(text(msg, \" for input \\\"\", source, \"\\\".\"), fn, ln);\n    }\n\n\n    enforce(!p.empty, bailOut());\n\n    bool sign = false;\n    switch (p.front)\n    {\n    case '-':\n        sign = true;\n        p.popFront();\n        enforce(!p.empty, bailOut());\n        if (toLower(p.front) == 'i')\n            goto case 'i';\n        break;\n    case '+':\n        p.popFront();\n        enforce(!p.empty, bailOut());\n        break;\n    case 'i': case 'I':\n        // inf\n        p.popFront();\n        enforce(!p.empty && toUpper(p.front) == 'N',\n               bailOut(\"error converting input to floating point\"));\n        p.popFront();\n        enforce(!p.empty && toUpper(p.front) == 'F',\n               bailOut(\"error converting input to floating point\"));\n        // skip past the last 'f'\n        p.popFront();\n        static if (isNarrowString!Source)\n            source = cast(Source) p;\n        return sign ? -Target.infinity : Target.infinity;\n    default: {}\n    }\n\n    bool isHex = false;\n    bool startsWithZero = p.front == '0';\n    if (startsWithZero)\n    {\n        p.popFront();\n        if (p.empty)\n        {\n            static if (isNarrowString!Source)\n                source = cast(Source) p;\n            return sign ? -0.0 : 0.0;\n        }\n\n        isHex = p.front == 'x' || p.front == 'X';\n        if (isHex) p.popFront();\n    }\n    else if (toLower(p.front) == 'n')\n    {\n        // nan\n        p.popFront();\n        enforce(!p.empty && toUpper(p.front) == 'A',\n               bailOut(\"error converting input to floating point\"));\n        p.popFront();\n        enforce(!p.empty && toUpper(p.front) == 'N',\n               bailOut(\"error converting input to floating point\"));\n        // skip past the last 'n'\n        p.popFront();\n        static if (isNarrowString!Source)\n            source = cast(Source) p;\n        return typeof(return).nan;\n    }\n\n    /*\n     * The following algorithm consists of 2 steps:\n     * 1) parseDigits processes the textual input into msdec and possibly\n     *    lsdec/msscale variables, followed by the exponent parser which sets\n     *    exp below.\n     *    Hex: input is 0xaaaaa...p+000... where aaaa is the mantissa in hex\n     *    and 000 is the exponent in decimal format with base 2.\n     *    Decimal: input is 0.00333...p+000... where 0.0033 is the mantissa\n     *    in decimal and 000 is the exponent in decimal format with base 10.\n     * 2) Convert msdec/lsdec and exp into native real format\n     */\n\n    real ldval = 0.0;\n    char dot = 0;                        /* if decimal point has been seen */\n    int exp = 0;\n    ulong msdec = 0, lsdec = 0;\n    ulong msscale = 1;\n    bool sawDigits;\n\n    enum { hex, decimal }\n\n    // sets msdec, lsdec/msscale, and sawDigits by parsing the mantissa digits\n    void parseDigits(alias FloatFormat)()\n    {\n        static if (FloatFormat == hex)\n        {\n            enum uint base = 16;\n            enum ulong msscaleMax = 0x1000_0000_0000_0000UL; // largest power of 16 a ulong holds\n            enum ubyte expIter = 4; // iterate the base-2 exponent by 4 for every hex digit\n            alias checkDigit = isHexDigit;\n            /*\n             * convert letter to binary representation: First clear bit\n             * to convert lower space chars to upperspace, then -('A'-10)\n             * converts letter A to 10, letter B to 11, ...\n             */\n            alias convertDigit = (int x) => isAlpha(x) ? ((x & ~0x20) - ('A' - 10)) : x - '0';\n            sawDigits = false;\n        }\n        else static if (FloatFormat == decimal)\n        {\n            enum uint base = 10;\n            enum ulong msscaleMax = 10_000_000_000_000_000_000UL; // largest power of 10 a ulong holds\n            enum ubyte expIter = 1; // iterate the base-10 exponent once for every decimal digit\n            alias checkDigit = isDigit;\n            alias convertDigit = (int x) => x - '0';\n            // Used to enforce that any mantissa digits are present\n            sawDigits = startsWithZero;\n        }\n        else\n            static assert(false, \"Unrecognized floating-point format used.\");\n\n        while (!p.empty)\n        {\n            int i = p.front;\n            while (checkDigit(i))\n            {\n                sawDigits = true;        /* must have at least 1 digit   */\n\n                i = convertDigit(i);\n\n                if (msdec < (ulong.max - base)/base)\n                {\n                    // For base 16: Y = ... + y3*16^3 + y2*16^2 + y1*16^1 + y0*16^0\n                    msdec = msdec * base + i;\n                }\n                else if (msscale < msscaleMax)\n                {\n                    lsdec = lsdec * base + i;\n                    msscale *= base;\n                }\n                else\n                {\n                    exp += expIter;\n                }\n                exp -= dot;\n                p.popFront();\n                if (p.empty)\n                    break;\n                i = p.front;\n                if (i == '_')\n                {\n                    p.popFront();\n                    if (p.empty)\n                        break;\n                    i = p.front;\n                }\n            }\n            if (i == '.' && !dot)\n            {\n                p.popFront();\n                dot += expIter;\n            }\n            else\n                break;\n        }\n\n        // Have we seen any mantissa digits so far?\n        enforce(sawDigits, bailOut(\"no digits seen\"));\n        static if (FloatFormat == hex)\n            enforce(!p.empty && (p.front == 'p' || p.front == 'P'),\n                    bailOut(\"Floating point parsing: exponent is required\"));\n    }\n\n    if (isHex)\n        parseDigits!hex;\n    else\n        parseDigits!decimal;\n\n    if (isHex || (!p.empty && (p.front == 'e' || p.front == 'E')))\n    {\n        char sexp = 0;\n        int e = 0;\n\n        p.popFront();\n        enforce(!p.empty, new ConvException(\"Unexpected end of input\"));\n        switch (p.front)\n        {\n            case '-':    sexp++;\n                         goto case;\n            case '+':    p.popFront();\n                         break;\n            default: {}\n        }\n        sawDigits = false;\n        while (!p.empty && isDigit(p.front))\n        {\n            if (e < 0x7FFFFFFF / 10 - 10)   // prevent integer overflow\n            {\n                e = e * 10 + p.front - '0';\n            }\n            p.popFront();\n            sawDigits = true;\n        }\n        exp += (sexp) ? -e : e;\n        enforce(sawDigits, new ConvException(\"No digits seen.\"));\n    }\n\n    ldval = msdec;\n    if (msscale != 1)               /* if stuff was accumulated in lsdec */\n        ldval = ldval * msscale + lsdec;\n    if (isHex)\n    {\n        import std.math : ldexp;\n\n        // Exponent is power of 2, not power of 10\n        ldval = ldexp(ldval,exp);\n    }\n    else if (ldval)\n    {\n        uint u = 0;\n        int pow = 4096;\n\n        while (exp > 0)\n        {\n            while (exp >= pow)\n            {\n                ldval *= postab[u];\n                exp -= pow;\n            }\n            pow >>= 1;\n            u++;\n        }\n        while (exp < 0)\n        {\n            while (exp <= -pow)\n            {\n                ldval *= negtab[u];\n                enforce(ldval != 0, new ConvException(\"Range error\"));\n                exp += pow;\n            }\n            pow >>= 1;\n            u++;\n        }\n    }\n\n    // if overflow occurred\n    enforce(ldval != real.infinity, new ConvException(\"Range error\"));\n\n    static if (isNarrowString!Source)\n        source = cast(Source) p;\n    return sign ? -ldval : ldval;\n}\n\n///\n@safe unittest\n{\n    import std.math : approxEqual;\n    auto str = \"123.456\";\n\n    assert(parse!double(str).approxEqual(123.456));\n}\n\n@safe unittest\n{\n    import std.exception;\n    import std.math : isNaN, fabs;\n\n    // Compare reals with given precision\n    bool feq(in real rx, in real ry, in real precision = 0.000001L)\n    {\n        if (rx == ry)\n            return 1;\n\n        if (isNaN(rx))\n            return cast(bool) isNaN(ry);\n\n        if (isNaN(ry))\n            return 0;\n\n        return cast(bool)(fabs(rx - ry) <= precision);\n    }\n\n    // Make given typed literal\n    F Literal(F)(F f)\n    {\n        return f;\n    }\n\n    static foreach (Float; AliasSeq!(float, double, real))\n    {\n        assert(to!Float(\"123\") == Literal!Float(123));\n        assert(to!Float(\"+123\") == Literal!Float(+123));\n        assert(to!Float(\"-123\") == Literal!Float(-123));\n        assert(to!Float(\"123e2\") == Literal!Float(123e2));\n        assert(to!Float(\"123e+2\") == Literal!Float(123e+2));\n        assert(to!Float(\"123e-2\") == Literal!Float(123e-2));\n        assert(to!Float(\"123.\") == Literal!Float(123.0));\n        assert(to!Float(\".375\") == Literal!Float(.375));\n\n        assert(to!Float(\"1.23375E+2\") == Literal!Float(1.23375E+2));\n\n        assert(to!Float(\"0\") is 0.0);\n        assert(to!Float(\"-0\") is -0.0);\n\n        assert(isNaN(to!Float(\"nan\")));\n\n        assertThrown!ConvException(to!Float(\"\\x00\"));\n    }\n\n    // min and max\n    float f = to!float(\"1.17549e-38\");\n    assert(feq(cast(real) f, cast(real) 1.17549e-38));\n    assert(feq(cast(real) f, cast(real) float.min_normal));\n    f = to!float(\"3.40282e+38\");\n    assert(to!string(f) == to!string(3.40282e+38));\n\n    // min and max\n    double d = to!double(\"2.22508e-308\");\n    assert(feq(cast(real) d, cast(real) 2.22508e-308));\n    assert(feq(cast(real) d, cast(real) double.min_normal));\n    d = to!double(\"1.79769e+308\");\n    assert(to!string(d) == to!string(1.79769e+308));\n    assert(to!string(d) == to!string(double.max));\n\n    assert(to!string(to!real(to!string(real.max / 2L))) == to!string(real.max / 2L));\n\n    // min and max\n    real r = to!real(to!string(real.min_normal));\n    version (NetBSD)\n    {\n        // NetBSD notice\n        // to!string returns 3.3621e-4932L. It is less than real.min_normal and it is subnormal value\n        // Simple C code\n        //     long double rd = 3.3621e-4932L;\n        //     printf(\"%Le\\n\", rd);\n        // has unexpected result: 1.681050e-4932\n        //\n        // Bug report: http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=50937\n    }\n    else\n    {\n        assert(to!string(r) == to!string(real.min_normal));\n    }\n    r = to!real(to!string(real.max));\n    assert(to!string(r) == to!string(real.max));\n\n    real pi = 3.1415926535897932384626433832795028841971693993751;\n    string fullPrecision = \"3.1415926535897932384626433832795028841971693993751\";\n    assert(feq(parse!real(fullPrecision), pi, 2*real.epsilon));\n\n    real x = 0x1.FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAAFAAFAFAFAFAFAFAFAP-252;\n    string full = \"0x1.FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAAFAAFAFAFAFAFAFAFAP-252\";\n    assert(parse!real(full) == x);\n}\n\n// Tests for the double implementation\n@system unittest\n{\n    // @system because strtod is not @safe.\n    static if (real.mant_dig == 53)\n    {\n        import core.stdc.stdlib, std.exception, std.math;\n\n        //Should be parsed exactly: 53 bit mantissa\n        string s = \"0x1A_BCDE_F012_3456p10\";\n        auto x = parse!real(s);\n        assert(x == 0x1A_BCDE_F012_3456p10L);\n        //1 bit is implicit\n        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0xA_BCDE_F012_3456);\n        assert(strtod(\"0x1ABCDEF0123456p10\", null) == x);\n\n        //Should be parsed exactly: 10 bit mantissa\n        s = \"0x3FFp10\";\n        x = parse!real(s);\n        assert(x == 0x03FFp10);\n        //1 bit is implicit\n        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_F800_0000_0000);\n        assert(strtod(\"0x3FFp10\", null) == x);\n\n        //60 bit mantissa, round up\n        s = \"0xFFF_FFFF_FFFF_FFFFp10\";\n        x = parse!real(s);\n        assert(approxEqual(x, 0xFFF_FFFF_FFFF_FFFFp10));\n        //1 bit is implicit\n        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x0000_0000_0000_0000);\n        assert(strtod(\"0xFFFFFFFFFFFFFFFp10\", null) == x);\n\n        //60 bit mantissa, round down\n        s = \"0xFFF_FFFF_FFFF_FF90p10\";\n        x = parse!real(s);\n        assert(approxEqual(x, 0xFFF_FFFF_FFFF_FF90p10));\n        //1 bit is implicit\n        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_FFFF_FFFF_FFFF);\n        assert(strtod(\"0xFFFFFFFFFFFFF90p10\", null) == x);\n\n        //61 bit mantissa, round up 2\n        s = \"0x1F0F_FFFF_FFFF_FFFFp10\";\n        x = parse!real(s);\n        assert(approxEqual(x, 0x1F0F_FFFF_FFFF_FFFFp10));\n        //1 bit is implicit\n        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_1000_0000_0000);\n        assert(strtod(\"0x1F0FFFFFFFFFFFFFp10\", null) == x);\n\n        //61 bit mantissa, round down 2\n        s = \"0x1F0F_FFFF_FFFF_FF10p10\";\n        x = parse!real(s);\n        assert(approxEqual(x, 0x1F0F_FFFF_FFFF_FF10p10));\n        //1 bit is implicit\n        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_0FFF_FFFF_FFFF);\n        assert(strtod(\"0x1F0FFFFFFFFFFF10p10\", null) == x);\n\n        //Huge exponent\n        s = \"0x1F_FFFF_FFFF_FFFFp900\";\n        x = parse!real(s);\n        assert(strtod(\"0x1FFFFFFFFFFFFFp900\", null) == x);\n\n        //exponent too big -> converror\n        s = \"\";\n        assertThrown!ConvException(x = parse!real(s));\n        assert(strtod(\"0x1FFFFFFFFFFFFFp1024\", null) == real.infinity);\n\n        //-exponent too big -> 0\n        s = \"0x1FFFFFFFFFFFFFp-2000\";\n        x = parse!real(s);\n        assert(x == 0);\n        assert(strtod(\"0x1FFFFFFFFFFFFFp-2000\", null) == x);\n    }\n}\n\n@system unittest\n{\n    import core.stdc.errno;\n    import core.stdc.stdlib;\n    import std.math : floatTraits, RealFormat;\n\n    errno = 0;  // In case it was set by another unittest in a different module.\n    struct longdouble\n    {\n        static if (floatTraits!real.realFormat == RealFormat.ieeeQuadruple)\n        {\n            ushort[8] value;\n        }\n        else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended)\n        {\n            ushort[5] value;\n        }\n        else static if (floatTraits!real.realFormat == RealFormat.ieeeDouble)\n        {\n            ushort[4] value;\n        }\n        else\n            static assert(false, \"Not implemented\");\n    }\n\n    real ld;\n    longdouble x;\n    real ld1;\n    longdouble x1;\n    int i;\n\n    static if (floatTraits!real.realFormat == RealFormat.ieeeQuadruple)\n        enum s = \"0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-16382\";\n    else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended)\n        enum s = \"0x1.FFFFFFFFFFFFFFFEp-16382\";\n    else static if (floatTraits!real.realFormat == RealFormat.ieeeDouble)\n        enum s = \"0x1.FFFFFFFFFFFFFFFEp-1000\";\n    else\n        static assert(false, \"Floating point format for real not supported\");\n\n    auto s2 = s.idup;\n    ld = parse!real(s2);\n    assert(s2.empty);\n    x = *cast(longdouble *)&ld;\n\n    static if (floatTraits!real.realFormat == RealFormat.ieeeExtended)\n    {\n        version (CRuntime_Microsoft)\n            ld1 = 0x1.FFFFFFFFFFFFFFFEp-16382L; // strtold currently mapped to strtod\n        else\n            ld1 = strtold(s.ptr, null);\n    }\n    else\n        ld1 = strtold(s.ptr, null);\n\n    x1 = *cast(longdouble *)&ld1;\n    assert(x1 == x && ld1 == ld);\n\n    assert(!errno);\n\n    s2 = \"1.0e5\";\n    ld = parse!real(s2);\n    assert(s2.empty);\n    x = *cast(longdouble *)&ld;\n    ld1 = strtold(\"1.0e5\", null);\n    x1 = *cast(longdouble *)&ld1;\n}\n\n@safe pure unittest\n{\n    import std.exception;\n\n    // Bugzilla 4959\n    {\n        auto s = \"0 \";\n        auto x = parse!double(s);\n        assert(s == \" \");\n        assert(x == 0.0);\n    }\n\n    // Bugzilla 3369\n    assert(to!float(\"inf\") == float.infinity);\n    assert(to!float(\"-inf\") == -float.infinity);\n\n    // Bugzilla 6160\n    assert(6_5.536e3L == to!real(\"6_5.536e3\"));                     // 2^16\n    assert(0x1000_000_000_p10 == to!real(\"0x1000_000_000_p10\"));    // 7.03687e+13\n\n    // Bugzilla 6258\n    assertThrown!ConvException(to!real(\"-\"));\n    assertThrown!ConvException(to!real(\"in\"));\n\n    // Bugzilla 7055\n    assertThrown!ConvException(to!float(\"INF2\"));\n\n    //extra stress testing\n    auto ssOK    = [\"1.\", \"1.1.1\", \"1.e5\", \"2e1e\", \"2a\", \"2e1_1\", \"3.4_\",\n                    \"inf\", \"-inf\", \"infa\", \"-infa\", \"inf2e2\", \"-inf2e2\",\n                    \"nan\", \"-NAN\", \"+NaN\", \"-nAna\", \"NAn2e2\", \"-naN2e2\"];\n    auto ssKO    = [\"\", \" \", \"2e\", \"2e+\", \"2e-\", \"2ee\", \"2e++1\", \"2e--1\", \"2e_1\",\n                    \"+inf\", \"-in\", \"I\", \"+N\", \"-NaD\", \"0x3.F\"];\n    foreach (s; ssOK)\n        parse!double(s);\n    foreach (s; ssKO)\n        assertThrown!ConvException(parse!double(s));\n}\n\n/**\nParsing one character off a range returns the first element and calls `popFront`.\n\nParams:\n    Target = the type to convert to\n    s = the lvalue of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n\nReturns:\n    A character of type `Target`\n\nThrows:\n    A $(LREF ConvException) if the range is empty.\n */\nTarget parse(Target, Source)(ref Source s)\nif (isSomeString!Source && !is(Source == enum) &&\n    staticIndexOf!(Unqual!Target, dchar, Unqual!(ElementEncodingType!Source)) >= 0)\n{\n    if (s.empty)\n        throw convError!(Source, Target)(s);\n    static if (is(Unqual!Target == dchar))\n    {\n        Target result = s.front;\n        s.popFront();\n        return result;\n    }\n    else\n    {\n        // Special case: okay so parse a Char off a Char[]\n        Target result = s[0];\n        s = s[1 .. $];\n        return result;\n    }\n}\n\n@safe pure unittest\n{\n    static foreach (Str; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (Char; AliasSeq!(char, wchar, dchar))\n        {{\n            static if (is(Unqual!Char == dchar) ||\n                       Char.sizeof == ElementEncodingType!Str.sizeof)\n            {\n                Str s = \"aaa\";\n                assert(parse!Char(s) == 'a');\n                assert(s == \"aa\");\n            }\n        }}\n    }\n}\n\n/// ditto\nTarget parse(Target, Source)(ref Source s)\nif (!isSomeString!Source && isInputRange!Source && isSomeChar!(ElementType!Source) &&\n    isSomeChar!Target && Target.sizeof >= ElementType!Source.sizeof && !is(Target == enum))\n{\n    if (s.empty)\n        throw convError!(Source, Target)(s);\n    Target result = s.front;\n    s.popFront();\n    return result;\n}\n\n///\n@safe pure unittest\n{\n    auto s = \"Hello, World!\";\n    char first = parse!char(s);\n    assert(first == 'H');\n    assert(s == \"ello, World!\");\n}\n\n\n/*\n    Tests for to!bool and parse!bool\n*/\n@safe pure unittest\n{\n    import std.exception;\n\n    assert(to!bool(\"TruE\") == true);\n    assert(to!bool(\"faLse\"d) == false);\n    assertThrown!ConvException(to!bool(\"maybe\"));\n\n    auto t = \"TrueType\";\n    assert(parse!bool(t) == true);\n    assert(t == \"Type\");\n\n    auto f = \"False killer whale\"d;\n    assert(parse!bool(f) == false);\n    assert(f == \" killer whale\"d);\n\n    auto m = \"maybe\";\n    assertThrown!ConvException(parse!bool(m));\n    assert(m == \"maybe\");  // m shouldn't change on failure\n\n    auto s = \"true\";\n    auto b = parse!(const(bool))(s);\n    assert(b == true);\n}\n\n/**\nParsing a character range to `typeof(null)` returns `null` if the range\nspells `\"null\"`. This function is case insensitive.\n\nParams:\n    Target = the type to convert to\n    s = the lvalue of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n\nReturns:\n    `null`\n\nThrows:\n    A $(LREF ConvException) if the range doesn't represent `null`.\n */\nTarget parse(Target, Source)(ref Source s)\nif (isInputRange!Source &&\n    isSomeChar!(ElementType!Source) &&\n    is(Unqual!Target == typeof(null)))\n{\n    import std.ascii : toLower;\n    foreach (c; \"null\")\n    {\n        if (s.empty || toLower(s.front) != c)\n            throw parseError(\"null should be case-insensitive 'null'\");\n        s.popFront();\n    }\n    return null;\n}\n\n///\n@safe pure unittest\n{\n    import std.exception : assertThrown;\n\n    alias NullType = typeof(null);\n    auto s1 = \"null\";\n    assert(parse!NullType(s1) is null);\n    assert(s1 == \"\");\n\n    auto s2 = \"NUll\"d;\n    assert(parse!NullType(s2) is null);\n    assert(s2 == \"\");\n\n    auto m = \"maybe\";\n    assertThrown!ConvException(parse!NullType(m));\n    assert(m == \"maybe\");  // m shouldn't change on failure\n\n    auto s = \"NULL\";\n    assert(parse!(const NullType)(s) is null);\n}\n\n//Used internally by parse Array/AA, to remove ascii whites\npackage void skipWS(R)(ref R r)\n{\n    import std.ascii : isWhite;\n    static if (isSomeString!R)\n    {\n        //Implementation inspired from stripLeft.\n        foreach (i, c; r)\n        {\n            if (!isWhite(c))\n            {\n                r = r[i .. $];\n                return;\n            }\n        }\n        r = r[0 .. 0]; //Empty string with correct type.\n        return;\n    }\n    else\n    {\n        for (; !r.empty && isWhite(r.front); r.popFront())\n        {}\n    }\n}\n\n/**\n * Parses an array from a string given the left bracket (default $(D\n * '[')), right bracket (default `']'`), and element separator (by\n * default `','`). A trailing separator is allowed.\n *\n * Params:\n *     s = The string to parse\n *     lbracket = the character that starts the array\n *     rbracket = the character that ends the array\n *     comma = the character that separates the elements of the array\n *\n * Returns:\n *     An array of type `Target`\n */\nTarget parse(Target, Source)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar comma = ',')\nif (isSomeString!Source && !is(Source == enum) &&\n    isDynamicArray!Target && !is(Target == enum))\n{\n    import std.array : appender;\n\n    auto result = appender!Target();\n\n    parseCheck!s(lbracket);\n    skipWS(s);\n    if (s.empty)\n        throw convError!(Source, Target)(s);\n    if (s.front == rbracket)\n    {\n        s.popFront();\n        return result.data;\n    }\n    for (;; s.popFront(), skipWS(s))\n    {\n        if (!s.empty && s.front == rbracket)\n            break;\n        result ~= parseElement!(ElementType!Target)(s);\n        skipWS(s);\n        if (s.empty)\n            throw convError!(Source, Target)(s);\n        if (s.front != comma)\n            break;\n    }\n    parseCheck!s(rbracket);\n\n    return result.data;\n}\n\n///\n@safe pure unittest\n{\n    auto s1 = `[['h', 'e', 'l', 'l', 'o'], \"world\"]`;\n    auto a1 = parse!(string[])(s1);\n    assert(a1 == [\"hello\", \"world\"]);\n\n    auto s2 = `[\"aaa\", \"bbb\", \"ccc\"]`;\n    auto a2 = parse!(string[])(s2);\n    assert(a2 == [\"aaa\", \"bbb\", \"ccc\"]);\n}\n\n@safe unittest // Bugzilla 9615\n{\n    string s0 = \"[1,2, ]\";\n    string s1 = \"[1,2, \\t\\v\\r\\n]\";\n    string s2 = \"[1,2]\";\n    assert(s0.parse!(int[]) == [1,2]);\n    assert(s1.parse!(int[]) == [1,2]);\n    assert(s2.parse!(int[]) == [1,2]);\n\n    string s3 = `[\"a\",\"b\",]`;\n    string s4 = `[\"a\",\"b\"]`;\n    assert(s3.parse!(string[]) == [\"a\",\"b\"]);\n    assert(s4.parse!(string[]) == [\"a\",\"b\"]);\n\n    import std.exception : assertThrown;\n    string s5 = \"[,]\";\n    string s6 = \"[, \\t,]\";\n    assertThrown!ConvException(parse!(string[])(s5));\n    assertThrown!ConvException(parse!(int[])(s6));\n}\n\n@safe unittest\n{\n    int[] a = [1, 2, 3, 4, 5];\n    auto s = to!string(a);\n    assert(to!(int[])(s) == a);\n}\n\n@safe unittest\n{\n    int[][] a = [ [1, 2] , [3], [4, 5] ];\n    auto s = to!string(a);\n    assert(to!(int[][])(s) == a);\n}\n\n@safe unittest\n{\n    int[][][] ia = [ [[1,2],[3,4],[5]] , [[6],[],[7,8,9]] , [[]] ];\n\n    char[] s = to!(char[])(ia);\n    int[][][] ia2;\n\n    ia2 = to!(typeof(ia2))(s);\n    assert( ia == ia2);\n}\n\n@safe pure unittest\n{\n    import std.exception;\n\n    //Check proper failure\n    auto s = \"[ 1 , 2 , 3 ]\";\n    foreach (i ; 0 .. s.length-1)\n    {\n        auto ss = s[0 .. i];\n        assertThrown!ConvException(parse!(int[])(ss));\n    }\n    int[] arr = parse!(int[])(s);\n}\n\n@safe pure unittest\n{\n    //Checks parsing of strings with escaped characters\n    string s1 = `[\n        \"Contains a\\0null!\",\n        \"tab\\there\",\n        \"line\\nbreak\",\n        \"backslash \\\\ slash / question \\?\",\n        \"number \\x35 five\",\n        \"unicode \\u65E5 sun\",\n        \"very long \\U000065E5 sun\"\n    ]`;\n\n    //Note: escaped characters purposefully replaced and isolated to guarantee\n    //there are no typos in the escape syntax\n    string[] s2 = [\n        \"Contains a\" ~ '\\0' ~ \"null!\",\n        \"tab\" ~ '\\t' ~ \"here\",\n        \"line\" ~ '\\n' ~ \"break\",\n        \"backslash \" ~ '\\\\' ~ \" slash / question ?\",\n        \"number 5 five\",\n        \"unicode 日 sun\",\n        \"very long 日 sun\"\n    ];\n    assert(s2 == parse!(string[])(s1));\n    assert(s1.empty);\n}\n\n/// ditto\nTarget parse(Target, Source)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar comma = ',')\nif (isExactSomeString!Source &&\n    isStaticArray!Target && !is(Target == enum))\n{\n    static if (hasIndirections!Target)\n        Target result = Target.init[0].init;\n    else\n        Target result = void;\n\n    parseCheck!s(lbracket);\n    skipWS(s);\n    if (s.empty)\n        throw convError!(Source, Target)(s);\n    if (s.front == rbracket)\n    {\n        static if (result.length != 0)\n            goto Lmanyerr;\n        else\n        {\n            s.popFront();\n            return result;\n        }\n    }\n    for (size_t i = 0; ; s.popFront(), skipWS(s))\n    {\n        if (i == result.length)\n            goto Lmanyerr;\n        result[i++] = parseElement!(ElementType!Target)(s);\n        skipWS(s);\n        if (s.empty)\n            throw convError!(Source, Target)(s);\n        if (s.front != comma)\n        {\n            if (i != result.length)\n                goto Lfewerr;\n            break;\n        }\n    }\n    parseCheck!s(rbracket);\n\n    return result;\n\nLmanyerr:\n    throw parseError(text(\"Too many elements in input, \", result.length, \" elements expected.\"));\n\nLfewerr:\n    throw parseError(text(\"Too few elements in input, \", result.length, \" elements expected.\"));\n}\n\n@safe pure unittest\n{\n    import std.exception;\n\n    auto s1 = \"[1,2,3,4]\";\n    auto sa1 = parse!(int[4])(s1);\n    assert(sa1 == [1,2,3,4]);\n\n    auto s2 = \"[[1],[2,3],[4]]\";\n    auto sa2 = parse!(int[][3])(s2);\n    assert(sa2 == [[1],[2,3],[4]]);\n\n    auto s3 = \"[1,2,3]\";\n    assertThrown!ConvException(parse!(int[4])(s3));\n\n    auto s4 = \"[1,2,3,4,5]\";\n    assertThrown!ConvException(parse!(int[4])(s4));\n}\n\n/**\n * Parses an associative array from a string given the left bracket (default $(D\n * '[')), right bracket (default `']'`), key-value separator (default $(D\n * ':')), and element seprator (by default `','`).\n *\n * Params:\n *     s = the string to parse\n *     lbracket = the character that starts the associative array\n *     rbracket = the character that ends the associative array\n *     keyval = the character that associates the key with the value\n *     comma = the character that separates the elements of the associative array\n *\n * Returns:\n *     An associative array of type `Target`\n */\nTarget parse(Target, Source)(ref Source s, dchar lbracket = '[',\n                             dchar rbracket = ']', dchar keyval = ':', dchar comma = ',')\nif (isSomeString!Source && !is(Source == enum) &&\n    isAssociativeArray!Target && !is(Target == enum))\n{\n    alias KeyType = typeof(Target.init.keys[0]);\n    alias ValType = typeof(Target.init.values[0]);\n\n    Target result;\n\n    parseCheck!s(lbracket);\n    skipWS(s);\n    if (s.empty)\n        throw convError!(Source, Target)(s);\n    if (s.front == rbracket)\n    {\n        s.popFront();\n        return result;\n    }\n    for (;; s.popFront(), skipWS(s))\n    {\n        auto key = parseElement!KeyType(s);\n        skipWS(s);\n        parseCheck!s(keyval);\n        skipWS(s);\n        auto val = parseElement!ValType(s);\n        skipWS(s);\n        result[key] = val;\n        if (s.empty)\n            throw convError!(Source, Target)(s);\n        if (s.front != comma)\n            break;\n    }\n    parseCheck!s(rbracket);\n\n    return result;\n}\n\n///\n@safe pure unittest\n{\n    auto s1 = \"[1:10, 2:20, 3:30]\";\n    auto aa1 = parse!(int[int])(s1);\n    assert(aa1 == [1:10, 2:20, 3:30]);\n\n    auto s2 = `[\"aaa\":10, \"bbb\":20, \"ccc\":30]`;\n    auto aa2 = parse!(int[string])(s2);\n    assert(aa2 == [\"aaa\":10, \"bbb\":20, \"ccc\":30]);\n\n    auto s3 = `[\"aaa\":[1], \"bbb\":[2,3], \"ccc\":[4,5,6]]`;\n    auto aa3 = parse!(int[][string])(s3);\n    assert(aa3 == [\"aaa\":[1], \"bbb\":[2,3], \"ccc\":[4,5,6]]);\n}\n\n@safe pure unittest\n{\n    import std.exception;\n\n    //Check proper failure\n    auto s = \"[1:10, 2:20, 3:30]\";\n    foreach (i ; 0 .. s.length-1)\n    {\n        auto ss = s[0 .. i];\n        assertThrown!ConvException(parse!(int[int])(ss));\n    }\n    int[int] aa = parse!(int[int])(s);\n}\n\nprivate dchar parseEscape(Source)(ref Source s)\nif (isInputRange!Source && isSomeChar!(ElementType!Source))\n{\n    parseCheck!s('\\\\');\n    if (s.empty)\n        throw parseError(\"Unterminated escape sequence\");\n\n    dchar getHexDigit()(ref Source s_ = s)  // workaround\n    {\n        import std.ascii : isAlpha, isHexDigit;\n        if (s_.empty)\n            throw parseError(\"Unterminated escape sequence\");\n        s_.popFront();\n        if (s_.empty)\n            throw parseError(\"Unterminated escape sequence\");\n        dchar c = s_.front;\n        if (!isHexDigit(c))\n            throw parseError(\"Hex digit is missing\");\n        return isAlpha(c) ? ((c & ~0x20) - ('A' - 10)) : c - '0';\n    }\n\n    dchar result;\n\n    switch (s.front)\n    {\n        case '\"':   result = '\\\"';  break;\n        case '\\'':  result = '\\'';  break;\n        case '0':   result = '\\0';  break;\n        case '?':   result = '\\?';  break;\n        case '\\\\':  result = '\\\\';  break;\n        case 'a':   result = '\\a';  break;\n        case 'b':   result = '\\b';  break;\n        case 'f':   result = '\\f';  break;\n        case 'n':   result = '\\n';  break;\n        case 'r':   result = '\\r';  break;\n        case 't':   result = '\\t';  break;\n        case 'v':   result = '\\v';  break;\n        case 'x':\n            result  = getHexDigit() << 4;\n            result |= getHexDigit();\n            break;\n        case 'u':\n            result  = getHexDigit() << 12;\n            result |= getHexDigit() << 8;\n            result |= getHexDigit() << 4;\n            result |= getHexDigit();\n            break;\n        case 'U':\n            result  = getHexDigit() << 28;\n            result |= getHexDigit() << 24;\n            result |= getHexDigit() << 20;\n            result |= getHexDigit() << 16;\n            result |= getHexDigit() << 12;\n            result |= getHexDigit() << 8;\n            result |= getHexDigit() << 4;\n            result |= getHexDigit();\n            break;\n        default:\n            throw parseError(\"Unknown escape character \" ~ to!string(s.front));\n    }\n    if (s.empty)\n        throw parseError(\"Unterminated escape sequence\");\n\n    s.popFront();\n\n    return result;\n}\n\n@safe pure unittest\n{\n    string[] s1 = [\n        `\\\"`, `\\'`, `\\?`, `\\\\`, `\\a`, `\\b`, `\\f`, `\\n`, `\\r`, `\\t`, `\\v`, //Normal escapes\n        //`\\141`, //@@@9621@@@ Octal escapes.\n        `\\x61`,\n        `\\u65E5`, `\\U00012456`\n        //`\\&amp;`, `\\&quot;`, //@@@9621@@@ Named Character Entities.\n    ];\n\n    const(dchar)[] s2 = [\n        '\\\"', '\\'', '\\?', '\\\\', '\\a', '\\b', '\\f', '\\n', '\\r', '\\t', '\\v', //Normal escapes\n        //'\\141', //@@@9621@@@ Octal escapes.\n        '\\x61',\n        '\\u65E5', '\\U00012456'\n        //'\\&amp;', '\\&quot;', //@@@9621@@@ Named Character Entities.\n    ];\n\n    foreach (i ; 0 .. s1.length)\n    {\n        assert(s2[i] == parseEscape(s1[i]));\n        assert(s1[i].empty);\n    }\n}\n\n@safe pure unittest\n{\n    import std.exception;\n\n    string[] ss = [\n        `hello!`,  //Not an escape\n        `\\`,       //Premature termination\n        `\\/`,      //Not an escape\n        `\\gggg`,   //Not an escape\n        `\\xzz`,    //Not an hex\n        `\\x0`,     //Premature hex end\n        `\\XB9`,    //Not legal hex syntax\n        `\\u!!`,    //Not a unicode hex\n        `\\777`,    //Octal is larger than a byte //Note: Throws, but simply because octals are unsupported\n        `\\u123`,   //Premature hex end\n        `\\U123123` //Premature hex end\n    ];\n    foreach (s ; ss)\n        assertThrown!ConvException(parseEscape(s));\n}\n\n// Undocumented\nTarget parseElement(Target, Source)(ref Source s)\nif (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&\n    isExactSomeString!Target)\n{\n    import std.array : appender;\n    auto result = appender!Target();\n\n    // parse array of chars\n    if (s.empty)\n        throw convError!(Source, Target)(s);\n    if (s.front == '[')\n        return parse!Target(s);\n\n    parseCheck!s('\\\"');\n    if (s.empty)\n        throw convError!(Source, Target)(s);\n    if (s.front == '\\\"')\n    {\n        s.popFront();\n        return result.data;\n    }\n    while (true)\n    {\n        if (s.empty)\n            throw parseError(\"Unterminated quoted string\");\n        switch (s.front)\n        {\n            case '\\\"':\n                s.popFront();\n                return result.data;\n            case '\\\\':\n                result.put(parseEscape(s));\n                break;\n            default:\n                result.put(s.front);\n                s.popFront();\n                break;\n        }\n    }\n    assert(0);\n}\n\n// ditto\nTarget parseElement(Target, Source)(ref Source s)\nif (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&\n    isSomeChar!Target && !is(Target == enum))\n{\n    Target c;\n\n    parseCheck!s('\\'');\n    if (s.empty)\n        throw convError!(Source, Target)(s);\n    if (s.front != '\\\\')\n    {\n        c = s.front;\n        s.popFront();\n    }\n    else\n        c = parseEscape(s);\n    parseCheck!s('\\'');\n\n    return c;\n}\n\n// ditto\nTarget parseElement(Target, Source)(ref Source s)\nif (isInputRange!Source && isSomeChar!(ElementType!Source) &&\n    !isSomeString!Target && !isSomeChar!Target)\n{\n    return parse!Target(s);\n}\n\n\n/***************************************************************\n * Convenience functions for converting one or more arguments\n * of any type into _text (the three character widths).\n */\nstring text(T...)(T args)\nif (T.length > 0) { return textImpl!string(args); }\n\n///ditto\nwstring wtext(T...)(T args)\nif (T.length > 0) { return textImpl!wstring(args); }\n\n///ditto\ndstring dtext(T...)(T args)\nif (T.length > 0) { return textImpl!dstring(args); }\n\n///\n@safe unittest\n{\n    assert( text(42, ' ', 1.5, \": xyz\") == \"42 1.5: xyz\"c);\n    assert(wtext(42, ' ', 1.5, \": xyz\") == \"42 1.5: xyz\"w);\n    assert(dtext(42, ' ', 1.5, \": xyz\") == \"42 1.5: xyz\"d);\n}\n\n@safe unittest\n{\n    char  c = 'h';\n    wchar w = '你';\n    dchar d = 'እ';\n\n    assert( text(c, \"ello\", ' ', w, \"好 \", d, \"ው ሰላም ነው\") == \"hello 你好 እው ሰላም ነው\"c);\n    assert(wtext(c, \"ello\", ' ', w, \"好 \", d, \"ው ሰላም ነው\") == \"hello 你好 እው ሰላም ነው\"w);\n    assert(dtext(c, \"ello\", ' ', w, \"好 \", d, \"ው ሰላም ነው\") == \"hello 你好 እው ሰላም ነው\"d);\n\n    string  cs = \"今日は\";\n    wstring ws = \"여보세요\";\n    dstring ds = \"Здравствуйте\";\n\n    assert( text(cs, ' ', ws, \" \", ds) == \"今日は 여보세요 Здравствуйте\"c);\n    assert(wtext(cs, ' ', ws, \" \", ds) == \"今日は 여보세요 Здравствуйте\"w);\n    assert(dtext(cs, ' ', ws, \" \", ds) == \"今日は 여보세요 Здравствуйте\"d);\n}\n\nprivate S textImpl(S, U...)(U args)\n{\n    static if (U.length == 0)\n    {\n        return null;\n    }\n    else static if (U.length == 1)\n    {\n        return to!S(args[0]);\n    }\n    else\n    {\n        import std.array : appender;\n        import std.traits : isSomeChar, isSomeString;\n\n        auto app = appender!S();\n\n        // assume that on average, parameters will have less\n        // than 20 elements\n        app.reserve(U.length * 20);\n\n        foreach (arg; args)\n        {\n            static if (\n                isSomeChar!(typeof(arg)) || isSomeString!(typeof(arg)) ||\n                ( isInputRange!(typeof(arg)) && isSomeChar!(ElementType!(typeof(arg))) )\n            )\n                app.put(arg);\n            else static if (\n\n                is(Unqual!(typeof(arg)) == uint) || is(Unqual!(typeof(arg)) == ulong) ||\n                is(Unqual!(typeof(arg)) == int) || is(Unqual!(typeof(arg)) == long)\n            )\n                // https://issues.dlang.org/show_bug.cgi?id=17712#c15\n                app.put(textImpl!(S)(arg));\n            else\n                app.put(to!S(arg));\n        }\n\n        return app.data;\n    }\n}\n\n\n/***************************************************************\nThe `octal` facility provides a means to declare a number in base 8.\nUsing `octal!177` or `octal!\"177\"` for 127 represented in octal\n(same as 0177 in C).\n\nThe rules for strings are the usual for literals: If it can fit in an\n`int`, it is an `int`. Otherwise, it is a `long`. But, if the\nuser specifically asks for a `long` with the `L` suffix, always\ngive the `long`. Give an unsigned iff it is asked for with the $(D\nU) or `u` suffix. _Octals created from integers preserve the type\nof the passed-in integral.\n\nSee_Also:\n    $(LREF parse) for parsing octal strings at runtime.\n */\ntemplate octal(string num)\nif (isOctalLiteral(num))\n{\n    static if ((octalFitsInInt!num && !literalIsLong!num) && !literalIsUnsigned!num)\n        enum octal = octal!int(num);\n    else static if ((!octalFitsInInt!num || literalIsLong!num) && !literalIsUnsigned!num)\n        enum octal = octal!long(num);\n    else static if ((octalFitsInInt!num && !literalIsLong!num) && literalIsUnsigned!num)\n        enum octal = octal!uint(num);\n    else static if ((!octalFitsInInt!(num) || literalIsLong!(num)) && literalIsUnsigned!(num))\n        enum octal = octal!ulong(num);\n    else\n        static assert(false);\n}\n\n/// Ditto\ntemplate octal(alias decimalInteger)\nif (isIntegral!(typeof(decimalInteger)))\n{\n    enum octal = octal!(typeof(decimalInteger))(to!string(decimalInteger));\n}\n\n///\n@safe unittest\n{\n    // same as 0177\n    auto x = octal!177;\n    // octal is a compile-time device\n    enum y = octal!160;\n    // Create an unsigned octal\n    auto z = octal!\"1_000_000u\";\n}\n\n/*\n    Takes a string, num, which is an octal literal, and returns its\n    value, in the type T specified.\n*/\nprivate T octal(T)(const string num)\n{\n    assert(isOctalLiteral(num));\n\n    T value = 0;\n\n    foreach (const char s; num)\n    {\n        if (s < '0' || s > '7') // we only care about digits; skip the rest\n        // safe to skip - this is checked out in the assert so these\n        // are just suffixes\n            continue;\n\n        value *= 8;\n        value += s - '0';\n    }\n\n    return value;\n}\n\n@safe unittest\n{\n    int a = octal!int(\"10\");\n    assert(a == 8);\n}\n\n/*\nTake a look at int.max and int.max+1 in octal and the logic for this\nfunction follows directly.\n */\nprivate template octalFitsInInt(string octalNum)\n{\n    // note it is important to strip the literal of all\n    // non-numbers. kill the suffix and underscores lest they mess up\n    // the number of digits here that we depend on.\n    enum bool octalFitsInInt = strippedOctalLiteral(octalNum).length < 11 ||\n        strippedOctalLiteral(octalNum).length == 11 &&\n        strippedOctalLiteral(octalNum)[0] == '1';\n}\n\nprivate string strippedOctalLiteral(string original)\n{\n    string stripped = \"\";\n    foreach (c; original)\n        if (c >= '0' && c <= '7')\n            stripped ~= c;\n    return stripped;\n}\n\nprivate template literalIsLong(string num)\n{\n    static if (num.length > 1)\n    // can be xxL or xxLu according to spec\n        enum literalIsLong = (num[$-1] == 'L' || num[$-2] == 'L');\n    else\n        enum literalIsLong = false;\n}\n\nprivate template literalIsUnsigned(string num)\n{\n    static if (num.length > 1)\n    // can be xxU or xxUL according to spec\n        enum literalIsUnsigned = (num[$-1] == 'u' || num[$-2] == 'u')\n            // both cases are allowed too\n            || (num[$-1] == 'U' || num[$-2] == 'U');\n    else\n        enum literalIsUnsigned = false;\n}\n\n/*\nReturns if the given string is a correctly formatted octal literal.\n\nThe format is specified in spec/lex.html. The leading zero is allowed, but\nnot required.\n */\n@safe pure nothrow @nogc\nprivate bool isOctalLiteral(const string num)\n{\n    if (num.length == 0)\n        return false;\n\n    // Must start with a number. To avoid confusion, literals that\n    // start with a '0' are not allowed\n    if (num[0] == '0' && num.length > 1)\n        return false;\n    if (num[0] < '0' || num[0] > '7')\n        return false;\n\n    foreach (i, c; num)\n    {\n        if ((c < '0' || c > '7') && c != '_') // not a legal character\n        {\n            if (i < num.length - 2)\n                    return false;\n            else   // gotta check for those suffixes\n            {\n                if (c != 'U' && c != 'u' && c != 'L')\n                        return false;\n                if (i != num.length - 1)\n                {\n                    // if we're not the last one, the next one must\n                    // also be a suffix to be valid\n                    char c2 = num[$-1];\n                    if (c2 != 'U' && c2 != 'u' && c2 != 'L')\n                        return false; // spam at the end of the string\n                    if (c2 == c)\n                        return false; // repeats are disallowed\n                }\n            }\n        }\n    }\n\n    return true;\n}\n\n@safe unittest\n{\n    // ensure that you get the right types, even with embedded underscores\n    auto w = octal!\"100_000_000_000\";\n    static assert(!is(typeof(w) == int));\n    auto w2 = octal!\"1_000_000_000\";\n    static assert(is(typeof(w2) == int));\n\n    static assert(octal!\"45\" == 37);\n    static assert(octal!\"0\" == 0);\n    static assert(octal!\"7\" == 7);\n    static assert(octal!\"10\" == 8);\n    static assert(octal!\"666\" == 438);\n\n    static assert(octal!45 == 37);\n    static assert(octal!0 == 0);\n    static assert(octal!7 == 7);\n    static assert(octal!10 == 8);\n    static assert(octal!666 == 438);\n\n    static assert(octal!\"66_6\" == 438);\n\n    static assert(octal!2520046213 == 356535435);\n    static assert(octal!\"2520046213\" == 356535435);\n\n    static assert(octal!17777777777 == int.max);\n\n    static assert(!__traits(compiles, octal!823));\n\n    static assert(!__traits(compiles, octal!\"823\"));\n\n    static assert(!__traits(compiles, octal!\"_823\"));\n    static assert(!__traits(compiles, octal!\"spam\"));\n    static assert(!__traits(compiles, octal!\"77%\"));\n\n    static assert(is(typeof(octal!\"17777777777\") == int));\n    static assert(octal!\"17777777777\" == int.max);\n\n    static assert(is(typeof(octal!\"20000000000U\") == ulong)); // Shouldn't this be uint?\n    static assert(octal!\"20000000000\" == uint(int.max) + 1);\n\n    static assert(is(typeof(octal!\"777777777777777777777\") == long));\n    static assert(octal!\"777777777777777777777\" == long.max);\n\n    static assert(is(typeof(octal!\"1000000000000000000000U\") == ulong));\n    static assert(octal!\"1000000000000000000000\" == ulong(long.max) + 1);\n\n    int a;\n    long b;\n\n    // biggest value that should fit in an it\n    a = octal!\"17777777777\";\n    assert(a == int.max);\n    // should not fit in the int\n    static assert(!__traits(compiles, a = octal!\"20000000000\"));\n    // ... but should fit in a long\n    b = octal!\"20000000000\";\n    assert(b == 1L + int.max);\n\n    b = octal!\"1L\";\n    assert(b == 1);\n    b = octal!1L;\n    assert(b == 1);\n}\n\n/+\nemplaceRef is a package function for phobos internal use. It works like\nemplace, but takes its argument by ref (as opposed to \"by pointer\").\n\nThis makes it easier to use, easier to be safe, and faster in a non-inline\nbuild.\n\nFurthermore, emplaceRef optionally takes a type parameter, which specifies\nthe type we want to build. This helps to build qualified objects on mutable\nbuffer, without breaking the type system with unsafe casts.\n+/\npackage void emplaceRef(T, UT, Args...)(ref UT chunk, auto ref Args args)\n{\n    static if (args.length == 0)\n    {\n        static assert(is(typeof({static T i;})),\n            convFormat(\"Cannot emplace a %1$s because %1$s.this() is annotated with @disable.\", T.stringof));\n        static if (is(T == class)) static assert(!isAbstractClass!T,\n            T.stringof ~ \" is abstract and it can't be emplaced\");\n        emplaceInitializer(chunk);\n    }\n    else static if (\n        !is(T == struct) && Args.length == 1 /* primitives, enums, arrays */\n        ||\n        Args.length == 1 && is(typeof({T t = args[0];})) /* conversions */\n        ||\n        is(typeof(T(args))) /* general constructors */)\n    {\n        static struct S\n        {\n            T payload;\n            this(ref Args x)\n            {\n                static if (Args.length == 1)\n                    static if (is(typeof(payload = x[0])))\n                        payload = x[0];\n                    else\n                        payload = T(x[0]);\n                else\n                    payload = T(x);\n            }\n        }\n        if (__ctfe)\n        {\n            static if (is(typeof(chunk = T(args))))\n                chunk = T(args);\n            else static if (args.length == 1 && is(typeof(chunk = args[0])))\n                chunk = args[0];\n            else assert(0, \"CTFE emplace doesn't support \"\n                ~ T.stringof ~ \" from \" ~ Args.stringof);\n        }\n        else\n        {\n            S* p = () @trusted { return cast(S*) &chunk; }();\n            static if (UT.sizeof > 0)\n                emplaceInitializer(*p);\n            p.__ctor(args);\n        }\n    }\n    else static if (is(typeof(chunk.__ctor(args))))\n    {\n        // This catches the rare case of local types that keep a frame pointer\n        emplaceInitializer(chunk);\n        chunk.__ctor(args);\n    }\n    else\n    {\n        //We can't emplace. Try to diagnose a disabled postblit.\n        static assert(!(Args.length == 1 && is(Args[0] : T)),\n            convFormat(\"Cannot emplace a %1$s because %1$s.this(this) is annotated with @disable.\", T.stringof));\n\n        //We can't emplace.\n        static assert(false,\n            convFormat(\"%s cannot be emplaced from %s.\", T.stringof, Args[].stringof));\n    }\n}\n// ditto\npackage void emplaceRef(UT, Args...)(ref UT chunk, auto ref Args args)\nif (is(UT == Unqual!UT))\n{\n    emplaceRef!(UT, UT)(chunk, args);\n}\n\n//emplace helper functions\nprivate void emplaceInitializer(T)(scope ref T chunk) @trusted pure nothrow\n{\n    static if (!hasElaborateAssign!T && isAssignable!T)\n        chunk = T.init;\n    else\n    {\n        static if (__traits(isZeroInit, T))\n        {\n            import core.stdc.string : memset;\n            memset(&chunk, 0, T.sizeof);\n        }\n        else\n        {\n            import core.stdc.string : memcpy;\n            static immutable T init = T.init;\n            memcpy(&chunk, &init, T.sizeof);\n        }\n    }\n}\n\n// emplace\n/**\nGiven a pointer `chunk` to uninitialized memory (but already typed\nas `T`), constructs an object of non-`class` type `T` at that\naddress. If `T` is a class, initializes the class reference to null.\n\nReturns: A pointer to the newly constructed object (which is the same\nas `chunk`).\n */\nT* emplace(T)(T* chunk) @safe pure nothrow\n{\n    emplaceRef!T(*chunk);\n    return chunk;\n}\n\n///\n@system unittest\n{\n    static struct S\n    {\n        int i = 42;\n    }\n    S[2] s2 = void;\n    emplace(&s2);\n    assert(s2[0].i == 42 && s2[1].i == 42);\n}\n\n///\n@system unittest\n{\n    interface I {}\n    class K : I {}\n\n    K k = void;\n    emplace(&k);\n    assert(k is null);\n\n    I i = void;\n    emplace(&i);\n    assert(i is null);\n}\n\n/**\nGiven a pointer `chunk` to uninitialized memory (but already typed\nas a non-class type `T`), constructs an object of type `T` at\nthat address from arguments `args`. If `T` is a class, initializes\nthe class reference to `args[0]`.\n\nThis function can be `@trusted` if the corresponding constructor of\n`T` is `@safe`.\n\nReturns: A pointer to the newly constructed object (which is the same\nas `chunk`).\n */\nT* emplace(T, Args...)(T* chunk, auto ref Args args)\nif (is(T == struct) || Args.length == 1)\n{\n    emplaceRef!T(*chunk, args);\n    return chunk;\n}\n\n///\n@system unittest\n{\n    int a;\n    int b = 42;\n    assert(*emplace!int(&a, b) == 42);\n}\n\n@system unittest\n{\n    shared int i;\n    emplace(&i, 42);\n    assert(i == 42);\n}\n\nprivate @nogc pure nothrow @safe\nvoid testEmplaceChunk(void[] chunk, size_t typeSize, size_t typeAlignment)\n{\n    assert(chunk.length >= typeSize, \"emplace: Chunk size too small.\");\n    assert((cast(size_t) chunk.ptr) % typeAlignment == 0, \"emplace: Chunk is not aligned.\");\n}\n\n/**\nGiven a raw memory area `chunk` (but already typed as a class type `T`),\nconstructs an object of `class` type `T` at that address. The constructor\nis passed the arguments `Args`.\n\nIf `T` is an inner class whose `outer` field can be used to access an instance\nof the enclosing class, then `Args` must not be empty, and the first member of it\nmust be a valid initializer for that `outer` field. Correct initialization of\nthis field is essential to access members of the outer class inside `T` methods.\n\nNote:\nThis function is `@safe` if the corresponding constructor of `T` is `@safe`.\n\nReturns: The newly constructed object.\n */\nT emplace(T, Args...)(T chunk, auto ref Args args)\nif (is(T == class))\n{\n    static assert(!isAbstractClass!T, T.stringof ~\n        \" is abstract and it can't be emplaced\");\n\n    // Initialize the object in its pre-ctor state\n    enum classSize = __traits(classInstanceSize, T);\n    (() @trusted => (cast(void*) chunk)[0 .. classSize] = typeid(T).initializer[])();\n\n    static if (isInnerClass!T)\n    {\n        static assert(Args.length > 0,\n            \"Initializing an inner class requires a pointer to the outer class\");\n        static assert(is(Args[0] : typeof(T.outer)),\n            \"The first argument must be a pointer to the outer class\");\n\n        chunk.outer = args[0];\n        alias args1 = args[1..$];\n    }\n    else alias args1 = args;\n\n    // Call the ctor if any\n    static if (is(typeof(chunk.__ctor(args1))))\n    {\n        // T defines a genuine constructor accepting args\n        // Go the classic route: write .init first, then call ctor\n        chunk.__ctor(args1);\n    }\n    else\n    {\n        static assert(args1.length == 0 && !is(typeof(&T.__ctor)),\n            \"Don't know how to initialize an object of type \"\n            ~ T.stringof ~ \" with arguments \" ~ typeof(args1).stringof);\n    }\n    return chunk;\n}\n\n///\n@safe unittest\n{\n    () @safe {\n        class SafeClass\n        {\n            int x;\n            @safe this(int x) { this.x = x; }\n        }\n\n        auto buf = new void[__traits(classInstanceSize, SafeClass)];\n        auto support = (() @trusted => cast(SafeClass)(buf.ptr))();\n        auto safeClass = emplace!SafeClass(support, 5);\n        assert(safeClass.x == 5);\n\n        class UnsafeClass\n        {\n            int x;\n            @system this(int x) { this.x = x; }\n        }\n\n        auto buf2 = new void[__traits(classInstanceSize, UnsafeClass)];\n        auto support2 = (() @trusted => cast(UnsafeClass)(buf2.ptr))();\n        static assert(!__traits(compiles, emplace!UnsafeClass(support2, 5)));\n        static assert(!__traits(compiles, emplace!UnsafeClass(buf2, 5)));\n    }();\n}\n\n@safe unittest\n{\n    class Outer\n    {\n        int i = 3;\n        class Inner\n        {\n            @safe auto getI() { return i; }\n        }\n    }\n    auto outerBuf = new void[__traits(classInstanceSize, Outer)];\n    auto outerSupport = (() @trusted => cast(Outer)(outerBuf.ptr))();\n\n    auto innerBuf = new void[__traits(classInstanceSize, Outer.Inner)];\n    auto innerSupport = (() @trusted => cast(Outer.Inner)(innerBuf.ptr))();\n\n    auto inner = innerSupport.emplace!(Outer.Inner)(outerSupport.emplace!Outer);\n    assert(inner.getI == 3);\n}\n\n/**\nGiven a raw memory area `chunk`, constructs an object of `class` type `T` at\nthat address. The constructor is passed the arguments `Args`.\n\nIf `T` is an inner class whose `outer` field can be used to access an instance\nof the enclosing class, then `Args` must not be empty, and the first member of it\nmust be a valid initializer for that `outer` field. Correct initialization of\nthis field is essential to access members of the outer class inside `T` methods.\n\nPreconditions:\n`chunk` must be at least as large as `T` needs and should have an alignment\nmultiple of `T`'s alignment. (The size of a `class` instance is obtained by using\n$(D __traits(classInstanceSize, T))).\n\nNote:\nThis function can be `@trusted` if the corresponding constructor of `T` is `@safe`.\n\nReturns: The newly constructed object.\n */\nT emplace(T, Args...)(void[] chunk, auto ref Args args)\nif (is(T == class))\n{\n    enum classSize = __traits(classInstanceSize, T);\n    testEmplaceChunk(chunk, classSize, classInstanceAlignment!T);\n    return emplace!T(cast(T)(chunk.ptr), args);\n}\n\n///\n@system unittest\n{\n    static class C\n    {\n        int i;\n        this(int i){this.i = i;}\n    }\n    auto buf = new void[__traits(classInstanceSize, C)];\n    auto c = emplace!C(buf, 5);\n    assert(c.i == 5);\n}\n\n@system unittest\n{\n    class Outer\n    {\n        int i = 3;\n        class Inner\n        {\n            auto getI() { return i; }\n        }\n    }\n    auto outerBuf = new void[__traits(classInstanceSize, Outer)];\n    auto innerBuf = new void[__traits(classInstanceSize, Outer.Inner)];\n    auto inner = innerBuf.emplace!(Outer.Inner)(outerBuf.emplace!Outer);\n    assert(inner.getI == 3);\n}\n\n@nogc pure nothrow @safe unittest\n{\n    int var = 6;\n    align(__conv_EmplaceTestClass.alignof) ubyte[__traits(classInstanceSize, __conv_EmplaceTestClass)] buf;\n    auto support = (() @trusted => cast(__conv_EmplaceTestClass)(buf.ptr))();\n    auto k = emplace!__conv_EmplaceTestClass(support, 5, var);\n    assert(k.i == 5);\n    assert(var == 7);\n}\n\n/**\nGiven a raw memory area `chunk`, constructs an object of non-$(D\nclass) type `T` at that address. The constructor is passed the\narguments `args`, if any.\n\nPreconditions:\n`chunk` must be at least as large\nas `T` needs and should have an alignment multiple of `T`'s\nalignment.\n\nNote:\nThis function can be `@trusted` if the corresponding constructor of\n`T` is `@safe`.\n\nReturns: A pointer to the newly constructed object.\n */\nT* emplace(T, Args...)(void[] chunk, auto ref Args args)\nif (!is(T == class))\n{\n    testEmplaceChunk(chunk, T.sizeof, T.alignof);\n    emplaceRef!(T, Unqual!T)(*cast(Unqual!T*) chunk.ptr, args);\n    return cast(T*) chunk.ptr;\n}\n\n///\n@system unittest\n{\n    struct S\n    {\n        int a, b;\n    }\n    auto buf = new void[S.sizeof];\n    S s;\n    s.a = 42;\n    s.b = 43;\n    auto s1 = emplace!S(buf, s);\n    assert(s1.a == 42 && s1.b == 43);\n}\n\n// Bulk of emplace unittests starts here\n\n@system unittest /* unions */\n{\n    static union U\n    {\n        string a;\n        int b;\n        struct\n        {\n            long c;\n            int[] d;\n        }\n    }\n    U u1 = void;\n    U u2 = { \"hello\" };\n    emplace(&u1, u2);\n    assert(u1.a == \"hello\");\n}\n\nversion (unittest) private struct __conv_EmplaceTest\n{\n    int i = 3;\n    this(int i)\n    {\n        assert(this.i == 3 && i == 5);\n        this.i = i;\n    }\n    this(int i, ref int j)\n    {\n        assert(i == 5 && j == 6);\n        this.i = i;\n        ++j;\n    }\n\n@disable:\n    this();\n    this(this);\n    void opAssign();\n}\n\nversion (unittest) private class __conv_EmplaceTestClass\n{\n    int i = 3;\n    this(int i) @nogc @safe pure nothrow\n    {\n        assert(this.i == 3 && i == 5);\n        this.i = i;\n    }\n    this(int i, ref int j) @nogc @safe pure nothrow\n    {\n        assert(i == 5 && j == 6);\n        this.i = i;\n        ++j;\n    }\n}\n\n@system unittest // bugzilla 15772\n{\n    abstract class Foo {}\n    class Bar: Foo {}\n    void[] memory;\n    // test in emplaceInitializer\n    static assert(!is(typeof(emplace!Foo(cast(Foo*) memory.ptr))));\n    static assert( is(typeof(emplace!Bar(cast(Bar*) memory.ptr))));\n    // test in the emplace overload that takes void[]\n    static assert(!is(typeof(emplace!Foo(memory))));\n    static assert( is(typeof(emplace!Bar(memory))));\n}\n\n@system unittest\n{\n    struct S { @disable this(); }\n    S s = void;\n    static assert(!__traits(compiles, emplace(&s)));\n    emplace(&s, S.init);\n}\n\n@system unittest\n{\n    struct S1\n    {}\n\n    struct S2\n    {\n        void opAssign(S2);\n    }\n\n    S1 s1 = void;\n    S2 s2 = void;\n    S1[2] as1 = void;\n    S2[2] as2 = void;\n    emplace(&s1);\n    emplace(&s2);\n    emplace(&as1);\n    emplace(&as2);\n}\n\n@system unittest\n{\n    static struct S1\n    {\n        this(this) @disable;\n    }\n    static struct S2\n    {\n        this() @disable;\n    }\n    S1[2] ss1 = void;\n    S2[2] ss2 = void;\n    emplace(&ss1);\n    static assert(!__traits(compiles, emplace(&ss2)));\n    S1 s1 = S1.init;\n    S2 s2 = S2.init;\n    static assert(!__traits(compiles, emplace(&ss1, s1)));\n    emplace(&ss2, s2);\n}\n\n@system unittest\n{\n    struct S\n    {\n        immutable int i;\n    }\n    S s = void;\n    S[2] ss1 = void;\n    S[2] ss2 = void;\n    emplace(&s, 5);\n    assert(s.i == 5);\n    emplace(&ss1, s);\n    assert(ss1[0].i == 5 && ss1[1].i == 5);\n    emplace(&ss2, ss1);\n    assert(ss2 == ss1);\n}\n\n//Start testing emplace-args here\n\n@system unittest\n{\n    interface I {}\n    class K : I {}\n\n    K k = null, k2 = new K;\n    assert(k !is k2);\n    emplace!K(&k, k2);\n    assert(k is k2);\n\n    I i = null;\n    assert(i !is k);\n    emplace!I(&i, k);\n    assert(i is k);\n}\n\n@system unittest\n{\n    static struct S\n    {\n        int i = 5;\n        void opAssign(S){assert(0);}\n    }\n    S[2] sa = void;\n    S[2] sb;\n    emplace(&sa, sb);\n    assert(sa[0].i == 5 && sa[1].i == 5);\n}\n\n//Start testing emplace-struct here\n\n// Test constructor branch\n@system unittest\n{\n    struct S\n    {\n        double x = 5, y = 6;\n        this(int a, int b)\n        {\n            assert(x == 5 && y == 6);\n            x = a;\n            y = b;\n        }\n    }\n\n    auto s1 = new void[S.sizeof];\n    auto s2 = S(42, 43);\n    assert(*emplace!S(cast(S*) s1.ptr, s2) == s2);\n    assert(*emplace!S(cast(S*) s1, 44, 45) == S(44, 45));\n}\n\n@system unittest\n{\n    __conv_EmplaceTest k = void;\n    emplace(&k, 5);\n    assert(k.i == 5);\n}\n\n@system unittest\n{\n    int var = 6;\n    __conv_EmplaceTest k = void;\n    emplace(&k, 5, var);\n    assert(k.i == 5);\n    assert(var == 7);\n}\n\n// Test matching fields branch\n@system unittest\n{\n    struct S { uint n; }\n    S s;\n    emplace!S(&s, 2U);\n    assert(s.n == 2);\n}\n\n@safe unittest\n{\n    struct S { int a, b; this(int){} }\n    S s;\n    static assert(!__traits(compiles, emplace!S(&s, 2, 3)));\n}\n\n@system unittest\n{\n    struct S { int a, b = 7; }\n    S s1 = void, s2 = void;\n\n    emplace!S(&s1, 2);\n    assert(s1.a == 2 && s1.b == 7);\n\n    emplace!S(&s2, 2, 3);\n    assert(s2.a == 2 && s2.b == 3);\n}\n\n//opAssign\n@system unittest\n{\n    static struct S\n    {\n        int i = 5;\n        void opAssign(int){assert(0);}\n        void opAssign(S){assert(0);}\n    }\n    S sa1 = void;\n    S sa2 = void;\n    S sb1 = S(1);\n    emplace(&sa1, sb1);\n    emplace(&sa2, 2);\n    assert(sa1.i == 1);\n    assert(sa2.i == 2);\n}\n\n//postblit precedence\n@system unittest\n{\n    //Works, but breaks in \"-w -O\" because of @@@9332@@@.\n    //Uncomment test when 9332 is fixed.\n    static struct S\n    {\n        int i;\n\n        this(S other){assert(false);}\n        this(int i){this.i = i;}\n        this(this){}\n    }\n    S a = void;\n    assert(is(typeof({S b = a;})));    //Postblit\n    assert(is(typeof({S b = S(a);}))); //Constructor\n    auto b = S(5);\n    emplace(&a, b);\n    assert(a.i == 5);\n\n    static struct S2\n    {\n        int* p;\n        this(const S2){}\n    }\n    static assert(!is(immutable S2 : S2));\n    S2 s2 = void;\n    immutable is2 = (immutable S2).init;\n    emplace(&s2, is2);\n}\n\n//nested structs and postblit\n@system unittest\n{\n    static struct S\n    {\n        int* p;\n        this(int i){p = [i].ptr;}\n        this(this)\n        {\n            if (p)\n                p = [*p].ptr;\n        }\n    }\n    static struct SS\n    {\n        S s;\n        void opAssign(const SS)\n        {\n            assert(0);\n        }\n    }\n    SS ssa = void;\n    SS ssb = SS(S(5));\n    emplace(&ssa, ssb);\n    assert(*ssa.s.p == 5);\n    assert(ssa.s.p != ssb.s.p);\n}\n\n//disabled postblit\n@system unittest\n{\n    static struct S1\n    {\n        int i;\n        @disable this(this);\n    }\n    S1 s1 = void;\n    emplace(&s1, 1);\n    assert(s1.i == 1);\n    static assert(!__traits(compiles, emplace(&s1, S1.init)));\n\n    static struct S2\n    {\n        int i;\n        @disable this(this);\n        this(ref S2){}\n    }\n    S2 s2 = void;\n    static assert(!__traits(compiles, emplace(&s2, 1)));\n    emplace(&s2, S2.init);\n\n    static struct SS1\n    {\n        S1 s;\n    }\n    SS1 ss1 = void;\n    emplace(&ss1);\n    static assert(!__traits(compiles, emplace(&ss1, SS1.init)));\n\n    static struct SS2\n    {\n        S2 s;\n    }\n    SS2 ss2 = void;\n    emplace(&ss2);\n    static assert(!__traits(compiles, emplace(&ss2, SS2.init)));\n\n\n    // SS1 sss1 = s1;      //This doesn't compile\n    // SS1 sss1 = SS1(s1); //This doesn't compile\n    // So emplace shouldn't compile either\n    static assert(!__traits(compiles, emplace(&sss1, s1)));\n    static assert(!__traits(compiles, emplace(&sss2, s2)));\n}\n\n//Imutability\n@system unittest\n{\n    //Castable immutability\n    {\n        static struct S1\n        {\n            int i;\n        }\n        static assert(is( immutable(S1) : S1));\n        S1 sa = void;\n        auto sb = immutable(S1)(5);\n        emplace(&sa, sb);\n        assert(sa.i == 5);\n    }\n    //Un-castable immutability\n    {\n        static struct S2\n        {\n            int* p;\n        }\n        static assert(!is(immutable(S2) : S2));\n        S2 sa = void;\n        auto sb = immutable(S2)(null);\n        assert(!__traits(compiles, emplace(&sa, sb)));\n    }\n}\n\n@system unittest\n{\n    static struct S\n    {\n        immutable int i;\n        immutable(int)* j;\n    }\n    S s = void;\n    emplace(&s, 1, null);\n    emplace(&s, 2, &s.i);\n    assert(s is S(2, &s.i));\n}\n\n//Context pointer\n@system unittest\n{\n    int i = 0;\n    {\n        struct S1\n        {\n            void foo(){++i;}\n        }\n        S1 sa = void;\n        S1 sb;\n        emplace(&sa, sb);\n        sa.foo();\n        assert(i == 1);\n    }\n    {\n        struct S2\n        {\n            void foo(){++i;}\n            this(this){}\n        }\n        S2 sa = void;\n        S2 sb;\n        emplace(&sa, sb);\n        sa.foo();\n        assert(i == 2);\n    }\n}\n\n//Alias this\n@system unittest\n{\n    static struct S\n    {\n        int i;\n    }\n    //By Ref\n    {\n        static struct SS1\n        {\n            int j;\n            S s;\n            alias s this;\n        }\n        S s = void;\n        SS1 ss = SS1(1, S(2));\n        emplace(&s, ss);\n        assert(s.i == 2);\n    }\n    //By Value\n    {\n        static struct SS2\n        {\n            int j;\n            S s;\n            S foo() @property{return s;}\n            alias foo this;\n        }\n        S s = void;\n        SS2 ss = SS2(1, S(2));\n        emplace(&s, ss);\n        assert(s.i == 2);\n    }\n}\n\nversion (unittest)\n{\n    //Ambiguity\n    private struct __std_conv_S\n    {\n        int i;\n        this(__std_conv_SS ss)         {assert(0);}\n        static opCall(__std_conv_SS ss)\n        {\n            __std_conv_S s; s.i = ss.j;\n            return s;\n        }\n    }\n    private struct __std_conv_SS\n    {\n        int j;\n        __std_conv_S s;\n        ref __std_conv_S foo() return @property {s.i = j; return s;}\n        alias foo this;\n    }\n}\n\n@system unittest\n{\n    static assert(is(__std_conv_SS : __std_conv_S));\n    __std_conv_S s = void;\n    __std_conv_SS ss = __std_conv_SS(1);\n\n    __std_conv_S sTest1 = ss; //this calls \"SS alias this\" (and not \"S.this(SS)\")\n    emplace(&s, ss); //\"alias this\" should take precedence in emplace over \"opCall\"\n    assert(s.i == 1);\n}\n\n//Nested classes\n@system unittest\n{\n    class A{}\n    static struct S\n    {\n        A a;\n    }\n    S s1 = void;\n    S s2 = S(new A);\n    emplace(&s1, s2);\n    assert(s1.a is s2.a);\n}\n\n//safety & nothrow & CTFE\n@system unittest\n{\n    //emplace should be safe for anything with no elaborate opassign\n    static struct S1\n    {\n        int i;\n    }\n    static struct S2\n    {\n        int i;\n        this(int j)@safe nothrow{i = j;}\n    }\n\n    int i;\n    S1 s1 = void;\n    S2 s2 = void;\n\n    auto pi = &i;\n    auto ps1 = &s1;\n    auto ps2 = &s2;\n\n    void foo() @safe nothrow\n    {\n        emplace(pi);\n        emplace(pi, 5);\n        emplace(ps1);\n        emplace(ps1, 5);\n        emplace(ps1, S1.init);\n        emplace(ps2);\n        emplace(ps2, 5);\n        emplace(ps2, S2.init);\n    }\n    foo();\n\n    T bar(T)() @property\n    {\n        T t/+ = void+/; //CTFE void illegal\n        emplace(&t, 5);\n        return t;\n    }\n    // CTFE\n    enum a = bar!int;\n    static assert(a == 5);\n    enum b = bar!S1;\n    static assert(b.i == 5);\n    enum c = bar!S2;\n    static assert(c.i == 5);\n    // runtime\n    auto aa = bar!int;\n    assert(aa == 5);\n    auto bb = bar!S1;\n    assert(bb.i == 5);\n    auto cc = bar!S2;\n    assert(cc.i == 5);\n}\n\n\n@system unittest\n{\n    struct S\n    {\n        int[2] get(){return [1, 2];}\n        alias get this;\n    }\n    struct SS\n    {\n        int[2] ii;\n    }\n    struct ISS\n    {\n        int[2] ii;\n    }\n    S s;\n    SS ss = void;\n    ISS iss = void;\n    emplace(&ss, s);\n    emplace(&iss, s);\n    assert(ss.ii == [1, 2]);\n    assert(iss.ii == [1, 2]);\n}\n\n//disable opAssign\n@system unittest\n{\n    static struct S\n    {\n        @disable void opAssign(S);\n    }\n    S s;\n    emplace(&s, S.init);\n}\n\n//opCall\n@system unittest\n{\n    int i;\n    //Without constructor\n    {\n        static struct S1\n        {\n            int i;\n            static S1 opCall(int*){assert(0);}\n        }\n        S1 s = void;\n        static assert(!__traits(compiles, emplace(&s,  1)));\n    }\n    //With constructor\n    {\n        static struct S2\n        {\n            int i = 0;\n            static S2 opCall(int*){assert(0);}\n            static S2 opCall(int){assert(0);}\n            this(int i){this.i = i;}\n        }\n        S2 s = void;\n        emplace(&s,  1);\n        assert(s.i == 1);\n    }\n    //With postblit ambiguity\n    {\n        static struct S3\n        {\n            int i = 0;\n            static S3 opCall(ref S3){assert(0);}\n        }\n        S3 s = void;\n        emplace(&s, S3.init);\n    }\n}\n\n@safe unittest //@@@9559@@@\n{\n    import std.algorithm.iteration : map;\n    import std.array : array;\n    import std.typecons : Nullable;\n    alias I = Nullable!int;\n    auto ints = [0, 1, 2].map!(i => i & 1 ? I.init : I(i))();\n    auto asArray = array(ints);\n}\n\n@system unittest //http://forum.dlang.org/post/nxbdgtdlmwscocbiypjs@forum.dlang.org\n{\n    import std.array : array;\n    import std.datetime : SysTime, UTC;\n    import std.math : isNaN;\n\n    static struct A\n    {\n        double i;\n    }\n\n    static struct B\n    {\n        invariant()\n        {\n            if (j == 0)\n                assert(a.i.isNaN(), \"why is 'j' zero?? and i is not NaN?\");\n            else\n                assert(!a.i.isNaN());\n        }\n        SysTime when; // comment this line avoid the breakage\n        int j;\n        A a;\n    }\n\n    B b1 = B.init;\n    assert(&b1); // verify that default eyes invariants are ok;\n\n    auto b2 = B(SysTime(0, UTC()), 1, A(1));\n    assert(&b2);\n    auto b3 = B(SysTime(0, UTC()), 1, A(1));\n    assert(&b3);\n\n    auto arr = [b2, b3];\n\n    assert(arr[0].j == 1);\n    assert(arr[1].j == 1);\n    auto a2 = arr.array(); // << bang, invariant is raised, also if b2 and b3 are good\n}\n\n//static arrays\n@system unittest\n{\n    static struct S\n    {\n        int[2] ii;\n    }\n    static struct IS\n    {\n        immutable int[2] ii;\n    }\n    int[2] ii;\n    S  s   = void;\n    IS ims = void;\n    ubyte ub = 2;\n    emplace(&s, ub);\n    emplace(&s, ii);\n    emplace(&ims, ub);\n    emplace(&ims, ii);\n    uint[2] uu;\n    static assert(!__traits(compiles, {S ss = S(uu);}));\n    static assert(!__traits(compiles, emplace(&s, uu)));\n}\n\n@system unittest\n{\n    int[2]  sii;\n    int[2]  sii2;\n    uint[2] uii;\n    uint[2] uii2;\n    emplace(&sii, 1);\n    emplace(&sii, 1U);\n    emplace(&uii, 1);\n    emplace(&uii, 1U);\n    emplace(&sii, sii2);\n    //emplace(&sii, uii2); //Sorry, this implementation doesn't know how to...\n    //emplace(&uii, sii2); //Sorry, this implementation doesn't know how to...\n    emplace(&uii, uii2);\n    emplace(&sii, sii2[]);\n    //emplace(&sii, uii2[]); //Sorry, this implementation doesn't know how to...\n    //emplace(&uii, sii2[]); //Sorry, this implementation doesn't know how to...\n    emplace(&uii, uii2[]);\n}\n\n@system unittest\n{\n    bool allowDestruction = false;\n    struct S\n    {\n        int i;\n        this(this){}\n        ~this(){assert(allowDestruction);}\n    }\n    S s = S(1);\n    S[2] ss1 = void;\n    S[2] ss2 = void;\n    S[2] ss3 = void;\n    emplace(&ss1, s);\n    emplace(&ss2, ss1);\n    emplace(&ss3, ss2[]);\n    assert(ss1[1] == s);\n    assert(ss2[1] == s);\n    assert(ss3[1] == s);\n    allowDestruction = true;\n}\n\n@system unittest\n{\n    //Checks postblit, construction, and context pointer\n    int count = 0;\n    struct S\n    {\n        this(this)\n        {\n            ++count;\n        }\n        ~this()\n        {\n            --count;\n        }\n    }\n\n    S s;\n    {\n        S[4] ss = void;\n        emplace(&ss, s);\n        assert(count == 4);\n    }\n    assert(count == 0);\n}\n\n@system unittest\n{\n    struct S\n    {\n        int i;\n    }\n    S s;\n    S[2][2][2] sss = void;\n    emplace(&sss, s);\n}\n\n@system unittest //Constness\n{\n    import std.stdio;\n\n    int a = void;\n    emplaceRef!(const int)(a, 5);\n\n    immutable i = 5;\n    const(int)* p = void;\n    emplaceRef!(const int*)(p, &i);\n\n    struct S\n    {\n        int* p;\n    }\n    alias IS = immutable(S);\n    S s = void;\n    emplaceRef!IS(s, IS());\n    S[2] ss = void;\n    emplaceRef!(IS[2])(ss, IS());\n\n    IS[2] iss = IS.init;\n    emplaceRef!(IS[2])(ss, iss);\n    emplaceRef!(IS[2])(ss, iss[]);\n}\n\npure nothrow @safe @nogc unittest\n{\n    int i;\n    emplaceRef(i);\n    emplaceRef!int(i);\n    emplaceRef(i, 5);\n    emplaceRef!int(i, 5);\n}\n\n// Test attribute propagation for UDTs\npure nothrow @safe /* @nogc */ unittest\n{\n    static struct Safe\n    {\n        this(this) pure nothrow @safe @nogc {}\n    }\n\n    Safe safe = void;\n    emplaceRef(safe, Safe());\n\n    Safe[1] safeArr = [Safe()];\n    Safe[1] uninitializedSafeArr = void;\n    emplaceRef(uninitializedSafeArr, safe);\n    emplaceRef(uninitializedSafeArr, safeArr);\n\n    static struct Unsafe\n    {\n        this(this) @system {}\n    }\n\n    Unsafe unsafe = void;\n    static assert(!__traits(compiles, emplaceRef(unsafe, Unsafe())));\n\n    Unsafe[1] unsafeArr = [Unsafe()];\n    Unsafe[1] uninitializedUnsafeArr = void;\n    static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafe)));\n    static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafeArr)));\n}\n\n@system unittest\n{\n    // Issue 15313\n    static struct Node\n    {\n        int payload;\n        Node* next;\n        uint refs;\n    }\n\n    import core.stdc.stdlib : malloc;\n    void[] buf = malloc(Node.sizeof)[0 .. Node.sizeof];\n\n    import std.conv : emplace;\n    const Node* n = emplace!(const Node)(buf, 42, null, 10);\n    assert(n.payload == 42);\n    assert(n.next == null);\n    assert(n.refs == 10);\n}\n\n@system unittest\n{\n    int var = 6;\n    auto k = emplace!__conv_EmplaceTest(new void[__conv_EmplaceTest.sizeof], 5, var);\n    assert(k.i == 5);\n    assert(var == 7);\n}\n\n@system unittest\n{\n    class A\n    {\n        int x = 5;\n        int y = 42;\n        this(int z)\n        {\n            assert(x == 5 && y == 42);\n            x = y = z;\n        }\n    }\n    void[] buf;\n\n    static align(A.alignof) byte[__traits(classInstanceSize, A)] sbuf;\n    buf = sbuf[];\n    auto a = emplace!A(buf, 55);\n    assert(a.x == 55 && a.y == 55);\n\n    // emplace in bigger buffer\n    buf = new byte[](__traits(classInstanceSize, A) + 10);\n    a = emplace!A(buf, 55);\n    assert(a.x == 55 && a.y == 55);\n\n    // need ctor args\n    static assert(!is(typeof(emplace!A(buf))));\n}\n// Bulk of emplace unittests ends here\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    // Check fix for http://d.puremagic.com/issues/show_bug.cgi?id=2971\n    assert(equal(map!(to!int)([\"42\", \"34\", \"345\"]), [42, 34, 345]));\n}\n\n// Undocumented for the time being\nvoid toTextRange(T, W)(T value, W writer)\nif (isIntegral!T && isOutputRange!(W, char))\n{\n    import core.internal.string : SignedStringBuf, signedToTempString,\n                                  UnsignedStringBuf, unsignedToTempString;\n\n    if (value < 0)\n    {\n        SignedStringBuf buf = void;\n        put(writer, signedToTempString(value, buf, 10));\n    }\n    else\n    {\n        UnsignedStringBuf buf = void;\n        put(writer, unsignedToTempString(value, buf, 10));\n    }\n}\n\n@safe unittest\n{\n    import std.array : appender;\n    auto result = appender!(char[])();\n    toTextRange(-1, result);\n    assert(result.data == \"-1\");\n}\n\n\n/**\n    Returns the corresponding _unsigned value for `x` (e.g. if `x` has type\n    `int`, it returns $(D cast(uint) x)). The advantage compared to the cast\n    is that you do not need to rewrite the cast if `x` later changes type\n    (e.g from `int` to `long`).\n\n    Note that the result is always mutable even if the original type was const\n    or immutable. In order to retain the constness, use $(REF Unsigned, std,traits).\n */\nauto unsigned(T)(T x)\nif (isIntegral!T)\n{\n    return cast(Unqual!(Unsigned!T))x;\n}\n\n///\n@safe unittest\n{\n    import std.traits : Unsigned;\n    immutable int s = 42;\n    auto u1 = unsigned(s); //not qualified\n    static assert(is(typeof(u1) == uint));\n    Unsigned!(typeof(s)) u2 = unsigned(s); //same qualification\n    static assert(is(typeof(u2) == immutable uint));\n    immutable u3 = unsigned(s); //explicitly qualified\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(byte, ubyte))\n    {\n        static assert(is(typeof(unsigned(cast(T) 1)) == ubyte));\n        static assert(is(typeof(unsigned(cast(const T) 1)) == ubyte));\n        static assert(is(typeof(unsigned(cast(immutable T) 1)) == ubyte));\n    }\n\n    static foreach (T; AliasSeq!(short, ushort))\n    {\n        static assert(is(typeof(unsigned(cast(T) 1)) == ushort));\n        static assert(is(typeof(unsigned(cast(const T) 1)) == ushort));\n        static assert(is(typeof(unsigned(cast(immutable T) 1)) == ushort));\n    }\n\n    static foreach (T; AliasSeq!(int, uint))\n    {\n        static assert(is(typeof(unsigned(cast(T) 1)) == uint));\n        static assert(is(typeof(unsigned(cast(const T) 1)) == uint));\n        static assert(is(typeof(unsigned(cast(immutable T) 1)) == uint));\n    }\n\n    static foreach (T; AliasSeq!(long, ulong))\n    {\n        static assert(is(typeof(unsigned(cast(T) 1)) == ulong));\n        static assert(is(typeof(unsigned(cast(const T) 1)) == ulong));\n        static assert(is(typeof(unsigned(cast(immutable T) 1)) == ulong));\n    }\n}\n\nauto unsigned(T)(T x)\nif (isSomeChar!T)\n{\n    // All characters are unsigned\n    static assert(T.min == 0);\n    return cast(Unqual!T) x;\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(char, wchar, dchar))\n    {\n        static assert(is(typeof(unsigned(cast(T)'A')) == T));\n        static assert(is(typeof(unsigned(cast(const T)'A')) == T));\n        static assert(is(typeof(unsigned(cast(immutable T)'A')) == T));\n    }\n}\n\n\n/**\n    Returns the corresponding _signed value for `x` (e.g. if `x` has type\n    `uint`, it returns $(D cast(int) x)). The advantage compared to the cast\n    is that you do not need to rewrite the cast if `x` later changes type\n    (e.g from `uint` to `ulong`).\n\n    Note that the result is always mutable even if the original type was const\n    or immutable. In order to retain the constness, use $(REF Signed, std,traits).\n */\nauto signed(T)(T x)\nif (isIntegral!T)\n{\n    return cast(Unqual!(Signed!T))x;\n}\n\n///\n@safe unittest\n{\n    import std.traits : Signed;\n\n    immutable uint u = 42;\n    auto s1 = signed(u); //not qualified\n    static assert(is(typeof(s1) == int));\n    Signed!(typeof(u)) s2 = signed(u); //same qualification\n    static assert(is(typeof(s2) == immutable int));\n    immutable s3 = signed(u); //explicitly qualified\n}\n\n@system unittest\n{\n    static foreach (T; AliasSeq!(byte, ubyte))\n    {\n        static assert(is(typeof(signed(cast(T) 1)) == byte));\n        static assert(is(typeof(signed(cast(const T) 1)) == byte));\n        static assert(is(typeof(signed(cast(immutable T) 1)) == byte));\n    }\n\n    static foreach (T; AliasSeq!(short, ushort))\n    {\n        static assert(is(typeof(signed(cast(T) 1)) == short));\n        static assert(is(typeof(signed(cast(const T) 1)) == short));\n        static assert(is(typeof(signed(cast(immutable T) 1)) == short));\n    }\n\n    static foreach (T; AliasSeq!(int, uint))\n    {\n        static assert(is(typeof(signed(cast(T) 1)) == int));\n        static assert(is(typeof(signed(cast(const T) 1)) == int));\n        static assert(is(typeof(signed(cast(immutable T) 1)) == int));\n    }\n\n    static foreach (T; AliasSeq!(long, ulong))\n    {\n        static assert(is(typeof(signed(cast(T) 1)) == long));\n        static assert(is(typeof(signed(cast(const T) 1)) == long));\n        static assert(is(typeof(signed(cast(immutable T) 1)) == long));\n    }\n}\n\n@safe unittest\n{\n    // issue 10874\n    enum Test { a = 0 }\n    ulong l = 0;\n    auto t = l.to!Test;\n}\n\n// asOriginalType\n/**\nReturns the representation of an enumerated value, i.e. the value converted to\nthe base type of the enumeration.\n*/\nOriginalType!E asOriginalType(E)(E value)\nif (is(E == enum))\n{\n    return value;\n}\n\n///\n@safe unittest\n{\n    enum A { a = 42 }\n    static assert(is(typeof(A.a.asOriginalType) == int));\n    assert(A.a.asOriginalType == 42);\n    enum B : double { a = 43 }\n    static assert(is(typeof(B.a.asOriginalType) == double));\n    assert(B.a.asOriginalType == 43);\n}\n\n/**\n    A wrapper on top of the built-in cast operator that allows one to restrict\n    casting of the original type of the value.\n\n    A common issue with using a raw cast is that it may silently continue to\n    compile even if the value's type has changed during refactoring,\n    which breaks the initial assumption about the cast.\n\n    Params:\n        From  = The type to cast from. The programmer must ensure it is legal\n                to make this cast.\n */\ntemplate castFrom(From)\n{\n    /**\n        Params:\n            To    = The type _to cast _to.\n            value = The value _to cast. It must be of type `From`,\n                    otherwise a compile-time error is emitted.\n\n        Returns:\n            the value after the cast, returned by reference if possible.\n     */\n    auto ref to(To, T)(auto ref T value) @system\n    {\n        static assert(\n            is(From == T),\n            \"the value to cast is not of specified type '\" ~ From.stringof ~\n                 \"', it is of type '\" ~ T.stringof ~ \"'\"\n        );\n\n        static assert(\n            is(typeof(cast(To) value)),\n            \"can't cast from '\" ~ From.stringof ~ \"' to '\" ~ To.stringof ~ \"'\"\n        );\n\n        return cast(To) value;\n    }\n}\n\n///\n@system unittest\n{\n    // Regular cast, which has been verified to be legal by the programmer:\n    {\n        long x;\n        auto y = cast(int) x;\n    }\n\n    // However this will still compile if 'x' is changed to be a pointer:\n    {\n        long* x;\n        auto y = cast(int) x;\n    }\n\n    // castFrom provides a more reliable alternative to casting:\n    {\n        long x;\n        auto y = castFrom!long.to!int(x);\n    }\n\n    // Changing the type of 'x' will now issue a compiler error,\n    // allowing bad casts to be caught before it's too late:\n    {\n        long* x;\n        static assert(\n            !__traits(compiles, castFrom!long.to!int(x))\n        );\n\n        // if cast is still needed, must be changed to:\n        auto y = castFrom!(long*).to!int(x);\n    }\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=16667\n@system unittest\n{\n    ubyte[] a = ['a', 'b', 'c'];\n    assert(castFrom!(ubyte[]).to!(string)(a) == \"abc\");\n}\n\n/**\nCheck the correctness of a string for `hexString`.\nThe result is true if and only if the input string is composed of whitespace\ncharacters (\\f\\n\\r\\t\\v lineSep paraSep nelSep) and\nan even number of hexadecimal digits (regardless of the case).\n*/\n@safe pure @nogc\nprivate bool isHexLiteral(String)(scope const String hexData)\n{\n    import std.ascii : isHexDigit;\n    import std.uni : lineSep, paraSep, nelSep;\n    size_t i;\n    foreach (const dchar c; hexData)\n    {\n        switch (c)\n        {\n            case ' ':\n            case '\\t':\n            case '\\v':\n            case '\\f':\n            case '\\r':\n            case '\\n':\n            case lineSep:\n            case paraSep:\n            case nelSep:\n                continue;\n\n            default:\n                break;\n        }\n        if (c.isHexDigit)\n            ++i;\n        else\n            return false;\n    }\n    return !(i & 1);\n}\n\n@safe unittest\n{\n    // test all the hex digits\n    static assert( (\"0123456789abcdefABCDEF\").isHexLiteral);\n    // empty or white strings are not valid\n    static assert( \"\\r\\n\\t\".isHexLiteral);\n    // but are accepted if the count of hex digits is even\n    static assert( \"A\\r\\n\\tB\".isHexLiteral);\n}\n\n@safe unittest\n{\n    import std.ascii;\n    // empty/whites\n    static assert( \"\".isHexLiteral);\n    static assert( \" \\r\".isHexLiteral);\n    static assert( whitespace.isHexLiteral);\n    static assert( \"\"w.isHexLiteral);\n    static assert( \" \\r\"w.isHexLiteral);\n    static assert( \"\"d.isHexLiteral);\n    static assert( \" \\r\"d.isHexLiteral);\n    static assert( \"\\u2028\\u2029\\u0085\"d.isHexLiteral);\n    // odd x strings\n    static assert( !(\"5\" ~ whitespace).isHexLiteral);\n    static assert( !\"123\".isHexLiteral);\n    static assert( !\"1A3\".isHexLiteral);\n    static assert( !\"1 23\".isHexLiteral);\n    static assert( !\"\\r\\n\\tC\".isHexLiteral);\n    static assert( !\"123\"w.isHexLiteral);\n    static assert( !\"1A3\"w.isHexLiteral);\n    static assert( !\"1 23\"w.isHexLiteral);\n    static assert( !\"\\r\\n\\tC\"w.isHexLiteral);\n    static assert( !\"123\"d.isHexLiteral);\n    static assert( !\"1A3\"d.isHexLiteral);\n    static assert( !\"1 23\"d.isHexLiteral);\n    static assert( !\"\\r\\n\\tC\"d.isHexLiteral);\n    // even x strings with invalid charset\n    static assert( !\"12gG\".isHexLiteral);\n    static assert( !\"2A  3q\".isHexLiteral);\n    static assert( !\"12gG\"w.isHexLiteral);\n    static assert( !\"2A  3q\"w.isHexLiteral);\n    static assert( !\"12gG\"d.isHexLiteral);\n    static assert( !\"2A  3q\"d.isHexLiteral);\n    // valid x strings\n    static assert( (\"5A\" ~ whitespace).isHexLiteral);\n    static assert( (\"5A 01A C FF de 1b\").isHexLiteral);\n    static assert( (\"0123456789abcdefABCDEF\").isHexLiteral);\n    static assert( (\" 012 34 5 6789 abcd ef\\rAB\\nCDEF\").isHexLiteral);\n    static assert( (\"5A 01A C FF de 1b\"w).isHexLiteral);\n    static assert( (\"0123456789abcdefABCDEF\"w).isHexLiteral);\n    static assert( (\" 012 34 5 6789 abcd ef\\rAB\\nCDEF\"w).isHexLiteral);\n    static assert( (\"5A 01A C FF de 1b\"d).isHexLiteral);\n    static assert( (\"0123456789abcdefABCDEF\"d).isHexLiteral);\n    static assert( (\" 012 34 5 6789 abcd ef\\rAB\\nCDEF\"d).isHexLiteral);\n    // library version allows what's pointed by issue 10454\n    static assert( (\"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\").isHexLiteral);\n}\n\n/**\nConverts a hex literal to a string at compile time.\n\nTakes a string made of hexadecimal digits and returns\nthe matching string by converting each pair of digits to a character.\nThe input string can also include white characters, which can be used\nto keep the literal string readable in the source code.\n\nThe function is intended to replace the hexadecimal literal strings\nstarting with `'x'`, which could be removed to simplify the core language.\n\nParams:\n    hexData = string to be converted.\n\nReturns:\n    a `string`, a `wstring` or a `dstring`, according to the type of hexData.\n */\ntemplate hexString(string hexData)\nif (hexData.isHexLiteral)\n{\n    enum hexString = mixin(hexToString(hexData));\n}\n\n/// ditto\ntemplate hexString(wstring hexData)\nif (hexData.isHexLiteral)\n{\n    enum wstring hexString = mixin(hexToString(hexData));\n}\n\n/// ditto\ntemplate hexString(dstring hexData)\nif (hexData.isHexLiteral)\n{\n    enum dstring hexString = mixin(hexToString(hexData));\n}\n\n///\n@safe unittest\n{\n    // conversion at compile time\n    auto string1 = hexString!\"304A314B\";\n    assert(string1 == \"0J1K\");\n    auto string2 = hexString!\"304A314B\"w;\n    assert(string2 == \"0J1K\"w);\n    auto string3 = hexString!\"304A314B\"d;\n    assert(string3 == \"0J1K\"d);\n}\n\n@safe nothrow pure private\n{\n    /* These are meant to be used with CTFE.\n     * They cause the instantiations of hexStrLiteral()\n     * to be in Phobos, not user code.\n     */\n    string hexToString(string s)\n    {\n        return hexStrLiteral(s);\n    }\n\n    wstring hexToString(wstring s)\n    {\n        return hexStrLiteral(s);\n    }\n\n    dstring hexToString(dstring s)\n    {\n        return hexStrLiteral(s);\n    }\n}\n\n/*\n    Turn a hexadecimal string into a regular string literal.\n    I.e. \"dead beef\" is transformed into \"\\xde\\xad\\xbe\\xef\"\n    suitable for use in a mixin.\n    Params:\n        hexData is string, wstring, or dstring and validated by isHexLiteral()\n */\n@trusted nothrow pure\nprivate auto hexStrLiteral(String)(scope String hexData)\n{\n    import std.ascii : isHexDigit;\n    alias C = Unqual!(ElementEncodingType!String);    // char, wchar or dchar\n    C[] result;\n    result.length = 1 + hexData.length * 2 + 1;       // don't forget the \" \"\n    /* Use a pointer because we know it won't overrun,\n     * and this will reduce the size of the function substantially\n     * by not doing the array bounds checks.\n     * This is why this function is @trusted.\n     */\n    auto r = result.ptr;\n    r[0] = '\"';\n    size_t cnt = 0;\n    foreach (c; hexData)\n    {\n        if (c.isHexDigit)\n        {\n            if ((cnt & 1) == 0)\n            {\n                r[1 + cnt]     = '\\\\';\n                r[1 + cnt + 1] = 'x';\n                cnt += 2;\n            }\n            r[1 + cnt] = c;\n            ++cnt;\n        }\n    }\n    r[1 + cnt] = '\"';\n    result.length = 1 + cnt + 1;        // trim off any excess length\n    return result;\n}\n\n\n@safe unittest\n{\n    // compile time\n    assert(hexString!\"46 47 48 49 4A 4B\" == \"FGHIJK\");\n    assert(hexString!\"30\\r\\n\\t\\f\\v31 32 33 32 31 30\" == \"0123210\");\n    assert(hexString!\"ab cd\" == hexString!\"ABCD\");\n}\n\n\n/**\n * Convert integer to a range of characters.\n * Intended to be lightweight and fast.\n *\n * Params:\n *      radix = 2, 8, 10, 16\n *      Char = character type for output\n *      letterCase = lower for deadbeef, upper for DEADBEEF\n *      value = integer to convert. Can be uint or ulong. If radix is 10, can also be\n *              int or long.\n * Returns:\n *      Random access range with slicing and everything\n */\n\nauto toChars(ubyte radix = 10, Char = char, LetterCase letterCase = LetterCase.lower, T)(T value)\n    pure nothrow @nogc @safe\nif ((radix == 2 || radix == 8 || radix == 10 || radix == 16) &&\n    (is(Unqual!T == uint) || is(Unqual!T == ulong) ||\n    radix == 10 && (is(Unqual!T == int) || is(Unqual!T == long))))\n{\n    alias UT = Unqual!T;\n\n    static if (radix == 10)\n    {\n        /* uint.max  is 42_9496_7295\n         *  int.max  is 21_4748_3647\n         * ulong.max is 1844_6744_0737_0955_1615\n         *  long.max is  922_3372_0368_5477_5807\n         */\n        static struct Result\n        {\n            void initialize(UT value)\n            {\n                bool neg = false;\n                if (value < 10)\n                {\n                    if (value >= 0)\n                    {\n                        lwr = 0;\n                        upr = 1;\n                        buf[0] = cast(char)(cast(uint) value + '0');\n                        return;\n                    }\n                    value = -value;\n                    neg = true;\n                }\n                auto i = cast(uint) buf.length - 1;\n                while (cast(Unsigned!UT) value >= 10)\n                {\n                    buf[i] = cast(ubyte)('0' + cast(Unsigned!UT) value % 10);\n                    value = unsigned(value) / 10;\n                    --i;\n                }\n                buf[i] = cast(char)(cast(uint) value + '0');\n                if (neg)\n                {\n                    buf[i - 1] = '-';\n                    --i;\n                }\n                lwr = i;\n                upr = cast(uint) buf.length;\n            }\n\n            @property size_t length() { return upr - lwr; }\n\n            alias opDollar = length;\n\n            @property bool empty() { return upr == lwr; }\n\n            @property Char front() { return buf[lwr]; }\n\n            void popFront() { ++lwr; }\n\n            @property Char back() { return buf[upr - 1]; }\n\n            void popBack() { --upr; }\n\n            @property Result save() { return this; }\n\n            Char opIndex(size_t i) { return buf[lwr + i]; }\n\n            Result opSlice(size_t lwr, size_t upr)\n            {\n                Result result = void;\n                result.buf = buf;\n                result.lwr = cast(uint)(this.lwr + lwr);\n                result.upr = cast(uint)(this.lwr + upr);\n                return result;\n            }\n\n          private:\n            uint lwr = void, upr = void;\n            char[(UT.sizeof == 4) ? 10 + isSigned!T : 20] buf = void;\n        }\n\n        Result result = void;\n        result.initialize(value);\n        return result;\n    }\n    else\n    {\n        static if (radix == 2)\n            enum SHIFT = 1;\n        else static if (radix == 8)\n            enum SHIFT = 3;\n        else static if (radix == 16)\n            enum SHIFT = 4;\n        else\n            static assert(0);\n        static struct Result\n        {\n            this(UT value)\n            {\n                this.value = value;\n\n                ubyte len = 1;\n                while (value >>>= SHIFT)\n                   ++len;\n                this.len = len;\n            }\n\n            @property size_t length() { return len; }\n\n            @property bool empty() { return len == 0; }\n\n            @property Char front() { return opIndex(0); }\n\n            void popFront() { --len; }\n\n            @property Char back() { return opIndex(len - 1); }\n\n            void popBack()\n            {\n                value >>>= SHIFT;\n                --len;\n            }\n\n            @property Result save() { return this; }\n\n            Char opIndex(size_t i)\n            {\n                Char c = (value >>> ((len - i - 1) * SHIFT)) & ((1 << SHIFT) - 1);\n                return cast(Char)((radix < 10 || c < 10) ? c + '0'\n                                                         : (letterCase == LetterCase.upper ? c + 'A' - 10\n                                                                                           : c + 'a' - 10));\n            }\n\n            Result opSlice(size_t lwr, size_t upr)\n            {\n                Result result = void;\n                result.value = value >>> ((len - upr) * SHIFT);\n                result.len = cast(ubyte)(upr - lwr);\n                return result;\n            }\n\n          private:\n            UT value;\n            ubyte len;\n        }\n\n        return Result(value);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(toChars(1).equal(\"1\"));\n    assert(toChars(1_000_000).equal(\"1000000\"));\n\n    assert(toChars!(2)(2U).equal(\"10\"));\n    assert(toChars!(16)(255U).equal(\"ff\"));\n    assert(toChars!(16, char, LetterCase.upper)(255U).equal(\"FF\"));\n}\n\n\n@safe unittest\n{\n    import std.array;\n    import std.range;\n\n    {\n        assert(toChars!2(0u).array == \"0\");\n        assert(toChars!2(0Lu).array == \"0\");\n        assert(toChars!2(1u).array == \"1\");\n        assert(toChars!2(1Lu).array == \"1\");\n\n        auto r = toChars!2(2u);\n        assert(r.length == 2);\n        assert(r[0] == '1');\n        assert(r[1 .. 2].array == \"0\");\n        auto s = r.save;\n        assert(r.array == \"10\");\n        assert(s.retro.array == \"01\");\n    }\n    {\n        assert(toChars!8(0u).array == \"0\");\n        assert(toChars!8(0Lu).array == \"0\");\n        assert(toChars!8(1u).array == \"1\");\n        assert(toChars!8(1234567Lu).array == \"4553207\");\n\n        auto r = toChars!8(8u);\n        assert(r.length == 2);\n        assert(r[0] == '1');\n        assert(r[1 .. 2].array == \"0\");\n        auto s = r.save;\n        assert(r.array == \"10\");\n        assert(s.retro.array == \"01\");\n    }\n    {\n        assert(toChars!10(0u).array == \"0\");\n        assert(toChars!10(0Lu).array == \"0\");\n        assert(toChars!10(1u).array == \"1\");\n        assert(toChars!10(1234567Lu).array == \"1234567\");\n        assert(toChars!10(uint.max).array == \"4294967295\");\n        assert(toChars!10(ulong.max).array == \"18446744073709551615\");\n\n        auto r = toChars(10u);\n        assert(r.length == 2);\n        assert(r[0] == '1');\n        assert(r[1 .. 2].array == \"0\");\n        auto s = r.save;\n        assert(r.array == \"10\");\n        assert(s.retro.array == \"01\");\n    }\n    {\n        assert(toChars!10(0).array == \"0\");\n        assert(toChars!10(0L).array == \"0\");\n        assert(toChars!10(1).array == \"1\");\n        assert(toChars!10(1234567L).array == \"1234567\");\n        assert(toChars!10(int.max).array == \"2147483647\");\n        assert(toChars!10(long.max).array == \"9223372036854775807\");\n        assert(toChars!10(-int.max).array == \"-2147483647\");\n        assert(toChars!10(-long.max).array == \"-9223372036854775807\");\n        assert(toChars!10(int.min).array == \"-2147483648\");\n        assert(toChars!10(long.min).array == \"-9223372036854775808\");\n\n        auto r = toChars!10(10);\n        assert(r.length == 2);\n        assert(r[0] == '1');\n        assert(r[1 .. 2].array == \"0\");\n        auto s = r.save;\n        assert(r.array == \"10\");\n        assert(s.retro.array == \"01\");\n    }\n    {\n        assert(toChars!(16)(0u).array == \"0\");\n        assert(toChars!(16)(0Lu).array == \"0\");\n        assert(toChars!(16)(10u).array == \"a\");\n        assert(toChars!(16, char, LetterCase.upper)(0x12AF34567Lu).array == \"12AF34567\");\n\n        auto r = toChars!(16)(16u);\n        assert(r.length == 2);\n        assert(r[0] == '1');\n        assert(r[1 .. 2].array == \"0\");\n        auto s = r.save;\n        assert(r.array == \"10\");\n        assert(s.retro.array == \"01\");\n    }\n}\n\n@safe unittest // opSlice (issue 16192)\n{\n    import std.meta : AliasSeq;\n\n    static struct Test { ubyte radix; uint number; }\n\n    alias tests = AliasSeq!(\n        Test(2, 0b1_0110_0111u),\n        Test(2, 0b10_1100_1110u),\n        Test(8, octal!123456701u),\n        Test(8, octal!1234567012u),\n        Test(10, 123456789u),\n        Test(10, 1234567890u),\n        Test(16, 0x789ABCDu),\n        Test(16, 0x789ABCDEu),\n    );\n\n    foreach (test; tests)\n    {\n        enum ubyte radix = test.radix;\n        auto original = toChars!radix(test.number);\n\n        // opSlice vs popFront\n        auto r = original.save;\n        size_t i = 0;\n        for (; !r.empty; r.popFront(), ++i)\n        {\n            assert(original[i .. original.length].tupleof == r.tupleof);\n                // tupleof is used to work around issue 16216.\n        }\n\n        // opSlice vs popBack\n        r = original.save;\n        i = 0;\n        for (; !r.empty; r.popBack(), ++i)\n        {\n            assert(original[0 .. original.length - i].tupleof == r.tupleof);\n        }\n\n        // opSlice vs both popFront and popBack\n        r = original.save;\n        i = 0;\n        for (; r.length >= 2; r.popFront(), r.popBack(), ++i)\n        {\n            assert(original[i .. original.length - i].tupleof == r.tupleof);\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/csv.d",
    "content": "//Written in the D programming language\n\n/**\n * Implements functionality to read Comma Separated Values and its variants\n * from an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of `dchar`.\n *\n * Comma Separated Values provide a simple means to transfer and store\n * tabular data. It has been common for programs to use their own\n * variant of the CSV format. This parser will loosely follow the\n * $(HTTP tools.ietf.org/html/rfc4180, RFC-4180). CSV input should adhere\n * to the following criteria (differences from RFC-4180 in parentheses):\n *\n * $(UL\n *     $(LI A record is separated by a new line (CRLF,LF,CR))\n *     $(LI A final record may end with a new line)\n *     $(LI A header may be provided as the first record in input)\n *     $(LI A record has fields separated by a comma (customizable))\n *     $(LI A field containing new lines, commas, or double quotes\n *          should be enclosed in double quotes (customizable))\n *     $(LI Double quotes in a field are escaped with a double quote)\n *     $(LI Each record should contain the same number of fields)\n *   )\n *\n * Example:\n *\n * -------\n * import std.algorithm;\n * import std.array;\n * import std.csv;\n * import std.stdio;\n * import std.typecons;\n *\n * void main()\n * {\n *     auto text = \"Joe,Carpenter,300000\\nFred,Blacksmith,400000\\r\\n\";\n *\n *     foreach (record; csvReader!(Tuple!(string, string, int))(text))\n *     {\n *         writefln(\"%s works as a %s and earns $%d per year\",\n *                  record[0], record[1], record[2]);\n *     }\n *\n *     // To read the same string from the file \"filename.csv\":\n *\n *     auto file = File(\"filename.csv\", \"r\");\n *     foreach (record;\n *         file.byLine.joiner(\"\\n\").csvReader!(Tuple!(string, string, int)))\n *     {\n *         writefln(\"%s works as a %s and earns $%d per year\",\n *                  record[0], record[1], record[2]);\n *     }\n }\n * }\n * -------\n *\n * When an input contains a header the `Contents` can be specified as an\n * associative array. Passing null to signify that a header is present.\n *\n * -------\n * auto text = \"Name,Occupation,Salary\\r\"\n *     \"Joe,Carpenter,300000\\nFred,Blacksmith,400000\\r\\n\";\n *\n * foreach (record; csvReader!(string[string])\n *         (text, null))\n * {\n *     writefln(\"%s works as a %s and earns $%s per year.\",\n *              record[\"Name\"], record[\"Occupation\"],\n *              record[\"Salary\"]);\n * }\n * -------\n *\n * This module allows content to be iterated by record stored in a struct,\n * class, associative array, or as a range of fields. Upon detection of an\n * error an CSVException is thrown (can be disabled). csvNextToken has been\n * made public to allow for attempted recovery.\n *\n * Disabling exceptions will lift many restrictions specified above. A quote\n * can appear in a field if the field was not quoted. If in a quoted field any\n * quote by itself, not at the end of a field, will end processing for that\n * field. The field is ended when there is no input, even if the quote was not\n * closed.\n *\n *   See_Also:\n *      $(HTTP en.wikipedia.org/wiki/Comma-separated_values, Wikipedia\n *      Comma-separated values)\n *\n *   Copyright: Copyright 2011\n *   License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n *   Authors:   Jesse Phillips\n *   Source:    $(PHOBOSSRC std/csv.d)\n */\nmodule std.csv;\n\nimport std.conv;\nimport std.exception;  // basicExceptionCtors\nimport std.range.primitives;\nimport std.traits;\n\n/**\n * Exception containing the row and column for when an exception was thrown.\n *\n * Numbering of both row and col start at one and corresponds to the location\n * in the file rather than any specified header. Special consideration should\n * be made when there is failure to match the header see $(LREF\n * HeaderMismatchException) for details.\n *\n * When performing type conversions, $(REF ConvException, std,conv) is stored in\n * the `next` field.\n */\nclass CSVException : Exception\n{\n    ///\n    size_t row, col;\n\n    // FIXME: Use std.exception.basicExceptionCtors here once bug #11500 is fixed\n\n    this(string msg, string file = __FILE__, size_t line = __LINE__,\n         Throwable next = null) @nogc @safe pure nothrow\n    {\n        super(msg, file, line, next);\n    }\n\n    this(string msg, Throwable next, string file = __FILE__,\n         size_t line = __LINE__) @nogc @safe pure nothrow\n    {\n        super(msg, file, line, next);\n    }\n\n    this(string msg, size_t row, size_t col, Throwable next = null,\n         string file = __FILE__, size_t line = __LINE__) @nogc @safe pure nothrow\n    {\n        super(msg, next, file, line);\n        this.row = row;\n        this.col = col;\n    }\n\n    override string toString() @safe pure const\n    {\n        return \"(Row: \" ~ to!string(row) ~\n              \", Col: \" ~ to!string(col) ~ \") \" ~ msg;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.exception : collectException;\n    import std.algorithm.searching : count;\n    string text = \"a,b,c\\nHello,65\";\n    auto ex = collectException!CSVException(csvReader(text).count);\n    assert(ex.toString == \"(Row: 0, Col: 0) Row 2's length 2 does not match previous length of 3.\");\n}\n\n///\n@safe unittest\n{\n    import std.exception : collectException;\n    import std.algorithm.searching : count;\n    import std.typecons : Tuple;\n    string text = \"a,b\\nHello,65\";\n    auto ex = collectException!CSVException(csvReader!(Tuple!(string,int))(text).count);\n    assert(ex.toString == \"(Row: 1, Col: 2) Unexpected 'b' when converting from type string to type int\");\n}\n\n@safe pure unittest\n{\n    import std.string;\n    auto e1 = new Exception(\"Foobar\");\n    auto e2 = new CSVException(\"args\", e1);\n    assert(e2.next is e1);\n\n    size_t r = 13;\n    size_t c = 37;\n\n    auto e3 = new CSVException(\"argv\", r, c);\n    assert(e3.row == r);\n    assert(e3.col == c);\n\n    auto em = e3.toString();\n    assert(em.indexOf(\"13\") != -1);\n    assert(em.indexOf(\"37\") != -1);\n}\n\n/**\n * Exception thrown when a Token is identified to not be completed: a quote is\n * found in an unquoted field, data continues after a closing quote, or the\n * quoted field was not closed before data was empty.\n */\nclass IncompleteCellException : CSVException\n{\n    /**\n     * Data pulled from input before finding a problem\n     *\n     * This field is populated when using $(LREF csvReader)\n     * but not by $(LREF csvNextToken) as this data will have\n     * already been fed to the output range.\n     */\n    dstring partialData;\n\n    mixin basicExceptionCtors;\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    string text = \"a,\\\"b,c\\nHello,65,2.5\";\n    assertThrown!IncompleteCellException(text.csvReader([\"a\",\"b\",\"c\"]));\n}\n\n@safe pure unittest\n{\n    auto e1 = new Exception(\"Foobar\");\n    auto e2 = new IncompleteCellException(\"args\", e1);\n    assert(e2.next is e1);\n}\n\n/**\n * Exception thrown under different conditions based on the type of $(D\n * Contents).\n *\n * Structure, Class, and Associative Array\n * $(UL\n *     $(LI When a header is provided but a matching column is not found)\n *  )\n *\n * Other\n * $(UL\n *     $(LI When a header is provided but a matching column is not found)\n *     $(LI Order did not match that found in the input)\n *  )\n *\n * Since a row and column is not meaningful when a column specified by the\n * header is not found in the data, both row and col will be zero. Otherwise\n * row is always one and col is the first instance found in header that\n * occurred before the previous starting at one.\n */\nclass HeaderMismatchException : CSVException\n{\n    mixin basicExceptionCtors;\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    string text = \"a,b,c\\nHello,65,2.5\";\n    assertThrown!HeaderMismatchException(text.csvReader([\"b\",\"c\",\"invalid\"]));\n}\n\n@safe pure unittest\n{\n    auto e1 = new Exception(\"Foobar\");\n    auto e2 = new HeaderMismatchException(\"args\", e1);\n    assert(e2.next is e1);\n}\n\n/**\n * Determines the behavior for when an error is detected.\n *\n * Disabling exception will follow these rules:\n * $(UL\n *     $(LI A quote can appear in a field if the field was not quoted.)\n *     $(LI If in a quoted field any quote by itself, not at the end of a\n *     field, will end processing for that field.)\n *     $(LI The field is ended when there is no input, even if the quote was\n *     not closed.)\n *     $(LI If the given header does not match the order in the input, the\n *     content will return as it is found in the input.)\n *     $(LI If the given header contains columns not found in the input they\n *     will be ignored.)\n *  )\n*/\nenum Malformed\n{\n    ignore,           /// No exceptions are thrown due to incorrect CSV.\n    throwException    /// Use exceptions when input has incorrect CSV.\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.searching : count;\n    import std.exception : assertThrown;\n\n    string text = \"a,b,c\\nHello,65,\\\"2.5\";\n    assertThrown!IncompleteCellException(text.csvReader.count);\n\n    // ignore the exceptions and try to handle invalid CSV\n    auto firstLine = text.csvReader!(string, Malformed.ignore)(null).front;\n    assert(firstLine.equal([\"Hello\", \"65\", \"2.5\"]));\n}\n\n/**\nReturns an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\nfor iterating over records found in `input`.\n\nAn optional `header` can be provided. The first record will be read in\nas the header. If `Contents` is a struct then the header provided is\nexpected to correspond to the fields in the struct. When `Contents` is\nnot a type which can contain the entire record, the `header` must be\nprovided in the same order as the input or an exception is thrown.\n\nReturns:\n       An input range R as defined by\n       $(REF isInputRange, std,range,primitives). When `Contents` is a\n       struct, class, or an associative array, the element type of R is\n       `Contents`, otherwise the element type of R is itself a range with\n       element type `Contents`.\n\n       If a `header` argument is provided,\n       the returned range provides a `header` field for accessing the header\n       from the input in array form.\n\nThrows:\n      $(LREF CSVException) When a quote is found in an unquoted field,\n      data continues after a closing quote, the quoted field was not\n      closed before data was empty, a conversion failed, or when the row's\n      length does not match the previous length.\n\n      $(LREF HeaderMismatchException)  when a header is provided but a\n      matching column is not found or the order did not match that found in\n      the input. Read the exception documentation for specific details of\n      when the exception is thrown for different types of `Contents`.\n*/\nauto csvReader(Contents = string,Malformed ErrorLevel = Malformed.throwException, Range, Separator = char)(Range input,\n                 Separator delimiter = ',', Separator quote = '\"')\nif (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar)\n    && isSomeChar!(Separator)\n    && !is(Contents T : T[U], U : string))\n{\n    return CsvReader!(Contents,ErrorLevel,Range,\n                    Unqual!(ElementType!Range),string[])\n        (input, delimiter, quote);\n}\n\n/// ditto\nauto csvReader(Contents = string,\n               Malformed ErrorLevel = Malformed.throwException,\n               Range, Header, Separator = char)\n                (Range input, Header header,\n                 Separator delimiter = ',', Separator quote = '\"')\nif (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar)\n    && isSomeChar!(Separator)\n    && isForwardRange!Header\n    && isSomeString!(ElementType!Header))\n{\n    return CsvReader!(Contents,ErrorLevel,Range,\n                    Unqual!(ElementType!Range),Header)\n        (input, header, delimiter, quote);\n}\n\n/// ditto\nauto csvReader(Contents = string,\n               Malformed ErrorLevel = Malformed.throwException,\n               Range, Header, Separator = char)\n                (Range input, Header header,\n                 Separator delimiter = ',', Separator quote = '\"')\nif (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar)\n    && isSomeChar!(Separator)\n    && is(Header : typeof(null)))\n{\n    return CsvReader!(Contents,ErrorLevel,Range,\n                    Unqual!(ElementType!Range),string[])\n        (input, cast(string[]) null, delimiter, quote);\n}\n\n\n/**\nThe `Contents` of the input can be provided if all the records are the\nsame type such as all integer data:\n*/\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    string text = \"76,26,22\";\n    auto records = text.csvReader!int;\n    assert(records.equal!equal([\n        [76, 26, 22],\n    ]));\n}\n\n/**\nUsing a struct with modified delimiter:\n*/\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    string text = \"Hello;65;2.5\\nWorld;123;7.5\";\n    struct Layout\n    {\n        string name;\n        int value;\n        double other;\n    }\n\n    auto records = text.csvReader!Layout(';');\n    assert(records.equal([\n        Layout(\"Hello\", 65, 2.5),\n        Layout(\"World\", 123, 7.5),\n    ]));\n}\n\n/**\nSpecifying `ErrorLevel` as $(LREF Malformed.ignore) will lift restrictions\non the format. This example shows that an exception is not thrown when\nfinding a quote in a field not quoted.\n*/\n@safe unittest\n{\n    string text = \"A \\\" is now part of the data\";\n    auto records = text.csvReader!(string, Malformed.ignore);\n    auto record = records.front;\n\n    assert(record.front == text);\n}\n\n/// Read only column \"b\"\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    string text = \"a,b,c\\nHello,65,63.63\\nWorld,123,3673.562\";\n    auto records = text.csvReader!int([\"b\"]);\n\n    assert(records.equal!equal([\n        [65],\n        [123],\n    ]));\n}\n\n/// Read while rearranging the columns by specifying a header with a different order\"\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    string text = \"a,b,c\\nHello,65,2.5\\nWorld,123,7.5\";\n    struct Layout\n    {\n        int value;\n        double other;\n        string name;\n    }\n\n    auto records = text.csvReader!Layout([\"b\",\"c\",\"a\"]);\n    assert(records.equal([\n        Layout(65, 2.5, \"Hello\"),\n        Layout(123, 7.5, \"World\")\n    ]));\n}\n\n/**\nThe header can also be left empty if the input contains a header row\nand all columns should be iterated.\nThe header from the input can always be accessed from the `header` field.\n*/\n@safe unittest\n{\n    string text = \"a,b,c\\nHello,65,63.63\";\n    auto records = text.csvReader(null);\n\n    assert(records.header == [\"a\",\"b\",\"c\"]);\n}\n\n// Test standard iteration over input.\n@safe pure unittest\n{\n    string str = `one,\"two \"\"quoted\"\"\"` ~ \"\\n\\\"three\\nnew line\\\",\\nfive,six\";\n    auto records = csvReader(str);\n\n    int count;\n    foreach (record; records)\n    {\n        foreach (cell; record)\n        {\n            count++;\n        }\n    }\n    assert(count == 6);\n}\n\n// Test newline on last record\n@safe pure unittest\n{\n    string str = \"one,two\\nthree,four\\n\";\n    auto records = csvReader(str);\n    records.popFront();\n    records.popFront();\n    assert(records.empty);\n}\n\n// Test shorter row length\n@safe pure unittest\n{\n    wstring str = \"one,1\\ntwo\\nthree\"w;\n    struct Layout\n    {\n        string name;\n        int value;\n    }\n\n    Layout[3] ans;\n    ans[0].name = \"one\";\n    ans[0].value = 1;\n    ans[1].name = \"two\";\n    ans[1].value = 0;\n    ans[2].name = \"three\";\n    ans[2].value = 0;\n\n    auto records = csvReader!(Layout,Malformed.ignore)(str);\n\n    int count;\n    foreach (record; records)\n    {\n        assert(ans[count].name == record.name);\n        assert(ans[count].value == record.value);\n        count++;\n    }\n}\n\n// Test shorter row length exception\n@safe pure unittest\n{\n    import std.exception;\n\n    struct A\n    {\n        string a,b,c;\n    }\n\n    auto strs = [\"one,1\\ntwo\",\n                 \"one\\ntwo,2,二\\nthree,3,三\",\n                 \"one\\ntwo,2\\nthree,3\",\n                 \"one,1\\ntwo\\nthree,3\"];\n\n    foreach (str; strs)\n    {\n        auto records = csvReader!A(str);\n        assertThrown!CSVException((){foreach (record; records) { }}());\n    }\n}\n\n\n// Test structure conversion interface with unicode.\n@safe pure unittest\n{\n    import std.math : abs;\n\n    wstring str = \"\\U00010143Hello,65,63.63\\nWorld,123,3673.562\"w;\n    struct Layout\n    {\n        string name;\n        int value;\n        double other;\n    }\n\n    Layout[2] ans;\n    ans[0].name = \"\\U00010143Hello\";\n    ans[0].value = 65;\n    ans[0].other = 63.63;\n    ans[1].name = \"World\";\n    ans[1].value = 123;\n    ans[1].other = 3673.562;\n\n    auto records = csvReader!Layout(str);\n\n    int count;\n    foreach (record; records)\n    {\n        assert(ans[count].name == record.name);\n        assert(ans[count].value == record.value);\n        assert(abs(ans[count].other - record.other) < 0.00001);\n        count++;\n    }\n    assert(count == ans.length);\n}\n\n// Test input conversion interface\n@safe pure unittest\n{\n    import std.algorithm;\n    string str = `76,26,22`;\n    int[] ans = [76,26,22];\n    auto records = csvReader!int(str);\n\n    foreach (record; records)\n    {\n        assert(equal(record, ans));\n    }\n}\n\n// Test struct & header interface and same unicode\n@safe unittest\n{\n    import std.math : abs;\n\n    string str = \"a,b,c\\nHello,65,63.63\\n➊➋➂❹,123,3673.562\";\n    struct Layout\n    {\n        int value;\n        double other;\n        string name;\n    }\n\n    auto records = csvReader!Layout(str, [\"b\",\"c\",\"a\"]);\n\n    Layout[2] ans;\n    ans[0].name = \"Hello\";\n    ans[0].value = 65;\n    ans[0].other = 63.63;\n    ans[1].name = \"➊➋➂❹\";\n    ans[1].value = 123;\n    ans[1].other = 3673.562;\n\n    int count;\n    foreach (record; records)\n    {\n        assert(ans[count].name == record.name);\n        assert(ans[count].value == record.value);\n        assert(abs(ans[count].other - record.other) < 0.00001);\n        count++;\n    }\n    assert(count == ans.length);\n\n}\n\n// Test header interface\n@safe unittest\n{\n    import std.algorithm;\n\n    string str = \"a,b,c\\nHello,65,63.63\\nWorld,123,3673.562\";\n    auto records = csvReader!int(str, [\"b\"]);\n\n    auto ans = [[65],[123]];\n    foreach (record; records)\n    {\n        assert(equal(record, ans.front));\n        ans.popFront();\n    }\n\n    try\n    {\n        csvReader(str, [\"c\",\"b\"]);\n        assert(0);\n    }\n    catch (HeaderMismatchException e)\n    {\n        assert(e.col == 2);\n    }\n    auto records2 = csvReader!(string,Malformed.ignore)\n       (str, [\"b\",\"a\"], ',', '\"');\n\n    auto ans2 = [[\"Hello\",\"65\"],[\"World\",\"123\"]];\n    foreach (record; records2)\n    {\n        assert(equal(record, ans2.front));\n        ans2.popFront();\n    }\n\n    str = \"a,c,e\\nJoe,Carpenter,300000\\nFred,Fly,4\";\n    records2 = csvReader!(string,Malformed.ignore)\n       (str, [\"a\",\"b\",\"c\",\"d\"], ',', '\"');\n\n    ans2 = [[\"Joe\",\"Carpenter\"],[\"Fred\",\"Fly\"]];\n    foreach (record; records2)\n    {\n        assert(equal(record, ans2.front));\n        ans2.popFront();\n    }\n}\n\n// Test null header interface\n@safe unittest\n{\n    string str = \"a,b,c\\nHello,65,63.63\\nWorld,123,3673.562\";\n    auto records = csvReader(str, [\"a\"]);\n\n    assert(records.header == [\"a\",\"b\",\"c\"]);\n}\n\n// Test unchecked read\n@safe pure unittest\n{\n    string str = \"one \\\"quoted\\\"\";\n    foreach (record; csvReader!(string,Malformed.ignore)(str))\n    {\n        foreach (cell; record)\n        {\n            assert(cell == \"one \\\"quoted\\\"\");\n        }\n    }\n\n    str = \"one \\\"quoted\\\",two \\\"quoted\\\" end\";\n    struct Ans\n    {\n        string a,b;\n    }\n    foreach (record; csvReader!(Ans,Malformed.ignore)(str))\n    {\n        assert(record.a == \"one \\\"quoted\\\"\");\n        assert(record.b == \"two \\\"quoted\\\" end\");\n    }\n}\n\n// Test partial data returned\n@safe pure unittest\n{\n    string str = \"\\\"one\\nnew line\";\n\n    try\n    {\n        foreach (record; csvReader(str))\n        {}\n        assert(0);\n    }\n    catch (IncompleteCellException ice)\n    {\n        assert(ice.partialData == \"one\\nnew line\");\n    }\n}\n\n// Test Windows line break\n@safe pure unittest\n{\n    string str = \"one,two\\r\\nthree\";\n\n    auto records = csvReader(str);\n    auto record = records.front;\n    assert(record.front == \"one\");\n    record.popFront();\n    assert(record.front == \"two\");\n    records.popFront();\n    record = records.front;\n    assert(record.front == \"three\");\n}\n\n\n// Test associative array support with unicode separator\n@safe unittest\n{\n  string str = \"1❁2❁3\\n34❁65❁63\\n34❁65❁63\";\n\n  auto records = csvReader!(string[string])(str,[\"3\",\"1\"],'❁');\n  int count;\n  foreach (record; records)\n  {\n      count++;\n      assert(record[\"1\"] == \"34\");\n      assert(record[\"3\"] == \"63\");\n  }\n  assert(count == 2);\n}\n\n// Test restricted range\n@safe unittest\n{\n    import std.typecons;\n    struct InputRange\n    {\n        dstring text;\n\n        this(dstring txt)\n        {\n            text = txt;\n        }\n\n        @property auto empty()\n        {\n            return text.empty;\n        }\n\n        void popFront()\n        {\n            text.popFront();\n        }\n\n        @property dchar front()\n        {\n            return text[0];\n        }\n    }\n    auto ir = InputRange(\"Name,Occupation,Salary\\r\"d~\n          \"Joe,Carpenter,300000\\nFred,Blacksmith,400000\\r\\n\"d);\n\n    foreach (record; csvReader(ir, cast(string[]) null))\n        foreach (cell; record) {}\n    foreach (record; csvReader!(Tuple!(string, string, int))\n            (ir,cast(string[]) null)) {}\n    foreach (record; csvReader!(string[string])\n            (ir,cast(string[]) null)) {}\n}\n\n@safe unittest // const/immutable dchars\n{\n    import std.algorithm.iteration : map;\n    import std.array : array;\n    const(dchar)[] c = \"foo,bar\\n\";\n    assert(csvReader(c).map!array.array == [[\"foo\", \"bar\"]]);\n    immutable(dchar)[] i = \"foo,bar\\n\";\n    assert(csvReader(i).map!array.array == [[\"foo\", \"bar\"]]);\n}\n\n/*\n * This struct is stored on the heap for when the structures\n * are passed around.\n */\nprivate pure struct Input(Range, Malformed ErrorLevel)\n{\n    Range range;\n    size_t row, col;\n    static if (ErrorLevel == Malformed.throwException)\n        size_t rowLength;\n}\n\n/*\n * Range for iterating CSV records.\n *\n * This range is returned by the $(LREF csvReader) functions. It can be\n * created in a similar manner to allow `ErrorLevel` be set to $(LREF\n * Malformed).ignore if best guess processing should take place.\n */\nprivate struct CsvReader(Contents, Malformed ErrorLevel, Range, Separator, Header)\nif (isSomeChar!Separator && isInputRange!Range\n    && is(Unqual!(ElementType!Range) == dchar)\n    && isForwardRange!Header && isSomeString!(ElementType!Header))\n{\nprivate:\n    Input!(Range, ErrorLevel)* _input;\n    Separator _separator;\n    Separator _quote;\n    size_t[] indices;\n    bool _empty;\n    static if (is(Contents == struct) || is(Contents == class))\n    {\n        Contents recordContent;\n        CsvRecord!(string, ErrorLevel, Range, Separator) recordRange;\n    }\n    else static if (is(Contents T : T[U], U : string))\n    {\n        Contents recordContent;\n        CsvRecord!(T, ErrorLevel, Range, Separator) recordRange;\n    }\n    else\n        CsvRecord!(Contents, ErrorLevel, Range, Separator) recordRange;\npublic:\n    /**\n     * Header from the input in array form.\n     *\n     * -------\n     * string str = \"a,b,c\\nHello,65,63.63\";\n     * auto records = csvReader(str, [\"a\"]);\n     *\n     * assert(records.header == [\"a\",\"b\",\"c\"]);\n     * -------\n     */\n    string[] header;\n\n    /**\n     * Constructor to initialize the input, delimiter and quote for input\n     * without a header.\n     *\n     * -------\n     * string str = `76;^26^;22`;\n     * int[] ans = [76,26,22];\n     * auto records = CsvReader!(int,Malformed.ignore,string,char,string[])\n     *       (str, ';', '^');\n     *\n     * foreach (record; records)\n     * {\n     *    assert(equal(record, ans));\n     * }\n     * -------\n     */\n    this(Range input, Separator delimiter, Separator quote)\n    {\n        _input = new Input!(Range, ErrorLevel)(input);\n        _separator = delimiter;\n        _quote = quote;\n\n        prime();\n    }\n\n    /**\n     * Constructor to initialize the input, delimiter and quote for input\n     * with a header.\n     *\n     * -------\n     * string str = `high;mean;low\\n76;^26^;22`;\n     * auto records = CsvReader!(int,Malformed.ignore,string,char,string[])\n     *       (str, [\"high\",\"low\"], ';', '^');\n     *\n     * int[] ans = [76,22];\n     * foreach (record; records)\n     * {\n     *    assert(equal(record, ans));\n     * }\n     * -------\n     *\n     * Throws:\n     *       $(LREF HeaderMismatchException)  when a header is provided but a\n     *       matching column is not found or the order did not match that found\n     *       in the input (non-struct).\n     */\n    this(Range input, Header colHeaders, Separator delimiter, Separator quote)\n    {\n        _input = new Input!(Range, ErrorLevel)(input);\n        _separator = delimiter;\n        _quote = quote;\n\n        size_t[string] colToIndex;\n        foreach (h; colHeaders)\n        {\n            colToIndex[h] = size_t.max;\n        }\n\n        auto r = CsvRecord!(string, ErrorLevel, Range, Separator)\n            (_input, _separator, _quote, indices);\n\n        size_t colIndex;\n        foreach (col; r)\n        {\n            header ~= col;\n            auto ptr = col in colToIndex;\n            if (ptr)\n                *ptr = colIndex;\n            colIndex++;\n        }\n        // The above loop empties the header row.\n        recordRange._empty = true;\n\n        indices.length = colToIndex.length;\n        int i;\n        foreach (h; colHeaders)\n        {\n            immutable index = colToIndex[h];\n            static if (ErrorLevel != Malformed.ignore)\n                if (index == size_t.max)\n                    throw new HeaderMismatchException\n                        (\"Header not found: \" ~ to!string(h));\n            indices[i++] = index;\n        }\n\n        static if (!is(Contents == struct) && !is(Contents == class))\n        {\n            static if (is(Contents T : T[U], U : string))\n            {\n                import std.algorithm.sorting : sort;\n                sort(indices);\n            }\n            else static if (ErrorLevel == Malformed.ignore)\n            {\n                import std.algorithm.sorting : sort;\n                sort(indices);\n            }\n            else\n            {\n                import std.algorithm.searching : findAdjacent;\n                import std.algorithm.sorting : isSorted;\n                if (!isSorted(indices))\n                {\n                    auto ex = new HeaderMismatchException\n                           (\"Header in input does not match specified header.\");\n                    findAdjacent!\"a > b\"(indices);\n                    ex.row = 1;\n                    ex.col = indices.front;\n\n                    throw ex;\n                }\n            }\n        }\n\n        popFront();\n    }\n\n    /**\n     * Part of an input range as defined by\n     * $(REF isInputRange, std,range,primitives).\n     *\n     * Returns:\n     *      If `Contents` is a struct, will be filled with record data.\n     *\n     *      If `Contents` is a class, will be filled with record data.\n     *\n     *      If `Contents` is a associative array, will be filled\n     *      with record data.\n     *\n     *      If `Contents` is non-struct, a $(LREF CsvRecord) will be\n     *      returned.\n     */\n    @property auto front()\n    {\n        assert(!empty);\n        static if (is(Contents == struct) || is(Contents == class))\n        {\n            return recordContent;\n        }\n        else static if (is(Contents T : T[U], U : string))\n        {\n            return recordContent;\n        }\n        else\n        {\n            return recordRange;\n        }\n    }\n\n    /**\n     * Part of an input range as defined by\n     * $(REF isInputRange, std,range,primitives).\n     */\n    @property bool empty() @safe @nogc pure nothrow const\n    {\n        return _empty;\n    }\n\n    /**\n     * Part of an input range as defined by\n     * $(REF isInputRange, std,range,primitives).\n     *\n     * Throws:\n     *       $(LREF CSVException) When a quote is found in an unquoted field,\n     *       data continues after a closing quote, the quoted field was not\n     *       closed before data was empty, a conversion failed, or when the\n     *       row's length does not match the previous length.\n     */\n    void popFront()\n    {\n        while (!recordRange.empty)\n        {\n            recordRange.popFront();\n        }\n\n        static if (ErrorLevel == Malformed.throwException)\n            if (_input.rowLength == 0)\n                _input.rowLength = _input.col;\n\n        _input.col = 0;\n\n        if (!_input.range.empty)\n        {\n            if (_input.range.front == '\\r')\n            {\n                _input.range.popFront();\n                if (!_input.range.empty && _input.range.front == '\\n')\n                    _input.range.popFront();\n            }\n            else if (_input.range.front == '\\n')\n                _input.range.popFront();\n        }\n\n        if (_input.range.empty)\n        {\n            _empty = true;\n            return;\n        }\n\n        prime();\n    }\n\n    private void prime()\n    {\n        if (_empty)\n            return;\n        _input.row++;\n        static if (is(Contents == struct) || is(Contents == class))\n        {\n            recordRange = typeof(recordRange)\n                                 (_input, _separator, _quote, null);\n        }\n        else\n        {\n            recordRange = typeof(recordRange)\n                                 (_input, _separator, _quote, indices);\n        }\n\n        static if (is(Contents T : T[U], U : string))\n        {\n            T[U] aa;\n            try\n            {\n                for (; !recordRange.empty; recordRange.popFront())\n                {\n                    aa[header[_input.col-1]] = recordRange.front;\n                }\n            }\n            catch (ConvException e)\n            {\n                throw new CSVException(e.msg, _input.row, _input.col, e);\n            }\n\n            recordContent = aa;\n        }\n        else static if (is(Contents == struct) || is(Contents == class))\n        {\n            static if (is(Contents == class))\n                recordContent = new typeof(recordContent)();\n            else\n                recordContent = typeof(recordContent).init;\n            size_t colIndex;\n            try\n            {\n                for (; !recordRange.empty;)\n                {\n                    auto colData = recordRange.front;\n                    scope(exit) colIndex++;\n                    if (indices.length > 0)\n                    {\n                        foreach (ti, ToType; Fields!(Contents))\n                        {\n                            if (indices[ti] == colIndex)\n                            {\n                                static if (!isSomeString!ToType) skipWS(colData);\n                                recordContent.tupleof[ti] = to!ToType(colData);\n                            }\n                        }\n                    }\n                    else\n                    {\n                        foreach (ti, ToType; Fields!(Contents))\n                        {\n                            if (ti == colIndex)\n                            {\n                                static if (!isSomeString!ToType) skipWS(colData);\n                                recordContent.tupleof[ti] = to!ToType(colData);\n                            }\n                        }\n                    }\n                    recordRange.popFront();\n                }\n            }\n            catch (ConvException e)\n            {\n                throw new CSVException(e.msg, _input.row, colIndex, e);\n            }\n        }\n    }\n}\n\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    string str = `76;^26^;22`;\n    int[] ans = [76,26,22];\n    auto records = CsvReader!(int,Malformed.ignore,string,char,string[])\n          (str, ';', '^');\n\n    foreach (record; records)\n    {\n        assert(equal(record, ans));\n    }\n}\n\n// Bugzilla 15545\n// @system due to the catch for Throwable\n@system pure unittest\n{\n    import std.exception : assertNotThrown;\n    enum failData =\n    \"name, surname, age\n    Joe, Joker, 99\\r\";\n    auto r = csvReader(failData);\n    assertNotThrown((){foreach (entry; r){}}());\n}\n\n/*\n * This input range is accessible through $(LREF CsvReader) when the\n * requested `Contents` type is neither a structure or an associative array.\n */\nprivate struct CsvRecord(Contents, Malformed ErrorLevel, Range, Separator)\nif (!is(Contents == class) && !is(Contents == struct))\n{\n    import std.array : appender;\nprivate:\n    Input!(Range, ErrorLevel)* _input;\n    Separator _separator;\n    Separator _quote;\n    Contents curContentsoken;\n    typeof(appender!(dchar[])()) _front;\n    bool _empty;\n    size_t[] _popCount;\npublic:\n    /*\n     * Params:\n     *      input = Pointer to a character $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n     *      delimiter = Separator for each column\n     *      quote = Character used for quotation\n     *      indices = An array containing which columns will be returned.\n     *             If empty, all columns are returned. List must be in order.\n     */\n    this(Input!(Range, ErrorLevel)* input, Separator delimiter,\n         Separator quote, size_t[] indices)\n    {\n        _input = input;\n        _separator = delimiter;\n        _quote = quote;\n        _front = appender!(dchar[])();\n        _popCount = indices.dup;\n\n        // If a header was given, each call to popFront will need\n        // to eliminate so many tokens. This calculates\n        // how many will be skipped to get to the next header column\n        size_t normalizer;\n        foreach (ref c; _popCount)\n        {\n            static if (ErrorLevel == Malformed.ignore)\n            {\n                // If we are not throwing exceptions\n                // a header may not exist, indices are sorted\n                // and will be size_t.max if not found.\n                if (c == size_t.max)\n                    break;\n            }\n            c -= normalizer;\n            normalizer += c + 1;\n        }\n\n        prime();\n    }\n\n    /**\n     * Part of an input range as defined by\n     * $(REF isInputRange, std,range,primitives).\n     */\n    @property Contents front() @safe pure\n    {\n        assert(!empty);\n        return curContentsoken;\n    }\n\n    /**\n     * Part of an input range as defined by\n     * $(REF isInputRange, std,range,primitives).\n     */\n    @property bool empty() @safe pure nothrow @nogc const\n    {\n        return _empty;\n    }\n\n    /*\n     * CsvRecord is complete when input\n     * is empty or starts with record break\n     */\n    private bool recordEnd()\n    {\n        if (_input.range.empty\n           || _input.range.front == '\\n'\n           || _input.range.front == '\\r')\n        {\n            return true;\n        }\n        return false;\n    }\n\n\n    /**\n     * Part of an input range as defined by\n     * $(REF isInputRange, std,range,primitives).\n     *\n     * Throws:\n     *       $(LREF CSVException) When a quote is found in an unquoted field,\n     *       data continues after a closing quote, the quoted field was not\n     *       closed before data was empty, a conversion failed, or when the\n     *       row's length does not match the previous length.\n     */\n    void popFront()\n    {\n        static if (ErrorLevel == Malformed.throwException)\n            import std.format : format;\n        // Skip last of record when header is depleted.\n        if (_popCount.ptr && _popCount.empty)\n            while (!recordEnd())\n            {\n                prime(1);\n            }\n\n        if (recordEnd())\n        {\n            _empty = true;\n            static if (ErrorLevel == Malformed.throwException)\n                if (_input.rowLength != 0)\n                    if (_input.col != _input.rowLength)\n                        throw new CSVException(\n                           format(\"Row %s's length %s does not match \"~\n                                  \"previous length of %s.\", _input.row,\n                                  _input.col, _input.rowLength));\n            return;\n        }\n        else\n        {\n            static if (ErrorLevel == Malformed.throwException)\n                if (_input.rowLength != 0)\n                    if (_input.col > _input.rowLength)\n                        throw new CSVException(\n                           format(\"Row %s's length %s does not match \"~\n                                  \"previous length of %s.\", _input.row,\n                                  _input.col, _input.rowLength));\n        }\n\n        // Separator is left on the end of input from the last call.\n        // This cannot be moved to after the call to csvNextToken as\n        // there may be an empty record after it.\n        if (_input.range.front == _separator)\n            _input.range.popFront();\n\n        _front.shrinkTo(0);\n\n        prime();\n    }\n\n    /*\n     * Handles moving to the next skipNum token.\n     */\n    private void prime(size_t skipNum)\n    {\n        foreach (i; 0 .. skipNum)\n        {\n            _input.col++;\n            _front.shrinkTo(0);\n            if (_input.range.front == _separator)\n                _input.range.popFront();\n\n            try\n                csvNextToken!(Range, ErrorLevel, Separator)\n                                   (_input.range, _front, _separator, _quote,false);\n            catch (IncompleteCellException ice)\n            {\n                ice.row = _input.row;\n                ice.col = _input.col;\n                ice.partialData = _front.data.idup;\n                throw ice;\n            }\n            catch (ConvException e)\n            {\n                throw new CSVException(e.msg, _input.row, _input.col, e);\n            }\n        }\n    }\n\n    private void prime()\n    {\n        try\n        {\n            _input.col++;\n            csvNextToken!(Range, ErrorLevel, Separator)\n                (_input.range, _front, _separator, _quote,false);\n        }\n        catch (IncompleteCellException ice)\n        {\n            ice.row = _input.row;\n            ice.col = _input.col;\n            ice.partialData = _front.data.idup;\n            throw ice;\n        }\n\n        auto skipNum = _popCount.empty ? 0 : _popCount.front;\n        if (!_popCount.empty)\n            _popCount.popFront();\n\n        if (skipNum == size_t.max)\n        {\n            while (!recordEnd())\n                prime(1);\n            _empty = true;\n            return;\n        }\n\n        if (skipNum)\n            prime(skipNum);\n\n        auto data = _front.data;\n        static if (!isSomeString!Contents) skipWS(data);\n        try curContentsoken = to!Contents(data);\n        catch (ConvException e)\n        {\n            throw new CSVException(e.msg, _input.row, _input.col, e);\n        }\n    }\n}\n\n/**\n * Lower level control over parsing CSV\n *\n * This function consumes the input. After each call the input will\n * start with either a delimiter or record break (\\n, \\r\\n, \\r) which\n * must be removed for subsequent calls.\n *\n * Params:\n *       input = Any CSV input\n *       ans   = The first field in the input\n *       sep   = The character to represent a comma in the specification\n *       quote = The character to represent a quote in the specification\n *       startQuoted = Whether the input should be considered to already be in\n * quotes\n *\n * Throws:\n *       $(LREF IncompleteCellException) When a quote is found in an unquoted\n *       field, data continues after a closing quote, or the quoted field was\n *       not closed before data was empty.\n */\nvoid csvNextToken(Range, Malformed ErrorLevel = Malformed.throwException,\n                           Separator, Output)\n                          (ref Range input, ref Output ans,\n                           Separator sep, Separator quote,\n                           bool startQuoted = false)\nif (isSomeChar!Separator && isInputRange!Range\n    && is(Unqual!(ElementType!Range) == dchar)\n    && isOutputRange!(Output, dchar))\n{\n    bool quoted = startQuoted;\n    bool escQuote;\n    if (input.empty)\n        return;\n\n    if (input.front == '\\n')\n        return;\n    if (input.front == '\\r')\n        return;\n\n    if (input.front == quote)\n    {\n        quoted = true;\n        input.popFront();\n    }\n\n    while (!input.empty)\n    {\n        assert(!(quoted && escQuote));\n        if (!quoted)\n        {\n            // When not quoted the token ends at sep\n            if (input.front == sep)\n                break;\n            if (input.front == '\\r')\n                break;\n            if (input.front == '\\n')\n                break;\n        }\n        if (!quoted && !escQuote)\n        {\n            if (input.front == quote)\n            {\n                // Not quoted, but quote found\n                static if (ErrorLevel == Malformed.throwException)\n                    throw new IncompleteCellException(\n                          \"Quote located in unquoted token\");\n                else static if (ErrorLevel == Malformed.ignore)\n                    ans.put(quote);\n            }\n            else\n            {\n                // Not quoted, non-quote character\n                ans.put(input.front);\n            }\n        }\n        else\n        {\n            if (input.front == quote)\n            {\n                // Quoted, quote found\n                // By turning off quoted and turning on escQuote\n                // I can tell when to add a quote to the string\n                // escQuote is turned to false when it escapes a\n                // quote or is followed by a non-quote (see outside else).\n                // They are mutually exclusive, but provide different\n                // information.\n                if (escQuote)\n                {\n                    escQuote = false;\n                    quoted = true;\n                    ans.put(quote);\n                } else\n                {\n                    escQuote = true;\n                    quoted = false;\n                }\n            }\n            else\n            {\n                // Quoted, non-quote character\n                if (escQuote)\n                {\n                    static if (ErrorLevel == Malformed.throwException)\n                        throw new IncompleteCellException(\n                          \"Content continues after end quote, \" ~\n                          \"or needs to be escaped.\");\n                    else static if (ErrorLevel == Malformed.ignore)\n                        break;\n                }\n                ans.put(input.front);\n            }\n        }\n        input.popFront();\n    }\n\n    static if (ErrorLevel == Malformed.throwException)\n        if (quoted && (input.empty || input.front == '\\n' || input.front == '\\r'))\n            throw new IncompleteCellException(\n                  \"Data continues on future lines or trailing quote\");\n\n}\n\n///\n@safe unittest\n{\n    import std.array : appender;\n    import std.range.primitives : popFront;\n\n    string str = \"65,63\\n123,3673\";\n\n    auto a = appender!(char[])();\n\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"65\");\n    assert(str == \",63\\n123,3673\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"63\");\n    assert(str == \"\\n123,3673\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"123\");\n    assert(str == \",3673\");\n}\n\n// Test csvNextToken on simplest form and correct format.\n@safe pure unittest\n{\n    import std.array;\n\n    string str = \"\\U00010143Hello,65,63.63\\nWorld,123,3673.562\";\n\n    auto a = appender!(dchar[])();\n    csvNextToken!string(str,a,',','\"');\n    assert(a.data == \"\\U00010143Hello\");\n    assert(str == \",65,63.63\\nWorld,123,3673.562\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"65\");\n    assert(str == \",63.63\\nWorld,123,3673.562\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"63.63\");\n    assert(str == \"\\nWorld,123,3673.562\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"World\");\n    assert(str == \",123,3673.562\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"123\");\n    assert(str == \",3673.562\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"3673.562\");\n    assert(str == \"\");\n}\n\n// Test quoted tokens\n@safe pure unittest\n{\n    import std.array;\n\n    string str = `one,two,\"three \"\"quoted\"\"\",\"\",` ~ \"\\\"five\\nnew line\\\"\\nsix\";\n\n    auto a = appender!(dchar[])();\n    csvNextToken!string(str,a,',','\"');\n    assert(a.data == \"one\");\n    assert(str == `,two,\"three \"\"quoted\"\"\",\"\",` ~ \"\\\"five\\nnew line\\\"\\nsix\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"two\");\n    assert(str == `,\"three \"\"quoted\"\"\",\"\",` ~ \"\\\"five\\nnew line\\\"\\nsix\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"three \\\"quoted\\\"\");\n    assert(str == `,\"\",` ~ \"\\\"five\\nnew line\\\"\\nsix\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"\");\n    assert(str == \",\\\"five\\nnew line\\\"\\nsix\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"five\\nnew line\");\n    assert(str == \"\\nsix\");\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"six\");\n    assert(str == \"\");\n}\n\n// Test empty data is pulled at end of record.\n@safe pure unittest\n{\n    import std.array;\n\n    string str = \"one,\";\n    auto a = appender!(dchar[])();\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"one\");\n    assert(str == \",\");\n\n    a.shrinkTo(0);\n    csvNextToken(str,a,',','\"');\n    assert(a.data == \"\");\n}\n\n// Test exceptions\n@safe pure unittest\n{\n    import std.array;\n\n    string str = \"\\\"one\\nnew line\";\n\n    typeof(appender!(dchar[])()) a;\n    try\n    {\n        a = appender!(dchar[])();\n        csvNextToken(str,a,',','\"');\n        assert(0);\n    }\n    catch (IncompleteCellException ice)\n    {\n        assert(a.data == \"one\\nnew line\");\n        assert(str == \"\");\n    }\n\n    str = \"Hello world\\\"\";\n\n    try\n    {\n        a = appender!(dchar[])();\n        csvNextToken(str,a,',','\"');\n        assert(0);\n    }\n    catch (IncompleteCellException ice)\n    {\n        assert(a.data == \"Hello world\");\n        assert(str == \"\\\"\");\n    }\n\n    str = \"one, two \\\"quoted\\\" end\";\n\n    a = appender!(dchar[])();\n    csvNextToken!(string,Malformed.ignore)(str,a,',','\"');\n    assert(a.data == \"one\");\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken!(string,Malformed.ignore)(str,a,',','\"');\n    assert(a.data == \" two \\\"quoted\\\" end\");\n}\n\n// Test modifying token delimiter\n@safe pure unittest\n{\n    import std.array;\n\n    string str = `one|two|/three \"quoted\"/|//`;\n\n    auto a = appender!(dchar[])();\n    csvNextToken(str,a, '|','/');\n    assert(a.data == \"one\"d);\n    assert(str == `|two|/three \"quoted\"/|//`);\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a, '|','/');\n    assert(a.data == \"two\"d);\n    assert(str == `|/three \"quoted\"/|//`);\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a, '|','/');\n    assert(a.data == `three \"quoted\"`);\n    assert(str == `|//`);\n\n    str.popFront();\n    a.shrinkTo(0);\n    csvNextToken(str,a, '|','/');\n    assert(a.data == \"\"d);\n}\n\n// Bugzilla 8908\n@safe pure unittest\n{\n    string csv = `  1.0, 2.0, 3.0\n                    4.0, 5.0, 6.0`;\n\n    static struct Data { real a, b, c; }\n    size_t i = 0;\n    foreach (data; csvReader!Data(csv)) with (data)\n    {\n        int[] row = [cast(int) a, cast(int) b, cast(int) c];\n        if (i == 0)\n            assert(row == [1, 2, 3]);\n        else\n            assert(row == [4, 5, 6]);\n        ++i;\n    }\n\n    i = 0;\n    foreach (data; csvReader!real(csv))\n    {\n        auto a = data.front;    data.popFront();\n        auto b = data.front;    data.popFront();\n        auto c = data.front;\n        int[] row = [cast(int) a, cast(int) b, cast(int) c];\n        if (i == 0)\n            assert(row == [1, 2, 3]);\n        else\n            assert(row == [4, 5, 6]);\n        ++i;\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/datetime/date.d",
    "content": "// Written in the D programming language\n/++\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Main date types) $(TD\n    $(LREF Date)\n    $(LREF DateTime)\n))\n$(TR $(TD Other date types) $(TD\n    $(LREF Month)\n    $(LREF DayOfWeek)\n    $(LREF TimeOfDay)\n))\n$(TR $(TD Date checking) $(TD\n    $(LREF valid)\n    $(LREF validTimeUnits)\n    $(LREF yearIsLeapYear)\n    $(LREF isTimePoint)\n    $(LREF enforceValid)\n))\n$(TR $(TD Date conversion) $(TD\n    $(LREF daysToDayOfWeek)\n    $(LREF monthsToMonth)\n))\n$(TR $(TD Time units) $(TD\n    $(LREF cmpTimeUnits)\n    $(LREF timeStrings)\n))\n$(TR $(TD Other) $(TD\n    $(LREF AllowDayOverflow)\n    $(LREF DateTimeException)\n))\n)\n\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n    Source:    $(PHOBOSSRC std/datetime/date.d)\n+/\nmodule std.datetime.date;\n\n// Note: reconsider using specific imports below after\n// https://issues.dlang.org/show_bug.cgi?id=17630 has been fixed\nimport core.time;// : TimeException;\nimport std.traits : isSomeString, Unqual;\nimport std.typecons : Flag;\nimport std.range.primitives : isOutputRange;\n\nversion (unittest) import std.exception : assertThrown;\n\n@safe unittest\n{\n    initializeTests();\n}\n\n\n/++\n    Exception type used by std.datetime. It's an alias to\n    $(REF TimeException,core,time). Either can be caught without concern about\n    which module it came from.\n  +/\nalias DateTimeException = TimeException;\n\n\n/++\n    Represents the 12 months of the Gregorian year (January is 1).\n  +/\nenum Month : ubyte\n{\n    jan = 1, ///\n    feb,     ///\n    mar,     ///\n    apr,     ///\n    may,     ///\n    jun,     ///\n    jul,     ///\n    aug,     ///\n    sep,     ///\n    oct,     ///\n    nov,     ///\n    dec      ///\n}\n\n///\n@safe pure unittest\n{\n    assert(Date(2018, 10, 1).month == Month.oct);\n    assert(DateTime(1, 1, 1).month == Month.jan);\n}\n\n\n/++\n    Represents the 7 days of the Gregorian week (Sunday is 0).\n  +/\nenum DayOfWeek : ubyte\n{\n    sun = 0, ///\n    mon,     ///\n    tue,     ///\n    wed,     ///\n    thu,     ///\n    fri,     ///\n    sat      ///\n}\n\n///\n@safe pure unittest\n{\n    assert(Date(2018, 10, 1).dayOfWeek == DayOfWeek.mon);\n    assert(DateTime(5, 5, 5).dayOfWeek == DayOfWeek.thu);\n}\n\n/++\n    In some date calculations, adding months or years can cause the date to fall\n    on a day of the month which is not valid (e.g. February 29th 2001 or\n    June 31st 2000). If overflow is allowed (as is the default), then the month\n    will be incremented accordingly (so, February 29th 2001 would become\n    March 1st 2001, and June 31st 2000 would become July 1st 2000). If overflow\n    is not allowed, then the day will be adjusted to the last valid day in that\n    month (so, February 29th 2001 would become February 28th 2001 and\n    June 31st 2000 would become June 30th 2000).\n\n    AllowDayOverflow only applies to calculations involving months or years.\n\n    If set to `AllowDayOverflow.no`, then day overflow is not allowed.\n\n    Otherwise, if set to `AllowDayOverflow.yes`, then day overflow is\n    allowed.\n  +/\nalias AllowDayOverflow = Flag!\"allowDayOverflow\";\n\n\n/++\n    Array of the strings representing time units, starting with the smallest\n    unit and going to the largest. It does not include `\"nsecs\"`.\n\n    Includes `\"hnsecs\"` (hecto-nanoseconds (100 ns)),\n    `\"usecs\"` (microseconds), `\"msecs\"` (milliseconds), `\"seconds\"`,\n    `\"minutes\"`, `\"hours\"`, `\"days\"`, `\"weeks\"`, `\"months\"`, and\n    `\"years\"`\n  +/\nimmutable string[] timeStrings = [\"hnsecs\", \"usecs\", \"msecs\", \"seconds\", \"minutes\",\n                                  \"hours\", \"days\", \"weeks\", \"months\", \"years\"];\n\n\n/++\n    Combines the $(REF Date,std,datetime,date) and\n    $(REF TimeOfDay,std,datetime,date) structs to give an object which holds\n    both the date and the time. It is optimized for calendar-based operations\n    and has no concept of time zone. For an object which is optimized for time\n    operations based on the system time, use\n    $(REF SysTime,std,datetime,systime). $(REF SysTime,std,datetime,systime) has\n    a concept of time zone and has much higher precision (hnsecs). `DateTime`\n    is intended primarily for calendar-based uses rather than precise time\n    operations.\n  +/\nstruct DateTime\n{\npublic:\n\n    /++\n        Params:\n            date = The date portion of $(LREF DateTime).\n            tod  = The time portion of $(LREF DateTime).\n      +/\n    this(Date date, TimeOfDay tod = TimeOfDay.init) @safe pure nothrow @nogc\n    {\n        _date = date;\n        _tod = tod;\n    }\n\n    @safe unittest\n    {\n        {\n            auto dt = DateTime.init;\n            assert(dt._date == Date.init);\n            assert(dt._tod == TimeOfDay.init);\n        }\n\n        {\n            auto dt = DateTime(Date(1999, 7 ,6));\n            assert(dt._date == Date(1999, 7, 6));\n            assert(dt._tod == TimeOfDay.init);\n        }\n\n        {\n            auto dt = DateTime(Date(1999, 7 ,6), TimeOfDay(12, 30, 33));\n            assert(dt._date == Date(1999, 7, 6));\n            assert(dt._tod == TimeOfDay(12, 30, 33));\n        }\n    }\n\n\n    /++\n        Params:\n            year   = The year portion of the date.\n            month  = The month portion of the date (January is 1).\n            day    = The day portion of the date.\n            hour   = The hour portion of the time;\n            minute = The minute portion of the time;\n            second = The second portion of the time;\n      +/\n    this(int year, int month, int day, int hour = 0, int minute = 0, int second = 0) @safe pure\n    {\n        _date = Date(year, month, day);\n        _tod = TimeOfDay(hour, minute, second);\n    }\n\n    @safe unittest\n    {\n        {\n            auto dt = DateTime(1999, 7 ,6);\n            assert(dt._date == Date(1999, 7, 6));\n            assert(dt._tod == TimeOfDay.init);\n        }\n\n        {\n            auto dt = DateTime(1999, 7 ,6, 12, 30, 33);\n            assert(dt._date == Date(1999, 7, 6));\n            assert(dt._tod == TimeOfDay(12, 30, 33));\n        }\n    }\n\n\n    /++\n        Compares this $(LREF DateTime) with the given `DateTime.`.\n\n        Returns:\n            $(BOOKTABLE,\n            $(TR $(TD this &lt; rhs) $(TD &lt; 0))\n            $(TR $(TD this == rhs) $(TD 0))\n            $(TR $(TD this &gt; rhs) $(TD &gt; 0))\n            )\n     +/\n    int opCmp(DateTime rhs) const @safe pure nothrow @nogc\n    {\n        immutable dateResult = _date.opCmp(rhs._date);\n\n        if (dateResult != 0)\n            return dateResult;\n\n        return _tod.opCmp(rhs._tod);\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(DateTime(Date.init, TimeOfDay.init).opCmp(DateTime.init) == 0);\n\n        assert(DateTime(Date(1999, 1, 1)).opCmp(DateTime(Date(1999, 1, 1))) == 0);\n        assert(DateTime(Date(1, 7, 1)).opCmp(DateTime(Date(1, 7, 1))) == 0);\n        assert(DateTime(Date(1, 1, 6)).opCmp(DateTime(Date(1, 1, 6))) == 0);\n\n        assert(DateTime(Date(1999, 7, 1)).opCmp(DateTime(Date(1999, 7, 1))) == 0);\n        assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(1999, 7, 6))) == 0);\n\n        assert(DateTime(Date(1, 7, 6)).opCmp(DateTime(Date(1, 7, 6))) == 0);\n\n        assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(2000, 7, 6))) < 0);\n        assert(DateTime(Date(2000, 7, 6)).opCmp(DateTime(Date(1999, 7, 6))) > 0);\n        assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(1999, 8, 6))) < 0);\n        assert(DateTime(Date(1999, 8, 6)).opCmp(DateTime(Date(1999, 7, 6))) > 0);\n        assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(1999, 7, 7))) < 0);\n        assert(DateTime(Date(1999, 7, 7)).opCmp(DateTime(Date(1999, 7, 6))) > 0);\n\n        assert(DateTime(Date(1999, 8, 7)).opCmp(DateTime(Date(2000, 7, 6))) < 0);\n        assert(DateTime(Date(2000, 8, 6)).opCmp(DateTime(Date(1999, 7, 7))) > 0);\n        assert(DateTime(Date(1999, 7, 7)).opCmp(DateTime(Date(2000, 7, 6))) < 0);\n        assert(DateTime(Date(2000, 7, 6)).opCmp(DateTime(Date(1999, 7, 7))) > 0);\n        assert(DateTime(Date(1999, 7, 7)).opCmp(DateTime(Date(1999, 8, 6))) < 0);\n        assert(DateTime(Date(1999, 8, 6)).opCmp(DateTime(Date(1999, 7, 7))) > 0);\n\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0))) == 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0))) == 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 0)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 0))) == 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33))) == 0);\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0))) == 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) == 0);\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33))) == 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33))) == 0);\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) < 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) < 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) > 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) < 0);\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) < 0);\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(\n                   DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) > 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(\n                   DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) > 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(\n                   DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0);\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(\n                   DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) > 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(\n                   DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) > 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(\n                   DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0);\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) > 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(\n                   DateTime(Date(1999, 7, 7), TimeOfDay(12, 31, 33))) < 0);\n        assert(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(\n                   DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0);\n\n        // Test B.C.\n        assert(DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33))) == 0);\n        assert(DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33))) == 0);\n        assert(DateTime(Date(-1, 1, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1, 1, 6), TimeOfDay(12, 30, 33))) == 0);\n\n        assert(DateTime(Date(-1999, 7, 1), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 1), TimeOfDay(12, 30, 33))) == 0);\n        assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) == 0);\n\n        assert(DateTime(Date(-1, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1, 7, 6), TimeOfDay(12, 30, 33))) == 0);\n\n        assert(DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33))) > 0);\n        assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);\n        assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);\n\n        assert(DateTime(Date(-2000, 8, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33))) > 0);\n        assert(DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33))) > 0);\n        assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) > 0);\n\n        // Test Both\n        assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);\n\n        assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33))) > 0);\n\n        assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) > 0);\n\n        assert(DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33))) > 0);\n\n        assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(1999, 6, 6), TimeOfDay(12, 30, 33))) < 0);\n        assert(DateTime(Date(1999, 6, 8), TimeOfDay(12, 30, 33)).opCmp(\n                   DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);\n\n        auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30));\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30));\n        assert(dt.opCmp(dt) == 0);\n        assert(dt.opCmp(cdt) == 0);\n        assert(dt.opCmp(idt) == 0);\n        assert(cdt.opCmp(dt) == 0);\n        assert(cdt.opCmp(cdt) == 0);\n        assert(cdt.opCmp(idt) == 0);\n        assert(idt.opCmp(dt) == 0);\n        assert(idt.opCmp(cdt) == 0);\n        assert(idt.opCmp(idt) == 0);\n    }\n\n\n    /++\n        The date portion of $(LREF DateTime).\n      +/\n    @property Date date() const @safe pure nothrow @nogc\n    {\n        return _date;\n    }\n\n    @safe unittest\n    {\n        {\n            auto dt = DateTime.init;\n            assert(dt.date == Date.init);\n        }\n\n        {\n            auto dt = DateTime(Date(1999, 7, 6));\n            assert(dt.date == Date(1999, 7, 6));\n        }\n\n        const cdt = DateTime(1999, 7, 6);\n        immutable idt = DateTime(1999, 7, 6);\n        assert(cdt.date == Date(1999, 7, 6));\n        assert(idt.date == Date(1999, 7, 6));\n    }\n\n\n    /++\n        The date portion of $(LREF DateTime).\n\n        Params:\n            date = The Date to set this $(LREF DateTime)'s date portion to.\n      +/\n    @property void date(Date date) @safe pure nothrow @nogc\n    {\n        _date = date;\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime.init;\n        dt.date = Date(1999, 7, 6);\n        assert(dt._date == Date(1999, 7, 6));\n        assert(dt._tod == TimeOfDay.init);\n\n        const cdt = DateTime(1999, 7, 6);\n        immutable idt = DateTime(1999, 7, 6);\n        static assert(!__traits(compiles, cdt.date = Date(2010, 1, 1)));\n        static assert(!__traits(compiles, idt.date = Date(2010, 1, 1)));\n    }\n\n\n    /++\n        The time portion of $(LREF DateTime).\n      +/\n    @property TimeOfDay timeOfDay() const @safe pure nothrow @nogc\n    {\n        return _tod;\n    }\n\n    @safe unittest\n    {\n        {\n            auto dt = DateTime.init;\n            assert(dt.timeOfDay == TimeOfDay.init);\n        }\n\n        {\n            auto dt = DateTime(Date.init, TimeOfDay(12, 30, 33));\n            assert(dt.timeOfDay == TimeOfDay(12, 30, 33));\n        }\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        assert(cdt.timeOfDay == TimeOfDay(12, 30, 33));\n        assert(idt.timeOfDay == TimeOfDay(12, 30, 33));\n    }\n\n\n    /++\n        The time portion of $(LREF DateTime).\n\n        Params:\n            tod = The $(REF TimeOfDay,std,datetime,date) to set this\n                  $(LREF DateTime)'s time portion to.\n      +/\n    @property void timeOfDay(TimeOfDay tod) @safe pure nothrow @nogc\n    {\n        _tod = tod;\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime.init;\n        dt.timeOfDay = TimeOfDay(12, 30, 33);\n        assert(dt._date == Date.init);\n        assert(dt._tod == TimeOfDay(12, 30, 33));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.timeOfDay = TimeOfDay(12, 30, 33)));\n        static assert(!__traits(compiles, idt.timeOfDay = TimeOfDay(12, 30, 33)));\n    }\n\n\n    /++\n        Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive\n        are B.C.\n     +/\n    @property short year() const @safe pure nothrow @nogc\n    {\n        return _date.year;\n    }\n\n    @safe unittest\n    {\n        assert(Date.init.year == 1);\n        assert(Date(1999, 7, 6).year == 1999);\n        assert(Date(-1999, 7, 6).year == -1999);\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        assert(idt.year == 1999);\n        assert(idt.year == 1999);\n    }\n\n\n    /++\n        Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive\n        are B.C.\n\n        Params:\n            year = The year to set this $(LREF DateTime)'s year to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the new year is not\n            a leap year and if the resulting date would be on February 29th.\n     +/\n    @property void year(int year) @safe pure\n    {\n        _date.year = year;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).year == 1999);\n        assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).year == 2010);\n        assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).year == -7);\n    }\n\n    @safe unittest\n    {\n        static void testDT(DateTime dt, int year, DateTime expected, size_t line = __LINE__)\n        {\n            dt.year = year;\n            assert(dt == expected);\n        }\n\n        testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)),\n               1999,\n               DateTime(Date(1999, 1, 1), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)),\n               0,\n               DateTime(Date(0, 1, 1), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)),\n               -1999,\n               DateTime(Date(-1999, 1, 1), TimeOfDay(12, 30, 33)));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.year = 7));\n        static assert(!__traits(compiles, idt.year = 7));\n    }\n\n\n    /++\n        Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if `isAD` is true.\n     +/\n    @property short yearBC() const @safe pure\n    {\n        return _date.yearBC;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(0, 1, 1), TimeOfDay(12, 30, 33)).yearBC == 1);\n        assert(DateTime(Date(-1, 1, 1), TimeOfDay(10, 7, 2)).yearBC == 2);\n        assert(DateTime(Date(-100, 1, 1), TimeOfDay(4, 59, 0)).yearBC == 101);\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException((DateTime dt){dt.yearBC;}(DateTime(Date(1, 1, 1))));\n\n        auto dt = DateTime(1999, 7, 6, 12, 30, 33);\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        dt.yearBC = 12;\n        assert(dt.yearBC == 12);\n        static assert(!__traits(compiles, cdt.yearBC = 12));\n        static assert(!__traits(compiles, idt.yearBC = 12));\n    }\n\n\n    /++\n        Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.\n\n        Params:\n            year = The year B.C. to set this $(LREF DateTime)'s year to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if a non-positive value\n            is given.\n     +/\n    @property void yearBC(int year) @safe pure\n    {\n        _date.yearBC = year;\n    }\n\n    ///\n    @safe unittest\n    {\n        auto dt = DateTime(Date(2010, 1, 1), TimeOfDay(7, 30, 0));\n        dt.yearBC = 1;\n        assert(dt == DateTime(Date(0, 1, 1), TimeOfDay(7, 30, 0)));\n\n        dt.yearBC = 10;\n        assert(dt == DateTime(Date(-9, 1, 1), TimeOfDay(7, 30, 0)));\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException((DateTime dt){dt.yearBC = -1;}(DateTime(Date(1, 1, 1))));\n\n        auto dt = DateTime(1999, 7, 6, 12, 30, 33);\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        dt.yearBC = 12;\n        assert(dt.yearBC == 12);\n        static assert(!__traits(compiles, cdt.yearBC = 12));\n        static assert(!__traits(compiles, idt.yearBC = 12));\n    }\n\n\n    /++\n        Month of a Gregorian Year.\n     +/\n    @property Month month() const @safe pure nothrow @nogc\n    {\n        return _date.month;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).month == 7);\n        assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).month == 10);\n        assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).month == 4);\n    }\n\n    @safe unittest\n    {\n        assert(DateTime.init.month == 1);\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).month == 7);\n        assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).month == 7);\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        assert(cdt.month == 7);\n        assert(idt.month == 7);\n    }\n\n\n    /++\n        Month of a Gregorian Year.\n\n        Params:\n            month = The month to set this $(LREF DateTime)'s month to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given month is\n            not a valid month.\n     +/\n    @property void month(Month month) @safe pure\n    {\n        _date.month = month;\n    }\n\n    @safe unittest\n    {\n        static void testDT(DateTime dt, Month month, DateTime expected = DateTime.init, size_t line = __LINE__)\n        {\n            dt.month = month;\n            assert(expected != DateTime.init);\n            assert(dt == expected);\n        }\n\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), cast(Month) 0));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), cast(Month) 13));\n\n        testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)),\n               cast(Month) 7,\n               DateTime(Date(1, 7, 1), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33)),\n               cast(Month) 7,\n               DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33)));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.month = 12));\n        static assert(!__traits(compiles, idt.month = 12));\n    }\n\n\n    /++\n        Day of a Gregorian Month.\n     +/\n    @property ubyte day() const @safe pure nothrow @nogc\n    {\n        return _date.day;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).day == 6);\n        assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).day == 4);\n        assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).day == 5);\n    }\n\n    @safe unittest\n    {\n        import std.format : format;\n        import std.range : chain;\n\n        static void test(DateTime dateTime, int expected)\n        {\n            assert(dateTime.day == expected, format(\"Value given: %s\", dateTime));\n        }\n\n        foreach (year; chain(testYearsBC, testYearsAD))\n        {\n            foreach (md; testMonthDays)\n            {\n                foreach (tod; testTODs)\n                    test(DateTime(Date(year, md.month, md.day), tod), md.day);\n            }\n        }\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        assert(cdt.day == 6);\n        assert(idt.day == 6);\n    }\n\n\n    /++\n        Day of a Gregorian Month.\n\n        Params:\n            day = The day of the month to set this $(LREF DateTime)'s day to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given day is not\n            a valid day of the current month.\n     +/\n    @property void day(int day) @safe pure\n    {\n        _date.day = day;\n    }\n\n    @safe unittest\n    {\n        import std.exception : assertNotThrown;\n\n        static void testDT(DateTime dt, int day)\n        {\n            dt.day = day;\n        }\n\n        // Test A.D.\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 0));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 2, 1)), 29));\n        assertThrown!DateTimeException(testDT(DateTime(Date(4, 2, 1)), 30));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 3, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 4, 1)), 31));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 5, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 6, 1)), 31));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 7, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 8, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 9, 1)), 31));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 10, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 11, 1)), 31));\n        assertThrown!DateTimeException(testDT(DateTime(Date(1, 12, 1)), 32));\n\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 2, 1)), 28));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(4, 2, 1)), 29));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 3, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 4, 1)), 30));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 5, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 6, 1)), 30));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 7, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 8, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 9, 1)), 30));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 10, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 11, 1)), 30));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 12, 1)), 31));\n\n        {\n            auto dt = DateTime(Date(1, 1, 1), TimeOfDay(7, 12, 22));\n            dt.day = 6;\n            assert(dt == DateTime(Date(1, 1, 6), TimeOfDay(7, 12, 22)));\n        }\n\n        // Test B.C.\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 0));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 2, 1)), 29));\n        assertThrown!DateTimeException(testDT(DateTime(Date(0, 2, 1)), 30));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 3, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 4, 1)), 31));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 5, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 6, 1)), 31));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 7, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 8, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 9, 1)), 31));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 10, 1)), 32));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 11, 1)), 31));\n        assertThrown!DateTimeException(testDT(DateTime(Date(-1, 12, 1)), 32));\n\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 2, 1)), 28));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(0, 2, 1)), 29));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 3, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 4, 1)), 30));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 5, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 6, 1)), 30));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 7, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 8, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 9, 1)), 30));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 10, 1)), 31));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 11, 1)), 30));\n        assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 12, 1)), 31));\n\n        auto dt = DateTime(Date(-1, 1, 1), TimeOfDay(7, 12, 22));\n        dt.day = 6;\n        assert(dt == DateTime(Date(-1, 1, 6), TimeOfDay(7, 12, 22)));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.day = 27));\n        static assert(!__traits(compiles, idt.day = 27));\n    }\n\n\n    /++\n        Hours past midnight.\n     +/\n    @property ubyte hour() const @safe pure nothrow @nogc\n    {\n        return _tod.hour;\n    }\n\n    @safe unittest\n    {\n        assert(DateTime.init.hour == 0);\n        assert(DateTime(Date.init, TimeOfDay(12, 0, 0)).hour == 12);\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        assert(cdt.hour == 12);\n        assert(idt.hour == 12);\n    }\n\n\n    /++\n        Hours past midnight.\n\n        Params:\n            hour = The hour of the day to set this $(LREF DateTime)'s hour to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given hour would\n            result in an invalid $(LREF DateTime).\n     +/\n    @property void hour(int hour) @safe pure\n    {\n        _tod.hour = hour;\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException((){DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)).hour = 24;}());\n\n        auto dt = DateTime.init;\n        dt.hour = 12;\n        assert(dt == DateTime(1, 1, 1, 12, 0, 0));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.hour = 27));\n        static assert(!__traits(compiles, idt.hour = 27));\n    }\n\n\n    /++\n        Minutes past the hour.\n     +/\n    @property ubyte minute() const @safe pure nothrow @nogc\n    {\n        return _tod.minute;\n    }\n\n    @safe unittest\n    {\n        assert(DateTime.init.minute == 0);\n        assert(DateTime(1, 1, 1, 0, 30, 0).minute == 30);\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        assert(cdt.minute == 30);\n        assert(idt.minute == 30);\n    }\n\n\n    /++\n        Minutes past the hour.\n\n        Params:\n            minute = The minute to set this $(LREF DateTime)'s minute to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given minute\n            would result in an invalid $(LREF DateTime).\n     +/\n    @property void minute(int minute) @safe pure\n    {\n        _tod.minute = minute;\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException((){DateTime.init.minute = 60;}());\n\n        auto dt = DateTime.init;\n        dt.minute = 30;\n        assert(dt == DateTime(1, 1, 1, 0, 30, 0));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.minute = 27));\n        static assert(!__traits(compiles, idt.minute = 27));\n    }\n\n\n    /++\n        Seconds past the minute.\n     +/\n    @property ubyte second() const @safe pure nothrow @nogc\n    {\n        return _tod.second;\n    }\n\n    @safe unittest\n    {\n        assert(DateTime.init.second == 0);\n        assert(DateTime(1, 1, 1, 0, 0, 33).second == 33);\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        assert(cdt.second == 33);\n        assert(idt.second == 33);\n    }\n\n\n    /++\n        Seconds past the minute.\n\n        Params:\n            second = The second to set this $(LREF DateTime)'s second to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given seconds\n            would result in an invalid $(LREF DateTime).\n     +/\n    @property void second(int second) @safe pure\n    {\n        _tod.second = second;\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException((){DateTime.init.second = 60;}());\n\n        auto dt = DateTime.init;\n        dt.second = 33;\n        assert(dt == DateTime(1, 1, 1, 0, 0, 33));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.second = 27));\n        static assert(!__traits(compiles, idt.second = 27));\n    }\n\n\n    /++\n        Adds the given number of years or months to this $(LREF DateTime),\n        mutating it. A negative number will subtract.\n\n        Note that if day overflow is allowed, and the date with the adjusted\n        year/month overflows the number of days in the new month, then the month\n        will be incremented by one, and the day set to the number of days\n        overflowed. (e.g. if the day were 31 and the new month were June, then\n        the month would be incremented to July, and the new day would be 1). If\n        day overflow is not allowed, then the day will be set to the last valid\n        day in the month (e.g. June 31st would become June 30th).\n\n        Params:\n            units         = The type of units to add (\"years\" or \"months\").\n            value         = The number of months or years to add to this\n                            $(LREF DateTime).\n            allowOverflow = Whether the days should be allowed to overflow,\n                            causing the month to increment.\n\n        Returns:\n            A reference to the `DateTime` (`this`).\n      +/\n    ref DateTime add(string units)\n                    (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow @nogc\n        if (units == \"years\" || units == \"months\")\n    {\n        _date.add!units(value, allowOverflow);\n        return this;\n    }\n\n    ///\n    @safe unittest\n    {\n        auto dt1 = DateTime(2010, 1, 1, 12, 30, 33);\n        dt1.add!\"months\"(11);\n        assert(dt1 == DateTime(2010, 12, 1, 12, 30, 33));\n\n        auto dt2 = DateTime(2010, 1, 1, 12, 30, 33);\n        dt2.add!\"months\"(-11);\n        assert(dt2 == DateTime(2009, 2, 1, 12, 30, 33));\n\n        auto dt3 = DateTime(2000, 2, 29, 12, 30, 33);\n        dt3.add!\"years\"(1);\n        assert(dt3 == DateTime(2001, 3, 1, 12, 30, 33));\n\n        auto dt4 = DateTime(2000, 2, 29, 12, 30, 33);\n        dt4.add!\"years\"(1, AllowDayOverflow.no);\n        assert(dt4 == DateTime(2001, 2, 28, 12, 30, 33));\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime(2000, 1, 31);\n        dt.add!\"years\"(7).add!\"months\"(-4);\n        assert(dt == DateTime(2006, 10, 1));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.add!\"years\"(4)));\n        static assert(!__traits(compiles, idt.add!\"years\"(4)));\n        static assert(!__traits(compiles, cdt.add!\"months\"(4)));\n        static assert(!__traits(compiles, idt.add!\"months\"(4)));\n    }\n\n\n    /++\n        Adds the given number of years or months to this $(LREF DateTime),\n        mutating it. A negative number will subtract.\n\n        The difference between rolling and adding is that rolling does not\n        affect larger units. Rolling a $(LREF DateTime) 12 months\n        gets the exact same $(LREF DateTime). However, the days can still be\n        affected due to the differing number of days in each month.\n\n        Because there are no units larger than years, there is no difference\n        between adding and rolling years.\n\n        Params:\n            units         = The type of units to add (\"years\" or \"months\").\n            value         = The number of months or years to add to this\n                            $(LREF DateTime).\n            allowOverflow = Whether the days should be allowed to overflow,\n                            causing the month to increment.\n\n        Returns:\n            A reference to the `DateTime` (`this`).\n      +/\n    ref DateTime roll(string units)\n                     (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow @nogc\n        if (units == \"years\" || units == \"months\")\n    {\n        _date.roll!units(value, allowOverflow);\n        return this;\n    }\n\n    ///\n    @safe unittest\n    {\n        auto dt1 = DateTime(2010, 1, 1, 12, 33, 33);\n        dt1.roll!\"months\"(1);\n        assert(dt1 == DateTime(2010, 2, 1, 12, 33, 33));\n\n        auto dt2 = DateTime(2010, 1, 1, 12, 33, 33);\n        dt2.roll!\"months\"(-1);\n        assert(dt2 == DateTime(2010, 12, 1, 12, 33, 33));\n\n        auto dt3 = DateTime(1999, 1, 29, 12, 33, 33);\n        dt3.roll!\"months\"(1);\n        assert(dt3 == DateTime(1999, 3, 1, 12, 33, 33));\n\n        auto dt4 = DateTime(1999, 1, 29, 12, 33, 33);\n        dt4.roll!\"months\"(1, AllowDayOverflow.no);\n        assert(dt4 == DateTime(1999, 2, 28, 12, 33, 33));\n\n        auto dt5 = DateTime(2000, 2, 29, 12, 30, 33);\n        dt5.roll!\"years\"(1);\n        assert(dt5 == DateTime(2001, 3, 1, 12, 30, 33));\n\n        auto dt6 = DateTime(2000, 2, 29, 12, 30, 33);\n        dt6.roll!\"years\"(1, AllowDayOverflow.no);\n        assert(dt6 == DateTime(2001, 2, 28, 12, 30, 33));\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime(2000, 1, 31);\n        dt.roll!\"years\"(7).roll!\"months\"(-4);\n        assert(dt == DateTime(2007, 10, 1));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.roll!\"years\"(4)));\n        static assert(!__traits(compiles, idt.roll!\"years\"(4)));\n        static assert(!__traits(compiles, cdt.roll!\"months\"(4)));\n        static assert(!__traits(compiles, idt.roll!\"months\"(4)));\n    }\n\n\n    /++\n        Adds the given number of units to this $(LREF DateTime), mutating it. A\n        negative number will subtract.\n\n        The difference between rolling and adding is that rolling does not\n        affect larger units. For instance, rolling a $(LREF DateTime) one\n        year's worth of days gets the exact same $(LREF DateTime).\n\n        Accepted units are `\"days\"`, `\"minutes\"`, `\"hours\"`,\n        `\"minutes\"`, and `\"seconds\"`.\n\n        Params:\n            units = The units to add.\n            value = The number of $(D_PARAM units) to add to this\n                    $(LREF DateTime).\n\n        Returns:\n            A reference to the `DateTime` (`this`).\n      +/\n    ref DateTime roll(string units)(long value) @safe pure nothrow @nogc\n        if (units == \"days\")\n    {\n        _date.roll!\"days\"(value);\n        return this;\n    }\n\n    ///\n    @safe unittest\n    {\n        auto dt1 = DateTime(2010, 1, 1, 11, 23, 12);\n        dt1.roll!\"days\"(1);\n        assert(dt1 == DateTime(2010, 1, 2, 11, 23, 12));\n        dt1.roll!\"days\"(365);\n        assert(dt1 == DateTime(2010, 1, 26, 11, 23, 12));\n        dt1.roll!\"days\"(-32);\n        assert(dt1 == DateTime(2010, 1, 25, 11, 23, 12));\n\n        auto dt2 = DateTime(2010, 7, 4, 12, 0, 0);\n        dt2.roll!\"hours\"(1);\n        assert(dt2 == DateTime(2010, 7, 4, 13, 0, 0));\n\n        auto dt3 = DateTime(2010, 1, 1, 0, 0, 0);\n        dt3.roll!\"seconds\"(-1);\n        assert(dt3 == DateTime(2010, 1, 1, 0, 0, 59));\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime(2000, 1, 31);\n        dt.roll!\"days\"(7).roll!\"days\"(-4);\n        assert(dt == DateTime(2000, 1, 3));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.roll!\"days\"(4)));\n        static assert(!__traits(compiles, idt.roll!\"days\"(4)));\n    }\n\n\n    /// ditto\n    ref DateTime roll(string units)(long value) @safe pure nothrow @nogc\n        if (units == \"hours\" ||\n            units == \"minutes\" ||\n            units == \"seconds\")\n    {\n        _tod.roll!units(value);\n        return this;\n    }\n\n    // Test roll!\"hours\"().\n    @safe unittest\n    {\n        static void testDT(DateTime orig, int hours, DateTime expected, size_t line = __LINE__)\n        {\n            orig.roll!\"hours\"(hours);\n            assert(orig == expected);\n        }\n\n        // Test A.D.\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2,\n               DateTime(Date(1999, 7, 6), TimeOfDay(14, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3,\n               DateTime(Date(1999, 7, 6), TimeOfDay(15, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4,\n               DateTime(Date(1999, 7, 6), TimeOfDay(16, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5,\n               DateTime(Date(1999, 7, 6), TimeOfDay(17, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 6,\n               DateTime(Date(1999, 7, 6), TimeOfDay(18, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 7,\n               DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 8,\n               DateTime(Date(1999, 7, 6), TimeOfDay(20, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 9,\n               DateTime(Date(1999, 7, 6), TimeOfDay(21, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10,\n               DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 11,\n               DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 12,\n               DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 13,\n               DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 14,\n               DateTime(Date(1999, 7, 6), TimeOfDay(2, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15,\n               DateTime(Date(1999, 7, 6), TimeOfDay(3, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 16,\n               DateTime(Date(1999, 7, 6), TimeOfDay(4, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 17,\n               DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 18,\n               DateTime(Date(1999, 7, 6), TimeOfDay(6, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 19,\n               DateTime(Date(1999, 7, 6), TimeOfDay(7, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 20,\n               DateTime(Date(1999, 7, 6), TimeOfDay(8, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 21,\n               DateTime(Date(1999, 7, 6), TimeOfDay(9, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 22,\n               DateTime(Date(1999, 7, 6), TimeOfDay(10, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 23,\n               DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 24,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 25,\n               DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2,\n               DateTime(Date(1999, 7, 6), TimeOfDay(10, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3,\n               DateTime(Date(1999, 7, 6), TimeOfDay(9, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4,\n               DateTime(Date(1999, 7, 6), TimeOfDay(8, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5,\n               DateTime(Date(1999, 7, 6), TimeOfDay(7, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -6,\n               DateTime(Date(1999, 7, 6), TimeOfDay(6, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -7,\n               DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -8,\n               DateTime(Date(1999, 7, 6), TimeOfDay(4, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -9,\n               DateTime(Date(1999, 7, 6), TimeOfDay(3, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10,\n               DateTime(Date(1999, 7, 6), TimeOfDay(2, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -11,\n               DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -12,\n               DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -13,\n               DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -14,\n               DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15,\n               DateTime(Date(1999, 7, 6), TimeOfDay(21, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -16,\n               DateTime(Date(1999, 7, 6), TimeOfDay(20, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -17,\n               DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -18,\n               DateTime(Date(1999, 7, 6), TimeOfDay(18, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -19,\n               DateTime(Date(1999, 7, 6), TimeOfDay(17, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -20,\n               DateTime(Date(1999, 7, 6), TimeOfDay(16, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -21,\n               DateTime(Date(1999, 7, 6), TimeOfDay(15, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -22,\n               DateTime(Date(1999, 7, 6), TimeOfDay(14, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -23,\n               DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -24,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -25,\n               DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), 1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), 0,\n               DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), -1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), 1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), 0,\n               DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), -1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33)));\n\n        testDT(DateTime(Date(1999, 7, 31), TimeOfDay(23, 30, 33)), 1,\n               DateTime(Date(1999, 7, 31), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(1999, 8, 1), TimeOfDay(0, 30, 33)), -1,\n               DateTime(Date(1999, 8, 1), TimeOfDay(23, 30, 33)));\n\n        testDT(DateTime(Date(1999, 12, 31), TimeOfDay(23, 30, 33)), 1,\n               DateTime(Date(1999, 12, 31), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(2000, 1, 1), TimeOfDay(0, 30, 33)), -1,\n               DateTime(Date(2000, 1, 1), TimeOfDay(23, 30, 33)));\n\n        testDT(DateTime(Date(1999, 2, 28), TimeOfDay(23, 30, 33)), 25,\n               DateTime(Date(1999, 2, 28), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(1999, 3, 2), TimeOfDay(0, 30, 33)), -25,\n               DateTime(Date(1999, 3, 2), TimeOfDay(23, 30, 33)));\n\n        testDT(DateTime(Date(2000, 2, 28), TimeOfDay(23, 30, 33)), 25,\n               DateTime(Date(2000, 2, 28), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(2000, 3, 1), TimeOfDay(0, 30, 33)), -25,\n               DateTime(Date(2000, 3, 1), TimeOfDay(23, 30, 33)));\n\n        // Test B.C.\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(14, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(15, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(16, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(17, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 6,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(18, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 7,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(19, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 8,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(20, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 9,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(21, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 11,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 12,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 13,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 14,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(2, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(3, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 16,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(4, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 17,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(5, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 18,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(6, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 19,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(7, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 20,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(8, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 21,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(9, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 22,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(10, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 23,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 24,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 25,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(10, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(9, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(8, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(7, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -6,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(6, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -7,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(5, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -8,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(4, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -9,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(3, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(2, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -11,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -12,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -13,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -14,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(21, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -16,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(20, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -17,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(19, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -18,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(18, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -19,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(17, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -20,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(16, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -21,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(15, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -22,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(14, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -23,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -24,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -25,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), 1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), 0,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), -1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), 1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), 0,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), -1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 31), TimeOfDay(23, 30, 33)), 1,\n               DateTime(Date(-1999, 7, 31), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(-1999, 8, 1), TimeOfDay(0, 30, 33)), -1,\n               DateTime(Date(-1999, 8, 1), TimeOfDay(23, 30, 33)));\n\n        testDT(DateTime(Date(-2001, 12, 31), TimeOfDay(23, 30, 33)), 1,\n               DateTime(Date(-2001, 12, 31), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(-2000, 1, 1), TimeOfDay(0, 30, 33)), -1,\n               DateTime(Date(-2000, 1, 1), TimeOfDay(23, 30, 33)));\n\n        testDT(DateTime(Date(-2001, 2, 28), TimeOfDay(23, 30, 33)), 25,\n               DateTime(Date(-2001, 2, 28), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(-2001, 3, 2), TimeOfDay(0, 30, 33)), -25,\n               DateTime(Date(-2001, 3, 2), TimeOfDay(23, 30, 33)));\n\n        testDT(DateTime(Date(-2000, 2, 28), TimeOfDay(23, 30, 33)), 25,\n               DateTime(Date(-2000, 2, 28), TimeOfDay(0, 30, 33)));\n        testDT(DateTime(Date(-2000, 3, 1), TimeOfDay(0, 30, 33)), -25,\n               DateTime(Date(-2000, 3, 1), TimeOfDay(23, 30, 33)));\n\n        // Test Both\n        testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 17_546,\n               DateTime(Date(-1, 1, 1), TimeOfDay(13, 30, 33)));\n        testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -17_546,\n               DateTime(Date(1, 1, 1), TimeOfDay(11, 30, 33)));\n\n        auto dt = DateTime(2000, 1, 31, 9, 7, 6);\n        dt.roll!\"hours\"(27).roll!\"hours\"(-9);\n        assert(dt == DateTime(2000, 1, 31, 3, 7, 6));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.roll!\"hours\"(4)));\n        static assert(!__traits(compiles, idt.roll!\"hours\"(4)));\n    }\n\n    // Test roll!\"minutes\"().\n    @safe unittest\n    {\n        static void testDT(DateTime orig, int minutes, DateTime expected, size_t line = __LINE__)\n        {\n            orig.roll!\"minutes\"(minutes);\n            assert(orig == expected);\n        }\n\n        // Test A.D.\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 32, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 34, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 35, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 40, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 29,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 30,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 45,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 60,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 75,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 90,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 100,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 10, 33)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 689,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 690,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 691,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 960,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1439,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1440,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1441,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2880,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 28, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 27, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 26, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 25, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 20, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -29,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -30,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -45,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -60,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -75,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -90,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -100,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 50, 33)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -749,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -750,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -751,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -960,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1439,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1440,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1441,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2880,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), 1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), 0,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), -1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), 1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(11, 0, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), 0,\n               DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), -1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(11, 58, 33)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), 1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(0, 1, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), 0,\n               DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), -1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(0, 59, 33)));\n\n        testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), 1,\n               DateTime(Date(1999, 7, 5), TimeOfDay(23, 0, 33)));\n        testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), 0,\n               DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)));\n        testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), -1,\n               DateTime(Date(1999, 7, 5), TimeOfDay(23, 58, 33)));\n\n        testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), 1,\n               DateTime(Date(1998, 12, 31), TimeOfDay(23, 0, 33)));\n        testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), 0,\n               DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)));\n        testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), -1,\n               DateTime(Date(1998, 12, 31), TimeOfDay(23, 58, 33)));\n\n        // Test B.C.\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 32, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 33, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 34, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 35, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 40, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 29,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 30,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 45,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 60,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 75,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 90,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 100,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 10, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 689,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 690,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 691,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 960,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1439,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1440,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1441,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2880,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 28, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 27, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 26, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 25, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 20, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -29,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -30,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -45,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -60,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -75,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -90,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -100,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 50, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -749,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -750,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -751,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -960,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1439,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1440,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1441,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2880,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), 1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), 0,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), -1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), 1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(11, 0, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), 0,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), -1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(11, 58, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), 1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(0, 1, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), 0,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), -1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(0, 59, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), 1,\n               DateTime(Date(-1999, 7, 5), TimeOfDay(23, 0, 33)));\n        testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), 0,\n               DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)));\n        testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), -1,\n               DateTime(Date(-1999, 7, 5), TimeOfDay(23, 58, 33)));\n\n        testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), 1,\n               DateTime(Date(-2000, 12, 31), TimeOfDay(23, 0, 33)));\n        testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), 0,\n               DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)));\n        testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), -1,\n               DateTime(Date(-2000, 12, 31), TimeOfDay(23, 58, 33)));\n\n        // Test Both\n        testDT(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)), -1,\n               DateTime(Date(1, 1, 1), TimeOfDay(0, 59, 0)));\n        testDT(DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 0)), 1,\n               DateTime(Date(0, 12, 31), TimeOfDay(23, 0, 0)));\n\n        testDT(DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 0)), -1,\n               DateTime(Date(0, 1, 1), TimeOfDay(0, 59, 0)));\n        testDT(DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 0)), 1,\n               DateTime(Date(-1, 12, 31), TimeOfDay(23, 0, 0)));\n\n        testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 1_052_760,\n               DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)));\n        testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -1_052_760,\n               DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));\n\n        testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 1_052_782,\n               DateTime(Date(-1, 1, 1), TimeOfDay(11, 52, 33)));\n        testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 52, 33)), -1_052_782,\n               DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));\n\n        auto dt = DateTime(2000, 1, 31, 9, 7, 6);\n        dt.roll!\"minutes\"(92).roll!\"minutes\"(-292);\n        assert(dt == DateTime(2000, 1, 31, 9, 47, 6));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.roll!\"minutes\"(4)));\n        static assert(!__traits(compiles, idt.roll!\"minutes\"(4)));\n    }\n\n    // Test roll!\"seconds\"().\n    @safe unittest\n    {\n        static void testDT(DateTime orig, int seconds, DateTime expected, size_t line = __LINE__)\n        {\n            orig.roll!\"seconds\"(seconds);\n            assert(orig == expected);\n        }\n\n        // Test A.D.\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 35)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 36)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 37)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 38)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 43)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 48)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 26,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 27,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 30,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 3)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 59,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 60,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 61,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1766,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1767,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1768,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 1)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2007,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3599,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3600,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3601,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 7200,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 31)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 30)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 29)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 28)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 23)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 18)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -33,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -34,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -35,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 58)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -59,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -60,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -61,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), 1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 1)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), 0,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), -1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), 1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 1)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), 0,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), -1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 59)));\n\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), 1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 1)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), 0,\n               DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)));\n        testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), -1,\n               DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 59)));\n\n        testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), 1,\n               DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 0)));\n        testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), 0,\n               DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)));\n        testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), -1,\n               DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 58)));\n\n        testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), 1,\n               DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 0)));\n        testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), 0,\n               DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)));\n        testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), -1,\n               DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 58)));\n\n        // Test B.C.\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 35)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 36)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 37)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 38)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 43)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 48)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 26,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 27,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 30,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 3)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 59,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 60,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 61,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1766,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1767,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1768,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 1)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2007,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3599,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3600,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3601,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 7200,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 31)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 30)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 29)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 28)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 23)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 18)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -33,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -34,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -35,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 58)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -59,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -60,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -61,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), 1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 1)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), 0,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), -1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), 1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 1)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), 0,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), -1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 59)));\n\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), 1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 1)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), 0,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)));\n        testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), -1,\n               DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 59)));\n\n        testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), 1,\n               DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 0)));\n        testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), 0,\n               DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)));\n        testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), -1,\n               DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 58)));\n\n        testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), 1,\n               DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 0)));\n        testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), 0,\n               DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)));\n        testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), -1,\n               DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 58)));\n\n        // Test Both\n        testDT(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)), -1,\n               DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 59)));\n        testDT(DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 59)), 1,\n               DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 0)));\n\n        testDT(DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 0)), -1,\n               DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 59)));\n        testDT(DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 59)), 1,\n               DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 0)));\n\n        testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 63_165_600L,\n               DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)));\n        testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -63_165_600L,\n               DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));\n\n        testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 63_165_617L,\n               DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 50)));\n        testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 50)), -63_165_617L,\n               DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));\n\n        auto dt = DateTime(2000, 1, 31, 9, 7, 6);\n        dt.roll!\"seconds\"(92).roll!\"seconds\"(-292);\n        assert(dt == DateTime(2000, 1, 31, 9, 7, 46));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt.roll!\"seconds\"(4)));\n        static assert(!__traits(compiles, idt.roll!\"seconds\"(4)));\n    }\n\n\n    import core.time : Duration;\n    /++\n        Gives the result of adding or subtracting a $(REF Duration, core,time)\n        from this $(LREF DateTime).\n\n        The legal types of arithmetic for $(LREF DateTime) using this operator\n        are\n\n        $(BOOKTABLE,\n        $(TR $(TD DateTime) $(TD +) $(TD Duration) $(TD -->) $(TD DateTime))\n        $(TR $(TD DateTime) $(TD -) $(TD Duration) $(TD -->) $(TD DateTime))\n        )\n\n        Params:\n            duration = The $(REF Duration, core,time) to add to or subtract from\n                       this $(LREF DateTime).\n      +/\n    DateTime opBinary(string op)(Duration duration) const @safe pure nothrow @nogc\n        if (op == \"+\" || op == \"-\")\n    {\n        DateTime retval = this;\n        immutable seconds = duration.total!\"seconds\";\n        mixin(\"return retval._addSeconds(\" ~ op ~ \"seconds);\");\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : hours, seconds;\n\n        assert(DateTime(2015, 12, 31, 23, 59, 59) + seconds(1) ==\n               DateTime(2016, 1, 1, 0, 0, 0));\n\n        assert(DateTime(2015, 12, 31, 23, 59, 59) + hours(1) ==\n               DateTime(2016, 1, 1, 0, 59, 59));\n\n        assert(DateTime(2016, 1, 1, 0, 0, 0) - seconds(1) ==\n               DateTime(2015, 12, 31, 23, 59, 59));\n\n        assert(DateTime(2016, 1, 1, 0, 59, 59) - hours(1) ==\n               DateTime(2015, 12, 31, 23, 59, 59));\n    }\n\n    @safe unittest\n    {\n        import core.time : dur;\n\n        auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n\n        assert(dt + dur!\"weeks\"(7) == DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));\n        assert(dt + dur!\"weeks\"(-7) == DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));\n        assert(dt + dur!\"days\"(7) == DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));\n        assert(dt + dur!\"days\"(-7) == DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));\n\n        assert(dt + dur!\"hours\"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));\n        assert(dt + dur!\"hours\"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));\n        assert(dt + dur!\"minutes\"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));\n        assert(dt + dur!\"minutes\"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));\n        assert(dt + dur!\"seconds\"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(dt + dur!\"seconds\"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(dt + dur!\"msecs\"(7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(dt + dur!\"msecs\"(-7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(dt + dur!\"usecs\"(7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(dt + dur!\"usecs\"(-7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(dt + dur!\"hnsecs\"(70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(dt + dur!\"hnsecs\"(-70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n\n        assert(dt - dur!\"weeks\"(-7) == DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));\n        assert(dt - dur!\"weeks\"(7) == DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));\n        assert(dt - dur!\"days\"(-7) == DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));\n        assert(dt - dur!\"days\"(7) == DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));\n\n        assert(dt - dur!\"hours\"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));\n        assert(dt - dur!\"hours\"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));\n        assert(dt - dur!\"minutes\"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));\n        assert(dt - dur!\"minutes\"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));\n        assert(dt - dur!\"seconds\"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(dt - dur!\"seconds\"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(dt - dur!\"msecs\"(-7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(dt - dur!\"msecs\"(7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(dt - dur!\"usecs\"(-7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(dt - dur!\"usecs\"(7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(dt - dur!\"hnsecs\"(-70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(dt - dur!\"hnsecs\"(70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n\n        auto duration = dur!\"seconds\"(12);\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(cdt + duration == DateTime(1999, 7, 6, 12, 30, 45));\n        assert(idt + duration == DateTime(1999, 7, 6, 12, 30, 45));\n        assert(cdt - duration == DateTime(1999, 7, 6, 12, 30, 21));\n        assert(idt - duration == DateTime(1999, 7, 6, 12, 30, 21));\n    }\n\n\n    /++\n        Gives the result of adding or subtracting a duration from this\n        $(LREF DateTime), as well as assigning the result to this\n        $(LREF DateTime).\n\n        The legal types of arithmetic for $(LREF DateTime) using this operator\n        are\n\n        $(BOOKTABLE,\n        $(TR $(TD DateTime) $(TD +) $(TD duration) $(TD -->) $(TD DateTime))\n        $(TR $(TD DateTime) $(TD -) $(TD duration) $(TD -->) $(TD DateTime))\n        )\n\n        Params:\n            duration = The duration to add to or subtract from this\n                       $(LREF DateTime).\n      +/\n    ref DateTime opOpAssign(string op)(Duration duration) @safe pure nothrow @nogc\n        if (op == \"+\" || op == \"-\")\n    {\n        import core.time : convert;\n        import std.format : format;\n\n        DateTime retval = this;\n        immutable hnsecs = duration.total!\"hnsecs\";\n\n        mixin(format(`return _addSeconds(convert!(\"hnsecs\", \"seconds\")(%shnsecs));`, op));\n    }\n\n    @safe unittest\n    {\n        import core.time : dur;\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"weeks\"(7) ==\n               DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"weeks\"(-7) ==\n               DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"days\"(7) ==\n               DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"days\"(-7) ==\n               DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"hours\"(7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"hours\"(-7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"minutes\"(7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"minutes\"(-7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"seconds\"(7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"seconds\"(-7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"msecs\"(7_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"msecs\"(-7_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"usecs\"(7_000_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"usecs\"(-7_000_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"hnsecs\"(70_000_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!\"hnsecs\"(-70_000_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"weeks\"(-7) ==\n               DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"weeks\"(7) ==\n               DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"days\"(-7) ==\n               DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"days\"(7) ==\n               DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"hours\"(-7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"hours\"(7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"minutes\"(-7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"minutes\"(7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"seconds\"(-7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"seconds\"(7) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"msecs\"(-7_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"msecs\"(7_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"usecs\"(-7_000_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"usecs\"(7_000_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"hnsecs\"(-70_000_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!\"hnsecs\"(70_000_000) ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));\n\n        auto dt = DateTime(2000, 1, 31, 9, 7, 6);\n        (dt += dur!\"seconds\"(92)) -= dur!\"days\"(-500);\n        assert(dt == DateTime(2001, 6, 14, 9, 8, 38));\n\n        auto duration = dur!\"seconds\"(12);\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        static assert(!__traits(compiles, cdt += duration));\n        static assert(!__traits(compiles, idt += duration));\n        static assert(!__traits(compiles, cdt -= duration));\n        static assert(!__traits(compiles, idt -= duration));\n    }\n\n\n    /++\n        Gives the difference between two $(LREF DateTime)s.\n\n        The legal types of arithmetic for $(LREF DateTime) using this operator are\n\n        $(BOOKTABLE,\n        $(TR $(TD DateTime) $(TD -) $(TD DateTime) $(TD -->) $(TD duration))\n        )\n      +/\n    Duration opBinary(string op)(DateTime rhs) const @safe pure nothrow @nogc\n        if (op == \"-\")\n    {\n        immutable dateResult = _date - rhs.date;\n        immutable todResult = _tod - rhs._tod;\n\n        import core.time : dur;\n        return dur!\"hnsecs\"(dateResult.total!\"hnsecs\" + todResult.total!\"hnsecs\");\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime(1999, 7, 6, 12, 30, 33);\n\n        import core.time : dur;\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1998, 7, 6), TimeOfDay(12, 30, 33)) ==\n               dur!\"seconds\"(31_536_000));\n        assert(DateTime(Date(1998, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==\n               dur!\"seconds\"(-31_536_000));\n\n        assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==\n               dur!\"seconds\"(26_78_400));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)) ==\n               dur!\"seconds\"(-26_78_400));\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 5), TimeOfDay(12, 30, 33)) ==\n               dur!\"seconds\"(86_400));\n        assert(DateTime(Date(1999, 7, 5), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==\n               dur!\"seconds\"(-86_400));\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)) ==\n               dur!\"seconds\"(3600));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==\n               dur!\"seconds\"(-3600));\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==\n               dur!\"seconds\"(60));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)) ==\n               dur!\"seconds\"(-60));\n\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==\n               dur!\"seconds\"(1));\n        assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)) ==\n               dur!\"seconds\"(-1));\n\n        assert(DateTime(1, 1, 1, 12, 30, 33) - DateTime(1, 1, 1, 0, 0, 0) == dur!\"seconds\"(45033));\n        assert(DateTime(1, 1, 1, 0, 0, 0) - DateTime(1, 1, 1, 12, 30, 33) == dur!\"seconds\"(-45033));\n        assert(DateTime(0, 12, 31, 12, 30, 33) - DateTime(1, 1, 1, 0, 0, 0) == dur!\"seconds\"(-41367));\n        assert(DateTime(1, 1, 1, 0, 0, 0) - DateTime(0, 12, 31, 12, 30, 33) == dur!\"seconds\"(41367));\n\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(dt - dt == Duration.zero);\n        assert(cdt - dt == Duration.zero);\n        assert(idt - dt == Duration.zero);\n\n        assert(dt - cdt == Duration.zero);\n        assert(cdt - cdt == Duration.zero);\n        assert(idt - cdt == Duration.zero);\n\n        assert(dt - idt == Duration.zero);\n        assert(cdt - idt == Duration.zero);\n        assert(idt - idt == Duration.zero);\n    }\n\n\n    /++\n        Returns the difference between the two $(LREF DateTime)s in months.\n\n        To get the difference in years, subtract the year property\n        of two $(LREF DateTime)s. To get the difference in days or weeks,\n        subtract the $(LREF DateTime)s themselves and use the\n        $(REF Duration, core,time) that results. Because converting between\n        months and smaller units requires a specific date (which\n        $(REF Duration, core,time)s don't have), getting the difference in\n        months requires some math using both the year and month properties, so\n        this is a convenience function for getting the difference in months.\n\n        Note that the number of days in the months or how far into the month\n        either date is is irrelevant. It is the difference in the month property\n        combined with the difference in years * 12. So, for instance,\n        December 31st and January 1st are one month apart just as December 1st\n        and January 31st are one month apart.\n\n        Params:\n            rhs = The $(LREF DateTime) to subtract from this one.\n      +/\n    int diffMonths(DateTime rhs) const @safe pure nothrow @nogc\n    {\n        return _date.diffMonths(rhs._date);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(1999, 2, 1, 12, 2, 3).diffMonths(\n                   DateTime(1999, 1, 31, 23, 59, 59)) == 1);\n\n        assert(DateTime(1999, 1, 31, 0, 0, 0).diffMonths(\n                   DateTime(1999, 2, 1, 12, 3, 42)) == -1);\n\n        assert(DateTime(1999, 3, 1, 5, 30, 0).diffMonths(\n                   DateTime(1999, 1, 1, 2, 4, 7)) == 2);\n\n        assert(DateTime(1999, 1, 1, 7, 2, 4).diffMonths(\n                   DateTime(1999, 3, 31, 0, 30, 58)) == -2);\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(dt.diffMonths(dt) == 0);\n        assert(cdt.diffMonths(dt) == 0);\n        assert(idt.diffMonths(dt) == 0);\n\n        assert(dt.diffMonths(cdt) == 0);\n        assert(cdt.diffMonths(cdt) == 0);\n        assert(idt.diffMonths(cdt) == 0);\n\n        assert(dt.diffMonths(idt) == 0);\n        assert(cdt.diffMonths(idt) == 0);\n        assert(idt.diffMonths(idt) == 0);\n    }\n\n\n    /++\n        Whether this $(LREF DateTime) is in a leap year.\n     +/\n    @property bool isLeapYear() const @safe pure nothrow @nogc\n    {\n        return _date.isLeapYear;\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(!dt.isLeapYear);\n        assert(!cdt.isLeapYear);\n        assert(!idt.isLeapYear);\n    }\n\n\n    /++\n        Day of the week this $(LREF DateTime) is on.\n      +/\n    @property DayOfWeek dayOfWeek() const @safe pure nothrow @nogc\n    {\n        return _date.dayOfWeek;\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(dt.dayOfWeek == DayOfWeek.tue);\n        assert(cdt.dayOfWeek == DayOfWeek.tue);\n        assert(idt.dayOfWeek == DayOfWeek.tue);\n    }\n\n\n    /++\n        Day of the year this $(LREF DateTime) is on.\n      +/\n    @property ushort dayOfYear() const @safe pure nothrow @nogc\n    {\n        return _date.dayOfYear;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(1999, 1, 1), TimeOfDay(12, 22, 7)).dayOfYear == 1);\n        assert(DateTime(Date(1999, 12, 31), TimeOfDay(7, 2, 59)).dayOfYear == 365);\n        assert(DateTime(Date(2000, 12, 31), TimeOfDay(21, 20, 0)).dayOfYear == 366);\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(dt.dayOfYear == 187);\n        assert(cdt.dayOfYear == 187);\n        assert(idt.dayOfYear == 187);\n    }\n\n\n    /++\n        Day of the year.\n\n        Params:\n            day = The day of the year to set which day of the year this\n                  $(LREF DateTime) is on.\n      +/\n    @property void dayOfYear(int day) @safe pure\n    {\n        _date.dayOfYear = day;\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        dt.dayOfYear = 12;\n        assert(dt.dayOfYear == 12);\n        static assert(!__traits(compiles, cdt.dayOfYear = 12));\n        static assert(!__traits(compiles, idt.dayOfYear = 12));\n    }\n\n\n    /++\n        The Xth day of the Gregorian Calendar that this $(LREF DateTime) is on.\n     +/\n    @property int dayOfGregorianCal() const @safe pure nothrow @nogc\n    {\n        return _date.dayOfGregorianCal;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)).dayOfGregorianCal == 1);\n        assert(DateTime(Date(1, 12, 31), TimeOfDay(23, 59, 59)).dayOfGregorianCal == 365);\n        assert(DateTime(Date(2, 1, 1), TimeOfDay(2, 2, 2)).dayOfGregorianCal == 366);\n\n        assert(DateTime(Date(0, 12, 31), TimeOfDay(7, 7, 7)).dayOfGregorianCal == 0);\n        assert(DateTime(Date(0, 1, 1), TimeOfDay(19, 30, 0)).dayOfGregorianCal == -365);\n        assert(DateTime(Date(-1, 12, 31), TimeOfDay(4, 7, 0)).dayOfGregorianCal == -366);\n\n        assert(DateTime(Date(2000, 1, 1), TimeOfDay(9, 30, 20)).dayOfGregorianCal == 730_120);\n        assert(DateTime(Date(2010, 12, 31), TimeOfDay(15, 45, 50)).dayOfGregorianCal == 734_137);\n    }\n\n    @safe unittest\n    {\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(cdt.dayOfGregorianCal == 729_941);\n        assert(idt.dayOfGregorianCal == 729_941);\n    }\n\n\n    /++\n        The Xth day of the Gregorian Calendar that this $(LREF DateTime) is on.\n        Setting this property does not affect the time portion of\n        $(LREF DateTime).\n\n        Params:\n            days = The day of the Gregorian Calendar to set this $(LREF DateTime)\n                   to.\n     +/\n    @property void dayOfGregorianCal(int days) @safe pure nothrow @nogc\n    {\n        _date.dayOfGregorianCal = days;\n    }\n\n    ///\n    @safe unittest\n    {\n        auto dt = DateTime(Date.init, TimeOfDay(12, 0, 0));\n        dt.dayOfGregorianCal = 1;\n        assert(dt == DateTime(Date(1, 1, 1), TimeOfDay(12, 0, 0)));\n\n        dt.dayOfGregorianCal = 365;\n        assert(dt == DateTime(Date(1, 12, 31), TimeOfDay(12, 0, 0)));\n\n        dt.dayOfGregorianCal = 366;\n        assert(dt == DateTime(Date(2, 1, 1), TimeOfDay(12, 0, 0)));\n\n        dt.dayOfGregorianCal = 0;\n        assert(dt == DateTime(Date(0, 12, 31), TimeOfDay(12, 0, 0)));\n\n        dt.dayOfGregorianCal = -365;\n        assert(dt == DateTime(Date(-0, 1, 1), TimeOfDay(12, 0, 0)));\n\n        dt.dayOfGregorianCal = -366;\n        assert(dt == DateTime(Date(-1, 12, 31), TimeOfDay(12, 0, 0)));\n\n        dt.dayOfGregorianCal = 730_120;\n        assert(dt == DateTime(Date(2000, 1, 1), TimeOfDay(12, 0, 0)));\n\n        dt.dayOfGregorianCal = 734_137;\n        assert(dt == DateTime(Date(2010, 12, 31), TimeOfDay(12, 0, 0)));\n    }\n\n    @safe unittest\n    {\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        static assert(!__traits(compiles, cdt.dayOfGregorianCal = 7));\n        static assert(!__traits(compiles, idt.dayOfGregorianCal = 7));\n    }\n\n\n    /++\n        The ISO 8601 week of the year that this $(LREF DateTime) is in.\n\n        See_Also:\n            $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date)\n      +/\n    @property ubyte isoWeek() const @safe pure nothrow\n    {\n        return _date.isoWeek;\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(dt.isoWeek == 27);\n        assert(cdt.isoWeek == 27);\n        assert(idt.isoWeek == 27);\n    }\n\n\n    /++\n        $(LREF DateTime) for the last day in the month that this\n        $(LREF DateTime) is in. The time portion of endOfMonth is always\n        23:59:59.\n      +/\n    @property DateTime endOfMonth() const @safe pure nothrow\n    {\n        try\n            return DateTime(_date.endOfMonth, TimeOfDay(23, 59, 59));\n        catch (Exception e)\n            assert(0, \"DateTime constructor threw.\");\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(1999, 1, 6), TimeOfDay(0, 0, 0)).endOfMonth ==\n               DateTime(Date(1999, 1, 31), TimeOfDay(23, 59, 59)));\n\n        assert(DateTime(Date(1999, 2, 7), TimeOfDay(19, 30, 0)).endOfMonth ==\n               DateTime(Date(1999, 2, 28), TimeOfDay(23, 59, 59)));\n\n        assert(DateTime(Date(2000, 2, 7), TimeOfDay(5, 12, 27)).endOfMonth ==\n               DateTime(Date(2000, 2, 29), TimeOfDay(23, 59, 59)));\n\n        assert(DateTime(Date(2000, 6, 4), TimeOfDay(12, 22, 9)).endOfMonth ==\n               DateTime(Date(2000, 6, 30), TimeOfDay(23, 59, 59)));\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(DateTime(1999, 1, 1, 0, 13, 26).endOfMonth == DateTime(1999, 1, 31, 23, 59, 59));\n        assert(DateTime(1999, 2, 1, 1, 14, 27).endOfMonth == DateTime(1999, 2, 28, 23, 59, 59));\n        assert(DateTime(2000, 2, 1, 2, 15, 28).endOfMonth == DateTime(2000, 2, 29, 23, 59, 59));\n        assert(DateTime(1999, 3, 1, 3, 16, 29).endOfMonth == DateTime(1999, 3, 31, 23, 59, 59));\n        assert(DateTime(1999, 4, 1, 4, 17, 30).endOfMonth == DateTime(1999, 4, 30, 23, 59, 59));\n        assert(DateTime(1999, 5, 1, 5, 18, 31).endOfMonth == DateTime(1999, 5, 31, 23, 59, 59));\n        assert(DateTime(1999, 6, 1, 6, 19, 32).endOfMonth == DateTime(1999, 6, 30, 23, 59, 59));\n        assert(DateTime(1999, 7, 1, 7, 20, 33).endOfMonth == DateTime(1999, 7, 31, 23, 59, 59));\n        assert(DateTime(1999, 8, 1, 8, 21, 34).endOfMonth == DateTime(1999, 8, 31, 23, 59, 59));\n        assert(DateTime(1999, 9, 1, 9, 22, 35).endOfMonth == DateTime(1999, 9, 30, 23, 59, 59));\n        assert(DateTime(1999, 10, 1, 10, 23, 36).endOfMonth == DateTime(1999, 10, 31, 23, 59, 59));\n        assert(DateTime(1999, 11, 1, 11, 24, 37).endOfMonth == DateTime(1999, 11, 30, 23, 59, 59));\n        assert(DateTime(1999, 12, 1, 12, 25, 38).endOfMonth == DateTime(1999, 12, 31, 23, 59, 59));\n\n        // Test B.C.\n        assert(DateTime(-1999, 1, 1, 0, 13, 26).endOfMonth == DateTime(-1999, 1, 31, 23, 59, 59));\n        assert(DateTime(-1999, 2, 1, 1, 14, 27).endOfMonth == DateTime(-1999, 2, 28, 23, 59, 59));\n        assert(DateTime(-2000, 2, 1, 2, 15, 28).endOfMonth == DateTime(-2000, 2, 29, 23, 59, 59));\n        assert(DateTime(-1999, 3, 1, 3, 16, 29).endOfMonth == DateTime(-1999, 3, 31, 23, 59, 59));\n        assert(DateTime(-1999, 4, 1, 4, 17, 30).endOfMonth == DateTime(-1999, 4, 30, 23, 59, 59));\n        assert(DateTime(-1999, 5, 1, 5, 18, 31).endOfMonth == DateTime(-1999, 5, 31, 23, 59, 59));\n        assert(DateTime(-1999, 6, 1, 6, 19, 32).endOfMonth == DateTime(-1999, 6, 30, 23, 59, 59));\n        assert(DateTime(-1999, 7, 1, 7, 20, 33).endOfMonth == DateTime(-1999, 7, 31, 23, 59, 59));\n        assert(DateTime(-1999, 8, 1, 8, 21, 34).endOfMonth == DateTime(-1999, 8, 31, 23, 59, 59));\n        assert(DateTime(-1999, 9, 1, 9, 22, 35).endOfMonth == DateTime(-1999, 9, 30, 23, 59, 59));\n        assert(DateTime(-1999, 10, 1, 10, 23, 36).endOfMonth == DateTime(-1999, 10, 31, 23, 59, 59));\n        assert(DateTime(-1999, 11, 1, 11, 24, 37).endOfMonth == DateTime(-1999, 11, 30, 23, 59, 59));\n        assert(DateTime(-1999, 12, 1, 12, 25, 38).endOfMonth == DateTime(-1999, 12, 31, 23, 59, 59));\n\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(cdt.endOfMonth == DateTime(1999, 7, 31, 23, 59, 59));\n        assert(idt.endOfMonth == DateTime(1999, 7, 31, 23, 59, 59));\n    }\n\n\n    /++\n        The last day in the month that this $(LREF DateTime) is in.\n      +/\n    @property ubyte daysInMonth() const @safe pure nothrow @nogc\n    {\n        return _date.daysInMonth;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(1999, 1, 6), TimeOfDay(0, 0, 0)).daysInMonth == 31);\n        assert(DateTime(Date(1999, 2, 7), TimeOfDay(19, 30, 0)).daysInMonth == 28);\n        assert(DateTime(Date(2000, 2, 7), TimeOfDay(5, 12, 27)).daysInMonth == 29);\n        assert(DateTime(Date(2000, 6, 4), TimeOfDay(12, 22, 9)).daysInMonth == 30);\n    }\n\n    @safe unittest\n    {\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(cdt.daysInMonth == 31);\n        assert(idt.daysInMonth == 31);\n    }\n\n\n    /++\n        Whether the current year is a date in A.D.\n      +/\n    @property bool isAD() const @safe pure nothrow @nogc\n    {\n        return _date.isAD;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(1, 1, 1), TimeOfDay(12, 7, 0)).isAD);\n        assert(DateTime(Date(2010, 12, 31), TimeOfDay(0, 0, 0)).isAD);\n        assert(!DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 59)).isAD);\n        assert(!DateTime(Date(-2010, 1, 1), TimeOfDay(2, 2, 2)).isAD);\n    }\n\n    @safe unittest\n    {\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(cdt.isAD);\n        assert(idt.isAD);\n    }\n\n\n    /++\n        The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for this\n        $(LREF DateTime) at the given time. For example, prior to noon,\n        1996-03-31 would be the Julian day number 2_450_173, so this function\n        returns 2_450_173, while from noon onward, the julian day number would\n        be 2_450_174, so this function returns 2_450_174.\n      +/\n    @property long julianDay() const @safe pure nothrow @nogc\n    {\n        if (_tod._hour < 12)\n            return _date.julianDay - 1;\n        else\n            return _date.julianDay;\n    }\n\n    @safe unittest\n    {\n        assert(DateTime(Date(-4713, 11, 24), TimeOfDay(0, 0, 0)).julianDay == -1);\n        assert(DateTime(Date(-4713, 11, 24), TimeOfDay(12, 0, 0)).julianDay == 0);\n\n        assert(DateTime(Date(0, 12, 31), TimeOfDay(0, 0, 0)).julianDay == 1_721_424);\n        assert(DateTime(Date(0, 12, 31), TimeOfDay(12, 0, 0)).julianDay == 1_721_425);\n\n        assert(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)).julianDay == 1_721_425);\n        assert(DateTime(Date(1, 1, 1), TimeOfDay(12, 0, 0)).julianDay == 1_721_426);\n\n        assert(DateTime(Date(1582, 10, 15), TimeOfDay(0, 0, 0)).julianDay == 2_299_160);\n        assert(DateTime(Date(1582, 10, 15), TimeOfDay(12, 0, 0)).julianDay == 2_299_161);\n\n        assert(DateTime(Date(1858, 11, 17), TimeOfDay(0, 0, 0)).julianDay == 2_400_000);\n        assert(DateTime(Date(1858, 11, 17), TimeOfDay(12, 0, 0)).julianDay == 2_400_001);\n\n        assert(DateTime(Date(1982, 1, 4), TimeOfDay(0, 0, 0)).julianDay == 2_444_973);\n        assert(DateTime(Date(1982, 1, 4), TimeOfDay(12, 0, 0)).julianDay == 2_444_974);\n\n        assert(DateTime(Date(1996, 3, 31), TimeOfDay(0, 0, 0)).julianDay == 2_450_173);\n        assert(DateTime(Date(1996, 3, 31), TimeOfDay(12, 0, 0)).julianDay == 2_450_174);\n\n        assert(DateTime(Date(2010, 8, 24), TimeOfDay(0, 0, 0)).julianDay == 2_455_432);\n        assert(DateTime(Date(2010, 8, 24), TimeOfDay(12, 0, 0)).julianDay == 2_455_433);\n\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(cdt.julianDay == 2_451_366);\n        assert(idt.julianDay == 2_451_366);\n    }\n\n\n    /++\n        The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for any\n        time on this date (since, the modified Julian day changes at midnight).\n      +/\n    @property long modJulianDay() const @safe pure nothrow @nogc\n    {\n        return _date.modJulianDay;\n    }\n\n    @safe unittest\n    {\n        assert(DateTime(Date(1858, 11, 17), TimeOfDay(0, 0, 0)).modJulianDay == 0);\n        assert(DateTime(Date(1858, 11, 17), TimeOfDay(12, 0, 0)).modJulianDay == 0);\n\n        assert(DateTime(Date(2010, 8, 24), TimeOfDay(0, 0, 0)).modJulianDay == 55_432);\n        assert(DateTime(Date(2010, 8, 24), TimeOfDay(12, 0, 0)).modJulianDay == 55_432);\n\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(cdt.modJulianDay == 51_365);\n        assert(idt.modJulianDay == 51_365);\n    }\n\n\n    /++\n        Converts this $(LREF DateTime) to a string with the format `YYYYMMDDTHHMMSS`.\n        If `writer` is set, the resulting string will be written directly to it.\n\n        Params:\n            writer = A `char` accepting\n            $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toISOString() const @safe pure nothrow\n    {\n        import std.array : appender;\n        auto w = appender!string();\n        w.reserve(18);\n        try\n            toISOString(w);\n        catch (Exception e)\n            assert(0, \"toISOString() threw.\");\n        return w.data;\n    }\n\n    /// ditto\n    void toISOString(W)(ref W writer) const\n    if (isOutputRange!(W, char))\n    {\n        import std.format : formattedWrite;\n        _date.toISOString(writer);\n        formattedWrite!(\"T%02d%02d%02d\")(\n            writer,\n            _tod._hour,\n            _tod._minute,\n            _tod._second\n        );\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toISOString() ==\n               \"20100704T070612\");\n\n        assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toISOString() ==\n               \"19981225T021500\");\n\n        assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toISOString() ==\n               \"00000105T230959\");\n\n        assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toISOString() ==\n               \"-00040105T000002\");\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toISOString() == \"00091204T000000\");\n        assert(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toISOString() == \"00991204T050612\");\n        assert(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toISOString() == \"09991204T134459\");\n        assert(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toISOString() == \"99990704T235959\");\n        assert(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toISOString() == \"+100001020T010101\");\n\n        // Test B.C.\n        assert(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toISOString() == \"00001204T001204\");\n        assert(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toISOString() == \"-00091204T000000\");\n        assert(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toISOString() == \"-00991204T050612\");\n        assert(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toISOString() == \"-09991204T134459\");\n        assert(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toISOString() == \"-99990704T235959\");\n        assert(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toISOString() == \"-100001020T010101\");\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        assert(cdt.toISOString() == \"19990706T123033\");\n        assert(idt.toISOString() == \"19990706T123033\");\n    }\n\n\n    /++\n        Converts this $(LREF DateTime) to a string with the format\n        `YYYY-MM-DDTHH:MM:SS`. If `writer` is set, the resulting\n        string will be written directly to it.\n\n        Params:\n            writer = A `char` accepting\n            $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toISOExtString() const @safe pure nothrow\n    {\n        import std.array : appender;\n        auto w = appender!string();\n        w.reserve(20);\n        try\n            toISOExtString(w);\n        catch (Exception e)\n            assert(0, \"toISOExtString() threw.\");\n        return w.data;\n    }\n\n    /// ditto\n    void toISOExtString(W)(ref W writer) const\n    if (isOutputRange!(W, char))\n    {\n        import std.format : formattedWrite;\n        _date.toISOExtString(writer);\n        formattedWrite!(\"T%02d:%02d:%02d\")(\n            writer,\n            _tod._hour,\n            _tod._minute,\n            _tod._second\n        );\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toISOExtString() ==\n               \"2010-07-04T07:06:12\");\n\n        assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toISOExtString() ==\n               \"1998-12-25T02:15:00\");\n\n        assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toISOExtString() ==\n               \"0000-01-05T23:09:59\");\n\n        assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toISOExtString() ==\n               \"-0004-01-05T00:00:02\");\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toISOExtString() == \"0009-12-04T00:00:00\");\n        assert(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toISOExtString() == \"0099-12-04T05:06:12\");\n        assert(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toISOExtString() == \"0999-12-04T13:44:59\");\n        assert(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toISOExtString() == \"9999-07-04T23:59:59\");\n        assert(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toISOExtString() == \"+10000-10-20T01:01:01\");\n\n        // Test B.C.\n        assert(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toISOExtString() == \"0000-12-04T00:12:04\");\n        assert(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toISOExtString() == \"-0009-12-04T00:00:00\");\n        assert(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toISOExtString() == \"-0099-12-04T05:06:12\");\n        assert(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toISOExtString() == \"-0999-12-04T13:44:59\");\n        assert(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toISOExtString() == \"-9999-07-04T23:59:59\");\n        assert(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toISOExtString() == \"-10000-10-20T01:01:01\");\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        assert(cdt.toISOExtString() == \"1999-07-06T12:30:33\");\n        assert(idt.toISOExtString() == \"1999-07-06T12:30:33\");\n    }\n\n    /++\n        Converts this $(LREF DateTime) to a string with the format\n        `YYYY-Mon-DD HH:MM:SS`. If `writer` is set, the resulting\n        string will be written directly to it.\n\n        Params:\n            writer = A `char` accepting\n            $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toSimpleString() const @safe pure nothrow\n    {\n        import std.array : appender;\n        auto w = appender!string();\n        w.reserve(22);\n        try\n            toSimpleString(w);\n        catch (Exception e)\n            assert(0, \"toSimpleString() threw.\");\n        return w.data;\n    }\n\n    /// ditto\n    void toSimpleString(W)(ref W writer) const\n    if (isOutputRange!(W, char))\n    {\n        import std.format : formattedWrite;\n        _date.toSimpleString(writer);\n        formattedWrite!(\" %02d:%02d:%02d\")(\n            writer,\n            _tod._hour,\n            _tod._minute,\n            _tod._second\n        );\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toSimpleString() ==\n               \"2010-Jul-04 07:06:12\");\n\n        assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toSimpleString() ==\n               \"1998-Dec-25 02:15:00\");\n\n        assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toSimpleString() ==\n               \"0000-Jan-05 23:09:59\");\n\n        assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toSimpleString() ==\n               \"-0004-Jan-05 00:00:02\");\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toSimpleString() == \"0009-Dec-04 00:00:00\");\n        assert(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toSimpleString() == \"0099-Dec-04 05:06:12\");\n        assert(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toSimpleString() == \"0999-Dec-04 13:44:59\");\n        assert(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toSimpleString() == \"9999-Jul-04 23:59:59\");\n        assert(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toSimpleString() == \"+10000-Oct-20 01:01:01\");\n\n        // Test B.C.\n        assert(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toSimpleString() == \"0000-Dec-04 00:12:04\");\n        assert(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toSimpleString() == \"-0009-Dec-04 00:00:00\");\n        assert(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toSimpleString() == \"-0099-Dec-04 05:06:12\");\n        assert(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toSimpleString() == \"-0999-Dec-04 13:44:59\");\n        assert(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toSimpleString() == \"-9999-Jul-04 23:59:59\");\n        assert(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toSimpleString() == \"-10000-Oct-20 01:01:01\");\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        assert(cdt.toSimpleString() == \"1999-Jul-06 12:30:33\");\n        assert(idt.toSimpleString() == \"1999-Jul-06 12:30:33\");\n    }\n\n\n    /++\n        Converts this $(LREF DateTime) to a string.\n\n        This function exists to make it easy to convert a $(LREF DateTime) to a\n        string for code that does not care what the exact format is - just that\n        it presents the information in a clear manner. It also makes it easy to\n        simply convert a $(LREF DateTime) to a string when using functions such\n        as `to!string`, `format`, or `writeln` which use toString to convert\n        user-defined types. So, it is unlikely that much code will call\n        toString directly.\n\n        The format of the string is purposefully unspecified, and code that\n        cares about the format of the string should use `toISOString`,\n        `toISOExtString`, `toSimpleString`, or some other custom formatting\n        function that explicitly generates the format that the code needs. The\n        reason is that the code is then clear about what format it's using,\n        making it less error-prone to maintain the code and interact with other\n        software that consumes the generated strings. It's for this same reason\n        that $(LREF DateTime) has no `fromString` function, whereas it does have\n        `fromISOString`, `fromISOExtString`, and `fromSimpleString`.\n\n        The format returned by toString may or may not change in the future.\n      +/\n    string toString() const @safe pure nothrow\n    {\n        return toSimpleString();\n    }\n\n    @safe unittest\n    {\n        auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));\n        assert(dt.toString());\n        assert(cdt.toString());\n        assert(idt.toString());\n    }\n\n    /// ditto\n    void toString(W)(ref W writer) const\n    if (isOutputRange!(W, char))\n    {\n        toSimpleString(writer);\n    }\n\n    /++\n        Creates a $(LREF DateTime) from a string with the format YYYYMMDDTHHMMSS.\n        Whitespace is stripped from the given string.\n\n        Params:\n            isoString = A string formatted in the ISO format for dates and times.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given string is\n            not in the ISO format or if the resulting $(LREF DateTime) would not\n            be valid.\n      +/\n    static DateTime fromISOString(S)(scope const S isoString) @safe pure\n        if (isSomeString!S)\n    {\n        import std.algorithm.searching : countUntil;\n        import std.exception : enforce;\n        import std.format : format;\n        import std.string : strip;\n        import std.utf : byCodeUnit;\n\n        auto str = strip(isoString);\n\n        enforce(str.length >= 15, new DateTimeException(format(\"Invalid ISO String: %s\", isoString)));\n        auto t = str.byCodeUnit.countUntil('T');\n\n        enforce(t != -1, new DateTimeException(format(\"Invalid ISO String: %s\", isoString)));\n\n        immutable date = Date.fromISOString(str[0 .. t]);\n        immutable tod = TimeOfDay.fromISOString(str[t+1 .. $]);\n\n        return DateTime(date, tod);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime.fromISOString(\"20100704T070612\") ==\n               DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));\n\n        assert(DateTime.fromISOString(\"19981225T021500\") ==\n               DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));\n\n        assert(DateTime.fromISOString(\"00000105T230959\") ==\n               DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));\n\n        assert(DateTime.fromISOString(\"-00040105T000002\") ==\n               DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));\n\n        assert(DateTime.fromISOString(\" 20100704T070612 \") ==\n               DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException(DateTime.fromISOString(\"\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"20100704000000\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"20100704 000000\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"20100704t000000\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"20100704T000000.\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"20100704T000000.0\"));\n\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-07-0400:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-07-04 00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-07-04t00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-07-04T00:00:00.\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-07-04T00:00:00.0\"));\n\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-0400:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-04 00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-04t00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-04T00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-04 00:00:00.\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-04 00:00:00.0\"));\n\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-12-22T172201\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Dec-22 17:22:01\"));\n\n        assert(DateTime.fromISOString(\"20101222T172201\") == DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01)));\n        assert(DateTime.fromISOString(\"19990706T123033\") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromISOString(\"-19990706T123033\") == DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromISOString(\"+019990706T123033\") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromISOString(\"19990706T123033 \") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromISOString(\" 19990706T123033\") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromISOString(\" 19990706T123033 \") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n    }\n\n    // bug# 17801\n    @safe unittest\n    {\n        import std.conv : to;\n        import std.meta : AliasSeq;\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))\n                assert(DateTime.fromISOString(to!S(\"20121221T141516\")) == DateTime(2012, 12, 21, 14, 15, 16));\n        }\n    }\n\n\n    /++\n        Creates a $(LREF DateTime) from a string with the format\n        YYYY-MM-DDTHH:MM:SS. Whitespace is stripped from the given string.\n\n        Params:\n            isoExtString = A string formatted in the ISO Extended format for dates\n                           and times.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given string is\n            not in the ISO Extended format or if the resulting $(LREF DateTime)\n            would not be valid.\n      +/\n    static DateTime fromISOExtString(S)(scope const S isoExtString) @safe pure\n        if (isSomeString!(S))\n    {\n        import std.algorithm.searching : countUntil;\n        import std.exception : enforce;\n        import std.format : format;\n        import std.string : strip;\n        import std.utf : byCodeUnit;\n\n        auto str = strip(isoExtString);\n\n        enforce(str.length >= 15, new DateTimeException(format(\"Invalid ISO Extended String: %s\", isoExtString)));\n        auto t = str.byCodeUnit.countUntil('T');\n\n        enforce(t != -1, new DateTimeException(format(\"Invalid ISO Extended String: %s\", isoExtString)));\n\n        immutable date = Date.fromISOExtString(str[0 .. t]);\n        immutable tod = TimeOfDay.fromISOExtString(str[t+1 .. $]);\n\n        return DateTime(date, tod);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime.fromISOExtString(\"2010-07-04T07:06:12\") ==\n               DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));\n\n        assert(DateTime.fromISOExtString(\"1998-12-25T02:15:00\") ==\n               DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));\n\n        assert(DateTime.fromISOExtString(\"0000-01-05T23:09:59\") ==\n               DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));\n\n        assert(DateTime.fromISOExtString(\"-0004-01-05T00:00:02\") ==\n               DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));\n\n        assert(DateTime.fromISOExtString(\" 2010-07-04T07:06:12 \") ==\n               DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"20100704000000\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"20100704 000000\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"20100704t000000\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"20100704T000000.\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"20100704T000000.0\"));\n\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"2010-07:0400:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"2010-07-04 00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"2010-07-04 00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"2010-07-04t00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"2010-07-04T00:00:00.\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"2010-07-04T00:00:00.0\"));\n\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"2010-Jul-0400:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"2010-Jul-04t00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"2010-Jul-04 00:00:00.\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"2010-Jul-04 00:00:00.0\"));\n\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"20101222T172201\"));\n        assertThrown!DateTimeException(DateTime.fromISOExtString(\"2010-Dec-22 17:22:01\"));\n\n        assert(DateTime.fromISOExtString(\"2010-12-22T17:22:01\") == DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01)));\n        assert(DateTime.fromISOExtString(\"1999-07-06T12:30:33\") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromISOExtString(\"-1999-07-06T12:30:33\") == DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromISOExtString(\"+01999-07-06T12:30:33\") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromISOExtString(\"1999-07-06T12:30:33 \") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromISOExtString(\" 1999-07-06T12:30:33\") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromISOExtString(\" 1999-07-06T12:30:33 \") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n    }\n\n    // bug# 17801\n    @safe unittest\n    {\n        import std.conv : to;\n        import std.meta : AliasSeq;\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))\n                assert(DateTime.fromISOExtString(to!S(\"2012-12-21T14:15:16\")) == DateTime(2012, 12, 21, 14, 15, 16));\n        }\n    }\n\n\n    /++\n        Creates a $(LREF DateTime) from a string with the format\n        YYYY-Mon-DD HH:MM:SS. Whitespace is stripped from the given string.\n\n        Params:\n            simpleString = A string formatted in the way that toSimpleString\n                           formats dates and times.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given string is\n            not in the correct format or if the resulting $(LREF DateTime)\n            would not be valid.\n      +/\n    static DateTime fromSimpleString(S)(scope const S simpleString) @safe pure\n        if (isSomeString!(S))\n    {\n        import std.algorithm.searching : countUntil;\n        import std.exception : enforce;\n        import std.format : format;\n        import std.string : strip;\n        import std.utf : byCodeUnit;\n\n        auto str = strip(simpleString);\n\n        enforce(str.length >= 15, new DateTimeException(format(\"Invalid string format: %s\", simpleString)));\n        auto t = str.byCodeUnit.countUntil(' ');\n\n        enforce(t != -1, new DateTimeException(format(\"Invalid string format: %s\", simpleString)));\n\n        immutable date = Date.fromSimpleString(str[0 .. t]);\n        immutable tod = TimeOfDay.fromISOExtString(str[t+1 .. $]);\n\n        return DateTime(date, tod);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(DateTime.fromSimpleString(\"2010-Jul-04 07:06:12\") ==\n               DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));\n        assert(DateTime.fromSimpleString(\"1998-Dec-25 02:15:00\") ==\n               DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));\n        assert(DateTime.fromSimpleString(\"0000-Jan-05 23:09:59\") ==\n               DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));\n        assert(DateTime.fromSimpleString(\"-0004-Jan-05 00:00:02\") ==\n               DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));\n        assert(DateTime.fromSimpleString(\" 2010-Jul-04 07:06:12 \") ==\n               DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException(DateTime.fromISOString(\"\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"20100704000000\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"20100704 000000\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"20100704t000000\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"20100704T000000.\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"20100704T000000.0\"));\n\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-07-0400:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-07-04 00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-07-04t00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-07-04T00:00:00.\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-07-04T00:00:00.0\"));\n\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-0400:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-04 00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-04t00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-04T00:00:00\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-04 00:00:00.\"));\n        assertThrown!DateTimeException(DateTime.fromISOString(\"2010-Jul-04 00:00:00.0\"));\n\n        assertThrown!DateTimeException(DateTime.fromSimpleString(\"20101222T172201\"));\n        assertThrown!DateTimeException(DateTime.fromSimpleString(\"2010-12-22T172201\"));\n\n        assert(DateTime.fromSimpleString(\"2010-Dec-22 17:22:01\") ==\n               DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01)));\n        assert(DateTime.fromSimpleString(\"1999-Jul-06 12:30:33\") ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromSimpleString(\"-1999-Jul-06 12:30:33\") ==\n               DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromSimpleString(\"+01999-Jul-06 12:30:33\") ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromSimpleString(\"1999-Jul-06 12:30:33 \") ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromSimpleString(\" 1999-Jul-06 12:30:33\") ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n        assert(DateTime.fromSimpleString(\" 1999-Jul-06 12:30:33 \") ==\n               DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));\n    }\n\n    // bug# 17801\n    @safe unittest\n    {\n        import std.conv : to;\n        import std.meta : AliasSeq;\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))\n                assert(DateTime.fromSimpleString(to!S(\"2012-Dec-21 14:15:16\")) == DateTime(2012, 12, 21, 14, 15, 16));\n        }\n    }\n\n\n    /++\n        Returns the $(LREF DateTime) farthest in the past which is representable\n        by $(LREF DateTime).\n      +/\n    @property static DateTime min() @safe pure nothrow @nogc\n    out(result)\n    {\n        assert(result._date == Date.min);\n        assert(result._tod == TimeOfDay.min);\n    }\n    do\n    {\n        auto dt = DateTime.init;\n        dt._date._year = short.min;\n        dt._date._month = Month.jan;\n        dt._date._day = 1;\n\n        return dt;\n    }\n\n    @safe unittest\n    {\n        assert(DateTime.min.year < 0);\n        assert(DateTime.min < DateTime.max);\n    }\n\n\n    /++\n        Returns the $(LREF DateTime) farthest in the future which is\n        representable by $(LREF DateTime).\n      +/\n    @property static DateTime max() @safe pure nothrow @nogc\n    out(result)\n    {\n        assert(result._date == Date.max);\n        assert(result._tod == TimeOfDay.max);\n    }\n    do\n    {\n        auto dt = DateTime.init;\n        dt._date._year = short.max;\n        dt._date._month = Month.dec;\n        dt._date._day = 31;\n        dt._tod._hour = TimeOfDay.maxHour;\n        dt._tod._minute = TimeOfDay.maxMinute;\n        dt._tod._second = TimeOfDay.maxSecond;\n\n        return dt;\n    }\n\n    @safe unittest\n    {\n        assert(DateTime.max.year > 0);\n        assert(DateTime.max > DateTime.min);\n    }\n\n\nprivate:\n\n    /+\n        Add seconds to the time of day. Negative values will subtract. If the\n        number of seconds overflows (or underflows), then the seconds will wrap,\n        increasing (or decreasing) the number of minutes accordingly. The\n        same goes for any larger units.\n\n        Params:\n            seconds = The number of seconds to add to this $(LREF DateTime).\n      +/\n    ref DateTime _addSeconds(long seconds) return @safe pure nothrow @nogc\n    {\n        import core.time : convert;\n        long hnsecs = convert!(\"seconds\", \"hnsecs\")(seconds);\n        hnsecs += convert!(\"hours\", \"hnsecs\")(_tod._hour);\n        hnsecs += convert!(\"minutes\", \"hnsecs\")(_tod._minute);\n        hnsecs += convert!(\"seconds\", \"hnsecs\")(_tod._second);\n\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs);\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"days\", \"hnsecs\")(1);\n            --days;\n        }\n\n        _date._addDays(days);\n\n        immutable newHours = splitUnitsFromHNSecs!\"hours\"(hnsecs);\n        immutable newMinutes = splitUnitsFromHNSecs!\"minutes\"(hnsecs);\n        immutable newSeconds = splitUnitsFromHNSecs!\"seconds\"(hnsecs);\n\n        _tod._hour = cast(ubyte) newHours;\n        _tod._minute = cast(ubyte) newMinutes;\n        _tod._second = cast(ubyte) newSeconds;\n\n        return this;\n    }\n\n    @safe unittest\n    {\n        static void testDT(DateTime orig, int seconds, DateTime expected, size_t line = __LINE__)\n        {\n            orig._addSeconds(seconds);\n            assert(orig == expected);\n        }\n\n        // Test A.D.\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 0, DateTime(1999, 7, 6, 12, 30, 33));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 1, DateTime(1999, 7, 6, 12, 30, 34));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 2, DateTime(1999, 7, 6, 12, 30, 35));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 3, DateTime(1999, 7, 6, 12, 30, 36));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 4, DateTime(1999, 7, 6, 12, 30, 37));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 5, DateTime(1999, 7, 6, 12, 30, 38));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 10, DateTime(1999, 7, 6, 12, 30, 43));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 15, DateTime(1999, 7, 6, 12, 30, 48));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 26, DateTime(1999, 7, 6, 12, 30, 59));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 27, DateTime(1999, 7, 6, 12, 31, 0));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 30, DateTime(1999, 7, 6, 12, 31, 3));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 59, DateTime(1999, 7, 6, 12, 31, 32));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 60, DateTime(1999, 7, 6, 12, 31, 33));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 61, DateTime(1999, 7, 6, 12, 31, 34));\n\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 1766, DateTime(1999, 7, 6, 12, 59, 59));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 1767, DateTime(1999, 7, 6, 13, 0, 0));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 1768, DateTime(1999, 7, 6, 13, 0, 1));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 2007, DateTime(1999, 7, 6, 13, 4, 0));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 3599, DateTime(1999, 7, 6, 13, 30, 32));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 3600, DateTime(1999, 7, 6, 13, 30, 33));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 3601, DateTime(1999, 7, 6, 13, 30, 34));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), 7200, DateTime(1999, 7, 6, 14, 30, 33));\n        testDT(DateTime(1999, 7, 6, 23, 0, 0), 432_123, DateTime(1999, 7, 11, 23, 2, 3));\n\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -1, DateTime(1999, 7, 6, 12, 30, 32));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -2, DateTime(1999, 7, 6, 12, 30, 31));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -3, DateTime(1999, 7, 6, 12, 30, 30));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -4, DateTime(1999, 7, 6, 12, 30, 29));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -5, DateTime(1999, 7, 6, 12, 30, 28));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -10, DateTime(1999, 7, 6, 12, 30, 23));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -15, DateTime(1999, 7, 6, 12, 30, 18));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -33, DateTime(1999, 7, 6, 12, 30, 0));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -34, DateTime(1999, 7, 6, 12, 29, 59));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -35, DateTime(1999, 7, 6, 12, 29, 58));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -59, DateTime(1999, 7, 6, 12, 29, 34));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -60, DateTime(1999, 7, 6, 12, 29, 33));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -61, DateTime(1999, 7, 6, 12, 29, 32));\n\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -1833, DateTime(1999, 7, 6, 12, 0, 0));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -1834, DateTime(1999, 7, 6, 11, 59, 59));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -3600, DateTime(1999, 7, 6, 11, 30, 33));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -3601, DateTime(1999, 7, 6, 11, 30, 32));\n        testDT(DateTime(1999, 7, 6, 12, 30, 33), -5134, DateTime(1999, 7, 6, 11, 4, 59));\n        testDT(DateTime(1999, 7, 6, 23, 0, 0), -432_123, DateTime(1999, 7, 1, 22, 57, 57));\n\n        testDT(DateTime(1999, 7, 6, 12, 30, 0), 1, DateTime(1999, 7, 6, 12, 30, 1));\n        testDT(DateTime(1999, 7, 6, 12, 30, 0), 0, DateTime(1999, 7, 6, 12, 30, 0));\n        testDT(DateTime(1999, 7, 6, 12, 30, 0), -1, DateTime(1999, 7, 6, 12, 29, 59));\n\n        testDT(DateTime(1999, 7, 6, 12, 0, 0), 1, DateTime(1999, 7, 6, 12, 0, 1));\n        testDT(DateTime(1999, 7, 6, 12, 0, 0), 0, DateTime(1999, 7, 6, 12, 0, 0));\n        testDT(DateTime(1999, 7, 6, 12, 0, 0), -1, DateTime(1999, 7, 6, 11, 59, 59));\n\n        testDT(DateTime(1999, 7, 6, 0, 0, 0), 1, DateTime(1999, 7, 6, 0, 0, 1));\n        testDT(DateTime(1999, 7, 6, 0, 0, 0), 0, DateTime(1999, 7, 6, 0, 0, 0));\n        testDT(DateTime(1999, 7, 6, 0, 0, 0), -1, DateTime(1999, 7, 5, 23, 59, 59));\n\n        testDT(DateTime(1999, 7, 5, 23, 59, 59), 1, DateTime(1999, 7, 6, 0, 0, 0));\n        testDT(DateTime(1999, 7, 5, 23, 59, 59), 0, DateTime(1999, 7, 5, 23, 59, 59));\n        testDT(DateTime(1999, 7, 5, 23, 59, 59), -1, DateTime(1999, 7, 5, 23, 59, 58));\n\n        testDT(DateTime(1998, 12, 31, 23, 59, 59), 1, DateTime(1999, 1, 1, 0, 0, 0));\n        testDT(DateTime(1998, 12, 31, 23, 59, 59), 0, DateTime(1998, 12, 31, 23, 59, 59));\n        testDT(DateTime(1998, 12, 31, 23, 59, 59), -1, DateTime(1998, 12, 31, 23, 59, 58));\n\n        testDT(DateTime(1998, 1, 1, 0, 0, 0), 1, DateTime(1998, 1, 1, 0, 0, 1));\n        testDT(DateTime(1998, 1, 1, 0, 0, 0), 0, DateTime(1998, 1, 1, 0, 0, 0));\n        testDT(DateTime(1998, 1, 1, 0, 0, 0), -1, DateTime(1997, 12, 31, 23, 59, 59));\n\n        // Test B.C.\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 0, DateTime(-1999, 7, 6, 12, 30, 33));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1, DateTime(-1999, 7, 6, 12, 30, 34));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 2, DateTime(-1999, 7, 6, 12, 30, 35));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3, DateTime(-1999, 7, 6, 12, 30, 36));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 4, DateTime(-1999, 7, 6, 12, 30, 37));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 5, DateTime(-1999, 7, 6, 12, 30, 38));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 10, DateTime(-1999, 7, 6, 12, 30, 43));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 15, DateTime(-1999, 7, 6, 12, 30, 48));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 26, DateTime(-1999, 7, 6, 12, 30, 59));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 27, DateTime(-1999, 7, 6, 12, 31, 0));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 30, DateTime(-1999, 7, 6, 12, 31, 3));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 59, DateTime(-1999, 7, 6, 12, 31, 32));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 60, DateTime(-1999, 7, 6, 12, 31, 33));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 61, DateTime(-1999, 7, 6, 12, 31, 34));\n\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1766, DateTime(-1999, 7, 6, 12, 59, 59));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1767, DateTime(-1999, 7, 6, 13, 0, 0));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1768, DateTime(-1999, 7, 6, 13, 0, 1));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 2007, DateTime(-1999, 7, 6, 13, 4, 0));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3599, DateTime(-1999, 7, 6, 13, 30, 32));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3600, DateTime(-1999, 7, 6, 13, 30, 33));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3601, DateTime(-1999, 7, 6, 13, 30, 34));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), 7200, DateTime(-1999, 7, 6, 14, 30, 33));\n        testDT(DateTime(-1999, 7, 6, 23, 0, 0), 432_123, DateTime(-1999, 7, 11, 23, 2, 3));\n\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1, DateTime(-1999, 7, 6, 12, 30, 32));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -2, DateTime(-1999, 7, 6, 12, 30, 31));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3, DateTime(-1999, 7, 6, 12, 30, 30));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -4, DateTime(-1999, 7, 6, 12, 30, 29));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -5, DateTime(-1999, 7, 6, 12, 30, 28));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -10, DateTime(-1999, 7, 6, 12, 30, 23));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -15, DateTime(-1999, 7, 6, 12, 30, 18));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -33, DateTime(-1999, 7, 6, 12, 30, 0));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -34, DateTime(-1999, 7, 6, 12, 29, 59));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -35, DateTime(-1999, 7, 6, 12, 29, 58));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -59, DateTime(-1999, 7, 6, 12, 29, 34));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -60, DateTime(-1999, 7, 6, 12, 29, 33));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -61, DateTime(-1999, 7, 6, 12, 29, 32));\n\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1833, DateTime(-1999, 7, 6, 12, 0, 0));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1834, DateTime(-1999, 7, 6, 11, 59, 59));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3600, DateTime(-1999, 7, 6, 11, 30, 33));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3601, DateTime(-1999, 7, 6, 11, 30, 32));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -5134, DateTime(-1999, 7, 6, 11, 4, 59));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 33), -7200, DateTime(-1999, 7, 6, 10, 30, 33));\n        testDT(DateTime(-1999, 7, 6, 23, 0, 0), -432_123, DateTime(-1999, 7, 1, 22, 57, 57));\n\n        testDT(DateTime(-1999, 7, 6, 12, 30, 0), 1, DateTime(-1999, 7, 6, 12, 30, 1));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 0), 0, DateTime(-1999, 7, 6, 12, 30, 0));\n        testDT(DateTime(-1999, 7, 6, 12, 30, 0), -1, DateTime(-1999, 7, 6, 12, 29, 59));\n\n        testDT(DateTime(-1999, 7, 6, 12, 0, 0), 1, DateTime(-1999, 7, 6, 12, 0, 1));\n        testDT(DateTime(-1999, 7, 6, 12, 0, 0), 0, DateTime(-1999, 7, 6, 12, 0, 0));\n        testDT(DateTime(-1999, 7, 6, 12, 0, 0), -1, DateTime(-1999, 7, 6, 11, 59, 59));\n\n        testDT(DateTime(-1999, 7, 6, 0, 0, 0), 1, DateTime(-1999, 7, 6, 0, 0, 1));\n        testDT(DateTime(-1999, 7, 6, 0, 0, 0), 0, DateTime(-1999, 7, 6, 0, 0, 0));\n        testDT(DateTime(-1999, 7, 6, 0, 0, 0), -1, DateTime(-1999, 7, 5, 23, 59, 59));\n\n        testDT(DateTime(-1999, 7, 5, 23, 59, 59), 1, DateTime(-1999, 7, 6, 0, 0, 0));\n        testDT(DateTime(-1999, 7, 5, 23, 59, 59), 0, DateTime(-1999, 7, 5, 23, 59, 59));\n        testDT(DateTime(-1999, 7, 5, 23, 59, 59), -1, DateTime(-1999, 7, 5, 23, 59, 58));\n\n        testDT(DateTime(-2000, 12, 31, 23, 59, 59), 1, DateTime(-1999, 1, 1, 0, 0, 0));\n        testDT(DateTime(-2000, 12, 31, 23, 59, 59), 0, DateTime(-2000, 12, 31, 23, 59, 59));\n        testDT(DateTime(-2000, 12, 31, 23, 59, 59), -1, DateTime(-2000, 12, 31, 23, 59, 58));\n\n        testDT(DateTime(-2000, 1, 1, 0, 0, 0), 1, DateTime(-2000, 1, 1, 0, 0, 1));\n        testDT(DateTime(-2000, 1, 1, 0, 0, 0), 0, DateTime(-2000, 1, 1, 0, 0, 0));\n        testDT(DateTime(-2000, 1, 1, 0, 0, 0), -1, DateTime(-2001, 12, 31, 23, 59, 59));\n\n        // Test Both\n        testDT(DateTime(1, 1, 1, 0, 0, 0), -1, DateTime(0, 12, 31, 23, 59, 59));\n        testDT(DateTime(0, 12, 31, 23, 59, 59), 1, DateTime(1, 1, 1, 0, 0, 0));\n\n        testDT(DateTime(0, 1, 1, 0, 0, 0), -1, DateTime(-1, 12, 31, 23, 59, 59));\n        testDT(DateTime(-1, 12, 31, 23, 59, 59), 1, DateTime(0, 1, 1, 0, 0, 0));\n\n        testDT(DateTime(-1, 1, 1, 11, 30, 33), 63_165_600L, DateTime(1, 1, 1, 13, 30, 33));\n        testDT(DateTime(1, 1, 1, 13, 30, 33), -63_165_600L, DateTime(-1, 1, 1, 11, 30, 33));\n\n        testDT(DateTime(-1, 1, 1, 11, 30, 33), 63_165_617L, DateTime(1, 1, 1, 13, 30, 50));\n        testDT(DateTime(1, 1, 1, 13, 30, 50), -63_165_617L, DateTime(-1, 1, 1, 11, 30, 33));\n\n        const cdt = DateTime(1999, 7, 6, 12, 30, 33);\n        immutable idt = DateTime(1999, 7, 6, 12, 30, 33);\n        static assert(!__traits(compiles, cdt._addSeconds(4)));\n        static assert(!__traits(compiles, idt._addSeconds(4)));\n    }\n\n\n    Date      _date;\n    TimeOfDay _tod;\n}\n\n///\n@safe pure unittest\n{\n    import core.time : days, seconds;\n\n    auto dt = DateTime(2000, 6, 1, 10, 30, 0);\n\n    assert(dt.date == Date(2000, 6, 1));\n    assert(dt.timeOfDay == TimeOfDay(10, 30, 0));\n    assert(dt.dayOfYear == 153);\n    assert(dt.dayOfWeek == DayOfWeek.thu);\n\n    dt += 10.days + 100.seconds;\n    assert(dt == DateTime(2000, 6, 11, 10, 31, 40));\n\n    assert(dt.toISOExtString() == \"2000-06-11T10:31:40\");\n    assert(dt.toISOString() == \"20000611T103140\");\n    assert(dt.toSimpleString() == \"2000-Jun-11 10:31:40\");\n\n    assert(DateTime.fromISOExtString(\"2018-01-01T12:00:00\") == DateTime(2018, 1, 1, 12, 0, 0));\n    assert(DateTime.fromISOString(\"20180101T120000\") == DateTime(2018, 1, 1, 12, 0, 0));\n    assert(DateTime.fromSimpleString(\"2018-Jan-01 12:00:00\") == DateTime(2018, 1, 1, 12, 0, 0));\n}\n\n/++\n    Represents a date in the\n    $(HTTP en.wikipedia.org/wiki/Proleptic_Gregorian_calendar, Proleptic\n    Gregorian Calendar) ranging from 32,768 B.C. to 32,767 A.D. Positive years\n    are A.D. Non-positive years are B.C.\n\n    Year, month, and day are kept separately internally so that `Date` is\n    optimized for calendar-based operations.\n\n    `Date` uses the Proleptic Gregorian Calendar, so it assumes the Gregorian\n    leap year calculations for its entire length. As per\n    $(HTTP en.wikipedia.org/wiki/ISO_8601, ISO 8601), it treats 1 B.C. as\n    year 0, i.e. 1 B.C. is 0, 2 B.C. is -1, etc. Use $(LREF yearBC) to use B.C.\n    as a positive integer with 1 B.C. being the year prior to 1 A.D.\n\n    Year 0 is a leap year.\n +/\nstruct Date\n{\npublic:\n\n    /++\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the resulting\n            $(LREF Date) would not be valid.\n\n        Params:\n            year  = Year of the Gregorian Calendar. Positive values are A.D.\n                    Non-positive values are B.C. with year 0 being the year\n                    prior to 1 A.D.\n            month = Month of the year (January is 1).\n            day   = Day of the month.\n     +/\n    this(int year, int month, int day) @safe pure\n    {\n        enforceValid!\"months\"(cast(Month) month);\n        enforceValid!\"days\"(year, cast(Month) month, day);\n\n        _year  = cast(short) year;\n        _month = cast(Month) month;\n        _day   = cast(ubyte) day;\n    }\n\n    @safe unittest\n    {\n        import std.exception : assertNotThrown;\n        assert(Date(1, 1, 1) == Date.init);\n\n        static void testDate(Date date, int year, int month, int day)\n        {\n            assert(date._year == year);\n            assert(date._month == month);\n            assert(date._day == day);\n        }\n\n        testDate(Date(1999, 1 , 1), 1999, Month.jan, 1);\n        testDate(Date(1999, 7 , 1), 1999, Month.jul, 1);\n        testDate(Date(1999, 7 , 6), 1999, Month.jul, 6);\n\n        // Test A.D.\n        assertThrown!DateTimeException(Date(1, 0, 1));\n        assertThrown!DateTimeException(Date(1, 1, 0));\n        assertThrown!DateTimeException(Date(1999, 13, 1));\n        assertThrown!DateTimeException(Date(1999, 1, 32));\n        assertThrown!DateTimeException(Date(1999, 2, 29));\n        assertThrown!DateTimeException(Date(2000, 2, 30));\n        assertThrown!DateTimeException(Date(1999, 3, 32));\n        assertThrown!DateTimeException(Date(1999, 4, 31));\n        assertThrown!DateTimeException(Date(1999, 5, 32));\n        assertThrown!DateTimeException(Date(1999, 6, 31));\n        assertThrown!DateTimeException(Date(1999, 7, 32));\n        assertThrown!DateTimeException(Date(1999, 8, 32));\n        assertThrown!DateTimeException(Date(1999, 9, 31));\n        assertThrown!DateTimeException(Date(1999, 10, 32));\n        assertThrown!DateTimeException(Date(1999, 11, 31));\n        assertThrown!DateTimeException(Date(1999, 12, 32));\n\n        assertNotThrown!DateTimeException(Date(1999, 1, 31));\n        assertNotThrown!DateTimeException(Date(1999, 2, 28));\n        assertNotThrown!DateTimeException(Date(2000, 2, 29));\n        assertNotThrown!DateTimeException(Date(1999, 3, 31));\n        assertNotThrown!DateTimeException(Date(1999, 4, 30));\n        assertNotThrown!DateTimeException(Date(1999, 5, 31));\n        assertNotThrown!DateTimeException(Date(1999, 6, 30));\n        assertNotThrown!DateTimeException(Date(1999, 7, 31));\n        assertNotThrown!DateTimeException(Date(1999, 8, 31));\n        assertNotThrown!DateTimeException(Date(1999, 9, 30));\n        assertNotThrown!DateTimeException(Date(1999, 10, 31));\n        assertNotThrown!DateTimeException(Date(1999, 11, 30));\n        assertNotThrown!DateTimeException(Date(1999, 12, 31));\n\n        // Test B.C.\n        assertNotThrown!DateTimeException(Date(0, 1, 1));\n        assertNotThrown!DateTimeException(Date(-1, 1, 1));\n        assertNotThrown!DateTimeException(Date(-1, 12, 31));\n        assertNotThrown!DateTimeException(Date(-1, 2, 28));\n        assertNotThrown!DateTimeException(Date(-4, 2, 29));\n\n        assertThrown!DateTimeException(Date(-1, 2, 29));\n        assertThrown!DateTimeException(Date(-2, 2, 29));\n        assertThrown!DateTimeException(Date(-3, 2, 29));\n    }\n\n\n    /++\n        Params:\n            day = The Xth day of the Gregorian Calendar that the constructed\n                  $(LREF Date) will be for.\n     +/\n    this(int day) @safe pure nothrow @nogc\n    {\n        if (day > 0)\n        {\n            int years = (day / daysIn400Years) * 400 + 1;\n            day %= daysIn400Years;\n\n            {\n                immutable tempYears = day / daysIn100Years;\n\n                if (tempYears == 4)\n                {\n                    years += 300;\n                    day -= daysIn100Years * 3;\n                }\n                else\n                {\n                    years += tempYears * 100;\n                    day %= daysIn100Years;\n                }\n            }\n\n            years += (day / daysIn4Years) * 4;\n            day %= daysIn4Years;\n\n            {\n                immutable tempYears = day / daysInYear;\n\n                if (tempYears == 4)\n                {\n                    years += 3;\n                    day -= daysInYear * 3;\n                }\n                else\n                {\n                    years += tempYears;\n                    day %= daysInYear;\n                }\n            }\n\n            if (day == 0)\n            {\n                _year = cast(short)(years - 1);\n                _month = Month.dec;\n                _day = 31;\n            }\n            else\n            {\n                _year = cast(short) years;\n\n                setDayOfYear(day);\n            }\n        }\n        else if (day <= 0 && -day < daysInLeapYear)\n        {\n            _year = 0;\n\n            setDayOfYear(daysInLeapYear + day);\n        }\n        else\n        {\n            day += daysInLeapYear - 1;\n            int years = (day / daysIn400Years) * 400 - 1;\n            day %= daysIn400Years;\n\n            {\n                immutable tempYears = day / daysIn100Years;\n\n                if (tempYears == -4)\n                {\n                    years -= 300;\n                    day += daysIn100Years * 3;\n                }\n                else\n                {\n                    years += tempYears * 100;\n                    day %= daysIn100Years;\n                }\n            }\n\n            years += (day / daysIn4Years) * 4;\n            day %= daysIn4Years;\n\n            {\n                immutable tempYears = day / daysInYear;\n\n                if (tempYears == -4)\n                {\n                    years -= 3;\n                    day += daysInYear * 3;\n                }\n                else\n                {\n                    years += tempYears;\n                    day %= daysInYear;\n                }\n            }\n\n            if (day == 0)\n            {\n                _year = cast(short)(years + 1);\n                _month = Month.jan;\n                _day = 1;\n            }\n            else\n            {\n                _year = cast(short) years;\n                immutable newDoY = (yearIsLeapYear(_year) ? daysInLeapYear : daysInYear) + day + 1;\n\n                setDayOfYear(newDoY);\n            }\n        }\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        // Test A.D.\n        foreach (gd; chain(testGregDaysBC, testGregDaysAD))\n            assert(Date(gd.day) == gd.date);\n    }\n\n\n    /++\n        Compares this $(LREF Date) with the given $(LREF Date).\n\n        Returns:\n            $(BOOKTABLE,\n            $(TR $(TD this &lt; rhs) $(TD &lt; 0))\n            $(TR $(TD this == rhs) $(TD 0))\n            $(TR $(TD this &gt; rhs) $(TD &gt; 0))\n            )\n     +/\n    int opCmp(Date rhs) const @safe pure nothrow @nogc\n    {\n        if (_year < rhs._year)\n            return -1;\n        if (_year > rhs._year)\n            return 1;\n\n        if (_month < rhs._month)\n            return -1;\n        if (_month > rhs._month)\n            return 1;\n\n        if (_day < rhs._day)\n            return -1;\n        if (_day > rhs._day)\n            return 1;\n\n        return 0;\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(Date(1, 1, 1).opCmp(Date.init) == 0);\n\n        assert(Date(1999, 1, 1).opCmp(Date(1999, 1, 1)) == 0);\n        assert(Date(1, 7, 1).opCmp(Date(1, 7, 1)) == 0);\n        assert(Date(1, 1, 6).opCmp(Date(1, 1, 6)) == 0);\n\n        assert(Date(1999, 7, 1).opCmp(Date(1999, 7, 1)) == 0);\n        assert(Date(1999, 7, 6).opCmp(Date(1999, 7, 6)) == 0);\n\n        assert(Date(1, 7, 6).opCmp(Date(1, 7, 6)) == 0);\n\n        assert(Date(1999, 7, 6).opCmp(Date(2000, 7, 6)) < 0);\n        assert(Date(2000, 7, 6).opCmp(Date(1999, 7, 6)) > 0);\n        assert(Date(1999, 7, 6).opCmp(Date(1999, 8, 6)) < 0);\n        assert(Date(1999, 8, 6).opCmp(Date(1999, 7, 6)) > 0);\n        assert(Date(1999, 7, 6).opCmp(Date(1999, 7, 7)) < 0);\n        assert(Date(1999, 7, 7).opCmp(Date(1999, 7, 6)) > 0);\n\n        assert(Date(1999, 8, 7).opCmp(Date(2000, 7, 6)) < 0);\n        assert(Date(2000, 8, 6).opCmp(Date(1999, 7, 7)) > 0);\n        assert(Date(1999, 7, 7).opCmp(Date(2000, 7, 6)) < 0);\n        assert(Date(2000, 7, 6).opCmp(Date(1999, 7, 7)) > 0);\n        assert(Date(1999, 7, 7).opCmp(Date(1999, 8, 6)) < 0);\n        assert(Date(1999, 8, 6).opCmp(Date(1999, 7, 7)) > 0);\n\n        // Test B.C.\n        assert(Date(0, 1, 1).opCmp(Date(0, 1, 1)) == 0);\n        assert(Date(-1, 1, 1).opCmp(Date(-1, 1, 1)) == 0);\n        assert(Date(-1, 7, 1).opCmp(Date(-1, 7, 1)) == 0);\n        assert(Date(-1, 1, 6).opCmp(Date(-1, 1, 6)) == 0);\n\n        assert(Date(-1999, 7, 1).opCmp(Date(-1999, 7, 1)) == 0);\n        assert(Date(-1999, 7, 6).opCmp(Date(-1999, 7, 6)) == 0);\n\n        assert(Date(-1, 7, 6).opCmp(Date(-1, 7, 6)) == 0);\n\n        assert(Date(-2000, 7, 6).opCmp(Date(-1999, 7, 6)) < 0);\n        assert(Date(-1999, 7, 6).opCmp(Date(-2000, 7, 6)) > 0);\n        assert(Date(-1999, 7, 6).opCmp(Date(-1999, 8, 6)) < 0);\n        assert(Date(-1999, 8, 6).opCmp(Date(-1999, 7, 6)) > 0);\n        assert(Date(-1999, 7, 6).opCmp(Date(-1999, 7, 7)) < 0);\n        assert(Date(-1999, 7, 7).opCmp(Date(-1999, 7, 6)) > 0);\n\n        assert(Date(-2000, 8, 6).opCmp(Date(-1999, 7, 7)) < 0);\n        assert(Date(-1999, 8, 7).opCmp(Date(-2000, 7, 6)) > 0);\n        assert(Date(-2000, 7, 6).opCmp(Date(-1999, 7, 7)) < 0);\n        assert(Date(-1999, 7, 7).opCmp(Date(-2000, 7, 6)) > 0);\n        assert(Date(-1999, 7, 7).opCmp(Date(-1999, 8, 6)) < 0);\n        assert(Date(-1999, 8, 6).opCmp(Date(-1999, 7, 7)) > 0);\n\n        // Test Both\n        assert(Date(-1999, 7, 6).opCmp(Date(1999, 7, 6)) < 0);\n        assert(Date(1999, 7, 6).opCmp(Date(-1999, 7, 6)) > 0);\n\n        assert(Date(-1999, 8, 6).opCmp(Date(1999, 7, 6)) < 0);\n        assert(Date(1999, 7, 6).opCmp(Date(-1999, 8, 6)) > 0);\n\n        assert(Date(-1999, 7, 7).opCmp(Date(1999, 7, 6)) < 0);\n        assert(Date(1999, 7, 6).opCmp(Date(-1999, 7, 7)) > 0);\n\n        assert(Date(-1999, 8, 7).opCmp(Date(1999, 7, 6)) < 0);\n        assert(Date(1999, 7, 6).opCmp(Date(-1999, 8, 7)) > 0);\n\n        assert(Date(-1999, 8, 6).opCmp(Date(1999, 6, 6)) < 0);\n        assert(Date(1999, 6, 8).opCmp(Date(-1999, 7, 6)) > 0);\n\n        auto date = Date(1999, 7, 6);\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(date.opCmp(date) == 0);\n        assert(date.opCmp(cdate) == 0);\n        assert(date.opCmp(idate) == 0);\n        assert(cdate.opCmp(date) == 0);\n        assert(cdate.opCmp(cdate) == 0);\n        assert(cdate.opCmp(idate) == 0);\n        assert(idate.opCmp(date) == 0);\n        assert(idate.opCmp(cdate) == 0);\n        assert(idate.opCmp(idate) == 0);\n    }\n\n\n    /++\n        Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive\n        are B.C.\n     +/\n    @property short year() const @safe pure nothrow @nogc\n    {\n        return _year;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(1999, 7, 6).year == 1999);\n        assert(Date(2010, 10, 4).year == 2010);\n        assert(Date(-7, 4, 5).year == -7);\n    }\n\n    @safe unittest\n    {\n        assert(Date.init.year == 1);\n        assert(Date(1999, 7, 6).year == 1999);\n        assert(Date(-1999, 7, 6).year == -1999);\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.year == 1999);\n        assert(idate.year == 1999);\n    }\n\n    /++\n        Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive\n        are B.C.\n\n        Params:\n            year = The year to set this Date's year to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the new year is not\n            a leap year and the resulting date would be on February 29th.\n     +/\n    @property void year(int year) @safe pure\n    {\n        enforceValid!\"days\"(year, _month, _day);\n        _year = cast(short) year;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(1999, 7, 6).year == 1999);\n        assert(Date(2010, 10, 4).year == 2010);\n        assert(Date(-7, 4, 5).year == -7);\n    }\n\n    @safe unittest\n    {\n        static void testDateInvalid(Date date, int year)\n        {\n            date.year = year;\n        }\n\n        static void testDate(Date date, int year, Date expected)\n        {\n            date.year = year;\n            assert(date == expected);\n        }\n\n        assertThrown!DateTimeException(testDateInvalid(Date(4, 2, 29), 1));\n\n        testDate(Date(1, 1, 1), 1999, Date(1999, 1, 1));\n        testDate(Date(1, 1, 1), 0, Date(0, 1, 1));\n        testDate(Date(1, 1, 1), -1999, Date(-1999, 1, 1));\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate.year = 1999));\n        static assert(!__traits(compiles, idate.year = 1999));\n    }\n\n\n    /++\n        Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if `isAD` is true.\n     +/\n    @property ushort yearBC() const @safe pure\n    {\n        import std.format : format;\n\n        if (isAD)\n            throw new DateTimeException(format(\"Year %s is A.D.\", _year));\n        return cast(ushort)((_year * -1) + 1);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(0, 1, 1).yearBC == 1);\n        assert(Date(-1, 1, 1).yearBC == 2);\n        assert(Date(-100, 1, 1).yearBC == 101);\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException((Date date){date.yearBC;}(Date(1, 1, 1)));\n\n        auto date = Date(0, 7, 6);\n        const cdate = Date(0, 7, 6);\n        immutable idate = Date(0, 7, 6);\n        assert(date.yearBC == 1);\n        assert(cdate.yearBC == 1);\n        assert(idate.yearBC == 1);\n    }\n\n\n    /++\n        Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.\n\n        Params:\n            year = The year B.C. to set this $(LREF Date)'s year to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if a non-positive value\n            is given.\n     +/\n    @property void yearBC(int year) @safe pure\n    {\n        if (year <= 0)\n            throw new DateTimeException(\"The given year is not a year B.C.\");\n        _year = cast(short)((year - 1) * -1);\n    }\n\n    ///\n    @safe unittest\n    {\n        auto date = Date(2010, 1, 1);\n        date.yearBC = 1;\n        assert(date == Date(0, 1, 1));\n\n        date.yearBC = 10;\n        assert(date == Date(-9, 1, 1));\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException((Date date){date.yearBC = -1;}(Date(1, 1, 1)));\n\n        auto date = Date(0, 7, 6);\n        const cdate = Date(0, 7, 6);\n        immutable idate = Date(0, 7, 6);\n        date.yearBC = 7;\n        assert(date.yearBC == 7);\n        static assert(!__traits(compiles, cdate.yearBC = 7));\n        static assert(!__traits(compiles, idate.yearBC = 7));\n    }\n\n\n    /++\n        Month of a Gregorian Year.\n     +/\n    @property Month month() const @safe pure nothrow @nogc\n    {\n        return _month;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(1999, 7, 6).month == 7);\n        assert(Date(2010, 10, 4).month == 10);\n        assert(Date(-7, 4, 5).month == 4);\n    }\n\n    @safe unittest\n    {\n        assert(Date.init.month == 1);\n        assert(Date(1999, 7, 6).month == 7);\n        assert(Date(-1999, 7, 6).month == 7);\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.month == 7);\n        assert(idate.month == 7);\n    }\n\n    /++\n        Month of a Gregorian Year.\n\n        Params:\n            month = The month to set this $(LREF Date)'s month to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given month is\n            not a valid month or if the current day would not be valid in the\n            given month.\n     +/\n    @property void month(Month month) @safe pure\n    {\n        enforceValid!\"months\"(month);\n        enforceValid!\"days\"(_year, month, _day);\n        _month = cast(Month) month;\n    }\n\n    @safe unittest\n    {\n        static void testDate(Date date, Month month, Date expected = Date.init)\n        {\n            date.month = month;\n            assert(expected != Date.init);\n            assert(date == expected);\n        }\n\n        assertThrown!DateTimeException(testDate(Date(1, 1, 1), cast(Month) 0));\n        assertThrown!DateTimeException(testDate(Date(1, 1, 1), cast(Month) 13));\n        assertThrown!DateTimeException(testDate(Date(1, 1, 29), cast(Month) 2));\n        assertThrown!DateTimeException(testDate(Date(0, 1, 30), cast(Month) 2));\n\n        testDate(Date(1, 1, 1), cast(Month) 7, Date(1, 7, 1));\n        testDate(Date(-1, 1, 1), cast(Month) 7, Date(-1, 7, 1));\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate.month = 7));\n        static assert(!__traits(compiles, idate.month = 7));\n    }\n\n\n    /++\n        Day of a Gregorian Month.\n     +/\n    @property ubyte day() const @safe pure nothrow @nogc\n    {\n        return _day;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(1999, 7, 6).day == 6);\n        assert(Date(2010, 10, 4).day == 4);\n        assert(Date(-7, 4, 5).day == 5);\n    }\n\n    @safe unittest\n    {\n        import std.format : format;\n        import std.range : chain;\n\n        static void test(Date date, int expected)\n        {\n            assert(date.day == expected, format(\"Value given: %s\", date));\n        }\n\n        foreach (year; chain(testYearsBC, testYearsAD))\n        {\n            foreach (md; testMonthDays)\n                test(Date(year, md.month, md.day), md.day);\n        }\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.day == 6);\n        assert(idate.day == 6);\n    }\n\n    /++\n        Day of a Gregorian Month.\n\n        Params:\n            day = The day of the month to set this $(LREF Date)'s day to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given day is not\n            a valid day of the current month.\n     +/\n    @property void day(int day) @safe pure\n    {\n        enforceValid!\"days\"(_year, _month, day);\n        _day = cast(ubyte) day;\n    }\n\n    @safe unittest\n    {\n        import std.exception : assertNotThrown;\n\n        static void testDate(Date date, int day)\n        {\n            date.day = day;\n        }\n\n        // Test A.D.\n        assertThrown!DateTimeException(testDate(Date(1, 1, 1), 0));\n        assertThrown!DateTimeException(testDate(Date(1, 1, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(1, 2, 1), 29));\n        assertThrown!DateTimeException(testDate(Date(4, 2, 1), 30));\n        assertThrown!DateTimeException(testDate(Date(1, 3, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(1, 4, 1), 31));\n        assertThrown!DateTimeException(testDate(Date(1, 5, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(1, 6, 1), 31));\n        assertThrown!DateTimeException(testDate(Date(1, 7, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(1, 8, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(1, 9, 1), 31));\n        assertThrown!DateTimeException(testDate(Date(1, 10, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(1, 11, 1), 31));\n        assertThrown!DateTimeException(testDate(Date(1, 12, 1), 32));\n\n        assertNotThrown!DateTimeException(testDate(Date(1, 1, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(1, 2, 1), 28));\n        assertNotThrown!DateTimeException(testDate(Date(4, 2, 1), 29));\n        assertNotThrown!DateTimeException(testDate(Date(1, 3, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(1, 4, 1), 30));\n        assertNotThrown!DateTimeException(testDate(Date(1, 5, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(1, 6, 1), 30));\n        assertNotThrown!DateTimeException(testDate(Date(1, 7, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(1, 8, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(1, 9, 1), 30));\n        assertNotThrown!DateTimeException(testDate(Date(1, 10, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(1, 11, 1), 30));\n        assertNotThrown!DateTimeException(testDate(Date(1, 12, 1), 31));\n\n        {\n            auto date = Date(1, 1, 1);\n            date.day = 6;\n            assert(date == Date(1, 1, 6));\n        }\n\n        // Test B.C.\n        assertThrown!DateTimeException(testDate(Date(-1, 1, 1), 0));\n        assertThrown!DateTimeException(testDate(Date(-1, 1, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(-1, 2, 1), 29));\n        assertThrown!DateTimeException(testDate(Date(0, 2, 1), 30));\n        assertThrown!DateTimeException(testDate(Date(-1, 3, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(-1, 4, 1), 31));\n        assertThrown!DateTimeException(testDate(Date(-1, 5, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(-1, 6, 1), 31));\n        assertThrown!DateTimeException(testDate(Date(-1, 7, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(-1, 8, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(-1, 9, 1), 31));\n        assertThrown!DateTimeException(testDate(Date(-1, 10, 1), 32));\n        assertThrown!DateTimeException(testDate(Date(-1, 11, 1), 31));\n        assertThrown!DateTimeException(testDate(Date(-1, 12, 1), 32));\n\n        assertNotThrown!DateTimeException(testDate(Date(-1, 1, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(-1, 2, 1), 28));\n        assertNotThrown!DateTimeException(testDate(Date(0, 2, 1), 29));\n        assertNotThrown!DateTimeException(testDate(Date(-1, 3, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(-1, 4, 1), 30));\n        assertNotThrown!DateTimeException(testDate(Date(-1, 5, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(-1, 6, 1), 30));\n        assertNotThrown!DateTimeException(testDate(Date(-1, 7, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(-1, 8, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(-1, 9, 1), 30));\n        assertNotThrown!DateTimeException(testDate(Date(-1, 10, 1), 31));\n        assertNotThrown!DateTimeException(testDate(Date(-1, 11, 1), 30));\n        assertNotThrown!DateTimeException(testDate(Date(-1, 12, 1), 31));\n\n        {\n            auto date = Date(-1, 1, 1);\n            date.day = 6;\n            assert(date == Date(-1, 1, 6));\n        }\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate.day = 6));\n        static assert(!__traits(compiles, idate.day = 6));\n    }\n\n\n    /++\n        Adds the given number of years or months to this $(LREF Date), mutating\n        it. A negative number will subtract.\n\n        Note that if day overflow is allowed, and the date with the adjusted\n        year/month overflows the number of days in the new month, then the month\n        will be incremented by one, and the day set to the number of days\n        overflowed. (e.g. if the day were 31 and the new month were June, then\n        the month would be incremented to July, and the new day would be 1). If\n        day overflow is not allowed, then the day will be set to the last valid\n        day in the month (e.g. June 31st would become June 30th).\n\n        Params:\n            units         = The type of units to add (\"years\" or \"months\").\n            value         = The number of months or years to add to this\n                            $(LREF Date).\n            allowOverflow = Whether the day should be allowed to overflow,\n                            causing the month to increment.\n\n        Returns:\n            A reference to the `Date` (`this`).\n      +/\n    @safe pure nothrow @nogc\n    ref Date add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)\n        if (units == \"years\")\n    {\n        _year += value;\n\n        if (_month == Month.feb && _day == 29 && !yearIsLeapYear(_year))\n        {\n            if (allowOverflow == AllowDayOverflow.yes)\n            {\n                _month = Month.mar;\n                _day = 1;\n            }\n            else\n                _day = 28;\n        }\n\n        return this;\n    }\n\n    ///\n    @safe unittest\n    {\n        auto d1 = Date(2010, 1, 1);\n        d1.add!\"months\"(11);\n        assert(d1 == Date(2010, 12, 1));\n\n        auto d2 = Date(2010, 1, 1);\n        d2.add!\"months\"(-11);\n        assert(d2 == Date(2009, 2, 1));\n\n        auto d3 = Date(2000, 2, 29);\n        d3.add!\"years\"(1);\n        assert(d3 == Date(2001, 3, 1));\n\n        auto d4 = Date(2000, 2, 29);\n        d4.add!\"years\"(1, AllowDayOverflow.no);\n        assert(d4 == Date(2001, 2, 28));\n    }\n\n    // Test add!\"years\"() with AllowDayOverflow.yes\n    @safe unittest\n    {\n        // Test A.D.\n        {\n            auto date = Date(1999, 7, 6);\n            date.add!\"years\"(7);\n            assert(date == Date(2006, 7, 6));\n            date.add!\"years\"(-9);\n            assert(date == Date(1997, 7, 6));\n        }\n\n        {\n            auto date = Date(1999, 2, 28);\n            date.add!\"years\"(1);\n            assert(date == Date(2000, 2, 28));\n        }\n\n        {\n            auto date = Date(2000, 2, 29);\n            date.add!\"years\"(-1);\n            assert(date == Date(1999, 3, 1));\n        }\n\n        // Test B.C.\n        {\n            auto date = Date(-1999, 7, 6);\n            date.add!\"years\"(-7);\n            assert(date == Date(-2006, 7, 6));\n            date.add!\"years\"(9);\n            assert(date == Date(-1997, 7, 6));\n        }\n\n        {\n            auto date = Date(-1999, 2, 28);\n            date.add!\"years\"(-1);\n            assert(date == Date(-2000, 2, 28));\n        }\n\n        {\n            auto date = Date(-2000, 2, 29);\n            date.add!\"years\"(1);\n            assert(date == Date(-1999, 3, 1));\n        }\n\n        // Test Both\n        {\n            auto date = Date(4, 7, 6);\n            date.add!\"years\"(-5);\n            assert(date == Date(-1, 7, 6));\n            date.add!\"years\"(5);\n            assert(date == Date(4, 7, 6));\n        }\n\n        {\n            auto date = Date(-4, 7, 6);\n            date.add!\"years\"(5);\n            assert(date == Date(1, 7, 6));\n            date.add!\"years\"(-5);\n            assert(date == Date(-4, 7, 6));\n        }\n\n        {\n            auto date = Date(4, 7, 6);\n            date.add!\"years\"(-8);\n            assert(date == Date(-4, 7, 6));\n            date.add!\"years\"(8);\n            assert(date == Date(4, 7, 6));\n        }\n\n        {\n            auto date = Date(-4, 7, 6);\n            date.add!\"years\"(8);\n            assert(date == Date(4, 7, 6));\n            date.add!\"years\"(-8);\n            assert(date == Date(-4, 7, 6));\n        }\n\n        {\n            auto date = Date(-4, 2, 29);\n            date.add!\"years\"(5);\n            assert(date == Date(1, 3, 1));\n        }\n\n        {\n            auto date = Date(4, 2, 29);\n            date.add!\"years\"(-5);\n            assert(date == Date(-1, 3, 1));\n        }\n\n        {\n            auto date = Date(4, 2, 29);\n            date.add!\"years\"(-5).add!\"years\"(7);\n            assert(date == Date(6, 3, 1));\n        }\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate.add!\"years\"(7)));\n        static assert(!__traits(compiles, idate.add!\"years\"(7)));\n    }\n\n    // Test add!\"years\"() with AllowDayOverflow.no\n    @safe unittest\n    {\n        // Test A.D.\n        {\n            auto date = Date(1999, 7, 6);\n            date.add!\"years\"(7, AllowDayOverflow.no);\n            assert(date == Date(2006, 7, 6));\n            date.add!\"years\"(-9, AllowDayOverflow.no);\n            assert(date == Date(1997, 7, 6));\n        }\n\n        {\n            auto date = Date(1999, 2, 28);\n            date.add!\"years\"(1, AllowDayOverflow.no);\n            assert(date == Date(2000, 2, 28));\n        }\n\n        {\n            auto date = Date(2000, 2, 29);\n            date.add!\"years\"(-1, AllowDayOverflow.no);\n            assert(date == Date(1999, 2, 28));\n        }\n\n        // Test B.C.\n        {\n            auto date = Date(-1999, 7, 6);\n            date.add!\"years\"(-7, AllowDayOverflow.no);\n            assert(date == Date(-2006, 7, 6));\n            date.add!\"years\"(9, AllowDayOverflow.no);\n            assert(date == Date(-1997, 7, 6));\n        }\n\n        {\n            auto date = Date(-1999, 2, 28);\n            date.add!\"years\"(-1, AllowDayOverflow.no);\n            assert(date == Date(-2000, 2, 28));\n        }\n\n        {\n            auto date = Date(-2000, 2, 29);\n            date.add!\"years\"(1, AllowDayOverflow.no);\n            assert(date == Date(-1999, 2, 28));\n        }\n\n        // Test Both\n        {\n            auto date = Date(4, 7, 6);\n            date.add!\"years\"(-5, AllowDayOverflow.no);\n            assert(date == Date(-1, 7, 6));\n            date.add!\"years\"(5, AllowDayOverflow.no);\n            assert(date == Date(4, 7, 6));\n        }\n\n        {\n            auto date = Date(-4, 7, 6);\n            date.add!\"years\"(5, AllowDayOverflow.no);\n            assert(date == Date(1, 7, 6));\n            date.add!\"years\"(-5, AllowDayOverflow.no);\n            assert(date == Date(-4, 7, 6));\n        }\n\n        {\n            auto date = Date(4, 7, 6);\n            date.add!\"years\"(-8, AllowDayOverflow.no);\n            assert(date == Date(-4, 7, 6));\n            date.add!\"years\"(8, AllowDayOverflow.no);\n            assert(date == Date(4, 7, 6));\n        }\n\n        {\n            auto date = Date(-4, 7, 6);\n            date.add!\"years\"(8, AllowDayOverflow.no);\n            assert(date == Date(4, 7, 6));\n            date.add!\"years\"(-8, AllowDayOverflow.no);\n            assert(date == Date(-4, 7, 6));\n        }\n\n        {\n            auto date = Date(-4, 2, 29);\n            date.add!\"years\"(5, AllowDayOverflow.no);\n            assert(date == Date(1, 2, 28));\n        }\n\n        {\n            auto date = Date(4, 2, 29);\n            date.add!\"years\"(-5, AllowDayOverflow.no);\n            assert(date == Date(-1, 2, 28));\n        }\n\n        {\n            auto date = Date(4, 2, 29);\n            date.add!\"years\"(-5, AllowDayOverflow.no).add!\"years\"(7, AllowDayOverflow.no);\n            assert(date == Date(6, 2, 28));\n        }\n    }\n\n\n    // Shares documentation with \"years\" version.\n    @safe pure nothrow @nogc\n    ref Date add(string units)(long months, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)\n        if (units == \"months\")\n    {\n        auto years = months / 12;\n        months %= 12;\n        auto newMonth = _month + months;\n\n        if (months < 0)\n        {\n            if (newMonth < 1)\n            {\n                newMonth += 12;\n                --years;\n            }\n        }\n        else if (newMonth > 12)\n        {\n            newMonth -= 12;\n            ++years;\n        }\n\n        _year += years;\n        _month = cast(Month) newMonth;\n\n        immutable currMaxDay = maxDay(_year, _month);\n        immutable overflow = _day - currMaxDay;\n\n        if (overflow > 0)\n        {\n            if (allowOverflow == AllowDayOverflow.yes)\n            {\n                ++_month;\n                _day = cast(ubyte) overflow;\n            }\n            else\n                _day = cast(ubyte) currMaxDay;\n        }\n\n        return this;\n    }\n\n    // Test add!\"months\"() with AllowDayOverflow.yes\n    @safe unittest\n    {\n        // Test A.D.\n        {\n            auto date = Date(1999, 7, 6);\n            date.add!\"months\"(3);\n            assert(date == Date(1999, 10, 6));\n            date.add!\"months\"(-4);\n            assert(date == Date(1999, 6, 6));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date.add!\"months\"(6);\n            assert(date == Date(2000, 1, 6));\n            date.add!\"months\"(-6);\n            assert(date == Date(1999, 7, 6));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date.add!\"months\"(27);\n            assert(date == Date(2001, 10, 6));\n            date.add!\"months\"(-28);\n            assert(date == Date(1999, 6, 6));\n        }\n\n        {\n            auto date = Date(1999, 5, 31);\n            date.add!\"months\"(1);\n            assert(date == Date(1999, 7, 1));\n        }\n\n        {\n            auto date = Date(1999, 5, 31);\n            date.add!\"months\"(-1);\n            assert(date == Date(1999, 5, 1));\n        }\n\n        {\n            auto date = Date(1999, 2, 28);\n            date.add!\"months\"(12);\n            assert(date == Date(2000, 2, 28));\n        }\n\n        {\n            auto date = Date(2000, 2, 29);\n            date.add!\"months\"(12);\n            assert(date == Date(2001, 3, 1));\n        }\n\n        {\n            auto date = Date(1999, 7, 31);\n            date.add!\"months\"(1);\n            assert(date == Date(1999, 8, 31));\n            date.add!\"months\"(1);\n            assert(date == Date(1999, 10, 1));\n        }\n\n        {\n            auto date = Date(1998, 8, 31);\n            date.add!\"months\"(13);\n            assert(date == Date(1999, 10, 1));\n            date.add!\"months\"(-13);\n            assert(date == Date(1998, 9, 1));\n        }\n\n        {\n            auto date = Date(1997, 12, 31);\n            date.add!\"months\"(13);\n            assert(date == Date(1999, 1, 31));\n            date.add!\"months\"(-13);\n            assert(date == Date(1997, 12, 31));\n        }\n\n        {\n            auto date = Date(1997, 12, 31);\n            date.add!\"months\"(14);\n            assert(date == Date(1999, 3, 3));\n            date.add!\"months\"(-14);\n            assert(date == Date(1998, 1, 3));\n        }\n\n        {\n            auto date = Date(1998, 12, 31);\n            date.add!\"months\"(14);\n            assert(date == Date(2000, 3, 2));\n            date.add!\"months\"(-14);\n            assert(date == Date(1999, 1, 2));\n        }\n\n        {\n            auto date = Date(1999, 12, 31);\n            date.add!\"months\"(14);\n            assert(date == Date(2001, 3, 3));\n            date.add!\"months\"(-14);\n            assert(date == Date(2000, 1, 3));\n        }\n\n        // Test B.C.\n        {\n            auto date = Date(-1999, 7, 6);\n            date.add!\"months\"(3);\n            assert(date == Date(-1999, 10, 6));\n            date.add!\"months\"(-4);\n            assert(date == Date(-1999, 6, 6));\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date.add!\"months\"(6);\n            assert(date == Date(-1998, 1, 6));\n            date.add!\"months\"(-6);\n            assert(date == Date(-1999, 7, 6));\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date.add!\"months\"(-27);\n            assert(date == Date(-2001, 4, 6));\n            date.add!\"months\"(28);\n            assert(date == Date(-1999, 8, 6));\n        }\n\n        {\n            auto date = Date(-1999, 5, 31);\n            date.add!\"months\"(1);\n            assert(date == Date(-1999, 7, 1));\n        }\n\n        {\n            auto date = Date(-1999, 5, 31);\n            date.add!\"months\"(-1);\n            assert(date == Date(-1999, 5, 1));\n        }\n\n        {\n            auto date = Date(-1999, 2, 28);\n            date.add!\"months\"(-12);\n            assert(date == Date(-2000, 2, 28));\n        }\n\n        {\n            auto date = Date(-2000, 2, 29);\n            date.add!\"months\"(-12);\n            assert(date == Date(-2001, 3, 1));\n        }\n\n        {\n            auto date = Date(-1999, 7, 31);\n            date.add!\"months\"(1);\n            assert(date == Date(-1999, 8, 31));\n            date.add!\"months\"(1);\n            assert(date == Date(-1999, 10, 1));\n        }\n\n        {\n            auto date = Date(-1998, 8, 31);\n            date.add!\"months\"(13);\n            assert(date == Date(-1997, 10, 1));\n            date.add!\"months\"(-13);\n            assert(date == Date(-1998, 9, 1));\n        }\n\n        {\n            auto date = Date(-1997, 12, 31);\n            date.add!\"months\"(13);\n            assert(date == Date(-1995, 1, 31));\n            date.add!\"months\"(-13);\n            assert(date == Date(-1997, 12, 31));\n        }\n\n        {\n            auto date = Date(-1997, 12, 31);\n            date.add!\"months\"(14);\n            assert(date == Date(-1995, 3, 3));\n            date.add!\"months\"(-14);\n            assert(date == Date(-1996, 1, 3));\n        }\n\n        {\n            auto date = Date(-2002, 12, 31);\n            date.add!\"months\"(14);\n            assert(date == Date(-2000, 3, 2));\n            date.add!\"months\"(-14);\n            assert(date == Date(-2001, 1, 2));\n        }\n\n        {\n            auto date = Date(-2001, 12, 31);\n            date.add!\"months\"(14);\n            assert(date == Date(-1999, 3, 3));\n            date.add!\"months\"(-14);\n            assert(date == Date(-2000, 1, 3));\n        }\n\n        // Test Both\n        {\n            auto date = Date(1, 1, 1);\n            date.add!\"months\"(-1);\n            assert(date == Date(0, 12, 1));\n            date.add!\"months\"(1);\n            assert(date == Date(1, 1, 1));\n        }\n\n        {\n            auto date = Date(4, 1, 1);\n            date.add!\"months\"(-48);\n            assert(date == Date(0, 1, 1));\n            date.add!\"months\"(48);\n            assert(date == Date(4, 1, 1));\n        }\n\n        {\n            auto date = Date(4, 3, 31);\n            date.add!\"months\"(-49);\n            assert(date == Date(0, 3, 2));\n            date.add!\"months\"(49);\n            assert(date == Date(4, 4, 2));\n        }\n\n        {\n            auto date = Date(4, 3, 31);\n            date.add!\"months\"(-85);\n            assert(date == Date(-3, 3, 3));\n            date.add!\"months\"(85);\n            assert(date == Date(4, 4, 3));\n        }\n\n        {\n            auto date = Date(-3, 3, 31);\n            date.add!\"months\"(85).add!\"months\"(-83);\n            assert(date == Date(-3, 6, 1));\n        }\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate.add!\"months\"(3)));\n        static assert(!__traits(compiles, idate.add!\"months\"(3)));\n    }\n\n    // Test add!\"months\"() with AllowDayOverflow.no\n    @safe unittest\n    {\n        // Test A.D.\n        {\n            auto date = Date(1999, 7, 6);\n            date.add!\"months\"(3, AllowDayOverflow.no);\n            assert(date == Date(1999, 10, 6));\n            date.add!\"months\"(-4, AllowDayOverflow.no);\n            assert(date == Date(1999, 6, 6));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date.add!\"months\"(6, AllowDayOverflow.no);\n            assert(date == Date(2000, 1, 6));\n            date.add!\"months\"(-6, AllowDayOverflow.no);\n            assert(date == Date(1999, 7, 6));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date.add!\"months\"(27, AllowDayOverflow.no);\n            assert(date == Date(2001, 10, 6));\n            date.add!\"months\"(-28, AllowDayOverflow.no);\n            assert(date == Date(1999, 6, 6));\n        }\n\n        {\n            auto date = Date(1999, 5, 31);\n            date.add!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(1999, 6, 30));\n        }\n\n        {\n            auto date = Date(1999, 5, 31);\n            date.add!\"months\"(-1, AllowDayOverflow.no);\n            assert(date == Date(1999, 4, 30));\n        }\n\n        {\n            auto date = Date(1999, 2, 28);\n            date.add!\"months\"(12, AllowDayOverflow.no);\n            assert(date == Date(2000, 2, 28));\n        }\n\n        {\n            auto date = Date(2000, 2, 29);\n            date.add!\"months\"(12, AllowDayOverflow.no);\n            assert(date == Date(2001, 2, 28));\n        }\n\n        {\n            auto date = Date(1999, 7, 31);\n            date.add!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(1999, 8, 31));\n            date.add!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(1999, 9, 30));\n        }\n\n        {\n            auto date = Date(1998, 8, 31);\n            date.add!\"months\"(13, AllowDayOverflow.no);\n            assert(date == Date(1999, 9, 30));\n            date.add!\"months\"(-13, AllowDayOverflow.no);\n            assert(date == Date(1998, 8, 30));\n        }\n\n        {\n            auto date = Date(1997, 12, 31);\n            date.add!\"months\"(13, AllowDayOverflow.no);\n            assert(date == Date(1999, 1, 31));\n            date.add!\"months\"(-13, AllowDayOverflow.no);\n            assert(date == Date(1997, 12, 31));\n        }\n\n        {\n            auto date = Date(1997, 12, 31);\n            date.add!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(1999, 2, 28));\n            date.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(1997, 12, 28));\n        }\n\n        {\n            auto date = Date(1998, 12, 31);\n            date.add!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(2000, 2, 29));\n            date.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(1998, 12, 29));\n        }\n\n        {\n            auto date = Date(1999, 12, 31);\n            date.add!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(2001, 2, 28));\n            date.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(1999, 12, 28));\n        }\n\n        // Test B.C.\n        {\n            auto date = Date(-1999, 7, 6);\n            date.add!\"months\"(3, AllowDayOverflow.no);\n            assert(date == Date(-1999, 10, 6));\n            date.add!\"months\"(-4, AllowDayOverflow.no);\n            assert(date == Date(-1999, 6, 6));\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date.add!\"months\"(6, AllowDayOverflow.no);\n            assert(date == Date(-1998, 1, 6));\n            date.add!\"months\"(-6, AllowDayOverflow.no);\n            assert(date == Date(-1999, 7, 6));\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date.add!\"months\"(-27, AllowDayOverflow.no);\n            assert(date == Date(-2001, 4, 6));\n            date.add!\"months\"(28, AllowDayOverflow.no);\n            assert(date == Date(-1999, 8, 6));\n        }\n\n        {\n            auto date = Date(-1999, 5, 31);\n            date.add!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(-1999, 6, 30));\n        }\n\n        {\n            auto date = Date(-1999, 5, 31);\n            date.add!\"months\"(-1, AllowDayOverflow.no);\n            assert(date == Date(-1999, 4, 30));\n        }\n\n        {\n            auto date = Date(-1999, 2, 28);\n            date.add!\"months\"(-12, AllowDayOverflow.no);\n            assert(date == Date(-2000, 2, 28));\n        }\n\n        {\n            auto date = Date(-2000, 2, 29);\n            date.add!\"months\"(-12, AllowDayOverflow.no);\n            assert(date == Date(-2001, 2, 28));\n        }\n\n        {\n            auto date = Date(-1999, 7, 31);\n            date.add!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(-1999, 8, 31));\n            date.add!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(-1999, 9, 30));\n        }\n\n        {\n            auto date = Date(-1998, 8, 31);\n            date.add!\"months\"(13, AllowDayOverflow.no);\n            assert(date == Date(-1997, 9, 30));\n            date.add!\"months\"(-13, AllowDayOverflow.no);\n            assert(date == Date(-1998, 8, 30));\n        }\n\n        {\n            auto date = Date(-1997, 12, 31);\n            date.add!\"months\"(13, AllowDayOverflow.no);\n            assert(date == Date(-1995, 1, 31));\n            date.add!\"months\"(-13, AllowDayOverflow.no);\n            assert(date == Date(-1997, 12, 31));\n        }\n\n        {\n            auto date = Date(-1997, 12, 31);\n            date.add!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(-1995, 2, 28));\n            date.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(-1997, 12, 28));\n        }\n\n        {\n            auto date = Date(-2002, 12, 31);\n            date.add!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(-2000, 2, 29));\n            date.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(-2002, 12, 29));\n        }\n\n        {\n            auto date = Date(-2001, 12, 31);\n            date.add!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(-1999, 2, 28));\n            date.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(-2001, 12, 28));\n        }\n\n        // Test Both\n        {\n            auto date = Date(1, 1, 1);\n            date.add!\"months\"(-1, AllowDayOverflow.no);\n            assert(date == Date(0, 12, 1));\n            date.add!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(1, 1, 1));\n        }\n\n        {\n            auto date = Date(4, 1, 1);\n            date.add!\"months\"(-48, AllowDayOverflow.no);\n            assert(date == Date(0, 1, 1));\n            date.add!\"months\"(48, AllowDayOverflow.no);\n            assert(date == Date(4, 1, 1));\n        }\n\n        {\n            auto date = Date(4, 3, 31);\n            date.add!\"months\"(-49, AllowDayOverflow.no);\n            assert(date == Date(0, 2, 29));\n            date.add!\"months\"(49, AllowDayOverflow.no);\n            assert(date == Date(4, 3, 29));\n        }\n\n        {\n            auto date = Date(4, 3, 31);\n            date.add!\"months\"(-85, AllowDayOverflow.no);\n            assert(date == Date(-3, 2, 28));\n            date.add!\"months\"(85, AllowDayOverflow.no);\n            assert(date == Date(4, 3, 28));\n        }\n\n        {\n            auto date = Date(-3, 3, 31);\n            date.add!\"months\"(85, AllowDayOverflow.no).add!\"months\"(-83, AllowDayOverflow.no);\n            assert(date == Date(-3, 5, 30));\n        }\n    }\n\n\n    /++\n        Adds the given number of years or months to this $(LREF Date), mutating\n        it. A negative number will subtract.\n\n        The difference between rolling and adding is that rolling does not\n        affect larger units. Rolling a $(LREF Date) 12 months gets\n        the exact same $(LREF Date). However, the days can still be affected due\n        to the differing number of days in each month.\n\n        Because there are no units larger than years, there is no difference\n        between adding and rolling years.\n\n        Params:\n            units         = The type of units to add (\"years\" or \"months\").\n            value         = The number of months or years to add to this\n                            $(LREF Date).\n            allowOverflow = Whether the day should be allowed to overflow,\n                            causing the month to increment.\n\n        Returns:\n            A reference to the `Date` (`this`).\n      +/\n    @safe pure nothrow @nogc\n    ref Date roll(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)\n        if (units == \"years\")\n    {\n        return add!\"years\"(value, allowOverflow);\n    }\n\n    ///\n    @safe unittest\n    {\n        auto d1 = Date(2010, 1, 1);\n        d1.roll!\"months\"(1);\n        assert(d1 == Date(2010, 2, 1));\n\n        auto d2 = Date(2010, 1, 1);\n        d2.roll!\"months\"(-1);\n        assert(d2 == Date(2010, 12, 1));\n\n        auto d3 = Date(1999, 1, 29);\n        d3.roll!\"months\"(1);\n        assert(d3 == Date(1999, 3, 1));\n\n        auto d4 = Date(1999, 1, 29);\n        d4.roll!\"months\"(1, AllowDayOverflow.no);\n        assert(d4 == Date(1999, 2, 28));\n\n        auto d5 = Date(2000, 2, 29);\n        d5.roll!\"years\"(1);\n        assert(d5 == Date(2001, 3, 1));\n\n        auto d6 = Date(2000, 2, 29);\n        d6.roll!\"years\"(1, AllowDayOverflow.no);\n        assert(d6 == Date(2001, 2, 28));\n    }\n\n    @safe unittest\n    {\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate.roll!\"years\"(3)));\n        static assert(!__traits(compiles, idate.rolYears(3)));\n    }\n\n\n    // Shares documentation with \"years\" version.\n    @safe pure nothrow @nogc\n    ref Date roll(string units)(long months, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)\n        if (units == \"months\")\n    {\n        months %= 12;\n        auto newMonth = _month + months;\n\n        if (months < 0)\n        {\n            if (newMonth < 1)\n                newMonth += 12;\n        }\n        else\n        {\n            if (newMonth > 12)\n                newMonth -= 12;\n        }\n\n        _month = cast(Month) newMonth;\n\n        immutable currMaxDay = maxDay(_year, _month);\n        immutable overflow = _day - currMaxDay;\n\n        if (overflow > 0)\n        {\n            if (allowOverflow == AllowDayOverflow.yes)\n            {\n                ++_month;\n                _day = cast(ubyte) overflow;\n            }\n            else\n                _day = cast(ubyte) currMaxDay;\n        }\n\n        return this;\n    }\n\n    // Test roll!\"months\"() with AllowDayOverflow.yes\n    @safe unittest\n    {\n        // Test A.D.\n        {\n            auto date = Date(1999, 7, 6);\n            date.roll!\"months\"(3);\n            assert(date == Date(1999, 10, 6));\n            date.roll!\"months\"(-4);\n            assert(date == Date(1999, 6, 6));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date.roll!\"months\"(6);\n            assert(date == Date(1999, 1, 6));\n            date.roll!\"months\"(-6);\n            assert(date == Date(1999, 7, 6));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date.roll!\"months\"(27);\n            assert(date == Date(1999, 10, 6));\n            date.roll!\"months\"(-28);\n            assert(date == Date(1999, 6, 6));\n        }\n\n        {\n            auto date = Date(1999, 5, 31);\n            date.roll!\"months\"(1);\n            assert(date == Date(1999, 7, 1));\n        }\n\n        {\n            auto date = Date(1999, 5, 31);\n            date.roll!\"months\"(-1);\n            assert(date == Date(1999, 5, 1));\n        }\n\n        {\n            auto date = Date(1999, 2, 28);\n            date.roll!\"months\"(12);\n            assert(date == Date(1999, 2, 28));\n        }\n\n        {\n            auto date = Date(2000, 2, 29);\n            date.roll!\"months\"(12);\n            assert(date == Date(2000, 2, 29));\n        }\n\n        {\n            auto date = Date(1999, 7, 31);\n            date.roll!\"months\"(1);\n            assert(date == Date(1999, 8, 31));\n            date.roll!\"months\"(1);\n            assert(date == Date(1999, 10, 1));\n        }\n\n        {\n            auto date = Date(1998, 8, 31);\n            date.roll!\"months\"(13);\n            assert(date == Date(1998, 10, 1));\n            date.roll!\"months\"(-13);\n            assert(date == Date(1998, 9, 1));\n        }\n\n        {\n            auto date = Date(1997, 12, 31);\n            date.roll!\"months\"(13);\n            assert(date == Date(1997, 1, 31));\n            date.roll!\"months\"(-13);\n            assert(date == Date(1997, 12, 31));\n        }\n\n        {\n            auto date = Date(1997, 12, 31);\n            date.roll!\"months\"(14);\n            assert(date == Date(1997, 3, 3));\n            date.roll!\"months\"(-14);\n            assert(date == Date(1997, 1, 3));\n        }\n\n        {\n            auto date = Date(1998, 12, 31);\n            date.roll!\"months\"(14);\n            assert(date == Date(1998, 3, 3));\n            date.roll!\"months\"(-14);\n            assert(date == Date(1998, 1, 3));\n        }\n\n        {\n            auto date = Date(1999, 12, 31);\n            date.roll!\"months\"(14);\n            assert(date == Date(1999, 3, 3));\n            date.roll!\"months\"(-14);\n            assert(date == Date(1999, 1, 3));\n        }\n\n        // Test B.C.\n        {\n            auto date = Date(-1999, 7, 6);\n            date.roll!\"months\"(3);\n            assert(date == Date(-1999, 10, 6));\n            date.roll!\"months\"(-4);\n            assert(date == Date(-1999, 6, 6));\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date.roll!\"months\"(6);\n            assert(date == Date(-1999, 1, 6));\n            date.roll!\"months\"(-6);\n            assert(date == Date(-1999, 7, 6));\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date.roll!\"months\"(-27);\n            assert(date == Date(-1999, 4, 6));\n            date.roll!\"months\"(28);\n            assert(date == Date(-1999, 8, 6));\n        }\n\n        {\n            auto date = Date(-1999, 5, 31);\n            date.roll!\"months\"(1);\n            assert(date == Date(-1999, 7, 1));\n        }\n\n        {\n            auto date = Date(-1999, 5, 31);\n            date.roll!\"months\"(-1);\n            assert(date == Date(-1999, 5, 1));\n        }\n\n        {\n            auto date = Date(-1999, 2, 28);\n            date.roll!\"months\"(-12);\n            assert(date == Date(-1999, 2, 28));\n        }\n\n        {\n            auto date = Date(-2000, 2, 29);\n            date.roll!\"months\"(-12);\n            assert(date == Date(-2000, 2, 29));\n        }\n\n        {\n            auto date = Date(-1999, 7, 31);\n            date.roll!\"months\"(1);\n            assert(date == Date(-1999, 8, 31));\n            date.roll!\"months\"(1);\n            assert(date == Date(-1999, 10, 1));\n        }\n\n        {\n            auto date = Date(-1998, 8, 31);\n            date.roll!\"months\"(13);\n            assert(date == Date(-1998, 10, 1));\n            date.roll!\"months\"(-13);\n            assert(date == Date(-1998, 9, 1));\n        }\n\n        {\n            auto date = Date(-1997, 12, 31);\n            date.roll!\"months\"(13);\n            assert(date == Date(-1997, 1, 31));\n            date.roll!\"months\"(-13);\n            assert(date == Date(-1997, 12, 31));\n        }\n\n        {\n            auto date = Date(-1997, 12, 31);\n            date.roll!\"months\"(14);\n            assert(date == Date(-1997, 3, 3));\n            date.roll!\"months\"(-14);\n            assert(date == Date(-1997, 1, 3));\n        }\n\n        {\n            auto date = Date(-2002, 12, 31);\n            date.roll!\"months\"(14);\n            assert(date == Date(-2002, 3, 3));\n            date.roll!\"months\"(-14);\n            assert(date == Date(-2002, 1, 3));\n        }\n\n        {\n            auto date = Date(-2001, 12, 31);\n            date.roll!\"months\"(14);\n            assert(date == Date(-2001, 3, 3));\n            date.roll!\"months\"(-14);\n            assert(date == Date(-2001, 1, 3));\n        }\n\n        // Test Both\n        {\n            auto date = Date(1, 1, 1);\n            date.roll!\"months\"(-1);\n            assert(date == Date(1, 12, 1));\n            date.roll!\"months\"(1);\n            assert(date == Date(1, 1, 1));\n        }\n\n        {\n            auto date = Date(4, 1, 1);\n            date.roll!\"months\"(-48);\n            assert(date == Date(4, 1, 1));\n            date.roll!\"months\"(48);\n            assert(date == Date(4, 1, 1));\n        }\n\n        {\n            auto date = Date(4, 3, 31);\n            date.roll!\"months\"(-49);\n            assert(date == Date(4, 3, 2));\n            date.roll!\"months\"(49);\n            assert(date == Date(4, 4, 2));\n        }\n\n        {\n            auto date = Date(4, 3, 31);\n            date.roll!\"months\"(-85);\n            assert(date == Date(4, 3, 2));\n            date.roll!\"months\"(85);\n            assert(date == Date(4, 4, 2));\n        }\n\n        {\n            auto date = Date(-1, 1, 1);\n            date.roll!\"months\"(-1);\n            assert(date == Date(-1, 12, 1));\n            date.roll!\"months\"(1);\n            assert(date == Date(-1, 1, 1));\n        }\n\n        {\n            auto date = Date(-4, 1, 1);\n            date.roll!\"months\"(-48);\n            assert(date == Date(-4, 1, 1));\n            date.roll!\"months\"(48);\n            assert(date == Date(-4, 1, 1));\n        }\n\n        {\n            auto date = Date(-4, 3, 31);\n            date.roll!\"months\"(-49);\n            assert(date == Date(-4, 3, 2));\n            date.roll!\"months\"(49);\n            assert(date == Date(-4, 4, 2));\n        }\n\n        {\n            auto date = Date(-4, 3, 31);\n            date.roll!\"months\"(-85);\n            assert(date == Date(-4, 3, 2));\n            date.roll!\"months\"(85);\n            assert(date == Date(-4, 4, 2));\n        }\n\n        {\n            auto date = Date(-3, 3, 31);\n            date.roll!\"months\"(85).roll!\"months\"(-83);\n            assert(date == Date(-3, 6, 1));\n        }\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate.roll!\"months\"(3)));\n        static assert(!__traits(compiles, idate.roll!\"months\"(3)));\n    }\n\n    // Test roll!\"months\"() with AllowDayOverflow.no\n    @safe unittest\n    {\n        // Test A.D.\n        {\n            auto date = Date(1999, 7, 6);\n            date.roll!\"months\"(3, AllowDayOverflow.no);\n            assert(date == Date(1999, 10, 6));\n            date.roll!\"months\"(-4, AllowDayOverflow.no);\n            assert(date == Date(1999, 6, 6));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date.roll!\"months\"(6, AllowDayOverflow.no);\n            assert(date == Date(1999, 1, 6));\n            date.roll!\"months\"(-6, AllowDayOverflow.no);\n            assert(date == Date(1999, 7, 6));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date.roll!\"months\"(27, AllowDayOverflow.no);\n            assert(date == Date(1999, 10, 6));\n            date.roll!\"months\"(-28, AllowDayOverflow.no);\n            assert(date == Date(1999, 6, 6));\n        }\n\n        {\n            auto date = Date(1999, 5, 31);\n            date.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(1999, 6, 30));\n        }\n\n        {\n            auto date = Date(1999, 5, 31);\n            date.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(date == Date(1999, 4, 30));\n        }\n\n        {\n            auto date = Date(1999, 2, 28);\n            date.roll!\"months\"(12, AllowDayOverflow.no);\n            assert(date == Date(1999, 2, 28));\n        }\n\n        {\n            auto date = Date(2000, 2, 29);\n            date.roll!\"months\"(12, AllowDayOverflow.no);\n            assert(date == Date(2000, 2, 29));\n        }\n\n        {\n            auto date = Date(1999, 7, 31);\n            date.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(1999, 8, 31));\n            date.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(1999, 9, 30));\n        }\n\n        {\n            auto date = Date(1998, 8, 31);\n            date.roll!\"months\"(13, AllowDayOverflow.no);\n            assert(date == Date(1998, 9, 30));\n            date.roll!\"months\"(-13, AllowDayOverflow.no);\n            assert(date == Date(1998, 8, 30));\n        }\n\n        {\n            auto date = Date(1997, 12, 31);\n            date.roll!\"months\"(13, AllowDayOverflow.no);\n            assert(date == Date(1997, 1, 31));\n            date.roll!\"months\"(-13, AllowDayOverflow.no);\n            assert(date == Date(1997, 12, 31));\n        }\n\n        {\n            auto date = Date(1997, 12, 31);\n            date.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(1997, 2, 28));\n            date.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(1997, 12, 28));\n        }\n\n        {\n            auto date = Date(1998, 12, 31);\n            date.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(1998, 2, 28));\n            date.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(1998, 12, 28));\n        }\n\n        {\n            auto date = Date(1999, 12, 31);\n            date.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(1999, 2, 28));\n            date.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(1999, 12, 28));\n        }\n\n        // Test B.C.\n        {\n            auto date = Date(-1999, 7, 6);\n            date.roll!\"months\"(3, AllowDayOverflow.no);\n            assert(date == Date(-1999, 10, 6));\n            date.roll!\"months\"(-4, AllowDayOverflow.no);\n            assert(date == Date(-1999, 6, 6));\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date.roll!\"months\"(6, AllowDayOverflow.no);\n            assert(date == Date(-1999, 1, 6));\n            date.roll!\"months\"(-6, AllowDayOverflow.no);\n            assert(date == Date(-1999, 7, 6));\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date.roll!\"months\"(-27, AllowDayOverflow.no);\n            assert(date == Date(-1999, 4, 6));\n            date.roll!\"months\"(28, AllowDayOverflow.no);\n            assert(date == Date(-1999, 8, 6));\n        }\n\n        {\n            auto date = Date(-1999, 5, 31);\n            date.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(-1999, 6, 30));\n        }\n\n        {\n            auto date = Date(-1999, 5, 31);\n            date.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(date == Date(-1999, 4, 30));\n        }\n\n        {\n            auto date = Date(-1999, 2, 28);\n            date.roll!\"months\"(-12, AllowDayOverflow.no);\n            assert(date == Date(-1999, 2, 28));\n        }\n\n        {\n            auto date = Date(-2000, 2, 29);\n            date.roll!\"months\"(-12, AllowDayOverflow.no);\n            assert(date == Date(-2000, 2, 29));\n        }\n\n        {\n            auto date = Date(-1999, 7, 31);\n            date.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(-1999, 8, 31));\n            date.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(-1999, 9, 30));\n        }\n\n        {\n            auto date = Date(-1998, 8, 31);\n            date.roll!\"months\"(13, AllowDayOverflow.no);\n            assert(date == Date(-1998, 9, 30));\n            date.roll!\"months\"(-13, AllowDayOverflow.no);\n            assert(date == Date(-1998, 8, 30));\n        }\n\n        {\n            auto date = Date(-1997, 12, 31);\n            date.roll!\"months\"(13, AllowDayOverflow.no);\n            assert(date == Date(-1997, 1, 31));\n            date.roll!\"months\"(-13, AllowDayOverflow.no);\n            assert(date == Date(-1997, 12, 31));\n        }\n\n        {\n            auto date = Date(-1997, 12, 31);\n            date.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(-1997, 2, 28));\n            date.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(-1997, 12, 28));\n        }\n\n        {\n            auto date = Date(-2002, 12, 31);\n            date.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(-2002, 2, 28));\n            date.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(-2002, 12, 28));\n        }\n\n        {\n            auto date = Date(-2001, 12, 31);\n            date.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(date == Date(-2001, 2, 28));\n            date.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(date == Date(-2001, 12, 28));\n        }\n\n        // Test Both\n        {\n            auto date = Date(1, 1, 1);\n            date.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(date == Date(1, 12, 1));\n            date.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(1, 1, 1));\n        }\n\n        {\n            auto date = Date(4, 1, 1);\n            date.roll!\"months\"(-48, AllowDayOverflow.no);\n            assert(date == Date(4, 1, 1));\n            date.roll!\"months\"(48, AllowDayOverflow.no);\n            assert(date == Date(4, 1, 1));\n        }\n\n        {\n            auto date = Date(4, 3, 31);\n            date.roll!\"months\"(-49, AllowDayOverflow.no);\n            assert(date == Date(4, 2, 29));\n            date.roll!\"months\"(49, AllowDayOverflow.no);\n            assert(date == Date(4, 3, 29));\n        }\n\n        {\n            auto date = Date(4, 3, 31);\n            date.roll!\"months\"(-85, AllowDayOverflow.no);\n            assert(date == Date(4, 2, 29));\n            date.roll!\"months\"(85, AllowDayOverflow.no);\n            assert(date == Date(4, 3, 29));\n        }\n\n        {\n            auto date = Date(-1, 1, 1);\n            date.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(date == Date(-1, 12, 1));\n            date.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(date == Date(-1, 1, 1));\n        }\n\n        {\n            auto date = Date(-4, 1, 1);\n            date.roll!\"months\"(-48, AllowDayOverflow.no);\n            assert(date == Date(-4, 1, 1));\n            date.roll!\"months\"(48, AllowDayOverflow.no);\n            assert(date == Date(-4, 1, 1));\n        }\n\n        {\n            auto date = Date(-4, 3, 31);\n            date.roll!\"months\"(-49, AllowDayOverflow.no);\n            assert(date == Date(-4, 2, 29));\n            date.roll!\"months\"(49, AllowDayOverflow.no);\n            assert(date == Date(-4, 3, 29));\n        }\n\n        {\n            auto date = Date(-4, 3, 31);\n            date.roll!\"months\"(-85, AllowDayOverflow.no);\n            assert(date == Date(-4, 2, 29));\n            date.roll!\"months\"(85, AllowDayOverflow.no);\n            assert(date == Date(-4, 3, 29));\n        }\n\n        {\n            auto date = Date(-3, 3, 31);\n            date.roll!\"months\"(85, AllowDayOverflow.no).roll!\"months\"(-83, AllowDayOverflow.no);\n            assert(date == Date(-3, 5, 30));\n        }\n    }\n\n\n    /++\n        Adds the given number of units to this $(LREF Date), mutating it. A\n        negative number will subtract.\n\n        The difference between rolling and adding is that rolling does not\n        affect larger units. For instance, rolling a $(LREF Date) one\n        year's worth of days gets the exact same $(LREF Date).\n\n        The only accepted units are `\"days\"`.\n\n        Params:\n            units = The units to add. Must be `\"days\"`.\n            days  = The number of days to add to this $(LREF Date).\n\n        Returns:\n            A reference to the `Date` (`this`).\n      +/\n    ref Date roll(string units)(long days) @safe pure nothrow @nogc\n        if (units == \"days\")\n    {\n        immutable limit = maxDay(_year, _month);\n        days %= limit;\n        auto newDay = _day + days;\n\n        if (days < 0)\n        {\n            if (newDay < 1)\n                newDay += limit;\n        }\n        else if (newDay > limit)\n            newDay -= limit;\n\n        _day = cast(ubyte) newDay;\n        return this;\n    }\n\n    ///\n    @safe unittest\n    {\n        auto d = Date(2010, 1, 1);\n        d.roll!\"days\"(1);\n        assert(d == Date(2010, 1, 2));\n        d.roll!\"days\"(365);\n        assert(d == Date(2010, 1, 26));\n        d.roll!\"days\"(-32);\n        assert(d == Date(2010, 1, 25));\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        {\n            auto date = Date(1999, 2, 28);\n            date.roll!\"days\"(1);\n            assert(date == Date(1999, 2, 1));\n            date.roll!\"days\"(-1);\n            assert(date == Date(1999, 2, 28));\n        }\n\n        {\n            auto date = Date(2000, 2, 28);\n            date.roll!\"days\"(1);\n            assert(date == Date(2000, 2, 29));\n            date.roll!\"days\"(1);\n            assert(date == Date(2000, 2, 1));\n            date.roll!\"days\"(-1);\n            assert(date == Date(2000, 2, 29));\n        }\n\n        {\n            auto date = Date(1999, 6, 30);\n            date.roll!\"days\"(1);\n            assert(date == Date(1999, 6, 1));\n            date.roll!\"days\"(-1);\n            assert(date == Date(1999, 6, 30));\n        }\n\n        {\n            auto date = Date(1999, 7, 31);\n            date.roll!\"days\"(1);\n            assert(date == Date(1999, 7, 1));\n            date.roll!\"days\"(-1);\n            assert(date == Date(1999, 7, 31));\n        }\n\n        {\n            auto date = Date(1999, 1, 1);\n            date.roll!\"days\"(-1);\n            assert(date == Date(1999, 1, 31));\n            date.roll!\"days\"(1);\n            assert(date == Date(1999, 1, 1));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date.roll!\"days\"(9);\n            assert(date == Date(1999, 7, 15));\n            date.roll!\"days\"(-11);\n            assert(date == Date(1999, 7, 4));\n            date.roll!\"days\"(30);\n            assert(date == Date(1999, 7, 3));\n            date.roll!\"days\"(-3);\n            assert(date == Date(1999, 7, 31));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date.roll!\"days\"(365);\n            assert(date == Date(1999, 7, 30));\n            date.roll!\"days\"(-365);\n            assert(date == Date(1999, 7, 6));\n            date.roll!\"days\"(366);\n            assert(date == Date(1999, 7, 31));\n            date.roll!\"days\"(730);\n            assert(date == Date(1999, 7, 17));\n            date.roll!\"days\"(-1096);\n            assert(date == Date(1999, 7, 6));\n        }\n\n        {\n            auto date = Date(1999, 2, 6);\n            date.roll!\"days\"(365);\n            assert(date == Date(1999, 2, 7));\n            date.roll!\"days\"(-365);\n            assert(date == Date(1999, 2, 6));\n            date.roll!\"days\"(366);\n            assert(date == Date(1999, 2, 8));\n            date.roll!\"days\"(730);\n            assert(date == Date(1999, 2, 10));\n            date.roll!\"days\"(-1096);\n            assert(date == Date(1999, 2, 6));\n        }\n\n        // Test B.C.\n        {\n            auto date = Date(-1999, 2, 28);\n            date.roll!\"days\"(1);\n            assert(date == Date(-1999, 2, 1));\n            date.roll!\"days\"(-1);\n            assert(date == Date(-1999, 2, 28));\n        }\n\n        {\n            auto date = Date(-2000, 2, 28);\n            date.roll!\"days\"(1);\n            assert(date == Date(-2000, 2, 29));\n            date.roll!\"days\"(1);\n            assert(date == Date(-2000, 2, 1));\n            date.roll!\"days\"(-1);\n            assert(date == Date(-2000, 2, 29));\n        }\n\n        {\n            auto date = Date(-1999, 6, 30);\n            date.roll!\"days\"(1);\n            assert(date == Date(-1999, 6, 1));\n            date.roll!\"days\"(-1);\n            assert(date == Date(-1999, 6, 30));\n        }\n\n        {\n            auto date = Date(-1999, 7, 31);\n            date.roll!\"days\"(1);\n            assert(date == Date(-1999, 7, 1));\n            date.roll!\"days\"(-1);\n            assert(date == Date(-1999, 7, 31));\n        }\n\n        {\n            auto date = Date(-1999, 1, 1);\n            date.roll!\"days\"(-1);\n            assert(date == Date(-1999, 1, 31));\n            date.roll!\"days\"(1);\n            assert(date == Date(-1999, 1, 1));\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date.roll!\"days\"(9);\n            assert(date == Date(-1999, 7, 15));\n            date.roll!\"days\"(-11);\n            assert(date == Date(-1999, 7, 4));\n            date.roll!\"days\"(30);\n            assert(date == Date(-1999, 7, 3));\n            date.roll!\"days\"(-3);\n            assert(date == Date(-1999, 7, 31));\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date.roll!\"days\"(365);\n            assert(date == Date(-1999, 7, 30));\n            date.roll!\"days\"(-365);\n            assert(date == Date(-1999, 7, 6));\n            date.roll!\"days\"(366);\n            assert(date == Date(-1999, 7, 31));\n            date.roll!\"days\"(730);\n            assert(date == Date(-1999, 7, 17));\n            date.roll!\"days\"(-1096);\n            assert(date == Date(-1999, 7, 6));\n        }\n\n        // Test Both\n        {\n            auto date = Date(1, 7, 6);\n            date.roll!\"days\"(-365);\n            assert(date == Date(1, 7, 13));\n            date.roll!\"days\"(365);\n            assert(date == Date(1, 7, 6));\n            date.roll!\"days\"(-731);\n            assert(date == Date(1, 7, 19));\n            date.roll!\"days\"(730);\n            assert(date == Date(1, 7, 5));\n        }\n\n        {\n            auto date = Date(0, 7, 6);\n            date.roll!\"days\"(-365);\n            assert(date == Date(0, 7, 13));\n            date.roll!\"days\"(365);\n            assert(date == Date(0, 7, 6));\n            date.roll!\"days\"(-731);\n            assert(date == Date(0, 7, 19));\n            date.roll!\"days\"(730);\n            assert(date == Date(0, 7, 5));\n        }\n\n        {\n            auto date = Date(0, 7, 6);\n            date.roll!\"days\"(-365).roll!\"days\"(362).roll!\"days\"(-12).roll!\"days\"(730);\n            assert(date == Date(0, 7, 8));\n        }\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate.roll!\"days\"(12)));\n        static assert(!__traits(compiles, idate.roll!\"days\"(12)));\n    }\n\n    import core.time : Duration;\n    /++\n        Gives the result of adding or subtracting a $(REF Duration, core,time)\n        from\n\n        The legal types of arithmetic for $(LREF Date) using this operator are\n\n        $(BOOKTABLE,\n        $(TR $(TD Date) $(TD +) $(TD Duration) $(TD -->) $(TD Date))\n        $(TR $(TD Date) $(TD -) $(TD Duration) $(TD -->) $(TD Date))\n        )\n\n        Params:\n            duration = The $(REF Duration, core,time) to add to or subtract from\n                       this $(LREF Date).\n      +/\n    Date opBinary(string op)(Duration duration) const @safe pure nothrow @nogc\n        if (op == \"+\" || op == \"-\")\n    {\n        Date retval = this;\n        immutable days = duration.total!\"days\";\n        mixin(\"return retval._addDays(\" ~ op ~ \"days);\");\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : days;\n\n        assert(Date(2015, 12, 31) + days(1) == Date(2016, 1, 1));\n        assert(Date(2004, 2, 26) + days(4) == Date(2004, 3, 1));\n\n        assert(Date(2016, 1, 1) - days(1) == Date(2015, 12, 31));\n        assert(Date(2004, 3, 1) - days(4) == Date(2004, 2, 26));\n    }\n\n    @safe unittest\n    {\n        auto date = Date(1999, 7, 6);\n\n        import core.time : dur;\n        assert(date + dur!\"weeks\"(7) == Date(1999, 8, 24));\n        assert(date + dur!\"weeks\"(-7) == Date(1999, 5, 18));\n        assert(date + dur!\"days\"(7) == Date(1999, 7, 13));\n        assert(date + dur!\"days\"(-7) == Date(1999, 6, 29));\n\n        assert(date + dur!\"hours\"(24) == Date(1999, 7, 7));\n        assert(date + dur!\"hours\"(-24) == Date(1999, 7, 5));\n        assert(date + dur!\"minutes\"(1440) == Date(1999, 7, 7));\n        assert(date + dur!\"minutes\"(-1440) == Date(1999, 7, 5));\n        assert(date + dur!\"seconds\"(86_400) == Date(1999, 7, 7));\n        assert(date + dur!\"seconds\"(-86_400) == Date(1999, 7, 5));\n        assert(date + dur!\"msecs\"(86_400_000) == Date(1999, 7, 7));\n        assert(date + dur!\"msecs\"(-86_400_000) == Date(1999, 7, 5));\n        assert(date + dur!\"usecs\"(86_400_000_000) == Date(1999, 7, 7));\n        assert(date + dur!\"usecs\"(-86_400_000_000) == Date(1999, 7, 5));\n        assert(date + dur!\"hnsecs\"(864_000_000_000) == Date(1999, 7, 7));\n        assert(date + dur!\"hnsecs\"(-864_000_000_000) == Date(1999, 7, 5));\n\n        assert(date - dur!\"weeks\"(-7) == Date(1999, 8, 24));\n        assert(date - dur!\"weeks\"(7) == Date(1999, 5, 18));\n        assert(date - dur!\"days\"(-7) == Date(1999, 7, 13));\n        assert(date - dur!\"days\"(7) == Date(1999, 6, 29));\n\n        assert(date - dur!\"hours\"(-24) == Date(1999, 7, 7));\n        assert(date - dur!\"hours\"(24) == Date(1999, 7, 5));\n        assert(date - dur!\"minutes\"(-1440) == Date(1999, 7, 7));\n        assert(date - dur!\"minutes\"(1440) == Date(1999, 7, 5));\n        assert(date - dur!\"seconds\"(-86_400) == Date(1999, 7, 7));\n        assert(date - dur!\"seconds\"(86_400) == Date(1999, 7, 5));\n        assert(date - dur!\"msecs\"(-86_400_000) == Date(1999, 7, 7));\n        assert(date - dur!\"msecs\"(86_400_000) == Date(1999, 7, 5));\n        assert(date - dur!\"usecs\"(-86_400_000_000) == Date(1999, 7, 7));\n        assert(date - dur!\"usecs\"(86_400_000_000) == Date(1999, 7, 5));\n        assert(date - dur!\"hnsecs\"(-864_000_000_000) == Date(1999, 7, 7));\n        assert(date - dur!\"hnsecs\"(864_000_000_000) == Date(1999, 7, 5));\n\n        auto duration = dur!\"days\"(12);\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(date + duration == Date(1999, 7, 18));\n        assert(cdate + duration == Date(1999, 7, 18));\n        assert(idate + duration == Date(1999, 7, 18));\n\n        assert(date - duration == Date(1999, 6, 24));\n        assert(cdate - duration == Date(1999, 6, 24));\n        assert(idate - duration == Date(1999, 6, 24));\n    }\n\n\n    /++\n        Gives the result of adding or subtracting a $(REF Duration, core,time)\n        from this $(LREF Date), as well as assigning the result to this\n        $(LREF Date).\n\n        The legal types of arithmetic for $(LREF Date) using this operator are\n\n        $(BOOKTABLE,\n        $(TR $(TD Date) $(TD +) $(TD Duration) $(TD -->) $(TD Date))\n        $(TR $(TD Date) $(TD -) $(TD Duration) $(TD -->) $(TD Date))\n        )\n\n        Params:\n            duration = The $(REF Duration, core,time) to add to or subtract from\n                       this $(LREF Date).\n      +/\n    ref Date opOpAssign(string op)(Duration duration) @safe pure nothrow @nogc\n        if (op == \"+\" || op == \"-\")\n    {\n        immutable days = duration.total!\"days\";\n        mixin(\"return _addDays(\" ~ op ~ \"days);\");\n    }\n\n    @safe unittest\n    {\n        import core.time : dur;\n        assert(Date(1999, 7, 6) + dur!\"weeks\"(7) == Date(1999, 8, 24));\n        assert(Date(1999, 7, 6) + dur!\"weeks\"(-7) == Date(1999, 5, 18));\n        assert(Date(1999, 7, 6) + dur!\"days\"(7) == Date(1999, 7, 13));\n        assert(Date(1999, 7, 6) + dur!\"days\"(-7) == Date(1999, 6, 29));\n\n        assert(Date(1999, 7, 6) + dur!\"hours\"(24) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) + dur!\"hours\"(-24) == Date(1999, 7, 5));\n        assert(Date(1999, 7, 6) + dur!\"minutes\"(1440) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) + dur!\"minutes\"(-1440) == Date(1999, 7, 5));\n        assert(Date(1999, 7, 6) + dur!\"seconds\"(86_400) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) + dur!\"seconds\"(-86_400) == Date(1999, 7, 5));\n        assert(Date(1999, 7, 6) + dur!\"msecs\"(86_400_000) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) + dur!\"msecs\"(-86_400_000) == Date(1999, 7, 5));\n        assert(Date(1999, 7, 6) + dur!\"usecs\"(86_400_000_000) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) + dur!\"usecs\"(-86_400_000_000) == Date(1999, 7, 5));\n        assert(Date(1999, 7, 6) + dur!\"hnsecs\"(864_000_000_000) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) + dur!\"hnsecs\"(-864_000_000_000) == Date(1999, 7, 5));\n\n        assert(Date(1999, 7, 6) - dur!\"weeks\"(-7) == Date(1999, 8, 24));\n        assert(Date(1999, 7, 6) - dur!\"weeks\"(7) == Date(1999, 5, 18));\n        assert(Date(1999, 7, 6) - dur!\"days\"(-7) == Date(1999, 7, 13));\n        assert(Date(1999, 7, 6) - dur!\"days\"(7) == Date(1999, 6, 29));\n\n        assert(Date(1999, 7, 6) - dur!\"hours\"(-24) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) - dur!\"hours\"(24) == Date(1999, 7, 5));\n        assert(Date(1999, 7, 6) - dur!\"minutes\"(-1440) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) - dur!\"minutes\"(1440) == Date(1999, 7, 5));\n        assert(Date(1999, 7, 6) - dur!\"seconds\"(-86_400) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) - dur!\"seconds\"(86_400) == Date(1999, 7, 5));\n        assert(Date(1999, 7, 6) - dur!\"msecs\"(-86_400_000) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) - dur!\"msecs\"(86_400_000) == Date(1999, 7, 5));\n        assert(Date(1999, 7, 6) - dur!\"usecs\"(-86_400_000_000) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) - dur!\"usecs\"(86_400_000_000) == Date(1999, 7, 5));\n        assert(Date(1999, 7, 6) - dur!\"hnsecs\"(-864_000_000_000) == Date(1999, 7, 7));\n        assert(Date(1999, 7, 6) - dur!\"hnsecs\"(864_000_000_000) == Date(1999, 7, 5));\n\n        {\n            auto date = Date(0, 1, 31);\n            (date += dur!\"days\"(507)) += dur!\"days\"(-2);\n            assert(date == Date(1, 6, 19));\n        }\n\n        auto duration = dur!\"days\"(12);\n        auto date = Date(1999, 7, 6);\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        date += duration;\n        static assert(!__traits(compiles, cdate += duration));\n        static assert(!__traits(compiles, idate += duration));\n\n        date -= duration;\n        static assert(!__traits(compiles, cdate -= duration));\n        static assert(!__traits(compiles, idate -= duration));\n    }\n\n\n    /++\n        Gives the difference between two $(LREF Date)s.\n\n        The legal types of arithmetic for $(LREF Date) using this operator are\n\n        $(BOOKTABLE,\n        $(TR $(TD Date) $(TD -) $(TD Date) $(TD -->) $(TD duration))\n        )\n      +/\n    Duration opBinary(string op)(Date rhs) const @safe pure nothrow @nogc\n        if (op == \"-\")\n    {\n        import core.time : dur;\n        return dur!\"days\"(this.dayOfGregorianCal - rhs.dayOfGregorianCal);\n    }\n\n    @safe unittest\n    {\n        auto date = Date(1999, 7, 6);\n\n        import core.time : dur;\n        assert(Date(1999, 7, 6) - Date(1998, 7, 6) == dur!\"days\"(365));\n        assert(Date(1998, 7, 6) - Date(1999, 7, 6) == dur!\"days\"(-365));\n        assert(Date(1999, 6, 6) - Date(1999, 5, 6) == dur!\"days\"(31));\n        assert(Date(1999, 5, 6) - Date(1999, 6, 6) == dur!\"days\"(-31));\n        assert(Date(1999, 1, 1) - Date(1998, 12, 31) == dur!\"days\"(1));\n        assert(Date(1998, 12, 31) - Date(1999, 1, 1) == dur!\"days\"(-1));\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(date - date == Duration.zero);\n        assert(cdate - date == Duration.zero);\n        assert(idate - date == Duration.zero);\n\n        assert(date - cdate == Duration.zero);\n        assert(cdate - cdate == Duration.zero);\n        assert(idate - cdate == Duration.zero);\n\n        assert(date - idate == Duration.zero);\n        assert(cdate - idate == Duration.zero);\n        assert(idate - idate == Duration.zero);\n    }\n\n\n    /++\n        Returns the difference between the two $(LREF Date)s in months.\n\n        To get the difference in years, subtract the year property\n        of two $(LREF Date)s. To get the difference in days or weeks,\n        subtract the $(LREF Date)s themselves and use the\n        $(REF Duration, core,time) that results. Because converting between\n        months and smaller units requires a specific date (which\n        $(REF Duration, core,time)s don't have), getting the difference in\n        months requires some math using both the year and month properties, so\n        this is a convenience function for getting the difference in months.\n\n        Note that the number of days in the months or how far into the month\n        either $(LREF Date) is is irrelevant. It is the difference in the month\n        property combined with the difference in years * 12. So, for instance,\n        December 31st and January 1st are one month apart just as December 1st\n        and January 31st are one month apart.\n\n        Params:\n            rhs = The $(LREF Date) to subtract from this one.\n      +/\n    int diffMonths(Date rhs) const @safe pure nothrow @nogc\n    {\n        immutable yearDiff = _year - rhs._year;\n        immutable monthDiff = _month - rhs._month;\n\n        return yearDiff * 12 + monthDiff;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(1999, 2, 1).diffMonths(Date(1999, 1, 31)) == 1);\n        assert(Date(1999, 1, 31).diffMonths(Date(1999, 2, 1)) == -1);\n        assert(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1)) == 2);\n        assert(Date(1999, 1, 1).diffMonths(Date(1999, 3, 31)) == -2);\n    }\n\n    @safe unittest\n    {\n        auto date = Date(1999, 7, 6);\n\n        // Test A.D.\n        assert(date.diffMonths(Date(1998, 6, 5)) == 13);\n        assert(date.diffMonths(Date(1998, 7, 5)) == 12);\n        assert(date.diffMonths(Date(1998, 8, 5)) == 11);\n        assert(date.diffMonths(Date(1998, 9, 5)) == 10);\n        assert(date.diffMonths(Date(1998, 10, 5)) == 9);\n        assert(date.diffMonths(Date(1998, 11, 5)) == 8);\n        assert(date.diffMonths(Date(1998, 12, 5)) == 7);\n        assert(date.diffMonths(Date(1999, 1, 5)) == 6);\n        assert(date.diffMonths(Date(1999, 2, 6)) == 5);\n        assert(date.diffMonths(Date(1999, 3, 6)) == 4);\n        assert(date.diffMonths(Date(1999, 4, 6)) == 3);\n        assert(date.diffMonths(Date(1999, 5, 6)) == 2);\n        assert(date.diffMonths(Date(1999, 6, 6)) == 1);\n        assert(date.diffMonths(date) == 0);\n        assert(date.diffMonths(Date(1999, 8, 6)) == -1);\n        assert(date.diffMonths(Date(1999, 9, 6)) == -2);\n        assert(date.diffMonths(Date(1999, 10, 6)) == -3);\n        assert(date.diffMonths(Date(1999, 11, 6)) == -4);\n        assert(date.diffMonths(Date(1999, 12, 6)) == -5);\n        assert(date.diffMonths(Date(2000, 1, 6)) == -6);\n        assert(date.diffMonths(Date(2000, 2, 6)) == -7);\n        assert(date.diffMonths(Date(2000, 3, 6)) == -8);\n        assert(date.diffMonths(Date(2000, 4, 6)) == -9);\n        assert(date.diffMonths(Date(2000, 5, 6)) == -10);\n        assert(date.diffMonths(Date(2000, 6, 6)) == -11);\n        assert(date.diffMonths(Date(2000, 7, 6)) == -12);\n        assert(date.diffMonths(Date(2000, 8, 6)) == -13);\n\n        assert(Date(1998, 6, 5).diffMonths(date) == -13);\n        assert(Date(1998, 7, 5).diffMonths(date) == -12);\n        assert(Date(1998, 8, 5).diffMonths(date) == -11);\n        assert(Date(1998, 9, 5).diffMonths(date) == -10);\n        assert(Date(1998, 10, 5).diffMonths(date) == -9);\n        assert(Date(1998, 11, 5).diffMonths(date) == -8);\n        assert(Date(1998, 12, 5).diffMonths(date) == -7);\n        assert(Date(1999, 1, 5).diffMonths(date) == -6);\n        assert(Date(1999, 2, 6).diffMonths(date) == -5);\n        assert(Date(1999, 3, 6).diffMonths(date) == -4);\n        assert(Date(1999, 4, 6).diffMonths(date) == -3);\n        assert(Date(1999, 5, 6).diffMonths(date) == -2);\n        assert(Date(1999, 6, 6).diffMonths(date) == -1);\n        assert(Date(1999, 8, 6).diffMonths(date) == 1);\n        assert(Date(1999, 9, 6).diffMonths(date) == 2);\n        assert(Date(1999, 10, 6).diffMonths(date) == 3);\n        assert(Date(1999, 11, 6).diffMonths(date) == 4);\n        assert(Date(1999, 12, 6).diffMonths(date) == 5);\n        assert(Date(2000, 1, 6).diffMonths(date) == 6);\n        assert(Date(2000, 2, 6).diffMonths(date) == 7);\n        assert(Date(2000, 3, 6).diffMonths(date) == 8);\n        assert(Date(2000, 4, 6).diffMonths(date) == 9);\n        assert(Date(2000, 5, 6).diffMonths(date) == 10);\n        assert(Date(2000, 6, 6).diffMonths(date) == 11);\n        assert(Date(2000, 7, 6).diffMonths(date) == 12);\n        assert(Date(2000, 8, 6).diffMonths(date) == 13);\n\n        assert(date.diffMonths(Date(1999, 6, 30)) == 1);\n        assert(date.diffMonths(Date(1999, 7, 1)) == 0);\n        assert(date.diffMonths(Date(1999, 7, 6)) == 0);\n        assert(date.diffMonths(Date(1999, 7, 11)) == 0);\n        assert(date.diffMonths(Date(1999, 7, 16)) == 0);\n        assert(date.diffMonths(Date(1999, 7, 21)) == 0);\n        assert(date.diffMonths(Date(1999, 7, 26)) == 0);\n        assert(date.diffMonths(Date(1999, 7, 31)) == 0);\n        assert(date.diffMonths(Date(1999, 8, 1)) == -1);\n\n        assert(date.diffMonths(Date(1990, 6, 30)) == 109);\n        assert(date.diffMonths(Date(1990, 7, 1)) == 108);\n        assert(date.diffMonths(Date(1990, 7, 6)) == 108);\n        assert(date.diffMonths(Date(1990, 7, 11)) == 108);\n        assert(date.diffMonths(Date(1990, 7, 16)) == 108);\n        assert(date.diffMonths(Date(1990, 7, 21)) == 108);\n        assert(date.diffMonths(Date(1990, 7, 26)) == 108);\n        assert(date.diffMonths(Date(1990, 7, 31)) == 108);\n        assert(date.diffMonths(Date(1990, 8, 1)) == 107);\n\n        assert(Date(1999, 6, 30).diffMonths(date) == -1);\n        assert(Date(1999, 7, 1).diffMonths(date) == 0);\n        assert(Date(1999, 7, 6).diffMonths(date) == 0);\n        assert(Date(1999, 7, 11).diffMonths(date) == 0);\n        assert(Date(1999, 7, 16).diffMonths(date) == 0);\n        assert(Date(1999, 7, 21).diffMonths(date) == 0);\n        assert(Date(1999, 7, 26).diffMonths(date) == 0);\n        assert(Date(1999, 7, 31).diffMonths(date) == 0);\n        assert(Date(1999, 8, 1).diffMonths(date) == 1);\n\n        assert(Date(1990, 6, 30).diffMonths(date) == -109);\n        assert(Date(1990, 7, 1).diffMonths(date) == -108);\n        assert(Date(1990, 7, 6).diffMonths(date) == -108);\n        assert(Date(1990, 7, 11).diffMonths(date) == -108);\n        assert(Date(1990, 7, 16).diffMonths(date) == -108);\n        assert(Date(1990, 7, 21).diffMonths(date) == -108);\n        assert(Date(1990, 7, 26).diffMonths(date) == -108);\n        assert(Date(1990, 7, 31).diffMonths(date) == -108);\n        assert(Date(1990, 8, 1).diffMonths(date) == -107);\n\n        // Test B.C.\n        auto dateBC = Date(-1999, 7, 6);\n\n        assert(dateBC.diffMonths(Date(-2000, 6, 5)) == 13);\n        assert(dateBC.diffMonths(Date(-2000, 7, 5)) == 12);\n        assert(dateBC.diffMonths(Date(-2000, 8, 5)) == 11);\n        assert(dateBC.diffMonths(Date(-2000, 9, 5)) == 10);\n        assert(dateBC.diffMonths(Date(-2000, 10, 5)) == 9);\n        assert(dateBC.diffMonths(Date(-2000, 11, 5)) == 8);\n        assert(dateBC.diffMonths(Date(-2000, 12, 5)) == 7);\n        assert(dateBC.diffMonths(Date(-1999, 1, 5)) == 6);\n        assert(dateBC.diffMonths(Date(-1999, 2, 6)) == 5);\n        assert(dateBC.diffMonths(Date(-1999, 3, 6)) == 4);\n        assert(dateBC.diffMonths(Date(-1999, 4, 6)) == 3);\n        assert(dateBC.diffMonths(Date(-1999, 5, 6)) == 2);\n        assert(dateBC.diffMonths(Date(-1999, 6, 6)) == 1);\n        assert(dateBC.diffMonths(dateBC) == 0);\n        assert(dateBC.diffMonths(Date(-1999, 8, 6)) == -1);\n        assert(dateBC.diffMonths(Date(-1999, 9, 6)) == -2);\n        assert(dateBC.diffMonths(Date(-1999, 10, 6)) == -3);\n        assert(dateBC.diffMonths(Date(-1999, 11, 6)) == -4);\n        assert(dateBC.diffMonths(Date(-1999, 12, 6)) == -5);\n        assert(dateBC.diffMonths(Date(-1998, 1, 6)) == -6);\n        assert(dateBC.diffMonths(Date(-1998, 2, 6)) == -7);\n        assert(dateBC.diffMonths(Date(-1998, 3, 6)) == -8);\n        assert(dateBC.diffMonths(Date(-1998, 4, 6)) == -9);\n        assert(dateBC.diffMonths(Date(-1998, 5, 6)) == -10);\n        assert(dateBC.diffMonths(Date(-1998, 6, 6)) == -11);\n        assert(dateBC.diffMonths(Date(-1998, 7, 6)) == -12);\n        assert(dateBC.diffMonths(Date(-1998, 8, 6)) == -13);\n\n        assert(Date(-2000, 6, 5).diffMonths(dateBC) == -13);\n        assert(Date(-2000, 7, 5).diffMonths(dateBC) == -12);\n        assert(Date(-2000, 8, 5).diffMonths(dateBC) == -11);\n        assert(Date(-2000, 9, 5).diffMonths(dateBC) == -10);\n        assert(Date(-2000, 10, 5).diffMonths(dateBC) == -9);\n        assert(Date(-2000, 11, 5).diffMonths(dateBC) == -8);\n        assert(Date(-2000, 12, 5).diffMonths(dateBC) == -7);\n        assert(Date(-1999, 1, 5).diffMonths(dateBC) == -6);\n        assert(Date(-1999, 2, 6).diffMonths(dateBC) == -5);\n        assert(Date(-1999, 3, 6).diffMonths(dateBC) == -4);\n        assert(Date(-1999, 4, 6).diffMonths(dateBC) == -3);\n        assert(Date(-1999, 5, 6).diffMonths(dateBC) == -2);\n        assert(Date(-1999, 6, 6).diffMonths(dateBC) == -1);\n        assert(Date(-1999, 8, 6).diffMonths(dateBC) == 1);\n        assert(Date(-1999, 9, 6).diffMonths(dateBC) == 2);\n        assert(Date(-1999, 10, 6).diffMonths(dateBC) == 3);\n        assert(Date(-1999, 11, 6).diffMonths(dateBC) == 4);\n        assert(Date(-1999, 12, 6).diffMonths(dateBC) == 5);\n        assert(Date(-1998, 1, 6).diffMonths(dateBC) == 6);\n        assert(Date(-1998, 2, 6).diffMonths(dateBC) == 7);\n        assert(Date(-1998, 3, 6).diffMonths(dateBC) == 8);\n        assert(Date(-1998, 4, 6).diffMonths(dateBC) == 9);\n        assert(Date(-1998, 5, 6).diffMonths(dateBC) == 10);\n        assert(Date(-1998, 6, 6).diffMonths(dateBC) == 11);\n        assert(Date(-1998, 7, 6).diffMonths(dateBC) == 12);\n        assert(Date(-1998, 8, 6).diffMonths(dateBC) == 13);\n\n        assert(dateBC.diffMonths(Date(-1999, 6, 30)) == 1);\n        assert(dateBC.diffMonths(Date(-1999, 7, 1)) == 0);\n        assert(dateBC.diffMonths(Date(-1999, 7, 6)) == 0);\n        assert(dateBC.diffMonths(Date(-1999, 7, 11)) == 0);\n        assert(dateBC.diffMonths(Date(-1999, 7, 16)) == 0);\n        assert(dateBC.diffMonths(Date(-1999, 7, 21)) == 0);\n        assert(dateBC.diffMonths(Date(-1999, 7, 26)) == 0);\n        assert(dateBC.diffMonths(Date(-1999, 7, 31)) == 0);\n        assert(dateBC.diffMonths(Date(-1999, 8, 1)) == -1);\n\n        assert(dateBC.diffMonths(Date(-2008, 6, 30)) == 109);\n        assert(dateBC.diffMonths(Date(-2008, 7, 1)) == 108);\n        assert(dateBC.diffMonths(Date(-2008, 7, 6)) == 108);\n        assert(dateBC.diffMonths(Date(-2008, 7, 11)) == 108);\n        assert(dateBC.diffMonths(Date(-2008, 7, 16)) == 108);\n        assert(dateBC.diffMonths(Date(-2008, 7, 21)) == 108);\n        assert(dateBC.diffMonths(Date(-2008, 7, 26)) == 108);\n        assert(dateBC.diffMonths(Date(-2008, 7, 31)) == 108);\n        assert(dateBC.diffMonths(Date(-2008, 8, 1)) == 107);\n\n        assert(Date(-1999, 6, 30).diffMonths(dateBC) == -1);\n        assert(Date(-1999, 7, 1).diffMonths(dateBC) == 0);\n        assert(Date(-1999, 7, 6).diffMonths(dateBC) == 0);\n        assert(Date(-1999, 7, 11).diffMonths(dateBC) == 0);\n        assert(Date(-1999, 7, 16).diffMonths(dateBC) == 0);\n        assert(Date(-1999, 7, 21).diffMonths(dateBC) == 0);\n        assert(Date(-1999, 7, 26).diffMonths(dateBC) == 0);\n        assert(Date(-1999, 7, 31).diffMonths(dateBC) == 0);\n        assert(Date(-1999, 8, 1).diffMonths(dateBC) == 1);\n\n        assert(Date(-2008, 6, 30).diffMonths(dateBC) == -109);\n        assert(Date(-2008, 7, 1).diffMonths(dateBC) == -108);\n        assert(Date(-2008, 7, 6).diffMonths(dateBC) == -108);\n        assert(Date(-2008, 7, 11).diffMonths(dateBC) == -108);\n        assert(Date(-2008, 7, 16).diffMonths(dateBC) == -108);\n        assert(Date(-2008, 7, 21).diffMonths(dateBC) == -108);\n        assert(Date(-2008, 7, 26).diffMonths(dateBC) == -108);\n        assert(Date(-2008, 7, 31).diffMonths(dateBC) == -108);\n        assert(Date(-2008, 8, 1).diffMonths(dateBC) == -107);\n\n        // Test Both\n        assert(Date(3, 3, 3).diffMonths(Date(-5, 5, 5)) == 94);\n        assert(Date(-5, 5, 5).diffMonths(Date(3, 3, 3)) == -94);\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(date.diffMonths(date) == 0);\n        assert(cdate.diffMonths(date) == 0);\n        assert(idate.diffMonths(date) == 0);\n\n        assert(date.diffMonths(cdate) == 0);\n        assert(cdate.diffMonths(cdate) == 0);\n        assert(idate.diffMonths(cdate) == 0);\n\n        assert(date.diffMonths(idate) == 0);\n        assert(cdate.diffMonths(idate) == 0);\n        assert(idate.diffMonths(idate) == 0);\n    }\n\n\n    /++\n        Whether this $(LREF Date) is in a leap year.\n     +/\n    @property bool isLeapYear() const @safe pure nothrow @nogc\n    {\n        return yearIsLeapYear(_year);\n    }\n\n    @safe unittest\n    {\n        auto date = Date(1999, 7, 6);\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, date.isLeapYear = true));\n        static assert(!__traits(compiles, cdate.isLeapYear = true));\n        static assert(!__traits(compiles, idate.isLeapYear = true));\n    }\n\n\n    /++\n        Day of the week this $(LREF Date) is on.\n      +/\n    @property DayOfWeek dayOfWeek() const @safe pure nothrow @nogc\n    {\n        return getDayOfWeek(dayOfGregorianCal);\n    }\n\n    @safe unittest\n    {\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.dayOfWeek == DayOfWeek.tue);\n        static assert(!__traits(compiles, cdate.dayOfWeek = DayOfWeek.sun));\n        assert(idate.dayOfWeek == DayOfWeek.tue);\n        static assert(!__traits(compiles, idate.dayOfWeek = DayOfWeek.sun));\n    }\n\n\n    /++\n        Day of the year this $(LREF Date) is on.\n      +/\n    @property ushort dayOfYear() const @safe pure nothrow @nogc\n    {\n        if (_month >= Month.jan && _month <= Month.dec)\n        {\n            immutable int[] lastDay = isLeapYear ? lastDayLeap : lastDayNonLeap;\n            auto monthIndex = _month - Month.jan;\n\n            return cast(ushort)(lastDay[monthIndex] + _day);\n        }\n        assert(0, \"Invalid month.\");\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(1999, 1, 1).dayOfYear == 1);\n        assert(Date(1999, 12, 31).dayOfYear == 365);\n        assert(Date(2000, 12, 31).dayOfYear == 366);\n    }\n\n    @safe unittest\n    {\n        import std.algorithm.iteration : filter;\n        import std.range : chain;\n\n        foreach (year; filter!((a){return !yearIsLeapYear(a);})(chain(testYearsBC, testYearsAD)))\n        {\n            foreach (doy; testDaysOfYear)\n                assert(Date(year, doy.md.month, doy.md.day).dayOfYear == doy.day);\n        }\n\n        foreach (year; filter!((a){return yearIsLeapYear(a);})(chain(testYearsBC, testYearsAD)))\n        {\n            foreach (doy; testDaysOfLeapYear)\n                assert(Date(year, doy.md.month, doy.md.day).dayOfYear == doy.day);\n        }\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.dayOfYear == 187);\n        assert(idate.dayOfYear == 187);\n    }\n\n    /++\n        Day of the year.\n\n        Params:\n            day = The day of the year to set which day of the year this\n                  $(LREF Date) is on.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given day is an\n            invalid day of the year.\n      +/\n    @property void dayOfYear(int day) @safe pure\n    {\n        setDayOfYear!true(day);\n    }\n\n    private void setDayOfYear(bool useExceptions = false)(int day)\n    {\n        immutable int[] lastDay = isLeapYear ? lastDayLeap : lastDayNonLeap;\n\n        bool dayOutOfRange = day <= 0 || day > (isLeapYear ? daysInLeapYear : daysInYear);\n        enum errorMsg = \"Invalid day of the year.\";\n\n        static if (useExceptions)\n        {\n            if (dayOutOfRange) throw new DateTimeException(errorMsg);\n        }\n        else\n        {\n            assert(!dayOutOfRange, errorMsg);\n        }\n\n        foreach (i; 1 .. lastDay.length)\n        {\n            if (day <= lastDay[i])\n            {\n                _month = cast(Month)(cast(int) Month.jan + i - 1);\n                _day = cast(ubyte)(day - lastDay[i - 1]);\n                return;\n            }\n        }\n        assert(0, \"Invalid day of the year.\");\n    }\n\n    @safe unittest\n    {\n        static void test(Date date, int day, MonthDay expected, size_t line = __LINE__)\n        {\n            date.dayOfYear = day;\n            assert(date.month == expected.month);\n            assert(date.day == expected.day);\n        }\n\n        foreach (doy; testDaysOfYear)\n        {\n            test(Date(1999, 1, 1), doy.day, doy.md);\n            test(Date(-1, 1, 1), doy.day, doy.md);\n        }\n\n        foreach (doy; testDaysOfLeapYear)\n        {\n            test(Date(2000, 1, 1), doy.day, doy.md);\n            test(Date(-4, 1, 1), doy.day, doy.md);\n        }\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate.dayOfYear = 187));\n        static assert(!__traits(compiles, idate.dayOfYear = 187));\n    }\n\n\n    /++\n        The Xth day of the Gregorian Calendar that this $(LREF Date) is on.\n     +/\n    @property int dayOfGregorianCal() const @safe pure nothrow @nogc\n    {\n        if (isAD)\n        {\n            if (_year == 1)\n                return dayOfYear;\n\n            int years = _year - 1;\n            auto days = (years / 400) * daysIn400Years;\n            years %= 400;\n\n            days += (years / 100) * daysIn100Years;\n            years %= 100;\n\n            days += (years / 4) * daysIn4Years;\n            years %= 4;\n\n            days += years * daysInYear;\n\n            days += dayOfYear;\n\n            return days;\n        }\n        else if (_year == 0)\n            return dayOfYear - daysInLeapYear;\n        else\n        {\n            int years = _year;\n            auto days = (years / 400) * daysIn400Years;\n            years %= 400;\n\n            days += (years / 100) * daysIn100Years;\n            years %= 100;\n\n            days += (years / 4) * daysIn4Years;\n            years %= 4;\n\n            if (years < 0)\n            {\n                days -= daysInLeapYear;\n                ++years;\n\n                days += years * daysInYear;\n\n                days -= daysInYear - dayOfYear;\n            }\n            else\n                days -= daysInLeapYear - dayOfYear;\n\n            return days;\n        }\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(1, 1, 1).dayOfGregorianCal == 1);\n        assert(Date(1, 12, 31).dayOfGregorianCal == 365);\n        assert(Date(2, 1, 1).dayOfGregorianCal == 366);\n\n        assert(Date(0, 12, 31).dayOfGregorianCal == 0);\n        assert(Date(0, 1, 1).dayOfGregorianCal == -365);\n        assert(Date(-1, 12, 31).dayOfGregorianCal == -366);\n\n        assert(Date(2000, 1, 1).dayOfGregorianCal == 730_120);\n        assert(Date(2010, 12, 31).dayOfGregorianCal == 734_137);\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        foreach (gd; chain(testGregDaysBC, testGregDaysAD))\n            assert(gd.date.dayOfGregorianCal == gd.day);\n\n        auto date = Date(1999, 7, 6);\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(date.dayOfGregorianCal == 729_941);\n        assert(cdate.dayOfGregorianCal == 729_941);\n        assert(idate.dayOfGregorianCal == 729_941);\n    }\n\n    /++\n        The Xth day of the Gregorian Calendar that this $(LREF Date) is on.\n\n        Params:\n            day = The day of the Gregorian Calendar to set this $(LREF Date) to.\n     +/\n    @property void dayOfGregorianCal(int day) @safe pure nothrow @nogc\n    {\n        this = Date(day);\n    }\n\n    ///\n    @safe unittest\n    {\n        auto date = Date.init;\n        date.dayOfGregorianCal = 1;\n        assert(date == Date(1, 1, 1));\n\n        date.dayOfGregorianCal = 365;\n        assert(date == Date(1, 12, 31));\n\n        date.dayOfGregorianCal = 366;\n        assert(date == Date(2, 1, 1));\n\n        date.dayOfGregorianCal = 0;\n        assert(date == Date(0, 12, 31));\n\n        date.dayOfGregorianCal = -365;\n        assert(date == Date(-0, 1, 1));\n\n        date.dayOfGregorianCal = -366;\n        assert(date == Date(-1, 12, 31));\n\n        date.dayOfGregorianCal = 730_120;\n        assert(date == Date(2000, 1, 1));\n\n        date.dayOfGregorianCal = 734_137;\n        assert(date == Date(2010, 12, 31));\n    }\n\n    @safe unittest\n    {\n        auto date = Date(1999, 7, 6);\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        date.dayOfGregorianCal = 187;\n        assert(date.dayOfGregorianCal == 187);\n        static assert(!__traits(compiles, cdate.dayOfGregorianCal = 187));\n        static assert(!__traits(compiles, idate.dayOfGregorianCal = 187));\n    }\n\n\n    /++\n        The ISO 8601 week of the year that this $(LREF Date) is in.\n\n        See_Also:\n            $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date)\n      +/\n    @property ubyte isoWeek() const @safe pure nothrow\n    {\n        immutable weekday = dayOfWeek;\n        immutable adjustedWeekday = weekday == DayOfWeek.sun ? 7 : weekday;\n        immutable week = (dayOfYear - adjustedWeekday + 10) / 7;\n\n        try\n        {\n            if (week == 53)\n            {\n                switch (Date(_year + 1, 1, 1).dayOfWeek)\n                {\n                    case DayOfWeek.mon:\n                    case DayOfWeek.tue:\n                    case DayOfWeek.wed:\n                    case DayOfWeek.thu:\n                        return 1;\n                    case DayOfWeek.fri:\n                    case DayOfWeek.sat:\n                    case DayOfWeek.sun:\n                        return 53;\n                    default:\n                        assert(0, \"Invalid ISO Week\");\n                }\n            }\n            else if (week > 0)\n                return cast(ubyte) week;\n            else\n                return Date(_year - 1, 12, 31).isoWeek;\n        }\n        catch (Exception e)\n            assert(0, \"Date's constructor threw.\");\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(Date(2009, 12, 28).isoWeek == 53);\n        assert(Date(2009, 12, 29).isoWeek == 53);\n        assert(Date(2009, 12, 30).isoWeek == 53);\n        assert(Date(2009, 12, 31).isoWeek == 53);\n        assert(Date(2010, 1, 1).isoWeek == 53);\n        assert(Date(2010, 1, 2).isoWeek == 53);\n        assert(Date(2010, 1, 3).isoWeek == 53);\n        assert(Date(2010, 1, 4).isoWeek == 1);\n        assert(Date(2010, 1, 5).isoWeek == 1);\n        assert(Date(2010, 1, 6).isoWeek == 1);\n        assert(Date(2010, 1, 7).isoWeek == 1);\n        assert(Date(2010, 1, 8).isoWeek == 1);\n        assert(Date(2010, 1, 9).isoWeek == 1);\n        assert(Date(2010, 1, 10).isoWeek == 1);\n        assert(Date(2010, 1, 11).isoWeek == 2);\n        assert(Date(2010, 12, 31).isoWeek == 52);\n\n        assert(Date(2004, 12, 26).isoWeek == 52);\n        assert(Date(2004, 12, 27).isoWeek == 53);\n        assert(Date(2004, 12, 28).isoWeek == 53);\n        assert(Date(2004, 12, 29).isoWeek == 53);\n        assert(Date(2004, 12, 30).isoWeek == 53);\n        assert(Date(2004, 12, 31).isoWeek == 53);\n        assert(Date(2005, 1, 1).isoWeek == 53);\n        assert(Date(2005, 1, 2).isoWeek == 53);\n\n        assert(Date(2005, 12, 31).isoWeek == 52);\n        assert(Date(2007, 1, 1).isoWeek == 1);\n\n        assert(Date(2007, 12, 30).isoWeek == 52);\n        assert(Date(2007, 12, 31).isoWeek == 1);\n        assert(Date(2008, 1, 1).isoWeek == 1);\n\n        assert(Date(2008, 12, 28).isoWeek == 52);\n        assert(Date(2008, 12, 29).isoWeek == 1);\n        assert(Date(2008, 12, 30).isoWeek == 1);\n        assert(Date(2008, 12, 31).isoWeek == 1);\n        assert(Date(2009, 1, 1).isoWeek == 1);\n        assert(Date(2009, 1, 2).isoWeek == 1);\n        assert(Date(2009, 1, 3).isoWeek == 1);\n        assert(Date(2009, 1, 4).isoWeek == 1);\n\n        // Test B.C.\n        // The algorithm should work identically for both A.D. and B.C. since\n        // it doesn't really take the year into account, so B.C. testing\n        // probably isn't really needed.\n        assert(Date(0, 12, 31).isoWeek == 52);\n        assert(Date(0, 1, 4).isoWeek == 1);\n        assert(Date(0, 1, 1).isoWeek == 52);\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.isoWeek == 27);\n        static assert(!__traits(compiles, cdate.isoWeek = 3));\n        assert(idate.isoWeek == 27);\n        static assert(!__traits(compiles, idate.isoWeek = 3));\n    }\n\n\n    /++\n        $(LREF Date) for the last day in the month that this $(LREF Date) is in.\n      +/\n    @property Date endOfMonth() const @safe pure nothrow\n    {\n        try\n            return Date(_year, _month, maxDay(_year, _month));\n        catch (Exception e)\n            assert(0, \"Date's constructor threw.\");\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(1999, 1, 6).endOfMonth == Date(1999, 1, 31));\n        assert(Date(1999, 2, 7).endOfMonth == Date(1999, 2, 28));\n        assert(Date(2000, 2, 7).endOfMonth == Date(2000, 2, 29));\n        assert(Date(2000, 6, 4).endOfMonth == Date(2000, 6, 30));\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(Date(1999, 1, 1).endOfMonth == Date(1999, 1, 31));\n        assert(Date(1999, 2, 1).endOfMonth == Date(1999, 2, 28));\n        assert(Date(2000, 2, 1).endOfMonth == Date(2000, 2, 29));\n        assert(Date(1999, 3, 1).endOfMonth == Date(1999, 3, 31));\n        assert(Date(1999, 4, 1).endOfMonth == Date(1999, 4, 30));\n        assert(Date(1999, 5, 1).endOfMonth == Date(1999, 5, 31));\n        assert(Date(1999, 6, 1).endOfMonth == Date(1999, 6, 30));\n        assert(Date(1999, 7, 1).endOfMonth == Date(1999, 7, 31));\n        assert(Date(1999, 8, 1).endOfMonth == Date(1999, 8, 31));\n        assert(Date(1999, 9, 1).endOfMonth == Date(1999, 9, 30));\n        assert(Date(1999, 10, 1).endOfMonth == Date(1999, 10, 31));\n        assert(Date(1999, 11, 1).endOfMonth == Date(1999, 11, 30));\n        assert(Date(1999, 12, 1).endOfMonth == Date(1999, 12, 31));\n\n        // Test B.C.\n        assert(Date(-1999, 1, 1).endOfMonth == Date(-1999, 1, 31));\n        assert(Date(-1999, 2, 1).endOfMonth == Date(-1999, 2, 28));\n        assert(Date(-2000, 2, 1).endOfMonth == Date(-2000, 2, 29));\n        assert(Date(-1999, 3, 1).endOfMonth == Date(-1999, 3, 31));\n        assert(Date(-1999, 4, 1).endOfMonth == Date(-1999, 4, 30));\n        assert(Date(-1999, 5, 1).endOfMonth == Date(-1999, 5, 31));\n        assert(Date(-1999, 6, 1).endOfMonth == Date(-1999, 6, 30));\n        assert(Date(-1999, 7, 1).endOfMonth == Date(-1999, 7, 31));\n        assert(Date(-1999, 8, 1).endOfMonth == Date(-1999, 8, 31));\n        assert(Date(-1999, 9, 1).endOfMonth == Date(-1999, 9, 30));\n        assert(Date(-1999, 10, 1).endOfMonth == Date(-1999, 10, 31));\n        assert(Date(-1999, 11, 1).endOfMonth == Date(-1999, 11, 30));\n        assert(Date(-1999, 12, 1).endOfMonth == Date(-1999, 12, 31));\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate.endOfMonth = Date(1999, 7, 30)));\n        static assert(!__traits(compiles, idate.endOfMonth = Date(1999, 7, 30)));\n    }\n\n\n    /++\n        The last day in the month that this $(LREF Date) is in.\n      +/\n    @property ubyte daysInMonth() const @safe pure nothrow @nogc\n    {\n        return maxDay(_year, _month);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(1999, 1, 6).daysInMonth == 31);\n        assert(Date(1999, 2, 7).daysInMonth == 28);\n        assert(Date(2000, 2, 7).daysInMonth == 29);\n        assert(Date(2000, 6, 4).daysInMonth == 30);\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(Date(1999, 1, 1).daysInMonth == 31);\n        assert(Date(1999, 2, 1).daysInMonth == 28);\n        assert(Date(2000, 2, 1).daysInMonth == 29);\n        assert(Date(1999, 3, 1).daysInMonth == 31);\n        assert(Date(1999, 4, 1).daysInMonth == 30);\n        assert(Date(1999, 5, 1).daysInMonth == 31);\n        assert(Date(1999, 6, 1).daysInMonth == 30);\n        assert(Date(1999, 7, 1).daysInMonth == 31);\n        assert(Date(1999, 8, 1).daysInMonth == 31);\n        assert(Date(1999, 9, 1).daysInMonth == 30);\n        assert(Date(1999, 10, 1).daysInMonth == 31);\n        assert(Date(1999, 11, 1).daysInMonth == 30);\n        assert(Date(1999, 12, 1).daysInMonth == 31);\n\n        // Test B.C.\n        assert(Date(-1999, 1, 1).daysInMonth == 31);\n        assert(Date(-1999, 2, 1).daysInMonth == 28);\n        assert(Date(-2000, 2, 1).daysInMonth == 29);\n        assert(Date(-1999, 3, 1).daysInMonth == 31);\n        assert(Date(-1999, 4, 1).daysInMonth == 30);\n        assert(Date(-1999, 5, 1).daysInMonth == 31);\n        assert(Date(-1999, 6, 1).daysInMonth == 30);\n        assert(Date(-1999, 7, 1).daysInMonth == 31);\n        assert(Date(-1999, 8, 1).daysInMonth == 31);\n        assert(Date(-1999, 9, 1).daysInMonth == 30);\n        assert(Date(-1999, 10, 1).daysInMonth == 31);\n        assert(Date(-1999, 11, 1).daysInMonth == 30);\n        assert(Date(-1999, 12, 1).daysInMonth == 31);\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate.daysInMonth = 30));\n        static assert(!__traits(compiles, idate.daysInMonth = 30));\n    }\n\n\n    /++\n        Whether the current year is a date in A.D.\n      +/\n    @property bool isAD() const @safe pure nothrow @nogc\n    {\n        return _year > 0;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(1, 1, 1).isAD);\n        assert(Date(2010, 12, 31).isAD);\n        assert(!Date(0, 12, 31).isAD);\n        assert(!Date(-2010, 1, 1).isAD);\n    }\n\n    @safe unittest\n    {\n        assert(Date(2010, 7, 4).isAD);\n        assert(Date(1, 1, 1).isAD);\n        assert(!Date(0, 1, 1).isAD);\n        assert(!Date(-1, 1, 1).isAD);\n        assert(!Date(-2010, 7, 4).isAD);\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.isAD);\n        assert(idate.isAD);\n    }\n\n\n    /++\n        The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for this\n        $(LREF Date) at noon (since the Julian day changes at noon).\n      +/\n    @property long julianDay() const @safe pure nothrow @nogc\n    {\n        return dayOfGregorianCal + 1_721_425;\n    }\n\n    @safe unittest\n    {\n        assert(Date(-4713, 11, 24).julianDay == 0);\n        assert(Date(0, 12, 31).julianDay == 1_721_425);\n        assert(Date(1, 1, 1).julianDay == 1_721_426);\n        assert(Date(1582, 10, 15).julianDay == 2_299_161);\n        assert(Date(1858, 11, 17).julianDay == 2_400_001);\n        assert(Date(1982, 1, 4).julianDay == 2_444_974);\n        assert(Date(1996, 3, 31).julianDay == 2_450_174);\n        assert(Date(2010, 8, 24).julianDay == 2_455_433);\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.julianDay == 2_451_366);\n        assert(idate.julianDay == 2_451_366);\n    }\n\n\n    /++\n        The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for\n        any time on this date (since, the modified Julian day changes at\n        midnight).\n      +/\n    @property long modJulianDay() const @safe pure nothrow @nogc\n    {\n        return julianDay - 2_400_001;\n    }\n\n    @safe unittest\n    {\n        assert(Date(1858, 11, 17).modJulianDay == 0);\n        assert(Date(2010, 8, 24).modJulianDay == 55_432);\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.modJulianDay == 51_365);\n        assert(idate.modJulianDay == 51_365);\n    }\n\n\n    /++\n        Converts this $(LREF Date) to a string with the format `YYYYMMDD`.\n        If `writer` is set, the resulting string will be written directly\n        to it.\n\n        Params:\n            writer = A `char` accepting $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toISOString() const @safe pure nothrow\n    {\n        import std.array : appender;\n        auto w = appender!string();\n        w.reserve(8);\n        try\n            toISOString(w);\n        catch (Exception e)\n            assert(0, \"toISOString() threw.\");\n        return w.data;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(2010, 7, 4).toISOString() == \"20100704\");\n        assert(Date(1998, 12, 25).toISOString() == \"19981225\");\n        assert(Date(0, 1, 5).toISOString() == \"00000105\");\n        assert(Date(-4, 1, 5).toISOString() == \"-00040105\");\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(Date(9, 12, 4).toISOString() == \"00091204\");\n        assert(Date(99, 12, 4).toISOString() == \"00991204\");\n        assert(Date(999, 12, 4).toISOString() == \"09991204\");\n        assert(Date(9999, 7, 4).toISOString() == \"99990704\");\n        assert(Date(10000, 10, 20).toISOString() == \"+100001020\");\n\n        // Test B.C.\n        assert(Date(0, 12, 4).toISOString() == \"00001204\");\n        assert(Date(-9, 12, 4).toISOString() == \"-00091204\");\n        assert(Date(-99, 12, 4).toISOString() == \"-00991204\");\n        assert(Date(-999, 12, 4).toISOString() == \"-09991204\");\n        assert(Date(-9999, 7, 4).toISOString() == \"-99990704\");\n        assert(Date(-10000, 10, 20).toISOString() == \"-100001020\");\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.toISOString() == \"19990706\");\n        assert(idate.toISOString() == \"19990706\");\n    }\n\n    /// ditto\n    void toISOString(W)(ref W writer) const\n    if (isOutputRange!(W, char))\n    {\n        import std.format : formattedWrite;\n        if (_year >= 0)\n        {\n            if (_year < 10_000)\n                formattedWrite(writer, \"%04d%02d%02d\", _year, _month, _day);\n            else\n                formattedWrite(writer, \"+%05d%02d%02d\", _year, _month, _day);\n        }\n        else if (_year > -10_000)\n            formattedWrite(writer, \"%05d%02d%02d\", _year, _month, _day);\n        else\n            formattedWrite(writer, \"%06d%02d%02d\", _year, _month, _day);\n    }\n\n    @safe pure unittest\n    {\n        import std.array : appender;\n\n        auto w = appender!(char[])();\n        Date(2010, 7, 4).toISOString(w);\n        assert(w.data == \"20100704\");\n        w.clear();\n        Date(1998, 12, 25).toISOString(w);\n        assert(w.data == \"19981225\");\n    }\n\n    /++\n        Converts this $(LREF Date) to a string with the format `YYYY-MM-DD`.\n        If `writer` is set, the resulting string will be written directly\n        to it.\n\n        Params:\n            writer = A `char` accepting $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toISOExtString() const @safe pure nothrow\n    {\n        import std.array : appender;\n        auto w = appender!string();\n        w.reserve(10);\n        try\n            toISOExtString(w);\n        catch (Exception e)\n            assert(0, \"toISOExtString() threw.\");\n        return w.data;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(2010, 7, 4).toISOExtString() == \"2010-07-04\");\n        assert(Date(1998, 12, 25).toISOExtString() == \"1998-12-25\");\n        assert(Date(0, 1, 5).toISOExtString() == \"0000-01-05\");\n        assert(Date(-4, 1, 5).toISOExtString() == \"-0004-01-05\");\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(Date(9, 12, 4).toISOExtString() == \"0009-12-04\");\n        assert(Date(99, 12, 4).toISOExtString() == \"0099-12-04\");\n        assert(Date(999, 12, 4).toISOExtString() == \"0999-12-04\");\n        assert(Date(9999, 7, 4).toISOExtString() == \"9999-07-04\");\n        assert(Date(10000, 10, 20).toISOExtString() == \"+10000-10-20\");\n\n        // Test B.C.\n        assert(Date(0, 12, 4).toISOExtString() == \"0000-12-04\");\n        assert(Date(-9, 12, 4).toISOExtString() == \"-0009-12-04\");\n        assert(Date(-99, 12, 4).toISOExtString() == \"-0099-12-04\");\n        assert(Date(-999, 12, 4).toISOExtString() == \"-0999-12-04\");\n        assert(Date(-9999, 7, 4).toISOExtString() == \"-9999-07-04\");\n        assert(Date(-10000, 10, 20).toISOExtString() == \"-10000-10-20\");\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.toISOExtString() == \"1999-07-06\");\n        assert(idate.toISOExtString() == \"1999-07-06\");\n    }\n\n    /// ditto\n    void toISOExtString(W)(ref W writer) const\n    if (isOutputRange!(W, char))\n    {\n        import std.format : formattedWrite;\n        if (_year >= 0)\n        {\n            if (_year < 10_000)\n                formattedWrite(writer, \"%04d-%02d-%02d\", _year, _month, _day);\n            else\n                formattedWrite(writer, \"+%05d-%02d-%02d\", _year, _month, _day);\n        }\n        else if (_year > -10_000)\n            formattedWrite(writer, \"%05d-%02d-%02d\", _year, _month, _day);\n        else\n            formattedWrite(writer, \"%06d-%02d-%02d\", _year, _month, _day);\n    }\n\n    @safe pure unittest\n    {\n        import std.array : appender;\n\n        auto w = appender!(char[])();\n        Date(2010, 7, 4).toISOExtString(w);\n        assert(w.data == \"2010-07-04\");\n        w.clear();\n        Date(-4, 1, 5).toISOExtString(w);\n        assert(w.data == \"-0004-01-05\");\n    }\n\n    /++\n        Converts this $(LREF Date) to a string with the format `YYYY-Mon-DD`.\n        If `writer` is set, the resulting string will be written directly\n        to it.\n\n        Params:\n            writer = A `char` accepting $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toSimpleString() const @safe pure nothrow\n    {\n        import std.array : appender;\n        auto w = appender!string();\n        w.reserve(11);\n        try\n            toSimpleString(w);\n        catch (Exception e)\n            assert(0, \"toSimpleString() threw.\");\n        return w.data;\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date(2010, 7, 4).toSimpleString() == \"2010-Jul-04\");\n        assert(Date(1998, 12, 25).toSimpleString() == \"1998-Dec-25\");\n        assert(Date(0, 1, 5).toSimpleString() == \"0000-Jan-05\");\n        assert(Date(-4, 1, 5).toSimpleString() == \"-0004-Jan-05\");\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        assert(Date(9, 12, 4).toSimpleString() == \"0009-Dec-04\");\n        assert(Date(99, 12, 4).toSimpleString() == \"0099-Dec-04\");\n        assert(Date(999, 12, 4).toSimpleString() == \"0999-Dec-04\");\n        assert(Date(9999, 7, 4).toSimpleString() == \"9999-Jul-04\");\n        assert(Date(10000, 10, 20).toSimpleString() == \"+10000-Oct-20\");\n\n        // Test B.C.\n        assert(Date(0, 12, 4).toSimpleString() == \"0000-Dec-04\");\n        assert(Date(-9, 12, 4).toSimpleString() == \"-0009-Dec-04\");\n        assert(Date(-99, 12, 4).toSimpleString() == \"-0099-Dec-04\");\n        assert(Date(-999, 12, 4).toSimpleString() == \"-0999-Dec-04\");\n        assert(Date(-9999, 7, 4).toSimpleString() == \"-9999-Jul-04\");\n        assert(Date(-10000, 10, 20).toSimpleString() == \"-10000-Oct-20\");\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(cdate.toSimpleString() == \"1999-Jul-06\");\n        assert(idate.toSimpleString() == \"1999-Jul-06\");\n    }\n\n    /// ditto\n    void toSimpleString(W)(ref W writer) const\n    if (isOutputRange!(W, char))\n    {\n        import std.format : formattedWrite;\n        if (_year >= 0)\n        {\n            if (_year < 10_000)\n                formattedWrite(writer, \"%04d-%s-%02d\", _year, monthToString(_month), _day);\n            else\n                formattedWrite(writer, \"+%05d-%s-%02d\", _year, monthToString(_month), _day);\n        }\n        else if (_year > -10_000)\n            formattedWrite(writer, \"%05d-%s-%02d\", _year, monthToString(_month), _day);\n        else\n            formattedWrite(writer, \"%06d-%s-%02d\", _year, monthToString(_month), _day);\n    }\n\n    @safe pure unittest\n    {\n        import std.array : appender;\n\n        auto w = appender!(char[])();\n        Date(9, 12, 4).toSimpleString(w);\n        assert(w.data == \"0009-Dec-04\");\n        w.clear();\n        Date(-10000, 10, 20).toSimpleString(w);\n        assert(w.data == \"-10000-Oct-20\");\n    }\n\n    /++\n        Converts this $(LREF Date) to a string.\n\n        This function exists to make it easy to convert a $(LREF Date) to a\n        string for code that does not care what the exact format is - just that\n        it presents the information in a clear manner. It also makes it easy to\n        simply convert a $(LREF Date) to a string when using functions such as\n        `to!string`, `format`, or `writeln` which use toString to convert\n        user-defined types. So, it is unlikely that much code will call\n        toString directly.\n\n        The format of the string is purposefully unspecified, and code that\n        cares about the format of the string should use `toISOString`,\n        `toISOExtString`, `toSimpleString`, or some other custom formatting\n        function that explicitly generates the format that the code needs. The\n        reason is that the code is then clear about what format it's using,\n        making it less error-prone to maintain the code and interact with other\n        software that consumes the generated strings. It's for this same reason\n        $(LREF Date) has no `fromString` function, whereas it does have\n        `fromISOString`, `fromISOExtString`, and `fromSimpleString`.\n\n        The format returned by toString may or may not change in the future.\n      +/\n    string toString() const @safe pure nothrow\n    {\n        return toSimpleString();\n    }\n\n    @safe unittest\n    {\n        auto date = Date(1999, 7, 6);\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        assert(date.toString());\n        assert(cdate.toString());\n        assert(idate.toString());\n    }\n\n    /// ditto\n    void toString(W)(ref W writer) const\n    if (isOutputRange!(W, char))\n    {\n        toSimpleString(writer);\n    }\n\n    /++\n        Creates a $(LREF Date) from a string with the format YYYYMMDD. Whitespace\n        is stripped from the given string.\n\n        Params:\n            isoString = A string formatted in the ISO format for dates.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given string is\n            not in the ISO format or if the resulting $(LREF Date) would not be\n            valid.\n      +/\n    static Date fromISOString(S)(scope const S isoString) @safe pure\n        if (isSomeString!S)\n    {\n        import std.algorithm.searching : startsWith;\n        import std.conv : to, text, ConvException;\n        import std.exception : enforce;\n        import std.string : strip;\n\n        auto str = isoString.strip;\n\n        enforce!DateTimeException(str.length >= 8, text(\"Invalid ISO String: \", isoString));\n\n        int day, month, year;\n        auto yearStr = str[0 .. $ - 4];\n\n        try\n        {\n            // using conversion to uint plus cast because it checks for +/-\n            // for us quickly while throwing ConvException\n            day = cast(int) to!uint(str[$ - 2 .. $]);\n            month = cast(int) to!uint(str[$ - 4 .. $ - 2]);\n\n            if (yearStr.length > 4)\n            {\n                enforce!DateTimeException(yearStr.startsWith('-', '+'),\n                        text(\"Invalid ISO String: \", isoString));\n                year = to!int(yearStr);\n            }\n            else\n            {\n                year = cast(int) to!uint(yearStr);\n            }\n        }\n        catch (ConvException)\n        {\n            throw new DateTimeException(text(\"Invalid ISO String: \", isoString));\n        }\n\n        return Date(year, month, day);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date.fromISOString(\"20100704\") == Date(2010, 7, 4));\n        assert(Date.fromISOString(\"19981225\") == Date(1998, 12, 25));\n        assert(Date.fromISOString(\"00000105\") == Date(0, 1, 5));\n        assert(Date.fromISOString(\"-00040105\") == Date(-4, 1, 5));\n        assert(Date.fromISOString(\" 20100704 \") == Date(2010, 7, 4));\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException(Date.fromISOString(\"\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"990704\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"0100704\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010070\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010070 \"));\n        assertThrown!DateTimeException(Date.fromISOString(\"120100704\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"-0100704\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"+0100704\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010070a\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"20100a04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010a704\"));\n\n        assertThrown!DateTimeException(Date.fromISOString(\"99-07-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"010-07-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-07-0\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-07-0 \"));\n        assertThrown!DateTimeException(Date.fromISOString(\"12010-07-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"-010-07-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"+010-07-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-07-0a\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-0a-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-a7-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010/07/04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010/7/04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010/7/4\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010/07/4\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-7-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-7-4\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-07-4\"));\n\n        assertThrown!DateTimeException(Date.fromISOString(\"99Jul04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"010Jul04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010Jul0\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010Jul0 \"));\n        assertThrown!DateTimeException(Date.fromISOString(\"12010Jul04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"-010Jul04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"+010Jul04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010Jul0a\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010Jua04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010aul04\"));\n\n        assertThrown!DateTimeException(Date.fromISOString(\"99-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-Jul-0\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-Jul-0 \"));\n        assertThrown!DateTimeException(Date.fromISOString(\"12010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"-010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"+010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-Jul-0a\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-Jua-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-Jal-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-aul-04\"));\n\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-07-04\"));\n        assertThrown!DateTimeException(Date.fromISOString(\"2010-Jul-04\"));\n\n        assert(Date.fromISOString(\"19990706\") == Date(1999, 7, 6));\n        assert(Date.fromISOString(\"-19990706\") == Date(-1999, 7, 6));\n        assert(Date.fromISOString(\"+019990706\") == Date(1999, 7, 6));\n        assert(Date.fromISOString(\"19990706 \") == Date(1999, 7, 6));\n        assert(Date.fromISOString(\" 19990706\") == Date(1999, 7, 6));\n        assert(Date.fromISOString(\" 19990706 \") == Date(1999, 7, 6));\n    }\n\n    // bug# 17801\n    @safe unittest\n    {\n        import std.conv : to;\n        import std.meta : AliasSeq;\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))\n                assert(Date.fromISOString(to!S(\"20121221\")) == Date(2012, 12, 21));\n        }\n    }\n\n\n    /++\n        Creates a $(LREF Date) from a string with the format YYYY-MM-DD.\n        Whitespace is stripped from the given string.\n\n        Params:\n            isoExtString = A string formatted in the ISO Extended format for\n                           dates.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given string is\n            not in the ISO Extended format or if the resulting $(LREF Date)\n            would not be valid.\n      +/\n    static Date fromISOExtString(S)(scope const S isoExtString) @safe pure\n        if (isSomeString!(S))\n    {\n        import std.algorithm.searching : startsWith;\n        import std.conv : to, ConvException;\n        import std.format : format;\n        import std.string : strip;\n\n        auto str = strip(isoExtString);\n        short year;\n        ubyte month, day;\n\n        if (str.length < 10 || str[$-3] != '-' || str[$-6] != '-')\n            throw new DateTimeException(format(\"Invalid ISO Extended String: %s\", isoExtString));\n\n        auto yearStr = str[0 .. $-6];\n        auto signAtBegining = cast(bool) yearStr.startsWith('-', '+');\n        if ((yearStr.length > 4) != signAtBegining)\n        {\n            throw new DateTimeException(format(\"Invalid ISO Extended String: %s\", isoExtString));\n        }\n\n        try\n        {\n            day = to!ubyte(str[$-2 .. $]);\n            month = to!ubyte(str[$-5 .. $-3]);\n            year = to!short(yearStr);\n        }\n        catch (ConvException)\n        {\n            throw new DateTimeException(format(\"Invalid ISO Extended String: %s\", isoExtString));\n        }\n\n        return Date(year, month, day);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date.fromISOExtString(\"2010-07-04\") == Date(2010, 7, 4));\n        assert(Date.fromISOExtString(\"1998-12-25\") == Date(1998, 12, 25));\n        assert(Date.fromISOExtString(\"0000-01-05\") == Date(0, 1, 5));\n        assert(Date.fromISOExtString(\"-0004-01-05\") == Date(-4, 1, 5));\n        assert(Date.fromISOExtString(\" 2010-07-04 \") == Date(2010, 7, 4));\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException(Date.fromISOExtString(\"\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"990704\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"0100704\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010070\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010070 \"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"120100704\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"-0100704\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"+0100704\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010070a\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"20100a04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010a704\"));\n\n        assertThrown!DateTimeException(Date.fromISOExtString(\"99-07-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"010-07-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-07-0\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-07-0 \"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"12010-07-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"-010-07-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"+010-07-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-07-0a\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-0a-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-a7-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010/07/04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010/7/04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010/7/4\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010/07/4\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-7-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-7-4\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-07-4\"));\n\n        assertThrown!DateTimeException(Date.fromISOExtString(\"99Jul04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"010Jul04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010Jul0\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-Jul-0 \"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"12010Jul04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"-010Jul04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"+010Jul04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010Jul0a\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010Jua04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010aul04\"));\n\n        assertThrown!DateTimeException(Date.fromISOExtString(\"99-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-Jul-0\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010Jul0 \"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"12010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"-010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"+010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-Jul-0a\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-Jua-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-Jal-04\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-aul-04\"));\n\n        assertThrown!DateTimeException(Date.fromISOExtString(\"20100704\"));\n        assertThrown!DateTimeException(Date.fromISOExtString(\"2010-Jul-04\"));\n\n        assert(Date.fromISOExtString(\"1999-07-06\") == Date(1999, 7, 6));\n        assert(Date.fromISOExtString(\"-1999-07-06\") == Date(-1999, 7, 6));\n        assert(Date.fromISOExtString(\"+01999-07-06\") == Date(1999, 7, 6));\n        assert(Date.fromISOExtString(\"1999-07-06 \") == Date(1999, 7, 6));\n        assert(Date.fromISOExtString(\" 1999-07-06\") == Date(1999, 7, 6));\n        assert(Date.fromISOExtString(\" 1999-07-06 \") == Date(1999, 7, 6));\n    }\n\n    // bug# 17801\n    @safe unittest\n    {\n        import std.conv : to;\n        import std.meta : AliasSeq;\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))\n                assert(Date.fromISOExtString(to!S(\"2012-12-21\")) == Date(2012, 12, 21));\n        }\n    }\n\n\n    /++\n        Creates a $(LREF Date) from a string with the format YYYY-Mon-DD.\n        Whitespace is stripped from the given string.\n\n        Params:\n            simpleString = A string formatted in the way that toSimpleString\n                           formats dates.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given string is\n            not in the correct format or if the resulting $(LREF Date) would not\n            be valid.\n      +/\n    static Date fromSimpleString(S)(scope const S simpleString) @safe pure\n        if (isSomeString!(S))\n    {\n        import std.algorithm.searching : startsWith;\n        import std.conv : to, ConvException;\n        import std.format : format;\n        import std.string : strip;\n\n        auto str = strip(simpleString);\n\n        if (str.length < 11 || str[$-3] != '-' || str[$-7] != '-')\n            throw new DateTimeException(format!\"Invalid string format: %s\"(simpleString));\n\n        int year;\n        uint day;\n        auto month = monthFromString(str[$ - 6 .. $ - 3]);\n        auto yearStr = str[0 .. $ - 7];\n        auto signAtBegining = cast(bool) yearStr.startsWith('-', '+');\n        if ((yearStr.length > 4) != signAtBegining)\n        {\n            throw new DateTimeException(format!\"Invalid string format: %s\"(simpleString));\n        }\n\n        try\n        {\n            day = to!uint(str[$ - 2 .. $]);\n            year = to!int(yearStr);\n        }\n        catch (ConvException)\n        {\n            throw new DateTimeException(format!\"Invalid string format: %s\"(simpleString));\n        }\n\n        return Date(year, month, day);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(Date.fromSimpleString(\"2010-Jul-04\") == Date(2010, 7, 4));\n        assert(Date.fromSimpleString(\"1998-Dec-25\") == Date(1998, 12, 25));\n        assert(Date.fromSimpleString(\"0000-Jan-05\") == Date(0, 1, 5));\n        assert(Date.fromSimpleString(\"-0004-Jan-05\") == Date(-4, 1, 5));\n        assert(Date.fromSimpleString(\" 2010-Jul-04 \") == Date(2010, 7, 4));\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException(Date.fromSimpleString(\"\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"990704\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"0100704\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010070\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010070 \"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"120100704\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"-0100704\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"+0100704\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010070a\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"20100a04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010a704\"));\n\n        assertThrown!DateTimeException(Date.fromSimpleString(\"99-07-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"010-07-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-07-0\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-07-0 \"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"12010-07-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"-010-07-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"+010-07-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-07-0a\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-0a-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-a7-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010/07/04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010/7/04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010/7/4\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010/07/4\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-7-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-7-4\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-07-4\"));\n\n        assertThrown!DateTimeException(Date.fromSimpleString(\"99Jul04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"010Jul04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010Jul0\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010Jul0 \"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"12010Jul04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"-010Jul04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"+010Jul04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010Jul0a\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010Jua04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010aul04\"));\n\n        assertThrown!DateTimeException(Date.fromSimpleString(\"99-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-Jul-0\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-Jul-0 \"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"12010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"-010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"+010-Jul-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-Jul-0a\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-Jua-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-Jal-04\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-aul-04\"));\n\n        assertThrown!DateTimeException(Date.fromSimpleString(\"20100704\"));\n        assertThrown!DateTimeException(Date.fromSimpleString(\"2010-07-04\"));\n\n        assert(Date.fromSimpleString(\"1999-Jul-06\") == Date(1999, 7, 6));\n        assert(Date.fromSimpleString(\"-1999-Jul-06\") == Date(-1999, 7, 6));\n        assert(Date.fromSimpleString(\"+01999-Jul-06\") == Date(1999, 7, 6));\n        assert(Date.fromSimpleString(\"1999-Jul-06 \") == Date(1999, 7, 6));\n        assert(Date.fromSimpleString(\" 1999-Jul-06\") == Date(1999, 7, 6));\n        assert(Date.fromSimpleString(\" 1999-Jul-06 \") == Date(1999, 7, 6));\n    }\n\n    // bug# 17801\n    @safe unittest\n    {\n        import std.conv : to;\n        import std.meta : AliasSeq;\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))\n                assert(Date.fromSimpleString(to!S(\"2012-Dec-21\")) == Date(2012, 12, 21));\n        }\n    }\n\n\n    /++\n        Returns the $(LREF Date) farthest in the past which is representable by\n        $(LREF Date).\n      +/\n    @property static Date min() @safe pure nothrow @nogc\n    {\n        auto date = Date.init;\n        date._year = short.min;\n        date._month = Month.jan;\n        date._day = 1;\n\n        return date;\n    }\n\n    @safe unittest\n    {\n        assert(Date.min.year < 0);\n        assert(Date.min < Date.max);\n    }\n\n\n    /++\n        Returns the $(LREF Date) farthest in the future which is representable\n        by $(LREF Date).\n      +/\n    @property static Date max() @safe pure nothrow @nogc\n    {\n        auto date = Date.init;\n        date._year = short.max;\n        date._month = Month.dec;\n        date._day = 31;\n\n        return date;\n    }\n\n    @safe unittest\n    {\n        assert(Date.max.year > 0);\n        assert(Date.max > Date.min);\n    }\n\n\nprivate:\n\n    /+\n        Whether the given values form a valid date.\n\n        Params:\n            year  = The year to test.\n            month = The month of the Gregorian Calendar to test.\n            day   = The day of the month to test.\n     +/\n    static bool _valid(int year, int month, int day) @safe pure nothrow @nogc\n    {\n        if (!valid!\"months\"(month))\n            return false;\n        return valid!\"days\"(year, month, day);\n    }\n\n\npackage:\n\n    /+\n        Adds the given number of days to this $(LREF Date). A negative number\n        will subtract.\n\n        The month will be adjusted along with the day if the number of days\n        added (or subtracted) would overflow (or underflow) the current month.\n        The year will be adjusted along with the month if the increase (or\n        decrease) to the month would cause it to overflow (or underflow) the\n        current year.\n\n        `_addDays(numDays)` is effectively equivalent to\n        $(D date.dayOfGregorianCal = date.dayOfGregorianCal + days).\n\n        Params:\n            days = The number of days to add to this Date.\n      +/\n    ref Date _addDays(long days) return @safe pure nothrow @nogc\n    {\n        dayOfGregorianCal = cast(int)(dayOfGregorianCal + days);\n        return this;\n    }\n\n    @safe unittest\n    {\n        // Test A.D.\n        {\n            auto date = Date(1999, 2, 28);\n            date._addDays(1);\n            assert(date == Date(1999, 3, 1));\n            date._addDays(-1);\n            assert(date == Date(1999, 2, 28));\n        }\n\n        {\n            auto date = Date(2000, 2, 28);\n            date._addDays(1);\n            assert(date == Date(2000, 2, 29));\n            date._addDays(1);\n            assert(date == Date(2000, 3, 1));\n            date._addDays(-1);\n            assert(date == Date(2000, 2, 29));\n        }\n\n        {\n            auto date = Date(1999, 6, 30);\n            date._addDays(1);\n            assert(date == Date(1999, 7, 1));\n            date._addDays(-1);\n            assert(date == Date(1999, 6, 30));\n        }\n\n        {\n            auto date = Date(1999, 7, 31);\n            date._addDays(1);\n            assert(date == Date(1999, 8, 1));\n            date._addDays(-1);\n            assert(date == Date(1999, 7, 31));\n        }\n\n        {\n            auto date = Date(1999, 1, 1);\n            date._addDays(-1);\n            assert(date == Date(1998, 12, 31));\n            date._addDays(1);\n            assert(date == Date(1999, 1, 1));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date._addDays(9);\n            assert(date == Date(1999, 7, 15));\n            date._addDays(-11);\n            assert(date == Date(1999, 7, 4));\n            date._addDays(30);\n            assert(date == Date(1999, 8, 3));\n            date._addDays(-3);\n            assert(date == Date(1999, 7, 31));\n        }\n\n        {\n            auto date = Date(1999, 7, 6);\n            date._addDays(365);\n            assert(date == Date(2000, 7, 5));\n            date._addDays(-365);\n            assert(date == Date(1999, 7, 6));\n            date._addDays(366);\n            assert(date == Date(2000, 7, 6));\n            date._addDays(730);\n            assert(date == Date(2002, 7, 6));\n            date._addDays(-1096);\n            assert(date == Date(1999, 7, 6));\n        }\n\n        // Test B.C.\n        {\n            auto date = Date(-1999, 2, 28);\n            date._addDays(1);\n            assert(date == Date(-1999, 3, 1));\n            date._addDays(-1);\n            assert(date == Date(-1999, 2, 28));\n        }\n\n        {\n            auto date = Date(-2000, 2, 28);\n            date._addDays(1);\n            assert(date == Date(-2000, 2, 29));\n            date._addDays(1);\n            assert(date == Date(-2000, 3, 1));\n            date._addDays(-1);\n            assert(date == Date(-2000, 2, 29));\n        }\n\n        {\n            auto date = Date(-1999, 6, 30);\n            date._addDays(1);\n            assert(date == Date(-1999, 7, 1));\n            date._addDays(-1);\n            assert(date == Date(-1999, 6, 30));\n        }\n\n        {\n            auto date = Date(-1999, 7, 31);\n            date._addDays(1);\n            assert(date == Date(-1999, 8, 1));\n            date._addDays(-1);\n            assert(date == Date(-1999, 7, 31));\n        }\n\n        {\n            auto date = Date(-1999, 1, 1);\n            date._addDays(-1);\n            assert(date == Date(-2000, 12, 31));\n            date._addDays(1);\n            assert(date == Date(-1999, 1, 1));\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date._addDays(9);\n            assert(date == Date(-1999, 7, 15));\n            date._addDays(-11);\n            assert(date == Date(-1999, 7, 4));\n            date._addDays(30);\n            assert(date == Date(-1999, 8, 3));\n            date._addDays(-3);\n        }\n\n        {\n            auto date = Date(-1999, 7, 6);\n            date._addDays(365);\n            assert(date == Date(-1998, 7, 6));\n            date._addDays(-365);\n            assert(date == Date(-1999, 7, 6));\n            date._addDays(366);\n            assert(date == Date(-1998, 7, 7));\n            date._addDays(730);\n            assert(date == Date(-1996, 7, 6));\n            date._addDays(-1096);\n            assert(date == Date(-1999, 7, 6));\n        }\n\n        // Test Both\n        {\n            auto date = Date(1, 7, 6);\n            date._addDays(-365);\n            assert(date == Date(0, 7, 6));\n            date._addDays(365);\n            assert(date == Date(1, 7, 6));\n            date._addDays(-731);\n            assert(date == Date(-1, 7, 6));\n            date._addDays(730);\n            assert(date == Date(1, 7, 5));\n        }\n\n        const cdate = Date(1999, 7, 6);\n        immutable idate = Date(1999, 7, 6);\n        static assert(!__traits(compiles, cdate._addDays(12)));\n        static assert(!__traits(compiles, idate._addDays(12)));\n    }\n\n\n    @safe pure invariant()\n    {\n        import std.format : format;\n        assert(valid!\"months\"(_month),\n               format(\"Invariant Failure: year [%s] month [%s] day [%s]\", _year, _month, _day));\n        assert(valid!\"days\"(_year, _month, _day),\n               format(\"Invariant Failure: year [%s] month [%s] day [%s]\", _year, _month, _day));\n    }\n\n    short _year  = 1;\n    Month _month = Month.jan;\n    ubyte _day   = 1;\n}\n\n///\n@safe pure unittest\n{\n    import core.time : days;\n\n    auto d = Date(2000, 6, 1);\n\n    assert(d.dayOfYear == 153);\n    assert(d.dayOfWeek == DayOfWeek.thu);\n\n    d += 10.days;\n    assert(d == Date(2000, 6, 11));\n\n    assert(d.toISOExtString() == \"2000-06-11\");\n    assert(d.toISOString() == \"20000611\");\n    assert(d.toSimpleString() == \"2000-Jun-11\");\n\n    assert(Date.fromISOExtString(\"2018-01-01\") == Date(2018, 1, 1));\n    assert(Date.fromISOString(\"20180101\") == Date(2018, 1, 1));\n    assert(Date.fromSimpleString(\"2018-Jan-01\") == Date(2018, 1, 1));\n}\n\n\n/++\n    Represents a time of day with hours, minutes, and seconds. It uses 24 hour\n    time.\n+/\nstruct TimeOfDay\n{\npublic:\n\n    /++\n        Params:\n            hour   = Hour of the day [0 - 24$(RPAREN).\n            minute = Minute of the hour [0 - 60$(RPAREN).\n            second = Second of the minute [0 - 60$(RPAREN).\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the resulting\n            $(LREF TimeOfDay) would be not be valid.\n     +/\n    this(int hour, int minute, int second = 0) @safe pure\n    {\n        enforceValid!\"hours\"(hour);\n        enforceValid!\"minutes\"(minute);\n        enforceValid!\"seconds\"(second);\n\n        _hour   = cast(ubyte) hour;\n        _minute = cast(ubyte) minute;\n        _second = cast(ubyte) second;\n    }\n\n    @safe unittest\n    {\n        assert(TimeOfDay(0, 0) == TimeOfDay.init);\n\n        {\n            auto tod = TimeOfDay(0, 0);\n            assert(tod._hour == 0);\n            assert(tod._minute == 0);\n            assert(tod._second == 0);\n        }\n\n        {\n            auto tod = TimeOfDay(12, 30, 33);\n            assert(tod._hour == 12);\n            assert(tod._minute == 30);\n            assert(tod._second == 33);\n        }\n\n        {\n            auto tod = TimeOfDay(23, 59, 59);\n            assert(tod._hour == 23);\n            assert(tod._minute == 59);\n            assert(tod._second == 59);\n        }\n\n        assertThrown!DateTimeException(TimeOfDay(24, 0, 0));\n        assertThrown!DateTimeException(TimeOfDay(0, 60, 0));\n        assertThrown!DateTimeException(TimeOfDay(0, 0, 60));\n    }\n\n\n    /++\n        Compares this $(LREF TimeOfDay) with the given $(LREF TimeOfDay).\n\n        Returns:\n            $(BOOKTABLE,\n            $(TR $(TD this &lt; rhs) $(TD &lt; 0))\n            $(TR $(TD this == rhs) $(TD 0))\n            $(TR $(TD this &gt; rhs) $(TD &gt; 0))\n            )\n     +/\n    int opCmp(TimeOfDay rhs) const @safe pure nothrow @nogc\n    {\n        if (_hour < rhs._hour)\n            return -1;\n        if (_hour > rhs._hour)\n            return 1;\n\n        if (_minute < rhs._minute)\n            return -1;\n        if (_minute > rhs._minute)\n            return 1;\n\n        if (_second < rhs._second)\n            return -1;\n        if (_second > rhs._second)\n            return 1;\n\n        return 0;\n    }\n\n    @safe unittest\n    {\n        assert(TimeOfDay(0, 0, 0).opCmp(TimeOfDay.init) == 0);\n\n        assert(TimeOfDay(0, 0, 0).opCmp(TimeOfDay(0, 0, 0)) == 0);\n        assert(TimeOfDay(12, 0, 0).opCmp(TimeOfDay(12, 0, 0)) == 0);\n        assert(TimeOfDay(0, 30, 0).opCmp(TimeOfDay(0, 30, 0)) == 0);\n        assert(TimeOfDay(0, 0, 33).opCmp(TimeOfDay(0, 0, 33)) == 0);\n\n        assert(TimeOfDay(12, 30, 0).opCmp(TimeOfDay(12, 30, 0)) == 0);\n        assert(TimeOfDay(12, 30, 33).opCmp(TimeOfDay(12, 30, 33)) == 0);\n\n        assert(TimeOfDay(0, 30, 33).opCmp(TimeOfDay(0, 30, 33)) == 0);\n        assert(TimeOfDay(0, 0, 33).opCmp(TimeOfDay(0, 0, 33)) == 0);\n\n        assert(TimeOfDay(12, 30, 33).opCmp(TimeOfDay(13, 30, 33)) < 0);\n        assert(TimeOfDay(13, 30, 33).opCmp(TimeOfDay(12, 30, 33)) > 0);\n        assert(TimeOfDay(12, 30, 33).opCmp(TimeOfDay(12, 31, 33)) < 0);\n        assert(TimeOfDay(12, 31, 33).opCmp(TimeOfDay(12, 30, 33)) > 0);\n        assert(TimeOfDay(12, 30, 33).opCmp(TimeOfDay(12, 30, 34)) < 0);\n        assert(TimeOfDay(12, 30, 34).opCmp(TimeOfDay(12, 30, 33)) > 0);\n\n        assert(TimeOfDay(13, 30, 33).opCmp(TimeOfDay(12, 30, 34)) > 0);\n        assert(TimeOfDay(12, 30, 34).opCmp(TimeOfDay(13, 30, 33)) < 0);\n        assert(TimeOfDay(13, 30, 33).opCmp(TimeOfDay(12, 31, 33)) > 0);\n        assert(TimeOfDay(12, 31, 33).opCmp(TimeOfDay(13, 30, 33)) < 0);\n\n        assert(TimeOfDay(12, 31, 33).opCmp(TimeOfDay(12, 30, 34)) > 0);\n        assert(TimeOfDay(12, 30, 34).opCmp(TimeOfDay(12, 31, 33)) < 0);\n\n        const ctod = TimeOfDay(12, 30, 33);\n        immutable itod = TimeOfDay(12, 30, 33);\n        assert(ctod.opCmp(itod) == 0);\n        assert(itod.opCmp(ctod) == 0);\n    }\n\n\n    /++\n        Hours past midnight.\n     +/\n    @property ubyte hour() const @safe pure nothrow @nogc\n    {\n        return _hour;\n    }\n\n    @safe unittest\n    {\n        assert(TimeOfDay.init.hour == 0);\n        assert(TimeOfDay(12, 0, 0).hour == 12);\n\n        const ctod = TimeOfDay(12, 0, 0);\n        immutable itod = TimeOfDay(12, 0, 0);\n        assert(ctod.hour == 12);\n        assert(itod.hour == 12);\n    }\n\n\n    /++\n        Hours past midnight.\n\n        Params:\n            hour = The hour of the day to set this $(LREF TimeOfDay)'s hour to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given hour would\n            result in an invalid $(LREF TimeOfDay).\n     +/\n    @property void hour(int hour) @safe pure\n    {\n        enforceValid!\"hours\"(hour);\n        _hour = cast(ubyte) hour;\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException((){TimeOfDay(0, 0, 0).hour = 24;}());\n\n        auto tod = TimeOfDay(0, 0, 0);\n        tod.hour = 12;\n        assert(tod == TimeOfDay(12, 0, 0));\n\n        const ctod = TimeOfDay(0, 0, 0);\n        immutable itod = TimeOfDay(0, 0, 0);\n        static assert(!__traits(compiles, ctod.hour = 12));\n        static assert(!__traits(compiles, itod.hour = 12));\n    }\n\n\n    /++\n        Minutes past the hour.\n     +/\n    @property ubyte minute() const @safe pure nothrow @nogc\n    {\n        return _minute;\n    }\n\n    @safe unittest\n    {\n        assert(TimeOfDay.init.minute == 0);\n        assert(TimeOfDay(0, 30, 0).minute == 30);\n\n        const ctod = TimeOfDay(0, 30, 0);\n        immutable itod = TimeOfDay(0, 30, 0);\n        assert(ctod.minute == 30);\n        assert(itod.minute == 30);\n    }\n\n\n    /++\n        Minutes past the hour.\n\n        Params:\n            minute = The minute to set this $(LREF TimeOfDay)'s minute to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given minute\n            would result in an invalid $(LREF TimeOfDay).\n     +/\n    @property void minute(int minute) @safe pure\n    {\n        enforceValid!\"minutes\"(minute);\n        _minute = cast(ubyte) minute;\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException((){TimeOfDay(0, 0, 0).minute = 60;}());\n\n        auto tod = TimeOfDay(0, 0, 0);\n        tod.minute = 30;\n        assert(tod == TimeOfDay(0, 30, 0));\n\n        const ctod = TimeOfDay(0, 0, 0);\n        immutable itod = TimeOfDay(0, 0, 0);\n        static assert(!__traits(compiles, ctod.minute = 30));\n        static assert(!__traits(compiles, itod.minute = 30));\n    }\n\n\n    /++\n        Seconds past the minute.\n     +/\n    @property ubyte second() const @safe pure nothrow @nogc\n    {\n        return _second;\n    }\n\n    @safe unittest\n    {\n        assert(TimeOfDay.init.second == 0);\n        assert(TimeOfDay(0, 0, 33).second == 33);\n\n        const ctod = TimeOfDay(0, 0, 33);\n        immutable itod = TimeOfDay(0, 0, 33);\n        assert(ctod.second == 33);\n        assert(itod.second == 33);\n    }\n\n\n    /++\n        Seconds past the minute.\n\n        Params:\n            second = The second to set this $(LREF TimeOfDay)'s second to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given second\n            would result in an invalid $(LREF TimeOfDay).\n     +/\n    @property void second(int second) @safe pure\n    {\n        enforceValid!\"seconds\"(second);\n        _second = cast(ubyte) second;\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException((){TimeOfDay(0, 0, 0).second = 60;}());\n\n        auto tod = TimeOfDay(0, 0, 0);\n        tod.second = 33;\n        assert(tod == TimeOfDay(0, 0, 33));\n\n        const ctod = TimeOfDay(0, 0, 0);\n        immutable itod = TimeOfDay(0, 0, 0);\n        static assert(!__traits(compiles, ctod.second = 33));\n        static assert(!__traits(compiles, itod.second = 33));\n    }\n\n\n    /++\n        Adds the given number of units to this $(LREF TimeOfDay), mutating it. A\n        negative number will subtract.\n\n        The difference between rolling and adding is that rolling does not\n        affect larger units. For instance, rolling a $(LREF TimeOfDay)\n        one hours's worth of minutes gets the exact same\n        $(LREF TimeOfDay).\n\n        Accepted units are `\"hours\"`, `\"minutes\"`, and `\"seconds\"`.\n\n        Params:\n            units = The units to add.\n            value = The number of $(D_PARAM units) to add to this\n                    $(LREF TimeOfDay).\n\n        Returns:\n            A reference to the `TimeOfDay` (`this`).\n      +/\n    ref TimeOfDay roll(string units)(long value) @safe pure nothrow @nogc\n        if (units == \"hours\")\n    {\n        import core.time : dur;\n        return this += dur!\"hours\"(value);\n    }\n\n    ///\n    @safe unittest\n    {\n        auto tod1 = TimeOfDay(7, 12, 0);\n        tod1.roll!\"hours\"(1);\n        assert(tod1 == TimeOfDay(8, 12, 0));\n\n        auto tod2 = TimeOfDay(7, 12, 0);\n        tod2.roll!\"hours\"(-1);\n        assert(tod2 == TimeOfDay(6, 12, 0));\n\n        auto tod3 = TimeOfDay(23, 59, 0);\n        tod3.roll!\"minutes\"(1);\n        assert(tod3 == TimeOfDay(23, 0, 0));\n\n        auto tod4 = TimeOfDay(0, 0, 0);\n        tod4.roll!\"minutes\"(-1);\n        assert(tod4 == TimeOfDay(0, 59, 0));\n\n        auto tod5 = TimeOfDay(23, 59, 59);\n        tod5.roll!\"seconds\"(1);\n        assert(tod5 == TimeOfDay(23, 59, 0));\n\n        auto tod6 = TimeOfDay(0, 0, 0);\n        tod6.roll!\"seconds\"(-1);\n        assert(tod6 == TimeOfDay(0, 0, 59));\n    }\n\n    @safe unittest\n    {\n        auto tod = TimeOfDay(12, 27, 2);\n        tod.roll!\"hours\"(22).roll!\"hours\"(-7);\n        assert(tod == TimeOfDay(3, 27, 2));\n\n        const ctod = TimeOfDay(0, 0, 0);\n        immutable itod = TimeOfDay(0, 0, 0);\n        static assert(!__traits(compiles, ctod.roll!\"hours\"(53)));\n        static assert(!__traits(compiles, itod.roll!\"hours\"(53)));\n    }\n\n\n    /// ditto\n    ref TimeOfDay roll(string units)(long value) @safe pure nothrow @nogc\n        if (units == \"minutes\" || units == \"seconds\")\n    {\n        import std.format : format;\n\n        enum memberVarStr = units[0 .. $ - 1];\n        value %= 60;\n        mixin(format(\"auto newVal = cast(ubyte)(_%s) + value;\", memberVarStr));\n\n        if (value < 0)\n        {\n            if (newVal < 0)\n                newVal += 60;\n        }\n        else if (newVal >= 60)\n            newVal -= 60;\n\n        mixin(format(\"_%s = cast(ubyte) newVal;\", memberVarStr));\n        return this;\n    }\n\n    // Test roll!\"minutes\"().\n    @safe unittest\n    {\n        static void testTOD(TimeOfDay orig, int minutes, TimeOfDay expected, size_t line = __LINE__)\n        {\n            orig.roll!\"minutes\"(minutes);\n            assert(orig == expected);\n        }\n\n        testTOD(TimeOfDay(12, 30, 33), 0, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), 1, TimeOfDay(12, 31, 33));\n        testTOD(TimeOfDay(12, 30, 33), 2, TimeOfDay(12, 32, 33));\n        testTOD(TimeOfDay(12, 30, 33), 3, TimeOfDay(12, 33, 33));\n        testTOD(TimeOfDay(12, 30, 33), 4, TimeOfDay(12, 34, 33));\n        testTOD(TimeOfDay(12, 30, 33), 5, TimeOfDay(12, 35, 33));\n        testTOD(TimeOfDay(12, 30, 33), 10, TimeOfDay(12, 40, 33));\n        testTOD(TimeOfDay(12, 30, 33), 15, TimeOfDay(12, 45, 33));\n        testTOD(TimeOfDay(12, 30, 33), 29, TimeOfDay(12, 59, 33));\n        testTOD(TimeOfDay(12, 30, 33), 30, TimeOfDay(12, 0, 33));\n        testTOD(TimeOfDay(12, 30, 33), 45, TimeOfDay(12, 15, 33));\n        testTOD(TimeOfDay(12, 30, 33), 60, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), 75, TimeOfDay(12, 45, 33));\n        testTOD(TimeOfDay(12, 30, 33), 90, TimeOfDay(12, 0, 33));\n        testTOD(TimeOfDay(12, 30, 33), 100, TimeOfDay(12, 10, 33));\n\n        testTOD(TimeOfDay(12, 30, 33), 689, TimeOfDay(12, 59, 33));\n        testTOD(TimeOfDay(12, 30, 33), 690, TimeOfDay(12, 0, 33));\n        testTOD(TimeOfDay(12, 30, 33), 691, TimeOfDay(12, 1, 33));\n        testTOD(TimeOfDay(12, 30, 33), 960, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), 1439, TimeOfDay(12, 29, 33));\n        testTOD(TimeOfDay(12, 30, 33), 1440, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), 1441, TimeOfDay(12, 31, 33));\n        testTOD(TimeOfDay(12, 30, 33), 2880, TimeOfDay(12, 30, 33));\n\n        testTOD(TimeOfDay(12, 30, 33), -1, TimeOfDay(12, 29, 33));\n        testTOD(TimeOfDay(12, 30, 33), -2, TimeOfDay(12, 28, 33));\n        testTOD(TimeOfDay(12, 30, 33), -3, TimeOfDay(12, 27, 33));\n        testTOD(TimeOfDay(12, 30, 33), -4, TimeOfDay(12, 26, 33));\n        testTOD(TimeOfDay(12, 30, 33), -5, TimeOfDay(12, 25, 33));\n        testTOD(TimeOfDay(12, 30, 33), -10, TimeOfDay(12, 20, 33));\n        testTOD(TimeOfDay(12, 30, 33), -15, TimeOfDay(12, 15, 33));\n        testTOD(TimeOfDay(12, 30, 33), -29, TimeOfDay(12, 1, 33));\n        testTOD(TimeOfDay(12, 30, 33), -30, TimeOfDay(12, 0, 33));\n        testTOD(TimeOfDay(12, 30, 33), -45, TimeOfDay(12, 45, 33));\n        testTOD(TimeOfDay(12, 30, 33), -60, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), -75, TimeOfDay(12, 15, 33));\n        testTOD(TimeOfDay(12, 30, 33), -90, TimeOfDay(12, 0, 33));\n        testTOD(TimeOfDay(12, 30, 33), -100, TimeOfDay(12, 50, 33));\n\n        testTOD(TimeOfDay(12, 30, 33), -749, TimeOfDay(12, 1, 33));\n        testTOD(TimeOfDay(12, 30, 33), -750, TimeOfDay(12, 0, 33));\n        testTOD(TimeOfDay(12, 30, 33), -751, TimeOfDay(12, 59, 33));\n        testTOD(TimeOfDay(12, 30, 33), -960, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), -1439, TimeOfDay(12, 31, 33));\n        testTOD(TimeOfDay(12, 30, 33), -1440, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), -1441, TimeOfDay(12, 29, 33));\n        testTOD(TimeOfDay(12, 30, 33), -2880, TimeOfDay(12, 30, 33));\n\n        testTOD(TimeOfDay(12, 0, 33), 1, TimeOfDay(12, 1, 33));\n        testTOD(TimeOfDay(12, 0, 33), 0, TimeOfDay(12, 0, 33));\n        testTOD(TimeOfDay(12, 0, 33), -1, TimeOfDay(12, 59, 33));\n\n        testTOD(TimeOfDay(11, 59, 33), 1, TimeOfDay(11, 0, 33));\n        testTOD(TimeOfDay(11, 59, 33), 0, TimeOfDay(11, 59, 33));\n        testTOD(TimeOfDay(11, 59, 33), -1, TimeOfDay(11, 58, 33));\n\n        testTOD(TimeOfDay(0, 0, 33), 1, TimeOfDay(0, 1, 33));\n        testTOD(TimeOfDay(0, 0, 33), 0, TimeOfDay(0, 0, 33));\n        testTOD(TimeOfDay(0, 0, 33), -1, TimeOfDay(0, 59, 33));\n\n        testTOD(TimeOfDay(23, 59, 33), 1, TimeOfDay(23, 0, 33));\n        testTOD(TimeOfDay(23, 59, 33), 0, TimeOfDay(23, 59, 33));\n        testTOD(TimeOfDay(23, 59, 33), -1, TimeOfDay(23, 58, 33));\n\n        auto tod = TimeOfDay(12, 27, 2);\n        tod.roll!\"minutes\"(97).roll!\"minutes\"(-102);\n        assert(tod == TimeOfDay(12, 22, 2));\n\n        const ctod = TimeOfDay(0, 0, 0);\n        immutable itod = TimeOfDay(0, 0, 0);\n        static assert(!__traits(compiles, ctod.roll!\"minutes\"(7)));\n        static assert(!__traits(compiles, itod.roll!\"minutes\"(7)));\n    }\n\n    // Test roll!\"seconds\"().\n    @safe unittest\n    {\n        static void testTOD(TimeOfDay orig, int seconds, TimeOfDay expected, size_t line = __LINE__)\n        {\n            orig.roll!\"seconds\"(seconds);\n            assert(orig == expected);\n        }\n\n        testTOD(TimeOfDay(12, 30, 33), 0, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), 1, TimeOfDay(12, 30, 34));\n        testTOD(TimeOfDay(12, 30, 33), 2, TimeOfDay(12, 30, 35));\n        testTOD(TimeOfDay(12, 30, 33), 3, TimeOfDay(12, 30, 36));\n        testTOD(TimeOfDay(12, 30, 33), 4, TimeOfDay(12, 30, 37));\n        testTOD(TimeOfDay(12, 30, 33), 5, TimeOfDay(12, 30, 38));\n        testTOD(TimeOfDay(12, 30, 33), 10, TimeOfDay(12, 30, 43));\n        testTOD(TimeOfDay(12, 30, 33), 15, TimeOfDay(12, 30, 48));\n        testTOD(TimeOfDay(12, 30, 33), 26, TimeOfDay(12, 30, 59));\n        testTOD(TimeOfDay(12, 30, 33), 27, TimeOfDay(12, 30, 0));\n        testTOD(TimeOfDay(12, 30, 33), 30, TimeOfDay(12, 30, 3));\n        testTOD(TimeOfDay(12, 30, 33), 59, TimeOfDay(12, 30, 32));\n        testTOD(TimeOfDay(12, 30, 33), 60, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), 61, TimeOfDay(12, 30, 34));\n\n        testTOD(TimeOfDay(12, 30, 33), 1766, TimeOfDay(12, 30, 59));\n        testTOD(TimeOfDay(12, 30, 33), 1767, TimeOfDay(12, 30, 0));\n        testTOD(TimeOfDay(12, 30, 33), 1768, TimeOfDay(12, 30, 1));\n        testTOD(TimeOfDay(12, 30, 33), 2007, TimeOfDay(12, 30, 0));\n        testTOD(TimeOfDay(12, 30, 33), 3599, TimeOfDay(12, 30, 32));\n        testTOD(TimeOfDay(12, 30, 33), 3600, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), 3601, TimeOfDay(12, 30, 34));\n        testTOD(TimeOfDay(12, 30, 33), 7200, TimeOfDay(12, 30, 33));\n\n        testTOD(TimeOfDay(12, 30, 33), -1, TimeOfDay(12, 30, 32));\n        testTOD(TimeOfDay(12, 30, 33), -2, TimeOfDay(12, 30, 31));\n        testTOD(TimeOfDay(12, 30, 33), -3, TimeOfDay(12, 30, 30));\n        testTOD(TimeOfDay(12, 30, 33), -4, TimeOfDay(12, 30, 29));\n        testTOD(TimeOfDay(12, 30, 33), -5, TimeOfDay(12, 30, 28));\n        testTOD(TimeOfDay(12, 30, 33), -10, TimeOfDay(12, 30, 23));\n        testTOD(TimeOfDay(12, 30, 33), -15, TimeOfDay(12, 30, 18));\n        testTOD(TimeOfDay(12, 30, 33), -33, TimeOfDay(12, 30, 0));\n        testTOD(TimeOfDay(12, 30, 33), -34, TimeOfDay(12, 30, 59));\n        testTOD(TimeOfDay(12, 30, 33), -35, TimeOfDay(12, 30, 58));\n        testTOD(TimeOfDay(12, 30, 33), -59, TimeOfDay(12, 30, 34));\n        testTOD(TimeOfDay(12, 30, 33), -60, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), -61, TimeOfDay(12, 30, 32));\n\n        testTOD(TimeOfDay(12, 30, 0), 1, TimeOfDay(12, 30, 1));\n        testTOD(TimeOfDay(12, 30, 0), 0, TimeOfDay(12, 30, 0));\n        testTOD(TimeOfDay(12, 30, 0), -1, TimeOfDay(12, 30, 59));\n\n        testTOD(TimeOfDay(12, 0, 0), 1, TimeOfDay(12, 0, 1));\n        testTOD(TimeOfDay(12, 0, 0), 0, TimeOfDay(12, 0, 0));\n        testTOD(TimeOfDay(12, 0, 0), -1, TimeOfDay(12, 0, 59));\n\n        testTOD(TimeOfDay(0, 0, 0), 1, TimeOfDay(0, 0, 1));\n        testTOD(TimeOfDay(0, 0, 0), 0, TimeOfDay(0, 0, 0));\n        testTOD(TimeOfDay(0, 0, 0), -1, TimeOfDay(0, 0, 59));\n\n        testTOD(TimeOfDay(23, 59, 59), 1, TimeOfDay(23, 59, 0));\n        testTOD(TimeOfDay(23, 59, 59), 0, TimeOfDay(23, 59, 59));\n        testTOD(TimeOfDay(23, 59, 59), -1, TimeOfDay(23, 59, 58));\n\n        auto tod = TimeOfDay(12, 27, 2);\n        tod.roll!\"seconds\"(105).roll!\"seconds\"(-77);\n        assert(tod == TimeOfDay(12, 27, 30));\n\n        const ctod = TimeOfDay(0, 0, 0);\n        immutable itod = TimeOfDay(0, 0, 0);\n        static assert(!__traits(compiles, ctod.roll!\"seconds\"(7)));\n        static assert(!__traits(compiles, itod.roll!\"seconds\"(7)));\n    }\n\n\n    import core.time : Duration;\n    /++\n        Gives the result of adding or subtracting a $(REF Duration, core,time)\n        from this $(LREF TimeOfDay).\n\n        The legal types of arithmetic for $(LREF TimeOfDay) using this operator\n        are\n\n        $(BOOKTABLE,\n        $(TR $(TD TimeOfDay) $(TD +) $(TD Duration) $(TD -->) $(TD TimeOfDay))\n        $(TR $(TD TimeOfDay) $(TD -) $(TD Duration) $(TD -->) $(TD TimeOfDay))\n        )\n\n        Params:\n            duration = The $(REF Duration, core,time) to add to or subtract from\n                       this $(LREF TimeOfDay).\n      +/\n    TimeOfDay opBinary(string op)(Duration duration) const @safe pure nothrow @nogc\n        if (op == \"+\" || op == \"-\")\n    {\n        TimeOfDay retval = this;\n        immutable seconds = duration.total!\"seconds\";\n        mixin(\"return retval._addSeconds(\" ~ op ~ \"seconds);\");\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : hours, minutes, seconds;\n\n        assert(TimeOfDay(12, 12, 12) + seconds(1) == TimeOfDay(12, 12, 13));\n        assert(TimeOfDay(12, 12, 12) + minutes(1) == TimeOfDay(12, 13, 12));\n        assert(TimeOfDay(12, 12, 12) + hours(1) == TimeOfDay(13, 12, 12));\n        assert(TimeOfDay(23, 59, 59) + seconds(1) == TimeOfDay(0, 0, 0));\n\n        assert(TimeOfDay(12, 12, 12) - seconds(1) == TimeOfDay(12, 12, 11));\n        assert(TimeOfDay(12, 12, 12) - minutes(1) == TimeOfDay(12, 11, 12));\n        assert(TimeOfDay(12, 12, 12) - hours(1) == TimeOfDay(11, 12, 12));\n        assert(TimeOfDay(0, 0, 0) - seconds(1) == TimeOfDay(23, 59, 59));\n    }\n\n    @safe unittest\n    {\n        auto tod = TimeOfDay(12, 30, 33);\n\n        import core.time : dur;\n        assert(tod + dur!\"hours\"(7) == TimeOfDay(19, 30, 33));\n        assert(tod + dur!\"hours\"(-7) == TimeOfDay(5, 30, 33));\n        assert(tod + dur!\"minutes\"(7) == TimeOfDay(12, 37, 33));\n        assert(tod + dur!\"minutes\"(-7) == TimeOfDay(12, 23, 33));\n        assert(tod + dur!\"seconds\"(7) == TimeOfDay(12, 30, 40));\n        assert(tod + dur!\"seconds\"(-7) == TimeOfDay(12, 30, 26));\n\n        assert(tod + dur!\"msecs\"(7000) == TimeOfDay(12, 30, 40));\n        assert(tod + dur!\"msecs\"(-7000) == TimeOfDay(12, 30, 26));\n        assert(tod + dur!\"usecs\"(7_000_000) == TimeOfDay(12, 30, 40));\n        assert(tod + dur!\"usecs\"(-7_000_000) == TimeOfDay(12, 30, 26));\n        assert(tod + dur!\"hnsecs\"(70_000_000) == TimeOfDay(12, 30, 40));\n        assert(tod + dur!\"hnsecs\"(-70_000_000) == TimeOfDay(12, 30, 26));\n\n        assert(tod - dur!\"hours\"(-7) == TimeOfDay(19, 30, 33));\n        assert(tod - dur!\"hours\"(7) == TimeOfDay(5, 30, 33));\n        assert(tod - dur!\"minutes\"(-7) == TimeOfDay(12, 37, 33));\n        assert(tod - dur!\"minutes\"(7) == TimeOfDay(12, 23, 33));\n        assert(tod - dur!\"seconds\"(-7) == TimeOfDay(12, 30, 40));\n        assert(tod - dur!\"seconds\"(7) == TimeOfDay(12, 30, 26));\n\n        assert(tod - dur!\"msecs\"(-7000) == TimeOfDay(12, 30, 40));\n        assert(tod - dur!\"msecs\"(7000) == TimeOfDay(12, 30, 26));\n        assert(tod - dur!\"usecs\"(-7_000_000) == TimeOfDay(12, 30, 40));\n        assert(tod - dur!\"usecs\"(7_000_000) == TimeOfDay(12, 30, 26));\n        assert(tod - dur!\"hnsecs\"(-70_000_000) == TimeOfDay(12, 30, 40));\n        assert(tod - dur!\"hnsecs\"(70_000_000) == TimeOfDay(12, 30, 26));\n\n        auto duration = dur!\"hours\"(11);\n        const ctod = TimeOfDay(12, 30, 33);\n        immutable itod = TimeOfDay(12, 30, 33);\n        assert(tod + duration == TimeOfDay(23, 30, 33));\n        assert(ctod + duration == TimeOfDay(23, 30, 33));\n        assert(itod + duration == TimeOfDay(23, 30, 33));\n\n        assert(tod - duration == TimeOfDay(1, 30, 33));\n        assert(ctod - duration == TimeOfDay(1, 30, 33));\n        assert(itod - duration == TimeOfDay(1, 30, 33));\n    }\n\n\n    /++\n        Gives the result of adding or subtracting a $(REF Duration, core,time)\n        from this $(LREF TimeOfDay), as well as assigning the result to this\n        $(LREF TimeOfDay).\n\n        The legal types of arithmetic for $(LREF TimeOfDay) using this operator\n        are\n\n        $(BOOKTABLE,\n        $(TR $(TD TimeOfDay) $(TD +) $(TD Duration) $(TD -->) $(TD TimeOfDay))\n        $(TR $(TD TimeOfDay) $(TD -) $(TD Duration) $(TD -->) $(TD TimeOfDay))\n        )\n\n        Params:\n            duration = The $(REF Duration, core,time) to add to or subtract from\n                       this $(LREF TimeOfDay).\n      +/\n    ref TimeOfDay opOpAssign(string op)(Duration duration) @safe pure nothrow @nogc\n        if (op == \"+\" || op == \"-\")\n    {\n        immutable seconds = duration.total!\"seconds\";\n        mixin(\"return _addSeconds(\" ~ op ~ \"seconds);\");\n    }\n\n    @safe unittest\n    {\n        import core.time : dur;\n        auto duration = dur!\"hours\"(12);\n\n        assert(TimeOfDay(12, 30, 33) + dur!\"hours\"(7) == TimeOfDay(19, 30, 33));\n        assert(TimeOfDay(12, 30, 33) + dur!\"hours\"(-7) == TimeOfDay(5, 30, 33));\n        assert(TimeOfDay(12, 30, 33) + dur!\"minutes\"(7) == TimeOfDay(12, 37, 33));\n        assert(TimeOfDay(12, 30, 33) + dur!\"minutes\"(-7) == TimeOfDay(12, 23, 33));\n        assert(TimeOfDay(12, 30, 33) + dur!\"seconds\"(7) == TimeOfDay(12, 30, 40));\n        assert(TimeOfDay(12, 30, 33) + dur!\"seconds\"(-7) == TimeOfDay(12, 30, 26));\n\n        assert(TimeOfDay(12, 30, 33) + dur!\"msecs\"(7000) == TimeOfDay(12, 30, 40));\n        assert(TimeOfDay(12, 30, 33) + dur!\"msecs\"(-7000) == TimeOfDay(12, 30, 26));\n        assert(TimeOfDay(12, 30, 33) + dur!\"usecs\"(7_000_000) == TimeOfDay(12, 30, 40));\n        assert(TimeOfDay(12, 30, 33) + dur!\"usecs\"(-7_000_000) == TimeOfDay(12, 30, 26));\n        assert(TimeOfDay(12, 30, 33) + dur!\"hnsecs\"(70_000_000) == TimeOfDay(12, 30, 40));\n        assert(TimeOfDay(12, 30, 33) + dur!\"hnsecs\"(-70_000_000) == TimeOfDay(12, 30, 26));\n\n        assert(TimeOfDay(12, 30, 33) - dur!\"hours\"(-7) == TimeOfDay(19, 30, 33));\n        assert(TimeOfDay(12, 30, 33) - dur!\"hours\"(7) == TimeOfDay(5, 30, 33));\n        assert(TimeOfDay(12, 30, 33) - dur!\"minutes\"(-7) == TimeOfDay(12, 37, 33));\n        assert(TimeOfDay(12, 30, 33) - dur!\"minutes\"(7) == TimeOfDay(12, 23, 33));\n        assert(TimeOfDay(12, 30, 33) - dur!\"seconds\"(-7) == TimeOfDay(12, 30, 40));\n        assert(TimeOfDay(12, 30, 33) - dur!\"seconds\"(7) == TimeOfDay(12, 30, 26));\n\n        assert(TimeOfDay(12, 30, 33) - dur!\"msecs\"(-7000) == TimeOfDay(12, 30, 40));\n        assert(TimeOfDay(12, 30, 33) - dur!\"msecs\"(7000) == TimeOfDay(12, 30, 26));\n        assert(TimeOfDay(12, 30, 33) - dur!\"usecs\"(-7_000_000) == TimeOfDay(12, 30, 40));\n        assert(TimeOfDay(12, 30, 33) - dur!\"usecs\"(7_000_000) == TimeOfDay(12, 30, 26));\n        assert(TimeOfDay(12, 30, 33) - dur!\"hnsecs\"(-70_000_000) == TimeOfDay(12, 30, 40));\n        assert(TimeOfDay(12, 30, 33) - dur!\"hnsecs\"(70_000_000) == TimeOfDay(12, 30, 26));\n\n        auto tod = TimeOfDay(19, 17, 22);\n        (tod += dur!\"seconds\"(9)) += dur!\"seconds\"(-7292);\n        assert(tod == TimeOfDay(17, 15, 59));\n\n        const ctod = TimeOfDay(12, 33, 30);\n        immutable itod = TimeOfDay(12, 33, 30);\n        static assert(!__traits(compiles, ctod += duration));\n        static assert(!__traits(compiles, itod += duration));\n        static assert(!__traits(compiles, ctod -= duration));\n        static assert(!__traits(compiles, itod -= duration));\n    }\n\n\n    /++\n        Gives the difference between two $(LREF TimeOfDay)s.\n\n        The legal types of arithmetic for $(LREF TimeOfDay) using this operator\n        are\n\n        $(BOOKTABLE,\n        $(TR $(TD TimeOfDay) $(TD -) $(TD TimeOfDay) $(TD -->) $(TD duration))\n        )\n\n        Params:\n            rhs = The $(LREF TimeOfDay) to subtract from this one.\n      +/\n    Duration opBinary(string op)(TimeOfDay rhs) const @safe pure nothrow @nogc\n        if (op == \"-\")\n    {\n        immutable lhsSec = _hour * 3600 + _minute * 60 + _second;\n        immutable rhsSec = rhs._hour * 3600 + rhs._minute * 60 + rhs._second;\n\n        import core.time : dur;\n        return dur!\"seconds\"(lhsSec - rhsSec);\n    }\n\n    @safe unittest\n    {\n        auto tod = TimeOfDay(12, 30, 33);\n\n        import core.time : dur;\n        assert(TimeOfDay(7, 12, 52) - TimeOfDay(12, 30, 33) == dur!\"seconds\"(-19_061));\n        assert(TimeOfDay(12, 30, 33) - TimeOfDay(7, 12, 52) == dur!\"seconds\"(19_061));\n        assert(TimeOfDay(12, 30, 33) - TimeOfDay(14, 30, 33) == dur!\"seconds\"(-7200));\n        assert(TimeOfDay(14, 30, 33) - TimeOfDay(12, 30, 33) == dur!\"seconds\"(7200));\n        assert(TimeOfDay(12, 30, 33) - TimeOfDay(12, 34, 33) == dur!\"seconds\"(-240));\n        assert(TimeOfDay(12, 34, 33) - TimeOfDay(12, 30, 33) == dur!\"seconds\"(240));\n        assert(TimeOfDay(12, 30, 33) - TimeOfDay(12, 30, 34) == dur!\"seconds\"(-1));\n        assert(TimeOfDay(12, 30, 34) - TimeOfDay(12, 30, 33) == dur!\"seconds\"(1));\n\n        const ctod = TimeOfDay(12, 30, 33);\n        immutable itod = TimeOfDay(12, 30, 33);\n        assert(tod - tod == Duration.zero);\n        assert(ctod - tod == Duration.zero);\n        assert(itod - tod == Duration.zero);\n\n        assert(tod - ctod == Duration.zero);\n        assert(ctod - ctod == Duration.zero);\n        assert(itod - ctod == Duration.zero);\n\n        assert(tod - itod == Duration.zero);\n        assert(ctod - itod == Duration.zero);\n        assert(itod - itod == Duration.zero);\n    }\n\n\n    /++\n        Converts this $(LREF TimeOfDay) to a string with the format `HHMMSS`.\n        If `writer` is set, the resulting string will be written directly to it.\n\n        Params:\n            writer = A `char` accepting $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toISOString() const @safe pure nothrow\n    {\n        import std.array : appender;\n        auto w = appender!string();\n        w.reserve(6);\n        try\n            toISOString(w);\n        catch (Exception e)\n            assert(0, \"toISOString() threw.\");\n        return w.data;\n    }\n\n    /// ditto\n    void toISOString(W)(ref W writer) const\n    if (isOutputRange!(W, char))\n    {\n        import std.format : formattedWrite;\n        formattedWrite(writer, \"%02d%02d%02d\", _hour, _minute, _second);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(TimeOfDay(0, 0, 0).toISOString() == \"000000\");\n        assert(TimeOfDay(12, 30, 33).toISOString() == \"123033\");\n    }\n\n    @safe unittest\n    {\n        auto tod = TimeOfDay(12, 30, 33);\n        const ctod = TimeOfDay(12, 30, 33);\n        immutable itod = TimeOfDay(12, 30, 33);\n        assert(tod.toISOString() == \"123033\");\n        assert(ctod.toISOString() == \"123033\");\n        assert(itod.toISOString() == \"123033\");\n    }\n\n\n    /++\n        Converts this $(LREF TimeOfDay) to a string with the format `HH:MM:SS`.\n        If `writer` is set, the resulting string will be written directly to it.\n\n        Params:\n            writer = A `char` accepting $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toISOExtString() const @safe pure nothrow\n    {\n        import std.array : appender;\n        auto w = appender!string();\n        w.reserve(8);\n        try\n            toISOExtString(w);\n        catch (Exception e)\n            assert(0, \"toISOExtString() threw.\");\n        return w.data;\n    }\n\n    /// ditto\n    void toISOExtString(W)(ref W writer) const\n    if (isOutputRange!(W, char))\n    {\n        import std.format : formattedWrite;\n        formattedWrite(writer, \"%02d:%02d:%02d\", _hour, _minute, _second);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(TimeOfDay(0, 0, 0).toISOExtString() == \"00:00:00\");\n        assert(TimeOfDay(12, 30, 33).toISOExtString() == \"12:30:33\");\n    }\n\n    @safe unittest\n    {\n        auto tod = TimeOfDay(12, 30, 33);\n        const ctod = TimeOfDay(12, 30, 33);\n        immutable itod = TimeOfDay(12, 30, 33);\n        assert(tod.toISOExtString() == \"12:30:33\");\n        assert(ctod.toISOExtString() == \"12:30:33\");\n        assert(itod.toISOExtString() == \"12:30:33\");\n    }\n\n\n    /++\n        Converts this TimeOfDay to a string.\n\n        This function exists to make it easy to convert a $(LREF TimeOfDay) to a\n        string for code that does not care what the exact format is - just that\n        it presents the information in a clear manner. It also makes it easy to\n        simply convert a $(LREF TimeOfDay) to a string when using functions such\n        as `to!string`, `format`, or `writeln` which use toString to convert\n        user-defined types. So, it is unlikely that much code will call\n        toString directly.\n\n        The format of the string is purposefully unspecified, and code that\n        cares about the format of the string should use `toISOString`,\n        `toISOExtString`, or some other custom formatting function that\n        explicitly generates the format that the code needs. The reason is that\n        the code is then clear about what format it's using, making it less\n        error-prone to maintain the code and interact with other software that\n        consumes the generated strings. It's for this same reason that\n        $(LREF TimeOfDay) has no `fromString` function, whereas it does have\n        `fromISOString` and `fromISOExtString`.\n\n        The format returned by toString may or may not change in the future.\n\n        Params:\n            writer = A `char` accepting $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toString() const @safe pure nothrow\n    {\n        return toISOExtString();\n    }\n\n    /// ditto\n    void toString(W)(ref W writer) const\n    if (isOutputRange!(W, char))\n    {\n        toISOExtString(writer);\n    }\n\n    @safe unittest\n    {\n        auto tod = TimeOfDay(12, 30, 33);\n        const ctod = TimeOfDay(12, 30, 33);\n        immutable itod = TimeOfDay(12, 30, 33);\n        assert(tod.toString());\n        assert(ctod.toString());\n        assert(itod.toString());\n    }\n\n\n    /++\n        Creates a $(LREF TimeOfDay) from a string with the format HHMMSS.\n        Whitespace is stripped from the given string.\n\n        Params:\n            isoString = A string formatted in the ISO format for times.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given string is\n            not in the ISO format or if the resulting $(LREF TimeOfDay) would\n            not be valid.\n      +/\n    static TimeOfDay fromISOString(S)(scope const S isoString) @safe pure\n        if (isSomeString!S)\n    {\n        import std.conv : to, text, ConvException;\n        import std.exception : enforce;\n        import std.string : strip;\n\n        int hours, minutes, seconds;\n        auto str = strip(isoString);\n\n        enforce!DateTimeException(str.length == 6, text(\"Invalid ISO String: \", isoString));\n\n        try\n        {\n            // cast to int from uint is used because it checks for\n            // non digits without extra loops\n            hours = cast(int) to!uint(str[0 .. 2]);\n            minutes = cast(int) to!uint(str[2 .. 4]);\n            seconds = cast(int) to!uint(str[4 .. $]);\n        }\n        catch (ConvException)\n        {\n            throw new DateTimeException(text(\"Invalid ISO String: \", isoString));\n        }\n\n        return TimeOfDay(hours, minutes, seconds);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(TimeOfDay.fromISOString(\"000000\") == TimeOfDay(0, 0, 0));\n        assert(TimeOfDay.fromISOString(\"123033\") == TimeOfDay(12, 30, 33));\n        assert(TimeOfDay.fromISOString(\" 123033 \") == TimeOfDay(12, 30, 33));\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"00\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"000\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"0000\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"00000\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"13033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"1277\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12707\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12070\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12303a\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"1230a3\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"123a33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12a033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"1a0033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"a20033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"1200330\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"0120033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"-120033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"+120033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"120033am\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"120033pm\"));\n\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"0::\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\":0:\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"::0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"0:0:0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"0:0:00\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"0:00:0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"00:0:0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"00:00:0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"00:0:00\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"13:0:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12:7:7\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12:7:07\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12:07:0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12:30:3a\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12:30:a3\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12:3a:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12:a0:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"1a:00:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"a2:00:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12:003:30\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"120:03:30\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"012:00:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"01:200:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"-12:00:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"+12:00:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12:00:33am\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12:00:33pm\"));\n\n        assertThrown!DateTimeException(TimeOfDay.fromISOString(\"12:00:33\"));\n\n        assert(TimeOfDay.fromISOString(\"011217\") == TimeOfDay(1, 12, 17));\n        assert(TimeOfDay.fromISOString(\"001412\") == TimeOfDay(0, 14, 12));\n        assert(TimeOfDay.fromISOString(\"000007\") == TimeOfDay(0, 0, 7));\n        assert(TimeOfDay.fromISOString(\"011217 \") == TimeOfDay(1, 12, 17));\n        assert(TimeOfDay.fromISOString(\" 011217\") == TimeOfDay(1, 12, 17));\n        assert(TimeOfDay.fromISOString(\" 011217 \") == TimeOfDay(1, 12, 17));\n    }\n\n    // bug# 17801\n    @safe unittest\n    {\n        import std.conv : to;\n        import std.meta : AliasSeq;\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))\n                assert(TimeOfDay.fromISOString(to!S(\"141516\")) == TimeOfDay(14, 15, 16));\n        }\n    }\n\n\n    /++\n        Creates a $(LREF TimeOfDay) from a string with the format HH:MM:SS.\n        Whitespace is stripped from the given string.\n\n        Params:\n            isoExtString = A string formatted in the ISO Extended format for\n            times.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given string is\n            not in the ISO Extended format or if the resulting $(LREF TimeOfDay)\n            would not be valid.\n      +/\n    static TimeOfDay fromISOExtString(S)(scope const S isoExtString) @safe pure\n        if (isSomeString!S)\n    {\n        import std.conv : ConvException, text, to;\n        import std.string : strip;\n\n        auto str = strip(isoExtString);\n        int hours, minutes, seconds;\n\n        if (str.length != 8 || str[2] != ':' || str[5] != ':')\n            throw new DateTimeException(text(\"Invalid ISO Extended String: \", isoExtString));\n\n        try\n        {\n            // cast to int from uint is used because it checks for\n            // non digits without extra loops\n            hours = cast(int) to!uint(str[0 .. 2]);\n            minutes = cast(int) to!uint(str[3 .. 5]);\n            seconds = cast(int) to!uint(str[6 .. $]);\n        }\n        catch (ConvException)\n        {\n            throw new DateTimeException(text(\"Invalid ISO Extended String: \", isoExtString));\n        }\n\n        return TimeOfDay(hours, minutes, seconds);\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(TimeOfDay.fromISOExtString(\"00:00:00\") == TimeOfDay(0, 0, 0));\n        assert(TimeOfDay.fromISOExtString(\"12:30:33\") == TimeOfDay(12, 30, 33));\n        assert(TimeOfDay.fromISOExtString(\" 12:30:33 \") == TimeOfDay(12, 30, 33));\n    }\n\n    @safe unittest\n    {\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"00\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"000\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"0000\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"00000\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"13033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"1277\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12707\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12070\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12303a\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"1230a3\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"123a33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12a033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"1a0033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"a20033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"1200330\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"0120033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"-120033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"+120033\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"120033am\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"120033pm\"));\n\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"0::\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\":0:\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"::0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"0:0:0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"0:0:00\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"0:00:0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"00:0:0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"00:00:0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"00:0:00\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"13:0:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12:7:7\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12:7:07\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12:07:0\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12:30:3a\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12:30:a3\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12:3a:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12:a0:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"1a:00:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"a2:00:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12:003:30\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"120:03:30\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"012:00:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"01:200:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"-12:00:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"+12:00:33\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12:00:33am\"));\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"12:00:33pm\"));\n\n        assertThrown!DateTimeException(TimeOfDay.fromISOExtString(\"120033\"));\n\n        assert(TimeOfDay.fromISOExtString(\"01:12:17\") == TimeOfDay(1, 12, 17));\n        assert(TimeOfDay.fromISOExtString(\"00:14:12\") == TimeOfDay(0, 14, 12));\n        assert(TimeOfDay.fromISOExtString(\"00:00:07\") == TimeOfDay(0, 0, 7));\n        assert(TimeOfDay.fromISOExtString(\"01:12:17 \") == TimeOfDay(1, 12, 17));\n        assert(TimeOfDay.fromISOExtString(\" 01:12:17\") == TimeOfDay(1, 12, 17));\n        assert(TimeOfDay.fromISOExtString(\" 01:12:17 \") == TimeOfDay(1, 12, 17));\n    }\n\n    // bug# 17801\n    @safe unittest\n    {\n        import std.conv : to;\n        import std.meta : AliasSeq;\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))\n                assert(TimeOfDay.fromISOExtString(to!S(\"14:15:16\")) == TimeOfDay(14, 15, 16));\n        }\n    }\n\n\n    /++\n        Returns midnight.\n      +/\n    @property static TimeOfDay min() @safe pure nothrow @nogc\n    {\n        return TimeOfDay.init;\n    }\n\n    @safe unittest\n    {\n        assert(TimeOfDay.min.hour == 0);\n        assert(TimeOfDay.min.minute == 0);\n        assert(TimeOfDay.min.second == 0);\n        assert(TimeOfDay.min < TimeOfDay.max);\n    }\n\n\n    /++\n        Returns one second short of midnight.\n      +/\n    @property static TimeOfDay max() @safe pure nothrow @nogc\n    {\n        auto tod = TimeOfDay.init;\n        tod._hour = maxHour;\n        tod._minute = maxMinute;\n        tod._second = maxSecond;\n\n        return tod;\n    }\n\n    @safe unittest\n    {\n        assert(TimeOfDay.max.hour == 23);\n        assert(TimeOfDay.max.minute == 59);\n        assert(TimeOfDay.max.second == 59);\n        assert(TimeOfDay.max > TimeOfDay.min);\n    }\n\n\nprivate:\n\n    /+\n        Add seconds to the time of day. Negative values will subtract. If the\n        number of seconds overflows (or underflows), then the seconds will wrap,\n        increasing (or decreasing) the number of minutes accordingly. If the\n        number of minutes overflows (or underflows), then the minutes will wrap.\n        If the number of minutes overflows(or underflows), then the hour will\n        wrap. (e.g. adding 90 seconds to 23:59:00 would result in 00:00:30).\n\n        Params:\n            seconds = The number of seconds to add to this TimeOfDay.\n      +/\n    ref TimeOfDay _addSeconds(long seconds) return @safe pure nothrow @nogc\n    {\n        import core.time : convert;\n        long hnsecs = convert!(\"seconds\", \"hnsecs\")(seconds);\n        hnsecs += convert!(\"hours\", \"hnsecs\")(_hour);\n        hnsecs += convert!(\"minutes\", \"hnsecs\")(_minute);\n        hnsecs += convert!(\"seconds\", \"hnsecs\")(_second);\n\n        hnsecs %= convert!(\"days\", \"hnsecs\")(1);\n\n        if (hnsecs < 0)\n            hnsecs += convert!(\"days\", \"hnsecs\")(1);\n\n        immutable newHours = splitUnitsFromHNSecs!\"hours\"(hnsecs);\n        immutable newMinutes = splitUnitsFromHNSecs!\"minutes\"(hnsecs);\n        immutable newSeconds = splitUnitsFromHNSecs!\"seconds\"(hnsecs);\n\n        _hour = cast(ubyte) newHours;\n        _minute = cast(ubyte) newMinutes;\n        _second = cast(ubyte) newSeconds;\n\n        return this;\n    }\n\n    @safe unittest\n    {\n        static void testTOD(TimeOfDay orig, int seconds, TimeOfDay expected, size_t line = __LINE__)\n        {\n            orig._addSeconds(seconds);\n            assert(orig == expected);\n        }\n\n        testTOD(TimeOfDay(12, 30, 33), 0, TimeOfDay(12, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), 1, TimeOfDay(12, 30, 34));\n        testTOD(TimeOfDay(12, 30, 33), 2, TimeOfDay(12, 30, 35));\n        testTOD(TimeOfDay(12, 30, 33), 3, TimeOfDay(12, 30, 36));\n        testTOD(TimeOfDay(12, 30, 33), 4, TimeOfDay(12, 30, 37));\n        testTOD(TimeOfDay(12, 30, 33), 5, TimeOfDay(12, 30, 38));\n        testTOD(TimeOfDay(12, 30, 33), 10, TimeOfDay(12, 30, 43));\n        testTOD(TimeOfDay(12, 30, 33), 15, TimeOfDay(12, 30, 48));\n        testTOD(TimeOfDay(12, 30, 33), 26, TimeOfDay(12, 30, 59));\n        testTOD(TimeOfDay(12, 30, 33), 27, TimeOfDay(12, 31, 0));\n        testTOD(TimeOfDay(12, 30, 33), 30, TimeOfDay(12, 31, 3));\n        testTOD(TimeOfDay(12, 30, 33), 59, TimeOfDay(12, 31, 32));\n        testTOD(TimeOfDay(12, 30, 33), 60, TimeOfDay(12, 31, 33));\n        testTOD(TimeOfDay(12, 30, 33), 61, TimeOfDay(12, 31, 34));\n\n        testTOD(TimeOfDay(12, 30, 33), 1766, TimeOfDay(12, 59, 59));\n        testTOD(TimeOfDay(12, 30, 33), 1767, TimeOfDay(13, 0, 0));\n        testTOD(TimeOfDay(12, 30, 33), 1768, TimeOfDay(13, 0, 1));\n        testTOD(TimeOfDay(12, 30, 33), 2007, TimeOfDay(13, 4, 0));\n        testTOD(TimeOfDay(12, 30, 33), 3599, TimeOfDay(13, 30, 32));\n        testTOD(TimeOfDay(12, 30, 33), 3600, TimeOfDay(13, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), 3601, TimeOfDay(13, 30, 34));\n        testTOD(TimeOfDay(12, 30, 33), 7200, TimeOfDay(14, 30, 33));\n\n        testTOD(TimeOfDay(12, 30, 33), -1, TimeOfDay(12, 30, 32));\n        testTOD(TimeOfDay(12, 30, 33), -2, TimeOfDay(12, 30, 31));\n        testTOD(TimeOfDay(12, 30, 33), -3, TimeOfDay(12, 30, 30));\n        testTOD(TimeOfDay(12, 30, 33), -4, TimeOfDay(12, 30, 29));\n        testTOD(TimeOfDay(12, 30, 33), -5, TimeOfDay(12, 30, 28));\n        testTOD(TimeOfDay(12, 30, 33), -10, TimeOfDay(12, 30, 23));\n        testTOD(TimeOfDay(12, 30, 33), -15, TimeOfDay(12, 30, 18));\n        testTOD(TimeOfDay(12, 30, 33), -33, TimeOfDay(12, 30, 0));\n        testTOD(TimeOfDay(12, 30, 33), -34, TimeOfDay(12, 29, 59));\n        testTOD(TimeOfDay(12, 30, 33), -35, TimeOfDay(12, 29, 58));\n        testTOD(TimeOfDay(12, 30, 33), -59, TimeOfDay(12, 29, 34));\n        testTOD(TimeOfDay(12, 30, 33), -60, TimeOfDay(12, 29, 33));\n        testTOD(TimeOfDay(12, 30, 33), -61, TimeOfDay(12, 29, 32));\n\n        testTOD(TimeOfDay(12, 30, 33), -1833, TimeOfDay(12, 0, 0));\n        testTOD(TimeOfDay(12, 30, 33), -1834, TimeOfDay(11, 59, 59));\n        testTOD(TimeOfDay(12, 30, 33), -3600, TimeOfDay(11, 30, 33));\n        testTOD(TimeOfDay(12, 30, 33), -3601, TimeOfDay(11, 30, 32));\n        testTOD(TimeOfDay(12, 30, 33), -5134, TimeOfDay(11, 4, 59));\n        testTOD(TimeOfDay(12, 30, 33), -7200, TimeOfDay(10, 30, 33));\n\n        testTOD(TimeOfDay(12, 30, 0), 1, TimeOfDay(12, 30, 1));\n        testTOD(TimeOfDay(12, 30, 0), 0, TimeOfDay(12, 30, 0));\n        testTOD(TimeOfDay(12, 30, 0), -1, TimeOfDay(12, 29, 59));\n\n        testTOD(TimeOfDay(12, 0, 0), 1, TimeOfDay(12, 0, 1));\n        testTOD(TimeOfDay(12, 0, 0), 0, TimeOfDay(12, 0, 0));\n        testTOD(TimeOfDay(12, 0, 0), -1, TimeOfDay(11, 59, 59));\n\n        testTOD(TimeOfDay(0, 0, 0), 1, TimeOfDay(0, 0, 1));\n        testTOD(TimeOfDay(0, 0, 0), 0, TimeOfDay(0, 0, 0));\n        testTOD(TimeOfDay(0, 0, 0), -1, TimeOfDay(23, 59, 59));\n\n        testTOD(TimeOfDay(23, 59, 59), 1, TimeOfDay(0, 0, 0));\n        testTOD(TimeOfDay(23, 59, 59), 0, TimeOfDay(23, 59, 59));\n        testTOD(TimeOfDay(23, 59, 59), -1, TimeOfDay(23, 59, 58));\n\n        const ctod = TimeOfDay(0, 0, 0);\n        immutable itod = TimeOfDay(0, 0, 0);\n        static assert(!__traits(compiles, ctod._addSeconds(7)));\n        static assert(!__traits(compiles, itod._addSeconds(7)));\n    }\n\n\n    /+\n        Whether the given values form a valid $(LREF TimeOfDay).\n     +/\n    static bool _valid(int hour, int minute, int second) @safe pure nothrow @nogc\n    {\n        return valid!\"hours\"(hour) && valid!\"minutes\"(minute) && valid!\"seconds\"(second);\n    }\n\n\n    @safe pure invariant()\n    {\n        import std.format : format;\n        assert(_valid(_hour, _minute, _second),\n               format(\"Invariant Failure: hour [%s] minute [%s] second [%s]\", _hour, _minute, _second));\n    }\n\n\npackage:\n\n    ubyte _hour;\n    ubyte _minute;\n    ubyte _second;\n\n    enum ubyte maxHour   = 24 - 1;\n    enum ubyte maxMinute = 60 - 1;\n    enum ubyte maxSecond = 60 - 1;\n}\n\n///\n@safe pure unittest\n{\n    import core.time : minutes, seconds;\n\n    auto t = TimeOfDay(12, 30, 0);\n\n    t += 10.minutes + 100.seconds;\n    assert(t == TimeOfDay(12, 41, 40));\n\n    assert(t.toISOExtString() == \"12:41:40\");\n    assert(t.toISOString() == \"124140\");\n\n    assert(TimeOfDay.fromISOExtString(\"15:00:00\") == TimeOfDay(15, 0, 0));\n    assert(TimeOfDay.fromISOString(\"015000\") == TimeOfDay(1, 50, 0));\n}\n\n/++\n    Returns whether the given value is valid for the given unit type when in a\n    time point. Naturally, a duration is not held to a particular range, but\n    the values in a time point are (e.g. a month must be in the range of\n    1 - 12 inclusive).\n\n    Params:\n        units = The units of time to validate.\n        value = The number to validate.\n  +/\nbool valid(string units)(int value) @safe pure nothrow @nogc\nif (units == \"months\" ||\n    units == \"hours\" ||\n    units == \"minutes\" ||\n    units == \"seconds\")\n{\n    static if (units == \"months\")\n        return value >= Month.jan && value <= Month.dec;\n    else static if (units == \"hours\")\n        return value >= 0 && value <= 23;\n    else static if (units == \"minutes\")\n        return value >= 0 && value <= 59;\n    else static if (units == \"seconds\")\n        return value >= 0 && value <= 59;\n}\n\n///\n@safe unittest\n{\n    assert(valid!\"hours\"(12));\n    assert(!valid!\"hours\"(32));\n    assert(valid!\"months\"(12));\n    assert(!valid!\"months\"(13));\n}\n\n/++\n    Returns whether the given day is valid for the given year and month.\n\n    Params:\n        units = The units of time to validate.\n        year  = The year of the day to validate.\n        month = The month of the day to validate (January is 1).\n        day   = The day to validate.\n  +/\nbool valid(string units)(int year, int month, int day) @safe pure nothrow @nogc\nif (units == \"days\")\n{\n    return day > 0 && day <= maxDay(year, month);\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(valid!\"days\"(2016, 2, 29));\n    assert(!valid!\"days\"(2016, 2, 30));\n    assert(valid!\"days\"(2017, 2, 20));\n    assert(!valid!\"days\"(2017, 2, 29));\n}\n\n\n/++\n    Params:\n        units = The units of time to validate.\n        value = The number to validate.\n        file  = The file that the $(LREF DateTimeException) will list if thrown.\n        line  = The line number that the $(LREF DateTimeException) will list if\n                thrown.\n\n    Throws:\n        $(LREF DateTimeException) if `valid!units(value)` is false.\n  +/\nvoid enforceValid(string units)(int value, string file = __FILE__, size_t line = __LINE__) @safe pure\nif (units == \"months\" ||\n    units == \"hours\" ||\n    units == \"minutes\" ||\n    units == \"seconds\")\n{\n    import std.format : format;\n\n    static if (units == \"months\")\n    {\n        if (!valid!units(value))\n            throw new DateTimeException(format(\"%s is not a valid month of the year.\", value), file, line);\n    }\n    else static if (units == \"hours\")\n    {\n        if (!valid!units(value))\n            throw new DateTimeException(format(\"%s is not a valid hour of the day.\", value), file, line);\n    }\n    else static if (units == \"minutes\")\n    {\n        if (!valid!units(value))\n            throw new DateTimeException(format(\"%s is not a valid minute of an hour.\", value), file, line);\n    }\n    else static if (units == \"seconds\")\n    {\n        if (!valid!units(value))\n            throw new DateTimeException(format(\"%s is not a valid second of a minute.\", value), file, line);\n    }\n}\n\n///\n@safe pure unittest\n{\n    import std.exception : assertThrown, assertNotThrown;\n\n    assertNotThrown(enforceValid!\"months\"(10));\n    assertNotThrown(enforceValid!\"seconds\"(40));\n\n    assertThrown!DateTimeException(enforceValid!\"months\"(0));\n    assertThrown!DateTimeException(enforceValid!\"hours\"(24));\n    assertThrown!DateTimeException(enforceValid!\"minutes\"(60));\n    assertThrown!DateTimeException(enforceValid!\"seconds\"(60));\n}\n\n\n/++\n    Because the validity of the day number depends on both on the year\n    and month of which the day is occurring, take all three variables\n    to validate the day.\n\n    Params:\n        units = The units of time to validate.\n        year  = The year of the day to validate.\n        month = The month of the day to validate.\n        day   = The day to validate.\n        file  = The file that the $(LREF DateTimeException) will list if thrown.\n        line  = The line number that the $(LREF DateTimeException) will list if\n                thrown.\n\n    Throws:\n        $(LREF DateTimeException) if $(D valid!\"days\"(year, month, day)) is false.\n  +/\nvoid enforceValid(string units)\n                 (int year, Month month, int day, string file = __FILE__, size_t line = __LINE__) @safe pure\nif (units == \"days\")\n{\n    import std.format : format;\n    if (!valid!\"days\"(year, month, day))\n        throw new DateTimeException(format(\"%s is not a valid day in %s in %s\", day, month, year), file, line);\n}\n\n///\n@safe pure unittest\n{\n    import std.exception : assertThrown, assertNotThrown;\n\n    assertNotThrown(enforceValid!\"days\"(2000, Month.jan, 1));\n    // leap year\n    assertNotThrown(enforceValid!\"days\"(2000, Month.feb, 29));\n\n    assertThrown!DateTimeException(enforceValid!\"days\"(2001, Month.feb, 29));\n    assertThrown!DateTimeException(enforceValid!\"days\"(2000, Month.jan, 32));\n    assertThrown!DateTimeException(enforceValid!\"days\"(2000, Month.apr, 31));\n}\n\n\n/++\n    Returns the number of days from the current day of the week to the given\n    day of the week. If they are the same, then the result is 0.\n\n    Params:\n        currDoW = The current day of the week.\n        dow     = The day of the week to get the number of days to.\n  +/\nint daysToDayOfWeek(DayOfWeek currDoW, DayOfWeek dow) @safe pure nothrow @nogc\n{\n    if (currDoW == dow)\n        return 0;\n    if (currDoW < dow)\n        return dow - currDoW;\n    return DayOfWeek.sat - currDoW + dow + 1;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.mon) == 0);\n    assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.sun) == 6);\n    assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.wed) == 2);\n}\n\n@safe unittest\n{\n    assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.sun) == 0);\n    assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.mon) == 1);\n    assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.tue) == 2);\n    assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.wed) == 3);\n    assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.thu) == 4);\n    assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.fri) == 5);\n    assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.sat) == 6);\n\n    assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.sun) == 6);\n    assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.mon) == 0);\n    assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.tue) == 1);\n    assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.wed) == 2);\n    assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.thu) == 3);\n    assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.fri) == 4);\n    assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.sat) == 5);\n\n    assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.sun) == 5);\n    assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.mon) == 6);\n    assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.tue) == 0);\n    assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.wed) == 1);\n    assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.thu) == 2);\n    assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.fri) == 3);\n    assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.sat) == 4);\n\n    assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.sun) == 4);\n    assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.mon) == 5);\n    assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.tue) == 6);\n    assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.wed) == 0);\n    assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.thu) == 1);\n    assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.fri) == 2);\n    assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.sat) == 3);\n\n    assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.sun) == 3);\n    assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.mon) == 4);\n    assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.tue) == 5);\n    assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.wed) == 6);\n    assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.thu) == 0);\n    assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.fri) == 1);\n    assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.sat) == 2);\n\n    assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.sun) == 2);\n    assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.mon) == 3);\n    assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.tue) == 4);\n    assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.wed) == 5);\n    assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.thu) == 6);\n    assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.fri) == 0);\n    assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.sat) == 1);\n\n    assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.sun) == 1);\n    assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.mon) == 2);\n    assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.tue) == 3);\n    assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.wed) == 4);\n    assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.thu) == 5);\n    assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.fri) == 6);\n    assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.sat) == 0);\n}\n\n\n/++\n    Returns the number of months from the current months of the year to the\n    given month of the year. If they are the same, then the result is 0.\n\n    Params:\n        currMonth = The current month of the year.\n        month     = The month of the year to get the number of months to.\n  +/\nint monthsToMonth(int currMonth, int month) @safe pure\n{\n    enforceValid!\"months\"(currMonth);\n    enforceValid!\"months\"(month);\n\n    if (currMonth == month)\n        return 0;\n    if (currMonth < month)\n        return month - currMonth;\n    return Month.dec - currMonth + month;\n}\n\n///\n@safe pure unittest\n{\n    assert(monthsToMonth(Month.jan, Month.jan) == 0);\n    assert(monthsToMonth(Month.jan, Month.dec) == 11);\n    assert(monthsToMonth(Month.jul, Month.oct) == 3);\n}\n\n@safe unittest\n{\n    assert(monthsToMonth(Month.jan, Month.jan) == 0);\n    assert(monthsToMonth(Month.jan, Month.feb) == 1);\n    assert(monthsToMonth(Month.jan, Month.mar) == 2);\n    assert(monthsToMonth(Month.jan, Month.apr) == 3);\n    assert(monthsToMonth(Month.jan, Month.may) == 4);\n    assert(monthsToMonth(Month.jan, Month.jun) == 5);\n    assert(monthsToMonth(Month.jan, Month.jul) == 6);\n    assert(monthsToMonth(Month.jan, Month.aug) == 7);\n    assert(monthsToMonth(Month.jan, Month.sep) == 8);\n    assert(monthsToMonth(Month.jan, Month.oct) == 9);\n    assert(monthsToMonth(Month.jan, Month.nov) == 10);\n    assert(monthsToMonth(Month.jan, Month.dec) == 11);\n\n    assert(monthsToMonth(Month.may, Month.jan) == 8);\n    assert(monthsToMonth(Month.may, Month.feb) == 9);\n    assert(monthsToMonth(Month.may, Month.mar) == 10);\n    assert(monthsToMonth(Month.may, Month.apr) == 11);\n    assert(monthsToMonth(Month.may, Month.may) == 0);\n    assert(monthsToMonth(Month.may, Month.jun) == 1);\n    assert(monthsToMonth(Month.may, Month.jul) == 2);\n    assert(monthsToMonth(Month.may, Month.aug) == 3);\n    assert(monthsToMonth(Month.may, Month.sep) == 4);\n    assert(monthsToMonth(Month.may, Month.oct) == 5);\n    assert(monthsToMonth(Month.may, Month.nov) == 6);\n    assert(monthsToMonth(Month.may, Month.dec) == 7);\n\n    assert(monthsToMonth(Month.oct, Month.jan) == 3);\n    assert(monthsToMonth(Month.oct, Month.feb) == 4);\n    assert(monthsToMonth(Month.oct, Month.mar) == 5);\n    assert(monthsToMonth(Month.oct, Month.apr) == 6);\n    assert(monthsToMonth(Month.oct, Month.may) == 7);\n    assert(monthsToMonth(Month.oct, Month.jun) == 8);\n    assert(monthsToMonth(Month.oct, Month.jul) == 9);\n    assert(monthsToMonth(Month.oct, Month.aug) == 10);\n    assert(monthsToMonth(Month.oct, Month.sep) == 11);\n    assert(monthsToMonth(Month.oct, Month.oct) == 0);\n    assert(monthsToMonth(Month.oct, Month.nov) == 1);\n    assert(monthsToMonth(Month.oct, Month.dec) == 2);\n\n    assert(monthsToMonth(Month.dec, Month.jan) == 1);\n    assert(monthsToMonth(Month.dec, Month.feb) == 2);\n    assert(monthsToMonth(Month.dec, Month.mar) == 3);\n    assert(monthsToMonth(Month.dec, Month.apr) == 4);\n    assert(monthsToMonth(Month.dec, Month.may) == 5);\n    assert(monthsToMonth(Month.dec, Month.jun) == 6);\n    assert(monthsToMonth(Month.dec, Month.jul) == 7);\n    assert(monthsToMonth(Month.dec, Month.aug) == 8);\n    assert(monthsToMonth(Month.dec, Month.sep) == 9);\n    assert(monthsToMonth(Month.dec, Month.oct) == 10);\n    assert(monthsToMonth(Month.dec, Month.nov) == 11);\n    assert(monthsToMonth(Month.dec, Month.dec) == 0);\n}\n\n\n/++\n    Whether the given Gregorian Year is a leap year.\n\n    Params:\n        year = The year to to be tested.\n +/\nbool yearIsLeapYear(int year) @safe pure nothrow @nogc\n{\n    if (year % 400 == 0)\n        return true;\n    if (year % 100 == 0)\n        return false;\n    return year % 4 == 0;\n}\n\n///\n@safe unittest\n{\n    foreach (year; [1, 2, 100, 2001, 2002, 2003, 2005, 2006, 2007, 2009, 2010])\n    {\n        assert(!yearIsLeapYear(year));\n        assert(!yearIsLeapYear(-year));\n    }\n\n    foreach (year; [0, 4, 8, 400, 800, 1600, 1996, 2000, 2004, 2008, 2012])\n    {\n        assert(yearIsLeapYear(year));\n        assert(yearIsLeapYear(-year));\n    }\n}\n\n@safe unittest\n{\n    import std.format : format;\n    foreach (year; [1, 2, 3, 5, 6, 7, 100, 200, 300, 500, 600, 700, 1998, 1999,\n                    2001, 2002, 2003, 2005, 2006, 2007, 2009, 2010, 2011])\n    {\n        assert(!yearIsLeapYear(year), format(\"year: %s.\", year));\n        assert(!yearIsLeapYear(-year), format(\"year: %s.\", year));\n    }\n\n    foreach (year; [0, 4, 8, 400, 800, 1600, 1996, 2000, 2004, 2008, 2012])\n    {\n        assert(yearIsLeapYear(year), format(\"year: %s.\", year));\n        assert(yearIsLeapYear(-year), format(\"year: %s.\", year));\n    }\n}\n\n\n/++\n    Whether the given type defines all of the necessary functions for it to\n    function as a time point.\n\n    1. `T` must define a static property named `min` which is the smallest\n       value of `T` as `Unqual!T`.\n\n    2. `T` must define a static property named `max` which is the largest\n       value of `T` as `Unqual!T`.\n\n    3. `T` must define an `opBinary` for addition and subtraction that\n       accepts $(REF Duration, core,time) and returns `Unqual!T`.\n\n    4. `T` must define an `opOpAssign` for addition and subtraction that\n       accepts $(REF Duration, core,time) and returns $(D ref Unqual!T).\n\n    5. `T` must define a `opBinary` for subtraction which accepts `T`\n       and returns returns $(REF Duration, core,time).\n  +/\ntemplate isTimePoint(T)\n{\n    import core.time : Duration;\n    import std.traits : FunctionAttribute, functionAttributes, Unqual;\n\n    enum isTimePoint = hasMin &&\n                       hasMax &&\n                       hasOverloadedOpBinaryWithDuration &&\n                       hasOverloadedOpAssignWithDuration &&\n                       hasOverloadedOpBinaryWithSelf &&\n                       !is(U == Duration);\n\nprivate:\n\n    alias U = Unqual!T;\n\n    enum hasMin = __traits(hasMember, T, \"min\") &&\n                  is(typeof(T.min) == U) &&\n                  is(typeof({static assert(__traits(isStaticFunction, T.min));}));\n\n    enum hasMax = __traits(hasMember, T, \"max\") &&\n                  is(typeof(T.max) == U) &&\n                  is(typeof({static assert(__traits(isStaticFunction, T.max));}));\n\n    enum hasOverloadedOpBinaryWithDuration = is(typeof(T.init + Duration.init) == U) &&\n                                             is(typeof(T.init - Duration.init) == U);\n\n    enum hasOverloadedOpAssignWithDuration = is(typeof(U.init += Duration.init) == U) &&\n                                             is(typeof(U.init -= Duration.init) == U) &&\n                                             is(typeof(\n                                             {\n                                                 alias add = U.opOpAssign!\"+\";\n                                                 alias sub = U.opOpAssign!\"-\";\n                                                 alias FA = FunctionAttribute;\n                                                 static assert((functionAttributes!add & FA.ref_) != 0);\n                                                 static assert((functionAttributes!sub & FA.ref_) != 0);\n                                             }));\n\n    enum hasOverloadedOpBinaryWithSelf = is(typeof(T.init - T.init) == Duration);\n}\n\n///\n@safe unittest\n{\n    import core.time : Duration;\n    import std.datetime.interval : Interval;\n    import std.datetime.systime : SysTime;\n\n    static assert(isTimePoint!Date);\n    static assert(isTimePoint!DateTime);\n    static assert(isTimePoint!SysTime);\n    static assert(isTimePoint!TimeOfDay);\n\n    static assert(!isTimePoint!int);\n    static assert(!isTimePoint!Duration);\n    static assert(!isTimePoint!(Interval!SysTime));\n}\n\n@safe unittest\n{\n    import core.time;\n    import std.datetime.interval;\n    import std.datetime.systime;\n    import std.meta : AliasSeq;\n\n    static foreach (TP; AliasSeq!(Date, DateTime, SysTime, TimeOfDay))\n    {\n        static assert(isTimePoint!(const TP), TP.stringof);\n        static assert(isTimePoint!(immutable TP), TP.stringof);\n    }\n\n    static foreach (T; AliasSeq!(float, string, Duration, Interval!Date, PosInfInterval!Date, NegInfInterval!Date))\n        static assert(!isTimePoint!T, T.stringof);\n}\n\n\n/++\n    Whether all of the given strings are valid units of time.\n\n    `\"nsecs\"` is not considered a valid unit of time. Nothing in std.datetime\n    can handle precision greater than hnsecs, and the few functions in core.time\n    which deal with \"nsecs\" deal with it explicitly.\n  +/\nbool validTimeUnits(string[] units...) @safe pure nothrow @nogc\n{\n    import std.algorithm.searching : canFind;\n    foreach (str; units)\n    {\n        if (!canFind(timeStrings[], str))\n            return false;\n    }\n    return true;\n}\n\n///\n@safe @nogc nothrow unittest\n{\n    assert(validTimeUnits(\"msecs\", \"seconds\", \"minutes\"));\n    assert(validTimeUnits(\"days\", \"weeks\", \"months\"));\n    assert(!validTimeUnits(\"ms\", \"seconds\", \"minutes\"));\n}\n\n\n/++\n    Compares two time unit strings. `\"years\"` are the largest units and\n    `\"hnsecs\"` are the smallest.\n\n    Returns:\n        $(BOOKTABLE,\n        $(TR $(TD this &lt; rhs) $(TD &lt; 0))\n        $(TR $(TD this == rhs) $(TD 0))\n        $(TR $(TD this &gt; rhs) $(TD &gt; 0))\n        )\n\n    Throws:\n        $(LREF DateTimeException) if either of the given strings is not a valid\n        time unit string.\n +/\nint cmpTimeUnits(string lhs, string rhs) @safe pure\n{\n    import std.algorithm.searching : countUntil;\n    import std.exception : enforce;\n    import std.format : format;\n\n    immutable indexOfLHS = countUntil(timeStrings, lhs);\n    immutable indexOfRHS = countUntil(timeStrings, rhs);\n\n    enforce!DateTimeException(indexOfLHS != -1, format(\"%s is not a valid TimeString\", lhs));\n    enforce!DateTimeException(indexOfRHS != -1, format(\"%s is not a valid TimeString\", rhs));\n\n    if (indexOfLHS < indexOfRHS)\n        return -1;\n    if (indexOfLHS > indexOfRHS)\n        return 1;\n\n    return 0;\n}\n\n///\n@safe pure unittest\n{\n    import std.exception : assertThrown;\n\n    assert(cmpTimeUnits(\"hours\", \"hours\") == 0);\n    assert(cmpTimeUnits(\"hours\", \"weeks\") < 0);\n    assert(cmpTimeUnits(\"months\", \"seconds\") > 0);\n\n    assertThrown!DateTimeException(cmpTimeUnits(\"month\", \"second\"));\n}\n\n@safe unittest\n{\n    foreach (i, outerUnits; timeStrings)\n    {\n        assert(cmpTimeUnits(outerUnits, outerUnits) == 0);\n\n        // For some reason, $ won't compile.\n        foreach (innerUnits; timeStrings[i + 1 .. timeStrings.length])\n            assert(cmpTimeUnits(outerUnits, innerUnits) == -1);\n    }\n\n    foreach (i, outerUnits; timeStrings)\n    {\n        foreach (innerUnits; timeStrings[0 .. i])\n            assert(cmpTimeUnits(outerUnits, innerUnits) == 1);\n    }\n}\n\n\n/++\n    Compares two time unit strings at compile time. `\"years\"` are the largest\n    units and `\"hnsecs\"` are the smallest.\n\n    This template is used instead of `cmpTimeUnits` because exceptions\n    can't be thrown at compile time and `cmpTimeUnits` must enforce that\n    the strings it's given are valid time unit strings. This template uses a\n    template constraint instead.\n\n    Returns:\n        $(BOOKTABLE,\n        $(TR $(TD this &lt; rhs) $(TD &lt; 0))\n        $(TR $(TD this == rhs) $(TD 0))\n        $(TR $(TD this &gt; rhs) $(TD &gt; 0))\n        )\n +/\ntemplate CmpTimeUnits(string lhs, string rhs)\nif (validTimeUnits(lhs, rhs))\n{\n    enum CmpTimeUnits = cmpTimeUnitsCTFE(lhs, rhs);\n}\n\n///\n@safe pure unittest\n{\n    static assert(CmpTimeUnits!(\"years\", \"weeks\") > 0);\n    static assert(CmpTimeUnits!(\"days\", \"days\") == 0);\n    static assert(CmpTimeUnits!(\"seconds\", \"hours\") < 0);\n}\n\n// Helper function for CmpTimeUnits.\nprivate int cmpTimeUnitsCTFE(string lhs, string rhs) @safe pure nothrow @nogc\n{\n    import std.algorithm.searching : countUntil;\n    auto tstrings = timeStrings;\n    immutable indexOfLHS = countUntil(tstrings, lhs);\n    immutable indexOfRHS = countUntil(tstrings, rhs);\n\n    if (indexOfLHS < indexOfRHS)\n        return -1;\n    if (indexOfLHS > indexOfRHS)\n        return 1;\n\n    return 0;\n}\n\n@safe unittest\n{\n    static foreach (i; 0 .. timeStrings.length)\n    {\n        static assert(CmpTimeUnits!(timeStrings[i], timeStrings[i]) == 0);\n\n        static foreach (next; timeStrings[i + 1 .. $])\n            static assert(CmpTimeUnits!(timeStrings[i], next) == -1);\n\n        static foreach (prev; timeStrings[0 .. i])\n            static assert(CmpTimeUnits!(timeStrings[i], prev) == 1);\n    }\n}\n\n\npackage:\n\n\n/+\n    Array of the short (three letter) names of each month.\n  +/\nimmutable string[12] _monthNames = [\"Jan\",\n                                    \"Feb\",\n                                    \"Mar\",\n                                    \"Apr\",\n                                    \"May\",\n                                    \"Jun\",\n                                    \"Jul\",\n                                    \"Aug\",\n                                    \"Sep\",\n                                    \"Oct\",\n                                    \"Nov\",\n                                    \"Dec\"];\n\n/+\n    The maximum valid Day in the given month in the given year.\n\n    Params:\n        year  = The year to get the day for.\n        month = The month of the Gregorian Calendar to get the day for.\n +/\nubyte maxDay(int year, int month) @safe pure nothrow @nogc\nin\n{\n    assert(valid!\"months\"(month));\n}\ndo\n{\n    switch (month)\n    {\n        case Month.jan, Month.mar, Month.may, Month.jul, Month.aug, Month.oct, Month.dec:\n            return 31;\n        case Month.feb:\n            return yearIsLeapYear(year) ? 29 : 28;\n        case Month.apr, Month.jun, Month.sep, Month.nov:\n            return 30;\n        default:\n            assert(0, \"Invalid month.\");\n    }\n}\n\n@safe unittest\n{\n    // Test A.D.\n    assert(maxDay(1999, 1) == 31);\n    assert(maxDay(1999, 2) == 28);\n    assert(maxDay(1999, 3) == 31);\n    assert(maxDay(1999, 4) == 30);\n    assert(maxDay(1999, 5) == 31);\n    assert(maxDay(1999, 6) == 30);\n    assert(maxDay(1999, 7) == 31);\n    assert(maxDay(1999, 8) == 31);\n    assert(maxDay(1999, 9) == 30);\n    assert(maxDay(1999, 10) == 31);\n    assert(maxDay(1999, 11) == 30);\n    assert(maxDay(1999, 12) == 31);\n\n    assert(maxDay(2000, 1) == 31);\n    assert(maxDay(2000, 2) == 29);\n    assert(maxDay(2000, 3) == 31);\n    assert(maxDay(2000, 4) == 30);\n    assert(maxDay(2000, 5) == 31);\n    assert(maxDay(2000, 6) == 30);\n    assert(maxDay(2000, 7) == 31);\n    assert(maxDay(2000, 8) == 31);\n    assert(maxDay(2000, 9) == 30);\n    assert(maxDay(2000, 10) == 31);\n    assert(maxDay(2000, 11) == 30);\n    assert(maxDay(2000, 12) == 31);\n\n    // Test B.C.\n    assert(maxDay(-1999, 1) == 31);\n    assert(maxDay(-1999, 2) == 28);\n    assert(maxDay(-1999, 3) == 31);\n    assert(maxDay(-1999, 4) == 30);\n    assert(maxDay(-1999, 5) == 31);\n    assert(maxDay(-1999, 6) == 30);\n    assert(maxDay(-1999, 7) == 31);\n    assert(maxDay(-1999, 8) == 31);\n    assert(maxDay(-1999, 9) == 30);\n    assert(maxDay(-1999, 10) == 31);\n    assert(maxDay(-1999, 11) == 30);\n    assert(maxDay(-1999, 12) == 31);\n\n    assert(maxDay(-2000, 1) == 31);\n    assert(maxDay(-2000, 2) == 29);\n    assert(maxDay(-2000, 3) == 31);\n    assert(maxDay(-2000, 4) == 30);\n    assert(maxDay(-2000, 5) == 31);\n    assert(maxDay(-2000, 6) == 30);\n    assert(maxDay(-2000, 7) == 31);\n    assert(maxDay(-2000, 8) == 31);\n    assert(maxDay(-2000, 9) == 30);\n    assert(maxDay(-2000, 10) == 31);\n    assert(maxDay(-2000, 11) == 30);\n    assert(maxDay(-2000, 12) == 31);\n}\n\n/+\n    Splits out a particular unit from hnsecs and gives the value for that\n    unit and the remaining hnsecs. It really shouldn't be used unless unless\n    all units larger than the given units have already been split out.\n\n    Params:\n        units  = The units to split out.\n        hnsecs = The current total hnsecs. Upon returning, it is the hnsecs left\n                 after splitting out the given units.\n\n    Returns:\n        The number of the given units from converting hnsecs to those units.\n  +/\nlong splitUnitsFromHNSecs(string units)(ref long hnsecs) @safe pure nothrow @nogc\nif (validTimeUnits(units) && CmpTimeUnits!(units, \"months\") < 0)\n{\n    import core.time : convert;\n    immutable value = convert!(\"hnsecs\", units)(hnsecs);\n    hnsecs -= convert!(units, \"hnsecs\")(value);\n    return value;\n}\n\n@safe unittest\n{\n    auto hnsecs = 2595000000007L;\n    immutable days = splitUnitsFromHNSecs!\"days\"(hnsecs);\n    assert(days == 3);\n    assert(hnsecs == 3000000007);\n\n    immutable minutes = splitUnitsFromHNSecs!\"minutes\"(hnsecs);\n    assert(minutes == 5);\n    assert(hnsecs == 7);\n}\n\n\n/+\n    Returns the day of the week for the given day of the Gregorian Calendar.\n\n    Params:\n        day = The day of the Gregorian Calendar for which to get the day of\n              the week.\n  +/\nDayOfWeek getDayOfWeek(int day) @safe pure nothrow @nogc\n{\n    // January 1st, 1 A.D. was a Monday\n    if (day >= 0)\n        return cast(DayOfWeek)(day % 7);\n    else\n    {\n        immutable dow = cast(DayOfWeek)((day % 7) + 7);\n\n        if (dow == 7)\n            return DayOfWeek.sun;\n        else\n            return dow;\n    }\n}\n\n@safe unittest\n{\n    import std.datetime.systime : SysTime;\n\n    // Test A.D.\n    assert(getDayOfWeek(SysTime(Date(1, 1, 1)).dayOfGregorianCal) == DayOfWeek.mon);\n    assert(getDayOfWeek(SysTime(Date(1, 1, 2)).dayOfGregorianCal) == DayOfWeek.tue);\n    assert(getDayOfWeek(SysTime(Date(1, 1, 3)).dayOfGregorianCal) == DayOfWeek.wed);\n    assert(getDayOfWeek(SysTime(Date(1, 1, 4)).dayOfGregorianCal) == DayOfWeek.thu);\n    assert(getDayOfWeek(SysTime(Date(1, 1, 5)).dayOfGregorianCal) == DayOfWeek.fri);\n    assert(getDayOfWeek(SysTime(Date(1, 1, 6)).dayOfGregorianCal) == DayOfWeek.sat);\n    assert(getDayOfWeek(SysTime(Date(1, 1, 7)).dayOfGregorianCal) == DayOfWeek.sun);\n    assert(getDayOfWeek(SysTime(Date(1, 1, 8)).dayOfGregorianCal) == DayOfWeek.mon);\n    assert(getDayOfWeek(SysTime(Date(1, 1, 9)).dayOfGregorianCal) == DayOfWeek.tue);\n    assert(getDayOfWeek(SysTime(Date(2, 1, 1)).dayOfGregorianCal) == DayOfWeek.tue);\n    assert(getDayOfWeek(SysTime(Date(3, 1, 1)).dayOfGregorianCal) == DayOfWeek.wed);\n    assert(getDayOfWeek(SysTime(Date(4, 1, 1)).dayOfGregorianCal) == DayOfWeek.thu);\n    assert(getDayOfWeek(SysTime(Date(5, 1, 1)).dayOfGregorianCal) == DayOfWeek.sat);\n    assert(getDayOfWeek(SysTime(Date(2000, 1, 1)).dayOfGregorianCal) == DayOfWeek.sat);\n    assert(getDayOfWeek(SysTime(Date(2010, 8, 22)).dayOfGregorianCal) == DayOfWeek.sun);\n    assert(getDayOfWeek(SysTime(Date(2010, 8, 23)).dayOfGregorianCal) == DayOfWeek.mon);\n    assert(getDayOfWeek(SysTime(Date(2010, 8, 24)).dayOfGregorianCal) == DayOfWeek.tue);\n    assert(getDayOfWeek(SysTime(Date(2010, 8, 25)).dayOfGregorianCal) == DayOfWeek.wed);\n    assert(getDayOfWeek(SysTime(Date(2010, 8, 26)).dayOfGregorianCal) == DayOfWeek.thu);\n    assert(getDayOfWeek(SysTime(Date(2010, 8, 27)).dayOfGregorianCal) == DayOfWeek.fri);\n    assert(getDayOfWeek(SysTime(Date(2010, 8, 28)).dayOfGregorianCal) == DayOfWeek.sat);\n    assert(getDayOfWeek(SysTime(Date(2010, 8, 29)).dayOfGregorianCal) == DayOfWeek.sun);\n\n    // Test B.C.\n    assert(getDayOfWeek(SysTime(Date(0, 12, 31)).dayOfGregorianCal) == DayOfWeek.sun);\n    assert(getDayOfWeek(SysTime(Date(0, 12, 30)).dayOfGregorianCal) == DayOfWeek.sat);\n    assert(getDayOfWeek(SysTime(Date(0, 12, 29)).dayOfGregorianCal) == DayOfWeek.fri);\n    assert(getDayOfWeek(SysTime(Date(0, 12, 28)).dayOfGregorianCal) == DayOfWeek.thu);\n    assert(getDayOfWeek(SysTime(Date(0, 12, 27)).dayOfGregorianCal) == DayOfWeek.wed);\n    assert(getDayOfWeek(SysTime(Date(0, 12, 26)).dayOfGregorianCal) == DayOfWeek.tue);\n    assert(getDayOfWeek(SysTime(Date(0, 12, 25)).dayOfGregorianCal) == DayOfWeek.mon);\n    assert(getDayOfWeek(SysTime(Date(0, 12, 24)).dayOfGregorianCal) == DayOfWeek.sun);\n    assert(getDayOfWeek(SysTime(Date(0, 12, 23)).dayOfGregorianCal) == DayOfWeek.sat);\n}\n\n\nprivate:\n\nenum daysInYear     = 365;  // The number of days in a non-leap year.\nenum daysInLeapYear = 366;  // The numbef or days in a leap year.\nenum daysIn4Years   = daysInYear * 3 + daysInLeapYear;  // Number of days in 4 years.\nenum daysIn100Years = daysIn4Years * 25 - 1;  // The number of days in 100 years.\nenum daysIn400Years = daysIn100Years * 4 + 1; // The number of days in 400 years.\n\n/+\n    Array of integers representing the last days of each month in a year.\n  +/\nimmutable int[13] lastDayNonLeap = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];\n\n/+\n    Array of integers representing the last days of each month in a leap year.\n  +/\nimmutable int[13] lastDayLeap = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366];\n\n\n/+\n    Returns the string representation of the given month.\n  +/\nstring monthToString(Month month) @safe pure\n{\n    import std.format : format;\n    assert(month >= Month.jan && month <= Month.dec, format(\"Invalid month: %s\", month));\n    return _monthNames[month - Month.jan];\n}\n\n@safe unittest\n{\n    assert(monthToString(Month.jan) == \"Jan\");\n    assert(monthToString(Month.feb) == \"Feb\");\n    assert(monthToString(Month.mar) == \"Mar\");\n    assert(monthToString(Month.apr) == \"Apr\");\n    assert(monthToString(Month.may) == \"May\");\n    assert(monthToString(Month.jun) == \"Jun\");\n    assert(monthToString(Month.jul) == \"Jul\");\n    assert(monthToString(Month.aug) == \"Aug\");\n    assert(monthToString(Month.sep) == \"Sep\");\n    assert(monthToString(Month.oct) == \"Oct\");\n    assert(monthToString(Month.nov) == \"Nov\");\n    assert(monthToString(Month.dec) == \"Dec\");\n}\n\n\n/+\n    Returns the Month corresponding to the given string.\n\n    Params:\n        monthStr = The string representation of the month to get the Month for.\n\n    Throws:\n        $(REF DateTimeException,std,datetime,date) if the given month is not a\n        valid month string.\n  +/\nMonth monthFromString(T)(T monthStr) @safe pure\nif (isSomeString!T)\n{\n    import std.format : format;\n    switch (monthStr)\n    {\n        case \"Jan\":\n            return Month.jan;\n        case \"Feb\":\n            return Month.feb;\n        case \"Mar\":\n            return Month.mar;\n        case \"Apr\":\n            return Month.apr;\n        case \"May\":\n            return Month.may;\n        case \"Jun\":\n            return Month.jun;\n        case \"Jul\":\n            return Month.jul;\n        case \"Aug\":\n            return Month.aug;\n        case \"Sep\":\n            return Month.sep;\n        case \"Oct\":\n            return Month.oct;\n        case \"Nov\":\n            return Month.nov;\n        case \"Dec\":\n            return Month.dec;\n        default:\n            throw new DateTimeException(format!\"Invalid month %s\"(monthStr));\n    }\n}\n\n@safe unittest\n{\n    import std.conv : to;\n    import std.traits : EnumMembers;\n    foreach (badStr; [\"Ja\", \"Janu\", \"Januar\", \"Januarys\", \"JJanuary\", \"JANUARY\",\n                      \"JAN\", \"january\", \"jaNuary\", \"jaN\", \"jaNuaRy\", \"jAn\"])\n    {\n        assertThrown!DateTimeException(monthFromString(badStr), badStr);\n    }\n\n    foreach (month; EnumMembers!Month)\n    {\n        assert(monthFromString(monthToString(month)) == month, month.to!string);\n    }\n}\n\n\nversion (unittest)\n{\nprivate:\n    // All of these helper arrays are sorted in ascending order.\n    auto testYearsBC = [-1999, -1200, -600, -4, -1, 0];\n    auto testYearsAD = [1, 4, 1000, 1999, 2000, 2012];\n\n    // I'd use a Tuple, but I get forward reference errors if I try.\n    struct MonthDay\n    {\n        Month month;\n        short day;\n\n        this(int m, short d)\n        {\n            month = cast(Month) m;\n            day = d;\n        }\n    }\n\n    MonthDay[] testMonthDays = [MonthDay(1, 1),\n                                MonthDay(1, 2),\n                                MonthDay(3, 17),\n                                MonthDay(7, 4),\n                                MonthDay(10, 27),\n                                MonthDay(12, 30),\n                                MonthDay(12, 31)];\n\n    auto testDays = [1, 2, 9, 10, 16, 20, 25, 28, 29, 30, 31];\n\n    auto testTODs = [TimeOfDay(0, 0, 0),\n                     TimeOfDay(0, 0, 1),\n                     TimeOfDay(0, 1, 0),\n                     TimeOfDay(1, 0, 0),\n                     TimeOfDay(13, 13, 13),\n                     TimeOfDay(23, 59, 59)];\n\n    auto testHours = [0, 1, 12, 22, 23];\n    auto testMinSecs = [0, 1, 30, 58, 59];\n\n    // Throwing exceptions is incredibly expensive, so we want to use a smaller\n    // set of values for tests using assertThrown.\n    auto testTODsThrown = [TimeOfDay(0, 0, 0),\n                           TimeOfDay(13, 13, 13),\n                           TimeOfDay(23, 59, 59)];\n\n    Date[] testDatesBC;\n    Date[] testDatesAD;\n\n    DateTime[] testDateTimesBC;\n    DateTime[] testDateTimesAD;\n\n    // I'd use a Tuple, but I get forward reference errors if I try.\n    struct GregDay { int day; Date date; }\n    auto testGregDaysBC = [GregDay(-1_373_427, Date(-3760, 9, 7)), // Start of the Hebrew Calendar\n                           GregDay(-735_233, Date(-2012, 1, 1)),\n                           GregDay(-735_202, Date(-2012, 2, 1)),\n                           GregDay(-735_175, Date(-2012, 2, 28)),\n                           GregDay(-735_174, Date(-2012, 2, 29)),\n                           GregDay(-735_173, Date(-2012, 3, 1)),\n                           GregDay(-734_502, Date(-2010, 1, 1)),\n                           GregDay(-734_472, Date(-2010, 1, 31)),\n                           GregDay(-734_471, Date(-2010, 2, 1)),\n                           GregDay(-734_444, Date(-2010, 2, 28)),\n                           GregDay(-734_443, Date(-2010, 3, 1)),\n                           GregDay(-734_413, Date(-2010, 3, 31)),\n                           GregDay(-734_412, Date(-2010, 4, 1)),\n                           GregDay(-734_383, Date(-2010, 4, 30)),\n                           GregDay(-734_382, Date(-2010, 5, 1)),\n                           GregDay(-734_352, Date(-2010, 5, 31)),\n                           GregDay(-734_351, Date(-2010, 6, 1)),\n                           GregDay(-734_322, Date(-2010, 6, 30)),\n                           GregDay(-734_321, Date(-2010, 7, 1)),\n                           GregDay(-734_291, Date(-2010, 7, 31)),\n                           GregDay(-734_290, Date(-2010, 8, 1)),\n                           GregDay(-734_260, Date(-2010, 8, 31)),\n                           GregDay(-734_259, Date(-2010, 9, 1)),\n                           GregDay(-734_230, Date(-2010, 9, 30)),\n                           GregDay(-734_229, Date(-2010, 10, 1)),\n                           GregDay(-734_199, Date(-2010, 10, 31)),\n                           GregDay(-734_198, Date(-2010, 11, 1)),\n                           GregDay(-734_169, Date(-2010, 11, 30)),\n                           GregDay(-734_168, Date(-2010, 12, 1)),\n                           GregDay(-734_139, Date(-2010, 12, 30)),\n                           GregDay(-734_138, Date(-2010, 12, 31)),\n                           GregDay(-731_215, Date(-2001, 1, 1)),\n                           GregDay(-730_850, Date(-2000, 1, 1)),\n                           GregDay(-730_849, Date(-2000, 1, 2)),\n                           GregDay(-730_486, Date(-2000, 12, 30)),\n                           GregDay(-730_485, Date(-2000, 12, 31)),\n                           GregDay(-730_484, Date(-1999, 1, 1)),\n                           GregDay(-694_690, Date(-1901, 1, 1)),\n                           GregDay(-694_325, Date(-1900, 1, 1)),\n                           GregDay(-585_118, Date(-1601, 1, 1)),\n                           GregDay(-584_753, Date(-1600, 1, 1)),\n                           GregDay(-584_388, Date(-1600, 12, 31)),\n                           GregDay(-584_387, Date(-1599, 1, 1)),\n                           GregDay(-365_972, Date(-1001, 1, 1)),\n                           GregDay(-365_607, Date(-1000, 1, 1)),\n                           GregDay(-183_351, Date(-501, 1, 1)),\n                           GregDay(-182_986, Date(-500, 1, 1)),\n                           GregDay(-182_621, Date(-499, 1, 1)),\n                           GregDay(-146_827, Date(-401, 1, 1)),\n                           GregDay(-146_462, Date(-400, 1, 1)),\n                           GregDay(-146_097, Date(-400, 12, 31)),\n                           GregDay(-110_302, Date(-301, 1, 1)),\n                           GregDay(-109_937, Date(-300, 1, 1)),\n                           GregDay(-73_778, Date(-201, 1, 1)),\n                           GregDay(-73_413, Date(-200, 1, 1)),\n                           GregDay(-38_715, Date(-105, 1, 1)),\n                           GregDay(-37_254, Date(-101, 1, 1)),\n                           GregDay(-36_889, Date(-100, 1, 1)),\n                           GregDay(-36_524, Date(-99, 1, 1)),\n                           GregDay(-36_160, Date(-99, 12, 31)),\n                           GregDay(-35_794, Date(-97, 1, 1)),\n                           GregDay(-18_627, Date(-50, 1, 1)),\n                           GregDay(-18_262, Date(-49, 1, 1)),\n                           GregDay(-3652, Date(-9, 1, 1)),\n                           GregDay(-2191, Date(-5, 1, 1)),\n                           GregDay(-1827, Date(-5, 12, 31)),\n                           GregDay(-1826, Date(-4, 1, 1)),\n                           GregDay(-1825, Date(-4, 1, 2)),\n                           GregDay(-1462, Date(-4, 12, 30)),\n                           GregDay(-1461, Date(-4, 12, 31)),\n                           GregDay(-1460, Date(-3, 1, 1)),\n                           GregDay(-1096, Date(-3, 12, 31)),\n                           GregDay(-1095, Date(-2, 1, 1)),\n                           GregDay(-731, Date(-2, 12, 31)),\n                           GregDay(-730, Date(-1, 1, 1)),\n                           GregDay(-367, Date(-1, 12, 30)),\n                           GregDay(-366, Date(-1, 12, 31)),\n                           GregDay(-365, Date(0, 1, 1)),\n                           GregDay(-31, Date(0, 11, 30)),\n                           GregDay(-30, Date(0, 12, 1)),\n                           GregDay(-1, Date(0, 12, 30)),\n                           GregDay(0, Date(0, 12, 31))];\n\n    auto testGregDaysAD = [GregDay(1, Date(1, 1, 1)),\n                           GregDay(2, Date(1, 1, 2)),\n                           GregDay(32, Date(1, 2, 1)),\n                           GregDay(365, Date(1, 12, 31)),\n                           GregDay(366, Date(2, 1, 1)),\n                           GregDay(731, Date(3, 1, 1)),\n                           GregDay(1096, Date(4, 1, 1)),\n                           GregDay(1097, Date(4, 1, 2)),\n                           GregDay(1460, Date(4, 12, 30)),\n                           GregDay(1461, Date(4, 12, 31)),\n                           GregDay(1462, Date(5, 1, 1)),\n                           GregDay(17_898, Date(50, 1, 1)),\n                           GregDay(35_065, Date(97, 1, 1)),\n                           GregDay(36_160, Date(100, 1, 1)),\n                           GregDay(36_525, Date(101, 1, 1)),\n                           GregDay(37_986, Date(105, 1, 1)),\n                           GregDay(72_684, Date(200, 1, 1)),\n                           GregDay(73_049, Date(201, 1, 1)),\n                           GregDay(109_208, Date(300, 1, 1)),\n                           GregDay(109_573, Date(301, 1, 1)),\n                           GregDay(145_732, Date(400, 1, 1)),\n                           GregDay(146_098, Date(401, 1, 1)),\n                           GregDay(182_257, Date(500, 1, 1)),\n                           GregDay(182_622, Date(501, 1, 1)),\n                           GregDay(364_878, Date(1000, 1, 1)),\n                           GregDay(365_243, Date(1001, 1, 1)),\n                           GregDay(584_023, Date(1600, 1, 1)),\n                           GregDay(584_389, Date(1601, 1, 1)),\n                           GregDay(693_596, Date(1900, 1, 1)),\n                           GregDay(693_961, Date(1901, 1, 1)),\n                           GregDay(729_755, Date(1999, 1, 1)),\n                           GregDay(730_120, Date(2000, 1, 1)),\n                           GregDay(730_121, Date(2000, 1, 2)),\n                           GregDay(730_484, Date(2000, 12, 30)),\n                           GregDay(730_485, Date(2000, 12, 31)),\n                           GregDay(730_486, Date(2001, 1, 1)),\n                           GregDay(733_773, Date(2010, 1, 1)),\n                           GregDay(733_774, Date(2010, 1, 2)),\n                           GregDay(733_803, Date(2010, 1, 31)),\n                           GregDay(733_804, Date(2010, 2, 1)),\n                           GregDay(733_831, Date(2010, 2, 28)),\n                           GregDay(733_832, Date(2010, 3, 1)),\n                           GregDay(733_862, Date(2010, 3, 31)),\n                           GregDay(733_863, Date(2010, 4, 1)),\n                           GregDay(733_892, Date(2010, 4, 30)),\n                           GregDay(733_893, Date(2010, 5, 1)),\n                           GregDay(733_923, Date(2010, 5, 31)),\n                           GregDay(733_924, Date(2010, 6, 1)),\n                           GregDay(733_953, Date(2010, 6, 30)),\n                           GregDay(733_954, Date(2010, 7, 1)),\n                           GregDay(733_984, Date(2010, 7, 31)),\n                           GregDay(733_985, Date(2010, 8, 1)),\n                           GregDay(734_015, Date(2010, 8, 31)),\n                           GregDay(734_016, Date(2010, 9, 1)),\n                           GregDay(734_045, Date(2010, 9, 30)),\n                           GregDay(734_046, Date(2010, 10, 1)),\n                           GregDay(734_076, Date(2010, 10, 31)),\n                           GregDay(734_077, Date(2010, 11, 1)),\n                           GregDay(734_106, Date(2010, 11, 30)),\n                           GregDay(734_107, Date(2010, 12, 1)),\n                           GregDay(734_136, Date(2010, 12, 30)),\n                           GregDay(734_137, Date(2010, 12, 31)),\n                           GregDay(734_503, Date(2012, 1, 1)),\n                           GregDay(734_534, Date(2012, 2, 1)),\n                           GregDay(734_561, Date(2012, 2, 28)),\n                           GregDay(734_562, Date(2012, 2, 29)),\n                           GregDay(734_563, Date(2012, 3, 1)),\n                           GregDay(734_858, Date(2012, 12, 21))];\n\n    // I'd use a Tuple, but I get forward reference errors if I try.\n    struct DayOfYear { int day; MonthDay md; }\n    auto testDaysOfYear = [DayOfYear(1, MonthDay(1, 1)),\n                           DayOfYear(2, MonthDay(1, 2)),\n                           DayOfYear(3, MonthDay(1, 3)),\n                           DayOfYear(31, MonthDay(1, 31)),\n                           DayOfYear(32, MonthDay(2, 1)),\n                           DayOfYear(59, MonthDay(2, 28)),\n                           DayOfYear(60, MonthDay(3, 1)),\n                           DayOfYear(90, MonthDay(3, 31)),\n                           DayOfYear(91, MonthDay(4, 1)),\n                           DayOfYear(120, MonthDay(4, 30)),\n                           DayOfYear(121, MonthDay(5, 1)),\n                           DayOfYear(151, MonthDay(5, 31)),\n                           DayOfYear(152, MonthDay(6, 1)),\n                           DayOfYear(181, MonthDay(6, 30)),\n                           DayOfYear(182, MonthDay(7, 1)),\n                           DayOfYear(212, MonthDay(7, 31)),\n                           DayOfYear(213, MonthDay(8, 1)),\n                           DayOfYear(243, MonthDay(8, 31)),\n                           DayOfYear(244, MonthDay(9, 1)),\n                           DayOfYear(273, MonthDay(9, 30)),\n                           DayOfYear(274, MonthDay(10, 1)),\n                           DayOfYear(304, MonthDay(10, 31)),\n                           DayOfYear(305, MonthDay(11, 1)),\n                           DayOfYear(334, MonthDay(11, 30)),\n                           DayOfYear(335, MonthDay(12, 1)),\n                           DayOfYear(363, MonthDay(12, 29)),\n                           DayOfYear(364, MonthDay(12, 30)),\n                           DayOfYear(365, MonthDay(12, 31))];\n\n    auto testDaysOfLeapYear = [DayOfYear(1, MonthDay(1, 1)),\n                               DayOfYear(2, MonthDay(1, 2)),\n                               DayOfYear(3, MonthDay(1, 3)),\n                               DayOfYear(31, MonthDay(1, 31)),\n                               DayOfYear(32, MonthDay(2, 1)),\n                               DayOfYear(59, MonthDay(2, 28)),\n                               DayOfYear(60, MonthDay(2, 29)),\n                               DayOfYear(61, MonthDay(3, 1)),\n                               DayOfYear(91, MonthDay(3, 31)),\n                               DayOfYear(92, MonthDay(4, 1)),\n                               DayOfYear(121, MonthDay(4, 30)),\n                               DayOfYear(122, MonthDay(5, 1)),\n                               DayOfYear(152, MonthDay(5, 31)),\n                               DayOfYear(153, MonthDay(6, 1)),\n                               DayOfYear(182, MonthDay(6, 30)),\n                               DayOfYear(183, MonthDay(7, 1)),\n                               DayOfYear(213, MonthDay(7, 31)),\n                               DayOfYear(214, MonthDay(8, 1)),\n                               DayOfYear(244, MonthDay(8, 31)),\n                               DayOfYear(245, MonthDay(9, 1)),\n                               DayOfYear(274, MonthDay(9, 30)),\n                               DayOfYear(275, MonthDay(10, 1)),\n                               DayOfYear(305, MonthDay(10, 31)),\n                               DayOfYear(306, MonthDay(11, 1)),\n                               DayOfYear(335, MonthDay(11, 30)),\n                               DayOfYear(336, MonthDay(12, 1)),\n                               DayOfYear(364, MonthDay(12, 29)),\n                               DayOfYear(365, MonthDay(12, 30)),\n                               DayOfYear(366, MonthDay(12, 31))];\n\n    void initializeTests() @safe\n    {\n        foreach (year; testYearsBC)\n        {\n            foreach (md; testMonthDays)\n                testDatesBC ~= Date(year, md.month, md.day);\n        }\n\n        foreach (year; testYearsAD)\n        {\n            foreach (md; testMonthDays)\n                testDatesAD ~= Date(year, md.month, md.day);\n        }\n\n        foreach (dt; testDatesBC)\n        {\n            foreach (tod; testTODs)\n                testDateTimesBC ~= DateTime(dt, tod);\n        }\n\n        foreach (dt; testDatesAD)\n        {\n            foreach (tod; testTODs)\n                testDateTimesAD ~= DateTime(dt, tod);\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/datetime/interval.d",
    "content": "// Written in the D programming language\n\n/++\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Main types) $(TD\n    $(LREF Interval)\n    $(LREF Direction)\n))\n$(TR $(TD Special intervals) $(TD\n    $(LREF everyDayOfWeek)\n    $(LREF everyMonth)\n    $(LREF everyDuration)\n))\n$(TR $(TD Special intervals) $(TD\n    $(LREF NegInfInterval)\n    $(LREF PosInfInterval)\n))\n$(TR $(TD Underlying ranges) $(TD\n    $(LREF IntervalRange)\n    $(LREF NegInfIntervalRange)\n    $(LREF PosInfIntervalRange)\n))\n$(TR $(TD Flags) $(TD\n    $(LREF PopFirst)\n))\n)\n\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n    Source:    $(PHOBOSSRC std/datetime/interval.d)\n+/\nmodule std.datetime.interval;\n\nimport core.time : Duration, dur;\nimport std.datetime.date : AllowDayOverflow, DateTimeException, daysToDayOfWeek,\n                           DayOfWeek, isTimePoint, Month;\nimport std.exception : enforce;\nimport std.range.primitives : isOutputRange;\nimport std.traits : isIntegral, Unqual;\nimport std.typecons : Flag;\n\nversion (unittest) import std.exception : assertThrown;\n\n\n/++\n    Indicates a direction in time. One example of its use is $(LREF Interval)'s\n    $(LREF expand) function which uses it to indicate whether the interval\n    should be expanded backwards (into the past), forwards (into the future), or\n    both.\n  +/\nenum Direction\n{\n    /// Backward.\n    bwd,\n\n    /// Forward.\n    fwd,\n\n    /// Both backward and forward.\n    both\n}\n\n\n/++\n    Used to indicate whether `popFront` should be called immediately upon\n    creating a range. The idea is that for some functions used to generate a\n    range for an interval, `front` is not necessarily a time point which\n    would ever be generated by the range (e.g. if the range were every Sunday\n    within an interval, but the interval started on a Monday), so there needs\n    to be a way to deal with that. To get the first time point in the range to\n    match what the function generates, then use `PopFirst.yes` to indicate\n    that the range should have `popFront` called on it before the range is\n    returned so that `front` is a time point which the function would\n    generate. To let the first time point not match the generator function,\n    use `PopFront.no`.\n\n    For instance, if the function used to generate a range of time points\n    generated successive Easters (i.e. you're iterating over all of the Easters\n    within the interval), the initial date probably isn't an Easter. Using\n    `PopFirst.yes` would tell the function which returned the range that\n    `popFront` was to be called so that front would then be an Easter - the\n    next one generated by the function (which when iterating forward would be\n    the Easter following the original `front`, while when iterating backward,\n    it would be the Easter prior to the original `front`). If\n    `PopFirst.no` were used, then `front` would remain the original time\n    point and it would not necessarily be a time point which would be generated\n    by the range-generating function (which in many cases is exactly what is\n    desired - e.g. if iterating over every day starting at the beginning of the\n    interval).\n\n    If set to `PopFirst.no`, then popFront is not called before returning\n    the range.\n\n    Otherwise, if set to `PopFirst.yes`, then popFront is called before\n    returning the range.\n  +/\nalias PopFirst = Flag!\"popFirst\";\n\n\n/++\n    Represents an interval of time.\n\n    An `Interval` has a starting point and an end point. The interval of time\n    is therefore the time starting at the starting point up to, but not\n    including, the end point. e.g.\n\n    $(BOOKTABLE,\n    $(TR $(TD [January 5th, 2010 - March 10th, 2010$(RPAREN)))\n    $(TR $(TD [05:00:30 - 12:00:00$(RPAREN)))\n    $(TR $(TD [1982-01-04T08:59:00 - 2010-07-04T12:00:00$(RPAREN)))\n    )\n\n    A range can be obtained from an `Interval`, allowing iteration over\n    that interval, with the exact time points which are iterated over depending\n    on the function which generates the range.\n  +/\nstruct Interval(TP)\n{\npublic:\n\n    /++\n        Params:\n            begin = The time point which begins the interval.\n            end   = The time point which ends (but is not included in) the\n                    interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if $(D_PARAM end) is\n            before $(D_PARAM begin).\n\n        Example:\n        --------------------\n        Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n        --------------------\n      +/\n    this(U)(scope const TP begin, scope const U end) pure\n        if (is(Unqual!TP == Unqual!U))\n    {\n        if (!_valid(begin, end))\n            throw new DateTimeException(\"Arguments would result in an invalid Interval.\");\n        _begin = cast(TP) begin;\n        _end = cast(TP) end;\n    }\n\n\n    /++\n        Params:\n            begin    = The time point which begins the interval.\n            duration = The duration from the starting point to the end point.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the resulting\n            `end` is before `begin`.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), dur!\"days\"(3)) ==\n               Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5)));\n        --------------------\n      +/\n    this(D)(scope const TP begin, scope const D duration) pure\n        if (__traits(compiles, begin + duration))\n    {\n        _begin = cast(TP) begin;\n        _end = begin + duration;\n        if (!_valid(_begin, _end))\n            throw new DateTimeException(\"Arguments would result in an invalid Interval.\");\n    }\n\n\n    /++\n        Params:\n            rhs = The $(LREF Interval) to assign to this one.\n      +/\n    ref Interval opAssign(const ref Interval rhs) pure nothrow\n    {\n        _begin = cast(TP) rhs._begin;\n        _end = cast(TP) rhs._end;\n        return this;\n    }\n\n\n    /++\n        Params:\n            rhs = The $(LREF Interval) to assign to this one.\n      +/\n    ref Interval opAssign(Interval rhs) pure nothrow\n    {\n        _begin = cast(TP) rhs._begin;\n        _end = cast(TP) rhs._end;\n        return this;\n    }\n\n\n    /++\n        The starting point of the interval. It is included in the interval.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin ==\n               Date(1996, 1, 2));\n        --------------------\n      +/\n    @property TP begin() const pure nothrow\n    {\n        return cast(TP) _begin;\n    }\n\n\n    /++\n        The starting point of the interval. It is included in the interval.\n\n        Params:\n            timePoint = The time point to set `begin` to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the resulting\n            interval would be invalid.\n      +/\n    @property void begin(TP timePoint) pure\n    {\n        if (!_valid(timePoint, _end))\n            throw new DateTimeException(\"Arguments would result in an invalid Interval.\");\n        _begin = timePoint;\n    }\n\n\n    /++\n        The end point of the interval. It is excluded from the interval.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end ==\n               Date(2012, 3, 1));\n        --------------------\n      +/\n    @property TP end() const pure nothrow\n    {\n        return cast(TP) _end;\n    }\n\n\n    /++\n        The end point of the interval. It is excluded from the interval.\n\n        Params:\n            timePoint = The time point to set end to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the resulting\n            interval would be invalid.\n      +/\n    @property void end(TP timePoint) pure\n    {\n        if (!_valid(_begin, timePoint))\n            throw new DateTimeException(\"Arguments would result in an invalid Interval.\");\n        _end = timePoint;\n    }\n\n\n    /++\n        Returns the duration between `begin` and `end`.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length ==\n               dur!\"days\"(5903));\n        --------------------\n      +/\n    @property auto length() const pure nothrow\n    {\n        return _end - _begin;\n    }\n\n\n    /++\n        Whether the interval's length is 0, that is, whether $(D begin == end).\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty);\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty);\n        --------------------\n      +/\n    @property bool empty() const pure nothrow\n    {\n        return _begin == _end;\n    }\n\n\n    /++\n        Whether the given time point is within this interval.\n\n        Params:\n            timePoint = The time point to check for inclusion in this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(\n                    Date(1994, 12, 24)));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(\n                    Date(2000, 1, 5)));\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(\n                    Date(2012, 3, 1)));\n        --------------------\n      +/\n    bool contains(scope const TP timePoint) const pure\n    {\n        _enforceNotEmpty();\n        return timePoint >= _begin && timePoint < _end;\n    }\n\n\n    /++\n        Whether the given interval is completely within this interval.\n\n        Params:\n            interval = The interval to check for inclusion in this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if either interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(\n                    Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(\n                    Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(\n                    Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));\n        --------------------\n      +/\n    bool contains(scope const Interval interval) const pure\n    {\n        _enforceNotEmpty();\n        interval._enforceNotEmpty();\n        return interval._begin >= _begin &&\n               interval._begin < _end &&\n               interval._end <= _end;\n    }\n\n\n    /++\n        Whether the given interval is completely within this interval.\n\n        Always returns false (unless this interval is empty), because an\n        interval going to positive infinity can never be contained in a finite\n        interval.\n\n        Params:\n            interval = The interval to check for inclusion in this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(\n                    PosInfInterval!Date(Date(1999, 5, 4))));\n        --------------------\n      +/\n    bool contains(scope const PosInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return false;\n    }\n\n\n    /++\n        Whether the given interval is completely within this interval.\n\n        Always returns false (unless this interval is empty), because an\n        interval beginning at negative infinity can never be contained in a\n        finite interval.\n\n        Params:\n            interval = The interval to check for inclusion in this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(\n                    NegInfInterval!Date(Date(1996, 5, 4))));\n        --------------------\n      +/\n    bool contains(scope const NegInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return false;\n    }\n\n\n    /++\n        Whether this interval is before the given time point.\n\n        Params:\n            timePoint = The time point to check whether this interval is before\n                        it.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n                    Date(1994, 12, 24)));\n\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n                    Date(2000, 1, 5)));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n                    Date(2012, 3, 1)));\n        --------------------\n      +/\n    bool isBefore(scope const TP timePoint) const pure\n    {\n        _enforceNotEmpty();\n        return _end <= timePoint;\n    }\n\n\n    /++\n        Whether this interval is before the given interval and does not\n        intersect with it.\n\n        Params:\n            interval = The interval to check for against this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if either interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n                    Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n                    Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n                    Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1))));\n        --------------------\n      +/\n    bool isBefore(scope const Interval interval) const pure\n    {\n        _enforceNotEmpty();\n        interval._enforceNotEmpty();\n        return _end <= interval._begin;\n    }\n\n\n    /++\n        Whether this interval is before the given interval and does not\n        intersect with it.\n\n        Params:\n            interval = The interval to check for against this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n                    PosInfInterval!Date(Date(1999, 5, 4))));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n                    PosInfInterval!Date(Date(2013, 3, 7))));\n        --------------------\n      +/\n    bool isBefore(scope const PosInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return _end <= interval._begin;\n    }\n\n\n    /++\n        Whether this interval is before the given interval and does not\n        intersect with it.\n\n        Always returns false (unless this interval is empty) because a finite\n        interval can never be before an interval beginning at negative infinity.\n\n        Params:\n            interval = The interval to check for against this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n                    NegInfInterval!Date(Date(1996, 5, 4))));\n        --------------------\n      +/\n    bool isBefore(scope const NegInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return false;\n    }\n\n\n    /++\n        Whether this interval is after the given time point.\n\n        Params:\n            timePoint = The time point to check whether this interval is after\n                        it.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(\n                    Date(1994, 12, 24)));\n\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(\n                    Date(2000, 1, 5)));\n\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(\n                    Date(2012, 3, 1)));\n        --------------------\n      +/\n    bool isAfter(scope const TP timePoint) const pure\n    {\n        _enforceNotEmpty();\n        return timePoint < _begin;\n    }\n\n\n    /++\n        Whether this interval is after the given interval and does not intersect\n        it.\n\n        Params:\n            interval = The interval to check against this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if either interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(\n                    Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(\n                    Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(\n                    Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));\n        --------------------\n      +/\n    bool isAfter(scope const Interval interval) const pure\n    {\n        _enforceNotEmpty();\n        interval._enforceNotEmpty();\n        return _begin >= interval._end;\n    }\n\n\n    /++\n        Whether this interval is after the given interval and does not intersect\n        it.\n\n        Always returns false (unless this interval is empty) because a finite\n        interval can never be after an interval going to positive infinity.\n\n        Params:\n            interval = The interval to check against this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(\n                    PosInfInterval!Date(Date(1999, 5, 4))));\n        --------------------\n      +/\n    bool isAfter(scope const PosInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return false;\n    }\n\n\n    /++\n        Whether this interval is after the given interval and does not intersect\n        it.\n\n        Params:\n            interval = The interval to check against this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(\n                    NegInfInterval!Date(Date(1996, 1, 2))));\n        --------------------\n      +/\n    bool isAfter(scope const NegInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return _begin >= interval._end;\n    }\n\n\n    /++\n        Whether the given interval overlaps this interval.\n\n        Params:\n            interval = The interval to check for intersection with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if either interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(\n                    Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(\n                    Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(\n                    Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));\n        --------------------\n      +/\n    bool intersects(scope const Interval interval) const pure\n    {\n        _enforceNotEmpty();\n        interval._enforceNotEmpty();\n        return interval._begin < _end && interval._end > _begin;\n    }\n\n\n    /++\n        Whether the given interval overlaps this interval.\n\n        Params:\n            interval = The interval to check for intersection with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(\n                    PosInfInterval!Date(Date(1999, 5, 4))));\n\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(\n                    PosInfInterval!Date(Date(2012, 3, 1))));\n        --------------------\n      +/\n    bool intersects(scope const PosInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return _end > interval._begin;\n    }\n\n\n    /++\n        Whether the given interval overlaps this interval.\n\n        Params:\n            interval = The interval to check for intersection with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(\n                    NegInfInterval!Date(Date(1996, 1, 2))));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(\n                    NegInfInterval!Date(Date(2000, 1, 2))));\n        --------------------\n      +/\n    bool intersects(scope const NegInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return _begin < interval._end;\n    }\n\n\n    /++\n        Returns the intersection of two intervals\n\n        Params:\n            interval = The interval to intersect with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect or if either interval is empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n                    Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n               Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2)));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n                    Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==\n               Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17)));\n        --------------------\n      +/\n    Interval intersection(scope const Interval interval) const\n    {\n        import std.format : format;\n\n        enforce(this.intersects(interval),\n                new DateTimeException(format(\"%s and %s do not intersect.\", this, interval)));\n\n        auto begin = _begin > interval._begin ? _begin : interval._begin;\n        auto end = _end < interval._end ? _end : interval._end;\n\n        return Interval(begin, end);\n    }\n\n\n    /++\n        Returns the intersection of two intervals\n\n        Params:\n            interval = The interval to intersect with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect or if this interval is empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n                    PosInfInterval!Date(Date(1990, 7, 6))) ==\n               Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n                    PosInfInterval!Date(Date(1999, 1, 12))) ==\n               Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));\n        --------------------\n      +/\n    Interval intersection(scope const PosInfInterval!TP interval) const\n    {\n        import std.format : format;\n\n        enforce(this.intersects(interval),\n                new DateTimeException(format(\"%s and %s do not intersect.\", this, interval)));\n\n        return Interval(_begin > interval._begin ? _begin : interval._begin, _end);\n    }\n\n\n    /++\n        Returns the intersection of two intervals\n\n        Params:\n            interval = The interval to intersect with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect or if this interval is empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n                    NegInfInterval!Date(Date(1999, 7, 6))) ==\n               Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6)));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n                    NegInfInterval!Date(Date(2013, 1, 12))) ==\n               Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));\n        --------------------\n      +/\n    Interval intersection(scope const NegInfInterval!TP interval) const\n    {\n        import std.format : format;\n\n        enforce(this.intersects(interval),\n                new DateTimeException(format(\"%s and %s do not intersect.\", this, interval)));\n\n        return Interval(_begin, _end < interval._end ? _end : interval._end);\n    }\n\n\n    /++\n        Whether the given interval is adjacent to this interval.\n\n        Params:\n            interval = The interval to check whether its adjecent to this\n                       interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if either interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(\n                    Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2))));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(\n                    Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17))));\n\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(\n                    Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1))));\n        --------------------\n      +/\n    bool isAdjacent(scope const Interval interval) const pure\n    {\n        _enforceNotEmpty();\n        interval._enforceNotEmpty();\n        return _begin == interval._end || _end == interval._begin;\n    }\n\n\n    /++\n        Whether the given interval is adjacent to this interval.\n\n        Params:\n            interval = The interval to check whether its adjecent to this\n                       interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(\n                    PosInfInterval!Date(Date(1999, 5, 4))));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(\n                    PosInfInterval!Date(Date(2012, 3, 1))));\n        --------------------\n      +/\n    bool isAdjacent(scope const PosInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return _end == interval._begin;\n    }\n\n\n    /++\n        Whether the given interval is adjacent to this interval.\n\n        Params:\n            interval = The interval to check whether its adjecent to this\n                       interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(\n                    NegInfInterval!Date(Date(1996, 1, 2))));\n\n        assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(\n                    NegInfInterval!Date(Date(2000, 1, 2))));\n        --------------------\n      +/\n    bool isAdjacent(scope const NegInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return _begin == interval._end;\n    }\n\n\n    /++\n        Returns the union of two intervals\n\n        Params:\n            interval = The interval to merge with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect and are not adjacent or if either interval is empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(\n                    Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n               Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(\n                    Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) ==\n               Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));\n        --------------------\n      +/\n    Interval merge(scope const Interval interval) const\n    {\n        import std.format : format;\n\n        enforce(this.isAdjacent(interval) || this.intersects(interval),\n                new DateTimeException(format(\"%s and %s are not adjacent and do not intersect.\", this, interval)));\n\n        auto begin = _begin < interval._begin ? _begin : interval._begin;\n        auto end = _end > interval._end ? _end : interval._end;\n\n        return Interval(begin, end);\n    }\n\n\n    /++\n        Returns the union of two intervals\n\n        Params:\n            interval = The interval to merge with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect and are not adjacent or if this interval is empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(\n                    PosInfInterval!Date(Date(1990, 7, 6))) ==\n               PosInfInterval!Date(Date(1990, 7 , 6)));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(\n                    PosInfInterval!Date(Date(2012, 3, 1))) ==\n               PosInfInterval!Date(Date(1996, 1 , 2)));\n        --------------------\n      +/\n    PosInfInterval!TP merge(scope const PosInfInterval!TP interval) const\n    {\n        import std.format : format;\n\n        enforce(this.isAdjacent(interval) || this.intersects(interval),\n                new DateTimeException(format(\"%s and %s are not adjacent and do not intersect.\", this, interval)));\n\n        return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin);\n    }\n\n\n    /++\n        Returns the union of two intervals\n\n        Params:\n            interval = The interval to merge with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect and are not adjacent or if this interval is empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(\n                    NegInfInterval!Date(Date(1996, 1, 2))) ==\n               NegInfInterval!Date(Date(2012, 3 , 1)));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(\n                    NegInfInterval!Date(Date(2013, 1, 12))) ==\n               NegInfInterval!Date(Date(2013, 1 , 12)));\n        --------------------\n      +/\n    NegInfInterval!TP merge(scope const NegInfInterval!TP interval) const\n    {\n        import std.format : format;\n\n        enforce(this.isAdjacent(interval) || this.intersects(interval),\n                new DateTimeException(format(\"%s and %s are not adjacent and do not intersect.\", this, interval)));\n\n        return NegInfInterval!TP(_end > interval._end ? _end : interval._end);\n    }\n\n\n    /++\n        Returns an interval that covers from the earliest time point of two\n        intervals up to (but not including) the latest time point of two\n        intervals.\n\n        Params:\n            interval = The interval to create a span together with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if either interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(\n                    Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) ==\n               Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(\n                    Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) ==\n               Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));\n        --------------------\n      +/\n    Interval span(scope const Interval interval) const pure\n    {\n        _enforceNotEmpty();\n        interval._enforceNotEmpty();\n\n        auto begin = _begin < interval._begin ? _begin : interval._begin;\n        auto end = _end > interval._end ? _end : interval._end;\n\n        return Interval(begin, end);\n    }\n\n\n    /++\n        Returns an interval that covers from the earliest time point of two\n        intervals up to (but not including) the latest time point of two\n        intervals.\n\n        Params:\n            interval = The interval to create a span together with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(\n                    PosInfInterval!Date(Date(1990, 7, 6))) ==\n               PosInfInterval!Date(Date(1990, 7 , 6)));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(\n                    PosInfInterval!Date(Date(2050, 1, 1))) ==\n               PosInfInterval!Date(Date(1996, 1 , 2)));\n        --------------------\n      +/\n    PosInfInterval!TP span(scope const PosInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin);\n    }\n\n\n    /++\n        Returns an interval that covers from the earliest time point of two\n        intervals up to (but not including) the latest time point of two\n        intervals.\n\n        Params:\n            interval = The interval to create a span together with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Example:\n        --------------------\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(\n                    NegInfInterval!Date(Date(1602, 5, 21))) ==\n               NegInfInterval!Date(Date(2012, 3 , 1)));\n\n        assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(\n                    NegInfInterval!Date(Date(2013, 1, 12))) ==\n               NegInfInterval!Date(Date(2013, 1 , 12)));\n        --------------------\n      +/\n    NegInfInterval!TP span(scope const NegInfInterval!TP interval) const pure\n    {\n        _enforceNotEmpty();\n        return NegInfInterval!TP(_end > interval._end ? _end : interval._end);\n    }\n\n\n    /++\n        Shifts the interval forward or backwards in time by the given duration\n        (a positive duration shifts the interval forward; a negative duration\n        shifts it backward). Effectively, it does $(D begin += duration) and\n        $(D end += duration).\n\n        Params:\n            duration = The duration to shift the interval by.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) this interval is empty\n            or if the resulting interval would be invalid.\n\n        Example:\n        --------------------\n        auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));\n        auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));\n\n        interval1.shift(dur!\"days\"(50));\n        assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25)));\n\n        interval2.shift(dur!\"days\"(-50));\n        assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15)));\n        --------------------\n      +/\n    void shift(D)(D duration) pure\n        if (__traits(compiles, begin + duration))\n    {\n        _enforceNotEmpty();\n\n        auto begin = _begin + duration;\n        auto end = _end + duration;\n\n        if (!_valid(begin, end))\n            throw new DateTimeException(\"Argument would result in an invalid Interval.\");\n\n        _begin = begin;\n        _end = end;\n    }\n\n\n    static if (__traits(compiles, begin.add!\"months\"(1)) &&\n               __traits(compiles, begin.add!\"years\"(1)))\n    {\n        /++\n            Shifts the interval forward or backwards in time by the given number\n            of years and/or months (a positive number of years and months shifts\n            the interval forward; a negative number shifts it backward).\n            It adds the years the given years and months to both begin and end.\n            It effectively calls `add!\"years\"()` and then `add!\"months\"()`\n            on begin and end with the given number of years and months.\n\n            Params:\n                years         = The number of years to shift the interval by.\n                months        = The number of months to shift the interval by.\n                allowOverflow = Whether the days should be allowed to overflow\n                                on `begin` and `end`, causing their month\n                                to increment.\n\n            Throws:\n                $(REF DateTimeException,std,datetime,date) if this interval is\n                empty or if the resulting interval would be invalid.\n\n            Example:\n            --------------------\n            auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n            auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n\n            interval1.shift(2);\n            assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1)));\n\n            interval2.shift(-2);\n            assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1)));\n            --------------------\n          +/\n        void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)\n            if (isIntegral!T)\n        {\n            _enforceNotEmpty();\n\n            auto begin = _begin;\n            auto end = _end;\n\n            begin.add!\"years\"(years, allowOverflow);\n            begin.add!\"months\"(months, allowOverflow);\n            end.add!\"years\"(years, allowOverflow);\n            end.add!\"months\"(months, allowOverflow);\n\n            enforce(_valid(begin, end), new DateTimeException(\"Argument would result in an invalid Interval.\"));\n\n            _begin = begin;\n            _end = end;\n        }\n    }\n\n\n    /++\n        Expands the interval forwards and/or backwards in time. Effectively,\n        it does $(D begin -= duration) and/or $(D end += duration). Whether\n        it expands forwards and/or backwards in time is determined by\n        $(D_PARAM dir).\n\n        Params:\n            duration = The duration to expand the interval by.\n            dir      = The direction in time to expand the interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) this interval is empty\n            or if the resulting interval would be invalid.\n\n        Example:\n        --------------------\n        auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n        auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n\n        interval1.expand(2);\n        assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1)));\n\n        interval2.expand(-2);\n        assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1)));\n        --------------------\n      +/\n    void expand(D)(D duration, Direction dir = Direction.both) pure\n        if (__traits(compiles, begin + duration))\n    {\n        _enforceNotEmpty();\n\n        switch (dir)\n        {\n            case Direction.both:\n            {\n                auto begin = _begin - duration;\n                auto end = _end + duration;\n\n                if (!_valid(begin, end))\n                    throw new DateTimeException(\"Argument would result in an invalid Interval.\");\n\n                _begin = begin;\n                _end = end;\n\n                return;\n            }\n            case Direction.fwd:\n            {\n                auto end = _end + duration;\n\n                if (!_valid(_begin, end))\n                    throw new DateTimeException(\"Argument would result in an invalid Interval.\");\n                _end = end;\n\n                return;\n            }\n            case Direction.bwd:\n            {\n                auto begin = _begin - duration;\n\n                if (!_valid(begin, _end))\n                    throw new DateTimeException(\"Argument would result in an invalid Interval.\");\n                _begin = begin;\n\n                return;\n            }\n            default:\n                assert(0, \"Invalid Direction.\");\n        }\n    }\n\n    static if (__traits(compiles, begin.add!\"months\"(1)) &&\n               __traits(compiles, begin.add!\"years\"(1)))\n    {\n        /++\n            Expands the interval forwards and/or backwards in time. Effectively,\n            it subtracts the given number of months/years from `begin` and\n            adds them to `end`. Whether it expands forwards and/or backwards\n            in time is determined by $(D_PARAM dir).\n\n            Params:\n                years         = The number of years to expand the interval by.\n                months        = The number of months to expand the interval by.\n                allowOverflow = Whether the days should be allowed to overflow\n                                on `begin` and `end`, causing their month\n                                to increment.\n                dir           = The direction in time to expand the interval.\n\n            Throws:\n                $(REF DateTimeException,std,datetime,date) if this interval is\n                empty or if the resulting interval would be invalid.\n\n            Example:\n            --------------------\n            auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n            auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n\n            interval1.expand(2);\n            assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1)));\n\n            interval2.expand(-2);\n            assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1)));\n            --------------------\n          +/\n        void expand(T)(T years,\n                       T months = 0,\n                       AllowDayOverflow allowOverflow = AllowDayOverflow.yes,\n                       Direction dir = Direction.both)\n        if (isIntegral!T)\n        {\n            _enforceNotEmpty();\n\n            switch (dir)\n            {\n                case Direction.both:\n                {\n                    auto begin = _begin;\n                    auto end = _end;\n\n                    begin.add!\"years\"(-years, allowOverflow);\n                    begin.add!\"months\"(-months, allowOverflow);\n                    end.add!\"years\"(years, allowOverflow);\n                    end.add!\"months\"(months, allowOverflow);\n\n                    enforce(_valid(begin, end), new DateTimeException(\"Argument would result in an invalid Interval.\"));\n                    _begin = begin;\n                    _end = end;\n\n                    return;\n                }\n                case Direction.fwd:\n                {\n                    auto end = _end;\n\n                    end.add!\"years\"(years, allowOverflow);\n                    end.add!\"months\"(months, allowOverflow);\n\n                    enforce(_valid(_begin, end),\n                            new DateTimeException(\"Argument would result in an invalid Interval.\"));\n                    _end = end;\n\n                    return;\n                }\n                case Direction.bwd:\n                {\n                    auto begin = _begin;\n\n                    begin.add!\"years\"(-years, allowOverflow);\n                    begin.add!\"months\"(-months, allowOverflow);\n\n                    enforce(_valid(begin, _end),\n                            new DateTimeException(\"Argument would result in an invalid Interval.\"));\n                    _begin = begin;\n\n                    return;\n                }\n                default:\n                    assert(0, \"Invalid Direction.\");\n            }\n        }\n    }\n\n\n    /++\n        Returns a range which iterates forward over the interval, starting\n        at `begin`, using $(D_PARAM func) to generate each successive time\n        point.\n\n        The range's `front` is the interval's `begin`. $(D_PARAM func) is\n        used to generate the next `front` when `popFront` is called. If\n        $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called\n        before the range is returned (so that `front` is a time point which\n        $(D_PARAM func) would generate).\n\n        If $(D_PARAM func) ever generates a time point less than or equal to the\n        current `front` of the range, then a\n        $(REF DateTimeException,std,datetime,date) will be thrown. The range\n        will be empty and iteration complete when $(D_PARAM func) generates a\n        time point equal to or beyond the `end` of the interval.\n\n        There are helper functions in this module which generate common\n        delegates to pass to `fwdRange`. Their documentation starts with\n        \"Range-generating function,\" making them easily searchable.\n\n        Params:\n            func     = The function used to generate the time points of the\n                       range over the interval.\n            popFirst = Whether `popFront` should be called on the range\n                       before returning it.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Warning:\n            $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)\n            would be a function pointer to a pure function, but forcing\n            $(D_PARAM func) to be pure is far too restrictive to be useful, and\n            in order to have the ease of use of having functions which generate\n            functions to pass to `fwdRange`, $(D_PARAM func) must be a\n            delegate.\n\n            If $(D_PARAM func) retains state which changes as it is called, then\n            some algorithms will not work correctly, because the range's\n            `save` will have failed to have really saved the range's state.\n            To avoid such bugs, don't pass a delegate which is\n            not logically pure to `fwdRange`. If $(D_PARAM func) is given the\n            same time point with two different calls, it must return the same\n            result both times.\n\n            Of course, none of the functions in this module have this problem,\n            so it's only relevant if when creating a custom delegate.\n\n        Example:\n        --------------------\n        auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));\n        auto func = delegate (scope const Date date) // For iterating over even-numbered days.\n                    {\n                        if ((date.day & 1) == 0)\n                            return date + dur!\"days\"(2);\n\n                        return date + dur!\"days\"(1);\n                    };\n        auto range = interval.fwdRange(func);\n\n        // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).\n        assert(range.front == Date(2010, 9, 1));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 2));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 4));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 6));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 8));\n\n        range.popFront();\n        assert(range.empty);\n        --------------------\n      +/\n    IntervalRange!(TP, Direction.fwd) fwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const\n    {\n        _enforceNotEmpty();\n\n        auto range = IntervalRange!(TP, Direction.fwd)(this, func);\n\n        if (popFirst == PopFirst.yes)\n            range.popFront();\n\n        return range;\n    }\n\n\n    /++\n        Returns a range which iterates backwards over the interval, starting\n        at `end`, using $(D_PARAM func) to generate each successive time\n        point.\n\n        The range's `front` is the interval's `end`. $(D_PARAM func) is\n        used to generate the next `front` when `popFront` is called. If\n        $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called\n        before the range is returned (so that `front` is a time point which\n        $(D_PARAM func) would generate).\n\n        If $(D_PARAM func) ever generates a time point greater than or equal to\n        the current `front` of the range, then a\n        $(REF DateTimeException,std,datetime,date) will be thrown. The range\n        will be empty and iteration complete when $(D_PARAM func) generates a\n        time point equal to or less than the `begin` of the interval.\n\n        There are helper functions in this module which generate common\n        delegates to pass to `bwdRange`. Their documentation starts with\n        \"Range-generating function,\" making them easily searchable.\n\n        Params:\n            func     = The function used to generate the time points of the\n                       range over the interval.\n            popFirst = Whether `popFront` should be called on the range\n                       before returning it.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Warning:\n            $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)\n            would be a function pointer to a pure function, but forcing\n            $(D_PARAM func) to be pure is far too restrictive to be useful, and\n            in order to have the ease of use of having functions which generate\n            functions to pass to `fwdRange`, $(D_PARAM func) must be a\n            delegate.\n\n            If $(D_PARAM func) retains state which changes as it is called, then\n            some algorithms will not work correctly, because the range's\n            `save` will have failed to have really saved the range's state.\n            To avoid such bugs, don't pass a delegate which is\n            not logically pure to `fwdRange`. If $(D_PARAM func) is given the\n            same time point with two different calls, it must return the same\n            result both times.\n\n            Of course, none of the functions in this module have this problem,\n            so it's only relevant for custom delegates.\n\n        Example:\n        --------------------\n        auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));\n        auto func = delegate (scope const Date date) // For iterating over even-numbered days.\n                    {\n                        if ((date.day & 1) == 0)\n                            return date - dur!\"days\"(2);\n\n                        return date - dur!\"days\"(1);\n                    };\n        auto range = interval.bwdRange(func);\n\n        // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).\n        assert(range.front == Date(2010, 9, 9));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 8));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 6));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 4));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 2));\n\n        range.popFront();\n        assert(range.empty);\n        --------------------\n      +/\n    IntervalRange!(TP, Direction.bwd) bwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const\n    {\n        _enforceNotEmpty();\n\n        auto range = IntervalRange!(TP, Direction.bwd)(this, func);\n\n        if (popFirst == PopFirst.yes)\n            range.popFront();\n\n        return range;\n    }\n\n    /++\n        Converts this interval to a string.\n        Params:\n            w = A `char` accepting\n            $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toString() const @safe nothrow\n    {\n        import std.array : appender;\n        auto app = appender!string();\n        try\n            toString(app);\n        catch (Exception e)\n            assert(0, \"toString() threw.\");\n        return app.data;\n    }\n\n    /// ditto\n    void toString(Writer)(ref Writer w) const\n    if (isOutputRange!(Writer, char))\n    {\n        import std.range.primitives : put;\n        put(w, '[');\n        _begin.toString(w);\n        put(w, \" - \");\n        _end.toString(w);\n        put(w, ')');\n    }\n\nprivate:\n    /+\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n      +/\n    void _enforceNotEmpty(size_t line = __LINE__) const pure\n    {\n        if (empty)\n            throw new DateTimeException(\"Invalid operation for an empty Interval.\", __FILE__, line);\n    }\n\n\n    /+\n        Whether the given values form a valid time interval.\n\n        Params:\n            begin = The starting point of the interval.\n            end   = The end point of the interval.\n     +/\n    static bool _valid(scope const TP begin, scope const TP end) pure nothrow @trusted\n    {\n        return begin <= end;\n    }\n\n\n    pure invariant()\n    {\n        assert(_valid(_begin, _end), \"Invariant Failure: begin is not before or equal to end.\");\n    }\n\n\n    TP _begin;\n    TP _end;\n}\n\n// Test Interval's constructors.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 1, 1), Date(1, 1, 1)));\n\n    Interval!Date(Date.init, Date.init);\n    Interval!TimeOfDay(TimeOfDay.init, TimeOfDay.init);\n    Interval!DateTime(DateTime.init, DateTime.init);\n    Interval!SysTime(SysTime(0), SysTime(0));\n\n    Interval!DateTime(DateTime.init, dur!\"days\"(7));\n\n    // Verify Examples.\n    Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n    assert(Interval!Date(Date(1996, 1, 2), dur!\"weeks\"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 23)));\n    assert(Interval!Date(Date(1996, 1, 2), dur!\"days\"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5)));\n    assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!\"hours\"(3)) ==\n           Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 15, 0, 0)));\n    assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!\"minutes\"(3)) ==\n           Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 3, 0)));\n    assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!\"seconds\"(3)) ==\n           Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3)));\n    assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!\"msecs\"(3000)) ==\n           Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3)));\n}\n\n// Test Interval's begin.\n@safe unittest\n{\n    import std.datetime.date;\n\n    assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).begin == Date(1, 1, 1));\n    assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).begin == Date(2010, 1, 1));\n    assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).begin == Date(1997, 12, 31));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    assert(cInterval.begin == Date(2010, 7, 4));\n    assert(iInterval.begin == Date(2010, 7, 4));\n\n    // Verify Examples.\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == Date(1996, 1, 2));\n}\n\n// Test Interval's end.\n@safe unittest\n{\n    import std.datetime.date;\n\n    assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1));\n    assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1));\n    assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).end == Date(1998, 1, 1));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    assert(cInterval.end == Date(2012, 1, 7));\n    assert(iInterval.end == Date(2012, 1, 7));\n\n    // Verify Examples.\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == Date(2012, 3, 1));\n}\n\n// Test Interval's length.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).length == dur!\"days\"(0));\n    assert(Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).length == dur!\"days\"(90));\n    assert(Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).length == dur!\"seconds\"(42_727));\n    assert(Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).length ==\n           dur!\"seconds\"(129_127));\n    assert(Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)),SysTime(DateTime(2010, 1, 2, 12, 22, 7))).length ==\n           dur!\"seconds\"(129_127));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    assert(cInterval.length != Duration.zero);\n    assert(iInterval.length != Duration.zero);\n\n    // Verify Examples.\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == dur!\"days\"(5903));\n}\n\n// Test Interval's empty.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).empty);\n    assert(!Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).empty);\n    assert(!Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).empty);\n    assert(!Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).empty);\n    assert(!Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)), SysTime(DateTime(2010, 1, 2, 12, 22, 7))).empty);\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    assert(!cInterval.empty);\n    assert(!iInterval.empty);\n\n    // Verify Examples.\n    assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty);\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty);\n}\n\n// Test Interval's contains(time point).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).contains(Date(2010, 7, 4)));\n\n    assert(!interval.contains(Date(2009, 7, 4)));\n    assert(!interval.contains(Date(2010, 7, 3)));\n    assert(interval.contains(Date(2010, 7, 4)));\n    assert(interval.contains(Date(2010, 7, 5)));\n    assert(interval.contains(Date(2011, 7, 1)));\n    assert(interval.contains(Date(2012, 1, 6)));\n    assert(!interval.contains(Date(2012, 1, 7)));\n    assert(!interval.contains(Date(2012, 1, 8)));\n    assert(!interval.contains(Date(2013, 1, 7)));\n\n    const cdate = Date(2010, 7, 6);\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    assert(interval.contains(cdate));\n    assert(cInterval.contains(cdate));\n    assert(iInterval.contains(cdate));\n\n    // Verify Examples.\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(1994, 12, 24)));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2000, 1, 5)));\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2012, 3, 1)));\n}\n\n// Test Interval's contains(Interval).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    assertThrown!DateTimeException(interval.contains(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).contains(interval));\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4),dur!\"days\"(0)).contains(\n                                       Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(interval.contains(interval));\n    assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(!interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(!interval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(!interval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).contains(interval));\n    assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).contains(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).contains(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).contains(interval));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).contains(interval));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).contains(interval));\n    assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).contains(interval));\n    assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).contains(interval));\n    assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).contains(interval));\n    assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).contains(interval));\n    assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).contains(interval));\n    assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).contains(interval));\n\n    assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(interval.contains(interval));\n    assert(interval.contains(cInterval));\n    assert(interval.contains(iInterval));\n    assert(!interval.contains(posInfInterval));\n    assert(!interval.contains(cPosInfInterval));\n    assert(!interval.contains(iPosInfInterval));\n    assert(!interval.contains(negInfInterval));\n    assert(!interval.contains(cNegInfInterval));\n    assert(!interval.contains(iNegInfInterval));\n    assert(cInterval.contains(interval));\n    assert(cInterval.contains(cInterval));\n    assert(cInterval.contains(iInterval));\n    assert(!cInterval.contains(posInfInterval));\n    assert(!cInterval.contains(cPosInfInterval));\n    assert(!cInterval.contains(iPosInfInterval));\n    assert(!cInterval.contains(negInfInterval));\n    assert(!cInterval.contains(cNegInfInterval));\n    assert(!cInterval.contains(iNegInfInterval));\n    assert(iInterval.contains(interval));\n    assert(iInterval.contains(cInterval));\n    assert(iInterval.contains(iInterval));\n    assert(!iInterval.contains(posInfInterval));\n    assert(!iInterval.contains(cPosInfInterval));\n    assert(!iInterval.contains(iPosInfInterval));\n    assert(!iInterval.contains(negInfInterval));\n    assert(!iInterval.contains(cNegInfInterval));\n    assert(!iInterval.contains(iNegInfInterval));\n\n    // Verify Examples.\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(\n               Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(\n               Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(\n               Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));\n\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4))));\n\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4))));\n}\n\n// Test Interval's isBefore(time point).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).isBefore(Date(2010, 7, 4)));\n\n    assert(!interval.isBefore(Date(2009, 7, 3)));\n    assert(!interval.isBefore(Date(2010, 7, 3)));\n    assert(!interval.isBefore(Date(2010, 7, 4)));\n    assert(!interval.isBefore(Date(2010, 7, 5)));\n    assert(!interval.isBefore(Date(2011, 7, 1)));\n    assert(!interval.isBefore(Date(2012, 1, 6)));\n    assert(interval.isBefore(Date(2012, 1, 7)));\n    assert(interval.isBefore(Date(2012, 1, 8)));\n    assert(interval.isBefore(Date(2013, 1, 7)));\n\n    const cdate = Date(2010, 7, 6);\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    assert(!interval.isBefore(cdate));\n    assert(!cInterval.isBefore(cdate));\n    assert(!iInterval.isBefore(cdate));\n\n    // Verify Examples.\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(1994, 12, 24)));\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2000, 1, 5)));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2012, 3, 1)));\n}\n\n// Test Interval's isBefore(Interval).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    assertThrown!DateTimeException(interval.isBefore(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).isBefore(interval));\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).isBefore(\n                                       Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(!interval.isBefore(interval));\n    assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(interval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(interval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isBefore(interval));\n    assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isBefore(interval));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isBefore(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isBefore(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isBefore(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isBefore(interval));\n    assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isBefore(interval));\n    assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isBefore(interval));\n    assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isBefore(interval));\n    assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isBefore(interval));\n    assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isBefore(interval));\n    assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isBefore(interval));\n\n    assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(!interval.isBefore(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!interval.isBefore(interval));\n    assert(!interval.isBefore(cInterval));\n    assert(!interval.isBefore(iInterval));\n    assert(!interval.isBefore(posInfInterval));\n    assert(!interval.isBefore(cPosInfInterval));\n    assert(!interval.isBefore(iPosInfInterval));\n    assert(!interval.isBefore(negInfInterval));\n    assert(!interval.isBefore(cNegInfInterval));\n    assert(!interval.isBefore(iNegInfInterval));\n    assert(!cInterval.isBefore(interval));\n    assert(!cInterval.isBefore(cInterval));\n    assert(!cInterval.isBefore(iInterval));\n    assert(!cInterval.isBefore(posInfInterval));\n    assert(!cInterval.isBefore(cPosInfInterval));\n    assert(!cInterval.isBefore(iPosInfInterval));\n    assert(!cInterval.isBefore(negInfInterval));\n    assert(!cInterval.isBefore(cNegInfInterval));\n    assert(!cInterval.isBefore(iNegInfInterval));\n    assert(!iInterval.isBefore(interval));\n    assert(!iInterval.isBefore(cInterval));\n    assert(!iInterval.isBefore(iInterval));\n    assert(!iInterval.isBefore(posInfInterval));\n    assert(!iInterval.isBefore(cPosInfInterval));\n    assert(!iInterval.isBefore(iPosInfInterval));\n    assert(!iInterval.isBefore(negInfInterval));\n    assert(!iInterval.isBefore(cNegInfInterval));\n    assert(!iInterval.isBefore(iNegInfInterval));\n\n    // Verify Examples.\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n               Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n               Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(\n               Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1))));\n\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4))));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2013, 3, 7))));\n\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4))));\n}\n\n// Test Interval's isAfter(time point).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).isAfter(Date(2010, 7, 4)));\n\n    assert(interval.isAfter(Date(2009, 7, 4)));\n    assert(interval.isAfter(Date(2010, 7, 3)));\n    assert(!interval.isAfter(Date(2010, 7, 4)));\n    assert(!interval.isAfter(Date(2010, 7, 5)));\n    assert(!interval.isAfter(Date(2011, 7, 1)));\n    assert(!interval.isAfter(Date(2012, 1, 6)));\n    assert(!interval.isAfter(Date(2012, 1, 7)));\n    assert(!interval.isAfter(Date(2012, 1, 8)));\n    assert(!interval.isAfter(Date(2013, 1, 7)));\n\n    const cdate = Date(2010, 7, 6);\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    assert(!interval.isAfter(cdate));\n    assert(!cInterval.isAfter(cdate));\n    assert(!iInterval.isAfter(cdate));\n\n    // Verify Examples.\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(1994, 12, 24)));\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2000, 1, 5)));\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2012, 3, 1)));\n}\n\n// Test Interval's isAfter(Interval).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    assertThrown!DateTimeException(interval.isAfter(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).isAfter(interval));\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).isAfter(\n                                       Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(!interval.isAfter(interval));\n    assert(interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(!interval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(!interval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAfter(interval));\n    assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAfter(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAfter(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAfter(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAfter(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAfter(interval));\n    assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAfter(interval));\n    assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAfter(interval));\n    assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAfter(interval));\n    assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAfter(interval));\n    assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAfter(interval));\n    assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAfter(interval));\n\n    assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(!interval.isAfter(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!interval.isAfter(interval));\n    assert(!interval.isAfter(cInterval));\n    assert(!interval.isAfter(iInterval));\n    assert(!interval.isAfter(posInfInterval));\n    assert(!interval.isAfter(cPosInfInterval));\n    assert(!interval.isAfter(iPosInfInterval));\n    assert(!interval.isAfter(negInfInterval));\n    assert(!interval.isAfter(cNegInfInterval));\n    assert(!interval.isAfter(iNegInfInterval));\n    assert(!cInterval.isAfter(interval));\n    assert(!cInterval.isAfter(cInterval));\n    assert(!cInterval.isAfter(iInterval));\n    assert(!cInterval.isAfter(posInfInterval));\n    assert(!cInterval.isAfter(cPosInfInterval));\n    assert(!cInterval.isAfter(iPosInfInterval));\n    assert(!cInterval.isAfter(negInfInterval));\n    assert(!cInterval.isAfter(cNegInfInterval));\n    assert(!cInterval.isAfter(iNegInfInterval));\n    assert(!iInterval.isAfter(interval));\n    assert(!iInterval.isAfter(cInterval));\n    assert(!iInterval.isAfter(iInterval));\n    assert(!iInterval.isAfter(posInfInterval));\n    assert(!iInterval.isAfter(cPosInfInterval));\n    assert(!iInterval.isAfter(iPosInfInterval));\n    assert(!iInterval.isAfter(negInfInterval));\n    assert(!iInterval.isAfter(cNegInfInterval));\n    assert(!iInterval.isAfter(iNegInfInterval));\n\n    // Verify Examples.\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(\n               Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(\n               Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(\n               Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));\n\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4))));\n\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 1, 2))));\n}\n\n// Test Interval's intersects().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    assertThrown!DateTimeException(interval.intersects(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).intersects(interval));\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).intersects(\n                                       Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(interval.intersects(interval));\n    assert(!interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(!interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(!interval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(!interval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersects(interval));\n    assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersects(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersects(interval));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersects(interval));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersects(interval));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersects(interval));\n    assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersects(interval));\n    assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersects(interval));\n    assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersects(interval));\n    assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersects(interval));\n    assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersects(interval));\n    assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersects(interval));\n\n    assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(interval.intersects(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(interval.intersects(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(interval.intersects(interval));\n    assert(interval.intersects(cInterval));\n    assert(interval.intersects(iInterval));\n    assert(interval.intersects(posInfInterval));\n    assert(interval.intersects(cPosInfInterval));\n    assert(interval.intersects(iPosInfInterval));\n    assert(interval.intersects(negInfInterval));\n    assert(interval.intersects(cNegInfInterval));\n    assert(interval.intersects(iNegInfInterval));\n    assert(cInterval.intersects(interval));\n    assert(cInterval.intersects(cInterval));\n    assert(cInterval.intersects(iInterval));\n    assert(cInterval.intersects(posInfInterval));\n    assert(cInterval.intersects(cPosInfInterval));\n    assert(cInterval.intersects(iPosInfInterval));\n    assert(cInterval.intersects(negInfInterval));\n    assert(cInterval.intersects(cNegInfInterval));\n    assert(cInterval.intersects(iNegInfInterval));\n    assert(iInterval.intersects(interval));\n    assert(iInterval.intersects(cInterval));\n    assert(iInterval.intersects(iInterval));\n    assert(iInterval.intersects(posInfInterval));\n    assert(iInterval.intersects(cPosInfInterval));\n    assert(iInterval.intersects(iPosInfInterval));\n    assert(iInterval.intersects(negInfInterval));\n    assert(iInterval.intersects(cNegInfInterval));\n    assert(iInterval.intersects(iNegInfInterval));\n\n    // Verify Examples.\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(\n               Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(\n               Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(\n               Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));\n\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4))));\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1))));\n\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 1, 2))));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2000, 1, 2))));\n}\n\n// Test Interval's intersection().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).intersection(interval));\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)).intersection(\n                                       Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersection(interval));\n    assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersection(interval));\n    assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersection(interval));\n    assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersection(interval));\n\n    assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 7))));\n    assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 3))));\n    assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 4))));\n\n    assert(interval.intersection(interval) == interval);\n    assert(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));\n    assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==\n           Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));\n    assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));\n    assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));\n    assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));\n\n    assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersection(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersection(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersection(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersection(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersection(interval) ==\n           Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));\n    assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersection(interval) ==\n           Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersection(interval) ==\n           Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersection(interval) ==\n           Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));\n\n    assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) ==\n           Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));\n    assert(interval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) ==\n           Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));\n\n    assert(interval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));\n    assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6)));\n    assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!interval.intersection(interval).empty);\n    assert(!interval.intersection(cInterval).empty);\n    assert(!interval.intersection(iInterval).empty);\n    assert(!interval.intersection(posInfInterval).empty);\n    assert(!interval.intersection(cPosInfInterval).empty);\n    assert(!interval.intersection(iPosInfInterval).empty);\n    assert(!interval.intersection(negInfInterval).empty);\n    assert(!interval.intersection(cNegInfInterval).empty);\n    assert(!interval.intersection(iNegInfInterval).empty);\n    assert(!cInterval.intersection(interval).empty);\n    assert(!cInterval.intersection(cInterval).empty);\n    assert(!cInterval.intersection(iInterval).empty);\n    assert(!cInterval.intersection(posInfInterval).empty);\n    assert(!cInterval.intersection(cPosInfInterval).empty);\n    assert(!cInterval.intersection(iPosInfInterval).empty);\n    assert(!cInterval.intersection(negInfInterval).empty);\n    assert(!cInterval.intersection(cNegInfInterval).empty);\n    assert(!cInterval.intersection(iNegInfInterval).empty);\n    assert(!iInterval.intersection(interval).empty);\n    assert(!iInterval.intersection(cInterval).empty);\n    assert(!iInterval.intersection(iInterval).empty);\n    assert(!iInterval.intersection(posInfInterval).empty);\n    assert(!iInterval.intersection(cPosInfInterval).empty);\n    assert(!iInterval.intersection(iPosInfInterval).empty);\n    assert(!iInterval.intersection(negInfInterval).empty);\n    assert(!iInterval.intersection(cNegInfInterval).empty);\n    assert(!iInterval.intersection(iNegInfInterval).empty);\n\n    // Verify Examples.\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n               Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n           Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2)));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n               Interval!Date(Date(1999, 1, 12),Date(2011, 9, 17))) ==\n           Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17)));\n\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n               PosInfInterval!Date(Date(1990, 7, 6))) ==\n           Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n               PosInfInterval!Date(Date(1999, 1, 12))) ==\n           Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));\n\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n               NegInfInterval!Date(Date(1999, 7, 6))) ==\n           Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6)));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(\n               NegInfInterval!Date(Date(2013, 1, 12))) ==\n           Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));\n}\n\n// Test Interval's isAdjacent().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    static void testInterval(scope const Interval!Date interval1, scope const Interval!Date interval2)\n    {\n        interval1.isAdjacent(interval2);\n    }\n\n    assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n    assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)), interval));\n    assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)),\n                                                Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(!interval.isAdjacent(interval));\n    assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(interval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAdjacent(interval));\n    assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAdjacent(interval));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAdjacent(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAdjacent(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAdjacent(interval));\n    assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAdjacent(interval));\n    assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAdjacent(interval));\n    assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAdjacent(interval));\n    assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAdjacent(interval));\n    assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAdjacent(interval));\n    assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAdjacent(interval));\n    assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAdjacent(interval));\n\n    assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!interval.isAdjacent(interval));\n    assert(!interval.isAdjacent(cInterval));\n    assert(!interval.isAdjacent(iInterval));\n    assert(!interval.isAdjacent(posInfInterval));\n    assert(!interval.isAdjacent(cPosInfInterval));\n    assert(!interval.isAdjacent(iPosInfInterval));\n    assert(!interval.isAdjacent(negInfInterval));\n    assert(!interval.isAdjacent(cNegInfInterval));\n    assert(!interval.isAdjacent(iNegInfInterval));\n    assert(!cInterval.isAdjacent(interval));\n    assert(!cInterval.isAdjacent(cInterval));\n    assert(!cInterval.isAdjacent(iInterval));\n    assert(!cInterval.isAdjacent(posInfInterval));\n    assert(!cInterval.isAdjacent(cPosInfInterval));\n    assert(!cInterval.isAdjacent(iPosInfInterval));\n    assert(!cInterval.isAdjacent(negInfInterval));\n    assert(!cInterval.isAdjacent(cNegInfInterval));\n    assert(!cInterval.isAdjacent(iNegInfInterval));\n    assert(!iInterval.isAdjacent(interval));\n    assert(!iInterval.isAdjacent(cInterval));\n    assert(!iInterval.isAdjacent(iInterval));\n    assert(!iInterval.isAdjacent(posInfInterval));\n    assert(!iInterval.isAdjacent(cPosInfInterval));\n    assert(!iInterval.isAdjacent(iPosInfInterval));\n    assert(!iInterval.isAdjacent(negInfInterval));\n    assert(!iInterval.isAdjacent(cNegInfInterval));\n    assert(!iInterval.isAdjacent(iNegInfInterval));\n\n    // Verify Examples.\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(\n               Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2))));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(\n               Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17))));\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(\n               Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1))));\n\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4))));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1))));\n\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2))));\n    assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)) .isAdjacent(NegInfInterval!Date(Date(2000, 1, 2))));\n}\n\n// Test Interval's merge().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    static void testInterval(I)(scope const Interval!Date interval1, scope const I interval2)\n    {\n        interval1.merge(interval2);\n    }\n\n    assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n    assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)), interval));\n    assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)),\n                                                Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)), interval));\n    assertThrown!DateTimeException(testInterval(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)), interval));\n\n    assertThrown!DateTimeException(testInterval(interval, PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assertThrown!DateTimeException(testInterval(interval, NegInfInterval!Date(Date(2010, 7, 3))));\n\n    assert(interval.merge(interval) == interval);\n    assert(interval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==\n           Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));\n    assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));\n    assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));\n    assert(interval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));\n\n    assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).merge(interval) ==\n           Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).merge(interval) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).merge(interval) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).merge(interval) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).merge(interval) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));\n    assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).merge(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).merge(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).merge(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).merge(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));\n    assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).merge(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));\n\n    assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 3))) ==\n           PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 4))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 5))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 6))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 7))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n\n    assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 4))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 5))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 6))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 7))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 8))) ==\n           NegInfInterval!Date(Date(2012, 1, 8)));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!interval.merge(interval).empty);\n    assert(!interval.merge(cInterval).empty);\n    assert(!interval.merge(iInterval).empty);\n    assert(!interval.merge(posInfInterval).empty);\n    assert(!interval.merge(cPosInfInterval).empty);\n    assert(!interval.merge(iPosInfInterval).empty);\n    assert(!interval.merge(negInfInterval).empty);\n    assert(!interval.merge(cNegInfInterval).empty);\n    assert(!interval.merge(iNegInfInterval).empty);\n    assert(!cInterval.merge(interval).empty);\n    assert(!cInterval.merge(cInterval).empty);\n    assert(!cInterval.merge(iInterval).empty);\n    assert(!cInterval.merge(posInfInterval).empty);\n    assert(!cInterval.merge(cPosInfInterval).empty);\n    assert(!cInterval.merge(iPosInfInterval).empty);\n    assert(!cInterval.merge(negInfInterval).empty);\n    assert(!cInterval.merge(cNegInfInterval).empty);\n    assert(!cInterval.merge(iNegInfInterval).empty);\n    assert(!iInterval.merge(interval).empty);\n    assert(!iInterval.merge(cInterval).empty);\n    assert(!iInterval.merge(iInterval).empty);\n    assert(!iInterval.merge(posInfInterval).empty);\n    assert(!iInterval.merge(cPosInfInterval).empty);\n    assert(!iInterval.merge(iPosInfInterval).empty);\n    assert(!iInterval.merge(negInfInterval).empty);\n    assert(!iInterval.merge(cNegInfInterval).empty);\n    assert(!iInterval.merge(iNegInfInterval).empty);\n\n    // Verify Examples.\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n           Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) ==\n           Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));\n\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(1990, 7, 6))) ==\n           PosInfInterval!Date(Date(1990, 7 , 6)));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(2012, 3, 1))) ==\n           PosInfInterval!Date(Date(1996, 1 , 2)));\n\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1996, 1, 2))) ==\n           NegInfInterval!Date(Date(2012, 3 , 1)));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) ==\n           NegInfInterval!Date(Date(2013, 1 , 12)));\n}\n\n// Test Interval's span().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    static void testInterval(scope const Interval!Date interval1, scope const Interval!Date interval2)\n    {\n        interval1.span(interval2);\n    }\n\n    assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n    assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)),interval));\n    assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)),\n                                                Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(interval.span(interval) == interval);\n    assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) ==\n           Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7)));\n    assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==\n           Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));\n    assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));\n    assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));\n    assert(interval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));\n    assert(interval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9)));\n\n    assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).span(interval) ==\n           Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).span(interval) ==\n           Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).span(interval) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).span(interval) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).span(interval) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).span(interval) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));\n    assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).span(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).span(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).span(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).span(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));\n    assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).span(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));\n    assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).span(interval) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9)));\n\n    assert(interval.span(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(interval.span(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(interval.span(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(interval.span(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(interval.span(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(interval.span(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4)));\n\n    assert(interval.span(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(interval.span(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(interval.span(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(interval.span(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(interval.span(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(interval.span(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8)));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!interval.span(interval).empty);\n    assert(!interval.span(cInterval).empty);\n    assert(!interval.span(iInterval).empty);\n    assert(!interval.span(posInfInterval).empty);\n    assert(!interval.span(cPosInfInterval).empty);\n    assert(!interval.span(iPosInfInterval).empty);\n    assert(!interval.span(negInfInterval).empty);\n    assert(!interval.span(cNegInfInterval).empty);\n    assert(!interval.span(iNegInfInterval).empty);\n    assert(!cInterval.span(interval).empty);\n    assert(!cInterval.span(cInterval).empty);\n    assert(!cInterval.span(iInterval).empty);\n    assert(!cInterval.span(posInfInterval).empty);\n    assert(!cInterval.span(cPosInfInterval).empty);\n    assert(!cInterval.span(iPosInfInterval).empty);\n    assert(!cInterval.span(negInfInterval).empty);\n    assert(!cInterval.span(cNegInfInterval).empty);\n    assert(!cInterval.span(iNegInfInterval).empty);\n    assert(!iInterval.span(interval).empty);\n    assert(!iInterval.span(cInterval).empty);\n    assert(!iInterval.span(iInterval).empty);\n    assert(!iInterval.span(posInfInterval).empty);\n    assert(!iInterval.span(cPosInfInterval).empty);\n    assert(!iInterval.span(iPosInfInterval).empty);\n    assert(!iInterval.span(negInfInterval).empty);\n    assert(!iInterval.span(cNegInfInterval).empty);\n    assert(!iInterval.span(iNegInfInterval).empty);\n\n    // Verify Examples.\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) ==\n           Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) ==\n           Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));\n\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(1990, 7, 6))) ==\n           PosInfInterval!Date(Date(1990, 7 , 6)));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(2050, 1, 1))) ==\n           PosInfInterval!Date(Date(1996, 1 , 2)));\n\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1602, 5, 21))) ==\n           NegInfInterval!Date(Date(2012, 3 , 1)));\n    assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) ==\n           NegInfInterval!Date(Date(2013, 1 , 12)));\n}\n\n// Test Interval's shift(duration).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n    static void testIntervalFail(Interval!Date interval, scope const Duration duration)\n    {\n        interval.shift(duration);\n    }\n\n    assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)), dur!\"days\"(1)));\n\n    static void testInterval(I)(I interval, scope const Duration duration,\n                                scope const I expected, size_t line = __LINE__)\n    {\n        interval.shift(duration);\n        assert(interval == expected);\n    }\n\n    testInterval(interval, dur!\"days\"(22), Interval!Date(Date(2010, 7, 26), Date(2012, 1, 29)));\n    testInterval(interval, dur!\"days\"(-22), Interval!Date(Date(2010, 6, 12), Date(2011, 12, 16)));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    static assert(!__traits(compiles, cInterval.shift(dur!\"days\"(5))));\n    static assert(!__traits(compiles, iInterval.shift(dur!\"days\"(5))));\n\n    // Verify Examples.\n    auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));\n    auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));\n\n    interval1.shift(dur!\"days\"(50));\n    assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25)));\n\n    interval2.shift(dur!\"days\"(-50));\n    assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15)));\n}\n\n// Test Interval's shift(int, int, AllowDayOverflow).\n@safe unittest\n{\n    import std.datetime.date;\n\n    {\n        auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n\n        static void testIntervalFail(Interval!Date interval, int years, int months)\n        {\n            interval.shift(years, months);\n        }\n\n        assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)), 1, 0));\n\n        static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow,\n                                    in I expected, size_t line = __LINE__)\n        {\n            interval.shift(years, months, allow);\n            assert(interval == expected);\n        }\n\n        testInterval(interval, 5, 0, AllowDayOverflow.yes, Interval!Date(Date(2015, 7, 4), Date(2017, 1, 7)));\n        testInterval(interval, -5, 0, AllowDayOverflow.yes, Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7)));\n\n        auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.yes, Interval!Date(Date(2001, 3, 1), Date(2011, 7, 1)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.yes, Interval!Date(Date(2000, 12, 29), Date(2011, 5, 1)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.yes, Interval!Date(Date(1998, 12, 29), Date(2009, 5, 1)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.yes, Interval!Date(Date(1999, 3, 1), Date(2009, 7, 1)));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.no, Interval!Date(Date(2001, 2, 28), Date(2011, 6, 30)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.no, Interval!Date(Date(2000, 12, 29), Date(2011, 4, 30)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.no, Interval!Date(Date(1998, 12, 29), Date(2009, 4, 30)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.no, Interval!Date(Date(1999, 2, 28), Date(2009, 6, 30)));\n    }\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    static assert(!__traits(compiles, cInterval.shift(5)));\n    static assert(!__traits(compiles, iInterval.shift(5)));\n\n    // Verify Examples.\n    auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n    auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n\n    interval1.shift(2);\n    assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1)));\n\n    interval2.shift(-2);\n    assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1)));\n}\n\n// Test Interval's expand(Duration).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7));\n\n    static void testIntervalFail(I)(I interval, scope const Duration duration)\n    {\n        interval.expand(duration);\n    }\n\n    assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)), dur!\"days\"(1)));\n    assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)), dur!\"days\"(-5)));\n\n    static void testInterval(I)(I interval, scope const Duration duration,\n                                scope const I expected, size_t line = __LINE__)\n    {\n        interval.expand(duration);\n        assert(interval == expected);\n    }\n\n    testInterval(interval, dur!\"days\"(22), Interval!Date(Date(2000, 6, 12), Date(2012, 1, 29)));\n    testInterval(interval, dur!\"days\"(-22), Interval!Date(Date(2000, 7, 26), Date(2011, 12, 16)));\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    static assert(!__traits(compiles, cInterval.expand(dur!\"days\"(5))));\n    static assert(!__traits(compiles, iInterval.expand(dur!\"days\"(5))));\n\n    // Verify Examples.\n    auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n    auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n\n    interval1.expand(dur!\"days\"(2));\n    assert(interval1 == Interval!Date(Date(1995, 12, 31), Date(2012, 3, 3)));\n\n    interval2.expand(dur!\"days\"(-2));\n    assert(interval2 == Interval!Date(Date(1996, 1, 4), Date(2012, 2, 28)));\n}\n\n// Test Interval's expand(int, int, AllowDayOverflow, Direction)\n@safe unittest\n{\n    import std.datetime.date;\n\n    {\n        auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7));\n\n        static void testIntervalFail(Interval!Date interval, int years, int months)\n        {\n            interval.expand(years, months);\n        }\n\n        assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0)), 1, 0));\n        assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)), -5, 0));\n\n        static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, Direction dir,\n                                    in I expected, size_t line = __LINE__)\n        {\n            interval.expand(years, months, allow, dir);\n            assert(interval == expected);\n        }\n\n        testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.both,\n                     Interval!Date(Date(1995, 7, 4), Date(2017, 1, 7)));\n        testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.both,\n                     Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7)));\n\n        testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.fwd,\n                     Interval!Date(Date(2000, 7, 4), Date(2017, 1, 7)));\n        testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.fwd,\n                     Interval!Date(Date(2000, 7, 4), Date(2007, 1, 7)));\n\n        testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.bwd,\n                     Interval!Date(Date(1995, 7, 4), Date(2012, 1, 7)));\n        testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.bwd,\n                     Interval!Date(Date(2005, 7, 4), Date(2012, 1, 7)));\n\n        auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.both,\n                     Interval!Date(Date(1998, 12, 29), Date(2011, 7, 1)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.both,\n                     Interval!Date(Date(1999, 3, 1), Date(2011, 5, 1)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.both,\n                     Interval!Date(Date(2001, 3, 1), Date(2009, 5, 1)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.both,\n                     Interval!Date(Date(2000, 12, 29), Date(2009, 7, 1)));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.both,\n                     Interval!Date(Date(1998, 12, 29), Date(2011, 6, 30)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.both,\n                     Interval!Date(Date(1999, 2, 28), Date(2011, 4, 30)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.both,\n                     Interval!Date(Date(2001, 2, 28), Date(2009, 4, 30)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.both,\n                     Interval!Date(Date(2000, 12, 29), Date(2009, 6, 30)));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.fwd,\n                     Interval!Date(Date(2000, 1, 29), Date(2011, 7, 1)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.fwd,\n                     Interval!Date(Date(2000, 1, 29), Date(2011, 5, 1)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.fwd,\n                     Interval!Date(Date(2000, 1, 29), Date(2009, 5, 1)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.fwd,\n                     Interval!Date(Date(2000, 1, 29), Date(2009, 7, 1)));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.fwd,\n                     Interval!Date(Date(2000, 1, 29), Date(2011, 6, 30)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.fwd,\n                     Interval!Date(Date(2000, 1, 29), Date(2011, 4, 30)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.fwd,\n                     Interval!Date(Date(2000, 1, 29), Date(2009, 4, 30)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.fwd,\n                     Interval!Date(Date(2000, 1, 29), Date(2009, 6, 30)));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.bwd,\n                     Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.bwd,\n                     Interval!Date(Date(1999, 3, 1), Date(2010, 5, 31)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.bwd,\n                     Interval!Date(Date(2001, 3, 1), Date(2010, 5, 31)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.bwd,\n                     Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31)));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.bwd,\n                     Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.bwd,\n                     Interval!Date(Date(1999, 2, 28), Date(2010, 5, 31)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.bwd,\n                     Interval!Date(Date(2001, 2, 28), Date(2010, 5, 31)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.bwd,\n                     Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31)));\n    }\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    static assert(!__traits(compiles, cInterval.expand(5)));\n    static assert(!__traits(compiles, iInterval.expand(5)));\n\n    // Verify Examples.\n    auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n    auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));\n\n    interval1.expand(2);\n    assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1)));\n\n    interval2.expand(-2);\n    assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1)));\n}\n\n// Test Interval's fwdRange.\n@system unittest\n{\n    import std.datetime.date;\n\n    {\n        auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21));\n\n        static void testInterval1(Interval!Date interval)\n        {\n            interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));\n        }\n\n        assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n        static void testInterval2(Interval!Date interval)\n        {\n            interval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront();\n        }\n\n        assertThrown!DateTimeException(testInterval2(interval));\n\n        assert(!interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);\n        assert(interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).empty);\n\n        assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front ==\n               Date(2010, 9, 12));\n\n        assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange(\n                   everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 17));\n    }\n\n    // Verify Examples.\n    {\n        auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));\n        auto func = delegate (scope const Date date)\n                    {\n                        if ((date.day & 1) == 0)\n                            return date + dur!\"days\"(2);\n                        return date + dur!\"days\"(1);\n                    };\n        auto range = interval.fwdRange(func);\n\n        // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).\n        assert(range.front == Date(2010, 9, 1));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 2));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 4));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 6));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 8));\n\n        range.popFront();\n        assert(range.empty);\n    }\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    assert(!cInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);\n    assert(!iInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);\n}\n\n// Test Interval's bwdRange.\n@system unittest\n{\n    import std.datetime.date;\n\n    {\n        auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21));\n\n        static void testInterval1(Interval!Date interval)\n        {\n            interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));\n        }\n\n        assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n        static void testInterval2(Interval!Date interval)\n        {\n            interval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront();\n        }\n\n        assertThrown!DateTimeException(testInterval2(interval));\n\n        assert(!interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty);\n        assert(interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).empty);\n\n        assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange(\n                   everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front == Date(2010, 10, 1));\n\n        assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange(\n                   everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 24));\n    }\n\n    // Verify Examples.\n    {\n        auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));\n        auto func = delegate (scope const Date date)\n                    {\n                        if ((date.day & 1) == 0)\n                            return date - dur!\"days\"(2);\n                        return date - dur!\"days\"(1);\n                    };\n        auto range = interval.bwdRange(func);\n\n        // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).\n        assert(range.front == Date(2010, 9, 9));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 8));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 6));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 4));\n\n        range.popFront();\n        assert(range.front == Date(2010, 9, 2));\n\n        range.popFront();\n        assert(range.empty);\n    }\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    assert(!cInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);\n    assert(!iInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);\n}\n\n// Test Interval's toString().\n@safe unittest\n{\n    import std.datetime.date;\n\n    assert(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).toString() == \"[2010-Jul-04 - 2012-Jan-07)\");\n\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    assert(cInterval.toString());\n    assert(iInterval.toString());\n}\n\n\n/++\n    Represents an interval of time which has positive infinity as its end point.\n\n    Any ranges which iterate over a `PosInfInterval` are infinite. So, the\n    main purpose of using `PosInfInterval` is to create an infinite range\n    which starts at a fixed point in time and goes to positive infinity.\n  +/\nstruct PosInfInterval(TP)\n{\npublic:\n\n    /++\n        Params:\n            begin = The time point which begins the interval.\n\n        Example:\n--------------------\nauto interval = PosInfInterval!Date(Date(1996, 1, 2));\n--------------------\n      +/\n    this(scope const TP begin) pure nothrow\n    {\n        _begin = cast(TP) begin;\n    }\n\n\n    /++\n        Params:\n            rhs = The `PosInfInterval` to assign to this one.\n      +/\n    ref PosInfInterval opAssign(const ref PosInfInterval rhs) pure nothrow\n    {\n        _begin = cast(TP) rhs._begin;\n        return this;\n    }\n\n\n    /++\n        Params:\n            rhs = The `PosInfInterval` to assign to this one.\n      +/\n    ref PosInfInterval opAssign(PosInfInterval rhs) pure nothrow\n    {\n        _begin = cast(TP) rhs._begin;\n        return this;\n    }\n\n\n    /++\n        The starting point of the interval. It is included in the interval.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2));\n--------------------\n      +/\n    @property TP begin() const pure nothrow\n    {\n        return cast(TP)_begin;\n    }\n\n\n    /++\n        The starting point of the interval. It is included in the interval.\n\n        Params:\n            timePoint = The time point to set `begin` to.\n      +/\n    @property void begin(TP timePoint) pure nothrow\n    {\n        _begin = timePoint;\n    }\n\n\n    /++\n        Whether the interval's length is 0. Always returns false.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).empty);\n--------------------\n      +/\n    enum bool empty = false;\n\n\n    /++\n        Whether the given time point is within this interval.\n\n        Params:\n            timePoint = The time point to check for inclusion in this interval.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24)));\nassert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5)));\n--------------------\n      +/\n    bool contains(TP timePoint) const pure nothrow\n    {\n        return timePoint >= _begin;\n    }\n\n\n    /++\n        Whether the given interval is completely within this interval.\n\n        Params:\n            interval = The interval to check for inclusion in this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).contains(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).contains(\n            Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));\n--------------------\n      +/\n    bool contains(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return interval._begin >= _begin;\n    }\n\n\n    /++\n        Whether the given interval is completely within this interval.\n\n        Params:\n            interval = The interval to check for inclusion in this interval.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).contains(\n            PosInfInterval!Date(Date(1999, 5, 4))));\n\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(\n            PosInfInterval!Date(Date(1995, 7, 2))));\n--------------------\n      +/\n    bool contains(scope const PosInfInterval interval) const pure nothrow\n    {\n        return interval._begin >= _begin;\n    }\n\n\n    /++\n        Whether the given interval is completely within this interval.\n\n        Always returns false because an interval going to positive infinity\n        can never contain an interval beginning at negative infinity.\n\n        Params:\n            interval = The interval to check for inclusion in this interval.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(\n            NegInfInterval!Date(Date(1996, 5, 4))));\n--------------------\n      +/\n    bool contains(scope const NegInfInterval!TP interval) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Whether this interval is before the given time point.\n\n        Always returns false because an interval going to positive infinity\n        can never be before any time point.\n\n        Params:\n            timePoint = The time point to check whether this interval is before\n                        it.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24)));\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5)));\n--------------------\n      +/\n    bool isBefore(scope const TP timePoint) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Whether this interval is before the given interval and does not\n        intersect it.\n\n        Always returns false (unless the given interval is empty) because an\n        interval going to positive infinity can never be before any other\n        interval.\n\n        Params:\n            interval = The interval to check for against this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n--------------------\n      +/\n    bool isBefore(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return false;\n    }\n\n\n    /++\n        Whether this interval is before the given interval and does not\n        intersect it.\n\n        Always returns false because an interval going to positive infinity can\n        never be before any other interval.\n\n        Params:\n            interval = The interval to check for against this interval.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(\n            PosInfInterval!Date(Date(1992, 5, 4))));\n\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(\n            PosInfInterval!Date(Date(2013, 3, 7))));\n--------------------\n      +/\n    bool isBefore(scope const PosInfInterval interval) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Whether this interval is before the given interval and does not\n        intersect it.\n\n        Always returns false because an interval going to positive infinity can\n        never be before any other interval.\n\n        Params:\n            interval = The interval to check for against this interval.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(\n            NegInfInterval!Date(Date(1996, 5, 4))));\n--------------------\n      +/\n    bool isBefore(scope const NegInfInterval!TP interval) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Whether this interval is after the given time point.\n\n        Params:\n            timePoint = The time point to check whether this interval is after\n                        it.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24)));\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5)));\n--------------------\n      +/\n    bool isAfter(scope const TP timePoint) const pure nothrow\n    {\n        return timePoint < _begin;\n    }\n\n\n    /++\n        Whether this interval is after the given interval and does not intersect\n        it.\n\n        Params:\n            interval = The interval to check against this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(\n            Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));\n--------------------\n      +/\n    bool isAfter(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return _begin >= interval._end;\n    }\n\n\n    /++\n        Whether this interval is after the given interval and does not intersect\n        it.\n\n        Always returns false because an interval going to positive infinity can\n        never be after another interval going to positive infinity.\n\n        Params:\n            interval = The interval to check against this interval.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(\n            PosInfInterval!Date(Date(1990, 1, 7))));\n\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(\n            PosInfInterval!Date(Date(1999, 5, 4))));\n--------------------\n      +/\n    bool isAfter(scope const PosInfInterval interval) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Whether this interval is after the given interval and does not intersect\n        it.\n\n        Params:\n            interval = The interval to check against this interval.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(\n            NegInfInterval!Date(Date(1996, 1, 2))));\n\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(\n            NegInfInterval!Date(Date(2000, 7, 1))));\n--------------------\n      +/\n    bool isAfter(scope const NegInfInterval!TP interval) const pure nothrow\n    {\n        return _begin >= interval._end;\n    }\n\n\n    /++\n        Whether the given interval overlaps this interval.\n\n        Params:\n            interval = The interval to check for intersection with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(\n            Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));\n--------------------\n      +/\n    bool intersects(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return interval._end > _begin;\n    }\n\n\n    /++\n        Whether the given interval overlaps this interval.\n\n        Always returns true because two intervals going to positive infinity\n        always overlap.\n\n        Params:\n            interval = The interval to check for intersection with this\n                       interval.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(\n            PosInfInterval!Date(Date(1990, 1, 7))));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(\n            PosInfInterval!Date(Date(1999, 5, 4))));\n--------------------\n      +/\n    bool intersects(scope const PosInfInterval interval) const pure nothrow\n    {\n        return true;\n    }\n\n\n    /++\n        Whether the given interval overlaps this interval.\n\n        Params:\n            interval = The interval to check for intersection with this\n                       interval.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(\n            NegInfInterval!Date(Date(1996, 1, 2))));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(\n            NegInfInterval!Date(Date(2000, 7, 1))));\n--------------------\n      +/\n    bool intersects(scope const NegInfInterval!TP interval) const pure nothrow\n    {\n        return _begin < interval._end;\n    }\n\n\n    /++\n        Returns the intersection of two intervals\n\n        Params:\n            interval = The interval to intersect with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect or if the given interval is empty.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n       Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2)));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==\n       Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17)));\n--------------------\n      +/\n    Interval!TP intersection(scope const Interval!TP interval) const\n    {\n        import std.format : format;\n\n        enforce(this.intersects(interval),\n                new DateTimeException(format(\"%s and %s do not intersect.\", this, interval)));\n\n        auto begin = _begin > interval._begin ? _begin : interval._begin;\n\n        return Interval!TP(begin, interval._end);\n    }\n\n\n    /++\n        Returns the intersection of two intervals\n\n        Params:\n            interval = The interval to intersect with this interval.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(\n            PosInfInterval!Date(Date(1990, 7, 6))) ==\n       PosInfInterval!Date(Date(1996, 1 , 2)));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(\n            PosInfInterval!Date(Date(1999, 1, 12))) ==\n       PosInfInterval!Date(Date(1999, 1 , 12)));\n--------------------\n      +/\n    PosInfInterval intersection(scope const PosInfInterval interval) const pure nothrow\n    {\n        return PosInfInterval(_begin < interval._begin ? interval._begin : _begin);\n    }\n\n\n    /++\n        Returns the intersection of two intervals\n\n        Params:\n            interval = The interval to intersect with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(\n            NegInfInterval!Date(Date(1999, 7, 6))) ==\n       Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6)));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(\n            NegInfInterval!Date(Date(2013, 1, 12))) ==\n       Interval!Date(Date(1996, 1 , 2), Date(2013, 1, 12)));\n--------------------\n      +/\n    Interval!TP intersection(scope const NegInfInterval!TP interval) const\n    {\n        import std.format : format;\n\n        enforce(this.intersects(interval),\n                new DateTimeException(format(\"%s and %s do not intersect.\", this, interval)));\n\n        return Interval!TP(_begin, interval._end);\n    }\n\n\n    /++\n        Whether the given interval is adjacent to this interval.\n\n        Params:\n            interval = The interval to check whether its adjecent to this\n                       interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(\n            Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));\n\nassert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n--------------------\n      +/\n    bool isAdjacent(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return _begin == interval._end;\n    }\n\n\n    /++\n        Whether the given interval is adjacent to this interval.\n\n        Always returns false because two intervals going to positive infinity\n        can never be adjacent to one another.\n\n        Params:\n            interval = The interval to check whether its adjecent to this\n                       interval.\n\n        Example:\n--------------------\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(\n            PosInfInterval!Date(Date(1990, 1, 7))));\n\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(\n            PosInfInterval!Date(Date(1996, 1, 2))));\n--------------------\n      +/\n    bool isAdjacent(scope const PosInfInterval interval) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Whether the given interval is adjacent to this interval.\n\n        Params:\n            interval = The interval to check whether its adjecent to this\n                       interval.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(\n            NegInfInterval!Date(Date(1996, 1, 2))));\n\nassert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(\n            NegInfInterval!Date(Date(2000, 7, 1))));\n--------------------\n      +/\n    bool isAdjacent(scope const NegInfInterval!TP interval) const pure nothrow\n    {\n        return _begin == interval._end;\n    }\n\n\n    /++\n        Returns the union of two intervals\n\n        Params:\n            interval = The interval to merge with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect and are not adjacent or if the given interval is\n            empty.\n\n        Note:\n            There is no overload for `merge` which takes a\n            `NegInfInterval`, because an interval\n            going from negative infinity to positive infinity\n            is not possible.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).merge(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n       PosInfInterval!Date(Date(1990, 7 , 6)));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).merge(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==\n       PosInfInterval!Date(Date(1996, 1 , 2)));\n--------------------\n      +/\n    PosInfInterval merge(scope const Interval!TP interval) const\n    {\n        import std.format : format;\n\n        enforce(this.isAdjacent(interval) || this.intersects(interval),\n                new DateTimeException(format(\"%s and %s are not adjacent and do not intersect.\", this, interval)));\n\n        return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);\n    }\n\n\n    /++\n        Returns the union of two intervals\n\n        Params:\n            interval = The interval to merge with this interval.\n\n        Note:\n            There is no overload for `merge` which takes a\n            `NegInfInterval`, because an interval\n            going from negative infinity to positive infinity\n            is not possible.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).merge(\n            PosInfInterval!Date(Date(1990, 7, 6))) ==\n       PosInfInterval!Date(Date(1990, 7 , 6)));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).merge(\n            PosInfInterval!Date(Date(1999, 1, 12))) ==\n       PosInfInterval!Date(Date(1996, 1 , 2)));\n--------------------\n      +/\n    PosInfInterval merge(scope const PosInfInterval interval) const pure nothrow\n    {\n        return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);\n    }\n\n\n    /++\n        Returns an interval that covers from the earliest time point of two\n        intervals up to (but not including) the latest time point of two\n        intervals.\n\n        Params:\n            interval = The interval to create a span together with this\n                       interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty.\n\n        Note:\n            There is no overload for `span` which takes a\n            `NegInfInterval`, because an interval\n            going from negative infinity to positive infinity\n            is not possible.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).span(\n            Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) ==\n       PosInfInterval!Date(Date(500, 8, 9)));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).span(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n       PosInfInterval!Date(Date(1990, 7 , 6)));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).span(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==\n       PosInfInterval!Date(Date(1996, 1 , 2)));\n--------------------\n      +/\n    PosInfInterval span(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);\n    }\n\n\n    /++\n        Returns an interval that covers from the earliest time point of two\n        intervals up to (but not including) the latest time point of two\n        intervals.\n\n        Params:\n            interval = The interval to create a span together with this\n                       interval.\n\n        Note:\n            There is no overload for `span` which takes a\n            `NegInfInterval`, because an interval\n            going from negative infinity to positive infinity\n            is not possible.\n\n        Example:\n--------------------\nassert(PosInfInterval!Date(Date(1996, 1, 2)).span(\n            PosInfInterval!Date(Date(1990, 7, 6))) ==\n       PosInfInterval!Date(Date(1990, 7 , 6)));\n\nassert(PosInfInterval!Date(Date(1996, 1, 2)).span(\n            PosInfInterval!Date(Date(1999, 1, 12))) ==\n       PosInfInterval!Date(Date(1996, 1 , 2)));\n--------------------\n      +/\n    PosInfInterval span(scope const PosInfInterval interval) const pure nothrow\n    {\n        return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);\n    }\n\n\n    /++\n        Shifts the `begin` of this interval forward or backwards in time by\n        the given duration (a positive duration shifts the interval forward; a\n        negative duration shifts it backward). Effectively, it does\n        $(D begin += duration).\n\n        Params:\n            duration = The duration to shift the interval by.\n\n        Example:\n--------------------\nauto interval1 = PosInfInterval!Date(Date(1996, 1, 2));\nauto interval2 = PosInfInterval!Date(Date(1996, 1, 2));\n\ninterval1.shift(dur!\"days\"(50));\nassert(interval1 == PosInfInterval!Date(Date(1996, 2, 21)));\n\ninterval2.shift(dur!\"days\"(-50));\nassert(interval2 == PosInfInterval!Date(Date(1995, 11, 13)));\n--------------------\n      +/\n    void shift(D)(D duration) pure nothrow\n        if (__traits(compiles, begin + duration))\n    {\n        _begin += duration;\n    }\n\n\n    static if (__traits(compiles, begin.add!\"months\"(1)) &&\n               __traits(compiles, begin.add!\"years\"(1)))\n    {\n        /++\n            Shifts the `begin` of this interval forward or backwards in time\n            by the given number of years and/or months (a positive number of\n            years and months shifts the interval forward; a negative number\n            shifts it backward). It adds the years the given years and months to\n            `begin`. It effectively calls `add!\"years\"()` and then\n            `add!\"months\"()` on `begin` with the given number of years and\n            months.\n\n            Params:\n                years         = The number of years to shift the interval by.\n                months        = The number of months to shift the interval by.\n                allowOverflow = Whether the days should be allowed to overflow\n                                on `begin`, causing its month to increment.\n\n            Throws:\n                $(REF DateTimeException,std,datetime,date) if this interval is\n                empty or if the resulting interval would be invalid.\n\n            Example:\n--------------------\nauto interval1 = PosInfInterval!Date(Date(1996, 1, 2));\nauto interval2 = PosInfInterval!Date(Date(1996, 1, 2));\n\ninterval1.shift(dur!\"days\"(50));\nassert(interval1 == PosInfInterval!Date(Date(1996, 2, 21)));\n\ninterval2.shift(dur!\"days\"(-50));\nassert(interval2 == PosInfInterval!Date(Date(1995, 11, 13)));\n--------------------\n          +/\n        void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)\n            if (isIntegral!T)\n        {\n            auto begin = _begin;\n\n            begin.add!\"years\"(years, allowOverflow);\n            begin.add!\"months\"(months, allowOverflow);\n\n            _begin = begin;\n        }\n    }\n\n\n    /++\n        Expands the interval backwards in time. Effectively, it does\n        $(D begin -= duration).\n\n        Params:\n            duration = The duration to expand the interval by.\n\n        Example:\n--------------------\nauto interval1 = PosInfInterval!Date(Date(1996, 1, 2));\nauto interval2 = PosInfInterval!Date(Date(1996, 1, 2));\n\ninterval1.expand(dur!\"days\"(2));\nassert(interval1 == PosInfInterval!Date(Date(1995, 12, 31)));\n\ninterval2.expand(dur!\"days\"(-2));\nassert(interval2 == PosInfInterval!Date(Date(1996, 1, 4)));\n--------------------\n      +/\n    void expand(D)(D duration) pure nothrow\n        if (__traits(compiles, begin + duration))\n    {\n        _begin -= duration;\n    }\n\n\n    static if (__traits(compiles, begin.add!\"months\"(1)) &&\n               __traits(compiles, begin.add!\"years\"(1)))\n    {\n        /++\n            Expands the interval forwards and/or backwards in time. Effectively,\n            it subtracts the given number of months/years from `begin`.\n\n            Params:\n                years         = The number of years to expand the interval by.\n                months        = The number of months to expand the interval by.\n                allowOverflow = Whether the days should be allowed to overflow\n                                on `begin`, causing its month to increment.\n\n            Throws:\n                $(REF DateTimeException,std,datetime,date) if this interval is\n                empty or if the resulting interval would be invalid.\n\n            Example:\n--------------------\nauto interval1 = PosInfInterval!Date(Date(1996, 1, 2));\nauto interval2 = PosInfInterval!Date(Date(1996, 1, 2));\n\ninterval1.expand(2);\nassert(interval1 == PosInfInterval!Date(Date(1994, 1, 2)));\n\ninterval2.expand(-2);\nassert(interval2 == PosInfInterval!Date(Date(1998, 1, 2)));\n--------------------\n          +/\n        void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)\n            if (isIntegral!T)\n        {\n            auto begin = _begin;\n\n            begin.add!\"years\"(-years, allowOverflow);\n            begin.add!\"months\"(-months, allowOverflow);\n\n            _begin = begin;\n        }\n    }\n\n\n    /++\n        Returns a range which iterates forward over the interval, starting\n        at `begin`, using $(D_PARAM func) to generate each successive time\n        point.\n\n        The range's `front` is the interval's `begin`. $(D_PARAM func) is\n        used to generate the next `front` when `popFront` is called. If\n        $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called\n        before the range is returned (so that `front` is a time point which\n        $(D_PARAM func) would generate).\n\n        If $(D_PARAM func) ever generates a time point less than or equal to the\n        current `front` of the range, then a\n        $(REF DateTimeException,std,datetime,date) will be thrown.\n\n        There are helper functions in this module which generate common\n        delegates to pass to `fwdRange`. Their documentation starts with\n        \"Range-generating function,\" to make them easily searchable.\n\n        Params:\n            func     = The function used to generate the time points of the\n                       range over the interval.\n            popFirst = Whether `popFront` should be called on the range\n                       before returning it.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Warning:\n            $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)\n            would be a function pointer to a pure function, but forcing\n            $(D_PARAM func) to be pure is far too restrictive to be useful, and\n            in order to have the ease of use of having functions which generate\n            functions to pass to `fwdRange`, $(D_PARAM func) must be a\n            delegate.\n\n            If $(D_PARAM func) retains state which changes as it is called, then\n            some algorithms will not work correctly, because the range's\n            `save` will have failed to have really saved the range's state.\n            To avoid such bugs, don't pass a delegate which is\n            not logically pure to `fwdRange`. If $(D_PARAM func) is given the\n            same time point with two different calls, it must return the same\n            result both times.\n\n            Of course, none of the functions in this module have this problem,\n            so it's only relevant for custom delegates.\n\n        Example:\n--------------------\nauto interval = PosInfInterval!Date(Date(2010, 9, 1));\nauto func = delegate (scope const Date date) //For iterating over even-numbered days.\n            {\n                if ((date.day & 1) == 0)\n                    return date + dur!\"days\"(2);\n\n                return date + dur!\"days\"(1);\n            };\nauto range = interval.fwdRange(func);\n\n//An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).\nassert(range.front == Date(2010, 9, 1));\n\nrange.popFront();\nassert(range.front == Date(2010, 9, 2));\n\nrange.popFront();\nassert(range.front == Date(2010, 9, 4));\n\nrange.popFront();\nassert(range.front == Date(2010, 9, 6));\n\nrange.popFront();\nassert(range.front == Date(2010, 9, 8));\n\nrange.popFront();\nassert(!range.empty);\n--------------------\n      +/\n    PosInfIntervalRange!(TP) fwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const\n    {\n        auto range = PosInfIntervalRange!(TP)(this, func);\n\n        if (popFirst == PopFirst.yes)\n            range.popFront();\n\n        return range;\n    }\n\n\n    /+\n        Converts this interval to a string.\n      +/\n    //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't\n    //have versions of toString() with extra modifiers, so we define one version\n    //with modifiers and one without.\n    string toString()\n    {\n        return _toStringImpl();\n    }\n\n\n    /++\n        Converts this interval to a string.\n      +/\n    //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't\n    //have versions of toString() with extra modifiers, so we define one version\n    //with modifiers and one without.\n    string toString() const nothrow\n    {\n        return _toStringImpl();\n    }\n\nprivate:\n\n    /+\n        Since we have two versions of toString(), we have _toStringImpl()\n        so that they can share implementations.\n      +/\n    string _toStringImpl() const nothrow\n    {\n        import std.format : format;\n        try\n            return format(\"[%s - ∞)\", _begin);\n        catch (Exception e)\n            assert(0, \"format() threw.\");\n    }\n\n\n    TP _begin;\n}\n\n//Test PosInfInterval's constructor.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    PosInfInterval!Date(Date.init);\n    PosInfInterval!TimeOfDay(TimeOfDay.init);\n    PosInfInterval!DateTime(DateTime.init);\n    PosInfInterval!SysTime(SysTime(0));\n\n    //Verify Examples.\n    auto interval = PosInfInterval!Date(Date(1996, 1, 2));\n}\n\n//Test PosInfInterval's begin.\n@safe unittest\n{\n    import std.datetime.date;\n\n    assert(PosInfInterval!Date(Date(1, 1, 1)).begin == Date(1, 1, 1));\n    assert(PosInfInterval!Date(Date(2010, 1, 1)).begin == Date(2010, 1, 1));\n    assert(PosInfInterval!Date(Date(1997, 12, 31)).begin == Date(1997, 12, 31));\n\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    assert(cPosInfInterval.begin != Date.init);\n    assert(iPosInfInterval.begin != Date.init);\n\n    //Verify Examples.\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2));\n}\n\n//Test PosInfInterval's empty.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    assert(!PosInfInterval!Date(Date(2010, 1, 1)).empty);\n    assert(!PosInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty);\n    assert(!PosInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty);\n    assert(!PosInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty);\n\n    const cPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    assert(!cPosInfInterval.empty);\n    assert(!iPosInfInterval.empty);\n\n    //Verify Examples.\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty);\n}\n\n//Test PosInfInterval's contains(time point).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    assert(!posInfInterval.contains(Date(2009, 7, 4)));\n    assert(!posInfInterval.contains(Date(2010, 7, 3)));\n    assert(posInfInterval.contains(Date(2010, 7, 4)));\n    assert(posInfInterval.contains(Date(2010, 7, 5)));\n    assert(posInfInterval.contains(Date(2011, 7, 1)));\n    assert(posInfInterval.contains(Date(2012, 1, 6)));\n    assert(posInfInterval.contains(Date(2012, 1, 7)));\n    assert(posInfInterval.contains(Date(2012, 1, 8)));\n    assert(posInfInterval.contains(Date(2013, 1, 7)));\n\n    const cdate = Date(2010, 7, 6);\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    assert(posInfInterval.contains(cdate));\n    assert(cPosInfInterval.contains(cdate));\n    assert(iPosInfInterval.contains(cdate));\n\n    //Verify Examples.\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24)));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5)));\n}\n\n//Test PosInfInterval's contains(Interval).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval)\n    {\n        posInfInterval.contains(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(posInfInterval.contains(posInfInterval));\n    assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(!posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(PosInfInterval!Date(Date(2010, 7, 3)).contains(posInfInterval));\n    assert(PosInfInterval!Date(Date(2010, 7, 4)).contains(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2010, 7, 5)).contains(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 6)).contains(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 7)).contains(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 8)).contains(posInfInterval));\n\n    assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(posInfInterval.contains(interval));\n    assert(posInfInterval.contains(cInterval));\n    assert(posInfInterval.contains(iInterval));\n    assert(posInfInterval.contains(posInfInterval));\n    assert(posInfInterval.contains(cPosInfInterval));\n    assert(posInfInterval.contains(iPosInfInterval));\n    assert(!posInfInterval.contains(negInfInterval));\n    assert(!posInfInterval.contains(cNegInfInterval));\n    assert(!posInfInterval.contains(iNegInfInterval));\n    assert(cPosInfInterval.contains(interval));\n    assert(cPosInfInterval.contains(cInterval));\n    assert(cPosInfInterval.contains(iInterval));\n    assert(cPosInfInterval.contains(posInfInterval));\n    assert(cPosInfInterval.contains(cPosInfInterval));\n    assert(cPosInfInterval.contains(iPosInfInterval));\n    assert(!cPosInfInterval.contains(negInfInterval));\n    assert(!cPosInfInterval.contains(cNegInfInterval));\n    assert(!cPosInfInterval.contains(iNegInfInterval));\n    assert(iPosInfInterval.contains(interval));\n    assert(iPosInfInterval.contains(cInterval));\n    assert(iPosInfInterval.contains(iInterval));\n    assert(iPosInfInterval.contains(posInfInterval));\n    assert(iPosInfInterval.contains(cPosInfInterval));\n    assert(iPosInfInterval.contains(iPosInfInterval));\n    assert(!iPosInfInterval.contains(negInfInterval));\n    assert(!iPosInfInterval.contains(cNegInfInterval));\n    assert(!iPosInfInterval.contains(iNegInfInterval));\n\n    //Verify Examples.\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));\n\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1999, 5, 4))));\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1995, 7, 2))));\n\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(NegInfInterval!Date(Date(1996, 5, 4))));\n}\n\n//Test PosInfInterval's isBefore(time point).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    assert(!posInfInterval.isBefore(Date(2009, 7, 3)));\n    assert(!posInfInterval.isBefore(Date(2010, 7, 3)));\n    assert(!posInfInterval.isBefore(Date(2010, 7, 4)));\n    assert(!posInfInterval.isBefore(Date(2010, 7, 5)));\n    assert(!posInfInterval.isBefore(Date(2011, 7, 1)));\n    assert(!posInfInterval.isBefore(Date(2012, 1, 6)));\n    assert(!posInfInterval.isBefore(Date(2012, 1, 7)));\n    assert(!posInfInterval.isBefore(Date(2012, 1, 8)));\n    assert(!posInfInterval.isBefore(Date(2013, 1, 7)));\n\n    const cdate = Date(2010, 7, 6);\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    assert(!posInfInterval.isBefore(cdate));\n    assert(!cPosInfInterval.isBefore(cdate));\n    assert(!iPosInfInterval.isBefore(cdate));\n\n    //Verify Examples.\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24)));\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5)));\n}\n\n//Test PosInfInterval's isBefore(Interval).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval)\n    {\n        posInfInterval.isBefore(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(!posInfInterval.isBefore(posInfInterval));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(!PosInfInterval!Date(Date(2010, 7, 3)).isBefore(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2010, 7, 4)).isBefore(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2010, 7, 5)).isBefore(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 6)).isBefore(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 7)).isBefore(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 8)).isBefore(posInfInterval));\n\n    assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!posInfInterval.isBefore(interval));\n    assert(!posInfInterval.isBefore(cInterval));\n    assert(!posInfInterval.isBefore(iInterval));\n    assert(!posInfInterval.isBefore(posInfInterval));\n    assert(!posInfInterval.isBefore(cPosInfInterval));\n    assert(!posInfInterval.isBefore(iPosInfInterval));\n    assert(!posInfInterval.isBefore(negInfInterval));\n    assert(!posInfInterval.isBefore(cNegInfInterval));\n    assert(!posInfInterval.isBefore(iNegInfInterval));\n    assert(!cPosInfInterval.isBefore(interval));\n    assert(!cPosInfInterval.isBefore(cInterval));\n    assert(!cPosInfInterval.isBefore(iInterval));\n    assert(!cPosInfInterval.isBefore(posInfInterval));\n    assert(!cPosInfInterval.isBefore(cPosInfInterval));\n    assert(!cPosInfInterval.isBefore(iPosInfInterval));\n    assert(!cPosInfInterval.isBefore(negInfInterval));\n    assert(!cPosInfInterval.isBefore(cNegInfInterval));\n    assert(!cPosInfInterval.isBefore(iNegInfInterval));\n    assert(!iPosInfInterval.isBefore(interval));\n    assert(!iPosInfInterval.isBefore(cInterval));\n    assert(!iPosInfInterval.isBefore(iInterval));\n    assert(!iPosInfInterval.isBefore(posInfInterval));\n    assert(!iPosInfInterval.isBefore(cPosInfInterval));\n    assert(!iPosInfInterval.isBefore(iPosInfInterval));\n    assert(!iPosInfInterval.isBefore(negInfInterval));\n    assert(!iPosInfInterval.isBefore(cNegInfInterval));\n    assert(!iPosInfInterval.isBefore(iNegInfInterval));\n\n    //Verify Examples.\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(1992, 5, 4))));\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(2013, 3, 7))));\n\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(NegInfInterval!Date(Date(1996, 5, 4))));\n}\n\n//Test PosInfInterval's isAfter(time point).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    assert(posInfInterval.isAfter(Date(2009, 7, 3)));\n    assert(posInfInterval.isAfter(Date(2010, 7, 3)));\n    assert(!posInfInterval.isAfter(Date(2010, 7, 4)));\n    assert(!posInfInterval.isAfter(Date(2010, 7, 5)));\n    assert(!posInfInterval.isAfter(Date(2011, 7, 1)));\n    assert(!posInfInterval.isAfter(Date(2012, 1, 6)));\n    assert(!posInfInterval.isAfter(Date(2012, 1, 7)));\n    assert(!posInfInterval.isAfter(Date(2012, 1, 8)));\n    assert(!posInfInterval.isAfter(Date(2013, 1, 7)));\n\n    const cdate = Date(2010, 7, 6);\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    assert(!posInfInterval.isAfter(cdate));\n    assert(!cPosInfInterval.isAfter(cdate));\n    assert(!iPosInfInterval.isAfter(cdate));\n\n    //Verify Examples.\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24)));\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5)));\n}\n\n//Test PosInfInterval's isAfter(Interval).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval)\n    {\n        posInfInterval.isAfter(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(!posInfInterval.isAfter(posInfInterval));\n    assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAfter(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAfter(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAfter(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAfter(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAfter(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAfter(posInfInterval));\n\n    assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!posInfInterval.isAfter(interval));\n    assert(!posInfInterval.isAfter(cInterval));\n    assert(!posInfInterval.isAfter(iInterval));\n    assert(!posInfInterval.isAfter(posInfInterval));\n    assert(!posInfInterval.isAfter(cPosInfInterval));\n    assert(!posInfInterval.isAfter(iPosInfInterval));\n    assert(!posInfInterval.isAfter(negInfInterval));\n    assert(!posInfInterval.isAfter(cNegInfInterval));\n    assert(!posInfInterval.isAfter(iNegInfInterval));\n    assert(!cPosInfInterval.isAfter(interval));\n    assert(!cPosInfInterval.isAfter(cInterval));\n    assert(!cPosInfInterval.isAfter(iInterval));\n    assert(!cPosInfInterval.isAfter(posInfInterval));\n    assert(!cPosInfInterval.isAfter(cPosInfInterval));\n    assert(!cPosInfInterval.isAfter(iPosInfInterval));\n    assert(!cPosInfInterval.isAfter(negInfInterval));\n    assert(!cPosInfInterval.isAfter(cNegInfInterval));\n    assert(!cPosInfInterval.isAfter(iNegInfInterval));\n    assert(!iPosInfInterval.isAfter(interval));\n    assert(!iPosInfInterval.isAfter(cInterval));\n    assert(!iPosInfInterval.isAfter(iInterval));\n    assert(!iPosInfInterval.isAfter(posInfInterval));\n    assert(!iPosInfInterval.isAfter(cPosInfInterval));\n    assert(!iPosInfInterval.isAfter(iPosInfInterval));\n    assert(!iPosInfInterval.isAfter(negInfInterval));\n    assert(!iPosInfInterval.isAfter(cNegInfInterval));\n    assert(!iPosInfInterval.isAfter(iNegInfInterval));\n\n    //Verify Examples.\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));\n\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1990, 1, 7))));\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1999, 5, 4))));\n\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(1996, 1, 2))));\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(2000, 7, 1))));\n}\n\n//Test PosInfInterval's intersects().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval)\n    {\n        posInfInterval.intersects(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(posInfInterval.intersects(posInfInterval));\n    assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(PosInfInterval!Date(Date(2010, 7, 3)).intersects(posInfInterval));\n    assert(PosInfInterval!Date(Date(2010, 7, 4)).intersects(posInfInterval));\n    assert(PosInfInterval!Date(Date(2010, 7, 5)).intersects(posInfInterval));\n    assert(PosInfInterval!Date(Date(2012, 1, 6)).intersects(posInfInterval));\n    assert(PosInfInterval!Date(Date(2012, 1, 7)).intersects(posInfInterval));\n    assert(PosInfInterval!Date(Date(2012, 1, 8)).intersects(posInfInterval));\n\n    assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(posInfInterval.intersects(interval));\n    assert(posInfInterval.intersects(cInterval));\n    assert(posInfInterval.intersects(iInterval));\n    assert(posInfInterval.intersects(posInfInterval));\n    assert(posInfInterval.intersects(cPosInfInterval));\n    assert(posInfInterval.intersects(iPosInfInterval));\n    assert(posInfInterval.intersects(negInfInterval));\n    assert(posInfInterval.intersects(cNegInfInterval));\n    assert(posInfInterval.intersects(iNegInfInterval));\n    assert(cPosInfInterval.intersects(interval));\n    assert(cPosInfInterval.intersects(cInterval));\n    assert(cPosInfInterval.intersects(iInterval));\n    assert(cPosInfInterval.intersects(posInfInterval));\n    assert(cPosInfInterval.intersects(cPosInfInterval));\n    assert(cPosInfInterval.intersects(iPosInfInterval));\n    assert(cPosInfInterval.intersects(negInfInterval));\n    assert(cPosInfInterval.intersects(cNegInfInterval));\n    assert(cPosInfInterval.intersects(iNegInfInterval));\n    assert(iPosInfInterval.intersects(interval));\n    assert(iPosInfInterval.intersects(cInterval));\n    assert(iPosInfInterval.intersects(iInterval));\n    assert(iPosInfInterval.intersects(posInfInterval));\n    assert(iPosInfInterval.intersects(cPosInfInterval));\n    assert(iPosInfInterval.intersects(iPosInfInterval));\n    assert(iPosInfInterval.intersects(negInfInterval));\n    assert(iPosInfInterval.intersects(cNegInfInterval));\n    assert(iPosInfInterval.intersects(iNegInfInterval));\n\n    //Verify Examples.\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));\n\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1990, 1, 7))));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1999, 5, 4))));\n\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(1996, 1, 2))));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(2000, 7, 1))));\n}\n\n//Test PosInfInterval's intersection().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    static void testInterval(I, J)(scope const I interval1, scope const J interval2)\n    {\n        interval1.intersection(interval2);\n    }\n\n    assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n\n    assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 3))));\n    assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 4))));\n\n    assert(posInfInterval.intersection(posInfInterval) == posInfInterval);\n    assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2013, 7, 3)));\n    assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));\n    assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));\n    assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==\n           Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));\n    assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));\n    assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));\n    assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)));\n    assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)));\n    assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) ==\n           Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)));\n\n    assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 5)));\n    assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2012, 1, 6)));\n    assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2012, 1, 7)));\n    assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2012, 1, 8)));\n\n    assert(PosInfInterval!Date(Date(2010, 7, 3)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(PosInfInterval!Date(Date(2010, 7, 4)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(PosInfInterval!Date(Date(2010, 7, 5)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 5)));\n    assert(PosInfInterval!Date(Date(2012, 1, 6)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 6)));\n    assert(PosInfInterval!Date(Date(2012, 1, 7)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 7)));\n    assert(PosInfInterval!Date(Date(2012, 1, 8)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 8)));\n\n    assert(posInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));\n    assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6)));\n    assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));\n    assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!posInfInterval.intersection(interval).empty);\n    assert(!posInfInterval.intersection(cInterval).empty);\n    assert(!posInfInterval.intersection(iInterval).empty);\n    assert(!posInfInterval.intersection(posInfInterval).empty);\n    assert(!posInfInterval.intersection(cPosInfInterval).empty);\n    assert(!posInfInterval.intersection(iPosInfInterval).empty);\n    assert(!posInfInterval.intersection(negInfInterval).empty);\n    assert(!posInfInterval.intersection(cNegInfInterval).empty);\n    assert(!posInfInterval.intersection(iNegInfInterval).empty);\n    assert(!cPosInfInterval.intersection(interval).empty);\n    assert(!cPosInfInterval.intersection(cInterval).empty);\n    assert(!cPosInfInterval.intersection(iInterval).empty);\n    assert(!cPosInfInterval.intersection(posInfInterval).empty);\n    assert(!cPosInfInterval.intersection(cPosInfInterval).empty);\n    assert(!cPosInfInterval.intersection(iPosInfInterval).empty);\n    assert(!cPosInfInterval.intersection(negInfInterval).empty);\n    assert(!cPosInfInterval.intersection(cNegInfInterval).empty);\n    assert(!cPosInfInterval.intersection(iNegInfInterval).empty);\n    assert(!iPosInfInterval.intersection(interval).empty);\n    assert(!iPosInfInterval.intersection(cInterval).empty);\n    assert(!iPosInfInterval.intersection(iInterval).empty);\n    assert(!iPosInfInterval.intersection(posInfInterval).empty);\n    assert(!iPosInfInterval.intersection(cPosInfInterval).empty);\n    assert(!iPosInfInterval.intersection(iPosInfInterval).empty);\n    assert(!iPosInfInterval.intersection(negInfInterval).empty);\n    assert(!iPosInfInterval.intersection(cNegInfInterval).empty);\n    assert(!iPosInfInterval.intersection(iNegInfInterval).empty);\n\n    //Verify Examples.\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n           Interval!Date(Date(1996, 1, 2), Date(2000, 8, 2)));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==\n           Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)));\n\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) ==\n           PosInfInterval!Date(Date(1996, 1, 2)));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) ==\n           PosInfInterval!Date(Date(1999, 1, 12)));\n\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) ==\n           Interval!Date(Date(1996, 1, 2), Date(1999, 7, 6)));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) ==\n           Interval!Date(Date(1996, 1, 2), Date(2013, 1, 12)));\n}\n\n//Test PosInfInterval's isAdjacent().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval)\n    {\n        posInfInterval.isAdjacent(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(!posInfInterval.isAdjacent(posInfInterval));\n    assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAdjacent(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAdjacent(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAdjacent(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAdjacent(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAdjacent(posInfInterval));\n    assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAdjacent(posInfInterval));\n\n    assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!posInfInterval.isAdjacent(interval));\n    assert(!posInfInterval.isAdjacent(cInterval));\n    assert(!posInfInterval.isAdjacent(iInterval));\n    assert(!posInfInterval.isAdjacent(posInfInterval));\n    assert(!posInfInterval.isAdjacent(cPosInfInterval));\n    assert(!posInfInterval.isAdjacent(iPosInfInterval));\n    assert(!posInfInterval.isAdjacent(negInfInterval));\n    assert(!posInfInterval.isAdjacent(cNegInfInterval));\n    assert(!posInfInterval.isAdjacent(iNegInfInterval));\n    assert(!cPosInfInterval.isAdjacent(interval));\n    assert(!cPosInfInterval.isAdjacent(cInterval));\n    assert(!cPosInfInterval.isAdjacent(iInterval));\n    assert(!cPosInfInterval.isAdjacent(posInfInterval));\n    assert(!cPosInfInterval.isAdjacent(cPosInfInterval));\n    assert(!cPosInfInterval.isAdjacent(iPosInfInterval));\n    assert(!cPosInfInterval.isAdjacent(negInfInterval));\n    assert(!cPosInfInterval.isAdjacent(cNegInfInterval));\n    assert(!cPosInfInterval.isAdjacent(iNegInfInterval));\n    assert(!iPosInfInterval.isAdjacent(interval));\n    assert(!iPosInfInterval.isAdjacent(cInterval));\n    assert(!iPosInfInterval.isAdjacent(iInterval));\n    assert(!iPosInfInterval.isAdjacent(posInfInterval));\n    assert(!iPosInfInterval.isAdjacent(cPosInfInterval));\n    assert(!iPosInfInterval.isAdjacent(iPosInfInterval));\n    assert(!iPosInfInterval.isAdjacent(negInfInterval));\n    assert(!iPosInfInterval.isAdjacent(cNegInfInterval));\n    assert(!iPosInfInterval.isAdjacent(iNegInfInterval));\n\n    //Verify Examples.\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));\n    assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1990, 1, 7))));\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1996, 1, 2))));\n\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2))));\n    assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(2000, 7, 1))));\n}\n\n//Test PosInfInterval's merge().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval)\n    {\n        posInfInterval.merge(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n\n    assert(posInfInterval.merge(posInfInterval) == posInfInterval);\n    assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==\n           PosInfInterval!Date(Date(2010, 7, 1)));\n    assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==\n           PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==\n           PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==\n           PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==\n           PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n\n    assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4)));\n\n    assert(PosInfInterval!Date(Date(2010, 7, 3)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(PosInfInterval!Date(Date(2010, 7, 4)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(PosInfInterval!Date(Date(2010, 7, 5)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(PosInfInterval!Date(Date(2012, 1, 6)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(PosInfInterval!Date(Date(2012, 1, 7)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(PosInfInterval!Date(Date(2012, 1, 8)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n\n    static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3)))));\n    static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4)))));\n    static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5)))));\n    static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6)))));\n    static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7)))));\n    static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8)))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!posInfInterval.merge(interval).empty);\n    assert(!posInfInterval.merge(cInterval).empty);\n    assert(!posInfInterval.merge(iInterval).empty);\n    assert(!posInfInterval.merge(posInfInterval).empty);\n    assert(!posInfInterval.merge(cPosInfInterval).empty);\n    assert(!posInfInterval.merge(iPosInfInterval).empty);\n    static assert(!__traits(compiles, posInfInterval.merge(negInfInterval)));\n    static assert(!__traits(compiles, posInfInterval.merge(cNegInfInterval)));\n    static assert(!__traits(compiles, posInfInterval.merge(iNegInfInterval)));\n    assert(!cPosInfInterval.merge(interval).empty);\n    assert(!cPosInfInterval.merge(cInterval).empty);\n    assert(!cPosInfInterval.merge(iInterval).empty);\n    assert(!cPosInfInterval.merge(posInfInterval).empty);\n    assert(!cPosInfInterval.merge(cPosInfInterval).empty);\n    assert(!cPosInfInterval.merge(iPosInfInterval).empty);\n    static assert(!__traits(compiles, cPosInfInterval.merge(negInfInterval)));\n    static assert(!__traits(compiles, cPosInfInterval.merge(cNegInfInterval)));\n    static assert(!__traits(compiles, cPosInfInterval.merge(iNegInfInterval)));\n    assert(!iPosInfInterval.merge(interval).empty);\n    assert(!iPosInfInterval.merge(cInterval).empty);\n    assert(!iPosInfInterval.merge(iInterval).empty);\n    assert(!iPosInfInterval.merge(posInfInterval).empty);\n    assert(!iPosInfInterval.merge(cPosInfInterval).empty);\n    assert(!iPosInfInterval.merge(iPosInfInterval).empty);\n    static assert(!__traits(compiles, iPosInfInterval.merge(negInfInterval)));\n    static assert(!__traits(compiles, iPosInfInterval.merge(cNegInfInterval)));\n    static assert(!__traits(compiles, iPosInfInterval.merge(iNegInfInterval)));\n\n    //Verify Examples.\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n           PosInfInterval!Date(Date(1990, 7, 6)));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==\n           PosInfInterval!Date(Date(1996, 1, 2)));\n\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1990, 7, 6))) ==\n           PosInfInterval!Date(Date(1990, 7, 6)));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1999, 1, 12))) ==\n           PosInfInterval!Date(Date(1996, 1, 2)));\n}\n\n//Test PosInfInterval's span().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval)\n    {\n        posInfInterval.span(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(posInfInterval.span(posInfInterval) == posInfInterval);\n    assert(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) ==\n           PosInfInterval!Date(Date(2010, 7, 1)));\n    assert(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==\n           PosInfInterval!Date(Date(2010, 7, 1)));\n    assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==\n           PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==\n           PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==\n           PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==\n           PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) ==\n           PosInfInterval!Date(Date(2010, 7, 4)));\n\n    assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4)));\n\n    assert(PosInfInterval!Date(Date(2010, 7, 3)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 3)));\n    assert(PosInfInterval!Date(Date(2010, 7, 4)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(PosInfInterval!Date(Date(2010, 7, 5)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(PosInfInterval!Date(Date(2012, 1, 6)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(PosInfInterval!Date(Date(2012, 1, 7)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n    assert(PosInfInterval!Date(Date(2012, 1, 8)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));\n\n    static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3)))));\n    static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4)))));\n    static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5)))));\n    static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6)))));\n    static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7)))));\n    static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8)))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!posInfInterval.span(interval).empty);\n    assert(!posInfInterval.span(cInterval).empty);\n    assert(!posInfInterval.span(iInterval).empty);\n    assert(!posInfInterval.span(posInfInterval).empty);\n    assert(!posInfInterval.span(cPosInfInterval).empty);\n    assert(!posInfInterval.span(iPosInfInterval).empty);\n    static assert(!__traits(compiles, posInfInterval.span(negInfInterval)));\n    static assert(!__traits(compiles, posInfInterval.span(cNegInfInterval)));\n    static assert(!__traits(compiles, posInfInterval.span(iNegInfInterval)));\n    assert(!cPosInfInterval.span(interval).empty);\n    assert(!cPosInfInterval.span(cInterval).empty);\n    assert(!cPosInfInterval.span(iInterval).empty);\n    assert(!cPosInfInterval.span(posInfInterval).empty);\n    assert(!cPosInfInterval.span(cPosInfInterval).empty);\n    assert(!cPosInfInterval.span(iPosInfInterval).empty);\n    static assert(!__traits(compiles, cPosInfInterval.span(negInfInterval)));\n    static assert(!__traits(compiles, cPosInfInterval.span(cNegInfInterval)));\n    static assert(!__traits(compiles, cPosInfInterval.span(iNegInfInterval)));\n    assert(!iPosInfInterval.span(interval).empty);\n    assert(!iPosInfInterval.span(cInterval).empty);\n    assert(!iPosInfInterval.span(iInterval).empty);\n    assert(!iPosInfInterval.span(posInfInterval).empty);\n    assert(!iPosInfInterval.span(cPosInfInterval).empty);\n    assert(!iPosInfInterval.span(iPosInfInterval).empty);\n    static assert(!__traits(compiles, iPosInfInterval.span(negInfInterval)));\n    static assert(!__traits(compiles, iPosInfInterval.span(cNegInfInterval)));\n    static assert(!__traits(compiles, iPosInfInterval.span(iNegInfInterval)));\n\n    //Verify Examples.\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) ==\n           PosInfInterval!Date(Date(500, 8, 9)));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n           PosInfInterval!Date(Date(1990, 7, 6)));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==\n           PosInfInterval!Date(Date(1996, 1, 2)));\n\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1990, 7, 6))) ==\n           PosInfInterval!Date(Date(1990, 7, 6)));\n    assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1999, 1, 12))) ==\n           PosInfInterval!Date(Date(1996, 1, 2)));\n}\n\n//Test PosInfInterval's shift().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = PosInfInterval!Date(Date(2010, 7, 4));\n\n    static void testInterval(I)(I interval, scope const Duration duration,\n                                scope const I expected, size_t line = __LINE__)\n    {\n        interval.shift(duration);\n        assert(interval == expected);\n    }\n\n    testInterval(interval, dur!\"days\"(22), PosInfInterval!Date(Date(2010, 7, 26)));\n    testInterval(interval, dur!\"days\"(-22), PosInfInterval!Date(Date(2010, 6, 12)));\n\n    const cInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    static assert(!__traits(compiles, cInterval.shift(dur!\"days\"(5))));\n    static assert(!__traits(compiles, iInterval.shift(dur!\"days\"(5))));\n\n    //Verify Examples.\n    auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));\n    auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));\n\n    interval1.shift(dur!\"days\"(50));\n    assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21)));\n\n    interval2.shift(dur!\"days\"(-50));\n    assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13)));\n}\n\n//Test PosInfInterval's shift(int, int, AllowDayOverflow).\n@safe unittest\n{\n    import std.datetime.date;\n\n    {\n        auto interval = PosInfInterval!Date(Date(2010, 7, 4));\n\n        static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow,\n                                    in I expected, size_t line = __LINE__)\n        {\n            interval.shift(years, months, allow);\n            assert(interval == expected);\n        }\n\n        testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2015, 7, 4)));\n        testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4)));\n\n        auto interval2 = PosInfInterval!Date(Date(2000, 1, 29));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1)));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28)));\n    }\n\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    static assert(!__traits(compiles, cPosInfInterval.shift(1)));\n    static assert(!__traits(compiles, iPosInfInterval.shift(1)));\n\n    //Verify Examples.\n    auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));\n    auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));\n\n    interval1.shift(2);\n    assert(interval1 == PosInfInterval!Date(Date(1998, 1, 2)));\n\n    interval2.shift(-2);\n    assert(interval2 == PosInfInterval!Date(Date(1994, 1, 2)));\n}\n\n//Test PosInfInterval's expand().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = PosInfInterval!Date(Date(2000, 7, 4));\n\n    static void testInterval(I)(I interval, scope const Duration duration,\n                                scope const I expected, size_t line = __LINE__)\n    {\n        interval.expand(duration);\n        assert(interval == expected);\n    }\n\n    testInterval(interval, dur!\"days\"(22), PosInfInterval!Date(Date(2000, 6, 12)));\n    testInterval(interval, dur!\"days\"(-22), PosInfInterval!Date(Date(2000, 7, 26)));\n\n    const cInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    static assert(!__traits(compiles, cInterval.expand(dur!\"days\"(5))));\n    static assert(!__traits(compiles, iInterval.expand(dur!\"days\"(5))));\n\n    //Verify Examples.\n    auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));\n    auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));\n\n    interval1.expand(dur!\"days\"(2));\n    assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31)));\n\n    interval2.expand(dur!\"days\"(-2));\n    assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4)));\n}\n\n//Test PosInfInterval's expand(int, int, AllowDayOverflow).\n@safe unittest\n{\n    import std.datetime.date;\n\n    {\n        auto interval = PosInfInterval!Date(Date(2000, 7, 4));\n\n        static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow,\n                                    in I expected, size_t line = __LINE__)\n        {\n            interval.expand(years, months, allow);\n            assert(interval == expected);\n        }\n\n        testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(1995, 7, 4)));\n        testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4)));\n\n        auto interval2 = PosInfInterval!Date(Date(2000, 1, 29));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29)));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29)));\n    }\n\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    static assert(!__traits(compiles, cPosInfInterval.expand(1)));\n    static assert(!__traits(compiles, iPosInfInterval.expand(1)));\n\n    //Verify Examples.\n    auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));\n    auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));\n\n    interval1.expand(2);\n    assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2)));\n\n    interval2.expand(-2);\n    assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2)));\n}\n\n//Test PosInfInterval's fwdRange().\n@system unittest\n{\n    import std.datetime.date;\n\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 9, 19));\n\n    static void testInterval(PosInfInterval!Date posInfInterval)\n    {\n        posInfInterval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront();\n    }\n\n    assertThrown!DateTimeException(testInterval(posInfInterval));\n\n    assert(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front ==\n           Date(2010, 9, 12));\n\n    assert(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front ==\n           Date(2010, 9, 17));\n\n    //Verify Examples.\n    auto interval = PosInfInterval!Date(Date(2010, 9, 1));\n    auto func = delegate (scope const Date date)\n                {\n                    if ((date.day & 1) == 0)\n                        return date + dur!\"days\"(2);\n                    return date + dur!\"days\"(1);\n                };\n    auto range = interval.fwdRange(func);\n\n    assert(range.front == Date(2010, 9, 1)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 2));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 4));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 6));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 8));\n\n    range.popFront();\n    assert(!range.empty);\n\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    assert(!cPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);\n    assert(!iPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);\n}\n\n//Test PosInfInterval's toString().\n@safe unittest\n{\n    import std.datetime.date;\n    assert(PosInfInterval!Date(Date(2010, 7, 4)).toString() == \"[2010-Jul-04 - ∞)\");\n\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    assert(cPosInfInterval.toString());\n    assert(iPosInfInterval.toString());\n}\n\n\n/++\n    Represents an interval of time which has negative infinity as its starting\n    point.\n\n    Any ranges which iterate over a `NegInfInterval` are infinite. So, the\n    main purpose of using `NegInfInterval` is to create an infinite range\n    which starts at negative infinity and goes to a fixed end point.\n    Iterate over it in reverse.\n  +/\nstruct NegInfInterval(TP)\n{\npublic:\n\n    /++\n        Params:\n            end = The time point which ends the interval.\n\n        Example:\n--------------------\nauto interval = PosInfInterval!Date(Date(1996, 1, 2));\n--------------------\n      +/\n    this(scope const TP end) pure nothrow\n    {\n        _end = cast(TP) end;\n    }\n\n\n    /++\n        Params:\n            rhs = The `NegInfInterval` to assign to this one.\n      +/\n    ref NegInfInterval opAssign(const ref NegInfInterval rhs) pure nothrow\n    {\n        _end = cast(TP) rhs._end;\n        return this;\n    }\n\n\n    /++\n        Params:\n            rhs = The `NegInfInterval` to assign to this one.\n      +/\n    ref NegInfInterval opAssign(NegInfInterval rhs) pure nothrow\n    {\n        _end = cast(TP) rhs._end;\n        return this;\n    }\n\n\n    /++\n        The end point of the interval. It is excluded from the interval.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1));\n--------------------\n      +/\n    @property TP end() const pure nothrow\n    {\n        return cast(TP)_end;\n    }\n\n\n    /++\n        The end point of the interval. It is excluded from the interval.\n\n        Params:\n            timePoint = The time point to set end to.\n      +/\n    @property void end(TP timePoint) pure nothrow\n    {\n        _end = timePoint;\n    }\n\n\n    /++\n        Whether the interval's length is 0. Always returns false.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(1996, 1, 2)).empty);\n--------------------\n      +/\n    enum bool empty = false;\n\n\n    /++\n        Whether the given time point is within this interval.\n\n        Params:\n            timePoint = The time point to check for inclusion in this interval.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24)));\nassert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5)));\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1)));\n--------------------\n      +/\n    bool contains(TP timePoint) const pure nothrow\n    {\n        return timePoint < _end;\n    }\n\n\n    /++\n        Whether the given interval is completely within this interval.\n\n        Params:\n            interval = The interval to check for inclusion in this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).contains(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).contains(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(\n            Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));\n--------------------\n      +/\n    bool contains(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return interval._end <= _end;\n    }\n\n\n    /++\n        Whether the given interval is completely within this interval.\n\n        Always returns false because an interval beginning at negative\n        infinity can never contain an interval going to positive infinity.\n\n        Params:\n            interval = The interval to check for inclusion in this interval.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(\n            PosInfInterval!Date(Date(1999, 5, 4))));\n--------------------\n      +/\n    bool contains(scope const PosInfInterval!TP interval) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Whether the given interval is completely within this interval.\n\n        Params:\n            interval = The interval to check for inclusion in this interval.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).contains(\n            NegInfInterval!Date(Date(1996, 5, 4))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(\n            NegInfInterval!Date(Date(2013, 7, 9))));\n--------------------\n      +/\n    bool contains(scope const NegInfInterval interval) const pure nothrow\n    {\n        return interval._end <= _end;\n    }\n\n\n    /++\n        Whether this interval is before the given time point.\n\n        Params:\n            timePoint = The time point to check whether this interval is\n                        before it.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24)));\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5)));\nassert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1)));\n--------------------\n      +/\n    bool isBefore(scope const TP timePoint) const pure nothrow\n    {\n        return timePoint >= _end;\n    }\n\n\n    /++\n        Whether this interval is before the given interval and does not\n        intersect it.\n\n        Params:\n            interval = The interval to check for against this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(\n            Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));\n--------------------\n      +/\n    bool isBefore(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return _end <= interval._begin;\n    }\n\n\n    /++\n        Whether this interval is before the given interval and does not\n        intersect it.\n\n        Params:\n            interval = The interval to check for against this interval.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(\n            PosInfInterval!Date(Date(1999, 5, 4))));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(\n            PosInfInterval!Date(Date(2012, 3, 1))));\n--------------------\n      +/\n    bool isBefore(scope const PosInfInterval!TP interval) const pure nothrow\n    {\n        return _end <= interval._begin;\n    }\n\n\n    /++\n        Whether this interval is before the given interval and does not\n        intersect it.\n\n        Always returns false because an interval beginning at negative\n        infinity can never be before another interval beginning at negative\n        infinity.\n\n        Params:\n            interval = The interval to check for against this interval.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(\n            NegInfInterval!Date(Date(1996, 5, 4))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(\n            NegInfInterval!Date(Date(2013, 7, 9))));\n--------------------\n      +/\n    bool isBefore(scope const NegInfInterval interval) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Whether this interval is after the given time point.\n\n        Always returns false because an interval beginning at negative infinity\n        can never be after any time point.\n\n        Params:\n            timePoint = The time point to check whether this interval is after\n                        it.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24)));\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5)));\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1)));\n--------------------\n      +/\n    bool isAfter(scope const TP timePoint) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Whether this interval is after the given interval and does not\n        intersect it.\n\n        Always returns false (unless the given interval is empty) because an\n        interval beginning at negative infinity can never be after any other\n        interval.\n\n        Params:\n            interval = The interval to check against this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(\n            Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));\n--------------------\n      +/\n    bool isAfter(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return false;\n    }\n\n\n    /++\n        Whether this interval is after the given interval and does not intersect\n        it.\n\n        Always returns false because an interval beginning at negative infinity\n        can never be after any other interval.\n\n        Params:\n            interval = The interval to check against this interval.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(\n            PosInfInterval!Date(Date(1999, 5, 4))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(\n            PosInfInterval!Date(Date(2012, 3, 1))));\n--------------------\n      +/\n    bool isAfter(scope const PosInfInterval!TP interval) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Whether this interval is after the given interval and does not intersect\n        it.\n\n        Always returns false because an interval beginning at negative infinity\n        can never be after any other interval.\n\n        Params:\n            interval = The interval to check against this interval.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(\n            NegInfInterval!Date(Date(1996, 5, 4))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(\n            NegInfInterval!Date(Date(2013, 7, 9))));\n--------------------\n      +/\n    bool isAfter(scope const NegInfInterval interval) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Whether the given interval overlaps this interval.\n\n        Params:\n            interval = The interval to check for intersection with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(\n            Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(\n            Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));\n--------------------\n      +/\n    bool intersects(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return interval._begin < _end;\n    }\n\n\n    /++\n        Whether the given interval overlaps this interval.\n\n        Params:\n            interval = The interval to check for intersection with this\n                       interval.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(\n            PosInfInterval!Date(Date(1999, 5, 4))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(\n            PosInfInterval!Date(Date(2012, 3, 1))));\n--------------------\n      +/\n    bool intersects(scope const PosInfInterval!TP interval) const pure nothrow\n    {\n        return interval._begin < _end;\n    }\n\n\n    /++\n        Whether the given interval overlaps this interval.\n\n        Always returns true because two intervals beginning at negative infinity\n        always overlap.\n\n        Params:\n            interval = The interval to check for intersection with this interval.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(\n            NegInfInterval!Date(Date(1996, 5, 4))));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(\n            NegInfInterval!Date(Date(2013, 7, 9))));\n--------------------\n      +/\n    bool intersects(scope const NegInfInterval!TP interval) const pure nothrow\n    {\n        return true;\n    }\n\n\n    /++\n        Returns the intersection of two intervals\n\n        Params:\n            interval = The interval to intersect with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect or if the given interval is empty.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n       Interval!Date(Date(1990, 7 , 6), Date(2000, 8, 2)));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(\n            Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==\n       Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));\n--------------------\n      +/\n    Interval!TP intersection(scope const Interval!TP interval) const\n    {\n        import std.format : format;\n\n        enforce(this.intersects(interval),\n                new DateTimeException(format(\"%s and %s do not intersect.\", this, interval)));\n\n        auto end = _end < interval._end ? _end : interval._end;\n\n        return Interval!TP(interval._begin, end);\n    }\n\n\n    /++\n        Returns the intersection of two intervals\n\n        Params:\n            interval = The interval to intersect with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(\n            PosInfInterval!Date(Date(1990, 7, 6))) ==\n       Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(\n            PosInfInterval!Date(Date(1999, 1, 12))) ==\n       Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));\n--------------------\n      +/\n    Interval!TP intersection(scope const PosInfInterval!TP interval) const\n    {\n        import std.format : format;\n\n        enforce(this.intersects(interval),\n                new DateTimeException(format(\"%s and %s do not intersect.\", this, interval)));\n\n        return Interval!TP(interval._begin, _end);\n    }\n\n\n    /++\n        Returns the intersection of two intervals\n\n        Params:\n            interval = The interval to intersect with this interval.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(\n            NegInfInterval!Date(Date(1999, 7, 6))) ==\n       NegInfInterval!Date(Date(1999, 7 , 6)));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(\n            NegInfInterval!Date(Date(2013, 1, 12))) ==\n       NegInfInterval!Date(Date(2012, 3 , 1)));\n--------------------\n      +/\n    NegInfInterval intersection(scope const NegInfInterval interval) const nothrow\n    {\n        return NegInfInterval(_end < interval._end ? _end : interval._end);\n    }\n\n\n    /++\n        Whether the given interval is adjacent to this interval.\n\n        Params:\n            interval = The interval to check whether its adjecent to this\n                       interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(\n            Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(\n            Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(\n            Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));\n--------------------\n      +/\n    bool isAdjacent(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return interval._begin == _end;\n    }\n\n\n    /++\n        Whether the given interval is adjacent to this interval.\n\n        Params:\n            interval = The interval to check whether its adjecent to this\n                       interval.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(\n            PosInfInterval!Date(Date(1999, 5, 4))));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(\n            PosInfInterval!Date(Date(2012, 3, 1))));\n--------------------\n      +/\n    bool isAdjacent(scope const PosInfInterval!TP interval) const pure nothrow\n    {\n        return interval._begin == _end;\n    }\n\n\n    /++\n        Whether the given interval is adjacent to this interval.\n\n        Always returns false because two intervals beginning at negative\n        infinity can never be adjacent to one another.\n\n        Params:\n            interval = The interval to check whether its adjecent to this\n                       interval.\n\n        Example:\n--------------------\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(\n            NegInfInterval!Date(Date(1996, 5, 4))));\n\nassert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(\n            NegInfInterval!Date(Date(2012, 3, 1))));\n--------------------\n      +/\n    bool isAdjacent(scope const NegInfInterval interval) const pure nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Returns the union of two intervals\n\n        Params:\n            interval = The interval to merge with this interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the two intervals do\n            not intersect and are not adjacent or if the given interval is empty.\n\n        Note:\n            There is no overload for `merge` which takes a\n            `PosInfInterval`, because an interval\n            going from negative infinity to positive infinity\n            is not possible.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).merge(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n       NegInfInterval!Date(Date(2012, 3 , 1)));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).merge(\n            Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==\n       NegInfInterval!Date(Date(2015, 9 , 2)));\n--------------------\n      +/\n    NegInfInterval merge(scope const Interval!TP interval) const\n    {\n        import std.format : format;\n\n        enforce(this.isAdjacent(interval) || this.intersects(interval),\n                new DateTimeException(format(\"%s and %s are not adjacent and do not intersect.\", this, interval)));\n\n        return NegInfInterval(_end > interval._end ? _end : interval._end);\n    }\n\n\n    /++\n        Returns the union of two intervals\n\n        Params:\n            interval = The interval to merge with this interval.\n\n        Note:\n            There is no overload for `merge` which takes a\n            `PosInfInterval`, because an interval\n            going from negative infinity to positive infinity\n            is not possible.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).merge(\n            NegInfInterval!Date(Date(1999, 7, 6))) ==\n       NegInfInterval!Date(Date(2012, 3 , 1)));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).merge(\n            NegInfInterval!Date(Date(2013, 1, 12))) ==\n       NegInfInterval!Date(Date(2013, 1 , 12)));\n--------------------\n      +/\n    NegInfInterval merge(scope const NegInfInterval interval) const pure nothrow\n    {\n        return NegInfInterval(_end > interval._end ? _end : interval._end);\n    }\n\n\n    /++\n        Returns an interval that covers from the earliest time point of two\n        intervals up to (but not including) the latest time point of two\n        intervals.\n\n        Params:\n            interval = The interval to create a span together with this\n                       interval.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given interval\n            is empty.\n\n        Note:\n            There is no overload for `span` which takes a\n            `PosInfInterval`, because an interval\n            going from negative infinity to positive infinity\n            is not possible.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).span(\n            Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n       NegInfInterval!Date(Date(2012, 3 , 1)));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).span(\n            Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==\n       NegInfInterval!Date(Date(2015, 9 , 2)));\n\nassert(NegInfInterval!Date(Date(1600, 1, 7)).span(\n            Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) ==\n       NegInfInterval!Date(Date(2017, 7 , 1)));\n--------------------\n      +/\n    NegInfInterval span(scope const Interval!TP interval) const pure\n    {\n        interval._enforceNotEmpty();\n        return NegInfInterval(_end > interval._end ? _end : interval._end);\n    }\n\n\n    /++\n        Returns an interval that covers from the earliest time point of two\n        intervals up to (but not including) the latest time point of two\n        intervals.\n\n        Params:\n            interval = The interval to create a span together with this\n                       interval.\n\n        Note:\n            There is no overload for `span` which takes a\n            `PosInfInterval`, because an interval\n            going from negative infinity to positive infinity\n            is not possible.\n\n        Example:\n--------------------\nassert(NegInfInterval!Date(Date(2012, 3, 1)).span(\n            NegInfInterval!Date(Date(1999, 7, 6))) ==\n       NegInfInterval!Date(Date(2012, 3 , 1)));\n\nassert(NegInfInterval!Date(Date(2012, 3, 1)).span(\n            NegInfInterval!Date(Date(2013, 1, 12))) ==\n       NegInfInterval!Date(Date(2013, 1 , 12)));\n--------------------\n      +/\n    NegInfInterval span(scope const NegInfInterval interval) const pure nothrow\n    {\n        return NegInfInterval(_end > interval._end ? _end : interval._end);\n    }\n\n\n    /++\n        Shifts the `end` of this interval forward or backwards in time by the\n        given duration (a positive duration shifts the interval forward; a\n        negative duration shifts it backward). Effectively, it does\n        $(D end += duration).\n\n        Params:\n            duration = The duration to shift the interval by.\n\n        Example:\n--------------------\nauto interval1 = NegInfInterval!Date(Date(2012, 4, 5));\nauto interval2 = NegInfInterval!Date(Date(2012, 4, 5));\n\ninterval1.shift(dur!\"days\"(50));\nassert(interval1 == NegInfInterval!Date(Date(2012, 5, 25)));\n\ninterval2.shift(dur!\"days\"(-50));\nassert(interval2 == NegInfInterval!Date( Date(2012, 2, 15)));\n--------------------\n      +/\n    void shift(D)(D duration) pure nothrow\n        if (__traits(compiles, end + duration))\n    {\n        _end += duration;\n    }\n\n\n    static if (__traits(compiles, end.add!\"months\"(1)) &&\n               __traits(compiles, end.add!\"years\"(1)))\n    {\n        /++\n            Shifts the `end` of this interval forward or backwards in time by\n            the given number of years and/or months (a positive number of years\n            and months shifts the interval forward; a negative number shifts it\n            backward). It adds the years the given years and months to end. It\n            effectively calls `add!\"years\"()` and then `add!\"months\"()`\n            on end with the given number of years and months.\n\n            Params:\n                years         = The number of years to shift the interval by.\n                months        = The number of months to shift the interval by.\n                allowOverflow = Whether the days should be allowed to overflow\n                                on `end`, causing its month to increment.\n\n            Throws:\n                $(REF DateTimeException,std,datetime,date) if empty is true or\n                if the resulting interval would be invalid.\n\n            Example:\n--------------------\nauto interval1 = NegInfInterval!Date(Date(2012, 3, 1));\nauto interval2 = NegInfInterval!Date(Date(2012, 3, 1));\n\ninterval1.shift(2);\nassert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));\n\ninterval2.shift(-2);\nassert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));\n--------------------\n          +/\n        void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)\n            if (isIntegral!T)\n        {\n            auto end = _end;\n\n            end.add!\"years\"(years, allowOverflow);\n            end.add!\"months\"(months, allowOverflow);\n\n            _end = end;\n        }\n    }\n\n\n    /++\n        Expands the interval forwards in time. Effectively, it does\n        $(D end += duration).\n\n        Params:\n            duration = The duration to expand the interval by.\n\n        Example:\n--------------------\nauto interval1 = NegInfInterval!Date(Date(2012, 3, 1));\nauto interval2 = NegInfInterval!Date(Date(2012, 3, 1));\n\ninterval1.expand(dur!\"days\"(2));\nassert(interval1 == NegInfInterval!Date(Date(2012, 3, 3)));\n\ninterval2.expand(dur!\"days\"(-2));\nassert(interval2 == NegInfInterval!Date(Date(2012, 2, 28)));\n--------------------\n      +/\n    void expand(D)(D duration) pure nothrow\n        if (__traits(compiles, end + duration))\n    {\n        _end += duration;\n    }\n\n\n    static if (__traits(compiles, end.add!\"months\"(1)) &&\n               __traits(compiles, end.add!\"years\"(1)))\n    {\n        /++\n            Expands the interval forwards and/or backwards in time. Effectively,\n            it adds the given number of months/years to end.\n\n            Params:\n                years         = The number of years to expand the interval by.\n                months        = The number of months to expand the interval by.\n                allowOverflow = Whether the days should be allowed to overflow\n                                on `end`, causing their month to increment.\n\n            Throws:\n                $(REF DateTimeException,std,datetime,date) if empty is true or\n                if the resulting interval would be invalid.\n\n            Example:\n--------------------\nauto interval1 = NegInfInterval!Date(Date(2012, 3, 1));\nauto interval2 = NegInfInterval!Date(Date(2012, 3, 1));\n\ninterval1.expand(2);\nassert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));\n\ninterval2.expand(-2);\nassert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));\n--------------------\n          +/\n        void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)\n            if (isIntegral!T)\n        {\n            auto end = _end;\n\n            end.add!\"years\"(years, allowOverflow);\n            end.add!\"months\"(months, allowOverflow);\n\n            _end = end;\n        }\n    }\n\n\n    /++\n        Returns a range which iterates backwards over the interval, starting\n        at `end`, using $(D_PARAM func) to generate each successive time\n        point.\n\n        The range's `front` is the interval's `end`. $(D_PARAM func) is\n        used to generate the next `front` when `popFront` is called. If\n        $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called\n        before the range is returned (so that `front` is a time point which\n        $(D_PARAM func) would generate).\n\n        If $(D_PARAM func) ever generates a time point greater than or equal to\n        the current `front` of the range, then a\n        $(REF DateTimeException,std,datetime,date) will be thrown.\n\n        There are helper functions in this module which generate common\n        delegates to pass to `bwdRange`. Their documentation starts with\n        \"Range-generating function,\" to make them easily searchable.\n\n        Params:\n            func     = The function used to generate the time points of the\n                       range over the interval.\n            popFirst = Whether `popFront` should be called on the range\n                       before returning it.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n\n        Warning:\n            $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)\n            would be a function pointer to a pure function, but forcing\n            $(D_PARAM func) to be pure is far too restrictive to be useful, and\n            in order to have the ease of use of having functions which generate\n            functions to pass to `fwdRange`, $(D_PARAM func) must be a\n            delegate.\n\n            If $(D_PARAM func) retains state which changes as it is called, then\n            some algorithms will not work correctly, because the range's\n            `save` will have failed to have really saved the range's state.\n            To avoid such bugs, don't pass a delegate which is\n            not logically pure to `fwdRange`. If $(D_PARAM func) is given the\n            same time point with two different calls, it must return the same\n            result both times.\n\n            Of course, none of the functions in this module have this problem,\n            so it's only relevant for custom delegates.\n\n        Example:\n--------------------\nauto interval = NegInfInterval!Date(Date(2010, 9, 9));\nauto func = delegate (scope const Date date) //For iterating over even-numbered days.\n            {\n                if ((date.day & 1) == 0)\n                    return date - dur!\"days\"(2);\n\n                return date - dur!\"days\"(1);\n            };\nauto range = interval.bwdRange(func);\n\nassert(range.front == Date(2010, 9, 9)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).\n\nrange.popFront();\nassert(range.front == Date(2010, 9, 8));\n\nrange.popFront();\nassert(range.front == Date(2010, 9, 6));\n\nrange.popFront();\nassert(range.front == Date(2010, 9, 4));\n\nrange.popFront();\nassert(range.front == Date(2010, 9, 2));\n\nrange.popFront();\nassert(!range.empty);\n--------------------\n      +/\n    NegInfIntervalRange!(TP) bwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const\n    {\n        auto range = NegInfIntervalRange!(TP)(this, func);\n\n        if (popFirst == PopFirst.yes)\n            range.popFront();\n\n        return range;\n    }\n\n\n    /+\n        Converts this interval to a string.\n      +/\n    //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't\n    //have versions of toString() with extra modifiers, so we define one version\n    //with modifiers and one without.\n    string toString()\n    {\n        return _toStringImpl();\n    }\n\n\n    /++\n        Converts this interval to a string.\n      +/\n    //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't\n    //have versions of toString() with extra modifiers, so we define one version\n    //with modifiers and one without.\n    string toString() const nothrow\n    {\n        return _toStringImpl();\n    }\n\nprivate:\n\n    /+\n        Since we have two versions of toString(), we have _toStringImpl()\n        so that they can share implementations.\n      +/\n    string _toStringImpl() const nothrow\n    {\n        import std.format : format;\n        try\n            return format(\"[-∞ - %s)\", _end);\n        catch (Exception e)\n            assert(0, \"format() threw.\");\n    }\n\n\n    TP _end;\n}\n\n//Test NegInfInterval's constructor.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    NegInfInterval!Date(Date.init);\n    NegInfInterval!TimeOfDay(TimeOfDay.init);\n    NegInfInterval!DateTime(DateTime.init);\n    NegInfInterval!SysTime(SysTime(0));\n}\n\n//Test NegInfInterval's end.\n@safe unittest\n{\n    import std.datetime.date;\n\n    assert(NegInfInterval!Date(Date(2010, 1, 1)).end == Date(2010, 1, 1));\n    assert(NegInfInterval!Date(Date(2010, 1, 1)).end == Date(2010, 1, 1));\n    assert(NegInfInterval!Date(Date(1998, 1, 1)).end == Date(1998, 1, 1));\n\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(cNegInfInterval.end != Date.init);\n    assert(iNegInfInterval.end != Date.init);\n\n    //Verify Examples.\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1));\n}\n\n//Test NegInfInterval's empty.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    assert(!NegInfInterval!Date(Date(2010, 1, 1)).empty);\n    assert(!NegInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty);\n    assert(!NegInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty);\n    assert(!NegInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty);\n\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!cNegInfInterval.empty);\n    assert(!iNegInfInterval.empty);\n\n    //Verify Examples.\n    assert(!NegInfInterval!Date(Date(1996, 1, 2)).empty);\n}\n\n//Test NegInfInterval's contains(time point).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    assert(negInfInterval.contains(Date(2009, 7, 4)));\n    assert(negInfInterval.contains(Date(2010, 7, 3)));\n    assert(negInfInterval.contains(Date(2010, 7, 4)));\n    assert(negInfInterval.contains(Date(2010, 7, 5)));\n    assert(negInfInterval.contains(Date(2011, 7, 1)));\n    assert(negInfInterval.contains(Date(2012, 1, 6)));\n    assert(!negInfInterval.contains(Date(2012, 1, 7)));\n    assert(!negInfInterval.contains(Date(2012, 1, 8)));\n    assert(!negInfInterval.contains(Date(2013, 1, 7)));\n\n    const cdate = Date(2010, 7, 6);\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(negInfInterval.contains(cdate));\n    assert(cNegInfInterval.contains(cdate));\n    assert(iNegInfInterval.contains(cdate));\n\n    //Verify Examples.\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24)));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5)));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1)));\n}\n\n//Test NegInfInterval's contains(Interval).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval)\n    {\n        negInfInterval.contains(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(negInfInterval.contains(negInfInterval));\n    assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(!NegInfInterval!Date(Date(2010, 7, 3)).contains(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2010, 7, 4)).contains(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2010, 7, 5)).contains(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2012, 1, 6)).contains(negInfInterval));\n    assert(NegInfInterval!Date(Date(2012, 1, 7)).contains(negInfInterval));\n    assert(NegInfInterval!Date(Date(2012, 1, 8)).contains(negInfInterval));\n\n    assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(negInfInterval.contains(interval));\n    assert(negInfInterval.contains(cInterval));\n    assert(negInfInterval.contains(iInterval));\n    assert(!negInfInterval.contains(posInfInterval));\n    assert(!negInfInterval.contains(cPosInfInterval));\n    assert(!negInfInterval.contains(iPosInfInterval));\n    assert(negInfInterval.contains(negInfInterval));\n    assert(negInfInterval.contains(cNegInfInterval));\n    assert(negInfInterval.contains(iNegInfInterval));\n    assert(cNegInfInterval.contains(interval));\n    assert(cNegInfInterval.contains(cInterval));\n    assert(cNegInfInterval.contains(iInterval));\n    assert(!cNegInfInterval.contains(posInfInterval));\n    assert(!cNegInfInterval.contains(cPosInfInterval));\n    assert(!cNegInfInterval.contains(iPosInfInterval));\n    assert(cNegInfInterval.contains(negInfInterval));\n    assert(cNegInfInterval.contains(cNegInfInterval));\n    assert(cNegInfInterval.contains(iNegInfInterval));\n    assert(iNegInfInterval.contains(interval));\n    assert(iNegInfInterval.contains(cInterval));\n    assert(iNegInfInterval.contains(iInterval));\n    assert(!iNegInfInterval.contains(posInfInterval));\n    assert(!iNegInfInterval.contains(cPosInfInterval));\n    assert(!iNegInfInterval.contains(iPosInfInterval));\n    assert(iNegInfInterval.contains(negInfInterval));\n    assert(iNegInfInterval.contains(cNegInfInterval));\n    assert(iNegInfInterval.contains(iNegInfInterval));\n\n    //Verify Examples.\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));\n\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4))));\n\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(2013, 7, 9))));\n}\n\n//Test NegInfInterval's isBefore(time point).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    assert(!negInfInterval.isBefore(Date(2009, 7, 4)));\n    assert(!negInfInterval.isBefore(Date(2010, 7, 3)));\n    assert(!negInfInterval.isBefore(Date(2010, 7, 4)));\n    assert(!negInfInterval.isBefore(Date(2010, 7, 5)));\n    assert(!negInfInterval.isBefore(Date(2011, 7, 1)));\n    assert(!negInfInterval.isBefore(Date(2012, 1, 6)));\n    assert(negInfInterval.isBefore(Date(2012, 1, 7)));\n    assert(negInfInterval.isBefore(Date(2012, 1, 8)));\n    assert(negInfInterval.isBefore(Date(2013, 1, 7)));\n\n    const cdate = Date(2010, 7, 6);\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!negInfInterval.isBefore(cdate));\n    assert(!cNegInfInterval.isBefore(cdate));\n    assert(!iNegInfInterval.isBefore(cdate));\n\n    //Verify Examples.\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24)));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5)));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1)));\n}\n\n//Test NegInfInterval's isBefore(Interval).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval)\n    {\n        negInfInterval.isBefore(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(!negInfInterval.isBefore(negInfInterval));\n    assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(!NegInfInterval!Date(Date(2010, 7, 3)).isBefore(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2010, 7, 4)).isBefore(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2010, 7, 5)).isBefore(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2012, 1, 6)).isBefore(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2012, 1, 7)).isBefore(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2012, 1, 8)).isBefore(negInfInterval));\n\n    assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!negInfInterval.isBefore(interval));\n    assert(!negInfInterval.isBefore(cInterval));\n    assert(!negInfInterval.isBefore(iInterval));\n    assert(!negInfInterval.isBefore(posInfInterval));\n    assert(!negInfInterval.isBefore(cPosInfInterval));\n    assert(!negInfInterval.isBefore(iPosInfInterval));\n    assert(!negInfInterval.isBefore(negInfInterval));\n    assert(!negInfInterval.isBefore(cNegInfInterval));\n    assert(!negInfInterval.isBefore(iNegInfInterval));\n    assert(!cNegInfInterval.isBefore(interval));\n    assert(!cNegInfInterval.isBefore(cInterval));\n    assert(!cNegInfInterval.isBefore(iInterval));\n    assert(!cNegInfInterval.isBefore(posInfInterval));\n    assert(!cNegInfInterval.isBefore(cPosInfInterval));\n    assert(!cNegInfInterval.isBefore(iPosInfInterval));\n    assert(!cNegInfInterval.isBefore(negInfInterval));\n    assert(!cNegInfInterval.isBefore(cNegInfInterval));\n    assert(!cNegInfInterval.isBefore(iNegInfInterval));\n    assert(!iNegInfInterval.isBefore(interval));\n    assert(!iNegInfInterval.isBefore(cInterval));\n    assert(!iNegInfInterval.isBefore(iInterval));\n    assert(!iNegInfInterval.isBefore(posInfInterval));\n    assert(!iNegInfInterval.isBefore(cPosInfInterval));\n    assert(!iNegInfInterval.isBefore(iPosInfInterval));\n    assert(!iNegInfInterval.isBefore(negInfInterval));\n    assert(!iNegInfInterval.isBefore(cNegInfInterval));\n    assert(!iNegInfInterval.isBefore(iNegInfInterval));\n\n    //Verify Examples.\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));\n\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4))));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2012, 3, 1))));\n\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(2013, 7, 9))));\n}\n\n//Test NegInfInterval's isAfter(time point).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    assert(!negInfInterval.isAfter(Date(2009, 7, 4)));\n    assert(!negInfInterval.isAfter(Date(2010, 7, 3)));\n    assert(!negInfInterval.isAfter(Date(2010, 7, 4)));\n    assert(!negInfInterval.isAfter(Date(2010, 7, 5)));\n    assert(!negInfInterval.isAfter(Date(2011, 7, 1)));\n    assert(!negInfInterval.isAfter(Date(2012, 1, 6)));\n    assert(!negInfInterval.isAfter(Date(2012, 1, 7)));\n    assert(!negInfInterval.isAfter(Date(2012, 1, 8)));\n    assert(!negInfInterval.isAfter(Date(2013, 1, 7)));\n\n    const cdate = Date(2010, 7, 6);\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!negInfInterval.isAfter(cdate));\n    assert(!cNegInfInterval.isAfter(cdate));\n    assert(!iNegInfInterval.isAfter(cdate));\n}\n\n//Test NegInfInterval's isAfter(Interval).\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval)\n    {\n        negInfInterval.isAfter(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(!negInfInterval.isAfter(negInfInterval));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAfter(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAfter(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAfter(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAfter(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAfter(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAfter(negInfInterval));\n\n    assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!negInfInterval.isAfter(interval));\n    assert(!negInfInterval.isAfter(cInterval));\n    assert(!negInfInterval.isAfter(iInterval));\n    assert(!negInfInterval.isAfter(posInfInterval));\n    assert(!negInfInterval.isAfter(cPosInfInterval));\n    assert(!negInfInterval.isAfter(iPosInfInterval));\n    assert(!negInfInterval.isAfter(negInfInterval));\n    assert(!negInfInterval.isAfter(cNegInfInterval));\n    assert(!negInfInterval.isAfter(iNegInfInterval));\n    assert(!cNegInfInterval.isAfter(interval));\n    assert(!cNegInfInterval.isAfter(cInterval));\n    assert(!cNegInfInterval.isAfter(iInterval));\n    assert(!cNegInfInterval.isAfter(posInfInterval));\n    assert(!cNegInfInterval.isAfter(cPosInfInterval));\n    assert(!cNegInfInterval.isAfter(iPosInfInterval));\n    assert(!cNegInfInterval.isAfter(negInfInterval));\n    assert(!cNegInfInterval.isAfter(cNegInfInterval));\n    assert(!cNegInfInterval.isAfter(iNegInfInterval));\n    assert(!iNegInfInterval.isAfter(interval));\n    assert(!iNegInfInterval.isAfter(cInterval));\n    assert(!iNegInfInterval.isAfter(iInterval));\n    assert(!iNegInfInterval.isAfter(posInfInterval));\n    assert(!iNegInfInterval.isAfter(cPosInfInterval));\n    assert(!iNegInfInterval.isAfter(iPosInfInterval));\n    assert(!iNegInfInterval.isAfter(negInfInterval));\n    assert(!iNegInfInterval.isAfter(cNegInfInterval));\n    assert(!iNegInfInterval.isAfter(iNegInfInterval));\n\n    //Verify Examples.\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24)));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5)));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1)));\n\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));\n\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(2012, 3, 1))));\n\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 5, 4))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(2013, 7, 9))));\n}\n\n//Test NegInfInterval's intersects().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval)\n    {\n        negInfInterval.intersects(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(negInfInterval.intersects(negInfInterval));\n    assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(NegInfInterval!Date(Date(2010, 7, 3)).intersects(negInfInterval));\n    assert(NegInfInterval!Date(Date(2010, 7, 4)).intersects(negInfInterval));\n    assert(NegInfInterval!Date(Date(2010, 7, 5)).intersects(negInfInterval));\n    assert(NegInfInterval!Date(Date(2012, 1, 6)).intersects(negInfInterval));\n    assert(NegInfInterval!Date(Date(2012, 1, 7)).intersects(negInfInterval));\n    assert(NegInfInterval!Date(Date(2012, 1, 8)).intersects(negInfInterval));\n\n    assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(negInfInterval.intersects(interval));\n    assert(negInfInterval.intersects(cInterval));\n    assert(negInfInterval.intersects(iInterval));\n    assert(negInfInterval.intersects(posInfInterval));\n    assert(negInfInterval.intersects(cPosInfInterval));\n    assert(negInfInterval.intersects(iPosInfInterval));\n    assert(negInfInterval.intersects(negInfInterval));\n    assert(negInfInterval.intersects(cNegInfInterval));\n    assert(negInfInterval.intersects(iNegInfInterval));\n    assert(cNegInfInterval.intersects(interval));\n    assert(cNegInfInterval.intersects(cInterval));\n    assert(cNegInfInterval.intersects(iInterval));\n    assert(cNegInfInterval.intersects(posInfInterval));\n    assert(cNegInfInterval.intersects(cPosInfInterval));\n    assert(cNegInfInterval.intersects(iPosInfInterval));\n    assert(cNegInfInterval.intersects(negInfInterval));\n    assert(cNegInfInterval.intersects(cNegInfInterval));\n    assert(cNegInfInterval.intersects(iNegInfInterval));\n    assert(iNegInfInterval.intersects(interval));\n    assert(iNegInfInterval.intersects(cInterval));\n    assert(iNegInfInterval.intersects(iInterval));\n    assert(iNegInfInterval.intersects(posInfInterval));\n    assert(iNegInfInterval.intersects(cPosInfInterval));\n    assert(iNegInfInterval.intersects(iPosInfInterval));\n    assert(iNegInfInterval.intersects(negInfInterval));\n    assert(iNegInfInterval.intersects(cNegInfInterval));\n    assert(iNegInfInterval.intersects(iNegInfInterval));\n\n    //Verify Examples.\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));\n\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1))));\n\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 5, 4))));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2013, 7, 9))));\n}\n\n//Test NegInfInterval's intersection().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    static void testInterval(I, J)(scope const I interval1, scope const J interval2)\n    {\n        interval1.intersection(interval2);\n    }\n\n    assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 7))));\n    assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(negInfInterval.intersection(negInfInterval) == negInfInterval);\n    assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) ==\n           Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)));\n    assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==\n           Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7)));\n    assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)));\n    assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)));\n    assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));\n    assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==\n           Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));\n    assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));\n    assert(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==\n           Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));\n    assert(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==\n           Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));\n\n    assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2010, 7, 3)));\n    assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2010, 7, 4)));\n    assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2010, 7, 5)));\n    assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 6)));\n    assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 7)));\n\n    assert(NegInfInterval!Date(Date(2010, 7, 3)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 3)));\n    assert(NegInfInterval!Date(Date(2010, 7, 4)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 4)));\n    assert(NegInfInterval!Date(Date(2010, 7, 5)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 5)));\n    assert(NegInfInterval!Date(Date(2012, 1, 6)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 6)));\n    assert(NegInfInterval!Date(Date(2012, 1, 7)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(NegInfInterval!Date(Date(2012, 1, 8)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n\n    assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) ==\n           Interval!Date(Date(2010, 7, 3), Date(2012, 1 ,7)));\n    assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) ==\n           Interval!Date(Date(2010, 7, 4), Date(2012, 1 ,7)));\n    assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) ==\n           Interval!Date(Date(2010, 7, 5), Date(2012, 1 ,7)));\n    assert(negInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) ==\n           Interval!Date(Date(2012, 1, 6), Date(2012, 1 ,7)));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!negInfInterval.intersection(interval).empty);\n    assert(!negInfInterval.intersection(cInterval).empty);\n    assert(!negInfInterval.intersection(iInterval).empty);\n    assert(!negInfInterval.intersection(posInfInterval).empty);\n    assert(!negInfInterval.intersection(cPosInfInterval).empty);\n    assert(!negInfInterval.intersection(iPosInfInterval).empty);\n    assert(!negInfInterval.intersection(negInfInterval).empty);\n    assert(!negInfInterval.intersection(cNegInfInterval).empty);\n    assert(!negInfInterval.intersection(iNegInfInterval).empty);\n    assert(!cNegInfInterval.intersection(interval).empty);\n    assert(!cNegInfInterval.intersection(cInterval).empty);\n    assert(!cNegInfInterval.intersection(iInterval).empty);\n    assert(!cNegInfInterval.intersection(posInfInterval).empty);\n    assert(!cNegInfInterval.intersection(cPosInfInterval).empty);\n    assert(!cNegInfInterval.intersection(iPosInfInterval).empty);\n    assert(!cNegInfInterval.intersection(negInfInterval).empty);\n    assert(!cNegInfInterval.intersection(cNegInfInterval).empty);\n    assert(!cNegInfInterval.intersection(iNegInfInterval).empty);\n    assert(!iNegInfInterval.intersection(interval).empty);\n    assert(!iNegInfInterval.intersection(cInterval).empty);\n    assert(!iNegInfInterval.intersection(iInterval).empty);\n    assert(!iNegInfInterval.intersection(posInfInterval).empty);\n    assert(!iNegInfInterval.intersection(cPosInfInterval).empty);\n    assert(!iNegInfInterval.intersection(iPosInfInterval).empty);\n    assert(!iNegInfInterval.intersection(negInfInterval).empty);\n    assert(!iNegInfInterval.intersection(cNegInfInterval).empty);\n    assert(!iNegInfInterval.intersection(iNegInfInterval).empty);\n\n    //Verify Examples.\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n           Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==\n           Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1)));\n\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) ==\n           Interval!Date(Date(1990, 7, 6), Date(2012, 3, 1)));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) ==\n           Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1)));\n\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) ==\n           NegInfInterval!Date(Date(1999, 7, 6)));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) ==\n           NegInfInterval!Date(Date(2012, 3, 1)));\n}\n\n//Test NegInfInterval's isAdjacent().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval)\n    {\n        negInfInterval.isAdjacent(interval);\n    }\n\n    assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(!negInfInterval.isAdjacent(negInfInterval));\n    assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));\n    assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));\n    assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));\n    assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));\n    assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));\n    assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));\n    assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));\n    assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));\n    assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));\n    assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));\n    assert(negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));\n    assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3))));\n    assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4))));\n    assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5))));\n    assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6))));\n    assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7))));\n    assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8))));\n\n    assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAdjacent(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAdjacent(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAdjacent(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAdjacent(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAdjacent(negInfInterval));\n    assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAdjacent(negInfInterval));\n\n    assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3))));\n    assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4))));\n    assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5))));\n    assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6))));\n    assert(negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7))));\n    assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!negInfInterval.isAdjacent(interval));\n    assert(!negInfInterval.isAdjacent(cInterval));\n    assert(!negInfInterval.isAdjacent(iInterval));\n    assert(!negInfInterval.isAdjacent(posInfInterval));\n    assert(!negInfInterval.isAdjacent(cPosInfInterval));\n    assert(!negInfInterval.isAdjacent(iPosInfInterval));\n    assert(!negInfInterval.isAdjacent(negInfInterval));\n    assert(!negInfInterval.isAdjacent(cNegInfInterval));\n    assert(!negInfInterval.isAdjacent(iNegInfInterval));\n    assert(!cNegInfInterval.isAdjacent(interval));\n    assert(!cNegInfInterval.isAdjacent(cInterval));\n    assert(!cNegInfInterval.isAdjacent(iInterval));\n    assert(!cNegInfInterval.isAdjacent(posInfInterval));\n    assert(!cNegInfInterval.isAdjacent(cPosInfInterval));\n    assert(!cNegInfInterval.isAdjacent(iPosInfInterval));\n    assert(!cNegInfInterval.isAdjacent(negInfInterval));\n    assert(!cNegInfInterval.isAdjacent(cNegInfInterval));\n    assert(!cNegInfInterval.isAdjacent(iNegInfInterval));\n    assert(!iNegInfInterval.isAdjacent(interval));\n    assert(!iNegInfInterval.isAdjacent(cInterval));\n    assert(!iNegInfInterval.isAdjacent(iInterval));\n    assert(!iNegInfInterval.isAdjacent(posInfInterval));\n    assert(!iNegInfInterval.isAdjacent(cPosInfInterval));\n    assert(!iNegInfInterval.isAdjacent(iPosInfInterval));\n    assert(!iNegInfInterval.isAdjacent(negInfInterval));\n    assert(!iNegInfInterval.isAdjacent(cNegInfInterval));\n    assert(!iNegInfInterval.isAdjacent(iNegInfInterval));\n\n    //Verify Examples.\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));\n\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4))));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1))));\n\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 5, 4))));\n    assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(2012, 3, 1))));\n}\n\n//Test NegInfInterval's merge().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    static void testInterval(I, J)(scope const I interval1, scope const J interval2)\n    {\n        interval1.merge(interval2);\n    }\n\n    assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));\n\n    assert(negInfInterval.merge(negInfInterval) == negInfInterval);\n    assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==\n           NegInfInterval!Date(Date(2013, 7, 3)));\n    assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==\n           NegInfInterval!Date(Date(2012, 1, 8)));\n    assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==\n           NegInfInterval!Date(Date(2012, 1, 8)));\n    assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==\n           NegInfInterval!Date(Date(2012, 1, 8)));\n\n    assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8)));\n\n    assert(NegInfInterval!Date(Date(2010, 7, 3)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(NegInfInterval!Date(Date(2010, 7, 4)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(NegInfInterval!Date(Date(2010, 7, 5)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(NegInfInterval!Date(Date(2012, 1, 6)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(NegInfInterval!Date(Date(2012, 1, 7)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(NegInfInterval!Date(Date(2012, 1, 8)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 8)));\n\n    static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3)))));\n    static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4)))));\n    static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5)))));\n    static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6)))));\n    static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7)))));\n    static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8)))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!negInfInterval.merge(interval).empty);\n    assert(!negInfInterval.merge(cInterval).empty);\n    assert(!negInfInterval.merge(iInterval).empty);\n    static assert(!__traits(compiles, negInfInterval.merge(posInfInterval)));\n    static assert(!__traits(compiles, negInfInterval.merge(cPosInfInterval)));\n    static assert(!__traits(compiles, negInfInterval.merge(iPosInfInterval)));\n    assert(!negInfInterval.merge(negInfInterval).empty);\n    assert(!negInfInterval.merge(cNegInfInterval).empty);\n    assert(!negInfInterval.merge(iNegInfInterval).empty);\n    assert(!cNegInfInterval.merge(interval).empty);\n    assert(!cNegInfInterval.merge(cInterval).empty);\n    assert(!cNegInfInterval.merge(iInterval).empty);\n    static assert(!__traits(compiles, cNegInfInterval.merge(posInfInterval)));\n    static assert(!__traits(compiles, cNegInfInterval.merge(cPosInfInterval)));\n    static assert(!__traits(compiles, cNegInfInterval.merge(iPosInfInterval)));\n    assert(!cNegInfInterval.merge(negInfInterval).empty);\n    assert(!cNegInfInterval.merge(cNegInfInterval).empty);\n    assert(!cNegInfInterval.merge(iNegInfInterval).empty);\n    assert(!iNegInfInterval.merge(interval).empty);\n    assert(!iNegInfInterval.merge(cInterval).empty);\n    assert(!iNegInfInterval.merge(iInterval).empty);\n    static assert(!__traits(compiles, iNegInfInterval.merge(posInfInterval)));\n    static assert(!__traits(compiles, iNegInfInterval.merge(cPosInfInterval)));\n    static assert(!__traits(compiles, iNegInfInterval.merge(iPosInfInterval)));\n    assert(!iNegInfInterval.merge(negInfInterval).empty);\n    assert(!iNegInfInterval.merge(cNegInfInterval).empty);\n    assert(!iNegInfInterval.merge(iNegInfInterval).empty);\n\n    //Verify Examples.\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n           NegInfInterval!Date(Date(2012, 3, 1)));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==\n           NegInfInterval!Date(Date(2015, 9, 2)));\n\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1999, 7, 6))) ==\n           NegInfInterval!Date(Date(2012, 3, 1)));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) ==\n           NegInfInterval!Date(Date(2013, 1, 12)));\n}\n\n//Test NegInfInterval's span().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    static void testInterval(I, J)(scope const I interval1, scope const J interval2)\n    {\n        interval1.span(interval2);\n    }\n\n    assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!\"days\"(0))));\n\n    assert(negInfInterval.span(negInfInterval) == negInfInterval);\n    assert(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==\n           NegInfInterval!Date(Date(2013, 7, 3)));\n    assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==\n           NegInfInterval!Date(Date(2012, 1, 8)));\n    assert(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==\n           NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==\n           NegInfInterval!Date(Date(2012, 1, 8)));\n    assert(negInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==\n           NegInfInterval!Date(Date(2012, 1, 8)));\n    assert(negInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) ==\n           NegInfInterval!Date(Date(2012, 1, 9)));\n\n    assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8)));\n\n    assert(NegInfInterval!Date(Date(2010, 7, 3)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(NegInfInterval!Date(Date(2010, 7, 4)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(NegInfInterval!Date(Date(2010, 7, 5)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(NegInfInterval!Date(Date(2012, 1, 6)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(NegInfInterval!Date(Date(2012, 1, 7)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));\n    assert(NegInfInterval!Date(Date(2012, 1, 8)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 8)));\n\n    static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3)))));\n    static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4)))));\n    static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5)))));\n    static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6)))));\n    static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7)))));\n    static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8)))));\n\n    auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n    auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!negInfInterval.span(interval).empty);\n    assert(!negInfInterval.span(cInterval).empty);\n    assert(!negInfInterval.span(iInterval).empty);\n    static assert(!__traits(compiles, negInfInterval.span(posInfInterval)));\n    static assert(!__traits(compiles, negInfInterval.span(cPosInfInterval)));\n    static assert(!__traits(compiles, negInfInterval.span(iPosInfInterval)));\n    assert(!negInfInterval.span(negInfInterval).empty);\n    assert(!negInfInterval.span(cNegInfInterval).empty);\n    assert(!negInfInterval.span(iNegInfInterval).empty);\n    assert(!cNegInfInterval.span(interval).empty);\n    assert(!cNegInfInterval.span(cInterval).empty);\n    assert(!cNegInfInterval.span(iInterval).empty);\n    static assert(!__traits(compiles, cNegInfInterval.span(posInfInterval)));\n    static assert(!__traits(compiles, cNegInfInterval.span(cPosInfInterval)));\n    static assert(!__traits(compiles, cNegInfInterval.span(iPosInfInterval)));\n    assert(!cNegInfInterval.span(negInfInterval).empty);\n    assert(!cNegInfInterval.span(cNegInfInterval).empty);\n    assert(!cNegInfInterval.span(iNegInfInterval).empty);\n    assert(!iNegInfInterval.span(interval).empty);\n    assert(!iNegInfInterval.span(cInterval).empty);\n    assert(!iNegInfInterval.span(iInterval).empty);\n    static assert(!__traits(compiles, iNegInfInterval.span(posInfInterval)));\n    static assert(!__traits(compiles, iNegInfInterval.span(cPosInfInterval)));\n    static assert(!__traits(compiles, iNegInfInterval.span(iPosInfInterval)));\n    assert(!iNegInfInterval.span(negInfInterval).empty);\n    assert(!iNegInfInterval.span(cNegInfInterval).empty);\n    assert(!iNegInfInterval.span(iNegInfInterval).empty);\n\n    //Verify Examples.\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==\n           NegInfInterval!Date(Date(2012, 3, 1)));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==\n           NegInfInterval!Date(Date(2015, 9, 2)));\n    assert(NegInfInterval!Date(Date(1600, 1, 7)).span(Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) ==\n           NegInfInterval!Date(Date(2017, 7, 1)));\n\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1999, 7, 6))) ==\n           NegInfInterval!Date(Date(2012, 3, 1)));\n    assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) ==\n           NegInfInterval!Date(Date(2013, 1, 12)));\n}\n\n//Test NegInfInterval's shift().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    static void testInterval(I)(I interval, scope const Duration duration,\n                                scope const I expected, size_t line = __LINE__)\n    {\n        interval.shift(duration);\n        assert(interval == expected);\n    }\n\n    testInterval(interval, dur!\"days\"(22), NegInfInterval!Date(Date(2012, 1, 29)));\n    testInterval(interval, dur!\"days\"(-22), NegInfInterval!Date(Date(2011, 12, 16)));\n\n    const cInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    static assert(!__traits(compiles, cInterval.shift(dur!\"days\"(5))));\n    static assert(!__traits(compiles, iInterval.shift(dur!\"days\"(5))));\n\n    //Verify Examples.\n    auto interval1 = NegInfInterval!Date(Date(2012, 4, 5));\n    auto interval2 = NegInfInterval!Date(Date(2012, 4, 5));\n\n    interval1.shift(dur!\"days\"(50));\n    assert(interval1 == NegInfInterval!Date(Date(2012, 5, 25)));\n\n    interval2.shift(dur!\"days\"(-50));\n    assert(interval2 == NegInfInterval!Date( Date(2012, 2, 15)));\n}\n\n//Test NegInfInterval's shift(int, int, AllowDayOverflow).\n@safe unittest\n{\n    import std.datetime.date;\n\n    {\n        auto interval = NegInfInterval!Date(Date(2012, 1, 7));\n\n        static void testIntervalFail(I)(I interval, int years, int months)\n        {\n            interval.shift(years, months);\n        }\n\n        static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow,\n                                    in I expected, size_t line = __LINE__)\n        {\n            interval.shift(years, months, allow);\n            assert(interval == expected);\n        }\n\n        testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7)));\n        testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7)));\n\n        auto interval2 = NegInfInterval!Date(Date(2010, 5, 31));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1)));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 6, 30)));\n    }\n\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    static assert(!__traits(compiles, cNegInfInterval.shift(1)));\n    static assert(!__traits(compiles, iNegInfInterval.shift(1)));\n\n    //Verify Examples.\n    auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));\n    auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));\n\n    interval1.shift(2);\n    assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));\n\n    interval2.shift(-2);\n    assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));\n}\n\n//Test NegInfInterval's expand().\n@safe unittest\n{\n    import std.datetime.date;\n\n    auto interval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    static void testInterval(I)(I interval,\n                                scope const Duration duration, scope const I expected, size_t line = __LINE__)\n    {\n        interval.expand(duration);\n        assert(interval == expected);\n    }\n\n    testInterval(interval, dur!\"days\"(22), NegInfInterval!Date(Date(2012, 1, 29)));\n    testInterval(interval, dur!\"days\"(-22), NegInfInterval!Date(Date(2011, 12, 16)));\n\n    const cInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    static assert(!__traits(compiles, cInterval.expand(dur!\"days\"(5))));\n    static assert(!__traits(compiles, iInterval.expand(dur!\"days\"(5))));\n\n    //Verify Examples.\n    auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));\n    auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));\n\n    interval1.expand(dur!\"days\"(2));\n    assert(interval1 == NegInfInterval!Date(Date(2012, 3, 3)));\n\n    interval2.expand(dur!\"days\"(-2));\n    assert(interval2 == NegInfInterval!Date(Date(2012, 2, 28)));\n}\n\n//Test NegInfInterval's expand(int, int, AllowDayOverflow).\n@safe unittest\n{\n    import std.datetime.date;\n\n    {\n        auto interval = NegInfInterval!Date(Date(2012, 1, 7));\n\n        static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow,\n                                    in I expected, size_t line = __LINE__)\n        {\n            interval.expand(years, months, allow);\n            assert(interval == expected);\n        }\n\n        testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7)));\n        testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7)));\n\n        auto interval2 = NegInfInterval!Date(Date(2010, 5, 31));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1)));\n\n        testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30)));\n        testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30)));\n        testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30)));\n        testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date( Date(2009, 6, 30)));\n    }\n\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    static assert(!__traits(compiles, cNegInfInterval.expand(1)));\n    static assert(!__traits(compiles, iNegInfInterval.expand(1)));\n\n    //Verify Examples.\n    auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));\n    auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));\n\n    interval1.expand(2);\n    assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));\n\n    interval2.expand(-2);\n    assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));\n}\n\n//Test NegInfInterval's bwdRange().\n@system unittest\n{\n    import std.datetime.date;\n\n    auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n\n    static void testInterval(NegInfInterval!Date negInfInterval)\n    {\n        negInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront();\n    }\n\n    assertThrown!DateTimeException(testInterval(negInfInterval));\n\n    assert(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front ==\n           Date(2010, 10, 1));\n\n    assert(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange(\n               everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 24));\n\n    //Verify Examples.\n    auto interval = NegInfInterval!Date(Date(2010, 9, 9));\n    auto func = delegate (scope const Date date)\n                {\n                    if ((date.day & 1) == 0)\n                        return date - dur!\"days\"(2);\n                    return date - dur!\"days\"(1);\n                };\n    auto range = interval.bwdRange(func);\n\n    //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).\n    assert(range.front == Date(2010, 9, 9));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 8));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 6));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 4));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 2));\n\n    range.popFront();\n    assert(!range.empty);\n\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(!cNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty);\n    assert(!iNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty);\n}\n\n//Test NegInfInterval's toString().\n@safe unittest\n{\n    import std.datetime.date;\n\n    assert(NegInfInterval!Date(Date(2012, 1, 7)).toString() == \"[-∞ - 2012-Jan-07)\");\n\n    const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n    assert(cNegInfInterval.toString());\n    assert(iNegInfInterval.toString());\n}\n\n\n/++\n    Range-generating function.\n\n    Returns a delegate which returns the next time point with the given\n    `DayOfWeek` in a range.\n\n    Using this delegate allows iteration over successive time points which\n    are all the same day of the week. e.g. passing `DayOfWeek.mon` to\n    `everyDayOfWeek` would result in a delegate which could be used to\n    iterate over all of the Mondays in a range.\n\n    Params:\n        dir       = The direction to iterate in. If passing the return value to\n                    `fwdRange`, use `Direction.fwd`. If passing it to\n                    `bwdRange`, use `Direction.bwd`.\n        dayOfWeek = The week that each time point in the range will be.\n  +/\nTP delegate(scope const TP) everyDayOfWeek(TP, Direction dir = Direction.fwd)(DayOfWeek dayOfWeek) nothrow\nif (isTimePoint!TP &&\n    (dir == Direction.fwd || dir == Direction.bwd) &&\n    __traits(hasMember, TP, \"dayOfWeek\") &&\n    !__traits(isStaticFunction, TP.dayOfWeek) &&\n    is(typeof(TP.dayOfWeek) == DayOfWeek))\n{\n    TP func(scope const TP tp)\n    {\n        TP retval = cast(TP) tp;\n        immutable days = daysToDayOfWeek(retval.dayOfWeek, dayOfWeek);\n\n        static if (dir == Direction.fwd)\n            immutable adjustedDays = days == 0 ? 7 : days;\n        else\n            immutable adjustedDays = days == 0 ? -7 : days - 7;\n\n        return retval += dur!\"days\"(adjustedDays);\n    }\n\n    return &func;\n}\n\n///\n@system unittest\n{\n    import std.datetime.date : Date, DayOfWeek;\n\n    auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));\n    auto func = everyDayOfWeek!Date(DayOfWeek.mon);\n    auto range = interval.fwdRange(func);\n\n    // A Thursday. Using PopFirst.yes would have made this Date(2010, 9, 6).\n    assert(range.front == Date(2010, 9, 2));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 6));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 13));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 20));\n\n    range.popFront();\n    assert(range.empty);\n}\n\n@system unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    auto funcFwd = everyDayOfWeek!Date(DayOfWeek.mon);\n    auto funcBwd = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.mon);\n\n    assert(funcFwd(Date(2010, 8, 28)) == Date(2010, 8, 30));\n    assert(funcFwd(Date(2010, 8, 29)) == Date(2010, 8, 30));\n    assert(funcFwd(Date(2010, 8, 30)) == Date(2010, 9, 6));\n    assert(funcFwd(Date(2010, 8, 31)) == Date(2010, 9, 6));\n    assert(funcFwd(Date(2010, 9, 1)) == Date(2010, 9, 6));\n    assert(funcFwd(Date(2010, 9, 2)) == Date(2010, 9, 6));\n    assert(funcFwd(Date(2010, 9, 3)) == Date(2010, 9, 6));\n    assert(funcFwd(Date(2010, 9, 4)) == Date(2010, 9, 6));\n    assert(funcFwd(Date(2010, 9, 5)) == Date(2010, 9, 6));\n    assert(funcFwd(Date(2010, 9, 6)) == Date(2010, 9, 13));\n    assert(funcFwd(Date(2010, 9, 7)) == Date(2010, 9, 13));\n\n    assert(funcBwd(Date(2010, 8, 28)) == Date(2010, 8, 23));\n    assert(funcBwd(Date(2010, 8, 29)) == Date(2010, 8, 23));\n    assert(funcBwd(Date(2010, 8, 30)) == Date(2010, 8, 23));\n    assert(funcBwd(Date(2010, 8, 31)) == Date(2010, 8, 30));\n    assert(funcBwd(Date(2010, 9, 1)) == Date(2010, 8, 30));\n    assert(funcBwd(Date(2010, 9, 2)) == Date(2010, 8, 30));\n    assert(funcBwd(Date(2010, 9, 3)) == Date(2010, 8, 30));\n    assert(funcBwd(Date(2010, 9, 4)) == Date(2010, 8, 30));\n    assert(funcBwd(Date(2010, 9, 5)) == Date(2010, 8, 30));\n    assert(funcBwd(Date(2010, 9, 6)) == Date(2010, 8, 30));\n    assert(funcBwd(Date(2010, 9, 7)) == Date(2010, 9, 6));\n\n    static assert(!__traits(compiles, everyDayOfWeek!TimeOfDay(DayOfWeek.mon)));\n    assert(everyDayOfWeek!DateTime(DayOfWeek.mon) !is null);\n    assert(everyDayOfWeek!SysTime(DayOfWeek.mon) !is null);\n}\n\n\n/++\n    Range-generating function.\n\n    Returns a delegate which returns the next time point with the given month\n    which would be reached by adding months to the given time point.\n\n    So, using this delegate allows iteration over successive time points\n    which are in the same month but different years. For example,\n    iterate over each successive December 25th in an interval by starting with a\n    date which had the 25th as its day and passed `Month.dec` to\n    `everyMonth` to create the delegate.\n\n    Since it wouldn't really make sense to be iterating over a specific month\n    and end up with some of the time points in the succeeding month or two years\n    after the previous time point, `AllowDayOverflow.no` is always used when\n    calculating the next time point.\n\n    Params:\n        dir   = The direction to iterate in. If passing the return value to\n                `fwdRange`, use `Direction.fwd`. If passing it to\n                `bwdRange`, use `Direction.bwd`.\n        month = The month that each time point in the range will be in\n                (January is 1).\n  +/\nTP delegate(scope const TP) everyMonth(TP, Direction dir = Direction.fwd)(int month)\nif (isTimePoint!TP &&\n    (dir == Direction.fwd || dir == Direction.bwd) &&\n    __traits(hasMember, TP, \"month\") &&\n    !__traits(isStaticFunction, TP.month) &&\n    is(typeof(TP.month) == Month))\n{\n    import std.datetime.date : enforceValid, monthsToMonth;\n\n    enforceValid!\"months\"(month);\n\n    TP func(scope const TP tp)\n    {\n        TP retval = cast(TP) tp;\n        immutable months = monthsToMonth(retval.month, month);\n\n        static if (dir == Direction.fwd)\n            immutable adjustedMonths = months == 0 ? 12 : months;\n        else\n            immutable adjustedMonths = months == 0 ? -12 : months - 12;\n\n        retval.add!\"months\"(adjustedMonths, AllowDayOverflow.no);\n\n        if (retval.month != month)\n        {\n            retval.add!\"months\"(-1);\n            assert(retval.month == month);\n        }\n\n        return retval;\n    }\n\n    return &func;\n}\n\n///\n@system unittest\n{\n    import std.datetime.date : Date, Month;\n\n    auto interval = Interval!Date(Date(2000, 1, 30), Date(2004, 8, 5));\n    auto func = everyMonth!Date(Month.feb);\n    auto range = interval.fwdRange(func);\n\n    // Using PopFirst.yes would have made this Date(2010, 2, 29).\n    assert(range.front == Date(2000, 1, 30));\n\n    range.popFront();\n    assert(range.front == Date(2000, 2, 29));\n\n    range.popFront();\n    assert(range.front == Date(2001, 2, 28));\n\n    range.popFront();\n    assert(range.front == Date(2002, 2, 28));\n\n    range.popFront();\n    assert(range.front == Date(2003, 2, 28));\n\n    range.popFront();\n    assert(range.front == Date(2004, 2, 28));\n\n    range.popFront();\n    assert(range.empty);\n}\n\n@system unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    auto funcFwd = everyMonth!Date(Month.jun);\n    auto funcBwd = everyMonth!(Date, Direction.bwd)(Month.jun);\n\n    assert(funcFwd(Date(2010, 5, 31)) == Date(2010, 6, 30));\n    assert(funcFwd(Date(2010, 6, 30)) == Date(2011, 6, 30));\n    assert(funcFwd(Date(2010, 7, 31)) == Date(2011, 6, 30));\n    assert(funcFwd(Date(2010, 8, 31)) == Date(2011, 6, 30));\n    assert(funcFwd(Date(2010, 9, 30)) == Date(2011, 6, 30));\n    assert(funcFwd(Date(2010, 10, 31)) == Date(2011, 6, 30));\n    assert(funcFwd(Date(2010, 11, 30)) == Date(2011, 6, 30));\n    assert(funcFwd(Date(2010, 12, 31)) == Date(2011, 6, 30));\n    assert(funcFwd(Date(2011, 1, 31)) == Date(2011, 6, 30));\n    assert(funcFwd(Date(2011, 2, 28)) == Date(2011, 6, 28));\n    assert(funcFwd(Date(2011, 3, 31)) == Date(2011, 6, 30));\n    assert(funcFwd(Date(2011, 4, 30)) == Date(2011, 6, 30));\n    assert(funcFwd(Date(2011, 5, 31)) == Date(2011, 6, 30));\n    assert(funcFwd(Date(2011, 6, 30)) == Date(2012, 6, 30));\n    assert(funcFwd(Date(2011, 7, 31)) == Date(2012, 6, 30));\n\n    assert(funcBwd(Date(2010, 5, 31)) == Date(2009, 6, 30));\n    assert(funcBwd(Date(2010, 6, 30)) == Date(2009, 6, 30));\n    assert(funcBwd(Date(2010, 7, 31)) == Date(2010, 6, 30));\n    assert(funcBwd(Date(2010, 8, 31)) == Date(2010, 6, 30));\n    assert(funcBwd(Date(2010, 9, 30)) == Date(2010, 6, 30));\n    assert(funcBwd(Date(2010, 10, 31)) == Date(2010, 6, 30));\n    assert(funcBwd(Date(2010, 11, 30)) == Date(2010, 6, 30));\n    assert(funcBwd(Date(2010, 12, 31)) == Date(2010, 6, 30));\n    assert(funcBwd(Date(2011, 1, 31)) == Date(2010, 6, 30));\n    assert(funcBwd(Date(2011, 2, 28)) == Date(2010, 6, 28));\n    assert(funcBwd(Date(2011, 3, 31)) == Date(2010, 6, 30));\n    assert(funcBwd(Date(2011, 4, 30)) == Date(2010, 6, 30));\n    assert(funcBwd(Date(2011, 5, 31)) == Date(2010, 6, 30));\n    assert(funcBwd(Date(2011, 6, 30)) == Date(2010, 6, 30));\n    assert(funcBwd(Date(2011, 7, 30)) == Date(2011, 6, 30));\n\n    static assert(!__traits(compiles, everyMonth!TimeOfDay(Month.jan)));\n    assert(everyMonth!DateTime(Month.jan) !is null);\n    assert(everyMonth!SysTime(Month.jan) !is null);\n}\n\n\n/++\n    Range-generating function.\n\n    Returns a delegate which returns the next time point which is the given\n    duration later.\n\n    Using this delegate allows iteration over successive time points which\n    are apart by the given duration e.g. passing `dur!\"days\"(3)` to\n    `everyDuration` would result in a delegate which could be used to iterate\n    over a range of days which are each 3 days apart.\n\n    Params:\n        dir      = The direction to iterate in. If passing the return value to\n                   `fwdRange`, use `Direction.fwd`. If passing it to\n                   `bwdRange`, use `Direction.bwd`.\n        duration = The duration which separates each successive time point in\n                   the range.\n  +/\nTP delegate(scope const TP) everyDuration(TP, Direction dir = Direction.fwd, D)(D duration) nothrow\nif (isTimePoint!TP &&\n    __traits(compiles, TP.init + duration) &&\n    (dir == Direction.fwd || dir == Direction.bwd))\n{\n    TP func(scope const TP tp)\n    {\n        static if (dir == Direction.fwd)\n            return tp + duration;\n        else\n            return tp - duration;\n    }\n\n    return &func;\n}\n\n///\n@system unittest\n{\n    import core.time : dur;\n    import std.datetime.date : Date;\n\n    auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));\n    auto func = everyDuration!Date(dur!\"days\"(8));\n    auto range = interval.fwdRange(func);\n\n    // Using PopFirst.yes would have made this Date(2010, 9, 10).\n    assert(range.front == Date(2010, 9, 2));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 10));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 18));\n\n    range.popFront();\n    assert(range.front == Date(2010, 9, 26));\n\n    range.popFront();\n    assert(range.empty);\n}\n\n@system unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    auto funcFwd = everyDuration!Date(dur!\"days\"(27));\n    auto funcBwd = everyDuration!(Date, Direction.bwd)(dur!\"days\"(27));\n\n    assert(funcFwd(Date(2009, 12, 25)) == Date(2010, 1, 21));\n    assert(funcFwd(Date(2009, 12, 26)) == Date(2010, 1, 22));\n    assert(funcFwd(Date(2009, 12, 27)) == Date(2010, 1, 23));\n    assert(funcFwd(Date(2009, 12, 28)) == Date(2010, 1, 24));\n\n    assert(funcBwd(Date(2010, 1, 21)) == Date(2009, 12, 25));\n    assert(funcBwd(Date(2010, 1, 22)) == Date(2009, 12, 26));\n    assert(funcBwd(Date(2010, 1, 23)) == Date(2009, 12, 27));\n    assert(funcBwd(Date(2010, 1, 24)) == Date(2009, 12, 28));\n\n    assert(everyDuration!Date(dur!\"hnsecs\"(1)) !is null);\n    assert(everyDuration!TimeOfDay(dur!\"hnsecs\"(1)) !is null);\n    assert(everyDuration!DateTime(dur!\"hnsecs\"(1)) !is null);\n    assert(everyDuration!SysTime(dur!\"hnsecs\"(1)) !is null);\n}\n\n\n/++\n    Range-generating function.\n\n    Returns a delegate which returns the next time point which is the given\n    number of years, month, and duration later.\n\n    The difference between this version of `everyDuration` and the version\n    which just takes a $(REF Duration, core,time) is that this one also takes\n    the number of years and months (along with an `AllowDayOverflow` to\n    indicate whether adding years and months should allow the days to overflow).\n\n    Note that if iterating forward, `add!\"years\"()` is called on the given\n    time point, then `add!\"months\"()`, and finally the duration is added\n    to it. However, if iterating backwards, the duration is added first, then\n    `add!\"months\"()` is called, and finally `add!\"years\"()` is called.\n    That way, going backwards generates close to the same time points that\n    iterating forward does, but since adding years and months is not entirely\n    reversible (due to possible day overflow, regardless of whether\n    `AllowDayOverflow.yes` or `AllowDayOverflow.no` is used), it can't be\n    guaranteed that iterating backwards will give the same time points as\n    iterating forward would have (even assuming that the end of the range is a\n    time point which would be returned by the delegate when iterating forward\n    from `begin`).\n\n    Params:\n        dir           = The direction to iterate in. If passing the return\n                        value to `fwdRange`, use `Direction.fwd`. If\n                        passing it to `bwdRange`, use `Direction.bwd`.\n        years         = The number of years to add to the time point passed to\n                        the delegate.\n        months        = The number of months to add to the time point passed to\n                        the delegate.\n        allowOverflow = Whether the days should be allowed to overflow on\n                        `begin` and `end`, causing their month to\n                        increment.\n        duration      = The duration to add to the time point passed to the\n                        delegate.\n  +/\nTP delegate(scope const TP) everyDuration(TP, Direction dir = Direction.fwd, D)\n                                 (int years,\n                                 int months = 0,\n                                 AllowDayOverflow allowOverflow = AllowDayOverflow.yes,\n                                 D duration = dur!\"days\"(0)) nothrow\nif (isTimePoint!TP &&\n    __traits(compiles, TP.init + duration) &&\n    __traits(compiles, TP.init.add!\"years\"(years)) &&\n    __traits(compiles, TP.init.add!\"months\"(months)) &&\n    (dir == Direction.fwd || dir == Direction.bwd))\n{\n    TP func(scope const TP tp)\n    {\n        static if (dir == Direction.fwd)\n        {\n            TP retval = cast(TP) tp;\n\n            retval.add!\"years\"(years, allowOverflow);\n            retval.add!\"months\"(months, allowOverflow);\n\n            return retval + duration;\n        }\n        else\n        {\n            TP retval = tp - duration;\n\n            retval.add!\"months\"(-months, allowOverflow);\n            retval.add!\"years\"(-years, allowOverflow);\n\n            return retval;\n        }\n    }\n\n    return &func;\n}\n\n///\n@system unittest\n{\n    import core.time : dur;\n    import std.datetime.date : AllowDayOverflow, Date;\n\n    auto interval = Interval!Date(Date(2010, 9, 2), Date(2025, 9, 27));\n    auto func = everyDuration!Date(4, 1, AllowDayOverflow.yes, dur!\"days\"(2));\n    auto range = interval.fwdRange(func);\n\n    // Using PopFirst.yes would have made this Date(2014, 10, 12).\n    assert(range.front == Date(2010, 9, 2));\n\n    range.popFront();\n    assert(range.front == Date(2014, 10, 4));\n\n    range.popFront();\n    assert(range.front == Date(2018, 11, 6));\n\n    range.popFront();\n    assert(range.front == Date(2022, 12, 8));\n\n    range.popFront();\n    assert(range.empty);\n}\n\n@system unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    {\n        auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!\"days\"(3));\n        auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!\"days\"(3));\n\n        assert(funcFwd(Date(2009, 12, 25)) == Date(2011, 2, 28));\n        assert(funcFwd(Date(2009, 12, 26)) == Date(2011, 3, 1));\n        assert(funcFwd(Date(2009, 12, 27)) == Date(2011, 3, 2));\n        assert(funcFwd(Date(2009, 12, 28)) == Date(2011, 3, 3));\n        assert(funcFwd(Date(2009, 12, 29)) == Date(2011, 3, 4));\n\n        assert(funcBwd(Date(2011, 2, 28)) == Date(2009, 12, 25));\n        assert(funcBwd(Date(2011, 3, 1)) == Date(2009, 12, 26));\n        assert(funcBwd(Date(2011, 3, 2)) == Date(2009, 12, 27));\n        assert(funcBwd(Date(2011, 3, 3)) == Date(2009, 12, 28));\n        assert(funcBwd(Date(2011, 3, 4)) == Date(2010, 1, 1));\n    }\n\n    {\n        auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.no, dur!\"days\"(3));\n        auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!\"days\"(3));\n\n        assert(funcFwd(Date(2009, 12, 25)) == Date(2011, 2, 28));\n        assert(funcFwd(Date(2009, 12, 26)) == Date(2011, 3, 1));\n        assert(funcFwd(Date(2009, 12, 27)) == Date(2011, 3, 2));\n        assert(funcFwd(Date(2009, 12, 28)) == Date(2011, 3, 3));\n        assert(funcFwd(Date(2009, 12, 29)) == Date(2011, 3, 3));\n\n        assert(funcBwd(Date(2011, 2, 28)) == Date(2009, 12, 25));\n        assert(funcBwd(Date(2011, 3, 1)) == Date(2009, 12, 26));\n        assert(funcBwd(Date(2011, 3, 2)) == Date(2009, 12, 27));\n        assert(funcBwd(Date(2011, 3, 3)) == Date(2009, 12, 28));\n        assert(funcBwd(Date(2011, 3, 4)) == Date(2010, 1, 1));\n    }\n\n    assert(everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!\"hnsecs\"(1)) !is null);\n    static assert(!__traits(compiles, everyDuration!TimeOfDay(1, 2, AllowDayOverflow.yes, dur!\"hnsecs\"(1))));\n    assert(everyDuration!DateTime(1, 2, AllowDayOverflow.yes, dur!\"hnsecs\"(1)) !is null);\n    assert(everyDuration!SysTime(1, 2, AllowDayOverflow.yes, dur!\"hnsecs\"(1)) !is null);\n}\n\n\n/++\n    A range over an $(LREF Interval).\n\n    `IntervalRange` is only ever constructed by $(LREF Interval). However, when\n    it is constructed, it is given a function, `func`, which is used to\n    generate the time points which are iterated over. `func` takes a time\n    point and returns a time point of the same type. For instance,\n    to iterate over all of the days in\n    the interval `Interval!Date`, pass a function to $(LREF Interval)'s\n    `fwdRange` where that function took a $(REF Date,std,datetime,date) and\n    returned a $(REF Date,std,datetime,date) which was one day later. That\n    function would then be used by `IntervalRange`'s `popFront` to iterate\n    over the $(REF Date,std,datetime,date)s in the interval.\n\n    If $(D dir == Direction.fwd), then a range iterates forward in time, whereas\n    if $(D dir == Direction.bwd), then it iterates backwards in time. So, if\n    $(D dir == Direction.fwd) then $(D front == interval.begin), whereas if\n    $(D dir == Direction.bwd) then $(D front == interval.end). `func` must\n    generate a time point going in the proper direction of iteration, or a\n    $(REF DateTimeException,std,datetime,date) will be thrown. So, to iterate\n    forward in time, the time point that `func` generates must be later in\n    time than the one passed to it. If it's either identical or earlier in time,\n    then a $(REF DateTimeException,std,datetime,date) will be thrown. To\n    iterate backwards, then the generated time point must be before the time\n    point which was passed in.\n\n    If the generated time point is ever passed the edge of the range in the\n    proper direction, then the edge of that range will be used instead. So, if\n    iterating forward, and the generated time point is past the interval's\n    `end`, then `front` becomes `end`. If iterating backwards, and the\n    generated time point is before `begin`, then `front` becomes\n    `begin`. In either case, the range would then be empty.\n\n    Also note that while normally the `begin` of an interval is included in\n    it and its `end` is excluded from it, if $(D dir == Direction.bwd), then\n    `begin` is treated as excluded and `end` is treated as included. This\n    allows for the same behavior in both directions. This works because none of\n    $(LREF Interval)'s functions which care about whether `begin` or `end`\n    is included or excluded are ever called by `IntervalRange`. `interval`\n    returns a normal interval, regardless of whether $(D dir == Direction.fwd)\n    or if $(D dir == Direction.bwd), so any $(LREF Interval) functions which are\n    called on it which care about whether `begin` or `end` are included or\n    excluded will treat `begin` as included and `end` as excluded.\n  +/\nstruct IntervalRange(TP, Direction dir)\nif (isTimePoint!TP && dir != Direction.both)\n{\npublic:\n\n    /++\n        Params:\n            rhs = The `IntervalRange` to assign to this one.\n      +/\n    ref IntervalRange opAssign(ref IntervalRange rhs) pure nothrow\n    {\n        _interval = rhs._interval;\n        _func = rhs._func;\n        return this;\n    }\n\n\n    /++ Ditto +/\n    ref IntervalRange opAssign(IntervalRange rhs) pure nothrow\n    {\n        return this = rhs;\n    }\n\n\n    /++\n        Whether this `IntervalRange` is empty.\n      +/\n    @property bool empty() const pure nothrow\n    {\n        return _interval.empty;\n    }\n\n\n    /++\n        The first time point in the range.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the range is empty.\n      +/\n    @property TP front() const pure\n    {\n        _enforceNotEmpty();\n\n        static if (dir == Direction.fwd)\n            return _interval.begin;\n        else\n            return _interval.end;\n    }\n\n\n    /++\n        Pops `front` from the range, using `func` to generate the next\n        time point in the range. If the generated time point is beyond the edge\n        of the range, then `front` is set to that edge, and the range is then\n        empty. So, if iterating forwards, and the generated time point is\n        greater than the interval's `end`, then `front` is set to\n        `end`. If iterating backwards, and the generated time point is less\n        than the interval's `begin`, then `front` is set to `begin`.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the range is empty\n            or if the generated time point is in the wrong direction (i.e. if\n            iterating forward and the generated time point is before `front`,\n            or if iterating backwards and the generated time point is after\n            `front`).\n      +/\n    void popFront()\n    {\n        _enforceNotEmpty();\n\n        static if (dir == Direction.fwd)\n        {\n            auto begin = _func(_interval.begin);\n\n            if (begin > _interval.end)\n                begin = _interval.end;\n\n            _enforceCorrectDirection(begin);\n\n            _interval.begin = begin;\n        }\n        else\n        {\n            auto end = _func(_interval.end);\n\n            if (end < _interval.begin)\n                end = _interval.begin;\n\n            _enforceCorrectDirection(end);\n\n            _interval.end = end;\n        }\n    }\n\n\n    /++\n        Returns a copy of `this`.\n      +/\n    @property IntervalRange save() pure nothrow\n    {\n        return this;\n    }\n\n\n    /++\n        The interval that this `IntervalRange` currently covers.\n      +/\n    @property Interval!TP interval() const pure nothrow\n    {\n        return cast(Interval!TP)_interval;\n    }\n\n\n    /++\n        The function used to generate the next time point in the range.\n      +/\n    TP delegate(scope const TP) func() pure nothrow @property\n    {\n        return _func;\n    }\n\n\n    /++\n        The `Direction` that this range iterates in.\n      +/\n    @property Direction direction() const pure nothrow\n    {\n        return dir;\n    }\n\n\nprivate:\n\n    /+\n        Params:\n            interval = The interval that this range covers.\n            func     = The function used to generate the time points which are\n                       iterated over.\n      +/\n    this(const Interval!TP interval, TP delegate(scope const TP) func) pure nothrow @safe\n    {\n        _func = func;\n        _interval = interval;\n    }\n\n\n    /+\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if this interval is\n            empty.\n      +/\n    void _enforceNotEmpty(size_t line = __LINE__) const pure\n    {\n        if (empty)\n            throw new DateTimeException(\"Invalid operation for an empty IntervalRange.\", __FILE__, line);\n    }\n\n\n    /+\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is\n            in the wrong direction.\n      +/\n    void _enforceCorrectDirection(scope const TP newTP, size_t line = __LINE__) const\n    {\n        import std.format : format;\n\n        static if (dir == Direction.fwd)\n        {\n            enforce(newTP > _interval._begin,\n                    new DateTimeException(format(\"Generated time point is before previous begin: prev [%s] new [%s]\",\n                                                 interval._begin,\n                                                 newTP),\n                                                 __FILE__,\n                                                 line));\n        }\n        else\n        {\n            enforce(newTP < _interval._end,\n                    new DateTimeException(format(\"Generated time point is after previous end: prev [%s] new [%s]\",\n                                                 interval._end,\n                                                 newTP),\n                                                 __FILE__,\n                                                 line));\n        }\n    }\n\n\n    Interval!TP        _interval;\n    TP delegate(scope const TP) _func;\n}\n\n//Test that IntervalRange satisfies the range predicates that it's supposed to satisfy.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n    import std.range.primitives;\n\n    static assert(isInputRange!(IntervalRange!(Date, Direction.fwd)));\n    static assert(isForwardRange!(IntervalRange!(Date, Direction.fwd)));\n\n    //Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895\n    //static assert(!isOutputRange!(IntervalRange!(Date, Direction.fwd), Date));\n\n    static assert(!isBidirectionalRange!(IntervalRange!(Date, Direction.fwd)));\n    static assert(!isRandomAccessRange!(IntervalRange!(Date, Direction.fwd)));\n    static assert(!hasSwappableElements!(IntervalRange!(Date, Direction.fwd)));\n    static assert(!hasAssignableElements!(IntervalRange!(Date, Direction.fwd)));\n    static assert(!hasLength!(IntervalRange!(Date, Direction.fwd)));\n    static assert(!isInfinite!(IntervalRange!(Date, Direction.fwd)));\n    static assert(!hasSlicing!(IntervalRange!(Date, Direction.fwd)));\n\n    static assert(is(ElementType!(IntervalRange!(Date, Direction.fwd)) == Date));\n    static assert(is(ElementType!(IntervalRange!(TimeOfDay, Direction.fwd)) == TimeOfDay));\n    static assert(is(ElementType!(IntervalRange!(DateTime, Direction.fwd)) == DateTime));\n    static assert(is(ElementType!(IntervalRange!(SysTime, Direction.fwd)) == SysTime));\n}\n\n//Test construction of IntervalRange.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    {\n        Date dateFunc(scope const Date date) { return date; }\n        auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n        auto ir = IntervalRange!(Date, Direction.fwd)(interval, &dateFunc);\n    }\n\n    {\n        TimeOfDay todFunc(scope const TimeOfDay tod) { return tod; }\n        auto interval = Interval!TimeOfDay(TimeOfDay(12, 1, 7), TimeOfDay(14, 0, 0));\n        auto ir = IntervalRange!(TimeOfDay, Direction.fwd)(interval, &todFunc);\n    }\n\n    {\n        DateTime dtFunc(scope const DateTime dt) { return dt; }\n        auto interval = Interval!DateTime(DateTime(2010, 7, 4, 12, 1, 7), DateTime(2012, 1, 7, 14, 0, 0));\n        auto ir = IntervalRange!(DateTime, Direction.fwd)(interval, &dtFunc);\n    }\n\n    {\n        SysTime stFunc(scope const SysTime st) { return cast(SysTime) st; }\n        auto interval = Interval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)),\n                                         SysTime(DateTime(2012, 1, 7, 14, 0, 0)));\n        auto ir = IntervalRange!(SysTime, Direction.fwd)(interval, &stFunc);\n    }\n}\n\n//Test IntervalRange's empty().\n@system unittest\n{\n    import std.datetime.date;\n\n    //fwd\n    {\n        auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));\n\n        assert(!range.empty);\n        range.popFront();\n        assert(range.empty);\n\n        const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));\n        assert(!cRange.empty);\n\n        //Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if\n        //empty works with it. However, since an immutable range is pretty useless, it's no great loss.\n    }\n\n    //bwd\n    {\n        auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).bwdRange(\n            everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));\n\n        assert(!range.empty);\n        range.popFront();\n        assert(range.empty);\n\n        const cRange = Interval!Date( Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(\n            everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));\n        assert(!cRange.empty);\n\n        //Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if\n        //empty works with it. However, since an immutable range is pretty useless, it's no great loss.\n    }\n}\n\n//Test IntervalRange's front.\n@system unittest\n{\n    import std.datetime.date;\n\n    //fwd\n    {\n        auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange(\n            everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);\n        assertThrown!DateTimeException(\n            (scope const IntervalRange!(Date, Direction.fwd) range){range.front;}(emptyRange));\n\n        auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed));\n        assert(range.front == Date(2010, 7, 4));\n\n        auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(\n            everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);\n        assert(poppedRange.front == Date(2010, 7, 7));\n\n        const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));\n        assert(cRange.front != Date.init);\n    }\n\n    //bwd\n    {\n        auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange(\n            everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);\n        assertThrown!DateTimeException(\n            (scope const IntervalRange!(Date, Direction.bwd) range){range.front;}(emptyRange));\n\n        auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(\n            everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed));\n        assert(range.front == Date(2012, 1, 7));\n\n        auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(\n            everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);\n        assert(poppedRange.front == Date(2012, 1, 4));\n\n        const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(\n            everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));\n        assert(cRange.front != Date.init);\n    }\n}\n\n//Test IntervalRange's popFront().\n@system unittest\n{\n    import std.datetime.date;\n    import std.range.primitives : walkLength;\n\n    //fwd\n    {\n        auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange(\n            everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);\n        assertThrown!DateTimeException((IntervalRange!(Date, Direction.fwd) range){range.popFront();}(emptyRange));\n\n        auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(\n            everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);\n        auto expected = range.front;\n\n        foreach (date; range)\n        {\n            assert(date == expected);\n            expected += dur!\"days\"(7);\n        }\n\n        assert(walkLength(range) == 79);\n\n        const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));\n        assert(cRange.front != Date.init);\n    }\n\n    //bwd\n    {\n        auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange(\n            everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);\n        assertThrown!DateTimeException((IntervalRange!(Date, Direction.bwd) range){range.popFront();}(emptyRange));\n\n        auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(\n            everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);\n        auto expected = range.front;\n\n        foreach (date; range)\n        {\n            assert(date == expected);\n            expected += dur!\"days\"(-7);\n        }\n\n        assert(walkLength(range) == 79);\n\n        const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(\n            everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));\n        static assert(!__traits(compiles, cRange.popFront()));\n    }\n}\n\n//Test IntervalRange's save.\n@system unittest\n{\n    import std.datetime.date;\n\n    //fwd\n    {\n        auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n        auto func = everyDayOfWeek!Date(DayOfWeek.fri);\n        auto range = interval.fwdRange(func);\n\n        assert(range.save == range);\n    }\n\n    //bwd\n    {\n        auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n        auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);\n        auto range = interval.bwdRange(func);\n\n        assert(range.save == range);\n    }\n}\n\n//Test IntervalRange's interval.\n@system unittest\n{\n    import std.datetime.date;\n\n    //fwd\n    {\n        auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n        auto func = everyDayOfWeek!Date(DayOfWeek.fri);\n        auto range = interval.fwdRange(func);\n\n        assert(range.interval == interval);\n\n        const cRange = range;\n        assert(!cRange.interval.empty);\n    }\n\n    //bwd\n    {\n        auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n        auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);\n        auto range = interval.bwdRange(func);\n\n        assert(range.interval == interval);\n\n        const cRange = range;\n        assert(!cRange.interval.empty);\n    }\n}\n\n//Test IntervalRange's func.\n@system unittest\n{\n    import std.datetime.date;\n\n    //fwd\n    {\n        auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n        auto func = everyDayOfWeek!Date(DayOfWeek.fri);\n        auto range = interval.fwdRange(func);\n\n        assert(range.func == func);\n    }\n\n    //bwd\n    {\n        auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n        auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);\n        auto range = interval.bwdRange(func);\n\n        assert(range.func == func);\n    }\n}\n\n//Test IntervalRange's direction.\n@system unittest\n{\n    import std.datetime.date;\n\n    //fwd\n    {\n        auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n        auto func = everyDayOfWeek!Date(DayOfWeek.fri);\n        auto range = interval.fwdRange(func);\n\n        assert(range.direction == Direction.fwd);\n\n        const cRange = range;\n        assert(cRange.direction == Direction.fwd);\n    }\n\n    //bwd\n    {\n        auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));\n        auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);\n        auto range = interval.bwdRange(func);\n\n        assert(range.direction == Direction.bwd);\n\n        const cRange = range;\n        assert(cRange.direction == Direction.bwd);\n    }\n}\n\n\n/++\n    A range over a `PosInfInterval`. It is an infinite range.\n\n    `PosInfIntervalRange` is only ever constructed by `PosInfInterval`.\n    However, when it is constructed, it is given a function, `func`, which\n    is used to generate the time points which are iterated over. `func`\n    takes a time point and returns a time point of the same type. For\n    instance, to iterate\n    over all of the days in the interval `PosInfInterval!Date`, pass a\n    function to `PosInfInterval`'s `fwdRange` where that function took a\n    $(REF Date,std,datetime,date) and returned a $(REF Date,std,datetime,date)\n    which was one day later. That function would then be used by\n    `PosInfIntervalRange`'s `popFront` to iterate over the\n    $(REF Date,std,datetime,date)s in the interval - though obviously, since the\n    range is infinite, use a function such as `std.range.take` with it rather\n    than iterating over $(I all) of the dates.\n\n    As the interval goes to positive infinity, the range is always iterated over\n    forwards, never backwards. `func` must generate a time point going in\n    the proper direction of iteration, or a\n    $(REF DateTimeException,std,datetime,date) will be thrown. So, the time\n    points that `func` generates must be later in time than the one passed to\n    it. If it's either identical or earlier in time, then a\n    $(REF DateTimeException,std,datetime,date) will be thrown.\n  +/\nstruct PosInfIntervalRange(TP)\nif (isTimePoint!TP)\n{\npublic:\n\n    /++\n        Params:\n            rhs = The `PosInfIntervalRange` to assign to this one.\n      +/\n    ref PosInfIntervalRange opAssign(ref PosInfIntervalRange rhs) pure nothrow\n    {\n        _interval = rhs._interval;\n        _func = rhs._func;\n        return this;\n    }\n\n\n    /++ Ditto +/\n    ref PosInfIntervalRange opAssign(PosInfIntervalRange rhs) pure nothrow\n    {\n        return this = rhs;\n    }\n\n\n    /++\n        This is an infinite range, so it is never empty.\n      +/\n    enum bool empty = false;\n\n\n    /++\n        The first time point in the range.\n      +/\n    @property TP front() const pure nothrow\n    {\n        return _interval.begin;\n    }\n\n\n    /++\n        Pops `front` from the range, using `func` to generate the next\n        time point in the range.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the generated time\n            point is less than `front`.\n      +/\n    void popFront()\n    {\n        auto begin = _func(_interval.begin);\n        _enforceCorrectDirection(begin);\n        _interval.begin = begin;\n    }\n\n\n    /++\n        Returns a copy of `this`.\n      +/\n    @property PosInfIntervalRange save() pure nothrow\n    {\n        return this;\n    }\n\n\n    /++\n        The interval that this range currently covers.\n      +/\n    @property PosInfInterval!TP interval() const pure nothrow\n    {\n        return cast(PosInfInterval!TP)_interval;\n    }\n\n\n    /++\n        The function used to generate the next time point in the range.\n      +/\n    TP delegate(scope const TP) func() pure nothrow @property\n    {\n        return _func;\n    }\n\n\nprivate:\n\n    /+\n        Params:\n            interval = The interval that this range covers.\n            func     = The function used to generate the time points which are\n                       iterated over.\n      +/\n    this(const PosInfInterval!TP interval, TP delegate(scope const TP) func) pure nothrow\n    {\n        _func = func;\n        _interval = interval;\n    }\n\n\n    /+\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is\n            in the wrong direction.\n      +/\n    void _enforceCorrectDirection(scope const TP newTP, size_t line = __LINE__) const\n    {\n        import std.format : format;\n\n        enforce(newTP > _interval._begin,\n                new DateTimeException(format(\"Generated time point is before previous begin: prev [%s] new [%s]\",\n                                             interval._begin,\n                                             newTP),\n                                             __FILE__,\n                                             line));\n    }\n\n\n    PosInfInterval!TP  _interval;\n    TP delegate(scope const TP) _func;\n}\n\n//Test that PosInfIntervalRange satisfies the range predicates that it's supposed to satisfy.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n    import std.range.primitives;\n\n    static assert(isInputRange!(PosInfIntervalRange!Date));\n    static assert(isForwardRange!(PosInfIntervalRange!Date));\n    static assert(isInfinite!(PosInfIntervalRange!Date));\n\n    //Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895\n    //static assert(!isOutputRange!(PosInfIntervalRange!Date, Date));\n    static assert(!isBidirectionalRange!(PosInfIntervalRange!Date));\n    static assert(!isRandomAccessRange!(PosInfIntervalRange!Date));\n    static assert(!hasSwappableElements!(PosInfIntervalRange!Date));\n    static assert(!hasAssignableElements!(PosInfIntervalRange!Date));\n    static assert(!hasLength!(PosInfIntervalRange!Date));\n    static assert(!hasSlicing!(PosInfIntervalRange!Date));\n\n    static assert(is(ElementType!(PosInfIntervalRange!Date) == Date));\n    static assert(is(ElementType!(PosInfIntervalRange!TimeOfDay) == TimeOfDay));\n    static assert(is(ElementType!(PosInfIntervalRange!DateTime) == DateTime));\n    static assert(is(ElementType!(PosInfIntervalRange!SysTime) == SysTime));\n}\n\n//Test construction of PosInfIntervalRange.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    {\n        Date dateFunc(scope const Date date) { return date; }\n        auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));\n        auto ir = PosInfIntervalRange!Date(posInfInterval, &dateFunc);\n    }\n\n    {\n        TimeOfDay todFunc(scope const TimeOfDay tod) { return tod; }\n        auto posInfInterval = PosInfInterval!TimeOfDay(TimeOfDay(12, 1, 7));\n        auto ir = PosInfIntervalRange!(TimeOfDay)(posInfInterval, &todFunc);\n    }\n\n    {\n        DateTime dtFunc(scope const DateTime dt) { return dt; }\n        auto posInfInterval = PosInfInterval!DateTime(DateTime(2010, 7, 4, 12, 1, 7));\n        auto ir = PosInfIntervalRange!(DateTime)(posInfInterval, &dtFunc);\n    }\n\n    {\n        SysTime stFunc(scope const SysTime st) { return cast(SysTime) st; }\n        auto posInfInterval = PosInfInterval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)));\n        auto ir = PosInfIntervalRange!SysTime(posInfInterval, &stFunc);\n    }\n}\n\n//Test PosInfIntervalRange's front.\n@system unittest\n{\n    import std.datetime.date;\n\n    auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed));\n    assert(range.front == Date(2010, 7, 4));\n\n    auto poppedRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);\n    assert(poppedRange.front == Date(2010, 7, 7));\n\n    const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));\n    assert(cRange.front != Date.init);\n}\n\n//Test PosInfIntervalRange's popFront().\n@system unittest\n{\n    import std.datetime.date;\n    import std.range : take;\n\n    auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);\n    auto expected = range.front;\n\n    foreach (date; take(range, 79))\n    {\n        assert(date == expected);\n        expected += dur!\"days\"(7);\n    }\n\n    const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));\n    static assert(!__traits(compiles, cRange.popFront()));\n}\n\n//Test PosInfIntervalRange's save.\n@system unittest\n{\n    import std.datetime.date;\n\n    auto interval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto func = everyDayOfWeek!Date(DayOfWeek.fri);\n    auto range = interval.fwdRange(func);\n\n    assert(range.save == range);\n}\n\n//Test PosInfIntervalRange's interval.\n@system unittest\n{\n    import std.datetime.date;\n\n    auto interval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto func = everyDayOfWeek!Date(DayOfWeek.fri);\n    auto range = interval.fwdRange(func);\n\n    assert(range.interval == interval);\n\n    const cRange = range;\n    assert(!cRange.interval.empty);\n}\n\n//Test PosInfIntervalRange's func.\n@system unittest\n{\n    import std.datetime.date;\n\n    auto interval = PosInfInterval!Date(Date(2010, 7, 4));\n    auto func = everyDayOfWeek!Date(DayOfWeek.fri);\n    auto range = interval.fwdRange(func);\n\n    assert(range.func == func);\n}\n\n\n/++\n    A range over a `NegInfInterval`. It is an infinite range.\n\n    `NegInfIntervalRange` is only ever constructed by `NegInfInterval`.\n    However, when it is constructed, it is given a function, `func`, which\n    is used to generate the time points which are iterated over. `func`\n    takes a time point and returns a time point of the same type. For\n    instance, to iterate over all of the days in the interval\n    `NegInfInterval!Date`, pass a function to `NegInfInterval`'s\n    `bwdRange` where that function took a $(REF Date,std,datetime,date) and\n    returned a $(REF Date,std,datetime,date) which was one day earlier. That\n    function would then be used by `NegInfIntervalRange`'s `popFront` to\n    iterate over the $(REF Date,std,datetime,date)s in the interval - though\n    obviously, since the range is infinite, use a function such as\n    `std.range.take` with it rather than iterating over $(I all) of the dates.\n\n    As the interval goes to negative infinity, the range is always iterated over\n    backwards, never forwards. `func` must generate a time point going in\n    the proper direction of iteration, or a\n    $(REF DateTimeException,std,datetime,date) will be thrown. So, the time\n    points that `func` generates must be earlier in time than the one passed\n    to it. If it's either identical or later in time, then a\n    $(REF DateTimeException,std,datetime,date) will be thrown.\n\n    Also note that while normally the `end` of an interval is excluded from\n    it, `NegInfIntervalRange` treats it as if it were included. This allows\n    for the same behavior as with `PosInfIntervalRange`. This works\n    because none of `NegInfInterval`'s functions which care about whether\n    `end` is included or excluded are ever called by\n    `NegInfIntervalRange`. `interval` returns a normal interval, so any\n    `NegInfInterval` functions which are called on it which care about\n    whether `end` is included or excluded will treat `end` as excluded.\n  +/\nstruct NegInfIntervalRange(TP)\nif (isTimePoint!TP)\n{\npublic:\n\n    /++\n        Params:\n            rhs = The `NegInfIntervalRange` to assign to this one.\n      +/\n    ref NegInfIntervalRange opAssign(ref NegInfIntervalRange rhs) pure nothrow\n    {\n        _interval = rhs._interval;\n        _func = rhs._func;\n\n        return this;\n    }\n\n\n    /++ Ditto +/\n    ref NegInfIntervalRange opAssign(NegInfIntervalRange rhs) pure nothrow\n    {\n        return this = rhs;\n    }\n\n\n    /++\n        This is an infinite range, so it is never empty.\n      +/\n    enum bool empty = false;\n\n\n    /++\n        The first time point in the range.\n      +/\n    @property TP front() const pure nothrow\n    {\n        return _interval.end;\n    }\n\n\n    /++\n        Pops `front` from the range, using `func` to generate the next\n        time point in the range.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the generated time\n            point is greater than `front`.\n      +/\n    void popFront()\n    {\n        auto end = _func(_interval.end);\n        _enforceCorrectDirection(end);\n        _interval.end = end;\n    }\n\n\n    /++\n        Returns a copy of `this`.\n      +/\n    @property NegInfIntervalRange save() pure nothrow\n    {\n        return this;\n    }\n\n\n    /++\n        The interval that this range currently covers.\n      +/\n    @property NegInfInterval!TP interval() const pure nothrow\n    {\n        return cast(NegInfInterval!TP)_interval;\n    }\n\n\n    /++\n        The function used to generate the next time point in the range.\n      +/\n    TP delegate(scope const TP) func() pure nothrow @property\n    {\n        return _func;\n    }\n\n\nprivate:\n\n    /+\n        Params:\n            interval = The interval that this range covers.\n            func     = The function used to generate the time points which are\n                       iterated over.\n      +/\n    this(const NegInfInterval!TP interval, TP delegate(scope const TP) func) pure nothrow\n    {\n        _func = func;\n        _interval = interval;\n    }\n\n\n    /+\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is\n            in the wrong direction.\n      +/\n    void _enforceCorrectDirection(scope const TP newTP, size_t line = __LINE__) const\n    {\n        import std.format : format;\n\n        enforce(newTP < _interval._end,\n                new DateTimeException(format(\"Generated time point is before previous end: prev [%s] new [%s]\",\n                                             interval._end,\n                                             newTP),\n                                             __FILE__,\n                                             line));\n    }\n\n\n    NegInfInterval!TP  _interval;\n    TP delegate(scope const TP) _func;\n}\n\n//Test that NegInfIntervalRange satisfies the range predicates that it's supposed to satisfy.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.range.primitives;\n\n    static assert(isInputRange!(NegInfIntervalRange!Date));\n    static assert(isForwardRange!(NegInfIntervalRange!Date));\n    static assert(isInfinite!(NegInfIntervalRange!Date));\n\n    //Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895\n    //static assert(!isOutputRange!(NegInfIntervalRange!Date, Date));\n    static assert(!isBidirectionalRange!(NegInfIntervalRange!Date));\n    static assert(!isRandomAccessRange!(NegInfIntervalRange!Date));\n    static assert(!hasSwappableElements!(NegInfIntervalRange!Date));\n    static assert(!hasAssignableElements!(NegInfIntervalRange!Date));\n    static assert(!hasLength!(NegInfIntervalRange!Date));\n    static assert(!hasSlicing!(NegInfIntervalRange!Date));\n\n    static assert(is(ElementType!(NegInfIntervalRange!Date) == Date));\n    static assert(is(ElementType!(NegInfIntervalRange!TimeOfDay) == TimeOfDay));\n    static assert(is(ElementType!(NegInfIntervalRange!DateTime) == DateTime));\n}\n\n//Test construction of NegInfIntervalRange.\n@safe unittest\n{\n    import std.datetime.date;\n    import std.datetime.systime;\n\n    {\n        Date dateFunc(scope const Date date) { return date; }\n        auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));\n        auto ir = NegInfIntervalRange!Date(negInfInterval, &dateFunc);\n    }\n\n    {\n        TimeOfDay todFunc(scope const TimeOfDay tod) { return tod; }\n        auto negInfInterval = NegInfInterval!TimeOfDay(TimeOfDay(14, 0, 0));\n        auto ir = NegInfIntervalRange!(TimeOfDay)(negInfInterval, &todFunc);\n    }\n\n    {\n        DateTime dtFunc(scope const DateTime dt) { return dt; }\n        auto negInfInterval = NegInfInterval!DateTime(DateTime(2012, 1, 7, 14, 0, 0));\n        auto ir = NegInfIntervalRange!(DateTime)(negInfInterval, &dtFunc);\n    }\n\n    {\n        SysTime stFunc(scope const SysTime st) { return cast(SysTime)(st); }\n        auto negInfInterval = NegInfInterval!SysTime(SysTime(DateTime(2012, 1, 7, 14, 0, 0)));\n        auto ir = NegInfIntervalRange!(SysTime)(negInfInterval, &stFunc);\n    }\n}\n\n//Test NegInfIntervalRange's front.\n@system unittest\n{\n    import std.datetime.date;\n\n    auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed));\n    assert(range.front == Date(2012, 1, 7));\n\n    auto poppedRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(\n        everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);\n    assert(poppedRange.front == Date(2012, 1, 4));\n\n    const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));\n    assert(cRange.front != Date.init);\n}\n\n//Test NegInfIntervalRange's popFront().\n@system unittest\n{\n    import std.datetime.date;\n    import std.range : take;\n\n    auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(\n        everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);\n    auto expected = range.front;\n\n    foreach (date; take(range, 79))\n    {\n        assert(date == expected);\n        expected += dur!\"days\"(-7);\n    }\n\n    const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));\n    static assert(!__traits(compiles, cRange.popFront()));\n}\n\n//Test NegInfIntervalRange's save.\n@system unittest\n{\n    import std.datetime.date;\n\n    auto interval = NegInfInterval!Date(Date(2012, 1, 7));\n    auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);\n    auto range = interval.bwdRange(func);\n\n    assert(range.save == range);\n}\n\n//Test NegInfIntervalRange's interval.\n@system unittest\n{\n    import std.datetime.date;\n\n    auto interval = NegInfInterval!Date(Date(2012, 1, 7));\n    auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);\n    auto range = interval.bwdRange(func);\n\n    assert(range.interval == interval);\n\n    const cRange = range;\n    assert(!cRange.interval.empty);\n}\n\n//Test NegInfIntervalRange's func.\n@system unittest\n{\n    import std.datetime.date;\n\n    auto interval = NegInfInterval!Date(Date(2012, 1, 7));\n    auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);\n    auto range = interval.bwdRange(func);\n\n    assert(range.func == func);\n}\n"
  },
  {
    "path": "libphobos/src/std/datetime/package.d",
    "content": "// Written in the D programming language\n\n/++\n    $(SCRIPT inhibitQuickIndex = 1;)\n\n    Phobos provides the following functionality for time:\n\n    $(DIVC quickindex,\n    $(BOOKTABLE ,\n    $(TR $(TH Functionality) $(TH Symbols)\n    )\n    $(TR\n        $(TD Points in Time)\n        $(TD\n            $(REF_ALTTEXT Date, Date, std, datetime, date)$(NBSP)\n            $(REF_ALTTEXT TimeOfDay, TimeOfDay, std, datetime, date)$(NBSP)\n            $(REF_ALTTEXT DateTime, DateTime, std, datetime, date)$(NBSP)\n            $(REF_ALTTEXT SysTime, SysTime, std, datetime, systime)$(NBSP)\n        )\n    )\n    $(TR\n        $(TD Timezones)\n        $(TD\n            $(REF_ALTTEXT TimeZone, TimeZone, std, datetime, timezone)$(NBSP)\n            $(REF_ALTTEXT UTC, UTC, std, datetime, timezone)$(NBSP)\n            $(REF_ALTTEXT LocalTime, LocalTime, std, datetime, timezone)$(NBSP)\n            $(REF_ALTTEXT PosixTimeZone, PosixTimeZone, std, datetime, timezone)$(NBSP)\n            $(REF_ALTTEXT WindowsTimeZone, WindowsTimeZone, std, datetime, timezone)$(NBSP)\n            $(REF_ALTTEXT SimpleTimeZone, SimpleTimeZone, std, datetime, timezone)$(NBSP)\n        )\n    )\n    $(TR\n        $(TD Intervals and Ranges of Time)\n        $(TD\n            $(REF_ALTTEXT Interval, Interval, std, datetime, interval)$(NBSP)\n            $(REF_ALTTEXT PosInfInterval, PosInfInterval, std, datetime, interval)$(NBSP)\n            $(REF_ALTTEXT NegInfInterval, NegInfInterval, std, datetime, interval)$(NBSP)\n        )\n    )\n    $(TR\n        $(TD Durations of Time)\n        $(TD\n            $(REF_ALTTEXT Duration, Duration, core, time)$(NBSP)\n            $(REF_ALTTEXT weeks, weeks, core, time)$(NBSP)\n            $(REF_ALTTEXT days, days, core, time)$(NBSP)\n            $(REF_ALTTEXT hours, hours, core, time)$(NBSP)\n            $(REF_ALTTEXT minutes, minutes, core, time)$(NBSP)\n            $(REF_ALTTEXT seconds, seconds, core, time)$(NBSP)\n            $(REF_ALTTEXT msecs, msecs, core, time)$(NBSP)\n            $(REF_ALTTEXT usecs, usecs, core, time)$(NBSP)\n            $(REF_ALTTEXT hnsecs, hnsecs, core, time)$(NBSP)\n            $(REF_ALTTEXT nsecs, nsecs, core, time)$(NBSP)\n        )\n    )\n    $(TR\n        $(TD Time Measurement and Benchmarking)\n        $(TD\n            $(REF_ALTTEXT MonoTime, MonoTime, core, time)$(NBSP)\n            $(REF_ALTTEXT StopWatch, StopWatch, std, datetime, stopwatch)$(NBSP)\n            $(REF_ALTTEXT benchmark, benchmark, std, datetime, stopwatch)$(NBSP)\n        )\n    )\n    ))\n\n    This functionality is separated into the following modules\n\n    $(UL\n        $(LI $(MREF std, datetime, date) for points in time without timezones.)\n        $(LI $(MREF std, datetime, timezone) for classes which represent timezones.)\n        $(LI $(MREF std, datetime, systime) for a point in time with a timezone.)\n        $(LI $(MREF std, datetime, interval) for types which represent series of points in time.)\n        $(LI $(MREF std, datetime, stopwatch) for measuring time.)\n    )\n\n    See_Also:\n        $(DDLINK intro-to-datetime, Introduction to std.datetime,\n                 Introduction to std&#46;datetime)<br>\n        $(HTTP en.wikipedia.org/wiki/ISO_8601, ISO 8601)<br>\n        $(HTTP en.wikipedia.org/wiki/Tz_database,\n              Wikipedia entry on TZ Database)<br>\n        $(HTTP en.wikipedia.org/wiki/List_of_tz_database_time_zones,\n              List of Time Zones)<br>\n\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis) and Kato Shoichi\n    Source:    $(PHOBOSSRC std/datetime/package.d)\n+/\nmodule std.datetime;\n\n/// Get the current time from the system clock\n@safe unittest\n{\n    import std.datetime.systime : SysTime, Clock;\n\n    SysTime currentTime = Clock.currTime();\n}\n\n/**\nConstruct a specific point in time without timezone information\nand get its ISO string.\n */\n@safe unittest\n{\n    import std.datetime.date : DateTime;\n\n    auto dt = DateTime(2018, 1, 1, 12, 30, 10);\n    assert(dt.toISOString() == \"20180101T123010\");\n    assert(dt.toISOExtString() == \"2018-01-01T12:30:10\");\n}\n\n/**\nConstruct a specific point in time in the UTC timezone and\nadd two days.\n */\n@safe unittest\n{\n    import std.datetime.systime : SysTime;\n    import std.datetime.timezone : UTC;\n    import core.time : days;\n\n    auto st = SysTime(DateTime(2018, 1, 1, 12, 30, 10), UTC());\n    assert(st.toISOExtString() == \"2018-01-01T12:30:10Z\");\n    st += 2.days;\n    assert(st.toISOExtString() == \"2018-01-03T12:30:10Z\");\n}\n\npublic import core.time;\npublic import std.datetime.date;\npublic import std.datetime.interval;\npublic import std.datetime.systime;\npublic import std.datetime.timezone;\n\nimport core.exception : AssertError;\nimport std.functional : unaryFun;\nimport std.traits;\nimport std.typecons : Flag, Yes, No;\n\n\n// Verify module example.\n@safe unittest\n{\n    auto currentTime = Clock.currTime();\n    auto timeString = currentTime.toISOExtString();\n    auto restoredTime = SysTime.fromISOExtString(timeString);\n}\n\n// Verify Examples for core.time.Duration which couldn't be in core.time.\n@safe unittest\n{\n    assert(std.datetime.Date(2010, 9, 7) + dur!\"days\"(5) ==\n           std.datetime.Date(2010, 9, 12));\n\n    assert(std.datetime.Date(2010, 9, 7) - std.datetime.Date(2010, 10, 3) ==\n           dur!\"days\"(-26));\n}\n\n@safe unittest\n{\n    import std.traits : hasUnsharedAliasing;\n    /* Issue 6642 */\n    static assert(!hasUnsharedAliasing!Date);\n    static assert(!hasUnsharedAliasing!TimeOfDay);\n    static assert(!hasUnsharedAliasing!DateTime);\n    static assert(!hasUnsharedAliasing!SysTime);\n}\n\n// @@@DEPRECATED_2018-10@@@\n/++\n    $(RED The old benchmarking functionality in std.datetime (which uses\n          $(REF TickDuration,core,time)) has been deprecated. Use what's in\n          std.datetime.stopwatch instead. It uses $(REF MonoTime,core,time) and\n          $(REF Duration,core,time). See\n          $(REF AutoStart,std,datetime,stopwatch). This symbol will be removed\n          from the documentation in October 2018 and fully removed from Phobos\n          in October 2019.)\n\n    Used by StopWatch to indicate whether it should start immediately upon\n    construction.\n\n    If set to `AutoStart.no`, then the stopwatch is not started when it is\n    constructed.\n\n    Otherwise, if set to `AutoStart.yes`, then the stopwatch is started when\n    it is constructed.\n  +/\ndeprecated(\"Use std.datetime.stopwatch.AutoStart.\") alias AutoStart = Flag!\"autoStart\";\n\n\n// @@@DEPRECATED_2018-10@@@\n/++\n    $(RED The old benchmarking functionality in std.datetime (which uses\n          $(REF TickDuration,core,time)) has been deprecated. Use what's in\n          std.datetime.stopwatch instead. It uses $(REF MonoTime,core,time) and\n          $(REF Duration,core,time). See\n          $(REF _StopWatch,std,datetime,stopwatch). This symbol will be removed\n          from the documentation in October 2018 and fully removed from Phobos\n          in October 2019.)\n\n    `StopWatch` measures time as precisely as possible.\n\n    This class uses a high-performance counter. On Windows systems, it uses\n    `QueryPerformanceCounter`, and on Posix systems, it uses\n    `clock_gettime` if available, and `gettimeofday` otherwise.\n\n    But the precision of `StopWatch` differs from system to system. It is\n    impossible to for it to be the same from system to system since the precision\n    of the system clock varies from system to system, and other system-dependent\n    and situation-dependent stuff (such as the overhead of a context switch\n    between threads) can also affect `StopWatch`'s accuracy.\n  +/\ndeprecated(\"Use std.datetime.stopwatch.StopWatch.\")\n@safe struct StopWatch\n{\npublic:\n\n    /++\n       Auto start with constructor.\n      +/\n    this(AutoStart autostart) @nogc\n    {\n        if (autostart)\n            start();\n    }\n\n    @nogc @safe unittest\n    {\n        auto sw = StopWatch(Yes.autoStart);\n        sw.stop();\n    }\n\n\n    ///\n    bool opEquals(const StopWatch rhs) const pure nothrow @nogc\n    {\n        return opEquals(rhs);\n    }\n\n    /// ditto\n    bool opEquals(const ref StopWatch rhs) const pure nothrow @nogc\n    {\n        return _timeStart == rhs._timeStart &&\n               _timeMeasured == rhs._timeMeasured;\n    }\n\n\n    /++\n       Resets the stop watch.\n      +/\n    void reset() @nogc\n    {\n        if (_flagStarted)\n        {\n            // Set current system time if StopWatch is measuring.\n            _timeStart = TickDuration.currSystemTick;\n        }\n        else\n        {\n            // Set zero if StopWatch is not measuring.\n            _timeStart.length = 0;\n        }\n\n        _timeMeasured.length = 0;\n    }\n\n    @nogc @safe unittest\n    {\n        StopWatch sw;\n        sw.start();\n        sw.stop();\n        sw.reset();\n        assert(sw.peek().to!(\"seconds\", real)() == 0);\n    }\n\n\n    /++\n       Starts the stop watch.\n      +/\n    void start() @nogc\n    {\n        assert(!_flagStarted);\n        _flagStarted = true;\n        _timeStart = TickDuration.currSystemTick;\n    }\n\n    @nogc @system unittest\n    {\n        StopWatch sw;\n        sw.start();\n        auto t1 = sw.peek();\n        bool doublestart = true;\n        try\n            sw.start();\n        catch (AssertError e)\n            doublestart = false;\n        assert(!doublestart);\n        sw.stop();\n        assert((t1 - sw.peek()).to!(\"seconds\", real)() <= 0);\n    }\n\n\n    /++\n       Stops the stop watch.\n      +/\n    void stop() @nogc\n    {\n        assert(_flagStarted);\n        _flagStarted = false;\n        _timeMeasured += TickDuration.currSystemTick - _timeStart;\n    }\n\n    @nogc @system unittest\n    {\n        StopWatch sw;\n        sw.start();\n        sw.stop();\n        auto t1 = sw.peek();\n        bool doublestop = true;\n        try\n            sw.stop();\n        catch (AssertError e)\n            doublestop = false;\n        assert(!doublestop);\n        assert((t1 - sw.peek()).to!(\"seconds\", real)() == 0);\n    }\n\n\n    /++\n       Peek at the amount of time which has passed since the stop watch was\n       started.\n      +/\n    TickDuration peek() const @nogc\n    {\n        if (_flagStarted)\n            return TickDuration.currSystemTick - _timeStart + _timeMeasured;\n\n        return _timeMeasured;\n    }\n\n    @nogc @safe unittest\n    {\n        StopWatch sw;\n        sw.start();\n        auto t1 = sw.peek();\n        sw.stop();\n        auto t2 = sw.peek();\n        auto t3 = sw.peek();\n        assert(t1 <= t2);\n        assert(t2 == t3);\n    }\n\n\n    /++\n       Set the amount of time which has been measured since the stop watch was\n       started.\n      +/\n    void setMeasured(TickDuration d) @nogc\n    {\n        reset();\n        _timeMeasured = d;\n    }\n\n    @nogc @safe unittest\n    {\n        StopWatch sw;\n        TickDuration t0;\n        t0.length = 100;\n        sw.setMeasured(t0);\n        auto t1 = sw.peek();\n        assert(t0 == t1);\n    }\n\n\n    /++\n       Confirm whether this stopwatch is measuring time.\n      +/\n    bool running() @property const pure nothrow @nogc\n    {\n        return _flagStarted;\n    }\n\n    @nogc @safe unittest\n    {\n        StopWatch sw1;\n        assert(!sw1.running);\n        sw1.start();\n        assert(sw1.running);\n        sw1.stop();\n        assert(!sw1.running);\n        StopWatch sw2 = Yes.autoStart;\n        assert(sw2.running);\n        sw2.stop();\n        assert(!sw2.running);\n        sw2.start();\n        assert(sw2.running);\n    }\n\n\n\n\nprivate:\n\n    // true if observing.\n    bool _flagStarted = false;\n\n    // TickDuration at the time of StopWatch starting measurement.\n    TickDuration _timeStart;\n\n    // Total time that StopWatch ran.\n    TickDuration _timeMeasured;\n}\n\n///\ndeprecated @safe unittest\n{\n    void writeln(S...)(S args){}\n    static void bar() {}\n\n    StopWatch sw;\n    enum n = 100;\n    TickDuration[n] times;\n    TickDuration last = TickDuration.from!\"seconds\"(0);\n    foreach (i; 0 .. n)\n    {\n       sw.start(); //start/resume mesuring.\n       foreach (unused; 0 .. 1_000_000)\n           bar();\n       sw.stop();  //stop/pause measuring.\n       //Return value of peek() after having stopped are the always same.\n       writeln((i + 1) * 1_000_000, \" times done, lap time: \",\n               sw.peek().msecs, \"[ms]\");\n       times[i] = sw.peek() - last;\n       last = sw.peek();\n    }\n    real sum = 0;\n    // To get the number of seconds,\n    // use properties of TickDuration.\n    // (seconds, msecs, usecs, hnsecs)\n    foreach (t; times)\n       sum += t.hnsecs;\n    writeln(\"Average time: \", sum/n, \" hnsecs\");\n}\n\n\n// @@@DEPRECATED_2018-10@@@\n/++\n    $(RED The old benchmarking functionality in std.datetime (which uses\n          $(REF TickDuration,core,time)) has been deprecated. Use what's in\n          std.datetime.stopwatch instead. It uses $(REF MonoTime,core,time) and\n          $(REF Duration,core,time). See\n          $(REF benchmark,std,datetime,stopwatch). This symbol will be removed\n          from the documentation in October 2018 and fully removed from Phobos\n          in October 2019.)\n\n    Benchmarks code for speed assessment and comparison.\n\n    Params:\n        fun = aliases of callable objects (e.g. function names). Each should\n              take no arguments.\n        n   = The number of times each function is to be executed.\n\n    Returns:\n        The amount of time (as a $(REF TickDuration, core,time)) that it took to\n        call each function `n` times. The first value is the length of time\n        that it took to call `fun[0]` `n` times. The second value is the\n        length of time it took to call `fun[1]` `n` times. Etc.\n\n    Note that casting the TickDurations to $(REF Duration, core,time)s will make\n    the results easier to deal with (and it may change in the future that\n    benchmark will return an array of Durations rather than TickDurations).\n\n    See_Also:\n        $(LREF measureTime)\n  +/\ndeprecated(\"Use std.datetime.stopwatch.benchmark.\")\nTickDuration[fun.length] benchmark(fun...)(uint n)\n{\n    TickDuration[fun.length] result;\n    StopWatch sw;\n    sw.start();\n\n    foreach (i, unused; fun)\n    {\n        sw.reset();\n        foreach (j; 0 .. n)\n            fun[i]();\n        result[i] = sw.peek();\n    }\n\n    return result;\n}\n\n///\ndeprecated @safe unittest\n{\n    import std.conv : to;\n    int a;\n    void f0() {}\n    void f1() {auto b = a;}\n    void f2() {auto b = to!string(a);}\n    auto r = benchmark!(f0, f1, f2)(10_000);\n    auto f0Result = to!Duration(r[0]); // time f0 took to run 10,000 times\n    auto f1Result = to!Duration(r[1]); // time f1 took to run 10,000 times\n    auto f2Result = to!Duration(r[2]); // time f2 took to run 10,000 times\n}\n\ndeprecated @safe unittest\n{\n    int a;\n    void f0() {}\n    //void f1() {auto b = to!(string)(a);}\n    void f2() {auto b = (a);}\n    auto r = benchmark!(f0, f2)(100);\n}\n\n\n// @@@DEPRECATED_2018-10@@@\n/++\n    $(RED The old benchmarking functionality in std.datetime (which uses\n          $(REF TickDuration,core,time)) has been deprecated. Use what's in\n          std.datetime.stopwatch instead. It uses $(REF MonoTime,core,time) and\n          $(REF Duration,core,time). Note that comparingBenchmark has\n          not been ported over, because it's a trivial wrapper around benchmark.\n          See $(REF benchmark,std,datetime,stopwatch). This symbol will be\n          removed from the documentation in October 2018 and fully removed from\n          Phobos in October 2019.)\n\n    Benchmark with two functions comparing.\n\n    Params:\n        baseFunc   = The function to become the base of the speed.\n        targetFunc = The function that wants to measure speed.\n        times      = The number of times each function is to be executed.\n  +/\ndeprecated(\"Use std.datetime.stopwatch.benchmark.\") @safe struct ComparingBenchmarkResult\n{\n    /++\n       Evaluation value\n\n       This returns the evaluation value of performance as the ratio of\n       baseFunc's time over targetFunc's time. If performance is high, this\n       returns a high value.\n      +/\n    @property real point() const pure nothrow\n    {\n        return _baseTime.length / cast(const real)_targetTime.length;\n    }\n\n\n    /++\n       The time required of the base function\n      +/\n    @property public TickDuration baseTime() const pure nothrow\n    {\n        return _baseTime;\n    }\n\n\n    /++\n       The time required of the target function\n      +/\n    @property public TickDuration targetTime() const pure nothrow\n    {\n        return _targetTime;\n    }\n\nprivate:\n\n    this(TickDuration baseTime, TickDuration targetTime) pure nothrow\n    {\n        _baseTime = baseTime;\n        _targetTime = targetTime;\n    }\n\n    TickDuration _baseTime;\n    TickDuration _targetTime;\n}\n\n\n// @@@DEPRECATED_2018-10@@@\n/// ditto\ndeprecated(\"Use std.datetime.stopwatch.benchmark.\")\nComparingBenchmarkResult comparingBenchmark(alias baseFunc,\n                                            alias targetFunc,\n                                            int times = 0xfff)()\n{\n    auto t = benchmark!(baseFunc, targetFunc)(times);\n    return ComparingBenchmarkResult(t[0], t[1]);\n}\n\n///\ndeprecated @safe unittest\n{\n    void f1x() {}\n    void f2x() {}\n    @safe void f1o() {}\n    @safe void f2o() {}\n    auto b1 = comparingBenchmark!(f1o, f2o, 1)(); // OK\n    //writeln(b1.point);\n}\n\n//Bug# 8450\ndeprecated @system unittest\n{\n    @safe    void safeFunc() {}\n    @trusted void trustFunc() {}\n    @system  void sysFunc() {}\n    auto safeResult  = comparingBenchmark!((){safeFunc();}, (){safeFunc();})();\n    auto trustResult = comparingBenchmark!((){trustFunc();}, (){trustFunc();})();\n    auto sysResult   = comparingBenchmark!((){sysFunc();}, (){sysFunc();})();\n    auto mixedResult1  = comparingBenchmark!((){safeFunc();}, (){trustFunc();})();\n    auto mixedResult2  = comparingBenchmark!((){trustFunc();}, (){sysFunc();})();\n    auto mixedResult3  = comparingBenchmark!((){safeFunc();}, (){sysFunc();})();\n}\n\n\n// @@@DEPRECATED_2018-10@@@\n/++\n    $(RED The old benchmarking functionality in std.datetime (which uses\n          $(REF TickDuration,core,time)) has been deprecated. Use what's in\n          std.datetime.stopwatch instead. It uses $(REF MonoTime,core,time) and\n          $(REF Duration,core,time). Note that measureTime has not been ported\n          over, because it's a trivial wrapper around StopWatch. See\n          $(REF StopWatch,std,datetime,stopwatch). This symbol will be removed\n          from the documentation in October 2018 and fully removed from Phobos\n          in October 2019.)\n\n    Function for starting to a stop watch time when the function is called\n    and stopping it when its return value goes out of scope and is destroyed.\n\n    When the value that is returned by this function is destroyed,\n    `func` will run. `func` is a unary function that takes a\n    $(REF TickDuration, core,time).\n\n    See_Also:\n        $(LREF benchmark)\n+/\ndeprecated(\"Use std.datetime.stopwatch.StopWatch.\") @safe auto measureTime(alias func)()\nif (isSafe!((){StopWatch sw; unaryFun!func(sw.peek());}))\n{\n    struct Result\n    {\n        private StopWatch _sw = void;\n        this(AutoStart as)\n        {\n            _sw = StopWatch(as);\n        }\n        ~this()\n        {\n            unaryFun!(func)(_sw.peek());\n        }\n    }\n    return Result(Yes.autoStart);\n}\n\n/// Ditto\ndeprecated(\"Use std.datetime.stopwatch.StopWatch.\") auto measureTime(alias func)()\nif (!isSafe!((){StopWatch sw; unaryFun!func(sw.peek());}))\n{\n    struct Result\n    {\n        private StopWatch _sw = void;\n        this(AutoStart as)\n        {\n            _sw = StopWatch(as);\n        }\n        ~this()\n        {\n            unaryFun!(func)(_sw.peek());\n        }\n    }\n    return Result(Yes.autoStart);\n}\n\n///\ndeprecated @safe unittest\n{\n    {\n        auto mt = measureTime!((TickDuration a)\n            { /+ do something when the scope is exited +/ });\n        // do something that needs to be timed\n    }\n\n    // functionally equivalent to the above\n    {\n        auto sw = StopWatch(Yes.autoStart);\n        scope(exit)\n        {\n            TickDuration a = sw.peek();\n            /+ do something when the scope is exited +/\n        }\n        // do something that needs to be timed\n    }\n}\n\ndeprecated @safe unittest\n{\n    import std.math : isNaN;\n\n    @safe static void func(TickDuration td)\n    {\n        assert(!td.to!(\"seconds\", real)().isNaN());\n    }\n\n    auto mt = measureTime!(func)();\n\n    /+\n    with (measureTime!((a){assert(a.seconds);}))\n    {\n        // doSomething();\n        // @@@BUG@@@ doesn't work yet.\n    }\n    +/\n}\n\ndeprecated @safe unittest\n{\n    import std.math : isNaN;\n\n    static void func(TickDuration td)\n    {\n        assert(!td.to!(\"seconds\", real)().isNaN());\n    }\n\n    auto mt = measureTime!(func)();\n\n    /+\n    with (measureTime!((a){assert(a.seconds);}))\n    {\n        // doSomething();\n        // @@@BUG@@@ doesn't work yet.\n    }\n    +/\n}\n\n//Bug# 8450\ndeprecated @system unittest\n{\n    @safe    void safeFunc() {}\n    @trusted void trustFunc() {}\n    @system  void sysFunc() {}\n    auto safeResult  = measureTime!((a){safeFunc();})();\n    auto trustResult = measureTime!((a){trustFunc();})();\n    auto sysResult   = measureTime!((a){sysFunc();})();\n}\n"
  },
  {
    "path": "libphobos/src/std/datetime/stopwatch.d",
    "content": "// Written in the D programming language\n\n/++\n    Module containing some basic benchmarking and timing functionality.\n\n    For convenience, this module publicly imports $(MREF core,time).\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Main functionality) $(TD\n    $(LREF StopWatch)\n    $(LREF benchmark)\n))\n$(TR $(TD Flags) $(TD\n    $(LREF AutoStart)\n))\n)\n\n    $(RED Unlike the other modules in std.datetime, this module is not currently\n          publicly imported in std.datetime.package, because the old\n          versions of this functionality which use\n          $(REF TickDuration,core,time) are in std.datetime.package and would\n          conflict with the symbols in this module. After the old symbols have\n          gone through the deprecation cycle and have been fully removed, then\n          this module will be publicly imported in std.datetime.package. The\n          old, deprecated symbols are currently scheduled to be removed from the\n          documentation in October 2018 and fully removed from Phobos in October\n          2019.)\n\n    So, for now, when using std.datetime.stopwatch, if other modules from\n    std.datetime are needed, then either import them individually rather than\n    importing std.datetime, or use selective or static imports to import\n    std.datetime.stopwatch. e.g.\n\n    ----------------------------------------------------------------------------\n    import std.datetime;\n    import std.datetime.stopwatch : benchmark, StopWatch;\n    ----------------------------------------------------------------------------\n\n    The compiler will then know to use the symbols from std.datetime.stopwatch\n    rather than the deprecated ones from std.datetime.package.\n\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis) and Kato Shoichi\n    Source:    $(PHOBOSSRC std/datetime/stopwatch.d)\n+/\nmodule std.datetime.stopwatch;\n\npublic import core.time;\nimport std.typecons : Flag;\n\n/++\n    Used by StopWatch to indicate whether it should start immediately upon\n    construction.\n\n    If set to `AutoStart.no`, then the StopWatch is not started when it is\n    constructed.\n\n    Otherwise, if set to `AutoStart.yes`, then the StopWatch is started when\n    it is constructed.\n  +/\nalias AutoStart = Flag!\"autoStart\";\n\n\n/++\n    StopWatch is used to measure time just like one would do with a physical\n    stopwatch, including stopping, restarting, and/or resetting it.\n\n    $(REF MonoTime,core,time) is used to hold the time, and it uses the system's\n    monotonic clock, which is high precision and never counts backwards (unlike\n    the wall clock time, which $(I can) count backwards, which is why\n    $(REF SysTime,std,datetime,systime) should not be used for timing).\n\n    Note that the precision of StopWatch differs from system to system. It is\n    impossible for it to be the same for all systems, since the precision of the\n    system clock and other system-dependent and situation-dependent factors\n    (such as the overhead of a context switch between threads) varies from\n    system to system and can affect StopWatch's accuracy.\n  +/\nstruct StopWatch\n{\npublic:\n\n    /++\n        Constructs a StopWatch. Whether it starts immediately depends on the\n        $(LREF AutoStart) argument.\n\n        If `StopWatch.init` is used, then the constructed StopWatch isn't\n        running (and can't be, since no constructor ran).\n      +/\n    this(AutoStart autostart) @safe nothrow @nogc\n    {\n        if (autostart)\n            start();\n    }\n\n    ///\n    @system nothrow @nogc unittest\n    {\n        import core.thread : Thread;\n\n        {\n            auto sw = StopWatch(AutoStart.yes);\n            assert(sw.running);\n            Thread.sleep(usecs(1));\n            assert(sw.peek() > Duration.zero);\n        }\n        {\n            auto sw = StopWatch(AutoStart.no);\n            assert(!sw.running);\n            Thread.sleep(usecs(1));\n            assert(sw.peek() == Duration.zero);\n        }\n        {\n            StopWatch sw;\n            assert(!sw.running);\n            Thread.sleep(usecs(1));\n            assert(sw.peek() == Duration.zero);\n        }\n\n        assert(StopWatch.init == StopWatch(AutoStart.no));\n        assert(StopWatch.init != StopWatch(AutoStart.yes));\n    }\n\n\n    /++\n       Resets the StopWatch.\n\n       The StopWatch can be reset while it's running, and resetting it while\n       it's running will not cause it to stop.\n      +/\n    void reset() @safe nothrow @nogc\n    {\n        if (_running)\n            _timeStarted = MonoTime.currTime;\n        _ticksElapsed = 0;\n    }\n\n    ///\n    @system nothrow @nogc unittest\n    {\n        import core.thread : Thread;\n\n        auto sw = StopWatch(AutoStart.yes);\n        Thread.sleep(usecs(1));\n        sw.stop();\n        assert(sw.peek() > Duration.zero);\n        sw.reset();\n        assert(sw.peek() == Duration.zero);\n    }\n\n    @system nothrow @nogc unittest\n    {\n        import core.thread : Thread;\n\n        auto sw = StopWatch(AutoStart.yes);\n        Thread.sleep(msecs(1));\n        assert(sw.peek() > msecs(1));\n        immutable before = MonoTime.currTime;\n\n        // Just in case the system clock is slow enough or the system is fast\n        // enough for the call to MonoTime.currTime inside of reset to get\n        // the same that we just got by calling MonoTime.currTime.\n        Thread.sleep(usecs(1));\n\n        sw.reset();\n        assert(sw.peek() < msecs(1));\n        assert(sw._timeStarted > before);\n        assert(sw._timeStarted <= MonoTime.currTime);\n    }\n\n\n    /++\n       Starts the StopWatch.\n\n       start should not be called if the StopWatch is already running.\n      +/\n    void start() @safe nothrow @nogc\n    in { assert(!_running, \"start was called when the StopWatch was already running.\"); }\n    do\n    {\n        _running = true;\n        _timeStarted = MonoTime.currTime;\n    }\n\n    ///\n    @system nothrow @nogc unittest\n    {\n        import core.thread : Thread;\n\n        StopWatch sw;\n        assert(!sw.running);\n        assert(sw.peek() == Duration.zero);\n        sw.start();\n        assert(sw.running);\n        Thread.sleep(usecs(1));\n        assert(sw.peek() > Duration.zero);\n    }\n\n\n    /++\n       Stops the StopWatch.\n\n       stop should not be called if the StopWatch is not running.\n      +/\n    void stop() @safe nothrow @nogc\n    in { assert(_running, \"stop was called when the StopWatch was not running.\"); }\n    do\n    {\n        _running = false;\n        _ticksElapsed += MonoTime.currTime.ticks - _timeStarted.ticks;\n    }\n\n    ///\n    @system nothrow @nogc unittest\n    {\n        import core.thread : Thread;\n\n        auto sw = StopWatch(AutoStart.yes);\n        assert(sw.running);\n        Thread.sleep(usecs(1));\n        immutable t1 = sw.peek();\n        assert(t1 > Duration.zero);\n\n        sw.stop();\n        assert(!sw.running);\n        immutable t2 = sw.peek();\n        assert(t2 >= t1);\n        immutable t3 = sw.peek();\n        assert(t2 == t3);\n    }\n\n\n    /++\n       Peek at the amount of time that the the StopWatch has been running.\n\n       This does not include any time during which the StopWatch was stopped but\n       does include $(I all) of the time that it was running and not just the\n       time since it was started last.\n\n       Calling $(LREF reset) will reset this to `Duration.zero`.\n      +/\n    Duration peek() @safe const nothrow @nogc\n    {\n        enum hnsecsPerSecond = convert!(\"seconds\", \"hnsecs\")(1);\n        immutable hnsecsMeasured = convClockFreq(_ticksElapsed, MonoTime.ticksPerSecond, hnsecsPerSecond);\n        return _running ? MonoTime.currTime - _timeStarted + hnsecs(hnsecsMeasured)\n                        : hnsecs(hnsecsMeasured);\n    }\n\n    ///\n    @system nothrow @nogc unittest\n    {\n        import core.thread : Thread;\n\n        auto sw = StopWatch(AutoStart.no);\n        assert(sw.peek() == Duration.zero);\n        sw.start();\n\n        Thread.sleep(usecs(1));\n        assert(sw.peek() >= usecs(1));\n\n        Thread.sleep(usecs(1));\n        assert(sw.peek() >= usecs(2));\n\n        sw.stop();\n        immutable stopped = sw.peek();\n        Thread.sleep(usecs(1));\n        assert(sw.peek() == stopped);\n\n        sw.start();\n        Thread.sleep(usecs(1));\n        assert(sw.peek() > stopped);\n    }\n\n    @safe nothrow @nogc unittest\n    {\n        assert(StopWatch.init.peek() == Duration.zero);\n    }\n\n\n    /++\n       Sets the total time which the StopWatch has been running (i.e. what peek\n       returns).\n\n       The StopWatch does not have to be stopped for setTimeElapsed to be\n       called, nor will calling it cause the StopWatch to stop.\n      +/\n    void setTimeElapsed(Duration timeElapsed) @safe nothrow @nogc\n    {\n        enum hnsecsPerSecond = convert!(\"seconds\", \"hnsecs\")(1);\n        _ticksElapsed = convClockFreq(timeElapsed.total!\"hnsecs\", hnsecsPerSecond, MonoTime.ticksPerSecond);\n        _timeStarted = MonoTime.currTime;\n    }\n\n    ///\n    @system nothrow @nogc unittest\n    {\n        import core.thread : Thread;\n\n        StopWatch sw;\n        sw.setTimeElapsed(hours(1));\n\n        // As discussed in MonoTime's documentation, converting between\n        // Duration and ticks is not exact, though it will be close.\n        // How exact it is depends on the frequency/resolution of the\n        // system's monotonic clock.\n        assert(abs(sw.peek() - hours(1)) < usecs(1));\n\n        sw.start();\n        Thread.sleep(usecs(1));\n        assert(sw.peek() > hours(1) + usecs(1));\n    }\n\n\n    /++\n       Returns whether this StopWatch is currently running.\n      +/\n    @property bool running() @safe const pure nothrow @nogc\n    {\n        return _running;\n    }\n\n    ///\n    @safe nothrow @nogc unittest\n    {\n        StopWatch sw;\n        assert(!sw.running);\n        sw.start();\n        assert(sw.running);\n        sw.stop();\n        assert(!sw.running);\n    }\n\n\nprivate:\n\n    // We track the ticks for the elapsed time rather than a Duration so that we\n    // don't lose any precision.\n\n    bool _running = false; // Whether the StopWatch is currently running\n    MonoTime _timeStarted; // The time the StopWatch started measuring (i.e. when it was started or reset).\n    long _ticksElapsed;    // Total time that the StopWatch ran before it was stopped last.\n}\n\n/// Measure a time in milliseconds, microseconds, or nanoseconds\n@safe nothrow @nogc unittest\n{\n    auto sw = StopWatch(AutoStart.no);\n    sw.start();\n    // ... Insert operations to be timed here ...\n    sw.stop();\n\n    long msecs = sw.peek.total!\"msecs\";\n    long usecs = sw.peek.total!\"usecs\";\n    long nsecs = sw.peek.total!\"nsecs\";\n\n    assert(usecs >= msecs * 1000);\n    assert(nsecs >= usecs * 1000);\n}\n\n///\n@system nothrow @nogc unittest\n{\n    import core.thread : Thread;\n\n    auto sw = StopWatch(AutoStart.yes);\n\n    Duration t1 = sw.peek();\n    Thread.sleep(usecs(1));\n    Duration t2 = sw.peek();\n    assert(t2 > t1);\n\n    Thread.sleep(usecs(1));\n    sw.stop();\n\n    Duration t3 = sw.peek();\n    assert(t3 > t2);\n    Duration t4 = sw.peek();\n    assert(t3 == t4);\n\n    sw.start();\n    Thread.sleep(usecs(1));\n\n    Duration t5 = sw.peek();\n    assert(t5 > t4);\n\n    // If stopping or resetting the StopWatch is not required, then\n    // MonoTime can easily be used by itself without StopWatch.\n    auto before = MonoTime.currTime;\n    // do stuff...\n    auto timeElapsed = MonoTime.currTime - before;\n}\n\n\n/++\n    Benchmarks code for speed assessment and comparison.\n\n    Params:\n        fun = aliases of callable objects (e.g. function names). Each callable\n              object should take no arguments.\n        n   = The number of times each function is to be executed.\n\n    Returns:\n        The amount of time (as a $(REF Duration,core,time)) that it took to call\n        each function `n` times. The first value is the length of time that\n        it took to call `fun[0]` `n` times. The second value is the length\n        of time it took to call `fun[1]` `n` times. Etc.\n  +/\nDuration[fun.length] benchmark(fun...)(uint n)\n{\n    Duration[fun.length] result;\n    auto sw = StopWatch(AutoStart.yes);\n\n    foreach (i, unused; fun)\n    {\n        sw.reset();\n        foreach (_; 0 .. n)\n            fun[i]();\n        result[i] = sw.peek();\n    }\n\n    return result;\n}\n\n///\n@safe unittest\n{\n    import std.conv : to;\n\n    int a;\n    void f0() {}\n    void f1() { auto b = a; }\n    void f2() { auto b = to!string(a); }\n    auto r = benchmark!(f0, f1, f2)(10_000);\n    Duration f0Result = r[0]; // time f0 took to run 10,000 times\n    Duration f1Result = r[1]; // time f1 took to run 10,000 times\n    Duration f2Result = r[2]; // time f2 took to run 10,000 times\n}\n\n@safe nothrow unittest\n{\n    import std.conv : to;\n\n    int a;\n    void f0() nothrow {}\n    void f1() nothrow @trusted {\n        // do not allow any optimizer to optimize this function away\n        import core.thread : getpid;\n        import core.stdc.stdio : printf;\n        auto b = getpid.to!string;\n        if (getpid == 1) // never happens, but prevents optimization\n            printf(\"%p\", &b);\n    }\n    auto r = benchmark!(f0, f1)(1000);\n    assert(r[0] >= Duration.zero);\n    assert(r[1] > Duration.zero);\n    assert(r[1] > r[0]);\n    assert(r[0] < seconds(1));\n    assert(r[1] < seconds(1));\n}\n\n@safe nothrow @nogc unittest\n{\n    int f0Count;\n    int f1Count;\n    int f2Count;\n    void f0() nothrow @nogc { ++f0Count; }\n    void f1() nothrow @nogc { ++f1Count; }\n    void f2() nothrow @nogc { ++f2Count; }\n    auto r = benchmark!(f0, f1, f2)(552);\n    assert(f0Count == 552);\n    assert(f1Count == 552);\n    assert(f2Count == 552);\n}\n"
  },
  {
    "path": "libphobos/src/std/datetime/systime.d",
    "content": "// Written in the D programming language\n\n/++\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Types) $(TD\n    $(LREF Clock)\n    $(LREF SysTime)\n    $(LREF DosFileTime)\n))\n$(TR $(TD Conversion) $(TD\n    $(LREF parseRFC822DateTime)\n    $(LREF DosFileTimeToSysTime)\n    $(LREF FILETIMEToStdTime)\n    $(LREF FILETIMEToSysTime)\n    $(LREF stdTimeToFILETIME)\n    $(LREF stdTimeToUnixTime)\n    $(LREF SYSTEMTIMEToSysTime)\n    $(LREF SysTimeToDosFileTime)\n    $(LREF SysTimeToFILETIME)\n    $(LREF SysTimeToSYSTEMTIME)\n    $(LREF unixTimeToStdTime)\n))\n)\n\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n    Source:    $(PHOBOSSRC std/datetime/systime.d)\n+/\nmodule std.datetime.systime;\n\n/// Get the current time as a $(LREF SysTime)\n@safe unittest\n{\n    import std.datetime.timezone : LocalTime;\n    SysTime today = Clock.currTime();\n    assert(today.timezone is LocalTime());\n}\n\n/// Construct a $(LREF SysTime) from a ISO time string\n@safe unittest\n{\n    import std.datetime.date : DateTime;\n    import std.datetime.timezone : UTC;\n\n    auto st = SysTime.fromISOExtString(\"2018-01-01T10:30:00Z\");\n    assert(st == SysTime(DateTime(2018, 1, 1, 10, 30, 0), UTC()));\n}\n\n/// Make a specific point in time in the New York timezone\n@safe unittest\n{\n    import core.time : hours;\n    import std.datetime.date : DateTime;\n    import std.datetime.timezone : SimpleTimeZone;\n\n    auto ny = SysTime(\n        DateTime(2018, 1, 1, 10, 30, 0),\n        new immutable SimpleTimeZone(-5.hours, \"America/New_York\")\n    );\n\n    // ISO standard time strings\n    assert(ny.toISOString() == \"20180101T103000-05:00\");\n    assert(ny.toISOExtString() == \"2018-01-01T10:30:00-05:00\");\n}\n\n// Note: reconsider using specific imports below after\n// https://issues.dlang.org/show_bug.cgi?id=17630 has been fixed\nimport core.time;// : ClockType, convert, dur, Duration, seconds, TimeException;\nimport std.datetime.date;// : _monthNames, AllowDayOverflow, CmpTimeUnits, Date,\n    //DateTime, DateTimeException, DayOfWeek, enforceValid, getDayOfWeek, maxDay,\n    //Month, splitUnitsFromHNSecs, TimeOfDay, validTimeUnits, yearIsLeapYear;\nimport std.datetime.timezone;// : LocalTime, SimpleTimeZone, TimeZone, UTC;\nimport std.exception : enforce;\nimport std.format : format;\nimport std.range.primitives;\nimport std.traits : isIntegral, isSigned, isSomeString, Unqual, isNarrowString;\n\nversion (Windows)\n{\n    import core.stdc.time : time_t;\n    import core.sys.windows.windows;\n    import core.sys.windows.winsock2;\n}\nelse version (Posix)\n{\n    import core.sys.posix.signal : timespec;\n    import core.sys.posix.sys.types : time_t;\n}\n\nversion (unittest)\n{\n    import core.exception : AssertError;\n    import std.exception : assertThrown;\n}\n\n\n@safe unittest\n{\n    initializeTests();\n}\n\n\n/++\n    Effectively a namespace to make it clear that the methods it contains are\n    getting the time from the system clock. It cannot be instantiated.\n +/\nfinal class Clock\n{\npublic:\n\n    /++\n        Returns the current time in the given time zone.\n\n        Params:\n            clockType = The $(REF ClockType, core,time) indicates which system\n                        clock to use to get the current time. Very few programs\n                        need to use anything other than the default.\n            tz = The time zone for the SysTime that's returned.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if it fails to get the\n            time.\n      +/\n    static SysTime currTime(ClockType clockType = ClockType.normal)(immutable TimeZone tz = LocalTime()) @safe\n    {\n        return SysTime(currStdTime!clockType, tz);\n    }\n\n    @safe unittest\n    {\n        import std.format : format;\n        import core.time;\n        assert(currTime().timezone is LocalTime());\n        assert(currTime(UTC()).timezone is UTC());\n\n        // core.stdc.time.time does not always use unix time on Windows systems.\n        // In particular, dmc does not use unix time. If we can guarantee that\n        // the MS runtime uses unix time, then we may be able run this test\n        // then, but for now, we're just not going to run this test on Windows.\n        version (Posix)\n        {\n            static import core.stdc.time;\n            static import std.math;\n            immutable unixTimeD = currTime().toUnixTime();\n            immutable unixTimeC = core.stdc.time.time(null);\n            assert(std.math.abs(unixTimeC - unixTimeD) <= 2);\n        }\n\n        auto norm1 = Clock.currTime;\n        auto norm2 = Clock.currTime(UTC());\n        assert(norm1 <= norm2, format(\"%s %s\", norm1, norm2));\n        assert(abs(norm1 - norm2) <= seconds(2));\n\n        import std.meta : AliasSeq;\n        static foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second))\n        {{\n            auto value1 = Clock.currTime!ct;\n            auto value2 = Clock.currTime!ct(UTC());\n            assert(value1 <= value2, format(\"%s %s (ClockType: %s)\", value1, value2, ct));\n            assert(abs(value1 - value2) <= seconds(2), format(\"ClockType.%s\", ct));\n        }}\n    }\n\n\n    /++\n        Returns the number of hnsecs since midnight, January 1st, 1 A.D. for the\n        current time.\n\n        Params:\n            clockType = The $(REF ClockType, core,time) indicates which system\n                        clock to use to get the current time. Very few programs\n                        need to use anything other than the default.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if it fails to get the\n            time.\n      +/\n    static @property long currStdTime(ClockType clockType = ClockType.normal)() @trusted\n    {\n        static if (clockType != ClockType.coarse &&\n                   clockType != ClockType.normal &&\n                   clockType != ClockType.precise &&\n                   clockType != ClockType.second)\n        {\n            static assert(0, format(\"ClockType.%s is not supported by Clock.currTime or Clock.currStdTime\", clockType));\n        }\n\n        version (Windows)\n        {\n            FILETIME fileTime;\n            GetSystemTimeAsFileTime(&fileTime);\n            immutable result = FILETIMEToStdTime(&fileTime);\n            static if (clockType == ClockType.second)\n            {\n                // Ideally, this would use core.std.time.time, but the C runtime\n                // has to be using unix time for that to work, and that's not\n                // guaranteed on Windows. Digital Mars does not use unix time.\n                // MS may or may not. If it does, then this can be made to use\n                // core.stdc.time for MS, but for now, we'll leave it like this.\n                return convert!(\"seconds\", \"hnsecs\")(convert!(\"hnsecs\", \"seconds\")(result));\n            }\n            else\n                return result;\n        }\n        else version (Posix)\n        {\n            static import core.stdc.time;\n            enum hnsecsToUnixEpoch = unixTimeToStdTime(0);\n\n            version (OSX)\n            {\n                static if (clockType == ClockType.second)\n                    return unixTimeToStdTime(core.stdc.time.time(null));\n                else\n                {\n                    import core.sys.posix.sys.time : gettimeofday, timeval;\n                    timeval tv;\n                    if (gettimeofday(&tv, null) != 0)\n                        throw new TimeException(\"Call to gettimeofday() failed\");\n                    return convert!(\"seconds\", \"hnsecs\")(tv.tv_sec) +\n                           convert!(\"usecs\", \"hnsecs\")(tv.tv_usec) +\n                           hnsecsToUnixEpoch;\n                }\n            }\n            else version (linux)\n            {\n                static if (clockType == ClockType.second)\n                    return unixTimeToStdTime(core.stdc.time.time(null));\n                else\n                {\n                    import core.sys.linux.time : CLOCK_REALTIME_COARSE;\n                    import core.sys.posix.time : clock_gettime, CLOCK_REALTIME;\n                    static if (clockType == ClockType.coarse)       alias clockArg = CLOCK_REALTIME_COARSE;\n                    else static if (clockType == ClockType.normal)  alias clockArg = CLOCK_REALTIME;\n                    else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;\n                    else static assert(0, \"Previous static if is wrong.\");\n                    timespec ts;\n                    if (clock_gettime(clockArg, &ts) != 0)\n                        throw new TimeException(\"Call to clock_gettime() failed\");\n                    return convert!(\"seconds\", \"hnsecs\")(ts.tv_sec) +\n                           ts.tv_nsec / 100 +\n                           hnsecsToUnixEpoch;\n                }\n            }\n            else version (FreeBSD)\n            {\n                import core.sys.freebsd.time : clock_gettime, CLOCK_REALTIME,\n                    CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND;\n                static if (clockType == ClockType.coarse)       alias clockArg = CLOCK_REALTIME_FAST;\n                else static if (clockType == ClockType.normal)  alias clockArg = CLOCK_REALTIME;\n                else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE;\n                else static if (clockType == ClockType.second)  alias clockArg = CLOCK_SECOND;\n                else static assert(0, \"Previous static if is wrong.\");\n                timespec ts;\n                if (clock_gettime(clockArg, &ts) != 0)\n                    throw new TimeException(\"Call to clock_gettime() failed\");\n                return convert!(\"seconds\", \"hnsecs\")(ts.tv_sec) +\n                       ts.tv_nsec / 100 +\n                       hnsecsToUnixEpoch;\n            }\n            else version (NetBSD)\n            {\n                static if (clockType == ClockType.second)\n                    return unixTimeToStdTime(core.stdc.time.time(null));\n                else\n                {\n                    import core.sys.posix.sys.time : gettimeofday, timeval;\n                    timeval tv;\n                    if (gettimeofday(&tv, null) != 0)\n                        throw new TimeException(\"Call to gettimeofday() failed\");\n                    return convert!(\"seconds\", \"hnsecs\")(tv.tv_sec) +\n                           convert!(\"usecs\", \"hnsecs\")(tv.tv_usec) +\n                           hnsecsToUnixEpoch;\n                }\n            }\n            else version (DragonFlyBSD)\n            {\n                import core.sys.dragonflybsd.time : clock_gettime, CLOCK_REALTIME,\n                    CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND;\n                static if (clockType == ClockType.coarse)       alias clockArg = CLOCK_REALTIME_FAST;\n                else static if (clockType == ClockType.normal)  alias clockArg = CLOCK_REALTIME;\n                else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE;\n                else static if (clockType == ClockType.second)  alias clockArg = CLOCK_SECOND;\n                else static assert(0, \"Previous static if is wrong.\");\n                timespec ts;\n                if (clock_gettime(clockArg, &ts) != 0)\n                    throw new TimeException(\"Call to clock_gettime() failed\");\n                return convert!(\"seconds\", \"hnsecs\")(ts.tv_sec) +\n                       ts.tv_nsec / 100 +\n                       hnsecsToUnixEpoch;\n            }\n            else version (Solaris)\n            {\n                static if (clockType == ClockType.second)\n                    return unixTimeToStdTime(core.stdc.time.time(null));\n                else\n                {\n                    import core.sys.solaris.time : clock_gettime, CLOCK_REALTIME;\n                    static if (clockType == ClockType.coarse)       alias clockArg = CLOCK_REALTIME;\n                    else static if (clockType == ClockType.normal)  alias clockArg = CLOCK_REALTIME;\n                    else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;\n                    else static assert(0, \"Previous static if is wrong.\");\n                    timespec ts;\n                    if (clock_gettime(clockArg, &ts) != 0)\n                        throw new TimeException(\"Call to clock_gettime() failed\");\n                    return convert!(\"seconds\", \"hnsecs\")(ts.tv_sec) +\n                           ts.tv_nsec / 100 +\n                           hnsecsToUnixEpoch;\n                }\n            }\n            else static assert(0, \"Unsupported OS\");\n        }\n        else static assert(0, \"Unsupported OS\");\n    }\n\n    @safe unittest\n    {\n        import std.format : format;\n        import std.math : abs;\n        import std.meta : AliasSeq;\n        enum limit = convert!(\"seconds\", \"hnsecs\")(2);\n\n        auto norm1 = Clock.currStdTime;\n        auto norm2 = Clock.currStdTime;\n        assert(norm1 <= norm2, format(\"%s %s\", norm1, norm2));\n        assert(abs(norm1 - norm2) <= limit);\n\n        static foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second))\n        {{\n            auto value1 = Clock.currStdTime!ct;\n            auto value2 = Clock.currStdTime!ct;\n            assert(value1 <= value2, format(\"%s %s (ClockType: %s)\", value1, value2, ct));\n            assert(abs(value1 - value2) <= limit);\n        }}\n    }\n\n\nprivate:\n\n    @disable this() {}\n}\n\n/// Get the current time as a $(LREF SysTime)\n@safe unittest\n{\n    import std.datetime.timezone : LocalTime;\n    SysTime today = Clock.currTime();\n    assert(today.timezone is LocalTime());\n}\n\n\n/++\n    `SysTime` is the type used to get the current time from the\n    system or doing anything that involves time zones. Unlike\n    $(REF DateTime,std,datetime,date), the time zone is an integral part of\n    `SysTime` (though for local time applications, time zones can be ignored\n    and it will work, since it defaults to using the local time zone). It holds\n    its internal time in std time (hnsecs since midnight, January 1st, 1 A.D.\n    UTC), so it interfaces well with the system time. However, that means that,\n    unlike $(REF DateTime,std,datetime,date), it is not optimized for\n    calendar-based operations, and getting individual units from it such as\n    years or days is going to involve conversions and be less efficient.\n\n    For calendar-based operations that don't\n    care about time zones, then $(REF DateTime,std,datetime,date) would be\n    the type to use. For system time, use `SysTime`.\n\n    $(LREF Clock.currTime) will return the current time as a `SysTime`.\n    To convert a `SysTime` to a $(REF Date,std,datetime,date) or\n    $(REF DateTime,std,datetime,date), simply cast it. To convert a\n    $(REF Date,std,datetime,date) or $(REF DateTime,std,datetime,date) to a\n    `SysTime`, use `SysTime`'s constructor, and pass in the ntended time\n    zone with it (or don't pass in a $(REF TimeZone,std,datetime,timezone), and\n    the local time zone will be used). Be aware, however, that converting from a\n    $(REF DateTime,std,datetime,date) to a `SysTime` will not necessarily\n    be 100% accurate due to DST (one hour of the year doesn't exist and another\n    occurs twice). To not risk any conversion errors, keep times as\n    `SysTime`s. Aside from DST though, there shouldn't be any conversion\n    problems.\n\n    For using time zones other than local time or UTC, use\n    $(REF PosixTimeZone,std,datetime,timezone) on Posix systems (or on Windows,\n    if providing the TZ Database files), and use\n    $(REF WindowsTimeZone,std,datetime,timezone) on Windows systems. The time in\n    `SysTime` is kept internally in hnsecs from midnight, January 1st, 1 A.D.\n    UTC. Conversion error cannot happen when changing the time zone of a\n    `SysTime`. $(REF LocalTime,std,datetime,timezone) is the\n    $(REF TimeZone,std,datetime,timezone) class which represents the local time,\n    and `UTC` is the $(REF TimeZone,std,datetime,timezone) class which\n    represents UTC. `SysTime` uses $(REF LocalTime,std,datetime,timezone) if\n    no $(REF TimeZone,std,datetime,timezone) is provided. For more details on\n    time zones, see the documentation for $(REF TimeZone,std,datetime,timezone),\n    $(REF PosixTimeZone,std,datetime,timezone), and\n    $(REF WindowsTimeZone,std,datetime,timezone).\n\n    `SysTime`'s range is from approximately 29,000 B.C. to approximately\n    29,000 A.D.\n  +/\nstruct SysTime\n{\n    import core.stdc.time : tm;\n    version (Posix) import core.sys.posix.sys.time : timeval;\n    import std.typecons : Rebindable;\n\npublic:\n\n    /++\n        Params:\n            dateTime = The $(REF DateTime,std,datetime,date) to use to set\n                       this $(LREF SysTime)'s internal std time. As\n                       $(REF DateTime,std,datetime,date) has no concept of\n                       time zone, tz is used as its time zone.\n            tz       = The $(REF TimeZone,std,datetime,timezone) to use for this\n                       $(LREF SysTime). If null,\n                       $(REF LocalTime,std,datetime,timezone) will be used. The\n                       given $(REF DateTime,std,datetime,date) is assumed to\n                       be in the given time zone.\n      +/\n    this(DateTime dateTime, immutable TimeZone tz = null) @safe nothrow\n    {\n        try\n            this(dateTime, Duration.zero, tz);\n        catch (Exception e)\n            assert(0, \"SysTime's constructor threw when it shouldn't have.\");\n    }\n\n    @safe unittest\n    {\n        static void test(DateTime dt, immutable TimeZone tz, long expected)\n        {\n            auto sysTime = SysTime(dt, tz);\n            assert(sysTime._stdTime == expected);\n            assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format(\"Given DateTime: %s\", dt));\n        }\n\n        test(DateTime.init, UTC(), 0);\n        test(DateTime(1, 1, 1, 12, 30, 33), UTC(), 450_330_000_000L);\n        test(DateTime(0, 12, 31, 12, 30, 33), UTC(), -413_670_000_000L);\n        test(DateTime(1, 1, 1, 0, 0, 0), UTC(), 0);\n        test(DateTime(1, 1, 1, 0, 0, 1), UTC(), 10_000_000L);\n        test(DateTime(0, 12, 31, 23, 59, 59), UTC(), -10_000_000L);\n\n        test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!\"minutes\"(-60)), 36_000_000_000L);\n        test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(Duration.zero), 0);\n        test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!\"minutes\"(60)), -36_000_000_000L);\n\n        static void testScope(scope ref DateTime dt) @safe\n        {\n            auto st = SysTime(dt);\n        }\n    }\n\n    /++\n        Params:\n            dateTime = The $(REF DateTime,std,datetime,date) to use to set\n                       this $(LREF SysTime)'s internal std time. As\n                       $(REF DateTime,std,datetime,date) has no concept of\n                       time zone, tz is used as its time zone.\n            fracSecs = The fractional seconds portion of the time.\n            tz       = The $(REF TimeZone,std,datetime,timezone) to use for this\n                       $(LREF SysTime). If null,\n                       $(REF LocalTime,std,datetime,timezone) will be used. The\n                       given $(REF DateTime,std,datetime,date) is assumed to\n                       be in the given time zone.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if `fracSecs` is negative or if it's\n            greater than or equal to one second.\n      +/\n    this(DateTime dateTime, Duration fracSecs, immutable TimeZone tz = null) @safe\n    {\n        enforce(fracSecs >= Duration.zero, new DateTimeException(\"A SysTime cannot have negative fractional seconds.\"));\n        enforce(fracSecs < seconds(1), new DateTimeException(\"Fractional seconds must be less than one second.\"));\n        auto nonNullTZ = tz is null ? LocalTime() : tz;\n\n        immutable dateDiff = dateTime.date - Date.init;\n        immutable todDiff = dateTime.timeOfDay - TimeOfDay.init;\n\n        immutable adjustedTime = dateDiff + todDiff + fracSecs;\n        immutable standardTime = nonNullTZ.tzToUTC(adjustedTime.total!\"hnsecs\");\n\n        this(standardTime, nonNullTZ);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        static void test(DateTime dt, Duration fracSecs, immutable TimeZone tz, long expected)\n        {\n            auto sysTime = SysTime(dt, fracSecs, tz);\n            assert(sysTime._stdTime == expected);\n            assert(sysTime._timezone is (tz is null ? LocalTime() : tz),\n                   format(\"Given DateTime: %s, Given Duration: %s\", dt, fracSecs));\n        }\n\n        test(DateTime.init, Duration.zero, UTC(), 0);\n        test(DateTime(1, 1, 1, 12, 30, 33), Duration.zero, UTC(), 450_330_000_000L);\n        test(DateTime(0, 12, 31, 12, 30, 33), Duration.zero, UTC(), -413_670_000_000L);\n        test(DateTime(1, 1, 1, 0, 0, 0), msecs(1), UTC(), 10_000L);\n        test(DateTime(0, 12, 31, 23, 59, 59), msecs(999), UTC(), -10_000L);\n\n        test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC(), -1);\n        test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC(), -9_999_999);\n        test(DateTime(0, 12, 31, 23, 59, 59), Duration.zero, UTC(), -10_000_000);\n\n        assertThrown!DateTimeException(SysTime(DateTime.init, hnsecs(-1), UTC()));\n        assertThrown!DateTimeException(SysTime(DateTime.init, seconds(1), UTC()));\n\n        static void testScope(scope ref DateTime dt, scope ref Duration d) @safe\n        {\n            auto st = SysTime(dt, d);\n        }\n    }\n\n    /++\n        Params:\n            date = The $(REF Date,std,datetime,date) to use to set this\n                   $(LREF SysTime)'s internal std time. As\n                   $(REF Date,std,datetime,date) has no concept of time zone, tz\n                   is used as its time zone.\n            tz   = The $(REF TimeZone,std,datetime,timezone) to use for this\n                   $(LREF SysTime). If null,\n                   $(REF LocalTime,std,datetime,timezone) will be used. The\n                   given $(REF Date,std,datetime,date) is assumed to be in the\n                   given time zone.\n      +/\n    this(Date date, immutable TimeZone tz = null) @safe nothrow\n    {\n        _timezone = tz is null ? LocalTime() : tz;\n\n        try\n        {\n            immutable adjustedTime = (date - Date(1, 1, 1)).total!\"hnsecs\";\n            immutable standardTime = _timezone.tzToUTC(adjustedTime);\n\n            this(standardTime, _timezone);\n        }\n        catch (Exception e)\n            assert(0, \"Date's constructor through when it shouldn't have.\");\n    }\n\n    @safe unittest\n    {\n        static void test(Date d, immutable TimeZone tz, long expected)\n        {\n            auto sysTime = SysTime(d, tz);\n            assert(sysTime._stdTime == expected);\n            assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format(\"Given Date: %s\", d));\n        }\n\n        test(Date.init, UTC(), 0);\n        test(Date(1, 1, 1), UTC(), 0);\n        test(Date(1, 1, 2), UTC(), 864000000000);\n        test(Date(0, 12, 31), UTC(), -864000000000);\n\n        static void testScope(scope ref Date d) @safe\n        {\n            auto st = SysTime(d);\n        }\n    }\n\n    /++\n        Note:\n            Whereas the other constructors take in the given date/time, assume\n            that it's in the given time zone, and convert it to hnsecs in UTC\n            since midnight, January 1st, 1 A.D. UTC - i.e. std time - this\n            constructor takes a std time, which is specifically already in UTC,\n            so no conversion takes place. Of course, the various getter\n            properties and functions will use the given time zone's conversion\n            function to convert the results to that time zone, but no conversion\n            of the arguments to this constructor takes place.\n\n        Params:\n            stdTime = The number of hnsecs since midnight, January 1st, 1 A.D.\n                      UTC.\n            tz      = The $(REF TimeZone,std,datetime,timezone) to use for this\n                      $(LREF SysTime). If null,\n                      $(REF LocalTime,std,datetime,timezone) will be used.\n      +/\n    this(long stdTime, immutable TimeZone tz = null) @safe pure nothrow\n    {\n        _stdTime = stdTime;\n        _timezone = tz is null ? LocalTime() : tz;\n    }\n\n    @safe unittest\n    {\n        static void test(long stdTime, immutable TimeZone tz)\n        {\n            auto sysTime = SysTime(stdTime, tz);\n            assert(sysTime._stdTime == stdTime);\n            assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format(\"Given stdTime: %s\", stdTime));\n        }\n\n        foreach (stdTime; [-1234567890L, -250, 0, 250, 1235657390L])\n        {\n            foreach (tz; testTZs)\n                test(stdTime, tz);\n        }\n    }\n\n\n    /++\n        Params:\n            rhs = The $(LREF SysTime) to assign to this one.\n\n        Returns: The `this` of this `SysTime`.\n      +/\n    ref SysTime opAssign()(auto ref const(SysTime) rhs) return @safe pure nothrow scope\n    {\n        _stdTime = rhs._stdTime;\n        _timezone = rhs._timezone;\n        return this;\n    }\n\n    @safe unittest\n    {\n        SysTime st;\n        st = SysTime(DateTime(2012, 12, 21, 1, 2, 3), UTC());\n        assert(st == SysTime(DateTime(2012, 12, 21, 1, 2, 3), UTC()));\n\n        const other = SysTime(DateTime(19, 1, 7, 13, 14, 15), LocalTime());\n        st = other;\n        assert(st == other);\n\n        static void testScope(scope ref SysTime left, const scope SysTime right) @safe\n        {\n            left = right;\n        }\n    }\n\n\n    /++\n        Checks for equality between this $(LREF SysTime) and the given\n        $(LREF SysTime).\n\n        Note that the time zone is ignored. Only the internal\n        std times (which are in UTC) are compared.\n     +/\n    bool opEquals()(auto ref const(SysTime) rhs) @safe const pure nothrow scope\n    {\n        return _stdTime == rhs._stdTime;\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        assert(SysTime(DateTime.init, UTC()) == SysTime(0, UTC()));\n        assert(SysTime(DateTime.init, UTC()) == SysTime(0));\n        assert(SysTime(Date.init, UTC()) == SysTime(0));\n        assert(SysTime(0) == SysTime(0));\n\n        static void test(DateTime dt, immutable TimeZone tz1, immutable TimeZone tz2)\n        {\n            auto st1 = SysTime(dt);\n            st1.timezone = tz1;\n\n            auto st2 = SysTime(dt);\n            st2.timezone = tz2;\n\n            assert(st1 == st2);\n        }\n\n        foreach (tz1; testTZs)\n        {\n            foreach (tz2; testTZs)\n            {\n                foreach (dt; chain(testDateTimesBC, testDateTimesAD))\n                    test(dt, tz1, tz2);\n            }\n        }\n\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30));\n        assert(st == st);\n        assert(st == cst);\n        assert(st == ist);\n        assert(cst == st);\n        assert(cst == cst);\n        assert(cst == ist);\n        assert(ist == st);\n        assert(ist == cst);\n        assert(ist == ist);\n\n        static void testScope(scope ref SysTime left, const scope SysTime right) @safe\n        {\n            assert(left == right);\n            assert(right == left);\n        }\n    }\n\n\n    /++\n        Compares this $(LREF SysTime) with the given $(LREF SysTime).\n\n        Time zone is irrelevant when comparing $(LREF SysTime)s.\n\n        Returns:\n            $(BOOKTABLE,\n            $(TR $(TD this &lt; rhs) $(TD &lt; 0))\n            $(TR $(TD this == rhs) $(TD 0))\n            $(TR $(TD this &gt; rhs) $(TD &gt; 0))\n            )\n     +/\n    int opCmp()(auto ref const(SysTime) rhs) @safe const pure nothrow scope\n    {\n        if (_stdTime < rhs._stdTime)\n            return -1;\n        if (_stdTime > rhs._stdTime)\n            return 1;\n        return 0;\n    }\n\n    @safe unittest\n    {\n        import std.algorithm.iteration : map;\n        import std.array : array;\n        import std.range : chain;\n\n        assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0, UTC())) == 0);\n        assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0)) == 0);\n        assert(SysTime(Date.init, UTC()).opCmp(SysTime(0)) == 0);\n        assert(SysTime(0).opCmp(SysTime(0)) == 0);\n\n        static void testEqual(SysTime st, immutable TimeZone tz1, immutable TimeZone tz2)\n        {\n            auto st1 = st;\n            st1.timezone = tz1;\n\n            auto st2 = st;\n            st2.timezone = tz2;\n\n            assert(st1.opCmp(st2) == 0);\n        }\n\n        auto sts = array(map!SysTime(chain(testDateTimesBC, testDateTimesAD)));\n\n        foreach (st; sts)\n        {\n            foreach (tz1; testTZs)\n            {\n                foreach (tz2; testTZs)\n                    testEqual(st, tz1, tz2);\n            }\n        }\n\n        static void testCmp(SysTime st1, immutable TimeZone tz1, SysTime st2, immutable TimeZone tz2)\n        {\n            st1.timezone = tz1;\n            st2.timezone = tz2;\n            assert(st1.opCmp(st2) < 0);\n            assert(st2.opCmp(st1) > 0);\n        }\n\n        foreach (si, st1; sts)\n        {\n            foreach (st2; sts[si + 1 .. $])\n            {\n                foreach (tz1; testTZs)\n                {\n                    foreach (tz2; testTZs)\n                        testCmp(st1, tz1, st2, tz2);\n                }\n            }\n        }\n\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30));\n        assert(st.opCmp(st) == 0);\n        assert(st.opCmp(cst) == 0);\n        assert(st.opCmp(ist) == 0);\n        assert(cst.opCmp(st) == 0);\n        assert(cst.opCmp(cst) == 0);\n        assert(cst.opCmp(ist) == 0);\n        assert(ist.opCmp(st) == 0);\n        assert(ist.opCmp(cst) == 0);\n        assert(ist.opCmp(ist) == 0);\n\n        static void testScope(scope ref SysTime left, const scope SysTime right) @safe\n        {\n            assert(left < right);\n            assert(right > left);\n        }\n    }\n\n\n    /++\n        Returns: A hash of the $(LREF SysTime).\n     +/\n    size_t toHash() const @nogc pure nothrow @safe scope\n    {\n        static if (is(size_t == ulong))\n            return _stdTime;\n        else\n        {\n            // MurmurHash2\n            enum ulong m = 0xc6a4a7935bd1e995UL;\n            enum ulong n = m * 16;\n            enum uint r = 47;\n\n            ulong k = _stdTime;\n            k *= m;\n            k ^= k >> r;\n            k *= m;\n\n            ulong h = n;\n            h ^= k;\n            h *= m;\n\n            return cast(size_t) h;\n        }\n    }\n\n    @safe unittest\n    {\n        assert(SysTime(0).toHash == SysTime(0).toHash);\n        assert(SysTime(DateTime(2000, 1, 1)).toHash == SysTime(DateTime(2000, 1, 1)).toHash);\n        assert(SysTime(DateTime(2000, 1, 1)).toHash != SysTime(DateTime(2000, 1, 2)).toHash);\n\n        // test that timezones aren't taken into account\n        assert(SysTime(0, LocalTime()).toHash == SysTime(0, LocalTime()).toHash);\n        assert(SysTime(0, LocalTime()).toHash == SysTime(0, UTC()).toHash);\n        assert(SysTime(DateTime(2000, 1, 1), LocalTime()).toHash == SysTime(DateTime(2000, 1, 1), LocalTime()).toHash);\n        immutable zone = new SimpleTimeZone(dur!\"minutes\"(60));\n        assert(SysTime(DateTime(2000, 1, 1, 1), zone).toHash == SysTime(DateTime(2000, 1, 1), UTC()).toHash);\n        assert(SysTime(DateTime(2000, 1, 1), zone).toHash != SysTime(DateTime(2000, 1, 1), UTC()).toHash);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.toHash();\n        }\n    }\n\n\n    /++\n        Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive\n        are B.C.\n     +/\n    @property short year() @safe const nothrow scope\n    {\n        return (cast(Date) this).year;\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n        static void test(SysTime sysTime, long expected)\n        {\n            assert(sysTime.year == expected, format(\"Value given: %s\", sysTime));\n        }\n\n        test(SysTime(0, UTC()), 1);\n        test(SysTime(1, UTC()), 1);\n        test(SysTime(-1, UTC()), 0);\n\n        foreach (year; chain(testYearsBC, testYearsAD))\n        {\n            foreach (md; testMonthDays)\n            {\n                foreach (tod; testTODs)\n                {\n                    auto dt = DateTime(Date(year, md.month, md.day), tod);\n                    foreach (tz; testTZs)\n                    {\n                        foreach (fs; testFracSecs)\n                            test(SysTime(dt, fs, tz), year);\n                    }\n                }\n            }\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.year == 1999);\n        assert(ist.year == 1999);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.year;\n        }\n    }\n\n    /++\n        Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive\n        are B.C.\n\n        Params:\n            year = The year to set this $(LREF SysTime)'s year to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the new year is not\n            a leap year and the resulting date would be on February 29th.\n     +/\n    @property void year(int year) @safe scope\n    {\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        auto date = Date(cast(int) days);\n        date.year = year;\n\n        immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(date.dayOfGregorianCal - 1);\n        adjTime = newDaysHNSecs + hnsecs;\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).year == 1999);\n        assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).year == 2010);\n        assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).year == -7);\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        static void test(SysTime st, int year, SysTime expected)\n        {\n            st.year = year;\n            assert(st == expected);\n        }\n\n        foreach (st; chain(testSysTimesBC, testSysTimesAD))\n        {\n            auto dt = cast(DateTime) st;\n\n            foreach (year; chain(testYearsBC, testYearsAD))\n            {\n                auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second),\n                                 st.fracSecs,\n                                 st.timezone);\n                test(st, year, e);\n            }\n        }\n\n        foreach (fs; testFracSecs)\n        {\n            foreach (tz; testTZs)\n            {\n                foreach (tod; testTODs)\n                {\n                    test(SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz), 2000,\n                         SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz));\n                    test(SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz), 1999,\n                         SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz));\n                }\n\n                foreach (tod; testTODsThrown)\n                {\n                    auto st = SysTime(DateTime(Date(2000, 2, 29), tod), fs, tz);\n                    assertThrown!DateTimeException(st.year = 1999);\n                }\n            }\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.year = 7));\n        static assert(!__traits(compiles, ist.year = 7));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.year = 42;\n        }\n    }\n\n    /++\n        Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if `isAD` is true.\n     +/\n    @property ushort yearBC() @safe const scope\n    {\n        return (cast(Date) this).yearBC;\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(0, 1, 1, 12, 30, 33)).yearBC == 1);\n        assert(SysTime(DateTime(-1, 1, 1, 10, 7, 2)).yearBC == 2);\n        assert(SysTime(DateTime(-100, 1, 1, 4, 59, 0)).yearBC == 101);\n    }\n\n    @safe unittest\n    {\n        import std.exception : assertNotThrown;\n        foreach (st; testSysTimesBC)\n        {\n            auto msg = format(\"SysTime: %s\", st);\n            assertNotThrown!DateTimeException(st.yearBC, msg);\n            assert(st.yearBC == (st.year * -1) + 1, msg);\n        }\n\n        foreach (st; [testSysTimesAD[0], testSysTimesAD[$/2], testSysTimesAD[$-1]])\n            assertThrown!DateTimeException(st.yearBC, format(\"SysTime: %s\", st));\n\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        st.year = 12;\n        assert(st.year == 12);\n        static assert(!__traits(compiles, cst.year = 12));\n        static assert(!__traits(compiles, ist.year = 12));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.yearBC;\n        }\n    }\n\n\n    /++\n        Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.\n\n        Params:\n            year = The year B.C. to set this $(LREF SysTime)'s year to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if a non-positive value\n            is given.\n     +/\n    @property void yearBC(int year) @safe scope\n    {\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        auto date = Date(cast(int) days);\n        date.yearBC = year;\n\n        immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(date.dayOfGregorianCal - 1);\n        adjTime = newDaysHNSecs + hnsecs;\n    }\n\n    @safe unittest\n    {\n        auto st = SysTime(DateTime(2010, 1, 1, 7, 30, 0));\n        st.yearBC = 1;\n        assert(st == SysTime(DateTime(0, 1, 1, 7, 30, 0)));\n\n        st.yearBC = 10;\n        assert(st == SysTime(DateTime(-9, 1, 1, 7, 30, 0)));\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n        static void test(SysTime st, int year, SysTime expected)\n        {\n            st.yearBC = year;\n            assert(st == expected, format(\"SysTime: %s\", st));\n        }\n\n        foreach (st; chain(testSysTimesBC, testSysTimesAD))\n        {\n            auto dt = cast(DateTime) st;\n\n            foreach (year; testYearsBC)\n            {\n                auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second),\n                                 st.fracSecs,\n                                 st.timezone);\n                test(st, (year * -1) + 1, e);\n            }\n        }\n\n        foreach (st; [testSysTimesBC[0], testSysTimesBC[$ - 1], testSysTimesAD[0], testSysTimesAD[$ - 1]])\n        {\n            foreach (year; testYearsBC)\n                assertThrown!DateTimeException(st.yearBC = year);\n        }\n\n        foreach (fs; testFracSecs)\n        {\n            foreach (tz; testTZs)\n            {\n                foreach (tod; testTODs)\n                {\n                    test(SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz), 2001,\n                         SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz));\n                    test(SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz), 2000,\n                         SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz));\n                }\n\n                foreach (tod; testTODsThrown)\n                {\n                    auto st = SysTime(DateTime(Date(-2000, 2, 29), tod), fs, tz);\n                    assertThrown!DateTimeException(st.year = -1999);\n                }\n            }\n        }\n\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        st.yearBC = 12;\n        assert(st.yearBC == 12);\n        static assert(!__traits(compiles, cst.yearBC = 12));\n        static assert(!__traits(compiles, ist.yearBC = 12));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.yearBC = 42;\n        }\n    }\n\n\n    /++\n        Month of a Gregorian Year.\n     +/\n    @property Month month() @safe const nothrow scope\n    {\n        return (cast(Date) this).month;\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).month == 7);\n        assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).month == 10);\n        assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).month == 4);\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        static void test(SysTime sysTime, Month expected)\n        {\n            assert(sysTime.month == expected, format(\"Value given: %s\", sysTime));\n        }\n\n        test(SysTime(0, UTC()), Month.jan);\n        test(SysTime(1, UTC()), Month.jan);\n        test(SysTime(-1, UTC()), Month.dec);\n\n        foreach (year; chain(testYearsBC, testYearsAD))\n        {\n            foreach (md; testMonthDays)\n            {\n                foreach (tod; testTODs)\n                {\n                    auto dt = DateTime(Date(year, md.month, md.day), tod);\n                    foreach (fs; testFracSecs)\n                    {\n                        foreach (tz; testTZs)\n                            test(SysTime(dt, fs, tz), md.month);\n                    }\n                }\n            }\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.month == 7);\n        assert(ist.month == 7);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.month;\n        }\n    }\n\n\n    /++\n        Month of a Gregorian Year.\n\n        Params:\n            month = The month to set this $(LREF SysTime)'s month to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given month is\n            not a valid month.\n     +/\n    @property void month(Month month) @safe scope\n    {\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        auto date = Date(cast(int) days);\n        date.month = month;\n\n        immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(date.dayOfGregorianCal - 1);\n        adjTime = newDaysHNSecs + hnsecs;\n    }\n\n    @safe unittest\n    {\n        import std.algorithm.iteration : filter;\n        import std.range : chain;\n\n        static void test(SysTime st, Month month, SysTime expected)\n        {\n            st.month = cast(Month) month;\n            assert(st == expected);\n        }\n\n        foreach (st; chain(testSysTimesBC, testSysTimesAD))\n        {\n            auto dt = cast(DateTime) st;\n\n            foreach (md; testMonthDays)\n            {\n                if (st.day > maxDay(dt.year, md.month))\n                    continue;\n                auto e = SysTime(DateTime(dt.year, md.month, dt.day, dt.hour, dt.minute, dt.second),\n                                 st.fracSecs,\n                                 st.timezone);\n                test(st, md.month, e);\n            }\n        }\n\n        foreach (fs; testFracSecs)\n        {\n            foreach (tz; testTZs)\n            {\n                foreach (tod; testTODs)\n                {\n                    foreach (year; filter!((a){return yearIsLeapYear(a);}) (chain(testYearsBC, testYearsAD)))\n                    {\n                        test(SysTime(DateTime(Date(year, 1, 29), tod), fs, tz),\n                             Month.feb,\n                             SysTime(DateTime(Date(year, 2, 29), tod), fs, tz));\n                    }\n\n                    foreach (year; chain(testYearsBC, testYearsAD))\n                    {\n                        test(SysTime(DateTime(Date(year, 1, 28), tod), fs, tz),\n                             Month.feb,\n                             SysTime(DateTime(Date(year, 2, 28), tod), fs, tz));\n                        test(SysTime(DateTime(Date(year, 7, 30), tod), fs, tz),\n                             Month.jun,\n                             SysTime(DateTime(Date(year, 6, 30), tod), fs, tz));\n                    }\n                }\n            }\n        }\n\n        foreach (fs; [testFracSecs[0], testFracSecs[$-1]])\n        {\n            foreach (tz; testTZs)\n            {\n                foreach (tod; testTODsThrown)\n                {\n                    foreach (year; [testYearsBC[$-3], testYearsBC[$-2],\n                                    testYearsBC[$-2], testYearsAD[0],\n                                    testYearsAD[$-2], testYearsAD[$-1]])\n                    {\n                        auto day = yearIsLeapYear(year) ? 30 : 29;\n                        auto st1 = SysTime(DateTime(Date(year, 1, day), tod), fs, tz);\n                        assertThrown!DateTimeException(st1.month = Month.feb);\n\n                        auto st2 = SysTime(DateTime(Date(year, 7, 31), tod), fs, tz);\n                        assertThrown!DateTimeException(st2.month = Month.jun);\n                    }\n                }\n            }\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.month = Month.dec));\n        static assert(!__traits(compiles, ist.month = Month.dec));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.month = Month.dec;\n        }\n    }\n\n    /++\n        Day of a Gregorian Month.\n     +/\n    @property ubyte day() @safe const nothrow scope\n    {\n        return (cast(Date) this).day;\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).day == 6);\n        assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).day == 4);\n        assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).day == 5);\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        static void test(SysTime sysTime, int expected)\n        {\n            assert(sysTime.day == expected, format(\"Value given: %s\", sysTime));\n        }\n\n        test(SysTime(0, UTC()), 1);\n        test(SysTime(1, UTC()), 1);\n        test(SysTime(-1, UTC()), 31);\n\n        foreach (year; chain(testYearsBC, testYearsAD))\n        {\n            foreach (md; testMonthDays)\n            {\n                foreach (tod; testTODs)\n                {\n                    auto dt = DateTime(Date(year, md.month, md.day), tod);\n\n                    foreach (tz; testTZs)\n                    {\n                        foreach (fs; testFracSecs)\n                            test(SysTime(dt, fs, tz), md.day);\n                    }\n                }\n            }\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n         assert(cst.day == 6);\n        assert(ist.day == 6);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.day;\n        }\n    }\n\n\n    /++\n        Day of a Gregorian Month.\n\n        Params:\n            day = The day of the month to set this $(LREF SysTime)'s day to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given day is not\n            a valid day of the current month.\n     +/\n    @property void day(int day) @safe scope\n    {\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        auto date = Date(cast(int) days);\n        date.day = day;\n\n        immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(date.dayOfGregorianCal - 1);\n        adjTime = newDaysHNSecs + hnsecs;\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n        import std.traits : EnumMembers;\n\n        foreach (day; chain(testDays))\n        {\n            foreach (st; chain(testSysTimesBC, testSysTimesAD))\n            {\n                auto dt = cast(DateTime) st;\n\n                if (day > maxDay(dt.year, dt.month))\n                    continue;\n                auto expected = SysTime(DateTime(dt.year, dt.month, day, dt.hour, dt.minute, dt.second),\n                                        st.fracSecs,\n                                        st.timezone);\n                st.day = day;\n                assert(st == expected, format(\"[%s] [%s]\", st, expected));\n            }\n        }\n\n        foreach (tz; testTZs)\n        {\n            foreach (tod; testTODs)\n            {\n                foreach (fs; testFracSecs)\n                {\n                    foreach (year; chain(testYearsBC, testYearsAD))\n                    {\n                        foreach (month; EnumMembers!Month)\n                        {\n                            auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz);\n                            immutable max = maxDay(year, month);\n                            auto expected = SysTime(DateTime(Date(year, month, max), tod), fs, tz);\n\n                            st.day = max;\n                            assert(st == expected, format(\"[%s] [%s]\", st, expected));\n                        }\n                    }\n                }\n            }\n        }\n\n        foreach (tz; testTZs)\n        {\n            foreach (tod; testTODsThrown)\n            {\n                foreach (fs; [testFracSecs[0], testFracSecs[$-1]])\n                {\n                    foreach (year; [testYearsBC[$-3], testYearsBC[$-2],\n                                    testYearsBC[$-2], testYearsAD[0],\n                                    testYearsAD[$-2], testYearsAD[$-1]])\n                    {\n                        foreach (month; EnumMembers!Month)\n                        {\n                            auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz);\n                            immutable max = maxDay(year, month);\n\n                            assertThrown!DateTimeException(st.day = max + 1);\n                        }\n                    }\n                }\n            }\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.day = 27));\n        static assert(!__traits(compiles, ist.day = 27));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.day = 12;\n        }\n    }\n\n\n    /++\n        Hours past midnight.\n     +/\n    @property ubyte hour() @safe const nothrow scope\n    {\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        return cast(ubyte) getUnitsFromHNSecs!\"hours\"(hnsecs);\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        static void test(SysTime sysTime, int expected)\n        {\n            assert(sysTime.hour == expected, format(\"Value given: %s\", sysTime));\n        }\n\n        test(SysTime(0, UTC()), 0);\n        test(SysTime(1, UTC()), 0);\n        test(SysTime(-1, UTC()), 23);\n\n        foreach (tz; testTZs)\n        {\n            foreach (year; chain(testYearsBC, testYearsAD))\n            {\n                foreach (md; testMonthDays)\n                {\n                    foreach (hour; testHours)\n                    {\n                        foreach (minute; testMinSecs)\n                        {\n                            foreach (second; testMinSecs)\n                            {\n                                auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second));\n                                foreach (fs; testFracSecs)\n                                    test(SysTime(dt, fs, tz), hour);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.hour == 12);\n        assert(ist.hour == 12);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.hour;\n        }\n    }\n\n\n    /++\n        Hours past midnight.\n\n        Params:\n            hour = The hours to set this $(LREF SysTime)'s hour to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given hour are\n            not a valid hour of the day.\n     +/\n    @property void hour(int hour) @safe scope\n    {\n        enforceValid!\"hours\"(hour);\n\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs);\n        immutable daysHNSecs = convert!(\"days\", \"hnsecs\")(days);\n        immutable negative = hnsecs < 0;\n\n        if (negative)\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n\n        hnsecs = removeUnitsFromHNSecs!\"hours\"(hnsecs);\n        hnsecs += convert!(\"hours\", \"hnsecs\")(hour);\n\n        if (negative)\n            hnsecs -= convert!(\"hours\", \"hnsecs\")(24);\n\n        adjTime = daysHNSecs + hnsecs;\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        foreach (hour; chain(testHours))\n        {\n            foreach (st; chain(testSysTimesBC, testSysTimesAD))\n            {\n                auto dt = cast(DateTime) st;\n                auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, hour, dt.minute, dt.second),\n                                        st.fracSecs,\n                                        st.timezone);\n                st.hour = hour;\n                assert(st == expected, format(\"[%s] [%s]\", st, expected));\n            }\n        }\n\n        auto st = testSysTimesAD[0];\n        assertThrown!DateTimeException(st.hour = -1);\n        assertThrown!DateTimeException(st.hour = 60);\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.hour = 27));\n        static assert(!__traits(compiles, ist.hour = 27));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.hour = 12;\n        }\n    }\n\n\n    /++\n        Minutes past the current hour.\n     +/\n    @property ubyte minute() @safe const nothrow scope\n    {\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        hnsecs = removeUnitsFromHNSecs!\"hours\"(hnsecs);\n\n        return cast(ubyte) getUnitsFromHNSecs!\"minutes\"(hnsecs);\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        static void test(SysTime sysTime, int expected)\n        {\n            assert(sysTime.minute == expected, format(\"Value given: %s\", sysTime));\n        }\n\n        test(SysTime(0, UTC()), 0);\n        test(SysTime(1, UTC()), 0);\n        test(SysTime(-1, UTC()), 59);\n\n        foreach (tz; testTZs)\n        {\n            foreach (year; chain(testYearsBC, testYearsAD))\n            {\n                foreach (md; testMonthDays)\n                {\n                    foreach (hour; testHours)\n                    {\n                        foreach (minute; testMinSecs)\n                        {\n                            foreach (second; testMinSecs)\n                            {\n                                auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second));\n                                foreach (fs; testFracSecs)\n                                    test(SysTime(dt, fs, tz), minute);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.minute == 30);\n        assert(ist.minute == 30);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.minute;\n        }\n    }\n\n\n    /++\n        Minutes past the current hour.\n\n        Params:\n            minute = The minute to set this $(LREF SysTime)'s minute to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given minute are\n            not a valid minute of an hour.\n     +/\n    @property void minute(int minute) @safe scope\n    {\n        enforceValid!\"minutes\"(minute);\n\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs);\n        immutable daysHNSecs = convert!(\"days\", \"hnsecs\")(days);\n        immutable negative = hnsecs < 0;\n\n        if (negative)\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n\n        immutable hour = splitUnitsFromHNSecs!\"hours\"(hnsecs);\n        hnsecs = removeUnitsFromHNSecs!\"minutes\"(hnsecs);\n\n        hnsecs += convert!(\"hours\", \"hnsecs\")(hour);\n        hnsecs += convert!(\"minutes\", \"hnsecs\")(minute);\n\n        if (negative)\n            hnsecs -= convert!(\"hours\", \"hnsecs\")(24);\n\n        adjTime = daysHNSecs + hnsecs;\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        foreach (minute; testMinSecs)\n        {\n            foreach (st; chain(testSysTimesBC, testSysTimesAD))\n            {\n                auto dt = cast(DateTime) st;\n                auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, minute, dt.second),\n                                        st.fracSecs,\n                                        st.timezone);\n                st.minute = minute;\n                assert(st == expected, format(\"[%s] [%s]\", st, expected));\n            }\n        }\n\n        auto st = testSysTimesAD[0];\n        assertThrown!DateTimeException(st.minute = -1);\n        assertThrown!DateTimeException(st.minute = 60);\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.minute = 27));\n        static assert(!__traits(compiles, ist.minute = 27));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.minute = 12;\n        }\n    }\n\n\n    /++\n        Seconds past the current minute.\n     +/\n    @property ubyte second() @safe const nothrow scope\n    {\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        hnsecs = removeUnitsFromHNSecs!\"hours\"(hnsecs);\n        hnsecs = removeUnitsFromHNSecs!\"minutes\"(hnsecs);\n\n        return cast(ubyte) getUnitsFromHNSecs!\"seconds\"(hnsecs);\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        static void test(SysTime sysTime, int expected)\n        {\n            assert(sysTime.second == expected, format(\"Value given: %s\", sysTime));\n        }\n\n        test(SysTime(0, UTC()), 0);\n        test(SysTime(1, UTC()), 0);\n        test(SysTime(-1, UTC()), 59);\n\n        foreach (tz; testTZs)\n        {\n            foreach (year; chain(testYearsBC, testYearsAD))\n            {\n                foreach (md; testMonthDays)\n                {\n                    foreach (hour; testHours)\n                    {\n                        foreach (minute; testMinSecs)\n                        {\n                            foreach (second; testMinSecs)\n                            {\n                                auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second));\n                                foreach (fs; testFracSecs)\n                                    test(SysTime(dt, fs, tz), second);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.second == 33);\n        assert(ist.second == 33);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.second;\n        }\n    }\n\n\n    /++\n        Seconds past the current minute.\n\n        Params:\n            second = The second to set this $(LREF SysTime)'s second to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given second are\n            not a valid second of a minute.\n     +/\n    @property void second(int second) @safe scope\n    {\n        enforceValid!\"seconds\"(second);\n\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs);\n        immutable daysHNSecs = convert!(\"days\", \"hnsecs\")(days);\n        immutable negative = hnsecs < 0;\n\n        if (negative)\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n\n        immutable hour = splitUnitsFromHNSecs!\"hours\"(hnsecs);\n        immutable minute = splitUnitsFromHNSecs!\"minutes\"(hnsecs);\n        hnsecs = removeUnitsFromHNSecs!\"seconds\"(hnsecs);\n\n        hnsecs += convert!(\"hours\", \"hnsecs\")(hour);\n        hnsecs += convert!(\"minutes\", \"hnsecs\")(minute);\n        hnsecs += convert!(\"seconds\", \"hnsecs\")(second);\n\n        if (negative)\n            hnsecs -= convert!(\"hours\", \"hnsecs\")(24);\n\n        adjTime = daysHNSecs + hnsecs;\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n\n        foreach (second; testMinSecs)\n        {\n            foreach (st; chain(testSysTimesBC, testSysTimesAD))\n            {\n                auto dt = cast(DateTime) st;\n                auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, second),\n                                        st.fracSecs,\n                                        st.timezone);\n                st.second = second;\n                assert(st == expected, format(\"[%s] [%s]\", st, expected));\n            }\n        }\n\n        auto st = testSysTimesAD[0];\n        assertThrown!DateTimeException(st.second = -1);\n        assertThrown!DateTimeException(st.second = 60);\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.seconds = 27));\n        static assert(!__traits(compiles, ist.seconds = 27));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.second = 12;\n        }\n    }\n\n\n    /++\n        Fractional seconds past the second (i.e. the portion of a\n        $(LREF SysTime) which is less than a second).\n     +/\n    @property Duration fracSecs() @safe const nothrow scope\n    {\n        auto hnsecs = removeUnitsFromHNSecs!\"days\"(adjTime);\n\n        if (hnsecs < 0)\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n\n        return dur!\"hnsecs\"(removeUnitsFromHNSecs!\"seconds\"(hnsecs));\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : msecs, usecs, hnsecs, nsecs;\n        import std.datetime.date : DateTime;\n\n        auto dt = DateTime(1982, 4, 1, 20, 59, 22);\n        assert(SysTime(dt, msecs(213)).fracSecs == msecs(213));\n        assert(SysTime(dt, usecs(5202)).fracSecs == usecs(5202));\n        assert(SysTime(dt, hnsecs(1234567)).fracSecs == hnsecs(1234567));\n\n        // SysTime and Duration both have a precision of hnsecs (100 ns),\n        // so nsecs are going to be truncated.\n        assert(SysTime(dt, nsecs(123456789)).fracSecs == nsecs(123456700));\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n        import core.time;\n\n        assert(SysTime(0, UTC()).fracSecs == Duration.zero);\n        assert(SysTime(1, UTC()).fracSecs == hnsecs(1));\n        assert(SysTime(-1, UTC()).fracSecs == hnsecs(9_999_999));\n\n        foreach (tz; testTZs)\n        {\n            foreach (year; chain(testYearsBC, testYearsAD))\n            {\n                foreach (md; testMonthDays)\n                {\n                    foreach (hour; testHours)\n                    {\n                        foreach (minute; testMinSecs)\n                        {\n                            foreach (second; testMinSecs)\n                            {\n                                auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second));\n                                foreach (fs; testFracSecs)\n                                    assert(SysTime(dt, fs, tz).fracSecs == fs);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.fracSecs == Duration.zero);\n        assert(ist.fracSecs == Duration.zero);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.fracSecs;\n        }\n    }\n\n\n    /++\n        Fractional seconds past the second (i.e. the portion of a\n        $(LREF SysTime) which is less than a second).\n\n        Params:\n            fracSecs = The duration to set this $(LREF SysTime)'s fractional\n                       seconds to.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given duration\n            is negative or if it's greater than or equal to one second.\n     +/\n    @property void fracSecs(Duration fracSecs) @safe scope\n    {\n        enforce(fracSecs >= Duration.zero, new DateTimeException(\"A SysTime cannot have negative fractional seconds.\"));\n        enforce(fracSecs < seconds(1), new DateTimeException(\"Fractional seconds must be less than one second.\"));\n\n        auto oldHNSecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(oldHNSecs);\n        immutable daysHNSecs = convert!(\"days\", \"hnsecs\")(days);\n        immutable negative = oldHNSecs < 0;\n\n        if (negative)\n            oldHNSecs += convert!(\"hours\", \"hnsecs\")(24);\n\n        immutable seconds = splitUnitsFromHNSecs!\"seconds\"(oldHNSecs);\n        immutable secondsHNSecs = convert!(\"seconds\", \"hnsecs\")(seconds);\n        auto newHNSecs = fracSecs.total!\"hnsecs\" + secondsHNSecs;\n\n        if (negative)\n            newHNSecs -= convert!(\"hours\", \"hnsecs\")(24);\n\n        adjTime = daysHNSecs + newHNSecs;\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : Duration, msecs, hnsecs, nsecs;\n        import std.datetime.date : DateTime;\n\n        auto st = SysTime(DateTime(1982, 4, 1, 20, 59, 22));\n        assert(st.fracSecs == Duration.zero);\n\n        st.fracSecs = msecs(213);\n        assert(st.fracSecs == msecs(213));\n\n        st.fracSecs = hnsecs(1234567);\n        assert(st.fracSecs == hnsecs(1234567));\n\n        // SysTime has a precision of hnsecs (100 ns), so nsecs are\n        // going to be truncated.\n        st.fracSecs = nsecs(123456789);\n        assert(st.fracSecs == hnsecs(1234567));\n    }\n\n    @safe unittest\n    {\n        import std.range : chain;\n        import core.time;\n\n        foreach (fracSec; testFracSecs)\n        {\n            foreach (st; chain(testSysTimesBC, testSysTimesAD))\n            {\n                auto dt = cast(DateTime) st;\n                auto expected = SysTime(dt, fracSec, st.timezone);\n                st.fracSecs = fracSec;\n                assert(st == expected, format(\"[%s] [%s]\", st, expected));\n            }\n        }\n\n        auto st = testSysTimesAD[0];\n        assertThrown!DateTimeException(st.fracSecs = hnsecs(-1));\n        assertThrown!DateTimeException(st.fracSecs = seconds(1));\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.fracSecs = msecs(7)));\n        static assert(!__traits(compiles, ist.fracSecs = msecs(7)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.fracSecs = Duration.zero;\n        }\n    }\n\n\n    /++\n        The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the\n        internal representation of $(LREF SysTime).\n     +/\n    @property long stdTime() @safe const pure nothrow scope\n    {\n        return _stdTime;\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        assert(SysTime(0).stdTime == 0);\n        assert(SysTime(1).stdTime == 1);\n        assert(SysTime(-1).stdTime == -1);\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC()).stdTime == 330_000_502L);\n        assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC()).stdTime == 621_355_968_000_000_000L);\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.stdTime > 0);\n        assert(ist.stdTime > 0);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.stdTime;\n        }\n    }\n\n\n    /++\n        The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the\n        internal representation of $(LREF SysTime).\n\n        Params:\n            stdTime = The number of hnsecs since January 1st, 1 A.D. UTC.\n     +/\n    @property void stdTime(long stdTime) @safe pure nothrow scope\n    {\n        _stdTime = stdTime;\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        static void test(long stdTime, SysTime expected, size_t line = __LINE__)\n        {\n            auto st = SysTime(0, UTC());\n            st.stdTime = stdTime;\n            assert(st == expected);\n        }\n\n        test(0, SysTime(Date(1, 1, 1), UTC()));\n        test(1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()));\n        test(-1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()));\n        test(330_000_502L, SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC()));\n        test(621_355_968_000_000_000L, SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC()));\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.stdTime = 27));\n        static assert(!__traits(compiles, ist.stdTime = 27));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.stdTime = 42;\n        }\n    }\n\n\n    /++\n        The current time zone of this $(LREF SysTime). Its internal time is\n        always kept in UTC, so there are no conversion issues between time zones\n        due to DST. Functions which return all or part of the time - such as\n        hours - adjust the time to this $(LREF SysTime)'s time zone before\n        returning.\n      +/\n    @property immutable(TimeZone) timezone() @safe const pure nothrow scope\n    {\n        return _timezone;\n    }\n\n    @safe unittest\n    {\n        assert(SysTime.init.timezone is InitTimeZone());\n        assert(SysTime(DateTime.init, UTC()).timezone is UTC());\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.timezone;\n        }\n    }\n\n\n    /++\n        The current time zone of this $(LREF SysTime). It's internal time is\n        always kept in UTC, so there are no conversion issues between time zones\n        due to DST. Functions which return all or part of the time - such as\n        hours - adjust the time to this $(LREF SysTime)'s time zone before\n        returning.\n\n        Params:\n            timezone = The $(REF _TimeZone,std,datetime,_timezone) to set this\n                       $(LREF SysTime)'s time zone to.\n      +/\n    @property void timezone(immutable TimeZone timezone) @safe pure nothrow scope\n    {\n        if (timezone is null)\n            _timezone = LocalTime();\n        else\n            _timezone = timezone;\n    }\n\n    @safe unittest\n    {\n        SysTime st;\n        st.timezone = null;\n        assert(st.timezone is LocalTime());\n        st.timezone = UTC();\n        assert(st.timezone is UTC());\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.timezone = UTC();\n        }\n    }\n\n\n    /++\n        Returns whether DST is in effect for this $(LREF SysTime).\n      +/\n    @property bool dstInEffect() @safe const nothrow scope\n    {\n        return _timezone.dstInEffect(_stdTime);\n    }\n\n    // This function's full unit testing is done in the time zone classes, but\n    // this verifies that SysTime.init works correctly, since historically, it\n    // has segfaulted due to a null _timezone.\n    @safe unittest\n    {\n        assert(!SysTime.init.dstInEffect);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.dstInEffect;\n        }\n    }\n\n\n    /++\n        Returns what the offset from UTC is for this $(LREF SysTime).\n        It includes the DST offset in effect at that time (if any).\n      +/\n    @property Duration utcOffset() @safe const nothrow scope\n    {\n        return _timezone.utcOffsetAt(_stdTime);\n    }\n\n    // This function's full unit testing is done in the time zone classes, but\n    // this verifies that SysTime.init works correctly, since historically, it\n    // has segfaulted due to a null _timezone.\n    @safe unittest\n    {\n        assert(SysTime.init.utcOffset == Duration.zero);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.utcOffset;\n        }\n    }\n\n\n    /++\n        Returns a $(LREF SysTime) with the same std time as this one, but with\n        $(REF LocalTime,std,datetime,timezone) as its time zone.\n      +/\n    SysTime toLocalTime() @safe const pure nothrow scope\n    {\n        return SysTime(_stdTime, LocalTime());\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        {\n            auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27));\n            assert(sysTime == sysTime.toLocalTime());\n            assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime);\n            assert(sysTime.toLocalTime().timezone is LocalTime());\n            assert(sysTime.toLocalTime().timezone is sysTime.timezone);\n            assert(sysTime.toLocalTime().timezone !is UTC());\n        }\n\n        {\n            auto stz = new immutable SimpleTimeZone(dur!\"minutes\"(-3 * 60));\n            auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27), stz);\n            assert(sysTime == sysTime.toLocalTime());\n            assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime);\n            assert(sysTime.toLocalTime().timezone is LocalTime());\n            assert(sysTime.toLocalTime().timezone !is UTC());\n            assert(sysTime.toLocalTime().timezone !is stz);\n        }\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.toLocalTime();\n        }\n    }\n\n\n    /++\n        Returns a $(LREF SysTime) with the same std time as this one, but with\n        `UTC` as its time zone.\n      +/\n    SysTime toUTC() @safe const pure nothrow scope\n    {\n        return SysTime(_stdTime, UTC());\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27));\n        assert(sysTime == sysTime.toUTC());\n        assert(sysTime._stdTime == sysTime.toUTC()._stdTime);\n        assert(sysTime.toUTC().timezone is UTC());\n        assert(sysTime.toUTC().timezone !is LocalTime());\n        assert(sysTime.toUTC().timezone !is sysTime.timezone);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.toUTC();\n        }\n    }\n\n\n    /++\n        Returns a $(LREF SysTime) with the same std time as this one, but with\n        given time zone as its time zone.\n      +/\n    SysTime toOtherTZ(immutable TimeZone tz) @safe const pure nothrow scope\n    {\n        if (tz is null)\n            return SysTime(_stdTime, LocalTime());\n        else\n            return SysTime(_stdTime, tz);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        auto stz = new immutable SimpleTimeZone(dur!\"minutes\"(11 * 60));\n        auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27));\n        assert(sysTime == sysTime.toOtherTZ(stz));\n        assert(sysTime._stdTime == sysTime.toOtherTZ(stz)._stdTime);\n        assert(sysTime.toOtherTZ(stz).timezone is stz);\n        assert(sysTime.toOtherTZ(stz).timezone !is LocalTime());\n        assert(sysTime.toOtherTZ(stz).timezone !is UTC());\n        assert(sysTime.toOtherTZ(null).timezone is LocalTime());\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.toOtherTZ(null);\n        }\n    }\n\n\n    /++\n        Converts this $(LREF SysTime) to unix time (i.e. seconds from midnight,\n        January 1st, 1970 in UTC).\n\n        The C standard does not specify the representation of time_t, so it is\n        implementation defined. On POSIX systems, unix time is equivalent to\n        time_t, but that's not necessarily true on other systems (e.g. it is\n        not true for the Digital Mars C runtime). So, be careful when using unix\n        time with C functions on non-POSIX systems.\n\n        By default, the return type is time_t (which is normally an alias for\n        int on 32-bit systems and long on 64-bit systems), but if a different\n        size is required than either int or long can be passed as a template\n        argument to get the desired size.\n\n        If the return type is int, and the result can't fit in an int, then the\n        closest value that can be held in 32 bits will be used (so `int.max`\n        if it goes over and `int.min` if it goes under). However, no attempt\n        is made to deal with integer overflow if the return type is long.\n\n        Params:\n            T = The return type (int or long). It defaults to time_t, which is\n                normally 32 bits on a 32-bit system and 64 bits on a 64-bit\n                system.\n\n        Returns:\n            A signed integer representing the unix time which is equivalent to\n            this SysTime.\n      +/\n    T toUnixTime(T = time_t)() @safe const pure nothrow scope\n        if (is(T == int) || is(T == long))\n    {\n        return stdTimeToUnixTime!T(_stdTime);\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : hours;\n        import std.datetime.date : DateTime;\n        import std.datetime.timezone : SimpleTimeZone, UTC;\n\n        assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0);\n\n        auto pst = new immutable SimpleTimeZone(hours(-8));\n        assert(SysTime(DateTime(1970, 1, 1), pst).toUnixTime() == 28800);\n\n        auto utc = SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC());\n        assert(utc.toUnixTime() == 1_198_311_285);\n\n        auto ca = SysTime(DateTime(2007, 12, 22, 8, 14, 45), pst);\n        assert(ca.toUnixTime() == 1_198_340_085);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.toUnixTime();\n        }\n    }\n\n    @safe unittest\n    {\n        import std.meta : AliasSeq;\n        import core.time;\n        assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0);\n        static foreach (units; [\"hnsecs\", \"usecs\", \"msecs\"])\n            assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), dur!units(1), UTC()).toUnixTime() == 0);\n        assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toUnixTime() == 1);\n        assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toUnixTime() == 0);\n        assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toUnixTime() == 0);\n        assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toUnixTime() == 0);\n        assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toUnixTime() == -1);\n    }\n\n\n    /++\n        Converts from unix time (i.e. seconds from midnight, January 1st, 1970\n        in UTC) to a $(LREF SysTime).\n\n        The C standard does not specify the representation of time_t, so it is\n        implementation defined. On POSIX systems, unix time is equivalent to\n        time_t, but that's not necessarily true on other systems (e.g. it is\n        not true for the Digital Mars C runtime). So, be careful when using unix\n        time with C functions on non-POSIX systems.\n\n        Params:\n            unixTime = Seconds from midnight, January 1st, 1970 in UTC.\n            tz = The time zone for the SysTime that's returned.\n      +/\n    static SysTime fromUnixTime(long unixTime, immutable TimeZone tz = LocalTime()) @safe pure nothrow\n    {\n        return SysTime(unixTimeToStdTime(unixTime), tz);\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : hours;\n        import std.datetime.date : DateTime;\n        import std.datetime.timezone : SimpleTimeZone, UTC;\n\n        assert(SysTime.fromUnixTime(0) ==\n               SysTime(DateTime(1970, 1, 1), UTC()));\n\n        auto pst = new immutable SimpleTimeZone(hours(-8));\n        assert(SysTime.fromUnixTime(28800) ==\n               SysTime(DateTime(1970, 1, 1), pst));\n\n        auto st1 = SysTime.fromUnixTime(1_198_311_285, UTC());\n        assert(st1 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC()));\n        assert(st1.timezone is UTC());\n        assert(st1 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst));\n\n        auto st2 = SysTime.fromUnixTime(1_198_311_285, pst);\n        assert(st2 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC()));\n        assert(st2.timezone is pst);\n        assert(st2 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst));\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        assert(SysTime.fromUnixTime(0) == SysTime(DateTime(1970, 1, 1), UTC()));\n        assert(SysTime.fromUnixTime(1) == SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()));\n        assert(SysTime.fromUnixTime(-1) == SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()));\n\n        auto st = SysTime.fromUnixTime(0);\n        auto dt = cast(DateTime) st;\n        assert(dt <= DateTime(1970, 2, 1) && dt >= DateTime(1969, 12, 31));\n        assert(st.timezone is LocalTime());\n\n        auto aest = new immutable SimpleTimeZone(hours(10));\n        assert(SysTime.fromUnixTime(-36000) == SysTime(DateTime(1970, 1, 1), aest));\n    }\n\n\n    /++\n        Returns a `timeval` which represents this $(LREF SysTime).\n\n        Note that like all conversions in std.datetime, this is a truncating\n        conversion.\n\n        If `timeval.tv_sec` is int, and the result can't fit in an int, then\n        the closest value that can be held in 32 bits will be used for\n        `tv_sec`. (so `int.max` if it goes over and `int.min` if it\n        goes under).\n      +/\n    timeval toTimeVal() @safe const pure nothrow scope\n    {\n        immutable tv_sec = toUnixTime!(typeof(timeval.tv_sec))();\n        immutable fracHNSecs = removeUnitsFromHNSecs!\"seconds\"(_stdTime - 621_355_968_000_000_000L);\n        immutable tv_usec = cast(typeof(timeval.tv_usec))convert!(\"hnsecs\", \"usecs\")(fracHNSecs);\n        return timeval(tv_sec, tv_usec);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeVal() == timeval(0, 0));\n        assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeVal() == timeval(0, 0));\n        assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeVal() == timeval(0, 1));\n        assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeVal() == timeval(0, 7));\n\n        assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeVal() == timeval(1, 0));\n        assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeVal() == timeval(1, 0));\n        assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeVal() == timeval(1, 1));\n        assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeVal() == timeval(1, 7));\n\n        assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeVal() == timeval(0, 0));\n        assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeVal() == timeval(0, -1));\n\n        assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeVal() == timeval(0, -1));\n        assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeVal() == timeval(0, -999_001));\n        assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeVal() == timeval(0, -1000));\n        assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeVal() == timeval(-1, 0));\n        assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeVal() == timeval(-1, -999_983));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.toTimeVal();\n        }\n    }\n\n\n    version (StdDdoc)\n    {\n        private struct timespec {}\n        /++\n            Returns a `timespec` which represents this $(LREF SysTime).\n\n            $(BLUE This function is Posix-Only.)\n          +/\n        timespec toTimeSpec() @safe const pure nothrow scope;\n    }\n    else version (Posix)\n    {\n        timespec toTimeSpec() @safe const pure nothrow scope\n        {\n            immutable tv_sec = toUnixTime!(typeof(timespec.tv_sec))();\n            immutable fracHNSecs = removeUnitsFromHNSecs!\"seconds\"(_stdTime - 621_355_968_000_000_000L);\n            immutable tv_nsec = cast(typeof(timespec.tv_nsec))convert!(\"hnsecs\", \"nsecs\")(fracHNSecs);\n            return timespec(tv_sec, tv_nsec);\n        }\n\n        @safe unittest\n        {\n            import core.time;\n            assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeSpec() == timespec(0, 0));\n            assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(0, 900));\n            assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(0, 1000));\n            assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeSpec() == timespec(0, 7000));\n\n            assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeSpec() == timespec(1, 0));\n            assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(1, 900));\n            assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(1, 1000));\n            assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeSpec() == timespec(1, 7000));\n\n            assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeSpec() ==\n                   timespec(0, -100));\n            assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeSpec() ==\n                   timespec(0, -1000));\n\n            assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeSpec() ==\n                   timespec(0, -1_000));\n            assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeSpec() ==\n                   timespec(0, -999_001_000));\n            assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeSpec() ==\n                   timespec(0, -1_000_000));\n            assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeSpec() ==\n                   timespec(-1, 0));\n            assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeSpec() ==\n                   timespec(-1, -999_983_000));\n\n            static void testScope(scope ref SysTime st) @safe\n            {\n                auto result = st.toTimeSpec();\n            }\n        }\n    }\n\n    /++\n        Returns a `tm` which represents this $(LREF SysTime).\n      +/\n    tm toTM() @safe const nothrow scope\n    {\n        auto dateTime = cast(DateTime) this;\n        tm timeInfo;\n\n        timeInfo.tm_sec = dateTime.second;\n        timeInfo.tm_min = dateTime.minute;\n        timeInfo.tm_hour = dateTime.hour;\n        timeInfo.tm_mday = dateTime.day;\n        timeInfo.tm_mon = dateTime.month - 1;\n        timeInfo.tm_year = dateTime.year - 1900;\n        timeInfo.tm_wday = dateTime.dayOfWeek;\n        timeInfo.tm_yday = dateTime.dayOfYear - 1;\n        timeInfo.tm_isdst = _timezone.dstInEffect(_stdTime);\n\n        version (Posix)\n        {\n            import std.utf : toUTFz;\n            timeInfo.tm_gmtoff = cast(int) convert!(\"hnsecs\", \"seconds\")(adjTime - _stdTime);\n            auto zone = timeInfo.tm_isdst ? _timezone.dstName : _timezone.stdName;\n            timeInfo.tm_zone = zone.toUTFz!(char*)();\n        }\n\n        return timeInfo;\n    }\n\n    @system unittest\n    {\n        import std.conv : to;\n        import core.time;\n\n        version (Posix)\n        {\n            import std.datetime.timezone : clearTZEnvVar, setTZEnvVar;\n            setTZEnvVar(\"America/Los_Angeles\");\n            scope(exit) clearTZEnvVar();\n        }\n\n        {\n            auto timeInfo = SysTime(DateTime(1970, 1, 1)).toTM();\n\n            assert(timeInfo.tm_sec == 0);\n            assert(timeInfo.tm_min == 0);\n            assert(timeInfo.tm_hour == 0);\n            assert(timeInfo.tm_mday == 1);\n            assert(timeInfo.tm_mon == 0);\n            assert(timeInfo.tm_year == 70);\n            assert(timeInfo.tm_wday == 4);\n            assert(timeInfo.tm_yday == 0);\n\n            version (Posix)\n                assert(timeInfo.tm_isdst == 0);\n            else version (Windows)\n                assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1);\n\n            version (Posix)\n            {\n                assert(timeInfo.tm_gmtoff == -8 * 60 * 60);\n                assert(to!string(timeInfo.tm_zone) == \"PST\");\n            }\n        }\n\n        {\n            auto timeInfo = SysTime(DateTime(2010, 7, 4, 12, 15, 7), hnsecs(15)).toTM();\n\n            assert(timeInfo.tm_sec == 7);\n            assert(timeInfo.tm_min == 15);\n            assert(timeInfo.tm_hour == 12);\n            assert(timeInfo.tm_mday == 4);\n            assert(timeInfo.tm_mon == 6);\n            assert(timeInfo.tm_year == 110);\n            assert(timeInfo.tm_wday == 0);\n            assert(timeInfo.tm_yday == 184);\n\n            version (Posix)\n                assert(timeInfo.tm_isdst == 1);\n            else version (Windows)\n                assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1);\n\n            version (Posix)\n            {\n                assert(timeInfo.tm_gmtoff == -7 * 60 * 60);\n                assert(to!string(timeInfo.tm_zone) == \"PDT\");\n            }\n        }\n\n        // This is more to verify that SysTime.init.toTM() doesn't segfault and\n        // does something sane rather than that the value is anything\n        // particularly useful.\n        {\n            auto timeInfo = SysTime.init.toTM();\n\n            assert(timeInfo.tm_sec == 0);\n            assert(timeInfo.tm_min == 0);\n            assert(timeInfo.tm_hour == 0);\n            assert(timeInfo.tm_mday == 1);\n            assert(timeInfo.tm_mon == 0);\n            assert(timeInfo.tm_year == -1899);\n            assert(timeInfo.tm_wday == 1);\n            assert(timeInfo.tm_yday == 0);\n            assert(timeInfo.tm_isdst == 0);\n\n            version (Posix)\n            {\n                assert(timeInfo.tm_gmtoff == 0);\n                assert(to!string(timeInfo.tm_zone) == \"SysTime.init's timezone\");\n            }\n        }\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.toTM();\n        }\n    }\n\n\n    /++\n        Adds the given number of years or months to this $(LREF SysTime). A\n        negative number will subtract.\n\n        Note that if day overflow is allowed, and the date with the adjusted\n        year/month overflows the number of days in the new month, then the month\n        will be incremented by one, and the day set to the number of days\n        overflowed. (e.g. if the day were 31 and the new month were June, then\n        the month would be incremented to July, and the new day would be 1). If\n        day overflow is not allowed, then the day will be set to the last valid\n        day in the month (e.g. June 31st would become June 30th).\n\n        Params:\n            units         = The type of units to add (\"years\" or \"months\").\n            value         = The number of months or years to add to this\n                            $(LREF SysTime).\n            allowOverflow = Whether the days should be allowed to overflow,\n                            causing the month to increment.\n      +/\n    ref SysTime add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope\n        if (units == \"years\" || units == \"months\")\n    {\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        auto date = Date(cast(int) days);\n        date.add!units(value, allowOverflow);\n        days = date.dayOfGregorianCal - 1;\n\n        if (days < 0)\n        {\n            hnsecs -= convert!(\"hours\", \"hnsecs\")(24);\n            ++days;\n        }\n\n        immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(days);\n\n        adjTime = newDaysHNSecs + hnsecs;\n\n        return this;\n    }\n\n    @safe unittest\n    {\n        auto st1 = SysTime(DateTime(2010, 1, 1, 12, 30, 33));\n        st1.add!\"months\"(11);\n        assert(st1 == SysTime(DateTime(2010, 12, 1, 12, 30, 33)));\n\n        auto st2 = SysTime(DateTime(2010, 1, 1, 12, 30, 33));\n        st2.add!\"months\"(-11);\n        assert(st2 == SysTime(DateTime(2009, 2, 1, 12, 30, 33)));\n\n        auto st3 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));\n        st3.add!\"years\"(1);\n        assert(st3 == SysTime(DateTime(2001, 3, 1, 12, 30, 33)));\n\n        auto st4 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));\n        st4.add!\"years\"(1, AllowDayOverflow.no);\n        assert(st4 == SysTime(DateTime(2001, 2, 28, 12, 30, 33)));\n    }\n\n    // Test add!\"years\"() with AllowDayOverflow.yes\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.add!\"years\"(7);\n            assert(sysTime == SysTime(Date(2006, 7, 6)));\n            sysTime.add!\"years\"(-9);\n            assert(sysTime == SysTime(Date(1997, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 2, 28));\n            sysTime.add!\"years\"(1);\n            assert(sysTime == SysTime(Date(2000, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(2000, 2, 29));\n            sysTime.add!\"years\"(-1);\n            assert(sysTime == SysTime(Date(1999, 3, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234));\n            sysTime.add!\"years\"(7);\n            assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234)));\n            sysTime.add!\"years\"(-9);\n            assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207));\n            sysTime.add!\"years\"(1);\n            assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207));\n            sysTime.add!\"years\"(-1);\n            assert(sysTime == SysTime(DateTime(1999, 3, 1, 0, 7, 2), usecs(1207)));\n        }\n\n        // Test B.C.\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.add!\"years\"(-7);\n            assert(sysTime == SysTime(Date(-2006, 7, 6)));\n            sysTime.add!\"years\"(9);\n            assert(sysTime == SysTime(Date(-1997, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 2, 28));\n            sysTime.add!\"years\"(-1);\n            assert(sysTime == SysTime(Date(-2000, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2000, 2, 29));\n            sysTime.add!\"years\"(1);\n            assert(sysTime == SysTime(Date(-1999, 3, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234));\n            sysTime.add!\"years\"(-7);\n            assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234)));\n            sysTime.add!\"years\"(9);\n            assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3));\n            sysTime.add!\"years\"(-1);\n            assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3));\n            sysTime.add!\"years\"(1);\n            assert(sysTime == SysTime(DateTime(-1999, 3, 1, 3, 3, 3), hnsecs(3)));\n        }\n\n        // Test Both\n        {\n            auto sysTime = SysTime(Date(4, 7, 6));\n            sysTime.add!\"years\"(-5);\n            assert(sysTime == SysTime(Date(-1, 7, 6)));\n            sysTime.add!\"years\"(5);\n            assert(sysTime == SysTime(Date(4, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 7, 6));\n            sysTime.add!\"years\"(5);\n            assert(sysTime == SysTime(Date(1, 7, 6)));\n            sysTime.add!\"years\"(-5);\n            assert(sysTime == SysTime(Date(-4, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 7, 6));\n            sysTime.add!\"years\"(-8);\n            assert(sysTime == SysTime(Date(-4, 7, 6)));\n            sysTime.add!\"years\"(8);\n            assert(sysTime == SysTime(Date(4, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 7, 6));\n            sysTime.add!\"years\"(8);\n            assert(sysTime == SysTime(Date(4, 7, 6)));\n            sysTime.add!\"years\"(-8);\n            assert(sysTime == SysTime(Date(-4, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 2, 29));\n            sysTime.add!\"years\"(5);\n            assert(sysTime == SysTime(Date(1, 3, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 2, 29));\n            sysTime.add!\"years\"(-5);\n            assert(sysTime == SysTime(Date(-1, 3, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n            sysTime.add!\"years\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));\n            sysTime.add!\"years\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.add!\"years\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.add!\"years\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0));\n            sysTime.add!\"years\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n            sysTime.add!\"years\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.add!\"years\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.add!\"years\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329));\n            sysTime.add!\"years\"(-5);\n            assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329)));\n            sysTime.add!\"years\"(5);\n            assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329));\n            sysTime.add!\"years\"(5);\n            assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329)));\n            sysTime.add!\"years\"(-5);\n            assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555));\n            sysTime.add!\"years\"(5);\n            assert(sysTime == SysTime(DateTime(1, 3, 1, 5, 5, 5), msecs(555)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555));\n            sysTime.add!\"years\"(-5);\n            assert(sysTime == SysTime(DateTime(-1, 3, 1, 5, 5, 5), msecs(555)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555));\n            sysTime.add!\"years\"(-5).add!\"years\"(7);\n            assert(sysTime == SysTime(DateTime(6, 3, 1, 5, 5, 5), msecs(555)));\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.add!\"years\"(4)));\n        static assert(!__traits(compiles, ist.add!\"years\"(4)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.add!\"years\"(42);\n        }\n    }\n\n    // Test add!\"years\"() with AllowDayOverflow.no\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.add!\"years\"(7, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(2006, 7, 6)));\n            sysTime.add!\"years\"(-9, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1997, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 2, 28));\n            sysTime.add!\"years\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(2000, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(2000, 2, 29));\n            sysTime.add!\"years\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234));\n            sysTime.add!\"years\"(7, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234)));\n            sysTime.add!\"years\"(-9, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207));\n            sysTime.add!\"years\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207));\n            sysTime.add!\"years\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207)));\n        }\n\n        // Test B.C.\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.add!\"years\"(-7, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2006, 7, 6)));\n            sysTime.add!\"years\"(9, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1997, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 2, 28));\n            sysTime.add!\"years\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2000, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2000, 2, 29));\n            sysTime.add!\"years\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234));\n            sysTime.add!\"years\"(-7, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234)));\n            sysTime.add!\"years\"(9, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3));\n            sysTime.add!\"years\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3));\n            sysTime.add!\"years\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3)));\n        }\n\n        // Test Both\n        {\n            auto sysTime = SysTime(Date(4, 7, 6));\n            sysTime.add!\"years\"(-5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1, 7, 6)));\n            sysTime.add!\"years\"(5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 7, 6));\n            sysTime.add!\"years\"(5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1, 7, 6)));\n            sysTime.add!\"years\"(-5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-4, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 7, 6));\n            sysTime.add!\"years\"(-8, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-4, 7, 6)));\n            sysTime.add!\"years\"(8, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 7, 6));\n            sysTime.add!\"years\"(8, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 7, 6)));\n            sysTime.add!\"years\"(-8, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-4, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 2, 29));\n            sysTime.add!\"years\"(5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 2, 29));\n            sysTime.add!\"years\"(-5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n            sysTime.add!\"years\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));\n            sysTime.add!\"years\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.add!\"years\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.add!\"years\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0));\n            sysTime.add!\"years\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n            sysTime.add!\"years\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.add!\"years\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.add!\"years\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329));\n            sysTime.add!\"years\"(-5);\n            assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329)));\n            sysTime.add!\"years\"(5);\n            assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329));\n            sysTime.add!\"years\"(-5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329)));\n            sysTime.add!\"years\"(5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329));\n            sysTime.add!\"years\"(5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329)));\n            sysTime.add!\"years\"(-5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555));\n            sysTime.add!\"years\"(5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 2, 28, 5, 5, 5), msecs(555)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555));\n            sysTime.add!\"years\"(-5, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-1, 2, 28, 5, 5, 5), msecs(555)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555));\n            sysTime.add!\"years\"(-5, AllowDayOverflow.no).add!\"years\"(7, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(6, 2, 28, 5, 5, 5), msecs(555)));\n        }\n    }\n\n    // Test add!\"months\"() with AllowDayOverflow.yes\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.add!\"months\"(3);\n            assert(sysTime == SysTime(Date(1999, 10, 6)));\n            sysTime.add!\"months\"(-4);\n            assert(sysTime == SysTime(Date(1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.add!\"months\"(6);\n            assert(sysTime == SysTime(Date(2000, 1, 6)));\n            sysTime.add!\"months\"(-6);\n            assert(sysTime == SysTime(Date(1999, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.add!\"months\"(27);\n            assert(sysTime == SysTime(Date(2001, 10, 6)));\n            sysTime.add!\"months\"(-28);\n            assert(sysTime == SysTime(Date(1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 5, 31));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(Date(1999, 7, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 5, 31));\n            sysTime.add!\"months\"(-1);\n            assert(sysTime == SysTime(Date(1999, 5, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 2, 28));\n            sysTime.add!\"months\"(12);\n            assert(sysTime == SysTime(Date(2000, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(2000, 2, 29));\n            sysTime.add!\"months\"(12);\n            assert(sysTime == SysTime(Date(2001, 3, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 31));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(Date(1999, 8, 31)));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(Date(1999, 10, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1998, 8, 31));\n            sysTime.add!\"months\"(13);\n            assert(sysTime == SysTime(Date(1999, 10, 1)));\n            sysTime.add!\"months\"(-13);\n            assert(sysTime == SysTime(Date(1998, 9, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1997, 12, 31));\n            sysTime.add!\"months\"(13);\n            assert(sysTime == SysTime(Date(1999, 1, 31)));\n            sysTime.add!\"months\"(-13);\n            assert(sysTime == SysTime(Date(1997, 12, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1997, 12, 31));\n            sysTime.add!\"months\"(14);\n            assert(sysTime == SysTime(Date(1999, 3, 3)));\n            sysTime.add!\"months\"(-14);\n            assert(sysTime == SysTime(Date(1998, 1, 3)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1998, 12, 31));\n            sysTime.add!\"months\"(14);\n            assert(sysTime == SysTime(Date(2000, 3, 2)));\n            sysTime.add!\"months\"(-14);\n            assert(sysTime == SysTime(Date(1999, 1, 2)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 12, 31));\n            sysTime.add!\"months\"(14);\n            assert(sysTime == SysTime(Date(2001, 3, 3)));\n            sysTime.add!\"months\"(-14);\n            assert(sysTime == SysTime(Date(2000, 1, 3)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007));\n            sysTime.add!\"months\"(3);\n            assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007)));\n            sysTime.add!\"months\"(-4);\n            assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.add!\"months\"(14);\n            assert(sysTime == SysTime(DateTime(2000, 3, 2, 7, 7, 7), hnsecs(422202)));\n            sysTime.add!\"months\"(-14);\n            assert(sysTime == SysTime(DateTime(1999, 1, 2, 7, 7, 7), hnsecs(422202)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.add!\"months\"(14);\n            assert(sysTime == SysTime(DateTime(2001, 3, 3, 7, 7, 7), hnsecs(422202)));\n            sysTime.add!\"months\"(-14);\n            assert(sysTime == SysTime(DateTime(2000, 1, 3, 7, 7, 7), hnsecs(422202)));\n        }\n\n        // Test B.C.\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.add!\"months\"(3);\n            assert(sysTime == SysTime(Date(-1999, 10, 6)));\n            sysTime.add!\"months\"(-4);\n            assert(sysTime == SysTime(Date(-1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.add!\"months\"(6);\n            assert(sysTime == SysTime(Date(-1998, 1, 6)));\n            sysTime.add!\"months\"(-6);\n            assert(sysTime == SysTime(Date(-1999, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.add!\"months\"(-27);\n            assert(sysTime == SysTime(Date(-2001, 4, 6)));\n            sysTime.add!\"months\"(28);\n            assert(sysTime == SysTime(Date(-1999, 8, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 5, 31));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(Date(-1999, 7, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 5, 31));\n            sysTime.add!\"months\"(-1);\n            assert(sysTime == SysTime(Date(-1999, 5, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 2, 28));\n            sysTime.add!\"months\"(-12);\n            assert(sysTime == SysTime(Date(-2000, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2000, 2, 29));\n            sysTime.add!\"months\"(-12);\n            assert(sysTime == SysTime(Date(-2001, 3, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 31));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(Date(-1999, 8, 31)));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(Date(-1999, 10, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1998, 8, 31));\n            sysTime.add!\"months\"(13);\n            assert(sysTime == SysTime(Date(-1997, 10, 1)));\n            sysTime.add!\"months\"(-13);\n            assert(sysTime == SysTime(Date(-1998, 9, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1997, 12, 31));\n            sysTime.add!\"months\"(13);\n            assert(sysTime == SysTime(Date(-1995, 1, 31)));\n            sysTime.add!\"months\"(-13);\n            assert(sysTime == SysTime(Date(-1997, 12, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1997, 12, 31));\n            sysTime.add!\"months\"(14);\n            assert(sysTime == SysTime(Date(-1995, 3, 3)));\n            sysTime.add!\"months\"(-14);\n            assert(sysTime == SysTime(Date(-1996, 1, 3)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2002, 12, 31));\n            sysTime.add!\"months\"(14);\n            assert(sysTime == SysTime(Date(-2000, 3, 2)));\n            sysTime.add!\"months\"(-14);\n            assert(sysTime == SysTime(Date(-2001, 1, 2)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2001, 12, 31));\n            sysTime.add!\"months\"(14);\n            assert(sysTime == SysTime(Date(-1999, 3, 3)));\n            sysTime.add!\"months\"(-14);\n            assert(sysTime == SysTime(Date(-2000, 1, 3)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007));\n            sysTime.add!\"months\"(3);\n            assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007)));\n            sysTime.add!\"months\"(-4);\n            assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.add!\"months\"(14);\n            assert(sysTime == SysTime(DateTime(-2000, 3, 2, 7, 7, 7), hnsecs(422202)));\n            sysTime.add!\"months\"(-14);\n            assert(sysTime == SysTime(DateTime(-2001, 1, 2, 7, 7, 7), hnsecs(422202)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.add!\"months\"(14);\n            assert(sysTime == SysTime(DateTime(-1999, 3, 3, 7, 7, 7), hnsecs(422202)));\n            sysTime.add!\"months\"(-14);\n            assert(sysTime == SysTime(DateTime(-2000, 1, 3, 7, 7, 7), hnsecs(422202)));\n        }\n\n        // Test Both\n        {\n            auto sysTime = SysTime(Date(1, 1, 1));\n            sysTime.add!\"months\"(-1);\n            assert(sysTime == SysTime(Date(0, 12, 1)));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(Date(1, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 1, 1));\n            sysTime.add!\"months\"(-48);\n            assert(sysTime == SysTime(Date(0, 1, 1)));\n            sysTime.add!\"months\"(48);\n            assert(sysTime == SysTime(Date(4, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 3, 31));\n            sysTime.add!\"months\"(-49);\n            assert(sysTime == SysTime(Date(0, 3, 2)));\n            sysTime.add!\"months\"(49);\n            assert(sysTime == SysTime(Date(4, 4, 2)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 3, 31));\n            sysTime.add!\"months\"(-85);\n            assert(sysTime == SysTime(Date(-3, 3, 3)));\n            sysTime.add!\"months\"(85);\n            assert(sysTime == SysTime(Date(4, 4, 3)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n            sysTime.add!\"months\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.add!\"months\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n            sysTime.add!\"months\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.add!\"months\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17));\n            sysTime.add!\"months\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17)));\n            sysTime.add!\"months\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.add!\"months\"(-85);\n            assert(sysTime == SysTime(DateTime(-3, 3, 3, 12, 11, 10), msecs(9)));\n            sysTime.add!\"months\"(85);\n            assert(sysTime == SysTime(DateTime(4, 4, 3, 12, 11, 10), msecs(9)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.add!\"months\"(85);\n            assert(sysTime == SysTime(DateTime(4, 5, 1, 12, 11, 10), msecs(9)));\n            sysTime.add!\"months\"(-85);\n            assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.add!\"months\"(85).add!\"months\"(-83);\n            assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9)));\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.add!\"months\"(4)));\n        static assert(!__traits(compiles, ist.add!\"months\"(4)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.add!\"months\"(42);\n        }\n    }\n\n    // Test add!\"months\"() with AllowDayOverflow.no\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.add!\"months\"(3, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 10, 6)));\n            sysTime.add!\"months\"(-4, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.add!\"months\"(6, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(2000, 1, 6)));\n            sysTime.add!\"months\"(-6, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.add!\"months\"(27, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(2001, 10, 6)));\n            sysTime.add!\"months\"(-28, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 5, 31));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 6, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 5, 31));\n            sysTime.add!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 4, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 2, 28));\n            sysTime.add!\"months\"(12, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(2000, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(2000, 2, 29));\n            sysTime.add!\"months\"(12, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(2001, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 31));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 8, 31)));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 9, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1998, 8, 31));\n            sysTime.add!\"months\"(13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 9, 30)));\n            sysTime.add!\"months\"(-13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1998, 8, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1997, 12, 31));\n            sysTime.add!\"months\"(13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 1, 31)));\n            sysTime.add!\"months\"(-13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1997, 12, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1997, 12, 31));\n            sysTime.add!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 2, 28)));\n            sysTime.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1997, 12, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1998, 12, 31));\n            sysTime.add!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(2000, 2, 29)));\n            sysTime.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1998, 12, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 12, 31));\n            sysTime.add!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(2001, 2, 28)));\n            sysTime.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 12, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007));\n            sysTime.add!\"months\"(3, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007)));\n            sysTime.add!\"months\"(-4, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.add!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(2000, 2, 29, 7, 7, 7), hnsecs(422202)));\n            sysTime.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1998, 12, 29, 7, 7, 7), hnsecs(422202)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.add!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(2001, 2, 28, 7, 7, 7), hnsecs(422202)));\n            sysTime.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202)));\n        }\n\n        // Test B.C.\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.add!\"months\"(3, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 10, 6)));\n            sysTime.add!\"months\"(-4, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.add!\"months\"(6, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1998, 1, 6)));\n            sysTime.add!\"months\"(-6, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.add!\"months\"(-27, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2001, 4, 6)));\n            sysTime.add!\"months\"(28, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 8, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 5, 31));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 6, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 5, 31));\n            sysTime.add!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 4, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 2, 28));\n            sysTime.add!\"months\"(-12, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2000, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2000, 2, 29));\n            sysTime.add!\"months\"(-12, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2001, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 31));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 8, 31)));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 9, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1998, 8, 31));\n            sysTime.add!\"months\"(13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1997, 9, 30)));\n            sysTime.add!\"months\"(-13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1998, 8, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1997, 12, 31));\n            sysTime.add!\"months\"(13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1995, 1, 31)));\n            sysTime.add!\"months\"(-13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1997, 12, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1997, 12, 31));\n            sysTime.add!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1995, 2, 28)));\n            sysTime.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1997, 12, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2002, 12, 31));\n            sysTime.add!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2000, 2, 29)));\n            sysTime.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2002, 12, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2001, 12, 31));\n            sysTime.add!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 2, 28)));\n            sysTime.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2001, 12, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007));\n            sysTime.add!\"months\"(3, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007)));\n            sysTime.add!\"months\"(-4, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.add!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-2000, 2, 29, 7, 7, 7), hnsecs(422202)));\n            sysTime.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-2002, 12, 29, 7, 7, 7), hnsecs(422202)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.add!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 7, 7), hnsecs(422202)));\n            sysTime.add!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202)));\n        }\n\n        // Test Both\n        {\n            auto sysTime = SysTime(Date(1, 1, 1));\n            sysTime.add!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(0, 12, 1)));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 1, 1));\n            sysTime.add!\"months\"(-48, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(0, 1, 1)));\n            sysTime.add!\"months\"(48, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 3, 31));\n            sysTime.add!\"months\"(-49, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(0, 2, 29)));\n            sysTime.add!\"months\"(49, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 3, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 3, 31));\n            sysTime.add!\"months\"(-85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-3, 2, 28)));\n            sysTime.add!\"months\"(85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 3, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n            sysTime.add!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.add!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n            sysTime.add!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.add!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17));\n            sysTime.add!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17)));\n            sysTime.add!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.add!\"months\"(-85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-3, 2, 28, 12, 11, 10), msecs(9)));\n            sysTime.add!\"months\"(85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(4, 3, 28, 12, 11, 10), msecs(9)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.add!\"months\"(85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(4, 4, 30, 12, 11, 10), msecs(9)));\n            sysTime.add!\"months\"(-85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.add!\"months\"(85, AllowDayOverflow.no).add!\"months\"(-83, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9)));\n        }\n    }\n\n\n    /++\n        Adds the given number of years or months to this $(LREF SysTime). A\n        negative number will subtract.\n\n        The difference between rolling and adding is that rolling does not\n        affect larger units. Rolling a $(LREF SysTime) 12 months\n        gets the exact same $(LREF SysTime). However, the days can still be\n        affected due to the differing number of days in each month.\n\n        Because there are no units larger than years, there is no difference\n        between adding and rolling years.\n\n        Params:\n            units         = The type of units to add (\"years\" or \"months\").\n            value         = The number of months or years to add to this\n                            $(LREF SysTime).\n            allowOverflow = Whether the days should be allowed to overflow,\n                            causing the month to increment.\n      +/\n    ref SysTime roll(string units)\n                    (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope\n    if (units == \"years\")\n    {\n        return add!\"years\"(value, allowOverflow);\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.datetime.date : AllowDayOverflow, DateTime;\n\n        auto st1 = SysTime(DateTime(2010, 1, 1, 12, 33, 33));\n        st1.roll!\"months\"(1);\n        assert(st1 == SysTime(DateTime(2010, 2, 1, 12, 33, 33)));\n\n        auto st2 = SysTime(DateTime(2010, 1, 1, 12, 33, 33));\n        st2.roll!\"months\"(-1);\n        assert(st2 == SysTime(DateTime(2010, 12, 1, 12, 33, 33)));\n\n        auto st3 = SysTime(DateTime(1999, 1, 29, 12, 33, 33));\n        st3.roll!\"months\"(1);\n        assert(st3 == SysTime(DateTime(1999, 3, 1, 12, 33, 33)));\n\n        auto st4 = SysTime(DateTime(1999, 1, 29, 12, 33, 33));\n        st4.roll!\"months\"(1, AllowDayOverflow.no);\n        assert(st4 == SysTime(DateTime(1999, 2, 28, 12, 33, 33)));\n\n        auto st5 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));\n        st5.roll!\"years\"(1);\n        assert(st5 == SysTime(DateTime(2001, 3, 1, 12, 30, 33)));\n\n        auto st6 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));\n        st6.roll!\"years\"(1, AllowDayOverflow.no);\n        assert(st6 == SysTime(DateTime(2001, 2, 28, 12, 30, 33)));\n    }\n\n    @safe unittest\n    {\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        st.roll!\"years\"(4);\n        static assert(!__traits(compiles, cst.roll!\"years\"(4)));\n        static assert(!__traits(compiles, ist.roll!\"years\"(4)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.roll!\"years\"(42);\n        }\n    }\n\n\n    // Shares documentation with \"years\" overload.\n    ref SysTime roll(string units)\n                    (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope\n    if (units == \"months\")\n    {\n        auto hnsecs = adjTime;\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        auto date = Date(cast(int) days);\n        date.roll!\"months\"(value, allowOverflow);\n        days = date.dayOfGregorianCal - 1;\n\n        if (days < 0)\n        {\n            hnsecs -= convert!(\"hours\", \"hnsecs\")(24);\n            ++days;\n        }\n\n        immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(days);\n        adjTime = newDaysHNSecs + hnsecs;\n        return this;\n    }\n\n    // Test roll!\"months\"() with AllowDayOverflow.yes\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.roll!\"months\"(3);\n            assert(sysTime == SysTime(Date(1999, 10, 6)));\n            sysTime.roll!\"months\"(-4);\n            assert(sysTime == SysTime(Date(1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.roll!\"months\"(6);\n            assert(sysTime == SysTime(Date(1999, 1, 6)));\n            sysTime.roll!\"months\"(-6);\n            assert(sysTime == SysTime(Date(1999, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.roll!\"months\"(27);\n            assert(sysTime == SysTime(Date(1999, 10, 6)));\n            sysTime.roll!\"months\"(-28);\n            assert(sysTime == SysTime(Date(1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 5, 31));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(Date(1999, 7, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 5, 31));\n            sysTime.roll!\"months\"(-1);\n            assert(sysTime == SysTime(Date(1999, 5, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 2, 28));\n            sysTime.roll!\"months\"(12);\n            assert(sysTime == SysTime(Date(1999, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(2000, 2, 29));\n            sysTime.roll!\"months\"(12);\n            assert(sysTime == SysTime(Date(2000, 2, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 31));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(Date(1999, 8, 31)));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(Date(1999, 10, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1998, 8, 31));\n            sysTime.roll!\"months\"(13);\n            assert(sysTime == SysTime(Date(1998, 10, 1)));\n            sysTime.roll!\"months\"(-13);\n            assert(sysTime == SysTime(Date(1998, 9, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1997, 12, 31));\n            sysTime.roll!\"months\"(13);\n            assert(sysTime == SysTime(Date(1997, 1, 31)));\n            sysTime.roll!\"months\"(-13);\n            assert(sysTime == SysTime(Date(1997, 12, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1997, 12, 31));\n            sysTime.roll!\"months\"(14);\n            assert(sysTime == SysTime(Date(1997, 3, 3)));\n            sysTime.roll!\"months\"(-14);\n            assert(sysTime == SysTime(Date(1997, 1, 3)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1998, 12, 31));\n            sysTime.roll!\"months\"(14);\n            assert(sysTime == SysTime(Date(1998, 3, 3)));\n            sysTime.roll!\"months\"(-14);\n            assert(sysTime == SysTime(Date(1998, 1, 3)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 12, 31));\n            sysTime.roll!\"months\"(14);\n            assert(sysTime == SysTime(Date(1999, 3, 3)));\n            sysTime.roll!\"months\"(-14);\n            assert(sysTime == SysTime(Date(1999, 1, 3)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007));\n            sysTime.roll!\"months\"(3);\n            assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007)));\n            sysTime.roll!\"months\"(-4);\n            assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.roll!\"months\"(14);\n            assert(sysTime == SysTime(DateTime(1998, 3, 3, 7, 7, 7), hnsecs(422202)));\n            sysTime.roll!\"months\"(-14);\n            assert(sysTime == SysTime(DateTime(1998, 1, 3, 7, 7, 7), hnsecs(422202)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.roll!\"months\"(14);\n            assert(sysTime == SysTime(DateTime(1999, 3, 3, 7, 7, 7), hnsecs(422202)));\n            sysTime.roll!\"months\"(-14);\n            assert(sysTime == SysTime(DateTime(1999, 1, 3, 7, 7, 7), hnsecs(422202)));\n        }\n\n        // Test B.C.\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.roll!\"months\"(3);\n            assert(sysTime == SysTime(Date(-1999, 10, 6)));\n            sysTime.roll!\"months\"(-4);\n            assert(sysTime == SysTime(Date(-1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.roll!\"months\"(6);\n            assert(sysTime == SysTime(Date(-1999, 1, 6)));\n            sysTime.roll!\"months\"(-6);\n            assert(sysTime == SysTime(Date(-1999, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.roll!\"months\"(-27);\n            assert(sysTime == SysTime(Date(-1999, 4, 6)));\n            sysTime.roll!\"months\"(28);\n            assert(sysTime == SysTime(Date(-1999, 8, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 5, 31));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(Date(-1999, 7, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 5, 31));\n            sysTime.roll!\"months\"(-1);\n            assert(sysTime == SysTime(Date(-1999, 5, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 2, 28));\n            sysTime.roll!\"months\"(-12);\n            assert(sysTime == SysTime(Date(-1999, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2000, 2, 29));\n            sysTime.roll!\"months\"(-12);\n            assert(sysTime == SysTime(Date(-2000, 2, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 31));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(Date(-1999, 8, 31)));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(Date(-1999, 10, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1998, 8, 31));\n            sysTime.roll!\"months\"(13);\n            assert(sysTime == SysTime(Date(-1998, 10, 1)));\n            sysTime.roll!\"months\"(-13);\n            assert(sysTime == SysTime(Date(-1998, 9, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1997, 12, 31));\n            sysTime.roll!\"months\"(13);\n            assert(sysTime == SysTime(Date(-1997, 1, 31)));\n            sysTime.roll!\"months\"(-13);\n            assert(sysTime == SysTime(Date(-1997, 12, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1997, 12, 31));\n            sysTime.roll!\"months\"(14);\n            assert(sysTime == SysTime(Date(-1997, 3, 3)));\n            sysTime.roll!\"months\"(-14);\n            assert(sysTime == SysTime(Date(-1997, 1, 3)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2002, 12, 31));\n            sysTime.roll!\"months\"(14);\n            assert(sysTime == SysTime(Date(-2002, 3, 3)));\n            sysTime.roll!\"months\"(-14);\n            assert(sysTime == SysTime(Date(-2002, 1, 3)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2001, 12, 31));\n            sysTime.roll!\"months\"(14);\n            assert(sysTime == SysTime(Date(-2001, 3, 3)));\n            sysTime.roll!\"months\"(-14);\n            assert(sysTime == SysTime(Date(-2001, 1, 3)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n            sysTime.roll!\"months\"(-1);\n            assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0)));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"months\"(-1);\n            assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));\n            sysTime.roll!\"months\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.roll!\"months\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), hnsecs(5007));\n            sysTime.roll!\"months\"(3);\n            assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), hnsecs(5007)));\n            sysTime.roll!\"months\"(-4);\n            assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), hnsecs(5007)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.roll!\"months\"(14);\n            assert(sysTime == SysTime(DateTime(-2002, 3, 3, 7, 7, 7), hnsecs(422202)));\n            sysTime.roll!\"months\"(-14);\n            assert(sysTime == SysTime(DateTime(-2002, 1, 3, 7, 7, 7), hnsecs(422202)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.roll!\"months\"(14);\n            assert(sysTime == SysTime(DateTime(-2001, 3, 3, 7, 7, 7), hnsecs(422202)));\n            sysTime.roll!\"months\"(-14);\n            assert(sysTime == SysTime(DateTime(-2001, 1, 3, 7, 7, 7), hnsecs(422202)));\n        }\n\n        // Test Both\n        {\n            auto sysTime = SysTime(Date(1, 1, 1));\n            sysTime.roll!\"months\"(-1);\n            assert(sysTime == SysTime(Date(1, 12, 1)));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(Date(1, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 1, 1));\n            sysTime.roll!\"months\"(-48);\n            assert(sysTime == SysTime(Date(4, 1, 1)));\n            sysTime.roll!\"months\"(48);\n            assert(sysTime == SysTime(Date(4, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 3, 31));\n            sysTime.roll!\"months\"(-49);\n            assert(sysTime == SysTime(Date(4, 3, 2)));\n            sysTime.roll!\"months\"(49);\n            assert(sysTime == SysTime(Date(4, 4, 2)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 3, 31));\n            sysTime.roll!\"months\"(-85);\n            assert(sysTime == SysTime(Date(4, 3, 2)));\n            sysTime.roll!\"months\"(85);\n            assert(sysTime == SysTime(Date(4, 4, 2)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1, 1, 1));\n            sysTime.roll!\"months\"(-1);\n            assert(sysTime == SysTime(Date(-1, 12, 1)));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(Date(-1, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 1, 1));\n            sysTime.roll!\"months\"(-48);\n            assert(sysTime == SysTime(Date(-4, 1, 1)));\n            sysTime.roll!\"months\"(48);\n            assert(sysTime == SysTime(Date(-4, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 3, 31));\n            sysTime.roll!\"months\"(-49);\n            assert(sysTime == SysTime(Date(-4, 3, 2)));\n            sysTime.roll!\"months\"(49);\n            assert(sysTime == SysTime(Date(-4, 4, 2)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 3, 31));\n            sysTime.roll!\"months\"(-85);\n            assert(sysTime == SysTime(Date(-4, 3, 2)));\n            sysTime.roll!\"months\"(85);\n            assert(sysTime == SysTime(Date(-4, 4, 2)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17));\n            sysTime.roll!\"months\"(-1);\n            assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17)));\n            sysTime.roll!\"months\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.roll!\"months\"(-85);\n            assert(sysTime == SysTime(DateTime(4, 3, 2, 12, 11, 10), msecs(9)));\n            sysTime.roll!\"months\"(85);\n            assert(sysTime == SysTime(DateTime(4, 4, 2, 12, 11, 10), msecs(9)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.roll!\"months\"(85);\n            assert(sysTime == SysTime(DateTime(-3, 5, 1, 12, 11, 10), msecs(9)));\n            sysTime.roll!\"months\"(-85);\n            assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.roll!\"months\"(85).roll!\"months\"(-83);\n            assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9)));\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.roll!\"months\"(4)));\n        static assert(!__traits(compiles, ist.roll!\"months\"(4)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.roll!\"months\"(42);\n        }\n    }\n\n    // Test roll!\"months\"() with AllowDayOverflow.no\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.roll!\"months\"(3, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 10, 6)));\n            sysTime.roll!\"months\"(-4, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.roll!\"months\"(6, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 1, 6)));\n            sysTime.roll!\"months\"(-6, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.roll!\"months\"(27, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 10, 6)));\n            sysTime.roll!\"months\"(-28, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 5, 31));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 6, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 5, 31));\n            sysTime.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 4, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 2, 28));\n            sysTime.roll!\"months\"(12, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(2000, 2, 29));\n            sysTime.roll!\"months\"(12, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(2000, 2, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 31));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 8, 31)));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 9, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1998, 8, 31));\n            sysTime.roll!\"months\"(13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1998, 9, 30)));\n            sysTime.roll!\"months\"(-13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1998, 8, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1997, 12, 31));\n            sysTime.roll!\"months\"(13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1997, 1, 31)));\n            sysTime.roll!\"months\"(-13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1997, 12, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1997, 12, 31));\n            sysTime.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1997, 2, 28)));\n            sysTime.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1997, 12, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1998, 12, 31));\n            sysTime.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1998, 2, 28)));\n            sysTime.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1998, 12, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 12, 31));\n            sysTime.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 2, 28)));\n            sysTime.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1999, 12, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007));\n            sysTime.roll!\"months\"(3, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007)));\n            sysTime.roll!\"months\"(-4, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1998, 2, 28, 7, 7, 7), hnsecs(422202)));\n            sysTime.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1998, 12, 28, 7, 7, 7), hnsecs(422202)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 7, 7), hnsecs(422202)));\n            sysTime.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202)));\n        }\n\n        // Test B.C.\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.roll!\"months\"(3, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 10, 6)));\n            sysTime.roll!\"months\"(-4, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 6, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.roll!\"months\"(6, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 1, 6)));\n            sysTime.roll!\"months\"(-6, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.roll!\"months\"(-27, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 4, 6)));\n            sysTime.roll!\"months\"(28, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 8, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 5, 31));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 6, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 5, 31));\n            sysTime.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 4, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 2, 28));\n            sysTime.roll!\"months\"(-12, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2000, 2, 29));\n            sysTime.roll!\"months\"(-12, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2000, 2, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 31));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 8, 31)));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1999, 9, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1998, 8, 31));\n            sysTime.roll!\"months\"(13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1998, 9, 30)));\n            sysTime.roll!\"months\"(-13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1998, 8, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1997, 12, 31));\n            sysTime.roll!\"months\"(13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1997, 1, 31)));\n            sysTime.roll!\"months\"(-13, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1997, 12, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1997, 12, 31));\n            sysTime.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1997, 2, 28)));\n            sysTime.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1997, 12, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2002, 12, 31));\n            sysTime.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2002, 2, 28)));\n            sysTime.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2002, 12, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2001, 12, 31));\n            sysTime.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2001, 2, 28)));\n            sysTime.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-2001, 12, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007));\n            sysTime.roll!\"months\"(3, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007)));\n            sysTime.roll!\"months\"(-4, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-2002, 2, 28, 7, 7, 7), hnsecs(422202)));\n            sysTime.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-2002, 12, 28, 7, 7, 7), hnsecs(422202)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202));\n            sysTime.roll!\"months\"(14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-2001, 2, 28, 7, 7, 7), hnsecs(422202)));\n            sysTime.roll!\"months\"(-14, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202)));\n        }\n\n        // Test Both\n        {\n            auto sysTime = SysTime(Date(1, 1, 1));\n            sysTime.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1, 12, 1)));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(1, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 1, 1));\n            sysTime.roll!\"months\"(-48, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 1, 1)));\n            sysTime.roll!\"months\"(48, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 3, 31));\n            sysTime.roll!\"months\"(-49, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 2, 29)));\n            sysTime.roll!\"months\"(49, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 3, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(4, 3, 31));\n            sysTime.roll!\"months\"(-85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 2, 29)));\n            sysTime.roll!\"months\"(85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(4, 3, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1, 1, 1));\n            sysTime.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1, 12, 1)));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-1, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 1, 1));\n            sysTime.roll!\"months\"(-48, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-4, 1, 1)));\n            sysTime.roll!\"months\"(48, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-4, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 3, 31));\n            sysTime.roll!\"months\"(-49, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-4, 2, 29)));\n            sysTime.roll!\"months\"(49, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-4, 3, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-4, 3, 31));\n            sysTime.roll!\"months\"(-85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-4, 2, 29)));\n            sysTime.roll!\"months\"(85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(Date(-4, 3, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n            sysTime.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0)));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));\n            sysTime.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17));\n            sysTime.roll!\"months\"(-1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17)));\n            sysTime.roll!\"months\"(1, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.roll!\"months\"(-85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(4, 2, 29, 12, 11, 10), msecs(9)));\n            sysTime.roll!\"months\"(85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(4, 3, 29, 12, 11, 10), msecs(9)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.roll!\"months\"(85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-3, 4, 30, 12, 11, 10), msecs(9)));\n            sysTime.roll!\"months\"(-85, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));\n            sysTime.roll!\"months\"(85, AllowDayOverflow.no).roll!\"months\"(-83, AllowDayOverflow.no);\n            assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9)));\n        }\n    }\n\n\n    /++\n        Adds the given number of units to this $(LREF SysTime). A negative number\n        will subtract.\n\n        The difference between rolling and adding is that rolling does not\n        affect larger units. For instance, rolling a $(LREF SysTime) one\n        year's worth of days gets the exact same $(LREF SysTime).\n\n        Accepted units are `\"days\"`, `\"minutes\"`, `\"hours\"`,\n        `\"minutes\"`, `\"seconds\"`, `\"msecs\"`, `\"usecs\"`, and\n        `\"hnsecs\"`.\n\n        Note that when rolling msecs, usecs or hnsecs, they all add up to a\n        second. So, for example, rolling 1000 msecs is exactly the same as\n        rolling 100,000 usecs.\n\n        Params:\n            units = The units to add.\n            value = The number of $(D_PARAM units) to add to this\n                    $(LREF SysTime).\n      +/\n    ref SysTime roll(string units)(long value) @safe nothrow scope\n        if (units == \"days\")\n    {\n        auto hnsecs = adjTime;\n        auto gdays = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --gdays;\n        }\n\n        auto date = Date(cast(int) gdays);\n        date.roll!\"days\"(value);\n        gdays = date.dayOfGregorianCal - 1;\n\n        if (gdays < 0)\n        {\n            hnsecs -= convert!(\"hours\", \"hnsecs\")(24);\n            ++gdays;\n        }\n\n        immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(gdays);\n        adjTime = newDaysHNSecs + hnsecs;\n        return  this;\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : msecs, hnsecs;\n        import std.datetime.date : DateTime;\n\n        auto st1 = SysTime(DateTime(2010, 1, 1, 11, 23, 12));\n        st1.roll!\"days\"(1);\n        assert(st1 == SysTime(DateTime(2010, 1, 2, 11, 23, 12)));\n        st1.roll!\"days\"(365);\n        assert(st1 == SysTime(DateTime(2010, 1, 26, 11, 23, 12)));\n        st1.roll!\"days\"(-32);\n        assert(st1 == SysTime(DateTime(2010, 1, 25, 11, 23, 12)));\n\n        auto st2 = SysTime(DateTime(2010, 7, 4, 12, 0, 0));\n        st2.roll!\"hours\"(1);\n        assert(st2 == SysTime(DateTime(2010, 7, 4, 13, 0, 0)));\n\n        auto st3 = SysTime(DateTime(2010, 2, 12, 12, 0, 0));\n        st3.roll!\"hours\"(-1);\n        assert(st3 == SysTime(DateTime(2010, 2, 12, 11, 0, 0)));\n\n        auto st4 = SysTime(DateTime(2009, 12, 31, 0, 0, 0));\n        st4.roll!\"minutes\"(1);\n        assert(st4 == SysTime(DateTime(2009, 12, 31, 0, 1, 0)));\n\n        auto st5 = SysTime(DateTime(2010, 1, 1, 0, 0, 0));\n        st5.roll!\"minutes\"(-1);\n        assert(st5 == SysTime(DateTime(2010, 1, 1, 0, 59, 0)));\n\n        auto st6 = SysTime(DateTime(2009, 12, 31, 0, 0, 0));\n        st6.roll!\"seconds\"(1);\n        assert(st6 == SysTime(DateTime(2009, 12, 31, 0, 0, 1)));\n\n        auto st7 = SysTime(DateTime(2010, 1, 1, 0, 0, 0));\n        st7.roll!\"seconds\"(-1);\n        assert(st7 == SysTime(DateTime(2010, 1, 1, 0, 0, 59)));\n\n        auto dt = DateTime(2010, 1, 1, 0, 0, 0);\n        auto st8 = SysTime(dt);\n        st8.roll!\"msecs\"(1);\n        assert(st8 == SysTime(dt, msecs(1)));\n\n        auto st9 = SysTime(dt);\n        st9.roll!\"msecs\"(-1);\n        assert(st9 == SysTime(dt, msecs(999)));\n\n        auto st10 = SysTime(dt);\n        st10.roll!\"hnsecs\"(1);\n        assert(st10 == SysTime(dt, hnsecs(1)));\n\n        auto st11 = SysTime(dt);\n        st11.roll!\"hnsecs\"(-1);\n        assert(st11 == SysTime(dt, hnsecs(9_999_999)));\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        {\n            auto sysTime = SysTime(Date(1999, 2, 28));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(1999, 2, 1)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(Date(1999, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(2000, 2, 28));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(2000, 2, 29)));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(2000, 2, 1)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(Date(2000, 2, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 6, 30));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(1999, 6, 1)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(Date(1999, 6, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 31));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(1999, 7, 1)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(Date(1999, 7, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 1, 1));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(Date(1999, 1, 31)));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(1999, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.roll!\"days\"(9);\n            assert(sysTime == SysTime(Date(1999, 7, 15)));\n            sysTime.roll!\"days\"(-11);\n            assert(sysTime == SysTime(Date(1999, 7, 4)));\n            sysTime.roll!\"days\"(30);\n            assert(sysTime == SysTime(Date(1999, 7, 3)));\n            sysTime.roll!\"days\"(-3);\n            assert(sysTime == SysTime(Date(1999, 7, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 7, 6));\n            sysTime.roll!\"days\"(365);\n            assert(sysTime == SysTime(Date(1999, 7, 30)));\n            sysTime.roll!\"days\"(-365);\n            assert(sysTime == SysTime(Date(1999, 7, 6)));\n            sysTime.roll!\"days\"(366);\n            assert(sysTime == SysTime(Date(1999, 7, 31)));\n            sysTime.roll!\"days\"(730);\n            assert(sysTime == SysTime(Date(1999, 7, 17)));\n            sysTime.roll!\"days\"(-1096);\n            assert(sysTime == SysTime(Date(1999, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(1999, 2, 6));\n            sysTime.roll!\"days\"(365);\n            assert(sysTime == SysTime(Date(1999, 2, 7)));\n            sysTime.roll!\"days\"(-365);\n            assert(sysTime == SysTime(Date(1999, 2, 6)));\n            sysTime.roll!\"days\"(366);\n            assert(sysTime == SysTime(Date(1999, 2, 8)));\n            sysTime.roll!\"days\"(730);\n            assert(sysTime == SysTime(Date(1999, 2, 10)));\n            sysTime.roll!\"days\"(-1096);\n            assert(sysTime == SysTime(Date(1999, 2, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(DateTime(1999, 2, 1, 7, 9, 2), usecs(234578)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1999, 7, 6, 7, 9, 2), usecs(234578));\n            sysTime.roll!\"days\"(9);\n            assert(sysTime == SysTime(DateTime(1999, 7, 15, 7, 9, 2), usecs(234578)));\n            sysTime.roll!\"days\"(-11);\n            assert(sysTime == SysTime(DateTime(1999, 7, 4, 7, 9, 2), usecs(234578)));\n            sysTime.roll!\"days\"(30);\n            assert(sysTime == SysTime(DateTime(1999, 7, 3, 7, 9, 2), usecs(234578)));\n            sysTime.roll!\"days\"(-3);\n            assert(sysTime == SysTime(DateTime(1999, 7, 31, 7, 9, 2), usecs(234578)));\n        }\n\n        // Test B.C.\n        {\n            auto sysTime = SysTime(Date(-1999, 2, 28));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(-1999, 2, 1)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(Date(-1999, 2, 28)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-2000, 2, 28));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(-2000, 2, 29)));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(-2000, 2, 1)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(Date(-2000, 2, 29)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 6, 30));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(-1999, 6, 1)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(Date(-1999, 6, 30)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 31));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(-1999, 7, 1)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(Date(-1999, 7, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 1, 1));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(Date(-1999, 1, 31)));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(Date(-1999, 1, 1)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.roll!\"days\"(9);\n            assert(sysTime == SysTime(Date(-1999, 7, 15)));\n            sysTime.roll!\"days\"(-11);\n            assert(sysTime == SysTime(Date(-1999, 7, 4)));\n            sysTime.roll!\"days\"(30);\n            assert(sysTime == SysTime(Date(-1999, 7, 3)));\n            sysTime.roll!\"days\"(-3);\n            assert(sysTime == SysTime(Date(-1999, 7, 31)));\n        }\n\n        {\n            auto sysTime = SysTime(Date(-1999, 7, 6));\n            sysTime.roll!\"days\"(365);\n            assert(sysTime == SysTime(Date(-1999, 7, 30)));\n            sysTime.roll!\"days\"(-365);\n            assert(sysTime == SysTime(Date(-1999, 7, 6)));\n            sysTime.roll!\"days\"(366);\n            assert(sysTime == SysTime(Date(-1999, 7, 31)));\n            sysTime.roll!\"days\"(730);\n            assert(sysTime == SysTime(Date(-1999, 7, 17)));\n            sysTime.roll!\"days\"(-1096);\n            assert(sysTime == SysTime(Date(-1999, 7, 6)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(DateTime(-1999, 2, 1, 7, 9, 2), usecs(234578)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(-1999, 7, 6, 7, 9, 2), usecs(234578));\n            sysTime.roll!\"days\"(9);\n            assert(sysTime == SysTime(DateTime(-1999, 7, 15, 7, 9, 2), usecs(234578)));\n            sysTime.roll!\"days\"(-11);\n            assert(sysTime == SysTime(DateTime(-1999, 7, 4, 7, 9, 2), usecs(234578)));\n            sysTime.roll!\"days\"(30);\n            assert(sysTime == SysTime(DateTime(-1999, 7, 3, 7, 9, 2), usecs(234578)));\n            sysTime.roll!\"days\"(-3);\n        }\n\n        // Test Both\n        {\n            auto sysTime = SysTime(Date(1, 7, 6));\n            sysTime.roll!\"days\"(-365);\n            assert(sysTime == SysTime(Date(1, 7, 13)));\n            sysTime.roll!\"days\"(365);\n            assert(sysTime == SysTime(Date(1, 7, 6)));\n            sysTime.roll!\"days\"(-731);\n            assert(sysTime == SysTime(Date(1, 7, 19)));\n            sysTime.roll!\"days\"(730);\n            assert(sysTime == SysTime(Date(1, 7, 5)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(DateTime(1, 1, 31, 0, 0, 0)));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(DateTime(1, 1, 31, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 31, 0, 0, 0));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"days\"(1);\n            assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.roll!\"days\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22));\n            sysTime.roll!\"days\"(-365);\n            assert(sysTime == SysTime(DateTime(1, 7, 13, 13, 13, 9), msecs(22)));\n            sysTime.roll!\"days\"(365);\n            assert(sysTime == SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22)));\n            sysTime.roll!\"days\"(-731);\n            assert(sysTime == SysTime(DateTime(1, 7, 19, 13, 13, 9), msecs(22)));\n            sysTime.roll!\"days\"(730);\n            assert(sysTime == SysTime(DateTime(1, 7, 5, 13, 13, 9), msecs(22)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22));\n            sysTime.roll!\"days\"(-365);\n            assert(sysTime == SysTime(DateTime(0, 7, 13, 13, 13, 9), msecs(22)));\n            sysTime.roll!\"days\"(365);\n            assert(sysTime == SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22)));\n            sysTime.roll!\"days\"(-731);\n            assert(sysTime == SysTime(DateTime(0, 7, 19, 13, 13, 9), msecs(22)));\n            sysTime.roll!\"days\"(730);\n            assert(sysTime == SysTime(DateTime(0, 7, 5, 13, 13, 9), msecs(22)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22));\n            sysTime.roll!\"days\"(-365).roll!\"days\"(362).roll!\"days\"(-12).roll!\"days\"(730);\n            assert(sysTime == SysTime(DateTime(0, 7, 8, 13, 13, 9), msecs(22)));\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.roll!\"days\"(4)));\n        static assert(!__traits(compiles, ist.roll!\"days\"(4)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.roll!\"days\"(42);\n        }\n    }\n\n\n    // Shares documentation with \"days\" version.\n    ref SysTime roll(string units)(long value) @safe nothrow scope\n        if (units == \"hours\" || units == \"minutes\" || units == \"seconds\")\n    {\n        try\n        {\n            auto hnsecs = adjTime;\n            auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n            if (hnsecs < 0)\n            {\n                hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n                --days;\n            }\n\n            immutable hour = splitUnitsFromHNSecs!\"hours\"(hnsecs);\n            immutable minute = splitUnitsFromHNSecs!\"minutes\"(hnsecs);\n            immutable second = splitUnitsFromHNSecs!\"seconds\"(hnsecs);\n\n            auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour,\n                                          cast(int) minute, cast(int) second));\n            dateTime.roll!units(value);\n            --days;\n\n            hnsecs += convert!(\"hours\", \"hnsecs\")(dateTime.hour);\n            hnsecs += convert!(\"minutes\", \"hnsecs\")(dateTime.minute);\n            hnsecs += convert!(\"seconds\", \"hnsecs\")(dateTime.second);\n\n            if (days < 0)\n            {\n                hnsecs -= convert!(\"hours\", \"hnsecs\")(24);\n                ++days;\n            }\n\n            immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(days);\n            adjTime = newDaysHNSecs + hnsecs;\n            return this;\n        }\n        catch (Exception e)\n            assert(0, \"Either DateTime's constructor or TimeOfDay's constructor threw.\");\n    }\n\n    // Test roll!\"hours\"().\n    @safe unittest\n    {\n        import core.time;\n        static void testST(SysTime orig, int hours, SysTime expected, size_t line = __LINE__) @safe\n        {\n            orig.roll!\"hours\"(hours);\n            if (orig != expected)\n                throw new AssertError(format(\"Failed. actual [%s] != expected [%s]\", orig, expected), __FILE__, line);\n        }\n\n        // Test A.D.\n        immutable d = msecs(45);\n        auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d);\n        testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d));\n        testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d));\n        testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d));\n        testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d));\n        testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d));\n        testST(beforeAD, 6, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d));\n        testST(beforeAD, 7, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d));\n        testST(beforeAD, 8, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d));\n        testST(beforeAD, 9, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d));\n        testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d));\n        testST(beforeAD, 11, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d));\n        testST(beforeAD, 12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d));\n        testST(beforeAD, 13, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d));\n        testST(beforeAD, 14, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d));\n        testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d));\n        testST(beforeAD, 16, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d));\n        testST(beforeAD, 17, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d));\n        testST(beforeAD, 18, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d));\n        testST(beforeAD, 19, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d));\n        testST(beforeAD, 20, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d));\n        testST(beforeAD, 21, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d));\n        testST(beforeAD, 22, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d));\n        testST(beforeAD, 23, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d));\n        testST(beforeAD, 24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, 25, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d));\n        testST(beforeAD, 50, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d));\n        testST(beforeAD, 10_000, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d));\n\n        testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d));\n        testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d));\n        testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d));\n        testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d));\n        testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d));\n        testST(beforeAD, -6, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d));\n        testST(beforeAD, -7, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d));\n        testST(beforeAD, -8, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d));\n        testST(beforeAD, -9, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d));\n        testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d));\n        testST(beforeAD, -11, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d));\n        testST(beforeAD, -12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d));\n        testST(beforeAD, -13, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d));\n        testST(beforeAD, -14, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d));\n        testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d));\n        testST(beforeAD, -16, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d));\n        testST(beforeAD, -17, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d));\n        testST(beforeAD, -18, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d));\n        testST(beforeAD, -19, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d));\n        testST(beforeAD, -20, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d));\n        testST(beforeAD, -21, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d));\n        testST(beforeAD, -22, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d));\n        testST(beforeAD, -23, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d));\n        testST(beforeAD, -24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, -25, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d));\n        testST(beforeAD, -50, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d));\n        testST(beforeAD, -10_000, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d));\n\n        testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d));\n        testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d));\n        testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d));\n\n        testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d));\n        testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d));\n        testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d));\n\n        testST(SysTime(DateTime(1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 31, 0, 30, 33), d));\n        testST(SysTime(DateTime(1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(1999, 8, 1, 23, 30, 33), d));\n\n        testST(SysTime(DateTime(1999, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 12, 31, 0, 30, 33), d));\n        testST(SysTime(DateTime(2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(2000, 1, 1, 23, 30, 33), d));\n\n        testST(SysTime(DateTime(1999, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(1999, 2, 28, 0, 30, 33), d));\n        testST(SysTime(DateTime(1999, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(1999, 3, 2, 23, 30, 33), d));\n\n        testST(SysTime(DateTime(2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(2000, 2, 28, 0, 30, 33), d));\n        testST(SysTime(DateTime(2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(2000, 3, 1, 23, 30, 33), d));\n\n        // Test B.C.\n        auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d);\n        testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d));\n        testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d));\n        testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d));\n        testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d));\n        testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d));\n        testST(beforeBC, 6, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d));\n        testST(beforeBC, 7, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d));\n        testST(beforeBC, 8, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d));\n        testST(beforeBC, 9, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d));\n        testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d));\n        testST(beforeBC, 11, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d));\n        testST(beforeBC, 12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d));\n        testST(beforeBC, 13, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d));\n        testST(beforeBC, 14, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d));\n        testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d));\n        testST(beforeBC, 16, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d));\n        testST(beforeBC, 17, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d));\n        testST(beforeBC, 18, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d));\n        testST(beforeBC, 19, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d));\n        testST(beforeBC, 20, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d));\n        testST(beforeBC, 21, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d));\n        testST(beforeBC, 22, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d));\n        testST(beforeBC, 23, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d));\n        testST(beforeBC, 24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, 25, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d));\n        testST(beforeBC, 50, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d));\n        testST(beforeBC, 10_000, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d));\n\n        testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d));\n        testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d));\n        testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d));\n        testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d));\n        testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d));\n        testST(beforeBC, -6, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d));\n        testST(beforeBC, -7, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d));\n        testST(beforeBC, -8, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d));\n        testST(beforeBC, -9, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d));\n        testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d));\n        testST(beforeBC, -11, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d));\n        testST(beforeBC, -12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d));\n        testST(beforeBC, -13, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d));\n        testST(beforeBC, -14, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d));\n        testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d));\n        testST(beforeBC, -16, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d));\n        testST(beforeBC, -17, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d));\n        testST(beforeBC, -18, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d));\n        testST(beforeBC, -19, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d));\n        testST(beforeBC, -20, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d));\n        testST(beforeBC, -21, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d));\n        testST(beforeBC, -22, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d));\n        testST(beforeBC, -23, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d));\n        testST(beforeBC, -24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, -25, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d));\n        testST(beforeBC, -50, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d));\n        testST(beforeBC, -10_000, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d));\n\n        testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d));\n\n        testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d));\n\n        testST(SysTime(DateTime(-1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 31, 0, 30, 33), d));\n        testST(SysTime(DateTime(-1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 8, 1, 23, 30, 33), d));\n\n        testST(SysTime(DateTime(-2001, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(-2001, 12, 31, 0, 30, 33), d));\n        testST(SysTime(DateTime(-2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(-2000, 1, 1, 23, 30, 33), d));\n\n        testST(SysTime(DateTime(-2001, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2001, 2, 28, 0, 30, 33), d));\n        testST(SysTime(DateTime(-2001, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(-2001, 3, 2, 23, 30, 33), d));\n\n        testST(SysTime(DateTime(-2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2000, 2, 28, 0, 30, 33), d));\n        testST(SysTime(DateTime(-2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(-2000, 3, 1, 23, 30, 33), d));\n\n        // Test Both\n        testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 17_546, SysTime(DateTime(-1, 1, 1, 13, 30, 33), d));\n        testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -17_546, SysTime(DateTime(1, 1, 1, 11, 30, 33), d));\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n            sysTime.roll!\"hours\"(-1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 0, 0)));\n            sysTime.roll!\"hours\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"hours\"(-1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n            sysTime.roll!\"hours\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 31, 23, 0, 0));\n            sysTime.roll!\"hours\"(1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0)));\n            sysTime.roll!\"hours\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"hours\"(1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 59, 59), hnsecs(9_999_999)));\n            sysTime.roll!\"hours\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"hours\"(1).roll!\"hours\"(-67);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 5, 59, 59), hnsecs(9_999_999)));\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.roll!\"hours\"(4)));\n        static assert(!__traits(compiles, ist.roll!\"hours\"(4)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.roll!\"hours\"(42);\n        }\n    }\n\n    // Test roll!\"minutes\"().\n    @safe unittest\n    {\n        import core.time;\n        static void testST(SysTime orig, int minutes, SysTime expected, size_t line = __LINE__) @safe\n        {\n            orig.roll!\"minutes\"(minutes);\n            if (orig != expected)\n                throw new AssertError(format(\"Failed. actual [%s] != expected [%s]\", orig, expected), __FILE__, line);\n        }\n\n        // Test A.D.\n        immutable d = usecs(7203);\n        auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d);\n        testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d));\n        testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 32, 33), d));\n        testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 33, 33), d));\n        testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 34, 33), d));\n        testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 35, 33), d));\n        testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 40, 33), d));\n        testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d));\n        testST(beforeAD, 29, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d));\n        testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));\n        testST(beforeAD, 45, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d));\n        testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, 75, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d));\n        testST(beforeAD, 90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));\n        testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 10, 33), d));\n\n        testST(beforeAD, 689, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d));\n        testST(beforeAD, 690, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));\n        testST(beforeAD, 691, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d));\n        testST(beforeAD, 960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, 1439, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d));\n        testST(beforeAD, 1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, 1441, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d));\n        testST(beforeAD, 2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n\n        testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d));\n        testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 28, 33), d));\n        testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 27, 33), d));\n        testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 26, 33), d));\n        testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 25, 33), d));\n        testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 20, 33), d));\n        testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d));\n        testST(beforeAD, -29, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d));\n        testST(beforeAD, -30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));\n        testST(beforeAD, -45, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d));\n        testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, -75, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d));\n        testST(beforeAD, -90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));\n        testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 50, 33), d));\n\n        testST(beforeAD, -749, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d));\n        testST(beforeAD, -750, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));\n        testST(beforeAD, -751, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d));\n        testST(beforeAD, -960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, -1439, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d));\n        testST(beforeAD, -1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, -1441, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d));\n        testST(beforeAD, -2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n\n        testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d));\n        testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));\n        testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d));\n\n        testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(1999, 7, 6, 11, 0, 33), d));\n        testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(1999, 7, 6, 11, 59, 33), d));\n        testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(1999, 7, 6, 11, 58, 33), d));\n\n        testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 1, 33), d));\n        testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 33), d));\n        testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 0, 59, 33), d));\n\n        testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(1999, 7, 5, 23, 0, 33), d));\n        testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 33), d));\n        testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(1999, 7, 5, 23, 58, 33), d));\n\n        testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(1998, 12, 31, 23, 0, 33), d));\n        testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 33), d));\n        testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(1998, 12, 31, 23, 58, 33), d));\n\n        // Test B.C.\n        auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d);\n        testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d));\n        testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 32, 33), d));\n        testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 33, 33), d));\n        testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 34, 33), d));\n        testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 35, 33), d));\n        testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 40, 33), d));\n        testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d));\n        testST(beforeBC, 29, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d));\n        testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));\n        testST(beforeBC, 45, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d));\n        testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, 75, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d));\n        testST(beforeBC, 90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));\n        testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 10, 33), d));\n\n        testST(beforeBC, 689, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d));\n        testST(beforeBC, 690, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));\n        testST(beforeBC, 691, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d));\n        testST(beforeBC, 960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, 1439, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d));\n        testST(beforeBC, 1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, 1441, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d));\n        testST(beforeBC, 2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n\n        testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d));\n        testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 28, 33), d));\n        testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 27, 33), d));\n        testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 26, 33), d));\n        testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 25, 33), d));\n        testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 20, 33), d));\n        testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d));\n        testST(beforeBC, -29, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d));\n        testST(beforeBC, -30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));\n        testST(beforeBC, -45, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d));\n        testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, -75, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d));\n        testST(beforeBC, -90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));\n        testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 50, 33), d));\n\n        testST(beforeBC, -749, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d));\n        testST(beforeBC, -750, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));\n        testST(beforeBC, -751, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d));\n        testST(beforeBC, -960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, -1439, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d));\n        testST(beforeBC, -1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, -1441, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d));\n        testST(beforeBC, -2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n\n        testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d));\n\n        testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 11, 0, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 11, 58, 33), d));\n\n        testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 1, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 59, 33), d));\n\n        testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 0, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d));\n        testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 58, 33), d));\n\n        testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 0, 33), d));\n        testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d));\n        testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 58, 33), d));\n\n        // Test Both\n        testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(1, 1, 1, 0, 59, 0)));\n        testST(SysTime(DateTime(0, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(0, 12, 31, 23, 0, 0)));\n\n        testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(0, 1, 1, 0, 59, 0)));\n        testST(SysTime(DateTime(-1, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(-1, 12, 31, 23, 0, 0)));\n\n        testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_760, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d));\n        testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -1_052_760, SysTime(DateTime(1, 1, 1, 13, 30, 33), d));\n\n        testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_782, SysTime(DateTime(-1, 1, 1, 11, 52, 33), d));\n        testST(SysTime(DateTime(1, 1, 1, 13, 52, 33), d), -1_052_782, SysTime(DateTime(1, 1, 1, 13, 30, 33), d));\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n            sysTime.roll!\"minutes\"(-1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 0)));\n            sysTime.roll!\"minutes\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999));\n            sysTime.roll!\"minutes\"(-1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999)));\n            sysTime.roll!\"minutes\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 0));\n            sysTime.roll!\"minutes\"(1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0)));\n            sysTime.roll!\"minutes\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"minutes\"(1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 59), hnsecs(9_999_999)));\n            sysTime.roll!\"minutes\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"minutes\"(1).roll!\"minutes\"(-79);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 41, 59), hnsecs(9_999_999)));\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.roll!\"minutes\"(4)));\n        static assert(!__traits(compiles, ist.roll!\"minutes\"(4)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.roll!\"minutes\"(42);\n        }\n    }\n\n    // Test roll!\"seconds\"().\n    @safe unittest\n    {\n        import core.time;\n        static void testST(SysTime orig, int seconds, SysTime expected, size_t line = __LINE__) @safe\n        {\n            orig.roll!\"seconds\"(seconds);\n            if (orig != expected)\n                throw new AssertError(format(\"Failed. actual [%s] != expected [%s]\", orig, expected), __FILE__, line);\n        }\n\n        // Test A.D.\n        immutable d = msecs(274);\n        auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d);\n        testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d));\n        testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 35), d));\n        testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 30, 36), d));\n        testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 30, 37), d));\n        testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 30, 38), d));\n        testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 43), d));\n        testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 30, 48), d));\n        testST(beforeAD, 26, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d));\n        testST(beforeAD, 27, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d));\n        testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 30, 3), d));\n        testST(beforeAD, 59, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d));\n        testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, 61, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d));\n\n        testST(beforeAD, 1766, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d));\n        testST(beforeAD, 1767, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d));\n        testST(beforeAD, 1768, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d));\n        testST(beforeAD, 2007, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d));\n        testST(beforeAD, 3599, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d));\n        testST(beforeAD, 3600, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, 3601, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d));\n        testST(beforeAD, 7200, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n\n        testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d));\n        testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 31), d));\n        testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 30, 30), d));\n        testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 30, 29), d));\n        testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 30, 28), d));\n        testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 23), d));\n        testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 30, 18), d));\n        testST(beforeAD, -33, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d));\n        testST(beforeAD, -34, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d));\n        testST(beforeAD, -35, SysTime(DateTime(1999, 7, 6, 12, 30, 58), d));\n        testST(beforeAD, -59, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d));\n        testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));\n        testST(beforeAD, -61, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d));\n\n        testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d));\n        testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d));\n        testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d));\n\n        testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 0, 1), d));\n        testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 0), d));\n        testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 0, 59), d));\n\n        testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 0, 0, 1), d));\n        testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 0), d));\n        testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 0, 0, 59), d));\n\n        testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(1999, 7, 5, 23, 59, 0), d));\n        testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 59), d));\n        testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(1999, 7, 5, 23, 59, 58), d));\n\n        testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(1998, 12, 31, 23, 59, 0), d));\n        testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 59), d));\n        testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(1998, 12, 31, 23, 59, 58), d));\n\n        // Test B.C.\n        auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d);\n        testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d));\n        testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 35), d));\n        testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 30, 36), d));\n        testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 30, 37), d));\n        testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 30, 38), d));\n        testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 43), d));\n        testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 30, 48), d));\n        testST(beforeBC, 26, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d));\n        testST(beforeBC, 27, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d));\n        testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 30, 3), d));\n        testST(beforeBC, 59, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d));\n        testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, 61, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d));\n\n        testST(beforeBC, 1766, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d));\n        testST(beforeBC, 1767, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d));\n        testST(beforeBC, 1768, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d));\n        testST(beforeBC, 2007, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d));\n        testST(beforeBC, 3599, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d));\n        testST(beforeBC, 3600, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, 3601, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d));\n        testST(beforeBC, 7200, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n\n        testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d));\n        testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 31), d));\n        testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 30, 30), d));\n        testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 30, 29), d));\n        testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 30, 28), d));\n        testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 23), d));\n        testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 30, 18), d));\n        testST(beforeBC, -33, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d));\n        testST(beforeBC, -34, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d));\n        testST(beforeBC, -35, SysTime(DateTime(-1999, 7, 6, 12, 30, 58), d));\n        testST(beforeBC, -59, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d));\n        testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));\n        testST(beforeBC, -61, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d));\n\n        testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d));\n\n        testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 0, 1), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 0, 59), d));\n\n        testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 0, 1), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d));\n        testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 0, 59), d));\n\n        testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 59, 0), d));\n        testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d));\n        testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 59, 58), d));\n\n        testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 59, 0), d));\n        testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d));\n        testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 59, 58), d));\n\n        // Test Both\n        testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(1, 1, 1, 0, 0, 59), d));\n        testST(SysTime(DateTime(0, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(0, 12, 31, 23, 59, 0), d));\n\n        testST(SysTime(DateTime(0, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(0, 1, 1, 0, 0, 59), d));\n        testST(SysTime(DateTime(-1, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-1, 12, 31, 23, 59, 0), d));\n\n        testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_600L, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d));\n        testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -63_165_600L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d));\n\n        testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_617L, SysTime(DateTime(-1, 1, 1, 11, 30, 50), d));\n        testST(SysTime(DateTime(1, 1, 1, 13, 30, 50), d), -63_165_617L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d));\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n            sysTime.roll!\"seconds\"(-1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59)));\n            sysTime.roll!\"seconds\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999));\n            sysTime.roll!\"seconds\"(-1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999)));\n            sysTime.roll!\"seconds\"(1);\n            assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59));\n            sysTime.roll!\"seconds\"(1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0)));\n            sysTime.roll!\"seconds\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"seconds\"(1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0), hnsecs(9_999_999)));\n            sysTime.roll!\"seconds\"(-1);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        }\n\n        {\n            auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n            sysTime.roll!\"seconds\"(1).roll!\"seconds\"(-102);\n            assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 18), hnsecs(9_999_999)));\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.roll!\"seconds\"(4)));\n        static assert(!__traits(compiles, ist.roll!\"seconds\"(4)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.roll!\"seconds\"(42);\n        }\n    }\n\n\n    // Shares documentation with \"days\" version.\n    ref SysTime roll(string units)(long value) @safe nothrow scope\n        if (units == \"msecs\" || units == \"usecs\" || units == \"hnsecs\")\n    {\n        auto hnsecs = adjTime;\n        immutable days = splitUnitsFromHNSecs!\"days\"(hnsecs);\n        immutable negative = hnsecs < 0;\n\n        if (negative)\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n\n        immutable seconds = splitUnitsFromHNSecs!\"seconds\"(hnsecs);\n        hnsecs += convert!(units, \"hnsecs\")(value);\n        hnsecs %= convert!(\"seconds\", \"hnsecs\")(1);\n\n        if (hnsecs < 0)\n            hnsecs += convert!(\"seconds\", \"hnsecs\")(1);\n        hnsecs += convert!(\"seconds\", \"hnsecs\")(seconds);\n\n        if (negative)\n            hnsecs -= convert!(\"hours\", \"hnsecs\")(24);\n\n        immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(days);\n        adjTime = newDaysHNSecs + hnsecs;\n        return this;\n    }\n\n\n    // Test roll!\"msecs\"().\n    @safe unittest\n    {\n        import core.time;\n        static void testST(SysTime orig, int milliseconds, SysTime expected, size_t line = __LINE__) @safe\n        {\n            orig.roll!\"msecs\"(milliseconds);\n            if (orig != expected)\n                throw new AssertError(format(\"Failed. actual [%s] != expected [%s]\", orig, expected), __FILE__, line);\n        }\n\n        // Test A.D.\n        auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274));\n        testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)));\n        testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275)));\n        testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(276)));\n        testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(284)));\n        testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(374)));\n        testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));\n        testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)));\n        testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275)));\n        testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)));\n        testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));\n        testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(1)));\n        testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));\n        testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n\n        testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273)));\n        testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(272)));\n        testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(264)));\n        testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(174)));\n        testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));\n        testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)));\n        testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273)));\n        testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)));\n        testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));\n        testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));\n\n        // Test B.C.\n        auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274));\n        testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)));\n        testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275)));\n        testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(276)));\n        testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(284)));\n        testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(374)));\n        testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));\n        testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n        testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)));\n        testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275)));\n        testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)));\n        testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));\n        testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n        testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(1)));\n        testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));\n        testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n\n        testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273)));\n        testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(272)));\n        testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(264)));\n        testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(174)));\n        testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n        testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));\n        testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)));\n        testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273)));\n        testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)));\n        testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n        testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));\n        testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n        testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));\n\n        // Test Both\n        auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n        testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(1)));\n        testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(999)));\n        testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(998)));\n        testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(445)));\n\n        auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n        testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_989_999)));\n        testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999)));\n        testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999)));\n        testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(5_549_999)));\n\n        {\n            auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n            st.roll!\"msecs\"(1202).roll!\"msecs\"(-703);\n            assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(4_989_999)));\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.roll!\"msecs\"(4)));\n        static assert(!__traits(compiles, ist.roll!\"msecs\"(4)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.roll!\"msecs\"(42);\n        }\n    }\n\n    // Test roll!\"usecs\"().\n    @safe unittest\n    {\n        import core.time;\n        static void testST(SysTime orig, long microseconds, SysTime expected, size_t line = __LINE__) @safe\n        {\n            orig.roll!\"usecs\"(microseconds);\n            if (orig != expected)\n                throw new AssertError(format(\"Failed. actual [%s] != expected [%s]\", orig, expected), __FILE__, line);\n        }\n\n        // Test A.D.\n        auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274));\n        testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));\n        testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(275)));\n        testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(276)));\n        testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(284)));\n        testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(374)));\n        testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999)));\n        testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1000)));\n        testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1274)));\n        testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1275)));\n        testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(2274)));\n        testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(26_999)));\n        testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_000)));\n        testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_001)));\n        testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(766_999)));\n        testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(767_000)));\n        testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));\n        testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));\n        testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));\n\n        testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(273)));\n        testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(272)));\n        testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(264)));\n        testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(174)));\n        testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_999)));\n        testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_274)));\n        testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_273)));\n        testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(998_274)));\n        testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(967_000)));\n        testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(966_999)));\n        testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(167_000)));\n        testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(166_999)));\n        testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));\n        testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));\n        testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));\n\n        // Test B.C.\n        auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274));\n        testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));\n        testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(275)));\n        testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(276)));\n        testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(284)));\n        testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(374)));\n        testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999)));\n        testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1000)));\n        testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1274)));\n        testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1275)));\n        testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(2274)));\n        testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(26_999)));\n        testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_000)));\n        testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_001)));\n        testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(766_999)));\n        testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(767_000)));\n        testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));\n        testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));\n        testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));\n\n        testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(273)));\n        testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(272)));\n        testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(264)));\n        testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(174)));\n        testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n        testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_999)));\n        testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_274)));\n        testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_273)));\n        testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(998_274)));\n        testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(967_000)));\n        testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(966_999)));\n        testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(167_000)));\n        testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(166_999)));\n        testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));\n        testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));\n        testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));\n\n        // Test Both\n        auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n        testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(1)));\n        testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_999)));\n        testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_998)));\n        testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_000)));\n        testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(998_000)));\n        testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(997_445)));\n        testST(beforeBoth1, -1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(beforeBoth1, -2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(beforeBoth1, -2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(666_667)));\n\n        auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n        testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_989)));\n        testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9)));\n        testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19)));\n        testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999)));\n        testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999)));\n        testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(25_549)));\n        testST(beforeBoth2, 1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(beforeBoth2, 2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(beforeBoth2, 2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(3_333_329)));\n\n        {\n            auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n            st.roll!\"usecs\"(9_020_027);\n            assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(200_269)));\n        }\n\n        {\n            auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n            st.roll!\"usecs\"(9_020_027).roll!\"usecs\"(-70_034);\n            assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_499_929)));\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.roll!\"usecs\"(4)));\n        static assert(!__traits(compiles, ist.roll!\"usecs\"(4)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.roll!\"usecs\"(42);\n        }\n    }\n\n    // Test roll!\"hnsecs\"().\n    @safe unittest\n    {\n        import core.time;\n        static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe\n        {\n            orig.roll!\"hnsecs\"(hnsecs);\n            if (orig != expected)\n                throw new AssertError(format(\"Failed. actual [%s] != expected [%s]\", orig, expected), __FILE__, line);\n        }\n\n        // Test A.D.\n        auto dtAD = DateTime(1999, 7, 6, 12, 30, 33);\n        auto beforeAD = SysTime(dtAD, hnsecs(274));\n        testST(beforeAD, 0, SysTime(dtAD, hnsecs(274)));\n        testST(beforeAD, 1, SysTime(dtAD, hnsecs(275)));\n        testST(beforeAD, 2, SysTime(dtAD, hnsecs(276)));\n        testST(beforeAD, 10, SysTime(dtAD, hnsecs(284)));\n        testST(beforeAD, 100, SysTime(dtAD, hnsecs(374)));\n        testST(beforeAD, 725, SysTime(dtAD, hnsecs(999)));\n        testST(beforeAD, 726, SysTime(dtAD, hnsecs(1000)));\n        testST(beforeAD, 1000, SysTime(dtAD, hnsecs(1274)));\n        testST(beforeAD, 1001, SysTime(dtAD, hnsecs(1275)));\n        testST(beforeAD, 2000, SysTime(dtAD, hnsecs(2274)));\n        testST(beforeAD, 26_725, SysTime(dtAD, hnsecs(26_999)));\n        testST(beforeAD, 26_726, SysTime(dtAD, hnsecs(27_000)));\n        testST(beforeAD, 26_727, SysTime(dtAD, hnsecs(27_001)));\n        testST(beforeAD, 1_766_725, SysTime(dtAD, hnsecs(1_766_999)));\n        testST(beforeAD, 1_766_726, SysTime(dtAD, hnsecs(1_767_000)));\n        testST(beforeAD, 1_000_000, SysTime(dtAD, hnsecs(1_000_274)));\n        testST(beforeAD, 60_000_000L, SysTime(dtAD, hnsecs(274)));\n        testST(beforeAD, 3_600_000_000L, SysTime(dtAD, hnsecs(274)));\n        testST(beforeAD, 600_000_000L, SysTime(dtAD, hnsecs(274)));\n        testST(beforeAD, 36_000_000_000L, SysTime(dtAD, hnsecs(274)));\n\n        testST(beforeAD, -1, SysTime(dtAD, hnsecs(273)));\n        testST(beforeAD, -2, SysTime(dtAD, hnsecs(272)));\n        testST(beforeAD, -10, SysTime(dtAD, hnsecs(264)));\n        testST(beforeAD, -100, SysTime(dtAD, hnsecs(174)));\n        testST(beforeAD, -274, SysTime(dtAD));\n        testST(beforeAD, -275, SysTime(dtAD, hnsecs(9_999_999)));\n        testST(beforeAD, -1000, SysTime(dtAD, hnsecs(9_999_274)));\n        testST(beforeAD, -1001, SysTime(dtAD, hnsecs(9_999_273)));\n        testST(beforeAD, -2000, SysTime(dtAD, hnsecs(9_998_274)));\n        testST(beforeAD, -33_274, SysTime(dtAD, hnsecs(9_967_000)));\n        testST(beforeAD, -33_275, SysTime(dtAD, hnsecs(9_966_999)));\n        testST(beforeAD, -1_833_274, SysTime(dtAD, hnsecs(8_167_000)));\n        testST(beforeAD, -1_833_275, SysTime(dtAD, hnsecs(8_166_999)));\n        testST(beforeAD, -1_000_000, SysTime(dtAD, hnsecs(9_000_274)));\n        testST(beforeAD, -60_000_000L, SysTime(dtAD, hnsecs(274)));\n        testST(beforeAD, -3_600_000_000L, SysTime(dtAD, hnsecs(274)));\n        testST(beforeAD, -600_000_000L, SysTime(dtAD, hnsecs(274)));\n        testST(beforeAD, -36_000_000_000L, SysTime(dtAD, hnsecs(274)));\n\n        // Test B.C.\n        auto dtBC = DateTime(-1999, 7, 6, 12, 30, 33);\n        auto beforeBC = SysTime(dtBC, hnsecs(274));\n        testST(beforeBC, 0, SysTime(dtBC, hnsecs(274)));\n        testST(beforeBC, 1, SysTime(dtBC, hnsecs(275)));\n        testST(beforeBC, 2, SysTime(dtBC, hnsecs(276)));\n        testST(beforeBC, 10, SysTime(dtBC, hnsecs(284)));\n        testST(beforeBC, 100, SysTime(dtBC, hnsecs(374)));\n        testST(beforeBC, 725, SysTime(dtBC, hnsecs(999)));\n        testST(beforeBC, 726, SysTime(dtBC, hnsecs(1000)));\n        testST(beforeBC, 1000, SysTime(dtBC, hnsecs(1274)));\n        testST(beforeBC, 1001, SysTime(dtBC, hnsecs(1275)));\n        testST(beforeBC, 2000, SysTime(dtBC, hnsecs(2274)));\n        testST(beforeBC, 26_725, SysTime(dtBC, hnsecs(26_999)));\n        testST(beforeBC, 26_726, SysTime(dtBC, hnsecs(27_000)));\n        testST(beforeBC, 26_727, SysTime(dtBC, hnsecs(27_001)));\n        testST(beforeBC, 1_766_725, SysTime(dtBC, hnsecs(1_766_999)));\n        testST(beforeBC, 1_766_726, SysTime(dtBC, hnsecs(1_767_000)));\n        testST(beforeBC, 1_000_000, SysTime(dtBC, hnsecs(1_000_274)));\n        testST(beforeBC, 60_000_000L, SysTime(dtBC, hnsecs(274)));\n        testST(beforeBC, 3_600_000_000L, SysTime(dtBC, hnsecs(274)));\n        testST(beforeBC, 600_000_000L, SysTime(dtBC, hnsecs(274)));\n        testST(beforeBC, 36_000_000_000L, SysTime(dtBC, hnsecs(274)));\n\n        testST(beforeBC, -1, SysTime(dtBC, hnsecs(273)));\n        testST(beforeBC, -2, SysTime(dtBC, hnsecs(272)));\n        testST(beforeBC, -10, SysTime(dtBC, hnsecs(264)));\n        testST(beforeBC, -100, SysTime(dtBC, hnsecs(174)));\n        testST(beforeBC, -274, SysTime(dtBC));\n        testST(beforeBC, -275, SysTime(dtBC, hnsecs(9_999_999)));\n        testST(beforeBC, -1000, SysTime(dtBC, hnsecs(9_999_274)));\n        testST(beforeBC, -1001, SysTime(dtBC, hnsecs(9_999_273)));\n        testST(beforeBC, -2000, SysTime(dtBC, hnsecs(9_998_274)));\n        testST(beforeBC, -33_274, SysTime(dtBC, hnsecs(9_967_000)));\n        testST(beforeBC, -33_275, SysTime(dtBC, hnsecs(9_966_999)));\n        testST(beforeBC, -1_833_274, SysTime(dtBC, hnsecs(8_167_000)));\n        testST(beforeBC, -1_833_275, SysTime(dtBC, hnsecs(8_166_999)));\n        testST(beforeBC, -1_000_000, SysTime(dtBC, hnsecs(9_000_274)));\n        testST(beforeBC, -60_000_000L, SysTime(dtBC, hnsecs(274)));\n        testST(beforeBC, -3_600_000_000L, SysTime(dtBC, hnsecs(274)));\n        testST(beforeBC, -600_000_000L, SysTime(dtBC, hnsecs(274)));\n        testST(beforeBC, -36_000_000_000L, SysTime(dtBC, hnsecs(274)));\n\n        // Test Both\n        auto dtBoth1 = DateTime(1, 1, 1, 0, 0, 0);\n        auto beforeBoth1 = SysTime(dtBoth1);\n        testST(beforeBoth1, 1, SysTime(dtBoth1, hnsecs(1)));\n        testST(beforeBoth1, 0, SysTime(dtBoth1));\n        testST(beforeBoth1, -1, SysTime(dtBoth1, hnsecs(9_999_999)));\n        testST(beforeBoth1, -2, SysTime(dtBoth1, hnsecs(9_999_998)));\n        testST(beforeBoth1, -1000, SysTime(dtBoth1, hnsecs(9_999_000)));\n        testST(beforeBoth1, -2000, SysTime(dtBoth1, hnsecs(9_998_000)));\n        testST(beforeBoth1, -2555, SysTime(dtBoth1, hnsecs(9_997_445)));\n        testST(beforeBoth1, -1_000_000, SysTime(dtBoth1, hnsecs(9_000_000)));\n        testST(beforeBoth1, -2_000_000, SysTime(dtBoth1, hnsecs(8_000_000)));\n        testST(beforeBoth1, -2_333_333, SysTime(dtBoth1, hnsecs(7_666_667)));\n        testST(beforeBoth1, -10_000_000, SysTime(dtBoth1));\n        testST(beforeBoth1, -20_000_000, SysTime(dtBoth1));\n        testST(beforeBoth1, -20_888_888, SysTime(dtBoth1, hnsecs(9_111_112)));\n\n        auto dtBoth2 = DateTime(0, 12, 31, 23, 59, 59);\n        auto beforeBoth2 = SysTime(dtBoth2, hnsecs(9_999_999));\n        testST(beforeBoth2, -1, SysTime(dtBoth2, hnsecs(9_999_998)));\n        testST(beforeBoth2, 0, SysTime(dtBoth2, hnsecs(9_999_999)));\n        testST(beforeBoth2, 1, SysTime(dtBoth2));\n        testST(beforeBoth2, 2, SysTime(dtBoth2, hnsecs(1)));\n        testST(beforeBoth2, 1000, SysTime(dtBoth2, hnsecs(999)));\n        testST(beforeBoth2, 2000, SysTime(dtBoth2, hnsecs(1999)));\n        testST(beforeBoth2, 2555, SysTime(dtBoth2, hnsecs(2554)));\n        testST(beforeBoth2, 1_000_000, SysTime(dtBoth2, hnsecs(999_999)));\n        testST(beforeBoth2, 2_000_000, SysTime(dtBoth2, hnsecs(1_999_999)));\n        testST(beforeBoth2, 2_333_333, SysTime(dtBoth2, hnsecs(2_333_332)));\n        testST(beforeBoth2, 10_000_000, SysTime(dtBoth2, hnsecs(9_999_999)));\n        testST(beforeBoth2, 20_000_000, SysTime(dtBoth2, hnsecs(9_999_999)));\n        testST(beforeBoth2, 20_888_888, SysTime(dtBoth2, hnsecs(888_887)));\n\n        {\n            auto st = SysTime(dtBoth2, hnsecs(9_999_999));\n            st.roll!\"hnsecs\"(70_777_222).roll!\"hnsecs\"(-222_555_292);\n            assert(st == SysTime(dtBoth2, hnsecs(8_221_929)));\n        }\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.roll!\"hnsecs\"(4)));\n        static assert(!__traits(compiles, ist.roll!\"hnsecs\"(4)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.roll!\"hnsecs\"(42);\n        }\n    }\n\n\n    /++\n        Gives the result of adding or subtracting a $(REF Duration, core,time)\n        from this $(LREF SysTime).\n\n        The legal types of arithmetic for $(LREF SysTime) using this operator\n        are\n\n        $(BOOKTABLE,\n        $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime))\n        $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime))\n        )\n\n        Params:\n            duration = The $(REF Duration, core,time) to add to or subtract from\n                       this $(LREF SysTime).\n      +/\n    SysTime opBinary(string op)(Duration duration) @safe const pure nothrow scope\n        if (op == \"+\" || op == \"-\")\n    {\n        SysTime retval = SysTime(this._stdTime, this._timezone);\n        immutable hnsecs = duration.total!\"hnsecs\";\n        mixin(\"retval._stdTime \" ~ op ~ \"= hnsecs;\");\n        return retval;\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : hours, seconds;\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + seconds(1) ==\n               SysTime(DateTime(2016, 1, 1, 0, 0, 0)));\n\n        assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + hours(1) ==\n               SysTime(DateTime(2016, 1, 1, 0, 59, 59)));\n\n        assert(SysTime(DateTime(2016, 1, 1, 0, 0, 0)) - seconds(1) ==\n               SysTime(DateTime(2015, 12, 31, 23, 59, 59)));\n\n        assert(SysTime(DateTime(2016, 1, 1, 0, 59, 59)) - hours(1) ==\n               SysTime(DateTime(2015, 12, 31, 23, 59, 59)));\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_678));\n\n        assert(st + dur!\"weeks\"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678)));\n        assert(st + dur!\"weeks\"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678)));\n        assert(st + dur!\"days\"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678)));\n        assert(st + dur!\"days\"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678)));\n        assert(st + dur!\"hours\"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678)));\n        assert(st + dur!\"hours\"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678)));\n        assert(st + dur!\"minutes\"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678)));\n        assert(st + dur!\"minutes\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678)));\n        assert(st + dur!\"seconds\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678)));\n        assert(st + dur!\"seconds\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678)));\n        assert(st + dur!\"msecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678)));\n        assert(st + dur!\"msecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678)));\n        assert(st + dur!\"usecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748)));\n        assert(st + dur!\"usecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608)));\n        assert(st + dur!\"hnsecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685)));\n        assert(st + dur!\"hnsecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671)));\n\n        assert(st - dur!\"weeks\"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678)));\n        assert(st - dur!\"weeks\"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678)));\n        assert(st - dur!\"days\"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678)));\n        assert(st - dur!\"days\"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678)));\n        assert(st - dur!\"hours\"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678)));\n        assert(st - dur!\"hours\"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678)));\n        assert(st - dur!\"minutes\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678)));\n        assert(st - dur!\"minutes\"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678)));\n        assert(st - dur!\"seconds\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678)));\n        assert(st - dur!\"seconds\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678)));\n        assert(st - dur!\"msecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678)));\n        assert(st - dur!\"msecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678)));\n        assert(st - dur!\"usecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748)));\n        assert(st - dur!\"usecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608)));\n        assert(st - dur!\"hnsecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685)));\n        assert(st - dur!\"hnsecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671)));\n\n        static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe\n        {\n            auto result = orig + dur!\"hnsecs\"(hnsecs);\n            if (result != expected)\n                throw new AssertError(format(\"Failed. actual [%s] != expected [%s]\", result, expected), __FILE__, line);\n        }\n\n        // Test A.D.\n        auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274));\n        testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)));\n        testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275)));\n        testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276)));\n        testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284)));\n        testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374)));\n        testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999)));\n        testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000)));\n        testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274)));\n        testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275)));\n        testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274)));\n        testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999)));\n        testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000)));\n        testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001)));\n        testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999)));\n        testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000)));\n        testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274)));\n        testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274)));\n        testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274)));\n        testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274)));\n        testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274)));\n\n        testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273)));\n        testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272)));\n        testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264)));\n        testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174)));\n        testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999)));\n        testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274)));\n        testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273)));\n        testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274)));\n        testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000)));\n        testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999)));\n        testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000)));\n        testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999)));\n        testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274)));\n        testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274)));\n        testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274)));\n        testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274)));\n        testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274)));\n\n        // Test B.C.\n        auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274));\n        testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)));\n        testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275)));\n        testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276)));\n        testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284)));\n        testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374)));\n        testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999)));\n        testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000)));\n        testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274)));\n        testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275)));\n        testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274)));\n        testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999)));\n        testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000)));\n        testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001)));\n        testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999)));\n        testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000)));\n        testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274)));\n        testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274)));\n        testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274)));\n        testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274)));\n        testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274)));\n\n        testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273)));\n        testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272)));\n        testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264)));\n        testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174)));\n        testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n        testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999)));\n        testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274)));\n        testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273)));\n        testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274)));\n        testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000)));\n        testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999)));\n        testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000)));\n        testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999)));\n        testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274)));\n        testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274)));\n        testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274)));\n        testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274)));\n        testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274)));\n\n        // Test Both\n        auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n        testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));\n        testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)));\n        testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000)));\n        testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000)));\n        testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445)));\n        testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000)));\n        testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000)));\n        testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667)));\n        testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59)));\n        testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58)));\n        testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112)));\n\n        auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n        testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)));\n        testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));\n        testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999)));\n        testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999)));\n        testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554)));\n        testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999)));\n        testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999)));\n        testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332)));\n        testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999)));\n        testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999)));\n        testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887)));\n\n        auto duration = dur!\"seconds\"(12);\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45)));\n        assert(ist + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45)));\n        assert(cst - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21)));\n        assert(ist - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21)));\n\n        static void testScope(scope ref SysTime st, scope ref Duration d) @safe\n        {\n            auto result = st + d;\n        }\n    }\n\n\n    /++\n        Gives the result of adding or subtracting a $(REF Duration, core,time) from\n        this $(LREF SysTime), as well as assigning the result to this\n        $(LREF SysTime).\n\n        The legal types of arithmetic for $(LREF SysTime) using this operator are\n\n        $(BOOKTABLE,\n        $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime))\n        $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime))\n        )\n\n        Params:\n            duration = The $(REF Duration, core,time) to add to or subtract from\n                       this $(LREF SysTime).\n      +/\n    ref SysTime opOpAssign(string op)(Duration duration) @safe pure nothrow scope\n        if (op == \"+\" || op == \"-\")\n    {\n        immutable hnsecs = duration.total!\"hnsecs\";\n        mixin(\"_stdTime \" ~ op ~ \"= hnsecs;\");\n        return this;\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        auto before = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(before + dur!\"weeks\"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33)));\n        assert(before + dur!\"weeks\"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33)));\n        assert(before + dur!\"days\"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33)));\n        assert(before + dur!\"days\"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33)));\n\n        assert(before + dur!\"hours\"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33)));\n        assert(before + dur!\"hours\"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33)));\n        assert(before + dur!\"minutes\"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33)));\n        assert(before + dur!\"minutes\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33)));\n        assert(before + dur!\"seconds\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40)));\n        assert(before + dur!\"seconds\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26)));\n        assert(before + dur!\"msecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7)));\n        assert(before + dur!\"msecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993)));\n        assert(before + dur!\"usecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7)));\n        assert(before + dur!\"usecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993)));\n        assert(before + dur!\"hnsecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7)));\n        assert(before + dur!\"hnsecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993)));\n\n        assert(before - dur!\"weeks\"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33)));\n        assert(before - dur!\"weeks\"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33)));\n        assert(before - dur!\"days\"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33)));\n        assert(before - dur!\"days\"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33)));\n\n        assert(before - dur!\"hours\"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33)));\n        assert(before - dur!\"hours\"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33)));\n        assert(before - dur!\"minutes\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33)));\n        assert(before - dur!\"minutes\"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33)));\n        assert(before - dur!\"seconds\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40)));\n        assert(before - dur!\"seconds\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26)));\n        assert(before - dur!\"msecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7)));\n        assert(before - dur!\"msecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993)));\n        assert(before - dur!\"usecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7)));\n        assert(before - dur!\"usecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993)));\n        assert(before - dur!\"hnsecs\"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7)));\n        assert(before - dur!\"hnsecs\"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993)));\n\n        static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe\n        {\n            auto r = orig += dur!\"hnsecs\"(hnsecs);\n            if (orig != expected)\n                throw new AssertError(format(\"Failed 1. actual [%s] != expected [%s]\", orig, expected), __FILE__, line);\n            if (r != expected)\n                throw new AssertError(format(\"Failed 2. actual [%s] != expected [%s]\", r, expected), __FILE__, line);\n        }\n\n        // Test A.D.\n        auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274));\n        testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)));\n        testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275)));\n        testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276)));\n        testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284)));\n        testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374)));\n        testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999)));\n        testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000)));\n        testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274)));\n        testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275)));\n        testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274)));\n        testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999)));\n        testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000)));\n        testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001)));\n        testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999)));\n        testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000)));\n        testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274)));\n        testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274)));\n        testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274)));\n        testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274)));\n        testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274)));\n\n        testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273)));\n        testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272)));\n        testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264)));\n        testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174)));\n        testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999)));\n        testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274)));\n        testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273)));\n        testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274)));\n        testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000)));\n        testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999)));\n        testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000)));\n        testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999)));\n        testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274)));\n        testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274)));\n        testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274)));\n        testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274)));\n        testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274)));\n\n        // Test B.C.\n        auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274));\n        testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)));\n        testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275)));\n        testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276)));\n        testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284)));\n        testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374)));\n        testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999)));\n        testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000)));\n        testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274)));\n        testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275)));\n        testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274)));\n        testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999)));\n        testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000)));\n        testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001)));\n        testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999)));\n        testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000)));\n        testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274)));\n        testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274)));\n        testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274)));\n        testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274)));\n        testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274)));\n\n        testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273)));\n        testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272)));\n        testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264)));\n        testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174)));\n        testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n        testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999)));\n        testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274)));\n        testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273)));\n        testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274)));\n        testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000)));\n        testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999)));\n        testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000)));\n        testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999)));\n        testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274)));\n        testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274)));\n        testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274)));\n        testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274)));\n        testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274)));\n\n        // Test Both\n        auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0));\n        testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));\n        testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)));\n        testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000)));\n        testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000)));\n        testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445)));\n        testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000)));\n        testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000)));\n        testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667)));\n        testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59)));\n        testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58)));\n        testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112)));\n\n        auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n        testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)));\n        testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));\n        testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999)));\n        testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999)));\n        testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554)));\n        testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999)));\n        testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999)));\n        testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332)));\n        testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999)));\n        testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999)));\n        testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887)));\n\n        {\n            auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));\n            (st += dur!\"hnsecs\"(52)) += dur!\"seconds\"(-907);\n            assert(st == SysTime(DateTime(0, 12, 31, 23, 44, 53), hnsecs(51)));\n        }\n\n        auto duration = dur!\"seconds\"(12);\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst += duration));\n        static assert(!__traits(compiles, ist += duration));\n        static assert(!__traits(compiles, cst -= duration));\n        static assert(!__traits(compiles, ist -= duration));\n\n        static void testScope(scope ref SysTime st, scope ref Duration d) @safe\n        {\n            auto result1 = st += d;\n            auto result2 = st -= d;\n        }\n    }\n\n\n    /++\n        Gives the difference between two $(LREF SysTime)s.\n\n        The legal types of arithmetic for $(LREF SysTime) using this operator\n        are\n\n        $(BOOKTABLE,\n        $(TR $(TD SysTime) $(TD -) $(TD SysTime) $(TD -->) $(TD duration))\n        )\n      +/\n    Duration opBinary(string op)(SysTime rhs) @safe const pure nothrow scope\n        if (op == \"-\")\n    {\n        return dur!\"hnsecs\"(_stdTime - rhs._stdTime);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1998, 7, 6, 12, 30, 33)) ==\n               dur!\"seconds\"(31_536_000));\n        assert(SysTime(DateTime(1998, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==\n               dur!\"seconds\"(-31_536_000));\n\n        assert(SysTime(DateTime(1999, 8, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==\n               dur!\"seconds\"(26_78_400));\n        assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 8, 6, 12, 30, 33)) ==\n               dur!\"seconds\"(-26_78_400));\n\n        assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 5, 12, 30, 33)) ==\n               dur!\"seconds\"(86_400));\n        assert(SysTime(DateTime(1999, 7, 5, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==\n               dur!\"seconds\"(-86_400));\n\n        assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 11, 30, 33)) ==\n               dur!\"seconds\"(3600));\n        assert(SysTime(DateTime(1999, 7, 6, 11, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==\n               dur!\"seconds\"(-3600));\n\n        assert(SysTime(DateTime(1999, 7, 6, 12, 31, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==\n               dur!\"seconds\"(60));\n        assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 31, 33)) ==\n               dur!\"seconds\"(-60));\n\n        assert(SysTime(DateTime(1999, 7, 6, 12, 30, 34)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==\n               dur!\"seconds\"(1));\n        assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 34)) ==\n               dur!\"seconds\"(-1));\n\n        {\n            auto dt = DateTime(1999, 7, 6, 12, 30, 33);\n            assert(SysTime(dt, msecs(532)) - SysTime(dt) == msecs(532));\n            assert(SysTime(dt) - SysTime(dt, msecs(532)) == msecs(-532));\n\n            assert(SysTime(dt, usecs(333_347)) - SysTime(dt) == usecs(333_347));\n            assert(SysTime(dt) - SysTime(dt, usecs(333_347)) == usecs(-333_347));\n\n            assert(SysTime(dt, hnsecs(1_234_567)) - SysTime(dt) == hnsecs(1_234_567));\n            assert(SysTime(dt) - SysTime(dt, hnsecs(1_234_567)) == hnsecs(-1_234_567));\n        }\n\n        assert(SysTime(DateTime(1, 1, 1, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!\"seconds\"(45033));\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(1, 1, 1, 12, 30, 33)) == dur!\"seconds\"(-45033));\n        assert(SysTime(DateTime(0, 12, 31, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!\"seconds\"(-41367));\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 12, 30, 33)) == dur!\"seconds\"(41367));\n\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) ==\n               dur!\"hnsecs\"(1));\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) ==\n               dur!\"hnsecs\"(-1));\n\n        version (Posix)\n        {\n            import std.datetime.timezone : PosixTimeZone;\n            immutable tz = PosixTimeZone.getTimeZone(\"America/Los_Angeles\");\n        }\n        else version (Windows)\n        {\n            import std.datetime.timezone : WindowsTimeZone;\n            immutable tz = WindowsTimeZone.getTimeZone(\"Pacific Standard Time\");\n        }\n\n        {\n            auto dt = DateTime(2011, 1, 13, 8, 17, 2);\n            auto d = msecs(296);\n            assert(SysTime(dt, d, tz) - SysTime(dt, d, tz) == Duration.zero);\n            assert(SysTime(dt, d, tz) - SysTime(dt, d, UTC()) == hours(8));\n            assert(SysTime(dt, d, UTC()) - SysTime(dt, d, tz) == hours(-8));\n        }\n\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(st - st == Duration.zero);\n        assert(cst - st == Duration.zero);\n        assert(ist - st == Duration.zero);\n\n        assert(st - cst == Duration.zero);\n        assert(cst - cst == Duration.zero);\n        assert(ist - cst == Duration.zero);\n\n        assert(st - ist == Duration.zero);\n        assert(cst - ist == Duration.zero);\n        assert(ist - ist == Duration.zero);\n\n        static void testScope(scope ref SysTime left, scope ref SysTime right) @safe\n        {\n            auto result = left - right;\n        }\n    }\n\n\n    /++\n        Returns the difference between the two $(LREF SysTime)s in months.\n\n        To get the difference in years, subtract the year property\n        of two $(LREF SysTime)s. To get the difference in days or weeks,\n        subtract the $(LREF SysTime)s themselves and use the\n        $(REF Duration, core,time) that results. Because converting between\n        months and smaller units requires a specific date (which\n        $(REF Duration, core,time)s don't have), getting the difference in\n        months requires some math using both the year and month properties, so\n        this is a convenience function for getting the difference in months.\n\n        Note that the number of days in the months or how far into the month\n        either date is is irrelevant. It is the difference in the month property\n        combined with the difference in years * 12. So, for instance,\n        December 31st and January 1st are one month apart just as December 1st\n        and January 31st are one month apart.\n\n        Params:\n            rhs = The $(LREF SysTime) to subtract from this one.\n      +/\n    int diffMonths(scope SysTime rhs) @safe const nothrow scope\n    {\n        return (cast(Date) this).diffMonths(cast(Date) rhs);\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time;\n        import std.datetime.date : Date;\n\n        assert(SysTime(Date(1999, 2, 1)).diffMonths(\n                   SysTime(Date(1999, 1, 31))) == 1);\n\n        assert(SysTime(Date(1999, 1, 31)).diffMonths(\n                   SysTime(Date(1999, 2, 1))) == -1);\n\n        assert(SysTime(Date(1999, 3, 1)).diffMonths(\n                   SysTime(Date(1999, 1, 1))) == 2);\n\n        assert(SysTime(Date(1999, 1, 1)).diffMonths(\n                   SysTime(Date(1999, 3, 31))) == -2);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(st.diffMonths(st) == 0);\n        assert(cst.diffMonths(st) == 0);\n        assert(ist.diffMonths(st) == 0);\n\n        assert(st.diffMonths(cst) == 0);\n        assert(cst.diffMonths(cst) == 0);\n        assert(ist.diffMonths(cst) == 0);\n\n        assert(st.diffMonths(ist) == 0);\n        assert(cst.diffMonths(ist) == 0);\n        assert(ist.diffMonths(ist) == 0);\n\n        static void testScope(scope ref SysTime left, scope ref SysTime right) @safe\n        {\n            auto result = left.diffMonths(right);\n        }\n    }\n\n\n    /++\n        Whether this $(LREF SysTime) is in a leap year.\n     +/\n    @property bool isLeapYear() @safe const nothrow scope\n    {\n        return (cast(Date) this).isLeapYear;\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(!st.isLeapYear);\n        assert(!cst.isLeapYear);\n        assert(!ist.isLeapYear);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.isLeapYear;\n        }\n    }\n\n\n    /++\n        Day of the week this $(LREF SysTime) is on.\n      +/\n    @property DayOfWeek dayOfWeek() @safe const nothrow scope\n    {\n        return getDayOfWeek(dayOfGregorianCal);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(st.dayOfWeek == DayOfWeek.tue);\n        assert(cst.dayOfWeek == DayOfWeek.tue);\n        assert(ist.dayOfWeek == DayOfWeek.tue);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.dayOfWeek;\n        }\n    }\n\n\n    /++\n        Day of the year this $(LREF SysTime) is on.\n      +/\n    @property ushort dayOfYear() @safe const nothrow scope\n    {\n        return (cast(Date) this).dayOfYear;\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time;\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(1999, 1, 1, 12, 22, 7)).dayOfYear == 1);\n        assert(SysTime(DateTime(1999, 12, 31, 7, 2, 59)).dayOfYear == 365);\n        assert(SysTime(DateTime(2000, 12, 31, 21, 20, 0)).dayOfYear == 366);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(st.dayOfYear == 187);\n        assert(cst.dayOfYear == 187);\n        assert(ist.dayOfYear == 187);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.dayOfYear;\n        }\n    }\n\n\n    /++\n        Day of the year.\n\n        Params:\n            day = The day of the year to set which day of the year this\n                  $(LREF SysTime) is on.\n      +/\n    @property void dayOfYear(int day) @safe scope\n    {\n        immutable hnsecs = adjTime;\n        immutable days = convert!(\"hnsecs\", \"days\")(hnsecs);\n        immutable theRest = hnsecs - convert!(\"days\", \"hnsecs\")(days);\n\n        auto date = Date(cast(int) days);\n        date.dayOfYear = day;\n\n        immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(date.dayOfGregorianCal - 1);\n\n        adjTime = newDaysHNSecs + theRest;\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        st.dayOfYear = 12;\n        assert(st.dayOfYear == 12);\n        static assert(!__traits(compiles, cst.dayOfYear = 12));\n        static assert(!__traits(compiles, ist.dayOfYear = 12));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.dayOfYear = 42;\n        }\n    }\n\n\n    /++\n        The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on.\n     +/\n    @property int dayOfGregorianCal() @safe const nothrow scope\n    {\n        immutable adjustedTime = adjTime;\n\n        // We have to add one because 0 would be midnight, January 1st, 1 A.D.,\n        // which would be the 1st day of the Gregorian Calendar, not the 0th. So,\n        // simply casting to days is one day off.\n        if (adjustedTime > 0)\n            return cast(int) getUnitsFromHNSecs!\"days\"(adjustedTime) + 1;\n\n        long hnsecs = adjustedTime;\n        immutable days = cast(int) splitUnitsFromHNSecs!\"days\"(hnsecs);\n\n        return hnsecs == 0 ? days + 1 : days;\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time;\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1);\n        assert(SysTime(DateTime(1, 12, 31, 23, 59, 59)).dayOfGregorianCal == 365);\n        assert(SysTime(DateTime(2, 1, 1, 2, 2, 2)).dayOfGregorianCal == 366);\n\n        assert(SysTime(DateTime(0, 12, 31, 7, 7, 7)).dayOfGregorianCal == 0);\n        assert(SysTime(DateTime(0, 1, 1, 19, 30, 0)).dayOfGregorianCal == -365);\n        assert(SysTime(DateTime(-1, 12, 31, 4, 7, 0)).dayOfGregorianCal == -366);\n\n        assert(SysTime(DateTime(2000, 1, 1, 9, 30, 20)).dayOfGregorianCal == 730_120);\n        assert(SysTime(DateTime(2010, 12, 31, 15, 45, 50)).dayOfGregorianCal == 734_137);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1);\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 1);\n        assert(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 1);\n\n        assert(SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1);\n        assert(SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212)).dayOfGregorianCal == 2);\n        assert(SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 32);\n        assert(SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 366);\n        assert(SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 731);\n        assert(SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1096);\n        assert(SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1462);\n        assert(SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 17_898);\n        assert(SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 35_065);\n        assert(SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_160);\n        assert(SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_525);\n        assert(SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 37_986);\n        assert(SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 72_684);\n        assert(SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 73_049);\n        assert(SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_208);\n        assert(SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_573);\n        assert(SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 145_732);\n        assert(SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 146_098);\n        assert(SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_257);\n        assert(SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_622);\n        assert(SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 364_878);\n        assert(SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 365_243);\n        assert(SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_023);\n        assert(SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_389);\n        assert(SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_596);\n        assert(SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_961);\n        assert(SysTime(DateTime(1945, 11, 12, 12, 2, 9), msecs(212)).dayOfGregorianCal == 710_347);\n        assert(SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 729_755);\n        assert(SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_120);\n        assert(SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_486);\n\n        assert(SysTime(DateTime(2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_773);\n        assert(SysTime(DateTime(2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_803);\n        assert(SysTime(DateTime(2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_804);\n        assert(SysTime(DateTime(2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_831);\n        assert(SysTime(DateTime(2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_832);\n        assert(SysTime(DateTime(2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_862);\n        assert(SysTime(DateTime(2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_863);\n        assert(SysTime(DateTime(2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_892);\n        assert(SysTime(DateTime(2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_893);\n        assert(SysTime(DateTime(2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_923);\n        assert(SysTime(DateTime(2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_924);\n        assert(SysTime(DateTime(2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_953);\n        assert(SysTime(DateTime(2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_954);\n        assert(SysTime(DateTime(2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_984);\n        assert(SysTime(DateTime(2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_985);\n        assert(SysTime(DateTime(2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_015);\n        assert(SysTime(DateTime(2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_016);\n        assert(SysTime(DateTime(2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_045);\n        assert(SysTime(DateTime(2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_046);\n        assert(SysTime(DateTime(2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_076);\n        assert(SysTime(DateTime(2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_077);\n        assert(SysTime(DateTime(2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_106);\n        assert(SysTime(DateTime(2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_107);\n        assert(SysTime(DateTime(2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_137);\n\n        assert(SysTime(DateTime(2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == 734_534);\n        assert(SysTime(DateTime(2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == 734_561);\n        assert(SysTime(DateTime(2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == 734_562);\n        assert(SysTime(DateTime(2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == 734_563);\n\n        // Test B.C.\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 0);\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == 0);\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59)).dayOfGregorianCal == 0);\n        assert(SysTime(DateTime(0, 12, 31, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 0);\n        assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).dayOfGregorianCal == 0);\n\n        assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == -366);\n        assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == -366);\n        assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59)).dayOfGregorianCal == -366);\n        assert(SysTime(DateTime(-1, 12, 31, 0, 0, 0)).dayOfGregorianCal == -366);\n\n        assert(SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == 0);\n        assert(SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1);\n        assert(SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -30);\n        assert(SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -31);\n\n        assert(SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -366);\n        assert(SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -367);\n        assert(SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730);\n        assert(SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731);\n        assert(SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1095);\n        assert(SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1096);\n        assert(SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1460);\n        assert(SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1461);\n        assert(SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1826);\n        assert(SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1827);\n        assert(SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -2191);\n        assert(SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -3652);\n\n        assert(SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_262);\n        assert(SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_627);\n        assert(SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -35_794);\n        assert(SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_160);\n        assert(SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_524);\n        assert(SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_889);\n        assert(SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -37_254);\n        assert(SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -38_715);\n        assert(SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_413);\n        assert(SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_778);\n        assert(SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -109_937);\n        assert(SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -110_302);\n        assert(SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_097);\n        assert(SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_462);\n        assert(SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_827);\n        assert(SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_621);\n        assert(SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_986);\n        assert(SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -183_351);\n        assert(SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_607);\n        assert(SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_972);\n        assert(SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_387);\n        assert(SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_388);\n        assert(SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_753);\n        assert(SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -585_118);\n        assert(SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_325);\n        assert(SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_690);\n        assert(SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_484);\n        assert(SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_485);\n        assert(SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_850);\n        assert(SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731_215);\n\n        assert(SysTime(DateTime(-2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_502);\n        assert(SysTime(DateTime(-2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_472);\n        assert(SysTime(DateTime(-2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_471);\n        assert(SysTime(DateTime(-2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_444);\n        assert(SysTime(DateTime(-2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_443);\n        assert(SysTime(DateTime(-2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_413);\n        assert(SysTime(DateTime(-2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_412);\n        assert(SysTime(DateTime(-2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_383);\n        assert(SysTime(DateTime(-2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_382);\n        assert(SysTime(DateTime(-2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_352);\n        assert(SysTime(DateTime(-2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_351);\n        assert(SysTime(DateTime(-2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_322);\n        assert(SysTime(DateTime(-2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_321);\n        assert(SysTime(DateTime(-2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_291);\n        assert(SysTime(DateTime(-2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_290);\n        assert(SysTime(DateTime(-2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_260);\n        assert(SysTime(DateTime(-2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_259);\n        assert(SysTime(DateTime(-2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_230);\n        assert(SysTime(DateTime(-2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_229);\n        assert(SysTime(DateTime(-2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_199);\n        assert(SysTime(DateTime(-2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_198);\n        assert(SysTime(DateTime(-2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_169);\n        assert(SysTime(DateTime(-2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_168);\n        assert(SysTime(DateTime(-2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_138);\n\n        assert(SysTime(DateTime(-2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == -735_202);\n        assert(SysTime(DateTime(-2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == -735_175);\n        assert(SysTime(DateTime(-2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == -735_174);\n        assert(SysTime(DateTime(-2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == -735_173);\n\n        // Start of Hebrew Calendar\n        assert(SysTime(DateTime(-3760, 9, 7, 0, 0, 0)).dayOfGregorianCal == -1_373_427);\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.dayOfGregorianCal == 729_941);\n        assert(ist.dayOfGregorianCal == 729_941);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.dayOfGregorianCal;\n        }\n    }\n\n\n    // Test that the logic for the day of the Gregorian Calendar is consistent\n    // between Date and SysTime.\n    @safe unittest\n    {\n        import core.time;\n        void test(Date date, SysTime st, size_t line = __LINE__)\n        {\n            if (date.dayOfGregorianCal != st.dayOfGregorianCal)\n            {\n                throw new AssertError(format(\"Date [%s] SysTime [%s]\", date.dayOfGregorianCal, st.dayOfGregorianCal),\n                                      __FILE__, line);\n            }\n        }\n\n        // Test A.D.\n        test(Date(1, 1, 1), SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        test(Date(1, 1, 2), SysTime(DateTime(1, 1, 2, 0, 0, 0), hnsecs(500)));\n        test(Date(1, 2, 1), SysTime(DateTime(1, 2, 1, 0, 0, 0), hnsecs(50_000)));\n        test(Date(2, 1, 1), SysTime(DateTime(2, 1, 1, 0, 0, 0), hnsecs(9_999_999)));\n        test(Date(3, 1, 1), SysTime(DateTime(3, 1, 1, 12, 13, 14)));\n        test(Date(4, 1, 1), SysTime(DateTime(4, 1, 1, 12, 13, 14), hnsecs(500)));\n        test(Date(5, 1, 1), SysTime(DateTime(5, 1, 1, 12, 13, 14), hnsecs(50_000)));\n        test(Date(50, 1, 1), SysTime(DateTime(50, 1, 1, 12, 13, 14), hnsecs(9_999_999)));\n        test(Date(97, 1, 1), SysTime(DateTime(97, 1, 1, 23, 59, 59)));\n        test(Date(100, 1, 1), SysTime(DateTime(100, 1, 1, 23, 59, 59), hnsecs(500)));\n        test(Date(101, 1, 1), SysTime(DateTime(101, 1, 1, 23, 59, 59), hnsecs(50_000)));\n        test(Date(105, 1, 1), SysTime(DateTime(105, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        test(Date(200, 1, 1), SysTime(DateTime(200, 1, 1, 0, 0, 0)));\n        test(Date(201, 1, 1), SysTime(DateTime(201, 1, 1, 0, 0, 0), hnsecs(500)));\n        test(Date(300, 1, 1), SysTime(DateTime(300, 1, 1, 0, 0, 0), hnsecs(50_000)));\n        test(Date(301, 1, 1), SysTime(DateTime(301, 1, 1, 0, 0, 0), hnsecs(9_999_999)));\n        test(Date(400, 1, 1), SysTime(DateTime(400, 1, 1, 12, 13, 14)));\n        test(Date(401, 1, 1), SysTime(DateTime(401, 1, 1, 12, 13, 14), hnsecs(500)));\n        test(Date(500, 1, 1), SysTime(DateTime(500, 1, 1, 12, 13, 14), hnsecs(50_000)));\n        test(Date(501, 1, 1), SysTime(DateTime(501, 1, 1, 12, 13, 14), hnsecs(9_999_999)));\n        test(Date(1000, 1, 1), SysTime(DateTime(1000, 1, 1, 23, 59, 59)));\n        test(Date(1001, 1, 1), SysTime(DateTime(1001, 1, 1, 23, 59, 59), hnsecs(500)));\n        test(Date(1600, 1, 1), SysTime(DateTime(1600, 1, 1, 23, 59, 59), hnsecs(50_000)));\n        test(Date(1601, 1, 1), SysTime(DateTime(1601, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        test(Date(1900, 1, 1), SysTime(DateTime(1900, 1, 1, 0, 0, 0)));\n        test(Date(1901, 1, 1), SysTime(DateTime(1901, 1, 1, 0, 0, 0), hnsecs(500)));\n        test(Date(1945, 11, 12), SysTime(DateTime(1945, 11, 12, 0, 0, 0), hnsecs(50_000)));\n        test(Date(1999, 1, 1), SysTime(DateTime(1999, 1, 1, 0, 0, 0), hnsecs(9_999_999)));\n        test(Date(1999, 7, 6), SysTime(DateTime(1999, 7, 6, 12, 13, 14)));\n        test(Date(2000, 1, 1), SysTime(DateTime(2000, 1, 1, 12, 13, 14), hnsecs(500)));\n        test(Date(2001, 1, 1), SysTime(DateTime(2001, 1, 1, 12, 13, 14), hnsecs(50_000)));\n\n        test(Date(2010, 1, 1), SysTime(DateTime(2010, 1, 1, 12, 13, 14), hnsecs(9_999_999)));\n        test(Date(2010, 1, 31), SysTime(DateTime(2010, 1, 31, 23, 0, 0)));\n        test(Date(2010, 2, 1), SysTime(DateTime(2010, 2, 1, 23, 59, 59), hnsecs(500)));\n        test(Date(2010, 2, 28), SysTime(DateTime(2010, 2, 28, 23, 59, 59), hnsecs(50_000)));\n        test(Date(2010, 3, 1), SysTime(DateTime(2010, 3, 1, 23, 59, 59), hnsecs(9_999_999)));\n        test(Date(2010, 3, 31), SysTime(DateTime(2010, 3, 31, 0, 0, 0)));\n        test(Date(2010, 4, 1), SysTime(DateTime(2010, 4, 1, 0, 0, 0), hnsecs(500)));\n        test(Date(2010, 4, 30), SysTime(DateTime(2010, 4, 30, 0, 0, 0), hnsecs(50_000)));\n        test(Date(2010, 5, 1), SysTime(DateTime(2010, 5, 1, 0, 0, 0), hnsecs(9_999_999)));\n        test(Date(2010, 5, 31), SysTime(DateTime(2010, 5, 31, 12, 13, 14)));\n        test(Date(2010, 6, 1), SysTime(DateTime(2010, 6, 1, 12, 13, 14), hnsecs(500)));\n        test(Date(2010, 6, 30), SysTime(DateTime(2010, 6, 30, 12, 13, 14), hnsecs(50_000)));\n        test(Date(2010, 7, 1), SysTime(DateTime(2010, 7, 1, 12, 13, 14), hnsecs(9_999_999)));\n        test(Date(2010, 7, 31), SysTime(DateTime(2010, 7, 31, 23, 59, 59)));\n        test(Date(2010, 8, 1), SysTime(DateTime(2010, 8, 1, 23, 59, 59), hnsecs(500)));\n        test(Date(2010, 8, 31), SysTime(DateTime(2010, 8, 31, 23, 59, 59), hnsecs(50_000)));\n        test(Date(2010, 9, 1), SysTime(DateTime(2010, 9, 1, 23, 59, 59), hnsecs(9_999_999)));\n        test(Date(2010, 9, 30), SysTime(DateTime(2010, 9, 30, 12, 0, 0)));\n        test(Date(2010, 10, 1), SysTime(DateTime(2010, 10, 1, 0, 12, 0), hnsecs(500)));\n        test(Date(2010, 10, 31), SysTime(DateTime(2010, 10, 31, 0, 0, 12), hnsecs(50_000)));\n        test(Date(2010, 11, 1), SysTime(DateTime(2010, 11, 1, 23, 0, 0), hnsecs(9_999_999)));\n        test(Date(2010, 11, 30), SysTime(DateTime(2010, 11, 30, 0, 59, 0)));\n        test(Date(2010, 12, 1), SysTime(DateTime(2010, 12, 1, 0, 0, 59), hnsecs(500)));\n        test(Date(2010, 12, 31), SysTime(DateTime(2010, 12, 31, 0, 59, 59), hnsecs(50_000)));\n\n        test(Date(2012, 2, 1), SysTime(DateTime(2012, 2, 1, 23, 0, 59), hnsecs(9_999_999)));\n        test(Date(2012, 2, 28), SysTime(DateTime(2012, 2, 28, 23, 59, 0)));\n        test(Date(2012, 2, 29), SysTime(DateTime(2012, 2, 29, 7, 7, 7), hnsecs(7)));\n        test(Date(2012, 3, 1), SysTime(DateTime(2012, 3, 1, 7, 7, 7), hnsecs(7)));\n\n        // Test B.C.\n        test(Date(0, 12, 31), SysTime(DateTime(0, 12, 31, 0, 0, 0)));\n        test(Date(0, 12, 30), SysTime(DateTime(0, 12, 30, 0, 0, 0), hnsecs(500)));\n        test(Date(0, 12, 1), SysTime(DateTime(0, 12, 1, 0, 0, 0), hnsecs(50_000)));\n        test(Date(0, 11, 30), SysTime(DateTime(0, 11, 30, 0, 0, 0), hnsecs(9_999_999)));\n\n        test(Date(-1, 12, 31), SysTime(DateTime(-1, 12, 31, 12, 13, 14)));\n        test(Date(-1, 12, 30), SysTime(DateTime(-1, 12, 30, 12, 13, 14), hnsecs(500)));\n        test(Date(-1, 1, 1), SysTime(DateTime(-1, 1, 1, 12, 13, 14), hnsecs(50_000)));\n        test(Date(-2, 12, 31), SysTime(DateTime(-2, 12, 31, 12, 13, 14), hnsecs(9_999_999)));\n        test(Date(-2, 1, 1), SysTime(DateTime(-2, 1, 1, 23, 59, 59)));\n        test(Date(-3, 12, 31), SysTime(DateTime(-3, 12, 31, 23, 59, 59), hnsecs(500)));\n        test(Date(-3, 1, 1), SysTime(DateTime(-3, 1, 1, 23, 59, 59), hnsecs(50_000)));\n        test(Date(-4, 12, 31), SysTime(DateTime(-4, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        test(Date(-4, 1, 1), SysTime(DateTime(-4, 1, 1, 0, 0, 0)));\n        test(Date(-5, 12, 31), SysTime(DateTime(-5, 12, 31, 0, 0, 0), hnsecs(500)));\n        test(Date(-5, 1, 1), SysTime(DateTime(-5, 1, 1, 0, 0, 0), hnsecs(50_000)));\n        test(Date(-9, 1, 1), SysTime(DateTime(-9, 1, 1, 0, 0, 0), hnsecs(9_999_999)));\n\n        test(Date(-49, 1, 1), SysTime(DateTime(-49, 1, 1, 12, 13, 14)));\n        test(Date(-50, 1, 1), SysTime(DateTime(-50, 1, 1, 12, 13, 14), hnsecs(500)));\n        test(Date(-97, 1, 1), SysTime(DateTime(-97, 1, 1, 12, 13, 14), hnsecs(50_000)));\n        test(Date(-99, 12, 31), SysTime(DateTime(-99, 12, 31, 12, 13, 14), hnsecs(9_999_999)));\n        test(Date(-99, 1, 1), SysTime(DateTime(-99, 1, 1, 23, 59, 59)));\n        test(Date(-100, 1, 1), SysTime(DateTime(-100, 1, 1, 23, 59, 59), hnsecs(500)));\n        test(Date(-101, 1, 1), SysTime(DateTime(-101, 1, 1, 23, 59, 59), hnsecs(50_000)));\n        test(Date(-105, 1, 1), SysTime(DateTime(-105, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        test(Date(-200, 1, 1), SysTime(DateTime(-200, 1, 1, 0, 0, 0)));\n        test(Date(-201, 1, 1), SysTime(DateTime(-201, 1, 1, 0, 0, 0), hnsecs(500)));\n        test(Date(-300, 1, 1), SysTime(DateTime(-300, 1, 1, 0, 0, 0), hnsecs(50_000)));\n        test(Date(-301, 1, 1), SysTime(DateTime(-301, 1, 1, 0, 0, 0), hnsecs(9_999_999)));\n        test(Date(-400, 12, 31), SysTime(DateTime(-400, 12, 31, 12, 13, 14)));\n        test(Date(-400, 1, 1), SysTime(DateTime(-400, 1, 1, 12, 13, 14), hnsecs(500)));\n        test(Date(-401, 1, 1), SysTime(DateTime(-401, 1, 1, 12, 13, 14), hnsecs(50_000)));\n        test(Date(-499, 1, 1), SysTime(DateTime(-499, 1, 1, 12, 13, 14), hnsecs(9_999_999)));\n        test(Date(-500, 1, 1), SysTime(DateTime(-500, 1, 1, 23, 59, 59)));\n        test(Date(-501, 1, 1), SysTime(DateTime(-501, 1, 1, 23, 59, 59), hnsecs(500)));\n        test(Date(-1000, 1, 1), SysTime(DateTime(-1000, 1, 1, 23, 59, 59), hnsecs(50_000)));\n        test(Date(-1001, 1, 1), SysTime(DateTime(-1001, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        test(Date(-1599, 1, 1), SysTime(DateTime(-1599, 1, 1, 0, 0, 0)));\n        test(Date(-1600, 12, 31), SysTime(DateTime(-1600, 12, 31, 0, 0, 0), hnsecs(500)));\n        test(Date(-1600, 1, 1), SysTime(DateTime(-1600, 1, 1, 0, 0, 0), hnsecs(50_000)));\n        test(Date(-1601, 1, 1), SysTime(DateTime(-1601, 1, 1, 0, 0, 0), hnsecs(9_999_999)));\n        test(Date(-1900, 1, 1), SysTime(DateTime(-1900, 1, 1, 12, 13, 14)));\n        test(Date(-1901, 1, 1), SysTime(DateTime(-1901, 1, 1, 12, 13, 14), hnsecs(500)));\n        test(Date(-1999, 1, 1), SysTime(DateTime(-1999, 1, 1, 12, 13, 14), hnsecs(50_000)));\n        test(Date(-1999, 7, 6), SysTime(DateTime(-1999, 7, 6, 12, 13, 14), hnsecs(9_999_999)));\n        test(Date(-2000, 12, 31), SysTime(DateTime(-2000, 12, 31, 23, 59, 59)));\n        test(Date(-2000, 1, 1), SysTime(DateTime(-2000, 1, 1, 23, 59, 59), hnsecs(500)));\n        test(Date(-2001, 1, 1), SysTime(DateTime(-2001, 1, 1, 23, 59, 59), hnsecs(50_000)));\n\n        test(Date(-2010, 1, 1), SysTime(DateTime(-2010, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n        test(Date(-2010, 1, 31), SysTime(DateTime(-2010, 1, 31, 0, 0, 0)));\n        test(Date(-2010, 2, 1), SysTime(DateTime(-2010, 2, 1, 0, 0, 0), hnsecs(500)));\n        test(Date(-2010, 2, 28), SysTime(DateTime(-2010, 2, 28, 0, 0, 0), hnsecs(50_000)));\n        test(Date(-2010, 3, 1), SysTime(DateTime(-2010, 3, 1, 0, 0, 0), hnsecs(9_999_999)));\n        test(Date(-2010, 3, 31), SysTime(DateTime(-2010, 3, 31, 12, 13, 14)));\n        test(Date(-2010, 4, 1), SysTime(DateTime(-2010, 4, 1, 12, 13, 14), hnsecs(500)));\n        test(Date(-2010, 4, 30), SysTime(DateTime(-2010, 4, 30, 12, 13, 14), hnsecs(50_000)));\n        test(Date(-2010, 5, 1), SysTime(DateTime(-2010, 5, 1, 12, 13, 14), hnsecs(9_999_999)));\n        test(Date(-2010, 5, 31), SysTime(DateTime(-2010, 5, 31, 23, 59, 59)));\n        test(Date(-2010, 6, 1), SysTime(DateTime(-2010, 6, 1, 23, 59, 59), hnsecs(500)));\n        test(Date(-2010, 6, 30), SysTime(DateTime(-2010, 6, 30, 23, 59, 59), hnsecs(50_000)));\n        test(Date(-2010, 7, 1), SysTime(DateTime(-2010, 7, 1, 23, 59, 59), hnsecs(9_999_999)));\n        test(Date(-2010, 7, 31), SysTime(DateTime(-2010, 7, 31, 0, 0, 0)));\n        test(Date(-2010, 8, 1), SysTime(DateTime(-2010, 8, 1, 0, 0, 0), hnsecs(500)));\n        test(Date(-2010, 8, 31), SysTime(DateTime(-2010, 8, 31, 0, 0, 0), hnsecs(50_000)));\n        test(Date(-2010, 9, 1), SysTime(DateTime(-2010, 9, 1, 0, 0, 0), hnsecs(9_999_999)));\n        test(Date(-2010, 9, 30), SysTime(DateTime(-2010, 9, 30, 12, 0, 0)));\n        test(Date(-2010, 10, 1), SysTime(DateTime(-2010, 10, 1, 0, 12, 0), hnsecs(500)));\n        test(Date(-2010, 10, 31), SysTime(DateTime(-2010, 10, 31, 0, 0, 12), hnsecs(50_000)));\n        test(Date(-2010, 11, 1), SysTime(DateTime(-2010, 11, 1, 23, 0, 0), hnsecs(9_999_999)));\n        test(Date(-2010, 11, 30), SysTime(DateTime(-2010, 11, 30, 0, 59, 0)));\n        test(Date(-2010, 12, 1), SysTime(DateTime(-2010, 12, 1, 0, 0, 59), hnsecs(500)));\n        test(Date(-2010, 12, 31), SysTime(DateTime(-2010, 12, 31, 0, 59, 59), hnsecs(50_000)));\n\n        test(Date(-2012, 2, 1), SysTime(DateTime(-2012, 2, 1, 23, 0, 59), hnsecs(9_999_999)));\n        test(Date(-2012, 2, 28), SysTime(DateTime(-2012, 2, 28, 23, 59, 0)));\n        test(Date(-2012, 2, 29), SysTime(DateTime(-2012, 2, 29, 7, 7, 7), hnsecs(7)));\n        test(Date(-2012, 3, 1), SysTime(DateTime(-2012, 3, 1, 7, 7, 7), hnsecs(7)));\n\n        test(Date(-3760, 9, 7), SysTime(DateTime(-3760, 9, 7, 0, 0, 0)));\n    }\n\n\n    /++\n        The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on.\n        Setting this property does not affect the time portion of $(LREF SysTime).\n\n        Params:\n            days = The day of the Gregorian Calendar to set this $(LREF SysTime)\n                   to.\n     +/\n    @property void dayOfGregorianCal(int days) @safe nothrow scope\n    {\n        auto hnsecs = adjTime;\n        hnsecs = removeUnitsFromHNSecs!\"days\"(hnsecs);\n\n        if (hnsecs < 0)\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n\n        if (--days < 0)\n        {\n            hnsecs -= convert!(\"hours\", \"hnsecs\")(24);\n            ++days;\n        }\n\n        immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(days);\n\n        adjTime = newDaysHNSecs + hnsecs;\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time;\n        import std.datetime.date : DateTime;\n\n        auto st = SysTime(DateTime(0, 1, 1, 12, 0, 0));\n        st.dayOfGregorianCal = 1;\n        assert(st == SysTime(DateTime(1, 1, 1, 12, 0, 0)));\n\n        st.dayOfGregorianCal = 365;\n        assert(st == SysTime(DateTime(1, 12, 31, 12, 0, 0)));\n\n        st.dayOfGregorianCal = 366;\n        assert(st == SysTime(DateTime(2, 1, 1, 12, 0, 0)));\n\n        st.dayOfGregorianCal = 0;\n        assert(st == SysTime(DateTime(0, 12, 31, 12, 0, 0)));\n\n        st.dayOfGregorianCal = -365;\n        assert(st == SysTime(DateTime(-0, 1, 1, 12, 0, 0)));\n\n        st.dayOfGregorianCal = -366;\n        assert(st == SysTime(DateTime(-1, 12, 31, 12, 0, 0)));\n\n        st.dayOfGregorianCal = 730_120;\n        assert(st == SysTime(DateTime(2000, 1, 1, 12, 0, 0)));\n\n        st.dayOfGregorianCal = 734_137;\n        assert(st == SysTime(DateTime(2010, 12, 31, 12, 0, 0)));\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        void testST(SysTime orig, int day, SysTime expected, size_t line = __LINE__) @safe\n        {\n            orig.dayOfGregorianCal = day;\n            if (orig != expected)\n                throw new AssertError(format(\"Failed. actual [%s] != expected [%s]\", orig, expected), __FILE__, line);\n        }\n\n        // Test A.D.\n        testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));\n        testST(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 1,\n               SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n\n        // Test B.C.\n        testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0)));\n        testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 0,\n               SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(1)), 0,\n               SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1)));\n        testST(SysTime(DateTime(0, 1, 1, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59)));\n\n        // Test Both.\n        testST(SysTime(DateTime(-512, 7, 20, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0)));\n        testST(SysTime(DateTime(-513, 6, 6, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));\n        testST(SysTime(DateTime(-511, 5, 7, 23, 59, 59), hnsecs(9_999_999)), 1,\n               SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));\n\n        testST(SysTime(DateTime(1607, 4, 8, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0)));\n        testST(SysTime(DateTime(1500, 3, 9, 23, 59, 59), hnsecs(9_999_999)), 0,\n               SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n        testST(SysTime(DateTime(999, 2, 10, 23, 59, 59), hnsecs(1)), 0,\n               SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1)));\n        testST(SysTime(DateTime(2007, 12, 11, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59)));\n\n\n        auto st = SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212));\n\n        void testST2(int day, SysTime expected, size_t line = __LINE__) @safe\n        {\n            st.dayOfGregorianCal = day;\n            if (st != expected)\n                throw new AssertError(format(\"Failed. actual [%s] != expected [%s]\", st, expected), __FILE__, line);\n        }\n\n        // Test A.D.\n        testST2(1, SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(2, SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212)));\n        testST2(32, SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212)));\n        testST2(366, SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(731, SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(1096, SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(1462, SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(17_898, SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(35_065, SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(36_160, SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(36_525, SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(37_986, SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(72_684, SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(73_049, SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(109_208, SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(109_573, SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(145_732, SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(146_098, SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(182_257, SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(182_622, SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(364_878, SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(365_243, SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(584_023, SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(584_389, SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(693_596, SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(693_961, SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(729_755, SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(730_120, SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(730_486, SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212)));\n\n        testST2(733_773, SysTime(DateTime(2010, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(733_803, SysTime(DateTime(2010, 1, 31, 12, 2, 9), msecs(212)));\n        testST2(733_804, SysTime(DateTime(2010, 2, 1, 12, 2, 9), msecs(212)));\n        testST2(733_831, SysTime(DateTime(2010, 2, 28, 12, 2, 9), msecs(212)));\n        testST2(733_832, SysTime(DateTime(2010, 3, 1, 12, 2, 9), msecs(212)));\n        testST2(733_862, SysTime(DateTime(2010, 3, 31, 12, 2, 9), msecs(212)));\n        testST2(733_863, SysTime(DateTime(2010, 4, 1, 12, 2, 9), msecs(212)));\n        testST2(733_892, SysTime(DateTime(2010, 4, 30, 12, 2, 9), msecs(212)));\n        testST2(733_893, SysTime(DateTime(2010, 5, 1, 12, 2, 9), msecs(212)));\n        testST2(733_923, SysTime(DateTime(2010, 5, 31, 12, 2, 9), msecs(212)));\n        testST2(733_924, SysTime(DateTime(2010, 6, 1, 12, 2, 9), msecs(212)));\n        testST2(733_953, SysTime(DateTime(2010, 6, 30, 12, 2, 9), msecs(212)));\n        testST2(733_954, SysTime(DateTime(2010, 7, 1, 12, 2, 9), msecs(212)));\n        testST2(733_984, SysTime(DateTime(2010, 7, 31, 12, 2, 9), msecs(212)));\n        testST2(733_985, SysTime(DateTime(2010, 8, 1, 12, 2, 9), msecs(212)));\n        testST2(734_015, SysTime(DateTime(2010, 8, 31, 12, 2, 9), msecs(212)));\n        testST2(734_016, SysTime(DateTime(2010, 9, 1, 12, 2, 9), msecs(212)));\n        testST2(734_045, SysTime(DateTime(2010, 9, 30, 12, 2, 9), msecs(212)));\n        testST2(734_046, SysTime(DateTime(2010, 10, 1, 12, 2, 9), msecs(212)));\n        testST2(734_076, SysTime(DateTime(2010, 10, 31, 12, 2, 9), msecs(212)));\n        testST2(734_077, SysTime(DateTime(2010, 11, 1, 12, 2, 9), msecs(212)));\n        testST2(734_106, SysTime(DateTime(2010, 11, 30, 12, 2, 9), msecs(212)));\n        testST2(734_107, SysTime(DateTime(2010, 12, 1, 12, 2, 9), msecs(212)));\n        testST2(734_137, SysTime(DateTime(2010, 12, 31, 12, 2, 9), msecs(212)));\n\n        testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212)));\n        testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212)));\n        testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212)));\n        testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212)));\n\n        testST2(734_534,  SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212)));\n\n        testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212)));\n        testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212)));\n        testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212)));\n\n        // Test B.C.\n        testST2(0, SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212)));\n        testST2(-1, SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212)));\n        testST2(-30, SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212)));\n        testST2(-31, SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212)));\n\n        testST2(-366, SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212)));\n        testST2(-367, SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212)));\n        testST2(-730, SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-731, SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212)));\n        testST2(-1095, SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-1096, SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212)));\n        testST2(-1460, SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-1461, SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212)));\n        testST2(-1826, SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-1827, SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212)));\n        testST2(-2191, SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-3652, SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212)));\n\n        testST2(-18_262, SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-18_627, SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-35_794, SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-36_160, SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212)));\n        testST2(-36_524, SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-36_889, SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-37_254, SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-38_715, SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-73_413, SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-73_778, SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-109_937, SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-110_302, SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-146_097, SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212)));\n        testST2(-146_462, SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-146_827, SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-182_621, SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-182_986, SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-183_351, SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-365_607, SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-365_972, SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-584_387, SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-584_388, SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212)));\n        testST2(-584_753, SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-585_118, SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-694_325, SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-694_690, SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-730_484, SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-730_485, SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212)));\n        testST2(-730_850, SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-731_215, SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212)));\n\n        testST2(-734_502, SysTime(DateTime(-2010, 1, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_472, SysTime(DateTime(-2010, 1, 31, 12, 2, 9), msecs(212)));\n        testST2(-734_471, SysTime(DateTime(-2010, 2, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_444, SysTime(DateTime(-2010, 2, 28, 12, 2, 9), msecs(212)));\n        testST2(-734_443, SysTime(DateTime(-2010, 3, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_413, SysTime(DateTime(-2010, 3, 31, 12, 2, 9), msecs(212)));\n        testST2(-734_412, SysTime(DateTime(-2010, 4, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_383, SysTime(DateTime(-2010, 4, 30, 12, 2, 9), msecs(212)));\n        testST2(-734_382, SysTime(DateTime(-2010, 5, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_352, SysTime(DateTime(-2010, 5, 31, 12, 2, 9), msecs(212)));\n        testST2(-734_351, SysTime(DateTime(-2010, 6, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_322, SysTime(DateTime(-2010, 6, 30, 12, 2, 9), msecs(212)));\n        testST2(-734_321, SysTime(DateTime(-2010, 7, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_291, SysTime(DateTime(-2010, 7, 31, 12, 2, 9), msecs(212)));\n        testST2(-734_290, SysTime(DateTime(-2010, 8, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_260, SysTime(DateTime(-2010, 8, 31, 12, 2, 9), msecs(212)));\n        testST2(-734_259, SysTime(DateTime(-2010, 9, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_230, SysTime(DateTime(-2010, 9, 30, 12, 2, 9), msecs(212)));\n        testST2(-734_229, SysTime(DateTime(-2010, 10, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_199, SysTime(DateTime(-2010, 10, 31, 12, 2, 9), msecs(212)));\n        testST2(-734_198, SysTime(DateTime(-2010, 11, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_169, SysTime(DateTime(-2010, 11, 30, 12, 2, 9), msecs(212)));\n        testST2(-734_168, SysTime(DateTime(-2010, 12, 1, 12, 2, 9), msecs(212)));\n        testST2(-734_138, SysTime(DateTime(-2010, 12, 31, 12, 2, 9), msecs(212)));\n\n        testST2(-735_202, SysTime(DateTime(-2012, 2, 1, 12, 2, 9), msecs(212)));\n        testST2(-735_175, SysTime(DateTime(-2012, 2, 28, 12, 2, 9), msecs(212)));\n        testST2(-735_174, SysTime(DateTime(-2012, 2, 29, 12, 2, 9), msecs(212)));\n        testST2(-735_173, SysTime(DateTime(-2012, 3, 1, 12, 2, 9), msecs(212)));\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(!__traits(compiles, cst.dayOfGregorianCal = 7));\n        static assert(!__traits(compiles, ist.dayOfGregorianCal = 7));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            st.dayOfGregorianCal = 42;\n        }\n    }\n\n\n    /++\n        The ISO 8601 week of the year that this $(LREF SysTime) is in.\n\n        See_Also:\n            $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date).\n      +/\n    @property ubyte isoWeek() @safe const nothrow scope\n    {\n        return (cast(Date) this).isoWeek;\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time;\n        import std.datetime.date : Date;\n\n        auto st = SysTime(Date(1999, 7, 6));\n        const cst = SysTime(Date(2010, 5, 1));\n        immutable ist = SysTime(Date(2015, 10, 10));\n\n        assert(st.isoWeek == 27);\n        assert(cst.isoWeek == 17);\n        assert(ist.isoWeek == 41);\n    }\n\n    @safe unittest\n    {\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.isoWeek;\n        }\n    }\n\n\n    /++\n        $(LREF SysTime) for the last day in the month that this Date is in.\n        The time portion of endOfMonth is always 23:59:59.9999999.\n      +/\n    @property SysTime endOfMonth() @safe const nothrow scope\n    {\n        immutable hnsecs = adjTime;\n        immutable days = getUnitsFromHNSecs!\"days\"(hnsecs);\n\n        auto date = Date(cast(int) days + 1).endOfMonth;\n        auto newDays = date.dayOfGregorianCal - 1;\n        long theTimeHNSecs;\n\n        if (newDays < 0)\n        {\n            theTimeHNSecs = -1;\n            ++newDays;\n        }\n        else\n            theTimeHNSecs = convert!(\"days\", \"hnsecs\")(1) - 1;\n\n        immutable newDaysHNSecs = convert!(\"days\", \"hnsecs\")(newDays);\n\n        auto retval = SysTime(this._stdTime, this._timezone);\n        retval.adjTime = newDaysHNSecs + theTimeHNSecs;\n\n        return retval;\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : msecs, usecs, hnsecs;\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).endOfMonth ==\n               SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999)));\n\n        assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0), msecs(24)).endOfMonth ==\n               SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999)));\n\n        assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27), usecs(5203)).endOfMonth ==\n               SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999)));\n\n        assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9), hnsecs(12345)).endOfMonth ==\n               SysTime(DateTime(2000, 6, 30, 23, 59, 59), hnsecs(9_999_999)));\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        assert(SysTime(Date(1999, 1, 1)).endOfMonth == SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(1999, 2, 1)).endOfMonth == SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(2000, 2, 1)).endOfMonth == SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(1999, 3, 1)).endOfMonth == SysTime(DateTime(1999, 3, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(1999, 4, 1)).endOfMonth == SysTime(DateTime(1999, 4, 30, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(1999, 5, 1)).endOfMonth == SysTime(DateTime(1999, 5, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(1999, 6, 1)).endOfMonth == SysTime(DateTime(1999, 6, 30, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(1999, 7, 1)).endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(1999, 8, 1)).endOfMonth == SysTime(DateTime(1999, 8, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(1999, 9, 1)).endOfMonth == SysTime(DateTime(1999, 9, 30, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(1999, 10, 1)).endOfMonth == SysTime(DateTime(1999, 10, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(1999, 11, 1)).endOfMonth == SysTime(DateTime(1999, 11, 30, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(1999, 12, 1)).endOfMonth == SysTime(DateTime(1999, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n\n        // Test B.C.\n        assert(SysTime(Date(-1999, 1, 1)).endOfMonth == SysTime(DateTime(-1999, 1, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-1999, 2, 1)).endOfMonth == SysTime(DateTime(-1999, 2, 28, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-2000, 2, 1)).endOfMonth == SysTime(DateTime(-2000, 2, 29, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-1999, 3, 1)).endOfMonth == SysTime(DateTime(-1999, 3, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-1999, 4, 1)).endOfMonth == SysTime(DateTime(-1999, 4, 30, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-1999, 5, 1)).endOfMonth == SysTime(DateTime(-1999, 5, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-1999, 6, 1)).endOfMonth == SysTime(DateTime(-1999, 6, 30, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-1999, 7, 1)).endOfMonth == SysTime(DateTime(-1999, 7, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-1999, 8, 1)).endOfMonth == SysTime(DateTime(-1999, 8, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-1999, 9, 1)).endOfMonth == SysTime(DateTime(-1999, 9, 30, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-1999, 10, 1)).endOfMonth ==\n               SysTime(DateTime(-1999, 10, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-1999, 11, 1)).endOfMonth ==\n               SysTime(DateTime(-1999, 11, 30, 23, 59, 59), hnsecs(9_999_999)));\n        assert(SysTime(Date(-1999, 12, 1)).endOfMonth ==\n               SysTime(DateTime(-1999, 12, 31, 23, 59, 59), hnsecs(9_999_999)));\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999)));\n        assert(ist.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999)));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.endOfMonth;\n        }\n    }\n\n\n    /++\n        The last day in the month that this $(LREF SysTime) is in.\n      +/\n    @property ubyte daysInMonth() @safe const nothrow scope\n    {\n        return Date(dayOfGregorianCal).daysInMonth;\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time;\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).daysInMonth == 31);\n        assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0)).daysInMonth == 28);\n        assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27)).daysInMonth == 29);\n        assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9)).daysInMonth == 30);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        assert(SysTime(DateTime(1999, 1, 1, 12, 1, 13)).daysInMonth == 31);\n        assert(SysTime(DateTime(1999, 2, 1, 17, 13, 12)).daysInMonth == 28);\n        assert(SysTime(DateTime(2000, 2, 1, 13, 2, 12)).daysInMonth == 29);\n        assert(SysTime(DateTime(1999, 3, 1, 12, 13, 12)).daysInMonth == 31);\n        assert(SysTime(DateTime(1999, 4, 1, 12, 6, 13)).daysInMonth == 30);\n        assert(SysTime(DateTime(1999, 5, 1, 15, 13, 12)).daysInMonth == 31);\n        assert(SysTime(DateTime(1999, 6, 1, 13, 7, 12)).daysInMonth == 30);\n        assert(SysTime(DateTime(1999, 7, 1, 12, 13, 17)).daysInMonth == 31);\n        assert(SysTime(DateTime(1999, 8, 1, 12, 3, 13)).daysInMonth == 31);\n        assert(SysTime(DateTime(1999, 9, 1, 12, 13, 12)).daysInMonth == 30);\n        assert(SysTime(DateTime(1999, 10, 1, 13, 19, 12)).daysInMonth == 31);\n        assert(SysTime(DateTime(1999, 11, 1, 12, 13, 17)).daysInMonth == 30);\n        assert(SysTime(DateTime(1999, 12, 1, 12, 52, 13)).daysInMonth == 31);\n\n        // Test B.C.\n        assert(SysTime(DateTime(-1999, 1, 1, 12, 1, 13)).daysInMonth == 31);\n        assert(SysTime(DateTime(-1999, 2, 1, 7, 13, 12)).daysInMonth == 28);\n        assert(SysTime(DateTime(-2000, 2, 1, 13, 2, 12)).daysInMonth == 29);\n        assert(SysTime(DateTime(-1999, 3, 1, 12, 13, 12)).daysInMonth == 31);\n        assert(SysTime(DateTime(-1999, 4, 1, 12, 6, 13)).daysInMonth == 30);\n        assert(SysTime(DateTime(-1999, 5, 1, 5, 13, 12)).daysInMonth == 31);\n        assert(SysTime(DateTime(-1999, 6, 1, 13, 7, 12)).daysInMonth == 30);\n        assert(SysTime(DateTime(-1999, 7, 1, 12, 13, 17)).daysInMonth == 31);\n        assert(SysTime(DateTime(-1999, 8, 1, 12, 3, 13)).daysInMonth == 31);\n        assert(SysTime(DateTime(-1999, 9, 1, 12, 13, 12)).daysInMonth == 30);\n        assert(SysTime(DateTime(-1999, 10, 1, 13, 19, 12)).daysInMonth == 31);\n        assert(SysTime(DateTime(-1999, 11, 1, 12, 13, 17)).daysInMonth == 30);\n        assert(SysTime(DateTime(-1999, 12, 1, 12, 52, 13)).daysInMonth == 31);\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.daysInMonth == 31);\n        assert(ist.daysInMonth == 31);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.daysInMonth;\n        }\n    }\n\n\n    /++\n        Whether the current year is a date in A.D.\n      +/\n    @property bool isAD() @safe const nothrow scope\n    {\n        return adjTime >= 0;\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time;\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(1, 1, 1, 12, 7, 0)).isAD);\n        assert(SysTime(DateTime(2010, 12, 31, 0, 0, 0)).isAD);\n        assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD);\n        assert(!SysTime(DateTime(-2010, 1, 1, 2, 2, 2)).isAD);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        assert(SysTime(DateTime(2010, 7, 4, 12, 0, 9)).isAD);\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).isAD);\n        assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD);\n        assert(!SysTime(DateTime(0, 1, 1, 23, 59, 59)).isAD);\n        assert(!SysTime(DateTime(-1, 1, 1, 23 ,59 ,59)).isAD);\n        assert(!SysTime(DateTime(-2010, 7, 4, 12, 2, 2)).isAD);\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.isAD);\n        assert(ist.isAD);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.isAD;\n        }\n    }\n\n\n    /++\n        The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day)\n        for this $(LREF SysTime) at the given time. For example,\n        prior to noon, 1996-03-31 would be the Julian day number 2_450_173, so\n        this function returns 2_450_173, while from noon onward, the Julian\n        day number would be 2_450_174, so this function returns 2_450_174.\n      +/\n    @property long julianDay() @safe const nothrow scope\n    {\n        immutable jd = dayOfGregorianCal + 1_721_425;\n        return hour < 12 ? jd - 1 : jd;\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        assert(SysTime(DateTime(-4713, 11, 24, 0, 0, 0)).julianDay == -1);\n        assert(SysTime(DateTime(-4713, 11, 24, 12, 0, 0)).julianDay == 0);\n\n        assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).julianDay == 1_721_424);\n        assert(SysTime(DateTime(0, 12, 31, 12, 0, 0)).julianDay == 1_721_425);\n\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).julianDay == 1_721_425);\n        assert(SysTime(DateTime(1, 1, 1, 12, 0, 0)).julianDay == 1_721_426);\n\n        assert(SysTime(DateTime(1582, 10, 15, 0, 0, 0)).julianDay == 2_299_160);\n        assert(SysTime(DateTime(1582, 10, 15, 12, 0, 0)).julianDay == 2_299_161);\n\n        assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).julianDay == 2_400_000);\n        assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).julianDay == 2_400_001);\n\n        assert(SysTime(DateTime(1982, 1, 4, 0, 0, 0)).julianDay == 2_444_973);\n        assert(SysTime(DateTime(1982, 1, 4, 12, 0, 0)).julianDay == 2_444_974);\n\n        assert(SysTime(DateTime(1996, 3, 31, 0, 0, 0)).julianDay == 2_450_173);\n        assert(SysTime(DateTime(1996, 3, 31, 12, 0, 0)).julianDay == 2_450_174);\n\n        assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).julianDay == 2_455_432);\n        assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).julianDay == 2_455_433);\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.julianDay == 2_451_366);\n        assert(ist.julianDay == 2_451_366);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.julianDay;\n        }\n    }\n\n\n    /++\n        The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for\n        any time on this date (since, the modified Julian day changes at\n        midnight).\n      +/\n    @property long modJulianDay() @safe const nothrow scope\n    {\n        return dayOfGregorianCal + 1_721_425 - 2_400_001;\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).modJulianDay == 0);\n        assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).modJulianDay == 0);\n\n        assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).modJulianDay == 55_432);\n        assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).modJulianDay == 55_432);\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.modJulianDay == 51_365);\n        assert(ist.modJulianDay == 51_365);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.modJulianDay;\n        }\n    }\n\n\n    /++\n        Returns a $(REF Date,std,datetime,date) equivalent to this $(LREF SysTime).\n      +/\n    Date opCast(T)() @safe const nothrow scope\n        if (is(Unqual!T == Date))\n    {\n        return Date(dayOfGregorianCal);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        assert(cast(Date) SysTime(Date(1999, 7, 6)) == Date(1999, 7, 6));\n        assert(cast(Date) SysTime(Date(2000, 12, 31)) == Date(2000, 12, 31));\n        assert(cast(Date) SysTime(Date(2001, 1, 1)) == Date(2001, 1, 1));\n\n        assert(cast(Date) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == Date(1999, 7, 6));\n        assert(cast(Date) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == Date(2000, 12, 31));\n        assert(cast(Date) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == Date(2001, 1, 1));\n\n        assert(cast(Date) SysTime(Date(-1999, 7, 6)) == Date(-1999, 7, 6));\n        assert(cast(Date) SysTime(Date(-2000, 12, 31)) == Date(-2000, 12, 31));\n        assert(cast(Date) SysTime(Date(-2001, 1, 1)) == Date(-2001, 1, 1));\n\n        assert(cast(Date) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == Date(-1999, 7, 6));\n        assert(cast(Date) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == Date(-2000, 12, 31));\n        assert(cast(Date) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == Date(-2001, 1, 1));\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cast(Date) cst != Date.init);\n        assert(cast(Date) ist != Date.init);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = cast(Date) st;\n        }\n    }\n\n\n    /++\n        Returns a $(REF DateTime,std,datetime,date) equivalent to this\n        $(LREF SysTime).\n      +/\n    DateTime opCast(T)() @safe const nothrow scope\n        if (is(Unqual!T == DateTime))\n    {\n        try\n        {\n            auto hnsecs = adjTime;\n            auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n            if (hnsecs < 0)\n            {\n                hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n                --days;\n            }\n\n            immutable hour = splitUnitsFromHNSecs!\"hours\"(hnsecs);\n            immutable minute = splitUnitsFromHNSecs!\"minutes\"(hnsecs);\n            immutable second = getUnitsFromHNSecs!\"seconds\"(hnsecs);\n\n            return DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second));\n        }\n        catch (Exception e)\n            assert(0, \"Either DateTime's constructor or TimeOfDay's constructor threw.\");\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22)) == DateTime(1, 1, 6, 7, 12, 22));\n        assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(1, 1, 6, 7, 12, 22));\n        assert(cast(DateTime) SysTime(Date(1999, 7, 6)) == DateTime(1999, 7, 6, 0, 0, 0));\n        assert(cast(DateTime) SysTime(Date(2000, 12, 31)) == DateTime(2000, 12, 31, 0, 0, 0));\n        assert(cast(DateTime) SysTime(Date(2001, 1, 1)) == DateTime(2001, 1, 1, 0, 0, 0));\n\n        assert(cast(DateTime) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == DateTime(1999, 7, 6, 12, 10, 9));\n        assert(cast(DateTime) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == DateTime(2000, 12, 31, 13, 11, 10));\n        assert(cast(DateTime) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == DateTime(2001, 1, 1, 14, 12, 11));\n\n        assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22)) == DateTime(-1, 1, 6, 7, 12, 22));\n        assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(-1, 1, 6, 7, 12, 22));\n        assert(cast(DateTime) SysTime(Date(-1999, 7, 6)) == DateTime(-1999, 7, 6, 0, 0, 0));\n        assert(cast(DateTime) SysTime(Date(-2000, 12, 31)) == DateTime(-2000, 12, 31, 0, 0, 0));\n        assert(cast(DateTime) SysTime(Date(-2001, 1, 1)) == DateTime(-2001, 1, 1, 0, 0, 0));\n\n        assert(cast(DateTime) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == DateTime(-1999, 7, 6, 12, 10, 9));\n        assert(cast(DateTime) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == DateTime(-2000, 12, 31, 13, 11, 10));\n        assert(cast(DateTime) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == DateTime(-2001, 1, 1, 14, 12, 11));\n\n        assert(cast(DateTime) SysTime(DateTime(2011, 1, 13, 8, 17, 2), msecs(296), LocalTime()) ==\n               DateTime(2011, 1, 13, 8, 17, 2));\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cast(DateTime) cst != DateTime.init);\n        assert(cast(DateTime) ist != DateTime.init);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = cast(DateTime) st;\n        }\n    }\n\n\n    /++\n        Returns a $(REF TimeOfDay,std,datetime,date) equivalent to this\n        $(LREF SysTime).\n      +/\n    TimeOfDay opCast(T)() @safe const nothrow scope\n        if (is(Unqual!T == TimeOfDay))\n    {\n        try\n        {\n            auto hnsecs = adjTime;\n            hnsecs = removeUnitsFromHNSecs!\"days\"(hnsecs);\n\n            if (hnsecs < 0)\n                hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n\n            immutable hour = splitUnitsFromHNSecs!\"hours\"(hnsecs);\n            immutable minute = splitUnitsFromHNSecs!\"minutes\"(hnsecs);\n            immutable second = getUnitsFromHNSecs!\"seconds\"(hnsecs);\n\n            return TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second);\n        }\n        catch (Exception e)\n            assert(0, \"TimeOfDay's constructor threw.\");\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        assert(cast(TimeOfDay) SysTime(Date(1999, 7, 6)) == TimeOfDay(0, 0, 0));\n        assert(cast(TimeOfDay) SysTime(Date(2000, 12, 31)) == TimeOfDay(0, 0, 0));\n        assert(cast(TimeOfDay) SysTime(Date(2001, 1, 1)) == TimeOfDay(0, 0, 0));\n\n        assert(cast(TimeOfDay) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9));\n        assert(cast(TimeOfDay) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10));\n        assert(cast(TimeOfDay) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11));\n\n        assert(cast(TimeOfDay) SysTime(Date(-1999, 7, 6)) == TimeOfDay(0, 0, 0));\n        assert(cast(TimeOfDay) SysTime(Date(-2000, 12, 31)) == TimeOfDay(0, 0, 0));\n        assert(cast(TimeOfDay) SysTime(Date(-2001, 1, 1)) == TimeOfDay(0, 0, 0));\n\n        assert(cast(TimeOfDay) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9));\n        assert(cast(TimeOfDay) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10));\n        assert(cast(TimeOfDay) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11));\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cast(TimeOfDay) cst != TimeOfDay.init);\n        assert(cast(TimeOfDay) ist != TimeOfDay.init);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = cast(TimeOfDay) st;\n        }\n    }\n\n\n    // Temporary hack until bug http://d.puremagic.com/issues/show_bug.cgi?id=4867 is fixed.\n    // This allows assignment from const(SysTime) to SysTime.\n    // It may be a good idea to keep it though, since casting from a type to itself\n    // should be allowed, and it doesn't work without this opCast() since opCast()\n    // has already been defined for other types.\n    SysTime opCast(T)() @safe const pure nothrow scope\n        if (is(Unqual!T == SysTime))\n    {\n        return SysTime(_stdTime, _timezone);\n    }\n\n    @safe unittest\n    {\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = cast(SysTime) st;\n        }\n    }\n\n\n    /++\n        Converts this $(LREF SysTime) to a string with the format\n        YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ is time\n        zone).\n\n        Note that the number of digits in the fractional seconds varies with the\n        number of fractional seconds. It's a maximum of 7 (which would be\n        hnsecs), but only has as many as are necessary to hold the correct value\n        (so no trailing zeroes), and if there are no fractional seconds, then\n        there is no decimal point.\n\n        If this $(LREF SysTime)'s time zone is\n        $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time\n        zone is `UTC`, then it is \"Z\". Otherwise, it is the offset from UTC\n        (e.g. +0100 or -0700). Note that the offset from UTC is $(I not) enough\n        to uniquely identify the time zone.\n\n        Time zone offsets will be in the form +HHMM or -HHMM.\n\n        $(RED Warning:\n            Previously, toISOString did the same as $(LREF toISOExtString) and\n            generated +HH:MM or -HH:MM for the time zone when it was not\n            $(REF LocalTime,std,datetime,timezone) or\n            $(REF UTC,std,datetime,timezone), which is not in conformance with\n            ISO 8601 for the non-extended string format. This has now been\n            fixed. However, for now, fromISOString will continue to accept the\n            extended format for the time zone so that any code which has been\n            writing out the result of toISOString to read in later will continue\n            to work. The current behavior will be kept until July 2019 at which\n            point, fromISOString will be fixed to be standards compliant.)\n\n        Params:\n            writer = A `char` accepting\n            $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toISOString() @safe const nothrow scope\n    {\n        import std.array : appender;\n        auto app = appender!string();\n        app.reserve(30);\n        try\n            toISOString(app);\n        catch (Exception e)\n            assert(0, \"toISOString() threw.\");\n        return app.data;\n    }\n\n    /// ditto\n    void toISOString(W)(ref W writer) const scope\n    if (isOutputRange!(W, char))\n    {\n        immutable adjustedTime = adjTime;\n        long hnsecs = adjustedTime;\n\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        immutable hour = splitUnitsFromHNSecs!\"hours\"(hnsecs);\n        immutable minute = splitUnitsFromHNSecs!\"minutes\"(hnsecs);\n        immutable second = splitUnitsFromHNSecs!\"seconds\"(hnsecs);\n\n        auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour,\n                                      cast(int) minute, cast(int) second));\n\n        if (_timezone is LocalTime())\n        {\n            dateTime.toISOString(writer);\n            fracSecsToISOString(writer, cast(int) hnsecs);\n            return;\n        }\n\n        if (_timezone is UTC())\n        {\n            dateTime.toISOString(writer);\n            fracSecsToISOString(writer, cast(int) hnsecs);\n            put(writer, 'Z');\n            return;\n        }\n\n        immutable utcOffset = dur!\"hnsecs\"(adjustedTime - stdTime);\n\n        dateTime.toISOString(writer);\n        fracSecsToISOString(writer, cast(int) hnsecs);\n        SimpleTimeZone.toISOExtString(writer, utcOffset);\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : msecs, hnsecs;\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOString() ==\n               \"20100704T070612\");\n\n        assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOString() ==\n               \"19981225T021500.024\");\n\n        assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOString() ==\n               \"00000105T230959\");\n\n        assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOString() ==\n               \"-00040105T000002.052092\");\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        assert(SysTime(DateTime.init, UTC()).toISOString() == \"00010101T000000Z\");\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOString() == \"00010101T000000.0000001Z\");\n\n        assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOString() == \"00091204T000000\");\n        assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOString() == \"00991204T050612\");\n        assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOString() == \"09991204T134459\");\n        assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOString() == \"99990704T235959\");\n        assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOString() == \"+100001020T010101\");\n\n        assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == \"00091204T000000.042\");\n        assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == \"00991204T050612.1\");\n        assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == \"09991204T134459.04502\");\n        assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == \"99990704T235959.0000012\");\n        assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == \"+100001020T010101.050789\");\n\n        assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),\n                       new immutable SimpleTimeZone(dur!\"minutes\"(-360))).toISOString() ==\n               \"20121221T121212-06:00\");\n\n        assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),\n                       new immutable SimpleTimeZone(dur!\"minutes\"(420))).toISOString() ==\n               \"20121221T121212+07:00\");\n\n        // Test B.C.\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOString() ==\n               \"00001231T235959.9999999Z\");\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOString() == \"00001231T235959.0000001Z\");\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOString() == \"00001231T235959Z\");\n\n        assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOString() == \"00001204T001204\");\n        assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOString() == \"-00091204T000000\");\n        assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOString() == \"-00991204T050612\");\n        assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOString() == \"-09991204T134459\");\n        assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOString() == \"-99990704T235959\");\n        assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOString() == \"-100001020T010101\");\n\n        assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOString() == \"00001204T000000.007\");\n        assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == \"-00091204T000000.042\");\n        assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == \"-00991204T050612.1\");\n        assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == \"-09991204T134459.04502\");\n        assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == \"-99990704T235959.0000012\");\n        assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == \"-100001020T010101.050789\");\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.toISOString() == \"19990706T123033\");\n        assert(ist.toISOString() == \"19990706T123033\");\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.toISOString();\n        }\n    }\n\n\n\n    /++\n        Converts this $(LREF SysTime) to a string with the format\n        YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ\n        is the time zone).\n\n        Note that the number of digits in the fractional seconds varies with the\n        number of fractional seconds. It's a maximum of 7 (which would be\n        hnsecs), but only has as many as are necessary to hold the correct value\n        (so no trailing zeroes), and if there are no fractional seconds, then\n        there is no decimal point.\n\n        If this $(LREF SysTime)'s time zone is\n        $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time\n        zone is `UTC`, then it is \"Z\". Otherwise, it is the offset from UTC\n        (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not)\n        enough to uniquely identify the time zone.\n\n        Time zone offsets will be in the form +HH:MM or -HH:MM.\n\n        Params:\n            writer = A `char` accepting\n            $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toISOExtString() @safe const nothrow scope\n    {\n        import std.array : appender;\n        auto app = appender!string();\n        app.reserve(35);\n        try\n            toISOExtString(app);\n        catch (Exception e)\n            assert(0, \"toISOExtString() threw.\");\n        return app.data;\n    }\n\n    /// ditto\n    void toISOExtString(W)(ref W writer) const scope\n    if (isOutputRange!(W, char))\n    {\n        immutable adjustedTime = adjTime;\n        long hnsecs = adjustedTime;\n\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        immutable hour = splitUnitsFromHNSecs!\"hours\"(hnsecs);\n        immutable minute = splitUnitsFromHNSecs!\"minutes\"(hnsecs);\n        immutable second = splitUnitsFromHNSecs!\"seconds\"(hnsecs);\n\n        immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour,\n                                      cast(int) minute, cast(int) second));\n\n        if (_timezone is LocalTime())\n        {\n            dateTime.toISOExtString(writer);\n            fracSecsToISOString(writer, cast(int) hnsecs);\n            return;\n        }\n\n        if (_timezone is UTC())\n        {\n            dateTime.toISOExtString(writer);\n            fracSecsToISOString(writer, cast(int) hnsecs);\n            put(writer, 'Z');\n            return;\n        }\n\n        immutable utcOffset = dur!\"hnsecs\"(adjustedTime - stdTime);\n\n        dateTime.toISOExtString(writer);\n        fracSecsToISOString(writer, cast(int) hnsecs);\n        SimpleTimeZone.toISOExtString(writer, utcOffset);\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : msecs, hnsecs;\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOExtString() ==\n               \"2010-07-04T07:06:12\");\n\n        assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOExtString() ==\n               \"1998-12-25T02:15:00.024\");\n\n        assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOExtString() ==\n               \"0000-01-05T23:09:59\");\n\n        assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString() ==\n               \"-0004-01-05T00:00:02.052092\");\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        assert(SysTime(DateTime.init, UTC()).toISOExtString() == \"0001-01-01T00:00:00Z\");\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOExtString() ==\n               \"0001-01-01T00:00:00.0000001Z\");\n\n        assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOExtString() == \"0009-12-04T00:00:00\");\n        assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOExtString() == \"0099-12-04T05:06:12\");\n        assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOExtString() == \"0999-12-04T13:44:59\");\n        assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOExtString() == \"9999-07-04T23:59:59\");\n        assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOExtString() == \"+10000-10-20T01:01:01\");\n\n        assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == \"0009-12-04T00:00:00.042\");\n        assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == \"0099-12-04T05:06:12.1\");\n        assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == \"0999-12-04T13:44:59.04502\");\n        assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == \"9999-07-04T23:59:59.0000012\");\n        assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() ==\n               \"+10000-10-20T01:01:01.050789\");\n\n        assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),\n                       new immutable SimpleTimeZone(dur!\"minutes\"(-360))).toISOExtString() ==\n               \"2012-12-21T12:12:12-06:00\");\n\n        assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),\n                       new immutable SimpleTimeZone(dur!\"minutes\"(420))).toISOExtString() ==\n               \"2012-12-21T12:12:12+07:00\");\n\n        // Test B.C.\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOExtString() ==\n               \"0000-12-31T23:59:59.9999999Z\");\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOExtString() ==\n               \"0000-12-31T23:59:59.0000001Z\");\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOExtString() == \"0000-12-31T23:59:59Z\");\n\n        assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOExtString() == \"0000-12-04T00:12:04\");\n        assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOExtString() == \"-0009-12-04T00:00:00\");\n        assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOExtString() == \"-0099-12-04T05:06:12\");\n        assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOExtString() == \"-0999-12-04T13:44:59\");\n        assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOExtString() == \"-9999-07-04T23:59:59\");\n        assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOExtString() == \"-10000-10-20T01:01:01\");\n\n        assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOExtString() == \"0000-12-04T00:00:00.007\");\n        assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == \"-0009-12-04T00:00:00.042\");\n        assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == \"-0099-12-04T05:06:12.1\");\n        assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() ==\n               \"-0999-12-04T13:44:59.04502\");\n        assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() ==\n               \"-9999-07-04T23:59:59.0000012\");\n        assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() ==\n               \"-10000-10-20T01:01:01.050789\");\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.toISOExtString() == \"1999-07-06T12:30:33\");\n        assert(ist.toISOExtString() == \"1999-07-06T12:30:33\");\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.toISOExtString();\n        }\n    }\n\n    /++\n        Converts this $(LREF SysTime) to a string with the format\n        YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ\n        is the time zone).\n\n        Note that the number of digits in the fractional seconds varies with the\n        number of fractional seconds. It's a maximum of 7 (which would be\n        hnsecs), but only has as many as are necessary to hold the correct value\n        (so no trailing zeroes), and if there are no fractional seconds, then\n        there is no decimal point.\n\n        If this $(LREF SysTime)'s time zone is\n        $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time\n        zone is `UTC`, then it is \"Z\". Otherwise, it is the offset from UTC\n        (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not)\n        enough to uniquely identify the time zone.\n\n        Time zone offsets will be in the form +HH:MM or -HH:MM.\n\n        Params:\n            writer = A `char` accepting\n            $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toSimpleString() @safe const nothrow scope\n    {\n        import std.array : appender;\n        auto app = appender!string();\n        app.reserve(35);\n        try\n            toSimpleString(app);\n        catch (Exception e)\n            assert(0, \"toSimpleString() threw.\");\n        return app.data;\n    }\n\n    /// ditto\n    void toSimpleString(W)(ref W writer) const scope\n    if (isOutputRange!(W, char))\n    {\n        immutable adjustedTime = adjTime;\n        long hnsecs = adjustedTime;\n\n        auto days = splitUnitsFromHNSecs!\"days\"(hnsecs) + 1;\n\n        if (hnsecs < 0)\n        {\n            hnsecs += convert!(\"hours\", \"hnsecs\")(24);\n            --days;\n        }\n\n        immutable hour = splitUnitsFromHNSecs!\"hours\"(hnsecs);\n        immutable minute = splitUnitsFromHNSecs!\"minutes\"(hnsecs);\n        immutable second = splitUnitsFromHNSecs!\"seconds\"(hnsecs);\n\n        immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour,\n                                      cast(int) minute, cast(int) second));\n\n        if (_timezone is LocalTime())\n        {\n            dateTime.toSimpleString(writer);\n            fracSecsToISOString(writer, cast(int) hnsecs);\n            return;\n        }\n\n        if (_timezone is UTC())\n        {\n            dateTime.toSimpleString(writer);\n            fracSecsToISOString(writer, cast(int) hnsecs);\n            put(writer, 'Z');\n            return;\n        }\n\n        immutable utcOffset = dur!\"hnsecs\"(adjustedTime - stdTime);\n\n        dateTime.toSimpleString(writer);\n        fracSecsToISOString(writer, cast(int) hnsecs);\n        SimpleTimeZone.toISOExtString(writer, utcOffset);\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : msecs, hnsecs;\n        import std.datetime.date : DateTime;\n\n        assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toSimpleString() ==\n               \"2010-Jul-04 07:06:12\");\n\n        assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toSimpleString() ==\n               \"1998-Dec-25 02:15:00.024\");\n\n        assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toSimpleString() ==\n               \"0000-Jan-05 23:09:59\");\n\n        assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toSimpleString() ==\n                \"-0004-Jan-05 00:00:02.052092\");\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        // Test A.D.\n        assert(SysTime(DateTime.init, UTC()).toString() == \"0001-Jan-01 00:00:00Z\");\n        assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toString() == \"0001-Jan-01 00:00:00.0000001Z\");\n\n        assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toSimpleString() == \"0009-Dec-04 00:00:00\");\n        assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toSimpleString() == \"0099-Dec-04 05:06:12\");\n        assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toSimpleString() == \"0999-Dec-04 13:44:59\");\n        assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toSimpleString() == \"9999-Jul-04 23:59:59\");\n        assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toSimpleString() == \"+10000-Oct-20 01:01:01\");\n\n        assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == \"0009-Dec-04 00:00:00.042\");\n        assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == \"0099-Dec-04 05:06:12.1\");\n        assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() ==\n               \"0999-Dec-04 13:44:59.04502\");\n        assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() ==\n               \"9999-Jul-04 23:59:59.0000012\");\n        assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() ==\n               \"+10000-Oct-20 01:01:01.050789\");\n\n        assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),\n                       new immutable SimpleTimeZone(dur!\"minutes\"(-360))).toSimpleString() ==\n               \"2012-Dec-21 12:12:12-06:00\");\n\n        assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),\n                       new immutable SimpleTimeZone(dur!\"minutes\"(420))).toSimpleString() ==\n               \"2012-Dec-21 12:12:12+07:00\");\n\n        // Test B.C.\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toSimpleString() ==\n               \"0000-Dec-31 23:59:59.9999999Z\");\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toSimpleString() ==\n               \"0000-Dec-31 23:59:59.0000001Z\");\n        assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toSimpleString() == \"0000-Dec-31 23:59:59Z\");\n\n        assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toSimpleString() == \"0000-Dec-04 00:12:04\");\n        assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toSimpleString() == \"-0009-Dec-04 00:00:00\");\n        assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toSimpleString() == \"-0099-Dec-04 05:06:12\");\n        assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toSimpleString() == \"-0999-Dec-04 13:44:59\");\n        assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toSimpleString() == \"-9999-Jul-04 23:59:59\");\n        assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toSimpleString() == \"-10000-Oct-20 01:01:01\");\n\n        assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toSimpleString() == \"0000-Dec-04 00:00:00.007\");\n        assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == \"-0009-Dec-04 00:00:00.042\");\n        assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == \"-0099-Dec-04 05:06:12.1\");\n        assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() ==\n               \"-0999-Dec-04 13:44:59.04502\");\n        assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() ==\n               \"-9999-Jul-04 23:59:59.0000012\");\n        assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() ==\n               \"-10000-Oct-20 01:01:01.050789\");\n\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        assert(cst.toSimpleString() == \"1999-Jul-06 12:30:33\");\n        assert(ist.toSimpleString() == \"1999-Jul-06 12:30:33\");\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.toSimpleString();\n        }\n    }\n\n\n    /++\n        Converts this $(LREF SysTime) to a string.\n\n        This function exists to make it easy to convert a $(LREF SysTime) to a\n        string for code that does not care what the exact format is - just that\n        it presents the information in a clear manner. It also makes it easy to\n        simply convert a $(LREF SysTime) to a string when using functions such\n        as `to!string`, `format`, or `writeln` which use toString to convert\n        user-defined types. So, it is unlikely that much code will call\n        toString directly.\n\n        The format of the string is purposefully unspecified, and code that\n        cares about the format of the string should use `toISOString`,\n        `toISOExtString`, `toSimpleString`, or some other custom formatting\n        function that explicitly generates the format that the code needs. The\n        reason is that the code is then clear about what format it's using,\n        making it less error-prone to maintain the code and interact with other\n        software that consumes the generated strings. It's for this same reason\n        that $(LREF SysTime) has no `fromString` function, whereas it does have\n        `fromISOString`, `fromISOExtString`, and `fromSimpleString`.\n\n        The format returned by toString may or may not change in the future.\n\n        Params:\n            writer = A `char` accepting\n            $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n        Returns:\n            A `string` when not using an output range; `void` otherwise.\n      +/\n    string toString() @safe const nothrow scope\n    {\n        return toSimpleString();\n    }\n\n    /// ditto\n    void toString(W)(ref W writer) const scope\n    if (isOutputRange!(W, char))\n    {\n        toSimpleString(writer);\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));\n        static assert(__traits(compiles, st.toString()));\n        static assert(__traits(compiles, cst.toString()));\n        static assert(__traits(compiles, ist.toString()));\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = st.toString();\n        }\n    }\n\n\n    /++\n        Creates a $(LREF SysTime) from a string with the format\n        YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds is the time\n        zone). Whitespace is stripped from the given string.\n\n        The exact format is exactly as described in `toISOString` except that\n        trailing zeroes are permitted - including having fractional seconds with\n        all zeroes. However, a decimal point with nothing following it is\n        invalid. Also, while $(LREF toISOString) will never generate a string\n        with more than 7 digits in the fractional seconds (because that's the\n        limit with hecto-nanosecond precision), it will allow more than 7 digits\n        in order to read strings from other sources that have higher precision\n        (however, any digits beyond 7 will be truncated).\n\n        If there is no time zone in the string, then\n        $(REF LocalTime,std,datetime,timezone) is used. If the time zone is \"Z\",\n        then `UTC` is used. Otherwise, a\n        $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the\n        given offset from UTC is used. To get the returned $(LREF SysTime) to be\n        a particular time zone, pass in that time zone and the $(LREF SysTime)\n        to be returned will be converted to that time zone (though it will still\n        be read in as whatever time zone is in its string).\n\n        The accepted formats for time zone offsets are +HH, -HH, +HHMM, and\n        -HHMM.\n\n        $(RED Warning:\n            Previously, $(LREF toISOString) did the same as\n            $(LREF toISOExtString) and generated +HH:MM or -HH:MM for the time\n            zone when it was not $(REF LocalTime,std,datetime,timezone) or\n            $(REF UTC,std,datetime,timezone), which is not in conformance with\n            ISO 8601 for the non-extended string format. This has now been\n            fixed. However, for now, fromISOString will continue to accept the\n            extended format for the time zone so that any code which has been\n            writing out the result of toISOString to read in later will continue\n            to work. The current behavior will be kept until July 2019 at which\n            point, fromISOString will be fixed to be standards compliant.)\n\n        Params:\n            isoString = A string formatted in the ISO format for dates and times.\n            tz        = The time zone to convert the given time to (no\n                        conversion occurs if null).\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given string is\n            not in the ISO format or if the resulting $(LREF SysTime) would not\n            be valid.\n      +/\n    static SysTime fromISOString(S)(scope const S isoString, immutable TimeZone tz = null) @safe\n        if (isSomeString!S)\n    {\n        import std.algorithm.searching : startsWith, find;\n        import std.conv : to;\n        import std.string : strip;\n        import std.utf : byCodeUnit;\n\n        auto str = strip(isoString);\n        immutable skipFirst = str.startsWith('+', '-');\n\n        auto found = (skipFirst ? str[1..$] : str).byCodeUnit.find('.', 'Z', '+', '-');\n        auto dateTimeStr = str[0 .. $ - found[0].length];\n\n        typeof(str) fracSecStr;\n        typeof(str) zoneStr;\n\n        if (found[1] != 0)\n        {\n            if (found[1] == 1)\n            {\n                auto foundTZ = found[0].find('Z', '+', '-');\n\n                if (foundTZ[1] != 0)\n                {\n                    static if (isNarrowString!S)\n                    {\n                        fracSecStr = found[0][0 .. $ - foundTZ[0].length].source;\n                        zoneStr = foundTZ[0].source;\n                    }\n                    else\n                    {\n                        fracSecStr = found[0][0 .. $ - foundTZ[0].length];\n                        zoneStr = foundTZ[0];\n                    }\n                }\n                else\n                {\n                    static if (isNarrowString!S)\n                        fracSecStr = found[0].source;\n                    else\n                        fracSecStr = found[0];\n                }\n            }\n            else\n            {\n                static if (isNarrowString!S)\n                    zoneStr = found[0].source;\n                else\n                    zoneStr = found[0];\n            }\n        }\n\n        try\n        {\n            auto dateTime = DateTime.fromISOString(dateTimeStr);\n            auto fracSec = fracSecsFromISOString(fracSecStr);\n\n            Rebindable!(immutable TimeZone) parsedZone;\n\n            if (zoneStr.empty)\n                parsedZone = LocalTime();\n            else if (zoneStr == \"Z\")\n                parsedZone = UTC();\n            else\n            {\n                try\n                    parsedZone = SimpleTimeZone.fromISOString(zoneStr);\n                catch (DateTimeException dte)\n                    parsedZone = SimpleTimeZone.fromISOExtString(zoneStr);\n            }\n\n            auto retval = SysTime(dateTime, fracSec, parsedZone);\n\n            if (tz !is null)\n                retval.timezone = tz;\n\n            return retval;\n        }\n        catch (DateTimeException dte)\n            throw new DateTimeException(format(\"Invalid ISO String: %s\", isoString));\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : hours, msecs, usecs, hnsecs;\n        import std.datetime.date : DateTime;\n        import std.datetime.timezone : SimpleTimeZone, UTC;\n\n        assert(SysTime.fromISOString(\"20100704T070612\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12)));\n\n        assert(SysTime.fromISOString(\"19981225T021500.007\") ==\n               SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7)));\n\n        assert(SysTime.fromISOString(\"00000105T230959.00002\") ==\n               SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20)));\n\n        assert(SysTime.fromISOString(\"20130207T043937.000050392\") ==\n               SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503)));\n\n        assert(SysTime.fromISOString(\"-00040105T000002\") ==\n               SysTime(DateTime(-4, 1, 5, 0, 0, 2)));\n\n        assert(SysTime.fromISOString(\" 20100704T070612 \") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12)));\n\n        assert(SysTime.fromISOString(\"20100704T070612Z\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));\n\n        assert(SysTime.fromISOString(\"20100704T070612-0800\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12),\n                       new immutable SimpleTimeZone(hours(-8))));\n\n        assert(SysTime.fromISOString(\"20100704T070612+0800\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12),\n                       new immutable SimpleTimeZone(hours(8))));\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        foreach (str; [\"\", \"20100704000000\", \"20100704 000000\", \"20100704t000000\",\n                       \"20100704T000000.\", \"20100704T000000.A\", \"20100704T000000.Z\",\n                       \"20100704T000000.0000000A\", \"20100704T000000.00000000A\",\n                       \"20100704T000000+\", \"20100704T000000-\", \"20100704T000000:\",\n                       \"20100704T000000-:\", \"20100704T000000+:\", \"20100704T000000-1:\",\n                       \"20100704T000000+1:\", \"20100704T000000+1:0\",\n                       \"20100704T000000-12.00\", \"20100704T000000+12.00\",\n                       \"20100704T000000-8\", \"20100704T000000+8\",\n                       \"20100704T000000-800\", \"20100704T000000+800\",\n                       \"20100704T000000-080\", \"20100704T000000+080\",\n                       \"20100704T000000-2400\", \"20100704T000000+2400\",\n                       \"20100704T000000-1260\", \"20100704T000000+1260\",\n                       \"20100704T000000.0-8\", \"20100704T000000.0+8\",\n                       \"20100704T000000.0-800\", \"20100704T000000.0+800\",\n                       \"20100704T000000.0-080\", \"20100704T000000.0+080\",\n                       \"20100704T000000.0-2400\", \"20100704T000000.0+2400\",\n                       \"20100704T000000.0-1260\", \"20100704T000000.0+1260\",\n                       \"20100704T000000-8:00\", \"20100704T000000+8:00\",\n                       \"20100704T000000-08:0\", \"20100704T000000+08:0\",\n                       \"20100704T000000-24:00\", \"20100704T000000+24:00\",\n                       \"20100704T000000-12:60\", \"20100704T000000+12:60\",\n                       \"20100704T000000.0-8:00\", \"20100704T000000.0+8:00\",\n                       \"20100704T000000.0-08:0\", \"20100704T000000.0+08:0\",\n                       \"20100704T000000.0-24:00\", \"20100704T000000.0+24:00\",\n                       \"20100704T000000.0-12:60\", \"20100704T000000.0+12:60\",\n                       \"2010-07-0400:00:00\", \"2010-07-04 00:00:00\",\n                       \"2010-07-04t00:00:00\", \"2010-07-04T00:00:00.\",\n                       \"2010-Jul-0400:00:00\", \"2010-Jul-04 00:00:00\", \"2010-Jul-04t00:00:00\",\n                       \"2010-Jul-04T00:00:00\", \"2010-Jul-04 00:00:00.\",\n                       \"2010-12-22T172201\", \"2010-Dec-22 17:22:01\"])\n        {\n            assertThrown!DateTimeException(SysTime.fromISOString(str), format(\"[%s]\", str));\n        }\n\n        static void test(string str, SysTime st, size_t line = __LINE__)\n        {\n            if (SysTime.fromISOString(str) != st)\n                throw new AssertError(\"unittest failure\", __FILE__, line);\n        }\n\n        test(\"20101222T172201\", SysTime(DateTime(2010, 12, 22, 17, 22, 01)));\n        test(\"19990706T123033\", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\"-19990706T123033\", SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n        test(\"+019990706T123033\", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\"19990706T123033 \", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\" 19990706T123033\", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\" 19990706T123033 \", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n\n        test(\"19070707T121212.0\", SysTime(DateTime(1907, 07, 07, 12, 12, 12)));\n        test(\"19070707T121212.0000000\", SysTime(DateTime(1907, 07, 07, 12, 12, 12)));\n        test(\"19070707T121212.0000001\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), hnsecs(1)));\n        test(\"20100704T000000.00000000\", SysTime(Date(2010, 07, 04)));\n        test(\"20100704T000000.00000009\", SysTime(Date(2010, 07, 04)));\n        test(\"20100704T000000.00000019\", SysTime(DateTime(2010, 07, 04), hnsecs(1)));\n        test(\"19070707T121212.000001\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1)));\n        test(\"19070707T121212.0000010\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1)));\n        test(\"19070707T121212.001\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1)));\n        test(\"19070707T121212.0010000\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1)));\n\n        auto west60 = new immutable SimpleTimeZone(hours(-1));\n        auto west90 = new immutable SimpleTimeZone(minutes(-90));\n        auto west480 = new immutable SimpleTimeZone(hours(-8));\n        auto east60 = new immutable SimpleTimeZone(hours(1));\n        auto east90 = new immutable SimpleTimeZone(minutes(90));\n        auto east480 = new immutable SimpleTimeZone(hours(8));\n\n        test(\"20101222T172201Z\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC()));\n        test(\"20101222T172201-0100\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60));\n        test(\"20101222T172201-01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60));\n        test(\"20101222T172201-0130\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90));\n        test(\"20101222T172201-0800\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480));\n        test(\"20101222T172201+0100\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60));\n        test(\"20101222T172201+01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60));\n        test(\"20101222T172201+0130\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90));\n        test(\"20101222T172201+0800\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480));\n\n        test(\"20101103T065106.57159Z\", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC()));\n        test(\"20101222T172201.23412Z\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_341_200), UTC()));\n        test(\"20101222T172201.23112-0100\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60));\n        test(\"20101222T172201.45-01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), west60));\n        test(\"20101222T172201.1-0130\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90));\n        test(\"20101222T172201.55-0800\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480));\n        test(\"20101222T172201.1234567+0100\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60));\n        test(\"20101222T172201.0+01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60));\n        test(\"20101222T172201.0000000+0130\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90));\n        test(\"20101222T172201.45+0800\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480));\n\n        // for dstring coverage\n        assert(SysTime.fromISOString(\"20101222T172201.23112-0100\"d) == SysTime(\n            DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60));\n        assert(SysTime.fromISOString(\"19070707T121212.0010000\"d) == SysTime(\n            DateTime(1907, 07, 07, 12, 12, 12), msecs(1)));\n\n        // @@@DEPRECATED_2019-07@@@\n        // This isn't deprecated per se, but that text will make it so that it\n        // pops up when deprecations are moved along around July 2019. At that\n        // time, we will update fromISOString so that it is conformant with ISO\n        // 8601, and it will no longer accept ISO extended time zones (it does\n        // currently because of issue #15654 - toISOString used to incorrectly\n        // use the ISO extended time zone format). These tests will then start\n        // failing will need to be updated accordingly. Also, the notes about\n        // this issue in toISOString and fromISOString's documentation will need\n        // to be removed.\n        test(\"20101222T172201-01:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60));\n        test(\"20101222T172201-01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90));\n        test(\"20101222T172201-08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480));\n        test(\"20101222T172201+01:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60));\n        test(\"20101222T172201+01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90));\n        test(\"20101222T172201+08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480));\n\n        test(\"20101222T172201.23112-01:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60));\n        test(\"20101222T172201.1-01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90));\n        test(\"20101222T172201.55-08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480));\n        test(\"20101222T172201.1234567+01:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60));\n        test(\"20101222T172201.0000000+01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90));\n        test(\"20101222T172201.45+08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480));\n\n        static void testScope(scope ref string str) @safe\n        {\n            auto result = SysTime.fromISOString(str);\n        }\n    }\n\n    // bug# 17801\n    @safe unittest\n    {\n        import std.conv : to;\n        import std.meta : AliasSeq;\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))\n            {\n                assert(SysTime.fromISOString(to!S(\"20121221T141516Z\")) ==\n                       SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC()));\n            }\n        }\n    }\n\n\n    /++\n        Creates a $(LREF SysTime) from a string with the format\n        YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the\n        time zone). Whitespace is stripped from the given string.\n\n        The exact format is exactly as described in `toISOExtString`\n        except that trailing zeroes are permitted - including having fractional\n        seconds with all zeroes. However, a decimal point with nothing following\n        it is invalid. Also, while $(LREF toISOExtString) will never generate a\n        string with more than 7 digits in the fractional seconds (because that's\n        the limit with hecto-nanosecond precision), it will allow more than 7\n        digits in order to read strings from other sources that have higher\n        precision (however, any digits beyond 7 will be truncated).\n\n        If there is no time zone in the string, then\n        $(REF LocalTime,std,datetime,timezone) is used. If the time zone is \"Z\",\n        then `UTC` is used. Otherwise, a\n        $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the\n        given offset from UTC is used. To get the returned $(LREF SysTime) to be\n        a particular time zone, pass in that time zone and the $(LREF SysTime)\n        to be returned will be converted to that time zone (though it will still\n        be read in as whatever time zone is in its string).\n\n        The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and\n        -HH:MM.\n\n        Params:\n            isoExtString = A string formatted in the ISO Extended format for\n                           dates and times.\n            tz           = The time zone to convert the given time to (no\n                           conversion occurs if null).\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given string is\n            not in the ISO format or if the resulting $(LREF SysTime) would not\n            be valid.\n      +/\n    static SysTime fromISOExtString(S)(scope const S isoExtString, immutable TimeZone tz = null) @safe\n        if (isSomeString!(S))\n    {\n        import std.algorithm.searching : countUntil, find;\n        import std.conv : to;\n        import std.string : strip, indexOf;\n\n        auto str = strip(isoExtString);\n\n        auto tIndex = str.indexOf('T');\n        enforce(tIndex != -1, new DateTimeException(format(\"Invalid ISO Extended String: %s\", isoExtString)));\n\n        auto found = str[tIndex + 1 .. $].find('.', 'Z', '+', '-');\n        auto dateTimeStr = str[0 .. $ - found[0].length];\n\n        typeof(str) fracSecStr;\n        typeof(str) zoneStr;\n\n        if (found[1] != 0)\n        {\n            if (found[1] == 1)\n            {\n                auto foundTZ = found[0].find('Z', '+', '-');\n\n                if (foundTZ[1] != 0)\n                {\n                    fracSecStr = found[0][0 .. $ - foundTZ[0].length];\n                    zoneStr = foundTZ[0];\n                }\n                else\n                    fracSecStr = found[0];\n            }\n            else\n                zoneStr = found[0];\n        }\n\n        try\n        {\n            auto dateTime = DateTime.fromISOExtString(dateTimeStr);\n            auto fracSec = fracSecsFromISOString(fracSecStr);\n            Rebindable!(immutable TimeZone) parsedZone;\n\n            if (zoneStr.empty)\n                parsedZone = LocalTime();\n            else if (zoneStr == \"Z\")\n                parsedZone = UTC();\n            else\n                parsedZone = SimpleTimeZone.fromISOExtString(zoneStr);\n\n            auto retval = SysTime(dateTime, fracSec, parsedZone);\n\n            if (tz !is null)\n                retval.timezone = tz;\n\n            return retval;\n        }\n        catch (DateTimeException dte)\n            throw new DateTimeException(format(\"Invalid ISO Extended String: %s\", isoExtString));\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : hours, msecs, usecs, hnsecs;\n        import std.datetime.date : DateTime;\n        import std.datetime.timezone : SimpleTimeZone, UTC;\n\n        assert(SysTime.fromISOExtString(\"2010-07-04T07:06:12\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12)));\n\n        assert(SysTime.fromISOExtString(\"1998-12-25T02:15:00.007\") ==\n               SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7)));\n\n        assert(SysTime.fromISOExtString(\"0000-01-05T23:09:59.00002\") ==\n               SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20)));\n\n        assert(SysTime.fromISOExtString(\"2013-02-07T04:39:37.000050392\") ==\n               SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503)));\n\n        assert(SysTime.fromISOExtString(\"-0004-01-05T00:00:02\") ==\n               SysTime(DateTime(-4, 1, 5, 0, 0, 2)));\n\n        assert(SysTime.fromISOExtString(\" 2010-07-04T07:06:12 \") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12)));\n\n        assert(SysTime.fromISOExtString(\"2010-07-04T07:06:12Z\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));\n\n        assert(SysTime.fromISOExtString(\"2010-07-04T07:06:12-08:00\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12),\n                       new immutable SimpleTimeZone(hours(-8))));\n        assert(SysTime.fromISOExtString(\"2010-07-04T07:06:12+08:00\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12),\n                       new immutable SimpleTimeZone(hours(8))));\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        foreach (str; [\"\", \"20100704000000\", \"20100704 000000\",\n                       \"20100704t000000\", \"20100704T000000.\", \"20100704T000000.0\",\n                       \"2010-07:0400:00:00\", \"2010-07-04 00:00:00\",\n                       \"2010-07-04 00:00:00\", \"2010-07-04t00:00:00\",\n                       \"2010-07-04T00:00:00.\", \"2010-07-04T00:00:00.A\", \"2010-07-04T00:00:00.Z\",\n                       \"2010-07-04T00:00:00.0000000A\", \"2010-07-04T00:00:00.00000000A\",\n                       \"2010-07-04T00:00:00+\", \"2010-07-04T00:00:00-\",\n                       \"2010-07-04T00:00:00:\", \"2010-07-04T00:00:00-:\", \"2010-07-04T00:00:00+:\",\n                       \"2010-07-04T00:00:00-1:\", \"2010-07-04T00:00:00+1:\", \"2010-07-04T00:00:00+1:0\",\n                       \"2010-07-04T00:00:00-12.00\", \"2010-07-04T00:00:00+12.00\",\n                       \"2010-07-04T00:00:00-8\", \"2010-07-04T00:00:00+8\",\n                       \"20100704T000000-800\", \"20100704T000000+800\",\n                       \"20100704T000000-080\", \"20100704T000000+080\",\n                       \"20100704T000000-2400\", \"20100704T000000+2400\",\n                       \"20100704T000000-1260\", \"20100704T000000+1260\",\n                       \"20100704T000000.0-800\", \"20100704T000000.0+800\",\n                       \"20100704T000000.0-8\", \"20100704T000000.0+8\",\n                       \"20100704T000000.0-080\", \"20100704T000000.0+080\",\n                       \"20100704T000000.0-2400\", \"20100704T000000.0+2400\",\n                       \"20100704T000000.0-1260\", \"20100704T000000.0+1260\",\n                       \"2010-07-04T00:00:00-8:00\", \"2010-07-04T00:00:00+8:00\",\n                       \"2010-07-04T00:00:00-24:00\", \"2010-07-04T00:00:00+24:00\",\n                       \"2010-07-04T00:00:00-12:60\", \"2010-07-04T00:00:00+12:60\",\n                       \"2010-07-04T00:00:00.0-8:00\", \"2010-07-04T00:00:00.0+8:00\",\n                       \"2010-07-04T00:00:00.0-8\", \"2010-07-04T00:00:00.0+8\",\n                       \"2010-07-04T00:00:00.0-24:00\", \"2010-07-04T00:00:00.0+24:00\",\n                       \"2010-07-04T00:00:00.0-12:60\", \"2010-07-04T00:00:00.0+12:60\",\n                       \"2010-Jul-0400:00:00\", \"2010-Jul-04t00:00:00\",\n                       \"2010-Jul-04 00:00:00.\", \"2010-Jul-04 00:00:00.0\",\n                       \"20101222T172201\", \"2010-Dec-22 17:22:01\"])\n        {\n            assertThrown!DateTimeException(SysTime.fromISOExtString(str), format(\"[%s]\", str));\n        }\n\n        static void test(string str, SysTime st, size_t line = __LINE__)\n        {\n            if (SysTime.fromISOExtString(str) != st)\n                throw new AssertError(\"unittest failure\", __FILE__, line);\n        }\n\n        test(\"2010-12-22T17:22:01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01)));\n        test(\"1999-07-06T12:30:33\", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\"-1999-07-06T12:30:33\", SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n        test(\"+01999-07-06T12:30:33\", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\"1999-07-06T12:30:33 \", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\" 1999-07-06T12:30:33\", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\" 1999-07-06T12:30:33 \", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n\n        test(\"1907-07-07T12:12:12.0\", SysTime(DateTime(1907, 07, 07, 12, 12, 12)));\n        test(\"1907-07-07T12:12:12.0000000\", SysTime(DateTime(1907, 07, 07, 12, 12, 12)));\n        test(\"1907-07-07T12:12:12.0000001\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), hnsecs(1)));\n        test(\"2010-07-04T00:00:00.00000000\", SysTime(Date(2010, 07, 04)));\n        test(\"2010-07-04T00:00:00.00000009\", SysTime(Date(2010, 07, 04)));\n        test(\"2010-07-04T00:00:00.00000019\", SysTime(DateTime(2010, 07, 04), hnsecs(1)));\n        test(\"1907-07-07T12:12:12.000001\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1)));\n        test(\"1907-07-07T12:12:12.0000010\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1)));\n        test(\"1907-07-07T12:12:12.001\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1)));\n        test(\"1907-07-07T12:12:12.0010000\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1)));\n\n        auto west60 = new immutable SimpleTimeZone(hours(-1));\n        auto west90 = new immutable SimpleTimeZone(minutes(-90));\n        auto west480 = new immutable SimpleTimeZone(hours(-8));\n        auto east60 = new immutable SimpleTimeZone(hours(1));\n        auto east90 = new immutable SimpleTimeZone(minutes(90));\n        auto east480 = new immutable SimpleTimeZone(hours(8));\n\n        test(\"2010-12-22T17:22:01Z\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC()));\n        test(\"2010-12-22T17:22:01-01:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60));\n        test(\"2010-12-22T17:22:01-01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60));\n        test(\"2010-12-22T17:22:01-01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90));\n        test(\"2010-12-22T17:22:01-08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480));\n        test(\"2010-12-22T17:22:01+01:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60));\n        test(\"2010-12-22T17:22:01+01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60));\n        test(\"2010-12-22T17:22:01+01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90));\n        test(\"2010-12-22T17:22:01+08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480));\n\n        test(\"2010-11-03T06:51:06.57159Z\", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC()));\n        test(\"2010-12-22T17:22:01.23412Z\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_341_200), UTC()));\n        test(\"2010-12-22T17:22:01.23112-01:00\",\n             SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60));\n        test(\"2010-12-22T17:22:01.45-01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), west60));\n        test(\"2010-12-22T17:22:01.1-01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90));\n        test(\"2010-12-22T17:22:01.55-08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480));\n        test(\"2010-12-22T17:22:01.1234567+01:00\",\n             SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60));\n        test(\"2010-12-22T17:22:01.0+01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60));\n        test(\"2010-12-22T17:22:01.0000000+01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90));\n        test(\"2010-12-22T17:22:01.45+08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480));\n\n        static void testScope(scope ref string str) @safe\n        {\n            auto result = SysTime.fromISOExtString(str);\n        }\n    }\n\n    // bug# 17801\n    @safe unittest\n    {\n        import core.time;\n        import std.conv : to;\n        import std.meta : AliasSeq;\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))\n            {\n                assert(SysTime.fromISOExtString(to!S(\"2012-12-21T14:15:16Z\")) ==\n                       SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC()));\n            }\n        }\n    }\n\n\n    /++\n        Creates a $(LREF SysTime) from a string with the format\n        YYYY-MM-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the\n        time zone). Whitespace is stripped from the given string.\n\n        The exact format is exactly as described in `toSimpleString` except\n        that trailing zeroes are permitted - including having fractional seconds\n        with all zeroes. However, a decimal point with nothing following it is\n        invalid. Also, while $(LREF toSimpleString) will never generate a\n        string with more than 7 digits in the fractional seconds (because that's\n        the limit with hecto-nanosecond precision), it will allow more than 7\n        digits in order to read strings from other sources that have higher\n        precision (however, any digits beyond 7 will be truncated).\n\n        If there is no time zone in the string, then\n        $(REF LocalTime,std,datetime,timezone) is used. If the time zone is \"Z\",\n        then `UTC` is used. Otherwise, a\n        $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the\n        given offset from UTC is used. To get the returned $(LREF SysTime) to be\n        a particular time zone, pass in that time zone and the $(LREF SysTime)\n        to be returned will be converted to that time zone (though it will still\n        be read in as whatever time zone is in its string).\n\n        The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and\n        -HH:MM.\n\n        Params:\n            simpleString = A string formatted in the way that\n                           `toSimpleString` formats dates and times.\n            tz           = The time zone to convert the given time to (no\n                           conversion occurs if null).\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given string is\n            not in the ISO format or if the resulting $(LREF SysTime) would not\n            be valid.\n      +/\n    static SysTime fromSimpleString(S)(scope const S simpleString, immutable TimeZone tz = null) @safe\n        if (isSomeString!(S))\n    {\n        import std.algorithm.searching : find;\n        import std.conv : to;\n        import std.string : strip, indexOf;\n\n        auto str = strip(simpleString);\n\n        auto spaceIndex = str.indexOf(' ');\n        enforce(spaceIndex != -1, new DateTimeException(format(\"Invalid Simple String: %s\", simpleString)));\n\n        auto found = str[spaceIndex + 1 .. $].find('.', 'Z', '+', '-');\n        auto dateTimeStr = str[0 .. $ - found[0].length];\n\n        typeof(str) fracSecStr;\n        typeof(str) zoneStr;\n\n        if (found[1] != 0)\n        {\n            if (found[1] == 1)\n            {\n                auto foundTZ = found[0].find('Z', '+', '-');\n\n                if (foundTZ[1] != 0)\n                {\n                    fracSecStr = found[0][0 .. $ - foundTZ[0].length];\n                    zoneStr = foundTZ[0];\n                }\n                else\n                    fracSecStr = found[0];\n            }\n            else\n                zoneStr = found[0];\n        }\n\n        try\n        {\n            auto dateTime = DateTime.fromSimpleString(dateTimeStr);\n            auto fracSec = fracSecsFromISOString(fracSecStr);\n            Rebindable!(immutable TimeZone) parsedZone;\n\n            if (zoneStr.empty)\n                parsedZone = LocalTime();\n            else if (zoneStr == \"Z\")\n                parsedZone = UTC();\n            else\n                parsedZone = SimpleTimeZone.fromISOExtString(zoneStr);\n\n            auto retval = SysTime(dateTime, fracSec, parsedZone);\n\n            if (tz !is null)\n                retval.timezone = tz;\n\n            return retval;\n        }\n        catch (DateTimeException dte)\n            throw new DateTimeException(format(\"Invalid Simple String: %s\", simpleString));\n    }\n\n    ///\n    @safe unittest\n    {\n        import core.time : hours, msecs, usecs, hnsecs;\n        import std.datetime.date : DateTime;\n        import std.datetime.timezone : SimpleTimeZone, UTC;\n\n        assert(SysTime.fromSimpleString(\"2010-Jul-04 07:06:12\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12)));\n\n        assert(SysTime.fromSimpleString(\"1998-Dec-25 02:15:00.007\") ==\n               SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7)));\n\n        assert(SysTime.fromSimpleString(\"0000-Jan-05 23:09:59.00002\") ==\n               SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20)));\n\n        assert(SysTime.fromSimpleString(\"2013-Feb-07 04:39:37.000050392\") ==\n               SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503)));\n\n        assert(SysTime.fromSimpleString(\"-0004-Jan-05 00:00:02\") ==\n               SysTime(DateTime(-4, 1, 5, 0, 0, 2)));\n\n        assert(SysTime.fromSimpleString(\" 2010-Jul-04 07:06:12 \") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12)));\n\n        assert(SysTime.fromSimpleString(\"2010-Jul-04 07:06:12Z\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));\n\n        assert(SysTime.fromSimpleString(\"2010-Jul-04 07:06:12-08:00\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12),\n                       new immutable SimpleTimeZone(hours(-8))));\n\n        assert(SysTime.fromSimpleString(\"2010-Jul-04 07:06:12+08:00\") ==\n               SysTime(DateTime(2010, 7, 4, 7, 6, 12),\n                       new immutable SimpleTimeZone(hours(8))));\n    }\n\n    @safe unittest\n    {\n        import core.time;\n        foreach (str; [\"\", \"20100704000000\", \"20100704 000000\",\n                       \"20100704t000000\", \"20100704T000000.\", \"20100704T000000.0\",\n                       \"2010-07-0400:00:00\", \"2010-07-04 00:00:00\", \"2010-07-04t00:00:00\",\n                       \"2010-07-04T00:00:00.\", \"2010-07-04T00:00:00.0\",\n                       \"2010-Jul-0400:00:00\", \"2010-Jul-04t00:00:00\", \"2010-Jul-04T00:00:00\",\n                       \"2010-Jul-04 00:00:00.\", \"2010-Jul-04 00:00:00.A\", \"2010-Jul-04 00:00:00.Z\",\n                       \"2010-Jul-04 00:00:00.0000000A\", \"2010-Jul-04 00:00:00.00000000A\",\n                       \"2010-Jul-04 00:00:00+\", \"2010-Jul-04 00:00:00-\",\n                       \"2010-Jul-04 00:00:00:\", \"2010-Jul-04 00:00:00-:\",\n                       \"2010-Jul-04 00:00:00+:\", \"2010-Jul-04 00:00:00-1:\",\n                       \"2010-Jul-04 00:00:00+1:\", \"2010-Jul-04 00:00:00+1:0\",\n                       \"2010-Jul-04 00:00:00-12.00\", \"2010-Jul-04 00:00:00+12.00\",\n                       \"2010-Jul-04 00:00:00-8\", \"2010-Jul-04 00:00:00+8\",\n                       \"20100704T000000-800\", \"20100704T000000+800\",\n                       \"20100704T000000-080\", \"20100704T000000+080\",\n                       \"20100704T000000-2400\", \"20100704T000000+2400\",\n                       \"20100704T000000-1260\", \"20100704T000000+1260\",\n                       \"20100704T000000.0-800\", \"20100704T000000.0+800\",\n                       \"20100704T000000.0-8\", \"20100704T000000.0+8\",\n                       \"20100704T000000.0-080\", \"20100704T000000.0+080\",\n                       \"20100704T000000.0-2400\", \"20100704T000000.0+2400\",\n                       \"20100704T000000.0-1260\", \"20100704T000000.0+1260\",\n                       \"2010-Jul-04 00:00:00-8:00\", \"2010-Jul-04 00:00:00+8:00\",\n                       \"2010-Jul-04 00:00:00-08:0\", \"2010-Jul-04 00:00:00+08:0\",\n                       \"2010-Jul-04 00:00:00-24:00\", \"2010-Jul-04 00:00:00+24:00\",\n                       \"2010-Jul-04 00:00:00-12:60\", \"2010-Jul-04 00:00:00+24:60\",\n                       \"2010-Jul-04 00:00:00.0-8:00\", \"2010-Jul-04 00:00:00+8:00\",\n                       \"2010-Jul-04 00:00:00.0-8\", \"2010-Jul-04 00:00:00.0+8\",\n                       \"2010-Jul-04 00:00:00.0-08:0\", \"2010-Jul-04 00:00:00.0+08:0\",\n                       \"2010-Jul-04 00:00:00.0-24:00\", \"2010-Jul-04 00:00:00.0+24:00\",\n                       \"2010-Jul-04 00:00:00.0-12:60\", \"2010-Jul-04 00:00:00.0+24:60\",\n                       \"20101222T172201\", \"2010-12-22T172201\"])\n        {\n            assertThrown!DateTimeException(SysTime.fromSimpleString(str), format(\"[%s]\", str));\n        }\n\n        static void test(string str, SysTime st, size_t line = __LINE__)\n        {\n            if (SysTime.fromSimpleString(str) != st)\n                throw new AssertError(\"unittest failure\", __FILE__, line);\n        }\n\n        test(\"2010-Dec-22 17:22:01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01)));\n        test(\"1999-Jul-06 12:30:33\", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\"-1999-Jul-06 12:30:33\", SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));\n        test(\"+01999-Jul-06 12:30:33\", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\"1999-Jul-06 12:30:33 \", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\" 1999-Jul-06 12:30:33\", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n        test(\" 1999-Jul-06 12:30:33 \", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));\n\n        test(\"1907-Jul-07 12:12:12.0\", SysTime(DateTime(1907, 07, 07, 12, 12, 12)));\n        test(\"1907-Jul-07 12:12:12.0000000\", SysTime(DateTime(1907, 07, 07, 12, 12, 12)));\n        test(\"2010-Jul-04 00:00:00.00000000\", SysTime(Date(2010, 07, 04)));\n        test(\"2010-Jul-04 00:00:00.00000009\", SysTime(Date(2010, 07, 04)));\n        test(\"2010-Jul-04 00:00:00.00000019\", SysTime(DateTime(2010, 07, 04), hnsecs(1)));\n        test(\"1907-Jul-07 12:12:12.0000001\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), hnsecs(1)));\n        test(\"1907-Jul-07 12:12:12.000001\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1)));\n        test(\"1907-Jul-07 12:12:12.0000010\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1)));\n        test(\"1907-Jul-07 12:12:12.001\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1)));\n        test(\"1907-Jul-07 12:12:12.0010000\", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1)));\n\n        auto west60 = new immutable SimpleTimeZone(hours(-1));\n        auto west90 = new immutable SimpleTimeZone(minutes(-90));\n        auto west480 = new immutable SimpleTimeZone(hours(-8));\n        auto east60 = new immutable SimpleTimeZone(hours(1));\n        auto east90 = new immutable SimpleTimeZone(minutes(90));\n        auto east480 = new immutable SimpleTimeZone(hours(8));\n\n        test(\"2010-Dec-22 17:22:01Z\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC()));\n        test(\"2010-Dec-22 17:22:01-01:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60));\n        test(\"2010-Dec-22 17:22:01-01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60));\n        test(\"2010-Dec-22 17:22:01-01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90));\n        test(\"2010-Dec-22 17:22:01-08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480));\n        test(\"2010-Dec-22 17:22:01+01:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60));\n        test(\"2010-Dec-22 17:22:01+01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60));\n        test(\"2010-Dec-22 17:22:01+01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90));\n        test(\"2010-Dec-22 17:22:01+08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480));\n\n        test(\"2010-Nov-03 06:51:06.57159Z\", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC()));\n        test(\"2010-Dec-22 17:22:01.23412Z\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_341_200), UTC()));\n        test(\"2010-Dec-22 17:22:01.23112-01:00\",\n             SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60));\n        test(\"2010-Dec-22 17:22:01.45-01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), west60));\n        test(\"2010-Dec-22 17:22:01.1-01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90));\n        test(\"2010-Dec-22 17:22:01.55-08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480));\n        test(\"2010-Dec-22 17:22:01.1234567+01:00\",\n             SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60));\n        test(\"2010-Dec-22 17:22:01.0+01\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60));\n        test(\"2010-Dec-22 17:22:01.0000000+01:30\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90));\n        test(\"2010-Dec-22 17:22:01.45+08:00\", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480));\n\n        static void testScope(scope ref string str) @safe\n        {\n            auto result = SysTime.fromSimpleString(str);\n        }\n    }\n\n    // bug# 17801\n    @safe unittest\n    {\n        import core.time;\n        import std.conv : to;\n        import std.meta : AliasSeq;\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))\n            {\n                assert(SysTime.fromSimpleString(to!S(\"2012-Dec-21 14:15:16Z\")) ==\n                       SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC()));\n            }\n        }\n    }\n\n\n    /++\n        Returns the $(LREF SysTime) farthest in the past which is representable\n        by $(LREF SysTime).\n\n        The $(LREF SysTime) which is returned is in UTC.\n      +/\n    @property static SysTime min() @safe pure nothrow\n    {\n        return SysTime(long.min, UTC());\n    }\n\n    @safe unittest\n    {\n        assert(SysTime.min.year < 0);\n        assert(SysTime.min < SysTime.max);\n    }\n\n\n    /++\n        Returns the $(LREF SysTime) farthest in the future which is representable\n        by $(LREF SysTime).\n\n        The $(LREF SysTime) which is returned is in UTC.\n      +/\n    @property static SysTime max() @safe pure nothrow\n    {\n        return SysTime(long.max, UTC());\n    }\n\n    @safe unittest\n    {\n        assert(SysTime.max.year > 0);\n        assert(SysTime.max > SysTime.min);\n    }\n\n\nprivate:\n\n    /+\n        Returns `stdTime` converted to $(LREF SysTime)'s time zone.\n      +/\n    @property long adjTime() @safe const nothrow scope\n    {\n        return _timezone.utcToTZ(_stdTime);\n    }\n\n\n    /+\n        Converts the given hnsecs from $(LREF SysTime)'s time zone to std time.\n      +/\n    @property void adjTime(long adjTime) @safe nothrow scope\n    {\n        _stdTime = _timezone.tzToUTC(adjTime);\n    }\n\n\n    final class InitTimeZone : TimeZone\n    {\n    public:\n\n        static immutable(InitTimeZone) opCall() @safe pure nothrow @nogc { return _initTimeZone; }\n\n        @property override bool hasDST() @safe const nothrow @nogc { return false; }\n\n        override bool dstInEffect(long stdTime) @safe const nothrow @nogc { return false; }\n\n        override long utcToTZ(long stdTime) @safe const nothrow @nogc { return 0; }\n\n        override long tzToUTC(long adjTime) @safe const nothrow @nogc { return 0; }\n\n        override Duration utcOffsetAt(long stdTime) @safe const nothrow @nogc { return Duration.zero; }\n\n    private:\n\n        this() @safe immutable pure\n        {\n            super(\"SysTime.init's timezone\", \"SysTime.init's timezone\", \"SysTime.init's timezone\");\n        }\n\n        static immutable InitTimeZone _initTimeZone = new immutable(InitTimeZone);\n    }\n\n    // https://issues.dlang.org/show_bug.cgi?id=17732\n    @safe unittest\n    {\n        assert(SysTime.init.timezone is InitTimeZone());\n        assert(SysTime.init.toISOString() == \"00010101T000000+00:00\");\n        assert(SysTime.init.toISOExtString() == \"0001-01-01T00:00:00+00:00\");\n        assert(SysTime.init.toSimpleString() == \"0001-Jan-01 00:00:00+00:00\");\n        assert(SysTime.init.toString() == \"0001-Jan-01 00:00:00+00:00\");\n    }\n\n    // Assigning a value to _timezone in SysTime.init currently doesn't work due\n    // to https://issues.dlang.org/show_bug.cgi?id=17740. So, to hack around\n    // that problem, these accessors have been added so that we can insert a\n    // runtime check for null and then use InitTimeZone for SysTime.init (which\n    // which is the only case where _timezone would be null). This thus fixes\n    // the problem with segfaulting when using SysTime.init but at the cost of\n    // what should be an unnecessary null check. Once 17740 has finally been\n    // fixed, _timezoneStorage should be removed, these accessors should be\n    // removed, and the _timezone variable declaration should be restored.\n    pragma(inline, true) @property _timezone() @safe const pure nothrow @nogc\n    {\n        return _timezoneStorage is null ? InitTimeZone() : _timezoneStorage;\n    }\n\n    pragma(inline, true) @property void _timezone(immutable TimeZone tz) @safe pure nothrow @nogc scope\n    {\n        _timezoneStorage = tz;\n    }\n\n\n    long  _stdTime;\n    Rebindable!(immutable TimeZone) _timezoneStorage;\n    //Rebindable!(immutable TimeZone) _timezone = InitTimeZone();\n}\n\n///\n@safe unittest\n{\n    import core.time : days, hours, seconds;\n    import std.datetime.date : DateTime;\n    import std.datetime.timezone : SimpleTimeZone, UTC;\n\n    // make a specific point in time in the UTC timezone\n    auto st = SysTime(DateTime(2018, 1, 1, 10, 30, 0), UTC());\n    // make a specific point in time in the New York timezone\n    auto ny = SysTime(\n        DateTime(2018, 1, 1, 10, 30, 0),\n        new immutable SimpleTimeZone(-5.hours, \"America/New_York\")\n    );\n\n    // ISO standard time strings\n    assert(st.toISOString() == \"20180101T103000Z\");\n    assert(st.toISOExtString() == \"2018-01-01T10:30:00Z\");\n\n    // add two days and 30 seconds\n    st += 2.days + 30.seconds;\n    assert(st.toISOExtString() == \"2018-01-03T10:30:30Z\");\n}\n\n\n/++\n    Converts from unix time (which uses midnight, January 1st, 1970 UTC as its\n    epoch and seconds as its units) to \"std time\" (which uses midnight,\n    January 1st, 1 A.D. UTC and hnsecs as its units).\n\n    The C standard does not specify the representation of time_t, so it is\n    implementation defined. On POSIX systems, unix time is equivalent to\n    time_t, but that's not necessarily true on other systems (e.g. it is\n    not true for the Digital Mars C runtime). So, be careful when using unix\n    time with C functions on non-POSIX systems.\n\n    \"std time\"'s epoch is based on the Proleptic Gregorian Calendar per ISO\n    8601 and is what $(LREF SysTime) uses internally. However, holding the time\n    as an integer in hnsecs since that epoch technically isn't actually part of\n    the standard, much as it's based on it, so the name \"std time\" isn't\n    particularly good, but there isn't an official name for it. C# uses \"ticks\"\n    for the same thing, but they aren't actually clock ticks, and the term\n    \"ticks\" $(I is) used for actual clock ticks for $(REF MonoTime, core,time),\n    so it didn't make sense to use the term ticks here. So, for better or worse,\n    std.datetime uses the term \"std time\" for this.\n\n    Params:\n        unixTime = The unix time to convert.\n\n    See_Also:\n        SysTime.fromUnixTime\n  +/\nlong unixTimeToStdTime(long unixTime) @safe pure nothrow @nogc\n{\n    return 621_355_968_000_000_000L + convert!(\"seconds\", \"hnsecs\")(unixTime);\n}\n\n///\n@safe unittest\n{\n    import std.datetime.date : DateTime;\n    import std.datetime.timezone : UTC;\n\n    // Midnight, January 1st, 1970\n    assert(unixTimeToStdTime(0) == 621_355_968_000_000_000L);\n    assert(SysTime(unixTimeToStdTime(0)) ==\n           SysTime(DateTime(1970, 1, 1), UTC()));\n\n    assert(unixTimeToStdTime(int.max) == 642_830_804_470_000_000L);\n    assert(SysTime(unixTimeToStdTime(int.max)) ==\n           SysTime(DateTime(2038, 1, 19, 3, 14, 07), UTC()));\n\n    assert(unixTimeToStdTime(-127_127) == 621_354_696_730_000_000L);\n    assert(SysTime(unixTimeToStdTime(-127_127)) ==\n           SysTime(DateTime(1969, 12, 30, 12, 41, 13), UTC()));\n}\n\n@safe unittest\n{\n    // Midnight, January 2nd, 1970\n    assert(unixTimeToStdTime(86_400) == 621_355_968_000_000_000L + 864_000_000_000L);\n    // Midnight, December 31st, 1969\n    assert(unixTimeToStdTime(-86_400) == 621_355_968_000_000_000L - 864_000_000_000L);\n\n    assert(unixTimeToStdTime(0) == (Date(1970, 1, 1) - Date(1, 1, 1)).total!\"hnsecs\");\n    assert(unixTimeToStdTime(0) == (DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!\"hnsecs\");\n\n    foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)])\n        assert(unixTimeToStdTime((dt - DateTime(1970, 1, 1)).total!\"seconds\") == (dt - DateTime.init).total!\"hnsecs\");\n}\n\n\n/++\n    Converts std time (which uses midnight, January 1st, 1 A.D. UTC as its epoch\n    and hnsecs as its units) to unix time (which uses midnight, January 1st,\n    1970 UTC as its epoch and seconds as its units).\n\n    The C standard does not specify the representation of time_t, so it is\n    implementation defined. On POSIX systems, unix time is equivalent to\n    time_t, but that's not necessarily true on other systems (e.g. it is\n    not true for the Digital Mars C runtime). So, be careful when using unix\n    time with C functions on non-POSIX systems.\n\n    \"std time\"'s epoch is based on the Proleptic Gregorian Calendar per ISO\n    8601 and is what $(LREF SysTime) uses internally. However, holding the time\n    as an integer in hnescs since that epoch technically isn't actually part of\n    the standard, much as it's based on it, so the name \"std time\" isn't\n    particularly good, but there isn't an official name for it. C# uses \"ticks\"\n    for the same thing, but they aren't actually clock ticks, and the term\n    \"ticks\" $(I is) used for actual clock ticks for $(REF MonoTime, core,time),\n    so it didn't make sense to use the term ticks here. So, for better or worse,\n    std.datetime uses the term \"std time\" for this.\n\n    By default, the return type is time_t (which is normally an alias for\n    int on 32-bit systems and long on 64-bit systems), but if a different\n    size is required than either int or long can be passed as a template\n    argument to get the desired size.\n\n    If the return type is int, and the result can't fit in an int, then the\n    closest value that can be held in 32 bits will be used (so `int.max`\n    if it goes over and `int.min` if it goes under). However, no attempt\n    is made to deal with integer overflow if the return type is long.\n\n    Params:\n        T = The return type (int or long). It defaults to time_t, which is\n            normally 32 bits on a 32-bit system and 64 bits on a 64-bit\n            system.\n        stdTime = The std time to convert.\n\n    Returns:\n        A signed integer representing the unix time which is equivalent to\n        the given std time.\n\n    See_Also:\n        SysTime.toUnixTime\n  +/\nT stdTimeToUnixTime(T = time_t)(long stdTime) @safe pure nothrow\nif (is(T == int) || is(T == long))\n{\n    immutable unixTime = convert!(\"hnsecs\", \"seconds\")(stdTime - 621_355_968_000_000_000L);\n\n    static assert(is(time_t == int) || is(time_t == long),\n                  \"Currently, std.datetime only supports systems where time_t is int or long\");\n\n    static if (is(T == long))\n        return unixTime;\n    else static if (is(T == int))\n    {\n        if (unixTime > int.max)\n            return int.max;\n        return unixTime < int.min ? int.min : cast(int) unixTime;\n    }\n    else\n        static assert(0, \"Bug in template constraint. Only int and long allowed.\");\n}\n\n///\n@safe unittest\n{\n    // Midnight, January 1st, 1970 UTC\n    assert(stdTimeToUnixTime(621_355_968_000_000_000L) == 0);\n\n    // 2038-01-19 03:14:07 UTC\n    assert(stdTimeToUnixTime(642_830_804_470_000_000L) == int.max);\n}\n\n@safe unittest\n{\n    enum unixEpochAsStdTime = (Date(1970, 1, 1) - Date.init).total!\"hnsecs\";\n\n    assert(stdTimeToUnixTime(unixEpochAsStdTime) == 0);  // Midnight, January 1st, 1970\n    assert(stdTimeToUnixTime(unixEpochAsStdTime + 864_000_000_000L) == 86_400);  // Midnight, January 2nd, 1970\n    assert(stdTimeToUnixTime(unixEpochAsStdTime - 864_000_000_000L) == -86_400);  // Midnight, December 31st, 1969\n\n    assert(stdTimeToUnixTime((Date(1970, 1, 1) - Date(1, 1, 1)).total!\"hnsecs\") == 0);\n    assert(stdTimeToUnixTime((DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!\"hnsecs\") == 0);\n\n    foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)])\n        assert(stdTimeToUnixTime((dt - DateTime.init).total!\"hnsecs\") == (dt - DateTime(1970, 1, 1)).total!\"seconds\");\n\n    enum max = convert!(\"seconds\", \"hnsecs\")(int.max);\n    enum min = convert!(\"seconds\", \"hnsecs\")(int.min);\n    enum one = convert!(\"seconds\", \"hnsecs\")(1);\n\n    assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max) == int.max);\n    assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max) == int.max);\n\n    assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + one) == int.max + 1L);\n    assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + one) == int.max);\n    assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + 9_999_999) == int.max);\n    assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + 9_999_999) == int.max);\n\n    assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min) == int.min);\n    assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min) == int.min);\n\n    assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - one) == int.min - 1L);\n    assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - one) == int.min);\n    assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - 9_999_999) == int.min);\n    assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - 9_999_999) == int.min);\n}\n\n\nversion (StdDdoc)\n{\n    version (Windows)\n    {}\n    else\n    {\n        alias SYSTEMTIME = void*;\n        alias FILETIME = void*;\n    }\n\n    /++\n        $(BLUE This function is Windows-Only.)\n\n        Converts a `SYSTEMTIME` struct to a $(LREF SysTime).\n\n        Params:\n            st = The `SYSTEMTIME` struct to convert.\n            tz = The time zone that the time in the `SYSTEMTIME` struct is\n                 assumed to be (if the `SYSTEMTIME` was supplied by a Windows\n                 system call, the `SYSTEMTIME` will either be in local time\n                 or UTC, depending on the call).\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given\n            `SYSTEMTIME` will not fit in a $(LREF SysTime), which is highly\n            unlikely to happen given that `SysTime.max` is in 29,228 A.D. and\n            the maximum `SYSTEMTIME` is in 30,827 A.D.\n      +/\n    SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe;\n\n\n    /++\n        $(BLUE This function is Windows-Only.)\n\n        Converts a $(LREF SysTime) to a `SYSTEMTIME` struct.\n\n        The `SYSTEMTIME` which is returned will be set using the given\n        $(LREF SysTime)'s time zone, so to get the `SYSTEMTIME` in\n        UTC, set the $(LREF SysTime)'s time zone to UTC.\n\n        Params:\n            sysTime = The $(LREF SysTime) to convert.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given\n            $(LREF SysTime) will not fit in a `SYSTEMTIME`. This will only\n            happen if the $(LREF SysTime)'s date is prior to 1601 A.D.\n      +/\n    SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe;\n\n\n    /++\n        $(BLUE This function is Windows-Only.)\n\n        Converts a `FILETIME` struct to the number of hnsecs since midnight,\n        January 1st, 1 A.D.\n\n        Params:\n            ft = The `FILETIME` struct to convert.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given\n            `FILETIME` cannot be represented as the return value.\n      +/\n    long FILETIMEToStdTime(scope const FILETIME* ft) @safe;\n\n\n    /++\n        $(BLUE This function is Windows-Only.)\n\n        Converts a `FILETIME` struct to a $(LREF SysTime).\n\n        Params:\n            ft = The `FILETIME` struct to convert.\n            tz = The time zone that the $(LREF SysTime) will be in\n                 (`FILETIME`s are in UTC).\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given\n            `FILETIME` will not fit in a $(LREF SysTime).\n      +/\n    SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe;\n\n\n    /++\n        $(BLUE This function is Windows-Only.)\n\n        Converts a number of hnsecs since midnight, January 1st, 1 A.D. to a\n        `FILETIME` struct.\n\n        Params:\n            stdTime = The number of hnsecs since midnight, January 1st, 1 A.D.\n                      UTC.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given value will\n            not fit in a `FILETIME`.\n      +/\n    FILETIME stdTimeToFILETIME(long stdTime) @safe;\n\n\n    /++\n        $(BLUE This function is Windows-Only.)\n\n        Converts a $(LREF SysTime) to a `FILETIME` struct.\n\n        `FILETIME`s are always in UTC.\n\n        Params:\n            sysTime = The $(LREF SysTime) to convert.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given\n            $(LREF SysTime) will not fit in a `FILETIME`.\n      +/\n    FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe;\n}\nelse version (Windows)\n{\n    SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe\n    {\n        const max = SysTime.max;\n\n        static void throwLaterThanMax()\n        {\n            throw new DateTimeException(\"The given SYSTEMTIME is for a date greater than SysTime.max.\");\n        }\n\n        if (st.wYear > max.year)\n            throwLaterThanMax();\n        else if (st.wYear == max.year)\n        {\n            if (st.wMonth > max.month)\n                throwLaterThanMax();\n            else if (st.wMonth == max.month)\n            {\n                if (st.wDay > max.day)\n                    throwLaterThanMax();\n                else if (st.wDay == max.day)\n                {\n                    if (st.wHour > max.hour)\n                        throwLaterThanMax();\n                    else if (st.wHour == max.hour)\n                    {\n                        if (st.wMinute > max.minute)\n                            throwLaterThanMax();\n                        else if (st.wMinute == max.minute)\n                        {\n                            if (st.wSecond > max.second)\n                                throwLaterThanMax();\n                            else if (st.wSecond == max.second)\n                            {\n                                if (st.wMilliseconds > max.fracSecs.total!\"msecs\")\n                                    throwLaterThanMax();\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        auto dt = DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);\n\n        import core.time : msecs;\n        return SysTime(dt, msecs(st.wMilliseconds), tz);\n    }\n\n    @system unittest\n    {\n        auto sysTime = Clock.currTime(UTC());\n        SYSTEMTIME st = void;\n        GetSystemTime(&st);\n        auto converted = SYSTEMTIMEToSysTime(&st, UTC());\n        import core.time : abs;\n        assert(abs((converted - sysTime)) <= dur!\"seconds\"(2));\n\n        static void testScope(scope SYSTEMTIME* st) @safe\n        {\n            auto result = SYSTEMTIMEToSysTime(st);\n        }\n    }\n\n\n    SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe\n    {\n        immutable dt = cast(DateTime) sysTime;\n\n        if (dt.year < 1601)\n            throw new DateTimeException(\"SYSTEMTIME cannot hold dates prior to the year 1601.\");\n\n        SYSTEMTIME st;\n\n        st.wYear = dt.year;\n        st.wMonth = dt.month;\n        st.wDayOfWeek = dt.dayOfWeek;\n        st.wDay = dt.day;\n        st.wHour = dt.hour;\n        st.wMinute = dt.minute;\n        st.wSecond = dt.second;\n        st.wMilliseconds = cast(ushort) sysTime.fracSecs.total!\"msecs\";\n\n        return st;\n    }\n\n    @system unittest\n    {\n        SYSTEMTIME st = void;\n        GetSystemTime(&st);\n        auto sysTime = SYSTEMTIMEToSysTime(&st, UTC());\n\n        SYSTEMTIME result = SysTimeToSYSTEMTIME(sysTime);\n\n        assert(st.wYear == result.wYear);\n        assert(st.wMonth == result.wMonth);\n        assert(st.wDayOfWeek == result.wDayOfWeek);\n        assert(st.wDay == result.wDay);\n        assert(st.wHour == result.wHour);\n        assert(st.wMinute == result.wMinute);\n        assert(st.wSecond == result.wSecond);\n        assert(st.wMilliseconds == result.wMilliseconds);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = SysTimeToSYSTEMTIME(st);\n        }\n    }\n\n    private enum hnsecsFrom1601 = 504_911_232_000_000_000L;\n\n    long FILETIMEToStdTime(scope const FILETIME* ft) @safe\n    {\n        ULARGE_INTEGER ul;\n        ul.HighPart = ft.dwHighDateTime;\n        ul.LowPart = ft.dwLowDateTime;\n        ulong tempHNSecs = ul.QuadPart;\n\n        if (tempHNSecs > long.max - hnsecsFrom1601)\n            throw new DateTimeException(\"The given FILETIME cannot be represented as a stdTime value.\");\n\n        return cast(long) tempHNSecs + hnsecsFrom1601;\n    }\n\n    SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe\n    {\n        auto sysTime = SysTime(FILETIMEToStdTime(ft), UTC());\n        sysTime.timezone = tz;\n        return sysTime;\n    }\n\n    @system unittest\n    {\n        auto sysTime = Clock.currTime(UTC());\n        SYSTEMTIME st = void;\n        GetSystemTime(&st);\n\n        FILETIME ft = void;\n        SystemTimeToFileTime(&st, &ft);\n\n        auto converted = FILETIMEToSysTime(&ft);\n\n        import core.time : abs;\n        assert(abs((converted - sysTime)) <= dur!\"seconds\"(2));\n\n        static void testScope(scope FILETIME* ft) @safe\n        {\n            auto result = FILETIMEToSysTime(ft);\n        }\n    }\n\n\n    FILETIME stdTimeToFILETIME(long stdTime) @safe\n    {\n        if (stdTime < hnsecsFrom1601)\n            throw new DateTimeException(\"The given stdTime value cannot be represented as a FILETIME.\");\n\n        ULARGE_INTEGER ul;\n        ul.QuadPart = cast(ulong) stdTime - hnsecsFrom1601;\n\n        FILETIME ft;\n        ft.dwHighDateTime = ul.HighPart;\n        ft.dwLowDateTime = ul.LowPart;\n\n        return ft;\n    }\n\n    FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe\n    {\n        return stdTimeToFILETIME(sysTime.stdTime);\n    }\n\n    @system unittest\n    {\n        SYSTEMTIME st = void;\n        GetSystemTime(&st);\n\n        FILETIME ft = void;\n        SystemTimeToFileTime(&st, &ft);\n        auto sysTime = FILETIMEToSysTime(&ft, UTC());\n\n        FILETIME result = SysTimeToFILETIME(sysTime);\n\n        assert(ft.dwLowDateTime == result.dwLowDateTime);\n        assert(ft.dwHighDateTime == result.dwHighDateTime);\n\n        static void testScope(scope ref SysTime st) @safe\n        {\n            auto result = SysTimeToFILETIME(st);\n        }\n    }\n}\n\n\n/++\n    Type representing the DOS file date/time format.\n  +/\nalias DosFileTime = uint;\n\n/++\n    Converts from DOS file date/time to $(LREF SysTime).\n\n    Params:\n        dft = The DOS file time to convert.\n        tz  = The time zone which the DOS file time is assumed to be in.\n\n    Throws:\n        $(REF DateTimeException,std,datetime,date) if the `DosFileTime` is\n        invalid.\n  +/\nSysTime DosFileTimeToSysTime(DosFileTime dft, immutable TimeZone tz = LocalTime()) @safe\n{\n    uint dt = cast(uint) dft;\n\n    if (dt == 0)\n        throw new DateTimeException(\"Invalid DosFileTime.\");\n\n    int year = ((dt >> 25) & 0x7F) + 1980;\n    int month = ((dt >> 21) & 0x0F);       // 1 .. 12\n    int dayOfMonth = ((dt >> 16) & 0x1F);  // 1 .. 31\n    int hour = (dt >> 11) & 0x1F;          // 0 .. 23\n    int minute = (dt >> 5) & 0x3F;         // 0 .. 59\n    int second = (dt << 1) & 0x3E;         // 0 .. 58 (in 2 second increments)\n\n    try\n        return SysTime(DateTime(year, month, dayOfMonth, hour, minute, second), tz);\n    catch (DateTimeException dte)\n        throw new DateTimeException(\"Invalid DosFileTime\", __FILE__, __LINE__, dte);\n}\n\n///\n@safe unittest\n{\n    import std.datetime.date : DateTime;\n\n    assert(DosFileTimeToSysTime(0b00000000001000010000000000000000) == SysTime(DateTime(1980, 1, 1, 0, 0, 0)));\n    assert(DosFileTimeToSysTime(0b11111111100111111011111101111101) == SysTime(DateTime(2107, 12, 31, 23, 59, 58)));\n    assert(DosFileTimeToSysTime(0x3E3F8456) == SysTime(DateTime(2011, 1, 31, 16, 34, 44)));\n}\n\n@safe unittest\n{\n    static void testScope(scope ref DosFileTime dft) @safe\n    {\n        auto result = DosFileTimeToSysTime(dft);\n    }\n}\n\n\n/++\n    Converts from $(LREF SysTime) to DOS file date/time.\n\n    Params:\n        sysTime = The $(LREF SysTime) to convert.\n\n    Throws:\n        $(REF DateTimeException,std,datetime,date) if the given\n        $(LREF SysTime) cannot be converted to a `DosFileTime`.\n  +/\nDosFileTime SysTimeToDosFileTime(scope SysTime sysTime) @safe\n{\n    auto dateTime = cast(DateTime) sysTime;\n\n    if (dateTime.year < 1980)\n        throw new DateTimeException(\"DOS File Times cannot hold dates prior to 1980.\");\n\n    if (dateTime.year > 2107)\n        throw new DateTimeException(\"DOS File Times cannot hold dates past 2107.\");\n\n    uint retval = 0;\n    retval = (dateTime.year - 1980) << 25;\n    retval |= (dateTime.month & 0x0F) << 21;\n    retval |= (dateTime.day & 0x1F) << 16;\n    retval |= (dateTime.hour & 0x1F) << 11;\n    retval |= (dateTime.minute & 0x3F) << 5;\n    retval |= (dateTime.second >> 1) & 0x1F;\n\n    return cast(DosFileTime) retval;\n}\n\n///\n@safe unittest\n{\n    import std.datetime.date : DateTime;\n\n    assert(SysTimeToDosFileTime(SysTime(DateTime(1980, 1, 1, 0, 0, 0))) == 0b00000000001000010000000000000000);\n    assert(SysTimeToDosFileTime(SysTime(DateTime(2107, 12, 31, 23, 59, 58))) == 0b11111111100111111011111101111101);\n    assert(SysTimeToDosFileTime(SysTime(DateTime(2011, 1, 31, 16, 34, 44))) == 0x3E3F8456);\n}\n\n@safe unittest\n{\n    static void testScope(scope ref SysTime st) @safe\n    {\n        auto result = SysTimeToDosFileTime(st);\n    }\n}\n\n\n/++\n    The given array of `char` or random-access range of `char` or\n    `ubyte` is expected to be in the format specified in\n    $(HTTP tools.ietf.org/html/rfc5322, RFC 5322) section 3.3 with the\n    grammar rule $(I date-time). It is the date-time format commonly used in\n    internet messages such as e-mail and HTTP. The corresponding\n    $(LREF SysTime) will be returned.\n\n    RFC 822 was the original spec (hence the function's name), whereas RFC 5322\n    is the current spec.\n\n    The day of the week is ignored beyond verifying that it's a valid day of the\n    week, as the day of the week can be inferred from the date. It is not\n    checked whether the given day of the week matches the actual day of the week\n    of the given date (though it is technically invalid per the spec if the\n    day of the week doesn't match the actual day of the week of the given date).\n\n    If the time zone is `\"-0000\"` (or considered to be equivalent to\n    `\"-0000\"` by section 4.3 of the spec), a\n    $(REF SimpleTimeZone,std,datetime,timezone) with a utc offset of `0` is\n    used rather than $(REF UTC,std,datetime,timezone), whereas `\"+0000\"` uses\n    $(REF UTC,std,datetime,timezone).\n\n    Note that because $(LREF SysTime) does not currently support having a second\n    value of 60 (as is sometimes done for leap seconds), if the date-time value\n    does have a value of 60 for the seconds, it is treated as 59.\n\n    The one area in which this function violates RFC 5322 is that it accepts\n    `\"\\n\"` in folding whitespace in the place of `\"\\r\\n\"`, because the\n    HTTP spec requires it.\n\n    Throws:\n        $(REF DateTimeException,std,datetime,date) if the given string doesn't\n        follow the grammar for a date-time field or if the resulting\n        $(LREF SysTime) is invalid.\n  +/\nSysTime parseRFC822DateTime()(scope const char[] value) @safe\n{\n    import std.string : representation;\n    return parseRFC822DateTime(value.representation);\n}\n\n/++ Ditto +/\nSysTime parseRFC822DateTime(R)(scope R value)\nif (isRandomAccessRange!R && hasSlicing!R && hasLength!R &&\n    (is(Unqual!(ElementType!R) == char) || is(Unqual!(ElementType!R) == ubyte)))\n{\n    import std.algorithm.searching : find, all;\n    import std.ascii : isDigit, isAlpha, isPrintable;\n    import std.conv : to;\n    import std.functional : not;\n    import std.string : capitalize, format;\n    import std.traits : EnumMembers, isArray;\n    import std.typecons : Rebindable;\n\n    void stripAndCheckLen(R valueBefore, size_t minLen, size_t line = __LINE__)\n    {\n        value = _stripCFWS(valueBefore);\n        if (value.length < minLen)\n            throw new DateTimeException(\"date-time value too short\", __FILE__, line);\n    }\n    stripAndCheckLen(value, \"7Dec1200:00A\".length);\n\n    static if (isArray!R && (is(ElementEncodingType!R == char) || is(ElementEncodingType!R == ubyte)))\n    {\n        static string sliceAsString(R str) @trusted\n        {\n            return cast(string) str;\n        }\n    }\n    else\n    {\n        char[4] temp;\n        char[] sliceAsString(R str) @trusted\n        {\n            size_t i = 0;\n            foreach (c; str)\n                temp[i++] = cast(char) c;\n            return temp[0 .. str.length];\n        }\n    }\n\n    // day-of-week\n    if (isAlpha(value[0]))\n    {\n        auto dowStr = sliceAsString(value[0 .. 3]);\n        switch (dowStr)\n        {\n            foreach (dow; EnumMembers!DayOfWeek)\n            {\n                enum dowC = capitalize(to!string(dow));\n                case dowC:\n                    goto afterDoW;\n            }\n            default: throw new DateTimeException(format(\"Invalid day-of-week: %s\", dowStr));\n        }\nafterDoW: stripAndCheckLen(value[3 .. value.length], \",7Dec1200:00A\".length);\n        if (value[0] != ',')\n            throw new DateTimeException(\"day-of-week missing comma\");\n        stripAndCheckLen(value[1 .. value.length], \"7Dec1200:00A\".length);\n    }\n\n    // day\n    immutable digits = isDigit(value[1]) ? 2 : 1;\n    immutable day = _convDigits!short(value[0 .. digits]);\n    if (day == -1)\n        throw new DateTimeException(\"Invalid day\");\n    stripAndCheckLen(value[digits .. value.length], \"Dec1200:00A\".length);\n\n    // month\n    Month month;\n    {\n        auto monStr = sliceAsString(value[0 .. 3]);\n        switch (monStr)\n        {\n            foreach (mon; EnumMembers!Month)\n            {\n                enum monC = capitalize(to!string(mon));\n                case monC:\n                {\n                    month = mon;\n                    goto afterMon;\n                }\n            }\n            default: throw new DateTimeException(format(\"Invalid month: %s\", monStr));\n        }\nafterMon: stripAndCheckLen(value[3 .. value.length], \"1200:00A\".length);\n    }\n\n    // year\n    auto found = value[2 .. value.length].find!(not!(std.ascii.isDigit))();\n    size_t yearLen = value.length - found.length;\n    if (found.length == 0)\n        throw new DateTimeException(\"Invalid year\");\n    if (found[0] == ':')\n        yearLen -= 2;\n    auto year = _convDigits!short(value[0 .. yearLen]);\n    if (year < 1900)\n    {\n        if (year == -1)\n            throw new DateTimeException(\"Invalid year\");\n        if (yearLen < 4)\n        {\n            if (yearLen == 3)\n                year += 1900;\n            else if (yearLen == 2)\n                year += year < 50 ? 2000 : 1900;\n            else\n                throw new DateTimeException(\"Invalid year. Too few digits.\");\n        }\n        else\n            throw new DateTimeException(\"Invalid year. Cannot be earlier than 1900.\");\n    }\n    stripAndCheckLen(value[yearLen .. value.length], \"00:00A\".length);\n\n    // hour\n    immutable hour = _convDigits!short(value[0 .. 2]);\n    stripAndCheckLen(value[2 .. value.length], \":00A\".length);\n    if (value[0] != ':')\n        throw new DateTimeException(\"Invalid hour\");\n    stripAndCheckLen(value[1 .. value.length], \"00A\".length);\n\n    // minute\n    immutable minute = _convDigits!short(value[0 .. 2]);\n    stripAndCheckLen(value[2 .. value.length], \"A\".length);\n\n    // second\n    short second;\n    if (value[0] == ':')\n    {\n        stripAndCheckLen(value[1 .. value.length], \"00A\".length);\n        second = _convDigits!short(value[0 .. 2]);\n        // this is just if/until SysTime is sorted out to fully support leap seconds\n        if (second == 60)\n            second = 59;\n        stripAndCheckLen(value[2 .. value.length], \"A\".length);\n    }\n\n    immutable(TimeZone) parseTZ(int sign)\n    {\n        if (value.length < 5)\n            throw new DateTimeException(\"Invalid timezone\");\n        immutable zoneHours = _convDigits!short(value[1 .. 3]);\n        immutable zoneMinutes = _convDigits!short(value[3 .. 5]);\n        if (zoneHours == -1 || zoneMinutes == -1 || zoneMinutes > 59)\n            throw new DateTimeException(\"Invalid timezone\");\n        value = value[5 .. value.length];\n        immutable utcOffset = (dur!\"hours\"(zoneHours) + dur!\"minutes\"(zoneMinutes)) * sign;\n        if (utcOffset == Duration.zero)\n        {\n            return sign == 1 ? cast(immutable(TimeZone))UTC()\n                             : cast(immutable(TimeZone))new immutable SimpleTimeZone(Duration.zero);\n        }\n        return new immutable(SimpleTimeZone)(utcOffset);\n    }\n\n    // zone\n    Rebindable!(immutable TimeZone) tz;\n    if (value[0] == '-')\n        tz = parseTZ(-1);\n    else if (value[0] == '+')\n        tz = parseTZ(1);\n    else\n    {\n        // obs-zone\n        immutable tzLen = value.length - find(value, ' ', '\\t', '(')[0].length;\n        switch (sliceAsString(value[0 .. tzLen <= 4 ? tzLen : 4]))\n        {\n            case \"UT\": case \"GMT\": tz = UTC(); break;\n            case \"EST\": tz = new immutable SimpleTimeZone(dur!\"hours\"(-5)); break;\n            case \"EDT\": tz = new immutable SimpleTimeZone(dur!\"hours\"(-4)); break;\n            case \"CST\": tz = new immutable SimpleTimeZone(dur!\"hours\"(-6)); break;\n            case \"CDT\": tz = new immutable SimpleTimeZone(dur!\"hours\"(-5)); break;\n            case \"MST\": tz = new immutable SimpleTimeZone(dur!\"hours\"(-7)); break;\n            case \"MDT\": tz = new immutable SimpleTimeZone(dur!\"hours\"(-6)); break;\n            case \"PST\": tz = new immutable SimpleTimeZone(dur!\"hours\"(-8)); break;\n            case \"PDT\": tz = new immutable SimpleTimeZone(dur!\"hours\"(-7)); break;\n            case \"J\": case \"j\": throw new DateTimeException(\"Invalid timezone\");\n            default:\n            {\n                if (all!(std.ascii.isAlpha)(value[0 .. tzLen]))\n                {\n                    tz = new immutable SimpleTimeZone(Duration.zero);\n                    break;\n                }\n                throw new DateTimeException(\"Invalid timezone\");\n            }\n        }\n        value = value[tzLen .. value.length];\n    }\n\n    // This is kind of arbitrary. Technically, nothing but CFWS is legal past\n    // the end of the timezone, but we don't want to be picky about that in a\n    // function that's just parsing rather than validating. So, the idea here is\n    // that if the next character is printable (and not part of CFWS), then it\n    // might be part of the timezone and thus affect what the timezone was\n    // supposed to be, so we'll throw, but otherwise, we'll just ignore it.\n    if (!value.empty && isPrintable(value[0]) && value[0] != ' ' && value[0] != '(')\n        throw new DateTimeException(\"Invalid timezone\");\n\n    try\n        return SysTime(DateTime(year, month, day, hour, minute, second), tz);\n    catch (DateTimeException dte)\n        throw new DateTimeException(\"date-time format is correct, but the resulting SysTime is invalid.\", dte);\n}\n\n///\n@safe unittest\n{\n    import core.time : hours;\n    import std.datetime.date : DateTime, DateTimeException;\n    import std.datetime.timezone : SimpleTimeZone, UTC;\n    import std.exception : assertThrown;\n\n    auto tz = new immutable SimpleTimeZone(hours(-8));\n    assert(parseRFC822DateTime(\"Sat, 6 Jan 1990 12:14:19 -0800\") ==\n           SysTime(DateTime(1990, 1, 6, 12, 14, 19), tz));\n\n    assert(parseRFC822DateTime(\"9 Jul 2002 13:11 +0000\") ==\n           SysTime(DateTime(2002, 7, 9, 13, 11, 0), UTC()));\n\n    auto badStr = \"29 Feb 2001 12:17:16 +0200\";\n    assertThrown!DateTimeException(parseRFC822DateTime(badStr));\n}\n\nversion (unittest) private void testParse822(alias cr)(string str, SysTime expected, size_t line = __LINE__)\n{\n    import std.format : format;\n    auto value = cr(str);\n    auto result = parseRFC822DateTime(value);\n    if (result != expected)\n        throw new AssertError(format(\"wrong result. expected [%s], actual[%s]\", expected, result), __FILE__, line);\n}\n\nversion (unittest) private void testBadParse822(alias cr)(string str, size_t line = __LINE__)\n{\n    try\n        parseRFC822DateTime(cr(str));\n    catch (DateTimeException)\n        return;\n    throw new AssertError(\"No DateTimeException was thrown\", __FILE__, line);\n}\n\n@system unittest\n{\n    import core.time;\n    import std.algorithm.iteration : filter, map;\n    import std.algorithm.searching : canFind;\n    import std.array : array;\n    import std.ascii : letters;\n    import std.format : format;\n    import std.meta : AliasSeq;\n    import std.range : chain, iota, take;\n    import std.stdio : writefln, writeln;\n    import std.string : representation;\n\n    static struct Rand3Letters\n    {\n        enum empty = false;\n        @property auto front() { return _mon; }\n        void popFront()\n        {\n            import std.exception : assumeUnique;\n            import std.random : rndGen;\n            _mon = rndGen.map!(a => letters[a % letters.length])().take(3).array().assumeUnique();\n        }\n        string _mon;\n        static auto start() { Rand3Letters retval; retval.popFront(); return retval; }\n    }\n\n    static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;},\n                           function(string a){return cast(ubyte[]) a;},\n                           function(string a){return a;},\n                           function(string a){return map!(b => cast(char) b)(a.representation);}))\n    {{\n        scope(failure) writeln(typeof(cr).stringof);\n        alias test = testParse822!cr;\n        alias testBad = testBadParse822!cr;\n\n        immutable std1 = DateTime(2012, 12, 21, 13, 14, 15);\n        immutable std2 = DateTime(2012, 12, 21, 13, 14, 0);\n        immutable dst1 = DateTime(1976, 7, 4, 5, 4, 22);\n        immutable dst2 = DateTime(1976, 7, 4, 5, 4, 0);\n\n        test(\"21 Dec 2012 13:14:15 +0000\", SysTime(std1, UTC()));\n        test(\"21 Dec 2012 13:14 +0000\", SysTime(std2, UTC()));\n        test(\"Fri, 21 Dec 2012 13:14 +0000\", SysTime(std2, UTC()));\n        test(\"Fri, 21 Dec 2012 13:14:15 +0000\", SysTime(std1, UTC()));\n\n        test(\"04 Jul 1976 05:04:22 +0000\", SysTime(dst1, UTC()));\n        test(\"04 Jul 1976 05:04 +0000\", SysTime(dst2, UTC()));\n        test(\"Sun, 04 Jul 1976 05:04 +0000\", SysTime(dst2, UTC()));\n        test(\"Sun, 04 Jul 1976 05:04:22 +0000\", SysTime(dst1, UTC()));\n\n        test(\"4 Jul 1976 05:04:22 +0000\", SysTime(dst1, UTC()));\n        test(\"4 Jul 1976 05:04 +0000\", SysTime(dst2, UTC()));\n        test(\"Sun, 4 Jul 1976 05:04 +0000\", SysTime(dst2, UTC()));\n        test(\"Sun, 4 Jul 1976 05:04:22 +0000\", SysTime(dst1, UTC()));\n\n        auto badTZ = new immutable SimpleTimeZone(Duration.zero);\n        test(\"21 Dec 2012 13:14:15 -0000\", SysTime(std1, badTZ));\n        test(\"21 Dec 2012 13:14 -0000\", SysTime(std2, badTZ));\n        test(\"Fri, 21 Dec 2012 13:14 -0000\", SysTime(std2, badTZ));\n        test(\"Fri, 21 Dec 2012 13:14:15 -0000\", SysTime(std1, badTZ));\n\n        test(\"04 Jul 1976 05:04:22 -0000\", SysTime(dst1, badTZ));\n        test(\"04 Jul 1976 05:04 -0000\", SysTime(dst2, badTZ));\n        test(\"Sun, 04 Jul 1976 05:04 -0000\", SysTime(dst2, badTZ));\n        test(\"Sun, 04 Jul 1976 05:04:22 -0000\", SysTime(dst1, badTZ));\n\n        test(\"4 Jul 1976 05:04:22 -0000\", SysTime(dst1, badTZ));\n        test(\"4 Jul 1976 05:04 -0000\", SysTime(dst2, badTZ));\n        test(\"Sun, 4 Jul 1976 05:04 -0000\", SysTime(dst2, badTZ));\n        test(\"Sun, 4 Jul 1976 05:04:22 -0000\", SysTime(dst1, badTZ));\n\n        auto pst = new immutable SimpleTimeZone(dur!\"hours\"(-8));\n        auto pdt = new immutable SimpleTimeZone(dur!\"hours\"(-7));\n        test(\"21 Dec 2012 13:14:15 -0800\", SysTime(std1, pst));\n        test(\"21 Dec 2012 13:14 -0800\", SysTime(std2, pst));\n        test(\"Fri, 21 Dec 2012 13:14 -0800\", SysTime(std2, pst));\n        test(\"Fri, 21 Dec 2012 13:14:15 -0800\", SysTime(std1, pst));\n\n        test(\"04 Jul 1976 05:04:22 -0700\", SysTime(dst1, pdt));\n        test(\"04 Jul 1976 05:04 -0700\", SysTime(dst2, pdt));\n        test(\"Sun, 04 Jul 1976 05:04 -0700\", SysTime(dst2, pdt));\n        test(\"Sun, 04 Jul 1976 05:04:22 -0700\", SysTime(dst1, pdt));\n\n        test(\"4 Jul 1976 05:04:22 -0700\", SysTime(dst1, pdt));\n        test(\"4 Jul 1976 05:04 -0700\", SysTime(dst2, pdt));\n        test(\"Sun, 4 Jul 1976 05:04 -0700\", SysTime(dst2, pdt));\n        test(\"Sun, 4 Jul 1976 05:04:22 -0700\", SysTime(dst1, pdt));\n\n        auto cet = new immutable SimpleTimeZone(dur!\"hours\"(1));\n        auto cest = new immutable SimpleTimeZone(dur!\"hours\"(2));\n        test(\"21 Dec 2012 13:14:15 +0100\", SysTime(std1, cet));\n        test(\"21 Dec 2012 13:14 +0100\", SysTime(std2, cet));\n        test(\"Fri, 21 Dec 2012 13:14 +0100\", SysTime(std2, cet));\n        test(\"Fri, 21 Dec 2012 13:14:15 +0100\", SysTime(std1, cet));\n\n        test(\"04 Jul 1976 05:04:22 +0200\", SysTime(dst1, cest));\n        test(\"04 Jul 1976 05:04 +0200\", SysTime(dst2, cest));\n        test(\"Sun, 04 Jul 1976 05:04 +0200\", SysTime(dst2, cest));\n        test(\"Sun, 04 Jul 1976 05:04:22 +0200\", SysTime(dst1, cest));\n\n        test(\"4 Jul 1976 05:04:22 +0200\", SysTime(dst1, cest));\n        test(\"4 Jul 1976 05:04 +0200\", SysTime(dst2, cest));\n        test(\"Sun, 4 Jul 1976 05:04 +0200\", SysTime(dst2, cest));\n        test(\"Sun, 4 Jul 1976 05:04:22 +0200\", SysTime(dst1, cest));\n\n        // dst and std times are switched in the Southern Hemisphere which is why the\n        // time zone names and DateTime variables don't match.\n        auto cstStd = new immutable SimpleTimeZone(dur!\"hours\"(9) + dur!\"minutes\"(30));\n        auto cstDST = new immutable SimpleTimeZone(dur!\"hours\"(10) + dur!\"minutes\"(30));\n        test(\"21 Dec 2012 13:14:15 +1030\", SysTime(std1, cstDST));\n        test(\"21 Dec 2012 13:14 +1030\", SysTime(std2, cstDST));\n        test(\"Fri, 21 Dec 2012 13:14 +1030\", SysTime(std2, cstDST));\n        test(\"Fri, 21 Dec 2012 13:14:15 +1030\", SysTime(std1, cstDST));\n\n        test(\"04 Jul 1976 05:04:22 +0930\", SysTime(dst1, cstStd));\n        test(\"04 Jul 1976 05:04 +0930\", SysTime(dst2, cstStd));\n        test(\"Sun, 04 Jul 1976 05:04 +0930\", SysTime(dst2, cstStd));\n        test(\"Sun, 04 Jul 1976 05:04:22 +0930\", SysTime(dst1, cstStd));\n\n        test(\"4 Jul 1976 05:04:22 +0930\", SysTime(dst1, cstStd));\n        test(\"4 Jul 1976 05:04 +0930\", SysTime(dst2, cstStd));\n        test(\"Sun, 4 Jul 1976 05:04 +0930\", SysTime(dst2, cstStd));\n        test(\"Sun, 4 Jul 1976 05:04:22 +0930\", SysTime(dst1, cstStd));\n\n        foreach (int i, mon; _monthNames)\n        {\n            test(format(\"17 %s 2012 00:05:02 +0000\", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 2), UTC()));\n            test(format(\"17 %s 2012 00:05 +0000\", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 0), UTC()));\n        }\n\n        import std.uni : toLower, toUpper;\n        foreach (mon; chain(_monthNames[].map!(a => toLower(a))(),\n                            _monthNames[].map!(a => toUpper(a))(),\n                            [\"Jam\", \"Jen\", \"Fec\", \"Fdb\", \"Mas\", \"Mbr\", \"Aps\", \"Aqr\", \"Mai\", \"Miy\",\n                             \"Jum\", \"Jbn\", \"Jup\", \"Jal\", \"Aur\", \"Apg\", \"Sem\", \"Sap\", \"Ocm\", \"Odt\",\n                             \"Nom\", \"Nav\", \"Dem\", \"Dac\"],\n                            Rand3Letters.start().filter!(a => !_monthNames[].canFind(a)).take(20)))\n        {\n            scope(failure) writefln(\"Month: %s\", mon);\n            testBad(format(\"17 %s 2012 00:05:02 +0000\", mon));\n            testBad(format(\"17 %s 2012 00:05 +0000\", mon));\n        }\n\n        immutable string[7] daysOfWeekNames = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\n        {\n            auto start = SysTime(DateTime(2012, 11, 11, 9, 42, 0), UTC());\n            int day = 11;\n\n            foreach (int i, dow; daysOfWeekNames)\n            {\n                auto curr = start + dur!\"days\"(i);\n                test(format(\"%s, %s Nov 2012 09:42:00 +0000\", dow, day), curr);\n                test(format(\"%s, %s Nov 2012 09:42 +0000\", dow, day++), curr);\n\n                // Whether the day of the week matches the date is ignored.\n                test(format(\"%s, 11 Nov 2012 09:42:00 +0000\", dow), start);\n                test(format(\"%s, 11 Nov 2012 09:42 +0000\", dow), start);\n            }\n        }\n\n        foreach (dow; chain(daysOfWeekNames[].map!(a => toLower(a))(),\n                            daysOfWeekNames[].map!(a => toUpper(a))(),\n                            [\"Sum\", \"Spn\", \"Mom\", \"Man\", \"Tuf\", \"Tae\", \"Wem\", \"Wdd\", \"The\", \"Tur\",\n                             \"Fro\", \"Fai\", \"San\", \"Sut\"],\n                            Rand3Letters.start().filter!(a => !daysOfWeekNames[].canFind(a)).take(20)))\n        {\n            scope(failure) writefln(\"Day of Week: %s\", dow);\n            testBad(format(\"%s, 11 Nov 2012 09:42:00 +0000\", dow));\n            testBad(format(\"%s, 11 Nov 2012 09:42 +0000\", dow));\n        }\n\n        testBad(\"31 Dec 1899 23:59:59 +0000\");\n        test(\"01 Jan 1900 00:00:00 +0000\", SysTime(Date(1900, 1, 1), UTC()));\n        test(\"01 Jan 1900 00:00:00 -0000\", SysTime(Date(1900, 1, 1),\n                                                   new immutable SimpleTimeZone(Duration.zero)));\n        test(\"01 Jan 1900 00:00:00 -0700\", SysTime(Date(1900, 1, 1),\n                                                   new immutable SimpleTimeZone(dur!\"hours\"(-7))));\n\n        {\n            auto st1 = SysTime(Date(1900, 1, 1), UTC());\n            auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!\"hours\"(-11)));\n            foreach (i; 1900 .. 2102)\n            {\n                test(format(\"1 Jan %05d 00:00 +0000\", i), st1);\n                test(format(\"1 Jan %05d 00:00 -1100\", i), st2);\n                st1.add!\"years\"(1);\n                st2.add!\"years\"(1);\n            }\n            st1.year = 9998;\n            st2.year = 9998;\n            foreach (i; 9998 .. 11_002)\n            {\n                test(format(\"1 Jan %05d 00:00 +0000\", i), st1);\n                test(format(\"1 Jan %05d 00:00 -1100\", i), st2);\n                st1.add!\"years\"(1);\n                st2.add!\"years\"(1);\n            }\n        }\n\n        testBad(\"12 Feb 1907 23:17:09 0000\");\n        testBad(\"12 Feb 1907 23:17:09 +000\");\n        testBad(\"12 Feb 1907 23:17:09 -000\");\n        testBad(\"12 Feb 1907 23:17:09 +00000\");\n        testBad(\"12 Feb 1907 23:17:09 -00000\");\n        testBad(\"12 Feb 1907 23:17:09 +A\");\n        testBad(\"12 Feb 1907 23:17:09 +PST\");\n        testBad(\"12 Feb 1907 23:17:09 -A\");\n        testBad(\"12 Feb 1907 23:17:09 -PST\");\n\n        // test trailing stuff that gets ignored\n        {\n            foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1)))\n            {\n                scope(failure) writefln(\"c: %d\", c);\n                test(format(\"21 Dec 2012 13:14:15 +0000%c\", cast(char) c), SysTime(std1, UTC()));\n                test(format(\"21 Dec 2012 13:14:15 +0000%c  \", cast(char) c), SysTime(std1, UTC()));\n                test(format(\"21 Dec 2012 13:14:15 +0000%chello\", cast(char) c), SysTime(std1, UTC()));\n            }\n        }\n\n        // test trailing stuff that doesn't get ignored\n        {\n            foreach (c; chain(iota(33, '('), iota('(' + 1, 127)))\n            {\n                scope(failure) writefln(\"c: %d\", c);\n                testBad(format(\"21 Dec 2012 13:14:15 +0000%c\", cast(char) c));\n                testBad(format(\"21 Dec 2012 13:14:15 +0000%c   \", cast(char) c));\n                testBad(format(\"21 Dec 2012 13:14:15 +0000%chello\", cast(char) c));\n            }\n        }\n\n        testBad(\"32 Jan 2012 12:13:14 -0800\");\n        testBad(\"31 Jan 2012 24:13:14 -0800\");\n        testBad(\"31 Jan 2012 12:60:14 -0800\");\n        testBad(\"31 Jan 2012 12:13:61 -0800\");\n        testBad(\"31 Jan 2012 12:13:14 -0860\");\n        test(\"31 Jan 2012 12:13:14 -0859\",\n             SysTime(DateTime(2012, 1, 31, 12, 13, 14),\n                     new immutable SimpleTimeZone(dur!\"hours\"(-8) + dur!\"minutes\"(-59))));\n\n        // leap-seconds\n        test(\"21 Dec 2012 15:59:60 -0800\", SysTime(DateTime(2012, 12, 21, 15, 59, 59), pst));\n\n        // FWS\n        test(\"Sun,4 Jul 1976 05:04 +0930\", SysTime(dst2, cstStd));\n        test(\"Sun,4 Jul 1976 05:04:22 +0930\", SysTime(dst1, cstStd));\n        test(\"Sun,4 Jul 1976 05:04 +0930 (foo)\", SysTime(dst2, cstStd));\n        test(\"Sun,4 Jul 1976 05:04:22 +0930 (foo)\", SysTime(dst1, cstStd));\n        test(\"Sun,4  \\r\\n  Jul  \\r\\n  1976  \\r\\n  05:04  \\r\\n  +0930  \\r\\n  (foo)\", SysTime(dst2, cstStd));\n        test(\"Sun,4  \\r\\n  Jul  \\r\\n  1976  \\r\\n  05:04:22  \\r\\n  +0930  \\r\\n  (foo)\", SysTime(dst1, cstStd));\n\n        auto str = \"01 Jan 2012 12:13:14 -0800 \";\n        test(str, SysTime(DateTime(2012, 1, 1, 12, 13, 14), new immutable SimpleTimeZone(hours(-8))));\n        foreach (i; 0 .. str.length)\n        {\n            auto currStr = str.dup;\n            currStr[i] = 'x';\n            scope(failure) writefln(\"failed: %s\", currStr);\n            testBad(cast(string) currStr);\n        }\n        foreach (i; 2 .. str.length)\n        {\n            auto currStr = str[0 .. $ - i];\n            scope(failure) writefln(\"failed: %s\", currStr);\n            testBad(cast(string) currStr);\n            testBad((cast(string) currStr) ~ \"                                    \");\n        }\n    }}\n\n    static void testScope(scope ref string str) @safe\n    {\n        auto result = parseRFC822DateTime(str);\n    }\n}\n\n// Obsolete Format per section 4.3 of RFC 5322.\n@system unittest\n{\n    import std.algorithm.iteration : filter, map;\n    import std.ascii : letters;\n    import std.exception : collectExceptionMsg;\n    import std.format : format;\n    import std.meta : AliasSeq;\n    import std.range : chain, iota;\n    import std.stdio : writefln, writeln;\n    import std.string : representation;\n\n    auto std1 = SysTime(DateTime(2012, 12, 21, 13, 14, 15), UTC());\n    auto std2 = SysTime(DateTime(2012, 12, 21, 13, 14, 0), UTC());\n    auto std3 = SysTime(DateTime(1912, 12, 21, 13, 14, 15), UTC());\n    auto std4 = SysTime(DateTime(1912, 12, 21, 13, 14, 0), UTC());\n    auto dst1 = SysTime(DateTime(1976, 7, 4, 5, 4, 22), UTC());\n    auto dst2 = SysTime(DateTime(1976, 7, 4, 5, 4, 0), UTC());\n    auto tooLate1 = SysTime(Date(10_000, 1, 1), UTC());\n    auto tooLate2 = SysTime(DateTime(12_007, 12, 31, 12, 22, 19), UTC());\n\n    static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;},\n                           function(string a){return cast(ubyte[]) a;},\n                           function(string a){return a;},\n                           function(string a){return map!(b => cast(char) b)(a.representation);}))\n    {{\n        scope(failure) writeln(typeof(cr).stringof);\n        alias test = testParse822!cr;\n        {\n            auto list = [\"\", \" \", \" \\r\\n\\t\", \"\\t\\r\\n (hello world( frien(dog)) silly \\r\\n )  \\t\\t \\r\\n ()\",\n                         \" \\n \", \"\\t\\n\\t\", \" \\n\\t (foo) \\n (bar) \\r\\n (baz) \\n \"];\n\n            foreach (i, cfws; list)\n            {\n                scope(failure) writefln(\"i: %s\", i);\n\n                test(format(\"%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s\", cfws), std1);\n                test(format(\"%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s\", cfws), std2);\n                test(format(\"%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s\", cfws), std2);\n                test(format(\"%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s\", cfws), std1);\n\n                test(format(\"%1$s04%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s\", cfws), dst1);\n                test(format(\"%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04:22 +0000%1$s\", cfws), dst1);\n\n                test(format(\"%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s\", cfws), dst1);\n                test(format(\"%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s\", cfws), dst1);\n\n                test(format(\"%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s\", cfws), std1);\n                test(format(\"%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s\", cfws), std2);\n                test(format(\"%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s\", cfws), std2);\n                test(format(\"%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s\", cfws), std1);\n\n                test(format(\"%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s\", cfws), dst1);\n                test(format(\"%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s\", cfws), dst1);\n\n                test(format(\"%1$s4%1$sJul%1$s76 05:04:22%1$s+0000%1$s\", cfws), dst1);\n                test(format(\"%1$s4%1$sJul%1$s76 05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s\", cfws), dst1);\n\n                test(format(\"%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s\", cfws), std3);\n                test(format(\"%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s\", cfws), std4);\n                test(format(\"%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s\", cfws), std4);\n                test(format(\"%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s\", cfws), std3);\n\n                test(format(\"%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s\", cfws), dst1);\n                test(format(\"%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s\", cfws), dst1);\n\n                test(format(\"%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s\", cfws), dst1);\n                test(format(\"%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s\", cfws), dst2);\n                test(format(\"%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s\", cfws), dst1);\n\n                test(format(\"%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s\", cfws), tooLate1);\n                test(format(\"%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s\", cfws), tooLate2);\n                test(format(\"%1$sSat%1$s,%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s\", cfws), tooLate1);\n                test(format(\"%1$sSun%1$s,%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s\", cfws), tooLate2);\n            }\n        }\n\n        // test years of 1, 2, and 3 digits.\n        {\n            auto st1 = SysTime(Date(2000, 1, 1), UTC());\n            auto st2 = SysTime(Date(2000, 1, 1), new immutable SimpleTimeZone(dur!\"hours\"(-12)));\n            foreach (i; 0 .. 50)\n            {\n                test(format(\"1 Jan %02d 00:00 GMT\", i), st1);\n                test(format(\"1 Jan %02d 00:00 -1200\", i), st2);\n                st1.add!\"years\"(1);\n                st2.add!\"years\"(1);\n            }\n        }\n\n        {\n            auto st1 = SysTime(Date(1950, 1, 1), UTC());\n            auto st2 = SysTime(Date(1950, 1, 1), new immutable SimpleTimeZone(dur!\"hours\"(-12)));\n            foreach (i; 50 .. 100)\n            {\n                test(format(\"1 Jan %02d 00:00 GMT\", i), st1);\n                test(format(\"1 Jan %02d 00:00 -1200\", i), st2);\n                st1.add!\"years\"(1);\n                st2.add!\"years\"(1);\n            }\n        }\n\n        {\n            auto st1 = SysTime(Date(1900, 1, 1), UTC());\n            auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!\"hours\"(-11)));\n            foreach (i; 0 .. 1000)\n            {\n                test(format(\"1 Jan %03d 00:00 GMT\", i), st1);\n                test(format(\"1 Jan %03d 00:00 -1100\", i), st2);\n                st1.add!\"years\"(1);\n                st2.add!\"years\"(1);\n            }\n        }\n\n        foreach (i; 0 .. 10)\n        {\n            auto str1 = cr(format(\"1 Jan %d 00:00 GMT\", i));\n            auto str2 = cr(format(\"1 Jan %d 00:00 -1200\", i));\n            assertThrown!DateTimeException(parseRFC822DateTime(str1));\n            assertThrown!DateTimeException(parseRFC822DateTime(str1));\n        }\n\n        // test time zones\n        {\n            auto dt = DateTime(1982, 05, 03, 12, 22, 04);\n            test(\"Wed, 03 May 1982 12:22:04 UT\", SysTime(dt, UTC()));\n            test(\"Wed, 03 May 1982 12:22:04 GMT\", SysTime(dt, UTC()));\n            test(\"Wed, 03 May 1982 12:22:04 EST\", SysTime(dt, new immutable SimpleTimeZone(dur!\"hours\"(-5))));\n            test(\"Wed, 03 May 1982 12:22:04 EDT\", SysTime(dt, new immutable SimpleTimeZone(dur!\"hours\"(-4))));\n            test(\"Wed, 03 May 1982 12:22:04 CST\", SysTime(dt, new immutable SimpleTimeZone(dur!\"hours\"(-6))));\n            test(\"Wed, 03 May 1982 12:22:04 CDT\", SysTime(dt, new immutable SimpleTimeZone(dur!\"hours\"(-5))));\n            test(\"Wed, 03 May 1982 12:22:04 MST\", SysTime(dt, new immutable SimpleTimeZone(dur!\"hours\"(-7))));\n            test(\"Wed, 03 May 1982 12:22:04 MDT\", SysTime(dt, new immutable SimpleTimeZone(dur!\"hours\"(-6))));\n            test(\"Wed, 03 May 1982 12:22:04 PST\", SysTime(dt, new immutable SimpleTimeZone(dur!\"hours\"(-8))));\n            test(\"Wed, 03 May 1982 12:22:04 PDT\", SysTime(dt, new immutable SimpleTimeZone(dur!\"hours\"(-7))));\n\n            auto badTZ = new immutable SimpleTimeZone(Duration.zero);\n            foreach (dchar c; filter!(a => a != 'j' && a != 'J')(letters))\n            {\n                scope(failure) writefln(\"c: %s\", c);\n                test(format(\"Wed, 03 May 1982 12:22:04 %s\", c), SysTime(dt, badTZ));\n                test(format(\"Wed, 03 May 1982 12:22:04%s\", c), SysTime(dt, badTZ));\n            }\n\n            foreach (dchar c; ['j', 'J'])\n            {\n                scope(failure) writefln(\"c: %s\", c);\n                assertThrown!DateTimeException(parseRFC822DateTime(cr(format(\"Wed, 03 May 1982 12:22:04 %s\", c))));\n                assertThrown!DateTimeException(parseRFC822DateTime(cr(format(\"Wed, 03 May 1982 12:22:04%s\", c))));\n            }\n\n            foreach (string s; [\"AAA\", \"GQW\", \"DDT\", \"PDA\", \"GT\", \"GM\"])\n            {\n                scope(failure) writefln(\"s: %s\", s);\n                test(format(\"Wed, 03 May 1982 12:22:04 %s\", s), SysTime(dt, badTZ));\n            }\n\n            // test trailing stuff that gets ignored\n            {\n                foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1)))\n                {\n                    scope(failure) writefln(\"c: %d\", c);\n                    test(format(\"21Dec1213:14:15+0000%c\", cast(char) c), std1);\n                    test(format(\"21Dec1213:14:15+0000%c  \", cast(char) c), std1);\n                    test(format(\"21Dec1213:14:15+0000%chello\", cast(char) c), std1);\n                }\n            }\n\n            // test trailing stuff that doesn't get ignored\n            {\n                foreach (c; chain(iota(33, '('), iota('(' + 1, 127)))\n                {\n                    scope(failure) writefln(\"c: %d\", c);\n                    assertThrown!DateTimeException(\n                        parseRFC822DateTime(cr(format(\"21Dec1213:14:15+0000%c\", cast(char) c))));\n                    assertThrown!DateTimeException(\n                        parseRFC822DateTime(cr(format(\"21Dec1213:14:15+0000%c  \", cast(char) c))));\n                    assertThrown!DateTimeException(\n                        parseRFC822DateTime(cr(format(\"21Dec1213:14:15+0000%chello\", cast(char) c))));\n                }\n            }\n        }\n\n        // test that the checks for minimum length work correctly and avoid\n        // any RangeErrors.\n        test(\"7Dec1200:00A\", SysTime(DateTime(2012, 12, 7, 00, 00, 00),\n                                     new immutable SimpleTimeZone(Duration.zero)));\n        test(\"Fri,7Dec1200:00A\", SysTime(DateTime(2012, 12, 7, 00, 00, 00),\n                                         new immutable SimpleTimeZone(Duration.zero)));\n        test(\"7Dec1200:00:00A\", SysTime(DateTime(2012, 12, 7, 00, 00, 00),\n                                        new immutable SimpleTimeZone(Duration.zero)));\n        test(\"Fri,7Dec1200:00:00A\", SysTime(DateTime(2012, 12, 7, 00, 00, 00),\n                                            new immutable SimpleTimeZone(Duration.zero)));\n\n        auto tooShortMsg = collectExceptionMsg!DateTimeException(parseRFC822DateTime(\"\"));\n        foreach (str; [\"Fri,7Dec1200:00:00\", \"7Dec1200:00:00\"])\n        {\n            foreach (i; 0 .. str.length)\n            {\n                auto value = str[0 .. $ - i];\n                scope(failure) writeln(value);\n                assert(collectExceptionMsg!DateTimeException(parseRFC822DateTime(value)) == tooShortMsg);\n            }\n        }\n    }}\n}\n\n\nprivate:\n\n/+\n    Returns the given hnsecs as an ISO string of fractional seconds.\n  +/\nstring fracSecsToISOString(int hnsecs) @safe pure nothrow\n{\n    import std.array : appender;\n    auto w = appender!string();\n    try\n        fracSecsToISOString(w, hnsecs);\n    catch (Exception e)\n        assert(0, \"fracSecsToISOString() threw.\");\n    return w.data;\n}\n\nvoid fracSecsToISOString(W)(ref W writer, int hnsecs)\n{\n    import std.conv : toChars;\n    import std.range : padLeft;\n\n    assert(hnsecs >= 0);\n\n    if (hnsecs == 0)\n        return;\n\n    put(writer, '.');\n    auto chars = hnsecs.toChars.padLeft('0', 7);\n    while (chars.back == '0')\n        chars.popBack();\n    put(writer, chars);\n}\n\n@safe unittest\n{\n    assert(fracSecsToISOString(0) == \"\");\n    assert(fracSecsToISOString(1) == \".0000001\");\n    assert(fracSecsToISOString(10) == \".000001\");\n    assert(fracSecsToISOString(100) == \".00001\");\n    assert(fracSecsToISOString(1000) == \".0001\");\n    assert(fracSecsToISOString(10_000) == \".001\");\n    assert(fracSecsToISOString(100_000) == \".01\");\n    assert(fracSecsToISOString(1_000_000) == \".1\");\n    assert(fracSecsToISOString(1_000_001) == \".1000001\");\n    assert(fracSecsToISOString(1_001_001) == \".1001001\");\n    assert(fracSecsToISOString(1_071_601) == \".1071601\");\n    assert(fracSecsToISOString(1_271_641) == \".1271641\");\n    assert(fracSecsToISOString(9_999_999) == \".9999999\");\n    assert(fracSecsToISOString(9_999_990) == \".999999\");\n    assert(fracSecsToISOString(9_999_900) == \".99999\");\n    assert(fracSecsToISOString(9_999_000) == \".9999\");\n    assert(fracSecsToISOString(9_990_000) == \".999\");\n    assert(fracSecsToISOString(9_900_000) == \".99\");\n    assert(fracSecsToISOString(9_000_000) == \".9\");\n    assert(fracSecsToISOString(999) == \".0000999\");\n    assert(fracSecsToISOString(9990) == \".000999\");\n    assert(fracSecsToISOString(99_900) == \".00999\");\n    assert(fracSecsToISOString(999_000) == \".0999\");\n}\n\n\n/+\n    Returns a Duration corresponding to to the given ISO string of\n    fractional seconds.\n  +/\nstatic Duration fracSecsFromISOString(S)(scope const S isoString) @safe pure\nif (isSomeString!S)\n{\n    import std.algorithm.searching : all;\n    import std.ascii : isDigit;\n    import std.conv : to;\n    import std.string : representation;\n\n    if (isoString.empty)\n        return Duration.zero;\n\n    auto str = isoString.representation;\n\n    enforce(str[0] == '.', new DateTimeException(\"Invalid ISO String\"));\n    str.popFront();\n\n    enforce(!str.empty && all!isDigit(str), new DateTimeException(\"Invalid ISO String\"));\n\n    dchar[7] fullISOString = void;\n    foreach (i, ref dchar c; fullISOString)\n    {\n        if (i < str.length)\n            c = str[i];\n        else\n            c = '0';\n    }\n\n    return hnsecs(to!int(fullISOString[]));\n}\n\n@safe unittest\n{\n    import core.time;\n    static void testFSInvalid(string isoString)\n    {\n        fracSecsFromISOString(isoString);\n    }\n\n    assertThrown!DateTimeException(testFSInvalid(\".\"));\n    assertThrown!DateTimeException(testFSInvalid(\"0.\"));\n    assertThrown!DateTimeException(testFSInvalid(\"0\"));\n    assertThrown!DateTimeException(testFSInvalid(\"0000000\"));\n    assertThrown!DateTimeException(testFSInvalid(\"T\"));\n    assertThrown!DateTimeException(testFSInvalid(\"T.\"));\n    assertThrown!DateTimeException(testFSInvalid(\".T\"));\n    assertThrown!DateTimeException(testFSInvalid(\".00000Q0\"));\n    assertThrown!DateTimeException(testFSInvalid(\".000000Q\"));\n    assertThrown!DateTimeException(testFSInvalid(\".0000000Q\"));\n    assertThrown!DateTimeException(testFSInvalid(\".0000000000Q\"));\n\n    assert(fracSecsFromISOString(\"\") == Duration.zero);\n    assert(fracSecsFromISOString(\".0000001\") == hnsecs(1));\n    assert(fracSecsFromISOString(\".000001\") == hnsecs(10));\n    assert(fracSecsFromISOString(\".00001\") == hnsecs(100));\n    assert(fracSecsFromISOString(\".0001\") == hnsecs(1000));\n    assert(fracSecsFromISOString(\".001\") == hnsecs(10_000));\n    assert(fracSecsFromISOString(\".01\") == hnsecs(100_000));\n    assert(fracSecsFromISOString(\".1\") == hnsecs(1_000_000));\n    assert(fracSecsFromISOString(\".1000001\") == hnsecs(1_000_001));\n    assert(fracSecsFromISOString(\".1001001\") == hnsecs(1_001_001));\n    assert(fracSecsFromISOString(\".1071601\") == hnsecs(1_071_601));\n    assert(fracSecsFromISOString(\".1271641\") == hnsecs(1_271_641));\n    assert(fracSecsFromISOString(\".9999999\") == hnsecs(9_999_999));\n    assert(fracSecsFromISOString(\".9999990\") == hnsecs(9_999_990));\n    assert(fracSecsFromISOString(\".999999\") == hnsecs(9_999_990));\n    assert(fracSecsFromISOString(\".9999900\") == hnsecs(9_999_900));\n    assert(fracSecsFromISOString(\".99999\") == hnsecs(9_999_900));\n    assert(fracSecsFromISOString(\".9999000\") == hnsecs(9_999_000));\n    assert(fracSecsFromISOString(\".9999\") == hnsecs(9_999_000));\n    assert(fracSecsFromISOString(\".9990000\") == hnsecs(9_990_000));\n    assert(fracSecsFromISOString(\".999\") == hnsecs(9_990_000));\n    assert(fracSecsFromISOString(\".9900000\") == hnsecs(9_900_000));\n    assert(fracSecsFromISOString(\".9900\") == hnsecs(9_900_000));\n    assert(fracSecsFromISOString(\".99\") == hnsecs(9_900_000));\n    assert(fracSecsFromISOString(\".9000000\") == hnsecs(9_000_000));\n    assert(fracSecsFromISOString(\".9\") == hnsecs(9_000_000));\n    assert(fracSecsFromISOString(\".0000999\") == hnsecs(999));\n    assert(fracSecsFromISOString(\".0009990\") == hnsecs(9990));\n    assert(fracSecsFromISOString(\".000999\") == hnsecs(9990));\n    assert(fracSecsFromISOString(\".0099900\") == hnsecs(99_900));\n    assert(fracSecsFromISOString(\".00999\") == hnsecs(99_900));\n    assert(fracSecsFromISOString(\".0999000\") == hnsecs(999_000));\n    assert(fracSecsFromISOString(\".0999\") == hnsecs(999_000));\n    assert(fracSecsFromISOString(\".00000000\") == Duration.zero);\n    assert(fracSecsFromISOString(\".00000001\") == Duration.zero);\n    assert(fracSecsFromISOString(\".00000009\") == Duration.zero);\n    assert(fracSecsFromISOString(\".1234567890\") == hnsecs(1_234_567));\n    assert(fracSecsFromISOString(\".12345678901234567890\") == hnsecs(1_234_567));\n}\n\n\n/+\n    This function is used to split out the units without getting the remaining\n    hnsecs.\n\n    Params:\n        units  = The units to split out.\n        hnsecs = The current total hnsecs.\n\n    Returns:\n        The split out value.\n  +/\nlong getUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow\nif (validTimeUnits(units) &&\n    CmpTimeUnits!(units, \"months\") < 0)\n{\n    return convert!(\"hnsecs\", units)(hnsecs);\n}\n\n@safe unittest\n{\n    auto hnsecs = 2595000000007L;\n    immutable days = getUnitsFromHNSecs!\"days\"(hnsecs);\n    assert(days == 3);\n    assert(hnsecs == 2595000000007L);\n}\n\n\n/+\n    This function is used to split out the units without getting the units but\n    just the remaining hnsecs.\n\n    Params:\n        units  = The units to split out.\n        hnsecs = The current total hnsecs.\n\n    Returns:\n        The remaining hnsecs.\n  +/\nlong removeUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow\nif (validTimeUnits(units) &&\n    CmpTimeUnits!(units, \"months\") < 0)\n{\n    immutable value = convert!(\"hnsecs\", units)(hnsecs);\n    return hnsecs - convert!(units, \"hnsecs\")(value);\n}\n\n@safe unittest\n{\n    auto hnsecs = 2595000000007L;\n    auto returned = removeUnitsFromHNSecs!\"days\"(hnsecs);\n    assert(returned == 3000000007);\n    assert(hnsecs == 2595000000007L);\n}\n\n\n/+\n    Strips what RFC 5322, section 3.2.2 refers to as CFWS from the left-hand\n    side of the given range (it strips comments delimited by $(D '(') and\n    `'`') as well as folding whitespace).\n\n    It is assumed that the given range contains the value of a header field and\n    no terminating CRLF for the line (though the CRLF for folding whitespace is\n    of course expected and stripped) and thus that the only case of CR or LF is\n    in folding whitespace.\n\n    If a comment does not terminate correctly (e.g. mismatched parens) or if the\n    the FWS is malformed, then the range will be empty when stripCWFS is done.\n    However, only minimal validation of the content is done (e.g. quoted pairs\n    within a comment aren't validated beyond \\$LPAREN or \\$RPAREN, because\n    they're inside a comment, and thus their value doesn't matter anyway). It's\n    only when the content does not conform to the grammar rules for FWS and thus\n    literally cannot be parsed that content is considered invalid, and an empty\n    range is returned.\n\n    Note that _stripCFWS is eager, not lazy. It does not create a new range.\n    Rather, it pops off the CFWS from the range and returns it.\n  +/\nR _stripCFWS(R)(R range)\nif (isRandomAccessRange!R && hasSlicing!R && hasLength!R &&\n    (is(Unqual!(ElementType!R) == char) || is(Unqual!(ElementType!R) == ubyte)))\n{\n    immutable e = range.length;\n    outer: for (size_t i = 0; i < e; )\n    {\n        switch (range[i])\n        {\n            case ' ': case '\\t':\n            {\n                ++i;\n                break;\n            }\n            case '\\r':\n            {\n                if (i + 2 < e && range[i + 1] == '\\n' && (range[i + 2] == ' ' || range[i + 2] == '\\t'))\n                {\n                    i += 3;\n                    break;\n                }\n                break outer;\n            }\n            case '\\n':\n            {\n                if (i + 1 < e && (range[i + 1] == ' ' || range[i + 1] == '\\t'))\n                {\n                    i += 2;\n                    break;\n                }\n                break outer;\n            }\n            case '(':\n            {\n                ++i;\n                size_t commentLevel = 1;\n                while (i < e)\n                {\n                    if (range[i] == '(')\n                        ++commentLevel;\n                    else if (range[i] == ')')\n                    {\n                        ++i;\n                        if (--commentLevel == 0)\n                            continue outer;\n                        continue;\n                    }\n                    else if (range[i] == '\\\\')\n                    {\n                        if (++i == e)\n                            break outer;\n                    }\n                    ++i;\n                }\n                break outer;\n            }\n            default: return range[i .. e];\n        }\n    }\n    return range[e .. e];\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    import std.meta : AliasSeq;\n    import std.stdio : writeln;\n    import std.string : representation;\n\n    static foreach (cr; AliasSeq!(function(string a){return cast(ubyte[]) a;},\n                           function(string a){return map!(b => cast(char) b)(a.representation);}))\n    {\n        scope(failure) writeln(typeof(cr).stringof);\n\n        assert(_stripCFWS(cr(\"\")).empty);\n        assert(_stripCFWS(cr(\"\\r\")).empty);\n        assert(_stripCFWS(cr(\"\\r\\n\")).empty);\n        assert(_stripCFWS(cr(\"\\r\\n \")).empty);\n        assert(_stripCFWS(cr(\" \\t\\r\\n\")).empty);\n        assert(equal(_stripCFWS(cr(\" \\t\\r\\n hello\")), cr(\"hello\")));\n        assert(_stripCFWS(cr(\" \\t\\r\\nhello\")).empty);\n        assert(_stripCFWS(cr(\" \\t\\r\\n\\v\")).empty);\n        assert(equal(_stripCFWS(cr(\"\\v \\t\\r\\n\\v\")), cr(\"\\v \\t\\r\\n\\v\")));\n        assert(_stripCFWS(cr(\"()\")).empty);\n        assert(_stripCFWS(cr(\"(hello world)\")).empty);\n        assert(_stripCFWS(cr(\"(hello world)(hello world)\")).empty);\n        assert(_stripCFWS(cr(\"(hello world\\r\\n foo\\r where's\\nwaldo)\")).empty);\n        assert(_stripCFWS(cr(\" \\t (hello \\tworld\\r\\n foo\\r where's\\nwaldo)\\t\\t \")).empty);\n        assert(_stripCFWS(cr(\"      \")).empty);\n        assert(_stripCFWS(cr(\"\\t\\t\\t\")).empty);\n        assert(_stripCFWS(cr(\"\\t \\r\\n\\r \\n\")).empty);\n        assert(_stripCFWS(cr(\"(hello world) (can't find waldo) (he's lost)\")).empty);\n        assert(_stripCFWS(cr(\"(hello\\\\) world) (can't \\\\(find waldo) (he's \\\\(\\\\)lost)\")).empty);\n        assert(_stripCFWS(cr(\"(((((\")).empty);\n        assert(_stripCFWS(cr(\"(((()))\")).empty);\n        assert(_stripCFWS(cr(\"(((())))\")).empty);\n        assert(equal(_stripCFWS(cr(\"(((()))))\")), cr(\")\")));\n        assert(equal(_stripCFWS(cr(\")))))\")), cr(\")))))\")));\n        assert(equal(_stripCFWS(cr(\"()))))\")), cr(\"))))\")));\n        assert(equal(_stripCFWS(cr(\" hello hello \")), cr(\"hello hello \")));\n        assert(equal(_stripCFWS(cr(\"\\thello (world)\")), cr(\"hello (world)\")));\n        assert(equal(_stripCFWS(cr(\" \\r\\n \\\\((\\\\))  foo\")), cr(\"\\\\((\\\\))  foo\")));\n        assert(equal(_stripCFWS(cr(\" \\r\\n (\\\\((\\\\)))  foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" \\r\\n (\\\\(()))  foo\")), cr(\")  foo\")));\n        assert(_stripCFWS(cr(\" \\r\\n (((\\\\)))  foo\")).empty);\n\n        assert(_stripCFWS(cr(\"(hello)(hello)\")).empty);\n        assert(_stripCFWS(cr(\" \\r\\n (hello)\\r\\n (hello)\")).empty);\n        assert(_stripCFWS(cr(\" \\r\\n (hello) \\r\\n (hello) \\r\\n \")).empty);\n        assert(_stripCFWS(cr(\"\\t\\t\\t\\t(hello)\\t\\t\\t\\t(hello)\\t\\t\\t\\t\")).empty);\n        assert(equal(_stripCFWS(cr(\" \\r\\n (hello)\\r\\n (hello) \\r\\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\" \\r\\n (hello) \\r\\n (hello) \\r\\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\"\\t\\r\\n\\t(hello)\\r\\n\\t(hello)\\t\\r\\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\"\\t\\r\\n\\t(hello)\\t\\r\\n\\t(hello)\\t\\r\\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\" \\r\\n (hello) \\r\\n \\r\\n (hello) \\r\\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\" \\r\\n (hello) \\r\\n (hello) \\r\\n \\r\\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\" \\r\\n \\r\\n (hello)\\t\\r\\n (hello) \\r\\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\" \\r\\n\\t\\r\\n\\t(hello)\\t\\r\\n (hello) \\r\\n hello\")), cr(\"hello\")));\n\n        assert(equal(_stripCFWS(cr(\" (\\r\\n ( \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n ( \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" (\\t\\r\\n ( \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" (\\r\\n\\t( \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n (\\t\\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n (\\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n (\\r\\n\\t) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n ( \\r\\n) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n ( \\r\\n )\\t\\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n ( \\r\\n )\\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n ( \\r\\n ) \\r\\n) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n ( \\r\\n ) \\r\\n\\t) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n ( \\r\\n ) \\r\\n ) \\r\\n foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n ( \\r\\n ) \\r\\n )\\t\\r\\n foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n ( \\r\\n ) \\r\\n )\\r\\n foo\")), cr(\"foo\")));\n\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n \\r\\n ( \\r\\n \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n \\r\\n ( \\r\\n \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" (\\t\\r\\n \\r\\n ( \\r\\n \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" (\\r\\n \\r\\n\\t( \\r\\n \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" (\\r\\n \\r\\n( \\r\\n \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" (\\r\\n \\r\\n ( \\r\\n \\r\\n\\t) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" (\\r\\n \\r\\n ( \\r\\n \\r\\n )\\t\\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" (\\r\\n \\r\\n ( \\r\\n \\r\\n )\\r\\n ) foo\")), cr(\"foo\")));\n\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n bar \\r\\n ( \\r\\n bar \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n () \\r\\n ( \\r\\n () \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n        assert(equal(_stripCFWS(cr(\" ( \\r\\n \\\\\\\\ \\r\\n ( \\r\\n \\\\\\\\ \\r\\n ) \\r\\n ) foo\")), cr(\"foo\")));\n\n        assert(_stripCFWS(cr(\"(hello)(hello)\")).empty);\n        assert(_stripCFWS(cr(\" \\n (hello)\\n (hello) \\n \")).empty);\n        assert(_stripCFWS(cr(\" \\n (hello) \\n (hello) \\n \")).empty);\n        assert(equal(_stripCFWS(cr(\" \\n (hello)\\n (hello) \\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\" \\n (hello) \\n (hello) \\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\"\\t\\n\\t(hello)\\n\\t(hello)\\t\\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\"\\t\\n\\t(hello)\\t\\n\\t(hello)\\t\\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\" \\n (hello) \\n \\n (hello) \\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\" \\n (hello) \\n (hello) \\n \\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\" \\n \\n (hello)\\t\\n (hello) \\n hello\")), cr(\"hello\")));\n        assert(equal(_stripCFWS(cr(\" \\n\\t\\n\\t(hello)\\t\\n (hello) \\n hello\")), cr(\"hello\")));\n    }\n}\n\n// This is so that we don't have to worry about std.conv.to throwing. It also\n// doesn't have to worry about quite as many cases as std.conv.to, since it\n// doesn't have to worry about a sign on the value or about whether it fits.\nT _convDigits(T, R)(R str)\nif (isIntegral!T && isSigned!T) // The constraints on R were already covered by parseRFC822DateTime.\n{\n    import std.ascii : isDigit;\n\n    assert(!str.empty);\n    T num = 0;\n    foreach (i; 0 .. str.length)\n    {\n        if (i != 0)\n            num *= 10;\n        if (!isDigit(str[i]))\n            return -1;\n        num += str[i] - '0';\n    }\n    return num;\n}\n\n@safe unittest\n{\n    import std.conv : to;\n    import std.range : chain, iota;\n    foreach (i; chain(iota(0, 101), [250, 999, 1000, 1001, 2345, 9999]))\n    {\n        assert(_convDigits!int(to!string(i)) == i, i.to!string);\n    }\n    foreach (str; [\"-42\", \"+42\", \"1a\", \"1 \", \" \", \" 42 \"])\n    {\n        assert(_convDigits!int(str) == -1, str);\n    }\n}\n\n\nversion (unittest)\n{\nprivate:\n    // Variables to help in testing.\n    Duration currLocalDiffFromUTC;\n    immutable (TimeZone)[] testTZs;\n\n    // All of these helper arrays are sorted in ascending order.\n    auto testYearsBC = [-1999, -1200, -600, -4, -1, 0];\n    auto testYearsAD = [1, 4, 1000, 1999, 2000, 2012];\n\n    // I'd use a Tuple, but I get forward reference errors if I try.\n    struct MonthDay\n    {\n        Month month;\n        short day;\n\n        this(int m, short d)\n        {\n            month = cast(Month) m;\n            day = d;\n        }\n    }\n\n    MonthDay[] testMonthDays = [MonthDay(1, 1),\n                                MonthDay(1, 2),\n                                MonthDay(3, 17),\n                                MonthDay(7, 4),\n                                MonthDay(10, 27),\n                                MonthDay(12, 30),\n                                MonthDay(12, 31)];\n\n    auto testDays = [1, 2, 9, 10, 16, 20, 25, 28, 29, 30, 31];\n\n    auto testTODs = [TimeOfDay(0, 0, 0),\n                     TimeOfDay(0, 0, 1),\n                     TimeOfDay(0, 1, 0),\n                     TimeOfDay(1, 0, 0),\n                     TimeOfDay(13, 13, 13),\n                     TimeOfDay(23, 59, 59)];\n\n    auto testHours = [0, 1, 12, 22, 23];\n    auto testMinSecs = [0, 1, 30, 58, 59];\n\n    // Throwing exceptions is incredibly expensive, so we want to use a smaller\n    // set of values for tests using assertThrown.\n    auto testTODsThrown = [TimeOfDay(0, 0, 0),\n                           TimeOfDay(13, 13, 13),\n                           TimeOfDay(23, 59, 59)];\n\n    Date[] testDatesBC;\n    Date[] testDatesAD;\n\n    DateTime[] testDateTimesBC;\n    DateTime[] testDateTimesAD;\n\n    Duration[] testFracSecs;\n\n    SysTime[] testSysTimesBC;\n    SysTime[] testSysTimesAD;\n\n    // I'd use a Tuple, but I get forward reference errors if I try.\n    struct GregDay { int day; Date date; }\n    auto testGregDaysBC = [GregDay(-1_373_427, Date(-3760, 9, 7)), // Start of the Hebrew Calendar\n                           GregDay(-735_233, Date(-2012, 1, 1)),\n                           GregDay(-735_202, Date(-2012, 2, 1)),\n                           GregDay(-735_175, Date(-2012, 2, 28)),\n                           GregDay(-735_174, Date(-2012, 2, 29)),\n                           GregDay(-735_173, Date(-2012, 3, 1)),\n                           GregDay(-734_502, Date(-2010, 1, 1)),\n                           GregDay(-734_472, Date(-2010, 1, 31)),\n                           GregDay(-734_471, Date(-2010, 2, 1)),\n                           GregDay(-734_444, Date(-2010, 2, 28)),\n                           GregDay(-734_443, Date(-2010, 3, 1)),\n                           GregDay(-734_413, Date(-2010, 3, 31)),\n                           GregDay(-734_412, Date(-2010, 4, 1)),\n                           GregDay(-734_383, Date(-2010, 4, 30)),\n                           GregDay(-734_382, Date(-2010, 5, 1)),\n                           GregDay(-734_352, Date(-2010, 5, 31)),\n                           GregDay(-734_351, Date(-2010, 6, 1)),\n                           GregDay(-734_322, Date(-2010, 6, 30)),\n                           GregDay(-734_321, Date(-2010, 7, 1)),\n                           GregDay(-734_291, Date(-2010, 7, 31)),\n                           GregDay(-734_290, Date(-2010, 8, 1)),\n                           GregDay(-734_260, Date(-2010, 8, 31)),\n                           GregDay(-734_259, Date(-2010, 9, 1)),\n                           GregDay(-734_230, Date(-2010, 9, 30)),\n                           GregDay(-734_229, Date(-2010, 10, 1)),\n                           GregDay(-734_199, Date(-2010, 10, 31)),\n                           GregDay(-734_198, Date(-2010, 11, 1)),\n                           GregDay(-734_169, Date(-2010, 11, 30)),\n                           GregDay(-734_168, Date(-2010, 12, 1)),\n                           GregDay(-734_139, Date(-2010, 12, 30)),\n                           GregDay(-734_138, Date(-2010, 12, 31)),\n                           GregDay(-731_215, Date(-2001, 1, 1)),\n                           GregDay(-730_850, Date(-2000, 1, 1)),\n                           GregDay(-730_849, Date(-2000, 1, 2)),\n                           GregDay(-730_486, Date(-2000, 12, 30)),\n                           GregDay(-730_485, Date(-2000, 12, 31)),\n                           GregDay(-730_484, Date(-1999, 1, 1)),\n                           GregDay(-694_690, Date(-1901, 1, 1)),\n                           GregDay(-694_325, Date(-1900, 1, 1)),\n                           GregDay(-585_118, Date(-1601, 1, 1)),\n                           GregDay(-584_753, Date(-1600, 1, 1)),\n                           GregDay(-584_388, Date(-1600, 12, 31)),\n                           GregDay(-584_387, Date(-1599, 1, 1)),\n                           GregDay(-365_972, Date(-1001, 1, 1)),\n                           GregDay(-365_607, Date(-1000, 1, 1)),\n                           GregDay(-183_351, Date(-501, 1, 1)),\n                           GregDay(-182_986, Date(-500, 1, 1)),\n                           GregDay(-182_621, Date(-499, 1, 1)),\n                           GregDay(-146_827, Date(-401, 1, 1)),\n                           GregDay(-146_462, Date(-400, 1, 1)),\n                           GregDay(-146_097, Date(-400, 12, 31)),\n                           GregDay(-110_302, Date(-301, 1, 1)),\n                           GregDay(-109_937, Date(-300, 1, 1)),\n                           GregDay(-73_778, Date(-201, 1, 1)),\n                           GregDay(-73_413, Date(-200, 1, 1)),\n                           GregDay(-38_715, Date(-105, 1, 1)),\n                           GregDay(-37_254, Date(-101, 1, 1)),\n                           GregDay(-36_889, Date(-100, 1, 1)),\n                           GregDay(-36_524, Date(-99, 1, 1)),\n                           GregDay(-36_160, Date(-99, 12, 31)),\n                           GregDay(-35_794, Date(-97, 1, 1)),\n                           GregDay(-18_627, Date(-50, 1, 1)),\n                           GregDay(-18_262, Date(-49, 1, 1)),\n                           GregDay(-3652, Date(-9, 1, 1)),\n                           GregDay(-2191, Date(-5, 1, 1)),\n                           GregDay(-1827, Date(-5, 12, 31)),\n                           GregDay(-1826, Date(-4, 1, 1)),\n                           GregDay(-1825, Date(-4, 1, 2)),\n                           GregDay(-1462, Date(-4, 12, 30)),\n                           GregDay(-1461, Date(-4, 12, 31)),\n                           GregDay(-1460, Date(-3, 1, 1)),\n                           GregDay(-1096, Date(-3, 12, 31)),\n                           GregDay(-1095, Date(-2, 1, 1)),\n                           GregDay(-731, Date(-2, 12, 31)),\n                           GregDay(-730, Date(-1, 1, 1)),\n                           GregDay(-367, Date(-1, 12, 30)),\n                           GregDay(-366, Date(-1, 12, 31)),\n                           GregDay(-365, Date(0, 1, 1)),\n                           GregDay(-31, Date(0, 11, 30)),\n                           GregDay(-30, Date(0, 12, 1)),\n                           GregDay(-1, Date(0, 12, 30)),\n                           GregDay(0, Date(0, 12, 31))];\n\n    auto testGregDaysAD = [GregDay(1, Date(1, 1, 1)),\n                           GregDay(2, Date(1, 1, 2)),\n                           GregDay(32, Date(1, 2, 1)),\n                           GregDay(365, Date(1, 12, 31)),\n                           GregDay(366, Date(2, 1, 1)),\n                           GregDay(731, Date(3, 1, 1)),\n                           GregDay(1096, Date(4, 1, 1)),\n                           GregDay(1097, Date(4, 1, 2)),\n                           GregDay(1460, Date(4, 12, 30)),\n                           GregDay(1461, Date(4, 12, 31)),\n                           GregDay(1462, Date(5, 1, 1)),\n                           GregDay(17_898, Date(50, 1, 1)),\n                           GregDay(35_065, Date(97, 1, 1)),\n                           GregDay(36_160, Date(100, 1, 1)),\n                           GregDay(36_525, Date(101, 1, 1)),\n                           GregDay(37_986, Date(105, 1, 1)),\n                           GregDay(72_684, Date(200, 1, 1)),\n                           GregDay(73_049, Date(201, 1, 1)),\n                           GregDay(109_208, Date(300, 1, 1)),\n                           GregDay(109_573, Date(301, 1, 1)),\n                           GregDay(145_732, Date(400, 1, 1)),\n                           GregDay(146_098, Date(401, 1, 1)),\n                           GregDay(182_257, Date(500, 1, 1)),\n                           GregDay(182_622, Date(501, 1, 1)),\n                           GregDay(364_878, Date(1000, 1, 1)),\n                           GregDay(365_243, Date(1001, 1, 1)),\n                           GregDay(584_023, Date(1600, 1, 1)),\n                           GregDay(584_389, Date(1601, 1, 1)),\n                           GregDay(693_596, Date(1900, 1, 1)),\n                           GregDay(693_961, Date(1901, 1, 1)),\n                           GregDay(729_755, Date(1999, 1, 1)),\n                           GregDay(730_120, Date(2000, 1, 1)),\n                           GregDay(730_121, Date(2000, 1, 2)),\n                           GregDay(730_484, Date(2000, 12, 30)),\n                           GregDay(730_485, Date(2000, 12, 31)),\n                           GregDay(730_486, Date(2001, 1, 1)),\n                           GregDay(733_773, Date(2010, 1, 1)),\n                           GregDay(733_774, Date(2010, 1, 2)),\n                           GregDay(733_803, Date(2010, 1, 31)),\n                           GregDay(733_804, Date(2010, 2, 1)),\n                           GregDay(733_831, Date(2010, 2, 28)),\n                           GregDay(733_832, Date(2010, 3, 1)),\n                           GregDay(733_862, Date(2010, 3, 31)),\n                           GregDay(733_863, Date(2010, 4, 1)),\n                           GregDay(733_892, Date(2010, 4, 30)),\n                           GregDay(733_893, Date(2010, 5, 1)),\n                           GregDay(733_923, Date(2010, 5, 31)),\n                           GregDay(733_924, Date(2010, 6, 1)),\n                           GregDay(733_953, Date(2010, 6, 30)),\n                           GregDay(733_954, Date(2010, 7, 1)),\n                           GregDay(733_984, Date(2010, 7, 31)),\n                           GregDay(733_985, Date(2010, 8, 1)),\n                           GregDay(734_015, Date(2010, 8, 31)),\n                           GregDay(734_016, Date(2010, 9, 1)),\n                           GregDay(734_045, Date(2010, 9, 30)),\n                           GregDay(734_046, Date(2010, 10, 1)),\n                           GregDay(734_076, Date(2010, 10, 31)),\n                           GregDay(734_077, Date(2010, 11, 1)),\n                           GregDay(734_106, Date(2010, 11, 30)),\n                           GregDay(734_107, Date(2010, 12, 1)),\n                           GregDay(734_136, Date(2010, 12, 30)),\n                           GregDay(734_137, Date(2010, 12, 31)),\n                           GregDay(734_503, Date(2012, 1, 1)),\n                           GregDay(734_534, Date(2012, 2, 1)),\n                           GregDay(734_561, Date(2012, 2, 28)),\n                           GregDay(734_562, Date(2012, 2, 29)),\n                           GregDay(734_563, Date(2012, 3, 1)),\n                           GregDay(734_858, Date(2012, 12, 21))];\n\n    // I'd use a Tuple, but I get forward reference errors if I try.\n    struct DayOfYear { int day; MonthDay md; }\n    auto testDaysOfYear = [DayOfYear(1, MonthDay(1, 1)),\n                           DayOfYear(2, MonthDay(1, 2)),\n                           DayOfYear(3, MonthDay(1, 3)),\n                           DayOfYear(31, MonthDay(1, 31)),\n                           DayOfYear(32, MonthDay(2, 1)),\n                           DayOfYear(59, MonthDay(2, 28)),\n                           DayOfYear(60, MonthDay(3, 1)),\n                           DayOfYear(90, MonthDay(3, 31)),\n                           DayOfYear(91, MonthDay(4, 1)),\n                           DayOfYear(120, MonthDay(4, 30)),\n                           DayOfYear(121, MonthDay(5, 1)),\n                           DayOfYear(151, MonthDay(5, 31)),\n                           DayOfYear(152, MonthDay(6, 1)),\n                           DayOfYear(181, MonthDay(6, 30)),\n                           DayOfYear(182, MonthDay(7, 1)),\n                           DayOfYear(212, MonthDay(7, 31)),\n                           DayOfYear(213, MonthDay(8, 1)),\n                           DayOfYear(243, MonthDay(8, 31)),\n                           DayOfYear(244, MonthDay(9, 1)),\n                           DayOfYear(273, MonthDay(9, 30)),\n                           DayOfYear(274, MonthDay(10, 1)),\n                           DayOfYear(304, MonthDay(10, 31)),\n                           DayOfYear(305, MonthDay(11, 1)),\n                           DayOfYear(334, MonthDay(11, 30)),\n                           DayOfYear(335, MonthDay(12, 1)),\n                           DayOfYear(363, MonthDay(12, 29)),\n                           DayOfYear(364, MonthDay(12, 30)),\n                           DayOfYear(365, MonthDay(12, 31))];\n\n    auto testDaysOfLeapYear = [DayOfYear(1, MonthDay(1, 1)),\n                               DayOfYear(2, MonthDay(1, 2)),\n                               DayOfYear(3, MonthDay(1, 3)),\n                               DayOfYear(31, MonthDay(1, 31)),\n                               DayOfYear(32, MonthDay(2, 1)),\n                               DayOfYear(59, MonthDay(2, 28)),\n                               DayOfYear(60, MonthDay(2, 29)),\n                               DayOfYear(61, MonthDay(3, 1)),\n                               DayOfYear(91, MonthDay(3, 31)),\n                               DayOfYear(92, MonthDay(4, 1)),\n                               DayOfYear(121, MonthDay(4, 30)),\n                               DayOfYear(122, MonthDay(5, 1)),\n                               DayOfYear(152, MonthDay(5, 31)),\n                               DayOfYear(153, MonthDay(6, 1)),\n                               DayOfYear(182, MonthDay(6, 30)),\n                               DayOfYear(183, MonthDay(7, 1)),\n                               DayOfYear(213, MonthDay(7, 31)),\n                               DayOfYear(214, MonthDay(8, 1)),\n                               DayOfYear(244, MonthDay(8, 31)),\n                               DayOfYear(245, MonthDay(9, 1)),\n                               DayOfYear(274, MonthDay(9, 30)),\n                               DayOfYear(275, MonthDay(10, 1)),\n                               DayOfYear(305, MonthDay(10, 31)),\n                               DayOfYear(306, MonthDay(11, 1)),\n                               DayOfYear(335, MonthDay(11, 30)),\n                               DayOfYear(336, MonthDay(12, 1)),\n                               DayOfYear(364, MonthDay(12, 29)),\n                               DayOfYear(365, MonthDay(12, 30)),\n                               DayOfYear(366, MonthDay(12, 31))];\n\n    void initializeTests() @safe\n    {\n        import std.algorithm.sorting : sort;\n        import std.typecons : Rebindable;\n        immutable lt = LocalTime().utcToTZ(0);\n        currLocalDiffFromUTC = dur!\"hnsecs\"(lt);\n\n        version (Posix)\n        {\n            import std.datetime.timezone : PosixTimeZone;\n            immutable otherTZ = lt < 0 ? PosixTimeZone.getTimeZone(\"Australia/Sydney\")\n                                       : PosixTimeZone.getTimeZone(\"America/Denver\");\n        }\n        else version (Windows)\n        {\n            import std.datetime.timezone : WindowsTimeZone;\n            immutable otherTZ = lt < 0 ? WindowsTimeZone.getTimeZone(\"AUS Eastern Standard Time\")\n                                       : WindowsTimeZone.getTimeZone(\"Mountain Standard Time\");\n        }\n\n        immutable ot = otherTZ.utcToTZ(0);\n\n        auto diffs = [0L, lt, ot];\n        auto diffAA = [0L : Rebindable!(immutable TimeZone)(UTC())];\n        diffAA[lt] = Rebindable!(immutable TimeZone)(LocalTime());\n        diffAA[ot] = Rebindable!(immutable TimeZone)(otherTZ);\n\n        sort(diffs);\n        testTZs = [diffAA[diffs[0]], diffAA[diffs[1]], diffAA[diffs[2]]];\n\n        testFracSecs = [Duration.zero, hnsecs(1), hnsecs(5007), hnsecs(9_999_999)];\n\n        foreach (year; testYearsBC)\n        {\n            foreach (md; testMonthDays)\n                testDatesBC ~= Date(year, md.month, md.day);\n        }\n\n        foreach (year; testYearsAD)\n        {\n            foreach (md; testMonthDays)\n                testDatesAD ~= Date(year, md.month, md.day);\n        }\n\n        foreach (dt; testDatesBC)\n        {\n            foreach (tod; testTODs)\n                testDateTimesBC ~= DateTime(dt, tod);\n        }\n\n        foreach (dt; testDatesAD)\n        {\n            foreach (tod; testTODs)\n                testDateTimesAD ~= DateTime(dt, tod);\n        }\n\n        foreach (dt; testDateTimesBC)\n        {\n            foreach (tz; testTZs)\n            {\n                foreach (fs; testFracSecs)\n                    testSysTimesBC ~= SysTime(dt, fs, tz);\n            }\n        }\n\n        foreach (dt; testDateTimesAD)\n        {\n            foreach (tz; testTZs)\n            {\n                foreach (fs; testFracSecs)\n                    testSysTimesAD ~= SysTime(dt, fs, tz);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/datetime/timezone.d",
    "content": "// Written in the D programming language\n\n/++\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Time zones) $(TD\n    $(LREF TimeZone)\n    $(LREF UTC)\n    $(LREF LocalTime)\n    $(LREF PosixTimeZone)\n    $(LREF WindowsTimeZone)\n    $(LREF SimpleTimeZone)\n))\n$(TR $(TD Utilities) $(TD\n    $(LREF clearTZEnvVar)\n    $(LREF parseTZConversions)\n    $(LREF setTZEnvVar)\n    $(LREF TZConversions)\n))\n)\n\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)\n    Source:    $(PHOBOSSRC std/datetime/timezone.d)\n+/\nmodule std.datetime.timezone;\n\n// Note: reconsider using specific imports below after\n// https://issues.dlang.org/show_bug.cgi?id=17630 has been fixed\nimport core.time;// : abs, convert, dur, Duration, hours, minutes;\nimport std.datetime.systime;// : Clock, stdTimeToUnixTime, SysTime;\nimport std.range.primitives;// : back, front, empty, popFront;\nimport std.traits : isIntegral, isSomeString, Unqual;\n\nversion (Windows)\n{\n    import core.stdc.time : time_t;\n    import core.sys.windows.windows;\n    import core.sys.windows.winsock2;\n    import std.windows.registry;\n\n    // Uncomment and run unittests to print missing Windows TZ translations.\n    // Please subscribe to Microsoft Daylight Saving Time & Time Zone Blog\n    // (https://blogs.technet.microsoft.com/dst2007/) if you feel responsible\n    // for updating the translations.\n    // version = UpdateWindowsTZTranslations;\n}\nelse version (Posix)\n{\n    import core.sys.posix.signal : timespec;\n    import core.sys.posix.sys.types : time_t;\n}\n\nversion (unittest) import std.exception : assertThrown;\n\n\n/++\n    Represents a time zone. It is used with $(REF SysTime,std,datetime,systime)\n    to indicate the time zone of a $(REF SysTime,std,datetime,systime).\n  +/\nabstract class TimeZone\n{\npublic:\n\n    /++\n        The name of the time zone. Exactly how the time zone name is formatted\n        depends on the derived class. In the case of $(LREF PosixTimeZone), it's\n        the TZ Database name, whereas with $(LREF WindowsTimeZone), it's the\n        name that Windows chose to give the registry key for that time zone\n        (typically the name that they give $(LREF stdTime) if the OS is in\n        English). For other time zone types, what it is depends on how they're\n        implemented.\n\n        See_Also:\n            $(HTTP en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ\n              Database)<br>\n            $(HTTP en.wikipedia.org/wiki/List_of_tz_database_time_zones, List of\n              Time Zones)\n      +/\n    @property string name() @safe const nothrow\n    {\n        return _name;\n    }\n\n\n    /++\n        Typically, the abbreviation (generally 3 or 4 letters) for the time zone\n        when DST is $(I not) in effect (e.g. PST). It is not necessarily unique.\n\n        However, on Windows, it may be the unabbreviated name (e.g. Pacific\n        Standard Time). Regardless, it is not the same as name.\n      +/\n    @property string stdName() @safe const nothrow\n    {\n        return _stdName;\n    }\n\n\n    /++\n        Typically, the abbreviation (generally 3 or 4 letters) for the time zone\n        when DST $(I is) in effect (e.g. PDT). It is not necessarily unique.\n\n        However, on Windows, it may be the unabbreviated name (e.g. Pacific\n        Daylight Time). Regardless, it is not the same as name.\n      +/\n    @property string dstName() @safe const nothrow\n    {\n        return _dstName;\n    }\n\n\n    /++\n        Whether this time zone has Daylight Savings Time at any point in time.\n        Note that for some time zone types it may not have DST for current dates\n        but will still return true for `hasDST` because the time zone did at\n        some point have DST.\n      +/\n    @property abstract bool hasDST() @safe const nothrow;\n\n\n    /++\n        Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.\n        in UTC time (i.e. std time) and returns whether DST is effect in this\n        time zone at the given point in time.\n\n        Params:\n            stdTime = The UTC time that needs to be checked for DST in this time\n                      zone.\n      +/\n    abstract bool dstInEffect(long stdTime) @safe const nothrow;\n\n\n    /++\n        Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.\n        in UTC time (i.e. std time) and converts it to this time zone's time.\n\n        Params:\n            stdTime = The UTC time that needs to be adjusted to this time zone's\n                      time.\n      +/\n    abstract long utcToTZ(long stdTime) @safe const nothrow;\n\n\n    /++\n        Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.\n        in this time zone's time and converts it to UTC (i.e. std time).\n\n        Params:\n            adjTime = The time in this time zone that needs to be adjusted to\n                      UTC time.\n      +/\n    abstract long tzToUTC(long adjTime) @safe const nothrow;\n\n\n    /++\n        Returns what the offset from UTC is at the given std time.\n        It includes the DST offset in effect at that time (if any).\n\n        Params:\n            stdTime = The UTC time for which to get the offset from UTC for this\n                      time zone.\n      +/\n    Duration utcOffsetAt(long stdTime) @safe const nothrow\n    {\n        return dur!\"hnsecs\"(utcToTZ(stdTime) - stdTime);\n    }\n\n    // The purpose of this is to handle the case where a Windows time zone is\n    // new and exists on an up-to-date Windows box but does not exist on Windows\n    // boxes which have not been properly updated. The \"date added\" is included\n    // on the theory that we'll be able to remove them at some point in the\n    // the future once enough time has passed, and that way, we know how much\n    // time has passed.\n    private static string _getOldName(string windowsTZName) @safe pure nothrow\n    {\n        switch (windowsTZName)\n        {\n            case \"Belarus Standard Time\": return \"Kaliningrad Standard Time\"; // Added 2014-10-08\n            case \"Russia Time Zone 10\": return \"Magadan Standard Time\"; // Added 2014-10-08\n            case \"Russia Time Zone 11\": return \"Magadan Standard Time\"; // Added 2014-10-08\n            case \"Russia Time Zone 3\": return \"Russian Standard Time\"; // Added 2014-10-08\n            default: return null;\n        }\n    }\n\n    // Since reading in the time zone files could be expensive, most unit tests\n    // are consolidated into this one unittest block which minimizes how often\n    // it reads a time zone file.\n    @system unittest\n    {\n        import core.exception : AssertError;\n        import std.conv : to;\n        import std.file : exists, isFile;\n        import std.format : format;\n        import std.path : chainPath;\n        import std.stdio : writefln;\n        import std.typecons : tuple;\n\n        version (Posix) alias getTimeZone = PosixTimeZone.getTimeZone;\n        else version (Windows) alias getTimeZone = WindowsTimeZone.getTimeZone;\n\n        version (Posix) scope(exit) clearTZEnvVar();\n\n        static immutable(TimeZone) testTZ(string tzName,\n                                          string stdName,\n                                          string dstName,\n                                          Duration utcOffset,\n                                          Duration dstOffset,\n                                          bool north = true)\n        {\n            scope(failure) writefln(\"Failed time zone: %s\", tzName);\n\n            version (Posix)\n            {\n                immutable tz = PosixTimeZone.getTimeZone(tzName);\n                assert(tz.name == tzName);\n            }\n            else version (Windows)\n            {\n                immutable tz = WindowsTimeZone.getTimeZone(tzName);\n                assert(tz.name == stdName);\n            }\n\n            immutable hasDST = dstOffset != Duration.zero;\n\n            //assert(tz.stdName == stdName);  //Locale-dependent\n            //assert(tz.dstName == dstName);  //Locale-dependent\n            assert(tz.hasDST == hasDST);\n\n            import std.datetime.date : DateTime;\n            immutable stdDate = DateTime(2010, north ? 1 : 7, 1, 6, 0, 0);\n            immutable dstDate = DateTime(2010, north ? 7 : 1, 1, 6, 0, 0);\n            auto std = SysTime(stdDate, tz);\n            auto dst = SysTime(dstDate, tz);\n            auto stdUTC = SysTime(stdDate - utcOffset, UTC());\n            auto dstUTC = SysTime(stdDate - utcOffset + dstOffset, UTC());\n\n            assert(!std.dstInEffect);\n            assert(dst.dstInEffect == hasDST);\n            assert(tz.utcOffsetAt(std.stdTime) == utcOffset);\n            assert(tz.utcOffsetAt(dst.stdTime) == utcOffset + dstOffset);\n\n            assert(cast(DateTime) std == stdDate);\n            assert(cast(DateTime) dst == dstDate);\n            assert(std == stdUTC);\n\n            version (Posix)\n            {\n                setTZEnvVar(tzName);\n\n                static void testTM(scope const SysTime st)\n                {\n                    import core.stdc.time : tm;\n                    import core.sys.posix.time : localtime_r;\n\n                    time_t unixTime = st.toUnixTime();\n                    tm osTimeInfo = void;\n                    localtime_r(&unixTime, &osTimeInfo);\n                    tm ourTimeInfo = st.toTM();\n\n                    assert(ourTimeInfo.tm_sec == osTimeInfo.tm_sec);\n                    assert(ourTimeInfo.tm_min == osTimeInfo.tm_min);\n                    assert(ourTimeInfo.tm_hour == osTimeInfo.tm_hour);\n                    assert(ourTimeInfo.tm_mday == osTimeInfo.tm_mday);\n                    assert(ourTimeInfo.tm_mon == osTimeInfo.tm_mon);\n                    assert(ourTimeInfo.tm_year == osTimeInfo.tm_year);\n                    assert(ourTimeInfo.tm_wday == osTimeInfo.tm_wday);\n                    assert(ourTimeInfo.tm_yday == osTimeInfo.tm_yday);\n                    assert(ourTimeInfo.tm_isdst == osTimeInfo.tm_isdst);\n                    assert(ourTimeInfo.tm_gmtoff == osTimeInfo.tm_gmtoff);\n                    assert(to!string(ourTimeInfo.tm_zone) == to!string(osTimeInfo.tm_zone));\n                }\n\n                testTM(std);\n                testTM(dst);\n\n                // Apparently, right/ does not exist on Mac OS X. I don't know\n                // whether or not it exists on FreeBSD. It's rather pointless\n                // normally, since the Posix standard requires that leap seconds\n                // be ignored, so it does make some sense that right/ wouldn't\n                // be there, but since PosixTimeZone _does_ use leap seconds if\n                // the time zone file does, we'll test that functionality if the\n                // appropriate files exist.\n                if (chainPath(PosixTimeZone.defaultTZDatabaseDir, \"right\", tzName).exists)\n                {\n                    auto leapTZ = PosixTimeZone.getTimeZone(\"right/\" ~ tzName);\n\n                    assert(leapTZ.name == \"right/\" ~ tzName);\n                    //assert(leapTZ.stdName == stdName);  //Locale-dependent\n                    //assert(leapTZ.dstName == dstName);  //Locale-dependent\n                    assert(leapTZ.hasDST == hasDST);\n\n                    auto leapSTD = SysTime(std.stdTime, leapTZ);\n                    auto leapDST = SysTime(dst.stdTime, leapTZ);\n\n                    assert(!leapSTD.dstInEffect);\n                    assert(leapDST.dstInEffect == hasDST);\n\n                    assert(leapSTD.stdTime == std.stdTime);\n                    assert(leapDST.stdTime == dst.stdTime);\n\n                    // Whenever a leap second is added/removed,\n                    // this will have to be adjusted.\n                    //enum leapDiff = convert!(\"seconds\", \"hnsecs\")(25);\n                    //assert(leapSTD.adjTime - leapDiff == std.adjTime);\n                    //assert(leapDST.adjTime - leapDiff == dst.adjTime);\n                }\n            }\n\n            return tz;\n        }\n\n        import std.datetime.date : DateTime;\n        auto dstSwitches = [/+America/Los_Angeles+/ tuple(DateTime(2012, 3, 11),  DateTime(2012, 11, 4), 2, 2),\n                            /+America/New_York+/    tuple(DateTime(2012, 3, 11),  DateTime(2012, 11, 4), 2, 2),\n                            ///+America/Santiago+/    tuple(DateTime(2011, 8, 21),  DateTime(2011, 5, 8), 0, 0),\n                            /+Europe/London+/       tuple(DateTime(2012, 3, 25),  DateTime(2012, 10, 28), 1, 2),\n                            /+Europe/Paris+/        tuple(DateTime(2012, 3, 25),  DateTime(2012, 10, 28), 2, 3),\n                            /+Australia/Adelaide+/  tuple(DateTime(2012, 10, 7),  DateTime(2012, 4, 1), 2, 3)];\n\n        import std.datetime.date : DateTimeException;\n        version (Posix)\n        {\n            version (FreeBSD)            enum utcZone = \"Etc/UTC\";\n            else version (NetBSD)        enum utcZone = \"UTC\";\n            else version (DragonFlyBSD)  enum utcZone = \"UTC\";\n            else version (linux)         enum utcZone = \"UTC\";\n            else version (OSX)           enum utcZone = \"UTC\";\n            else version (Solaris)       enum utcZone = \"UTC\";\n            else static assert(0, \"The location of the UTC timezone file on this Posix platform must be set.\");\n\n            auto tzs = [testTZ(\"America/Los_Angeles\", \"PST\", \"PDT\", dur!\"hours\"(-8), dur!\"hours\"(1)),\n                        testTZ(\"America/New_York\", \"EST\", \"EDT\", dur!\"hours\"(-5), dur!\"hours\"(1)),\n                        //testTZ(\"America/Santiago\", \"CLT\", \"CLST\", dur!\"hours\"(-4), dur!\"hours\"(1), false),\n                        testTZ(\"Europe/London\", \"GMT\", \"BST\", dur!\"hours\"(0), dur!\"hours\"(1)),\n                        testTZ(\"Europe/Paris\", \"CET\", \"CEST\", dur!\"hours\"(1), dur!\"hours\"(1)),\n                        // Per www.timeanddate.com, it should be \"CST\" and \"CDT\",\n                        // but the OS insists that it's \"CST\" for both. We should\n                        // probably figure out how to report an error in the TZ\n                        // database and report it.\n                        testTZ(\"Australia/Adelaide\", \"CST\", \"CST\",\n                               dur!\"hours\"(9) + dur!\"minutes\"(30), dur!\"hours\"(1), false)];\n\n            testTZ(utcZone, \"UTC\", \"UTC\", dur!\"hours\"(0), dur!\"hours\"(0));\n            assertThrown!DateTimeException(PosixTimeZone.getTimeZone(\"hello_world\"));\n        }\n        else version (Windows)\n        {\n            auto tzs = [testTZ(\"Pacific Standard Time\", \"Pacific Standard Time\",\n                               \"Pacific Daylight Time\", dur!\"hours\"(-8), dur!\"hours\"(1)),\n                        testTZ(\"Eastern Standard Time\", \"Eastern Standard Time\",\n                               \"Eastern Daylight Time\", dur!\"hours\"(-5), dur!\"hours\"(1)),\n                        //testTZ(\"Pacific SA Standard Time\", \"Pacific SA Standard Time\",\n                               //\"Pacific SA Daylight Time\", dur!\"hours\"(-4), dur!\"hours\"(1), false),\n                        testTZ(\"GMT Standard Time\", \"GMT Standard Time\",\n                               \"GMT Daylight Time\", dur!\"hours\"(0), dur!\"hours\"(1)),\n                        testTZ(\"Romance Standard Time\", \"Romance Standard Time\",\n                               \"Romance Daylight Time\", dur!\"hours\"(1), dur!\"hours\"(1)),\n                        testTZ(\"Cen. Australia Standard Time\", \"Cen. Australia Standard Time\",\n                               \"Cen. Australia Daylight Time\",\n                               dur!\"hours\"(9) + dur!\"minutes\"(30), dur!\"hours\"(1), false)];\n\n            testTZ(\"Greenwich Standard Time\", \"Greenwich Standard Time\",\n                   \"Greenwich Daylight Time\", dur!\"hours\"(0), dur!\"hours\"(0));\n            assertThrown!DateTimeException(WindowsTimeZone.getTimeZone(\"hello_world\"));\n        }\n        else\n            assert(0, \"OS not supported.\");\n\n        foreach (i; 0 .. tzs.length)\n        {\n            auto tz = tzs[i];\n            immutable spring = dstSwitches[i][2];\n            immutable fall = dstSwitches[i][3];\n            auto stdOffset = SysTime(dstSwitches[i][0] + dur!\"days\"(-1), tz).utcOffset;\n            auto dstOffset = stdOffset + dur!\"hours\"(1);\n\n            // Verify that creating a SysTime in the given time zone results\n            // in a SysTime with the correct std time during and surrounding\n            // a DST switch.\n            foreach (hour; -12 .. 13)\n            {\n                import std.exception : enforce;\n                auto st = SysTime(dstSwitches[i][0] + dur!\"hours\"(hour), tz);\n                immutable targetHour = hour < 0 ? hour + 24 : hour;\n\n                static void testHour(SysTime st, int hour, string tzName, size_t line = __LINE__)\n                {\n                    enforce(st.hour == hour,\n                            new AssertError(format(\"[%s] [%s]: [%s] [%s]\", st, tzName, st.hour, hour),\n                                            __FILE__, line));\n                }\n\n                void testOffset1(Duration offset, bool dstInEffect, size_t line = __LINE__)\n                {\n                    AssertError msg(string tag)\n                    {\n                        return new AssertError(format(\"%s [%s] [%s]: [%s] [%s] [%s]\",\n                                                      tag, st, tz.name, st.utcOffset, stdOffset, dstOffset),\n                                               __FILE__, line);\n                    }\n\n                    enforce(st.dstInEffect == dstInEffect, msg(\"1\"));\n                    enforce(st.utcOffset == offset, msg(\"2\"));\n                    enforce((st + dur!\"minutes\"(1)).utcOffset == offset, msg(\"3\"));\n                }\n\n                if (hour == spring)\n                {\n                    testHour(st, spring + 1, tz.name);\n                    testHour(st + dur!\"minutes\"(1), spring + 1, tz.name);\n                }\n                else\n                {\n                    testHour(st, targetHour, tz.name);\n                    testHour(st + dur!\"minutes\"(1), targetHour, tz.name);\n                }\n\n                if (hour < spring)\n                    testOffset1(stdOffset, false);\n                else\n                    testOffset1(dstOffset, true);\n\n                st = SysTime(dstSwitches[i][1] + dur!\"hours\"(hour), tz);\n                testHour(st, targetHour, tz.name);\n\n                // Verify that 01:00 is the first 01:00 (or whatever hour before the switch is).\n                if (hour == fall - 1)\n                    testHour(st + dur!\"hours\"(1), targetHour, tz.name);\n\n                if (hour < fall)\n                    testOffset1(dstOffset, true);\n                else\n                    testOffset1(stdOffset, false);\n            }\n\n            // Verify that converting a time in UTC to a time in another\n            // time zone results in the correct time during and surrounding\n            // a DST switch.\n            bool first = true;\n            auto springSwitch = SysTime(dstSwitches[i][0] + dur!\"hours\"(spring), UTC()) - stdOffset;\n            auto fallSwitch = SysTime(dstSwitches[i][1] + dur!\"hours\"(fall), UTC()) - dstOffset;\n            // @@@BUG@@@ 3659 makes this necessary.\n            auto fallSwitchMinus1 = fallSwitch - dur!\"hours\"(1);\n\n            foreach (hour; -24 .. 25)\n            {\n                auto utc = SysTime(dstSwitches[i][0] + dur!\"hours\"(hour), UTC());\n                auto local = utc.toOtherTZ(tz);\n\n                void testOffset2(Duration offset, size_t line = __LINE__)\n                {\n                    AssertError msg(string tag)\n                    {\n                        return new AssertError(format(\"%s [%s] [%s]: [%s] [%s]\", tag, hour, tz.name, utc, local),\n                                               __FILE__, line);\n                    }\n\n                    import std.exception : enforce;\n                    enforce((utc + offset).hour == local.hour, msg(\"1\"));\n                    enforce((utc + offset + dur!\"minutes\"(1)).hour == local.hour, msg(\"2\"));\n                }\n\n                if (utc < springSwitch)\n                    testOffset2(stdOffset);\n                else\n                    testOffset2(dstOffset);\n\n                utc = SysTime(dstSwitches[i][1] + dur!\"hours\"(hour), UTC());\n                local = utc.toOtherTZ(tz);\n\n                if (utc == fallSwitch || utc == fallSwitchMinus1)\n                {\n                    if (first)\n                    {\n                        testOffset2(dstOffset);\n                        first = false;\n                    }\n                    else\n                        testOffset2(stdOffset);\n                }\n                else if (utc > fallSwitch)\n                    testOffset2(stdOffset);\n                else\n                    testOffset2(dstOffset);\n            }\n        }\n    }\n\n\nprotected:\n\n    /++\n        Params:\n            name    = The name of the time zone.\n            stdName = The abbreviation for the time zone during std time.\n            dstName = The abbreviation for the time zone during DST.\n      +/\n    this(string name, string stdName, string dstName) @safe immutable pure\n    {\n        _name = name;\n        _stdName = stdName;\n        _dstName = dstName;\n    }\n\n\nprivate:\n\n    immutable string _name;\n    immutable string _stdName;\n    immutable string _dstName;\n}\n\n\n/++\n    A TimeZone which represents the current local time zone on\n    the system running your program.\n\n    This uses the underlying C calls to adjust the time rather than using\n    specific D code based off of system settings to calculate the time such as\n    $(LREF PosixTimeZone) and $(LREF WindowsTimeZone) do. That also means that\n    it will use whatever the current time zone is on the system, even if the\n    system's time zone changes while the program is running.\n  +/\nfinal class LocalTime : TimeZone\n{\npublic:\n\n    /++\n        $(LREF LocalTime) is a singleton class. $(LREF LocalTime) returns its\n        only instance.\n      +/\n    static immutable(LocalTime) opCall() @trusted pure nothrow\n    {\n        alias FuncType = @safe pure nothrow immutable(LocalTime) function();\n        return (cast(FuncType)&singleton)();\n    }\n\n\n    version (StdDdoc)\n    {\n        /++\n            In principle, this is the name of the local time zone. However,\n            this always returns the empty string. This is because time zones\n            cannot be uniquely identified by the attributes given by the\n            OS (such as the `stdName` and `dstName`), and neither Posix systems\n            nor Windows systems provide an easy way to get the TZ Database name\n            of the local time zone.\n\n            See_Also:\n                $(HTTP en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ\n                  Database)<br>\n                $(HTTP en.wikipedia.org/wiki/List_of_tz_database_time_zones, List\n                  of Time Zones)\n          +/\n        @property override string name() @safe const nothrow;\n    }\n\n\n    /++\n        Typically, the abbreviation (generally 3 or 4 letters) for the time zone\n        when DST is $(I not) in effect (e.g. PST). It is not necessarily unique.\n\n        However, on Windows, it may be the unabbreviated name (e.g. Pacific\n        Standard Time). Regardless, it is not the same as name.\n\n        This property is overridden because the local time of the system could\n        change while the program is running and we need to determine it\n        dynamically rather than it being fixed like it would be with most time\n        zones.\n      +/\n    @property override string stdName() @trusted const nothrow\n    {\n        version (Posix)\n        {\n            import core.stdc.time : tzname;\n            import std.conv : to;\n            try\n                return to!string(tzname[0]);\n            catch (Exception e)\n                assert(0, \"to!string(tzname[0]) failed.\");\n        }\n        else version (Windows)\n        {\n            TIME_ZONE_INFORMATION tzInfo;\n            GetTimeZoneInformation(&tzInfo);\n\n            // Cannot use to!string() like this should, probably due to bug\n            // http://d.puremagic.com/issues/show_bug.cgi?id=5016\n            //return to!string(tzInfo.StandardName);\n\n            wchar[32] str;\n\n            foreach (i, ref wchar c; str)\n                c = tzInfo.StandardName[i];\n\n            string retval;\n\n            try\n            {\n                foreach (dchar c; str)\n                {\n                    if (c == '\\0')\n                        break;\n\n                    retval ~= c;\n                }\n\n                return retval;\n            }\n            catch (Exception e)\n                assert(0, \"GetTimeZoneInformation() returned invalid UTF-16.\");\n        }\n    }\n\n    @safe unittest\n    {\n        version (FreeBSD)\n        {\n            // A bug on FreeBSD 9+ makes it so that this test fails.\n            // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=168862\n        }\n        else version (NetBSD)\n        {\n            // The same bug on NetBSD 7+\n        }\n        else\n        {\n            assert(LocalTime().stdName !is null);\n\n            version (Posix)\n            {\n                scope(exit) clearTZEnvVar();\n\n                setTZEnvVar(\"America/Los_Angeles\");\n                assert(LocalTime().stdName == \"PST\");\n\n                setTZEnvVar(\"America/New_York\");\n                assert(LocalTime().stdName == \"EST\");\n            }\n        }\n    }\n\n\n    /++\n        Typically, the abbreviation (generally 3 or 4 letters) for the time zone\n        when DST $(I is) in effect (e.g. PDT). It is not necessarily unique.\n\n        However, on Windows, it may be the unabbreviated name (e.g. Pacific\n        Daylight Time). Regardless, it is not the same as name.\n\n        This property is overridden because the local time of the system could\n        change while the program is running and we need to determine it\n        dynamically rather than it being fixed like it would be with most time\n        zones.\n      +/\n    @property override string dstName() @trusted const nothrow\n    {\n        version (Posix)\n        {\n            import core.stdc.time : tzname;\n            import std.conv : to;\n            try\n                return to!string(tzname[1]);\n            catch (Exception e)\n                assert(0, \"to!string(tzname[1]) failed.\");\n        }\n        else version (Windows)\n        {\n            TIME_ZONE_INFORMATION tzInfo;\n            GetTimeZoneInformation(&tzInfo);\n\n            // Cannot use to!string() like this should, probably due to bug\n            // http://d.puremagic.com/issues/show_bug.cgi?id=5016\n            //return to!string(tzInfo.DaylightName);\n\n            wchar[32] str;\n\n            foreach (i, ref wchar c; str)\n                c = tzInfo.DaylightName[i];\n\n            string retval;\n\n            try\n            {\n                foreach (dchar c; str)\n                {\n                    if (c == '\\0')\n                        break;\n\n                    retval ~= c;\n                }\n\n                return retval;\n            }\n            catch (Exception e)\n                assert(0, \"GetTimeZoneInformation() returned invalid UTF-16.\");\n        }\n    }\n\n    @safe unittest\n    {\n        // tzname, called from dstName, isn't set by default for Musl.\n        version (CRuntime_Musl)\n            assert(LocalTime().dstName is null);\n        else\n            assert(LocalTime().dstName !is null);\n\n        version (Posix)\n        {\n            scope(exit) clearTZEnvVar();\n\n            version (FreeBSD)\n            {\n                // A bug on FreeBSD 9+ makes it so that this test fails.\n                // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=168862\n            }\n            else version (NetBSD)\n            {\n                // The same bug on NetBSD 7+\n            }\n            else\n            {\n                setTZEnvVar(\"America/Los_Angeles\");\n                assert(LocalTime().dstName == \"PDT\");\n\n                setTZEnvVar(\"America/New_York\");\n                assert(LocalTime().dstName == \"EDT\");\n            }\n        }\n    }\n\n\n    /++\n        Whether this time zone has Daylight Savings Time at any point in time.\n        Note that for some time zone types it may not have DST for current\n        dates but will still return true for `hasDST` because the time zone\n        did at some point have DST.\n      +/\n    @property override bool hasDST() @trusted const nothrow\n    {\n        version (Posix)\n        {\n            static if (is(typeof(daylight)))\n                return cast(bool)(daylight);\n            else\n            {\n                try\n                {\n                    import std.datetime.date : Date;\n                    auto currYear = (cast(Date) Clock.currTime()).year;\n                    auto janOffset = SysTime(Date(currYear, 1, 4), cast(immutable) this).stdTime -\n                                     SysTime(Date(currYear, 1, 4), UTC()).stdTime;\n                    auto julyOffset = SysTime(Date(currYear, 7, 4), cast(immutable) this).stdTime -\n                                      SysTime(Date(currYear, 7, 4), UTC()).stdTime;\n\n                    return janOffset != julyOffset;\n                }\n                catch (Exception e)\n                    assert(0, \"Clock.currTime() threw.\");\n            }\n        }\n        else version (Windows)\n        {\n            TIME_ZONE_INFORMATION tzInfo;\n            GetTimeZoneInformation(&tzInfo);\n\n            return tzInfo.DaylightDate.wMonth != 0;\n        }\n    }\n\n    @safe unittest\n    {\n        LocalTime().hasDST;\n\n        version (Posix)\n        {\n            scope(exit) clearTZEnvVar();\n\n            setTZEnvVar(\"America/Los_Angeles\");\n            assert(LocalTime().hasDST);\n\n            setTZEnvVar(\"America/New_York\");\n            assert(LocalTime().hasDST);\n\n            setTZEnvVar(\"UTC\");\n            assert(!LocalTime().hasDST);\n        }\n    }\n\n\n    /++\n        Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.\n        in UTC time (i.e. std time) and returns whether DST is in effect in this\n        time zone at the given point in time.\n\n        Params:\n            stdTime = The UTC time that needs to be checked for DST in this time\n                      zone.\n      +/\n    override bool dstInEffect(long stdTime) @trusted const nothrow\n    {\n        import core.stdc.time : tm;\n\n        time_t unixTime = stdTimeToUnixTime(stdTime);\n\n        version (Posix)\n        {\n            import core.sys.posix.time : localtime_r;\n\n            tm timeInfo = void;\n            localtime_r(&unixTime, &timeInfo);\n\n            return cast(bool)(timeInfo.tm_isdst);\n        }\n        else version (Windows)\n        {\n            import core.stdc.time : localtime;\n\n            // Apparently Windows isn't smart enough to deal with negative time_t.\n            if (unixTime >= 0)\n            {\n                tm* timeInfo = localtime(&unixTime);\n\n                if (timeInfo)\n                    return cast(bool)(timeInfo.tm_isdst);\n            }\n\n            TIME_ZONE_INFORMATION tzInfo;\n            GetTimeZoneInformation(&tzInfo);\n\n            return WindowsTimeZone._dstInEffect(&tzInfo, stdTime);\n        }\n    }\n\n    @safe unittest\n    {\n        auto currTime = Clock.currStdTime;\n        LocalTime().dstInEffect(currTime);\n    }\n\n\n    /++\n        Returns hnsecs in the local time zone using the standard C function\n        calls on Posix systems and the standard Windows system calls on Windows\n        systems to adjust the time to the appropriate time zone from std time.\n\n        Params:\n            stdTime = The UTC time that needs to be adjusted to this time zone's\n                      time.\n\n        See_Also:\n            `TimeZone.utcToTZ`\n      +/\n    override long utcToTZ(long stdTime) @trusted const nothrow\n    {\n        version (Solaris)\n            return stdTime + convert!(\"seconds\", \"hnsecs\")(tm_gmtoff(stdTime));\n        else version (Posix)\n        {\n            import core.stdc.time : tm;\n            import core.sys.posix.time : localtime_r;\n            time_t unixTime = stdTimeToUnixTime(stdTime);\n            tm timeInfo = void;\n            localtime_r(&unixTime, &timeInfo);\n\n            return stdTime + convert!(\"seconds\", \"hnsecs\")(timeInfo.tm_gmtoff);\n        }\n        else version (Windows)\n        {\n            TIME_ZONE_INFORMATION tzInfo;\n            GetTimeZoneInformation(&tzInfo);\n\n            return WindowsTimeZone._utcToTZ(&tzInfo, stdTime, hasDST);\n        }\n    }\n\n    @safe unittest\n    {\n        LocalTime().utcToTZ(0);\n    }\n\n\n    /++\n        Returns std time using the standard C function calls on Posix systems\n        and the standard Windows system calls on Windows systems to adjust the\n        time to UTC from the appropriate time zone.\n\n        See_Also:\n            `TimeZone.tzToUTC`\n\n        Params:\n            adjTime = The time in this time zone that needs to be adjusted to\n                      UTC time.\n      +/\n    override long tzToUTC(long adjTime) @trusted const nothrow\n    {\n        version (Posix)\n        {\n            import core.stdc.time : tm;\n            import core.sys.posix.time : localtime_r;\n            time_t unixTime = stdTimeToUnixTime(adjTime);\n\n            immutable past = unixTime - cast(time_t) convert!(\"days\", \"seconds\")(1);\n            tm timeInfo = void;\n            localtime_r(past < unixTime ? &past : &unixTime, &timeInfo);\n            immutable pastOffset = timeInfo.tm_gmtoff;\n\n            immutable future = unixTime + cast(time_t) convert!(\"days\", \"seconds\")(1);\n            localtime_r(future > unixTime ? &future : &unixTime, &timeInfo);\n            immutable futureOffset = timeInfo.tm_gmtoff;\n\n            if (pastOffset == futureOffset)\n                return adjTime - convert!(\"seconds\", \"hnsecs\")(pastOffset);\n\n            if (pastOffset < futureOffset)\n                unixTime -= cast(time_t) convert!(\"hours\", \"seconds\")(1);\n\n            unixTime -= pastOffset;\n            localtime_r(&unixTime, &timeInfo);\n\n            return adjTime - convert!(\"seconds\", \"hnsecs\")(timeInfo.tm_gmtoff);\n        }\n        else version (Windows)\n        {\n            TIME_ZONE_INFORMATION tzInfo;\n            GetTimeZoneInformation(&tzInfo);\n\n            return WindowsTimeZone._tzToUTC(&tzInfo, adjTime, hasDST);\n        }\n    }\n\n    @safe unittest\n    {\n        import core.exception : AssertError;\n        import std.format : format;\n        import std.typecons : tuple;\n\n        assert(LocalTime().tzToUTC(LocalTime().utcToTZ(0)) == 0);\n        assert(LocalTime().utcToTZ(LocalTime().tzToUTC(0)) == 0);\n\n        assert(LocalTime().tzToUTC(LocalTime().utcToTZ(0)) == 0);\n        assert(LocalTime().utcToTZ(LocalTime().tzToUTC(0)) == 0);\n\n        version (Posix)\n        {\n            scope(exit) clearTZEnvVar();\n\n            import std.datetime.date : DateTime;\n            auto tzInfos = [tuple(\"America/Los_Angeles\", DateTime(2012, 3, 11), DateTime(2012, 11, 4), 2, 2),\n                            tuple(\"America/New_York\",    DateTime(2012, 3, 11), DateTime(2012, 11, 4), 2, 2),\n                            //tuple(\"America/Santiago\",    DateTime(2011, 8, 21), DateTime(2011, 5, 8), 0, 0),\n                            tuple(\"Atlantic/Azores\",     DateTime(2011, 3, 27), DateTime(2011, 10, 30), 0, 1),\n                            tuple(\"Europe/London\",       DateTime(2012, 3, 25), DateTime(2012, 10, 28), 1, 2),\n                            tuple(\"Europe/Paris\",        DateTime(2012, 3, 25), DateTime(2012, 10, 28), 2, 3),\n                            tuple(\"Australia/Adelaide\",  DateTime(2012, 10, 7), DateTime(2012, 4, 1), 2, 3)];\n\n            foreach (i; 0 .. tzInfos.length)\n            {\n                import std.exception : enforce;\n                auto tzName = tzInfos[i][0];\n                setTZEnvVar(tzName);\n                immutable spring = tzInfos[i][3];\n                immutable fall = tzInfos[i][4];\n                auto stdOffset = SysTime(tzInfos[i][1] + dur!\"hours\"(-12)).utcOffset;\n                auto dstOffset = stdOffset + dur!\"hours\"(1);\n\n                // Verify that creating a SysTime in the given time zone results\n                // in a SysTime with the correct std time during and surrounding\n                // a DST switch.\n                foreach (hour; -12 .. 13)\n                {\n                    auto st = SysTime(tzInfos[i][1] + dur!\"hours\"(hour));\n                    immutable targetHour = hour < 0 ? hour + 24 : hour;\n\n                    static void testHour(SysTime st, int hour, string tzName, size_t line = __LINE__)\n                    {\n                        enforce(st.hour == hour,\n                                new AssertError(format(\"[%s] [%s]: [%s] [%s]\", st, tzName, st.hour, hour),\n                                                __FILE__, line));\n                    }\n\n                    void testOffset1(Duration offset, bool dstInEffect, size_t line = __LINE__)\n                    {\n                        AssertError msg(string tag)\n                        {\n                            return new AssertError(format(\"%s [%s] [%s]: [%s] [%s] [%s]\",\n                                                          tag, st, tzName, st.utcOffset, stdOffset, dstOffset),\n                                                   __FILE__, line);\n                        }\n\n                        enforce(st.dstInEffect == dstInEffect, msg(\"1\"));\n                        enforce(st.utcOffset == offset, msg(\"2\"));\n                        enforce((st + dur!\"minutes\"(1)).utcOffset == offset, msg(\"3\"));\n                    }\n\n                    if (hour == spring)\n                    {\n                        testHour(st, spring + 1, tzName);\n                        testHour(st + dur!\"minutes\"(1), spring + 1, tzName);\n                    }\n                    else\n                    {\n                        testHour(st, targetHour, tzName);\n                        testHour(st + dur!\"minutes\"(1), targetHour, tzName);\n                    }\n\n                    if (hour < spring)\n                        testOffset1(stdOffset, false);\n                    else\n                        testOffset1(dstOffset, true);\n\n                    st = SysTime(tzInfos[i][2] + dur!\"hours\"(hour));\n                    testHour(st, targetHour, tzName);\n\n                    // Verify that 01:00 is the first 01:00 (or whatever hour before the switch is).\n                    if (hour == fall - 1)\n                        testHour(st + dur!\"hours\"(1), targetHour, tzName);\n\n                    if (hour < fall)\n                        testOffset1(dstOffset, true);\n                    else\n                        testOffset1(stdOffset, false);\n                }\n\n                // Verify that converting a time in UTC to a time in another\n                // time zone results in the correct time during and surrounding\n                // a DST switch.\n                bool first = true;\n                auto springSwitch = SysTime(tzInfos[i][1] + dur!\"hours\"(spring), UTC()) - stdOffset;\n                auto fallSwitch = SysTime(tzInfos[i][2] + dur!\"hours\"(fall), UTC()) - dstOffset;\n                // @@@BUG@@@ 3659 makes this necessary.\n                auto fallSwitchMinus1 = fallSwitch - dur!\"hours\"(1);\n\n                foreach (hour; -24 .. 25)\n                {\n                    auto utc = SysTime(tzInfos[i][1] + dur!\"hours\"(hour), UTC());\n                    auto local = utc.toLocalTime();\n\n                    void testOffset2(Duration offset, size_t line = __LINE__)\n                    {\n                        AssertError msg(string tag)\n                        {\n                            return new AssertError(format(\"%s [%s] [%s]: [%s] [%s]\", tag, hour, tzName, utc, local),\n                                                   __FILE__, line);\n                        }\n\n                        enforce((utc + offset).hour == local.hour, msg(\"1\"));\n                        enforce((utc + offset + dur!\"minutes\"(1)).hour == local.hour, msg(\"2\"));\n                    }\n\n                    if (utc < springSwitch)\n                        testOffset2(stdOffset);\n                    else\n                        testOffset2(dstOffset);\n\n                    utc = SysTime(tzInfos[i][2] + dur!\"hours\"(hour), UTC());\n                    local = utc.toLocalTime();\n\n                    if (utc == fallSwitch || utc == fallSwitchMinus1)\n                    {\n                        if (first)\n                        {\n                            testOffset2(dstOffset);\n                            first = false;\n                        }\n                        else\n                            testOffset2(stdOffset);\n                    }\n                    else if (utc > fallSwitch)\n                        testOffset2(stdOffset);\n                    else\n                        testOffset2(dstOffset);\n                }\n            }\n        }\n    }\n\n\nprivate:\n\n    this() @safe immutable pure\n    {\n        super(\"\", \"\", \"\");\n    }\n\n\n    // This is done so that we can maintain purity in spite of doing an impure\n    // operation the first time that LocalTime() is called.\n    static immutable(LocalTime) singleton() @trusted\n    {\n        import core.stdc.time : tzset;\n        import std.concurrency : initOnce;\n        static instance = new immutable(LocalTime)();\n        static shared bool guard;\n        initOnce!guard({tzset(); return true;}());\n        return instance;\n    }\n\n\n    // The Solaris version of struct tm has no tm_gmtoff field, so do it here\n    version (Solaris)\n    {\n        long tm_gmtoff(long stdTime) @trusted const nothrow\n        {\n            import core.stdc.time : tm;\n            import core.sys.posix.time : localtime_r, gmtime_r;\n\n            time_t unixTime = stdTimeToUnixTime(stdTime);\n            tm timeInfo = void;\n            localtime_r(&unixTime, &timeInfo);\n            tm timeInfoGmt = void;\n            gmtime_r(&unixTime, &timeInfoGmt);\n\n            return timeInfo.tm_sec - timeInfoGmt.tm_sec +\n                   convert!(\"minutes\", \"seconds\")(timeInfo.tm_min - timeInfoGmt.tm_min) +\n                   convert!(\"hours\", \"seconds\")(timeInfo.tm_hour - timeInfoGmt.tm_hour);\n        }\n    }\n}\n\n\n/++\n    A $(LREF TimeZone) which represents UTC.\n  +/\nfinal class UTC : TimeZone\n{\npublic:\n\n    /++\n        `UTC` is a singleton class. `UTC` returns its only instance.\n      +/\n    static immutable(UTC) opCall() @safe pure nothrow\n    {\n        return _utc;\n    }\n\n\n    /++\n        Always returns false.\n      +/\n    @property override bool hasDST() @safe const nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Always returns false.\n      +/\n    override bool dstInEffect(long stdTime) @safe const nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Returns the given hnsecs without changing them at all.\n\n        Params:\n            stdTime = The UTC time that needs to be adjusted to this time zone's\n                      time.\n\n        See_Also:\n            `TimeZone.utcToTZ`\n      +/\n    override long utcToTZ(long stdTime) @safe const nothrow\n    {\n        return stdTime;\n    }\n\n    @safe unittest\n    {\n        assert(UTC().utcToTZ(0) == 0);\n\n        version (Posix)\n        {\n            scope(exit) clearTZEnvVar();\n\n            setTZEnvVar(\"UTC\");\n            import std.datetime.date : Date;\n            auto std = SysTime(Date(2010, 1, 1));\n            auto dst = SysTime(Date(2010, 7, 1));\n            assert(UTC().utcToTZ(std.stdTime) == std.stdTime);\n            assert(UTC().utcToTZ(dst.stdTime) == dst.stdTime);\n        }\n    }\n\n\n    /++\n        Returns the given hnsecs without changing them at all.\n\n        See_Also:\n            `TimeZone.tzToUTC`\n\n        Params:\n            adjTime = The time in this time zone that needs to be adjusted to\n                      UTC time.\n      +/\n    override long tzToUTC(long adjTime) @safe const nothrow\n    {\n        return adjTime;\n    }\n\n    @safe unittest\n    {\n        assert(UTC().tzToUTC(0) == 0);\n\n        version (Posix)\n        {\n            scope(exit) clearTZEnvVar();\n\n            setTZEnvVar(\"UTC\");\n            import std.datetime.date : Date;\n            auto std = SysTime(Date(2010, 1, 1));\n            auto dst = SysTime(Date(2010, 7, 1));\n            assert(UTC().tzToUTC(std.stdTime) == std.stdTime);\n            assert(UTC().tzToUTC(dst.stdTime) == dst.stdTime);\n        }\n    }\n\n\n    /++\n        Returns a $(REF Duration, core,time) of 0.\n\n        Params:\n            stdTime = The UTC time for which to get the offset from UTC for this\n                      time zone.\n      +/\n    override Duration utcOffsetAt(long stdTime) @safe const nothrow\n    {\n        return dur!\"hnsecs\"(0);\n    }\n\n\nprivate:\n\n    this() @safe immutable pure\n    {\n        super(\"UTC\", \"UTC\", \"UTC\");\n    }\n\n\n    static immutable UTC _utc = new immutable(UTC)();\n}\n\n\n/++\n    Represents a time zone with an offset (in minutes, west is negative) from\n    UTC but no DST.\n\n    It's primarily used as the time zone in the result of\n    $(REF SysTime,std,datetime,systime)'s `fromISOString`,\n    `fromISOExtString`, and `fromSimpleString`.\n\n    `name` and `dstName` are always the empty string since this time zone\n    has no DST, and while it may be meant to represent a time zone which is in\n    the TZ Database, obviously it's not likely to be following the exact rules\n    of any of the time zones in the TZ Database, so it makes no sense to set it.\n  +/\nfinal class SimpleTimeZone : TimeZone\n{\npublic:\n\n    /++\n        Always returns false.\n      +/\n    @property override bool hasDST() @safe const nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Always returns false.\n      +/\n    override bool dstInEffect(long stdTime) @safe const nothrow\n    {\n        return false;\n    }\n\n\n    /++\n        Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.\n        in UTC time (i.e. std time) and converts it to this time zone's time.\n\n        Params:\n            stdTime = The UTC time that needs to be adjusted to this time zone's\n                      time.\n      +/\n    override long utcToTZ(long stdTime) @safe const nothrow\n    {\n        return stdTime + _utcOffset.total!\"hnsecs\";\n    }\n\n    @safe unittest\n    {\n        auto west = new immutable SimpleTimeZone(dur!\"hours\"(-8));\n        auto east = new immutable SimpleTimeZone(dur!\"hours\"(8));\n\n        assert(west.utcToTZ(0) == -288_000_000_000L);\n        assert(east.utcToTZ(0) == 288_000_000_000L);\n        assert(west.utcToTZ(54_321_234_567_890L) == 54_033_234_567_890L);\n\n        const cstz = west;\n        assert(cstz.utcToTZ(50002) == west.utcToTZ(50002));\n    }\n\n\n    /++\n        Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.\n        in this time zone's time and converts it to UTC (i.e. std time).\n\n        Params:\n            adjTime = The time in this time zone that needs to be adjusted to\n                      UTC time.\n      +/\n    override long tzToUTC(long adjTime) @safe const nothrow\n    {\n        return adjTime - _utcOffset.total!\"hnsecs\";\n    }\n\n    @safe unittest\n    {\n        auto west = new immutable SimpleTimeZone(dur!\"hours\"(-8));\n        auto east = new immutable SimpleTimeZone(dur!\"hours\"(8));\n\n        assert(west.tzToUTC(-288_000_000_000L) == 0);\n        assert(east.tzToUTC(288_000_000_000L) == 0);\n        assert(west.tzToUTC(54_033_234_567_890L) == 54_321_234_567_890L);\n\n        const cstz = west;\n        assert(cstz.tzToUTC(20005) == west.tzToUTC(20005));\n    }\n\n\n    /++\n        Returns utcOffset as a $(REF Duration, core,time).\n\n        Params:\n            stdTime = The UTC time for which to get the offset from UTC for this\n                      time zone.\n      +/\n    override Duration utcOffsetAt(long stdTime) @safe const nothrow\n    {\n        return _utcOffset;\n    }\n\n\n    /++\n        Params:\n            utcOffset = This time zone's offset from UTC with west of UTC being\n                        negative (it is added to UTC to get the adjusted time).\n            stdName   = The `stdName` for this time zone.\n      +/\n    this(Duration utcOffset, string stdName = \"\") @safe immutable pure\n    {\n        // FIXME This probably needs to be changed to something like (-12 - 13).\n        import std.datetime.date : DateTimeException;\n        import std.exception : enforce;\n        enforce!DateTimeException(abs(utcOffset) < dur!\"minutes\"(1440),\n                                    \"Offset from UTC must be within range (-24:00 - 24:00).\");\n        super(\"\", stdName, \"\");\n        this._utcOffset = utcOffset;\n    }\n\n    @safe unittest\n    {\n        auto stz = new immutable SimpleTimeZone(dur!\"hours\"(-8), \"PST\");\n        assert(stz.name == \"\");\n        assert(stz.stdName == \"PST\");\n        assert(stz.dstName == \"\");\n        assert(stz.utcOffset == dur!\"hours\"(-8));\n    }\n\n\n    /++\n        The amount of time the offset from UTC is (negative is west of UTC,\n        positive is east).\n      +/\n    @property Duration utcOffset() @safe const pure nothrow\n    {\n        return _utcOffset;\n    }\n\n\npackage:\n\n    /+\n        Returns a time zone as a string with an offset from UTC.\n\n        Time zone offsets will be in the form +HHMM or -HHMM.\n\n        Params:\n            utcOffset = The number of minutes offset from UTC (negative means\n                        west).\n      +/\n    static string toISOString(Duration utcOffset) @safe pure\n    {\n        import std.array : appender;\n        auto w = appender!string();\n        w.reserve(5);\n        toISOString(w, utcOffset);\n        return w.data;\n    }\n\n    // ditto\n    static void toISOString(W)(ref W writer, Duration utcOffset)\n    if (isOutputRange!(W, char))\n    {\n        import std.datetime.date : DateTimeException;\n        import std.exception : enforce;\n        import std.format : formattedWrite;\n        immutable absOffset = abs(utcOffset);\n        enforce!DateTimeException(absOffset < dur!\"minutes\"(1440),\n                                  \"Offset from UTC must be within range (-24:00 - 24:00).\");\n        int hours;\n        int minutes;\n        absOffset.split!(\"hours\", \"minutes\")(hours, minutes);\n        formattedWrite(\n            writer,\n            utcOffset < Duration.zero ? \"-%02d%02d\" : \"+%02d%02d\",\n            hours,\n            minutes\n        );\n    }\n\n    @safe unittest\n    {\n        static string testSTZInvalid(Duration offset)\n        {\n            return SimpleTimeZone.toISOString(offset);\n        }\n\n        import std.datetime.date : DateTimeException;\n        assertThrown!DateTimeException(testSTZInvalid(dur!\"minutes\"(1440)));\n        assertThrown!DateTimeException(testSTZInvalid(dur!\"minutes\"(-1440)));\n\n        assert(toISOString(dur!\"minutes\"(0)) == \"+0000\");\n        assert(toISOString(dur!\"minutes\"(1)) == \"+0001\");\n        assert(toISOString(dur!\"minutes\"(10)) == \"+0010\");\n        assert(toISOString(dur!\"minutes\"(59)) == \"+0059\");\n        assert(toISOString(dur!\"minutes\"(60)) == \"+0100\");\n        assert(toISOString(dur!\"minutes\"(90)) == \"+0130\");\n        assert(toISOString(dur!\"minutes\"(120)) == \"+0200\");\n        assert(toISOString(dur!\"minutes\"(480)) == \"+0800\");\n        assert(toISOString(dur!\"minutes\"(1439)) == \"+2359\");\n\n        assert(toISOString(dur!\"minutes\"(-1)) == \"-0001\");\n        assert(toISOString(dur!\"minutes\"(-10)) == \"-0010\");\n        assert(toISOString(dur!\"minutes\"(-59)) == \"-0059\");\n        assert(toISOString(dur!\"minutes\"(-60)) == \"-0100\");\n        assert(toISOString(dur!\"minutes\"(-90)) == \"-0130\");\n        assert(toISOString(dur!\"minutes\"(-120)) == \"-0200\");\n        assert(toISOString(dur!\"minutes\"(-480)) == \"-0800\");\n        assert(toISOString(dur!\"minutes\"(-1439)) == \"-2359\");\n    }\n\n\n    /+\n        Returns a time zone as a string with an offset from UTC.\n\n        Time zone offsets will be in the form +HH:MM or -HH:MM.\n\n        Params:\n            utcOffset = The number of minutes offset from UTC (negative means\n                        west).\n      +/\n    static string toISOExtString(Duration utcOffset) @safe pure\n    {\n        import std.array : appender;\n        auto w = appender!string();\n        w.reserve(6);\n        toISOExtString(w, utcOffset);\n        return w.data;\n    }\n\n    // ditto\n    static void toISOExtString(W)(ref W writer, Duration utcOffset)\n    {\n        import std.datetime.date : DateTimeException;\n        import std.format : formattedWrite;\n        import std.exception : enforce;\n\n        immutable absOffset = abs(utcOffset);\n        enforce!DateTimeException(absOffset < dur!\"minutes\"(1440),\n                                  \"Offset from UTC must be within range (-24:00 - 24:00).\");\n        int hours;\n        int minutes;\n        absOffset.split!(\"hours\", \"minutes\")(hours, minutes);\n        formattedWrite(\n            writer,\n            utcOffset < Duration.zero ? \"-%02d:%02d\" : \"+%02d:%02d\",\n            hours,\n            minutes\n        );\n    }\n\n    @safe unittest\n    {\n        static string testSTZInvalid(Duration offset)\n        {\n            return SimpleTimeZone.toISOExtString(offset);\n        }\n\n        import std.datetime.date : DateTimeException;\n        assertThrown!DateTimeException(testSTZInvalid(dur!\"minutes\"(1440)));\n        assertThrown!DateTimeException(testSTZInvalid(dur!\"minutes\"(-1440)));\n\n        assert(toISOExtString(dur!\"minutes\"(0)) == \"+00:00\");\n        assert(toISOExtString(dur!\"minutes\"(1)) == \"+00:01\");\n        assert(toISOExtString(dur!\"minutes\"(10)) == \"+00:10\");\n        assert(toISOExtString(dur!\"minutes\"(59)) == \"+00:59\");\n        assert(toISOExtString(dur!\"minutes\"(60)) == \"+01:00\");\n        assert(toISOExtString(dur!\"minutes\"(90)) == \"+01:30\");\n        assert(toISOExtString(dur!\"minutes\"(120)) == \"+02:00\");\n        assert(toISOExtString(dur!\"minutes\"(480)) == \"+08:00\");\n        assert(toISOExtString(dur!\"minutes\"(1439)) == \"+23:59\");\n\n        assert(toISOExtString(dur!\"minutes\"(-1)) == \"-00:01\");\n        assert(toISOExtString(dur!\"minutes\"(-10)) == \"-00:10\");\n        assert(toISOExtString(dur!\"minutes\"(-59)) == \"-00:59\");\n        assert(toISOExtString(dur!\"minutes\"(-60)) == \"-01:00\");\n        assert(toISOExtString(dur!\"minutes\"(-90)) == \"-01:30\");\n        assert(toISOExtString(dur!\"minutes\"(-120)) == \"-02:00\");\n        assert(toISOExtString(dur!\"minutes\"(-480)) == \"-08:00\");\n        assert(toISOExtString(dur!\"minutes\"(-1439)) == \"-23:59\");\n    }\n\n\n    /+\n        Takes a time zone as a string with an offset from UTC and returns a\n        $(LREF SimpleTimeZone) which matches.\n\n        The accepted formats for time zone offsets are +HH, -HH, +HHMM, and\n        -HHMM.\n\n        Params:\n            isoString = A string which represents a time zone in the ISO format.\n      +/\n    static immutable(SimpleTimeZone) fromISOString(S)(S isoString) @safe pure\n        if (isSomeString!S)\n    {\n        import std.algorithm.searching : startsWith;\n        import std.conv : text, to, ConvException;\n        import std.datetime.date : DateTimeException;\n        import std.exception : enforce;\n\n        auto whichSign = isoString.startsWith('-', '+');\n        enforce!DateTimeException(whichSign > 0, text(\"Invalid ISO String \", isoString));\n\n        isoString = isoString[1 .. $];\n        auto sign = whichSign == 1 ? -1 : 1;\n        int hours;\n        int minutes;\n\n        try\n        {\n            // cast to int from uint is used because it checks for\n            // non digits without extra loops\n            if (isoString.length == 2)\n            {\n                hours = cast(int) to!uint(isoString);\n            }\n            else if (isoString.length == 4)\n            {\n                hours = cast(int) to!uint(isoString[0 .. 2]);\n                minutes = cast(int) to!uint(isoString[2 .. 4]);\n            }\n            else\n            {\n                throw new DateTimeException(text(\"Invalid ISO String \", isoString));\n            }\n        }\n        catch (ConvException)\n        {\n            throw new DateTimeException(text(\"Invalid ISO String \", isoString));\n        }\n\n        enforce!DateTimeException(hours < 24 && minutes < 60, text(\"Invalid ISO String \", isoString));\n\n        return new immutable SimpleTimeZone(sign * (dur!\"hours\"(hours) + dur!\"minutes\"(minutes)));\n    }\n\n    @safe unittest\n    {\n        import core.exception : AssertError;\n        import std.format : format;\n\n        foreach (str; [\"\", \"Z\", \"-\", \"+\", \"-:\", \"+:\", \"-1:\", \"+1:\", \"+1\", \"-1\",\n                       \"-24:00\", \"+24:00\", \"-24\", \"+24\", \"-2400\", \"+2400\",\n                       \"1\", \"+1\", \"-1\", \"+9\", \"-9\",\n                       \"+1:0\", \"+01:0\", \"+1:00\", \"+01:000\", \"+01:60\",\n                       \"-1:0\", \"-01:0\", \"-1:00\", \"-01:000\", \"-01:60\",\n                       \"000\", \"00000\", \"0160\", \"-0160\",\n                       \" +08:00\", \"+ 08:00\", \"+08 :00\", \"+08: 00\", \"+08:00 \",\n                       \" -08:00\", \"- 08:00\", \"-08 :00\", \"-08: 00\", \"-08:00 \",\n                       \" +0800\", \"+ 0800\", \"+08 00\", \"+08 00\", \"+0800 \",\n                       \" -0800\", \"- 0800\", \"-08 00\", \"-08 00\", \"-0800 \",\n                       \"+ab:cd\", \"+abcd\", \"+0Z:00\", \"+Z\", \"+00Z\",\n                       \"-ab:cd\", \"+abcd\", \"-0Z:00\", \"-Z\", \"-00Z\",\n                       \"01:00\", \"12:00\", \"23:59\"])\n        {\n            import std.datetime.date : DateTimeException;\n            assertThrown!DateTimeException(SimpleTimeZone.fromISOString(str), format(\"[%s]\", str));\n        }\n\n        static void test(string str, Duration utcOffset, size_t line = __LINE__)\n        {\n            if (SimpleTimeZone.fromISOString(str).utcOffset != (new immutable SimpleTimeZone(utcOffset)).utcOffset)\n                throw new AssertError(\"unittest failure\", __FILE__, line);\n        }\n\n        test(\"+0000\", Duration.zero);\n        test(\"+0001\", minutes(1));\n        test(\"+0010\", minutes(10));\n        test(\"+0059\", minutes(59));\n        test(\"+0100\", hours(1));\n        test(\"+0130\", hours(1) + minutes(30));\n        test(\"+0200\", hours(2));\n        test(\"+0800\", hours(8));\n        test(\"+2359\", hours(23) + minutes(59));\n\n        test(\"-0001\", minutes(-1));\n        test(\"-0010\", minutes(-10));\n        test(\"-0059\", minutes(-59));\n        test(\"-0100\", hours(-1));\n        test(\"-0130\", hours(-1) - minutes(30));\n        test(\"-0200\", hours(-2));\n        test(\"-0800\", hours(-8));\n        test(\"-2359\", hours(-23) - minutes(59));\n\n        test(\"+00\", Duration.zero);\n        test(\"+01\", hours(1));\n        test(\"+02\", hours(2));\n        test(\"+12\", hours(12));\n        test(\"+23\", hours(23));\n\n        test(\"-00\", Duration.zero);\n        test(\"-01\", hours(-1));\n        test(\"-02\", hours(-2));\n        test(\"-12\", hours(-12));\n        test(\"-23\", hours(-23));\n    }\n\n    @safe unittest\n    {\n        import core.exception : AssertError;\n        import std.format : format;\n\n        static void test(scope const string isoString, int expectedOffset, size_t line = __LINE__)\n        {\n            auto stz = SimpleTimeZone.fromISOExtString(isoString);\n            if (stz.utcOffset != dur!\"minutes\"(expectedOffset))\n                throw new AssertError(format(\"unittest failure: wrong offset [%s]\", stz.utcOffset), __FILE__, line);\n\n            auto result = SimpleTimeZone.toISOExtString(stz.utcOffset);\n            if (result != isoString)\n                throw new AssertError(format(\"unittest failure: [%s] != [%s]\", result, isoString), __FILE__, line);\n        }\n\n        test(\"+00:00\", 0);\n        test(\"+00:01\", 1);\n        test(\"+00:10\", 10);\n        test(\"+00:59\", 59);\n        test(\"+01:00\", 60);\n        test(\"+01:30\", 90);\n        test(\"+02:00\", 120);\n        test(\"+08:00\", 480);\n        test(\"+08:00\", 480);\n        test(\"+23:59\", 1439);\n\n        test(\"-00:01\", -1);\n        test(\"-00:10\", -10);\n        test(\"-00:59\", -59);\n        test(\"-01:00\", -60);\n        test(\"-01:30\", -90);\n        test(\"-02:00\", -120);\n        test(\"-08:00\", -480);\n        test(\"-08:00\", -480);\n        test(\"-23:59\", -1439);\n    }\n\n\n    /+\n        Takes a time zone as a string with an offset from UTC and returns a\n        $(LREF SimpleTimeZone) which matches.\n\n        The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and\n        -HH:MM.\n\n        Params:\n            isoExtString = A string which represents a time zone in the ISO format.\n      +/\n    static immutable(SimpleTimeZone) fromISOExtString(S)(S isoExtString) @safe pure\n        if (isSomeString!S)\n    {\n        import std.algorithm.searching : startsWith;\n        import std.conv : ConvException, to;\n        import std.datetime.date : DateTimeException;\n        import std.exception : enforce;\n        import std.format : format;\n        import std.string : indexOf;\n\n        auto whichSign = isoExtString.startsWith('-', '+');\n        enforce!DateTimeException(whichSign > 0, format(\"Invalid ISO String: %s\", isoExtString));\n        auto sign = whichSign == 1 ? -1 : 1;\n\n        isoExtString = isoExtString[1 .. $];\n        enforce!DateTimeException(!isoExtString.empty, format(\"Invalid ISO String: %s\", isoExtString));\n\n        immutable colon = isoExtString.indexOf(':');\n        S hoursStr;\n        S minutesStr;\n        int hours, minutes;\n\n        if (colon != -1)\n        {\n            hoursStr = isoExtString[0 .. colon];\n            minutesStr = isoExtString[colon + 1 .. $];\n            enforce!DateTimeException(minutesStr.length == 2, format(\"Invalid ISO String: %s\", isoExtString));\n        }\n        else\n        {\n            hoursStr = isoExtString;\n        }\n\n        enforce!DateTimeException(hoursStr.length == 2, format(\"Invalid ISO String: %s\", isoExtString));\n\n        try\n        {\n            // cast to int from uint is used because it checks for\n            // non digits without extra loops\n            hours = cast(int) to!uint(hoursStr);\n            minutes = cast(int) (minutesStr.empty ? 0 : to!uint(minutesStr));\n        }\n        catch (ConvException)\n        {\n            throw new DateTimeException(format(\"Invalid ISO String: %s\", isoExtString));\n        }\n\n        enforce!DateTimeException(hours < 24 && minutes < 60, format(\"Invalid ISO String: %s\", isoExtString));\n\n        return new immutable SimpleTimeZone(sign * (dur!\"hours\"(hours) + dur!\"minutes\"(minutes)));\n    }\n\n    @safe unittest\n    {\n        import core.exception : AssertError;\n        import std.format : format;\n\n        foreach (str; [\"\", \"Z\", \"-\", \"+\", \"-:\", \"+:\", \"-1:\", \"+1:\", \"+1\", \"-1\",\n                       \"-24:00\", \"+24:00\", \"-24\", \"+24\", \"-2400\", \"-2400\",\n                       \"1\", \"+1\", \"-1\", \"+9\", \"-9\",\n                       \"+1:0\", \"+01:0\", \"+1:00\", \"+01:000\", \"+01:60\",\n                       \"-1:0\", \"-01:0\", \"-1:00\", \"-01:000\", \"-01:60\",\n                       \"000\", \"00000\", \"0160\", \"-0160\",\n                       \" +08:00\", \"+ 08:00\", \"+08 :00\", \"+08: 00\", \"+08:00 \",\n                       \" -08:00\", \"- 08:00\", \"-08 :00\", \"-08: 00\", \"-08:00 \",\n                       \" +0800\", \"+ 0800\", \"+08 00\", \"+08 00\", \"+0800 \",\n                       \" -0800\", \"- 0800\", \"-08 00\", \"-08 00\", \"-0800 \",\n                       \"+ab:cd\", \"abcd\", \"+0Z:00\", \"+Z\", \"+00Z\",\n                       \"-ab:cd\", \"abcd\", \"-0Z:00\", \"-Z\", \"-00Z\",\n                       \"0100\", \"1200\", \"2359\"])\n        {\n            import std.datetime.date : DateTimeException;\n            assertThrown!DateTimeException(SimpleTimeZone.fromISOExtString(str), format(\"[%s]\", str));\n        }\n\n        static void test(string str, Duration utcOffset, size_t line = __LINE__)\n        {\n            if (SimpleTimeZone.fromISOExtString(str).utcOffset != (new immutable SimpleTimeZone(utcOffset)).utcOffset)\n                throw new AssertError(\"unittest failure\", __FILE__, line);\n        }\n\n        test(\"+00:00\", Duration.zero);\n        test(\"+00:01\", minutes(1));\n        test(\"+00:10\", minutes(10));\n        test(\"+00:59\", minutes(59));\n        test(\"+01:00\", hours(1));\n        test(\"+01:30\", hours(1) + minutes(30));\n        test(\"+02:00\", hours(2));\n        test(\"+08:00\", hours(8));\n        test(\"+23:59\", hours(23) + minutes(59));\n\n        test(\"-00:01\", minutes(-1));\n        test(\"-00:10\", minutes(-10));\n        test(\"-00:59\", minutes(-59));\n        test(\"-01:00\", hours(-1));\n        test(\"-01:30\", hours(-1) - minutes(30));\n        test(\"-02:00\", hours(-2));\n        test(\"-08:00\", hours(-8));\n        test(\"-23:59\", hours(-23) - minutes(59));\n\n        test(\"+00\", Duration.zero);\n        test(\"+01\", hours(1));\n        test(\"+02\", hours(2));\n        test(\"+12\", hours(12));\n        test(\"+23\", hours(23));\n\n        test(\"-00\", Duration.zero);\n        test(\"-01\", hours(-1));\n        test(\"-02\", hours(-2));\n        test(\"-12\", hours(-12));\n        test(\"-23\", hours(-23));\n    }\n\n    @safe unittest\n    {\n        import core.exception : AssertError;\n        import std.format : format;\n\n        static void test(scope const string isoExtString, int expectedOffset, size_t line = __LINE__)\n        {\n            auto stz = SimpleTimeZone.fromISOExtString(isoExtString);\n            if (stz.utcOffset != dur!\"minutes\"(expectedOffset))\n                throw new AssertError(format(\"unittest failure: wrong offset [%s]\", stz.utcOffset), __FILE__, line);\n\n            auto result = SimpleTimeZone.toISOExtString(stz.utcOffset);\n            if (result != isoExtString)\n                throw new AssertError(format(\"unittest failure: [%s] != [%s]\", result, isoExtString), __FILE__, line);\n        }\n\n        test(\"+00:00\", 0);\n        test(\"+00:01\", 1);\n        test(\"+00:10\", 10);\n        test(\"+00:59\", 59);\n        test(\"+01:00\", 60);\n        test(\"+01:30\", 90);\n        test(\"+02:00\", 120);\n        test(\"+08:00\", 480);\n        test(\"+08:00\", 480);\n        test(\"+23:59\", 1439);\n\n        test(\"-00:01\", -1);\n        test(\"-00:10\", -10);\n        test(\"-00:59\", -59);\n        test(\"-01:00\", -60);\n        test(\"-01:30\", -90);\n        test(\"-02:00\", -120);\n        test(\"-08:00\", -480);\n        test(\"-08:00\", -480);\n        test(\"-23:59\", -1439);\n    }\n\n\nprivate:\n\n    immutable Duration _utcOffset;\n}\n\n\n/++\n    Represents a time zone from a TZ Database time zone file. Files from the TZ\n    Database are how Posix systems hold their time zone information.\n    Unfortunately, Windows does not use the TZ Database. To use the TZ Database,\n    use `PosixTimeZone` (which reads its information from the TZ Database\n    files on disk) on Windows by providing the TZ Database files and telling\n    `PosixTimeZone.getTimeZone` where the directory holding them is.\n\n    To get a `PosixTimeZone`, call `PosixTimeZone.getTimeZone`\n    (which allows specifying the location the time zone files).\n\n    Note:\n        Unless your system's local time zone deals with leap seconds (which is\n        highly unlikely), then the only way to get a time zone which\n        takes leap seconds into account is to use `PosixTimeZone` with a\n        time zone whose name starts with \"right/\". Those time zone files do\n        include leap seconds, and `PosixTimeZone` will take them into account\n        (though posix systems which use a \"right/\" time zone as their local time\n        zone will $(I not) take leap seconds into account even though they're\n        in the file).\n\n    See_Also:\n        $(HTTP www.iana.org/time-zones, Home of the TZ Database files)<br>\n        $(HTTP en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ Database)<br>\n        $(HTTP en.wikipedia.org/wiki/List_of_tz_database_time_zones, List of Time\n          Zones)\n  +/\nfinal class PosixTimeZone : TimeZone\n{\n    import std.algorithm.searching : countUntil, canFind, startsWith;\n    import std.file : isDir, isFile, exists, dirEntries, SpanMode, DirEntry;\n    import std.path : extension;\n    import std.stdio : File;\n    import std.string : strip, representation;\n    import std.traits : isArray, isSomeChar;\npublic:\n\n    /++\n        Whether this time zone has Daylight Savings Time at any point in time.\n        Note that for some time zone types it may not have DST for current\n        dates but will still return true for `hasDST` because the time zone\n        did at some point have DST.\n      +/\n    @property override bool hasDST() @safe const nothrow\n    {\n        return _hasDST;\n    }\n\n\n    /++\n        Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.\n        in UTC time (i.e. std time) and returns whether DST is in effect in this\n        time zone at the given point in time.\n\n        Params:\n            stdTime = The UTC time that needs to be checked for DST in this time\n                      zone.\n      +/\n    override bool dstInEffect(long stdTime) @safe const nothrow\n    {\n        assert(!_transitions.empty);\n\n        immutable unixTime = stdTimeToUnixTime(stdTime);\n        immutable found = countUntil!\"b < a.timeT\"(_transitions, unixTime);\n\n        if (found == -1)\n            return _transitions.back.ttInfo.isDST;\n\n        immutable transition = found == 0 ? _transitions[0] : _transitions[found - 1];\n\n        return transition.ttInfo.isDST;\n    }\n\n\n    /++\n        Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.\n        in UTC time (i.e. std time) and converts it to this time zone's time.\n\n        Params:\n            stdTime = The UTC time that needs to be adjusted to this time zone's\n                      time.\n      +/\n    override long utcToTZ(long stdTime) @safe const nothrow\n    {\n        assert(!_transitions.empty);\n\n        immutable leapSecs = calculateLeapSeconds(stdTime);\n        immutable unixTime = stdTimeToUnixTime(stdTime);\n        immutable found = countUntil!\"b < a.timeT\"(_transitions, unixTime);\n\n        if (found == -1)\n            return stdTime + convert!(\"seconds\", \"hnsecs\")(_transitions.back.ttInfo.utcOffset + leapSecs);\n\n        immutable transition = found == 0 ? _transitions[0] : _transitions[found - 1];\n\n        return stdTime + convert!(\"seconds\", \"hnsecs\")(transition.ttInfo.utcOffset + leapSecs);\n    }\n\n\n    /++\n        Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.\n        in this time zone's time and converts it to UTC (i.e. std time).\n\n        Params:\n            adjTime = The time in this time zone that needs to be adjusted to\n                      UTC time.\n      +/\n    override long tzToUTC(long adjTime) @safe const nothrow\n    {\n        assert(!_transitions.empty);\n\n        immutable leapSecs = calculateLeapSeconds(adjTime);\n        time_t unixTime = stdTimeToUnixTime(adjTime);\n        immutable past = unixTime - convert!(\"days\", \"seconds\")(1);\n        immutable future = unixTime + convert!(\"days\", \"seconds\")(1);\n\n        immutable pastFound = countUntil!\"b < a.timeT\"(_transitions, past);\n\n        if (pastFound == -1)\n            return adjTime - convert!(\"seconds\", \"hnsecs\")(_transitions.back.ttInfo.utcOffset + leapSecs);\n\n        immutable futureFound = countUntil!\"b < a.timeT\"(_transitions[pastFound .. $], future);\n        immutable pastTrans = pastFound == 0 ? _transitions[0] : _transitions[pastFound - 1];\n\n        if (futureFound == 0)\n            return adjTime - convert!(\"seconds\", \"hnsecs\")(pastTrans.ttInfo.utcOffset + leapSecs);\n\n        immutable futureTrans = futureFound == -1 ? _transitions.back\n                                                  : _transitions[pastFound + futureFound - 1];\n        immutable pastOffset = pastTrans.ttInfo.utcOffset;\n\n        if (pastOffset < futureTrans.ttInfo.utcOffset)\n            unixTime -= convert!(\"hours\", \"seconds\")(1);\n\n        immutable found = countUntil!\"b < a.timeT\"(_transitions[pastFound .. $], unixTime - pastOffset);\n\n        if (found == -1)\n            return adjTime - convert!(\"seconds\", \"hnsecs\")(_transitions.back.ttInfo.utcOffset + leapSecs);\n\n        immutable transition = found == 0 ? pastTrans : _transitions[pastFound + found - 1];\n\n        return adjTime - convert!(\"seconds\", \"hnsecs\")(transition.ttInfo.utcOffset + leapSecs);\n    }\n\n\n    version (StdDdoc)\n    {\n        /++\n            The default directory where the TZ Database files are stored. It's\n            empty for Windows, since Windows doesn't have them. You can also use\n            the TZDatabaseDir version to pass an arbitrary path at compile-time,\n            rather than hard-coding it here. Android concatenates all time zone\n            data into a single file called tzdata and stores it in the directory\n            below.\n          +/\n        enum defaultTZDatabaseDir = \"\";\n    }\n    else version (TZDatabaseDir)\n    {\n        import std.string : strip;\n        enum defaultTZDatabaseDir = strip(import(\"TZDatabaseDirFile\"));\n    }\n    else version (Android)\n    {\n        enum defaultTZDatabaseDir = \"/system/usr/share/zoneinfo/\";\n    }\n    else version (Solaris)\n    {\n        enum defaultTZDatabaseDir = \"/usr/share/lib/zoneinfo/\";\n    }\n    else version (Posix)\n    {\n        enum defaultTZDatabaseDir = \"/usr/share/zoneinfo/\";\n    }\n    else version (Windows)\n    {\n        enum defaultTZDatabaseDir = \"\";\n    }\n\n\n    /++\n        Returns a $(LREF TimeZone) with the give name per the TZ Database. The\n        time zone information is fetched from the TZ Database time zone files in\n        the given directory.\n\n        See_Also:\n            $(HTTP en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ\n              Database)<br>\n            $(HTTP en.wikipedia.org/wiki/List_of_tz_database_time_zones, List of\n              Time Zones)\n\n        Params:\n            name          = The TZ Database name of the desired time zone\n            tzDatabaseDir = The directory where the TZ Database files are\n                            located. Because these files are not located on\n                            Windows systems, provide them\n                            and give their location here to\n                            use $(LREF PosixTimeZone)s.\n\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if the given time zone\n            could not be found or `FileException` if the TZ Database file\n            could not be opened.\n      +/\n    // TODO make it possible for tzDatabaseDir to be gzipped tar file rather than an uncompressed\n    //      directory.\n    static immutable(PosixTimeZone) getTimeZone(string name, string tzDatabaseDir = defaultTZDatabaseDir) @trusted\n    {\n        import std.algorithm.sorting : sort;\n        import std.conv : to;\n        import std.datetime.date : DateTimeException;\n        import std.exception : enforce;\n        import std.format : format;\n        import std.path : asNormalizedPath, chainPath;\n        import std.range : retro;\n\n        name = strip(name);\n\n        enforce(tzDatabaseDir.exists(), new DateTimeException(format(\"Directory %s does not exist.\", tzDatabaseDir)));\n        enforce(tzDatabaseDir.isDir, new DateTimeException(format(\"%s is not a directory.\", tzDatabaseDir)));\n\n        version (Android)\n        {\n            auto tzfileOffset = name in tzdataIndex(tzDatabaseDir);\n            enforce(tzfileOffset, new DateTimeException(format(\"The time zone %s is not listed.\", name)));\n            string tzFilename = separate_index ? \"zoneinfo.dat\" : \"tzdata\";\n            const file = asNormalizedPath(chainPath(tzDatabaseDir, tzFilename)).to!string;\n        }\n        else\n            const file = asNormalizedPath(chainPath(tzDatabaseDir, name)).to!string;\n\n        enforce(file.exists(), new DateTimeException(format(\"File %s does not exist.\", file)));\n        enforce(file.isFile, new DateTimeException(format(\"%s is not a file.\", file)));\n\n        auto tzFile = File(file);\n        version (Android) tzFile.seek(*tzfileOffset);\n        immutable gmtZone = name.representation().canFind(\"GMT\");\n\n        import std.datetime.date : DateTimeException;\n        try\n        {\n            _enforceValidTZFile(readVal!(char[])(tzFile, 4) == \"TZif\");\n\n            immutable char tzFileVersion = readVal!char(tzFile);\n            _enforceValidTZFile(tzFileVersion == '\\0' || tzFileVersion == '2' || tzFileVersion == '3');\n\n            {\n                auto zeroBlock = readVal!(ubyte[])(tzFile, 15);\n                bool allZeroes = true;\n\n                foreach (val; zeroBlock)\n                {\n                    if (val != 0)\n                    {\n                        allZeroes = false;\n                        break;\n                    }\n                }\n\n                _enforceValidTZFile(allZeroes);\n            }\n\n\n            // The number of UTC/local indicators stored in the file.\n            auto tzh_ttisgmtcnt = readVal!int(tzFile);\n\n            // The number of standard/wall indicators stored in the file.\n            auto tzh_ttisstdcnt = readVal!int(tzFile);\n\n            // The number of leap seconds for which data is stored in the file.\n            auto tzh_leapcnt = readVal!int(tzFile);\n\n            // The number of \"transition times\" for which data is stored in the file.\n            auto tzh_timecnt = readVal!int(tzFile);\n\n            // The number of \"local time types\" for which data is stored in the file (must not be zero).\n            auto tzh_typecnt = readVal!int(tzFile);\n            _enforceValidTZFile(tzh_typecnt != 0);\n\n            // The number of characters of \"timezone abbreviation strings\" stored in the file.\n            auto tzh_charcnt = readVal!int(tzFile);\n\n            // time_ts where DST transitions occur.\n            auto transitionTimeTs = new long[](tzh_timecnt);\n            foreach (ref transition; transitionTimeTs)\n                transition = readVal!int(tzFile);\n\n            // Indices into ttinfo structs indicating the changes\n            // to be made at the corresponding DST transition.\n            auto ttInfoIndices = new ubyte[](tzh_timecnt);\n            foreach (ref ttInfoIndex; ttInfoIndices)\n                ttInfoIndex = readVal!ubyte(tzFile);\n\n            // ttinfos which give info on DST transitions.\n            auto tempTTInfos = new TempTTInfo[](tzh_typecnt);\n            foreach (ref ttInfo; tempTTInfos)\n                ttInfo = readVal!TempTTInfo(tzFile);\n\n            // The array of time zone abbreviation characters.\n            auto tzAbbrevChars = readVal!(char[])(tzFile, tzh_charcnt);\n\n            auto leapSeconds = new LeapSecond[](tzh_leapcnt);\n            foreach (ref leapSecond; leapSeconds)\n            {\n                // The time_t when the leap second occurs.\n                auto timeT = readVal!int(tzFile);\n\n                // The total number of leap seconds to be applied after\n                // the corresponding leap second.\n                auto total = readVal!int(tzFile);\n\n                leapSecond = LeapSecond(timeT, total);\n            }\n\n            // Indicate whether each corresponding DST transition were specified\n            // in standard time or wall clock time.\n            auto transitionIsStd = new bool[](tzh_ttisstdcnt);\n            foreach (ref isStd; transitionIsStd)\n                isStd = readVal!bool(tzFile);\n\n            // Indicate whether each corresponding DST transition associated with\n            // local time types are specified in UTC or local time.\n            auto transitionInUTC = new bool[](tzh_ttisgmtcnt);\n            foreach (ref inUTC; transitionInUTC)\n                inUTC = readVal!bool(tzFile);\n\n            _enforceValidTZFile(!tzFile.eof);\n\n            // If version 2 or 3, the information is duplicated in 64-bit.\n            if (tzFileVersion == '2' || tzFileVersion == '3')\n            {\n                _enforceValidTZFile(readVal!(char[])(tzFile, 4) == \"TZif\");\n\n                immutable char tzFileVersion2 = readVal!(char)(tzFile);\n                _enforceValidTZFile(tzFileVersion2 == '2' || tzFileVersion2 == '3');\n\n                {\n                    auto zeroBlock = readVal!(ubyte[])(tzFile, 15);\n                    bool allZeroes = true;\n\n                    foreach (val; zeroBlock)\n                    {\n                        if (val != 0)\n                        {\n                            allZeroes = false;\n                            break;\n                        }\n                    }\n\n                    _enforceValidTZFile(allZeroes);\n                }\n\n\n                // The number of UTC/local indicators stored in the file.\n                tzh_ttisgmtcnt = readVal!int(tzFile);\n\n                // The number of standard/wall indicators stored in the file.\n                tzh_ttisstdcnt = readVal!int(tzFile);\n\n                // The number of leap seconds for which data is stored in the file.\n                tzh_leapcnt = readVal!int(tzFile);\n\n                // The number of \"transition times\" for which data is stored in the file.\n                tzh_timecnt = readVal!int(tzFile);\n\n                // The number of \"local time types\" for which data is stored in the file (must not be zero).\n                tzh_typecnt = readVal!int(tzFile);\n                _enforceValidTZFile(tzh_typecnt != 0);\n\n                // The number of characters of \"timezone abbreviation strings\" stored in the file.\n                tzh_charcnt = readVal!int(tzFile);\n\n                // time_ts where DST transitions occur.\n                transitionTimeTs = new long[](tzh_timecnt);\n                foreach (ref transition; transitionTimeTs)\n                    transition = readVal!long(tzFile);\n\n                // Indices into ttinfo structs indicating the changes\n                // to be made at the corresponding DST transition.\n                ttInfoIndices = new ubyte[](tzh_timecnt);\n                foreach (ref ttInfoIndex; ttInfoIndices)\n                    ttInfoIndex = readVal!ubyte(tzFile);\n\n                // ttinfos which give info on DST transitions.\n                tempTTInfos = new TempTTInfo[](tzh_typecnt);\n                foreach (ref ttInfo; tempTTInfos)\n                    ttInfo = readVal!TempTTInfo(tzFile);\n\n                // The array of time zone abbreviation characters.\n                tzAbbrevChars = readVal!(char[])(tzFile, tzh_charcnt);\n\n                leapSeconds = new LeapSecond[](tzh_leapcnt);\n                foreach (ref leapSecond; leapSeconds)\n                {\n                    // The time_t when the leap second occurs.\n                    auto timeT = readVal!long(tzFile);\n\n                    // The total number of leap seconds to be applied after\n                    // the corresponding leap second.\n                    auto total = readVal!int(tzFile);\n\n                    leapSecond = LeapSecond(timeT, total);\n                }\n\n                // Indicate whether each corresponding DST transition were specified\n                // in standard time or wall clock time.\n                transitionIsStd = new bool[](tzh_ttisstdcnt);\n                foreach (ref isStd; transitionIsStd)\n                    isStd = readVal!bool(tzFile);\n\n                // Indicate whether each corresponding DST transition associated with\n                // local time types are specified in UTC or local time.\n                transitionInUTC = new bool[](tzh_ttisgmtcnt);\n                foreach (ref inUTC; transitionInUTC)\n                    inUTC = readVal!bool(tzFile);\n            }\n\n            _enforceValidTZFile(tzFile.readln().strip().empty);\n\n            cast(void) tzFile.readln();\n\n            version (Android)\n            {\n                // Android uses a single file for all timezone data, so the file\n                // doesn't end here.\n            }\n            else\n            {\n                _enforceValidTZFile(tzFile.readln().strip().empty);\n                _enforceValidTZFile(tzFile.eof);\n            }\n\n\n            auto transitionTypes = new TransitionType*[](tempTTInfos.length);\n\n            foreach (i, ref ttype; transitionTypes)\n            {\n                bool isStd = false;\n\n                if (i < transitionIsStd.length && !transitionIsStd.empty)\n                    isStd = transitionIsStd[i];\n\n                bool inUTC = false;\n\n                if (i < transitionInUTC.length && !transitionInUTC.empty)\n                    inUTC = transitionInUTC[i];\n\n                ttype = new TransitionType(isStd, inUTC);\n            }\n\n            auto ttInfos = new immutable(TTInfo)*[](tempTTInfos.length);\n            foreach (i, ref ttInfo; ttInfos)\n            {\n                auto tempTTInfo = tempTTInfos[i];\n\n                if (gmtZone)\n                    tempTTInfo.tt_gmtoff = -tempTTInfo.tt_gmtoff;\n\n                auto abbrevChars = tzAbbrevChars[tempTTInfo.tt_abbrind .. $];\n                string abbrev = abbrevChars[0 .. abbrevChars.countUntil('\\0')].idup;\n\n                ttInfo = new immutable(TTInfo)(tempTTInfos[i], abbrev);\n            }\n\n            auto tempTransitions = new TempTransition[](transitionTimeTs.length);\n            foreach (i, ref tempTransition; tempTransitions)\n            {\n                immutable ttiIndex = ttInfoIndices[i];\n                auto transitionTimeT = transitionTimeTs[i];\n                auto ttype = transitionTypes[ttiIndex];\n                auto ttInfo = ttInfos[ttiIndex];\n\n                tempTransition = TempTransition(transitionTimeT, ttInfo, ttype);\n            }\n\n            if (tempTransitions.empty)\n            {\n                _enforceValidTZFile(ttInfos.length == 1 && transitionTypes.length == 1);\n                tempTransitions ~= TempTransition(0, ttInfos[0], transitionTypes[0]);\n            }\n\n            sort!\"a.timeT < b.timeT\"(tempTransitions);\n            sort!\"a.timeT < b.timeT\"(leapSeconds);\n\n            auto transitions = new Transition[](tempTransitions.length);\n            foreach (i, ref transition; transitions)\n            {\n                auto tempTransition = tempTransitions[i];\n                auto transitionTimeT = tempTransition.timeT;\n                auto ttInfo = tempTransition.ttInfo;\n\n                _enforceValidTZFile(i == 0 || transitionTimeT > tempTransitions[i - 1].timeT);\n\n                transition = Transition(transitionTimeT, ttInfo);\n            }\n\n            string stdName;\n            string dstName;\n            bool hasDST = false;\n\n            foreach (transition; retro(transitions))\n            {\n                auto ttInfo = transition.ttInfo;\n\n                if (ttInfo.isDST)\n                {\n                    if (dstName.empty)\n                        dstName = ttInfo.abbrev;\n                    hasDST = true;\n                }\n                else\n                {\n                    if (stdName.empty)\n                        stdName = ttInfo.abbrev;\n                }\n\n                if (!stdName.empty && !dstName.empty)\n                    break;\n            }\n\n            return new immutable PosixTimeZone(transitions.idup, leapSeconds.idup, name, stdName, dstName, hasDST);\n        }\n        catch (DateTimeException dte)\n            throw dte;\n        catch (Exception e)\n            throw new DateTimeException(\"Not a valid TZ data file\", __FILE__, __LINE__, e);\n    }\n\n    ///\n    @safe unittest\n    {\n        version (Posix)\n        {\n            auto tz = PosixTimeZone.getTimeZone(\"America/Los_Angeles\");\n\n            assert(tz.name == \"America/Los_Angeles\");\n            assert(tz.stdName == \"PST\");\n            assert(tz.dstName == \"PDT\");\n        }\n    }\n\n    /++\n        Returns a list of the names of the time zones installed on the system.\n\n        Providing a sub-name narrows down the list of time zones (which\n        can number in the thousands). For example,\n        passing in \"America\" as the sub-name returns only the time zones which\n        begin with \"America\".\n\n        Params:\n            subName       = The first part of the desired time zones.\n            tzDatabaseDir = The directory where the TZ Database files are\n                            located.\n\n        Throws:\n            `FileException` if it fails to read from disk.\n      +/\n    static string[] getInstalledTZNames(string subName = \"\", string tzDatabaseDir = defaultTZDatabaseDir) @trusted\n    {\n        import std.algorithm.sorting : sort;\n        import std.array : appender;\n        import std.exception : enforce;\n        import std.format : format;\n\n        version (Posix)\n            subName = strip(subName);\n        else version (Windows)\n        {\n            import std.array : replace;\n            import std.path : dirSeparator;\n            subName = replace(strip(subName), \"/\", dirSeparator);\n        }\n\n        import std.datetime.date : DateTimeException;\n        enforce(tzDatabaseDir.exists(), new DateTimeException(format(\"Directory %s does not exist.\", tzDatabaseDir)));\n        enforce(tzDatabaseDir.isDir, new DateTimeException(format(\"%s is not a directory.\", tzDatabaseDir)));\n\n        auto timezones = appender!(string[])();\n\n        version (Android)\n        {\n            import std.algorithm.iteration : filter;\n            import std.algorithm.mutation : copy;\n            tzdataIndex(tzDatabaseDir).byKey.filter!(a => a.startsWith(subName)).copy(timezones);\n        }\n        else\n        {\n            import std.path : baseName;\n            foreach (DirEntry de; dirEntries(tzDatabaseDir, SpanMode.depth))\n            {\n                if (de.isFile)\n                {\n                    auto tzName = de.name[tzDatabaseDir.length .. $];\n\n                    if (!tzName.extension().empty ||\n                        !tzName.startsWith(subName) ||\n                        baseName(tzName) == \"leapseconds\" ||\n                        tzName == \"+VERSION\")\n                    {\n                        continue;\n                    }\n\n                    timezones.put(tzName);\n                }\n            }\n        }\n\n        sort(timezones.data);\n\n        return timezones.data;\n    }\n\n    version (Posix) @system unittest\n    {\n        import std.exception : assertNotThrown;\n        import std.stdio : writefln;\n        static void testPTZSuccess(string tzName)\n        {\n            scope(failure) writefln(\"TZName which threw: %s\", tzName);\n\n            PosixTimeZone.getTimeZone(tzName);\n        }\n\n        static void testPTZFailure(string tzName)\n        {\n            scope(success) writefln(\"TZName which was supposed to throw: %s\", tzName);\n\n            PosixTimeZone.getTimeZone(tzName);\n        }\n\n        auto tzNames = getInstalledTZNames();\n\n        import std.datetime.date : DateTimeException;\n        foreach (tzName; tzNames)\n            assertNotThrown!DateTimeException(testPTZSuccess(tzName));\n\n        // No timezone directories on Android, just a single tzdata file\n        version (Android)\n        {}\n        else\n        {\n            foreach (DirEntry de; dirEntries(defaultTZDatabaseDir, SpanMode.depth))\n            {\n                if (de.isFile)\n                {\n                    auto tzName = de.name[defaultTZDatabaseDir.length .. $];\n\n                    if (!canFind(tzNames, tzName))\n                        assertThrown!DateTimeException(testPTZFailure(tzName));\n                }\n            }\n        }\n    }\n\n\nprivate:\n\n    /+\n        Holds information on when a time transition occures (usually a\n        transition to or from DST) as well as a pointer to the `TTInfo` which\n        holds information on the utc offset past the transition.\n      +/\n    struct Transition\n    {\n        this(long timeT, immutable (TTInfo)* ttInfo) @safe pure\n        {\n            this.timeT = timeT;\n            this.ttInfo = ttInfo;\n        }\n\n        long    timeT;\n        immutable (TTInfo)* ttInfo;\n    }\n\n\n    /+\n        Holds information on when a leap second occurs.\n      +/\n    struct LeapSecond\n    {\n        this(long timeT, int total) @safe pure\n        {\n            this.timeT = timeT;\n            this.total = total;\n        }\n\n        long timeT;\n        int total;\n    }\n\n    /+\n        Holds information on the utc offset after a transition as well as\n        whether DST is in effect after that transition.\n      +/\n    struct TTInfo\n    {\n        this(scope const TempTTInfo tempTTInfo, string abbrev) @safe immutable pure\n        {\n            utcOffset = tempTTInfo.tt_gmtoff;\n            isDST = tempTTInfo.tt_isdst;\n            this.abbrev = abbrev;\n        }\n\n        immutable int    utcOffset;  // Offset from UTC.\n        immutable bool   isDST;      // Whether DST is in effect.\n        immutable string abbrev;     // The current abbreviation for the time zone.\n    }\n\n\n    /+\n        Struct used to hold information relating to `TTInfo` while organizing\n        the time zone information prior to putting it in its final form.\n      +/\n    struct TempTTInfo\n    {\n        this(int gmtOff, bool isDST, ubyte abbrInd) @safe pure\n        {\n            tt_gmtoff = gmtOff;\n            tt_isdst = isDST;\n            tt_abbrind = abbrInd;\n        }\n\n        int   tt_gmtoff;\n        bool  tt_isdst;\n        ubyte tt_abbrind;\n    }\n\n\n    /+\n        Struct used to hold information relating to `Transition` while\n        organizing the time zone information prior to putting it in its final\n        form.\n      +/\n    struct TempTransition\n    {\n        this(long timeT, immutable (TTInfo)* ttInfo, TransitionType* ttype) @safe pure\n        {\n            this.timeT = timeT;\n            this.ttInfo = ttInfo;\n            this.ttype = ttype;\n        }\n\n        long                timeT;\n        immutable (TTInfo)* ttInfo;\n        TransitionType*     ttype;\n    }\n\n\n    /+\n        Struct used to hold information relating to `Transition` and\n        `TTInfo` while organizing the time zone information prior to putting\n        it in its final form.\n      +/\n    struct TransitionType\n    {\n        this(bool isStd, bool inUTC) @safe pure\n        {\n            this.isStd = isStd;\n            this.inUTC = inUTC;\n        }\n\n        // Whether the transition is in std time (as opposed to wall clock time).\n        bool isStd;\n\n        // Whether the transition is in UTC (as opposed to local time).\n        bool inUTC;\n    }\n\n\n    /+\n        Reads an int from a TZ file.\n      +/\n    static T readVal(T)(ref File tzFile) @trusted\n        if ((isIntegral!T || isSomeChar!T) || is(Unqual!T == bool))\n    {\n        import std.bitmanip : bigEndianToNative;\n        T[1] buff;\n\n        _enforceValidTZFile(!tzFile.eof);\n        tzFile.rawRead(buff);\n\n        return bigEndianToNative!T(cast(ubyte[T.sizeof]) buff);\n    }\n\n    /+\n        Reads an array of values from a TZ file.\n      +/\n    static T readVal(T)(ref File tzFile, size_t length) @trusted\n        if (isArray!T)\n    {\n        auto buff = new T(length);\n\n        _enforceValidTZFile(!tzFile.eof);\n        tzFile.rawRead(buff);\n\n        return buff;\n    }\n\n\n    /+\n        Reads a `TempTTInfo` from a TZ file.\n      +/\n    static T readVal(T)(ref File tzFile) @safe\n        if (is(T == TempTTInfo))\n    {\n        return TempTTInfo(readVal!int(tzFile),\n                          readVal!bool(tzFile),\n                          readVal!ubyte(tzFile));\n    }\n\n\n    /+\n        Throws:\n            $(REF DateTimeException,std,datetime,date) if `result` is false.\n      +/\n    static void _enforceValidTZFile(bool result, size_t line = __LINE__) @safe pure\n    {\n        import std.datetime.date : DateTimeException;\n        if (!result)\n            throw new DateTimeException(\"Not a valid tzdata file.\", __FILE__, line);\n    }\n\n\n    int calculateLeapSeconds(long stdTime) @safe const pure nothrow\n    {\n        if (_leapSeconds.empty)\n            return 0;\n\n        immutable unixTime = stdTimeToUnixTime(stdTime);\n\n        if (_leapSeconds.front.timeT >= unixTime)\n            return 0;\n\n        immutable found = countUntil!\"b < a.timeT\"(_leapSeconds, unixTime);\n\n        if (found == -1)\n            return _leapSeconds.back.total;\n\n        immutable leapSecond = found == 0 ? _leapSeconds[0] : _leapSeconds[found - 1];\n\n        return leapSecond.total;\n    }\n\n\n    this(immutable Transition[] transitions,\n         immutable LeapSecond[] leapSeconds,\n         string name,\n         string stdName,\n         string dstName,\n         bool hasDST) @safe immutable pure\n    {\n        if (dstName.empty && !stdName.empty)\n            dstName = stdName;\n        else if (stdName.empty && !dstName.empty)\n            stdName = dstName;\n\n        super(name, stdName, dstName);\n\n        if (!transitions.empty)\n        {\n            foreach (i, transition; transitions[0 .. $-1])\n                _enforceValidTZFile(transition.timeT < transitions[i + 1].timeT);\n        }\n\n        foreach (i, leapSecond; leapSeconds)\n            _enforceValidTZFile(i == leapSeconds.length - 1 || leapSecond.timeT < leapSeconds[i + 1].timeT);\n\n        _transitions = transitions;\n        _leapSeconds = leapSeconds;\n        _hasDST = hasDST;\n    }\n\n    // Android concatenates the usual timezone directories into a single file,\n    // tzdata, along with an index to jump to each timezone's offset.  In older\n    // versions of Android, the index was stored in a separate file, zoneinfo.idx,\n    // whereas now it's stored at the beginning of tzdata.\n    version (Android)\n    {\n        // Keep track of whether there's a separate index, zoneinfo.idx.  Only\n        // check this after calling tzdataIndex, as it's initialized there.\n        static shared bool separate_index;\n\n        // Extracts the name of each time zone and the offset where its data is\n        // located in the tzdata file from the index and caches it for later.\n        static const(uint[string]) tzdataIndex(string tzDir)\n        {\n            import std.concurrency : initOnce;\n\n            __gshared uint[string] _tzIndex;\n\n            // _tzIndex is initialized once and then shared across all threads.\n            initOnce!_tzIndex(\n            {\n                import std.conv : to;\n                import std.format : format;\n                import std.path : asNormalizedPath, chainPath;\n\n                enum indexEntrySize = 52;\n                const combinedFile = asNormalizedPath(chainPath(tzDir, \"tzdata\")).to!string;\n                const indexFile = asNormalizedPath(chainPath(tzDir, \"zoneinfo.idx\")).to!string;\n                File tzFile;\n                uint indexEntries, dataOffset;\n                uint[string] initIndex;\n\n                // Check for the combined file tzdata, which stores the index\n                // and the time zone data together.\n                if (combinedFile.exists() && combinedFile.isFile)\n                {\n                    tzFile = File(combinedFile);\n                    _enforceValidTZFile(readVal!(char[])(tzFile, 6) == \"tzdata\");\n                    auto tzDataVersion = readVal!(char[])(tzFile, 6);\n                    _enforceValidTZFile(tzDataVersion[5] == '\\0');\n\n                    uint indexOffset = readVal!uint(tzFile);\n                    dataOffset = readVal!uint(tzFile);\n                    readVal!uint(tzFile);\n\n                    indexEntries = (dataOffset - indexOffset) / indexEntrySize;\n                    separate_index = false;\n                }\n                else if (indexFile.exists() && indexFile.isFile)\n                {\n                    tzFile = File(indexFile);\n                    indexEntries = to!uint(tzFile.size/indexEntrySize);\n                    separate_index = true;\n                }\n                else\n                {\n                    throw new DateTimeException(format(\"Both timezone files %s and %s do not exist.\",\n                                                       combinedFile, indexFile));\n                }\n\n                foreach (_; 0 .. indexEntries)\n                {\n                    string tzName = to!string(readVal!(char[])(tzFile, 40).ptr);\n                    uint tzOffset = readVal!uint(tzFile);\n                    readVal!(uint[])(tzFile, 2);\n                    initIndex[tzName] = dataOffset + tzOffset;\n                }\n                initIndex.rehash;\n                return initIndex;\n            }());\n            return _tzIndex;\n        }\n    }\n\n    // List of times when the utc offset changes.\n    immutable Transition[] _transitions;\n\n    // List of leap second occurrences.\n    immutable LeapSecond[] _leapSeconds;\n\n    // Whether DST is in effect for this time zone at any point in time.\n    immutable bool _hasDST;\n}\n\n\nversion (StdDdoc)\n{\n    /++\n        $(BLUE This class is Windows-Only.)\n\n        Represents a time zone from the Windows registry. Unfortunately, Windows\n        does not use the TZ Database. To use the TZ Database, use\n        $(LREF PosixTimeZone) (which reads its information from the TZ Database\n        files on disk) on Windows by providing the TZ Database files and telling\n        `PosixTimeZone.getTimeZone` where the directory holding them is.\n\n        The TZ Database files and Windows' time zone information frequently\n        do not match. Windows has many errors with regards to when DST switches\n        occur (especially for historical dates). Also, the TZ Database files\n        include far more time zones than Windows does. So, for accurate\n        time zone information, use the TZ Database files with\n        $(LREF PosixTimeZone) rather than `WindowsTimeZone`. However, because\n        `WindowsTimeZone` uses Windows system calls to deal with the time,\n        it's far more likely to match the behavior of other Windows programs.\n        Be aware of the differences when selecting a method.\n\n        `WindowsTimeZone` does not exist on Posix systems.\n\n        To get a `WindowsTimeZone`, call `WindowsTimeZone.getTimeZone`.\n\n        See_Also:\n            $(HTTP www.iana.org/time-zones, Home of the TZ Database files)\n      +/\n    final class WindowsTimeZone : TimeZone\n    {\n    public:\n\n        /++\n            Whether this time zone has Daylight Savings Time at any point in\n            time. Note that for some time zone types it may not have DST for\n            current dates but will still return true for `hasDST` because the\n            time zone did at some point have DST.\n          +/\n        @property override bool hasDST() @safe const nothrow;\n\n\n        /++\n            Takes the number of hnsecs (100 ns) since midnight, January 1st,\n            1 A.D. in UTC time (i.e. std time) and returns whether DST is in\n            effect in this time zone at the given point in time.\n\n            Params:\n                stdTime = The UTC time that needs to be checked for DST in this\n                          time zone.\n          +/\n        override bool dstInEffect(long stdTime) @safe const nothrow;\n\n\n        /++\n            Takes the number of hnsecs (100 ns) since midnight, January 1st,\n            1 A.D. in UTC time (i.e. std time) and converts it to this time\n                zone's time.\n\n            Params:\n                stdTime = The UTC time that needs to be adjusted to this time\n                          zone's time.\n          +/\n        override long utcToTZ(long stdTime) @safe const nothrow;\n\n\n        /++\n            Takes the number of hnsecs (100 ns) since midnight, January 1st,\n            1 A.D. in this time zone's time and converts it to UTC (i.e. std\n            time).\n\n            Params:\n                adjTime = The time in this time zone that needs to be adjusted\n                          to UTC time.\n          +/\n        override long tzToUTC(long adjTime) @safe const nothrow;\n\n\n        /++\n            Returns a $(LREF TimeZone) with the given name per the Windows time\n            zone names. The time zone information is fetched from the Windows\n            registry.\n\n            See_Also:\n                $(HTTP en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ\n                  Database)<br>\n                $(HTTP en.wikipedia.org/wiki/List_of_tz_database_time_zones, List\n                  of Time Zones)\n\n            Params:\n                name = The TZ Database name of the desired time zone.\n\n            Throws:\n                $(REF DateTimeException,std,datetime,date) if the given time\n                zone could not be found.\n\n            Example:\n    --------------------\n    auto tz = WindowsTimeZone.getTimeZone(\"Pacific Standard Time\");\n    --------------------\n          +/\n        static immutable(WindowsTimeZone) getTimeZone(string name) @safe;\n\n\n        /++\n            Returns a list of the names of the time zones installed on the\n            system. The list returned by WindowsTimeZone contains the Windows\n            TZ names, not the TZ Database names. However,\n            `TimeZone.getinstalledTZNames` will return the TZ Database names\n            which are equivalent to the Windows TZ names.\n          +/\n        static string[] getInstalledTZNames() @safe;\n\n    private:\n\n        version (Windows)\n        {}\n        else\n            alias TIME_ZONE_INFORMATION = void*;\n\n        static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) nothrow;\n        static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) nothrow;\n        static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) nothrow;\n\n        this() immutable pure\n        {\n            super(\"\", \"\", \"\");\n        }\n    }\n\n}\nelse version (Windows)\n{\n    final class WindowsTimeZone : TimeZone\n    {\n        import std.algorithm.sorting : sort;\n        import std.array : appender;\n        import std.conv : to;\n        import std.format : format;\n\n    public:\n\n        @property override bool hasDST() @safe const nothrow\n        {\n            return _tzInfo.DaylightDate.wMonth != 0;\n        }\n\n\n        override bool dstInEffect(long stdTime) @safe const nothrow\n        {\n            return _dstInEffect(&_tzInfo, stdTime);\n        }\n\n\n        override long utcToTZ(long stdTime) @safe const nothrow\n        {\n            return _utcToTZ(&_tzInfo, stdTime, hasDST);\n        }\n\n\n        override long tzToUTC(long adjTime) @safe const nothrow\n        {\n            return _tzToUTC(&_tzInfo, adjTime, hasDST);\n        }\n\n\n        static immutable(WindowsTimeZone) getTimeZone(string name) @trusted\n        {\n            scope baseKey = Registry.localMachine.getKey(`Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones`);\n\n            foreach (tzKeyName; baseKey.keyNames)\n            {\n                if (tzKeyName != name)\n                    continue;\n\n                scope tzKey = baseKey.getKey(tzKeyName);\n\n                scope stdVal = tzKey.getValue(\"Std\");\n                auto stdName = stdVal.value_SZ;\n\n                scope dstVal = tzKey.getValue(\"Dlt\");\n                auto dstName = dstVal.value_SZ;\n\n                scope tziVal = tzKey.getValue(\"TZI\");\n                auto binVal = tziVal.value_BINARY;\n                assert(binVal.length == REG_TZI_FORMAT.sizeof);\n                auto tziFmt = cast(REG_TZI_FORMAT*) binVal.ptr;\n\n                TIME_ZONE_INFORMATION tzInfo;\n\n                auto wstdName = stdName.to!wstring;\n                auto wdstName = dstName.to!wstring;\n                auto wstdNameLen = wstdName.length > 32 ? 32 : wstdName.length;\n                auto wdstNameLen = wdstName.length > 32 ? 32 : wdstName.length;\n\n                tzInfo.Bias = tziFmt.Bias;\n                tzInfo.StandardName[0 .. wstdNameLen] = wstdName[0 .. wstdNameLen];\n                tzInfo.StandardName[wstdNameLen .. $] = '\\0';\n                tzInfo.StandardDate = tziFmt.StandardDate;\n                tzInfo.StandardBias = tziFmt.StandardBias;\n                tzInfo.DaylightName[0 .. wdstNameLen] = wdstName[0 .. wdstNameLen];\n                tzInfo.DaylightName[wdstNameLen .. $] = '\\0';\n                tzInfo.DaylightDate = tziFmt.DaylightDate;\n                tzInfo.DaylightBias = tziFmt.DaylightBias;\n\n                return new immutable WindowsTimeZone(name, tzInfo);\n            }\n            import std.datetime.date : DateTimeException;\n            throw new DateTimeException(format(\"Failed to find time zone: %s\", name));\n        }\n\n        static string[] getInstalledTZNames() @trusted\n        {\n            auto timezones = appender!(string[])();\n\n            scope baseKey = Registry.localMachine.getKey(`Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones`);\n\n            foreach (tzKeyName; baseKey.keyNames)\n                timezones.put(tzKeyName);\n            sort(timezones.data);\n\n            return timezones.data;\n        }\n\n        @safe unittest\n        {\n            import std.exception : assertNotThrown;\n            import std.stdio : writefln;\n            static void testWTZSuccess(string tzName)\n            {\n                scope(failure) writefln(\"TZName which threw: %s\", tzName);\n\n                WindowsTimeZone.getTimeZone(tzName);\n            }\n\n            auto tzNames = getInstalledTZNames();\n\n            import std.datetime.date : DateTimeException;\n            foreach (tzName; tzNames)\n                assertNotThrown!DateTimeException(testWTZSuccess(tzName));\n        }\n\n\n    private:\n\n        static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) @trusted nothrow\n        {\n            try\n            {\n                if (tzInfo.DaylightDate.wMonth == 0)\n                    return false;\n\n                import std.datetime.date : DateTime, Month;\n                auto utcDateTime = cast(DateTime) SysTime(stdTime, UTC());\n\n                //The limits of what SystemTimeToTzSpecificLocalTime will accept.\n                if (utcDateTime.year < 1601)\n                {\n                    import std.datetime.date : Month;\n                    if (utcDateTime.month == Month.feb && utcDateTime.day == 29)\n                        utcDateTime.day = 28;\n                    utcDateTime.year = 1601;\n                }\n                else if (utcDateTime.year > 30_827)\n                {\n                    if (utcDateTime.month == Month.feb && utcDateTime.day == 29)\n                        utcDateTime.day = 28;\n                    utcDateTime.year = 30_827;\n                }\n\n                //SystemTimeToTzSpecificLocalTime doesn't act correctly at the\n                //beginning or end of the year (bleh). Unless some bizarre time\n                //zone changes DST on January 1st or December 31st, this should\n                //fix the problem.\n                if (utcDateTime.month == Month.jan)\n                {\n                    if (utcDateTime.day == 1)\n                        utcDateTime.day = 2;\n                }\n                else if (utcDateTime.month == Month.dec && utcDateTime.day == 31)\n                    utcDateTime.day = 30;\n\n                SYSTEMTIME utcTime = void;\n                SYSTEMTIME otherTime = void;\n\n                utcTime.wYear = utcDateTime.year;\n                utcTime.wMonth = utcDateTime.month;\n                utcTime.wDay = utcDateTime.day;\n                utcTime.wHour = utcDateTime.hour;\n                utcTime.wMinute = utcDateTime.minute;\n                utcTime.wSecond = utcDateTime.second;\n                utcTime.wMilliseconds = 0;\n\n                immutable result = SystemTimeToTzSpecificLocalTime(cast(TIME_ZONE_INFORMATION*) tzInfo,\n                                                                   &utcTime,\n                                                                   &otherTime);\n                assert(result);\n\n                immutable otherDateTime = DateTime(otherTime.wYear,\n                                                   otherTime.wMonth,\n                                                   otherTime.wDay,\n                                                   otherTime.wHour,\n                                                   otherTime.wMinute,\n                                                   otherTime.wSecond);\n                immutable diff = utcDateTime - otherDateTime;\n                immutable minutes = diff.total!\"minutes\" - tzInfo.Bias;\n\n                if (minutes == tzInfo.DaylightBias)\n                    return true;\n\n                assert(minutes == tzInfo.StandardBias);\n\n                return false;\n            }\n            catch (Exception e)\n                assert(0, \"DateTime's constructor threw.\");\n        }\n\n        @system unittest\n        {\n            TIME_ZONE_INFORMATION tzInfo;\n            GetTimeZoneInformation(&tzInfo);\n\n            import std.datetime.date : DateTime;\n            foreach (year; [1600, 1601, 30_827, 30_828])\n                WindowsTimeZone._dstInEffect(&tzInfo, SysTime(DateTime(year, 1, 1)).stdTime);\n        }\n\n\n        static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) @safe nothrow\n        {\n            if (hasDST && WindowsTimeZone._dstInEffect(tzInfo, stdTime))\n                return stdTime - convert!(\"minutes\", \"hnsecs\")(tzInfo.Bias + tzInfo.DaylightBias);\n\n            return stdTime - convert!(\"minutes\", \"hnsecs\")(tzInfo.Bias + tzInfo.StandardBias);\n        }\n\n\n        static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) @trusted nothrow\n        {\n            if (hasDST)\n            {\n                try\n                {\n                    import std.datetime.date : DateTime, Month;\n                    bool dstInEffectForLocalDateTime(DateTime localDateTime)\n                    {\n                        // The limits of what SystemTimeToTzSpecificLocalTime will accept.\n                        if (localDateTime.year < 1601)\n                        {\n                            if (localDateTime.month == Month.feb && localDateTime.day == 29)\n                                localDateTime.day = 28;\n\n                            localDateTime.year = 1601;\n                        }\n                        else if (localDateTime.year > 30_827)\n                        {\n                            if (localDateTime.month == Month.feb && localDateTime.day == 29)\n                                localDateTime.day = 28;\n\n                            localDateTime.year = 30_827;\n                        }\n\n                        // SystemTimeToTzSpecificLocalTime doesn't act correctly at the\n                        // beginning or end of the year (bleh). Unless some bizarre time\n                        // zone changes DST on January 1st or December 31st, this should\n                        // fix the problem.\n                        if (localDateTime.month == Month.jan)\n                        {\n                            if (localDateTime.day == 1)\n                                localDateTime.day = 2;\n                        }\n                        else if (localDateTime.month == Month.dec && localDateTime.day == 31)\n                            localDateTime.day = 30;\n\n                        SYSTEMTIME utcTime = void;\n                        SYSTEMTIME localTime = void;\n\n                        localTime.wYear = localDateTime.year;\n                        localTime.wMonth = localDateTime.month;\n                        localTime.wDay = localDateTime.day;\n                        localTime.wHour = localDateTime.hour;\n                        localTime.wMinute = localDateTime.minute;\n                        localTime.wSecond = localDateTime.second;\n                        localTime.wMilliseconds = 0;\n\n                        immutable result = TzSpecificLocalTimeToSystemTime(cast(TIME_ZONE_INFORMATION*) tzInfo,\n                                                                           &localTime,\n                                                                           &utcTime);\n                        assert(result);\n\n                        immutable utcDateTime = DateTime(utcTime.wYear,\n                                                         utcTime.wMonth,\n                                                         utcTime.wDay,\n                                                         utcTime.wHour,\n                                                         utcTime.wMinute,\n                                                         utcTime.wSecond);\n\n                        immutable diff = localDateTime - utcDateTime;\n                        immutable minutes = -tzInfo.Bias - diff.total!\"minutes\";\n\n                        if (minutes == tzInfo.DaylightBias)\n                            return true;\n\n                        assert(minutes == tzInfo.StandardBias);\n\n                        return false;\n                    }\n\n                    import std.datetime.date : DateTime;\n                    auto localDateTime = cast(DateTime) SysTime(adjTime, UTC());\n                    auto localDateTimeBefore = localDateTime - dur!\"hours\"(1);\n                    auto localDateTimeAfter = localDateTime + dur!\"hours\"(1);\n\n                    auto dstInEffectNow = dstInEffectForLocalDateTime(localDateTime);\n                    auto dstInEffectBefore = dstInEffectForLocalDateTime(localDateTimeBefore);\n                    auto dstInEffectAfter = dstInEffectForLocalDateTime(localDateTimeAfter);\n\n                    bool isDST;\n\n                    if (dstInEffectBefore && dstInEffectNow && dstInEffectAfter)\n                        isDST = true;\n                    else if (!dstInEffectBefore && !dstInEffectNow && !dstInEffectAfter)\n                        isDST = false;\n                    else if (!dstInEffectBefore && dstInEffectAfter)\n                        isDST = false;\n                    else if (dstInEffectBefore && !dstInEffectAfter)\n                        isDST = dstInEffectNow;\n                    else\n                        assert(0, \"Bad Logic.\");\n\n                    if (isDST)\n                        return adjTime + convert!(\"minutes\", \"hnsecs\")(tzInfo.Bias + tzInfo.DaylightBias);\n                }\n                catch (Exception e)\n                    assert(0, \"SysTime's constructor threw.\");\n            }\n\n            return adjTime + convert!(\"minutes\", \"hnsecs\")(tzInfo.Bias + tzInfo.StandardBias);\n        }\n\n\n        this(string name, TIME_ZONE_INFORMATION tzInfo) @trusted immutable pure\n        {\n            super(name, to!string(tzInfo.StandardName.ptr), to!string(tzInfo.DaylightName.ptr));\n            _tzInfo = tzInfo;\n        }\n\n\n        TIME_ZONE_INFORMATION _tzInfo;\n    }\n}\n\n\nversion (StdDdoc)\n{\n    /++\n        $(BLUE This function is Posix-Only.)\n\n        Sets the local time zone on Posix systems with the TZ\n        Database name by setting the TZ environment variable.\n\n        Unfortunately, there is no way to do it on Windows using the TZ\n        Database name, so this function only exists on Posix systems.\n      +/\n    void setTZEnvVar(string tzDatabaseName) @safe nothrow;\n\n\n    /++\n        $(BLUE This function is Posix-Only.)\n\n        Clears the TZ environment variable.\n      +/\n    void clearTZEnvVar() @safe nothrow;\n}\nelse version (Posix)\n{\n    void setTZEnvVar(string tzDatabaseName) @trusted nothrow\n    {\n        import core.stdc.time : tzset;\n        import core.sys.posix.stdlib : setenv;\n        import std.internal.cstring : tempCString;\n        import std.path : asNormalizedPath, chainPath;\n\n        version (Android)\n            auto value = asNormalizedPath(tzDatabaseName);\n        else\n            auto value = asNormalizedPath(chainPath(PosixTimeZone.defaultTZDatabaseDir, tzDatabaseName));\n        setenv(\"TZ\", value.tempCString(), 1);\n        tzset();\n    }\n\n\n    void clearTZEnvVar() @trusted nothrow\n    {\n        import core.stdc.time : tzset;\n        import core.sys.posix.stdlib : unsetenv;\n\n        unsetenv(\"TZ\");\n        tzset();\n    }\n}\n\n\n/++\n    Provides the conversions between the IANA time zone database time zone names\n    (which POSIX systems use) and the time zone names that Windows uses.\n\n    Windows uses a different set of time zone names than the IANA time zone\n    database does, and how they correspond to one another changes over time\n    (particularly when Microsoft updates Windows).\n    $(HTTP unicode.org/cldr/data/common/supplemental/windowsZones.xml, windowsZones.xml)\n    provides the current conversions (which may or may not match up with what's\n    on a particular Windows box depending on how up-to-date it is), and\n    parseTZConversions reads in those conversions from windowsZones.xml so that\n    a D program can use those conversions.\n\n    However, it should be noted that the time zone information on Windows is\n    frequently less accurate than that in the IANA time zone database, and if\n    someone really wants accurate time zone information, they should use the\n    IANA time zone database files with $(LREF PosixTimeZone) on Windows rather\n    than $(LREF WindowsTimeZone), whereas $(LREF WindowsTimeZone) makes more\n    sense when trying to match what Windows will think the time is in a specific\n    time zone.\n\n    Also, the IANA time zone database has a lot more time zones than Windows\n    does.\n\n    Params:\n        windowsZonesXMLText = The text from\n        $(HTTP unicode.org/cldr/data/common/supplemental/windowsZones.xml, windowsZones.xml)\n\n    Throws:\n        Exception if there is an error while parsing the given XML.\n\n--------------------\n    // Parse the conversions from a local file.\n    auto text = std.file.readText(\"path/to/windowsZones.xml\");\n    auto conversions = parseTZConversions(text);\n\n    // Alternatively, grab the XML file from the web at runtime\n    // and parse it so that it's guaranteed to be up-to-date, though\n    // that has the downside that the code needs to worry about the\n    // site being down or unicode.org changing the URL.\n    auto url = \"http://unicode.org/cldr/data/common/supplemental/windowsZones.xml\";\n    auto conversions2 = parseTZConversions(std.net.curl.get(url));\n--------------------\n  +/\nstruct TZConversions\n{\n    /++\n        The key is the Windows time zone name, and the value is a list of\n        IANA TZ database names which are close (currently only ever one, but\n        it allows for multiple in case it's ever necessary).\n      +/\n    string[][string] toWindows;\n\n    /++\n        The key is the IANA time zone database name, and the value is a list of\n        Windows time zone names which are close (usually only one, but it could\n        be multiple).\n      +/\n    string[][string] fromWindows;\n}\n\n/++ ditto +/\nTZConversions parseTZConversions(string windowsZonesXMLText) @safe pure\n{\n    // This is a bit hacky, since it doesn't properly read XML, but it avoids\n    // needing to pull in std.xml (which we're theoretically replacing at some\n    // point anyway).\n    import std.algorithm.iteration : uniq;\n    import std.algorithm.searching : find;\n    import std.algorithm.sorting : sort;\n    import std.array : array, split;\n    import std.string : lineSplitter;\n\n    string[][string] win2Nix;\n    string[][string] nix2Win;\n\n    immutable f1 = `<mapZone other=\"`;\n    immutable f2 = `type=\"`;\n\n    foreach (line; windowsZonesXMLText.lineSplitter())\n    {\n        import std.exception : enforce;\n        // Sample line:\n        // <mapZone other=\"Canada Central Standard Time\" territory=\"CA\" type=\"America/Regina America/Swift_Current\"/>\n\n        line = line.find(f1);\n        if (line.empty)\n            continue;\n        line = line[f1.length .. $];\n        auto next = line.find('\"');\n        enforce(!next.empty, \"Error parsing. Text does not appear to be from windowsZones.xml\");\n        auto win = line[0 .. $ - next.length];\n        line = next.find(f2);\n        enforce(!line.empty, \"Error parsing. Text does not appear to be from windowsZones.xml\");\n        line = line[f2.length .. $];\n        next = line.find('\"');\n        enforce(!next.empty, \"Error parsing. Text does not appear to be from windowsZones.xml\");\n        auto nixes = line[0 .. $ - next.length].split();\n\n        if (auto n = win in win2Nix)\n            *n ~= nixes;\n        else\n            win2Nix[win] = nixes;\n\n        foreach (nix; nixes)\n        {\n            if (auto w = nix in nix2Win)\n                *w ~= win;\n            else\n                nix2Win[nix] = [win];\n        }\n    }\n\n    foreach (key, ref value; nix2Win)\n        value = value.sort().uniq().array();\n    foreach (key, ref value; win2Nix)\n        value = value.sort().uniq().array();\n\n    return TZConversions(nix2Win, win2Nix);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : uniq;\n    import std.algorithm.sorting : isSorted;\n\n    // Reduced text from http://unicode.org/cldr/data/common/supplemental/windowsZones.xml\n    auto sampleFileText =\n`<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE supplementalData SYSTEM \"../../common/dtd/ldmlSupplemental.dtd\">\n<!--\nCopyright © 1991-2013 Unicode, Inc.\nCLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/)\nFor terms of use, see http://www.unicode.org/copyright.html\n-->\n\n<supplementalData>\n    <version number=\"$Revision$\"/>\n\n    <windowsZones>\n        <mapTimezones otherVersion=\"7df0005\" typeVersion=\"2015g\">\n\n            <!-- (UTC-12:00) International Date Line West -->\n            <mapZone other=\"Dateline Standard Time\" territory=\"001\" type=\"Etc/GMT+12\"/>\n            <mapZone other=\"Dateline Standard Time\" territory=\"ZZ\" type=\"Etc/GMT+12\"/>\n\n            <!-- (UTC-11:00) Coordinated Universal Time-11 -->\n            <mapZone other=\"UTC-11\" territory=\"001\" type=\"Etc/GMT+11\"/>\n            <mapZone other=\"UTC-11\" territory=\"AS\" type=\"Pacific/Pago_Pago\"/>\n            <mapZone other=\"UTC-11\" territory=\"NU\" type=\"Pacific/Niue\"/>\n            <mapZone other=\"UTC-11\" territory=\"UM\" type=\"Pacific/Midway\"/>\n            <mapZone other=\"UTC-11\" territory=\"ZZ\" type=\"Etc/GMT+11\"/>\n\n            <!-- (UTC-10:00) Hawaii -->\n            <mapZone other=\"Hawaiian Standard Time\" territory=\"001\" type=\"Pacific/Honolulu\"/>\n            <mapZone other=\"Hawaiian Standard Time\" territory=\"CK\" type=\"Pacific/Rarotonga\"/>\n            <mapZone other=\"Hawaiian Standard Time\" territory=\"PF\" type=\"Pacific/Tahiti\"/>\n            <mapZone other=\"Hawaiian Standard Time\" territory=\"UM\" type=\"Pacific/Johnston\"/>\n            <mapZone other=\"Hawaiian Standard Time\" territory=\"US\" type=\"Pacific/Honolulu\"/>\n            <mapZone other=\"Hawaiian Standard Time\" territory=\"ZZ\" type=\"Etc/GMT+10\"/>\n\n            <!-- (UTC-09:00) Alaska -->\n            <mapZone other=\"Alaskan Standard Time\" territory=\"001\" type=\"America/Anchorage\"/>\n            <mapZone other=\"Alaskan Standard Time\" territory=\"US\" `\n                ~ `type=\"America/Anchorage America/Juneau America/Nome America/Sitka America/Yakutat\"/>\n        </mapTimezones>\n    </windowsZones>\n</supplementalData>`;\n\n    auto tzConversions = parseTZConversions(sampleFileText);\n    assert(tzConversions.toWindows.length == 15);\n    assert(tzConversions.toWindows[\"America/Anchorage\"] == [\"Alaskan Standard Time\"]);\n    assert(tzConversions.toWindows[\"America/Juneau\"] == [\"Alaskan Standard Time\"]);\n    assert(tzConversions.toWindows[\"America/Nome\"] == [\"Alaskan Standard Time\"]);\n    assert(tzConversions.toWindows[\"America/Sitka\"] == [\"Alaskan Standard Time\"]);\n    assert(tzConversions.toWindows[\"America/Yakutat\"] == [\"Alaskan Standard Time\"]);\n    assert(tzConversions.toWindows[\"Etc/GMT+10\"] == [\"Hawaiian Standard Time\"]);\n    assert(tzConversions.toWindows[\"Etc/GMT+11\"] == [\"UTC-11\"]);\n    assert(tzConversions.toWindows[\"Etc/GMT+12\"] == [\"Dateline Standard Time\"]);\n    assert(tzConversions.toWindows[\"Pacific/Honolulu\"] == [\"Hawaiian Standard Time\"]);\n    assert(tzConversions.toWindows[\"Pacific/Johnston\"] == [\"Hawaiian Standard Time\"]);\n    assert(tzConversions.toWindows[\"Pacific/Midway\"] == [\"UTC-11\"]);\n    assert(tzConversions.toWindows[\"Pacific/Niue\"] == [\"UTC-11\"]);\n    assert(tzConversions.toWindows[\"Pacific/Pago_Pago\"] == [\"UTC-11\"]);\n    assert(tzConversions.toWindows[\"Pacific/Rarotonga\"] == [\"Hawaiian Standard Time\"]);\n    assert(tzConversions.toWindows[\"Pacific/Tahiti\"] == [\"Hawaiian Standard Time\"]);\n\n    assert(tzConversions.fromWindows.length == 4);\n    assert(tzConversions.fromWindows[\"Alaskan Standard Time\"] ==\n           [\"America/Anchorage\", \"America/Juneau\", \"America/Nome\", \"America/Sitka\", \"America/Yakutat\"]);\n    assert(tzConversions.fromWindows[\"Dateline Standard Time\"] == [\"Etc/GMT+12\"]);\n    assert(tzConversions.fromWindows[\"Hawaiian Standard Time\"] ==\n           [\"Etc/GMT+10\", \"Pacific/Honolulu\", \"Pacific/Johnston\", \"Pacific/Rarotonga\", \"Pacific/Tahiti\"]);\n    assert(tzConversions.fromWindows[\"UTC-11\"] ==\n           [\"Etc/GMT+11\", \"Pacific/Midway\", \"Pacific/Niue\", \"Pacific/Pago_Pago\"]);\n\n    foreach (key, value; tzConversions.fromWindows)\n    {\n        assert(value.isSorted, key);\n        assert(equal(value.uniq(), value), key);\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/demangle.d",
    "content": "// Written in the D programming language.\n\n/**\n * Demangle D mangled names.\n *\n * Copyright: Copyright The D Language Foundation 2000 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright),\n *                        Thomas K$(UUML)hne, Frits van Bommel\n * Source:    $(PHOBOSSRC std/demangle.d)\n * $(SCRIPT inhibitQuickIndex = 1;)\n */\n/*\n *          Copyright The D Language Foundation 2000 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.demangle;\n\n/**\nDemangle D mangled names.\n\nParams:\n    name = the mangled name\nReturns:\n    A `string`. If it is not a D mangled name, it returns its argument name.\n */\nstring demangle(string name) @safe pure nothrow\n{\n    import core.demangle : demangle;\n    import std.exception : assumeUnique;\n    auto ret = demangle(name);\n    return () @trusted { return ret.assumeUnique; } ();\n}\n\n///\n@safe pure unittest\n{\n    // int b in module a\n    assert(demangle(\"_D1a1bi\") == \"int a.b\");\n    // char array foo in module test\n    assert(demangle(\"_D4test3fooAa\") == \"char[] test.foo\");\n}\n\n/**\nThis program reads standard in and writes it to standard out,\npretty-printing any found D mangled names.\n */\n@system unittest\n{\n    import std.ascii : isAlphaNum;\n    import std.algorithm.iteration : chunkBy, joiner, map;\n    import std.algorithm.mutation : copy;\n    import std.conv : to;\n    import std.demangle : demangle;\n    import std.functional : pipe;\n    import std.stdio : stdin, stdout;\n\n    void main()\n    {\n        stdin.byLineCopy\n            .map!(\n                l => l.chunkBy!(a => isAlphaNum(a) || a == '_')\n                      .map!(a => a[1].pipe!(to!string, demangle)).joiner\n            )\n            .copy(stdout.lockingTextWriter);\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/digest/crc.d",
    "content": "/**\nCyclic Redundancy Check (32-bit) implementation.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n\n$(DIVC quickindex,\n$(BOOKTABLE ,\n$(TR $(TH Category) $(TH Functions)\n)\n$(TR $(TDNW Template API) $(TD $(MYREF CRC) $(MYREF CRC32) $(MYREF CRC64ECMA) $(MYREF CRC64ISO)\n)\n)\n$(TR $(TDNW OOP API) $(TD $(MYREF CRC32Digest) $(MYREF CRC64ECMADigest) $(MYREF CRC64ISODigest))\n)\n$(TR $(TDNW Helpers) $(TD $(MYREF crcHexString) $(MYREF crc32Of) $(MYREF crc64ECMAOf) $(MYREF crc64ISOOf))\n)\n)\n)\n\n *\n * This module conforms to the APIs defined in `std.digest`. To understand the\n * differences between the template and the OOP API, see $(MREF std, digest).\n *\n * This module publicly imports $(MREF std, digest) and can be used as a stand-alone\n * module.\n *\n * Note:\n * CRCs are usually printed with the MSB first. When using\n * $(REF toHexString, std,digest) the result will be in an unexpected\n * order. Use $(REF toHexString, std,digest)'s optional order parameter\n * to specify decreasing order for the correct result. The $(LREF crcHexString)\n * alias can also be used for this purpose.\n *\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n *\n * Authors:   Pavel \"EvilOne\" Minayev, Alex Rønne Petersen, Johannes Pfau\n *\n * References:\n *      $(LINK2 http://en.wikipedia.org/wiki/Cyclic_redundancy_check, Wikipedia on CRC)\n *\n * Source: $(PHOBOSSRC std/digest/crc.d)\n *\n * Standards:\n * Implements the 'common' IEEE CRC32 variant\n * (LSB-first order, Initial value uint.max, complement result)\n *\n * CTFE:\n * Digests do not work in CTFE\n */\n/*\n * Copyright (c) 2001 - 2002\n * Pavel \"EvilOne\" Minayev\n * Copyright (c) 2012\n * Alex Rønne Petersen\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.digest.crc;\n\npublic import std.digest;\n\n///\n@safe unittest\n{\n    //Template API\n    import std.digest.crc;\n\n    ubyte[4] hash = crc32Of(\"The quick brown fox jumps over the lazy dog\");\n    assert(crcHexString(hash) == \"414FA339\");\n\n    //Feeding data\n    ubyte[1024] data;\n    CRC32 crc;\n    crc.put(data[]);\n    crc.start(); //Start again\n    crc.put(data[]);\n    hash = crc.finish();\n}\n\n///\n@safe unittest\n{\n    //OOP API\n    import std.digest.crc;\n\n    auto crc = new CRC32Digest();\n    ubyte[] hash = crc.digest(\"The quick brown fox jumps over the lazy dog\");\n    assert(crcHexString(hash) == \"414FA339\"); //352441c2\n\n    //Feeding data\n    ubyte[1024] data;\n    crc.put(data[]);\n    crc.reset(); //Start again\n    crc.put(data[]);\n    hash = crc.finish();\n}\n\nprivate T[256][8] genTables(T)(T polynomial)\n{\n    T[256][8] res = void;\n\n    foreach (i; 0 .. 0x100)\n    {\n        T crc = i;\n        foreach (_; 0 .. 8)\n            crc = (crc >> 1) ^ (-int(crc & 1) & polynomial);\n        res[0][i] = crc;\n    }\n\n    foreach (i; 0 .. 0x100)\n    {\n        res[1][i] = (res[0][i] >> 8) ^ res[0][res[0][i] & 0xFF];\n        res[2][i] = (res[1][i] >> 8) ^ res[0][res[1][i] & 0xFF];\n        res[3][i] = (res[2][i] >> 8) ^ res[0][res[2][i] & 0xFF];\n        res[4][i] = (res[3][i] >> 8) ^ res[0][res[3][i] & 0xFF];\n        res[5][i] = (res[4][i] >> 8) ^ res[0][res[4][i] & 0xFF];\n        res[6][i] = (res[5][i] >> 8) ^ res[0][res[5][i] & 0xFF];\n        res[7][i] = (res[6][i] >> 8) ^ res[0][res[6][i] & 0xFF];\n    }\n    return res;\n}\n\n@system unittest\n{\n    auto tables = genTables(0xEDB88320);\n    assert(tables[0][0] == 0x00000000 && tables[0][$ - 1] == 0x2d02ef8d && tables[7][$ - 1] == 0x264b06e6);\n}\n\n/**\n * Template API CRC32 implementation.\n * See `std.digest` for differences between template and OOP API.\n */\nalias CRC32 = CRC!(32, 0xEDB88320);\n\n/**\n * Template API CRC64-ECMA implementation.\n * See `std.digest.digest` for differences between template and OOP API.\n */\nalias CRC64ECMA = CRC!(64, 0xC96C5795D7870F42);\n\n/**\n * Template API CRC64-ISO implementation.\n * See `std.digest.digest` for differences between template and OOP API.\n */\nalias CRC64ISO = CRC!(64, 0xD800000000000000);\n\n/**\n * Generic Template API used for CRC32 and CRC64 implementations.\n *\n * The N parameter indicate the size of the hash in bits.\n * The parameter P specify the polynomial to be used for reduction.\n *\n * You may want to use the CRC32, CRC65ECMA and CRC64ISO aliases\n * for convenience.\n *\n * See `std.digest.digest` for differences between template and OOP API.\n */\nstruct CRC(uint N, ulong P)\nif (N == 32 || N == 64)\n{\n    private:\n        static if (N == 32)\n        {\n            alias T = uint;\n        }\n        else\n        {\n            alias T = ulong;\n        }\n\n        static immutable T[256][8] tables = genTables!T(P);\n\n        /**\n         * Type of the finished CRC hash.\n         * ubyte[4] if N is 32, ubyte[8] if N is 64.\n         */\n        alias R = ubyte[T.sizeof];\n\n        // magic initialization constants\n        T _state = T.max;\n\n    public:\n        /**\n         * Use this to feed the digest with data.\n         * Also implements the $(REF isOutputRange, std,range,primitives)\n         * interface for `ubyte` and `const(ubyte)[]`.\n         */\n        void put(scope const(ubyte)[] data...) @trusted pure nothrow @nogc\n        {\n            T crc = _state;\n            // process eight bytes at once\n            while (data.length >= 8)\n            {\n                // Use byte-wise reads to support architectures without HW support\n                // for unaligned reads. This can be optimized by compilers to a single\n                // 32-bit read if unaligned reads are supported.\n                // DMD is not able to do this optimization though, so explicitly\n                // do unaligned reads for DMD's architectures.\n                version (X86)\n                    enum hasLittleEndianUnalignedReads = true;\n                else version (X86_64)\n                    enum hasLittleEndianUnalignedReads = true;\n                else\n                    enum hasLittleEndianUnalignedReads = false; // leave decision to optimizer\n                static if (hasLittleEndianUnalignedReads)\n                {\n                    uint one = (cast(uint*) data.ptr)[0];\n                    uint two = (cast(uint*) data.ptr)[1];\n                }\n                else\n                {\n                    uint one = (data.ptr[3] << 24 | data.ptr[2] << 16 | data.ptr[1] << 8 | data.ptr[0]);\n                    uint two = (data.ptr[7] << 24 | data.ptr[6] << 16 | data.ptr[5] << 8 | data.ptr[4]);\n                }\n\n                static if (N == 32)\n                {\n                    one ^= crc;\n                }\n                else\n                {\n                    one ^= (crc & 0xffffffff);\n                    two ^= (crc >> 32);\n                }\n\n                crc =\n                    tables[0][two >> 24] ^\n                    tables[1][(two >> 16) & 0xFF] ^\n                    tables[2][(two >>  8) & 0xFF] ^\n                    tables[3][two & 0xFF] ^\n                    tables[4][one >> 24] ^\n                    tables[5][(one >> 16) & 0xFF] ^\n                    tables[6][(one >>  8) & 0xFF] ^\n                    tables[7][one & 0xFF];\n\n                data = data[8 .. $];\n            }\n            // remaining 1 to 7 bytes\n            foreach (d; data)\n                crc = (crc >> 8) ^ tables[0][(crc & 0xFF) ^ d];\n            _state = crc;\n        }\n\n        /**\n         * Used to initialize the CRC32 digest.\n         *\n         * Note:\n         * For this CRC32 Digest implementation calling start after default construction\n         * is not necessary. Calling start is only necessary to reset the Digest.\n         *\n         * Generic code which deals with different Digest types should always call start though.\n         */\n        void start() @safe pure nothrow @nogc\n        {\n            this = CRC.init;\n        }\n\n        /**\n         * Returns the finished CRC hash. This also calls $(LREF start) to\n         * reset the internal state.\n         */\n        R finish() @safe pure nothrow @nogc\n        {\n            auto tmp = peek();\n            start();\n            return tmp;\n        }\n\n        /**\n         * Works like `finish` but does not reset the internal state, so it's possible\n         * to continue putting data into this CRC after a call to peek.\n         */\n        R peek() const @safe pure nothrow @nogc\n        {\n            import std.bitmanip : nativeToLittleEndian;\n            //Complement, LSB first / Little Endian, see http://rosettacode.org/wiki/CRC-32\n            return nativeToLittleEndian(~_state);\n        }\n}\n\n///\n@safe unittest\n{\n    //Simple example, hashing a string using crc32Of helper function\n    ubyte[4] hash32 = crc32Of(\"abc\");\n    //Let's get a hash string\n    assert(crcHexString(hash32) == \"352441C2\");\n    // Repeat for CRC64\n    ubyte[8] hash64ecma = crc64ECMAOf(\"abc\");\n    assert(crcHexString(hash64ecma) == \"2CD8094A1A277627\");\n    ubyte[8] hash64iso = crc64ISOOf(\"abc\");\n    assert(crcHexString(hash64iso) == \"3776C42000000000\");\n}\n\n///\n@safe unittest\n{\n    ubyte[1024] data;\n    //Using the basic API\n    CRC32 hash32;\n    CRC64ECMA hash64ecma;\n    CRC64ISO hash64iso;\n    //Initialize data here...\n    hash32.put(data);\n    ubyte[4] result32 = hash32.finish();\n    hash64ecma.put(data);\n    ubyte[8] result64ecma = hash64ecma.finish();\n    hash64iso.put(data);\n    ubyte[8] result64iso = hash64iso.finish();\n}\n\n///\n@safe unittest\n{\n    //Let's use the template features:\n    //Note: When passing a CRC32 to a function, it must be passed by reference!\n    void doSomething(T)(ref T hash)\n    if (isDigest!T)\n    {\n      hash.put(cast(ubyte) 0);\n    }\n    CRC32 crc32;\n    crc32.start();\n    doSomething(crc32);\n    assert(crcHexString(crc32.finish()) == \"D202EF8D\");\n    // repeat for CRC64\n    CRC64ECMA crc64ecma;\n    crc64ecma.start();\n    doSomething(crc64ecma);\n    assert(crcHexString(crc64ecma.finish()) == \"1FADA17364673F59\");\n    CRC64ISO crc64iso;\n    crc64iso.start();\n    doSomething(crc64iso);\n    assert(crcHexString(crc64iso.finish()) == \"6F90000000000000\");\n}\n\n@safe unittest\n{\n    assert(isDigest!CRC32);\n    assert(isDigest!CRC64ECMA);\n    assert(isDigest!CRC64ISO);\n}\n\n@system unittest\n{\n    import std.conv : hexString;\n    ubyte[4] digest;\n\n    CRC32 crc;\n    crc.put(cast(ubyte[])\"abcdefghijklmnopqrstuvwxyz\");\n    assert(crc.peek() == cast(ubyte[]) hexString!\"bd50274c\");\n    crc.start();\n    crc.put(cast(ubyte[])\"\");\n    assert(crc.finish() == cast(ubyte[]) hexString!\"00000000\");\n\n    digest = crc32Of(\"\");\n    assert(digest == cast(ubyte[]) hexString!\"00000000\");\n\n    //Test vector from http://rosettacode.org/wiki/CRC-32\n    assert(crcHexString(crc32Of(\"The quick brown fox jumps over the lazy dog\")) == \"414FA339\");\n\n    digest = crc32Of(\"a\");\n    assert(digest == cast(ubyte[]) hexString!\"43beb7e8\");\n\n    digest = crc32Of(\"abc\");\n    assert(digest == cast(ubyte[]) hexString!\"c2412435\");\n\n    digest = crc32Of(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    assert(digest == cast(ubyte[]) hexString!\"5f3f1a17\");\n\n    digest = crc32Of(\"message digest\");\n    assert(digest == cast(ubyte[]) hexString!\"7f9d1520\");\n\n    digest = crc32Of(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    assert(digest == cast(ubyte[]) hexString!\"d2e6c21f\");\n\n    digest = crc32Of(\"1234567890123456789012345678901234567890\"~\n                    \"1234567890123456789012345678901234567890\");\n    assert(digest == cast(ubyte[]) hexString!\"724aa97c\");\n\n    enum ubyte[4] input = cast(ubyte[4]) hexString!\"c3fcd3d7\";\n    assert(crcHexString(input) == \"D7D3FCC3\");\n}\n\n@system unittest\n{\n    import std.conv : hexString;\n    ubyte[8] digest;\n\n    CRC64ECMA crc;\n    crc.put(cast(ubyte[])\"abcdefghijklmnopqrstuvwxyz\");\n    assert(crc.peek() == cast(ubyte[]) hexString!\"2f121b7575789626\");\n    crc.start();\n    crc.put(cast(ubyte[])\"\");\n    assert(crc.finish() == cast(ubyte[]) hexString!\"0000000000000000\");\n    digest = crc64ECMAOf(\"\");\n    assert(digest == cast(ubyte[]) hexString!\"0000000000000000\");\n\n    //Test vector from http://rosettacode.org/wiki/CRC-32\n    assert(crcHexString(crc64ECMAOf(\"The quick brown fox jumps over the lazy dog\")) == \"5B5EB8C2E54AA1C4\");\n\n    digest = crc64ECMAOf(\"a\");\n    assert(digest == cast(ubyte[]) hexString!\"052b652e77840233\");\n\n    digest = crc64ECMAOf(\"abc\");\n    assert(digest == cast(ubyte[]) hexString!\"2776271a4a09d82c\");\n\n    digest = crc64ECMAOf(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    assert(digest == cast(ubyte[]) hexString!\"4b7cdce3746c449f\");\n\n    digest = crc64ECMAOf(\"message digest\");\n    assert(digest == cast(ubyte[]) hexString!\"6f9b8a3156c9bc5d\");\n\n    digest = crc64ECMAOf(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    assert(digest == cast(ubyte[]) hexString!\"2656b716e1bf0503\");\n\n    digest = crc64ECMAOf(\"1234567890123456789012345678901234567890\"~\n                         \"1234567890123456789012345678901234567890\");\n    assert(digest == cast(ubyte[]) hexString!\"bd3eb7765d0a22ae\");\n\n    enum ubyte[8] input = cast(ubyte[8]) hexString!\"c3fcd3d7efbeadde\";\n    assert(crcHexString(input) == \"DEADBEEFD7D3FCC3\");\n}\n\n@system unittest\n{\n    import std.conv : hexString;\n    ubyte[8] digest;\n\n    CRC64ISO crc;\n    crc.put(cast(ubyte[])\"abcdefghijklmnopqrstuvwxyz\");\n    assert(crc.peek() == cast(ubyte[]) hexString!\"f0494ab780989b42\");\n    crc.start();\n    crc.put(cast(ubyte[])\"\");\n    assert(crc.finish() == cast(ubyte[]) hexString!\"0000000000000000\");\n    digest = crc64ISOOf(\"\");\n    assert(digest == cast(ubyte[]) hexString!\"0000000000000000\");\n\n    //Test vector from http://rosettacode.org/wiki/CRC-32\n    assert(crcHexString(crc64ISOOf(\"The quick brown fox jumps over the lazy dog\")) == \"4EF14E19F4C6E28E\");\n\n    digest = crc64ISOOf(\"a\");\n    assert(digest == cast(ubyte[]) hexString!\"0000000000002034\");\n\n    digest = crc64ISOOf(\"abc\");\n    assert(digest == cast(ubyte[]) hexString!\"0000000020c47637\");\n\n    digest = crc64ISOOf(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    assert(digest == cast(ubyte[]) hexString!\"5173f717971365e5\");\n\n    digest = crc64ISOOf(\"message digest\");\n    assert(digest == cast(ubyte[]) hexString!\"a2c355bbc0b93f86\");\n\n    digest = crc64ISOOf(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    assert(digest == cast(ubyte[]) hexString!\"598B258292E40084\");\n\n    digest = crc64ISOOf(\"1234567890123456789012345678901234567890\"~\n                        \"1234567890123456789012345678901234567890\");\n    assert(digest == cast(ubyte[]) hexString!\"760cd2d3588bf809\");\n\n    enum ubyte[8] input = cast(ubyte[8]) hexString!\"c3fcd3d7efbeadde\";\n    assert(crcHexString(input) == \"DEADBEEFD7D3FCC3\");\n}\n\n/**\n * This is a convenience alias for $(REF digest, std,digest) using the\n * CRC32 implementation.\n *\n * Params:\n *      data = `InputRange` of `ElementType` implicitly convertible to\n *             `ubyte`, `ubyte[]` or `ubyte[num]` or one or more arrays\n *             of any type.\n *\n * Returns:\n *      CRC32 of data\n */\n//simple alias doesn't work here, hope this gets inlined...\nubyte[4] crc32Of(T...)(T data)\n{\n    return digest!(CRC32, T)(data);\n}\n\n///\n@system unittest\n{\n    ubyte[] data = [4,5,7,25];\n    assert(data.crc32Of == [167, 180, 199, 131]);\n\n    import std.utf : byChar;\n    assert(\"hello\"d.byChar.crc32Of == [134, 166, 16, 54]);\n\n    ubyte[4] hash = \"abc\".crc32Of();\n    assert(hash == digest!CRC32(\"ab\", \"c\"));\n\n    import std.range : iota;\n    enum ubyte S = 5, F = 66;\n    assert(iota(S, F).crc32Of == [59, 140, 234, 154]);\n}\n\n/**\n * This is a convenience alias for $(REF digest, std,digest) using the\n * CRC64-ECMA implementation.\n *\n * Params:\n *      data = `InputRange` of `ElementType` implicitly convertible to\n *             `ubyte`, `ubyte[]` or `ubyte[num]` or one or more arrays\n *             of any type.\n *\n * Returns:\n *      CRC64-ECMA of data\n */\n//simple alias doesn't work here, hope this gets inlined...\nubyte[8] crc64ECMAOf(T...)(T data)\n{\n    return digest!(CRC64ECMA, T)(data);\n}\n\n///\n@system unittest\n{\n    ubyte[] data = [4,5,7,25];\n    assert(data.crc64ECMAOf == [58, 142, 220, 214, 118, 98, 105, 69]);\n\n    import std.utf : byChar;\n    assert(\"hello\"d.byChar.crc64ECMAOf == [177, 55, 185, 219, 229, 218, 30, 155]);\n\n    ubyte[8] hash = \"abc\".crc64ECMAOf();\n    assert(\"abc\".crc64ECMAOf == [39, 118, 39, 26, 74, 9, 216, 44]);\n    assert(hash == digest!CRC64ECMA(\"ab\", \"c\"));\n\n    import std.range : iota;\n    enum ubyte S = 5, F = 66;\n    assert(iota(S, F).crc64ECMAOf == [6, 184, 91, 238, 46, 213, 127, 188]);\n}\n\n/**\n * This is a convenience alias for $(REF digest, std,digest,digest) using the\n * CRC64-ISO implementation.\n *\n * Params:\n *      data = `InputRange` of `ElementType` implicitly convertible to\n *             `ubyte`, `ubyte[]` or `ubyte[num]` or one or more arrays\n *             of any type.\n *\n * Returns:\n *      CRC64-ISO of data\n */\n//simple alias doesn't work here, hope this gets inlined...\nubyte[8] crc64ISOOf(T...)(T data)\n{\n    return digest!(CRC64ISO, T)(data);\n}\n\n///\n@system unittest\n{\n    ubyte[] data = [4,5,7,25];\n    assert(data.crc64ISOOf == [0, 0, 0, 80, 137, 232, 203, 120]);\n\n    import std.utf : byChar;\n    assert(\"hello\"d.byChar.crc64ISOOf == [0, 0, 16, 216, 226, 238, 62, 60]);\n\n    ubyte[8] hash = \"abc\".crc64ISOOf();\n    assert(\"abc\".crc64ISOOf == [0, 0, 0, 0, 32, 196, 118, 55]);\n    assert(hash == digest!CRC64ISO(\"ab\", \"c\"));\n\n    import std.range : iota;\n    enum ubyte S = 5, F = 66;\n\n    assert(iota(S, F).crc64ISOOf == [21, 185, 116, 95, 219, 11, 54, 7]);\n}\n\n/**\n * producing the usual CRC32 string output.\n */\npublic alias crcHexString = toHexString!(Order.decreasing);\n///ditto\npublic alias crcHexString = toHexString!(Order.decreasing, 16);\n\n/**\n * OOP API CRC32 implementation.\n * See `std.digest` for differences between template and OOP API.\n *\n * This is an alias for $(D $(REF WrapperDigest, std,digest)!CRC32), see\n * there for more information.\n */\nalias CRC32Digest = WrapperDigest!CRC32;\n\n/**\n * OOP API CRC64-ECMA implementation.\n * See `std.digest.digest` for differences between template and OOP API.\n *\n * This is an alias for $(D $(REF WrapperDigest, std,digest,digest)!CRC64ECMA),\n * see there for more information.\n */\nalias CRC64ECMADigest = WrapperDigest!CRC64ECMA;\n\n/**\n * OOP API CRC64-ISO implementation.\n * See `std.digest.digest` for differences between template and OOP API.\n *\n * This is an alias for $(D $(REF WrapperDigest, std,digest,digest)!CRC64ISO),\n * see there for more information.\n */\nalias CRC64ISODigest = WrapperDigest!CRC64ISO;\n\n///\n@safe unittest\n{\n    //Simple example, hashing a string using Digest.digest helper function\n    auto crc = new CRC32Digest();\n    ubyte[] hash = crc.digest(\"abc\");\n    //Let's get a hash string\n    assert(crcHexString(hash) == \"352441C2\");\n}\n\n///\n@system unittest\n{\n     //Let's use the OOP features:\n    void test(Digest dig)\n    {\n      dig.put(cast(ubyte) 0);\n    }\n    auto crc = new CRC32Digest();\n    test(crc);\n\n    //Let's use a custom buffer:\n    ubyte[4] buf;\n    ubyte[] result = crc.finish(buf[]);\n    assert(crcHexString(result) == \"D202EF8D\");\n}\n\n///\n@safe unittest\n{\n    //Simple example\n    auto hash = new CRC32Digest();\n    hash.put(cast(ubyte) 0);\n    ubyte[] result = hash.finish();\n}\n\n///\n@system unittest\n{\n    //using a supplied buffer\n    ubyte[4] buf;\n    auto hash = new CRC32Digest();\n    hash.put(cast(ubyte) 0);\n    ubyte[] result = hash.finish(buf[]);\n    //The result is now in result (and in buf. If you pass a buffer which is bigger than\n    //necessary, result will have the correct length, but buf will still have it's original\n    //length)\n}\n\n@system unittest\n{\n    import std.conv : hexString;\n    import std.range;\n    import std.exception;\n\n    auto crc = new CRC32Digest();\n\n    crc.put(cast(ubyte[])\"abcdefghijklmnopqrstuvwxyz\");\n    assert(crc.peek() == cast(ubyte[]) hexString!\"bd50274c\");\n    crc.reset();\n    crc.put(cast(ubyte[])\"\");\n    assert(crc.finish() == cast(ubyte[]) hexString!\"00000000\");\n\n    crc.put(cast(ubyte[])\"abcdefghijklmnopqrstuvwxyz\");\n    ubyte[20] result;\n    auto result2 = crc.finish(result[]);\n    assert(result[0 .. 4] == result2 && result2 == cast(ubyte[]) hexString!\"bd50274c\");\n\n    debug\n        assertThrown!Error(crc.finish(result[0 .. 3]));\n\n    assert(crc.length == 4);\n\n    assert(crc.digest(\"\") == cast(ubyte[]) hexString!\"00000000\");\n\n    assert(crc.digest(\"a\") == cast(ubyte[]) hexString!\"43beb7e8\");\n\n    assert(crc.digest(\"abc\") == cast(ubyte[]) hexString!\"c2412435\");\n\n    assert(crc.digest(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\")\n           == cast(ubyte[]) hexString!\"5f3f1a17\");\n\n    assert(crc.digest(\"message digest\") == cast(ubyte[]) hexString!\"7f9d1520\");\n\n    assert(crc.digest(\"abcdefghijklmnopqrstuvwxyz\")\n           == cast(ubyte[]) hexString!\"bd50274c\");\n\n    assert(crc.digest(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\")\n           == cast(ubyte[]) hexString!\"d2e6c21f\");\n\n    assert(crc.digest(\"1234567890123456789012345678901234567890\",\n                                   \"1234567890123456789012345678901234567890\")\n           == cast(ubyte[]) hexString!\"724aa97c\");\n\n    ubyte[] onemilliona = new ubyte[1000000];\n    onemilliona[] = 'a';\n    auto digest = crc32Of(onemilliona);\n    assert(digest == cast(ubyte[]) hexString!\"BCBF25DC\");\n\n    auto oneMillionRange = repeat!ubyte(cast(ubyte)'a', 1000000);\n    digest = crc32Of(oneMillionRange);\n    assert(digest == cast(ubyte[]) hexString!\"BCBF25DC\");\n}\n"
  },
  {
    "path": "libphobos/src/std/digest/digest.d",
    "content": "module std.digest.digest;\n\nimport _newDigest = std.digest;\n\n// @@@DEPRECATED_2.084@@@\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias isDigest = _newDigest.isDigest;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias DigestType = _newDigest.DigestType;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias hasPeek = _newDigest.hasPeek;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias hasBlockSize = _newDigest.hasBlockSize;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias digest = _newDigest.digest;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias hexDigest = _newDigest.hexDigest;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias makeDigest = _newDigest.makeDigest;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias Digest = _newDigest.Digest;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias Order = _newDigest.Order;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias toHexString = _newDigest.toHexString;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias asArray = _newDigest.asArray;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias digestLength = _newDigest.digestLength;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias WrapperDigest = _newDigest.WrapperDigest;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias secureEqual = _newDigest.secureEqual;\ndeprecated(\"import std.digest instead of std.digest.digest. std.digest.digest will be removed in 2.084\")\nalias LetterCase = _newDigest.LetterCase;\n"
  },
  {
    "path": "libphobos/src/std/digest/hmac.d",
    "content": "// Written in the D programming language.\n\n/**\nThis package implements the hash-based message authentication code (_HMAC)\nalgorithm as defined in $(HTTP tools.ietf.org/html/rfc2104, RFC2104). See also\nthe corresponding $(HTTP en.wikipedia.org/wiki/Hash-based_message_authentication_code, Wikipedia article).\n\n$(SCRIPT inhibitQuickIndex = 1;)\n\nMacros:\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nSource: $(PHOBOSSRC std/digest/hmac.d)\n */\n\nmodule std.digest.hmac;\n\nimport std.digest : isDigest, hasBlockSize, isDigestibleRange, DigestType;\nimport std.meta : allSatisfy;\n\n@safe:\n\n/**\n * Template API HMAC implementation.\n *\n * This implements an _HMAC over the digest H. If H doesn't provide\n * information about the block size, it can be supplied explicitly using\n * the second overload.\n *\n * This type conforms to $(REF isDigest, std,digest).\n */\n\n/// Compute HMAC over an input string\n@safe unittest\n{\n    import std.ascii : LetterCase;\n    import std.digest : toHexString;\n    import std.digest.sha : SHA1;\n    import std.string : representation;\n\n    auto secret = \"secret\".representation;\n    assert(\"The quick brown fox jumps over the lazy dog\"\n            .representation\n            .hmac!SHA1(secret)\n            .toHexString!(LetterCase.lower) == \"198ea1ea04c435c1246b586a06d5cf11c3ffcda6\");\n}\n\ntemplate HMAC(H)\nif (isDigest!H && hasBlockSize!H)\n{\n    alias HMAC = HMAC!(H, H.blockSize);\n}\n\n/**\n * Overload of HMAC to be used if H doesn't provide information about its\n * block size.\n */\n\nstruct HMAC(H, size_t hashBlockSize)\nif (hashBlockSize % 8 == 0)\n{\n    enum blockSize = hashBlockSize;\n\n    private H digest;\n    private ubyte[blockSize / 8] key;\n\n    /**\n     * Constructs the HMAC digest using the specified secret.\n     */\n\n    this(scope const(ubyte)[] secret)\n    {\n        // if secret is too long, shorten it by computing its hash\n        typeof(digest.finish()) buffer = void;\n        if (secret.length > blockSize / 8)\n        {\n            digest.start();\n            digest.put(secret);\n            buffer = digest.finish();\n            secret = buffer[];\n        }\n\n        // if secret is too short, it will be padded with zeroes\n        // (the key buffer is already zero-initialized)\n        import std.algorithm.mutation : copy;\n        secret.copy(key[]);\n\n        start();\n    }\n\n    ///\n    @safe pure nothrow @nogc unittest\n    {\n        import std.digest.sha : SHA1;\n        import std.string : representation;\n        auto hmac = HMAC!SHA1(\"My s3cR3T keY\".representation);\n        hmac.put(\"Hello, world\".representation);\n        static immutable expected = [\n            130, 32, 235, 44, 208, 141,\n            150, 232, 211, 214, 162, 195,\n            188, 127, 52, 89, 100, 68, 90, 216];\n        assert(hmac.finish() == expected);\n    }\n\n    /**\n     * Reinitializes the digest, making it ready for reuse.\n     *\n     * Note:\n     * The constructor leaves the digest in an initialized state, so that this\n     * method only needs to be called if an unfinished digest is to be reused.\n     *\n     * Returns:\n     * A reference to the digest for convenient chaining.\n     */\n\n    ref HMAC!(H, blockSize) start() return\n    {\n        ubyte[blockSize / 8] ipad = void;\n        foreach (immutable i; 0 .. blockSize / 8)\n            ipad[i] = key[i] ^ 0x36;\n\n        digest.start();\n        digest.put(ipad[]);\n\n        return this;\n    }\n\n    ///\n    @safe pure nothrow @nogc unittest\n    {\n        import std.digest.sha : SHA1;\n        import std.string : representation;\n        string data1 = \"Hello, world\", data2 = \"Hola mundo\";\n        auto hmac = HMAC!SHA1(\"My s3cR3T keY\".representation);\n        hmac.put(data1.representation);\n        hmac.start();                   // reset digest\n        hmac.put(data2.representation); // start over\n        static immutable expected = [\n            122, 151, 232, 240, 249, 80,\n            19, 178, 186, 77, 110, 23, 208,\n            52, 11, 88, 34, 151, 192, 255];\n        assert(hmac.finish() == expected);\n    }\n\n    /**\n     * Feeds a piece of data into the hash computation. This method allows the\n     * type to be used as an $(REF OutputRange, std,range).\n     *\n     * Returns:\n     * A reference to the digest for convenient chaining.\n     */\n\n    ref HMAC!(H, blockSize) put(in ubyte[] data...) return\n    {\n        digest.put(data);\n        return this;\n    }\n\n    ///\n    @safe pure nothrow @nogc unittest\n    {\n        import std.digest.hmac, std.digest.sha;\n        import std.string : representation;\n        string data1 = \"Hello, world\", data2 = \"Hola mundo\";\n        auto hmac = HMAC!SHA1(\"My s3cR3T keY\".representation);\n        hmac.put(data1.representation)\n            .put(data2.representation);\n        static immutable expected = [\n            197, 57, 52, 3, 13, 194, 13,\n            36, 117, 228, 8, 11, 111, 51,\n            165, 3, 123, 31, 251, 113];\n        assert(hmac.finish() == expected);\n    }\n\n    /**\n     * Resets the digest and returns the finished hash.\n     */\n\n    DigestType!H finish()\n    {\n        ubyte[blockSize / 8] opad = void;\n        foreach (immutable i; 0 .. blockSize / 8)\n            opad[i] = key[i] ^ 0x5c;\n\n        auto tmp = digest.finish();\n\n        digest.start();\n        digest.put(opad[]);\n        digest.put(tmp);\n        auto result = digest.finish();\n        start();    // reset the digest\n        return result;\n    }\n\n    ///\n    @safe pure nothrow @nogc unittest\n    {\n        import std.digest.sha : SHA1;\n        import std.string : representation;\n        string data1 = \"Hello, world\", data2 = \"Hola mundo\";\n        auto hmac = HMAC!SHA1(\"My s3cR3T keY\".representation);\n        auto digest = hmac.put(data1.representation)\n                          .put(data2.representation)\n                          .finish();\n        static immutable expected = [\n            197, 57, 52, 3, 13, 194, 13,\n            36, 117, 228, 8, 11, 111, 51,\n            165, 3, 123, 31, 251, 113];\n        assert(digest == expected);\n    }\n}\n\n/// ditto\ntemplate hmac(H)\nif (isDigest!H && hasBlockSize!H)\n{\n    alias hmac = hmac!(H, H.blockSize);\n}\n\n/// ditto\ntemplate hmac(H, size_t blockSize)\nif (isDigest!H)\n{\n    /**\n     * Constructs an HMAC digest with the specified secret.\n     *\n     * Returns:\n     * An instance of HMAC that can be fed data as desired, and finished\n     * to compute the final hash when done.\n     */\n    auto hmac(scope const(ubyte)[] secret)\n    {\n        return HMAC!(H, blockSize)(secret);\n    }\n\n    ///\n    @safe pure nothrow @nogc unittest\n    {\n        import std.digest.sha : SHA1;\n        import std.string : representation;\n        string data1 = \"Hello, world\", data2 = \"Hola mundo\";\n        auto digest = hmac!SHA1(\"My s3cR3T keY\".representation)\n                          .put(data1.representation)\n                          .put(data2.representation)\n                          .finish();\n        static immutable expected = [\n            197, 57, 52, 3, 13, 194, 13, 36,\n            117, 228, 8, 11, 111, 51, 165,\n            3, 123, 31, 251, 113];\n        assert(digest == expected);\n    }\n\n    /**\n     * Computes an _HMAC digest over the given range of data with the\n     * specified secret.\n     *\n     * Returns:\n     * The final _HMAC hash.\n     */\n    DigestType!H hmac(T...)(scope T data, scope const(ubyte)[] secret)\n    if (allSatisfy!(isDigestibleRange, typeof(data)))\n    {\n        import std.range.primitives : put;\n        auto hash = HMAC!(H, blockSize)(secret);\n        foreach (datum; data)\n            put(hash, datum);\n        return hash.finish();\n    }\n\n    ///\n    @safe pure nothrow @nogc unittest\n    {\n        import std.algorithm.iteration : map;\n        import std.digest.sha : SHA1;\n        import std.string : representation;\n        string data = \"Hello, world\";\n        auto digest = data.representation\n                      .map!(a => cast(ubyte)(a+1))\n                      .hmac!SHA1(\"My s3cR3T keY\".representation);\n        static assert(is(typeof(digest) == ubyte[20]));\n        static immutable expected = [\n            163, 208, 118, 179, 216, 93,\n            17, 10, 84, 200, 87, 104, 244,\n            111, 136, 214, 167, 210, 58, 10];\n        assert(digest == expected);\n    }\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    import std.digest.sha : SHA1;\n    import std.string : representation;\n    string data1 = \"Hello, world\", data2 = \"Hola mundo\";\n    auto hmac = HMAC!SHA1(\"My s3cR3T keY\".representation);\n    auto digest = hmac.put(data1.representation)\n                      .put(data2.representation)\n                      .finish();\n    static immutable expected = [\n        197, 57, 52, 3, 13, 194, 13,\n        36, 117, 228, 8, 11, 111, 51,\n        165, 3, 123, 31, 251, 113];\n    assert(digest == expected);\n}\n\n@safe pure nothrow @nogc\nunittest\n{\n    import std.digest.md : MD5;\n    import std.range : isOutputRange;\n    static assert(isOutputRange!(HMAC!MD5, ubyte));\n    static assert(isDigest!(HMAC!MD5));\n    static assert(hasBlockSize!(HMAC!MD5) && HMAC!MD5.blockSize == MD5.blockSize);\n}\n\n@safe pure nothrow\nunittest\n{\n    import std.digest.md : MD5;\n    import std.digest.sha : SHA1, SHA256;\n\n    // Note, can't be UFCS because we don't want to import inside\n    // version (unittest).\n    import std.digest : toHexString, LetterCase;\n    alias hex = toHexString!(LetterCase.lower);\n\n    ubyte[] nada;\n    assert(hex(hmac!MD5   (nada, nada)) == \"74e6f7298a9c2d168935f58c001bad88\");\n    assert(hex(hmac!SHA1  (nada, nada)) == \"fbdb1d1b18aa6c08324b7d64b71fb76370690e1d\");\n    assert(hex(hmac!SHA256(nada, nada)) == \"b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad\");\n\n    import std.string : representation;\n    auto key      = \"key\".representation,\n         long_key = (\"012345678901234567890123456789012345678901\"\n            ~\"234567890123456789012345678901234567890123456789\").representation,\n         data1    = \"The quick brown fox \".representation,\n         data2    = \"jumps over the lazy dog\".representation,\n         data     = data1 ~ data2;\n\n    assert(hex(data.hmac!MD5   (key)) == \"80070713463e7749b90c2dc24911e275\");\n    assert(hex(data.hmac!SHA1  (key)) == \"de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9\");\n    assert(hex(data.hmac!SHA256(key)) == \"f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8\");\n\n    assert(hex(data.hmac!MD5   (long_key)) == \"e1728d68e05beae186ea768561963778\");\n    assert(hex(data.hmac!SHA1  (long_key)) == \"560d3cd77316e57ab4bba0c186966200d2b37ba3\");\n    assert(hex(data.hmac!SHA256(long_key)) == \"a1b0065a5d1edd93152c677e1bc1b1e3bc70d3a76619842e7f733f02b8135c04\");\n\n    assert(hmac!MD5   (key).put(data1).put(data2).finish == data.hmac!MD5   (key));\n    assert(hmac!SHA1  (key).put(data1).put(data2).finish == data.hmac!SHA1  (key));\n    assert(hmac!SHA256(key).put(data1).put(data2).finish == data.hmac!SHA256(key));\n}\n"
  },
  {
    "path": "libphobos/src/std/digest/md.d",
    "content": "/**\n * Computes MD5 hashes of arbitrary data. MD5 hashes are 16 byte quantities that are like a\n * checksum or CRC, but are more robust.\n *\n$(SCRIPT inhibitQuickIndex = 1;)\n\n$(DIVC quickindex,\n$(BOOKTABLE ,\n$(TR $(TH Category) $(TH Functions)\n)\n$(TR $(TDNW Template API) $(TD $(MYREF MD5)\n)\n)\n$(TR $(TDNW OOP API) $(TD $(MYREF MD5Digest))\n)\n$(TR $(TDNW Helpers) $(TD $(MYREF md5Of))\n)\n)\n)\n\n * This module conforms to the APIs defined in `std.digest`. To understand the\n * differences between the template and the OOP API, see $(MREF std, digest).\n *\n * This module publicly imports $(MREF std, digest) and can be used as a stand-alone\n * module.\n *\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n *\n * CTFE:\n * Digests do not work in CTFE\n *\n * Authors:\n * Piotr Szturmaj, Kai Nacke, Johannes Pfau $(BR)\n * The routines and algorithms are derived from the $(I RSA Data Security, Inc. MD5 Message-Digest Algorithm).\n *\n * References:\n *      $(LINK2 http://en.wikipedia.org/wiki/Md5, Wikipedia on MD5)\n *\n * Source: $(PHOBOSSRC std/digest/md.d)\n *\n */\n\n/* md5.d - RSA Data Security, Inc., MD5 message-digest algorithm\n * Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm.\n */\nmodule std.digest.md;\n\npublic import std.digest;\n\n///\n@safe unittest\n{\n    //Template API\n    import std.digest.md;\n\n    //Feeding data\n    ubyte[1024] data;\n    MD5 md5;\n    md5.start();\n    md5.put(data[]);\n    md5.start(); //Start again\n    md5.put(data[]);\n    auto hash = md5.finish();\n}\n\n///\n@safe unittest\n{\n    //OOP API\n    import std.digest.md;\n\n    auto md5 = new MD5Digest();\n    ubyte[] hash = md5.digest(\"abc\");\n    assert(toHexString(hash) == \"900150983CD24FB0D6963F7D28E17F72\");\n\n    //Feeding data\n    ubyte[1024] data;\n    md5.put(data[]);\n    md5.reset(); //Start again\n    md5.put(data[]);\n    hash = md5.finish();\n}\n\n//rotateLeft rotates x left n bits\nprivate uint rotateLeft(uint x, uint n) @safe pure nothrow @nogc\n{\n    // With recently added optimization to DMD (commit 32ea0206 at 07/28/11), this is translated to rol.\n    // No assembler required.\n    return (x << n) | (x >> (32-n));\n}\n\n/**\n * Template API MD5 implementation.\n * See `std.digest` for differences between template and OOP API.\n */\nstruct MD5\n{\n    private:\n        // magic initialization constants\n        uint[4] _state = [0x67452301,0xefcdab89,0x98badcfe,0x10325476]; // state (ABCD)\n        ulong _count; //number of bits, modulo 2^64\n        ubyte[64] _buffer; // input buffer\n\n        static immutable ubyte[64] _padding =\n        [\n          0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n        ];\n\n        // F, G, H and I are basic MD5 functions\n        static @safe pure nothrow @nogc\n        {\n            uint F(uint x, uint y, uint z) { return (x & y) | (~x & z); }\n            uint G(uint x, uint y, uint z) { return (x & z) | (y & ~z); }\n            uint H(uint x, uint y, uint z) { return x ^ y ^ z; }\n            uint I(uint x, uint y, uint z) { return y ^ (x | ~z); }\n        }\n\n\n        /*\n         * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.\n         * Rotation is separate from addition to prevent recomputation.\n         */\n        static void FF(ref uint a, uint b, uint c, uint d, uint x, uint s, uint ac)\n            @safe pure nothrow @nogc\n        {\n            a += F (b, c, d) + x + ac;\n            a = rotateLeft(a, s);\n            a += b;\n        }\n\n        static void GG(ref uint a, uint b, uint c, uint d, uint x, uint s, uint ac)\n            @safe pure nothrow @nogc\n        {\n            a += G (b, c, d) + x + ac;\n            a = rotateLeft(a, s);\n            a += b;\n        }\n\n        static void HH(ref uint a, uint b, uint c, uint d, uint x, uint s, uint ac)\n            @safe pure nothrow @nogc\n        {\n            a += H (b, c, d) + x + ac;\n            a = rotateLeft(a, s);\n            a += b;\n        }\n\n        static void II(ref uint a, uint b, uint c, uint d, uint x, uint s, uint ac)\n            @safe pure nothrow @nogc\n        {\n            a += I (b, c, d) + x + ac;\n            a = rotateLeft(a, s);\n            a += b;\n        }\n\n        /*\n         * MD5 basic transformation. Transforms state based on block.\n         */\n\n        //Constants for MD5Transform routine.\n        enum\n        {\n            S11 = 7,\n            S12 = 12,\n            S13 = 17,\n            S14 = 22,\n            S21 = 5,\n            S22 = 9,\n            S23 = 14,\n            S24 = 20,\n            S31 = 4,\n            S32 = 11,\n            S33 = 16,\n            S34 = 23,\n            S41 = 6,\n            S42 = 10,\n            S43 = 15,\n            S44 = 21,\n        }\n\n        private void transform(const(ubyte[64])* block) pure nothrow @nogc\n        {\n            uint a = _state[0],\n                 b = _state[1],\n                 c = _state[2],\n                 d = _state[3];\n\n            uint[16] x = void;\n\n            version (BigEndian)\n            {\n                import std.bitmanip : littleEndianToNative;\n\n                for (size_t i = 0; i < 16; i++)\n                {\n                    x[i] = littleEndianToNative!uint(*cast(ubyte[4]*)&(*block)[i*4]);\n                }\n            }\n            else\n            {\n                (cast(ubyte*) x.ptr)[0 .. 64] = (cast(ubyte*) block)[0 .. 64];\n            }\n\n            //Round 1\n            FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */\n            FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */\n            FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */\n            FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */\n            FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */\n            FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */\n            FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */\n            FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */\n            FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */\n            FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */\n            FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */\n            FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */\n            FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */\n            FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */\n            FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */\n            FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */\n\n            //Round 2\n            GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */\n            GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */\n            GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */\n            GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */\n            GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */\n            GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */\n            GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */\n            GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */\n            GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */\n            GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */\n            GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */\n            GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */\n            GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */\n            GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */\n            GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */\n            GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */\n\n            //Round 3\n            HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */\n            HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */\n            HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */\n            HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */\n            HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */\n            HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */\n            HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */\n            HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */\n            HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */\n            HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */\n            HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */\n            HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */\n            HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */\n            HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */\n            HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */\n            HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */\n\n            //Round 4\n            II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */\n            II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */\n            II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */\n            II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */\n            II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */\n            II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */\n            II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */\n            II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */\n            II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */\n            II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */\n            II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */\n            II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */\n            II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */\n            II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */\n            II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */\n            II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */\n\n            _state[0] += a;\n            _state[1] += b;\n            _state[2] += c;\n            _state[3] += d;\n\n            //Zeroize sensitive information.\n            x[] = 0;\n        }\n\n    public:\n        enum blockSize = 512;\n\n        /**\n         * Use this to feed the digest with data.\n         * Also implements the $(REF isOutputRange, std,range,primitives)\n         * interface for `ubyte` and `const(ubyte)[]`.\n         *\n         * Example:\n         * ----\n         * MD5 dig;\n         * dig.put(cast(ubyte) 0); //single ubyte\n         * dig.put(cast(ubyte) 0, cast(ubyte) 0); //variadic\n         * ubyte[10] buf;\n         * dig.put(buf); //buffer\n         * ----\n         */\n        void put(scope const(ubyte)[] data...) @trusted pure nothrow @nogc\n        {\n            uint i, index, partLen;\n            auto inputLen = data.length;\n\n            //Compute number of bytes mod 64\n            index = (cast(uint)_count >> 3) & (64 - 1);\n\n            //Update number of bits\n            _count += inputLen * 8;\n\n            partLen = 64 - index;\n\n            //Transform as many times as possible\n            if (inputLen >= partLen)\n            {\n                (&_buffer[index])[0 .. partLen] = data.ptr[0 .. partLen];\n                transform(&_buffer);\n\n                for (i = partLen; i + 63 < inputLen; i += 64)\n                {\n                    transform(cast(const(ubyte[64])*)(data[i .. i + 64].ptr));\n                }\n\n                index = 0;\n            }\n            else\n            {\n                i = 0;\n            }\n\n            /* Buffer remaining input */\n            if (inputLen - i)\n                (&_buffer[index])[0 .. inputLen-i] = (&data[i])[0 .. inputLen-i];\n        }\n\n        /**\n         * Used to (re)initialize the MD5 digest.\n         *\n         * Note:\n         * For this MD5 Digest implementation calling start after default construction\n         * is not necessary. Calling start is only necessary to reset the Digest.\n         *\n         * Generic code which deals with different Digest types should always call start though.\n         *\n         * Example:\n         * --------\n         * MD5 digest;\n         * //digest.start(); //Not necessary\n         * digest.put(0);\n         * --------\n         */\n        void start() @safe pure nothrow @nogc\n        {\n            this = MD5.init;\n        }\n\n        /**\n         * Returns the finished MD5 hash. This also calls $(LREF start) to\n         * reset the internal state.\n          */\n        ubyte[16] finish() @trusted pure nothrow @nogc\n        {\n            import std.bitmanip : nativeToLittleEndian;\n\n            ubyte[16] data = void;\n            ubyte[8] bits = void;\n            uint index, padLen;\n\n            //Save number of bits\n            bits[0 .. 8] = nativeToLittleEndian(_count)[];\n\n            //Pad out to 56 mod 64\n            index = (cast(uint)_count >> 3) & (64 - 1);\n            padLen = (index < 56) ? (56 - index) : (120 - index);\n            put(_padding[0 .. padLen]);\n\n            //Append length (before padding)\n            put(bits);\n\n            //Store state in digest\n            data[0 .. 4]   = nativeToLittleEndian(_state[0])[];\n            data[4 .. 8]   = nativeToLittleEndian(_state[1])[];\n            data[8 .. 12]  = nativeToLittleEndian(_state[2])[];\n            data[12 .. 16] = nativeToLittleEndian(_state[3])[];\n\n            /* Zeroize sensitive information. */\n            start();\n            return data;\n        }\n        ///\n        @safe unittest\n        {\n            //Simple example\n            MD5 hash;\n            hash.start();\n            hash.put(cast(ubyte) 0);\n            ubyte[16] result = hash.finish();\n        }\n}\n\n///\n@safe unittest\n{\n    //Simple example, hashing a string using md5Of helper function\n    ubyte[16] hash = md5Of(\"abc\");\n    //Let's get a hash string\n    assert(toHexString(hash) == \"900150983CD24FB0D6963F7D28E17F72\");\n}\n\n///\n@safe unittest\n{\n    //Using the basic API\n    MD5 hash;\n    hash.start();\n    ubyte[1024] data;\n    //Initialize data here...\n    hash.put(data);\n    ubyte[16] result = hash.finish();\n}\n\n///\n@safe unittest\n{\n    //Let's use the template features:\n    void doSomething(T)(ref T hash)\n    if (isDigest!T)\n    {\n        hash.put(cast(ubyte) 0);\n    }\n    MD5 md5;\n    md5.start();\n    doSomething(md5);\n    assert(toHexString(md5.finish()) == \"93B885ADFE0DA089CDF634904FD59F71\");\n}\n\n@safe unittest\n{\n    assert(isDigest!MD5);\n}\n\n@system unittest\n{\n    import std.range;\n    import std.conv : hexString;\n\n    ubyte[16] digest;\n\n    MD5 md5;\n    md5.put(cast(ubyte[])\"abcdef\");\n    md5.start();\n    md5.put(cast(ubyte[])\"\");\n    assert(md5.finish() == cast(ubyte[]) hexString!\"d41d8cd98f00b204e9800998ecf8427e\");\n\n    digest = md5Of(\"\");\n    assert(digest == cast(ubyte[]) hexString!\"d41d8cd98f00b204e9800998ecf8427e\");\n\n    digest = md5Of(\"a\");\n    assert(digest == cast(ubyte[]) hexString!\"0cc175b9c0f1b6a831c399e269772661\");\n\n    digest = md5Of(\"abc\");\n    assert(digest == cast(ubyte[]) hexString!\"900150983cd24fb0d6963f7d28e17f72\");\n\n    digest = md5Of(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    assert(digest == cast(ubyte[]) hexString!\"8215ef0796a20bcaaae116d3876c664a\");\n\n    digest = md5Of(\"message digest\");\n    assert(digest == cast(ubyte[]) hexString!\"f96b697d7cb7938d525a2f31aaf161d0\");\n\n    digest = md5Of(\"abcdefghijklmnopqrstuvwxyz\");\n    assert(digest == cast(ubyte[]) hexString!\"c3fcd3d76192e4007dfb496cca67e13b\");\n\n    digest = md5Of(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    assert(digest == cast(ubyte[]) hexString!\"d174ab98d277d9f5a5611c2c9f419d9f\");\n\n    digest = md5Of(\"1234567890123456789012345678901234567890\"~\n                    \"1234567890123456789012345678901234567890\");\n    assert(digest == cast(ubyte[]) hexString!\"57edf4a22be3c955ac49da2e2107b67a\");\n\n    enum ubyte[16] input = cast(ubyte[16]) hexString!\"c3fcd3d76192e4007dfb496cca67e13b\";\n    assert(toHexString(input)\n        == \"C3FCD3D76192E4007DFB496CCA67E13B\");\n\n    ubyte[] onemilliona = new ubyte[1000000];\n    onemilliona[] = 'a';\n    digest = md5Of(onemilliona);\n    assert(digest == cast(ubyte[]) hexString!\"7707D6AE4E027C70EEA2A935C2296F21\");\n\n    auto oneMillionRange = repeat!ubyte(cast(ubyte)'a', 1000000);\n    digest = md5Of(oneMillionRange);\n    assert(digest == cast(ubyte[]) hexString!\"7707D6AE4E027C70EEA2A935C2296F21\");\n}\n\n/**\n * This is a convenience alias for $(REF digest, std,digest) using the\n * MD5 implementation.\n */\n//simple alias doesn't work here, hope this gets inlined...\nauto md5Of(T...)(T data)\n{\n    return digest!(MD5, T)(data);\n}\n\n///\n@safe unittest\n{\n    ubyte[16] hash = md5Of(\"abc\");\n    assert(hash == digest!MD5(\"abc\"));\n}\n\n/**\n * OOP API MD5 implementation.\n * See `std.digest` for differences between template and OOP API.\n *\n * This is an alias for $(D $(REF WrapperDigest, std,digest)!MD5), see\n * there for more information.\n */\nalias MD5Digest = WrapperDigest!MD5;\n\n///\n@safe unittest\n{\n    //Simple example, hashing a string using Digest.digest helper function\n    auto md5 = new MD5Digest();\n    ubyte[] hash = md5.digest(\"abc\");\n    //Let's get a hash string\n    assert(toHexString(hash) == \"900150983CD24FB0D6963F7D28E17F72\");\n}\n\n///\n@system unittest\n{\n     //Let's use the OOP features:\n    void test(Digest dig)\n    {\n      dig.put(cast(ubyte) 0);\n    }\n    auto md5 = new MD5Digest();\n    test(md5);\n\n    //Let's use a custom buffer:\n    ubyte[16] buf;\n    ubyte[] result = md5.finish(buf[]);\n    assert(toHexString(result) == \"93B885ADFE0DA089CDF634904FD59F71\");\n}\n\n@system unittest\n{\n    import std.conv : hexString;\n    auto md5 = new MD5Digest();\n\n    md5.put(cast(ubyte[])\"abcdef\");\n    md5.reset();\n    md5.put(cast(ubyte[])\"\");\n    assert(md5.finish() == cast(ubyte[]) hexString!\"d41d8cd98f00b204e9800998ecf8427e\");\n\n    md5.put(cast(ubyte[])\"abcdefghijklmnopqrstuvwxyz\");\n    ubyte[20] result;\n    auto result2 = md5.finish(result[]);\n    assert(result[0 .. 16] == result2 && result2 == cast(ubyte[]) hexString!\"c3fcd3d76192e4007dfb496cca67e13b\");\n\n    debug\n    {\n        import std.exception;\n        assertThrown!Error(md5.finish(result[0 .. 15]));\n    }\n\n    assert(md5.length == 16);\n\n    assert(md5.digest(\"\") == cast(ubyte[]) hexString!\"d41d8cd98f00b204e9800998ecf8427e\");\n\n    assert(md5.digest(\"a\") == cast(ubyte[]) hexString!\"0cc175b9c0f1b6a831c399e269772661\");\n\n    assert(md5.digest(\"abc\") == cast(ubyte[]) hexString!\"900150983cd24fb0d6963f7d28e17f72\");\n\n    assert(md5.digest(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\")\n           == cast(ubyte[]) hexString!\"8215ef0796a20bcaaae116d3876c664a\");\n\n    assert(md5.digest(\"message digest\") == cast(ubyte[]) hexString!\"f96b697d7cb7938d525a2f31aaf161d0\");\n\n    assert(md5.digest(\"abcdefghijklmnopqrstuvwxyz\")\n           == cast(ubyte[]) hexString!\"c3fcd3d76192e4007dfb496cca67e13b\");\n\n    assert(md5.digest(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\")\n           == cast(ubyte[]) hexString!\"d174ab98d277d9f5a5611c2c9f419d9f\");\n\n    assert(md5.digest(\"1234567890123456789012345678901234567890\",\n                                   \"1234567890123456789012345678901234567890\")\n           == cast(ubyte[]) hexString!\"57edf4a22be3c955ac49da2e2107b67a\");\n}\n"
  },
  {
    "path": "libphobos/src/std/digest/murmurhash.d",
    "content": "/**\nComputes $(LINK2 https://en.wikipedia.org/wiki/MurmurHash, MurmurHash) hashes\nof arbitrary data. MurmurHash is a non-cryptographic hash function suitable\nfor general hash-based lookup. It is optimized for x86 but can be used on\nall architectures.\n\nThe current version is MurmurHash3, which yields a 32-bit or 128-bit hash value.\nThe older MurmurHash 1 and 2 are currently not supported.\n\nMurmurHash3 comes in three flavors, listed in increasing order of throughput:\n$(UL\n$(LI `MurmurHash3!32` produces a 32-bit value and is optimized for 32-bit architectures)\n$(LI $(D MurmurHash3!(128, 32)) produces a 128-bit value and is optimized for 32-bit architectures)\n$(LI $(D MurmurHash3!(128, 64)) produces a 128-bit value and is optimized for 64-bit architectures)\n)\n\nNote:\n$(UL\n$(LI $(D MurmurHash3!(128, 32)) and $(D MurmurHash3!(128, 64)) produce different values.)\n$(LI The current implementation is optimized for little endian architectures.\n  It will exhibit different results on big endian architectures and a slightly\n  less uniform distribution.)\n)\n\nThis module conforms to the APIs defined in $(MREF std, digest).\n\nThis module publicly imports $(MREF std, digest) and can be used as a stand-alone module.\n\nSource: $(PHOBOSSRC std/digest/murmurhash.d)\nLicense: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors: Guillaume Chatelet\nReferences: $(LINK2 https://github.com/aappleby/smhasher, Reference implementation)\n$(BR) $(LINK2 https://en.wikipedia.org/wiki/MurmurHash, Wikipedia)\n*/\n/* Copyright Guillaume Chatelet 2016.\n * Distributed under the Boost Software License, Version 1.0.\n * (See LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.digest.murmurhash;\n\nversion (X86)\n    version = HaveUnalignedLoads;\nelse version (X86_64)\n    version = HaveUnalignedLoads;\n\n///\n@safe unittest\n{\n    // MurmurHash3!32, MurmurHash3!(128, 32) and MurmurHash3!(128, 64) implement\n    // the std.digest Template API.\n    static assert(isDigest!(MurmurHash3!32));\n    // The convenient digest template allows for quick hashing of any data.\n    ubyte[4] hashed = digest!(MurmurHash3!32)([1, 2, 3, 4]);\n    assert(hashed == [0, 173, 69, 68]);\n}\n\n///\n@safe unittest\n{\n    // One can also hash ubyte data piecewise by instanciating a hasher and call\n    // the 'put' method.\n    const(ubyte)[] data1 = [1, 2, 3];\n    const(ubyte)[] data2 = [4, 5, 6, 7];\n    // The incoming data will be buffered and hashed element by element.\n    MurmurHash3!32 hasher;\n    hasher.put(data1);\n    hasher.put(data2);\n    // The call to 'finish' ensures:\n    // - the remaining bits are processed\n    // - the hash gets finalized\n    auto hashed = hasher.finish();\n    assert(hashed == [181, 151, 88, 252]);\n}\n\n///\n@safe unittest\n{\n    // Using `putElements`, `putRemainder` and `finalize` you gain full\n    // control over which part of the algorithm to run.\n    // This allows for maximum throughput but needs extra care.\n\n    // Data type must be the same as the hasher's element type:\n    // - uint for MurmurHash3!32\n    // - uint[4] for MurmurHash3!(128, 32)\n    // - ulong[2] for MurmurHash3!(128, 64)\n    const(uint)[] data = [1, 2, 3, 4];\n    // Note the hasher starts with 'Fast'.\n    MurmurHash3!32 hasher;\n    // Push as many array of elements as you need. The less calls the better.\n    hasher.putElements(data);\n    // Put remainder bytes if needed. This method can be called only once.\n    hasher.putRemainder(ubyte(1), ubyte(1), ubyte(1));\n    // Call finalize to incorporate data length in the hash.\n    hasher.finalize();\n    // Finally get the hashed value.\n    auto hashed = hasher.getBytes();\n    assert(hashed == [188, 165, 108, 2]);\n}\n\npublic import std.digest;\n\n@safe:\n\n/*\nPerformance notes:\n - To help a bit with the performance when compiling with DMD some\n   functions have been rewritten to pass by value instead of by reference.\n - GDC and LDC are on par with their C++ counterpart.\n - DMD is typically between 20% to 50% of the GCC version.\n*/\n\n/++\n + Implements the MurmurHash3 functions. You can specify the `size` of the\n + hash in bit. For 128 bit hashes you can specify whether to optimize for 32\n + or 64 bit architectures. If you don't specify the `opt` value it will select\n + the fastest version of the host platform.\n +\n + This hasher is compatible with the `Digest` API:\n + $(UL\n + $(LI `void start()`)\n + $(LI `void put(scope const(ubyte)[] data...)`)\n + $(LI `ubyte[Element.sizeof] finish()`)\n + )\n +\n + It also provides a faster, low level API working with data of size\n + `Element.sizeof`:\n + $(UL\n + $(LI `void putElements(scope const(Element[]) elements...)`)\n + $(LI `void putRemainder(scope const(ubyte[]) data...)`)\n + $(LI `void finalize()`)\n + $(LI `Element get()`)\n + $(LI `ubyte[Element.sizeof] getBytes()`)\n + )\n +/\nstruct MurmurHash3(uint size /* 32 or 128 */ , uint opt = size_t.sizeof == 8 ? 64 : 32)\n{\n    enum blockSize = size; // Number of bits of the hashed value.\n    size_t element_count; // The number of full elements pushed, this is used for finalization.\n\n    static if (size == 32)\n    {\n        private enum uint c1 = 0xcc9e2d51;\n        private enum uint c2 = 0x1b873593;\n        private uint h1;\n        alias Element = uint; /// The element type for 32-bit implementation.\n\n        this(uint seed)\n        {\n            h1 = seed;\n        }\n        /++\n        Adds a single Element of data without increasing `element_count`.\n        Make sure to increase `element_count` by `Element.sizeof` for each call to `putElement`.\n        +/\n        void putElement(uint block) pure nothrow @nogc\n        {\n            h1 = update(h1, block, 0, c1, c2, 15, 13, 0xe6546b64U);\n        }\n\n        /// Put remainder bytes. This must be called only once after `putElement` and before `finalize`.\n        void putRemainder(scope const(ubyte[]) data...) pure nothrow @nogc\n        {\n            assert(data.length < Element.sizeof);\n            assert(data.length >= 0);\n            element_count += data.length;\n            uint k1 = 0;\n            final switch (data.length & 3)\n            {\n            case 3:\n                k1 ^= data[2] << 16;\n                goto case;\n            case 2:\n                k1 ^= data[1] << 8;\n                goto case;\n            case 1:\n                k1 ^= data[0];\n                h1 ^= shuffle(k1, c1, c2, 15);\n                goto case;\n            case 0:\n            }\n        }\n\n        /// Incorporate `element_count` and finalizes the hash.\n        void finalize() pure nothrow @nogc\n        {\n            h1 ^= element_count;\n            h1 = fmix(h1);\n        }\n\n        /// Returns the hash as an uint value.\n        Element get() pure nothrow @nogc\n        {\n            return h1;\n        }\n\n        /// Returns the current hashed value as an ubyte array.\n        ubyte[4] getBytes() pure nothrow @nogc\n        {\n            return cast(typeof(return)) cast(uint[1])[get()];\n        }\n    }\n    else static if (size == 128 && opt == 32)\n    {\n        private enum uint c1 = 0x239b961b;\n        private enum uint c2 = 0xab0e9789;\n        private enum uint c3 = 0x38b34ae5;\n        private enum uint c4 = 0xa1e38b93;\n        private uint h4, h3, h2, h1;\n\n        alias Element = uint[4]; /// The element type for 128-bit implementation.\n\n        this(uint seed4, uint seed3, uint seed2, uint seed1) pure nothrow @nogc\n        {\n            h4 = seed4;\n            h3 = seed3;\n            h2 = seed2;\n            h1 = seed1;\n        }\n\n        this(uint seed) pure nothrow @nogc\n        {\n            h4 = h3 = h2 = h1 = seed;\n        }\n\n        /++\n        Adds a single Element of data without increasing element_count.\n        Make sure to increase `element_count` by `Element.sizeof` for each call to `putElement`.\n        +/\n        void putElement(Element block) pure nothrow @nogc\n        {\n            h1 = update(h1, block[0], h2, c1, c2, 15, 19, 0x561ccd1bU);\n            h2 = update(h2, block[1], h3, c2, c3, 16, 17, 0x0bcaa747U);\n            h3 = update(h3, block[2], h4, c3, c4, 17, 15, 0x96cd1c35U);\n            h4 = update(h4, block[3], h1, c4, c1, 18, 13, 0x32ac3b17U);\n        }\n\n        /// Put remainder bytes. This must be called only once after `putElement` and before `finalize`.\n        void putRemainder(scope const(ubyte[]) data...) pure nothrow @nogc\n        {\n            assert(data.length < Element.sizeof);\n            assert(data.length >= 0);\n            element_count += data.length;\n            uint k1 = 0;\n            uint k2 = 0;\n            uint k3 = 0;\n            uint k4 = 0;\n\n            final switch (data.length & 15)\n            {\n            case 15:\n                k4 ^= data[14] << 16;\n                goto case;\n            case 14:\n                k4 ^= data[13] << 8;\n                goto case;\n            case 13:\n                k4 ^= data[12] << 0;\n                h4 ^= shuffle(k4, c4, c1, 18);\n                goto case;\n            case 12:\n                k3 ^= data[11] << 24;\n                goto case;\n            case 11:\n                k3 ^= data[10] << 16;\n                goto case;\n            case 10:\n                k3 ^= data[9] << 8;\n                goto case;\n            case 9:\n                k3 ^= data[8] << 0;\n                h3 ^= shuffle(k3, c3, c4, 17);\n                goto case;\n            case 8:\n                k2 ^= data[7] << 24;\n                goto case;\n            case 7:\n                k2 ^= data[6] << 16;\n                goto case;\n            case 6:\n                k2 ^= data[5] << 8;\n                goto case;\n            case 5:\n                k2 ^= data[4] << 0;\n                h2 ^= shuffle(k2, c2, c3, 16);\n                goto case;\n            case 4:\n                k1 ^= data[3] << 24;\n                goto case;\n            case 3:\n                k1 ^= data[2] << 16;\n                goto case;\n            case 2:\n                k1 ^= data[1] << 8;\n                goto case;\n            case 1:\n                k1 ^= data[0] << 0;\n                h1 ^= shuffle(k1, c1, c2, 15);\n                goto case;\n            case 0:\n            }\n        }\n\n        /// Incorporate `element_count` and finalizes the hash.\n        void finalize() pure nothrow @nogc\n        {\n            h1 ^= element_count;\n            h2 ^= element_count;\n            h3 ^= element_count;\n            h4 ^= element_count;\n\n            h1 += h2;\n            h1 += h3;\n            h1 += h4;\n            h2 += h1;\n            h3 += h1;\n            h4 += h1;\n\n            h1 = fmix(h1);\n            h2 = fmix(h2);\n            h3 = fmix(h3);\n            h4 = fmix(h4);\n\n            h1 += h2;\n            h1 += h3;\n            h1 += h4;\n            h2 += h1;\n            h3 += h1;\n            h4 += h1;\n        }\n\n        /// Returns the hash as an uint[4] value.\n        Element get() pure nothrow @nogc\n        {\n            return [h1, h2, h3, h4];\n        }\n\n        /// Returns the current hashed value as an ubyte array.\n        ubyte[16] getBytes() pure nothrow @nogc\n        {\n            return cast(typeof(return)) get();\n        }\n    }\n    else static if (size == 128 && opt == 64)\n    {\n        private enum ulong c1 = 0x87c37b91114253d5;\n        private enum ulong c2 = 0x4cf5ad432745937f;\n        private ulong h2, h1;\n\n        alias Element = ulong[2]; /// The element type for 128-bit implementation.\n\n        this(ulong seed) pure nothrow @nogc\n        {\n            h2 = h1 = seed;\n        }\n\n        this(ulong seed2, ulong seed1) pure nothrow @nogc\n        {\n            h2 = seed2;\n            h1 = seed1;\n        }\n\n        /++\n        Adds a single Element of data without increasing `element_count`.\n        Make sure to increase `element_count` by `Element.sizeof` for each call to `putElement`.\n        +/\n        void putElement(Element block) pure nothrow @nogc\n        {\n            h1 = update(h1, block[0], h2, c1, c2, 31, 27, 0x52dce729U);\n            h2 = update(h2, block[1], h1, c2, c1, 33, 31, 0x38495ab5U);\n        }\n\n        /// Put remainder bytes. This must be called only once after `putElement` and before `finalize`.\n        void putRemainder(scope const(ubyte[]) data...) pure nothrow @nogc\n        {\n            assert(data.length < Element.sizeof);\n            assert(data.length >= 0);\n            element_count += data.length;\n            ulong k1 = 0;\n            ulong k2 = 0;\n            final switch (data.length & 15)\n            {\n            case 15:\n                k2 ^= ulong(data[14]) << 48;\n                goto case;\n            case 14:\n                k2 ^= ulong(data[13]) << 40;\n                goto case;\n            case 13:\n                k2 ^= ulong(data[12]) << 32;\n                goto case;\n            case 12:\n                k2 ^= ulong(data[11]) << 24;\n                goto case;\n            case 11:\n                k2 ^= ulong(data[10]) << 16;\n                goto case;\n            case 10:\n                k2 ^= ulong(data[9]) << 8;\n                goto case;\n            case 9:\n                k2 ^= ulong(data[8]) << 0;\n                h2 ^= shuffle(k2, c2, c1, 33);\n                goto case;\n            case 8:\n                k1 ^= ulong(data[7]) << 56;\n                goto case;\n            case 7:\n                k1 ^= ulong(data[6]) << 48;\n                goto case;\n            case 6:\n                k1 ^= ulong(data[5]) << 40;\n                goto case;\n            case 5:\n                k1 ^= ulong(data[4]) << 32;\n                goto case;\n            case 4:\n                k1 ^= ulong(data[3]) << 24;\n                goto case;\n            case 3:\n                k1 ^= ulong(data[2]) << 16;\n                goto case;\n            case 2:\n                k1 ^= ulong(data[1]) << 8;\n                goto case;\n            case 1:\n                k1 ^= ulong(data[0]) << 0;\n                h1 ^= shuffle(k1, c1, c2, 31);\n                goto case;\n            case 0:\n            }\n        }\n\n        /// Incorporate `element_count` and finalizes the hash.\n        void finalize() pure nothrow @nogc\n        {\n            h1 ^= element_count;\n            h2 ^= element_count;\n\n            h1 += h2;\n            h2 += h1;\n            h1 = fmix(h1);\n            h2 = fmix(h2);\n            h1 += h2;\n            h2 += h1;\n        }\n\n        /// Returns the hash as an ulong[2] value.\n        Element get() pure nothrow @nogc\n        {\n            return [h1, h2];\n        }\n\n        /// Returns the current hashed value as an ubyte array.\n        ubyte[16] getBytes() pure nothrow @nogc\n        {\n            return cast(typeof(return)) get();\n        }\n    }\n    else\n    {\n        alias Element = char; // This is needed to trigger the following error message.\n        static assert(false, \"MurmurHash3(\" ~ size.stringof ~ \", \" ~ opt.stringof ~ \") is not implemented\");\n    }\n\n    /++\n    Pushes an array of elements at once. It is more efficient to push as much data as possible in a single call.\n    On platforms that do not support unaligned reads (MIPS or old ARM chips), the compiler may produce slower code to ensure correctness.\n    +/\n    void putElements(scope const(Element[]) elements...) pure nothrow @nogc\n    {\n        foreach (const block; elements)\n        {\n            putElement(block);\n        }\n        element_count += elements.length * Element.sizeof;\n    }\n\n    //-------------------------------------------------------------------------\n    // Implementation of the Digest API.\n    //-------------------------------------------------------------------------\n\n    private union BufferUnion\n    {\n        Element block;\n        ubyte[Element.sizeof] data;\n    }\n\n    private BufferUnion buffer;\n    private size_t bufferSize;\n\n    @disable this(this);\n\n    // Initialize\n    void start()\n    {\n        this = this.init;\n    }\n\n    /++\n    Adds data to the digester. This function can be called many times in a row\n    after start but before finish.\n    +/\n    void put(scope const(ubyte)[] data...) pure nothrow\n    {\n        // Buffer should never be full while entering this function.\n        assert(bufferSize < Element.sizeof);\n\n        // Check if the incoming data doesn't fill up a whole block buffer.\n        if (bufferSize + data.length < Element.sizeof)\n        {\n            buffer.data[bufferSize .. bufferSize + data.length] = data[];\n            bufferSize += data.length;\n            return;\n        }\n\n        // Check if there's some leftover data in the first block buffer, and\n        // fill the remaining space first.\n        if (bufferSize != 0)\n        {\n            const bufferLeeway = Element.sizeof - bufferSize;\n            buffer.data[bufferSize .. $] = data[0 .. bufferLeeway];\n            putElement(buffer.block);\n            element_count += Element.sizeof;\n            data = data[bufferLeeway .. $];\n        }\n\n        // Do main work: process chunks of `Element.sizeof` bytes.\n        const numElements = data.length / Element.sizeof;\n        const remainderStart = numElements * Element.sizeof;\n        version (HaveUnalignedLoads)\n        {\n            foreach (ref const Element block; cast(const(Element[])) data[0 .. remainderStart])\n            {\n                putElement(block);\n            }\n        }\n        else\n        {\n            void processChunks(T)() @trusted\n            {\n                alias TChunk = T[Element.sizeof / T.sizeof];\n                foreach (ref const chunk; cast(const(TChunk[])) data[0 .. remainderStart])\n                {\n                    static if (T.alignof >= Element.alignof)\n                    {\n                        putElement(*cast(const(Element)*) chunk.ptr);\n                    }\n                    else\n                    {\n                        Element[1] alignedCopy = void;\n                        (cast(T[]) alignedCopy)[] = chunk[];\n                        putElement(alignedCopy[0]);\n                    }\n                }\n            }\n\n            const startAddress = cast(size_t) data.ptr;\n            static if (size >= 64)\n            {\n                if ((startAddress & 7) == 0)\n                {\n                    processChunks!ulong();\n                    goto L_end;\n                }\n            }\n            static assert(size >= 32);\n            if ((startAddress & 3) == 0)\n                processChunks!uint();\n            else if ((startAddress & 1) == 0)\n                processChunks!ushort();\n            else\n                processChunks!ubyte();\n\nL_end:\n        }\n        element_count += numElements * Element.sizeof;\n        data = data[remainderStart .. $];\n\n        // Now add remaining data to buffer.\n        assert(data.length < Element.sizeof);\n        bufferSize = data.length;\n        buffer.data[0 .. data.length] = data[];\n    }\n\n    /++\n    Finalizes the computation of the hash and returns the computed value.\n    Note that `finish` can be called only once and that no subsequent calls\n    to `put` is allowed.\n    +/\n    ubyte[Element.sizeof] finish() pure nothrow\n    {\n        auto tail = buffer.data[0 .. bufferSize];\n        if (tail.length > 0)\n        {\n            putRemainder(tail);\n        }\n        finalize();\n        return getBytes();\n    }\n\n    //-------------------------------------------------------------------------\n    // MurmurHash3 utils\n    //-------------------------------------------------------------------------\n\n    private T rotl(T)(T x, uint y)\n    in\n    {\n        import std.traits : isUnsigned;\n\n        static assert(isUnsigned!T);\n        debug assert(y >= 0 && y <= (T.sizeof * 8));\n    }\n    do\n    {\n        return ((x << y) | (x >> ((T.sizeof * 8) - y)));\n    }\n\n    private T shuffle(T)(T k, T c1, T c2, ubyte r1)\n    {\n        import std.traits : isUnsigned;\n\n        static assert(isUnsigned!T);\n        k *= c1;\n        k = rotl(k, r1);\n        k *= c2;\n        return k;\n    }\n\n    private T update(T)(ref T h, T k, T mixWith, T c1, T c2, ubyte r1, ubyte r2, T n)\n    {\n        import std.traits : isUnsigned;\n\n        static assert(isUnsigned!T);\n        h ^= shuffle(k, c1, c2, r1);\n        h = rotl(h, r2);\n        h += mixWith;\n        return h * 5 + n;\n    }\n\n    private uint fmix(uint h) pure nothrow @nogc\n    {\n        h ^= h >> 16;\n        h *= 0x85ebca6b;\n        h ^= h >> 13;\n        h *= 0xc2b2ae35;\n        h ^= h >> 16;\n        return h;\n    }\n\n    private ulong fmix(ulong k) pure nothrow @nogc\n    {\n        k ^= k >> 33;\n        k *= 0xff51afd7ed558ccd;\n        k ^= k >> 33;\n        k *= 0xc4ceb9fe1a85ec53;\n        k ^= k >> 33;\n        return k;\n    }\n}\n\n\n/// The convenient digest template allows for quick hashing of any data.\n@safe unittest\n{\n    ubyte[4] hashed = digest!(MurmurHash3!32)([1, 2, 3, 4]);\n    assert(hashed == [0, 173, 69, 68]);\n}\n\n/**\nOne can also hash ubyte data piecewise by instanciating a hasher and call\nthe 'put' method.\n*/\n@safe unittest\n{\n    const(ubyte)[] data1 = [1, 2, 3];\n    const(ubyte)[] data2 = [4, 5, 6, 7];\n    // The incoming data will be buffered and hashed element by element.\n    MurmurHash3!32 hasher;\n    hasher.put(data1);\n    hasher.put(data2);\n    // The call to 'finish' ensures:\n    // - the remaining bits are processed\n    // - the hash gets finalized\n    auto hashed = hasher.finish();\n    assert(hashed == [181, 151, 88, 252]);\n}\n\nversion (unittest)\n{\n    private auto hash(H, Element = H.Element)(string data)\n    {\n        H hasher;\n        immutable elements = data.length / Element.sizeof;\n        hasher.putElements(cast(const(Element)[]) data[0 .. elements * Element.sizeof]);\n        hasher.putRemainder(cast(const(ubyte)[]) data[elements * Element.sizeof .. $]);\n        hasher.finalize();\n        return hasher.getBytes();\n    }\n\n    private void checkResult(H)(in string[string] groundtruth)\n    {\n        foreach (data, expectedHash; groundtruth)\n        {\n            assert(data.digest!H.toHexString() == expectedHash);\n            assert(data.hash!H.toHexString() == expectedHash);\n            H hasher;\n            foreach (element; data)\n            {\n                hasher.put(element);\n            }\n            assert(hasher.finish.toHexString() == expectedHash);\n        }\n    }\n}\n\n@safe unittest\n{\n    // dfmt off\n    checkResult!(MurmurHash3!32)([\n        \"\" : \"00000000\",\n        \"a\" : \"B269253C\",\n        \"ab\" : \"5FD7BF9B\",\n        \"abc\" : \"FA93DDB3\",\n        \"abcd\" : \"6A67ED43\",\n        \"abcde\" : \"F69A9BE8\",\n        \"abcdef\" : \"85C08161\",\n        \"abcdefg\" : \"069B3C88\",\n        \"abcdefgh\" : \"C4CCDD49\",\n        \"abcdefghi\" : \"F0061442\",\n        \"abcdefghij\" : \"91779288\",\n        \"abcdefghijk\" : \"DF253B5F\",\n        \"abcdefghijkl\" : \"273D6FA3\",\n        \"abcdefghijklm\" : \"1B1612F2\",\n        \"abcdefghijklmn\" : \"F06D52F8\",\n        \"abcdefghijklmno\" : \"D2F7099D\",\n        \"abcdefghijklmnop\" : \"ED9162E7\",\n        \"abcdefghijklmnopq\" : \"4A5E65B6\",\n        \"abcdefghijklmnopqr\" : \"94A819C2\",\n        \"abcdefghijklmnopqrs\" : \"C15BBF85\",\n        \"abcdefghijklmnopqrst\" : \"9A711CBE\",\n        \"abcdefghijklmnopqrstu\" : \"ABE7195A\",\n        \"abcdefghijklmnopqrstuv\" : \"C73CB670\",\n        \"abcdefghijklmnopqrstuvw\" : \"1C4D1EA5\",\n        \"abcdefghijklmnopqrstuvwx\" : \"3939F9B0\",\n        \"abcdefghijklmnopqrstuvwxy\" : \"1A568338\",\n        \"abcdefghijklmnopqrstuvwxyz\" : \"6D034EA3\"]);\n    // dfmt on\n}\n\n@safe unittest\n{\n    // dfmt off\n    checkResult!(MurmurHash3!(128,32))([\n        \"\" : \"00000000000000000000000000000000\",\n        \"a\" : \"3C9394A71BB056551BB056551BB05655\",\n        \"ab\" : \"DF5184151030BE251030BE251030BE25\",\n        \"abc\" : \"D1C6CD75A506B0A2A506B0A2A506B0A2\",\n        \"abcd\" : \"AACCB6962EC6AF452EC6AF452EC6AF45\",\n        \"abcde\" : \"FB2E40C5BCC5245D7701725A7701725A\",\n        \"abcdef\" : \"0AB97CE12127AFA1F9DFBEA9F9DFBEA9\",\n        \"abcdefg\" : \"D941B590DE3A86092869774A2869774A\",\n        \"abcdefgh\" : \"3611F4AE8714B1AD92806CFA92806CFA\",\n        \"abcdefghi\" : \"1C8C05AD6F590622107DD2147C4194DD\",\n        \"abcdefghij\" : \"A72ED9F50E90379A2AAA92C77FF12F69\",\n        \"abcdefghijk\" : \"DDC9C8A01E111FCA2DF1FE8257975EBD\",\n        \"abcdefghijkl\" : \"FE038573C02482F4ADDFD42753E58CD2\",\n        \"abcdefghijklm\" : \"15A23AC1ECA1AEDB66351CF470DE2CD9\",\n        \"abcdefghijklmn\" : \"8E11EC75D71F5D60F4456F944D89D4F1\",\n        \"abcdefghijklmno\" : \"691D6DEEAED51A4A5714CE84A861A7AD\",\n        \"abcdefghijklmnop\" : \"2776D29F5612B990218BCEE445BA93D1\",\n        \"abcdefghijklmnopq\" : \"D3A445046F5C51642ADC6DD99D07111D\",\n        \"abcdefghijklmnopqr\" : \"AA5493A0DA291D966A9E7128585841D9\",\n        \"abcdefghijklmnopqrs\" : \"281B6A4F9C45B9BFC3B77850930F2C20\",\n        \"abcdefghijklmnopqrst\" : \"19342546A8216DB62873B49E545DCB1F\",\n        \"abcdefghijklmnopqrstu\" : \"A6C0F30D6C738620E7B9590D2E088D99\",\n        \"abcdefghijklmnopqrstuv\" : \"A7D421D9095CDCEA393CBBA908342384\",\n        \"abcdefghijklmnopqrstuvw\" : \"C3A93D572B014949317BAD7EE809158F\",\n        \"abcdefghijklmnopqrstuvwx\" : \"802381D77956833791F87149326E4801\",\n        \"abcdefghijklmnopqrstuvwxy\" : \"0AC619A5302315755A80D74ADEFAA842\",\n        \"abcdefghijklmnopqrstuvwxyz\" : \"1306343E662F6F666E56F6172C3DE344\"]);\n    // dfmt on\n}\n\n@safe unittest\n{\n    // dfmt off\n    checkResult!(MurmurHash3!(128,64))([\n        \"\" : \"00000000000000000000000000000000\",\n        \"a\" : \"897859F6655555855A890E51483AB5E6\",\n        \"ab\" : \"2E1BED16EA118B93ADD4529B01A75EE6\",\n        \"abc\" : \"6778AD3F3F3F96B4522DCA264174A23B\",\n        \"abcd\" : \"4FCD5646D6B77BB875E87360883E00F2\",\n        \"abcde\" : \"B8BB96F491D036208CECCF4BA0EEC7C5\",\n        \"abcdef\" : \"55BFA3ACBF867DE45C842133990971B0\",\n        \"abcdefg\" : \"99E49EC09F2FCDA6B6BB55B13AA23A1C\",\n        \"abcdefgh\" : \"028CEF37B00A8ACCA14069EB600D8948\",\n        \"abcdefghi\" : \"64793CF1CFC0470533E041B7F53DB579\",\n        \"abcdefghij\" : \"998C2F770D5BC1B6C91A658CDC854DA2\",\n        \"abcdefghijk\" : \"029D78DFB8D095A871E75A45E2317CBB\",\n        \"abcdefghijkl\" : \"94E17AE6B19BF38E1C62FF7232309E1F\",\n        \"abcdefghijklm\" : \"73FAC0A78D2848167FCCE70DFF7B652E\",\n        \"abcdefghijklmn\" : \"E075C3F5A794D09124336AD2276009EE\",\n        \"abcdefghijklmno\" : \"FB2F0C895124BE8A612A969C2D8C546A\",\n        \"abcdefghijklmnop\" : \"23B74C22A33CCAC41AEB31B395D63343\",\n        \"abcdefghijklmnopq\" : \"57A6BD887F746475E40D11A19D49DAEC\",\n        \"abcdefghijklmnopqr\" : \"508A7F90EC8CF0776BC7005A29A8D471\",\n        \"abcdefghijklmnopqrs\" : \"886D9EDE23BC901574946FB62A4D8AA6\",\n        \"abcdefghijklmnopqrst\" : \"F1E237F926370B314BD016572AF40996\",\n        \"abcdefghijklmnopqrstu\" : \"3CC9FF79E268D5C9FB3C9BE9C148CCD7\",\n        \"abcdefghijklmnopqrstuv\" : \"56F8ABF430E388956DA9F4A8741FDB46\",\n        \"abcdefghijklmnopqrstuvw\" : \"8E234F9DBA0A4840FFE9541CEBB7BE83\",\n        \"abcdefghijklmnopqrstuvwx\" : \"F72CDED40F96946408F22153A3CF0F79\",\n        \"abcdefghijklmnopqrstuvwxy\" : \"0F96072FA4CBE771DBBD9E398115EEED\",\n        \"abcdefghijklmnopqrstuvwxyz\" : \"A94A6F517E9D9C7429D5A7B6899CADE9\"]);\n    // dfmt on\n}\n\n@safe unittest\n{\n    // Pushing unaligned data and making sure the result is still coherent.\n    void testUnalignedHash(H)()\n    {\n        immutable ubyte[1028] data = 0xAC;\n        immutable alignedHash = digest!H(data[0 .. 1024]);\n        foreach (i; 1 .. 5)\n        {\n            immutable unalignedHash = digest!H(data[i .. 1024 + i]);\n            assert(alignedHash == unalignedHash);\n        }\n    }\n\n    testUnalignedHash!(MurmurHash3!32)();\n    testUnalignedHash!(MurmurHash3!(128, 32))();\n    testUnalignedHash!(MurmurHash3!(128, 64))();\n}\n"
  },
  {
    "path": "libphobos/src/std/digest/package.d",
    "content": "/**\n * This module describes the digest APIs used in Phobos. All digests follow\n * these APIs. Additionally, this module contains useful helper methods which\n * can be used with every digest type.\n *\n$(SCRIPT inhibitQuickIndex = 1;)\n\n$(DIVC quickindex,\n$(BOOKTABLE ,\n$(TR $(TH Category) $(TH Functions)\n)\n$(TR $(TDNW Template API) $(TD $(MYREF isDigest) $(MYREF DigestType) $(MYREF hasPeek)\n  $(MYREF hasBlockSize)\n  $(MYREF ExampleDigest) $(MYREF digest) $(MYREF hexDigest) $(MYREF makeDigest)\n)\n)\n$(TR $(TDNW OOP API) $(TD $(MYREF Digest)\n)\n)\n$(TR $(TDNW Helper functions) $(TD $(MYREF toHexString) $(MYREF secureEqual))\n)\n$(TR $(TDNW Implementation helpers) $(TD $(MYREF digestLength) $(MYREF WrapperDigest))\n)\n)\n)\n\n * APIs:\n * There are two APIs for digests: The template API and the OOP API. The template API uses structs\n * and template helpers like $(LREF isDigest). The OOP API implements digests as classes inheriting\n * the $(LREF Digest) interface. All digests are named so that the template API struct is called \"$(B x)\"\n * and the OOP API class is called \"$(B x)Digest\". For example we have `MD5` <--> `MD5Digest`,\n * `CRC32` <--> `CRC32Digest`, etc.\n *\n * The template API is slightly more efficient. It does not have to allocate memory dynamically,\n * all memory is allocated on the stack. The OOP API has to allocate in the finish method if no\n * buffer was provided. If you provide a buffer to the OOP APIs finish function, it doesn't allocate,\n * but the $(LREF Digest) classes still have to be created using `new` which allocates them using the GC.\n *\n * The OOP API is useful to change the digest function and/or digest backend at 'runtime'. The benefit here\n * is that switching e.g. Phobos MD5Digest and an OpenSSLMD5Digest implementation is ABI compatible.\n *\n * If just one specific digest type and backend is needed, the template API is usually a good fit.\n * In this simplest case, the template API can even be used without templates: Just use the \"$(B x)\" structs\n * directly.\n *\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:\n * Johannes Pfau\n *\n * Source:    $(PHOBOSSRC std/digest/package.d)\n *\n * CTFE:\n * Digests do not work in CTFE\n *\n * TODO:\n * Digesting single bits (as opposed to bytes) is not implemented. This will be done as another\n * template constraint helper (hasBitDigesting!T) and an additional interface (BitDigest)\n */\n/*          Copyright Johannes Pfau 2012.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.digest;\n\npublic import std.ascii : LetterCase;\nimport std.meta : allSatisfy;\nimport std.range.primitives;\nimport std.traits;\n\n\n///\n@system unittest\n{\n    import std.digest.crc;\n\n    //Simple example\n    char[8] hexHash = hexDigest!CRC32(\"The quick brown fox jumps over the lazy dog\");\n    assert(hexHash == \"39A34F41\");\n\n    //Simple example, using the API manually\n    CRC32 context = makeDigest!CRC32();\n    context.put(cast(ubyte[])\"The quick brown fox jumps over the lazy dog\");\n    ubyte[4] hash = context.finish();\n    assert(toHexString(hash) == \"39A34F41\");\n}\n\n///\n@system unittest\n{\n    //Generating the hashes of a file, idiomatic D way\n    import std.digest.crc, std.digest.md, std.digest.sha;\n    import std.stdio;\n\n    // Digests a file and prints the result.\n    void digestFile(Hash)(string filename)\n    if (isDigest!Hash)\n    {\n        auto file = File(filename);\n        auto result = digest!Hash(file.byChunk(4096 * 1024));\n        writefln(\"%s (%s) = %s\", Hash.stringof, filename, toHexString(result));\n    }\n\n    void main(string[] args)\n    {\n        foreach (name; args[1 .. $])\n        {\n            digestFile!MD5(name);\n            digestFile!SHA1(name);\n            digestFile!CRC32(name);\n        }\n    }\n}\n///\n@system unittest\n{\n    //Generating the hashes of a file using the template API\n    import std.digest.crc, std.digest.md, std.digest.sha;\n    import std.stdio;\n    // Digests a file and prints the result.\n    void digestFile(Hash)(ref Hash hash, string filename)\n    if (isDigest!Hash)\n    {\n        File file = File(filename);\n\n        //As digests imlement OutputRange, we could use std.algorithm.copy\n        //Let's do it manually for now\n        foreach (buffer; file.byChunk(4096 * 1024))\n            hash.put(buffer);\n\n        auto result = hash.finish();\n        writefln(\"%s (%s) = %s\", Hash.stringof, filename, toHexString(result));\n    }\n\n    void uMain(string[] args)\n    {\n        MD5 md5;\n        SHA1 sha1;\n        CRC32 crc32;\n\n        md5.start();\n        sha1.start();\n        crc32.start();\n\n        foreach (arg; args[1 .. $])\n        {\n            digestFile(md5, arg);\n            digestFile(sha1, arg);\n            digestFile(crc32, arg);\n        }\n    }\n}\n\n///\n@system unittest\n{\n    import std.digest.crc, std.digest.md, std.digest.sha;\n    import std.stdio;\n\n    // Digests a file and prints the result.\n    void digestFile(Digest hash, string filename)\n    {\n        File file = File(filename);\n\n        //As digests implement OutputRange, we could use std.algorithm.copy\n        //Let's do it manually for now\n        foreach (buffer; file.byChunk(4096 * 1024))\n          hash.put(buffer);\n\n        ubyte[] result = hash.finish();\n        writefln(\"%s (%s) = %s\", typeid(hash).toString(), filename, toHexString(result));\n    }\n\n    void umain(string[] args)\n    {\n        auto md5 = new MD5Digest();\n        auto sha1 = new SHA1Digest();\n        auto crc32 = new CRC32Digest();\n\n        foreach (arg; args[1 .. $])\n        {\n          digestFile(md5, arg);\n          digestFile(sha1, arg);\n          digestFile(crc32, arg);\n        }\n    }\n}\n\nversion (StdDdoc)\n    version = ExampleDigest;\n\nversion (ExampleDigest)\n{\n    /**\n     * This documents the general structure of a Digest in the template API.\n     * All digest implementations should implement the following members and therefore pass\n     * the $(LREF isDigest) test.\n     *\n     * Note:\n     * $(UL\n     * $(LI A digest must be a struct (value type) to pass the $(LREF isDigest) test.)\n     * $(LI A digest passing the $(LREF isDigest) test is always an `OutputRange`)\n     * )\n     */\n    struct ExampleDigest\n    {\n        public:\n            /**\n             * Use this to feed the digest with data.\n             * Also implements the $(REF isOutputRange, std,range,primitives)\n             * interface for `ubyte` and `const(ubyte)[]`.\n             * The following usages of `put` must work for any type which\n             * passes $(LREF isDigest):\n             * Example:\n             * ----\n             * ExampleDigest dig;\n             * dig.put(cast(ubyte) 0); //single ubyte\n             * dig.put(cast(ubyte) 0, cast(ubyte) 0); //variadic\n             * ubyte[10] buf;\n             * dig.put(buf); //buffer\n             * ----\n             */\n            @trusted void put(scope const(ubyte)[] data...)\n            {\n\n            }\n\n            /**\n             * This function is used to (re)initialize the digest.\n             * It must be called before using the digest and it also works as a 'reset' function\n             * if the digest has already processed data.\n             */\n            @trusted void start()\n            {\n\n            }\n\n            /**\n             * The finish function returns the final hash sum and resets the Digest.\n             *\n             * Note:\n             * The actual type returned by finish depends on the digest implementation.\n             * `ubyte[16]` is just used as an example. It is guaranteed that the type is a\n             * static array of ubytes.\n             *\n             * $(UL\n             * $(LI Use $(LREF DigestType) to obtain the actual return type.)\n             * $(LI Use $(LREF digestLength) to obtain the length of the ubyte array.)\n             * )\n             */\n            @trusted ubyte[16] finish()\n            {\n                return (ubyte[16]).init;\n            }\n    }\n}\n\n///\n@system unittest\n{\n    //Using the OutputRange feature\n    import std.algorithm.mutation : copy;\n    import std.digest.md;\n    import std.range : repeat;\n\n    auto oneMillionRange = repeat!ubyte(cast(ubyte)'a', 1000000);\n    auto ctx = makeDigest!MD5();\n    copy(oneMillionRange, &ctx); //Note: You must pass a pointer to copy!\n    assert(ctx.finish().toHexString() == \"7707D6AE4E027C70EEA2A935C2296F21\");\n}\n\n/**\n * Use this to check if a type is a digest. See $(LREF ExampleDigest) to see what\n * a type must provide to pass this check.\n *\n * Note:\n * This is very useful as a template constraint (see examples)\n *\n * BUGS:\n * $(UL\n * $(LI Does not yet verify that put takes scope parameters.)\n * $(LI Should check that finish() returns a ubyte[num] array)\n * )\n */\ntemplate isDigest(T)\n{\n    import std.range : isOutputRange;\n    enum bool isDigest = isOutputRange!(T, const(ubyte)[]) && isOutputRange!(T, ubyte) &&\n        is(T == struct) &&\n        is(typeof(\n        {\n            T dig = void; //Can define\n            dig.put(cast(ubyte) 0, cast(ubyte) 0); //varags\n            dig.start(); //has start\n            auto value = dig.finish(); //has finish\n        }));\n}\n\n///\n@system unittest\n{\n    import std.digest.crc;\n    static assert(isDigest!CRC32);\n}\n///\n@system unittest\n{\n    import std.digest.crc;\n    void myFunction(T)()\n    if (isDigest!T)\n    {\n        T dig;\n        dig.start();\n        auto result = dig.finish();\n    }\n    myFunction!CRC32();\n}\n\n/**\n * Use this template to get the type which is returned by a digest's $(LREF finish) method.\n */\ntemplate DigestType(T)\n{\n    static if (isDigest!T)\n    {\n        alias DigestType =\n            ReturnType!(typeof(\n            {\n                T dig = void;\n                return dig.finish();\n            }));\n    }\n    else\n        static assert(false, T.stringof ~ \" is not a digest! (fails isDigest!T)\");\n}\n\n///\n@system unittest\n{\n    import std.digest.crc;\n    assert(is(DigestType!(CRC32) == ubyte[4]));\n}\n///\n@system unittest\n{\n    import std.digest.crc;\n    CRC32 dig;\n    dig.start();\n    DigestType!CRC32 result = dig.finish();\n}\n\n/**\n * Used to check if a digest supports the `peek` method.\n * Peek has exactly the same function signatures as finish, but it doesn't reset\n * the digest's internal state.\n *\n * Note:\n * $(UL\n * $(LI This is very useful as a template constraint (see examples))\n * $(LI This also checks if T passes $(LREF isDigest))\n * )\n */\ntemplate hasPeek(T)\n{\n    enum bool hasPeek = isDigest!T &&\n        is(typeof(\n        {\n            T dig = void; //Can define\n            DigestType!T val = dig.peek();\n        }));\n}\n\n///\n@system unittest\n{\n    import std.digest.crc, std.digest.md;\n    assert(!hasPeek!(MD5));\n    assert(hasPeek!CRC32);\n}\n///\n@system unittest\n{\n    import std.digest.crc;\n    void myFunction(T)()\n    if (hasPeek!T)\n    {\n        T dig;\n        dig.start();\n        auto result = dig.peek();\n    }\n    myFunction!CRC32();\n}\n\n/**\n * Checks whether the digest has a `blockSize` member, which contains the\n * digest's internal block size in bits. It is primarily used by $(REF HMAC, std,digest,hmac).\n */\n\ntemplate hasBlockSize(T)\nif (isDigest!T)\n{\n    enum bool hasBlockSize = __traits(compiles, { size_t blockSize = T.blockSize; });\n}\n\n///\n@system unittest\n{\n    import std.digest.hmac, std.digest.md;\n    static assert(hasBlockSize!MD5        && MD5.blockSize      == 512);\n    static assert(hasBlockSize!(HMAC!MD5) && HMAC!MD5.blockSize == 512);\n}\n\npackage template isDigestibleRange(Range)\n{\n    import std.digest.md;\n    import std.range : isInputRange, ElementType;\n    enum bool isDigestibleRange = isInputRange!Range && is(typeof(\n          {\n          MD5 ha; //Could use any conformant hash\n          ElementType!Range val;\n          ha.put(val);\n          }));\n}\n\n/**\n * This is a convenience function to calculate a hash using the template API.\n * Every digest passing the $(LREF isDigest) test can be used with this function.\n *\n * Params:\n *  range= an `InputRange` with `ElementType` `ubyte`, `ubyte[]` or `ubyte[num]`\n */\nDigestType!Hash digest(Hash, Range)(auto ref Range range)\nif (!isArray!Range\n    && isDigestibleRange!Range)\n{\n    import std.algorithm.mutation : copy;\n    Hash hash;\n    hash.start();\n    copy(range, &hash);\n    return hash.finish();\n}\n\n///\n@system unittest\n{\n    import std.digest.md;\n    import std.range : repeat;\n    auto testRange = repeat!ubyte(cast(ubyte)'a', 100);\n    auto md5 = digest!MD5(testRange);\n}\n\n/**\n * This overload of the digest function handles arrays.\n *\n * Params:\n *  data= one or more arrays of any type\n */\nDigestType!Hash digest(Hash, T...)(scope const T data)\nif (allSatisfy!(isArray, typeof(data)))\n{\n    Hash hash;\n    hash.start();\n    foreach (datum; data)\n        hash.put(cast(const(ubyte[]))datum);\n    return hash.finish();\n}\n\n///\n@system unittest\n{\n    import std.digest.crc, std.digest.md, std.digest.sha;\n    auto md5   = digest!MD5(  \"The quick brown fox jumps over the lazy dog\");\n    auto sha1  = digest!SHA1( \"The quick brown fox jumps over the lazy dog\");\n    auto crc32 = digest!CRC32(\"The quick brown fox jumps over the lazy dog\");\n    assert(toHexString(crc32) == \"39A34F41\");\n}\n\n///\n@system unittest\n{\n    import std.digest.crc;\n    auto crc32 = digest!CRC32(\"The quick \", \"brown \", \"fox jumps over the lazy dog\");\n    assert(toHexString(crc32) == \"39A34F41\");\n}\n\n/**\n * This is a convenience function similar to $(LREF digest), but it returns the string\n * representation of the hash. Every digest passing the $(LREF isDigest) test can be used with this\n * function.\n *\n * Params:\n *  order= the order in which the bytes are processed (see $(LREF toHexString))\n *  range= an `InputRange` with `ElementType` `ubyte`, `ubyte[]` or `ubyte[num]`\n */\nchar[digestLength!(Hash)*2] hexDigest(Hash, Order order = Order.increasing, Range)(ref Range range)\nif (!isArray!Range && isDigestibleRange!Range)\n{\n    return toHexString!order(digest!Hash(range));\n}\n\n///\n@system unittest\n{\n    import std.digest.md;\n    import std.range : repeat;\n    auto testRange = repeat!ubyte(cast(ubyte)'a', 100);\n    assert(hexDigest!MD5(testRange) == \"36A92CC94A9E0FA21F625F8BFB007ADF\");\n}\n\n/**\n * This overload of the hexDigest function handles arrays.\n *\n * Params:\n *  order= the order in which the bytes are processed (see $(LREF toHexString))\n *  data= one or more arrays of any type\n */\nchar[digestLength!(Hash)*2] hexDigest(Hash, Order order = Order.increasing, T...)(scope const T data)\nif (allSatisfy!(isArray, typeof(data)))\n{\n    return toHexString!order(digest!Hash(data));\n}\n\n///\n@system unittest\n{\n    import std.digest.crc;\n    assert(hexDigest!(CRC32, Order.decreasing)(\"The quick brown fox jumps over the lazy dog\") == \"414FA339\");\n}\n///\n@system unittest\n{\n    import std.digest.crc;\n    assert(hexDigest!(CRC32, Order.decreasing)(\"The quick \", \"brown \", \"fox jumps over the lazy dog\") == \"414FA339\");\n}\n\n/**\n * This is a convenience function which returns an initialized digest, so it's not necessary to call\n * start manually.\n */\nHash makeDigest(Hash)()\n{\n    Hash hash;\n    hash.start();\n    return hash;\n}\n\n///\n@system unittest\n{\n    import std.digest.md;\n    auto md5 = makeDigest!MD5();\n    md5.put(0);\n    assert(toHexString(md5.finish()) == \"93B885ADFE0DA089CDF634904FD59F71\");\n}\n\n/*+*************************** End of template part, welcome to OOP land **************************/\n\n/**\n * This describes the OOP API. To understand when to use the template API and when to use the OOP API,\n * see the module documentation at the top of this page.\n *\n * The Digest interface is the base interface which is implemented by all digests.\n *\n * Note:\n * A Digest implementation is always an `OutputRange`\n */\ninterface Digest\n{\n    public:\n        /**\n         * Use this to feed the digest with data.\n         * Also implements the $(REF isOutputRange, std,range,primitives)\n         * interface for `ubyte` and `const(ubyte)[]`.\n         *\n         * Example:\n         * ----\n         * void test(Digest dig)\n         * {\n         *     dig.put(cast(ubyte) 0); //single ubyte\n         *     dig.put(cast(ubyte) 0, cast(ubyte) 0); //variadic\n         *     ubyte[10] buf;\n         *     dig.put(buf); //buffer\n         * }\n         * ----\n         */\n        @trusted nothrow void put(scope const(ubyte)[] data...);\n\n        /**\n         * Resets the internal state of the digest.\n         * Note:\n         * $(LREF finish) calls this internally, so it's not necessary to call\n         * `reset` manually after a call to $(LREF finish).\n         */\n        @trusted nothrow void reset();\n\n        /**\n         * This is the length in bytes of the hash value which is returned by $(LREF finish).\n         * It's also the required size of a buffer passed to $(LREF finish).\n         */\n        @trusted nothrow @property size_t length() const;\n\n        /**\n         * The finish function returns the hash value. It takes an optional buffer to copy the data\n         * into. If a buffer is passed, it must be at least $(LREF length) bytes big.\n         */\n        @trusted nothrow ubyte[] finish();\n        ///ditto\n        nothrow ubyte[] finish(ubyte[] buf);\n        //@@@BUG@@@ http://d.puremagic.com/issues/show_bug.cgi?id=6549\n        /*in\n        {\n            assert(buf.length >= this.length);\n        }*/\n\n        /**\n         * This is a convenience function to calculate the hash of a value using the OOP API.\n         */\n        final @trusted nothrow ubyte[] digest(scope const(void[])[] data...)\n        {\n            this.reset();\n            foreach (datum; data)\n                this.put(cast(ubyte[]) datum);\n            return this.finish();\n        }\n}\n\n///\n@system unittest\n{\n    //Using the OutputRange feature\n    import std.algorithm.mutation : copy;\n    import std.digest.md;\n    import std.range : repeat;\n\n    auto oneMillionRange = repeat!ubyte(cast(ubyte)'a', 1000000);\n    auto ctx = new MD5Digest();\n    copy(oneMillionRange, ctx);\n    assert(ctx.finish().toHexString() == \"7707D6AE4E027C70EEA2A935C2296F21\");\n}\n\n///\n@system unittest\n{\n    import std.digest.crc, std.digest.md, std.digest.sha;\n    ubyte[] md5   = (new MD5Digest()).digest(\"The quick brown fox jumps over the lazy dog\");\n    ubyte[] sha1  = (new SHA1Digest()).digest(\"The quick brown fox jumps over the lazy dog\");\n    ubyte[] crc32 = (new CRC32Digest()).digest(\"The quick brown fox jumps over the lazy dog\");\n    assert(crcHexString(crc32) == \"414FA339\");\n}\n\n///\n@system unittest\n{\n    import std.digest.crc;\n    ubyte[] crc32 = (new CRC32Digest()).digest(\"The quick \", \"brown \", \"fox jumps over the lazy dog\");\n    assert(crcHexString(crc32) == \"414FA339\");\n}\n\n@system unittest\n{\n    import std.range : isOutputRange;\n    assert(!isDigest!(Digest));\n    assert(isOutputRange!(Digest, ubyte));\n}\n\n///\n@system unittest\n{\n    void test(Digest dig)\n    {\n        dig.put(cast(ubyte) 0); //single ubyte\n        dig.put(cast(ubyte) 0, cast(ubyte) 0); //variadic\n        ubyte[10] buf;\n        dig.put(buf); //buffer\n    }\n}\n\n/*+*************************** End of OOP part, helper functions follow ***************************/\n\n/**\n * See $(LREF toHexString)\n */\nenum Order : bool\n{\n    increasing, ///\n    decreasing ///\n}\n\n///\n@safe unittest\n{\n    import std.digest.crc : CRC32;\n\n    auto crc32 = digest!CRC32(\"The quick \", \"brown \", \"fox jumps over the lazy dog\");\n    assert(crc32.toHexString!(Order.decreasing) == \"414FA339\");\n    assert(crc32.toHexString!(LetterCase.lower, Order.decreasing) == \"414fa339\");\n}\n\n\n/**\n * Used to convert a hash value (a static or dynamic array of ubytes) to a string.\n * Can be used with the OOP and with the template API.\n *\n * The additional order parameter can be used to specify the order of the input data.\n * By default the data is processed in increasing order, starting at index 0. To process it in the\n * opposite order, pass Order.decreasing as a parameter.\n *\n * The additional letterCase parameter can be used to specify the case of the output data.\n * By default the output is in upper case. To change it to the lower case\n * pass LetterCase.lower as a parameter.\n *\n * Note:\n * The function overloads returning a string allocate their return values\n * using the GC. The versions returning static arrays use pass-by-value for\n * the return value, effectively avoiding dynamic allocation.\n */\nchar[num*2] toHexString(Order order = Order.increasing, size_t num, LetterCase letterCase = LetterCase.upper)\n(in ubyte[num] digest)\n{\n    static if (letterCase == LetterCase.upper)\n    {\n        import std.ascii : hexDigits = hexDigits;\n    }\n    else\n    {\n        import std.ascii : hexDigits = lowerHexDigits;\n    }\n\n\n    char[num*2] result;\n    size_t i;\n\n    static if (order == Order.increasing)\n    {\n        foreach (u; digest)\n        {\n            result[i++] = hexDigits[u >> 4];\n            result[i++] = hexDigits[u & 15];\n        }\n    }\n    else\n    {\n        size_t j = num - 1;\n        while (i < num*2)\n        {\n            result[i++] = hexDigits[digest[j] >> 4];\n            result[i++] = hexDigits[digest[j] & 15];\n            j--;\n        }\n    }\n    return result;\n}\n\n///ditto\nchar[num*2] toHexString(LetterCase letterCase, Order order = Order.increasing, size_t num)(in ubyte[num] digest)\n{\n    return toHexString!(order, num, letterCase)(digest);\n}\n\n///ditto\nstring toHexString(Order order = Order.increasing, LetterCase letterCase = LetterCase.upper)\n(in ubyte[] digest)\n{\n    static if (letterCase == LetterCase.upper)\n    {\n        import std.ascii : hexDigits = hexDigits;\n    }\n    else\n    {\n        import std.ascii : hexDigits = lowerHexDigits;\n    }\n\n    auto result = new char[digest.length*2];\n    size_t i;\n\n    static if (order == Order.increasing)\n    {\n        foreach (u; digest)\n        {\n            result[i++] = hexDigits[u >> 4];\n            result[i++] = hexDigits[u & 15];\n        }\n    }\n    else\n    {\n        import std.range : retro;\n        foreach (u; retro(digest))\n        {\n            result[i++] = hexDigits[u >> 4];\n            result[i++] = hexDigits[u & 15];\n        }\n    }\n    import std.exception : assumeUnique;\n    // memory was just created, so casting to immutable is safe\n    return () @trusted { return assumeUnique(result); }();\n}\n\n///ditto\nstring toHexString(LetterCase letterCase, Order order = Order.increasing)(in ubyte[] digest)\n{\n    return toHexString!(order, letterCase)(digest);\n}\n\n//For more example unittests, see Digest.digest, digest\n\n///\n@safe unittest\n{\n    import std.digest.crc;\n    //Test with template API:\n    auto crc32 = digest!CRC32(\"The quick \", \"brown \", \"fox jumps over the lazy dog\");\n    //Lower case variant:\n    assert(toHexString!(LetterCase.lower)(crc32) == \"39a34f41\");\n    //Usually CRCs are printed in this order, though:\n    assert(toHexString!(Order.decreasing)(crc32) == \"414FA339\");\n    assert(toHexString!(LetterCase.lower, Order.decreasing)(crc32) == \"414fa339\");\n}\n\n///\n@safe unittest\n{\n    import std.digest.crc;\n    // With OOP API\n    auto crc32 = (new CRC32Digest()).digest(\"The quick \", \"brown \", \"fox jumps over the lazy dog\");\n    //Usually CRCs are printed in this order, though:\n    assert(toHexString!(Order.decreasing)(crc32) == \"414FA339\");\n}\n\n@safe unittest\n{\n    ubyte[16] data;\n    assert(toHexString(data) == \"00000000000000000000000000000000\");\n\n    assert(toHexString(cast(ubyte[4])[42, 43, 44, 45]) == \"2A2B2C2D\");\n    assert(toHexString(cast(ubyte[])[42, 43, 44, 45]) == \"2A2B2C2D\");\n    assert(toHexString!(Order.decreasing)(cast(ubyte[4])[42, 43, 44, 45]) == \"2D2C2B2A\");\n    assert(toHexString!(Order.decreasing, LetterCase.lower)(cast(ubyte[4])[42, 43, 44, 45]) == \"2d2c2b2a\");\n    assert(toHexString!(Order.decreasing)(cast(ubyte[])[42, 43, 44, 45]) == \"2D2C2B2A\");\n}\n\n/*+*********************** End of public helper part, private helpers follow ***********************/\n\n/*\n * Used to convert from a ubyte[] slice to a ref ubyte[N].\n * This helper is used internally in the WrapperDigest template to wrap the template API's\n * finish function.\n */\nref T[N] asArray(size_t N, T)(ref T[] source, string errorMsg = \"\")\n{\n     assert(source.length >= N, errorMsg);\n     return *cast(T[N]*) source.ptr;\n}\n\n/*\n * Returns the length (in bytes) of the hash value produced by T.\n */\ntemplate digestLength(T)\nif (isDigest!T)\n{\n    enum size_t digestLength = (ReturnType!(T.finish)).length;\n}\n\n@safe pure nothrow @nogc\nunittest\n{\n    import std.digest.md : MD5;\n    import std.digest.sha : SHA1, SHA256, SHA512;\n    assert(digestLength!MD5 == 16);\n    assert(digestLength!SHA1 == 20);\n    assert(digestLength!SHA256 == 32);\n    assert(digestLength!SHA512 == 64);\n}\n\n/**\n * Wraps a template API hash struct into a Digest interface.\n * Modules providing digest implementations will usually provide\n * an alias for this template (e.g. MD5Digest, SHA1Digest, ...).\n */\nclass WrapperDigest(T)\nif (isDigest!T) : Digest\n{\n    protected:\n        T _digest;\n\n    public final:\n        /**\n         * Initializes the digest.\n         */\n        this()\n        {\n            _digest.start();\n        }\n\n        /**\n         * Use this to feed the digest with data.\n         * Also implements the $(REF isOutputRange, std,range,primitives)\n         * interface for `ubyte` and `const(ubyte)[]`.\n         */\n        @trusted nothrow void put(scope const(ubyte)[] data...)\n        {\n            _digest.put(data);\n        }\n\n        /**\n         * Resets the internal state of the digest.\n         * Note:\n         * $(LREF finish) calls this internally, so it's not necessary to call\n         * `reset` manually after a call to $(LREF finish).\n         */\n        @trusted nothrow void reset()\n        {\n            _digest.start();\n        }\n\n        /**\n         * This is the length in bytes of the hash value which is returned by $(LREF finish).\n         * It's also the required size of a buffer passed to $(LREF finish).\n         */\n        @trusted nothrow @property size_t length() const pure\n        {\n            return digestLength!T;\n        }\n\n        /**\n         * The finish function returns the hash value. It takes an optional buffer to copy the data\n         * into. If a buffer is passed, it must have a length at least $(LREF length) bytes.\n         *\n         * Example:\n         * --------\n         *\n         * import std.digest.md;\n         * ubyte[16] buf;\n         * auto hash = new WrapperDigest!MD5();\n         * hash.put(cast(ubyte) 0);\n         * auto result = hash.finish(buf[]);\n         * //The result is now in result (and in buf). If you pass a buffer which is bigger than\n         * //necessary, result will have the correct length, but buf will still have it's original\n         * //length\n         * --------\n         */\n        nothrow ubyte[] finish(ubyte[] buf)\n        in\n        {\n            assert(buf.length >= this.length, \"Given buffer is smaller than the local buffer.\");\n        }\n        do\n        {\n            enum string msg = \"Buffer needs to be at least \" ~ digestLength!(T).stringof ~ \" bytes \" ~\n                \"big, check \" ~ typeof(this).stringof ~ \".length!\";\n            asArray!(digestLength!T)(buf, msg) = _digest.finish();\n            return buf[0 .. digestLength!T];\n        }\n\n        ///ditto\n        @trusted nothrow ubyte[] finish()\n        {\n            enum len = digestLength!T;\n            auto buf = new ubyte[len];\n            asArray!(digestLength!T)(buf) = _digest.finish();\n            return buf;\n        }\n\n        version (StdDdoc)\n        {\n            /**\n             * Works like `finish` but does not reset the internal state, so it's possible\n             * to continue putting data into this WrapperDigest after a call to peek.\n             *\n             * These functions are only available if `hasPeek!T` is true.\n             */\n            @trusted ubyte[] peek(ubyte[] buf) const;\n            ///ditto\n            @trusted ubyte[] peek() const;\n        }\n        else static if (hasPeek!T)\n        {\n            @trusted ubyte[] peek(ubyte[] buf) const\n            in\n            {\n                assert(buf.length >= this.length, \"Given buffer is smaller than the local buffer.\");\n            }\n            do\n            {\n                enum string msg = \"Buffer needs to be at least \" ~ digestLength!(T).stringof ~ \" bytes \" ~\n                    \"big, check \" ~ typeof(this).stringof ~ \".length!\";\n                asArray!(digestLength!T)(buf, msg) = _digest.peek();\n                return buf[0 .. digestLength!T];\n            }\n\n            @trusted ubyte[] peek() const\n            {\n                enum len = digestLength!T;\n                auto buf = new ubyte[len];\n                asArray!(digestLength!T)(buf) = _digest.peek();\n                return buf;\n            }\n        }\n}\n\n///\n@system unittest\n{\n    import std.digest.md;\n    //Simple example\n    auto hash = new WrapperDigest!MD5();\n    hash.put(cast(ubyte) 0);\n    auto result = hash.finish();\n}\n\n///\n@system unittest\n{\n    //using a supplied buffer\n    import std.digest.md;\n    ubyte[16] buf;\n    auto hash = new WrapperDigest!MD5();\n    hash.put(cast(ubyte) 0);\n    auto result = hash.finish(buf[]);\n    //The result is now in result (and in buf). If you pass a buffer which is bigger than\n    //necessary, result will have the correct length, but buf will still have it's original\n    //length\n}\n\n@safe unittest\n{\n    // Test peek & length\n    import std.digest.crc;\n    auto hash = new WrapperDigest!CRC32();\n    assert(hash.length == 4);\n    hash.put(cast(const(ubyte[]))\"The quick brown fox jumps over the lazy dog\");\n    assert(hash.peek().toHexString() == \"39A34F41\");\n    ubyte[5] buf;\n    assert(hash.peek(buf).toHexString() == \"39A34F41\");\n}\n\n/**\n * Securely compares two digest representations while protecting against timing\n * attacks. Do not use `==` to compare digest representations.\n *\n * The attack happens as follows:\n *\n * $(OL\n *     $(LI An attacker wants to send harmful data to your server, which\n *     requires a integrity HMAC SHA1 token signed with a secret.)\n *     $(LI The length of the token is known to be 40 characters long due to its format,\n *     so the attacker first sends `\"0000000000000000000000000000000000000000\"`,\n *     then `\"1000000000000000000000000000000000000000\"`, and so on.)\n *     $(LI The given HMAC token is compared with the expected token using the\n *     `==` string comparison, which returns `false` as soon as the first wrong\n *     element is found. If a wrong element is found, then a rejection is sent\n *     back to the sender.)\n *     $(LI Eventually, the attacker is able to determine the first character in\n *     the correct token because the sever takes slightly longer to return a\n *     rejection. This is due to the comparison moving on to second item in\n *     the two arrays, seeing they are different, and then sending the rejection.)\n *     $(LI It may seem like too small of a difference in time for the attacker\n *     to notice, but security researchers have shown that differences as\n *     small as $(LINK2 http://www.cs.rice.edu/~dwallach/pub/crosby-timing2009.pdf,\n *     20µs can be reliably distinguished) even with network inconsistencies.)\n *     $(LI Repeat the process for each character until the attacker has the whole\n *     correct token and the server accepts the harmful data. This can be done\n *     in a week with the attacker pacing the attack to 10 requests per second\n *     with only one client.)\n * )\n *\n * This function defends against this attack by always comparing every single\n * item in the array if the two arrays are the same length. Therefore, this\n * function is always $(BIGOH n) for ranges of the same length.\n *\n * This attack can also be mitigated via rate limiting and banning IPs which have too\n * many rejected requests. However, this does not completely solve the problem,\n * as the attacker could be in control of a bot net. To fully defend against\n * the timing attack, rate limiting, banning IPs, and using this function\n * should be used together.\n *\n * Params:\n *     r1 = A digest representation\n *     r2 = A digest representation\n * Returns:\n *     `true` if both representations are equal, `false` otherwise\n * See_Also:\n *     $(LINK2 https://en.wikipedia.org/wiki/Timing_attack, The Wikipedia article\n *     on timing attacks).\n */\nbool secureEqual(R1, R2)(R1 r1, R2 r2)\nif (isInputRange!R1 && isInputRange!R2 && !isInfinite!R1 && !isInfinite!R2 &&\n    (isIntegral!(ElementEncodingType!R1) || isSomeChar!(ElementEncodingType!R1)) &&\n    !is(CommonType!(ElementEncodingType!R1, ElementEncodingType!R2) == void))\n{\n    static if (hasLength!R1 && hasLength!R2)\n        if (r1.length != r2.length)\n            return false;\n\n    int result;\n\n    static if (isRandomAccessRange!R1 && isRandomAccessRange!R2 &&\n               hasLength!R1 && hasLength!R2)\n    {\n        foreach (i; 0 .. r1.length)\n            result |= r1[i] ^ r2[i];\n    }\n    else static if (hasLength!R1 && hasLength!R2)\n    {\n        // Lengths are the same so we can squeeze out a bit of performance\n        // by not checking if r2 is empty\n        for (; !r1.empty; r1.popFront(), r2.popFront())\n        {\n            result |= r1.front ^ r2.front;\n        }\n    }\n    else\n    {\n        // Generic case, walk both ranges\n        for (; !r1.empty; r1.popFront(), r2.popFront())\n        {\n            if (r2.empty) return false;\n            result |= r1.front ^ r2.front;\n        }\n        if (!r2.empty) return false;\n    }\n\n    return result == 0;\n}\n\n///\n@system pure unittest\n{\n    import std.digest.hmac : hmac;\n    import std.digest.sha : SHA1;\n    import std.string : representation;\n\n    // a typical HMAC data integrity verification\n    auto secret = \"A7GZIP6TAQA6OHM7KZ42KB9303CEY0MOV5DD6NTV\".representation;\n    auto data = \"data\".representation;\n\n    auto hex1 = data.hmac!SHA1(secret).toHexString;\n    auto hex2 = data.hmac!SHA1(secret).toHexString;\n    auto hex3 = \"data1\".representation.hmac!SHA1(secret).toHexString;\n\n    assert( secureEqual(hex1[], hex2[]));\n    assert(!secureEqual(hex1[], hex3[]));\n}\n\n@system pure unittest\n{\n    import std.internal.test.dummyrange : ReferenceInputRange;\n    import std.range : takeExactly;\n    import std.string : representation;\n    import std.utf : byWchar, byDchar;\n\n    {\n        auto hex1 = \"02CA3484C375EDD3C0F08D3F50D119E61077\".representation;\n        auto hex2 = \"02CA3484C375EDD3C0F08D3F50D119E610779018\".representation;\n        assert(!secureEqual(hex1, hex2));\n    }\n    {\n        auto hex1 = \"02CA3484C375EDD3C0F08D3F50D119E610779018\"w.representation;\n        auto hex2 = \"02CA3484C375EDD3C0F08D3F50D119E610779018\"d.representation;\n        assert(secureEqual(hex1, hex2));\n    }\n    {\n        auto hex1 = \"02CA3484C375EDD3C0F08D3F50D119E610779018\".byWchar;\n        auto hex2 = \"02CA3484C375EDD3C0F08D3F50D119E610779018\".byDchar;\n        assert(secureEqual(hex1, hex2));\n    }\n    {\n        auto hex1 = \"02CA3484C375EDD3C0F08D3F50D119E61077\".byWchar;\n        auto hex2 = \"02CA3484C375EDD3C0F08D3F50D119E610779018\".byDchar;\n        assert(!secureEqual(hex1, hex2));\n    }\n    {\n        auto hex1 = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6, 7, 8]).takeExactly(9);\n        auto hex2 = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6, 7, 8]).takeExactly(9);\n        assert(secureEqual(hex1, hex2));\n    }\n    {\n        auto hex1 = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6, 7, 8]).takeExactly(9);\n        auto hex2 = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6, 7, 9]).takeExactly(9);\n        assert(!secureEqual(hex1, hex2));\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/digest/ripemd.d",
    "content": "/**\n * Computes RIPEMD-160 hashes of arbitrary data. RIPEMD-160 hashes are 20 byte quantities\n * that are like a checksum or CRC, but are more robust.\n *\n$(SCRIPT inhibitQuickIndex = 1;)\n\n$(DIVC quickindex,\n$(BOOKTABLE ,\n$(TR $(TH Category) $(TH Functions)\n)\n$(TR $(TDNW Template API) $(TD $(MYREF RIPEMD160)\n)\n)\n$(TR $(TDNW OOP API) $(TD $(MYREF RIPEMD160Digest))\n)\n$(TR $(TDNW Helpers) $(TD $(MYREF ripemd160Of))\n)\n)\n)\n\n * This module conforms to the APIs defined in $(MREF std, digest). To understand the\n * differences between the template and the OOP API, see $(MREF std, digest).\n *\n * This module publicly imports `std.digest` and can be used as a stand-alone\n * module.\n *\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n *\n * CTFE:\n * Digests do not work in CTFE\n *\n * Authors:\n * Kai Nacke $(BR)\n * The algorithm was designed by Hans Dobbertin, Antoon Bosselaers, and Bart Preneel. $(BR)\n * The D implementation is a direct translation of the ANSI C implementation by Antoon Bosselaers.\n *\n * References:\n * $(UL\n * $(LI $(LINK2 http://homes.esat.kuleuven.be/~bosselae/ripemd160.html, The hash function RIPEMD-160))\n * $(LI $(LINK2 http://en.wikipedia.org/wiki/RIPEMD-160, Wikipedia on RIPEMD-160))\n * )\n *\n * Source: $(PHOBOSSRC std/digest/ripemd.d)\n *\n */\n\nmodule std.digest.ripemd;\n\npublic import std.digest;\n\n///\n@safe unittest\n{\n    //Template API\n    import std.digest.md;\n\n    ubyte[20] hash = ripemd160Of(\"abc\");\n    assert(toHexString(hash) == \"8EB208F7E05D987A9B044A8E98C6B087F15A0BFC\");\n\n    //Feeding data\n    ubyte[1024] data;\n    RIPEMD160 md;\n    md.start();\n    md.put(data[]);\n    md.start(); //Start again\n    md.put(data[]);\n    hash = md.finish();\n}\n\n///\n@safe unittest\n{\n    //OOP API\n    import std.digest.md;\n\n    auto md = new RIPEMD160Digest();\n    ubyte[] hash = md.digest(\"abc\");\n    assert(toHexString(hash) == \"8EB208F7E05D987A9B044A8E98C6B087F15A0BFC\");\n\n    //Feeding data\n    ubyte[1024] data;\n    md.put(data[]);\n    md.reset(); //Start again\n    md.put(data[]);\n    hash = md.finish();\n}\n\n//rotateLeft rotates x left n bits\nprivate uint rotateLeft(uint x, uint n) @safe pure nothrow @nogc\n{\n    // With recently added optimization to DMD (commit 32ea0206 at 07/28/11), this is translated to rol.\n    // No assembler required.\n    return (x << n) | (x >> (32-n));\n}\n\n/**\n * Template API RIPEMD160 implementation.\n * See `std.digest` for differences between template and OOP API.\n */\nstruct RIPEMD160\n{\n    private:\n        // magic initialization constants\n        uint[5] _state = [0x67452301,0xefcdab89,0x98badcfe,0x10325476,0xc3d2e1f0]; // state (ABCDE)\n        ulong _count; //number of bits, modulo 2^64\n        ubyte[64] _buffer; // input buffer\n\n        static immutable ubyte[64] _padding =\n        [\n          0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n        ];\n\n        // F, G, H, I and J are basic RIPEMD160 functions\n        static @safe pure nothrow @nogc\n        {\n            uint F(uint x, uint y, uint z) { return x ^ y ^ z; }\n            uint G(uint x, uint y, uint z) { return (x & y) | (~x & z); }\n            uint H(uint x, uint y, uint z) { return (x | ~y) ^ z; }\n            uint I(uint x, uint y, uint z) { return (x & z) | (y & ~z); }\n            uint J(uint x, uint y, uint z) { return x ^ (y | ~z); }\n        }\n\n        /*\n         * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.\n         * Rotation is separate from addition to prevent recomputation.\n         */\n\n        /* the ten basic operations FF() through III() */\n        static void FF(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)\n            @safe pure nothrow @nogc\n        {\n            a += F(b, c, d) + x;\n            a = rotateLeft(a, s) + e;\n            c = rotateLeft(c, 10);\n        }\n\n        static void GG(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)\n            @safe pure nothrow @nogc\n        {\n            a += G(b, c, d) + x + 0x5a827999UL;\n            a = rotateLeft(a, s) + e;\n            c = rotateLeft(c, 10);\n        }\n\n        static void HH(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)\n            @safe pure nothrow @nogc\n        {\n            a += H(b, c, d) + x + 0x6ed9eba1UL;\n            a = rotateLeft(a, s) + e;\n            c = rotateLeft(c, 10);\n        }\n\n        static void II(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)\n            @safe pure nothrow @nogc\n        {\n            a += I(b, c, d) + x + 0x8f1bbcdcUL;\n            a = rotateLeft(a, s) + e;\n            c = rotateLeft(c, 10);\n        }\n\n        static void JJ(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)\n            @safe pure nothrow @nogc\n        {\n            a += J(b, c, d) + x + 0xa953fd4eUL;\n            a = rotateLeft(a, s) + e;\n            c = rotateLeft(c, 10);\n        }\n\n        /*\n         * FFF, GGG, HHH, and III transformations for parallel rounds 1, 2, 3, and 4.\n         * Rotation is separate from addition to prevent recomputation.\n         */\n\n        static void FFF(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)\n            @safe pure nothrow @nogc\n        {\n            a += F(b, c, d) + x;\n            a = rotateLeft(a, s) + e;\n            c = rotateLeft(c, 10);\n        }\n\n        static void GGG(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)\n            @safe pure nothrow @nogc\n        {\n            a += G(b, c, d) + x + 0x7a6d76e9UL;\n            a = rotateLeft(a, s) + e;\n            c = rotateLeft(c, 10);\n        }\n\n        static void HHH(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)\n            @safe pure nothrow @nogc\n        {\n            a += H(b, c, d) + x + 0x6d703ef3UL;\n            a = rotateLeft(a, s) + e;\n            c = rotateLeft(c, 10);\n        }\n\n        static void III(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)\n            @safe pure nothrow @nogc\n        {\n            a += I(b, c, d) + x + 0x5c4dd124UL;\n            a = rotateLeft(a, s) + e;\n            c = rotateLeft(c, 10);\n        }\n\n        static void JJJ(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)\n            @safe pure nothrow @nogc\n        {\n            a += J(b, c, d) + x + 0x50a28be6UL;\n            a = rotateLeft(a, s) + e;\n            c = rotateLeft(c, 10);\n        }\n\n        /*\n         * RIPEMD160 basic transformation. Transforms state based on block.\n         */\n\n        private void transform(const(ubyte[64])* block)\n            pure nothrow @nogc\n        {\n            uint aa = _state[0],\n                 bb = _state[1],\n                 cc = _state[2],\n                 dd = _state[3],\n                 ee = _state[4];\n            uint aaa = _state[0],\n                 bbb = _state[1],\n                 ccc = _state[2],\n                 ddd = _state[3],\n                 eee = _state[4];\n\n            uint[16] x = void;\n\n            version (BigEndian)\n            {\n                import std.bitmanip : littleEndianToNative;\n\n                for (size_t i = 0; i < 16; i++)\n                {\n                    x[i] = littleEndianToNative!uint(*cast(ubyte[4]*)&(*block)[i*4]);\n                }\n            }\n            else\n            {\n                (cast(ubyte*) x.ptr)[0 .. 64] = (cast(ubyte*) block)[0 .. 64];\n            }\n\n            /* round 1 */\n            FF(aa, bb, cc, dd, ee, x[ 0], 11);\n            FF(ee, aa, bb, cc, dd, x[ 1], 14);\n            FF(dd, ee, aa, bb, cc, x[ 2], 15);\n            FF(cc, dd, ee, aa, bb, x[ 3], 12);\n            FF(bb, cc, dd, ee, aa, x[ 4],  5);\n            FF(aa, bb, cc, dd, ee, x[ 5],  8);\n            FF(ee, aa, bb, cc, dd, x[ 6],  7);\n            FF(dd, ee, aa, bb, cc, x[ 7],  9);\n            FF(cc, dd, ee, aa, bb, x[ 8], 11);\n            FF(bb, cc, dd, ee, aa, x[ 9], 13);\n            FF(aa, bb, cc, dd, ee, x[10], 14);\n            FF(ee, aa, bb, cc, dd, x[11], 15);\n            FF(dd, ee, aa, bb, cc, x[12],  6);\n            FF(cc, dd, ee, aa, bb, x[13],  7);\n            FF(bb, cc, dd, ee, aa, x[14],  9);\n            FF(aa, bb, cc, dd, ee, x[15],  8);\n\n            /* round 2 */\n            GG(ee, aa, bb, cc, dd, x[ 7],  7);\n            GG(dd, ee, aa, bb, cc, x[ 4],  6);\n            GG(cc, dd, ee, aa, bb, x[13],  8);\n            GG(bb, cc, dd, ee, aa, x[ 1], 13);\n            GG(aa, bb, cc, dd, ee, x[10], 11);\n            GG(ee, aa, bb, cc, dd, x[ 6],  9);\n            GG(dd, ee, aa, bb, cc, x[15],  7);\n            GG(cc, dd, ee, aa, bb, x[ 3], 15);\n            GG(bb, cc, dd, ee, aa, x[12],  7);\n            GG(aa, bb, cc, dd, ee, x[ 0], 12);\n            GG(ee, aa, bb, cc, dd, x[ 9], 15);\n            GG(dd, ee, aa, bb, cc, x[ 5],  9);\n            GG(cc, dd, ee, aa, bb, x[ 2], 11);\n            GG(bb, cc, dd, ee, aa, x[14],  7);\n            GG(aa, bb, cc, dd, ee, x[11], 13);\n            GG(ee, aa, bb, cc, dd, x[ 8], 12);\n\n            /* round 3 */\n            HH(dd, ee, aa, bb, cc, x[ 3], 11);\n            HH(cc, dd, ee, aa, bb, x[10], 13);\n            HH(bb, cc, dd, ee, aa, x[14],  6);\n            HH(aa, bb, cc, dd, ee, x[ 4],  7);\n            HH(ee, aa, bb, cc, dd, x[ 9], 14);\n            HH(dd, ee, aa, bb, cc, x[15],  9);\n            HH(cc, dd, ee, aa, bb, x[ 8], 13);\n            HH(bb, cc, dd, ee, aa, x[ 1], 15);\n            HH(aa, bb, cc, dd, ee, x[ 2], 14);\n            HH(ee, aa, bb, cc, dd, x[ 7],  8);\n            HH(dd, ee, aa, bb, cc, x[ 0], 13);\n            HH(cc, dd, ee, aa, bb, x[ 6],  6);\n            HH(bb, cc, dd, ee, aa, x[13],  5);\n            HH(aa, bb, cc, dd, ee, x[11], 12);\n            HH(ee, aa, bb, cc, dd, x[ 5],  7);\n            HH(dd, ee, aa, bb, cc, x[12],  5);\n\n            /* round 4 */\n            II(cc, dd, ee, aa, bb, x[ 1], 11);\n            II(bb, cc, dd, ee, aa, x[ 9], 12);\n            II(aa, bb, cc, dd, ee, x[11], 14);\n            II(ee, aa, bb, cc, dd, x[10], 15);\n            II(dd, ee, aa, bb, cc, x[ 0], 14);\n            II(cc, dd, ee, aa, bb, x[ 8], 15);\n            II(bb, cc, dd, ee, aa, x[12],  9);\n            II(aa, bb, cc, dd, ee, x[ 4],  8);\n            II(ee, aa, bb, cc, dd, x[13],  9);\n            II(dd, ee, aa, bb, cc, x[ 3], 14);\n            II(cc, dd, ee, aa, bb, x[ 7],  5);\n            II(bb, cc, dd, ee, aa, x[15],  6);\n            II(aa, bb, cc, dd, ee, x[14],  8);\n            II(ee, aa, bb, cc, dd, x[ 5],  6);\n            II(dd, ee, aa, bb, cc, x[ 6],  5);\n            II(cc, dd, ee, aa, bb, x[ 2], 12);\n\n            /* round 5 */\n            JJ(bb, cc, dd, ee, aa, x[ 4],  9);\n            JJ(aa, bb, cc, dd, ee, x[ 0], 15);\n            JJ(ee, aa, bb, cc, dd, x[ 5],  5);\n            JJ(dd, ee, aa, bb, cc, x[ 9], 11);\n            JJ(cc, dd, ee, aa, bb, x[ 7],  6);\n            JJ(bb, cc, dd, ee, aa, x[12],  8);\n            JJ(aa, bb, cc, dd, ee, x[ 2], 13);\n            JJ(ee, aa, bb, cc, dd, x[10], 12);\n            JJ(dd, ee, aa, bb, cc, x[14],  5);\n            JJ(cc, dd, ee, aa, bb, x[ 1], 12);\n            JJ(bb, cc, dd, ee, aa, x[ 3], 13);\n            JJ(aa, bb, cc, dd, ee, x[ 8], 14);\n            JJ(ee, aa, bb, cc, dd, x[11], 11);\n            JJ(dd, ee, aa, bb, cc, x[ 6],  8);\n            JJ(cc, dd, ee, aa, bb, x[15],  5);\n            JJ(bb, cc, dd, ee, aa, x[13],  6);\n\n            /* parallel round 1 */\n            JJJ(aaa, bbb, ccc, ddd, eee, x[ 5],  8);\n            JJJ(eee, aaa, bbb, ccc, ddd, x[14],  9);\n            JJJ(ddd, eee, aaa, bbb, ccc, x[ 7],  9);\n            JJJ(ccc, ddd, eee, aaa, bbb, x[ 0], 11);\n            JJJ(bbb, ccc, ddd, eee, aaa, x[ 9], 13);\n            JJJ(aaa, bbb, ccc, ddd, eee, x[ 2], 15);\n            JJJ(eee, aaa, bbb, ccc, ddd, x[11], 15);\n            JJJ(ddd, eee, aaa, bbb, ccc, x[ 4],  5);\n            JJJ(ccc, ddd, eee, aaa, bbb, x[13],  7);\n            JJJ(bbb, ccc, ddd, eee, aaa, x[ 6],  7);\n            JJJ(aaa, bbb, ccc, ddd, eee, x[15],  8);\n            JJJ(eee, aaa, bbb, ccc, ddd, x[ 8], 11);\n            JJJ(ddd, eee, aaa, bbb, ccc, x[ 1], 14);\n            JJJ(ccc, ddd, eee, aaa, bbb, x[10], 14);\n            JJJ(bbb, ccc, ddd, eee, aaa, x[ 3], 12);\n            JJJ(aaa, bbb, ccc, ddd, eee, x[12],  6);\n\n            /* parallel round 2 */\n            III(eee, aaa, bbb, ccc, ddd, x[ 6],  9);\n            III(ddd, eee, aaa, bbb, ccc, x[11], 13);\n            III(ccc, ddd, eee, aaa, bbb, x[ 3], 15);\n            III(bbb, ccc, ddd, eee, aaa, x[ 7],  7);\n            III(aaa, bbb, ccc, ddd, eee, x[ 0], 12);\n            III(eee, aaa, bbb, ccc, ddd, x[13],  8);\n            III(ddd, eee, aaa, bbb, ccc, x[ 5],  9);\n            III(ccc, ddd, eee, aaa, bbb, x[10], 11);\n            III(bbb, ccc, ddd, eee, aaa, x[14],  7);\n            III(aaa, bbb, ccc, ddd, eee, x[15],  7);\n            III(eee, aaa, bbb, ccc, ddd, x[ 8], 12);\n            III(ddd, eee, aaa, bbb, ccc, x[12],  7);\n            III(ccc, ddd, eee, aaa, bbb, x[ 4],  6);\n            III(bbb, ccc, ddd, eee, aaa, x[ 9], 15);\n            III(aaa, bbb, ccc, ddd, eee, x[ 1], 13);\n            III(eee, aaa, bbb, ccc, ddd, x[ 2], 11);\n\n            /* parallel round 3 */\n            HHH(ddd, eee, aaa, bbb, ccc, x[15],  9);\n            HHH(ccc, ddd, eee, aaa, bbb, x[ 5],  7);\n            HHH(bbb, ccc, ddd, eee, aaa, x[ 1], 15);\n            HHH(aaa, bbb, ccc, ddd, eee, x[ 3], 11);\n            HHH(eee, aaa, bbb, ccc, ddd, x[ 7],  8);\n            HHH(ddd, eee, aaa, bbb, ccc, x[14],  6);\n            HHH(ccc, ddd, eee, aaa, bbb, x[ 6],  6);\n            HHH(bbb, ccc, ddd, eee, aaa, x[ 9], 14);\n            HHH(aaa, bbb, ccc, ddd, eee, x[11], 12);\n            HHH(eee, aaa, bbb, ccc, ddd, x[ 8], 13);\n            HHH(ddd, eee, aaa, bbb, ccc, x[12],  5);\n            HHH(ccc, ddd, eee, aaa, bbb, x[ 2], 14);\n            HHH(bbb, ccc, ddd, eee, aaa, x[10], 13);\n            HHH(aaa, bbb, ccc, ddd, eee, x[ 0], 13);\n            HHH(eee, aaa, bbb, ccc, ddd, x[ 4],  7);\n            HHH(ddd, eee, aaa, bbb, ccc, x[13],  5);\n\n            /* parallel round 4 */\n            GGG(ccc, ddd, eee, aaa, bbb, x[ 8], 15);\n            GGG(bbb, ccc, ddd, eee, aaa, x[ 6],  5);\n            GGG(aaa, bbb, ccc, ddd, eee, x[ 4],  8);\n            GGG(eee, aaa, bbb, ccc, ddd, x[ 1], 11);\n            GGG(ddd, eee, aaa, bbb, ccc, x[ 3], 14);\n            GGG(ccc, ddd, eee, aaa, bbb, x[11], 14);\n            GGG(bbb, ccc, ddd, eee, aaa, x[15],  6);\n            GGG(aaa, bbb, ccc, ddd, eee, x[ 0], 14);\n            GGG(eee, aaa, bbb, ccc, ddd, x[ 5],  6);\n            GGG(ddd, eee, aaa, bbb, ccc, x[12],  9);\n            GGG(ccc, ddd, eee, aaa, bbb, x[ 2], 12);\n            GGG(bbb, ccc, ddd, eee, aaa, x[13],  9);\n            GGG(aaa, bbb, ccc, ddd, eee, x[ 9], 12);\n            GGG(eee, aaa, bbb, ccc, ddd, x[ 7],  5);\n            GGG(ddd, eee, aaa, bbb, ccc, x[10], 15);\n            GGG(ccc, ddd, eee, aaa, bbb, x[14],  8);\n\n            /* parallel round 5 */\n            FFF(bbb, ccc, ddd, eee, aaa, x[12] ,  8);\n            FFF(aaa, bbb, ccc, ddd, eee, x[15] ,  5);\n            FFF(eee, aaa, bbb, ccc, ddd, x[10] , 12);\n            FFF(ddd, eee, aaa, bbb, ccc, x[ 4] ,  9);\n            FFF(ccc, ddd, eee, aaa, bbb, x[ 1] , 12);\n            FFF(bbb, ccc, ddd, eee, aaa, x[ 5] ,  5);\n            FFF(aaa, bbb, ccc, ddd, eee, x[ 8] , 14);\n            FFF(eee, aaa, bbb, ccc, ddd, x[ 7] ,  6);\n            FFF(ddd, eee, aaa, bbb, ccc, x[ 6] ,  8);\n            FFF(ccc, ddd, eee, aaa, bbb, x[ 2] , 13);\n            FFF(bbb, ccc, ddd, eee, aaa, x[13] ,  6);\n            FFF(aaa, bbb, ccc, ddd, eee, x[14] ,  5);\n            FFF(eee, aaa, bbb, ccc, ddd, x[ 0] , 15);\n            FFF(ddd, eee, aaa, bbb, ccc, x[ 3] , 13);\n            FFF(ccc, ddd, eee, aaa, bbb, x[ 9] , 11);\n            FFF(bbb, ccc, ddd, eee, aaa, x[11] , 11);\n\n            /* combine results */\n            ddd += cc + _state[1];               /* final result for _state[0] */\n            _state[1] = _state[2] + dd + eee;\n            _state[2] = _state[3] + ee + aaa;\n            _state[3] = _state[4] + aa + bbb;\n            _state[4] = _state[0] + bb + ccc;\n            _state[0] = ddd;\n\n            //Zeroize sensitive information.\n            x[] = 0;\n        }\n\n    public:\n        enum blockSize = 512;\n\n        /**\n         * Use this to feed the digest with data.\n         * Also implements the $(REF isOutputRange, std,range,primitives)\n         * interface for `ubyte` and `const(ubyte)[]`.\n         *\n         * Example:\n         * ----\n         * RIPEMD160 dig;\n         * dig.put(cast(ubyte) 0); //single ubyte\n         * dig.put(cast(ubyte) 0, cast(ubyte) 0); //variadic\n         * ubyte[10] buf;\n         * dig.put(buf); //buffer\n         * ----\n         */\n        void put(scope const(ubyte)[] data...) @trusted pure nothrow @nogc\n        {\n            uint i, index, partLen;\n            auto inputLen = data.length;\n\n            //Compute number of bytes mod 64\n            index = (cast(uint)_count >> 3) & (64 - 1);\n\n            //Update number of bits\n            _count += inputLen * 8;\n\n            partLen = 64 - index;\n\n            //Transform as many times as possible\n            if (inputLen >= partLen)\n            {\n                (&_buffer[index])[0 .. partLen] = data.ptr[0 .. partLen];\n                transform(&_buffer);\n\n                for (i = partLen; i + 63 < inputLen; i += 64)\n                {\n                    transform(cast(const(ubyte[64])*)(data[i .. i + 64].ptr));\n                }\n\n                index = 0;\n            }\n            else\n            {\n                i = 0;\n            }\n\n            /* Buffer remaining input */\n            if (inputLen - i)\n                (&_buffer[index])[0 .. inputLen-i] = (&data[i])[0 .. inputLen-i];\n        }\n\n        /**\n         * Used to (re)initialize the RIPEMD160 digest.\n         *\n         * Note:\n         * For this RIPEMD160 Digest implementation calling start after default construction\n         * is not necessary. Calling start is only necessary to reset the Digest.\n         *\n         * Generic code which deals with different Digest types should always call start though.\n         *\n         * Example:\n         * --------\n         * RIPEMD160 digest;\n         * //digest.start(); //Not necessary\n         * digest.put(0);\n         * --------\n         */\n        void start() @safe pure nothrow @nogc\n        {\n            this = RIPEMD160.init;\n        }\n\n        /**\n         * Returns the finished RIPEMD160 hash. This also calls $(LREF start) to\n         * reset the internal state.\n         *\n         * Example:\n         * --------\n         * //Simple example\n         * RIPEMD160 hash;\n         * hash.start();\n         * hash.put(cast(ubyte) 0);\n         * ubyte[20] result = hash.finish();\n         * assert(toHexString(result) == \"C81B94933420221A7AC004A90242D8B1D3E5070D\");\n         * --------\n         */\n        ubyte[20] finish() @trusted pure nothrow @nogc\n        {\n            import std.bitmanip : nativeToLittleEndian;\n\n            ubyte[20] data = void;\n            ubyte[8] bits = void;\n            uint index, padLen;\n\n            //Save number of bits\n            bits[0 .. 8] = nativeToLittleEndian(_count)[];\n\n            //Pad out to 56 mod 64\n            index = (cast(uint)_count >> 3) & (64 - 1);\n            padLen = (index < 56) ? (56 - index) : (120 - index);\n            put(_padding[0 .. padLen]);\n\n            //Append length (before padding)\n            put(bits);\n\n            //Store state in digest\n            data[0 .. 4]   = nativeToLittleEndian(_state[0])[];\n            data[4 .. 8]   = nativeToLittleEndian(_state[1])[];\n            data[8 .. 12]  = nativeToLittleEndian(_state[2])[];\n            data[12 .. 16] = nativeToLittleEndian(_state[3])[];\n            data[16 .. 20] = nativeToLittleEndian(_state[4])[];\n\n            /* Zeroize sensitive information. */\n            start();\n            return data;\n        }\n}\n\n///\n@safe unittest\n{\n    //Simple example, hashing a string using ripemd160Of helper function\n    ubyte[20] hash = ripemd160Of(\"abc\");\n    //Let's get a hash string\n    assert(toHexString(hash) == \"8EB208F7E05D987A9B044A8E98C6B087F15A0BFC\");\n}\n\n///\n@safe unittest\n{\n    //Using the basic API\n    RIPEMD160 hash;\n    hash.start();\n    ubyte[1024] data;\n    //Initialize data here...\n    hash.put(data);\n    ubyte[20] result = hash.finish();\n}\n\n///\n@safe unittest\n{\n    //Let's use the template features:\n    void doSomething(T)(ref T hash)\n    if (isDigest!T)\n    {\n        hash.put(cast(ubyte) 0);\n    }\n    RIPEMD160 md;\n    md.start();\n    doSomething(md);\n    assert(toHexString(md.finish()) == \"C81B94933420221A7AC004A90242D8B1D3E5070D\");\n}\n\n///\n@safe unittest\n{\n    //Simple example\n    RIPEMD160 hash;\n    hash.start();\n    hash.put(cast(ubyte) 0);\n    ubyte[20] result = hash.finish();\n    assert(toHexString(result) == \"C81B94933420221A7AC004A90242D8B1D3E5070D\");\n}\n\n@safe unittest\n{\n    assert(isDigest!RIPEMD160);\n}\n\n@system unittest\n{\n    import std.conv : hexString;\n    import std.range;\n\n    ubyte[20] digest;\n\n    RIPEMD160 md;\n    md.put(cast(ubyte[])\"abcdef\");\n    md.start();\n    md.put(cast(ubyte[])\"\");\n    assert(md.finish() == cast(ubyte[]) hexString!\"9c1185a5c5e9fc54612808977ee8f548b2258d31\");\n\n    digest = ripemd160Of(\"\");\n    assert(digest == cast(ubyte[]) hexString!\"9c1185a5c5e9fc54612808977ee8f548b2258d31\");\n\n    digest = ripemd160Of(\"a\");\n    assert(digest == cast(ubyte[]) hexString!\"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe\");\n\n    digest = ripemd160Of(\"abc\");\n    assert(digest == cast(ubyte[]) hexString!\"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc\");\n\n    digest = ripemd160Of(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    assert(digest == cast(ubyte[]) hexString!\"12a053384a9c0c88e405a06c27dcf49ada62eb2b\");\n\n    digest = ripemd160Of(\"message digest\");\n    assert(digest == cast(ubyte[]) hexString!\"5d0689ef49d2fae572b881b123a85ffa21595f36\");\n\n    digest = ripemd160Of(\"abcdefghijklmnopqrstuvwxyz\");\n    assert(digest == cast(ubyte[]) hexString!\"f71c27109c692c1b56bbdceb5b9d2865b3708dbc\");\n\n    digest = ripemd160Of(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    assert(digest == cast(ubyte[]) hexString!\"b0e20b6e3116640286ed3a87a5713079b21f5189\");\n\n    digest = ripemd160Of(\"1234567890123456789012345678901234567890\"~\n                    \"1234567890123456789012345678901234567890\");\n    assert(digest == cast(ubyte[]) hexString!\"9b752e45573d4b39f4dbd3323cab82bf63326bfb\");\n\n    enum ubyte[20] input = cast(ubyte[20]) hexString!\"f71c27109c692c1b56bbdceb5b9d2865b3708dbc\";\n    assert(toHexString(input)\n        == \"F71C27109C692C1B56BBDCEB5B9D2865B3708DBC\");\n\n    ubyte[] onemilliona = new ubyte[1000000];\n    onemilliona[] = 'a';\n    digest = ripemd160Of(onemilliona);\n    assert(digest == cast(ubyte[]) hexString!\"52783243c1697bdbe16d37f97f68f08325dc1528\");\n\n    auto oneMillionRange = repeat!ubyte(cast(ubyte)'a', 1000000);\n    digest = ripemd160Of(oneMillionRange);\n    assert(digest == cast(ubyte[]) hexString!\"52783243c1697bdbe16d37f97f68f08325dc1528\");\n}\n\n/**\n * This is a convenience alias for $(REF digest, std,digest) using the\n * RIPEMD160 implementation.\n */\n//simple alias doesn't work here, hope this gets inlined...\nauto ripemd160Of(T...)(T data)\n{\n    return digest!(RIPEMD160, T)(data);\n}\n\n///\n@safe unittest\n{\n    ubyte[20] hash = ripemd160Of(\"abc\");\n    assert(hash == digest!RIPEMD160(\"abc\"));\n}\n\n/**\n * OOP API RIPEMD160 implementation.\n * See `std.digest` for differences between template and OOP API.\n *\n * This is an alias for $(D $(REF WrapperDigest, std,digest)!RIPEMD160),\n * see there for more information.\n */\nalias RIPEMD160Digest = WrapperDigest!RIPEMD160;\n\n///\n@safe unittest\n{\n    //Simple example, hashing a string using Digest.digest helper function\n    auto md = new RIPEMD160Digest();\n    ubyte[] hash = md.digest(\"abc\");\n    //Let's get a hash string\n    assert(toHexString(hash) == \"8EB208F7E05D987A9B044A8E98C6B087F15A0BFC\");\n}\n\n///\n@system unittest\n{\n    //Let's use the OOP features:\n    void test(Digest dig)\n    {\n      dig.put(cast(ubyte) 0);\n    }\n    auto md = new RIPEMD160Digest();\n    test(md);\n\n    //Let's use a custom buffer:\n    ubyte[20] buf;\n    ubyte[] result = md.finish(buf[]);\n    assert(toHexString(result) == \"C81B94933420221A7AC004A90242D8B1D3E5070D\");\n}\n\n@system unittest\n{\n    import std.conv : hexString;\n    auto md = new RIPEMD160Digest();\n\n    md.put(cast(ubyte[])\"abcdef\");\n    md.reset();\n    md.put(cast(ubyte[])\"\");\n    assert(md.finish() == cast(ubyte[]) hexString!\"9c1185a5c5e9fc54612808977ee8f548b2258d31\");\n\n    md.put(cast(ubyte[])\"abcdefghijklmnopqrstuvwxyz\");\n    ubyte[20] result;\n    auto result2 = md.finish(result[]);\n    assert(result[0 .. 20] == result2 && result2 == cast(ubyte[]) hexString!\"f71c27109c692c1b56bbdceb5b9d2865b3708dbc\");\n\n    debug\n    {\n        import std.exception;\n        assertThrown!Error(md.finish(result[0 .. 19]));\n    }\n\n    assert(md.length == 20);\n\n    assert(md.digest(\"\") == cast(ubyte[]) hexString!\"9c1185a5c5e9fc54612808977ee8f548b2258d31\");\n\n    assert(md.digest(\"a\") == cast(ubyte[]) hexString!\"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe\");\n\n    assert(md.digest(\"abc\") == cast(ubyte[]) hexString!\"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc\");\n\n    assert(md.digest(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\")\n           == cast(ubyte[]) hexString!\"12a053384a9c0c88e405a06c27dcf49ada62eb2b\");\n\n    assert(md.digest(\"message digest\") == cast(ubyte[]) hexString!\"5d0689ef49d2fae572b881b123a85ffa21595f36\");\n\n    assert(md.digest(\"abcdefghijklmnopqrstuvwxyz\")\n           == cast(ubyte[]) hexString!\"f71c27109c692c1b56bbdceb5b9d2865b3708dbc\");\n\n    assert(md.digest(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\")\n           == cast(ubyte[]) hexString!\"b0e20b6e3116640286ed3a87a5713079b21f5189\");\n\n    assert(md.digest(\"1234567890123456789012345678901234567890\",\n                                   \"1234567890123456789012345678901234567890\")\n           == cast(ubyte[]) hexString!\"9b752e45573d4b39f4dbd3323cab82bf63326bfb\");\n\n    assert(md.digest(new ubyte[160/8]) // 160 zero bits\n           == cast(ubyte[]) hexString!\"5c00bd4aca04a9057c09b20b05f723f2e23deb65\");\n}\n"
  },
  {
    "path": "libphobos/src/std/digest/sha.d",
    "content": "// Written in the D programming language.\n/**\n * Computes SHA1 and SHA2 hashes of arbitrary data. SHA hashes are 20 to 64 byte\n * quantities (depending on the SHA algorithm) that are like a checksum or CRC,\n * but are more robust.\n *\n$(SCRIPT inhibitQuickIndex = 1;)\n\n$(DIVC quickindex,\n$(BOOKTABLE ,\n$(TR $(TH Category) $(TH Functions)\n)\n$(TR $(TDNW Template API) $(TD $(MYREF SHA1)\n)\n)\n$(TR $(TDNW OOP API) $(TD $(MYREF SHA1Digest))\n)\n$(TR $(TDNW Helpers) $(TD $(MYREF sha1Of))\n)\n)\n)\n\n * SHA2 comes in several different versions, all supported by this module:\n * SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224 and SHA-512/256.\n *\n * This module conforms to the APIs defined in $(MREF std, digest). To understand the\n * differences between the template and the OOP API, see $(MREF std, digest).\n *\n * This module publicly imports `std.digest` and can be used as a stand-alone\n * module.\n *\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n *\n * CTFE:\n * Digests do not work in CTFE\n *\n * Authors:\n * The routines and algorithms are derived from the\n * $(I Secure Hash Signature Standard (SHS) (FIPS PUB 180-2)). $(BR )\n * Kai Nacke, Johannes Pfau, Nick Sabalausky\n *\n * References:\n * $(UL\n * $(LI $(LINK2 http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf, FIPS PUB180-2))\n * $(LI $(LINK2 http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1/, Fast implementation of SHA1))\n * $(LI $(LINK2 http://en.wikipedia.org/wiki/Secure_Hash_Algorithm, Wikipedia article about SHA))\n * )\n *\n * Source: $(PHOBOSSRC std/digest/sha.d)\n *\n */\n\n/*          Copyright Kai Nacke 2012.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.digest.sha;\n\n///\n@safe unittest\n{\n    //Template API\n    import std.digest.sha;\n\n    ubyte[20] hash1 = sha1Of(\"abc\");\n    assert(toHexString(hash1) == \"A9993E364706816ABA3E25717850C26C9CD0D89D\");\n\n    ubyte[28] hash224 = sha224Of(\"abc\");\n    assert(toHexString(hash224) == \"23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7\");\n\n    //Feeding data\n    ubyte[1024] data;\n    SHA1 sha1;\n    sha1.start();\n    sha1.put(data[]);\n    sha1.start(); //Start again\n    sha1.put(data[]);\n    hash1 = sha1.finish();\n}\n\n///\n@safe unittest\n{\n    //OOP API\n    import std.digest.sha;\n\n    auto sha1 = new SHA1Digest();\n    ubyte[] hash1 = sha1.digest(\"abc\");\n    assert(toHexString(hash1) == \"A9993E364706816ABA3E25717850C26C9CD0D89D\");\n\n    auto sha224 = new SHA224Digest();\n    ubyte[] hash224 = sha224.digest(\"abc\");\n    assert(toHexString(hash224) == \"23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7\");\n\n    //Feeding data\n    ubyte[1024] data;\n    sha1.put(data[]);\n    sha1.reset(); //Start again\n    sha1.put(data[]);\n    hash1 = sha1.finish();\n}\n\nversion (Win64)\n{\n    // wrong calling convention\n}\nelse version (D_InlineAsm_X86)\n{\n    version (D_PIC) {} // Bugzilla 9378\n    else private version = USE_SSSE3;\n}\nelse version (D_InlineAsm_X86_64)\n{\n    private version = USE_SSSE3;\n}\n\nversion (LittleEndian) import core.bitop : bswap;\n\npublic import std.digest;\n\n/*\n * Helper methods for encoding the buffer.\n * Can be removed if the optimizer can inline the methods from std.bitmanip.\n */\nprivate ubyte[8] nativeToBigEndian(ulong val) @trusted pure nothrow @nogc\n{\n    version (LittleEndian)\n        immutable ulong res = (cast(ulong)  bswap(cast(uint) val)) << 32 | bswap(cast(uint) (val >> 32));\n    else\n        immutable ulong res = val;\n    return *cast(ubyte[8]*) &res;\n}\n\nprivate ubyte[4] nativeToBigEndian(uint val) @trusted pure nothrow @nogc\n{\n    version (LittleEndian)\n        immutable uint res = bswap(val);\n    else\n        immutable uint res = val;\n    return *cast(ubyte[4]*) &res;\n}\n\nprivate ulong bigEndianToNative(ubyte[8] val) @trusted pure nothrow @nogc\n{\n    version (LittleEndian)\n    {\n        import std.bitmanip : bigEndianToNative;\n        return bigEndianToNative!ulong(val);\n    }\n    else\n        return *cast(ulong*) &val;\n}\n\nprivate uint bigEndianToNative(ubyte[4] val) @trusted pure nothrow @nogc\n{\n    version (LittleEndian)\n        return bswap(*cast(uint*) &val);\n    else\n        return *cast(uint*) &val;\n}\n\n//rotateLeft rotates x left n bits\nprivate uint rotateLeft(uint x, uint n) @safe pure nothrow @nogc\n{\n    // With recently added optimization to DMD (commit 32ea0206 at 07/28/11), this is translated to rol.\n    // No assembler required.\n    return (x << n) | (x >> (32-n));\n}\n\n//rotateRight rotates x right n bits\nprivate uint rotateRight(uint x, uint n) @safe pure nothrow @nogc\n{\n    return (x >> n) | (x << (32-n));\n}\nprivate ulong rotateRight(ulong x, uint n) @safe pure nothrow @nogc\n{\n    return (x >> n) | (x << (64-n));\n}\n\n/**\n * Template API SHA1/SHA2 implementation. Supports: SHA-1, SHA-224, SHA-256,\n * SHA-384, SHA-512, SHA-512/224 and SHA-512/256.\n *\n * The hashBlockSize and digestSize are in bits. However, it's likely easier to\n * simply use the convenience aliases: SHA1, SHA224, SHA256, SHA384, SHA512,\n * SHA512_224 and SHA512_256.\n *\n * See `std.digest` for differences between template and OOP API.\n */\nstruct SHA(uint hashBlockSize, uint digestSize)\n{\n    enum blockSize = hashBlockSize;\n\n    static assert(blockSize == 512 || blockSize == 1024,\n        \"Invalid SHA blockSize, must be 512 or 1024\");\n    static assert(digestSize == 160 || digestSize == 224 || digestSize == 256 || digestSize == 384 || digestSize == 512,\n        \"Invalid SHA digestSize, must be 224, 256, 384 or 512\");\n    static assert(!(blockSize == 512 && digestSize > 256),\n        \"Invalid SHA digestSize for a blockSize of 512. The digestSize must be 160, 224 or 256.\");\n    static assert(!(blockSize == 1024 && digestSize < 224),\n        \"Invalid SHA digestSize for a blockSize of 1024. The digestSize must be 224, 256, 384 or 512.\");\n\n    static if (digestSize == 160) /* SHA-1 */\n    {\n        version (USE_SSSE3)\n        {\n            import core.cpuid : ssse3;\n            import std.internal.digest.sha_SSSE3 : sse3_constants=constants, transformSSSE3;\n\n            static void transform(uint[5]* state, const(ubyte[64])* block) pure nothrow @nogc\n            {\n                if (ssse3)\n                {\n                    version (D_InlineAsm_X86_64)\n                        // constants as extra argument for PIC, see Bugzilla 9378\n                        transformSSSE3(state, block, &sse3_constants);\n                    else\n                        transformSSSE3(state, block);\n                }\n                else\n                    transformX86(state, block);\n            }\n        }\n        else\n        {\n            alias transform = transformX86;\n        }\n    }\n    else static if (blockSize == 512) /* SHA-224, SHA-256 */\n        alias transform = transformSHA2!uint;\n    else static if (blockSize == 1024) /* SHA-384, SHA-512, SHA-512/224, SHA-512/256 */\n        alias transform = transformSHA2!ulong;\n    else\n        static assert(0);\n\n    private:\n        /* magic initialization constants - state (ABCDEFGH) */\n        static if (blockSize == 512 && digestSize == 160) /* SHA-1 */\n        {\n            uint[5] state =\n            [0x67452301,0xefcdab89,0x98badcfe,0x10325476,0xc3d2e1f0];\n        }\n        else static if (blockSize == 512 && digestSize == 224) /* SHA-224 */\n        {\n            uint[8] state = [\n                0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,\n                0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,\n            ];\n        }\n        else static if (blockSize == 512 && digestSize == 256) /* SHA-256 */\n        {\n            uint[8] state = [\n                0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\n                0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n            ];\n        }\n        else static if (blockSize == 1024 && digestSize == 224) /* SHA-512/224 */\n        {\n            ulong[8] state = [\n                0x8C3D37C8_19544DA2, 0x73E19966_89DCD4D6,\n                0x1DFAB7AE_32FF9C82, 0x679DD514_582F9FCF,\n                0x0F6D2B69_7BD44DA8, 0x77E36F73_04C48942,\n                0x3F9D85A8_6A1D36C8, 0x1112E6AD_91D692A1,\n            ];\n        }\n        else static if (blockSize == 1024 && digestSize == 256) /* SHA-512/256 */\n        {\n            ulong[8] state = [\n                0x22312194_FC2BF72C, 0x9F555FA3_C84C64C2,\n                0x2393B86B_6F53B151, 0x96387719_5940EABD,\n                0x96283EE2_A88EFFE3, 0xBE5E1E25_53863992,\n                0x2B0199FC_2C85B8AA, 0x0EB72DDC_81C52CA2,\n            ];\n        }\n        else static if (blockSize == 1024 && digestSize == 384) /* SHA-384 */\n        {\n            ulong[8] state = [\n                0xcbbb9d5d_c1059ed8, 0x629a292a_367cd507,\n                0x9159015a_3070dd17, 0x152fecd8_f70e5939,\n                0x67332667_ffc00b31, 0x8eb44a87_68581511,\n                0xdb0c2e0d_64f98fa7, 0x47b5481d_befa4fa4,\n            ];\n        }\n        else static if (blockSize == 1024 && digestSize == 512) /* SHA-512 */\n        {\n            ulong[8] state = [\n                0x6a09e667_f3bcc908, 0xbb67ae85_84caa73b,\n                0x3c6ef372_fe94f82b, 0xa54ff53a_5f1d36f1,\n                0x510e527f_ade682d1, 0x9b05688c_2b3e6c1f,\n                0x1f83d9ab_fb41bd6b, 0x5be0cd19_137e2179,\n            ];\n        }\n        else\n            static assert(0);\n\n        /* constants */\n        static if (blockSize == 512)\n        {\n            static immutable uint[64] constants = [\n                0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n                0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n                0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n                0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n                0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n                0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n                0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n                0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n            ];\n        }\n        else static if (blockSize == 1024)\n        {\n            static immutable ulong[80] constants = [\n                0x428a2f98_d728ae22, 0x71374491_23ef65cd, 0xb5c0fbcf_ec4d3b2f, 0xe9b5dba5_8189dbbc,\n                0x3956c25b_f348b538, 0x59f111f1_b605d019, 0x923f82a4_af194f9b, 0xab1c5ed5_da6d8118,\n                0xd807aa98_a3030242, 0x12835b01_45706fbe, 0x243185be_4ee4b28c, 0x550c7dc3_d5ffb4e2,\n                0x72be5d74_f27b896f, 0x80deb1fe_3b1696b1, 0x9bdc06a7_25c71235, 0xc19bf174_cf692694,\n                0xe49b69c1_9ef14ad2, 0xefbe4786_384f25e3, 0x0fc19dc6_8b8cd5b5, 0x240ca1cc_77ac9c65,\n                0x2de92c6f_592b0275, 0x4a7484aa_6ea6e483, 0x5cb0a9dc_bd41fbd4, 0x76f988da_831153b5,\n                0x983e5152_ee66dfab, 0xa831c66d_2db43210, 0xb00327c8_98fb213f, 0xbf597fc7_beef0ee4,\n                0xc6e00bf3_3da88fc2, 0xd5a79147_930aa725, 0x06ca6351_e003826f, 0x14292967_0a0e6e70,\n                0x27b70a85_46d22ffc, 0x2e1b2138_5c26c926, 0x4d2c6dfc_5ac42aed, 0x53380d13_9d95b3df,\n                0x650a7354_8baf63de, 0x766a0abb_3c77b2a8, 0x81c2c92e_47edaee6, 0x92722c85_1482353b,\n                0xa2bfe8a1_4cf10364, 0xa81a664b_bc423001, 0xc24b8b70_d0f89791, 0xc76c51a3_0654be30,\n                0xd192e819_d6ef5218, 0xd6990624_5565a910, 0xf40e3585_5771202a, 0x106aa070_32bbd1b8,\n                0x19a4c116_b8d2d0c8, 0x1e376c08_5141ab53, 0x2748774c_df8eeb99, 0x34b0bcb5_e19b48a8,\n                0x391c0cb3_c5c95a63, 0x4ed8aa4a_e3418acb, 0x5b9cca4f_7763e373, 0x682e6ff3_d6b2b8a3,\n                0x748f82ee_5defb2fc, 0x78a5636f_43172f60, 0x84c87814_a1f0ab72, 0x8cc70208_1a6439ec,\n                0x90befffa_23631e28, 0xa4506ceb_de82bde9, 0xbef9a3f7_b2c67915, 0xc67178f2_e372532b,\n                0xca273ece_ea26619c, 0xd186b8c7_21c0c207, 0xeada7dd6_cde0eb1e, 0xf57d4f7f_ee6ed178,\n                0x06f067aa_72176fba, 0x0a637dc5_a2c898a6, 0x113f9804_bef90dae, 0x1b710b35_131c471b,\n                0x28db77f5_23047d84, 0x32caab7b_40c72493, 0x3c9ebe0a_15c9bebc, 0x431d67c4_9c100d4c,\n                0x4cc5d4be_cb3e42b6, 0x597f299c_fc657e2a, 0x5fcb6fab_3ad6faec, 0x6c44198c_4a475817,\n            ];\n        }\n        else\n            static assert(0);\n\n        /*\n         * number of bits, modulo 2^64 (ulong[1]) or 2^128 (ulong[2]),\n         * should just use ucent instead of ulong[2] once it's available\n         */\n        ulong[blockSize/512] count;\n        ubyte[blockSize/8]   buffer; /* input buffer */\n\n        static immutable ubyte[128] padding =\n        [\n          0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\n          0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n        ];\n\n        /*\n         * Basic SHA1/SHA2 functions.\n         */\n        static @safe pure nothrow @nogc\n        {\n            /* All SHA1/SHA2 */\n            T Ch(T)(T x, T y, T z) { return z ^ (x & (y ^ z)); }\n            T Maj(T)(T x, T y, T z) { return (x & y) | (z & (x ^ y)); }\n\n            /* SHA-1 */\n            uint Parity(uint x, uint y, uint z) { return x ^ y ^ z; }\n\n            /* SHA-224, SHA-256 */\n            uint BigSigma0(uint x) { return rotateRight(x, 2) ^ rotateRight(x, 13) ^ rotateRight(x, 22); }\n            uint BigSigma1(uint x) { return rotateRight(x, 6) ^ rotateRight(x, 11) ^ rotateRight(x, 25); }\n            uint SmSigma0(uint x) { return rotateRight(x, 7) ^ rotateRight(x, 18) ^ x >> 3; }\n            uint SmSigma1(uint x) { return rotateRight(x, 17) ^ rotateRight(x, 19) ^ x >> 10; }\n\n            /* SHA-384, SHA-512, SHA-512/224, SHA-512/256 */\n            ulong BigSigma0(ulong x) { return rotateRight(x, 28) ^ rotateRight(x, 34) ^ rotateRight(x, 39); }\n            ulong BigSigma1(ulong x) { return rotateRight(x, 14) ^ rotateRight(x, 18) ^ rotateRight(x, 41); }\n            ulong SmSigma0(ulong x) { return rotateRight(x, 1) ^ rotateRight(x, 8) ^ x >> 7; }\n            ulong SmSigma1(ulong x) { return rotateRight(x, 19) ^ rotateRight(x, 61) ^ x >> 6; }\n        }\n\n        /*\n         * SHA1 basic transformation. Transforms state based on block.\n         */\n        static void T_0_15(int i, const(ubyte[64])* input, ref uint[16] W, uint A, ref uint B, uint C, uint D,\n            uint E, ref uint T) pure nothrow @nogc\n        {\n            uint Wi = W[i] = bigEndianToNative(*cast(ubyte[4]*)&((*input)[i*4]));\n            T = Ch(B, C, D) + E + rotateLeft(A, 5) + Wi + 0x5a827999;\n            B = rotateLeft(B, 30);\n        }\n\n        static void T_16_19(int i, ref uint[16] W, uint A, ref uint B, uint C, uint D, uint E, ref uint T)\n            pure nothrow @nogc\n        {\n            W[i&15] = rotateLeft(W[(i-3)&15] ^ W[(i-8)&15] ^ W[(i-14)&15] ^ W[(i-16)&15], 1);\n            T = Ch(B, C, D) + E + rotateLeft(A, 5) + W[i&15] + 0x5a827999;\n            B = rotateLeft(B, 30);\n        }\n\n        static void T_20_39(int i, ref uint[16] W, uint A, ref uint B, uint C, uint D, uint E,\n            ref uint T) pure nothrow @nogc\n        {\n            W[i&15] = rotateLeft(W[(i-3)&15] ^ W[(i-8)&15] ^ W[(i-14)&15] ^ W[(i-16)&15], 1);\n            T = Parity(B, C, D) + E + rotateLeft(A, 5) + W[i&15] + 0x6ed9eba1;\n            B = rotateLeft(B, 30);\n        }\n\n        static void T_40_59(int i, ref uint[16] W, uint A, ref uint B, uint C, uint D, uint E,\n            ref uint T) pure nothrow @nogc\n        {\n            W[i&15] = rotateLeft(W[(i-3)&15] ^ W[(i-8)&15] ^ W[(i-14)&15] ^ W[(i-16)&15], 1);\n            T = Maj(B, C, D) + E + rotateLeft(A, 5) + W[i&15] + 0x8f1bbcdc;\n            B = rotateLeft(B, 30);\n        }\n\n        static void T_60_79(int i, ref uint[16] W, uint A, ref uint B, uint C, uint D, uint E,\n            ref uint T) pure nothrow @nogc\n        {\n            W[i&15] = rotateLeft(W[(i-3)&15] ^ W[(i-8)&15] ^ W[(i-14)&15] ^ W[(i-16)&15], 1);\n            T = Parity(B, C, D) + E + rotateLeft(A, 5) + W[i&15] + 0xca62c1d6;\n            B = rotateLeft(B, 30);\n        }\n\n        private static void transformX86(uint[5]* state, const(ubyte[64])* block) pure nothrow @nogc\n        {\n            uint A, B, C, D, E, T;\n            uint[16] W = void;\n\n            A = (*state)[0];\n            B = (*state)[1];\n            C = (*state)[2];\n            D = (*state)[3];\n            E = (*state)[4];\n\n            T_0_15 ( 0, block, W, A, B, C, D, E, T);\n            T_0_15 ( 1, block, W, T, A, B, C, D, E);\n            T_0_15 ( 2, block, W, E, T, A, B, C, D);\n            T_0_15 ( 3, block, W, D, E, T, A, B, C);\n            T_0_15 ( 4, block, W, C, D, E, T, A, B);\n            T_0_15 ( 5, block, W, B, C, D, E, T, A);\n            T_0_15 ( 6, block, W, A, B, C, D, E, T);\n            T_0_15 ( 7, block, W, T, A, B, C, D, E);\n            T_0_15 ( 8, block, W, E, T, A, B, C, D);\n            T_0_15 ( 9, block, W, D, E, T, A, B, C);\n            T_0_15 (10, block, W, C, D, E, T, A, B);\n            T_0_15 (11, block, W, B, C, D, E, T, A);\n            T_0_15 (12, block, W, A, B, C, D, E, T);\n            T_0_15 (13, block, W, T, A, B, C, D, E);\n            T_0_15 (14, block, W, E, T, A, B, C, D);\n            T_0_15 (15, block, W, D, E, T, A, B, C);\n            T_16_19(16, W, C, D, E, T, A, B);\n            T_16_19(17, W, B, C, D, E, T, A);\n            T_16_19(18, W, A, B, C, D, E, T);\n            T_16_19(19, W, T, A, B, C, D, E);\n            T_20_39(20, W, E, T, A, B, C, D);\n            T_20_39(21, W, D, E, T, A, B, C);\n            T_20_39(22, W, C, D, E, T, A, B);\n            T_20_39(23, W, B, C, D, E, T, A);\n            T_20_39(24, W, A, B, C, D, E, T);\n            T_20_39(25, W, T, A, B, C, D, E);\n            T_20_39(26, W, E, T, A, B, C, D);\n            T_20_39(27, W, D, E, T, A, B, C);\n            T_20_39(28, W, C, D, E, T, A, B);\n            T_20_39(29, W, B, C, D, E, T, A);\n            T_20_39(30, W, A, B, C, D, E, T);\n            T_20_39(31, W, T, A, B, C, D, E);\n            T_20_39(32, W, E, T, A, B, C, D);\n            T_20_39(33, W, D, E, T, A, B, C);\n            T_20_39(34, W, C, D, E, T, A, B);\n            T_20_39(35, W, B, C, D, E, T, A);\n            T_20_39(36, W, A, B, C, D, E, T);\n            T_20_39(37, W, T, A, B, C, D, E);\n            T_20_39(38, W, E, T, A, B, C, D);\n            T_20_39(39, W, D, E, T, A, B, C);\n            T_40_59(40, W, C, D, E, T, A, B);\n            T_40_59(41, W, B, C, D, E, T, A);\n            T_40_59(42, W, A, B, C, D, E, T);\n            T_40_59(43, W, T, A, B, C, D, E);\n            T_40_59(44, W, E, T, A, B, C, D);\n            T_40_59(45, W, D, E, T, A, B, C);\n            T_40_59(46, W, C, D, E, T, A, B);\n            T_40_59(47, W, B, C, D, E, T, A);\n            T_40_59(48, W, A, B, C, D, E, T);\n            T_40_59(49, W, T, A, B, C, D, E);\n            T_40_59(50, W, E, T, A, B, C, D);\n            T_40_59(51, W, D, E, T, A, B, C);\n            T_40_59(52, W, C, D, E, T, A, B);\n            T_40_59(53, W, B, C, D, E, T, A);\n            T_40_59(54, W, A, B, C, D, E, T);\n            T_40_59(55, W, T, A, B, C, D, E);\n            T_40_59(56, W, E, T, A, B, C, D);\n            T_40_59(57, W, D, E, T, A, B, C);\n            T_40_59(58, W, C, D, E, T, A, B);\n            T_40_59(59, W, B, C, D, E, T, A);\n            T_60_79(60, W, A, B, C, D, E, T);\n            T_60_79(61, W, T, A, B, C, D, E);\n            T_60_79(62, W, E, T, A, B, C, D);\n            T_60_79(63, W, D, E, T, A, B, C);\n            T_60_79(64, W, C, D, E, T, A, B);\n            T_60_79(65, W, B, C, D, E, T, A);\n            T_60_79(66, W, A, B, C, D, E, T);\n            T_60_79(67, W, T, A, B, C, D, E);\n            T_60_79(68, W, E, T, A, B, C, D);\n            T_60_79(69, W, D, E, T, A, B, C);\n            T_60_79(70, W, C, D, E, T, A, B);\n            T_60_79(71, W, B, C, D, E, T, A);\n            T_60_79(72, W, A, B, C, D, E, T);\n            T_60_79(73, W, T, A, B, C, D, E);\n            T_60_79(74, W, E, T, A, B, C, D);\n            T_60_79(75, W, D, E, T, A, B, C);\n            T_60_79(76, W, C, D, E, T, A, B);\n            T_60_79(77, W, B, C, D, E, T, A);\n            T_60_79(78, W, A, B, C, D, E, T);\n            T_60_79(79, W, T, A, B, C, D, E);\n\n            (*state)[0] += E;\n            (*state)[1] += T;\n            (*state)[2] += A;\n            (*state)[3] += B;\n            (*state)[4] += C;\n\n            /* Zeroize sensitive information. */\n            W[] = 0;\n        }\n\n        /*\n         * SHA2 basic transformation. Transforms state based on block.\n         */\n        static void T_SHA2_0_15(Word)(int i, const(ubyte[blockSize/8])* input, ref Word[16] W,\n            Word A, Word B, Word C, ref Word D, Word E, Word F, Word G, ref Word H, Word K)\n            pure nothrow @nogc\n        {\n            Word Wi = W[i] = bigEndianToNative(*cast(ubyte[Word.sizeof]*)&((*input)[i*Word.sizeof]));\n            Word T1 = H + BigSigma1(E) + Ch(E, F, G) + K + Wi;\n            Word T2 = BigSigma0(A) + Maj(A, B, C);\n            D += T1;\n            H = T1 + T2;\n        }\n\n        static void T_SHA2_16_79(Word)(int i, ref Word[16] W,\n            Word A, Word B, Word C, ref Word D, Word E, Word F, Word G, ref Word H, Word K)\n            pure nothrow @nogc\n        {\n            W[i&15] = SmSigma1(W[(i-2)&15]) + W[(i-7)&15] + SmSigma0(W[(i-15)&15]) + W[i&15];\n            Word T1 = H + BigSigma1(E) + Ch(E, F, G) + K + W[i&15];\n            Word T2 = BigSigma0(A) + Maj(A, B, C);\n            D += T1;\n            H = T1 + T2;\n        }\n\n        private static void transformSHA2(Word)(Word[8]* state, const(ubyte[blockSize/8])* block)\n            pure nothrow @nogc\n        {\n            Word A, B, C, D, E, F, G, H;\n            Word[16] W = void;\n\n            A = (*state)[0];\n            B = (*state)[1];\n            C = (*state)[2];\n            D = (*state)[3];\n            E = (*state)[4];\n            F = (*state)[5];\n            G = (*state)[6];\n            H = (*state)[7];\n\n            T_SHA2_0_15!Word ( 0, block, W, A, B, C, D, E, F, G, H, constants[ 0]);\n            T_SHA2_0_15!Word ( 1, block, W, H, A, B, C, D, E, F, G, constants[ 1]);\n            T_SHA2_0_15!Word ( 2, block, W, G, H, A, B, C, D, E, F, constants[ 2]);\n            T_SHA2_0_15!Word ( 3, block, W, F, G, H, A, B, C, D, E, constants[ 3]);\n            T_SHA2_0_15!Word ( 4, block, W, E, F, G, H, A, B, C, D, constants[ 4]);\n            T_SHA2_0_15!Word ( 5, block, W, D, E, F, G, H, A, B, C, constants[ 5]);\n            T_SHA2_0_15!Word ( 6, block, W, C, D, E, F, G, H, A, B, constants[ 6]);\n            T_SHA2_0_15!Word ( 7, block, W, B, C, D, E, F, G, H, A, constants[ 7]);\n            T_SHA2_0_15!Word ( 8, block, W, A, B, C, D, E, F, G, H, constants[ 8]);\n            T_SHA2_0_15!Word ( 9, block, W, H, A, B, C, D, E, F, G, constants[ 9]);\n            T_SHA2_0_15!Word (10, block, W, G, H, A, B, C, D, E, F, constants[10]);\n            T_SHA2_0_15!Word (11, block, W, F, G, H, A, B, C, D, E, constants[11]);\n            T_SHA2_0_15!Word (12, block, W, E, F, G, H, A, B, C, D, constants[12]);\n            T_SHA2_0_15!Word (13, block, W, D, E, F, G, H, A, B, C, constants[13]);\n            T_SHA2_0_15!Word (14, block, W, C, D, E, F, G, H, A, B, constants[14]);\n            T_SHA2_0_15!Word (15, block, W, B, C, D, E, F, G, H, A, constants[15]);\n            T_SHA2_16_79!Word(16, W, A, B, C, D, E, F, G, H, constants[16]);\n            T_SHA2_16_79!Word(17, W, H, A, B, C, D, E, F, G, constants[17]);\n            T_SHA2_16_79!Word(18, W, G, H, A, B, C, D, E, F, constants[18]);\n            T_SHA2_16_79!Word(19, W, F, G, H, A, B, C, D, E, constants[19]);\n            T_SHA2_16_79!Word(20, W, E, F, G, H, A, B, C, D, constants[20]);\n            T_SHA2_16_79!Word(21, W, D, E, F, G, H, A, B, C, constants[21]);\n            T_SHA2_16_79!Word(22, W, C, D, E, F, G, H, A, B, constants[22]);\n            T_SHA2_16_79!Word(23, W, B, C, D, E, F, G, H, A, constants[23]);\n            T_SHA2_16_79!Word(24, W, A, B, C, D, E, F, G, H, constants[24]);\n            T_SHA2_16_79!Word(25, W, H, A, B, C, D, E, F, G, constants[25]);\n            T_SHA2_16_79!Word(26, W, G, H, A, B, C, D, E, F, constants[26]);\n            T_SHA2_16_79!Word(27, W, F, G, H, A, B, C, D, E, constants[27]);\n            T_SHA2_16_79!Word(28, W, E, F, G, H, A, B, C, D, constants[28]);\n            T_SHA2_16_79!Word(29, W, D, E, F, G, H, A, B, C, constants[29]);\n            T_SHA2_16_79!Word(30, W, C, D, E, F, G, H, A, B, constants[30]);\n            T_SHA2_16_79!Word(31, W, B, C, D, E, F, G, H, A, constants[31]);\n            T_SHA2_16_79!Word(32, W, A, B, C, D, E, F, G, H, constants[32]);\n            T_SHA2_16_79!Word(33, W, H, A, B, C, D, E, F, G, constants[33]);\n            T_SHA2_16_79!Word(34, W, G, H, A, B, C, D, E, F, constants[34]);\n            T_SHA2_16_79!Word(35, W, F, G, H, A, B, C, D, E, constants[35]);\n            T_SHA2_16_79!Word(36, W, E, F, G, H, A, B, C, D, constants[36]);\n            T_SHA2_16_79!Word(37, W, D, E, F, G, H, A, B, C, constants[37]);\n            T_SHA2_16_79!Word(38, W, C, D, E, F, G, H, A, B, constants[38]);\n            T_SHA2_16_79!Word(39, W, B, C, D, E, F, G, H, A, constants[39]);\n            T_SHA2_16_79!Word(40, W, A, B, C, D, E, F, G, H, constants[40]);\n            T_SHA2_16_79!Word(41, W, H, A, B, C, D, E, F, G, constants[41]);\n            T_SHA2_16_79!Word(42, W, G, H, A, B, C, D, E, F, constants[42]);\n            T_SHA2_16_79!Word(43, W, F, G, H, A, B, C, D, E, constants[43]);\n            T_SHA2_16_79!Word(44, W, E, F, G, H, A, B, C, D, constants[44]);\n            T_SHA2_16_79!Word(45, W, D, E, F, G, H, A, B, C, constants[45]);\n            T_SHA2_16_79!Word(46, W, C, D, E, F, G, H, A, B, constants[46]);\n            T_SHA2_16_79!Word(47, W, B, C, D, E, F, G, H, A, constants[47]);\n            T_SHA2_16_79!Word(48, W, A, B, C, D, E, F, G, H, constants[48]);\n            T_SHA2_16_79!Word(49, W, H, A, B, C, D, E, F, G, constants[49]);\n            T_SHA2_16_79!Word(50, W, G, H, A, B, C, D, E, F, constants[50]);\n            T_SHA2_16_79!Word(51, W, F, G, H, A, B, C, D, E, constants[51]);\n            T_SHA2_16_79!Word(52, W, E, F, G, H, A, B, C, D, constants[52]);\n            T_SHA2_16_79!Word(53, W, D, E, F, G, H, A, B, C, constants[53]);\n            T_SHA2_16_79!Word(54, W, C, D, E, F, G, H, A, B, constants[54]);\n            T_SHA2_16_79!Word(55, W, B, C, D, E, F, G, H, A, constants[55]);\n            T_SHA2_16_79!Word(56, W, A, B, C, D, E, F, G, H, constants[56]);\n            T_SHA2_16_79!Word(57, W, H, A, B, C, D, E, F, G, constants[57]);\n            T_SHA2_16_79!Word(58, W, G, H, A, B, C, D, E, F, constants[58]);\n            T_SHA2_16_79!Word(59, W, F, G, H, A, B, C, D, E, constants[59]);\n            T_SHA2_16_79!Word(60, W, E, F, G, H, A, B, C, D, constants[60]);\n            T_SHA2_16_79!Word(61, W, D, E, F, G, H, A, B, C, constants[61]);\n            T_SHA2_16_79!Word(62, W, C, D, E, F, G, H, A, B, constants[62]);\n            T_SHA2_16_79!Word(63, W, B, C, D, E, F, G, H, A, constants[63]);\n\n            static if (is(Word == ulong))\n            {\n                T_SHA2_16_79!Word(64, W, A, B, C, D, E, F, G, H, constants[64]);\n                T_SHA2_16_79!Word(65, W, H, A, B, C, D, E, F, G, constants[65]);\n                T_SHA2_16_79!Word(66, W, G, H, A, B, C, D, E, F, constants[66]);\n                T_SHA2_16_79!Word(67, W, F, G, H, A, B, C, D, E, constants[67]);\n                T_SHA2_16_79!Word(68, W, E, F, G, H, A, B, C, D, constants[68]);\n                T_SHA2_16_79!Word(69, W, D, E, F, G, H, A, B, C, constants[69]);\n                T_SHA2_16_79!Word(70, W, C, D, E, F, G, H, A, B, constants[70]);\n                T_SHA2_16_79!Word(71, W, B, C, D, E, F, G, H, A, constants[71]);\n                T_SHA2_16_79!Word(72, W, A, B, C, D, E, F, G, H, constants[72]);\n                T_SHA2_16_79!Word(73, W, H, A, B, C, D, E, F, G, constants[73]);\n                T_SHA2_16_79!Word(74, W, G, H, A, B, C, D, E, F, constants[74]);\n                T_SHA2_16_79!Word(75, W, F, G, H, A, B, C, D, E, constants[75]);\n                T_SHA2_16_79!Word(76, W, E, F, G, H, A, B, C, D, constants[76]);\n                T_SHA2_16_79!Word(77, W, D, E, F, G, H, A, B, C, constants[77]);\n                T_SHA2_16_79!Word(78, W, C, D, E, F, G, H, A, B, constants[78]);\n                T_SHA2_16_79!Word(79, W, B, C, D, E, F, G, H, A, constants[79]);\n            }\n\n            (*state)[0] += A;\n            (*state)[1] += B;\n            (*state)[2] += C;\n            (*state)[3] += D;\n            (*state)[4] += E;\n            (*state)[5] += F;\n            (*state)[6] += G;\n            (*state)[7] += H;\n\n            /* Zeroize sensitive information. */\n            W[] = 0;\n        }\n\n    public:\n        /**\n         * SHA initialization. Begins an SHA1/SHA2 operation.\n         *\n         * Note:\n         * For this SHA Digest implementation calling start after default construction\n         * is not necessary. Calling start is only necessary to reset the Digest.\n         *\n         * Generic code which deals with different Digest types should always call start though.\n         *\n         * Example:\n         * --------\n         * SHA1 digest;\n         * //digest.start(); //Not necessary\n         * digest.put(0);\n         * --------\n         */\n        void start() @safe pure nothrow @nogc\n        {\n            this = typeof(this).init;\n        }\n\n        /**\n         * Use this to feed the digest with data.\n         * Also implements the $(REF isOutputRange, std,range,primitives)\n         * interface for `ubyte` and `const(ubyte)[]`.\n         */\n        void put(scope const(ubyte)[] input...) @trusted pure nothrow @nogc\n        {\n            enum blockSizeInBytes = blockSize/8;\n            uint i, index, partLen;\n            auto inputLen = input.length;\n\n            /* Compute number of bytes mod block size (64 or 128 bytes) */\n            index = (cast(uint) count[0] >> 3) & (blockSizeInBytes - 1);\n\n            /* Update number of bits */\n            static if (blockSize == 512)\n                count[0] += inputLen * 8;\n            else static if (blockSize == 1024)\n            {\n                /* ugly hack to work around lack of ucent */\n                auto oldCount0 = count[0];\n                count[0] += inputLen * 8;\n                if (count[0] < oldCount0)\n                    count[1]++;\n            }\n            else\n                static assert(0);\n\n            partLen = blockSizeInBytes - index;\n\n            /* Transform as many times as possible. */\n            if (inputLen >= partLen)\n            {\n                (&buffer[index])[0 .. partLen] = input.ptr[0 .. partLen];\n                transform (&state, &buffer);\n\n                for (i = partLen; i + blockSizeInBytes-1 < inputLen; i += blockSizeInBytes)\n                   transform(&state, cast(ubyte[blockSizeInBytes]*)(input.ptr + i));\n\n                index = 0;\n            }\n            else\n                i = 0;\n\n            /* Buffer remaining input */\n            if (inputLen - i)\n                (&buffer[index])[0 .. inputLen-i] = (&input[i])[0 .. inputLen-i];\n        }\n\n        @safe unittest\n        {\n            typeof(this) dig;\n            dig.put(cast(ubyte) 0); //single ubyte\n            dig.put(cast(ubyte) 0, cast(ubyte) 0); //variadic\n            ubyte[10] buf;\n            dig.put(buf); //buffer\n        }\n\n\n        /**\n         * Returns the finished SHA hash. This also calls $(LREF start) to\n         * reset the internal state.\n         */\n        ubyte[digestSize/8] finish() @trusted pure nothrow @nogc\n        {\n            static if (blockSize == 512)\n            {\n                ubyte[32] data = void;\n                uint index, padLen;\n\n                /* Save number of bits */\n                ubyte[8] bits = nativeToBigEndian(count[0]);\n\n                /* Pad out to 56 mod 64. */\n                index = (cast(uint) count[0] >> 3) & (64 - 1);\n                padLen = (index < 56) ? (56 - index) : (120 - index);\n                put(padding[0 .. padLen]);\n\n                /* Append length (before padding) */\n                put(bits);\n\n                /* Store state in digest */\n                for (auto i = 0; i < ((digestSize == 160)? 5 : 8); i++)\n                    data[i*4..(i+1)*4] = nativeToBigEndian(state[i])[];\n\n                /* Zeroize sensitive information. */\n                start();\n                return data[0 .. digestSize/8];\n            }\n            else static if (blockSize == 1024)\n            {\n                ubyte[64] data = void;\n                uint index, padLen;\n\n                /* Save number of bits */\n                ubyte[16] bits;\n                bits[ 0 .. 8] = nativeToBigEndian(count[1]);\n                bits[8 .. 16] = nativeToBigEndian(count[0]);\n\n                /* Pad out to 112 mod 128. */\n                index = (cast(uint) count[0] >> 3) & (128 - 1);\n                padLen = (index < 112) ? (112 - index) : (240 - index);\n                put(padding[0 .. padLen]);\n\n                /* Append length (before padding) */\n                put(bits);\n\n                /* Store state in digest */\n                for (auto i = 0; i < 8; i++)\n                    data[i*8..(i+1)*8] = nativeToBigEndian(state[i])[];\n\n                /* Zeroize sensitive information. */\n                start();\n                return data[0 .. digestSize/8];\n            }\n            else\n                static assert(0);\n        }\n        ///\n        @safe unittest\n        {\n            //Simple example\n            SHA1 hash;\n            hash.start();\n            hash.put(cast(ubyte) 0);\n            ubyte[20] result = hash.finish();\n        }\n}\n\n///\n@safe unittest\n{\n    //Simple example, hashing a string using sha1Of helper function\n    ubyte[20] hash = sha1Of(\"abc\");\n    //Let's get a hash string\n    assert(toHexString(hash) == \"A9993E364706816ABA3E25717850C26C9CD0D89D\");\n\n    //The same, but using SHA-224\n    ubyte[28] hash224 = sha224Of(\"abc\");\n    assert(toHexString(hash224) == \"23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7\");\n}\n\n///\n@safe unittest\n{\n    //Using the basic API\n    SHA1 hash;\n    hash.start();\n    ubyte[1024] data;\n    //Initialize data here...\n    hash.put(data);\n    ubyte[20] result = hash.finish();\n}\n\n///\n@safe unittest\n{\n    //Let's use the template features:\n    //Note: When passing a SHA1 to a function, it must be passed by reference!\n    void doSomething(T)(ref T hash)\n    if (isDigest!T)\n    {\n      hash.put(cast(ubyte) 0);\n    }\n    SHA1 sha;\n    sha.start();\n    doSomething(sha);\n    assert(toHexString(sha.finish()) == \"5BA93C9DB0CFF93F52B521D7420E43F6EDA2784F\");\n}\n\nalias SHA1 = SHA!(512, 160);  /// SHA alias for SHA-1, hash is ubyte[20]\nalias SHA224 = SHA!(512, 224);  /// SHA alias for SHA-224, hash is ubyte[28]\nalias SHA256 = SHA!(512, 256);  /// SHA alias for SHA-256, hash is ubyte[32]\nalias SHA384 = SHA!(1024, 384); /// SHA alias for SHA-384, hash is ubyte[48]\nalias SHA512 = SHA!(1024, 512); /// SHA alias for SHA-512, hash is ubyte[64]\nalias SHA512_224 = SHA!(1024, 224); /// SHA alias for SHA-512/224, hash is ubyte[28]\nalias SHA512_256 = SHA!(1024, 256); /// SHA alias for SHA-512/256, hash is ubyte[32]\n\n@safe unittest\n{\n    assert(isDigest!SHA1);\n    assert(isDigest!SHA224);\n    assert(isDigest!SHA256);\n    assert(isDigest!SHA384);\n    assert(isDigest!SHA512);\n    assert(isDigest!SHA512_224);\n    assert(isDigest!SHA512_256);\n}\n\n@system unittest\n{\n    import std.conv : hexString;\n    import std.range;\n\n    ubyte[20] digest;\n    ubyte[28] digest224;\n    ubyte[32] digest256;\n    ubyte[48] digest384;\n    ubyte[64] digest512;\n    ubyte[28] digest512_224;\n    ubyte[32] digest512_256;\n\n    SHA1 sha;\n    sha.put(cast(ubyte[])\"abcdef\");\n    sha.start();\n    sha.put(cast(ubyte[])\"\");\n    assert(sha.finish() == cast(ubyte[]) hexString!\"da39a3ee5e6b4b0d3255bfef95601890afd80709\");\n\n    SHA224 sha224;\n    sha224.put(cast(ubyte[])\"abcdef\");\n    sha224.start();\n    sha224.put(cast(ubyte[])\"\");\n    assert(sha224.finish() == cast(ubyte[]) hexString!\"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f\");\n\n    SHA256 sha256;\n    sha256.put(cast(ubyte[])\"abcdef\");\n    sha256.start();\n    sha256.put(cast(ubyte[])\"\");\n    assert(sha256.finish() == cast(ubyte[])\n            hexString!\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\");\n\n    SHA384 sha384;\n    sha384.put(cast(ubyte[])\"abcdef\");\n    sha384.start();\n    sha384.put(cast(ubyte[])\"\");\n    assert(sha384.finish() == cast(ubyte[]) hexString!(\"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c\"\n        ~\"0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b\"));\n\n    SHA512 sha512;\n    sha512.put(cast(ubyte[])\"abcdef\");\n    sha512.start();\n    sha512.put(cast(ubyte[])\"\");\n    assert(sha512.finish() == cast(ubyte[])\n            hexString!(\"cf83e1357eefb8bdf1542850d66d8007d620e4050b571\"\n        ~\"5dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e\"));\n\n    SHA512_224 sha512_224;\n    sha512_224.put(cast(ubyte[])\"abcdef\");\n    sha512_224.start();\n    sha512_224.put(cast(ubyte[])\"\");\n    assert(sha512_224.finish() == cast(ubyte[]) hexString!\"6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4\");\n\n    SHA512_256 sha512_256;\n    sha512_256.put(cast(ubyte[])\"abcdef\");\n    sha512_256.start();\n    sha512_256.put(cast(ubyte[])\"\");\n    assert(sha512_256.finish() == cast(ubyte[])\n            hexString!\"c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a\");\n\n    digest        = sha1Of      (\"\");\n    digest224     = sha224Of    (\"\");\n    digest256     = sha256Of    (\"\");\n    digest384     = sha384Of    (\"\");\n    digest512     = sha512Of    (\"\");\n    digest512_224 = sha512_224Of(\"\");\n    digest512_256 = sha512_256Of(\"\");\n    assert(digest == cast(ubyte[]) hexString!\"da39a3ee5e6b4b0d3255bfef95601890afd80709\");\n    assert(digest224 == cast(ubyte[]) hexString!\"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f\");\n    assert(digest256 == cast(ubyte[]) hexString!\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\");\n    assert(digest384 == cast(ubyte[]) hexString!(\"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c\"\n        ~\"0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b\"));\n    assert(digest512 == cast(ubyte[]) hexString!(\"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83\"\n        ~\"f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e\"));\n    assert(digest512_224 == cast(ubyte[]) hexString!\"6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4\");\n    assert(digest512_256 == cast(ubyte[]) hexString!\"c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a\");\n\n    digest        = sha1Of      (\"a\");\n    digest224     = sha224Of    (\"a\");\n    digest256     = sha256Of    (\"a\");\n    digest384     = sha384Of    (\"a\");\n    digest512     = sha512Of    (\"a\");\n    digest512_224 = sha512_224Of(\"a\");\n    digest512_256 = sha512_256Of(\"a\");\n    assert(digest == cast(ubyte[]) hexString!\"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8\");\n    assert(digest224 == cast(ubyte[]) hexString!\"abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5\");\n    assert(digest256 == cast(ubyte[]) hexString!\"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb\");\n    assert(digest384 == cast(ubyte[]) hexString!(\"54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9\"\n        ~\"cd697e85175033caa88e6d57bc35efae0b5afd3145f31\"));\n    assert(digest512 == cast(ubyte[]) hexString!(\"1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05ab\"\n        ~\"c54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75\"));\n    assert(digest512_224 == cast(ubyte[]) hexString!\"d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327\");\n    assert(digest512_256 == cast(ubyte[]) hexString!\"455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8\");\n\n    digest        = sha1Of      (\"abc\");\n    digest224     = sha224Of    (\"abc\");\n    digest256     = sha256Of    (\"abc\");\n    digest384     = sha384Of    (\"abc\");\n    digest512     = sha512Of    (\"abc\");\n    digest512_224 = sha512_224Of(\"abc\");\n    digest512_256 = sha512_256Of(\"abc\");\n    assert(digest == cast(ubyte[]) hexString!\"a9993e364706816aba3e25717850c26c9cd0d89d\");\n    assert(digest224 == cast(ubyte[]) hexString!\"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7\");\n    assert(digest256 == cast(ubyte[]) hexString!\"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\");\n    assert(digest384 == cast(ubyte[]) hexString!(\"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a\"\n        ~\"8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7\"));\n    assert(digest512 == cast(ubyte[]) hexString!(\"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9\"\n        ~\"eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\"));\n    assert(digest512_224 == cast(ubyte[]) hexString!\"4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa\");\n    assert(digest512_256 == cast(ubyte[]) hexString!\"53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23\");\n\n    digest        = sha1Of      (\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    digest224     = sha224Of    (\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    digest256     = sha256Of    (\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    digest384     = sha384Of    (\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    digest512     = sha512Of    (\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    digest512_224 = sha512_224Of(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    digest512_256 = sha512_256Of(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\");\n    assert(digest == cast(ubyte[]) hexString!\"84983e441c3bd26ebaae4aa1f95129e5e54670f1\");\n    assert(digest224 == cast(ubyte[]) hexString!\"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525\");\n    assert(digest256 == cast(ubyte[]) hexString!\"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1\");\n    assert(digest384 == cast(ubyte[]) hexString!(\"3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe\"\n        ~\"8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b\"));\n    assert(digest512 == cast(ubyte[]) hexString!(\"204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a827\"\n        ~\"9be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445\"));\n    assert(digest512_224 == cast(ubyte[]) hexString!\"e5302d6d54bb242275d1e7622d68df6eb02dedd13f564c13dbda2174\");\n    assert(digest512_256 == cast(ubyte[]) hexString!\"bde8e1f9f19bb9fd3406c90ec6bc47bd36d8ada9f11880dbc8a22a7078b6a461\");\n\n    digest        = sha1Of      (\"message digest\");\n    digest224     = sha224Of    (\"message digest\");\n    digest256     = sha256Of    (\"message digest\");\n    digest384     = sha384Of    (\"message digest\");\n    digest512     = sha512Of    (\"message digest\");\n    digest512_224 = sha512_224Of(\"message digest\");\n    digest512_256 = sha512_256Of(\"message digest\");\n    assert(digest == cast(ubyte[]) hexString!\"c12252ceda8be8994d5fa0290a47231c1d16aae3\");\n    assert(digest224 == cast(ubyte[]) hexString!\"2cb21c83ae2f004de7e81c3c7019cbcb65b71ab656b22d6d0c39b8eb\");\n    assert(digest256 == cast(ubyte[]) hexString!\"f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650\");\n    assert(digest384 == cast(ubyte[]) hexString!(\"473ed35167ec1f5d8e550368a3db39be54639f828868e9454c\"\n        ~\"239fc8b52e3c61dbd0d8b4de1390c256dcbb5d5fd99cd5\"));\n    assert(digest512 == cast(ubyte[]) hexString!(\"107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c134\"\n        ~\"92ea45b0199f3309e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c\"));\n    assert(digest512_224 == cast(ubyte[]) hexString!\"ad1a4db188fe57064f4f24609d2a83cd0afb9b398eb2fcaeaae2c564\");\n    assert(digest512_256 == cast(ubyte[]) hexString!\"0cf471fd17ed69d990daf3433c89b16d63dec1bb9cb42a6094604ee5d7b4e9fb\");\n\n    digest        = sha1Of      (\"abcdefghijklmnopqrstuvwxyz\");\n    digest224     = sha224Of    (\"abcdefghijklmnopqrstuvwxyz\");\n    digest256     = sha256Of    (\"abcdefghijklmnopqrstuvwxyz\");\n    digest384     = sha384Of    (\"abcdefghijklmnopqrstuvwxyz\");\n    digest512     = sha512Of    (\"abcdefghijklmnopqrstuvwxyz\");\n    digest512_224 = sha512_224Of(\"abcdefghijklmnopqrstuvwxyz\");\n    digest512_256 = sha512_256Of(\"abcdefghijklmnopqrstuvwxyz\");\n    assert(digest == cast(ubyte[]) hexString!\"32d10c7b8cf96570ca04ce37f2a19d84240d3a89\");\n    assert(digest224 == cast(ubyte[]) hexString!\"45a5f72c39c5cff2522eb3429799e49e5f44b356ef926bcf390dccc2\");\n    assert(digest256 == cast(ubyte[]) hexString!\"71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73\");\n    assert(digest384 == cast(ubyte[]) hexString!(\"feb67349df3db6f5924815d6c3dc133f091809213731fe5c7b5\"\n        ~\"f4999e463479ff2877f5f2936fa63bb43784b12f3ebb4\"));\n    assert(digest512 == cast(ubyte[]) hexString!(\"4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034\"\n        ~\"898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1\"));\n    assert(digest512_224 == cast(ubyte[]) hexString!\"ff83148aa07ec30655c1b40aff86141c0215fe2a54f767d3f38743d8\");\n    assert(digest512_256 == cast(ubyte[]) hexString!\"fc3189443f9c268f626aea08a756abe7b726b05f701cb08222312ccfd6710a26\");\n\n    digest        = sha1Of      (\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    digest224     = sha224Of    (\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    digest256     = sha256Of    (\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    digest384     = sha384Of    (\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    digest512     = sha512Of    (\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    digest512_224 = sha512_224Of(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    digest512_256 = sha512_256Of(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\");\n    assert(digest == cast(ubyte[]) hexString!\"761c457bf73b14d27e9e9265c46f4b4dda11f940\");\n    assert(digest224 == cast(ubyte[]) hexString!\"bff72b4fcb7d75e5632900ac5f90d219e05e97a7bde72e740db393d9\");\n    assert(digest256 == cast(ubyte[]) hexString!\"db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0\");\n    assert(digest384 == cast(ubyte[]) hexString!(\"1761336e3f7cbfe51deb137f026f89e01a448e3b1fafa64039\"\n        ~\"c1464ee8732f11a5341a6f41e0c202294736ed64db1a84\"));\n    assert(digest512 == cast(ubyte[]) hexString!(\"1e07be23c26a86ea37ea810c8ec7809352515a970e9253c26f\"\n        ~\"536cfc7a9996c45c8370583e0a78fa4a90041d71a4ceab7423f19c71b9d5a3e01249f0bebd5894\"));\n    assert(digest512_224 == cast(ubyte[]) hexString!\"a8b4b9174b99ffc67d6f49be9981587b96441051e16e6dd036b140d3\");\n    assert(digest512_256 == cast(ubyte[]) hexString!\"cdf1cc0effe26ecc0c13758f7b4a48e000615df241284185c39eb05d355bb9c8\");\n\n    digest        = sha1Of      (\"1234567890123456789012345678901234567890\"~\n                                 \"1234567890123456789012345678901234567890\");\n    digest224     = sha224Of    (\"1234567890123456789012345678901234567890\"~\n                                 \"1234567890123456789012345678901234567890\");\n    digest256     = sha256Of    (\"1234567890123456789012345678901234567890\"~\n                                 \"1234567890123456789012345678901234567890\");\n    digest384     = sha384Of    (\"1234567890123456789012345678901234567890\"~\n                                 \"1234567890123456789012345678901234567890\");\n    digest512     = sha512Of    (\"1234567890123456789012345678901234567890\"~\n                                 \"1234567890123456789012345678901234567890\");\n    digest512_224 = sha512_224Of(\"1234567890123456789012345678901234567890\"~\n                                 \"1234567890123456789012345678901234567890\");\n    digest512_256 = sha512_256Of(\"1234567890123456789012345678901234567890\"~\n                                 \"1234567890123456789012345678901234567890\");\n    assert(digest == cast(ubyte[]) hexString!\"50abf5706a150990a08b2c5ea40fa0e585554732\");\n    assert(digest224 == cast(ubyte[]) hexString!\"b50aecbe4e9bb0b57bc5f3ae760a8e01db24f203fb3cdcd13148046e\");\n    assert(digest256 == cast(ubyte[]) hexString!\"f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e\");\n    assert(digest384 == cast(ubyte[]) hexString!(\"b12932b0627d1c060942f5447764155655bd4da0c9afa6dd9b\"\n        ~\"9ef53129af1b8fb0195996d2de9ca0df9d821ffee67026\"));\n    assert(digest512 == cast(ubyte[]) hexString!(\"72ec1ef1124a45b047e8b7c75a932195135bb61de24ec0d191\"\n        ~\"4042246e0aec3a2354e093d76f3048b456764346900cb130d2a4fd5dd16abb5e30bcb850dee843\"));\n    assert(digest512_224 == cast(ubyte[]) hexString!\"ae988faaa47e401a45f704d1272d99702458fea2ddc6582827556dd2\");\n    assert(digest512_256 == cast(ubyte[]) hexString!\"2c9fdbc0c90bdd87612ee8455474f9044850241dc105b1e8b94b8ddf5fac9148\");\n\n    ubyte[] onemilliona = new ubyte[1000000];\n    onemilliona[] = 'a';\n    digest = sha1Of(onemilliona);\n    digest224 = sha224Of(onemilliona);\n    digest256 = sha256Of(onemilliona);\n    digest384 = sha384Of(onemilliona);\n    digest512 = sha512Of(onemilliona);\n    digest512_224 = sha512_224Of(onemilliona);\n    digest512_256 = sha512_256Of(onemilliona);\n    assert(digest == cast(ubyte[]) hexString!\"34aa973cd4c4daa4f61eeb2bdbad27316534016f\");\n    assert(digest224 == cast(ubyte[]) hexString!\"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67\");\n    assert(digest256 == cast(ubyte[]) hexString!\"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0\");\n    assert(digest384 == cast(ubyte[]) hexString!(\"9d0e1809716474cb086e834e310a4a1ced149e9c00f2485279\"\n        ~\"72cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985\"));\n    assert(digest512 == cast(ubyte[]) hexString!(\"e718483d0ce769644e2e42c7bc15b4638e1f98b13b20442856\"\n        ~\"32a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b\"));\n    assert(digest512_224 == cast(ubyte[]) hexString!\"37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287\");\n    assert(digest512_256 == cast(ubyte[]) hexString!\"9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21\");\n\n    auto oneMillionRange = repeat!ubyte(cast(ubyte)'a', 1000000);\n    digest = sha1Of(oneMillionRange);\n    digest224 = sha224Of(oneMillionRange);\n    digest256 = sha256Of(oneMillionRange);\n    digest384 = sha384Of(oneMillionRange);\n    digest512 = sha512Of(oneMillionRange);\n    digest512_224 = sha512_224Of(oneMillionRange);\n    digest512_256 = sha512_256Of(oneMillionRange);\n    assert(digest == cast(ubyte[]) hexString!\"34aa973cd4c4daa4f61eeb2bdbad27316534016f\");\n    assert(digest224 == cast(ubyte[]) hexString!\"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67\");\n    assert(digest256 == cast(ubyte[]) hexString!\"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0\");\n    assert(digest384 == cast(ubyte[]) hexString!(\"9d0e1809716474cb086e834e310a4a1ced149e9c00f2485279\"\n        ~\"72cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985\"));\n    assert(digest512 == cast(ubyte[]) hexString!(\"e718483d0ce769644e2e42c7bc15b4638e1f98b13b20442856\"\n        ~\"32a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b\"));\n    assert(digest512_224 == cast(ubyte[]) hexString!\"37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287\");\n    assert(digest512_256 == cast(ubyte[]) hexString!\"9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21\");\n\n    enum ubyte[20] input = cast(ubyte[20]) hexString!\"a9993e364706816aba3e25717850c26c9cd0d89d\";\n    assert(toHexString(input)\n        == \"A9993E364706816ABA3E25717850C26C9CD0D89D\");\n}\n\n/**\n * These are convenience aliases for $(REF digest, std,digest) using the\n * SHA implementation.\n */\n//simple alias doesn't work here, hope this gets inlined...\nauto sha1Of(T...)(T data)\n{\n    return digest!(SHA1, T)(data);\n}\n///ditto\nauto sha224Of(T...)(T data)\n{\n    return digest!(SHA224, T)(data);\n}\n///ditto\nauto sha256Of(T...)(T data)\n{\n    return digest!(SHA256, T)(data);\n}\n///ditto\nauto sha384Of(T...)(T data)\n{\n    return digest!(SHA384, T)(data);\n}\n///ditto\nauto sha512Of(T...)(T data)\n{\n    return digest!(SHA512, T)(data);\n}\n///ditto\nauto sha512_224Of(T...)(T data)\n{\n    return digest!(SHA512_224, T)(data);\n}\n///ditto\nauto sha512_256Of(T...)(T data)\n{\n    return digest!(SHA512_256, T)(data);\n}\n\n///\n@safe unittest\n{\n    ubyte[20] hash = sha1Of(\"abc\");\n    assert(hash == digest!SHA1(\"abc\"));\n\n    ubyte[28] hash224 = sha224Of(\"abc\");\n    assert(hash224 == digest!SHA224(\"abc\"));\n\n    ubyte[32] hash256 = sha256Of(\"abc\");\n    assert(hash256 == digest!SHA256(\"abc\"));\n\n    ubyte[48] hash384 = sha384Of(\"abc\");\n    assert(hash384 == digest!SHA384(\"abc\"));\n\n    ubyte[64] hash512 = sha512Of(\"abc\");\n    assert(hash512 == digest!SHA512(\"abc\"));\n\n    ubyte[28] hash512_224 = sha512_224Of(\"abc\");\n    assert(hash512_224 == digest!SHA512_224(\"abc\"));\n\n    ubyte[32] hash512_256 = sha512_256Of(\"abc\");\n    assert(hash512_256 == digest!SHA512_256(\"abc\"));\n}\n\n@safe unittest\n{\n    string a = \"Mary has \", b = \"a little lamb\";\n    int[] c = [ 1, 2, 3, 4, 5 ];\n    auto d = toHexString(sha1Of(a, b, c));\n    version (LittleEndian)\n        assert(d[] == \"CDBB611D00AC2387B642D3D7BDF4C3B342237110\", d);\n    else\n        assert(d[] == \"A0F1196C7A379C09390476D9CA4AA11B71FD11C8\", d);\n}\n\n/**\n * OOP API SHA1 and SHA2 implementations.\n * See `std.digest` for differences between template and OOP API.\n *\n * This is an alias for $(D $(REF WrapperDigest, std,digest)!SHA1), see\n * there for more information.\n */\nalias SHA1Digest = WrapperDigest!SHA1;\nalias SHA224Digest = WrapperDigest!SHA224; ///ditto\nalias SHA256Digest = WrapperDigest!SHA256; ///ditto\nalias SHA384Digest = WrapperDigest!SHA384; ///ditto\nalias SHA512Digest = WrapperDigest!SHA512; ///ditto\nalias SHA512_224Digest = WrapperDigest!SHA512_224; ///ditto\nalias SHA512_256Digest = WrapperDigest!SHA512_256; ///ditto\n\n///\n@safe unittest\n{\n    //Simple example, hashing a string using Digest.digest helper function\n    auto sha = new SHA1Digest();\n    ubyte[] hash = sha.digest(\"abc\");\n    //Let's get a hash string\n    assert(toHexString(hash) == \"A9993E364706816ABA3E25717850C26C9CD0D89D\");\n\n    //The same, but using SHA-224\n    auto sha224 = new SHA224Digest();\n    ubyte[] hash224 = sha224.digest(\"abc\");\n    //Let's get a hash string\n    assert(toHexString(hash224) == \"23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7\");\n}\n\n///\n@system unittest\n{\n    //Let's use the OOP features:\n    void test(Digest dig)\n    {\n      dig.put(cast(ubyte) 0);\n    }\n    auto sha = new SHA1Digest();\n    test(sha);\n\n    //Let's use a custom buffer:\n    ubyte[20] buf;\n    ubyte[] result = sha.finish(buf[]);\n    assert(toHexString(result) == \"5BA93C9DB0CFF93F52B521D7420E43F6EDA2784F\");\n}\n\n@system unittest\n{\n    import std.conv : hexString;\n    import std.exception;\n    auto sha = new SHA1Digest();\n\n    sha.put(cast(ubyte[])\"abcdef\");\n    sha.reset();\n    sha.put(cast(ubyte[])\"\");\n    assert(sha.finish() == cast(ubyte[]) hexString!\"da39a3ee5e6b4b0d3255bfef95601890afd80709\");\n\n    sha.put(cast(ubyte[])\"abcdefghijklmnopqrstuvwxyz\");\n    ubyte[22] result;\n    auto result2 = sha.finish(result[]);\n    assert(result[0 .. 20] == result2 && result2 == cast(ubyte[]) hexString!\"32d10c7b8cf96570ca04ce37f2a19d84240d3a89\");\n\n    debug\n        assertThrown!Error(sha.finish(result[0 .. 15]));\n\n    assert(sha.length == 20);\n\n    assert(sha.digest(\"\") == cast(ubyte[]) hexString!\"da39a3ee5e6b4b0d3255bfef95601890afd80709\");\n\n    assert(sha.digest(\"a\") == cast(ubyte[]) hexString!\"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8\");\n\n    assert(sha.digest(\"abc\") == cast(ubyte[]) hexString!\"a9993e364706816aba3e25717850c26c9cd0d89d\");\n\n    assert(sha.digest(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\")\n           == cast(ubyte[]) hexString!\"84983e441c3bd26ebaae4aa1f95129e5e54670f1\");\n\n    assert(sha.digest(\"message digest\") == cast(ubyte[]) hexString!\"c12252ceda8be8994d5fa0290a47231c1d16aae3\");\n\n    assert(sha.digest(\"abcdefghijklmnopqrstuvwxyz\")\n           == cast(ubyte[]) hexString!\"32d10c7b8cf96570ca04ce37f2a19d84240d3a89\");\n\n    assert(sha.digest(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\")\n           == cast(ubyte[]) hexString!\"761c457bf73b14d27e9e9265c46f4b4dda11f940\");\n\n    assert(sha.digest(\"1234567890123456789012345678901234567890\",\n                                   \"1234567890123456789012345678901234567890\")\n           == cast(ubyte[]) hexString!\"50abf5706a150990a08b2c5ea40fa0e585554732\");\n\n    ubyte[] onemilliona = new ubyte[1000000];\n    onemilliona[] = 'a';\n    assert(sha.digest(onemilliona) == cast(ubyte[]) hexString!\"34aa973cd4c4daa4f61eeb2bdbad27316534016f\");\n}\n"
  },
  {
    "path": "libphobos/src/std/encoding.d",
    "content": "// Written in the D programming language.\n\n/**\nClasses and functions for handling and transcoding between various encodings.\n\nFor cases where the encoding is known at compile-time, functions are provided\nfor arbitrary encoding and decoding of characters, arbitrary transcoding\nbetween strings of different type, as well as validation and sanitization.\n\nEncodings currently supported are UTF-8, UTF-16, UTF-32, ASCII, ISO-8859-1\n(also known as LATIN-1), ISO-8859-2 (LATIN-2), WINDOWS-1250, WINDOWS-1251\nand WINDOWS-1252.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Decode) $(TD\n    $(LREF codePoints)\n    $(LREF decode)\n    $(LREF decodeReverse)\n    $(LREF safeDecode)\n))\n$(TR $(TD Conversion) $(TD\n    $(LREF codeUnits)\n    $(LREF sanitize)\n    $(LREF transcode)\n))\n$(TR $(TD Classification) $(TD\n    $(LREF canEncode)\n    $(LREF isValid)\n    $(LREF isValidCodePoint)\n    $(LREF isValidCodeUnit)\n))\n$(TR $(TD BOM) $(TD\n    $(LREF BOM)\n    $(LREF BOMSeq)\n    $(LREF getBOM)\n    $(LREF utfBOM)\n))\n$(TR $(TD Length &amp; Index) $(TD\n    $(LREF firstSequence)\n    $(LREF encodedLength)\n    $(LREF index)\n    $(LREF lastSequence)\n    $(LREF validLength)\n))\n$(TR $(TD Encoding schemes) $(TD\n    $(LREF encodingName)\n    $(LREF EncodingScheme)\n    $(LREF EncodingSchemeASCII)\n    $(LREF EncodingSchemeLatin1)\n    $(LREF EncodingSchemeLatin2)\n    $(LREF EncodingSchemeUtf16Native)\n    $(LREF EncodingSchemeUtf32Native)\n    $(LREF EncodingSchemeUtf8)\n    $(LREF EncodingSchemeWindows1250)\n    $(LREF EncodingSchemeWindows1251)\n    $(LREF EncodingSchemeWindows1252)\n))\n$(TR $(TD Representation) $(TD\n    $(LREF AsciiChar)\n    $(LREF AsciiString)\n    $(LREF Latin1Char)\n    $(LREF Latin1String)\n    $(LREF Latin2Char)\n    $(LREF Latin2String)\n    $(LREF Windows1250Char)\n    $(LREF Windows1250String)\n    $(LREF Windows1251Char)\n    $(LREF Windows1251String)\n    $(LREF Windows1252Char)\n    $(LREF Windows1252String)\n))\n$(TR $(TD Exceptions) $(TD\n    $(LREF INVALID_SEQUENCE)\n    $(LREF EncodingException)\n))\n)\n\nFor cases where the encoding is not known at compile-time, but is\nknown at run-time, the abstract class $(LREF EncodingScheme)\nand its subclasses is provided.  To construct a run-time encoder/decoder,\none does e.g.\n\n----------------------------------------------------\nauto e = EncodingScheme.create(\"utf-8\");\n----------------------------------------------------\n\nThis library supplies $(LREF EncodingScheme) subclasses for ASCII,\nISO-8859-1 (also known as LATIN-1), ISO-8859-2 (LATIN-2), WINDOWS-1250,\nWINDOWS-1251, WINDOWS-1252, UTF-8, and (on little-endian architectures)\nUTF-16LE and UTF-32LE; or (on big-endian architectures) UTF-16BE and UTF-32BE.\n\nThis library provides a mechanism whereby other modules may add $(LREF\nEncodingScheme) subclasses for any other encoding.\n\nCopyright: Copyright Janice Caron 2008 - 2009.\nLicense:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   Janice Caron\nSource:    $(PHOBOSSRC std/encoding.d)\n*/\n/*\n         Copyright Janice Caron 2008 - 2009.\nDistributed under the Boost Software License, Version 1.0.\n   (See accompanying file LICENSE_1_0.txt or copy at\n         http://www.boost.org/LICENSE_1_0.txt)\n*/\nmodule std.encoding;\n\nimport std.range.primitives;\nimport std.traits;\nimport std.typecons;\n\n@system unittest\n{\n    static ubyte[][] validStrings =\n    [\n        // Plain ASCII\n        cast(ubyte[])\"hello\",\n\n        // First possible sequence of a certain length\n        [ 0x00 ],                       // U+00000000   one byte\n        [ 0xC2, 0x80 ],                 // U+00000080   two bytes\n        [ 0xE0, 0xA0, 0x80 ],           // U+00000800   three bytes\n        [ 0xF0, 0x90, 0x80, 0x80 ],     // U+00010000   three bytes\n\n        // Last possible sequence of a certain length\n        [ 0x7F ],                       // U+0000007F   one byte\n        [ 0xDF, 0xBF ],                 // U+000007FF   two bytes\n        [ 0xEF, 0xBF, 0xBF ],           // U+0000FFFF   three bytes\n\n        // Other boundary conditions\n        [ 0xED, 0x9F, 0xBF ],\n        // U+0000D7FF   Last character before surrogates\n        [ 0xEE, 0x80, 0x80 ],\n        // U+0000E000   First character after surrogates\n        [ 0xEF, 0xBF, 0xBD ],\n        // U+0000FFFD   Unicode replacement character\n        [ 0xF4, 0x8F, 0xBF, 0xBF ],\n        // U+0010FFFF   Very last character\n\n        // Non-character code points\n        /*  NOTE: These are legal in UTF, and may be converted from\n            one UTF to another, however they do not represent Unicode\n            characters. These code points have been reserved by\n            Unicode as non-character code points. They are permissible\n            for data exchange within an application, but they are are\n            not permitted to be used as characters. Since this module\n            deals with UTF, and not with Unicode per se, we choose to\n            accept them here. */\n        [ 0xDF, 0xBE ],                 // U+0000FFFE\n        [ 0xDF, 0xBF ],                 // U+0000FFFF\n    ];\n\n    static ubyte[][] invalidStrings =\n    [\n        // First possible sequence of a certain length, but greater\n        // than U+10FFFF\n        [ 0xF8, 0x88, 0x80, 0x80, 0x80 ],           // U+00200000   five bytes\n        [ 0xFC, 0x84, 0x80, 0x80, 0x80, 0x80 ],     // U+04000000   six bytes\n\n        // Last possible sequence of a certain length, but greater than U+10FFFF\n        [ 0xF7, 0xBF, 0xBF, 0xBF ],                 // U+001FFFFF   four bytes\n        [ 0xFB, 0xBF, 0xBF, 0xBF, 0xBF ],           // U+03FFFFFF   five bytes\n        [ 0xFD, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF ],     // U+7FFFFFFF   six bytes\n\n        // Other boundary conditions\n        [ 0xF4, 0x90, 0x80, 0x80 ],                 // U+00110000\n                                                    // First code\n                                                    // point after\n                                                    // last character\n\n        // Unexpected continuation bytes\n        [ 0x80 ],\n        [ 0xBF ],\n        [ 0x20, 0x80, 0x20 ],\n        [ 0x20, 0xBF, 0x20 ],\n        [ 0x80, 0x9F, 0xA0 ],\n\n        // Lonely start bytes\n        [ 0xC0 ],\n        [ 0xCF ],\n        [ 0x20, 0xC0, 0x20 ],\n        [ 0x20, 0xCF, 0x20 ],\n        [ 0xD0 ],\n        [ 0xDF ],\n        [ 0x20, 0xD0, 0x20 ],\n        [ 0x20, 0xDF, 0x20 ],\n        [ 0xE0 ],\n        [ 0xEF ],\n        [ 0x20, 0xE0, 0x20 ],\n        [ 0x20, 0xEF, 0x20 ],\n        [ 0xF0 ],\n        [ 0xF1 ],\n        [ 0xF2 ],\n        [ 0xF3 ],\n        [ 0xF4 ],\n        [ 0xF5 ],   // If this were legal it would start a character > U+10FFFF\n        [ 0xF6 ],   // If this were legal it would start a character > U+10FFFF\n        [ 0xF7 ],   // If this were legal it would start a character > U+10FFFF\n\n        [ 0xEF, 0xBF ],             // Three byte sequence with third byte missing\n        [ 0xF7, 0xBF, 0xBF ],       // Four byte sequence with fourth byte missing\n        [ 0xEF, 0xBF, 0xF7, 0xBF, 0xBF ],   // Concatenation of the above\n\n        // Impossible bytes\n        [ 0xF8 ],\n        [ 0xF9 ],\n        [ 0xFA ],\n        [ 0xFB ],\n        [ 0xFC ],\n        [ 0xFD ],\n        [ 0xFE ],\n        [ 0xFF ],\n        [ 0x20, 0xF8, 0x20 ],\n        [ 0x20, 0xF9, 0x20 ],\n        [ 0x20, 0xFA, 0x20 ],\n        [ 0x20, 0xFB, 0x20 ],\n        [ 0x20, 0xFC, 0x20 ],\n        [ 0x20, 0xFD, 0x20 ],\n        [ 0x20, 0xFE, 0x20 ],\n        [ 0x20, 0xFF, 0x20 ],\n\n        // Overlong sequences, all representing U+002F\n        /*  With a safe UTF-8 decoder, all of the following five overlong\n            representations of the ASCII character slash (\"/\") should be\n            rejected like a malformed UTF-8 sequence */\n        [ 0xC0, 0xAF ],\n        [ 0xE0, 0x80, 0xAF ],\n        [ 0xF0, 0x80, 0x80, 0xAF ],\n        [ 0xF8, 0x80, 0x80, 0x80, 0xAF ],\n        [ 0xFC, 0x80, 0x80, 0x80, 0x80, 0xAF ],\n\n        // Maximum overlong sequences\n        /*  Below you see the highest Unicode value that is still resulting in\n            an overlong sequence if represented with the given number of bytes.\n            This is a boundary test for safe UTF-8 decoders. All five\n            characters should be rejected like malformed UTF-8 sequences. */\n        [ 0xC1, 0xBF ],                             // U+0000007F\n        [ 0xE0, 0x9F, 0xBF ],                       // U+000007FF\n        [ 0xF0, 0x8F, 0xBF, 0xBF ],                 // U+0000FFFF\n        [ 0xF8, 0x87, 0xBF, 0xBF, 0xBF ],           // U+001FFFFF\n        [ 0xFC, 0x83, 0xBF, 0xBF, 0xBF, 0xBF ],     // U+03FFFFFF\n\n        // Overlong representation of the NUL character\n        /*  The following five sequences should also be rejected like malformed\n            UTF-8 sequences and should not be treated like the ASCII NUL\n            character. */\n        [ 0xC0, 0x80 ],\n        [ 0xE0, 0x80, 0x80 ],\n        [ 0xF0, 0x80, 0x80, 0x80 ],\n        [ 0xF8, 0x80, 0x80, 0x80, 0x80 ],\n        [ 0xFC, 0x80, 0x80, 0x80, 0x80, 0x80 ],\n\n        // Illegal code positions\n        /*  The following UTF-8 sequences should be rejected like malformed\n            sequences, because they never represent valid ISO 10646 characters\n            and a UTF-8 decoder that accepts them might introduce security\n            problems comparable to overlong UTF-8 sequences. */\n        [ 0xED, 0xA0, 0x80 ],       // U+D800\n        [ 0xED, 0xAD, 0xBF ],       // U+DB7F\n        [ 0xED, 0xAE, 0x80 ],       // U+DB80\n        [ 0xED, 0xAF, 0xBF ],       // U+DBFF\n        [ 0xED, 0xB0, 0x80 ],       // U+DC00\n        [ 0xED, 0xBE, 0x80 ],       // U+DF80\n        [ 0xED, 0xBF, 0xBF ],       // U+DFFF\n    ];\n\n    static string[] sanitizedStrings =\n    [\n        \"\\uFFFD\",\"\\uFFFD\",\n        \"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\" \\uFFFD \",\n        \" \\uFFFD \",\"\\uFFFD\\uFFFD\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\" \\uFFFD \",\" \\uFFFD \",\n        \"\\uFFFD\",\"\\uFFFD\",\" \\uFFFD \",\" \\uFFFD \",\"\\uFFFD\",\"\\uFFFD\",\" \\uFFFD \",\n        \" \\uFFFD \",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\n        \"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\n        \"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\" \\uFFFD \",\n        \" \\uFFFD \",\" \\uFFFD \",\" \\uFFFD \",\" \\uFFFD \",\" \\uFFFD \",\" \\uFFFD \",\n        \" \\uFFFD \",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\n        \"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\n        \"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\"\\uFFFD\",\n    ];\n\n    // HELPER FUNCTIONS\n    // we can probably do this better...\n    static char toHexDigit(int n)\n    {\n        return \"0123456789ABCDEF\"[n & 0xF];\n    }\n\n    static string makeReadable(string s)\n    {\n        string r = \"\\\"\";\n        foreach (char c;s)\n        {\n            if (c >= 0x20 && c < 0x80)\n            {\n                r ~= c;\n            }\n            else\n            {\n                r ~= \"\\\\x\";\n                r ~= toHexDigit(c >> 4);\n                r ~= toHexDigit(c);\n            }\n        }\n        r ~= \"\\\"\";\n        return r;\n    }\n\n    void transcodeReverse(Src,Dst)(immutable(Src)[] s, out immutable(Dst)[] r)\n    {\n        static if (is(Src == Dst))\n        {\n            return s;\n        }\n        else static if (is(Src == AsciiChar))\n        {\n            transcodeReverse!(char,Dst)(cast(string) s,r);\n        }\n        else\n        {\n            foreach_reverse (d;codePoints(s))\n            {\n                foreach_reverse (c;codeUnits!(Dst)(d))\n                {\n                    r = c ~ r;\n                }\n            }\n        }\n    }\n\n    // Make sure everything that should be valid, is\n    foreach (a;validStrings)\n    {\n        string s = cast(string) a;\n        assert(isValid(s),\"Failed to validate: \"~makeReadable(s));\n    }\n\n    // Make sure everything that shouldn't be valid, isn't\n    foreach (a;invalidStrings)\n    {\n        string s = cast(string) a;\n        assert(!isValid(s),\"Incorrectly validated: \"~makeReadable(s));\n    }\n\n    // Make sure we can sanitize everything bad\n    assert(invalidStrings.length == sanitizedStrings.length);\n    for (int i=0; i<invalidStrings.length; ++i)\n    {\n        string s = cast(string) invalidStrings[i];\n        string t = sanitize(s);\n        assert(isValid(t));\n        assert(t == sanitizedStrings[i]);\n        ubyte[] u = cast(ubyte[]) t;\n        validStrings ~= u;\n    }\n\n    // Make sure all transcodings work in both directions, using both forward\n    // and reverse iteration\n    foreach (a; validStrings)\n    {\n        string s = cast(string) a;\n        string s2;\n        wstring ws, ws2;\n        dstring ds, ds2;\n\n        transcode(s,ws);\n        assert(isValid(ws));\n        transcode(ws,s2);\n        assert(s == s2);\n\n        transcode(s,ds);\n        assert(isValid(ds));\n        transcode(ds,s2);\n        assert(s == s2);\n\n        transcode(ws,s);\n        assert(isValid(s));\n        transcode(s,ws2);\n        assert(ws == ws2);\n\n        transcode(ws,ds);\n        assert(isValid(ds));\n        transcode(ds,ws2);\n        assert(ws == ws2);\n\n        transcode(ds,s);\n        assert(isValid(s));\n        transcode(s,ds2);\n        assert(ds == ds2);\n\n        transcode(ds,ws);\n        assert(isValid(ws));\n        transcode(ws,ds2);\n        assert(ds == ds2);\n\n        transcodeReverse(s,ws);\n        assert(isValid(ws));\n        transcodeReverse(ws,s2);\n        assert(s == s2);\n\n        transcodeReverse(s,ds);\n        assert(isValid(ds));\n        transcodeReverse(ds,s2);\n        assert(s == s2);\n\n        transcodeReverse(ws,s);\n        assert(isValid(s));\n        transcodeReverse(s,ws2);\n        assert(ws == ws2);\n\n        transcodeReverse(ws,ds);\n        assert(isValid(ds));\n        transcodeReverse(ds,ws2);\n        assert(ws == ws2);\n\n        transcodeReverse(ds,s);\n        assert(isValid(s));\n        transcodeReverse(s,ds2);\n        assert(ds == ds2);\n\n        transcodeReverse(ds,ws);\n        assert(isValid(ws));\n        transcodeReverse(ws,ds2);\n        assert(ds == ds2);\n    }\n\n    // Make sure the non-UTF encodings work too\n    {\n        auto s = \"\\u20AC100\";\n        Windows1252String t;\n        transcode(s,t);\n        assert(t == cast(Windows1252Char[])[0x80, '1', '0', '0']);\n        string u;\n        transcode(s,u);\n        assert(s == u);\n        Latin1String v;\n        transcode(s,v);\n        assert(cast(string) v == \"?100\");\n        AsciiString w;\n        transcode(v,w);\n        assert(cast(string) w == \"?100\");\n        s = \"\\u017Dlu\\u0165ou\\u010Dk\\u00FD k\\u016F\\u0148\";\n        Latin2String x;\n        transcode(s,x);\n        assert(x == cast(Latin2Char[])[0xae, 'l', 'u', 0xbb, 'o', 'u', 0xe8, 'k', 0xfd, ' ', 'k', 0xf9, 0xf2]);\n        Windows1250String y;\n        transcode(s,y);\n        assert(y == cast(Windows1250Char[])[0x8e, 'l', 'u', 0x9d, 'o', 'u', 0xe8, 'k', 0xfd, ' ', 'k', 0xf9, 0xf2]);\n        s = \"\\u0402lu\\u0403ou\\u201D\\u045C k\\u0414\\u044F\";\n        Windows1251String s51;\n        transcode(s,s51);\n        assert(s51 == cast(Windows1251Char[])[0x80, 'l', 'u', 0x81, 'o', 'u', 0x94, 0x9d, ' ', 'k', 0xc4, 0xff]);\n    }\n\n    // Make sure we can count properly\n    {\n        assert(encodedLength!(char)('A') == 1);\n        assert(encodedLength!(char)('\\u00E3') == 2);\n        assert(encodedLength!(char)('\\u2028') == 3);\n        assert(encodedLength!(char)('\\U0010FFF0') == 4);\n        assert(encodedLength!(wchar)('A') == 1);\n        assert(encodedLength!(wchar)('\\U0010FFF0') == 2);\n    }\n\n    // Make sure we can write into mutable arrays\n    {\n        char[4] buffer;\n        auto n = encode(cast(dchar)'\\u00E3',buffer);\n        assert(n == 2);\n        assert(buffer[0] == 0xC3);\n        assert(buffer[1] == 0xA3);\n    }\n}\n\n//=============================================================================\n\n/** Special value returned by `safeDecode` */\nenum dchar INVALID_SEQUENCE = cast(dchar) 0xFFFFFFFF;\n\ntemplate EncoderFunctions()\n{\n    // Various forms of read\n\n    template ReadFromString()\n    {\n        @property bool canRead() { return s.length != 0; }\n        E peek() @safe pure @nogc nothrow { return s[0]; }\n        E read() @safe pure @nogc nothrow { E t = s[0]; s = s[1..$]; return t; }\n    }\n\n    template ReverseReadFromString()\n    {\n        @property bool canRead() { return s.length != 0; }\n        E peek() @safe pure @nogc nothrow { return s[$-1]; }\n        E read() @safe pure @nogc nothrow { E t = s[$-1]; s = s[0..$-1]; return t; }\n    }\n\n    // Various forms of Write\n\n    template WriteToString()\n    {\n        E[] s;\n        void write(E c) @safe pure nothrow { s ~= c; }\n    }\n\n    template WriteToArray()\n    {\n        void write(E c) @safe pure @nogc nothrow { array[0] = c; array = array[1..$]; }\n    }\n\n    template WriteToDelegate()\n    {\n        void write(E c) { dg(c); }\n    }\n\n    // Functions we will export\n\n    template EncodeViaWrite()\n    {\n        mixin encodeViaWrite;\n        void encode(dchar c) { encodeViaWrite(c); }\n    }\n\n    template SkipViaRead()\n    {\n        mixin skipViaRead;\n        void skip() @safe pure @nogc nothrow { skipViaRead(); }\n    }\n\n    template DecodeViaRead()\n    {\n        mixin decodeViaRead;\n        dchar decode() @safe pure @nogc nothrow { return decodeViaRead(); }\n    }\n\n    template SafeDecodeViaRead()\n    {\n        mixin safeDecodeViaRead;\n        dchar safeDecode() @safe pure @nogc nothrow { return safeDecodeViaRead(); }\n    }\n\n    template DecodeReverseViaRead()\n    {\n        mixin decodeReverseViaRead;\n        dchar decodeReverse() @safe pure @nogc nothrow { return decodeReverseViaRead(); }\n    }\n\n    // Encoding to different destinations\n\n    template EncodeToString()\n    {\n        mixin WriteToString;\n        mixin EncodeViaWrite;\n    }\n\n    template EncodeToArray()\n    {\n        mixin WriteToArray;\n        mixin EncodeViaWrite;\n    }\n\n    template EncodeToDelegate()\n    {\n        mixin WriteToDelegate;\n        mixin EncodeViaWrite;\n    }\n\n    // Decoding functions\n\n    template SkipFromString()\n    {\n        mixin ReadFromString;\n        mixin SkipViaRead;\n    }\n\n    template DecodeFromString()\n    {\n        mixin ReadFromString;\n        mixin DecodeViaRead;\n    }\n\n    template SafeDecodeFromString()\n    {\n        mixin ReadFromString;\n        mixin SafeDecodeViaRead;\n    }\n\n    template DecodeReverseFromString()\n    {\n        mixin ReverseReadFromString;\n        mixin DecodeReverseViaRead;\n    }\n\n    //=========================================================================\n\n    // Below are the functions we will ultimately expose to the user\n\n    E[] encode(dchar c) @safe pure nothrow\n    {\n        mixin EncodeToString e;\n        e.encode(c);\n        return e.s;\n    }\n\n    void encode(dchar c, ref E[] array) @safe pure nothrow\n    {\n        mixin EncodeToArray e;\n        e.encode(c);\n    }\n\n    void encode(dchar c, void delegate(E) dg)\n    {\n        mixin EncodeToDelegate e;\n        e.encode(c);\n    }\n\n    void skip(ref const(E)[] s) @safe pure nothrow\n    {\n        mixin SkipFromString e;\n        e.skip();\n    }\n\n    dchar decode(S)(ref S s)\n    {\n        mixin DecodeFromString e;\n        return e.decode();\n    }\n\n    dchar safeDecode(S)(ref S s)\n    {\n        mixin SafeDecodeFromString e;\n        return e.safeDecode();\n    }\n\n    dchar decodeReverse(ref const(E)[] s) @safe pure nothrow\n    {\n        mixin DecodeReverseFromString e;\n        return e.decodeReverse();\n    }\n}\n\n//=========================================================================\n\nstruct CodePoints(E)\n{\n    const(E)[] s;\n\n    this(const(E)[] s)\n    in\n    {\n        assert(isValid(s));\n    }\n    do\n    {\n        this.s = s;\n    }\n\n    int opApply(scope int delegate(ref dchar) dg)\n    {\n        int result = 0;\n        while (s.length != 0)\n        {\n            dchar c = decode(s);\n            result = dg(c);\n            if (result != 0) break;\n        }\n        return result;\n    }\n\n    int opApply(scope int delegate(ref size_t, ref dchar) dg)\n    {\n        size_t i = 0;\n        int result = 0;\n        while (s.length != 0)\n        {\n            immutable len = s.length;\n            dchar c = decode(s);\n            size_t j = i; // We don't want the delegate corrupting i\n            result = dg(j,c);\n            if (result != 0) break;\n            i += len - s.length;\n        }\n        return result;\n    }\n\n    int opApplyReverse(scope int delegate(ref dchar) dg)\n    {\n        int result = 0;\n        while (s.length != 0)\n        {\n            dchar c = decodeReverse(s);\n            result = dg(c);\n            if (result != 0) break;\n        }\n        return result;\n    }\n\n    int opApplyReverse(scope int delegate(ref size_t, ref dchar) dg)\n    {\n        int result = 0;\n        while (s.length != 0)\n        {\n            dchar c = decodeReverse(s);\n            size_t i = s.length;\n            result = dg(i,c);\n            if (result != 0) break;\n        }\n        return result;\n    }\n}\n\nstruct CodeUnits(E)\n{\n    E[] s;\n\n    this(dchar d)\n    in\n    {\n        assert(isValidCodePoint(d));\n    }\n    do\n    {\n        s = encode!(E)(d);\n    }\n\n    int opApply(scope int delegate(ref E) dg)\n    {\n        int result = 0;\n        foreach (E c;s)\n        {\n            result = dg(c);\n            if (result != 0) break;\n        }\n        return result;\n    }\n\n    int opApplyReverse(scope int delegate(ref E) dg)\n    {\n        int result = 0;\n        foreach_reverse (E c;s)\n        {\n            result = dg(c);\n            if (result != 0) break;\n        }\n        return result;\n    }\n}\n\n//=============================================================================\n\ntemplate EncoderInstance(E)\n{\n    static assert(false,\"Cannot instantiate EncoderInstance for type \"\n        ~ E.stringof);\n}\n\nprivate template GenericEncoder()\n{\n    bool canEncode(dchar c) @safe pure @nogc nothrow\n    {\n        if (c < m_charMapStart || (c > m_charMapEnd && c < 0x100)) return true;\n        if (c >= 0xFFFD) return false;\n\n        auto idx = 0;\n        while (idx < bstMap.length)\n        {\n            if (bstMap[idx][0] == c) return true;\n            idx = bstMap[idx][0] > c ? 2 * idx + 1 : 2 * idx + 2; // next BST index\n        }\n\n        return false;\n    }\n\n    bool isValidCodeUnit(E c) @safe pure @nogc nothrow\n    {\n        if (c < m_charMapStart || c > m_charMapEnd) return true;\n        return charMap[c-m_charMapStart] != 0xFFFD;\n    }\n\n    size_t encodedLength(dchar c) @safe pure @nogc nothrow\n    in\n    {\n        assert(canEncode(c));\n    }\n    do\n    {\n        return 1;\n    }\n\n    void encodeViaWrite()(dchar c)\n    {\n        if (c < m_charMapStart || (c > m_charMapEnd && c < 0x100)) {}\n        else if (c >= 0xFFFD) { c = '?'; }\n        else\n        {\n            auto idx = 0;\n            while (idx < bstMap.length)\n            {\n                if (bstMap[idx][0] == c)\n                {\n                    write(cast(E) bstMap[idx][1]);\n                    return;\n                }\n                idx = bstMap[idx][0] > c ? 2 * idx + 1 : 2 * idx + 2; // next BST index\n            }\n            c = '?';\n        }\n        write(cast(E) c);\n    }\n\n    void skipViaRead()()\n    {\n        read();\n    }\n\n    dchar decodeViaRead()()\n    {\n        E c = read();\n        return (c >= m_charMapStart && c <= m_charMapEnd) ? charMap[c-m_charMapStart] : c;\n    }\n\n    dchar safeDecodeViaRead()()\n    {\n        immutable E c = read();\n        immutable d = (c >= m_charMapStart && c <= m_charMapEnd) ? charMap[c-m_charMapStart] : c;\n        return d == 0xFFFD ? INVALID_SEQUENCE : d;\n    }\n\n    dchar decodeReverseViaRead()()\n    {\n        E c = read();\n        return (c >= m_charMapStart && c <= m_charMapEnd) ? charMap[c-m_charMapStart] : c;\n    }\n\n    @property EString replacementSequence() @safe pure @nogc nothrow\n    {\n        return cast(EString)(\"?\");\n    }\n\n    mixin EncoderFunctions;\n}\n\n//=============================================================================\n//          ASCII\n//=============================================================================\n\n/** Defines various character sets. */\nenum AsciiChar : ubyte { init }\n/// Ditto\nalias AsciiString = immutable(AsciiChar)[];\n\ntemplate EncoderInstance(CharType : AsciiChar)\n{\n    alias E = AsciiChar;\n    alias EString = AsciiString;\n\n    @property string encodingName() @safe pure nothrow @nogc\n    {\n        return \"ASCII\";\n    }\n\n    bool canEncode(dchar c) @safe pure nothrow @nogc\n    {\n        return c < 0x80;\n    }\n\n    bool isValidCodeUnit(AsciiChar c) @safe pure nothrow @nogc\n    {\n        return c < 0x80;\n    }\n\n    size_t encodedLength(dchar c) @safe pure nothrow @nogc\n    in\n    {\n        assert(canEncode(c));\n    }\n    do\n    {\n        return 1;\n    }\n\n    void encodeX(Range)(dchar c, Range r)\n    {\n        if (!canEncode(c)) c = '?';\n        r.write(cast(AsciiChar) c);\n    }\n\n    void encodeViaWrite()(dchar c)\n    {\n        if (!canEncode(c)) c = '?';\n        write(cast(AsciiChar) c);\n    }\n\n    void skipViaRead()()\n    {\n        read();\n    }\n\n    dchar decodeViaRead()()\n    {\n        return read();\n    }\n\n    dchar safeDecodeViaRead()()\n    {\n        immutable c = read();\n        return canEncode(c) ? c : INVALID_SEQUENCE;\n    }\n\n    dchar decodeReverseViaRead()()\n    {\n        return read();\n    }\n\n    @property EString replacementSequence() @safe pure nothrow @nogc\n    {\n        return cast(EString)(\"?\");\n    }\n\n    mixin EncoderFunctions;\n}\n\n//=============================================================================\n//          ISO-8859-1\n//=============================================================================\n\n/** Defines an Latin1-encoded character. */\nenum Latin1Char : ubyte { init }\n/**\nDefines an Latin1-encoded string (as an array of $(D\nimmutable(Latin1Char))).\n */\nalias Latin1String = immutable(Latin1Char)[];\n\ntemplate EncoderInstance(CharType : Latin1Char)\n{\n    alias E = Latin1Char;\n    alias EString = Latin1String;\n\n    @property string encodingName() @safe pure nothrow @nogc\n    {\n        return \"ISO-8859-1\";\n    }\n\n    bool canEncode(dchar c) @safe pure nothrow @nogc\n    {\n        return c < 0x100;\n    }\n\n    bool isValidCodeUnit(Latin1Char c) @safe pure nothrow @nogc\n    {\n        return true;\n    }\n\n    size_t encodedLength(dchar c) @safe pure nothrow @nogc\n    in\n    {\n        assert(canEncode(c));\n    }\n    do\n    {\n        return 1;\n    }\n\n    void encodeViaWrite()(dchar c)\n    {\n        if (!canEncode(c)) c = '?';\n        write(cast(Latin1Char) c);\n    }\n\n    void skipViaRead()()\n    {\n        read();\n    }\n\n    dchar decodeViaRead()()\n    {\n        return read();\n    }\n\n    dchar safeDecodeViaRead()()\n    {\n        return read();\n    }\n\n    dchar decodeReverseViaRead()()\n    {\n        return read();\n    }\n\n    @property EString replacementSequence() @safe pure nothrow @nogc\n    {\n        return cast(EString)(\"?\");\n    }\n\n    mixin EncoderFunctions;\n}\n\n//=============================================================================\n//          ISO-8859-2\n//=============================================================================\n\n/// Defines a Latin2-encoded character.\nenum Latin2Char : ubyte { init }\n\n/**\n * Defines an Latin2-encoded string (as an array of $(D\n * immutable(Latin2Char))).\n */\nalias Latin2String = immutable(Latin2Char)[];\n\nprivate template EncoderInstance(CharType : Latin2Char)\n{\n    import std.typecons : Tuple, tuple;\n\n    alias E = Latin2Char;\n    alias EString = Latin2String;\n\n    @property string encodingName() @safe pure nothrow @nogc\n    {\n        return \"ISO-8859-2\";\n    }\n\n    private static immutable dchar m_charMapStart = 0xa1;\n    private static immutable dchar m_charMapEnd = 0xff;\n\n    private immutable wstring charMap =\n        \"\\u0104\\u02D8\\u0141\\u00A4\\u013D\\u015A\\u00A7\\u00A8\"~\n        \"\\u0160\\u015E\\u0164\\u0179\\u00AD\\u017D\\u017B\\u00B0\"~\n        \"\\u0105\\u02DB\\u0142\\u00B4\\u013E\\u015B\\u02C7\\u00B8\"~\n        \"\\u0161\\u015F\\u0165\\u017A\\u02DD\\u017E\\u017C\\u0154\"~\n        \"\\u00C1\\u00C2\\u0102\\u00C4\\u0139\\u0106\\u00C7\\u010C\"~\n        \"\\u00C9\\u0118\\u00CB\\u011A\\u00CD\\u00CE\\u010E\\u0110\"~\n        \"\\u0143\\u0147\\u00D3\\u00D4\\u0150\\u00D6\\u00D7\\u0158\"~\n        \"\\u016E\\u00DA\\u0170\\u00DC\\u00DD\\u0162\\u00DF\\u0155\"~\n        \"\\u00E1\\u00E2\\u0103\\u00E4\\u013A\\u0107\\u00E7\\u010D\"~\n        \"\\u00E9\\u0119\\u00EB\\u011B\\u00ED\\u00EE\\u010F\\u0111\"~\n        \"\\u0144\\u0148\\u00F3\\u00F4\\u0151\\u00F6\\u00F7\\u0159\"~\n        \"\\u016F\\u00FA\\u0171\\u00FC\\u00FD\\u0163\\u02D9\";\n\n    private immutable Tuple!(wchar, char)[] bstMap = [\n        tuple('\\u0148','\\xF2'), tuple('\\u00F3','\\xF3'), tuple('\\u0165','\\xBB'),\n        tuple('\\u00D3','\\xD3'), tuple('\\u010F','\\xEF'), tuple('\\u015B','\\xB6'),\n        tuple('\\u017C','\\xBF'), tuple('\\u00C1','\\xC1'), tuple('\\u00E1','\\xE1'),\n        tuple('\\u0103','\\xE3'), tuple('\\u013A','\\xE5'), tuple('\\u0155','\\xE0'),\n        tuple('\\u0161','\\xB9'), tuple('\\u0171','\\xFB'), tuple('\\u02D8','\\xA2'),\n        tuple('\\u00AD','\\xAD'), tuple('\\u00C9','\\xC9'), tuple('\\u00DA','\\xDA'),\n        tuple('\\u00E9','\\xE9'), tuple('\\u00FA','\\xFA'), tuple('\\u0107','\\xE6'),\n        tuple('\\u0119','\\xEA'), tuple('\\u0142','\\xB3'), tuple('\\u0151','\\xF5'),\n        tuple('\\u0159','\\xF8'), tuple('\\u015F','\\xBA'), tuple('\\u0163','\\xFE'),\n        tuple('\\u016F','\\xF9'), tuple('\\u017A','\\xBC'), tuple('\\u017E','\\xBE'),\n        tuple('\\u02DB','\\xB2'), tuple('\\u00A7','\\xA7'), tuple('\\u00B4','\\xB4'),\n        tuple('\\u00C4','\\xC4'), tuple('\\u00CD','\\xCD'), tuple('\\u00D6','\\xD6'),\n        tuple('\\u00DD','\\xDD'), tuple('\\u00E4','\\xE4'), tuple('\\u00ED','\\xED'),\n        tuple('\\u00F6','\\xF6'), tuple('\\u00FD','\\xFD'), tuple('\\u0105','\\xB1'),\n        tuple('\\u010D','\\xE8'), tuple('\\u0111','\\xF0'), tuple('\\u011B','\\xEC'),\n        tuple('\\u013E','\\xB5'), tuple('\\u0144','\\xF1'), tuple('\\u0150','\\xD5'),\n        tuple('\\u0154','\\xC0'), tuple('\\u0158','\\xD8'), tuple('\\u015A','\\xA6'),\n        tuple('\\u015E','\\xAA'), tuple('\\u0160','\\xA9'), tuple('\\u0162','\\xDE'),\n        tuple('\\u0164','\\xAB'), tuple('\\u016E','\\xD9'), tuple('\\u0170','\\xDB'),\n        tuple('\\u0179','\\xAC'), tuple('\\u017B','\\xAF'), tuple('\\u017D','\\xAE'),\n        tuple('\\u02C7','\\xB7'), tuple('\\u02D9','\\xFF'), tuple('\\u02DD','\\xBD'),\n        tuple('\\u00A4','\\xA4'), tuple('\\u00A8','\\xA8'), tuple('\\u00B0','\\xB0'),\n        tuple('\\u00B8','\\xB8'), tuple('\\u00C2','\\xC2'), tuple('\\u00C7','\\xC7'),\n        tuple('\\u00CB','\\xCB'), tuple('\\u00CE','\\xCE'), tuple('\\u00D4','\\xD4'),\n        tuple('\\u00D7','\\xD7'), tuple('\\u00DC','\\xDC'), tuple('\\u00DF','\\xDF'),\n        tuple('\\u00E2','\\xE2'), tuple('\\u00E7','\\xE7'), tuple('\\u00EB','\\xEB'),\n        tuple('\\u00EE','\\xEE'), tuple('\\u00F4','\\xF4'), tuple('\\u00F7','\\xF7'),\n        tuple('\\u00FC','\\xFC'), tuple('\\u0102','\\xC3'), tuple('\\u0104','\\xA1'),\n        tuple('\\u0106','\\xC6'), tuple('\\u010C','\\xC8'), tuple('\\u010E','\\xCF'),\n        tuple('\\u0110','\\xD0'), tuple('\\u0118','\\xCA'), tuple('\\u011A','\\xCC'),\n        tuple('\\u0139','\\xC5'), tuple('\\u013D','\\xA5'), tuple('\\u0141','\\xA3'),\n        tuple('\\u0143','\\xD1'), tuple('\\u0147','\\xD2')\n    ];\n\n    mixin GenericEncoder!();\n}\n\n//=============================================================================\n//          WINDOWS-1250\n//=============================================================================\n\n/// Defines a Windows1250-encoded character.\nenum Windows1250Char : ubyte { init }\n\n/**\n * Defines an Windows1250-encoded string (as an array of $(D\n * immutable(Windows1250Char))).\n */\nalias Windows1250String = immutable(Windows1250Char)[];\n\nprivate template EncoderInstance(CharType : Windows1250Char)\n{\n    import std.typecons : Tuple, tuple;\n\n    alias E = Windows1250Char;\n    alias EString = Windows1250String;\n\n    @property string encodingName() @safe pure nothrow @nogc\n    {\n        return \"windows-1250\";\n    }\n\n    private static immutable dchar m_charMapStart = 0x80;\n    private static immutable dchar m_charMapEnd = 0xff;\n\n    private immutable wstring charMap =\n        \"\\u20AC\\uFFFD\\u201A\\uFFFD\\u201E\\u2026\\u2020\\u2021\"~\n        \"\\uFFFD\\u2030\\u0160\\u2039\\u015A\\u0164\\u017D\\u0179\"~\n        \"\\uFFFD\\u2018\\u2019\\u201C\\u201D\\u2022\\u2013\\u2014\"~\n        \"\\uFFFD\\u2122\\u0161\\u203A\\u015B\\u0165\\u017E\\u017A\"~\n        \"\\u00A0\\u02C7\\u02D8\\u0141\\u00A4\\u0104\\u00A6\\u00A7\"~\n        \"\\u00A8\\u00A9\\u015E\\u00AB\\u00AC\\u00AD\\u00AE\\u017B\"~\n        \"\\u00B0\\u00B1\\u02DB\\u0142\\u00B4\\u00B5\\u00B6\\u00B7\"~\n        \"\\u00B8\\u0105\\u015F\\u00BB\\u013D\\u02DD\\u013E\\u017C\"~\n        \"\\u0154\\u00C1\\u00C2\\u0102\\u00C4\\u0139\\u0106\\u00C7\"~\n        \"\\u010C\\u00C9\\u0118\\u00CB\\u011A\\u00CD\\u00CE\\u010E\"~\n        \"\\u0110\\u0143\\u0147\\u00D3\\u00D4\\u0150\\u00D6\\u00D7\"~\n        \"\\u0158\\u016E\\u00DA\\u0170\\u00DC\\u00DD\\u0162\\u00DF\"~\n        \"\\u0155\\u00E1\\u00E2\\u0103\\u00E4\\u013A\\u0107\\u00E7\"~\n        \"\\u010D\\u00E9\\u0119\\u00EB\\u011B\\u00ED\\u00EE\\u010F\"~\n        \"\\u0111\\u0144\\u0148\\u00F3\\u00F4\\u0151\\u00F6\\u00F7\"~\n        \"\\u0159\\u016F\\u00FA\\u0171\\u00FC\\u00FD\\u0163\\u02D9\";\n\n    private immutable Tuple!(wchar, char)[] bstMap = [\n        tuple('\\u011A','\\xCC'), tuple('\\u00DC','\\xDC'), tuple('\\u0179','\\x8F'),\n        tuple('\\u00B7','\\xB7'), tuple('\\u00FC','\\xFC'), tuple('\\u0158','\\xD8'),\n        tuple('\\u201C','\\x93'), tuple('\\u00AC','\\xAC'), tuple('\\u00CB','\\xCB'),\n        tuple('\\u00EB','\\xEB'), tuple('\\u010C','\\xC8'), tuple('\\u0143','\\xD1'),\n        tuple('\\u0162','\\xDE'), tuple('\\u02D9','\\xFF'), tuple('\\u2039','\\x8B'),\n        tuple('\\u00A7','\\xA7'), tuple('\\u00B1','\\xB1'), tuple('\\u00C2','\\xC2'),\n        tuple('\\u00D4','\\xD4'), tuple('\\u00E2','\\xE2'), tuple('\\u00F4','\\xF4'),\n        tuple('\\u0104','\\xA5'), tuple('\\u0110','\\xD0'), tuple('\\u013D','\\xBC'),\n        tuple('\\u0150','\\xD5'), tuple('\\u015E','\\xAA'), tuple('\\u016E','\\xD9'),\n        tuple('\\u017D','\\x8E'), tuple('\\u2014','\\x97'), tuple('\\u2021','\\x87'),\n        tuple('\\u20AC','\\x80'), tuple('\\u00A4','\\xA4'), tuple('\\u00A9','\\xA9'),\n        tuple('\\u00AE','\\xAE'), tuple('\\u00B5','\\xB5'), tuple('\\u00BB','\\xBB'),\n        tuple('\\u00C7','\\xC7'), tuple('\\u00CE','\\xCE'), tuple('\\u00D7','\\xD7'),\n        tuple('\\u00DF','\\xDF'), tuple('\\u00E7','\\xE7'), tuple('\\u00EE','\\xEE'),\n        tuple('\\u00F7','\\xF7'), tuple('\\u0102','\\xC3'), tuple('\\u0106','\\xC6'),\n        tuple('\\u010E','\\xCF'), tuple('\\u0118','\\xCA'), tuple('\\u0139','\\xC5'),\n        tuple('\\u0141','\\xA3'), tuple('\\u0147','\\xD2'), tuple('\\u0154','\\xC0'),\n        tuple('\\u015A','\\x8C'), tuple('\\u0160','\\x8A'), tuple('\\u0164','\\x8D'),\n        tuple('\\u0170','\\xDB'), tuple('\\u017B','\\xAF'), tuple('\\u02C7','\\xA1'),\n        tuple('\\u02DD','\\xBD'), tuple('\\u2019','\\x92'), tuple('\\u201E','\\x84'),\n        tuple('\\u2026','\\x85'), tuple('\\u203A','\\x9B'), tuple('\\u2122','\\x99'),\n        tuple('\\u00A0','\\xA0'), tuple('\\u00A6','\\xA6'), tuple('\\u00A8','\\xA8'),\n        tuple('\\u00AB','\\xAB'), tuple('\\u00AD','\\xAD'), tuple('\\u00B0','\\xB0'),\n        tuple('\\u00B4','\\xB4'), tuple('\\u00B6','\\xB6'), tuple('\\u00B8','\\xB8'),\n        tuple('\\u00C1','\\xC1'), tuple('\\u00C4','\\xC4'), tuple('\\u00C9','\\xC9'),\n        tuple('\\u00CD','\\xCD'), tuple('\\u00D3','\\xD3'), tuple('\\u00D6','\\xD6'),\n        tuple('\\u00DA','\\xDA'), tuple('\\u00DD','\\xDD'), tuple('\\u00E1','\\xE1'),\n        tuple('\\u00E4','\\xE4'), tuple('\\u00E9','\\xE9'), tuple('\\u00ED','\\xED'),\n        tuple('\\u00F3','\\xF3'), tuple('\\u00F6','\\xF6'), tuple('\\u00FA','\\xFA'),\n        tuple('\\u00FD','\\xFD'), tuple('\\u0103','\\xE3'), tuple('\\u0105','\\xB9'),\n        tuple('\\u0107','\\xE6'), tuple('\\u010D','\\xE8'), tuple('\\u010F','\\xEF'),\n        tuple('\\u0111','\\xF0'), tuple('\\u0119','\\xEA'), tuple('\\u011B','\\xEC'),\n        tuple('\\u013A','\\xE5'), tuple('\\u013E','\\xBE'), tuple('\\u0142','\\xB3'),\n        tuple('\\u0144','\\xF1'), tuple('\\u0148','\\xF2'), tuple('\\u0151','\\xF5'),\n        tuple('\\u0155','\\xE0'), tuple('\\u0159','\\xF8'), tuple('\\u015B','\\x9C'),\n        tuple('\\u015F','\\xBA'), tuple('\\u0161','\\x9A'), tuple('\\u0163','\\xFE'),\n        tuple('\\u0165','\\x9D'), tuple('\\u016F','\\xF9'), tuple('\\u0171','\\xFB'),\n        tuple('\\u017A','\\x9F'), tuple('\\u017C','\\xBF'), tuple('\\u017E','\\x9E'),\n        tuple('\\u02D8','\\xA2'), tuple('\\u02DB','\\xB2'), tuple('\\u2013','\\x96'),\n        tuple('\\u2018','\\x91'), tuple('\\u201A','\\x82'), tuple('\\u201D','\\x94'),\n        tuple('\\u2020','\\x86'), tuple('\\u2022','\\x95'), tuple('\\u2030','\\x89')\n    ];\n\n    mixin GenericEncoder!();\n}\n\n//=============================================================================\n//          WINDOWS-1251\n//=============================================================================\n\n/// Defines a Windows1251-encoded character.\nenum Windows1251Char : ubyte { init }\n\n/**\n * Defines an Windows1251-encoded string (as an array of $(D\n * immutable(Windows1251Char))).\n */\nalias Windows1251String = immutable(Windows1251Char)[];\n\nprivate template EncoderInstance(CharType : Windows1251Char)\n{\n    import std.typecons : Tuple, tuple;\n\n    alias E = Windows1251Char;\n    alias EString = Windows1251String;\n\n    @property string encodingName() @safe pure nothrow @nogc\n    {\n        return \"windows-1251\";\n    }\n\n    private static immutable dchar m_charMapStart = 0x80;\n    private static immutable dchar m_charMapEnd = 0xff;\n\n    private immutable wstring charMap =\n        \"\\u0402\\u0403\\u201A\\u0453\\u201E\\u2026\\u2020\\u2021\"~\n        \"\\u20AC\\u2030\\u0409\\u2039\\u040A\\u040C\\u040B\\u040F\"~\n        \"\\u0452\\u2018\\u2019\\u201C\\u201D\\u2022\\u2013\\u2014\"~\n        \"\\uFFFD\\u2122\\u0459\\u203A\\u045A\\u045C\\u045B\\u045F\"~\n        \"\\u00A0\\u040E\\u045E\\u0408\\u00A4\\u0490\\u00A6\\u00A7\"~\n        \"\\u0401\\u00A9\\u0404\\u00AB\\u00AC\\u00AD\\u00AE\\u0407\"~\n        \"\\u00B0\\u00B1\\u0406\\u0456\\u0491\\u00B5\\u00B6\\u00B7\"~\n        \"\\u0451\\u2116\\u0454\\u00BB\\u0458\\u0405\\u0455\\u0457\"~\n        \"\\u0410\\u0411\\u0412\\u0413\\u0414\\u0415\\u0416\\u0417\"~\n        \"\\u0418\\u0419\\u041A\\u041B\\u041C\\u041D\\u041E\\u041F\"~\n        \"\\u0420\\u0421\\u0422\\u0423\\u0424\\u0425\\u0426\\u0427\"~\n        \"\\u0428\\u0429\\u042A\\u042B\\u042C\\u042D\\u042E\\u042F\"~\n        \"\\u0430\\u0431\\u0432\\u0433\\u0434\\u0435\\u0436\\u0437\"~\n        \"\\u0438\\u0439\\u043A\\u043B\\u043C\\u043D\\u043E\\u043F\"~\n        \"\\u0440\\u0441\\u0442\\u0443\\u0444\\u0445\\u0446\\u0447\"~\n        \"\\u0448\\u0449\\u044A\\u044B\\u044C\\u044D\\u044E\\u044F\";\n\n    private immutable Tuple!(wchar, char)[] bstMap = [\n        tuple('\\u0432','\\xE2'),tuple('\\u0412','\\xC2'),tuple('\\u0453','\\x83'),\n        tuple('\\u0401','\\xA8'),tuple('\\u0422','\\xD2'),tuple('\\u0442','\\xF2'),\n        tuple('\\u2018','\\x91'),tuple('\\u00AD','\\xAD'),tuple('\\u0409','\\x8A'),\n        tuple('\\u041A','\\xCA'),tuple('\\u042A','\\xDA'),tuple('\\u043A','\\xEA'),\n        tuple('\\u044A','\\xFA'),tuple('\\u045B','\\x9E'),tuple('\\u2022','\\x95'),\n        tuple('\\u00A7','\\xA7'),tuple('\\u00B5','\\xB5'),tuple('\\u0405','\\xBD'),\n        tuple('\\u040E','\\xA1'),tuple('\\u0416','\\xC6'),tuple('\\u041E','\\xCE'),\n        tuple('\\u0426','\\xD6'),tuple('\\u042E','\\xDE'),tuple('\\u0436','\\xE6'),\n        tuple('\\u043E','\\xEE'),tuple('\\u0446','\\xF6'),tuple('\\u044E','\\xFE'),\n        tuple('\\u0457','\\xBF'),tuple('\\u0490','\\xA5'),tuple('\\u201D','\\x94'),\n        tuple('\\u203A','\\x9B'),tuple('\\u00A4','\\xA4'),tuple('\\u00AB','\\xAB'),\n        tuple('\\u00B0','\\xB0'),tuple('\\u00B7','\\xB7'),tuple('\\u0403','\\x81'),\n        tuple('\\u0407','\\xAF'),tuple('\\u040B','\\x8E'),tuple('\\u0410','\\xC0'),\n        tuple('\\u0414','\\xC4'),tuple('\\u0418','\\xC8'),tuple('\\u041C','\\xCC'),\n        tuple('\\u0420','\\xD0'),tuple('\\u0424','\\xD4'),tuple('\\u0428','\\xD8'),\n        tuple('\\u042C','\\xDC'),tuple('\\u0430','\\xE0'),tuple('\\u0434','\\xE4'),\n        tuple('\\u0438','\\xE8'),tuple('\\u043C','\\xEC'),tuple('\\u0440','\\xF0'),\n        tuple('\\u0444','\\xF4'),tuple('\\u0448','\\xF8'),tuple('\\u044C','\\xFC'),\n        tuple('\\u0451','\\xB8'),tuple('\\u0455','\\xBE'),tuple('\\u0459','\\x9A'),\n        tuple('\\u045E','\\xA2'),tuple('\\u2013','\\x96'),tuple('\\u201A','\\x82'),\n        tuple('\\u2020','\\x86'),tuple('\\u2030','\\x89'),tuple('\\u2116','\\xB9'),\n        tuple('\\u00A0','\\xA0'),tuple('\\u00A6','\\xA6'),tuple('\\u00A9','\\xA9'),\n        tuple('\\u00AC','\\xAC'),tuple('\\u00AE','\\xAE'),tuple('\\u00B1','\\xB1'),\n        tuple('\\u00B6','\\xB6'),tuple('\\u00BB','\\xBB'),tuple('\\u0402','\\x80'),\n        tuple('\\u0404','\\xAA'),tuple('\\u0406','\\xB2'),tuple('\\u0408','\\xA3'),\n        tuple('\\u040A','\\x8C'),tuple('\\u040C','\\x8D'),tuple('\\u040F','\\x8F'),\n        tuple('\\u0411','\\xC1'),tuple('\\u0413','\\xC3'),tuple('\\u0415','\\xC5'),\n        tuple('\\u0417','\\xC7'),tuple('\\u0419','\\xC9'),tuple('\\u041B','\\xCB'),\n        tuple('\\u041D','\\xCD'),tuple('\\u041F','\\xCF'),tuple('\\u0421','\\xD1'),\n        tuple('\\u0423','\\xD3'),tuple('\\u0425','\\xD5'),tuple('\\u0427','\\xD7'),\n        tuple('\\u0429','\\xD9'),tuple('\\u042B','\\xDB'),tuple('\\u042D','\\xDD'),\n        tuple('\\u042F','\\xDF'),tuple('\\u0431','\\xE1'),tuple('\\u0433','\\xE3'),\n        tuple('\\u0435','\\xE5'),tuple('\\u0437','\\xE7'),tuple('\\u0439','\\xE9'),\n        tuple('\\u043B','\\xEB'),tuple('\\u043D','\\xED'),tuple('\\u043F','\\xEF'),\n        tuple('\\u0441','\\xF1'),tuple('\\u0443','\\xF3'),tuple('\\u0445','\\xF5'),\n        tuple('\\u0447','\\xF7'),tuple('\\u0449','\\xF9'),tuple('\\u044B','\\xFB'),\n        tuple('\\u044D','\\xFD'),tuple('\\u044F','\\xFF'),tuple('\\u0452','\\x90'),\n        tuple('\\u0454','\\xBA'),tuple('\\u0456','\\xB3'),tuple('\\u0458','\\xBC'),\n        tuple('\\u045A','\\x9C'),tuple('\\u045C','\\x9D'),tuple('\\u045F','\\x9F'),\n        tuple('\\u0491','\\xB4'),tuple('\\u2014','\\x97'),tuple('\\u2019','\\x92'),\n        tuple('\\u201C','\\x93'),tuple('\\u201E','\\x84'),tuple('\\u2021','\\x87'),\n        tuple('\\u2026','\\x85'),tuple('\\u2039','\\x8B'),tuple('\\u20AC','\\x88'),\n        tuple('\\u2122','\\x99')\n    ];\n\n    mixin GenericEncoder!();\n}\n\n//=============================================================================\n//          WINDOWS-1252\n//=============================================================================\n\n/// Defines a Windows1252-encoded character.\nenum Windows1252Char : ubyte { init }\n\n/**\n * Defines an Windows1252-encoded string (as an array of $(D\n * immutable(Windows1252Char))).\n */\nalias Windows1252String = immutable(Windows1252Char)[];\n\ntemplate EncoderInstance(CharType : Windows1252Char)\n{\n    import std.typecons : Tuple, tuple;\n\n    alias E = Windows1252Char;\n    alias EString = Windows1252String;\n\n    @property string encodingName() @safe pure nothrow @nogc\n    {\n        return \"windows-1252\";\n    }\n\n    private static immutable dchar m_charMapStart = 0x80;\n    private static immutable dchar m_charMapEnd = 0x9f;\n\n    private immutable wstring charMap =\n        \"\\u20AC\\uFFFD\\u201A\\u0192\\u201E\\u2026\\u2020\\u2021\"~\n        \"\\u02C6\\u2030\\u0160\\u2039\\u0152\\uFFFD\\u017D\\uFFFD\"~\n        \"\\uFFFD\\u2018\\u2019\\u201C\\u201D\\u2022\\u2013\\u2014\"~\n        \"\\u02DC\\u2122\\u0161\\u203A\\u0153\\uFFFD\\u017E\\u0178\";\n\n    private immutable Tuple!(wchar, char)[] bstMap = [\n        tuple('\\u201C','\\x93'), tuple('\\u0192','\\x83'), tuple('\\u2039','\\x8B'),\n        tuple('\\u0161','\\x9A'), tuple('\\u2014','\\x97'), tuple('\\u2021','\\x87'),\n        tuple('\\u20AC','\\x80'), tuple('\\u0153','\\x9C'), tuple('\\u017D','\\x8E'),\n        tuple('\\u02DC','\\x98'), tuple('\\u2019','\\x92'), tuple('\\u201E','\\x84'),\n        tuple('\\u2026','\\x85'), tuple('\\u203A','\\x9B'), tuple('\\u2122','\\x99'),\n        tuple('\\u0152','\\x8C'), tuple('\\u0160','\\x8A'), tuple('\\u0178','\\x9F'),\n        tuple('\\u017E','\\x9E'), tuple('\\u02C6','\\x88'), tuple('\\u2013','\\x96'),\n        tuple('\\u2018','\\x91'), tuple('\\u201A','\\x82'), tuple('\\u201D','\\x94'),\n        tuple('\\u2020','\\x86'), tuple('\\u2022','\\x95'), tuple('\\u2030','\\x89')\n    ];\n\n    mixin GenericEncoder!();\n}\n\n//=============================================================================\n//          UTF-8\n//=============================================================================\n\ntemplate EncoderInstance(CharType : char)\n{\n    alias E = char;\n    alias EString = immutable(char)[];\n\n    @property string encodingName() @safe pure nothrow @nogc\n    {\n        return \"UTF-8\";\n    }\n\n    bool canEncode(dchar c) @safe pure nothrow @nogc\n    {\n        return isValidCodePoint(c);\n    }\n\n    bool isValidCodeUnit(char c) @safe pure nothrow @nogc\n    {\n        return (c < 0xC0 || (c >= 0xC2 && c < 0xF5));\n    }\n\n    immutable ubyte[128] tailTable =\n    [\n        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n        2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,\n        3,3,3,3,3,3,3,3,4,4,4,4,5,5,6,0,\n    ];\n\n    private int tails(char c) @safe pure nothrow @nogc\n    in\n    {\n        assert(c >= 0x80);\n    }\n    do\n    {\n        return tailTable[c-0x80];\n    }\n\n    size_t encodedLength(dchar c) @safe pure nothrow @nogc\n    in\n    {\n        assert(canEncode(c));\n    }\n    do\n    {\n        if (c < 0x80) return 1;\n        if (c < 0x800) return 2;\n        if (c < 0x10000) return 3;\n        return 4;\n    }\n\n    void encodeViaWrite()(dchar c)\n    {\n        if (c < 0x80)\n        {\n            write(cast(char) c);\n        }\n        else if (c < 0x800)\n        {\n            write(cast(char)((c >> 6) + 0xC0));\n            write(cast(char)((c & 0x3F) + 0x80));\n        }\n        else if (c < 0x10000)\n        {\n            write(cast(char)((c >> 12) + 0xE0));\n            write(cast(char)(((c >> 6) & 0x3F) + 0x80));\n            write(cast(char)((c & 0x3F) + 0x80));\n        }\n        else\n        {\n            write(cast(char)((c >> 18) + 0xF0));\n            write(cast(char)(((c >> 12) & 0x3F) + 0x80));\n            write(cast(char)(((c >> 6) & 0x3F) + 0x80));\n            write(cast(char)((c & 0x3F) + 0x80));\n        }\n    }\n\n    void skipViaRead()()\n    {\n        auto c = read();\n        if (c < 0xC0) return;\n        int n = tails(cast(char) c);\n        for (size_t i=0; i<n; ++i)\n        {\n            read();\n        }\n    }\n\n    dchar decodeViaRead()()\n    {\n        dchar c = read();\n        if (c < 0xC0) return c;\n        int n = tails(cast(char) c);\n        c &= (1 << (6 - n)) - 1;\n        for (size_t i=0; i<n; ++i)\n        {\n            c = (c << 6) + (read() & 0x3F);\n        }\n        return c;\n    }\n\n    dchar safeDecodeViaRead()()\n    {\n        dchar c = read();\n        if (c < 0x80) return c;\n        int n = tails(cast(char) c);\n        if (n == 0) return INVALID_SEQUENCE;\n\n        if (!canRead) return INVALID_SEQUENCE;\n        size_t d = peek();\n        immutable err =\n        (\n            (c < 0xC2)                              // fail overlong 2-byte sequences\n        ||  (c > 0xF4)                              // fail overlong 4-6-byte sequences\n        ||  (c == 0xE0 && ((d & 0xE0) == 0x80))     // fail overlong 3-byte sequences\n        ||  (c == 0xED && ((d & 0xE0) == 0xA0))     // fail surrogates\n        ||  (c == 0xF0 && ((d & 0xF0) == 0x80))     // fail overlong 4-byte sequences\n        ||  (c == 0xF4 && ((d & 0xF0) >= 0x90))     // fail code points > 0x10FFFF\n        );\n\n        c &= (1 << (6 - n)) - 1;\n        for (size_t i=0; i<n; ++i)\n        {\n            if (!canRead) return INVALID_SEQUENCE;\n            d = peek();\n            if ((d & 0xC0) != 0x80) return INVALID_SEQUENCE;\n            c = (c << 6) + (read() & 0x3F);\n        }\n\n        return err ? INVALID_SEQUENCE : c;\n    }\n\n    dchar decodeReverseViaRead()()\n    {\n        dchar c = read();\n        if (c < 0x80) return c;\n        size_t shift = 0;\n        c &= 0x3F;\n        for (size_t i=0; i<4; ++i)\n        {\n            shift += 6;\n            auto d = read();\n            size_t n = tails(cast(char) d);\n            immutable mask = n == 0 ? 0x3F : (1 << (6 - n)) - 1;\n            c += ((d & mask) << shift);\n            if (n != 0) break;\n        }\n        return c;\n    }\n\n    @property EString replacementSequence() @safe pure nothrow @nogc\n    {\n        return \"\\uFFFD\";\n    }\n\n    mixin EncoderFunctions;\n}\n\n//=============================================================================\n//          UTF-16\n//=============================================================================\n\ntemplate EncoderInstance(CharType : wchar)\n{\n    alias E = wchar;\n    alias EString = immutable(wchar)[];\n\n    @property string encodingName() @safe pure nothrow @nogc\n    {\n        return \"UTF-16\";\n    }\n\n    bool canEncode(dchar c) @safe pure nothrow @nogc\n    {\n        return isValidCodePoint(c);\n    }\n\n    bool isValidCodeUnit(wchar c) @safe pure nothrow @nogc\n    {\n        return true;\n    }\n\n    size_t encodedLength(dchar c) @safe pure nothrow @nogc\n    in\n    {\n        assert(canEncode(c));\n    }\n    do\n    {\n        return (c < 0x10000) ? 1 : 2;\n    }\n\n    void encodeViaWrite()(dchar c)\n    {\n        if (c < 0x10000)\n        {\n            write(cast(wchar) c);\n        }\n        else\n        {\n            size_t n = c - 0x10000;\n            write(cast(wchar)(0xD800 + (n >> 10)));\n            write(cast(wchar)(0xDC00 + (n & 0x3FF)));\n        }\n    }\n\n    void skipViaRead()()\n    {\n        immutable c = read();\n        if (c < 0xD800 || c >= 0xE000) return;\n        read();\n    }\n\n    dchar decodeViaRead()()\n    {\n        wchar c = read();\n        if (c < 0xD800 || c >= 0xE000) return cast(dchar) c;\n        wchar d = read();\n        c &= 0x3FF;\n        d &= 0x3FF;\n        return 0x10000 + (c << 10) + d;\n    }\n\n    dchar safeDecodeViaRead()()\n    {\n        wchar c = read();\n        if (c < 0xD800 || c >= 0xE000) return cast(dchar) c;\n        if (c >= 0xDC00) return INVALID_SEQUENCE;\n        if (!canRead) return INVALID_SEQUENCE;\n        wchar d = peek();\n        if (d < 0xDC00 || d >= 0xE000) return INVALID_SEQUENCE;\n        d = read();\n        c &= 0x3FF;\n        d &= 0x3FF;\n        return 0x10000 + (c << 10) + d;\n    }\n\n    dchar decodeReverseViaRead()()\n    {\n        wchar c = read();\n        if (c < 0xD800 || c >= 0xE000) return cast(dchar) c;\n        wchar d = read();\n        c &= 0x3FF;\n        d &= 0x3FF;\n        return 0x10000 + (d << 10) + c;\n    }\n\n    @property EString replacementSequence() @safe pure nothrow @nogc\n    {\n        return \"\\uFFFD\"w;\n    }\n\n    mixin EncoderFunctions;\n}\n\n//=============================================================================\n//          UTF-32\n//=============================================================================\n\ntemplate EncoderInstance(CharType : dchar)\n{\n    alias E = dchar;\n    alias EString = immutable(dchar)[];\n\n    @property string encodingName() @safe pure nothrow @nogc\n    {\n        return \"UTF-32\";\n    }\n\n    bool canEncode(dchar c) @safe pure @nogc nothrow\n    {\n        return isValidCodePoint(c);\n    }\n\n    bool isValidCodeUnit(dchar c) @safe pure @nogc nothrow\n    {\n        return isValidCodePoint(c);\n    }\n\n    size_t encodedLength(dchar c) @safe pure @nogc nothrow\n    in\n    {\n        assert(canEncode(c));\n    }\n    do\n    {\n        return 1;\n    }\n\n    void encodeViaWrite()(dchar c)\n    {\n        write(c);\n    }\n\n    void skipViaRead()()\n    {\n        read();\n    }\n\n    dchar decodeViaRead()()\n    {\n        return cast(dchar) read();\n    }\n\n    dchar safeDecodeViaRead()()\n    {\n        immutable c = read();\n        return isValidCodePoint(c) ? c : INVALID_SEQUENCE;\n    }\n\n    dchar decodeReverseViaRead()()\n    {\n        return cast(dchar) read();\n    }\n\n    @property EString replacementSequence() @safe pure nothrow @nogc\n    {\n        return \"\\uFFFD\"d;\n    }\n\n    mixin EncoderFunctions;\n}\n\n//=============================================================================\n// Below are forwarding functions which expose the function to the user\n\n/**\nReturns true if c is a valid code point\n\n Note that this includes the non-character code points U+FFFE and U+FFFF,\n since these are valid code points (even though they are not valid\n characters).\n\n Supersedes:\n This function supersedes `std.utf.startsValidDchar()`.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    c = the code point to be tested\n */\nbool isValidCodePoint(dchar c) @safe pure nothrow @nogc\n{\n    return c < 0xD800 || (c >= 0xE000 && c < 0x110000);\n}\n\n/**\n Returns the name of an encoding.\n\n The type of encoding cannot be deduced. Therefore, it is necessary to\n explicitly specify the encoding type.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n */\n@property string encodingName(T)()\n{\n    return EncoderInstance!(T).encodingName;\n}\n\n///\n@safe unittest\n{\n    assert(encodingName!(char) == \"UTF-8\");\n    assert(encodingName!(wchar) == \"UTF-16\");\n    assert(encodingName!(dchar) == \"UTF-32\");\n    assert(encodingName!(AsciiChar) == \"ASCII\");\n    assert(encodingName!(Latin1Char) == \"ISO-8859-1\");\n    assert(encodingName!(Latin2Char) == \"ISO-8859-2\");\n    assert(encodingName!(Windows1250Char) == \"windows-1250\");\n    assert(encodingName!(Windows1251Char) == \"windows-1251\");\n    assert(encodingName!(Windows1252Char) == \"windows-1252\");\n}\n\n/**\n Returns true iff it is possible to represent the specified codepoint\n in the encoding.\n\n The type of encoding cannot be deduced. Therefore, it is necessary to\n explicitly specify the encoding type.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n */\nbool canEncode(E)(dchar c)\n{\n    return EncoderInstance!(E).canEncode(c);\n}\n\n///\n@safe pure unittest\n{\n    assert( canEncode!(Latin1Char)('A'));\n    assert( canEncode!(Latin2Char)('A'));\n    assert(!canEncode!(AsciiChar)('\\u00A0'));\n    assert( canEncode!(Latin1Char)('\\u00A0'));\n    assert( canEncode!(Latin2Char)('\\u00A0'));\n    assert( canEncode!(Windows1250Char)('\\u20AC'));\n    assert(!canEncode!(Windows1250Char)('\\u20AD'));\n    assert(!canEncode!(Windows1250Char)('\\uFFFD'));\n    assert( canEncode!(Windows1251Char)('\\u0402'));\n    assert(!canEncode!(Windows1251Char)('\\u20AD'));\n    assert(!canEncode!(Windows1251Char)('\\uFFFD'));\n    assert( canEncode!(Windows1252Char)('\\u20AC'));\n    assert(!canEncode!(Windows1252Char)('\\u20AD'));\n    assert(!canEncode!(Windows1252Char)('\\uFFFD'));\n    assert(!canEncode!(char)(cast(dchar) 0x110000));\n}\n\n/// How to check an entire string\n@safe pure unittest\n{\n    import std.algorithm.searching : find;\n    import std.utf : byDchar;\n\n    assert(\"The quick brown fox\"\n        .byDchar\n        .find!(x => !canEncode!AsciiChar(x))\n        .empty);\n}\n\n/**\n Returns true if the code unit is legal. For example, the byte 0x80 would\n not be legal in ASCII, because ASCII code units must always be in the range\n 0x00 to 0x7F.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    c = the code unit to be tested\n */\nbool isValidCodeUnit(E)(E c)\n{\n    return EncoderInstance!(E).isValidCodeUnit(c);\n}\n\n///\n@system pure unittest\n{\n    assert(!isValidCodeUnit(cast(char) 0xC0));\n    assert(!isValidCodeUnit(cast(char) 0xFF));\n    assert( isValidCodeUnit(cast(wchar) 0xD800));\n    assert(!isValidCodeUnit(cast(dchar) 0xD800));\n    assert(!isValidCodeUnit(cast(AsciiChar) 0xA0));\n    assert( isValidCodeUnit(cast(Windows1250Char) 0x80));\n    assert(!isValidCodeUnit(cast(Windows1250Char) 0x81));\n    assert( isValidCodeUnit(cast(Windows1251Char) 0x80));\n    assert(!isValidCodeUnit(cast(Windows1251Char) 0x98));\n    assert( isValidCodeUnit(cast(Windows1252Char) 0x80));\n    assert(!isValidCodeUnit(cast(Windows1252Char) 0x81));\n}\n\n/**\n Returns true if the string is encoded correctly\n\n Supersedes:\n This function supersedes std.utf.validate(), however note that this\n function returns a bool indicating whether the input was valid or not,\n whereas the older function would throw an exception.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    s = the string to be tested\n */\nbool isValid(E)(const(E)[] s)\n{\n    return s.length == validLength(s);\n}\n\n///\n@system pure unittest\n{\n    assert( isValid(\"\\u20AC100\"));\n    assert(!isValid(cast(char[3])[167, 133, 175]));\n}\n\n/**\n Returns the length of the longest possible substring, starting from\n the first code unit, which is validly encoded.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    s = the string to be tested\n */\nsize_t validLength(E)(const(E)[] s)\n{\n    size_t result, before = void;\n    while ((before = s.length) > 0)\n    {\n        if (EncoderInstance!(E).safeDecode(s) == INVALID_SEQUENCE)\n            break;\n        result += before - s.length;\n    }\n    return result;\n}\n\n/**\n Sanitizes a string by replacing malformed code unit sequences with valid\n code unit sequences. The result is guaranteed to be valid for this encoding.\n\n If the input string is already valid, this function returns the original,\n otherwise it constructs a new string by replacing all illegal code unit\n sequences with the encoding's replacement character, Invalid sequences will\n be replaced with the Unicode replacement character (U+FFFD) if the\n character repertoire contains it, otherwise invalid sequences will be\n replaced with '?'.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    s = the string to be sanitized\n */\nimmutable(E)[] sanitize(E)(immutable(E)[] s)\n{\n    size_t n = validLength(s);\n    if (n == s.length) return s;\n\n    auto repSeq = EncoderInstance!(E).replacementSequence;\n\n    // Count how long the string needs to be.\n    // Overestimating is not a problem\n    size_t len = s.length;\n    const(E)[] t = s[n..$];\n    while (t.length != 0)\n    {\n        immutable c = EncoderInstance!(E).safeDecode(t);\n        assert(c == INVALID_SEQUENCE);\n        len += repSeq.length;\n        t = t[validLength(t)..$];\n    }\n\n    // Now do the write\n    E[] array = new E[len];\n    array[0 .. n] = s[0 .. n];\n    size_t offset = n;\n\n    t = s[n..$];\n    while (t.length != 0)\n    {\n        immutable c = EncoderInstance!(E).safeDecode(t);\n        assert(c == INVALID_SEQUENCE);\n        array[offset .. offset+repSeq.length] = repSeq[];\n        offset += repSeq.length;\n        n = validLength(t);\n        array[offset .. offset+n] = t[0 .. n];\n        offset += n;\n        t = t[n..$];\n    }\n    return cast(immutable(E)[])array[0 .. offset];\n}\n\n///\n@system pure unittest\n{\n    assert(sanitize(\"hello \\xF0\\x80world\") == \"hello \\xEF\\xBF\\xBDworld\");\n}\n\n/**\n Returns the length of the first encoded sequence.\n\n The input to this function MUST be validly encoded.\n This is enforced by the function's in-contract.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n s = the string to be sliced\n */\nsize_t firstSequence(E)(const(E)[] s)\nin\n{\n    assert(s.length != 0);\n    const(E)[] u = s;\n    assert(safeDecode(u) != INVALID_SEQUENCE);\n}\ndo\n{\n    auto before = s.length;\n    EncoderInstance!(E).skip(s);\n    return before - s.length;\n}\n\n///\n@system pure unittest\n{\n    assert(firstSequence(\"\\u20AC1000\") == \"\\u20AC\".length);\n    assert(firstSequence(\"hel\") == \"h\".length);\n}\n\n/**\n Returns the length of the last encoded sequence.\n\n The input to this function MUST be validly encoded.\n This is enforced by the function's in-contract.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    s = the string to be sliced\n */\nsize_t lastSequence(E)(const(E)[] s)\nin\n{\n    assert(s.length != 0);\n    assert(isValid(s));\n}\ndo\n{\n    const(E)[] t = s;\n    EncoderInstance!(E).decodeReverse(s);\n    return t.length - s.length;\n}\n\n///\n@system pure unittest\n{\n    assert(lastSequence(\"1000\\u20AC\") == \"\\u20AC\".length);\n    assert(lastSequence(\"hellö\") == \"ö\".length);\n}\n\n/**\n Returns the array index at which the (n+1)th code point begins.\n\n The input to this function MUST be validly encoded.\n This is enforced by the function's in-contract.\n\n Supersedes:\n This function supersedes std.utf.toUTFindex().\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    s = the string to be counted\n    n = the current code point index\n */\nptrdiff_t index(E)(const(E)[] s,int n)\nin\n{\n    assert(isValid(s));\n    assert(n >= 0);\n}\ndo\n{\n    const(E)[] t = s;\n    for (size_t i=0; i<n; ++i) EncoderInstance!(E).skip(s);\n    return t.length - s.length;\n}\n\n///\n@system pure unittest\n{\n    assert(index(\"\\u20AC100\",1) == 3);\n    assert(index(\"hällo\",2) == 3);\n}\n\n/**\n Decodes a single code point.\n\n This function removes one or more code units from the start of a string,\n and returns the decoded code point which those code units represent.\n\n The input to this function MUST be validly encoded.\n This is enforced by the function's in-contract.\n\n Supersedes:\n This function supersedes std.utf.decode(), however, note that the\n function codePoints() supersedes it more conveniently.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    s = the string whose first code point is to be decoded\n */\ndchar decode(S)(ref S s)\nin\n{\n    assert(s.length != 0);\n    auto u = s;\n    assert(safeDecode(u) != INVALID_SEQUENCE);\n}\ndo\n{\n    return EncoderInstance!(typeof(s[0])).decode(s);\n}\n\n/**\n Decodes a single code point from the end of a string.\n\n This function removes one or more code units from the end of a string,\n and returns the decoded code point which those code units represent.\n\n The input to this function MUST be validly encoded.\n This is enforced by the function's in-contract.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    s = the string whose first code point is to be decoded\n */\ndchar decodeReverse(E)(ref const(E)[] s)\nin\n{\n    assert(s.length != 0);\n    assert(isValid(s));\n}\ndo\n{\n    return EncoderInstance!(E).decodeReverse(s);\n}\n\n/**\n Decodes a single code point. The input does not have to be valid.\n\n This function removes one or more code units from the start of a string,\n and returns the decoded code point which those code units represent.\n\n This function will accept an invalidly encoded string as input.\n If an invalid sequence is found at the start of the string, this\n function will remove it, and return the value INVALID_SEQUENCE.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    s = the string whose first code point is to be decoded\n */\ndchar safeDecode(S)(ref S s)\nin\n{\n    assert(s.length != 0);\n}\ndo\n{\n    return EncoderInstance!(typeof(s[0])).safeDecode(s);\n}\n\n/**\n Returns the number of code units required to encode a single code point.\n\n The input to this function MUST be a valid code point.\n This is enforced by the function's in-contract.\n\n The type of the output cannot be deduced. Therefore, it is necessary to\n explicitly specify the encoding as a template parameter.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    c = the code point to be encoded\n */\nsize_t encodedLength(E)(dchar c)\nin\n{\n    assert(isValidCodePoint(c));\n}\ndo\n{\n    return EncoderInstance!(E).encodedLength(c);\n}\n\n/**\n Encodes a single code point.\n\n This function encodes a single code point into one or more code units.\n It returns a string containing those code units.\n\n The input to this function MUST be a valid code point.\n This is enforced by the function's in-contract.\n\n The type of the output cannot be deduced. Therefore, it is necessary to\n explicitly specify the encoding as a template parameter.\n\n Supersedes:\n This function supersedes std.utf.encode(), however, note that the\n function codeUnits() supersedes it more conveniently.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    c = the code point to be encoded\n */\nE[] encode(E)(dchar c)\nin\n{\n    assert(isValidCodePoint(c));\n}\ndo\n{\n    return EncoderInstance!(E).encode(c);\n}\n\n/**\n Encodes a single code point into an array.\n\n This function encodes a single code point into one or more code units\n The code units are stored in a user-supplied fixed-size array,\n which must be passed by reference.\n\n The input to this function MUST be a valid code point.\n This is enforced by the function's in-contract.\n\n The type of the output cannot be deduced. Therefore, it is necessary to\n explicitly specify the encoding as a template parameter.\n\n Supersedes:\n This function supersedes std.utf.encode(), however, note that the\n function codeUnits() supersedes it more conveniently.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    c     = the code point to be encoded\n    array = the destination array\n\n Returns:\n          the number of code units written to the array\n */\nsize_t encode(E)(dchar c, E[] array)\nin\n{\n    assert(isValidCodePoint(c));\n}\ndo\n{\n    E[] t = array;\n    EncoderInstance!(E).encode(c,t);\n    return array.length - t.length;\n}\n\n/*\nEncodes `c` in units of type `E` and writes the result to the\noutput range `R`. Returns the number of `E`s written.\n */\nsize_t encode(E, R)(dchar c, auto ref R range)\nif (isNativeOutputRange!(R, E))\n{\n    static if (is(Unqual!E == char))\n    {\n        if (c <= 0x7F)\n        {\n            put(range, cast(char) c);\n            return 1;\n        }\n        if (c <= 0x7FF)\n        {\n            put(range, cast(char)(0xC0 | (c >> 6)));\n            put(range, cast(char)(0x80 | (c & 0x3F)));\n            return 2;\n        }\n        if (c <= 0xFFFF)\n        {\n            put(range, cast(char)(0xE0 | (c >> 12)));\n            put(range, cast(char)(0x80 | ((c >> 6) & 0x3F)));\n            put(range, cast(char)(0x80 | (c & 0x3F)));\n            return 3;\n        }\n        if (c <= 0x10FFFF)\n        {\n            put(range, cast(char)(0xF0 | (c >> 18)));\n            put(range, cast(char)(0x80 | ((c >> 12) & 0x3F)));\n            put(range, cast(char)(0x80 | ((c >> 6) & 0x3F)));\n            put(range, cast(char)(0x80 | (c & 0x3F)));\n            return 4;\n        }\n        else\n        {\n            assert(0);\n        }\n    }\n    else static if (is(Unqual!E == wchar))\n    {\n        if (c <= 0xFFFF)\n        {\n            range.put(cast(wchar) c);\n            return 1;\n        }\n        range.put(cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800));\n        range.put(cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00));\n        return 2;\n    }\n    else static if (is(Unqual!E == dchar))\n    {\n        range.put(c);\n        return 1;\n    }\n    else\n    {\n        static assert(0);\n    }\n}\n\n@safe pure unittest\n{\n    import std.array;\n    Appender!(char[]) r;\n    assert(encode!(char)('T', r) == 1);\n    assert(encode!(wchar)('T', r) == 1);\n    assert(encode!(dchar)('T', r) == 1);\n}\n\n/**\n Encodes a single code point to a delegate.\n\n This function encodes a single code point into one or more code units.\n The code units are passed one at a time to the supplied delegate.\n\n The input to this function MUST be a valid code point.\n This is enforced by the function's in-contract.\n\n The type of the output cannot be deduced. Therefore, it is necessary to\n explicitly specify the encoding as a template parameter.\n\n Supersedes:\n This function supersedes std.utf.encode(), however, note that the\n function codeUnits() supersedes it more conveniently.\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    c  = the code point to be encoded\n    dg = the delegate to invoke for each code unit\n */\nvoid encode(E)(dchar c, void delegate(E) dg)\nin\n{\n    assert(isValidCodePoint(c));\n}\ndo\n{\n    EncoderInstance!(E).encode(c,dg);\n}\n\n/**\nEncodes the contents of `s` in units of type `Tgt`, writing the result to an\noutput range.\n\nReturns: The number of `Tgt` elements written.\nParams:\nTgt = Element type of `range`.\ns = Input array.\nrange = Output range.\n */\nsize_t encode(Tgt, Src, R)(in Src[] s, R range)\n{\n    size_t result;\n    foreach (c; s)\n    {\n        result += encode!(Tgt)(c, range);\n    }\n    return result;\n}\n\n/**\n Returns a foreachable struct which can bidirectionally iterate over all\n code points in a string.\n\n The input to this function MUST be validly encoded.\n This is enforced by the function's in-contract.\n\n You can foreach either\n with or without an index. If an index is specified, it will be initialized\n at each iteration with the offset into the string at which the code point\n begins.\n\n Supersedes:\n This function supersedes std.utf.decode().\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    s = the string to be decoded\n\n Example:\n --------------------------------------------------------\n string s = \"hello world\";\n foreach (c;codePoints(s))\n {\n     // do something with c (which will always be a dchar)\n }\n --------------------------------------------------------\n\n Note that, currently, foreach (c:codePoints(s)) is superior to foreach (c;s)\n in that the latter will fall over on encountering U+FFFF.\n */\nCodePoints!(E) codePoints(E)(immutable(E)[] s)\nin\n{\n    assert(isValid(s));\n}\ndo\n{\n    return CodePoints!(E)(s);\n}\n\n///\n@system unittest\n{\n    string s = \"hello\";\n    string t;\n    foreach (c;codePoints(s))\n    {\n        t ~= cast(char) c;\n    }\n    assert(s == t);\n}\n\n/**\n Returns a foreachable struct which can bidirectionally iterate over all\n code units in a code point.\n\n The input to this function MUST be a valid code point.\n This is enforced by the function's in-contract.\n\n The type of the output cannot be deduced. Therefore, it is necessary to\n explicitly specify the encoding type in the template parameter.\n\n Supersedes:\n This function supersedes std.utf.encode().\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    c = the code point to be encoded\n */\nCodeUnits!(E) codeUnits(E)(dchar c)\nin\n{\n    assert(isValidCodePoint(c));\n}\ndo\n{\n    return CodeUnits!(E)(c);\n}\n\n///\n@system unittest\n{\n    char[] a;\n    foreach (c;codeUnits!(char)(cast(dchar)'\\u20AC'))\n    {\n        a ~= c;\n    }\n    assert(a.length == 3);\n    assert(a[0] == 0xE2);\n    assert(a[1] == 0x82);\n    assert(a[2] == 0xAC);\n}\n\n/**\n Convert a string from one encoding to another.\n\n Supersedes:\n This function supersedes std.utf.toUTF8(), std.utf.toUTF16() and\n std.utf.toUTF32()\n (but note that to!() supersedes it more conveniently).\n\n Standards: Unicode 5.0, ASCII, ISO-8859-1, ISO-8859-2, WINDOWS-1250,\n WINDOWS-1251, WINDOWS-1252\n\n Params:\n    s = Source string. $(B Must) be validly encoded.\n        This is enforced by the function's in-contract.\n    r = Destination string\n\n See_Also:\n    $(REF to, std,conv)\n */\nvoid transcode(Src, Dst)(Src[] s, out Dst[] r)\nin\n{\n    assert(isValid(s));\n}\ndo\n{\n    static if (is(Src == Dst) && is(Src == immutable))\n    {\n        r = s;\n    }\n    else static if (is(Unqual!Src == AsciiChar))\n    {\n        transcode(cast(const(char)[])s, r);\n    }\n    else\n    {\n        static if (is(Unqual!Dst == wchar))\n        {\n            immutable minReservePlace = 2;\n        }\n        else static if (is(Unqual!Dst == dchar))\n        {\n            immutable minReservePlace = 1;\n        }\n        else\n        {\n            immutable minReservePlace = 6;\n        }\n\n        auto buffer = new Unqual!Dst[s.length];\n        auto tmpBuffer = buffer;\n\n        while (s.length != 0)\n        {\n            if (tmpBuffer.length < minReservePlace)\n            {\n                size_t prevLength = buffer.length;\n                buffer.length += s.length + minReservePlace;\n                tmpBuffer = buffer[prevLength - tmpBuffer.length .. $];\n            }\n            EncoderInstance!(Unqual!Dst).encode(decode(s), tmpBuffer);\n        }\n\n        r = cast(Dst[]) buffer[0 .. buffer.length - tmpBuffer.length];\n    }\n}\n\n///\n@system pure unittest\n{\n    wstring ws;\n    // transcode from UTF-8 to UTF-16\n    transcode(\"hello world\",ws);\n    assert(ws == \"hello world\"w);\n\n    Latin1String ls;\n    // transcode from UTF-16 to ISO-8859-1\n    transcode(ws, ls);\n    assert(ws == \"hello world\");\n}\n\n@system pure unittest\n{\n    import std.meta;\n    import std.range;\n    {\n        import std.conv : to;\n\n        string asciiCharString = to!string(iota(0, 128, 1));\n\n        alias Types = AliasSeq!(string, Latin1String, Latin2String, AsciiString,\n            Windows1250String, Windows1251String, Windows1252String, dstring, wstring);\n        foreach (S; Types)\n            foreach (D; Types)\n            {\n                string str;\n                S sStr;\n                D dStr;\n                transcode(asciiCharString, sStr);\n                transcode(sStr, dStr);\n                transcode(dStr, str);\n                assert(asciiCharString == str);\n            }\n    }\n    {\n        string czechChars = \"Příliš žluťoučký kůň úpěl ďábelské ódy.\";\n        alias Types = AliasSeq!(string, dstring, wstring);\n        foreach (S; Types)\n            foreach (D; Types)\n            {\n                string str;\n                S sStr;\n                D dStr;\n                transcode(czechChars, sStr);\n                transcode(sStr, dStr);\n                transcode(dStr, str);\n                assert(czechChars == str);\n            }\n    }\n}\n\n@system unittest // mutable/const input/output\n{\n    import std.meta : AliasSeq;\n\n    static foreach (O; AliasSeq!(Latin1Char, const Latin1Char, immutable Latin1Char))\n    {{\n        O[] output;\n\n        char[] mutableInput = \"äbc\".dup;\n        transcode(mutableInput, output);\n        assert(output == [0xE4, 'b', 'c']);\n\n        const char[] constInput = \"öbc\";\n        transcode(constInput, output);\n        assert(output == [0xF6, 'b', 'c']);\n\n        immutable char[] immutInput = \"übc\";\n        transcode(immutInput, output);\n        assert(output == [0xFC, 'b', 'c']);\n    }}\n\n    // Make sure that const/mutable input is copied.\n    static foreach (C; AliasSeq!(char, const char))\n    {{\n        C[] input = \"foo\".dup;\n        C[] output;\n        transcode(input, output);\n        assert(input == output);\n        assert(input !is output);\n    }}\n\n    // But immutable input should not be copied.\n    string input = \"foo\";\n    string output;\n    transcode(input, output);\n    assert(input is output);\n}\n\n//=============================================================================\n\n/** The base class for exceptions thrown by this module */\nclass EncodingException : Exception { this(string msg) @safe pure { super(msg); } }\n\nclass UnrecognizedEncodingException : EncodingException\n{\n    private this(string msg) @safe pure { super(msg); }\n}\n\n/** Abstract base class of all encoding schemes */\nabstract class EncodingScheme\n{\n    import std.uni : toLower;\n\n    /**\n     * Registers a subclass of EncodingScheme.\n     *\n     * This function allows user-defined subclasses of EncodingScheme to\n     * be declared in other modules.\n     *\n     * Params:\n     *     Klass = The subclass of EncodingScheme to register.\n     *\n     * Example:\n     * ----------------------------------------------\n     * class Amiga1251 : EncodingScheme\n     * {\n     *     shared static this()\n     *     {\n     *         EncodingScheme.register!Amiga1251;\n     *     }\n     * }\n     * ----------------------------------------------\n     */\n    static void register(Klass:EncodingScheme)()\n    {\n        scope scheme = new Klass();\n        foreach (encodingName;scheme.names())\n        {\n            supported[toLower(encodingName)] = () => new Klass();\n        }\n    }\n\n    deprecated(\"Please pass the EncodingScheme subclass as template argument instead.\")\n    static void register(string className)\n    {\n        auto scheme = cast(EncodingScheme) ClassInfo.find(className).create();\n        if (scheme is null)\n            throw new EncodingException(\"Unable to create class \"~className);\n        foreach (encodingName;scheme.names())\n        {\n            supportedFactories[toLower(encodingName)] = className;\n        }\n    }\n\n    /**\n     * Obtains a subclass of EncodingScheme which is capable of encoding\n     * and decoding the named encoding scheme.\n     *\n     * This function is only aware of EncodingSchemes which have been\n     * registered with the register() function.\n     *\n     * Example:\n     * ---------------------------------------------------\n     * auto scheme = EncodingScheme.create(\"Amiga-1251\");\n     * ---------------------------------------------------\n     */\n    static EncodingScheme create(string encodingName)\n    {\n        static bool registerDefaultEncodings()\n        {\n            EncodingScheme.register!EncodingSchemeASCII;\n            EncodingScheme.register!EncodingSchemeLatin1;\n            EncodingScheme.register!EncodingSchemeLatin2;\n            EncodingScheme.register!EncodingSchemeWindows1250;\n            EncodingScheme.register!EncodingSchemeWindows1251;\n            EncodingScheme.register!EncodingSchemeWindows1252;\n            EncodingScheme.register!EncodingSchemeUtf8;\n            EncodingScheme.register!EncodingSchemeUtf16Native;\n            EncodingScheme.register!EncodingSchemeUtf32Native;\n            return true;\n        }\n\n        static shared bool initialized;\n        import std.concurrency : initOnce;\n        initOnce!initialized(registerDefaultEncodings());\n        encodingName = toLower(encodingName);\n\n        if (auto p = encodingName in supported)\n            return (*p)();\n\n        auto p = encodingName in supportedFactories;\n        if (p is null)\n            throw new EncodingException(\"Unrecognized Encoding: \"~encodingName);\n        string className = *p;\n        auto scheme = cast(EncodingScheme) ClassInfo.find(className).create();\n        if (scheme is null) throw new EncodingException(\"Unable to create class \"~className);\n        return scheme;\n    }\n\n    const\n    {\n        /**\n         * Returns the standard name of the encoding scheme\n         */\n        abstract override string toString();\n\n        /**\n         * Returns an array of all known names for this encoding scheme\n         */\n        abstract string[] names();\n\n        /**\n         * Returns true if the character c can be represented\n         * in this encoding scheme.\n         */\n        abstract bool canEncode(dchar c);\n\n        /**\n         * Returns the number of ubytes required to encode this code point.\n         *\n         * The input to this function MUST be a valid code point.\n         *\n         * Params:\n         *    c = the code point to be encoded\n         *\n         * Returns:\n         *    the number of ubytes required.\n         */\n        abstract size_t encodedLength(dchar c);\n\n        /**\n         * Encodes a single code point into a user-supplied, fixed-size buffer.\n         *\n         * This function encodes a single code point into one or more ubytes.\n         * The supplied buffer must be code unit aligned.\n         * (For example, UTF-16LE or UTF-16BE must be wchar-aligned,\n         * UTF-32LE or UTF-32BE must be dchar-aligned, etc.)\n         *\n         * The input to this function MUST be a valid code point.\n         *\n         * Params:\n         *    c      = the code point to be encoded\n         *    buffer = the destination array\n         *\n         * Returns:\n         *    the number of ubytes written.\n         */\n        abstract size_t encode(dchar c, ubyte[] buffer);\n\n        /**\n         * Decodes a single code point.\n         *\n         * This function removes one or more ubytes from the start of an array,\n         * and returns the decoded code point which those ubytes represent.\n         *\n         * The input to this function MUST be validly encoded.\n         *\n         * Params:\n         *    s = the array whose first code point is to be decoded\n         */\n        abstract dchar decode(ref const(ubyte)[] s);\n\n        /**\n         * Decodes a single code point. The input does not have to be valid.\n         *\n         * This function removes one or more ubytes from the start of an array,\n         * and returns the decoded code point which those ubytes represent.\n         *\n         * This function will accept an invalidly encoded array as input.\n         * If an invalid sequence is found at the start of the string, this\n         * function will remove it, and return the value INVALID_SEQUENCE.\n         *\n         * Params:\n         *    s = the array whose first code point is to be decoded\n         */\n        abstract dchar safeDecode(ref const(ubyte)[] s);\n\n        /**\n         * Returns the sequence of ubytes to be used to represent\n         * any character which cannot be represented in the encoding scheme.\n         *\n         * Normally this will be a representation of some substitution\n         * character, such as U+FFFD or '?'.\n         */\n        abstract @property immutable(ubyte)[] replacementSequence();\n    }\n\n    /**\n     * Returns true if the array is encoded correctly\n     *\n     * Params:\n     *    s = the array to be tested\n     */\n    bool isValid(const(ubyte)[] s)\n    {\n        while (s.length != 0)\n        {\n            if (safeDecode(s) == INVALID_SEQUENCE)\n                return false;\n        }\n        return true;\n    }\n\n    /**\n     * Returns the length of the longest possible substring, starting from\n     * the first element, which is validly encoded.\n     *\n     * Params:\n     *    s = the array to be tested\n     */\n    size_t validLength()(const(ubyte)[] s)\n    {\n        const(ubyte)[] r = s;\n        const(ubyte)[] t = s;\n        while (s.length != 0)\n        {\n            if (safeDecode(s) == INVALID_SEQUENCE) break;\n            t = s;\n        }\n        return r.length - t.length;\n    }\n\n    /**\n     * Sanitizes an array by replacing malformed ubyte sequences with valid\n     * ubyte sequences. The result is guaranteed to be valid for this\n     * encoding scheme.\n     *\n     * If the input array is already valid, this function returns the\n     * original, otherwise it constructs a new array by replacing all illegal\n     * sequences with the encoding scheme's replacement sequence.\n     *\n     * Params:\n     *    s = the string to be sanitized\n     */\n    immutable(ubyte)[] sanitize()(immutable(ubyte)[] s)\n    {\n        auto n = validLength(s);\n        if (n == s.length) return s;\n\n        auto repSeq = replacementSequence;\n\n        // Count how long the string needs to be.\n        // Overestimating is not a problem\n        auto len = s.length;\n        const(ubyte)[] t = s[n..$];\n        while (t.length != 0)\n        {\n            immutable c = safeDecode(t);\n            assert(c == INVALID_SEQUENCE);\n            len += repSeq.length;\n            t = t[validLength(t)..$];\n        }\n\n        // Now do the write\n        ubyte[] array = new ubyte[len];\n        array[0 .. n] = s[0 .. n];\n        auto offset = n;\n\n        t = s[n..$];\n        while (t.length != 0)\n        {\n            immutable c = safeDecode(t);\n            assert(c == INVALID_SEQUENCE);\n            array[offset .. offset+repSeq.length] = repSeq[];\n            offset += repSeq.length;\n            n = validLength(t);\n            array[offset .. offset+n] = t[0 .. n];\n            offset += n;\n            t = t[n..$];\n        }\n        return cast(immutable(ubyte)[])array[0 .. offset];\n    }\n\n    /**\n     * Returns the length of the first encoded sequence.\n     *\n     * The input to this function MUST be validly encoded.\n     * This is enforced by the function's in-contract.\n     *\n     * Params:\n     *    s = the array to be sliced\n     */\n    size_t firstSequence()(const(ubyte)[] s)\n    in\n    {\n        assert(s.length != 0);\n        const(ubyte)[] u = s;\n        assert(safeDecode(u) != INVALID_SEQUENCE);\n    }\n    do\n    {\n        const(ubyte)[] t = s;\n        decode(s);\n        return t.length - s.length;\n    }\n\n    /**\n     * Returns the total number of code points encoded in a ubyte array.\n     *\n     * The input to this function MUST be validly encoded.\n     * This is enforced by the function's in-contract.\n     *\n     * Params:\n     *    s = the string to be counted\n     */\n    size_t count()(const(ubyte)[] s)\n    in\n    {\n        assert(isValid(s));\n    }\n    do\n    {\n        size_t n = 0;\n        while (s.length != 0)\n        {\n            decode(s);\n            ++n;\n        }\n        return n;\n    }\n\n    /**\n     * Returns the array index at which the (n+1)th code point begins.\n     *\n     * The input to this function MUST be validly encoded.\n     * This is enforced by the function's in-contract.\n     *\n     * Params:\n     *    s = the string to be counted\n     *    n = the current code point index\n     */\n    ptrdiff_t index()(const(ubyte)[] s, size_t n)\n    in\n    {\n        assert(isValid(s));\n        assert(n >= 0);\n    }\n    do\n    {\n        const(ubyte)[] t = s;\n        for (size_t i=0; i<n; ++i) decode(s);\n        return t.length - s.length;\n    }\n\n    __gshared EncodingScheme function()[string] supported;\n    __gshared string[string] supportedFactories;\n}\n\n/**\n EncodingScheme to handle ASCII\n\n This scheme recognises the following names:\n                 \"ANSI_X3.4-1968\",\n                 \"ANSI_X3.4-1986\",\n                 \"ASCII\",\n                 \"IBM367\",\n                 \"ISO646-US\",\n                 \"ISO_646.irv:1991\",\n                 \"US-ASCII\",\n                 \"cp367\",\n                 \"csASCII\"\n                 \"iso-ir-6\",\n                 \"us\"\n */\nclass EncodingSchemeASCII : EncodingScheme\n{\n    /* // moved to std.internal.phobosinit\n    shared static this()\n    {\n        EncodingScheme.register(\"std.encoding.EncodingSchemeASCII\");\n    }*/\n\n    const\n    {\n        override string[] names() @safe pure nothrow\n        {\n            return\n            [\n                \"ANSI_X3.4-1968\",\n                \"ANSI_X3.4-1986\",\n                \"ASCII\",\n                \"IBM367\",\n                \"ISO646-US\",\n                \"ISO_646.irv:1991\",\n                \"US-ASCII\",\n                \"cp367\",\n                \"csASCII\",\n                \"iso-ir-6\",\n                \"us\"\n            ];\n        }\n\n        override string toString() @safe pure nothrow @nogc\n        {\n            return \"ASCII\";\n        }\n\n        override bool canEncode(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.canEncode!(AsciiChar)(c);\n        }\n\n        override size_t encodedLength(dchar c)  @safe pure nothrow @nogc\n        {\n            return std.encoding.encodedLength!(AsciiChar)(c);\n        }\n\n        override size_t encode(dchar c, ubyte[] buffer) @safe pure nothrow @nogc\n        {\n            auto r = cast(AsciiChar[]) buffer;\n            return std.encoding.encode(c,r);\n        }\n\n        override dchar decode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(AsciiChar)[]) s;\n            dchar c = std.encoding.decode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override dchar safeDecode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(AsciiChar)[]) s;\n            dchar c = std.encoding.safeDecode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override @property immutable(ubyte)[] replacementSequence() @safe pure nothrow @nogc\n        {\n            return cast(immutable(ubyte)[])\"?\";\n        }\n    }\n}\n\n/**\n EncodingScheme to handle Latin-1\n\n This scheme recognises the following names:\n                 \"CP819\",\n                 \"IBM819\",\n                 \"ISO-8859-1\",\n                 \"ISO_8859-1\",\n                 \"ISO_8859-1:1987\",\n                 \"csISOLatin1\",\n                 \"iso-ir-100\",\n                 \"l1\",\n                 \"latin1\"\n */\nclass EncodingSchemeLatin1 : EncodingScheme\n{\n    /* // moved to std.internal.phobosinit\n    shared static this()\n    {\n        EncodingScheme.register(\"std.encoding.EncodingSchemeLatin1\");\n    }*/\n\n    const\n    {\n        override string[] names() @safe pure nothrow\n        {\n            return\n            [\n                \"CP819\",\n                \"IBM819\",\n                \"ISO-8859-1\",\n                \"ISO_8859-1\",\n                \"ISO_8859-1:1987\",\n                \"csISOLatin1\",\n                \"iso-ir-100\",\n                \"l1\",\n                \"latin1\"\n            ];\n        }\n\n        override string toString() @safe pure nothrow @nogc\n        {\n            return \"ISO-8859-1\";\n        }\n\n        override bool canEncode(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.canEncode!(Latin1Char)(c);\n        }\n\n        override size_t encodedLength(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.encodedLength!(Latin1Char)(c);\n        }\n\n        override size_t encode(dchar c, ubyte[] buffer) @safe pure nothrow @nogc\n        {\n            auto r = cast(Latin1Char[]) buffer;\n            return std.encoding.encode(c,r);\n        }\n\n        override dchar decode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(Latin1Char)[]) s;\n            dchar c = std.encoding.decode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override dchar safeDecode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(Latin1Char)[]) s;\n            dchar c = std.encoding.safeDecode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override @property immutable(ubyte)[] replacementSequence() @safe pure nothrow @nogc\n        {\n            return cast(immutable(ubyte)[])\"?\";\n        }\n    }\n}\n\n/**\n EncodingScheme to handle Latin-2\n\n This scheme recognises the following names:\n                 \"Latin 2\",\n                 \"ISO-8859-2\",\n                 \"ISO_8859-2\",\n                 \"ISO_8859-2:1999\",\n                 \"Windows-28592\"\n */\nclass EncodingSchemeLatin2 : EncodingScheme\n{\n    /* // moved to std.internal.phobosinit\n    shared static this()\n    {\n        EncodingScheme.register(\"std.encoding.EncodingSchemeLatin2\");\n    }*/\n\n    const\n    {\n        override string[] names() @safe pure nothrow\n        {\n            return\n            [\n                \"Latin 2\",\n                \"ISO-8859-2\",\n                \"ISO_8859-2\",\n                \"ISO_8859-2:1999\",\n                \"windows-28592\"\n            ];\n        }\n\n        override string toString() @safe pure nothrow @nogc\n        {\n            return \"ISO-8859-2\";\n        }\n\n        override bool canEncode(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.canEncode!(Latin2Char)(c);\n        }\n\n        override size_t encodedLength(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.encodedLength!(Latin2Char)(c);\n        }\n\n        override size_t encode(dchar c, ubyte[] buffer) @safe pure nothrow @nogc\n        {\n            auto r = cast(Latin2Char[]) buffer;\n            return std.encoding.encode(c,r);\n        }\n\n        override dchar decode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(Latin2Char)[]) s;\n            dchar c = std.encoding.decode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override dchar safeDecode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(Latin2Char)[]) s;\n            dchar c = std.encoding.safeDecode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override @property immutable(ubyte)[] replacementSequence() @safe pure nothrow @nogc\n        {\n            return cast(immutable(ubyte)[])\"?\";\n        }\n    }\n}\n\n/**\n EncodingScheme to handle Windows-1250\n\n This scheme recognises the following names:\n                 \"windows-1250\"\n */\nclass EncodingSchemeWindows1250 : EncodingScheme\n{\n    /* // moved to std.internal.phobosinit\n    shared static this()\n    {\n        EncodingScheme.register(\"std.encoding.EncodingSchemeWindows1250\");\n    }*/\n\n    const\n    {\n        override string[] names() @safe pure nothrow\n        {\n            return\n            [\n                \"windows-1250\"\n            ];\n        }\n\n        override string toString() @safe pure nothrow @nogc\n        {\n            return \"windows-1250\";\n        }\n\n        override bool canEncode(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.canEncode!(Windows1250Char)(c);\n        }\n\n        override size_t encodedLength(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.encodedLength!(Windows1250Char)(c);\n        }\n\n        override size_t encode(dchar c, ubyte[] buffer) @safe pure nothrow @nogc\n        {\n            auto r = cast(Windows1250Char[]) buffer;\n            return std.encoding.encode(c,r);\n        }\n\n        override dchar decode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(Windows1250Char)[]) s;\n            dchar c = std.encoding.decode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override dchar safeDecode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(Windows1250Char)[]) s;\n            dchar c = std.encoding.safeDecode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override @property immutable(ubyte)[] replacementSequence() @safe pure nothrow @nogc\n        {\n            return cast(immutable(ubyte)[])\"?\";\n        }\n    }\n}\n\n/**\n EncodingScheme to handle Windows-1251\n\n This scheme recognises the following names:\n                 \"windows-1251\"\n */\nclass EncodingSchemeWindows1251 : EncodingScheme\n{\n    /* // moved to std.internal.phobosinit\n    shared static this()\n    {\n        EncodingScheme.register(\"std.encoding.EncodingSchemeWindows1251\");\n    }*/\n\n    const\n    {\n        override string[] names() @safe pure nothrow\n        {\n            return\n            [\n                \"windows-1251\"\n            ];\n        }\n\n        override string toString() @safe pure nothrow @nogc\n        {\n            return \"windows-1251\";\n        }\n\n        override bool canEncode(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.canEncode!(Windows1251Char)(c);\n        }\n\n        override size_t encodedLength(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.encodedLength!(Windows1251Char)(c);\n        }\n\n        override size_t encode(dchar c, ubyte[] buffer) @safe pure nothrow @nogc\n        {\n            auto r = cast(Windows1251Char[]) buffer;\n            return std.encoding.encode(c,r);\n        }\n\n        override dchar decode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(Windows1251Char)[]) s;\n            dchar c = std.encoding.decode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override dchar safeDecode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(Windows1251Char)[]) s;\n            dchar c = std.encoding.safeDecode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override @property immutable(ubyte)[] replacementSequence() @safe pure nothrow @nogc\n        {\n            return cast(immutable(ubyte)[])\"?\";\n        }\n    }\n}\n\n/**\n EncodingScheme to handle Windows-1252\n\n This scheme recognises the following names:\n                 \"windows-1252\"\n */\nclass EncodingSchemeWindows1252 : EncodingScheme\n{\n    /* // moved to std.internal.phobosinit\n    shared static this()\n    {\n        EncodingScheme.register(\"std.encoding.EncodingSchemeWindows1252\");\n    }*/\n\n    const\n    {\n        override string[] names() @safe pure nothrow\n        {\n            return\n            [\n                \"windows-1252\"\n            ];\n        }\n\n        override string toString() @safe pure nothrow @nogc\n        {\n            return \"windows-1252\";\n        }\n\n        override bool canEncode(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.canEncode!(Windows1252Char)(c);\n        }\n\n        override size_t encodedLength(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.encodedLength!(Windows1252Char)(c);\n        }\n\n        override size_t encode(dchar c, ubyte[] buffer) @safe pure nothrow @nogc\n        {\n            auto r = cast(Windows1252Char[]) buffer;\n            return std.encoding.encode(c,r);\n        }\n\n        override dchar decode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(Windows1252Char)[]) s;\n            dchar c = std.encoding.decode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override dchar safeDecode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(Windows1252Char)[]) s;\n            dchar c = std.encoding.safeDecode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override @property immutable(ubyte)[] replacementSequence() @safe pure nothrow @nogc\n        {\n            return cast(immutable(ubyte)[])\"?\";\n        }\n    }\n}\n\n@system unittest\n{\n    static string[] schemeNames =\n    [\n        \"ASCII\",\n        \"ISO-8859-1\",\n        \"ISO-8859-2\",\n        \"windows-1250\",\n        \"windows-1251\",\n        \"windows-1252\"\n    ];\n\n    EncodingScheme[] schemes;\n\n    foreach (name;schemeNames)\n    {\n       schemes ~= EncodingScheme.create(name);\n    }\n\n    ubyte[1] buffer;\n    static dchar[][] valid =\n    [\n        //Valid ASCII\n        ['\\u0001','\\u0020','\\u0040','\\u0060','\\u007F'],\n        //Vaild 8859-1\n        ['\\u0001','\\u0020','\\u0070','\\u00DA','\\u00FF'],\n        //Valid 8859-2\n        ['\\u0020','\\u00D7','\\u00DF','\\u010F','\\u02D9'],\n        //Valid 1250\n        ['\\u0020','\\u20AC','\\u201E','\\u2021','\\u2039'],\n        //Valid 1251\n        ['\\u0402','\\u00A4','\\u0415','\\u0439','\\u044F'],\n        //Valid 1252\n        ['\\u20AC','\\u0160','\\u2019','\\u2122','\\u0178'],\n    ];\n\n    static const(ubyte)[] invalid = [0xA0,0xFF,0xFF,0x81,0x98,0x81];\n\n    foreach (i,scheme;schemes)\n    {\n        assert(scheme.toString() == schemeNames[i],\"Error in the name of encoding scheme\"~schemeNames[i]);\n        assert(!scheme.canEncode('\\uFFFD'));\n        assert(scheme.encodedLength('A') == 1);\n        const(ubyte)[] encodeStr;\n        dchar[] decStr;\n        foreach (chr;valid[i])\n        {\n            assert(scheme.encode(chr,buffer) == 1);\n            encodeStr ~= buffer;\n            const(ubyte)[] buf = buffer;\n            decStr ~= scheme.decode(buf);\n        }\n\n        assert(scheme.isValid(encodeStr),\"Not correctly encoded UTF => \" ~ schemeNames[i]);\n        assert(valid[i] == decStr,\"Error encode/decode UTF8 <=> \" ~ schemeNames[i]);\n\n        if (schemeNames[i] == \"ISO-8859-1\" || schemeNames[i] == \"ISO-8859-2\")\n        {\n            assert(scheme.safeDecode(invalid) != INVALID_SEQUENCE);\n        }\n        else\n        {\n            assert(scheme.safeDecode(invalid) == INVALID_SEQUENCE);\n        }\n        assert(scheme.replacementSequence() == cast(immutable(ubyte)[])\"?\");\n    }\n    assert(invalid.length == 0);\n}\n\n/**\n EncodingScheme to handle UTF-8\n\n This scheme recognises the following names:\n                 \"UTF-8\"\n */\nclass EncodingSchemeUtf8 : EncodingScheme\n{\n    /* // moved to std.internal.phobosinit\n    shared static this()\n    {\n        EncodingScheme.register(\"std.encoding.EncodingSchemeUtf8\");\n    }*/\n\n    const\n    {\n        override string[] names() @safe pure nothrow\n        {\n            return\n            [\n                \"UTF-8\"\n            ];\n        }\n\n        override string toString() @safe pure nothrow @nogc\n        {\n            return \"UTF-8\";\n        }\n\n        override bool canEncode(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.canEncode!(char)(c);\n        }\n\n        override size_t encodedLength(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.encodedLength!(char)(c);\n        }\n\n        override size_t encode(dchar c, ubyte[] buffer) @safe pure nothrow @nogc\n        {\n            auto r = cast(char[]) buffer;\n            return std.encoding.encode(c,r);\n        }\n\n        override dchar decode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(char)[]) s;\n            dchar c = std.encoding.decode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override dchar safeDecode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        {\n            auto t = cast(const(char)[]) s;\n            dchar c = std.encoding.safeDecode(t);\n            s = s[$-t.length..$];\n            return c;\n        }\n\n        override @property immutable(ubyte)[] replacementSequence() @safe pure nothrow @nogc\n        {\n            return cast(immutable(ubyte)[])\"\\uFFFD\";\n        }\n    }\n}\n\n/**\n EncodingScheme to handle UTF-16 in native byte order\n\n This scheme recognises the following names:\n                 \"UTF-16LE\" (little-endian architecture only)\n                 \"UTF-16BE\" (big-endian architecture only)\n */\nclass EncodingSchemeUtf16Native : EncodingScheme\n{\n    /* // moved to std.internal.phobosinit\n    shared static this()\n    {\n        EncodingScheme.register(\"std.encoding.EncodingSchemeUtf16Native\");\n    }*/\n\n    const\n    {\n        version (LittleEndian) { enum string NAME = \"UTF-16LE\"; }\n        version (BigEndian)    { enum string NAME = \"UTF-16BE\"; }\n\n        override string[] names() @safe pure nothrow\n        {\n            return [ NAME ];\n        }\n\n        override string toString() @safe pure nothrow @nogc\n        {\n            return NAME;\n        }\n\n        override bool canEncode(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.canEncode!(wchar)(c);\n        }\n\n        override size_t encodedLength(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.encodedLength!(wchar)(c);\n        }\n\n        override size_t encode(dchar c, ubyte[] buffer) @safe pure nothrow @nogc\n        {\n            auto r = cast(wchar[]) buffer;\n            return wchar.sizeof * std.encoding.encode(c,r);\n        }\n\n        override dchar decode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        in\n        {\n            assert((s.length & 1) == 0);\n        }\n        do\n        {\n            auto t = cast(const(wchar)[]) s;\n            dchar c = std.encoding.decode(t);\n            s = s[$-t.length * wchar.sizeof..$];\n            return c;\n        }\n\n        override dchar safeDecode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        in\n        {\n            assert((s.length & 1) == 0);\n        }\n        do\n        {\n            auto t = cast(const(wchar)[]) s;\n            dchar c = std.encoding.safeDecode(t);\n            s = s[$-t.length * wchar.sizeof..$];\n            return c;\n        }\n\n        override @property immutable(ubyte)[] replacementSequence() @safe pure nothrow @nogc\n        {\n            return cast(immutable(ubyte)[])\"\\uFFFD\"w;\n        }\n    }\n}\n@system unittest\n{\n    version (LittleEndian)\n    {\n        auto efrom = EncodingScheme.create(\"utf-16le\");\n        ubyte[6] sample = [154,1, 155,1, 156,1];\n    }\n    version (BigEndian)\n    {\n        auto efrom = EncodingScheme.create(\"utf-16be\");\n        ubyte[6] sample = [1,154, 1,155, 1,156];\n    }\n    const(ubyte)[] ub = cast(const(ubyte)[])sample;\n    dchar dc = efrom.safeDecode(ub);\n    assert(dc == 410);\n    assert(ub.length == 4);\n}\n\n/**\n EncodingScheme to handle UTF-32 in native byte order\n\n This scheme recognises the following names:\n                 \"UTF-32LE\" (little-endian architecture only)\n                 \"UTF-32BE\" (big-endian architecture only)\n */\nclass EncodingSchemeUtf32Native : EncodingScheme\n{\n    /* // moved to std.internal.phobosinit\n    shared static this()\n    {\n        EncodingScheme.register(\"std.encoding.EncodingSchemeUtf32Native\");\n    }*/\n\n    const\n    {\n        version (LittleEndian) { enum string NAME = \"UTF-32LE\"; }\n        version (BigEndian)    { enum string NAME = \"UTF-32BE\"; }\n\n        override string[] names() @safe pure nothrow\n        {\n            return [ NAME ];\n        }\n\n        override string toString() @safe pure nothrow @nogc\n        {\n            return NAME;\n        }\n\n        override bool canEncode(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.canEncode!(dchar)(c);\n        }\n\n        override size_t encodedLength(dchar c) @safe pure nothrow @nogc\n        {\n            return std.encoding.encodedLength!(dchar)(c);\n        }\n\n        override size_t encode(dchar c, ubyte[] buffer) @safe pure nothrow @nogc\n        {\n            auto r = cast(dchar[]) buffer;\n            return dchar.sizeof * std.encoding.encode(c,r);\n        }\n\n        override dchar decode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        in\n        {\n            assert((s.length & 3) == 0);\n        }\n        do\n        {\n            auto t = cast(const(dchar)[]) s;\n            dchar c = std.encoding.decode(t);\n            s = s[$-t.length * dchar.sizeof..$];\n            return c;\n        }\n\n        override dchar safeDecode(ref const(ubyte)[] s) @safe pure nothrow @nogc\n        in\n        {\n            assert((s.length & 3) == 0);\n        }\n        do\n        {\n            auto t = cast(const(dchar)[]) s;\n            dchar c = std.encoding.safeDecode(t);\n            s = s[$-t.length * dchar.sizeof..$];\n            return c;\n        }\n\n        override @property immutable(ubyte)[] replacementSequence() @safe pure nothrow @nogc\n        {\n            return cast(immutable(ubyte)[])\"\\uFFFD\"d;\n        }\n    }\n}\n@system unittest\n{\n    version (LittleEndian)\n    {\n        auto efrom = EncodingScheme.create(\"utf-32le\");\n        ubyte[12] sample = [154,1,0,0, 155,1,0,0, 156,1,0,0];\n    }\n    version (BigEndian)\n    {\n        auto efrom = EncodingScheme.create(\"utf-32be\");\n        ubyte[12] sample = [0,0,1,154, 0,0,1,155, 0,0,1,156];\n    }\n    const(ubyte)[] ub = cast(const(ubyte)[])sample;\n    dchar dc = efrom.safeDecode(ub);\n    assert(dc == 410);\n    assert(ub.length == 8);\n}\n\n//=============================================================================\n\n\n/** Definitions of common Byte Order Marks.\nThe elements of the `enum` can used as indices into `bomTable` to get\nmatching `BOMSeq`.\n*/\nenum BOM\n{\n    none      = 0,  /// no BOM was found\n    utf32be   = 1,  /// [0x00, 0x00, 0xFE, 0xFF]\n    utf32le   = 2,  /// [0xFF, 0xFE, 0x00, 0x00]\n    utf7      = 3,  /*  [0x2B, 0x2F, 0x76, 0x38]\n                        [0x2B, 0x2F, 0x76, 0x39],\n                        [0x2B, 0x2F, 0x76, 0x2B],\n                        [0x2B, 0x2F, 0x76, 0x2F],\n                        [0x2B, 0x2F, 0x76, 0x38, 0x2D]\n                    */\n    utf1      = 8,  /// [0xF7, 0x64, 0x4C]\n    utfebcdic = 9,  /// [0xDD, 0x73, 0x66, 0x73]\n    scsu      = 10, /// [0x0E, 0xFE, 0xFF]\n    bocu1     = 11, /// [0xFB, 0xEE, 0x28]\n    gb18030   = 12, /// [0x84, 0x31, 0x95, 0x33]\n    utf8      = 13, /// [0xEF, 0xBB, 0xBF]\n    utf16be   = 14, /// [0xFE, 0xFF]\n    utf16le   = 15  /// [0xFF, 0xFE]\n}\n\n/// The type stored inside `bomTable`.\nalias BOMSeq = Tuple!(BOM, \"schema\", ubyte[], \"sequence\");\n\n/** Mapping of a byte sequence to $(B Byte Order Mark (BOM))\n*/\nimmutable bomTable = [\n    BOMSeq(BOM.none, null),\n    BOMSeq(BOM.utf32be, cast(ubyte[])([0x00, 0x00, 0xFE, 0xFF])),\n    BOMSeq(BOM.utf32le, cast(ubyte[])([0xFF, 0xFE, 0x00, 0x00])),\n    BOMSeq(BOM.utf7, cast(ubyte[])([0x2B, 0x2F, 0x76, 0x39])),\n    BOMSeq(BOM.utf7, cast(ubyte[])([0x2B, 0x2F, 0x76, 0x2B])),\n    BOMSeq(BOM.utf7, cast(ubyte[])([0x2B, 0x2F, 0x76, 0x2F])),\n    BOMSeq(BOM.utf7, cast(ubyte[])([0x2B, 0x2F, 0x76, 0x38, 0x2D])),\n    BOMSeq(BOM.utf7, cast(ubyte[])([0x2B, 0x2F, 0x76, 0x38])),\n    BOMSeq(BOM.utf1, cast(ubyte[])([0xF7, 0x64, 0x4C])),\n    BOMSeq(BOM.utfebcdic, cast(ubyte[])([0xDD, 0x73, 0x66, 0x73])),\n    BOMSeq(BOM.scsu, cast(ubyte[])([0x0E, 0xFE, 0xFF])),\n    BOMSeq(BOM.bocu1, cast(ubyte[])([0xFB, 0xEE, 0x28])),\n    BOMSeq(BOM.gb18030, cast(ubyte[])([0x84, 0x31, 0x95, 0x33])),\n    BOMSeq(BOM.utf8, cast(ubyte[])([0xEF, 0xBB, 0xBF])),\n    BOMSeq(BOM.utf16be, cast(ubyte[])([0xFE, 0xFF])),\n    BOMSeq(BOM.utf16le, cast(ubyte[])([0xFF, 0xFE]))\n];\n\n/** Returns a `BOMSeq` for a given `input`.\nIf no `BOM` is present the `BOMSeq` for `BOM.none` is\nreturned. The `BOM` sequence at the beginning of the range will\nnot be comsumed from the passed range. If you pass a reference type\nrange make sure that `save` creates a deep copy.\n\nParams:\n    input = The sequence to check for the `BOM`\n\nReturns:\n    the found `BOMSeq` corresponding to the passed `input`.\n*/\nimmutable(BOMSeq) getBOM(Range)(Range input)\nif (isForwardRange!Range && is(Unqual!(ElementType!Range) == ubyte))\n{\n    import std.algorithm.searching : startsWith;\n    foreach (it; bomTable[1 .. $])\n    {\n        if (startsWith(input.save, it.sequence))\n        {\n            return it;\n        }\n    }\n\n    return bomTable[0];\n}\n\n///\n@system unittest\n{\n    import std.format : format;\n\n    auto ts = dchar(0x0000FEFF) ~ \"Hello World\"d;\n\n    auto entry = getBOM(cast(ubyte[]) ts);\n    version (BigEndian)\n    {\n        assert(entry.schema == BOM.utf32be, format(\"%s\", entry.schema));\n    }\n    else\n    {\n        assert(entry.schema == BOM.utf32le, format(\"%s\", entry.schema));\n    }\n}\n\n@system unittest\n{\n    import std.format : format;\n\n    foreach (idx, it; bomTable)\n    {\n        auto s = it[1] ~ cast(ubyte[])\"hello world\";\n        auto i = getBOM(s);\n        assert(i[0] == bomTable[idx][0]);\n\n        if (idx < 4 || idx > 7) // get around the multiple utf7 bom's\n        {\n            assert(i[0] == BOM.init + idx);\n            assert(i[1] == it[1]);\n        }\n    }\n}\n\n@safe pure unittest\n{\n    struct BOMInputRange\n    {\n        ubyte[] arr;\n\n        @property ubyte front()\n        {\n            return this.arr.front;\n        }\n\n        @property bool empty()\n        {\n            return this.arr.empty;\n        }\n\n        void popFront()\n        {\n            this.arr = this.arr[1 .. $];\n        }\n\n        @property typeof(this) save()\n        {\n            return this;\n        }\n    }\n\n    static assert( isInputRange!BOMInputRange);\n    static assert(!isArray!BOMInputRange);\n\n    ubyte[] dummyEnd = [0,0,0,0];\n\n    foreach (idx, it; bomTable[1 .. $])\n    {\n        {\n            auto ir = BOMInputRange(it.sequence.dup);\n\n            auto b = getBOM(ir);\n            assert(b.schema == it.schema);\n            assert(ir.arr == it.sequence);\n        }\n\n        {\n            auto noBom = it.sequence[0 .. 1].dup ~ dummyEnd;\n            size_t oldLen = noBom.length;\n            assert(oldLen - 4 < it.sequence.length);\n\n            auto ir = BOMInputRange(noBom.dup);\n            auto b = getBOM(ir);\n            assert(b.schema == BOM.none);\n            assert(noBom.length == oldLen);\n        }\n    }\n}\n\n/** Constant defining a fully decoded BOM */\nenum dchar utfBOM = 0xfeff;\n"
  },
  {
    "path": "libphobos/src/std/exception.d",
    "content": "// Written in the D programming language.\n\n/++\n    This module defines functions related to exceptions and general error\n    handling. It also defines functions intended to aid in unit testing.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Assumptions) $(TD\n        $(LREF assertNotThrown)\n        $(LREF assertThrown)\n        $(LREF assumeUnique)\n        $(LREF assumeWontThrow)\n        $(LREF mayPointTo)\n))\n$(TR $(TD Enforce) $(TD\n        $(LREF doesPointTo)\n        $(LREF enforce)\n        $(LREF errnoEnforce)\n))\n$(TR $(TD Handlers) $(TD\n        $(LREF collectException)\n        $(LREF collectExceptionMsg)\n        $(LREF ifThrown)\n        $(LREF handle)\n))\n$(TR $(TD Other) $(TD\n        $(LREF basicExceptionCtors)\n        $(LREF emptyExceptionMsg)\n        $(LREF ErrnoException)\n        $(LREF RangePrimitive)\n))\n)\n\n    Copyright: Copyright Andrei Alexandrescu 2008-, Jonathan M Davis 2011-.\n    License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)\n    Authors:   $(HTTP erdani.org, Andrei Alexandrescu) and\n               $(HTTP jmdavisprog.com, Jonathan M Davis)\n    Source:    $(PHOBOSSRC std/exception.d)\n\n +/\nmodule std.exception;\n\n/// Synopis\n@system unittest\n{\n    import core.stdc.stdlib : malloc, free;\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map, splitter;\n    import std.algorithm.searching : endsWith;\n    import std.conv : ConvException, to;\n    import std.range : front, retro;\n\n    // use enforce like assert\n    int a = 3;\n    enforce(a > 2, \"a needs to be higher than 2.\");\n\n    // enforce can throw a custom exception\n    enforce!ConvException(a > 2, \"a needs to be higher than 2.\");\n\n    // enforce will return it's input\n    enum size = 42;\n    auto memory = enforce(malloc(size), \"malloc failed\")[0 .. size];\n    scope(exit) free(memory.ptr);\n\n    // collectException can be used to test for exceptions\n    Exception e = collectException(\"abc\".to!int);\n    assert(e.file.endsWith(\"conv.d\"));\n\n    // and just for the exception message\n    string msg = collectExceptionMsg(\"abc\".to!int);\n    assert(msg == \"Unexpected 'a' when converting from type string to type int\");\n\n    // assertThrown can be used to assert that an exception is thrown\n    assertThrown!ConvException(\"abc\".to!int);\n\n    // ifThrown can be used to provide a default value if an exception is thrown\n    assert(\"x\".to!int().ifThrown(0) == 0);\n\n    // handle is a more advanced version of ifThrown for ranges\n    auto r = \"12,1337z32,54\".splitter(',').map!(a => to!int(a));\n    auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0);\n    assert(h.equal([12, 0, 54]));\n    assertThrown!ConvException(h.retro.equal([54, 0, 12]));\n\n    // basicExceptionCtors avoids the boilerplate when creating custom exceptions\n    static class MeaCulpa : Exception\n    {\n        mixin basicExceptionCtors;\n    }\n    e = collectException((){throw new MeaCulpa(\"diagnostic message\");}());\n    assert(e.msg == \"diagnostic message\");\n    assert(e.file == __FILE__);\n    assert(e.line == __LINE__ - 3);\n\n    // assumeWontThrow can be used to cast throwing code into `nothrow`\n    void exceptionFreeCode() nothrow\n    {\n        // auto-decoding only throws if an invalid UTF char is given\n        assumeWontThrow(\"abc\".front);\n    }\n\n    // assumeUnique can be used to cast mutable instance to an `immutable` one\n    // use with care\n    char[] str = \"  mutable\".dup;\n    str[0 .. 2] = \"im\";\n    immutable res = assumeUnique(str);\n    assert(res == \"immutable\");\n}\n\nimport std.range.primitives;\nimport std.traits;\n\n/++\n    Asserts that the given expression does $(I not) throw the given type\n    of `Throwable`. If a `Throwable` of the given type is thrown,\n    it is caught and does not escape assertNotThrown. Rather, an\n    `AssertError` is thrown. However, any other `Throwable`s will escape.\n\n    Params:\n        T          = The `Throwable` to test for.\n        expression = The expression to test.\n        msg        = Optional message to output on test failure.\n                     If msg is empty, and the thrown exception has a\n                     non-empty msg field, the exception's msg field\n                     will be output on test failure.\n        file       = The file where the error occurred.\n                     Defaults to `__FILE__`.\n        line       = The line where the error occurred.\n                     Defaults to `__LINE__`.\n\n    Throws:\n        `AssertError` if the given `Throwable` is thrown.\n\n    Returns:\n        the result of `expression`.\n +/\nauto assertNotThrown(T : Throwable = Exception, E)\n                    (lazy E expression,\n                     string msg = null,\n                     string file = __FILE__,\n                     size_t line = __LINE__)\n{\n    import core.exception : AssertError;\n    try\n    {\n        return expression();\n    }\n    catch (T t)\n    {\n        immutable message = msg.length == 0 ? t.msg : msg;\n        immutable tail = message.length == 0 ? \".\" : \": \" ~ message;\n        throw new AssertError(\"assertNotThrown failed: \" ~ T.stringof ~ \" was thrown\" ~ tail, file, line, t);\n    }\n}\n///\n@system unittest\n{\n    import core.exception : AssertError;\n\n    import std.string;\n    assertNotThrown!StringException(enforce!StringException(true, \"Error!\"));\n\n    //Exception is the default.\n    assertNotThrown(enforce!StringException(true, \"Error!\"));\n\n    assert(collectExceptionMsg!AssertError(assertNotThrown!StringException(\n               enforce!StringException(false, \"Error!\"))) ==\n           `assertNotThrown failed: StringException was thrown: Error!`);\n}\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.string;\n    assert(collectExceptionMsg!AssertError(assertNotThrown!StringException(\n               enforce!StringException(false, \"\"), \"Error!\")) ==\n           `assertNotThrown failed: StringException was thrown: Error!`);\n\n    assert(collectExceptionMsg!AssertError(assertNotThrown!StringException(\n               enforce!StringException(false, \"\"))) ==\n           `assertNotThrown failed: StringException was thrown.`);\n\n    assert(collectExceptionMsg!AssertError(assertNotThrown!StringException(\n               enforce!StringException(false, \"\"), \"\")) ==\n           `assertNotThrown failed: StringException was thrown.`);\n}\n\n@system unittest\n{\n    import core.exception : AssertError;\n\n    void throwEx(Throwable t) { throw t; }\n    bool nothrowEx() { return true; }\n\n    try\n    {\n        assert(assertNotThrown!Exception(nothrowEx()));\n    }\n    catch (AssertError) assert(0);\n\n    try\n    {\n        assert(assertNotThrown!Exception(nothrowEx(), \"It's a message\"));\n    }\n    catch (AssertError) assert(0);\n\n    try\n    {\n        assert(assertNotThrown!AssertError(nothrowEx()));\n    }\n    catch (AssertError) assert(0);\n\n    try\n    {\n        assert(assertNotThrown!AssertError(nothrowEx(), \"It's a message\"));\n    }\n    catch (AssertError) assert(0);\n\n    {\n        bool thrown = false;\n        try\n        {\n            assertNotThrown!Exception(\n                throwEx(new Exception(\"It's an Exception\")));\n        }\n        catch (AssertError) thrown = true;\n        assert(thrown);\n    }\n\n    {\n        bool thrown = false;\n        try\n        {\n            assertNotThrown!Exception(\n                throwEx(new Exception(\"It's an Exception\")), \"It's a message\");\n        }\n        catch (AssertError) thrown = true;\n        assert(thrown);\n    }\n\n    {\n        bool thrown = false;\n        try\n        {\n            assertNotThrown!AssertError(\n                throwEx(new AssertError(\"It's an AssertError\", __FILE__, __LINE__)));\n        }\n        catch (AssertError) thrown = true;\n        assert(thrown);\n    }\n\n    {\n        bool thrown = false;\n        try\n        {\n            assertNotThrown!AssertError(\n                throwEx(new AssertError(\"It's an AssertError\", __FILE__, __LINE__)),\n                        \"It's a message\");\n        }\n        catch (AssertError) thrown = true;\n        assert(thrown);\n    }\n}\n\n/++\n    Asserts that the given expression throws the given type of `Throwable`.\n    The `Throwable` is caught and does not escape assertThrown. However,\n    any other `Throwable`s $(I will) escape, and if no `Throwable`\n    of the given type is thrown, then an `AssertError` is thrown.\n\n    Params:\n        T          = The `Throwable` to test for.\n        expression = The expression to test.\n        msg        = Optional message to output on test failure.\n        file       = The file where the error occurred.\n                     Defaults to `__FILE__`.\n        line       = The line where the error occurred.\n                     Defaults to `__LINE__`.\n\n    Throws:\n        `AssertError` if the given `Throwable` is not thrown.\n  +/\nvoid assertThrown(T : Throwable = Exception, E)\n                 (lazy E expression,\n                  string msg = null,\n                  string file = __FILE__,\n                  size_t line = __LINE__)\n{\n    import core.exception : AssertError;\n\n    try\n        expression();\n    catch (T)\n        return;\n    throw new AssertError(\"assertThrown failed: No \" ~ T.stringof ~ \" was thrown\"\n                                 ~ (msg.length == 0 ? \".\" : \": \") ~ msg,\n                          file, line);\n}\n///\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.string;\n\n    assertThrown!StringException(enforce!StringException(false, \"Error!\"));\n\n    //Exception is the default.\n    assertThrown(enforce!StringException(false, \"Error!\"));\n\n    assert(collectExceptionMsg!AssertError(assertThrown!StringException(\n               enforce!StringException(true, \"Error!\"))) ==\n           `assertThrown failed: No StringException was thrown.`);\n}\n\n@system unittest\n{\n    import core.exception : AssertError;\n\n    void throwEx(Throwable t) { throw t; }\n    void nothrowEx() { }\n\n    try\n    {\n        assertThrown!Exception(throwEx(new Exception(\"It's an Exception\")));\n    }\n    catch (AssertError) assert(0);\n\n    try\n    {\n        assertThrown!Exception(throwEx(new Exception(\"It's an Exception\")),\n                               \"It's a message\");\n    }\n    catch (AssertError) assert(0);\n\n    try\n    {\n        assertThrown!AssertError(throwEx(new AssertError(\"It's an AssertError\",\n                                                         __FILE__, __LINE__)));\n    }\n    catch (AssertError) assert(0);\n\n    try\n    {\n        assertThrown!AssertError(throwEx(new AssertError(\"It's an AssertError\",\n                                                         __FILE__, __LINE__)),\n                                 \"It's a message\");\n    }\n    catch (AssertError) assert(0);\n\n\n    {\n        bool thrown = false;\n        try\n            assertThrown!Exception(nothrowEx());\n        catch (AssertError)\n            thrown = true;\n\n        assert(thrown);\n    }\n\n    {\n        bool thrown = false;\n        try\n            assertThrown!Exception(nothrowEx(), \"It's a message\");\n        catch (AssertError)\n            thrown = true;\n\n        assert(thrown);\n    }\n\n    {\n        bool thrown = false;\n        try\n            assertThrown!AssertError(nothrowEx());\n        catch (AssertError)\n            thrown = true;\n\n        assert(thrown);\n    }\n\n    {\n        bool thrown = false;\n        try\n            assertThrown!AssertError(nothrowEx(), \"It's a message\");\n        catch (AssertError)\n            thrown = true;\n\n        assert(thrown);\n    }\n}\n\n\n/++\n    Enforces that the given value is true.\n    If the given value is false, an exception is thrown.\n    The\n    $(UL\n        $(LI `msg` - error message as a `string`)\n        $(LI `dg` - custom delegate that return a string and is only called if an exception occurred)\n        $(LI `ex` - custom exception to be thrown. It is `lazy` and is only created if an exception occurred)\n    )\n\n    Params:\n        value = The value to test.\n        E = Exception type to throw if the value evaluates to false.\n        msg = The error message to put in the exception if it is thrown.\n        dg = The delegate to be called if the value evaluates to false.\n        ex = The exception to throw if the value evaluates to false.\n        file = The source file of the caller.\n        line = The line number of the caller.\n\n    Returns: `value`, if `cast(bool) value` is true. Otherwise,\n    depending on the chosen overload, `new Exception(msg)`, `dg()` or `ex` is thrown.\n\n    Note:\n        `enforce` is used to throw exceptions and is therefore intended to\n        aid in error handling. It is $(I not) intended for verifying the logic\n        of your program. That is what `assert` is for. Also, do not use\n        `enforce` inside of contracts (i.e. inside of `in` and `out`\n        blocks and `invariant`s), because contracts are compiled out when\n        compiling with $(I -release).\n\n        If a delegate is passed, the safety and purity of this function are inferred\n        from `Dg`'s safety and purity.\n +/\ntemplate enforce(E : Throwable = Exception)\nif (is(typeof(new E(\"\", string.init, size_t.init)) : Throwable) ||\n    is(typeof(new E(string.init, size_t.init)) : Throwable))\n{\n    ///\n    T enforce(T)(T value, lazy const(char)[] msg = null,\n    string file = __FILE__, size_t line = __LINE__)\n    if (is(typeof({ if (!value) {} })))\n    {\n        if (!value) bailOut!E(file, line, msg);\n        return value;\n    }\n}\n\n/// ditto\nT enforce(T, Dg, string file = __FILE__, size_t line = __LINE__)\n    (T value, scope Dg dg)\nif (isSomeFunction!Dg && is(typeof( dg() )) &&\n    is(typeof({ if (!value) {} })))\n{\n    if (!value) dg();\n    return value;\n}\n\n/// ditto\nT enforce(T)(T value, lazy Throwable ex)\n{\n    if (!value) throw ex();\n    return value;\n}\n\n///\n@system unittest\n{\n    import core.stdc.stdlib : malloc, free;\n    import std.conv : ConvException, to;\n\n    // use enforce like assert\n    int a = 3;\n    enforce(a > 2, \"a needs to be higher than 2.\");\n\n    // enforce can throw a custom exception\n    enforce!ConvException(a > 2, \"a needs to be higher than 2.\");\n\n    // enforce will return it's input\n    enum size = 42;\n    auto memory = enforce(malloc(size), \"malloc failed\")[0 .. size];\n    scope(exit) free(memory.ptr);\n}\n\n///\n@safe unittest\n{\n    assertNotThrown(enforce(true, new Exception(\"this should not be thrown\")));\n    assertThrown(enforce(false, new Exception(\"this should be thrown\")));\n}\n\n///\n@safe unittest\n{\n    assert(enforce(123) == 123);\n\n    try\n    {\n        enforce(false, \"error\");\n        assert(false);\n    }\n    catch (Exception e)\n    {\n        assert(e.msg == \"error\");\n        assert(e.file == __FILE__);\n        assert(e.line == __LINE__-7);\n    }\n}\n\n/// Alias your own enforce function\n@safe unittest\n{\n    import std.conv : ConvException;\n    alias convEnforce = enforce!ConvException;\n    assertNotThrown(convEnforce(true));\n    assertThrown!ConvException(convEnforce(false, \"blah\"));\n}\n\nprivate void bailOut(E : Throwable = Exception)(string file, size_t line, scope const(char)[] msg)\n{\n    static if (is(typeof(new E(string.init, string.init, size_t.init))))\n    {\n        throw new E(msg ? msg.idup : \"Enforcement failed\", file, line);\n    }\n    else static if (is(typeof(new E(string.init, size_t.init))))\n    {\n        throw new E(file, line);\n    }\n    else\n    {\n        static assert(0, \"Expected this(string, string, size_t) or this(string, size_t)\" ~\n            \" constructor for \" ~ __traits(identifier, E));\n    }\n}\n\n@safe unittest\n{\n    // Issue 10510\n    extern(C) void cFoo() { }\n    enforce(false, &cFoo);\n}\n\n// purity and safety inference test\n@system unittest\n{\n    static foreach (EncloseSafe; [false, true])\n    static foreach (EnclosePure; [false, true])\n    {\n        static foreach (BodySafe; [false, true])\n        static foreach (BodyPure; [false, true])\n        {{\n            enum code =\n                \"delegate void() \" ~\n                (EncloseSafe ? \"@safe \" : \"\") ~\n                (EnclosePure ? \"pure \" : \"\") ~\n                \"{ enforce(true, { \" ~\n                        \"int n; \" ~\n                        (BodySafe ? \"\" : \"auto p = &n + 10; \"    ) ~    // unsafe code\n                        (BodyPure ? \"\" : \"static int g; g = 10; \") ~    // impure code\n                    \"}); \" ~\n                \"}\";\n            enum expect =\n                (BodySafe || !EncloseSafe) && (!EnclosePure || BodyPure);\n\n            version (none)\n            pragma(msg, \"safe = \", EncloseSafe?1:0, \"/\", BodySafe?1:0, \", \",\n                        \"pure = \", EnclosePure?1:0, \"/\", BodyPure?1:0, \", \",\n                        \"expect = \", expect?\"OK\":\"NG\", \", \",\n                        \"code = \", code);\n\n            static assert(__traits(compiles, mixin(code)()) == expect);\n        }}\n    }\n}\n\n// Test for bugzilla 8637\n@system unittest\n{\n    struct S\n    {\n        static int g;\n        ~this() {}  // impure & unsafe destructor\n        bool opCast(T:bool)() {\n            int* p = cast(int*) 0;   // unsafe operation\n            int n = g;              // impure operation\n            return true;\n        }\n    }\n    S s;\n\n    enforce(s);\n    enforce(s, {});\n    enforce(s, new Exception(\"\"));\n\n    errnoEnforce(s);\n\n    alias E1 = Exception;\n    static class E2 : Exception\n    {\n        this(string fn, size_t ln) { super(\"\", fn, ln); }\n    }\n    static class E3 : Exception\n    {\n        this(string msg) { super(msg, __FILE__, __LINE__); }\n    }\n    enforce!E1(s);\n    enforce!E2(s);\n}\n\n@safe unittest\n{\n    // Issue 14685\n\n    class E : Exception\n    {\n        this() { super(\"Not found\"); }\n    }\n    static assert(!__traits(compiles, { enforce!E(false); }));\n}\n\n/++\n    Enforces that the given value is true, throwing an `ErrnoException` if it\n    is not.\n\n    Params:\n        value = The value to test.\n        msg = The message to include in the `ErrnoException` if it is thrown.\n\n    Returns: `value`, if `cast(bool) value` is true. Otherwise,\n    $(D new ErrnoException(msg)) is thrown.  It is assumed that the last\n    operation set `errno` to an error code corresponding with the failed\n    condition.\n +/\nalias errnoEnforce = enforce!ErrnoException;\n\n///\n@system unittest\n{\n    import core.stdc.stdio : fclose, fgets, fopen;\n    auto f = fopen(__FILE_FULL_PATH__, \"r\").errnoEnforce;\n    scope(exit) fclose(f);\n    char[100] buf;\n    auto line = fgets(buf.ptr, buf.length, f);\n    enforce(line !is null); // expect a non-empty line\n}\n\n// @@@DEPRECATED_2.089@@@\n/++\n    $(RED Deprecated. Please use $(LREF enforce) instead. This function will be removed 2.089.)\n\n    If `!value` is `false`, `value` is returned. Otherwise,\n    $(D new E(msg, file, line)) is thrown. Or if `E` doesn't take a message\n    and can be constructed with $(D new E(file, line)), then\n    $(D new E(file, line)) will be thrown.\n\n    Example:\n    --------------------\n    auto f = enforceEx!FileMissingException(fopen(\"data.txt\"));\n    auto line = readln(f);\n    enforceEx!DataCorruptionException(line.length);\n    --------------------\n +/\ndeprecated(\"Use `enforce`. `enforceEx` will be removed with 2.089.\")\ntemplate enforceEx(E : Throwable)\nif (is(typeof(new E(\"\", string.init, size_t.init))))\n{\n    /++ Ditto +/\n    T enforceEx(T)(T value, lazy string msg = \"\", string file = __FILE__, size_t line = __LINE__)\n    {\n        if (!value) throw new E(msg, file, line);\n        return value;\n    }\n}\n\n/+ Ditto +/\ndeprecated(\"Use `enforce`. `enforceEx` will be removed with 2.089.\")\ntemplate enforceEx(E : Throwable)\nif (is(typeof(new E(string.init, size_t.init))) && !is(typeof(new E(\"\", string.init, size_t.init))))\n{\n    /++ Ditto +/\n    T enforceEx(T)(T value, string file = __FILE__, size_t line = __LINE__)\n    {\n        if (!value) throw new E(file, line);\n        return value;\n    }\n}\n\ndeprecated\n@system unittest\n{\n    import core.exception : OutOfMemoryError;\n    import std.array : empty;\n    assertNotThrown(enforceEx!Exception(true));\n    assertNotThrown(enforceEx!Exception(true, \"blah\"));\n    assertNotThrown(enforceEx!OutOfMemoryError(true));\n\n    {\n        auto e = collectException(enforceEx!Exception(false));\n        assert(e !is null);\n        assert(e.msg.empty);\n        assert(e.file == __FILE__);\n        assert(e.line == __LINE__ - 4);\n    }\n\n    {\n        auto e = collectException(enforceEx!Exception(false, \"hello\", \"file\", 42));\n        assert(e !is null);\n        assert(e.msg == \"hello\");\n        assert(e.file == \"file\");\n        assert(e.line == 42);\n    }\n\n    {\n        auto e = collectException!Error(enforceEx!OutOfMemoryError(false));\n        assert(e !is null);\n        assert(e.msg == \"Memory allocation failed\");\n        assert(e.file == __FILE__);\n        assert(e.line == __LINE__ - 4);\n    }\n\n    {\n        auto e = collectException!Error(enforceEx!OutOfMemoryError(false, \"file\", 42));\n        assert(e !is null);\n        assert(e.msg == \"Memory allocation failed\");\n        assert(e.file == \"file\");\n        assert(e.line == 42);\n    }\n\n    static assert(!is(typeof(enforceEx!int(true))));\n}\n\ndeprecated\n@safe unittest\n{\n    alias enf = enforceEx!Exception;\n    assertNotThrown(enf(true));\n    assertThrown(enf(false, \"blah\"));\n}\n\n/++\n    Catches and returns the exception thrown from the given expression.\n    If no exception is thrown, then null is returned and `result` is\n    set to the result of the expression.\n\n    Note that while `collectException` $(I can) be used to collect any\n    `Throwable` and not just `Exception`s, it is generally ill-advised to\n    catch anything that is neither an `Exception` nor a type derived from\n    `Exception`. So, do not use `collectException` to collect\n    non-`Exception`s unless you're sure that that's what you really want to\n    do.\n\n    Params:\n        T          = The type of exception to catch.\n        expression = The expression which may throw an exception.\n        result     = The result of the expression if no exception is thrown.\n+/\nT collectException(T = Exception, E)(lazy E expression, ref E result)\n{\n    try\n    {\n        result = expression();\n    }\n    catch (T e)\n    {\n        return e;\n    }\n    return null;\n}\n///\n@system unittest\n{\n    int b;\n    int foo() { throw new Exception(\"blah\"); }\n    assert(collectException(foo(), b));\n\n    int[] a = new int[3];\n    import core.exception : RangeError;\n    assert(collectException!RangeError(a[4], b));\n}\n\n/++\n    Catches and returns the exception thrown from the given expression.\n    If no exception is thrown, then null is returned. `E` can be\n    `void`.\n\n    Note that while `collectException` $(I can) be used to collect any\n    `Throwable` and not just `Exception`s, it is generally ill-advised to\n    catch anything that is neither an `Exception` nor a type derived from\n    `Exception`. So, do not use `collectException` to collect\n    non-`Exception`s unless you're sure that that's what you really want to\n    do.\n\n    Params:\n        T          = The type of exception to catch.\n        expression = The expression which may throw an exception.\n+/\nT collectException(T : Throwable = Exception, E)(lazy E expression)\n{\n    try\n    {\n        expression();\n    }\n    catch (T t)\n    {\n        return t;\n    }\n    return null;\n}\n\n///\n@safe unittest\n{\n    int foo() { throw new Exception(\"blah\"); }\n    assert(collectException(foo()).msg == \"blah\");\n}\n\n/++\n    Catches the exception thrown from the given expression and returns the\n    msg property of that exception. If no exception is thrown, then null is\n    returned. `E` can be `void`.\n\n    If an exception is thrown but it has an empty message, then\n    `emptyExceptionMsg` is returned.\n\n    Note that while `collectExceptionMsg` $(I can) be used to collect any\n    `Throwable` and not just `Exception`s, it is generally ill-advised to\n    catch anything that is neither an `Exception` nor a type derived from\n    `Exception`. So, do not use `collectExceptionMsg` to collect\n    non-`Exception`s unless you're sure that that's what you really want to\n    do.\n\n    Params:\n        T          = The type of exception to catch.\n        expression = The expression which may throw an exception.\n+/\nstring collectExceptionMsg(T = Exception, E)(lazy E expression)\n{\n    import std.array : empty;\n    try\n    {\n        expression();\n\n        return cast(string) null;\n    }\n    catch (T e)\n        return e.msg.empty ? emptyExceptionMsg : e.msg;\n}\n///\n@safe unittest\n{\n    void throwFunc() { throw new Exception(\"My Message.\"); }\n    assert(collectExceptionMsg(throwFunc()) == \"My Message.\");\n\n    void nothrowFunc() {}\n    assert(collectExceptionMsg(nothrowFunc()) is null);\n\n    void throwEmptyFunc() { throw new Exception(\"\"); }\n    assert(collectExceptionMsg(throwEmptyFunc()) == emptyExceptionMsg);\n}\n\n/++\n    Value that collectExceptionMsg returns when it catches an exception\n    with an empty exception message.\n +/\nenum emptyExceptionMsg = \"<Empty Exception Message>\";\n\n/**\n * Casts a mutable array to an immutable array in an idiomatic\n * manner. Technically, `assumeUnique` just inserts a cast,\n * but its name documents assumptions on the part of the\n * caller. `assumeUnique(arr)` should only be called when\n * there are no more active mutable aliases to elements of $(D\n * arr). To strengthen this assumption, `assumeUnique(arr)`\n * also clears `arr` before returning. Essentially $(D\n * assumeUnique(arr)) indicates commitment from the caller that there\n * is no more mutable access to any of `arr`'s elements\n * (transitively), and that all future accesses will be done through\n * the immutable array returned by `assumeUnique`.\n *\n * Typically, `assumeUnique` is used to return arrays from\n * functions that have allocated and built them.\n *\n * Params:\n *  array = The array to cast to immutable.\n *\n * Returns: The immutable array.\n *\n * Example:\n *\n * $(RUNNABLE_EXAMPLE\n * ----\n * string letters()\n * {\n *   char[] result = new char['z' - 'a' + 1];\n *   foreach (i, ref e; result)\n *   {\n *     e = cast(char)('a' + i);\n *   }\n *   return assumeUnique(result);\n * }\n * ----\n * )\n *\n * The use in the example above is correct because `result`\n * was private to `letters` and is inaccessible in writing\n * after the function returns. The following example shows an\n * incorrect use of `assumeUnique`.\n *\n * Bad:\n *\n * $(RUNNABLE_EXAMPLE\n * ----\n * private char[] buffer;\n * string letters(char first, char last)\n * {\n *   if (first >= last) return null; // fine\n *   auto sneaky = buffer;\n *   sneaky.length = last - first + 1;\n *   foreach (i, ref e; sneaky)\n *   {\n *     e = cast(char)('a' + i);\n *   }\n *   return assumeUnique(sneaky); // BAD\n * }\n * ----\n * )\n *\n * The example above wreaks havoc on client code because it is\n * modifying arrays that callers considered immutable. To obtain an\n * immutable array from the writable array `buffer`, replace\n * the last line with:\n *\n * ----\n * return to!(string)(sneaky); // not that sneaky anymore\n * ----\n *\n * The call will duplicate the array appropriately.\n *\n * Note that checking for uniqueness during compilation is\n * possible in certain cases, especially when a function is\n * marked as a pure function. The following example does not\n * need to call assumeUnique because the compiler can infer the\n * uniqueness of the array in the pure function:\n *\n * $(RUNNABLE_EXAMPLE\n * ----\n * string letters() pure\n * {\n *   char[] result = new char['z' - 'a' + 1];\n *   foreach (i, ref e; result)\n *   {\n *     e = cast(char)('a' + i);\n *   }\n *   return result;\n * }\n * ----\n * )\n *\n * For more on infering uniqueness see the $(B unique) and\n * $(B lent) keywords in the\n * $(HTTP www.cs.cmu.edu/~aldrich/papers/aldrich-dissertation.pdf, ArchJava)\n * language.\n *\n * The downside of using `assumeUnique`'s\n * convention-based usage is that at this time there is no\n * formal checking of the correctness of the assumption;\n * on the upside, the idiomatic use of `assumeUnique` is\n * simple and rare enough to be tolerable.\n *\n */\nimmutable(T)[] assumeUnique(T)(T[] array) pure nothrow\n{\n    return .assumeUnique(array);    // call ref version\n}\n/// ditto\nimmutable(T)[] assumeUnique(T)(ref T[] array) pure nothrow\n{\n    auto result = cast(immutable(T)[]) array;\n    array = null;\n    return result;\n}\n/// ditto\nimmutable(T[U]) assumeUnique(T, U)(ref T[U] array) pure nothrow\n{\n    auto result = cast(immutable(T[U])) array;\n    array = null;\n    return result;\n}\n\n///\n@system unittest\n{\n    int[] arr = new int[1];\n    auto arr1 = arr.assumeUnique;\n    static assert(is(typeof(arr1) == immutable(int)[]));\n    assert(arr == null);\n    assert(arr1 == [0]);\n}\n\n///\n@system unittest\n{\n    int[string] arr = [\"a\":1];\n    auto arr1 = arr.assumeUnique;\n    static assert(is(typeof(arr1) == immutable(int[string])));\n    assert(arr == null);\n    assert(arr1.keys == [\"a\"]);\n}\n\n/**\n * Wraps a possibly-throwing expression in a `nothrow` wrapper so that it\n * can be called by a `nothrow` function.\n *\n * This wrapper function documents commitment on the part of the caller that\n * the appropriate steps have been taken to avoid whatever conditions may\n * trigger an exception during the evaluation of `expr`.  If it turns out\n * that the expression $(I does) throw at runtime, the wrapper will throw an\n * `AssertError`.\n *\n * (Note that `Throwable` objects such as `AssertError` that do not\n * subclass `Exception` may be thrown even from `nothrow` functions,\n * since they are considered to be serious runtime problems that cannot be\n * recovered from.)\n *\n * Params:\n *  expr = The expression asserted not to throw.\n *  msg = The message to include in the `AssertError` if the assumption turns\n *      out to be false.\n *  file = The source file name of the caller.\n *  line = The line number of the caller.\n *\n * Returns:\n *  The value of `expr`, if any.\n */\nT assumeWontThrow(T)(lazy T expr,\n                     string msg = null,\n                     string file = __FILE__,\n                     size_t line = __LINE__) nothrow\n{\n    import core.exception : AssertError;\n    try\n    {\n        return expr;\n    }\n    catch (Exception e)\n    {\n        import std.range.primitives : empty;\n        immutable tail = msg.empty ? \".\" : \": \" ~ msg;\n        throw new AssertError(\"assumeWontThrow failed: Expression did throw\" ~\n                              tail, file, line);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.math : sqrt;\n\n    // This function may throw.\n    int squareRoot(int x)\n    {\n        if (x < 0)\n            throw new Exception(\"Tried to take root of negative number\");\n        return cast(int) sqrt(cast(double) x);\n    }\n\n    // This function never throws.\n    int computeLength(int x, int y) nothrow\n    {\n        // Since x*x + y*y is always positive, we can safely assume squareRoot\n        // won't throw, and use it to implement this nothrow function. If it\n        // does throw (e.g., if x*x + y*y overflows a 32-bit value), then the\n        // program will terminate.\n        return assumeWontThrow(squareRoot(x*x + y*y));\n    }\n\n    assert(computeLength(3, 4) == 5);\n}\n\n@system unittest\n{\n    import core.exception : AssertError;\n\n    void alwaysThrows()\n    {\n        throw new Exception(\"I threw up\");\n    }\n    void bad() nothrow\n    {\n        assumeWontThrow(alwaysThrows());\n    }\n    assertThrown!AssertError(bad());\n}\n\n/**\nChecks whether a given source object contains pointers or references to a given\ntarget object.\n\nParams:\n    source = The source object\n    target = The target object\n\nBugs:\n    The function is explicitly annotated `@nogc` because inference could fail,\n    see $(LINK2 https://issues.dlang.org/show_bug.cgi?id=17084, issue 17084).\n\nReturns: `true` if `source`'s representation embeds a pointer\nthat points to `target`'s representation or somewhere inside\nit.\n\nIf `source` is or contains a dynamic array, then, then these functions will check\nif there is overlap between the dynamic array and `target`'s representation.\n\nIf `source` is a class, then it will be handled as a pointer.\n\nIf `target` is a pointer, a dynamic array or a class, then these functions will only\ncheck if `source` points to `target`, $(I not) what `target` references.\n\nIf `source` is or contains a union, then there may be either false positives or\nfalse negatives:\n\n`doesPointTo` will return `true` if it is absolutely certain\n`source` points to `target`. It may produce false negatives, but never\nfalse positives. This function should be prefered when trying to validate\ninput data.\n\n`mayPointTo` will return `false` if it is absolutely certain\n`source` does not point to `target`. It may produce false positives, but never\nfalse negatives. This function should be prefered for defensively choosing a\ncode path.\n\nNote: Evaluating $(D doesPointTo(x, x)) checks whether `x` has\ninternal pointers. This should only be done as an assertive test,\nas the language is free to assume objects don't have internal pointers\n(TDPL 7.1.3.5).\n*/\nbool doesPointTo(S, T, Tdummy=void)(auto ref const S source, ref const T target) @nogc @trusted pure nothrow\nif (__traits(isRef, source) || isDynamicArray!S ||\n    isPointer!S || is(S == class))\n{\n    static if (isPointer!S || is(S == class) || is(S == interface))\n    {\n        const m = *cast(void**) &source;\n        const b = cast(void*) &target;\n        const e = b + target.sizeof;\n        return b <= m && m < e;\n    }\n    else static if (is(S == struct) || is(S == union))\n    {\n        foreach (i, Subobj; typeof(source.tupleof))\n            static if (!isUnionAliased!(S, i))\n                if (doesPointTo(source.tupleof[i], target)) return true;\n        return false;\n    }\n    else static if (isStaticArray!S)\n    {\n        foreach (ref s; source)\n            if (doesPointTo(s, target)) return true;\n        return false;\n    }\n    else static if (isDynamicArray!S)\n    {\n        import std.array : overlap;\n        return overlap(cast(void[]) source, cast(void[])(&target)[0 .. 1]).length != 0;\n    }\n    else\n    {\n        return false;\n    }\n}\n\n// for shared objects\n/// ditto\nbool doesPointTo(S, T)(auto ref const shared S source, ref const shared T target) @trusted pure nothrow\n{\n    return doesPointTo!(shared S, shared T, void)(source, target);\n}\n\n/// ditto\nbool mayPointTo(S, T, Tdummy=void)(auto ref const S source, ref const T target) @trusted pure nothrow\nif (__traits(isRef, source) || isDynamicArray!S ||\n    isPointer!S || is(S == class))\n{\n    static if (isPointer!S || is(S == class) || is(S == interface))\n    {\n        const m = *cast(void**) &source;\n        const b = cast(void*) &target;\n        const e = b + target.sizeof;\n        return b <= m && m < e;\n    }\n    else static if (is(S == struct) || is(S == union))\n    {\n        foreach (i, Subobj; typeof(source.tupleof))\n            if (mayPointTo(source.tupleof[i], target)) return true;\n        return false;\n    }\n    else static if (isStaticArray!S)\n    {\n        foreach (size_t i; 0 .. S.length)\n            if (mayPointTo(source[i], target)) return true;\n        return false;\n    }\n    else static if (isDynamicArray!S)\n    {\n        import std.array : overlap;\n        return overlap(cast(void[]) source, cast(void[])(&target)[0 .. 1]).length != 0;\n    }\n    else\n    {\n        return false;\n    }\n}\n\n// for shared objects\n/// ditto\nbool mayPointTo(S, T)(auto ref const shared S source, ref const shared T target) @trusted pure nothrow\n{\n    return mayPointTo!(shared S, shared T, void)(source, target);\n}\n\n/// Pointers\n@system unittest\n{\n    int  i = 0;\n    int* p = null;\n    assert(!p.doesPointTo(i));\n    p = &i;\n    assert( p.doesPointTo(i));\n}\n\n/// Structs and Unions\n@system unittest\n{\n    struct S\n    {\n        int v;\n        int* p;\n    }\n    int i;\n    auto s = S(0, &i);\n\n    // structs and unions \"own\" their members\n    // pointsTo will answer true if one of the members pointsTo.\n    assert(!s.doesPointTo(s.v)); //s.v is just v member of s, so not pointed.\n    assert( s.p.doesPointTo(i)); //i is pointed by s.p.\n    assert( s  .doesPointTo(i)); //which means i is pointed by s itself.\n\n    // Unions will behave exactly the same. Points to will check each \"member\"\n    // individually, even if they share the same memory\n}\n\n/// Arrays (dynamic and static)\n@system unittest\n{\n    int i;\n    int* p = &i; // trick the compiler when initializing slicep; https://issues.dlang.org/show_bug.cgi?id=18637\n    int[]  slice = [0, 1, 2, 3, 4];\n    int[5] arr   = [0, 1, 2, 3, 4];\n    int*[]  slicep = [p];\n    int*[1] arrp   = [&i];\n\n    // A slice points to all of its members:\n    assert( slice.doesPointTo(slice[3]));\n    assert(!slice[0 .. 2].doesPointTo(slice[3])); // Object 3 is outside of the\n                                                  // slice [0 .. 2]\n\n    // Note that a slice will not take into account what its members point to.\n    assert( slicep[0].doesPointTo(i));\n    assert(!slicep   .doesPointTo(i));\n\n    // static arrays are objects that own their members, just like structs:\n    assert(!arr.doesPointTo(arr[0])); // arr[0] is just a member of arr, so not\n                                      // pointed.\n    assert( arrp[0].doesPointTo(i));  // i is pointed by arrp[0].\n    assert( arrp   .doesPointTo(i));  // which means i is pointed by arrp\n                                      // itself.\n\n    // Notice the difference between static and dynamic arrays:\n    assert(!arr  .doesPointTo(arr[0]));\n    assert( arr[].doesPointTo(arr[0]));\n    assert( arrp  .doesPointTo(i));\n    assert(!arrp[].doesPointTo(i));\n}\n\n/// Classes\n@system unittest\n{\n    class C\n    {\n        this(int* p){this.p = p;}\n        int* p;\n    }\n    int i;\n    C a = new C(&i);\n    C b = a;\n\n    // Classes are a bit particular, as they are treated like simple pointers\n    // to a class payload.\n    assert( a.p.doesPointTo(i)); // a.p points to i.\n    assert(!a  .doesPointTo(i)); // Yet a itself does not point i.\n\n    //To check the class payload itself, iterate on its members:\n    ()\n    {\n        import std.traits : Fields;\n\n        foreach (index, _; Fields!C)\n            if (doesPointTo(a.tupleof[index], i))\n                return;\n        assert(0);\n    }();\n\n    // To check if a class points a specific payload, a direct memmory check\n    // can be done:\n    auto aLoc = cast(ubyte[__traits(classInstanceSize, C)]*) a;\n    assert(b.doesPointTo(*aLoc)); // b points to where a is pointing\n}\n\n\nversion (unittest)\n{\n    // 17084 : the bug doesn't happen if these declarations are\n    // in the unittest block (static or not).\n    private struct Page17084\n    {\n        URL17084 url;\n        int opCmp(P)(P) { return 0; }\n        int opCmp(P)(shared(P)) shared { return 0; }\n    }\n\n    private struct URL17084\n    {\n        int[] queryParams;\n        string toString()() const { return \"\"; }\n        alias toString this;\n    }\n}\n\n@system unittest // Bugzilla 17084\n{\n    import std.algorithm.sorting : sort;\n    Page17084[] s;\n    sort(s);\n    shared(Page17084)[] p;\n    sort(p);\n}\n\n@system unittest\n{\n    struct S1 { int a; S1 * b; }\n    S1 a1;\n    S1 * p = &a1;\n    assert(doesPointTo(p, a1));\n\n    S1 a2;\n    a2.b = &a1;\n    assert(doesPointTo(a2, a1));\n\n    struct S3 { int[10] a; }\n    S3 a3;\n    auto a4 = a3.a[2 .. 3];\n    assert(doesPointTo(a4, a3));\n\n    auto a5 = new double[4];\n    auto a6 = a5[1 .. 2];\n    assert(!doesPointTo(a5, a6));\n\n    auto a7 = new double[3];\n    auto a8 = new double[][1];\n    a8[0] = a7;\n    assert(!doesPointTo(a8[0], a8[0]));\n\n    // don't invoke postblit on subobjects\n    {\n        static struct NoCopy { this(this) { assert(0); } }\n        static struct Holder { NoCopy a, b, c; }\n        Holder h;\n        cast(void) doesPointTo(h, h);\n    }\n\n    shared S3 sh3;\n    shared sh3sub = sh3.a[];\n    assert(doesPointTo(sh3sub, sh3));\n\n    int[] darr = [1, 2, 3, 4];\n\n    //dynamic arrays don't point to each other, or slices of themselves\n    assert(!doesPointTo(darr, darr));\n    assert(!doesPointTo(darr[0 .. 1], darr));\n\n    //But they do point their elements\n    foreach (i; 0 .. 4)\n        assert(doesPointTo(darr, darr[i]));\n    assert(doesPointTo(darr[0 .. 3], darr[2]));\n    assert(!doesPointTo(darr[0 .. 3], darr[3]));\n}\n\n@system unittest\n{\n    //tests with static arrays\n    //Static arrays themselves are just objects, and don't really *point* to anything.\n    //They aggregate their contents, much the same way a structure aggregates its attributes.\n    //*However* The elements inside the static array may themselves point to stuff.\n\n    //Standard array\n    int[2] k;\n    assert(!doesPointTo(k, k)); //an array doesn't point to itself\n    //Technically, k doesn't point its elements, although it does alias them\n    assert(!doesPointTo(k, k[0]));\n    assert(!doesPointTo(k, k[1]));\n    //But an extracted slice will point to the same array.\n    assert(doesPointTo(k[], k));\n    assert(doesPointTo(k[], k[1]));\n\n    //An array of pointers\n    int*[2] pp;\n    int a;\n    int b;\n    pp[0] = &a;\n    assert( doesPointTo(pp, a));  //The array contains a pointer to a\n    assert(!doesPointTo(pp, b));  //The array does NOT contain a pointer to b\n    assert(!doesPointTo(pp, pp)); //The array does not point itslef\n\n    //A struct containing a static array of pointers\n    static struct S\n    {\n        int*[2] p;\n    }\n    S s;\n    s.p[0] = &a;\n    assert( doesPointTo(s, a)); //The struct contains an array that points a\n    assert(!doesPointTo(s, b)); //But doesn't point b\n    assert(!doesPointTo(s, s)); //The struct doesn't actually point itslef.\n\n    //An array containing structs that have pointers\n    static struct SS\n    {\n        int* p;\n    }\n    SS[2] ss = [SS(&a), SS(null)];\n    assert( doesPointTo(ss, a));  //The array contains a struct that points to a\n    assert(!doesPointTo(ss, b));  //The array doesn't contains a struct that points to b\n    assert(!doesPointTo(ss, ss)); //The array doesn't point itself.\n}\n\n\n@system unittest //Unions\n{\n    int i;\n    union U //Named union\n    {\n        size_t asInt = 0;\n        int*   asPointer;\n    }\n    struct S\n    {\n        union //Anonymous union\n        {\n            size_t asInt = 0;\n            int*   asPointer;\n        }\n    }\n\n    U u;\n    S s;\n    assert(!doesPointTo(u, i));\n    assert(!doesPointTo(s, i));\n    assert(!mayPointTo(u, i));\n    assert(!mayPointTo(s, i));\n\n    u.asPointer = &i;\n    s.asPointer = &i;\n    assert(!doesPointTo(u, i));\n    assert(!doesPointTo(s, i));\n    assert( mayPointTo(u, i));\n    assert( mayPointTo(s, i));\n\n    u.asInt = cast(size_t)&i;\n    s.asInt = cast(size_t)&i;\n    assert(!doesPointTo(u, i));\n    assert(!doesPointTo(s, i));\n    assert( mayPointTo(u, i));\n    assert( mayPointTo(s, i));\n}\n\n@system unittest //Classes\n{\n    int i;\n    static class A\n    {\n        int* p;\n    }\n    A a = new A, b = a;\n    assert(!doesPointTo(a, b)); //a does not point to b\n    a.p = &i;\n    assert(!doesPointTo(a, i)); //a does not point to i\n}\n@safe unittest //alias this test\n{\n    static int i;\n    static int j;\n    struct S\n    {\n        int* p;\n        @property int* foo(){return &i;}\n        alias foo this;\n    }\n    assert(is(S : int*));\n    S s = S(&j);\n    assert(!doesPointTo(s, i));\n    assert( doesPointTo(s, j));\n    assert( doesPointTo(cast(int*) s, i));\n    assert(!doesPointTo(cast(int*) s, j));\n}\n@safe unittest //more alias this opCast\n{\n    void* p;\n    class A\n    {\n        void* opCast(T)() if (is(T == void*))\n        {\n            return p;\n        }\n        alias foo = opCast!(void*);\n        alias foo this;\n    }\n    assert(!doesPointTo(A.init, p));\n    assert(!mayPointTo(A.init, p));\n}\n\n/+\nReturns true if the field at index `i` in ($D T) shares its address with another field.\n\nNote: This does not merelly check if the field is a member of an union, but also that\nit is not a single child.\n+/\npackage enum isUnionAliased(T, size_t i) = isUnionAliasedImpl!T(T.tupleof[i].offsetof);\nprivate bool isUnionAliasedImpl(T)(size_t offset)\n{\n    int count = 0;\n    foreach (i, U; typeof(T.tupleof))\n        if (T.tupleof[i].offsetof == offset)\n            ++count;\n    return count >= 2;\n}\n//\n@safe unittest\n{\n    static struct S\n    {\n        int a0; //Not aliased\n        union\n        {\n            int a1; //Not aliased\n        }\n        union\n        {\n            int a2; //Aliased\n            int a3; //Aliased\n        }\n        union A4\n        {\n            int b0; //Not aliased\n        }\n        A4 a4;\n        union A5\n        {\n            int b0; //Aliased\n            int b1; //Aliased\n        }\n        A5 a5;\n    }\n\n    static assert(!isUnionAliased!(S, 0)); //a0;\n    static assert(!isUnionAliased!(S, 1)); //a1;\n    static assert( isUnionAliased!(S, 2)); //a2;\n    static assert( isUnionAliased!(S, 3)); //a3;\n    static assert(!isUnionAliased!(S, 4)); //a4;\n        static assert(!isUnionAliased!(S.A4, 0)); //a4.b0;\n    static assert(!isUnionAliased!(S, 5)); //a5;\n        static assert( isUnionAliased!(S.A5, 0)); //a5.b0;\n        static assert( isUnionAliased!(S.A5, 1)); //a5.b1;\n}\n\nversion (CRuntime_Glibc) version = GNU_STRERROR;\nversion (CRuntime_UClibc) version = GNU_STRERROR;\n\npackage string errnoString(int errno) nothrow @trusted\n{\n    import core.stdc.string : strlen;\n    version (GNU_STRERROR)\n    {\n        import core.stdc.string : strerror_r;\n        char[1024] buf = void;\n        auto s = strerror_r(errno, buf.ptr, buf.length);\n    }\n    else version (Posix)\n    {\n        // XSI-compliant\n        import core.stdc.string : strerror_r;\n        char[1024] buf = void;\n        const(char)* s;\n        if (strerror_r(errno, buf.ptr, buf.length) == 0)\n            s = buf.ptr;\n        else\n            return \"Unknown error\";\n    }\n    else\n    {\n        import core.stdc.string : strerror;\n        auto s = strerror(errno);\n    }\n    return s[0 .. s.strlen].idup;\n}\n\n/*********************\n * Thrown if errors that set `errno` occur.\n */\nclass ErrnoException : Exception\n{\n    final @property uint errno() { return _errno; } /// Operating system error code.\n    private uint _errno;\n    /// Constructor which takes an error message. The current global $(REF errno, core,stdc,errno) value is used as error code.\n    this(string msg, string file = null, size_t line = 0) @trusted\n    {\n        import core.stdc.errno : errno;\n        this(msg, errno, file, line);\n    }\n    /// Constructor which takes an error message and error code.\n    this(string msg, int errno, string file = null, size_t line = 0) @trusted\n    {\n        _errno = errno;\n        super(msg ~ \" (\" ~ errnoString(errno) ~ \")\", file, line);\n    }\n}\n\n///\n@system unittest\n{\n    import core.stdc.errno : EAGAIN;\n    auto ex = new ErrnoException(\"oh no\", EAGAIN);\n    assert(ex.errno == EAGAIN);\n}\n\n/// errno is used by default if no explicit error code is provided\n@system unittest\n{\n    import core.stdc.errno : errno, EAGAIN;\n\n    auto old = errno;\n    scope(exit) errno = old;\n\n    // fake that errno got set by the callee\n    errno = EAGAIN;\n    auto ex = new ErrnoException(\"oh no\");\n    assert(ex.errno == EAGAIN);\n}\n\n/++\n    ML-style functional exception handling. Runs the supplied expression and\n    returns its result. If the expression throws a `Throwable`, runs the\n    supplied error handler instead and return its result. The error handler's\n    type must be the same as the expression's type.\n\n    Params:\n        E            = The type of `Throwable`s to catch. Defaults to `Exception`\n        T1           = The type of the expression.\n        T2           = The return type of the error handler.\n        expression   = The expression to run and return its result.\n        errorHandler = The handler to run if the expression throwed.\n\n    Returns:\n        expression, if it does not throw. Otherwise, returns the result of\n        errorHandler.\n+/\n//lazy version\nCommonType!(T1, T2) ifThrown(E : Throwable = Exception, T1, T2)(lazy scope T1 expression, lazy scope T2 errorHandler)\n{\n    static assert(!is(typeof(return) == void),\n        \"The error handler's return value(\"\n        ~ T2.stringof ~\n        \") does not have a common type with the expression(\"\n        ~ T1.stringof ~\n        \").\"\n    );\n    try\n    {\n        return expression();\n    }\n    catch (E)\n    {\n        return errorHandler();\n    }\n}\n\n///ditto\n//delegate version\nCommonType!(T1, T2) ifThrown(E : Throwable, T1, T2)(lazy scope T1 expression, scope T2 delegate(E) errorHandler)\n{\n    static assert(!is(typeof(return) == void),\n        \"The error handler's return value(\"\n        ~ T2.stringof ~\n        \") does not have a common type with the expression(\"\n        ~ T1.stringof ~\n        \").\"\n    );\n    try\n    {\n        return expression();\n    }\n    catch (E e)\n    {\n        return errorHandler(e);\n    }\n}\n\n///ditto\n//delegate version, general overload to catch any Exception\nCommonType!(T1, T2) ifThrown(T1, T2)(lazy scope T1 expression, scope T2 delegate(Exception) errorHandler)\n{\n    static assert(!is(typeof(return) == void),\n        \"The error handler's return value(\"\n        ~ T2.stringof ~\n        \") does not have a common type with the expression(\"\n        ~ T1.stringof ~\n        \").\"\n    );\n    try\n    {\n        return expression();\n    }\n    catch (Exception e)\n    {\n        return errorHandler(e);\n    }\n}\n\n/// Revert to a default value upon an error:\n@safe unittest\n{\n    import std.conv : to;\n    assert(\"x\".to!int.ifThrown(0) == 0);\n}\n\n/**\nChain multiple calls to ifThrown, each capturing errors from the\nentire preceding expression.\n*/\n@safe unittest\n{\n    import std.conv : ConvException, to;\n    string s = \"true\";\n    assert(s.to!int.ifThrown(cast(int) s.to!double)\n                   .ifThrown(cast(int) s.to!bool) == 1);\n\n    s = \"2.0\";\n    assert(s.to!int.ifThrown(cast(int) s.to!double)\n                   .ifThrown(cast(int) s.to!bool) == 2);\n\n    // Respond differently to different types of errors\n    alias orFallback = (lazy a)  => a.ifThrown!ConvException(\"not a number\")\n                                     .ifThrown!Exception(\"number too small\");\n\n    assert(orFallback(enforce(\"x\".to!int < 1).to!string) == \"not a number\");\n    assert(orFallback(enforce(\"2\".to!int < 1).to!string) == \"number too small\");\n}\n\n/**\nThe expression and the errorHandler must have a common type they can both\nbe implicitly casted to, and that type will be the type of the compound\nexpression.\n*/\n@safe unittest\n{\n    // null and new Object have a common type(Object).\n    static assert(is(typeof(null.ifThrown(new Object())) == Object));\n    static assert(is(typeof((new Object()).ifThrown(null)) == Object));\n\n    // 1 and new Object do not have a common type.\n    static assert(!__traits(compiles, 1.ifThrown(new Object())));\n    static assert(!__traits(compiles, (new Object()).ifThrown(1)));\n}\n\n/// Use a lambda to get the thrown object.\n@system unittest\n{\n    import std.format : format;\n    assert(\"%s\".format.ifThrown!Exception(e => e.classinfo.name) == \"std.format.FormatException\");\n}\n\n//Verify Examples\n@system unittest\n{\n    import std.conv;\n    import std.string;\n    //Revert to a default value upon an error:\n    assert(\"x\".to!int().ifThrown(0) == 0);\n\n    //Chaining multiple calls to ifThrown to attempt multiple things in a row:\n    string s=\"true\";\n    assert(s.to!int().\n            ifThrown(cast(int) s.to!double()).\n            ifThrown(cast(int) s.to!bool())\n            == 1);\n\n    //Respond differently to different types of errors\n    assert(enforce(\"x\".to!int() < 1).to!string()\n            .ifThrown!ConvException(\"not a number\")\n            .ifThrown!Exception(\"number too small\")\n            == \"not a number\");\n\n    //null and new Object have a common type(Object).\n    static assert(is(typeof(null.ifThrown(new Object())) == Object));\n    static assert(is(typeof((new Object()).ifThrown(null)) == Object));\n\n    //1 and new Object do not have a common type.\n    static assert(!__traits(compiles, 1.ifThrown(new Object())));\n    static assert(!__traits(compiles, (new Object()).ifThrown(1)));\n\n    //Use a lambda to get the thrown object.\n    assert(\"%s\".format().ifThrown(e => e.classinfo.name) == \"std.format.FormatException\");\n}\n\n@system unittest\n{\n    import core.exception;\n    import std.conv;\n    import std.string;\n    //Basic behaviour - all versions.\n    assert(\"1\".to!int().ifThrown(0) == 1);\n    assert(\"x\".to!int().ifThrown(0) == 0);\n    assert(\"1\".to!int().ifThrown!ConvException(0) == 1);\n    assert(\"x\".to!int().ifThrown!ConvException(0) == 0);\n    assert(\"1\".to!int().ifThrown(e=>0) == 1);\n    assert(\"x\".to!int().ifThrown(e=>0) == 0);\n    static if (__traits(compiles, 0.ifThrown!Exception(e => 0))) //This will only work with a fix that was not yet pulled\n    {\n        assert(\"1\".to!int().ifThrown!ConvException(e=>0) == 1);\n        assert(\"x\".to!int().ifThrown!ConvException(e=>0) == 0);\n    }\n\n    //Exceptions other than stated not caught.\n    assert(\"x\".to!int().ifThrown!StringException(0).collectException!ConvException() !is null);\n    static if (__traits(compiles, 0.ifThrown!Exception(e => 0))) //This will only work with a fix that was not yet pulled\n    {\n        assert(\"x\".to!int().ifThrown!StringException(e=>0).collectException!ConvException() !is null);\n    }\n\n    //Default does not include errors.\n    int throwRangeError() { throw new RangeError; }\n    assert(throwRangeError().ifThrown(0).collectException!RangeError() !is null);\n    assert(throwRangeError().ifThrown(e=>0).collectException!RangeError() !is null);\n\n    //Incompatible types are not accepted.\n    static assert(!__traits(compiles, 1.ifThrown(new Object())));\n    static assert(!__traits(compiles, (new Object()).ifThrown(1)));\n    static assert(!__traits(compiles, 1.ifThrown(e=>new Object())));\n    static assert(!__traits(compiles, (new Object()).ifThrown(e=>1)));\n}\n\nversion (unittest) package\nvoid assertCTFEable(alias dg)()\n{\n    static assert({ cast(void) dg(); return true; }());\n    cast(void) dg();\n}\n\n/** This `enum` is used to select the primitives of the range to handle by the\n  $(LREF handle) range wrapper. The values of the `enum` can be `OR`'d to\n  select multiple primitives to be handled.\n\n  `RangePrimitive.access` is a shortcut for the access primitives; `front`,\n  `back` and `opIndex`.\n\n  `RangePrimitive.pop` is a shortcut for the mutating primitives;\n  `popFront` and `popBack`.\n */\nenum RangePrimitive\n{\n    front    = 0b00_0000_0001, ///\n    back     = 0b00_0000_0010, /// Ditto\n    popFront = 0b00_0000_0100, /// Ditto\n    popBack  = 0b00_0000_1000, /// Ditto\n    empty    = 0b00_0001_0000, /// Ditto\n    save     = 0b00_0010_0000, /// Ditto\n    length   = 0b00_0100_0000, /// Ditto\n    opDollar = 0b00_1000_0000, /// Ditto\n    opIndex  = 0b01_0000_0000, /// Ditto\n    opSlice  = 0b10_0000_0000, /// Ditto\n    access   = front | back | opIndex, /// Ditto\n    pop      = popFront | popBack, /// Ditto\n}\n\n///\npure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map, splitter;\n    import std.conv : to, ConvException;\n\n    auto s = \"12,1337z32,54,2,7,9,1z,6,8\";\n\n    // The next line composition will throw when iterated\n    // as some elements of the input do not convert to integer\n    auto r = s.splitter(',').map!(a => to!int(a));\n\n    // Substitute 0 for cases of ConvException\n    auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0);\n    assert(h.equal([12, 0, 54, 2, 7, 9, 0, 6, 8]));\n}\n\n///\npure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : retro;\n    import std.utf : UTFException;\n\n    auto str = \"hello\\xFFworld\"; // 0xFF is an invalid UTF-8 code unit\n\n    auto handled = str.handle!(UTFException, RangePrimitive.access,\n            (e, r) => ' '); // Replace invalid code points with spaces\n\n    assert(handled.equal(\"hello world\")); // `front` is handled,\n    assert(handled.retro.equal(\"dlrow olleh\")); // as well as `back`\n}\n\n/** Handle exceptions thrown from range primitives.\n\nUse the $(LREF RangePrimitive) enum to specify which primitives to _handle.\nMultiple range primitives can be handled at once by using the `OR` operator\nor the pseudo-primitives `RangePrimitive.access` and `RangePrimitive.pop`.\nAll handled primitives must have return types or values compatible with the\nuser-supplied handler.\n\nParams:\n    E = The type of `Throwable` to _handle.\n    primitivesToHandle = Set of range primitives to _handle.\n    handler = The callable that is called when a handled primitive throws a\n    `Throwable` of type `E`. The handler must accept arguments of\n    the form $(D E, ref IRange) and its return value is used as the primitive's\n    return value whenever `E` is thrown. For `opIndex`, the handler can\n    optionally recieve a third argument; the index that caused the exception.\n    input = The range to _handle.\n\nReturns: A wrapper `struct` that preserves the range interface of `input`.\n\nNote:\nInfinite ranges with slicing support must return an instance of\n$(REF Take, std,range) when sliced with a specific lower and upper\nbound (see $(REF hasSlicing, std,range,primitives)); `handle` deals with\nthis by `take`ing 0 from the return value of the handler function and\nreturning that when an exception is caught.\n*/\nauto handle(E : Throwable, RangePrimitive primitivesToHandle, alias handler, Range)(Range input)\nif (isInputRange!Range)\n{\n    static struct Handler\n    {\n        private Range range;\n\n        static if (isForwardRange!Range)\n        {\n            @property typeof(this) save()\n            {\n                static if (primitivesToHandle & RangePrimitive.save)\n                {\n                    try\n                    {\n                        return typeof(this)(range.save);\n                    }\n                    catch (E exception)\n                    {\n                        return typeof(this)(handler(exception, this.range));\n                    }\n                }\n                else\n                    return typeof(this)(range.save);\n            }\n        }\n\n        static if (isInfinite!Range)\n        {\n            enum bool empty = false;\n        }\n        else\n        {\n            @property bool empty()\n            {\n                static if (primitivesToHandle & RangePrimitive.empty)\n                {\n                    try\n                    {\n                        return this.range.empty;\n                    }\n                    catch (E exception)\n                    {\n                        return handler(exception, this.range);\n                    }\n                }\n                else\n                    return this.range.empty;\n            }\n        }\n\n        @property auto ref front()\n        {\n            static if (primitivesToHandle & RangePrimitive.front)\n            {\n                try\n                {\n                    return this.range.front;\n                }\n                catch (E exception)\n                {\n                    return handler(exception, this.range);\n                }\n            }\n            else\n                return this.range.front;\n        }\n\n        void popFront()\n        {\n            static if (primitivesToHandle & RangePrimitive.popFront)\n            {\n                try\n                {\n                    this.range.popFront();\n                }\n                catch (E exception)\n                {\n                    handler(exception, this.range);\n                }\n            }\n            else\n                this.range.popFront();\n        }\n\n        static if (isBidirectionalRange!Range)\n        {\n            @property auto ref back()\n            {\n                static if (primitivesToHandle & RangePrimitive.back)\n                {\n                    try\n                    {\n                        return this.range.back;\n                    }\n                    catch (E exception)\n                    {\n                        return handler(exception, this.range);\n                    }\n                }\n                else\n                    return this.range.back;\n            }\n\n            void popBack()\n            {\n                static if (primitivesToHandle & RangePrimitive.popBack)\n                {\n                    try\n                    {\n                        this.range.popBack();\n                    }\n                    catch (E exception)\n                    {\n                        handler(exception, this.range);\n                    }\n                }\n                else\n                    this.range.popBack();\n            }\n        }\n\n        static if (isRandomAccessRange!Range)\n        {\n            auto ref opIndex(size_t index)\n            {\n                static if (primitivesToHandle & RangePrimitive.opIndex)\n                {\n                    try\n                    {\n                        return this.range[index];\n                    }\n                    catch (E exception)\n                    {\n                        static if (__traits(compiles, handler(exception, this.range, index)))\n                            return handler(exception, this.range, index);\n                        else\n                            return handler(exception, this.range);\n                    }\n                }\n                else\n                    return this.range[index];\n            }\n        }\n\n        static if (hasLength!Range)\n        {\n            @property auto length()\n            {\n                static if (primitivesToHandle & RangePrimitive.length)\n                {\n                    try\n                    {\n                        return this.range.length;\n                    }\n                    catch (E exception)\n                    {\n                        return handler(exception, this.range);\n                    }\n                }\n                else\n                    return this.range.length;\n            }\n        }\n\n        static if (hasSlicing!Range)\n        {\n            static if (hasLength!Range)\n            {\n                typeof(this) opSlice(size_t lower, size_t upper)\n                {\n                    static if (primitivesToHandle & RangePrimitive.opSlice)\n                    {\n                        try\n                        {\n                            return typeof(this)(this.range[lower .. upper]);\n                        }\n                        catch (E exception)\n                        {\n                            return typeof(this)(handler(exception, this.range));\n                        }\n                    }\n                    else\n                        return typeof(this)(this.range[lower .. upper]);\n                }\n            }\n            else static if (is(typeof(Range.init[size_t.init .. $])))\n            {\n                import std.range : Take, takeExactly;\n                static struct DollarToken {}\n                enum opDollar = DollarToken.init;\n\n                typeof(this) opSlice(size_t lower, DollarToken)\n                {\n                    static if (primitivesToHandle & RangePrimitive.opSlice)\n                    {\n                        try\n                        {\n                            return typeof(this)(this.range[lower .. $]);\n                        }\n                        catch (E exception)\n                        {\n                            return typeof(this)(handler(exception, this.range));\n                        }\n                    }\n                    else\n                        return typeof(this)(this.range[lower .. $]);\n                }\n\n                Take!Handler opSlice(size_t lower, size_t upper)\n                {\n                    static if (primitivesToHandle & RangePrimitive.opSlice)\n                    {\n                        try\n                        {\n                            return takeExactly(typeof(this)(this.range[lower .. $]), upper - 1);\n                        }\n                        catch (E exception)\n                        {\n                            return takeExactly(typeof(this)(handler(exception, this.range)), 0);\n                        }\n                    }\n                    else\n                        return takeExactly(typeof(this)(this.range[lower .. $]), upper - 1);\n                }\n            }\n        }\n    }\n\n    return Handler(input);\n}\n\n///\npure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map, splitter;\n    import std.conv : to, ConvException;\n\n    auto s = \"12,1337z32,54,2,7,9,1z,6,8\";\n\n    // The next line composition will throw when iterated\n    // as some elements of the input do not convert to integer\n    auto r = s.splitter(',').map!(a => to!int(a));\n\n    // Substitute 0 for cases of ConvException\n    auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0);\n    assert(h.equal([12, 0, 54, 2, 7, 9, 0, 6, 8]));\n}\n\n///\npure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : retro;\n    import std.utf : UTFException;\n\n    auto str = \"hello\\xFFworld\"; // 0xFF is an invalid UTF-8 code unit\n\n    auto handled = str.handle!(UTFException, RangePrimitive.access,\n            (e, r) => ' '); // Replace invalid code points with spaces\n\n    assert(handled.equal(\"hello world\")); // `front` is handled,\n    assert(handled.retro.equal(\"dlrow olleh\")); // as well as `back`\n}\n\npure nothrow @safe unittest\n{\n    static struct ThrowingRange\n    {\n        pure @safe:\n        @property bool empty()\n        {\n            throw new Exception(\"empty has thrown\");\n        }\n\n        @property int front()\n        {\n            throw new Exception(\"front has thrown\");\n        }\n\n        @property int back()\n        {\n            throw new Exception(\"back has thrown\");\n        }\n\n        void popFront()\n        {\n            throw new Exception(\"popFront has thrown\");\n        }\n\n        void popBack()\n        {\n            throw new Exception(\"popBack has thrown\");\n        }\n\n        int opIndex(size_t)\n        {\n            throw new Exception(\"opIndex has thrown\");\n        }\n\n        ThrowingRange opSlice(size_t, size_t)\n        {\n            throw new Exception(\"opSlice has thrown\");\n        }\n\n        @property size_t length()\n        {\n            throw new Exception(\"length has thrown\");\n        }\n\n        alias opDollar = length;\n\n        @property ThrowingRange save()\n        {\n            throw new Exception(\"save has thrown\");\n        }\n    }\n\n    static assert(isInputRange!ThrowingRange);\n    static assert(isForwardRange!ThrowingRange);\n    static assert(isBidirectionalRange!ThrowingRange);\n    static assert(hasSlicing!ThrowingRange);\n    static assert(hasLength!ThrowingRange);\n\n    auto f = ThrowingRange();\n    auto fb = f.handle!(Exception, RangePrimitive.front | RangePrimitive.back,\n            (e, r) => -1)();\n    assert(fb.front == -1);\n    assert(fb.back == -1);\n    assertThrown(fb.popFront());\n    assertThrown(fb.popBack());\n    assertThrown(fb.empty);\n    assertThrown(fb.save);\n    assertThrown(fb[0]);\n\n    auto accessRange = f.handle!(Exception, RangePrimitive.access,\n            (e, r) => -1);\n    assert(accessRange.front == -1);\n    assert(accessRange.back == -1);\n    assert(accessRange[0] == -1);\n    assertThrown(accessRange.popFront());\n    assertThrown(accessRange.popBack());\n\n    auto pfb = f.handle!(Exception, RangePrimitive.pop, (e, r) => -1)();\n\n    pfb.popFront(); // this would throw otherwise\n    pfb.popBack(); // this would throw otherwise\n\n    auto em = f.handle!(Exception,\n            RangePrimitive.empty, (e, r) => false)();\n\n    assert(!em.empty);\n\n    auto arr = f.handle!(Exception,\n            RangePrimitive.opIndex, (e, r) => 1337)();\n\n    assert(arr[0] == 1337);\n\n    auto arr2 = f.handle!(Exception,\n            RangePrimitive.opIndex, (e, r, i) => i)();\n\n    assert(arr2[0] == 0);\n    assert(arr2[1337] == 1337);\n\n    auto save = f.handle!(Exception,\n        RangePrimitive.save,\n        function(Exception e, ref ThrowingRange r) {\n            return ThrowingRange();\n        })();\n\n    save.save;\n\n    auto slice = f.handle!(Exception,\n        RangePrimitive.opSlice, (e, r) => ThrowingRange())();\n\n    auto sliced = slice[0 .. 1337]; // this would throw otherwise\n\n    static struct Infinite\n    {\n        import std.range : Take;\n        pure @safe:\n        enum bool empty = false;\n        int front() { assert(false); }\n        void popFront() { assert(false); }\n        Infinite save() @property { assert(false); }\n        static struct DollarToken {}\n        enum opDollar = DollarToken.init;\n        Take!Infinite opSlice(size_t, size_t) { assert(false); }\n        Infinite opSlice(size_t, DollarToken)\n        {\n            throw new Exception(\"opSlice has thrown\");\n        }\n    }\n\n    static assert(isInputRange!Infinite);\n    static assert(isInfinite!Infinite);\n    static assert(hasSlicing!Infinite);\n\n    assertThrown(Infinite()[0 .. $]);\n\n    auto infinite = Infinite.init.handle!(Exception,\n        RangePrimitive.opSlice, (e, r) => Infinite())();\n\n    auto infSlice = infinite[0 .. $]; // this would throw otherwise\n}\n\n\n/++\n    Convenience mixin for trivially sub-classing exceptions\n\n    Even trivially sub-classing an exception involves writing boilerplate code\n    for the constructor to: 1$(RPAREN) correctly pass in the source file and line number\n    the exception was thrown from; 2$(RPAREN) be usable with $(LREF enforce) which\n    expects exception constructors to take arguments in a fixed order. This\n    mixin provides that boilerplate code.\n\n    Note however that you need to mark the $(B mixin) line with at least a\n    minimal (i.e. just $(B ///)) DDoc comment if you want the mixed-in\n    constructors to be documented in the newly created Exception subclass.\n\n    $(RED Current limitation): Due to\n    $(LINK2 https://issues.dlang.org/show_bug.cgi?id=11500, bug #11500),\n    currently the constructors specified in this mixin cannot be overloaded with\n    any other custom constructors. Thus this mixin can currently only be used\n    when no such custom constructors need to be explicitly specified.\n +/\nmixin template basicExceptionCtors()\n{\n    /++\n        Params:\n            msg  = The message for the exception.\n            file = The file where the exception occurred.\n            line = The line number where the exception occurred.\n            next = The previous exception in the chain of exceptions, if any.\n    +/\n    this(string msg, string file = __FILE__, size_t line = __LINE__,\n         Throwable next = null) @nogc @safe pure nothrow\n    {\n        super(msg, file, line, next);\n    }\n\n    /++\n        Params:\n            msg  = The message for the exception.\n            next = The previous exception in the chain of exceptions.\n            file = The file where the exception occurred.\n            line = The line number where the exception occurred.\n    +/\n    this(string msg, Throwable next, string file = __FILE__,\n         size_t line = __LINE__) @nogc @safe pure nothrow\n    {\n        super(msg, file, line, next);\n    }\n}\n\n///\n@safe unittest\n{\n    class MeaCulpa: Exception\n    {\n        ///\n        mixin basicExceptionCtors;\n    }\n\n    try\n        throw new MeaCulpa(\"test\");\n    catch (MeaCulpa e)\n    {\n        assert(e.msg == \"test\");\n        assert(e.file == __FILE__);\n        assert(e.line == __LINE__ - 5);\n    }\n}\n\n@safe pure nothrow unittest\n{\n    class TestException : Exception { mixin basicExceptionCtors; }\n    auto e = new Exception(\"msg\");\n    auto te1 = new TestException(\"foo\");\n    auto te2 = new TestException(\"foo\", e);\n}\n\n@safe unittest\n{\n    class TestException : Exception { mixin basicExceptionCtors; }\n    auto e = new Exception(\"!!!\");\n\n    auto te1 = new TestException(\"message\", \"file\", 42, e);\n    assert(te1.msg == \"message\");\n    assert(te1.file == \"file\");\n    assert(te1.line == 42);\n    assert(te1.next is e);\n\n    auto te2 = new TestException(\"message\", e, \"file\", 42);\n    assert(te2.msg == \"message\");\n    assert(te2.file == \"file\");\n    assert(te2.line == 42);\n    assert(te2.next is e);\n\n    auto te3 = new TestException(\"foo\");\n    assert(te3.msg == \"foo\");\n    assert(te3.file == __FILE__);\n    assert(te3.line == __LINE__ - 3);\n    assert(te3.next is null);\n\n    auto te4 = new TestException(\"foo\", e);\n    assert(te4.msg == \"foo\");\n    assert(te4.file == __FILE__);\n    assert(te4.line == __LINE__ - 3);\n    assert(te4.next is e);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/all.d",
    "content": "/++\nConvenience file that allows to import entire Phobos in one command.\n+/\nmodule std.experimental.all;\n\n///\n@safe unittest\n{\n    import std.experimental.all;\n\n    int len;\n    const r = 6.iota\n              .filter!(a => a % 2) // 1 3 5\n              .map!(a => a * 2) // 2 6 10\n              .tee!(_ => len++)\n              .sum\n              .reverseArgs!format(\"Sum: %d\");\n\n    assert(len == 3);\n    assert(r == \"Sum: 18\");\n}\n\n///\n@safe unittest\n{\n    import std.experimental.all;\n    assert(10.iota.map!(partial!(pow, 2)).sum == 1023);\n}\n\npublic import std.algorithm;\npublic import std.array;\npublic import std.ascii;\npublic import std.base64;\npublic import std.bigint;\npublic import std.bitmanip;\npublic import std.compiler;\npublic import std.complex;\npublic import std.concurrency;\npublic import std.container;\npublic import std.conv;\npublic import std.csv;\npublic import std.datetime;\npublic import std.demangle;\npublic import std.digest;\npublic import std.encoding;\npublic import std.exception;\npublic import std.file;\npublic import std.format;\npublic import std.functional;\npublic import std.getopt;\npublic import std.json;\npublic import std.math;\npublic import std.mathspecial;\npublic import std.meta;\npublic import std.mmfile;\npublic import std.net.curl;\npublic import std.numeric;\npublic import std.outbuffer;\npublic import std.parallelism;\npublic import std.path;\npublic import std.process;\npublic import std.random;\npublic import std.range;\npublic import std.regex;\npublic import std.signals;\npublic import std.socket;\npublic import std.stdint;\npublic import std.stdio;\npublic import std.string;\npublic import std.system;\npublic import std.traits;\npublic import std.typecons;\n//public import std.typetuple; // this module is undocumented and about to be deprecated\npublic import std.uni;\npublic import std.uri;\npublic import std.utf;\npublic import std.uuid;\npublic import std.variant;\npublic import std.xml;\npublic import std.zip;\npublic import std.zlib;\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/affix_allocator.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/affix_allocator.d)\n*/\nmodule std.experimental.allocator.building_blocks.affix_allocator;\n\n/**\n\nAllocator that adds some extra data before (of type `Prefix`) and/or after\n(of type `Suffix`) any allocation made with its parent allocator. This is\nuseful for uses where additional allocation-related information is needed, such\nas mutexes, reference counts, or walls for debugging memory corruption errors.\n\nIf `Prefix` is not `void`, `Allocator` must guarantee an alignment at\nleast as large as `Prefix.alignof`.\n\nSuffixes are slower to get at because of alignment rounding, so prefixes should\nbe preferred. However, small prefixes blunt the alignment so if a large\nalignment with a small affix is needed, suffixes should be chosen.\n\nThe following methods are defined if `Allocator` defines them, and forward to it: `deallocateAll`, `empty`, `owns`.\n */\nstruct AffixAllocator(Allocator, Prefix, Suffix = void)\n{\n    import std.algorithm.comparison : min;\n    import std.conv : emplace;\n    import std.experimental.allocator : RCIAllocator, theAllocator;\n    import std.experimental.allocator.common : stateSize, forwardToMember,\n        roundUpToMultipleOf, alignedAt, alignDownTo, roundUpToMultipleOf,\n        hasStaticallyKnownAlignment;\n    import std.math : isPowerOf2;\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n\n    static if (hasStaticallyKnownAlignment!Allocator)\n    {\n        static assert(\n                !stateSize!Prefix || Allocator.alignment >= Prefix.alignof,\n                \"AffixAllocator does not work with allocators offering a smaller\"\n                ~ \" alignment than the prefix alignment.\");\n    }\n    static assert(alignment % Suffix.alignof == 0,\n        \"This restriction could be relaxed in the future.\");\n\n    /**\n    If `Prefix` is `void`, the alignment is that of the parent. Otherwise, the alignment is the same as the `Prefix`'s alignment.\n    */\n    static if (hasStaticallyKnownAlignment!Allocator)\n    {\n        enum uint alignment = isPowerOf2(stateSize!Prefix)\n            ? min(stateSize!Prefix, Allocator.alignment)\n            : (stateSize!Prefix ? Prefix.alignof : Allocator.alignment);\n    }\n    else static if (is(Prefix == void))\n    {\n        enum uint alignment = platformAlignment;\n    }\n    else\n    {\n        enum uint alignment = Prefix.alignof;\n    }\n\n    /**\n    If the parent allocator `Allocator` is stateful, an instance of it is\n    stored as a member. Otherwise, `AffixAllocator` uses\n    `Allocator.instance`. In either case, the name `_parent` is uniformly\n    used for accessing the parent allocator.\n    */\n    static if (stateSize!Allocator)\n    {\n        Allocator _parent;\n        static if (is(Allocator == RCIAllocator))\n        {\n            @nogc nothrow pure @safe\n            Allocator parent()\n            {\n                static @nogc nothrow\n                RCIAllocator wrapAllocatorObject()\n                {\n                    import std.experimental.allocator.gc_allocator : GCAllocator;\n                    import std.experimental.allocator : allocatorObject;\n\n                    return allocatorObject(GCAllocator.instance);\n                }\n\n                if (_parent.isNull)\n                {\n                    // If the `_parent` allocator is `null` we will assign\n                    // an object that references the GC as the `parent`.\n                    auto fn = (() @trusted =>\n                            cast(RCIAllocator function() @nogc nothrow pure @safe)(&wrapAllocatorObject))();\n                    _parent = fn();\n                }\n\n                // `RCIAllocator.alignment` currently doesn't have any attributes\n                // so we must cast; throughout the allocators module, `alignment`\n                // is defined as an `enum` for the existing allocators.\n                // `alignment` should always be `@nogc nothrow pure @safe`; once\n                // this is enforced by the interface we can remove the cast\n                auto pureAlign = (() @trusted =>\n                        cast(uint delegate() @nogc nothrow pure @safe)(&_parent.alignment))();\n                assert(alignment <= pureAlign());\n                return _parent;\n            }\n        }\n        else\n        {\n            alias parent = _parent;\n        }\n    }\n    else\n    {\n        alias parent = Allocator.instance;\n    }\n\n    private template Impl()\n    {\n\n        size_t goodAllocSize(size_t s)\n        {\n            import std.experimental.allocator.common : goodAllocSize;\n            auto a = actualAllocationSize(s);\n            return roundUpToMultipleOf(parent.goodAllocSize(a)\n                    - stateSize!Prefix - stateSize!Suffix,\n                this.alignment);\n        }\n\n        private size_t actualAllocationSize(size_t s) const\n        {\n            assert(s > 0);\n            static if (!stateSize!Suffix)\n            {\n                return s + stateSize!Prefix;\n            }\n            else\n            {\n                return\n                    roundUpToMultipleOf(s + stateSize!Prefix, Suffix.alignof)\n                    + stateSize!Suffix;\n            }\n        }\n\n        private void[] actualAllocation(void[] b) const\n        {\n            assert(b !is null);\n            return (b.ptr - stateSize!Prefix)\n                [0 .. actualAllocationSize(b.length)];\n        }\n\n        // Common code shared between allocate and allocateZeroed.\n        private enum _processAndReturnAllocateResult =\n        q{\n            if (result is null) return null;\n            static if (stateSize!Prefix)\n            {\n                assert(result.ptr.alignedAt(Prefix.alignof));\n                emplace!Prefix(cast(Prefix*) result.ptr);\n            }\n            static if (stateSize!Suffix)\n            {\n                auto suffixP = result.ptr + result.length - Suffix.sizeof;\n                assert(suffixP.alignedAt(Suffix.alignof));\n                emplace!Suffix(cast(Suffix*)(suffixP));\n            }\n            return result[stateSize!Prefix .. stateSize!Prefix + bytes];\n        };\n\n        void[] allocate(size_t bytes)\n        {\n            if (!bytes) return null;\n            auto result = parent.allocate(actualAllocationSize(bytes));\n            mixin(_processAndReturnAllocateResult);\n        }\n\n        static if (hasMember!(Allocator, \"allocateZeroed\"))\n        package(std) void[] allocateZeroed()(size_t bytes)\n        {\n            if (!bytes) return null;\n            auto result = parent.allocateZeroed(actualAllocationSize(bytes));\n            mixin(_processAndReturnAllocateResult);\n        }\n\n        static if (hasMember!(Allocator, \"allocateAll\"))\n        void[] allocateAll()\n        {\n            auto result = parent.allocateAll();\n            if (result is null) return null;\n            if (result.length < actualAllocationSize(1))\n            {\n                deallocate(result);\n                return null;\n            }\n            static if (stateSize!Prefix)\n            {\n                assert(result.length > stateSize!Prefix);\n                emplace!Prefix(cast(Prefix*) result.ptr);\n                result = result[stateSize!Prefix .. $];\n            }\n            static if (stateSize!Suffix)\n            {\n                assert(result.length > stateSize!Suffix);\n                // Ehm, find a properly aligned place for the suffix\n                auto p = (result.ptr + result.length - stateSize!Suffix)\n                    .alignDownTo(Suffix.alignof);\n                assert(p > result.ptr);\n                emplace!Suffix(cast(Suffix*) p);\n                result = result[0 .. p - result.ptr];\n            }\n            return result;\n        }\n\n        static if (hasMember!(Allocator, \"owns\"))\n        Ternary owns(void[] b)\n        {\n            if (b is null) return Ternary.no;\n            return parent.owns((() @trusted => actualAllocation(b))());\n        }\n\n        static if (hasMember!(Allocator, \"resolveInternalPointer\"))\n        Ternary resolveInternalPointer(const void* p, ref void[] result)\n        {\n            void[] p1;\n            Ternary r = parent.resolveInternalPointer(p, p1);\n            if (r != Ternary.yes || p1 is null)\n                return r;\n            p1 = p1[stateSize!Prefix .. $];\n            auto p2 = (() @trusted => (&p1[0] + p1.length - stateSize!Suffix)\n                                      .alignDownTo(Suffix.alignof))();\n            result = p1[0 .. p2 - &p1[0]];\n            return Ternary.yes;\n        }\n\n        static if (!stateSize!Suffix && hasMember!(Allocator, \"expand\")\n                    && hasMember!(Allocator, \"owns\"))\n        bool expand(ref void[] b, size_t delta)\n        {\n            if (!b || delta == 0) return delta == 0;\n            if (owns(b) == Ternary.no) return false;\n            auto t = (() @trusted => actualAllocation(b))();\n            const result = parent.expand(t, delta);\n            if (!result) return false;\n            b = (() @trusted => b.ptr[0 .. b.length + delta])();\n            return true;\n        }\n\n        static if (hasMember!(Allocator, \"reallocate\"))\n        bool reallocate(ref void[] b, size_t s)\n        {\n            if (b is null)\n            {\n                b = allocate(s);\n                return b.length == s;\n            }\n            auto t = actualAllocation(b);\n            const result = parent.reallocate(t, actualAllocationSize(s));\n            if (!result) return false; // no harm done\n            b = t.ptr[stateSize!Prefix .. stateSize!Prefix + s];\n            return true;\n        }\n\n        static if (hasMember!(Allocator, \"deallocate\"))\n        bool deallocate(void[] b)\n        {\n            if (!b.ptr) return true;\n            return parent.deallocate(actualAllocation(b));\n        }\n\n        /* The following methods are defined if `ParentAllocator` defines\n        them, and forward to it: `deallocateAll`, `empty`.*/\n        mixin(forwardToMember(\"parent\",\n            \"deallocateAll\", \"empty\"));\n\n        // Computes suffix type given buffer type\n        private template Payload2Affix(Payload, Affix)\n        {\n            static if (is(Payload[] : void[]))\n                alias Payload2Affix = Affix;\n            else static if (is(Payload[] : shared(void)[]))\n                alias Payload2Affix = shared Affix;\n            else static if (is(Payload[] : immutable(void)[]))\n                alias Payload2Affix = shared Affix;\n            else static if (is(Payload[] : const(shared(void))[]))\n                alias Payload2Affix = shared Affix;\n            else static if (is(Payload[] : const(void)[]))\n                alias Payload2Affix = const Affix;\n            else\n                static assert(0, \"Internal error for type \" ~ Payload.stringof);\n        }\n\n        // Extra functions\n        static if (stateSize!Prefix)\n        {\n            static auto ref prefix(T)(T[] b)\n            {\n                assert(b.ptr && b.ptr.alignedAt(Prefix.alignof));\n                return (cast(Payload2Affix!(T, Prefix)*) b.ptr)[-1];\n            }\n        }\n        static if (stateSize!Suffix)\n            auto ref suffix(T)(T[] b)\n            {\n                assert(b.ptr);\n                auto p = b.ptr - stateSize!Prefix\n                    + actualAllocationSize(b.length);\n                assert(p && p.alignedAt(Suffix.alignof));\n                return (cast(Payload2Affix!(T, Suffix)*) p)[-1];\n            }\n    }\n\n    version (StdDdoc)\n    {\n        /**\n        Standard allocator methods. Each is defined if and only if the parent\n        allocator defines the homonym method (except for `goodAllocSize`,\n        which may use the global default). Also, the methods will be $(D\n        shared) if the parent allocator defines them as such.\n        */\n        size_t goodAllocSize(size_t);\n        /// Ditto\n        void[] allocate(size_t);\n        /// Ditto\n        Ternary owns(void[]);\n        /// Ditto\n        bool expand(ref void[] b, size_t delta);\n        /// Ditto\n        bool reallocate(ref void[] b, size_t s);\n        /// Ditto\n        bool deallocate(void[] b);\n        /// Ditto\n        bool deallocateAll();\n        /// Ditto\n        Ternary empty();\n\n        /**\n        The `instance` singleton is defined if and only if the parent allocator\n        has no state and defines its own `it` object.\n        */\n        static AffixAllocator instance;\n\n        /**\n        Affix access functions offering references to the affixes of a\n        block `b` previously allocated with this allocator. `b` may not be null.\n        They are defined if and only if the corresponding affix is not `void`.\n\n        The qualifiers of the affix are not always the same as the qualifiers\n        of the argument. This is because the affixes are not part of the data\n        itself, but instead are just $(I associated) with the data and known\n        to the allocator. The table below documents the type of `preffix(b)` and\n        `affix(b)` depending on the type of `b`.\n\n        $(BOOKTABLE Result of `prefix`/`suffix` depending on argument (`U` is\n        any unqualified type, `Affix` is `Prefix` or `Suffix`),\n            $(TR $(TH Argument$(NBSP)Type) $(TH Return) $(TH Comments))\n\n            $(TR $(TD `shared(U)[]`) $(TD `ref shared Affix`)\n            $(TD Data is shared across threads and the affix follows suit.))\n\n            $(TR $(TD `immutable(U)[]`) $(TD `ref shared Affix`)\n            $(TD Although the data is immutable, the allocator \"knows\" the\n            underlying memory is mutable, so `immutable` is elided for the affix\n            which is independent from the data itself. However, the result is\n            `shared` because `immutable` is implicitly shareable so multiple\n            threads may access and manipulate the affix for the same data.))\n\n            $(TR $(TD `const(shared(U))[]`) $(TD `ref shared Affix`)\n            $(TD The data is always shareable across threads. Even if the data\n            is `const`, the affix is modifiable by the same reasoning as for\n            `immutable`.))\n\n            $(TR $(TD `const(U)[]`) $(TD `ref const Affix`)\n            $(TD The input may have originated from `U[]` or `immutable(U)[]`,\n            so it may be actually shared or not. Returning an unqualified affix\n            may result in race conditions, whereas returning a `shared` affix\n            may result in inadvertent sharing of mutable thread-local data\n            across multiple threads. So the returned type is conservatively\n            `ref const`.))\n\n            $(TR $(TD `U[]`) $(TD `ref Affix`)\n            $(TD Unqualified data has unqualified affixes.))\n        )\n\n        Precondition: `b !is null` and `b` must have been allocated with\n        this allocator.\n        */\n        static ref auto prefix(T)(T[] b);\n        /// Ditto\n        ref auto suffix(T)(T[] b);\n    }\n    else static if (is(typeof(Allocator.instance) == shared))\n    {\n        static assert(stateSize!Allocator == 0);\n        static shared AffixAllocator instance;\n        shared { mixin Impl!(); }\n    }\n    else static if (is(Allocator == shared))\n    {\n        static assert(stateSize!Allocator != 0);\n        shared { mixin Impl!(); }\n    }\n    else\n    {\n        mixin Impl!();\n        static if (stateSize!Allocator == 0)\n            __gshared AffixAllocator instance;\n    }\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    // One word before and after each allocation.\n    alias A = AffixAllocator!(Mallocator, size_t, size_t);\n    auto b = A.instance.allocate(11);\n    A.instance.prefix(b) = 0xCAFE_BABE;\n    A.instance.suffix(b) = 0xDEAD_BEEF;\n    assert(A.instance.prefix(b) == 0xCAFE_BABE\n        && A.instance.suffix(b) == 0xDEAD_BEEF);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator : theAllocator, RCIAllocator;\n\n    // One word before and after each allocation.\n    auto A = AffixAllocator!(RCIAllocator, size_t, size_t)(theAllocator);\n    auto a = A.allocate(11);\n    A.prefix(a) = 0xCAFE_BABE;\n    A.suffix(a) = 0xDEAD_BEEF;\n    assert(A.prefix(a) == 0xCAFE_BABE\n        && A.suffix(a) == 0xDEAD_BEEF);\n\n    // One word before and after each allocation.\n    auto B = AffixAllocator!(RCIAllocator, size_t, size_t)();\n    auto b = B.allocate(11);\n    B.prefix(b) = 0xCAFE_BABE;\n    B.suffix(b) = 0xDEAD_BEEF;\n    assert(B.prefix(b) == 0xCAFE_BABE\n        && B.suffix(b) == 0xDEAD_BEEF);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.bitmapped_block\n        : BitmappedBlock;\n    import std.experimental.allocator.common : testAllocator;\n    testAllocator!({\n        auto a = AffixAllocator!(BitmappedBlock!128, ulong, ulong)\n            (BitmappedBlock!128(new ubyte[128 * 4096]));\n        return a;\n    });\n}\n\n// Test empty\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlock;\n    import std.typecons : Ternary;\n\n    auto a = AffixAllocator!(BitmappedBlock!128, ulong, ulong)\n                (BitmappedBlock!128(new ubyte[128 * 4096]));\n    assert((() pure nothrow @safe @nogc => a.empty)() == Ternary.yes);\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    assert((() pure nothrow @safe @nogc => a.empty)() == Ternary.no);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    alias A = AffixAllocator!(Mallocator, size_t);\n    auto b = A.instance.allocate(10);\n    A.instance.prefix(b) = 10;\n    assert(A.instance.prefix(b) == 10);\n\n    import std.experimental.allocator.building_blocks.null_allocator\n        : NullAllocator;\n    alias B = AffixAllocator!(NullAllocator, size_t);\n    b = B.instance.allocate(100);\n    assert(b is null);\n}\n\n@system unittest\n{\n    import std.experimental.allocator;\n    import std.experimental.allocator.gc_allocator;\n    import std.typecons : Ternary;\n    alias MyAllocator = AffixAllocator!(GCAllocator, uint);\n    auto a = MyAllocator.instance.makeArray!(shared int)(100);\n    static assert(is(typeof(&MyAllocator.instance.prefix(a)) == shared(uint)*));\n    auto b = MyAllocator.instance.makeArray!(shared const int)(100);\n    static assert(is(typeof(&MyAllocator.instance.prefix(b)) == shared(uint)*));\n    auto c = MyAllocator.instance.makeArray!(immutable int)(100);\n    static assert(is(typeof(&MyAllocator.instance.prefix(c)) == shared(uint)*));\n    auto d = MyAllocator.instance.makeArray!(int)(100);\n    static assert(is(typeof(&MyAllocator.instance.prefix(d)) == uint*));\n    auto e = MyAllocator.instance.makeArray!(const int)(100);\n    static assert(is(typeof(&MyAllocator.instance.prefix(e)) == const(uint)*));\n\n    void[] p;\n    assert((() nothrow @safe @nogc => MyAllocator.instance.resolveInternalPointer(null, p))() == Ternary.no);\n    assert((() nothrow @safe => MyAllocator.instance.resolveInternalPointer(&d[0], p))() == Ternary.yes);\n    assert(p.ptr is d.ptr && p.length >= d.length);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator;\n    alias a = AffixAllocator!(GCAllocator, uint).instance;\n\n    // Check that goodAllocSize inherits from parent, i.e. GCAllocator\n    assert(__traits(compiles, (() nothrow @safe @nogc => a.goodAllocSize(1))()));\n\n    // Ensure deallocate inherits from parent\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    () nothrow @nogc { a.deallocate(b); }();\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n\n    auto a = AffixAllocator!(Region!(), uint)(Region!()(new ubyte[1024 * 64]));\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    // Test that expand infers from parent\n    assert((() pure nothrow @safe @nogc => a.expand(b, 58))());\n    assert(b.length == 100);\n    // Test that deallocateAll infers from parent\n    assert((() nothrow @nogc => a.deallocateAll())());\n}\n\n// Test that reallocate infers from parent\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    alias a = AffixAllocator!(Mallocator, uint).instance;\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    assert((() nothrow @nogc => a.reallocate(b, 100))());\n    assert(b.length == 100);\n    assert((() nothrow @nogc => a.deallocate(b))());\n}\n\n@system unittest\n{\n    import std.experimental.allocator : processAllocator, RCISharedAllocator;\n    import std.traits;\n\n    alias SharedAllocT = shared AffixAllocator!(RCISharedAllocator, int);\n    static assert(is(RCISharedAllocator == shared));\n    static assert(!is(SharedAllocT.instance));\n\n    SharedAllocT a = SharedAllocT(processAllocator);\n    auto buf = a.allocate(10);\n    static assert(is(typeof(a.allocate) == shared));\n    assert(buf.length == 10);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/aligned_block_list.d",
    "content": "// Written in the D programming language.\n/**\n`AlignedBlockList` represents a wrapper around a chain of allocators, allowing for fast deallocations\nand preserving a low degree of fragmentation by means of aligned allocations.\n\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/aligned_block_list.d)\n*/\nmodule std.experimental.allocator.building_blocks.aligned_block_list;\n\nimport std.experimental.allocator.common;\nimport std.experimental.allocator.building_blocks.null_allocator;\n\n// Common function implementation for thread local and shared AlignedBlockList\nprivate mixin template AlignedBlockListImpl(bool isShared)\n{\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n\n    static if (isShared)\n    import core.internal.spinlock : SpinLock;\n\nprivate:\n    // Doubly linked list of 'AlignedBlockNode'\n    // Each node contains an `Allocator` followed by its payload\n    static struct AlignedBlockNode\n    {\n        AlignedBlockNode* next, prev;\n        Allocator bAlloc;\n\n        static if (isShared)\n        {\n            shared(size_t) bytesUsed;\n            // Since the lock is not taken when allocating, this acts like a refcount\n            // keeping the node alive\n            uint keepAlive;\n        }\n        else\n        {\n            size_t bytesUsed;\n        }\n    }\n\n    // Root of the internal doubly linked list\n    AlignedBlockNode* root;\n\n    // Number of active nodes\n    uint numNodes;\n\n    // If the numNodes exceeds this limit, we will start deallocating nodes\n    enum uint maxNodes = 64;\n\n    // This lock is always taken when changing the list\n    // To improve performance, the lock is not taken when the allocation logic is called\n    static if (isShared)\n    SpinLock lock = SpinLock(SpinLock.Contention.brief);\n\n    // Moves a node to the front of the list, allowing for quick allocations\n    void moveToFront(AlignedBlockNode* tmp)\n    {\n        auto localRoot = cast(AlignedBlockNode*) root;\n        if (tmp == localRoot)\n            return;\n\n        if (tmp.prev) tmp.prev.next = tmp.next;\n        if (tmp.next) tmp.next.prev = tmp.prev;\n        if (localRoot) localRoot.prev = tmp;\n        tmp.next = localRoot;\n        tmp.prev = null;\n\n        root = cast(typeof(root)) tmp;\n    }\n\n    // Removes a node from the list, including its payload\n    // The payload is deallocated by calling 'parent.deallocate'\n    void removeNode(AlignedBlockNode* tmp)\n    {\n        auto next = tmp.next;\n        if (tmp.prev) tmp.prev.next = tmp.next;\n        if (tmp.next) tmp.next.prev = tmp.prev;\n        parent.deallocate((cast(void*) tmp)[0 .. theAlignment]);\n\n        if (tmp == cast(AlignedBlockNode*) root)\n            root = cast(typeof(root)) next;\n\n        static if (isShared)\n        {\n            import core.atomic : atomicOp;\n            atomicOp!\"-=\"(numNodes, 1);\n        }\n        else\n        {\n            numNodes--;\n        }\n    }\n\n    // If the nodes do not have available space, a new node is created\n    // by drawing memory from the parent allocator with aligned allocations.\n    // The new node is inserted at the front of the list\n    bool insertNewNode()\n    {\n        void[] buf = parent.alignedAllocate(theAlignment, theAlignment);\n        if (buf is null)\n            return false;\n\n        auto localRoot = cast(AlignedBlockNode*) root;\n        auto newNode = cast(AlignedBlockNode*) buf;\n\n        // The first part of the allocation represent the node contents\n        // followed by the actual payload\n        ubyte[] payload = cast(ubyte[]) buf[AlignedBlockNode.sizeof .. $];\n        newNode.bAlloc = Allocator(payload);\n\n        newNode.next = localRoot;\n        newNode.prev = null;\n        if (localRoot)\n            localRoot.prev = newNode;\n        root = cast(typeof(root)) newNode;\n\n        static if (isShared)\n        {\n            import core.atomic : atomicOp;\n            atomicOp!\"+=\"(numNodes, 1);\n        }\n        else\n        {\n            numNodes++;\n        }\n\n        return true;\n    }\n\npublic:\n    static if (stateSize!ParentAllocator) ParentAllocator parent;\n    else alias parent = ParentAllocator.instance;\n\n    enum ulong alignment = Allocator.alignment;\n\n    // Since all memory is drawn from ParentAllocator, we can\n    // forward this to the parent\n    static if (hasMember!(ParentAllocator, \"owns\"))\n    Ternary owns(void[] b)\n    {\n        return parent.owns(b);\n    }\n\n    // Use `theAlignment` to find the node which allocated this block\n    bool deallocate(void[] b)\n    {\n        if (b is null)\n            return true;\n\n        // Round buffer to nearest `theAlignment` multiple to quickly find\n        // the `parent` `AlignedBlockNode`\n        enum ulong mask = ~(theAlignment - 1);\n        ulong ptr = ((cast(ulong) b.ptr) & mask);\n        AlignedBlockNode *node = cast(AlignedBlockNode*) ptr;\n        if (node.bAlloc.deallocate(b))\n        {\n            static if (isShared)\n            {\n                import core.atomic : atomicOp;\n                atomicOp!\"-=\"(node.bytesUsed, b.length);\n            }\n            else\n            {\n                node.bytesUsed -= b.length;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    // Allocate works only if memory can be provided via `alignedAllocate` from the parent\n    static if (hasMember!(ParentAllocator, \"alignedAllocate\"))\n    void[] allocate(size_t n)\n    {\n        static if (isShared)\n        import core.atomic : atomicOp, atomicLoad;\n\n        if (n == 0 || n > theAlignment)\n            return null;\n\n        static if (isShared)\n        {\n            lock.lock();\n            scope(exit) lock.unlock();\n        }\n\n        auto tmp = cast(AlignedBlockNode*) root;\n\n        // Iterate through list and find first node which has memory available\n        while (tmp)\n        {\n            auto next = tmp.next;\n            static if (isShared)\n            {\n                // Allocations can happen outside the lock\n                // Make sure nobody deletes this node while using it\n                tmp.keepAlive++;\n                if (next) next.keepAlive++;\n                lock.unlock();\n            }\n\n            auto result = tmp.bAlloc.allocate(n);\n            if (result.length == n)\n            {\n                // Success\n                static if (isShared)\n                {\n                    atomicOp!\"+=\"(tmp.bytesUsed, n);\n                    lock.lock();\n                }\n                else\n                {\n                    tmp.bytesUsed += n;\n                }\n\n                // Most likely this node has memory for more allocations\n                // Move it to the front\n                moveToFront(tmp);\n\n                static if (isShared)\n                {\n                    tmp.keepAlive--;\n                    if (next) next.keepAlive--;\n                }\n\n                return result;\n            }\n\n            // This node can now be removed if necessary\n            static if (isShared)\n            {\n                lock.lock();\n                tmp.keepAlive--;\n                if (next) next.keepAlive--;\n            }\n\n            if (!next)\n                break;\n\n            tmp = next;\n            next = tmp.next;\n\n            // If there are too many nodes, free memory by removing empty nodes\n            static if (isShared)\n            {\n                if (atomicLoad(numNodes) > maxNodes &&\n                    atomicLoad(tmp.bytesUsed) == 0 &&\n                    tmp.keepAlive == 0)\n                {\n                    removeNode(tmp);\n                }\n            }\n            else\n            {\n                if (numNodes > maxNodes && tmp.bytesUsed == 0)\n                {\n                    removeNode(tmp);\n                }\n            }\n\n            tmp = next;\n        }\n\n        // Cannot create new AlignedBlockNode. Most likely the ParentAllocator ran out of resources\n        if (!insertNewNode())\n            return null;\n\n        tmp = cast(typeof(tmp)) root;\n        void[] result = tmp.bAlloc.allocate(n);\n\n        static if (isShared)\n        {\n            atomicOp!\"+=\"(root.bytesUsed, result.length);\n        }\n        else\n        {\n            root.bytesUsed += result.length;\n        }\n\n        return result;\n    }\n\n    // goodAllocSize should not use state\n    size_t goodAllocSize(const size_t n)\n    {\n        Allocator a = null;\n        return a.goodAllocSize(n);\n    }\n}\n\n/**\n`AlignedBlockList` represents a wrapper around a chain of allocators, allowing for fast deallocations\nand preserving a low degree of fragmentation.\nThe allocator holds internally a doubly linked list of `Allocator` objects, which will serve allocations\nin a most-recently-used fashion. Most recent allocators used for `allocate` calls, will be\nmoved to the front of the list.\n\nAlthough allocations are in theory served in linear searching time, `deallocate` calls take\n$(BIGOH 1) time, by using aligned allocations. `ParentAllocator` must implement `alignedAllocate`\nand it must be able to allocate `theAlignment` bytes at the same alignment. Each aligned allocation\ndone by `ParentAllocator` will contain metadata for an `Allocator`, followed by its payload.\n\nParams:\n    Allocator = the allocator which is used to manage each node; it must have a constructor which receives\n        `ubyte[]` and it must not have any parent allocators, except for the `NullAllocator`\n    ParentAllocator = each node draws memory from the parent allocator; it must support `alignedAllocate`\n    theAlignment = alignment of each block and at the same time length of each node\n*/\nstruct AlignedBlockList(Allocator, ParentAllocator, ulong theAlignment = (1 << 21))\n{\n    version (StdDdoc)\n    {\n        import std.typecons : Ternary;\n        import std.traits : hasMember;\n\n        /**\n        Returns a chunk of memory of size `n`\n        It finds the first node in the `AlignedBlockNode` list which has available memory,\n        and moves it to the front of the list.\n\n        All empty nodes which cannot return new memory, are removed from the list.\n\n        Params:\n            n = bytes to allocate\n        Returns:\n            A chunk of memory of the required length or `null` on failure or\n        */\n        static if (hasMember!(ParentAllocator, \"alignedAllocate\"))\n        void[] allocate(size_t n);\n\n        /**\n        Deallocates the buffer `b` given as parameter. Deallocations take place in constant\n        time, regardless of the number of nodes in the list. `b.ptr` is rounded down\n        to the nearest multiple of the `alignment` to quickly find the corresponding\n        `AlignedBlockNode`.\n\n        Params:\n            b = buffer candidate for deallocation\n        Returns:\n            `true` on success and `false` on failure\n        */\n        bool deallocate(void[] b);\n\n        /**\n        Returns `Ternary.yes` if the buffer belongs to the parent allocator and\n        `Ternary.no` otherwise.\n\n        Params:\n            b = buffer tested if owned by this allocator\n        Returns:\n            `Ternary.yes` if owned by this allocator and `Ternary.no` otherwise\n        */\n        static if (hasMember!(ParentAllocator, \"owns\"))\n        Ternary owns(void[] b);\n    }\n    else\n    {\n        import std.math : isPowerOf2;\n        static assert(isPowerOf2(alignment));\n        mixin AlignedBlockListImpl!false;\n    }\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.ascending_page_allocator : AscendingPageAllocator;\n    import std.experimental.allocator.building_blocks.segregator : Segregator;\n    import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlock;\n    import std.typecons : Ternary;\n\n    /*\n    In this example we use 'AlignedBlockList' in conjunction with other allocators\n    in order to create a more complex allocator.\n\n    The 'SuperAllocator' uses a 'Segregator' to distribute allocations to sub-allocators,\n    based on the requested size.\n\n    Each sub-allocator is represented by an 'AlignedBlockList' of 'BitmappedBlocks'.\n    Each 'AlignedBlockList' draws memory from a root allocator which in this case is an 'AscendingPageAllocator'\n\n    Such an allocator not only provides good performance, but also a low degree of memory fragmentation.\n    */\n    alias SuperAllocator = Segregator!(\n        32,\n        AlignedBlockList!(BitmappedBlock!32, AscendingPageAllocator*, 1 << 12),\n        Segregator!(\n\n        64,\n        AlignedBlockList!(BitmappedBlock!64, AscendingPageAllocator*, 1 << 12),\n        Segregator!(\n\n        128,\n        AlignedBlockList!(BitmappedBlock!128, AscendingPageAllocator*, 1 << 12),\n        AscendingPageAllocator*\n    )));\n\n    SuperAllocator a;\n    auto pageAlloc = AscendingPageAllocator(128 * 4096);\n\n    // Set the parent allocator for all the sub allocators\n    a.allocatorForSize!256 = &pageAlloc;\n    a.allocatorForSize!128.parent = &pageAlloc;\n    a.allocatorForSize!64.parent = &pageAlloc;\n    a.allocatorForSize!32.parent = &pageAlloc;\n\n    enum testNum = 10;\n    void[][testNum] buf;\n\n    // Allocations of size 32 will go to the first 'AlignedBlockList'\n    foreach (j; 0 .. testNum)\n    {\n        buf[j] = a.allocate(32);\n        assert(buf[j].length == 32);\n\n        // This is owned by the first 'AlignedBlockList'\n        assert(a.allocatorForSize!32.owns(buf[j]) == Ternary.yes);\n    }\n\n    // Free the memory\n    foreach (j; 0 .. testNum)\n        assert(a.deallocate(buf[j]));\n\n    // Allocations of size 64 will go to the second 'AlignedBlockList'\n    foreach (j; 0 .. testNum)\n    {\n        buf[j] = a.allocate(64);\n        assert(buf[j].length == 64);\n\n        // This is owned by the second 'AlignedBlockList'\n        assert(a.allocatorForSize!64.owns(buf[j]) == Ternary.yes);\n    }\n\n    // Free the memory\n    foreach (j; 0 .. testNum)\n        assert(a.deallocate(buf[j]));\n\n    // Allocations of size 128 will go to the third 'AlignedBlockList'\n    foreach (j; 0 .. testNum)\n    {\n        buf[j] = a.allocate(128);\n        assert(buf[j].length == 128);\n\n        // This is owned by the third 'AlignedBlockList'\n        assert(a.allocatorForSize!128.owns(buf[j]) == Ternary.yes);\n    }\n\n    // Free the memory\n    foreach (j; 0 .. testNum)\n        assert(a.deallocate(buf[j]));\n\n    // Allocations which exceed 128, will go to the 'AscendingPageAllocator*'\n    void[] b = a.allocate(256);\n    assert(b.length == 256);\n    a.deallocate(b);\n}\n\n/**\n`SharedAlignedBlockList` is the threadsafe version of `AlignedBlockList`.\nThe `Allocator` template parameter must refer a shared allocator.\nAlso, `ParentAllocator` must be a shared allocator, supporting `alignedAllocate`.\n\nParams:\n    Allocator = the shared allocator which is used to manage each node; it must have a constructor which receives\n        `ubyte[]` and it must not have any parent allocators, except for the `NullAllocator`\n    ParentAllocator = each node draws memory from the parent allocator; it must be shared and support `alignedAllocate`\n    theAlignment = alignment of each block and at the same time length of each node\n*/\nshared struct SharedAlignedBlockList(Allocator, ParentAllocator, ulong theAlignment = (1 << 21))\n{\n    version (StdDdoc)\n    {\n        import std.typecons : Ternary;\n        import std.traits : hasMember;\n\n        /**\n        Returns a chunk of memory of size `n`\n        It finds the first node in the `AlignedBlockNode` list which has available memory,\n        and moves it to the front of the list.\n\n        All empty nodes which cannot return new memory, are removed from the list.\n\n        Params:\n            n = bytes to allocate\n        Returns:\n            A chunk of memory of the required length or `null` on failure or\n        */\n        static if (hasMember!(ParentAllocator, \"alignedAllocate\"))\n        void[] allocate(size_t n);\n\n        /**\n        Deallocates the buffer `b` given as parameter. Deallocations take place in constant\n        time, regardless of the number of nodes in the list. `b.ptr` is rounded down\n        to the nearest multiple of the `alignment` to quickly find the corresponding\n        `AlignedBlockNode`.\n\n        Params:\n            b = buffer candidate for deallocation\n        Returns:\n            `true` on success and `false` on failure\n        */\n        bool deallocate(void[] b);\n\n        /**\n        Returns `Ternary.yes` if the buffer belongs to the parent allocator and\n        `Ternary.no` otherwise.\n\n        Params:\n            b = buffer tested if owned by this allocator\n        Returns:\n            `Ternary.yes` if owned by this allocator and `Ternary.no` otherwise\n        */\n        static if (hasMember!(ParentAllocator, \"owns\"))\n        Ternary owns(void[] b);\n    }\n    else\n    {\n        import std.math : isPowerOf2;\n        static assert(isPowerOf2(alignment));\n        mixin AlignedBlockListImpl!true;\n    }\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : SharedRegion;\n    import std.experimental.allocator.building_blocks.ascending_page_allocator : SharedAscendingPageAllocator;\n    import std.experimental.allocator.building_blocks.null_allocator : NullAllocator;\n    import core.thread : ThreadGroup;\n\n    enum numThreads = 8;\n    enum size = 2048;\n    enum maxIter = 10;\n\n    /*\n    In this example we use 'SharedAlignedBlockList' together with 'SharedRegion',\n    in order to create a fast, thread-safe allocator.\n    */\n    alias SuperAllocator = SharedAlignedBlockList!(\n            SharedRegion!(NullAllocator, 1),\n            SharedAscendingPageAllocator,\n            4096);\n\n    SuperAllocator a;\n    // The 'SuperAllocator' will draw memory from a 'SharedAscendingPageAllocator'\n    a.parent = SharedAscendingPageAllocator(4096 * 1024);\n\n    // Launch 'numThreads', each performing allocations\n    void fun()\n    {\n        foreach (i; 0 .. maxIter)\n        {\n            void[] b = a.allocate(size);\n            assert(b.length == size);\n        }\n    }\n\n    auto tg = new ThreadGroup;\n    foreach (i; 0 .. numThreads)\n    {\n        tg.create(&fun);\n    }\n    tg.joinAll();\n}\n\nversion (unittest)\n{\n    static void testrw(void[] b)\n    {\n        ubyte* buf = cast(ubyte*) b.ptr;\n        size_t len = (b.length).roundUpToMultipleOf(4096);\n        for (int i = 0; i < len; i += 4096)\n        {\n            buf[i] =  (cast(ubyte) i % 256);\n            assert(buf[i] == (cast(ubyte) i % 256));\n        }\n    }\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region;\n    import std.experimental.allocator.building_blocks.ascending_page_allocator;\n    import std.random;\n    import std.algorithm.sorting : sort;\n    import core.thread : ThreadGroup;\n    import core.internal.spinlock : SpinLock;\n\n    enum pageSize = 4096;\n    enum numThreads = 10;\n    enum maxIter = 20;\n    enum totalAllocs = maxIter * numThreads;\n    size_t count = 0;\n    SpinLock lock = SpinLock(SpinLock.Contention.brief);\n\n    alias SuperAllocator = SharedAlignedBlockList!(\n            SharedRegion!(NullAllocator, 1),\n            SharedAscendingPageAllocator,\n            1 << 16);\n    void[][totalAllocs] buf;\n\n    SuperAllocator a;\n    a.parent = SharedAscendingPageAllocator(4096 * 1024);\n\n    void fun()\n    {\n        auto rnd = Random(1000);\n\n        foreach (i; 0 .. maxIter)\n        {\n            auto size = uniform(1, pageSize + 1, rnd);\n            void[] b = a.allocate(size);\n            assert(b.length == size);\n            testrw(b);\n\n            lock.lock();\n            buf[count++] = b;\n            lock.unlock();\n        }\n    }\n    auto tg = new ThreadGroup;\n    foreach (i; 0 .. numThreads)\n    {\n        tg.create(&fun);\n    }\n    tg.joinAll();\n\n    sort!((a, b) => a.ptr < b.ptr)(buf[0 .. totalAllocs]);\n    foreach (i; 0 .. totalAllocs - 1)\n    {\n        assert(buf[i].ptr + a.goodAllocSize(buf[i].length) <= buf[i + 1].ptr);\n    }\n\n    foreach (i; 0 .. totalAllocs)\n    {\n        assert(a.deallocate(buf[totalAllocs - 1 - i]));\n    }\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.ascending_page_allocator : AscendingPageAllocator;\n    import std.experimental.allocator.building_blocks.segregator : Segregator;\n    import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlock;\n    import std.random;\n\n    alias SuperAllocator = Segregator!(\n        256,\n        AlignedBlockList!(BitmappedBlock!256, AscendingPageAllocator*, 1 << 16),\n        Segregator!(\n\n        512,\n        AlignedBlockList!(BitmappedBlock!512, AscendingPageAllocator*, 1 << 16),\n        Segregator!(\n\n        1024,\n        AlignedBlockList!(BitmappedBlock!1024, AscendingPageAllocator*, 1 << 16),\n        Segregator!(\n\n        2048,\n        AlignedBlockList!(BitmappedBlock!2048, AscendingPageAllocator*, 1 << 16),\n        AscendingPageAllocator*\n    ))));\n\n    SuperAllocator a;\n    auto pageAlloc = AscendingPageAllocator(4096 * 4096);\n    a.allocatorForSize!4096 = &pageAlloc;\n    a.allocatorForSize!2048.parent = &pageAlloc;\n    a.allocatorForSize!1024.parent = &pageAlloc;\n    a.allocatorForSize!512.parent = &pageAlloc;\n    a.allocatorForSize!256.parent = &pageAlloc;\n\n    auto rnd = Random(1000);\n\n    size_t maxIter = 10;\n    enum testNum = 10;\n    void[][testNum] buf;\n    int maxSize = 8192;\n    foreach (i; 0 .. maxIter)\n    {\n        foreach (j; 0 .. testNum)\n        {\n            auto size = uniform(1, maxSize + 1, rnd);\n            buf[j] = a.allocate(size);\n            assert(buf[j].length == size);\n            testrw(buf[j]);\n        }\n\n        randomShuffle(buf[]);\n\n        foreach (j; 0 .. testNum)\n        {\n            assert(a.deallocate(buf[j]));\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/allocator_list.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/allocator_list.d)\n*/\nmodule std.experimental.allocator.building_blocks.allocator_list;\n\nimport std.experimental.allocator.building_blocks.null_allocator;\nimport std.experimental.allocator.common;\nimport std.experimental.allocator.gc_allocator;\n\n// Turn this on for debugging\n// debug = allocator_list;\n\n/**\n\nGiven an $(LINK2 https://en.wikipedia.org/wiki/Factory_(object-oriented_programming),\nobject factory) of type `Factory` or a factory function\n`factoryFunction`, and optionally also `BookkeepingAllocator` as a supplemental\nallocator for bookkeeping, `AllocatorList` creates an allocator that lazily\ncreates as many allocators are needed for satisfying client allocation requests.\n\nAn embedded list builds a most-recently-used strategy: the most recent\nallocators used in calls to either `allocate`, `owns` (successful calls\nonly), or `deallocate` are tried for new allocations in order of their most\nrecent use. Thus, although core operations take in theory $(BIGOH k) time for\n`k` allocators in current use, in many workloads the factor is sublinear.\nDetails of the actual strategy may change in future releases.\n\n`AllocatorList` is primarily intended for coarse-grained handling of\nallocators, i.e. the number of allocators in the list is expected to be\nrelatively small compared to the number of allocations handled by each\nallocator. However, the per-allocator overhead is small so using\n`AllocatorList` with a large number of allocators should be satisfactory as long\nas the most-recently-used strategy is fast enough for the application.\n\n`AllocatorList` makes an effort to return allocated memory back when no\nlonger used. It does so by destroying empty allocators. However, in order to\navoid thrashing (excessive creation/destruction of allocators under certain use\npatterns), it keeps unused allocators for a while.\n\nParams:\nfactoryFunction = A function or template function (including function literals).\nNew allocators are created by calling `factoryFunction(n)` with strictly\npositive numbers `n`. Delegates that capture their enviroment are not created\namid concerns regarding garbage creation for the environment. When the factory\nneeds state, a `Factory` object should be used.\n\nBookkeepingAllocator = Allocator used for storing bookkeeping data. The size of\nbookkeeping data is proportional to the number of allocators. If $(D\nBookkeepingAllocator) is `NullAllocator`, then `AllocatorList` is\n\"ouroboros-style\", i.e. it keeps the bookkeeping data in memory obtained from\nthe allocators themselves. Note that for ouroboros-style management, the size\n`n` passed to `make` will be occasionally different from the size\nrequested by client code.\n\nFactory = Type of a factory object that returns new allocators on a need\nbasis. For an object `sweatshop` of type `Factory`, `sweatshop(n)` should\nreturn an allocator able to allocate at least `n` bytes (i.e. `Factory` must\ndefine `opCall(size_t)` to return an allocator object). Usually the capacity of\nallocators created should be much larger than `n` such that an allocator can\nbe used for many subsequent allocations. `n` is passed only to ensure the\nminimum necessary for the next allocation. The factory object is allowed to hold\nstate, which will be stored inside `AllocatorList` as a direct `public` member\ncalled `factory`.\n\n*/\nstruct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)\n{\n    import std.conv : emplace;\n    import std.experimental.allocator.building_blocks.stats_collector\n        : StatsCollector, Options;\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n\n    private enum ouroboros = is(BookkeepingAllocator == NullAllocator);\n\n    /**\n    Alias for `typeof(Factory()(1))`, i.e. the type of the individual\n    allocators.\n    */\n    alias Allocator = typeof(Factory.init(1));\n    // Allocator used internally\n    private alias SAllocator = StatsCollector!(Allocator, Options.bytesUsed);\n\n    private static struct Node\n    {\n        // Allocator in this node\n        SAllocator a;\n        Node* next;\n\n        @disable this(this);\n\n        // Is this node unused?\n        void setUnused() { next = &this; }\n        bool unused() const { return next is &this; }\n\n        // Just forward everything to the allocator\n        alias a this;\n    }\n\n    /**\n    If `BookkeepingAllocator` is not `NullAllocator`, `bkalloc` is\n    defined and accessible.\n    */\n\n    // State is stored in an array, but it has a list threaded through it by\n    // means of \"nextIdx\".\n\n    // state\n    static if (!ouroboros)\n    {\n        static if (stateSize!BookkeepingAllocator) BookkeepingAllocator bkalloc;\n        else alias bkalloc = BookkeepingAllocator.instance;\n    }\n    static if (stateSize!Factory)\n    {\n        Factory factory;\n    }\n    private Node[] allocators;\n    private Node* root;\n\n    static if (stateSize!Factory)\n    {\n        private auto make(size_t n) { return factory(n); }\n    }\n    else\n    {\n        private auto make(size_t n) { Factory f; return f(n); }\n    }\n\n    /**\n    Constructs an `AllocatorList` given a factory object. This constructor is\n    defined only if `Factory` has state.\n    */\n    static if (stateSize!Factory)\n    this(ref Factory plant)\n    {\n        factory = plant;\n    }\n    /// Ditto\n    static if (stateSize!Factory)\n    this(Factory plant)\n    {\n        factory = plant;\n    }\n\n    static if (hasMember!(Allocator, \"deallocateAll\")\n        && hasMember!(Allocator, \"owns\"))\n    ~this()\n    {\n        deallocateAll;\n    }\n\n    /**\n    The alignment offered.\n    */\n    enum uint alignment = Allocator.alignment;\n\n    /**\n    Allocate a block of size `s`. First tries to allocate from the existing\n    list of already-created allocators. If neither can satisfy the request,\n    creates a new allocator by calling `make(s)` and delegates the request\n    to it. However, if the allocation fresh off a newly created allocator\n    fails, subsequent calls to `allocate` will not cause more calls to $(D\n    make).\n    */\n    void[] allocate(size_t s)\n    {\n        for (auto p = &root, n = *p; n; p = &n.next, n = *p)\n        {\n            auto result = n.allocate(s);\n            if (result.length != s) continue;\n            // Bring to front if not already\n            if (root != n)\n            {\n                *p = n.next;\n                n.next = root;\n                root = n;\n            }\n            return result;\n        }\n\n        // Add a new allocator\n        if (auto a = addAllocator(s))\n        {\n            auto result = a.allocate(s);\n            assert(owns(result) == Ternary.yes || !result.ptr);\n            return result;\n        }\n        return null;\n    }\n\n    static if (hasMember!(Allocator, \"allocateZeroed\"))\n    package(std) void[] allocateZeroed()(size_t s)\n    {\n        for (auto p = &root, n = *p; n; p = &n.next, n = *p)\n        {\n            auto result = n.allocateZeroed(s);\n            if (result.length != s) continue;\n            // Bring to front if not already\n            if (root != n)\n            {\n                *p = n.next;\n                n.next = root;\n                root = n;\n            }\n            return result;\n        }\n\n        // Add a new allocator\n        if (auto a = addAllocator(s))\n        {\n            auto result = a.allocateZeroed(s);\n            assert(owns(result) == Ternary.yes || !result.ptr);\n            return result;\n        }\n        return null;\n    }\n\n    /**\n    Allocate a block of size `s` with alignment `a`. First tries to allocate\n    from the existing list of already-created allocators. If neither can\n    satisfy the request, creates a new allocator by calling `make(s + a - 1)`\n    and delegates the request to it. However, if the allocation fresh off a\n    newly created allocator fails, subsequent calls to `alignedAllocate`\n    will not cause more calls to `make`.\n    */\n    static if (hasMember!(Allocator, \"alignedAllocate\"))\n    void[] alignedAllocate(size_t s, uint theAlignment)\n    {\n        import std.algorithm.comparison : max;\n        import core.checkedint : addu;\n\n        if (theAlignment == 0 || s == 0)\n            return null;\n\n        for (auto p = &root, n = *p; n; p = &n.next, n = *p)\n        {\n            auto result = n.alignedAllocate(s, theAlignment);\n            if (result.length != s) continue;\n            // Bring to front if not already\n            if (root != n)\n            {\n                *p = n.next;\n                n.next = root;\n                root = n;\n            }\n            return result;\n        }\n\n        bool overflow = false;\n        size_t maxSize = addu(s - 1, cast(size_t) theAlignment, overflow);\n        assert(!overflow, \"Requested size is too large\");\n        if (overflow)\n            return null;\n\n        // Add a new allocator\n        if (auto a = addAllocator(maxSize))\n        {\n            auto result = a.alignedAllocate(s, theAlignment);\n            assert(owns(result) == Ternary.yes || !result.ptr);\n            return result;\n        }\n        return null;\n    }\n\n    private void moveAllocators(void[] newPlace)\n    {\n        assert(newPlace.ptr.alignedAt(Node.alignof));\n        assert(newPlace.length % Node.sizeof == 0);\n        auto newAllocators = cast(Node[]) newPlace;\n        assert(allocators.length <= newAllocators.length);\n\n        // Move allocators\n        foreach (i, ref e; allocators)\n        {\n            if (e.unused)\n            {\n                newAllocators[i].setUnused;\n                continue;\n            }\n            import core.stdc.string : memcpy;\n            memcpy(&newAllocators[i].a, &e.a, e.a.sizeof);\n            if (e.next)\n            {\n                newAllocators[i].next = newAllocators.ptr\n                    + (e.next - allocators.ptr);\n            }\n            else\n            {\n                newAllocators[i].next = null;\n            }\n        }\n\n        // Mark the unused portion as unused\n        foreach (i; allocators.length .. newAllocators.length)\n        {\n            newAllocators[i].setUnused;\n        }\n        auto toFree = allocators;\n\n        // Change state\n        root = newAllocators.ptr + (root - allocators.ptr);\n        allocators = newAllocators;\n\n        // Free the olden buffer\n        static if (ouroboros)\n        {\n            static if (hasMember!(Allocator, \"deallocate\")\n                    && hasMember!(Allocator, \"owns\"))\n                deallocate(toFree);\n        }\n        else\n        {\n            bkalloc.deallocate(toFree);\n        }\n    }\n\n    static if (ouroboros)\n    private Node* addAllocator(size_t atLeastBytes)\n    {\n        void[] t = allocators;\n        static if (hasMember!(Allocator, \"expand\")\n            && hasMember!(Allocator, \"owns\"))\n        {\n            immutable bool expanded = t && this.expand(t, Node.sizeof);\n        }\n        else\n        {\n            enum expanded = false;\n        }\n        if (expanded)\n        {\n            import core.stdc.string : memcpy;\n            assert(t.length % Node.sizeof == 0);\n            assert(t.ptr.alignedAt(Node.alignof));\n            allocators = cast(Node[]) t;\n            allocators[$ - 1].setUnused;\n            auto newAlloc = SAllocator(make(atLeastBytes));\n            memcpy(&allocators[$ - 1].a, &newAlloc, newAlloc.sizeof);\n            emplace(&newAlloc);\n        }\n        else\n        {\n            immutable toAlloc = (allocators.length + 1) * Node.sizeof\n                + atLeastBytes + 128;\n            auto newAlloc = SAllocator(make(toAlloc));\n            auto newPlace = newAlloc.allocate(\n                (allocators.length + 1) * Node.sizeof);\n            if (!newPlace) return null;\n            moveAllocators(newPlace);\n            import core.stdc.string : memcpy;\n            memcpy(&allocators[$ - 1].a, &newAlloc, newAlloc.sizeof);\n            emplace(&newAlloc);\n            assert(allocators[$ - 1].owns(allocators) == Ternary.yes);\n        }\n        // Insert as new root\n        if (root != &allocators[$ - 1])\n        {\n            allocators[$ - 1].next = root;\n            root = &allocators[$ - 1];\n        }\n        else\n        {\n            // This is the first one\n            root.next = null;\n        }\n        assert(!root.unused);\n        return root;\n    }\n\n    static if (!ouroboros)\n    private Node* addAllocator(size_t atLeastBytes)\n    {\n        void[] t = allocators;\n        static if (hasMember!(BookkeepingAllocator, \"expand\"))\n            immutable bool expanded = bkalloc.expand(t, Node.sizeof);\n        else\n            immutable bool expanded = false;\n        if (expanded)\n        {\n            assert(t.length % Node.sizeof == 0);\n            assert(t.ptr.alignedAt(Node.alignof));\n            allocators = cast(Node[]) t;\n            allocators[$ - 1].setUnused;\n        }\n        else\n        {\n            // Could not expand, create a new block\n            t = bkalloc.allocate((allocators.length + 1) * Node.sizeof);\n            assert(t.length % Node.sizeof == 0);\n            if (!t.ptr) return null;\n            moveAllocators(t);\n        }\n        assert(allocators[$ - 1].unused);\n        auto newAlloc = SAllocator(make(atLeastBytes));\n        import core.stdc.string : memcpy;\n        memcpy(&allocators[$ - 1].a, &newAlloc, newAlloc.sizeof);\n        emplace(&newAlloc);\n        // Creation succeeded, insert as root\n        if (allocators.length == 1)\n            allocators[$ - 1].next = null;\n        else\n            allocators[$ - 1].next = root;\n        assert(allocators[$ - 1].a.bytesUsed == 0);\n        root = &allocators[$ - 1];\n        return root;\n    }\n\n    /**\n    Defined only if `Allocator` defines `owns`. Tries each allocator in\n    turn, in most-recently-used order. If the owner is found, it is moved to\n    the front of the list as a side effect under the assumption it will be used\n    soon.\n\n    Returns: `Ternary.yes` if one allocator was found to return `Ternary.yes`,\n    `Ternary.no` if all component allocators returned `Ternary.no`, and\n    `Ternary.unknown` if no allocator returned `Ternary.yes` and at least one\n    returned  `Ternary.unknown`.\n    */\n    static if (hasMember!(Allocator, \"owns\"))\n    Ternary owns(void[] b)\n    {\n        auto result = Ternary.no;\n        for (auto p = &root, n = *p; n; p = &n.next, n = *p)\n        {\n            immutable t = n.owns(b);\n            if (t != Ternary.yes)\n            {\n                if (t == Ternary.unknown) result = t;\n                continue;\n            }\n            // Move the owner to front, speculating it'll be used\n            if (n != root)\n            {\n                *p = n.next;\n                n.next = root;\n                root = n;\n            }\n            return Ternary.yes;\n        }\n        return result;\n    }\n\n    /**\n    Defined only if `Allocator.expand` is defined. Finds the owner of `b`\n    and calls `expand` for it. The owner is not brought to the head of the\n    list.\n    */\n    static if (hasMember!(Allocator, \"expand\")\n        && hasMember!(Allocator, \"owns\"))\n    bool expand(ref void[] b, size_t delta)\n    {\n        if (!b) return delta == 0;\n        for (auto p = &root, n = *p; n; p = &n.next, n = *p)\n        {\n            if (n.owns(b) == Ternary.yes) return n.expand(b, delta);\n        }\n        return false;\n    }\n\n    /**\n    Defined only if `Allocator.reallocate` is defined. Finds the owner of\n    `b` and calls `reallocate` for it. If that fails, calls the global\n    `reallocate`, which allocates a new block and moves memory.\n    */\n    static if (hasMember!(Allocator, \"reallocate\"))\n    bool reallocate(ref void[] b, size_t s)\n    {\n        // First attempt to reallocate within the existing node\n        if (!b.ptr)\n        {\n            b = allocate(s);\n            return b.length == s;\n        }\n        for (auto p = &root, n = *p; n; p = &n.next, n = *p)\n        {\n            if (n.owns(b) == Ternary.yes) return n.reallocate(b, s);\n        }\n        // Failed, but we may find new memory in a new node.\n        return .reallocate(this, b, s);\n    }\n\n    /**\n     Defined if `Allocator.deallocate` and `Allocator.owns` are defined.\n    */\n    static if (hasMember!(Allocator, \"deallocate\")\n        && hasMember!(Allocator, \"owns\"))\n    bool deallocate(void[] b)\n    {\n        if (!b.ptr) return true;\n        assert(allocators.length);\n        assert(owns(b) == Ternary.yes);\n        bool result;\n        for (auto p = &root, n = *p; ; p = &n.next, n = *p)\n        {\n            assert(n);\n            if (n.owns(b) != Ternary.yes) continue;\n            result = n.deallocate(b);\n            // Bring to front\n            if (n != root)\n            {\n                *p = n.next;\n                n.next = root;\n                root = n;\n            }\n            if (n.empty != Ternary.yes) return result;\n            break;\n        }\n        // Hmmm... should we return this allocator back to the wild? Let's\n        // decide if there are TWO empty allocators we can release ONE. This\n        // is to avoid thrashing.\n        // Note that loop starts from the second element.\n        for (auto p = &root.next, n = *p; n; p = &n.next, n = *p)\n        {\n            if (n.unused || n.empty != Ternary.yes) continue;\n            // Used and empty baby, nuke it!\n            n.a.destroy;\n            *p = n.next;\n            n.setUnused;\n            break;\n        }\n        return result;\n    }\n\n    /**\n    Defined only if `Allocator.owns` and `Allocator.deallocateAll` are\n    defined.\n    */\n    static if (ouroboros && hasMember!(Allocator, \"deallocateAll\")\n        && hasMember!(Allocator, \"owns\"))\n    bool deallocateAll()\n    {\n        Node* special;\n        foreach (ref n; allocators)\n        {\n            if (n.unused) continue;\n            if (n.owns(allocators) == Ternary.yes)\n            {\n                special = &n;\n                continue;\n            }\n            n.a.deallocateAll;\n            n.a.destroy;\n        }\n        assert(special || !allocators.ptr);\n        if (special)\n        {\n            static if (stateSize!SAllocator)\n            {\n                import core.stdc.string : memcpy;\n                SAllocator specialCopy;\n                assert(special.a.sizeof == specialCopy.sizeof);\n                memcpy(&specialCopy, &special.a, specialCopy.sizeof);\n                emplace(&special.a);\n                specialCopy.deallocateAll();\n            }\n            else\n            {\n                special.deallocateAll();\n            }\n        }\n        allocators = null;\n        root = null;\n        return true;\n    }\n\n    static if (!ouroboros && hasMember!(Allocator, \"deallocateAll\")\n        && hasMember!(Allocator, \"owns\"))\n    bool deallocateAll()\n    {\n        foreach (ref n; allocators)\n        {\n            if (n.unused) continue;\n            n.a.deallocateAll;\n            n.a.destroy;\n        }\n        bkalloc.deallocate(allocators);\n        allocators = null;\n        root = null;\n        return true;\n    }\n\n    /**\n     Returns `Ternary.yes` if no allocators are currently active,\n    `Ternary.no` otherwise. This methods never returns `Ternary.unknown`.\n    */\n    pure nothrow @safe @nogc\n    Ternary empty() const\n    {\n        return Ternary(!allocators.length);\n    }\n}\n\n/// Ditto\ntemplate AllocatorList(alias factoryFunction,\n    BookkeepingAllocator = GCAllocator)\n{\n    alias A = typeof(factoryFunction(1));\n    static assert(\n        // is a template function (including literals)\n        is(typeof({A function(size_t) @system x = factoryFunction!size_t;}))\n        ||\n        // or a function (including literals)\n        is(typeof({A function(size_t) @system x = factoryFunction;}))\n        ,\n        \"Only function names and function literals that take size_t\"\n            ~ \" and return an allocator are accepted, not \"\n            ~ typeof(factoryFunction).stringof\n    );\n    static struct Factory\n    {\n        A opCall(size_t n) { return factoryFunction(n); }\n    }\n    alias AllocatorList = .AllocatorList!(Factory, BookkeepingAllocator);\n}\n\n///\nversion (Posix) @system unittest\n{\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.free_list : ContiguousFreeList;\n    import std.experimental.allocator.building_blocks.null_allocator : NullAllocator;\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.experimental.allocator.building_blocks.segregator : Segregator;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mmap_allocator : MmapAllocator;\n\n    // Ouroboros allocator list based upon 4MB regions, fetched directly from\n    // mmap. All memory is released upon destruction.\n    alias A1 = AllocatorList!((n) => Region!MmapAllocator(max(n, 1024 * 4096)),\n        NullAllocator);\n\n    // Allocator list based upon 4MB regions, fetched from the garbage\n    // collector. All memory is released upon destruction.\n    alias A2 = AllocatorList!((n) => Region!GCAllocator(max(n, 1024 * 4096)));\n\n    // Ouroboros allocator list based upon 4MB regions, fetched from the garbage\n    // collector. Memory is left to the collector.\n    alias A3 = AllocatorList!(\n        (n) => Region!NullAllocator(new ubyte[max(n, 1024 * 4096)]),\n        NullAllocator);\n\n    // Allocator list that creates one freelist for all objects\n    alias A4 =\n        Segregator!(\n            64, AllocatorList!(\n                (n) => ContiguousFreeList!(NullAllocator, 0, 64)(\n                    cast(ubyte[])(GCAllocator.instance.allocate(4096)))),\n            GCAllocator);\n\n    A4 a;\n    auto small = a.allocate(64);\n    assert(small);\n    a.deallocate(small);\n    auto b1 = a.allocate(1024 * 8192);\n    assert(b1 !is null); // still works due to overdimensioning\n    b1 = a.allocate(1024 * 10);\n    assert(b1.length == 1024 * 10);\n}\n\n@system unittest\n{\n    // Create an allocator based upon 4MB regions, fetched from the GC heap.\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.region : Region;\n    AllocatorList!((n) => Region!GCAllocator(new ubyte[max(n, 1024 * 4096)]),\n        NullAllocator) a;\n    const b1 = a.allocate(1024 * 8192);\n    assert(b1 !is null); // still works due to overdimensioning\n    const b2 = a.allocate(1024 * 10);\n    assert(b2.length == 1024 * 10);\n    a.deallocateAll();\n}\n\n@system unittest\n{\n    // Create an allocator based upon 4MB regions, fetched from the GC heap.\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.region : Region;\n    AllocatorList!((n) => Region!()(new ubyte[max(n, 1024 * 4096)])) a;\n    auto b1 = a.alignedAllocate(1024 * 8192, 1024);\n    assert(b1 !is null); // still works due to overdimensioning\n    assert(b1.length == 1024 * 8192);\n    assert(b1.ptr.alignedAt(1024));\n    assert(a.allocators.length == 1);\n\n    b1 = a.alignedAllocate(0, 1024);\n    assert(b1.length == 0);\n    assert(a.allocators.length == 1);\n\n    b1 = a.allocate(1024 * 10);\n    assert(b1.length == 1024 * 10);\n\n    assert(a.reallocate(b1, 1024));\n    assert(b1.length == 1024);\n\n    a.deallocateAll();\n}\n\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.exception : assertThrown;\n\n    // Create an allocator based upon 4MB regions, fetched from the GC heap.\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.region : Region;\n    AllocatorList!((n) => Region!()(new ubyte[max(n, 1024 * 4096)])) a;\n    auto b1 = a.alignedAllocate(0, 1);\n    assert(b1 is null);\n\n    b1 = a.alignedAllocate(1, 0);\n    assert(b1 is null);\n\n    b1 = a.alignedAllocate(0, 0);\n    assert(b1 is null);\n\n    assertThrown!AssertError(a.alignedAllocate(size_t.max, 1024));\n    a.deallocateAll();\n}\n\n@system unittest\n{\n    import std.typecons : Ternary;\n\n    // Create an allocator based upon 4MB regions, fetched from the GC heap.\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.region : Region;\n    AllocatorList!((n) => Region!()(new ubyte[max(n, 1024 * 4096)])) a;\n    auto b0 = a.alignedAllocate(1, 1024);\n    assert(b0.length == 1);\n    assert(b0.ptr.alignedAt(1024));\n    assert(a.allocators.length == 1);\n\n    auto b1 = a.alignedAllocate(1024 * 4096, 1024);\n    assert(b1.length == 1024 * 4096);\n    assert(b1.ptr.alignedAt(1024));\n    assert(a.allocators.length == 2);\n\n    auto b2 = a.alignedAllocate(1024, 128);\n    assert(b2.length == 1024);\n    assert(b2.ptr.alignedAt(128));\n    assert(a.allocators.length == 2);\n\n    auto b3 = a.allocate(1024);\n    assert(b3.length == 1024);\n    assert(a.allocators.length == 2);\n\n    auto b4 = a.allocate(1024 * 4096);\n    assert(b4.length == 1024 * 4096);\n    assert(a.allocators.length == 3);\n\n    assert(a.root.empty == Ternary.no);\n    assert(a.deallocate(b4));\n    assert(a.root.empty == Ternary.yes);\n\n    assert(a.deallocate(b1));\n    a.deallocateAll();\n}\n\n@system unittest\n{\n    // Create an allocator based upon 4MB regions, fetched from the GC heap.\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.region : Region;\n    AllocatorList!((n) => Region!()(new ubyte[max(n, 1024 * 4096)])) a;\n    auto b1 = a.allocate(1024 * 8192);\n    assert(b1 !is null); // still works due to overdimensioning\n    b1 = a.allocate(1024 * 10);\n    assert(b1.length == 1024 * 10);\n    assert(a.reallocate(b1, 1024));\n    assert(b1.length == 1024);\n    a.deallocateAll();\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Ternary;\n    AllocatorList!((n) => Region!()(new ubyte[max(n, 1024 * 4096)]), Mallocator) a;\n    auto b1 = a.allocate(1024 * 8192);\n    assert(b1 !is null);\n    b1 = a.allocate(1024 * 10);\n    assert(b1.length == 1024 * 10);\n    assert((() pure nothrow @safe @nogc => a.expand(b1, 10))());\n    assert(b1.length == 1025 * 10);\n    a.allocate(1024 * 4095);\n    assert((() pure nothrow @safe @nogc => a.empty)() == Ternary.no);\n    // Ensure deallocateAll infers from parent\n    assert((() nothrow @nogc => a.deallocateAll())());\n    assert((() pure nothrow @safe @nogc => a.empty)() == Ternary.yes);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    enum bs = GCAllocator.alignment;\n    AllocatorList!((n) => Region!GCAllocator(256 * bs)) a;\n    auto b1 = a.allocate(192 * bs);\n    assert(b1.length == 192 * bs);\n    assert(a.allocators.length == 1);\n    auto b2 = a.allocate(64 * bs);\n    assert(b2.length == 64 * bs);\n    assert(a.allocators.length == 1);\n    auto b3 = a.allocate(192 * bs);\n    assert(b3.length == 192 * bs);\n    assert(a.allocators.length == 2);\n    // Ensure deallocate inherits from parent allocators\n    () nothrow @nogc { a.deallocate(b1); }();\n    b1 = a.allocate(64 * bs);\n    assert(b1.length == 64 * bs);\n    assert(a.allocators.length == 2);\n    a.deallocateAll();\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.ascending_page_allocator : AscendingPageAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.algorithm.comparison : max;\n    import std.typecons : Ternary;\n\n    enum pageSize = 4096;\n\n    static void testrw(void[] b)\n    {\n        ubyte* buf = cast(ubyte*) b.ptr;\n        for (int i = 0; i < b.length; i += pageSize)\n        {\n            buf[i] = cast(ubyte) (i % 256);\n            assert(buf[i] == cast(ubyte) (i % 256));\n        }\n    }\n\n    enum numPages = 2;\n    AllocatorList!((n) => AscendingPageAllocator(max(n, numPages * pageSize)), Mallocator) a;\n\n    void[] b1 = a.allocate(1);\n    assert(b1.length == 1);\n    b1 = a.allocate(2);\n    assert(b1.length == 2);\n    testrw(b1);\n    assert(a.root.a.parent.getAvailableSize() == 0);\n\n    void[] b2 = a.allocate((numPages + 1) * pageSize);\n    assert(b2.length == (numPages + 1) * pageSize);\n    testrw(b2);\n\n    void[] b3 = a.allocate(3);\n    assert(b3.length == 3);\n    testrw(b3);\n\n    void[] b4 = a.allocate(0);\n    assert(b4.length == 0);\n\n    assert(a.allocators.length == 3);\n    assert(a.owns(b1) == Ternary.yes);\n    assert(a.owns(b2) == Ternary.yes);\n    assert(a.owns(b3) == Ternary.yes);\n\n    assert(a.expand(b1, pageSize - b1.length));\n    assert(b1.length == pageSize);\n    assert(!a.expand(b1, 1));\n    assert(!a.expand(b2, 1));\n\n    testrw(b1);\n    testrw(b2);\n    testrw(b3);\n\n    assert(a.deallocate(b1));\n    assert(a.deallocate(b2));\n\n    assert(a.deallocateAll());\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.ascending_page_allocator : AscendingPageAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.algorithm.comparison : max;\n    import std.typecons : Ternary;\n\n    enum pageSize = 4096;\n\n    static void testrw(void[] b)\n    {\n        ubyte* buf = cast(ubyte*) b.ptr;\n        for (int i = 0; i < b.length; i += pageSize)\n        {\n            buf[i] = cast(ubyte) (i % 256);\n            assert(buf[i] == cast(ubyte) (i % 256));\n        }\n    }\n\n    enum numPages = 2;\n    AllocatorList!((n) => AscendingPageAllocator(max(n, numPages * pageSize)), NullAllocator) a;\n\n    void[] b1 = a.allocate(1);\n    assert(b1.length == 1);\n    b1 = a.allocate(2);\n    assert(b1.length == 2);\n    testrw(b1);\n\n    void[] b2 = a.allocate((numPages + 1) * pageSize);\n    assert(b2.length == (numPages + 1) * pageSize);\n    testrw(b2);\n\n    void[] b3 = a.allocate(3);\n    assert(b3.length == 3);\n    testrw(b3);\n\n    void[] b4 = a.allocate(0);\n    assert(b4.length == 0);\n\n    assert(a.allocators.length == 3);\n    assert(a.owns(b1) == Ternary.yes);\n    assert(a.owns(b2) == Ternary.yes);\n    assert(a.owns(b3) == Ternary.yes);\n\n    assert(a.expand(b1, pageSize - b1.length));\n    assert(b1.length == pageSize);\n    assert(!a.expand(b1, 1));\n    assert(!a.expand(b2, 1));\n\n    testrw(b1);\n    testrw(b2);\n    testrw(b3);\n\n    assert(a.deallocate(b1));\n    assert(a.deallocate(b2));\n\n    b3 = a.alignedAllocate(70 * pageSize, 70 * pageSize);\n    assert(b3.length == 70 * pageSize);\n    assert(b3.ptr.alignedAt(70 * pageSize));\n    testrw(b3);\n    assert(a.allocators.length == 4);\n    assert(a.deallocate(b3));\n\n\n    assert(a.deallocateAll());\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.ascending_page_allocator : AscendingPageAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.algorithm.comparison : max;\n    import std.typecons : Ternary;\n\n    enum pageSize = 4096;\n\n    static void testrw(void[] b)\n    {\n        ubyte* buf = cast(ubyte*) b.ptr;\n        for (int i = 0; i < b.length; i += pageSize)\n        {\n            buf[i] = cast(ubyte) (i % 256);\n            assert(buf[i] == cast(ubyte) (i % 256));\n        }\n    }\n\n    enum numPages = 5;\n    AllocatorList!((n) => AscendingPageAllocator(max(n, numPages * pageSize)), NullAllocator) a;\n    auto b = a.alignedAllocate(1, pageSize * 2);\n    assert(b.length == 1);\n    assert(a.expand(b, 4095));\n    assert(b.ptr.alignedAt(2 * 4096));\n    assert(b.length == 4096);\n\n    b = a.allocate(4096);\n    assert(b.length == 4096);\n    assert(a.allocators.length == 1);\n\n    assert(a.allocate(4096 * 5).length == 4096 * 5);\n    assert(a.allocators.length == 2);\n\n    assert(a.deallocateAll());\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.ascending_page_allocator : AscendingPageAllocator;\n    import std.algorithm.comparison : max;\n\n    enum maxIter = 100;\n    enum pageSize = 4096;\n    enum numPages = 10;\n\n    AllocatorList!((n) => AscendingPageAllocator(max(n, numPages * pageSize)), NullAllocator) a;\n    foreach (i; 0 .. maxIter)\n    {\n        auto b1 = a.allocate(512);\n        assert(b1.length == 512);\n\n        assert(a.deallocate(b1));\n    }\n\n    assert(a.deallocateAll());\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/ascending_page_allocator.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/ascending_page_allocator.d)\n*/\nmodule std.experimental.allocator.building_blocks.ascending_page_allocator;\nimport std.experimental.allocator.common;\n\n// Common implementations for shared and thread local AscendingPageAllocator\nprivate mixin template AscendingPageAllocatorImpl(bool isShared)\n{\n    bool deallocate(void[] buf) nothrow @nogc\n    {\n        size_t goodSize = goodAllocSize(buf.length);\n        version (Posix)\n        {\n            import core.sys.posix.sys.mman : mmap, MAP_FAILED, MAP_PRIVATE,\n                MAP_ANON, MAP_FIXED, PROT_NONE, munmap;\n\n            auto ptr = mmap(buf.ptr, goodSize, PROT_NONE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);\n            if (ptr == MAP_FAILED)\n                 return false;\n        }\n        else version (Windows)\n        {\n            import core.sys.windows.windows : VirtualFree, MEM_RELEASE, MEM_DECOMMIT;\n\n            auto ret = VirtualFree(buf.ptr, goodSize, MEM_DECOMMIT);\n            if (ret == 0)\n                 return false;\n        }\n        else\n        {\n            static assert(0, \"Unsupported OS\");\n        }\n\n        static if (!isShared)\n        {\n            pagesUsed -= goodSize / pageSize;\n        }\n\n        return true;\n    }\n\n    Ternary owns(void[] buf) nothrow @nogc\n    {\n        if (!data)\n            return Ternary.no;\n        return Ternary(buf.ptr >= data && buf.ptr < buf.ptr + numPages * pageSize);\n    }\n\n    bool deallocateAll() nothrow @nogc\n    {\n        version (Posix)\n        {\n            import core.sys.posix.sys.mman : munmap;\n            auto ret = munmap(cast(void*) data, numPages * pageSize);\n            if (ret != 0)\n                assert(0, \"Failed to unmap memory, munmap failure\");\n        }\n        else version (Windows)\n        {\n            import core.sys.windows.windows : VirtualFree, MEM_RELEASE;\n            auto ret = VirtualFree(cast(void*) data, 0, MEM_RELEASE);\n            if (ret == 0)\n                assert(0, \"Failed to unmap memory, VirtualFree failure\");\n        }\n        else\n        {\n            static assert(0, \"Unsupported OS version\");\n        }\n        data = null;\n        offset = null;\n        return true;\n    }\n\n    size_t goodAllocSize(size_t n) nothrow @nogc\n    {\n        return n.roundUpToMultipleOf(cast(uint) pageSize);\n    }\n\n    this(size_t n) nothrow @nogc\n    {\n        static if (isShared)\n        {\n            lock = SpinLock(SpinLock.Contention.brief);\n        }\n\n        version (Posix)\n        {\n            import core.sys.posix.sys.mman : mmap, MAP_ANON, PROT_NONE,\n                MAP_PRIVATE, MAP_FAILED;\n            import core.sys.posix.unistd : sysconf, _SC_PAGESIZE;\n\n            pageSize = cast(size_t) sysconf(_SC_PAGESIZE);\n            numPages = n.roundUpToMultipleOf(cast(uint) pageSize) / pageSize;\n            data = cast(typeof(data)) mmap(null, pageSize * numPages,\n                PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);\n            if (data == MAP_FAILED)\n                assert(0, \"Failed to mmap memory\");\n        }\n        else version (Windows)\n        {\n            import core.sys.windows.windows : VirtualAlloc, PAGE_NOACCESS,\n                MEM_RESERVE, GetSystemInfo, SYSTEM_INFO;\n\n            SYSTEM_INFO si;\n            GetSystemInfo(&si);\n            pageSize = cast(size_t) si.dwPageSize;\n            numPages = n.roundUpToMultipleOf(cast(uint) pageSize) / pageSize;\n            data = cast(typeof(data)) VirtualAlloc(null, pageSize * numPages,\n                MEM_RESERVE, PAGE_NOACCESS);\n            if (!data)\n                assert(0, \"Failed to VirtualAlloc memory\");\n        }\n        else\n        {\n            static assert(0, \"Unsupported OS version\");\n        }\n\n        offset = data;\n        readWriteLimit = data;\n    }\n\n    size_t getAvailableSize() nothrow @nogc\n    {\n        static if (isShared)\n        {\n            lock.lock();\n        }\n\n        auto size = numPages * pageSize + data - offset;\n        static if (isShared)\n        {\n            lock.unlock();\n        }\n        return size;\n    }\n\n    // Sets the protection of a memory range to read/write\n    private bool extendMemoryProtection(void* start, size_t size) nothrow @nogc\n    {\n        version (Posix)\n        {\n            import core.sys.posix.sys.mman : mprotect, PROT_WRITE, PROT_READ;\n\n            auto ret = mprotect(start, size, PROT_WRITE | PROT_READ);\n            return ret == 0;\n        }\n        else version (Windows)\n        {\n            import core.sys.windows.windows : VirtualAlloc, MEM_COMMIT, PAGE_READWRITE;\n\n            auto ret = VirtualAlloc(start, size, MEM_COMMIT, PAGE_READWRITE);\n            return ret != null;\n        }\n        else\n        {\n            static assert(0, \"Unsupported OS\");\n        }\n    }\n}\n\n/**\n`AscendingPageAllocator` is a fast and safe allocator that rounds all allocations\nto multiples of the system's page size. It reserves a range of virtual addresses\n(using `mmap` on Posix and `VirtualAlloc` on Windows) and allocates memory at consecutive virtual\naddresses.\n\nWhen a chunk of memory is requested, the allocator finds a range of\nvirtual pages that satisfy the requested size, changing their protection to\nread/write using OS primitives (`mprotect` and `VirtualProtect`, respectively).\nThe physical memory is allocated on demand, when the pages are accessed.\n\nDeallocation removes any read/write permissions from the target pages\nand notifies the OS to reclaim the physical memory, while keeping the virtual\nmemory.\n\nBecause the allocator does not reuse memory, any dangling references to\ndeallocated memory will always result in deterministically crashing the process.\n\nSee_Also:\n$(HTTPS microsoft.com/en-us/research/wp-content/uploads/2017/03/kedia2017mem.pdf, Simple Fast and Safe Manual Memory Management) for the general approach.\n*/\nstruct AscendingPageAllocator\n{\n    import std.typecons : Ternary;\n\n    // Docs for mixin functions\n    version (StdDdoc)\n    {\n        /**\n        Rounds the mapping size to the next multiple of the page size and calls\n        the OS primitive responsible for creating memory mappings: `mmap` on POSIX and\n        `VirtualAlloc` on Windows.\n\n        Params:\n        n = mapping size in bytes\n        */\n        this(size_t n) nothrow @nogc;\n\n        /**\n        Rounds the requested size to the next multiple of the page size.\n        */\n        size_t goodAllocSize(size_t n) nothrow @nogc;\n\n        /**\n        Decommit all physical memory associated with the buffer given as parameter,\n        but keep the range of virtual addresses.\n\n        On POSIX systems `deallocate` calls `mmap` with `MAP_FIXED' a second time to decommit the memory.\n        On Windows, it uses `VirtualFree` with `MEM_DECOMMIT`.\n        */\n        void deallocate(void[] b) nothrow @nogc;\n\n        /**\n        Returns `Ternary.yes` if the passed buffer is inside the range of virtual adresses.\n        Does not guarantee that the passed buffer is still valid.\n        */\n        Ternary owns(void[] buf) nothrow @nogc;\n\n        /**\n        Removes the memory mapping causing all physical memory to be decommited and\n        the virtual address space to be reclaimed.\n        */\n        bool deallocateAll() nothrow @nogc;\n\n        /**\n        Returns the available size for further allocations in bytes.\n        */\n        size_t getAvailableSize() nothrow @nogc;\n    }\n\nprivate:\n    size_t pageSize;\n    size_t numPages;\n\n    // The start of the virtual address range\n    void* data;\n\n    // Keeps track of there the next allocation should start\n    void* offset;\n\n    // Number of pages which contain alive objects\n    size_t pagesUsed;\n\n    // On allocation requests, we allocate an extra 'extraAllocPages' pages\n    // The address up to which we have permissions is stored in 'readWriteLimit'\n    void* readWriteLimit;\n    enum extraAllocPages = 1000;\n\npublic:\n    enum uint alignment = 4096;\n\n    // Inject common function implementations\n    mixin AscendingPageAllocatorImpl!false;\n\n    /**\n    Rounds the allocation size to the next multiple of the page size.\n    The allocation only reserves a range of virtual pages but the actual\n    physical memory is allocated on demand, when accessing the memory.\n\n    Params:\n    n = Bytes to allocate\n\n    Returns:\n    `null` on failure or if the requested size exceeds the remaining capacity.\n    */\n    void[] allocate(size_t n) nothrow @nogc\n    {\n        import std.algorithm.comparison : min;\n\n        immutable pagedBytes = numPages * pageSize;\n        size_t goodSize = goodAllocSize(n);\n\n        // Requested exceeds the virtual memory range\n        if (goodSize > pagedBytes || offset - data > pagedBytes - goodSize)\n            return null;\n\n        // Current allocation exceeds readable/writable memory area\n        if (offset + goodSize > readWriteLimit)\n        {\n            // Extend r/w memory range to new limit\n            void* newReadWriteLimit = min(data + pagedBytes,\n                offset + goodSize + extraAllocPages * pageSize);\n            if (newReadWriteLimit != readWriteLimit)\n            {\n                assert(newReadWriteLimit > readWriteLimit);\n                if (!extendMemoryProtection(readWriteLimit, newReadWriteLimit - readWriteLimit))\n                    return null;\n\n                readWriteLimit = newReadWriteLimit;\n            }\n        }\n\n        void* result = offset;\n        offset += goodSize;\n        pagesUsed += goodSize / pageSize;\n\n        return cast(void[]) result[0 .. n];\n    }\n\n    /**\n    Rounds the allocation size to the next multiple of the page size.\n    The allocation only reserves a range of virtual pages but the actual\n    physical memory is allocated on demand, when accessing the memory.\n\n    The allocated memory is aligned to the specified alignment `a`.\n\n    Params:\n    n = Bytes to allocate\n    a = Alignment\n\n    Returns:\n    `null` on failure or if the requested size exceeds the remaining capacity.\n    */\n    void[] alignedAllocate(size_t n, uint a) nothrow @nogc\n    {\n        void* alignedStart = cast(void*) roundUpToMultipleOf(cast(size_t) offset, a);\n        assert(alignedStart.alignedAt(a));\n        immutable pagedBytes = numPages * pageSize;\n        size_t goodSize = goodAllocSize(n);\n        if (goodSize > pagedBytes ||\n            alignedStart - data > pagedBytes - goodSize)\n            return null;\n\n        // Same logic as allocate, only that the buffer must be properly aligned\n        auto oldOffset = offset;\n        offset = alignedStart;\n        auto result = allocate(n);\n        if (!result)\n            offset = oldOffset;\n        return result;\n    }\n\n    /**\n    If the passed buffer is not the last allocation, then `delta` can be\n    at most the number of bytes left on the last page.\n    Otherwise, we can expand the last allocation until the end of the virtual\n    address range.\n    */\n    bool expand(ref void[] b, size_t delta) nothrow @nogc\n    {\n        import std.algorithm.comparison : min;\n\n        if (!delta) return true;\n        if (b is null) return false;\n\n        size_t goodSize = goodAllocSize(b.length);\n        size_t bytesLeftOnPage = goodSize - b.length;\n\n        // If this is not the last allocation, we can only expand until\n        // completely filling the last page covered by this buffer\n        if (b.ptr + goodSize != offset && delta > bytesLeftOnPage)\n            return false;\n\n        size_t extraPages = 0;\n\n        // If the extra `delta` bytes requested do not fit the last page\n        // compute how many extra pages are neeeded\n        if (delta > bytesLeftOnPage)\n        {\n            extraPages = goodAllocSize(delta - bytesLeftOnPage) / pageSize;\n        }\n        else\n        {\n            b = cast(void[]) b.ptr[0 .. b.length + delta];\n            return true;\n        }\n\n        if (extraPages > numPages || offset - data > pageSize * (numPages - extraPages))\n            return false;\n\n        void* newPtrEnd = b.ptr + goodSize + extraPages * pageSize;\n        if (newPtrEnd > readWriteLimit)\n        {\n            void* newReadWriteLimit = min(data + numPages * pageSize,\n                newPtrEnd + extraAllocPages * pageSize);\n            if (newReadWriteLimit > readWriteLimit)\n            {\n                if (!extendMemoryProtection(readWriteLimit, newReadWriteLimit - readWriteLimit))\n                    return false;\n\n                readWriteLimit = newReadWriteLimit;\n            }\n        }\n\n        pagesUsed += extraPages;\n        offset += extraPages * pageSize;\n        b = cast(void[]) b.ptr[0 .. b.length + delta];\n        return true;\n    }\n\n    /**\n    Returns `Ternary.yes` if the allocator does not contain any alive objects\n    and `Ternary.no` otherwise.\n    */\n    Ternary empty() nothrow @nogc\n    {\n        return Ternary(pagesUsed == 0);\n    }\n\n    /**\n    Unmaps the whole virtual address range on destruction.\n    */\n    ~this() nothrow @nogc\n    {\n        if (data)\n            deallocateAll();\n    }\n}\n\n///\n@system @nogc nothrow unittest\n{\n    size_t pageSize = 4096;\n    size_t numPages = 100;\n    void[] buf;\n    void[] prevBuf = null;\n    AscendingPageAllocator a = AscendingPageAllocator(numPages * pageSize);\n\n    foreach (i; 0 .. numPages)\n    {\n        // Allocation is rounded up to page size\n        buf = a.allocate(pageSize - 100);\n        assert(buf.length == pageSize - 100);\n\n        // Allocations are served at increasing addresses\n        if (prevBuf)\n            assert(prevBuf.ptr + pageSize == buf.ptr);\n\n        assert(a.deallocate(buf));\n        prevBuf = buf;\n    }\n}\n\n/**\n`SharedAscendingPageAllocator` is the threadsafe version of `AscendingPageAllocator`.\n*/\nshared struct SharedAscendingPageAllocator\n{\n    import std.typecons : Ternary;\n    import core.internal.spinlock : SpinLock;\n\n    // Docs for mixin functions\n    version (StdDdoc)\n    {\n        /**\n        Rounds the mapping size to the next multiple of the page size and calls\n        the OS primitive responsible for creating memory mappings: `mmap` on POSIX and\n        `VirtualAlloc` on Windows.\n\n        Params:\n        n = mapping size in bytes\n        */\n        this(size_t n) nothrow @nogc;\n\n        /**\n        Rounds the requested size to the next multiple of the page size.\n        */\n        size_t goodAllocSize(size_t n) nothrow @nogc;\n\n        /**\n        Decommit all physical memory associated with the buffer given as parameter,\n        but keep the range of virtual addresses.\n\n        On POSIX systems `deallocate` calls `mmap` with `MAP_FIXED' a second time to decommit the memory.\n        On Windows, it uses `VirtualFree` with `MEM_DECOMMIT`.\n        */\n        void deallocate(void[] b) nothrow @nogc;\n\n        /**\n        Returns `Ternary.yes` if the passed buffer is inside the range of virtual adresses.\n        Does not guarantee that the passed buffer is still valid.\n        */\n        Ternary owns(void[] buf) nothrow @nogc;\n\n        /**\n        Removes the memory mapping causing all physical memory to be decommited and\n        the virtual address space to be reclaimed.\n        */\n        bool deallocateAll() nothrow @nogc;\n\n        /**\n        Returns the available size for further allocations in bytes.\n        */\n        size_t getAvailableSize() nothrow @nogc;\n    }\n\nprivate:\n    size_t pageSize;\n    size_t numPages;\n\n    // The start of the virtual address range\n    shared void* data;\n\n    // Keeps track of there the next allocation should start\n    shared void* offset;\n\n    // On allocation requests, we allocate an extra 'extraAllocPages' pages\n    // The address up to which we have permissions is stored in 'readWriteLimit'\n    shared void* readWriteLimit;\n    enum extraAllocPages = 1000;\n    SpinLock lock;\n\npublic:\n    enum uint alignment = 4096;\n\n    // Inject common function implementations\n    mixin AscendingPageAllocatorImpl!true;\n\n    /**\n    Rounds the allocation size to the next multiple of the page size.\n    The allocation only reserves a range of virtual pages but the actual\n    physical memory is allocated on demand, when accessing the memory.\n\n    Params:\n    n = Bytes to allocate\n\n    Returns:\n    `null` on failure or if the requested size exceeds the remaining capacity.\n    */\n    void[] allocate(size_t n) nothrow @nogc\n    {\n        return allocateImpl(n, 1);\n    }\n\n    /**\n    Rounds the allocation size to the next multiple of the page size.\n    The allocation only reserves a range of virtual pages but the actual\n    physical memory is allocated on demand, when accessing the memory.\n\n    The allocated memory is aligned to the specified alignment `a`.\n\n    Params:\n    n = Bytes to allocate\n    a = Alignment\n\n    Returns:\n    `null` on failure or if the requested size exceeds the remaining capacity.\n    */\n    void[] alignedAllocate(size_t n, uint a) nothrow @nogc\n    {\n        // For regular `allocate` calls, `a` will be set to 1\n        return allocateImpl(n, a);\n    }\n\n    private void[] allocateImpl(size_t n, uint a) nothrow @nogc\n    {\n        import std.algorithm.comparison : min;\n\n        size_t localExtraAlloc;\n        void* localOffset;\n        immutable pagedBytes = numPages * pageSize;\n        size_t goodSize = goodAllocSize(n);\n\n        if (goodSize > pagedBytes)\n            return null;\n\n        lock.lock();\n        scope(exit) lock.unlock();\n\n        localOffset = cast(void*) offset;\n        void* alignedStart = cast(void*) roundUpToMultipleOf(cast(size_t) localOffset, a);\n        assert(alignedStart.alignedAt(a));\n        if (alignedStart - data > pagedBytes - goodSize)\n            return null;\n\n        localOffset = alignedStart + goodSize;\n        if (localOffset > readWriteLimit)\n        {\n            void* newReadWriteLimit = min(cast(void*) data + pagedBytes,\n                cast(void*) localOffset + extraAllocPages * pageSize);\n            assert(newReadWriteLimit > readWriteLimit);\n            localExtraAlloc = newReadWriteLimit - readWriteLimit;\n            if (!extendMemoryProtection(cast(void*) readWriteLimit, localExtraAlloc))\n                return null;\n            readWriteLimit = cast(shared(void*)) newReadWriteLimit;\n        }\n\n        offset = cast(typeof(offset)) localOffset;\n        return cast(void[]) alignedStart[0 .. n];\n    }\n\n    /**\n    If the passed buffer is not the last allocation, then `delta` can be\n    at most the number of bytes left on the last page.\n    Otherwise, we can expand the last allocation until the end of the virtual\n    address range.\n    */\n    bool expand(ref void[] b, size_t delta) nothrow @nogc\n    {\n        import std.algorithm.comparison : min;\n\n        if (!delta) return true;\n        if (b is null) return false;\n\n        void* localOffset;\n        size_t localExtraAlloc;\n        size_t goodSize = goodAllocSize(b.length);\n        size_t bytesLeftOnPage = goodSize - b.length;\n\n        if (bytesLeftOnPage >= delta)\n        {\n            b = cast(void[]) b.ptr[0 .. b.length + delta];\n            return true;\n        }\n\n        lock.lock();\n        scope(exit) lock.unlock();\n\n        localOffset = cast(void*) offset;\n        if (b.ptr + goodSize != localOffset)\n            return false;\n\n        size_t extraPages = goodAllocSize(delta - bytesLeftOnPage) / pageSize;\n        if (extraPages > numPages || localOffset - data > pageSize * (numPages - extraPages))\n            return false;\n\n\n        localOffset = b.ptr + goodSize + extraPages * pageSize;\n        if (localOffset > readWriteLimit)\n        {\n            void* newReadWriteLimit = min(cast(void*) data + numPages * pageSize,\n                localOffset + extraAllocPages * pageSize);\n            assert(newReadWriteLimit > readWriteLimit);\n            localExtraAlloc = newReadWriteLimit - readWriteLimit;\n            if (!extendMemoryProtection(cast(void*) readWriteLimit, localExtraAlloc))\n                return false;\n            readWriteLimit = cast(shared(void*)) newReadWriteLimit;\n        }\n\n        offset = cast(typeof(offset)) localOffset;\n        b = cast(void[]) b.ptr[0 .. b.length + delta];\n        return true;\n    }\n}\n\n///\n@system unittest\n{\n    import core.thread : ThreadGroup;\n\n    enum numThreads = 100;\n    enum pageSize = 4096;\n    shared SharedAscendingPageAllocator a = SharedAscendingPageAllocator(pageSize * numThreads);\n\n    void fun()\n    {\n        void[] b = a.allocate(pageSize);\n        assert(b.length == pageSize);\n\n        assert(a.deallocate(b));\n    }\n\n    auto tg = new ThreadGroup;\n    foreach (i; 0 .. numThreads)\n    {\n        tg.create(&fun);\n    }\n    tg.joinAll();\n}\n\nversion (unittest)\n{\n    private static void testrw(void[] b) @nogc nothrow\n    {\n        ubyte* buf = cast(ubyte*) b.ptr;\n        buf[0] = 100;\n        assert(buf[0] == 100);\n        buf[b.length - 1] = 101;\n        assert(buf[b.length - 1] == 101);\n    }\n\n    private static size_t getPageSize() @nogc nothrow\n    {\n        size_t pageSize;\n        version (Posix)\n        {\n            import core.sys.posix.unistd : sysconf, _SC_PAGESIZE;\n\n            pageSize = cast(size_t) sysconf(_SC_PAGESIZE);\n        }\n        else version (Windows)\n        {\n            import core.sys.windows.windows : GetSystemInfo, SYSTEM_INFO;\n\n            SYSTEM_INFO si;\n            GetSystemInfo(&si);\n            pageSize = cast(size_t) si.dwPageSize;\n        }\n        return pageSize;\n    }\n}\n\n@system @nogc nothrow unittest\n{\n    static void testAlloc(Allocator)(ref Allocator a) @nogc nothrow\n    {\n        size_t pageSize = getPageSize();\n\n        void[] b1 = a.allocate(1);\n        assert(a.getAvailableSize() == 3 * pageSize);\n        testrw(b1);\n        void[] b2 = a.allocate(2);\n        assert(a.getAvailableSize() == 2 * pageSize);\n        testrw(b2);\n        void[] b3 = a.allocate(pageSize + 1);\n        assert(a.getAvailableSize() == 0);\n\n        testrw(b3);\n        assert(b1.length == 1);\n        assert(b2.length == 2);\n        assert(b3.length == pageSize + 1);\n\n        assert(a.offset - a.data == 4 * pageSize);\n        void[] b4 = a.allocate(4);\n        assert(!b4);\n\n        a.deallocate(b1);\n        assert(a.data);\n        a.deallocate(b2);\n        assert(a.data);\n        a.deallocate(b3);\n    }\n\n    size_t pageSize = getPageSize();\n    AscendingPageAllocator a = AscendingPageAllocator(4 * pageSize);\n    shared SharedAscendingPageAllocator aa = SharedAscendingPageAllocator(4 * pageSize);\n\n    testAlloc(a);\n    testAlloc(aa);\n}\n\n@system @nogc nothrow unittest\n{\n    size_t pageSize = getPageSize();\n    size_t numPages = 26214;\n    AscendingPageAllocator a = AscendingPageAllocator(numPages * pageSize);\n    foreach (i; 0 .. numPages)\n    {\n        void[] buf = a.allocate(pageSize);\n        assert(buf.length == pageSize);\n        testrw(buf);\n        a.deallocate(buf);\n    }\n\n    assert(!a.allocate(1));\n    assert(a.getAvailableSize() == 0);\n}\n\n@system @nogc nothrow unittest\n{\n    size_t pageSize = getPageSize();\n    size_t numPages = 26214;\n    uint alignment = cast(uint) pageSize;\n    AscendingPageAllocator a = AscendingPageAllocator(numPages * pageSize);\n\n    foreach (i; 0 .. numPages)\n    {\n        void[] buf = a.alignedAllocate(pageSize, alignment);\n        assert(buf.length == pageSize);\n        testrw(buf);\n        a.deallocate(buf);\n    }\n\n    assert(!a.allocate(1));\n    assert(a.getAvailableSize() == 0);\n}\n\n@system @nogc nothrow unittest\n{\n    static void testAlloc(Allocator)(ref Allocator a) @nogc nothrow\n    {\n        import std.traits : hasMember;\n\n        size_t pageSize = getPageSize();\n        size_t numPages = 5;\n        uint alignment = cast(uint) pageSize;\n\n        void[] b1 = a.allocate(pageSize / 2);\n        assert(b1.length == pageSize / 2);\n\n        void[] b2 = a.alignedAllocate(pageSize / 2, alignment);\n        assert(a.expand(b1, pageSize / 2));\n        assert(a.expand(b1, 0));\n        assert(!a.expand(b1, 1));\n        testrw(b1);\n\n        assert(a.expand(b2, pageSize / 2));\n        testrw(b2);\n        assert(b2.length == pageSize);\n\n        assert(a.getAvailableSize() == pageSize * 3);\n\n        void[] b3 = a.allocate(pageSize / 2);\n        assert(a.reallocate(b1, b1.length));\n        assert(a.reallocate(b2, b2.length));\n        assert(a.reallocate(b3, b3.length));\n\n        assert(b3.length == pageSize / 2);\n        testrw(b3);\n        assert(a.expand(b3, pageSize / 4));\n        testrw(b3);\n        assert(a.expand(b3, 0));\n        assert(b3.length == pageSize / 2 + pageSize / 4);\n        assert(a.expand(b3, pageSize / 4 - 1));\n        testrw(b3);\n        assert(a.expand(b3, 0));\n        assert(b3.length == pageSize - 1);\n        assert(a.expand(b3, 2));\n        assert(a.expand(b3, 0));\n        assert(a.getAvailableSize() == pageSize);\n        assert(b3.length == pageSize + 1);\n        testrw(b3);\n\n        assert(a.reallocate(b1, b1.length));\n        assert(a.reallocate(b2, b2.length));\n        assert(a.reallocate(b3, b3.length));\n\n        assert(a.reallocate(b3, 2 * pageSize));\n        testrw(b3);\n        assert(a.reallocate(b1, pageSize - 1));\n        testrw(b1);\n        assert(a.expand(b1, 1));\n        testrw(b1);\n        assert(!a.expand(b1, 1));\n\n        a.deallocate(b1);\n        a.deallocate(b2);\n        a.deallocate(b3);\n    }\n\n    size_t pageSize = getPageSize();\n    size_t numPages = 5;\n    uint alignment = cast(uint) pageSize;\n    AscendingPageAllocator a = AscendingPageAllocator(numPages * pageSize);\n    shared SharedAscendingPageAllocator aa = SharedAscendingPageAllocator(numPages * pageSize);\n\n    testAlloc(a);\n    testAlloc(aa);\n}\n\n@system @nogc nothrow unittest\n{\n    size_t pageSize = getPageSize();\n    size_t numPages = 21000;\n    enum testNum = 100;\n    enum allocPages = 10;\n    void[][testNum] buf;\n    AscendingPageAllocator a = AscendingPageAllocator(numPages * pageSize);\n\n    for (int i = 0; i < numPages; i += testNum * allocPages)\n    {\n        foreach (j; 0 .. testNum)\n        {\n            buf[j] = a.allocate(pageSize * allocPages);\n            testrw(buf[j]);\n        }\n\n        foreach (j; 0 .. testNum)\n        {\n            a.deallocate(buf[j]);\n        }\n    }\n}\n\n@system @nogc nothrow unittest\n{\n    size_t pageSize = getPageSize();\n    size_t numPages = 21000;\n    enum testNum = 100;\n    enum allocPages = 10;\n    void[][testNum] buf;\n    shared SharedAscendingPageAllocator a = SharedAscendingPageAllocator(numPages * pageSize);\n\n    for (int i = 0; i < numPages; i += testNum * allocPages)\n    {\n        foreach (j; 0 .. testNum)\n        {\n            buf[j] = a.allocate(pageSize * allocPages);\n            testrw(buf[j]);\n        }\n\n        foreach (j; 0 .. testNum)\n        {\n            a.deallocate(buf[j]);\n        }\n    }\n}\n\n@system @nogc nothrow unittest\n{\n    size_t pageSize = getPageSize();\n    enum numPages = 2;\n    AscendingPageAllocator a = AscendingPageAllocator(numPages * pageSize);\n    void[] b = a.allocate((numPages + 1) * pageSize);\n    assert(b is null);\n    b = a.allocate(1);\n    assert(b.length == 1);\n    assert(a.getAvailableSize() == pageSize);\n    a.deallocateAll();\n    assert(!a.data && !a.offset);\n}\n\n@system @nogc nothrow unittest\n{\n    size_t pageSize = getPageSize();\n    enum numPages = 26;\n    AscendingPageAllocator a = AscendingPageAllocator(numPages * pageSize);\n    uint alignment = cast(uint) ((numPages / 2) * pageSize);\n    void[] b = a.alignedAllocate(pageSize, alignment);\n    assert(b.length == pageSize);\n    testrw(b);\n    assert(b.ptr.alignedAt(alignment));\n    a.deallocateAll();\n    assert(!a.data && !a.offset);\n}\n\n@system @nogc nothrow unittest\n{\n    size_t pageSize = getPageSize();\n    enum numPages = 10;\n    AscendingPageAllocator a = AscendingPageAllocator(numPages * pageSize);\n    uint alignment = cast(uint) (2 * pageSize);\n\n    void[] b1 = a.alignedAllocate(pageSize, alignment);\n    assert(b1.length == pageSize);\n    testrw(b1);\n    assert(b1.ptr.alignedAt(alignment));\n\n    void[] b2 = a.alignedAllocate(pageSize, alignment);\n    assert(b2.length == pageSize);\n    testrw(b2);\n    assert(b2.ptr.alignedAt(alignment));\n\n    void[] b3 = a.alignedAllocate(pageSize, alignment);\n    assert(b3.length == pageSize);\n    testrw(b3);\n    assert(b3.ptr.alignedAt(alignment));\n\n    void[] b4 = a.allocate(pageSize);\n    assert(b4.length == pageSize);\n    testrw(b4);\n\n    assert(a.deallocate(b1));\n    assert(a.deallocate(b2));\n    assert(a.deallocate(b3));\n    assert(a.deallocate(b4));\n\n    a.deallocateAll();\n    assert(!a.data && !a.offset);\n}\n\n@system unittest\n{\n    import core.thread : ThreadGroup;\n    import std.algorithm.sorting : sort;\n    import core.internal.spinlock : SpinLock;\n\n    enum numThreads = 100;\n    SpinLock lock = SpinLock(SpinLock.Contention.brief);\n    ulong[numThreads] ptrVals;\n    size_t count = 0;\n    shared SharedAscendingPageAllocator a = SharedAscendingPageAllocator(4096 * numThreads);\n\n    void fun()\n    {\n        void[] b = a.allocate(4000);\n        assert(b.length == 4000);\n\n        assert(a.expand(b, 96));\n        assert(b.length == 4096);\n\n        lock.lock();\n        ptrVals[count] = cast(ulong) b.ptr;\n        count++;\n        lock.unlock();\n    }\n\n    auto tg = new ThreadGroup;\n    foreach (i; 0 .. numThreads)\n    {\n        tg.create(&fun);\n    }\n    tg.joinAll();\n\n    ptrVals[].sort();\n    foreach (i; 0 .. numThreads - 1)\n    {\n        assert(ptrVals[i] + 4096 == ptrVals[i + 1]);\n    }\n}\n\n@system unittest\n{\n    import core.thread : ThreadGroup;\n    import std.algorithm.sorting : sort;\n    import core.internal.spinlock : SpinLock;\n\n    SpinLock lock = SpinLock(SpinLock.Contention.brief);\n    enum numThreads = 100;\n    void[][numThreads] buf;\n    size_t count = 0;\n    shared SharedAscendingPageAllocator a = SharedAscendingPageAllocator(2 * 4096 * numThreads);\n\n    void fun()\n    {\n        void[] b = a.allocate(4000);\n        assert(b.length == 4000);\n\n        assert(a.expand(b, 96));\n        assert(b.length == 4096);\n\n        a.expand(b, 4096);\n        assert(b.length == 4096 || b.length == 8192);\n\n        lock.lock();\n        buf[count] = b;\n        count++;\n        lock.unlock();\n    }\n\n    auto tg = new ThreadGroup;\n    foreach (i; 0 .. numThreads)\n    {\n        tg.create(&fun);\n    }\n    tg.joinAll();\n\n    sort!((a, b) => a.ptr < b.ptr)(buf[0 .. 100]);\n    foreach (i; 0 .. numThreads - 1)\n    {\n        assert(buf[i].ptr + buf[i].length == buf[i + 1].ptr);\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/bitmapped_block.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/bitmapped_block.d)\n*/\nmodule std.experimental.allocator.building_blocks.bitmapped_block;\n\nimport std.experimental.allocator.building_blocks.null_allocator;\nimport std.experimental.allocator.common;\nimport std.typecons : Flag, Yes, No;\n\n\n// Common implementation for shared and non-shared versions of the BitmappedBlock\nprivate mixin template BitmappedBlockImpl(bool isShared, bool multiBlock)\n{\n    import std.conv : text;\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n    import std.typecons : tuple, Tuple;\n\n    static if (isShared && multiBlock)\n    import core.internal.spinlock : SpinLock;\n\n    static assert(theBlockSize > 0 && theAlignment.isGoodStaticAlignment);\n    static assert(theBlockSize == chooseAtRuntime ||\n        theBlockSize % theAlignment == 0, \"Block size must be a multiple of the alignment\");\n\n    static if (theBlockSize != chooseAtRuntime)\n    {\n        alias blockSize = theBlockSize;\n    }\n    else\n    {\n        // It is the caller's responsibilty to synchronize this with\n        // allocate/deallocate in shared environments\n        @property uint blockSize() { return _blockSize; }\n        @property void blockSize(uint s)\n        {\n            static if (multiBlock)\n            {\n                assert((cast(BitVector) _control).length == 0 && s % alignment == 0);\n            }\n            else\n            {\n                assert(_control.length == 0 && s % alignment == 0);\n            }\n            _blockSize = s;\n        }\n        private uint _blockSize;\n    }\n\n    static if (is(ParentAllocator == NullAllocator))\n    {\n        private enum parentAlignment = platformAlignment;\n    }\n    else\n    {\n        private alias parentAlignment = ParentAllocator.alignment;\n        static assert(parentAlignment >= ulong.alignof);\n    }\n\n    alias alignment = theAlignment;\n\n    static if (stateSize!ParentAllocator)\n    {\n        ParentAllocator parent;\n    }\n    else\n    {\n        alias parent = ParentAllocator.instance;\n    }\n\n    private size_t _blocks;\n    private void[] _payload;\n    private size_t _startIdx;\n\n    // For multiblock, '_control' is a BitVector, otherwise just a regular ulong[]\n    static if (multiBlock)\n    {\n        // Keeps track of first block which has never been used in an allocation.\n        // All blocks which are located right to the '_freshBit', should have never been\n        // allocated\n        private ulong _freshBit;\n        private BitVector _control;\n    }\n    else\n    {\n        private ulong[] _control;\n    }\n\n    static if (multiBlock && isShared)\n    {\n        SpinLock lock = SpinLock(SpinLock.Contention.brief);\n    }\n\n    pure nothrow @safe @nogc\n    private size_t totalAllocation(size_t capacity)\n    {\n        auto blocks = capacity.divideRoundUp(blockSize);\n        auto leadingUlongs = blocks.divideRoundUp(64);\n        import std.algorithm.comparison : min;\n        immutable initialAlignment = min(parentAlignment,\n            1U << min(31U, trailingZeros(leadingUlongs * 8)));\n        auto maxSlack = alignment <= initialAlignment\n            ? 0\n            : alignment - initialAlignment;\n        return leadingUlongs * 8 + maxSlack + blockSize * blocks;\n    }\n\n    this(ubyte[] data)\n    {\n        immutable a = data.ptr.effectiveAlignment;\n        assert(a >= size_t.alignof || !data.ptr,\n            \"Data must be aligned properly\");\n\n        immutable ulong totalBits = data.length * 8;\n        immutable ulong bitsPerBlock = blockSize * 8 + 1;\n        _blocks = totalBits / bitsPerBlock;\n\n        // Reality is a bit more complicated, iterate until a good number of\n        // blocks found.\n        size_t localBlocks;\n        for (localBlocks = _blocks; localBlocks; --localBlocks)\n        {\n            immutable controlWords = localBlocks.divideRoundUp(64);\n            auto payload = data[controlWords * 8 .. $].roundStartToMultipleOf(\n                alignment);\n            if (payload.length < localBlocks * blockSize)\n            {\n                // Overestimated\n                continue;\n            }\n\n            // Need the casts for shared versions\n            static if (multiBlock)\n            {\n                _control = cast(typeof(_control)) BitVector((cast(ulong*) data.ptr)[0 .. controlWords]);\n                (cast(BitVector) _control)[] = 0;\n            }\n            else\n            {\n                _control = (cast(typeof(_control.ptr)) data.ptr)[0 .. controlWords];\n                _control[] = 0;\n            }\n\n            _payload = cast(typeof(_payload)) payload;\n            break;\n        }\n\n        _blocks = cast(typeof(_blocks)) localBlocks;\n    }\n\n    static if (chooseAtRuntime == theBlockSize)\n    this(ubyte[] data, uint blockSize)\n    {\n        this._blockSize = blockSize;\n        this(data);\n    }\n\n    static if (!is(ParentAllocator == NullAllocator) && !stateSize!ParentAllocator)\n    this(size_t capacity)\n    {\n        size_t toAllocate = totalAllocation(capacity);\n        auto data = cast(ubyte[])(parent.allocate(toAllocate));\n        this(data);\n        assert(_blocks * blockSize >= capacity);\n    }\n\n    static if (!is(ParentAllocator == NullAllocator) && stateSize!ParentAllocator)\n    this(ParentAllocator parent, size_t capacity)\n    {\n        this.parent = parent;\n        size_t toAllocate = totalAllocation(capacity);\n        auto data = cast(ubyte[])(parent.allocate(toAllocate));\n        this(data);\n    }\n\n    static if (!is(ParentAllocator == NullAllocator) &&\n        chooseAtRuntime == theBlockSize &&\n        !stateSize!ParentAllocator)\n    this(size_t capacity, uint blockSize)\n    {\n        this._blockSize = blockSize;\n        this(capacity);\n    }\n\n    static if (!is(ParentAllocator == NullAllocator) &&\n        chooseAtRuntime == theBlockSize &&\n        stateSize!ParentAllocator)\n    this(ParentAllocator parent, size_t capacity, uint blockSize)\n    {\n        this._blockSize = blockSize;\n        this(parent, capacity);\n    }\n\n    static if (!is(ParentAllocator == NullAllocator)\n        && hasMember!(ParentAllocator, \"deallocate\"))\n    ~this()\n    {\n        // multiblock bitmapped blocks use a BitVector\n        static if (multiBlock)\n        {\n            void* start = cast(void*) _control.rep.ptr;\n        }\n        else\n        {\n            void* start = cast(void*) _control.ptr;\n        }\n        void* end = cast(void*) (_payload.ptr + _payload.length);\n        parent.deallocate(start[0 .. end - start]);\n    }\n\n    pure nothrow @safe @nogc\n    size_t goodAllocSize(size_t n)\n    {\n        return n.roundUpToMultipleOf(blockSize);\n    }\n\n    // Implementation of the 'multiBlock' BitmappedBlock\n    // For the shared version, the methods are protected by a common lock\n    static if (multiBlock)\n    {\n        /*\n        Adjusts the memoized _startIdx to the leftmost control word that has at\n        least one zero bit. Assumes all control words to the left of $(D\n        _control[_startIdx]) are already occupied.\n        */\n        private void adjustStartIdx()\n        {\n            while (_startIdx < _control.rep.length && _control.rep[_startIdx] == ulong.max)\n            {\n                static if (isShared)\n                {\n                    // Shared demands atomic increment, however this is protected\n                    // by a lock. Regular increment is fine\n                    auto localStart = _startIdx + 1;\n                    _startIdx = localStart;\n                }\n                else\n                {\n                    ++_startIdx;\n                }\n            }\n        }\n\n        /*\n        Based on the latest allocated bit, 'newBit', it adjusts '_freshBit'\n        */\n        pure nothrow @safe @nogc\n        private void adjustFreshBit(const ulong newBit)\n        {\n            import std.algorithm.comparison : max;\n            static if (isShared)\n            {\n                auto localFreshBit = max(newBit, _freshBit);\n                _freshBit = localFreshBit;\n            }\n            else\n            {\n                _freshBit = max(newBit, _freshBit);\n            }\n        }\n\n        /*\n        Returns the blocks corresponding to the control bits starting at word index\n        wordIdx and bit index msbIdx (MSB=0) for a total of howManyBlocks.\n        */\n        @trusted\n        private void[] blocksFor(this _)(size_t wordIdx, uint msbIdx, size_t howManyBlocks)\n        {\n            assert(msbIdx <= 63);\n            const start = (wordIdx * 64 + msbIdx) * blockSize;\n            const end = start + blockSize * howManyBlocks;\n            if (start == end) return null;\n            if (end <= _payload.length) return cast(void[]) _payload[start .. end];\n            // This could happen if we have more control bits than available memory.\n            // That's possible because the control bits are rounded up to fit in\n            // 64-bit words.\n            return null;\n        }\n\n        static if (isShared)\n        nothrow @safe @nogc\n        void[] allocate(const size_t s)\n        {\n            lock.lock();\n            scope(exit) lock.unlock();\n\n            return allocateImpl(s);\n        }\n\n        static if (!isShared)\n        pure nothrow @safe @nogc\n        void[] allocate(const size_t s)\n        {\n            return allocateImpl(s);\n        }\n\n\n        // If shared, this is protected by a lock inside 'allocate'\n        pure nothrow @trusted @nogc\n        private void[] allocateImpl(const size_t s)\n        {\n            const blocks = s.divideRoundUp(blockSize);\n            void[] result;\n\n        Lswitch:\n            switch (blocks)\n            {\n            case 1:\n                // inline code here for speed\n                // find the next available block\n                foreach (i; _startIdx .. _control.rep.length)\n                {\n                    const w = _control.rep[i];\n                    if (w == ulong.max) continue;\n                    uint j = leadingOnes(w);\n                    assert(j < 64, \"Invalid number of blocks\");\n                    assert((_control.rep[i] & ((1UL << 63) >> j)) == 0, \"Corrupted bitmap\");\n                    static if (isShared)\n                    {\n                        // Need the cast because shared does not recognize the lock\n                        *(cast(ulong*) &_control._rep[i]) |= (1UL << 63) >> j;\n                    }\n                    else\n                    {\n                        _control.rep[i] |= (1UL << 63) >> j;\n                    }\n                    if (i == _startIdx)\n                    {\n                        adjustStartIdx();\n                    }\n                    result = blocksFor(i, j, 1);\n                    break Lswitch;\n                }\n                goto case 0; // fall through\n            case 0:\n                return null;\n            case 2: .. case 64:\n                result = smallAlloc(cast(uint) blocks);\n                break;\n            default:\n                result = hugeAlloc(blocks);\n                break;\n            }\n            if (result)\n            {\n                adjustFreshBit((result.ptr - _payload.ptr) / blockSize + blocks);\n            }\n            return result.ptr ? result.ptr[0 .. s] : null;\n        }\n\n        @trusted void[] allocateFresh(const size_t s)\n        {\n            static if (isShared)\n            {\n                lock.lock();\n                scope(exit) lock.unlock();\n            }\n\n            const blocks = s.divideRoundUp(blockSize);\n\n            void[] result = blocksFor(cast(size_t) (_freshBit / 64),\n                cast(uint) (_freshBit % 64), blocks);\n            if (result)\n            {\n                (cast(BitVector) _control)[_freshBit .. _freshBit + blocks] = 1;\n                static if (isShared)\n                {\n                    ulong localFreshBit = _freshBit;\n                    localFreshBit += blocks;\n                    _freshBit = localFreshBit;\n                }\n                else\n                {\n                    _freshBit += blocks;\n                }\n            }\n            return result;\n        }\n\n        void[] alignedAllocate(size_t n, uint a)\n        {\n            static if (isShared)\n            {\n                lock.lock();\n                scope(exit) lock.unlock();\n            }\n\n            return alignedAllocateImpl(n, a);\n        }\n\n        // If shared, this is protected by a lock inside 'alignedAllocate'\n        private void[] alignedAllocateImpl(size_t n, uint a)\n        {\n            import std.math : isPowerOf2;\n            assert(a.isPowerOf2);\n            if (a <= alignment) return allocate(n);\n\n            // Overallocate to make sure we can get an aligned block\n            auto b = allocateImpl((n + a - alignment).roundUpToMultipleOf(blockSize));\n            if (!b.ptr) return null;\n            auto result = b.roundStartToMultipleOf(a);\n            assert(result.length >= n);\n            result = result.ptr[0 .. n]; // final result\n\n            // Free any blocks that might be slack at the beginning\n            auto slackHeadingBlocks = (result.ptr - b.ptr) / blockSize;\n            if (slackHeadingBlocks)\n            {\n                deallocateImpl(b[0 .. slackHeadingBlocks * blockSize]);\n            }\n\n            // Free any blocks that might be slack at the end\n            auto slackTrailingBlocks = ((b.ptr + b.length)\n                - (result.ptr + result.length)) / blockSize;\n            if (slackTrailingBlocks)\n            {\n                deallocateImpl(b[$ - slackTrailingBlocks * blockSize .. $]);\n            }\n\n            return result;\n        }\n\n        /*\n        Tries to allocate \"blocks\" blocks at the exact position indicated by the\n        position wordIdx/msbIdx (msbIdx counts from MSB, i.e. MSB has index 0). If\n        it succeeds, fills \"result\" with the result and returns tuple(size_t.max,\n        0). Otherwise, returns a tuple with the next position to search.\n        */\n        private Tuple!(size_t, uint) allocateAt(size_t wordIdx, uint msbIdx,\n                size_t blocks, ref void[] result)\n        {\n            assert(blocks > 0);\n            assert(wordIdx < _control.rep.length);\n            assert(msbIdx <= 63);\n            void[] tmpResult;\n            result = null;\n            if (msbIdx + blocks <= 64)\n            {\n                // Allocation should fit this control word\n                static if (isShared)\n                {\n                    ulong localControl = _control.rep[wordIdx];\n                    bool didSetBit = setBitsIfZero(localControl,\n                        cast(uint) (64 - msbIdx - blocks), 63 - msbIdx);\n                    _control.rep[wordIdx] = localControl;\n                }\n                else\n                {\n                    bool didSetBit = setBitsIfZero(_control.rep[wordIdx],\n                        cast(uint) (64 - msbIdx - blocks), 63 - msbIdx);\n                }\n                if (didSetBit)\n                {\n                    tmpResult = blocksFor(wordIdx, msbIdx, blocks);\n                    if (!tmpResult)\n                    {\n                        static if (isShared)\n                        {\n                            localControl = _control.rep[wordIdx];\n                            resetBits(localControl,\n                                cast(uint) (64 - msbIdx - blocks), 63 - msbIdx);\n                            _control.rep[wordIdx] = localControl;\n                        }\n                        else\n                        {\n                            resetBits(_control.rep[wordIdx],\n                                cast(uint) (64 - msbIdx - blocks), 63 - msbIdx);\n                        }\n                        return tuple(size_t.max - 1, 0u);\n                    }\n                    result = tmpResult;\n                    tmpResult = null;\n                    return tuple(size_t.max, 0u);\n                }\n                // Can't allocate, make a suggestion\n                return msbIdx + blocks == 64\n                    ? tuple(wordIdx + 1, 0u)\n                    : tuple(wordIdx, cast(uint) (msbIdx + blocks));\n            }\n            // Allocation spans two control words or more\n            immutable mask = ulong.max >> msbIdx;\n            if (_control.rep[wordIdx] & mask)\n            {\n                // We can't allocate the rest of this control word,\n                // return a suggestion.\n                return tuple(wordIdx + 1, 0u);\n            }\n            // We can allocate the rest of this control word, but we first need to\n            // make sure we can allocate the tail.\n            if (wordIdx + 1 == _control.rep.length)\n            {\n                // No more memory\n                return tuple(_control.rep.length, 0u);\n            }\n            auto hint = allocateAt(wordIdx + 1, 0, blocks - 64 + msbIdx, result);\n            if (hint[0] == size_t.max)\n            {\n                tmpResult = blocksFor(wordIdx, msbIdx, blocks);\n                if (!tmpResult)\n                {\n                    return tuple(size_t.max - 1, 0u);\n                }\n                static if (isShared)\n                {\n                    // Dont want atomics, because this is protected by 'lock'\n                    ulong localControl = _control.rep[wordIdx];\n                    localControl |= mask;\n                    _control.rep[wordIdx] = localControl;\n                }\n                else\n                {\n                    _control.rep[wordIdx] |= mask;\n                }\n                result = tmpResult;\n                tmpResult = null;\n                return tuple(size_t.max, 0u);\n            }\n            // Failed, return a suggestion that skips this whole run.\n            return hint;\n        }\n\n        /* Allocates as many blocks as possible at the end of the blocks indicated\n        by wordIdx. Returns the number of blocks allocated. */\n        private uint allocateAtTail(size_t wordIdx)\n        {\n            assert(wordIdx < _control.rep.length);\n            const available = trailingZeros(_control.rep[wordIdx]);\n            static if (isShared)\n            {\n                ulong localControl = _control.rep[wordIdx];\n                localControl |= ulong.max >> available;\n                _control.rep[wordIdx] = localControl;\n            }\n            else\n            {\n                _control.rep[wordIdx] |= ulong.max >> available;\n            }\n            return available;\n        }\n\n        pure nothrow @safe @nogc\n        private void[] smallAlloc(uint blocks)\n        {\n            assert(blocks >= 2 && blocks <= 64);\n            void[] result;\n            foreach (i; _startIdx .. _control.rep.length)\n            {\n                // Test within the current 64-bit word\n                const v = _control.rep[i];\n                if (v == ulong.max) continue;\n                auto j = findContigOnes(~v, blocks);\n                if (j < 64)\n                {\n                    // yay, found stuff\n                    result = blocksFor(i, j, blocks);\n                    if (result)\n                    {\n                        static if (isShared)\n                        {\n                            ulong localControl = _control.rep[i];\n                            setBits(localControl, 64 - j - blocks, 63 - j);\n                            _control.rep[i] = localControl;\n                        }\n                        else\n                        {\n                            setBits(_control.rep[i], 64 - j - blocks, 63 - j);\n                        }\n                    }\n                    return result;\n                }\n                // Next, try allocations that cross a word\n                auto available = trailingZeros(v);\n                if (available == 0) continue;\n                if (i + 1 >= _control.rep.length) break;\n                assert(available < blocks); // otherwise we should have found it\n                auto needed = blocks - available;\n                assert(needed > 0 && needed < 64);\n                result = blocksFor(i, 64 - available, blocks);\n                if (result && allocateAtFront(i + 1, needed))\n                {\n                    static if (isShared)\n                    {\n                        ulong localControl = _control.rep[i];\n                        localControl |= (1UL << available) - 1;\n                        _control.rep[i] = localControl;\n                    }\n                    else\n                    {\n                        _control.rep[i] |= (1UL << available) - 1;\n                    }\n                    return result;\n                }\n            }\n            return null;\n        }\n\n        pure nothrow @trusted @nogc\n        private void[] hugeAlloc(size_t blocks)\n        {\n            assert(blocks > 64);\n            if (_startIdx == _control._rep.length)\n            {\n                assert((cast(BitVector) _control).allAre1);\n                return null;\n            }\n\n            auto i = (cast(BitVector)_control).findZeros(blocks, _startIdx * 64);\n            if (i == i.max || i + blocks > _blocks) return null;\n            // Allocate those bits\n            (cast(BitVector) _control)[i .. i + blocks] = 1;\n            return cast(void[]) _payload[cast(size_t) (i * blockSize)\n                .. cast(size_t) ((i + blocks) * blockSize)];\n        }\n\n        // Rounds sizeInBytes to a multiple of blockSize.\n        private size_t bytes2blocks(size_t sizeInBytes)\n        {\n            return (sizeInBytes + blockSize - 1) / blockSize;\n        }\n\n        /* Allocates given blocks at the beginning blocks indicated by wordIdx.\n        Returns true if allocation was possible, false otherwise. */\n        private bool allocateAtFront(size_t wordIdx, uint blocks)\n        {\n            assert(wordIdx < _control.rep.length && blocks >= 1 && blocks <= 64);\n            const mask = (1UL << (64 - blocks)) - 1;\n            if (_control.rep[wordIdx] > mask) return false;\n            static if (isShared)\n            {\n                ulong localControl = _control.rep[wordIdx];\n                localControl |= ~mask;\n                _control.rep[wordIdx] = localControl;\n            }\n            else\n            {\n                _control.rep[wordIdx] |= ~mask;\n            }\n            return true;\n        }\n\n        // Since the lock is not pure, only the single threaded 'expand' is pure\n        static if (isShared)\n        {\n            nothrow @trusted @nogc\n            bool expand(ref void[] b, immutable size_t delta)\n            {\n                lock.lock();\n                scope(exit) lock.unlock();\n\n                return expandImpl(b, delta);\n            }\n        }\n        else\n        {\n            pure nothrow @trusted @nogc\n            bool expand(ref void[] b, immutable size_t delta)\n            {\n                return expandImpl(b, delta);\n            }\n        }\n\n        // If shared, this is protected by a lock inside 'expand'\n        pure nothrow @trusted @nogc\n        private bool expandImpl(ref void[] b, immutable size_t delta)\n        {\n            // Dispose with trivial corner cases\n            if (b is null || delta == 0) return delta == 0;\n\n            /* To simplify matters, refuse to expand buffers that don't start at a block start (this may be the case for blocks allocated with alignedAllocate).\n            */\n            if ((b.ptr - _payload.ptr) % blockSize) return false;\n\n            const blocksOld = bytes2blocks(b.length);\n            const blocksNew = bytes2blocks(b.length + delta);\n            assert(blocksOld <= blocksNew);\n\n            // Possibly we have enough slack at the end of the block!\n            if (blocksOld == blocksNew)\n            {\n                b = b.ptr[0 .. b.length + delta];\n                return true;\n            }\n\n            assert((b.ptr - _payload.ptr) % blockSize == 0);\n            const blockIdx = (b.ptr - _payload.ptr) / blockSize;\n            const blockIdxAfter = blockIdx + blocksOld;\n\n            // Try the maximum\n            const wordIdx = blockIdxAfter / 64,\n                msbIdx = cast(uint) (blockIdxAfter % 64);\n            void[] p;\n            auto hint = allocateAt(wordIdx, msbIdx,  blocksNew - blocksOld, p);\n            if (hint[0] != size_t.max)\n            {\n                return false;\n            }\n            // Expansion successful\n            assert(p.ptr == b.ptr + blocksOld * blockSize);\n            b = b.ptr[0 .. b.length + delta];\n            adjustFreshBit(blockIdx + blocksNew);\n            return true;\n        }\n\n        @system bool reallocate(ref void[] b, size_t newSize)\n        {\n            static if (isShared)\n            {\n                lock.lock();\n                scope(exit) lock.unlock();\n            }\n\n            return reallocateImpl(b, newSize);\n        }\n\n        // If shared, this is protected by a lock inside 'reallocate'\n        private @system bool reallocateImpl(ref void[] b, size_t newSize)\n        {\n            static bool slowReallocate(Allocator)(ref Allocator a, ref void[] b, size_t s)\n            {\n                if (b.length == s) return true;\n                if (b.length <= s && a.expandImpl(b, s - b.length)) return true;\n                auto newB = a.allocateImpl(s);\n                if (newB.length != s) return false;\n                if (newB.length <= b.length) newB[] = b[0 .. newB.length];\n                else newB[0 .. b.length] = b[];\n                a.deallocateImpl(b);\n                b = newB;\n                return true;\n            }\n\n            if (!b.ptr)\n            {\n                b = allocateImpl(newSize);\n                return b.length == newSize;\n            }\n            if (newSize == 0)\n            {\n                deallocateImpl(b);\n                b = null;\n                return true;\n            }\n            if (newSize < b.length)\n            {\n                // Shrink. Will shrink in place by deallocating the trailing part.\n                auto newCapacity = bytes2blocks(newSize) * blockSize;\n                deallocateImpl(b[newCapacity .. $]);\n                b = b[0 .. newSize];\n                return true;\n            }\n            // Go the slow route\n            return slowReallocate(this, b, newSize);\n        }\n\n        @system bool alignedReallocate(ref void[] b, size_t newSize, uint a)\n        {\n            static if (isShared)\n            {\n                lock.lock();\n                scope(exit) lock.unlock();\n            }\n\n            return alignedReallocateImpl(b, newSize, a);\n        }\n\n        // If shared, this is protected by a lock inside 'alignedReallocate'\n        private @system bool alignedReallocateImpl(ref void[] b, size_t newSize, uint a)\n        {\n            static bool slowAlignedReallocate(Allocator)(ref Allocator alloc,\n                    ref void[] b, size_t s, uint a)\n            {\n                if (b.length <= s && b.ptr.alignedAt(a)\n                    && alloc.expandImpl(b, s - b.length)) return true;\n\n                auto newB = alloc.alignedAllocateImpl(s, a);\n                if (newB.length != s) return false;\n                if (newB.length <= b.length) newB[] = b[0 .. newB.length];\n                else newB[0 .. b.length] = b[];\n                alloc.deallocateImpl(b);\n                b = newB;\n                return true;\n            }\n\n            if (newSize == 0)\n            {\n                deallocateImpl(b);\n                b = null;\n                return true;\n            }\n            // Go the slow route\n            return slowAlignedReallocate(this, b, newSize, a);\n        }\n\n        nothrow @nogc\n        bool deallocate(void[] b)\n        {\n            static if (isShared)\n            {\n                lock.lock();\n                scope(exit) lock.unlock();\n            }\n\n            return deallocateImpl(b);\n        }\n\n        // If shared, this is protected by a lock inside 'deallocate'\n        nothrow @nogc\n        private bool deallocateImpl(void[] b)\n        {\n            if (b is null) return true;\n\n            // Locate position\n            immutable pos = b.ptr - _payload.ptr;\n            immutable blockIdx = pos / blockSize;\n\n            // Adjust pointer, might be inside a block due to alignedAllocate\n            void* begin = cast(void*) (_payload.ptr + blockIdx * blockSize),\n                end = cast(void*) (b.ptr + b.length);\n            b = begin[0 .. end - begin];\n            // Round up size to multiple of block size\n            auto blocks = b.length.divideRoundUp(blockSize);\n\n            // Get into details\n            auto wordIdx = blockIdx / 64, msbIdx = cast(uint) (blockIdx % 64);\n            if (_startIdx > wordIdx) _startIdx = wordIdx;\n\n            // Three stages: heading bits, full words, leftover bits\n            if (msbIdx)\n            {\n                if (blocks + msbIdx <= 64)\n                {\n                    static if (isShared)\n                    {\n                        ulong localControl = _control.rep[wordIdx];\n                        resetBits(localControl,\n                            cast(uint) (64 - msbIdx - blocks),\n                            63 - msbIdx);\n                        _control.rep[wordIdx] = localControl;\n                    }\n                    else\n                    {\n                        resetBits(_control.rep[wordIdx],\n                            cast(uint) (64 - msbIdx - blocks),\n                            63 - msbIdx);\n                    }\n                    return true;\n                }\n                else\n                {\n                    static if (isShared)\n                    {\n                        ulong localControl = _control.rep[wordIdx];\n                        localControl &= ulong.max << (64 - msbIdx);\n                        _control.rep[wordIdx] = localControl;\n                    }\n                    else\n                    {\n                        _control.rep[wordIdx] &= ulong.max << (64 - msbIdx);\n                    }\n                    blocks -= 64 - msbIdx;\n                    ++wordIdx;\n                    msbIdx = 0;\n                }\n            }\n\n            // Stage 2: reset one word at a time\n            for (; blocks >= 64; blocks -= 64)\n            {\n                _control.rep[wordIdx++] = 0;\n            }\n\n            // Stage 3: deal with leftover bits, if any\n            assert(wordIdx <= _control.rep.length);\n            if (blocks)\n            {\n                static if (isShared)\n                {\n                    ulong localControl = _control.rep[wordIdx];\n                    localControl &= ulong.max >> blocks;\n                    _control.rep[wordIdx] = localControl;\n                }\n                else\n                {\n                    _control.rep[wordIdx] &= ulong.max >> blocks;\n                }\n            }\n            return true;\n        }\n\n        // Since the lock is not pure, only the single threaded version is pure\n        static if (isShared)\n        {\n            nothrow @nogc\n            bool deallocateAll()\n            {\n                lock.lock();\n                scope(exit) lock.unlock();\n\n                (cast(BitVector) _control)[] = 0;\n                _startIdx = 0;\n                return true;\n            }\n        }\n        else\n        {\n            pure nothrow @nogc\n            bool deallocateAll()\n            {\n                _control[] = 0;\n                _startIdx = 0;\n                return true;\n            }\n        }\n\n        // Since the lock is not pure, only the single threaded version is pure\n        static if (isShared)\n        {\n            nothrow @safe @nogc\n            Ternary empty()\n            {\n                lock.lock();\n                scope(exit) lock.unlock();\n\n                return emptyImpl();\n            }\n        }\n        else\n        {\n            pure nothrow @safe @nogc\n            Ternary empty()\n            {\n                return Ternary(_control.allAre0());\n            }\n        }\n\n        pure nothrow @trusted @nogc\n        private Ternary emptyImpl()\n        {\n            return Ternary((cast(BitVector) _control).allAre0());\n        }\n\n        // Debug helper\n        debug(StdBitmapped)\n        private void dump()\n        {\n            import std.stdio : writefln, writeln;\n\n            ulong controlLen = (cast(BitVector) _control).length;\n            writefln(\"%s @ %s {\", typeid(this), cast(void*) (cast(BitVector) _control)._rep.ptr);\n            scope(exit) writeln(\"}\");\n            assert(_payload.length >= blockSize * _blocks);\n            assert(controlLen >= _blocks);\n            writefln(\"  _startIdx=%s; blockSize=%s; blocks=%s\",\n                _startIdx, blockSize, _blocks);\n            if (!controlLen) return;\n            uint blockCount = 1;\n            bool inAllocatedStore = (cast(BitVector) _control)[0];\n            void* start = cast(void*) _payload.ptr;\n            for (size_t i = 1;; ++i)\n            {\n                if (i >= _blocks || (cast(BitVector) _control)[i] != inAllocatedStore)\n                {\n                    writefln(\"  %s block at 0x%s, length: %s (%s*%s)\",\n                        inAllocatedStore ? \"Busy\" : \"Free\",\n                        cast(void*) start,\n                        blockCount * blockSize,\n                        blockCount, blockSize);\n                    if (i >= _blocks) break;\n                    assert(i < controlLen);\n                    inAllocatedStore = (cast(BitVector) _control)[i];\n                    start = cast(void*) (_payload.ptr + blockCount * blockSize);\n                    blockCount = 1;\n                }\n                else\n                {\n                    ++blockCount;\n                }\n            }\n        }\n\n        void[] allocateAll()\n        {\n            static if (isShared)\n            {\n                lock.lock();\n                scope(exit) lock.unlock();\n            }\n\n            if (emptyImpl != Ternary.yes) return null;\n            (cast(BitVector) _control)[] = 1;\n            return cast(void[]) _payload;\n        }\n    } // Finish Yes.multiblock implementation specifics\n    else\n    {\n        static if (isShared)\n        pure nothrow @trusted @nogc\n        void[] allocate(const size_t s)\n        {\n            import core.atomic : cas, atomicLoad, atomicOp;\n            import core.bitop : bsr;\n            import std.range : iota;\n            import std.algorithm.iteration : map;\n            import std.array : array;\n\n            if (s.divideRoundUp(blockSize) != 1)\n                return null;\n\n            // First zero bit position for all values in the 0 - 255 range\n            // for fast lookup\n            static immutable ubyte[255] firstZero = iota(255U).map!\n                (x => (7 - (bsr((~x) & 0x000000ff)))).array;\n\n            foreach (size_t i; 0 .. _control.length)\n            {\n                ulong controlVal, newControlVal, bitIndex;\n                do\n                {\n                    bitIndex = 0;\n                    newControlVal = 0;\n                    controlVal = atomicLoad(_control[i]);\n\n                    // skip all control words which have all bits set\n                    if (controlVal == ulong.max)\n                        break;\n\n                    // fast lookup of first byte which has at least one zero bit\n                    foreach (byteIndex; 0 .. 8)\n                    {\n                        ulong mask = (0xFFUL << (8 * (7 - byteIndex)));\n                        if ((mask & controlVal) != mask)\n                        {\n                            ubyte byteVal = cast(ubyte) ((mask & controlVal) >> (8 * (7 - byteIndex)));\n                            bitIndex += firstZero[byteVal];\n                            newControlVal = controlVal | (1UL << (63 - bitIndex));\n                            break;\n                        }\n                        bitIndex += 8;\n                    }\n                } while (!cas(&_control[i], controlVal, newControlVal));\n\n                auto blockIndex = bitIndex + 64 * i;\n                if (controlVal != ulong.max && blockIndex < _blocks)\n                {\n                    size_t payloadBlockStart = cast(size_t) blockIndex * blockSize;\n                    return cast(void[]) _payload[payloadBlockStart .. payloadBlockStart + s];\n                }\n            }\n\n            return null;\n        }\n\n        static if (!isShared)\n        pure nothrow @trusted @nogc\n        void[] allocate(const size_t s)\n        {\n            import core.bitop : bsr;\n            import std.range : iota;\n            import std.algorithm.iteration : map;\n            import std.array : array;\n\n            if (s.divideRoundUp(blockSize) != 1)\n                return null;\n\n            // First zero bit position for all values in the 0 - 255 range\n            // for fast lookup\n            static immutable ubyte[255] firstZero = iota(255U).map!\n                (x => (7 - (bsr((~x) & 0x000000ff)))).array;\n\n            _startIdx = (_startIdx + 1) % _control.length;\n            foreach (size_t idx; 0 .. _control.length)\n            {\n                size_t i = (idx + _startIdx) % _control.length;\n                size_t bitIndex = 0;\n                // skip all control words which have all bits set\n                if (_control[i] == ulong.max)\n                    continue;\n\n                // fast lookup of first byte which has at least one zero bit\n                foreach (byteIndex; 0 .. 8)\n                {\n                    ulong mask = (0xFFUL << (8 * (7 - byteIndex)));\n                    if ((mask & _control[i]) != mask)\n                    {\n                        ubyte byteVal = cast(ubyte) ((mask & _control[i]) >> (8 * (7 - byteIndex)));\n                        bitIndex += firstZero[byteVal];\n                        _control[i] |= (1UL << (63 - bitIndex));\n                        break;\n                    }\n                    bitIndex += 8;\n                }\n\n                auto blockIndex = bitIndex + 64 * i;\n                if (blockIndex < _blocks)\n                {\n                    size_t payloadBlockStart = cast(size_t) blockIndex * blockSize;\n                    return cast(void[]) _payload[payloadBlockStart .. payloadBlockStart + s];\n                }\n            }\n\n            return null;\n        }\n\n        nothrow @nogc\n        bool deallocate(void[] b)\n        {\n            static if (isShared)\n            import core.atomic : atomicOp;\n\n            if (b is null)\n                return true;\n\n            auto blockIndex = (b.ptr - _payload.ptr) / blockSize;\n            auto controlIndex = blockIndex / 64;\n            auto bitIndex = blockIndex % 64;\n            static if (isShared)\n            {\n                atomicOp!\"&=\"(_control[controlIndex], ~(1UL << (63 - bitIndex)));\n            }\n            else\n            {\n                _control[controlIndex] &= ~(1UL << (63 - bitIndex));\n            }\n\n            return true;\n        }\n\n        pure nothrow @trusted @nogc\n        bool expand(ref void[] b, immutable size_t delta)\n        {\n            if (delta == 0)\n                return true;\n\n            immutable newLength = delta + b.length;\n            if (b is null || newLength > blockSize)\n                return false;\n\n            b = b.ptr[0 .. newLength];\n            return true;\n        }\n    } // Finish No.multiblock implementation specifics\n\n    pure nothrow @trusted @nogc\n    Ternary owns(const void[] b) const\n    {\n        assert(b || b.length == 0, \"Corrupt block.\");\n        return Ternary(b && _payload && (&b[0] >= &_payload[0])\n               && (&b[0] + b.length) <= (&_payload[0] + _payload.length));\n    }\n}\n\n/**\n`BitmappedBlock` implements a simple heap consisting of one contiguous area\nof memory organized in blocks, each of size `theBlockSize`. A block is a unit\nof allocation. A bitmap serves as bookkeeping data, more precisely one bit per\nblock indicating whether that block is currently allocated or not.\n\nPassing `NullAllocator` as `ParentAllocator` (the default) means user code\nmanages allocation of the memory block from the outside; in that case\n`BitmappedBlock` must be constructed with a `ubyte[]` preallocated block and\nhas no responsibility regarding the lifetime of its support underlying storage.\nIf another allocator type is passed, `BitmappedBlock` defines a destructor that\nuses the parent allocator to release the memory block. That makes the combination of `AllocatorList`,\n`BitmappedBlock`, and a back-end allocator such as `MmapAllocator`\na simple and scalable solution for memory allocation.\n\nThere are advantages to storing bookkeeping data separated from the payload\n(as opposed to e.g. using `AffixAllocator` to store metadata together with\neach allocation). The layout is more compact (overhead is one bit per block),\nsearching for a free block during allocation enjoys better cache locality, and\ndeallocation does not touch memory around the payload being deallocated (which\nis often cold).\n\nAllocation requests are handled on a first-fit basis. Although linear in\ncomplexity, allocation is in practice fast because of the compact bookkeeping\nrepresentation, use of simple and fast bitwise routines, and caching of the\nfirst available block position. A known issue with this general approach is\nfragmentation, partially mitigated by coalescing. Since `BitmappedBlock` does\nnot need to maintain the allocated size, freeing memory implicitly coalesces\nfree blocks together. Also, tuning `blockSize` has a considerable impact on\nboth internal and external fragmentation.\n\nIf the last template parameter is set to `No.multiblock`, the allocator will only serve\nallocations which require at most `theBlockSize`. The `BitmappedBlock` has a specialized\nimplementation for single-block allocations which allows for greater performance,\nat the cost of not being able to allocate more than one block at a time.\n\nThe size of each block can be selected either during compilation or at run\ntime. Statically-known block sizes are frequent in practice and yield slightly\nbetter performance. To choose a block size statically, pass it as the `blockSize`\nparameter as in `BitmappedBlock!(4096)`. To choose a block\nsize parameter, use `BitmappedBlock!(chooseAtRuntime)` and pass the\nblock size to the constructor.\n\nParams:\n    theBlockSize = the length of a block, which must be a multiple of `theAlignment`\n\n    theAlignment = alignment of each block\n\n    ParentAllocator = allocator from which the `BitmappedBlock` will draw memory.\n        If set to `NullAllocator`, the storage must be passed via the constructor\n\n    f = `Yes.multiblock` to support allocations spanning across multiple blocks and\n        `No.multiblock` to support single block allocations.\n        Although limited by single block allocations, `No.multiblock` will generally\n        provide higher performance.\n*/\nstruct BitmappedBlock(size_t theBlockSize, uint theAlignment = platformAlignment,\n   ParentAllocator = NullAllocator, Flag!\"multiblock\" f = Yes.multiblock)\n{\n    version (StdDdoc)\n    {\n        /**\n        Constructs a block allocator given a hunk of memory, or a desired capacity\n        in bytes.\n        $(UL\n        $(LI If `ParentAllocator` is $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator),\n        only the constructor taking `data` is defined and the user is responsible for freeing `data` if desired.)\n        $(LI Otherwise, both constructors are defined. The `data`-based\n        constructor assumes memory has been allocated with the parent allocator.\n        The `capacity`-based constructor uses `ParentAllocator` to allocate\n        an appropriate contiguous hunk of memory. Regardless of the constructor\n        used, the destructor releases the memory by using `ParentAllocator.deallocate`.)\n        )\n        */\n        this(ubyte[] data);\n\n        /// Ditto\n        this(ubyte[] data, uint blockSize);\n\n        /// Ditto\n        this(size_t capacity);\n\n        /// Ditto\n        this(ParentAllocator parent, size_t capacity);\n\n        /// Ditto\n        this(size_t capacity, uint blockSize);\n\n        /// Ditto\n        this(ParentAllocator parent, size_t capacity, uint blockSize);\n\n        /**\n        If `blockSize == chooseAtRuntime`, `BitmappedBlock` offers a read/write\n        property `blockSize`. It must be set before any use of the allocator.\n        Otherwise (i.e. `theBlockSize` is a legit constant), `blockSize` is\n        an alias for `theBlockSize`. Whether constant or variable, must also be\n        a multiple of `alignment`. This constraint is `assert`ed statically\n        and dynamically.\n        */\n        alias blockSize = theBlockSize;\n\n        /**\n        The _alignment offered is user-configurable statically through parameter\n        `theAlignment`, defaulted to `platformAlignment`.\n        */\n        alias alignment = theAlignment;\n\n        /**\n        The _parent allocator. Depending on whether `ParentAllocator` holds state\n        or not, this is a member variable or an alias for\n        `ParentAllocator.instance`.\n        */\n        ParentAllocator parent;\n\n        /**\n        Returns the actual bytes allocated when `n` bytes are requested, i.e.\n        `n.roundUpToMultipleOf(blockSize)`.\n        */\n        pure nothrow @safe @nogc\n        size_t goodAllocSize(size_t n);\n\n        /**\n        Returns `Ternary.yes` if `b` belongs to the `BitmappedBlock` object,\n        `Ternary.no` otherwise. Never returns `Ternary.unkown`. (This\n        method is somewhat tolerant in that accepts an interior slice.)\n        */\n        pure nothrow @trusted @nogc\n        Ternary owns(const void[] b) const;\n\n        /**\n        Expands in place a buffer previously allocated by `BitmappedBlock`.\n        If instantiated with `No.multiblock`, the expansion fails if the new length\n        exceeds `theBlockSize`.\n        */\n        pure nothrow @trusted @nogc\n        bool expand(ref void[] b, immutable size_t delta);\n\n        /**\n        Deallocates a block previously allocated with this allocator.\n        */\n        nothrow @nogc\n        bool deallocate(void[] b);\n\n        /**\n        Allocates `s` bytes of memory and returns it, or `null` if memory\n        could not be allocated.\n\n        The following information might be of help with choosing the appropriate\n        block size. Actual allocation occurs in sizes multiple of the block size.\n        Allocating one block is the fastest because only one 0 bit needs to be\n        found in the metadata. Allocating 2 through 64 blocks is the next cheapest\n        because it affects a maximum of two `ulong` in the metadata.\n        Allocations greater than 64 blocks require a multiword search through the\n        metadata.\n\n        If instantiated with `No.multiblock`, it performs a search for the first zero\n        bit in the bitmap and sets it.\n        */\n        pure nothrow @trusted @nogc\n        void[] allocate(const size_t s);\n\n        /**\n        Allocates s bytes of memory and returns it, or `null` if memory could not be allocated.\n        `allocateFresh` behaves just like allocate, the only difference being that this always\n        returns unused(fresh) memory. Although there may still be available space in the `BitmappedBlock`,\n        `allocateFresh` could still return null, because all the available blocks have been previously deallocated.\n        */\n        @trusted void[] allocateFresh(const size_t s);\n\n        /**\n        If the `BitmappedBlock` object is empty (has no active allocation), allocates\n        all memory within and returns a slice to it. Otherwise, returns `null`\n        (i.e. no attempt is made to allocate the largest available block).\n        */\n        void[] allocateAll();\n\n        /**\n        Returns `Ternary.yes` if no memory is currently allocated with this\n        allocator, otherwise `Ternary.no`. This method never returns\n        `Ternary.unknown`.\n        */\n        pure nothrow @safe @nogc\n        Ternary empty();\n\n        /**\n        Forcibly deallocates all memory allocated by this allocator, making it\n        available for further allocations. Does not return memory to `ParentAllocator`.\n        */\n        pure nothrow @nogc\n        bool deallocateAll();\n\n        /**\n        Reallocates a block previously allocated with `alignedAllocate`. Contractions do not occur in place.\n        */\n        @system bool alignedReallocate(ref void[] b, size_t newSize, uint a);\n\n        /**\n        Reallocates a previously-allocated block. Contractions occur in place.\n        */\n        @system bool reallocate(ref void[] b, size_t newSize);\n\n        /**\n        Allocates a block with specified alignment `a`. The alignment must be a\n        power of 2. If `a <= alignment`, function forwards to `allocate`.\n        Otherwise, it attempts to overallocate and then adjust the result for\n        proper alignment. In the worst case the slack memory is around two blocks.\n        */\n        void[] alignedAllocate(size_t n, uint a);\n\n        /**\n        If `ParentAllocator` is not `NullAllocator` and defines `deallocate`,\n        the destructor is defined to deallocate the block held.\n        */\n        ~this();\n    }\n    else\n    {\n        @system unittest\n        {\n            import std.algorithm.comparison : max;\n            import std.experimental.allocator.mallocator : AlignedMallocator;\n            auto m = cast(ubyte[])(AlignedMallocator.instance.alignedAllocate(1024 * 64,\n                                    max(theAlignment, cast(uint) size_t.sizeof)));\n            scope(exit) () nothrow @nogc { AlignedMallocator.instance.deallocate(m); }();\n            static if (theBlockSize == chooseAtRuntime)\n            {\n                testAllocator!(() => BitmappedBlock!(theBlockSize, theAlignment, NullAllocator)(m, 64));\n            }\n            else\n            {\n                testAllocator!(() => BitmappedBlock!(theBlockSize, theAlignment, NullAllocator)(m));\n            }\n        }\n        mixin BitmappedBlockImpl!(false, f == Yes.multiblock);\n    }\n}\n\n///\n@system unittest\n{\n    // Create a block allocator on top of a 10KB stack region.\n    import std.experimental.allocator.building_blocks.region : InSituRegion;\n    import std.traits : hasMember;\n    InSituRegion!(10_240, 64) r;\n    auto a = BitmappedBlock!(64, 64)(cast(ubyte[])(r.allocateAll()));\n    static assert(hasMember!(InSituRegion!(10_240, 64), \"allocateAll\"));\n    const b = a.allocate(100);\n    assert(b.length == 100);\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Flag, Yes;\n\n    enum blockSize = 64;\n    enum numBlocks = 10;\n\n    // The 'BitmappedBlock' is implicitly instantiated with Yes.multiblock\n    auto a = BitmappedBlock!(blockSize, 8, Mallocator, Yes.multiblock)(numBlocks * blockSize);\n\n    // Instantiated with Yes.multiblock, can allocate more than one block at a time\n    void[] buf = a.allocate(2 * blockSize);\n    assert(buf.length == 2 * blockSize);\n    assert(a.deallocate(buf));\n\n    // Can also allocate less than one block\n    buf = a.allocate(blockSize / 2);\n    assert(buf.length == blockSize / 2);\n\n    // Expands inside the same block\n    assert(a.expand(buf, blockSize / 2));\n    assert(buf.length == blockSize);\n\n    // If Yes.multiblock, can expand past the size of a single block\n    assert(a.expand(buf, 3 * blockSize));\n    assert(buf.length == 4 * blockSize);\n    assert(a.deallocate(buf));\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Flag, No;\n\n    enum blockSize = 64;\n    auto a = BitmappedBlock!(blockSize, 8, Mallocator, No.multiblock)(1024 * blockSize);\n\n    // Since instantiated with No.multiblock, can only allocate at most the block size\n    void[] buf = a.allocate(blockSize + 1);\n    assert(buf is null);\n\n    buf = a.allocate(blockSize);\n    assert(buf.length == blockSize);\n    assert(a.deallocate(buf));\n\n    // This is also fine, because it's less than the block size\n    buf = a.allocate(blockSize / 2);\n    assert(buf.length == blockSize / 2);\n\n    // Can expand the buffer until its length is at most 64\n    assert(a.expand(buf, blockSize / 2));\n    assert(buf.length == blockSize);\n\n    // Cannot expand anymore\n    assert(!a.expand(buf, 1));\n    assert(a.deallocate(buf));\n}\n\n// Test instantiation with stateful allocators\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.experimental.allocator.building_blocks.region : Region;\n    auto r = Region!Mallocator(1024 * 96);\n    auto a = BitmappedBlock!(chooseAtRuntime, 8, Region!Mallocator*, No.multiblock)(&r, 1024 * 64, 1024);\n}\n\n/**\nThe threadsafe version of the $(LREF BitmappedBlock).\nThe semantics of the `SharedBitmappedBlock` are identical to the regular $(LREF BitmappedBlock).\n\nParams:\n    theBlockSize = the length of a block, which must be a multiple of `theAlignment`\n\n    theAlignment = alignment of each block\n\n    ParentAllocator = allocator from which the `BitmappedBlock` will draw memory.\n        If set to `NullAllocator`, the storage must be passed via the constructor\n\n    f = `Yes.multiblock` to support allocations spanning across multiple blocks and\n        `No.multiblock` to support single block allocations.\n        Although limited by single block allocations, `No.multiblock` will generally\n        provide higher performance.\n*/\nshared struct SharedBitmappedBlock(size_t theBlockSize, uint theAlignment = platformAlignment,\n   ParentAllocator = NullAllocator, Flag!\"multiblock\" f = Yes.multiblock)\n{\n    version (StdDdoc)\n    {\n        /**\n        Constructs a block allocator given a hunk of memory, or a desired capacity\n        in bytes.\n        $(UL\n        $(LI If `ParentAllocator` is $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator),\n        only the constructor taking `data` is defined and the user is responsible for freeing `data` if desired.)\n        $(LI Otherwise, both constructors are defined. The `data`-based\n        constructor assumes memory has been allocated with the parent allocator.\n        The `capacity`-based constructor uses `ParentAllocator` to allocate\n        an appropriate contiguous hunk of memory. Regardless of the constructor\n        used, the destructor releases the memory by using `ParentAllocator.deallocate`.)\n        )\n        */\n        this(ubyte[] data);\n\n        /// Ditto\n        this(ubyte[] data, uint blockSize);\n\n        /// Ditto\n        this(size_t capacity);\n\n        /// Ditto\n        this(ParentAllocator parent, size_t capacity);\n\n        /// Ditto\n        this(size_t capacity, uint blockSize);\n\n        /// Ditto\n        this(ParentAllocator parent, size_t capacity, uint blockSize);\n\n        /**\n        If `blockSize == chooseAtRuntime`, `SharedBitmappedBlock` offers a read/write\n        property `blockSize`. It must be set before any use of the allocator.\n        Otherwise (i.e. `theBlockSize` is a legit constant), `blockSize` is\n        an alias for `theBlockSize`. Whether constant or variable, must also be\n        a multiple of `alignment`. This constraint is `assert`ed statically\n        and dynamically.\n        */\n        alias blockSize = theBlockSize;\n\n        /**\n        The _alignment offered is user-configurable statically through parameter\n        `theAlignment`, defaulted to `platformAlignment`.\n        */\n        alias alignment = theAlignment;\n\n        /**\n        The _parent allocator. Depending on whether `ParentAllocator` holds state\n        or not, this is a member variable or an alias for\n        `ParentAllocator.instance`.\n        */\n        ParentAllocator parent;\n\n        /**\n        Returns the actual bytes allocated when `n` bytes are requested, i.e.\n        `n.roundUpToMultipleOf(blockSize)`.\n        */\n        pure nothrow @safe @nogc\n        size_t goodAllocSize(size_t n);\n\n        /**\n        Returns `Ternary.yes` if `b` belongs to the `SharedBitmappedBlock` object,\n        `Ternary.no` otherwise. Never returns `Ternary.unkown`. (This\n        method is somewhat tolerant in that accepts an interior slice.)\n        */\n        pure nothrow @trusted @nogc\n        Ternary owns(const void[] b) const;\n\n        /**\n        Expands in place a buffer previously allocated by `SharedBitmappedBlock`.\n        Expansion fails if the new length exceeds the block size.\n        */\n        bool expand(ref void[] b, immutable size_t delta);\n\n        /**\n        Deallocates the given buffer `b`, by atomically setting the corresponding\n        bit to `0`. `b` must be valid, and cannot contain multiple adjacent `blocks`.\n        */\n        nothrow @nogc\n        bool deallocate(void[] b);\n\n        /**\n        Allocates `s` bytes of memory and returns it, or `null` if memory\n        could not be allocated.\n\n        The `SharedBitmappedBlock` cannot allocate more than the given block size.\n        Allocations are satisfied by searching the first unset bit in the bitmap,\n        and atomically setting it.\n        In rare memory pressure scenarios, the allocation could fail.\n        */\n        nothrow @trusted @nogc\n        void[] allocate(const size_t s);\n\n        /**\n        Allocates s bytes of memory and returns it, or `null` if memory could not be allocated.\n        `allocateFresh` behaves just like allocate, the only difference being that this always\n        returns unused(fresh) memory. Although there may still be available space in the `SharedBitmappedBlock`,\n        `allocateFresh` could still return null, because all the available blocks have been previously deallocated.\n        */\n        @trusted void[] allocateFresh(const size_t s);\n\n        /**\n        If the `SharedBitmappedBlock` object is empty (has no active allocation), allocates\n        all memory within and returns a slice to it. Otherwise, returns `null`\n        (i.e. no attempt is made to allocate the largest available block).\n        */\n        void[] allocateAll();\n\n        /**\n        Returns `Ternary.yes` if no memory is currently allocated with this\n        allocator, otherwise `Ternary.no`. This method never returns\n        `Ternary.unknown`.\n        */\n        nothrow @safe @nogc\n        Ternary empty();\n\n        /**\n        Forcibly deallocates all memory allocated by this allocator, making it\n        available for further allocations. Does not return memory to `ParentAllocator`.\n        */\n        nothrow @nogc\n        bool deallocateAll();\n\n        /**\n        Reallocates a block previously allocated with `alignedAllocate`. Contractions do not occur in place.\n        */\n        @system bool alignedReallocate(ref void[] b, size_t newSize, uint a);\n\n        /**\n        Reallocates a previously-allocated block. Contractions occur in place.\n        */\n        @system bool reallocate(ref void[] b, size_t newSize);\n\n        /**\n        Allocates a block with specified alignment `a`. The alignment must be a\n        power of 2. If `a <= alignment`, function forwards to `allocate`.\n        Otherwise, it attempts to overallocate and then adjust the result for\n        proper alignment. In the worst case the slack memory is around two blocks.\n        */\n        void[] alignedAllocate(size_t n, uint a);\n\n        /**\n        If `ParentAllocator` is not `NullAllocator` and defines `deallocate`,\n        the destructor is defined to deallocate the block held.\n        */\n        ~this();\n    }\n    else\n    {\n        version (unittest)\n        @system unittest\n        {\n            import std.algorithm.comparison : max;\n            import std.experimental.allocator.mallocator : AlignedMallocator;\n            auto m = cast(ubyte[])(AlignedMallocator.instance.alignedAllocate(1024 * 64,\n                                    max(theAlignment, cast(uint) size_t.sizeof)));\n            scope(exit) () nothrow @nogc { AlignedMallocator.instance.deallocate(m); }();\n            static if (theBlockSize == chooseAtRuntime)\n            {\n                testAllocator!(() => SharedBitmappedBlock!(theBlockSize, theAlignment, NullAllocator)(m, 64));\n            }\n            else\n            {\n                testAllocator!(() => SharedBitmappedBlock!(theBlockSize, theAlignment, NullAllocator)(m));\n            }\n        }\n        mixin BitmappedBlockImpl!(true, f == Yes.multiblock);\n    }\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.experimental.allocator.common : platformAlignment;\n    import std.typecons : Flag, Yes, No;\n\n    // Create 'numThreads' threads, each allocating in parallel a chunk of memory\n    static void testAlloc(Allocator)(ref Allocator a, size_t allocSize)\n    {\n        import core.thread : ThreadGroup;\n        import std.algorithm.sorting : sort;\n        import core.internal.spinlock : SpinLock;\n\n        SpinLock lock = SpinLock(SpinLock.Contention.brief);\n        enum numThreads = 10;\n        void[][numThreads] buf;\n        size_t count = 0;\n\n        // Each threads allocates 'allocSize'\n        void fun()\n        {\n            void[] b = a.allocate(allocSize);\n            assert(b.length == allocSize);\n\n            lock.lock();\n            scope(exit) lock.unlock();\n\n            buf[count] = b;\n            count++;\n        }\n\n        auto tg = new ThreadGroup;\n        foreach (i; 0 .. numThreads)\n        {\n            tg.create(&fun);\n        }\n        tg.joinAll();\n\n        // Sorting the allocations made by each thread, we expect the buffers to be\n        // adjacent inside the SharedBitmappedBlock\n        sort!((a, b) => a.ptr < b.ptr)(buf[0 .. numThreads]);\n        foreach (i; 0 .. numThreads - 1)\n        {\n            assert(buf[i].ptr + a.goodAllocSize(buf[i].length) <= buf[i + 1].ptr);\n        }\n\n        // Deallocate everything\n        foreach (i; 0 .. numThreads)\n        {\n            assert(a.deallocate(buf[i]));\n        }\n    }\n\n    enum blockSize = 64;\n    auto alloc1 = SharedBitmappedBlock!(blockSize, platformAlignment, Mallocator, Yes.multiblock)(1024 * 1024);\n    auto alloc2 = SharedBitmappedBlock!(blockSize, platformAlignment, Mallocator, No.multiblock)(1024 * 1024);\n    testAlloc(alloc1, 2 * blockSize);\n    testAlloc(alloc2, blockSize);\n}\n\n@system unittest\n{\n    // Test chooseAtRuntime\n    // Create a block allocator on top of a 10KB stack region.\n    import std.experimental.allocator.building_blocks.region : InSituRegion;\n    import std.traits : hasMember;\n    InSituRegion!(10_240, 64) r;\n    uint blockSize = 64;\n    auto a = BitmappedBlock!(chooseAtRuntime, 64)(cast(ubyte[])(r.allocateAll()), blockSize);\n    static assert(hasMember!(InSituRegion!(10_240, 64), \"allocateAll\"));\n    const b = (() pure nothrow @safe @nogc => a.allocate(100))();\n    assert(b.length == 100);\n}\n\npure @safe unittest\n{\n    import std.typecons : Ternary;\n\n    auto a = (() @trusted => BitmappedBlock!(64, 64, NullAllocator, Yes.multiblock)(new ubyte[10_240]))();\n    () nothrow @nogc {\n        assert(a.empty == Ternary.yes);\n        const b = a.allocate(100);\n        assert(b.length == 100);\n        assert(a.empty == Ternary.no);\n    }();\n}\n\n@safe unittest\n{\n    import std.typecons : Ternary;\n\n    auto a = (() @trusted => SharedBitmappedBlock!(64, 64, NullAllocator, Yes.multiblock)(new ubyte[10_240]))();\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.yes);\n    const b = a.allocate(100);\n    assert(b.length == 100);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    testAllocator!(() => BitmappedBlock!(64, 8, GCAllocator)(1024 * 64));\n}\n\n@system unittest\n{\n    // Test chooseAtRuntime\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    uint blockSize = 64;\n    testAllocator!(() => BitmappedBlock!(chooseAtRuntime, 8, GCAllocator, Yes.multiblock)(1024 * 64, blockSize));\n    testAllocator!(() => BitmappedBlock!(chooseAtRuntime, 8, GCAllocator, No.multiblock)(1024 * 64, blockSize));\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    testAllocator!(() => SharedBitmappedBlock!(64, 8, Mallocator, Yes.multiblock)(1024 * 64));\n    testAllocator!(() => SharedBitmappedBlock!(64, 8, Mallocator, No.multiblock)(1024 * 64));\n}\n\n@system unittest\n{\n    // Test chooseAtRuntime\n    import std.experimental.allocator.mallocator : Mallocator;\n    uint blockSize = 64;\n    testAllocator!(() => SharedBitmappedBlock!(chooseAtRuntime, 8, Mallocator, Yes.multiblock)(1024 * 64, blockSize));\n    testAllocator!(() => SharedBitmappedBlock!(chooseAtRuntime, 8, Mallocator, No.multiblock)(1024 * 64, blockSize));\n}\n\n@system unittest\n{\n    static void testAllocateAll(size_t bs, bool isShared = true)(size_t blocks, uint blocksAtATime)\n    {\n        template attribAllocate(string size)\n        {\n            static if (isShared)\n            {\n                const char[] attribAllocate = \"(() nothrow @safe @nogc => a.allocate(\" ~ size ~ \"))()\";\n            }\n            else\n            {\n                const char[] attribAllocate = \"(() pure nothrow @safe @nogc => a.allocate(\" ~ size ~ \"))()\";\n            }\n        }\n\n        assert(bs);\n        import std.typecons : Ternary;\n        import std.algorithm.comparison : min;\n        import std.experimental.allocator.gc_allocator : GCAllocator;\n\n        static if (isShared)\n        {\n            auto a = SharedBitmappedBlock!(bs, min(bs, platformAlignment), NullAllocator)(\n                cast(ubyte[])(GCAllocator.instance.allocate((blocks * bs * 8 + blocks) / 8)));\n        }\n        else\n        {\n            auto a = BitmappedBlock!(bs, min(bs, platformAlignment), NullAllocator)(\n                cast(ubyte[])(GCAllocator.instance.allocate((blocks * bs * 8 + blocks) / 8)));\n        }\n\n        import std.conv : text;\n        assert(blocks >= a._blocks, text(blocks, \" < \", a._blocks));\n        blocks = a._blocks;\n\n        // test allocation of 0 bytes\n        auto x = mixin(attribAllocate!(\"0\"));\n        assert(x is null);\n        // test allocation of 1 byte\n        x = mixin(attribAllocate!(\"1\"));\n        assert(x.length == 1 || blocks == 0);\n        assert((() nothrow @nogc => a.deallocateAll())());\n        assert(a.empty() == Ternary.yes);\n        bool twice = true;\n\n    begin:\n        foreach (i; 0 .. blocks / blocksAtATime)\n        {\n            auto b = mixin(attribAllocate!(\"bs * blocksAtATime\"));\n            assert(b.length == bs * blocksAtATime, text(i, \": \", b.length));\n        }\n\n        assert(mixin(attribAllocate!(\"bs * blocksAtATime\")) is null);\n        if (a._blocks % blocksAtATime == 0)\n        {\n            assert(mixin(attribAllocate!(\"1\")) is null);\n        }\n\n        // Now deallocate all and do it again!\n        assert((() nothrow @nogc => a.deallocateAll())());\n\n        // Test deallocation\n\n        auto v = new void[][blocks / blocksAtATime];\n        foreach (i; 0 .. blocks / blocksAtATime)\n        {\n            auto b = mixin(attribAllocate!(\"bs * blocksAtATime\"));\n            assert(b.length == bs * blocksAtATime, text(i, \": \", b.length));\n            v[i] = b;\n        }\n        assert(mixin(attribAllocate!(\"bs * blocksAtATime\")) is null);\n        if (a._blocks % blocksAtATime == 0)\n        {\n            assert(mixin(attribAllocate!(\"1\")) is null);\n        }\n\n        foreach (i; 0 .. blocks / blocksAtATime)\n        {\n            () nothrow @nogc { a.deallocate(v[i]); }();\n        }\n\n        foreach (i; 0 .. blocks / blocksAtATime)\n        {\n            auto b = mixin(attribAllocate!(\"bs * blocksAtATime\"));\n            assert(b.length == bs * blocksAtATime, text(i, \": \", b.length));\n            v[i] = b;\n        }\n\n        foreach (i; 0 .. v.length)\n        {\n            () nothrow @nogc { a.deallocate(v[i]); }();\n        }\n\n        if (twice)\n        {\n            twice = false;\n            goto begin;\n        }\n\n        assert((() nothrow @nogc => a.deallocateAll())());\n\n        // test expansion\n        if (blocks >= blocksAtATime)\n        {\n            foreach (i; 0 .. blocks / blocksAtATime - 1)\n            {\n                auto b = mixin(attribAllocate!(\"bs * blocksAtATime\"));\n                assert(b.length == bs * blocksAtATime, text(i, \": \", b.length));\n                (cast(ubyte[]) b)[] = 0xff;\n                static if (isShared)\n                {\n                    assert((() nothrow @safe @nogc => a.expand(b, blocksAtATime * bs))()\n                            , text(i));\n                }\n                else\n                {\n                    assert((() pure nothrow @safe @nogc => a.expand(b, blocksAtATime * bs))()\n                            , text(i));\n                }\n                (cast(ubyte[]) b)[] = 0xfe;\n                assert(b.length == bs * blocksAtATime * 2, text(i, \": \", b.length));\n                a.reallocate(b, blocksAtATime * bs) || assert(0);\n                assert(b.length == bs * blocksAtATime, text(i, \": \", b.length));\n            }\n        }\n    }\n\n    testAllocateAll!(1)(0, 1);\n    testAllocateAll!(1, false)(0, 1);\n    testAllocateAll!(1)(8, 1);\n    testAllocateAll!(1, false)(8, 1);\n\n    testAllocateAll!(4096)(128, 1);\n    testAllocateAll!(4096, false)(128, 1);\n\n    testAllocateAll!(1)(0, 2);\n    testAllocateAll!(1)(128, 2);\n    testAllocateAll!(4096)(128, 2);\n\n    testAllocateAll!(1, false)(0, 2);\n    testAllocateAll!(1, false)(128, 2);\n    testAllocateAll!(4096, false)(128, 2);\n\n    testAllocateAll!(1)(0, 4);\n    testAllocateAll!(1)(128, 4);\n    testAllocateAll!(4096)(128, 4);\n\n    testAllocateAll!(1, false)(0, 4);\n    testAllocateAll!(1, false)(128, 4);\n    testAllocateAll!(4096, false)(128, 4);\n\n    testAllocateAll!(1)(0, 3);\n    testAllocateAll!(1)(24, 3);\n    testAllocateAll!(3008)(100, 1);\n    testAllocateAll!(3008)(100, 3);\n\n    testAllocateAll!(1, false)(0, 3);\n    testAllocateAll!(1, false)(24, 3);\n    testAllocateAll!(3008, false)(100, 1);\n    testAllocateAll!(3008, false)(100, 3);\n\n    testAllocateAll!(1)(0, 128);\n    testAllocateAll!(1)(128 * 1, 128);\n    testAllocateAll!(128 * 20)(13 * 128, 128);\n\n    testAllocateAll!(1, false)(0, 128);\n    testAllocateAll!(1, false)(128 * 1, 128);\n    testAllocateAll!(128 * 20, false)(13 * 128, 128);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    enum blocks = 10000;\n    int count = 0;\n\n    ubyte[] payload = cast(ubyte[]) Mallocator.instance.allocate(blocks * 16);\n    auto a = BitmappedBlock!(16, 16)(payload);\n    void[][] buf = cast(void[][]) Mallocator.instance.allocate((void[]).sizeof * blocks);\n\n    assert(!a.allocateFresh(0));\n    assert(!a._control[0]);\n\n    void[] b = a.allocate(256 * 16);\n    assert(b.length == 256 * 16);\n    count += 256;\n\n    assert(!a._control[count]);\n    b = a.allocateFresh(16);\n    assert(b.length == 16);\n    count++;\n    assert(a._control[count - 1]);\n\n    b = a.allocateFresh(16 * 300);\n    assert(b.length == 16 * 300);\n    count += 300;\n\n    for (int i = 0; i < count; i++)\n        assert(a._control[i]);\n    assert(!a._control[count]);\n\n    assert(a.expand(b, 313 * 16));\n    count += 313;\n\n    for (int i = 0; i < count; i++)\n        assert(a._control[i]);\n    assert(!a._control[count]);\n\n    b = a.allocate(64 * 16);\n    assert(b.length == 64 * 16);\n    count += 64;\n\n    b = a.allocateFresh(16);\n    assert(b.length == 16);\n    count++;\n\n    for (int i = 0; i < count; i++)\n        assert(a._control[i]);\n    assert(!a._control[count]);\n\n    assert(a.deallocateAll());\n    for (int i = 0; i < a._blocks; i++)\n        assert(!a._control[i]);\n\n    b = a.allocateFresh(257 * 16);\n    assert(b.length == 257 * 16);\n    for (int i = 0; i < count; i++)\n        assert(!a._control[i]);\n    for (int i = count; i < count + 257; i++)\n        assert(a._control[i]);\n    count += 257;\n    assert(!a._control[count]);\n\n    while (true)\n    {\n        b = a.allocate(16);\n        if (!b)\n            break;\n        assert(b.length == 16);\n    }\n\n    assert(!a.allocateFresh(16));\n    assert(a.deallocateAll());\n\n    assert(a.allocate(16).length == 16);\n    assert(!a.allocateFresh(16));\n}\n\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.random;\n\n    static void testAlloc(Allocator)()\n    {\n        auto numBlocks = [1, 64, 256];\n        enum blocks = 10000;\n        int iter = 0;\n\n        ubyte[] payload = cast(ubyte[]) Mallocator.instance.allocate(blocks * 16);\n        auto a = Allocator(payload);\n        void[][] buf = cast(void[][]) Mallocator.instance.allocate((void[]).sizeof * blocks);\n\n        auto rnd = Random();\n        while (iter < blocks)\n        {\n            int event = uniform(0, 2, rnd);\n            int doExpand = uniform(0, 2, rnd);\n            int allocSize = numBlocks[uniform(0, 3, rnd)] * 16;\n            int expandSize = numBlocks[uniform(0, 3, rnd)] * 16;\n            int doDeallocate = uniform(0, 2, rnd);\n\n            if (event) buf[iter] = a.allocate(allocSize);\n            else buf[iter] = a.allocateFresh(allocSize);\n\n            if (!buf[iter])\n                break;\n            assert(buf[iter].length == allocSize);\n\n            auto oldSize = buf[iter].length;\n            if (doExpand && a.expand(buf[iter], expandSize))\n                assert(buf[iter].length == expandSize + oldSize);\n\n            if (doDeallocate)\n            {\n                assert(a.deallocate(buf[iter]));\n                buf[iter] = null;\n            }\n\n            iter++;\n        }\n\n        while (iter < blocks)\n        {\n            buf[iter++] = a.allocate(16);\n            if (!buf[iter - 1])\n                break;\n            assert(buf[iter - 1].length == 16);\n        }\n\n        for (size_t i = 0; i < a._blocks; i++)\n            assert((cast(BitVector) a._control)[i]);\n\n        assert(!a.allocate(16));\n        for (size_t i = 0; i < iter; i++)\n        {\n            if (buf[i])\n                assert(a.deallocate(buf[i]));\n        }\n\n        for (size_t i = 0; i < a._blocks; i++)\n            assert(!(cast(BitVector) a._control)[i]);\n    }\n\n    testAlloc!(BitmappedBlock!(16, 16))();\n    testAlloc!(SharedBitmappedBlock!(16, 16))();\n}\n\n// Test totalAllocation and goodAllocSize\nnothrow @safe @nogc unittest\n{\n    BitmappedBlock!(8, 8, NullAllocator) h1;\n    assert(h1.goodAllocSize(1) == 8);\n    assert(h1.totalAllocation(1) >= 8);\n    assert(h1.totalAllocation(64) >= 64);\n    assert(h1.totalAllocation(8 * 64) >= 8 * 64);\n    assert(h1.totalAllocation(8 * 63) >= 8 * 63);\n    assert(h1.totalAllocation(8 * 64 + 1) >= 8 * 65);\n\n    BitmappedBlock!(64, 8, NullAllocator) h2;\n    assert(h2.goodAllocSize(1) == 64);\n    assert(h2.totalAllocation(1) >= 64);\n    assert(h2.totalAllocation(64 * 64) >= 64 * 64);\n\n    BitmappedBlock!(4096, 4096, NullAllocator) h3;\n    assert(h3.goodAllocSize(1) == 4096);\n    assert(h3.totalAllocation(1) >= 4096);\n    assert(h3.totalAllocation(64 * 4096) >= 64 * 4096);\n    assert(h3.totalAllocation(64 * 4096 + 1) >= 65 * 4096);\n}\n\n// Test owns\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.typecons : Ternary;\n\n    auto a = BitmappedBlock!(64, 8, GCAllocator)(1024 * 64);\n    const void[] buff = (() pure nothrow @safe @nogc => a.allocate(42))();\n\n    assert((() nothrow @safe @nogc => a.owns(buff))() == Ternary.yes);\n    assert((() nothrow @safe @nogc => a.owns(null))() == Ternary.no);\n}\n\n// BitmappedBlockWithInternalPointers\n/**\n\nA `BitmappedBlock` with additional structure for supporting `resolveInternalPointer`.\nTo that end, `BitmappedBlockWithInternalPointers` adds a\nbitmap (one bit per block) that marks object starts. The bitmap itself has\nvariable size and is allocated together with regular allocations.\n\nThe time complexity of `resolveInternalPointer` is $(BIGOH k), where `k`\nis the size of the object within which the internal pointer is looked up.\n\n*/\nstruct BitmappedBlockWithInternalPointers(\n    size_t theBlockSize, uint theAlignment = platformAlignment,\n    ParentAllocator = NullAllocator)\n{\n    import std.conv : text;\n    import std.typecons : Ternary;\n\n    static if (!stateSize!ParentAllocator)\n    @system unittest\n    {\n        import std.experimental.allocator.mallocator : AlignedMallocator;\n        auto m = cast(ubyte[])(AlignedMallocator.instance.alignedAllocate(1024 * 64,\n            theAlignment));\n        scope(exit) () nothrow @nogc { AlignedMallocator.instance.deallocate(m); }();\n        testAllocator!(() => BitmappedBlockWithInternalPointers(m));\n    }\n\n    // state {\n    private BitmappedBlock!(theBlockSize, theAlignment, ParentAllocator) _heap;\n    private BitVector _allocStart;\n    // }\n\n    /**\n    Constructors accepting desired capacity or a preallocated buffer, similar\n    in semantics to those of `BitmappedBlock`.\n    */\n    static if (!stateSize!ParentAllocator)\n    this(ubyte[] data)\n    {\n        _heap = BitmappedBlock!(theBlockSize, theAlignment, ParentAllocator)(data);\n    }\n\n    static if (stateSize!ParentAllocator)\n    this(ParentAllocator parent, ubyte[] data)\n    {\n        _heap = BitmappedBlock!(theBlockSize, theAlignment, ParentAllocator)(data);\n        _heap.parent = parent;\n    }\n\n    /// Ditto\n    static if (!is(ParentAllocator == NullAllocator) && !stateSize!ParentAllocator)\n    this(size_t capacity)\n    {\n        // Add room for the _allocStart vector\n        _heap = BitmappedBlock!(theBlockSize, theAlignment, ParentAllocator)\n            (capacity + capacity.divideRoundUp(64));\n    }\n\n    /// Ditto\n    static if (!is(ParentAllocator == NullAllocator) && stateSize!ParentAllocator)\n    this(ParentAllocator parent, size_t capacity)\n    {\n        // Add room for the _allocStart vector\n        _heap = BitmappedBlock!(theBlockSize, theAlignment, ParentAllocator)\n            (parent, capacity + capacity.divideRoundUp(64));\n    }\n\n    // Makes sure there's enough room for _allocStart\n    @safe\n    private bool ensureRoomForAllocStart(size_t len)\n    {\n        if (_allocStart.length >= len) return true;\n        // Must ensure there's room\n        immutable oldLength = _allocStart.rep.length;\n        immutable bits = len.roundUpToMultipleOf(64);\n        void[] b = _allocStart.rep;\n        if ((() @trusted => !_heap.reallocate(b, bits / 8))()) return false;\n        assert(b.length * 8 == bits);\n        _allocStart = BitVector((() @trusted => cast(ulong[]) b)());\n        assert(_allocStart.rep.length * 64 == bits);\n        _allocStart.rep[oldLength .. $] = ulong.max;\n        return true;\n    }\n\n    /**\n    Allocator primitives.\n    */\n    alias alignment = theAlignment;\n\n    /// Ditto\n    pure nothrow @safe @nogc\n    size_t goodAllocSize(size_t n)\n    {\n        return n.roundUpToMultipleOf(_heap.blockSize);\n    }\n\n    /// Ditto\n    void[] allocate(size_t bytes)\n    {\n        auto r = _heap.allocate(bytes);\n        if (!r.ptr) return r;\n        immutable block = (() @trusted => (r.ptr - _heap._payload.ptr) / _heap.blockSize)();\n        immutable blocks =\n            (r.length + _heap.blockSize - 1) / _heap.blockSize;\n        if (!ensureRoomForAllocStart(block + blocks))\n        {\n            // Failed, free r and bailout\n            () @trusted { _heap.deallocate(r); r = null; }();\n            return null;\n        }\n        assert(block < _allocStart.length);\n        assert(block + blocks <= _allocStart.length);\n        // Mark the _allocStart bits\n        assert(blocks > 0);\n        _allocStart[block] = 1;\n        _allocStart[block + 1 .. block + blocks] = 0;\n        assert(block + blocks == _allocStart.length\n            || _allocStart[block + blocks] == 1);\n        return r;\n    }\n\n    /// Ditto\n    void[] allocateAll()\n    {\n        auto r = _heap.allocateAll();\n        if (!r.ptr) return r;\n        // Carve space at the end for _allocStart\n        auto p = alignDownTo(r.ptr + r.length - 8, ulong.alignof);\n        r = r[0 .. p - r.ptr];\n        // Initialize _allocStart\n        _allocStart = BitVector(cast(ulong[]) p[0 .. 8]);\n        _allocStart[] = 0;\n        immutable block = (r.ptr - _heap._payload.ptr) / _heap.blockSize;\n        assert(block < _allocStart.length);\n        _allocStart[block] = 1;\n        return r;\n    }\n\n    /// Ditto\n    bool expand(ref void[] b, size_t bytes)\n    {\n        if (!bytes) return true;\n        if (b is null) return false;\n        immutable oldBlocks =\n            (b.length + _heap.blockSize - 1) / _heap.blockSize;\n        assert(oldBlocks);\n        immutable newBlocks =\n            (b.length + bytes + _heap.blockSize - 1) / _heap.blockSize;\n        assert(newBlocks >= oldBlocks);\n        immutable block = (() @trusted => (b.ptr - _heap._payload.ptr) / _heap.blockSize)();\n        assert(_allocStart[block]);\n        if (!ensureRoomForAllocStart(block + newBlocks)\n                || !_heap.expand(b, bytes))\n        {\n            return false;\n        }\n        // Zero only the expanded bits\n        _allocStart[block + oldBlocks .. block + newBlocks] = 0;\n        assert(_allocStart[block]);\n        return true;\n    }\n\n    /// Ditto\n    bool deallocate(void[] b)\n    {\n        // No need to touch _allocStart here - except for the first bit, it's\n        // meaningless in freed memory. The first bit is already 1.\n        return _heap.deallocate(b);\n        // TODO: one smart thing to do is reduce memory occupied by\n        // _allocStart if we're freeing the rightmost block.\n    }\n\n    /// Ditto\n    nothrow @safe @nogc\n    Ternary resolveInternalPointer(const void* p, ref void[] result)\n    {\n        if ((() @trusted => _heap._payload\n                    && (p < &_heap._payload[0]\n                        || p >= &_heap._payload[0] + _heap._payload.length))())\n        {\n            return Ternary.no;\n        }\n        // Find block start\n        auto block = (() @trusted => (p - &_heap._payload[0]) / _heap.blockSize)();\n        if (block >= _allocStart.length) return Ternary.no;\n        // Within an allocation, must find the 1 just to the left of it\n        auto i = _allocStart.find1Backward(block);\n        if (i == i.max) return Ternary.no;\n        auto j = _allocStart.find1(i + 1);\n        result = (() @trusted => _heap._payload.ptr[cast(size_t) (_heap.blockSize * i)\n                                                    .. cast(size_t) (_heap.blockSize * j)])();\n        return Ternary.yes;\n    }\n\n    /// Ditto\n    Ternary empty()\n    {\n        return _heap.empty;\n    }\n\n    // Currently unused\n    private void markAllAsUnused()\n    {\n        // Mark all deallocated memory with 1 so we minimize damage created by\n        // false pointers. TODO: improve speed.\n        foreach (i, ref e; _allocStart.rep)\n        {\n            // Set to 1 all bits in _allocStart[i] that were 0 in control, and\n            // leave the others unchanged.\n            // (0, 0) => 1; (0, 1) => 0; (1, 0) => 1; (1, 1) => 1\n            e |= ~_heap._control.rep[i];\n        }\n        // Now zero all control bits\n        _heap._control[] = 0;\n        // EXCEPT for the _allocStart block itself\n        markAsUsed(_allocStart.rep);\n    }\n\n    // Currently unused\n    private bool markAsUsed(void[] b)\n    {\n        // Locate position\n        immutable pos = b.ptr - _heap._payload.ptr;\n        assert(pos % _heap.blockSize == 0);\n        auto blockIdx = pos / _heap.blockSize;\n        if (_heap._control[blockIdx]) return false;\n        // Round up size to multiple of block size\n        auto blocks = b.length.divideRoundUp(_heap.blockSize);\n        _heap._control[blockIdx .. blockIdx + blocks] = 1;\n        return true;\n    }\n\n    // Currently unused\n    private void doneMarking()\n    {\n        // Nothing to do, what's free stays free.\n    }\n}\n\n@system unittest\n{\n    import std.typecons : Ternary;\n\n    auto h = BitmappedBlockWithInternalPointers!(4096)(new ubyte[4096 * 1024]);\n    assert((() nothrow @safe @nogc => h.empty)() == Ternary.yes);\n    auto b = (() pure nothrow @safe @nogc => h.allocate(123))();\n    assert(b.length == 123);\n    assert((() nothrow @safe @nogc => h.empty)() == Ternary.no);\n\n    void[] p;\n    void* offset = &b[0] + 17;\n    assert((() nothrow @safe @nogc => h.resolveInternalPointer(offset, p))() == Ternary.yes);\n    assert(p.ptr is b.ptr);\n    assert(p.length >= b.length);\n    b = (() pure nothrow @safe @nogc => h.allocate(4096))();\n\n    offset = &b[0];\n    assert((() nothrow @safe @nogc => h.resolveInternalPointer(offset, p))() == Ternary.yes);\n    assert(p is b);\n\n    offset = &b[0] + 11;\n    assert((() nothrow @safe @nogc => h.resolveInternalPointer(offset, p))() == Ternary.yes);\n    assert(p is b);\n\n    void[] unchanged = p;\n    offset = &b[0] - 40_970;\n    assert((() nothrow @safe @nogc => h.resolveInternalPointer(offset, p))() == Ternary.no);\n    assert(p is unchanged);\n\n    assert((() @safe => h.expand(b, 1))());\n    assert(b.length == 4097);\n    offset = &b[0] + 4096;\n    assert((() nothrow @safe @nogc => h.resolveInternalPointer(offset, p))() == Ternary.yes);\n    assert(p.ptr is b.ptr);\n\n    // Ensure deallocate inherits from parent\n    () nothrow @nogc { h.deallocate(b); }();\n}\n\n@system unittest\n{\n    auto h = BitmappedBlockWithInternalPointers!(4096)(new ubyte[4096 * 1024]);\n    assert((() pure nothrow @safe @nogc => h.goodAllocSize(1))() == 4096);\n}\n\n// Test instantiation with stateful allocators\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.experimental.allocator.building_blocks.region : Region;\n    auto r = Region!Mallocator(1024 * 1024);\n    auto h = BitmappedBlockWithInternalPointers!(4096, 8, Region!Mallocator*)(&r, 4096 * 1024);\n}\n\n/**\nReturns the number of most significant ones before a zero can be found in `x`.\nIf `x` contains no zeros (i.e. is equal to `ulong.max`), returns 64.\n*/\npure nothrow @safe @nogc\nprivate uint leadingOnes(ulong x)\n{\n    uint result = 0;\n    while (cast(long) x < 0)\n    {\n        ++result;\n        x <<= 1;\n    }\n    return result;\n}\n\n@safe unittest\n{\n    assert(leadingOnes(0) == 0);\n    assert(leadingOnes(~0UL) == 64);\n    assert(leadingOnes(0xF000_0000_0000_0000) == 4);\n    assert(leadingOnes(0xE400_0000_0000_0000) == 3);\n    assert(leadingOnes(0xC700_0200_0000_0000) == 2);\n    assert(leadingOnes(0x8000_0030_0000_0000) == 1);\n    assert(leadingOnes(0x2000_0000_0000_0000) == 0);\n}\n\n/**\nFinds a run of contiguous ones in `x` of length at least `n`.\n*/\npure nothrow @safe @nogc\nprivate uint findContigOnes(ulong x, uint n)\n{\n    while (n > 1)\n    {\n        immutable s = n >> 1;\n        x &= x << s;\n        n -= s;\n    }\n    return leadingOnes(~x);\n}\n\n@safe unittest\n{\n    assert(findContigOnes(0x0000_0000_0000_0300, 2) == 54);\n\n    assert(findContigOnes(~0UL, 1) == 0);\n    assert(findContigOnes(~0UL, 2) == 0);\n    assert(findContigOnes(~0UL, 32) == 0);\n    assert(findContigOnes(~0UL, 64) == 0);\n    assert(findContigOnes(0UL, 1) == 64);\n\n    assert(findContigOnes(0x4000_0000_0000_0000, 1) == 1);\n    assert(findContigOnes(0x0000_0F00_0000_0000, 4) == 20);\n}\n\n/*\nUnconditionally sets the bits from lsb through msb in w to zero.\n*/\npure nothrow @safe @nogc\nprivate void setBits(ref ulong w, uint lsb, uint msb)\n{\n    assert(lsb <= msb && msb < 64);\n    const mask = (ulong.max << lsb) & (ulong.max >> (63 - msb));\n    w |= mask;\n}\n\n@safe unittest\n{\n    ulong w;\n    w = 0; setBits(w, 0, 63); assert(w == ulong.max);\n    w = 0; setBits(w, 1, 63); assert(w == ulong.max - 1);\n    w = 6; setBits(w, 0, 1); assert(w == 7);\n    w = 6; setBits(w, 3, 3); assert(w == 14);\n}\n\n/* Are bits from lsb through msb in w zero? If so, make then 1\nand return the resulting w. Otherwise, just return 0.\n*/\npure nothrow @safe @nogc\nprivate bool setBitsIfZero(ref ulong w, uint lsb, uint msb)\n{\n    assert(lsb <= msb && msb < 64);\n    const mask = (ulong.max << lsb) & (ulong.max >> (63 - msb));\n    if (w & mask) return false;\n    w |= mask;\n    return true;\n}\n\n// Assigns bits in w from lsb through msb to zero.\npure nothrow @safe @nogc\nprivate void resetBits(ref ulong w, uint lsb, uint msb)\n{\n    assert(lsb <= msb && msb < 64);\n    const mask = (ulong.max << lsb) & (ulong.max >> (63 - msb));\n    w &= ~mask;\n}\n\n/*\nBit disposition is MSB=0 (leftmost, big endian).\n*/\nprivate struct BitVector\n{\n    ulong[] _rep;\n\n    auto rep(this _)() { return _rep; }\n\n    pure nothrow @safe @nogc\n    this(ulong[] data) { _rep = data; }\n\n    pure nothrow @safe @nogc\n    void opSliceAssign(bool b) { _rep[] = b ? ulong.max : 0; }\n\n    pure nothrow @safe @nogc\n    void opSliceAssign(bool b, ulong x, ulong y)\n    {\n        assert(x <= y && y <= _rep.length * 64);\n        if (x == y) return;\n        --y;\n        assert(x / 64 <= size_t.max);\n        immutable i1 = cast(size_t) (x / 64);\n        immutable uint b1 = 63 - x % 64;\n        assert(y / 64 <= size_t.max);\n        immutable i2 = cast(size_t) (y / 64);\n        immutable uint b2 = 63 - y % 64;\n        assert(i1 <= i2 && i2 < _rep.length);\n        if (i1 == i2)\n        {\n            // Inside the same word\n            assert(b1 >= b2);\n            if (b) setBits(_rep[i1], b2, b1);\n            else resetBits(_rep[i1], b2, b1);\n        }\n        else\n        {\n            // Spans multiple words\n            assert(i1 < i2);\n            if (b) setBits(_rep[i1], 0, b1);\n            else resetBits(_rep[i1], 0, b1);\n            _rep[i1 + 1 .. i2] = (b ? ulong.max : 0);\n            if (b) setBits(_rep[i2], b2, 63);\n            else resetBits(_rep[i2], b2, 63);\n        }\n    }\n\n    pure nothrow @safe @nogc\n    bool opIndex(ulong x)\n    {\n        assert(x < length);\n        return (_rep[cast(size_t) (x / 64)]\n            & (0x8000_0000_0000_0000UL >> (x % 64))) != 0;\n    }\n\n    pure nothrow @safe @nogc\n    void opIndexAssign(bool b, ulong x)\n    {\n        assert(x / 64 <= size_t.max);\n        immutable i = cast(size_t) (x / 64);\n        immutable j = 0x8000_0000_0000_0000UL >> (x % 64);\n        if (b) _rep[i] |= j;\n        else _rep[i] &= ~j;\n    }\n\n    pure nothrow @safe @nogc\n    ulong length() const\n    {\n        return _rep.length * 64;\n    }\n\n    /* Returns the index of the first 1 to the right of i (including i itself),\n    or length if not found.\n    */\n    pure nothrow @safe @nogc\n    ulong find1(ulong i)\n    {\n        assert(i < length);\n        assert(i / 64 <= size_t.max);\n        auto w = cast(size_t) (i / 64);\n        immutable b = i % 64; // 0 through 63, 0 when i == 0\n        immutable mask = ulong.max >> b;\n        if (auto current = _rep[w] & mask)\n        {\n            // Great, found\n            return w * 64 + leadingOnes(~current);\n        }\n        // The current word doesn't have the solution, find the leftmost 1\n        // going to the right.\n        for (++w; w < _rep.length; ++w)\n        {\n            if (auto current = _rep[w])\n            {\n                return w * 64 + leadingOnes(~current);\n            }\n        }\n        return length;\n    }\n\n    /* Returns the index of the first 1 to the left of i (including i itself),\n    or ulong.max if not found.\n    */\n    pure nothrow @safe @nogc\n    ulong find1Backward(ulong i)\n    {\n        assert(i < length);\n        auto w = cast(size_t) (i / 64);\n        immutable b = 63 - (i % 64); // 0 through 63, 63 when i == 0\n        immutable mask = ~((1UL << b) - 1);\n        assert(mask != 0);\n        // First, let's see if the current word has a bit larger than ours.\n        if (auto currentWord = _rep[w] & mask)\n        {\n            // Great, this word contains the result.\n            return w * 64 + 63 - currentWord.trailingZeros;\n        }\n        // The current word doesn't have the solution, find the rightmost 1\n        // going to the left.\n        while (w >= 1)\n        {\n            --w;\n            if (auto currentWord = _rep[w])\n                return w * 64 + (63 - currentWord.trailingZeros);\n        }\n        return ulong.max;\n    }\n\n    /// Are all bits zero?\n    pure nothrow @safe @nogc\n    bool allAre0() const\n    {\n        foreach (w; _rep) if (w) return false;\n        return true;\n    }\n\n    /// Are all bits one?\n    pure nothrow @safe @nogc\n    bool allAre1() const\n    {\n        foreach (w; _rep) if (w != ulong.max) return false;\n        return true;\n    }\n\n    pure nothrow @safe @nogc\n    ulong findZeros(immutable size_t howMany, ulong start)\n    {\n        assert(start < length);\n        assert(howMany > 64);\n        auto i = cast(size_t) (start / 64);\n        while (_rep[i] & 1)\n        {\n            // No trailing zeros in this word, try the next one\n            if (++i == _rep.length) return ulong.max;\n            start = i * 64;\n        }\n        // Adjust start to have only trailing zeros after it\n        auto prefixLength = 64;\n        while (_rep[i] & (ulong.max >> (64 - prefixLength)))\n        {\n            assert(prefixLength > 0);\n            --prefixLength;\n            ++start;\n        }\n\n        assert(howMany > prefixLength);\n        auto needed = howMany - prefixLength;\n        for (++i; needed >= 64; needed -= 64, ++i)\n        {\n            if (i >= _rep.length) return ulong.max;\n            if (_rep[i] != 0) return findZeros(howMany, i * 64);\n        }\n        // Leftover < 64 bits\n        assert(needed < 64);\n        if (!needed) return start;\n        if (i >= _rep.length) return ulong.max;\n        if (leadingOnes(~_rep[i]) >= needed) return start;\n        return findZeros(howMany, i * 64);\n    }\n}\n\n@safe unittest\n{\n    auto v = BitVector(new ulong[10]);\n    assert(v.length == 640);\n\n    v[] = 0;\n    v[53] = 1;\n    assert(v[52] == 0);\n    assert(v[53] == 1);\n    assert(v[54] == 0);\n\n    v[] = 0;\n    v[53 .. 55] = 1;\n    assert(v[52] == 0);\n    assert(v[53] == 1);\n    assert(v[54] == 1);\n    assert(v[55] == 0);\n\n    v[] = 0;\n    v[2 .. 65] = 1;\n    assert(v.rep[0] == 0x3FFF_FFFF_FFFF_FFFF);\n    assert(v.rep[1] == 0x8000_0000_0000_0000);\n    assert(v.rep[2] == 0);\n\n    v[] = 0;\n    assert(v.find1Backward(0) == ulong.max);\n    assert(v.find1Backward(43) == ulong.max);\n    assert(v.find1Backward(83) == ulong.max);\n\n    v[0] = 1;\n    assert(v.find1Backward(0) == 0);\n    assert(v.find1Backward(43) == 0);\n    import std.conv : text;\n    assert(v.find1Backward(83) == 0, text(v.find1Backward(83)));\n\n    v[0] = 0;\n    v[101] = 1;\n    assert(v.find1Backward(0) == ulong.max);\n    assert(v.find1Backward(43) == ulong.max);\n    assert(v.find1Backward(83) == ulong.max);\n    assert(v.find1Backward(100) == ulong.max);\n    assert(v.find1Backward(101) == 101);\n    assert(v.find1Backward(553) == 101);\n\n    v[0 .. v.length] = 0;\n    v[v.length .. v.length] = 0;\n    v[0 .. 0] = 0;\n\n    v[] = 0;\n    assert(v.find1(0) == v.length);\n    v[139] = 1;\n    assert(v.find1(0) == 139);\n    assert(v.find1(100) == 139);\n    assert(v.find1(138) == 139);\n    assert(v.find1(139) == 139);\n    assert(v.find1(140) == v.length);\n\n    v[] = 0;\n    assert(v.findZeros(100, 0) == 0);\n    foreach (i; 0 .. 500)\n        assert(v.findZeros(100, i) == i, text(v.findZeros(100, i), \" != \", i));\n    assert(v.findZeros(540, 99) == 99);\n    assert(v.findZeros(99, 540) == 540);\n    assert(v.findZeros(540, 100) == 100);\n    assert(v.findZeros(640, 0) == 0);\n    assert(v.findZeros(641, 1) == ulong.max);\n    assert(v.findZeros(641, 100) == ulong.max);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/bucketizer.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/bucketizer.d)\n*/\nmodule std.experimental.allocator.building_blocks.bucketizer;\n\n/**\n\nA `Bucketizer` uses distinct allocators for handling allocations of sizes in\nthe intervals $(D [min, min + step - 1]), $(D [min + step, min + 2 * step - 1]),\n$(D [min + 2 * step, min + 3 * step - 1]), `...`, $(D [max - step + 1, max]).\n\n`Bucketizer` holds a fixed-size array of allocators and dispatches calls to\nthem appropriately. The size of the array is $(D (max + 1 - min) / step), which\nmust be an exact division.\n\nAllocations for sizes smaller than `min` or larger than `max` are illegal\nfor `Bucketizer`. To handle them separately, `Segregator` may be of use.\n\n*/\nstruct Bucketizer(Allocator, size_t min, size_t max, size_t step)\n{\n    import common = std.experimental.allocator.common : roundUpToMultipleOf,\n           alignedAt;\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n\n    static assert((max - (min - 1)) % step == 0,\n        \"Invalid limits when instantiating \" ~ Bucketizer.stringof);\n\n    // state\n    /**\n    The array of allocators is publicly available for e.g. initialization and\n    inspection.\n    */\n    Allocator[(max + 1 - min) / step] buckets;\n\n    pure nothrow @safe @nogc\n    private Allocator* allocatorFor(size_t n)\n    {\n        const i = (n - min) / step;\n        return i < buckets.length ? &buckets[i] : null;\n    }\n\n    /**\n    The alignment offered is the same as `Allocator.alignment`.\n    */\n    enum uint alignment = Allocator.alignment;\n\n    /**\n    Rounds up to the maximum size of the bucket in which `bytes` falls.\n    */\n    pure nothrow @safe @nogc\n    size_t goodAllocSize(size_t bytes) const\n    {\n        // round up bytes such that bytes - min + 1 is a multiple of step\n        assert(bytes >= min);\n        const min_1 = min - 1;\n        return min_1 + roundUpToMultipleOf(bytes - min_1, step);\n    }\n\n    /**\n    Directs the call to either one of the `buckets` allocators.\n    */\n    void[] allocate(size_t bytes)\n    {\n        if (!bytes) return null;\n        if (auto a = allocatorFor(bytes))\n        {\n            const actual = goodAllocSize(bytes);\n            auto result = a.allocate(actual);\n            return result.ptr ? result.ptr[0 .. bytes] : null;\n        }\n        return null;\n    }\n\n    static if (hasMember!(Allocator, \"allocateZeroed\"))\n    package(std) void[] allocateZeroed()(size_t bytes)\n    {\n        if (!bytes) return null;\n        if (auto a = allocatorFor(bytes))\n        {\n            const actual = goodAllocSize(bytes);\n            auto result = a.allocateZeroed(actual);\n            return result.ptr ? result.ptr[0 .. bytes] : null;\n        }\n        return null;\n    }\n\n    /**\n    Allocates the requested `bytes` of memory with specified `alignment`.\n    Directs the call to either one of the `buckets` allocators. Defined only\n    if `Allocator` defines `alignedAllocate`.\n    */\n    static if (hasMember!(Allocator, \"alignedAllocate\"))\n    void[] alignedAllocate(size_t bytes, uint alignment)\n    {\n        if (!bytes) return null;\n        if (auto a = allocatorFor(bytes))\n        {\n            const actual = goodAllocSize(bytes);\n            auto result = a.alignedAllocate(actual, alignment);\n            return result !is null ? (() @trusted => (&result[0])[0 .. bytes])() : null;\n        }\n        return null;\n    }\n\n    /**\n    This method allows expansion within the respective bucket range. It succeeds\n    if both `b.length` and $(D b.length + delta) fall in a range of the form\n    $(D [min + k * step, min + (k + 1) * step - 1]).\n    */\n    bool expand(ref void[] b, size_t delta)\n    {\n        if (!b || delta == 0) return delta == 0;\n        assert(b.length >= min && b.length <= max);\n        const available = goodAllocSize(b.length);\n        const desired = b.length + delta;\n        if (available < desired) return false;\n        b = (() @trusted => b.ptr[0 .. desired])();\n        return true;\n    }\n\n    /**\n    This method allows reallocation within the respective bucket range. If both\n    `b.length` and `size` fall in a range of the form $(D [min + k *\n    step, min + (k + 1) * step - 1]), then reallocation is in place. Otherwise,\n    reallocation with moving is attempted.\n    */\n    bool reallocate(ref void[] b, size_t size)\n    {\n        if (size == 0)\n        {\n            deallocate(b);\n            b = null;\n            return true;\n        }\n        if (size >= b.length && expand(b, size - b.length))\n        {\n            return true;\n        }\n        assert(b.length >= min && b.length <= max);\n        if (goodAllocSize(size) == goodAllocSize(b.length))\n        {\n            b = b.ptr[0 .. size];\n            return true;\n        }\n        // Move cross buckets\n        return common.reallocate(this, b, size);\n    }\n\n    /**\n    Similar to `reallocate`, with alignment. Defined only if `Allocator`\n    defines `alignedReallocate`.\n    */\n    static if (hasMember!(Allocator, \"alignedReallocate\"))\n    bool alignedReallocate(ref void[] b, size_t size, uint a)\n    {\n        if (size == 0)\n        {\n            deallocate(b);\n            b = null;\n            return true;\n        }\n        if (size >= b.length && b.ptr.alignedAt(a) && expand(b, size - b.length))\n        {\n            return true;\n        }\n        assert(b.length >= min && b.length <= max);\n        if (goodAllocSize(size) == goodAllocSize(b.length) && b.ptr.alignedAt(a))\n        {\n            b = b.ptr[0 .. size];\n            return true;\n        }\n        // Move cross buckets\n        return common.alignedReallocate(this, b, size, a);\n    }\n\n    /**\n    Defined only if `Allocator` defines `owns`. Finds the owner of `b` and forwards the call to it.\n    */\n    static if (hasMember!(Allocator, \"owns\"))\n    Ternary owns(void[] b)\n    {\n        if (!b.ptr) return Ternary.no;\n        if (auto a = allocatorFor(b.length))\n        {\n            const actual = goodAllocSize(b.length);\n            return a.owns(b.ptr[0 .. actual]);\n        }\n        return Ternary.no;\n    }\n\n    /**\n    This method is only defined if `Allocator` defines `deallocate`.\n    */\n    static if (hasMember!(Allocator, \"deallocate\"))\n    bool deallocate(void[] b)\n    {\n        if (!b.ptr) return true;\n        if (auto a = allocatorFor(b.length))\n        {\n            a.deallocate(b.ptr[0 .. goodAllocSize(b.length)]);\n        }\n        return true;\n    }\n\n    /**\n    This method is only defined if all allocators involved define $(D\n    deallocateAll), and calls it for each bucket in turn. Returns `true` if all\n    allocators could deallocate all.\n    */\n    static if (hasMember!(Allocator, \"deallocateAll\"))\n    bool deallocateAll()\n    {\n        bool result = true;\n        foreach (ref a; buckets)\n        {\n            if (!a.deallocateAll()) result = false;\n        }\n        return result;\n    }\n\n    /**\n    This method is only defined if all allocators involved define $(D\n    resolveInternalPointer), and tries it for each bucket in turn.\n    */\n    static if (hasMember!(Allocator, \"resolveInternalPointer\"))\n    Ternary resolveInternalPointer(const void* p, ref void[] result)\n    {\n        foreach (ref a; buckets)\n        {\n            Ternary r = a.resolveInternalPointer(p, result);\n            if (r == Ternary.yes) return r;\n        }\n        return Ternary.no;\n    }\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.allocator_list : AllocatorList;\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.experimental.allocator.common : unbounded;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Ternary;\n    Bucketizer!(\n        FreeList!(\n            AllocatorList!(\n                (size_t n) => Region!Mallocator(max(n, 1024 * 1024))),\n            0, unbounded),\n        65, 512, 64) a;\n    auto b = a.allocate(400);\n    assert(b.length == 400);\n    assert(a.owns(b) == Ternary.yes);\n    a.deallocate(b);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.allocator_list : AllocatorList;\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.experimental.allocator.common : unbounded;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Ternary;\n\n    Bucketizer!(\n        FreeList!(\n            AllocatorList!(\n                (size_t n) => Region!Mallocator(max(n, 1024 * 1024)), Mallocator),\n            0, unbounded),\n        65, 512, 64) a;\n\n    assert((() pure nothrow @safe @nogc => a.goodAllocSize(65))() == 128);\n\n    auto b = a.allocate(100);\n    assert(b.length == 100);\n    // Make reallocate use extend\n    assert((() nothrow @nogc => a.reallocate(b, 101))());\n    assert(b.length == 101);\n    // Move cross buckets\n    assert((() nothrow @nogc => a.reallocate(b, 200))());\n    assert(b.length == 200);\n    // Free through realloc\n    assert((() nothrow @nogc => a.reallocate(b, 0))());\n    assert(b is null);\n    // Ensure deallocate inherits from parent allocators\n    assert((() nothrow @nogc => a.deallocate(b))());\n    assert((() nothrow @nogc => a.deallocateAll())());\n}\n\n// Test alignedAllocate\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlock;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n\n    Bucketizer!(BitmappedBlock!(64, 8, GCAllocator), 65, 512, 64) a;\n    foreach (ref bucket; a.buckets)\n    {\n        bucket = BitmappedBlock!(64, 8, GCAllocator)(new ubyte[1024]);\n    }\n\n    auto b = a.alignedAllocate(100, 16);\n    assert(b.length == 100);\n    assert(a.alignedAllocate(42, 16) is null);\n    assert(a.alignedAllocate(0, 16) is null);\n    assert((() pure nothrow @safe @nogc => a.expand(b, 0))());\n    assert(b.length == 100);\n    assert((() pure nothrow @safe @nogc => a.expand(b, 28))());\n    assert(b.length == 128);\n    assert((() pure nothrow @safe @nogc => !a.expand(b, 1))());\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlock;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n\n    Bucketizer!(BitmappedBlock!(64, 8, GCAllocator), 1, 512, 64) a;\n    foreach (ref bucket; a.buckets)\n    {\n        bucket = BitmappedBlock!(64, 8, GCAllocator)(new ubyte[1024]);\n    }\n\n    auto b = a.alignedAllocate(1, 4);\n    assert(b.length == 1);\n    // Make reallocate use extend\n    assert(a.alignedReallocate(b, 11, 4));\n    assert(b.length == 11);\n    // Make reallocate use use realloc because of alignment change\n    assert(a.alignedReallocate(b, 21, 16));\n    assert(b.length == 21);\n    // Make reallocate use extend\n    assert(a.alignedReallocate(b, 22, 16));\n    assert(b.length == 22);\n    // Move cross buckets\n    assert(a.alignedReallocate(b, 101, 16));\n    assert(b.length == 101);\n    // Free through realloc\n    assert(a.alignedReallocate(b, 0, 16));\n    assert(b is null);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/fallback_allocator.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/fallback_allocator.d)\n*/\nmodule std.experimental.allocator.building_blocks.fallback_allocator;\n\nimport std.experimental.allocator.common;\n\n/**\n`FallbackAllocator` is the allocator equivalent of an \"or\" operator in\nalgebra. An allocation request is first attempted with the `Primary`\nallocator. If that returns `null`, the request is forwarded to the $(D\nFallback) allocator. All other requests are dispatched appropriately to one of\nthe two allocators.\n\nIn order to work, `FallbackAllocator` requires that `Primary` defines the\n`owns` method. This is needed in order to decide which allocator was\nresponsible for a given allocation.\n\n`FallbackAllocator` is useful for fast, special-purpose allocators backed up\nby general-purpose allocators. The example below features a stack region backed\nup by the `GCAllocator`.\n*/\nstruct FallbackAllocator(Primary, Fallback)\n{\n    import std.algorithm.comparison : min;\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n\n    // Need both allocators to be stateless\n    // This is to avoid using default initialized stateful allocators\n    static if (!stateSize!Primary && !stateSize!Fallback)\n    @system unittest\n    {\n        testAllocator!(() => FallbackAllocator());\n    }\n\n    /// The primary allocator.\n    static if (stateSize!Primary) Primary primary;\n    else alias primary = Primary.instance;\n\n    /// The fallback allocator.\n    static if (stateSize!Fallback) Fallback fallback;\n    else alias fallback = Fallback.instance;\n\n    /**\n    If both `Primary` and `Fallback` are stateless, `FallbackAllocator`\n    defines a static instance called `instance`.\n    */\n    static if (!stateSize!Primary && !stateSize!Fallback)\n    {\n        static FallbackAllocator instance;\n    }\n\n    /**\n    The alignment offered is the minimum of the two allocators' alignment.\n    */\n    enum uint alignment = min(Primary.alignment, Fallback.alignment);\n\n    /**\n    Allocates memory trying the primary allocator first. If it returns $(D\n    null), the fallback allocator is tried.\n    */\n    void[] allocate(size_t s)\n    {\n        auto result = primary.allocate(s);\n        return result.length == s ? result : fallback.allocate(s);\n    }\n\n    static if (hasMember!(Primary, \"allocateZeroed\")\n            || (hasMember!(Fallback, \"allocateZeroed\")))\n    package(std) void[] allocateZeroed()(size_t s)\n    {\n        // Try to allocate with primary.\n        static if (hasMember!(Primary, \"allocateZeroed\"))\n        {\n            void[] result = primary.allocateZeroed(s);\n            if (result.length == s) return result;\n        }\n        else\n        {\n            void[] result = primary.allocate(s);\n            if (result.length == s)\n            {\n                (() @trusted => (cast(ubyte[]) result)[] = 0)();\n                return result;\n            }\n        }\n        // Allocate with fallback.\n        static if (hasMember!(Fallback, \"allocateZeroed\"))\n        {\n            return fallback.allocateZeroed(s);\n        }\n        else\n        {\n            result = fallback.allocate(s);\n            (() @trusted => (cast(ubyte[]) result)[] = 0)(); // OK even if result is null.\n            return result;\n        }\n    }\n\n    /**\n    `FallbackAllocator` offers `alignedAllocate` iff at least one of the\n    allocators also offers it. It attempts to allocate using either or both.\n    */\n    static if (hasMember!(Primary, \"alignedAllocate\")\n        || hasMember!(Fallback, \"alignedAllocate\"))\n    void[] alignedAllocate(size_t s, uint a)\n    {\n        static if (hasMember!(Primary, \"alignedAllocate\"))\n        {{\n            auto result = primary.alignedAllocate(s, a);\n            if (result.length == s) return result;\n        }}\n        static if (hasMember!(Fallback, \"alignedAllocate\"))\n        {{\n            auto result = fallback.alignedAllocate(s, a);\n            if (result.length == s) return result;\n        }}\n        return null;\n    }\n\n    /**\n\n    `expand` is defined if and only if at least one of the allocators\n    defines `expand`. It works as follows. If `primary.owns(b)`, then the\n    request is forwarded to `primary.expand` if it is defined, or fails\n    (returning `false`) otherwise. If `primary` does not own `b`, then\n    the request is forwarded to `fallback.expand` if it is defined, or fails\n    (returning `false`) otherwise.\n\n    */\n    static if (hasMember!(Primary, \"owns\")\n        && (hasMember!(Primary, \"expand\") || hasMember!(Fallback, \"expand\")))\n    bool expand(ref void[] b, size_t delta)\n    {\n        if (!delta) return true;\n        if (!b.ptr) return false;\n        if (primary.owns(b) == Ternary.yes)\n        {\n            static if (hasMember!(Primary, \"expand\"))\n                return primary.expand(b, delta);\n            else\n                return false;\n        }\n        static if (hasMember!(Fallback, \"expand\"))\n            return fallback.expand(b, delta);\n        else\n            return false;\n    }\n\n    /**\n\n    `reallocate` works as follows. If `primary.owns(b)`, then $(D\n    primary.reallocate(b, newSize)) is attempted. If it fails, an attempt is\n    made to move the allocation from `primary` to `fallback`.\n\n    If `primary` does not own `b`, then $(D fallback.reallocate(b,\n    newSize)) is attempted. If that fails, an attempt is made to move the\n    allocation from `fallback` to `primary`.\n\n    */\n    static if (hasMember!(Primary, \"owns\"))\n    bool reallocate(ref void[] b, size_t newSize)\n    {\n        bool crossAllocatorMove(From, To)(ref From from, ref To to)\n        {\n            auto b1 = to.allocate(newSize);\n            if (b1.length != newSize) return false;\n            if (b.length < newSize) b1[0 .. b.length] = b[];\n            else b1[] = b[0 .. newSize];\n            static if (hasMember!(From, \"deallocate\"))\n                from.deallocate(b);\n            b = b1;\n            return true;\n        }\n\n        if (b is null || primary.owns(b) == Ternary.yes)\n        {\n            return primary.reallocate(b, newSize)\n                // Move from primary to fallback\n                || crossAllocatorMove(primary, fallback);\n        }\n        return fallback.reallocate(b, newSize)\n            // Interesting. Move from fallback to primary.\n            || crossAllocatorMove(fallback, primary);\n    }\n\n    static if (hasMember!(Primary, \"owns\")\n        && (hasMember!(Primary, \"alignedAllocate\")\n            || hasMember!(Fallback, \"alignedAllocate\")))\n    bool alignedReallocate(ref void[] b, size_t newSize, uint a)\n    {\n        bool crossAllocatorMove(From, To)(ref From from, ref To to)\n        {\n            static if (!hasMember!(To, \"alignedAllocate\"))\n            {\n                return false;\n            }\n            else\n            {\n                auto b1 = to.alignedAllocate(newSize, a);\n                if (b1.length != newSize) return false;\n                if (b.length < newSize) b1[0 .. b.length] = b[];\n                else b1[] = b[0 .. newSize];\n                static if (hasMember!(From, \"deallocate\"))\n                    from.deallocate(b);\n                b = b1;\n                return true;\n            }\n        }\n\n        static if (hasMember!(Primary, \"alignedAllocate\"))\n        {\n            if (b is null || primary.owns(b) == Ternary.yes)\n            {\n                return primary.alignedReallocate(b, newSize, a)\n                    || crossAllocatorMove(primary, fallback);\n            }\n        }\n        static if (hasMember!(Fallback, \"alignedAllocate\"))\n        {\n            return fallback.alignedReallocate(b, newSize, a)\n                || crossAllocatorMove(fallback, primary);\n        }\n        else\n        {\n            return false;\n        }\n    }\n\n    /**\n    `owns` is defined if and only if both allocators define `owns`.\n    Returns $(D primary.owns(b) | fallback.owns(b)).\n    */\n    static if (hasMember!(Primary, \"owns\") && hasMember!(Fallback, \"owns\"))\n    Ternary owns(void[] b)\n    {\n        return primary.owns(b) | fallback.owns(b);\n    }\n\n    /**\n    `resolveInternalPointer` is defined if and only if both allocators\n    define it.\n    */\n    static if (hasMember!(Primary, \"resolveInternalPointer\")\n        && hasMember!(Fallback, \"resolveInternalPointer\"))\n    Ternary resolveInternalPointer(const void* p, ref void[] result)\n    {\n        Ternary r = primary.resolveInternalPointer(p, result);\n        return r == Ternary.no ? fallback.resolveInternalPointer(p, result) : r;\n    }\n\n    /**\n    `deallocate` is defined if and only if at least one of the allocators\n    define    `deallocate`. It works as follows. If `primary.owns(b)`,\n    then the request is forwarded to `primary.deallocate` if it is defined,\n    or is a no-op otherwise. If `primary` does not own `b`, then the\n    request is forwarded to `fallback.deallocate` if it is defined, or is a\n    no-op otherwise.\n    */\n    static if (hasMember!(Primary, \"owns\") &&\n        (hasMember!(Primary, \"deallocate\")\n            || hasMember!(Fallback, \"deallocate\")))\n    bool deallocate(void[] b)\n    {\n        if (primary.owns(b) == Ternary.yes)\n        {\n            static if (hasMember!(Primary, \"deallocate\"))\n                return primary.deallocate(b);\n            else\n                return false;\n        }\n        else\n        {\n            static if (hasMember!(Fallback, \"deallocate\"))\n                return fallback.deallocate(b);\n            else\n                return false;\n        }\n    }\n\n    /**\n    `empty` is defined if both allocators also define it.\n\n    Returns: $(D primary.empty & fallback.empty)\n    */\n    static if (hasMember!(Primary, \"empty\")\n               && hasMember!(Fallback, \"empty\"))\n    Ternary empty()\n    {\n        return primary.empty & fallback.empty;\n    }\n}\n\n@system unittest\n{\n    import std.conv : text;\n    import std.experimental.allocator.building_blocks.region : InSituRegion;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.typecons : Ternary;\n    FallbackAllocator!(InSituRegion!16_384, GCAllocator) a;\n    // This allocation uses the stack\n    auto b1 = a.allocate(1024);\n    assert(b1.length == 1024, text(b1.length));\n    assert((() pure nothrow @safe @nogc => a.primary.owns(b1))() == Ternary.yes);\n    assert((() nothrow => a.reallocate(b1, 2048))());\n    assert(b1.length == 2048, text(b1.length));\n    assert((() pure nothrow @safe @nogc => a.primary.owns(b1))() == Ternary.yes);\n    // This large allocation will go to the GCAllocator\n    auto b2 = a.allocate(1024 * 1024);\n    assert((() pure nothrow @safe @nogc => a.primary.owns(b2))() == Ternary.no);\n    // Ensure deallocate inherits from parent allocators\n    () nothrow @nogc { a.deallocate(b1); }();\n    () nothrow @nogc { a.deallocate(b2); }();\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlockWithInternalPointers;\n    import std.typecons : Ternary;\n\n    alias A =\n        FallbackAllocator!(\n            BitmappedBlockWithInternalPointers!(4096),\n            BitmappedBlockWithInternalPointers!(4096)\n        );\n\n    A a = A(\n            BitmappedBlockWithInternalPointers!(4096)(new ubyte[4096 * 1024]),\n            BitmappedBlockWithInternalPointers!(4096)(new ubyte[4096 * 1024])\n    );\n\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.yes);\n    auto b = a.allocate(201);\n    assert(b.length == 201);\n    assert(a.reallocate(b, 202));\n    assert(b.length == 202);\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.no);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.typecons : Ternary;\n\n    auto a = FallbackAllocator!(Region!(), Region!())(\n                Region!()(new ubyte[4096 * 1024]),\n                Region!()(new ubyte[4096 * 1024]));\n\n    auto b = a.alignedAllocate(42, 8);\n    assert(b.length == 42);\n    assert((() nothrow @nogc => a.alignedReallocate(b, 100, 8))());\n    assert(b.length == 100);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlockWithInternalPointers;\n    import std.typecons : Ternary;\n\n    alias A =\n        FallbackAllocator!(\n            BitmappedBlockWithInternalPointers!(4096),\n            BitmappedBlockWithInternalPointers!(4096)\n        );\n\n    // Run testAllocator here since both allocators stateful\n    testAllocator!(\n        () => A(\n            BitmappedBlockWithInternalPointers!(4096)(new ubyte[4096 * 1024]),\n            BitmappedBlockWithInternalPointers!(4096)(new ubyte[4096 * 1024])\n        )\n    );\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Ternary;\n\n    alias a = FallbackAllocator!(Mallocator, Mallocator).instance;\n\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    assert((() nothrow @nogc => a.reallocate(b, 100))());\n    assert(b.length == 100);\n}\n\n/*\nForwards an argument from one function to another\n*/\nprivate auto ref forward(alias arg)()\n{\n    static if (__traits(isRef, arg))\n    {\n        return arg;\n    }\n    else\n    {\n        import std.algorithm.mutation : move;\n        return move(arg);\n    }\n}\n\n@safe unittest\n{\n    void fun(T)(auto ref T, string) { /* ... */ }\n    void gun(T...)(auto ref T args)\n    {\n        fun(forward!(args[0]), forward!(args[1]));\n    }\n    gun(42, \"hello\");\n    int x;\n    gun(x, \"hello\");\n}\n\n@safe unittest\n{\n    static void checkByRef(T)(auto ref T value)\n    {\n        static assert(__traits(isRef, value));\n    }\n\n    static void checkByVal(T)(auto ref T value)\n    {\n        static assert(!__traits(isRef, value));\n    }\n\n    static void test1(ref int a) { checkByRef(forward!a); }\n    static void test2(int a) { checkByVal(forward!a); }\n    static void test3() { int a; checkByVal(forward!a); }\n}\n\n/**\nConvenience function that uses type deduction to return the appropriate\n`FallbackAllocator` instance. To initialize with allocators that don't have\nstate, use their `it` static member.\n*/\nFallbackAllocator!(Primary, Fallback)\nfallbackAllocator(Primary, Fallback)(auto ref Primary p, auto ref Fallback f)\n{\n    alias R = FallbackAllocator!(Primary, Fallback);\n\n    static if (stateSize!Primary)\n        static if (stateSize!Fallback)\n            return R(forward!p, forward!f);\n        else\n            return R(forward!p);\n    else\n        static if (stateSize!Fallback)\n            return R(forward!f);\n        else\n            return R();\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.typecons : Ternary;\n    auto a = fallbackAllocator(Region!GCAllocator(1024), GCAllocator.instance);\n    auto b1 = a.allocate(1020);\n    assert(b1.length == 1020);\n    assert(a.primary.owns(b1) == Ternary.yes);\n    auto b2 = a.allocate(10);\n    assert(b2.length == 10);\n    assert(a.primary.owns(b2) == Ternary.no);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    testAllocator!(() => fallbackAllocator(Region!GCAllocator(1024), GCAllocator.instance));\n}\n\n// Ensure `owns` inherits function attributes\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : InSituRegion;\n    import std.typecons : Ternary;\n\n    FallbackAllocator!(InSituRegion!16_384, InSituRegion!16_384) a;\n    auto buff = a.allocate(42);\n    assert((() pure nothrow @safe @nogc => a.owns(buff))() == Ternary.yes);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.typecons : Ternary;\n\n    auto a = fallbackAllocator(GCAllocator.instance, GCAllocator.instance);\n    auto b = a.allocate(1020);\n    assert(b.length == 1020);\n\n    void[] p;\n    assert((() nothrow @safe @nogc => a.resolveInternalPointer(null, p))() == Ternary.no);\n    assert((() nothrow @safe @nogc => a.resolveInternalPointer(&b[0], p))() == Ternary.yes);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.typecons : Ternary;\n\n    alias A = FallbackAllocator!(Region!(), Region!());\n    auto a = A(Region!()(new ubyte[16_384]), Region!()(new ubyte[16_384]));\n\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    assert((() pure nothrow @safe @nogc => a.owns(b))() == Ternary.yes);\n    assert((() nothrow @safe @nogc => a.expand(b, 58))());\n    assert(b.length == 100);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/free_list.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/free_list.d)\n*/\nmodule std.experimental.allocator.building_blocks.free_list;\n\nimport std.experimental.allocator.common;\nimport std.typecons : Flag, Yes, No;\n\n/**\n\n$(HTTP en.wikipedia.org/wiki/Free_list, Free list allocator), stackable on top of\nanother allocator. Allocation requests between `min` and `max` bytes are\nrounded up to `max` and served from a singly-linked list of buffers\ndeallocated in the past. All other allocations are directed to $(D\nParentAllocator). Due to the simplicity of free list management, allocations\nfrom the free list are fast. If `adaptive` is set to `Yes.adaptive`,\nthe free list gradually reduces its size if allocations tend to use the parent\nallocator much more than the lists' available nodes.\n\nOne instantiation is of particular interest: $(D FreeList!(0, unbounded)) puts\nevery deallocation in the freelist, and subsequently serves any allocation from\nthe freelist (if not empty). There is no checking of size matching, which would\nbe incorrect for a freestanding allocator but is both correct and fast when an\nowning allocator on top of the free list allocator (such as `Segregator`) is\nalready in charge of handling size checking.\n\nThe following methods are defined if `ParentAllocator` defines them, and\nforward to it: `expand`, `owns`, `reallocate`.\n\n*/\nstruct FreeList(ParentAllocator,\n    size_t minSize, size_t maxSize = minSize,\n    Flag!\"adaptive\" adaptive = No.adaptive)\n{\n    import std.conv : text;\n    import std.exception : enforce;\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n    import std.experimental.allocator.building_blocks.null_allocator : NullAllocator;\n\n    static assert(minSize != unbounded, \"Use minSize = 0 for no low bound.\");\n    static assert(maxSize >= (void*).sizeof,\n        \"Maximum size must accommodate a pointer.\");\n\n    private enum unchecked = minSize == 0 && maxSize == unbounded;\n\n    private enum hasTolerance = !unchecked && (minSize != maxSize\n        || maxSize == chooseAtRuntime);\n\n    static if (minSize == chooseAtRuntime)\n    {\n        /**\n        Returns the smallest allocation size eligible for allocation from the\n        freelist. (If $(D minSize != chooseAtRuntime), this is simply an alias\n        for `minSize`.)\n        */\n        @property size_t min() const\n        {\n            assert(_min != chooseAtRuntime);\n            return _min;\n        }\n        /**\n        If `FreeList` has been instantiated with $(D minSize ==\n        chooseAtRuntime), then the `min` property is writable. Setting it\n        must precede any allocation.\n\n        Params:\n        low = new value for `min`\n\n        Precondition: $(D low <= max), or $(D maxSize == chooseAtRuntime) and\n        `max` has not yet been initialized. Also, no allocation has been\n        yet done with this allocator.\n\n        Postcondition: $(D min == low)\n        */\n        @property void min(size_t low)\n        {\n            assert(low <= max || max == chooseAtRuntime);\n            minimize;\n            _min = low;\n        }\n    }\n    else\n    {\n        alias min = minSize;\n    }\n\n    static if (maxSize == chooseAtRuntime)\n    {\n        /**\n        Returns the largest allocation size eligible for allocation from the\n        freelist. (If $(D maxSize != chooseAtRuntime), this is simply an alias\n        for `maxSize`.) All allocation requests for sizes greater than or\n        equal to `min` and less than or equal to `max` are rounded to $(D\n        max) and forwarded to the parent allocator. When the block fitting the\n        same constraint gets deallocated, it is put in the freelist with the\n        allocated size assumed to be `max`.\n        */\n        @property size_t max() const { return _max; }\n\n        /**\n        If `FreeList` has been instantiated with $(D maxSize ==\n        chooseAtRuntime), then the `max` property is writable. Setting it\n        must precede any allocation.\n\n        Params:\n        high = new value for `max`\n\n        Precondition: $(D high >= min), or $(D minSize == chooseAtRuntime) and\n        `min` has not yet been initialized. Also $(D high >= (void*).sizeof). Also, no allocation has been yet done with this allocator.\n\n        Postcondition: $(D max == high)\n        */\n        @property void max(size_t high)\n        {\n            assert((high >= min || min == chooseAtRuntime)\n                && high >= (void*).sizeof);\n            minimize;\n            _max = high;\n        }\n\n        @system unittest\n        {\n            import std.experimental.allocator.common : chooseAtRuntime;\n            import std.experimental.allocator.mallocator : Mallocator;\n\n            FreeList!(Mallocator, chooseAtRuntime, chooseAtRuntime) a;\n            a.min = 64;\n            a.max = 128;\n            assert(a.min == 64);\n            assert(a.max == 128);\n        }\n    }\n    else\n    {\n        alias max = maxSize;\n    }\n\n    private bool tooSmall(size_t n) const\n    {\n        static if (minSize == 0) return false;\n        else return n < min;\n    }\n\n    private bool tooLarge(size_t n) const\n    {\n        static if (maxSize == unbounded) return false;\n        else return n > max;\n    }\n\n    private bool freeListEligible(size_t n) const\n    {\n        static if (unchecked)\n        {\n            return true;\n        }\n        else\n        {\n            static if (minSize == 0)\n            {\n                if (!n) return false;\n            }\n            static if (minSize == maxSize && minSize != chooseAtRuntime)\n                return n == maxSize;\n            else\n                return !tooSmall(n) && !tooLarge(n);\n        }\n    }\n\n    static if (!unchecked)\n    private void[] blockFor(Node* p)\n    {\n        assert(p);\n        return (cast(void*) p)[0 .. max];\n    }\n\n    // statistics\n    static if (adaptive == Yes.adaptive)\n    {\n        private enum double windowLength = 1000.0;\n        private enum double tooFewMisses = 0.01;\n        private double probMiss = 1.0; // start with a high miss probability\n        private uint accumSamples, accumMisses;\n\n        void updateStats()\n        {\n            assert(accumSamples >= accumMisses);\n            /*\n            Given that for the past windowLength samples we saw misses with\n            estimated probability probMiss, and assuming the new sample wasMiss or\n            not, what's the new estimated probMiss?\n            */\n            probMiss = (probMiss * windowLength + accumMisses)\n                / (windowLength + accumSamples);\n            assert(probMiss <= 1.0);\n            accumSamples = 0;\n            accumMisses = 0;\n            // If probability to miss is under x%, yank one off the freelist\n            static if (!unchecked)\n            {\n                if (probMiss < tooFewMisses && _root)\n                {\n                    auto b = blockFor(_root);\n                    _root = _root.next;\n                    parent.deallocate(b);\n                }\n            }\n        }\n    }\n\n    private struct Node { Node* next; }\n    static assert(ParentAllocator.alignment >= Node.alignof);\n\n    // state\n    /**\n    The parent allocator. Depending on whether `ParentAllocator` holds state\n    or not, this is a member variable or an alias for\n    `ParentAllocator.instance`.\n    */\n    static if (stateSize!ParentAllocator) ParentAllocator parent;\n    else alias parent = ParentAllocator.instance;\n    private Node* root;\n    static if (minSize == chooseAtRuntime) private size_t _min = chooseAtRuntime;\n    static if (maxSize == chooseAtRuntime) private size_t _max = chooseAtRuntime;\n\n    /**\n    Alignment offered.\n    */\n    alias alignment = ParentAllocator.alignment;\n\n    /**\n    If $(D maxSize == unbounded), returns  `parent.goodAllocSize(bytes)`.\n    Otherwise, returns `max` for sizes in the interval $(D [min, max]), and\n    `parent.goodAllocSize(bytes)` otherwise.\n\n    Precondition:\n    If set at runtime, `min` and/or `max` must be initialized\n    appropriately.\n\n    Postcondition:\n    $(D result >= bytes)\n    */\n    size_t goodAllocSize(size_t bytes)\n    {\n        assert(minSize != chooseAtRuntime && maxSize != chooseAtRuntime);\n        static if (maxSize != unbounded)\n        {\n            if (freeListEligible(bytes))\n            {\n                assert(parent.goodAllocSize(max) == max,\n                    text(\"Wrongly configured freelist: maximum should be \",\n                        parent.goodAllocSize(max), \" instead of \", max));\n                return max;\n            }\n        }\n        return parent.goodAllocSize(bytes);\n    }\n\n    private void[] allocateEligible(string fillMode)(size_t bytes)\n    if (fillMode == \"void\" || fillMode == \"zero\")\n    {\n        enum bool isFillZero = fillMode == \"zero\";\n        assert(bytes);\n        if (root)\n        {\n            // faster\n            auto result = (cast(ubyte*) root)[0 .. bytes];\n            root = root.next;\n            static if (isFillZero) result[0 .. bytes] = 0;\n            return result;\n        }\n        // slower\n        static if (hasTolerance)\n        {\n            immutable toAllocate = max;\n        }\n        else\n        {\n            alias toAllocate = bytes;\n        }\n        assert(toAllocate == max || max == unbounded);\n        static if (isFillZero)\n            auto result = parent.allocateZeroed(toAllocate);\n        else\n            auto result = parent.allocate(toAllocate);\n        static if (hasTolerance)\n        {\n            if (result) result = result.ptr[0 .. bytes];\n        }\n        static if (adaptive == Yes.adaptive)\n        {\n            ++accumMisses;\n            updateStats;\n        }\n        return result;\n    }\n\n    /**\n    Allocates memory either off of the free list or from the parent allocator.\n    If `n` is within $(D [min, max]) or if the free list is unchecked\n    ($(D minSize == 0 && maxSize == size_t.max)), then the free list is\n    consulted first. If not empty (hit), the block at the front of the free\n    list is removed from the list and returned. Otherwise (miss), a new block\n    of `max` bytes is allocated, truncated to `n` bytes, and returned.\n\n    Params:\n    n = number of bytes to allocate\n\n    Returns:\n    The allocated block, or `null`.\n\n    Precondition:\n    If set at runtime, `min` and/or `max` must be initialized\n    appropriately.\n\n    Postcondition: $(D result.length == bytes || result is null)\n    */\n    void[] allocate(size_t n)\n    {\n        static if (adaptive == Yes.adaptive) ++accumSamples;\n        assert(n < size_t.max / 2);\n        // fast path\n        if (freeListEligible(n))\n        {\n            return allocateEligible!\"void\"(n);\n        }\n        // slower\n        static if (adaptive == Yes.adaptive)\n        {\n            updateStats;\n        }\n        return parent.allocate(n);\n    }\n\n    static if (hasMember!(ParentAllocator, \"allocateZeroed\"))\n    package(std) void[] allocateZeroed()(size_t n)\n    {\n        static if (adaptive == Yes.adaptive) ++accumSamples;\n        assert(n < size_t.max / 2);\n        // fast path\n        if (freeListEligible(n))\n        {\n            return allocateEligible!\"zero\"(n);\n        }\n        // slower\n        static if (adaptive == Yes.adaptive)\n        {\n            updateStats;\n        }\n        return parent.allocateZeroed(n);\n    }\n\n    // Forwarding methods\n    mixin(forwardToMember(\"parent\",\n        \"expand\", \"owns\", \"reallocate\"));\n\n    /**\n    If `block.length` is within $(D [min, max]) or if the free list is\n    unchecked ($(D minSize == 0 && maxSize == size_t.max)), then inserts the\n    block at the front of the free list. For all others, forwards to $(D\n    parent.deallocate) if `Parent.deallocate` is defined.\n\n    Params:\n    block = Block to deallocate.\n\n    Precondition:\n    If set at runtime, `min` and/or `max` must be initialized\n    appropriately. The block must have been allocated with this\n    freelist, and no dynamic changing of `min` or `max` is allowed to\n    occur between allocation and deallocation.\n    */\n    bool deallocate(void[] block)\n    {\n        if (freeListEligible(block.length))\n        {\n            if (min == 0)\n            {\n                // In this case a null pointer might have made it this far.\n                if (block is null) return true;\n            }\n            auto t = root;\n            root = cast(Node*) block.ptr;\n            root.next = t;\n            return true;\n        }\n        static if (hasMember!(ParentAllocator, \"deallocate\"))\n            return parent.deallocate(block);\n        else\n            return false;\n    }\n\n    /**\n    Defined only if `ParentAllocator` defines `deallocateAll`. If so,\n    forwards to it and resets the freelist.\n    */\n    static if (hasMember!(ParentAllocator, \"deallocateAll\"))\n    bool deallocateAll()\n    {\n        root = null;\n        return parent.deallocateAll();\n    }\n\n    /**\n    Nonstandard function that minimizes the memory usage of the freelist by\n    freeing each element in turn. Defined only if `ParentAllocator` defines\n    `deallocate`. $(D FreeList!(0, unbounded)) does not have this function.\n    */\n    static if (hasMember!(ParentAllocator, \"deallocate\") && !unchecked)\n    void minimize()\n    {\n        while (root)\n        {\n            auto nuke = blockFor(root);\n            root = root.next;\n            parent.deallocate(nuke);\n        }\n    }\n\n    /**\n    If `ParentAllocator` defines `deallocate`, the list frees all nodes\n    on destruction. $(D FreeList!(0, unbounded)) does not deallocate the memory\n    on destruction.\n    */\n    static if (!is(ParentAllocator == NullAllocator) &&\n        hasMember!(ParentAllocator, \"deallocate\") && !unchecked)\n    ~this()\n    {\n        minimize();\n    }\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.experimental.allocator.building_blocks.stats_collector\n        : StatsCollector, Options;\n\n    struct StatsCollectorWrapper {\n        ~this()\n        {\n            // buf2 should still be around and buf1 deallocated\n            assert(parent.numDeallocate == 1);\n            assert(parent.bytesUsed == 16);\n        }\n        static StatsCollector!(Mallocator, Options.all) parent;\n        alias parent this;\n    }\n\n    FreeList!(StatsCollectorWrapper, 16, 16) fl;\n    auto buf1 = fl.allocate(16);\n    auto buf2 = fl.allocate(16);\n    assert(fl.parent.bytesUsed == 32);\n\n    // After this, the list has 1 node, so no actual deallocation by Mallocator\n    fl.deallocate(buf1);\n    assert(fl.parent.bytesUsed == 32);\n\n    // Destruction should only deallocate the node\n    destroy(fl);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    FreeList!(GCAllocator, 0, 8) fl;\n    assert(fl.root is null);\n    auto b1 = fl.allocate(7);\n    fl.allocate(8);\n    assert(fl.root is null);\n    // Ensure deallocate inherits from parent\n    () nothrow @nogc { fl.deallocate(b1); }();\n    assert(fl.root !is null);\n    fl.allocate(8);\n    assert(fl.root is null);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    FreeList!(GCAllocator, 0, 16) fl;\n    // Not @nogc because of std.conv.text\n    assert((() nothrow @safe /*@nogc*/ => fl.goodAllocSize(1))() == 16);\n}\n\n// Test that deallocateAll infers from parent\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n\n    auto fl = FreeList!(Region!(), 0, 16)(Region!()(new ubyte[1024 * 64]));\n    auto b = fl.allocate(42);\n    assert(b.length == 42);\n    assert((() pure nothrow @safe @nogc => fl.expand(b, 48))());\n    assert(b.length == 90);\n    assert((() nothrow @nogc => fl.reallocate(b, 100))());\n    assert(b.length == 100);\n    assert((() nothrow @nogc => fl.deallocateAll())());\n}\n\n/**\nFree list built on top of exactly one contiguous block of memory. The block is\nassumed to have been allocated with `ParentAllocator`, and is released in\n`ContiguousFreeList`'s destructor (unless `ParentAllocator` is $(D\nNullAllocator)).\n\n`ContiguousFreeList` has most advantages of `FreeList` but fewer\ndisadvantages. It has better cache locality because items are closer to one\nanother. It imposes less fragmentation on its parent allocator.\n\nThe disadvantages of `ContiguousFreeList` over `FreeList` are its pay\nupfront model (as opposed to `FreeList`'s pay-as-you-go approach), and a\nhard limit on the number of nodes in the list. Thus, a large number of long-\nlived objects may occupy the entire block, making it unavailable for serving\nallocations from the free list. However, an absolute cap on the free list size\nmay be beneficial.\n\nThe options $(D minSize == unbounded) and $(D maxSize == unbounded) are not\navailable for `ContiguousFreeList`.\n*/\nstruct ContiguousFreeList(ParentAllocator,\n     size_t minSize, size_t maxSize = minSize)\n{\n    import std.experimental.allocator.building_blocks.null_allocator\n        : NullAllocator;\n    import std.experimental.allocator.building_blocks.stats_collector\n        : StatsCollector, Options;\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n\n    alias Impl = FreeList!(NullAllocator, minSize, maxSize);\n    enum unchecked = minSize == 0 && maxSize == unbounded;\n    alias Node = Impl.Node;\n\n    alias SParent = StatsCollector!(ParentAllocator, Options.bytesUsed);\n\n    // state\n    /**\n    The parent allocator. Depending on whether `ParentAllocator` holds state\n    or not, this is a member variable or an alias for\n    `ParentAllocator.instance`.\n    */\n    SParent parent;\n    FreeList!(NullAllocator, minSize, maxSize) fl;\n    void[] support;\n    size_t allocated;\n\n    /// Alignment offered.\n    enum uint alignment = (void*).alignof;\n\n    private void initialize(ubyte[] buffer, size_t itemSize = fl.max)\n    {\n        assert(itemSize != unbounded && itemSize != chooseAtRuntime);\n        assert(buffer.ptr.alignedAt(alignment));\n        immutable available = buffer.length / itemSize;\n        if (available == 0) return;\n        support = buffer;\n        fl.root = cast(Node*) buffer.ptr;\n        auto past = cast(Node*) (buffer.ptr + available * itemSize);\n        for (auto n = fl.root; ; )\n        {\n            auto next = cast(Node*) (cast(ubyte*) n + itemSize);\n            if (next == past)\n            {\n                n.next = null;\n                break;\n            }\n            assert(next < past);\n            assert(n < next);\n            n.next = next;\n            n = next;\n        }\n    }\n\n    /**\n    Constructors setting up the memory structured as a free list.\n\n    Params:\n    buffer = Buffer to structure as a free list. If `ParentAllocator` is not\n    `NullAllocator`, the buffer is assumed to be allocated by `parent`\n    and will be freed in the destructor.\n    parent = Parent allocator. For construction from stateless allocators, use\n    their `instance` static member.\n    bytes = Bytes (not items) to be allocated for the free list. Memory will be\n    allocated during construction and deallocated in the destructor.\n    max = Maximum size eligible for freelisting. Construction with this\n    parameter is defined only if $(D maxSize == chooseAtRuntime) or $(D maxSize\n    == unbounded).\n    min = Minimum size eligible for freelisting. Construction with this\n    parameter is defined only if $(D minSize == chooseAtRuntime). If this\n    condition is met and no `min` parameter is present, `min` is\n    initialized with `max`.\n    */\n    static if (!stateSize!ParentAllocator)\n    this(ubyte[] buffer)\n    {\n        initialize(buffer);\n    }\n\n    /// ditto\n    static if (stateSize!ParentAllocator)\n    this(ParentAllocator parent, ubyte[] buffer)\n    {\n        initialize(buffer);\n        this.parent = SParent(parent);\n    }\n\n    /// ditto\n    static if (!stateSize!ParentAllocator)\n    this(size_t bytes)\n    {\n        initialize(cast(ubyte[])(ParentAllocator.instance.allocate(bytes)));\n    }\n\n    /// ditto\n    static if (stateSize!ParentAllocator)\n    this(ParentAllocator parent, size_t bytes)\n    {\n        initialize(cast(ubyte[])(parent.allocate(bytes)));\n        this.parent = SParent(parent);\n    }\n\n    /// ditto\n    static if (!stateSize!ParentAllocator\n        && (maxSize == chooseAtRuntime || maxSize == unbounded))\n    this(size_t bytes, size_t max)\n    {\n        static if (maxSize == chooseAtRuntime) fl.max = max;\n        static if (minSize == chooseAtRuntime) fl.min = max;\n        initialize(cast(ubyte[])(parent.allocate(bytes)), max);\n    }\n\n    /// ditto\n    static if (stateSize!ParentAllocator\n        && (maxSize == chooseAtRuntime || maxSize == unbounded))\n    this(ParentAllocator parent, size_t bytes, size_t max)\n    {\n        static if (maxSize == chooseAtRuntime) fl.max = max;\n        static if (minSize == chooseAtRuntime) fl.min = max;\n        initialize(cast(ubyte[])(parent.allocate(bytes)), max);\n        this.parent = SParent(parent);\n    }\n\n    /// ditto\n    static if (!stateSize!ParentAllocator\n        && (maxSize == chooseAtRuntime || maxSize == unbounded)\n        && minSize == chooseAtRuntime)\n    this(size_t bytes, size_t min, size_t max)\n    {\n        static if (maxSize == chooseAtRuntime) fl.max = max;\n        fl.min = min;\n        initialize(cast(ubyte[])(parent.allocate(bytes)), max);\n        static if (stateSize!ParentAllocator)\n            this.parent = SParent(parent);\n    }\n\n    /// ditto\n    static if (stateSize!ParentAllocator\n        && (maxSize == chooseAtRuntime || maxSize == unbounded)\n        && minSize == chooseAtRuntime)\n    this(ParentAllocator parent, size_t bytes, size_t min, size_t max)\n    {\n        static if (maxSize == chooseAtRuntime) fl.max = max;\n        fl.min = min;\n        initialize(cast(ubyte[])(parent.allocate(bytes)), max);\n        static if (stateSize!ParentAllocator)\n            this.parent = SParent(parent);\n    }\n\n    /**\n    If `n` is eligible for freelisting, returns `max`. Otherwise, returns\n    `parent.goodAllocSize(n)`.\n\n    Precondition:\n    If set at runtime, `min` and/or `max` must be initialized\n    appropriately.\n\n    Postcondition:\n    $(D result >= bytes)\n    */\n    size_t goodAllocSize(size_t n)\n    {\n        if (fl.freeListEligible(n)) return fl.max;\n        return parent.goodAllocSize(n);\n    }\n\n    /**\n    Allocate `n` bytes of memory. If `n` is eligible for freelist and the\n    freelist is not empty, pops the memory off the free list. In all other\n    cases, uses the parent allocator.\n    */\n    void[] allocate(size_t n)\n    {\n        auto result = fl.allocate(n);\n        if (result)\n        {\n            // Only case we care about: eligible sizes allocated from us\n            ++allocated;\n            return result;\n        }\n        // All others, allocate from parent\n        return parent.allocate(n);\n    }\n\n    /**\n    Defined if `ParentAllocator` defines it. Checks whether the block\n    belongs to this allocator.\n    */\n    static if (hasMember!(SParent, \"owns\") || unchecked)\n    // Ternary owns(const void[] b) const ?\n    Ternary owns(void[] b)\n    {\n        if ((() @trusted => support && b\n                            && (&support[0] <= &b[0])\n                            && (&b[0] < &support[0] + support.length)\n            )())\n            return Ternary.yes;\n        static if (unchecked)\n            return Ternary.no;\n        else\n            return parent.owns(b);\n    }\n\n    /**\n    Deallocates `b`. If it's of eligible size, it's put on the free list.\n    Otherwise, it's returned to `parent`.\n\n    Precondition: `b` has been allocated with this allocator, or is $(D\n    null).\n    */\n    bool deallocate(void[] b)\n    {\n        if (support.ptr <= b.ptr && b.ptr < support.ptr + support.length)\n        {\n            // we own this guy\n            assert(fl.freeListEligible(b.length));\n            assert(allocated);\n            --allocated;\n            // Put manually in the freelist\n            auto t = fl.root;\n            fl.root = cast(Node*) b.ptr;\n            fl.root.next = t;\n            return true;\n        }\n        return parent.deallocate(b);\n    }\n\n    /**\n    Deallocates everything from the parent.\n    */\n    static if (hasMember!(ParentAllocator, \"deallocateAll\")\n        && stateSize!ParentAllocator)\n    bool deallocateAll()\n    {\n        bool result = fl.deallocateAll && parent.deallocateAll;\n        allocated = 0;\n        return result;\n    }\n\n    /**\n    Returns `Ternary.yes` if no memory is currently allocated with this\n    allocator, `Ternary.no` otherwise. This method never returns\n    `Ternary.unknown`.\n    */\n    Ternary empty()\n    {\n        return Ternary(allocated == 0 && parent.bytesUsed == 0);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.experimental.allocator.building_blocks.allocator_list\n        : AllocatorList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n\n    import std.experimental.allocator.common : unbounded;\n\n    alias ScalableFreeList = AllocatorList!((n) =>\n        ContiguousFreeList!(GCAllocator, 0, unbounded)(4096)\n    );\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.null_allocator\n        : NullAllocator;\n    import std.typecons : Ternary;\n    alias A = ContiguousFreeList!(NullAllocator, 0, 64);\n    auto a = A(new ubyte[1024]);\n\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.yes);\n\n    assert((() pure nothrow @safe @nogc => a.goodAllocSize(15))() == 64);\n    assert((() pure nothrow @safe @nogc => a.goodAllocSize(65))()\n            == (() nothrow @safe @nogc => NullAllocator.instance.goodAllocSize(65))());\n\n    auto b = a.allocate(100);\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.yes);\n    assert(b.length == 0);\n    // Ensure deallocate inherits from parent\n    () nothrow @nogc { a.deallocate(b); }();\n    b = a.allocate(64);\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.no);\n    assert(b.length == 64);\n    assert((() nothrow @safe @nogc => a.owns(b))() == Ternary.yes);\n    assert((() nothrow @safe @nogc => a.owns(null))() == Ternary.no);\n    () nothrow @nogc { a.deallocate(b); }();\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.typecons : Ternary;\n    alias A = ContiguousFreeList!(Region!GCAllocator, 0, 64);\n    auto a = A(Region!GCAllocator(1024 * 4), 1024);\n\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.yes);\n\n    assert((() pure nothrow @safe @nogc => a.goodAllocSize(15))() == 64);\n    assert((() pure nothrow @safe @nogc => a.goodAllocSize(65))()\n            == (() pure nothrow @safe @nogc => a.parent.goodAllocSize(65))());\n\n    auto b = a.allocate(100);\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.no);\n    assert(a.allocated == 0);\n    assert(b.length == 100);\n    // Ensure deallocate inherits from parent\n    assert((() nothrow @nogc => a.deallocate(b))());\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.yes);\n    b = a.allocate(64);\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.no);\n    assert(b.length == 64);\n    assert(a.reallocate(b, 100));\n    assert(b.length == 100);\n    assert((() nothrow @safe @nogc => a.owns(b))() == Ternary.yes);\n    assert((() nothrow @safe @nogc => a.owns(null))() == Ternary.no);\n    // Test deallocate infers from parent\n    assert((() nothrow @nogc => a.deallocate(b))());\n    assert((() nothrow @nogc => a.deallocateAll())());\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    alias A = ContiguousFreeList!(GCAllocator, 64, 64);\n    auto a = A(1024);\n    const b = a.allocate(100);\n    assert(b.length == 100);\n}\n\n/**\nFreeList shared across threads. Allocation and deallocation are lock-free. The\nparameters have the same semantics as for `FreeList`.\n\n`expand` is defined to forward to `ParentAllocator.expand`\n(it must be also `shared`).\n*/\nstruct SharedFreeList(ParentAllocator,\n    size_t minSize, size_t maxSize = minSize, size_t approxMaxNodes = unbounded)\n{\n    import std.conv : text;\n    import std.exception : enforce;\n    import std.traits : hasMember;\n\n    static if (hasMember!(ParentAllocator, \"owns\"))\n    {\n        import std.typecons : Ternary;\n    }\n\n    static assert(approxMaxNodes, \"approxMaxNodes must not be null.\");\n    static assert(minSize != unbounded, \"Use minSize = 0 for no low bound.\");\n    static assert(maxSize >= (void*).sizeof,\n        \"Maximum size must accommodate a pointer.\");\n\n    import core.atomic : atomicOp, cas;\n    import core.internal.spinlock : SpinLock;\n\n    private enum unchecked = minSize == 0 && maxSize == unbounded;\n\n    static if (minSize != chooseAtRuntime)\n    {\n        alias min = minSize;\n    }\n    else\n    {\n        private shared size_t _min = chooseAtRuntime;\n        @property size_t min() const shared\n        {\n            assert(_min != chooseAtRuntime);\n            return _min;\n        }\n        @property void min(size_t x) shared\n        {\n            enforce(x <= max);\n            enforce(cas(&_min, chooseAtRuntime, x),\n                \"SharedFreeList.min must be initialized exactly once.\");\n        }\n        static if (maxSize == chooseAtRuntime)\n        {\n            // Both bounds can be set, provide one function for setting both in\n            // one shot.\n            void setBounds(size_t low, size_t high) shared\n            {\n                enforce(low <= high && high >= (void*).sizeof);\n                enforce(cas(&_min, chooseAtRuntime, low),\n                    \"SharedFreeList.min must be initialized exactly once.\");\n                enforce(cas(&_max, chooseAtRuntime, high),\n                    \"SharedFreeList.max must be initialized exactly once.\");\n            }\n        }\n    }\n\n    private bool tooSmall(size_t n) const shared\n    {\n        static if (minSize == 0) return false;\n        else static if (minSize == chooseAtRuntime) return n < _min;\n        else return n < minSize;\n    }\n\n    static if (maxSize != chooseAtRuntime)\n    {\n        alias max = maxSize;\n    }\n    else\n    {\n        private shared size_t _max = chooseAtRuntime;\n        @property size_t max() const shared { return _max; }\n        @property void max(size_t x) shared\n        {\n            enforce(x >= min && x >= (void*).sizeof);\n            enforce(cas(&_max, chooseAtRuntime, x),\n                \"SharedFreeList.max must be initialized exactly once.\");\n        }\n    }\n\n    private bool tooLarge(size_t n) const shared\n    {\n        static if (maxSize == unbounded) return false;\n        else static if (maxSize == chooseAtRuntime) return n > _max;\n        else return n > maxSize;\n    }\n\n    private bool freeListEligible(size_t n) const shared\n    {\n        static if (minSize == maxSize && minSize != chooseAtRuntime)\n            return n == maxSize;\n        else return !tooSmall(n) && !tooLarge(n);\n    }\n\n    static if (approxMaxNodes != chooseAtRuntime)\n    {\n        alias approxMaxLength = approxMaxNodes;\n    }\n    else\n    {\n        private shared size_t _approxMaxLength = chooseAtRuntime;\n        @property size_t approxMaxLength() const shared { return _approxMaxLength; }\n        @property void approxMaxLength(size_t x) shared { _approxMaxLength = enforce(x); }\n    }\n\n    static if (approxMaxNodes != unbounded)\n    {\n        private shared size_t nodes;\n        private void incNodes() shared\n        {\n            atomicOp!(\"+=\")(nodes, 1);\n        }\n        private void decNodes() shared\n        {\n            assert(nodes);\n            atomicOp!(\"-=\")(nodes, 1);\n        }\n        private void resetNodes() shared\n        {\n            nodes = 0;\n        }\n        private bool nodesFull() shared\n        {\n            return nodes >= approxMaxLength;\n        }\n    }\n    else\n    {\n        private static void incNodes() { }\n        private static void decNodes() { }\n        private static void resetNodes() { }\n        private enum bool nodesFull = false;\n    }\n\n    version (StdDdoc)\n    {\n        /**\n        Properties for getting (and possibly setting) the bounds. Setting bounds\n        is allowed only once , and before any allocation takes place. Otherwise,\n        the primitives have the same semantics as those of `FreeList`.\n        */\n        @property size_t min();\n        /// Ditto\n        @property void min(size_t newMinSize);\n        /// Ditto\n        @property size_t max();\n        /// Ditto\n        @property void max(size_t newMaxSize);\n        /// Ditto\n        void setBounds(size_t newMin, size_t newMax);\n\n        /**\n        Properties for getting (and possibly setting) the approximate maximum length of a shared freelist.\n        */\n        @property size_t approxMaxLength() const shared;\n        /// ditto\n        @property void approxMaxLength(size_t x) shared;\n    }\n\n    /**\n    The parent allocator. Depending on whether `ParentAllocator` holds state\n    or not, this is a member variable or an alias for\n    `ParentAllocator.instance`.\n    */\n    static if (stateSize!ParentAllocator) shared ParentAllocator parent;\n    else alias parent = ParentAllocator.instance;\n\n    mixin(forwardToMember(\"parent\", \"expand\"));\n\n    private SpinLock lock;\n\n    private struct Node { Node* next; }\n    static assert(ParentAllocator.alignment >= Node.alignof);\n    private Node* _root;\n\n    /// Standard primitives.\n    enum uint alignment = ParentAllocator.alignment;\n\n    /// Ditto\n    size_t goodAllocSize(size_t bytes) shared\n    {\n        if (freeListEligible(bytes)) return maxSize == unbounded ? bytes : max;\n        return parent.goodAllocSize(bytes);\n    }\n\n    /// Ditto\n    static if (hasMember!(ParentAllocator, \"owns\"))\n    Ternary owns(const void[] b) shared const\n    {\n        return parent.owns(b);\n    }\n\n    /// Ditto\n    static if (hasMember!(ParentAllocator, \"reallocate\"))\n    bool reallocate(ref void[] b, size_t s) shared\n    {\n        return parent.reallocate(b, s);\n    }\n\n    /// Ditto\n    void[] allocate(size_t bytes) shared\n    {\n        assert(bytes < size_t.max / 2);\n        if (!freeListEligible(bytes)) return parent.allocate(bytes);\n        if (maxSize != unbounded) bytes = max;\n\n        // Try to pop off the freelist\n        lock.lock();\n        if (!_root)\n        {\n            lock.unlock();\n            return allocateFresh(bytes);\n        }\n        else\n        {\n            auto oldRoot = _root;\n            _root = _root.next;\n            decNodes();\n            lock.unlock();\n            return (cast(ubyte*) oldRoot)[0 .. bytes];\n        }\n    }\n\n    private void[] allocateFresh(const size_t bytes) shared\n    {\n        assert(bytes == max || max == unbounded);\n        return parent.allocate(bytes);\n    }\n\n    /// Ditto\n    bool deallocate(void[] b) shared\n    {\n        if (!nodesFull && freeListEligible(b.length))\n        {\n            auto newRoot = cast(shared Node*) b.ptr;\n            lock.lock();\n            newRoot.next = _root;\n            _root = newRoot;\n            incNodes();\n            lock.unlock();\n            return true;\n        }\n        static if (hasMember!(ParentAllocator, \"deallocate\"))\n            return parent.deallocate(b);\n        else\n            return false;\n    }\n\n    /// Ditto\n    bool deallocateAll() shared\n    {\n        bool result = false;\n        lock.lock();\n        scope(exit) lock.unlock();\n        static if (hasMember!(ParentAllocator, \"deallocateAll\"))\n        {\n            result = parent.deallocateAll();\n        }\n        else static if (hasMember!(ParentAllocator, \"deallocate\"))\n        {\n            result = true;\n            for (auto n = _root; n;)\n            {\n                auto tmp = n.next;\n                if (!parent.deallocate((cast(ubyte*) n)[0 .. max]))\n                    result = false;\n                n = tmp;\n            }\n        }\n        _root = null;\n        resetNodes();\n        return result;\n    }\n\n    /**\n    Nonstandard function that minimizes the memory usage of the freelist by\n    freeing each element in turn. Defined only if `ParentAllocator` defines\n    `deallocate`.\n    */\n    static if (hasMember!(ParentAllocator, \"deallocate\") && !unchecked)\n    void minimize() shared\n    {\n        lock.lock();\n        scope(exit) lock.unlock();\n\n        for (auto n = _root; n;)\n        {\n            auto tmp = n.next;\n            parent.deallocate((cast(ubyte*) n)[0 .. max]);\n            n = tmp;\n        }\n\n        _root = null;\n        resetNodes();\n    }\n}\n\n///\n@safe unittest\n{\n    import std.experimental.allocator.common : chooseAtRuntime;\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    shared SharedFreeList!(Mallocator, chooseAtRuntime, chooseAtRuntime) a;\n    a.setBounds(64, 128);\n    assert(a.max == 128);\n    assert(a.min == 64);\n}\n\n///\n@safe unittest\n{\n    import std.experimental.allocator.common : chooseAtRuntime;\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    shared SharedFreeList!(Mallocator, 50, 50, chooseAtRuntime) a;\n    // Set the maxSize first so setting the minSize doesn't throw\n    a.approxMaxLength = 128;\n    assert(a.approxMaxLength  == 128);\n    a.approxMaxLength = 1024;\n    assert(a.approxMaxLength  == 1024);\n    a.approxMaxLength = 1;\n    assert(a.approxMaxLength  == 1);\n}\n\n@system unittest\n{\n    import core.thread : ThreadGroup;\n    import std.algorithm.comparison : equal;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.range : repeat;\n\n    static shared SharedFreeList!(Mallocator, 64, 128, 10) a;\n\n    assert((() nothrow @safe @nogc => a.goodAllocSize(1))() == platformAlignment);\n\n    auto b = a.allocate(96);\n    // Ensure deallocate inherits from parent\n    () nothrow @nogc { a.deallocate(b); }();\n\n    void fun()\n    {\n        auto b = cast(size_t[]) a.allocate(96);\n        b[] = cast(size_t) &b;\n\n        assert(b.equal(repeat(cast(size_t) &b, b.length)));\n        () nothrow @nogc { a.deallocate(b); }();\n    }\n\n    auto tg = new ThreadGroup;\n    foreach (i; 0 .. 20)\n    {\n        tg.create(&fun);\n    }\n\n    tg.joinAll();\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    static shared SharedFreeList!(Mallocator, 64, 128, 10) a;\n    auto b = a.allocate(100);\n    // Ensure deallocate inherits from parent\n    () nothrow @nogc { a.deallocate(b); }();\n    assert(a.nodes == 1);\n    b = [];\n    assert((() nothrow @nogc => a.deallocateAll())());\n    assert(a.nodes == 0);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    static shared SharedFreeList!(Mallocator, 64, 128, 10) a;\n    auto b = a.allocate(100);\n    auto c = a.allocate(100);\n    // Ensure deallocate inherits from parent\n    () nothrow @nogc { a.deallocate(c); }();\n    assert(a.nodes == 1);\n    c = [];\n    a.minimize();\n    assert(a.nodes == 0);\n    () nothrow @nogc { a.deallocate(b); }();\n    assert(a.nodes == 1);\n    b = [];\n    a.minimize();\n    assert(a.nodes == 0);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    static shared SharedFreeList!(Mallocator, 64, 128, 10) a;\n    auto b = a.allocate(100);\n    auto c = a.allocate(100);\n    assert(a.nodes == 0);\n    // Ensure deallocate inherits from parent\n    () nothrow @nogc { a.deallocate(b); }();\n    () nothrow @nogc { a.deallocate(c); }();\n    assert(a.nodes == 2);\n    b = [];\n    c = [];\n    a.minimize();\n    assert(a.nodes == 0);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    shared SharedFreeList!(Mallocator, chooseAtRuntime, chooseAtRuntime) a;\n    scope(exit) assert((() nothrow @nogc => a.deallocateAll())());\n    auto c = a.allocate(64);\n    assert((() nothrow @nogc => a.reallocate(c, 96))());\n    assert(c.length == 96);\n    // Ensure deallocate inherits from parent\n    () nothrow @nogc { a.deallocate(c); }();\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    shared SharedFreeList!(Mallocator, chooseAtRuntime, chooseAtRuntime, chooseAtRuntime) a;\n    scope(exit) assert((() nothrow @nogc => a.deallocateAll())());\n    a.allocate(64);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    shared SharedFreeList!(Mallocator, 30, 40) a;\n    scope(exit) assert((() nothrow @nogc => a.deallocateAll())());\n    a.allocate(64);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    shared SharedFreeList!(Mallocator, 30, 40, chooseAtRuntime) a;\n    scope(exit) assert((() nothrow @nogc => a.deallocateAll())());\n    a.allocate(64);\n}\n\n@system unittest\n{\n    // Pull request #5556\n    import std.experimental.allocator.mallocator : Mallocator;\n    shared SharedFreeList!(Mallocator, 0, chooseAtRuntime) a;\n    scope(exit) assert((() nothrow @nogc => a.deallocateAll())());\n    a.max = 64;\n    a.allocate(64);\n}\n\n@system unittest\n{\n    // Pull request #5556\n    import std.experimental.allocator.mallocator : Mallocator;\n    shared SharedFreeList!(Mallocator, chooseAtRuntime, 64) a;\n    scope(exit) assert((() nothrow @nogc => a.deallocateAll())());\n    a.min = 32;\n    a.allocate(64);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/free_tree.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/_free_tree.d)\n*/\nmodule std.experimental.allocator.building_blocks.free_tree;\n\nimport std.experimental.allocator.common;\n\n//debug = std_experimental_allocator_free_tree;\n\n/**\n\nThe Free Tree allocator, stackable on top of any other allocator, bears\nsimilarity with the free list allocator. Instead of a singly-linked list of\npreviously freed blocks, it maintains a binary search tree. This allows the\nFree Tree allocator to manage blocks of arbitrary lengths and search them\nefficiently.\n\nCommon uses of `FreeTree` include:\n\n$(UL\n$(LI Adding `deallocate` capability to an allocator that lacks it (such as simple regions).)\n$(LI Getting the benefits of multiple adaptable freelists that do not need to\nbe tuned for one specific size but insted automatically adapts itself to\nfrequently used sizes.)\n)\n\nThe free tree has special handling of duplicates (a singly-linked list per\nnode) in anticipation of large number of duplicates. Allocation time from the\nfree tree is expected to be $(BIGOH log n) where `n` is the number of\ndistinct sizes (not total nodes) kept in the free tree.\n\nAllocation requests first search the tree for a buffer of suitable size\ndeallocated in the past. If a match is found, the node is removed from the tree\nand the memory is returned. Otherwise, the allocation is directed to $(D\nParentAllocator). If at this point `ParentAllocator` also fails to allocate,\n`FreeTree` frees everything and then tries the parent allocator again.\n\nUpon deallocation, the deallocated block is inserted in the internally\nmaintained free tree (not returned to the parent). The free tree is not kept\nbalanced. Instead, it has a last-in-first-out flavor because newly inserted\nblocks are rotated to the root of the tree. That way allocations are cache\nfriendly and also frequently used sizes are more likely to be found quickly,\nwhereas seldom used sizes migrate to the leaves of the tree.\n\n`FreeTree` rounds up small allocations to at least $(D 4 * size_t.sizeof),\nwhich on 64-bit system is one cache line size. If very small objects need to\nbe efficiently allocated, the `FreeTree` should be fronted with an\nappropriate small object allocator.\n\nThe following methods are defined if `ParentAllocator` defines them, and forward to it: `allocateAll`, `expand`, `owns`, `reallocate`.\n*/\nstruct FreeTree(ParentAllocator)\n{\n    static assert(ParentAllocator.alignment % size_t.alignof == 0,\n        \"FreeTree must be on top of a word-aligned allocator\");\n\n    import std.algorithm.comparison : min, max;\n    import std.algorithm.mutation : swap;\n    import std.traits : hasMember;\n\n    // State\n    static if (stateSize!ParentAllocator) private ParentAllocator parent;\n    else private alias parent = ParentAllocator.instance;\n    private Node* root; // that's the entire added state\n\n    private struct Node\n    {\n        Node*[2] kid;\n        Node* sibling;\n        size_t size;\n        ref Node* left() { return kid[0]; }\n        ref Node* right() { return kid[1]; }\n    }\n\n    // Removes \"which\" from the tree, returns the memory it occupied\n    private void[] remove(ref Node* which)\n    {\n        assert(which);\n        assert(!which.sibling);\n        auto result = (cast(ubyte*) which)[0 .. which.size];\n        if (!which.right) which = which.left;\n        else if (!which.left) which = which.right;\n        else\n        {\n            // result has two kids\n            static bool toggler;\n            // Crude randomization: alternate left/right choices\n            toggler = !toggler;\n            auto newRoot = which.kid[toggler], orphan = which.kid[!toggler];\n            which = newRoot;\n            for (Node* n = void; (n = newRoot.kid[!toggler]) !is null; )\n            {\n                newRoot = n;\n            }\n            newRoot.kid[!toggler] = orphan;\n        }\n        return result;\n    }\n\n    private void[] findAndRemove(ref Node* n, size_t s)\n    {\n        if (!n) return null;\n        if (s == n.size)\n        {\n            if (auto sis = n.sibling)\n            {\n                // Nice, give away one from the freelist\n                auto result = (cast(ubyte*) sis)[0 .. sis.size];\n                n.sibling = sis.sibling;\n                return result;\n            }\n            return remove(n);\n        }\n        return findAndRemove(n.kid[s > n.size], s);\n    }\n\n    debug(std_experimental_allocator_free_tree)\n    private void dump()\n    {\n        import std.stdio : writef, writefln, writeln;\n        writeln(typeof(this).stringof, \"@\", &this, \" {\");\n        scope(exit) writeln(\"}\");\n\n        if (!root) return;\n\n        static void recurse(Node* n, uint indent = 4)\n        {\n            if (!n)\n            {\n                writefln(\"%*s(null)\", indent, \"\");\n                return;\n            }\n            for (auto sis = n; sis; sis = sis.sibling)\n            {\n                writef(\"%*s%x (%s bytes) \", indent, \"\",\n                    cast(void*) n, n.size);\n            }\n            writeln;\n            if (!n.left && !n.right) return;\n            recurse(n.left, indent + 4);\n            recurse(n.right, indent + 4);\n        }\n        recurse(root);\n    }\n\n    private string formatSizes()\n    {\n        string result = \"(\";\n        void recurse(Node* n)\n        {\n            if (!n)\n            {\n                result ~= \"_\";\n                return;\n            }\n            import std.conv : to;\n            result ~= to!string(n.size);\n            for (auto sis = n.sibling; sis; sis = sis.sibling)\n            {\n                result ~= \"+moar\";\n            }\n            if (n.left || n.right)\n            {\n                result ~= \" (\";\n                recurse(n.left);\n                result ~= ' ';\n                recurse(n.right);\n                result ~= \")\";\n            }\n        }\n        recurse(root);\n        return result ~= \")\";\n    }\n\n    private static void rotate(ref Node* parent, bool toRight)\n    {\n        assert(parent);\n        auto opposing = parent.kid[!toRight];\n        if (!opposing) return;\n        parent.kid[!toRight] = opposing.kid[toRight];\n        opposing.kid[toRight] = parent;\n        parent = opposing;\n    }\n\n    // Inserts which into the tree, making it the new root\n    private void insertAsRoot(Node* which)\n    {\n        assert(which);\n        debug(std_experimental_allocator_free_tree)\n        {\n            assertValid;\n            scope(exit) assertValid;\n        }\n\n        static void recurse(ref Node* where, Node* which)\n        {\n            if (!where)\n            {\n                where = which;\n                which.left = null;\n                which.right = null;\n                which.sibling = null;\n                return;\n            }\n            if (which.size == where.size)\n            {\n                // Special handling of duplicates\n                which.sibling = where.sibling;\n                where.sibling = which;\n                which.left = null;\n                which.right = null;\n                return;\n            }\n            bool goRight = which.size > where.size;\n            recurse(where.kid[goRight], which);\n            rotate(where, !goRight);\n        }\n        recurse(root, which);\n    }\n\n    private void assertValid()\n    {\n        debug(std_experimental_allocator_free_tree)\n        {\n            static bool isBST(Node* n, size_t lb = 0, size_t ub = size_t.max)\n            {\n                if (!n) return true;\n                for (auto sis = n.sibling; sis; sis = sis.sibling)\n                {\n                    assert(n.size == sis.size);\n                    assert(sis.left is null);\n                    assert(sis.right is null);\n                }\n                return lb < n.size && n.size <= ub\n                    && isBST(n.left, lb, min(ub, n.size))\n                    && isBST(n.right, max(lb, n.size), ub);\n            }\n            if (isBST(root)) return;\n            dump;\n            assert(0);\n        }\n    }\n\n    /**\n    The `FreeTree` is word aligned.\n    */\n    enum uint alignment = size_t.alignof;\n\n    /**\n    The `FreeTree` allocator is noncopyable.\n    */\n    this(this) @disable;\n\n    /**\n    The destructor of `FreeTree` releases all memory back to the parent\n    allocator.\n    */\n    static if (hasMember!(ParentAllocator, \"deallocate\"))\n    ~this()\n    {\n        clear;\n    }\n\n    /**\n    Returns $(D parent.goodAllocSize(max(Node.sizeof, s))).\n    */\n    static if (stateSize!ParentAllocator)\n        size_t goodAllocSize(size_t s)\n        {\n            return parent.goodAllocSize(max(Node.sizeof, s));\n        }\n    else\n        static size_t goodAllocSize(size_t s)\n        {\n            return parent.goodAllocSize(max(Node.sizeof, s));\n        }\n\n    /**\n\n    Allocates `n` bytes of memory. First consults the free tree, and returns\n    from it if a suitably sized block is found. Otherwise, the parent allocator\n    is tried. If allocation from the parent succeeds, the allocated block is\n    returned. Otherwise, the free tree tries an alternate strategy: If $(D\n    ParentAllocator) defines `deallocate`, `FreeTree` releases all of its\n    contents and tries again.\n\n    TODO: Splitting and coalescing should be implemented if `ParentAllocator` does not defined `deallocate`.\n\n    */\n    void[] allocate(size_t n)\n    {\n        assertValid;\n        if (n == 0) return null;\n\n        immutable s = goodAllocSize(n);\n\n        // Consult the free tree.\n        auto result = findAndRemove(root, s);\n        if (result.ptr) return result.ptr[0 .. n];\n\n        // No block found, try the parent allocator.\n        result = parent.allocate(s);\n        if (result.ptr) return result.ptr[0 .. n];\n\n        // Parent ran out of juice, desperation mode on\n        static if (hasMember!(ParentAllocator, \"deallocate\"))\n        {\n            clear;\n            // Try parent allocator again.\n            result = parent.allocate(s);\n            if (result.ptr) return result.ptr[0 .. n];\n            return null;\n        }\n        else\n        {\n            // TODO: get smart here\n            return null;\n        }\n    }\n\n    // Forwarding methods\n    mixin(forwardToMember(\"parent\",\n        \"allocateAll\", \"expand\", \"owns\", \"reallocate\"));\n\n    /** Places `b` into the free tree. */\n    bool deallocate(void[] b)\n    {\n        if (!b.ptr) return true;\n        auto which = cast(Node*) b.ptr;\n        which.size = goodAllocSize(b.length);\n        // deliberately don't initialize which.left and which.right\n        assert(which.size >= Node.sizeof);\n        insertAsRoot(which);\n        return true;\n    }\n\n    @system unittest // test a few simple configurations\n    {\n        import std.experimental.allocator.gc_allocator;\n        FreeTree!GCAllocator a;\n        auto b1 = a.allocate(10000);\n        auto b2 = a.allocate(20000);\n        auto b3 = a.allocate(30000);\n        assert(b1.ptr && b2.ptr && b3.ptr);\n        () nothrow @nogc { a.deallocate(b1); }();\n        () nothrow @nogc { a.deallocate(b3); }();\n        () nothrow @nogc { a.deallocate(b2); }();\n        assert(a.formatSizes == \"(20480 (12288 32768))\", a.formatSizes);\n\n        b1 = a.allocate(10000);\n        assert(a.formatSizes == \"(20480 (_ 32768))\", a.formatSizes);\n        b1 = a.allocate(30000);\n        assert(a.formatSizes == \"(20480)\", a.formatSizes);\n        b1 = a.allocate(20000);\n        assert(a.formatSizes == \"(_)\", a.formatSizes);\n    }\n\n    @system unittest // build a complex free tree\n    {\n        import std.experimental.allocator.gc_allocator, std.range;\n        FreeTree!GCAllocator a;\n        uint[] sizes = [3008,704,1856,576,1632,672,832,1856,1120,2656,1216,672,\n            448,992,2400,1376,2688,2656,736,1440];\n        void[][] allocs;\n        foreach (s; sizes)\n            allocs ~= a.allocate(s);\n        foreach_reverse (b; allocs)\n        {\n            assert(b.ptr);\n            () nothrow @nogc { a.deallocate(b); }();\n        }\n        a.assertValid;\n        allocs = null;\n        foreach (s; sizes)\n            allocs ~= a.allocate(s);\n        assert(a.root is null);\n        a.assertValid;\n    }\n\n    /** Defined if `ParentAllocator.deallocate` exists, and returns to it\n    all memory held in the free tree. */\n    static if (hasMember!(ParentAllocator, \"deallocate\"))\n    void clear()\n    {\n        void recurse(Node* n)\n        {\n            if (!n) return;\n            recurse(n.left);\n            recurse(n.right);\n            parent.deallocate((cast(ubyte*) n)[0 .. n.size]);\n        }\n        recurse(root);\n        root = null;\n    }\n\n    /**\n\n    Defined if `ParentAllocator.deallocateAll` exists, and forwards to it.\n    Also nullifies the free tree (it's assumed the parent frees all memory\n    stil managed by the free tree).\n\n    */\n    static if (hasMember!(ParentAllocator, \"deallocateAll\"))\n    bool deallocateAll()\n    {\n        // This is easy, just nuke the root and deallocate all from the\n        // parent\n        root = null;\n        return parent.deallocateAll;\n    }\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator;\n    testAllocator!(() => FreeTree!GCAllocator());\n}\n\n@system unittest // issue 16506\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    static void f(ParentAllocator)(size_t sz)\n    {\n        static FreeTree!ParentAllocator myAlloc;\n        byte[] _payload = cast(byte[]) myAlloc.allocate(sz);\n        assert(_payload, \"_payload is null\");\n        _payload[] = 0;\n        () nothrow @nogc { myAlloc.deallocate(_payload); }();\n    }\n\n    f!Mallocator(33);\n    f!Mallocator(43);\n    f!GCAllocator(1);\n}\n\n@system unittest // issue 16507\n{\n    static struct MyAllocator\n    {\n        byte dummy;\n        static bool alive = true;\n        void[] allocate(size_t s) { return new byte[](s); }\n        bool deallocate(void[] ) { if (alive) assert(false); return true; }\n        enum alignment = size_t.sizeof;\n    }\n\n    FreeTree!MyAllocator ft;\n    void[] x = ft.allocate(1);\n    () nothrow @nogc { ft.deallocate(x); }();\n    ft.allocate(1000);\n    MyAllocator.alive = false;\n}\n\n@system unittest // \"desperation mode\"\n{\n    uint myDeallocCounter = 0;\n\n    struct MyAllocator\n    {\n        byte[] allocation;\n        void[] allocate(size_t s)\n        {\n            if (allocation.ptr) return null;\n            allocation = new byte[](s);\n            return allocation;\n        }\n        bool deallocate(void[] )\n        {\n            ++myDeallocCounter;\n            allocation = null;\n            return true;\n        }\n        enum alignment = size_t.sizeof;\n    }\n\n    FreeTree!MyAllocator ft;\n    void[] x = ft.allocate(1);\n    () nothrow @nogc { ft.deallocate(x); }();\n    assert(myDeallocCounter == 0);\n    x = ft.allocate(1000); // Triggers \"desperation mode\".\n    assert(myDeallocCounter == 1);\n    assert(x.ptr);\n    void[] y = ft.allocate(1000); /* Triggers \"desperation mode\" but there's\n        nothing to deallocate so MyAllocator can't deliver. */\n    assert(myDeallocCounter == 1);\n    assert(y.ptr is null);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator;\n    FreeTree!GCAllocator a;\n\n    assert((() nothrow @safe @nogc => a.goodAllocSize(1))() == typeof(*a.root).sizeof);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n\n    auto a = FreeTree!(Region!())(Region!()(new ubyte[1024 * 64]));\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    assert((() pure nothrow @safe @nogc => a.expand(b, 22))());\n    assert(b.length == 64);\n    assert((() nothrow @nogc => a.reallocate(b, 100))());\n    assert(b.length == 100);\n    assert((() nothrow @nogc => a.deallocateAll())());\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/kernighan_ritchie.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/kernighan_ritchie.d)\n*/\nmodule std.experimental.allocator.building_blocks.kernighan_ritchie;\nimport std.experimental.allocator.building_blocks.null_allocator;\n\n//debug = KRRegion;\ndebug(KRRegion) import std.stdio;\n\n// KRRegion\n/**\n`KRRegion` draws inspiration from the $(MREF_ALTTEXT region allocation\nstrategy, std,experimental,allocator,building_blocks,region) and also the\n$(HTTP stackoverflow.com/questions/13159564/explain-this-implementation-of-malloc-from-the-kr-book,\nfamed allocator) described by Brian Kernighan and Dennis Ritchie in section 8.7\nof the book $(HTTP amazon.com/exec/obidos/ASIN/0131103628/classicempire, \"The C\nProgramming Language\"), Second Edition, Prentice Hall, 1988.\n\n$(H4 `KRRegion` = `Region` + Kernighan-Ritchie Allocator)\n\nInitially, `KRRegion` starts in \"region\" mode: allocations are served from\nthe memory chunk in a region fashion. Thus, as long as there is enough memory\nleft, `KRRegion.allocate` has the performance profile of a region allocator.\nDeallocation inserts (in $(BIGOH 1) time) the deallocated blocks in an\nunstructured freelist, which is not read in region mode.\n\nOnce the region cannot serve an `allocate` request, `KRRegion` switches\nto \"free list\" mode. It sorts the list of previously deallocated blocks by\naddress and serves allocation requests off that free list. The allocation and\ndeallocation follow the pattern described by Kernighan and Ritchie.\n\nThe recommended use of `KRRegion` is as a $(I region with deallocation). If the\n`KRRegion` is dimensioned appropriately, it could often not enter free list\nmode during its lifetime. Thus it is as fast as a simple region, whilst\noffering deallocation at a small cost. When the region memory is  exhausted,\nthe previously deallocated memory is still usable, at a performance  cost. If\nthe region is not excessively large and fragmented, the linear  allocation and\ndeallocation cost may still be compensated for by the good locality\ncharacteristics.\n\nIf the chunk of memory managed is large, it may be desirable to switch\nmanagement to free list from the beginning. That way, memory may be used in a\nmore compact manner than region mode. To force free list mode, call $(D\nswitchToFreeList) shortly after construction or when deemed appropriate.\n\nThe smallest size that can be allocated is two words (16 bytes on 64-bit\nsystems, 8 bytes on 32-bit systems). This is because the free list management\nneeds two words (one for the length, the other for the next pointer in the\nsingly-linked list).\n\nThe `ParentAllocator` type parameter is the type of the allocator used to\nallocate the memory chunk underlying the `KRRegion` object. Choosing the\ndefault (`NullAllocator`) means the user is responsible for passing a buffer\nat construction (and for deallocating it if necessary). Otherwise, `KRRegion`\nautomatically deallocates the buffer during destruction. For that reason, if\n`ParentAllocator` is not `NullAllocator`, then `KRRegion` is not\ncopyable.\n\n$(H4 Implementation Details)\n\nIn free list mode, `KRRegion` embeds a free blocks list onto the chunk of\nmemory. The free list is circular, coalesced, and sorted by address at all\ntimes. Allocations and deallocations take time proportional to the number of\npreviously deallocated blocks. (In practice the cost may be lower, e.g. if\nmemory is deallocated in reverse order of allocation, all operations take\nconstant time.) Memory utilization is good (small control structure and no\nper-allocation overhead). The disadvantages of freelist mode include proneness\nto fragmentation, a minimum allocation size of two words, and linear worst-case\nallocation and deallocation times.\n\nSimilarities of `KRRegion` (in free list mode) with the\nKernighan-Ritchie allocator:\n\n$(UL\n$(LI Free blocks have variable size and are linked in a singly-linked list.)\n$(LI The freelist is maintained in increasing address order, which makes\ncoalescing easy.)\n$(LI The strategy for finding the next available block is first fit.)\n$(LI The free list is circular, with the last node pointing back to the first.)\n$(LI Coalescing is carried during deallocation.)\n)\n\nDifferences from the Kernighan-Ritchie allocator:\n\n$(UL\n$(LI Once the chunk is exhausted, the Kernighan-Ritchie allocator allocates\nanother chunk using operating system primitives. For better composability, $(D\nKRRegion) just gets full (returns `null` on new allocation requests). The\ndecision to allocate more blocks is deferred to a higher-level entity. For an\nexample, see the example below using `AllocatorList` in conjunction with $(D\nKRRegion).)\n$(LI Allocated blocks do not hold a size prefix. This is because in D the size\ninformation is available in client code at deallocation time.)\n)\n\n*/\nstruct KRRegion(ParentAllocator = NullAllocator)\n{\n    import std.experimental.allocator.common : stateSize, alignedAt;\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n\n    private static struct Node\n    {\n        import std.typecons : tuple, Tuple;\n\n        Node* next;\n        size_t size;\n\n        this(this) @disable;\n\n        void[] payload() inout\n        {\n            return (cast(ubyte*) &this)[0 .. size];\n        }\n\n        bool adjacent(in Node* right) const\n        {\n            assert(right);\n            auto p = payload;\n            return p.ptr < right && right < p.ptr + p.length + Node.sizeof;\n        }\n\n        bool coalesce(void* memoryEnd = null)\n        {\n            // Coalesce the last node before the memory end with any possible gap\n            if (memoryEnd\n                && memoryEnd < payload.ptr + payload.length + Node.sizeof)\n            {\n                size += memoryEnd - (payload.ptr + payload.length);\n                return true;\n            }\n\n            if (!adjacent(next)) return false;\n            size = (cast(ubyte*) next + next.size) - cast(ubyte*) &this;\n            next = next.next;\n            return true;\n        }\n\n        Tuple!(void[], Node*) allocateHere(size_t bytes)\n        {\n            assert(bytes >= Node.sizeof);\n            assert(bytes % Node.alignof == 0);\n            assert(next);\n            assert(!adjacent(next));\n            if (size < bytes) return typeof(return)();\n            assert(size >= bytes);\n            immutable leftover = size - bytes;\n\n            if (leftover >= Node.sizeof)\n            {\n                // There's room for another node\n                auto newNode = cast(Node*) ((cast(ubyte*) &this) + bytes);\n                newNode.size = leftover;\n                newNode.next = next == &this ? newNode : next;\n                assert(next);\n                return tuple(payload, newNode);\n            }\n\n            // No slack space, just return next node\n            return tuple(payload, next == &this ? null : next);\n        }\n    }\n\n    // state\n    /**\n    If `ParentAllocator` holds state, `parent` is a public member of type\n    `KRRegion`. Otherwise, `parent` is an `alias` for\n    `ParentAllocator.instance`.\n    */\n    static if (stateSize!ParentAllocator) ParentAllocator parent;\n    else alias parent = ParentAllocator.instance;\n    private void[] payload;\n    private Node* root;\n    private bool regionMode() const { return bytesUsedRegionMode != size_t.max; }\n    private void cancelRegionMode() { bytesUsedRegionMode = size_t.max; }\n    private size_t bytesUsedRegionMode = 0;\n\n    auto byNodePtr()\n    {\n        static struct Range\n        {\n            Node* start, current;\n            @property bool empty() { return !current; }\n            @property Node* front() { return current; }\n            void popFront()\n            {\n                assert(current && current.next);\n                current = current.next;\n                if (current == start) current = null;\n            }\n            @property Range save() { return this; }\n        }\n        import std.range : isForwardRange;\n        static assert(isForwardRange!Range);\n        return Range(root, root);\n    }\n\n    string toString()\n    {\n        import std.format : format;\n        string s = \"KRRegion@\";\n        s ~= format(\"%s-%s(0x%s[%s] %s\", &this, &this + 1,\n            payload.ptr, payload.length,\n            regionMode ? \"(region)\" : \"(freelist)\");\n\n        Node* lastNode = null;\n        if (!regionMode)\n        {\n            foreach (node; byNodePtr)\n            {\n                s ~= format(\", %sfree(0x%s[%s])\",\n                    lastNode && lastNode.adjacent(node) ? \"+\" : \"\",\n                    cast(void*) node, node.size);\n                lastNode = node;\n            }\n        }\n        else\n        {\n            for (auto node = root; node; node = node.next)\n            {\n                s ~= format(\", %sfree(0x%s[%s])\",\n                    lastNode && lastNode.adjacent(node) ? \"+\" : \"\",\n                    cast(void*) node, node.size);\n                lastNode = node;\n            }\n        }\n\n        s ~= ')';\n        return s;\n    }\n\n    private void assertValid(string s)\n    {\n        assert(!regionMode);\n        if (!payload.ptr)\n        {\n            assert(!root, s);\n            return;\n        }\n        if (!root)\n        {\n            return;\n        }\n        assert(root >= payload.ptr, s);\n        assert(root < payload.ptr + payload.length, s);\n\n        // Check that the list terminates\n        size_t n;\n        foreach (node; byNodePtr)\n        {\n            assert(node.next);\n            assert(!node.adjacent(node.next));\n            assert(n++ < payload.length / Node.sizeof, s);\n        }\n    }\n\n    private Node* sortFreelist(Node* root)\n    {\n        // Find a monotonic run\n        auto last = root;\n        for (;;)\n        {\n            if (!last.next) return root;\n            if (last > last.next) break;\n            assert(last < last.next);\n            last = last.next;\n        }\n        auto tail = last.next;\n        last.next = null;\n        tail = sortFreelist(tail);\n        return merge(root, tail);\n    }\n\n    private Node* merge(Node* left, Node* right)\n    {\n        assert(left != right);\n        if (!left) return right;\n        if (!right) return left;\n        if (left < right)\n        {\n            auto result = left;\n            result.next = merge(left.next, right);\n            return result;\n        }\n        auto result = right;\n        result.next = merge(left, right.next);\n        return result;\n    }\n\n    private void coalesceAndMakeCircular()\n    {\n        for (auto n = root;;)\n        {\n            assert(!n.next || n < n.next);\n            if (!n.next)\n            {\n                // Convert to circular\n                n.next = root;\n                break;\n            }\n            if (n.coalesce) continue; // possibly another coalesce\n            n = n.next;\n        }\n    }\n\n    /**\n    Create a `KRRegion`. If `ParentAllocator` is not `NullAllocator`,\n    `KRRegion`'s destructor will call `parent.deallocate`.\n\n    Params:\n    b = Block of memory to serve as support for the allocator. Memory must be\n    larger than two words and word-aligned.\n    n = Capacity desired. This constructor is defined only if $(D\n    ParentAllocator) is not `NullAllocator`.\n    */\n    this(ubyte[] b)\n    {\n        if (b.length < Node.sizeof)\n        {\n            // Init as empty\n            assert(root is null);\n            assert(payload is null);\n            return;\n        }\n        assert(b.length >= Node.sizeof);\n        assert(b.ptr.alignedAt(Node.alignof));\n        assert(b.length >= 2 * Node.sizeof);\n        payload = b;\n        root = cast(Node*) b.ptr;\n        // Initialize the free list with all list\n        assert(regionMode);\n        root.next = null;\n        root.size = b.length;\n        debug(KRRegion) writefln(\"KRRegion@%s: init with %s[%s]\", &this,\n            b.ptr, b.length);\n    }\n\n    /// Ditto\n    static if (!is(ParentAllocator == NullAllocator) && !stateSize!ParentAllocator)\n    this(size_t n)\n    {\n        assert(n > Node.sizeof);\n        this(cast(ubyte[])(parent.allocate(n)));\n    }\n\n    /// Ditto\n    static if (!is(ParentAllocator == NullAllocator) && stateSize!ParentAllocator)\n    this(ParentAllocator parent, size_t n)\n    {\n        assert(n > Node.sizeof);\n        this.parent = parent;\n        this(cast(ubyte[])(parent.allocate(n)));\n    }\n\n    /// Ditto\n    static if (!is(ParentAllocator == NullAllocator)\n        && hasMember!(ParentAllocator, \"deallocate\"))\n    ~this()\n    {\n        parent.deallocate(payload);\n    }\n\n    /**\n    Forces free list mode. If already in free list mode, does nothing.\n    Otherwise, sorts the free list accumulated so far and switches strategy for\n    future allocations to KR style.\n    */\n    void switchToFreeList()\n    {\n        if (!regionMode) return;\n        cancelRegionMode;\n        if (!root) return;\n        root = sortFreelist(root);\n        coalesceAndMakeCircular;\n    }\n\n    /*\n    Noncopyable\n    */\n    @disable this(this);\n\n    /**\n    Word-level alignment.\n    */\n    enum alignment = Node.alignof;\n\n    /**\n    Allocates `n` bytes. Allocation searches the list of available blocks\n    until a free block with `n` or more bytes is found (first fit strategy).\n    The block is split (if larger) and returned.\n\n    Params: n = number of bytes to _allocate\n\n    Returns: A word-aligned buffer of `n` bytes, or `null`.\n    */\n    void[] allocate(size_t n)\n    {\n        if (!n || !root) return null;\n        const actualBytes = goodAllocSize(n);\n\n        // Try the region first\n        if (regionMode)\n        {\n            // Only look at the head of the freelist\n            if (root.size >= actualBytes)\n            {\n                // Enough room for allocation\n                bytesUsedRegionMode += actualBytes;\n                void* result = root;\n                immutable balance = root.size - actualBytes;\n                if (balance >= Node.sizeof)\n                {\n                    auto newRoot = cast(Node*) (result + actualBytes);\n                    newRoot.next = root.next;\n                    newRoot.size = balance;\n                    root = newRoot;\n                }\n                else\n                {\n                    root = null;\n                    switchToFreeList;\n                }\n                return result[0 .. n];\n            }\n\n            // Not enough memory, switch to freelist mode and fall through\n            switchToFreeList;\n        }\n\n        // Try to allocate from next after the iterating node\n        for (auto pnode = root;;)\n        {\n            assert(!pnode.adjacent(pnode.next));\n            auto k = pnode.next.allocateHere(actualBytes);\n            if (k[0] !is null)\n            {\n                // awes\n                assert(k[0].length >= n);\n                if (root == pnode.next) root = k[1];\n                pnode.next = k[1];\n                return k[0][0 .. n];\n            }\n\n            pnode = pnode.next;\n            if (pnode == root) break;\n        }\n        return null;\n    }\n\n    /**\n    Deallocates `b`, which is assumed to have been previously allocated with\n    this allocator. Deallocation performs a linear search in the free list to\n    preserve its sorting order. It follows that blocks with higher addresses in\n    allocators with many free blocks are slower to deallocate.\n\n    Params: b = block to be deallocated\n    */\n    nothrow @nogc\n    bool deallocate(void[] b)\n    {\n        debug(KRRegion) writefln(\"KRRegion@%s: deallocate(%s[%s])\", &this,\n            b.ptr, b.length);\n        if (!b.ptr) return true;\n        assert(owns(b) == Ternary.yes);\n        assert(b.ptr.alignedAt(Node.alignof));\n\n        // Insert back in the freelist, keeping it sorted by address. Do not\n        // coalesce at this time. Instead, do it lazily during allocation.\n        auto n = cast(Node*) b.ptr;\n        n.size = goodAllocSize(b.length);\n        auto memoryEnd = payload.ptr + payload.length;\n\n        if (regionMode)\n        {\n            assert(root);\n            // Insert right after root\n            bytesUsedRegionMode -= n.size;\n            n.next = root.next;\n            root.next = n;\n            return true;\n        }\n\n        if (!root)\n        {\n            // What a sight for sore eyes\n            root = n;\n            root.next = root;\n\n            // If the first block freed is the last one allocated,\n            // maybe there's a gap after it.\n            root.coalesce(memoryEnd);\n            return true;\n        }\n\n        version (assert) foreach (test; byNodePtr)\n        {\n            assert(test != n);\n        }\n        // Linear search\n        auto pnode = root;\n        do\n        {\n            assert(pnode && pnode.next);\n            assert(pnode != n);\n            assert(pnode.next != n);\n\n            if (pnode < pnode.next)\n            {\n                if (pnode > n || n > pnode.next) continue;\n                // Insert in between pnode and pnode.next\n                n.next = pnode.next;\n                pnode.next = n;\n                n.coalesce;\n                pnode.coalesce;\n                root = pnode;\n                return true;\n            }\n            else if (pnode < n)\n            {\n                // Insert at the end of the list\n                // Add any possible gap at the end of n to the length of n\n                n.next = pnode.next;\n                pnode.next = n;\n                n.coalesce(memoryEnd);\n                pnode.coalesce;\n                root = pnode;\n                return true;\n            }\n            else if (n < pnode.next)\n            {\n                // Insert at the front of the list\n                n.next = pnode.next;\n                pnode.next = n;\n                n.coalesce;\n                root = n;\n                return true;\n            }\n        }\n        while ((pnode = pnode.next) != root);\n        assert(0, \"Wrong parameter passed to deallocate\");\n    }\n\n    /**\n    Allocates all memory available to this allocator. If the allocator is empty,\n    returns the entire available block of memory. Otherwise, it still performs\n    a best-effort allocation: if there is no fragmentation (e.g. `allocate`\n    has been used but not `deallocate`), allocates and returns the only\n    available block of memory.\n\n    The operation takes time proportional to the number of adjacent free blocks\n    at the front of the free list. These blocks get coalesced, whether\n    `allocateAll` succeeds or fails due to fragmentation.\n    */\n    void[] allocateAll()\n    {\n        if (regionMode) switchToFreeList;\n        if (root && root.next == root)\n            return allocate(root.size);\n        return null;\n    }\n\n    ///\n    @system unittest\n    {\n        import std.experimental.allocator.gc_allocator : GCAllocator;\n        auto alloc = KRRegion!GCAllocator(1024 * 64);\n        const b1 = alloc.allocate(2048);\n        assert(b1.length == 2048);\n        const b2 = alloc.allocateAll;\n        assert(b2.length == 1024 * 62);\n    }\n\n    /**\n    Deallocates all memory currently allocated, making the allocator ready for\n    other allocations. This is a $(BIGOH 1) operation.\n    */\n    pure nothrow @nogc\n    bool deallocateAll()\n    {\n        debug(KRRegion) assertValid(\"deallocateAll\");\n        debug(KRRegion) scope(exit) assertValid(\"deallocateAll\");\n        root = cast(Node*) payload.ptr;\n\n        // Reset to regionMode\n        bytesUsedRegionMode = 0;\n        if (root)\n        {\n            root.next = null;\n            root.size = payload.length;\n        }\n        return true;\n    }\n\n    /**\n    Checks whether the allocator is responsible for the allocation of `b`.\n    It does a simple $(BIGOH 1) range check. `b` should be a buffer either\n    allocated with `this` or obtained through other means.\n    */\n    pure nothrow @trusted @nogc\n    Ternary owns(void[] b)\n    {\n        debug(KRRegion) assertValid(\"owns\");\n        debug(KRRegion) scope(exit) assertValid(\"owns\");\n        return Ternary(b && payload && (&b[0] >= &payload[0])\n                       && (&b[0] < &payload[0] + payload.length));\n    }\n\n    /**\n    Adjusts `n` to a size suitable for allocation (two words or larger,\n    word-aligned).\n    */\n    pure nothrow @safe @nogc\n    static size_t goodAllocSize(size_t n)\n    {\n        import std.experimental.allocator.common : roundUpToMultipleOf;\n        return n <= Node.sizeof\n            ? Node.sizeof : n.roundUpToMultipleOf(alignment);\n    }\n\n    /**\n    Returns: `Ternary.yes` if the allocator is empty, `Ternary.no` otherwise.\n    Never returns `Ternary.unknown`.\n    */\n    pure nothrow @safe @nogc\n    Ternary empty()\n    {\n        if (regionMode)\n            return Ternary(bytesUsedRegionMode == 0);\n\n        return Ternary(root && root.size == payload.length);\n    }\n}\n\n/**\n`KRRegion` is preferable to `Region` as a front for a general-purpose\nallocator if `deallocate` is needed, yet the actual deallocation traffic is\nrelatively low. The example below shows a `KRRegion` using stack storage\nfronting the GC allocator.\n*/\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.fallback_allocator\n        : fallbackAllocator;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.typecons : Ternary;\n    // KRRegion fronting a general-purpose allocator\n    ubyte[1024 * 128] buf;\n    auto alloc = fallbackAllocator(KRRegion!()(buf), GCAllocator.instance);\n    auto b = alloc.allocate(100);\n    assert(b.length == 100);\n    assert((() pure nothrow @safe @nogc => alloc.primary.owns(b))() == Ternary.yes);\n}\n\n/**\nThe code below defines a scalable allocator consisting of 1 MB (or larger)\nblocks fetched from the garbage-collected heap. Each block is organized as a\nKR-style heap. More blocks are allocated and freed on a need basis.\n\nThis is the closest example to the allocator introduced in the K$(AMP)R book.\nIt should perform slightly better because instead of searching through one\nlarge free list, it searches through several shorter lists in LRU order. Also,\nit actually returns memory to the operating system when possible.\n*/\n@system unittest\n{\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.allocator_list\n        : AllocatorList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mmap_allocator : MmapAllocator;\n    AllocatorList!(n => KRRegion!MmapAllocator(max(n * 16, 1024 * 1024))) alloc;\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.allocator_list\n        : AllocatorList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Ternary;\n    /*\n    Create a scalable allocator consisting of 1 MB (or larger) blocks fetched\n    from the garbage-collected heap. Each block is organized as a KR-style\n    heap. More blocks are allocated and freed on a need basis.\n    */\n    AllocatorList!(n => KRRegion!Mallocator(max(n * 16, 1024 * 1024)),\n        NullAllocator) alloc;\n    void[][50] array;\n    foreach (i; 0 .. array.length)\n    {\n        auto length = i * 10_000 + 1;\n        array[i] = alloc.allocate(length);\n        assert(array[i].ptr);\n        assert(array[i].length == length);\n    }\n    import std.random : randomShuffle;\n    randomShuffle(array[]);\n    foreach (i; 0 .. array.length)\n    {\n        assert(array[i].ptr);\n        assert((() pure nothrow @safe @nogc => alloc.owns(array[i]))() == Ternary.yes);\n        () nothrow @nogc { alloc.deallocate(array[i]); }();\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.allocator_list\n        : AllocatorList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mmap_allocator : MmapAllocator;\n    import std.typecons : Ternary;\n    /*\n    Create a scalable allocator consisting of 1 MB (or larger) blocks fetched\n    from the garbage-collected heap. Each block is organized as a KR-style\n    heap. More blocks are allocated and freed on a need basis.\n    */\n    AllocatorList!((n) {\n        auto result = KRRegion!MmapAllocator(max(n * 2, 1024 * 1024));\n        return result;\n    }) alloc;\n    void[][99] array;\n    foreach (i; 0 .. array.length)\n    {\n        auto length = i * 10_000 + 1;\n        array[i] = alloc.allocate(length);\n        assert(array[i].ptr);\n        foreach (j; 0 .. i)\n        {\n            assert(array[i].ptr != array[j].ptr);\n        }\n        assert(array[i].length == length);\n    }\n    import std.random : randomShuffle;\n    randomShuffle(array[]);\n    foreach (i; 0 .. array.length)\n    {\n        assert((() pure nothrow @safe @nogc => alloc.owns(array[i]))() == Ternary.yes);\n        () nothrow @nogc { alloc.deallocate(array[i]); }();\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.allocator_list\n        : AllocatorList;\n    import std.experimental.allocator.common : testAllocator;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    testAllocator!(() => AllocatorList!(\n        n => KRRegion!GCAllocator(max(n * 16, 1024 * 1024)))());\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n\n    auto alloc = KRRegion!GCAllocator(1024 * 1024);\n\n    void[][] array;\n    foreach (i; 1 .. 4)\n    {\n        array ~= alloc.allocate(i);\n        assert(array[$ - 1].length == i);\n    }\n    () nothrow @nogc { alloc.deallocate(array[1]); }();\n    () nothrow @nogc { alloc.deallocate(array[0]); }();\n    () nothrow @nogc { alloc.deallocate(array[2]); }();\n    assert(alloc.allocateAll().length == 1024 * 1024);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.typecons : Ternary;\n    auto alloc = KRRegion!()(\n                    cast(ubyte[])(GCAllocator.instance.allocate(1024 * 1024)));\n    const store = alloc.allocate(KRRegion!().sizeof);\n    auto p = cast(KRRegion!()* ) store.ptr;\n    import core.stdc.string : memcpy;\n    import std.algorithm.mutation : move;\n    import std.conv : text, emplace;\n\n    memcpy(p, &alloc, alloc.sizeof);\n    emplace(&alloc);\n\n    void[][100] array;\n    foreach (i; 0 .. array.length)\n    {\n        auto length = 100 * i + 1;\n        array[i] = p.allocate(length);\n        assert(array[i].length == length, text(array[i].length));\n        assert((() pure nothrow @safe @nogc => p.owns(array[i]))() == Ternary.yes);\n    }\n    import std.random : randomShuffle;\n    randomShuffle(array[]);\n    foreach (i; 0 .. array.length)\n    {\n        assert((() pure nothrow @safe @nogc => p.owns(array[i]))() == Ternary.yes);\n        () nothrow @nogc { p.deallocate(array[i]); }();\n    }\n    auto b = p.allocateAll();\n    assert(b.length == 1024 * 1024 - KRRegion!().sizeof, text(b.length));\n}\n\n@system unittest\n{\n    import std.typecons : Ternary;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    auto alloc = KRRegion!()(\n                    cast(ubyte[])(GCAllocator.instance.allocate(1024 * 1024)));\n    auto p = alloc.allocateAll();\n    assert(p.length == 1024 * 1024);\n    assert((() nothrow @nogc => alloc.deallocateAll())());\n    assert(alloc.empty() == Ternary.yes);\n    p = alloc.allocateAll();\n    assert(p.length == 1024 * 1024);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks;\n    import std.random;\n    import std.typecons : Ternary;\n\n    // Both sequences must work on either system\n\n    // A sequence of allocs which generates the error described in issue 16564\n    // that is a gap at the end of buf from the perspective of the allocator\n\n    // for 64 bit systems (leftover balance = 8 bytes < 16)\n    int[] sizes64 = [18904, 2008, 74904, 224, 111904, 1904, 52288, 8];\n\n    // for 32 bit systems (leftover balance < 8)\n    int[] sizes32 = [81412, 107068, 49892, 23768];\n\n\n    void test(int[] sizes)\n    {\n        align(size_t.sizeof) ubyte[256 * 1024] buf;\n        auto a = KRRegion!()(buf);\n\n        void[][] bufs;\n\n        foreach (size; sizes)\n        {\n            bufs ~= a.allocate(size);\n        }\n\n        foreach (b; bufs.randomCover)\n        {\n            () nothrow @nogc { a.deallocate(b); }();\n        }\n\n        assert((() pure nothrow @safe @nogc => a.empty)() == Ternary.yes);\n    }\n\n    test(sizes64);\n    test(sizes32);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks;\n    import std.random;\n    import std.typecons : Ternary;\n\n    // For 64 bits, we allocate in multiples of 8, but the minimum alloc size is 16.\n    // This can create gaps.\n    // This test is an example of such a case. The gap is formed between the block\n    // allocated for the second value in sizes and the third. There is also a gap\n    // at the very end. (total lost 2 * word)\n\n    int[] sizes64 = [2008, 18904, 74904, 224, 111904, 1904, 52288, 8];\n    int[] sizes32 = [81412, 107068, 49892, 23768];\n\n    int word64 = 8;\n    int word32 = 4;\n\n    void test(int[] sizes, int word)\n    {\n        align(size_t.sizeof) ubyte[256 * 1024] buf;\n        auto a = KRRegion!()(buf);\n\n        void[][] bufs;\n\n        foreach (size; sizes)\n        {\n            bufs ~= a.allocate(size);\n        }\n\n        () nothrow @nogc { a.deallocate(bufs[1]); }();\n        bufs ~= a.allocate(sizes[1] - word);\n\n        () nothrow @nogc { a.deallocate(bufs[0]); }();\n        foreach (i; 2 .. bufs.length)\n        {\n            () nothrow @nogc { a.deallocate(bufs[i]); }();\n        }\n\n        assert((() pure nothrow @safe @nogc => a.empty)() == Ternary.yes);\n    }\n\n    test(sizes64, word64);\n    test(sizes32, word32);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n\n    auto a = KRRegion!GCAllocator(1024 * 1024);\n    assert((() pure nothrow @safe @nogc => a.goodAllocSize(1))() == typeof(*a.root).sizeof);\n}\n\n@system unittest\n{   import std.typecons : Ternary;\n\n    ubyte[1024] b;\n    auto alloc = KRRegion!()(b);\n\n    auto k = alloc.allocate(128);\n    assert(k.length == 128);\n    assert(alloc.empty == Ternary.no);\n    assert(alloc.deallocate(k));\n    assert(alloc.empty == Ternary.yes);\n\n    k = alloc.allocate(512);\n    assert(k.length == 512);\n    assert(alloc.empty == Ternary.no);\n    assert(alloc.deallocate(k));\n    assert(alloc.empty == Ternary.yes);\n\n    k = alloc.allocate(1024);\n    assert(k.length == 1024);\n    assert(alloc.empty == Ternary.no);\n    assert(alloc.deallocate(k));\n    assert(alloc.empty == Ternary.yes);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/null_allocator.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/null_allocator.d)\n*/\nmodule std.experimental.allocator.building_blocks.null_allocator;\n\n/**\n`NullAllocator` is an emphatically empty implementation of the allocator\ninterface. Although it has no direct use, it is useful as a \"terminator\" in\ncomposite allocators.\n*/\nstruct NullAllocator\n{\n    import std.typecons : Ternary;\n\n    nothrow @nogc pure @safe:\n    /**\n    `NullAllocator` advertises a relatively large _alignment equal to 64 KB.\n    This is because `NullAllocator` never actually needs to honor this\n    alignment and because composite allocators using `NullAllocator`\n    shouldn't be unnecessarily constrained.\n    */\n    enum uint alignment = 64 * 1024;\n    // /// Returns `n`.\n    //size_t goodAllocSize(size_t n) shared const\n    //{ return .goodAllocSize(this, n); }\n    /// Always returns `null`.\n    void[] allocate(size_t) shared { return null; }\n    /// Always returns `null`.\n    void[] alignedAllocate(size_t, uint) shared { return null; }\n    /// Always returns `null`.\n    void[] allocateAll() shared { return null; }\n    /**\n    These methods return `false`.\n    Precondition: $(D b is null). This is because there is no other possible\n    legitimate input.\n    */\n    bool expand(ref void[] b, size_t s) shared\n    { assert(b is null); return s == 0; }\n    /// Ditto\n    bool reallocate(ref void[] b, size_t) shared\n    { assert(b is null); return false; }\n    /// Ditto\n    bool alignedReallocate(ref void[] b, size_t, uint) shared\n    { assert(b is null); return false; }\n    /// Returns `Ternary.no`.\n    Ternary owns(const void[]) shared const { return Ternary.no; }\n    /**\n    Returns `Ternary.no`.\n    */\n    Ternary resolveInternalPointer(const void*, ref void[]) shared const\n    { return Ternary.no; }\n    /**\n    No-op.\n    Precondition: $(D b is null)\n    */\n    bool deallocate(void[] b) shared { assert(b is null); return true; }\n    /**\n    No-op.\n    */\n    bool deallocateAll() shared { return true; }\n    /**\n    Returns `Ternary.yes`.\n    */\n    Ternary empty() shared const { return Ternary.yes; }\n    /**\n    Returns the `shared` global instance of the `NullAllocator`.\n    */\n    static shared NullAllocator instance;\n}\n\nnothrow @nogc pure @safe unittest\n{\n    alias a = NullAllocator.instance;\n\n    assert(a.alignedAllocate(100, 0) is null);\n    assert(a.allocateAll() is null);\n    auto b = a.allocate(100);\n    assert(b is null);\n    assert(a.expand(b, 0));\n    assert(!a.expand(b, 42));\n    assert(!a.reallocate(b, 42));\n    assert(!a.alignedReallocate(b, 42, 0));\n    assert(a.deallocate(b));\n    assert(a.deallocateAll());\n\n    import std.typecons : Ternary;\n    assert(a.empty == Ternary.yes);\n    assert(a.owns(null) == Ternary.no);\n\n    void[] p;\n    assert(a.resolveInternalPointer(null, p) == Ternary.no);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/package.d",
    "content": "// Written in the D programming language.\n/**\n$(H2 Assembling Your Own Allocator)\n\nThis package also implements\nuntyped composable memory allocators. They are $(I untyped) because they deal\nexclusively in `void[]` and have no notion of what type the memory allocated\nwould be destined for. They are $(I composable) because the included allocators\nare building blocks that can be assembled in complex nontrivial allocators.\n\n$(P Unlike the allocators for the C and C++ programming languages, which manage\nthe allocated size internally, these allocators require that the client\nmaintains (or knows $(I a priori)) the allocation size for each piece of memory\nallocated. Put simply, the client must pass the allocated size upon\ndeallocation. Storing the size in the _allocator has significant negative\nperformance implications, and is virtually always redundant because client code\nneeds knowledge of the allocated size in order to avoid buffer overruns. (See\nmore discussion in a $(HTTP open-\nstd.org/JTC1/SC22/WG21/docs/papers/2013/n3536.html, proposal) for sized\ndeallocation in C++.) For this reason, allocators herein traffic in `void[]`\nas opposed to `void*`.)\n\n$(P In order to be usable as an _allocator, a type should implement the\nfollowing methods with their respective semantics. Only `alignment` and  $(D\nallocate) are required. If any of the other methods is missing, the _allocator\nis assumed to not have that capability (for example some allocators do not offer\nmanual deallocation of memory). Allocators should NOT implement\nunsupported methods to always fail. For example, an allocator that lacks the\ncapability to implement `alignedAllocate` should not define it at all (as\nopposed to defining it to always return `null` or throw an exception). The\nmissing implementation statically informs other components about the\nallocator's capabilities and allows them to make design decisions accordingly.)\n\n$(BOOKTABLE ,\n$(TR $(TH Method name) $(TH Semantics))\n\n$(TR $(TDC uint alignment;, $(POST $(RES) > 0)) $(TD Returns the minimum\nalignment of all data returned by the allocator. An allocator may implement $(D\nalignment) as a statically-known `enum` value only. Applications that need\ndynamically-chosen alignment values should use the `alignedAllocate` and $(D\nalignedReallocate) APIs.))\n\n$(TR $(TDC size_t goodAllocSize(size_t n);, $(POST $(RES) >= n)) $(TD Allocators\ncustomarily allocate memory in discretely-sized chunks. Therefore, a request for\n`n` bytes may result in a larger allocation. The extra memory allocated goes\nunused and adds to the so-called $(HTTP goo.gl/YoKffF,internal fragmentation).\nThe function `goodAllocSize(n)` returns the actual number of bytes that would\nbe allocated upon a request for `n` bytes. This module defines a default\nimplementation that returns `n` rounded up to a multiple of the allocator's\nalignment.))\n\n$(TR $(TDC void[] allocate(size_t s);, $(POST $(RES) is null || $(RES).length ==\ns)) $(TD If $(D s == 0), the call may return any empty slice (including $(D\nnull)). Otherwise, the call allocates `s` bytes of memory and returns the\nallocated block, or `null` if the request could not be satisfied.))\n\n$(TR $(TDC void[] alignedAllocate(size_t s, uint a);, $(POST $(RES) is null ||\n$(RES).length == s)) $(TD Similar to `allocate`, with the additional\nguarantee that the memory returned is aligned to at least `a` bytes. `a`\nmust be a power of 2.))\n\n$(TR $(TDC void[] allocateAll();) $(TD Offers all of allocator's memory to the\ncaller, so it's usually defined by fixed-size allocators. If the allocator is\ncurrently NOT managing any memory, then `allocateAll()` shall allocate and\nreturn all memory available to the allocator, and subsequent calls to all\nallocation primitives should not succeed (e.g. `allocate` shall return $(D\nnull) etc). Otherwise, `allocateAll` only works on a best-effort basis, and\nthe allocator is allowed to return `null` even if does have available memory.\nMemory allocated with `allocateAll` is not otherwise special (e.g. can be\nreallocated or deallocated with the usual primitives, if defined).))\n\n$(TR $(TDC bool expand(ref void[] b, size_t delta);, $(POST !$(RES) || b.length\n== $(I old)(b).length + delta)) $(TD Expands `b` by `delta` bytes. If $(D\ndelta == 0), succeeds without changing `b`. If $(D b is null), returns\n`false` (the null pointer cannot be expanded in place). Otherwise, $(D\nb) must be a buffer previously allocated with the same allocator. If expansion\nwas successful, `expand` changes `b`'s length to $(D b.length + delta) and\nreturns `true`. Upon failure, the call effects no change upon the allocator\nobject, leaves `b` unchanged, and returns `false`.))\n\n$(TR $(TDC bool reallocate(ref void[] b, size_t s);, $(POST !$(RES) || b.length\n== s)) $(TD Reallocates `b` to size `s`, possibly moving memory around.\n`b` must be `null` or a buffer allocated with the same allocator. If\nreallocation was successful, `reallocate` changes `b` appropriately and\nreturns `true`. Upon failure, the call effects no change upon the allocator\nobject, leaves `b` unchanged, and returns `false`. An allocator should\nimplement `reallocate` if it can derive some advantage from doing so;\notherwise, this module defines a `reallocate` free function implemented in\nterms of `expand`, `allocate`, and `deallocate`.))\n\n$(TR $(TDC bool alignedReallocate(ref void[] b,$(BR) size_t s, uint a);, $(POST\n!$(RES) || b.length == s)) $(TD Similar to `reallocate`, but guarantees the\nreallocated memory is aligned at `a` bytes. The buffer must have been\noriginated with a call to `alignedAllocate`. `a` must be a power of 2\ngreater than `(void*).sizeof`. An allocator should implement $(D\nalignedReallocate) if it can derive some advantage from doing so; otherwise,\nthis module defines a `alignedReallocate` free function implemented in terms\nof `expand`, `alignedAllocate`, and `deallocate`.))\n\n$(TR $(TDC Ternary owns(void[] b);) $(TD Returns `Ternary.yes` if `b` has been\nallocated with this allocator. An allocator should define this method only if it\ncan decide on ownership precisely and fast (in constant time, logarithmic time,\nor linear time with a low multiplication factor). Traditional allocators such as\nthe C heap do not define such functionality. If $(D b is null), the allocator\nshall return `Ternary.no`, i.e. no allocator owns the `null` slice.))\n\n$(TR $(TDC Ternary resolveInternalPointer(void* p, ref void[] result);) $(TD If\n`p` is a pointer somewhere inside a block allocated with this allocator,\n`result` holds a pointer to the beginning of the allocated block and returns\n`Ternary.yes`. Otherwise, `result` holds `null` and returns `Ternary.no`.\nIf the pointer points immediately after an allocated block, the result is\nimplementation defined.))\n\n$(TR $(TDC bool deallocate(void[] b);) $(TD If $(D b is null), does\nnothing and returns `true`. Otherwise, deallocates memory previously allocated\nwith this allocator and returns `true` if successful, `false` otherwise. An\nimplementation that would not support deallocation (i.e. would always return\n`false` should not define this primitive at all.)))\n\n$(TR $(TDC bool deallocateAll();, $(POST empty)) $(TD Deallocates all memory\nallocated with this allocator. If an allocator implements this method, it must\nspecify whether its destructor calls it, too.))\n\n$(TR $(TDC Ternary empty();) $(TD Returns `Ternary.yes` if and only if the\nallocator holds no memory (i.e. no allocation has occurred, or all allocations\nhave been deallocated).))\n\n$(TR $(TDC static Allocator instance;, $(POST instance $(I is a valid)\nAllocator $(I object))) $(TD Some allocators are $(I monostate), i.e. have only\nan instance and hold only global state. (Notable examples are C's own\n`malloc`-based allocator and D's garbage-collected heap.) Such allocators must\ndefine a static `instance` instance that serves as the symbolic placeholder\nfor the global instance of the allocator. An allocator should not hold state\nand define `instance` simultaneously. Depending on whether the allocator is\nthread-safe or not, this instance may be `shared`.))\n)\n\n$(H2 Sample Assembly)\n\nThe example below features an _allocator modeled after $(HTTP goo.gl/m7329l,\njemalloc), which uses a battery of free-list allocators spaced so as to keep\ninternal fragmentation to a minimum. The `FList` definitions specify no\nbounds for the freelist because the `Segregator` does all size selection in\nadvance.\n\nSizes through 3584 bytes are handled via freelists of staggered sizes. Sizes\nfrom 3585 bytes through 4072 KB are handled by a `BitmappedBlock` with a\nblock size of 4 KB. Sizes above that are passed direct to the `GCAllocator`.\n\n----\n    alias FList = FreeList!(GCAllocator, 0, unbounded);\n    alias A = Segregator!(\n        8, FreeList!(GCAllocator, 0, 8),\n        128, Bucketizer!(FList, 1, 128, 16),\n        256, Bucketizer!(FList, 129, 256, 32),\n        512, Bucketizer!(FList, 257, 512, 64),\n        1024, Bucketizer!(FList, 513, 1024, 128),\n        2048, Bucketizer!(FList, 1025, 2048, 256),\n        3584, Bucketizer!(FList, 2049, 3584, 512),\n        4072 * 1024, AllocatorList!(\n            () => BitmappedBlock!(GCAllocator, 4096)(4072 * 1024)),\n        GCAllocator\n    );\n    A tuMalloc;\n    auto b = tuMalloc.allocate(500);\n    assert(b.length == 500);\n    auto c = tuMalloc.allocate(113);\n    assert(c.length == 113);\n    assert(tuMalloc.expand(c, 14));\n    tuMalloc.deallocate(b);\n    tuMalloc.deallocate(c);\n----\n\n$(H2 Allocating memory for sharing across threads)\n\nOne allocation pattern used in multithreaded applications is to share memory\nacross threads, and to deallocate blocks in a different thread than the one that\nallocated it.\n\nAll allocators in this module accept and return `void[]` (as opposed to\n$(D shared void[])). This is because at the time of allocation, deallocation, or\nreallocation, the memory is effectively not `shared` (if it were, it would\nreveal a bug at the application level).\n\nThe issue remains of calling `a.deallocate(b)` from a different thread than\nthe one that allocated `b`. It follows that both threads must have access to\nthe same instance `a` of the respective allocator type. By definition of D,\nthis is possible only if `a` has the `shared` qualifier. It follows that\nthe allocator type must implement `allocate` and `deallocate` as $(D\nshared) methods. That way, the allocator commits to allowing usable `shared`\ninstances.\n\nConversely, allocating memory with one non-`shared` allocator, passing it\nacross threads (by casting the obtained buffer to `shared`), and later\ndeallocating it in a different thread (either with a different allocator object\nor with the same allocator object after casting it to `shared`) is illegal.\n\n$(H2 Building Blocks)\n\n$(P The table below gives a synopsis of predefined allocator building blocks,\nwith their respective modules. Either `import` the needed modules individually,\nor `import` `std.experimental.building_blocks`, which imports them all\n`public`ly. The building blocks can be assembled in unbounded ways and also\ncombined with your own. For a collection of typical and useful preassembled\nallocators and for inspiration in defining more such assemblies, refer to\n$(MREF std,experimental,allocator,showcase).)\n\n$(BOOKTABLE,\n$(TR $(TH Allocator$(BR)) $(TH Description))\n\n$(TR $(TDC2 NullAllocator, null_allocator) $(TD Very good at doing absolutely nothing. A good\nstarting point for defining other allocators or for studying the API.))\n\n$(TR $(TDC3 GCAllocator, gc_allocator) $(TD The system-provided garbage-collector allocator.\nThis should be the default fallback allocator tapping into system memory. It\noffers manual `free` and dutifully collects litter.))\n\n$(TR $(TDC3 Mallocator, mallocator) $(TD The C heap _allocator, a.k.a. $(D\nmalloc)/`realloc`/`free`. Use sparingly and only for code that is unlikely\nto leak.))\n\n$(TR $(TDC3 AlignedMallocator, mallocator) $(TD Interface to OS-specific _allocators that\nsupport specifying alignment:\n$(HTTP man7.org/linux/man-pages/man3/posix_memalign.3.html, `posix_memalign`)\non Posix and $(HTTP msdn.microsoft.com/en-us/library/fs9stz4e(v=vs.80).aspx,\n`__aligned_xxx`) on Windows.))\n\n$(TR $(TDC2 AlignedBlockList, aligned_block_list) $(TD A wrapper around a list of allocators\nwhich allow for very fast deallocations.))\n\n$(TR $(TDC2 AffixAllocator, affix_allocator) $(TD Allocator that allows and manages allocating\nextra prefix and/or a suffix bytes for each block allocated.))\n\n$(TR $(TDC2 BitmappedBlock, bitmapped_block) $(TD Organizes one contiguous chunk of memory in\nequal-size blocks and tracks allocation status at the cost of one bit per\nblock.))\n\n$(TR $(TDC2 FallbackAllocator, fallback_allocator) $(TD Allocator that combines two other allocators\n - primary and fallback. Allocation requests are first tried with primary, and\n upon failure are passed to the fallback. Useful for small and fast allocators\n fronting general-purpose ones.))\n\n$(TR $(TDC2 FreeList, free_list) $(TD Allocator that implements a $(HTTP\nwikipedia.org/wiki/Free_list, free list) on top of any other allocator. The\npreferred size, tolerance, and maximum elements are configurable at compile- and\nrun time.))\n\n$(TR $(TDC2 SharedFreeList, free_list) $(TD Same features as `FreeList`, but packaged as\na `shared` structure that is accessible to several threads.))\n\n$(TR $(TDC2 FreeTree, free_tree) $(TD Allocator similar to `FreeList` that uses a\nbinary search tree to adaptively store not one, but many free lists.))\n\n$(TR $(TDC2 Region, region) $(TD Region allocator organizes a chunk of memory as a\nsimple bump-the-pointer allocator.))\n\n$(TR $(TDC2 InSituRegion, region) $(TD Region holding its own allocation, most often on\nthe stack. Has statically-determined size.))\n\n$(TR $(TDC2 SbrkRegion, region) $(TD Region using $(D $(LINK2 https://en.wikipedia.org/wiki/Sbrk,\nsbrk)) for allocating memory.))\n\n$(TR $(TDC3 MmapAllocator, mmap_allocator) $(TD Allocator using\n            $(D $(LINK2 https://en.wikipedia.org/wiki/Mmap, mmap)) directly.))\n\n$(TR $(TDC2 StatsCollector, stats_collector) $(TD Collect statistics about any other\nallocator.))\n\n$(TR $(TDC2 Quantizer, quantizer) $(TD Allocates in coarse-grained quantas, thus\nimproving performance of reallocations by often reallocating in place. The drawback is higher memory consumption because of allocated and unused memory.))\n\n$(TR $(TDC2 AllocatorList, allocator_list) $(TD Given an allocator factory, lazily creates as\nmany allocators as needed to satisfy allocation requests. The allocators are\nstored in a linked list. Requests for allocation are satisfied by searching the\nlist in a linear manner.))\n\n$(TR $(TDC2 Segregator, segregator) $(TD Segregates allocation requests by size\nand dispatches them to distinct allocators.))\n\n$(TR $(TDC2 Bucketizer, bucketizer) $(TD Divides allocation sizes in discrete buckets and\nuses an array of allocators, one per bucket, to satisfy requests.))\n\n$(TR $(TDC2 AscendingPageAllocator, ascending_page_allocator) $(TD A memory safe allocator\nwhere sizes are rounded to a multiple of the page size and allocations are satisfied at increasing addresses.))\n\n$(COMMENT $(TR $(TDC2 InternalPointersTree) $(TD Adds support for resolving internal\npointers on top of another allocator.)))\n)\n\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/package.d)\n\nMacros:\nMYREF2 = $(REF_SHORT $1, std,experimental,allocator,building_blocks,$2)\nMYREF3 = $(REF_SHORT $1, std,experimental,allocator,$2)\nTDC = $(TDNW `$1`$+)\nTDC2 = $(TDNW $(D $(MYREF2 $1,$+))$(BR)$(SMALL\n`std.experimental.allocator.building_blocks.$2`))\nTDC3 = $(TDNW $(D $(MYREF3 $1,$+))$(BR)$(SMALL\n`std.experimental.allocator.$2`))\nRES = $(I result)\nPOST = $(BR)$(SMALL $(I Post:) $(BLUE `$0`))\n*/\n\nmodule std.experimental.allocator.building_blocks;\n\npublic import\n    std.experimental.allocator.building_blocks.affix_allocator,\n    std.experimental.allocator.building_blocks.aligned_block_list,\n    std.experimental.allocator.building_blocks.allocator_list,\n    std.experimental.allocator.building_blocks.ascending_page_allocator,\n    std.experimental.allocator.building_blocks.bucketizer,\n    std.experimental.allocator.building_blocks.fallback_allocator,\n    std.experimental.allocator.building_blocks.free_list,\n    std.experimental.allocator.building_blocks.free_tree,\n    std.experimental.allocator.gc_allocator,\n    std.experimental.allocator.building_blocks.bitmapped_block,\n    std.experimental.allocator.building_blocks.kernighan_ritchie,\n    std.experimental.allocator.mallocator,\n    std.experimental.allocator.mmap_allocator,\n    std.experimental.allocator.building_blocks.null_allocator,\n    std.experimental.allocator.building_blocks.quantizer,\n    std.experimental.allocator.building_blocks.region,\n    std.experimental.allocator.building_blocks.segregator,\n    std.experimental.allocator.building_blocks.stats_collector;\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/quantizer.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/quantizer.d)\n*/\nmodule std.experimental.allocator.building_blocks.quantizer;\n\nimport std.experimental.allocator.common;\n\n/**\nThis allocator sits on top of `ParentAllocator` and quantizes allocation sizes,\nusually from arbitrary positive numbers to a small set of round numbers (e.g.\npowers of two, page sizes etc). This technique is commonly used to:\n\n$(UL\n$(LI Preallocate more memory than requested such that later on, when\nreallocation is needed (e.g. to grow an array), expansion can be done quickly\nin place. Reallocation to smaller sizes is also fast (in-place) when the new\nsize requested is within the same quantum as the existing size. Code that's\nreallocation-heavy can therefore benefit from fronting a generic allocator with\na `Quantizer`. These advantages are present even if `ParentAllocator` does not\nsupport reallocation at all.)\n$(LI Improve behavior of allocators sensitive to allocation sizes, such as\n`FreeList` and `FreeTree`. Rounding allocation requests up makes for smaller\nfree lists/trees at the cost of slack memory (internal fragmentation).)\n)\n\nThe following methods are forwarded to the parent allocator if present:\n`allocateAll`, `owns`, `deallocateAll`, `empty`.\n\nPreconditions: `roundingFunction` must satisfy three constraints. These are\nnot enforced (save for the use of `assert`) for the sake of efficiency.\n$(OL\n$(LI $(D roundingFunction(n) >= n) for all `n` of type `size_t`;)\n$(LI `roundingFunction` must be monotonically increasing, i.e. $(D\nroundingFunction(n1) <= roundingFunction(n2)) for all $(D n1 < n2);)\n$(LI `roundingFunction` must be `nothrow`, `@safe`, `@nogc` and `pure`, i.e.\nalways return the same value for a given `n`.)\n)\n*/\nstruct Quantizer(ParentAllocator, alias roundingFunction)\n{\n    import std.traits : hasMember;\n\n    /**\n    The parent allocator. Depending on whether `ParentAllocator` holds state\n    or not, this is a member variable or an alias for\n    `ParentAllocator.instance`.\n    */\n    static if (stateSize!ParentAllocator)\n    {\n        ParentAllocator parent;\n    }\n    else\n    {\n        alias parent = ParentAllocator.instance;\n        __gshared Quantizer instance;\n    }\n\n    /**\n    Returns `roundingFunction(n)`.\n    */\n    size_t goodAllocSize(size_t n)\n    {\n        auto result = roundingFunction(n);\n        assert(result >= n);\n        return result;\n    }\n\n    /**\n    Alignment is identical to that of the parent.\n    */\n    enum alignment = ParentAllocator.alignment;\n\n    /**\n    Gets a larger buffer `buf` by calling\n    `parent.allocate(goodAllocSize(n))`. If `buf` is `null`, returns\n    `null`. Otherwise, returns $(D buf[0 .. n]).\n    */\n    void[] allocate(size_t n)\n    {\n        auto result = parent.allocate(goodAllocSize(n));\n        return result.ptr ? result.ptr[0 .. n] : null;\n    }\n\n    static if (hasMember!(ParentAllocator, \"allocateZeroed\"))\n    package(std) void[] allocateZeroed()(size_t n)\n    {\n        auto result = parent.allocateZeroed(goodAllocSize(n));\n        return result.ptr ? result.ptr[0 .. n] : null;\n    }\n\n    /**\n    Defined only if `parent.alignedAllocate` exists and works similarly to\n    `allocate` by forwarding to\n    $(D parent.alignedAllocate(goodAllocSize(n), a)).\n    */\n    static if (hasMember!(ParentAllocator, \"alignedAllocate\"))\n    void[] alignedAllocate(size_t n, uint a)\n    {\n        auto result = parent.alignedAllocate(goodAllocSize(n), a);\n        return result.ptr ? result.ptr[0 .. n] : null;\n    }\n\n    /**\n    First checks whether there's enough slack memory preallocated for `b`\n    by evaluating $(D b.length + delta <= goodAllocSize(b.length)). If that's\n    the case, expands `b` in place. Otherwise, attempts to use\n    `parent.expand` appropriately if present.\n    */\n    bool expand(ref void[] b, size_t delta)\n    {\n        if (!b || delta == 0) return delta == 0;\n        immutable allocated = goodAllocSize(b.length),\n            needed = b.length + delta,\n            neededAllocation = goodAllocSize(needed);\n        assert(b.length <= allocated);\n        assert(needed <= neededAllocation);\n        assert(allocated <= neededAllocation);\n        // Second test needed because expand must work for null pointers, too.\n        if (allocated == neededAllocation)\n        {\n            // Nice!\n            b = (() @trusted => b.ptr[0 .. needed])();\n            return true;\n        }\n        // Hail Mary\n        static if (hasMember!(ParentAllocator, \"expand\"))\n        {\n            // Expand to the appropriate quantum\n            auto original = (() @trusted => b.ptr[0 .. allocated])();\n            assert(goodAllocSize(needed) >= allocated);\n            if (!parent.expand(original, neededAllocation - allocated))\n                return false;\n            // Dial back the size\n            b = (() @trusted => original.ptr[0 .. needed])();\n            return true;\n        }\n        else\n        {\n            return false;\n        }\n    }\n\n    /**\n    Expands or shrinks allocated block to an allocated size of $(D\n    goodAllocSize(s)). Expansion occurs in place under the conditions required\n    by `expand`. Shrinking occurs in place if $(D goodAllocSize(b.length)\n    == goodAllocSize(s)).\n    */\n    bool reallocate(ref void[] b, size_t s)\n    {\n        if (!b.ptr)\n        {\n            b = allocate(s);\n            return b.length == s;\n        }\n        if (s >= b.length && expand(b, s - b.length)) return true;\n        immutable toAllocate = goodAllocSize(s),\n            allocated = goodAllocSize(b.length);\n        // Are the lengths within the same quantum?\n        if (allocated == toAllocate)\n        {\n            // Reallocation (whether up or down) will be done in place\n            b = b.ptr[0 .. s];\n            return true;\n        }\n        // Defer to parent (or global) with quantized size\n        auto original = b.ptr[0 .. allocated];\n        if (!parent.reallocate(original, toAllocate)) return false;\n        b = original.ptr[0 .. s];\n        return true;\n    }\n\n    /**\n    Defined only if `ParentAllocator.alignedAllocate` exists. Expansion\n    occurs in place under the conditions required by `expand`. Shrinking\n    occurs in place if $(D goodAllocSize(b.length) == goodAllocSize(s)).\n    */\n    static if (hasMember!(ParentAllocator, \"alignedAllocate\"))\n    bool alignedReallocate(ref void[] b, size_t s, uint a)\n    {\n        if (!b.ptr)\n        {\n            b = alignedAllocate(s, a);\n            return b.length == s;\n        }\n        if (s >= b.length && b.ptr.alignedAt(a) && expand(b, s - b.length)) return true;\n        immutable toAllocate = goodAllocSize(s),\n            allocated = goodAllocSize(b.length);\n        // Are the lengths within the same quantum?\n        if (allocated == toAllocate && b.ptr.alignedAt(a))\n        {\n            assert(b.ptr); // code above must have caught this\n            // Reallocation (whether up or down) will be done in place\n            b = b.ptr[0 .. s];\n            return true;\n        }\n        // Defer to parent (or global) with quantized size\n        auto original = b.ptr[0 .. allocated];\n        if (!parent.alignedReallocate(original, toAllocate, a)) return false;\n        b = original.ptr[0 .. s];\n        return true;\n    }\n\n    /**\n    Defined if `ParentAllocator.deallocate` exists and forwards to\n    $(D parent.deallocate(b.ptr[0 .. goodAllocSize(b.length)])).\n    */\n    static if (hasMember!(ParentAllocator, \"deallocate\"))\n    bool deallocate(void[] b)\n    {\n        if (!b.ptr) return true;\n        return parent.deallocate(b.ptr[0 .. goodAllocSize(b.length)]);\n    }\n\n    // Forwarding methods\n    mixin(forwardToMember(\"parent\",\n        \"allocateAll\", \"owns\", \"deallocateAll\", \"empty\"));\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.free_tree : FreeTree;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n\n    size_t roundUpToMultipleOf(size_t s, uint base)\n    {\n        auto rem = s % base;\n        return rem ? s + base - rem : s;\n    }\n\n    // Quantize small allocations to a multiple of cache line, large ones to a\n    // multiple of page size\n    alias MyAlloc = Quantizer!(\n        FreeTree!GCAllocator,\n        n => roundUpToMultipleOf(n, n <= 16_384 ? 64 : 4096));\n    MyAlloc alloc;\n    const buf = alloc.allocate(256);\n    assert(buf.ptr);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    alias MyAlloc = Quantizer!(GCAllocator,\n        (size_t n) => n.roundUpToMultipleOf(64));\n    testAllocator!(() => MyAlloc());\n\n    assert((() pure nothrow @safe @nogc => MyAlloc().goodAllocSize(1))() == 64);\n\n    auto a = MyAlloc();\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    // Inplace expand, since goodAllocSize is 64\n    assert((() @safe => a.expand(b, 22))());\n    //assert((() nothrow @safe => a.expand(b, 22))());\n    assert(b.length == 64);\n    // Trigger parent.expand, which may or may not succed\n    //() nothrow @safe { a.expand(b, 1); }();\n    () @safe { a.expand(b, 1); }();\n    assert(a.reallocate(b, 100));\n    assert(b.length == 100);\n    // Ensure deallocate inherits from parent\n    () nothrow @nogc { a.deallocate(b); }();\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Ternary;\n\n    alias Alloc = Quantizer!(Region!(Mallocator),\n            (size_t n) => n.roundUpToMultipleOf(64));\n    auto a = Alloc(Region!Mallocator(1024 * 64));\n    const b = a.allocate(42);\n    assert(b.length == 42);\n    // Check that owns inherits from parent, i.e. Region\n    assert((() pure nothrow @safe @nogc => a.owns(b))() == Ternary.yes);\n    assert((() pure nothrow @safe @nogc => a.owns(null))() == Ternary.no);\n\n    auto c = a.allocate(42);\n    assert(c.length == 42);\n    assert((() pure nothrow @safe @nogc => a.owns(c))() == Ternary.yes);\n    // Inplace expand, since goodAllocSize is 64\n    assert((() nothrow @safe => a.expand(c, 22))());\n    assert(c.length == 64);\n    // Trigger parent.expand\n    assert((() nothrow @safe => a.expand(c, 1))());\n    assert(c.length == 65);\n    // Check that reallocate inherits from parent\n    assert((() nothrow @nogc => a.reallocate(c, 100))());\n    assert(c.length == 100);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    alias MyAlloc = Quantizer!(Region!(Mallocator),\n            (size_t n) => n.roundUpToMultipleOf(64));\n    testAllocator!(() => MyAlloc(Region!Mallocator(1024 * 64)));\n\n    auto a = MyAlloc(Region!Mallocator(1024 * 64));\n    void[] b;\n    assert((() nothrow @nogc => a.alignedReallocate(b, 42, 16))());\n    assert(b.length == 42);\n    assert(alignedAt(&b[0], 16));\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.typecons : Ternary;\n\n    alias MyAlloc = Quantizer!(Region!(),\n        (size_t n) => n.roundUpToMultipleOf(64));\n    testAllocator!(() => MyAlloc(Region!()(new ubyte[1024 * 64])));\n\n    auto a = MyAlloc(Region!()(new ubyte[1024 * 64]));\n    // Check that empty inherits from parent\n    assert((() pure nothrow @safe @nogc => a.empty)() == Ternary.yes);\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    assert((() pure nothrow @safe @nogc => a.empty)() == Ternary.no);\n    // Check that deallocateAll inherits from parent\n    assert((() nothrow @nogc => a.deallocateAll())());\n    assert((() pure nothrow @safe @nogc => a.empty)() == Ternary.yes);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/region.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/region.d)\n*/\nmodule std.experimental.allocator.building_blocks.region;\n\nimport std.experimental.allocator.building_blocks.null_allocator;\nimport std.experimental.allocator.common;\nimport std.typecons : Flag, Yes, No;\n\n/**\nA `Region` allocator allocates memory straight from one contiguous chunk.\nThere is no deallocation, and once the region is full, allocation requests\nreturn `null`. Therefore, `Region`s are often used (a) in conjunction with\nmore sophisticated allocators; or (b) for batch-style very fast allocations\nthat deallocate everything at once.\n\nThe region only stores three pointers, corresponding to the current position in\nthe store and the limits. One allocation entails rounding up the allocation\nsize for alignment purposes, bumping the current pointer, and comparing it\nagainst the limit.\n\nIf `ParentAllocator` is different from $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator), `Region`\ndeallocates the chunk of memory during destruction.\n\nThe `minAlign` parameter establishes alignment. If $(D minAlign > 1), the\nsizes of all allocation requests are rounded up to a multiple of `minAlign`.\nApplications aiming at maximum speed may want to choose $(D minAlign = 1) and\ncontrol alignment externally.\n\n*/\nstruct Region(ParentAllocator = NullAllocator,\n    uint minAlign = platformAlignment,\n    Flag!\"growDownwards\" growDownwards = No.growDownwards)\n{\n    static assert(minAlign.isGoodStaticAlignment);\n    static assert(ParentAllocator.alignment >= minAlign);\n\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n\n    // state\n    /**\n    The _parent allocator. Depending on whether `ParentAllocator` holds state\n    or not, this is a member variable or an alias for\n    `ParentAllocator.instance`.\n    */\n    static if (stateSize!ParentAllocator)\n    {\n        ParentAllocator parent;\n    }\n    else\n    {\n        alias parent = ParentAllocator.instance;\n    }\n\n    private void* _current, _begin, _end;\n\n    private void* roundedBegin() const pure nothrow @trusted @nogc\n    {\n        return cast(void*) roundUpToAlignment(cast(size_t) _begin, alignment);\n    }\n\n    private void* roundedEnd() const pure nothrow @trusted @nogc\n    {\n        return cast(void*) roundDownToAlignment(cast(size_t) _end, alignment);\n    }\n    /**\n    Constructs a region backed by a user-provided store.\n    Assumes the memory was allocated with `ParentAllocator`\n    (if different from $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator)).\n\n    Params:\n        store = User-provided store backing up the region. If $(D\n        ParentAllocator) is different from $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator), memory is assumed to\n        have been allocated with `ParentAllocator`.\n        n = Bytes to allocate using `ParentAllocator`. This constructor is only\n        defined If `ParentAllocator` is different from $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator). If\n        `parent.allocate(n)` returns `null`, the region will be initialized\n        as empty (correctly initialized but unable to allocate).\n        */\n    this(ubyte[] store) pure nothrow @nogc\n    {\n        _begin = store.ptr;\n        _end = store.ptr + store.length;\n        static if (growDownwards)\n            _current = roundedEnd();\n        else\n            _current = roundedBegin();\n    }\n\n    /// Ditto\n    static if (!is(ParentAllocator == NullAllocator) && !stateSize!ParentAllocator)\n    this(size_t n)\n    {\n        this(cast(ubyte[]) (parent.allocate(n.roundUpToAlignment(alignment))));\n    }\n\n    /// Ditto\n    static if (!is(ParentAllocator == NullAllocator) && stateSize!ParentAllocator)\n    this(ParentAllocator parent, size_t n)\n    {\n        this.parent = parent;\n        this(cast(ubyte[]) (parent.allocate(n.roundUpToAlignment(alignment))));\n    }\n\n    /*\n    TODO: The postblit of `BasicRegion` should be disabled because such objects\n    should not be copied around naively.\n    */\n\n    /**\n    If `ParentAllocator` is not $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator) and defines `deallocate`,\n    the region defines a destructor that uses `ParentAllocator.deallocate` to free the\n    memory chunk.\n    */\n    static if (!is(ParentAllocator == NullAllocator)\n        && hasMember!(ParentAllocator, \"deallocate\"))\n    ~this()\n    {\n        parent.deallocate(_begin[0 .. _end - _begin]);\n    }\n\n    /**\n    Rounds the given size to a multiple of the `alignment`\n    */\n    size_t goodAllocSize(size_t n) const pure nothrow @safe @nogc\n    {\n        return n.roundUpToAlignment(alignment);\n    }\n\n    /**\n    Alignment offered.\n    */\n    alias alignment = minAlign;\n\n    /**\n    Allocates `n` bytes of memory. The shortest path involves an alignment\n    adjustment (if $(D alignment > 1)), an increment, and a comparison.\n\n    Params:\n        n = number of bytes to allocate\n\n    Returns:\n        A properly-aligned buffer of size `n` or `null` if request could not\n        be satisfied.\n    */\n    void[] allocate(size_t n) pure nothrow @trusted @nogc\n    {\n        const rounded = goodAllocSize(n);\n        if (n == 0 || rounded < n || available < rounded) return null;\n\n        static if (growDownwards)\n        {\n            assert(available >= rounded);\n            auto result = (_current - rounded)[0 .. n];\n            assert(result.ptr >= _begin);\n            _current = result.ptr;\n            assert(owns(result) == Ternary.yes);\n        }\n        else\n        {\n            auto result = _current[0 .. n];\n            _current += rounded;\n        }\n\n        return result;\n    }\n\n    /**\n    Allocates `n` bytes of memory aligned at alignment `a`.\n\n    Params:\n        n = number of bytes to allocate\n        a = alignment for the allocated block\n\n    Returns:\n        Either a suitable block of `n` bytes aligned at `a`, or `null`.\n    */\n    void[] alignedAllocate(size_t n, uint a) pure nothrow @trusted @nogc\n    {\n        import std.math : isPowerOf2;\n        assert(a.isPowerOf2);\n\n        const rounded = goodAllocSize(n);\n        if (n == 0 || rounded < n || available < rounded) return null;\n\n        static if (growDownwards)\n        {\n            auto tmpCurrent = _current - rounded;\n            auto result = tmpCurrent.alignDownTo(a);\n            if (result <= tmpCurrent && result >= _begin)\n            {\n                _current = result;\n                return cast(void[]) result[0 .. n];\n            }\n        }\n        else\n        {\n            // Just bump the pointer to the next good allocation\n            auto newCurrent = _current.alignUpTo(a);\n            if (newCurrent < _current || newCurrent > _end)\n                return null;\n\n            auto save = _current;\n            _current = newCurrent;\n            auto result = allocate(n);\n            if (result.ptr)\n            {\n                assert(result.length == n);\n                return result;\n            }\n            // Failed, rollback\n            _current = save;\n        }\n        return null;\n    }\n\n    /// Allocates and returns all memory available to this region.\n    void[] allocateAll() pure nothrow @trusted @nogc\n    {\n        static if (growDownwards)\n        {\n            auto result = _begin[0 .. available];\n            _current = _begin;\n        }\n        else\n        {\n            auto result = _current[0 .. available];\n            _current = _end;\n        }\n        return result;\n    }\n\n    /**\n    Expands an allocated block in place. Expansion will succeed only if the\n    block is the last allocated. Defined only if `growDownwards` is\n    `No.growDownwards`.\n    */\n    static if (growDownwards == No.growDownwards)\n    bool expand(ref void[] b, size_t delta) pure nothrow @safe @nogc\n    {\n        assert(owns(b) == Ternary.yes || b is null);\n        assert((() @trusted => b.ptr + b.length <= _current)() || b is null);\n        if (b is null || delta == 0) return delta == 0;\n        auto newLength = b.length + delta;\n        if ((() @trusted => _current < b.ptr + b.length + alignment)())\n        {\n            immutable currentGoodSize = this.goodAllocSize(b.length);\n            immutable newGoodSize = this.goodAllocSize(newLength);\n            immutable goodDelta = newGoodSize - currentGoodSize;\n            // This was the last allocation! Allocate some more and we're done.\n            if (goodDelta == 0\n                || (() @trusted => allocate(goodDelta).length == goodDelta)())\n            {\n                b = (() @trusted => b.ptr[0 .. newLength])();\n                assert((() @trusted => _current < b.ptr + b.length + alignment)());\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n    Deallocates `b`. This works only if `b` was obtained as the last call\n    to `allocate`; otherwise (i.e. another allocation has occurred since) it\n    does nothing.\n\n    Params:\n        b = Block previously obtained by a call to `allocate` against this\n        allocator (`null` is allowed).\n    */\n    bool deallocate(void[] b) pure nothrow @nogc\n    {\n        assert(owns(b) == Ternary.yes || b.ptr is null);\n        auto rounded = goodAllocSize(b.length);\n        static if (growDownwards)\n        {\n            if (b.ptr == _current)\n            {\n                _current += rounded;\n                return true;\n            }\n        }\n        else\n        {\n            if (b.ptr + rounded == _current)\n            {\n                assert(b.ptr !is null || _current is null);\n                _current = b.ptr;\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n    Deallocates all memory allocated by this region, which can be subsequently\n    reused for new allocations.\n    */\n    bool deallocateAll() pure nothrow @nogc\n    {\n        static if (growDownwards)\n        {\n            _current = roundedEnd();\n        }\n        else\n        {\n            _current = roundedBegin();\n        }\n        return true;\n    }\n\n    /**\n    Queries whether `b` has been allocated with this region.\n\n    Params:\n        b = Arbitrary block of memory (`null` is allowed; `owns(null)` returns\n        `false`).\n\n    Returns:\n        `true` if `b` has been allocated with this region, `false` otherwise.\n    */\n    Ternary owns(const void[] b) const pure nothrow @trusted @nogc\n    {\n        return Ternary(b && (&b[0] >= _begin) && (&b[0] + b.length <= _end));\n    }\n\n    /**\n    Returns `Ternary.yes` if no memory has been allocated in this region,\n    `Ternary.no` otherwise. (Never returns `Ternary.unknown`.)\n    */\n    Ternary empty() const pure nothrow @safe @nogc\n    {\n        static if (growDownwards)\n            return Ternary(_current == roundedEnd());\n        else\n            return Ternary(_current == roundedBegin());\n    }\n\n    /// Nonstandard property that returns bytes available for allocation.\n    size_t available() const @safe pure nothrow @nogc\n    {\n        static if (growDownwards)\n        {\n            return _current - _begin;\n        }\n        else\n        {\n            return _end - _current;\n        }\n    }\n}\n\n///\n@system nothrow unittest\n{\n    import std.algorithm.comparison : max;\n    import std.experimental.allocator.building_blocks.allocator_list\n        : AllocatorList;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Ternary;\n    // Create a scalable list of regions. Each gets at least 1MB at a time by\n    // using malloc.\n    auto batchAllocator = AllocatorList!(\n        (size_t n) => Region!Mallocator(max(n, 1024 * 1024))\n    )();\n    assert(batchAllocator.empty ==  Ternary.yes);\n    auto b = batchAllocator.allocate(101);\n    assert(b.length == 101);\n    assert(batchAllocator.empty ==  Ternary.no);\n    // This will cause a second allocation\n    b = batchAllocator.allocate(2 * 1024 * 1024);\n    assert(b.length == 2 * 1024 * 1024);\n    // Destructor will free the memory\n}\n\n@system nothrow @nogc unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Ternary;\n\n    static void testAlloc(Allocator)(ref Allocator a)\n    {\n        assert((() pure nothrow @safe @nogc => a.empty)() ==  Ternary.yes);\n        const b = a.allocate(101);\n        assert(b.length == 101);\n        assert((() nothrow @safe @nogc => a.owns(b))() == Ternary.yes);\n\n        // Ensure deallocate inherits from parent allocators\n        auto c = a.allocate(42);\n        assert(c.length == 42);\n        assert((() nothrow @nogc => a.deallocate(c))());\n        assert((() pure nothrow @safe @nogc => a.empty)() ==  Ternary.no);\n    }\n\n    // Create a 64 KB region allocated with malloc\n    auto reg = Region!(Mallocator, Mallocator.alignment,\n        Yes.growDownwards)(1024 * 64);\n    testAlloc(reg);\n\n    // Create a 64 KB shared region allocated with malloc\n    auto sharedReg = SharedRegion!(Mallocator, Mallocator.alignment,\n        Yes.growDownwards)(1024 * 64);\n    testAlloc(sharedReg);\n}\n\n@system nothrow @nogc unittest\n{\n    import std.experimental.allocator.mallocator : AlignedMallocator;\n    import std.typecons : Ternary;\n\n    ubyte[] buf = cast(ubyte[]) AlignedMallocator.instance.alignedAllocate(64, 64);\n    auto reg = Region!(NullAllocator, 64, Yes.growDownwards)(buf);\n    assert(reg.alignedAllocate(10, 32).length == 10);\n    assert(!reg.available);\n}\n\n@system nothrow @nogc unittest\n{\n    // test 'this(ubyte[] store)' constructed regions properly clean up\n    // their inner storage after destruction\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    static shared struct LocalAllocator\n    {\n    nothrow @nogc:\n        enum alignment = Mallocator.alignment;\n        void[] buf;\n        bool deallocate(void[] b)\n        {\n            assert(buf.ptr == b.ptr && buf.length == b.length);\n            return true;\n        }\n\n        void[] allocate(size_t n)\n        {\n            return null;\n        }\n\n    }\n\n    enum bufLen = 10 * Mallocator.alignment;\n    void[] tmp = Mallocator.instance.allocate(bufLen);\n\n    LocalAllocator a;\n    a.buf = cast(typeof(a.buf)) tmp[1 .. $];\n\n    auto reg = Region!(LocalAllocator, Mallocator.alignment,\n        Yes.growDownwards)(cast(ubyte[]) a.buf);\n    auto sharedReg = SharedRegion!(LocalAllocator, Mallocator.alignment,\n        Yes.growDownwards)(cast(ubyte[]) a.buf);\n    reg.parent = a;\n    sharedReg.parent = a;\n\n    Mallocator.instance.deallocate(tmp);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    testAllocator!(() => Region!(Mallocator)(1024 * 64));\n    testAllocator!(() => Region!(Mallocator, Mallocator.alignment, Yes.growDownwards)(1024 * 64));\n\n    testAllocator!(() => SharedRegion!(Mallocator)(1024 * 64));\n    testAllocator!(() => SharedRegion!(Mallocator, Mallocator.alignment, Yes.growDownwards)(1024 * 64));\n}\n\n@system nothrow @nogc unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    auto reg = Region!(Mallocator)(1024 * 64);\n    auto b = reg.allocate(101);\n    assert(b.length == 101);\n    assert((() pure nothrow @safe @nogc => reg.expand(b, 20))());\n    assert((() pure nothrow @safe @nogc => reg.expand(b, 73))());\n    assert((() pure nothrow @safe @nogc => !reg.expand(b, 1024 * 64))());\n    assert((() nothrow @nogc => reg.deallocateAll())());\n}\n\n/**\n\n`InSituRegion` is a convenient region that carries its storage within itself\n(in the form of a statically-sized array).\n\nThe first template argument is the size of the region and the second is the\nneeded alignment. Depending on the alignment requested and platform details,\nthe actual available storage may be smaller than the compile-time parameter. To\nmake sure that at least `n` bytes are available in the region, use\n$(D InSituRegion!(n + a - 1, a)).\n\nGiven that the most frequent use of `InSituRegion` is as a stack allocator, it\nallocates starting at the end on systems where stack grows downwards, such that\nhot memory is used first.\n\n*/\nstruct InSituRegion(size_t size, size_t minAlign = platformAlignment)\n{\n    import std.algorithm.comparison : max;\n    import std.conv : to;\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n\n    static assert(minAlign.isGoodStaticAlignment);\n    static assert(size >= minAlign);\n\n    version (X86) enum growDownwards = Yes.growDownwards;\n    else version (X86_64) enum growDownwards = Yes.growDownwards;\n    else version (ARM) enum growDownwards = Yes.growDownwards;\n    else version (AArch64) enum growDownwards = Yes.growDownwards;\n    else version (PPC) enum growDownwards = Yes.growDownwards;\n    else version (PPC64) enum growDownwards = Yes.growDownwards;\n    else version (MIPS32) enum growDownwards = Yes.growDownwards;\n    else version (MIPS64) enum growDownwards = Yes.growDownwards;\n    else version (SPARC) enum growDownwards = Yes.growDownwards;\n    else version (SystemZ) enum growDownwards = Yes.growDownwards;\n    else static assert(0, \"Dunno how the stack grows on this architecture.\");\n\n    @disable this(this);\n\n    // state {\n    private Region!(NullAllocator, minAlign, growDownwards) _impl;\n    union\n    {\n        private ubyte[size] _store = void;\n        private double _forAlignmentOnly1 = void;\n    }\n    // }\n\n    /**\n    An alias for `minAlign`, which must be a valid alignment (nonzero power\n    of 2). The start of the region and all allocation requests will be rounded\n    up to a multiple of the alignment.\n\n    ----\n    InSituRegion!(4096) a1;\n    assert(a1.alignment == platformAlignment);\n    InSituRegion!(4096, 64) a2;\n    assert(a2.alignment == 64);\n    ----\n    */\n    alias alignment = minAlign;\n\n    private void lazyInit()\n    {\n        assert(!_impl._current);\n        _impl = typeof(_impl)(_store);\n        assert(_impl._current.alignedAt(alignment));\n    }\n\n    /**\n    Allocates `bytes` and returns them, or `null` if the region cannot\n    accommodate the request. For efficiency reasons, if $(D bytes == 0) the\n    function returns an empty non-null slice.\n    */\n    void[] allocate(size_t n)\n    {\n        // Fast path\n    entry:\n        auto result = _impl.allocate(n);\n        if (result.length == n) return result;\n        // Slow path\n        if (_impl._current) return null; // no more room\n        lazyInit;\n        assert(_impl._current);\n        goto entry;\n    }\n\n    /**\n    As above, but the memory allocated is aligned at `a` bytes.\n    */\n    void[] alignedAllocate(size_t n, uint a)\n    {\n        // Fast path\n    entry:\n        auto result = _impl.alignedAllocate(n, a);\n        if (result.length == n) return result;\n        // Slow path\n        if (_impl._current) return null; // no more room\n        lazyInit;\n        assert(_impl._current);\n        goto entry;\n    }\n\n    /**\n    Deallocates `b`. This works only if `b` was obtained as the last call\n    to `allocate`; otherwise (i.e. another allocation has occurred since) it\n    does nothing. This semantics is tricky and therefore `deallocate` is\n    defined only if `Region` is instantiated with `Yes.defineDeallocate`\n    as the third template argument.\n\n    Params:\n        b = Block previously obtained by a call to `allocate` against this\n        allocator (`null` is allowed).\n    */\n    bool deallocate(void[] b)\n    {\n        if (!_impl._current) return b is null;\n        return _impl.deallocate(b);\n    }\n\n    /**\n    Returns `Ternary.yes` if `b` is the result of a previous allocation,\n    `Ternary.no` otherwise.\n    */\n    Ternary owns(const void[] b) pure nothrow @safe @nogc\n    {\n        if (!_impl._current) return Ternary.no;\n        return _impl.owns(b);\n    }\n\n    /**\n    Expands an allocated block in place. Expansion will succeed only if the\n    block is the last allocated.\n    */\n    static if (hasMember!(typeof(_impl), \"expand\"))\n    bool expand(ref void[] b, size_t delta)\n    {\n        if (!_impl._current) lazyInit;\n        return _impl.expand(b, delta);\n    }\n\n    /**\n    Deallocates all memory allocated with this allocator.\n    */\n    bool deallocateAll()\n    {\n        // We don't care to lazily init the region\n        return _impl.deallocateAll;\n    }\n\n    /**\n    Allocates all memory available with this allocator.\n    */\n    void[] allocateAll()\n    {\n        if (!_impl._current) lazyInit;\n        return _impl.allocateAll;\n    }\n\n    /**\n    Nonstandard function that returns the bytes available for allocation.\n    */\n    size_t available()\n    {\n        if (!_impl._current) lazyInit;\n        return _impl.available;\n    }\n}\n\n///\n@system unittest\n{\n    // 128KB region, allocated to x86's cache line\n    InSituRegion!(128 * 1024, 16) r1;\n    auto a1 = r1.allocate(101);\n    assert(a1.length == 101);\n\n    // 128KB region, with fallback to the garbage collector.\n    import std.experimental.allocator.building_blocks.fallback_allocator\n        : FallbackAllocator;\n    import std.experimental.allocator.building_blocks.free_list\n        : FreeList;\n    import std.experimental.allocator.building_blocks.bitmapped_block\n        : BitmappedBlock;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    FallbackAllocator!(InSituRegion!(128 * 1024), GCAllocator) r2;\n    const a2 = r2.allocate(102);\n    assert(a2.length == 102);\n\n    // Reap with GC fallback.\n    InSituRegion!(128 * 1024, 8) tmp3;\n    FallbackAllocator!(BitmappedBlock!(64, 8), GCAllocator) r3;\n    r3.primary = BitmappedBlock!(64, 8)(cast(ubyte[]) (tmp3.allocateAll()));\n    const a3 = r3.allocate(103);\n    assert(a3.length == 103);\n\n    // Reap/GC with a freelist for small objects up to 16 bytes.\n    InSituRegion!(128 * 1024, 64) tmp4;\n    FreeList!(FallbackAllocator!(BitmappedBlock!(64, 64), GCAllocator), 0, 16) r4;\n    r4.parent.primary = BitmappedBlock!(64, 64)(cast(ubyte[]) (tmp4.allocateAll()));\n    const a4 = r4.allocate(104);\n    assert(a4.length == 104);\n}\n\n@system pure nothrow unittest\n{\n    import std.typecons : Ternary;\n\n    InSituRegion!(4096, 1) r1;\n    auto a = r1.allocate(2001);\n    assert(a.length == 2001);\n    import std.conv : text;\n    assert(r1.available == 2095, text(r1.available));\n    // Ensure deallocate inherits from parent\n    assert((() nothrow @nogc => r1.deallocate(a))());\n    assert((() nothrow @nogc => r1.deallocateAll())());\n\n    InSituRegion!(65_536, 1024*4) r2;\n    assert(r2.available <= 65_536);\n    a = r2.allocate(2001);\n    assert(a.length == 2001);\n    const void[] buff = r2.allocate(42);\n    assert((() nothrow @safe @nogc => r2.owns(buff))() == Ternary.yes);\n    assert((() nothrow @nogc => r2.deallocateAll())());\n}\n\nversion (CRuntime_Musl)\n{\n    // sbrk and brk are disabled in Musl:\n    // https://git.musl-libc.org/cgit/musl/commit/?id=7a995fe706e519a4f55399776ef0df9596101f93\n    // https://git.musl-libc.org/cgit/musl/commit/?id=863d628d93ea341b6a32661a1654320ce69f6a07\n}\nelse\n{\n    private extern(C) void* sbrk(long) nothrow @nogc;\n    private extern(C) int brk(shared void*) nothrow @nogc;\n}\n\n/**\n\nAllocator backed by $(D $(LINK2 https://en.wikipedia.org/wiki/Sbrk, sbrk))\nfor Posix systems. Due to the fact that `sbrk` is not thread-safe\n$(HTTP lifecs.likai.org/2010/02/sbrk-is-not-thread-safe.html, by design),\n`SbrkRegion` uses a mutex internally. This implies\nthat uncontrolled calls to `brk` and `sbrk` may affect the workings of $(D\nSbrkRegion) adversely.\n\n*/\nversion (CRuntime_Musl) {} else\nversion (Posix) struct SbrkRegion(uint minAlign = platformAlignment)\n{\n    import core.sys.posix.pthread : pthread_mutex_init, pthread_mutex_destroy,\n        pthread_mutex_t, pthread_mutex_lock, pthread_mutex_unlock,\n        PTHREAD_MUTEX_INITIALIZER;\n    private static shared pthread_mutex_t sbrkMutex = PTHREAD_MUTEX_INITIALIZER;\n    import std.typecons : Ternary;\n\n    static assert(minAlign.isGoodStaticAlignment);\n    static assert(size_t.sizeof == (void*).sizeof);\n    private shared void* _brkInitial, _brkCurrent;\n\n    /**\n    Instance shared by all callers.\n    */\n    static shared SbrkRegion instance;\n\n    /**\n    Standard allocator primitives.\n    */\n    enum uint alignment = minAlign;\n\n    /**\n    Rounds the given size to a multiple of thew `alignment`\n    */\n    size_t goodAllocSize(size_t n) shared const pure nothrow @safe @nogc\n    {\n        return n.roundUpToMultipleOf(alignment);\n    }\n\n    /// Ditto\n    void[] allocate(size_t bytes) shared @trusted nothrow @nogc\n    {\n        // Take alignment rounding into account\n        const rounded = goodAllocSize(bytes);\n\n        pthread_mutex_lock(cast(pthread_mutex_t*) &sbrkMutex) == 0 || assert(0);\n        scope(exit) pthread_mutex_unlock(cast(pthread_mutex_t*) &sbrkMutex) == 0\n            || assert(0);\n        // Assume sbrk returns the old break. Most online documentation confirms\n        // that, except for http://www.inf.udec.cl/~leo/Malloc_tutorial.pdf,\n        // which claims the returned value is not portable.\n        auto p = sbrk(rounded);\n        if (p == cast(void*) -1)\n        {\n            return null;\n        }\n        if (!_brkInitial)\n        {\n            _brkInitial = cast(shared) p;\n            assert(cast(size_t) _brkInitial % minAlign == 0,\n                \"Too large alignment chosen for \" ~ typeof(this).stringof);\n        }\n        _brkCurrent = cast(shared) (p + rounded);\n        return p[0 .. bytes];\n    }\n\n    /// Ditto\n    void[] alignedAllocate(size_t bytes, uint a) shared @trusted nothrow @nogc\n    {\n        pthread_mutex_lock(cast(pthread_mutex_t*) &sbrkMutex) == 0 || assert(0);\n        scope(exit) pthread_mutex_unlock(cast(pthread_mutex_t*) &sbrkMutex) == 0\n            || assert(0);\n        if (!_brkInitial)\n        {\n            // This is one extra call, but it'll happen only once.\n            _brkInitial = cast(shared) sbrk(0);\n            assert(cast(size_t) _brkInitial % minAlign == 0,\n                \"Too large alignment chosen for \" ~ typeof(this).stringof);\n            (_brkInitial != cast(void*) -1) || assert(0);\n            _brkCurrent = _brkInitial;\n        }\n        immutable size_t delta = cast(shared void*) roundUpToMultipleOf(\n            cast(size_t) _brkCurrent, a) - _brkCurrent;\n        // Still must make sure the total size is aligned to the allocator's\n        // alignment.\n        immutable rounded = (bytes + delta).roundUpToMultipleOf(alignment);\n\n        auto p = sbrk(rounded);\n        if (p == cast(void*) -1)\n        {\n            return null;\n        }\n        _brkCurrent = cast(shared) (p + rounded);\n        return p[delta .. delta + bytes];\n    }\n\n    /**\n\n    The `expand` method may only succeed if the argument is the last block\n    allocated. In that case, `expand` attempts to push the break pointer to\n    the right.\n\n    */\n    bool expand(ref void[] b, size_t delta) shared nothrow @trusted @nogc\n    {\n        if (b is null || delta == 0) return delta == 0;\n        assert(_brkInitial && _brkCurrent); // otherwise where did b come from?\n        pthread_mutex_lock(cast(pthread_mutex_t*) &sbrkMutex) == 0 || assert(0);\n        scope(exit) pthread_mutex_unlock(cast(pthread_mutex_t*) &sbrkMutex) == 0\n            || assert(0);\n\n        // Take alignment rounding into account\n        const rounded = goodAllocSize(b.length);\n\n        const slack = rounded - b.length;\n        if (delta <= slack)\n        {\n            b = b.ptr[0 .. b.length + delta];\n            return true;\n        }\n\n        if (_brkCurrent != b.ptr + rounded) return false;\n        // Great, can expand the last block\n        delta -= slack;\n\n        const roundedDelta = goodAllocSize(delta);\n        auto p = sbrk(roundedDelta);\n        if (p == cast(void*) -1)\n        {\n            return false;\n        }\n        _brkCurrent = cast(shared) (p + roundedDelta);\n        b = b.ptr[0 .. b.length + slack + delta];\n        return true;\n    }\n\n    /// Ditto\n    Ternary owns(const void[] b) shared pure nothrow @trusted @nogc\n    {\n        // No need to lock here.\n        assert(!_brkCurrent || !b || &b[0] + b.length <= _brkCurrent);\n        return Ternary(_brkInitial && b && (&b[0] >= _brkInitial));\n    }\n\n    /**\n\n    The `deallocate` method only works (and returns `true`)  on systems\n    that support reducing the  break address (i.e. accept calls to `sbrk`\n    with negative offsets). OSX does not accept such. In addition the argument\n    must be the last block allocated.\n\n    */\n    bool deallocate(void[] b) shared nothrow @nogc\n    {\n        // Take alignment rounding into account\n        const rounded = goodAllocSize(b.length);\n        pthread_mutex_lock(cast(pthread_mutex_t*) &sbrkMutex) == 0 || assert(0);\n        scope(exit) pthread_mutex_unlock(cast(pthread_mutex_t*) &sbrkMutex) == 0\n            || assert(0);\n        if (_brkCurrent != b.ptr + rounded) return false;\n        assert(b.ptr >= _brkInitial);\n        if (sbrk(-rounded) == cast(void*) -1)\n            return false;\n        _brkCurrent = cast(shared) b.ptr;\n        return true;\n    }\n\n    /**\n    The `deallocateAll` method only works (and returns `true`) on systems\n    that support reducing the  break address (i.e. accept calls to `sbrk`\n    with negative offsets). OSX does not accept such.\n    */\n    nothrow @nogc\n    bool deallocateAll() shared\n    {\n        pthread_mutex_lock(cast(pthread_mutex_t*) &sbrkMutex) == 0 || assert(0);\n        scope(exit) pthread_mutex_unlock(cast(pthread_mutex_t*) &sbrkMutex) == 0\n            || assert(0);\n        return !_brkInitial || brk(_brkInitial) == 0;\n    }\n\n    /// Standard allocator API.\n    Ternary empty() shared pure nothrow @safe @nogc\n    {\n        // Also works when they're both null.\n        return Ternary(_brkCurrent == _brkInitial);\n    }\n}\n\nversion (CRuntime_Musl) {} else\nversion (Posix) @system nothrow @nogc unittest\n{\n    // Let's test the assumption that sbrk(n) returns the old address\n    const p1 = sbrk(0);\n    const p2 = sbrk(4096);\n    assert(p1 == p2);\n    const p3 = sbrk(0);\n    assert(p3 == p2 + 4096);\n    // Try to reset brk, but don't make a fuss if it doesn't work\n    sbrk(-4096);\n}\n\nversion (CRuntime_Musl) {} else\nversion (Posix) @system nothrow @nogc unittest\n{\n    import std.typecons : Ternary;\n    import std.algorithm.comparison : min;\n    alias alloc = SbrkRegion!(min(8, platformAlignment)).instance;\n    assert((() nothrow @safe @nogc => alloc.empty)() == Ternary.yes);\n    auto a = alloc.alignedAllocate(2001, 4096);\n    assert(a.length == 2001);\n    assert((() nothrow @safe @nogc => alloc.empty)() == Ternary.no);\n    auto oldBrkCurr = alloc._brkCurrent;\n    auto b = alloc.allocate(2001);\n    assert(b.length == 2001);\n    assert((() nothrow @safe @nogc => alloc.expand(b, 0))());\n    assert(b.length == 2001);\n    // Expand with a small size to fit the rounded slack due to alignment\n    assert((() nothrow @safe @nogc => alloc.expand(b, 1))());\n    assert(b.length == 2002);\n    // Exceed the rounded slack due to alignment\n    assert((() nothrow @safe @nogc => alloc.expand(b, 10))());\n    assert(b.length == 2012);\n    assert((() nothrow @safe @nogc => alloc.owns(a))() == Ternary.yes);\n    assert((() nothrow @safe @nogc => alloc.owns(b))() == Ternary.yes);\n    // reducing the brk does not work on OSX\n    version (OSX) {} else\n    {\n        assert((() nothrow @nogc => alloc.deallocate(b))());\n        // Check that expand and deallocate work well\n        assert(oldBrkCurr == alloc._brkCurrent);\n        assert((() nothrow @nogc => alloc.deallocate(a))());\n        assert((() nothrow @nogc => alloc.deallocateAll())());\n    }\n    const void[] c = alloc.allocate(2001);\n    assert(c.length == 2001);\n    assert((() nothrow @safe @nogc => alloc.owns(c))() == Ternary.yes);\n    assert((() nothrow @safe @nogc => alloc.owns(null))() == Ternary.no);\n}\n\n/**\nThe threadsafe version of the `Region` allocator.\nAllocations and deallocations are lock-free based using $(REF cas, core,atomic).\n*/\nshared struct SharedRegion(ParentAllocator = NullAllocator,\n    uint minAlign = platformAlignment,\n    Flag!\"growDownwards\" growDownwards = No.growDownwards)\n{\n    static assert(minAlign.isGoodStaticAlignment);\n    static assert(ParentAllocator.alignment >= minAlign);\n\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n\n    // state\n    /**\n    The _parent allocator. Depending on whether `ParentAllocator` holds state\n    or not, this is a member variable or an alias for\n    `ParentAllocator.instance`.\n    */\n    static if (stateSize!ParentAllocator)\n    {\n        ParentAllocator parent;\n    }\n    else\n    {\n        alias parent = ParentAllocator.instance;\n    }\n    private shared void* _current, _begin, _end;\n\n    private void* roundedBegin() const pure nothrow @trusted @nogc\n    {\n        return cast(void*) roundUpToAlignment(cast(size_t) _begin, alignment);\n    }\n\n    private void* roundedEnd() const pure nothrow @trusted @nogc\n    {\n        return cast(void*) roundDownToAlignment(cast(size_t) _end, alignment);\n    }\n\n\n    /**\n    Constructs a region backed by a user-provided store.\n    Assumes the memory was allocated with `ParentAllocator`\n    (if different from $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator)).\n\n    Params:\n        store = User-provided store backing up the region. If `ParentAllocator`\n        is different from $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator), memory is assumed to\n        have been allocated with `ParentAllocator`.\n        n = Bytes to allocate using `ParentAllocator`. This constructor is only\n        defined If `ParentAllocator` is different from $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator). If\n        `parent.allocate(n)` returns `null`, the region will be initialized\n        as empty (correctly initialized but unable to allocate).\n    */\n    this(ubyte[] store) pure nothrow @nogc\n    {\n        _begin = cast(typeof(_begin)) store.ptr;\n        _end = cast(typeof(_end)) (store.ptr + store.length);\n        static if (growDownwards)\n            _current = cast(typeof(_current)) roundedEnd();\n        else\n            _current = cast(typeof(_current)) roundedBegin();\n    }\n\n    /// Ditto\n    static if (!is(ParentAllocator == NullAllocator))\n    this(size_t n)\n    {\n        this(cast(ubyte[]) (parent.allocate(n.roundUpToAlignment(alignment))));\n    }\n\n    /**\n    Rounds the given size to a multiple of the `alignment`\n    */\n    size_t goodAllocSize(size_t n) const pure nothrow @safe @nogc\n    {\n        return n.roundUpToAlignment(alignment);\n    }\n\n    /**\n    Alignment offered.\n    */\n    alias alignment = minAlign;\n\n    /**\n    Allocates `n` bytes of memory. The allocation is served by atomically incrementing\n    a pointer which keeps track of the current used space.\n\n    Params:\n        n = number of bytes to allocate\n\n    Returns:\n        A properly-aligned buffer of size `n`, or `null` if request could not\n        be satisfied.\n    */\n    void[] allocate(size_t n) pure nothrow @trusted @nogc\n    {\n        import core.atomic : cas, atomicLoad;\n\n        if (n == 0) return null;\n        const rounded = goodAllocSize(n);\n\n        shared void* localCurrent, localNewCurrent;\n        static if (growDownwards)\n        {\n            do\n            {\n                localCurrent = atomicLoad(_current);\n                localNewCurrent = localCurrent - rounded;\n                if (localNewCurrent > localCurrent || localNewCurrent < _begin)\n                    return null;\n            } while (!cas(&_current, localCurrent, localNewCurrent));\n\n            return cast(void[]) localNewCurrent[0 .. n];\n        }\n        else\n        {\n            do\n            {\n                localCurrent = atomicLoad(_current);\n                localNewCurrent = localCurrent + rounded;\n                if (localNewCurrent < localCurrent || localNewCurrent > _end)\n                    return null;\n            } while (!cas(&_current, localCurrent, localNewCurrent));\n\n            return cast(void[]) localCurrent[0 .. n];\n        }\n\n        assert(0, \"Unexpected error in SharedRegion.allocate\");\n    }\n\n    /**\n    Deallocates `b`. This works only if `b` was obtained as the last call\n    to `allocate`; otherwise (i.e. another allocation has occurred since) it\n    does nothing.\n\n    Params:\n        b = Block previously obtained by a call to `allocate` against this\n        allocator (`null` is allowed).\n    */\n    bool deallocate(void[] b) pure nothrow @nogc\n    {\n        import core.atomic : cas, atomicLoad;\n\n        const rounded = goodAllocSize(b.length);\n        shared void* localCurrent, localNewCurrent;\n\n        // The cas is done only once, because only the last allocation can be reverted\n        localCurrent = atomicLoad(_current);\n        static if (growDownwards)\n        {\n            localNewCurrent = localCurrent + rounded;\n            if (b.ptr == localCurrent)\n                return cas(&_current, localCurrent, localNewCurrent);\n        }\n        else\n        {\n            localNewCurrent = localCurrent - rounded;\n            if (b.ptr == localNewCurrent)\n                return cas(&_current, localCurrent, localNewCurrent);\n        }\n\n        return false;\n    }\n\n    /**\n    Deallocates all memory allocated by this region, which can be subsequently\n    reused for new allocations.\n    */\n    bool deallocateAll() pure nothrow @nogc\n    {\n        import core.atomic : atomicStore;\n        static if (growDownwards)\n        {\n            atomicStore(_current, cast(shared(void*)) roundedEnd());\n        }\n        else\n        {\n            atomicStore(_current, cast(shared(void*)) roundedBegin());\n        }\n        return true;\n    }\n\n    /**\n    Allocates `n` bytes of memory aligned at alignment `a`.\n    Params:\n        n = number of bytes to allocate\n        a = alignment for the allocated block\n\n    Returns:\n        Either a suitable block of `n` bytes aligned at `a`, or `null`.\n    */\n    void[] alignedAllocate(size_t n, uint a) pure nothrow @trusted @nogc\n    {\n        import core.atomic : cas, atomicLoad;\n        import std.math : isPowerOf2;\n\n        assert(a.isPowerOf2);\n        if (n == 0) return null;\n\n        const rounded = goodAllocSize(n);\n        shared void* localCurrent, localNewCurrent;\n\n        static if (growDownwards)\n        {\n            do\n            {\n                localCurrent = atomicLoad(_current);\n                auto alignedCurrent = cast(void*)(localCurrent - rounded);\n                localNewCurrent = cast(shared(void*)) alignedCurrent.alignDownTo(a);\n                if (alignedCurrent > localCurrent || localNewCurrent > alignedCurrent ||\n                    localNewCurrent < _begin)\n                    return null;\n            } while (!cas(&_current, localCurrent, localNewCurrent));\n\n            return cast(void[]) localNewCurrent[0 .. n];\n        }\n        else\n        {\n            do\n            {\n                localCurrent = atomicLoad(_current);\n                auto alignedCurrent = alignUpTo(cast(void*) localCurrent, a);\n                localNewCurrent = cast(shared(void*)) (alignedCurrent + rounded);\n                if (alignedCurrent < localCurrent || localNewCurrent < alignedCurrent ||\n                    localNewCurrent > _end)\n                    return null;\n            } while (!cas(&_current, localCurrent, localNewCurrent));\n\n            return cast(void[]) (localNewCurrent - rounded)[0 .. n];\n        }\n\n        assert(0, \"Unexpected error in SharedRegion.alignedAllocate\");\n    }\n\n    /**\n    Queries whether `b` has been allocated with this region.\n\n    Params:\n        b = Arbitrary block of memory (`null` is allowed; `owns(null)` returns\n        `false`).\n\n    Returns:\n        `true` if `b` has been allocated with this region, `false` otherwise.\n    */\n    Ternary owns(const void[] b) const pure nothrow @trusted @nogc\n    {\n        return Ternary(b && (&b[0] >= _begin) && (&b[0] + b.length <= _end));\n    }\n\n    /**\n    Returns `Ternary.yes` if no memory has been allocated in this region,\n    `Ternary.no` otherwise. (Never returns `Ternary.unknown`.)\n    */\n    Ternary empty() const pure nothrow @safe @nogc\n    {\n        import core.atomic : atomicLoad;\n\n        auto localCurrent = atomicLoad(_current);\n        static if (growDownwards)\n            return Ternary(localCurrent == roundedEnd());\n        else\n            return Ternary(localCurrent == roundedBegin());\n    }\n\n    /**\n    If `ParentAllocator` is not $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator) and defines `deallocate`,\n    the region defines a destructor that uses `ParentAllocator.deallocate` to free the\n    memory chunk.\n    */\n    static if (!is(ParentAllocator == NullAllocator)\n        && hasMember!(ParentAllocator, \"deallocate\"))\n    ~this()\n    {\n        parent.deallocate(cast(void[]) _begin[0 .. _end - _begin]);\n    }\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    static void testAlloc(Allocator)(ref Allocator a, bool growDownwards)\n    {\n        import core.thread : ThreadGroup;\n        import std.algorithm.sorting : sort;\n        import core.internal.spinlock : SpinLock;\n\n        SpinLock lock = SpinLock(SpinLock.Contention.brief);\n        enum numThreads = 100;\n        void[][numThreads] buf;\n        size_t count = 0;\n\n        void fun()\n        {\n            void[] b = a.allocate(63);\n            assert(b.length == 63);\n\n            lock.lock();\n            buf[count] = b;\n            count++;\n            lock.unlock();\n        }\n\n        auto tg = new ThreadGroup;\n        foreach (i; 0 .. numThreads)\n        {\n            tg.create(&fun);\n        }\n        tg.joinAll();\n\n        sort!((a, b) => a.ptr < b.ptr)(buf[0 .. numThreads]);\n        foreach (i; 0 .. numThreads - 1)\n        {\n            assert(buf[i].ptr + a.goodAllocSize(buf[i].length) == buf[i + 1].ptr);\n        }\n\n        assert(!a.deallocate(buf[1]));\n\n        foreach (i; 0 .. numThreads)\n        {\n            if (!growDownwards)\n                assert(a.deallocate(buf[numThreads - 1 - i]));\n            else\n                assert(a.deallocate(buf[i]));\n        }\n\n        assert(a.deallocateAll());\n        void[] b = a.allocate(63);\n        assert(b.length == 63);\n        assert(a.deallocate(b));\n    }\n\n    auto a1 = SharedRegion!(Mallocator, Mallocator.alignment,\n        Yes.growDownwards)(1024 * 64);\n\n    auto a2 = SharedRegion!(Mallocator, Mallocator.alignment,\n        No.growDownwards)(1024 * 64);\n\n    testAlloc(a1, true);\n    testAlloc(a2, false);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    static void testAlloc(Allocator)(ref Allocator a, bool growDownwards)\n    {\n        import core.thread : ThreadGroup;\n        import std.algorithm.sorting : sort;\n        import core.internal.spinlock : SpinLock;\n\n        SpinLock lock = SpinLock(SpinLock.Contention.brief);\n        enum numThreads = 100;\n        void[][2 * numThreads] buf;\n        size_t count = 0;\n\n        void fun()\n        {\n            void[] b = a.allocate(63);\n            assert(b.length == 63);\n\n            lock.lock();\n            buf[count] = b;\n            count++;\n            lock.unlock();\n\n            b = a.alignedAllocate(63, 32);\n            assert(b.length == 63);\n            assert(cast(size_t) b.ptr % 32 == 0);\n\n            lock.lock();\n            buf[count] = b;\n            count++;\n            lock.unlock();\n        }\n\n        auto tg = new ThreadGroup;\n        foreach (i; 0 .. numThreads)\n        {\n            tg.create(&fun);\n        }\n        tg.joinAll();\n\n        sort!((a, b) => a.ptr < b.ptr)(buf[0 .. 2 * numThreads]);\n        foreach (i; 0 .. 2 * numThreads - 1)\n        {\n            assert(buf[i].ptr + buf[i].length <= buf[i + 1].ptr);\n        }\n\n        assert(!a.deallocate(buf[1]));\n        assert(a.deallocateAll());\n\n        void[] b = a.allocate(13);\n        assert(b.length == 13);\n        assert(a.deallocate(b));\n    }\n\n    auto a1 = SharedRegion!(Mallocator, Mallocator.alignment,\n        Yes.growDownwards)(1024 * 64);\n\n    auto a2 = SharedRegion!(Mallocator, Mallocator.alignment,\n        No.growDownwards)(1024 * 64);\n\n    testAlloc(a1, true);\n    testAlloc(a2, false);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/scoped_allocator.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/scoped_allocator.d)\n*/\nmodule std.experimental.allocator.building_blocks.scoped_allocator;\n\nimport std.experimental.allocator.common;\n\n/**\n\n`ScopedAllocator` delegates all allocation requests to `ParentAllocator`.\nWhen destroyed, the `ScopedAllocator` object automatically calls $(D\ndeallocate) for all memory allocated through its lifetime. (The $(D\ndeallocateAll) function is also implemented with the same semantics.)\n\n`deallocate` is also supported, which is where most implementation effort\nand overhead of `ScopedAllocator` go. If `deallocate` is not needed, a\nsimpler design combining `AllocatorList` with `Region` is recommended.\n\n*/\nstruct ScopedAllocator(ParentAllocator)\n{\n    static if (!stateSize!ParentAllocator)\n    {\n        // This test is available only for stateless allocators\n        @system unittest\n        {\n            testAllocator!(() => ScopedAllocator());\n        }\n    }\n\n    import std.experimental.allocator.building_blocks.affix_allocator\n        : AffixAllocator;\n    import std.traits : hasMember;\n    import std.typecons : Ternary;\n\n    private struct Node\n    {\n        Node* prev;\n        Node* next;\n        size_t length;\n    }\n\n    alias Allocator = AffixAllocator!(ParentAllocator, Node);\n\n    // state\n    /**\n    If `ParentAllocator` is stateful, `parent` is a property giving access\n    to an `AffixAllocator!ParentAllocator`. Otherwise, `parent` is an alias for `AffixAllocator!ParentAllocator.instance`.\n    */\n    static if (stateSize!ParentAllocator)\n    {\n        Allocator parent;\n    }\n    else\n    {\n        alias parent = Allocator.instance;\n    }\n    private Node* root;\n\n    /**\n    `ScopedAllocator` is not copyable.\n    */\n    @disable this(this);\n\n    /**\n    `ScopedAllocator`'s destructor releases all memory allocated during its\n    lifetime.\n    */\n    ~this()\n    {\n        deallocateAll;\n    }\n\n    /// Alignment offered\n    enum alignment = Allocator.alignment;\n\n    /**\n    Forwards to `parent.goodAllocSize` (which accounts for the management\n    overhead).\n    */\n    size_t goodAllocSize(size_t n)\n    {\n        return parent.goodAllocSize(n);\n    }\n\n    // Common code shared between allocate and allocateZeroed.\n    private enum _processAndReturnAllocateResult =\n    q{\n       if (!b.ptr) return b;\n        Node* toInsert = & parent.prefix(b);\n        toInsert.prev = null;\n        toInsert.next = root;\n        toInsert.length = n;\n        assert(!root || !root.prev);\n        if (root) root.prev = toInsert;\n        root = toInsert;\n        return b;\n    };\n\n    /**\n    Allocates memory. For management it actually allocates extra memory from\n    the parent.\n    */\n    void[] allocate(size_t n)\n    {\n        auto b = parent.allocate(n);\n        mixin(_processAndReturnAllocateResult);\n    }\n\n    static if (hasMember!(Allocator, \"allocateZeroed\"))\n    package(std) void[] allocateZeroed()(size_t n)\n    {\n        auto b = parent.allocateZeroed(n);\n        mixin(_processAndReturnAllocateResult);\n    }\n\n    /**\n    Forwards to $(D parent.expand(b, delta)).\n    */\n    static if (hasMember!(Allocator, \"expand\"))\n    bool expand(ref void[] b, size_t delta)\n    {\n        auto result = parent.expand(b, delta);\n        if (result && b)\n        {\n            () @trusted { parent.prefix(b).length = b.length; }();\n        }\n        return result;\n    }\n\n    /**\n    Reallocates `b` to new size `s`.\n    */\n    bool reallocate(ref void[] b, size_t s)\n    {\n        // Remove from list\n        if (b.ptr)\n        {\n            Node* n = & parent.prefix(b);\n            if (n.prev) n.prev.next = n.next;\n            else root = n.next;\n            if (n.next) n.next.prev = n.prev;\n        }\n        auto result = parent.reallocate(b, s);\n        // Add back to list\n        if (b.ptr)\n        {\n            Node* n = & parent.prefix(b);\n            n.prev = null;\n            n.next = root;\n            n.length = s;\n            if (root) root.prev = n;\n            root = n;\n        }\n        return result;\n    }\n\n    /**\n    Forwards to `parent.owns(b)`.\n    */\n    static if (hasMember!(Allocator, \"owns\"))\n    Ternary owns(void[] b)\n    {\n        return parent.owns(b);\n    }\n\n    /**\n    Deallocates `b`.\n    */\n    static if (hasMember!(Allocator, \"deallocate\"))\n    bool deallocate(void[] b)\n    {\n        // Remove from list\n        if (b.ptr)\n        {\n            Node* n = & parent.prefix(b);\n            if (n.prev) n.prev.next = n.next;\n            else root = n.next;\n            if (n.next) n.next.prev = n.prev;\n        }\n        return parent.deallocate(b);\n    }\n\n    /**\n    Deallocates all memory allocated.\n    */\n    bool deallocateAll()\n    {\n        bool result = true;\n        for (auto n = root; n; )\n        {\n            void* p = n + 1;\n            auto length = n.length;\n            n = n.next;\n            if (!parent.deallocate(p[0 .. length]))\n                result = false;\n        }\n        root = null;\n        return result;\n    }\n\n    /**\n    Returns `Ternary.yes` if this allocator is not responsible for any memory,\n    `Ternary.no` otherwise. (Never returns `Ternary.unknown`.)\n    */\n    pure nothrow @safe @nogc\n    Ternary empty() const\n    {\n        return Ternary(root is null);\n    }\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Ternary;\n    ScopedAllocator!Mallocator alloc;\n    assert(alloc.empty == Ternary.yes);\n    const b = alloc.allocate(10);\n    assert(b.length == 10);\n    assert(alloc.empty == Ternary.no);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    testAllocator!(() => ScopedAllocator!GCAllocator());\n}\n\n@system unittest // https://issues.dlang.org/show_bug.cgi?id=16046\n{\n    import std.exception;\n    import std.experimental.allocator;\n    import std.experimental.allocator.mallocator;\n    ScopedAllocator!Mallocator alloc;\n    auto foo = alloc.make!int(1).enforce;\n    auto bar = alloc.make!int(2).enforce;\n    alloc.dispose(foo);\n    alloc.dispose(bar); // segfault here\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    ScopedAllocator!GCAllocator a;\n\n    assert(__traits(compiles, (() nothrow @safe @nogc => a.goodAllocSize(0))()));\n\n    // Ensure deallocate inherits from parent allocators\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    () nothrow @nogc { a.deallocate(b); }();\n}\n\n// Test that deallocateAll infers from parent\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n\n    ScopedAllocator!(Region!()) a;\n    a.parent.parent = Region!()(new ubyte[1024 * 64]);\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    assert((() pure nothrow @safe @nogc => a.expand(b, 22))());\n    assert(b.length == 64);\n    assert((() nothrow @nogc => a.reallocate(b, 100))());\n    assert(b.length == 100);\n    assert((() nothrow @nogc => a.deallocateAll())());\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Ternary;\n\n    auto a = Region!(Mallocator)(1024 * 64);\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    assert((() pure nothrow @safe @nogc => a.expand(b, 22))());\n    assert(b.length == 64);\n    assert((() pure nothrow @safe @nogc => a.owns(b))() == Ternary.yes);\n    assert((() nothrow @nogc => a.reallocate(b, 100))());\n    assert(b.length == 100);\n    assert((() pure nothrow @safe @nogc => a.owns(b))() == Ternary.yes);\n    assert((() pure nothrow @safe @nogc => a.owns(null))() == Ternary.no);\n}\n\n// Test empty\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.typecons : Ternary;\n    ScopedAllocator!Mallocator alloc;\n\n    assert((() pure nothrow @safe @nogc => alloc.empty)() == Ternary.yes);\n    const b = alloc.allocate(10);\n    assert((() pure nothrow @safe @nogc => alloc.empty)() == Ternary.no);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/segregator.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/segregator.d)\n*/\nmodule std.experimental.allocator.building_blocks.segregator;\n\nimport std.experimental.allocator.common;\n\n/**\nDispatches allocations (and deallocations) between two allocators ($(D\nSmallAllocator) and `LargeAllocator`) depending on the size allocated, as\nfollows. All allocations smaller than or equal to `threshold` will be\ndispatched to `SmallAllocator`. The others will go to `LargeAllocator`.\n\nIf both allocators are `shared`, the `Segregator` will also offer $(D\nshared) methods.\n*/\nstruct Segregator(size_t threshold, SmallAllocator, LargeAllocator)\n{\n    import std.algorithm.comparison : min;\n    import std.traits : hasMember, ReturnType;\n    import std.typecons : Ternary;\n\n    static if (stateSize!SmallAllocator) private SmallAllocator _small;\n    else private alias _small = SmallAllocator.instance;\n    static if (stateSize!LargeAllocator) private LargeAllocator _large;\n    else private alias _large = LargeAllocator.instance;\n\n    version (StdDdoc)\n    {\n        /**\n        The alignment offered is the minimum of the two allocators' alignment.\n        */\n        enum uint alignment;\n        /**\n        This method is defined only if at least one of the allocators defines\n        it. The good allocation size is obtained from `SmallAllocator` if $(D\n        s <= threshold), or `LargeAllocator` otherwise. (If one of the\n        allocators does not define `goodAllocSize`, the default\n        implementation in this module applies.)\n        */\n        static size_t goodAllocSize(size_t s);\n        /**\n        The memory is obtained from `SmallAllocator` if $(D s <= threshold),\n        or `LargeAllocator` otherwise.\n        */\n        void[] allocate(size_t);\n        /**\n        This method is defined if both allocators define it, and forwards to\n        `SmallAllocator` or `LargeAllocator` appropriately.\n        */\n        void[] alignedAllocate(size_t, uint);\n        /**\n        This method is defined only if at least one of the allocators defines\n        it. If `SmallAllocator` defines `expand` and $(D b.length +\n        delta <= threshold), the call is forwarded to `SmallAllocator`. If $(D\n        LargeAllocator) defines `expand` and $(D b.length > threshold), the\n        call is forwarded to `LargeAllocator`. Otherwise, the call returns\n        `false`.\n        */\n        bool expand(ref void[] b, size_t delta);\n        /**\n        This method is defined only if at least one of the allocators defines\n        it. If `SmallAllocator` defines `reallocate` and $(D b.length <=\n        threshold && s <= threshold), the call is forwarded to $(D\n        SmallAllocator). If `LargeAllocator` defines `expand` and $(D\n        b.length > threshold && s > threshold), the call is forwarded to $(D\n        LargeAllocator). Otherwise, the call returns `false`.\n        */\n        bool reallocate(ref void[] b, size_t s);\n        /**\n        This method is defined only if at least one of the allocators defines\n        it, and work similarly to `reallocate`.\n        */\n        bool alignedReallocate(ref void[] b, size_t s, uint a);\n        /**\n        This method is defined only if both allocators define it. The call is\n        forwarded to `SmallAllocator` if $(D b.length <= threshold), or $(D\n        LargeAllocator) otherwise.\n        */\n        Ternary owns(void[] b);\n        /**\n        This function is defined only if both allocators define it, and forwards\n        appropriately depending on `b.length`.\n        */\n        bool deallocate(void[] b);\n        /**\n        This function is defined only if both allocators define it, and calls\n        `deallocateAll` for them in turn.\n        */\n        bool deallocateAll();\n        /**\n        This function is defined only if both allocators define it, and returns\n        the conjunction of `empty` calls for the two.\n        */\n        Ternary empty();\n    }\n\n    /**\n    Composite allocators involving nested instantiations of `Segregator` make\n    it difficult to access individual sub-allocators stored within. $(D\n    allocatorForSize) simplifies the task by supplying the allocator nested\n    inside a `Segregator` that is responsible for a specific size `s`.\n\n    Example:\n    ----\n    alias A = Segregator!(300,\n        Segregator!(200, A1, A2),\n        A3);\n    A a;\n    static assert(typeof(a.allocatorForSize!10) == A1);\n    static assert(typeof(a.allocatorForSize!250) == A2);\n    static assert(typeof(a.allocatorForSize!301) == A3);\n    ----\n    */\n    ref auto allocatorForSize(size_t s)()\n    {\n        static if (s <= threshold)\n            static if (is(SmallAllocator == Segregator!(Args), Args...))\n                return _small.allocatorForSize!s;\n            else return _small;\n        else\n            static if (is(LargeAllocator == Segregator!(Args), Args...))\n                return _large.allocatorForSize!s;\n            else return _large;\n    }\n\n    enum uint alignment = min(SmallAllocator.alignment,\n        LargeAllocator.alignment);\n\n    private template Impl()\n    {\n        size_t goodAllocSize(size_t s)\n        {\n            return s <= threshold\n                ? _small.goodAllocSize(s)\n                : _large.goodAllocSize(s);\n        }\n\n        void[] allocate(size_t s)\n        {\n            return s <= threshold ? _small.allocate(s) : _large.allocate(s);\n        }\n\n        static if (hasMember!(SmallAllocator, \"alignedAllocate\")\n                && hasMember!(LargeAllocator, \"alignedAllocate\"))\n        void[] alignedAllocate(size_t s, uint a)\n        {\n            return s <= threshold\n                ? _small.alignedAllocate(s, a)\n                : _large.alignedAllocate(s, a);\n        }\n\n        static if (hasMember!(SmallAllocator, \"expand\")\n                || hasMember!(LargeAllocator, \"expand\"))\n        bool expand(ref void[] b, size_t delta)\n        {\n            if (!delta) return true;\n            if (b.length + delta <= threshold)\n            {\n                // Old and new allocations handled by _small\n                static if (hasMember!(SmallAllocator, \"expand\"))\n                    return _small.expand(b, delta);\n                else\n                    return false;\n            }\n            if (b.length > threshold)\n            {\n                // Old and new allocations handled by _large\n                static if (hasMember!(LargeAllocator, \"expand\"))\n                    return _large.expand(b, delta);\n                else\n                    return false;\n            }\n            // Oops, cross-allocator transgression\n            return false;\n        }\n\n        static if (hasMember!(SmallAllocator, \"reallocate\")\n                || hasMember!(LargeAllocator, \"reallocate\"))\n        bool reallocate(ref void[] b, size_t s)\n        {\n            static if (hasMember!(SmallAllocator, \"reallocate\"))\n                if (b.length <= threshold && s <= threshold)\n                {\n                    // Old and new allocations handled by _small\n                    return _small.reallocate(b, s);\n                }\n            static if (hasMember!(LargeAllocator, \"reallocate\"))\n                if (b.length > threshold && s > threshold)\n                {\n                    // Old and new allocations handled by _large\n                    return _large.reallocate(b, s);\n                }\n            // Cross-allocator transgression\n            return .reallocate(this, b, s);\n        }\n\n        static if (hasMember!(SmallAllocator, \"alignedReallocate\")\n                || hasMember!(LargeAllocator, \"alignedReallocate\"))\n        bool alignedReallocate(ref void[] b, size_t s, uint a)\n        {\n            static if (hasMember!(SmallAllocator, \"alignedReallocate\"))\n                if (b.length <= threshold && s <= threshold)\n                {\n                    // Old and new allocations handled by _small\n                    return _small.alignedReallocate(b, s, a);\n                }\n            static if (hasMember!(LargeAllocator, \"alignedReallocate\"))\n                if (b.length > threshold && s > threshold)\n                {\n                    // Old and new allocations handled by _large\n                    return _large.alignedReallocate(b, s, a);\n                }\n            // Cross-allocator transgression\n            return .alignedReallocate(this, b, s, a);\n        }\n\n        static if (hasMember!(SmallAllocator, \"allocateZeroed\")\n                || hasMember!(LargeAllocator, \"allocateZeroed\"))\n        package(std) void[] allocateZeroed()(size_t s)\n        {\n            if (s <= threshold)\n            {\n                static if (hasMember!(SmallAllocator, \"allocateZeroed\"))\n                    return _small.allocateZeroed(s);\n                else\n                {\n                    auto b = _small.allocate(s);\n                    (() @trusted => (cast(ubyte[]) b)[] = 0)(); // OK even if b is null.\n                    return b;\n                }\n            }\n            else\n            {\n                static if (hasMember!(LargeAllocator, \"allocateZeroed\"))\n                    return _large.allocateZeroed(s);\n                else\n                {\n                    auto b = _large.allocate(s);\n                    (() @trusted => (cast(ubyte[]) b)[] = 0)(); // OK even if b is null.\n                    return b;\n                }\n            }\n        }\n\n        static if (hasMember!(SmallAllocator, \"owns\")\n                && hasMember!(LargeAllocator, \"owns\"))\n        Ternary owns(void[] b)\n        {\n            return Ternary(b.length <= threshold\n                ? _small.owns(b) : _large.owns(b));\n        }\n\n        static if (hasMember!(SmallAllocator, \"deallocate\")\n                && hasMember!(LargeAllocator, \"deallocate\"))\n        bool deallocate(void[] data)\n        {\n            return data.length <= threshold\n                ? _small.deallocate(data)\n                : _large.deallocate(data);\n        }\n\n        static if (hasMember!(SmallAllocator, \"deallocateAll\")\n                && hasMember!(LargeAllocator, \"deallocateAll\"))\n        bool deallocateAll()\n        {\n            // Use & insted of && to evaluate both\n            return _small.deallocateAll() & _large.deallocateAll();\n        }\n\n        static if (hasMember!(SmallAllocator, \"empty\")\n                && hasMember!(LargeAllocator, \"empty\"))\n        Ternary empty()\n        {\n            return _small.empty & _large.empty;\n        }\n\n        static if (hasMember!(SmallAllocator, \"resolveInternalPointer\")\n                && hasMember!(LargeAllocator, \"resolveInternalPointer\"))\n        Ternary resolveInternalPointer(const void* p, ref void[] result)\n        {\n            Ternary r = _small.resolveInternalPointer(p, result);\n            return r == Ternary.no ? _large.resolveInternalPointer(p, result) : r;\n        }\n    }\n\n    private enum sharedMethods =\n        !stateSize!SmallAllocator\n        && !stateSize!LargeAllocator\n        && is(typeof(SmallAllocator.instance) == shared)\n        && is(typeof(LargeAllocator.instance) == shared);\n\n    static if (sharedMethods)\n    {\n        static shared Segregator instance;\n        shared { mixin Impl!(); }\n    }\n    else\n    {\n        static if (!stateSize!SmallAllocator && !stateSize!LargeAllocator)\n            __gshared Segregator instance;\n        mixin Impl!();\n    }\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n    alias A =\n        Segregator!(\n            1024 * 4,\n            Segregator!(\n                128, FreeList!(Mallocator, 0, 128),\n                GCAllocator),\n            Segregator!(\n                1024 * 1024, Mallocator,\n                GCAllocator)\n            );\n    A a;\n    auto b = a.allocate(200);\n    assert(b.length == 200);\n    a.deallocate(b);\n}\n\n/**\nA `Segregator` with more than three arguments expands to a composition of\nelemental `Segregator`s, as illustrated by the following example:\n\n----\nalias A =\n    Segregator!(\n        n1, A1,\n        n2, A2,\n        n3, A3,\n        A4\n    );\n----\n\nWith this definition, allocation requests for `n1` bytes or less are directed\nto `A1`; requests between $(D n1 + 1) and `n2` bytes (inclusive) are\ndirected to `A2`; requests between $(D n2 + 1) and `n3` bytes (inclusive)\nare directed to `A3`; and requests for more than `n3` bytes are directed\nto `A4`. If some particular range should not be handled, `NullAllocator`\nmay be used appropriately.\n\n*/\ntemplate Segregator(Args...)\nif (Args.length > 3)\n{\n    // Binary search\n    private enum cutPoint = ((Args.length - 2) / 4) * 2;\n    static if (cutPoint >= 2)\n    {\n        alias Segregator = .Segregator!(\n            Args[cutPoint],\n            .Segregator!(Args[0 .. cutPoint], Args[cutPoint + 1]),\n            .Segregator!(Args[cutPoint + 2 .. $])\n        );\n    }\n    else\n    {\n        // Favor small sizes\n        alias Segregator = .Segregator!(\n            Args[0],\n            Args[1],\n            .Segregator!(Args[2 .. $])\n        );\n    }\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n    alias A =\n        Segregator!(\n            128, FreeList!(Mallocator, 0, 128),\n            1024 * 4, GCAllocator,\n            1024 * 1024, Mallocator,\n            GCAllocator\n        );\n    A a;\n    auto b = a.allocate(201);\n    assert(b.length == 201);\n    a.deallocate(b);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.building_blocks.kernighan_ritchie : KRRegion;\n    Segregator!(128, GCAllocator, KRRegion!GCAllocator) alloc;\n    assert((() nothrow @safe @nogc => alloc.goodAllocSize(1))()\n            == GCAllocator.instance.goodAllocSize(1));\n\n    // Note: we infer `shared` from GCAllocator.goodAllocSize so we need a\n    // shared object in order to be able to use the function\n    shared Segregator!(128, GCAllocator, GCAllocator) sharedAlloc;\n    assert((() nothrow @safe @nogc => sharedAlloc.goodAllocSize(1))()\n            == GCAllocator.instance.goodAllocSize(1));\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlock;\n    import std.typecons : Ternary;\n\n    alias A =\n        Segregator!(\n            128, BitmappedBlock!(4096),\n            BitmappedBlock!(4096)\n        );\n\n    A a = A(\n            BitmappedBlock!(4096)(new ubyte[4096 * 1024]),\n            BitmappedBlock!(4096)(new ubyte[4096 * 1024])\n    );\n\n    assert(a.empty == Ternary.yes);\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    assert(a.empty == Ternary.no);\n    assert(a.alignedReallocate(b, 256, 512));\n    assert(b.length == 256);\n    assert(a.alignedReallocate(b, 42, 512));\n    assert(b.length == 42);\n    assert((() pure nothrow @safe @nogc => a.owns(b))() == Ternary.yes);\n    assert((() pure nothrow @safe @nogc => a.owns(null))() == Ternary.no);\n    // Ensure deallocate inherits from parent allocators\n    assert((() nothrow @nogc => a.deallocate(b))());\n    assert(a.empty == Ternary.yes);\n\n    // Test that deallocateAll inherits from parents\n    auto c = a.allocate(42);\n    assert(c.length == 42);\n    assert((() pure nothrow @safe @nogc => a.expand(c, 58))());\n    assert(c.length == 100);\n    assert(a.empty == Ternary.no);\n    assert((() nothrow @nogc => a.deallocateAll())());\n    assert(a.empty == Ternary.yes);\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.typecons : Ternary;\n\n    shared Segregator!(1024 * 4, GCAllocator, GCAllocator) a;\n\n    auto b = a.allocate(201);\n    assert(b.length == 201);\n\n    void[] p;\n    assert((() nothrow @safe @nogc => a.resolveInternalPointer(&b[0], p))() == Ternary.yes);\n    assert((() nothrow @safe @nogc => a.resolveInternalPointer(null, p))() == Ternary.no);\n\n    // Ensure deallocate inherits from parent allocators\n    assert((() nothrow @nogc => a.deallocate(b))());\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlockWithInternalPointers;\n    import std.typecons : Ternary;\n\n    alias A =\n        Segregator!(\n            10_240, BitmappedBlockWithInternalPointers!(4096),\n            BitmappedBlockWithInternalPointers!(4096)\n        );\n\n    A a = A(\n            BitmappedBlockWithInternalPointers!(4096)(new ubyte[4096 * 1024]),\n            BitmappedBlockWithInternalPointers!(4096)(new ubyte[4096 * 1024])\n    );\n\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.yes);\n    auto b = a.allocate(201);\n    assert(b.length == 201);\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.no);\n    assert((() nothrow @nogc => a.deallocate(b))());\n}\n\n// Test that reallocate infers from parent\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    alias a = Segregator!(10_240, Mallocator, Mallocator).instance;\n\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    assert((() nothrow @nogc => a.reallocate(b, 100))());\n    assert(b.length == 100);\n    assert((() nothrow @nogc => a.deallocate(b))());\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.typecons : Ternary;\n\n    auto a = Segregator!(10_240, Region!(), Region!())(\n                Region!()(new ubyte[4096 * 1024]),\n                Region!()(new ubyte[4096 * 1024]));\n\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.yes);\n    auto b = a.alignedAllocate(42, 8);\n    assert(b.length == 42);\n    assert((() nothrow @nogc => a.alignedReallocate(b, 100, 8))());\n    assert(b.length == 100);\n    assert((() nothrow @safe @nogc => a.empty)() == Ternary.no);\n    assert((() nothrow @nogc => a.deallocate(b))());\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/building_blocks/stats_collector.d",
    "content": "// Written in the D programming language.\n/**\nAllocator that collects useful statistics about allocations, both global and per\ncalling point. The statistics collected can be configured statically by choosing\ncombinations of `Options` appropriately.\n\nSource: $(PHOBOSSRC std/experimental/allocator/building_blocks/stats_collector.d)\n*/\nmodule std.experimental.allocator.building_blocks.stats_collector;\n\n///\n@safe unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    alias Allocator = StatsCollector!(GCAllocator, Options.bytesUsed);\n}\n\nimport std.experimental.allocator.common;\n\n/**\n_Options for `StatsCollector` defined below. Each enables during\ncompilation one specific counter, statistic, or other piece of information.\n*/\nenum Options : ulong\n{\n    /**\n    Counts the number of calls to `owns`.\n    */\n    numOwns = 1u << 0,\n    /**\n    Counts the number of calls to `allocate`. All calls are counted,\n    including requests for zero bytes or failed requests.\n    */\n    numAllocate = 1u << 1,\n    /**\n    Counts the number of calls to `allocate` that succeeded, i.e. they\n    returned a block as large as requested. (N.B. requests for zero bytes count\n    as successful.)\n    */\n    numAllocateOK = 1u << 2,\n    /**\n    Counts the number of calls to `expand`, regardless of arguments or\n    result.\n    */\n    numExpand = 1u << 3,\n    /**\n    Counts the number of calls to `expand` that resulted in a successful\n    expansion.\n    */\n    numExpandOK = 1u << 4,\n    /**\n    Counts the number of calls to `reallocate`, regardless of arguments or\n    result.\n    */\n    numReallocate = 1u << 5,\n    /**\n    Counts the number of calls to `reallocate` that succeeded.\n    (Reallocations to zero bytes count as successful.)\n    */\n    numReallocateOK = 1u << 6,\n    /**\n    Counts the number of calls to `reallocate` that resulted in an in-place\n    reallocation (no memory moved). If this number is close to the total number\n    of reallocations, that indicates the allocator finds room at the current\n    block's end in a large fraction of the cases, but also that internal\n    fragmentation may be high (the size of the unit of allocation is large\n    compared to the typical allocation size of the application).\n    */\n    numReallocateInPlace = 1u << 7,\n    /**\n    Counts the number of calls to `deallocate`.\n    */\n    numDeallocate = 1u << 8,\n    /**\n    Counts the number of calls to `deallocateAll`.\n    */\n    numDeallocateAll = 1u << 9,\n    /**\n    Counts the number of calls to `alignedAllocate`. All calls are counted,\n    including requests for zero bytes or failed requests.\n    */\n    numAlignedAllocate = 1u << 10,\n    /**\n    Counts the number of calls to `alignedAllocate` that succeeded, i.e. they\n    returned a block as large as requested. (N.B. requests for zero bytes count\n    as successful.)\n    */\n    numAlignedAllocateOk = 1u << 11,\n    /**\n    Chooses all `numXxx` flags.\n    */\n    numAll = (1u << 12) - 1,\n    /**\n    Tracks bytes currently allocated by this allocator. This number goes up\n    and down as memory is allocated and deallocated, and is zero if the\n    allocator currently has no active allocation.\n    */\n    bytesUsed = 1u << 12,\n    /**\n    Tracks total cumulative bytes allocated by means of `allocate`,\n    `expand`, and `reallocate` (when resulting in an expansion). This\n    number always grows and indicates allocation traffic. To compute bytes\n    deallocated cumulatively, subtract `bytesUsed` from `bytesAllocated`.\n    */\n    bytesAllocated = 1u << 13,\n    /**\n    Tracks the sum of all `delta` values in calls of the form\n    $(D expand(b, delta)) that succeed (return `true`).\n    */\n    bytesExpanded = 1u << 14,\n    /**\n    Tracks the sum of all $(D b.length - s) with $(D b.length > s) in calls of\n    the form $(D realloc(b, s)) that succeed (return `true`). In per-call\n    statistics, also unambiguously counts the bytes deallocated with\n    `deallocate`.\n    */\n    bytesContracted = 1u << 15,\n    /**\n    Tracks the sum of all bytes moved as a result of calls to `realloc` that\n    were unable to reallocate in place. A large number (relative to $(D\n    bytesAllocated)) indicates that the application should use larger\n    preallocations.\n    */\n    bytesMoved = 1u << 16,\n    /**\n    Tracks the sum of all bytes NOT moved as result of calls to `realloc`\n    that managed to reallocate in place. A large number (relative to $(D\n    bytesAllocated)) indicates that the application is expansion-intensive and\n    is saving a good amount of moves. However, if this number is relatively\n    small and `bytesSlack` is high, it means the application is\n    overallocating for little benefit.\n    */\n    bytesNotMoved = 1u << 17,\n    /**\n    Measures the sum of extra bytes allocated beyond the bytes requested, i.e.\n    the $(HTTP goo.gl/YoKffF, internal fragmentation). This is the current\n    effective number of slack bytes, and it goes up and down with time.\n    */\n    bytesSlack = 1u << 18,\n    /**\n    Measures the maximum bytes allocated over the time. This is useful for\n    dimensioning allocators.\n    */\n    bytesHighTide = 1u << 19,\n    /**\n    Chooses all `byteXxx` flags.\n    */\n    bytesAll = ((1u << 20) - 1) & ~numAll,\n    /**\n    Combines all flags above.\n    */\n    all = (1u << 20) - 1\n}\n\n/**\n\nAllocator that collects extra data about allocations. Since each piece of\ninformation adds size and time overhead, statistics can be individually enabled\nor disabled through compile-time `flags`.\n\nAll stats of the form `numXxx` record counts of events occurring, such as\ncalls to functions and specific results. The stats of the form `bytesXxx`\ncollect cumulative sizes.\n\nIn addition, the data `callerSize`, `callerModule`, `callerFile`, $(D\ncallerLine), and `callerTime` is associated with each specific allocation.\nThis data prefixes each allocation.\n\n*/\nstruct StatsCollector(Allocator, ulong flags = Options.all,\n    ulong perCallFlags = 0)\n{\nprivate:\n    import std.traits : hasMember, Signed;\n    import std.typecons : Ternary;\n\n    static string define(string type, string[] names...)\n    {\n        string result;\n        foreach (v; names)\n            result ~= \"static if (flags & Options.\"~v~\") {\"\n                ~ \"private \"~type~\" _\"~v~\";\"\n                ~ \"public const(\"~type~\") \"~v~\"() const { return _\"~v~\"; }\"\n                ~ \"}\";\n        return result;\n    }\n\n    void add(string counter)(Signed!size_t n)\n    {\n        mixin(\"static if (flags & Options.\" ~ counter\n            ~ \") _\" ~ counter ~ \" += n;\");\n        static if (counter == \"bytesUsed\" && (flags & Options.bytesHighTide))\n        {\n            if (bytesHighTide < bytesUsed ) _bytesHighTide = bytesUsed;\n        }\n    }\n\n    void up(string counter)() { add!counter(1); }\n    void down(string counter)() { add!counter(-1); }\n\n    version (StdDdoc)\n    {\n        /**\n        Read-only properties enabled by the homonym `flags` chosen by the\n        user.\n\n        Example:\n        ----\n        StatsCollector!(Mallocator,\n            Options.bytesUsed | Options.bytesAllocated) a;\n        auto d1 = a.allocate(10);\n        auto d2 = a.allocate(11);\n        a.deallocate(d1);\n        assert(a.bytesAllocated == 21);\n        assert(a.bytesUsed == 11);\n        a.deallocate(d2);\n        assert(a.bytesAllocated == 21);\n        assert(a.bytesUsed == 0);\n        ----\n        */\n        @property ulong numOwns() const;\n        /// Ditto\n        @property ulong numAllocate() const;\n        /// Ditto\n        @property ulong numAllocateOK() const;\n        /// Ditto\n        @property ulong numExpand() const;\n        /// Ditto\n        @property ulong numExpandOK() const;\n        /// Ditto\n        @property ulong numReallocate() const;\n        /// Ditto\n        @property ulong numReallocateOK() const;\n        /// Ditto\n        @property ulong numReallocateInPlace() const;\n        /// Ditto\n        @property ulong numDeallocate() const;\n        /// Ditto\n        @property ulong numDeallocateAll() const;\n        /// Ditto\n        @property ulong numAlignedAllocate() const;\n        /// Ditto\n        @property ulong numAlignedAllocateOk() const;\n        /// Ditto\n        @property ulong bytesUsed() const;\n        /// Ditto\n        @property ulong bytesAllocated() const;\n        /// Ditto\n        @property ulong bytesExpanded() const;\n        /// Ditto\n        @property ulong bytesContracted() const;\n        /// Ditto\n        @property ulong bytesMoved() const;\n        /// Ditto\n        @property ulong bytesNotMoved() const;\n        /// Ditto\n        @property ulong bytesSlack() const;\n        /// Ditto\n        @property ulong bytesHighTide() const;\n    }\n\npublic:\n    /**\n    The parent allocator is publicly accessible either as a direct member if it\n    holds state, or as an alias to `Allocator.instance` otherwise. One may use\n    it for making calls that won't count toward statistics collection.\n    */\n    static if (stateSize!Allocator) Allocator parent;\n    else alias parent = Allocator.instance;\n\nprivate:\n    // Per-allocator state\n    mixin(define(\"ulong\",\n        \"numOwns\",\n        \"numAllocate\",\n        \"numAllocateOK\",\n        \"numExpand\",\n        \"numExpandOK\",\n        \"numReallocate\",\n        \"numReallocateOK\",\n        \"numReallocateInPlace\",\n        \"numDeallocate\",\n        \"numDeallocateAll\",\n        \"numAlignedAllocate\",\n        \"numAlignedAllocateOk\",\n        \"bytesUsed\",\n        \"bytesAllocated\",\n        \"bytesExpanded\",\n        \"bytesContracted\",\n        \"bytesMoved\",\n        \"bytesNotMoved\",\n        \"bytesSlack\",\n        \"bytesHighTide\",\n    ));\n\npublic:\n\n    /// Alignment offered is equal to `Allocator.alignment`.\n    alias alignment = Allocator.alignment;\n\n    /**\n    Increments `numOwns` (per instance and and per call) and forwards to $(D\n    parent.owns(b)).\n    */\n    static if (hasMember!(Allocator, \"owns\"))\n    {\n        static if ((perCallFlags & Options.numOwns) == 0)\n        Ternary owns(void[] b)\n        { return ownsImpl(b); }\n        else\n        Ternary owns(string f = __FILE__, uint n = __LINE__)(void[] b)\n        { return ownsImpl!(f, n)(b); }\n    }\n\n    private Ternary ownsImpl(string f = null, uint n = 0)(void[] b)\n    {\n        up!\"numOwns\";\n        addPerCall!(f, n, \"numOwns\")(1);\n        return parent.owns(b);\n    }\n\n    /**\n    Forwards to `parent.allocate`. Affects per instance: `numAllocate`,\n    `bytesUsed`, `bytesAllocated`, `bytesSlack`, `numAllocateOK`,\n    and `bytesHighTide`. Affects per call: `numAllocate`, $(D\n    numAllocateOK), and `bytesAllocated`.\n    */\n    static if (!(perCallFlags\n        & (Options.numAllocate | Options.numAllocateOK\n            | Options.bytesAllocated)))\n    {\n        void[] allocate(size_t n)\n        { return allocateImpl(n); }\n    }\n    else\n    {\n        void[] allocate(string f = __FILE__, ulong n = __LINE__)\n            (size_t bytes)\n        { return allocateImpl!(f, n)(bytes); }\n    }\n\n    // Common code currently shared between allocateImpl and allocateZeroedImpl.\n    private enum _updateStatsForAllocateResult =\n    q{\n        add!\"bytesUsed\"(result.length);\n        add!\"bytesAllocated\"(result.length);\n        immutable slack = this.goodAllocSize(result.length) - result.length;\n        add!\"bytesSlack\"(slack);\n        up!\"numAllocate\";\n        add!\"numAllocateOK\"(result.length == bytes); // allocating 0 bytes is OK\n        addPerCall!(f, n, \"numAllocate\", \"numAllocateOK\", \"bytesAllocated\")\n            (1, result.length == bytes, result.length);\n    };\n\n    private void[] allocateImpl(string f = null, ulong n = 0)(size_t bytes)\n    {\n        auto result = parent.allocate(bytes);\n        mixin(_updateStatsForAllocateResult);\n        return result;\n    }\n\n    static if (hasMember!(Allocator, \"allocateZeroed\"))\n    {\n        static if (!(perCallFlags\n            & (Options.numAllocate | Options.numAllocateOK\n                | Options.bytesAllocated)))\n        {\n            package(std) void[] allocateZeroed()(size_t n)\n            { return allocateZeroedImpl(n); }\n        }\n        else\n        {\n            package(std) void[] allocateZeroed(string f = __FILE__, ulong n = __LINE__)\n                (size_t bytes)\n            { return allocateZeroedImpl!(f, n)(bytes); }\n        }\n\n        private void[] allocateZeroedImpl(string f = null, ulong n = 0)(size_t bytes)\n        {\n            auto result = parent.allocateZeroed(bytes);\n            // Note: calls to `allocateZeroed` are counted for statistical purposes\n            // as if they were calls to `allocate`. If/when `allocateZeroed` is made\n            // public it might be of interest to count such calls separately.\n            mixin(_updateStatsForAllocateResult);\n            return result;\n        }\n    }\n\n    /**\n    Forwards to `parent.alignedAllocate`. Affects per instance: `numAlignedAllocate`,\n    `bytesUsed`, `bytesAllocated`, `bytesSlack`, `numAlignedAllocateOk`,\n    and `bytesHighTide`. Affects per call: `numAlignedAllocate`, `numAlignedAllocateOk`,\n    and `bytesAllocated`.\n    */\n    static if (!(perCallFlags\n        & (Options.numAlignedAllocate | Options.numAlignedAllocateOk\n            | Options.bytesAllocated)))\n    {\n        void[] alignedAllocate(size_t n, uint a)\n        { return alignedAllocateImpl(n, a); }\n    }\n    else\n    {\n        void[] alignedAllocate(string f = __FILE__, ulong n = __LINE__)\n            (size_t bytes, uint a)\n        { return alignedAllocateImpl!(f, n)(bytes, a); }\n    }\n\n    private void[] alignedAllocateImpl(string f = null, ulong n = 0)(size_t bytes, uint a)\n    {\n        up!\"numAlignedAllocate\";\n        static if (!hasMember!(Allocator, \"alignedAllocate\"))\n        {\n            if (bytes == 0)\n                up!\"numAlignedAllocateOk\";\n            void[] result = null;\n        }\n        else\n        {\n            auto result = parent.alignedAllocate(bytes, a);\n            add!\"bytesUsed\"(result.length);\n            add!\"bytesAllocated\"(result.length);\n            immutable slack = this.goodAllocSize(result.length) - result.length;\n            add!\"bytesSlack\"(slack);\n            add!\"numAlignedAllocateOk\"(result.length == bytes); // allocating 0 bytes is OK\n        }\n        addPerCall!(f, n, \"numAlignedAllocate\", \"numAlignedAllocateOk\", \"bytesAllocated\")\n            (1, result.length == bytes, result.length);\n\n        return result;\n    }\n\n    /**\n    Defined whether or not `Allocator.expand` is defined. Affects\n    per instance: `numExpand`, `numExpandOK`, `bytesExpanded`,\n    `bytesSlack`, `bytesAllocated`, and `bytesUsed`. Affects per call:\n    `numExpand`, `numExpandOK`, `bytesExpanded`, and\n    `bytesAllocated`.\n    */\n    static if (!(perCallFlags\n        & (Options.numExpand | Options.numExpandOK | Options.bytesExpanded)))\n    {\n        bool expand(ref void[] b, size_t delta)\n        { return expandImpl(b, delta); }\n    }\n    else\n    {\n        bool expand(string f = __FILE__, uint n = __LINE__)\n            (ref void[] b, size_t delta)\n        { return expandImpl!(f, n)(b, delta); }\n    }\n\n    private bool expandImpl(string f = null, uint n = 0)(ref void[] b, size_t s)\n    {\n        up!\"numExpand\";\n        Signed!size_t slack = 0;\n        static if (!hasMember!(Allocator, \"expand\"))\n        {\n            auto result = s == 0;\n        }\n        else\n        {\n            immutable bytesSlackB4 = this.goodAllocSize(b.length) - b.length;\n            auto result = parent.expand(b, s);\n            if (result)\n            {\n                up!\"numExpandOK\";\n                add!\"bytesUsed\"(s);\n                add!\"bytesAllocated\"(s);\n                add!\"bytesExpanded\"(s);\n                slack = Signed!size_t(this.goodAllocSize(b.length) - b.length\n                    - bytesSlackB4);\n                add!\"bytesSlack\"(slack);\n            }\n        }\n        immutable xtra = result ? s : 0;\n        addPerCall!(f, n, \"numExpand\", \"numExpandOK\", \"bytesExpanded\",\n            \"bytesAllocated\")\n            (1, result, xtra, xtra);\n        return result;\n    }\n\n    /**\n    Defined whether or not `Allocator.reallocate` is defined. Affects\n    per instance: `numReallocate`, `numReallocateOK`, $(D\n    numReallocateInPlace), `bytesNotMoved`, `bytesAllocated`, $(D\n    bytesSlack), `bytesExpanded`, and `bytesContracted`. Affects per call:\n    `numReallocate`, `numReallocateOK`, `numReallocateInPlace`,\n    `bytesNotMoved`, `bytesExpanded`, `bytesContracted`, and\n    `bytesMoved`.\n    */\n    static if (!(perCallFlags\n        & (Options.numReallocate | Options.numReallocateOK\n            | Options.numReallocateInPlace | Options.bytesNotMoved\n            | Options.bytesExpanded | Options.bytesContracted\n            | Options.bytesMoved)))\n    {\n        bool reallocate(ref void[] b, size_t s)\n        { return reallocateImpl(b, s); }\n    }\n    else\n    {\n        bool reallocate(string f = __FILE__, ulong n = __LINE__)\n            (ref void[] b, size_t s)\n        { return reallocateImpl!(f, n)(b, s); }\n    }\n\n    private bool reallocateImpl(string f = null, uint n = 0)\n        (ref void[] b, size_t s)\n    {\n        up!\"numReallocate\";\n        const bytesSlackB4 = this.goodAllocSize(b.length) - b.length;\n        const oldB = b.ptr;\n        const oldLength = b.length;\n\n        const result = parent.reallocate(b, s);\n\n        Signed!size_t slack = 0;\n        bool wasInPlace = false;\n        Signed!size_t delta = 0;\n\n        if (result)\n        {\n            up!\"numReallocateOK\";\n            slack = (this.goodAllocSize(b.length) - b.length) - bytesSlackB4;\n            add!\"bytesSlack\"(slack);\n            add!\"bytesUsed\"(Signed!size_t(b.length - oldLength));\n            if (oldB == b.ptr)\n            {\n                // This was an in-place reallocation, yay\n                wasInPlace = true;\n                up!\"numReallocateInPlace\";\n                add!\"bytesNotMoved\"(oldLength);\n                delta = b.length - oldLength;\n                if (delta >= 0)\n                {\n                    // Expansion\n                    add!\"bytesAllocated\"(delta);\n                    add!\"bytesExpanded\"(delta);\n                }\n                else\n                {\n                    // Contraction\n                    add!\"bytesContracted\"(-delta);\n                }\n            }\n            else\n            {\n                // This was a allocate-move-deallocate cycle\n                add!\"bytesAllocated\"(b.length);\n                add!\"bytesMoved\"(oldLength);\n            }\n        }\n        addPerCall!(f, n, \"numReallocate\", \"numReallocateOK\",\n            \"numReallocateInPlace\", \"bytesNotMoved\",\n            \"bytesExpanded\", \"bytesContracted\", \"bytesMoved\")\n            (1, result, wasInPlace, wasInPlace ? oldLength : 0,\n                delta >= 0 ? delta : 0, delta < 0 ? -delta : 0,\n                wasInPlace ? 0 : oldLength);\n        return result;\n    }\n\n    /**\n    Defined whether or not `Allocator.deallocate` is defined. Affects\n    per instance: `numDeallocate`, `bytesUsed`, and `bytesSlack`.\n    Affects per call: `numDeallocate` and `bytesContracted`.\n    */\n    static if (!(perCallFlags &\n            (Options.numDeallocate | Options.bytesContracted)))\n        bool deallocate(void[] b)\n        { return deallocateImpl(b); }\n    else\n        bool deallocate(string f = __FILE__, uint n = __LINE__)(void[] b)\n        { return deallocateImpl!(f, n)(b); }\n\n    private bool deallocateImpl(string f = null, uint n = 0)(void[] b)\n    {\n        up!\"numDeallocate\";\n        add!\"bytesUsed\"(-Signed!size_t(b.length));\n        add!\"bytesSlack\"(-(this.goodAllocSize(b.length) - b.length));\n        addPerCall!(f, n, \"numDeallocate\", \"bytesContracted\")(1, b.length);\n        static if (hasMember!(Allocator, \"deallocate\"))\n            return parent.deallocate(b);\n        else\n            return false;\n    }\n\n    static if (hasMember!(Allocator, \"deallocateAll\"))\n    {\n        /**\n        Defined only if `Allocator.deallocateAll` is defined. Affects\n        per instance and per call `numDeallocateAll`.\n        */\n        static if (!(perCallFlags & Options.numDeallocateAll))\n            bool deallocateAll()\n            { return deallocateAllImpl(); }\n        else\n            bool deallocateAll(string f = __FILE__, uint n = __LINE__)()\n            { return deallocateAllImpl!(f, n)(); }\n\n        private bool deallocateAllImpl(string f = null, uint n = 0)()\n        {\n            up!\"numDeallocateAll\";\n            addPerCall!(f, n, \"numDeallocateAll\")(1);\n            static if ((flags & Options.bytesUsed))\n                _bytesUsed = 0;\n            return parent.deallocateAll();\n        }\n    }\n\n    /**\n    Defined only if `Options.bytesUsed` is defined. Returns $(D bytesUsed ==\n    0).\n    */\n    static if (flags & Options.bytesUsed)\n    pure nothrow @safe @nogc\n    Ternary empty()\n    {\n        return Ternary(_bytesUsed == 0);\n    }\n\n    /**\n    Reports per instance statistics to `output` (e.g. `stdout`). The\n    format is simple: one kind and value per line, separated by a colon, e.g.\n    `bytesAllocated:7395404`\n    */\n    void reportStatistics(R)(auto ref R output)\n    {\n        import std.conv : to;\n        import std.traits : EnumMembers;\n        foreach (e; EnumMembers!Options)\n        {\n            static if ((flags & e) && e != Options.numAll\n                    && e != Options.bytesAll && e != Options.all)\n                output.write(e.to!string, \":\", mixin(e.to!string), '\\n');\n        }\n    }\n\n    static if (perCallFlags)\n    {\n        /**\n        Defined if `perCallFlags` is nonzero.\n        */\n        struct PerCallStatistics\n        {\n            /// The file and line of the call.\n            string file;\n            /// Ditto\n            uint line;\n            /// The options corresponding to the statistics collected.\n            Options[] opts;\n            /// The values of the statistics. Has the same length as `opts`.\n            ulong[] values;\n            // Next in the chain.\n            private PerCallStatistics* next;\n\n            /**\n            Format to a string such as:\n            $(D mymodule.d(655): [numAllocate:21, numAllocateOK:21, bytesAllocated:324202]).\n            */\n            string toString() const\n            {\n                import std.conv : text, to;\n                auto result = text(file, \"(\", line, \"): [\");\n                foreach (i, opt; opts)\n                {\n                    if (i) result ~= \", \";\n                    result ~= opt.to!string;\n                    result ~= ':';\n                    result ~= values[i].to!string;\n                }\n                return result ~= \"]\";\n            }\n        }\n        private static PerCallStatistics* root;\n\n        /**\n        Defined if `perCallFlags` is nonzero. Iterates all monitored\n        file/line instances. The order of iteration is not meaningful (items\n        are inserted at the front of a list upon the first call), so\n        preprocessing the statistics after collection might be appropriate.\n        */\n        static auto byFileLine()\n        {\n            static struct Voldemort\n            {\n                PerCallStatistics* current;\n                bool empty() { return !current; }\n                ref PerCallStatistics front() { return *current; }\n                void popFront() { current = current.next; }\n                auto save() { return this; }\n            }\n            return Voldemort(root);\n        }\n\n        /**\n        Defined if `perCallFlags` is nonzero. Outputs (e.g. to a `File`)\n        a simple report of the collected per-call statistics.\n        */\n        static void reportPerCallStatistics(R)(auto ref R output)\n        {\n            output.write(\"Stats for: \", StatsCollector.stringof, '\\n');\n            foreach (ref stat; byFileLine)\n            {\n                output.write(stat, '\\n');\n            }\n        }\n\n        private PerCallStatistics* statsAt(string f, uint n, opts...)()\n        {\n            import std.array : array;\n            import std.range : repeat;\n\n            static PerCallStatistics s = { f, n, [ opts ],\n                repeat(0UL, opts.length).array };\n            static bool inserted;\n\n            if (!inserted)\n            {\n                // Insert as root\n                s.next = root;\n                root = &s;\n                inserted = true;\n            }\n            return &s;\n        }\n\n        private void addPerCall(string f, uint n, names...)(ulong[] values...)\n        {\n            import std.array : join;\n            enum uint mask = mixin(\"Options.\"~[names].join(\"|Options.\"));\n            static if (perCallFlags & mask)\n            {\n                // Per allocation info\n                auto ps = mixin(\"statsAt!(f, n,\"\n                    ~ \"Options.\"~[names].join(\", Options.\")\n                ~\")\");\n                foreach (i; 0 .. names.length)\n                {\n                    ps.values[i] += values[i];\n                }\n            }\n        }\n    }\n    else\n    {\n        private void addPerCall(string f, uint n, names...)(ulong[]...)\n        {\n        }\n    }\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    alias Allocator = StatsCollector!(GCAllocator, Options.all, Options.all);\n\n    Allocator alloc;\n    auto b = alloc.allocate(10);\n    alloc.reallocate(b, 20);\n    alloc.deallocate(b);\n\n    import std.file : deleteme, remove;\n    import std.range : walkLength;\n    import std.stdio : File;\n\n    auto f = deleteme ~ \"-dlang.std.experimental.allocator.stats_collector.txt\";\n    scope(exit) remove(f);\n    Allocator.reportPerCallStatistics(File(f, \"w\"));\n    alloc.reportStatistics(File(f, \"a\"));\n    assert(File(f).byLine.walkLength == 24);\n}\n\n@system unittest\n{\n    void test(Allocator)()\n    {\n        import std.range : walkLength;\n        import std.typecons : Ternary;\n\n        Allocator a;\n        assert((() pure nothrow @safe @nogc => a.empty)() == Ternary.yes);\n        auto b1 = a.allocate(100);\n        assert(a.numAllocate == 1);\n        assert((() nothrow @safe => a.expand(b1, 0))());\n        assert(a.reallocate(b1, b1.length + 1));\n        auto b2 = a.allocate(101);\n        assert(a.numAllocate == 2);\n        assert(a.bytesAllocated == 202);\n        assert(a.bytesUsed == 202);\n        auto b3 = a.allocate(202);\n        assert(a.numAllocate == 3);\n        assert(a.bytesAllocated == 404);\n        assert((() pure nothrow @safe @nogc => a.empty)() == Ternary.no);\n\n        () nothrow @nogc { a.deallocate(b2); }();\n        assert(a.numDeallocate == 1);\n        () nothrow @nogc { a.deallocate(b1); }();\n        assert(a.numDeallocate == 2);\n        () nothrow @nogc { a.deallocate(b3); }();\n        assert(a.numDeallocate == 3);\n        assert(a.numAllocate == a.numDeallocate);\n        assert(a.bytesUsed == 0);\n     }\n\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    test!(StatsCollector!(GCAllocator, Options.all, Options.all));\n    test!(StatsCollector!(FreeList!(GCAllocator, 128), Options.all,\n        Options.all));\n}\n\n@system unittest\n{\n    void test(Allocator)()\n    {\n        import std.range : walkLength;\n        Allocator a;\n        auto b1 = a.allocate(100);\n        assert((() nothrow @safe => a.expand(b1, 0))());\n        assert(a.reallocate(b1, b1.length + 1));\n        auto b2 = a.allocate(101);\n        auto b3 = a.allocate(202);\n\n        () nothrow @nogc { a.deallocate(b2); }();\n        () nothrow @nogc { a.deallocate(b1); }();\n        () nothrow @nogc { a.deallocate(b3); }();\n    }\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    test!(StatsCollector!(GCAllocator, 0, 0));\n}\n\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    StatsCollector!(GCAllocator, 0, 0) a;\n\n    // calls std.experimental.allocator.common.goodAllocSize\n    assert((() pure nothrow @safe @nogc => a.goodAllocSize(1))());\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n\n    auto a = StatsCollector!(Region!(), Options.all, Options.all)(Region!()(new ubyte[1024 * 64]));\n    auto b = a.allocate(42);\n    assert(b.length == 42);\n    // Test that reallocate infers from parent\n    assert((() nothrow @nogc => a.reallocate(b, 100))());\n    assert(b.length == 100);\n    // Test that deallocateAll infers from parent\n    assert((() nothrow @nogc => a.deallocateAll())());\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n\n    auto a = StatsCollector!(Region!(), Options.all)(Region!()(new ubyte[1024 * 64]));\n    auto b = a.alignedAllocate(42, 128);\n    assert(b.length == 42);\n    assert(b.ptr.alignedAt(128));\n    assert(a.numAlignedAllocate == 1);\n    assert(a.numAlignedAllocateOk == 1);\n    assert(a.bytesUsed == 42);\n\n    b = a.alignedAllocate(23, 256);\n    assert(b.length == 23);\n    assert(b.ptr.alignedAt(256));\n    assert(a.numAlignedAllocate == 2);\n    assert(a.numAlignedAllocateOk == 2);\n    assert(a.bytesUsed == 65);\n\n    b = a.alignedAllocate(0, 512);\n    assert(b.length == 0);\n    assert(a.numAlignedAllocate == 3);\n    assert(a.numAlignedAllocateOk == 3);\n    assert(a.bytesUsed == 65);\n\n    b = a.alignedAllocate(1024 * 1024, 512);\n    assert(b is null);\n    assert(a.numAlignedAllocate == 4);\n    assert(a.numAlignedAllocateOk == 3);\n    assert(a.bytesUsed == 65);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/common.d",
    "content": "// Written in the D programming language.\n/**\nUtility and ancillary artifacts of `std.experimental.allocator`. This module\nshouldn't be used directly; its functionality will be migrated into more\nappropriate parts of `std`.\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu), Timon Gehr (`Ternary`)\n\nSource: $(PHOBOSSRC std/experimental/allocator/common.d)\n*/\nmodule std.experimental.allocator.common;\nimport std.algorithm.comparison, std.traits;\n\n/**\nReturns the size in bytes of the state that needs to be allocated to hold an\nobject of type `T`. `stateSize!T` is zero for `struct`s that are not\nnested and have no nonstatic member variables.\n */\ntemplate stateSize(T)\n{\n    static if (is(T == class) || is(T == interface))\n        enum stateSize = __traits(classInstanceSize, T);\n    else static if (is(T == struct) || is(T == union))\n        enum stateSize = Fields!T.length || isNested!T ? T.sizeof : 0;\n    else static if (is(T == void))\n        enum size_t stateSize = 0;\n    else\n        enum stateSize = T.sizeof;\n}\n\n@safe @nogc nothrow pure\nunittest\n{\n    static assert(stateSize!void == 0);\n    struct A {}\n    static assert(stateSize!A == 0);\n    struct B { int x; }\n    static assert(stateSize!B == 4);\n    interface I1 {}\n    //static assert(stateSize!I1 == 2 * size_t.sizeof);\n    class C1 {}\n    static assert(stateSize!C1 == 3 * size_t.sizeof);\n    class C2 { char c; }\n    static assert(stateSize!C2 == 4 * size_t.sizeof);\n    static class C3 { char c; }\n    static assert(stateSize!C3 == 2 * size_t.sizeof + char.sizeof);\n}\n\n/**\nReturns `true` if the `Allocator` has the alignment known at compile time;\notherwise it returns `false`.\n */\ntemplate hasStaticallyKnownAlignment(Allocator)\n{\n    enum hasStaticallyKnownAlignment = __traits(compiles,\n                                                {enum x = Allocator.alignment;});\n}\n\n/**\n`chooseAtRuntime` is a compile-time constant of type `size_t` that several\nparameterized structures in this module recognize to mean deferral to runtime of\nthe exact value. For example, $(D BitmappedBlock!(Allocator, 4096)) (described in\ndetail below) defines a block allocator with block size of 4096 bytes, whereas\n$(D BitmappedBlock!(Allocator, chooseAtRuntime)) defines a block allocator that has a\nfield storing the block size, initialized by the user.\n*/\nenum chooseAtRuntime = size_t.max - 1;\n\n/**\n`unbounded` is a compile-time constant of type `size_t` that several\nparameterized structures in this module recognize to mean \"infinite\" bounds for\nthe parameter. For example, `Freelist` (described in detail below) accepts a\n`maxNodes` parameter limiting the number of freelist items. If `unbounded`\nis passed for `maxNodes`, then there is no limit and no checking for the\nnumber of nodes.\n*/\nenum unbounded = size_t.max;\n\n/**\nThe alignment that is guaranteed to accommodate any D object allocation on the\ncurrent platform.\n*/\nenum uint platformAlignment = std.algorithm.comparison.max(double.alignof, real.alignof);\n\n/**\nThe default good size allocation is deduced as `n` rounded up to the\nallocator's alignment.\n*/\nsize_t goodAllocSize(A)(auto ref A a, size_t n)\n{\n    return n.roundUpToMultipleOf(a.alignment);\n}\n\n/*\nReturns s rounded up to a multiple of base.\n*/\n@safe @nogc nothrow pure\npackage size_t roundUpToMultipleOf(size_t s, uint base)\n{\n    assert(base);\n    auto rem = s % base;\n    return rem ? s + base - rem : s;\n}\n\n@safe @nogc nothrow pure\nunittest\n{\n    assert(10.roundUpToMultipleOf(11) == 11);\n    assert(11.roundUpToMultipleOf(11) == 11);\n    assert(12.roundUpToMultipleOf(11) == 22);\n    assert(118.roundUpToMultipleOf(11) == 121);\n}\n\n/*\nReturns `n` rounded up to a multiple of alignment, which must be a power of 2.\n*/\n@safe @nogc nothrow pure\npackage size_t roundUpToAlignment(size_t n, uint alignment)\n{\n    import std.math : isPowerOf2;\n    assert(alignment.isPowerOf2);\n    immutable uint slack = cast(uint) n & (alignment - 1);\n    const result = slack\n        ? n + alignment - slack\n        : n;\n    assert(result >= n);\n    return result;\n}\n\n@safe @nogc nothrow pure\nunittest\n{\n    assert(10.roundUpToAlignment(4) == 12);\n    assert(11.roundUpToAlignment(2) == 12);\n    assert(12.roundUpToAlignment(8) == 16);\n    assert(118.roundUpToAlignment(64) == 128);\n}\n\n/*\nReturns `n` rounded down to a multiple of alignment, which must be a power of 2.\n*/\n@safe @nogc nothrow pure\npackage size_t roundDownToAlignment(size_t n, uint alignment)\n{\n    import std.math : isPowerOf2;\n    assert(alignment.isPowerOf2);\n    return n & ~size_t(alignment - 1);\n}\n\n@safe @nogc nothrow pure\nunittest\n{\n    assert(10.roundDownToAlignment(4) == 8);\n    assert(11.roundDownToAlignment(2) == 10);\n    assert(12.roundDownToAlignment(8) == 8);\n    assert(63.roundDownToAlignment(64) == 0);\n}\n\n/*\nAdvances the beginning of `b` to start at alignment `a`. The resulting buffer\nmay therefore be shorter. Returns the adjusted buffer, or null if obtaining a\nnon-empty buffer is impossible.\n*/\n@nogc nothrow pure\npackage void[] roundUpToAlignment(void[] b, uint a)\n{\n    auto e = b.ptr + b.length;\n    auto p = cast(void*) roundUpToAlignment(cast(size_t) b.ptr, a);\n    if (e <= p) return null;\n    return p[0 .. e - p];\n}\n\n@nogc nothrow pure\n@system unittest\n{\n    void[] empty;\n    assert(roundUpToAlignment(empty, 4) == null);\n    char[128] buf;\n    // At least one pointer inside buf is 128-aligned\n    assert(roundUpToAlignment(buf, 128) !is null);\n}\n\n/*\nLike `a / b` but rounds the result up, not down.\n*/\n@safe @nogc nothrow pure\npackage size_t divideRoundUp(size_t a, size_t b)\n{\n    assert(b);\n    return (a + b - 1) / b;\n}\n\n/*\nReturns `s` rounded up to a multiple of `base`.\n*/\n@nogc nothrow pure\npackage void[] roundStartToMultipleOf(void[] s, uint base)\n{\n    assert(base);\n    auto p = cast(void*) roundUpToMultipleOf(\n        cast(size_t) s.ptr, base);\n    auto end = s.ptr + s.length;\n    return p[0 .. end - p];\n}\n\nnothrow pure\n@system unittest\n{\n    void[] p;\n    assert(roundStartToMultipleOf(p, 16) is null);\n    p = new ulong[10];\n    assert(roundStartToMultipleOf(p, 16) is p);\n}\n\n/*\nReturns `s` rounded up to the nearest power of 2.\n*/\n@safe @nogc nothrow pure\npackage size_t roundUpToPowerOf2(size_t s)\n{\n    import std.meta : AliasSeq;\n    assert(s <= (size_t.max >> 1) + 1);\n    --s;\n    static if (size_t.sizeof == 4)\n        alias Shifts = AliasSeq!(1, 2, 4, 8, 16);\n    else\n        alias Shifts = AliasSeq!(1, 2, 4, 8, 16, 32);\n    foreach (i; Shifts)\n    {\n        s |= s >> i;\n    }\n    return s + 1;\n}\n\n@safe @nogc nothrow pure\nunittest\n{\n    assert(0.roundUpToPowerOf2 == 0);\n    assert(1.roundUpToPowerOf2 == 1);\n    assert(2.roundUpToPowerOf2 == 2);\n    assert(3.roundUpToPowerOf2 == 4);\n    assert(7.roundUpToPowerOf2 == 8);\n    assert(8.roundUpToPowerOf2 == 8);\n    assert(10.roundUpToPowerOf2 == 16);\n    assert(11.roundUpToPowerOf2 == 16);\n    assert(12.roundUpToPowerOf2 == 16);\n    assert(118.roundUpToPowerOf2 == 128);\n    assert((size_t.max >> 1).roundUpToPowerOf2 == (size_t.max >> 1) + 1);\n    assert(((size_t.max >> 1) + 1).roundUpToPowerOf2 == (size_t.max >> 1) + 1);\n}\n\n/*\nReturns the number of trailing zeros of `x`.\n*/\n@safe @nogc nothrow pure\npackage uint trailingZeros(ulong x)\n{\n    uint result;\n    while (result < 64 && !(x & (1UL << result)))\n    {\n        ++result;\n    }\n    return result;\n}\n\n@safe @nogc nothrow pure\nunittest\n{\n    assert(trailingZeros(0) == 64);\n    assert(trailingZeros(1) == 0);\n    assert(trailingZeros(2) == 1);\n    assert(trailingZeros(3) == 0);\n    assert(trailingZeros(4) == 2);\n}\n\n/*\nReturns `true` if `ptr` is aligned at `alignment`.\n*/\n@nogc nothrow pure\npackage bool alignedAt(T)(T* ptr, uint alignment)\n{\n    return cast(size_t) ptr % alignment == 0;\n}\n\n/*\nReturns the effective alignment of `ptr`, i.e. the largest power of two that is\na divisor of `ptr`.\n*/\n@nogc nothrow pure\npackage size_t effectiveAlignment(void* ptr)\n{\n    return (cast(size_t) 1) << trailingZeros(cast(size_t) ptr);\n}\n\n@nogc nothrow pure\n@system unittest\n{\n    int x;\n    assert(effectiveAlignment(&x) >= int.alignof);\n\n    const max = (cast(size_t) 1) << (size_t.sizeof * 8 - 1);\n    assert(effectiveAlignment(cast(void*) max) == max);\n}\n\n/*\nAligns a pointer down to a specified alignment. The resulting pointer is less\nthan or equal to the given pointer.\n*/\n@nogc nothrow pure\npackage void* alignDownTo(void* ptr, uint alignment)\n{\n    import std.math : isPowerOf2;\n    assert(alignment.isPowerOf2);\n    return cast(void*) (cast(size_t) ptr & ~(alignment - 1UL));\n}\n\n/*\nAligns a pointer up to a specified alignment. The resulting pointer is greater\nthan or equal to the given pointer.\n*/\n@nogc nothrow pure\npackage void* alignUpTo(void* ptr, uint alignment)\n{\n    import std.math : isPowerOf2;\n    assert(alignment.isPowerOf2);\n    immutable uint slack = cast(size_t) ptr & (alignment - 1U);\n    return slack ? ptr + alignment - slack : ptr;\n}\n\n@safe @nogc nothrow pure\npackage bool isGoodStaticAlignment(uint x)\n{\n    import std.math : isPowerOf2;\n    return x.isPowerOf2;\n}\n\n@safe @nogc nothrow pure\npackage bool isGoodDynamicAlignment(uint x)\n{\n    import std.math : isPowerOf2;\n    return x.isPowerOf2 && x >= (void*).sizeof;\n}\n\n/**\nThe default `reallocate` function first attempts to use `expand`. If $(D\nAllocator.expand) is not defined or returns `false`, `reallocate`\nallocates a new block of memory of appropriate size and copies data from the old\nblock to the new block. Finally, if `Allocator` defines `deallocate`, $(D\nreallocate) uses it to free the old memory block.\n\n`reallocate` does not attempt to use `Allocator.reallocate` even if\ndefined. This is deliberate so allocators may use it internally within their own\nimplementation of `reallocate`.\n\n*/\nbool reallocate(Allocator)(ref Allocator a, ref void[] b, size_t s)\n{\n    if (b.length == s) return true;\n    static if (hasMember!(Allocator, \"expand\"))\n    {\n        if (b.length <= s && a.expand(b, s - b.length)) return true;\n    }\n    auto newB = a.allocate(s);\n    if (newB.length != s) return false;\n    if (newB.length <= b.length) newB[] = b[0 .. newB.length];\n    else newB[0 .. b.length] = b[];\n    static if (hasMember!(Allocator, \"deallocate\"))\n        a.deallocate(b);\n    b = newB;\n    return true;\n}\n\n/**\n\nThe default `alignedReallocate` function first attempts to use `expand`.\nIf `Allocator.expand` is not defined or returns `false`,  $(D\nalignedReallocate) allocates a new block of memory of appropriate size and\ncopies data from the old block to the new block. Finally, if `Allocator`\ndefines `deallocate`, `alignedReallocate` uses it to free the old memory\nblock.\n\n`alignedReallocate` does not attempt to use `Allocator.reallocate` even if\ndefined. This is deliberate so allocators may use it internally within their own\nimplementation of `reallocate`.\n\n*/\nbool alignedReallocate(Allocator)(ref Allocator alloc,\n        ref void[] b, size_t s, uint a)\nif (hasMember!(Allocator, \"alignedAllocate\"))\n{\n    static if (hasMember!(Allocator, \"expand\"))\n    {\n        if (b.length <= s && b.ptr.alignedAt(a)\n            && alloc.expand(b, s - b.length)) return true;\n    }\n    else\n    {\n        if (b.length == s && b.ptr.alignedAt(a)) return true;\n    }\n    auto newB = alloc.alignedAllocate(s, a);\n    if (newB.length != s) return false;\n    if (newB.length <= b.length) newB[] = b[0 .. newB.length];\n    else newB[0 .. b.length] = b[];\n    static if (hasMember!(Allocator, \"deallocate\"))\n        alloc.deallocate(b);\n    b = newB;\n    return true;\n}\n\n@system unittest\n{\n    bool called = false;\n    struct DummyAllocator\n    {\n        void[] alignedAllocate(size_t size, uint alignment)\n        {\n            called = true;\n            return null;\n        }\n    }\n\n    struct DummyAllocatorExpand\n    {\n        void[] alignedAllocate(size_t size, uint alignment)\n        {\n            return null;\n        }\n\n        bool expand(ref void[] b, size_t length)\n        {\n            called = true;\n            return true;\n        }\n    }\n\n    char[128] buf;\n    uint alignment = 32;\n    auto alignedPtr = roundUpToMultipleOf(cast(size_t) buf.ptr, alignment);\n    auto diff = alignedPtr - cast(size_t) buf.ptr;\n\n    // Align the buffer to 'alignment'\n    void[] b = cast(void[]) (buf.ptr + diff)[0 .. buf.length - diff];\n\n    DummyAllocator a1;\n    // Ask for same length and alignment, should not call 'alignedAllocate'\n    assert(alignedReallocate(a1, b, b.length, alignment));\n    assert(!called);\n\n    // Ask for same length, different alignment\n    // should call 'alignedAllocate' if not aligned to new value\n    alignedReallocate(a1, b, b.length, alignment + 1);\n    assert(b.ptr.alignedAt(alignment + 1) || called);\n    called = false;\n\n    DummyAllocatorExpand a2;\n    // Ask for bigger length, same alignment, should call 'expand'\n    assert(alignedReallocate(a2, b, b.length + 1, alignment));\n    assert(called);\n    called = false;\n\n    // Ask for bigger length, different alignment\n    // should call 'alignedAllocate' if not aligned to new value\n    alignedReallocate(a2, b, b.length + 1, alignment + 1);\n    assert(b.ptr.alignedAt(alignment + 1) || !called);\n}\n\n/**\nForwards each of the methods in `funs` (if defined) to `member`.\n*/\n/*package*/ string forwardToMember(string member, string[] funs...)\n{\n    string result = \"    import std.traits : hasMember, Parameters;\\n\";\n    foreach (fun; funs)\n    {\n        result ~= \"\n    static if (hasMember!(typeof(\"~member~\"), `\"~fun~\"`))\n    auto ref \"~fun~\"(Parameters!(typeof(\"~member~\".\"~fun~\")) args)\n    {\n        return \"~member~\".\"~fun~\"(args);\n    }\\n\";\n    }\n    return result;\n}\n\nversion (unittest)\n{\n\n    package void testAllocator(alias make)()\n    {\n        import std.conv : text;\n        import std.math : isPowerOf2;\n        import std.stdio : writeln, stderr;\n        import std.typecons : Ternary;\n        alias A = typeof(make());\n        scope(failure) stderr.writeln(\"testAllocator failed for \", A.stringof);\n\n        auto a = make();\n\n        // Test alignment\n        static assert(A.alignment.isPowerOf2);\n\n        // Test goodAllocSize\n        assert(a.goodAllocSize(1) >= A.alignment,\n                text(a.goodAllocSize(1), \" < \", A.alignment));\n        assert(a.goodAllocSize(11) >= 11.roundUpToMultipleOf(A.alignment));\n        assert(a.goodAllocSize(111) >= 111.roundUpToMultipleOf(A.alignment));\n\n        // Test allocate\n        assert(a.allocate(0) is null);\n\n        auto b1 = a.allocate(1);\n        assert(b1.length == 1);\n        auto b2 = a.allocate(2);\n        assert(b2.length == 2);\n        assert(b2.ptr + b2.length <= b1.ptr || b1.ptr + b1.length <= b2.ptr);\n\n        // Test allocateZeroed\n        static if (hasMember!(A, \"allocateZeroed\"))\n        {{\n            auto b3 = a.allocateZeroed(8);\n            if (b3 !is null)\n            {\n                assert(b3.length == 8);\n                foreach (e; cast(ubyte[]) b3)\n                    assert(e == 0);\n            }\n        }}\n\n        // Test alignedAllocate\n        static if (hasMember!(A, \"alignedAllocate\"))\n        {{\n             auto b3 = a.alignedAllocate(1, 256);\n             assert(b3.length <= 1);\n             assert(b3.ptr.alignedAt(256));\n             assert(a.alignedReallocate(b3, 2, 512));\n             assert(b3.ptr.alignedAt(512));\n             static if (hasMember!(A, \"alignedDeallocate\"))\n             {\n                 a.alignedDeallocate(b3);\n             }\n         }}\n        else\n        {\n            static assert(!hasMember!(A, \"alignedDeallocate\"));\n            // This seems to be a bug in the compiler:\n            //static assert(!hasMember!(A, \"alignedReallocate\"), A.stringof);\n        }\n\n        static if (hasMember!(A, \"allocateAll\"))\n        {{\n             auto aa = make();\n             if (aa.allocateAll().ptr)\n             {\n                 // Can't get any more memory\n                 assert(!aa.allocate(1).ptr);\n             }\n             auto ab = make();\n             const b4 = ab.allocateAll();\n             assert(b4.length);\n             // Can't get any more memory\n             assert(!ab.allocate(1).ptr);\n         }}\n\n        static if (hasMember!(A, \"expand\"))\n        {{\n             assert(a.expand(b1, 0));\n             auto len = b1.length;\n             if (a.expand(b1, 102))\n             {\n                 assert(b1.length == len + 102, text(b1.length, \" != \", len + 102));\n             }\n             auto aa = make();\n             void[] b5 = null;\n             assert(aa.expand(b5, 0));\n             assert(b5 is null);\n             assert(!aa.expand(b5, 1));\n             assert(b5.length == 0);\n         }}\n\n        void[] b6 = null;\n        assert(a.reallocate(b6, 0));\n        assert(b6.length == 0);\n        assert(a.reallocate(b6, 1));\n        assert(b6.length == 1, text(b6.length));\n        assert(a.reallocate(b6, 2));\n        assert(b6.length == 2);\n\n        // Test owns\n        static if (hasMember!(A, \"owns\"))\n        {{\n             assert(a.owns(null) == Ternary.no);\n             assert(a.owns(b1) == Ternary.yes);\n             assert(a.owns(b2) == Ternary.yes);\n             assert(a.owns(b6) == Ternary.yes);\n         }}\n\n        static if (hasMember!(A, \"resolveInternalPointer\"))\n        {{\n             void[] p;\n             assert(a.resolveInternalPointer(null, p) == Ternary.no);\n             Ternary r = a.resolveInternalPointer(b1.ptr, p);\n             assert(p.ptr is b1.ptr && p.length >= b1.length);\n             r = a.resolveInternalPointer(b1.ptr + b1.length / 2, p);\n             assert(p.ptr is b1.ptr && p.length >= b1.length);\n             r = a.resolveInternalPointer(b2.ptr, p);\n             assert(p.ptr is b2.ptr && p.length >= b2.length);\n             r = a.resolveInternalPointer(b2.ptr + b2.length / 2, p);\n             assert(p.ptr is b2.ptr && p.length >= b2.length);\n             r = a.resolveInternalPointer(b6.ptr, p);\n             assert(p.ptr is b6.ptr && p.length >= b6.length);\n             r = a.resolveInternalPointer(b6.ptr + b6.length / 2, p);\n             assert(p.ptr is b6.ptr && p.length >= b6.length);\n             static int[10] b7 = [ 1, 2, 3 ];\n             assert(a.resolveInternalPointer(b7.ptr, p) == Ternary.no);\n             assert(a.resolveInternalPointer(b7.ptr + b7.length / 2, p) == Ternary.no);\n             assert(a.resolveInternalPointer(b7.ptr + b7.length, p) == Ternary.no);\n             int[3] b8 = [ 1, 2, 3 ];\n             assert(a.resolveInternalPointer(b8.ptr, p) == Ternary.no);\n             assert(a.resolveInternalPointer(b8.ptr + b8.length / 2, p) == Ternary.no);\n             assert(a.resolveInternalPointer(b8.ptr + b8.length, p) == Ternary.no);\n         }}\n    }\n\n    package void testAllocatorObject(RCAllocInterface)(RCAllocInterface a)\n    {\n        // this used to be a template constraint, but moving it inside prevents\n        // unnecessary import of std.experimental.allocator\n        import std.experimental.allocator : RCIAllocator, RCISharedAllocator;\n        static assert(is(RCAllocInterface == RCIAllocator)\n            || is (RCAllocInterface == RCISharedAllocator));\n\n        import std.conv : text;\n        import std.math : isPowerOf2;\n        import std.stdio : writeln, stderr;\n        import std.typecons : Ternary;\n        scope(failure) stderr.writeln(\"testAllocatorObject failed for \",\n                RCAllocInterface.stringof);\n\n        assert(!a.isNull);\n\n        // Test alignment\n        assert(a.alignment.isPowerOf2);\n\n        // Test goodAllocSize\n        assert(a.goodAllocSize(1) >= a.alignment,\n                text(a.goodAllocSize(1), \" < \", a.alignment));\n        assert(a.goodAllocSize(11) >= 11.roundUpToMultipleOf(a.alignment));\n        assert(a.goodAllocSize(111) >= 111.roundUpToMultipleOf(a.alignment));\n\n        // Test empty\n        assert(a.empty != Ternary.no);\n\n        // Test allocate\n        assert(a.allocate(0) is null);\n\n        auto b1 = a.allocate(1);\n        assert(b1.length == 1);\n        auto b2 = a.allocate(2);\n        assert(b2.length == 2);\n        assert(b2.ptr + b2.length <= b1.ptr || b1.ptr + b1.length <= b2.ptr);\n\n        // Test alignedAllocate\n        {\n            // If not implemented it will return null, so those should pass\n            auto b3 = a.alignedAllocate(1, 256);\n            assert(b3.length <= 1);\n            assert(b3.ptr.alignedAt(256));\n            if (a.alignedReallocate(b3, 1, 256))\n            {\n                // If it is false, then the wrapped allocator did not implement\n                // this\n                assert(a.alignedReallocate(b3, 2, 512));\n                assert(b3.ptr.alignedAt(512));\n            }\n        }\n\n        // Test allocateAll\n        {\n            auto aa = a.allocateAll();\n            if (aa.ptr)\n            {\n                // Can't get any more memory\n                assert(!a.allocate(1).ptr);\n                a.deallocate(aa);\n            }\n            const b4 = a.allocateAll();\n            if (b4.ptr)\n            {\n                // Can't get any more memory\n                assert(!a.allocate(1).ptr);\n            }\n        }\n\n        // Test expand\n        {\n            assert(a.expand(b1, 0));\n            auto len = b1.length;\n            if (a.expand(b1, 102))\n            {\n                assert(b1.length == len + 102, text(b1.length, \" != \", len + 102));\n            }\n        }\n\n        void[] b6 = null;\n        assert(a.reallocate(b6, 0));\n        assert(b6.length == 0);\n        assert(a.reallocate(b6, 1));\n        assert(b6.length == 1, text(b6.length));\n        assert(a.reallocate(b6, 2));\n        assert(b6.length == 2);\n\n        // Test owns\n        {\n            if (a.owns(null) != Ternary.unknown)\n            {\n                assert(a.owns(null) == Ternary.no);\n                assert(a.owns(b1) == Ternary.yes);\n                assert(a.owns(b2) == Ternary.yes);\n                assert(a.owns(b6) == Ternary.yes);\n            }\n        }\n\n        // Test resolveInternalPointer\n        {\n            void[] p;\n            if (a.resolveInternalPointer(null, p) != Ternary.unknown)\n            {\n                assert(a.resolveInternalPointer(null, p) == Ternary.no);\n                Ternary r = a.resolveInternalPointer(b1.ptr, p);\n                assert(p.ptr is b1.ptr && p.length >= b1.length);\n                r = a.resolveInternalPointer(b1.ptr + b1.length / 2, p);\n                assert(p.ptr is b1.ptr && p.length >= b1.length);\n                r = a.resolveInternalPointer(b2.ptr, p);\n                assert(p.ptr is b2.ptr && p.length >= b2.length);\n                r = a.resolveInternalPointer(b2.ptr + b2.length / 2, p);\n                assert(p.ptr is b2.ptr && p.length >= b2.length);\n                r = a.resolveInternalPointer(b6.ptr, p);\n                assert(p.ptr is b6.ptr && p.length >= b6.length);\n                r = a.resolveInternalPointer(b6.ptr + b6.length / 2, p);\n                assert(p.ptr is b6.ptr && p.length >= b6.length);\n                static int[10] b7 = [ 1, 2, 3 ];\n                assert(a.resolveInternalPointer(b7.ptr, p) == Ternary.no);\n                assert(a.resolveInternalPointer(b7.ptr + b7.length / 2, p) == Ternary.no);\n                assert(a.resolveInternalPointer(b7.ptr + b7.length, p) == Ternary.no);\n                int[3] b8 = [ 1, 2, 3 ];\n                assert(a.resolveInternalPointer(b8.ptr, p) == Ternary.no);\n                assert(a.resolveInternalPointer(b8.ptr + b8.length / 2, p) == Ternary.no);\n                assert(a.resolveInternalPointer(b8.ptr + b8.length, p) == Ternary.no);\n            }\n        }\n\n        // Test deallocateAll\n        {\n            if (a.deallocateAll())\n            {\n                if (a.empty != Ternary.unknown)\n                {\n                    assert(a.empty == Ternary.yes);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/gc_allocator.d",
    "content": "// Written in the D programming language.\n/**\nD's built-in garbage-collected allocator.\n\nSource: $(PHOBOSSRC std/experimental/allocator/_gc_allocator.d)\n*/\nmodule std.experimental.allocator.gc_allocator;\nimport std.experimental.allocator.common;\n\n/**\nD's built-in garbage-collected allocator.\n*/\nstruct GCAllocator\n{\n    import core.memory : GC;\n    import std.typecons : Ternary;\n    @system unittest { testAllocator!(() => GCAllocator.instance); }\n\n    /**\n    The alignment is a static constant equal to `platformAlignment`, which\n    ensures proper alignment for any D data type.\n    */\n    enum uint alignment = platformAlignment;\n\n    /**\n    Standard allocator methods per the semantics defined above. The $(D\n    deallocate) and `reallocate` methods are `@system` because they may\n    move memory around, leaving dangling pointers in user code.\n    */\n    pure nothrow @trusted void[] allocate(size_t bytes) shared const\n    {\n        if (!bytes) return null;\n        auto p = GC.malloc(bytes);\n        return p ? p[0 .. bytes] : null;\n    }\n\n    /// Ditto\n    pure nothrow @trusted bool expand(ref void[] b, size_t delta) shared const\n    {\n        if (delta == 0) return true;\n        if (b is null) return false;\n        immutable curLength = GC.sizeOf(b.ptr);\n        assert(curLength != 0); // we have a valid GC pointer here\n        immutable desired = b.length + delta;\n        if (desired > curLength) // check to see if the current block can't hold the data\n        {\n            immutable sizeRequest = desired - curLength;\n            immutable newSize = GC.extend(b.ptr, sizeRequest, sizeRequest);\n            if (newSize == 0)\n            {\n                // expansion unsuccessful\n                return false;\n            }\n            assert(newSize >= desired);\n        }\n        b = b.ptr[0 .. desired];\n        return true;\n    }\n\n    /// Ditto\n    pure nothrow @system bool reallocate(ref void[] b, size_t newSize) shared const\n    {\n        import core.exception : OutOfMemoryError;\n        try\n        {\n            auto p = cast(ubyte*) GC.realloc(b.ptr, newSize);\n            b = p[0 .. newSize];\n        }\n        catch (OutOfMemoryError)\n        {\n            // leave the block in place, tell caller\n            return false;\n        }\n        return true;\n    }\n\n    /// Ditto\n    pure nothrow @trusted @nogc\n    Ternary resolveInternalPointer(const void* p, ref void[] result) shared const\n    {\n        auto r = GC.addrOf(cast(void*) p);\n        if (!r) return Ternary.no;\n        result = r[0 .. GC.sizeOf(r)];\n        return Ternary.yes;\n    }\n\n    /// Ditto\n    pure nothrow @system @nogc\n    bool deallocate(void[] b) shared const\n    {\n        GC.free(b.ptr);\n        return true;\n    }\n\n    /// Ditto\n    pure nothrow @safe @nogc\n    size_t goodAllocSize(size_t n) shared const\n    {\n        if (n == 0)\n            return 0;\n        if (n <= 16)\n            return 16;\n\n        import core.bitop : bsr;\n\n        auto largestBit = bsr(n-1) + 1;\n        if (largestBit <= 12) // 4096 or less\n            return size_t(1) << largestBit;\n\n        // larger, we use a multiple of 4096.\n        return ((n + 4095) / 4096) * 4096;\n    }\n\n    package pure nothrow @trusted void[] allocateZeroed()(size_t bytes) shared const\n    {\n        if (!bytes) return null;\n        auto p = GC.calloc(bytes);\n        return p ? p[0 .. bytes] : null;\n    }\n\n    /**\n    Returns the global instance of this allocator type. The garbage collected\n    allocator is thread-safe, therefore all of its methods and `instance` itself\n    are `shared`.\n    */\n\n    static shared const GCAllocator instance;\n\n    // Leave it undocummented for now.\n    nothrow @trusted void collect() shared const\n    {\n        GC.collect();\n    }\n}\n\n///\npure @system unittest\n{\n    auto buffer = GCAllocator.instance.allocate(1024 * 1024 * 4);\n    // deallocate upon scope's end (alternatively: leave it to collection)\n    scope(exit) GCAllocator.instance.deallocate(buffer);\n    //...\n}\n\npure @safe unittest\n{\n    auto b = GCAllocator.instance.allocate(10_000);\n    assert(GCAllocator.instance.expand(b, 1));\n}\n\npure @system unittest\n{\n    import core.memory : GC;\n    import std.typecons : Ternary;\n\n    // test allocation sizes\n    assert((() nothrow @safe @nogc => GCAllocator.instance.goodAllocSize(1))() == 16);\n    for (size_t s = 16; s <= 8192; s *= 2)\n    {\n        assert((() nothrow @safe @nogc => GCAllocator.instance.goodAllocSize(s))() == s);\n        assert((() nothrow @safe @nogc => GCAllocator.instance.goodAllocSize(s - (s / 2) + 1))() == s);\n\n        auto buffer = GCAllocator.instance.allocate(s);\n        scope(exit) () nothrow @nogc { GCAllocator.instance.deallocate(buffer); }();\n\n        void[] p;\n        assert((() nothrow @safe => GCAllocator.instance.resolveInternalPointer(null, p))() == Ternary.no);\n        assert((() nothrow @safe => GCAllocator.instance.resolveInternalPointer(&buffer[0], p))() == Ternary.yes);\n        assert(p.ptr is buffer.ptr && p.length >= buffer.length);\n\n        assert(GC.sizeOf(buffer.ptr) == s);\n\n        auto buffer2 = GCAllocator.instance.allocate(s - (s / 2) + 1);\n        scope(exit) () nothrow @nogc { GCAllocator.instance.deallocate(buffer2); }();\n\n        assert(GC.sizeOf(buffer2.ptr) == s);\n    }\n\n    // anything above a page is simply rounded up to next page\n    assert((() nothrow @safe @nogc => GCAllocator.instance.goodAllocSize(4096 * 4 + 1))() == 4096 * 5);\n}\n\npure nothrow @safe unittest\n{\n    import std.typecons : Ternary;\n\n    void[] buffer = GCAllocator.instance.allocate(42);\n    void[] result;\n    Ternary found = GCAllocator.instance.resolveInternalPointer(&buffer[0], result);\n\n    assert(found == Ternary.yes && &result[0] == &buffer[0] && result.length >= buffer.length);\n    assert(GCAllocator.instance.resolveInternalPointer(null, result) == Ternary.no);\n    void *badPtr = (() @trusted => cast(void*)(0xdeadbeef))();\n    assert(GCAllocator.instance.resolveInternalPointer(badPtr, result) == Ternary.no);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/mallocator.d",
    "content": "// Written in the D programming language.\n/**\nThe C heap allocator.\n\nSource: $(PHOBOSSRC std/experimental/allocator/mallocator.d)\n*/\nmodule std.experimental.allocator.mallocator;\nimport std.experimental.allocator.common;\n\n/**\n   The C heap allocator.\n */\nstruct Mallocator\n{\n    @system unittest { testAllocator!(() => Mallocator.instance); }\n\n    /**\n    The alignment is a static constant equal to `platformAlignment`, which\n    ensures proper alignment for any D data type.\n    */\n    enum uint alignment = platformAlignment;\n\n    /**\n    Standard allocator methods per the semantics defined above. The\n    `deallocate` and `reallocate` methods are `@system` because they\n    may move memory around, leaving dangling pointers in user code. Somewhat\n    paradoxically, `malloc` is `@safe` but that's only useful to safe\n    programs that can afford to leak memory allocated.\n    */\n    @trusted @nogc nothrow pure\n    void[] allocate(size_t bytes) shared\n    {\n        import core.memory : pureMalloc;\n        if (!bytes) return null;\n        auto p = pureMalloc(bytes);\n        return p ? p[0 .. bytes] : null;\n    }\n\n    /// Ditto\n    @system @nogc nothrow pure\n    bool deallocate(void[] b) shared\n    {\n        import core.memory : pureFree;\n        pureFree(b.ptr);\n        return true;\n    }\n\n    /// Ditto\n    @system @nogc nothrow pure\n    bool reallocate(ref void[] b, size_t s) shared\n    {\n        import core.memory : pureRealloc;\n        if (!s)\n        {\n            // fuzzy area in the C standard, see http://goo.gl/ZpWeSE\n            // so just deallocate and nullify the pointer\n            deallocate(b);\n            b = null;\n            return true;\n        }\n        auto p = cast(ubyte*) pureRealloc(b.ptr, s);\n        if (!p) return false;\n        b = p[0 .. s];\n        return true;\n    }\n\n    @trusted @nogc nothrow pure\n    package void[] allocateZeroed()(size_t bytes) shared\n    {\n        import core.memory : pureCalloc;\n        if (!bytes) return null;\n        auto p = pureCalloc(1, bytes);\n        return p ? p[0 .. bytes] : null;\n    }\n\n    /**\n    Returns the global instance of this allocator type. The C heap allocator is\n    thread-safe, therefore all of its methods and `it` itself are\n    `shared`.\n    */\n    static shared Mallocator instance;\n}\n\n///\n@nogc @system nothrow pure unittest\n{\n    auto buffer = Mallocator.instance.allocate(1024 * 1024 * 4);\n    scope(exit) Mallocator.instance.deallocate(buffer);\n    //...\n}\n\n@nogc @system nothrow pure unittest\n{\n    @nogc nothrow pure\n    static void test(A)()\n    {\n        int* p = null;\n        p = cast(int*) A.instance.allocate(int.sizeof);\n        scope(exit) () nothrow @nogc { A.instance.deallocate(p[0 .. int.sizeof]); }();\n        *p = 42;\n        assert(*p == 42);\n    }\n    test!Mallocator();\n}\n\n@nogc @system nothrow pure unittest\n{\n    static void test(A)()\n    {\n        import std.experimental.allocator : make;\n        Object p = null;\n        p = A.instance.make!Object();\n        assert(p !is null);\n    }\n\n    test!Mallocator();\n}\n\nversion (Windows)\n{\n    // DMD Win 32 bit, DigitalMars C standard library misses the _aligned_xxx\n    // functions family (snn.lib)\n    version (CRuntime_DigitalMars)\n    {\n        // Helper to cast the infos written before the aligned pointer\n        // this header keeps track of the size (required to realloc) and of\n        // the base ptr (required to free).\n        private struct AlignInfo\n        {\n            void* basePtr;\n            size_t size;\n\n            @nogc nothrow\n            static AlignInfo* opCall(void* ptr)\n            {\n                return cast(AlignInfo*) (ptr - AlignInfo.sizeof);\n            }\n        }\n\n        @nogc nothrow\n        private void* _aligned_malloc(size_t size, size_t alignment)\n        {\n            import core.stdc.stdlib : malloc;\n            size_t offset = alignment + size_t.sizeof * 2 - 1;\n\n            // unaligned chunk\n            void* basePtr = malloc(size + offset);\n            if (!basePtr) return null;\n\n            // get aligned location within the chunk\n            void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)\n                & ~(alignment - 1));\n\n            // write the header before the aligned pointer\n            AlignInfo* head = AlignInfo(alignedPtr);\n            head.basePtr = basePtr;\n            head.size = size;\n\n            return alignedPtr;\n        }\n\n        @nogc nothrow\n        private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)\n        {\n            import core.stdc.stdlib : free;\n            import core.stdc.string : memcpy;\n\n            if (!ptr) return _aligned_malloc(size, alignment);\n\n            // gets the header from the exising pointer\n            AlignInfo* head = AlignInfo(ptr);\n\n            // gets a new aligned pointer\n            void* alignedPtr = _aligned_malloc(size, alignment);\n            if (!alignedPtr)\n            {\n                //to https://msdn.microsoft.com/en-us/library/ms235462.aspx\n                //see Return value: in this case the original block is unchanged\n                return null;\n            }\n\n            // copy exising data\n            memcpy(alignedPtr, ptr, head.size);\n            free(head.basePtr);\n\n            return alignedPtr;\n        }\n\n        @nogc nothrow\n        private void _aligned_free(void *ptr)\n        {\n            import core.stdc.stdlib : free;\n            if (!ptr) return;\n            AlignInfo* head = AlignInfo(ptr);\n            free(head.basePtr);\n        }\n\n    }\n    // DMD Win 64 bit, uses microsoft standard C library which implements them\n    else\n    {\n        @nogc nothrow private extern(C) void* _aligned_malloc(size_t, size_t);\n        @nogc nothrow private extern(C) void _aligned_free(void *memblock);\n        @nogc nothrow private extern(C) void* _aligned_realloc(void *, size_t, size_t);\n    }\n}\n\n/**\n   Aligned allocator using OS-specific primitives, under a uniform API.\n */\nstruct AlignedMallocator\n{\n    @system unittest { testAllocator!(() => typeof(this).instance); }\n\n    /**\n    The default alignment is `platformAlignment`.\n    */\n    enum uint alignment = platformAlignment;\n\n    /**\n    Forwards to $(D alignedAllocate(bytes, platformAlignment)).\n    */\n    @trusted @nogc nothrow\n    void[] allocate(size_t bytes) shared\n    {\n        if (!bytes) return null;\n        return alignedAllocate(bytes, alignment);\n    }\n\n    /**\n    Uses $(HTTP man7.org/linux/man-pages/man3/posix_memalign.3.html,\n    `posix_memalign`) on Posix and\n    $(HTTP msdn.microsoft.com/en-us/library/8z34s9c6(v=vs.80).aspx,\n    `__aligned_malloc`) on Windows.\n    */\n    version (Posix)\n    @trusted @nogc nothrow\n    void[] alignedAllocate(size_t bytes, uint a) shared\n    {\n        import core.stdc.errno : ENOMEM, EINVAL;\n        import core.sys.posix.stdlib : posix_memalign;\n        assert(a.isGoodDynamicAlignment);\n        void* result;\n        auto code = posix_memalign(&result, a, bytes);\n\nversion (OSX)\nversion (LDC_AddressSanitizer)\n{\n        // The return value with AddressSanitizer may be -1 instead of ENOMEM\n        // or EINVAL. See https://bugs.llvm.org/show_bug.cgi?id=36510\n        if (code == -1)\n            return null;\n}\n        if (code == ENOMEM)\n            return null;\n\n        else if (code == EINVAL)\n        {\n            assert(0, \"AlignedMallocator.alignment is not a power of two \"\n                ~\"multiple of (void*).sizeof, according to posix_memalign!\");\n        }\n        else if (code != 0)\n            assert(0, \"posix_memalign returned an unknown code!\");\n\n        else\n            return result[0 .. bytes];\n    }\n    else version (Windows)\n    @trusted @nogc nothrow\n    void[] alignedAllocate(size_t bytes, uint a) shared\n    {\n        auto result = _aligned_malloc(bytes, a);\n        return result ? result[0 .. bytes] : null;\n    }\n    else static assert(0);\n\n    /**\n    Calls `free(b.ptr)` on Posix and\n    $(HTTP msdn.microsoft.com/en-US/library/17b5h8td(v=vs.80).aspx,\n    `__aligned_free(b.ptr)`) on Windows.\n    */\n    version (Posix)\n    @system @nogc nothrow\n    bool deallocate(void[] b) shared\n    {\n        import core.stdc.stdlib : free;\n        free(b.ptr);\n        return true;\n    }\n    else version (Windows)\n    @system @nogc nothrow\n    bool deallocate(void[] b) shared\n    {\n        _aligned_free(b.ptr);\n        return true;\n    }\n    else static assert(0);\n\n    /**\n    Forwards to $(D alignedReallocate(b, newSize, platformAlignment)).\n    Should be used with blocks obtained with `allocate` otherwise the custom\n    alignment passed with `alignedAllocate` can be lost.\n    */\n    @system @nogc nothrow\n    bool reallocate(ref void[] b, size_t newSize) shared\n    {\n        return alignedReallocate(b, newSize, alignment);\n    }\n\n    /**\n    On Posix there is no `realloc` for aligned memory, so `alignedReallocate` emulates\n    the needed behavior by using `alignedAllocate` to get a new block. The existing\n    block is copied to the new block and then freed.\n    On Windows, calls $(HTTPS msdn.microsoft.com/en-us/library/y69db7sx.aspx,\n    $(D __aligned_realloc(b.ptr, newSize, a))).\n    */\n    version (Windows)\n    @system @nogc nothrow\n    bool alignedReallocate(ref void[] b, size_t s, uint a) shared\n    {\n        if (!s)\n        {\n            deallocate(b);\n            b = null;\n            return true;\n        }\n        auto p = cast(ubyte*) _aligned_realloc(b.ptr, s, a);\n        if (!p) return false;\n        b = p[0 .. s];\n        return true;\n    }\n\n    /// ditto\n    version (Posix)\n    @system @nogc nothrow\n    bool alignedReallocate(ref void[] b, size_t s, uint a) shared\n    {\n        if (!s)\n        {\n            deallocate(b);\n            b = null;\n            return true;\n        }\n        auto p = alignedAllocate(s, a);\n        if (!p.ptr)\n        {\n            return false;\n        }\n        import std.algorithm.comparison : min;\n        const upTo = min(s, b.length);\n        p[0 .. upTo] = b[0 .. upTo];\n        deallocate(b);\n        b = p;\n        return true;\n    }\n\n    /**\n    Returns the global instance of this allocator type. The C heap allocator is\n    thread-safe, therefore all of its methods and `instance` itself are\n    `shared`.\n    */\n    static shared AlignedMallocator instance;\n}\n\n///\n@nogc @system nothrow unittest\n{\n    auto buffer = AlignedMallocator.instance.alignedAllocate(1024 * 1024 * 4,\n        128);\n    scope(exit) AlignedMallocator.instance.deallocate(buffer);\n    //...\n}\n\nversion (Posix)\n@nogc @system nothrow unittest\n{\n    // 16398 : test the \"pseudo\" alignedReallocate for Posix\n    void[] s = AlignedMallocator.instance.alignedAllocate(16, 32);\n    (cast(ubyte[]) s)[] = ubyte(1);\n    AlignedMallocator.instance.alignedReallocate(s, 32, 32);\n    ubyte[16] o;\n    o[] = 1;\n    assert((cast(ubyte[]) s)[0 .. 16] == o);\n    AlignedMallocator.instance.alignedReallocate(s, 4, 32);\n    assert((cast(ubyte[]) s)[0 .. 3] == o[0 .. 3]);\n    AlignedMallocator.instance.alignedReallocate(s, 128, 32);\n    assert((cast(ubyte[]) s)[0 .. 3] == o[0 .. 3]);\n    AlignedMallocator.instance.deallocate(s);\n\n    void[] c;\n    AlignedMallocator.instance.alignedReallocate(c, 32, 32);\n    assert(c.ptr);\n\n    version (DragonFlyBSD) {} else    /* FIXME: Malloc on DragonFly does not return NULL when allocating more than UINTPTR_MAX\n                                       * $(LINK: https://bugs.dragonflybsd.org/issues/3114, dragonfly bug report)\n                                       * $(LINK: https://github.com/dlang/druntime/pull/1999#discussion_r157536030, PR Discussion) */\n    assert(!AlignedMallocator.instance.alignedReallocate(c, size_t.max, 4096));\n    AlignedMallocator.instance.deallocate(c);\n}\n\nversion (CRuntime_DigitalMars)\n@nogc @system nothrow unittest\n{\n    void* m;\n\n    size_t m_addr() { return cast(size_t) m; }\n\n    m = _aligned_malloc(16, 0x10);\n    if (m)\n    {\n        assert((m_addr & 0xF) == 0);\n        _aligned_free(m);\n    }\n\n    m = _aligned_malloc(16, 0x100);\n    if (m)\n    {\n        assert((m_addr & 0xFF) == 0);\n        _aligned_free(m);\n    }\n\n    m = _aligned_malloc(16, 0x1000);\n    if (m)\n    {\n        assert((m_addr & 0xFFF) == 0);\n        _aligned_free(m);\n    }\n\n    m = _aligned_malloc(16, 0x10);\n    if (m)\n    {\n        assert((cast(size_t) m & 0xF) == 0);\n        m = _aligned_realloc(m, 32, 0x10000);\n        if (m) assert((m_addr & 0xFFFF) == 0);\n        _aligned_free(m);\n    }\n\n    m = _aligned_malloc(8, 0x10);\n    if (m)\n    {\n        *cast(ulong*) m = 0X01234567_89ABCDEF;\n        m = _aligned_realloc(m, 0x800, 0x1000);\n        if (m) assert(*cast(ulong*) m == 0X01234567_89ABCDEF);\n        _aligned_free(m);\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/mmap_allocator.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/allocator/_mmap_allocator.d)\n*/\nmodule std.experimental.allocator.mmap_allocator;\n\n/**\nAllocator (currently defined only for Posix and Windows) using\n$(D $(LINK2 https://en.wikipedia.org/wiki/Mmap, mmap))\nand $(D $(LUCKY munmap)) directly (or their Windows equivalents). There is no\nadditional structure: each call to `allocate(s)` issues a call to\n$(D mmap(null, s, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)),\nand each call to `deallocate(b)` issues $(D munmap(b.ptr, b.length)).\nSo `MmapAllocator` is usually intended for allocating large chunks to be\nmanaged by fine-granular allocators.\n*/\nstruct MmapAllocator\n{\n    /// The one shared instance.\n    static shared const MmapAllocator instance;\n\n    /**\n    Alignment is page-size and hardcoded to 4096 (even though on certain systems\n    it could be larger).\n    */\n    enum size_t alignment = 4096;\n\n    version (Posix)\n    {\n        /// Allocator API.\n        pure nothrow @nogc @safe\n        void[] allocate(size_t bytes) shared const\n        {\n            import core.sys.posix.sys.mman : MAP_ANON, PROT_READ,\n                PROT_WRITE, MAP_PRIVATE, MAP_FAILED;\n            if (!bytes) return null;\n            const errnosave = (() @trusted => fakePureErrno())(); // For purity revert changes to errno.\n            auto p = (() @trusted => fakePureMmap(null, bytes, PROT_READ | PROT_WRITE,\n                MAP_PRIVATE | MAP_ANON, -1, 0))();\n            if (p is MAP_FAILED)\n            {\n                (() @trusted => fakePureErrno() = errnosave)(); // errno only changed on MAP_FAILED.\n                return null;\n            }\n            return (() @trusted => p[0 .. bytes])();\n        }\n\n        /// Ditto\n        pure nothrow @nogc\n        bool deallocate(void[] b) shared const\n        {\n            // Because we assert(0) on error we don't need to reset errno for purity.\n            if (b.ptr) fakePureMunmap(b.ptr, b.length) == 0 || assert(0);\n            return true;\n        }\n\n        // Anonymous mmap might be zero-filled on all Posix systems but\n        // not all commit to this in the documentation.\n        version (linux)\n            // http://man7.org/linux/man-pages/man2/mmap.2.html\n            package alias allocateZeroed = allocate;\n        else version (NetBSD)\n            // http://netbsd.gw.com/cgi-bin/man-cgi?mmap+2+NetBSD-current\n            package alias allocateZeroed = allocate;\n        else version (Solaris)\n            // https://docs.oracle.com/cd/E88353_01/html/E37841/mmap-2.html\n            package alias allocateZeroed = allocate;\n        else version (AIX)\n            // https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.basetrf1/mmap.htm\n            package alias allocateZeroed = allocate;\n    }\n    else version (Windows)\n    {\n        import core.sys.windows.windows : MEM_COMMIT, PAGE_READWRITE, MEM_RELEASE;\n\n        /// Allocator API.\n        pure nothrow @nogc @safe\n        void[] allocate(size_t bytes) shared const\n        {\n            if (!bytes) return null;\n            // For purity ensure last-error does not visibly change.\n            const lastErrorSave = (() @trusted => GetLastError())();\n            auto p = (() @trusted => VirtualAlloc(null, bytes, MEM_COMMIT, PAGE_READWRITE))();\n            if (p == null)\n            {\n                // Last-error only changed if allocation failed.\n                (() @trusted => SetLastError(lastErrorSave))();\n                return null;\n            }\n            return (() @trusted => p[0 .. bytes])();\n        }\n\n        /// Ditto\n        pure nothrow @nogc\n        bool deallocate(void[] b) shared const\n        {\n            const lastErrorSave = GetLastError(); // For purity ensure last-error does not visibly change.\n            scope(exit) SetLastError(lastErrorSave);\n            return b.ptr is null || VirtualFree(b.ptr, 0, MEM_RELEASE) != 0;\n        }\n\n        package alias allocateZeroed = allocate;\n    }\n}\n\n// pure wrappers around `mmap` and `munmap` because they are used here locally\n// solely to perform allocation and deallocation which in this case is `pure`\nversion (Posix)\nextern (C) private pure @system @nogc nothrow\n{\n    import core.sys.posix.sys.types : off_t;\n    pragma(mangle, \"fakePureErrnoImpl\") ref int fakePureErrno();\n    pragma(mangle, \"mmap\") void* fakePureMmap(void*, size_t, int, int, int, off_t);\n    pragma(mangle, \"munmap\") int fakePureMunmap(void*, size_t);\n}\n\n// Pure wrappers around VirtualAlloc/VirtualFree for use here only. Their use is sound\n// because when we call them we ensure that last-error is not visibly changed.\nversion (Windows)\nextern (Windows) private pure @system @nogc nothrow\n{\n    import core.sys.windows.basetsd : SIZE_T;\n    import core.sys.windows.windef : BOOL, DWORD;\n    import core.sys.windows.winnt : LPVOID, PVOID;\n\n    DWORD GetLastError();\n    void SetLastError(DWORD);\n    PVOID VirtualAlloc(PVOID, SIZE_T, DWORD, DWORD);\n    BOOL VirtualFree(PVOID, SIZE_T, DWORD);\n}\n\npure nothrow @safe @nogc unittest\n{\n    alias alloc = MmapAllocator.instance;\n    auto p = alloc.allocate(100);\n    assert(p.length == 100);\n    () @trusted { alloc.deallocate(p); p = null; }();\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/package.d",
    "content": "// Written in the D programming language.\n/**\n\nHigh-level interface for allocators. Implements bundled allocation/creation\nand destruction/deallocation of data including `struct`s and `class`es,\nand also array primitives related to allocation. This module is the entry point\nfor both making use of allocators and for their documentation.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Make) $(TD\n    $(LREF make)\n    $(LREF makeArray)\n    $(LREF makeMultidimensionalArray)\n))\n$(TR $(TD Dispose) $(TD\n    $(LREF dispose)\n    $(LREF disposeMultidimensionalArray)\n))\n$(TR $(TD Modify) $(TD\n    $(LREF expandArray)\n    $(LREF shrinkArray)\n))\n$(TR $(TD Global) $(TD\n    $(LREF processAllocator)\n    $(LREF theAllocator)\n))\n$(TR $(TD Class interface) $(TD\n    $(LREF allocatorObject)\n    $(LREF CAllocatorImpl)\n    $(LREF IAllocator)\n))\n)\n\nSynopsis:\n---\n// Allocate an int, initialize it with 42\nint* p = theAllocator.make!int(42);\nassert(*p == 42);\n// Destroy and deallocate it\ntheAllocator.dispose(p);\n\n// Allocate using the global process allocator\np = processAllocator.make!int(100);\nassert(*p == 100);\n// Destroy and deallocate\nprocessAllocator.dispose(p);\n\n// Create an array of 50 doubles initialized to -1.0\ndouble[] arr = theAllocator.makeArray!double(50, -1.0);\n// Append two zeros to it\ntheAllocator.expandArray(arr, 2, 0.0);\n// On second thought, take that back\ntheAllocator.shrinkArray(arr, 2);\n// Destroy and deallocate\ntheAllocator.dispose(arr);\n---\n\n$(H2 Layered Structure)\n\nD's allocators have a layered structure in both implementation and documentation:\n\n$(OL\n$(LI A high-level, dynamically-typed layer (described further down in this\nmodule). It consists of an interface called $(LREF IAllocator), which concrete\nallocators need to implement. The interface primitives themselves are oblivious\nto the type of the objects being allocated; they only deal in `void[]`, by\nnecessity of the interface being dynamic (as opposed to type-parameterized).\nEach thread has a current allocator it uses by default, which is a thread-local\nvariable $(LREF theAllocator) of type $(LREF IAllocator). The process has a\nglobal allocator called $(LREF processAllocator), also of type $(LREF\nIAllocator). When a new thread is created, $(LREF processAllocator) is copied\ninto $(LREF theAllocator). An application can change the objects to which these\nreferences point. By default, at application startup, $(LREF processAllocator)\nrefers to an object that uses D's garbage collected heap. This layer also\ninclude high-level functions such as $(LREF make) and $(LREF dispose) that\ncomfortably allocate/create and respectively destroy/deallocate objects. This\nlayer is all needed for most casual uses of allocation primitives.)\n\n$(LI A mid-level, statically-typed layer for assembling several allocators into\none. It uses properties of the type of the objects being created to route\nallocation requests to possibly specialized allocators. This layer is relatively\nthin and implemented and documented in the $(MREF\nstd,experimental,allocator,typed) module. It allows an interested user to e.g.\nuse different allocators for arrays versus fixed-sized objects, to the end of\nbetter overall performance.)\n\n$(LI A low-level collection of highly generic $(I heap building blocks)$(MDASH)\nLego-like pieces that can be used to assemble application-specific allocators.\nThe real allocation smarts are occurring at this level. This layer is of\ninterest to advanced applications that want to configure their own allocators.\nA good illustration of typical uses of these building blocks is module $(MREF\nstd,experimental,allocator,showcase) which defines a collection of frequently-\nused preassembled allocator objects. The implementation and documentation entry\npoint is $(MREF std,experimental,allocator,building_blocks). By design, the\nprimitives of the static interface have the same signatures as the $(LREF\nIAllocator) primitives but are for the most part optional and driven by static\nintrospection. The parameterized class $(LREF CAllocatorImpl) offers an\nimmediate and useful means to package a static low-level allocator into an\nimplementation of $(LREF IAllocator).)\n\n$(LI Core allocator objects that interface with D's garbage collected heap\n($(MREF std,experimental,allocator,gc_allocator)), the C `malloc` family\n($(MREF std,experimental,allocator,mallocator)), and the OS ($(MREF\nstd,experimental,allocator,mmap_allocator)). Most custom allocators would\nultimately obtain memory from one of these core allocators.)\n)\n\n$(H2 Idiomatic Use of `std.experimental.allocator`)\n\nAs of this time, `std.experimental.allocator` is not integrated with D's\nbuilt-in operators that allocate memory, such as `new`, array literals, or\narray concatenation operators. That means `std.experimental.allocator` is\nopt-in$(MDASH)applications need to make explicit use of it.\n\nFor casual creation and disposal of dynamically-allocated objects, use $(LREF\nmake), $(LREF dispose), and the array-specific functions $(LREF makeArray),\n$(LREF expandArray), and $(LREF shrinkArray). These use by default D's garbage\ncollected heap, but open the application to better configuration options. These\nprimitives work either with `theAllocator` but also with any allocator obtained\nby combining heap building blocks. For example:\n\n----\nvoid fun(size_t n)\n{\n    // Use the current allocator\n    int[] a1 = theAllocator.makeArray!int(n);\n    scope(exit) theAllocator.dispose(a1);\n    ...\n}\n----\n\nTo experiment with alternative allocators, set $(LREF theAllocator) for the\ncurrent thread. For example, consider an application that allocates many 8-byte\nobjects. These are not well supported by the default allocator, so a\n$(MREF_ALTTEXT free list allocator,\nstd,experimental,allocator,building_blocks,free_list) would be recommended.\nTo install one in `main`, the application would use:\n\n----\nvoid main()\n{\n    import std.experimental.allocator.building_blocks.free_list\n        : FreeList;\n    theAllocator = allocatorObject(FreeList!8());\n    ...\n}\n----\n\n$(H3 Saving the `IAllocator` Reference For Later Use)\n\nAs with any global resource, setting `theAllocator` and `processAllocator`\nshould not be done often and casually. In particular, allocating memory with\none allocator and deallocating with another causes undefined behavior.\nTypically, these variables are set during application initialization phase and\nlast through the application.\n\nTo avoid this, long-lived objects that need to perform allocations,\nreallocations, and deallocations relatively often may want to store a reference\nto the allocator object they use throughout their lifetime. Then, instead of\nusing `theAllocator` for internal allocation-related tasks, they'd use the\ninternally held reference. For example, consider a user-defined hash table:\n\n----\nstruct HashTable\n{\n    private IAllocator allocator;\n    this(size_t buckets, IAllocator allocator = theAllocator) {\n        this.allocator = allocator;\n        ...\n    }\n    // Getter and setter\n    IAllocator allocator() { return allocator; }\n    void allocator(IAllocator a) { assert(empty); allocator = a; }\n}\n----\n\nFollowing initialization, the `HashTable` object would consistently use its\n`allocator` object for acquiring memory. Furthermore, setting\n`HashTable.allocator` to point to a different allocator should be legal but\nonly if the object is empty; otherwise, the object wouldn't be able to\ndeallocate its existing state.\n\n$(H3 Using Allocators without `IAllocator`)\n\nAllocators assembled from the heap building blocks don't need to go through\n`IAllocator` to be usable. They have the same primitives as `IAllocator` and\nthey work with $(LREF make), $(LREF makeArray), $(LREF dispose) etc. So it\nsuffice to create allocator objects wherever fit and use them appropriately:\n\n----\nvoid fun(size_t n)\n{\n    // Use a stack-installed allocator for up to 64KB\n    StackFront!65536 myAllocator;\n    int[] a2 = myAllocator.makeArray!int(n);\n    scope(exit) myAllocator.dispose(a2);\n    ...\n}\n----\n\nIn this case, `myAllocator` does not obey the `IAllocator` interface, but\nimplements its primitives so it can work with `makeArray` by means of duck\ntyping.\n\nOne important thing to note about this setup is that statically-typed assembled\nallocators are almost always faster than allocators that go through\n`IAllocator`. An important rule of thumb is: \"assemble allocator first, adapt\nto `IAllocator` after\". A good allocator implements intricate logic by means of\ntemplate assembly, and gets wrapped with `IAllocator` (usually by means of\n$(LREF allocatorObject)) only once, at client level.\n\nCopyright: Andrei Alexandrescu 2013-.\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu)\n\nSource: $(PHOBOSSRC std/experimental/allocator)\n\n*/\n\nmodule std.experimental.allocator;\n\npublic import std.experimental.allocator.common,\n    std.experimental.allocator.typed;\n\n// Fix issue 17806: this should always be the first unittest in this module\n// in order to ensure that we use the `processAllocator` setter before the getter\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    auto newAlloc = sharedAllocatorObject(Mallocator.instance);\n    processAllocator = newAlloc;\n    assert(processAllocator is newAlloc);\n    processAllocator = sharedAllocatorObject(GCAllocator.instance);\n}\n\n// Example in the synopsis above\n@system unittest\n{\n    import std.algorithm.comparison : min, max;\n    import std.experimental.allocator.building_blocks.allocator_list\n        : AllocatorList;\n    import std.experimental.allocator.building_blocks.bitmapped_block\n        : BitmappedBlock;\n    import std.experimental.allocator.building_blocks.bucketizer : Bucketizer;\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.building_blocks.segregator : Segregator;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n\n    alias FList = FreeList!(GCAllocator, 0, unbounded);\n    alias A = Segregator!(\n        8, FreeList!(GCAllocator, 0, 8),\n        128, Bucketizer!(FList, 1, 128, 16),\n        256, Bucketizer!(FList, 129, 256, 32),\n        512, Bucketizer!(FList, 257, 512, 64),\n        1024, Bucketizer!(FList, 513, 1024, 128),\n        2048, Bucketizer!(FList, 1025, 2048, 256),\n        3584, Bucketizer!(FList, 2049, 3584, 512),\n        4072 * 1024, AllocatorList!(\n            (n) => BitmappedBlock!(4096)(\n                    cast(ubyte[])(GCAllocator.instance.allocate(\n                        max(n, 4072 * 1024))))),\n        GCAllocator\n    );\n    A tuMalloc;\n    auto b = tuMalloc.allocate(500);\n    assert(b.length == 500);\n    auto c = tuMalloc.allocate(113);\n    assert(c.length == 113);\n    assert(tuMalloc.expand(c, 14));\n    tuMalloc.deallocate(b);\n    tuMalloc.deallocate(c);\n}\n\nimport std.range.primitives;\nimport std.traits;\nimport std.typecons;\n\n/**\nDynamic allocator interface. Code that defines allocators ultimately implements\nthis interface. This should be used wherever a uniform type is required for\nencapsulating various allocator implementations.\n\nComposition of allocators is not recommended at this level due to\ninflexibility of dynamic interfaces and inefficiencies caused by cascaded\nmultiple calls. Instead, compose allocators using the static interface defined\nin $(MREF std,experimental,allocator,building_blocks),\nthen adapt the composed\nallocator to `IAllocator` (possibly by using $(LREF CAllocatorImpl) below).\n\nMethods returning `Ternary` return `Ternary.yes` upon success,\n`Ternary.no` upon failure, and `Ternary.unknown` if the primitive is not\nimplemented by the allocator instance.\n*/\ninterface IAllocator\n{\nnothrow:\n    /**\n    Returns the alignment offered.\n    */\n    @property uint alignment();\n\n    /**\n    Returns the good allocation size that guarantees zero internal\n    fragmentation.\n    */\n    size_t goodAllocSize(size_t s);\n\n    /**\n    Allocates `n` bytes of memory.\n    */\n    void[] allocate(size_t, TypeInfo ti = null);\n\n    /**\n    Allocates `n` bytes of memory with specified alignment `a`. Implementations\n    that do not support this primitive should always return `null`.\n    */\n    void[] alignedAllocate(size_t n, uint a);\n\n    /**\n    Allocates and returns all memory available to this allocator.\n    Implementations that do not support this primitive should always return\n    `null`.\n    */\n    void[] allocateAll();\n\n    /**\n    Expands a memory block in place and returns `true` if successful.\n    Implementations that don't support this primitive should always return\n    `false`.\n    */\n    bool expand(ref void[], size_t);\n\n    /// Reallocates a memory block.\n    bool reallocate(ref void[], size_t);\n\n    /// Reallocates a memory block with specified alignment.\n    bool alignedReallocate(ref void[] b, size_t size, uint alignment);\n\n    /**\n    Returns `Ternary.yes` if the allocator owns `b`, `Ternary.no` if\n    the allocator doesn't own `b`, and `Ternary.unknown` if ownership\n    cannot be determined. Implementations that don't support this primitive\n    should always return `Ternary.unknown`.\n    */\n    Ternary owns(void[] b);\n\n    /**\n    Resolves an internal pointer to the full block allocated. Implementations\n    that don't support this primitive should always return `Ternary.unknown`.\n    */\n    Ternary resolveInternalPointer(const void* p, ref void[] result);\n\n    /**\n    Deallocates a memory block. Implementations that don't support this\n    primitive should always return `false`. A simple way to check that an\n    allocator supports deallocation is to call `deallocate(null)`.\n    */\n    bool deallocate(void[] b);\n\n    /**\n    Deallocates all memory. Implementations that don't support this primitive\n    should always return `false`.\n    */\n    bool deallocateAll();\n\n    /**\n    Returns `Ternary.yes` if no memory is currently allocated from this\n    allocator, `Ternary.no` if some allocations are currently active, or\n    `Ternary.unknown` if not supported.\n    */\n    Ternary empty();\n\n    /**\n    Increases the reference count of the concrete class that implements this\n    interface.\n\n    For stateless allocators, this does nothing.\n    */\n    @safe @nogc pure\n    void incRef();\n\n    /**\n    Decreases the reference count of the concrete class that implements this\n    interface.\n    When the reference count is `0`, the object self-destructs.\n\n    Returns: `true` if the reference count is greater than `0` and `false` when\n    it hits `0`. For stateless allocators, it always returns `true`.\n    */\n    @safe @nogc pure\n    bool decRef();\n}\n\n/**\nA reference counted struct that wraps the dynamic allocator interface.\nThis should be used wherever a uniform type is required for encapsulating\nvarious allocator implementations.\n\nCode that defines allocators ultimately implements the $(LREF IAllocator)\ninterface, possibly by using $(LREF CAllocatorImpl) below, and then build a\n`RCIAllocator` out of this.\n\nComposition of allocators is not recommended at this level due to\ninflexibility of dynamic interfaces and inefficiencies caused by cascaded\nmultiple calls. Instead, compose allocators using the static interface defined\nin $(A std_experimental_allocator_building_blocks.html,\n`std.experimental.allocator.building_blocks`), then adapt the composed\nallocator to `RCIAllocator` (possibly by using $(LREF allocatorObject) below).\n*/\nstruct RCIAllocator\n{\n    private IAllocator _alloc;\n\nnothrow:\n    private @nogc pure @safe\n    this(this _)(IAllocator alloc)\n    {\n        assert(alloc);\n        _alloc = alloc;\n    }\n\n    @nogc pure @safe\n    this(this)\n    {\n        if (_alloc !is null)\n        {\n            _alloc.incRef();\n        }\n    }\n\n    @nogc pure @safe\n    ~this()\n    {\n        if (_alloc !is null)\n        {\n            bool isLast = !_alloc.decRef();\n            if (isLast) _alloc = null;\n        }\n    }\n\n    @nogc pure @safe\n    auto ref opAssign()(typeof(this) rhs)\n    {\n        if (_alloc is rhs._alloc)\n        {\n            return this;\n        }\n        // incRef was allready called by rhs posblit, so we're just moving\n        // calling dtor is the equivalent of decRef\n        __dtor();\n        _alloc = rhs._alloc;\n        // move\n        rhs._alloc = null;\n        return this;\n    }\n\n    @nogc pure @safe\n    bool isNull(this _)()\n    {\n        return _alloc is null;\n    }\n\n    @property uint alignment()\n    {\n        assert(_alloc);\n        return _alloc.alignment();\n    }\n\n    size_t goodAllocSize(size_t s)\n    {\n        assert(_alloc);\n        return _alloc.goodAllocSize(s);\n    }\n\n    void[] allocate(size_t n, TypeInfo ti = null)\n    {\n        assert(_alloc);\n        return _alloc.allocate(n, ti);\n    }\n\n    void[] alignedAllocate(size_t n, uint a)\n    {\n        assert(_alloc);\n        return _alloc.alignedAllocate(n, a);\n    }\n\n    void[] allocateAll()\n    {\n        assert(_alloc);\n        return _alloc.allocateAll();\n    }\n\n    bool expand(ref void[] b, size_t size)\n    {\n        assert(_alloc);\n        return _alloc.expand(b, size);\n    }\n\n    bool reallocate(ref void[] b, size_t size)\n    {\n        assert(_alloc);\n        return _alloc.reallocate(b, size);\n    }\n\n    bool alignedReallocate(ref void[] b, size_t size, uint alignment)\n    {\n        assert(_alloc);\n        return _alloc.alignedReallocate(b, size, alignment);\n    }\n\n    Ternary owns(void[] b)\n    {\n        assert(_alloc);\n        return _alloc.owns(b);\n    }\n\n    Ternary resolveInternalPointer(const void* p, ref void[] result)\n    {\n        assert(_alloc);\n        return _alloc.resolveInternalPointer(p, result);\n    }\n\n    bool deallocate(void[] b)\n    {\n        assert(_alloc);\n        return _alloc.deallocate(b);\n    }\n\n    bool deallocateAll()\n    {\n        assert(_alloc);\n        return _alloc.deallocateAll();\n    }\n\n    Ternary empty()\n    {\n        assert(_alloc);\n        return _alloc.empty();\n    }\n}\n\n@system unittest\n{\n    import std.experimental.allocator.building_blocks.region : Region;\n    import std.conv : emplace;\n\n    auto reg = Region!()(new ubyte[1024]);\n    auto state = reg.allocate(stateSize!(CAllocatorImpl!(Region!(), Yes.indirect)));\n    auto regObj = emplace!(CAllocatorImpl!(Region!(), Yes.indirect))(state, &reg);\n\n    auto rcalloc = RCIAllocator(regObj);\n    auto b = rcalloc.allocate(10);\n    assert(b.length == 10);\n\n    // The reference counting is zero based\n    assert((cast(CAllocatorImpl!(Region!(), Yes.indirect))(rcalloc._alloc)).rc == 1);\n    {\n        auto rca2 = rcalloc;\n        assert((cast(CAllocatorImpl!(Region!(), Yes.indirect))(rcalloc._alloc)).rc == 2);\n    }\n    assert((cast(CAllocatorImpl!(Region!(), Yes.indirect))(rcalloc._alloc)).rc == 1);\n}\n\n@system unittest\n{\n    import std.conv;\n    import std.experimental.allocator.mallocator;\n    import std.experimental.allocator.building_blocks.stats_collector;\n\n    alias SCAlloc = StatsCollector!(Mallocator, Options.bytesUsed);\n    SCAlloc statsCollectorAlloc;\n\n    ulong bytesUsed = statsCollectorAlloc.bytesUsed;\n    assert(bytesUsed == 0);\n\n    {\n        auto _allocator = allocatorObject(&statsCollectorAlloc);\n        bytesUsed = statsCollectorAlloc.bytesUsed;\n        assert(bytesUsed == stateSize!(CAllocatorImpl!(SCAlloc, Yes.indirect)));\n    }\n\n    bytesUsed = statsCollectorAlloc.bytesUsed;\n    assert(bytesUsed == 0, \"RCIAllocator leaks memory; leaked \"\n            ~ to!string(bytesUsed) ~ \" bytes\");\n}\n\n@system unittest\n{\n    import std.conv;\n    import std.experimental.allocator.mallocator;\n    import std.experimental.allocator.building_blocks.stats_collector;\n\n    alias SCAlloc = StatsCollector!(Mallocator, Options.bytesUsed);\n    SCAlloc statsCollectorAlloc;\n\n    ulong bytesUsed = statsCollectorAlloc.bytesUsed;\n    assert(bytesUsed == 0);\n\n    {\n        auto _allocator = allocatorObject(statsCollectorAlloc);\n\n        // Ensure that the allocator was passed through in CAllocatorImpl\n        // This allocator was used to allocate the chunk that holds the\n        // CAllocatorImpl object; which is it's own wrapper\n        bytesUsed = (cast(CAllocatorImpl!(SCAlloc))(_allocator._alloc)).impl.bytesUsed;\n        assert(bytesUsed == stateSize!(CAllocatorImpl!(SCAlloc)),\n               \"RCIAllocator leaks memory; leaked \" ~ to!string(bytesUsed) ~ \" bytes\");\n        _allocator.allocate(1);\n        bytesUsed = (cast(CAllocatorImpl!(SCAlloc))(_allocator._alloc)).impl.bytesUsed;\n        assert(bytesUsed == stateSize!(CAllocatorImpl!(SCAlloc)) + 1,\n               \"RCIAllocator leaks memory; leaked \" ~ to!string(bytesUsed) ~ \" bytes\");\n    }\n\n    bytesUsed = statsCollectorAlloc.bytesUsed;\n    assert(bytesUsed == stateSize!(CAllocatorImpl!(SCAlloc)),\n            \"RCIAllocator leaks memory; leaked \"\n            ~ to!string(bytesUsed) ~ \" bytes\");\n}\n\n/**\nDynamic shared allocator interface. Code that defines allocators shareable\nacross threads ultimately implements this interface. This should be used\nwherever a uniform type is required for encapsulating various allocator\nimplementations.\n\nComposition of allocators is not recommended at this level due to\ninflexibility of dynamic interfaces and inefficiencies caused by cascaded\nmultiple calls. Instead, compose allocators using the static interface defined\nin $(MREF std,experimental,allocator,building_blocks),\nthen adapt the composed\nallocator to `ISharedAllocator` (possibly by using $(LREF CSharedAllocatorImpl) below).\n\nMethods returning `Ternary` return `Ternary.yes` upon success,\n`Ternary.no` upon failure, and `Ternary.unknown` if the primitive is not\nimplemented by the allocator instance.\n*/\ninterface ISharedAllocator\n{\nnothrow:\n    /**\n    Returns the alignment offered.\n    */\n    @property uint alignment() shared;\n\n    /**\n    Returns the good allocation size that guarantees zero internal\n    fragmentation.\n    */\n    size_t goodAllocSize(size_t s) shared;\n\n    /**\n    Allocates `n` bytes of memory.\n    */\n    void[] allocate(size_t, TypeInfo ti = null) shared;\n\n    /**\n    Allocates `n` bytes of memory with specified alignment `a`. Implementations\n    that do not support this primitive should always return `null`.\n    */\n    void[] alignedAllocate(size_t n, uint a) shared;\n\n    /**\n    Allocates and returns all memory available to this allocator.\n    Implementations that do not support this primitive should always return\n    `null`.\n    */\n    void[] allocateAll() shared;\n\n    /**\n    Expands a memory block in place and returns `true` if successful.\n    Implementations that don't support this primitive should always return\n    `false`.\n    */\n    bool expand(ref void[], size_t) shared;\n\n    /// Reallocates a memory block.\n    bool reallocate(ref void[], size_t) shared;\n\n    /// Reallocates a memory block with specified alignment.\n    bool alignedReallocate(ref void[] b, size_t size, uint alignment) shared;\n\n    /**\n    Returns `Ternary.yes` if the allocator owns `b`, `Ternary.no` if\n    the allocator doesn't own `b`, and `Ternary.unknown` if ownership\n    cannot be determined. Implementations that don't support this primitive\n    should always return `Ternary.unknown`.\n    */\n    Ternary owns(void[] b) shared;\n\n    /**\n    Resolves an internal pointer to the full block allocated. Implementations\n    that don't support this primitive should always return `Ternary.unknown`.\n    */\n    Ternary resolveInternalPointer(const void* p, ref void[] result) shared;\n\n    /**\n    Deallocates a memory block. Implementations that don't support this\n    primitive should always return `false`. A simple way to check that an\n    allocator supports deallocation is to call `deallocate(null)`.\n    */\n    bool deallocate(void[] b) shared;\n\n    /**\n    Deallocates all memory. Implementations that don't support this primitive\n    should always return `false`.\n    */\n    bool deallocateAll() shared;\n\n    /**\n    Returns `Ternary.yes` if no memory is currently allocated from this\n    allocator, `Ternary.no` if some allocations are currently active, or\n    `Ternary.unknown` if not supported.\n    */\n    Ternary empty() shared;\n\n    /**\n    Increases the reference count of the concrete class that implements this\n    interface.\n\n    For stateless allocators, this does nothing.\n    */\n    @safe @nogc pure\n    void incRef() shared;\n\n    /**\n    Decreases the reference count of the concrete class that implements this\n    interface.\n    When the reference count is `0`, the object self-destructs.\n\n    For stateless allocators, this does nothing.\n\n    Returns: `true` if the reference count is greater than `0` and `false` when\n    it hits `0`. For stateless allocators, it always returns `true`.\n    */\n    @safe @nogc pure\n    bool decRef() shared;\n}\n\n/**\nA reference counted struct that wraps the dynamic shared allocator interface.\nThis should be used wherever a uniform type is required for encapsulating\nvarious allocator implementations.\n\nCode that defines allocators shareable across threads ultimately implements the\n$(LREF ISharedAllocator) interface, possibly by using\n$(LREF CSharedAllocatorImpl) below, and then build a `RCISharedAllocator` out\nof this.\n\nComposition of allocators is not recommended at this level due to\ninflexibility of dynamic interfaces and inefficiencies caused by cascaded\nmultiple calls. Instead, compose allocators using the static interface defined\nin $(A std_experimental_allocator_building_blocks.html,\n`std.experimental.allocator.building_blocks`), then adapt the composed allocator\nto `RCISharedAllocator` (possibly by using $(LREF sharedAllocatorObject) below).\n*/\nshared struct RCISharedAllocator\n{\n    private ISharedAllocator _alloc;\n\nnothrow:\n    private @nogc pure @safe\n    this(shared ISharedAllocator alloc)\n    {\n        assert(alloc);\n        _alloc = alloc;\n    }\n\n    @nogc pure @safe\n    this(this)\n    {\n        if (_alloc !is null)\n        {\n            _alloc.incRef();\n        }\n    }\n\n    @nogc pure @safe\n    ~this()\n    {\n        if (_alloc !is null)\n        {\n            bool isLast = !_alloc.decRef();\n            if (isLast) _alloc = null;\n        }\n    }\n\n    @nogc pure @safe\n    auto ref opAssign()(RCISharedAllocator rhs)\n    {\n        if (_alloc is rhs._alloc)\n        {\n            return this;\n        }\n        // incRef was allready called by rhs posblit, so we're just moving\n        if (_alloc !is null)\n        {\n            _alloc.decRef();\n        }\n        _alloc = rhs._alloc;\n        // move\n        rhs._alloc = null;\n        return this;\n    }\n\n    @nogc pure @safe\n    bool isNull(this _)()\n    {\n        return _alloc is null;\n    }\n\n    @property uint alignment()\n    {\n        assert(_alloc);\n        return _alloc.alignment();\n    }\n\n    size_t goodAllocSize(size_t s)\n    {\n        assert(_alloc);\n        return _alloc.goodAllocSize(s);\n    }\n\n    void[] allocate(size_t n, TypeInfo ti = null)\n    {\n        assert(_alloc);\n        return _alloc.allocate(n, ti);\n    }\n\n    void[] alignedAllocate(size_t n, uint a)\n    {\n        assert(_alloc);\n        return _alloc.alignedAllocate(n, a);\n    }\n\n    void[] allocateAll()\n    {\n        assert(_alloc);\n        return _alloc.allocateAll();\n    }\n\n    bool expand(ref void[] b, size_t size)\n    {\n        assert(_alloc);\n        return _alloc.expand(b, size);\n    }\n\n    bool reallocate(ref void[] b, size_t size)\n    {\n        assert(_alloc);\n        return _alloc.reallocate(b, size);\n    }\n\n    bool alignedReallocate(ref void[] b, size_t size, uint alignment)\n    {\n        assert(_alloc);\n        return _alloc.alignedReallocate(b, size, alignment);\n    }\n\n    Ternary owns(void[] b)\n    {\n        assert(_alloc);\n        return _alloc.owns(b);\n    }\n\n    Ternary resolveInternalPointer(const void* p, ref void[] result)\n    {\n        assert(_alloc);\n        return _alloc.resolveInternalPointer(p, result);\n    }\n\n    bool deallocate(void[] b)\n    {\n        assert(_alloc);\n        return _alloc.deallocate(b);\n    }\n\n    bool deallocateAll()\n    {\n        assert(_alloc);\n        return _alloc.deallocateAll();\n    }\n\n    Ternary empty()\n    {\n        assert(_alloc);\n        return _alloc.empty();\n    }\n}\n\nprivate RCISharedAllocator _processAllocator;\nprivate RCIAllocator _threadAllocator;\n\n@nogc nothrow @safe\nprivate ref RCIAllocator setupThreadAllocator()\n{\n    /*\n    Forwards the `_threadAllocator` calls to the `processAllocator`\n    */\n    static class ThreadAllocator : IAllocator\n    {\n    nothrow:\n        private RCISharedAllocator _allocator;\n\n        @nogc @safe\n        this(ref RCISharedAllocator procAlloc)\n        {\n            _allocator = procAlloc;\n        }\n\n        override @property uint alignment()\n        {\n            return _allocator.alignment();\n        }\n\n        override size_t goodAllocSize(size_t s)\n        {\n            return _allocator.goodAllocSize(s);\n        }\n\n        override void[] allocate(size_t n, TypeInfo ti = null)\n        {\n            return _allocator.allocate(n, ti);\n        }\n\n        override void[] alignedAllocate(size_t n, uint a)\n        {\n            return _allocator.alignedAllocate(n, a);\n        }\n\n        override void[] allocateAll()\n        {\n            return _allocator.allocateAll();\n        }\n\n        override bool expand(ref void[] b, size_t size)\n        {\n            return _allocator.expand(b, size);\n        }\n\n        override bool reallocate(ref void[] b, size_t size)\n        {\n            return _allocator.reallocate(b, size);\n        }\n\n        override bool alignedReallocate(ref void[] b, size_t size, uint alignment)\n        {\n            return _allocator.alignedReallocate(b, size, alignment);\n        }\n\n        override Ternary owns(void[] b)\n        {\n            return _allocator.owns(b);\n        }\n\n        override Ternary resolveInternalPointer(const void* p, ref void[] result)\n        {\n            return _allocator.resolveInternalPointer(p, result);\n        }\n\n        override bool deallocate(void[] b)\n        {\n            return _allocator.deallocate(b);\n        }\n\n        override bool deallocateAll()\n        {\n            return _allocator.deallocateAll();\n        }\n\n        override Ternary empty()\n        {\n            return _allocator.empty();\n        }\n\n        @nogc pure @safe\n        override void incRef()\n        {\n            _allocator._alloc.incRef();\n        }\n\n        @nogc pure @safe\n        override bool decRef()\n        {\n            return _allocator._alloc.decRef();\n        }\n    }\n\n    assert(_threadAllocator.isNull);\n    import std.conv : emplace;\n    static ulong[stateSize!(ThreadAllocator).divideRoundUp(ulong.sizeof)] _threadAllocatorState;\n    () @trusted {\n        _threadAllocator = RCIAllocator(emplace!(ThreadAllocator)(_threadAllocatorState[], processAllocator()));\n    }();\n    return _threadAllocator;\n}\n\n// Fix threadAllocator bug: the threadAllocator should hold an internal reference\n// to the processAllocator that it's using\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    auto a = sharedAllocatorObject(Mallocator.instance);\n    auto buf = theAllocator.allocate(42);\n    processAllocator = a;\n    theAllocator.deallocate(buf);\n}\n\n/**\nGets/sets the allocator for the current thread. This is the default allocator\nthat should be used for allocating thread-local memory. For allocating memory\nto be shared across threads, use `processAllocator` (below). By default,\n`theAllocator` ultimately fetches memory from `processAllocator`, which\nin turn uses the garbage collected heap.\n*/\n@nogc nothrow @safe\n@property ref RCIAllocator theAllocator()\n{\n    alias p = _threadAllocator;\n    return !p.isNull() ? p : setupThreadAllocator();\n}\n\n/// Ditto\nnothrow @system @nogc\n@property void theAllocator(RCIAllocator a)\n{\n    assert(!a.isNull);\n    _threadAllocator = a;\n}\n\n///\n@system unittest\n{\n    // Install a new allocator that is faster for 128-byte allocations.\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    auto oldAllocator = theAllocator;\n    scope(exit) theAllocator = oldAllocator;\n    theAllocator = allocatorObject(FreeList!(GCAllocator, 128)());\n    // Use the now changed allocator to allocate an array\n    const ubyte[] arr = theAllocator.makeArray!ubyte(128);\n    assert(arr.ptr);\n    //...\n}\n\n/**\nGets/sets the allocator for the current process. This allocator must be used\nfor allocating memory shared across threads. Objects created using this\nallocator can be cast to `shared`.\n*/\n@nogc nothrow @trusted\n@property ref RCISharedAllocator processAllocator()\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.concurrency : initOnce;\n\n    static RCISharedAllocator* forceAttributes()\n    {\n        return &initOnce!_processAllocator(\n                sharedAllocatorObject(GCAllocator.instance));\n    }\n\n    return *(cast(RCISharedAllocator* function() @nogc nothrow)(&forceAttributes))();\n}\n\n/// Ditto\n@nogc nothrow @system\n@property void processAllocator(ref RCISharedAllocator a)\n{\n    assert(!a.isNull);\n    processAllocator() = a;\n}\n\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.exception : assertThrown;\n    import std.experimental.allocator.building_blocks.free_list : SharedFreeList;\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    assert(!processAllocator.isNull);\n    assert(!theAllocator.isNull);\n\n    testAllocatorObject(processAllocator);\n    testAllocatorObject(theAllocator);\n\n    shared SharedFreeList!(Mallocator, chooseAtRuntime, chooseAtRuntime) sharedFL;\n    RCISharedAllocator sharedFLObj = sharedAllocatorObject(sharedFL);\n    alias SharedAllocT = CSharedAllocatorImpl!(\n            shared SharedFreeList!(\n                Mallocator, chooseAtRuntime, chooseAtRuntime));\n\n    assert((cast(SharedAllocT)(sharedFLObj._alloc)).rc == 1);\n    assert(!sharedFLObj.isNull);\n    testAllocatorObject(sharedFLObj);\n\n    // Test processAllocator setter\n    RCISharedAllocator oldProcessAllocator = processAllocator;\n    processAllocator = sharedFLObj;\n    assert((cast(SharedAllocT)(sharedFLObj._alloc)).rc == 2);\n    assert(processAllocator._alloc is sharedFLObj._alloc);\n\n    testAllocatorObject(processAllocator);\n    testAllocatorObject(theAllocator);\n    assertThrown!AssertError(processAllocator = RCISharedAllocator(null));\n\n    // Restore initial processAllocator state\n    processAllocator = oldProcessAllocator;\n    assert((cast(SharedAllocT)(sharedFLObj._alloc)).rc == 1);\n    assert(processAllocator is oldProcessAllocator);\n\n    RCISharedAllocator indirectShFLObj = sharedAllocatorObject(&sharedFL);\n    testAllocatorObject(indirectShFLObj);\n    alias IndirectSharedAllocT = CSharedAllocatorImpl!(\n            shared SharedFreeList!(\n                Mallocator, chooseAtRuntime, chooseAtRuntime)\n            , Yes.indirect);\n\n    assert((cast(IndirectSharedAllocT)(indirectShFLObj._alloc)).rc == 1);\n\n    RCIAllocator indirectMallocator = allocatorObject(&Mallocator.instance);\n    testAllocatorObject(indirectMallocator);\n}\n\n/**\nDynamically allocates (using `alloc`) and then creates in the memory\nallocated an object of type `T`, using `args` (if any) for its\ninitialization. Initialization occurs in the memory allocated and is otherwise\nsemantically the same as `T(args)`.\n(Note that using `alloc.make!(T[])` creates a pointer to an (empty) array\nof `T`s, not an array. To use an allocator to allocate and initialize an\narray, use `alloc.makeArray!T` described below.)\n\nParams:\nT = Type of the object being created.\nalloc = The allocator used for getting the needed memory. It may be an object\nimplementing the static interface for allocators, or an `IAllocator`\nreference.\nargs = Optional arguments used for initializing the created object. If not\npresent, the object is default constructed.\n\nReturns: If `T` is a class type, returns a reference to the created `T`\nobject. Otherwise, returns a `T*` pointing to the created object. In all\ncases, returns `null` if allocation failed.\n\nThrows: If `T`'s constructor throws, deallocates the allocated memory and\npropagates the exception.\n*/\nauto make(T, Allocator, A...)(auto ref Allocator alloc, auto ref A args)\n{\n    import std.algorithm.comparison : max;\n    static if (!is(T == class) && !is(T == interface) && A.length == 0\n        && __traits(compiles, {T t;}) && __traits(isZeroInit, T)\n        && is(typeof(alloc.allocateZeroed(size_t.max))))\n    {\n        auto m = alloc.allocateZeroed(max(T.sizeof, 1));\n        return (() @trusted => cast(T*) m.ptr)();\n    }\n    else\n    {\n        import std.conv : emplace, emplaceRef;\n        auto m = alloc.allocate(max(stateSize!T, 1));\n        if (!m.ptr) return null;\n\n        // make can only be @safe if emplace or emplaceRef is `pure`\n        auto construct()\n        {\n            static if (is(T == class)) return emplace!T(m, args);\n            else\n            {\n                // Assume cast is safe as allocation succeeded for `stateSize!T`\n                auto p = () @trusted { return cast(T*) m.ptr; }();\n                emplaceRef(*p, args);\n                return p;\n            }\n        }\n\n        scope(failure)\n        {\n            static if (is(typeof(() pure { return construct(); })))\n            {\n                // Assume deallocation is safe because:\n                // 1) in case of failure, `m` is the only reference to this memory\n                // 2) `m` is known to originate from `alloc`\n                () @trusted { alloc.deallocate(m); }();\n            }\n            else\n            {\n                alloc.deallocate(m);\n            }\n        }\n\n        return construct();\n    }\n}\n\n///\n@system unittest\n{\n    // Dynamically allocate one integer\n    const int* p1 = theAllocator.make!int;\n    // It's implicitly initialized with its .init value\n    assert(*p1 == 0);\n    // Dynamically allocate one double, initialize to 42.5\n    const double* p2 = theAllocator.make!double(42.5);\n    assert(*p2 == 42.5);\n\n    // Dynamically allocate a struct\n    static struct Point\n    {\n        int x, y, z;\n    }\n    // Use the generated constructor taking field values in order\n    const Point* p = theAllocator.make!Point(1, 2);\n    assert(p.x == 1 && p.y == 2 && p.z == 0);\n\n    // Dynamically allocate a class object\n    static class Customer\n    {\n        uint id = uint.max;\n        this() {}\n        this(uint id) { this.id = id; }\n        // ...\n    }\n    Customer cust = theAllocator.make!Customer;\n    assert(cust.id == uint.max); // default initialized\n    cust = theAllocator.make!Customer(42);\n    assert(cust.id == 42);\n\n    // explicit passing of outer pointer\n    static class Outer\n    {\n        int x = 3;\n        class Inner\n        {\n            auto getX() { return x; }\n        }\n    }\n    auto outer = theAllocator.make!Outer();\n    auto inner = theAllocator.make!(Outer.Inner)(outer);\n    assert(outer.x == inner.getX);\n}\n\n@system unittest // bugzilla 15639 & 15772\n{\n    abstract class Foo {}\n    class Bar: Foo {}\n    static assert(!is(typeof(theAllocator.make!Foo)));\n    static assert( is(typeof(theAllocator.make!Bar)));\n}\n\n@system unittest\n{\n    void test(Allocator)(auto ref Allocator alloc)\n    {\n        const int* a = alloc.make!int(10);\n        assert(*a == 10);\n\n        struct A\n        {\n            int x;\n            string y;\n            double z;\n        }\n\n        A* b = alloc.make!A(42);\n        assert(b.x == 42);\n        assert(b.y is null);\n        import std.math : isNaN;\n        assert(b.z.isNaN);\n\n        b = alloc.make!A(43, \"44\", 45);\n        assert(b.x == 43);\n        assert(b.y == \"44\");\n        assert(b.z == 45);\n\n        static class B\n        {\n            int x;\n            string y;\n            double z;\n            this(int _x, string _y = null, double _z = double.init)\n            {\n                x = _x;\n                y = _y;\n                z = _z;\n            }\n        }\n\n        B c = alloc.make!B(42);\n        assert(c.x == 42);\n        assert(c.y is null);\n        assert(c.z.isNaN);\n\n        c = alloc.make!B(43, \"44\", 45);\n        assert(c.x == 43);\n        assert(c.y == \"44\");\n        assert(c.z == 45);\n\n        const parray = alloc.make!(int[]);\n        assert((*parray).empty);\n    }\n\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    test(GCAllocator.instance);\n    test(theAllocator);\n}\n\n// Attribute propagation\nnothrow @safe @nogc unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    alias alloc = Mallocator.instance;\n\n    void test(T, Args...)(auto ref Args args)\n    {\n        auto k = alloc.make!T(args);\n        () @trusted { alloc.dispose(k); }();\n    }\n\n    test!int;\n    test!(int*);\n    test!int(0);\n    test!(int*)(null);\n}\n\n// should be pure with the GCAllocator\n/*pure nothrow*/ @safe unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n\n    alias alloc = GCAllocator.instance;\n\n    void test(T, Args...)(auto ref Args args)\n    {\n        auto k = alloc.make!T(args);\n        (a) @trusted { a.dispose(k); }(alloc);\n    }\n\n    test!int();\n    test!(int*);\n    test!int(0);\n    test!(int*)(null);\n}\n\n// Verify that making an object by calling an impure constructor is not @safe\nnothrow @safe @nogc unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    static struct Pure { this(int) pure nothrow @nogc @safe {} }\n\n    cast(void) Mallocator.instance.make!Pure(0);\n\n    static int g = 0;\n    static struct Impure { this(int) nothrow @nogc @safe {\n        g++;\n    } }\n    static assert(!__traits(compiles, cast(void) Mallocator.instance.make!Impure(0)));\n}\n\n// test failure with a pure, failing struct\n@safe unittest\n{\n    import std.exception : assertThrown, enforce;\n\n    // this struct can't be initialized\n    struct InvalidStruct\n    {\n        this(int b)\n        {\n            enforce(1 == 2);\n        }\n    }\n    import std.experimental.allocator.mallocator : Mallocator;\n    assertThrown(make!InvalidStruct(Mallocator.instance, 42));\n}\n\n// test failure with an impure, failing struct\n@system unittest\n{\n    import std.exception : assertThrown, enforce;\n    static int g;\n    struct InvalidImpureStruct\n    {\n        this(int b)\n        {\n            g++;\n            enforce(1 == 2);\n        }\n    }\n    import std.experimental.allocator.mallocator : Mallocator;\n    assertThrown(make!InvalidImpureStruct(Mallocator.instance, 42));\n}\n\n// Don't allow zero-ctor-args `make` for structs with `@disable this();`\n@system unittest\n{\n    struct NoDefaultCtor\n    {\n        int i;\n        @disable this();\n    }\n    import std.experimental.allocator.mallocator : Mallocator;\n    static assert(!__traits(compiles, make!NoDefaultCtor(Mallocator.instance)),\n        \"Don't allow zero-ctor-args `make` for structs with `@disable this();`\");\n}\n\n@safe unittest // issue 18937\n{\n    static struct S\n    {\n        ubyte[16 * 1024] data;\n    }\n\n    static struct SomeAllocator\n    {\n        ubyte[] allocate(size_t) { return []; }\n        void deallocate(void[]) {}\n    }\n\n    auto x = SomeAllocator().make!S();\n}\n\nprivate void fillWithMemcpy(T)(scope void[] array, auto ref T filler) nothrow\nif (T.sizeof == 1)\n{\n    import core.stdc.string : memset;\n    import std.traits : CopyConstness;\n    if (!array.length) return;\n    memset(array.ptr, *cast(CopyConstness!(T*, ubyte*)) &filler, array.length);\n}\n\nprivate void fillWithMemcpy(T)(scope void[] array, auto ref T filler) nothrow\nif (T.sizeof != 1)\n{\n    import core.stdc.string : memcpy;\n    import std.algorithm.comparison : min;\n    if (!array.length) return;\n    memcpy(array.ptr, &filler, T.sizeof);\n    // Fill the array from the initialized portion of itself exponentially.\n    for (size_t offset = T.sizeof; offset < array.length; )\n    {\n        size_t extent = min(offset, array.length - offset);\n        memcpy(array.ptr + offset, array.ptr, extent);\n        offset += extent;\n    }\n}\n\n@system unittest\n{\n    // Test T.sizeof == 1 path of fillWithMemcpy.\n    ubyte[] a;\n    fillWithMemcpy(a, ubyte(42));\n    assert(a.length == 0);\n    a = [ 1, 2, 3, 4, 5 ];\n    fillWithMemcpy(a, ubyte(42));\n    assert(a == [ 42, 42, 42, 42, 42]);\n}\n\n@system unittest\n{\n    int[] a;\n    fillWithMemcpy(a, 42);\n    assert(a.length == 0);\n    a = [ 1, 2, 3, 4, 5 ];\n    fillWithMemcpy(a, 42);\n    assert(a == [ 42, 42, 42, 42, 42]);\n}\n\nprivate T[] uninitializedFillDefault(T)(T[] array) nothrow\n{\n    static if (__traits(isZeroInit, T))\n    {\n        import core.stdc.string : memset;\n        if (array !is null)\n            memset(array.ptr, 0, T.sizeof * array.length);\n        return array;\n    }\n    else static if (is(Unqual!T == char) || is(Unqual!T == wchar))\n    {\n        import core.stdc.string : memset;\n        if (array !is null)\n            memset(array.ptr, 0xff, T.sizeof * array.length);\n        return array;\n    }\n    else\n    {\n        T t = T.init;\n        fillWithMemcpy(array, t);\n        return array;\n    }\n}\n\npure nothrow @nogc\n@system unittest\n{\n    static struct S { int x = 42; @disable this(this); }\n\n    int[5] expected = [42, 42, 42, 42, 42];\n    S[5] arr = void;\n    uninitializedFillDefault(arr);\n    assert((cast(int*) arr.ptr)[0 .. arr.length] == expected);\n}\n\n@system unittest\n{\n    int[] a = [1, 2, 4];\n    uninitializedFillDefault(a);\n    assert(a == [0, 0, 0]);\n\n    char[] b = [1, 2, 4];\n    uninitializedFillDefault(b);\n    assert(b == [0xff, 0xff, 0xff]);\n\n    wchar[] c = [1, 2, 4];\n    uninitializedFillDefault(c);\n    assert(c == [0xffff, 0xffff, 0xffff]);\n}\n\n@system unittest\n{\n    static struct P { float x = 0; float y = 0; }\n\n    static assert(__traits(isZeroInit, P));\n    P[] a = [P(10, 11), P(20, 21), P(40, 41)];\n    uninitializedFillDefault(a);\n    assert(a == [P.init, P.init, P.init]);\n}\n\n/**\nCreate an array of `T` with `length` elements using `alloc`. The array is either default-initialized, filled with copies of `init`, or initialized with values fetched from `range`.\n\nParams:\nT = element type of the array being created\nalloc = the allocator used for getting memory\nlength = length of the newly created array\ninit = element used for filling the array\nrange = range used for initializing the array elements\n\nReturns:\nThe newly-created array, or `null` if either `length` was `0` or\nallocation failed.\n\nThrows:\nThe first two overloads throw only if `alloc`'s primitives do. The\noverloads that involve copy initialization deallocate memory and propagate the\nexception if the copy operation throws.\n*/\nT[] makeArray(T, Allocator)(auto ref Allocator alloc, size_t length)\n{\n    if (!length) return null;\n    static if (T.sizeof <= 1)\n    {\n        const nAlloc = length * T.sizeof;\n    }\n    else\n    {\n        import core.checkedint : mulu;\n        bool overflow;\n        const nAlloc = mulu(length, T.sizeof, overflow);\n        if (overflow) return null;\n    }\n\n    static if (__traits(isZeroInit, T) && hasMember!(Allocator, \"allocateZeroed\"))\n    {\n        auto m = alloc.allocateZeroed(nAlloc);\n        return (() @trusted => cast(T[]) m)();\n    }\n    else\n    {\n        auto m = alloc.allocate(nAlloc);\n        if (!m.ptr) return null;\n        alias U = Unqual!T;\n        return () @trusted { return cast(T[]) uninitializedFillDefault(cast(U[]) m); }();\n    }\n}\n\n@system unittest\n{\n    void test1(A)(auto ref A alloc)\n    {\n        int[] a = alloc.makeArray!int(0);\n        assert(a.length == 0 && a.ptr is null);\n        a = alloc.makeArray!int(5);\n        assert(a.length == 5);\n        static immutable cheatsheet = [0, 0, 0, 0, 0];\n        assert(a == cheatsheet);\n    }\n\n    void test2(A)(auto ref A alloc)\n    {\n        static struct S { int x = 42; @disable this(this); }\n        S[] arr = alloc.makeArray!S(5);\n        assert(arr.length == 5);\n        int[] arrInt = () @trusted { return (cast(int*) arr.ptr)[0 .. 5]; }();\n        static immutable res = [42, 42, 42, 42, 42];\n        assert(arrInt == res);\n    }\n\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n    (alloc) /*pure nothrow*/ @safe { test1(alloc); test2(alloc);} (GCAllocator.instance);\n    (alloc) nothrow @safe @nogc { test1(alloc); test2(alloc);} (Mallocator.instance);\n    test2(theAllocator);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    auto a = theAllocator.makeArray!(shared int)(5);\n    static assert(is(typeof(a) == shared(int)[]));\n    assert(a.length == 5);\n    assert(a.equal([0, 0, 0, 0, 0]));\n\n    auto b = theAllocator.makeArray!(const int)(5);\n    static assert(is(typeof(b) == const(int)[]));\n    assert(b.length == 5);\n    assert(b.equal([0, 0, 0, 0, 0]));\n\n    auto c = theAllocator.makeArray!(immutable int)(5);\n    static assert(is(typeof(c) == immutable(int)[]));\n    assert(c.length == 5);\n    assert(c.equal([0, 0, 0, 0, 0]));\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=19085 - makeArray with void\n@system unittest\n{\n    auto b = theAllocator.makeArray!void(5);\n    scope(exit) theAllocator.dispose(b);\n    auto c = cast(ubyte[]) b;\n    assert(c.length == 5);\n    assert(c == [0, 0, 0, 0, 0]); // default initialization\n}\n\nprivate enum hasPurePostblit(T) = !hasElaborateCopyConstructor!T ||\n    is(typeof(() pure { T.init.__xpostblit(); }));\n\nprivate enum hasPureDtor(T) = !hasElaborateDestructor!T ||\n    is(typeof(() pure { T.init.__xdtor(); }));\n\n// `true` when postblit and destructor of T cannot escape references to itself\nprivate enum canSafelyDeallocPostRewind(T) = hasPurePostblit!T && hasPureDtor!T;\n\n/// Ditto\nT[] makeArray(T, Allocator)(auto ref Allocator alloc, size_t length, T init)\n{\n    if (!length) return null;\n    auto m = alloc.allocate(T.sizeof * length);\n    if (!m.ptr) return null;\n    auto result = () @trusted { return cast(T[]) m; } ();\n    import std.traits : hasElaborateCopyConstructor;\n    static if (hasElaborateCopyConstructor!T)\n    {\n        scope(failure)\n        {\n            static if (canSafelyDeallocPostRewind!T)\n                () @trusted { alloc.deallocate(m); } ();\n            else\n                alloc.deallocate(m);\n        }\n\n        size_t i = 0;\n        static if (hasElaborateDestructor!T)\n        {\n            scope (failure)\n            {\n                foreach (j; 0 .. i)\n                {\n                    destroy(result[j]);\n                }\n            }\n        }\n        import std.conv : emplace;\n        for (; i < length; ++i)\n        {\n            emplace!T(&result[i], init);\n        }\n    }\n    else\n    {\n        alias U = Unqual!T;\n        () @trusted { fillWithMemcpy(cast(U[]) result, *(cast(U*) &init)); }();\n    }\n    return result;\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    static void test(T)()\n    {\n        T[] a = theAllocator.makeArray!T(2);\n        assert(a.equal([0, 0]));\n        a = theAllocator.makeArray!T(3, 42);\n        assert(a.equal([42, 42, 42]));\n        import std.range : only;\n        a = theAllocator.makeArray!T(only(42, 43, 44));\n        assert(a.equal([42, 43, 44]));\n    }\n    test!int();\n    test!(shared int)();\n    test!(const int)();\n    test!(immutable int)();\n}\n\n@system unittest\n{\n    void test(T)(in T initialValue)\n    {\n        auto t = theAllocator.makeArray!T(100, initialValue);\n        //auto t = theAllocator.makeArray(100, initialValue); // works well with the old code\n    }\n\n    const int init = 3;\n    test(init);\n}\n\n@system unittest\n{\n    void test(A)(auto ref A alloc)\n    {\n        long[] a = alloc.makeArray!long(0, 42);\n        assert(a.length == 0 && a.ptr is null);\n        a = alloc.makeArray!long(5, 42);\n        assert(a.length == 5);\n        assert(a == [ 42, 42, 42, 42, 42 ]);\n    }\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    (alloc) /*pure nothrow*/ @safe { test(alloc); } (GCAllocator.instance);\n    test(theAllocator);\n}\n\n// test failure with a pure, failing struct\n@safe unittest\n{\n    import std.exception : assertThrown, enforce;\n\n    struct NoCopy\n    {\n        @disable this();\n\n        this(int b){}\n\n        // can't be copied\n        this(this)\n        {\n            enforce(1 == 2);\n        }\n    }\n    import std.experimental.allocator.mallocator : Mallocator;\n    assertThrown(makeArray!NoCopy(Mallocator.instance, 10, NoCopy(42)));\n}\n\n// test failure with an impure, failing struct\n@system unittest\n{\n    import std.exception : assertThrown, enforce;\n\n    static int i = 0;\n    struct Singleton\n    {\n        @disable this();\n\n        this(int b){}\n\n        // can't be copied\n        this(this)\n        {\n            enforce(i++ == 0);\n        }\n\n        ~this()\n        {\n            i--;\n        }\n    }\n    import std.experimental.allocator.mallocator : Mallocator;\n    assertThrown(makeArray!Singleton(Mallocator.instance, 10, Singleton(42)));\n}\n\n/// Ditto\nUnqual!(ElementEncodingType!R)[] makeArray(Allocator, R)(auto ref Allocator alloc, R range)\nif (isInputRange!R && !isInfinite!R)\n{\n    alias T = Unqual!(ElementEncodingType!R);\n    return makeArray!(T, Allocator, R)(alloc, range);\n}\n\n/// Ditto\nT[] makeArray(T, Allocator, R)(auto ref Allocator alloc, R range)\nif (isInputRange!R && !isInfinite!R)\n{\n    static if (isForwardRange!R || hasLength!R)\n    {\n        static if (hasLength!R || isNarrowString!R)\n            immutable length = range.length;\n        else\n            immutable length = range.save.walkLength;\n\n        if (!length) return null;\n        auto m = alloc.allocate(T.sizeof * length);\n        if (!m.ptr) return null;\n        auto result = () @trusted { return cast(T[]) m; } ();\n\n        size_t i = 0;\n        scope (failure)\n        {\n            foreach (j; 0 .. i)\n            {\n                auto p = () @trusted { return cast(Unqual!T*) &result[j]; }();\n                destroy(p);\n            }\n\n            static if (canSafelyDeallocPostRewind!T)\n                () @trusted { alloc.deallocate(m); } ();\n            else\n                alloc.deallocate(m);\n        }\n\n        import std.conv : emplaceRef;\n        static if (isNarrowString!R || isRandomAccessRange!R)\n        {\n            foreach (j; 0 .. range.length)\n            {\n                emplaceRef!T(result[i++], range[j]);\n            }\n        }\n        else\n        {\n            for (; !range.empty; range.popFront, ++i)\n            {\n                emplaceRef!T(result[i], range.front);\n            }\n        }\n\n        return result;\n    }\n    else\n    {\n        // Estimated size\n        size_t estimated = 8;\n        auto m = alloc.allocate(T.sizeof * estimated);\n        if (!m.ptr) return null;\n        auto result = () @trusted { return cast(T[]) m; } ();\n\n        size_t initialized = 0;\n        void bailout()\n        {\n            foreach (i; 0 .. initialized + 1)\n            {\n                destroy(result[i]);\n            }\n\n            static if (canSafelyDeallocPostRewind!T)\n                () @trusted { alloc.deallocate(m); } ();\n            else\n                alloc.deallocate(m);\n        }\n        scope (failure) bailout;\n\n        for (; !range.empty; range.popFront, ++initialized)\n        {\n            if (initialized == estimated)\n            {\n                // Need to reallocate\n                static if (hasPurePostblit!T)\n                    auto success = () @trusted { return alloc.reallocate(m, T.sizeof * (estimated *= 2)); } ();\n                else\n                    auto success = alloc.reallocate(m, T.sizeof * (estimated *= 2));\n                if (!success)\n                {\n                    bailout;\n                    return null;\n                }\n                result = () @trusted { return cast(T[]) m; } ();\n            }\n            import std.conv : emplaceRef;\n            emplaceRef(result[initialized], range.front);\n        }\n\n        if (initialized < estimated)\n        {\n            // Try to shrink memory, no harm if not possible\n            static if (hasPurePostblit!T)\n                auto success = () @trusted { return alloc.reallocate(m, T.sizeof * initialized); } ();\n            else\n                auto success = alloc.reallocate(m, T.sizeof * initialized);\n            if (success)\n                result = () @trusted { return cast(T[]) m; } ();\n        }\n\n        return result[0 .. initialized];\n    }\n}\n\n@system unittest\n{\n    void test(A)(auto ref A alloc)\n    {\n        long[] a = alloc.makeArray!long((int[]).init);\n        assert(a.length == 0 && a.ptr is null);\n        a = alloc.makeArray!long([5, 42]);\n        assert(a.length == 2);\n        assert(a == [ 5, 42]);\n\n        // we can also infer the type\n        auto b = alloc.makeArray([4.0, 2.0]);\n        static assert(is(typeof(b) == double[]));\n        assert(b == [4.0, 2.0]);\n    }\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    (alloc) pure nothrow @safe { test(alloc); } (GCAllocator.instance);\n    test(theAllocator);\n}\n\n// infer types for strings\n@system unittest\n{\n    void test(A)(auto ref A alloc)\n    {\n        auto c = alloc.makeArray(\"fooπ😜\");\n        static assert(is(typeof(c) == char[]));\n        assert(c == \"fooπ😜\");\n\n        auto d = alloc.makeArray(\"fooπ😜\"d);\n        static assert(is(typeof(d) == dchar[]));\n        assert(d == \"fooπ😜\");\n\n        auto w = alloc.makeArray(\"fooπ😜\"w);\n        static assert(is(typeof(w) == wchar[]));\n        assert(w == \"fooπ😜\");\n    }\n\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    (alloc) pure nothrow @safe { test(alloc); } (GCAllocator.instance);\n    test(theAllocator);\n}\n\n/*pure*/ nothrow @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.internal.test.dummyrange;\n    import std.range : iota;\n    foreach (DummyType; AllDummyRanges)\n    {\n        (alloc) pure nothrow @safe\n        {\n            DummyType d;\n            auto arr = alloc.makeArray(d);\n            assert(arr.length == 10);\n            assert(arr.equal(iota(1, 11)));\n        } (GCAllocator.instance);\n    }\n}\n\n// test failure with a pure, failing struct\n@safe unittest\n{\n    import std.exception : assertThrown, enforce;\n\n    struct NoCopy\n    {\n        int b;\n\n        @disable this();\n\n        this(int b)\n        {\n            this.b = b;\n        }\n\n        // can't be copied\n        this(this)\n        {\n            enforce(b < 3, \"there can only be three elements\");\n        }\n    }\n    import std.experimental.allocator.mallocator : Mallocator;\n    auto arr = [NoCopy(1), NoCopy(2), NoCopy(3)];\n    assertThrown(makeArray!NoCopy(Mallocator.instance, arr));\n\n    struct NoCopyRange\n    {\n        static j = 0;\n        bool empty()\n        {\n            return j > 5;\n        }\n\n        auto front()\n        {\n            return NoCopy(j);\n        }\n\n        void popFront()\n        {\n            j++;\n        }\n    }\n    assertThrown(makeArray!NoCopy(Mallocator.instance, NoCopyRange()));\n}\n\n// test failure with an impure, failing struct\n@system unittest\n{\n    import std.exception : assertThrown, enforce;\n\n    static i = 0;\n    static maxElements = 2;\n    struct NoCopy\n    {\n        int val;\n        @disable this();\n\n        this(int b){\n            this.val = i++;\n        }\n\n        // can't be copied\n        this(this)\n        {\n            enforce(i++ < maxElements, \"there can only be four elements\");\n        }\n    }\n\n    import std.experimental.allocator.mallocator : Mallocator;\n    auto arr = [NoCopy(1), NoCopy(2)];\n    assertThrown(makeArray!NoCopy(Mallocator.instance, arr));\n\n    // allow more copies and thus force reallocation\n    i = 0;\n    maxElements = 30;\n    static j = 0;\n\n    struct NoCopyRange\n    {\n        bool empty()\n        {\n            return j > 100;\n        }\n\n        auto front()\n        {\n            return NoCopy(1);\n        }\n\n        void popFront()\n        {\n            j++;\n        }\n    }\n    assertThrown(makeArray!NoCopy(Mallocator.instance, NoCopyRange()));\n\n    maxElements = 300;\n    auto arr2 = makeArray!NoCopy(Mallocator.instance, NoCopyRange());\n\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    import std.range : iota;\n    assert(arr2.map!`a.val`.equal(iota(32, 204, 2)));\n}\n\nversion (unittest)\n{\n    private struct ForcedInputRange\n    {\n        int[]* array;\n        pure nothrow @safe @nogc:\n        bool empty() { return !array || (*array).empty; }\n        ref int front() { return (*array)[0]; }\n        void popFront() { *array = (*array)[1 .. $]; }\n    }\n}\n\n@system unittest\n{\n    import std.array : array;\n    import std.range : iota;\n    int[] arr = iota(10).array;\n\n    void test(A)(auto ref A alloc)\n    {\n        ForcedInputRange r;\n        long[] a = alloc.makeArray!long(r);\n        assert(a.length == 0 && a.ptr is null);\n        auto arr2 = arr;\n        r.array = () @trusted { return &arr2; } ();\n        a = alloc.makeArray!long(r);\n        assert(a.length == 10);\n        assert(a == iota(10).array);\n    }\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    (alloc) pure nothrow @safe { test(alloc); } (GCAllocator.instance);\n    test(theAllocator);\n}\n\n/**\nGrows `array` by appending `delta` more elements. The needed memory is\nallocated using `alloc`. The extra elements added are either default-\ninitialized, filled with copies of `init`, or initialized with values\nfetched from `range`.\n\nParams:\nT = element type of the array being created\nalloc = the allocator used for getting memory\narray = a reference to the array being grown\ndelta = number of elements to add (upon success the new length of `array` is\n$(D array.length + delta))\ninit = element used for filling the array\nrange = range used for initializing the array elements\n\nReturns:\n`true` upon success, `false` if memory could not be allocated. In the\nlatter case `array` is left unaffected.\n\nThrows:\nThe first two overloads throw only if `alloc`'s primitives do. The\noverloads that involve copy initialization deallocate memory and propagate the\nexception if the copy operation throws.\n*/\nbool expandArray(T, Allocator)(auto ref Allocator alloc, ref T[] array,\n        size_t delta)\n{\n    if (!delta) return true;\n    if (array is null) return false;\n    immutable oldLength = array.length;\n    void[] buf = array;\n    if (!alloc.reallocate(buf, buf.length + T.sizeof * delta)) return false;\n    array = cast(T[]) buf;\n    array[oldLength .. $].uninitializedFillDefault;\n    return true;\n}\n\n@system unittest\n{\n    void test(A)(auto ref A alloc)\n    {\n        auto arr = alloc.makeArray!int([1, 2, 3]);\n        assert(alloc.expandArray(arr, 3));\n        assert(arr == [1, 2, 3, 0, 0, 0]);\n    }\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    test(GCAllocator.instance);\n    test(theAllocator);\n}\n\n/// Ditto\nbool expandArray(T, Allocator)(auto ref Allocator alloc, ref T[] array,\n    size_t delta, auto ref T init)\n{\n    if (!delta) return true;\n    if (array is null) return false;\n    void[] buf = array;\n    if (!alloc.reallocate(buf, buf.length + T.sizeof * delta)) return false;\n    immutable oldLength = array.length;\n    array = cast(T[]) buf;\n    scope(failure) array[oldLength .. $].uninitializedFillDefault;\n    import std.algorithm.mutation : uninitializedFill;\n    array[oldLength .. $].uninitializedFill(init);\n    return true;\n}\n\n@system unittest\n{\n    void test(A)(auto ref A alloc)\n    {\n        auto arr = alloc.makeArray!int([1, 2, 3]);\n        assert(alloc.expandArray(arr, 3, 1));\n        assert(arr == [1, 2, 3, 1, 1, 1]);\n    }\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    test(GCAllocator.instance);\n    test(theAllocator);\n}\n\n/// Ditto\nbool expandArray(T, Allocator, R)(auto ref Allocator alloc, ref T[] array,\n        R range)\nif (isInputRange!R)\n{\n    if (array is null) return false;\n    static if (isForwardRange!R)\n    {\n        immutable delta = walkLength(range.save);\n        if (!delta) return true;\n        immutable oldLength = array.length;\n\n        // Reallocate support memory\n        void[] buf = array;\n        if (!alloc.reallocate(buf, buf.length + T.sizeof * delta))\n        {\n            return false;\n        }\n        array = cast(T[]) buf;\n        // At this point we're committed to the new length.\n\n        auto toFill = array[oldLength .. $];\n        scope (failure)\n        {\n            // Fill the remainder with default-constructed data\n            toFill.uninitializedFillDefault;\n        }\n\n        for (; !range.empty; range.popFront, toFill.popFront)\n        {\n            assert(!toFill.empty);\n            import std.conv : emplace;\n            emplace!T(&toFill.front, range.front);\n        }\n        assert(toFill.empty);\n    }\n    else\n    {\n        scope(failure)\n        {\n            // The last element didn't make it, fill with default\n            array[$ - 1 .. $].uninitializedFillDefault;\n        }\n        void[] buf = array;\n        for (; !range.empty; range.popFront)\n        {\n            if (!alloc.reallocate(buf, buf.length + T.sizeof))\n            {\n                array = cast(T[]) buf;\n                return false;\n            }\n            import std.conv : emplace;\n            emplace!T(buf[$ - T.sizeof .. $], range.front);\n        }\n\n        array = cast(T[]) buf;\n    }\n    return true;\n}\n\n///\n@system unittest\n{\n    auto arr = theAllocator.makeArray!int([1, 2, 3]);\n    assert(theAllocator.expandArray(arr, 2));\n    assert(arr == [1, 2, 3, 0, 0]);\n    import std.range : only;\n    assert(theAllocator.expandArray(arr, only(4, 5)));\n    assert(arr == [1, 2, 3, 0, 0, 4, 5]);\n}\n\n@system unittest\n{\n    auto arr = theAllocator.makeArray!int([1, 2, 3]);\n    ForcedInputRange r;\n    int[] b = [ 1, 2, 3, 4 ];\n    auto temp = b;\n    r.array = &temp;\n    assert(theAllocator.expandArray(arr, r));\n    assert(arr == [1, 2, 3, 1, 2, 3, 4]);\n}\n\n/**\nShrinks an array by `delta` elements.\n\nIf $(D array.length < delta), does nothing and returns `false`. Otherwise,\ndestroys the last $(D array.length - delta) elements in the array and then\nreallocates the array's buffer. If reallocation fails, fills the array with\ndefault-initialized data.\n\nParams:\nT = element type of the array being created\nalloc = the allocator used for getting memory\narray = a reference to the array being shrunk\ndelta = number of elements to remove (upon success the new length of `array` is $(D array.length - delta))\n\nReturns:\n`true` upon success, `false` if memory could not be reallocated. In the latter\ncase, the slice $(D array[$ - delta .. $]) is left with default-initialized\nelements.\n\nThrows:\nThe first two overloads throw only if `alloc`'s primitives do. The\noverloads that involve copy initialization deallocate memory and propagate the\nexception if the copy operation throws.\n*/\nbool shrinkArray(T, Allocator)(auto ref Allocator alloc,\n        ref T[] array, size_t delta)\n{\n    if (delta > array.length) return false;\n\n    // Destroy elements. If a destructor throws, fill the already destroyed\n    // stuff with the default initializer.\n    {\n        size_t destroyed;\n        scope(failure)\n        {\n            array[$ - delta .. $][0 .. destroyed].uninitializedFillDefault;\n        }\n        foreach (ref e; array[$ - delta .. $])\n        {\n            e.destroy;\n            ++destroyed;\n        }\n    }\n\n    if (delta == array.length)\n    {\n        alloc.deallocate(array);\n        array = null;\n        return true;\n    }\n\n    void[] buf = array;\n    if (!alloc.reallocate(buf, buf.length - T.sizeof * delta))\n    {\n        // urgh, at least fill back with default\n        array[$ - delta .. $].uninitializedFillDefault;\n        return false;\n    }\n    array = cast(T[]) buf;\n    return true;\n}\n\n///\n@system unittest\n{\n    int[] a = theAllocator.makeArray!int(100, 42);\n    assert(a.length == 100);\n    assert(theAllocator.shrinkArray(a, 98));\n    assert(a.length == 2);\n    assert(a == [42, 42]);\n}\n\n@system unittest\n{\n    void test(A)(auto ref A alloc)\n    {\n        long[] a = alloc.makeArray!long((int[]).init);\n        assert(a.length == 0 && a.ptr is null);\n        a = alloc.makeArray!long(100, 42);\n        assert(alloc.shrinkArray(a, 98));\n        assert(a.length == 2);\n        assert(a == [ 42, 42]);\n    }\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    test(GCAllocator.instance);\n    test(theAllocator);\n}\n\n/**\n\nDestroys and then deallocates (using `alloc`) the object pointed to by a\npointer, the class object referred to by a `class` or `interface`\nreference, or an entire array. It is assumed the respective entities had been\nallocated with the same allocator.\n\n*/\nvoid dispose(A, T)(auto ref A alloc, auto ref T* p)\n{\n    static if (hasElaborateDestructor!T)\n    {\n        destroy(*p);\n    }\n    alloc.deallocate((cast(void*) p)[0 .. T.sizeof]);\n    static if (__traits(isRef, p))\n        p = null;\n}\n\n/// Ditto\nvoid dispose(A, T)(auto ref A alloc, auto ref T p)\nif (is(T == class) || is(T == interface))\n{\n    if (!p) return;\n    static if (is(T == interface))\n    {\n        version (Windows)\n        {\n            import core.sys.windows.unknwn : IUnknown;\n            static assert(!is(T: IUnknown), \"COM interfaces can't be destroyed in \"\n                ~ __PRETTY_FUNCTION__);\n        }\n        auto ob = cast(Object) p;\n    }\n    else\n        alias ob = p;\n    auto support = (cast(void*) ob)[0 .. typeid(ob).initializer.length];\n    destroy(p);\n    alloc.deallocate(support);\n    static if (__traits(isRef, p))\n        p = null;\n}\n\n/// Ditto\nvoid dispose(A, T)(auto ref A alloc, auto ref T[] array)\n{\n    static if (hasElaborateDestructor!(typeof(array[0])))\n    {\n        foreach (ref e; array)\n        {\n            destroy(e);\n        }\n    }\n    alloc.deallocate(array);\n    static if (__traits(isRef, array))\n        array = null;\n}\n\n@system unittest\n{\n    static int x;\n    static interface I\n    {\n        void method();\n    }\n    static class A : I\n    {\n        int y;\n        override void method() { x = 21; }\n        ~this() { x = 42; }\n    }\n    static class B : A\n    {\n    }\n    auto a = theAllocator.make!A;\n    a.method();\n    assert(x == 21);\n    theAllocator.dispose(a);\n    assert(x == 42);\n\n    B b = theAllocator.make!B;\n    b.method();\n    assert(x == 21);\n    theAllocator.dispose(b);\n    assert(x == 42);\n\n    I i = theAllocator.make!B;\n    i.method();\n    assert(x == 21);\n    theAllocator.dispose(i);\n    assert(x == 42);\n\n    int[] arr = theAllocator.makeArray!int(43);\n    theAllocator.dispose(arr);\n}\n\n@system unittest //bugzilla 16512\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    int* i = Mallocator.instance.make!int(0);\n    Mallocator.instance.dispose(i);\n    assert(i is null);\n\n    Object o = Mallocator.instance.make!Object();\n    Mallocator.instance.dispose(o);\n    assert(o is null);\n\n    uint* u = Mallocator.instance.make!uint(0);\n    Mallocator.instance.dispose((){return u;}());\n    assert(u !is null);\n\n    uint[] ua = Mallocator.instance.makeArray!uint([0,1,2]);\n    Mallocator.instance.dispose(ua);\n    assert(ua is null);\n}\n\n@system unittest //bugzilla 15721\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    interface Foo {}\n    class Bar: Foo {}\n\n    Bar bar;\n    Foo foo;\n    bar = Mallocator.instance.make!Bar;\n    foo = cast(Foo) bar;\n    Mallocator.instance.dispose(foo);\n}\n\n/**\nAllocates a multidimensional array of elements of type T.\n\nParams:\nN = number of dimensions\nT = element type of an element of the multidimensional arrat\nalloc = the allocator used for getting memory\nlengths = static array containing the size of each dimension\n\nReturns:\nAn N-dimensional array with individual elements of type T.\n*/\nauto makeMultidimensionalArray(T, Allocator, size_t N)(auto ref Allocator alloc, size_t[N] lengths...)\n{\n    static if (N == 1)\n    {\n        return makeArray!T(alloc, lengths[0]);\n    }\n    else\n    {\n        alias E = typeof(makeMultidimensionalArray!(T, Allocator, N - 1)(alloc, lengths[1 .. $]));\n        auto ret = makeArray!E(alloc, lengths[0]);\n        foreach (ref e; ret)\n            e = makeMultidimensionalArray!(T, Allocator, N - 1)(alloc, lengths[1 .. $]);\n        return ret;\n    }\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    auto mArray = Mallocator.instance.makeMultidimensionalArray!int(2, 3, 6);\n\n    // deallocate when exiting scope\n    scope(exit)\n    {\n        Mallocator.instance.disposeMultidimensionalArray(mArray);\n    }\n\n    assert(mArray.length == 2);\n    foreach (lvl2Array; mArray)\n    {\n        assert(lvl2Array.length == 3);\n        foreach (lvl3Array; lvl2Array)\n            assert(lvl3Array.length == 6);\n    }\n}\n\n/**\nDestroys and then deallocates a multidimensional array, assuming it was\ncreated with makeMultidimensionalArray and the same allocator was used.\n\nParams:\nT = element type of an element of the multidimensional array\nalloc = the allocator used for getting memory\narray = the multidimensional array that is to be deallocated\n*/\nvoid disposeMultidimensionalArray(T, Allocator)(auto ref Allocator alloc, auto ref T[] array)\n{\n    static if (isArray!T)\n    {\n        foreach (ref e; array)\n            disposeMultidimensionalArray(alloc, e);\n    }\n\n    dispose(alloc, array);\n    static if (__traits(isRef, array))\n        array = null;\n}\n\n///\n@system unittest\n{\n    struct TestAllocator\n    {\n        import std.experimental.allocator.common : platformAlignment;\n        import std.experimental.allocator.mallocator : Mallocator;\n\n        alias allocator = Mallocator.instance;\n\n        private static struct ByteRange\n        {\n            void* ptr;\n            size_t length;\n        }\n\n        private ByteRange[] _allocations;\n\n        enum uint alignment = platformAlignment;\n\n        void[] allocate(size_t numBytes)\n        {\n             auto ret = allocator.allocate(numBytes);\n             _allocations ~= ByteRange(ret.ptr, ret.length);\n             return ret;\n        }\n\n        bool deallocate(void[] bytes)\n        {\n            import std.algorithm.mutation : remove;\n            import std.algorithm.searching : canFind;\n\n            bool pred(ByteRange other)\n            { return other.ptr == bytes.ptr && other.length == bytes.length; }\n\n            assert(_allocations.canFind!pred);\n\n             _allocations = _allocations.remove!pred;\n             return allocator.deallocate(bytes);\n        }\n\n        ~this()\n        {\n            assert(!_allocations.length);\n        }\n    }\n\n    TestAllocator allocator;\n\n    auto mArray = allocator.makeMultidimensionalArray!int(2, 3, 5, 6, 7, 2);\n\n    allocator.disposeMultidimensionalArray(mArray);\n}\n\n/**\n\nReturns a dynamically-typed `CAllocator` built around a given statically-\ntyped allocator `a` of type `A`. Passing a pointer to the allocator\ncreates a dynamic allocator around the allocator pointed to by the pointer,\nwithout attempting to copy or move it. Passing the allocator by value or\nreference behaves as follows.\n\n$(UL\n$(LI If `A` has no state, the resulting object is allocated in static\nshared storage.)\n$(LI If `A` has state, the result will $(REF move, std,algorithm,mutation)\nthe supplied allocator $(D A a) within. The result itself is allocated in its\nown statically-typed allocator.)\n)\n\n*/\nRCIAllocator allocatorObject(A)(auto ref A a)\nif (!isPointer!A)\n{\n    import std.conv : emplace;\n    static if (stateSize!A == 0)\n    {\n        enum s = stateSize!(CAllocatorImpl!A).divideRoundUp(ulong.sizeof);\n        __gshared ulong[s] state;\n        __gshared RCIAllocator result;\n        if (result.isNull)\n        {\n            // Don't care about a few races\n            result = RCIAllocator(emplace!(CAllocatorImpl!A)(state[]));\n        }\n        assert(!result.isNull);\n        return result;\n    }\n    else\n    {\n        auto state = a.allocate(stateSize!(CAllocatorImpl!A));\n        import std.algorithm.mutation : move;\n        import std.traits : hasMember;\n        static if (hasMember!(A, \"deallocate\"))\n        {\n            scope(failure) a.deallocate(state);\n        }\n        auto tmp = cast(CAllocatorImpl!A) emplace!(CAllocatorImpl!A)(state);\n        move(a, tmp.impl);\n        return RCIAllocator(tmp);\n    }\n}\n\n/// Ditto\nRCIAllocator allocatorObject(A)(A* pa)\n{\n    assert(pa);\n    import std.conv : emplace;\n    auto state = pa.allocate(stateSize!(CAllocatorImpl!(A, Yes.indirect)));\n    import std.traits : hasMember;\n    static if (hasMember!(A, \"deallocate\"))\n    {\n        scope(failure) pa.deallocate(state);\n    }\n    return RCIAllocator(emplace!(CAllocatorImpl!(A, Yes.indirect))\n                            (state, pa));\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    RCIAllocator a = allocatorObject(Mallocator.instance);\n    auto b = a.allocate(100);\n    assert(b.length == 100);\n    assert(a.deallocate(b));\n\n    // The in-situ region must be used by pointer\n    import std.experimental.allocator.building_blocks.region : InSituRegion;\n    auto r = InSituRegion!1024();\n    a = allocatorObject(&r);\n    b = a.allocate(200);\n    assert(b.length == 200);\n    // In-situ regions can deallocate the last allocation\n    assert(a.deallocate(b));\n}\n\n@system unittest\n{\n    import std.conv;\n    import std.experimental.allocator.mallocator;\n    import std.experimental.allocator.building_blocks.stats_collector;\n\n    alias SCAlloc = StatsCollector!(Mallocator, Options.bytesUsed);\n    SCAlloc statsCollectorAlloc;\n    assert(statsCollectorAlloc.bytesUsed == 0);\n\n    auto _allocator = allocatorObject(statsCollectorAlloc);\n    // Ensure that the allocator was passed through in CAllocatorImpl\n    // This allocator was used to allocate the chunk that holds the\n    // CAllocatorImpl object; which is it's own wrapper\n    assert((cast(CAllocatorImpl!(SCAlloc))(_allocator._alloc)).impl.bytesUsed\n            == stateSize!(CAllocatorImpl!(SCAlloc)));\n    _allocator.allocate(1);\n    assert((cast(CAllocatorImpl!(SCAlloc))(_allocator._alloc)).impl.bytesUsed\n            == stateSize!(CAllocatorImpl!(SCAlloc)) + 1);\n}\n\n/**\n\nReturns a dynamically-typed `CSharedAllocator` built around a given statically-\ntyped allocator `a` of type `A`. Passing a pointer to the allocator\ncreates a dynamic allocator around the allocator pointed to by the pointer,\nwithout attempting to copy or move it. Passing the allocator by value or\nreference behaves as follows.\n\n$(UL\n$(LI If `A` has no state, the resulting object is allocated in static\nshared storage.)\n$(LI If `A` has state and is copyable, the result will\n$(REF move, std,algorithm,mutation) the supplied allocator $(D A a) within.\nThe result itself is allocated in its own statically-typed allocator.)\n$(LI If `A` has state and is not copyable, the result will move the\npassed-in argument into the result. The result itself is allocated in its own\nstatically-typed allocator.)\n)\n\n*/\n//nothrow @safe\n//nothrow @nogc @safe\nnothrow\nRCISharedAllocator sharedAllocatorObject(A)(auto ref A a)\nif (!isPointer!A)\n{\n    import std.conv : emplace;\n    static if (stateSize!A == 0)\n    {\n        enum s = stateSize!(CSharedAllocatorImpl!A).divideRoundUp(ulong.sizeof);\n        static shared ulong[s] state;\n        static RCISharedAllocator result;\n        if (result.isNull)\n        {\n            // Don't care about a few races\n            result = RCISharedAllocator(\n                    (cast(shared CSharedAllocatorImpl!A)(\n                        emplace!(CSharedAllocatorImpl!A)(\n                            (() @trusted => cast(ulong[]) state[])()))));\n        }\n        assert(!result.isNull);\n        return result;\n    }\n    else static if (is(typeof({ shared A b = a; shared A c = b; }))) // copyable\n    {\n        auto state = a.allocate(stateSize!(CSharedAllocatorImpl!A));\n        import std.algorithm.mutation : move;\n        import std.traits : hasMember;\n        static if (hasMember!(A, \"deallocate\"))\n        {\n            scope(failure) a.deallocate(state);\n        }\n        auto tmp = emplace!(shared CSharedAllocatorImpl!A)(state);\n        move(a, tmp.impl);\n        return RCISharedAllocator(tmp);\n    }\n    else // the allocator object is not copyable\n    {\n        assert(0, \"Not yet implemented\");\n    }\n}\n\n/// Ditto\nRCISharedAllocator sharedAllocatorObject(A)(A* pa)\n{\n    assert(pa);\n    import std.conv : emplace;\n    auto state = pa.allocate(stateSize!(CSharedAllocatorImpl!(A, Yes.indirect)));\n    import std.traits : hasMember;\n    static if (hasMember!(A, \"deallocate\"))\n    {\n        scope(failure) pa.deallocate(state);\n    }\n    return RCISharedAllocator(emplace!(shared CSharedAllocatorImpl!(A, Yes.indirect))(state, pa));\n}\n\n\n/**\n\nImplementation of `IAllocator` using `Allocator`. This adapts a\nstatically-built allocator type to `IAllocator` that is directly usable by\nnon-templated code.\n\nUsually `CAllocatorImpl` is used indirectly by calling $(LREF theAllocator).\n*/\nclass CAllocatorImpl(Allocator, Flag!\"indirect\" indirect = No.indirect)\n    : IAllocator\n{\n    import std.traits : hasMember;\n\n    static if (stateSize!Allocator) private size_t rc = 1;\n\n    /**\n    The implementation is available as a public member.\n    */\n    static if (indirect)\n    {\n    nothrow:\n        private Allocator* pimpl;\n\n        @nogc pure @safe\n        ref Allocator impl()\n        {\n            return *pimpl;\n        }\n\n        @nogc pure @safe\n        this(Allocator* pa)\n        {\n            pimpl = pa;\n        }\n    }\n    else\n    {\n        static if (stateSize!Allocator) Allocator impl;\n        else alias impl = Allocator.instance;\n    }\n\nnothrow:\n    /// Returns `impl.alignment`.\n    override @property uint alignment()\n    {\n        return impl.alignment;\n    }\n\n    /**\n    Returns `impl.goodAllocSize(s)`.\n    */\n    override size_t goodAllocSize(size_t s)\n    {\n        return impl.goodAllocSize(s);\n    }\n\n    /**\n    Returns `impl.allocate(s)`.\n    */\n    override void[] allocate(size_t s, TypeInfo ti = null)\n    {\n        return impl.allocate(s);\n    }\n\n    /**\n    If `impl.alignedAllocate` exists, calls it and returns the result.\n    Otherwise, always returns `null`.\n    */\n    override void[] alignedAllocate(size_t s, uint a)\n    {\n        static if (hasMember!(Allocator, \"alignedAllocate\"))\n            return impl.alignedAllocate(s, a);\n        else\n            return null;\n    }\n\n    /**\n    If `Allocator` implements `owns`, forwards to it. Otherwise, returns\n    `Ternary.unknown`.\n    */\n    override Ternary owns(void[] b)\n    {\n        static if (hasMember!(Allocator, \"owns\")) return impl.owns(b);\n        else return Ternary.unknown;\n    }\n\n    /// Returns $(D impl.expand(b, s)) if defined, `false` otherwise.\n    override bool expand(ref void[] b, size_t s)\n    {\n        static if (hasMember!(Allocator, \"expand\"))\n            return impl.expand(b, s);\n        else\n            return s == 0;\n    }\n\n    /// Returns $(D impl.reallocate(b, s)).\n    override bool reallocate(ref void[] b, size_t s)\n    {\n        return impl.reallocate(b, s);\n    }\n\n    /// Forwards to `impl.alignedReallocate` if defined, `false` otherwise.\n    bool alignedReallocate(ref void[] b, size_t s, uint a)\n    {\n        static if (!hasMember!(Allocator, \"alignedAllocate\"))\n        {\n            return false;\n        }\n        else\n        {\n            return impl.alignedReallocate(b, s, a);\n        }\n    }\n\n    // Undocumented for now\n    Ternary resolveInternalPointer(const void* p, ref void[] result)\n    {\n        static if (hasMember!(Allocator, \"resolveInternalPointer\"))\n        {\n            return impl.resolveInternalPointer(p, result);\n        }\n        else\n        {\n            return Ternary.unknown;\n        }\n    }\n\n    /**\n    If `impl.deallocate` is not defined, returns `false`. Otherwise it forwards\n    the call.\n    */\n    override bool deallocate(void[] b)\n    {\n        static if (hasMember!(Allocator, \"deallocate\"))\n        {\n            return impl.deallocate(b);\n        }\n        else\n        {\n            return false;\n        }\n    }\n\n    /**\n    Calls `impl.deallocateAll()` and returns the result if defined,\n    otherwise returns `false`.\n    */\n    override bool deallocateAll()\n    {\n        static if (hasMember!(Allocator, \"deallocateAll\"))\n        {\n            return impl.deallocateAll();\n        }\n        else\n        {\n            return false;\n        }\n    }\n\n    /**\n    Forwards to `impl.empty()` if defined, otherwise returns `Ternary.unknown`.\n    */\n    override Ternary empty()\n    {\n        static if (hasMember!(Allocator, \"empty\"))\n        {\n            return Ternary(impl.empty);\n        }\n        else\n        {\n            return Ternary.unknown;\n        }\n    }\n\n    /**\n    Returns `impl.allocateAll()` if present, `null` otherwise.\n    */\n    override void[] allocateAll()\n    {\n        static if (hasMember!(Allocator, \"allocateAll\"))\n        {\n            return impl.allocateAll();\n        }\n        else\n        {\n            return null;\n        }\n    }\n\n    @nogc nothrow pure @safe\n    override void incRef()\n    {\n        static if (stateSize!Allocator) ++rc;\n    }\n\n    @nogc nothrow pure @trusted\n    override bool decRef()\n    {\n        static if (stateSize!Allocator)\n        {\n            import core.stdc.string : memcpy;\n\n            if (rc == 1)\n            {\n                static if (indirect)\n                {\n                    Allocator* tmp = pimpl;\n                }\n                else\n                {\n                    Allocator tmp;\n                    memcpy(&tmp, &this.impl, Allocator.sizeof);\n                }\n                void[] support = (cast(void*) this)[0 .. stateSize!(typeof(this))];\n                tmp.deallocate(support);\n                return false;\n            }\n\n            --rc;\n            return true;\n        }\n        else\n        {\n            return true;\n        }\n    }\n}\n\n/**\n\nImplementation of `ISharedAllocator` using `Allocator`. This adapts a\nstatically-built, shareable across threads, allocator type to `ISharedAllocator`\nthat is directly usable by non-templated code.\n\nUsually `CSharedAllocatorImpl` is used indirectly by calling\n$(LREF processAllocator).\n*/\nclass CSharedAllocatorImpl(Allocator, Flag!\"indirect\" indirect = No.indirect)\n    : ISharedAllocator\n{\n    import std.traits : hasMember;\n    import core.atomic : atomicOp, atomicLoad;\n\n    static if (stateSize!Allocator) shared size_t rc = 1;\n\n    /**\n    The implementation is available as a public member.\n    */\n    static if (indirect)\n    {\n    nothrow:\n        private shared Allocator* pimpl;\n\n        @nogc pure @safe\n        ref Allocator impl() shared\n        {\n            return *pimpl;\n        }\n\n        @nogc pure @safe\n        this(Allocator* pa) shared\n        {\n            pimpl = pa;\n        }\n    }\n    else\n    {\n        static if (stateSize!Allocator) shared Allocator impl;\n        else alias impl = Allocator.instance;\n    }\n\nnothrow:\n    /// Returns `impl.alignment`.\n    override @property uint alignment() shared\n    {\n        return impl.alignment;\n    }\n\n    /**\n    Returns `impl.goodAllocSize(s)`.\n    */\n    override size_t goodAllocSize(size_t s) shared\n    {\n        return impl.goodAllocSize(s);\n    }\n\n    /**\n    Returns `impl.allocate(s)`.\n    */\n    override void[] allocate(size_t s, TypeInfo ti = null) shared\n    {\n        return impl.allocate(s);\n    }\n\n    /**\n    If `impl.alignedAllocate` exists, calls it and returns the result.\n    Otherwise, always returns `null`.\n    */\n    override void[] alignedAllocate(size_t s, uint a) shared\n    {\n        static if (hasMember!(Allocator, \"alignedAllocate\"))\n            return impl.alignedAllocate(s, a);\n        else\n            return null;\n    }\n\n    /**\n    If `Allocator` implements `owns`, forwards to it. Otherwise, returns\n    `Ternary.unknown`.\n    */\n    override Ternary owns(void[] b) shared\n    {\n        static if (hasMember!(Allocator, \"owns\")) return impl.owns(b);\n        else return Ternary.unknown;\n    }\n\n    /// Returns $(D impl.expand(b, s)) if defined, `false` otherwise.\n    override bool expand(ref void[] b, size_t s) shared\n    {\n        static if (hasMember!(Allocator, \"expand\"))\n            return impl.expand(b, s);\n        else\n            return s == 0;\n    }\n\n    /// Returns $(D impl.reallocate(b, s)).\n    override bool reallocate(ref void[] b, size_t s) shared\n    {\n        return impl.reallocate(b, s);\n    }\n\n    /// Forwards to `impl.alignedReallocate` if defined, `false` otherwise.\n    bool alignedReallocate(ref void[] b, size_t s, uint a) shared\n    {\n        static if (!hasMember!(Allocator, \"alignedAllocate\"))\n        {\n            return false;\n        }\n        else\n        {\n            return impl.alignedReallocate(b, s, a);\n        }\n    }\n\n    // Undocumented for now\n    Ternary resolveInternalPointer(const void* p, ref void[] result) shared\n    {\n        static if (hasMember!(Allocator, \"resolveInternalPointer\"))\n        {\n            return impl.resolveInternalPointer(p, result);\n        }\n        else\n        {\n            return Ternary.unknown;\n        }\n    }\n\n    /**\n    If `impl.deallocate` is not defined, returns `false`. Otherwise it forwards\n    the call.\n    */\n    override bool deallocate(void[] b) shared\n    {\n        static if (hasMember!(Allocator, \"deallocate\"))\n        {\n            return impl.deallocate(b);\n        }\n        else\n        {\n            return false;\n        }\n    }\n\n    /**\n    Calls `impl.deallocateAll()` and returns the result if defined,\n    otherwise returns `false`.\n    */\n    override bool deallocateAll() shared\n    {\n        static if (hasMember!(Allocator, \"deallocateAll\"))\n        {\n            return impl.deallocateAll();\n        }\n        else\n        {\n            return false;\n        }\n    }\n\n    /**\n    Forwards to `impl.empty()` if defined, otherwise returns `Ternary.unknown`.\n    */\n    override Ternary empty() shared\n    {\n        static if (hasMember!(Allocator, \"empty\"))\n        {\n            return Ternary(impl.empty);\n        }\n        else\n        {\n            return Ternary.unknown;\n        }\n    }\n\n    /**\n    Returns `impl.allocateAll()` if present, `null` otherwise.\n    */\n    override void[] allocateAll() shared\n    {\n        static if (hasMember!(Allocator, \"allocateAll\"))\n        {\n            return impl.allocateAll();\n        }\n        else\n        {\n            return null;\n        }\n    }\n\n    @nogc nothrow pure @safe\n    override void incRef() shared\n    {\n        static if (stateSize!Allocator) atomicOp!\"+=\"(rc, 1);\n    }\n\n    @nogc nothrow pure @trusted\n    override bool decRef() shared\n    {\n        static if (stateSize!Allocator)\n        {\n            import core.stdc.string : memcpy;\n\n            // rc starts as 1 to avoid comparing with size_t(0) - 1\n            if (atomicOp!\"-=\"(rc, 1) == 0)\n            {\n                static if (indirect)\n                {\n                    Allocator* tmp = pimpl;\n                }\n                else\n                {\n                    Allocator tmp;\n                    memcpy(cast(void*) &tmp, cast(void*) &this.impl, Allocator.sizeof);\n                    Allocator empty;\n                    memcpy(cast(void*) &this.impl, cast(void*) &empty, Allocator.sizeof);\n                }\n                void[] support = (cast(void*) this)[0 .. stateSize!(typeof(this))];\n                (cast(bool delegate(void[]) @nogc nothrow pure)(&tmp.deallocate))(support);\n                return false;\n            }\n            return true;\n        }\n        else\n        {\n            return true;\n        }\n    }\n}\n\n\n// Example in intro above\n@system unittest\n{\n    // Allocate an int, initialize it with 42\n    int* p = theAllocator.make!int(42);\n    assert(*p == 42);\n\n    // Destroy and deallocate it\n    theAllocator.dispose(p);\n\n    // Allocate using the global process allocator\n    p = processAllocator.make!int(100);\n    assert(*p == 100);\n\n    // Destroy and deallocate\n    processAllocator.dispose(p);\n\n    // Create an array of 50 doubles initialized to -1.0\n    double[] arr = theAllocator.makeArray!double(50, -1.0);\n\n    // Check internal pointer\n    void[] result;\n    assert(theAllocator.resolveInternalPointer(null, result) == Ternary.no);\n    Ternary r = theAllocator.resolveInternalPointer(arr.ptr, result);\n    assert(result.ptr is arr.ptr && result.length >= arr.length);\n\n    // Append two zeros to it\n    theAllocator.expandArray(arr, 2, 0.0);\n    // On second thought, take that back\n    theAllocator.shrinkArray(arr, 2);\n    // Destroy and deallocate\n    theAllocator.dispose(arr);\n}\n\n__EOF__\n\n/**\n\nStores an allocator object in thread-local storage (i.e. non-`shared` D\nglobal). `ThreadLocal!A` is a subtype of `A` so it appears to implement\n`A`'s allocator primitives.\n\n`A` must hold state, otherwise `ThreadLocal!A` refuses instantiation. This\nmeans e.g. `ThreadLocal!Mallocator` does not work because `Mallocator`'s\nstate is not stored as members of `Mallocator`, but instead is hidden in the\nC library implementation.\n\n*/\nstruct ThreadLocal(A)\n{\n    static assert(stateSize!A,\n        typeof(A).stringof\n        ~ \" does not have state so it cannot be used with ThreadLocal\");\n\n    /**\n    The allocator instance.\n    */\n    static A instance;\n\n    /**\n    `ThreadLocal!A` is a subtype of `A` so it appears to implement `A`'s\n    allocator primitives.\n    */\n    alias instance this;\n\n    /**\n    `ThreadLocal` disables all constructors. The intended usage is\n    `ThreadLocal!A.instance`.\n    */\n    @disable this();\n    /// Ditto\n    @disable this(this);\n}\n\n///\nunittest\n{\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    static assert(!is(ThreadLocal!Mallocator));\n    static assert(!is(ThreadLocal!GCAllocator));\n    alias ThreadLocal!(FreeList!(GCAllocator, 0, 8)) Allocator;\n    auto b = Allocator.instance.allocate(5);\n    static assert(hasMember!(Allocator, \"allocate\"));\n}\n\n/*\n(Not public.)\n\nA binary search tree that uses no allocation of its own. Instead, it relies on\nuser code to allocate nodes externally. Then `EmbeddedTree`'s primitives wire\nthe nodes appropriately.\n\nWarning: currently `EmbeddedTree` is not using rebalancing, so it may\ndegenerate. A red-black tree implementation storing the color with one of the\npointers is planned for the future.\n*/\nprivate struct EmbeddedTree(T, alias less)\n{\n    static struct Node\n    {\n        T payload;\n        Node* left, right;\n    }\n\n    private Node* root;\n\n    private Node* insert(Node* n, ref Node* backref)\n    {\n        backref = n;\n        n.left = n.right = null;\n        return n;\n    }\n\n    Node* find(Node* data)\n    {\n        for (auto n = root; n; )\n        {\n            if (less(data, n))\n            {\n                n = n.left;\n            }\n            else if (less(n, data))\n            {\n                n = n.right;\n            }\n            else\n            {\n                return n;\n            }\n        }\n        return null;\n    }\n\n    Node* insert(Node* data)\n    {\n        if (!root)\n        {\n            root = data;\n            data.left = data.right = null;\n            return root;\n        }\n        auto n = root;\n        for (;;)\n        {\n            if (less(data, n))\n            {\n                if (!n.left)\n                {\n                    // Found insertion point\n                    return insert(data, n.left);\n                }\n                n = n.left;\n            }\n            else if (less(n, data))\n            {\n                if (!n.right)\n                {\n                    // Found insertion point\n                    return insert(data, n.right);\n                }\n                n = n.right;\n            }\n            else\n            {\n                // Found\n                return n;\n            }\n            if (!n) return null;\n        }\n    }\n\n    Node* remove(Node* data)\n    {\n        auto n = root;\n        Node* parent = null;\n        for (;;)\n        {\n            if (!n) return null;\n            if (less(data, n))\n            {\n                parent = n;\n                n = n.left;\n            }\n            else if (less(n, data))\n            {\n                parent = n;\n                n = n.right;\n            }\n            else\n            {\n                // Found\n                remove(n, parent);\n                return n;\n            }\n        }\n    }\n\n    private void remove(Node* n, Node* parent)\n    {\n        assert(n);\n        assert(!parent || parent.left == n || parent.right == n);\n        Node** referrer = parent\n            ? (parent.left == n ? &parent.left : &parent.right)\n            : &root;\n        if (!n.left)\n        {\n            *referrer = n.right;\n        }\n        else if (!n.right)\n        {\n            *referrer = n.left;\n        }\n        else\n        {\n            // Find the leftmost child in the right subtree\n            auto leftmost = n.right;\n            Node** leftmostReferrer = &n.right;\n            while (leftmost.left)\n            {\n                leftmostReferrer = &leftmost.left;\n                leftmost = leftmost.left;\n            }\n            // Unlink leftmost from there\n            *leftmostReferrer = leftmost.right;\n            // Link leftmost in lieu of n\n            leftmost.left = n.left;\n            leftmost.right = n.right;\n            *referrer = leftmost;\n        }\n    }\n\n    Ternary empty() const\n    {\n        return Ternary(!root);\n    }\n\n    void dump()\n    {\n        import std.stdio;\n        writeln(typeid(this), \" @ \", cast(void*) &this);\n        dump(root, 3);\n    }\n\n    void dump(Node* r, uint indent)\n    {\n        import std.stdio;\n        import std.range : repeat;\n        import std.array : array;\n\n        write(repeat(' ', indent).array);\n        if (!r)\n        {\n            writeln(\"(null)\");\n            return;\n        }\n        writeln(r.payload, \" @ \", cast(void*) r);\n        dump(r.left, indent + 3);\n        dump(r.right, indent + 3);\n    }\n\n    void assertSane()\n    {\n        static bool isBST(Node* r, Node* lb, Node* ub)\n        {\n            if (!r) return true;\n            if (lb && !less(lb, r)) return false;\n            if (ub && !less(r, ub)) return false;\n            return isBST(r.left, lb, r) &&\n                isBST(r.right, r, ub);\n        }\n        if (isBST(root, null, null)) return;\n        dump;\n        assert(0);\n    }\n}\n\nunittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n\n    alias a = GCAllocator.instance;\n    alias Tree = EmbeddedTree!(int, (a, b) => a.payload < b.payload);\n    Tree t;\n    assert(t.empty == Ternary.yes);\n    int[] vals = [ 6, 3, 9, 1, 0, 2, 8, 11 ];\n    foreach (v; vals)\n    {\n        auto n = new Tree.Node(v, null, null);\n        assert(t.insert(n));\n        assert(n);\n        t.assertSane;\n    }\n    assert(t.empty != Ternary.yes);\n    foreach (v; vals)\n    {\n        Tree.Node n = { v };\n        assert(t.remove(&n));\n        t.assertSane;\n    }\n    assert(t.empty == Ternary.yes);\n}\n\n/*\n\n`InternalPointersTree` adds a primitive on top of another allocator: calling\n`resolveInternalPointer(p)` returns the block within which the internal\npointer `p` lies. Pointers right after the end of allocated blocks are also\nconsidered internal.\n\nThe implementation stores three additional words with each allocation (one for\nthe block size and two for search management).\n\n*/\nprivate struct InternalPointersTree(Allocator)\n{\n    import std.experimental.allocator.building_blocks.affix_allocator : AffixAllocator;\n\n    alias Tree = EmbeddedTree!(size_t,\n        (a, b) => cast(void*) a + a.payload < cast(void*) b);\n    alias Parent = AffixAllocator!(Allocator, Tree.Node);\n\n    // Own state\n    private Tree blockMap;\n\n    alias alignment = Parent.alignment;\n\n    /**\n    The implementation is available as a public member.\n    */\n    static if (stateSize!Parent) Parent parent;\n    else alias parent = Parent.instance;\n\n    /// Allocator API.\n    void[] allocate(size_t bytes)\n    {\n        auto r = parent.allocate(bytes);\n        if (!r.ptr) return r;\n        Tree.Node* n = &parent.prefix(r);\n        n.payload = bytes;\n        blockMap.insert(n) || assert(0);\n        return r;\n    }\n\n    /// Ditto\n    bool deallocate(void[] b)\n    {\n        if (!b.ptr) return true;\n        Tree.Node* n = &parent.prefix(b);\n        blockMap.remove(n) || assert(false);\n        parent.deallocate(b);\n        return true;\n    }\n\n    /// Ditto\n    static if (hasMember!(Allocator, \"reallocate\"))\n    bool reallocate(ref void[] b, size_t s)\n    {\n        auto n = &parent.prefix(b);\n        assert(n.payload == b.length);\n        blockMap.remove(n) || assert(0);\n        if (!parent.reallocate(b, s))\n        {\n            // Failed, must reinsert the same node in the tree\n            assert(n.payload == b.length);\n            blockMap.insert(n) || assert(0);\n            return false;\n        }\n        // Insert the new node\n        n = &parent.prefix(b);\n        n.payload = s;\n        blockMap.insert(n) || assert(0);\n        return true;\n    }\n\n    /// Ditto\n    Ternary owns(void[] b)\n    {\n        void[] result;\n        return resolveInternalPointer(b.ptr, result);\n    }\n\n    /// Ditto\n    Ternary empty()\n    {\n        return Ternary(blockMap.empty);\n    }\n\n    /** Returns the block inside which `p` resides, or `null` if the\n    pointer does not belong.\n    */\n    pure nothrow @safe @nogc\n    Ternary resolveInternalPointer(const void* p, ref void[] result)\n    {\n        // Must define a custom find\n        Tree.Node* find()\n        {\n            for (auto n = blockMap.root; n; )\n            {\n                if (p < n)\n                {\n                    n = n.left;\n                }\n                else if ((() @trusted => p > (cast(void*) (n + 1)) + n.payload)())\n                {\n                    n = n.right;\n                }\n                else\n                {\n                    return n;\n                }\n            }\n            return null;\n        }\n\n        auto n = find();\n        if (!n) return Ternary.no;\n        result = (() @trusted => (cast(void*) (n + 1))[0 .. n.payload])();\n        return Ternary.yes;\n    }\n}\n\nunittest\n{\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.random : randomCover;\n\n    InternalPointersTree!(Mallocator) a;\n    int[] vals = [ 6, 3, 9, 1, 2, 8, 11 ];\n    void[][] allox;\n    foreach (v; vals)\n    {\n        allox ~= a.allocate(v);\n    }\n    a.blockMap.assertSane;\n\n    foreach (b; allox)\n    {\n        () pure nothrow @safe {\n            void[] p;\n            Ternary r = (() @nogc => a.resolveInternalPointer(&b[0], p))();\n            assert(&p[0] == &b[0] && p.length >= b.length);\n            r = a.resolveInternalPointer((() @trusted => &b[0] + b.length)(), p);\n            assert(&p[0] == &b[0] && p.length >= b.length);\n            r = a.resolveInternalPointer((() @trusted => &b[0] + b.length / 2)(), p);\n            assert(&p[0] == &b[0] && p.length >= b.length);\n            auto bogus = new void[b.length];\n            assert(a.resolveInternalPointer(&bogus[0], p) == Ternary.no);\n        }();\n    }\n\n    foreach (b; allox.randomCover)\n    {\n        () nothrow @nogc { a.deallocate(b); }();\n    }\n\n    assert(a.empty == Ternary.yes);\n}\n\n//version (std_allocator_benchmark)\nunittest\n{\n    import std.experimental.allocator.building_blocks.null_allocator : NullAllocator;\n    import std.experimental.allocator.building_blocks.allocator_list : AllocatorList;\n    import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlock;\n    import std.experimental.allocator.building_blocks.segregator : Segregator;\n    import std.experimental.allocator.building_blocks.bucketizer : Bucketizer;\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    static void testSpeed(A)()\n    {\n        static if (stateSize!A) A a;\n        else alias a = A.instance;\n\n        void[][128] bufs;\n\n        import std.random;\n        foreach (i; 0 .. 100_000)\n        {\n            auto j = uniform(0, bufs.length);\n            switch (uniform(0, 2))\n            {\n            case 0:\n                () nothrow @nogc { a.deallocate(bufs[j]); }();\n                bufs[j] = a.allocate(uniform(0, 4096));\n                break;\n            case 1:\n                () nothrow @nogc { a.deallocate(bufs[j]); }();\n                bufs[j] = null;\n                break;\n            default:\n                assert(0);\n            }\n        }\n    }\n\n    import std.algorithm.comparison : max;\n\n    alias FList = FreeList!(GCAllocator, 0, unbounded);\n    alias A = Segregator!(\n        8, FreeList!(GCAllocator, 0, 8),\n        128, Bucketizer!(FList, 1, 128, 16),\n        256, Bucketizer!(FList, 129, 256, 32),\n        512, Bucketizer!(FList, 257, 512, 64),\n        1024, Bucketizer!(FList, 513, 1024, 128),\n        2048, Bucketizer!(FList, 1025, 2048, 256),\n        3584, Bucketizer!(FList, 2049, 3584, 512),\n        4072 * 1024, AllocatorList!(\n            (size_t n) => BitmappedBlock!(4096)(cast(ubyte[]) GCAllocator.instance.allocate(\n                max(n, 4072 * 1024)))),\n        GCAllocator\n    );\n\n    import std.stdio;\n    import std.conv : to;\n    import std.datetime.stopwatch;\n    import std.algorithm.iteration : map;\n\n    if (false) writeln(benchmark!(\n        testSpeed!NullAllocator,\n        testSpeed!Mallocator,\n        testSpeed!GCAllocator,\n        testSpeed!(ThreadLocal!A),\n        testSpeed!(A),\n    )(20)[].map!(t => t.to!Duration));\n}\n\nunittest\n{\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.building_blocks.region : InSituRegion;\n    import std.experimental.allocator.building_blocks.fallback_allocator : FallbackAllocator;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n\n    auto a = allocatorObject(Mallocator.instance);\n    auto b = a.allocate(100);\n    assert(b.length == 100);\n\n    FreeList!(GCAllocator, 0, 8) fl;\n    auto sa = allocatorObject(fl);\n    b = a.allocate(101);\n    assert(b.length == 101);\n\n    FallbackAllocator!(InSituRegion!(10240, 64), GCAllocator) fb;\n    // Doesn't work yet...\n    //a = allocatorObject(fb);\n    //b = a.allocate(102);\n    //assert(b.length == 102);\n}\n\n///\nunittest\n{\n    import std.experimental.allocator.building_blocks.allocator_list : AllocatorList;\n    import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlock;\n    import std.experimental.allocator.building_blocks.segregator : Segregator;\n    import std.experimental.allocator.building_blocks.bucketizer : Bucketizer;\n    import std.experimental.allocator.building_blocks.free_list : FreeList;\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n\n    /// Define an allocator bound to the built-in GC.\n    IAllocator alloc = allocatorObject(GCAllocator.instance);\n    auto b = alloc.allocate(42);\n    assert(b.length == 42);\n    assert(alloc.deallocate(b));\n\n    import std.algorithm.comparison : max;\n    // Define an elaborate allocator and bind it to the class API.\n    alias FList = FreeList!(GCAllocator, 0, unbounded);\n    alias A = ThreadLocal!(\n        Segregator!(\n            8, FreeList!(GCAllocator, 0, 8),\n            128, Bucketizer!(FList, 1, 128, 16),\n            256, Bucketizer!(FList, 129, 256, 32),\n            512, Bucketizer!(FList, 257, 512, 64),\n            1024, Bucketizer!(FList, 513, 1024, 128),\n            2048, Bucketizer!(FList, 1025, 2048, 256),\n            3584, Bucketizer!(FList, 2049, 3584, 512),\n            4072 * 1024, AllocatorList!(\n                (n) => BitmappedBlock!(4096)(cast(ubyte[]) GCAllocator.instance.allocate(\n                    max(n, 4072 * 1024)))),\n            GCAllocator\n        )\n    );\n\n    auto alloc2 = allocatorObject(A.instance);\n    b = alloc2.allocate(101);\n    assert(alloc2.deallocate(b));\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/showcase.d",
    "content": "// Written in the D programming language.\n/**\nCollection of typical and useful prebuilt allocators using the given\ncomponents. User code would typically import this module and use its\nfacilities, or import individual heap building blocks and assemble them.\n\nSource: $(PHOBOSSRC std/experimental/allocator/_showcase.d)\n*/\nmodule std.experimental.allocator.showcase;\n\nimport std.experimental.allocator.building_blocks.fallback_allocator,\n    std.experimental.allocator.gc_allocator,\n    std.experimental.allocator.building_blocks.region;\nimport std.traits : hasMember;\n\n/**\n\nAllocator that uses stack allocation for up to `stackSize` bytes and\nthen falls back to `Allocator`. Defined as:\n\n----\nalias StackFront(size_t stackSize, Allocator) =\n    FallbackAllocator!(\n        InSituRegion!(stackSize, Allocator.alignment,\n            hasMember!(Allocator, \"deallocate\")\n                ? Yes.defineDeallocate\n                : No.defineDeallocate),\n        Allocator);\n----\n\nChoosing `stackSize` is as always a compromise. Too small a size exhausts the\nstack storage after a few allocations, after which there are no gains over the\nbackup allocator. Too large a size increases the stack consumed by the thread\nand may end up worse off because it explores cold portions of the stack.\n\n*/\nalias StackFront(size_t stackSize, Allocator = GCAllocator) =\n    FallbackAllocator!(\n        InSituRegion!(stackSize, Allocator.alignment),\n        Allocator);\n\n///\n@system unittest\n{\n    StackFront!4096 a;\n    auto b = a.allocate(4000);\n    assert(b.length == 4000);\n    auto c = a.allocate(4000);\n    assert(c.length == 4000);\n    a.deallocate(b);\n    a.deallocate(c);\n}\n\n/**\nCreates a scalable `AllocatorList` of `Regions`, each having at least\n`bytesPerRegion` bytes. Allocation is very fast. This allocator does not offer\n`deallocate` but does free all regions in its destructor. It is recommended for\nshort-lived batch applications that count on never running out of memory.\n*/\nauto mmapRegionList(size_t bytesPerRegion)\n{\n    static struct Factory\n    {\n        size_t bytesPerRegion;\n        import std.algorithm.comparison : max;\n        import std.experimental.allocator.building_blocks.region\n            : Region;\n        import std.experimental.allocator.mmap_allocator\n            : MmapAllocator;\n        this(size_t n)\n        {\n            bytesPerRegion = n;\n        }\n        auto opCall(size_t n)\n        {\n            return Region!MmapAllocator(max(n, bytesPerRegion));\n        }\n    }\n    import std.experimental.allocator.building_blocks.allocator_list\n        : AllocatorList;\n    import std.experimental.allocator.building_blocks.null_allocator\n        : NullAllocator;\n    auto shop = Factory(bytesPerRegion);\n    return AllocatorList!(Factory, NullAllocator)(shop);\n}\n\n///\n@system unittest\n{\n    auto alloc = mmapRegionList(1024 * 1024);\n    const b = alloc.allocate(100);\n    assert(b.length == 100);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/allocator/typed.d",
    "content": "// Written in the D programming language.\n/**\nThis module defines `TypedAllocator`, a statically-typed allocator that\naggregates multiple untyped allocators and uses them depending on the static\nproperties of the types allocated. For example, distinct allocators may be used\nfor thread-local vs. thread-shared data, or for fixed-size data (`struct`,\n`class` objects) vs. resizable data (arrays).\n\nSource: $(PHOBOSSRC std/experimental/allocator/typed.d)\n\nMacros:\nT2=$(TR <td style=\"text-align:left\">`$1`</td> $(TD $(ARGS $+)))\n*/\n\nmodule std.experimental.allocator.typed;\n\nimport std.experimental.allocator;\nimport std.experimental.allocator.common;\nimport std.range : isInputRange, isForwardRange, walkLength, save, empty,\n    front, popFront;\nimport std.traits : isPointer, hasElaborateDestructor;\nimport std.typecons : Flag, Yes, No;\n\n/**\nAllocation-related flags dictated by type characteristics. `TypedAllocator`\ndeduces these flags from the type being allocated and uses the appropriate\nallocator accordingly.\n*/\nenum AllocFlag : uint\n{\n    init = 0,\n    /**\n    Fixed-size allocation (unlikely to get reallocated later). Examples: `int`,\n    `double`, any `struct` or `class` type. By default it is assumed that the\n    allocation is variable-size, i.e. susceptible to later reallocation\n    (for example all array types). This flag is advisory, i.e. in-place resizing\n    may be attempted for `fixedSize` allocations and may succeed. The flag is\n    just a hint to the compiler it may use allocation strategies that work well\n    with objects of fixed size.\n    */\n    fixedSize = 1,\n    /**\n    The type being allocated embeds no pointers. Examples: `int`, `int[]`, $(D\n    Tuple!(int, float)). The implicit conservative assumption is that the type\n    has members with indirections so it needs to be scanned if garbage\n    collected. Example of types with pointers: `int*[]`, $(D Tuple!(int,\n    string)).\n    */\n    hasNoIndirections = 4,\n    /**\n    By default it is conservatively assumed that allocated memory may be `cast`\n    to `shared`, passed across threads, and deallocated in a different thread\n    than the one that allocated it. If that's not the case, there are two\n    options. First, `immutableShared` means the memory is allocated for\n    `immutable` data and will be deallocated in the same thread it was\n    allocated in. Second, `threadLocal` means the memory is not to be shared\n    across threads at all. The two flags cannot be simultaneously present.\n    */\n    immutableShared = 8,\n    /// ditto\n    threadLocal = 16,\n}\n\n/**\n`TypedAllocator` acts like a chassis on which several specialized allocators\ncan be assembled. To let the system make a choice about a particular kind of\nallocation, use `Default` for the respective parameters.\n\nThere is a hierarchy of allocation kinds. When an allocator is implemented for\na given combination of flags, it is used. Otherwise, the next down the list is\nchosen.\n\n$(BOOKTABLE ,\n\n$(TR $(TH `AllocFlag` combination) $(TH Description))\n\n$(T2 AllocFlag.threadLocal |$(NBSP)AllocFlag.hasNoIndirections\n|$(NBSP)AllocFlag.fixedSize,\nThis is the most specific allocation policy: the memory being allocated is\nthread local, has no indirections at all, and will not be reallocated. Examples\nof types fitting this description: `int`, `double`, $(D Tuple!(int, long)), but\nnot $(D Tuple!(int, string)), which contains an indirection.)\n\n$(T2 AllocFlag.threadLocal |$(NBSP)AllocFlag.hasNoIndirections,\nAs above, but may be reallocated later. Examples of types fitting this\ndescription are `int[]`, `double[]`, $(D Tuple!(int, long)[]), but not\n$(D Tuple!(int, string)[]), which contains an indirection.)\n\n$(T2 AllocFlag.threadLocal,\nAs above, but may embed indirections. Examples of types fitting this\ndescription are `int*[]`, `Object[]`, $(D Tuple!(int, string)[]).)\n\n$(T2 AllocFlag.immutableShared |$(NBSP)AllocFlag.hasNoIndirections\n|$(NBSP)AllocFlag.fixedSize,\nThe type being allocated is `immutable` and has no pointers. The thread that\nallocated it must also deallocate it. Example: `immutable(int)`.)\n\n$(T2 AllocFlag.immutableShared |$(NBSP)AllocFlag.hasNoIndirections,\nAs above, but the type may be appended to in the future. Example: `string`.)\n\n$(T2 AllocFlag.immutableShared,\nAs above, but the type may embed references. Example: `immutable(Object)[]`.)\n\n$(T2 AllocFlag.hasNoIndirections |$(NBSP)AllocFlag.fixedSize,\nThe type being allocated may be shared across threads, embeds no indirections,\nand has fixed size.)\n\n$(T2 AllocFlag.hasNoIndirections,\nThe type being allocated may be shared across threads, may embed indirections,\nand has variable size.)\n\n$(T2 AllocFlag.fixedSize,\nThe type being allocated may be shared across threads, may embed indirections,\nand has fixed size.)\n\n$(T2 0, The most conservative/general allocation: memory may be shared,\ndeallocated in a different thread, may or may not be resized, and may embed\nreferences.)\n)\n\nParams:\nPrimaryAllocator = The default allocator.\nPolicies = Zero or more pairs consisting of an `AllocFlag` and an allocator\ntype.\n*/\nstruct TypedAllocator(PrimaryAllocator, Policies...)\n{\n    import std.algorithm.sorting : isSorted;\n    import std.meta : AliasSeq;\n    import std.typecons : Tuple;\n\n    static assert(Policies.length == 0 || isSorted([Stride2!Policies]));\n\n    private template Stride2(T...)\n    {\n        static if (T.length >= 2)\n        {\n            alias Stride2 = AliasSeq!(T[0], Stride2!(T[2 .. $]));\n        }\n        else\n        {\n            alias Stride2 = AliasSeq!(T[0 .. $]);\n        }\n    }\n\n    // state\n    static if (stateSize!PrimaryAllocator) private PrimaryAllocator primary;\n    else alias primary = PrimaryAllocator.instance;\n    static if (Policies.length > 0)\n        private Tuple!(Stride2!(Policies[1 .. $])) extras;\n\n    private static bool match(uint have, uint want)\n    {\n        enum uint maskAway =\n            ~(AllocFlag.immutableShared | AllocFlag.threadLocal);\n        // Do we offer thread local?\n        if (have & AllocFlag.threadLocal)\n        {\n            if (want & AllocFlag.threadLocal)\n                return match(have & maskAway, want & maskAway);\n            return false;\n        }\n        if (have & AllocFlag.immutableShared)\n        {\n            // Okay to ask for either thread local or immutable shared\n            if (want & (AllocFlag.threadLocal\n                    | AllocFlag.immutableShared))\n                return match(have & maskAway, want & maskAway);\n            return false;\n        }\n        // From here on we have full-blown thread sharing.\n        if (have & AllocFlag.hasNoIndirections)\n        {\n            if (want & AllocFlag.hasNoIndirections)\n                return match(have & ~AllocFlag.hasNoIndirections,\n                    want & ~AllocFlag.hasNoIndirections);\n            return false;\n        }\n        // Fixed size or variable size both match.\n        return true;\n    }\n\n    /**\n    Given `flags` as a combination of `AllocFlag` values, or a type `T`, returns\n    the allocator that's a closest fit in capabilities.\n    */\n    auto ref allocatorFor(uint flags)()\n    {\n        static if (Policies.length == 0 || !match(Policies[0], flags))\n        {\n            return primary;\n        }\n        else static if (Policies.length && match(Policies[$ - 2], flags))\n        {\n            return extras[$ - 1];\n        }\n        else\n        {\n            foreach (i, choice; Stride2!Policies)\n            {\n                static if (!match(choice, flags))\n                {\n                    return extras[i - 1];\n                }\n            }\n            assert(0);\n        }\n    }\n\n    /// ditto\n    auto ref allocatorFor(T)()\n    {\n        static if (is(T == void[]))\n        {\n            return primary;\n        }\n        else\n        {\n            return allocatorFor!(type2flags!T)();\n        }\n    }\n\n    /**\n    Given a type `T`, returns its allocation-related flags as a combination of\n    `AllocFlag` values.\n    */\n    static uint type2flags(T)()\n    {\n        uint result;\n        static if (is(T == immutable))\n            result |= AllocFlag.immutableShared;\n        else static if (is(T == shared))\n            result |= AllocFlag.forSharing;\n        static if (!is(T == U[], U))\n            result |= AllocFlag.fixedSize;\n        import std.traits : hasIndirections;\n        static if (!hasIndirections!T)\n            result |= AllocFlag.hasNoIndirections;\n        return result;\n    }\n\n    /**\n    Dynamically allocates (using the appropriate allocator chosen with\n    `allocatorFor!T`) and then creates in the memory allocated an object of\n    type `T`, using `args` (if any) for its initialization. Initialization\n    occurs in the memory allocated and is otherwise semantically the same as\n    `T(args)`. (Note that using `make!(T[])` creates a pointer to an\n    (empty) array of `T`s, not an array. To allocate and initialize an\n    array, use `makeArray!T` described below.)\n\n    Params:\n    T = Type of the object being created.\n    args = Optional arguments used for initializing the created object. If not\n    present, the object is default constructed.\n\n    Returns: If `T` is a class type, returns a reference to the created `T`\n    object. Otherwise, returns a `T*` pointing to the created object. In all\n    cases, returns `null` if allocation failed.\n\n    Throws: If `T`'s constructor throws, deallocates the allocated memory and\n    propagates the exception.\n    */\n    auto make(T, A...)(auto ref A args)\n    {\n        return .make!T(allocatorFor!T, args);\n    }\n\n    /**\n    Create an array of `T` with `length` elements. The array is either\n    default-initialized, filled with copies of `init`, or initialized with\n    values fetched from `range`.\n\n    Params:\n    T = element type of the array being created\n    length = length of the newly created array\n    init = element used for filling the array\n    range = range used for initializing the array elements\n\n    Returns:\n    The newly-created array, or `null` if either `length` was `0` or\n    allocation failed.\n\n    Throws:\n    The first two overloads throw only if the used allocator's primitives do.\n    The overloads that involve copy initialization deallocate memory and propagate the exception if the copy operation throws.\n    */\n    T[] makeArray(T)(size_t length)\n    {\n        return .makeArray!T(allocatorFor!(T[]), length);\n    }\n\n    /// Ditto\n    T[] makeArray(T)(size_t length, auto ref T init)\n    {\n        return .makeArray!T(allocatorFor!(T[]), init, length);\n    }\n\n    /// Ditto\n    T[] makeArray(T, R)(R range)\n    if (isInputRange!R)\n    {\n        return .makeArray!T(allocatorFor!(T[]), range);\n    }\n\n    /**\n    Grows `array` by appending `delta` more elements. The needed memory is\n    allocated using the same allocator that was used for the array type. The\n    extra elements added are either default-initialized, filled with copies of\n    `init`, or initialized with values fetched from `range`.\n\n    Params:\n    T = element type of the array being created\n    array = a reference to the array being grown\n    delta = number of elements to add (upon success the new length of `array`\n    is $(D array.length + delta))\n    init = element used for filling the array\n    range = range used for initializing the array elements\n\n    Returns:\n    `true` upon success, `false` if memory could not be allocated. In the\n    latter case `array` is left unaffected.\n\n    Throws:\n    The first two overloads throw only if the used allocator's primitives do.\n    The overloads that involve copy initialization deallocate memory and\n    propagate the exception if the copy operation throws.\n    */\n    bool expandArray(T)(ref T[] array, size_t delta)\n    {\n        return .expandArray(allocatorFor!(T[]), array, delta);\n    }\n    /// Ditto\n    bool expandArray(T)(T[] array, size_t delta, auto ref T init)\n    {\n        return .expandArray(allocatorFor!(T[]), array, delta, init);\n    }\n    /// Ditto\n    bool expandArray(T, R)(ref T[] array, R range)\n    if (isInputRange!R)\n    {\n        return .expandArray(allocatorFor!(T[]), array, range);\n    }\n\n    /**\n    Shrinks an array by `delta` elements using `allocatorFor!(T[])`.\n\n    If $(D arr.length < delta), does nothing and returns `false`. Otherwise,\n    destroys the last $(D arr.length - delta) elements in the array and then\n    reallocates the array's buffer. If reallocation fails, fills the array with\n    default-initialized data.\n\n    Params:\n    T = element type of the array being created\n    arr = a reference to the array being shrunk\n    delta = number of elements to remove (upon success the new length of\n    `arr` is $(D arr.length - delta))\n\n    Returns:\n    `true` upon success, `false` if memory could not be reallocated. In the\n    latter case $(D arr[$ - delta .. $]) is left with default-initialized\n    elements.\n\n    Throws:\n    The first two overloads throw only if the used allocator's primitives do.\n    The overloads that involve copy initialization deallocate memory and\n    propagate the exception if the copy operation throws.\n    */\n    bool shrinkArray(T)(ref T[] arr, size_t delta)\n    {\n        return .shrinkArray(allocatorFor!(T[]), arr, delta);\n    }\n\n    /**\n    Destroys and then deallocates (using `allocatorFor!T`) the object pointed\n    to by a pointer, the class object referred to by a `class` or `interface`\n    reference, or an entire array. It is assumed the respective entities had\n    been allocated with the same allocator.\n    */\n    void dispose(T)(T* p)\n    {\n        return .dispose(allocatorFor!T, p);\n    }\n    /// Ditto\n    void dispose(T)(T p)\n    if (is(T == class) || is(T == interface))\n    {\n        return .dispose(allocatorFor!T, p);\n    }\n    /// Ditto\n    void dispose(T)(T[] array)\n    {\n        return .dispose(allocatorFor!(T[]), array);\n    }\n}\n\n///\n@system unittest\n{\n    import std.experimental.allocator.gc_allocator : GCAllocator;\n    import std.experimental.allocator.mallocator : Mallocator;\n    import std.experimental.allocator.mmap_allocator : MmapAllocator;\n    alias MyAllocator = TypedAllocator!(GCAllocator,\n        AllocFlag.fixedSize | AllocFlag.threadLocal, Mallocator,\n        AllocFlag.fixedSize | AllocFlag.threadLocal\n                | AllocFlag.hasNoIndirections,\n            MmapAllocator,\n    );\n\n    MyAllocator a;\n    auto b = &a.allocatorFor!0();\n    static assert(is(typeof(*b) == shared const(GCAllocator)));\n    enum f1 = AllocFlag.fixedSize | AllocFlag.threadLocal;\n    auto c = &a.allocatorFor!f1();\n    static assert(is(typeof(*c) == Mallocator));\n    enum f2 = AllocFlag.fixedSize | AllocFlag.threadLocal;\n    static assert(is(typeof(a.allocatorFor!f2()) == Mallocator));\n    // Partial match\n    enum f3 = AllocFlag.threadLocal;\n    static assert(is(typeof(a.allocatorFor!f3()) == Mallocator));\n\n    int* p = a.make!int;\n    scope(exit) a.dispose(p);\n    int[] arr = a.makeArray!int(42);\n    scope(exit) a.dispose(arr);\n    assert(a.expandArray(arr, 3));\n    assert(a.shrinkArray(arr, 4));\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/checkedint.d",
    "content": "// Written in the D programming language.\n/**\n$(SCRIPT inhibitQuickIndex = 1;)\n\nThis module defines facilities for efficient checking of integral operations\nagainst overflow, casting with loss of precision, unexpected change of sign,\netc. The checking (and possibly correction) can be done at operation level, for\nexample $(LREF opChecked)$(D !\"+\"(x, y, overflow)) adds two integrals `x` and\n`y` and sets `overflow` to `true` if an overflow occurred. The flag `overflow`\n(a `bool` passed by reference) is not touched if the operation succeeded, so the\nsame flag can be reused for a sequence of operations and tested at the end.\n\nIssuing individual checked operations is flexible and efficient but often\ntedious. The $(LREF Checked) facility offers encapsulated integral wrappers that\ndo all checking internally and have configurable behavior upon erroneous\nresults. For example, `Checked!int` is a type that behaves like `int` but aborts\nexecution immediately whenever involved in an operation that produces the\narithmetically wrong result. The accompanying convenience function $(LREF\nchecked) uses type deduction to convert a value `x` of integral type `T` to\n`Checked!T` by means of `checked(x)`. For example:\n\n---\nvoid main()\n{\n    import std.experimental.checkedint, std.stdio;\n    writeln((checked(5) + 7).get); // 12\n    writeln((checked(10) * 1000 * 1000 * 1000).get); // Overflow\n}\n---\n\nSimilarly, $(D checked(-1) > uint(0)) aborts execution (even though the built-in\ncomparison $(D int(-1) > uint(0)) is surprisingly true due to language's\nconversion rules modeled after C). Thus, `Checked!int` is a virtually drop-in\nreplacement for `int` useable in debug builds, to be replaced by `int` in\nrelease mode if efficiency demands it.\n\n`Checked`  has customizable behavior with the help of a second type parameter,\n`Hook`. Depending on what methods `Hook` defines, core operations on the\nunderlying integral may be verified for overflow or completely redefined. If\n`Hook` defines no method at all and carries no state, there is no change in\nbehavior, i.e. $(D Checked!(int, void)) is a wrapper around `int` that adds no\ncustomization at all.\n\nThis module provides a few predefined hooks (below) that add useful behavior to\n`Checked`:\n\n$(BOOKTABLE ,\n    $(TR $(TD $(LREF Abort)) $(TD\n        fails every incorrect operation with a message to $(REF\n        stderr, std, stdio) followed by a call to `assert(0)`. It is the default\n        second parameter, i.e. `Checked!short` is the same as\n        $(D Checked!(short, Abort)).\n    ))\n    $(TR $(TD $(LREF Throw)) $(TD\n        fails every incorrect operation by throwing an exception.\n    ))\n    $(TR $(TD $(LREF Warn)) $(TD\n        prints incorrect operations to $(REF stderr, std, stdio)\n        but otherwise preserves the built-in behavior.\n    ))\n    $(TR $(TD $(LREF ProperCompare)) $(TD\n        fixes the comparison operators `==`, `!=`, `<`, `<=`, `>`, and `>=`\n        to return correct results in all circumstances,\n        at a slight cost in efficiency. For example,\n        $(D Checked!(uint, ProperCompare)(1) > -1) is `true`,\n        which is not the case for the built-in comparison. Also, comparing\n        numbers for equality with floating-point numbers only passes if the\n        integral can be converted to the floating-point number precisely,\n        so as to preserve transitivity of equality.\n    ))\n    $(TR $(TD $(LREF WithNaN)) $(TD\n        reserves a special \"Not a Number\" (NaN) value akin to the homonym value\n        reserved for floating-point values. Once a $(D Checked!(X, WithNaN))\n        gets this special value, it preserves and propagates it until\n        reassigned. $(LREF isNaN) can be used to query whether the object\n        is not a number.\n    ))\n    $(TR $(TD $(LREF Saturate)) $(TD\n        implements saturating arithmetic, i.e. $(D Checked!(int, Saturate))\n        \"stops\" at `int.max` for all operations that would cause an `int` to\n        overflow toward infinity, and at `int.min` for all operations that would\n        correspondingly overflow toward negative infinity.\n    ))\n)\n\n\nThese policies may be used alone, e.g. $(D Checked!(uint, WithNaN)) defines a\n`uint`-like type that reaches a stable NaN state for all erroneous operations.\nThey may also be \"stacked\" on top of each other, owing to the property that a\nchecked integral emulates an actual integral, which means another checked\nintegral can be built on top of it. Some combinations of interest include:\n\n$(BOOKTABLE ,\n    $(TR $(TD $(D Checked!(Checked!int, ProperCompare))))\n    $(TR $(TD\ndefines an `int` with fixed\ncomparison operators that will fail with `assert(0)` upon overflow. (Recall that\n`Abort` is the default policy.) The order in which policies are combined is\nimportant because the outermost policy (`ProperCompare` in this case) has the\nfirst crack at intercepting an operator. The converse combination $(D\nChecked!(Checked!(int, ProperCompare))) is meaningless because `Abort` will\nintercept comparison and will fail without giving `ProperCompare` a chance to\nintervene.\n    ))\n    $(TR $(TD))\n    $(TR $(TDNW $(D Checked!(Checked!(int, ProperCompare), WithNaN))))\n    $(TR $(TD\ndefines an `int`-like\ntype that supports a NaN value. For values that are not NaN, comparison works\nproperly. Again the composition order is important; $(D Checked!(Checked!(int,\nWithNaN), ProperCompare)) does not have good semantics because `ProperCompare`\nintercepts comparisons before the numbers involved are tested for NaN.\n    ))\n)\n\nThe hook's members are looked up statically in a Design by Introspection manner\nand are all optional. The table below illustrates the members that a hook type\nmay define and their influence over the behavior of the `Checked` type using it.\nIn the table, `hook` is an alias for `Hook` if the type `Hook` does not\nintroduce any state, or an object of type `Hook` otherwise.\n\n$(TABLE ,\n$(TR $(TH `Hook` member) $(TH Semantics in $(D Checked!(T, Hook)))\n)\n$(TR $(TD `defaultValue`) $(TD If defined, `Hook.defaultValue!T` is used as the\ndefault initializer of the payload.)\n)\n$(TR $(TD `min`) $(TD If defined, `Hook.min!T` is used as the minimum value of\nthe payload.)\n)\n$(TR $(TD `max`) $(TD If defined, `Hook.max!T` is used as the maximum value of\nthe payload.)\n)\n$(TR $(TD `hookOpCast`) $(TD If defined, `hook.hookOpCast!U(get)` is forwarded\nto unconditionally when the payload is to be cast to type `U`.)\n)\n$(TR $(TD `onBadCast`) $(TD If defined and `hookOpCast` is $(I not) defined,\n`onBadCast!U(get)` is forwarded to when the payload is to be cast to type `U`\nand the cast would lose information or force a change of sign.)\n)\n$(TR $(TD `hookOpEquals`) $(TD If defined, $(D hook.hookOpEquals(get, rhs)) is\nforwarded to unconditionally when the payload is compared for equality against\nvalue `rhs` of integral, floating point, or Boolean type.)\n)\n$(TR $(TD `hookOpCmp`) $(TD If defined, $(D hook.hookOpCmp(get, rhs)) is\nforwarded to unconditionally when the payload is compared for ordering against\nvalue `rhs` of integral, floating point, or Boolean type.)\n)\n$(TR $(TD `hookOpUnary`) $(TD If defined, `hook.hookOpUnary!op(get)` (where `op`\nis the operator symbol) is forwarded to for unary operators `-` and `~`. In\naddition, for unary operators `++` and `--`, `hook.hookOpUnary!op(payload)` is\ncalled, where `payload` is a reference to the value wrapped by `Checked` so the\nhook can change it.)\n)\n$(TR $(TD `hookOpBinary`) $(TD If defined, $(D hook.hookOpBinary!op(get, rhs))\n(where `op` is the operator symbol and `rhs` is the right-hand side operand) is\nforwarded to unconditionally for binary operators `+`,  `-`, `*`, `/`, `%`,\n`^^`, `&`, `|`, `^`, `<<`, `>>`, and `>>>`.)\n)\n$(TR $(TD `hookOpBinaryRight`) $(TD If defined, $(D\nhook.hookOpBinaryRight!op(lhs, get)) (where `op` is the operator symbol and\n`lhs` is the left-hand side operand) is forwarded to unconditionally for binary\noperators `+`,  `-`, `*`, `/`, `%`, `^^`, `&`, `|`, `^`, `<<`, `>>`, and `>>>`.)\n)\n$(TR $(TD `onOverflow`) $(TD If defined, `hook.onOverflow!op(get)` is forwarded\nto for unary operators that overflow but only if `hookOpUnary` is not defined.\nUnary `~` does not overflow; unary `-` overflows only when the most negative\nvalue of a signed type is negated, and the result of the hook call is returned.\nWhen the increment or decrement operators overflow, the payload is assigned the\nresult of `hook.onOverflow!op(get)`. When a binary operator overflows, the\nresult of $(D hook.onOverflow!op(get, rhs)) is returned, but only if `Hook` does\nnot define `hookOpBinary`.)\n)\n$(TR $(TD `hookOpOpAssign`) $(TD If defined, $(D hook.hookOpOpAssign!op(payload,\nrhs)) (where `op` is the operator symbol and `rhs` is the right-hand side\noperand) is forwarded to unconditionally for binary operators `+=`,  `-=`, `*=`, `/=`, `%=`,\n`^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`, and `>>>=`.)\n)\n$(TR $(TD `onLowerBound`) $(TD If defined, $(D hook.onLowerBound(value, bound))\n(where `value` is the value being assigned) is forwarded to when the result of\nbinary operators `+=`,  `-=`, `*=`, `/=`, `%=`, `^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`,\nand `>>>=` is smaller than the smallest value representable by `T`.)\n)\n$(TR $(TD `onUpperBound`) $(TD If defined, $(D hook.onUpperBound(value, bound))\n(where `value` is the value being assigned) is forwarded to when the result of\nbinary operators `+=`,  `-=`, `*=`, `/=`, `%=`, `^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`,\nand `>>>=` is larger than the largest value representable by `T`.)\n)\n$(TR $(TD `hookToHash`) $(TD If defined, $(D hook.hookToHash(payload))\n(where `payload` is a reference to the value wrapped by Checked) is forwarded\nto when `toHash` is called on a Checked type. Custom hashing can be implemented\nin a `Hook`, otherwise the built-in hashing is used.)\n)\n)\n\nSource: $(PHOBOSSRC std/experimental/checkedint.d)\n*/\nmodule std.experimental.checkedint;\nimport std.traits : isFloatingPoint, isIntegral, isNumeric, isUnsigned, Unqual;\n\n///\n@system unittest\n{\n    int[] concatAndAdd(int[] a, int[] b, int offset)\n    {\n        // Aborts on overflow on size computation\n        auto r = new int[(checked(a.length) + b.length).get];\n        // Aborts on overflow on element computation\n        foreach (i; 0 .. a.length)\n            r[i] = (a[i] + checked(offset)).get;\n        foreach (i; 0 .. b.length)\n            r[i + a.length] = (b[i] + checked(offset)).get;\n        return r;\n    }\n    assert(concatAndAdd([1, 2, 3], [4, 5], -1) == [0, 1, 2, 3, 4]);\n}\n\n\n/// `Saturate` stops at an overflow\n@safe unittest\n{\n    auto x = (cast(byte) 127).checked!Saturate;\n    assert(x == 127);\n    x++;\n    assert(x == 127);\n}\n\n/// `WithNaN` has a special \"Not a Number\" (NaN) value akin to the homonym value reserved for floating-point values\n@safe unittest\n{\n    auto x = 100.checked!WithNaN;\n    assert(x == 100);\n    x /= 0;\n    assert(x.isNaN);\n}\n\n/// `ProperCompare` fixes the comparison operators ==, !=, <, <=, >, and >= to return correct results\n@safe unittest\n{\n    uint x = 1;\n    auto y = x.checked!ProperCompare;\n    assert(x < -1); // built-in comparison\n    assert(y > -1); // ProperCompare\n}\n\n/// `Throw` fails every incorrect operation by throwing an exception\n@safe unittest\n{\n    import std.exception : assertThrown;\n    auto x = -1.checked!Throw;\n    assertThrown(x / 0);\n    assertThrown(x + int.min);\n    assertThrown(x == uint.max);\n}\n\n/**\nChecked integral type wraps an integral `T` and customizes its behavior with the\nhelp of a `Hook` type. The type wrapped must be one of the predefined integrals\n(unqualified), or another instance of `Checked`.\n*/\nstruct Checked(T, Hook = Abort)\nif (isIntegral!T || is(T == Checked!(U, H), U, H))\n{\n    import std.algorithm.comparison : among;\n    import std.experimental.allocator.common : stateSize;\n    import std.traits : hasMember;\n\n    /**\n    The type of the integral subject to checking.\n    */\n    alias Representation = T;\n\n    // state {\n    static if (hasMember!(Hook, \"defaultValue\"))\n        private T payload = Hook.defaultValue!T;\n    else\n        private T payload;\n    /**\n    `hook` is a member variable if it has state, or an alias for `Hook`\n    otherwise.\n    */\n    static if (stateSize!Hook > 0) Hook hook;\n    else alias hook = Hook;\n    // } state\n\n    // get\n    /**\n    Returns a copy of the underlying value.\n    */\n    auto get() inout { return payload; }\n    ///\n    @safe unittest\n    {\n        auto x = checked(ubyte(42));\n        static assert(is(typeof(x.get()) == ubyte));\n        assert(x.get == 42);\n        const y = checked(ubyte(42));\n        static assert(is(typeof(y.get()) == const ubyte));\n        assert(y.get == 42);\n    }\n\n    /**\n    Defines the minimum and maximum. These values are hookable by defining\n    `Hook.min` and/or `Hook.max`.\n    */\n    static if (hasMember!(Hook, \"min\"))\n    {\n        enum Checked!(T, Hook) min = Checked!(T, Hook)(Hook.min!T);\n        ///\n        @system unittest\n        {\n            assert(Checked!short.min == -32768);\n            assert(Checked!(short, WithNaN).min == -32767);\n            assert(Checked!(uint, WithNaN).max == uint.max - 1);\n        }\n    }\n    else\n        enum Checked!(T, Hook) min = Checked(T.min);\n    /// ditto\n    static if (hasMember!(Hook, \"max\"))\n        enum Checked!(T, Hook) max = Checked(Hook.max!T);\n    else\n        enum Checked!(T, Hook) max = Checked(T.max);\n\n    /**\n    Constructor taking a value properly convertible to the underlying type. `U`\n    may be either an integral that can be converted to `T` without a loss, or\n    another `Checked` instance whose representation may be in turn converted to\n    `T` without a loss.\n    */\n    this(U)(U rhs)\n    if (valueConvertible!(U, T) ||\n        !isIntegral!T && is(typeof(T(rhs))) ||\n        is(U == Checked!(V, W), V, W) &&\n            is(typeof(Checked!(T, Hook)(rhs.get))))\n    {\n        static if (isIntegral!U)\n            payload = rhs;\n        else\n            payload = rhs.payload;\n    }\n    ///\n    @system unittest\n    {\n        auto a = checked(42L);\n        assert(a == 42);\n        auto b = Checked!long(4242); // convert 4242 to long\n        assert(b == 4242);\n    }\n\n    /**\n    Assignment operator. Has the same constraints as the constructor.\n    */\n    void opAssign(U)(U rhs) if (is(typeof(Checked!(T, Hook)(rhs))))\n    {\n        static if (isIntegral!U)\n            payload = rhs;\n        else\n            payload = rhs.payload;\n    }\n    ///\n    @system unittest\n    {\n        Checked!long a;\n        a = 42L;\n        assert(a == 42);\n        a = 4242;\n        assert(a == 4242);\n    }\n\n    // opCast\n    /**\n    Casting operator to integral, `bool`, or floating point type. If `Hook`\n    defines `hookOpCast`, the call immediately returns\n    `hook.hookOpCast!U(get)`. Otherwise, casting to `bool` yields $(D\n    get != 0) and casting to another integral that can represent all\n    values of `T` returns `get` promoted to `U`.\n\n    If a cast to a floating-point type is requested and `Hook` defines\n    `onBadCast`, the cast is verified by ensuring $(D get == cast(T)\n    U(get)). If that is not `true`, `hook.onBadCast!U(get)` is returned.\n\n    If a cast to an integral type is requested and `Hook` defines `onBadCast`,\n    the cast is verified by ensuring `get` and $(D cast(U)\n    get) are the same arithmetic number. (Note that `int(-1)` and\n    `uint(1)` are different values arithmetically although they have the same\n    bitwise representation and compare equal by language rules.) If the numbers\n    are not arithmetically equal, `hook.onBadCast!U(get)` is\n    returned.\n\n    */\n    U opCast(U, this _)()\n    if (isIntegral!U || isFloatingPoint!U || is(U == bool))\n    {\n        static if (hasMember!(Hook, \"hookOpCast\"))\n        {\n            return hook.hookOpCast!U(payload);\n        }\n        else static if (is(U == bool))\n        {\n            return payload != 0;\n        }\n        else static if (valueConvertible!(T, U))\n        {\n            return payload;\n        }\n        // may lose bits or precision\n        else static if (!hasMember!(Hook, \"onBadCast\"))\n        {\n            return cast(U) payload;\n        }\n        else\n        {\n            if (isUnsigned!T || !isUnsigned!U ||\n                    T.sizeof > U.sizeof || payload >= 0)\n            {\n                auto result = cast(U) payload;\n                // If signedness is different, we need additional checks\n                if (result == payload &&\n                        (!isUnsigned!T || isUnsigned!U || result >= 0))\n                    return result;\n            }\n            return hook.onBadCast!U(payload);\n        }\n    }\n    ///\n    @system unittest\n    {\n        assert(cast(uint) checked(42) == 42);\n        assert(cast(uint) checked!WithNaN(-42) == uint.max);\n    }\n\n    // opEquals\n    /**\n    Compares `this` against `rhs` for equality. If `Hook` defines\n    `hookOpEquals`, the function forwards to $(D\n    hook.hookOpEquals(get, rhs)). Otherwise, the result of the\n    built-in operation $(D get == rhs) is returned.\n\n    If `U` is also an instance of `Checked`, both hooks (left- and right-hand\n    side) are introspected for the method `hookOpEquals`. If both define it,\n    priority is given to the left-hand side.\n\n    */\n    bool opEquals(U, this _)(U rhs)\n    if (isIntegral!U || isFloatingPoint!U || is(U == bool) ||\n        is(U == Checked!(V, W), V, W) && is(typeof(this == rhs.payload)))\n    {\n        static if (is(U == Checked!(V, W), V, W))\n        {\n            alias R = typeof(payload + rhs.payload);\n            static if (is(Hook == W))\n            {\n                // Use the lhs hook if there\n                return this == rhs.payload;\n            }\n            else static if (valueConvertible!(T, R) && valueConvertible!(V, R))\n            {\n                return payload == rhs.payload;\n            }\n            else static if (hasMember!(Hook, \"hookOpEquals\"))\n            {\n                return hook.hookOpEquals(payload, rhs.payload);\n            }\n            else static if (hasMember!(W, \"hookOpEquals\"))\n            {\n                return rhs.hook.hookOpEquals(rhs.payload, payload);\n            }\n            else\n            {\n                return payload == rhs.payload;\n            }\n        }\n        else static if (hasMember!(Hook, \"hookOpEquals\"))\n            return hook.hookOpEquals(payload, rhs);\n        else static if (isIntegral!U || isFloatingPoint!U || is(U == bool))\n            return payload == rhs;\n    }\n\n    ///\n    static if (is(T == int) && is(Hook == void)) @safe unittest\n    {\n        static struct MyHook\n        {\n            static bool thereWereErrors;\n            static bool hookOpEquals(L, R)(L lhs, R rhs)\n            {\n                if (lhs != rhs) return false;\n                static if (isUnsigned!L && !isUnsigned!R)\n                {\n                    if (lhs > 0 && rhs < 0) thereWereErrors = true;\n                }\n                else static if (isUnsigned!R && !isUnsigned!L)\n                    if (lhs < 0 && rhs > 0) thereWereErrors = true;\n                // Preserve built-in behavior.\n                return true;\n            }\n        }\n        auto a = checked!MyHook(-42);\n        assert(a == uint(-42));\n        assert(MyHook.thereWereErrors);\n        MyHook.thereWereErrors = false;\n        assert(checked!MyHook(uint(-42)) == -42);\n        assert(MyHook.thereWereErrors);\n        static struct MyHook2\n        {\n            static bool hookOpEquals(L, R)(L lhs, R rhs)\n            {\n                return lhs == rhs;\n            }\n        }\n        MyHook.thereWereErrors = false;\n        assert(checked!MyHook2(uint(-42)) == a);\n        // Hook on left hand side takes precedence, so no errors\n        assert(!MyHook.thereWereErrors);\n    }\n\n    // toHash\n    /**\n    Generates a hash for `this`. If `Hook` defines `hookToHash`, the call\n    immediately returns `hook.hookToHash(payload)`. If `Hook` does not\n    implement `hookToHash`, but it has state, a hash will be generated for\n    the `Hook` using the built-in function and it will be xored with the\n    hash of the `payload`.\n    */\n    size_t toHash() const nothrow @safe\n    {\n        static if (hasMember!(Hook, \"hookToHash\"))\n        {\n            return hook.hookToHash(payload);\n        }\n        else static if (stateSize!Hook > 0)\n        {\n            static if (hasMember!(typeof(payload), \"toHash\"))\n            {\n                return payload.toHash() ^ hashOf(hook);\n            }\n            else\n            {\n                return hashOf(payload) ^ hashOf(hook);\n            }\n        }\n        else static if (hasMember!(typeof(payload), \"toHash\"))\n        {\n            return payload.toHash();\n        }\n        else\n        {\n            return .hashOf(payload);\n        }\n    }\n\n    // opCmp\n    /**\n\n    Compares `this` against `rhs` for ordering. If `Hook` defines `hookOpCmp`,\n    the function forwards to $(D hook.hookOpCmp(get, rhs)). Otherwise, the\n    result of the built-in comparison operation is returned.\n\n    If `U` is also an instance of `Checked`, both hooks (left- and right-hand\n    side) are introspected for the method `hookOpCmp`. If both define it,\n    priority is given to the left-hand side.\n\n    */\n    auto opCmp(U, this _)(const U rhs) //const pure @safe nothrow @nogc\n    if (isIntegral!U || isFloatingPoint!U || is(U == bool))\n    {\n        static if (hasMember!(Hook, \"hookOpCmp\"))\n        {\n            return hook.hookOpCmp(payload, rhs);\n        }\n        else static if (valueConvertible!(T, U) || valueConvertible!(U, T))\n        {\n            return payload < rhs ? -1 : payload > rhs;\n        }\n        else static if (isFloatingPoint!U)\n        {\n            U lhs = payload;\n            return lhs < rhs ? U(-1.0)\n                : lhs > rhs ? U(1.0)\n                : lhs == rhs ? U(0.0) : U.init;\n        }\n        else\n        {\n            return payload < rhs ? -1 : payload > rhs;\n        }\n    }\n\n    /// ditto\n    auto opCmp(U, Hook1, this _)(Checked!(U, Hook1) rhs)\n    {\n        alias R = typeof(payload + rhs.payload);\n        static if (valueConvertible!(T, R) && valueConvertible!(U, R))\n        {\n            return payload < rhs.payload ? -1 : payload > rhs.payload;\n        }\n        else static if (is(Hook == Hook1))\n        {\n            // Use the lhs hook\n            return this.opCmp(rhs.payload);\n        }\n        else static if (hasMember!(Hook, \"hookOpCmp\"))\n        {\n            return hook.hookOpCmp(get, rhs.get);\n        }\n        else static if (hasMember!(Hook1, \"hookOpCmp\"))\n        {\n            return -rhs.hook.hookOpCmp(rhs.payload, get);\n        }\n        else\n        {\n            return payload < rhs.payload ? -1 : payload > rhs.payload;\n        }\n    }\n\n    ///\n    static if (is(T == int) && is(Hook == void)) @safe unittest\n    {\n        static struct MyHook\n        {\n            static bool thereWereErrors;\n            static int hookOpCmp(L, R)(L lhs, R rhs)\n            {\n                static if (isUnsigned!L && !isUnsigned!R)\n                {\n                    if (rhs < 0 && rhs >= lhs)\n                        thereWereErrors = true;\n                }\n                else static if (isUnsigned!R && !isUnsigned!L)\n                {\n                    if (lhs < 0 && lhs >= rhs)\n                        thereWereErrors = true;\n                }\n                // Preserve built-in behavior.\n                return lhs < rhs ? -1 : lhs > rhs;\n            }\n        }\n        auto a = checked!MyHook(-42);\n        assert(a > uint(42));\n        assert(MyHook.thereWereErrors);\n        static struct MyHook2\n        {\n            static int hookOpCmp(L, R)(L lhs, R rhs)\n            {\n                // Default behavior\n                return lhs < rhs ? -1 : lhs > rhs;\n            }\n        }\n        MyHook.thereWereErrors = false;\n        assert(Checked!(uint, MyHook2)(uint(-42)) <= a);\n        //assert(Checked!(uint, MyHook2)(uint(-42)) >= a);\n        // Hook on left hand side takes precedence, so no errors\n        assert(!MyHook.thereWereErrors);\n        assert(a <= Checked!(uint, MyHook2)(uint(-42)));\n        assert(MyHook.thereWereErrors);\n    }\n\n    // For coverage\n    static if (is(T == int) && is(Hook == void)) @system unittest\n    {\n        assert(checked(42) <= checked!void(42));\n        assert(checked!void(42) <= checked(42u));\n        assert(checked!void(42) <= checked!(void*)(42u));\n    }\n\n    // opUnary\n    /**\n\n    Defines unary operators `+`, `-`, `~`, `++`, and `--`. Unary `+` is not\n    overridable and always has built-in behavior (returns `this`). For the\n    others, if `Hook` defines `hookOpUnary`, `opUnary` forwards to $(D\n    Checked!(typeof(hook.hookOpUnary!op(get)),\n    Hook)(hook.hookOpUnary!op(get))).\n\n    If `Hook` does not define `hookOpUnary` but defines `onOverflow`, `opUnary`\n    forwards to `hook.onOverflow!op(get)` in case an overflow occurs.\n    For `++` and `--`, the payload is assigned from the result of the call to\n    `onOverflow`.\n\n    Note that unary `-` is considered to overflow if `T` is a signed integral of\n    32 or 64 bits and is equal to the most negative value. This is because that\n    value has no positive negation.\n\n    */\n    auto opUnary(string op, this _)()\n    if (op == \"+\" || op == \"-\" || op == \"~\")\n    {\n        static if (op == \"+\")\n            return Checked(this); // \"+\" is not hookable\n        else static if (hasMember!(Hook, \"hookOpUnary\"))\n        {\n            auto r = hook.hookOpUnary!op(payload);\n            return Checked!(typeof(r), Hook)(r);\n        }\n        else static if (op == \"-\" && isIntegral!T && T.sizeof >= 4 &&\n                !isUnsigned!T && hasMember!(Hook, \"onOverflow\"))\n        {\n            static assert(is(typeof(-payload) == typeof(payload)));\n            bool overflow;\n            import core.checkedint : negs;\n            auto r = negs(payload, overflow);\n            if (overflow) r = hook.onOverflow!op(payload);\n            return Checked(r);\n        }\n        else\n            return Checked(mixin(op ~ \"payload\"));\n    }\n\n    /// ditto\n    ref Checked opUnary(string op)() return\n    if (op == \"++\" || op == \"--\")\n    {\n        static if (hasMember!(Hook, \"hookOpUnary\"))\n            hook.hookOpUnary!op(payload);\n        else static if (hasMember!(Hook, \"onOverflow\"))\n        {\n            static if (op == \"++\")\n            {\n                if (payload == max.payload)\n                    payload = hook.onOverflow!\"++\"(payload);\n                else\n                    ++payload;\n            }\n            else\n            {\n                if (payload == min.payload)\n                    payload = hook.onOverflow!\"--\"(payload);\n                else\n                    --payload;\n            }\n        }\n        else\n            mixin(op ~ \"payload;\");\n        return this;\n    }\n\n    ///\n    static if (is(T == int) && is(Hook == void)) @safe unittest\n    {\n        static struct MyHook\n        {\n            static bool thereWereErrors;\n            static L hookOpUnary(string x, L)(L lhs)\n            {\n                if (x == \"-\" && lhs == -lhs) thereWereErrors = true;\n                return -lhs;\n            }\n        }\n        auto a = checked!MyHook(long.min);\n        assert(a == -a);\n        assert(MyHook.thereWereErrors);\n        auto b = checked!void(42);\n        assert(++b == 43);\n    }\n\n    // opBinary\n    /**\n\n    Defines binary operators `+`, `-`, `*`, `/`, `%`, `^^`, `&`, `|`, `^`, `<<`, `>>`,\n    and `>>>`. If `Hook` defines `hookOpBinary`, `opBinary` forwards to $(D\n    Checked!(typeof(hook.hookOpBinary!op(get, rhs)),\n    Hook)(hook.hookOpBinary!op(get, rhs))).\n\n    If `Hook` does not define `hookOpBinary` but defines `onOverflow`,\n    `opBinary` forwards to `hook.onOverflow!op(get, rhs)` in case an\n    overflow occurs.\n\n    If two `Checked` instances are involved in a binary operation and both\n    define `hookOpBinary`, the left-hand side hook has priority. If both define\n    `onOverflow`, a compile-time error occurs.\n\n    */\n    auto opBinary(string op, Rhs)(const Rhs rhs)\n    if (isIntegral!Rhs || isFloatingPoint!Rhs || is(Rhs == bool))\n    {\n        return opBinaryImpl!(op, Rhs, typeof(this))(rhs);\n    }\n\n    /// ditto\n    auto opBinary(string op, Rhs)(const Rhs rhs) const\n    if (isIntegral!Rhs || isFloatingPoint!Rhs || is(Rhs == bool))\n    {\n        return opBinaryImpl!(op, Rhs, typeof(this))(rhs);\n    }\n\n    private auto opBinaryImpl(string op, Rhs, this _)(const Rhs rhs)\n    {\n        alias R = typeof(mixin(\"payload\" ~ op ~ \"rhs\"));\n        static assert(is(typeof(mixin(\"payload\" ~ op ~ \"rhs\")) == R));\n        static if (isIntegral!R) alias Result = Checked!(R, Hook);\n        else alias Result = R;\n\n        static if (hasMember!(Hook, \"hookOpBinary\"))\n        {\n            auto r = hook.hookOpBinary!op(payload, rhs);\n            return Checked!(typeof(r), Hook)(r);\n        }\n        else static if (is(Rhs == bool))\n        {\n            return mixin(\"this\" ~ op ~ \"ubyte(rhs)\");\n        }\n        else static if (isFloatingPoint!Rhs)\n        {\n            return mixin(\"payload\" ~ op ~ \"rhs\");\n        }\n        else static if (hasMember!(Hook, \"onOverflow\"))\n        {\n            bool overflow;\n            auto r = opChecked!op(payload, rhs, overflow);\n            if (overflow) r = hook.onOverflow!op(payload, rhs);\n            return Result(r);\n        }\n        else\n        {\n            // Default is built-in behavior\n            return Result(mixin(\"payload\" ~ op ~ \"rhs\"));\n        }\n    }\n\n    /// ditto\n    auto opBinary(string op, U, Hook1)(Checked!(U, Hook1) rhs)\n    {\n        return opBinaryImpl2!(op, U, Hook1, typeof(this))(rhs);\n    }\n\n    /// ditto\n    auto opBinary(string op, U, Hook1)(Checked!(U, Hook1) rhs) const\n    {\n        return opBinaryImpl2!(op, U, Hook1, typeof(this))(rhs);\n    }\n\n    private\n    auto opBinaryImpl2(string op, U, Hook1, this _)(Checked!(U, Hook1) rhs)\n    {\n        alias R = typeof(get + rhs.payload);\n        static if (valueConvertible!(T, R) && valueConvertible!(U, R) ||\n            is(Hook == Hook1))\n        {\n            // Delegate to lhs\n            return mixin(\"this\" ~ op ~ \"rhs.payload\");\n        }\n        else static if (hasMember!(Hook, \"hookOpBinary\"))\n        {\n            return hook.hookOpBinary!op(payload, rhs);\n        }\n        else static if (hasMember!(Hook1, \"hookOpBinary\"))\n        {\n            // Delegate to rhs\n            return mixin(\"this.payload\" ~ op ~ \"rhs\");\n        }\n        else static if (hasMember!(Hook, \"onOverflow\") &&\n            !hasMember!(Hook1, \"onOverflow\"))\n        {\n            // Delegate to lhs\n            return mixin(\"this\" ~ op ~ \"rhs.payload\");\n        }\n        else static if (hasMember!(Hook1, \"onOverflow\") &&\n            !hasMember!(Hook, \"onOverflow\"))\n        {\n            // Delegate to rhs\n            return mixin(\"this.payload\" ~ op ~ \"rhs\");\n        }\n        else\n        {\n            static assert(0, \"Conflict between lhs and rhs hooks,\" ~\n                \" use .get on one side to disambiguate.\");\n        }\n    }\n\n    static if (is(T == int) && is(Hook == void)) @system unittest\n    {\n        const a = checked(42);\n        assert(a + 1 == 43);\n        assert(a + checked(uint(42)) == 84);\n        assert(checked(42) + checked!void(42u) == 84);\n        assert(checked!void(42) + checked(42u) == 84);\n\n        static struct MyHook\n        {\n            static uint tally;\n            static auto hookOpBinary(string x, L, R)(L lhs, R rhs)\n            {\n                ++tally;\n                return mixin(\"lhs\" ~ x ~ \"rhs\");\n            }\n        }\n        assert(checked!MyHook(42) + checked(42u) == 84);\n        assert(checked!void(42) + checked!MyHook(42u) == 84);\n        assert(MyHook.tally == 2);\n    }\n\n    // opBinaryRight\n    /**\n\n    Defines binary operators `+`, `-`, `*`, `/`, `%`, `^^`, `&`, `|`, `^`, `<<`,\n    `>>`, and `>>>` for the case when a built-in numeric or Boolean type is on\n    the left-hand side, and a `Checked` instance is on the right-hand side.\n\n    */\n    auto opBinaryRight(string op, Lhs)(const Lhs lhs)\n    if (isIntegral!Lhs || isFloatingPoint!Lhs || is(Lhs == bool))\n    {\n        return opBinaryRightImpl!(op, Lhs, typeof(this))(lhs);\n    }\n\n    /// ditto\n    auto opBinaryRight(string op, Lhs)(const Lhs lhs) const\n    if (isIntegral!Lhs || isFloatingPoint!Lhs || is(Lhs == bool))\n    {\n        return opBinaryRightImpl!(op, Lhs, typeof(this))(lhs);\n    }\n\n    private auto opBinaryRightImpl(string op, Lhs, this _)(const Lhs lhs)\n    {\n        static if (hasMember!(Hook, \"hookOpBinaryRight\"))\n        {\n            auto r = hook.hookOpBinaryRight!op(lhs, payload);\n            return Checked!(typeof(r), Hook)(r);\n        }\n        else static if (hasMember!(Hook, \"hookOpBinary\"))\n        {\n            auto r = hook.hookOpBinary!op(lhs, payload);\n            return Checked!(typeof(r), Hook)(r);\n        }\n        else static if (is(Lhs == bool))\n        {\n            return mixin(\"ubyte(lhs)\" ~ op ~ \"this\");\n        }\n        else static if (isFloatingPoint!Lhs)\n        {\n            return mixin(\"lhs\" ~ op ~ \"payload\");\n        }\n        else static if (hasMember!(Hook, \"onOverflow\"))\n        {\n            bool overflow;\n            auto r = opChecked!op(lhs, T(payload), overflow);\n            if (overflow) r = hook.onOverflow!op(42);\n            return Checked!(typeof(r), Hook)(r);\n        }\n        else\n        {\n            // Default is built-in behavior\n            auto r = mixin(\"lhs\" ~ op ~ \"T(payload)\");\n            return Checked!(typeof(r), Hook)(r);\n        }\n    }\n\n    static if (is(T == int) && is(Hook == void)) @system unittest\n    {\n        assert(1 + checked(1) == 2);\n        static uint tally;\n        static struct MyHook\n        {\n            static auto hookOpBinaryRight(string x, L, R)(L lhs, R rhs)\n            {\n                ++tally;\n                return mixin(\"lhs\" ~ x ~ \"rhs\");\n            }\n        }\n        assert(1 + checked!MyHook(1) == 2);\n        assert(tally == 1);\n\n        immutable x1 = checked(1);\n        assert(1 + x1 == 2);\n        immutable x2 = checked!MyHook(1);\n        assert(1 + x2 == 2);\n        assert(tally == 2);\n    }\n\n    // opOpAssign\n    /**\n\n    Defines operators `+=`, `-=`, `*=`, `/=`, `%=`, `^^=`, `&=`, `|=`, `^=`,\n    `<<=`, `>>=`, and `>>>=`.\n\n    If `Hook` defines `hookOpOpAssign`, `opOpAssign` forwards to\n    `hook.hookOpOpAssign!op(payload, rhs)`, where `payload` is a reference to\n    the internally held data so the hook can change it.\n\n    Otherwise, the operator first evaluates $(D auto result =\n    opBinary!op(payload, rhs).payload), which is subject to the hooks in\n    `opBinary`. Then, if `result` is less than $(D Checked!(T, Hook).min) and if\n    `Hook` defines `onLowerBound`, the payload is assigned from $(D\n    hook.onLowerBound(result, min)). If `result` is greater than $(D Checked!(T,\n    Hook).max) and if `Hook` defines `onUpperBound`, the payload is assigned\n    from $(D hook.onUpperBound(result, min)).\n\n    If the right-hand side is also a Checked but with a different hook or\n    underlying type, the hook and underlying type of this Checked takes\n    precedence.\n\n    In all other cases, the built-in behavior is carried out.\n\n    Params:\n    op = The operator involved (without the `\"=\"`, e.g. `\"+\"` for `\"+=\"` etc)\n    rhs = The right-hand side of the operator (left-hand side is `this`)\n\n    Returns: A reference to `this`.\n    */\n    ref Checked opOpAssign(string op, Rhs)(const Rhs rhs) return\n    if (isIntegral!Rhs || isFloatingPoint!Rhs || is(Rhs == bool))\n    {\n        static assert(is(typeof(mixin(\"payload\" ~ op ~ \"=rhs\")) == T));\n\n        static if (hasMember!(Hook, \"hookOpOpAssign\"))\n        {\n            hook.hookOpOpAssign!op(payload, rhs);\n        }\n        else\n        {\n            alias R = typeof(get + rhs);\n            auto r = opBinary!op(rhs).get;\n            import std.conv : unsigned;\n\n            static if (ProperCompare.hookOpCmp(R.min, min.get) < 0 &&\n                hasMember!(Hook, \"onLowerBound\"))\n            {\n                if (ProperCompare.hookOpCmp(r, min.get) < 0)\n                {\n                    // Example: Checked!uint(1) += int(-3)\n                    payload = hook.onLowerBound(r, min.get);\n                    return this;\n                }\n            }\n            static if (ProperCompare.hookOpCmp(max.get, R.max) < 0 &&\n                hasMember!(Hook, \"onUpperBound\"))\n            {\n                if (ProperCompare.hookOpCmp(r, max.get) > 0)\n                {\n                    // Example: Checked!uint(1) += long(uint.max)\n                    payload = hook.onUpperBound(r, max.get);\n                    return this;\n                }\n            }\n            payload = cast(T) r;\n        }\n        return this;\n    }\n\n    /// ditto\n    ref Checked opOpAssign(string op, Rhs)(const Rhs rhs) return\n    if (is(Rhs == Checked!(RhsT, RhsHook), RhsT, RhsHook))\n    {\n        return opOpAssign!(op, typeof(rhs.payload))(rhs.payload);\n    }\n\n    ///\n    static if (is(T == int) && is(Hook == void)) @safe unittest\n    {\n        static struct MyHook\n        {\n            static bool thereWereErrors;\n            static T onLowerBound(Rhs, T)(Rhs rhs, T bound)\n            {\n                thereWereErrors = true;\n                return bound;\n            }\n            static T onUpperBound(Rhs, T)(Rhs rhs, T bound)\n            {\n                thereWereErrors = true;\n                return bound;\n            }\n        }\n        auto x = checked!MyHook(byte.min);\n        x -= 1;\n        assert(MyHook.thereWereErrors);\n        MyHook.thereWereErrors = false;\n        x = byte.max;\n        x += 1;\n        assert(MyHook.thereWereErrors);\n    }\n}\n\n/**\n\nConvenience function that turns an integral into the corresponding `Checked`\ninstance by using template argument deduction. The hook type may be specified\n(by default `Abort`).\n\n*/\nChecked!(T, Hook) checked(Hook = Abort, T)(const T value)\nif (is(typeof(Checked!(T, Hook)(value))))\n{\n    return Checked!(T, Hook)(value);\n}\n\n///\n@system unittest\n{\n    static assert(is(typeof(checked(42)) == Checked!int));\n    assert(checked(42) == Checked!int(42));\n    static assert(is(typeof(checked!WithNaN(42)) == Checked!(int, WithNaN)));\n    assert(checked!WithNaN(42) == Checked!(int, WithNaN)(42));\n}\n\n// get\n@safe unittest\n{\n    void test(T)()\n    {\n        assert(Checked!(T, void)(ubyte(22)).get == 22);\n    }\n    test!ubyte;\n    test!(const ubyte);\n    test!(immutable ubyte);\n}\n\n// Abort\n/**\n\nForce all integral errors to fail by printing an error message to `stderr` and\nthen abort the program. `Abort` is the default second argument for `Checked`.\n\n*/\nstruct Abort\n{\nstatic:\n    /**\n\n    Called automatically upon a bad cast (one that loses precision or attempts\n    to convert a negative value to an unsigned type). The source type is `Src`\n    and the destination type is `Dst`.\n\n    Params:\n    src = The source of the cast\n\n    Returns: Nominally the result is the desired value of the cast operation,\n    which will be forwarded as the result of the cast. For `Abort`, the\n    function never returns because it aborts the program.\n\n    */\n    Dst onBadCast(Dst, Src)(Src src)\n    {\n        Warn.onBadCast!Dst(src);\n        assert(0);\n    }\n\n    /**\n\n    Called automatically upon a bounds error.\n\n    Params:\n    rhs = The right-hand side value in the assignment, after the operator has\n    been evaluated\n    bound = The value of the bound being violated\n\n    Returns: Nominally the result is the desired value of the operator, which\n    will be forwarded as result. For `Abort`, the function never returns because\n    it aborts the program.\n\n    */\n    T onLowerBound(Rhs, T)(Rhs rhs, T bound)\n    {\n        Warn.onLowerBound(rhs, bound);\n        assert(0);\n    }\n    /// ditto\n    T onUpperBound(Rhs, T)(Rhs rhs, T bound)\n    {\n        Warn.onUpperBound(rhs, bound);\n        assert(0);\n    }\n\n    /**\n\n    Called automatically upon a comparison for equality. In case of a erroneous\n    comparison (one that would make a signed negative value appear equal to an\n    unsigned positive value), this hook issues `assert(0)` which terminates the\n    application.\n\n    Params:\n    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of\n      the operator is `Checked!int`\n    rhs = The right-hand side type involved in the operator\n\n    Returns: Upon a correct comparison, returns the result of the comparison.\n    Otherwise, the function terminates the application so it never returns.\n\n    */\n    static bool hookOpEquals(Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        bool error;\n        auto result = opChecked!\"==\"(lhs, rhs, error);\n        if (error)\n        {\n            Warn.hookOpEquals(lhs, rhs);\n            assert(0);\n        }\n        return result;\n    }\n\n    /**\n\n    Called automatically upon a comparison for ordering using one of the\n    operators `<`, `<=`, `>`, or `>=`. In case the comparison is erroneous (i.e.\n    it would make a signed negative value appear greater than or equal to an\n    unsigned positive value), then application is terminated with `assert(0)`.\n    Otherwise, the three-state result is returned (positive if $(D lhs > rhs),\n    negative if $(D lhs < rhs), `0` otherwise).\n\n    Params:\n    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of\n      the operator is `Checked!int`\n    rhs = The right-hand side type involved in the operator\n\n    Returns: For correct comparisons, returns a positive integer if $(D lhs >\n    rhs), a negative integer if  $(D lhs < rhs), `0` if the two are equal. Upon\n    a mistaken comparison such as $(D int(-1) < uint(0)), the function never\n    returns because it aborts the program.\n\n    */\n    int hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        bool error;\n        auto result = opChecked!\"cmp\"(lhs, rhs, error);\n        if (error)\n        {\n            Warn.hookOpCmp(lhs, rhs);\n            assert(0);\n        }\n        return result;\n    }\n\n    /**\n\n    Called automatically upon an overflow during a unary or binary operation.\n\n    Params:\n    x = The operator, e.g. `-`\n    lhs = The left-hand side (or sole) argument\n    rhs = The right-hand side type involved in the operator\n\n    Returns: Nominally the result is the desired value of the operator, which\n    will be forwarded as result. For `Abort`, the function never returns because\n    it aborts the program.\n\n    */\n    typeof(~Lhs()) onOverflow(string x, Lhs)(Lhs lhs)\n    {\n        Warn.onOverflow!x(lhs);\n        assert(0);\n    }\n    /// ditto\n    typeof(Lhs() + Rhs()) onOverflow(string x, Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        Warn.onOverflow!x(lhs, rhs);\n        assert(0);\n    }\n}\n\n@system unittest\n{\n    void test(T)()\n    {\n        Checked!(int, Abort) x;\n        x = 42;\n        auto x1 = cast(T) x;\n        assert(x1 == 42);\n        //x1 += long(int.max);\n    }\n    test!short;\n    test!(const short);\n    test!(immutable short);\n}\n\n\n// Throw\n/**\n\nForce all integral errors to fail by throwing an exception of type\n`Throw.CheckFailure`. The message coming with the error is similar to the one\nprinted by `Warn`.\n\n*/\nstruct Throw\n{\n    /**\n    Exception type thrown upon any failure.\n    */\n    static class CheckFailure : Exception\n    {\n        this(T...)(string f, T vals)\n        {\n            import std.format : format;\n            super(format(f, vals));\n        }\n    }\n\n    /**\n\n    Called automatically upon a bad cast (one that loses precision or attempts\n    to convert a negative value to an unsigned type). The source type is `Src`\n    and the destination type is `Dst`.\n\n    Params:\n    src = The source of the cast\n\n    Returns: Nominally the result is the desired value of the cast operation,\n    which will be forwarded as the result of the cast. For `Throw`, the\n    function never returns because it throws an exception.\n\n    */\n    static Dst onBadCast(Dst, Src)(Src src)\n    {\n        throw new CheckFailure(\"Erroneous cast: cast(%s) %s(%s)\",\n            Dst.stringof, Src.stringof, src);\n    }\n\n    /**\n\n    Called automatically upon a bounds error.\n\n    Params:\n    rhs = The right-hand side value in the assignment, after the operator has\n    been evaluated\n    bound = The value of the bound being violated\n\n    Returns: Nominally the result is the desired value of the operator, which\n    will be forwarded as result. For `Throw`, the function never returns because\n    it throws.\n\n    */\n    static T onLowerBound(Rhs, T)(Rhs rhs, T bound)\n    {\n        throw new CheckFailure(\"Lower bound error: %s(%s) < %s(%s)\",\n            Rhs.stringof, rhs, T.stringof, bound);\n    }\n    /// ditto\n    static T onUpperBound(Rhs, T)(Rhs rhs, T bound)\n    {\n        throw new CheckFailure(\"Upper bound error: %s(%s) > %s(%s)\",\n            Rhs.stringof, rhs, T.stringof, bound);\n    }\n\n    /**\n\n    Called automatically upon a comparison for equality. Throws upon an\n    erroneous comparison (one that would make a signed negative value appear\n    equal to an unsigned positive value).\n\n    Params:\n    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of\n      the operator is `Checked!int`\n    rhs = The right-hand side type involved in the operator\n\n    Returns: The result of the comparison.\n\n    Throws: `CheckFailure` if the comparison is mathematically erroneous.\n\n    */\n    static bool hookOpEquals(L, R)(L lhs, R rhs)\n    {\n        bool error;\n        auto result = opChecked!\"==\"(lhs, rhs, error);\n        if (error)\n        {\n            throw new CheckFailure(\"Erroneous comparison: %s(%s) == %s(%s)\",\n                L.stringof, lhs, R.stringof, rhs);\n        }\n        return result;\n    }\n\n    /**\n\n    Called automatically upon a comparison for ordering using one of the\n    operators `<`, `<=`, `>`, or `>=`. In case the comparison is erroneous (i.e.\n    it would make a signed negative value appear greater than or equal to an\n    unsigned positive value), throws a `Throw.CheckFailure` exception.\n    Otherwise, the three-state result is returned (positive if $(D lhs > rhs),\n    negative if $(D lhs < rhs), `0` otherwise).\n\n    Params:\n    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of\n      the operator is `Checked!int`\n    rhs = The right-hand side type involved in the operator\n\n    Returns: For correct comparisons, returns a positive integer if $(D lhs >\n    rhs), a negative integer if  $(D lhs < rhs), `0` if the two are equal.\n\n    Throws: Upon a mistaken comparison such as $(D int(-1) < uint(0)), the\n    function never returns because it throws a `Throw.CheckedFailure` exception.\n\n    */\n    static int hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        bool error;\n        auto result = opChecked!\"cmp\"(lhs, rhs, error);\n        if (error)\n        {\n            throw new CheckFailure(\"Erroneous ordering comparison: %s(%s) and %s(%s)\",\n                Lhs.stringof, lhs, Rhs.stringof, rhs);\n        }\n        return result;\n    }\n\n    /**\n\n    Called automatically upon an overflow during a unary or binary operation.\n\n    Params:\n    x = The operator, e.g. `-`\n    lhs = The left-hand side (or sole) argument\n    rhs = The right-hand side type involved in the operator\n\n    Returns: Nominally the result is the desired value of the operator, which\n    will be forwarded as result. For `Throw`, the function never returns because\n    it throws an exception.\n\n    */\n    static typeof(~Lhs()) onOverflow(string x, Lhs)(Lhs lhs)\n    {\n        throw new CheckFailure(\"Overflow on unary operator: %s%s(%s)\",\n            x, Lhs.stringof, lhs);\n    }\n    /// ditto\n    static typeof(Lhs() + Rhs()) onOverflow(string x, Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        throw new CheckFailure(\"Overflow on binary operator: %s(%s) %s %s(%s)\",\n            Lhs.stringof, lhs, x, Rhs.stringof, rhs);\n    }\n}\n\n///\n@safe unittest\n{\n    void test(T)()\n    {\n        Checked!(int, Throw) x;\n        x = 42;\n        auto x1 = cast(T) x;\n        assert(x1 == 42);\n        x = T.max + 1;\n        import std.exception : assertThrown, assertNotThrown;\n        assertThrown(cast(T) x);\n        x = x.max;\n        assertThrown(x += 42);\n        assertThrown(x += 42L);\n        x = x.min;\n        assertThrown(-x);\n        assertThrown(x -= 42);\n        assertThrown(x -= 42L);\n        x = -1;\n        assertNotThrown(x == -1);\n        assertThrown(x == uint(-1));\n        assertNotThrown(x <= -1);\n        assertThrown(x <= uint(-1));\n    }\n    test!short;\n    test!(const short);\n    test!(immutable short);\n}\n\n// Warn\n/**\nHook that prints to `stderr` a trace of all integral errors, without affecting\ndefault behavior.\n*/\nstruct Warn\n{\n    import std.stdio : stderr;\nstatic:\n    /**\n\n    Called automatically upon a bad cast from `src` to type `Dst` (one that\n    loses precision or attempts to convert a negative value to an unsigned\n    type).\n\n    Params:\n    src = The source of the cast\n    Dst = The target type of the cast\n\n    Returns: `cast(Dst) src`\n\n    */\n    Dst onBadCast(Dst, Src)(Src src)\n    {\n        stderr.writefln(\"Erroneous cast: cast(%s) %s(%s)\",\n            Dst.stringof, Src.stringof, src);\n        return cast(Dst) src;\n    }\n\n    /**\n\n    Called automatically upon a bad `opOpAssign` call (one that loses precision\n    or attempts to convert a negative value to an unsigned type).\n\n    Params:\n    rhs = The right-hand side value in the assignment, after the operator has\n    been evaluated\n    bound = The bound being violated\n\n    Returns: `cast(Lhs) rhs`\n    */\n    Lhs onLowerBound(Rhs, T)(Rhs rhs, T bound)\n    {\n        stderr.writefln(\"Lower bound error: %s(%s) < %s(%s)\",\n            Rhs.stringof, rhs, T.stringof, bound);\n        return cast(T) rhs;\n    }\n    /// ditto\n    T onUpperBound(Rhs, T)(Rhs rhs, T bound)\n    {\n        stderr.writefln(\"Upper bound error: %s(%s) > %s(%s)\",\n            Rhs.stringof, rhs, T.stringof, bound);\n        return cast(T) rhs;\n    }\n\n    /**\n\n    Called automatically upon a comparison for equality. In case of an Erroneous\n    comparison (one that would make a signed negative value appear equal to an\n    unsigned positive value), writes a warning message to `stderr` as a side\n    effect.\n\n    Params:\n    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of\n      the operator is `Checked!int`\n    rhs = The right-hand side type involved in the operator\n\n    Returns: In all cases the function returns the built-in result of $(D lhs ==\n    rhs).\n\n    */\n    bool hookOpEquals(Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        bool error;\n        auto result = opChecked!\"==\"(lhs, rhs, error);\n        if (error)\n        {\n            stderr.writefln(\"Erroneous comparison: %s(%s) == %s(%s)\",\n                Lhs.stringof, lhs, Rhs.stringof, rhs);\n            return lhs == rhs;\n        }\n        return result;\n    }\n\n    ///\n    @system unittest\n    {\n        auto x = checked!Warn(-42);\n        // Passes\n        assert(x == -42);\n        // Passes but prints a warning\n        // assert(x == uint(-42));\n    }\n\n    /**\n\n    Called automatically upon a comparison for ordering using one of the\n    operators `<`, `<=`, `>`, or `>=`. In case the comparison is erroneous (i.e.\n    it would make a signed negative value appear greater than or equal to an\n    unsigned positive value), then a warning message is printed to `stderr`.\n\n    Params:\n    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of\n      the operator is `Checked!int`\n    rhs = The right-hand side type involved in the operator\n\n    Returns: In all cases, returns $(D lhs < rhs ? -1 : lhs > rhs). The result\n    is  not autocorrected in case of an erroneous comparison.\n\n    */\n    int hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        bool error;\n        auto result = opChecked!\"cmp\"(lhs, rhs, error);\n        if (error)\n        {\n            stderr.writefln(\"Erroneous ordering comparison: %s(%s) and %s(%s)\",\n                Lhs.stringof, lhs, Rhs.stringof, rhs);\n            return lhs < rhs ? -1 : lhs > rhs;\n        }\n        return result;\n    }\n\n    ///\n    @system unittest\n    {\n        auto x = checked!Warn(-42);\n        // Passes\n        assert(x <= -42);\n        // Passes but prints a warning\n        // assert(x <= uint(-42));\n    }\n\n    /**\n\n    Called automatically upon an overflow during a unary or binary operation.\n\n    Params:\n    x = The operator involved\n    Lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of\n      the operator is `Checked!int`\n    Rhs = The right-hand side type involved in the operator\n\n    Returns: $(D mixin(x ~ \"lhs\")) for unary, $(D mixin(\"lhs\" ~ x ~ \"rhs\")) for\n    binary\n\n    */\n    typeof(~Lhs()) onOverflow(string x, Lhs)(ref Lhs lhs)\n    {\n        stderr.writefln(\"Overflow on unary operator: %s%s(%s)\",\n            x, Lhs.stringof, lhs);\n        return mixin(x ~ \"lhs\");\n    }\n    /// ditto\n    typeof(Lhs() + Rhs()) onOverflow(string x, Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        stderr.writefln(\"Overflow on binary operator: %s(%s) %s %s(%s)\",\n            Lhs.stringof, lhs, x, Rhs.stringof, rhs);\n        return mixin(\"lhs\" ~ x ~ \"rhs\");\n    }\n}\n\n///\n@system unittest\n{\n    auto x = checked!Warn(42);\n    short x1 = cast(short) x;\n    //x += long(int.max);\n    auto y = checked!Warn(cast(const int) 42);\n    short y1 = cast(const byte) y;\n}\n\n// ProperCompare\n/**\n\nHook that provides arithmetically correct comparisons for equality and ordering.\nComparing an object of type $(D Checked!(X, ProperCompare)) against another\nintegral (for equality or ordering) ensures that no surprising conversions from\nsigned to unsigned integral occur before the comparison. Using $(D Checked!(X,\nProperCompare)) on either side of a comparison for equality against a\nfloating-point number makes sure the integral can be properly converted to the\nfloating point type, thus making sure equality is transitive.\n\n*/\nstruct ProperCompare\n{\n    /**\n    Hook for `==` and `!=` that ensures comparison against integral values has\n    the behavior expected by the usual arithmetic rules. The built-in semantics\n    yield surprising behavior when comparing signed values against unsigned\n    values for equality, for example $(D uint.max == -1) or $(D -1_294_967_296 ==\n    3_000_000_000u). The call $(D hookOpEquals(x, y)) returns `true` if and only\n    if `x` and `y` represent the same arithmetic number.\n\n    If one of the numbers is an integral and the other is a floating-point\n    number, $(D hookOpEquals(x, y)) returns `true` if and only if the integral\n    can be converted exactly (without approximation) to the floating-point\n    number. This is in order to preserve transitivity of equality: if $(D\n    hookOpEquals(x, y)) and $(D hookOpEquals(y, z)) then $(D hookOpEquals(y,\n    z)), in case `x`, `y`, and `z` are a mix of integral and floating-point\n    numbers.\n\n    Params:\n    lhs = The left-hand side of the comparison for equality\n    rhs = The right-hand side of the comparison for equality\n\n    Returns:\n    The result of the comparison, `true` if the values are equal\n    */\n    static bool hookOpEquals(L, R)(L lhs, R rhs)\n    {\n        alias C = typeof(lhs + rhs);\n        static if (isFloatingPoint!C)\n        {\n            static if (!isFloatingPoint!L)\n            {\n                return hookOpEquals(rhs, lhs);\n            }\n            else static if (!isFloatingPoint!R)\n            {\n                static assert(isFloatingPoint!L && !isFloatingPoint!R);\n                auto rhs1 = C(rhs);\n                return lhs == rhs1 && cast(R) rhs1 == rhs;\n            }\n            else\n                return lhs == rhs;\n        }\n        else\n        {\n            bool error;\n            auto result = opChecked!\"==\"(lhs, rhs, error);\n            if (error)\n            {\n                // Only possible error is a wrong \"true\"\n                return false;\n            }\n            return result;\n        }\n    }\n\n    /**\n    Hook for `<`, `<=`, `>`, and `>=` that ensures comparison against integral\n    values has the behavior expected by the usual arithmetic rules. The built-in\n    semantics yield surprising behavior when comparing signed values against\n    unsigned values, for example $(D 0u < -1). The call $(D hookOpCmp(x, y))\n    returns `-1` if and only if `x` is smaller than `y` in abstract arithmetic\n    sense.\n\n    If one of the numbers is an integral and the other is a floating-point\n    number, $(D hookOpEquals(x, y)) returns a floating-point number that is `-1`\n    if `x < y`, `0` if `x == y`, `1` if `x > y`, and `NaN` if the floating-point\n    number is `NaN`.\n\n    Params:\n    lhs = The left-hand side of the comparison for ordering\n    rhs = The right-hand side of the comparison for ordering\n\n    Returns:\n    The result of the comparison (negative if $(D lhs < rhs), positive if $(D\n    lhs > rhs), `0` if the values are equal)\n    */\n    static auto hookOpCmp(L, R)(L lhs, R rhs)\n    {\n        alias C = typeof(lhs + rhs);\n        static if (isFloatingPoint!C)\n        {\n            return lhs < rhs\n                ? C(-1)\n                : lhs > rhs ? C(1) : lhs == rhs ? C(0) : C.init;\n        }\n        else\n        {\n            static if (!valueConvertible!(L, C) || !valueConvertible!(R, C))\n            {\n                static assert(isUnsigned!C);\n                static assert(isUnsigned!L != isUnsigned!R);\n                if (!isUnsigned!L && lhs < 0)\n                    return -1;\n                if (!isUnsigned!R && rhs < 0)\n                    return 1;\n            }\n            return lhs < rhs ? -1 : lhs > rhs;\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    alias opEqualsProper = ProperCompare.hookOpEquals;\n    assert(opEqualsProper(42, 42));\n    assert(opEqualsProper(42.0, 42.0));\n    assert(opEqualsProper(42u, 42));\n    assert(opEqualsProper(42, 42u));\n    assert(-1 == 4294967295u);\n    assert(!opEqualsProper(-1, 4294967295u));\n    assert(!opEqualsProper(const uint(-1), -1));\n    assert(!opEqualsProper(uint(-1), -1.0));\n    assert(3_000_000_000U == -1_294_967_296);\n    assert(!opEqualsProper(3_000_000_000U, -1_294_967_296));\n}\n\n@safe unittest\n{\n    alias opCmpProper = ProperCompare.hookOpCmp;\n    assert(opCmpProper(42, 42) == 0);\n    assert(opCmpProper(42, 42.0) == 0);\n    assert(opCmpProper(41, 42.0) < 0);\n    assert(opCmpProper(42, 41.0) > 0);\n    import std.math : isNaN;\n    assert(isNaN(opCmpProper(41, double.init)));\n    assert(opCmpProper(42u, 42) == 0);\n    assert(opCmpProper(42, 42u) == 0);\n    assert(opCmpProper(-1, uint(-1)) < 0);\n    assert(opCmpProper(uint(-1), -1) > 0);\n    assert(opCmpProper(-1.0, -1) == 0);\n}\n\n@safe unittest\n{\n    auto x1 = Checked!(uint, ProperCompare)(42u);\n    assert(x1.get < -1);\n    assert(x1 > -1);\n}\n\n// WithNaN\n/**\n\nHook that reserves a special value as a \"Not a Number\" representative. For\nsigned integrals, the reserved value is `T.min`. For signed integrals, the\nreserved value is `T.max`.\n\nThe default value of a $(D Checked!(X, WithNaN)) is its NaN value, so care must\nbe taken that all variables are explicitly initialized. Any arithmetic and logic\noperation involving at least on NaN becomes NaN itself. All of $(D a == b), $(D\na < b), $(D a > b), $(D a <= b), $(D a >= b) yield `false` if at least one of\n`a` and `b` is NaN.\n\n*/\nstruct WithNaN\n{\nstatic:\n    /**\n    The default value used for values not explicitly initialized. It is the NaN\n    value, i.e. `T.min` for signed integrals and `T.max` for unsigned integrals.\n    */\n    enum T defaultValue(T) = T.min == 0 ? T.max : T.min;\n    /**\n    The maximum value representable is `T.max` for signed integrals, $(D\n    T.max - 1) for unsigned integrals. The minimum value representable is $(D\n    T.min + 1) for signed integrals, `0` for unsigned integrals.\n    */\n    enum T max(T) = cast(T) (T.min == 0 ? T.max - 1 : T.max);\n    /// ditto\n    enum T min(T) = cast(T) (T.min == 0 ? T(0) : T.min + 1);\n\n    /**\n    If `rhs` is `WithNaN.defaultValue!Rhs`, returns\n    `WithNaN.defaultValue!Lhs`. Otherwise, returns $(D cast(Lhs) rhs).\n\n    Params:\n    rhs = the value being cast (`Rhs` is the first argument to `Checked`)\n    Lhs = the target type of the cast\n\n    Returns: The result of the cast operation.\n    */\n    Lhs hookOpCast(Lhs, Rhs)(Rhs rhs)\n    {\n        static if (is(Lhs == bool))\n        {\n            return rhs != defaultValue!Rhs && rhs != 0;\n        }\n        else static if (valueConvertible!(Rhs, Lhs))\n        {\n            return rhs != defaultValue!Rhs ? Lhs(rhs) : defaultValue!Lhs;\n        }\n        else\n        {\n            // Not value convertible, only viable option is rhs fits within the\n            // bounds of Lhs\n            static if (ProperCompare.hookOpCmp(Rhs.min, Lhs.min) < 0)\n            {\n                // Example: hookOpCast!short(int(42)), hookOpCast!uint(int(42))\n                if (ProperCompare.hookOpCmp(rhs, Lhs.min) < 0)\n                    return defaultValue!Lhs;\n            }\n            static if (ProperCompare.hookOpCmp(Rhs.max, Lhs.max) > 0)\n            {\n                // Example: hookOpCast!int(uint(42))\n                if (ProperCompare.hookOpCmp(rhs, Lhs.max) > 0)\n                    return defaultValue!Lhs;\n            }\n            return cast(Lhs) rhs;\n        }\n    }\n\n    ///\n    @safe unittest\n    {\n        auto x = checked!WithNaN(422);\n        assert((cast(ubyte) x) == 255);\n        x = checked!WithNaN(-422);\n        assert((cast(byte) x) == -128);\n        assert(cast(short) x == -422);\n        assert(cast(bool) x);\n        x = x.init; // set back to NaN\n        assert(x != true);\n        assert(x != false);\n    }\n\n    /**\n\n    Returns `false` if $(D lhs == WithNaN.defaultValue!Lhs), $(D lhs == rhs)\n    otherwise.\n\n    Params:\n    lhs = The left-hand side of the comparison (`Lhs` is the first argument to\n    `Checked`)\n    rhs = The right-hand side of the comparison\n\n    Returns: `lhs != WithNaN.defaultValue!Lhs && lhs == rhs`\n    */\n    bool hookOpEquals(Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        return lhs != defaultValue!Lhs && lhs == rhs;\n    }\n\n    /**\n\n    If $(D lhs == WithNaN.defaultValue!Lhs), returns `double.init`. Otherwise,\n    has the same semantics as the default comparison.\n\n    Params:\n    lhs = The left-hand side of the comparison (`Lhs` is the first argument to\n    `Checked`)\n    rhs = The right-hand side of the comparison\n\n    Returns: `double.init` if `lhs == WitnNaN.defaultValue!Lhs`, `-1.0` if $(D\n    lhs < rhs), `0.0` if $(D lhs == rhs), `1.0` if $(D lhs > rhs).\n\n    */\n    double hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        if (lhs == defaultValue!Lhs) return double.init;\n        return lhs < rhs\n            ? -1.0\n            : lhs > rhs ? 1.0 : lhs == rhs ? 0.0 : double.init;\n    }\n\n    ///\n    @safe unittest\n    {\n        Checked!(int, WithNaN) x;\n        assert(!(x < 0) && !(x > 0) && !(x == 0));\n        x = 1;\n        assert(x > 0 && !(x < 0) && !(x == 0));\n    }\n\n    /**\n    Defines hooks for unary operators `-`, `~`, `++`, and `--`.\n\n    For `-` and `~`, if $(D v == WithNaN.defaultValue!T), returns\n    `WithNaN.defaultValue!T`. Otherwise, the semantics is the same as for the\n    built-in operator.\n\n    For `++` and `--`, if $(D v == WithNaN.defaultValue!Lhs) or the operation\n    would result in an overflow, sets `v` to `WithNaN.defaultValue!T`.\n    Otherwise, the semantics is the same as for the built-in operator.\n\n    Params:\n    x = The operator symbol\n    v = The left-hand side of the comparison (`T` is the first argument to\n    `Checked`)\n\n    Returns: $(UL $(LI For $(D x == \"-\" || x == \"~\"): If  $(D v ==\n    WithNaN.defaultValue!T), the function returns `WithNaN.defaultValue!T`.\n    Otherwise it returns the normal result of the operator.) $(LI For $(D x ==\n    \"++\" || x == \"--\"): The function returns `void`.))\n\n    */\n    auto hookOpUnary(string x, T)(ref T v)\n    {\n        static if (x == \"-\" || x == \"~\")\n        {\n            return v != defaultValue!T ? mixin(x ~ \"v\") : v;\n        }\n        else static if (x == \"++\")\n        {\n            static if (defaultValue!T == T.min)\n            {\n                if (v != defaultValue!T)\n                {\n                    if (v == T.max) v = defaultValue!T;\n                    else ++v;\n                }\n            }\n            else\n            {\n                static assert(defaultValue!T == T.max);\n                if (v != defaultValue!T) ++v;\n            }\n        }\n        else static if (x == \"--\")\n        {\n            if (v != defaultValue!T) --v;\n        }\n    }\n\n    ///\n    @safe unittest\n    {\n        Checked!(int, WithNaN) x;\n        ++x;\n        assert(x.isNaN);\n        x = 1;\n        assert(!x.isNaN);\n        x = -x;\n        ++x;\n        assert(!x.isNaN);\n    }\n\n    @safe unittest // for coverage\n    {\n        Checked!(uint, WithNaN) y;\n        ++y;\n        assert(y.isNaN);\n    }\n\n    /**\n    Defines hooks for binary operators `+`, `-`, `*`, `/`, `%`, `^^`, `&`, `|`,\n     `^`, `<<`, `>>`, and `>>>` for cases where a `Checked` object is the\n    left-hand side operand. If $(D lhs == WithNaN.defaultValue!Lhs), returns\n    $(D WithNaN.defaultValue!(typeof(lhs + rhs))) without evaluating the\n    operand. Otherwise, evaluates the operand. If evaluation does not overflow,\n    returns the result. Otherwise, returns $(D WithNaN.defaultValue!(typeof(lhs\n    + rhs))).\n\n    Params:\n    x = The operator symbol\n    lhs = The left-hand side operand (`Lhs` is the first argument to `Checked`)\n    rhs = The right-hand side operand\n\n    Returns: If $(D lhs != WithNaN.defaultValue!Lhs) and the operator does not\n    overflow, the function returns the same result as the built-in operator. In\n    all other cases, returns $(D WithNaN.defaultValue!(typeof(lhs + rhs))).\n    */\n    auto hookOpBinary(string x, L, R)(L lhs, R rhs)\n    {\n        alias Result = typeof(lhs + rhs);\n        if (lhs != defaultValue!L)\n        {\n            bool error;\n            auto result = opChecked!x(lhs, rhs, error);\n            if (!error) return result;\n        }\n        return defaultValue!Result;\n    }\n\n    ///\n    @safe unittest\n    {\n        Checked!(int, WithNaN) x;\n        assert((x + 1).isNaN);\n        x = 100;\n        assert(!(x + 1).isNaN);\n    }\n\n    /**\n    Defines hooks for binary operators `+`, `-`, `*`, `/`, `%`, `^^`, `&`, `|`,\n     `^`, `<<`, `>>`, and `>>>` for cases where a `Checked` object is the\n    right-hand side operand. If $(D rhs == WithNaN.defaultValue!Rhs), returns\n    $(D WithNaN.defaultValue!(typeof(lhs + rhs))) without evaluating the\n    operand. Otherwise, evaluates the operand. If evaluation does not overflow,\n    returns the result. Otherwise, returns $(D WithNaN.defaultValue!(typeof(lhs\n    + rhs))).\n\n    Params:\n    x = The operator symbol\n    lhs = The left-hand side operand\n    rhs = The right-hand side operand (`Rhs` is the first argument to `Checked`)\n\n    Returns: If $(D rhs != WithNaN.defaultValue!Rhs) and the operator does not\n    overflow, the function returns the same result as the built-in operator. In\n    all other cases, returns $(D WithNaN.defaultValue!(typeof(lhs + rhs))).\n    */\n    auto hookOpBinaryRight(string x, L, R)(L lhs, R rhs)\n    {\n        alias Result = typeof(lhs + rhs);\n        if (rhs != defaultValue!R)\n        {\n            bool error;\n            auto result = opChecked!x(lhs, rhs, error);\n            if (!error) return result;\n        }\n        return defaultValue!Result;\n    }\n    ///\n    @safe unittest\n    {\n        Checked!(int, WithNaN) x;\n        assert((1 + x).isNaN);\n        x = 100;\n        assert(!(1 + x).isNaN);\n    }\n\n    /**\n\n    Defines hooks for binary operators `+=`, `-=`, `*=`, `/=`, `%=`, `^^=`,\n    `&=`, `|=`, `^=`, `<<=`, `>>=`, and `>>>=` for cases where a `Checked`\n    object is the left-hand side operand. If $(D lhs ==\n    WithNaN.defaultValue!Lhs), no action is carried. Otherwise, evaluates the\n    operand. If evaluation does not overflow and fits in `Lhs` without loss of\n    information or change of sign, sets `lhs` to the result. Otherwise, sets\n    `lhs` to `WithNaN.defaultValue!Lhs`.\n\n    Params:\n    x = The operator symbol (without the `=`)\n    lhs = The left-hand side operand (`Lhs` is the first argument to `Checked`)\n    rhs = The right-hand side operand\n\n    Returns: `void`\n    */\n    void hookOpOpAssign(string x, L, R)(ref L lhs, R rhs)\n    {\n        if (lhs == defaultValue!L)\n            return;\n        bool error;\n        auto temp = opChecked!x(lhs, rhs, error);\n        lhs = error\n            ? defaultValue!L\n            : hookOpCast!L(temp);\n    }\n\n    ///\n    @safe unittest\n    {\n        Checked!(int, WithNaN) x;\n        x += 4;\n        assert(x.isNaN);\n        x = 0;\n        x += 4;\n        assert(!x.isNaN);\n        x += int.max;\n        assert(x.isNaN);\n    }\n}\n\n///\n@safe unittest\n{\n    auto x1 = Checked!(int, WithNaN)();\n    assert(x1.isNaN);\n    assert(x1.get == int.min);\n    assert(x1 != x1);\n    assert(!(x1 < x1));\n    assert(!(x1 > x1));\n    assert(!(x1 == x1));\n    ++x1;\n    assert(x1.isNaN);\n    assert(x1.get == int.min);\n    --x1;\n    assert(x1.isNaN);\n    assert(x1.get == int.min);\n    x1 = 42;\n    assert(!x1.isNaN);\n    assert(x1 == x1);\n    assert(x1 <= x1);\n    assert(x1 >= x1);\n    static assert(x1.min == int.min + 1);\n    x1 += long(int.max);\n}\n\n/**\nQueries whether a $(D Checked!(T, WithNaN)) object is not a number (NaN).\n\nParams: x = the `Checked` instance queried\n\nReturns: `true` if `x` is a NaN, `false` otherwise\n*/\nbool isNaN(T)(const Checked!(T, WithNaN) x)\n{\n    return x.get == x.init.get;\n}\n\n///\n@safe unittest\n{\n    auto x1 = Checked!(int, WithNaN)();\n    assert(x1.isNaN);\n    x1 = 1;\n    assert(!x1.isNaN);\n    x1 = x1.init;\n    assert(x1.isNaN);\n}\n\n@safe unittest\n{\n    void test1(T)()\n    {\n        auto x1 = Checked!(T, WithNaN)();\n        assert(x1.isNaN);\n        assert(x1.get == int.min);\n        assert(x1 != x1);\n        assert(!(x1 < x1));\n        assert(!(x1 > x1));\n        assert(!(x1 == x1));\n        assert(x1.get == int.min);\n        auto x2 = Checked!(T, WithNaN)(42);\n        assert(!x2.isNaN);\n        assert(x2 == x2);\n        assert(x2 <= x2);\n        assert(x2 >= x2);\n        static assert(x2.min == T.min + 1);\n    }\n    test1!int;\n    test1!(const int);\n    test1!(immutable int);\n\n    void test2(T)()\n    {\n        auto x1 = Checked!(T, WithNaN)();\n        assert(x1.get == T.min);\n        assert(x1 != x1);\n        assert(!(x1 < x1));\n        assert(!(x1 > x1));\n        assert(!(x1 == x1));\n        ++x1;\n        assert(x1.get == T.min);\n        --x1;\n        assert(x1.get == T.min);\n        x1 = 42;\n        assert(x1 == x1);\n        assert(x1 <= x1);\n        assert(x1 >= x1);\n        static assert(x1.min == T.min + 1);\n        x1 += long(T.max);\n    }\n    test2!int;\n}\n\n@safe unittest\n{\n    alias Smart(T) = Checked!(Checked!(T, ProperCompare), WithNaN);\n    Smart!int x1;\n    assert(x1 != x1);\n    x1 = -1;\n    assert(x1 < 1u);\n    auto x2 = Smart!(const int)(42);\n}\n\n// Saturate\n/**\n\nHook that implements $(I saturation), i.e. any arithmetic operation that would\noverflow leaves the result at its extreme value (`min` or `max` depending on the\ndirection of the overflow).\n\nSaturation is not sticky; if a value reaches its saturation value, another\noperation may take it back to normal range.\n\n*/\nstruct Saturate\n{\nstatic:\n    /**\n\n    Implements saturation for operators `+=`, `-=`, `*=`, `/=`, `%=`, `^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`,\n    and `>>>=`. This hook is called if the result of the binary operation does\n    not fit in `Lhs` without loss of information or a change in sign.\n\n    Params:\n    Rhs = The right-hand side type in the assignment, after the operation has\n    been computed\n    bound = The bound being violated\n\n    Returns: `Lhs.max` if $(D rhs >= 0), `Lhs.min` otherwise.\n\n    */\n    T onLowerBound(Rhs, T)(Rhs rhs, T bound)\n    {\n        return bound;\n    }\n    /// ditto\n    T onUpperBound(Rhs, T)(Rhs rhs, T bound)\n    {\n        return bound;\n    }\n    ///\n    @safe unittest\n    {\n        auto x = checked!Saturate(short(100));\n        x += 33000;\n        assert(x == short.max);\n        x -= 70000;\n        assert(x == short.min);\n    }\n\n    /**\n\n    Implements saturation for operators `+`, `-` (unary and binary), `*`, `/`,\n    `%`, `^^`, `&`, `|`, `^`, `<<`, `>>`, and `>>>`.\n\n    For unary `-`, `onOverflow` is called if $(D lhs == Lhs.min) and `Lhs` is a\n    signed type. The function returns `Lhs.max`.\n\n    For binary operators, the result is as follows: $(UL $(LI `Lhs.max` if the\n    result overflows in the positive direction, on division by `0`, or on\n    shifting right by a negative value) $(LI `Lhs.min` if the result overflows\n    in the negative direction) $(LI `0` if `lhs` is being shifted left by a\n    negative value, or shifted right by a large positive value))\n\n    Params:\n    x = The operator involved in the `opAssign` operation\n    Lhs = The left-hand side of the operator (`Lhs` is the first argument to\n    `Checked`)\n    Rhs = The right-hand side type in the operator\n\n    Returns: The saturated result of the operator.\n\n    */\n    auto onOverflow(string x, Lhs)(Lhs lhs)\n    {\n        static assert(x == \"-\" || x == \"++\" || x == \"--\");\n        return x == \"--\" ? Lhs.min : Lhs.max;\n    }\n    /// ditto\n    typeof(Lhs() + Rhs()) onOverflow(string x, Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        static if (x == \"+\")\n            return rhs >= 0 ? Lhs.max : Lhs.min;\n        else static if (x == \"*\")\n            return (lhs >= 0) == (rhs >= 0) ? Lhs.max : Lhs.min;\n        else static if (x == \"^^\")\n            return lhs > 0 || !(rhs & 1) ? Lhs.max : Lhs.min;\n        else static if (x == \"-\")\n            return rhs >= 0 ? Lhs.min : Lhs.max;\n        else static if (x == \"/\" || x == \"%\")\n            return Lhs.max;\n        else static if (x == \"<<\")\n            return rhs >= 0 ? Lhs.max : 0;\n        else static if (x == \">>\" || x == \">>>\")\n            return rhs >= 0 ? 0 : Lhs.max;\n        else\n            static assert(false);\n    }\n    ///\n    @safe unittest\n    {\n        assert(checked!Saturate(int.max) + 1 == int.max);\n        assert(checked!Saturate(100) ^^ 10 == int.max);\n        assert(checked!Saturate(-100) ^^ 10 == int.max);\n        assert(checked!Saturate(100) / 0 == int.max);\n        assert(checked!Saturate(100) << -1 == 0);\n        assert(checked!Saturate(100) << 33 == int.max);\n        assert(checked!Saturate(100) >> -1 == int.max);\n        assert(checked!Saturate(100) >> 33 == 0);\n    }\n}\n\n///\n@safe unittest\n{\n    auto x = checked!Saturate(int.max);\n    ++x;\n    assert(x == int.max);\n    --x;\n    assert(x == int.max - 1);\n    x = int.min;\n    assert(-x == int.max);\n    x -= 42;\n    assert(x == int.min);\n    assert(x * -2 == int.max);\n}\n\n/*\nYields `true` if `T1` is \"value convertible\" (by C's \"value preserving\" rule,\nsee $(HTTP c-faq.com/expr/preservingrules.html)) to `T2`, where the two are\nintegral types. That is, all of values in `T1` are also in `T2`. For example\n`int` is value convertible to `long` but not to `uint` or `ulong`.\n*/\nprivate enum valueConvertible(T1, T2) = isIntegral!T1 && isIntegral!T2 &&\n    is(T1 : T2) && (\n        isUnsigned!T1 == isUnsigned!T2 || // same signedness\n        !isUnsigned!T2 && T2.sizeof > T1.sizeof // safely convertible\n    );\n\n/**\n\nDefines binary operations with overflow checking for any two integral types.\nThe result type obeys the language rules (even when they may be\ncounterintuitive), and `overflow` is set if an overflow occurs (including\ninadvertent change of signedness, e.g. `-1` is converted to `uint`).\nConceptually the behavior is:\n\n$(OL $(LI Perform the operation in infinite precision)\n$(LI If the infinite-precision result fits in the result type, return it and\ndo not touch `overflow`)\n$(LI Otherwise, set `overflow` to `true` and return an unspecified value)\n)\n\nThe implementation exploits properties of types and operations to minimize\nadditional work.\n\nParams:\nx = The binary operator involved, e.g. `/`\nlhs = The left-hand side of the operator\nrhs = The right-hand side of the operator\noverflow = The overflow indicator (assigned `true` in case there's an error)\n\nReturns:\nThe result of the operation, which is the same as the built-in operator\n*/\ntypeof(mixin(x == \"cmp\" ? \"0\" : (\"L() \" ~ x ~ \" R()\")))\nopChecked(string x, L, R)(const L lhs, const R rhs, ref bool overflow)\nif (isIntegral!L && isIntegral!R)\n{\n    static if (x == \"cmp\")\n        alias Result = int;\n    else\n        alias Result = typeof(mixin(\"L() \" ~ x ~ \" R()\"));\n\n    import core.checkedint : addu, adds, subs, muls, subu, mulu;\n    import std.algorithm.comparison : among;\n    static if (x == \"==\")\n    {\n        alias C = typeof(lhs + rhs);\n        static if (valueConvertible!(L, C) && valueConvertible!(R, C))\n        {\n            // Values are converted to R before comparison, cool.\n            return lhs == rhs;\n        }\n        else\n        {\n            static assert(isUnsigned!C);\n            static assert(isUnsigned!L != isUnsigned!R);\n            if (lhs != rhs) return false;\n            // R(lhs) and R(rhs) have the same bit pattern, yet may be\n            // different due to signedness change.\n            static if (!isUnsigned!R)\n            {\n                if (rhs >= 0)\n                    return true;\n            }\n            else\n            {\n                if (lhs >= 0)\n                    return true;\n            }\n            overflow = true;\n            return true;\n        }\n    }\n    else static if (x == \"cmp\")\n    {\n        alias C = typeof(lhs + rhs);\n        static if (!valueConvertible!(L, C) || !valueConvertible!(R, C))\n        {\n            static assert(isUnsigned!C);\n            static assert(isUnsigned!L != isUnsigned!R);\n            if (!isUnsigned!L && lhs < 0)\n            {\n                overflow = true;\n                return -1;\n            }\n            if (!isUnsigned!R && rhs < 0)\n            {\n                overflow = true;\n                return 1;\n            }\n        }\n        return lhs < rhs ? -1 : lhs > rhs;\n    }\n    else static if (x.among(\"<<\", \">>\", \">>>\"))\n    {\n        // Handle shift separately from all others. The test below covers\n        // negative rhs as well.\n        import std.conv : unsigned;\n        if (unsigned(rhs) > 8 * Result.sizeof) goto fail;\n        return mixin(\"lhs\" ~ x ~ \"rhs\");\n    }\n    else static if (x.among(\"&\", \"|\", \"^\"))\n    {\n        // Nothing to check\n        return mixin(\"lhs\" ~ x ~ \"rhs\");\n    }\n    else static if (x == \"^^\")\n    {\n        // Exponentiation is weird, handle separately\n        return pow(lhs, rhs, overflow);\n    }\n    else static if (valueConvertible!(L, Result) &&\n            valueConvertible!(R, Result))\n    {\n        static if (L.sizeof < Result.sizeof && R.sizeof < Result.sizeof &&\n            x.among(\"+\", \"-\", \"*\"))\n        {\n            // No checks - both are value converted and result is in range\n            return mixin(\"lhs\" ~ x ~ \"rhs\");\n        }\n        else static if (x == \"+\")\n        {\n            static if (isUnsigned!Result) alias impl = addu;\n            else alias impl = adds;\n            return impl(Result(lhs), Result(rhs), overflow);\n        }\n        else static if (x == \"-\")\n        {\n            static if (isUnsigned!Result) alias impl = subu;\n            else alias impl = subs;\n            return impl(Result(lhs), Result(rhs), overflow);\n        }\n        else static if (x == \"*\")\n        {\n            static if (!isUnsigned!L && !isUnsigned!R &&\n                is(L == Result))\n            {\n                if (lhs == Result.min && rhs == -1) goto fail;\n            }\n            static if (isUnsigned!Result) alias impl = mulu;\n            else alias impl = muls;\n            return impl(Result(lhs), Result(rhs), overflow);\n        }\n        else static if (x == \"/\" || x == \"%\")\n        {\n            static if (!isUnsigned!L && !isUnsigned!R &&\n                is(L == Result) && x == \"/\")\n            {\n                if (lhs == Result.min && rhs == -1) goto fail;\n            }\n            if (rhs == 0) goto fail;\n            return mixin(\"lhs\" ~ x ~ \"rhs\");\n        }\n        else static assert(0, x);\n    }\n    else // Mixed signs\n    {\n        static assert(isUnsigned!Result);\n        static assert(isUnsigned!L != isUnsigned!R);\n        static if (x == \"+\")\n        {\n            static if (!isUnsigned!L)\n            {\n                if (lhs < 0)\n                    return subu(Result(rhs), Result(-lhs), overflow);\n            }\n            else static if (!isUnsigned!R)\n            {\n                if (rhs < 0)\n                    return subu(Result(lhs), Result(-rhs), overflow);\n            }\n            return addu(Result(lhs), Result(rhs), overflow);\n        }\n        else static if (x == \"-\")\n        {\n            static if (!isUnsigned!L)\n            {\n                if (lhs < 0) goto fail;\n            }\n            else static if (!isUnsigned!R)\n            {\n                if (rhs < 0)\n                    return addu(Result(lhs), Result(-rhs), overflow);\n            }\n            return subu(Result(lhs), Result(rhs), overflow);\n        }\n        else static if (x == \"*\")\n        {\n            static if (!isUnsigned!L)\n            {\n                if (lhs < 0) goto fail;\n            }\n            else static if (!isUnsigned!R)\n            {\n                if (rhs < 0) goto fail;\n            }\n            return mulu(Result(lhs), Result(rhs), overflow);\n        }\n        else static if (x == \"/\" || x == \"%\")\n        {\n            static if (!isUnsigned!L)\n            {\n                if (lhs < 0 || rhs == 0) goto fail;\n            }\n            else static if (!isUnsigned!R)\n            {\n                if (rhs <= 0) goto fail;\n            }\n            return mixin(\"Result(lhs)\" ~ x ~ \"Result(rhs)\");\n        }\n        else static assert(0, x);\n    }\n    debug assert(false);\nfail:\n    overflow = true;\n    return Result(0);\n}\n\n///\n@safe unittest\n{\n    bool overflow;\n    assert(opChecked!\"+\"(const short(1), short(1), overflow) == 2 && !overflow);\n    assert(opChecked!\"+\"(1, 1, overflow) == 2 && !overflow);\n    assert(opChecked!\"+\"(1, 1u, overflow) == 2 && !overflow);\n    assert(opChecked!\"+\"(-1, 1u, overflow) == 0 && !overflow);\n    assert(opChecked!\"+\"(1u, -1, overflow) == 0 && !overflow);\n}\n\n///\n@safe unittest\n{\n    bool overflow;\n    assert(opChecked!\"-\"(1, 1, overflow) == 0 && !overflow);\n    assert(opChecked!\"-\"(1, 1u, overflow) == 0 && !overflow);\n    assert(opChecked!\"-\"(1u, -1, overflow) == 2 && !overflow);\n    assert(opChecked!\"-\"(-1, 1u, overflow) == 0 && overflow);\n}\n\n@safe unittest\n{\n    bool overflow;\n    assert(opChecked!\"*\"(2, 3, overflow) == 6 && !overflow);\n    assert(opChecked!\"*\"(2, 3u, overflow) == 6 && !overflow);\n    assert(opChecked!\"*\"(1u, -1, overflow) == 0 && overflow);\n    //assert(mul(-1, 1u, overflow) == uint.max - 1 && overflow);\n}\n\n@safe unittest\n{\n    bool overflow;\n    assert(opChecked!\"/\"(6, 3, overflow) == 2 && !overflow);\n    assert(opChecked!\"/\"(6, 3, overflow) == 2 && !overflow);\n    assert(opChecked!\"/\"(6u, 3, overflow) == 2 && !overflow);\n    assert(opChecked!\"/\"(6, 3u, overflow) == 2 && !overflow);\n    assert(opChecked!\"/\"(11, 0, overflow) == 0 && overflow);\n    overflow = false;\n    assert(opChecked!\"/\"(6u, 0, overflow) == 0 && overflow);\n    overflow = false;\n    assert(opChecked!\"/\"(-6, 2u, overflow) == 0 && overflow);\n    overflow = false;\n    assert(opChecked!\"/\"(-6, 0u, overflow) == 0 && overflow);\n    overflow = false;\n    assert(opChecked!\"cmp\"(0u, -6, overflow) == 1 && overflow);\n    overflow = false;\n    assert(opChecked!\"|\"(1, 2, overflow) == 3 && !overflow);\n}\n\n/*\nExponentiation function used by the implementation of operator `^^`.\n*/\nprivate pure @safe nothrow @nogc\nauto pow(L, R)(const L lhs, const R rhs, ref bool overflow)\nif (isIntegral!L && isIntegral!R)\n{\n    if (rhs <= 1)\n    {\n        if (rhs == 0) return 1;\n        static if (!isUnsigned!R)\n            return rhs == 1\n                ? lhs\n                : (rhs == -1 && (lhs == 1 || lhs == -1)) ? lhs : 0;\n        else\n            return lhs;\n    }\n\n    typeof(lhs ^^ rhs) b = void;\n    static if (!isUnsigned!L && isUnsigned!(typeof(b)))\n    {\n        // Need to worry about mixed-sign stuff\n        if (lhs < 0)\n        {\n            if (rhs & 1)\n            {\n                if (lhs < 0) overflow = true;\n                return 0;\n            }\n            b = -lhs;\n        }\n        else\n        {\n            b = lhs;\n        }\n    }\n    else\n    {\n        b = lhs;\n    }\n    if (b == 1) return 1;\n    if (b == -1) return (rhs & 1) ? -1 : 1;\n    if (rhs > 63)\n    {\n        overflow = true;\n        return 0;\n    }\n\n    assert((b > 1 || b < -1) && rhs > 1);\n    return powImpl(b, cast(uint) rhs, overflow);\n}\n\n// Inspiration: http://www.stepanovpapers.com/PAM.pdf\npure @safe nothrow @nogc\nprivate T powImpl(T)(T b, uint e, ref bool overflow)\nif (isIntegral!T && T.sizeof >= 4)\n{\n    assert(e > 1);\n\n    import core.checkedint : muls, mulu;\n    static if (isUnsigned!T) alias mul = mulu;\n    else alias mul = muls;\n\n    T r = b;\n    --e;\n    // Loop invariant: r * (b ^^ e) is the actual result\n    for (;; e /= 2)\n    {\n        if (e % 2)\n        {\n            r = mul(r, b, overflow);\n            if (e == 1) break;\n        }\n        b = mul(b, b, overflow);\n    }\n    return r;\n}\n\n@safe unittest\n{\n    static void testPow(T)(T x, uint e)\n    {\n        bool overflow;\n        assert(opChecked!\"^^\"(T(0), 0, overflow) == 1);\n        assert(opChecked!\"^^\"(-2, T(0), overflow) == 1);\n        assert(opChecked!\"^^\"(-2, T(1), overflow) == -2);\n        assert(opChecked!\"^^\"(-1, -1, overflow) == -1);\n        assert(opChecked!\"^^\"(-2, 1, overflow) == -2);\n        assert(opChecked!\"^^\"(-2, -1, overflow) == 0);\n        assert(opChecked!\"^^\"(-2, 4u, overflow) == 16);\n        assert(!overflow);\n        assert(opChecked!\"^^\"(-2, 3u, overflow) == 0);\n        assert(overflow);\n        overflow = false;\n        assert(opChecked!\"^^\"(3, 64u, overflow) == 0);\n        assert(overflow);\n        overflow = false;\n        foreach (uint i; 0 .. e)\n        {\n            assert(opChecked!\"^^\"(x, i, overflow) == x ^^ i);\n            assert(!overflow);\n        }\n        assert(opChecked!\"^^\"(x, e, overflow) == x ^^ e);\n        assert(overflow);\n    }\n\n    testPow!int(3, 21);\n    testPow!uint(3, 21);\n    testPow!long(3, 40);\n    testPow!ulong(3, 41);\n}\n\nversion (unittest) private struct CountOverflows\n{\n    uint calls;\n    auto onOverflow(string op, Lhs)(Lhs lhs)\n    {\n        ++calls;\n        return mixin(op ~ \"lhs\");\n    }\n    auto onOverflow(string op, Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        ++calls;\n        return mixin(\"lhs\" ~ op ~ \"rhs\");\n    }\n    T onLowerBound(Rhs, T)(Rhs rhs, T bound)\n    {\n        ++calls;\n        return cast(T) rhs;\n    }\n    T onUpperBound(Rhs, T)(Rhs rhs, T bound)\n    {\n        ++calls;\n        return cast(T) rhs;\n    }\n}\n\nversion (unittest) private struct CountOpBinary\n{\n    uint calls;\n    auto hookOpBinary(string op, Lhs, Rhs)(Lhs lhs, Rhs rhs)\n    {\n        ++calls;\n        return mixin(\"lhs\" ~ op ~ \"rhs\");\n    }\n}\n\n// opBinary\n@nogc nothrow pure @safe unittest\n{\n    auto x = Checked!(const int, void)(42), y = Checked!(immutable int, void)(142);\n    assert(x + y == 184);\n    assert(x + 100 == 142);\n    assert(y - x == 100);\n    assert(200 - x == 158);\n    assert(y * x == 142 * 42);\n    assert(x / 1 == 42);\n    assert(x % 20 == 2);\n\n    auto x1 = Checked!(int, CountOverflows)(42);\n    assert(x1 + 0 == 42);\n    assert(x1 + false == 42);\n    assert(is(typeof(x1 + 0.5) == double));\n    assert(x1 + 0.5 == 42.5);\n    assert(x1.hook.calls == 0);\n    assert(x1 + int.max == int.max + 42);\n    assert(x1.hook.calls == 1);\n    assert(x1 * 2 == 84);\n    assert(x1.hook.calls == 1);\n    assert(x1 / 2 == 21);\n    assert(x1.hook.calls == 1);\n    assert(x1 % 20 == 2);\n    assert(x1.hook.calls == 1);\n    assert(x1 << 2 == 42 << 2);\n    assert(x1.hook.calls == 1);\n    assert(x1 << 42 == x1.get << x1.get);\n    assert(x1.hook.calls == 2);\n    x1 = int.min;\n    assert(x1 - 1 == int.max);\n    assert(x1.hook.calls == 3);\n\n    auto x2 = Checked!(int, CountOpBinary)(42);\n    assert(x2 + 1 == 43);\n    assert(x2.hook.calls == 1);\n\n    auto x3 = Checked!(uint, CountOverflows)(42u);\n    assert(x3 + 1 == 43);\n    assert(x3.hook.calls == 0);\n    assert(x3 - 1 == 41);\n    assert(x3.hook.calls == 0);\n    assert(x3 + (-42) == 0);\n    assert(x3.hook.calls == 0);\n    assert(x3 - (-42) == 84);\n    assert(x3.hook.calls == 0);\n    assert(x3 * 2 == 84);\n    assert(x3.hook.calls == 0);\n    assert(x3 * -2 == -84);\n    assert(x3.hook.calls == 1);\n    assert(x3 / 2 == 21);\n    assert(x3.hook.calls == 1);\n    assert(x3 / -2 == 0);\n    assert(x3.hook.calls == 2);\n    assert(x3 ^^ 2 == 42 * 42);\n    assert(x3.hook.calls == 2);\n\n    auto x4 = Checked!(int, CountOverflows)(42);\n    assert(x4 + 1 == 43);\n    assert(x4.hook.calls == 0);\n    assert(x4 + 1u == 43);\n    assert(x4.hook.calls == 0);\n    assert(x4 - 1 == 41);\n    assert(x4.hook.calls == 0);\n    assert(x4 * 2 == 84);\n    assert(x4.hook.calls == 0);\n    x4 = -2;\n    assert(x4 + 2u == 0);\n    assert(x4.hook.calls == 0);\n    assert(x4 * 2u == -4);\n    assert(x4.hook.calls == 1);\n\n    auto x5 = Checked!(int, CountOverflows)(3);\n    assert(x5 ^^ 0 == 1);\n    assert(x5 ^^ 1 == 3);\n    assert(x5 ^^ 2 == 9);\n    assert(x5 ^^ 3 == 27);\n    assert(x5 ^^ 4 == 81);\n    assert(x5 ^^ 5 == 81 * 3);\n    assert(x5 ^^ 6 == 81 * 9);\n}\n\n// opBinaryRight\n@nogc nothrow pure @safe unittest\n{\n    auto x1 = Checked!(int, CountOverflows)(42);\n    assert(1 + x1 == 43);\n    assert(true + x1 == 43);\n    assert(0.5 + x1 == 42.5);\n    auto x2 = Checked!(int, void)(42);\n    assert(x1 + x2 == 84);\n    assert(x2 + x1   == 84);\n}\n\n// opOpAssign\n@safe unittest\n{\n    auto x1 = Checked!(int, CountOverflows)(3);\n    assert((x1 += 2) == 5);\n    x1 *= 2_000_000_000L;\n    assert(x1.hook.calls == 1);\n    x1 *= -2_000_000_000L;\n    assert(x1.hook.calls == 2);\n\n    auto x2 = Checked!(ushort, CountOverflows)(ushort(3));\n    assert((x2 += 2) == 5);\n    assert(x2.hook.calls == 0);\n    assert((x2 += ushort.max) == cast(ushort) (ushort(5) + ushort.max));\n    assert(x2.hook.calls == 1);\n\n    auto x3 = Checked!(uint, CountOverflows)(3u);\n    x3 *= ulong(2_000_000_000);\n    assert(x3.hook.calls == 1);\n}\n\n// opAssign\n@safe unittest\n{\n    Checked!(int, void) x;\n    x = 42;\n    assert(x.get == 42);\n    x = x;\n    assert(x.get == 42);\n    x = short(43);\n    assert(x.get == 43);\n    x = ushort(44);\n    assert(x.get == 44);\n}\n\n@safe unittest\n{\n    static assert(!is(typeof(Checked!(short, void)(ushort(42)))));\n    static assert(!is(typeof(Checked!(int, void)(long(42)))));\n    static assert(!is(typeof(Checked!(int, void)(ulong(42)))));\n    assert(Checked!(short, void)(short(42)).get == 42);\n    assert(Checked!(int, void)(ushort(42)).get == 42);\n}\n\n// opCast\n@nogc nothrow pure @safe unittest\n{\n    static assert(is(typeof(cast(float) Checked!(int, void)(42)) == float));\n    assert(cast(float) Checked!(int, void)(42) == 42);\n\n    assert(is(typeof(cast(long) Checked!(int, void)(42)) == long));\n    assert(cast(long) Checked!(int, void)(42) == 42);\n    static assert(is(typeof(cast(long) Checked!(uint, void)(42u)) == long));\n    assert(cast(long) Checked!(uint, void)(42u) == 42);\n\n    auto x = Checked!(int, void)(42);\n    if (x) {} else assert(0);\n    x = 0;\n    if (x) assert(0);\n\n    static struct Hook1\n    {\n        uint calls;\n        Dst hookOpCast(Dst, Src)(Src value)\n        {\n            ++calls;\n            return 42;\n        }\n    }\n    auto y = Checked!(long, Hook1)(long.max);\n    assert(cast(int) y == 42);\n    assert(cast(uint) y == 42);\n    assert(y.hook.calls == 2);\n\n    static struct Hook2\n    {\n        uint calls;\n        Dst onBadCast(Dst, Src)(Src value)\n        {\n            ++calls;\n            return 42;\n        }\n    }\n    auto x1 = Checked!(uint, Hook2)(100u);\n    assert(cast(ushort) x1 == 100);\n    assert(cast(short) x1 == 100);\n    assert(cast(float) x1 == 100);\n    assert(cast(double) x1 == 100);\n    assert(cast(real) x1 == 100);\n    assert(x1.hook.calls == 0);\n    assert(cast(int) x1 == 100);\n    assert(x1.hook.calls == 0);\n    x1 = uint.max;\n    assert(cast(int) x1 == 42);\n    assert(x1.hook.calls == 1);\n\n    auto x2 = Checked!(int, Hook2)(-100);\n    assert(cast(short) x2 == -100);\n    assert(cast(ushort) x2 == 42);\n    assert(cast(uint) x2 == 42);\n    assert(cast(ulong) x2 == 42);\n    assert(x2.hook.calls == 3);\n}\n\n// opEquals\n@nogc nothrow pure @safe unittest\n{\n    assert(Checked!(int, void)(42) == 42L);\n    assert(42UL == Checked!(int, void)(42));\n\n    static struct Hook1\n    {\n        uint calls;\n        bool hookOpEquals(Lhs, Rhs)(const Lhs lhs, const Rhs rhs)\n        {\n            ++calls;\n            return lhs != rhs;\n        }\n    }\n    auto x1 = Checked!(int, Hook1)(100);\n    assert(x1 != Checked!(long, Hook1)(100));\n    assert(x1.hook.calls == 1);\n    assert(x1 != 100u);\n    assert(x1.hook.calls == 2);\n\n    static struct Hook2\n    {\n        uint calls;\n        bool hookOpEquals(Lhs, Rhs)(Lhs lhs, Rhs rhs)\n        {\n            ++calls;\n            return false;\n        }\n    }\n    auto x2 = Checked!(int, Hook2)(-100);\n    assert(x2 != x1);\n    // For coverage: lhs has no hookOpEquals, rhs does\n    assert(Checked!(uint, void)(100u) != x2);\n    // For coverage: different types, neither has a hookOpEquals\n    assert(Checked!(uint, void)(100u) == Checked!(int, void*)(100));\n    assert(x2.hook.calls == 0);\n    assert(x2 != -100);\n    assert(x2.hook.calls == 1);\n    assert(x2 != cast(uint) -100);\n    assert(x2.hook.calls == 2);\n    x2 = 100;\n    assert(x2 != cast(uint) 100);\n    assert(x2.hook.calls == 3);\n    x2 = -100;\n\n    auto x3 = Checked!(uint, Hook2)(100u);\n    assert(x3 != 100);\n    x3 = uint.max;\n    assert(x3 != -1);\n\n    assert(x2 != x3);\n}\n\n// opCmp\n@nogc nothrow pure @safe unittest\n{\n    Checked!(int, void) x;\n    assert(x <= x);\n    assert(x < 45);\n    assert(x < 45u);\n    assert(x > -45);\n    assert(x < 44.2);\n    assert(x > -44.2);\n    assert(!(x < double.init));\n    assert(!(x > double.init));\n    assert(!(x <= double.init));\n    assert(!(x >= double.init));\n\n    static struct Hook1\n    {\n        uint calls;\n        int hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)\n        {\n            ++calls;\n            return 0;\n        }\n    }\n    auto x1 = Checked!(int, Hook1)(42);\n    assert(!(x1 < 43u));\n    assert(!(43u < x1));\n    assert(x1.hook.calls == 2);\n\n    static struct Hook2\n    {\n        uint calls;\n        int hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)\n        {\n            ++calls;\n            return ProperCompare.hookOpCmp(lhs, rhs);\n        }\n    }\n    auto x2 = Checked!(int, Hook2)(-42);\n    assert(x2 < 43u);\n    assert(43u > x2);\n    assert(x2.hook.calls == 2);\n    x2 = 42;\n    assert(x2 > 41u);\n\n    auto x3 = Checked!(uint, Hook2)(42u);\n    assert(x3 > 41);\n    assert(x3 > -41);\n}\n\n// opUnary\n@nogc nothrow pure @safe unittest\n{\n    auto x = Checked!(int, void)(42);\n    assert(x == +x);\n    static assert(is(typeof(-x) == typeof(x)));\n    assert(-x == Checked!(int, void)(-42));\n    static assert(is(typeof(~x) == typeof(x)));\n    assert(~x == Checked!(int, void)(~42));\n    assert(++x == 43);\n    assert(--x == 42);\n\n    static struct Hook1\n    {\n        uint calls;\n        auto hookOpUnary(string op, T)(T value) if (op == \"-\")\n        {\n            ++calls;\n            return T(42);\n        }\n        auto hookOpUnary(string op, T)(T value) if (op == \"~\")\n        {\n            ++calls;\n            return T(43);\n        }\n    }\n    auto x1 = Checked!(int, Hook1)(100);\n    assert(is(typeof(-x1) == typeof(x1)));\n    assert(-x1 == Checked!(int, Hook1)(42));\n    assert(is(typeof(~x1) == typeof(x1)));\n    assert(~x1 == Checked!(int, Hook1)(43));\n    assert(x1.hook.calls == 2);\n\n    static struct Hook2\n    {\n        uint calls;\n        void hookOpUnary(string op, T)(ref T value) if (op == \"++\")\n        {\n            ++calls;\n            --value;\n        }\n        void hookOpUnary(string op, T)(ref T value) if (op == \"--\")\n        {\n            ++calls;\n            ++value;\n        }\n    }\n    auto x2 = Checked!(int, Hook2)(100);\n    assert(++x2 == 99);\n    assert(x2 == 99);\n    assert(--x2 == 100);\n    assert(x2 == 100);\n\n    auto x3 = Checked!(int, CountOverflows)(int.max - 1);\n    assert(++x3 == int.max);\n    assert(x3.hook.calls == 0);\n    assert(++x3 == int.min);\n    assert(x3.hook.calls == 1);\n    assert(-x3 == int.min);\n    assert(x3.hook.calls == 2);\n\n    x3 = int.min + 1;\n    assert(--x3 == int.min);\n    assert(x3.hook.calls == 2);\n    assert(--x3 == int.max);\n    assert(x3.hook.calls == 3);\n}\n\n//\n@nogc nothrow pure @safe unittest\n{\n    Checked!(int, void) x;\n    assert(x == x);\n    assert(x == +x);\n    assert(x == -x);\n    ++x;\n    assert(x == 1);\n    x++;\n    assert(x == 2);\n\n    x = 42;\n    assert(x == 42);\n    const short _short = 43;\n    x = _short;\n    assert(x == _short);\n    ushort _ushort = 44;\n    x = _ushort;\n    assert(x == _ushort);\n    assert(x == 44.0);\n    assert(x != 44.1);\n    assert(x < 45);\n    assert(x < 44.2);\n    assert(x > -45);\n    assert(x > -44.2);\n\n    assert(cast(long) x == 44);\n    assert(cast(short) x == 44);\n\n    const Checked!(uint, void) y;\n    assert(y <= y);\n    assert(y == 0);\n    assert(y < x);\n    x = -1;\n    assert(x > y);\n}\n\n@nogc nothrow pure @safe unittest\n{\n    alias cint = Checked!(int, void);\n    cint a = 1, b = 2;\n    a += b;\n    assert(a == cint(3));\n\n    alias ccint = Checked!(cint, Saturate);\n    ccint c = 14;\n    a += c;\n    assert(a == cint(17));\n}\n\n// toHash\n@system unittest\n{\n    assert(checked(42).toHash() == checked(42).toHash());\n    assert(checked(12).toHash() != checked(19).toHash());\n\n    static struct Hook1\n    {\n        static size_t hookToHash(T)(T payload) nothrow @trusted\n        {\n            static if (size_t.sizeof == 4)\n            {\n                return typeid(payload).getHash(&payload) ^ 0xFFFF_FFFF;\n            }\n            else\n            {\n                return typeid(payload).getHash(&payload) ^ 0xFFFF_FFFF_FFFF_FFFF;\n            }\n\n        }\n    }\n\n    auto a = checked!Hook1(78);\n    auto b = checked!Hook1(78);\n    assert(a.toHash() == b.toHash());\n\n    assert(checked!Hook1(12).toHash() != checked!Hook1(13).toHash());\n\n    static struct Hook2\n    {\n        static if (size_t.sizeof == 4)\n        {\n            static size_t hashMask = 0xFFFF_0000;\n        }\n        else\n        {\n            static size_t hashMask = 0xFFFF_0000_FFFF_0000;\n        }\n\n        static size_t hookToHash(T)(T payload) nothrow @trusted\n        {\n            return typeid(payload).getHash(&payload) ^ hashMask;\n        }\n    }\n\n    auto x = checked!Hook2(1901);\n    auto y = checked!Hook2(1989);\n\n    assert((() nothrow @safe => x.toHash() == x.toHash())());\n\n    assert(x.toHash() == x.toHash());\n    assert(x.toHash() != y.toHash());\n    assert(checked!Hook1(1901).toHash() != x.toHash());\n\n    immutable z = checked!Hook1(1901);\n    immutable t = checked!Hook1(1901);\n    immutable w = checked!Hook2(1901);\n\n    assert(z.toHash() == t.toHash());\n    assert(z.toHash() != x.toHash());\n    assert(z.toHash() != w.toHash());\n\n    const long c = 0xF0F0F0F0;\n    const long d = 0xF0F0F0F0;\n\n    assert(checked!Hook1(c).toHash() != checked!Hook2(c));\n    assert(checked!Hook1(c).toHash() != checked!Hook1(d));\n\n    // Hook with state, does not implement hookToHash\n    static struct Hook3\n    {\n        ulong var1 = ulong.max;\n        uint var2 = uint.max;\n    }\n\n    assert(checked!Hook3(12).toHash() != checked!Hook3(13).toHash());\n    assert(checked!Hook3(13).toHash() == checked!Hook3(13).toHash());\n\n    // Hook with no state and no hookToHash, payload has its own hashing function\n    auto x1 = Checked!(Checked!int, ProperCompare)(123);\n    auto x2 = Checked!(Checked!int, ProperCompare)(123);\n    auto x3 = Checked!(Checked!int, ProperCompare)(144);\n\n    assert(x1.toHash() == x2.toHash());\n    assert(x1.toHash() != x3.toHash());\n    assert(x2.toHash() != x3.toHash());\n}\n\n///\n@system unittest\n{\n    struct MyHook\n    {\n        static size_t hookToHash(T)(const T payload) nothrow @trusted\n        {\n            return .hashOf(payload);\n        }\n    }\n\n    int[Checked!(int, MyHook)] aa;\n    Checked!(int, MyHook) var = 42;\n    aa[var] = 100;\n\n    assert(aa[var] == 100);\n\n    int[Checked!(int, Abort)] bb;\n    Checked!(int, Abort) var2 = 42;\n    bb[var2] = 100;\n\n    assert(bb[var2] == 100);\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/logger/core.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/logger/core.d)\n*/\nmodule std.experimental.logger.core;\n\nimport core.sync.mutex : Mutex;\nimport std.datetime.date : DateTime;\nimport std.datetime.systime : Clock, SysTime;\nimport std.range.primitives;\nimport std.traits;\n\nimport std.experimental.logger.filelogger;\n\n/** This template evaluates if the passed `LogLevel` is active.\nThe previously described version statements are used to decide if the\n`LogLevel` is active. The version statements only influence the compile\nunit they are used with, therefore this function can only disable logging this\nspecific compile unit.\n*/\ntemplate isLoggingActiveAt(LogLevel ll)\n{\n    version (StdLoggerDisableLogging)\n    {\n        enum isLoggingActiveAt = false;\n    }\n    else\n    {\n        static if (ll == LogLevel.trace)\n        {\n            version (StdLoggerDisableTrace) enum isLoggingActiveAt = false;\n        }\n        else static if (ll == LogLevel.info)\n        {\n            version (StdLoggerDisableInfo) enum isLoggingActiveAt = false;\n        }\n        else static if (ll == LogLevel.warning)\n        {\n            version (StdLoggerDisableWarning) enum isLoggingActiveAt = false;\n        }\n        else static if (ll == LogLevel.error)\n        {\n            version (StdLoggerDisableError) enum isLoggingActiveAt = false;\n        }\n        else static if (ll == LogLevel.critical)\n        {\n            version (StdLoggerDisableCritical) enum isLoggingActiveAt = false;\n        }\n        else static if (ll == LogLevel.fatal)\n        {\n            version (StdLoggerDisableFatal) enum isLoggingActiveAt = false;\n        }\n        // If `isLoggingActiveAt` didn't get defined above to false,\n        // we default it to true.\n        static if (!is(typeof(isLoggingActiveAt) == bool))\n        {\n            enum isLoggingActiveAt = true;\n        }\n    }\n}\n\n/// This compile-time flag is `true` if logging is not statically disabled.\nenum isLoggingActive = isLoggingActiveAt!(LogLevel.all);\n\n/** This functions is used at runtime to determine if a `LogLevel` is\nactive. The same previously defined version statements are used to disable\ncertain levels. Again the version statements are associated with a compile\nunit and can therefore not disable logging in other compile units.\npure bool isLoggingEnabled()(LogLevel ll) @safe nothrow @nogc\n*/\nbool isLoggingEnabled()(LogLevel ll, LogLevel loggerLL,\n    LogLevel globalLL, lazy bool condition = true) @safe\n{\n    switch (ll)\n    {\n        case LogLevel.trace:\n            version (StdLoggerDisableTrace) return false;\n            else break;\n        case LogLevel.info:\n            version (StdLoggerDisableInfo) return false;\n            else break;\n        case LogLevel.warning:\n            version (StdLoggerDisableWarning) return false;\n            else break;\n        case LogLevel.critical:\n            version (StdLoggerDisableCritical) return false;\n            else break;\n        case LogLevel.fatal:\n            version (StdLoggerDisableFatal) return false;\n            else break;\n        default: break;\n    }\n\n    return ll >= globalLL\n        && ll >= loggerLL\n        && ll != LogLevel.off\n        && globalLL != LogLevel.off\n        && loggerLL != LogLevel.off\n        && condition;\n}\n\n/** This template returns the `LogLevel` named \"logLevel\" of type $(D\nLogLevel) defined in a user defined module where the filename has the\nsuffix \"_loggerconfig.d\". This `LogLevel` sets the minimal `LogLevel`\nof the module.\n\nA minimal `LogLevel` can be defined on a per module basis.\nIn order to define a module `LogLevel` a file with a modulename\n\"MODULENAME_loggerconfig\" must be found. If no such module exists and the\nmodule is a nested module, it is checked if there exists a\n\"PARENT_MODULE_loggerconfig\" module with such a symbol.\nIf this module exists and it contains a `LogLevel` called logLevel this $(D\nLogLevel) will be used. This parent lookup is continued until there is no\nparent module. Then the moduleLogLevel is `LogLevel.all`.\n*/\ntemplate moduleLogLevel(string moduleName)\nif (!moduleName.length)\n{\n    // default\n    enum moduleLogLevel = LogLevel.all;\n}\n\n///\n@system unittest\n{\n    static assert(moduleLogLevel!\"\" == LogLevel.all);\n}\n\n/// ditto\ntemplate moduleLogLevel(string moduleName)\nif (moduleName.length)\n{\n    import std.string : format;\n    mixin(q{\n        static if (__traits(compiles, {import %1$s : logLevel;}))\n        {\n            import %1$s : logLevel;\n            static assert(is(typeof(logLevel) : LogLevel),\n                          \"Expect 'logLevel' to be of Type 'LogLevel'.\");\n            // don't enforce enum here\n            alias moduleLogLevel = logLevel;\n        }\n        else\n            // use logLevel of package or default\n            alias moduleLogLevel = moduleLogLevel!(parentOf(moduleName));\n    }.format(moduleName ~ \"_loggerconfig\"));\n}\n\n///\n@system unittest\n{\n    static assert(moduleLogLevel!\"not.amodule.path\" == LogLevel.all);\n}\n\nprivate string parentOf(string mod)\n{\n    foreach_reverse (i, c; mod)\n        if (c == '.') return mod[0 .. i];\n    return null;\n}\n\n/* This function formates a `SysTime` into an `OutputRange`.\n\nThe `SysTime` is formatted similar to\n$(LREF std.datatime.DateTime.toISOExtString) except the fractional second part.\nThe fractional second part is in milliseconds and is always 3 digits.\n*/\nvoid systimeToISOString(OutputRange)(OutputRange o, const ref SysTime time)\nif (isOutputRange!(OutputRange,string))\n{\n    import std.format : formattedWrite;\n\n    const auto dt = cast(DateTime) time;\n    const auto fsec = time.fracSecs.total!\"msecs\";\n\n    formattedWrite(o, \"%04d-%02d-%02dT%02d:%02d:%02d.%03d\",\n        dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,\n        fsec);\n}\n\n/** This function logs data.\n\nIn order for the data to be processed, the `LogLevel` of the log call must\nbe greater or equal to the `LogLevel` of the `sharedLog` and the\n`defaultLogLevel`; additionally the condition passed must be `true`.\n\nParams:\n  ll = The `LogLevel` used by this log call.\n  condition = The condition must be `true` for the data to be logged.\n  args = The data that should be logged.\n\nExample:\n--------------------\nlog(LogLevel.warning, true, \"Hello World\", 3.1415);\n--------------------\n*/\nvoid log(int line = __LINE__, string file = __FILE__,\n    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,\n    string moduleName = __MODULE__, A...)(const LogLevel ll,\n    lazy bool condition, lazy A args)\nif (args.length != 1)\n{\n    static if (isLoggingActive)\n    {\n        if (ll >= moduleLogLevel!moduleName)\n        {\n               stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)\n                (ll, condition, args);\n        }\n    }\n}\n\n/// Ditto\nvoid log(T, string moduleName = __MODULE__)(const LogLevel ll,\n    lazy bool condition, lazy T arg, int line = __LINE__, string file = __FILE__,\n    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__)\n{\n    static if (isLoggingActive)\n    {\n        if (ll >= moduleLogLevel!moduleName)\n        {\n            stdThreadLocalLog.log!(T,moduleName)(ll, condition, arg, line, file, funcName,\n                prettyFuncName);\n        }\n    }\n}\n\n/** This function logs data.\n\nIn order for the data to be processed the `LogLevel` of the log call must\nbe greater or equal to the `LogLevel` of the `sharedLog`.\n\nParams:\n  ll = The `LogLevel` used by this log call.\n  args = The data that should be logged.\n\nExample:\n--------------------\nlog(LogLevel.warning, \"Hello World\", 3.1415);\n--------------------\n*/\nvoid log(int line = __LINE__, string file = __FILE__,\n    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,\n    string moduleName = __MODULE__, A...)(const LogLevel ll, lazy A args)\nif (args.length > 1 && !is(Unqual!(A[0]) : bool))\n{\n    static if (isLoggingActive)\n    {\n        if (ll >= moduleLogLevel!moduleName)\n        {\n            stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)\n                (ll, args);\n        }\n    }\n}\n\n/// Ditto\nvoid log(T, string moduleName = __MODULE__)(const LogLevel ll, lazy T arg,\n    int line = __LINE__, string file = __FILE__, string funcName = __FUNCTION__,\n    string prettyFuncName = __PRETTY_FUNCTION__)\n{\n    static if (isLoggingActive)\n    {\n        if (ll >= moduleLogLevel!moduleName)\n        {\n            stdThreadLocalLog.log!T(ll, arg, line, file, funcName, prettyFuncName,\n                moduleName);\n        }\n    }\n}\n\n/** This function logs data.\n\nIn order for the data to be processed the `LogLevel` of the\n`sharedLog` must be greater or equal to the `defaultLogLevel`\nadd the condition passed must be `true`.\n\nParams:\n  condition = The condition must be `true` for the data to be logged.\n  args = The data that should be logged.\n\nExample:\n--------------------\nlog(true, \"Hello World\", 3.1415);\n--------------------\n*/\nvoid log(int line = __LINE__, string file = __FILE__,\n    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,\n    string moduleName = __MODULE__, A...)(lazy bool condition, lazy A args)\nif (args.length != 1)\n{\n    static if (isLoggingActive)\n    {\n        stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)\n            (stdThreadLocalLog.logLevel, condition, args);\n    }\n}\n\n/// Ditto\nvoid log(T, string moduleName = __MODULE__)(lazy bool condition, lazy T arg,\n    int line = __LINE__, string file = __FILE__, string funcName = __FUNCTION__,\n    string prettyFuncName = __PRETTY_FUNCTION__)\n{\n    static if (isLoggingActive)\n    {\n        stdThreadLocalLog.log!(T,moduleName)(stdThreadLocalLog.logLevel,\n            condition, arg, line, file, funcName, prettyFuncName);\n    }\n}\n\n/** This function logs data.\n\nIn order for the data to be processed the `LogLevel` of the\n`sharedLog` must be greater or equal to the `defaultLogLevel`.\n\nParams:\n  args = The data that should be logged.\n\nExample:\n--------------------\nlog(\"Hello World\", 3.1415);\n--------------------\n*/\nvoid log(int line = __LINE__, string file = __FILE__,\n    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,\n    string moduleName = __MODULE__, A...)(lazy A args)\nif ((args.length > 1 && !is(Unqual!(A[0]) : bool)\n    && !is(Unqual!(A[0]) == LogLevel))\n    || args.length == 0)\n{\n    static if (isLoggingActive)\n    {\n        stdThreadLocalLog.log!(line, file, funcName,\n           prettyFuncName, moduleName)(stdThreadLocalLog.logLevel, args);\n    }\n}\n\nvoid log(T)(lazy T arg, int line = __LINE__, string file = __FILE__,\n    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,\n    string moduleName = __MODULE__)\n{\n    static if (isLoggingActive)\n    {\n        stdThreadLocalLog.log!T(stdThreadLocalLog.logLevel, arg, line, file,\n            funcName, prettyFuncName, moduleName);\n    }\n}\n\n/** This function logs data in a `printf`-style manner.\n\nIn order for the data to be processed the `LogLevel` of the log call must\nbe greater or equal to the `LogLevel` of the `sharedLog` and the\n`defaultLogLevel` additionally the condition passed must be `true`.\n\nParams:\n  ll = The `LogLevel` used by this log call.\n  condition = The condition must be `true` for the data to be logged.\n  msg = The `printf`-style string.\n  args = The data that should be logged.\n\nExample:\n--------------------\nlogf(LogLevel.warning, true, \"Hello World %f\", 3.1415);\n--------------------\n*/\nvoid logf(int line = __LINE__, string file = __FILE__,\n    string funcName = __FUNCTION__,\n    string prettyFuncName = __PRETTY_FUNCTION__,\n    string moduleName = __MODULE__, A...)(const LogLevel ll,\n    lazy bool condition, lazy string msg, lazy A args)\n{\n    static if (isLoggingActive)\n    {\n        if (ll >= moduleLogLevel!moduleName)\n        {\n            stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)\n                (ll, condition, msg, args);\n        }\n    }\n}\n\n/** This function logs data in a `printf`-style manner.\n\nIn order for the data to be processed the `LogLevel` of the log call must\nbe greater or equal to the `LogLevel` of the `sharedLog` and the\n`defaultLogLevel`.\n\nParams:\n  ll = The `LogLevel` used by this log call.\n  msg = The `printf`-style string.\n  args = The data that should be logged.\n\nExample:\n--------------------\nlogf(LogLevel.warning, \"Hello World %f\", 3.1415);\n--------------------\n*/\nvoid logf(int line = __LINE__, string file = __FILE__,\n    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,\n    string moduleName = __MODULE__, A...)(const LogLevel ll, lazy string msg,\n        lazy A args)\n{\n    static if (isLoggingActive)\n    {\n        if (ll >= moduleLogLevel!moduleName)\n        {\n            stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)\n                (ll, msg, args);\n        }\n    }\n}\n\n/** This function logs data in a `printf`-style manner.\n\nIn order for the data to be processed the `LogLevel` of the log call must\nbe greater or equal to the `defaultLogLevel` additionally the condition\npassed must be `true`.\n\nParams:\n  condition = The condition must be `true` for the data to be logged.\n  msg = The `printf`-style string.\n  args = The data that should be logged.\n\nExample:\n--------------------\nlogf(true, \"Hello World %f\", 3.1415);\n--------------------\n*/\nvoid logf(int line = __LINE__, string file = __FILE__,\n    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,\n    string moduleName = __MODULE__, A...)(lazy bool condition,\n        lazy string msg, lazy A args)\n{\n    static if (isLoggingActive)\n    {\n        stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)\n            (stdThreadLocalLog.logLevel, condition, msg, args);\n    }\n}\n\n/** This function logs data in a `printf`-style manner.\n\nIn order for the data to be processed the `LogLevel` of the log call must\nbe greater or equal to the `defaultLogLevel`.\n\nParams:\n  msg = The `printf`-style string.\n  args = The data that should be logged.\n\nExample:\n--------------------\nlogf(\"Hello World %f\", 3.1415);\n--------------------\n*/\nvoid logf(int line = __LINE__, string file = __FILE__,\n    string funcName = __FUNCTION__,\n    string prettyFuncName = __PRETTY_FUNCTION__,\n    string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)\n{\n    static if (isLoggingActive)\n    {\n        stdThreadLocalLog.logf!(line, file, funcName,prettyFuncName, moduleName)\n            (stdThreadLocalLog.logLevel, msg, args);\n    }\n}\n\n/** This template provides the global log functions with the `LogLevel`\nis encoded in the function name.\n\nThe aliases following this template create the public names of these log\nfunctions.\n*/\ntemplate defaultLogFunction(LogLevel ll)\n{\n    void defaultLogFunction(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(lazy A args)\n        if ((args.length > 0 && !is(Unqual!(A[0]) : bool)) || args.length == 0)\n    {\n        static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)\n        {\n            stdThreadLocalLog.memLogFunctions!(ll).logImpl!(line, file, funcName,\n                prettyFuncName, moduleName)(args);\n        }\n    }\n\n    void defaultLogFunction(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(lazy bool condition, lazy A args)\n    {\n        static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)\n        {\n            stdThreadLocalLog.memLogFunctions!(ll).logImpl!(line, file, funcName,\n                prettyFuncName, moduleName)(condition, args);\n        }\n    }\n}\n\n/** This function logs data to the `stdThreadLocalLog`, optionally depending\non a condition.\n\nIn order for the resulting log message to be logged the `LogLevel` must\nbe greater or equal than the `LogLevel` of the `stdThreadLocalLog` and\nmust be greater or equal than the global `LogLevel`.\nAdditionally the `LogLevel` must be greater or equal than the `LogLevel`\nof the `stdSharedLogger`.\nIf a condition is given, it must evaluate to `true`.\n\nParams:\n  condition = The condition must be `true` for the data to be logged.\n  args = The data that should be logged.\n\nExample:\n--------------------\ntrace(1337, \"is number\");\ninfo(1337, \"is number\");\nerror(1337, \"is number\");\ncritical(1337, \"is number\");\nfatal(1337, \"is number\");\ntrace(true, 1337, \"is number\");\ninfo(false, 1337, \"is number\");\nerror(true, 1337, \"is number\");\ncritical(false, 1337, \"is number\");\nfatal(true, 1337, \"is number\");\n--------------------\n*/\nalias trace = defaultLogFunction!(LogLevel.trace);\n/// Ditto\nalias info = defaultLogFunction!(LogLevel.info);\n/// Ditto\nalias warning = defaultLogFunction!(LogLevel.warning);\n/// Ditto\nalias error = defaultLogFunction!(LogLevel.error);\n/// Ditto\nalias critical = defaultLogFunction!(LogLevel.critical);\n/// Ditto\nalias fatal = defaultLogFunction!(LogLevel.fatal);\n\n/** This template provides the global `printf`-style log functions with\nthe `LogLevel` is encoded in the function name.\n\nThe aliases following this template create the public names of the log\nfunctions.\n*/\ntemplate defaultLogFunctionf(LogLevel ll)\n{\n    void defaultLogFunctionf(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)\n    {\n        static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)\n        {\n            stdThreadLocalLog.memLogFunctions!(ll).logImplf!(line, file, funcName,\n                prettyFuncName, moduleName)(msg, args);\n        }\n    }\n\n    void defaultLogFunctionf(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(lazy bool condition,\n            lazy string msg, lazy A args)\n    {\n        static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)\n        {\n            stdThreadLocalLog.memLogFunctions!(ll).logImplf!(line, file, funcName,\n                prettyFuncName, moduleName)(condition, msg, args);\n        }\n    }\n}\n\n/** This function logs data to the `sharedLog` in a `printf`-style\nmanner.\n\nIn order for the resulting log message to be logged the `LogLevel` must\nbe greater or equal than the `LogLevel` of the `sharedLog` and\nmust be greater or equal than the global `LogLevel`.\nAdditionally the `LogLevel` must be greater or equal than the `LogLevel`\nof the `stdSharedLogger`.\n\nParams:\n  msg = The `printf`-style string.\n  args = The data that should be logged.\n\nExample:\n--------------------\ntracef(\"is number %d\", 1);\ninfof(\"is number %d\", 2);\nerrorf(\"is number %d\", 3);\ncriticalf(\"is number %d\", 4);\nfatalf(\"is number %d\", 5);\n--------------------\n\nThe second version of the function logs data to the `sharedLog` in a $(D\nprintf)-style manner.\n\nIn order for the resulting log message to be logged the `LogLevel` must\nbe greater or equal than the `LogLevel` of the `sharedLog` and\nmust be greater or equal than the global `LogLevel`.\nAdditionally the `LogLevel` must be greater or equal than the `LogLevel`\nof the `stdSharedLogger`.\n\nParams:\n  condition = The condition must be `true` for the data to be logged.\n  msg = The `printf`-style string.\n  args = The data that should be logged.\n\nExample:\n--------------------\ntracef(false, \"is number %d\", 1);\ninfof(false, \"is number %d\", 2);\nerrorf(true, \"is number %d\", 3);\ncriticalf(true, \"is number %d\", 4);\nfatalf(someFunct(), \"is number %d\", 5);\n--------------------\n*/\nalias tracef = defaultLogFunctionf!(LogLevel.trace);\n/// Ditto\nalias infof = defaultLogFunctionf!(LogLevel.info);\n/// Ditto\nalias warningf = defaultLogFunctionf!(LogLevel.warning);\n/// Ditto\nalias errorf = defaultLogFunctionf!(LogLevel.error);\n/// Ditto\nalias criticalf = defaultLogFunctionf!(LogLevel.critical);\n/// Ditto\nalias fatalf = defaultLogFunctionf!(LogLevel.fatal);\n\nprivate struct MsgRange\n{\n    import std.traits : isSomeString, isSomeChar;\n\n    private Logger log;\n\n    this(Logger log) @safe\n    {\n        this.log = log;\n    }\n\n    void put(T)(T msg) @safe\n        if (isSomeString!T)\n    {\n        log.logMsgPart(msg);\n    }\n\n    void put(dchar elem) @safe\n    {\n        import std.utf : encode;\n        char[4] buffer;\n        size_t len = encode(buffer, elem);\n        log.logMsgPart(buffer[0 .. len]);\n    }\n}\n\nprivate void formatString(A...)(MsgRange oRange, A args)\n{\n    import std.format : formattedWrite;\n\n    foreach (arg; args)\n    {\n        formattedWrite(oRange, \"%s\", arg);\n    }\n}\n\n@system unittest\n{\n    void dummy() @safe\n    {\n        auto tl = new TestLogger();\n        auto dst = MsgRange(tl);\n        formatString(dst, \"aaa\", \"bbb\");\n    }\n\n    dummy();\n}\n\n/**\nThere are eight usable logging level. These level are $(I all), $(I trace),\n$(I info), $(I warning), $(I error), $(I critical), $(I fatal), and $(I off).\nIf a log function with `LogLevel.fatal` is called the shutdown handler of\nthat logger is called.\n*/\nenum LogLevel : ubyte\n{\n    all = 1, /** Lowest possible assignable `LogLevel`. */\n    trace = 32, /** `LogLevel` for tracing the execution of the program. */\n    info = 64, /** This level is used to display information about the\n                program. */\n    warning = 96, /** warnings about the program should be displayed with this\n                   level. */\n    error = 128, /** Information about errors should be logged with this\n                   level.*/\n    critical = 160, /** Messages that inform about critical errors should be\n                    logged with this level. */\n    fatal = 192,   /** Log messages that describe fatal errors should use this\n                  level. */\n    off = ubyte.max /** Highest possible `LogLevel`. */\n}\n\n/** This class is the base of every logger. In order to create a new kind of\nlogger a deriving class needs to implement the `writeLogMsg` method. By\ndefault this is not thread-safe.\n\nIt is also possible to `override` the three methods `beginLogMsg`,\n`logMsgPart` and `finishLogMsg` together, this option gives more\nflexibility.\n*/\nabstract class Logger\n{\n    import std.array : appender, Appender;\n    import std.concurrency : thisTid, Tid;\n\n    /** LogEntry is a aggregation combining all information associated\n    with a log message. This aggregation will be passed to the method\n    writeLogMsg.\n    */\n    protected struct LogEntry\n    {\n        /// the filename the log function was called from\n        string file;\n        /// the line number the log function was called from\n        int line;\n        /// the name of the function the log function was called from\n        string funcName;\n        /// the pretty formatted name of the function the log function was\n        /// called from\n        string prettyFuncName;\n        /// the name of the module the log message is coming from\n        string moduleName;\n        /// the `LogLevel` associated with the log message\n        LogLevel logLevel;\n        /// thread id of the log message\n        Tid threadId;\n        /// the time the message was logged\n        SysTime timestamp;\n        /// the message of the log message\n        string msg;\n        /// A refernce to the `Logger` used to create this `LogEntry`\n        Logger logger;\n    }\n\n    /**\n    Every subclass of `Logger` has to call this constructor from their\n    constructor. It sets the `LogLevel`, and creates a fatal handler. The fatal\n    handler will throw an `Error` if a log call is made with level\n    `LogLevel.fatal`.\n\n    Params:\n         lv = `LogLevel` to use for this `Logger` instance.\n    */\n    this(LogLevel lv) @safe\n    {\n        this.logLevel_ = lv;\n        this.fatalHandler_ = delegate() {\n            throw new Error(\"A fatal log message was logged\");\n        };\n\n        this.mutex = new Mutex();\n    }\n\n    /** A custom logger must implement this method in order to work in a\n    `MultiLogger` and `ArrayLogger`.\n\n    Params:\n      payload = All information associated with call to log function.\n\n    See_Also: beginLogMsg, logMsgPart, finishLogMsg\n    */\n    abstract protected void writeLogMsg(ref LogEntry payload) @safe;\n\n    /* The default implementation will use an `std.array.appender`\n    internally to construct the message string. This means dynamic,\n    GC memory allocation. A logger can avoid this allocation by\n    reimplementing `beginLogMsg`, `logMsgPart` and `finishLogMsg`.\n    `beginLogMsg` is always called first, followed by any number of calls\n    to `logMsgPart` and one call to `finishLogMsg`.\n\n    As an example for such a custom `Logger` compare this:\n    ----------------\n    class CLogger : Logger\n    {\n        override void beginLogMsg(string file, int line, string funcName,\n            string prettyFuncName, string moduleName, LogLevel logLevel,\n            Tid threadId, SysTime timestamp)\n        {\n            ... logic here\n        }\n\n        override void logMsgPart(const(char)[] msg)\n        {\n            ... logic here\n        }\n\n        override void finishLogMsg()\n        {\n            ... logic here\n        }\n\n        void writeLogMsg(ref LogEntry payload)\n        {\n            this.beginLogMsg(payload.file, payload.line, payload.funcName,\n                payload.prettyFuncName, payload.moduleName, payload.logLevel,\n                payload.threadId, payload.timestamp, payload.logger);\n\n            this.logMsgPart(payload.msg);\n            this.finishLogMsg();\n        }\n    }\n    ----------------\n    */\n    protected void beginLogMsg(string file, int line, string funcName,\n        string prettyFuncName, string moduleName, LogLevel logLevel,\n        Tid threadId, SysTime timestamp, Logger logger)\n        @safe\n    {\n        static if (isLoggingActive)\n        {\n            msgAppender = appender!string();\n            header = LogEntry(file, line, funcName, prettyFuncName,\n                moduleName, logLevel, threadId, timestamp, null, logger);\n        }\n    }\n\n    /** Logs a part of the log message. */\n    protected void logMsgPart(scope const(char)[] msg) @safe\n    {\n        static if (isLoggingActive)\n        {\n               msgAppender.put(msg);\n        }\n    }\n\n    /** Signals that the message has been written and no more calls to\n    `logMsgPart` follow. */\n    protected void finishLogMsg() @safe\n    {\n        static if (isLoggingActive)\n        {\n            header.msg = msgAppender.data;\n            this.writeLogMsg(header);\n        }\n    }\n\n    /** The `LogLevel` determines if the log call are processed or dropped\n    by the `Logger`. In order for the log call to be processed the\n    `LogLevel` of the log call must be greater or equal to the `LogLevel`\n    of the `logger`.\n\n    These two methods set and get the `LogLevel` of the used `Logger`.\n\n    Example:\n    -----------\n    auto f = new FileLogger(stdout);\n    f.logLevel = LogLevel.info;\n    assert(f.logLevel == LogLevel.info);\n    -----------\n    */\n    @property final LogLevel logLevel() const pure @safe @nogc\n    {\n        return trustedLoad(this.logLevel_);\n    }\n\n    /// Ditto\n    @property final void logLevel(const LogLevel lv) @safe @nogc\n    {\n        synchronized (mutex) this.logLevel_ = lv;\n    }\n\n    /** This `delegate` is called in case a log message with\n    `LogLevel.fatal` gets logged.\n\n    By default an `Error` will be thrown.\n    */\n    @property final void delegate() fatalHandler() @safe @nogc\n    {\n        synchronized (mutex) return this.fatalHandler_;\n    }\n\n    /// Ditto\n    @property final void fatalHandler(void delegate() @safe fh) @safe @nogc\n    {\n        synchronized (mutex) this.fatalHandler_ = fh;\n    }\n\n    /** This method allows forwarding log entries from one logger to another.\n\n    `forwardMsg` will ensure proper synchronization and then call\n    `writeLogMsg`. This is an API for implementing your own loggers and\n    should not be called by normal user code. A notable difference from other\n    logging functions is that the `globalLogLevel` wont be evaluated again\n    since it is assumed that the caller already checked that.\n    */\n    void forwardMsg(ref LogEntry payload) @trusted\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            if (isLoggingEnabled(payload.logLevel, this.logLevel_,\n                globalLogLevel))\n            {\n                this.writeLogMsg(payload);\n\n                if (payload.logLevel == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /** This template provides the log functions for the `Logger` `class`\n    with the `LogLevel` encoded in the function name.\n\n    For further information see the the two functions defined inside of this\n    template.\n\n    The aliases following this template create the public names of these log\n    functions.\n    */\n    template memLogFunctions(LogLevel ll)\n    {\n        /** This function logs data to the used `Logger`.\n\n        In order for the resulting log message to be logged the `LogLevel`\n        must be greater or equal than the `LogLevel` of the used `Logger`\n        and must be greater or equal than the global `LogLevel`.\n\n        Params:\n          args = The data that should be logged.\n\n        Example:\n        --------------------\n        auto s = new FileLogger(stdout);\n        s.trace(1337, \"is number\");\n        s.info(1337, \"is number\");\n        s.error(1337, \"is number\");\n        s.critical(1337, \"is number\");\n        s.fatal(1337, \"is number\");\n        --------------------\n        */\n        void logImpl(int line = __LINE__, string file = __FILE__,\n            string funcName = __FUNCTION__,\n            string prettyFuncName = __PRETTY_FUNCTION__,\n            string moduleName = __MODULE__, A...)(lazy A args)\n            if (args.length == 0 || (args.length > 0 && !is(A[0] : bool)))\n        {\n            static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)\n                synchronized (mutex)\n            {\n                if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))\n                {\n                    this.beginLogMsg(file, line, funcName, prettyFuncName,\n                        moduleName, ll, thisTid, Clock.currTime, this);\n\n                    auto writer = MsgRange(this);\n                    formatString(writer, args);\n\n                    this.finishLogMsg();\n\n                    static if (ll == LogLevel.fatal)\n                        this.fatalHandler_();\n                }\n            }\n        }\n\n        /** This function logs data to the used `Logger` depending on a\n        condition.\n\n        In order for the resulting log message to be logged the `LogLevel` must\n        be greater or equal than the `LogLevel` of the used `Logger` and\n        must be greater or equal than the global `LogLevel` additionally the\n        condition passed must be `true`.\n\n        Params:\n          condition = The condition must be `true` for the data to be logged.\n          args = The data that should be logged.\n\n        Example:\n        --------------------\n        auto s = new FileLogger(stdout);\n        s.trace(true, 1337, \"is number\");\n        s.info(false, 1337, \"is number\");\n        s.error(true, 1337, \"is number\");\n        s.critical(false, 1337, \"is number\");\n        s.fatal(true, 1337, \"is number\");\n        --------------------\n        */\n        void logImpl(int line = __LINE__, string file = __FILE__,\n            string funcName = __FUNCTION__,\n            string prettyFuncName = __PRETTY_FUNCTION__,\n            string moduleName = __MODULE__, A...)(lazy bool condition,\n                lazy A args)\n        {\n            static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)\n                synchronized (mutex)\n            {\n                if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel,\n                                     condition))\n                {\n                    this.beginLogMsg(file, line, funcName, prettyFuncName,\n                        moduleName, ll, thisTid, Clock.currTime, this);\n\n                    auto writer = MsgRange(this);\n                    formatString(writer, args);\n\n                    this.finishLogMsg();\n\n                    static if (ll == LogLevel.fatal)\n                        this.fatalHandler_();\n                }\n            }\n        }\n\n        /** This function logs data to the used `Logger` in a\n        `printf`-style manner.\n\n        In order for the resulting log message to be logged the `LogLevel`\n        must be greater or equal than the `LogLevel` of the used `Logger`\n        and must be greater or equal than the global `LogLevel` additionally\n           the passed condition must be `true`.\n\n        Params:\n          condition = The condition must be `true` for the data to be logged.\n          msg = The `printf`-style string.\n          args = The data that should be logged.\n\n        Example:\n        --------------------\n        auto s = new FileLogger(stderr);\n        s.tracef(true, \"is number %d\", 1);\n        s.infof(true, \"is number %d\", 2);\n        s.errorf(false, \"is number %d\", 3);\n        s.criticalf(someFunc(), \"is number %d\", 4);\n        s.fatalf(true, \"is number %d\", 5);\n        --------------------\n        */\n        void logImplf(int line = __LINE__, string file = __FILE__,\n            string funcName = __FUNCTION__,\n            string prettyFuncName = __PRETTY_FUNCTION__,\n            string moduleName = __MODULE__, A...)(lazy bool condition,\n                lazy string msg, lazy A args)\n        {\n            static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)\n                synchronized (mutex)\n            {\n                import std.format : formattedWrite;\n\n                if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel,\n                                     condition))\n                {\n                    this.beginLogMsg(file, line, funcName, prettyFuncName,\n                        moduleName, ll, thisTid, Clock.currTime, this);\n\n                    auto writer = MsgRange(this);\n                    formattedWrite(writer, msg, args);\n\n                    this.finishLogMsg();\n\n                    static if (ll == LogLevel.fatal)\n                        this.fatalHandler_();\n                }\n            }\n        }\n\n        /** This function logs data to the used `Logger` in a\n        `printf`-style manner.\n\n        In order for the resulting log message to be logged the `LogLevel` must\n        be greater or equal than the `LogLevel` of the used `Logger` and\n        must be greater or equal than the global `LogLevel`.\n\n        Params:\n          msg = The `printf`-style string.\n          args = The data that should be logged.\n\n        Example:\n        --------------------\n        auto s = new FileLogger(stderr);\n        s.tracef(\"is number %d\", 1);\n        s.infof(\"is number %d\", 2);\n        s.errorf(\"is number %d\", 3);\n        s.criticalf(\"is number %d\", 4);\n        s.fatalf(\"is number %d\", 5);\n        --------------------\n        */\n        void logImplf(int line = __LINE__, string file = __FILE__,\n            string funcName = __FUNCTION__,\n            string prettyFuncName = __PRETTY_FUNCTION__,\n            string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)\n        {\n            static if (isLoggingActiveAt!ll && ll >= moduleLogLevel!moduleName)\n                synchronized (mutex)\n            {\n                import std.format : formattedWrite;\n\n                if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))\n                {\n                    this.beginLogMsg(file, line, funcName, prettyFuncName,\n                        moduleName, ll, thisTid, Clock.currTime, this);\n\n                    auto writer = MsgRange(this);\n                    formattedWrite(writer, msg, args);\n\n                    this.finishLogMsg();\n\n                    static if (ll == LogLevel.fatal)\n                        this.fatalHandler_();\n                }\n            }\n        }\n    }\n\n    /// Ditto\n    alias trace = memLogFunctions!(LogLevel.trace).logImpl;\n    /// Ditto\n    alias tracef = memLogFunctions!(LogLevel.trace).logImplf;\n    /// Ditto\n    alias info = memLogFunctions!(LogLevel.info).logImpl;\n    /// Ditto\n    alias infof = memLogFunctions!(LogLevel.info).logImplf;\n    /// Ditto\n    alias warning = memLogFunctions!(LogLevel.warning).logImpl;\n    /// Ditto\n    alias warningf = memLogFunctions!(LogLevel.warning).logImplf;\n    /// Ditto\n    alias error = memLogFunctions!(LogLevel.error).logImpl;\n    /// Ditto\n    alias errorf = memLogFunctions!(LogLevel.error).logImplf;\n    /// Ditto\n    alias critical = memLogFunctions!(LogLevel.critical).logImpl;\n    /// Ditto\n    alias criticalf = memLogFunctions!(LogLevel.critical).logImplf;\n    /// Ditto\n    alias fatal = memLogFunctions!(LogLevel.fatal).logImpl;\n    /// Ditto\n    alias fatalf = memLogFunctions!(LogLevel.fatal).logImplf;\n\n    /** This method logs data with the `LogLevel` of the used `Logger`.\n\n    This method takes a `bool` as first argument. In order for the\n    data to be processed the `bool` must be `true` and the `LogLevel`\n    of the Logger must be greater or equal to the global `LogLevel`.\n\n    Params:\n      args = The data that should be logged.\n      condition = The condition must be `true` for the data to be logged.\n      args = The data that is to be logged.\n\n    Returns: The logger used by the logging function as reference.\n\n    Example:\n    --------------------\n    auto l = new StdioLogger();\n    l.log(1337);\n    --------------------\n    */\n    void log(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(const LogLevel ll,\n        lazy bool condition, lazy A args)\n        if (args.length != 1)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel, condition))\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, ll, thisTid, Clock.currTime, this);\n\n                auto writer = MsgRange(this);\n                formatString(writer, args);\n\n                this.finishLogMsg();\n\n                if (ll == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /// Ditto\n    void log(T, string moduleName = __MODULE__)(const LogLevel ll,\n        lazy bool condition, lazy T args, int line = __LINE__,\n        string file = __FILE__, string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel,\n                condition) && ll >= moduleLogLevel!moduleName)\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, ll, thisTid, Clock.currTime, this);\n                auto writer = MsgRange(this);\n                formatString(writer, args);\n\n                this.finishLogMsg();\n\n                if (ll == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /** This function logs data to the used `Logger` with a specific\n    `LogLevel`.\n\n    In order for the resulting log message to be logged the `LogLevel`\n    must be greater or equal than the `LogLevel` of the used `Logger`\n    and must be greater or equal than the global `LogLevel`.\n\n    Params:\n      ll = The specific `LogLevel` used for logging the log message.\n      args = The data that should be logged.\n\n    Example:\n    --------------------\n    auto s = new FileLogger(stdout);\n    s.log(LogLevel.trace, 1337, \"is number\");\n    s.log(LogLevel.info, 1337, \"is number\");\n    s.log(LogLevel.warning, 1337, \"is number\");\n    s.log(LogLevel.error, 1337, \"is number\");\n    s.log(LogLevel.fatal, 1337, \"is number\");\n    --------------------\n    */\n    void log(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(const LogLevel ll, lazy A args)\n        if ((args.length > 1 && !is(Unqual!(A[0]) : bool)) || args.length == 0)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, ll, thisTid, Clock.currTime, this);\n\n                auto writer = MsgRange(this);\n                formatString(writer, args);\n\n                this.finishLogMsg();\n\n                if (ll == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /// Ditto\n    void log(T)(const LogLevel ll, lazy T args, int line = __LINE__,\n        string file = __FILE__, string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, ll, thisTid, Clock.currTime, this);\n                auto writer = MsgRange(this);\n                formatString(writer, args);\n\n                this.finishLogMsg();\n\n                if (ll == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /** This function logs data to the used `Logger` depending on a\n    explicitly passed condition with the `LogLevel` of the used\n    `Logger`.\n\n    In order for the resulting log message to be logged the `LogLevel`\n    of the used `Logger` must be greater or equal than the global\n    `LogLevel` and the condition must be `true`.\n\n    Params:\n      condition = The condition must be `true` for the data to be logged.\n      args = The data that should be logged.\n\n    Example:\n    --------------------\n    auto s = new FileLogger(stdout);\n    s.log(true, 1337, \"is number\");\n    s.log(true, 1337, \"is number\");\n    s.log(true, 1337, \"is number\");\n    s.log(false, 1337, \"is number\");\n    s.log(false, 1337, \"is number\");\n    --------------------\n    */\n    void log(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(lazy bool condition, lazy A args)\n        if (args.length != 1)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            if (isLoggingEnabled(this.logLevel_, this.logLevel_,\n                globalLogLevel, condition))\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);\n\n                auto writer = MsgRange(this);\n                formatString(writer, args);\n\n                this.finishLogMsg();\n\n                if (this.logLevel_ == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /// Ditto\n    void log(T)(lazy bool condition, lazy T args, int line = __LINE__,\n        string file = __FILE__, string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            if (isLoggingEnabled(this.logLevel_, this.logLevel_, globalLogLevel,\n                condition))\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);\n                auto writer = MsgRange(this);\n                formatString(writer, args);\n\n                this.finishLogMsg();\n\n                if (this.logLevel_ == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /** This function logs data to the used `Logger` with the `LogLevel`\n    of the used `Logger`.\n\n    In order for the resulting log message to be logged the `LogLevel`\n    of the used `Logger` must be greater or equal than the global\n    `LogLevel`.\n\n    Params:\n      args = The data that should be logged.\n\n    Example:\n    --------------------\n    auto s = new FileLogger(stdout);\n    s.log(1337, \"is number\");\n    s.log(info, 1337, \"is number\");\n    s.log(1337, \"is number\");\n    s.log(1337, \"is number\");\n    s.log(1337, \"is number\");\n    --------------------\n    */\n    void log(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(lazy A args)\n        if ((args.length > 1\n                && !is(Unqual!(A[0]) : bool)\n                && !is(Unqual!(A[0]) == LogLevel))\n            || args.length == 0)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            if (isLoggingEnabled(this.logLevel_, this.logLevel_,\n                globalLogLevel))\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);\n                auto writer = MsgRange(this);\n                formatString(writer, args);\n\n                this.finishLogMsg();\n\n                if (this.logLevel_ == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /// Ditto\n    void log(T)(lazy T arg, int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            if (isLoggingEnabled(this.logLevel_, this.logLevel_, globalLogLevel))\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);\n                auto writer = MsgRange(this);\n                formatString(writer, arg);\n\n                this.finishLogMsg();\n\n                if (this.logLevel_ == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /** This function logs data to the used `Logger` with a specific\n    `LogLevel` and depending on a condition in a `printf`-style manner.\n\n    In order for the resulting log message to be logged the `LogLevel`\n    must be greater or equal than the `LogLevel` of the used `Logger`\n    and must be greater or equal than the global `LogLevel` and the\n    condition must be `true`.\n\n    Params:\n      ll = The specific `LogLevel` used for logging the log message.\n      condition = The condition must be `true` for the data to be logged.\n      msg = The format string used for this log call.\n      args = The data that should be logged.\n\n    Example:\n    --------------------\n    auto s = new FileLogger(stdout);\n    s.logf(LogLevel.trace, true ,\"%d %s\", 1337, \"is number\");\n    s.logf(LogLevel.info, true ,\"%d %s\", 1337, \"is number\");\n    s.logf(LogLevel.warning, true ,\"%d %s\", 1337, \"is number\");\n    s.logf(LogLevel.error, false ,\"%d %s\", 1337, \"is number\");\n    s.logf(LogLevel.fatal, true ,\"%d %s\", 1337, \"is number\");\n    --------------------\n    */\n    void logf(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(const LogLevel ll,\n        lazy bool condition, lazy string msg, lazy A args)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            import std.format : formattedWrite;\n\n            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel, condition))\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, ll, thisTid, Clock.currTime, this);\n\n                auto writer = MsgRange(this);\n                formattedWrite(writer, msg, args);\n\n                this.finishLogMsg();\n\n                if (ll == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /** This function logs data to the used `Logger` with a specific\n    `LogLevel` in a `printf`-style manner.\n\n    In order for the resulting log message to be logged the `LogLevel`\n    must be greater or equal than the `LogLevel` of the used `Logger`\n    and must be greater or equal than the global `LogLevel`.\n\n    Params:\n      ll = The specific `LogLevel` used for logging the log message.\n      msg = The format string used for this log call.\n      args = The data that should be logged.\n\n    Example:\n    --------------------\n    auto s = new FileLogger(stdout);\n    s.logf(LogLevel.trace, \"%d %s\", 1337, \"is number\");\n    s.logf(LogLevel.info, \"%d %s\", 1337, \"is number\");\n    s.logf(LogLevel.warning, \"%d %s\", 1337, \"is number\");\n    s.logf(LogLevel.error, \"%d %s\", 1337, \"is number\");\n    s.logf(LogLevel.fatal, \"%d %s\", 1337, \"is number\");\n    --------------------\n    */\n    void logf(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(const LogLevel ll,\n            lazy string msg, lazy A args)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            import std.format : formattedWrite;\n\n            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, ll, thisTid, Clock.currTime, this);\n\n                auto writer = MsgRange(this);\n                formattedWrite(writer, msg, args);\n\n                this.finishLogMsg();\n\n                if (ll == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /** This function logs data to the used `Logger` depending on a\n    condition with the `LogLevel` of the used `Logger` in a\n    `printf`-style manner.\n\n    In order for the resulting log message to be logged the `LogLevel`\n    of the used `Logger` must be greater or equal than the global\n    `LogLevel` and the condition must be `true`.\n\n    Params:\n      condition = The condition must be `true` for the data to be logged.\n      msg = The format string used for this log call.\n      args = The data that should be logged.\n\n    Example:\n    --------------------\n    auto s = new FileLogger(stdout);\n    s.logf(true ,\"%d %s\", 1337, \"is number\");\n    s.logf(true ,\"%d %s\", 1337, \"is number\");\n    s.logf(true ,\"%d %s\", 1337, \"is number\");\n    s.logf(false ,\"%d %s\", 1337, \"is number\");\n    s.logf(true ,\"%d %s\", 1337, \"is number\");\n    --------------------\n    */\n    void logf(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(lazy bool condition,\n            lazy string msg, lazy A args)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            import std.format : formattedWrite;\n\n            if (isLoggingEnabled(this.logLevel_, this.logLevel_, globalLogLevel,\n                condition))\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);\n\n                auto writer = MsgRange(this);\n                formattedWrite(writer, msg, args);\n\n                this.finishLogMsg();\n\n                if (this.logLevel_ == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    /** This method logs data to the used `Logger` with the `LogLevel`\n    of the this `Logger` in a `printf`-style manner.\n\n    In order for the data to be processed the `LogLevel` of the `Logger`\n    must be greater or equal to the global `LogLevel`.\n\n    Params:\n      msg = The format string used for this log call.\n      args = The data that should be logged.\n\n    Example:\n    --------------------\n    auto s = new FileLogger(stdout);\n    s.logf(\"%d %s\", 1337, \"is number\");\n    s.logf(\"%d %s\", 1337, \"is number\");\n    s.logf(\"%d %s\", 1337, \"is number\");\n    s.logf(\"%d %s\", 1337, \"is number\");\n    s.logf(\"%d %s\", 1337, \"is number\");\n    --------------------\n    */\n    void logf(int line = __LINE__, string file = __FILE__,\n        string funcName = __FUNCTION__,\n        string prettyFuncName = __PRETTY_FUNCTION__,\n        string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)\n    {\n        static if (isLoggingActive) synchronized (mutex)\n        {\n            import std.format : formattedWrite;\n\n            if (isLoggingEnabled(this.logLevel_, this.logLevel_,\n                globalLogLevel))\n            {\n                this.beginLogMsg(file, line, funcName, prettyFuncName,\n                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);\n\n                auto writer = MsgRange(this);\n                formattedWrite(writer, msg, args);\n\n                this.finishLogMsg();\n\n                if (this.logLevel_ == LogLevel.fatal)\n                    this.fatalHandler_();\n            }\n        }\n    }\n\n    private void delegate() @safe fatalHandler_;\n    private shared LogLevel logLevel_ = LogLevel.info;\n    private Mutex mutex;\n\n    protected Appender!string msgAppender;\n    protected LogEntry header;\n}\n\n// Thread Global\n\nprivate __gshared Logger stdSharedDefaultLogger;\nprivate shared Logger stdSharedLogger;\nprivate shared LogLevel stdLoggerGlobalLogLevel = LogLevel.all;\n\n/* This method returns the global default Logger.\n * Marked @trusted because of excessive reliance on __gshared data\n */\nprivate @property Logger defaultSharedLoggerImpl() @trusted\n{\n    import std.conv : emplace;\n    import std.stdio : stderr;\n\n    __gshared align(FileLogger.alignof) void[__traits(classInstanceSize, FileLogger)] _buffer;\n\n    import std.concurrency : initOnce;\n    initOnce!stdSharedDefaultLogger({\n        auto buffer = cast(ubyte[]) _buffer;\n        return emplace!FileLogger(buffer, stderr, LogLevel.all);\n    }());\n\n    return stdSharedDefaultLogger;\n}\n\n/** This property sets and gets the default `Logger`.\n\nExample:\n-------------\nsharedLog = new FileLogger(yourFile);\n-------------\nThe example sets a new `FileLogger` as new `sharedLog`.\n\nIf at some point you want to use the original default logger again, you can\nuse $(D sharedLog = null;). This will put back the original.\n\nNote:\nWhile getting and setting `sharedLog` is thread-safe, it has to be considered\nthat the returned reference is only a current snapshot and in the following\ncode, you must make sure no other thread reassigns to it between reading and\nwriting `sharedLog`.\n\n`sharedLog` is only thread-safe if the the used `Logger` is thread-safe.\nThe default `Logger` is thread-safe.\n-------------\nif (sharedLog !is myLogger)\n    sharedLog = new myLogger;\n-------------\n*/\n@property Logger sharedLog() @safe\n{\n    static auto trustedLoad(ref shared Logger logger) @trusted\n    {\n        import core.atomic : atomicLoad, MemoryOrder;\n        return cast() atomicLoad!(MemoryOrder.acq)(logger);\n            //FIXME: Casting shared away here. Not good. See issue 16232.\n    }\n\n    // If we have set up our own logger use that\n    if (auto logger = trustedLoad(stdSharedLogger))\n    {\n        return logger;\n    }\n    else\n    {\n        // Otherwise resort to the default logger\n        return defaultSharedLoggerImpl;\n    }\n}\n\n/// Ditto\n@property void sharedLog(Logger logger) @trusted\n{\n    import core.atomic : atomicStore, MemoryOrder;\n    atomicStore!(MemoryOrder.rel)(stdSharedLogger, cast(shared) logger);\n}\n\n/** This methods get and set the global `LogLevel`.\n\nEvery log message with a `LogLevel` lower as the global `LogLevel`\nwill be discarded before it reaches `writeLogMessage` method of any\n`Logger`.\n*/\n/* Implementation note:\nFor any public logging call, the global log level shall only be queried once on\nentry. Otherwise when another threads changes the level, we would work with\ndifferent levels at different spots in the code.\n*/\n@property LogLevel globalLogLevel() @safe @nogc\n{\n    return trustedLoad(stdLoggerGlobalLogLevel);\n}\n\n/// Ditto\n@property void globalLogLevel(LogLevel ll) @safe\n{\n    trustedStore(stdLoggerGlobalLogLevel, ll);\n}\n\n// Thread Local\n\n/** The `StdForwardLogger` will always forward anything to the sharedLog.\n\nThe `StdForwardLogger` will not throw if data is logged with $(D\nLogLevel.fatal).\n*/\nclass StdForwardLogger : Logger\n{\n    /** The default constructor for the `StdForwardLogger`.\n\n    Params:\n      lv = The `LogLevel` for the `MultiLogger`. By default the $(D\n          LogLevel) is `all`.\n    */\n    this(const LogLevel lv = LogLevel.all) @safe\n    {\n        super(lv);\n        this.fatalHandler = delegate() {};\n    }\n\n    override protected void writeLogMsg(ref LogEntry payload)\n    {\n          sharedLog.forwardMsg(payload);\n    }\n}\n\n///\n@safe unittest\n{\n    auto nl1 = new StdForwardLogger(LogLevel.all);\n}\n\n/** This `LogLevel` is unqiue to every thread.\n\nThe thread local `Logger` will use this `LogLevel` to filter log calls\nevery same way as presented earlier.\n*/\n//public LogLevel threadLogLevel = LogLevel.all;\nprivate Logger stdLoggerThreadLogger;\nprivate Logger stdLoggerDefaultThreadLogger;\n\n/* This method returns the thread local default Logger.\n*/\nprivate @property Logger stdThreadLocalLogImpl() @trusted\n{\n    import std.conv : emplace;\n\n    static void*[(__traits(classInstanceSize, StdForwardLogger) - 1) / (void*).sizeof + 1] _buffer;\n\n    auto buffer = cast(ubyte[]) _buffer;\n\n    if (stdLoggerDefaultThreadLogger is null)\n    {\n        stdLoggerDefaultThreadLogger = emplace!StdForwardLogger(buffer, LogLevel.all);\n    }\n    return stdLoggerDefaultThreadLogger;\n}\n\n/** This function returns a thread unique `Logger`, that by default\npropergates all data logged to it to the `sharedLog`.\n\nThese properties can be used to set and get this `Logger`. Every\nmodification to this `Logger` will only be visible in the thread the\nmodification has been done from.\n\nThis `Logger` is called by the free standing log functions. This allows to\ncreate thread local redirections and still use the free standing log\nfunctions.\n*/\n@property Logger stdThreadLocalLog() @safe\n{\n    // If we have set up our own logger use that\n    if (auto logger = stdLoggerThreadLogger)\n        return logger;\n    else\n        // Otherwise resort to the default logger\n        return stdThreadLocalLogImpl;\n}\n\n/// Ditto\n@property void stdThreadLocalLog(Logger logger) @safe\n{\n    stdLoggerThreadLogger = logger;\n}\n\n/// Ditto\n@system unittest\n{\n    import std.experimental.logger.filelogger : FileLogger;\n    import std.file : deleteme, remove;\n    Logger l = stdThreadLocalLog;\n    stdThreadLocalLog = new FileLogger(deleteme ~ \"-someFile.log\");\n    scope(exit) remove(deleteme ~ \"-someFile.log\");\n\n    auto tempLog = stdThreadLocalLog;\n    stdThreadLocalLog = l;\n    destroy(tempLog);\n}\n\n@safe unittest\n{\n    LogLevel ll = globalLogLevel;\n    globalLogLevel = LogLevel.fatal;\n    assert(globalLogLevel == LogLevel.fatal);\n    globalLogLevel = ll;\n}\n\npackage class TestLogger : Logger\n{\n    int line = -1;\n    string file = null;\n    string func = null;\n    string prettyFunc = null;\n    string msg = null;\n    LogLevel lvl;\n\n    this(const LogLevel lv = LogLevel.all) @safe\n    {\n        super(lv);\n    }\n\n    override protected void writeLogMsg(ref LogEntry payload) @safe\n    {\n        this.line = payload.line;\n        this.file = payload.file;\n        this.func = payload.funcName;\n        this.prettyFunc = payload.prettyFuncName;\n        this.lvl = payload.logLevel;\n        this.msg = payload.msg;\n    }\n}\n\nversion (unittest) private void testFuncNames(Logger logger) @safe\n{\n    string s = \"I'm here\";\n    logger.log(s);\n}\n\n@safe unittest\n{\n    auto tl1 = new TestLogger();\n    testFuncNames(tl1);\n    assert(tl1.func == \"std.experimental.logger.core.testFuncNames\", tl1.func);\n    assert(tl1.prettyFunc ==\n        \"void std.experimental.logger.core.testFuncNames(Logger logger) @safe\",\n        tl1.prettyFunc);\n    assert(tl1.msg == \"I'm here\", tl1.msg);\n}\n\n@safe unittest\n{\n    auto tl1 = new TestLogger(LogLevel.all);\n    tl1.log();\n    assert(tl1.line == __LINE__ - 1);\n    tl1.log(true);\n    assert(tl1.line == __LINE__ - 1);\n    tl1.log(false);\n    assert(tl1.line == __LINE__ - 3);\n    tl1.log(LogLevel.info);\n    assert(tl1.line == __LINE__ - 1);\n    tl1.log(LogLevel.off);\n    assert(tl1.line == __LINE__ - 3);\n    tl1.log(LogLevel.info, true);\n    assert(tl1.line == __LINE__ - 1);\n    tl1.log(LogLevel.info, false);\n    assert(tl1.line == __LINE__ - 3);\n\n    auto oldunspecificLogger = sharedLog;\n    scope(exit) {\n        sharedLog = oldunspecificLogger;\n    }\n\n    sharedLog = tl1;\n\n    log();\n    assert(tl1.line == __LINE__ - 1);\n\n    log(LogLevel.info);\n    assert(tl1.line == __LINE__ - 1);\n\n    log(true);\n    assert(tl1.line == __LINE__ - 1);\n\n    log(LogLevel.warning, true);\n    assert(tl1.line == __LINE__ - 1);\n\n    trace();\n    assert(tl1.line == __LINE__ - 1);\n}\n\n@safe unittest\n{\n    import std.experimental.logger.multilogger : MultiLogger;\n\n    auto tl1 = new TestLogger;\n    auto tl2 = new TestLogger;\n\n    auto ml = new MultiLogger();\n    ml.insertLogger(\"one\", tl1);\n    ml.insertLogger(\"two\", tl2);\n\n    string msg = \"Hello Logger World\";\n    ml.log(msg);\n    int lineNumber = __LINE__ - 1;\n    assert(tl1.msg == msg);\n    assert(tl1.line == lineNumber);\n    assert(tl2.msg == msg);\n    assert(tl2.line == lineNumber);\n\n    ml.removeLogger(\"one\");\n    ml.removeLogger(\"two\");\n    auto n = ml.removeLogger(\"one\");\n    assert(n is null);\n}\n\n@safe unittest\n{\n    bool errorThrown = false;\n    auto tl = new TestLogger;\n    auto dele = delegate() {\n        errorThrown = true;\n    };\n    tl.fatalHandler = dele;\n    tl.fatal();\n    assert(errorThrown);\n}\n\n@safe unittest\n{\n    import std.conv : to;\n    import std.exception : assertThrown, assertNotThrown;\n    import std.format : format;\n\n    auto l = new TestLogger(LogLevel.all);\n    string msg = \"Hello Logger World\";\n    l.log(msg);\n    int lineNumber = __LINE__ - 1;\n    assert(l.msg == msg);\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    l.log(true, msg);\n    lineNumber = __LINE__ - 1;\n    assert(l.msg == msg, l.msg);\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    l.log(false, msg);\n    assert(l.msg == msg);\n    assert(l.line == lineNumber, to!string(l.line));\n    assert(l.logLevel == LogLevel.all);\n\n    msg = \"%s Another message\";\n    l.logf(msg, \"Yet\");\n    lineNumber = __LINE__ - 1;\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    l.logf(true, msg, \"Yet\");\n    lineNumber = __LINE__ - 1;\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    l.logf(false, msg, \"Yet\");\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    () @trusted {\n        assertThrown!Throwable(l.logf(LogLevel.fatal, msg, \"Yet\"));\n    } ();\n    lineNumber = __LINE__ - 2;\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    () @trusted {\n        assertThrown!Throwable(l.logf(LogLevel.fatal, true, msg, \"Yet\"));\n    } ();\n    lineNumber = __LINE__ - 2;\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    assertNotThrown(l.logf(LogLevel.fatal, false, msg, \"Yet\"));\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    auto oldunspecificLogger = sharedLog;\n\n    assert(oldunspecificLogger.logLevel == LogLevel.all,\n         to!string(oldunspecificLogger.logLevel));\n\n    assert(l.logLevel == LogLevel.all);\n    sharedLog = l;\n    assert(globalLogLevel == LogLevel.all,\n            to!string(globalLogLevel));\n\n    scope(exit)\n    {\n        sharedLog = oldunspecificLogger;\n    }\n\n    assert(sharedLog.logLevel == LogLevel.all);\n    assert(stdThreadLocalLog.logLevel == LogLevel.all);\n    assert(globalLogLevel == LogLevel.all);\n\n    msg = \"Another message\";\n    log(msg);\n    lineNumber = __LINE__ - 1;\n    assert(l.logLevel == LogLevel.all);\n    assert(l.line == lineNumber, to!string(l.line));\n    assert(l.msg == msg, l.msg);\n\n    log(true, msg);\n    lineNumber = __LINE__ - 1;\n    assert(l.msg == msg);\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    log(false, msg);\n    assert(l.msg == msg);\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    msg = \"%s Another message\";\n    logf(msg, \"Yet\");\n    lineNumber = __LINE__ - 1;\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    logf(true, msg, \"Yet\");\n    lineNumber = __LINE__ - 1;\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    logf(false, msg, \"Yet\");\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    msg = \"%s Another message\";\n    () @trusted {\n        assertThrown!Throwable(logf(LogLevel.fatal, msg, \"Yet\"));\n    } ();\n    lineNumber = __LINE__ - 2;\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    () @trusted {\n        assertThrown!Throwable(logf(LogLevel.fatal, true, msg, \"Yet\"));\n    } ();\n    lineNumber = __LINE__ - 2;\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n\n    assertNotThrown(logf(LogLevel.fatal, false, msg, \"Yet\"));\n    assert(l.msg == msg.format(\"Yet\"));\n    assert(l.line == lineNumber);\n    assert(l.logLevel == LogLevel.all);\n}\n\n@system unittest // default logger\n{\n    import std.file : deleteme, exists, remove;\n    import std.stdio : File;\n    import std.string : indexOf;\n\n    string filename = deleteme ~ __FUNCTION__ ~ \".tempLogFile\";\n    FileLogger l = new FileLogger(filename);\n    auto oldunspecificLogger = sharedLog;\n    sharedLog = l;\n\n    scope(exit)\n    {\n        remove(filename);\n        assert(!exists(filename));\n        sharedLog = oldunspecificLogger;\n        globalLogLevel = LogLevel.all;\n    }\n\n    string notWritten = \"this should not be written to file\";\n    string written = \"this should be written to file\";\n\n    globalLogLevel = LogLevel.critical;\n    assert(globalLogLevel == LogLevel.critical);\n\n    log(LogLevel.warning, notWritten);\n    log(LogLevel.critical, written);\n\n    l.file.flush();\n    l.file.close();\n\n    auto file = File(filename, \"r\");\n    assert(!file.eof);\n\n    string readLine = file.readln();\n    assert(readLine.indexOf(written) != -1, readLine);\n    assert(readLine.indexOf(notWritten) == -1, readLine);\n    file.close();\n}\n\n@system unittest\n{\n    import std.file : deleteme, remove;\n    import std.stdio : File;\n    import std.string : indexOf;\n\n    string filename = deleteme ~ __FUNCTION__ ~ \".tempLogFile\";\n    auto oldunspecificLogger = sharedLog;\n\n    scope(exit)\n    {\n        remove(filename);\n        sharedLog = oldunspecificLogger;\n        globalLogLevel = LogLevel.all;\n    }\n\n    string notWritten = \"this should not be written to file\";\n    string written = \"this should be written to file\";\n\n    auto l = new FileLogger(filename);\n    sharedLog = l;\n    sharedLog.logLevel = LogLevel.critical;\n\n    log(LogLevel.error, false, notWritten);\n    log(LogLevel.critical, true, written);\n    destroy(l);\n\n    auto file = File(filename, \"r\");\n    auto readLine = file.readln();\n    assert(!readLine.empty, readLine);\n    assert(readLine.indexOf(written) != -1);\n    assert(readLine.indexOf(notWritten) == -1);\n    file.close();\n}\n\n@safe unittest\n{\n    import std.conv : to;\n\n    auto tl = new TestLogger(LogLevel.all);\n    int l = __LINE__;\n    tl.info(\"a\");\n    assert(tl.line == l+1);\n    assert(tl.msg == \"a\");\n    assert(tl.logLevel == LogLevel.all);\n    assert(globalLogLevel == LogLevel.all);\n    l = __LINE__;\n    tl.trace(\"b\");\n    assert(tl.msg == \"b\", tl.msg);\n    assert(tl.line == l+1, to!string(tl.line));\n}\n\n// testing possible log conditions\n@safe unittest\n{\n    import std.conv : to;\n    import std.format : format;\n    import std.string : indexOf;\n\n    auto oldunspecificLogger = sharedLog;\n\n    auto mem = new TestLogger;\n    mem.fatalHandler = delegate() {};\n    sharedLog = mem;\n\n    scope(exit)\n    {\n        sharedLog = oldunspecificLogger;\n        globalLogLevel = LogLevel.all;\n    }\n\n    int value = 0;\n    foreach (gll; [cast(LogLevel) LogLevel.all, LogLevel.trace,\n            LogLevel.info, LogLevel.warning, LogLevel.error,\n            LogLevel.critical, LogLevel.fatal, LogLevel.off])\n    {\n\n        globalLogLevel = gll;\n\n        foreach (ll; [cast(LogLevel) LogLevel.all, LogLevel.trace,\n                LogLevel.info, LogLevel.warning, LogLevel.error,\n                LogLevel.critical, LogLevel.fatal, LogLevel.off])\n        {\n\n            mem.logLevel = ll;\n\n            foreach (cond; [true, false])\n            {\n                foreach (condValue; [true, false])\n                {\n                    foreach (memOrG; [true, false])\n                    {\n                        foreach (prntf; [true, false])\n                        {\n                            foreach (ll2; [cast(LogLevel) LogLevel.all, LogLevel.trace,\n                                    LogLevel.info, LogLevel.warning,\n                                    LogLevel.error, LogLevel.critical,\n                                    LogLevel.fatal, LogLevel.off])\n                            {\n                                foreach (singleMulti; 0 .. 2)\n                                {\n                                    int lineCall;\n                                    mem.msg = \"-1\";\n                                    if (memOrG)\n                                    {\n                                        if (prntf)\n                                        {\n                                            if (cond)\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    mem.logf(ll2, condValue, \"%s\",\n                                                        value);\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    mem.logf(ll2, condValue,\n                                                        \"%d %d\", value, value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                            else\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    mem.logf(ll2, \"%s\", value);\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    mem.logf(ll2, \"%d %d\",\n                                                        value, value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                        }\n                                        else\n                                        {\n                                            if (cond)\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    mem.log(ll2, condValue,\n                                                        to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    mem.log(ll2, condValue,\n                                                        to!string(value), value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                            else\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    mem.log(ll2, to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    mem.log(ll2,\n                                                        to!string(value),\n                                                        value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                        }\n                                    }\n                                    else\n                                    {\n                                        if (prntf)\n                                        {\n                                            if (cond)\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    logf(ll2, condValue, \"%s\",\n                                                        value);\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    logf(ll2, condValue,\n                                                        \"%s %d\", value, value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                            else\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    logf(ll2, \"%s\", value);\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    logf(ll2, \"%s %s\", value,\n                                                        value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                        }\n                                        else\n                                        {\n                                            if (cond)\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    log(ll2, condValue,\n                                                        to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    log(ll2, condValue, value,\n                                                        to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                            else\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    log(ll2, to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    log(ll2, value,\n                                                        to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                        }\n                                    }\n\n                                    string valueStr = to!string(value);\n                                    ++value;\n\n                                    bool ll2Off = (ll2 != LogLevel.off);\n                                    bool gllOff = (gll != LogLevel.off);\n                                    bool llOff = (ll != LogLevel.off);\n                                    bool condFalse = (cond ? condValue : true);\n                                    bool ll2VSgll = (ll2 >= gll);\n                                    bool ll2VSll = (ll2 >= ll);\n\n                                    bool shouldLog = ll2Off && gllOff && llOff\n                                        && condFalse && ll2VSgll && ll2VSll;\n\n                                    /*\n                                    writefln(\n                                        \"go(%b) ll2o(%b) c(%b) lg(%b) ll(%b) s(%b)\"\n                                        , gll != LogLevel.off, ll2 != LogLevel.off,\n                                        cond ? condValue : true,\n                                        ll2 >= gll, ll2 >= ll, shouldLog);\n                                    */\n\n\n                                    if (shouldLog)\n                                    {\n                                        assert(mem.msg.indexOf(valueStr) != -1,\n                                            format(\n                                            \"lineCall(%d) ll2Off(%u) gll(%u) ll(%u) ll2(%u) \" ~\n                                            \"cond(%b) condValue(%b)\" ~\n                                            \" memOrG(%b) shouldLog(%b) %s == %s\" ~\n                                            \" %b %b %b %b %b\",\n                                            lineCall, ll2Off, gll, ll, ll2, cond,\n                                            condValue, memOrG, shouldLog, mem.msg,\n                                            valueStr, gllOff, llOff, condFalse,\n                                            ll2VSgll, ll2VSll\n                                        ));\n                                    }\n                                    else\n                                    {\n                                        assert(mem.msg.indexOf(valueStr),\n                                            format(\n                                            \"lineCall(%d) ll2Off(%u) gll(%u) ll(%u) ll2(%u) \" ~\n                                            \"cond(%b) condValue(%b)\" ~\n                                            \" memOrG(%b) shouldLog(%b) %s == %s\" ~\n                                            \" %b %b %b %b %b\",\n                                            lineCall, ll2Off, gll, ll, ll2, cond,\n                                            condValue, memOrG, shouldLog, mem.msg,\n                                            valueStr, gllOff, llOff, condFalse,\n                                            ll2VSgll, ll2VSll\n                                        ));\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n// more testing\n@safe unittest\n{\n    import std.conv : to;\n    import std.format : format;\n    import std.string : indexOf;\n\n    auto oldunspecificLogger = sharedLog;\n\n    auto mem = new TestLogger;\n    mem.fatalHandler = delegate() {};\n    sharedLog = mem;\n\n    scope(exit)\n    {\n        sharedLog = oldunspecificLogger;\n        globalLogLevel = LogLevel.all;\n    }\n\n    int value = 0;\n    foreach (gll; [cast(LogLevel) LogLevel.all, LogLevel.trace,\n            LogLevel.info, LogLevel.warning, LogLevel.error,\n            LogLevel.critical, LogLevel.fatal, LogLevel.off])\n    {\n\n        globalLogLevel = gll;\n\n        foreach (ll; [cast(LogLevel) LogLevel.all, LogLevel.trace,\n                LogLevel.info, LogLevel.warning, LogLevel.error,\n                LogLevel.critical, LogLevel.fatal, LogLevel.off])\n        {\n            mem.logLevel = ll;\n\n            foreach (tll; [cast(LogLevel) LogLevel.all, LogLevel.trace,\n                    LogLevel.info, LogLevel.warning, LogLevel.error,\n                    LogLevel.critical, LogLevel.fatal, LogLevel.off])\n            {\n                stdThreadLocalLog.logLevel = tll;\n\n                foreach (cond; [true, false])\n                {\n                    foreach (condValue; [true, false])\n                    {\n                        foreach (memOrG; [true, false])\n                        {\n                            foreach (prntf; [true, false])\n                            {\n                                foreach (singleMulti; 0 .. 2)\n                                {\n                                    int lineCall;\n                                    mem.msg = \"-1\";\n                                    if (memOrG)\n                                    {\n                                        if (prntf)\n                                        {\n                                            if (cond)\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    mem.logf(condValue, \"%s\",\n                                                        value);\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    mem.logf(condValue,\n                                                        \"%d %d\", value, value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                            else\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    mem.logf(\"%s\", value);\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    mem.logf(\"%d %d\",\n                                                        value, value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                        }\n                                        else\n                                        {\n                                            if (cond)\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    mem.log(condValue,\n                                                        to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    mem.log(condValue,\n                                                        to!string(value), value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                            else\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    mem.log(to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    mem.log(to!string(value),\n                                                        value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                        }\n                                    }\n                                    else\n                                    {\n                                        if (prntf)\n                                        {\n                                            if (cond)\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    logf(condValue, \"%s\", value);\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    logf(condValue, \"%s %d\", value,\n                                                        value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                            else\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    logf(\"%s\", value);\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    logf(\"%s %s\", value, value);\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                        }\n                                        else\n                                        {\n                                            if (cond)\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    log(condValue,\n                                                        to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    log(condValue, value,\n                                                        to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                            else\n                                            {\n                                                if (singleMulti == 0)\n                                                {\n                                                    log(to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                                else\n                                                {\n                                                    log(value, to!string(value));\n                                                    lineCall = __LINE__;\n                                                }\n                                            }\n                                        }\n                                    }\n\n                                    string valueStr = to!string(value);\n                                    ++value;\n\n                                    bool gllOff = (gll != LogLevel.off);\n                                    bool llOff = (ll != LogLevel.off);\n                                    bool tllOff = (tll != LogLevel.off);\n                                    bool llVSgll = (ll >= gll);\n                                    bool tllVSll =\n                                        (stdThreadLocalLog.logLevel >= ll);\n                                    bool condFalse = (cond ? condValue : true);\n\n                                    bool shouldLog = gllOff && llOff\n                                        && (memOrG ? true : tllOff)\n                                        && (memOrG ?\n                                            (ll >= gll) :\n                                            (tll >= gll && tll >= ll))\n                                        && condFalse;\n\n                                    if (shouldLog)\n                                    {\n                                        assert(mem.msg.indexOf(valueStr) != -1,\n                                            format(\"\\ngll(%s) ll(%s) tll(%s) \" ~\n                                                \"cond(%s) condValue(%s) \" ~\n                                                \"memOrG(%s) prntf(%s) \" ~\n                                                \"singleMulti(%s)\",\n                                                gll, ll, tll, cond, condValue,\n                                                memOrG, prntf, singleMulti)\n                                            ~ format(\" gllOff(%s) llOff(%s) \" ~\n                                                \"llVSgll(%s) tllVSll(%s) \" ~\n                                                \"tllOff(%s) condFalse(%s) \"\n                                                ~ \"shoudlLog(%s)\",\n                                                gll != LogLevel.off,\n                                                ll != LogLevel.off, llVSgll,\n                                                tllVSll, tllOff, condFalse,\n                                                shouldLog)\n                                            ~ format(\"msg(%s) line(%s) \" ~\n                                                \"lineCall(%s) valueStr(%s)\",\n                                                mem.msg, mem.line, lineCall,\n                                                valueStr)\n                                        );\n                                    }\n                                    else\n                                    {\n                                        assert(mem.msg.indexOf(valueStr) == -1,\n                                            format(\"\\ngll(%s) ll(%s) tll(%s) \" ~\n                                                \"cond(%s) condValue(%s) \" ~\n                                                \"memOrG(%s) prntf(%s) \" ~\n                                                \"singleMulti(%s)\",\n                                                gll, ll, tll, cond, condValue,\n                                                memOrG, prntf, singleMulti)\n                                            ~ format(\" gllOff(%s) llOff(%s) \" ~\n                                                \"llVSgll(%s) tllVSll(%s) \" ~\n                                                \"tllOff(%s) condFalse(%s) \"\n                                                ~ \"shoudlLog(%s)\",\n                                                gll != LogLevel.off,\n                                                ll != LogLevel.off, llVSgll,\n                                                tllVSll, tllOff, condFalse,\n                                                shouldLog)\n                                            ~ format(\"msg(%s) line(%s) \" ~\n                                                \"lineCall(%s) valueStr(%s)\",\n                                                mem.msg, mem.line, lineCall,\n                                                valueStr)\n                                        );\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n// testing more possible log conditions\n@safe unittest\n{\n    bool fatalLog;\n    auto mem = new TestLogger;\n    mem.fatalHandler = delegate() { fatalLog = true; };\n    auto oldunspecificLogger = sharedLog;\n\n    stdThreadLocalLog.logLevel = LogLevel.all;\n\n    sharedLog = mem;\n    scope(exit)\n    {\n        sharedLog = oldunspecificLogger;\n        globalLogLevel = LogLevel.all;\n    }\n\n    foreach (gll; [cast(LogLevel) LogLevel.all, LogLevel.trace,\n            LogLevel.info, LogLevel.warning, LogLevel.error,\n            LogLevel.critical, LogLevel.fatal, LogLevel.off])\n    {\n\n        globalLogLevel = gll;\n\n        foreach (ll; [cast(LogLevel) LogLevel.all, LogLevel.trace,\n                LogLevel.info, LogLevel.warning, LogLevel.error,\n                LogLevel.critical, LogLevel.fatal, LogLevel.off])\n        {\n            mem.logLevel = ll;\n\n            foreach (tll; [cast(LogLevel) LogLevel.all, LogLevel.trace,\n                    LogLevel.info, LogLevel.warning, LogLevel.error,\n                    LogLevel.critical, LogLevel.fatal, LogLevel.off])\n            {\n                stdThreadLocalLog.logLevel = tll;\n\n                foreach (cond; [true, false])\n                {\n                    assert(globalLogLevel == gll);\n                    assert(mem.logLevel == ll);\n\n                    bool gllVSll = LogLevel.trace >= globalLogLevel;\n                    bool llVSgll = ll >= globalLogLevel;\n                    bool lVSll = LogLevel.trace >= ll;\n                    bool gllOff = globalLogLevel != LogLevel.off;\n                    bool llOff = mem.logLevel != LogLevel.off;\n                    bool tllOff = stdThreadLocalLog.logLevel != LogLevel.off;\n                    bool tllVSll = tll >= ll;\n                    bool tllVSgll = tll >= gll;\n                    bool lVSgll = LogLevel.trace >= tll;\n\n                    bool test = llVSgll && gllVSll && lVSll && gllOff && llOff && cond;\n                    bool testG = gllOff && llOff && tllOff && lVSgll && tllVSll && tllVSgll && cond;\n\n                    mem.line = -1;\n                    /*\n                    writefln(\"gll(%3u) ll(%3u) cond(%b) test(%b)\",\n                        gll, ll, cond, test);\n                    writefln(\"%b %b %b %b %b %b test2(%b)\", llVSgll, gllVSll, lVSll,\n                        gllOff, llOff, cond, test2);\n                    */\n\n                    mem.trace(__LINE__); int line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    trace(__LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.trace(cond, __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    trace(cond, __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.tracef(\"%d\", __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    tracef(\"%d\", __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.tracef(cond, \"%d\", __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    tracef(cond, \"%d\", __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    llVSgll = ll >= globalLogLevel;\n                    lVSll = LogLevel.info >= ll;\n                    lVSgll = LogLevel.info >= tll;\n                    test = llVSgll && gllVSll && lVSll && gllOff && llOff && cond;\n                    testG = gllOff && llOff && tllOff && tllVSll && tllVSgll &&\n                        lVSgll && cond;\n\n                    mem.info(__LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    info(__LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.info(cond, __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    info(cond, __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.infof(\"%d\", __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    infof(\"%d\", __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.infof(cond, \"%d\", __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    infof(cond, \"%d\", __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    llVSgll = ll >= globalLogLevel;\n                    lVSll = LogLevel.warning >= ll;\n                    lVSgll = LogLevel.warning >= tll;\n                    test = llVSgll && gllVSll && lVSll && gllOff && llOff && cond;\n                    testG = gllOff && llOff && tllOff && tllVSll && tllVSgll &&\n                        lVSgll && cond;\n\n                    mem.warning(__LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    warning(__LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.warning(cond, __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    warning(cond, __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.warningf(\"%d\", __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    warningf(\"%d\", __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.warningf(cond, \"%d\", __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    warningf(cond, \"%d\", __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    llVSgll = ll >= globalLogLevel;\n                    lVSll = LogLevel.critical >= ll;\n                    lVSgll = LogLevel.critical >= tll;\n                    test = llVSgll && gllVSll && lVSll && gllOff && llOff && cond;\n                    testG = gllOff && llOff && tllOff && tllVSll && tllVSgll &&\n                        lVSgll && cond;\n\n                    mem.critical(__LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    critical(__LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.critical(cond, __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    critical(cond, __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.criticalf(\"%d\", __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    criticalf(\"%d\", __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    mem.criticalf(cond, \"%d\", __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n\n                    criticalf(cond, \"%d\", __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n\n                    llVSgll = ll >= globalLogLevel;\n                    lVSll = LogLevel.fatal >= ll;\n                    lVSgll = LogLevel.fatal >= tll;\n                    test = llVSgll && gllVSll && lVSll && gllOff && llOff && cond;\n                    testG = gllOff && llOff && tllOff && tllVSll && tllVSgll &&\n                        lVSgll && cond;\n\n                    mem.fatal(__LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n                    assert(test ? fatalLog : true);\n                    fatalLog = false;\n\n                    fatal(__LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n                    assert(testG ? fatalLog : true);\n                    fatalLog = false;\n\n                    mem.fatal(cond, __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n                    assert(test ? fatalLog : true);\n                    fatalLog = false;\n\n                    fatal(cond, __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n                    assert(testG ? fatalLog : true);\n                    fatalLog = false;\n\n                    mem.fatalf(\"%d\", __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n                    assert(test ? fatalLog : true);\n                    fatalLog = false;\n\n                    fatalf(\"%d\", __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n                    assert(testG ? fatalLog : true);\n                    fatalLog = false;\n\n                    mem.fatalf(cond, \"%d\", __LINE__); line = __LINE__;\n                    assert(test ? mem.line == line : true); line = -1;\n                    assert(test ? fatalLog : true);\n                    fatalLog = false;\n\n                    fatalf(cond, \"%d\", __LINE__); line = __LINE__;\n                    assert(testG ? mem.line == line : true); line = -1;\n                    assert(testG ? fatalLog : true);\n                    fatalLog = false;\n                }\n            }\n        }\n    }\n}\n\n// Issue #5\n@safe unittest\n{\n    import std.string : indexOf;\n\n    auto oldunspecificLogger = sharedLog;\n\n    scope(exit)\n    {\n        sharedLog = oldunspecificLogger;\n        globalLogLevel = LogLevel.all;\n    }\n\n    auto tl = new TestLogger(LogLevel.info);\n    sharedLog = tl;\n\n    trace(\"trace\");\n    assert(tl.msg.indexOf(\"trace\") == -1);\n}\n\n// Issue #5\n@safe unittest\n{\n    import std.experimental.logger.multilogger : MultiLogger;\n    import std.string : indexOf;\n\n    stdThreadLocalLog.logLevel = LogLevel.all;\n\n    auto oldunspecificLogger = sharedLog;\n\n    scope(exit)\n    {\n        sharedLog = oldunspecificLogger;\n        globalLogLevel = LogLevel.all;\n    }\n\n    auto logger = new MultiLogger(LogLevel.error);\n\n    auto tl = new TestLogger(LogLevel.info);\n    logger.insertLogger(\"required\", tl);\n    sharedLog = logger;\n\n    trace(\"trace\");\n    assert(tl.msg.indexOf(\"trace\") == -1);\n    info(\"info\");\n    assert(tl.msg.indexOf(\"info\") == -1);\n    error(\"error\");\n    assert(tl.msg.indexOf(\"error\") == 0);\n}\n\n@system unittest\n{\n    import std.exception : assertThrown;\n    auto tl = new TestLogger();\n    assertThrown!Throwable(tl.fatal(\"fatal\"));\n}\n\n// log objects with non-safe toString\n@system unittest\n{\n    struct Test\n    {\n        string toString() const @system\n        {\n            return \"test\";\n        }\n    }\n\n    auto tl = new TestLogger();\n    tl.info(Test.init);\n    assert(tl.msg == \"test\");\n}\n\n// Workaround for atomics not allowed in @safe code\nprivate auto trustedLoad(T)(ref shared T value) @trusted\n{\n    import core.atomic : atomicLoad, MemoryOrder;\n    return atomicLoad!(MemoryOrder.acq)(value);\n}\n\n// ditto\nprivate void trustedStore(T)(ref shared T dst, ref T src) @trusted\n{\n    import core.atomic : atomicStore, MemoryOrder;\n    atomicStore!(MemoryOrder.rel)(dst, src);\n}\n\n// check that thread-local logging does not propagate\n// to shared logger\n@system unittest\n{\n    import core.atomic, core.thread, std.concurrency;\n\n    static shared logged_count = 0;\n\n    class TestLog : Logger\n    {\n        Tid tid;\n\n        this()\n        {\n            super (LogLevel.trace);\n            this.tid = thisTid;\n        }\n\n        override void writeLogMsg(ref LogEntry payload) @trusted\n        {\n            assert(thisTid == this.tid);\n            atomicOp!\"+=\"(logged_count, 1);\n        }\n    }\n\n    class IgnoredLog : Logger\n    {\n        this()\n        {\n            super (LogLevel.trace);\n        }\n\n        override void writeLogMsg(ref LogEntry payload) @trusted\n        {\n            assert(false);\n        }\n    }\n\n    auto oldSharedLog = sharedLog;\n    scope(exit)\n    {\n        sharedLog = oldSharedLog;\n    }\n\n    sharedLog = new IgnoredLog;\n    Thread[] spawned;\n\n    foreach (i; 0 .. 4)\n    {\n        spawned ~= new Thread({\n            stdThreadLocalLog = new TestLog;\n            trace(\"zzzzzzzzzz\");\n        });\n        spawned[$-1].start();\n    }\n\n    foreach (t; spawned)\n        t.join();\n\n    assert(atomicOp!\"==\"(logged_count, 4));\n}\n\n@safe unittest\n{\n    auto dl = cast(FileLogger) sharedLog;\n    assert(dl !is null);\n    assert(dl.logLevel == LogLevel.all);\n    assert(globalLogLevel == LogLevel.all);\n\n    auto tl = cast(StdForwardLogger) stdThreadLocalLog;\n    assert(tl !is null);\n    stdThreadLocalLog.logLevel = LogLevel.all;\n}\n\n// Issue 14940\n@safe unittest\n{\n    import std.typecons : Nullable;\n\n    Nullable!int a = 1;\n    auto l = new TestLogger();\n    l.infof(\"log: %s\", a);\n    assert(l.msg == \"log: 1\");\n}\n\n// Ensure @system toString methods work\n@system unittest\n{\n    enum SystemToStringMsg = \"SystemToString\";\n    static struct SystemToString\n    {\n        string toString() @system\n        {\n            return SystemToStringMsg;\n        }\n    }\n\n    auto tl = new TestLogger();\n\n    SystemToString sts;\n    tl.logf(\"%s\", sts);\n    assert(tl.msg == SystemToStringMsg);\n}\n\n// Issue 17328\n@safe unittest\n{\n    import std.format : format;\n\n    ubyte[] data = [0];\n    string s = format(\"%(%02x%)\", data); // format 00\n    assert(s == \"00\");\n\n    auto tl = new TestLogger();\n\n    tl.infof(\"%(%02x%)\", data);    // infof    000\n\n    size_t i;\n    string fs = tl.msg;\n    for (; i < s.length; ++i)\n    {\n        assert(s[s.length - 1 - i] == fs[fs.length - 1 - i], fs);\n    }\n    assert(fs.length == 2);\n}\n\n// Issue 15954\n@safe unittest\n{\n    import std.conv : to;\n    auto tl = new TestLogger();\n    tl.log(\"123456789\".to!wstring);\n    assert(tl.msg == \"123456789\");\n}\n\n// Issue 16256\n@safe unittest\n{\n    import std.conv : to;\n    auto tl = new TestLogger();\n    tl.log(\"123456789\"d);\n    assert(tl.msg == \"123456789\");\n}\n\n// Issue 15517\n@system unittest\n{\n    import std.file : exists, remove;\n    import std.stdio : File;\n    import std.string : indexOf;\n\n    string fn = \"logfile.log\";\n    if (exists(fn))\n    {\n        remove(fn);\n    }\n\n    auto oldShared = sharedLog;\n    scope(exit)\n    {\n        sharedLog = oldShared;\n        if (exists(fn))\n        {\n            remove(fn);\n        }\n    }\n\n    auto ts = [ \"Test log 1\", \"Test log 2\", \"Test log 3\"];\n\n    auto fl = new FileLogger(fn);\n    sharedLog = fl;\n    assert(exists(fn));\n\n    foreach (t; ts)\n    {\n        log(t);\n    }\n\n    auto f = File(fn);\n    auto l = f.byLine();\n    assert(!l.empty);\n    size_t idx;\n    foreach (it; l)\n    {\n        assert(it.indexOf(ts[idx]) != -1, it);\n        ++idx;\n    }\n\n    assert(exists(fn));\n    fl.file.close();\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/logger/filelogger.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/logger/filelogger.d)\n*/\nmodule std.experimental.logger.filelogger;\n\nimport std.experimental.logger.core;\nimport std.stdio;\n\nimport std.typecons : Flag;\n\n/** An option to create $(LREF FileLogger) directory if it is non-existent.\n*/\nalias CreateFolder = Flag!\"CreateFolder\";\n\n/** This `Logger` implementation writes log messages to the associated\nfile. The name of the file has to be passed on construction time. If the file\nis already present new log messages will be append at its end.\n*/\nclass FileLogger : Logger\n{\n    import std.concurrency : Tid;\n    import std.datetime.systime : SysTime;\n    import std.format : formattedWrite;\n\n    /** A constructor for the `FileLogger` Logger.\n\n    Params:\n      fn = The filename of the output file of the `FileLogger`. If that\n      file can not be opened for writting an exception will be thrown.\n      lv = The `LogLevel` for the `FileLogger`. By default the\n\n    Example:\n    -------------\n    auto l1 = new FileLogger(\"logFile\");\n    auto l2 = new FileLogger(\"logFile\", LogLevel.fatal);\n    auto l3 = new FileLogger(\"logFile\", LogLevel.fatal, CreateFolder.yes);\n    -------------\n    */\n    this(in string fn, const LogLevel lv = LogLevel.all) @safe\n    {\n         this(fn, lv, CreateFolder.yes);\n    }\n\n    /** A constructor for the `FileLogger` Logger that takes a reference to\n    a `File`.\n\n    The `File` passed must be open for all the log call to the\n    `FileLogger`. If the `File` gets closed, using the `FileLogger`\n    for logging will result in undefined behaviour.\n\n    Params:\n      fn = The file used for logging.\n      lv = The `LogLevel` for the `FileLogger`. By default the\n      `LogLevel` for `FileLogger` is `LogLevel.all`.\n      createFileNameFolder = if yes and fn contains a folder name, this\n      folder will be created.\n\n    Example:\n    -------------\n    auto file = File(\"logFile.log\", \"w\");\n    auto l1 = new FileLogger(file);\n    auto l2 = new FileLogger(file, LogLevel.fatal);\n    -------------\n    */\n    this(in string fn, const LogLevel lv, CreateFolder createFileNameFolder) @safe\n    {\n        import std.file : exists, mkdirRecurse;\n        import std.path : dirName;\n        import std.conv : text;\n\n        super(lv);\n        this.filename = fn;\n\n        if (createFileNameFolder)\n        {\n            auto d = dirName(this.filename);\n            mkdirRecurse(d);\n            assert(exists(d), text(\"The folder the FileLogger should have\",\n                                   \" created in '\", d,\"' could not be created.\"));\n        }\n\n        this.file_.open(this.filename, \"a\");\n    }\n\n    /** A constructor for the `FileLogger` Logger that takes a reference to\n    a `File`.\n\n    The `File` passed must be open for all the log call to the\n    `FileLogger`. If the `File` gets closed, using the `FileLogger`\n    for logging will result in undefined behaviour.\n\n    Params:\n      file = The file used for logging.\n      lv = The `LogLevel` for the `FileLogger`. By default the\n      `LogLevel` for `FileLogger` is `LogLevel.all`.\n\n    Example:\n    -------------\n    auto file = File(\"logFile.log\", \"w\");\n    auto l1 = new FileLogger(file);\n    auto l2 = new FileLogger(file, LogLevel.fatal);\n    -------------\n    */\n    this(File file, const LogLevel lv = LogLevel.all) @safe\n    {\n        super(lv);\n        this.file_ = file;\n    }\n\n    /** If the `FileLogger` is managing the `File` it logs to, this\n    method will return a reference to this File.\n    */\n    @property File file() @safe\n    {\n        return this.file_;\n    }\n\n    /* This method overrides the base class method in order to log to a file\n    without requiring heap allocated memory. Additionally, the `FileLogger`\n    local mutex is logged to serialize the log calls.\n    */\n    override protected void beginLogMsg(string file, int line, string funcName,\n        string prettyFuncName, string moduleName, LogLevel logLevel,\n        Tid threadId, SysTime timestamp, Logger logger)\n        @safe\n    {\n        import std.string : lastIndexOf;\n        ptrdiff_t fnIdx = file.lastIndexOf('/') + 1;\n        ptrdiff_t funIdx = funcName.lastIndexOf('.') + 1;\n\n        auto lt = this.file_.lockingTextWriter();\n        systimeToISOString(lt, timestamp);\n        formattedWrite(lt, \":%s:%s:%u \", file[fnIdx .. $],\n            funcName[funIdx .. $], line);\n    }\n\n    /* This methods overrides the base class method and writes the parts of\n    the log call directly to the file.\n    */\n    override protected void logMsgPart(scope const(char)[] msg)\n    {\n        formattedWrite(this.file_.lockingTextWriter(), \"%s\", msg);\n    }\n\n    /* This methods overrides the base class method and finalizes the active\n    log call. This requires flushing the `File` and releasing the\n    `FileLogger` local mutex.\n    */\n    override protected void finishLogMsg()\n    {\n        this.file_.lockingTextWriter().put(\"\\n\");\n        this.file_.flush();\n    }\n\n    /* This methods overrides the base class method and delegates the\n    `LogEntry` data to the actual implementation.\n    */\n    override protected void writeLogMsg(ref LogEntry payload)\n    {\n        this.beginLogMsg(payload.file, payload.line, payload.funcName,\n            payload.prettyFuncName, payload.moduleName, payload.logLevel,\n            payload.threadId, payload.timestamp, payload.logger);\n        this.logMsgPart(payload.msg);\n        this.finishLogMsg();\n    }\n\n    /** If the `FileLogger` was constructed with a filename, this method\n    returns this filename. Otherwise an empty `string` is returned.\n    */\n    string getFilename()\n    {\n        return this.filename;\n    }\n\n    /** The `File` log messages are written to. */\n    protected File file_;\n\n    /** The filename of the `File` log messages are written to. */\n    protected string filename;\n}\n\n@system unittest\n{\n    import std.array : empty;\n    import std.file : deleteme, remove;\n    import std.string : indexOf;\n\n    string filename = deleteme ~ __FUNCTION__ ~ \".tempLogFile\";\n    auto l = new FileLogger(filename);\n\n    scope(exit)\n    {\n        remove(filename);\n    }\n\n    string notWritten = \"this should not be written to file\";\n    string written = \"this should be written to file\";\n\n    l.logLevel = LogLevel.critical;\n    l.log(LogLevel.warning, notWritten);\n    l.log(LogLevel.critical, written);\n    destroy(l);\n\n    auto file = File(filename, \"r\");\n    string readLine = file.readln();\n    assert(readLine.indexOf(written) != -1, readLine);\n    readLine = file.readln();\n    assert(readLine.indexOf(notWritten) == -1, readLine);\n}\n\n@safe unittest\n{\n    import std.file : rmdirRecurse, exists, deleteme;\n    import std.path : dirName;\n\n    const string tmpFolder = dirName(deleteme);\n    const string filepath = tmpFolder ~ \"/bug15771/minas/oops/\";\n    const string filename = filepath ~ \"output.txt\";\n    assert(!exists(filepath));\n\n    auto f = new FileLogger(filename, LogLevel.all, CreateFolder.yes);\n    scope(exit) () @trusted { rmdirRecurse(tmpFolder ~ \"/bug15771\"); }();\n\n    f.log(\"Hello World!\");\n    assert(exists(filepath));\n    f.file.close();\n}\n\n@system unittest\n{\n    import std.array : empty;\n    import std.file : deleteme, remove;\n    import std.string : indexOf;\n\n    string filename = deleteme ~ __FUNCTION__ ~ \".tempLogFile\";\n    auto file = File(filename, \"w\");\n    auto l = new FileLogger(file);\n\n    scope(exit)\n    {\n        remove(filename);\n    }\n\n    string notWritten = \"this should not be written to file\";\n    string written = \"this should be written to file\";\n\n    l.logLevel = LogLevel.critical;\n    l.log(LogLevel.warning, notWritten);\n    l.log(LogLevel.critical, written);\n    file.close();\n\n    file = File(filename, \"r\");\n    string readLine = file.readln();\n    assert(readLine.indexOf(written) != -1, readLine);\n    readLine = file.readln();\n    assert(readLine.indexOf(notWritten) == -1, readLine);\n    file.close();\n}\n\n@safe unittest\n{\n    auto dl = cast(FileLogger) sharedLog;\n    assert(dl !is null);\n    assert(dl.logLevel == LogLevel.all);\n    assert(globalLogLevel == LogLevel.all);\n\n    auto tl = cast(StdForwardLogger) stdThreadLocalLog;\n    assert(tl !is null);\n    stdThreadLocalLog.logLevel = LogLevel.all;\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/logger/multilogger.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/logger/multilogger.d)\n*/\nmodule std.experimental.logger.multilogger;\n\nimport std.experimental.logger.core;\nimport std.experimental.logger.filelogger;\n\n/** This Element is stored inside the `MultiLogger` and associates a\n`Logger` to a `string`.\n*/\nstruct MultiLoggerEntry\n{\n    string name; /// The name if the `Logger`\n    Logger logger; /// The stored `Logger`\n}\n\n/** MultiLogger logs to multiple `Logger`. The `Logger`s are stored in an\n`Logger[]` in their order of insertion.\n\nEvery data logged to this `MultiLogger` will be distributed to all the $(D\nLogger)s inserted into it. This `MultiLogger` implementation can\nhold multiple `Logger`s with the same name. If the method `removeLogger`\nis used to remove a `Logger` only the first occurrence with that name will\nbe removed.\n*/\nclass MultiLogger : Logger\n{\n    /** A constructor for the `MultiLogger` Logger.\n\n    Params:\n      lv = The `LogLevel` for the `MultiLogger`. By default the\n      `LogLevel` for `MultiLogger` is `LogLevel.all`.\n\n    Example:\n    -------------\n    auto l1 = new MultiLogger(LogLevel.trace);\n    -------------\n    */\n    this(const LogLevel lv = LogLevel.all) @safe\n    {\n        super(lv);\n    }\n\n    /** This member holds all `Logger`s stored in the `MultiLogger`.\n\n    When inheriting from `MultiLogger` this member can be used to gain\n    access to the stored `Logger`.\n    */\n    protected MultiLoggerEntry[] logger;\n\n    /** This method inserts a new Logger into the `MultiLogger`.\n\n    Params:\n      name = The name of the `Logger` to insert.\n      newLogger = The `Logger` to insert.\n    */\n    void insertLogger(string name, Logger newLogger) @safe\n    {\n        this.logger ~= MultiLoggerEntry(name, newLogger);\n    }\n\n    /** This method removes a Logger from the `MultiLogger`.\n\n    Params:\n      toRemove = The name of the `Logger` to remove. If the `Logger`\n        is not found `null` will be returned. Only the first occurrence of\n        a `Logger` with the given name will be removed.\n\n    Returns: The removed `Logger`.\n    */\n    Logger removeLogger(in char[] toRemove) @safe\n    {\n        import std.algorithm.mutation : copy;\n        import std.range.primitives : back, popBack;\n        for (size_t i = 0; i < this.logger.length; ++i)\n        {\n            if (this.logger[i].name == toRemove)\n            {\n                Logger ret = this.logger[i].logger;\n                this.logger[i] = this.logger.back;\n                this.logger.popBack();\n\n                return ret;\n            }\n        }\n\n        return null;\n    }\n\n    /* The override to pass the payload to all children of the\n    `MultiLoggerBase`.\n    */\n    override protected void writeLogMsg(ref LogEntry payload) @safe\n    {\n        foreach (it; this.logger)\n        {\n            /* We don't perform any checks here to avoid race conditions.\n            Instead the child will check on its own if its log level matches\n            and assume LogLevel.all for the globalLogLevel (since we already\n            know the message passes this test).\n            */\n            it.logger.forwardMsg(payload);\n        }\n    }\n}\n\n@safe unittest\n{\n    import std.exception : assertThrown;\n    import std.experimental.logger.nulllogger;\n    auto a = new MultiLogger;\n    auto n0 = new NullLogger();\n    auto n1 = new NullLogger();\n    a.insertLogger(\"zero\", n0);\n    a.insertLogger(\"one\", n1);\n\n    auto n0_1 = a.removeLogger(\"zero\");\n    assert(n0_1 is n0);\n    auto n = a.removeLogger(\"zero\");\n    assert(n is null);\n\n    auto n1_1 = a.removeLogger(\"one\");\n    assert(n1_1 is n1);\n    n = a.removeLogger(\"one\");\n    assert(n is null);\n}\n\n@safe unittest\n{\n    auto a = new MultiLogger;\n    auto n0 = new TestLogger;\n    auto n1 = new TestLogger;\n    a.insertLogger(\"zero\", n0);\n    a.insertLogger(\"one\", n1);\n\n    a.log(\"Hello TestLogger\"); int line = __LINE__;\n    assert(n0.msg == \"Hello TestLogger\");\n    assert(n0.line == line);\n    assert(n1.msg == \"Hello TestLogger\");\n    assert(n1.line == line);\n}\n\n// Issue #16\n@system unittest\n{\n    import std.file : deleteme;\n    import std.stdio : File;\n    import std.string : indexOf;\n    string logName = deleteme ~ __FUNCTION__ ~ \".log\";\n    auto logFileOutput = File(logName, \"w\");\n    scope(exit)\n    {\n        import std.file : remove;\n        logFileOutput.close();\n        remove(logName);\n    }\n    auto traceLog = new FileLogger(logFileOutput, LogLevel.all);\n    auto infoLog  = new TestLogger(LogLevel.info);\n\n    auto root = new MultiLogger(LogLevel.all);\n    root.insertLogger(\"fileLogger\", traceLog);\n    root.insertLogger(\"stdoutLogger\", infoLog);\n\n    string tMsg = \"A trace message\";\n    root.trace(tMsg); int line1 = __LINE__;\n\n    assert(infoLog.line != line1);\n    assert(infoLog.msg != tMsg);\n\n    string iMsg = \"A info message\";\n    root.info(iMsg); int line2 = __LINE__;\n\n    assert(infoLog.line == line2);\n    assert(infoLog.msg == iMsg, infoLog.msg ~ \":\" ~ iMsg);\n\n    logFileOutput.close();\n    logFileOutput = File(logName, \"r\");\n    assert(logFileOutput.isOpen);\n    assert(!logFileOutput.eof);\n\n    auto line = logFileOutput.readln();\n    assert(line.indexOf(tMsg) != -1, line ~ \":\" ~ tMsg);\n    assert(!logFileOutput.eof);\n    line = logFileOutput.readln();\n    assert(line.indexOf(iMsg) != -1, line ~ \":\" ~ tMsg);\n}\n\n@safe unittest\n{\n    auto dl = cast(FileLogger) sharedLog;\n    assert(dl !is null);\n    assert(dl.logLevel == LogLevel.all);\n    assert(globalLogLevel == LogLevel.all);\n\n    auto tl = cast(StdForwardLogger) stdThreadLocalLog;\n    assert(tl !is null);\n    stdThreadLocalLog.logLevel = LogLevel.all;\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/logger/nulllogger.d",
    "content": "// Written in the D programming language.\n/**\nSource: $(PHOBOSSRC std/experimental/logger/nulllogger.d)\n*/\nmodule std.experimental.logger.nulllogger;\n\nimport std.experimental.logger.core;\n\n/** The `NullLogger` will not process any log messages.\n\nIn case of a log message with `LogLevel.fatal` nothing will happen.\n*/\nclass NullLogger : Logger\n{\n    /** The default constructor for the `NullLogger`.\n\n    Independent of the parameter this Logger will never log a message.\n\n    Params:\n      lv = The `LogLevel` for the `NullLogger`. By default the `LogLevel`\n      for `NullLogger` is `LogLevel.all`.\n    */\n    this(const LogLevel lv = LogLevel.all) @safe\n    {\n        super(lv);\n        this.fatalHandler = delegate() {};\n    }\n\n    override protected void writeLogMsg(ref LogEntry payload) @safe @nogc\n    {\n    }\n}\n\n///\n@safe unittest\n{\n    import std.experimental.logger.core : LogLevel;\n    auto nl1 = new NullLogger(LogLevel.all);\n    nl1.info(\"You will never read this.\");\n    nl1.fatal(\"You will never read this, either and it will not throw\");\n}\n"
  },
  {
    "path": "libphobos/src/std/experimental/logger/package.d",
    "content": "// Written in the D programming language.\n/**\nImplements logging facilities.\n\nCopyright: Copyright Robert \"burner\" Schadek 2013 --\nLicense: <a href=\"http://www.boost.org/LICENSE_1_0.txt\">Boost License 1.0</a>.\nAuthors: $(HTTP www.svs.informatik.uni-oldenburg.de/60865.html, Robert burner Schadek)\n\n$(H3 Basic Logging)\n\nMessage logging is a common approach to expose runtime information of a\nprogram. Logging should be easy, but also flexible and powerful, therefore\n`D` provides a standard interface for logging.\n\nThe easiest way to create a log message is to write:\n-------------\nimport std.experimental.logger;\n\nvoid main() {\n    log(\"Hello World\");\n}\n-------------\nThis will print a message to the `stderr` device. The message will contain\nthe filename, the line number, the name of the surrounding function, the time\nand the message.\n\nMore complex log call can go along the lines like:\n-------------\nlog(\"Logging to the sharedLog with its default LogLevel\");\nlogf(LogLevel.info, 5 < 6, \"%s to the sharedLog with its LogLevel.info\", \"Logging\");\ninfo(\"Logging to the sharedLog with its info LogLevel\");\nwarning(5 < 6, \"Logging to the sharedLog with its LogLevel.warning if 5 is less than 6\");\nerror(\"Logging to the sharedLog with its error LogLevel\");\nerrorf(\"Logging %s the sharedLog %s its error LogLevel\", \"to\", \"with\");\ncritical(\"Logging to the\",\" sharedLog with its error LogLevel\");\nfatal(\"Logging to the sharedLog with its fatal LogLevel\");\n\nauto fLogger = new FileLogger(\"NameOfTheLogFile\");\nfLogger.log(\"Logging to the fileLogger with its default LogLevel\");\nfLogger.info(\"Logging to the fileLogger with its default LogLevel\");\nfLogger.warning(5 < 6, \"Logging to the fileLogger with its LogLevel.warning if 5 is less than 6\");\nfLogger.warningf(5 < 6, \"Logging to the fileLogger with its LogLevel.warning if %s is %s than 6\", 5, \"less\");\nfLogger.critical(\"Logging to the fileLogger with its info LogLevel\");\nfLogger.log(LogLevel.trace, 5 < 6, \"Logging to the fileLogger\",\" with its default LogLevel if 5 is less than 6\");\nfLogger.fatal(\"Logging to the fileLogger with its warning LogLevel\");\n-------------\nAdditionally, this example shows how a new `FileLogger` is created.\nIndividual `Logger` and the global log functions share commonly named\nfunctions to log data.\n\nThe names of the functions are as follows:\n$(UL\n    $(LI `log`)\n    $(LI `trace`)\n    $(LI `info`)\n    $(LI `warning`)\n    $(LI `critical`)\n    $(LI `fatal`)\n)\nThe default `Logger` will by default log to `stderr` and has a default\n`LogLevel` of `LogLevel.all`. The default Logger can be accessed by\nusing the property called `sharedLog`. This property is a reference to the\ncurrent default `Logger`. This reference can be used to assign a new\ndefault `Logger`.\n-------------\nsharedLog = new FileLogger(\"New_Default_Log_File.log\");\n-------------\n\nAdditional `Logger` can be created by creating a new instance of the\nrequired `Logger`.\n\n$(H3 Logging Fundamentals)\n$(H4 LogLevel)\nThe `LogLevel` of a log call can be defined in two ways. The first is by\ncalling `log` and passing the `LogLevel` explicitly as the first argument.\nThe second way of setting the `LogLevel` of a\nlog call, is by calling either `trace`, `info`, `warning`,\n`critical`, or `fatal`. The log call will then have the respective\n`LogLevel`. If no `LogLevel` is defined the log call will use the\ncurrent `LogLevel` of the used `Logger`. If data is logged with\n`LogLevel` `fatal` by default an `Error` will be thrown.\nThis behaviour can be modified by using the member `fatalHandler` to\nassign a custom delegate to handle log call with `LogLevel` `fatal`.\n\n$(H4 Conditional Logging)\nConditional logging can be achieved be passing a `bool` as first\nargument to a log function. If conditional logging is used the condition must\nbe `true` in order to have the log message logged.\n\nIn order to combine an explicit `LogLevel` passing with conditional\nlogging, the `LogLevel` has to be passed as first argument followed by the\n`bool`.\n\n$(H4 Filtering Log Messages)\nMessages are logged if the `LogLevel` of the log message is greater than or\nequal to the `LogLevel` of the used `Logger` and additionally if the\n`LogLevel` of the log message is greater than or equal to the global `LogLevel`.\nIf a condition is passed into the log call, this condition must be true.\n\nThe global `LogLevel` is accessible by using `globalLogLevel`.\nTo assign a `LogLevel` of a `Logger` use the `logLevel` property of\nthe logger.\n\n$(H4 Printf Style Logging)\nIf `printf`-style logging is needed add a $(B f) to the logging call, such as\n$(D myLogger.infof(\"Hello %s\", \"world\");) or $(D fatalf(\"errno %d\", 1337)).\nThe additional $(B f) appended to the function name enables `printf`-style\nlogging for all combinations of explicit `LogLevel` and conditional\nlogging functions and methods.\n\n$(H4 Thread Local Redirection)\nCalls to the free standing log functions are not directly forwarded to the\nglobal `Logger` `sharedLog`. Actually, a thread local `Logger` of\ntype `StdForwardLogger` processes the log call and then, by default, forwards\nthe created `Logger.LogEntry` to the `sharedLog` `Logger`.\nThe thread local `Logger` is accessible by the `stdThreadLocalLog`\nproperty. This property allows to assign user defined `Logger`. The default\n`LogLevel` of the `stdThreadLocalLog` `Logger` is `LogLevel.all`\nand it will therefore forward all messages to the `sharedLog` `Logger`.\nThe `LogLevel` of the `stdThreadLocalLog` can be used to filter log\ncalls before they reach the `sharedLog` `Logger`.\n\n$(H3 User Defined Logger)\nTo customize the `Logger` behavior, create a new `class` that inherits from\nthe abstract `Logger` `class`, and implements the `writeLogMsg`\nmethod.\n-------------\nclass MyCustomLogger : Logger\n{\n    this(LogLevel lv) @safe\n    {\n        super(lv);\n    }\n\n    override void writeLogMsg(ref LogEntry payload)\n    {\n        // log message in my custom way\n    }\n}\n\nauto logger = new MyCustomLogger(LogLevel.info);\nlogger.log(\"Awesome log message with LogLevel.info\");\n-------------\n\nTo gain more precise control over the logging process, additionally to\noverriding the `writeLogMsg` method the methods `beginLogMsg`,\n`logMsgPart` and `finishLogMsg` can be overridden.\n\n$(H3 Compile Time Disabling of `Logger`)\nIn order to disable logging at compile time, pass `StdLoggerDisableLogging` as a\nversion argument to the `D` compiler when compiling your program code.\nThis will disable all logging functionality.\nSpecific `LogLevel` can be disabled at compile time as well.\nIn order to disable logging with the `trace` `LogLevel` pass\n`StdLoggerDisableTrace` as a version.\nThe following table shows which version statement disables which\n`LogLevel`.\n$(TABLE\n    $(TR $(TD `LogLevel.trace` ) $(TD StdLoggerDisableTrace))\n    $(TR $(TD `LogLevel.info` ) $(TD StdLoggerDisableInfo))\n    $(TR $(TD `LogLevel.warning` ) $(TD StdLoggerDisableWarning))\n    $(TR $(TD `LogLevel.error` ) $(TD StdLoggerDisableError))\n    $(TR $(TD `LogLevel.critical` ) $(TD StdLoggerDisableCritical))\n    $(TR $(TD `LogLevel.fatal` ) $(TD StdLoggerDisableFatal))\n)\nSuch a version statement will only disable logging in the associated compile\nunit.\n\n$(H3 Provided Logger)\nBy default four `Logger` implementations are given. The `FileLogger`\nlogs data to files. It can also be used to log to `stdout` and `stderr`\nas these devices are files as well. A `Logger` that logs to `stdout` can\ntherefore be created by $(D new FileLogger(stdout)).\nThe `MultiLogger` is basically an associative array of `string`s to\n`Logger`. It propagates log calls to its stored `Logger`. The\n`ArrayLogger` contains an array of `Logger` and also propagates log\ncalls to its stored `Logger`. The `NullLogger` does not do anything. It\nwill never log a message and will never throw on a log call with `LogLevel`\n`error`.\n\nSource: $(PHOBOSSRC std/experimental/logger/package.d)\n*/\nmodule std.experimental.logger;\n\npublic import std.experimental.logger.core;\npublic import std.experimental.logger.filelogger;\npublic import std.experimental.logger.multilogger;\npublic import std.experimental.logger.nulllogger;\n"
  },
  {
    "path": "libphobos/src/std/experimental/note.md",
    "content": "This is intended for experimental modules.\n"
  },
  {
    "path": "libphobos/src/std/experimental/typecons.d",
    "content": "// Written in the D programming language.\n\n/**\nThis module implements experimental additions/modifications to $(MREF std, typecons).\n\nUse this module to test out new functionality for $(REF wrap, std, typecons)\nwhich allows for a struct to be wrapped against an interface; the\nimplementation in $(MREF std, typecons) only allows for classes to use the wrap\nfunctionality.\n\nSource:    $(PHOBOSSRC std/experimental/typecons.d)\n\nCopyright: Copyright the respective authors, 2008-\nLicense:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   $(HTTP erdani.org, Andrei Alexandrescu),\n           $(HTTP bartoszmilewski.wordpress.com, Bartosz Milewski),\n           Don Clugston,\n           Shin Fujishiro,\n           Kenji Hara\n */\nmodule std.experimental.typecons;\n\nimport std.meta; // : AliasSeq, allSatisfy;\nimport std.traits;\n\nimport std.typecons : Tuple, tuple, Bind, DerivedFunctionType, GetOverloadedMethods;\n\nprivate\n{\n    pragma(mangle, \"_d_toObject\")\n    extern(C) pure nothrow Object typecons_d_toObject(void* p);\n}\n\n/*\n * Avoids opCast operator overloading.\n */\nprivate template dynamicCast(T)\nif (is(T == class) || is(T == interface))\n{\n    @trusted\n    T dynamicCast(S)(inout S source)\n    if (is(S == class) || is(S == interface))\n    {\n        static if (is(Unqual!S : Unqual!T))\n        {\n            import std.traits : QualifierOf;\n            alias Qual = QualifierOf!S; // SharedOf or MutableOf\n            alias TmpT = Qual!(Unqual!T);\n            inout(TmpT) tmp = source;   // bypass opCast by implicit conversion\n            return *cast(T*)(&tmp);     // + variable pointer cast + dereference\n        }\n        else\n        {\n            return cast(T) typecons_d_toObject(*cast(void**)(&source));\n        }\n    }\n}\n\n@system unittest\n{\n    class C { @disable void opCast(T)(); }\n    auto c = new C;\n    static assert(!__traits(compiles, cast(Object) c));\n    auto o = dynamicCast!Object(c);\n    assert(c is o);\n\n    interface I { @disable void opCast(T)(); Object instance(); }\n    interface J { @disable void opCast(T)(); Object instance(); }\n    class D : I, J { Object instance() { return this; } }\n    I i = new D();\n    static assert(!__traits(compiles, cast(J) i));\n    J j = dynamicCast!J(i);\n    assert(i.instance() is j.instance());\n}\n\n/*\n * Determines if the `Source` type satisfies all interface requirements of\n * `Targets`.\n */\nprivate template implementsInterface(Source, Targets...)\nif (Targets.length >= 1 && allSatisfy!(isMutable, Targets))\n{\n    import std.meta : staticMap;\n\n    // strict upcast\n    bool implementsInterface()()\n    if (Targets.length == 1 && is(Source : Targets[0]))\n    {\n        return true;\n    }\n    // structural upcast\n    template implementsInterface()\n    if (!allSatisfy!(Bind!(isImplicitlyConvertible, Source), Targets))\n    {\n        auto implementsInterface()\n        {\n            return hasRequiredMethods!();\n        }\n\n        // list of FuncInfo\n        alias TargetMembers = UniqMembers!(ConcatInterfaceMembers!Targets);\n        // list of function symbols\n        alias SourceMembers = GetOverloadedMethods!Source;\n\n        // Check whether all of SourceMembers satisfy covariance target in\n        // TargetMembers\n        template hasRequiredMethods(size_t i = 0)\n        {\n            static if (i >= TargetMembers.length)\n                enum hasRequiredMethods = true;\n            else\n            {\n                enum foundFunc = findCovariantFunction!(TargetMembers[i], Source, SourceMembers);\n                static if (foundFunc == -1)\n                    pragma(msg, \"Could not locate matching function for: \" ~ TargetMembers[i].stringof);\n                enum hasRequiredMethods =\n                    foundFunc != -1 &&\n                    hasRequiredMethods!(i + 1);\n            }\n        }\n    }\n}\n// ditto\nprivate template implementsInterface(Source, Targets...)\nif (Targets.length >= 1 && !allSatisfy!(isMutable, Targets))\n{\n    import std.meta : staticMap;\n\n    alias implementsInterface = .implementsInterface!(Source, staticMap!(Unqual, Targets));\n}\n\n@safe unittest\n{\n    interface Foo {\n        void foo();\n    }\n    interface Bar {\n        void bar();\n    }\n    interface FooBar : Foo, Bar {\n        void foobar();\n    }\n\n    struct A {\n        void foo() {}\n    }\n    struct B {\n        void bar() {}\n        void foobar() {}\n    }\n    class C {\n        void foo() {}\n        void bar() {}\n    }\n    struct D {\n        void foo() {}\n        void bar() {}\n        void foobar() {}\n    }\n    // Implements interface\n    static assert(implementsInterface!(A, Foo));\n    static assert(implementsInterface!(A, const(Foo)));\n    static assert(implementsInterface!(A, immutable(Foo)));\n    // Doesn't implement interface\n    static assert(!implementsInterface!(B, Foo));\n    static assert(implementsInterface!(B, Bar));\n    // Implements both interfaces\n    static assert(implementsInterface!(C, Foo));\n    static assert(implementsInterface!(C, Bar));\n    static assert(implementsInterface!(C, Foo, Bar));\n    static assert(implementsInterface!(C, Foo, const(Bar)));\n    static assert(!implementsInterface!(A, Foo, Bar));\n    static assert(!implementsInterface!(A, Foo, immutable(Bar)));\n    // Implements inherited\n    static assert(implementsInterface!(D, FooBar));\n    static assert(!implementsInterface!(B, FooBar));\n}\n\nprivate enum isInterface(ConceptType) = is(ConceptType == interface);\n\n///\ntemplate wrap(Targets...)\nif (Targets.length >= 1 && allSatisfy!(isInterface, Targets))\n{\n    import std.meta : ApplyLeft, staticMap;\n\n    version (StdDdoc)\n    {\n        /**\n         * Wrap src in an anonymous class implementing $(D_PARAM Targets).\n         *\n         * wrap creates an internal wrapper class which implements the\n         * interfaces in `Targets` using the methods of `src`, then returns a\n         * GC-allocated instance of it.\n         *\n         * $(D_PARAM Source) can be either a `class` or a `struct`, but it must\n         * $(I structurally conform) with all the $(D_PARAM Targets)\n         * interfaces; i.e. it must provide concrete methods with compatible\n         * signatures of those in $(D_PARAM Targets).\n         *\n         * If $(D_PARAM Source) is a `struct` then wrapping/unwrapping will\n         * create a copy; it is not possible to affect the original `struct`\n         * through the wrapper.\n         *\n         * The returned object additionally supports $(LREF unwrap).\n         *\n         * Note:\n         * If $(D_PARAM Targets) has only one entry and $(D_PARAM Source) is a\n         * class which explicitly implements it, wrap simply returns src\n         * upcasted to `Targets[0]`.\n         *\n         * Bugs:\n         * wrap does not support interfaces which take their own type as either\n         * a parameter type or return type in any of its methods.\n         *\n         * See_Also: $(LREF unwrap) for examples\n         */\n        auto wrap(Source)(inout Source src)\n            if (implementsInterface!(Source, Targets));\n    }\n\n    static if (!allSatisfy!(isMutable, Targets))\n        alias wrap = .wrap!(staticMap!(Unqual, Targets));\n    else\n    {\n        // strict upcast\n        auto wrap(Source)(inout Source src)\n        if (Targets.length == 1 && is(Source : Targets[0]))\n        {\n            alias T = Select!(is(Source == shared), shared Targets[0], Targets[0]);\n            return dynamicCast!(inout T)(src);\n        }\n\n        // structural upcast\n        template wrap(Source)\n        if (!allSatisfy!(ApplyLeft!(isImplicitlyConvertible, Source), Targets))\n        {\n            auto wrap(inout Source src)\n            {\n                static assert(implementsInterface!(Source, Targets),\n                              \"Source \"~Source.stringof~\n                              \" does not have structural conformance to \"~\n                              Targets.stringof);\n\n                alias T = Select!(is(Source == shared), shared Impl, Impl);\n                return new inout T(src);\n            }\n\n            // list of FuncInfo\n            alias TargetMembers = UniqMembers!(ConcatInterfaceMembers!(Targets));\n            // list of function symbols\n            alias SourceMembers = GetOverloadedMethods!Source;\n\n            static if (is(Source == class) || is(Source == interface))\n                alias StructuralType = Object;\n            else static if (is(Source == struct))\n                alias StructuralType = Source;\n\n            // Check whether all of SourceMembers satisfy covariance target in TargetMembers\n            // Internal wrapper class\n            final class Impl : Structural!StructuralType, Targets\n            {\n            private:\n                Source _wrap_source;\n\n                this(       inout Source s)        inout @safe pure nothrow { _wrap_source = s; }\n                this(shared inout Source s) shared inout @safe pure nothrow { _wrap_source = s; }\n\n                static if (is(Source == class) || is(Source == interface))\n                {\n                    // BUG: making private should work with NVI.\n                    protected inout(Object) _wrap_getSource() inout @safe\n                    {\n                        return dynamicCast!(inout Object)(_wrap_source);\n                    }\n                }\n                else\n                {\n                    // BUG: making private should work with NVI.\n                    protected inout(Source) _wrap_getSource() inout @safe\n                    {\n                        return _wrap_source;\n                    }\n                }\n\n                import std.conv : to;\n                import std.functional : forward;\n                template generateFun(size_t i)\n                {\n                    enum name = TargetMembers[i].name;\n                    enum fa = functionAttributes!(TargetMembers[i].type);\n                    static args(int num)()\n                    {\n                        string r;\n                        bool first = true;\n                        foreach (i; 0 .. num)\n                        {\n                            import std.conv : to;\n                            r ~= (first ? \"\" : \", \") ~ \" a\" ~ (i+1).to!string;\n                            first = false;\n                        }\n                        return r;\n                    }\n                    static if (fa & FunctionAttribute.property)\n                    {\n                        static if (Parameters!(TargetMembers[i].type).length == 0)\n                            enum fbody = \"_wrap_source.\"~name;\n                        else\n                            enum fbody = \"_wrap_source.\"~name~\" = a1\";\n                    }\n                    else\n                    {\n                            enum fbody = \"_wrap_source.\"~name~\"(\"~args!(Parameters!(TargetMembers[i].type).length)~\")\";\n                    }\n                    enum generateFun =\n                        \"override \"~wrapperSignature!(TargetMembers[i]) ~\n                        \"{ return \"~fbody~\"; }\";\n                }\n\n            public:\n                static foreach (i; 0 .. TargetMembers.length)\n                    mixin(generateFun!i);\n            }\n        }\n    }\n}\n\n// Build a signature that matches the provided function\n// Each argument will be provided a name in the form a#\nprivate template wrapperSignature(alias fun)\n{\n    enum name = fun.name;\n    enum fa = functionAttributes!(fun.type);\n    static @property stc()\n    {\n        string r;\n        if (fa & FunctionAttribute.property)    r ~= \"@property \";\n        if (fa & FunctionAttribute.ref_)        r ~= \"ref \";\n        if (fa & FunctionAttribute.pure_)       r ~= \"pure \";\n        if (fa & FunctionAttribute.nothrow_)    r ~= \"nothrow \";\n        if (fa & FunctionAttribute.trusted)     r ~= \"@trusted \";\n        if (fa & FunctionAttribute.safe)        r ~= \"@safe \";\n        return r;\n    }\n    static @property mod()\n    {\n        alias type = AliasSeq!(fun.type)[0];\n        string r;\n        static if (is(type == immutable))       r ~= \" immutable\";\n        else\n        {\n            static if (is(type == shared))      r ~= \" shared\";\n            static if (is(type == const))       r ~= \" const\";\n            else static if (is(type == inout))  r ~= \" inout\";\n            //else  --> mutable\n        }\n        return r;\n    }\n    alias param = Parameters!(fun.type);\n    static @property wrapperParameters()\n    {\n        string r;\n        bool first = true;\n        foreach (i, p; param)\n        {\n            import std.conv : to;\n            r ~= (first ? \"\" : \", \") ~ p.stringof ~ \" a\" ~ (i+1).to!string;\n            first = false;\n        }\n        return r;\n    }\n\n    enum wrapperSignature =\n        stc~ReturnType!(fun.type).stringof ~ \" \"\n        ~ name~\"(\"~wrapperParameters~\")\"~mod;\n}\n\n@safe unittest\n{\n    interface M\n    {\n        void f1();\n        void f2(string[] args, int count);\n        void f3(string[] args, int count) pure const;\n    }\n\n    alias TargetMembers = UniqMembers!(ConcatInterfaceMembers!M);\n    static assert(wrapperSignature!(TargetMembers[0]) == \"void f1()\"\n                  , wrapperSignature!(TargetMembers[0]));\n\n    static assert(wrapperSignature!(TargetMembers[1]) == \"void f2(string[] a1, int a2)\"\n                  , wrapperSignature!(TargetMembers[1]));\n\n    static assert(wrapperSignature!(TargetMembers[2]) == \"pure void f3(string[] a1, int a2) const\"\n                  , wrapperSignature!(TargetMembers[2]));\n}\n\n// Internal class to support dynamic cross-casting\nprivate interface Structural(T)\n{\n    inout(T) _wrap_getSource() inout @safe pure nothrow;\n}\n\nprivate string unwrapExceptionText(Source, Target)()\n{\n    return Target.stringof~ \" not wrapped into \"~ Source.stringof;\n}\n\nversion (StdDdoc)\n{\n    /**\n     * Extract object previously wrapped by $(LREF wrap).\n     *\n     * Params:\n     *     Target = type of wrapped object\n     *     src = wrapper object returned by $(LREF wrap)\n     *\n     * Returns: the wrapped object, or null if src is not a wrapper created\n     * by $(LREF wrap) and $(D_PARAM Target) is a class\n     *\n     * Throws: $(REF ConvException, std, conv) when attempting to extract a\n     * struct which is not the wrapped type\n     *\n     * See_also: $(LREF wrap)\n     */\n    public inout(Target) unwrap(Target, Source)(inout Source src);\n}\n\n///\n@system unittest\n{\n    interface Quack\n    {\n        int quack();\n        @property int height();\n    }\n    interface Flyer\n    {\n        @property int height();\n    }\n    class Duck : Quack\n    {\n        int quack() { return 1; }\n        @property int height() { return 10; }\n    }\n    class Human\n    {\n        int quack() { return 2; }\n        @property int height() { return 20; }\n    }\n    struct HumanStructure\n    {\n        int quack() { return 3; }\n        @property int height() { return 30; }\n    }\n\n    Duck d1 = new Duck();\n    Human h1 = new Human();\n    HumanStructure hs1;\n\n    interface Refreshable\n    {\n        int refresh();\n    }\n    // does not have structural conformance\n    static assert(!__traits(compiles, d1.wrap!Refreshable));\n    static assert(!__traits(compiles, h1.wrap!Refreshable));\n    static assert(!__traits(compiles, hs1.wrap!Refreshable));\n\n    // strict upcast\n    Quack qd = d1.wrap!Quack;\n    assert(qd is d1);\n    assert(qd.quack() == 1);    // calls Duck.quack\n    // strict downcast\n    Duck d2 = qd.unwrap!Duck;\n    assert(d2 is d1);\n\n    // structural upcast\n    Quack qh = h1.wrap!Quack;\n    Quack qhs = hs1.wrap!Quack;\n    assert(qh.quack() == 2);    // calls Human.quack\n    assert(qhs.quack() == 3);    // calls HumanStructure.quack\n    // structural downcast\n    Human h2 = qh.unwrap!Human;\n    HumanStructure hs2 = qhs.unwrap!HumanStructure;\n    assert(h2 is h1);\n    assert(hs2 is hs1);\n\n    // structural upcast (two steps)\n    Quack qx = h1.wrap!Quack;   // Human -> Quack\n    Quack qxs = hs1.wrap!Quack;   // HumanStructure -> Quack\n    Flyer fx = qx.wrap!Flyer;   // Quack -> Flyer\n    Flyer fxs = qxs.wrap!Flyer;   // Quack -> Flyer\n    assert(fx.height == 20);    // calls Human.height\n    assert(fxs.height == 30);    // calls HumanStructure.height\n    // strucural downcast (two steps)\n    Quack qy = fx.unwrap!Quack; // Flyer -> Quack\n    Quack qys = fxs.unwrap!Quack; // Flyer -> Quack\n    Human hy = qy.unwrap!Human; // Quack -> Human\n    HumanStructure hys = qys.unwrap!HumanStructure; // Quack -> HumanStructure\n    assert(hy is h1);\n    assert(hys is hs1);\n    // strucural downcast (one step)\n    Human hz = fx.unwrap!Human; // Flyer -> Human\n    HumanStructure hzs = fxs.unwrap!HumanStructure; // Flyer -> HumanStructure\n    assert(hz is h1);\n    assert(hzs is hs1);\n}\n\n///\n@system unittest\n{\n    import std.traits : functionAttributes, FunctionAttribute;\n    interface A { int run(); }\n    interface B { int stop(); @property int status(); }\n    class X\n    {\n        int run() { return 1; }\n        int stop() { return 2; }\n        @property int status() { return 3; }\n    }\n\n    auto x = new X();\n    auto ab = x.wrap!(A, B);\n    A a = ab;\n    B b = ab;\n    assert(a.run() == 1);\n    assert(b.stop() == 2);\n    assert(b.status == 3);\n    static assert(functionAttributes!(typeof(ab).status) & FunctionAttribute.property);\n}\n\ntemplate unwrap(Target)\n{\n    static if (!isMutable!Target)\n        alias unwrap = .unwrap!(Unqual!Target);\n    else\n    {\n        // strict downcast\n        auto unwrap(Source)(inout Source src)\n        if (is(Target : Source))\n        {\n            alias T = Select!(is(Source == shared), shared Target, Target);\n            return dynamicCast!(inout T)(src);\n        }\n\n        // structural downcast for struct target\n        auto unwrap(Source)(inout Source src)\n        if (is(Target == struct))\n        {\n            alias T = Select!(is(Source == shared), shared Target, Target);\n            auto upCastSource = dynamicCast!Object(src);   // remove qualifier\n            do\n            {\n                if (auto a = dynamicCast!(Structural!Object)(upCastSource))\n                {\n                    upCastSource = a._wrap_getSource();\n                }\n                else if (auto a = dynamicCast!(Structural!T)(upCastSource))\n                {\n                    return a._wrap_getSource();\n                }\n                else\n                {\n                    static if (hasMember!(Source, \"_wrap_getSource\"))\n                        return unwrap!Target(src._wrap_getSource());\n                    else\n                        break;\n                }\n            } while (upCastSource);\n            import std.conv : ConvException;\n            throw new ConvException(unwrapExceptionText!(Source,Target));\n        }\n        // structural downcast for class target\n        auto unwrap(Source)(inout Source src)\n        if (!is(Target : Source) && !is(Target == struct))\n        {\n            alias T = Select!(is(Source == shared), shared Target, Target);\n            Object upCastSource = dynamicCast!(Object)(src);   // remove qualifier\n            do\n            {\n                // Unwrap classes\n                if (auto a = dynamicCast!(Structural!Object)(upCastSource))\n                {\n                    if (auto d = dynamicCast!(inout T)(upCastSource = a._wrap_getSource()))\n                        return d;\n                }\n                // Unwrap a structure of type T\n                else if (auto a = dynamicCast!(Structural!T)(upCastSource))\n                {\n                    return a._wrap_getSource();\n                }\n                // Unwrap class that already inherited from interface\n                else if (auto d = dynamicCast!(inout T)(upCastSource))\n                {\n                    return d;\n                }\n                // Recurse to find the struct Target within a wrapped tree\n                else\n                {\n                    static if (hasMember!(Source, \"_wrap_getSource\"))\n                        return unwrap!Target(src._wrap_getSource());\n                    else\n                        break;\n                }\n            } while (upCastSource);\n            return null;\n        }\n    }\n}\n\n@system unittest\n{\n    // Validate const/immutable\n    class A\n    {\n        int draw()              { return 1; }\n        int draw(int v)         { return v; }\n\n        int draw() const        { return 2; }\n        int draw() shared       { return 3; }\n        int draw() shared const { return 4; }\n        int draw() immutable    { return 5; }\n    }\n    interface Drawable\n    {\n        int draw();\n        int draw() const;\n        int draw() shared;\n        int draw() shared const;\n        int draw() immutable;\n    }\n    interface Drawable2\n    {\n        int draw(int v);\n    }\n\n    auto ma = new A();\n    auto sa = new shared A();\n    auto ia = new immutable A();\n    {\n                     Drawable  md = ma.wrap!Drawable;\n               const Drawable  cd = ma.wrap!Drawable;\n              shared Drawable  sd = sa.wrap!Drawable;\n        shared const Drawable scd = sa.wrap!Drawable;\n           immutable Drawable  id = ia.wrap!Drawable;\n        assert( md.draw() == 1);\n        assert( cd.draw() == 2);\n        assert( sd.draw() == 3);\n        assert(scd.draw() == 4);\n        assert( id.draw() == 5);\n    }\n    {\n        Drawable2 d = ma.wrap!Drawable2;\n        static assert(!__traits(compiles, d.draw()));\n        assert(d.draw(10) == 10);\n    }\n}\n@system unittest\n{\n    // Bugzilla 10377\n    import std.algorithm, std.range;\n\n    interface MyInputRange(T)\n    {\n        @property T front();\n        void popFront();\n        @property bool empty();\n    }\n\n    //auto o = iota(0,10,1).inputRangeObject();\n    //pragma(msg, __traits(allMembers, typeof(o)));\n    auto r = iota(0,10,1).inputRangeObject().wrap!(MyInputRange!int)();\n    assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));\n}\n@system unittest\n{\n    // Bugzilla 10536\n    interface Interface\n    {\n        int foo();\n    }\n    class Pluggable\n    {\n        int foo() { return 1; }\n        @disable void opCast(T, this X)();  // !\n    }\n\n    Interface i = new Pluggable().wrap!Interface;\n    assert(i.foo() == 1);\n}\n@system unittest\n{\n    // Enhancement 10538\n    interface Interface\n    {\n        int foo();\n        int bar(int);\n    }\n    class Pluggable\n    {\n        int opDispatch(string name, A...)(A args) { return 100; }\n    }\n\n    Interface i = wrap!Interface(new Pluggable());\n    assert(i.foo() == 100);\n    assert(i.bar(10) == 100);\n}\n\n// Concat all Targets function members into one tuple\nprivate template ConcatInterfaceMembers(Targets...)\n{\n    static if (Targets.length == 0)\n        alias ConcatInterfaceMembers = AliasSeq!();\n    else static if (Targets.length == 1)\n        alias ConcatInterfaceMembers\n          = AliasSeq!(GetOverloadedMethods!(Targets[0]));\n    else\n        alias ConcatInterfaceMembers = AliasSeq!(\n                GetOverloadedMethods!(Targets[0]),\n                ConcatInterfaceMembers!(Targets[1..$]));\n}\n// Remove duplicated functions based on the identifier name and function type covariance\nprivate template UniqMembers(members...)\n{\n    template FuncInfo(string s, F)\n    {\n        enum name = s;\n        alias type = F;\n    }\n\n    static if (members.length == 0)\n        alias UniqMembers = AliasSeq!();\n    else\n    {\n        alias func = members[0];\n        enum  name = __traits(identifier, func);\n        alias type = FunctionTypeOf!func;\n        template check(size_t i, mem...)\n        {\n            static if (i >= mem.length)\n                enum ptrdiff_t check = -1;\n            else static if\n              (__traits(identifier, func) == __traits(identifier, mem[i]) &&\n              !is(DerivedFunctionType!(type, FunctionTypeOf!(mem[i])) == void))\n            {\n                enum ptrdiff_t check = i;\n            }\n            else\n                enum ptrdiff_t check = check!(i + 1, mem);\n        }\n        enum ptrdiff_t x = 1 + check!(0, members[1 .. $]);\n        static if (x >= 1)\n        {\n            alias typex = DerivedFunctionType!(type, FunctionTypeOf!(members[x]));\n            alias remain = UniqMembers!(members[1 .. x], members[x + 1 .. $]);\n\n            static if (remain.length >= 1 && remain[0].name == name &&\n                       !is(DerivedFunctionType!(typex, remain[0].type) == void))\n            {\n                alias F = DerivedFunctionType!(typex, remain[0].type);\n                alias UniqMembers = AliasSeq!(FuncInfo!(name, F), remain[1 .. $]);\n            }\n            else\n                alias UniqMembers = AliasSeq!(FuncInfo!(name, typex), remain);\n        }\n        else\n        {\n            alias UniqMembers = AliasSeq!(FuncInfo!(name, type), UniqMembers!(members[1 .. $]));\n        }\n    }\n}\n\n// find a function from Fs that has same identifier and covariant type with f\nprivate template findCovariantFunction(alias finfo, Source, Fs...)\n{\n    template check(size_t i = 0)\n    {\n        static if (i >= Fs.length)\n            enum ptrdiff_t check = -1;\n        else\n        {\n            enum ptrdiff_t check =\n                (finfo.name == __traits(identifier, Fs[i])) &&\n                isCovariantWith!(FunctionTypeOf!(Fs[i]), finfo.type)\n              ? i : check!(i + 1);\n        }\n    }\n    enum x = check!();\n    static if (x == -1 && is(typeof(Source.opDispatch)))\n    {\n        alias Params = Parameters!(finfo.type);\n        enum ptrdiff_t findCovariantFunction =\n            is(typeof((             Source).init.opDispatch!(finfo.name)(Params.init))) ||\n            is(typeof((       const Source).init.opDispatch!(finfo.name)(Params.init))) ||\n            is(typeof((   immutable Source).init.opDispatch!(finfo.name)(Params.init))) ||\n            is(typeof((      shared Source).init.opDispatch!(finfo.name)(Params.init))) ||\n            is(typeof((shared const Source).init.opDispatch!(finfo.name)(Params.init)))\n          ? ptrdiff_t.max : -1;\n    }\n    else\n        enum ptrdiff_t findCovariantFunction = x;\n}\n\n/**\nType constructor for final (aka head-const) variables.\n\nFinal variables cannot be directly mutated or rebound, but references\nreached through the variable are typed with their original mutability.\nIt is equivalent to `final` variables in D1 and Java, as well as\n`readonly` variables in C#.\n\nWhen `T` is a `const` or `immutable` type, `Final` aliases\nto `T`.\n*/\ntemplate Final(T)\n{\nstatic if (is(T == const) || is(T == immutable))\n    alias Final = T;\nelse\n{\n    struct Final\n    {\n        import std.typecons : Proxy;\n\n        private T final_value;\n        mixin Proxy!final_value;\n\n        /**\n         * Construction is forwarded to the underlying type.\n         */\n        this(T other)\n        {\n            this.final_value = other;\n        }\n\n        /// Ditto\n        this(Args...)(auto ref Args args)\n            if (__traits(compiles, T(args)))\n        {\n            static assert((!is(T == struct) && !is(T == union)) || !isNested!T,\n                \"Non-static nested type \" ~ fullyQualifiedName!T ~ \" must be \" ~\n                \"constructed explicitly at the call-site (e.g. auto s = \" ~\n                \"makeFinal(\" ~ T.stringof ~ \"(...));)\");\n            this.final_value = T(args);\n        }\n\n        // Attaching function attributes gives less noisy error messages\n        pure nothrow @safe @nogc\n        {\n            /++\n             + All operators, including member access, are forwarded to the\n             + underlying value of type `T` except for these mutating operators,\n             + which are disabled.\n             +/\n            void opAssign(Other)(Other other)\n            {\n                static assert(0, typeof(this).stringof ~\n                                 \" cannot be reassigned.\");\n            }\n\n            /// Ditto\n            void opOpAssign(string op, Other)(Other other)\n            {\n                static assert(0, typeof(this).stringof ~\n                                 \" cannot be reassigned.\");\n            }\n\n            /// Ditto\n            void opUnary(string op : \"--\")()\n            {\n                static assert(0, typeof(this).stringof ~\n                                 \" cannot be mutated.\");\n            }\n\n            /// Ditto\n            void opUnary(string op : \"++\")()\n            {\n                static assert(0, typeof(this).stringof ~\n                                 \" cannot be mutated.\");\n            }\n        }\n\n        /**\n         *\n         * `Final!T` implicitly converts to an rvalue of type `T` through\n         * `AliasThis`.\n         */\n        inout(T) final_get() inout\n        {\n            return final_value;\n        }\n\n        /// Ditto\n        alias final_get this;\n\n        /// Ditto\n        auto ref opUnary(string op)()\n            if (__traits(compiles, mixin(op ~ \"T.init\")))\n        {\n            return mixin(op ~ \"this.final_value\");\n        }\n    }\n}\n}\n\n/// Ditto\nFinal!T makeFinal(T)(T t)\n{\n    return Final!T(t);\n}\n\n/// `Final` can be used to create class references which cannot be rebound:\npure nothrow @safe unittest\n{\n    static class A\n    {\n        int i;\n\n        this(int i) pure nothrow @nogc @safe\n        {\n            this.i = i;\n        }\n    }\n\n    auto a = makeFinal(new A(42));\n    assert(a.i == 42);\n\n    //a = new A(24); // Reassignment is illegal,\n    a.i = 24; // But fields are still mutable.\n\n    assert(a.i == 24);\n}\n\n/// `Final` can also be used to create read-only data fields without using transitive immutability:\npure nothrow @safe unittest\n{\n    static class A\n    {\n        int i;\n\n        this(int i) pure nothrow @nogc @safe\n        {\n            this.i = i;\n        }\n    }\n\n    static class B\n    {\n        Final!A a;\n\n        this(A a) pure nothrow @nogc @safe\n        {\n            this.a = a; // Construction, thus allowed.\n        }\n    }\n\n    auto b = new B(new A(42));\n    assert(b.a.i == 42);\n\n    // b.a = new A(24); // Reassignment is illegal,\n    b.a.i = 24; // but `a` is still mutable.\n\n    assert(b.a.i == 24);\n}\n\npure nothrow @safe unittest\n{\n    static class A { int i; }\n    static assert(!is(Final!A == A));\n    static assert(is(Final!(const A) == const A));\n    static assert(is(Final!(immutable A) == immutable A));\n\n    Final!A a = new A;\n    static assert(!__traits(compiles, a = new A));\n\n    static void foo(ref A a) pure nothrow @safe @nogc {}\n    static assert(!__traits(compiles, foo(a)));\n\n    assert(a.i == 0);\n    a.i = 42;\n    assert(a.i == 42);\n\n    Final!int i = 42;\n    static assert(!__traits(compiles, i = 24));\n    static assert(!__traits(compiles, --i));\n    static assert(!__traits(compiles, ++i));\n    assert(i == 42);\n    int iCopy = i;\n    assert(iCopy == 42);\n    iCopy = -i; // non-mutating unary operators must work\n    assert(iCopy == -42);\n\n    static struct S\n    {\n        int i;\n\n        pure nothrow @safe @nogc:\n        this(int i){}\n        this(string s){}\n        this(int i, string s, float f){ this.i = i; }\n    }\n\n    Final!S sint = 42;\n    Final!S sstr = \"foo\";\n    static assert(!__traits(compiles, sint = sstr));\n\n    auto sboth = Final!S(42, \"foo\", 3.14);\n    assert(sboth.i == 42);\n\n    sboth.i = 24;\n    assert(sboth.i == 24);\n\n    struct NestedS\n    {\n        int i;\n        int get() pure nothrow @safe @nogc { return sboth.i + i; }\n    }\n\n    // Nested structs must be constructed at the call-site\n    static assert(!__traits(compiles, Final!NestedS(6)));\n    auto s = makeFinal(NestedS(6));\n    assert(s.i == 6);\n    assert(s.get == 30);\n\n    class NestedC\n    {\n        int i;\n\n        pure nothrow @safe @nogc:\n        this(int i) { this.i = i; }\n        int get() { return sboth.i + i; }\n    }\n\n    auto c = makeFinal(new NestedC(6));\n    assert(c.i == 6);\n    assert(c.get == 30);\n}\n\npure nothrow @safe unittest\n{\n    auto arr = makeFinal([1, 2, 3]);\n    static assert(!__traits(compiles, arr = null));\n    static assert(!__traits(compiles, arr ~= 4));\n    assert((arr ~ 4) == [1, 2, 3, 4]);\n}\n\n// issue 17270\npure nothrow @nogc @system unittest\n{\n    int i = 1;\n    Final!(int*) fp = &i;\n    assert(*fp == 1);\n    static assert(!__traits(compiles,\n        fp = &i // direct assignment\n    ));\n    static assert(is(typeof(*fp) == int));\n    *fp = 2; // indirect assignment\n    assert(*fp == 2);\n    int* p = fp;\n    assert(*p == 2);\n}\n\npure nothrow @system unittest\n{\n    Final!(int[]) arr;\n    // static assert(!__traits(compiles,\n        // arr.length = 10; // bug!\n    // ));\n    static assert(!__traits(compiles,\n        arr.ptr = null\n    ));\n    static assert(!__traits(compiles,\n        arr.ptr++\n    ));\n}\n"
  },
  {
    "path": "libphobos/src/std/file.d",
    "content": "// Written in the D programming language.\n\n/**\nUtilities for manipulating files and scanning directories. Functions\nin this module handle files as a unit, e.g., read or write one file\nat a time. For opening files and manipulating them via handles refer\nto module $(MREF std, stdio).\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD General) $(TD\n          $(LREF exists)\n          $(LREF isDir)\n          $(LREF isFile)\n          $(LREF isSymlink)\n          $(LREF rename)\n          $(LREF thisExePath)\n))\n$(TR $(TD Directories) $(TD\n          $(LREF chdir)\n          $(LREF dirEntries)\n          $(LREF getcwd)\n          $(LREF mkdir)\n          $(LREF mkdirRecurse)\n          $(LREF rmdir)\n          $(LREF rmdirRecurse)\n          $(LREF tempDir)\n))\n$(TR $(TD Files) $(TD\n          $(LREF append)\n          $(LREF copy)\n          $(LREF read)\n          $(LREF readText)\n          $(LREF remove)\n          $(LREF slurp)\n          $(LREF write)\n))\n$(TR $(TD Symlinks) $(TD\n          $(LREF symlink)\n          $(LREF readLink)\n))\n$(TR $(TD Attributes) $(TD\n          $(LREF attrIsDir)\n          $(LREF attrIsFile)\n          $(LREF attrIsSymlink)\n          $(LREF getAttributes)\n          $(LREF getLinkAttributes)\n          $(LREF getSize)\n          $(LREF setAttributes)\n))\n$(TR $(TD Timestamp) $(TD\n          $(LREF getTimes)\n          $(LREF getTimesWin)\n          $(LREF setTimes)\n          $(LREF timeLastModified)\n          $(LREF timeLastAccessed)\n          $(LREF timeStatusChanged)\n))\n$(TR $(TD Other) $(TD\n          $(LREF DirEntry)\n          $(LREF FileException)\n          $(LREF PreserveAttributes)\n          $(LREF SpanMode)\n))\n)\n\n\nCopyright: Copyright The D Language Foundation 2007 - 2011.\nSee_Also:  The $(HTTP ddili.org/ders/d.en/files.html, official tutorial) for an\nintroduction to working with files in D, module\n$(MREF std, stdio) for opening files and manipulating them via handles,\nand module $(MREF std, path) for manipulating path strings.\n\nLicense:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   $(HTTP digitalmars.com, Walter Bright),\n           $(HTTP erdani.org, Andrei Alexandrescu),\n           $(HTTP jmdavisprog.com, Jonathan M Davis)\nSource:    $(PHOBOSSRC std/file.d)\n */\nmodule std.file;\n\nimport core.stdc.errno, core.stdc.stdlib, core.stdc.string;\nimport core.time : abs, dur, hnsecs, seconds;\n\nimport std.datetime.date : DateTime;\nimport std.datetime.systime : Clock, SysTime, unixTimeToStdTime;\nimport std.internal.cstring;\nimport std.meta;\nimport std.range.primitives;\nimport std.traits;\nimport std.typecons;\n\nversion (Windows)\n{\n    import core.sys.windows.windows, std.windows.syserror;\n}\nelse version (Posix)\n{\n    import core.sys.posix.dirent, core.sys.posix.fcntl, core.sys.posix.sys.stat,\n        core.sys.posix.sys.time, core.sys.posix.unistd, core.sys.posix.utime;\n}\nelse\n    static assert(false, \"Module \" ~ .stringof ~ \" not implemented for this OS.\");\n\n// Character type used for operating system filesystem APIs\nversion (Windows)\n{\n    private alias FSChar = wchar;\n}\nelse version (Posix)\n{\n    private alias FSChar = char;\n}\nelse\n    static assert(0);\n\n// Purposefully not documented. Use at your own risk\n@property string deleteme() @safe\n{\n    import std.conv : to;\n    import std.path : buildPath;\n    import std.process : thisProcessID;\n\n    static _deleteme = \"deleteme.dmd.unittest.pid\";\n    static _first = true;\n\n    if (_first)\n    {\n        _deleteme = buildPath(tempDir(), _deleteme) ~ to!string(thisProcessID);\n        _first = false;\n    }\n\n    return _deleteme;\n}\n\nversion (unittest) private struct TestAliasedString\n{\n    string get() @safe @nogc pure nothrow { return _s; }\n    alias get this;\n    @disable this(this);\n    string _s;\n}\n\nversion (Android)\n{\n    package enum system_directory = \"/system/etc\";\n    package enum system_file      = \"/system/etc/hosts\";\n}\nelse version (Posix)\n{\n    package enum system_directory = \"/usr/include\";\n    package enum system_file      = \"/usr/include/assert.h\";\n}\n\n\n/++\n    Exception thrown for file I/O errors.\n +/\nclass FileException : Exception\n{\n    import std.conv : text, to;\n\n    /++\n        OS error code.\n     +/\n    immutable uint errno;\n\n    private this(scope const(char)[] name, scope const(char)[] msg, string file, size_t line, uint errno) @safe pure\n    {\n        if (msg.empty)\n            super(name.idup, file, line);\n        else\n            super(text(name, \": \", msg), file, line);\n\n        this.errno = errno;\n    }\n\n    /++\n        Constructor which takes an error message.\n\n        Params:\n            name = Name of file for which the error occurred.\n            msg  = Message describing the error.\n            file = The file where the error occurred.\n            line = The _line where the error occurred.\n     +/\n    this(scope const(char)[] name, scope const(char)[] msg, string file = __FILE__, size_t line = __LINE__) @safe pure\n    {\n        this(name, msg, file, line, 0);\n    }\n\n    /++\n        Constructor which takes the error number ($(LUCKY GetLastError)\n        in Windows, $(D_PARAM errno) in Posix).\n\n        Params:\n            name  = Name of file for which the error occurred.\n            errno = The error number.\n            file  = The file where the error occurred.\n                    Defaults to `__FILE__`.\n            line  = The _line where the error occurred.\n                    Defaults to `__LINE__`.\n     +/\n    version (Windows) this(scope const(char)[] name,\n                          uint errno = .GetLastError(),\n                          string file = __FILE__,\n                          size_t line = __LINE__) @safe\n    {\n        this(name, sysErrorString(errno), file, line, errno);\n    }\n    else version (Posix) this(scope const(char)[] name,\n                             uint errno = .errno,\n                             string file = __FILE__,\n                             size_t line = __LINE__) @trusted\n    {\n        import std.exception : errnoString;\n        this(name, errnoString(errno), file, line, errno);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    assertThrown!FileException(\"non.existing.file.\".readText);\n}\n\nprivate T cenforce(T)(T condition, lazy scope const(char)[] name, string file = __FILE__, size_t line = __LINE__)\n{\n    if (condition)\n        return condition;\n    version (Windows)\n    {\n        throw new FileException(name, .GetLastError(), file, line);\n    }\n    else version (Posix)\n    {\n        throw new FileException(name, .errno, file, line);\n    }\n}\n\nversion (Windows)\n@trusted\nprivate T cenforce(T)(T condition, scope const(char)[] name, scope const(FSChar)* namez,\n    string file = __FILE__, size_t line = __LINE__)\n{\n    if (condition)\n        return condition;\n    if (!name)\n    {\n        import core.stdc.wchar_ : wcslen;\n        import std.conv : to;\n\n        auto len = namez ? wcslen(namez) : 0;\n        name = to!string(namez[0 .. len]);\n    }\n    throw new FileException(name, .GetLastError(), file, line);\n}\n\nversion (Posix)\n@trusted\nprivate T cenforce(T)(T condition, scope const(char)[] name, scope const(FSChar)* namez,\n    string file = __FILE__, size_t line = __LINE__)\n{\n    if (condition)\n        return condition;\n    if (!name)\n    {\n        import core.stdc.string : strlen;\n\n        auto len = namez ? strlen(namez) : 0;\n        name = namez[0 .. len].idup;\n    }\n    throw new FileException(name, .errno, file, line);\n}\n\n@safe unittest\n{\n    // issue 17102\n    try\n    {\n        cenforce(false, null, null,\n                __FILE__, __LINE__);\n    }\n    catch (FileException) {}\n}\n\n/* **********************************\n * Basic File operations.\n */\n\n/********************************************\nRead entire contents of file `name` and returns it as an untyped\narray. If the file size is larger than `upTo`, only `upTo`\nbytes are _read.\n\nParams:\n    name = string or range of characters representing the file _name\n    upTo = if present, the maximum number of bytes to _read\n\nReturns: Untyped array of bytes _read.\n\nThrows: $(LREF FileException) on error.\n */\n\nvoid[] read(R)(R name, size_t upTo = size_t.max)\nif (isInputRange!R && isSomeChar!(ElementEncodingType!R) && !isInfinite!R &&\n    !isConvertibleToString!R)\n{\n    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n        return readImpl(name, name.tempCString!FSChar(), upTo);\n    else\n        return readImpl(null, name.tempCString!FSChar(), upTo);\n}\n\n///\n@safe unittest\n{\n    import std.utf : byChar;\n    scope(exit)\n    {\n        assert(exists(deleteme));\n        remove(deleteme);\n    }\n\n    std.file.write(deleteme, \"1234\"); // deleteme is the name of a temporary file\n    assert(read(deleteme, 2) == \"12\");\n    assert(read(deleteme.byChar) == \"1234\");\n    assert((cast(const(ubyte)[])read(deleteme)).length == 4);\n}\n\n/// ditto\nvoid[] read(R)(auto ref R name, size_t upTo = size_t.max)\nif (isConvertibleToString!R)\n{\n    return read!(StringTypeOf!R)(name, upTo);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, read(TestAliasedString(null))));\n}\n\nversion (Posix) private void[] readImpl(scope const(char)[] name, scope const(FSChar)* namez,\n                                        size_t upTo = size_t.max) @trusted\n{\n    import core.memory : GC;\n    import std.algorithm.comparison : min;\n    import std.array : uninitializedArray;\n    import std.conv : to;\n    import std.experimental.checkedint : checked;\n\n    // A few internal configuration parameters {\n    enum size_t\n        minInitialAlloc = 1024 * 4,\n        maxInitialAlloc = size_t.max / 2,\n        sizeIncrement = 1024 * 16,\n        maxSlackMemoryAllowed = 1024;\n    // }\n\n    immutable fd = core.sys.posix.fcntl.open(namez,\n            core.sys.posix.fcntl.O_RDONLY);\n    cenforce(fd != -1, name);\n    scope(exit) core.sys.posix.unistd.close(fd);\n\n    stat_t statbuf = void;\n    cenforce(fstat(fd, &statbuf) == 0, name, namez);\n\n    immutable initialAlloc = min(upTo, to!size_t(statbuf.st_size\n        ? min(statbuf.st_size + 1, maxInitialAlloc)\n        : minInitialAlloc));\n    void[] result = uninitializedArray!(ubyte[])(initialAlloc);\n    scope(failure) GC.free(result.ptr);\n\n    auto size = checked(size_t(0));\n\n    for (;;)\n    {\n        immutable actual = core.sys.posix.unistd.read(fd, result.ptr + size.get,\n                (min(result.length, upTo) - size).get);\n        cenforce(actual != -1, name, namez);\n        if (actual == 0) break;\n        size += actual;\n        if (size >= upTo) break;\n        if (size < result.length) continue;\n        immutable newAlloc = size + sizeIncrement;\n        result = GC.realloc(result.ptr, newAlloc.get, GC.BlkAttr.NO_SCAN)[0 .. newAlloc.get];\n    }\n\n    return result.length - size >= maxSlackMemoryAllowed\n        ? GC.realloc(result.ptr, size.get, GC.BlkAttr.NO_SCAN)[0 .. size.get]\n        : result[0 .. size.get];\n}\n\n\nversion (Windows) private void[] readImpl(scope const(char)[] name, scope const(FSChar)* namez,\n                                          size_t upTo = size_t.max) @safe\n{\n    import core.memory : GC;\n    import std.algorithm.comparison : min;\n    import std.array : uninitializedArray;\n    static trustedCreateFileW(scope const(wchar)* namez, DWORD dwDesiredAccess, DWORD dwShareMode,\n                              SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition,\n                              DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) @trusted\n    {\n        return CreateFileW(namez, dwDesiredAccess, dwShareMode,\n                           lpSecurityAttributes, dwCreationDisposition,\n                           dwFlagsAndAttributes, hTemplateFile);\n\n    }\n    static trustedCloseHandle(HANDLE hObject) @trusted\n    {\n        return CloseHandle(hObject);\n    }\n    static trustedGetFileSize(HANDLE hFile, out ulong fileSize) @trusted\n    {\n        DWORD sizeHigh;\n        DWORD sizeLow = GetFileSize(hFile, &sizeHigh);\n        const bool result = sizeLow != INVALID_FILE_SIZE;\n        if (result)\n            fileSize = makeUlong(sizeLow, sizeHigh);\n        return result;\n    }\n    static trustedReadFile(HANDLE hFile, void *lpBuffer, ulong nNumberOfBytesToRead) @trusted\n    {\n        // Read by chunks of size < 4GB (Windows API limit)\n        ulong totalNumRead = 0;\n        while (totalNumRead != nNumberOfBytesToRead)\n        {\n            const uint chunkSize = min(nNumberOfBytesToRead - totalNumRead, 0xffff_0000);\n            DWORD numRead = void;\n            const result = ReadFile(hFile, lpBuffer + totalNumRead, chunkSize, &numRead, null);\n            if (result == 0 || numRead != chunkSize)\n                return false;\n            totalNumRead += chunkSize;\n        }\n        return true;\n    }\n\n    alias defaults =\n        AliasSeq!(GENERIC_READ,\n            FILE_SHARE_READ | FILE_SHARE_WRITE, (SECURITY_ATTRIBUTES*).init,\n            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,\n            HANDLE.init);\n    auto h = trustedCreateFileW(namez, defaults);\n\n    cenforce(h != INVALID_HANDLE_VALUE, name, namez);\n    scope(exit) cenforce(trustedCloseHandle(h), name, namez);\n    ulong fileSize = void;\n    cenforce(trustedGetFileSize(h, fileSize), name, namez);\n    size_t size = min(upTo, fileSize);\n    auto buf = uninitializedArray!(ubyte[])(size);\n\n    scope(failure)\n    {\n        () @trusted { GC.free(buf.ptr); } ();\n    }\n\n    if (size)\n        cenforce(trustedReadFile(h, &buf[0], size), name, namez);\n    return buf[0 .. size];\n}\n\nversion (linux) @safe unittest\n{\n    // A file with \"zero\" length that doesn't have 0 length at all\n    auto s = std.file.readText(\"/proc/sys/kernel/osrelease\");\n    assert(s.length > 0);\n    //writefln(\"'%s'\", s);\n}\n\n@safe unittest\n{\n    scope(exit) if (exists(deleteme)) remove(deleteme);\n    import std.stdio;\n    auto f = File(deleteme, \"w\");\n    f.write(\"abcd\"); f.flush();\n    assert(read(deleteme) == \"abcd\");\n}\n\n/++\n    Reads and validates (using $(REF validate, std, utf)) a text file. S can be\n    an array of any character type. However, no width or endian conversions are\n    performed. So, if the width or endianness of the characters in the given\n    file differ from the width or endianness of the element type of S, then\n    validation will fail.\n\n    Params:\n        S = the string type of the file\n        name = string or range of characters representing the file _name\n\n    Returns: Array of characters read.\n\n    Throws: $(LREF FileException) if there is an error reading the file,\n            $(REF UTFException, std, utf) on UTF decoding error.\n+/\nS readText(S = string, R)(auto ref R name)\nif (isSomeString!S && (isInputRange!R && !isInfinite!R && isSomeChar!(ElementType!R) || is(StringTypeOf!R)))\n{\n    import std.algorithm.searching : startsWith;\n    import std.encoding : getBOM, BOM;\n    import std.exception : enforce;\n    import std.format : format;\n    import std.utf : UTFException, validate;\n\n    static if (is(StringTypeOf!R))\n        StringTypeOf!R filename = name;\n    else\n        auto filename = name;\n\n    static auto trustedCast(T)(void[] buf) @trusted { return cast(T) buf; }\n    auto data = trustedCast!(ubyte[])(read(filename));\n\n    immutable bomSeq = getBOM(data);\n    immutable bom = bomSeq.schema;\n\n    static if (is(Unqual!(ElementEncodingType!S) == char))\n    {\n        with(BOM) switch (bom)\n        {\n            case utf16be:\n            case utf16le: throw new UTFException(\"UTF-8 requested. BOM is for UTF-16\");\n            case utf32be:\n            case utf32le: throw new UTFException(\"UTF-8 requested. BOM is for UTF-32\");\n            default: break;\n        }\n    }\n    else static if (is(Unqual!(ElementEncodingType!S) == wchar))\n    {\n        with(BOM) switch (bom)\n        {\n            case utf8: throw new UTFException(\"UTF-16 requested. BOM is for UTF-8\");\n            case utf16be:\n            {\n                version (BigEndian)\n                    break;\n                else\n                    throw new UTFException(\"BOM is for UTF-16 LE on Big Endian machine\");\n            }\n            case utf16le:\n            {\n                version (BigEndian)\n                    throw new UTFException(\"BOM is for UTF-16 BE on Little Endian machine\");\n                else\n                    break;\n            }\n            case utf32be:\n            case utf32le: throw new UTFException(\"UTF-8 requested. BOM is for UTF-32\");\n            default: break;\n        }\n    }\n    else\n    {\n        with(BOM) switch (bom)\n        {\n            case utf8: throw new UTFException(\"UTF-16 requested. BOM is for UTF-8\");\n            case utf16be:\n            case utf16le: throw new UTFException(\"UTF-8 requested. BOM is for UTF-16\");\n            case utf32be:\n            {\n                version (BigEndian)\n                    break;\n                else\n                    throw new UTFException(\"BOM is for UTF-32 LE on Big Endian machine\");\n            }\n            case utf32le:\n            {\n                version (BigEndian)\n                    throw new UTFException(\"BOM is for UTF-32 BE on Little Endian machine\");\n                else\n                    break;\n            }\n            default: break;\n        }\n    }\n\n    if (data.length % ElementEncodingType!S.sizeof != 0)\n        throw new UTFException(format!\"The content of %s is not UTF-%s\"(filename, ElementEncodingType!S.sizeof * 8));\n\n    auto result = trustedCast!S(data);\n    validate(result);\n    return result;\n}\n\n/// Read file with UTF-8 text.\n@safe unittest\n{\n    write(deleteme, \"abc\"); // deleteme is the name of a temporary file\n    scope(exit) remove(deleteme);\n    string content = readText(deleteme);\n    assert(content == \"abc\");\n}\n\n// Read file with UTF-8 text but try to read it as UTF-16.\n@safe unittest\n{\n    import std.exception : assertThrown;\n    import std.utf : UTFException;\n\n    write(deleteme, \"abc\");\n    scope(exit) remove(deleteme);\n    // Throws because the file is not valid UTF-16.\n    assertThrown!UTFException(readText!wstring(deleteme));\n}\n\n// Read file with UTF-16 text.\n@safe unittest\n{\n    import std.algorithm.searching : skipOver;\n\n    write(deleteme, \"\\uFEFFabc\"w); // With BOM\n    scope(exit) remove(deleteme);\n    auto content = readText!wstring(deleteme);\n    assert(content == \"\\uFEFFabc\"w);\n    // Strips BOM if present.\n    content.skipOver('\\uFEFF');\n    assert(content == \"abc\"w);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, readText(TestAliasedString(null))));\n}\n\n@system unittest\n{\n    import std.array : appender;\n    import std.bitmanip : append, Endian;\n    import std.exception : assertThrown;\n    import std.path : buildPath;\n    import std.string : representation;\n    import std.utf : UTFException;\n\n    mkdir(deleteme);\n    scope(exit) rmdirRecurse(deleteme);\n\n    immutable none8 = buildPath(deleteme, \"none8\");\n    immutable none16 = buildPath(deleteme, \"none16\");\n    immutable utf8 = buildPath(deleteme, \"utf8\");\n    immutable utf16be = buildPath(deleteme, \"utf16be\");\n    immutable utf16le = buildPath(deleteme, \"utf16le\");\n    immutable utf32be = buildPath(deleteme, \"utf32be\");\n    immutable utf32le = buildPath(deleteme, \"utf32le\");\n    immutable utf7 = buildPath(deleteme, \"utf7\");\n\n    write(none8, \"京都市\");\n    write(none16, \"京都市\"w);\n    write(utf8, (cast(char[])[0xEF, 0xBB, 0xBF]) ~ \"京都市\");\n    {\n        auto str = \"\\uFEFF京都市\"w;\n        auto arr = appender!(ubyte[])();\n        foreach (c; str)\n            arr.append(c);\n        write(utf16be, arr.data);\n    }\n    {\n        auto str = \"\\uFEFF京都市\"w;\n        auto arr = appender!(ubyte[])();\n        foreach (c; str)\n            arr.append!(ushort, Endian.littleEndian)(c);\n        write(utf16le, arr.data);\n    }\n    {\n        auto str = \"\\U0000FEFF京都市\"d;\n        auto arr = appender!(ubyte[])();\n        foreach (c; str)\n            arr.append(c);\n        write(utf32be, arr.data);\n    }\n    {\n        auto str = \"\\U0000FEFF京都市\"d;\n        auto arr = appender!(ubyte[])();\n        foreach (c; str)\n            arr.append!(uint, Endian.littleEndian)(c);\n        write(utf32le, arr.data);\n    }\n    write(utf7, (cast(ubyte[])[0x2B, 0x2F, 0x76, 0x38, 0x2D]) ~ \"foobar\".representation);\n\n    assertThrown!UTFException(readText(none16));\n    assert(readText(utf8) == (cast(char[])[0xEF, 0xBB, 0xBF]) ~ \"京都市\");\n    assertThrown!UTFException(readText(utf16be));\n    assertThrown!UTFException(readText(utf16le));\n    assertThrown!UTFException(readText(utf32be));\n    assertThrown!UTFException(readText(utf32le));\n    assert(readText(utf7) == (cast(char[])[0x2B, 0x2F, 0x76, 0x38, 0x2D]) ~ \"foobar\");\n\n    assertThrown!UTFException(readText!wstring(none8));\n    assert(readText!wstring(none16) == \"京都市\"w);\n    assertThrown!UTFException(readText!wstring(utf8));\n    version (BigEndian)\n    {\n        assert(readText!wstring(utf16be) == \"\\uFEFF京都市\"w);\n        assertThrown!UTFException(readText!wstring(utf16le));\n    }\n    else\n    {\n        assertThrown!UTFException(readText!wstring(utf16be));\n        assert(readText!wstring(utf16le) == \"\\uFEFF京都市\"w);\n    }\n    assertThrown!UTFException(readText!wstring(utf32be));\n    assertThrown!UTFException(readText!wstring(utf32le));\n    assertThrown!UTFException(readText!wstring(utf7));\n\n    assertThrown!UTFException(readText!dstring(utf8));\n    assertThrown!UTFException(readText!dstring(utf16be));\n    assertThrown!UTFException(readText!dstring(utf16le));\n    version (BigEndian)\n    {\n       assert(readText!dstring(utf32be) == \"\\U0000FEFF京都市\"d);\n       assertThrown!UTFException(readText!dstring(utf32le));\n    }\n    else\n    {\n       assertThrown!UTFException(readText!dstring(utf32be));\n       assert(readText!dstring(utf32le) == \"\\U0000FEFF京都市\"d);\n    }\n    assertThrown!UTFException(readText!dstring(utf7));\n}\n\n/*********************************************\nWrite `buffer` to file `name`.\n\nCreates the file if it does not already exist.\n\nParams:\n    name = string or range of characters representing the file _name\n    buffer = data to be written to file\n\nThrows: $(LREF FileException) on error.\n\nSee_also: $(REF toFile, std,stdio)\n */\nvoid write(R)(R name, const void[] buffer)\nif ((isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isSomeString!R) &&\n    !isConvertibleToString!R)\n{\n    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n        writeImpl(name, name.tempCString!FSChar(), buffer, false);\n    else\n        writeImpl(null, name.tempCString!FSChar(), buffer, false);\n}\n\n///\n@system unittest\n{\n   scope(exit)\n   {\n       assert(exists(deleteme));\n       remove(deleteme);\n   }\n\n   int[] a = [ 0, 1, 1, 2, 3, 5, 8 ];\n   write(deleteme, a); // deleteme is the name of a temporary file\n   assert(cast(int[]) read(deleteme) == a);\n}\n\n/// ditto\nvoid write(R)(auto ref R name, const void[] buffer)\nif (isConvertibleToString!R)\n{\n    write!(StringTypeOf!R)(name, buffer);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, write(TestAliasedString(null), null)));\n}\n\n/*********************************************\nAppends `buffer` to file `name`.\n\nCreates the file if it does not already exist.\n\nParams:\n    name = string or range of characters representing the file _name\n    buffer = data to be appended to file\n\nThrows: $(LREF FileException) on error.\n */\nvoid append(R)(R name, const void[] buffer)\nif ((isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isSomeString!R) &&\n    !isConvertibleToString!R)\n{\n    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n        writeImpl(name, name.tempCString!FSChar(), buffer, true);\n    else\n        writeImpl(null, name.tempCString!FSChar(), buffer, true);\n}\n\n///\n@system unittest\n{\n   scope(exit)\n   {\n       assert(exists(deleteme));\n       remove(deleteme);\n   }\n\n   int[] a = [ 0, 1, 1, 2, 3, 5, 8 ];\n   write(deleteme, a); // deleteme is the name of a temporary file\n   int[] b = [ 13, 21 ];\n   append(deleteme, b);\n   assert(cast(int[]) read(deleteme) == a ~ b);\n}\n\n/// ditto\nvoid append(R)(auto ref R name, const void[] buffer)\nif (isConvertibleToString!R)\n{\n    append!(StringTypeOf!R)(name, buffer);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, append(TestAliasedString(\"foo\"), [0, 1, 2, 3])));\n}\n\n// Posix implementation helper for write and append\n\nversion (Posix) private void writeImpl(scope const(char)[] name, scope const(FSChar)* namez,\n        scope const(void)[] buffer, bool append) @trusted\n{\n    import std.conv : octal;\n\n    // append or write\n    auto mode = append ? O_CREAT | O_WRONLY | O_APPEND\n                       : O_CREAT | O_WRONLY | O_TRUNC;\n\n    immutable fd = core.sys.posix.fcntl.open(namez, mode, octal!666);\n    cenforce(fd != -1, name, namez);\n    {\n        scope(failure) core.sys.posix.unistd.close(fd);\n\n        immutable size = buffer.length;\n        size_t sum, cnt = void;\n        while (sum != size)\n        {\n            cnt = (size - sum < 2^^30) ? (size - sum) : 2^^30;\n            const numwritten = core.sys.posix.unistd.write(fd, buffer.ptr + sum, cnt);\n            if (numwritten != cnt)\n                break;\n            sum += numwritten;\n        }\n        cenforce(sum == size, name, namez);\n    }\n    cenforce(core.sys.posix.unistd.close(fd) == 0, name, namez);\n}\n\n// Windows implementation helper for write and append\n\nversion (Windows) private void writeImpl(scope const(char)[] name, scope const(FSChar)* namez,\n        scope const(void)[] buffer, bool append) @trusted\n{\n    HANDLE h;\n    if (append)\n    {\n        alias defaults =\n            AliasSeq!(GENERIC_WRITE, 0, null, OPEN_ALWAYS,\n                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,\n                HANDLE.init);\n\n        h = CreateFileW(namez, defaults);\n        cenforce(h != INVALID_HANDLE_VALUE, name, namez);\n        cenforce(SetFilePointer(h, 0, null, FILE_END) != INVALID_SET_FILE_POINTER,\n            name, namez);\n    }\n    else // write\n    {\n        alias defaults =\n            AliasSeq!(GENERIC_WRITE, 0, null, CREATE_ALWAYS,\n                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,\n                HANDLE.init);\n\n        h = CreateFileW(namez, defaults);\n        cenforce(h != INVALID_HANDLE_VALUE, name, namez);\n    }\n    immutable size = buffer.length;\n    size_t sum, cnt = void;\n    DWORD numwritten = void;\n    while (sum != size)\n    {\n        cnt = (size - sum < 2^^30) ? (size - sum) : 2^^30;\n        WriteFile(h, buffer.ptr + sum, cast(uint) cnt, &numwritten, null);\n        if (numwritten != cnt)\n            break;\n        sum += numwritten;\n    }\n    cenforce(sum == size && CloseHandle(h), name, namez);\n}\n\n/***************************************************\n * Rename file `from` _to `to`.\n * If the target file exists, it is overwritten.\n * Params:\n *    from = string or range of characters representing the existing file name\n *    to = string or range of characters representing the target file name\n * Throws: $(LREF FileException) on error.\n */\nvoid rename(RF, RT)(RF from, RT to)\nif ((isInputRange!RF && !isInfinite!RF && isSomeChar!(ElementEncodingType!RF) || isSomeString!RF)\n    && !isConvertibleToString!RF &&\n    (isInputRange!RT && !isInfinite!RT && isSomeChar!(ElementEncodingType!RT) || isSomeString!RT)\n    && !isConvertibleToString!RT)\n{\n    // Place outside of @trusted block\n    auto fromz = from.tempCString!FSChar();\n    auto toz = to.tempCString!FSChar();\n\n    static if (isNarrowString!RF && is(Unqual!(ElementEncodingType!RF) == char))\n        alias f = from;\n    else\n        enum string f = null;\n\n    static if (isNarrowString!RT && is(Unqual!(ElementEncodingType!RT) == char))\n        alias t = to;\n    else\n        enum string t = null;\n\n    renameImpl(f, t, fromz, toz);\n}\n\n/// ditto\nvoid rename(RF, RT)(auto ref RF from, auto ref RT to)\nif (isConvertibleToString!RF || isConvertibleToString!RT)\n{\n    import std.meta : staticMap;\n    alias Types = staticMap!(convertToString, RF, RT);\n    rename!Types(from, to);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, rename(TestAliasedString(null), TestAliasedString(null))));\n    static assert(__traits(compiles, rename(\"\", TestAliasedString(null))));\n    static assert(__traits(compiles, rename(TestAliasedString(null), \"\")));\n    import std.utf : byChar;\n    static assert(__traits(compiles, rename(TestAliasedString(null), \"\".byChar)));\n}\n\n///\n@safe unittest\n{\n    auto t1 = deleteme, t2 = deleteme~\"2\";\n    scope(exit) foreach (t; [t1, t2]) if (t.exists) t.remove();\n\n    t1.write(\"1\");\n    t1.rename(t2);\n    assert(t2.readText == \"1\");\n\n    t1.write(\"2\");\n    t1.rename(t2);\n    assert(t2.readText == \"2\");\n}\n\nprivate void renameImpl(scope const(char)[] f, scope const(char)[] t,\n                        scope const(FSChar)* fromz, scope const(FSChar)* toz) @trusted\n{\n    version (Windows)\n    {\n        import std.exception : enforce;\n\n        const result = MoveFileExW(fromz, toz, MOVEFILE_REPLACE_EXISTING);\n        if (!result)\n        {\n            import core.stdc.wchar_ : wcslen;\n            import std.conv : to, text;\n\n            if (!f)\n                f = to!(typeof(f))(fromz[0 .. wcslen(fromz)]);\n\n            if (!t)\n                t = to!(typeof(t))(toz[0 .. wcslen(toz)]);\n\n            enforce(false,\n                new FileException(\n                    text(\"Attempting to rename file \", f, \" to \", t)));\n        }\n    }\n    else version (Posix)\n    {\n        static import core.stdc.stdio;\n\n        cenforce(core.stdc.stdio.rename(fromz, toz) == 0, t, toz);\n    }\n}\n\n@safe unittest\n{\n    import std.utf : byWchar;\n\n    auto t1 = deleteme, t2 = deleteme~\"2\";\n    scope(exit) foreach (t; [t1, t2]) if (t.exists) t.remove();\n\n    write(t1, \"1\");\n    rename(t1, t2);\n    assert(readText(t2) == \"1\");\n\n    write(t1, \"2\");\n    rename(t1, t2.byWchar);\n    assert(readText(t2) == \"2\");\n}\n\n/***************************************************\nDelete file `name`.\n\nParams:\n    name = string or range of characters representing the file _name\n\nThrows: $(LREF FileException) on error.\n */\nvoid remove(R)(R name)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n        removeImpl(name, name.tempCString!FSChar());\n    else\n        removeImpl(null, name.tempCString!FSChar());\n}\n\n/// ditto\nvoid remove(R)(auto ref R name)\nif (isConvertibleToString!R)\n{\n    remove!(StringTypeOf!R)(name);\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    deleteme.write(\"Hello\");\n    assert(deleteme.readText == \"Hello\");\n\n    deleteme.remove;\n    assertThrown!FileException(deleteme.readText);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, remove(TestAliasedString(\"foo\"))));\n}\n\nprivate void removeImpl(scope const(char)[] name, scope const(FSChar)* namez) @trusted\n{\n    version (Windows)\n    {\n        cenforce(DeleteFileW(namez), name, namez);\n    }\n    else version (Posix)\n    {\n        static import core.stdc.stdio;\n\n        if (!name)\n        {\n            import core.stdc.string : strlen;\n            auto len = strlen(namez);\n            name = namez[0 .. len];\n        }\n        cenforce(core.stdc.stdio.remove(namez) == 0,\n            \"Failed to remove file \" ~ name);\n    }\n}\n\nversion (Windows) private WIN32_FILE_ATTRIBUTE_DATA getFileAttributesWin(R)(R name)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R))\n{\n    auto namez = name.tempCString!FSChar();\n\n    WIN32_FILE_ATTRIBUTE_DATA fad = void;\n\n    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n    {\n        static void getFA(scope const(char)[] name, scope const(FSChar)* namez,\n                          out WIN32_FILE_ATTRIBUTE_DATA fad) @trusted\n        {\n            import std.exception : enforce;\n            enforce(GetFileAttributesExW(namez, GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, &fad),\n                new FileException(name.idup));\n        }\n        getFA(name, namez, fad);\n    }\n    else\n    {\n        static void getFA(scope const(FSChar)* namez, out WIN32_FILE_ATTRIBUTE_DATA fad) @trusted\n        {\n            import core.stdc.wchar_ : wcslen;\n            import std.conv : to;\n            import std.exception : enforce;\n\n            enforce(GetFileAttributesExW(namez, GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, &fad),\n                new FileException(namez[0 .. wcslen(namez)].to!string));\n        }\n        getFA(namez, fad);\n    }\n    return fad;\n}\n\nversion (Windows) private ulong makeUlong(DWORD dwLow, DWORD dwHigh) @safe pure nothrow @nogc\n{\n    ULARGE_INTEGER li;\n    li.LowPart  = dwLow;\n    li.HighPart = dwHigh;\n    return li.QuadPart;\n}\n\n/**\nGet size of file `name` in bytes.\n\nParams:\n    name = string or range of characters representing the file _name\nReturns:\n    The size of file in bytes.\nThrows:\n    $(LREF FileException) on error (e.g., file not found).\n */\nulong getSize(R)(R name)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    version (Windows)\n    {\n        with (getFileAttributesWin(name))\n            return makeUlong(nFileSizeLow, nFileSizeHigh);\n    }\n    else version (Posix)\n    {\n        auto namez = name.tempCString();\n\n        static trustedStat(const(FSChar)* namez, out stat_t buf) @trusted\n        {\n            return stat(namez, &buf);\n        }\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias names = name;\n        else\n            string names = null;\n        stat_t statbuf = void;\n        cenforce(trustedStat(namez, statbuf) == 0, names, namez);\n        return statbuf.st_size;\n    }\n}\n\n/// ditto\nulong getSize(R)(auto ref R name)\nif (isConvertibleToString!R)\n{\n    return getSize!(StringTypeOf!R)(name);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, getSize(TestAliasedString(\"foo\"))));\n}\n\n///\n@safe unittest\n{\n    scope(exit) deleteme.remove;\n\n    // create a file of size 1\n    write(deleteme, \"a\");\n    assert(getSize(deleteme) == 1);\n\n    // create a file of size 3\n    write(deleteme, \"abc\");\n    assert(getSize(deleteme) == 3);\n}\n\n@safe unittest\n{\n    // create a file of size 1\n    write(deleteme, \"a\");\n    scope(exit) deleteme.exists && deleteme.remove;\n    assert(getSize(deleteme) == 1);\n    // create a file of size 3\n    write(deleteme, \"abc\");\n    import std.utf : byChar;\n    assert(getSize(deleteme.byChar) == 3);\n}\n\n// Reads a time field from a stat_t with full precision.\nversion (Posix)\nprivate SysTime statTimeToStdTime(char which)(ref const stat_t statbuf)\n{\n    auto unixTime = mixin(`statbuf.st_` ~ which ~ `time`);\n    long stdTime = unixTimeToStdTime(unixTime);\n\n    static if (is(typeof(mixin(`statbuf.st_` ~ which ~ `tim`))))\n        stdTime += mixin(`statbuf.st_` ~ which ~ `tim.tv_nsec`) / 100;\n    else\n    static if (is(typeof(mixin(`statbuf.st_` ~ which ~ `timensec`))))\n        stdTime += mixin(`statbuf.st_` ~ which ~ `timensec`) / 100;\n    else\n    static if (is(typeof(mixin(`statbuf.st_` ~ which ~ `time_nsec`))))\n        stdTime += mixin(`statbuf.st_` ~ which ~ `time_nsec`) / 100;\n    else\n    static if (is(typeof(mixin(`statbuf.__st_` ~ which ~ `timensec`))))\n        stdTime += mixin(`statbuf.__st_` ~ which ~ `timensec`) / 100;\n\n    return SysTime(stdTime);\n}\n\n/++\n    Get the access and modified times of file or folder `name`.\n\n    Params:\n        name             = File/Folder _name to get times for.\n        accessTime       = Time the file/folder was last accessed.\n        modificationTime = Time the file/folder was last modified.\n\n    Throws:\n        $(LREF FileException) on error.\n +/\nvoid getTimes(R)(R name,\n              out SysTime accessTime,\n              out SysTime modificationTime)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    version (Windows)\n    {\n        import std.datetime.systime : FILETIMEToSysTime;\n\n        with (getFileAttributesWin(name))\n        {\n            accessTime = FILETIMEToSysTime(&ftLastAccessTime);\n            modificationTime = FILETIMEToSysTime(&ftLastWriteTime);\n        }\n    }\n    else version (Posix)\n    {\n        auto namez = name.tempCString();\n\n        static auto trustedStat(const(FSChar)* namez, ref stat_t buf) @trusted\n        {\n            return stat(namez, &buf);\n        }\n        stat_t statbuf = void;\n\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias names = name;\n        else\n            string names = null;\n        cenforce(trustedStat(namez, statbuf) == 0, names, namez);\n\n        accessTime = statTimeToStdTime!'a'(statbuf);\n        modificationTime = statTimeToStdTime!'m'(statbuf);\n    }\n}\n\n/// ditto\nvoid getTimes(R)(auto ref R name,\n              out SysTime accessTime,\n              out SysTime modificationTime)\nif (isConvertibleToString!R)\n{\n    return getTimes!(StringTypeOf!R)(name, accessTime, modificationTime);\n}\n\n///\n@safe unittest\n{\n    import std.datetime : abs, SysTime;\n\n    scope(exit) deleteme.remove;\n    write(deleteme, \"a\");\n\n    SysTime accessTime, modificationTime;\n\n    getTimes(deleteme, accessTime, modificationTime);\n\n    import std.datetime : Clock, seconds;\n    auto currTime = Clock.currTime();\n    enum leeway = 5.seconds;\n\n    auto diffAccess = accessTime - currTime;\n    auto diffModification = modificationTime - currTime;\n    assert(abs(diffAccess) <= leeway);\n    assert(abs(diffModification) <= leeway);\n}\n\n@safe unittest\n{\n    SysTime atime, mtime;\n    static assert(__traits(compiles, getTimes(TestAliasedString(\"foo\"), atime, mtime)));\n}\n\n@system unittest\n{\n    import std.stdio : writefln;\n\n    auto currTime = Clock.currTime();\n\n    write(deleteme, \"a\");\n    scope(exit) assert(deleteme.exists), deleteme.remove;\n\n    SysTime accessTime1 = void;\n    SysTime modificationTime1 = void;\n\n    getTimes(deleteme, accessTime1, modificationTime1);\n\n    enum leeway = 5.seconds;\n\n    {\n        auto diffa = accessTime1 - currTime;\n        auto diffm = modificationTime1 - currTime;\n        scope(failure) writefln(\"[%s] [%s] [%s] [%s] [%s]\", accessTime1, modificationTime1, currTime, diffa, diffm);\n\n        assert(abs(diffa) <= leeway);\n        assert(abs(diffm) <= leeway);\n    }\n\n    version (fullFileTests)\n    {\n        import core.thread;\n        enum sleepTime = dur!\"seconds\"(2);\n        Thread.sleep(sleepTime);\n\n        currTime = Clock.currTime();\n        write(deleteme, \"b\");\n\n        SysTime accessTime2 = void;\n        SysTime modificationTime2 = void;\n\n        getTimes(deleteme, accessTime2, modificationTime2);\n\n        {\n            auto diffa = accessTime2 - currTime;\n            auto diffm = modificationTime2 - currTime;\n            scope(failure) writefln(\"[%s] [%s] [%s] [%s] [%s]\", accessTime2, modificationTime2, currTime, diffa, diffm);\n\n            //There is no guarantee that the access time will be updated.\n            assert(abs(diffa) <= leeway + sleepTime);\n            assert(abs(diffm) <= leeway);\n        }\n\n        assert(accessTime1 <= accessTime2);\n        assert(modificationTime1 <= modificationTime2);\n    }\n}\n\n\nversion (StdDdoc)\n{\n    /++\n     $(BLUE This function is Windows-Only.)\n\n     Get creation/access/modified times of file `name`.\n\n     This is the same as `getTimes` except that it also gives you the file\n     creation time - which isn't possible on Posix systems.\n\n     Params:\n     name                 = File _name to get times for.\n     fileCreationTime     = Time the file was created.\n     fileAccessTime       = Time the file was last accessed.\n     fileModificationTime = Time the file was last modified.\n\n     Throws:\n     $(LREF FileException) on error.\n     +/\n    void getTimesWin(R)(R name,\n                        out SysTime fileCreationTime,\n                        out SysTime fileAccessTime,\n                        out SysTime fileModificationTime)\n    if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n        !isConvertibleToString!R);\n}\nelse version (Windows)\n{\n    void getTimesWin(R)(R name,\n                        out SysTime fileCreationTime,\n                        out SysTime fileAccessTime,\n                        out SysTime fileModificationTime)\n    if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n        !isConvertibleToString!R)\n    {\n        import std.datetime.systime : FILETIMEToSysTime;\n\n        with (getFileAttributesWin(name))\n        {\n            fileCreationTime = FILETIMEToSysTime(&ftCreationTime);\n            fileAccessTime = FILETIMEToSysTime(&ftLastAccessTime);\n            fileModificationTime = FILETIMEToSysTime(&ftLastWriteTime);\n        }\n    }\n\n    void getTimesWin(R)(auto ref R name,\n                        out SysTime fileCreationTime,\n                        out SysTime fileAccessTime,\n                        out SysTime fileModificationTime)\n    if (isConvertibleToString!R)\n    {\n        getTimesWin!(StringTypeOf!R)(name, fileCreationTime, fileAccessTime, fileModificationTime);\n    }\n}\n\nversion (Windows) @system unittest\n{\n    import std.stdio : writefln;\n    auto currTime = Clock.currTime();\n\n    write(deleteme, \"a\");\n    scope(exit) { assert(exists(deleteme)); remove(deleteme); }\n\n    SysTime creationTime1 = void;\n    SysTime accessTime1 = void;\n    SysTime modificationTime1 = void;\n\n    getTimesWin(deleteme, creationTime1, accessTime1, modificationTime1);\n\n    enum leeway = dur!\"seconds\"(5);\n\n    {\n        auto diffc = creationTime1 - currTime;\n        auto diffa = accessTime1 - currTime;\n        auto diffm = modificationTime1 - currTime;\n        scope(failure)\n        {\n            writefln(\"[%s] [%s] [%s] [%s] [%s] [%s] [%s]\",\n                     creationTime1, accessTime1, modificationTime1, currTime, diffc, diffa, diffm);\n        }\n\n        // Deleting and recreating a file doesn't seem to always reset the \"file creation time\"\n        //assert(abs(diffc) <= leeway);\n        assert(abs(diffa) <= leeway);\n        assert(abs(diffm) <= leeway);\n    }\n\n    version (fullFileTests)\n    {\n        import core.thread;\n        Thread.sleep(dur!\"seconds\"(2));\n\n        currTime = Clock.currTime();\n        write(deleteme, \"b\");\n\n        SysTime creationTime2 = void;\n        SysTime accessTime2 = void;\n        SysTime modificationTime2 = void;\n\n        getTimesWin(deleteme, creationTime2, accessTime2, modificationTime2);\n\n        {\n            auto diffa = accessTime2 - currTime;\n            auto diffm = modificationTime2 - currTime;\n            scope(failure)\n            {\n                writefln(\"[%s] [%s] [%s] [%s] [%s]\",\n                         accessTime2, modificationTime2, currTime, diffa, diffm);\n            }\n\n            assert(abs(diffa) <= leeway);\n            assert(abs(diffm) <= leeway);\n        }\n\n        assert(creationTime1 == creationTime2);\n        assert(accessTime1 <= accessTime2);\n        assert(modificationTime1 <= modificationTime2);\n    }\n\n    {\n        SysTime ctime, atime, mtime;\n        static assert(__traits(compiles, getTimesWin(TestAliasedString(\"foo\"), ctime, atime, mtime)));\n    }\n}\n\n\n/++\n    Set access/modified times of file or folder `name`.\n\n    Params:\n        name             = File/Folder _name to get times for.\n        accessTime       = Time the file/folder was last accessed.\n        modificationTime = Time the file/folder was last modified.\n\n    Throws:\n        $(LREF FileException) on error.\n +/\nvoid setTimes(R)(R name,\n              SysTime accessTime,\n              SysTime modificationTime)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    version (Windows)\n    {\n        import std.datetime.systime : SysTimeToFILETIME;\n\n        auto namez = name.tempCString!FSChar();\n        static auto trustedCreateFileW(const(FSChar)* namez, DWORD dwDesiredAccess, DWORD dwShareMode,\n                                       SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition,\n                                       DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) @trusted\n        {\n            return CreateFileW(namez, dwDesiredAccess, dwShareMode,\n                               lpSecurityAttributes, dwCreationDisposition,\n                               dwFlagsAndAttributes, hTemplateFile);\n\n        }\n        static auto trustedCloseHandle(HANDLE hObject) @trusted\n        {\n            return CloseHandle(hObject);\n        }\n        static auto trustedSetFileTime(HANDLE hFile, in FILETIME *lpCreationTime,\n                                       in ref FILETIME lpLastAccessTime, in ref FILETIME lpLastWriteTime) @trusted\n        {\n            return SetFileTime(hFile, lpCreationTime, &lpLastAccessTime, &lpLastWriteTime);\n        }\n\n        const ta = SysTimeToFILETIME(accessTime);\n        const tm = SysTimeToFILETIME(modificationTime);\n        alias defaults =\n            AliasSeq!(GENERIC_WRITE,\n                      0,\n                      null,\n                      OPEN_EXISTING,\n                      FILE_ATTRIBUTE_NORMAL |\n                      FILE_ATTRIBUTE_DIRECTORY |\n                      FILE_FLAG_BACKUP_SEMANTICS,\n                      HANDLE.init);\n        auto h = trustedCreateFileW(namez, defaults);\n\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias names = name;\n        else\n            string names = null;\n        cenforce(h != INVALID_HANDLE_VALUE, names, namez);\n\n        scope(exit)\n            cenforce(trustedCloseHandle(h), names, namez);\n\n        cenforce(trustedSetFileTime(h, null, ta, tm), names, namez);\n    }\n    else version (Posix)\n    {\n        auto namez = name.tempCString!FSChar();\n        static if (is(typeof(&utimensat)))\n        {\n            static auto trustedUtimensat(int fd, const(FSChar)* namez, const ref timespec[2] times, int flags) @trusted\n            {\n                return utimensat(fd, namez, times, flags);\n            }\n            timespec[2] t = void;\n\n            t[0] = accessTime.toTimeSpec();\n            t[1] = modificationTime.toTimeSpec();\n\n            static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n                alias names = name;\n            else\n                string names = null;\n            cenforce(trustedUtimensat(AT_FDCWD, namez, t, 0) == 0, names, namez);\n        }\n        else\n        {\n            static auto trustedUtimes(const(FSChar)* namez, const ref timeval[2] times) @trusted\n            {\n                return utimes(namez, times);\n            }\n            timeval[2] t = void;\n\n            t[0] = accessTime.toTimeVal();\n            t[1] = modificationTime.toTimeVal();\n\n            static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n                alias names = name;\n            else\n                string names = null;\n            cenforce(trustedUtimes(namez, t) == 0, names, namez);\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    import std.datetime : DateTime, hnsecs, SysTime;\n\n    scope(exit) deleteme.remove;\n    write(deleteme, \"a\");\n\n    SysTime accessTime = SysTime(DateTime(2010, 10, 4, 0, 0, 30));\n    SysTime modificationTime = SysTime(DateTime(2018, 10, 4, 0, 0, 30));\n    setTimes(deleteme, accessTime, modificationTime);\n\n    SysTime accessTimeResolved, modificationTimeResolved;\n    getTimes(deleteme, accessTimeResolved, modificationTimeResolved);\n\n    assert(accessTime == accessTimeResolved);\n    assert(modificationTime == modificationTimeResolved);\n}\n\n/// ditto\nvoid setTimes(R)(auto ref R name,\n              SysTime accessTime,\n              SysTime modificationTime)\nif (isConvertibleToString!R)\n{\n    setTimes!(StringTypeOf!R)(name, accessTime, modificationTime);\n}\n\n@safe unittest\n{\n    if (false) // Test instatiation\n        setTimes(TestAliasedString(\"foo\"), SysTime.init, SysTime.init);\n}\n\n@system unittest\n{\n    import std.stdio : File;\n    string newdir = deleteme ~ r\".dir\";\n    string dir = newdir ~ r\"/a/b/c\";\n    string file = dir ~ \"/file\";\n\n    if (!exists(dir)) mkdirRecurse(dir);\n    { auto f = File(file, \"w\"); }\n\n    void testTimes(int hnsecValue)\n    {\n        foreach (path; [file, dir])  // test file and dir\n        {\n            SysTime atime = SysTime(DateTime(2010, 10, 4, 0, 0, 30), hnsecs(hnsecValue));\n            SysTime mtime = SysTime(DateTime(2011, 10, 4, 0, 0, 30), hnsecs(hnsecValue));\n            setTimes(path, atime, mtime);\n\n            SysTime atime_res;\n            SysTime mtime_res;\n            getTimes(path, atime_res, mtime_res);\n            assert(atime == atime_res);\n            assert(mtime == mtime_res);\n        }\n    }\n\n    testTimes(0);\n    version (linux)\n        testTimes(123_456_7);\n\n    rmdirRecurse(newdir);\n}\n\n/++\n    Returns the time that the given file was last modified.\n\n    Params:\n        name = the name of the file to check\n    Returns:\n        A $(REF SysTime,std,datetime,systime).\n    Throws:\n        $(LREF FileException) if the given file does not exist.\n+/\nSysTime timeLastModified(R)(R name)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    version (Windows)\n    {\n        SysTime dummy;\n        SysTime ftm;\n\n        getTimesWin(name, dummy, dummy, ftm);\n\n        return ftm;\n    }\n    else version (Posix)\n    {\n        auto namez = name.tempCString!FSChar();\n        static auto trustedStat(const(FSChar)* namez, ref stat_t buf) @trusted\n        {\n            return stat(namez, &buf);\n        }\n        stat_t statbuf = void;\n\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias names = name;\n        else\n            string names = null;\n        cenforce(trustedStat(namez, statbuf) == 0, names, namez);\n\n        return statTimeToStdTime!'m'(statbuf);\n    }\n}\n\n/// ditto\nSysTime timeLastModified(R)(auto ref R name)\nif (isConvertibleToString!R)\n{\n    return timeLastModified!(StringTypeOf!R)(name);\n}\n\n///\n@safe unittest\n{\n    import std.datetime : abs, DateTime, hnsecs, SysTime;\n    scope(exit) deleteme.remove;\n\n    import std.datetime : Clock, seconds;\n    auto currTime = Clock.currTime();\n    enum leeway = 5.seconds;\n    deleteme.write(\"bb\");\n    assert(abs(deleteme.timeLastModified - currTime) <= leeway);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, timeLastModified(TestAliasedString(\"foo\"))));\n}\n\n/++\n    Returns the time that the given file was last modified. If the\n    file does not exist, returns `returnIfMissing`.\n\n    A frequent usage pattern occurs in build automation tools such as\n    $(HTTP gnu.org/software/make, make) or $(HTTP\n    en.wikipedia.org/wiki/Apache_Ant, ant). To check whether file $(D\n    target) must be rebuilt from file `source` (i.e., `target` is\n    older than `source` or does not exist), use the comparison\n    below. The code throws a $(LREF FileException) if `source` does not\n    exist (as it should). On the other hand, the `SysTime.min` default\n    makes a non-existing `target` seem infinitely old so the test\n    correctly prompts building it.\n\n    Params:\n        name = The name of the file to get the modification time for.\n        returnIfMissing = The time to return if the given file does not exist.\n    Returns:\n        A $(REF SysTime,std,datetime,systime).\n\nExample:\n--------------------\nif (source.timeLastModified >= target.timeLastModified(SysTime.min))\n{\n    // must (re)build\n}\nelse\n{\n    // target is up-to-date\n}\n--------------------\n+/\nSysTime timeLastModified(R)(R name, SysTime returnIfMissing)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R))\n{\n    version (Windows)\n    {\n        if (!exists(name))\n            return returnIfMissing;\n\n        SysTime dummy;\n        SysTime ftm;\n\n        getTimesWin(name, dummy, dummy, ftm);\n\n        return ftm;\n    }\n    else version (Posix)\n    {\n        auto namez = name.tempCString!FSChar();\n        static auto trustedStat(const(FSChar)* namez, ref stat_t buf) @trusted\n        {\n            return stat(namez, &buf);\n        }\n        stat_t statbuf = void;\n\n        return trustedStat(namez, statbuf) != 0 ?\n               returnIfMissing :\n               statTimeToStdTime!'m'(statbuf);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.datetime : SysTime;\n\n    assert(\"file.does.not.exist\".timeLastModified(SysTime.min) == SysTime.min);\n\n    auto source = deleteme ~ \"source\";\n    auto target = deleteme ~ \"target\";\n    scope(exit) source.remove, target.remove;\n\n    source.write(\".\");\n    assert(target.timeLastModified(SysTime.min) < source.timeLastModified);\n    target.write(\".\");\n    assert(target.timeLastModified(SysTime.min) >= source.timeLastModified);\n}\n\nversion (StdDdoc)\n{\n    /++\n     $(BLUE This function is Posix-Only.)\n\n     Returns the time that the given file was last modified.\n     Params:\n        statbuf = stat_t retrieved from file.\n     +/\n    SysTime timeLastModified()(auto ref stat_t statbuf) pure nothrow {assert(false);}\n    /++\n     $(BLUE This function is Posix-Only.)\n\n     Returns the time that the given file was last accessed.\n     Params:\n        statbuf = stat_t retrieved from file.\n     +/\n    SysTime timeLastAccessed()(auto ref stat_t statbuf) pure nothrow {assert(false);}\n    /++\n     $(BLUE This function is Posix-Only.)\n\n     Returns the time that the given file was last changed.\n     Params:\n        statbuf = stat_t retrieved from file.\n     +/\n    SysTime timeStatusChanged()(auto ref stat_t statbuf) pure nothrow {assert(false);}\n}\nelse version (Posix)\n{\n    SysTime timeLastModified()(auto ref stat_t statbuf) pure nothrow\n    {\n        return statTimeToStdTime!'m'(statbuf);\n    }\n    SysTime timeLastAccessed()(auto ref stat_t statbuf) pure nothrow\n    {\n        return statTimeToStdTime!'a'(statbuf);\n    }\n    SysTime timeStatusChanged()(auto ref stat_t statbuf) pure nothrow\n    {\n        return statTimeToStdTime!'c'(statbuf);\n    }\n\n    @safe unittest\n    {\n        stat_t statbuf;\n        // check that both lvalues and rvalues work\n        timeLastAccessed(statbuf);\n        timeLastAccessed(stat_t.init);\n    }\n}\n\n@safe unittest\n{\n    //std.process.system(\"echo a > deleteme\") == 0 || assert(false);\n    if (exists(deleteme))\n        remove(deleteme);\n\n    write(deleteme, \"a\\n\");\n\n    scope(exit)\n    {\n        assert(exists(deleteme));\n        remove(deleteme);\n    }\n\n    // assert(lastModified(\"deleteme\") >\n    //         lastModified(\"this file does not exist\", SysTime.min));\n    //assert(lastModified(\"deleteme\") > lastModified(__FILE__));\n}\n\n\n// Tests sub-second precision of querying file times.\n// Should pass on most modern systems running on modern filesystems.\n// Exceptions:\n// - FreeBSD, where one would need to first set the\n//   vfs.timestamp_precision sysctl to a value greater than zero.\n// - OS X, where the native filesystem (HFS+) stores filesystem\n//   timestamps with 1-second precision.\nversion (FreeBSD) {} else\nversion (DragonFlyBSD) {} else\nversion (OSX) {} else\n@system unittest\n{\n    import core.thread;\n\n    if (exists(deleteme))\n        remove(deleteme);\n\n    SysTime lastTime;\n    foreach (n; 0 .. 3)\n    {\n        write(deleteme, \"a\");\n        auto time = timeLastModified(deleteme);\n        remove(deleteme);\n        assert(time != lastTime);\n        lastTime = time;\n        Thread.sleep(10.msecs);\n    }\n}\n\n\n/**\n * Determine whether the given file (or directory) _exists.\n * Params:\n *    name = string or range of characters representing the file _name\n * Returns:\n *    true if the file _name specified as input _exists\n */\nbool exists(R)(R name)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    return existsImpl(name.tempCString!FSChar());\n}\n\n/// ditto\nbool exists(R)(auto ref R name)\nif (isConvertibleToString!R)\n{\n    return exists!(StringTypeOf!R)(name);\n}\n\n///\n@safe unittest\n{\n    auto f = deleteme ~ \"does.not.exist\";\n    assert(!f.exists);\n\n    f.write(\"hello\");\n    assert(f.exists);\n\n    f.remove;\n    assert(!f.exists);\n}\n\nprivate bool existsImpl(const(FSChar)* namez) @trusted nothrow @nogc\n{\n    version (Windows)\n    {\n        // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/\n        // fileio/base/getfileattributes.asp\n        return GetFileAttributesW(namez) != 0xFFFFFFFF;\n    }\n    else version (Posix)\n    {\n        /*\n            The reason why we use stat (and not access) here is\n            the quirky behavior of access for SUID programs: if\n            we used access, a file may not appear to \"exist\",\n            despite that the program would be able to open it\n            just fine. The behavior in question is described as\n            follows in the access man page:\n\n            > The check is done using the calling process's real\n            > UID and GID, rather than the effective IDs as is\n            > done when actually attempting an operation (e.g.,\n            > open(2)) on the file. This allows set-user-ID\n            > programs to easily determine the invoking user's\n            > authority.\n\n            While various operating systems provide eaccess or\n            euidaccess functions, these are not part of POSIX -\n            so it's safer to use stat instead.\n        */\n\n        stat_t statbuf = void;\n        return lstat(namez, &statbuf) == 0;\n    }\n    else\n        static assert(0);\n}\n\n///\n@safe unittest\n{\n    assert(\".\".exists);\n    assert(!\"this file does not exist\".exists);\n    deleteme.write(\"a\\n\");\n    scope(exit) deleteme.remove;\n    assert(deleteme.exists);\n}\n\n@safe unittest // Bugzilla 16573\n{\n    enum S : string { foo = \"foo\" }\n    assert(__traits(compiles, S.foo.exists));\n}\n\n/++\n Returns the attributes of the given file.\n\n Note that the file attributes on Windows and Posix systems are\n completely different. On Windows, they're what is returned by\n $(HTTP msdn.microsoft.com/en-us/library/aa364944(v=vs.85).aspx,\n GetFileAttributes), whereas on Posix systems, they're the\n `st_mode` value which is part of the $(D stat struct) gotten by\n calling the $(HTTP en.wikipedia.org/wiki/Stat_%28Unix%29, `stat`)\n function.\n\n On Posix systems, if the given file is a symbolic link, then\n attributes are the attributes of the file pointed to by the symbolic\n link.\n\n Params:\n    name = The file to get the attributes of.\n Returns:\n    The attributes of the file as a `uint`.\n Throws: $(LREF FileException) on error.\n  +/\nuint getAttributes(R)(R name)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    version (Windows)\n    {\n        auto namez = name.tempCString!FSChar();\n        static auto trustedGetFileAttributesW(const(FSChar)* namez) @trusted\n        {\n            return GetFileAttributesW(namez);\n        }\n        immutable result = trustedGetFileAttributesW(namez);\n\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias names = name;\n        else\n            string names = null;\n        cenforce(result != INVALID_FILE_ATTRIBUTES, names, namez);\n\n        return result;\n    }\n    else version (Posix)\n    {\n        auto namez = name.tempCString!FSChar();\n        static auto trustedStat(const(FSChar)* namez, ref stat_t buf) @trusted\n        {\n            return stat(namez, &buf);\n        }\n        stat_t statbuf = void;\n\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias names = name;\n        else\n            string names = null;\n        cenforce(trustedStat(namez, statbuf) == 0, names, namez);\n\n        return statbuf.st_mode;\n    }\n}\n\n/// ditto\nuint getAttributes(R)(auto ref R name)\nif (isConvertibleToString!R)\n{\n    return getAttributes!(StringTypeOf!R)(name);\n}\n\n/// getAttributes with a file\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto f = deleteme ~ \"file\";\n    scope(exit) f.remove;\n\n    assert(!f.exists);\n    assertThrown!FileException(f.getAttributes);\n\n    f.write(\".\");\n    auto attributes = f.getAttributes;\n    assert(!attributes.attrIsDir);\n    assert(attributes.attrIsFile);\n}\n\n/// getAttributes with a directory\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto dir = deleteme ~ \"dir\";\n    scope(exit) dir.rmdir;\n\n    assert(!dir.exists);\n    assertThrown!FileException(dir.getAttributes);\n\n    dir.mkdir;\n    auto attributes = dir.getAttributes;\n    assert(attributes.attrIsDir);\n    assert(!attributes.attrIsFile);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, getAttributes(TestAliasedString(null))));\n}\n\n/++\n    If the given file is a symbolic link, then this returns the attributes of the\n    symbolic link itself rather than file that it points to. If the given file\n    is $(I not) a symbolic link, then this function returns the same result\n    as getAttributes.\n\n    On Windows, getLinkAttributes is identical to getAttributes. It exists on\n    Windows so that you don't have to special-case code for Windows when dealing\n    with symbolic links.\n\n    Params:\n        name = The file to get the symbolic link attributes of.\n\n    Returns:\n        the attributes\n\n    Throws:\n        $(LREF FileException) on error.\n +/\nuint getLinkAttributes(R)(R name)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    version (Windows)\n    {\n        return getAttributes(name);\n    }\n    else version (Posix)\n    {\n        auto namez = name.tempCString!FSChar();\n        static auto trustedLstat(const(FSChar)* namez, ref stat_t buf) @trusted\n        {\n            return lstat(namez, &buf);\n        }\n        stat_t lstatbuf = void;\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias names = name;\n        else\n            string names = null;\n        cenforce(trustedLstat(namez, lstatbuf) == 0, names, namez);\n        return lstatbuf.st_mode;\n    }\n}\n\n/// ditto\nuint getLinkAttributes(R)(auto ref R name)\nif (isConvertibleToString!R)\n{\n    return getLinkAttributes!(StringTypeOf!R)(name);\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto source = deleteme ~ \"source\";\n    auto target = deleteme ~ \"target\";\n\n    assert(!source.exists);\n    assertThrown!FileException(source.getLinkAttributes);\n\n    // symlinking isn't available on Windows\n    version (Posix)\n    {\n        scope(exit) source.remove, target.remove;\n\n        target.write(\"target\");\n        target.symlink(source);\n        assert(source.readText == \"target\");\n        assert(source.isSymlink);\n        assert(source.getLinkAttributes.attrIsSymlink);\n    }\n}\n\n/// if the file is no symlink, getLinkAttributes behaves like getAttributes\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto f = deleteme ~ \"file\";\n    scope(exit) f.remove;\n\n    assert(!f.exists);\n    assertThrown!FileException(f.getLinkAttributes);\n\n    f.write(\".\");\n    auto attributes = f.getLinkAttributes;\n    assert(!attributes.attrIsDir);\n    assert(attributes.attrIsFile);\n}\n\n/// if the file is no symlink, getLinkAttributes behaves like getAttributes\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto dir = deleteme ~ \"dir\";\n    scope(exit) dir.rmdir;\n\n    assert(!dir.exists);\n    assertThrown!FileException(dir.getLinkAttributes);\n\n    dir.mkdir;\n    auto attributes = dir.getLinkAttributes;\n    assert(attributes.attrIsDir);\n    assert(!attributes.attrIsFile);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, getLinkAttributes(TestAliasedString(null))));\n}\n\n/++\n    Set the _attributes of the given file.\n\n    Params:\n        name = the file _name\n        attributes = the _attributes to set the file to\n\n    Throws:\n        $(LREF FileException) if the given file does not exist.\n +/\nvoid setAttributes(R)(R name, uint attributes)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    version (Windows)\n    {\n        auto namez = name.tempCString!FSChar();\n        static auto trustedSetFileAttributesW(const(FSChar)* namez, uint dwFileAttributes) @trusted\n        {\n            return SetFileAttributesW(namez, dwFileAttributes);\n        }\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias names = name;\n        else\n            string names = null;\n        cenforce(trustedSetFileAttributesW(namez, attributes), names, namez);\n    }\n    else version (Posix)\n    {\n        auto namez = name.tempCString!FSChar();\n        static auto trustedChmod(const(FSChar)* namez, mode_t mode) @trusted\n        {\n            return chmod(namez, mode);\n        }\n        assert(attributes <= mode_t.max);\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias names = name;\n        else\n            string names = null;\n        cenforce(!trustedChmod(namez, cast(mode_t) attributes), names, namez);\n    }\n}\n\n/// ditto\nvoid setAttributes(R)(auto ref R name, uint attributes)\nif (isConvertibleToString!R)\n{\n    return setAttributes!(StringTypeOf!R)(name, attributes);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, setAttributes(TestAliasedString(null), 0)));\n}\n\n/// setAttributes with a file\n@safe unittest\n{\n    import std.exception : assertThrown;\n    import std.conv : octal;\n\n    auto f = deleteme ~ \"file\";\n    version (Posix)\n    {\n        scope(exit) f.remove;\n\n        assert(!f.exists);\n        assertThrown!FileException(f.setAttributes(octal!777));\n\n        f.write(\".\");\n        auto attributes = f.getAttributes;\n        assert(!attributes.attrIsDir);\n        assert(attributes.attrIsFile);\n\n        f.setAttributes(octal!777);\n        attributes = f.getAttributes;\n\n        assert((attributes & 1023) == octal!777);\n    }\n}\n\n/// setAttributes with a directory\n@safe unittest\n{\n    import std.exception : assertThrown;\n    import std.conv : octal;\n\n    auto dir = deleteme ~ \"dir\";\n    version (Posix)\n    {\n        scope(exit) dir.rmdir;\n\n        assert(!dir.exists);\n        assertThrown!FileException(dir.setAttributes(octal!777));\n\n        dir.mkdir;\n        auto attributes = dir.getAttributes;\n        assert(attributes.attrIsDir);\n        assert(!attributes.attrIsFile);\n\n        dir.setAttributes(octal!777);\n        attributes = dir.getAttributes;\n\n        assert((attributes & 1023) == octal!777);\n    }\n}\n\n/++\n    Returns whether the given file is a directory.\n\n    Params:\n        name = The path to the file.\n\n    Returns:\n        true if name specifies a directory\n\n    Throws:\n        $(LREF FileException) if the given file does not exist.\n  +/\n@property bool isDir(R)(R name)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    version (Windows)\n    {\n        return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) != 0;\n    }\n    else version (Posix)\n    {\n        return (getAttributes(name) & S_IFMT) == S_IFDIR;\n    }\n}\n\n/// ditto\n@property bool isDir(R)(auto ref R name)\nif (isConvertibleToString!R)\n{\n    return name.isDir!(StringTypeOf!R);\n}\n\n///\n\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto dir = deleteme ~ \"dir\";\n    auto f = deleteme ~ \"f\";\n    scope(exit) dir.rmdir, f.remove;\n\n    assert(!dir.exists);\n    assertThrown!FileException(dir.isDir);\n\n    dir.mkdir;\n    assert(dir.isDir);\n\n    f.write(\".\");\n    assert(!f.isDir);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, TestAliasedString(null).isDir));\n}\n\n@safe unittest\n{\n    version (Windows)\n    {\n        if (\"C:\\\\Program Files\\\\\".exists)\n            assert(\"C:\\\\Program Files\\\\\".isDir);\n\n        if (\"C:\\\\Windows\\\\system.ini\".exists)\n            assert(!\"C:\\\\Windows\\\\system.ini\".isDir);\n    }\n    else version (Posix)\n    {\n        if (system_directory.exists)\n            assert(system_directory.isDir);\n\n        if (system_file.exists)\n            assert(!system_file.isDir);\n    }\n}\n\n@system unittest\n{\n    version (Windows)\n        enum dir = \"C:\\\\Program Files\\\\\";\n    else version (Posix)\n        enum dir = system_directory;\n\n    if (dir.exists)\n    {\n        DirEntry de = DirEntry(dir);\n        assert(de.isDir);\n        assert(DirEntry(dir).isDir);\n    }\n}\n\n/++\n    Returns whether the given file _attributes are for a directory.\n\n    Params:\n        attributes = The file _attributes.\n\n    Returns:\n        true if attributes specifies a directory\n+/\nbool attrIsDir(uint attributes) @safe pure nothrow @nogc\n{\n    version (Windows)\n    {\n        return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;\n    }\n    else version (Posix)\n    {\n        return (attributes & S_IFMT) == S_IFDIR;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto dir = deleteme ~ \"dir\";\n    auto f = deleteme ~ \"f\";\n    scope(exit) dir.rmdir, f.remove;\n\n    assert(!dir.exists);\n    assertThrown!FileException(dir.getAttributes.attrIsDir);\n\n    dir.mkdir;\n    assert(dir.isDir);\n    assert(dir.getAttributes.attrIsDir);\n\n    f.write(\".\");\n    assert(!f.isDir);\n    assert(!f.getAttributes.attrIsDir);\n}\n\n@safe unittest\n{\n    version (Windows)\n    {\n        if (\"C:\\\\Program Files\\\\\".exists)\n        {\n            assert(attrIsDir(getAttributes(\"C:\\\\Program Files\\\\\")));\n            assert(attrIsDir(getLinkAttributes(\"C:\\\\Program Files\\\\\")));\n        }\n\n        if (\"C:\\\\Windows\\\\system.ini\".exists)\n        {\n            assert(!attrIsDir(getAttributes(\"C:\\\\Windows\\\\system.ini\")));\n            assert(!attrIsDir(getLinkAttributes(\"C:\\\\Windows\\\\system.ini\")));\n        }\n    }\n    else version (Posix)\n    {\n        if (system_directory.exists)\n        {\n            assert(attrIsDir(getAttributes(system_directory)));\n            assert(attrIsDir(getLinkAttributes(system_directory)));\n        }\n\n        if (system_file.exists)\n        {\n            assert(!attrIsDir(getAttributes(system_file)));\n            assert(!attrIsDir(getLinkAttributes(system_file)));\n        }\n    }\n}\n\n\n/++\n    Returns whether the given file (or directory) is a file.\n\n    On Windows, if a file is not a directory, then it's a file. So,\n    either `isFile` or `isDir` will return true for any given file.\n\n    On Posix systems, if `isFile` is `true`, that indicates that the file\n    is a regular file (e.g. not a block not device). So, on Posix systems, it's\n    possible for both `isFile` and `isDir` to be `false` for a\n    particular file (in which case, it's a special file). You can use\n    `getAttributes` to get the attributes to figure out what type of special\n    it is, or you can use `DirEntry` to get at its `statBuf`, which is the\n    result from `stat`. In either case, see the man page for `stat` for\n    more information.\n\n    Params:\n        name = The path to the file.\n\n    Returns:\n        true if name specifies a file\n\n    Throws:\n        $(LREF FileException) if the given file does not exist.\n+/\n@property bool isFile(R)(R name)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    version (Windows)\n        return !name.isDir;\n    else version (Posix)\n        return (getAttributes(name) & S_IFMT) == S_IFREG;\n}\n\n/// ditto\n@property bool isFile(R)(auto ref R name)\nif (isConvertibleToString!R)\n{\n    return isFile!(StringTypeOf!R)(name);\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto dir = deleteme ~ \"dir\";\n    auto f = deleteme ~ \"f\";\n    scope(exit) dir.rmdir, f.remove;\n\n    dir.mkdir;\n    assert(!dir.isFile);\n\n    assert(!f.exists);\n    assertThrown!FileException(f.isFile);\n\n    f.write(\".\");\n    assert(f.isFile);\n}\n\n@system unittest // bugzilla 15658\n{\n    DirEntry e = DirEntry(\".\");\n    static assert(is(typeof(isFile(e))));\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, TestAliasedString(null).isFile));\n}\n\n@safe unittest\n{\n    version (Windows)\n    {\n        if (\"C:\\\\Program Files\\\\\".exists)\n            assert(!\"C:\\\\Program Files\\\\\".isFile);\n\n        if (\"C:\\\\Windows\\\\system.ini\".exists)\n            assert(\"C:\\\\Windows\\\\system.ini\".isFile);\n    }\n    else version (Posix)\n    {\n        if (system_directory.exists)\n            assert(!system_directory.isFile);\n\n        if (system_file.exists)\n            assert(system_file.isFile);\n    }\n}\n\n\n/++\n    Returns whether the given file _attributes are for a file.\n\n    On Windows, if a file is not a directory, it's a file. So, either\n    `attrIsFile` or `attrIsDir` will return `true` for the\n    _attributes of any given file.\n\n    On Posix systems, if `attrIsFile` is `true`, that indicates that the\n    file is a regular file (e.g. not a block not device). So, on Posix systems,\n    it's possible for both `attrIsFile` and `attrIsDir` to be `false`\n    for a particular file (in which case, it's a special file). If a file is a\n    special file, you can use the _attributes to check what type of special file\n    it is (see the man page for `stat` for more information).\n\n    Params:\n        attributes = The file _attributes.\n\n    Returns:\n        true if the given file _attributes are for a file\n\nExample:\n--------------------\nassert(attrIsFile(getAttributes(\"/etc/fonts/fonts.conf\")));\nassert(attrIsFile(getLinkAttributes(\"/etc/fonts/fonts.conf\")));\n--------------------\n  +/\nbool attrIsFile(uint attributes) @safe pure nothrow @nogc\n{\n    version (Windows)\n    {\n        return (attributes & FILE_ATTRIBUTE_DIRECTORY) == 0;\n    }\n    else version (Posix)\n    {\n        return (attributes & S_IFMT) == S_IFREG;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto dir = deleteme ~ \"dir\";\n    auto f = deleteme ~ \"f\";\n    scope(exit) dir.rmdir, f.remove;\n\n    dir.mkdir;\n    assert(!dir.isFile);\n    assert(!dir.getAttributes.attrIsFile);\n\n    assert(!f.exists);\n    assertThrown!FileException(f.getAttributes.attrIsFile);\n\n    f.write(\".\");\n    assert(f.isFile);\n    assert(f.getAttributes.attrIsFile);\n}\n\n@safe unittest\n{\n    version (Windows)\n    {\n        if (\"C:\\\\Program Files\\\\\".exists)\n        {\n            assert(!attrIsFile(getAttributes(\"C:\\\\Program Files\\\\\")));\n            assert(!attrIsFile(getLinkAttributes(\"C:\\\\Program Files\\\\\")));\n        }\n\n        if (\"C:\\\\Windows\\\\system.ini\".exists)\n        {\n            assert(attrIsFile(getAttributes(\"C:\\\\Windows\\\\system.ini\")));\n            assert(attrIsFile(getLinkAttributes(\"C:\\\\Windows\\\\system.ini\")));\n        }\n    }\n    else version (Posix)\n    {\n        if (system_directory.exists)\n        {\n            assert(!attrIsFile(getAttributes(system_directory)));\n            assert(!attrIsFile(getLinkAttributes(system_directory)));\n        }\n\n        if (system_file.exists)\n        {\n            assert(attrIsFile(getAttributes(system_file)));\n            assert(attrIsFile(getLinkAttributes(system_file)));\n        }\n    }\n}\n\n\n/++\n    Returns whether the given file is a symbolic link.\n\n    On Windows, returns `true` when the file is either a symbolic link or a\n    junction point.\n\n    Params:\n        name = The path to the file.\n\n    Returns:\n        true if name is a symbolic link\n\n    Throws:\n        $(LREF FileException) if the given file does not exist.\n  +/\n@property bool isSymlink(R)(R name)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    version (Windows)\n        return (getAttributes(name) & FILE_ATTRIBUTE_REPARSE_POINT) != 0;\n    else version (Posix)\n        return (getLinkAttributes(name) & S_IFMT) == S_IFLNK;\n}\n\n/// ditto\n@property bool isSymlink(R)(auto ref R name)\nif (isConvertibleToString!R)\n{\n    return name.isSymlink!(StringTypeOf!R);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, TestAliasedString(null).isSymlink));\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto source = deleteme ~ \"source\";\n    auto target = deleteme ~ \"target\";\n\n    assert(!source.exists);\n    assertThrown!FileException(source.isSymlink);\n\n    // symlinking isn't available on Windows\n    version (Posix)\n    {\n        scope(exit) source.remove, target.remove;\n\n        target.write(\"target\");\n        target.symlink(source);\n        assert(source.readText == \"target\");\n        assert(source.isSymlink);\n        assert(source.getLinkAttributes.attrIsSymlink);\n    }\n}\n\n@system unittest\n{\n    version (Windows)\n    {\n        if (\"C:\\\\Program Files\\\\\".exists)\n            assert(!\"C:\\\\Program Files\\\\\".isSymlink);\n\n        if (\"C:\\\\Users\\\\\".exists && \"C:\\\\Documents and Settings\\\\\".exists)\n            assert(\"C:\\\\Documents and Settings\\\\\".isSymlink);\n\n        enum fakeSymFile = \"C:\\\\Windows\\\\system.ini\";\n        if (fakeSymFile.exists)\n        {\n            assert(!fakeSymFile.isSymlink);\n\n            assert(!fakeSymFile.isSymlink);\n            assert(!attrIsSymlink(getAttributes(fakeSymFile)));\n            assert(!attrIsSymlink(getLinkAttributes(fakeSymFile)));\n\n            assert(attrIsFile(getAttributes(fakeSymFile)));\n            assert(attrIsFile(getLinkAttributes(fakeSymFile)));\n            assert(!attrIsDir(getAttributes(fakeSymFile)));\n            assert(!attrIsDir(getLinkAttributes(fakeSymFile)));\n\n            assert(getAttributes(fakeSymFile) == getLinkAttributes(fakeSymFile));\n        }\n    }\n    else version (Posix)\n    {\n        if (system_directory.exists)\n        {\n            assert(!system_directory.isSymlink);\n\n            immutable symfile = deleteme ~ \"_slink\\0\";\n            scope(exit) if (symfile.exists) symfile.remove();\n\n            core.sys.posix.unistd.symlink(system_directory, symfile.ptr);\n\n            assert(symfile.isSymlink);\n            assert(!attrIsSymlink(getAttributes(symfile)));\n            assert(attrIsSymlink(getLinkAttributes(symfile)));\n\n            assert(attrIsDir(getAttributes(symfile)));\n            assert(!attrIsDir(getLinkAttributes(symfile)));\n\n            assert(!attrIsFile(getAttributes(symfile)));\n            assert(!attrIsFile(getLinkAttributes(symfile)));\n        }\n\n        if (system_file.exists)\n        {\n            assert(!system_file.isSymlink);\n\n            immutable symfile = deleteme ~ \"_slink\\0\";\n            scope(exit) if (symfile.exists) symfile.remove();\n\n            core.sys.posix.unistd.symlink(system_file, symfile.ptr);\n\n            assert(symfile.isSymlink);\n            assert(!attrIsSymlink(getAttributes(symfile)));\n            assert(attrIsSymlink(getLinkAttributes(symfile)));\n\n            assert(!attrIsDir(getAttributes(symfile)));\n            assert(!attrIsDir(getLinkAttributes(symfile)));\n\n            assert(attrIsFile(getAttributes(symfile)));\n            assert(!attrIsFile(getLinkAttributes(symfile)));\n        }\n    }\n\n    static assert(__traits(compiles, () @safe { return \"dummy\".isSymlink; }));\n}\n\n\n/++\n    Returns whether the given file attributes are for a symbolic link.\n\n    On Windows, return `true` when the file is either a symbolic link or a\n    junction point.\n\n    Params:\n        attributes = The file attributes.\n\n    Returns:\n        true if attributes are for a symbolic link\n\nExample:\n--------------------\ncore.sys.posix.unistd.symlink(\"/etc/fonts/fonts.conf\", \"/tmp/alink\");\n\nassert(!getAttributes(\"/tmp/alink\").isSymlink);\nassert(getLinkAttributes(\"/tmp/alink\").isSymlink);\n--------------------\n  +/\nbool attrIsSymlink(uint attributes) @safe pure nothrow @nogc\n{\n    version (Windows)\n        return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;\n    else version (Posix)\n        return (attributes & S_IFMT) == S_IFLNK;\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto source = deleteme ~ \"source\";\n    auto target = deleteme ~ \"target\";\n\n    assert(!source.exists);\n    assertThrown!FileException(source.getLinkAttributes.attrIsSymlink);\n\n    // symlinking isn't available on Windows\n    version (Posix)\n    {\n        scope(exit) source.remove, target.remove;\n\n        target.write(\"target\");\n        target.symlink(source);\n        assert(source.readText == \"target\");\n        assert(source.isSymlink);\n        assert(source.getLinkAttributes.attrIsSymlink);\n    }\n}\n\n/**\nChange directory to `pathname`. Equivalent to `cd` on\nWindows and Posix.\n\nParams:\n    pathname = the directory to step into\n\nThrows: $(LREF FileException) on error.\n */\nvoid chdir(R)(R pathname)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    // Place outside of @trusted block\n    auto pathz = pathname.tempCString!FSChar();\n\n    version (Windows)\n    {\n        static auto trustedChdir(const(FSChar)* pathz) @trusted\n        {\n            return SetCurrentDirectoryW(pathz);\n        }\n    }\n    else version (Posix)\n    {\n        static auto trustedChdir(const(FSChar)* pathz) @trusted\n        {\n            return core.sys.posix.unistd.chdir(pathz) == 0;\n        }\n    }\n    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n        alias pathStr = pathname;\n    else\n        string pathStr = null;\n    cenforce(trustedChdir(pathz), pathStr, pathz);\n}\n\n/// ditto\nvoid chdir(R)(auto ref R pathname)\nif (isConvertibleToString!R)\n{\n    return chdir!(StringTypeOf!R)(pathname);\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.path : buildPath;\n\n    auto cwd = getcwd;\n    auto dir = deleteme ~ \"dir\";\n    dir.mkdir;\n    scope(exit) cwd.chdir, dir.rmdirRecurse;\n\n    dir.buildPath(\"a\").write(\".\");\n    dir.chdir; // step into dir\n    \"b\".write(\".\");\n    dirEntries(\".\", SpanMode.shallow).equal(\n        [\".\".buildPath(\"b\"), \".\".buildPath(\"a\")]\n    );\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, chdir(TestAliasedString(null))));\n}\n\n/**\nMake a new directory `pathname`.\n\nParams:\n    pathname = the path of the directory to make\n\nThrows:\n    $(LREF FileException) on Posix or $(LREF WindowsException) on Windows\n    if an error occured.\n */\nvoid mkdir(R)(R pathname)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    // Place outside of @trusted block\n    const pathz = pathname.tempCString!FSChar();\n\n    version (Windows)\n    {\n        static auto trustedCreateDirectoryW(const(FSChar)* pathz) @trusted\n        {\n            return CreateDirectoryW(pathz, null);\n        }\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias pathStr = pathname;\n        else\n            string pathStr = null;\n        wenforce(trustedCreateDirectoryW(pathz), pathStr, pathz);\n    }\n    else version (Posix)\n    {\n        import std.conv : octal;\n\n        static auto trustedMkdir(const(FSChar)* pathz, mode_t mode) @trusted\n        {\n            return core.sys.posix.sys.stat.mkdir(pathz, mode);\n        }\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias pathStr = pathname;\n        else\n            string pathStr = null;\n        cenforce(trustedMkdir(pathz, octal!777) == 0, pathStr, pathz);\n    }\n}\n\n/// ditto\nvoid mkdir(R)(auto ref R pathname)\nif (isConvertibleToString!R)\n{\n    return mkdir!(StringTypeOf!R)(pathname);\n}\n\n@safe unittest\n{\n    import std.file : mkdir;\n    static assert(__traits(compiles, mkdir(TestAliasedString(null))));\n}\n\n///\n@safe unittest\n{\n    import std.file : mkdir;\n\n    auto dir = deleteme ~ \"dir\";\n    scope(exit) dir.rmdir;\n\n    dir.mkdir;\n    assert(dir.exists);\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    assertThrown(\"a/b/c/d/e\".mkdir);\n}\n\n// Same as mkdir but ignores \"already exists\" errors.\n// Returns: \"true\" if the directory was created,\n//   \"false\" if it already existed.\nprivate bool ensureDirExists()(scope const(char)[] pathname)\n{\n    import std.exception : enforce;\n    const pathz = pathname.tempCString!FSChar();\n\n    version (Windows)\n    {\n        if (() @trusted { return CreateDirectoryW(pathz, null); }())\n            return true;\n        cenforce(GetLastError() == ERROR_ALREADY_EXISTS, pathname.idup);\n    }\n    else version (Posix)\n    {\n        import std.conv : octal;\n\n        if (() @trusted { return core.sys.posix.sys.stat.mkdir(pathz, octal!777); }() == 0)\n            return true;\n        cenforce(errno == EEXIST || errno == EISDIR, pathname);\n    }\n    enforce(pathname.isDir, new FileException(pathname.idup));\n    return false;\n}\n\n/**\nMake directory and all parent directories as needed.\n\nDoes nothing if the directory specified by\n`pathname` already exists.\n\nParams:\n    pathname = the full path of the directory to create\n\nThrows: $(LREF FileException) on error.\n */\nvoid mkdirRecurse(scope const(char)[] pathname) @safe\n{\n    import std.path : dirName, baseName;\n\n    const left = dirName(pathname);\n    if (left.length != pathname.length && !exists(left))\n    {\n        mkdirRecurse(left);\n    }\n    if (!baseName(pathname).empty)\n    {\n        ensureDirExists(pathname);\n    }\n}\n\n///\n@system unittest\n{\n    import std.path : buildPath;\n\n    auto dir = deleteme ~ \"dir\";\n    scope(exit) dir.rmdirRecurse;\n\n    dir.mkdir;\n    assert(dir.exists);\n    dir.mkdirRecurse; // does nothing\n\n    // creates all parent directories as needed\n    auto nested = dir.buildPath(\"a\", \"b\", \"c\");\n    nested.mkdirRecurse;\n    assert(nested.exists);\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    scope(exit) deleteme.remove;\n    deleteme.write(\"a\");\n\n    // cannot make directory as it's already a file\n    assertThrown!FileException(deleteme.mkdirRecurse);\n}\n\n@safe unittest\n{\n    import std.exception : assertThrown;\n    {\n        import std.path : buildPath, buildNormalizedPath;\n\n        immutable basepath = deleteme ~ \"_dir\";\n        scope(exit) () @trusted { rmdirRecurse(basepath); }();\n\n        auto path = buildPath(basepath, \"a\", \"..\", \"b\");\n        mkdirRecurse(path);\n        path = path.buildNormalizedPath;\n        assert(path.isDir);\n\n        path = buildPath(basepath, \"c\");\n        write(path, \"\");\n        assertThrown!FileException(mkdirRecurse(path));\n\n        path = buildPath(basepath, \"d\");\n        mkdirRecurse(path);\n        mkdirRecurse(path); // should not throw\n    }\n\n    version (Windows)\n    {\n        assertThrown!FileException(mkdirRecurse(`1:\\foobar`));\n    }\n\n    // bug3570\n    {\n        immutable basepath = deleteme ~ \"_dir\";\n        version (Windows)\n        {\n            immutable path = basepath ~ \"\\\\fake\\\\here\\\\\";\n        }\n        else version (Posix)\n        {\n            immutable path = basepath ~ `/fake/here/`;\n        }\n\n        mkdirRecurse(path);\n        assert(basepath.exists && basepath.isDir);\n        scope(exit) () @trusted { rmdirRecurse(basepath); }();\n        assert(path.exists && path.isDir);\n    }\n}\n\n/****************************************************\nRemove directory `pathname`.\n\nParams:\n    pathname = Range or string specifying the directory name\n\nThrows: $(LREF FileException) on error.\n */\nvoid rmdir(R)(R pathname)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&\n    !isConvertibleToString!R)\n{\n    // Place outside of @trusted block\n    auto pathz = pathname.tempCString!FSChar();\n\n    version (Windows)\n    {\n        static auto trustedRmdir(const(FSChar)* pathz) @trusted\n        {\n            return RemoveDirectoryW(pathz);\n        }\n    }\n    else version (Posix)\n    {\n        static auto trustedRmdir(const(FSChar)* pathz) @trusted\n        {\n            return core.sys.posix.unistd.rmdir(pathz) == 0;\n        }\n    }\n    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n        alias pathStr = pathname;\n    else\n        string pathStr = null;\n    cenforce(trustedRmdir(pathz), pathStr, pathz);\n}\n\n/// ditto\nvoid rmdir(R)(auto ref R pathname)\nif (isConvertibleToString!R)\n{\n    rmdir!(StringTypeOf!R)(pathname);\n}\n\n@safe unittest\n{\n    static assert(__traits(compiles, rmdir(TestAliasedString(null))));\n}\n\n///\n@system unittest\n{\n    auto dir = deleteme ~ \"dir\";\n\n    dir.mkdir;\n    assert(dir.exists);\n    dir.rmdir;\n    assert(!dir.exists);\n}\n\n/++\n    $(BLUE This function is Posix-Only.)\n\n    Creates a symbolic _link (_symlink).\n\n    Params:\n        original = The file that is being linked. This is the target path that's\n            stored in the _symlink. A relative path is relative to the created\n            _symlink.\n        link = The _symlink to create. A relative path is relative to the\n            current working directory.\n\n    Throws:\n        $(LREF FileException) on error (which includes if the _symlink already\n        exists).\n  +/\nversion (StdDdoc) void symlink(RO, RL)(RO original, RL link)\nif ((isInputRange!RO && !isInfinite!RO && isSomeChar!(ElementEncodingType!RO) ||\n    isConvertibleToString!RO) &&\n    (isInputRange!RL && !isInfinite!RL && isSomeChar!(ElementEncodingType!RL) ||\n    isConvertibleToString!RL));\nelse version (Posix) void symlink(RO, RL)(RO original, RL link)\nif ((isInputRange!RO && !isInfinite!RO && isSomeChar!(ElementEncodingType!RO) ||\n    isConvertibleToString!RO) &&\n    (isInputRange!RL && !isInfinite!RL && isSomeChar!(ElementEncodingType!RL) ||\n    isConvertibleToString!RL))\n{\n    static if (isConvertibleToString!RO || isConvertibleToString!RL)\n    {\n        import std.meta : staticMap;\n        alias Types = staticMap!(convertToString, RO, RL);\n        symlink!Types(original, link);\n    }\n    else\n    {\n        import std.conv : text;\n        auto oz = original.tempCString();\n        auto lz = link.tempCString();\n        alias posixSymlink = core.sys.posix.unistd.symlink;\n        immutable int result = () @trusted { return posixSymlink(oz, lz); } ();\n        cenforce(result == 0, text(link));\n    }\n}\n\nversion (Posix) @safe unittest\n{\n    if (system_directory.exists)\n    {\n        immutable symfile = deleteme ~ \"_slink\\0\";\n        scope(exit) if (symfile.exists) symfile.remove();\n\n        symlink(system_directory, symfile);\n\n        assert(symfile.exists);\n        assert(symfile.isSymlink);\n        assert(!attrIsSymlink(getAttributes(symfile)));\n        assert(attrIsSymlink(getLinkAttributes(symfile)));\n\n        assert(attrIsDir(getAttributes(symfile)));\n        assert(!attrIsDir(getLinkAttributes(symfile)));\n\n        assert(!attrIsFile(getAttributes(symfile)));\n        assert(!attrIsFile(getLinkAttributes(symfile)));\n    }\n\n    if (system_file.exists)\n    {\n        assert(!system_file.isSymlink);\n\n        immutable symfile = deleteme ~ \"_slink\\0\";\n        scope(exit) if (symfile.exists) symfile.remove();\n\n        symlink(system_file, symfile);\n\n        assert(symfile.exists);\n        assert(symfile.isSymlink);\n        assert(!attrIsSymlink(getAttributes(symfile)));\n        assert(attrIsSymlink(getLinkAttributes(symfile)));\n\n        assert(!attrIsDir(getAttributes(symfile)));\n        assert(!attrIsDir(getLinkAttributes(symfile)));\n\n        assert(attrIsFile(getAttributes(symfile)));\n        assert(!attrIsFile(getLinkAttributes(symfile)));\n    }\n}\n\nversion (Posix) @safe unittest\n{\n    static assert(__traits(compiles,\n        symlink(TestAliasedString(null), TestAliasedString(null))));\n}\n\n\n/++\n    $(BLUE This function is Posix-Only.)\n\n    Returns the path to the file pointed to by a symlink. Note that the\n    path could be either relative or absolute depending on the symlink.\n    If the path is relative, it's relative to the symlink, not the current\n    working directory.\n\n    Throws:\n        $(LREF FileException) on error.\n  +/\nversion (StdDdoc) string readLink(R)(R link)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) ||\n    isConvertibleToString!R);\nelse version (Posix) string readLink(R)(R link)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) ||\n    isConvertibleToString!R)\n{\n    static if (isConvertibleToString!R)\n    {\n        return readLink!(convertToString!R)(link);\n    }\n    else\n    {\n        import std.conv : to;\n        import std.exception : assumeUnique;\n        alias posixReadlink = core.sys.posix.unistd.readlink;\n        enum bufferLen = 2048;\n        enum maxCodeUnits = 6;\n        char[bufferLen] buffer;\n        const linkz = link.tempCString();\n        auto size = () @trusted {\n            return posixReadlink(linkz, buffer.ptr, buffer.length);\n        } ();\n        cenforce(size != -1, to!string(link));\n\n        if (size <= bufferLen - maxCodeUnits)\n            return to!string(buffer[0 .. size]);\n\n        auto dynamicBuffer = new char[](bufferLen * 3 / 2);\n\n        foreach (i; 0 .. 10)\n        {\n            size = () @trusted {\n                return posixReadlink(linkz, dynamicBuffer.ptr,\n                    dynamicBuffer.length);\n            } ();\n            cenforce(size != -1, to!string(link));\n\n            if (size <= dynamicBuffer.length - maxCodeUnits)\n            {\n                dynamicBuffer.length = size;\n                return () @trusted {\n                    return assumeUnique(dynamicBuffer);\n                } ();\n            }\n\n            dynamicBuffer.length = dynamicBuffer.length * 3 / 2;\n        }\n\n        throw new FileException(to!string(link), \"Path is too long to read.\");\n    }\n}\n\nversion (Posix) @safe unittest\n{\n    import std.exception : assertThrown;\n    import std.string;\n\n    foreach (file; [system_directory, system_file])\n    {\n        if (file.exists)\n        {\n            immutable symfile = deleteme ~ \"_slink\\0\";\n            scope(exit) if (symfile.exists) symfile.remove();\n\n            symlink(file, symfile);\n            assert(readLink(symfile) == file, format(\"Failed file: %s\", file));\n        }\n    }\n\n    assertThrown!FileException(readLink(\"/doesnotexist\"));\n}\n\nversion (Posix) @safe unittest\n{\n    static assert(__traits(compiles, readLink(TestAliasedString(\"foo\"))));\n}\n\nversion (Posix) @system unittest // input range of dchars\n{\n    mkdirRecurse(deleteme);\n    scope(exit) if (deleteme.exists) rmdirRecurse(deleteme);\n    write(deleteme ~ \"/f\", \"\");\n    import std.range.interfaces : InputRange, inputRangeObject;\n    import std.utf : byChar;\n    immutable string link = deleteme ~ \"/l\";\n    symlink(\"f\", link);\n    InputRange!dchar linkr = inputRangeObject(link);\n    alias R = typeof(linkr);\n    static assert(isInputRange!R);\n    static assert(!isForwardRange!R);\n    assert(readLink(linkr) == \"f\");\n}\n\n\n/****************************************************\n * Get the current working directory.\n * Throws: $(LREF FileException) on error.\n */\nversion (Windows) string getcwd() @trusted\n{\n    import std.conv : to;\n    import std.experimental.checkedint : checked;\n    /* GetCurrentDirectory's return value:\n        1. function succeeds: the number of characters that are written to\n    the buffer, not including the terminating null character.\n        2. function fails: zero\n        3. the buffer (lpBuffer) is not large enough: the required size of\n    the buffer, in characters, including the null-terminating character.\n    */\n    version (unittest)\n        enum BUF_SIZE = 10;     // trigger reallocation code\n    else\n        enum BUF_SIZE = 4096;   // enough for most common case\n    wchar[BUF_SIZE] buffW = void;\n    immutable n = cenforce(GetCurrentDirectoryW(to!DWORD(buffW.length), buffW.ptr),\n            \"getcwd\");\n    // we can do it because toUTFX always produces a fresh string\n    if (n < buffW.length)\n    {\n        return buffW[0 .. n].to!string;\n    }\n    else //staticBuff isn't enough\n    {\n        auto cn = checked(n);\n        auto ptr = cast(wchar*) malloc((cn * wchar.sizeof).get);\n        scope(exit) free(ptr);\n        immutable n2 = GetCurrentDirectoryW(cn.get, ptr);\n        cenforce(n2 && n2 < cn, \"getcwd\");\n        return ptr[0 .. n2].to!string;\n    }\n}\nelse version (Solaris) string getcwd() @trusted\n{\n    /* BUF_SIZE >= PATH_MAX */\n    enum BUF_SIZE = 4096;\n    /* The user should be able to specify any size buffer > 0 */\n    auto p = cenforce(core.sys.posix.unistd.getcwd(null, BUF_SIZE),\n            \"cannot get cwd\");\n    scope(exit) core.stdc.stdlib.free(p);\n    return p[0 .. core.stdc.string.strlen(p)].idup;\n}\nelse version (Posix) string getcwd() @trusted\n{\n    auto p = cenforce(core.sys.posix.unistd.getcwd(null, 0),\n            \"cannot get cwd\");\n    scope(exit) core.stdc.stdlib.free(p);\n    return p[0 .. core.stdc.string.strlen(p)].idup;\n}\n\n///\n@safe unittest\n{\n    auto s = getcwd();\n    assert(s.length);\n}\n\nversion (OSX)\n    private extern (C) int _NSGetExecutablePath(char* buf, uint* bufsize);\nelse version (FreeBSD)\n    private extern (C) int sysctl (const int* name, uint namelen, void* oldp,\n        size_t* oldlenp, const void* newp, size_t newlen);\nelse version (NetBSD)\n    private extern (C) int sysctl (const int* name, uint namelen, void* oldp,\n        size_t* oldlenp, const void* newp, size_t newlen);\n\n/**\n * Returns the full path of the current executable.\n *\n * Returns:\n *     The path of the executable as a `string`.\n *\n * Throws:\n * $(REF1 Exception, object)\n */\n@trusted string thisExePath()\n{\n    version (OSX)\n    {\n        import core.sys.posix.stdlib : realpath;\n        import std.conv : to;\n        import std.exception : errnoEnforce;\n\n        uint size;\n\n        _NSGetExecutablePath(null, &size); // get the length of the path\n        auto buffer = new char[size];\n        _NSGetExecutablePath(buffer.ptr, &size);\n\n        auto absolutePath = realpath(buffer.ptr, null); // let the function allocate\n\n        scope (exit)\n        {\n            if (absolutePath)\n                free(absolutePath);\n        }\n\n        errnoEnforce(absolutePath);\n        return to!(string)(absolutePath);\n    }\n    else version (linux)\n    {\n        return readLink(\"/proc/self/exe\");\n    }\n    else version (Windows)\n    {\n        import std.conv : to;\n        import std.exception : enforce;\n\n        wchar[MAX_PATH] buf;\n        wchar[] buffer = buf[];\n\n        while (true)\n        {\n            auto len = GetModuleFileNameW(null, buffer.ptr, cast(DWORD) buffer.length);\n            enforce(len, sysErrorString(GetLastError()));\n            if (len != buffer.length)\n                return to!(string)(buffer[0 .. len]);\n            buffer.length *= 2;\n        }\n    }\n    else version (FreeBSD)\n    {\n        import std.exception : errnoEnforce, assumeUnique;\n        enum\n        {\n            CTL_KERN = 1,\n            KERN_PROC = 14,\n            KERN_PROC_PATHNAME = 12\n        }\n\n        int[4] mib = [CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1];\n        size_t len;\n\n        auto result = sysctl(mib.ptr, mib.length, null, &len, null, 0); // get the length of the path\n        errnoEnforce(result == 0);\n\n        auto buffer = new char[len - 1];\n        result = sysctl(mib.ptr, mib.length, buffer.ptr, &len, null, 0);\n        errnoEnforce(result == 0);\n\n        return buffer.assumeUnique;\n    }\n    else version (NetBSD)\n    {\n        return readLink(\"/proc/self/exe\");\n    }\n    else version (DragonFlyBSD)\n    {\n        return readLink(\"/proc/curproc/file\");\n    }\n    else version (Solaris)\n    {\n        import core.sys.posix.unistd : getpid;\n        import std.string : format;\n\n        // Only Solaris 10 and later\n        return readLink(format(\"/proc/%d/path/a.out\", getpid()));\n    }\n    else\n        static assert(0, \"thisExePath is not supported on this platform\");\n}\n\n///\n@safe unittest\n{\n    import std.path : isAbsolute;\n    auto path = thisExePath();\n\n    assert(path.exists);\n    assert(path.isAbsolute);\n    assert(path.isFile);\n}\n\nversion (StdDdoc)\n{\n    /++\n        Info on a file, similar to what you'd get from stat on a Posix system.\n      +/\n    struct DirEntry\n    {\n        @safe:\n        /++\n            Constructs a `DirEntry` for the given file (or directory).\n\n            Params:\n                path = The file (or directory) to get a DirEntry for.\n\n            Throws:\n                $(LREF FileException) if the file does not exist.\n        +/\n        this(string path);\n\n        version (Windows)\n        {\n            private this(string path, in WIN32_FIND_DATAW *fd);\n        }\n        else version (Posix)\n        {\n            private this(string path, core.sys.posix.dirent.dirent* fd);\n        }\n\n        /++\n            Returns the path to the file represented by this `DirEntry`.\n\nExample:\n--------------------\nauto de1 = DirEntry(\"/etc/fonts/fonts.conf\");\nassert(de1.name == \"/etc/fonts/fonts.conf\");\n\nauto de2 = DirEntry(\"/usr/share/include\");\nassert(de2.name == \"/usr/share/include\");\n--------------------\n          +/\n        @property string name() const;\n\n\n        /++\n            Returns whether the file represented by this `DirEntry` is a\n            directory.\n\nExample:\n--------------------\nauto de1 = DirEntry(\"/etc/fonts/fonts.conf\");\nassert(!de1.isDir);\n\nauto de2 = DirEntry(\"/usr/share/include\");\nassert(de2.isDir);\n--------------------\n          +/\n        @property bool isDir();\n\n\n        /++\n            Returns whether the file represented by this `DirEntry` is a file.\n\n            On Windows, if a file is not a directory, then it's a file. So,\n            either `isFile` or `isDir` will return `true`.\n\n            On Posix systems, if `isFile` is `true`, that indicates that\n            the file is a regular file (e.g. not a block not device). So, on\n            Posix systems, it's possible for both `isFile` and `isDir` to\n            be `false` for a particular file (in which case, it's a special\n            file). You can use `attributes` or `statBuf` to get more\n            information about a special file (see the stat man page for more\n            details).\n\nExample:\n--------------------\nauto de1 = DirEntry(\"/etc/fonts/fonts.conf\");\nassert(de1.isFile);\n\nauto de2 = DirEntry(\"/usr/share/include\");\nassert(!de2.isFile);\n--------------------\n          +/\n        @property bool isFile();\n\n        /++\n            Returns whether the file represented by this `DirEntry` is a\n            symbolic link.\n\n            On Windows, return `true` when the file is either a symbolic\n            link or a junction point.\n          +/\n        @property bool isSymlink();\n\n        /++\n            Returns the size of the the file represented by this `DirEntry`\n            in bytes.\n          +/\n        @property ulong size();\n\n        /++\n            $(BLUE This function is Windows-Only.)\n\n            Returns the creation time of the file represented by this\n            `DirEntry`.\n          +/\n        @property SysTime timeCreated() const;\n\n        /++\n            Returns the time that the file represented by this `DirEntry` was\n            last accessed.\n\n            Note that many file systems do not update the access time for files\n            (generally for performance reasons), so there's a good chance that\n            `timeLastAccessed` will return the same value as\n            `timeLastModified`.\n          +/\n        @property SysTime timeLastAccessed();\n\n        /++\n            Returns the time that the file represented by this `DirEntry` was\n            last modified.\n          +/\n        @property SysTime timeLastModified();\n\n        /++\n            $(BLUE This function is Posix-Only.)\n\n            Returns the time that the file represented by this `DirEntry` was\n            last changed (not only in contents, but also in permissions or ownership).\n          +/\n        @property SysTime timeStatusChanged() const;\n\n        /++\n            Returns the _attributes of the file represented by this `DirEntry`.\n\n            Note that the file _attributes on Windows and Posix systems are\n            completely different. On, Windows, they're what is returned by\n            `GetFileAttributes`\n            $(HTTP msdn.microsoft.com/en-us/library/aa364944(v=vs.85).aspx, GetFileAttributes)\n            Whereas, an Posix systems, they're the `st_mode` value which is\n            part of the `stat` struct gotten by calling `stat`.\n\n            On Posix systems, if the file represented by this `DirEntry` is a\n            symbolic link, then _attributes are the _attributes of the file\n            pointed to by the symbolic link.\n          +/\n        @property uint attributes();\n\n        /++\n            On Posix systems, if the file represented by this `DirEntry` is a\n            symbolic link, then `linkAttributes` are the attributes of the\n            symbolic link itself. Otherwise, `linkAttributes` is identical to\n            `attributes`.\n\n            On Windows, `linkAttributes` is identical to `attributes`. It\n            exists on Windows so that you don't have to special-case code for\n            Windows when dealing with symbolic links.\n          +/\n        @property uint linkAttributes();\n\n        version (Windows)\n            alias stat_t = void*;\n\n        /++\n            $(BLUE This function is Posix-Only.)\n\n            The `stat` struct gotten from calling `stat`.\n          +/\n        @property stat_t statBuf();\n    }\n}\nelse version (Windows)\n{\n    struct DirEntry\n    {\n    @safe:\n    public:\n        alias name this;\n\n        this(string path)\n        {\n            import std.datetime.systime : FILETIMEToSysTime;\n\n            if (!path.exists())\n                throw new FileException(path, \"File does not exist\");\n\n            _name = path;\n\n            with (getFileAttributesWin(path))\n            {\n                _size = makeUlong(nFileSizeLow, nFileSizeHigh);\n                _timeCreated = FILETIMEToSysTime(&ftCreationTime);\n                _timeLastAccessed = FILETIMEToSysTime(&ftLastAccessTime);\n                _timeLastModified = FILETIMEToSysTime(&ftLastWriteTime);\n                _attributes = dwFileAttributes;\n            }\n        }\n\n        private this(string path, WIN32_FIND_DATAW *fd) @trusted\n        {\n            import core.stdc.wchar_ : wcslen;\n            import std.conv : to;\n            import std.datetime.systime : FILETIMEToSysTime;\n            import std.path : buildPath;\n\n            fd.cFileName[$ - 1] = 0;\n\n            size_t clength = wcslen(&fd.cFileName[0]);\n            _name = buildPath(path, fd.cFileName[0 .. clength].to!string);\n            _size = (cast(ulong) fd.nFileSizeHigh << 32) | fd.nFileSizeLow;\n            _timeCreated = FILETIMEToSysTime(&fd.ftCreationTime);\n            _timeLastAccessed = FILETIMEToSysTime(&fd.ftLastAccessTime);\n            _timeLastModified = FILETIMEToSysTime(&fd.ftLastWriteTime);\n            _attributes = fd.dwFileAttributes;\n        }\n\n        @property string name() const pure nothrow\n        {\n            return _name;\n        }\n\n        @property bool isDir() const pure nothrow\n        {\n            return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;\n        }\n\n        @property bool isFile() const pure nothrow\n        {\n            //Are there no options in Windows other than directory and file?\n            //If there are, then this probably isn't the best way to determine\n            //whether this DirEntry is a file or not.\n            return !isDir;\n        }\n\n        @property bool isSymlink() const pure nothrow\n        {\n            return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;\n        }\n\n        @property ulong size() const pure nothrow\n        {\n            return _size;\n        }\n\n        @property SysTime timeCreated() const pure nothrow\n        {\n            return cast(SysTime)_timeCreated;\n        }\n\n        @property SysTime timeLastAccessed() const pure nothrow\n        {\n            return cast(SysTime)_timeLastAccessed;\n        }\n\n        @property SysTime timeLastModified() const pure nothrow\n        {\n            return cast(SysTime)_timeLastModified;\n        }\n\n        @property uint attributes() const pure nothrow\n        {\n            return _attributes;\n        }\n\n        @property uint linkAttributes() const pure nothrow\n        {\n            return _attributes;\n        }\n\n    private:\n        string _name; /// The file or directory represented by this DirEntry.\n\n        SysTime _timeCreated;      /// The time when the file was created.\n        SysTime _timeLastAccessed; /// The time when the file was last accessed.\n        SysTime _timeLastModified; /// The time when the file was last modified.\n\n        ulong _size;       /// The size of the file in bytes.\n        uint  _attributes; /// The file attributes from WIN32_FIND_DATAW.\n    }\n}\nelse version (Posix)\n{\n    struct DirEntry\n    {\n    @safe:\n    public:\n        alias name this;\n\n        this(string path)\n        {\n            if (!path.exists)\n                throw new FileException(path, \"File does not exist\");\n\n            _name = path;\n\n            _didLStat = false;\n            _didStat = false;\n            _dTypeSet = false;\n        }\n\n        private this(string path, core.sys.posix.dirent.dirent* fd) @safe\n        {\n            import std.algorithm.searching : countUntil;\n            import std.path : buildPath;\n            import std.string : representation;\n\n            immutable len = fd.d_name[].representation.countUntil(0);\n            _name = buildPath(path, fd.d_name[0 .. len]);\n\n            _didLStat = false;\n            _didStat = false;\n\n            //fd_d_type doesn't work for all file systems,\n            //in which case the result is DT_UNKOWN. But we\n            //can determine the correct type from lstat, so\n            //we'll only set the dtype here if we could\n            //correctly determine it (not lstat in the case\n            //of DT_UNKNOWN in case we don't ever actually\n            //need the dtype, thus potentially avoiding the\n            //cost of calling lstat).\n            static if (__traits(compiles, fd.d_type != DT_UNKNOWN))\n            {\n                if (fd.d_type != DT_UNKNOWN)\n                {\n                    _dType = fd.d_type;\n                    _dTypeSet = true;\n                }\n                else\n                    _dTypeSet = false;\n            }\n            else\n            {\n                // e.g. Solaris does not have the d_type member\n                _dTypeSet = false;\n            }\n        }\n\n        @property string name() const pure nothrow\n        {\n            return _name;\n        }\n\n        @property bool isDir()\n        {\n            _ensureStatOrLStatDone();\n\n            return (_statBuf.st_mode & S_IFMT) == S_IFDIR;\n        }\n\n        @property bool isFile()\n        {\n            _ensureStatOrLStatDone();\n\n            return (_statBuf.st_mode & S_IFMT) == S_IFREG;\n        }\n\n        @property bool isSymlink()\n        {\n            _ensureLStatDone();\n\n            return (_lstatMode & S_IFMT) == S_IFLNK;\n        }\n\n        @property ulong size()\n        {\n            _ensureStatDone();\n            return _statBuf.st_size;\n        }\n\n        @property SysTime timeStatusChanged()\n        {\n            _ensureStatDone();\n\n            return statTimeToStdTime!'c'(_statBuf);\n        }\n\n        @property SysTime timeLastAccessed()\n        {\n            _ensureStatDone();\n\n            return statTimeToStdTime!'a'(_statBuf);\n        }\n\n        @property SysTime timeLastModified()\n        {\n            _ensureStatDone();\n\n            return statTimeToStdTime!'m'(_statBuf);\n        }\n\n        @property uint attributes()\n        {\n            _ensureStatDone();\n\n            return _statBuf.st_mode;\n        }\n\n        @property uint linkAttributes()\n        {\n            _ensureLStatDone();\n\n            return _lstatMode;\n        }\n\n        @property stat_t statBuf()\n        {\n            _ensureStatDone();\n\n            return _statBuf;\n        }\n\n    private:\n        /++\n            This is to support lazy evaluation, because doing stat's is\n            expensive and not always needed.\n         +/\n        void _ensureStatDone() @trusted\n        {\n            import std.exception : enforce;\n\n            if (_didStat)\n                return;\n\n            enforce(stat(_name.tempCString(), &_statBuf) == 0,\n                    \"Failed to stat file `\" ~ _name ~ \"'\");\n\n            _didStat = true;\n        }\n\n        /++\n            This is to support lazy evaluation, because doing stat's is\n            expensive and not always needed.\n\n            Try both stat and lstat for isFile and isDir\n            to detect broken symlinks.\n         +/\n        void _ensureStatOrLStatDone() @trusted\n        {\n            if (_didStat)\n                return;\n\n            if (stat(_name.tempCString(), &_statBuf) != 0)\n            {\n                _ensureLStatDone();\n\n                _statBuf = stat_t.init;\n                _statBuf.st_mode = S_IFLNK;\n            }\n            else\n            {\n                _didStat = true;\n            }\n        }\n\n        /++\n            This is to support lazy evaluation, because doing stat's is\n            expensive and not always needed.\n         +/\n        void _ensureLStatDone() @trusted\n        {\n            import std.exception : enforce;\n\n            if (_didLStat)\n                return;\n\n            stat_t statbuf = void;\n            enforce(lstat(_name.tempCString(), &statbuf) == 0,\n                \"Failed to stat file `\" ~ _name ~ \"'\");\n\n            _lstatMode = statbuf.st_mode;\n\n            _dTypeSet = true;\n            _didLStat = true;\n        }\n\n        string _name; /// The file or directory represented by this DirEntry.\n\n        stat_t _statBuf = void;   /// The result of stat().\n        uint  _lstatMode;         /// The stat mode from lstat().\n        ubyte _dType;             /// The type of the file.\n\n        bool _didLStat = false;   /// Whether lstat() has been called for this DirEntry.\n        bool _didStat = false;    /// Whether stat() has been called for this DirEntry.\n        bool _dTypeSet = false;   /// Whether the dType of the file has been set.\n    }\n}\n\n@system unittest\n{\n    version (Windows)\n    {\n        if (\"C:\\\\Program Files\\\\\".exists)\n        {\n            auto de = DirEntry(\"C:\\\\Program Files\\\\\");\n            assert(!de.isFile);\n            assert(de.isDir);\n            assert(!de.isSymlink);\n        }\n\n        if (\"C:\\\\Users\\\\\".exists && \"C:\\\\Documents and Settings\\\\\".exists)\n        {\n            auto de = DirEntry(\"C:\\\\Documents and Settings\\\\\");\n            assert(de.isSymlink);\n        }\n\n        if (\"C:\\\\Windows\\\\system.ini\".exists)\n        {\n            auto de = DirEntry(\"C:\\\\Windows\\\\system.ini\");\n            assert(de.isFile);\n            assert(!de.isDir);\n            assert(!de.isSymlink);\n        }\n    }\n    else version (Posix)\n    {\n        import std.exception : assertThrown;\n\n        if (system_directory.exists)\n        {\n            {\n                auto de = DirEntry(system_directory);\n                assert(!de.isFile);\n                assert(de.isDir);\n                assert(!de.isSymlink);\n            }\n\n            immutable symfile = deleteme ~ \"_slink\\0\";\n            scope(exit) if (symfile.exists) symfile.remove();\n\n            core.sys.posix.unistd.symlink(system_directory, symfile.ptr);\n\n            {\n                auto de = DirEntry(symfile);\n                assert(!de.isFile);\n                assert(de.isDir);\n                assert(de.isSymlink);\n            }\n\n            symfile.remove();\n            core.sys.posix.unistd.symlink((deleteme ~ \"_broken_symlink\\0\").ptr, symfile.ptr);\n\n            {\n                //Issue 8298\n                DirEntry de = DirEntry(symfile);\n\n                assert(!de.isFile);\n                assert(!de.isDir);\n                assert(de.isSymlink);\n                assertThrown(de.size);\n                assertThrown(de.timeStatusChanged);\n                assertThrown(de.timeLastAccessed);\n                assertThrown(de.timeLastModified);\n                assertThrown(de.attributes);\n                assertThrown(de.statBuf);\n                assert(symfile.exists);\n                symfile.remove();\n            }\n        }\n\n        if (system_file.exists)\n        {\n            auto de = DirEntry(system_file);\n            assert(de.isFile);\n            assert(!de.isDir);\n            assert(!de.isSymlink);\n        }\n    }\n}\n\nalias PreserveAttributes = Flag!\"preserveAttributes\";\n\nversion (StdDdoc)\n{\n    /// Defaults to `Yes.preserveAttributes` on Windows, and the opposite on all other platforms.\n    PreserveAttributes preserveAttributesDefault;\n}\nelse version (Windows)\n{\n    enum preserveAttributesDefault = Yes.preserveAttributes;\n}\nelse\n{\n    enum preserveAttributesDefault = No.preserveAttributes;\n}\n\n/***************************************************\nCopy file `from` _to file `to`. File timestamps are preserved.\nFile attributes are preserved, if `preserve` equals `Yes.preserveAttributes`.\nOn Windows only `Yes.preserveAttributes` (the default on Windows) is supported.\nIf the target file exists, it is overwritten.\n\nParams:\n    from = string or range of characters representing the existing file name\n    to = string or range of characters representing the target file name\n    preserve = whether to _preserve the file attributes\n\nThrows: $(LREF FileException) on error.\n */\nvoid copy(RF, RT)(RF from, RT to, PreserveAttributes preserve = preserveAttributesDefault)\nif (isInputRange!RF && !isInfinite!RF && isSomeChar!(ElementEncodingType!RF) && !isConvertibleToString!RF &&\n    isInputRange!RT && !isInfinite!RT && isSomeChar!(ElementEncodingType!RT) && !isConvertibleToString!RT)\n{\n    // Place outside of @trusted block\n    auto fromz = from.tempCString!FSChar();\n    auto toz = to.tempCString!FSChar();\n\n    static if (isNarrowString!RF && is(Unqual!(ElementEncodingType!RF) == char))\n        alias f = from;\n    else\n        enum string f = null;\n\n    static if (isNarrowString!RT && is(Unqual!(ElementEncodingType!RT) == char))\n        alias t = to;\n    else\n        enum string t = null;\n\n    copyImpl(f, t, fromz, toz, preserve);\n}\n\n/// ditto\nvoid copy(RF, RT)(auto ref RF from, auto ref RT to, PreserveAttributes preserve = preserveAttributesDefault)\nif (isConvertibleToString!RF || isConvertibleToString!RT)\n{\n    import std.meta : staticMap;\n    alias Types = staticMap!(convertToString, RF, RT);\n    copy!Types(from, to, preserve);\n}\n\n///\n@safe unittest\n{\n    auto source = deleteme ~ \"source\";\n    auto target = deleteme ~ \"target\";\n    auto targetNonExistent = deleteme ~ \"target2\";\n\n    scope(exit) source.remove, target.remove, targetNonExistent.remove;\n\n    source.write(\"source\");\n    target.write(\"target\");\n\n    assert(target.readText == \"target\");\n\n    source.copy(target);\n    assert(target.readText == \"source\");\n\n    source.copy(targetNonExistent);\n    assert(targetNonExistent.readText == \"source\");\n}\n\n@safe unittest // issue 15319\n{\n    assert(__traits(compiles, copy(\"from.txt\", \"to.txt\")));\n}\n\nprivate void copyImpl(scope const(char)[] f, scope const(char)[] t,\n                      scope const(FSChar)* fromz, scope const(FSChar)* toz,\n                      PreserveAttributes preserve) @trusted\n{\n    version (Windows)\n    {\n        assert(preserve == Yes.preserveAttributes);\n        immutable result = CopyFileW(fromz, toz, false);\n        if (!result)\n        {\n            import core.stdc.wchar_ : wcslen;\n            import std.conv : to;\n\n            if (!t)\n                t = to!(typeof(t))(toz[0 .. wcslen(toz)]);\n\n            throw new FileException(t);\n        }\n    }\n    else version (Posix)\n    {\n        static import core.stdc.stdio;\n        import std.conv : to, octal;\n\n        immutable fdr = core.sys.posix.fcntl.open(fromz, O_RDONLY);\n        cenforce(fdr != -1, f, fromz);\n        scope(exit) core.sys.posix.unistd.close(fdr);\n\n        stat_t statbufr = void;\n        cenforce(fstat(fdr, &statbufr) == 0, f, fromz);\n        //cenforce(core.sys.posix.sys.stat.fstat(fdr, &statbufr) == 0, f, fromz);\n\n        immutable fdw = core.sys.posix.fcntl.open(toz,\n                O_CREAT | O_WRONLY, octal!666);\n        cenforce(fdw != -1, t, toz);\n        {\n            scope(failure) core.sys.posix.unistd.close(fdw);\n\n            stat_t statbufw = void;\n            cenforce(fstat(fdw, &statbufw) == 0, t, toz);\n            if (statbufr.st_dev == statbufw.st_dev && statbufr.st_ino == statbufw.st_ino)\n                throw new FileException(t, \"Source and destination are the same file\");\n        }\n\n        scope(failure) core.stdc.stdio.remove(toz);\n        {\n            scope(failure) core.sys.posix.unistd.close(fdw);\n            cenforce(ftruncate(fdw, 0) == 0, t, toz);\n\n            auto BUFSIZ = 4096u * 16;\n            auto buf = core.stdc.stdlib.malloc(BUFSIZ);\n            if (!buf)\n            {\n                BUFSIZ = 4096;\n                buf = core.stdc.stdlib.malloc(BUFSIZ);\n                if (!buf)\n                {\n                    import core.exception : onOutOfMemoryError;\n                    onOutOfMemoryError();\n                }\n            }\n            scope(exit) core.stdc.stdlib.free(buf);\n\n            for (auto size = statbufr.st_size; size; )\n            {\n                immutable toxfer = (size > BUFSIZ) ? BUFSIZ : cast(size_t) size;\n                cenforce(\n                    core.sys.posix.unistd.read(fdr, buf, toxfer) == toxfer\n                    && core.sys.posix.unistd.write(fdw, buf, toxfer) == toxfer,\n                    f, fromz);\n                assert(size >= toxfer);\n                size -= toxfer;\n            }\n            if (preserve)\n                cenforce(fchmod(fdw, to!mode_t(statbufr.st_mode)) == 0, f, fromz);\n        }\n\n        cenforce(core.sys.posix.unistd.close(fdw) != -1, f, fromz);\n\n        utimbuf utim = void;\n        utim.actime = cast(time_t) statbufr.st_atime;\n        utim.modtime = cast(time_t) statbufr.st_mtime;\n\n        cenforce(utime(toz, &utim) != -1, f, fromz);\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm, std.file; // issue 14817\n    auto t1 = deleteme, t2 = deleteme~\"2\";\n    scope(exit) foreach (t; [t1, t2]) if (t.exists) t.remove();\n    write(t1, \"11\");\n    copy(t1, t2);\n    assert(readText(t2) == \"11\");\n    write(t1, \"2\");\n    copy(t1, t2);\n    assert(readText(t2) == \"2\");\n\n    import std.utf : byChar;\n    copy(t1.byChar, t2.byChar);\n    assert(readText(t2.byChar) == \"2\");\n}\n\n@safe version (Posix) @safe unittest //issue 11434\n{\n    import std.conv : octal;\n    auto t1 = deleteme, t2 = deleteme~\"2\";\n    scope(exit) foreach (t; [t1, t2]) if (t.exists) t.remove();\n    write(t1, \"1\");\n    setAttributes(t1, octal!767);\n    copy(t1, t2, Yes.preserveAttributes);\n    assert(readText(t2) == \"1\");\n    assert(getAttributes(t2) == octal!100767);\n}\n\n@safe unittest // issue 15865\n{\n    import std.exception : assertThrown;\n    auto t = deleteme;\n    write(t, \"a\");\n    scope(exit) t.remove();\n    assertThrown!FileException(copy(t, t));\n    assert(readText(t) == \"a\");\n}\n\n/++\n    Remove directory and all of its content and subdirectories,\n    recursively.\n\n    Params:\n        pathname = the path of the directory to completely remove\n        de = The $(LREF DirEntry) to remove\n\n    Throws:\n        $(LREF FileException) if there is an error (including if the given\n        file is not a directory).\n +/\nvoid rmdirRecurse(scope const(char)[] pathname)\n{\n    //No references to pathname will be kept after rmdirRecurse,\n    //so the cast is safe\n    rmdirRecurse(DirEntry(cast(string) pathname));\n}\n\n/// ditto\nvoid rmdirRecurse(ref DirEntry de)\n{\n    if (!de.isDir)\n        throw new FileException(de.name, \"Not a directory\");\n\n    if (de.isSymlink)\n    {\n        version (Windows)\n            rmdir(de.name);\n        else\n            remove(de.name);\n    }\n    else\n    {\n        // all children, recursively depth-first\n        foreach (DirEntry e; dirEntries(de.name, SpanMode.depth, false))\n        {\n            attrIsDir(e.linkAttributes) ? rmdir(e.name) : remove(e.name);\n        }\n\n        // the dir itself\n        rmdir(de.name);\n    }\n}\n///ditto\n//Note, without this overload, passing an RValue DirEntry still works, but\n//actually fully reconstructs a DirEntry inside the\n//\"rmdirRecurse(in char[] pathname)\" implementation. That is needlessly\n//expensive.\n//A DirEntry is a bit big (72B), so keeping the \"by ref\" signature is desirable.\nvoid rmdirRecurse(DirEntry de)\n{\n    rmdirRecurse(de);\n}\n\n///\n@system unittest\n{\n    import std.path : buildPath;\n\n    auto dir = deleteme.buildPath(\"a\", \"b\", \"c\");\n\n    dir.mkdirRecurse;\n    assert(dir.exists);\n\n    deleteme.rmdirRecurse;\n    assert(!dir.exists);\n    assert(!deleteme.exists);\n}\n\nversion (Windows) @system unittest\n{\n    import std.exception : enforce;\n    auto d = deleteme ~ r\".dir\\a\\b\\c\\d\\e\\f\\g\";\n    mkdirRecurse(d);\n    rmdirRecurse(deleteme ~ \".dir\");\n    enforce(!exists(deleteme ~ \".dir\"));\n}\n\nversion (Posix) @system unittest\n{\n    import std.exception : enforce, collectException;\n    import std.process : executeShell;\n    collectException(rmdirRecurse(deleteme));\n    auto d = deleteme~\"/a/b/c/d/e/f/g\";\n    enforce(collectException(mkdir(d)));\n    mkdirRecurse(d);\n    core.sys.posix.unistd.symlink((deleteme~\"/a/b/c\\0\").ptr,\n            (deleteme~\"/link\\0\").ptr);\n    rmdirRecurse(deleteme~\"/link\");\n    enforce(exists(d));\n    rmdirRecurse(deleteme);\n    enforce(!exists(deleteme));\n\n    d = deleteme~\"/a/b/c/d/e/f/g\";\n    mkdirRecurse(d);\n    version (Android) string link_cmd = \"ln -s \";\n    else string link_cmd = \"ln -sf \";\n    executeShell(link_cmd~deleteme~\"/a/b/c \"~deleteme~\"/link\");\n    rmdirRecurse(deleteme);\n    enforce(!exists(deleteme));\n}\n\n@system unittest\n{\n    void[] buf;\n\n    buf = new void[10];\n    (cast(byte[]) buf)[] = 3;\n    string unit_file = deleteme ~ \"-unittest_write.tmp\";\n    if (exists(unit_file)) remove(unit_file);\n    write(unit_file, buf);\n    void[] buf2 = read(unit_file);\n    assert(buf == buf2);\n\n    string unit2_file = deleteme ~ \"-unittest_write2.tmp\";\n    copy(unit_file, unit2_file);\n    buf2 = read(unit2_file);\n    assert(buf == buf2);\n\n    remove(unit_file);\n    assert(!exists(unit_file));\n    remove(unit2_file);\n    assert(!exists(unit2_file));\n}\n\n/**\n * Dictates directory spanning policy for $(D_PARAM dirEntries) (see below).\n */\nenum SpanMode\n{\n    /** Only spans one directory. */\n    shallow,\n    /** Spans the directory in\n     $(HTTPS en.wikipedia.org/wiki/Tree_traversal#Post-order,\n     _depth-first $(B post)-order), i.e. the content of any\n     subdirectory is spanned before that subdirectory itself. Useful\n     e.g. when recursively deleting files.  */\n    depth,\n    /** Spans the directory in\n    $(HTTPS en.wikipedia.org/wiki/Tree_traversal#Pre-order, depth-first\n    $(B pre)-order), i.e. the content of any subdirectory is spanned\n    right after that subdirectory itself.\n\n    Note that `SpanMode.breadth` will not result in all directory\n    members occurring before any subdirectory members, i.e. it is not\n    _true\n    $(HTTPS en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search,\n    _breadth-first traversal).\n    */\n    breadth,\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    import std.path : buildPath, relativePath;\n\n    auto root = deleteme ~ \"root\";\n    scope(exit) root.rmdirRecurse;\n    root.mkdir;\n\n    root.buildPath(\"animals\").mkdir;\n    root.buildPath(\"animals\", \"cat\").mkdir;\n    root.buildPath(\"animals\", \"dog\").mkdir;\n    root.buildPath(\"plants\").mkdir;\n\n    alias removeRoot = (e) => e.relativePath(root);\n\n    root.dirEntries(SpanMode.shallow).map!removeRoot.equal(\n        [\"plants\", \"animals\"]);\n\n    root.dirEntries(SpanMode.depth).map!removeRoot.equal(\n        [\"plants\", \"animals/dog\", \"animals/cat\", \"animals\"]);\n\n    root.dirEntries(SpanMode.breadth).map!removeRoot.equal(\n        [\"plants\", \"animals\", \"animals/dog\", \"animals/cat\"]);\n}\n\nprivate struct DirIteratorImpl\n{\n  @safe:\n    SpanMode _mode;\n    // Whether we should follow symlinked directories while iterating.\n    // It also indicates whether we should avoid functions which call\n    // stat (since we should only need lstat in this case and it would\n    // be more efficient to not call stat in addition to lstat).\n    bool _followSymlink;\n    DirEntry _cur;\n    DirHandle[] _stack;\n    DirEntry[] _stashed; //used in depth first mode\n\n    //stack helpers\n    void pushExtra(DirEntry de)\n    {\n        _stashed ~= de;\n    }\n\n    //ditto\n    bool hasExtra()\n    {\n        return _stashed.length != 0;\n    }\n\n    //ditto\n    DirEntry popExtra()\n    {\n        DirEntry de;\n        de = _stashed[$-1];\n        _stashed.popBack();\n        return de;\n    }\n\n    version (Windows)\n    {\n        WIN32_FIND_DATAW _findinfo;\n        struct DirHandle\n        {\n            string dirpath;\n            HANDLE h;\n        }\n\n        bool stepIn(string directory) @safe\n        {\n            import std.path : chainPath;\n            auto searchPattern = chainPath(directory, \"*.*\");\n\n            static auto trustedFindFirstFileW(typeof(searchPattern) pattern, WIN32_FIND_DATAW* findinfo) @trusted\n            {\n                return FindFirstFileW(pattern.tempCString!FSChar(), findinfo);\n            }\n\n            HANDLE h = trustedFindFirstFileW(searchPattern, &_findinfo);\n            cenforce(h != INVALID_HANDLE_VALUE, directory);\n            _stack ~= DirHandle(directory, h);\n            return toNext(false, &_findinfo);\n        }\n\n        bool next()\n        {\n            if (_stack.length == 0)\n                return false;\n            return toNext(true, &_findinfo);\n        }\n\n        bool toNext(bool fetch, WIN32_FIND_DATAW* findinfo) @trusted\n        {\n            import core.stdc.wchar_ : wcscmp;\n\n            if (fetch)\n            {\n                if (FindNextFileW(_stack[$-1].h, findinfo) == FALSE)\n                {\n                    popDirStack();\n                    return false;\n                }\n            }\n            while (wcscmp(&findinfo.cFileName[0], \".\") == 0 ||\n                   wcscmp(&findinfo.cFileName[0], \"..\") == 0)\n                if (FindNextFileW(_stack[$-1].h, findinfo) == FALSE)\n                {\n                    popDirStack();\n                    return false;\n                }\n            _cur = DirEntry(_stack[$-1].dirpath, findinfo);\n            return true;\n        }\n\n        void popDirStack() @trusted\n        {\n            assert(_stack.length != 0);\n            FindClose(_stack[$-1].h);\n            _stack.popBack();\n        }\n\n        void releaseDirStack() @trusted\n        {\n            foreach (d; _stack)\n                FindClose(d.h);\n        }\n\n        bool mayStepIn()\n        {\n            return _followSymlink ? _cur.isDir : _cur.isDir && !_cur.isSymlink;\n        }\n    }\n    else version (Posix)\n    {\n        struct DirHandle\n        {\n            string dirpath;\n            DIR*   h;\n        }\n\n        bool stepIn(string directory)\n        {\n            static auto trustedOpendir(string dir) @trusted\n            {\n                return opendir(dir.tempCString());\n            }\n\n            auto h = directory.length ? trustedOpendir(directory) : trustedOpendir(\".\");\n            cenforce(h, directory);\n            _stack ~= (DirHandle(directory, h));\n            return next();\n        }\n\n        bool next() @trusted\n        {\n            if (_stack.length == 0)\n                return false;\n\n            for (dirent* fdata; (fdata = readdir(_stack[$-1].h)) != null; )\n            {\n                // Skip \".\" and \"..\"\n                if (core.stdc.string.strcmp(&fdata.d_name[0], \".\") &&\n                    core.stdc.string.strcmp(&fdata.d_name[0], \"..\"))\n                {\n                    _cur = DirEntry(_stack[$-1].dirpath, fdata);\n                    return true;\n                }\n            }\n\n            popDirStack();\n            return false;\n        }\n\n        void popDirStack() @trusted\n        {\n            assert(_stack.length != 0);\n            closedir(_stack[$-1].h);\n            _stack.popBack();\n        }\n\n        void releaseDirStack() @trusted\n        {\n            foreach (d; _stack)\n                closedir(d.h);\n        }\n\n        bool mayStepIn()\n        {\n            return _followSymlink ? _cur.isDir : attrIsDir(_cur.linkAttributes);\n        }\n    }\n\n    this(R)(R pathname, SpanMode mode, bool followSymlink)\n        if (isInputRange!R && isSomeChar!(ElementEncodingType!R))\n    {\n        _mode = mode;\n        _followSymlink = followSymlink;\n\n        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))\n            alias pathnameStr = pathname;\n        else\n        {\n            import std.array : array;\n            string pathnameStr = pathname.array;\n        }\n        if (stepIn(pathnameStr))\n        {\n            if (_mode == SpanMode.depth)\n                while (mayStepIn())\n                {\n                    auto thisDir = _cur;\n                    if (stepIn(_cur.name))\n                    {\n                        pushExtra(thisDir);\n                    }\n                    else\n                        break;\n                }\n        }\n    }\n\n    @property bool empty()\n    {\n        return _stashed.length == 0 && _stack.length == 0;\n    }\n\n    @property DirEntry front()\n    {\n        return _cur;\n    }\n\n    void popFront()\n    {\n        switch (_mode)\n        {\n        case SpanMode.depth:\n            if (next())\n            {\n                while (mayStepIn())\n                {\n                    auto thisDir = _cur;\n                    if (stepIn(_cur.name))\n                    {\n                        pushExtra(thisDir);\n                    }\n                    else\n                        break;\n                }\n            }\n            else if (hasExtra())\n                _cur = popExtra();\n            break;\n        case SpanMode.breadth:\n            if (mayStepIn())\n            {\n                if (!stepIn(_cur.name))\n                    while (!empty && !next()){}\n            }\n            else\n                while (!empty && !next()){}\n            break;\n        default:\n            next();\n        }\n    }\n\n    ~this()\n    {\n        releaseDirStack();\n    }\n}\n\nstruct DirIterator\n{\n@safe:\nprivate:\n    RefCounted!(DirIteratorImpl, RefCountedAutoInitialize.no) impl = void;\n    this(string pathname, SpanMode mode, bool followSymlink) @trusted\n    {\n        impl = typeof(impl)(pathname, mode, followSymlink);\n    }\npublic:\n    @property bool empty() { return impl.empty; }\n    @property DirEntry front() { return impl.front; }\n    void popFront() { impl.popFront(); }\n}\n/++\n    Returns an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    of `DirEntry` that lazily iterates a given directory,\n    also provides two ways of foreach iteration. The iteration variable can be of\n    type `string` if only the name is needed, or `DirEntry`\n    if additional details are needed. The span _mode dictates how the\n    directory is traversed. The name of each iterated directory entry\n    contains the absolute or relative _path (depending on _pathname).\n\n    Params:\n        path = The directory to iterate over.\n               If empty, the current directory will be iterated.\n\n        pattern = Optional string with wildcards, such as $(RED\n                  \"*.d\"). When present, it is used to filter the\n                  results by their file name. The supported wildcard\n                  strings are described under $(REF globMatch,\n                  std,_path).\n\n        mode = Whether the directory's sub-directories should be\n               iterated in depth-first port-order ($(LREF depth)),\n               depth-first pre-order ($(LREF breadth)), or not at all\n               ($(LREF shallow)).\n\n        followSymlink = Whether symbolic links which point to directories\n                         should be treated as directories and their contents\n                         iterated over.\n\n    Returns:\n        An $(REF_ALTTEXT input range, isInputRange,std,range,primitives) of\n        $(LREF DirEntries).\n\n    Throws:\n        $(LREF FileException) if the directory does not exist.\n\nExample:\n--------------------\n// Iterate a directory in depth\nforeach (string name; dirEntries(\"destroy/me\", SpanMode.depth))\n{\n    remove(name);\n}\n\n// Iterate the current directory in breadth\nforeach (string name; dirEntries(\"\", SpanMode.breadth))\n{\n    writeln(name);\n}\n\n// Iterate a directory and get detailed info about it\nforeach (DirEntry e; dirEntries(\"dmd-testing\", SpanMode.breadth))\n{\n    writeln(e.name, \"\\t\", e.size);\n}\n\n// Iterate over all *.d files in current directory and all its subdirectories\nauto dFiles = dirEntries(\"\", SpanMode.depth).filter!(f => f.name.endsWith(\".d\"));\nforeach (d; dFiles)\n    writeln(d.name);\n\n// Hook it up with std.parallelism to compile them all in parallel:\nforeach (d; parallel(dFiles, 1)) //passes by 1 file to each thread\n{\n    string cmd = \"dmd -c \"  ~ d.name;\n    writeln(cmd);\n    std.process.system(cmd);\n}\n\n// Iterate over all D source files in current directory and all its\n// subdirectories\nauto dFiles = dirEntries(\"\",\"*.{d,di}\",SpanMode.depth);\nforeach (d; dFiles)\n    writeln(d.name);\n--------------------\n +/\nauto dirEntries(string path, SpanMode mode, bool followSymlink = true)\n{\n    return DirIterator(path, mode, followSymlink);\n}\n\n/// Duplicate functionality of D1's `std.file.listdir()`:\n@safe unittest\n{\n    string[] listdir(string pathname)\n    {\n        import std.algorithm;\n        import std.array;\n        import std.file;\n        import std.path;\n\n        return std.file.dirEntries(pathname, SpanMode.shallow)\n            .filter!(a => a.isFile)\n            .map!(a => std.path.baseName(a.name))\n            .array;\n    }\n\n    void main(string[] args)\n    {\n        import std.stdio;\n\n        string[] files = listdir(args[1]);\n        writefln(\"%s\", files);\n     }\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    import std.algorithm.searching : startsWith;\n    import std.array : array;\n    import std.conv : to;\n    import std.path : buildPath, absolutePath;\n    import std.file : dirEntries;\n    import std.process : thisProcessID;\n    import std.range.primitives : walkLength;\n\n    version (Android)\n        string testdir = deleteme; // This has to be an absolute path when\n                                   // called from a shared library on Android,\n                                   // ie an apk\n    else\n        string testdir = \"deleteme.dmd.unittest.std.file\" ~ to!string(thisProcessID); // needs to be relative\n    mkdirRecurse(buildPath(testdir, \"somedir\"));\n    scope(exit) rmdirRecurse(testdir);\n    write(buildPath(testdir, \"somefile\"), null);\n    write(buildPath(testdir, \"somedir\", \"somedeepfile\"), null);\n\n    // testing range interface\n    size_t equalEntries(string relpath, SpanMode mode)\n    {\n        import std.exception : enforce;\n        auto len = enforce(walkLength(dirEntries(absolutePath(relpath), mode)));\n        assert(walkLength(dirEntries(relpath, mode)) == len);\n        assert(equal(\n                   map!(a => absolutePath(a.name))(dirEntries(relpath, mode)),\n                   map!(a => a.name)(dirEntries(absolutePath(relpath), mode))));\n        return len;\n    }\n\n    assert(equalEntries(testdir, SpanMode.shallow) == 2);\n    assert(equalEntries(testdir, SpanMode.depth) == 3);\n    assert(equalEntries(testdir, SpanMode.breadth) == 3);\n\n    // testing opApply\n    foreach (string name; dirEntries(testdir, SpanMode.breadth))\n    {\n        //writeln(name);\n        assert(name.startsWith(testdir));\n    }\n    foreach (DirEntry e; dirEntries(absolutePath(testdir), SpanMode.breadth))\n    {\n        //writeln(name);\n        assert(e.isFile || e.isDir, e.name);\n    }\n\n    //issue 7264\n    foreach (string name; dirEntries(testdir, \"*.d\", SpanMode.breadth))\n    {\n\n    }\n    foreach (entry; dirEntries(testdir, SpanMode.breadth))\n    {\n        static assert(is(typeof(entry) == DirEntry));\n    }\n    //issue 7138\n    auto a = array(dirEntries(testdir, SpanMode.shallow));\n\n    // issue 11392\n    auto dFiles = dirEntries(testdir, SpanMode.shallow);\n    foreach (d; dFiles){}\n\n    // issue 15146\n    dirEntries(\"\", SpanMode.shallow).walkLength();\n}\n\n/// Ditto\nauto dirEntries(string path, string pattern, SpanMode mode,\n    bool followSymlink = true)\n{\n    import std.algorithm.iteration : filter;\n    import std.path : globMatch, baseName;\n\n    bool f(DirEntry de) { return globMatch(baseName(de.name), pattern); }\n    return filter!f(DirIterator(path, mode, followSymlink));\n}\n\n@system unittest\n{\n    import std.stdio : writefln;\n    immutable dpath = deleteme ~ \"_dir\";\n    immutable fpath = deleteme ~ \"_file\";\n    immutable sdpath = deleteme ~ \"_sdir\";\n    immutable sfpath = deleteme ~ \"_sfile\";\n    scope(exit)\n    {\n        if (dpath.exists) rmdirRecurse(dpath);\n        if (fpath.exists) remove(fpath);\n        if (sdpath.exists) remove(sdpath);\n        if (sfpath.exists) remove(sfpath);\n    }\n\n    mkdir(dpath);\n    write(fpath, \"hello world\");\n    version (Posix)\n    {\n        core.sys.posix.unistd.symlink((dpath ~ '\\0').ptr, (sdpath ~ '\\0').ptr);\n        core.sys.posix.unistd.symlink((fpath ~ '\\0').ptr, (sfpath ~ '\\0').ptr);\n    }\n\n    static struct Flags { bool dir, file, link; }\n    auto tests = [dpath : Flags(true), fpath : Flags(false, true)];\n    version (Posix)\n    {\n        tests[sdpath] = Flags(true, false, true);\n        tests[sfpath] = Flags(false, true, true);\n    }\n\n    auto past = Clock.currTime() - 2.seconds;\n    auto future = past + 4.seconds;\n\n    foreach (path, flags; tests)\n    {\n        auto de = DirEntry(path);\n        assert(de.name == path);\n        assert(de.isDir == flags.dir);\n        assert(de.isFile == flags.file);\n        assert(de.isSymlink == flags.link);\n\n        assert(de.isDir == path.isDir);\n        assert(de.isFile == path.isFile);\n        assert(de.isSymlink == path.isSymlink);\n        assert(de.size == path.getSize());\n        assert(de.attributes == getAttributes(path));\n        assert(de.linkAttributes == getLinkAttributes(path));\n\n        scope(failure) writefln(\"[%s] [%s] [%s] [%s]\", past, de.timeLastAccessed, de.timeLastModified, future);\n        assert(de.timeLastAccessed > past);\n        assert(de.timeLastAccessed < future);\n        assert(de.timeLastModified > past);\n        assert(de.timeLastModified < future);\n\n        assert(attrIsDir(de.attributes) == flags.dir);\n        assert(attrIsDir(de.linkAttributes) == (flags.dir && !flags.link));\n        assert(attrIsFile(de.attributes) == flags.file);\n        assert(attrIsFile(de.linkAttributes) == (flags.file && !flags.link));\n        assert(!attrIsSymlink(de.attributes));\n        assert(attrIsSymlink(de.linkAttributes) == flags.link);\n\n        version (Windows)\n        {\n            assert(de.timeCreated > past);\n            assert(de.timeCreated < future);\n        }\n        else version (Posix)\n        {\n            assert(de.timeStatusChanged > past);\n            assert(de.timeStatusChanged < future);\n            assert(de.attributes == de.statBuf.st_mode);\n        }\n    }\n}\n\n// Bugzilla 17962 - Make sure that dirEntries does not butcher Unicode file names.\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    import std.algorithm.sorting : sort;\n    import std.array : array;\n    import std.path : buildPath;\n    import std.uni : normalize;\n\n    // The Unicode normalization is required to make the tests pass on Mac OS X.\n    auto dir = deleteme ~ normalize(\"𐐷\");\n    scope(exit) if (dir.exists) rmdirRecurse(dir);\n    mkdir(dir);\n    auto files = [\"Hello World\",\n                  \"Ma Chérie.jpeg\",\n                  \"さいごの果実.txt\"].map!(a => buildPath(dir, normalize(a)))().array();\n    sort(files);\n    foreach (file; files)\n        write(file, \"nothing\");\n\n    auto result = dirEntries(dir, SpanMode.shallow).map!(a => a.name.normalize()).array();\n    sort(result);\n\n    assert(equal(files, result));\n}\n\n\n/**\n * Reads a file line by line and parses the line into a single value or a\n * $(REF Tuple, std,typecons) of values depending on the length of `Types`.\n * The lines are parsed using the specified format string. The format string is\n * passed to $(REF formattedRead, std,_format), and therefore must conform to the\n * _format string specification outlined in $(MREF std, _format).\n *\n * Params:\n *     Types = the types that each of the elements in the line should be returned as\n *     filename = the name of the file to read\n *     format = the _format string to use when reading\n *\n * Returns:\n *     If only one type is passed, then an array of that type. Otherwise, an\n *     array of $(REF Tuple, std,typecons)s.\n *\n * Throws:\n *     `Exception` if the format string is malformed. Also, throws `Exception`\n *     if any of the lines in the file are not fully consumed by the call\n *     to $(REF formattedRead, std,_format). Meaning that no empty lines or lines\n *     with extra characters are allowed.\n */\nSelect!(Types.length == 1, Types[0][], Tuple!(Types)[])\nslurp(Types...)(string filename, scope const(char)[] format)\n{\n    import std.array : appender;\n    import std.conv : text;\n    import std.exception : enforce;\n    import std.format : formattedRead;\n    import std.stdio : File;\n    import std.string : stripRight;\n\n    auto app = appender!(typeof(return))();\n    ElementType!(typeof(return)) toAdd;\n    auto f = File(filename);\n    scope(exit) f.close();\n    foreach (line; f.byLine())\n    {\n        formattedRead(line, format, &toAdd);\n        enforce(line.stripRight(\"\\r\").empty,\n                text(\"Trailing characters at the end of line: `\", line,\n                        \"'\"));\n        app.put(toAdd);\n    }\n    return app.data;\n}\n\n///\n@system unittest\n{\n    import std.typecons : tuple;\n\n    scope(exit)\n    {\n        assert(exists(deleteme));\n        remove(deleteme);\n    }\n\n    write(deleteme, \"12 12.25\\n345 1.125\"); // deleteme is the name of a temporary file\n\n    // Load file; each line is an int followed by comma, whitespace and a\n    // double.\n    auto a = slurp!(int, double)(deleteme, \"%s %s\");\n    assert(a.length == 2);\n    assert(a[0] == tuple(12, 12.25));\n    assert(a[1] == tuple(345, 1.125));\n}\n\n@system unittest\n{\n    import std.typecons : tuple;\n\n    scope(exit)\n    {\n        assert(exists(deleteme));\n        remove(deleteme);\n    }\n    write(deleteme, \"10\\r\\n20\");\n    assert(slurp!(int)(deleteme, \"%d\") == [10, 20]);\n}\n\n\n/**\nReturns the path to a directory for temporary files.\n\nThe return value of the function is cached, so the procedures described\nbelow will only be performed the first time the function is called.  All\nsubsequent runs will return the same string, regardless of whether\nenvironment variables and directory structures have changed in the\nmeantime.\n\nThe POSIX `tempDir` algorithm is inspired by Python's\n$(LINK2 http://docs.python.org/library/tempfile.html#tempfile.tempdir, `tempfile.tempdir`).\n\nReturns:\n    On Windows, this function returns the result of calling the Windows API function\n    $(LINK2 http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992.aspx, `GetTempPath`).\n\n    On POSIX platforms, it searches through the following list of directories\n    and returns the first one which is found to exist:\n    $(OL\n        $(LI The directory given by the `TMPDIR` environment variable.)\n        $(LI The directory given by the `TEMP` environment variable.)\n        $(LI The directory given by the `TMP` environment variable.)\n        $(LI `/tmp`)\n        $(LI `/var/tmp`)\n        $(LI `/usr/tmp`)\n    )\n\n    On all platforms, `tempDir` returns `\".\"` on failure, representing\n    the current working directory.\n*/\nstring tempDir() @trusted\n{\n    static string cache;\n    if (cache is null)\n    {\n        version (Windows)\n        {\n            import std.conv : to;\n            // http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992(v=vs.85).aspx\n            wchar[MAX_PATH + 2] buf;\n            DWORD len = GetTempPathW(buf.length, buf.ptr);\n            if (len) cache = buf[0 .. len].to!string;\n        }\n        else version (Posix)\n        {\n            import std.process : environment;\n            // This function looks through the list of alternative directories\n            // and returns the first one which exists and is a directory.\n            static string findExistingDir(T...)(lazy T alternatives)\n            {\n                foreach (dir; alternatives)\n                    if (!dir.empty && exists(dir)) return dir;\n                return null;\n            }\n\n            cache = findExistingDir(environment.get(\"TMPDIR\"),\n                                    environment.get(\"TEMP\"),\n                                    environment.get(\"TMP\"),\n                                    \"/tmp\",\n                                    \"/var/tmp\",\n                                    \"/usr/tmp\");\n        }\n        else static assert(false, \"Unsupported platform\");\n\n        if (cache is null) cache = getcwd();\n    }\n    return cache;\n}\n\n///\n@safe unittest\n{\n    import std.ascii : letters;\n    import std.conv : to;\n    import std.path : buildPath;\n    import std.random : randomSample;\n    import std.utf : byCodeUnit;\n\n    // random id with 20 letters\n    auto id = letters.byCodeUnit.randomSample(20).to!string;\n    auto myFile = tempDir.buildPath(id ~ \"my_tmp_file\");\n    scope(exit) myFile.remove;\n\n    myFile.write(\"hello\");\n    assert(myFile.readText == \"hello\");\n}\n"
  },
  {
    "path": "libphobos/src/std/format.d",
    "content": "// Written in the D programming language.\n\n/**\n   This module implements the formatting functionality for strings and\n   I/O. It's comparable to C99's `vsprintf()` and uses a similar\n   _format encoding scheme.\n\n   For an introductory look at $(B std._format)'s capabilities and how to use\n   this module see the dedicated\n   $(LINK2 http://wiki.dlang.org/Defining_custom_print_format_specifiers, DWiki article).\n\n   This module centers around two functions:\n\n$(BOOKTABLE ,\n$(TR $(TH Function Name) $(TH Description)\n)\n    $(TR $(TD $(LREF formattedRead))\n        $(TD Reads values according to the format string from an InputRange.\n    ))\n    $(TR $(TD $(LREF formattedWrite))\n        $(TD Formats its arguments according to the format string and puts them\n        to an OutputRange.\n    ))\n)\n\n   Please see the documentation of function $(LREF formattedWrite) for a\n   description of the format string.\n\n   Two functions have been added for convenience:\n\n$(BOOKTABLE ,\n$(TR $(TH Function Name) $(TH Description)\n)\n    $(TR $(TD $(LREF format))\n        $(TD Returns a GC-allocated string with the formatting result.\n    ))\n    $(TR $(TD $(LREF sformat))\n        $(TD Puts the formatting result into a preallocated array.\n    ))\n)\n\n   These two functions are publicly imported by $(MREF std, string)\n   to be easily available.\n\n   The functions $(LREF formatValue) and $(LREF unformatValue) are\n   used for the plumbing.\n   Copyright: Copyright The D Language Foundation 2000-2013.\n\n   License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\n   Authors: $(HTTP walterbright.com, Walter Bright), $(HTTP erdani.com,\n   Andrei Alexandrescu), and Kenji Hara\n\n   Source: $(PHOBOSSRC std/format.d)\n */\nmodule std.format;\n\n//debug=format;                // uncomment to turn on debugging printf's\n\nimport core.vararg;\nimport std.exception;\nimport std.meta;\nimport std.range.primitives;\nimport std.traits;\n\n\n/**\nSignals a mismatch between a format and its corresponding argument.\n */\nclass FormatException : Exception\n{\n    @safe @nogc pure nothrow\n    this()\n    {\n        super(\"format error\");\n    }\n\n    @safe @nogc pure nothrow\n    this(string msg, string fn = __FILE__, size_t ln = __LINE__, Throwable next = null)\n    {\n        super(msg, fn, ln, next);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    assertThrown!FormatException(format(\"%d\", \"foo\"));\n}\n\nprivate alias enforceFmt = enforce!FormatException;\n\n\n/**********************************************************************\n   Interprets variadic argument list `args`, formats them according\n   to `fmt`, and sends the resulting characters to `w`. The\n   encoding of the output is the same as `Char`. The type `Writer`\n   must satisfy $(D $(REF isOutputRange, std,range,primitives)!(Writer, Char)).\n\n   The variadic arguments are normally consumed in order. POSIX-style\n   $(HTTP opengroup.org/onlinepubs/009695399/functions/printf.html,\n   positional parameter syntax) is also supported. Each argument is\n   formatted into a sequence of chars according to the format\n   specification, and the characters are passed to `w`. As many\n   arguments as specified in the format string are consumed and\n   formatted. If there are fewer arguments than format specifiers, a\n   `FormatException` is thrown. If there are more remaining arguments\n   than needed by the format specification, they are ignored but only\n   if at least one argument was formatted.\n\n   The format string supports the formatting of array and nested array elements\n   via the grouping format specifiers $(B %&#40;) and $(B %&#41;). Each\n   matching pair of $(B %&#40;) and $(B %&#41;) corresponds with a single array\n   argument. The enclosed sub-format string is applied to individual array\n   elements.  The trailing portion of the sub-format string following the\n   conversion specifier for the array element is interpreted as the array\n   delimiter, and is therefore omitted following the last array element. The\n   $(B %|) specifier may be used to explicitly indicate the start of the\n   delimiter, so that the preceding portion of the string will be included\n   following the last array element.  (See below for explicit examples.)\n\n   Params:\n\n   w = Output is sent to this writer. Typical output writers include\n   $(REF Appender!string, std,array) and $(REF LockingTextWriter, std,stdio).\n\n   fmt = Format string.\n\n   args = Variadic argument list.\n\n   Returns: Formatted number of arguments.\n\n   Throws: Mismatched arguments and formats result in a $(D\n   FormatException) being thrown.\n\n   Format_String: <a name=\"format-string\">$(I Format strings)</a>\n   consist of characters interspersed with $(I format\n   specifications). Characters are simply copied to the output (such\n   as putc) after any necessary conversion to the corresponding UTF-8\n   sequence.\n\n   The format string has the following grammar:\n\n$(PRE\n$(I FormatString):\n    $(I FormatStringItem)*\n$(I FormatStringItem):\n    $(B '%%')\n    $(B '%') $(I Position) $(I Flags) $(I Width) $(I Separator) $(I Precision) $(I FormatChar)\n    $(B '%$(LPAREN)') $(I FormatString) $(B '%$(RPAREN)')\n    $(I OtherCharacterExceptPercent)\n$(I Position):\n    $(I empty)\n    $(I Integer) $(B '$')\n$(I Flags):\n    $(I empty)\n    $(B '-') $(I Flags)\n    $(B '+') $(I Flags)\n    $(B '#') $(I Flags)\n    $(B '0') $(I Flags)\n    $(B ' ') $(I Flags)\n$(I Width):\n    $(I empty)\n    $(I Integer)\n    $(B '*')\n$(I Separator):\n    $(I empty)\n    $(B ',')\n    $(B ',') $(B '?')\n    $(B ',') $(B '*') $(B '?')\n    $(B ',') $(I Integer) $(B '?')\n    $(B ',') $(B '*')\n    $(B ',') $(I Integer)\n$(I Precision):\n    $(I empty)\n    $(B '.')\n    $(B '.') $(I Integer)\n    $(B '.*')\n$(I Integer):\n    $(I Digit)\n    $(I Digit) $(I Integer)\n$(I Digit):\n    $(B '0')|$(B '1')|$(B '2')|$(B '3')|$(B '4')|$(B '5')|$(B '6')|$(B '7')|$(B '8')|$(B '9')\n$(I FormatChar):\n    $(B 's')|$(B 'c')|$(B 'b')|$(B 'd')|$(B 'o')|$(B 'x')|$(B 'X')|$(B 'e')|$(B 'E')|$(B 'f')|$(B 'F')|$(B 'g')|$(B 'G')|$(B 'a')|$(B 'A')|$(B '|')\n)\n\n    $(BOOKTABLE Flags affect formatting depending on the specifier as\n    follows., $(TR $(TH Flag) $(TH Types&nbsp;affected) $(TH Semantics))\n\n    $(TR $(TD $(B '-')) $(TD numeric) $(TD Left justify the result in\n        the field.  It overrides any $(B 0) flag.))\n\n    $(TR $(TD $(B '+')) $(TD numeric) $(TD Prefix positive numbers in\n    a signed conversion with a $(B +).  It overrides any $(I space)\n    flag.))\n\n    $(TR $(TD $(B '#')) $(TD integral ($(B 'o'))) $(TD Add to\n    precision as necessary so that the first digit of the octal\n    formatting is a '0', even if both the argument and the $(I\n    Precision) are zero.))\n\n    $(TR $(TD $(B '#')) $(TD integral ($(B 'x'), $(B 'X'))) $(TD If\n       non-zero, prefix result with $(B 0x) ($(B 0X)).))\n\n    $(TR $(TD $(B '#')) $(TD floating) $(TD Always insert the decimal\n       point and print trailing zeros.))\n\n    $(TR $(TD $(B '0')) $(TD numeric) $(TD Use leading\n    zeros to pad rather than spaces (except for the floating point\n    values `nan` and `infinity`).  Ignore if there's a $(I\n    Precision).))\n\n    $(TR $(TD $(B ' ')) $(TD numeric) $(TD Prefix positive\n    numbers in a signed conversion with a space.)))\n\n    $(DL\n        $(DT $(I Width))\n        $(DD\n        Specifies the minimum field width.\n        If the width is a $(B *), an additional argument of type $(B int),\n        preceding the actual argument, is taken as the width.\n        If the width is negative, it is as if the $(B -) was given\n        as a $(I Flags) character.)\n\n        $(DT $(I Precision))\n        $(DD Gives the precision for numeric conversions.\n        If the precision is a $(B *), an additional argument of type $(B int),\n        preceding the actual argument, is taken as the precision.\n        If it is negative, it is as if there was no $(I Precision) specifier.)\n\n        $(DT $(I Separator))\n        $(DD Inserts the separator symbols ',' every $(I X) digits, from right\n        to left, into numeric values to increase readability.\n        The fractional part of floating point values inserts the separator\n        from left to right.\n        Entering an integer after the ',' allows to specify $(I X).\n        If a '*' is placed after the ',' then $(I X) is specified by an\n        additional parameter to the format function.\n        Adding a '?' after the ',' or $(I X) specifier allows to specify\n        the separator character as an additional parameter.\n        )\n\n        $(DT $(I FormatChar))\n        $(DD\n        $(DL\n            $(DT $(B 's'))\n            $(DD The corresponding argument is formatted in a manner consistent\n            with its type:\n            $(DL\n                $(DT $(B bool))\n                $(DD The result is `\"true\"` or `\"false\"`.)\n                $(DT integral types)\n                $(DD The $(B %d) format is used.)\n                $(DT floating point types)\n                $(DD The $(B %g) format is used.)\n                $(DT string types)\n                $(DD The result is the string converted to UTF-8.\n                A $(I Precision) specifies the maximum number of characters\n                to use in the result.)\n                $(DT structs)\n                $(DD If the struct defines a $(B toString()) method the result is\n                the string returned from this function. Otherwise the result is\n                StructName(field<sub>0</sub>, field<sub>1</sub>, ...) where\n                field<sub>n</sub> is the nth element formatted with the default\n                format.)\n                $(DT classes derived from $(B Object))\n                $(DD The result is the string returned from the class instance's\n                $(B .toString()) method.\n                A $(I Precision) specifies the maximum number of characters\n                to use in the result.)\n                $(DT unions)\n                $(DD If the union defines a $(B toString()) method the result is\n                the string returned from this function. Otherwise the result is\n                the name of the union, without its contents.)\n                $(DT non-string static and dynamic arrays)\n                $(DD The result is [s<sub>0</sub>, s<sub>1</sub>, ...]\n                where s<sub>n</sub> is the nth element\n                formatted with the default format.)\n                $(DT associative arrays)\n                $(DD The result is the equivalent of what the initializer\n                would look like for the contents of the associative array,\n                e.g.: [\"red\" : 10, \"blue\" : 20].)\n            ))\n\n            $(DT $(B 'c'))\n            $(DD The corresponding argument must be a character type.)\n\n            $(DT $(B 'b','d','o','x','X'))\n            $(DD The corresponding argument must be an integral type\n            and is formatted as an integer. If the argument is a signed type\n            and the $(I FormatChar) is $(B d) it is converted to\n            a signed string of characters, otherwise it is treated as\n            unsigned. An argument of type $(B bool) is formatted as '1'\n            or '0'. The base used is binary for $(B b), octal for $(B o),\n            decimal\n            for $(B d), and hexadecimal for $(B x) or $(B X).\n            $(B x) formats using lower case letters, $(B X) uppercase.\n            If there are fewer resulting digits than the $(I Precision),\n            leading zeros are used as necessary.\n            If the $(I Precision) is 0 and the number is 0, no digits\n            result.)\n\n            $(DT $(B 'e','E'))\n            $(DD A floating point number is formatted as one digit before\n            the decimal point, $(I Precision) digits after, the $(I FormatChar),\n            &plusmn;, followed by at least a two digit exponent:\n            $(I d.dddddd)e$(I &plusmn;dd).\n            If there is no $(I Precision), six\n            digits are generated after the decimal point.\n            If the $(I Precision) is 0, no decimal point is generated.)\n\n            $(DT $(B 'f','F'))\n            $(DD A floating point number is formatted in decimal notation.\n            The $(I Precision) specifies the number of digits generated\n            after the decimal point. It defaults to six. At least one digit\n            is generated before the decimal point. If the $(I Precision)\n            is zero, no decimal point is generated.)\n\n            $(DT $(B 'g','G'))\n            $(DD A floating point number is formatted in either $(B e) or\n            $(B f) format for $(B g); $(B E) or $(B F) format for\n            $(B G).\n            The $(B f) format is used if the exponent for an $(B e) format\n            is greater than -5 and less than the $(I Precision).\n            The $(I Precision) specifies the number of significant\n            digits, and defaults to six.\n            Trailing zeros are elided after the decimal point, if the fractional\n            part is zero then no decimal point is generated.)\n\n            $(DT $(B 'a','A'))\n            $(DD A floating point number is formatted in hexadecimal\n            exponential notation 0x$(I h.hhhhhh)p$(I &plusmn;d).\n            There is one hexadecimal digit before the decimal point, and as\n            many after as specified by the $(I Precision).\n            If the $(I Precision) is zero, no decimal point is generated.\n            If there is no $(I Precision), as many hexadecimal digits as\n            necessary to exactly represent the mantissa are generated.\n            The exponent is written in as few digits as possible,\n            but at least one, is in decimal, and represents a power of 2 as in\n            $(I h.hhhhhh)*2<sup>$(I &plusmn;d)</sup>.\n            The exponent for zero is zero.\n            The hexadecimal digits, x and p are in upper case if the\n            $(I FormatChar) is upper case.)\n        ))\n    )\n\n    Floating point NaN's are formatted as $(B nan) if the\n    $(I FormatChar) is lower case, or $(B NAN) if upper.\n    Floating point infinities are formatted as $(B inf) or\n    $(B infinity) if the\n    $(I FormatChar) is lower case, or $(B INF) or $(B INFINITY) if upper.\n\n    The positional and non-positional styles can be mixed in the same\n    format string. (POSIX leaves this behavior undefined.) The internal\n    counter for non-positional parameters tracks the next parameter after\n    the largest positional parameter already used.\n\n    Example using array and nested array formatting:\n    -------------------------\n    import std.stdio;\n\n    void main()\n    {\n        writefln(\"My items are %(%s %).\", [1,2,3]);\n        writefln(\"My items are %(%s, %).\", [1,2,3]);\n    }\n    -------------------------\n    The output is:\n$(CONSOLE\nMy items are 1 2 3.\nMy items are 1, 2, 3.\n)\n\n    The trailing end of the sub-format string following the specifier for each\n    item is interpreted as the array delimiter, and is therefore omitted\n    following the last array item. The $(B %|) delimiter specifier may be used\n    to indicate where the delimiter begins, so that the portion of the format\n    string prior to it will be retained in the last array element:\n    -------------------------\n    import std.stdio;\n\n    void main()\n    {\n        writefln(\"My items are %(-%s-%|, %).\", [1,2,3]);\n    }\n    -------------------------\n    which gives the output:\n$(CONSOLE\nMy items are -1-, -2-, -3-.\n)\n\n    These compound format specifiers may be nested in the case of a nested\n    array argument:\n    -------------------------\n    import std.stdio;\n    void main() {\n         auto mat = [[1, 2, 3],\n                     [4, 5, 6],\n                     [7, 8, 9]];\n\n         writefln(\"%(%(%d %)\\n%)\", mat);\n         writeln();\n\n         writefln(\"[%(%(%d %)\\n %)]\", mat);\n         writeln();\n\n         writefln(\"[%([%(%d %)]%|\\n %)]\", mat);\n         writeln();\n    }\n    -------------------------\n    The output is:\n$(CONSOLE\n1 2 3\n4 5 6\n7 8 9\n\n[1 2 3\n 4 5 6\n 7 8 9]\n\n[[1 2 3]\n [4 5 6]\n [7 8 9]]\n)\n\n    Inside a compound format specifier, strings and characters are escaped\n    automatically. To avoid this behavior, add $(B '-') flag to\n    `\"%$(LPAREN)\"`.\n    -------------------------\n    import std.stdio;\n\n    void main()\n    {\n        writefln(\"My friends are %s.\", [\"John\", \"Nancy\"]);\n        writefln(\"My friends are %(%s, %).\", [\"John\", \"Nancy\"]);\n        writefln(\"My friends are %-(%s, %).\", [\"John\", \"Nancy\"]);\n    }\n    -------------------------\n   which gives the output:\n$(CONSOLE\nMy friends are [\"John\", \"Nancy\"].\nMy friends are \"John\", \"Nancy\".\nMy friends are John, Nancy.\n)\n */\nuint formattedWrite(alias fmt, Writer, A...)(auto ref Writer w, A args)\nif (isSomeString!(typeof(fmt)))\n{\n    alias e = checkFormatException!(fmt, A);\n    static assert(!e, e.msg);\n    return .formattedWrite(w, fmt, args);\n}\n\n/// The format string can be checked at compile-time (see $(LREF format) for details):\n@safe pure unittest\n{\n    import std.array : appender;\n\n    auto writer = appender!string();\n    writer.formattedWrite!\"%s is the ultimate %s.\"(42, \"answer\");\n    assert(writer.data == \"42 is the ultimate answer.\");\n\n    // Clear the writer\n    writer = appender!string();\n    formattedWrite(writer, \"Date: %2$s %1$s\", \"October\", 5);\n    assert(writer.data == \"Date: 5 October\");\n}\n\n/// ditto\nuint formattedWrite(Writer, Char, A...)(auto ref Writer w, in Char[] fmt, A args)\n{\n    import std.conv : text;\n\n    auto spec = FormatSpec!Char(fmt);\n\n    // Are we already done with formats? Then just dump each parameter in turn\n    uint currentArg = 0;\n    while (spec.writeUpToNextSpec(w))\n    {\n        if (currentArg == A.length && !spec.indexStart)\n        {\n            // leftover spec?\n            enforceFmt(fmt.length == 0,\n                text(\"Orphan format specifier: %\", spec.spec));\n            break;\n        }\n\n        if (spec.width == spec.DYNAMIC)\n        {\n            auto width = getNthInt!\"integer width\"(currentArg, args);\n            if (width < 0)\n            {\n                spec.flDash = true;\n                width = -width;\n            }\n            spec.width = width;\n            ++currentArg;\n        }\n        else if (spec.width < 0)\n        {\n            // means: get width as a positional parameter\n            auto index = cast(uint) -spec.width;\n            assert(index > 0);\n            auto width = getNthInt!\"integer width\"(index - 1, args);\n            if (currentArg < index) currentArg = index;\n            if (width < 0)\n            {\n                spec.flDash = true;\n                width = -width;\n            }\n            spec.width = width;\n        }\n\n        if (spec.precision == spec.DYNAMIC)\n        {\n            auto precision = getNthInt!\"integer precision\"(currentArg, args);\n            if (precision >= 0) spec.precision = precision;\n            // else negative precision is same as no precision\n            else spec.precision = spec.UNSPECIFIED;\n            ++currentArg;\n        }\n        else if (spec.precision < 0)\n        {\n            // means: get precision as a positional parameter\n            auto index = cast(uint) -spec.precision;\n            assert(index > 0);\n            auto precision = getNthInt!\"integer precision\"(index- 1, args);\n            if (currentArg < index) currentArg = index;\n            if (precision >= 0) spec.precision = precision;\n            // else negative precision is same as no precision\n            else spec.precision = spec.UNSPECIFIED;\n        }\n\n        if (spec.separators == spec.DYNAMIC)\n        {\n            auto separators = getNthInt!\"separator digit width\"(currentArg, args);\n            spec.separators = separators;\n            ++currentArg;\n        }\n\n        if (spec.separatorCharPos == spec.DYNAMIC)\n        {\n            auto separatorChar =\n                getNth!(\"separator character\", isSomeChar, dchar)(currentArg, args);\n            spec.separatorChar = separatorChar;\n            ++currentArg;\n        }\n\n        if (currentArg == A.length && !spec.indexStart)\n        {\n            // leftover spec?\n            enforceFmt(fmt.length == 0,\n                text(\"Orphan format specifier: %\", spec.spec));\n            break;\n        }\n\n        // Format an argument\n        // This switch uses a static foreach to generate a jump table.\n        // Currently `spec.indexStart` use the special value '0' to signal\n        // we should use the current argument. An enhancement would be to\n        // always store the index.\n        size_t index = currentArg;\n        if (spec.indexStart != 0)\n            index = spec.indexStart - 1;\n        else\n            ++currentArg;\n    SWITCH: switch (index)\n        {\n            foreach (i, Tunused; A)\n            {\n            case i:\n                formatValue(w, args[i], spec);\n                if (currentArg < spec.indexEnd)\n                    currentArg = spec.indexEnd;\n                // A little know feature of format is to format a range\n                // of arguments, e.g. `%1:3$` will format the first 3\n                // arguments. Since they have to be consecutive we can\n                // just use explicit fallthrough to cover that case.\n                if (i + 1 < spec.indexEnd)\n                {\n                    // You cannot goto case if the next case is the default\n                    static if (i + 1 < A.length)\n                        goto case;\n                    else\n                        goto default;\n                }\n                else\n                    break SWITCH;\n            }\n        default:\n            throw new FormatException(\n                text(\"Positional specifier %\", spec.indexStart, '$', spec.spec,\n                     \" index exceeds \", A.length));\n        }\n    }\n    return currentArg;\n}\n\n///\n@safe unittest\n{\n    assert(format(\"%,d\", 1000) == \"1,000\");\n    assert(format(\"%,f\", 1234567.891011) == \"1,234,567.891,011\");\n    assert(format(\"%,?d\", '?', 1000) == \"1?000\");\n    assert(format(\"%,1d\", 1000) == \"1,0,0,0\", format(\"%,1d\", 1000));\n    assert(format(\"%,*d\", 4, -12345) == \"-1,2345\");\n    assert(format(\"%,*?d\", 4, '_', -12345) == \"-1_2345\");\n    assert(format(\"%,6?d\", '_', -12345678) == \"-12_345678\");\n    assert(format(\"%12,3.3f\", 1234.5678) == \"   1,234.568\", \"'\" ~\n            format(\"%12,3.3f\", 1234.5678) ~ \"'\");\n}\n\n@safe pure unittest\n{\n    import std.array;\n    auto w = appender!string();\n    formattedWrite(w, \"%s %d\", \"@safe/pure\", 42);\n    assert(w.data == \"@safe/pure 42\");\n}\n\n@safe pure unittest\n{\n    char[20] buf;\n    auto w = buf[];\n    formattedWrite(w, \"%s %d\", \"@safe/pure\", 42);\n    assert(buf[0 .. $ - w.length] == \"@safe/pure 42\");\n}\n\n/**\nReads characters from $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n`r`, converts them according to `fmt`, and writes them to `args`.\n\nParams:\n    r = The range to read from.\n    fmt = The format of the data to read.\n    args = The drain of the data read.\n\nReturns:\n\nOn success, the function returns the number of variables filled. This count\ncan match the expected number of readings or fewer, even zero, if a\nmatching failure happens.\n\nThrows:\n    A `FormatException` if `S.length == 0` and `fmt` has format specifiers.\n */\nuint formattedRead(alias fmt, R, S...)(auto ref R r, auto ref S args)\nif (isSomeString!(typeof(fmt)))\n{\n    alias e = checkFormatException!(fmt, S);\n    static assert(!e, e.msg);\n    return .formattedRead(r, fmt, args);\n}\n\n/// ditto\nuint formattedRead(R, Char, S...)(auto ref R r, const(Char)[] fmt, auto ref S args)\n{\n    import std.typecons : isTuple;\n\n    auto spec = FormatSpec!Char(fmt);\n    static if (!S.length)\n    {\n        spec.readUpToNextSpec(r);\n        enforceFmt(spec.trailing.empty, \"Trailing characters in formattedRead format string\");\n        return 0;\n    }\n    else\n    {\n        enum hasPointer = isPointer!(typeof(args[0]));\n\n        // The function below accounts for '*' == fields meant to be\n        // read and skipped\n        void skipUnstoredFields()\n        {\n            for (;;)\n            {\n                spec.readUpToNextSpec(r);\n                if (spec.width != spec.DYNAMIC) break;\n                // must skip this field\n                skipData(r, spec);\n            }\n        }\n\n        skipUnstoredFields();\n        if (r.empty)\n        {\n            // Input is empty, nothing to read\n            return 0;\n        }\n        static if (hasPointer)\n            alias A = typeof(*args[0]);\n        else\n            alias A = typeof(args[0]);\n\n        static if (isTuple!A)\n        {\n            foreach (i, T; A.Types)\n            {\n                static if (hasPointer)\n                    (*args[0])[i] = unformatValue!(T)(r, spec);\n                else\n                    args[0][i] = unformatValue!(T)(r, spec);\n                skipUnstoredFields();\n            }\n        }\n        else\n        {\n            static if (hasPointer)\n                *args[0] = unformatValue!(A)(r, spec);\n            else\n                args[0] = unformatValue!(A)(r, spec);\n        }\n        return 1 + formattedRead(r, spec.trailing, args[1 .. $]);\n    }\n}\n\n/// The format string can be checked at compile-time (see $(LREF format) for details):\n@safe pure unittest\n{\n    string s = \"hello!124:34.5\";\n    string a;\n    int b;\n    double c;\n    s.formattedRead!\"%s!%s:%s\"(a, b, c);\n    assert(a == \"hello\" && b == 124 && c == 34.5);\n}\n\n@safe unittest\n{\n    import std.math;\n    string s = \" 1.2 3.4 \";\n    double x, y, z;\n    assert(formattedRead(s, \" %s %s %s \", x, y, z) == 2);\n    assert(s.empty);\n    assert(approxEqual(x, 1.2));\n    assert(approxEqual(y, 3.4));\n    assert(isNaN(z));\n}\n\n// for backwards compatibility\n@system pure unittest\n{\n    string s = \"hello!124:34.5\";\n    string a;\n    int b;\n    double c;\n    formattedRead(s, \"%s!%s:%s\", &a, &b, &c);\n    assert(a == \"hello\" && b == 124 && c == 34.5);\n\n    // mix pointers and auto-ref\n    s = \"world!200:42.25\";\n    formattedRead(s, \"%s!%s:%s\", a, &b, &c);\n    assert(a == \"world\" && b == 200 && c == 42.25);\n\n    s = \"world1!201:42.5\";\n    formattedRead(s, \"%s!%s:%s\", &a, &b, c);\n    assert(a == \"world1\" && b == 201 && c == 42.5);\n\n    s = \"world2!202:42.75\";\n    formattedRead(s, \"%s!%s:%s\", a, b, &c);\n    assert(a == \"world2\" && b == 202 && c == 42.75);\n}\n\n// for backwards compatibility\n@system pure unittest\n{\n    import std.math;\n    string s = \" 1.2 3.4 \";\n    double x, y, z;\n    assert(formattedRead(s, \" %s %s %s \", &x, &y, &z) == 2);\n    assert(s.empty);\n    assert(approxEqual(x, 1.2));\n    assert(approxEqual(y, 3.4));\n    assert(isNaN(z));\n}\n\n@system pure unittest\n{\n    string line;\n\n    bool f1;\n\n    line = \"true\";\n    formattedRead(line, \"%s\", &f1);\n    assert(f1);\n\n    line = \"TrUE\";\n    formattedRead(line, \"%s\", &f1);\n    assert(f1);\n\n    line = \"false\";\n    formattedRead(line, \"%s\", &f1);\n    assert(!f1);\n\n    line = \"fALsE\";\n    formattedRead(line, \"%s\", &f1);\n    assert(!f1);\n\n    line = \"1\";\n    formattedRead(line, \"%d\", &f1);\n    assert(f1);\n\n    line = \"-1\";\n    formattedRead(line, \"%d\", &f1);\n    assert(f1);\n\n    line = \"0\";\n    formattedRead(line, \"%d\", &f1);\n    assert(!f1);\n\n    line = \"-0\";\n    formattedRead(line, \"%d\", &f1);\n    assert(!f1);\n}\n\n@system pure unittest\n{\n     union B\n     {\n         char[int.sizeof] untyped;\n         int typed;\n     }\n     B b;\n     b.typed = 5;\n     char[] input = b.untyped[];\n     int witness;\n     formattedRead(input, \"%r\", &witness);\n     assert(witness == b.typed);\n}\n\n@system pure unittest\n{\n    union A\n    {\n        char[float.sizeof] untyped;\n        float typed;\n    }\n    A a;\n    a.typed = 5.5;\n    char[] input = a.untyped[];\n    float witness;\n    formattedRead(input, \"%r\", &witness);\n    assert(witness == a.typed);\n}\n\n@system pure unittest\n{\n    import std.typecons;\n    char[] line = \"1 2\".dup;\n    int a, b;\n    formattedRead(line, \"%s %s\", &a, &b);\n    assert(a == 1 && b == 2);\n\n    line = \"10 2 3\".dup;\n    formattedRead(line, \"%d \", &a);\n    assert(a == 10);\n    assert(line == \"2 3\");\n\n    Tuple!(int, float) t;\n    line = \"1 2.125\".dup;\n    formattedRead(line, \"%d %g\", &t);\n    assert(t[0] == 1 && t[1] == 2.125);\n\n    line = \"1 7643 2.125\".dup;\n    formattedRead(line, \"%s %*u %s\", &t);\n    assert(t[0] == 1 && t[1] == 2.125);\n}\n\n@system pure unittest\n{\n    string line;\n\n    char c1, c2;\n\n    line = \"abc\";\n    formattedRead(line, \"%s%c\", &c1, &c2);\n    assert(c1 == 'a' && c2 == 'b');\n    assert(line == \"c\");\n}\n\n@system pure unittest\n{\n    string line;\n\n    line = \"[1,2,3]\";\n    int[] s1;\n    formattedRead(line, \"%s\", &s1);\n    assert(s1 == [1,2,3]);\n}\n\n@system pure unittest\n{\n    string line;\n\n    line = \"[1,2,3]\";\n    int[] s1;\n    formattedRead(line, \"[%(%s,%)]\", &s1);\n    assert(s1 == [1,2,3]);\n\n    line = `[\"hello\", \"world\"]`;\n    string[] s2;\n    formattedRead(line, \"[%(%s, %)]\", &s2);\n    assert(s2 == [\"hello\", \"world\"]);\n\n    line = \"123 456\";\n    int[] s3;\n    formattedRead(line, \"%(%s %)\", &s3);\n    assert(s3 == [123, 456]);\n\n    line = \"h,e,l,l,o; w,o,r,l,d\";\n    string[] s4;\n    formattedRead(line, \"%(%(%c,%); %)\", &s4);\n    assert(s4 == [\"hello\", \"world\"]);\n}\n\n@system pure unittest\n{\n    string line;\n\n    int[4] sa1;\n    line = `[1,2,3,4]`;\n    formattedRead(line, \"%s\", &sa1);\n    assert(sa1 == [1,2,3,4]);\n\n    int[4] sa2;\n    line = `[1,2,3]`;\n    assertThrown(formattedRead(line, \"%s\", &sa2));\n\n    int[4] sa3;\n    line = `[1,2,3,4,5]`;\n    assertThrown(formattedRead(line, \"%s\", &sa3));\n}\n\n@system pure unittest\n{\n    string input;\n\n    int[4] sa1;\n    input = `[1,2,3,4]`;\n    formattedRead(input, \"[%(%s,%)]\", &sa1);\n    assert(sa1 == [1,2,3,4]);\n\n    int[4] sa2;\n    input = `[1,2,3]`;\n    assertThrown!FormatException(formattedRead(input, \"[%(%s,%)]\", &sa2));\n}\n\n@system pure unittest\n{\n    string line;\n\n    string s1, s2;\n\n    line = \"hello, world\";\n    formattedRead(line, \"%s\", &s1);\n    assert(s1 == \"hello, world\", s1);\n\n    line = \"hello, world;yah\";\n    formattedRead(line, \"%s;%s\", &s1, &s2);\n    assert(s1 == \"hello, world\", s1);\n    assert(s2 == \"yah\", s2);\n\n    line = `['h','e','l','l','o']`;\n    string s3;\n    formattedRead(line, \"[%(%s,%)]\", &s3);\n    assert(s3 == \"hello\");\n\n    line = `\"hello\"`;\n    string s4;\n    formattedRead(line, \"\\\"%(%c%)\\\"\", &s4);\n    assert(s4 == \"hello\");\n}\n\n@system pure unittest\n{\n    string line;\n\n    string[int] aa1;\n    line = `[1:\"hello\", 2:\"world\"]`;\n    formattedRead(line, \"%s\", &aa1);\n    assert(aa1 == [1:\"hello\", 2:\"world\"]);\n\n    int[string] aa2;\n    line = `{\"hello\"=1; \"world\"=2}`;\n    formattedRead(line, \"{%(%s=%s; %)}\", &aa2);\n    assert(aa2 == [\"hello\":1, \"world\":2]);\n\n    int[string] aa3;\n    line = `{[hello=1]; [world=2]}`;\n    formattedRead(line, \"{%([%(%c%)=%s]%|; %)}\", &aa3);\n    assert(aa3 == [\"hello\":1, \"world\":2]);\n}\n\n// test rvalue using\n@system pure unittest\n{\n    string[int] aa1;\n    formattedRead!(\"%s\")(`[1:\"hello\", 2:\"world\"]`, aa1);\n    assert(aa1 == [1:\"hello\", 2:\"world\"]);\n\n    int[string] aa2;\n    formattedRead(`{\"hello\"=1; \"world\"=2}`, \"{%(%s=%s; %)}\", aa2);\n    assert(aa2 == [\"hello\":1, \"world\":2]);\n}\n\ntemplate FormatSpec(Char)\nif (!is(Unqual!Char == Char))\n{\n    alias FormatSpec = FormatSpec!(Unqual!Char);\n}\n\n/**\n * A General handler for `printf` style format specifiers. Used for building more\n * specific formatting functions.\n */\nstruct FormatSpec(Char)\nif (is(Unqual!Char == Char))\n{\n    import std.algorithm.searching : startsWith;\n    import std.ascii : isDigit, isPunctuation, isAlpha;\n    import std.conv : parse, text, to;\n\n    /**\n       Minimum _width, default `0`.\n     */\n    int width = 0;\n\n    /**\n       Precision. Its semantics depends on the argument type. For\n       floating point numbers, _precision dictates the number of\n       decimals printed.\n     */\n    int precision = UNSPECIFIED;\n\n    /**\n       Number of digits printed between _separators.\n    */\n    int separators = UNSPECIFIED;\n\n    /**\n       Set to `DYNAMIC` when the separator character is supplied at runtime.\n    */\n    int separatorCharPos = UNSPECIFIED;\n\n    /**\n       Character to insert between digits.\n    */\n    dchar separatorChar = ',';\n\n    /**\n       Special value for width and precision. `DYNAMIC` width or\n       precision means that they were specified with `'*'` in the\n       format string and are passed at runtime through the varargs.\n     */\n    enum int DYNAMIC = int.max;\n\n    /**\n       Special value for precision, meaning the format specifier\n       contained no explicit precision.\n     */\n    enum int UNSPECIFIED = DYNAMIC - 1;\n\n    /**\n       The actual format specifier, `'s'` by default.\n    */\n    char spec = 's';\n\n    /**\n       Index of the argument for positional parameters, from `1` to\n       `ubyte.max`. (`0` means not used).\n    */\n    ubyte indexStart;\n\n    /**\n       Index of the last argument for positional parameter range, from\n       `1` to `ubyte.max`. (`0` means not used).\n    */\n    ubyte indexEnd;\n\n    version (StdDdoc)\n    {\n        /**\n         The format specifier contained a `'-'` (`printf`\n         compatibility).\n         */\n        bool flDash;\n\n        /**\n         The format specifier contained a `'0'` (`printf`\n         compatibility).\n         */\n        bool flZero;\n\n        /**\n         The format specifier contained a $(D ' ') (`printf`\n         compatibility).\n         */\n        bool flSpace;\n\n        /**\n         The format specifier contained a `'+'` (`printf`\n         compatibility).\n         */\n        bool flPlus;\n\n        /**\n         The format specifier contained a `'#'` (`printf`\n         compatibility).\n         */\n        bool flHash;\n\n        /**\n         The format specifier contained a `','`\n         */\n        bool flSeparator;\n\n        // Fake field to allow compilation\n        ubyte allFlags;\n    }\n    else\n    {\n        union\n        {\n            import std.bitmanip : bitfields;\n            mixin(bitfields!(\n                        bool, \"flDash\", 1,\n                        bool, \"flZero\", 1,\n                        bool, \"flSpace\", 1,\n                        bool, \"flPlus\", 1,\n                        bool, \"flHash\", 1,\n                        bool, \"flSeparator\", 1,\n                        ubyte, \"\", 2));\n            ubyte allFlags;\n        }\n    }\n\n    /**\n       In case of a compound format specifier starting with $(D\n       \"%$(LPAREN)\") and ending with `\"%$(RPAREN)\"`, `_nested`\n       contains the string contained within the two separators.\n     */\n    const(Char)[] nested;\n\n    /**\n       In case of a compound format specifier, `_sep` contains the\n       string positioning after `\"%|\"`.\n       `sep is null` means no separator else `sep.empty` means 0 length\n        separator.\n     */\n    const(Char)[] sep;\n\n    /**\n       `_trailing` contains the rest of the format string.\n     */\n    const(Char)[] trailing;\n\n    /*\n       This string is inserted before each sequence (e.g. array)\n       formatted (by default `\"[\"`).\n     */\n    enum immutable(Char)[] seqBefore = \"[\";\n\n    /*\n       This string is inserted after each sequence formatted (by\n       default `\"]\"`).\n     */\n    enum immutable(Char)[] seqAfter = \"]\";\n\n    /*\n       This string is inserted after each element keys of a sequence (by\n       default `\":\"`).\n     */\n    enum immutable(Char)[] keySeparator = \":\";\n\n    /*\n       This string is inserted in between elements of a sequence (by\n       default $(D \", \")).\n     */\n    enum immutable(Char)[] seqSeparator = \", \";\n\n    /**\n       Construct a new `FormatSpec` using the format string `fmt`, no\n       processing is done until needed.\n     */\n    this(in Char[] fmt) @safe pure\n    {\n        trailing = fmt;\n    }\n\n    bool writeUpToNextSpec(OutputRange)(ref OutputRange writer)\n    {\n        if (trailing.empty)\n            return false;\n        for (size_t i = 0; i < trailing.length; ++i)\n        {\n            if (trailing[i] != '%') continue;\n            put(writer, trailing[0 .. i]);\n            trailing = trailing[i .. $];\n            enforceFmt(trailing.length >= 2, `Unterminated format specifier: \"%\"`);\n            trailing = trailing[1 .. $];\n\n            if (trailing[0] != '%')\n            {\n                // Spec found. Fill up the spec, and bailout\n                fillUp();\n                return true;\n            }\n            // Doubled! Reset and Keep going\n            i = 0;\n        }\n        // no format spec found\n        put(writer, trailing);\n        trailing = null;\n        return false;\n    }\n\n    @safe unittest\n    {\n        import std.array;\n        auto w = appender!(char[])();\n        auto f = FormatSpec(\"abc%sdef%sghi\");\n        f.writeUpToNextSpec(w);\n        assert(w.data == \"abc\", w.data);\n        assert(f.trailing == \"def%sghi\", text(f.trailing));\n        f.writeUpToNextSpec(w);\n        assert(w.data == \"abcdef\", w.data);\n        assert(f.trailing == \"ghi\");\n        // test with embedded %%s\n        f = FormatSpec(\"ab%%cd%%ef%sg%%h%sij\");\n        w.clear();\n        f.writeUpToNextSpec(w);\n        assert(w.data == \"ab%cd%ef\" && f.trailing == \"g%%h%sij\", w.data);\n        f.writeUpToNextSpec(w);\n        assert(w.data == \"ab%cd%efg%h\" && f.trailing == \"ij\");\n        // bug4775\n        f = FormatSpec(\"%%%s\");\n        w.clear();\n        f.writeUpToNextSpec(w);\n        assert(w.data == \"%\" && f.trailing == \"\");\n        f = FormatSpec(\"%%%%%s%%\");\n        w.clear();\n        while (f.writeUpToNextSpec(w)) continue;\n        assert(w.data == \"%%%\");\n\n        f = FormatSpec(\"a%%b%%c%\");\n        w.clear();\n        assertThrown!FormatException(f.writeUpToNextSpec(w));\n        assert(w.data == \"a%b%c\" && f.trailing == \"%\");\n    }\n\n    private void fillUp()\n    {\n        // Reset content\n        if (__ctfe)\n        {\n            flDash = false;\n            flZero = false;\n            flSpace = false;\n            flPlus = false;\n            flHash = false;\n            flSeparator = false;\n        }\n        else\n        {\n            allFlags = 0;\n        }\n\n        width = 0;\n        precision = UNSPECIFIED;\n        nested = null;\n        // Parse the spec (we assume we're past '%' already)\n        for (size_t i = 0; i < trailing.length; )\n        {\n            switch (trailing[i])\n            {\n            case '(':\n                // Embedded format specifier.\n                auto j = i + 1;\n                // Get the matching balanced paren\n                for (uint innerParens;;)\n                {\n                    enforceFmt(j + 1 < trailing.length,\n                        text(\"Incorrect format specifier: %\", trailing[i .. $]));\n                    if (trailing[j++] != '%')\n                    {\n                        // skip, we're waiting for %( and %)\n                        continue;\n                    }\n                    if (trailing[j] == '-') // for %-(\n                    {\n                        ++j;    // skip\n                        enforceFmt(j < trailing.length,\n                            text(\"Incorrect format specifier: %\", trailing[i .. $]));\n                    }\n                    if (trailing[j] == ')')\n                    {\n                        if (innerParens-- == 0) break;\n                    }\n                    else if (trailing[j] == '|')\n                    {\n                        if (innerParens == 0) break;\n                    }\n                    else if (trailing[j] == '(')\n                    {\n                        ++innerParens;\n                    }\n                }\n                if (trailing[j] == '|')\n                {\n                    auto k = j;\n                    for (++j;;)\n                    {\n                        if (trailing[j++] != '%')\n                            continue;\n                        if (trailing[j] == '%')\n                            ++j;\n                        else if (trailing[j] == ')')\n                            break;\n                        else\n                            throw new FormatException(\n                                text(\"Incorrect format specifier: %\",\n                                        trailing[j .. $]));\n                    }\n                    nested = trailing[i + 1 .. k - 1];\n                    sep = trailing[k + 1 .. j - 1];\n                }\n                else\n                {\n                    nested = trailing[i + 1 .. j - 1];\n                    sep = null; // no separator\n                }\n                //this = FormatSpec(innerTrailingSpec);\n                spec = '(';\n                // We practically found the format specifier\n                trailing = trailing[j + 1 .. $];\n                return;\n            case '-': flDash = true; ++i; break;\n            case '+': flPlus = true; ++i; break;\n            case '#': flHash = true; ++i; break;\n            case '0': flZero = true; ++i; break;\n            case ' ': flSpace = true; ++i; break;\n            case '*':\n                if (isDigit(trailing[++i]))\n                {\n                    // a '*' followed by digits and '$' is a\n                    // positional format\n                    trailing = trailing[1 .. $];\n                    width = -parse!(typeof(width))(trailing);\n                    i = 0;\n                    enforceFmt(trailing[i++] == '$',\n                        \"$ expected\");\n                }\n                else\n                {\n                    // read result\n                    width = DYNAMIC;\n                }\n                break;\n            case '1': .. case '9':\n                auto tmp = trailing[i .. $];\n                const widthOrArgIndex = parse!uint(tmp);\n                enforceFmt(tmp.length,\n                    text(\"Incorrect format specifier %\", trailing[i .. $]));\n                i = arrayPtrDiff(tmp, trailing);\n                if (tmp.startsWith('$'))\n                {\n                    // index of the form %n$\n                    indexEnd = indexStart = to!ubyte(widthOrArgIndex);\n                    ++i;\n                }\n                else if (tmp.startsWith(':'))\n                {\n                    // two indexes of the form %m:n$, or one index of the form %m:$\n                    indexStart = to!ubyte(widthOrArgIndex);\n                    tmp = tmp[1 .. $];\n                    if (tmp.startsWith('$'))\n                    {\n                        indexEnd = indexEnd.max;\n                    }\n                    else\n                    {\n                        indexEnd = parse!(typeof(indexEnd))(tmp);\n                    }\n                    i = arrayPtrDiff(tmp, trailing);\n                    enforceFmt(trailing[i++] == '$',\n                        \"$ expected\");\n                }\n                else\n                {\n                    // width\n                    width = to!int(widthOrArgIndex);\n                }\n                break;\n            case ',':\n                // Precision\n                ++i;\n                flSeparator = true;\n\n                if (trailing[i] == '*')\n                {\n                    ++i;\n                    // read result\n                    separators = DYNAMIC;\n                }\n                else if (isDigit(trailing[i]))\n                {\n                    auto tmp = trailing[i .. $];\n                    separators = parse!int(tmp);\n                    i = arrayPtrDiff(tmp, trailing);\n                }\n                else\n                {\n                    // \",\" was specified, but nothing after it\n                    separators = 3;\n                }\n\n                if (trailing[i] == '?')\n                {\n                    separatorCharPos = DYNAMIC;\n                    ++i;\n                }\n\n                break;\n            case '.':\n                // Precision\n                if (trailing[++i] == '*')\n                {\n                    if (isDigit(trailing[++i]))\n                    {\n                        // a '.*' followed by digits and '$' is a\n                        // positional precision\n                        trailing = trailing[i .. $];\n                        i = 0;\n                        precision = -parse!int(trailing);\n                        enforceFmt(trailing[i++] == '$',\n                            \"$ expected\");\n                    }\n                    else\n                    {\n                        // read result\n                        precision = DYNAMIC;\n                    }\n                }\n                else if (trailing[i] == '-')\n                {\n                    // negative precision, as good as 0\n                    precision = 0;\n                    auto tmp = trailing[i .. $];\n                    parse!int(tmp); // skip digits\n                    i = arrayPtrDiff(tmp, trailing);\n                }\n                else if (isDigit(trailing[i]))\n                {\n                    auto tmp = trailing[i .. $];\n                    precision = parse!int(tmp);\n                    i = arrayPtrDiff(tmp, trailing);\n                }\n                else\n                {\n                    // \".\" was specified, but nothing after it\n                    precision = 0;\n                }\n                break;\n            default:\n                // this is the format char\n                spec = cast(char) trailing[i++];\n                trailing = trailing[i .. $];\n                return;\n            } // end switch\n        } // end for\n        throw new FormatException(text(\"Incorrect format specifier: \", trailing));\n    }\n\n    //--------------------------------------------------------------------------\n    private bool readUpToNextSpec(R)(ref R r)\n    {\n        import std.ascii : isLower, isWhite;\n        import std.utf : stride;\n\n        // Reset content\n        if (__ctfe)\n        {\n            flDash = false;\n            flZero = false;\n            flSpace = false;\n            flPlus = false;\n            flHash = false;\n            flSeparator = false;\n        }\n        else\n        {\n            allFlags = 0;\n        }\n        width = 0;\n        precision = UNSPECIFIED;\n        nested = null;\n        // Parse the spec\n        while (trailing.length)\n        {\n            const c = trailing[0];\n            if (c == '%' && trailing.length > 1)\n            {\n                const c2 = trailing[1];\n                if (c2 == '%')\n                {\n                    assert(!r.empty);\n                    // Require a '%'\n                    if (r.front != '%') break;\n                    trailing = trailing[2 .. $];\n                    r.popFront();\n                }\n                else\n                {\n                    enforceFmt(isLower(c2) || c2 == '*' ||\n                            c2 == '(',\n                            text(\"'%\", c2,\n                                    \"' not supported with formatted read\"));\n                    trailing = trailing[1 .. $];\n                    fillUp();\n                    return true;\n                }\n            }\n            else\n            {\n                if (c == ' ')\n                {\n                    while (!r.empty && isWhite(r.front)) r.popFront();\n                    //r = std.algorithm.find!(not!(isWhite))(r);\n                }\n                else\n                {\n                    enforceFmt(!r.empty,\n                            text(\"parseToFormatSpec: Cannot find character '\",\n                                    c, \"' in the input string.\"));\n                    if (r.front != trailing.front) break;\n                    r.popFront();\n                }\n                trailing = trailing[stride(trailing, 0) .. $];\n            }\n        }\n        return false;\n    }\n\n    private string getCurFmtStr() const\n    {\n        import std.array : appender;\n        auto w = appender!string();\n        auto f = FormatSpec!Char(\"%s\"); // for stringnize\n\n        put(w, '%');\n        if (indexStart != 0)\n        {\n            formatValue(w, indexStart, f);\n            put(w, '$');\n        }\n        if (flDash)  put(w, '-');\n        if (flZero)  put(w, '0');\n        if (flSpace) put(w, ' ');\n        if (flPlus)  put(w, '+');\n        if (flHash)  put(w, '#');\n        if (flSeparator)  put(w, ',');\n        if (width != 0)\n            formatValue(w, width, f);\n        if (precision != FormatSpec!Char.UNSPECIFIED)\n        {\n            put(w, '.');\n            formatValue(w, precision, f);\n        }\n        put(w, spec);\n        return w.data;\n    }\n\n    @safe unittest\n    {\n        // issue 5237\n        import std.array;\n        auto w = appender!string();\n        auto f = FormatSpec!char(\"%.16f\");\n        f.writeUpToNextSpec(w); // dummy eating\n        assert(f.spec == 'f');\n        auto fmt = f.getCurFmtStr();\n        assert(fmt == \"%.16f\");\n    }\n\n    private const(Char)[] headUpToNextSpec()\n    {\n        import std.array : appender;\n        auto w = appender!(typeof(return))();\n        auto tr = trailing;\n\n        while (tr.length)\n        {\n            if (tr[0] == '%')\n            {\n                if (tr.length > 1 && tr[1] == '%')\n                {\n                    tr = tr[2 .. $];\n                    w.put('%');\n                }\n                else\n                    break;\n            }\n            else\n            {\n                w.put(tr.front);\n                tr.popFront();\n            }\n        }\n        return w.data;\n    }\n\n    /**\n     * Gives a string containing all of the member variables on their own\n     * line.\n     *\n     * Params:\n     *     writer = A `char` accepting\n     *     $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n     * Returns:\n     *     A `string` when not using an output range; `void` otherwise.\n     */\n    string toString() const @safe pure\n    {\n        import std.array : appender;\n        auto app = appender!string();\n        app.reserve(200 + trailing.length);\n        toString(app);\n        return app.data;\n    }\n\n    /// ditto\n    void toString(OutputRange)(ref OutputRange writer) const\n    if (isOutputRange!(OutputRange, char))\n    {\n        auto s = singleSpec(\"%s\");\n\n        put(writer, \"address = \");\n        formatValue(writer, &this, s);\n        put(writer, \"\\nwidth = \");\n        formatValue(writer, width, s);\n        put(writer, \"\\nprecision = \");\n        formatValue(writer, precision, s);\n        put(writer, \"\\nspec = \");\n        formatValue(writer, spec, s);\n        put(writer, \"\\nindexStart = \");\n        formatValue(writer, indexStart, s);\n        put(writer, \"\\nindexEnd = \");\n        formatValue(writer, indexEnd, s);\n        put(writer, \"\\nflDash = \");\n        formatValue(writer, flDash, s);\n        put(writer, \"\\nflZero = \");\n        formatValue(writer, flZero, s);\n        put(writer, \"\\nflSpace = \");\n        formatValue(writer, flSpace, s);\n        put(writer, \"\\nflPlus = \");\n        formatValue(writer, flPlus, s);\n        put(writer, \"\\nflHash = \");\n        formatValue(writer, flHash, s);\n        put(writer, \"\\nflSeparator = \");\n        formatValue(writer, flSeparator, s);\n        put(writer, \"\\nnested = \");\n        formatValue(writer, nested, s);\n        put(writer, \"\\ntrailing = \");\n        formatValue(writer, trailing, s);\n        put(writer, '\\n');\n    }\n}\n\n///\n@safe pure unittest\n{\n    import std.array;\n    auto a = appender!(string)();\n    auto fmt = \"Number: %2.4e\\nString: %s\";\n    auto f = FormatSpec!char(fmt);\n\n    f.writeUpToNextSpec(a);\n\n    assert(a.data == \"Number: \");\n    assert(f.trailing == \"\\nString: %s\");\n    assert(f.spec == 'e');\n    assert(f.width == 2);\n    assert(f.precision == 4);\n\n    f.writeUpToNextSpec(a);\n\n    assert(a.data == \"Number: \\nString: \");\n    assert(f.trailing == \"\");\n    assert(f.spec == 's');\n}\n\n// Issue 14059\n@safe unittest\n{\n    import std.array : appender;\n    auto a = appender!(string)();\n\n    auto f = FormatSpec!char(\"%-(%s%\"); // %)\")\n    assertThrown!FormatException(f.writeUpToNextSpec(a));\n\n    f = FormatSpec!char(\"%(%-\"); // %)\")\n    assertThrown!FormatException(f.writeUpToNextSpec(a));\n}\n\n@safe unittest\n{\n    import std.array : appender;\n    auto a = appender!(string)();\n\n    auto f = FormatSpec!char(\"%,d\");\n    f.writeUpToNextSpec(a);\n\n    assert(f.spec == 'd', format(\"%s\", f.spec));\n    assert(f.precision == FormatSpec!char.UNSPECIFIED);\n    assert(f.separators == 3);\n\n    f = FormatSpec!char(\"%5,10f\");\n    f.writeUpToNextSpec(a);\n    assert(f.spec == 'f', format(\"%s\", f.spec));\n    assert(f.separators == 10);\n    assert(f.width == 5);\n\n    f = FormatSpec!char(\"%5,10.4f\");\n    f.writeUpToNextSpec(a);\n    assert(f.spec == 'f', format(\"%s\", f.spec));\n    assert(f.separators == 10);\n    assert(f.width == 5);\n    assert(f.precision == 4);\n}\n\n@safe pure unittest\n{\n    import std.algorithm.searching : canFind, findSplitBefore;\n    auto expected = \"width = 2\" ~\n        \"\\nprecision = 5\" ~\n        \"\\nspec = f\" ~\n        \"\\nindexStart = 0\" ~\n        \"\\nindexEnd = 0\" ~\n        \"\\nflDash = false\" ~\n        \"\\nflZero = false\" ~\n        \"\\nflSpace = false\" ~\n        \"\\nflPlus = false\" ~\n        \"\\nflHash = false\" ~\n        \"\\nflSeparator = false\" ~\n        \"\\nnested = \" ~\n        \"\\ntrailing = \\n\";\n    auto spec = singleSpec(\"%2.5f\");\n    auto res = spec.toString();\n    // make sure the address exists, then skip it\n    assert(res.canFind(\"address\"));\n    assert(res.findSplitBefore(\"width\")[1] == expected);\n}\n\n/**\nHelper function that returns a `FormatSpec` for a single specifier given\nin `fmt`.\n\nParams:\n    fmt = A format specifier.\n\nReturns:\n    A `FormatSpec` with the specifier parsed.\nThrows:\n    A `FormatException` when more than one specifier is given or the specifier\n    is malformed.\n  */\nFormatSpec!Char singleSpec(Char)(Char[] fmt)\n{\n    import std.conv : text;\n    enforceFmt(fmt.length >= 2, \"fmt must be at least 2 characters long\");\n    enforceFmt(fmt.front == '%', \"fmt must start with a '%' character\");\n\n    static struct DummyOutputRange {\n        void put(C)(scope const C[] buf) {} // eat elements\n    }\n    auto a = DummyOutputRange();\n    auto spec = FormatSpec!Char(fmt);\n    //dummy write\n    spec.writeUpToNextSpec(a);\n\n    enforceFmt(spec.trailing.empty,\n            text(\"Trailing characters in fmt string: '\", spec.trailing));\n\n    return spec;\n}\n\n///\n@safe pure unittest\n{\n    import std.exception : assertThrown;\n    auto spec = singleSpec(\"%2.3e\");\n\n    assert(spec.trailing == \"\");\n    assert(spec.spec == 'e');\n    assert(spec.width == 2);\n    assert(spec.precision == 3);\n\n    assertThrown!FormatException(singleSpec(\"\"));\n    assertThrown!FormatException(singleSpec(\"2.3e\"));\n    assertThrown!FormatException(singleSpec(\"%2.3eTest\"));\n}\n\n/**\n * Formats any value into `Char` accepting `OutputRange`, using the given `FormatSpec`.\n *\n * Aggregates:\n * `struct`, `union`, `class`, and `interface` are formatted by calling `toString`.\n *\n * `toString` should have one of the following signatures:\n *\n * ---\n * void toString(W)(ref W w, const ref FormatSpec fmt)\n * void toString(W)(ref W w)\n * string toString();\n * ---\n *\n * Where `W` is an $(REF_ALTTEXT output range, isOutputRange, std,range,primitives)\n * which accepts characters. The template type does not have to be called `W`.\n *\n * The following overloads are also accepted for legacy reasons or for use in virtual\n * functions. It's recommended that any new code forgo these overloads if possible for\n * speed and attribute acceptance reasons.\n *\n * ---\n * void toString(scope void delegate(const(char)[]) sink, const ref FormatSpec fmt);\n * void toString(scope void delegate(const(char)[]) sink, string fmt);\n * void toString(scope void delegate(const(char)[]) sink);\n * ---\n *\n * For the class objects which have input range interface,\n * $(UL\n *     $(LI If the instance `toString` has overridden `Object.toString`, it is used.)\n *     $(LI Otherwise, the objects are formatted as input range.)\n * )\n *\n * For the `struct` and `union` objects which does not have `toString`,\n * $(UL\n *     $(LI If they have range interface, formatted as input range.)\n *     $(LI Otherwise, they are formatted like `Type(field1, filed2, ...)`.)\n * )\n *\n * Otherwise, are formatted just as their type name.\n *\n * Params:\n *     w = The $(REF_ALTTEXT output range, isOutputRange, std,range,primitives) to write to.\n *     val = The value to write.\n *     f = The $(REF FormatSpec, std, format) defining how to write the value.\n */\nvoid formatValue(Writer, T, Char)(auto ref Writer w, auto ref T val, const ref FormatSpec!Char f)\n{\n    formatValueImpl(w, val, f);\n}\n\n/++\n   The following code compares the use of `formatValue` and `formattedWrite`.\n +/\n@safe pure unittest\n{\n   import std.array : appender;\n\n   auto writer1 = appender!string();\n   writer1.formattedWrite(\"%08b\", 42);\n\n   auto writer2 = appender!string();\n   auto f = singleSpec(\"%08b\");\n   writer2.formatValue(42, f);\n\n   assert(writer1.data == writer2.data && writer1.data == \"00101010\");\n}\n\n/**\n * `bool`s are formatted as `\"true\"` or `\"false\"` with `%s` and as `1` or\n * `0` with integral-specific format specs.\n */\n@safe pure unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n    formatValue(w, true, spec);\n\n    assert(w.data == \"true\");\n}\n\n/// `null` literal is formatted as `\"null\"`.\n@safe pure unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n    formatValue(w, null, spec);\n\n    assert(w.data == \"null\");\n}\n\n/// Integrals are formatted like $(REF printf, core, stdc, stdio).\n@safe pure unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%d\");\n    formatValue(w, 1337, spec);\n\n    assert(w.data == \"1337\");\n}\n\n/// Floating-point values are formatted like $(REF printf, core, stdc, stdio)\n@safe unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%.1f\");\n    formatValue(w, 1337.7, spec);\n\n    assert(w.data == \"1337.7\");\n}\n\n/**\n * Individual characters (`char, `wchar`, or `dchar`) are formatted as\n * Unicode characters with `%s` and as integers with integral-specific format\n * specs.\n */\n@safe pure unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%c\");\n    formatValue(w, 'a', spec);\n\n    assert(w.data == \"a\");\n}\n\n/// Strings are formatted like $(REF printf, core, stdc, stdio)\n@safe pure unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n    formatValue(w, \"hello\", spec);\n\n    assert(w.data == \"hello\");\n}\n\n/// Static-size arrays are formatted as dynamic arrays.\n@safe pure unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n    char[2] two = ['a', 'b'];\n    formatValue(w, two, spec);\n\n    assert(w.data == \"ab\");\n}\n\n/**\n * Dynamic arrays are formatted as input ranges.\n *\n * Specializations:\n *   $(UL\n *      $(LI `void[]` is formatted like `ubyte[]`.)\n *      $(LI Const array is converted to input range by removing its qualifier.)\n *   )\n */\n@safe pure unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n    auto two = [1, 2];\n    formatValue(w, two, spec);\n\n    assert(w.data == \"[1, 2]\");\n}\n\n/**\n * Associative arrays are formatted by using `':'` and `\", \"` as\n * separators, and enclosed by `'['` and `']'`.\n */\n@safe pure unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n    auto aa = [\"H\":\"W\"];\n    formatValue(w, aa, spec);\n\n    assert(w.data == \"[\\\"H\\\":\\\"W\\\"]\", w.data);\n}\n\n/// `enum`s are formatted like their base value\n@safe pure unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n\n    enum A { first, second, third }\n\n    formatValue(w, A.second, spec);\n\n    assert(w.data == \"second\");\n}\n\n/**\n * Formatting a struct by defining a method `toString`, which takes an output\n * range.\n *\n * It's recommended that any `toString` using $(REF_ALTTEXT output ranges, isOutputRange, std,range,primitives)\n * use $(REF put, std,range,primitives) rather than use the `put` method of the range\n * directly.\n */\n@safe unittest\n{\n    import std.array : appender;\n    import std.range.primitives;\n\n    static struct Point\n    {\n        int x, y;\n\n        void toString(W)(ref W writer, const ref FormatSpec!char f)\n        if (isOutputRange!(W, char))\n        {\n            // std.range.primitives.put\n            put(writer, \"(\");\n            formatValue(writer, x, f);\n            put(writer, \",\");\n            formatValue(writer, y, f);\n            put(writer, \")\");\n        }\n    }\n\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n    auto p = Point(16, 11);\n\n    formatValue(w, p, spec);\n    assert(w.data == \"(16,11)\");\n}\n\n/**\n * Another example of formatting a `struct` with a defined `toString`,\n * this time using the `scope delegate` method.\n *\n * $(RED This method is now discouraged for non-virtual functions).\n * If possible, please use the output range method instead.\n */\n@safe unittest\n{\n   static struct Point\n   {\n       int x, y;\n\n       void toString(scope void delegate(scope const(char)[]) @safe sink,\n                     FormatSpec!char fmt) const\n       {\n           sink(\"(\");\n           sink.formatValue(x, fmt);\n           sink(\",\");\n           sink.formatValue(y, fmt);\n           sink(\")\");\n       }\n   }\n\n   auto p = Point(16,11);\n   assert(format(\"%03d\", p) == \"(016,011)\");\n   assert(format(\"%02x\", p) == \"(10,0b)\");\n}\n\n/// Pointers are formatted as hex integers.\n@system pure unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n\n    auto q = cast(void*) 0xFFEECCAA;\n    formatValue(w, q, spec);\n\n    assert(w.data == \"FFEECCAA\");\n}\n\n/// SIMD vectors are formatted as arrays.\n@safe unittest\n{\n    import core.simd;\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n\n    static if (is(float4))\n    {\n        version (X86) {}\n        else\n        {\n            float4 f4;\n            f4.array[0] = 1;\n            f4.array[1] = 2;\n            f4.array[2] = 3;\n            f4.array[3] = 4;\n\n            formatValue(w, f4, spec);\n            assert(w.data == \"[1, 2, 3, 4]\");\n        }\n    }\n}\n\n/// Delegates are formatted by `ReturnType delegate(Parameters) FunctionAttributes`\n@safe unittest\n{\n    import std.conv : to;\n\n    int i;\n\n    int foo(short k) @nogc\n    {\n        return i + k;\n    }\n\n    @system int delegate(short) @nogc bar() nothrow pure\n    {\n        int* p = new int(1);\n        i = *p;\n        return &foo;\n    }\n\n    assert(to!string(&bar) == \"int delegate(short) @nogc delegate() pure nothrow @system\");\n    assert(() @trusted { return bar()(3); }() == 4);\n}\n\n/*\n    `bool`s are formatted as `\"true\"` or `\"false\"` with `%s` and as `1` or\n    `0` with integral-specific format specs.\n */\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f)\nif (is(BooleanTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))\n{\n    BooleanTypeOf!T val = obj;\n\n    if (f.spec == 's')\n    {\n        string s = val ? \"true\" : \"false\";\n        if (!f.flDash)\n        {\n            // right align\n            if (f.width > s.length)\n                foreach (i ; 0 .. f.width - s.length) put(w, ' ');\n            put(w, s);\n        }\n        else\n        {\n            // left align\n            put(w, s);\n            if (f.width > s.length)\n                foreach (i ; 0 .. f.width - s.length) put(w, ' ');\n        }\n    }\n    else\n        formatValueImpl(w, cast(int) val, f);\n}\n\n@safe pure unittest\n{\n    assertCTFEable!(\n    {\n        formatTest( false, \"false\" );\n        formatTest( true,  \"true\"  );\n    });\n}\n@system unittest\n{\n    class C1 { bool val; alias val this; this(bool v){ val = v; } }\n    class C2 { bool val; alias val this; this(bool v){ val = v; }\n               override string toString() const { return \"C\"; } }\n    formatTest( new C1(false), \"false\" );\n    formatTest( new C1(true),  \"true\" );\n    formatTest( new C2(false), \"C\" );\n    formatTest( new C2(true),  \"C\" );\n\n    struct S1 { bool val; alias val this; }\n    struct S2 { bool val; alias val this;\n                string toString() const { return \"S\"; } }\n    formatTest( S1(false), \"false\" );\n    formatTest( S1(true),  \"true\"  );\n    formatTest( S2(false), \"S\" );\n    formatTest( S2(true),  \"S\" );\n}\n\n@safe pure unittest\n{\n    string t1 = format(\"[%6s] [%6s] [%-6s]\", true, false, true);\n    assert(t1 == \"[  true] [ false] [true  ]\");\n\n    string t2 = format(\"[%3s] [%-2s]\", true, false);\n    assert(t2 == \"[true] [false]\");\n}\n\n/*\n    `null` literal is formatted as `\"null\"`\n*/\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f)\nif (is(Unqual!T == typeof(null)) && !is(T == enum) && !hasToString!(T, Char))\n{\n    enforceFmt(f.spec == 's',\n        \"null literal cannot match %\" ~ f.spec);\n\n    put(w, \"null\");\n}\n\n@safe pure unittest\n{\n    assert(collectExceptionMsg!FormatException(format(\"%p\", null)).back == 'p');\n\n    assertCTFEable!(\n    {\n        formatTest( null, \"null\" );\n    });\n}\n\n/*\n    Integrals are formatted like $(REF printf, core, stdc, stdio).\n*/\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f)\nif (is(IntegralTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))\n{\n    alias U = IntegralTypeOf!T;\n    U val = obj;    // Extracting alias this may be impure/system/may-throw\n\n    if (f.spec == 'r')\n    {\n        // raw write, skip all else and write the thing\n        auto raw = (ref val)@trusted{\n            return (cast(const char*) &val)[0 .. val.sizeof];\n        }(val);\n        if (needToSwapEndianess(f))\n        {\n            foreach_reverse (c; raw)\n                put(w, c);\n        }\n        else\n        {\n            foreach (c; raw)\n                put(w, c);\n        }\n        return;\n    }\n\n    immutable uint base =\n        f.spec == 'x' || f.spec == 'X' ? 16 :\n        f.spec == 'o' ? 8 :\n        f.spec == 'b' ? 2 :\n        f.spec == 's' || f.spec == 'd' || f.spec == 'u' ? 10 :\n        0;\n    enforceFmt(base > 0,\n        \"incompatible format character for integral argument: %\" ~ f.spec);\n\n    // Forward on to formatIntegral to handle both U and const(U)\n    // Saves duplication of code for both versions.\n    static if (is(ucent) && (is(U == cent) || is(U == ucent)))\n        alias C = U;\n    else static if (isSigned!U)\n        alias C = long;\n    else\n        alias C = ulong;\n    formatIntegral(w, cast(C) val, f, base, Unsigned!U.max);\n}\n\nprivate void formatIntegral(Writer, T, Char)(ref Writer w, const(T) val, const ref FormatSpec!Char fs,\n    uint base, ulong mask)\n{\n    T arg = val;\n\n    immutable negative = (base == 10 && arg < 0);\n    if (negative)\n    {\n        arg = -arg;\n    }\n\n    // All unsigned integral types should fit in ulong.\n    static if (is(ucent) && is(typeof(arg) == ucent))\n        formatUnsigned(w, (cast(ucent) arg) & mask, fs, base, negative);\n    else\n        formatUnsigned(w, (cast(ulong) arg) & mask, fs, base, negative);\n}\n\nprivate void formatUnsigned(Writer, T, Char)\n(ref Writer w, T arg, const ref FormatSpec!Char fs, uint base, bool negative)\n{\n    /* Write string:\n     *    leftpad prefix1 prefix2 zerofill digits rightpad\n     */\n\n    /* Convert arg to digits[].\n     * Note that 0 becomes an empty digits[]\n     */\n    char[64] buffer = void; // 64 bits in base 2 at most\n    char[] digits;\n    if (arg < base && base <= 10 && arg)\n    {\n        // Most numbers are a single digit - avoid expensive divide\n        buffer[0] = cast(char)(arg + '0');\n        digits = buffer[0 .. 1];\n    }\n    else\n    {\n        size_t i = buffer.length;\n        while (arg)\n        {\n            --i;\n            char c = cast(char) (arg % base);\n            arg /= base;\n            if (c < 10)\n                buffer[i] = cast(char)(c + '0');\n            else\n                buffer[i] = cast(char)(c + (fs.spec == 'x' ? 'a' - 10 : 'A' - 10));\n        }\n        digits = buffer[i .. $]; // got the digits without the sign\n    }\n\n\n    immutable precision = (fs.precision == fs.UNSPECIFIED) ? 1 : fs.precision;\n\n    char padChar = 0;\n    if (!fs.flDash)\n    {\n        padChar = (fs.flZero && fs.precision == fs.UNSPECIFIED) ? '0' : ' ';\n    }\n\n    // Compute prefix1 and prefix2\n    char prefix1 = 0;\n    char prefix2 = 0;\n    if (base == 10)\n    {\n        if (negative)\n            prefix1 = '-';\n        else if (fs.flPlus)\n            prefix1 = '+';\n        else if (fs.flSpace)\n            prefix1 = ' ';\n    }\n    else if (base == 16 && fs.flHash && digits.length)\n    {\n        prefix1 = '0';\n        prefix2 = fs.spec == 'x' ? 'x' : 'X';\n    }\n    // adjust precision to print a '0' for octal if alternate format is on\n    else if (base == 8 && fs.flHash &&\n             (precision <= 1 || precision <= digits.length) && // too low precision\n             digits.length > 0)\n        prefix1 = '0';\n\n    size_t zerofill = precision > digits.length ? precision - digits.length : 0;\n    size_t leftpad = 0;\n    size_t rightpad = 0;\n\n    immutable size_t dlen = digits.length == 0 ? 0 : digits.length - 1;\n    immutable ptrdiff_t spacesToPrint =\n        fs.width - (\n              (prefix1 != 0)\n            + (prefix2 != 0)\n            + zerofill\n            + digits.length\n            + ((fs.flSeparator != 0) * (dlen / fs.separators))\n        );\n    if (spacesToPrint > 0) // need to do some padding\n    {\n        if (padChar == '0')\n            zerofill += spacesToPrint;\n        else if (padChar)\n            leftpad = spacesToPrint;\n        else\n            rightpad = spacesToPrint;\n    }\n\n    // Print\n    foreach (i ; 0 .. leftpad)\n        put(w, ' ');\n\n    if (prefix1) put(w, prefix1);\n    if (prefix2) put(w, prefix2);\n\n    if (fs.flSeparator)\n    {\n        if (zerofill > 0)\n        {\n            put(w, '0');\n            --zerofill;\n        }\n\n        int j = fs.width;\n        for (size_t i = 0; i < zerofill; ++i, --j)\n        {\n            if (j != fs.width && j % fs.separators == 0)\n            {\n                put(w, fs.separatorChar);\n                ++i;\n            }\n            if (i < zerofill)\n            {\n                   put(w, '0');\n            }\n        }\n    }\n    else\n    {\n        foreach (i ; 0 .. zerofill)\n            put(w, '0');\n    }\n\n    if (fs.flSeparator)\n    {\n        for (size_t j = 0; j < digits.length; ++j)\n        {\n            if (j != 0 && (digits.length - j) % fs.separators == 0)\n            {\n                put(w, fs.separatorChar);\n            }\n            put(w, digits[j]);\n        }\n    }\n    else\n    {\n        put(w, digits);\n    }\n\n    foreach (i ; 0 .. rightpad)\n        put(w, ' ');\n}\n\n@safe pure unittest  // bugzilla 18838\n{\n    assert(\"%12,d\".format(0) == \"           0\");\n}\n\n@safe pure unittest\n{\n    assert(collectExceptionMsg!FormatException(format(\"%c\", 5)).back == 'c');\n\n    assertCTFEable!(\n    {\n        formatTest(9, \"9\");\n        formatTest( 10, \"10\" );\n    });\n}\n\n@system unittest\n{\n    class C1 { long val; alias val this; this(long v){ val = v; } }\n    class C2 { long val; alias val this; this(long v){ val = v; }\n               override string toString() const { return \"C\"; } }\n    formatTest( new C1(10), \"10\" );\n    formatTest( new C2(10), \"C\" );\n\n    struct S1 { long val; alias val this; }\n    struct S2 { long val; alias val this;\n                string toString() const { return \"S\"; } }\n    formatTest( S1(10), \"10\" );\n    formatTest( S2(10), \"S\" );\n}\n\n// bugzilla 9117\n@safe unittest\n{\n    static struct Frop {}\n\n    static struct Foo\n    {\n        int n = 0;\n        alias n this;\n        T opCast(T) () if (is(T == Frop))\n        {\n            return Frop();\n        }\n        string toString()\n        {\n            return \"Foo\";\n        }\n    }\n\n    static struct Bar\n    {\n        Foo foo;\n        alias foo this;\n        string toString()\n        {\n            return \"Bar\";\n        }\n    }\n\n    const(char)[] result;\n    void put(scope const char[] s){ result ~= s; }\n\n    Foo foo;\n    formattedWrite(&put, \"%s\", foo);    // OK\n    assert(result == \"Foo\");\n\n    result = null;\n\n    Bar bar;\n    formattedWrite(&put, \"%s\", bar);    // NG\n    assert(result == \"Bar\");\n\n    result = null;\n\n    int i = 9;\n    formattedWrite(&put, \"%s\", 9);\n    assert(result == \"9\");\n}\n\nprivate enum ctfpMessage = \"Cannot format floating point types at compile-time\";\n\n/*\n    Floating-point values are formatted like $(REF printf, core, stdc, stdio)\n */\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f)\nif (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))\n{\n    import std.algorithm.comparison : min;\n    import std.algorithm.searching : find;\n    import std.string : indexOf, indexOfAny, indexOfNeither;\n\n    FormatSpec!Char fs = f; // fs is copy for change its values.\n    FloatingPointTypeOf!T val = obj;\n\n    if (fs.spec == 'r')\n    {\n        // raw write, skip all else and write the thing\n        auto raw = (ref val)@trusted{\n            return (cast(const char*) &val)[0 .. val.sizeof];\n        }(val);\n        if (needToSwapEndianess(f))\n        {\n            foreach_reverse (c; raw)\n                put(w, c);\n        }\n        else\n        {\n            foreach (c; raw)\n                put(w, c);\n        }\n        return;\n    }\n    enforceFmt(find(\"fgFGaAeEs\", fs.spec).length,\n        \"incompatible format character for floating point argument: %\" ~ fs.spec);\n    enforceFmt(!__ctfe, ctfpMessage);\n\n    version (CRuntime_Microsoft)\n    {\n        import std.math : isNaN, isInfinity;\n        immutable double tval = val; // convert early to get \"inf\" in case of overflow\n        string s;\n        if (isNaN(tval))\n            s = \"nan\"; // snprintf writes 1.#QNAN\n        else if (isInfinity(tval))\n            s = val >= 0 ? \"inf\" : \"-inf\"; // snprintf writes 1.#INF\n\n        if (s.length > 0)\n        {\n          version (none)\n          {\n            return formatValueImpl(w, s, f);\n          }\n          else  // FIXME:workaround\n          {\n            s = s[0 .. f.precision < $ ? f.precision : $];\n            if (!f.flDash)\n            {\n                // right align\n                if (f.width > s.length)\n                    foreach (j ; 0 .. f.width - s.length) put(w, ' ');\n                put(w, s);\n            }\n            else\n            {\n                // left align\n                put(w, s);\n                if (f.width > s.length)\n                    foreach (j ; 0 .. f.width - s.length) put(w, ' ');\n            }\n            return;\n          }\n        }\n    }\n    else\n        alias tval = val;\n    if (fs.spec == 's') fs.spec = 'g';\n    char[1 /*%*/ + 5 /*flags*/ + 3 /*width.prec*/ + 2 /*format*/\n                     + 1 /*\\0*/] sprintfSpec = void;\n    sprintfSpec[0] = '%';\n    uint i = 1;\n    if (fs.flDash) sprintfSpec[i++] = '-';\n    if (fs.flPlus) sprintfSpec[i++] = '+';\n    if (fs.flZero) sprintfSpec[i++] = '0';\n    if (fs.flSpace) sprintfSpec[i++] = ' ';\n    if (fs.flHash) sprintfSpec[i++] = '#';\n    sprintfSpec[i .. i + 3] = \"*.*\";\n    i += 3;\n    if (is(Unqual!(typeof(val)) == real)) sprintfSpec[i++] = 'L';\n    sprintfSpec[i++] = fs.spec;\n    sprintfSpec[i] = 0;\n    //printf(\"format: '%s'; geeba: %g\\n\", sprintfSpec.ptr, val);\n    char[512] buf = void;\n\n    immutable n = ()@trusted{\n        import core.stdc.stdio : snprintf;\n        return snprintf(buf.ptr, buf.length,\n                        sprintfSpec.ptr,\n                        fs.width,\n                        // negative precision is same as no precision specified\n                        fs.precision == fs.UNSPECIFIED ? -1 : fs.precision,\n                        tval);\n    }();\n\n    enforceFmt(n >= 0,\n        \"floating point formatting failure\");\n\n    auto len = min(n, buf.length-1);\n    ptrdiff_t dot = buf[0 .. len].indexOf('.');\n    if (fs.flSeparator)\n    {\n        ptrdiff_t firstDigit = buf[0 .. len].indexOfAny(\"0123456789\");\n        ptrdiff_t ePos = buf[0 .. len].indexOf('e');\n        auto dotIdx = dot == -1 ? ePos == -1 ? len : ePos : dot;\n        size_t j;\n\n        ptrdiff_t firstLen = dotIdx - firstDigit;\n\n        size_t separatorScoreCnt = firstLen / fs.separators;\n\n        size_t afterDotIdx;\n        if (ePos != -1)\n        {\n            afterDotIdx = ePos;\n        }\n        else\n        {\n            afterDotIdx = len;\n        }\n\n        if (dot != -1)\n        {\n            ptrdiff_t mantissaLen = afterDotIdx - (dot + 1);\n            separatorScoreCnt += (mantissaLen > 0) ? (mantissaLen - 1) / fs.separators : 0;\n        }\n\n        // plus, minus prefix\n        ptrdiff_t digitsBegin = buf[0 .. separatorScoreCnt].indexOfNeither(\" \");\n        if (digitsBegin == -1)\n        {\n            digitsBegin = separatorScoreCnt;\n        }\n        put(w, buf[digitsBegin .. firstDigit]);\n\n        // digits until dot with separator\n        for (j = 0; j < firstLen; ++j)\n        {\n            if (j > 0 && (firstLen - j) % fs.separators == 0)\n            {\n                put(w, fs.separatorChar);\n            }\n            put(w, buf[j + firstDigit]);\n        }\n\n        // print dot for decimal numbers only or with '#' format specifier\n        if (dot != -1 || fs.flHash)\n        {\n            put(w, '.');\n        }\n\n        // digits after dot\n        for (j = dotIdx + 1; j < afterDotIdx; ++j)\n        {\n            auto realJ = (j - (dotIdx + 1));\n            if (realJ != 0 && realJ % fs.separators == 0)\n            {\n                put(w, fs.separatorChar);\n            }\n            put(w, buf[j]);\n        }\n\n        // rest\n        if (ePos != -1)\n        {\n            put(w, buf[afterDotIdx .. len]);\n        }\n    }\n    else\n    {\n        put(w, buf[0 .. len]);\n    }\n}\n\n@safe unittest\n{\n    assert(format(\"%.1f\", 1337.7) == \"1337.7\");\n    assert(format(\"%,3.2f\", 1331.982) == \"1,331.98\");\n    assert(format(\"%,3.0f\", 1303.1982) == \"1,303\");\n    assert(format(\"%#,3.4f\", 1303.1982) == \"1,303.198,2\");\n    assert(format(\"%#,3.0f\", 1303.1982) == \"1,303.\");\n}\n\n@safe /*pure*/ unittest     // formatting floating point values is now impure\n{\n    import std.conv : to;\n\n    assert(collectExceptionMsg!FormatException(format(\"%d\", 5.1)).back == 'd');\n\n    static foreach (T; AliasSeq!(float, double, real))\n    {\n        formatTest( to!(          T)(5.5), \"5.5\" );\n        formatTest( to!(    const T)(5.5), \"5.5\" );\n        formatTest( to!(immutable T)(5.5), \"5.5\" );\n\n        formatTest( T.nan, \"nan\" );\n    }\n}\n\n@system unittest\n{\n    formatTest( 2.25, \"2.25\" );\n\n    class C1 { double val; alias val this; this(double v){ val = v; } }\n    class C2 { double val; alias val this; this(double v){ val = v; }\n               override string toString() const { return \"C\"; } }\n    formatTest( new C1(2.25), \"2.25\" );\n    formatTest( new C2(2.25), \"C\" );\n\n    struct S1 { double val; alias val this; }\n    struct S2 { double val; alias val this;\n                string toString() const { return \"S\"; } }\n    formatTest( S1(2.25), \"2.25\" );\n    formatTest( S2(2.25), \"S\" );\n}\n\n/*\n    Formatting a `creal` is deprecated but still kept around for a while.\n */\ndeprecated(\"Use of complex types is deprecated. Use std.complex\")\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f)\nif (is(Unqual!T : creal) && !is(T == enum) && !hasToString!(T, Char))\n{\n    immutable creal val = obj;\n\n    formatValueImpl(w, val.re, f);\n    if (val.im >= 0)\n    {\n        put(w, '+');\n    }\n    formatValueImpl(w, val.im, f);\n    put(w, 'i');\n}\n\nversion (TestComplex)\ndeprecated\n@safe /*pure*/ unittest     // formatting floating point values is now impure\n{\n    import std.conv : to;\n    static foreach (T; AliasSeq!(cfloat, cdouble, creal))\n    {\n        formatTest( to!(          T)(1 + 1i), \"1+1i\" );\n        formatTest( to!(    const T)(1 + 1i), \"1+1i\" );\n        formatTest( to!(immutable T)(1 + 1i), \"1+1i\" );\n    }\n    static foreach (T; AliasSeq!(cfloat, cdouble, creal))\n    {\n        formatTest( to!(          T)(0 - 3i), \"0-3i\" );\n        formatTest( to!(    const T)(0 - 3i), \"0-3i\" );\n        formatTest( to!(immutable T)(0 - 3i), \"0-3i\" );\n    }\n}\n\nversion (TestComplex)\ndeprecated\n@system unittest\n{\n    formatTest( 3+2.25i, \"3+2.25i\" );\n\n    class C1 { cdouble val; alias val this; this(cdouble v){ val = v; } }\n    class C2 { cdouble val; alias val this; this(cdouble v){ val = v; }\n               override string toString() const { return \"C\"; } }\n    formatTest( new C1(3+2.25i), \"3+2.25i\" );\n    formatTest( new C2(3+2.25i), \"C\" );\n\n    struct S1 { cdouble val; alias val this; }\n    struct S2 { cdouble val; alias val this;\n                string toString() const { return \"S\"; } }\n    formatTest( S1(3+2.25i), \"3+2.25i\" );\n    formatTest( S2(3+2.25i), \"S\" );\n}\n\n/*\n    Formatting an `ireal` is deprecated but still kept around for a while.\n */\ndeprecated(\"Use of imaginary types is deprecated. Use std.complex\")\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f)\nif (is(Unqual!T : ireal) && !is(T == enum) && !hasToString!(T, Char))\n{\n    immutable ireal val = obj;\n\n    formatValueImpl(w, val.im, f);\n    put(w, 'i');\n}\n\nversion (TestComplex)\ndeprecated\n@safe /*pure*/ unittest     // formatting floating point values is now impure\n{\n    import std.conv : to;\n    static foreach (T; AliasSeq!(ifloat, idouble, ireal))\n    {\n        formatTest( to!(          T)(1i), \"1i\" );\n        formatTest( to!(    const T)(1i), \"1i\" );\n        formatTest( to!(immutable T)(1i), \"1i\" );\n    }\n}\n\nversion (TestComplex)\ndeprecated\n@system unittest\n{\n    formatTest( 2.25i, \"2.25i\" );\n\n    class C1 { idouble val; alias val this; this(idouble v){ val = v; } }\n    class C2 { idouble val; alias val this; this(idouble v){ val = v; }\n               override string toString() const { return \"C\"; } }\n    formatTest( new C1(2.25i), \"2.25i\" );\n    formatTest( new C2(2.25i), \"C\" );\n\n    struct S1 { idouble val; alias val this; }\n    struct S2 { idouble val; alias val this;\n                string toString() const { return \"S\"; } }\n    formatTest( S1(2.25i), \"2.25i\" );\n    formatTest( S2(2.25i), \"S\" );\n}\n\n/*\n    Individual characters are formatted as Unicode characters with `%s`\n    and as integers with integral-specific format specs\n */\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f)\nif (is(CharTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))\n{\n    CharTypeOf!T val = obj;\n\n    if (f.spec == 's' || f.spec == 'c')\n    {\n        put(w, val);\n    }\n    else\n    {\n        alias U = AliasSeq!(ubyte, ushort, uint)[CharTypeOf!T.sizeof/2];\n        formatValueImpl(w, cast(U) val, f);\n    }\n}\n\n@safe pure unittest\n{\n    assertCTFEable!(\n    {\n        formatTest( 'c', \"c\" );\n    });\n}\n\n@system unittest\n{\n    class C1 { char val; alias val this; this(char v){ val = v; } }\n    class C2 { char val; alias val this; this(char v){ val = v; }\n               override string toString() const { return \"C\"; } }\n    formatTest( new C1('c'), \"c\" );\n    formatTest( new C2('c'), \"C\" );\n\n    struct S1 { char val; alias val this; }\n    struct S2 { char val; alias val this;\n                string toString() const { return \"S\"; } }\n    formatTest( S1('c'), \"c\" );\n    formatTest( S2('c'), \"S\" );\n}\n\n@safe unittest\n{\n    //Little Endian\n    formatTest( \"%-r\", cast( char)'c', ['c'         ] );\n    formatTest( \"%-r\", cast(wchar)'c', ['c', 0      ] );\n    formatTest( \"%-r\", cast(dchar)'c', ['c', 0, 0, 0] );\n    formatTest( \"%-r\", '本', ['\\x2c', '\\x67'] );\n\n    //Big Endian\n    formatTest( \"%+r\", cast( char)'c', [         'c'] );\n    formatTest( \"%+r\", cast(wchar)'c', [0,       'c'] );\n    formatTest( \"%+r\", cast(dchar)'c', [0, 0, 0, 'c'] );\n    formatTest( \"%+r\", '本', ['\\x67', '\\x2c'] );\n}\n\n/*\n    Strings are formatted like $(REF printf, core, stdc, stdio)\n */\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f)\nif (is(StringTypeOf!T) && !is(StaticArrayTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))\n{\n    Unqual!(StringTypeOf!T) val = obj;  // for `alias this`, see bug5371\n    formatRange(w, val, f);\n}\n\n@safe unittest\n{\n    formatTest( \"abc\", \"abc\" );\n}\n\n@system unittest\n{\n    // Test for bug 5371 for classes\n    class C1 { const string var; alias var this; this(string s){ var = s; } }\n    class C2 {       string var; alias var this; this(string s){ var = s; } }\n    formatTest( new C1(\"c1\"), \"c1\" );\n    formatTest( new C2(\"c2\"), \"c2\" );\n\n    // Test for bug 5371 for structs\n    struct S1 { const string var; alias var this; }\n    struct S2 {       string var; alias var this; }\n    formatTest( S1(\"s1\"), \"s1\" );\n    formatTest( S2(\"s2\"), \"s2\" );\n}\n\n@system unittest\n{\n    class  C3 { string val; alias val this; this(string s){ val = s; }\n                override string toString() const { return \"C\"; } }\n    formatTest( new C3(\"c3\"), \"C\" );\n\n    struct S3 { string val; alias val this;\n                string toString() const { return \"S\"; } }\n    formatTest( S3(\"s3\"), \"S\" );\n}\n\n@safe pure unittest\n{\n    //Little Endian\n    formatTest( \"%-r\", \"ab\"c, ['a'         , 'b'         ] );\n    formatTest( \"%-r\", \"ab\"w, ['a', 0      , 'b', 0      ] );\n    formatTest( \"%-r\", \"ab\"d, ['a', 0, 0, 0, 'b', 0, 0, 0] );\n    formatTest( \"%-r\", \"日本語\"c, ['\\xe6', '\\x97', '\\xa5', '\\xe6', '\\x9c', '\\xac', '\\xe8', '\\xaa', '\\x9e'] );\n    formatTest( \"%-r\", \"日本語\"w, ['\\xe5', '\\x65', '\\x2c', '\\x67', '\\x9e', '\\x8a']);\n    formatTest( \"%-r\", \"日本語\"d, ['\\xe5', '\\x65', '\\x00', '\\x00', '\\x2c', '\\x67',\n        '\\x00', '\\x00', '\\x9e', '\\x8a', '\\x00', '\\x00'] );\n\n    //Big Endian\n    formatTest( \"%+r\", \"ab\"c, [         'a',          'b'] );\n    formatTest( \"%+r\", \"ab\"w, [      0, 'a',       0, 'b'] );\n    formatTest( \"%+r\", \"ab\"d, [0, 0, 0, 'a', 0, 0, 0, 'b'] );\n    formatTest( \"%+r\", \"日本語\"c, ['\\xe6', '\\x97', '\\xa5', '\\xe6', '\\x9c', '\\xac', '\\xe8', '\\xaa', '\\x9e'] );\n    formatTest( \"%+r\", \"日本語\"w, ['\\x65', '\\xe5', '\\x67', '\\x2c', '\\x8a', '\\x9e'] );\n    formatTest( \"%+r\", \"日本語\"d, ['\\x00', '\\x00', '\\x65', '\\xe5', '\\x00', '\\x00',\n        '\\x67', '\\x2c', '\\x00', '\\x00', '\\x8a', '\\x9e'] );\n}\n\n/*\n    Static-size arrays are formatted as dynamic arrays.\n */\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, auto ref T obj, const ref FormatSpec!Char f)\nif (is(StaticArrayTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))\n{\n    formatValueImpl(w, obj[], f);\n}\n\n@safe unittest    // Test for issue 8310\n{\n    import std.array : appender;\n    FormatSpec!char f;\n    auto w = appender!string();\n\n    char[2] two = ['a', 'b'];\n    formatValue(w, two, f);\n\n    char[2] getTwo(){ return two; }\n    formatValue(w, getTwo(), f);\n}\n\n/*\n    Dynamic arrays are formatted as input ranges.\n */\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f)\nif (is(DynamicArrayTypeOf!T) && !is(StringTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))\n{\n    static if (is(const(ArrayTypeOf!T) == const(void[])))\n    {\n        formatValueImpl(w, cast(const ubyte[]) obj, f);\n    }\n    else static if (!isInputRange!T)\n    {\n        alias U = Unqual!(ArrayTypeOf!T);\n        static assert(isInputRange!U);\n        U val = obj;\n        formatValueImpl(w, val, f);\n    }\n    else\n    {\n        formatRange(w, obj, f);\n    }\n}\n\n// alias this, input range I/F, and toString()\n@system unittest\n{\n    struct S(int flags)\n    {\n        int[] arr;\n      static if (flags & 1)\n        alias arr this;\n\n      static if (flags & 2)\n      {\n        @property bool empty() const { return arr.length == 0; }\n        @property int front() const { return arr[0] * 2; }\n        void popFront() { arr = arr[1..$]; }\n      }\n\n      static if (flags & 4)\n        string toString() const { return \"S\"; }\n    }\n    formatTest(S!0b000([0, 1, 2]), \"S!0([0, 1, 2])\");\n    formatTest(S!0b001([0, 1, 2]), \"[0, 1, 2]\");        // Test for bug 7628\n    formatTest(S!0b010([0, 1, 2]), \"[0, 2, 4]\");\n    formatTest(S!0b011([0, 1, 2]), \"[0, 2, 4]\");\n    formatTest(S!0b100([0, 1, 2]), \"S\");\n    formatTest(S!0b101([0, 1, 2]), \"S\");                // Test for bug 7628\n    formatTest(S!0b110([0, 1, 2]), \"S\");\n    formatTest(S!0b111([0, 1, 2]), \"S\");\n\n    class C(uint flags)\n    {\n        int[] arr;\n      static if (flags & 1)\n        alias arr this;\n\n        this(int[] a) { arr = a; }\n\n      static if (flags & 2)\n      {\n        @property bool empty() const { return arr.length == 0; }\n        @property int front() const { return arr[0] * 2; }\n        void popFront() { arr = arr[1..$]; }\n      }\n\n      static if (flags & 4)\n        override string toString() const { return \"C\"; }\n    }\n    formatTest(new C!0b000([0, 1, 2]), (new C!0b000([])).toString());\n    formatTest(new C!0b001([0, 1, 2]), \"[0, 1, 2]\");    // Test for bug 7628\n    formatTest(new C!0b010([0, 1, 2]), \"[0, 2, 4]\");\n    formatTest(new C!0b011([0, 1, 2]), \"[0, 2, 4]\");\n    formatTest(new C!0b100([0, 1, 2]), \"C\");\n    formatTest(new C!0b101([0, 1, 2]), \"C\");            // Test for bug 7628\n    formatTest(new C!0b110([0, 1, 2]), \"C\");\n    formatTest(new C!0b111([0, 1, 2]), \"C\");\n}\n\n@system unittest\n{\n    // void[]\n    void[] val0;\n    formatTest( val0, \"[]\" );\n\n    void[] val = cast(void[]) cast(ubyte[])[1, 2, 3];\n    formatTest( val, \"[1, 2, 3]\" );\n\n    void[0] sval0 = [];\n    formatTest( sval0, \"[]\");\n\n    void[3] sval = cast(void[3]) cast(ubyte[3])[1, 2, 3];\n    formatTest( sval, \"[1, 2, 3]\" );\n}\n\n@safe unittest\n{\n    // const(T[]) -> const(T)[]\n    const short[] a = [1, 2, 3];\n    formatTest( a, \"[1, 2, 3]\" );\n\n    struct S { const(int[]) arr; alias arr this; }\n    auto s = S([1,2,3]);\n    formatTest( s, \"[1, 2, 3]\" );\n}\n\n@safe unittest\n{\n    // 6640\n    struct Range\n    {\n      @safe:\n        string value;\n        @property bool empty() const { return !value.length; }\n        @property dchar front() const { return value.front; }\n        void popFront() { value.popFront(); }\n\n        @property size_t length() const { return value.length; }\n    }\n    immutable table =\n    [\n        [\"[%s]\", \"[string]\"],\n        [\"[%10s]\", \"[    string]\"],\n        [\"[%-10s]\", \"[string    ]\"],\n        [\"[%(%02x %)]\", \"[73 74 72 69 6e 67]\"],\n        [\"[%(%c %)]\", \"[s t r i n g]\"],\n    ];\n    foreach (e; table)\n    {\n        formatTest(e[0], \"string\", e[1]);\n        formatTest(e[0], Range(\"string\"), e[1]);\n    }\n}\n\n@system unittest\n{\n    // string literal from valid UTF sequence is encoding free.\n    static foreach (StrType; AliasSeq!(string, wstring, dstring))\n    {\n        // Valid and printable (ASCII)\n        formatTest( [cast(StrType)\"hello\"],\n                    `[\"hello\"]` );\n\n        // 1 character escape sequences (' is not escaped in strings)\n        formatTest( [cast(StrType)\"\\\"'\\0\\\\\\a\\b\\f\\n\\r\\t\\v\"],\n                    `[\"\\\"'\\0\\\\\\a\\b\\f\\n\\r\\t\\v\"]` );\n\n        // 1 character optional escape sequences\n        formatTest( [cast(StrType)\"\\'\\?\"],\n                    `[\"'?\"]` );\n\n        // Valid and non-printable code point (<= U+FF)\n        formatTest( [cast(StrType)\"\\x10\\x1F\\x20test\"],\n                    `[\"\\x10\\x1F test\"]` );\n\n        // Valid and non-printable code point (<= U+FFFF)\n        formatTest( [cast(StrType)\"\\u200B..\\u200F\"],\n                    `[\"\\u200B..\\u200F\"]` );\n\n        // Valid and non-printable code point (<= U+10FFFF)\n        formatTest( [cast(StrType)\"\\U000E0020..\\U000E007F\"],\n                    `[\"\\U000E0020..\\U000E007F\"]` );\n    }\n\n    // invalid UTF sequence needs hex-string literal postfix (c/w/d)\n    {\n        // U+FFFF with UTF-8 (Invalid code point for interchange)\n        formatTest( [cast(string)[0xEF, 0xBF, 0xBF]],\n                    `[x\"EF BF BF\"c]` );\n\n        // U+FFFF with UTF-16 (Invalid code point for interchange)\n        formatTest( [cast(wstring)[0xFFFF]],\n                    `[x\"FFFF\"w]` );\n\n        // U+FFFF with UTF-32 (Invalid code point for interchange)\n        formatTest( [cast(dstring)[0xFFFF]],\n                    `[x\"FFFF\"d]` );\n    }\n}\n\n@safe unittest\n{\n    // nested range formatting with array of string\n    formatTest( \"%({%(%02x %)}%| %)\", [\"test\", \"msg\"],\n                `{74 65 73 74} {6d 73 67}` );\n}\n\n@safe unittest\n{\n    // stop auto escaping inside range formatting\n    auto arr = [\"hello\", \"world\"];\n    formatTest( \"%(%s, %)\",  arr, `\"hello\", \"world\"` );\n    formatTest( \"%-(%s, %)\", arr, `hello, world` );\n\n    auto aa1 = [1:\"hello\", 2:\"world\"];\n    formatTest( \"%(%s:%s, %)\",  aa1, [`1:\"hello\", 2:\"world\"`, `2:\"world\", 1:\"hello\"`] );\n    formatTest( \"%-(%s:%s, %)\", aa1, [`1:hello, 2:world`, `2:world, 1:hello`] );\n\n    auto aa2 = [1:[\"ab\", \"cd\"], 2:[\"ef\", \"gh\"]];\n    formatTest( \"%-(%s:%s, %)\",        aa2, [`1:[\"ab\", \"cd\"], 2:[\"ef\", \"gh\"]`, `2:[\"ef\", \"gh\"], 1:[\"ab\", \"cd\"]`] );\n    formatTest( \"%-(%s:%(%s%), %)\",    aa2, [`1:\"ab\"\"cd\", 2:\"ef\"\"gh\"`, `2:\"ef\"\"gh\", 1:\"ab\"\"cd\"`] );\n    formatTest( \"%-(%s:%-(%s%)%|, %)\", aa2, [`1:abcd, 2:efgh`, `2:efgh, 1:abcd`] );\n}\n\n// input range formatting\nprivate void formatRange(Writer, T, Char)(ref Writer w, ref T val, const ref FormatSpec!Char f)\nif (isInputRange!T)\n{\n    import std.conv : text;\n\n    // Formatting character ranges like string\n    if (f.spec == 's')\n    {\n        alias E = ElementType!T;\n\n        static if (!is(E == enum) && is(CharTypeOf!E))\n        {\n            static if (is(StringTypeOf!T))\n            {\n                auto s = val[0 .. f.precision < $ ? f.precision : $];\n\n                size_t width;\n                if (f.width > 0)\n                {\n                    // strings that are fully made of ASCII characters\n                    // can be aligned w/o graphemeStride\n                    bool onlyAscii = true;\n                    for (size_t i; i < s.length; i++)\n                    {\n                        if (s[i] > 0x7F)\n                        {\n                            onlyAscii = false;\n                            break;\n                        }\n                    }\n                    if (!onlyAscii)\n                    {\n                        //TODO: optimize this\n                        import std.uni : graphemeStride;\n                        for (size_t i; i < s.length; i += graphemeStride(s, i))\n                            width++;\n                    }\n                    else width = s.length;\n                }\n                else width = s.length;\n\n                if (!f.flDash)\n                {\n                    // right align\n                    if (f.width > width)\n                        foreach (i ; 0 .. f.width - width) put(w, ' ');\n                    put(w, s);\n                }\n                else\n                {\n                    // left align\n                    put(w, s);\n                    if (f.width > width)\n                        foreach (i ; 0 .. f.width - width) put(w, ' ');\n                }\n            }\n            else\n            {\n                if (!f.flDash)\n                {\n                    static if (hasLength!T)\n                    {\n                        // right align\n                        auto len = val.length;\n                    }\n                    else static if (isForwardRange!T && !isInfinite!T)\n                    {\n                        auto len = walkLength(val.save);\n                    }\n                    else\n                    {\n                        enforceFmt(f.width == 0, \"Cannot right-align a range without length\");\n                        size_t len = 0;\n                    }\n                    if (f.precision != f.UNSPECIFIED && len > f.precision)\n                        len = f.precision;\n\n                    if (f.width > len)\n                        foreach (i ; 0 .. f.width - len)\n                            put(w, ' ');\n                    if (f.precision == f.UNSPECIFIED)\n                        put(w, val);\n                    else\n                    {\n                        size_t printed = 0;\n                        for (; !val.empty && printed < f.precision; val.popFront(), ++printed)\n                            put(w, val.front);\n                    }\n                }\n                else\n                {\n                    size_t printed = void;\n\n                    // left align\n                    if (f.precision == f.UNSPECIFIED)\n                    {\n                        static if (hasLength!T)\n                        {\n                            printed = val.length;\n                            put(w, val);\n                        }\n                        else\n                        {\n                            printed = 0;\n                            for (; !val.empty; val.popFront(), ++printed)\n                                put(w, val.front);\n                        }\n                    }\n                    else\n                    {\n                        printed = 0;\n                        for (; !val.empty && printed < f.precision; val.popFront(), ++printed)\n                            put(w, val.front);\n                    }\n\n                    if (f.width > printed)\n                        foreach (i ; 0 .. f.width - printed)\n                            put(w, ' ');\n                }\n            }\n        }\n        else\n        {\n            put(w, f.seqBefore);\n            if (!val.empty)\n            {\n                formatElement(w, val.front, f);\n                val.popFront();\n                for (size_t i; !val.empty; val.popFront(), ++i)\n                {\n                    put(w, f.seqSeparator);\n                    formatElement(w, val.front, f);\n                }\n            }\n            static if (!isInfinite!T) put(w, f.seqAfter);\n        }\n    }\n    else if (f.spec == 'r')\n    {\n        static if (is(DynamicArrayTypeOf!T))\n        {\n            alias ARR = DynamicArrayTypeOf!T;\n            foreach (e ; cast(ARR) val)\n            {\n                formatValue(w, e, f);\n            }\n        }\n        else\n        {\n            for (size_t i; !val.empty; val.popFront(), ++i)\n            {\n                formatValue(w, val.front, f);\n            }\n        }\n    }\n    else if (f.spec == '(')\n    {\n        if (val.empty)\n            return;\n        // Nested specifier is to be used\n        for (;;)\n        {\n            auto fmt = FormatSpec!Char(f.nested);\n            fmt.writeUpToNextSpec(w);\n            if (f.flDash)\n                formatValue(w, val.front, fmt);\n            else\n                formatElement(w, val.front, fmt);\n            if (f.sep !is null)\n            {\n                put(w, fmt.trailing);\n                val.popFront();\n                if (val.empty)\n                    break;\n                put(w, f.sep);\n            }\n            else\n            {\n                val.popFront();\n                if (val.empty)\n                    break;\n                put(w, fmt.trailing);\n            }\n        }\n    }\n    else\n        throw new FormatException(text(\"Incorrect format specifier for range: %\", f.spec));\n}\n\n@safe pure unittest\n{\n    assert(collectExceptionMsg(format(\"%d\", \"hi\")).back == 'd');\n}\n\n// character formatting with ecaping\nprivate void formatChar(Writer)(ref Writer w, in dchar c, in char quote)\n{\n    import std.uni : isGraphical;\n\n    string fmt;\n    if (isGraphical(c))\n    {\n        if (c == quote || c == '\\\\')\n            put(w, '\\\\');\n        put(w, c);\n        return;\n    }\n    else if (c <= 0xFF)\n    {\n        if (c < 0x20)\n        {\n            foreach (i, k; \"\\n\\r\\t\\a\\b\\f\\v\\0\")\n            {\n                if (c == k)\n                {\n                    put(w, '\\\\');\n                    put(w, \"nrtabfv0\"[i]);\n                    return;\n                }\n            }\n        }\n        fmt = \"\\\\x%02X\";\n    }\n    else if (c <= 0xFFFF)\n        fmt = \"\\\\u%04X\";\n    else\n        fmt = \"\\\\U%08X\";\n\n    formattedWrite(w, fmt, cast(uint) c);\n}\n\n// undocumented because of deprecation\n// string elements are formatted like UTF-8 string literals.\nvoid formatElement(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f)\nif (is(StringTypeOf!T) && !is(T == enum))\n{\n    import std.array : appender;\n    import std.utf : UTFException;\n\n    StringTypeOf!T str = val;   // bug 8015\n\n    if (f.spec == 's')\n    {\n        try\n        {\n            // ignore other specifications and quote\n            auto app = appender!(typeof(val[0])[])();\n            put(app, '\\\"');\n            for (size_t i = 0; i < str.length; )\n            {\n                import std.utf : decode;\n\n                auto c = decode(str, i);\n                // \\uFFFE and \\uFFFF are considered valid by isValidDchar,\n                // so need checking for interchange.\n                if (c == 0xFFFE || c == 0xFFFF)\n                    goto LinvalidSeq;\n                formatChar(app, c, '\"');\n            }\n            put(app, '\\\"');\n            put(w, app.data);\n            return;\n        }\n        catch (UTFException)\n        {\n        }\n\n        // If val contains invalid UTF sequence, formatted like HexString literal\n    LinvalidSeq:\n        static if (is(typeof(str[0]) : const(char)))\n        {\n            enum postfix = 'c';\n            alias IntArr = const(ubyte)[];\n        }\n        else static if (is(typeof(str[0]) : const(wchar)))\n        {\n            enum postfix = 'w';\n            alias IntArr = const(ushort)[];\n        }\n        else static if (is(typeof(str[0]) : const(dchar)))\n        {\n            enum postfix = 'd';\n            alias IntArr = const(uint)[];\n        }\n        formattedWrite(w, \"x\\\"%(%02X %)\\\"%s\", cast(IntArr) str, postfix);\n    }\n    else\n        formatValue(w, str, f);\n}\n\n@safe pure unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n    formatElement(w, \"Hello World\", spec);\n\n    assert(w.data == \"\\\"Hello World\\\"\");\n}\n\n@safe unittest\n{\n    // Test for bug 8015\n    import std.typecons;\n\n    struct MyStruct {\n        string str;\n        @property string toStr() {\n            return str;\n        }\n        alias toStr this;\n    }\n\n    Tuple!(MyStruct) t;\n}\n\n// undocumented because of deprecation\n// Character elements are formatted like UTF-8 character literals.\nvoid formatElement(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f)\nif (is(CharTypeOf!T) && !is(T == enum))\n{\n    if (f.spec == 's')\n    {\n        put(w, '\\'');\n        formatChar(w, val, '\\'');\n        put(w, '\\'');\n    }\n    else\n        formatValue(w, val, f);\n}\n\n///\n@safe unittest\n{\n    import std.array : appender;\n    auto w = appender!string();\n    auto spec = singleSpec(\"%s\");\n    formatElement(w, \"H\", spec);\n\n    assert(w.data == \"\\\"H\\\"\", w.data);\n}\n\n// undocumented\n// Maybe T is noncopyable struct, so receive it by 'auto ref'.\nvoid formatElement(Writer, T, Char)(auto ref Writer w, auto ref T val, const ref FormatSpec!Char f)\nif (!is(StringTypeOf!T) && !is(CharTypeOf!T) || is(T == enum))\n{\n    formatValue(w, val, f);\n}\n\n/*\n   Associative arrays are formatted by using `':'` and $(D \", \") as\n   separators, and enclosed by `'['` and `']'`.\n */\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f)\nif (is(AssocArrayTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))\n{\n    AssocArrayTypeOf!T val = obj;\n\n    enforceFmt(f.spec == 's' || f.spec == '(',\n        \"incompatible format character for associative array argument: %\" ~ f.spec);\n\n    enum const(Char)[] defSpec = \"%s\" ~ f.keySeparator ~ \"%s\" ~ f.seqSeparator;\n    auto fmtSpec = f.spec == '(' ? f.nested : defSpec;\n\n    size_t i = 0;\n    immutable end = val.length;\n\n    if (f.spec == 's')\n        put(w, f.seqBefore);\n    foreach (k, ref v; val)\n    {\n        auto fmt = FormatSpec!Char(fmtSpec);\n        fmt.writeUpToNextSpec(w);\n        if (f.flDash)\n        {\n            formatValue(w, k, fmt);\n            fmt.writeUpToNextSpec(w);\n            formatValue(w, v, fmt);\n        }\n        else\n        {\n            formatElement(w, k, fmt);\n            fmt.writeUpToNextSpec(w);\n            formatElement(w, v, fmt);\n        }\n        if (f.sep !is null)\n        {\n            fmt.writeUpToNextSpec(w);\n            if (++i != end)\n                put(w, f.sep);\n        }\n        else\n        {\n            if (++i != end)\n                fmt.writeUpToNextSpec(w);\n        }\n    }\n    if (f.spec == 's')\n        put(w, f.seqAfter);\n}\n\n@safe unittest\n{\n    assert(collectExceptionMsg!FormatException(format(\"%d\", [0:1])).back == 'd');\n\n    int[string] aa0;\n    formatTest( aa0, `[]` );\n\n    // elements escaping\n    formatTest(  [\"aaa\":1, \"bbb\":2],\n               [`[\"aaa\":1, \"bbb\":2]`, `[\"bbb\":2, \"aaa\":1]`] );\n    formatTest(  ['c':\"str\"],\n                `['c':\"str\"]` );\n    formatTest(  ['\"':\"\\\"\", '\\'':\"'\"],\n               [`['\"':\"\\\"\", '\\'':\"'\"]`, `['\\'':\"'\", '\"':\"\\\"\"]`] );\n\n    // range formatting for AA\n    auto aa3 = [1:\"hello\", 2:\"world\"];\n    // escape\n    formatTest( \"{%(%s:%s $ %)}\", aa3,\n               [`{1:\"hello\" $ 2:\"world\"}`, `{2:\"world\" $ 1:\"hello\"}`]);\n    // use range formatting for key and value, and use %|\n    formatTest( \"{%([%04d->%(%c.%)]%| $ %)}\", aa3,\n               [`{[0001->h.e.l.l.o] $ [0002->w.o.r.l.d]}`, `{[0002->w.o.r.l.d] $ [0001->h.e.l.l.o]}`] );\n\n    // issue 12135\n    formatTest(\"%(%s:<%s>%|,%)\", [1:2], \"1:<2>\");\n    formatTest(\"%(%s:<%s>%|%)\" , [1:2], \"1:<2>\");\n}\n\n@system unittest\n{\n    class C1 { int[char] val; alias val this; this(int[char] v){ val = v; } }\n    class C2 { int[char] val; alias val this; this(int[char] v){ val = v; }\n               override string toString() const { return \"C\"; } }\n    formatTest( new C1(['c':1, 'd':2]), [`['c':1, 'd':2]`, `['d':2, 'c':1]`] );\n    formatTest( new C2(['c':1, 'd':2]), \"C\" );\n\n    struct S1 { int[char] val; alias val this; }\n    struct S2 { int[char] val; alias val this;\n                string toString() const { return \"S\"; } }\n    formatTest( S1(['c':1, 'd':2]), [`['c':1, 'd':2]`, `['d':2, 'c':1]`] );\n    formatTest( S2(['c':1, 'd':2]), \"S\" );\n}\n\n@safe unittest  // Issue 8921\n{\n    enum E : char { A = 'a', B = 'b', C = 'c' }\n    E[3] e = [E.A, E.B, E.C];\n    formatTest(e, \"[A, B, C]\");\n\n    E[] e2 = [E.A, E.B, E.C];\n    formatTest(e2, \"[A, B, C]\");\n}\n\nprivate template hasToString(T, Char)\n{\n    static if (isPointer!T && !isAggregateType!T)\n    {\n        // X* does not have toString, even if X is aggregate type has toString.\n        enum hasToString = 0;\n    }\n    else static if (is(typeof(\n        {T val = void;\n        const FormatSpec!Char f;\n        static struct S {void put(scope Char s){}}\n        S s;\n        val.toString(s, f);\n        // force toString to take parameters by ref\n        static assert(!__traits(compiles, val.toString(s, FormatSpec!Char())));\n        static assert(!__traits(compiles, val.toString(S(), f)));}\n    )))\n    {\n        enum hasToString = 6;\n    }\n    else static if (is(typeof(\n        {T val = void;\n        static struct S {void put(scope Char s){}}\n        S s;\n        val.toString(s);\n        // force toString to take parameters by ref\n        static assert(!__traits(compiles, val.toString(S())));}\n    )))\n    {\n        enum hasToString = 5;\n    }\n    else static if (is(typeof({ T val = void; FormatSpec!Char f; val.toString((scope const(char)[] s){}, f); })))\n    {\n        enum hasToString = 4;\n    }\n    else static if (is(typeof({ T val = void; val.toString((scope const(char)[] s){}, \"%s\"); })))\n    {\n        enum hasToString = 3;\n    }\n    else static if (is(typeof({ T val = void; val.toString((scope const(char)[] s){}); })))\n    {\n        enum hasToString = 2;\n    }\n    else static if (is(typeof({ T val = void; return val.toString(); }()) S) && isSomeString!S)\n    {\n        enum hasToString = 1;\n    }\n    else\n    {\n        enum hasToString = 0;\n    }\n}\n\n@safe unittest\n{\n    static struct A\n    {\n        void toString(Writer)(ref Writer w)\n        if (isOutputRange!(Writer, string))\n        {}\n    }\n    static struct B\n    {\n        void toString(scope void delegate(scope const(char)[]) sink, FormatSpec!char fmt) {}\n    }\n    static struct C\n    {\n        void toString(scope void delegate(scope const(char)[]) sink, string fmt) {}\n    }\n    static struct D\n    {\n        void toString(scope void delegate(scope const(char)[]) sink) {}\n    }\n    static struct E\n    {\n        string toString() {return \"\";}\n    }\n    static struct F\n    {\n        void toString(Writer)(ref Writer w, const ref FormatSpec!char fmt)\n        if (isOutputRange!(Writer, string))\n        {}\n    }\n    static struct G\n    {\n        string toString() {return \"\";}\n        void toString(Writer)(ref Writer w) if (isOutputRange!(Writer, string)) {}\n    }\n    static struct H\n    {\n        string toString() {return \"\";}\n        void toString(Writer)(ref Writer w, const ref FormatSpec!char fmt)\n        if (isOutputRange!(Writer, string))\n        {}\n    }\n    static struct I\n    {\n        void toString(Writer)(ref Writer w) if (isOutputRange!(Writer, string)) {}\n        void toString(Writer)(ref Writer w, const ref FormatSpec!char fmt)\n        if (isOutputRange!(Writer, string))\n        {}\n    }\n    static struct J\n    {\n        string toString() {return \"\";}\n        void toString(Writer)(ref Writer w, ref FormatSpec!char fmt)\n        if (isOutputRange!(Writer, string))\n        {}\n    }\n    static struct K\n    {\n        void toString(Writer)(Writer w, const ref FormatSpec!char fmt)\n        if (isOutputRange!(Writer, string))\n        {}\n    }\n    static struct L\n    {\n        void toString(Writer)(ref Writer w, const FormatSpec!char fmt)\n        if (isOutputRange!(Writer, string))\n        {}\n    }\n\n    static assert(hasToString!(A, char) == 5);\n    static assert(hasToString!(B, char) == 4);\n    static assert(hasToString!(C, char) == 3);\n    static assert(hasToString!(D, char) == 2);\n    static assert(hasToString!(E, char) == 1);\n    static assert(hasToString!(F, char) == 6);\n    static assert(hasToString!(G, char) == 5);\n    static assert(hasToString!(H, char) == 6);\n    static assert(hasToString!(I, char) == 6);\n    static assert(hasToString!(J, char) == 1);\n    static assert(hasToString!(K, char) == 4);\n    static assert(hasToString!(L, char) == 0);\n}\n\n// Like NullSink, but toString() isn't even called at all. Used to test the format string.\nprivate struct NoOpSink\n{\n    void put(E)(scope const E) pure @safe @nogc nothrow {}\n}\n\n// object formatting with toString\nprivate void formatObject(Writer, T, Char)(ref Writer w, ref T val, const ref FormatSpec!Char f)\nif (hasToString!(T, Char))\n{\n    enum overload = hasToString!(T, Char);\n\n    enum noop = is(Writer == NoOpSink);\n\n    static if (overload == 6)\n    {\n        static if (!noop) val.toString(w, f);\n    }\n    else static if (overload == 5)\n    {\n        static if (!noop) val.toString(w);\n    }\n    // not using the overload enum to not break badly defined toString overloads\n    // e.g. defining the FormatSpec as ref and not const ref led this function\n    // to ignore that toString overload\n    else static if (is(typeof(val.toString((scope const(char)[] s){}, f))))\n    {\n        static if (!noop) val.toString((scope const(char)[] s) { put(w, s); }, f);\n    }\n    else static if (is(typeof(val.toString((scope const(char)[] s){}, \"%s\"))))\n    {\n        static if (!noop) val.toString((const(char)[] s) { put(w, s); }, f.getCurFmtStr());\n    }\n    else static if (is(typeof(val.toString((scope const(char)[] s){}))))\n    {\n        static if (!noop) val.toString((scope const(char)[] s) { put(w, s); });\n    }\n    else static if (is(typeof(val.toString()) S) && isSomeString!S)\n    {\n        static if (!noop) put(w, val.toString());\n    }\n    else\n    {\n        static assert(0);\n    }\n}\n\nvoid enforceValidFormatSpec(T, Char)(const ref FormatSpec!Char f)\n{\n    static if (!isInputRange!T && hasToString!(T, Char) < 4)\n    {\n        enforceFmt(f.spec == 's',\n            \"Expected '%s' format specifier for type '\" ~ T.stringof ~ \"'\");\n    }\n}\n\n@system unittest\n{\n    static interface IF1 { }\n    class CIF1 : IF1 { }\n    static struct SF1 { }\n    static union UF1 { }\n    static class CF1 { }\n\n    static interface IF2 { string toString(); }\n    static class CIF2 : IF2 { override string toString() { return \"\"; } }\n    static struct SF2 { string toString() { return \"\"; } }\n    static union UF2 { string toString() { return \"\"; } }\n    static class CF2 { override string toString() { return \"\"; } }\n\n    static interface IK1 { void toString(scope void delegate(scope const(char)[]) sink,\n                           FormatSpec!char) const; }\n    static class CIK1 : IK1 { override void toString(scope void delegate(scope const(char)[]) sink,\n                              FormatSpec!char) const { sink(\"CIK1\"); } }\n    static struct KS1 { void toString(scope void delegate(scope const(char)[]) sink,\n                        FormatSpec!char) const { sink(\"KS1\"); } }\n\n    static union KU1 { void toString(scope void delegate(scope const(char)[]) sink,\n                       FormatSpec!char) const { sink(\"KU1\"); } }\n\n    static class KC1 { void toString(scope void delegate(scope const(char)[]) sink,\n                       FormatSpec!char) const { sink(\"KC1\"); } }\n\n    IF1 cif1 = new CIF1;\n    assertThrown!FormatException(format(\"%f\", cif1));\n    assertThrown!FormatException(format(\"%f\", SF1()));\n    assertThrown!FormatException(format(\"%f\", UF1()));\n    assertThrown!FormatException(format(\"%f\", new CF1()));\n\n    IF2 cif2 = new CIF2;\n    assertThrown!FormatException(format(\"%f\", cif2));\n    assertThrown!FormatException(format(\"%f\", SF2()));\n    assertThrown!FormatException(format(\"%f\", UF2()));\n    assertThrown!FormatException(format(\"%f\", new CF2()));\n\n    IK1 cik1 = new CIK1;\n    assert(format(\"%f\", cik1) == \"CIK1\");\n    assert(format(\"%f\", KS1()) == \"KS1\");\n    assert(format(\"%f\", KU1()) == \"KU1\");\n    assert(format(\"%f\", new KC1()) == \"KC1\");\n}\n\n/*\n   Aggregates\n */\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f)\nif (is(T == class) && !is(T == enum))\n{\n    enforceValidFormatSpec!(T, Char)(f);\n\n    // TODO: remove this check once `@disable override` deprecation cycle is finished\n    static if (__traits(hasMember, T, \"toString\") && isSomeFunction!(val.toString))\n        static assert(!__traits(isDisabled, T.toString), T.stringof ~\n            \" cannot be formatted because its `toString` is marked with `@disable`\");\n\n    if (val is null)\n        put(w, \"null\");\n    else\n    {\n        static if ((is(T == immutable) || is(T == const) || is(T == shared)) && hasToString!(T, Char) == 0)\n        {\n            // issue 7879, remove this when Object gets const toString\n            static if (is(T == immutable))\n                put(w, \"immutable(\");\n            else static if (is(T == const))\n                put(w, \"const(\");\n            else static if (is(T == shared))\n                put(w, \"shared(\");\n\n            put(w, typeid(Unqual!T).name);\n            put(w, ')');\n        }\n        else static if (hasToString!(T, Char) > 1 || !isInputRange!T && !is(BuiltinTypeOf!T))\n        {\n            formatObject!(Writer, T, Char)(w, val, f);\n        }\n        else\n        {\n          //string delegate() dg = &val.toString;\n            Object o = val;     // workaround\n            string delegate() dg = &o.toString;\n            if (dg.funcptr != &Object.toString) // toString is overridden\n            {\n                formatObject(w, val, f);\n            }\n            else static if (isInputRange!T)\n            {\n                formatRange(w, val, f);\n            }\n            else static if (is(BuiltinTypeOf!T X))\n            {\n                X x = val;\n                formatValueImpl(w, x, f);\n            }\n            else\n            {\n                formatObject(w, val, f);\n            }\n        }\n    }\n}\n\n@system unittest\n{\n    import std.array : appender;\n    import std.range.interfaces;\n    // class range (issue 5154)\n    auto c = inputRangeObject([1,2,3,4]);\n    formatTest( c, \"[1, 2, 3, 4]\" );\n    assert(c.empty);\n    c = null;\n    formatTest( c, \"null\" );\n}\n\n@system unittest\n{\n    // 5354\n    // If the class has both range I/F and custom toString, the use of custom\n    // toString routine is prioritized.\n\n    // Enable the use of custom toString that gets a sink delegate\n    // for class formatting.\n\n    enum inputRangeCode =\n    q{\n        int[] arr;\n        this(int[] a){ arr = a; }\n        @property int front() const { return arr[0]; }\n        @property bool empty() const { return arr.length == 0; }\n        void popFront(){ arr = arr[1..$]; }\n    };\n\n    class C1\n    {\n        mixin(inputRangeCode);\n        void toString(scope void delegate(scope const(char)[]) dg, const ref FormatSpec!char f) const { dg(\"[012]\"); }\n    }\n    class C2\n    {\n        mixin(inputRangeCode);\n        void toString(scope void delegate(const(char)[]) dg, string f) const { dg(\"[012]\"); }\n    }\n    class C3\n    {\n        mixin(inputRangeCode);\n        void toString(scope void delegate(const(char)[]) dg) const { dg(\"[012]\"); }\n    }\n    class C4\n    {\n        mixin(inputRangeCode);\n        override string toString() const { return \"[012]\"; }\n    }\n    class C5\n    {\n        mixin(inputRangeCode);\n    }\n\n    formatTest( new C1([0, 1, 2]), \"[012]\" );\n    formatTest( new C2([0, 1, 2]), \"[012]\" );\n    formatTest( new C3([0, 1, 2]), \"[012]\" );\n    formatTest( new C4([0, 1, 2]), \"[012]\" );\n    formatTest( new C5([0, 1, 2]), \"[0, 1, 2]\" );\n}\n\n// outside the unittest block, otherwise the FQN of the\n// class contains the line number of the unittest\nversion (unittest)\n{\n    private class C {}\n}\n\n// issue 7879\n@safe unittest\n{\n    const(C) c;\n    auto s = format(\"%s\", c);\n    assert(s == \"null\");\n\n    immutable(C) c2 = new C();\n    s = format(\"%s\", c2);\n    assert(s == \"immutable(std.format.C)\");\n\n    const(C) c3 = new C();\n    s = format(\"%s\", c3);\n    assert(s == \"const(std.format.C)\");\n\n    shared(C) c4 = new C();\n    s = format(\"%s\", c4);\n    assert(s == \"shared(std.format.C)\");\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=19003\n@safe unittest\n{\n    struct S\n    {\n        int i;\n\n        @disable this();\n\n        invariant { assert(this.i); }\n\n        this(int i) @safe in { assert(i); } do { this.i = i; }\n\n        string toString() { return \"S\"; }\n    }\n\n    S s = S(1);\n\n    format!\"%s\"(s);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=7879\n@safe unittest\n{\n    class F\n    {\n        override string toString() const @safe\n        {\n            return \"Foo\";\n        }\n    }\n\n    const(F) c;\n    auto s = format(\"%s\", c);\n    assert(s == \"null\");\n\n    const(F) c2 = new F();\n    s = format(\"%s\", c2);\n    assert(s == \"Foo\", s);\n}\n\n// ditto\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f)\nif (is(T == interface) && (hasToString!(T, Char) || !is(BuiltinTypeOf!T)) && !is(T == enum))\n{\n    enforceValidFormatSpec!(T, Char)(f);\n    if (val is null)\n        put(w, \"null\");\n    else\n    {\n        static if (__traits(hasMember, T, \"toString\") && isSomeFunction!(val.toString))\n            static assert(!__traits(isDisabled, T.toString), T.stringof ~\n                \" cannot be formatted because its `toString` is marked with `@disable`\");\n\n        static if (hasToString!(T, Char))\n        {\n            formatObject(w, val, f);\n        }\n        else static if (isInputRange!T)\n        {\n            formatRange(w, val, f);\n        }\n        else\n        {\n            version (Windows)\n            {\n                import core.sys.windows.com : IUnknown;\n                static if (is(T : IUnknown))\n                {\n                    formatValueImpl(w, *cast(void**)&val, f);\n                }\n                else\n                {\n                    formatValueImpl(w, cast(Object) val, f);\n                }\n            }\n            else\n            {\n                formatValueImpl(w, cast(Object) val, f);\n            }\n        }\n    }\n}\n\n@system unittest\n{\n    // interface\n    import std.range.interfaces;\n    InputRange!int i = inputRangeObject([1,2,3,4]);\n    formatTest( i, \"[1, 2, 3, 4]\" );\n    assert(i.empty);\n    i = null;\n    formatTest( i, \"null\" );\n\n    // interface (downcast to Object)\n    interface Whatever {}\n    class C : Whatever\n    {\n        override @property string toString() const { return \"ab\"; }\n    }\n    Whatever val = new C;\n    formatTest( val, \"ab\" );\n\n    // Issue 11175\n    version (Windows)\n    {\n        import core.sys.windows.com : IUnknown, IID;\n        import core.sys.windows.windows : HRESULT;\n\n        interface IUnknown2 : IUnknown { }\n\n        class D : IUnknown2\n        {\n            extern(Windows) HRESULT QueryInterface(const(IID)* riid, void** pvObject) { return typeof(return).init; }\n            extern(Windows) uint AddRef() { return 0; }\n            extern(Windows) uint Release() { return 0; }\n        }\n\n        IUnknown2 d = new D;\n        string expected = format(\"%X\", cast(void*) d);\n        formatTest(d, expected);\n    }\n}\n\n/// ditto\n// Maybe T is noncopyable struct, so receive it by 'auto ref'.\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, auto ref T val, const ref FormatSpec!Char f)\nif ((is(T == struct) || is(T == union)) && (hasToString!(T, Char) || !is(BuiltinTypeOf!T)) && !is(T == enum))\n{\n\n    static if (__traits(hasMember, T, \"toString\") && isSomeFunction!(val.toString))\n        static assert(!__traits(isDisabled, T.toString), T.stringof ~\n            \" cannot be formatted because its `toString` is marked with `@disable`\");\n\n    enforceValidFormatSpec!(T, Char)(f);\n    static if (hasToString!(T, Char))\n    {\n        formatObject(w, val, f);\n    }\n    else static if (isInputRange!T)\n    {\n        formatRange(w, val, f);\n    }\n    else static if (is(T == struct))\n    {\n        enum left = T.stringof~\"(\";\n        enum separator = \", \";\n        enum right = \")\";\n\n        put(w, left);\n        foreach (i, e; val.tupleof)\n        {\n            static if (0 < i && val.tupleof[i-1].offsetof == val.tupleof[i].offsetof)\n            {\n                static if (i == val.tupleof.length - 1 || val.tupleof[i].offsetof != val.tupleof[i+1].offsetof)\n                    put(w, separator~val.tupleof[i].stringof[4..$]~\"}\");\n                else\n                    put(w, separator~val.tupleof[i].stringof[4..$]);\n            }\n            else\n            {\n                static if (i+1 < val.tupleof.length && val.tupleof[i].offsetof == val.tupleof[i+1].offsetof)\n                    put(w, (i > 0 ? separator : \"\")~\"#{overlap \"~val.tupleof[i].stringof[4..$]);\n                else\n                {\n                    static if (i > 0)\n                        put(w, separator);\n                    formatElement(w, e, f);\n                }\n            }\n        }\n        put(w, right);\n    }\n    else\n    {\n        put(w, T.stringof);\n    }\n}\n\n@safe unittest\n{\n    // bug 4638\n    struct U8  {  string toString() const { return \"blah\"; } }\n    struct U16 { wstring toString() const { return \"blah\"; } }\n    struct U32 { dstring toString() const { return \"blah\"; } }\n    formatTest( U8(), \"blah\" );\n    formatTest( U16(), \"blah\" );\n    formatTest( U32(), \"blah\" );\n}\n\n@safe unittest\n{\n    // 3890\n    struct Int{ int n; }\n    struct Pair{ string s; Int i; }\n    formatTest( Pair(\"hello\", Int(5)),\n                `Pair(\"hello\", Int(5))` );\n}\n\n@system unittest\n{\n    // union formatting without toString\n    union U1\n    {\n        int n;\n        string s;\n    }\n    U1 u1;\n    formatTest( u1, \"U1\" );\n\n    // union formatting with toString\n    union U2\n    {\n        int n;\n        string s;\n        string toString() const { return s; }\n    }\n    U2 u2;\n    u2.s = \"hello\";\n    formatTest( u2, \"hello\" );\n}\n\n@system unittest\n{\n    import std.array;\n    // 7230\n    static struct Bug7230\n    {\n        string s = \"hello\";\n        union {\n            string a;\n            int b;\n            double c;\n        }\n        long x = 10;\n    }\n\n    Bug7230 bug;\n    bug.b = 123;\n\n    FormatSpec!char f;\n    auto w = appender!(char[])();\n    formatValue(w, bug, f);\n    assert(w.data == `Bug7230(\"hello\", #{overlap a, b, c}, 10)`);\n}\n\n@safe unittest\n{\n    import std.array : appender;\n    static struct S{ @disable this(this); }\n    S s;\n\n    FormatSpec!char f;\n    auto w = appender!string();\n    formatValue(w, s, f);\n    assert(w.data == \"S()\");\n}\n\n@safe unittest\n{\n    //struct Foo { @disable string toString(); }\n    //Foo foo;\n\n    interface Bar { @disable string toString(); }\n    Bar bar;\n\n    import std.array : appender;\n    auto w = appender!(char[])();\n    FormatSpec!char f;\n\n    // NOTE: structs cant be tested : the assertion is correct so compilation\n    // continues and fails when trying to link the unimplemented toString.\n    //static assert(!__traits(compiles, formatValue(w, foo, f)));\n    static assert(!__traits(compiles, formatValue(w, bar, f)));\n}\n\n/*\n    `enum`s are formatted like their base value\n */\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f)\nif (is(T == enum))\n{\n    if (f.spec == 's')\n    {\n        foreach (i, e; EnumMembers!T)\n        {\n            if (val == e)\n            {\n                formatValueImpl(w, __traits(allMembers, T)[i], f);\n                return;\n            }\n        }\n\n        // val is not a member of T, output cast(T) rawValue instead.\n        put(w, \"cast(\" ~ T.stringof ~ \")\");\n        static assert(!is(OriginalType!T == T));\n    }\n    formatValueImpl(w, cast(OriginalType!T) val, f);\n}\n\n@safe unittest\n{\n    enum A { first, second, third }\n    formatTest( A.second, \"second\" );\n    formatTest( cast(A) 72, \"cast(A)72\" );\n}\n@safe unittest\n{\n    enum A : string { one = \"uno\", two = \"dos\", three = \"tres\" }\n    formatTest( A.three, \"three\" );\n    formatTest( cast(A)\"mill\\&oacute;n\", \"cast(A)mill\\&oacute;n\" );\n}\n@safe unittest\n{\n    enum A : bool { no, yes }\n    formatTest( A.yes, \"yes\" );\n    formatTest( A.no, \"no\" );\n}\n@safe unittest\n{\n    // Test for bug 6892\n    enum Foo { A = 10 }\n    formatTest(\"%s\",    Foo.A, \"A\");\n    formatTest(\">%4s<\", Foo.A, \">   A<\");\n    formatTest(\"%04d\",  Foo.A, \"0010\");\n    formatTest(\"%+2u\",  Foo.A, \"+10\");\n    formatTest(\"%02x\",  Foo.A, \"0a\");\n    formatTest(\"%3o\",   Foo.A, \" 12\");\n    formatTest(\"%b\",    Foo.A, \"1010\");\n}\n\n/*\n   Pointers are formatted as hex integers.\n */\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f)\nif (isPointer!T && !is(T == enum) && !hasToString!(T, Char))\n{\n    static if (isInputRange!T)\n    {\n        if (val !is null)\n        {\n            formatRange(w, *val, f);\n            return;\n        }\n    }\n\n    static if (is(typeof({ shared const void* p = val; })))\n        alias SharedOf(T) = shared(T);\n    else\n        alias SharedOf(T) = T;\n\n    const SharedOf!(void*) p = val;\n    const pnum = ()@trusted{ return cast(ulong) p; }();\n\n    if (f.spec == 's')\n    {\n        if (p is null)\n        {\n            put(w, \"null\");\n            return;\n        }\n        FormatSpec!Char fs = f; // fs is copy for change its values.\n        fs.spec = 'X';\n        formatValueImpl(w, pnum, fs);\n    }\n    else\n    {\n        enforceFmt(f.spec == 'X' || f.spec == 'x',\n           \"Expected one of %s, %x or %X for pointer type.\");\n        formatValueImpl(w, pnum, f);\n    }\n}\n\n/*\n   SIMD vectors are formatted as arrays.\n */\nprivate void formatValueImpl(Writer, V, Char)(auto ref Writer w, V val, const ref FormatSpec!Char f)\nif (isSIMDVector!V)\n{\n    formatValueImpl(w, val.array, f);\n}\n\n@safe unittest\n{\n    import core.simd;\n    static if (is(float4))\n    {\n        version (X86)\n        {\n            version (OSX) {/* issue 17823 */}\n        }\n        else\n        {\n            float4 f;\n            f.array[0] = 1;\n            f.array[1] = 2;\n            f.array[2] = 3;\n            f.array[3] = 4;\n            formatTest(f, \"[1, 2, 3, 4]\");\n        }\n    }\n}\n\n@safe pure unittest\n{\n    // pointer\n    import std.range;\n    auto r = retro([1,2,3,4]);\n    auto p = ()@trusted{ auto p = &r; return p; }();\n    formatTest( p, \"[4, 3, 2, 1]\" );\n    assert(p.empty);\n    p = null;\n    formatTest( p, \"null\" );\n\n    auto q = ()@trusted{ return cast(void*) 0xFFEECCAA; }();\n    formatTest( q, \"FFEECCAA\" );\n}\n\n@system pure unittest\n{\n    // Test for issue 7869\n    struct S\n    {\n        string toString() const { return \"\"; }\n    }\n    S* p = null;\n    formatTest( p, \"null\" );\n\n    S* q = cast(S*) 0xFFEECCAA;\n    formatTest( q, \"FFEECCAA\" );\n}\n\n@system unittest\n{\n    // Test for issue 8186\n    class B\n    {\n        int*a;\n        this(){ a = new int; }\n        alias a this;\n    }\n    formatTest( B.init, \"null\" );\n}\n\n@system pure unittest\n{\n    // Test for issue 9336\n    shared int i;\n    format(\"%s\", &i);\n}\n\n@system pure unittest\n{\n    // Test for issue 11778\n    int* p = null;\n    assertThrown!FormatException(format(\"%d\", p));\n    assertThrown!FormatException(format(\"%04d\", p + 2));\n}\n\n@safe pure unittest\n{\n    // Test for issue 12505\n    void* p = null;\n    formatTest( \"%08X\", p, \"00000000\" );\n}\n\n/*\n   Delegates are formatted by `ReturnType delegate(Parameters) FunctionAttributes`\n */\nprivate void formatValueImpl(Writer, T, Char)(auto ref Writer w, scope T, const ref FormatSpec!Char f)\nif (isDelegate!T)\n{\n    formatValueImpl(w, T.stringof, f);\n}\n\n@safe unittest\n{\n    void func() @system { __gshared int x; ++x; throw new Exception(\"msg\"); }\n    version (linux) formatTest( &func, \"void delegate() @system\" );\n}\n\n@safe pure unittest\n{\n    int[] a = [ 1, 3, 2 ];\n    formatTest( \"testing %(%s & %) embedded\", a,\n                \"testing 1 & 3 & 2 embedded\");\n    formatTest( \"testing %((%s) %)) wyda3\", a,\n                \"testing (1) (3) (2) wyda3\" );\n\n    int[0] empt = [];\n    formatTest( \"(%s)\", empt,\n                \"([])\" );\n}\n\n//------------------------------------------------------------------------------\n// Fix for issue 1591\nprivate int getNthInt(string kind, A...)(uint index, A args)\n{\n    return getNth!(kind, isIntegral,int)(index, args);\n}\n\nprivate T getNth(string kind, alias Condition, T, A...)(uint index, A args)\n{\n    import std.conv : text, to;\n\n    switch (index)\n    {\n        foreach (n, _; A)\n        {\n            case n:\n                static if (Condition!(typeof(args[n])))\n                {\n                    return to!T(args[n]);\n                }\n                else\n                {\n                    throw new FormatException(\n                        text(kind, \" expected, not \", typeof(args[n]).stringof,\n                            \" for argument #\", index + 1));\n                }\n        }\n        default:\n            throw new FormatException(\n                text(\"Missing \", kind, \" argument\"));\n    }\n}\n\n@safe unittest\n{\n    // width/precision\n    assert(collectExceptionMsg!FormatException(format(\"%*.d\", 5.1, 2))\n        == \"integer width expected, not double for argument #1\");\n    assert(collectExceptionMsg!FormatException(format(\"%-1*.d\", 5.1, 2))\n        == \"integer width expected, not double for argument #1\");\n\n    assert(collectExceptionMsg!FormatException(format(\"%.*d\", '5', 2))\n        == \"integer precision expected, not char for argument #1\");\n    assert(collectExceptionMsg!FormatException(format(\"%-1.*d\", 4.7, 3))\n        == \"integer precision expected, not double for argument #1\");\n    assert(collectExceptionMsg!FormatException(format(\"%.*d\", 5))\n        == \"Orphan format specifier: %d\");\n    assert(collectExceptionMsg!FormatException(format(\"%*.*d\", 5))\n        == \"Missing integer precision argument\");\n\n    // separatorCharPos\n    assert(collectExceptionMsg!FormatException(format(\"%,?d\", 5))\n        == \"separator character expected, not int for argument #1\");\n    assert(collectExceptionMsg!FormatException(format(\"%,?d\", '?'))\n        == \"Orphan format specifier: %d\");\n    assert(collectExceptionMsg!FormatException(format(\"%.*,*?d\", 5))\n        == \"Missing separator digit width argument\");\n}\n\n/* ======================== Unit Tests ====================================== */\n\nversion (unittest)\nprivate void formatTest(T)(T val, string expected, size_t ln = __LINE__, string fn = __FILE__)\n{\n    import core.exception : AssertError;\n    import std.array : appender;\n    import std.conv : text;\n    FormatSpec!char f;\n    auto w = appender!string();\n    formatValue(w, val, f);\n    enforce!AssertError(\n            w.data == expected,\n            text(\"expected = `\", expected, \"`, result = `\", w.data, \"`\"), fn, ln);\n}\n\nversion (unittest)\nprivate void formatTest(T)(string fmt, T val, string expected, size_t ln = __LINE__, string fn = __FILE__) @safe\n{\n    import core.exception : AssertError;\n    import std.array : appender;\n    import std.conv : text;\n    auto w = appender!string();\n    formattedWrite(w, fmt, val);\n    enforce!AssertError(\n            w.data == expected,\n            text(\"expected = `\", expected, \"`, result = `\", w.data, \"`\"), fn, ln);\n}\n\nversion (unittest)\nprivate void formatTest(T)(T val, string[] expected, size_t ln = __LINE__, string fn = __FILE__)\n{\n    import core.exception : AssertError;\n    import std.array : appender;\n    import std.conv : text;\n    FormatSpec!char f;\n    auto w = appender!string();\n    formatValue(w, val, f);\n    foreach (cur; expected)\n    {\n        if (w.data == cur) return;\n    }\n    enforce!AssertError(\n            false,\n            text(\"expected one of `\", expected, \"`, result = `\", w.data, \"`\"), fn, ln);\n}\n\nversion (unittest)\nprivate void formatTest(T)(string fmt, T val, string[] expected, size_t ln = __LINE__, string fn = __FILE__) @safe\n{\n    import core.exception : AssertError;\n    import std.array : appender;\n    import std.conv : text;\n    auto w = appender!string();\n    formattedWrite(w, fmt, val);\n    foreach (cur; expected)\n    {\n        if (w.data == cur) return;\n    }\n    enforce!AssertError(\n            false,\n            text(\"expected one of `\", expected, \"`, result = `\", w.data, \"`\"), fn, ln);\n}\n\n@safe /*pure*/ unittest     // formatting floating point values is now impure\n{\n    import std.array;\n\n    auto stream = appender!string();\n    formattedWrite(stream, \"%s\", 1.1);\n    assert(stream.data == \"1.1\", stream.data);\n}\n\n@safe pure unittest\n{\n    import std.algorithm;\n    import std.array;\n\n    auto stream = appender!string();\n    formattedWrite(stream, \"%s\", map!\"a*a\"([2, 3, 5]));\n    assert(stream.data == \"[4, 9, 25]\", stream.data);\n\n    // Test shared data.\n    stream = appender!string();\n    shared int s = 6;\n    formattedWrite(stream, \"%s\", s);\n    assert(stream.data == \"6\");\n}\n\n@safe pure unittest\n{\n    import std.array;\n    auto stream = appender!string();\n    formattedWrite(stream, \"%u\", 42);\n    assert(stream.data == \"42\", stream.data);\n}\n\n@safe pure unittest\n{\n    // testing raw writes\n    import std.array;\n    auto w = appender!(char[])();\n    uint a = 0x02030405;\n    formattedWrite(w, \"%+r\", a);\n    assert(w.data.length == 4 && w.data[0] == 2 && w.data[1] == 3\n        && w.data[2] == 4 && w.data[3] == 5);\n    w.clear();\n    formattedWrite(w, \"%-r\", a);\n    assert(w.data.length == 4 && w.data[0] == 5 && w.data[1] == 4\n        && w.data[2] == 3 && w.data[3] == 2);\n}\n\n@safe pure unittest\n{\n    // testing positional parameters\n    import std.array;\n    auto w = appender!(char[])();\n    formattedWrite(w,\n            \"Numbers %2$s and %1$s are reversed and %1$s%2$s repeated\",\n            42, 0);\n    assert(w.data == \"Numbers 0 and 42 are reversed and 420 repeated\",\n            w.data);\n    assert(collectExceptionMsg!FormatException(formattedWrite(w, \"%1$s, %3$s\", 1, 2))\n        == \"Positional specifier %3$s index exceeds 2\");\n\n    w.clear();\n    formattedWrite(w, \"asd%s\", 23);\n    assert(w.data == \"asd23\", w.data);\n    w.clear();\n    formattedWrite(w, \"%s%s\", 23, 45);\n    assert(w.data == \"2345\", w.data);\n}\n\n@safe unittest\n{\n    import core.stdc.string : strlen;\n    import std.array : appender;\n    import std.conv : text, octal;\n    import core.stdc.stdio : snprintf;\n\n    debug(format) printf(\"std.format.format.unittest\\n\");\n\n    auto stream = appender!(char[])();\n    //goto here;\n\n    formattedWrite(stream,\n            \"hello world! %s %s \", true, 57, 1_000_000_000, 'x', \" foo\");\n    assert(stream.data == \"hello world! true 57 \",\n        stream.data);\n\n    stream.clear();\n    formattedWrite(stream, \"%g %A %s\", 1.67, -1.28, float.nan);\n    // core.stdc.stdio.fwrite(stream.data.ptr, stream.data.length, 1, stderr);\n\n    /* The host C library is used to format floats.  C99 doesn't\n    * specify what the hex digit before the decimal point is for\n    * %A.  */\n\n    version (CRuntime_Glibc)\n    {\n        assert(stream.data == \"1.67 -0X1.47AE147AE147BP+0 nan\",\n                stream.data);\n    }\n    else version (OSX)\n    {\n        assert(stream.data == \"1.67 -0X1.47AE147AE147BP+0 nan\",\n                stream.data);\n    }\n    else version (MinGW)\n    {\n        assert(stream.data == \"1.67 -0XA.3D70A3D70A3D8P-3 nan\",\n                stream.data);\n    }\n    else version (CRuntime_Microsoft)\n    {\n        assert(stream.data == \"1.67 -0X1.47AE14P+0 nan\"\n            || stream.data == \"1.67 -0X1.47AE147AE147BP+0 nan\", // MSVCRT 14+ (VS 2015)\n                stream.data);\n    }\n    else\n    {\n        assert(stream.data == \"1.67 -0X1.47AE147AE147BP+0 nan\",\n                stream.data);\n    }\n    stream.clear();\n\n    formattedWrite(stream, \"%x %X\", 0x1234AF, 0xAFAFAFAF);\n    assert(stream.data == \"1234af AFAFAFAF\");\n    stream.clear();\n\n    formattedWrite(stream, \"%b %o\", 0x1234AF, 0xAFAFAFAF);\n    assert(stream.data == \"100100011010010101111 25753727657\");\n    stream.clear();\n\n    formattedWrite(stream, \"%d %s\", 0x1234AF, 0xAFAFAFAF);\n    assert(stream.data == \"1193135 2947526575\");\n    stream.clear();\n\n    // formattedWrite(stream, \"%s\", 1.2 + 3.4i);\n    // assert(stream.data == \"1.2+3.4i\");\n    // stream.clear();\n\n    formattedWrite(stream, \"%a %A\", 1.32, 6.78f);\n    //formattedWrite(stream, \"%x %X\", 1.32);\n    version (CRuntime_Microsoft)\n        assert(stream.data == \"0x1.51eb85p+0 0X1.B1EB86P+2\"\n            || stream.data == \"0x1.51eb851eb851fp+0 0X1.B1EB860000000P+2\"); // MSVCRT 14+ (VS 2015)\n    else\n        assert(stream.data == \"0x1.51eb851eb851fp+0 0X1.B1EB86P+2\");\n    stream.clear();\n\n    formattedWrite(stream, \"%#06.*f\",2,12.345);\n    assert(stream.data == \"012.35\");\n    stream.clear();\n\n    formattedWrite(stream, \"%#0*.*f\",6,2,12.345);\n    assert(stream.data == \"012.35\");\n    stream.clear();\n\n    const real constreal = 1;\n    formattedWrite(stream, \"%g\",constreal);\n    assert(stream.data == \"1\");\n    stream.clear();\n\n    formattedWrite(stream, \"%7.4g:\", 12.678);\n    assert(stream.data == \"  12.68:\");\n    stream.clear();\n\n    formattedWrite(stream, \"%7.4g:\", 12.678L);\n    assert(stream.data == \"  12.68:\");\n    stream.clear();\n\n    formattedWrite(stream, \"%04f|%05d|%#05x|%#5x\",-4.0,-10,1,1);\n    assert(stream.data == \"-4.000000|-0010|0x001|  0x1\",\n            stream.data);\n    stream.clear();\n\n    int i;\n    string s;\n\n    i = -10;\n    formattedWrite(stream, \"%d|%3d|%03d|%1d|%01.4f\",i,i,i,i,cast(double) i);\n    assert(stream.data == \"-10|-10|-10|-10|-10.0000\");\n    stream.clear();\n\n    i = -5;\n    formattedWrite(stream, \"%d|%3d|%03d|%1d|%01.4f\",i,i,i,i,cast(double) i);\n    assert(stream.data == \"-5| -5|-05|-5|-5.0000\");\n    stream.clear();\n\n    i = 0;\n    formattedWrite(stream, \"%d|%3d|%03d|%1d|%01.4f\",i,i,i,i,cast(double) i);\n    assert(stream.data == \"0|  0|000|0|0.0000\");\n    stream.clear();\n\n    i = 5;\n    formattedWrite(stream, \"%d|%3d|%03d|%1d|%01.4f\",i,i,i,i,cast(double) i);\n    assert(stream.data == \"5|  5|005|5|5.0000\");\n    stream.clear();\n\n    i = 10;\n    formattedWrite(stream, \"%d|%3d|%03d|%1d|%01.4f\",i,i,i,i,cast(double) i);\n    assert(stream.data == \"10| 10|010|10|10.0000\");\n    stream.clear();\n\n    formattedWrite(stream, \"%.0d\", 0);\n    assert(stream.data == \"\");\n    stream.clear();\n\n    formattedWrite(stream, \"%.g\", .34);\n    assert(stream.data == \"0.3\");\n    stream.clear();\n\n    stream.clear(); formattedWrite(stream, \"%.0g\", .34);\n    assert(stream.data == \"0.3\");\n\n    stream.clear(); formattedWrite(stream, \"%.2g\", .34);\n    assert(stream.data == \"0.34\");\n\n    stream.clear(); formattedWrite(stream, \"%0.0008f\", 1e-08);\n    assert(stream.data == \"0.00000001\");\n\n    stream.clear(); formattedWrite(stream, \"%0.0008f\", 1e-05);\n    assert(stream.data == \"0.00001000\");\n\n    //return;\n    //core.stdc.stdio.fwrite(stream.data.ptr, stream.data.length, 1, stderr);\n\n    s = \"helloworld\";\n    string r;\n    stream.clear(); formattedWrite(stream, \"%.2s\", s[0 .. 5]);\n    assert(stream.data == \"he\");\n    stream.clear(); formattedWrite(stream, \"%.20s\", s[0 .. 5]);\n    assert(stream.data == \"hello\");\n    stream.clear(); formattedWrite(stream, \"%8s\", s[0 .. 5]);\n    assert(stream.data == \"   hello\");\n\n    byte[] arrbyte = new byte[4];\n    arrbyte[0] = 100;\n    arrbyte[1] = -99;\n    arrbyte[3] = 0;\n    stream.clear(); formattedWrite(stream, \"%s\", arrbyte);\n    assert(stream.data == \"[100, -99, 0, 0]\", stream.data);\n\n    ubyte[] arrubyte = new ubyte[4];\n    arrubyte[0] = 100;\n    arrubyte[1] = 200;\n    arrubyte[3] = 0;\n    stream.clear(); formattedWrite(stream, \"%s\", arrubyte);\n    assert(stream.data == \"[100, 200, 0, 0]\", stream.data);\n\n    short[] arrshort = new short[4];\n    arrshort[0] = 100;\n    arrshort[1] = -999;\n    arrshort[3] = 0;\n    stream.clear(); formattedWrite(stream, \"%s\", arrshort);\n    assert(stream.data == \"[100, -999, 0, 0]\");\n    stream.clear(); formattedWrite(stream, \"%s\",arrshort);\n    assert(stream.data == \"[100, -999, 0, 0]\");\n\n    ushort[] arrushort = new ushort[4];\n    arrushort[0] = 100;\n    arrushort[1] = 20_000;\n    arrushort[3] = 0;\n    stream.clear(); formattedWrite(stream, \"%s\", arrushort);\n    assert(stream.data == \"[100, 20000, 0, 0]\");\n\n    int[] arrint = new int[4];\n    arrint[0] = 100;\n    arrint[1] = -999;\n    arrint[3] = 0;\n    stream.clear(); formattedWrite(stream, \"%s\", arrint);\n    assert(stream.data == \"[100, -999, 0, 0]\");\n    stream.clear(); formattedWrite(stream, \"%s\",arrint);\n    assert(stream.data == \"[100, -999, 0, 0]\");\n\n    long[] arrlong = new long[4];\n    arrlong[0] = 100;\n    arrlong[1] = -999;\n    arrlong[3] = 0;\n    stream.clear(); formattedWrite(stream, \"%s\", arrlong);\n    assert(stream.data == \"[100, -999, 0, 0]\");\n    stream.clear(); formattedWrite(stream, \"%s\",arrlong);\n    assert(stream.data == \"[100, -999, 0, 0]\");\n\n    ulong[] arrulong = new ulong[4];\n    arrulong[0] = 100;\n    arrulong[1] = 999;\n    arrulong[3] = 0;\n    stream.clear(); formattedWrite(stream, \"%s\", arrulong);\n    assert(stream.data == \"[100, 999, 0, 0]\");\n\n    string[] arr2 = new string[4];\n    arr2[0] = \"hello\";\n    arr2[1] = \"world\";\n    arr2[3] = \"foo\";\n    stream.clear(); formattedWrite(stream, \"%s\", arr2);\n    assert(stream.data == `[\"hello\", \"world\", \"\", \"foo\"]`, stream.data);\n\n    stream.clear(); formattedWrite(stream, \"%.8d\", 7);\n    assert(stream.data == \"00000007\");\n\n    stream.clear(); formattedWrite(stream, \"%.8x\", 10);\n    assert(stream.data == \"0000000a\");\n\n    stream.clear(); formattedWrite(stream, \"%-3d\", 7);\n    assert(stream.data == \"7  \");\n\n    stream.clear(); formattedWrite(stream, \"%*d\", -3, 7);\n    assert(stream.data == \"7  \");\n\n    stream.clear(); formattedWrite(stream, \"%.*d\", -3, 7);\n    //writeln(stream.data);\n    assert(stream.data == \"7\");\n\n    stream.clear(); formattedWrite(stream, \"%s\", \"abc\"c);\n    assert(stream.data == \"abc\");\n    stream.clear(); formattedWrite(stream, \"%s\", \"def\"w);\n    assert(stream.data == \"def\", text(stream.data.length));\n    stream.clear(); formattedWrite(stream, \"%s\", \"ghi\"d);\n    assert(stream.data == \"ghi\");\n\nhere:\n    @trusted void* deadBeef() { return cast(void*) 0xDEADBEEF; }\n    stream.clear(); formattedWrite(stream, \"%s\", deadBeef());\n    assert(stream.data == \"DEADBEEF\", stream.data);\n\n    stream.clear(); formattedWrite(stream, \"%#x\", 0xabcd);\n    assert(stream.data == \"0xabcd\");\n    stream.clear(); formattedWrite(stream, \"%#X\", 0xABCD);\n    assert(stream.data == \"0XABCD\");\n\n    stream.clear(); formattedWrite(stream, \"%#o\", octal!12345);\n    assert(stream.data == \"012345\");\n    stream.clear(); formattedWrite(stream, \"%o\", 9);\n    assert(stream.data == \"11\");\n\n    stream.clear(); formattedWrite(stream, \"%+d\", 123);\n    assert(stream.data == \"+123\");\n    stream.clear(); formattedWrite(stream, \"%+d\", -123);\n    assert(stream.data == \"-123\");\n    stream.clear(); formattedWrite(stream, \"% d\", 123);\n    assert(stream.data == \" 123\");\n    stream.clear(); formattedWrite(stream, \"% d\", -123);\n    assert(stream.data == \"-123\");\n\n    stream.clear(); formattedWrite(stream, \"%%\");\n    assert(stream.data == \"%\");\n\n    stream.clear(); formattedWrite(stream, \"%d\", true);\n    assert(stream.data == \"1\");\n    stream.clear(); formattedWrite(stream, \"%d\", false);\n    assert(stream.data == \"0\");\n\n    stream.clear(); formattedWrite(stream, \"%d\", 'a');\n    assert(stream.data == \"97\", stream.data);\n    wchar wc = 'a';\n    stream.clear(); formattedWrite(stream, \"%d\", wc);\n    assert(stream.data == \"97\");\n    dchar dc = 'a';\n    stream.clear(); formattedWrite(stream, \"%d\", dc);\n    assert(stream.data == \"97\");\n\n    byte b = byte.max;\n    stream.clear(); formattedWrite(stream, \"%x\", b);\n    assert(stream.data == \"7f\");\n    stream.clear(); formattedWrite(stream, \"%x\", ++b);\n    assert(stream.data == \"80\");\n    stream.clear(); formattedWrite(stream, \"%x\", ++b);\n    assert(stream.data == \"81\");\n\n    short sh = short.max;\n    stream.clear(); formattedWrite(stream, \"%x\", sh);\n    assert(stream.data == \"7fff\");\n    stream.clear(); formattedWrite(stream, \"%x\", ++sh);\n    assert(stream.data == \"8000\");\n    stream.clear(); formattedWrite(stream, \"%x\", ++sh);\n    assert(stream.data == \"8001\");\n\n    i = int.max;\n    stream.clear(); formattedWrite(stream, \"%x\", i);\n    assert(stream.data == \"7fffffff\");\n    stream.clear(); formattedWrite(stream, \"%x\", ++i);\n    assert(stream.data == \"80000000\");\n    stream.clear(); formattedWrite(stream, \"%x\", ++i);\n    assert(stream.data == \"80000001\");\n\n    stream.clear(); formattedWrite(stream, \"%x\", 10);\n    assert(stream.data == \"a\");\n    stream.clear(); formattedWrite(stream, \"%X\", 10);\n    assert(stream.data == \"A\");\n    stream.clear(); formattedWrite(stream, \"%x\", 15);\n    assert(stream.data == \"f\");\n    stream.clear(); formattedWrite(stream, \"%X\", 15);\n    assert(stream.data == \"F\");\n\n    @trusted void ObjectTest()\n    {\n        Object c = null;\n        stream.clear(); formattedWrite(stream, \"%s\", c);\n        assert(stream.data == \"null\");\n    }\n    ObjectTest();\n\n    enum TestEnum\n    {\n        Value1, Value2\n    }\n    stream.clear(); formattedWrite(stream, \"%s\", TestEnum.Value2);\n    assert(stream.data == \"Value2\", stream.data);\n    stream.clear(); formattedWrite(stream, \"%s\", cast(TestEnum) 5);\n    assert(stream.data == \"cast(TestEnum)5\", stream.data);\n\n    //immutable(char[5])[int] aa = ([3:\"hello\", 4:\"betty\"]);\n    //stream.clear(); formattedWrite(stream, \"%s\", aa.values);\n    //core.stdc.stdio.fwrite(stream.data.ptr, stream.data.length, 1, stderr);\n    //assert(stream.data == \"[[h,e,l,l,o],[b,e,t,t,y]]\");\n    //stream.clear(); formattedWrite(stream, \"%s\", aa);\n    //assert(stream.data == \"[3:[h,e,l,l,o],4:[b,e,t,t,y]]\");\n\n    static const dchar[] ds = ['a','b'];\n    for (int j = 0; j < ds.length; ++j)\n    {\n        stream.clear(); formattedWrite(stream, \" %d\", ds[j]);\n        if (j == 0)\n            assert(stream.data == \" 97\");\n        else\n            assert(stream.data == \" 98\");\n    }\n\n    stream.clear(); formattedWrite(stream, \"%.-3d\", 7);\n    assert(stream.data == \"7\", \">\" ~ stream.data ~ \"<\");\n}\n\n@safe unittest\n{\n    import std.array;\n    import std.stdio;\n\n    immutable(char[5])[int] aa = ([3:\"hello\", 4:\"betty\"]);\n    assert(aa[3] == \"hello\");\n    assert(aa[4] == \"betty\");\n\n    auto stream = appender!(char[])();\n    alias AllNumerics =\n        AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong,\n                  float, double, real);\n    foreach (T; AllNumerics)\n    {\n        T value = 1;\n        stream.clear();\n        formattedWrite(stream, \"%s\", value);\n        assert(stream.data == \"1\");\n    }\n\n    stream.clear();\n    formattedWrite(stream, \"%s\", aa);\n}\n\n@system unittest\n{\n    string s = \"hello!124:34.5\";\n    string a;\n    int b;\n    double c;\n    formattedRead(s, \"%s!%s:%s\", &a, &b, &c);\n    assert(a == \"hello\" && b == 124 && c == 34.5);\n}\n\nversion (unittest)\nprivate void formatReflectTest(T)(ref T val, string fmt, string formatted, string fn = __FILE__, size_t ln = __LINE__)\n{\n    import core.exception : AssertError;\n    import std.array : appender;\n    auto w = appender!string();\n    formattedWrite(w, fmt, val);\n\n    auto input = w.data;\n    enforce!AssertError(\n            input == formatted,\n            input, fn, ln);\n\n    T val2;\n    formattedRead(input, fmt, &val2);\n    static if (isAssociativeArray!T)\n    if (__ctfe)\n    {\n        alias aa1 = val;\n        alias aa2 = val2;\n        assert(aa1 == aa2);\n\n        assert(aa1.length == aa2.length);\n\n        assert(aa1.keys == aa2.keys);\n\n        assert(aa1.values == aa2.values);\n        assert(aa1.values.length == aa2.values.length);\n        foreach (i; 0 .. aa1.values.length)\n            assert(aa1.values[i] == aa2.values[i]);\n\n        foreach (i, key; aa1.keys)\n            assert(aa1.values[i] == aa1[key]);\n        foreach (i, key; aa2.keys)\n            assert(aa2.values[i] == aa2[key]);\n        return;\n    }\n    enforce!AssertError(\n            val == val2,\n            input, fn, ln);\n}\n\nversion (unittest)\nprivate void formatReflectTest(T)(ref T val, string fmt, string[] formatted, string fn = __FILE__, size_t ln = __LINE__)\n{\n    import core.exception : AssertError;\n    import std.array : appender;\n    auto w = appender!string();\n    formattedWrite(w, fmt, val);\n\n    auto input = w.data;\n\n    foreach (cur; formatted)\n    {\n        if (input == cur) return;\n    }\n    enforce!AssertError(\n            false,\n            input,\n            fn,\n            ln);\n\n    T val2;\n    formattedRead(input, fmt, &val2);\n    static if (isAssociativeArray!T)\n    if (__ctfe)\n    {\n        alias aa1 = val;\n        alias aa2 = val2;\n        assert(aa1 == aa2);\n\n        assert(aa1.length == aa2.length);\n\n        assert(aa1.keys == aa2.keys);\n\n        assert(aa1.values == aa2.values);\n        assert(aa1.values.length == aa2.values.length);\n        foreach (i; 0 .. aa1.values.length)\n            assert(aa1.values[i] == aa2.values[i]);\n\n        foreach (i, key; aa1.keys)\n            assert(aa1.values[i] == aa1[key]);\n        foreach (i, key; aa2.keys)\n            assert(aa2.values[i] == aa2[key]);\n        return;\n    }\n    enforce!AssertError(\n            val == val2,\n            input, fn, ln);\n}\n\n@system unittest\n{\n    void booleanTest()\n    {\n        auto b = true;\n        formatReflectTest(b, \"%s\",  `true`);\n        formatReflectTest(b, \"%b\",  `1`);\n        formatReflectTest(b, \"%o\",  `1`);\n        formatReflectTest(b, \"%d\",  `1`);\n        formatReflectTest(b, \"%u\",  `1`);\n        formatReflectTest(b, \"%x\",  `1`);\n    }\n\n    void integerTest()\n    {\n        auto n = 127;\n        formatReflectTest(n, \"%s\",  `127`);\n        formatReflectTest(n, \"%b\",  `1111111`);\n        formatReflectTest(n, \"%o\",  `177`);\n        formatReflectTest(n, \"%d\",  `127`);\n        formatReflectTest(n, \"%u\",  `127`);\n        formatReflectTest(n, \"%x\",  `7f`);\n    }\n\n    void floatingTest()\n    {\n        auto f = 3.14;\n        formatReflectTest(f, \"%s\",  `3.14`);\n        version (MinGW)\n            formatReflectTest(f, \"%e\",  `3.140000e+000`);\n        else\n            formatReflectTest(f, \"%e\",  `3.140000e+00`);\n        formatReflectTest(f, \"%f\",  `3.140000`);\n        formatReflectTest(f, \"%g\",  `3.14`);\n    }\n\n    void charTest()\n    {\n        auto c = 'a';\n        formatReflectTest(c, \"%s\",  `a`);\n        formatReflectTest(c, \"%c\",  `a`);\n        formatReflectTest(c, \"%b\",  `1100001`);\n        formatReflectTest(c, \"%o\",  `141`);\n        formatReflectTest(c, \"%d\",  `97`);\n        formatReflectTest(c, \"%u\",  `97`);\n        formatReflectTest(c, \"%x\",  `61`);\n    }\n\n    void strTest()\n    {\n        auto s = \"hello\";\n        formatReflectTest(s, \"%s\",                      `hello`);\n        formatReflectTest(s, \"%(%c,%)\",                 `h,e,l,l,o`);\n        formatReflectTest(s, \"%(%s,%)\",                 `'h','e','l','l','o'`);\n        formatReflectTest(s, \"[%(<%c>%| $ %)]\",         `[<h> $ <e> $ <l> $ <l> $ <o>]`);\n    }\n\n    void daTest()\n    {\n        auto a = [1,2,3,4];\n        formatReflectTest(a, \"%s\",                      `[1, 2, 3, 4]`);\n        formatReflectTest(a, \"[%(%s; %)]\",              `[1; 2; 3; 4]`);\n        formatReflectTest(a, \"[%(<%s>%| $ %)]\",         `[<1> $ <2> $ <3> $ <4>]`);\n    }\n\n    void saTest()\n    {\n        int[4] sa = [1,2,3,4];\n        formatReflectTest(sa, \"%s\",                     `[1, 2, 3, 4]`);\n        formatReflectTest(sa, \"[%(%s; %)]\",             `[1; 2; 3; 4]`);\n        formatReflectTest(sa, \"[%(<%s>%| $ %)]\",        `[<1> $ <2> $ <3> $ <4>]`);\n    }\n\n    void aaTest()\n    {\n        auto aa = [1:\"hello\", 2:\"world\"];\n        formatReflectTest(aa, \"%s\",                     [`[1:\"hello\", 2:\"world\"]`, `[2:\"world\", 1:\"hello\"]`]);\n        formatReflectTest(aa, \"[%(%s->%s, %)]\",         [`[1->\"hello\", 2->\"world\"]`, `[2->\"world\", 1->\"hello\"]`]);\n        formatReflectTest(aa, \"{%([%s=%(%c%)]%|; %)}\",  [`{[1=hello]; [2=world]}`, `{[2=world]; [1=hello]}`]);\n    }\n\n    import std.exception;\n    assertCTFEable!(\n    {\n        booleanTest();\n        integerTest();\n        if (!__ctfe) floatingTest();    // snprintf\n        charTest();\n        strTest();\n        daTest();\n        saTest();\n        aaTest();\n        return true;\n    });\n}\n\n//------------------------------------------------------------------------------\nprivate void skipData(Range, Char)(ref Range input, const ref FormatSpec!Char spec)\n{\n    import std.ascii : isDigit;\n    import std.conv : text;\n\n    switch (spec.spec)\n    {\n        case 'c': input.popFront(); break;\n        case 'd':\n            if (input.front == '+' || input.front == '-') input.popFront();\n            goto case 'u';\n        case 'u':\n            while (!input.empty && isDigit(input.front)) input.popFront();\n            break;\n        default:\n            assert(false,\n                    text(\"Format specifier not understood: %\", spec.spec));\n    }\n}\n\nprivate template acceptedSpecs(T)\n{\n         static if (isIntegral!T)       enum acceptedSpecs = \"bdosuxX\";\n    else static if (isFloatingPoint!T)  enum acceptedSpecs = \"seEfgG\";\n    else static if (isSomeChar!T)       enum acceptedSpecs = \"bcdosuxX\";    // integral + 'c'\n    else                                enum acceptedSpecs = \"\";\n}\n\n/**\n * Reads a value from the given _input range according to spec\n * and returns it as type `T`.\n *\n * Params:\n *     T = the type to return\n *     input = the _input range to read from\n *     spec = the `FormatSpec` to use when reading from `input`\n * Returns:\n *     A value from `input` of type `T`\n * Throws:\n *     A `FormatException` if `spec` cannot read a type `T`\n * See_Also:\n *     $(REF parse, std, conv) and $(REF to, std, conv)\n */\nT unformatValue(T, Range, Char)(ref Range input, const ref FormatSpec!Char spec)\n{\n    return unformatValueImpl!T(input, spec);\n}\n\n/// Booleans\n@safe pure unittest\n{\n    auto str = \"false\";\n    auto spec = singleSpec(\"%s\");\n    assert(unformatValue!bool(str, spec) == false);\n\n    str = \"1\";\n    spec = singleSpec(\"%d\");\n    assert(unformatValue!bool(str, spec));\n}\n\n/// Null values\n@safe pure unittest\n{\n    auto str = \"null\";\n    auto spec = singleSpec(\"%s\");\n    assert(str.unformatValue!(typeof(null))(spec) == null);\n}\n\n/// Integrals\n@safe pure unittest\n{\n    auto str = \"123\";\n    auto spec = singleSpec(\"%s\");\n    assert(str.unformatValue!int(spec) == 123);\n\n    str = \"ABC\";\n    spec = singleSpec(\"%X\");\n    assert(str.unformatValue!int(spec) == 2748);\n\n    str = \"11610\";\n    spec = singleSpec(\"%o\");\n    assert(str.unformatValue!int(spec) == 5000);\n}\n\n/// Floating point numbers\n@safe pure unittest\n{\n    import std.math : approxEqual;\n\n    auto str = \"123.456\";\n    auto spec = singleSpec(\"%s\");\n    assert(str.unformatValue!double(spec).approxEqual(123.456));\n}\n\n/// Character input ranges\n@safe pure unittest\n{\n    auto str = \"aaa\";\n    auto spec = singleSpec(\"%s\");\n    assert(str.unformatValue!char(spec) == 'a');\n\n    // Using a numerical format spec reads a Unicode value from a string\n    str = \"65\";\n    spec = singleSpec(\"%d\");\n    assert(str.unformatValue!char(spec) == 'A');\n\n    str = \"41\";\n    spec = singleSpec(\"%x\");\n    assert(str.unformatValue!char(spec) == 'A');\n\n    str = \"10003\";\n    spec = singleSpec(\"%d\");\n    assert(str.unformatValue!dchar(spec) == '✓');\n}\n\n/// Arrays and static arrays\n@safe pure unittest\n{\n    string str = \"aaa\";\n    auto spec = singleSpec(\"%s\");\n    assert(str.unformatValue!(dchar[])(spec) == \"aaa\"d);\n\n    str = \"aaa\";\n    spec = singleSpec(\"%s\");\n    dchar[3] ret = ['a', 'a', 'a'];\n    assert(str.unformatValue!(dchar[3])(spec) == ret);\n\n    str = \"[1, 2, 3, 4]\";\n    spec = singleSpec(\"%s\");\n    assert(str.unformatValue!(int[])(spec) == [1, 2, 3, 4]);\n\n    str = \"[1, 2, 3, 4]\";\n    spec = singleSpec(\"%s\");\n    int[4] ret2 = [1, 2, 3, 4];\n    assert(str.unformatValue!(int[4])(spec) == ret2);\n}\n\n/// Associative arrays\n@safe pure unittest\n{\n    auto str = `[\"one\": 1, \"two\": 2]`;\n    auto spec = singleSpec(\"%s\");\n    assert(str.unformatValue!(int[string])(spec) == [\"one\": 1, \"two\": 2]);\n}\n\n@safe pure unittest\n{\n    // 7241\n    string input = \"a\";\n    auto spec = FormatSpec!char(\"%s\");\n    spec.readUpToNextSpec(input);\n    auto result = unformatValue!(dchar[1])(input, spec);\n    assert(result[0] == 'a');\n}\n\nprivate T unformatValueImpl(T, Range, Char)(ref Range input, const ref FormatSpec!Char spec)\nif (isInputRange!Range && is(Unqual!T == bool))\n{\n    import std.algorithm.searching : find;\n    import std.conv : parse, text;\n\n    if (spec.spec == 's') return parse!T(input);\n\n    enforceFmt(find(acceptedSpecs!long, spec.spec).length,\n            text(\"Wrong unformat specifier '%\", spec.spec , \"' for \", T.stringof));\n\n    return unformatValue!long(input, spec) != 0;\n}\n\nprivate T unformatValueImpl(T, Range, Char)(ref Range input, const ref FormatSpec!Char spec)\nif (isInputRange!Range && is(T == typeof(null)))\n{\n    import std.conv : parse, text;\n    enforceFmt(spec.spec == 's',\n            text(\"Wrong unformat specifier '%\", spec.spec , \"' for \", T.stringof));\n\n    return parse!T(input);\n}\n\n/// ditto\nprivate T unformatValueImpl(T, Range, Char)(ref Range input, const ref FormatSpec!Char spec)\nif (isInputRange!Range && isIntegral!T && !is(T == enum) && isSomeChar!(ElementType!Range))\n{\n\n    import std.algorithm.searching : find;\n    import std.conv : parse, text;\n\n    if (spec.spec == 'r')\n    {\n        static if (is(Unqual!(ElementEncodingType!Range) == char)\n                || is(Unqual!(ElementEncodingType!Range) == byte)\n                || is(Unqual!(ElementEncodingType!Range) == ubyte))\n            return rawRead!T(input);\n        else\n            throw new FormatException(\n                \"The raw read specifier %r may only be used with narrow strings and ranges of bytes.\"\n            );\n    }\n\n    enforceFmt(find(acceptedSpecs!T, spec.spec).length,\n            text(\"Wrong unformat specifier '%\", spec.spec , \"' for \", T.stringof));\n\n    enforceFmt(spec.width == 0, \"Parsing integers with a width specification is not implemented\");   // TODO\n\n    immutable uint base =\n        spec.spec == 'x' || spec.spec == 'X' ? 16 :\n        spec.spec == 'o' ? 8 :\n        spec.spec == 'b' ? 2 :\n        spec.spec == 's' || spec.spec == 'd' || spec.spec == 'u' ? 10 : 0;\n    assert(base != 0);\n\n    return parse!T(input, base);\n\n}\n\n/// ditto\nprivate T unformatValueImpl(T, Range, Char)(ref Range input, const ref FormatSpec!Char spec)\nif (isFloatingPoint!T && !is(T == enum) && isInputRange!Range\n    && isSomeChar!(ElementType!Range)&& !is(Range == enum))\n{\n    import std.algorithm.searching : find;\n    import std.conv : parse, text;\n\n    if (spec.spec == 'r')\n    {\n        static if (is(Unqual!(ElementEncodingType!Range) == char)\n                || is(Unqual!(ElementEncodingType!Range) == byte)\n                || is(Unqual!(ElementEncodingType!Range) == ubyte))\n            return rawRead!T(input);\n        else\n            throw new FormatException(\n                \"The raw read specifier %r may only be used with narrow strings and ranges of bytes.\"\n            );\n    }\n\n    enforceFmt(find(acceptedSpecs!T, spec.spec).length,\n            text(\"Wrong unformat specifier '%\", spec.spec , \"' for \", T.stringof));\n\n    return parse!T(input);\n}\n\n/// ditto\nprivate T unformatValueImpl(T, Range, Char)(ref Range input, const ref FormatSpec!Char spec)\nif (isInputRange!Range && isSomeChar!T && !is(T == enum) && isSomeChar!(ElementType!Range))\n{\n    import std.algorithm.searching : find;\n    import std.conv : to, text;\n    if (spec.spec == 's' || spec.spec == 'c')\n    {\n        auto result = to!T(input.front);\n        input.popFront();\n        return result;\n    }\n    enforceFmt(find(acceptedSpecs!T, spec.spec).length,\n            text(\"Wrong unformat specifier '%\", spec.spec , \"' for \", T.stringof));\n\n    static if (T.sizeof == 1)\n        return unformatValue!ubyte(input, spec);\n    else static if (T.sizeof == 2)\n        return unformatValue!ushort(input, spec);\n    else static if (T.sizeof == 4)\n        return unformatValue!uint(input, spec);\n    else\n        static assert(0);\n}\n\n/// ditto\nprivate T unformatValueImpl(T, Range, Char)(ref Range input, const ref FormatSpec!Char spec)\nif (isInputRange!Range && is(StringTypeOf!T) && !isAggregateType!T && !is(T == enum))\n{\n    import std.conv : text;\n\n    if (spec.spec == '(')\n    {\n        return unformatRange!T(input, spec);\n    }\n    enforceFmt(spec.spec == 's',\n            text(\"Wrong unformat specifier '%\", spec.spec , \"' for \", T.stringof));\n\n    static if (isStaticArray!T)\n    {\n        T result;\n        auto app = result[];\n    }\n    else\n    {\n        import std.array : appender;\n        auto app = appender!T();\n    }\n    if (spec.trailing.empty)\n    {\n        for (; !input.empty; input.popFront())\n        {\n            static if (isStaticArray!T)\n                if (app.empty)\n                    break;\n            app.put(input.front);\n        }\n    }\n    else\n    {\n        immutable end = spec.trailing.front;\n        for (; !input.empty && input.front != end; input.popFront())\n        {\n            static if (isStaticArray!T)\n                if (app.empty)\n                    break;\n            app.put(input.front);\n        }\n    }\n    static if (isStaticArray!T)\n    {\n        enforceFmt(app.empty, \"need more input\");\n        return result;\n    }\n    else\n        return app.data;\n}\n\n/// ditto\nprivate T unformatValueImpl(T, Range, Char)(ref Range input, const ref FormatSpec!Char spec)\nif (isInputRange!Range && isArray!T && !is(StringTypeOf!T) && !isAggregateType!T && !is(T == enum))\n{\n    import std.conv : parse, text;\n    if (spec.spec == '(')\n    {\n        return unformatRange!T(input, spec);\n    }\n    enforceFmt(spec.spec == 's',\n            text(\"Wrong unformat specifier '%\", spec.spec , \"' for \", T.stringof));\n\n    return parse!T(input);\n}\n\n/// ditto\nprivate T unformatValueImpl(T, Range, Char)(ref Range input, const ref FormatSpec!Char spec)\nif (isInputRange!Range && isAssociativeArray!T && !is(T == enum))\n{\n    import std.conv : parse, text;\n    if (spec.spec == '(')\n    {\n        return unformatRange!T(input, spec);\n    }\n    enforceFmt(spec.spec == 's',\n            text(\"Wrong unformat specifier '%\", spec.spec , \"' for \", T.stringof));\n\n    return parse!T(input);\n}\n\n/**\n * Function that performs raw reading. Used by unformatValue\n * for integral and float types.\n */\nprivate T rawRead(T, Range)(ref Range input)\nif (is(Unqual!(ElementEncodingType!Range) == char)\n    || is(Unqual!(ElementEncodingType!Range) == byte)\n    || is(Unqual!(ElementEncodingType!Range) == ubyte))\n{\n    union X\n    {\n        ubyte[T.sizeof] raw;\n        T typed;\n    }\n    X x;\n    foreach (i; 0 .. T.sizeof)\n    {\n        static if (isSomeString!Range)\n        {\n            x.raw[i] = input[0];\n            input = input[1 .. $];\n        }\n        else\n        {\n            // TODO: recheck this\n            x.raw[i] = input.front;\n            input.popFront();\n        }\n    }\n    return x.typed;\n}\n\n//debug = unformatRange;\n\nprivate T unformatRange(T, Range, Char)(ref Range input, const ref FormatSpec!Char spec)\nin\n{\n    assert(spec.spec == '(');\n}\ndo\n{\n    debug (unformatRange) printf(\"unformatRange:\\n\");\n\n    T result;\n    static if (isStaticArray!T)\n    {\n        size_t i;\n    }\n\n    const(Char)[] cont = spec.trailing;\n    for (size_t j = 0; j < spec.trailing.length; ++j)\n    {\n        if (spec.trailing[j] == '%')\n        {\n            cont = spec.trailing[0 .. j];\n            break;\n        }\n    }\n    debug (unformatRange) printf(\"\\t\");\n    debug (unformatRange) if (!input.empty) printf(\"input.front = %c, \", input.front);\n    debug (unformatRange) printf(\"cont = %.*s\\n\", cont);\n\n    bool checkEnd()\n    {\n        return input.empty || !cont.empty && input.front == cont.front;\n    }\n\n    if (!checkEnd())\n    {\n        for (;;)\n        {\n            auto fmt = FormatSpec!Char(spec.nested);\n            fmt.readUpToNextSpec(input);\n            enforceFmt(!input.empty, \"Unexpected end of input when parsing range\");\n\n            debug (unformatRange) printf(\"\\t) spec = %c, front = %c \", fmt.spec, input.front);\n            static if (isStaticArray!T)\n            {\n                result[i++] = unformatElement!(typeof(T.init[0]))(input, fmt);\n            }\n            else static if (isDynamicArray!T)\n            {\n                result ~= unformatElement!(ElementType!T)(input, fmt);\n            }\n            else static if (isAssociativeArray!T)\n            {\n                auto key = unformatElement!(typeof(T.init.keys[0]))(input, fmt);\n                fmt.readUpToNextSpec(input);        // eat key separator\n\n                result[key] = unformatElement!(typeof(T.init.values[0]))(input, fmt);\n            }\n            debug (unformatRange) {\n            if (input.empty) printf(\"-> front = [empty] \");\n            else             printf(\"-> front = %c \", input.front);\n            }\n\n            static if (isStaticArray!T)\n            {\n                debug (unformatRange) printf(\"i = %u < %u\\n\", i, T.length);\n                enforceFmt(i <= T.length, \"Too many format specifiers for static array of length %d\".format(T.length));\n            }\n\n            if (spec.sep !is null)\n                fmt.readUpToNextSpec(input);\n            auto sep = spec.sep !is null ? spec.sep\n                         : fmt.trailing;\n            debug (unformatRange) {\n            if (!sep.empty && !input.empty) printf(\"-> %c, sep = %.*s\\n\", input.front, sep);\n            else                            printf(\"\\n\");\n            }\n\n            if (checkEnd())\n                break;\n\n            if (!sep.empty && input.front == sep.front)\n            {\n                while (!sep.empty)\n                {\n                    enforceFmt(!input.empty, \"Unexpected end of input when parsing range separator\");\n                    enforceFmt(input.front == sep.front, \"Unexpected character when parsing range separator\");\n                    input.popFront();\n                    sep.popFront();\n                }\n                debug (unformatRange) printf(\"input.front = %c\\n\", input.front);\n            }\n        }\n    }\n    static if (isStaticArray!T)\n    {\n        enforceFmt(i == T.length, \"Too few (%d) format specifiers for static array of length %d\".format(i, T.length));\n    }\n    return result;\n}\n\n// Undocumented\nT unformatElement(T, Range, Char)(ref Range input, const ref FormatSpec!Char spec)\nif (isInputRange!Range)\n{\n    import std.conv : parseElement;\n    static if (isSomeString!T)\n    {\n        if (spec.spec == 's')\n        {\n            return parseElement!T(input);\n        }\n    }\n    else static if (isSomeChar!T)\n    {\n        if (spec.spec == 's')\n        {\n            return parseElement!T(input);\n        }\n    }\n\n    return unformatValue!T(input, spec);\n}\n\n\n// Legacy implementation\n// @@@DEPRECATED_2019-01@@@\ndeprecated(\"Use std.demangle\")\nenum Mangle : char\n{\n    Tvoid     = 'v',\n    Tbool     = 'b',\n    Tbyte     = 'g',\n    Tubyte    = 'h',\n    Tshort    = 's',\n    Tushort   = 't',\n    Tint      = 'i',\n    Tuint     = 'k',\n    Tlong     = 'l',\n    Tulong    = 'm',\n    Tfloat    = 'f',\n    Tdouble   = 'd',\n    Treal     = 'e',\n\n    Tifloat   = 'o',\n    Tidouble  = 'p',\n    Tireal    = 'j',\n    Tcfloat   = 'q',\n    Tcdouble  = 'r',\n    Tcreal    = 'c',\n\n    Tchar     = 'a',\n    Twchar    = 'u',\n    Tdchar    = 'w',\n\n    Tarray    = 'A',\n    Tsarray   = 'G',\n    Taarray   = 'H',\n    Tpointer  = 'P',\n    Tfunction = 'F',\n    Tident    = 'I',\n    Tclass    = 'C',\n    Tstruct   = 'S',\n    Tenum     = 'E',\n    Ttypedef  = 'T',\n    Tdelegate = 'D',\n\n    Tconst    = 'x',\n    Timmutable = 'y',\n}\n\nprivate bool needToSwapEndianess(Char)(const ref FormatSpec!Char f)\n{\n    import std.system : endian, Endian;\n\n    return endian == Endian.littleEndian && f.flPlus\n        || endian == Endian.bigEndian && f.flDash;\n}\n\n/* ======================== Unit Tests ====================================== */\n\n@system unittest\n{\n    import std.conv : octal;\n\n    int i;\n    string s;\n\n    debug(format) printf(\"std.format.format.unittest\\n\");\n\n    s = format(\"hello world! %s %s %s%s%s\", true, 57, 1_000_000_000, 'x', \" foo\");\n    assert(s == \"hello world! true 57 1000000000x foo\");\n\n    s = format(\"%s %A %s\", 1.67, -1.28, float.nan);\n    /* The host C library is used to format floats.\n     * C99 doesn't specify what the hex digit before the decimal point\n     * is for %A.\n     */\n    //version (linux)\n    //    assert(s == \"1.67 -0XA.3D70A3D70A3D8P-3 nan\");\n    //else version (OSX)\n    //    assert(s == \"1.67 -0XA.3D70A3D70A3D8P-3 nan\", s);\n    //else\n    version (MinGW)\n        assert(s == \"1.67 -0XA.3D70A3D70A3D8P-3 nan\", s);\n    else version (CRuntime_Microsoft)\n        assert(s == \"1.67 -0X1.47AE14P+0 nan\"\n            || s == \"1.67 -0X1.47AE147AE147BP+0 nan\", s); // MSVCRT 14+ (VS 2015)\n    else\n        assert(s == \"1.67 -0X1.47AE147AE147BP+0 nan\", s);\n\n    s = format(\"%x %X\", 0x1234AF, 0xAFAFAFAF);\n    assert(s == \"1234af AFAFAFAF\");\n\n    s = format(\"%b %o\", 0x1234AF, 0xAFAFAFAF);\n    assert(s == \"100100011010010101111 25753727657\");\n\n    s = format(\"%d %s\", 0x1234AF, 0xAFAFAFAF);\n    assert(s == \"1193135 2947526575\");\n}\n\nversion (TestComplex)\ndeprecated\n@system unittest\n{\n        string s = format(\"%s\", 1.2 + 3.4i);\n        assert(s == \"1.2+3.4i\", s);\n}\n\n@system unittest\n{\n    import std.conv : octal;\n\n    string s;\n    int i;\n\n    s = format(\"%#06.*f\",2,12.345);\n    assert(s == \"012.35\");\n\n    s = format(\"%#0*.*f\",6,2,12.345);\n    assert(s == \"012.35\");\n\n    s = format(\"%7.4g:\", 12.678);\n    assert(s == \"  12.68:\");\n\n    s = format(\"%7.4g:\", 12.678L);\n    assert(s == \"  12.68:\");\n\n    s = format(\"%04f|%05d|%#05x|%#5x\",-4.0,-10,1,1);\n    assert(s == \"-4.000000|-0010|0x001|  0x1\");\n\n    i = -10;\n    s = format(\"%d|%3d|%03d|%1d|%01.4f\",i,i,i,i,cast(double) i);\n    assert(s == \"-10|-10|-10|-10|-10.0000\");\n\n    i = -5;\n    s = format(\"%d|%3d|%03d|%1d|%01.4f\",i,i,i,i,cast(double) i);\n    assert(s == \"-5| -5|-05|-5|-5.0000\");\n\n    i = 0;\n    s = format(\"%d|%3d|%03d|%1d|%01.4f\",i,i,i,i,cast(double) i);\n    assert(s == \"0|  0|000|0|0.0000\");\n\n    i = 5;\n    s = format(\"%d|%3d|%03d|%1d|%01.4f\",i,i,i,i,cast(double) i);\n    assert(s == \"5|  5|005|5|5.0000\");\n\n    i = 10;\n    s = format(\"%d|%3d|%03d|%1d|%01.4f\",i,i,i,i,cast(double) i);\n    assert(s == \"10| 10|010|10|10.0000\");\n\n    s = format(\"%.0d\", 0);\n    assert(s == \"\");\n\n    s = format(\"%.g\", .34);\n    assert(s == \"0.3\");\n\n    s = format(\"%.0g\", .34);\n    assert(s == \"0.3\");\n\n    s = format(\"%.2g\", .34);\n    assert(s == \"0.34\");\n\n    s = format(\"%0.0008f\", 1e-08);\n    assert(s == \"0.00000001\");\n\n    s = format(\"%0.0008f\", 1e-05);\n    assert(s == \"0.00001000\");\n\n    s = \"helloworld\";\n    string r;\n    r = format(\"%.2s\", s[0 .. 5]);\n    assert(r == \"he\");\n    r = format(\"%.20s\", s[0 .. 5]);\n    assert(r == \"hello\");\n    r = format(\"%8s\", s[0 .. 5]);\n    assert(r == \"   hello\");\n\n    byte[] arrbyte = new byte[4];\n    arrbyte[0] = 100;\n    arrbyte[1] = -99;\n    arrbyte[3] = 0;\n    r = format(\"%s\", arrbyte);\n    assert(r == \"[100, -99, 0, 0]\");\n\n    ubyte[] arrubyte = new ubyte[4];\n    arrubyte[0] = 100;\n    arrubyte[1] = 200;\n    arrubyte[3] = 0;\n    r = format(\"%s\", arrubyte);\n    assert(r == \"[100, 200, 0, 0]\");\n\n    short[] arrshort = new short[4];\n    arrshort[0] = 100;\n    arrshort[1] = -999;\n    arrshort[3] = 0;\n    r = format(\"%s\", arrshort);\n    assert(r == \"[100, -999, 0, 0]\");\n\n    ushort[] arrushort = new ushort[4];\n    arrushort[0] = 100;\n    arrushort[1] = 20_000;\n    arrushort[3] = 0;\n    r = format(\"%s\", arrushort);\n    assert(r == \"[100, 20000, 0, 0]\");\n\n    int[] arrint = new int[4];\n    arrint[0] = 100;\n    arrint[1] = -999;\n    arrint[3] = 0;\n    r = format(\"%s\", arrint);\n    assert(r == \"[100, -999, 0, 0]\");\n\n    long[] arrlong = new long[4];\n    arrlong[0] = 100;\n    arrlong[1] = -999;\n    arrlong[3] = 0;\n    r = format(\"%s\", arrlong);\n    assert(r == \"[100, -999, 0, 0]\");\n\n    ulong[] arrulong = new ulong[4];\n    arrulong[0] = 100;\n    arrulong[1] = 999;\n    arrulong[3] = 0;\n    r = format(\"%s\", arrulong);\n    assert(r == \"[100, 999, 0, 0]\");\n\n    string[] arr2 = new string[4];\n    arr2[0] = \"hello\";\n    arr2[1] = \"world\";\n    arr2[3] = \"foo\";\n    r = format(\"%s\", arr2);\n    assert(r == `[\"hello\", \"world\", \"\", \"foo\"]`);\n\n    r = format(\"%.8d\", 7);\n    assert(r == \"00000007\");\n    r = format(\"%.8x\", 10);\n    assert(r == \"0000000a\");\n\n    r = format(\"%-3d\", 7);\n    assert(r == \"7  \");\n\n    r = format(\"%-1*d\", 4, 3);\n    assert(r == \"3   \");\n\n    r = format(\"%*d\", -3, 7);\n    assert(r == \"7  \");\n\n    r = format(\"%.*d\", -3, 7);\n    assert(r == \"7\");\n\n    r = format(\"%-1.*f\", 2, 3.1415);\n    assert(r == \"3.14\");\n\n    r = format(\"abc\"c);\n    assert(r == \"abc\");\n\n    //format() returns the same type as inputted.\n    wstring wr;\n    wr = format(\"def\"w);\n    assert(wr == \"def\"w);\n\n    dstring dr;\n    dr = format(\"ghi\"d);\n    assert(dr == \"ghi\"d);\n\n    void* p = cast(void*) 0xDEADBEEF;\n    r = format(\"%s\", p);\n    assert(r == \"DEADBEEF\");\n\n    r = format(\"%#x\", 0xabcd);\n    assert(r == \"0xabcd\");\n    r = format(\"%#X\", 0xABCD);\n    assert(r == \"0XABCD\");\n\n    r = format(\"%#o\", octal!12345);\n    assert(r == \"012345\");\n    r = format(\"%o\", 9);\n    assert(r == \"11\");\n    r = format(\"%#o\", 0);   // issue 15663\n    assert(r == \"0\");\n\n    r = format(\"%+d\", 123);\n    assert(r == \"+123\");\n    r = format(\"%+d\", -123);\n    assert(r == \"-123\");\n    r = format(\"% d\", 123);\n    assert(r == \" 123\");\n    r = format(\"% d\", -123);\n    assert(r == \"-123\");\n\n    r = format(\"%%\");\n    assert(r == \"%\");\n\n    r = format(\"%d\", true);\n    assert(r == \"1\");\n    r = format(\"%d\", false);\n    assert(r == \"0\");\n\n    r = format(\"%d\", 'a');\n    assert(r == \"97\");\n    wchar wc = 'a';\n    r = format(\"%d\", wc);\n    assert(r == \"97\");\n    dchar dc = 'a';\n    r = format(\"%d\", dc);\n    assert(r == \"97\");\n\n    byte b = byte.max;\n    r = format(\"%x\", b);\n    assert(r == \"7f\");\n    r = format(\"%x\", ++b);\n    assert(r == \"80\");\n    r = format(\"%x\", ++b);\n    assert(r == \"81\");\n\n    short sh = short.max;\n    r = format(\"%x\", sh);\n    assert(r == \"7fff\");\n    r = format(\"%x\", ++sh);\n    assert(r == \"8000\");\n    r = format(\"%x\", ++sh);\n    assert(r == \"8001\");\n\n    i = int.max;\n    r = format(\"%x\", i);\n    assert(r == \"7fffffff\");\n    r = format(\"%x\", ++i);\n    assert(r == \"80000000\");\n    r = format(\"%x\", ++i);\n    assert(r == \"80000001\");\n\n    r = format(\"%x\", 10);\n    assert(r == \"a\");\n    r = format(\"%X\", 10);\n    assert(r == \"A\");\n    r = format(\"%x\", 15);\n    assert(r == \"f\");\n    r = format(\"%X\", 15);\n    assert(r == \"F\");\n\n    Object c = null;\n    r = format(\"%s\", c);\n    assert(r == \"null\");\n\n    enum TestEnum\n    {\n        Value1, Value2\n    }\n    r = format(\"%s\", TestEnum.Value2);\n    assert(r == \"Value2\");\n\n    immutable(char[5])[int] aa = ([3:\"hello\", 4:\"betty\"]);\n    r = format(\"%s\", aa.values);\n    assert(r == `[\"hello\", \"betty\"]` || r == `[\"betty\", \"hello\"]`);\n    r = format(\"%s\", aa);\n    assert(r == `[3:\"hello\", 4:\"betty\"]` || r == `[4:\"betty\", 3:\"hello\"]`);\n\n    static const dchar[] ds = ['a','b'];\n    for (int j = 0; j < ds.length; ++j)\n    {\n        r = format(\" %d\", ds[j]);\n        if (j == 0)\n            assert(r == \" 97\");\n        else\n            assert(r == \" 98\");\n    }\n\n    r = format(\">%14d<, %s\", 15, [1,2,3]);\n    assert(r == \">            15<, [1, 2, 3]\");\n\n    assert(format(\"%8s\", \"bar\") == \"     bar\");\n    assert(format(\"%8s\", \"b\\u00e9ll\\u00f4\") == \"   b\\u00e9ll\\u00f4\");\n}\n\n@safe pure unittest // bugzilla 18205\n{\n    assert(\"|%8s|\".format(\"abc\")        == \"|     abc|\");\n    assert(\"|%8s|\".format(\"αβγ\")        == \"|     αβγ|\");\n    assert(\"|%8s|\".format(\"   \")        == \"|        |\");\n    assert(\"|%8s|\".format(\"été\"d)       == \"|     été|\");\n    assert(\"|%8s|\".format(\"été 2018\"w)  == \"|été 2018|\");\n\n    assert(\"%2s\".format(\"e\\u0301\"w) == \" e\\u0301\");\n    assert(\"%2s\".format(\"a\\u0310\\u0337\"d) == \" a\\u0310\\u0337\");\n}\n\n@safe unittest\n{\n    // bugzilla 3479\n    import std.array;\n    auto stream = appender!(char[])();\n    formattedWrite(stream, \"%2$.*1$d\", 12, 10);\n    assert(stream.data == \"000000000010\", stream.data);\n}\n\n@safe unittest\n{\n    // bug 6893\n    import std.array;\n    enum E : ulong { A, B, C }\n    auto stream = appender!(char[])();\n    formattedWrite(stream, \"%s\", E.C);\n    assert(stream.data == \"C\");\n}\n\n// Used to check format strings are compatible with argument types\npackage static const checkFormatException(alias fmt, Args...) =\n{\n    import std.conv : text;\n\n    try\n    {\n        auto n = .formattedWrite(NoOpSink(), fmt, Args.init);\n\n        enforceFmt(n == Args.length, text(\"Orphan format arguments: args[\", n, \"..\", Args.length, \"]\"));\n    }\n    catch (Exception e)\n        return (e.msg == ctfpMessage) ? null : e;\n    return null;\n}();\n\n/**\n * Format arguments into a string.\n *\n * If the format string is fixed, passing it as a template parameter checks the\n * type correctness of the parameters at compile-time. This also can result in\n * better performance.\n *\n * Params: fmt  = Format string. For detailed specification, see $(LREF formattedWrite).\n *         args = Variadic list of arguments to format into returned string.\n *\n * Throws:\n *     $(LREF, FormatException) if the number of arguments doesn't match the number\n *     of format parameters and vice-versa.\n */\ntypeof(fmt) format(alias fmt, Args...)(Args args)\nif (isSomeString!(typeof(fmt)))\n{\n    import std.array : appender;\n\n    alias e = checkFormatException!(fmt, Args);\n    alias Char = Unqual!(ElementEncodingType!(typeof(fmt)));\n\n    static assert(!e, e.msg);\n    auto w = appender!(immutable(Char)[]);\n\n    // no need to traverse the string twice during compile time\n    if (!__ctfe)\n    {\n        enum len = guessLength!Char(fmt);\n        w.reserve(len);\n    }\n    else\n    {\n        w.reserve(fmt.length);\n    }\n\n    formattedWrite(w, fmt, args);\n    return w.data;\n}\n\n/// Type checking can be done when fmt is known at compile-time:\n@safe unittest\n{\n    auto s = format!\"%s is %s\"(\"Pi\", 3.14);\n    assert(s == \"Pi is 3.14\");\n\n    static assert(!__traits(compiles, {s = format!\"%l\"();}));     // missing arg\n    static assert(!__traits(compiles, {s = format!\"\"(404);}));    // surplus arg\n    static assert(!__traits(compiles, {s = format!\"%d\"(4.03);})); // incompatible arg\n}\n\n// called during compilation to guess the length of the\n// result of format\nprivate size_t guessLength(Char, S)(S fmtString)\n{\n    import std.array : appender;\n\n    size_t len;\n    auto output = appender!(immutable(Char)[])();\n    auto spec = FormatSpec!Char(fmtString);\n    while (spec.writeUpToNextSpec(output))\n    {\n        // take a guess\n        if (spec.width == 0 && (spec.precision == spec.UNSPECIFIED || spec.precision == spec.DYNAMIC))\n        {\n            switch (spec.spec)\n            {\n                case 'c':\n                    ++len;\n                    break;\n                case 'd':\n                case 'x':\n                case 'X':\n                    len += 3;\n                    break;\n                case 'b':\n                    len += 8;\n                    break;\n                case 'f':\n                case 'F':\n                    len += 10;\n                    break;\n                case 's':\n                case 'e':\n                case 'E':\n                case 'g':\n                case 'G':\n                    len += 12;\n                    break;\n                default: break;\n            }\n\n            continue;\n        }\n\n        if ((spec.spec == 'e' || spec.spec == 'E' || spec.spec == 'g' ||\n             spec.spec == 'G' || spec.spec == 'f' || spec.spec == 'F') &&\n            spec.precision != spec.UNSPECIFIED && spec.precision != spec.DYNAMIC &&\n            spec.width == 0\n        )\n        {\n            len += spec.precision + 5;\n            continue;\n        }\n\n        if (spec.width == spec.precision)\n            len += spec.width;\n        else if (spec.width > 0 && spec.width != spec.DYNAMIC &&\n                 (spec.precision == spec.UNSPECIFIED || spec.width > spec.precision))\n        {\n            len += spec.width;\n        }\n        else if (spec.precision != spec.UNSPECIFIED && spec.precision > spec.width)\n            len += spec.precision;\n    }\n    len += output.data.length;\n    return len;\n}\n\n@safe pure\nunittest\n{\n    assert(guessLength!char(\"%c\") == 1);\n    assert(guessLength!char(\"%d\") == 3);\n    assert(guessLength!char(\"%x\") == 3);\n    assert(guessLength!char(\"%b\") == 8);\n    assert(guessLength!char(\"%f\") == 10);\n    assert(guessLength!char(\"%s\") == 12);\n    assert(guessLength!char(\"%02d\") == 2);\n    assert(guessLength!char(\"%02d\") == 2);\n    assert(guessLength!char(\"%4.4d\") == 4);\n    assert(guessLength!char(\"%2.4f\") == 4);\n    assert(guessLength!char(\"%02d:%02d:%02d\") == 8);\n    assert(guessLength!char(\"%0.2f\") == 7);\n    assert(guessLength!char(\"%0*d\") == 0);\n}\n\n/// ditto\nimmutable(Char)[] format(Char, Args...)(in Char[] fmt, Args args)\nif (isSomeChar!Char)\n{\n    import std.array : appender;\n    auto w = appender!(immutable(Char)[]);\n    auto n = formattedWrite(w, fmt, args);\n    version (all)\n    {\n        // In the future, this check will be removed to increase consistency\n        // with formattedWrite\n        import std.conv : text;\n        enforceFmt(n == args.length, text(\"Orphan format arguments: args[\", n, \"..\", args.length, \"]\"));\n    }\n    return w.data;\n}\n\n@safe pure unittest\n{\n    import core.exception;\n    import std.exception;\n    assertCTFEable!(\n    {\n//  assert(format(null) == \"\");\n    assert(format(\"foo\") == \"foo\");\n    assert(format(\"foo%%\") == \"foo%\");\n    assert(format(\"foo%s\", 'C') == \"fooC\");\n    assert(format(\"%s foo\", \"bar\") == \"bar foo\");\n    assert(format(\"%s foo %s\", \"bar\", \"abc\") == \"bar foo abc\");\n    assert(format(\"foo %d\", -123) == \"foo -123\");\n    assert(format(\"foo %d\", 123) == \"foo 123\");\n\n    assertThrown!FormatException(format(\"foo %s\"));\n    assertThrown!FormatException(format(\"foo %s\", 123, 456));\n\n    assert(format(\"hel%slo%s%s%s\", \"world\", -138, 'c', true) ==\n                  \"helworldlo-138ctrue\");\n    });\n\n    assert(is(typeof(format(\"happy\")) == string));\n    assert(is(typeof(format(\"happy\"w)) == wstring));\n    assert(is(typeof(format(\"happy\"d)) == dstring));\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=16661\n@safe unittest\n{\n    assert(format(\"%.2f\"d, 0.4) == \"0.40\");\n    assert(\"%02d\"d.format(1) == \"01\"d);\n}\n\n/*****************************************************\n * Format arguments into buffer $(I buf) which must be large\n * enough to hold the result.\n *\n * Returns:\n *     The slice of `buf` containing the formatted string.\n *\n * Throws:\n *     A `RangeError` if `buf` isn't large enough to hold the\n *     formatted string.\n *\n *     A $(LREF FormatException) if the length of `args` is different\n *     than the number of format specifiers in `fmt`.\n */\nchar[] sformat(alias fmt, Args...)(char[] buf, Args args)\nif (isSomeString!(typeof(fmt)))\n{\n    alias e = checkFormatException!(fmt, Args);\n    static assert(!e, e.msg);\n    return .sformat(buf, fmt, args);\n}\n\n/// ditto\nchar[] sformat(Char, Args...)(return scope char[] buf, scope const(Char)[] fmt, Args args)\n{\n    import core.exception : RangeError;\n    import std.utf : encode;\n\n    size_t i;\n\n    struct Sink\n    {\n        void put(dchar c)\n        {\n            char[4] enc;\n            auto n = encode(enc, c);\n\n            if (buf.length < i + n)\n                throw new RangeError(__FILE__, __LINE__);\n\n            buf[i .. i + n] = enc[0 .. n];\n            i += n;\n        }\n        void put(scope const(char)[] s)\n        {\n            if (buf.length < i + s.length)\n                throw new RangeError(__FILE__, __LINE__);\n\n            buf[i .. i + s.length] = s[];\n            i += s.length;\n        }\n        void put(scope const(wchar)[] s)\n        {\n            for (; !s.empty; s.popFront())\n                put(s.front);\n        }\n        void put(scope const(dchar)[] s)\n        {\n            for (; !s.empty; s.popFront())\n                put(s.front);\n        }\n    }\n    auto n = formattedWrite(Sink(), fmt, args);\n    version (all)\n    {\n        // In the future, this check will be removed to increase consistency\n        // with formattedWrite\n        import std.conv : text;\n        enforceFmt(\n            n == args.length,\n            text(\"Orphan format arguments: args[\", n, \" .. \", args.length, \"]\")\n        );\n    }\n    return buf[0 .. i];\n}\n\n/// The format string can be checked at compile-time (see $(LREF format) for details):\n@system unittest\n{\n    char[10] buf;\n\n    assert(buf[].sformat!\"foo%s\"('C') == \"fooC\");\n    assert(sformat(buf[], \"%s foo\", \"bar\") == \"bar foo\");\n}\n\n@system unittest\n{\n    import core.exception;\n\n    debug(string) trustedPrintf(\"std.string.sformat.unittest\\n\");\n\n    import std.exception;\n    assertCTFEable!(\n    {\n    char[10] buf;\n\n    assert(sformat(buf[], \"foo\") == \"foo\");\n    assert(sformat(buf[], \"foo%%\") == \"foo%\");\n    assert(sformat(buf[], \"foo%s\", 'C') == \"fooC\");\n    assert(sformat(buf[], \"%s foo\", \"bar\") == \"bar foo\");\n    assertThrown!RangeError(sformat(buf[], \"%s foo %s\", \"bar\", \"abc\"));\n    assert(sformat(buf[], \"foo %d\", -123) == \"foo -123\");\n    assert(sformat(buf[], \"foo %d\", 123) == \"foo 123\");\n\n    assertThrown!FormatException(sformat(buf[], \"foo %s\"));\n    assertThrown!FormatException(sformat(buf[], \"foo %s\", 123, 456));\n\n    assert(sformat(buf[], \"%s %s %s\", \"c\"c, \"w\"w, \"d\"d) == \"c w d\");\n    });\n}\n\n/*****************************\n * The .ptr is unsafe because it could be dereferenced and the length of the array may be 0.\n * Returns:\n *      the difference between the starts of the arrays\n */\n@trusted private pure nothrow @nogc\n    ptrdiff_t arrayPtrDiff(T)(const T[] array1, const T[] array2)\n{\n    return array1.ptr - array2.ptr;\n}\n\n@safe unittest\n{\n    assertCTFEable!({\n    auto tmp = format(\"%,d\", 1000);\n    assert(tmp == \"1,000\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%,?d\", 'z', 1234567);\n    assert(tmp == \"1z234z567\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%10,?d\", 'z', 1234567);\n    assert(tmp == \" 1z234z567\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%11,2?d\", 'z', 1234567);\n    assert(tmp == \" 1z23z45z67\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%11,*?d\", 2, 'z', 1234567);\n    assert(tmp == \" 1z23z45z67\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%11,*d\", 2, 1234567);\n    assert(tmp == \" 1,23,45,67\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%11,2d\", 1234567);\n    assert(tmp == \" 1,23,45,67\", \"'\" ~ tmp ~ \"'\");\n    });\n}\n\n@safe unittest\n{\n    auto tmp = format(\"%,f\", 1000.0);\n    assert(tmp == \"1,000.000,000\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%,f\", 1234567.891011);\n    assert(tmp == \"1,234,567.891,011\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%,f\", -1234567.891011);\n    assert(tmp == \"-1,234,567.891,011\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%,2f\", 1234567.891011);\n    assert(tmp == \"1,23,45,67.89,10,11\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%18,f\", 1234567.891011);\n    assert(tmp == \" 1,234,567.891,011\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%18,?f\", '.', 1234567.891011);\n    assert(tmp == \" 1.234.567.891.011\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%,?.3f\", 'ä', 1234567.891011);\n    assert(tmp == \"1ä234ä567.891\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%,*?.3f\", 1, 'ä', 1234567.891011);\n    assert(tmp == \"1ä2ä3ä4ä5ä6ä7.8ä9ä1\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%,4?.3f\", '_', 1234567.891011);\n    assert(tmp == \"123_4567.891\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%12,3.3f\", 1234.5678);\n    assert(tmp == \"   1,234.568\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%,e\", 3.141592653589793238462);\n    assert(tmp == \"3.141,593e+00\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%15,e\", 3.141592653589793238462);\n    assert(tmp == \"  3.141,593e+00\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%15,e\", -3.141592653589793238462);\n    assert(tmp == \" -3.141,593e+00\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%.4,*e\", 2, 3.141592653589793238462);\n    assert(tmp == \"3.14,16e+00\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%13.4,*e\", 2, 3.141592653589793238462);\n    assert(tmp == \"  3.14,16e+00\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%,.0f\", 3.14);\n    assert(tmp == \"3\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%3,g\", 1_000_000.123456);\n    assert(tmp == \"1e+06\", \"'\" ~ tmp ~ \"'\");\n\n    tmp = format(\"%19,?f\", '.', -1234567.891011);\n    assert(tmp == \" -1.234.567.891.011\", \"'\" ~ tmp ~ \"'\");\n}\n\n// Test for multiple indexes\n@safe unittest\n{\n    auto tmp = format(\"%2:5$s\", 1, 2, 3, 4, 5);\n    assert(tmp == \"2345\", tmp);\n}\n\n// Issue 18047\n@safe unittest\n{\n    auto cmp = \"     123,456\";\n    assert(cmp.length == 12, format(\"%d\", cmp.length));\n    auto tmp = format(\"%12,d\", 123456);\n    assert(tmp.length == 12, format(\"%d\", tmp.length));\n\n    assert(tmp == cmp, \"'\" ~ tmp ~ \"'\");\n}\n\n// Issue 17459\n@safe unittest\n{\n    auto cmp = \"100\";\n    auto tmp  = format(\"%0d\", 100);\n    assert(tmp == cmp, tmp);\n\n    cmp = \"0100\";\n    tmp  = format(\"%04d\", 100);\n    assert(tmp == cmp, tmp);\n\n    cmp = \"0000,000,100\";\n    tmp  = format(\"%012,3d\", 100);\n    assert(tmp == cmp, tmp);\n\n    cmp = \"0000,001,000\";\n    tmp = format(\"%012,3d\", 1_000);\n    assert(tmp == cmp, tmp);\n\n    cmp = \"0000,100,000\";\n    tmp = format(\"%012,3d\", 100_000);\n    assert(tmp == cmp, tmp);\n\n    cmp = \"0001,000,000\";\n    tmp = format(\"%012,3d\", 1_000_000);\n    assert(tmp == cmp, tmp);\n\n    cmp = \"0100,000,000\";\n    tmp = format(\"%012,3d\", 100_000_000);\n    assert(tmp == cmp, tmp);\n}\n\n// Issue 17459\n@safe unittest\n{\n    auto cmp = \"100,000\";\n    auto tmp  = format(\"%06,d\", 100_000);\n    assert(tmp == cmp, tmp);\n\n    cmp = \"100,000\";\n    tmp  = format(\"%07,d\", 100_000);\n    assert(tmp == cmp, tmp);\n\n    cmp = \"0100,000\";\n    tmp  = format(\"%08,d\", 100_000);\n    assert(tmp == cmp, tmp);\n}\n"
  },
  {
    "path": "libphobos/src/std/functional.d",
    "content": "// Written in the D programming language.\n\n/**\nFunctions that manipulate other functions.\n\nThis module provides functions for compile time function composition. These\nfunctions are helpful when constructing predicates for the algorithms in\n$(MREF std, algorithm) or $(MREF std, range).\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE ,\n$(TR $(TH Function Name) $(TH Description)\n)\n    $(TR $(TD $(LREF adjoin))\n        $(TD Joins a couple of functions into one that executes the original\n        functions independently and returns a tuple with all the results.\n    ))\n    $(TR $(TD $(LREF compose), $(LREF pipe))\n        $(TD Join a couple of functions into one that executes the original\n        functions one after the other, using one function's result for the next\n        function's argument.\n    ))\n    $(TR $(TD $(LREF forward))\n        $(TD Forwards function arguments while saving ref-ness.\n    ))\n    $(TR $(TD $(LREF lessThan), $(LREF greaterThan), $(LREF equalTo))\n        $(TD Ready-made predicate functions to compare two values.\n    ))\n    $(TR $(TD $(LREF memoize))\n        $(TD Creates a function that caches its result for fast re-evaluation.\n    ))\n    $(TR $(TD $(LREF not))\n        $(TD Creates a function that negates another.\n    ))\n    $(TR $(TD $(LREF partial))\n        $(TD Creates a function that binds the first argument of a given function\n        to a given value.\n    ))\n    $(TR $(TD $(LREF reverseArgs))\n        $(TD Predicate that reverses the order of its arguments.\n    ))\n    $(TR $(TD $(LREF toDelegate))\n        $(TD Converts a callable to a delegate.\n    ))\n    $(TR $(TD $(LREF unaryFun), $(LREF binaryFun))\n        $(TD Create a unary or binary function from a string. Most often\n        used when defining algorithms on ranges.\n    ))\n)\n\nCopyright: Copyright Andrei Alexandrescu 2008 - 2009.\nLicense:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   $(HTTP erdani.org, Andrei Alexandrescu)\nSource:    $(PHOBOSSRC std/functional.d)\n*/\n/*\n         Copyright Andrei Alexandrescu 2008 - 2009.\nDistributed under the Boost Software License, Version 1.0.\n   (See accompanying file LICENSE_1_0.txt or copy at\n         http://www.boost.org/LICENSE_1_0.txt)\n*/\nmodule std.functional;\n\nimport std.meta; // AliasSeq, Reverse\nimport std.traits; // isCallable, Parameters\n\n\nprivate template needOpCallAlias(alias fun)\n{\n    /* Determine whether or not unaryFun and binaryFun need to alias to fun or\n     * fun.opCall. Basically, fun is a function object if fun(...) compiles. We\n     * want is(unaryFun!fun) (resp., is(binaryFun!fun)) to be true if fun is\n     * any function object. There are 4 possible cases:\n     *\n     *  1) fun is the type of a function object with static opCall;\n     *  2) fun is an instance of a function object with static opCall;\n     *  3) fun is the type of a function object with non-static opCall;\n     *  4) fun is an instance of a function object with non-static opCall.\n     *\n     * In case (1), is(unaryFun!fun) should compile, but does not if unaryFun\n     * aliases itself to fun, because typeof(fun) is an error when fun itself\n     * is a type. So it must be aliased to fun.opCall instead. All other cases\n     * should be aliased to fun directly.\n     */\n    static if (is(typeof(fun.opCall) == function))\n    {\n        enum needOpCallAlias = !is(typeof(fun)) && __traits(compiles, () {\n            return fun(Parameters!fun.init);\n        });\n    }\n    else\n        enum needOpCallAlias = false;\n}\n\n/**\nTransforms a `string` representing an expression into a unary\nfunction. The `string` must either use symbol name `a` as\nthe parameter or provide the symbol via the `parmName` argument.\n\nParams:\n    fun = a `string` or a callable\n    parmName = the name of the parameter if `fun` is a string. Defaults\n    to `\"a\"`.\nReturns:\n    If `fun` is a `string`, a new single parameter function\n\n    If `fun` is not a `string`, an alias to `fun`.\n*/\ntemplate unaryFun(alias fun, string parmName = \"a\")\n{\n    static if (is(typeof(fun) : string))\n    {\n        static if (!fun._ctfeMatchUnary(parmName))\n        {\n            import std.algorithm, std.conv, std.exception, std.math, std.range, std.string;\n            import std.meta, std.traits, std.typecons;\n        }\n        auto unaryFun(ElementType)(auto ref ElementType __a)\n        {\n            mixin(\"alias \" ~ parmName ~ \" = __a ;\");\n            return mixin(fun);\n        }\n    }\n    else static if (needOpCallAlias!fun)\n    {\n        // Issue 9906\n        alias unaryFun = fun.opCall;\n    }\n    else\n    {\n        alias unaryFun = fun;\n    }\n}\n\n///\n@safe unittest\n{\n    // Strings are compiled into functions:\n    alias isEven = unaryFun!(\"(a & 1) == 0\");\n    assert(isEven(2) && !isEven(1));\n}\n\n@safe unittest\n{\n    static int f1(int a) { return a + 1; }\n    static assert(is(typeof(unaryFun!(f1)(1)) == int));\n    assert(unaryFun!(f1)(41) == 42);\n    int f2(int a) { return a + 1; }\n    static assert(is(typeof(unaryFun!(f2)(1)) == int));\n    assert(unaryFun!(f2)(41) == 42);\n    assert(unaryFun!(\"a + 1\")(41) == 42);\n    //assert(unaryFun!(\"return a + 1;\")(41) == 42);\n\n    int num = 41;\n    assert(unaryFun!\"a + 1\"(num) == 42);\n\n    // Issue 9906\n    struct Seen\n    {\n        static bool opCall(int n) { return true; }\n    }\n    static assert(needOpCallAlias!Seen);\n    static assert(is(typeof(unaryFun!Seen(1))));\n    assert(unaryFun!Seen(1));\n\n    Seen s;\n    static assert(!needOpCallAlias!s);\n    static assert(is(typeof(unaryFun!s(1))));\n    assert(unaryFun!s(1));\n\n    struct FuncObj\n    {\n        bool opCall(int n) { return true; }\n    }\n    FuncObj fo;\n    static assert(!needOpCallAlias!fo);\n    static assert(is(typeof(unaryFun!fo)));\n    assert(unaryFun!fo(1));\n\n    // Function object with non-static opCall can only be called with an\n    // instance, not with merely the type.\n    static assert(!is(typeof(unaryFun!FuncObj)));\n}\n\n/**\nTransforms a `string` representing an expression into a binary function. The\n`string` must either use symbol names `a` and `b` as the parameters or\nprovide the symbols via the `parm1Name` and `parm2Name` arguments.\n\nParams:\n    fun = a `string` or a callable\n    parm1Name = the name of the first parameter if `fun` is a string.\n    Defaults to `\"a\"`.\n    parm2Name = the name of the second parameter if `fun` is a string.\n    Defaults to `\"b\"`.\nReturns:\n    If `fun` is not a string, `binaryFun` aliases itself away to\n    `fun`.\n*/\ntemplate binaryFun(alias fun, string parm1Name = \"a\",\n        string parm2Name = \"b\")\n{\n    static if (is(typeof(fun) : string))\n    {\n        static if (!fun._ctfeMatchBinary(parm1Name, parm2Name))\n        {\n            import std.algorithm, std.conv, std.exception, std.math, std.range, std.string;\n            import std.meta, std.traits, std.typecons;\n        }\n        auto binaryFun(ElementType1, ElementType2)\n            (auto ref ElementType1 __a, auto ref ElementType2 __b)\n        {\n            mixin(\"alias \"~parm1Name~\" = __a ;\");\n            mixin(\"alias \"~parm2Name~\" = __b ;\");\n            return mixin(fun);\n        }\n    }\n    else static if (needOpCallAlias!fun)\n    {\n        // Issue 9906\n        alias binaryFun = fun.opCall;\n    }\n    else\n    {\n        alias binaryFun = fun;\n    }\n}\n\n///\n@safe unittest\n{\n    alias less = binaryFun!(\"a < b\");\n    assert(less(1, 2) && !less(2, 1));\n    alias greater = binaryFun!(\"a > b\");\n    assert(!greater(\"1\", \"2\") && greater(\"2\", \"1\"));\n}\n\n@safe unittest\n{\n    static int f1(int a, string b) { return a + 1; }\n    static assert(is(typeof(binaryFun!(f1)(1, \"2\")) == int));\n    assert(binaryFun!(f1)(41, \"a\") == 42);\n    string f2(int a, string b) { return b ~ \"2\"; }\n    static assert(is(typeof(binaryFun!(f2)(1, \"1\")) == string));\n    assert(binaryFun!(f2)(1, \"4\") == \"42\");\n    assert(binaryFun!(\"a + b\")(41, 1) == 42);\n    //@@BUG\n    //assert(binaryFun!(\"return a + b;\")(41, 1) == 42);\n\n    // Issue 9906\n    struct Seen\n    {\n        static bool opCall(int x, int y) { return true; }\n    }\n    static assert(is(typeof(binaryFun!Seen)));\n    assert(binaryFun!Seen(1,1));\n\n    struct FuncObj\n    {\n        bool opCall(int x, int y) { return true; }\n    }\n    FuncObj fo;\n    static assert(!needOpCallAlias!fo);\n    static assert(is(typeof(binaryFun!fo)));\n    assert(unaryFun!fo(1,1));\n\n    // Function object with non-static opCall can only be called with an\n    // instance, not with merely the type.\n    static assert(!is(typeof(binaryFun!FuncObj)));\n}\n\n// skip all ASCII chars except a .. z, A .. Z, 0 .. 9, '_' and '.'.\nprivate uint _ctfeSkipOp(ref string op)\n{\n    if (!__ctfe) assert(false);\n    import std.ascii : isASCII, isAlphaNum;\n    immutable oldLength = op.length;\n    while (op.length)\n    {\n        immutable front = op[0];\n        if (front.isASCII() && !(front.isAlphaNum() || front == '_' || front == '.'))\n            op = op[1..$];\n        else\n            break;\n    }\n    return oldLength != op.length;\n}\n\n// skip all digits\nprivate uint _ctfeSkipInteger(ref string op)\n{\n    if (!__ctfe) assert(false);\n    import std.ascii : isDigit;\n    immutable oldLength = op.length;\n    while (op.length)\n    {\n        immutable front = op[0];\n        if (front.isDigit())\n            op = op[1..$];\n        else\n            break;\n    }\n    return oldLength != op.length;\n}\n\n// skip name\nprivate uint _ctfeSkipName(ref string op, string name)\n{\n    if (!__ctfe) assert(false);\n    if (op.length >= name.length && op[0 .. name.length] == name)\n    {\n        op = op[name.length..$];\n        return 1;\n    }\n    return 0;\n}\n\n// returns 1 if `fun` is trivial unary function\nprivate uint _ctfeMatchUnary(string fun, string name)\n{\n    if (!__ctfe) assert(false);\n    fun._ctfeSkipOp();\n    for (;;)\n    {\n        immutable h = fun._ctfeSkipName(name) + fun._ctfeSkipInteger();\n        if (h == 0)\n        {\n            fun._ctfeSkipOp();\n            break;\n        }\n        else if (h == 1)\n        {\n            if (!fun._ctfeSkipOp())\n                break;\n        }\n        else\n            return 0;\n    }\n    return fun.length == 0;\n}\n\n@safe unittest\n{\n    static assert(!_ctfeMatchUnary(\"sqrt(ё)\", \"ё\"));\n    static assert(!_ctfeMatchUnary(\"ё.sqrt\", \"ё\"));\n    static assert(!_ctfeMatchUnary(\".ё+ё\", \"ё\"));\n    static assert(!_ctfeMatchUnary(\"_ё+ё\", \"ё\"));\n    static assert(!_ctfeMatchUnary(\"ёё\", \"ё\"));\n    static assert(_ctfeMatchUnary(\"a+a\", \"a\"));\n    static assert(_ctfeMatchUnary(\"a + 10\", \"a\"));\n    static assert(_ctfeMatchUnary(\"4 == a\", \"a\"));\n    static assert(_ctfeMatchUnary(\"2 == a\", \"a\"));\n    static assert(_ctfeMatchUnary(\"1 != a\", \"a\"));\n    static assert(_ctfeMatchUnary(\"a != 4\", \"a\"));\n    static assert(_ctfeMatchUnary(\"a< 1\", \"a\"));\n    static assert(_ctfeMatchUnary(\"434 < a\", \"a\"));\n    static assert(_ctfeMatchUnary(\"132 > a\", \"a\"));\n    static assert(_ctfeMatchUnary(\"123 >a\", \"a\"));\n    static assert(_ctfeMatchUnary(\"a>82\", \"a\"));\n    static assert(_ctfeMatchUnary(\"ё>82\", \"ё\"));\n    static assert(_ctfeMatchUnary(\"ё[ё(ё)]\", \"ё\"));\n    static assert(_ctfeMatchUnary(\"ё[21]\", \"ё\"));\n}\n\n// returns 1 if `fun` is trivial binary function\nprivate uint _ctfeMatchBinary(string fun, string name1, string name2)\n{\n    if (!__ctfe) assert(false);\n    fun._ctfeSkipOp();\n    for (;;)\n    {\n        immutable h = fun._ctfeSkipName(name1) + fun._ctfeSkipName(name2) + fun._ctfeSkipInteger();\n        if (h == 0)\n        {\n            fun._ctfeSkipOp();\n            break;\n        }\n        else if (h == 1)\n        {\n            if (!fun._ctfeSkipOp())\n                break;\n        }\n        else\n            return 0;\n    }\n    return fun.length == 0;\n}\n\n@safe unittest\n{\n\n    static assert(!_ctfeMatchBinary(\"sqrt(ё)\", \"ё\", \"b\"));\n    static assert(!_ctfeMatchBinary(\"ё.sqrt\", \"ё\", \"b\"));\n    static assert(!_ctfeMatchBinary(\".ё+ё\", \"ё\", \"b\"));\n    static assert(!_ctfeMatchBinary(\"_ё+ё\", \"ё\", \"b\"));\n    static assert(!_ctfeMatchBinary(\"ёё\", \"ё\", \"b\"));\n    static assert(_ctfeMatchBinary(\"a+a\", \"a\", \"b\"));\n    static assert(_ctfeMatchBinary(\"a + 10\", \"a\", \"b\"));\n    static assert(_ctfeMatchBinary(\"4 == a\", \"a\", \"b\"));\n    static assert(_ctfeMatchBinary(\"2 == a\", \"a\", \"b\"));\n    static assert(_ctfeMatchBinary(\"1 != a\", \"a\", \"b\"));\n    static assert(_ctfeMatchBinary(\"a != 4\", \"a\", \"b\"));\n    static assert(_ctfeMatchBinary(\"a< 1\", \"a\", \"b\"));\n    static assert(_ctfeMatchBinary(\"434 < a\", \"a\", \"b\"));\n    static assert(_ctfeMatchBinary(\"132 > a\", \"a\", \"b\"));\n    static assert(_ctfeMatchBinary(\"123 >a\", \"a\", \"b\"));\n    static assert(_ctfeMatchBinary(\"a>82\", \"a\", \"b\"));\n    static assert(_ctfeMatchBinary(\"ё>82\", \"ё\", \"q\"));\n    static assert(_ctfeMatchBinary(\"ё[ё(10)]\", \"ё\", \"q\"));\n    static assert(_ctfeMatchBinary(\"ё[21]\", \"ё\", \"q\"));\n\n    static assert(!_ctfeMatchBinary(\"sqrt(ё)+b\", \"b\", \"ё\"));\n    static assert(!_ctfeMatchBinary(\"ё.sqrt-b\", \"b\", \"ё\"));\n    static assert(!_ctfeMatchBinary(\".ё+b\", \"b\", \"ё\"));\n    static assert(!_ctfeMatchBinary(\"_b+ё\", \"b\", \"ё\"));\n    static assert(!_ctfeMatchBinary(\"ba\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"a+b\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"a + b\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"b == a\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"b == a\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"b != a\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"a != b\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"a< b\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"b < a\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"b > a\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"b >a\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"a>b\", \"b\", \"a\"));\n    static assert(_ctfeMatchBinary(\"ё>b\", \"b\", \"ё\"));\n    static assert(_ctfeMatchBinary(\"b[ё(-1)]\", \"b\", \"ё\"));\n    static assert(_ctfeMatchBinary(\"ё[-21]\", \"b\", \"ё\"));\n}\n\n//undocumented\ntemplate safeOp(string S)\nif (S==\"<\"||S==\">\"||S==\"<=\"||S==\">=\"||S==\"==\"||S==\"!=\")\n{\n    import std.traits : isIntegral;\n    private bool unsafeOp(ElementType1, ElementType2)(ElementType1 a, ElementType2 b) pure\n        if (isIntegral!ElementType1 && isIntegral!ElementType2)\n    {\n        import std.traits : CommonType;\n        alias T = CommonType!(ElementType1, ElementType2);\n        return mixin(\"cast(T)a \"~S~\" cast(T) b\");\n    }\n\n    bool safeOp(T0, T1)(auto ref T0 a, auto ref T1 b)\n    {\n        import std.traits : mostNegative;\n        static if (isIntegral!T0 && isIntegral!T1 &&\n                   (mostNegative!T0 < 0) != (mostNegative!T1 < 0))\n        {\n            static if (S == \"<=\" || S == \"<\")\n            {\n                static if (mostNegative!T0 < 0)\n                    immutable result = a < 0 || unsafeOp(a, b);\n                else\n                    immutable result = b >= 0 && unsafeOp(a, b);\n            }\n            else\n            {\n                static if (mostNegative!T0 < 0)\n                    immutable result = a >= 0 && unsafeOp(a, b);\n                else\n                    immutable result = b < 0 || unsafeOp(a, b);\n            }\n        }\n        else\n        {\n            static assert(is(typeof(mixin(\"a \"~S~\" b\"))),\n                \"Invalid arguments: Cannot compare types \" ~ T0.stringof ~ \" and \" ~ T1.stringof ~ \".\");\n\n            immutable result = mixin(\"a \"~S~\" b\");\n        }\n        return result;\n    }\n}\n\n@safe unittest //check user defined types\n{\n    import std.algorithm.comparison : equal;\n    struct Foo\n    {\n        int a;\n        auto opEquals(Foo foo)\n        {\n            return a == foo.a;\n        }\n    }\n    assert(safeOp!\"!=\"(Foo(1), Foo(2)));\n}\n\n/**\n   Predicate that returns $(D_PARAM a < b).\n   Correctly compares signed and unsigned integers, ie. -1 < 2U.\n*/\nalias lessThan = safeOp!\"<\";\n\n///\npure @safe @nogc nothrow unittest\n{\n    assert(lessThan(2, 3));\n    assert(lessThan(2U, 3U));\n    assert(lessThan(2, 3.0));\n    assert(lessThan(-2, 3U));\n    assert(lessThan(2, 3U));\n    assert(!lessThan(3U, -2));\n    assert(!lessThan(3U, 2));\n    assert(!lessThan(0, 0));\n    assert(!lessThan(0U, 0));\n    assert(!lessThan(0, 0U));\n}\n\n/**\n   Predicate that returns $(D_PARAM a > b).\n   Correctly compares signed and unsigned integers, ie. 2U > -1.\n*/\nalias greaterThan = safeOp!\">\";\n\n///\n@safe unittest\n{\n    assert(!greaterThan(2, 3));\n    assert(!greaterThan(2U, 3U));\n    assert(!greaterThan(2, 3.0));\n    assert(!greaterThan(-2, 3U));\n    assert(!greaterThan(2, 3U));\n    assert(greaterThan(3U, -2));\n    assert(greaterThan(3U, 2));\n    assert(!greaterThan(0, 0));\n    assert(!greaterThan(0U, 0));\n    assert(!greaterThan(0, 0U));\n}\n\n/**\n   Predicate that returns $(D_PARAM a == b).\n   Correctly compares signed and unsigned integers, ie. !(-1 == ~0U).\n*/\nalias equalTo = safeOp!\"==\";\n\n///\n@safe unittest\n{\n    assert(equalTo(0U, 0));\n    assert(equalTo(0, 0U));\n    assert(!equalTo(-1, ~0U));\n}\n/**\nN-ary predicate that reverses the order of arguments, e.g., given\n$(D pred(a, b, c)), returns $(D pred(c, b, a)).\n\nParams:\n    pred = A callable\nReturns:\n    A function which calls `pred` after reversing the given parameters\n*/\ntemplate reverseArgs(alias pred)\n{\n    auto reverseArgs(Args...)(auto ref Args args)\n    if (is(typeof(pred(Reverse!args))))\n    {\n        return pred(Reverse!args);\n    }\n}\n\n///\n@safe unittest\n{\n    alias gt = reverseArgs!(binaryFun!(\"a < b\"));\n    assert(gt(2, 1) && !gt(1, 1));\n}\n\n///\n@safe unittest\n{\n    int x = 42;\n    bool xyz(int a, int b) { return a * x < b / x; }\n    auto foo = &xyz;\n    foo(4, 5);\n    alias zyx = reverseArgs!(foo);\n    assert(zyx(5, 4) == foo(4, 5));\n}\n\n///\n@safe unittest\n{\n    alias gt = reverseArgs!(binaryFun!(\"a < b\"));\n    assert(gt(2, 1) && !gt(1, 1));\n    int x = 42;\n    bool xyz(int a, int b) { return a * x < b / x; }\n    auto foo = &xyz;\n    foo(4, 5);\n    alias zyx = reverseArgs!(foo);\n    assert(zyx(5, 4) == foo(4, 5));\n}\n\n///\n@safe unittest\n{\n    int abc(int a, int b, int c) { return a * b + c; }\n    alias cba = reverseArgs!abc;\n    assert(abc(91, 17, 32) == cba(32, 17, 91));\n}\n\n///\n@safe unittest\n{\n    int a(int a) { return a * 2; }\n    alias _a = reverseArgs!a;\n    assert(a(2) == _a(2));\n}\n\n///\n@safe unittest\n{\n    int b() { return 4; }\n    alias _b = reverseArgs!b;\n    assert(b() == _b());\n}\n\n// @@@DEPRECATED_2.089@@@\n/**\nBinary predicate that reverses the order of arguments, e.g., given\n$(D pred(a, b)), returns $(D pred(b, a)).\n\n$(RED DEPRECATED: Use $(LREF reverseArgs))\n\nParams:\n    pred = A callable\nReturns:\n    A function which calls `pred` after reversing the given parameters\n*/\ndeprecated(\"Use `reverseArgs`. `binaryReverseArgs` will be removed in 2.089.\")\ntemplate binaryReverseArgs(alias pred)\n{\n    auto binaryReverseArgs(ElementType1, ElementType2)\n            (auto ref ElementType1 a, auto ref ElementType2 b)\n    {\n        return pred(b, a);\n    }\n}\n\n///\ndeprecated\n@safe unittest\n{\n    alias gt = binaryReverseArgs!(binaryFun!(\"a < b\"));\n    assert(gt(2, 1) && !gt(1, 1));\n}\n\n///\ndeprecated\n@safe unittest\n{\n    int x = 42;\n    bool xyz(int a, int b) { return a * x < b / x; }\n    auto foo = &xyz;\n    foo(4, 5);\n    alias zyx = binaryReverseArgs!(foo);\n    assert(zyx(5, 4) == foo(4, 5));\n}\n\n/**\nNegates predicate `pred`.\n\nParams:\n    pred = A string or a callable\nReturns:\n    A function which calls `pred` and returns the logical negation of its\n    return value.\n */\ntemplate not(alias pred)\n{\n    auto not(T...)(auto ref T args)\n    {\n        static if (is(typeof(!pred(args))))\n            return !pred(args);\n        else static if (T.length == 1)\n            return !unaryFun!pred(args);\n        else static if (T.length == 2)\n            return !binaryFun!pred(args);\n        else\n            static assert(0);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.searching : find;\n    import std.functional;\n    import std.uni : isWhite;\n    string a = \"   Hello, world!\";\n    assert(find!(not!isWhite)(a) == \"Hello, world!\");\n}\n\n@safe unittest\n{\n    assert(not!\"a != 5\"(5));\n    assert(not!\"a != b\"(5, 5));\n\n    assert(not!(() => false)());\n    assert(not!(a => a != 5)(5));\n    assert(not!((a, b) => a != b)(5, 5));\n    assert(not!((a, b, c) => a * b * c != 125 )(5, 5, 5));\n}\n\n/**\n$(LINK2 http://en.wikipedia.org/wiki/Partial_application, Partially\napplies) $(D_PARAM fun) by tying its first argument to $(D_PARAM arg).\n\nParams:\n    fun = A callable\n    arg = The first argument to apply to `fun`\nReturns:\n    A new function which calls `fun` with `arg` plus the passed parameters.\n */\ntemplate partial(alias fun, alias arg)\n{\n    import std.traits : isCallable;\n    // Check whether fun is a user defined type which implements opCall or a template.\n    // As opCall itself can be templated, std.traits.isCallable does not work here.\n    enum isSomeFunctor = (is(typeof(fun) == struct) || is(typeof(fun) == class)) && __traits(hasMember, fun, \"opCall\");\n    static if (isSomeFunctor || __traits(isTemplate, fun))\n    {\n        auto partial(Ts...)(Ts args2)\n        {\n            static if (is(typeof(fun(arg, args2))))\n            {\n                return fun(arg, args2);\n            }\n            else\n            {\n                static string errormsg()\n                {\n                    string msg = \"Cannot call '\" ~ fun.stringof ~ \"' with arguments \" ~\n                        \"(\" ~ arg.stringof;\n                    foreach (T; Ts)\n                        msg ~= \", \" ~ T.stringof;\n                    msg ~= \").\";\n                    return msg;\n                }\n                static assert(0, errormsg());\n            }\n        }\n    }\n    else static if (!isCallable!fun)\n    {\n        static assert(false, \"Cannot apply partial to a non-callable '\" ~ fun.stringof ~ \"'.\");\n    }\n    else // Assume fun is callable and uniquely defined.\n    {\n        static if (Parameters!fun.length == 0)\n        {\n            static assert(0, \"Cannot partially apply '\" ~ fun.stringof ~ \"'.\" ~\n                \"'\" ~ fun.stringof ~ \"' has 0 arguments.\");\n        }\n        else static if (!is(typeof(arg) : Parameters!fun[0]))\n        {\n            string errorMsg()\n            {\n                string msg = \"Argument mismatch for '\" ~ fun.stringof ~ \"': expected \" ~\n                    Parameters!fun[0].stringof ~ \", but got \" ~ typeof(arg).stringof ~ \".\";\n                return msg;\n            }\n            static assert(0, errorMsg());\n        }\n        else\n        {\n            import std.traits : ReturnType;\n            ReturnType!fun partial(Parameters!fun[1..$] args2)\n            {\n                return fun(arg, args2);\n            }\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    int fun(int a, int b) { return a + b; }\n    alias fun5 = partial!(fun, 5);\n    assert(fun5(6) == 11);\n    // Note that in most cases you'd use an alias instead of a value\n    // assignment. Using an alias allows you to partially evaluate template\n    // functions without committing to a particular type of the function.\n}\n\n// tests for partially evaluating callables\n@safe unittest\n{\n    static int f1(int a, int b) { return a + b; }\n    assert(partial!(f1, 5)(6) == 11);\n\n    int f2(int a, int b) { return a + b; }\n    int x = 5;\n    assert(partial!(f2, x)(6) == 11);\n    x = 7;\n    assert(partial!(f2, x)(6) == 13);\n    static assert(partial!(f2, 5)(6) == 11);\n\n    auto dg = &f2;\n    auto f3 = &partial!(dg, x);\n    assert(f3(6) == 13);\n\n    static int funOneArg(int a) { return a; }\n    assert(partial!(funOneArg, 1)() == 1);\n\n    static int funThreeArgs(int a, int b, int c) { return a + b + c; }\n    alias funThreeArgs1 = partial!(funThreeArgs, 1);\n    assert(funThreeArgs1(2, 3) == 6);\n    static assert(!is(typeof(funThreeArgs1(2))));\n\n    enum xe = 5;\n    alias fe = partial!(f2, xe);\n    static assert(fe(6) == 11);\n}\n\n// tests for partially evaluating templated/overloaded callables\n@safe unittest\n{\n    static auto add(A, B)(A x, B y)\n    {\n        return x + y;\n    }\n\n    alias add5 = partial!(add, 5);\n    assert(add5(6) == 11);\n    static assert(!is(typeof(add5())));\n    static assert(!is(typeof(add5(6, 7))));\n\n    // taking address of templated partial evaluation needs explicit type\n    auto dg = &add5!(int);\n    assert(dg(6) == 11);\n\n    int x = 5;\n    alias addX = partial!(add, x);\n    assert(addX(6) == 11);\n\n    static struct Callable\n    {\n        static string opCall(string a, string b) { return a ~ b; }\n        int opCall(int a, int b) { return a * b; }\n        double opCall(double a, double b) { return a + b; }\n    }\n    Callable callable;\n    assert(partial!(Callable, \"5\")(\"6\") == \"56\");\n    assert(partial!(callable, 5)(6) == 30);\n    assert(partial!(callable, 7.0)(3.0) == 7.0 + 3.0);\n\n    static struct TCallable\n    {\n        auto opCall(A, B)(A a, B b)\n        {\n            return a + b;\n        }\n    }\n    TCallable tcallable;\n    assert(partial!(tcallable, 5)(6) == 11);\n    static assert(!is(typeof(partial!(tcallable, \"5\")(6))));\n\n    static struct NonCallable{}\n    static assert(!__traits(compiles, partial!(NonCallable, 5)), \"Partial should not work on non-callable structs.\");\n    static assert(!__traits(compiles, partial!(NonCallable.init, 5)),\n        \"Partial should not work on instances of non-callable structs.\");\n\n    static A funOneArg(A)(A a) { return a; }\n    alias funOneArg1 = partial!(funOneArg, 1);\n    assert(funOneArg1() == 1);\n\n    static auto funThreeArgs(A, B, C)(A a, B b, C c) { return a + b + c; }\n    alias funThreeArgs1 = partial!(funThreeArgs, 1);\n    assert(funThreeArgs1(2, 3) == 6);\n    static assert(!is(typeof(funThreeArgs1(1))));\n\n    auto dg2 = &funOneArg1!();\n    assert(dg2() == 1);\n}\n\n// Fix issue 15732\n@safe unittest\n{\n    // Test whether it works with functions.\n    auto partialFunction(){\n        auto fullFunction = (float a, float b, float c) => a + b / c;\n        alias apply1 = partial!(fullFunction, 1);\n        return &apply1;\n    }\n    auto result = partialFunction()(2, 4);\n    assert(result == 1.5f);\n\n    // And with delegates.\n    auto partialDelegate(float c){\n        auto fullDelegate = (float a, float b) => a + b / c;\n        alias apply1 = partial!(fullDelegate, 1);\n        return &apply1;\n    }\n    auto result2 = partialDelegate(4)(2);\n    assert(result2 == 1.5f);\n}\n\n/**\nTakes multiple functions and adjoins them together.\n\nParams:\n    F = the call-able(s) to adjoin\nReturns:\n    A new function which returns a $(REF Tuple, std,typecons). Each of the\n    elements of the tuple will be the return values of `F`.\n\nNote: In the special case where only a single function is provided\n($(D F.length == 1)), adjoin simply aliases to the single passed function\n(`F[0]`).\n*/\ntemplate adjoin(F...)\nif (F.length == 1)\n{\n    alias adjoin = F[0];\n}\n/// ditto\ntemplate adjoin(F...)\nif (F.length > 1)\n{\n    auto adjoin(V...)(auto ref V a)\n    {\n        import std.typecons : tuple;\n        static if (F.length == 2)\n        {\n            return tuple(F[0](a), F[1](a));\n        }\n        else static if (F.length == 3)\n        {\n            return tuple(F[0](a), F[1](a), F[2](a));\n        }\n        else\n        {\n            import std.format : format;\n            import std.range : iota;\n            return mixin (q{tuple(%(F[%s](a)%|, %))}.format(iota(0, F.length)));\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    import std.functional, std.typecons : Tuple;\n    static bool f1(int a) { return a != 0; }\n    static int f2(int a) { return a / 2; }\n    auto x = adjoin!(f1, f2)(5);\n    assert(is(typeof(x) == Tuple!(bool, int)));\n    assert(x[0] == true && x[1] == 2);\n}\n\n@safe unittest\n{\n    import std.typecons : Tuple;\n    static bool F1(int a) { return a != 0; }\n    auto x1 = adjoin!(F1)(5);\n    static int F2(int a) { return a / 2; }\n    auto x2 = adjoin!(F1, F2)(5);\n    assert(is(typeof(x2) == Tuple!(bool, int)));\n    assert(x2[0] && x2[1] == 2);\n    auto x3 = adjoin!(F1, F2, F2)(5);\n    assert(is(typeof(x3) == Tuple!(bool, int, int)));\n    assert(x3[0] && x3[1] == 2 && x3[2] == 2);\n\n    bool F4(int a) { return a != x1; }\n    alias eff4 = adjoin!(F4);\n    static struct S\n    {\n        bool delegate(int) @safe store;\n        int fun() { return 42 + store(5); }\n    }\n    S s;\n    s.store = (int a) { return eff4(a); };\n    auto x4 = s.fun();\n    assert(x4 == 43);\n}\n\n@safe unittest\n{\n    import std.meta : staticMap;\n    import std.typecons : Tuple, tuple;\n    alias funs = staticMap!(unaryFun, \"a\", \"a * 2\", \"a * 3\", \"a * a\", \"-a\");\n    alias afun = adjoin!funs;\n    assert(afun(5) == tuple(5, 10, 15, 25, -5));\n\n    static class C{}\n    alias IC = immutable(C);\n    IC foo(){return typeof(return).init;}\n    Tuple!(IC, IC, IC, IC) ret1 = adjoin!(foo, foo, foo, foo)();\n\n    static struct S{int* p;}\n    alias IS = immutable(S);\n    IS bar(){return typeof(return).init;}\n    enum Tuple!(IS, IS, IS, IS) ret2 = adjoin!(bar, bar, bar, bar)();\n}\n\n/**\n   Composes passed-in functions $(D fun[0], fun[1], ...).\n\n   Params:\n        fun = the call-able(s) or `string`(s) to compose into one function\n    Returns:\n        A new function `f(x)` that in turn returns $(D fun[0](fun[1](...(x)))...).\n\n   See_Also: $(LREF pipe)\n*/\ntemplate compose(fun...)\n{\n    static if (fun.length == 1)\n    {\n        alias compose = unaryFun!(fun[0]);\n    }\n    else static if (fun.length == 2)\n    {\n        // starch\n        alias fun0 = unaryFun!(fun[0]);\n        alias fun1 = unaryFun!(fun[1]);\n\n        // protein: the core composition operation\n        typeof({ E a; return fun0(fun1(a)); }()) compose(E)(E a)\n        {\n            return fun0(fun1(a));\n        }\n    }\n    else\n    {\n        // protein: assembling operations\n        alias compose = compose!(fun[0], compose!(fun[1 .. $]));\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    import std.array : split;\n    import std.conv : to;\n\n    // First split a string in whitespace-separated tokens and then\n    // convert each token into an integer\n    assert(compose!(map!(to!(int)), split)(\"1 2 3\").equal([1, 2, 3]));\n}\n\n/**\n   Pipes functions in sequence. Offers the same functionality as $(D\n   compose), but with functions specified in reverse order. This may\n   lead to more readable code in some situation because the order of\n   execution is the same as lexical order.\n\n   Params:\n        fun = the call-able(s) or `string`(s) to compose into one function\n    Returns:\n        A new function `f(x)` that in turn returns $(D fun[0](fun[1](...(x)))...).\n\n   Example:\n\n----\n// Read an entire text file, split the resulting string in\n// whitespace-separated tokens, and then convert each token into an\n// integer\nint[] a = pipe!(readText, split, map!(to!(int)))(\"file.txt\");\n----\n\n   See_Also: $(LREF compose)\n */\nalias pipe(fun...) = compose!(Reverse!(fun));\n\n///\n@safe unittest\n{\n    import std.conv : to;\n    string foo(int a) { return to!(string)(a); }\n    int bar(string a) { return to!(int)(a) + 1; }\n    double baz(int a) { return a + 0.5; }\n    assert(compose!(baz, bar, foo)(1) == 2.5);\n    assert(pipe!(foo, bar, baz)(1) == 2.5);\n\n    assert(compose!(baz, `to!(int)(a) + 1`, foo)(1) == 2.5);\n    assert(compose!(baz, bar)(\"1\"[]) == 2.5);\n\n    assert(compose!(baz, bar)(\"1\") == 2.5);\n\n    assert(compose!(`a + 0.5`, `to!(int)(a) + 1`, foo)(1) == 2.5);\n}\n\n/**\n * $(LINK2 https://en.wikipedia.org/wiki/Memoization, Memoizes) a function so as\n * to avoid repeated computation. The memoization structure is a hash table keyed by a\n * tuple of the function's arguments. There is a speed gain if the\n * function is repeatedly called with the same arguments and is more\n * expensive than a hash table lookup. For more information on memoization, refer to $(HTTP docs.google.com/viewer?url=http%3A%2F%2Fhop.perl.plover.com%2Fbook%2Fpdf%2F03CachingAndMemoization.pdf, this book chapter).\n\nExample:\n----\ndouble transmogrify(int a, string b)\n{\n   ... expensive computation ...\n}\nalias fastTransmogrify = memoize!transmogrify;\nunittest\n{\n    auto slow = transmogrify(2, \"hello\");\n    auto fast = fastTransmogrify(2, \"hello\");\n    assert(slow == fast);\n}\n----\n\nParams:\n    fun = the call-able to memozie\n    maxSize = The maximum size of the GC buffer to hold the return values\nReturns:\n    A new function which calls `fun` and caches its return values.\n\nNote:\n    Technically the memoized function should be pure because `memoize` assumes it will\n    always return the same result for a given tuple of arguments. However, `memoize` does not\n    enforce that because sometimes it is useful to memoize an impure function, too.\n*/\ntemplate memoize(alias fun)\n{\n    import std.traits : ReturnType;\n    // alias Args = Parameters!fun; // Bugzilla 13580\n\n    ReturnType!fun memoize(Parameters!fun args)\n    {\n        alias Args = Parameters!fun;\n        import std.typecons : Tuple;\n\n        static ReturnType!fun[Tuple!Args] memo;\n        auto t = Tuple!Args(args);\n        if (auto p = t in memo)\n            return *p;\n        return memo[t] = fun(args);\n    }\n}\n\n/// ditto\ntemplate memoize(alias fun, uint maxSize)\n{\n    import std.traits : ReturnType;\n    // alias Args = Parameters!fun; // Bugzilla 13580\n    ReturnType!fun memoize(Parameters!fun args)\n    {\n        import std.traits : hasIndirections;\n        import std.typecons : tuple;\n        static struct Value { Parameters!fun args; ReturnType!fun res; }\n        static Value[] memo;\n        static size_t[] initialized;\n\n        if (!memo.length)\n        {\n            import core.memory : GC;\n\n            // Ensure no allocation overflows\n            static assert(maxSize < size_t.max / Value.sizeof);\n            static assert(maxSize < size_t.max - (8 * size_t.sizeof - 1));\n\n            enum attr = GC.BlkAttr.NO_INTERIOR | (hasIndirections!Value ? 0 : GC.BlkAttr.NO_SCAN);\n            memo = (cast(Value*) GC.malloc(Value.sizeof * maxSize, attr))[0 .. maxSize];\n            enum nwords = (maxSize + 8 * size_t.sizeof - 1) / (8 * size_t.sizeof);\n            initialized = (cast(size_t*) GC.calloc(nwords * size_t.sizeof, attr | GC.BlkAttr.NO_SCAN))[0 .. nwords];\n        }\n\n        import core.bitop : bt, bts;\n        import std.conv : emplace;\n\n        size_t hash;\n        foreach (ref arg; args)\n            hash = hashOf(arg, hash);\n        // cuckoo hashing\n        immutable idx1 = hash % maxSize;\n        if (!bt(initialized.ptr, idx1))\n        {\n            emplace(&memo[idx1], args, fun(args));\n            bts(initialized.ptr, idx1); // only set to initialized after setting args and value (bugzilla 14025)\n            return memo[idx1].res;\n        }\n        else if (memo[idx1].args == args)\n            return memo[idx1].res;\n        // FNV prime\n        immutable idx2 = (hash * 16_777_619) % maxSize;\n        if (!bt(initialized.ptr, idx2))\n        {\n            emplace(&memo[idx2], memo[idx1]);\n            bts(initialized.ptr, idx2); // only set to initialized after setting args and value (bugzilla 14025)\n        }\n        else if (memo[idx2].args == args)\n            return memo[idx2].res;\n        else if (idx1 != idx2)\n            memo[idx2] = memo[idx1];\n\n        memo[idx1] = Value(args, fun(args));\n        return memo[idx1].res;\n    }\n}\n\n/**\n * To _memoize a recursive function, simply insert the memoized call in lieu of the plain recursive call.\n * For example, to transform the exponential-time Fibonacci implementation into a linear-time computation:\n */\n@safe unittest\n{\n    ulong fib(ulong n) @safe\n    {\n        return n < 2 ? n : memoize!fib(n - 2) + memoize!fib(n - 1);\n    }\n    assert(fib(10) == 55);\n}\n\n/**\n * To improve the speed of the factorial function,\n */\n@safe unittest\n{\n    ulong fact(ulong n) @safe\n    {\n        return n < 2 ? 1 : n * memoize!fact(n - 1);\n    }\n    assert(fact(10) == 3628800);\n}\n\n/**\n * This memoizes all values of `fact` up to the largest argument. To only cache the final\n * result, move `memoize` outside the function as shown below.\n */\n@safe unittest\n{\n    ulong factImpl(ulong n) @safe\n    {\n        return n < 2 ? 1 : n * factImpl(n - 1);\n    }\n    alias fact = memoize!factImpl;\n    assert(fact(10) == 3628800);\n}\n\n/**\n * When the `maxSize` parameter is specified, memoize will used\n * a fixed size hash table to limit the number of cached entries.\n */\n@system unittest // not @safe due to memoize\n{\n    ulong fact(ulong n)\n    {\n        // Memoize no more than 8 values\n        return n < 2 ? 1 : n * memoize!(fact, 8)(n - 1);\n    }\n    assert(fact(8) == 40320);\n    // using more entries than maxSize will overwrite existing entries\n    assert(fact(10) == 3628800);\n}\n\n@system unittest // not @safe due to memoize\n{\n    import core.math : sqrt;\n    alias msqrt = memoize!(function double(double x) { return sqrt(x); });\n    auto y = msqrt(2.0);\n    assert(y == msqrt(2.0));\n    y = msqrt(4.0);\n    assert(y == sqrt(4.0));\n\n    // alias mrgb2cmyk = memoize!rgb2cmyk;\n    // auto z = mrgb2cmyk([43, 56, 76]);\n    // assert(z == mrgb2cmyk([43, 56, 76]));\n\n    //alias mfib = memoize!fib;\n\n    static ulong fib(ulong n) @safe\n    {\n        alias mfib = memoize!fib;\n        return n < 2 ? 1 : mfib(n - 2) + mfib(n - 1);\n    }\n\n    auto z = fib(10);\n    assert(z == 89);\n\n    static ulong fact(ulong n) @safe\n    {\n        alias mfact = memoize!fact;\n        return n < 2 ? 1 : n * mfact(n - 1);\n    }\n    assert(fact(10) == 3628800);\n\n    // Issue 12568\n    static uint len2(const string s) { // Error\n    alias mLen2 = memoize!len2;\n    if (s.length == 0)\n        return 0;\n    else\n        return 1 + mLen2(s[1 .. $]);\n    }\n\n    int _func(int x) @safe { return 1; }\n    alias func = memoize!(_func, 10);\n    assert(func(int.init) == 1);\n    assert(func(int.init) == 1);\n}\n\n// 16079: memoize should work with arrays\n@system unittest // not @safe with -dip1000 due to memoize\n{\n    int executed = 0;\n    T median(T)(const T[] nums) {\n        import std.algorithm.sorting : sort;\n        executed++;\n        auto arr = nums.dup;\n        arr.sort();\n        if (arr.length % 2)\n            return arr[$ / 2];\n        else\n            return (arr[$ / 2 - 1]\n                + arr[$ / 2]) / 2;\n    }\n\n    alias fastMedian = memoize!(median!int);\n\n    assert(fastMedian([7, 5, 3]) == 5);\n    assert(fastMedian([7, 5, 3]) == 5);\n\n    assert(executed == 1);\n}\n\n// 16079: memoize should work with structs\n@safe unittest\n{\n    int executed = 0;\n    T pickFirst(T)(T first)\n    {\n        executed++;\n        return first;\n    }\n\n    struct Foo { int k; }\n    Foo A = Foo(3);\n\n    alias first = memoize!(pickFirst!Foo);\n    assert(first(Foo(3)) == A);\n    assert(first(Foo(3)) == A);\n    assert(executed == 1);\n}\n\n// 16079: memoize should work with classes\n@system unittest // not @safe with -dip1000 due to memoize\n{\n    int executed = 0;\n    T pickFirst(T)(T first)\n    {\n        executed++;\n        return first;\n    }\n\n    class Bar\n    {\n        size_t k;\n        this(size_t k)\n        {\n            this.k = k;\n        }\n        override size_t toHash()\n        {\n            return k;\n        }\n        override bool opEquals(Object o)\n        {\n            auto b = cast(Bar) o;\n            return b && k == b.k;\n        }\n    }\n\n    alias firstClass = memoize!(pickFirst!Bar);\n    assert(firstClass(new Bar(3)).k == 3);\n    assert(firstClass(new Bar(3)).k == 3);\n    assert(executed == 1);\n}\n\nprivate struct DelegateFaker(F)\n{\n    import std.typecons : FuncInfo, MemberFunctionGenerator;\n\n    // for @safe\n    static F castToF(THIS)(THIS x) @trusted\n    {\n        return cast(F) x;\n    }\n\n    /*\n     * What all the stuff below does is this:\n     *--------------------\n     * struct DelegateFaker(F) {\n     *     extern(linkage)\n     *     [ref] ReturnType!F doIt(Parameters!F args) [@attributes]\n     *     {\n     *         auto fp = cast(F) &this;\n     *         return fp(args);\n     *     }\n     * }\n     *--------------------\n     */\n\n    // We will use MemberFunctionGenerator in std.typecons.  This is a policy\n    // configuration for generating the doIt().\n    template GeneratingPolicy()\n    {\n        // Inform the genereator that we only have type information.\n        enum WITHOUT_SYMBOL = true;\n\n        // Generate the function body of doIt().\n        template generateFunctionBody(unused...)\n        {\n            enum generateFunctionBody =\n            // [ref] ReturnType doIt(Parameters args) @attributes\n            q{\n                // When this function gets called, the this pointer isn't\n                // really a this pointer (no instance even really exists), but\n                // a function pointer that points to the function to be called.\n                // Cast it to the correct type and call it.\n\n                auto fp = castToF(&this);\n                return fp(args);\n            };\n        }\n    }\n    // Type information used by the generated code.\n    alias FuncInfo_doIt = FuncInfo!(F);\n\n    // Generate the member function doIt().\n    mixin( MemberFunctionGenerator!(GeneratingPolicy!())\n            .generateFunction!(\"FuncInfo_doIt\", \"doIt\", F) );\n}\n\n/**\n * Convert a callable to a delegate with the same parameter list and\n * return type, avoiding heap allocations and use of auxiliary storage.\n *\n * Params:\n *     fp = a function pointer or an aggregate type with `opCall` defined.\n * Returns:\n *     A delegate with the context pointer pointing to nothing.\n *\n * Example:\n * ----\n * void doStuff() {\n *     writeln(\"Hello, world.\");\n * }\n *\n * void runDelegate(void delegate() myDelegate) {\n *     myDelegate();\n * }\n *\n * auto delegateToPass = toDelegate(&doStuff);\n * runDelegate(delegateToPass);  // Calls doStuff, prints \"Hello, world.\"\n * ----\n *\n * BUGS:\n * $(UL\n *   $(LI Does not work with `@safe` functions.)\n *   $(LI Ignores C-style / D-style variadic arguments.)\n * )\n */\nauto toDelegate(F)(auto ref F fp)\nif (isCallable!(F))\n{\n    static if (is(F == delegate))\n    {\n        return fp;\n    }\n    else static if (is(typeof(&F.opCall) == delegate)\n                || (is(typeof(&F.opCall) V : V*) && is(V == function)))\n    {\n        return toDelegate(&fp.opCall);\n    }\n    else\n    {\n        alias DelType = typeof(&(new DelegateFaker!(F)).doIt);\n\n        static struct DelegateFields {\n            union {\n                DelType del;\n                //pragma(msg, typeof(del));\n\n                struct {\n                    void* contextPtr;\n                    void* funcPtr;\n                }\n            }\n        }\n\n        // fp is stored in the returned delegate's context pointer.\n        // The returned delegate's function pointer points to\n        // DelegateFaker.doIt.\n        DelegateFields df;\n\n        df.contextPtr = cast(void*) fp;\n\n        DelegateFaker!(F) dummy;\n        auto dummyDel = &dummy.doIt;\n        df.funcPtr = dummyDel.funcptr;\n\n        return df.del;\n    }\n}\n\n///\n@system unittest\n{\n    static int inc(ref uint num) {\n        num++;\n        return 8675309;\n    }\n\n    uint myNum = 0;\n    auto incMyNumDel = toDelegate(&inc);\n    auto returnVal = incMyNumDel(myNum);\n    assert(myNum == 1);\n}\n\n@system unittest // not @safe due to toDelegate\n{\n    static int inc(ref uint num) {\n        num++;\n        return 8675309;\n    }\n\n    uint myNum = 0;\n    auto incMyNumDel = toDelegate(&inc);\n    int delegate(ref uint) dg = incMyNumDel;\n    auto returnVal = incMyNumDel(myNum);\n    assert(myNum == 1);\n\n    interface I { int opCall(); }\n    class C: I { int opCall() { inc(myNum); return myNum;} }\n    auto c = new C;\n    auto i = cast(I) c;\n\n    auto getvalc = toDelegate(c);\n    assert(getvalc() == 2);\n\n    auto getvali = toDelegate(i);\n    assert(getvali() == 3);\n\n    struct S1 { int opCall() { inc(myNum); return myNum; } }\n    static assert(!is(typeof(&s1.opCall) == delegate));\n    S1 s1;\n    auto getvals1 = toDelegate(s1);\n    assert(getvals1() == 4);\n\n    struct S2 { static int opCall() { return 123456; } }\n    static assert(!is(typeof(&S2.opCall) == delegate));\n    S2 s2;\n    auto getvals2 =&S2.opCall;\n    assert(getvals2() == 123456);\n\n    /* test for attributes */\n    {\n        static int refvar = 0xDeadFace;\n\n        static ref int func_ref() { return refvar; }\n        static int func_pure() pure { return 1; }\n        static int func_nothrow() nothrow { return 2; }\n        static int func_property() @property { return 3; }\n        static int func_safe() @safe { return 4; }\n        static int func_trusted() @trusted { return 5; }\n        static int func_system() @system { return 6; }\n        static int func_pure_nothrow() pure nothrow { return 7; }\n        static int func_pure_nothrow_safe() pure nothrow @safe { return 8; }\n\n        auto dg_ref = toDelegate(&func_ref);\n        int delegate() pure dg_pure = toDelegate(&func_pure);\n        int delegate() nothrow dg_nothrow = toDelegate(&func_nothrow);\n        int delegate() @property dg_property = toDelegate(&func_property);\n        int delegate() @safe dg_safe = toDelegate(&func_safe);\n        int delegate() @trusted dg_trusted = toDelegate(&func_trusted);\n        int delegate() @system dg_system = toDelegate(&func_system);\n        int delegate() pure nothrow dg_pure_nothrow = toDelegate(&func_pure_nothrow);\n        int delegate() @safe pure nothrow dg_pure_nothrow_safe = toDelegate(&func_pure_nothrow_safe);\n\n        //static assert(is(typeof(dg_ref) == ref int delegate())); // [BUG@DMD]\n\n        assert(dg_ref() == refvar);\n        assert(dg_pure() == 1);\n        assert(dg_nothrow() == 2);\n        assert(dg_property() == 3);\n        assert(dg_safe() == 4);\n        assert(dg_trusted() == 5);\n        assert(dg_system() == 6);\n        assert(dg_pure_nothrow() == 7);\n        assert(dg_pure_nothrow_safe() == 8);\n    }\n    /* test for linkage */\n    {\n        struct S\n        {\n            extern(C) static void xtrnC() {}\n            extern(D) static void xtrnD() {}\n        }\n        auto dg_xtrnC = toDelegate(&S.xtrnC);\n        auto dg_xtrnD = toDelegate(&S.xtrnD);\n        static assert(! is(typeof(dg_xtrnC) == typeof(dg_xtrnD)));\n    }\n}\n\n/**\nForwards function arguments while keeping `out`, `ref`, and `lazy` on\nthe parameters.\n\nParams:\n    args = a parameter list or an $(REF AliasSeq,std,meta).\nReturns:\n    An `AliasSeq` of `args` with `out`, `ref`, and `lazy` saved.\n*/\ntemplate forward(args...)\n{\n    static if (args.length)\n    {\n        import std.algorithm.mutation : move;\n\n        alias arg = args[0];\n        // by ref || lazy || const/immutable\n        static if (__traits(isRef,  arg) ||\n                   __traits(isOut,  arg) ||\n                   __traits(isLazy, arg) ||\n                   !is(typeof(move(arg))))\n            alias fwd = arg;\n        // (r)value\n        else\n            @property auto fwd(){ return move(arg); }\n\n        static if (args.length == 1)\n            alias forward = fwd;\n        else\n            alias forward = AliasSeq!(fwd, forward!(args[1..$]));\n    }\n    else\n        alias forward = AliasSeq!();\n}\n\n///\n@safe unittest\n{\n    class C\n    {\n        static int foo(int n) { return 1; }\n        static int foo(ref int n) { return 2; }\n    }\n\n    // with forward\n    int bar()(auto ref int x) { return C.foo(forward!x); }\n\n    // without forward\n    int baz()(auto ref int x) { return C.foo(x); }\n\n    int i;\n    assert(bar(1) == 1);\n    assert(bar(i) == 2);\n\n    assert(baz(1) == 2);\n    assert(baz(i) == 2);\n}\n\n///\n@safe unittest\n{\n    void foo(int n, ref string s) { s = null; foreach (i; 0 .. n) s ~= \"Hello\"; }\n\n    // forwards all arguments which are bound to parameter tuple\n    void bar(Args...)(auto ref Args args) { return foo(forward!args); }\n\n    // forwards all arguments with swapping order\n    void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }\n\n    string s;\n    bar(1, s);\n    assert(s == \"Hello\");\n    baz(s, 2);\n    assert(s == \"HelloHello\");\n}\n\n@safe unittest\n{\n    auto foo(TL...)(auto ref TL args)\n    {\n        string result = \"\";\n        foreach (i, _; args)\n        {\n            //pragma(msg, \"[\",i,\"] \", __traits(isRef, args[i]) ? \"L\" : \"R\");\n            result ~= __traits(isRef, args[i]) ? \"L\" : \"R\";\n        }\n        return result;\n    }\n\n    string bar(TL...)(auto ref TL args)\n    {\n        return foo(forward!args);\n    }\n    string baz(TL...)(auto ref TL args)\n    {\n        int x;\n        return foo(forward!args[3], forward!args[2], 1, forward!args[1], forward!args[0], x);\n    }\n\n    struct S {}\n    S makeS(){ return S(); }\n    int n;\n    string s;\n    assert(bar(S(), makeS(), n, s) == \"RRLL\");\n    assert(baz(S(), makeS(), n, s) == \"LLRRRL\");\n}\n\n@safe unittest\n{\n    ref int foo(return ref int a) { return a; }\n    ref int bar(Args)(auto ref Args args)\n    {\n        return foo(forward!args);\n    }\n    static assert(!__traits(compiles, { auto x1 = bar(3); })); // case of NG\n    int value = 3;\n    auto x2 = bar(value); // case of OK\n}\n\n///\n@safe unittest\n{\n    struct X {\n        int i;\n        this(this)\n        {\n            ++i;\n        }\n    }\n\n    struct Y\n    {\n        private X x_;\n        this()(auto ref X x)\n        {\n            x_ = forward!x;\n        }\n    }\n\n    struct Z\n    {\n        private const X x_;\n        this()(auto ref X x)\n        {\n            x_ = forward!x;\n        }\n        this()(auto const ref X x)\n        {\n            x_ = forward!x;\n        }\n    }\n\n    X x;\n    const X cx;\n    auto constX = (){ const X x; return x; };\n    static assert(__traits(compiles, { Y y = x; }));\n    static assert(__traits(compiles, { Y y = X(); }));\n    static assert(!__traits(compiles, { Y y = cx; }));\n    static assert(!__traits(compiles, { Y y = constX(); }));\n    static assert(__traits(compiles, { Z z = x; }));\n    static assert(__traits(compiles, { Z z = X(); }));\n    static assert(__traits(compiles, { Z z = cx; }));\n    static assert(__traits(compiles, { Z z = constX(); }));\n\n\n    Y y1 = x;\n    // ref lvalue, copy\n    assert(y1.x_.i == 1);\n    Y y2 = X();\n    // rvalue, move\n    assert(y2.x_.i == 0);\n\n    Z z1 = x;\n    // ref lvalue, copy\n    assert(z1.x_.i == 1);\n    Z z2 = X();\n    // rvalue, move\n    assert(z2.x_.i == 0);\n    Z z3 = cx;\n    // ref const lvalue, copy\n    assert(z3.x_.i == 1);\n    Z z4 = constX();\n    // const rvalue, copy\n    assert(z4.x_.i == 1);\n}\n\n// lazy -> lazy\n@safe unittest\n{\n    int foo1(lazy int i) { return i; }\n    int foo2(A)(auto ref A i) { return foo1(forward!i); }\n    int foo3(lazy int i) { return foo2(i); }\n\n    int numCalls = 0;\n    assert(foo3({ ++numCalls; return 42; }()) == 42);\n    assert(numCalls == 1);\n}\n\n// lazy -> non-lazy\n@safe unittest\n{\n    int foo1(int a, int b) { return a + b; }\n    int foo2(A...)(auto ref A args) { return foo1(forward!args); }\n    int foo3(int a, lazy int b) { return foo2(a, b); }\n\n    int numCalls;\n    assert(foo3(11, { ++numCalls; return 31; }()) == 42);\n    assert(numCalls == 1);\n}\n\n// non-lazy -> lazy\n@safe unittest\n{\n    int foo1(int a, lazy int b) { return a + b; }\n    int foo2(A...)(auto ref A args) { return foo1(forward!args); }\n    int foo3(int a, int b) { return foo2(a, b); }\n\n    assert(foo3(11, 31) == 42);\n}\n\n// out\n@safe unittest\n{\n    void foo1(int a, out int b) { b = a; }\n    void foo2(A...)(auto ref A args) { foo1(forward!args); }\n    void foo3(int a, out int b) { foo2(a, b); }\n\n    int b;\n    foo3(42, b);\n    assert(b == 42);\n}\n"
  },
  {
    "path": "libphobos/src/std/getopt.d",
    "content": "// Written in the D programming language.\n\n/**\nProcessing of command line options.\n\nThe getopt module implements a `getopt` function, which adheres to\nthe POSIX syntax for command line options. GNU extensions are\nsupported in the form of long options introduced by a double dash\n(\"--\"). Support for bundling of command line options, as was the case\nwith the more traditional single-letter approach, is provided but not\nenabled by default.\n\nCopyright: Copyright Andrei Alexandrescu 2008 - 2015.\nLicense:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   $(HTTP erdani.org, Andrei Alexandrescu)\nCredits:   This module and its documentation are inspired by Perl's $(HTTP\n           perldoc.perl.org/Getopt/Long.html, Getopt::Long) module. The syntax of\n           D's `getopt` is simpler than its Perl counterpart because $(D\n           getopt) infers the expected parameter types from the static types of\n           the passed-in pointers.\nSource:    $(PHOBOSSRC std/getopt.d)\n*/\n/*\n         Copyright Andrei Alexandrescu 2008 - 2015.\nDistributed under the Boost Software License, Version 1.0.\n   (See accompanying file LICENSE_1_0.txt or copy at\n         http://www.boost.org/LICENSE_1_0.txt)\n*/\nmodule std.getopt;\n\nimport std.exception;  // basicExceptionCtors\nimport std.traits;\n\n/**\nThrown on one of the following conditions:\n$(UL\n  $(LI An unrecognized command-line argument is passed, and\n       `std.getopt.config.passThrough` was not present.)\n  $(LI A command-line option was not found, and\n       `std.getopt.config.required` was present.)\n)\n*/\nclass GetOptException : Exception\n{\n    mixin basicExceptionCtors;\n}\n\nstatic assert(is(typeof(new GetOptException(\"message\"))));\nstatic assert(is(typeof(new GetOptException(\"message\", Exception.init))));\n\n/**\n   Parse and remove command line options from a string array.\n\n   Synopsis:\n\n---------\nimport std.getopt;\n\nstring data = \"file.dat\";\nint length = 24;\nbool verbose;\nenum Color { no, yes };\nColor color;\n\nvoid main(string[] args)\n{\n  auto helpInformation = getopt(\n    args,\n    \"length\",  &length,    // numeric\n    \"file\",    &data,      // string\n    \"verbose\", &verbose,   // flag\n    \"color\", \"Information about this color\", &color);    // enum\n  ...\n\n  if (helpInformation.helpWanted)\n  {\n    defaultGetoptPrinter(\"Some information about the program.\",\n      helpInformation.options);\n  }\n}\n---------\n\n The `getopt` function takes a reference to the command line\n (as received by `main`) as its first argument, and an\n unbounded number of pairs of strings and pointers. Each string is an\n option meant to \"fill\" the value referenced by the pointer to its\n right (the \"bound\" pointer). The option string in the call to\n `getopt` should not start with a dash.\n\n In all cases, the command-line options that were parsed and used by\n `getopt` are removed from `args`. Whatever in the\n arguments did not look like an option is left in `args` for\n further processing by the program. Values that were unaffected by the\n options are not touched, so a common idiom is to initialize options\n to their defaults and then invoke `getopt`. If a\n command-line argument is recognized as an option with a parameter and\n the parameter cannot be parsed properly (e.g., a number is expected\n but not present), a `ConvException` exception is thrown.\n If `std.getopt.config.passThrough` was not passed to `getopt`\n and an unrecognized command-line argument is found, a `GetOptException`\n is thrown.\n\n Depending on the type of the pointer being bound, `getopt`\n recognizes the following kinds of options:\n\n $(OL\n    $(LI $(I Boolean options). A lone argument sets the option to `true`.\n    Additionally $(B true) or $(B false) can be set within the option separated\n    with an \"=\" sign:\n\n---------\n  bool verbose = false, debugging = true;\n  getopt(args, \"verbose\", &verbose, \"debug\", &debugging);\n---------\n\n    To set `verbose` to `true`, invoke the program with either\n    `--verbose` or `--verbose=true`.\n\n    To set `debugging` to `false`, invoke the program with\n    `--debugging=false`.\n    )\n\n    $(LI $(I Numeric options.) If an option is bound to a numeric type, a\n    number is expected as the next option, or right within the option separated\n    with an \"=\" sign:\n\n---------\n  uint timeout;\n  getopt(args, \"timeout\", &timeout);\n---------\n\n    To set `timeout` to `5`, invoke the program with either\n    `--timeout=5` or $(D --timeout 5).\n    )\n\n    $(LI $(I Incremental options.) If an option name has a \"+\" suffix and is\n    bound to a numeric type, then the option's value tracks the number of times\n    the option occurred on the command line:\n\n---------\n  uint paranoid;\n  getopt(args, \"paranoid+\", &paranoid);\n---------\n\n    Invoking the program with \"--paranoid --paranoid --paranoid\" will set $(D\n    paranoid) to 3. Note that an incremental option never expects a parameter,\n    e.g., in the command line \"--paranoid 42 --paranoid\", the \"42\" does not set\n    `paranoid` to 42; instead, `paranoid` is set to 2 and \"42\" is not\n    considered as part of the normal program arguments.\n    )\n\n    $(LI $(I Enum options.) If an option is bound to an enum, an enum symbol as\n    a string is expected as the next option, or right within the option\n    separated with an \"=\" sign:\n\n---------\n  enum Color { no, yes };\n  Color color; // default initialized to Color.no\n  getopt(args, \"color\", &color);\n---------\n\n    To set `color` to `Color.yes`, invoke the program with either\n    `--color=yes` or $(D --color yes).\n    )\n\n    $(LI $(I String options.) If an option is bound to a string, a string is\n    expected as the next option, or right within the option separated with an\n    \"=\" sign:\n\n---------\nstring outputFile;\ngetopt(args, \"output\", &outputFile);\n---------\n\n    Invoking the program with \"--output=myfile.txt\" or \"--output myfile.txt\"\n    will set `outputFile` to \"myfile.txt\". If you want to pass a string\n    containing spaces, you need to use the quoting that is appropriate to your\n    shell, e.g. --output='my file.txt'.\n    )\n\n    $(LI $(I Array options.) If an option is bound to an array, a new element\n    is appended to the array each time the option occurs:\n\n---------\nstring[] outputFiles;\ngetopt(args, \"output\", &outputFiles);\n---------\n\n    Invoking the program with \"--output=myfile.txt --output=yourfile.txt\" or\n    \"--output myfile.txt --output yourfile.txt\" will set `outputFiles` to\n    $(D [ \"myfile.txt\", \"yourfile.txt\" ]).\n\n    Alternatively you can set $(LREF arraySep) as the element separator:\n\n---------\nstring[] outputFiles;\narraySep = \",\";  // defaults to \"\", separation by whitespace\ngetopt(args, \"output\", &outputFiles);\n---------\n\n    With the above code you can invoke the program with\n    \"--output=myfile.txt,yourfile.txt\", or \"--output myfile.txt,yourfile.txt\".)\n\n    $(LI $(I Hash options.) If an option is bound to an associative array, a\n    string of the form \"name=value\" is expected as the next option, or right\n    within the option separated with an \"=\" sign:\n\n---------\ndouble[string] tuningParms;\ngetopt(args, \"tune\", &tuningParms);\n---------\n\n    Invoking the program with e.g. \"--tune=alpha=0.5 --tune beta=0.6\" will set\n    `tuningParms` to [ \"alpha\" : 0.5, \"beta\" : 0.6 ].\n\n    Alternatively you can set $(LREF arraySep) as the element separator:\n\n---------\ndouble[string] tuningParms;\narraySep = \",\";  // defaults to \"\", separation by whitespace\ngetopt(args, \"tune\", &tuningParms);\n---------\n\n    With the above code you can invoke the program with\n    \"--tune=alpha=0.5,beta=0.6\", or \"--tune alpha=0.5,beta=0.6\".\n\n    In general, the keys and values can be of any parsable types.\n    )\n\n    $(LI $(I Callback options.) An option can be bound to a function or\n    delegate with the signature $(D void function()), $(D void function(string\n    option)), $(D void function(string option, string value)), or their\n    delegate equivalents.\n\n    $(UL\n        $(LI If the callback doesn't take any arguments, the callback is\n        invoked whenever the option is seen.\n        )\n\n        $(LI If the callback takes one string argument, the option string\n        (without the leading dash(es)) is passed to the callback.  After that,\n        the option string is considered handled and removed from the options\n        array.\n\n---------\nvoid main(string[] args)\n{\n  uint verbosityLevel = 1;\n  void myHandler(string option)\n  {\n    if (option == \"quiet\")\n    {\n      verbosityLevel = 0;\n    }\n    else\n    {\n      assert(option == \"verbose\");\n      verbosityLevel = 2;\n    }\n  }\n  getopt(args, \"verbose\", &myHandler, \"quiet\", &myHandler);\n}\n---------\n\n        )\n\n        $(LI If the callback takes two string arguments, the option string is\n        handled as an option with one argument, and parsed accordingly. The\n        option and its value are passed to the callback. After that, whatever\n        was passed to the callback is considered handled and removed from the\n        list.\n\n---------\nint main(string[] args)\n{\n  uint verbosityLevel = 1;\n  bool handlerFailed = false;\n  void myHandler(string option, string value)\n  {\n    switch (value)\n    {\n      case \"quiet\": verbosityLevel = 0; break;\n      case \"verbose\": verbosityLevel = 2; break;\n      case \"shouting\": verbosityLevel = verbosityLevel.max; break;\n      default :\n        stderr.writeln(\"Unknown verbosity level \", value);\n        handlerFailed = true;\n        break;\n    }\n  }\n  getopt(args, \"verbosity\", &myHandler);\n  return handlerFailed ? 1 : 0;\n}\n---------\n        )\n    ))\n)\n\nOptions_with_multiple_names:\nSometimes option synonyms are desirable, e.g. \"--verbose\",\n\"--loquacious\", and \"--garrulous\" should have the same effect. Such\nalternate option names can be included in the option specification,\nusing \"|\" as a separator:\n\n---------\nbool verbose;\ngetopt(args, \"verbose|loquacious|garrulous\", &verbose);\n---------\n\nCase:\nBy default options are case-insensitive. You can change that behavior\nby passing `getopt` the `caseSensitive` directive like this:\n\n---------\nbool foo, bar;\ngetopt(args,\n    std.getopt.config.caseSensitive,\n    \"foo\", &foo,\n    \"bar\", &bar);\n---------\n\nIn the example above, \"--foo\" and \"--bar\" are recognized, but \"--Foo\", \"--Bar\",\n\"--FOo\", \"--bAr\", etc. are rejected.\nThe directive is active until the end of `getopt`, or until the\nconverse directive `caseInsensitive` is encountered:\n\n---------\nbool foo, bar;\ngetopt(args,\n    std.getopt.config.caseSensitive,\n    \"foo\", &foo,\n    std.getopt.config.caseInsensitive,\n    \"bar\", &bar);\n---------\n\nThe option \"--Foo\" is rejected due to $(D\nstd.getopt.config.caseSensitive), but not \"--Bar\", \"--bAr\"\netc. because the directive $(D\nstd.getopt.config.caseInsensitive) turned sensitivity off before\noption \"bar\" was parsed.\n\nShort_versus_long_options:\nTraditionally, programs accepted single-letter options preceded by\nonly one dash (e.g. `-t`). `getopt` accepts such parameters\nseamlessly. When used with a double-dash (e.g. `--t`), a\nsingle-letter option behaves the same as a multi-letter option. When\nused with a single dash, a single-letter option is accepted. If the\noption has a parameter, that must be \"stuck\" to the option without\nany intervening space or \"=\":\n\n---------\nuint timeout;\ngetopt(args, \"timeout|t\", &timeout);\n---------\n\nTo set `timeout` to `5`, use either of the following: `--timeout=5`,\n$(D --timeout 5), `--t=5`, $(D --t 5), or `-t5`. Forms such as $(D -t 5)\nand `-timeout=5` will be not accepted.\n\nFor more details about short options, refer also to the next section.\n\nBundling:\nSingle-letter options can be bundled together, i.e. \"-abc\" is the same as\n$(D \"-a -b -c\"). By default, this option is turned off. You can turn it on\nwith the `std.getopt.config.bundling` directive:\n\n---------\nbool foo, bar;\ngetopt(args,\n    std.getopt.config.bundling,\n    \"foo|f\", &foo,\n    \"bar|b\", &bar);\n---------\n\nIn case you want to only enable bundling for some of the parameters,\nbundling can be turned off with `std.getopt.config.noBundling`.\n\nRequired:\nAn option can be marked as required. If that option is not present in the\narguments an exception will be thrown.\n\n---------\nbool foo, bar;\ngetopt(args,\n    std.getopt.config.required,\n    \"foo|f\", &foo,\n    \"bar|b\", &bar);\n---------\n\nOnly the option directly following `std.getopt.config.required` is\nrequired.\n\nPassing_unrecognized_options_through:\nIf an application needs to do its own processing of whichever arguments\n`getopt` did not understand, it can pass the\n`std.getopt.config.passThrough` directive to `getopt`:\n\n---------\nbool foo, bar;\ngetopt(args,\n    std.getopt.config.passThrough,\n    \"foo\", &foo,\n    \"bar\", &bar);\n---------\n\nAn unrecognized option such as \"--baz\" will be found untouched in\n`args` after `getopt` returns.\n\nHelp_Information_Generation:\nIf an option string is followed by another string, this string serves as a\ndescription for this option. The `getopt` function returns a struct of type\n`GetoptResult`. This return value contains information about all passed options\nas well a $(D bool GetoptResult.helpWanted) flag indicating whether information\nabout these options was requested. The `getopt` function always adds an option for\n`--help|-h` to set the flag if the option is seen on the command line.\n\nOptions_Terminator:\nA lone double-dash terminates `getopt` gathering. It is used to\nseparate program options from other parameters (e.g., options to be passed\nto another program). Invoking the example above with $(D \"--foo -- --bar\")\nparses foo but leaves \"--bar\" in `args`. The double-dash itself is\nremoved from the argument array unless the `std.getopt.config.keepEndOfOptions`\ndirective is given.\n*/\nGetoptResult getopt(T...)(ref string[] args, T opts)\n{\n    import std.exception : enforce;\n    enforce(args.length,\n            \"Invalid arguments string passed: program name missing\");\n    configuration cfg;\n    GetoptResult rslt;\n\n    GetOptException excep;\n    void[][string] visitedLongOpts, visitedShortOpts;\n    getoptImpl(args, cfg, rslt, excep, visitedLongOpts, visitedShortOpts, opts);\n\n    if (!rslt.helpWanted && excep !is null)\n    {\n        throw excep;\n    }\n\n    return rslt;\n}\n\n///\n@system unittest\n{\n    auto args = [\"prog\", \"--foo\", \"-b\"];\n\n    bool foo;\n    bool bar;\n    auto rslt = getopt(args, \"foo|f\", \"Some information about foo.\", &foo, \"bar|b\",\n        \"Some help message about bar.\", &bar);\n\n    if (rslt.helpWanted)\n    {\n        defaultGetoptPrinter(\"Some information about the program.\",\n            rslt.options);\n    }\n}\n\n/**\n   Configuration options for `getopt`.\n\n   You can pass them to `getopt` in any position, except in between an option\n   string and its bound pointer.\n*/\nenum config {\n    /// Turn case sensitivity on\n    caseSensitive,\n    /// Turn case sensitivity off (default)\n    caseInsensitive,\n    /// Turn bundling on\n    bundling,\n    /// Turn bundling off (default)\n    noBundling,\n    /// Pass unrecognized arguments through\n    passThrough,\n    /// Signal unrecognized arguments as errors (default)\n    noPassThrough,\n    /// Stop at first argument that does not look like an option\n    stopOnFirstNonOption,\n    /// Do not erase the endOfOptions separator from args\n    keepEndOfOptions,\n    /// Make the next option a required option\n    required\n}\n\n/** The result of the `getopt` function.\n\n`helpWanted` is set if the option `--help` or `-h` was passed to the option parser.\n*/\nstruct GetoptResult {\n    bool helpWanted; /// Flag indicating if help was requested\n    Option[] options; /// All possible options\n}\n\n/** Information about an option.\n*/\nstruct Option {\n    string optShort; /// The short symbol for this option\n    string optLong; /// The long symbol for this option\n    string help; /// The description of this option\n    bool required; /// If a option is required, not passing it will result in an error\n}\n\nprivate pure Option splitAndGet(string opt) @trusted nothrow\n{\n    import std.array : split;\n    auto sp = split(opt, \"|\");\n    Option ret;\n    if (sp.length > 1)\n    {\n        ret.optShort = \"-\" ~ (sp[0].length < sp[1].length ?\n            sp[0] : sp[1]);\n        ret.optLong = \"--\" ~ (sp[0].length > sp[1].length ?\n            sp[0] : sp[1]);\n    }\n    else if (sp[0].length > 1)\n    {\n        ret.optLong = \"--\" ~ sp[0];\n    }\n    else\n    {\n        ret.optShort = \"-\" ~ sp[0];\n    }\n\n    return ret;\n}\n\n@safe unittest\n{\n    auto oshort = splitAndGet(\"f\");\n    assert(oshort.optShort == \"-f\");\n    assert(oshort.optLong == \"\");\n\n    auto olong = splitAndGet(\"foo\");\n    assert(olong.optShort == \"\");\n    assert(olong.optLong == \"--foo\");\n\n    auto oshortlong = splitAndGet(\"f|foo\");\n    assert(oshortlong.optShort == \"-f\");\n    assert(oshortlong.optLong == \"--foo\");\n\n    auto olongshort = splitAndGet(\"foo|f\");\n    assert(olongshort.optShort == \"-f\");\n    assert(olongshort.optLong == \"--foo\");\n}\n\n/*\nThis function verifies that the variadic parameters passed in getOpt\nfollow this pattern:\n\n  [config override], option, [description], receiver,\n\n - config override: a config value, optional\n - option:          a string or a char\n - description:     a string, optional\n - receiver:        a pointer or a callable\n*/\nprivate template optionValidator(A...)\n{\n    import std.format : format;\n\n    enum fmt = \"getopt validator: %s (at position %d)\";\n    enum isReceiver(T) = isPointer!T || (is(T == function)) || (is(T == delegate));\n    enum isOptionStr(T) = isSomeString!T || isSomeChar!T;\n\n    auto validator()\n    {\n        string msg;\n        static if (A.length > 0)\n        {\n            static if (isReceiver!(A[0]))\n            {\n                msg = format(fmt, \"first argument must be a string or a config\", 0);\n            }\n            else static if (!isOptionStr!(A[0]) && !is(A[0] == config))\n            {\n                msg = format(fmt, \"invalid argument type: \" ~ A[0].stringof, 0);\n            }\n            else\n            {\n                static foreach (i; 1 .. A.length)\n                {\n                    static if (!isReceiver!(A[i]) && !isOptionStr!(A[i]) &&\n                        !(is(A[i] == config)))\n                    {\n                        msg = format(fmt, \"invalid argument type: \" ~ A[i].stringof, i);\n                        goto end;\n                    }\n                    else static if (isReceiver!(A[i]) && !isOptionStr!(A[i-1]))\n                    {\n                        msg = format(fmt, \"a receiver can not be preceeded by a receiver\", i);\n                        goto end;\n                    }\n                    else static if (i > 1 && isOptionStr!(A[i]) && isOptionStr!(A[i-1])\n                        && isSomeString!(A[i-2]))\n                    {\n                        msg = format(fmt, \"a string can not be preceeded by two strings\", i);\n                        goto end;\n                    }\n                }\n            }\n            static if (!isReceiver!(A[$-1]) && !is(A[$-1] == config))\n            {\n                msg = format(fmt, \"last argument must be a receiver or a config\",\n                    A.length -1);\n            }\n        }\n    end:\n        return msg;\n    }\n    enum message = validator;\n    alias optionValidator = message;\n}\n\n@safe pure unittest\n{\n    alias P = void*;\n    alias S = string;\n    alias A = char;\n    alias C = config;\n    alias F = void function();\n\n    static assert(optionValidator!(S,P) == \"\");\n    static assert(optionValidator!(S,F) == \"\");\n    static assert(optionValidator!(A,P) == \"\");\n    static assert(optionValidator!(A,F) == \"\");\n\n    static assert(optionValidator!(C,S,P) == \"\");\n    static assert(optionValidator!(C,S,F) == \"\");\n    static assert(optionValidator!(C,A,P) == \"\");\n    static assert(optionValidator!(C,A,F) == \"\");\n\n    static assert(optionValidator!(C,S,S,P) == \"\");\n    static assert(optionValidator!(C,S,S,F) == \"\");\n    static assert(optionValidator!(C,A,S,P) == \"\");\n    static assert(optionValidator!(C,A,S,F) == \"\");\n\n    static assert(optionValidator!(C,S,S,P) == \"\");\n    static assert(optionValidator!(C,S,S,P,C,S,F) == \"\");\n    static assert(optionValidator!(C,S,P,C,S,S,F) == \"\");\n\n    static assert(optionValidator!(C,A,P,A,S,F) == \"\");\n    static assert(optionValidator!(C,A,P,C,A,S,F) == \"\");\n\n    static assert(optionValidator!(P,S,S) != \"\");\n    static assert(optionValidator!(P,P,S) != \"\");\n    static assert(optionValidator!(P,F,S,P) != \"\");\n    static assert(optionValidator!(C,C,S) != \"\");\n    static assert(optionValidator!(S,S,P,S,S,P,S) != \"\");\n    static assert(optionValidator!(S,S,P,P) != \"\");\n    static assert(optionValidator!(S,S,S,P) != \"\");\n\n    static assert(optionValidator!(C,A,S,P,C,A,F) == \"\");\n    static assert(optionValidator!(C,A,P,C,A,S,F) == \"\");\n}\n\n@system unittest // bugzilla 15914\n{\n    bool opt;\n    string[] args = [\"program\", \"-a\"];\n    getopt(args, config.passThrough, 'a', &opt);\n    assert(opt);\n    opt = false;\n    args = [\"program\", \"-a\"];\n    getopt(args, 'a', &opt);\n    assert(opt);\n    opt = false;\n    args = [\"program\", \"-a\"];\n    getopt(args, 'a', \"help string\", &opt);\n    assert(opt);\n    opt = false;\n    args = [\"program\", \"-a\"];\n    getopt(args, config.caseSensitive, 'a', \"help string\", &opt);\n    assert(opt);\n\n    assertThrown(getopt(args, \"\", \"forgot to put a string\", &opt));\n}\n\nprivate void getoptImpl(T...)(ref string[] args, ref configuration cfg,\n    ref GetoptResult rslt, ref GetOptException excep,\n    void[][string] visitedLongOpts, void[][string] visitedShortOpts, T opts)\n{\n    enum validationMessage = optionValidator!T;\n    static assert(validationMessage == \"\", validationMessage);\n\n    import std.algorithm.mutation : remove;\n    import std.conv : to;\n    static if (opts.length)\n    {\n        static if (is(typeof(opts[0]) : config))\n        {\n            // it's a configuration flag, act on it\n            setConfig(cfg, opts[0]);\n            return getoptImpl(args, cfg, rslt, excep, visitedLongOpts,\n                visitedShortOpts, opts[1 .. $]);\n        }\n        else\n        {\n            // it's an option string\n            auto option = to!string(opts[0]);\n            if (option.length == 0)\n            {\n                excep = new GetOptException(\"An option name may not be an empty string\", excep);\n                return;\n            }\n            Option optionHelp = splitAndGet(option);\n            optionHelp.required = cfg.required;\n\n            if (optionHelp.optLong.length)\n            {\n                assert(optionHelp.optLong !in visitedLongOpts,\n                    \"Long option \" ~ optionHelp.optLong ~ \" is multiply defined\");\n\n                visitedLongOpts[optionHelp.optLong] = [];\n            }\n\n            if (optionHelp.optShort.length)\n            {\n                assert(optionHelp.optShort !in visitedShortOpts,\n                    \"Short option \" ~ optionHelp.optShort\n                    ~ \" is multiply defined\");\n\n                visitedShortOpts[optionHelp.optShort] = [];\n            }\n\n            static if (is(typeof(opts[1]) : string))\n            {\n                auto receiver = opts[2];\n                optionHelp.help = opts[1];\n                immutable lowSliceIdx = 3;\n            }\n            else\n            {\n                auto receiver = opts[1];\n                immutable lowSliceIdx = 2;\n            }\n\n            rslt.options ~= optionHelp;\n\n            bool incremental;\n            // Handle options of the form --blah+\n            if (option.length && option[$ - 1] == autoIncrementChar)\n            {\n                option = option[0 .. $ - 1];\n                incremental = true;\n            }\n\n            bool optWasHandled = handleOption(option, receiver, args, cfg, incremental);\n\n            if (cfg.required && !optWasHandled)\n            {\n                excep = new GetOptException(\"Required option \"\n                    ~ option ~ \" was not supplied\", excep);\n            }\n            cfg.required = false;\n\n            getoptImpl(args, cfg, rslt, excep, visitedLongOpts,\n                visitedShortOpts, opts[lowSliceIdx .. $]);\n        }\n    }\n    else\n    {\n        // no more options to look for, potentially some arguments left\n        for (size_t i = 1; i < args.length;)\n        {\n            auto a = args[i];\n            if (endOfOptions.length && a == endOfOptions)\n            {\n                // Consume the \"--\" if keepEndOfOptions is not specified\n                if (!cfg.keepEndOfOptions)\n                    args = args.remove(i);\n                break;\n            }\n            if (!a.length || a[0] != optionChar)\n            {\n                // not an option\n                if (cfg.stopOnFirstNonOption) break;\n                ++i;\n                continue;\n            }\n            if (a == \"--help\" || a == \"-h\")\n            {\n                rslt.helpWanted = true;\n                args = args.remove(i);\n                continue;\n            }\n            if (!cfg.passThrough)\n            {\n                throw new GetOptException(\"Unrecognized option \"~a, excep);\n            }\n            ++i;\n        }\n\n        Option helpOpt;\n        helpOpt.optShort = \"-h\";\n        helpOpt.optLong = \"--help\";\n        helpOpt.help = \"This help information.\";\n        rslt.options ~= helpOpt;\n    }\n}\n\nprivate bool handleOption(R)(string option, R receiver, ref string[] args,\n    ref configuration cfg, bool incremental)\n{\n    import std.algorithm.iteration : map, splitter;\n    import std.ascii : isAlpha;\n    import std.conv : text, to;\n    // Scan arguments looking for a match for this option\n    bool ret = false;\n    for (size_t i = 1; i < args.length; )\n    {\n        auto a = args[i];\n        if (endOfOptions.length && a == endOfOptions) break;\n        if (cfg.stopOnFirstNonOption && (!a.length || a[0] != optionChar))\n        {\n            // first non-option is end of options\n            break;\n        }\n        // Unbundle bundled arguments if necessary\n        if (cfg.bundling && a.length > 2 && a[0] == optionChar &&\n                a[1] != optionChar)\n        {\n            string[] expanded;\n            foreach (j, dchar c; a[1 .. $])\n            {\n                // If the character is not alpha, stop right there. This allows\n                // e.g. -j100 to work as \"pass argument 100 to option -j\".\n                if (!isAlpha(c))\n                {\n                    if (c == '=')\n                        j++;\n                    expanded ~= a[j + 1 .. $];\n                    break;\n                }\n                expanded ~= text(optionChar, c);\n            }\n            args = args[0 .. i] ~ expanded ~ args[i + 1 .. $];\n            continue;\n        }\n\n        string val;\n        if (!optMatch(a, option, val, cfg))\n        {\n            ++i;\n            continue;\n        }\n\n        ret = true;\n\n        // found it\n        // from here on, commit to eat args[i]\n        // (and potentially args[i + 1] too, but that comes later)\n        args = args[0 .. i] ~ args[i + 1 .. $];\n\n        static if (is(typeof(*receiver) == bool))\n        {\n            if (val.length)\n            {\n                // parse '--b=true/false'\n                *receiver = to!(typeof(*receiver))(val);\n            }\n            else\n            {\n                // no argument means set it to true\n                *receiver = true;\n            }\n        }\n        else\n        {\n            import std.exception : enforce;\n            // non-boolean option, which might include an argument\n            //enum isCallbackWithOneParameter = is(typeof(receiver(\"\")) : void);\n            enum isCallbackWithLessThanTwoParameters =\n                (is(typeof(receiver) == delegate) || is(typeof(*receiver) == function)) &&\n                !is(typeof(receiver(\"\", \"\")));\n            if (!isCallbackWithLessThanTwoParameters && !(val.length) && !incremental)\n            {\n                // Eat the next argument too.  Check to make sure there's one\n                // to be eaten first, though.\n                enforce(i < args.length,\n                    \"Missing value for argument \" ~ a ~ \".\");\n                val = args[i];\n                args = args[0 .. i] ~ args[i + 1 .. $];\n            }\n            static if (is(typeof(*receiver) == enum))\n            {\n                *receiver = to!(typeof(*receiver))(val);\n            }\n            else static if (is(typeof(*receiver) : real))\n            {\n                // numeric receiver\n                if (incremental) ++*receiver;\n                else *receiver = to!(typeof(*receiver))(val);\n            }\n            else static if (is(typeof(*receiver) == string))\n            {\n                // string receiver\n                *receiver = to!(typeof(*receiver))(val);\n            }\n            else static if (is(typeof(receiver) == delegate) ||\n                            is(typeof(*receiver) == function))\n            {\n                static if (is(typeof(receiver(\"\", \"\")) : void))\n                {\n                    // option with argument\n                    receiver(option, val);\n                }\n                else static if (is(typeof(receiver(\"\")) : void))\n                {\n                    static assert(is(typeof(receiver(\"\")) : void));\n                    // boolean-style receiver\n                    receiver(option);\n                }\n                else\n                {\n                    static assert(is(typeof(receiver()) : void));\n                    // boolean-style receiver without argument\n                    receiver();\n                }\n            }\n            else static if (isArray!(typeof(*receiver)))\n            {\n                // array receiver\n                import std.range : ElementEncodingType;\n                alias E = ElementEncodingType!(typeof(*receiver));\n\n                if (arraySep == \"\")\n                {\n                    *receiver ~= to!E(val);\n                }\n                else\n                {\n                    foreach (elem; val.splitter(arraySep).map!(a => to!E(a))())\n                        *receiver ~= elem;\n                }\n            }\n            else static if (isAssociativeArray!(typeof(*receiver)))\n            {\n                // hash receiver\n                alias K = typeof(receiver.keys[0]);\n                alias V = typeof(receiver.values[0]);\n\n                import std.range : only;\n                import std.string : indexOf;\n                import std.typecons : Tuple, tuple;\n\n                static Tuple!(K, V) getter(string input)\n                {\n                    auto j = indexOf(input, assignChar);\n                    enforce!GetOptException(j != -1, \"Could not find '\"\n                        ~ to!string(assignChar) ~ \"' in argument '\" ~ input ~ \"'.\");\n                    auto key = input[0 .. j];\n                    auto value = input[j + 1 .. $];\n                    return tuple(to!K(key), to!V(value));\n                }\n\n                static void setHash(Range)(R receiver, Range range)\n                {\n                    foreach (k, v; range.map!getter)\n                        (*receiver)[k] = v;\n                }\n\n                if (arraySep == \"\")\n                    setHash(receiver, val.only);\n                else\n                    setHash(receiver, val.splitter(arraySep));\n            }\n            else\n                static assert(false, \"getopt does not know how to handle the type \" ~ typeof(receiver).stringof);\n        }\n    }\n\n    return ret;\n}\n\n// 17574\n@system unittest\n{\n    import std.algorithm.searching : startsWith;\n\n    try\n    {\n        string[string] mapping;\n        immutable as = arraySep;\n        arraySep = \",\";\n        scope (exit)\n            arraySep = as;\n        string[] args = [\"testProgram\", \"-m\", \"a=b,c=\\\"d,e,f\\\"\"];\n        args.getopt(\"m\", &mapping);\n        assert(false, \"Exception not thrown\");\n    }\n    catch (GetOptException goe)\n        assert(goe.msg.startsWith(\"Could not find\"));\n}\n\n// 5316 - arrays with arraySep\n@system unittest\n{\n    import std.conv;\n\n    arraySep = \",\";\n    scope (exit) arraySep = \"\";\n\n    string[] names;\n    auto args = [\"program.name\", \"-nfoo,bar,baz\"];\n    getopt(args, \"name|n\", &names);\n    assert(names == [\"foo\", \"bar\", \"baz\"], to!string(names));\n\n    names = names.init;\n    args = [\"program.name\", \"-n\", \"foo,bar,baz\"];\n    getopt(args, \"name|n\", &names);\n    assert(names == [\"foo\", \"bar\", \"baz\"], to!string(names));\n\n    names = names.init;\n    args = [\"program.name\", \"--name=foo,bar,baz\"];\n    getopt(args, \"name|n\", &names);\n    assert(names == [\"foo\", \"bar\", \"baz\"], to!string(names));\n\n    names = names.init;\n    args = [\"program.name\", \"--name\", \"foo,bar,baz\"];\n    getopt(args, \"name|n\", &names);\n    assert(names == [\"foo\", \"bar\", \"baz\"], to!string(names));\n}\n\n// 5316 - associative arrays with arraySep\n@system unittest\n{\n    import std.conv;\n\n    arraySep = \",\";\n    scope (exit) arraySep = \"\";\n\n    int[string] values;\n    values = values.init;\n    auto args = [\"program.name\", \"-vfoo=0,bar=1,baz=2\"];\n    getopt(args, \"values|v\", &values);\n    assert(values == [\"foo\":0, \"bar\":1, \"baz\":2], to!string(values));\n\n    values = values.init;\n    args = [\"program.name\", \"-v\", \"foo=0,bar=1,baz=2\"];\n    getopt(args, \"values|v\", &values);\n    assert(values == [\"foo\":0, \"bar\":1, \"baz\":2], to!string(values));\n\n    values = values.init;\n    args = [\"program.name\", \"--values=foo=0,bar=1,baz=2\"];\n    getopt(args, \"values|t\", &values);\n    assert(values == [\"foo\":0, \"bar\":1, \"baz\":2], to!string(values));\n\n    values = values.init;\n    args = [\"program.name\", \"--values\", \"foo=0,bar=1,baz=2\"];\n    getopt(args, \"values|v\", &values);\n    assert(values == [\"foo\":0, \"bar\":1, \"baz\":2], to!string(values));\n}\n\n/**\n   The option character (default '-').\n\n   Defaults to '-' but it can be assigned to prior to calling `getopt`.\n */\ndchar optionChar = '-';\n\n/**\n   The string that conventionally marks the end of all options (default '--').\n\n   Defaults to \"--\" but can be assigned to prior to calling `getopt`. Assigning an\n   empty string to `endOfOptions` effectively disables it.\n */\nstring endOfOptions = \"--\";\n\n/**\n   The assignment character used in options with parameters (default '=').\n\n   Defaults to '=' but can be assigned to prior to calling `getopt`.\n */\ndchar assignChar = '=';\n\n/**\n   The string used to separate the elements of an array or associative array\n   (default is \"\" which means the elements are separated by whitespace).\n\n   Defaults to \"\" but can be assigned to prior to calling `getopt`.\n */\nstring arraySep = \"\";\n\nprivate enum autoIncrementChar = '+';\n\nprivate struct configuration\n{\n    import std.bitmanip : bitfields;\n    mixin(bitfields!(\n                bool, \"caseSensitive\",  1,\n                bool, \"bundling\", 1,\n                bool, \"passThrough\", 1,\n                bool, \"stopOnFirstNonOption\", 1,\n                bool, \"keepEndOfOptions\", 1,\n                bool, \"required\", 1,\n                ubyte, \"\", 2));\n}\n\nprivate bool optMatch(string arg, string optPattern, ref string value,\n    configuration cfg) @safe\n{\n    import std.array : split;\n    import std.string : indexOf;\n    import std.uni : toUpper;\n    //writeln(\"optMatch:\\n  \", arg, \"\\n  \", optPattern, \"\\n  \", value);\n    //scope(success) writeln(\"optMatch result: \", value);\n    if (arg.length < 2 || arg[0] != optionChar) return false;\n    // yank the leading '-'\n    arg = arg[1 .. $];\n    immutable isLong = arg.length > 1 && arg[0] == optionChar;\n    //writeln(\"isLong: \", isLong);\n    // yank the second '-' if present\n    if (isLong) arg = arg[1 .. $];\n    immutable eqPos = indexOf(arg, assignChar);\n    if (isLong && eqPos >= 0)\n    {\n        // argument looks like --opt=value\n        value = arg[eqPos + 1 .. $];\n        arg = arg[0 .. eqPos];\n    }\n    else\n    {\n        if (!isLong && eqPos == 1)\n        {\n            // argument looks like -o=value\n            value = arg[2 .. $];\n            arg = arg[0 .. 1];\n        }\n        else\n        if (!isLong && !cfg.bundling)\n        {\n            // argument looks like -ovalue and there's no bundling\n            value = arg[1 .. $];\n            arg = arg[0 .. 1];\n        }\n        else\n        {\n            // argument looks like --opt, or -oxyz with bundling\n            value = null;\n        }\n    }\n    //writeln(\"Arg: \", arg, \" pattern: \", optPattern, \" value: \", value);\n    // Split the option\n    const variants = split(optPattern, \"|\");\n    foreach (v ; variants)\n    {\n        //writeln(\"Trying variant: \", v, \" against \", arg);\n        if (arg == v || !cfg.caseSensitive && toUpper(arg) == toUpper(v))\n            return true;\n        if (cfg.bundling && !isLong && v.length == 1\n                && indexOf(arg, v) >= 0)\n        {\n            //writeln(\"success\");\n            return true;\n        }\n    }\n    return false;\n}\n\nprivate void setConfig(ref configuration cfg, config option) @safe pure nothrow @nogc\n{\n    final switch (option)\n    {\n    case config.caseSensitive: cfg.caseSensitive = true; break;\n    case config.caseInsensitive: cfg.caseSensitive = false; break;\n    case config.bundling: cfg.bundling = true; break;\n    case config.noBundling: cfg.bundling = false; break;\n    case config.passThrough: cfg.passThrough = true; break;\n    case config.noPassThrough: cfg.passThrough = false; break;\n    case config.required: cfg.required = true; break;\n    case config.stopOnFirstNonOption:\n        cfg.stopOnFirstNonOption = true; break;\n    case config.keepEndOfOptions:\n        cfg.keepEndOfOptions = true; break;\n    }\n}\n\n@system unittest\n{\n    import std.conv;\n    import std.math;\n\n    uint paranoid = 2;\n    string[] args = [\"program.name\", \"--paranoid\", \"--paranoid\", \"--paranoid\"];\n    getopt(args, \"paranoid+\", &paranoid);\n    assert(paranoid == 5, to!(string)(paranoid));\n\n    enum Color { no, yes }\n    Color color;\n    args = [\"program.name\", \"--color=yes\",];\n    getopt(args, \"color\", &color);\n    assert(color, to!(string)(color));\n\n    color = Color.no;\n    args = [\"program.name\", \"--color\", \"yes\",];\n    getopt(args, \"color\", &color);\n    assert(color, to!(string)(color));\n\n    string data = \"file.dat\";\n    int length = 24;\n    bool verbose = false;\n    args = [\"program.name\", \"--length=5\", \"--file\", \"dat.file\", \"--verbose\"];\n    getopt(\n        args,\n        \"length\",  &length,\n        \"file\",    &data,\n        \"verbose\", &verbose);\n    assert(args.length == 1);\n    assert(data == \"dat.file\");\n    assert(length == 5);\n    assert(verbose);\n\n    //\n    string[] outputFiles;\n    args = [\"program.name\", \"--output=myfile.txt\", \"--output\", \"yourfile.txt\"];\n    getopt(args, \"output\", &outputFiles);\n    assert(outputFiles.length == 2\n           && outputFiles[0] == \"myfile.txt\" && outputFiles[1] == \"yourfile.txt\");\n\n    outputFiles = [];\n    arraySep = \",\";\n    args = [\"program.name\", \"--output\", \"myfile.txt,yourfile.txt\"];\n    getopt(args, \"output\", &outputFiles);\n    assert(outputFiles.length == 2\n           && outputFiles[0] == \"myfile.txt\" && outputFiles[1] == \"yourfile.txt\");\n    arraySep = \"\";\n\n    foreach (testArgs;\n        [[\"program.name\", \"--tune=alpha=0.5\", \"--tune\", \"beta=0.6\"],\n         [\"program.name\", \"--tune=alpha=0.5,beta=0.6\"],\n         [\"program.name\", \"--tune\", \"alpha=0.5,beta=0.6\"]])\n    {\n        arraySep = \",\";\n        double[string] tuningParms;\n        getopt(testArgs, \"tune\", &tuningParms);\n        assert(testArgs.length == 1);\n        assert(tuningParms.length == 2);\n        assert(approxEqual(tuningParms[\"alpha\"], 0.5));\n        assert(approxEqual(tuningParms[\"beta\"], 0.6));\n        arraySep = \"\";\n    }\n\n    uint verbosityLevel = 1;\n    void myHandler(string option)\n    {\n        if (option == \"quiet\")\n        {\n            verbosityLevel = 0;\n        }\n        else\n        {\n            assert(option == \"verbose\");\n            verbosityLevel = 2;\n        }\n    }\n    args = [\"program.name\", \"--quiet\"];\n    getopt(args, \"verbose\", &myHandler, \"quiet\", &myHandler);\n    assert(verbosityLevel == 0);\n    args = [\"program.name\", \"--verbose\"];\n    getopt(args, \"verbose\", &myHandler, \"quiet\", &myHandler);\n    assert(verbosityLevel == 2);\n\n    verbosityLevel = 1;\n    void myHandler2(string option, string value)\n    {\n        assert(option == \"verbose\");\n        verbosityLevel = 2;\n    }\n    args = [\"program.name\", \"--verbose\", \"2\"];\n    getopt(args, \"verbose\", &myHandler2);\n    assert(verbosityLevel == 2);\n\n    verbosityLevel = 1;\n    void myHandler3()\n    {\n        verbosityLevel = 2;\n    }\n    args = [\"program.name\", \"--verbose\"];\n    getopt(args, \"verbose\", &myHandler3);\n    assert(verbosityLevel == 2);\n\n    bool foo, bar;\n    args = [\"program.name\", \"--foo\", \"--bAr\"];\n    getopt(args,\n        std.getopt.config.caseSensitive,\n        std.getopt.config.passThrough,\n        \"foo\", &foo,\n        \"bar\", &bar);\n    assert(args[1] == \"--bAr\");\n\n    // test stopOnFirstNonOption\n\n    args = [\"program.name\", \"--foo\", \"nonoption\", \"--bar\"];\n    foo = bar = false;\n    getopt(args,\n        std.getopt.config.stopOnFirstNonOption,\n        \"foo\", &foo,\n        \"bar\", &bar);\n    assert(foo && !bar && args[1] == \"nonoption\" && args[2] == \"--bar\");\n\n    args = [\"program.name\", \"--foo\", \"nonoption\", \"--zab\"];\n    foo = bar = false;\n    getopt(args,\n        std.getopt.config.stopOnFirstNonOption,\n        \"foo\", &foo,\n        \"bar\", &bar);\n    assert(foo && !bar && args[1] == \"nonoption\" && args[2] == \"--zab\");\n\n    args = [\"program.name\", \"--fb1\", \"--fb2=true\", \"--tb1=false\"];\n    bool fb1, fb2;\n    bool tb1 = true;\n    getopt(args, \"fb1\", &fb1, \"fb2\", &fb2, \"tb1\", &tb1);\n    assert(fb1 && fb2 && !tb1);\n\n    // test keepEndOfOptions\n\n    args = [\"program.name\", \"--foo\", \"nonoption\", \"--bar\", \"--\", \"--baz\"];\n    getopt(args,\n        std.getopt.config.keepEndOfOptions,\n        \"foo\", &foo,\n        \"bar\", &bar);\n    assert(args == [\"program.name\", \"nonoption\", \"--\", \"--baz\"]);\n\n    // Ensure old behavior without the keepEndOfOptions\n\n    args = [\"program.name\", \"--foo\", \"nonoption\", \"--bar\", \"--\", \"--baz\"];\n    getopt(args,\n        \"foo\", &foo,\n        \"bar\", &bar);\n    assert(args == [\"program.name\", \"nonoption\", \"--baz\"]);\n\n    // test function callbacks\n\n    static class MyEx : Exception\n    {\n        this() { super(\"\"); }\n        this(string option) { this(); this.option = option; }\n        this(string option, string value) { this(option); this.value = value; }\n\n        string option;\n        string value;\n    }\n\n    static void myStaticHandler1() { throw new MyEx(); }\n    args = [\"program.name\", \"--verbose\"];\n    try { getopt(args, \"verbose\", &myStaticHandler1); assert(0); }\n    catch (MyEx ex) { assert(ex.option is null && ex.value is null); }\n\n    static void myStaticHandler2(string option) { throw new MyEx(option); }\n    args = [\"program.name\", \"--verbose\"];\n    try { getopt(args, \"verbose\", &myStaticHandler2); assert(0); }\n    catch (MyEx ex) { assert(ex.option == \"verbose\" && ex.value is null); }\n\n    static void myStaticHandler3(string option, string value) { throw new MyEx(option, value); }\n    args = [\"program.name\", \"--verbose\", \"2\"];\n    try { getopt(args, \"verbose\", &myStaticHandler3); assert(0); }\n    catch (MyEx ex) { assert(ex.option == \"verbose\" && ex.value == \"2\"); }\n}\n\n@safe unittest // @safe std.getopt.config option use\n{\n    long x = 0;\n    string[] args = [\"program\", \"--inc-x\", \"--inc-x\"];\n    getopt(args,\n           std.getopt.config.caseSensitive,\n           \"inc-x\", \"Add one to x\", delegate void() { x++; });\n    assert(x == 2);\n}\n\n@system unittest\n{\n    // From bugzilla 2142\n    bool f_linenum, f_filename;\n    string[] args = [ \"\", \"-nl\" ];\n    getopt\n        (\n            args,\n            std.getopt.config.bundling,\n            //std.getopt.config.caseSensitive,\n            \"linenum|l\", &f_linenum,\n            \"filename|n\", &f_filename\n        );\n    assert(f_linenum);\n    assert(f_filename);\n}\n\n@system unittest\n{\n    // From bugzilla 6887\n    string[] p;\n    string[] args = [\"\", \"-pa\"];\n    getopt(args, \"p\", &p);\n    assert(p.length == 1);\n    assert(p[0] == \"a\");\n}\n\n@system unittest\n{\n    // From bugzilla 6888\n    int[string] foo;\n    auto args = [\"\", \"-t\", \"a=1\"];\n    getopt(args, \"t\", &foo);\n    assert(foo == [\"a\":1]);\n}\n\n@system unittest\n{\n    // From bugzilla 9583\n    int opt;\n    auto args = [\"prog\", \"--opt=123\", \"--\", \"--a\", \"--b\", \"--c\"];\n    getopt(args, \"opt\", &opt);\n    assert(args == [\"prog\", \"--a\", \"--b\", \"--c\"]);\n}\n\n@system unittest\n{\n    string foo, bar;\n    auto args = [\"prog\", \"-thello\", \"-dbar=baz\"];\n    getopt(args, \"t\", &foo, \"d\", &bar);\n    assert(foo == \"hello\");\n    assert(bar == \"bar=baz\");\n\n    // From bugzilla 5762\n    string a;\n    args = [\"prog\", \"-a-0x12\"];\n    getopt(args, config.bundling, \"a|addr\", &a);\n    assert(a == \"-0x12\", a);\n    args = [\"prog\", \"--addr=-0x12\"];\n    getopt(args, config.bundling, \"a|addr\", &a);\n    assert(a == \"-0x12\");\n\n    // From https://d.puremagic.com/issues/show_bug.cgi?id=11764\n    args = [\"main\", \"-test\"];\n    bool opt;\n    args.getopt(config.passThrough, \"opt\", &opt);\n    assert(args == [\"main\", \"-test\"]);\n\n    // From https://issues.dlang.org/show_bug.cgi?id=15220\n    args = [\"main\", \"-o=str\"];\n    string o;\n    args.getopt(\"o\", &o);\n    assert(o == \"str\");\n\n    args = [\"main\", \"-o=str\"];\n    o = null;\n    args.getopt(config.bundling, \"o\", &o);\n    assert(o == \"str\");\n}\n\n@system unittest // 5228\n{\n    import std.conv;\n    import std.exception;\n\n    auto args = [\"prog\", \"--foo=bar\"];\n    int abc;\n    assertThrown!GetOptException(getopt(args, \"abc\", &abc));\n\n    args = [\"prog\", \"--abc=string\"];\n    assertThrown!ConvException(getopt(args, \"abc\", &abc));\n}\n\n@system unittest // From bugzilla 7693\n{\n    import std.exception;\n\n    enum Foo {\n        bar,\n        baz\n    }\n\n    auto args = [\"prog\", \"--foo=barZZZ\"];\n    Foo foo;\n    assertThrown(getopt(args, \"foo\", &foo));\n    args = [\"prog\", \"--foo=bar\"];\n    assertNotThrown(getopt(args, \"foo\", &foo));\n    args = [\"prog\", \"--foo\", \"barZZZ\"];\n    assertThrown(getopt(args, \"foo\", &foo));\n    args = [\"prog\", \"--foo\", \"baz\"];\n    assertNotThrown(getopt(args, \"foo\", &foo));\n}\n\n@system unittest // same bug as 7693 only for bool\n{\n    import std.exception;\n\n    auto args = [\"prog\", \"--foo=truefoobar\"];\n    bool foo;\n    assertThrown(getopt(args, \"foo\", &foo));\n    args = [\"prog\", \"--foo\"];\n    getopt(args, \"foo\", &foo);\n    assert(foo);\n}\n\n@system unittest\n{\n    bool foo;\n    auto args = [\"prog\", \"--foo\"];\n    getopt(args, \"foo\", &foo);\n    assert(foo);\n}\n\n@system unittest\n{\n    bool foo;\n    bool bar;\n    auto args = [\"prog\", \"--foo\", \"-b\"];\n    getopt(args, config.caseInsensitive,\"foo|f\", \"Some foo\", &foo,\n        config.caseSensitive, \"bar|b\", \"Some bar\", &bar);\n    assert(foo);\n    assert(bar);\n}\n\n@system unittest\n{\n    bool foo;\n    bool bar;\n    auto args = [\"prog\", \"-b\", \"--foo\", \"-z\"];\n    getopt(args, config.caseInsensitive, config.required, \"foo|f\", \"Some foo\",\n        &foo, config.caseSensitive, \"bar|b\", \"Some bar\", &bar,\n        config.passThrough);\n    assert(foo);\n    assert(bar);\n}\n\n@system unittest\n{\n    import std.exception;\n\n    bool foo;\n    bool bar;\n    auto args = [\"prog\", \"-b\", \"-z\"];\n    assertThrown(getopt(args, config.caseInsensitive, config.required, \"foo|f\",\n        \"Some foo\", &foo, config.caseSensitive, \"bar|b\", \"Some bar\", &bar,\n        config.passThrough));\n}\n\n@system unittest\n{\n    import std.exception;\n\n    bool foo;\n    bool bar;\n    auto args = [\"prog\", \"--foo\", \"-z\"];\n    assertNotThrown(getopt(args, config.caseInsensitive, config.required,\n        \"foo|f\", \"Some foo\", &foo, config.caseSensitive, \"bar|b\", \"Some bar\",\n        &bar, config.passThrough));\n    assert(foo);\n    assert(!bar);\n}\n\n@system unittest\n{\n    bool foo;\n    auto args = [\"prog\", \"-f\"];\n    auto r = getopt(args, config.caseInsensitive, \"help|f\", \"Some foo\", &foo);\n    assert(foo);\n    assert(!r.helpWanted);\n}\n\n@safe unittest // implicit help option without config.passThrough\n{\n    string[] args = [\"program\", \"--help\"];\n    auto r = getopt(args);\n    assert(r.helpWanted);\n}\n\n// Issue 13316 - std.getopt: implicit help option breaks the next argument\n@system unittest\n{\n    string[] args = [\"program\", \"--help\", \"--\", \"something\"];\n    getopt(args);\n    assert(args == [\"program\", \"something\"]);\n\n    args = [\"program\", \"--help\", \"--\"];\n    getopt(args);\n    assert(args == [\"program\"]);\n\n    bool b;\n    args = [\"program\", \"--help\", \"nonoption\", \"--option\"];\n    getopt(args, config.stopOnFirstNonOption, \"option\", &b);\n    assert(args == [\"program\", \"nonoption\", \"--option\"]);\n}\n\n// Issue 13317 - std.getopt: endOfOptions broken when it doesn't look like an option\n@system unittest\n{\n    auto endOfOptionsBackup = endOfOptions;\n    scope(exit) endOfOptions = endOfOptionsBackup;\n    endOfOptions = \"endofoptions\";\n    string[] args = [\"program\", \"endofoptions\", \"--option\"];\n    bool b = false;\n    getopt(args, \"option\", &b);\n    assert(!b);\n    assert(args == [\"program\", \"--option\"]);\n}\n\n/** This function prints the passed `Option`s and text in an aligned manner on `stdout`.\n\nThe passed text will be printed first, followed by a newline, then the short\nand long version of every option will be printed. The short and long version\nwill be aligned to the longest option of every `Option` passed. If the option\nis required, then \"Required:\" will be printed after the long version of the\n`Option`. If a help message is present it will be printed next. The format is\nillustrated by this code:\n\n------------\nforeach (it; opt)\n{\n    writefln(\"%*s %*s%s%s\", lengthOfLongestShortOption, it.optShort,\n        lengthOfLongestLongOption, it.optLong,\n        it.required ? \" Required: \" : \" \", it.help);\n}\n------------\n\nParams:\n    text = The text to printed at the beginning of the help output.\n    opt = The `Option` extracted from the `getopt` parameter.\n*/\nvoid defaultGetoptPrinter(string text, Option[] opt)\n{\n    import std.stdio : stdout;\n\n    defaultGetoptFormatter(stdout.lockingTextWriter(), text, opt);\n}\n\n/** This function writes the passed text and `Option` into an output range\nin the manner described in the documentation of function\n`defaultGetoptPrinter`.\n\nParams:\n    output = The output range used to write the help information.\n    text = The text to print at the beginning of the help output.\n    opt = The `Option` extracted from the `getopt` parameter.\n*/\nvoid defaultGetoptFormatter(Output)(Output output, string text, Option[] opt)\n{\n    import std.algorithm.comparison : min, max;\n    import std.format : formattedWrite;\n\n    output.formattedWrite(\"%s\\n\", text);\n\n    size_t ls, ll;\n    bool hasRequired = false;\n    foreach (it; opt)\n    {\n        ls = max(ls, it.optShort.length);\n        ll = max(ll, it.optLong.length);\n\n        hasRequired = hasRequired || it.required;\n    }\n\n    string re = \" Required: \";\n\n    foreach (it; opt)\n    {\n        output.formattedWrite(\"%*s %*s%*s%s\\n\", ls, it.optShort, ll, it.optLong,\n            hasRequired ? re.length : 1, it.required ? re : \" \", it.help);\n    }\n}\n\n@system unittest\n{\n    import std.conv;\n\n    import std.array;\n    import std.string;\n    bool a;\n    auto args = [\"prog\", \"--foo\"];\n    auto t = getopt(args, \"foo|f\", \"Help\", &a);\n    string s;\n    auto app = appender!string();\n    defaultGetoptFormatter(app, \"Some Text\", t.options);\n\n    string helpMsg = app.data;\n    //writeln(helpMsg);\n    assert(helpMsg.length);\n    assert(helpMsg.count(\"\\n\") == 3, to!string(helpMsg.count(\"\\n\")) ~ \" \"\n        ~ helpMsg);\n    assert(helpMsg.indexOf(\"--foo\") != -1);\n    assert(helpMsg.indexOf(\"-f\") != -1);\n    assert(helpMsg.indexOf(\"-h\") != -1);\n    assert(helpMsg.indexOf(\"--help\") != -1);\n    assert(helpMsg.indexOf(\"Help\") != -1);\n\n    string wanted = \"Some Text\\n-f  --foo Help\\n-h --help This help \"\n        ~ \"information.\\n\";\n    assert(wanted == helpMsg);\n}\n\n@system unittest\n{\n    import std.array ;\n    import std.conv;\n    import std.string;\n    bool a;\n    auto args = [\"prog\", \"--foo\"];\n    auto t = getopt(args, config.required, \"foo|f\", \"Help\", &a);\n    string s;\n    auto app = appender!string();\n    defaultGetoptFormatter(app, \"Some Text\", t.options);\n\n    string helpMsg = app.data;\n    //writeln(helpMsg);\n    assert(helpMsg.length);\n    assert(helpMsg.count(\"\\n\") == 3, to!string(helpMsg.count(\"\\n\")) ~ \" \"\n        ~ helpMsg);\n    assert(helpMsg.indexOf(\"Required:\") != -1);\n    assert(helpMsg.indexOf(\"--foo\") != -1);\n    assert(helpMsg.indexOf(\"-f\") != -1);\n    assert(helpMsg.indexOf(\"-h\") != -1);\n    assert(helpMsg.indexOf(\"--help\") != -1);\n    assert(helpMsg.indexOf(\"Help\") != -1);\n\n    string wanted = \"Some Text\\n-f  --foo Required: Help\\n-h --help \"\n        ~ \"          This help information.\\n\";\n    assert(wanted == helpMsg, helpMsg ~ wanted);\n}\n\n@system unittest // Issue 14724\n{\n    bool a;\n    auto args = [\"prog\", \"--help\"];\n    GetoptResult rslt;\n    try\n    {\n        rslt = getopt(args, config.required, \"foo|f\", \"bool a\", &a);\n    }\n    catch (Exception e)\n    {\n        enum errorMsg = \"If the request for help was passed required options\" ~\n                \"must not be set.\";\n        assert(false, errorMsg);\n    }\n\n    assert(rslt.helpWanted);\n}\n\n// throw on duplicate options\n@system unittest\n{\n    import core.exception;\n    auto args = [\"prog\", \"--abc\", \"1\"];\n    int abc, def;\n    assertThrown!AssertError(getopt(args, \"abc\", &abc, \"abc\", &abc));\n    assertThrown!AssertError(getopt(args, \"abc|a\", &abc, \"def|a\", &def));\n    assertNotThrown!AssertError(getopt(args, \"abc\", &abc, \"def\", &def));\n}\n\n@system unittest // Issue 17327 repeated option use\n{\n    long num = 0;\n\n    string[] args = [\"program\", \"--num\", \"3\"];\n    getopt(args, \"n|num\", &num);\n    assert(num == 3);\n\n    args = [\"program\", \"--num\", \"3\", \"--num\", \"5\"];\n    getopt(args, \"n|num\", &num);\n    assert(num == 5);\n\n    args = [\"program\", \"--n\", \"3\", \"--num\", \"5\", \"-n\", \"-7\"];\n    getopt(args, \"n|num\", &num);\n    assert(num == -7);\n\n    void add1() { num++; }\n    void add2(string option) { num += 2; }\n    void addN(string option, string value)\n    {\n        import std.conv : to;\n        num += value.to!long;\n    }\n\n    num = 0;\n    args = [\"program\", \"--add1\", \"--add2\", \"--add1\", \"--add\", \"5\", \"--add2\", \"--add\", \"10\"];\n    getopt(args,\n           \"add1\", \"Add 1 to num\", &add1,\n           \"add2\", \"Add 2 to num\", &add2,\n           \"add\", \"Add N to num\", &addN,);\n    assert(num == 21);\n\n    bool flag = false;\n    args = [\"program\", \"--flag\"];\n    getopt(args, \"f|flag\", \"Boolean\", &flag);\n    assert(flag);\n\n    flag = false;\n    args = [\"program\", \"-f\", \"-f\"];\n    getopt(args, \"f|flag\", \"Boolean\", &flag);\n    assert(flag);\n\n    flag = false;\n    args = [\"program\", \"--flag=true\", \"--flag=false\"];\n    getopt(args, \"f|flag\", \"Boolean\", &flag);\n    assert(!flag);\n\n    flag = false;\n    args = [\"program\", \"--flag=true\", \"--flag=false\", \"-f\"];\n    getopt(args, \"f|flag\", \"Boolean\", &flag);\n    assert(flag);\n}\n\n@safe unittest  // Delegates as callbacks\n{\n    alias TwoArgOptionHandler = void delegate(string option, string value) @safe;\n\n    TwoArgOptionHandler makeAddNHandler(ref long dest)\n    {\n        void addN(ref long dest, string n)\n        {\n            import std.conv : to;\n            dest += n.to!long;\n        }\n\n        return (option, value) => addN(dest, value);\n    }\n\n    long x = 0;\n    long y = 0;\n\n    string[] args =\n        [\"program\", \"--x-plus-1\", \"--x-plus-1\", \"--x-plus-5\", \"--x-plus-n\", \"10\",\n         \"--y-plus-n\", \"25\", \"--y-plus-7\", \"--y-plus-n\", \"15\", \"--y-plus-3\"];\n\n    getopt(args,\n           \"x-plus-1\", \"Add one to x\", delegate void() { x += 1; },\n           \"x-plus-5\", \"Add five to x\", delegate void(string option) { x += 5; },\n           \"x-plus-n\", \"Add NUM to x\", makeAddNHandler(x),\n           \"y-plus-7\", \"Add seven to y\", delegate void() { y += 7; },\n           \"y-plus-3\", \"Add three to y\", delegate void(string option) { y += 3; },\n           \"y-plus-n\", \"Add NUM to x\", makeAddNHandler(y),);\n\n    assert(x == 17);\n    assert(y == 50);\n}\n\n@system unittest // Hyphens at the start of option values; Issue 17650\n{\n    auto args = [\"program\", \"-m\", \"-5\", \"-n\", \"-50\", \"-c\", \"-\", \"-f\", \"-\"];\n\n    int m;\n    int n;\n    char c;\n    string f;\n\n    getopt(args,\n           \"m|mm\", \"integer\", &m,\n           \"n|nn\", \"integer\", &n,\n           \"c|cc\", \"character\", &c,\n           \"f|file\", \"filename or hyphen for stdin\", &f);\n\n    assert(m == -5);\n    assert(n == -50);\n    assert(c == '-');\n    assert(f == \"-\");\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/attributes.d",
    "content": "module std.internal.attributes;\n\n/**\nUsed to annotate `unittest`s which need to be tested in a `-betterC` environment.\n\nSuch `unittest`s will be compiled and executed without linking druntime in, with\na `__traits(getUnitTests, mixin(__MODULE__))` style test runner.\nNote that just like any other `unittest` in phobos, they will also be compiled\nand executed without `-betterC`.\n*/\npackage(std) enum betterC = 1;\n"
  },
  {
    "path": "libphobos/src/std/internal/cstring.d",
    "content": "/**\nHelper functions for working with $(I C strings).\n\nThis module is intended to provide fast, safe and garbage free\nway to work with $(I C strings).\n\nCopyright: Denis Shelomovskij 2013-2014\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: Denis Shelomovskij\n\nMacros:\nCOREREF = $(HTTP dlang.org/phobos/core_$1.html#$2, `core.$1.$2`)\n*/\nmodule std.internal.cstring;\n\n///\n@safe unittest\n{\n    version (Posix)\n    {\n        import core.stdc.stdlib : free;\n        import core.sys.posix.stdlib : setenv;\n        import std.exception : enforce;\n\n        void setEnvironment(scope const(char)[] name, scope const(char)[] value)\n        { enforce(setenv(name.tempCString(), value.tempCString(), 1) != -1); }\n    }\n\n    version (Windows)\n    {\n        import core.sys.windows.windows : SetEnvironmentVariableW;\n        import std.exception : enforce;\n\n        void setEnvironment(scope const(char)[] name, scope const(char)[] value)\n        { enforce(SetEnvironmentVariableW(name.tempCStringW(), value.tempCStringW())); }\n    }\n}\n\nimport std.range;\nimport std.traits;\n\n/**\nCreates temporary 0-terminated $(I C string) with copy of passed text.\n\nParams:\n    To = character type of returned C string\n    str = string or input range to be converted\n\nReturns:\n\nThe value returned is implicitly convertible to $(D const To*) and\nhas two properties: `ptr` to access $(I C string) as $(D const To*)\nand `buffPtr` to access it as `To*`.\n\nThe value returned can be indexed by [] to access it as an array.\n\nThe temporary $(I C string) is valid unless returned object is destroyed.\nThus if returned object is assigned to a variable the temporary is\nvalid unless the variable goes out of scope. If returned object isn't\nassigned to a variable it will be destroyed at the end of creating\nprimary expression.\n\nImplementation_note:\nFor small strings tempCString will use stack allocated buffer,\nfor large strings (approximately 250 characters and more) it will\nallocate temporary one using C's `malloc`.\n\nNote:\nThis function is intended to be used in function call expression (like\n`strlen(str.tempCString())`). Incorrect usage of this function may\nlead to memory corruption.\nSee $(RED WARNING) in $(B Examples) section.\n*/\n\nauto tempCString(To = char, From)(scope From str)\nif (isSomeChar!To && (isInputRange!From || isSomeString!From) &&\n    isSomeChar!(ElementEncodingType!From))\n{\n    alias CF = Unqual!(ElementEncodingType!From);\n\n    auto res = TempCStringBuffer!To.trustedVoidInit(); // expensive to fill _buff[]\n\n    // Note: res._ptr can't point to res._buff as structs are movable.\n\n    To[] p = res._buff;\n    size_t i;\n\n    size_t strLength;\n    static if (hasLength!From)\n    {\n        strLength = str.length;\n    }\n    import std.utf : byUTF;\n    static if (isSomeString!From)\n    {\n        auto r = cast(const(CF)[])str;  // because inout(CF) causes problems with byUTF\n        if (r is null)  // Bugzilla 14980\n        {\n            res._length = 0;\n            res._ptr = null;\n            return res;\n        }\n    }\n    else\n        alias r = str;\n    To[] heapBuffer;\n    foreach (const c; byUTF!(Unqual!To)(r))\n    {\n        if (i + 1 == p.length)\n        {\n            heapBuffer = trustedRealloc(p, strLength, heapBuffer is null);\n            p = heapBuffer;\n        }\n        p[i++] = c;\n    }\n    p[i] = 0;\n    res._length = i;\n    res._ptr = (heapBuffer is null ? res.useStack : &heapBuffer[0]);\n    return res;\n}\n\n///\nnothrow @nogc @system unittest\n{\n    import core.stdc.string;\n\n    string str = \"abc\";\n\n    // Intended usage\n    assert(strlen(str.tempCString()) == 3);\n\n    // Correct usage\n    auto tmp = str.tempCString();\n    assert(strlen(tmp) == 3); // or `tmp.ptr`, or `tmp.buffPtr`\n\n    // $(RED WARNING): $(RED Incorrect usage)\n    auto pInvalid1 = str.tempCString().ptr;\n    const char* pInvalid2 = str.tempCString();\n    // Both pointers refer to invalid memory here as\n    // returned values aren't assigned to a variable and\n    // both primary expressions are ended.\n}\n\n@safe pure nothrow @nogc unittest\n{\n    static inout(C)[] arrayFor(C)(inout(C)* cstr) pure nothrow @nogc @trusted\n    {\n        assert(cstr);\n        size_t length = 0;\n        while (cstr[length])\n            ++length;\n        return cstr[0 .. length];\n    }\n\n    assert(arrayFor(\"abc\".tempCString()) == \"abc\");\n    assert(arrayFor(\"abc\"d.tempCString().ptr) == \"abc\");\n    assert(arrayFor(\"abc\".tempCString!wchar().buffPtr) == \"abc\"w);\n\n    import std.utf : byChar, byWchar;\n    char[300] abc = 'a';\n    assert(arrayFor(tempCString(abc[].byChar).buffPtr) == abc);\n    assert(arrayFor(tempCString(abc[].byWchar).buffPtr) == abc);\n    assert(tempCString(abc[].byChar)[] == abc);\n}\n\n// Bugzilla 14980\npure nothrow @nogc @safe unittest\n{\n    const(char[]) str = null;\n    auto res = tempCString(str);\n    const char* ptr = res;\n    assert(ptr is null);\n}\n\nversion (Windows)\n    alias tempCStringW = tempCString!(wchar, const(char)[]);\n\nprivate struct TempCStringBuffer(To = char)\n{\n@trusted pure nothrow @nogc:\n\n    @disable this();\n    @disable this(this);\n    alias ptr this; /// implicitly covert to raw pointer\n\n    @property inout(To)* buffPtr() inout\n    {\n        return _ptr == useStack ? _buff.ptr : _ptr;\n    }\n\n    @property const(To)* ptr() const\n    {\n        return buffPtr;\n    }\n\n    const(To)[] opIndex() const pure\n    {\n        return buffPtr[0 .. _length];\n    }\n\n    ~this()\n    {\n        if (_ptr != useStack)\n        {\n            import core.memory : pureFree;\n            pureFree(_ptr);\n        }\n    }\n\nprivate:\n    enum To* useStack = () @trusted { return cast(To*) size_t.max; }();\n\n    To* _ptr;\n    size_t _length;        // length of the string\n    version (unittest)\n    // the 'small string optimization'\n    {\n        // smaller size to trigger reallocations. Padding is to account for\n        // unittest/non-unittest cross-compilation (to avoid corruption)\n        To[16 / To.sizeof] _buff;\n        To[(256 - 16) / To.sizeof] _unittest_pad;\n    }\n    else\n    {\n        To[256 / To.sizeof] _buff; // production size\n    }\n\n    static TempCStringBuffer trustedVoidInit() { TempCStringBuffer res = void; return res; }\n}\n\nprivate To[] trustedRealloc(To)(scope To[] buf, size_t strLength, bool bufIsOnStack)\n    @trusted @nogc pure nothrow\n{\n    pragma(inline, false);  // because it's rarely called\n\n    import core.exception : onOutOfMemoryError;\n    import core.memory : pureMalloc, pureRealloc;\n\n    size_t newlen = buf.length * 3 / 2;\n\n    if (bufIsOnStack)\n    {\n        if (newlen <= strLength)\n            newlen = strLength + 1; // +1 for terminating 0\n        auto ptr = cast(To*) pureMalloc(newlen * To.sizeof);\n        if (!ptr)\n            onOutOfMemoryError();\n        ptr[0 .. buf.length] = buf[];\n        return ptr[0 .. newlen];\n    }\n    else\n    {\n        if (buf.length >= size_t.max / (2 * To.sizeof))\n            onOutOfMemoryError();\n        auto ptr = cast(To*) pureRealloc(buf.ptr, newlen * To.sizeof);\n        if (!ptr)\n            onOutOfMemoryError();\n        return ptr[0 .. newlen];\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/math/biguintcore.d",
    "content": "/** Fundamental operations for arbitrary-precision arithmetic\n *\n * These functions are for internal use only.\n */\n/*          Copyright Don Clugston 2008 - 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\n/* References:\n   \"Modern Computer Arithmetic\" (MCA) is the primary reference for all\n    algorithms used in this library.\n  - R.P. Brent and P. Zimmermann, \"Modern Computer Arithmetic\",\n    Version 0.5.9, (Oct 2010).\n  - C. Burkinel and J. Ziegler, \"Fast Recursive Division\", MPI-I-98-1-022,\n    Max-Planck Institute fuer Informatik, (Oct 1998).\n  - G. Hanrot, M. Quercia, and P. Zimmermann, \"The Middle Product Algorithm, I.\",\n    INRIA 4664, (Dec 2002).\n  - M. Bodrato and A. Zanoni, \"What about Toom-Cook Matrices Optimality?\",\n    http://bodrato.it/papers (2006).\n  - A. Fog, \"Optimizing subroutines in assembly language\",\n    www.agner.org/optimize (2008).\n  - A. Fog, \"The microarchitecture of Intel and AMD CPU's\",\n    www.agner.org/optimize (2008).\n  - A. Fog, \"Instruction tables: Lists of instruction latencies, throughputs\n    and micro-operation breakdowns for Intel and AMD CPU's.\", www.agner.org/optimize (2008).\n\nIdioms:\n  Many functions in this module use\n  'func(Tulong)(Tulong x) if (is(Tulong == ulong))' rather than 'func(ulong x)'\n  in order to disable implicit conversion.\n\n*/\nmodule std.internal.math.biguintcore;\n\nversion (D_InlineAsm_X86)\n{\n    static import std.internal.math.biguintx86;\n}\nstatic import std.internal.math.biguintnoasm;\n\nimport std.internal.math.biguintnoasm : BigDigit, KARATSUBALIMIT,\n    KARATSUBASQUARELIMIT;\n\nalias multibyteAdd = multibyteAddSub!('+');\nalias multibyteSub = multibyteAddSub!('-');\n\nprivate import std.traits;\nprivate import std.range.primitives;\npublic import std.ascii : LetterCase;\nimport std.range.primitives;\nimport std.traits;\n\nprivate:\n\n// dipatchers to the right low-level primitives. Added to allow BigInt CTFE for\n// 32 bit systems (issue 14767) although it's used by the other architectures too.\n// See comments below in case it has to be refactored.\nversion (X86)\nuint multibyteAddSub(char op)(uint[] dest, const(uint)[] src1, const (uint)[] src2, uint carry)\n{\n    // must be checked before, otherwise D_InlineAsm_X86 is true.\n    if (__ctfe)\n        return std.internal.math.biguintnoasm.multibyteAddSub!op(dest, src1, src2, carry);\n    // Runtime.\n    else version (D_InlineAsm_X86)\n        return std.internal.math.biguintx86.multibyteAddSub!op(dest, src1, src2, carry);\n    // Runtime if no asm available.\n    else\n        return std.internal.math.biguintnoasm.multibyteAddSub!op(dest, src1, src2, carry);\n}\n// Any other architecture\nelse alias multibyteAddSub = std.internal.math.biguintnoasm.multibyteAddSub;\n\nversion (X86)\nuint multibyteIncrementAssign(char op)(uint[] dest, uint carry)\n{\n    if (__ctfe)\n        return std.internal.math.biguintnoasm.multibyteIncrementAssign!op(dest, carry);\n    else version (D_InlineAsm_X86)\n        return std.internal.math.biguintx86.multibyteIncrementAssign!op(dest, carry);\n    else\n        return std.internal.math.biguintnoasm.multibyteIncrementAssign!op(dest, carry);\n}\nelse alias multibyteIncrementAssign = std.internal.math.biguintnoasm.multibyteIncrementAssign;\n\nversion (X86)\nuint multibyteShl()(uint[] dest, const(uint)[] src, uint numbits)\n{\n    if (__ctfe)\n        return std.internal.math.biguintnoasm.multibyteShl(dest, src, numbits);\n    else version (D_InlineAsm_X86)\n        return std.internal.math.biguintx86.multibyteShl(dest, src, numbits);\n    else\n        return std.internal.math.biguintnoasm.multibyteShl(dest, src, numbits);\n}\nelse alias multibyteShl = std.internal.math.biguintnoasm.multibyteShl;\n\nversion (X86)\nvoid multibyteShr()(uint[] dest, const(uint)[] src, uint numbits)\n{\n    if (__ctfe)\n        std.internal.math.biguintnoasm.multibyteShr(dest, src, numbits);\n    else version (D_InlineAsm_X86)\n        std.internal.math.biguintx86.multibyteShr(dest, src, numbits);\n    else\n        std.internal.math.biguintnoasm.multibyteShr(dest, src, numbits);\n}\nelse alias multibyteShr = std.internal.math.biguintnoasm.multibyteShr;\n\nversion (X86)\nuint multibyteMul()(uint[] dest, const(uint)[] src, uint multiplier, uint carry)\n{\n    if (__ctfe)\n        return std.internal.math.biguintnoasm.multibyteMul(dest, src, multiplier, carry);\n    else version (D_InlineAsm_X86)\n        return std.internal.math.biguintx86.multibyteMul(dest, src, multiplier, carry);\n    else\n        return std.internal.math.biguintnoasm.multibyteMul(dest, src, multiplier, carry);\n}\nelse alias multibyteMul = std.internal.math.biguintnoasm.multibyteMul;\n\nversion (X86)\nuint multibyteMulAdd(char op)(uint[] dest, const(uint)[] src, uint multiplier, uint carry)\n{\n    if (__ctfe)\n        return std.internal.math.biguintnoasm.multibyteMulAdd!op(dest, src, multiplier, carry);\n    else version (D_InlineAsm_X86)\n        return std.internal.math.biguintx86.multibyteMulAdd!op(dest, src, multiplier, carry);\n    else\n        return std.internal.math.biguintnoasm.multibyteMulAdd!op(dest, src, multiplier, carry);\n}\nelse alias multibyteMulAdd = std.internal.math.biguintnoasm.multibyteMulAdd;\n\nversion (X86)\nvoid multibyteMultiplyAccumulate()(uint[] dest, const(uint)[] left, const(uint)[] right)\n{\n    if (__ctfe)\n        std.internal.math.biguintnoasm.multibyteMultiplyAccumulate(dest, left, right);\n    else version (D_InlineAsm_X86)\n        std.internal.math.biguintx86.multibyteMultiplyAccumulate(dest, left, right);\n    else\n        std.internal.math.biguintnoasm.multibyteMultiplyAccumulate(dest, left, right);\n}\nelse alias multibyteMultiplyAccumulate = std.internal.math.biguintnoasm.multibyteMultiplyAccumulate;\n\nversion (X86)\nuint multibyteDivAssign()(uint[] dest, uint divisor, uint overflow)\n{\n    if (__ctfe)\n        return std.internal.math.biguintnoasm.multibyteDivAssign(dest, divisor, overflow);\n    else version (D_InlineAsm_X86)\n        return std.internal.math.biguintx86.multibyteDivAssign(dest, divisor, overflow);\n    else\n        return std.internal.math.biguintnoasm.multibyteDivAssign(dest, divisor, overflow);\n}\nelse alias multibyteDivAssign = std.internal.math.biguintnoasm.multibyteDivAssign;\n\nversion (X86)\nvoid multibyteAddDiagonalSquares()(uint[] dest, const(uint)[] src)\n{\n    if (__ctfe)\n        std.internal.math.biguintnoasm.multibyteAddDiagonalSquares(dest, src);\n    else version (D_InlineAsm_X86)\n        std.internal.math.biguintx86.multibyteAddDiagonalSquares(dest, src);\n    else\n        std.internal.math.biguintnoasm.multibyteAddDiagonalSquares(dest, src);\n}\nelse alias multibyteAddDiagonalSquares = std.internal.math.biguintnoasm.multibyteAddDiagonalSquares;\n\nversion (X86)\nvoid multibyteTriangleAccumulate()(uint[] dest, const(uint)[] x)\n{\n    if (__ctfe)\n        std.internal.math.biguintnoasm.multibyteTriangleAccumulate(dest, x);\n    else version (D_InlineAsm_X86)\n        std.internal.math.biguintx86.multibyteTriangleAccumulate(dest, x);\n    else\n        std.internal.math.biguintnoasm.multibyteTriangleAccumulate(dest, x);\n}\nelse alias multibyteTriangleAccumulate = std.internal.math.biguintnoasm.multibyteTriangleAccumulate;\n\nversion (X86)\nvoid multibyteSquare()(BigDigit[] result, const(BigDigit)[] x)\n{\n    if (__ctfe)\n        std.internal.math.biguintnoasm.multibyteSquare(result, x);\n    else version (D_InlineAsm_X86)\n        std.internal.math.biguintx86.multibyteSquare(result, x);\n    else\n        std.internal.math.biguintnoasm.multibyteSquare(result, x);\n}\nelse alias multibyteSquare = std.internal.math.biguintnoasm.multibyteSquare;\n\n// Limits for when to switch between algorithms.\n// Half the size of the data cache.\n@nogc nothrow pure size_t getCacheLimit()\n{\n    import core.cpuid : dataCaches;\n    return (cast(size_t function() @nogc nothrow pure)\n        (() => dataCaches[0].size * 1024 / 2))();\n}\nenum size_t FASTDIVLIMIT = 100; // crossover to recursive division\n\n\n// These constants are used by shift operations\nstatic if (BigDigit.sizeof == int.sizeof)\n{\n    enum { LG2BIGDIGITBITS = 5, BIGDIGITSHIFTMASK = 31 }\n    alias BIGHALFDIGIT = ushort;\n}\nelse static if (BigDigit.sizeof == long.sizeof)\n{\n    alias BIGHALFDIGIT = uint;\n    enum { LG2BIGDIGITBITS = 6, BIGDIGITSHIFTMASK = 63 }\n}\nelse static assert(0, \"Unsupported BigDigit size\");\n\nimport std.exception : assumeUnique;\nimport std.traits : isIntegral;\nenum BigDigitBits = BigDigit.sizeof*8;\ntemplate maxBigDigits(T)\nif (isIntegral!T)\n{\n    enum maxBigDigits = (T.sizeof+BigDigit.sizeof-1)/BigDigit.sizeof;\n}\n\nstatic immutable BigDigit[] ZERO = [0];\nstatic immutable BigDigit[] ONE = [1];\nstatic immutable BigDigit[] TWO = [2];\nstatic immutable BigDigit[] TEN = [10];\n\n\npublic:\n\n/// BigUint performs memory management and wraps the low-level calls.\nstruct BigUint\n{\nprivate:\n    pure invariant()\n    {\n        assert( data.length >= 1 && (data.length == 1 || data[$-1] != 0 ));\n    }\n\n    immutable(BigDigit) [] data = ZERO;\n\n    this(immutable(BigDigit) [] x) pure nothrow @nogc @safe\n    {\n       data = x;\n    }\n  package(std)  // used from: std.bigint\n    this(T)(T x) pure nothrow @safe if (isIntegral!T)\n    {\n        opAssign(x);\n    }\n\n    enum trustedAssumeUnique = function(BigDigit[] input) pure @trusted @nogc {\n        return assumeUnique(input);\n    };\npublic:\n    // Length in uints\n    @property size_t uintLength() pure nothrow const @safe @nogc\n    {\n        static if (BigDigit.sizeof == uint.sizeof)\n        {\n            return data.length;\n        }\n        else static if (BigDigit.sizeof == ulong.sizeof)\n        {\n            return data.length * 2 -\n            ((data[$-1] & 0xFFFF_FFFF_0000_0000L) ? 1 : 0);\n        }\n    }\n    @property size_t ulongLength() pure nothrow const @safe @nogc\n    {\n        static if (BigDigit.sizeof == uint.sizeof)\n        {\n            return (data.length + 1) >> 1;\n        }\n        else static if (BigDigit.sizeof == ulong.sizeof)\n        {\n            return data.length;\n        }\n    }\n\n    // The value at (cast(ulong[]) data)[n]\n    ulong peekUlong(size_t n) pure nothrow const @safe @nogc\n    {\n        static if (BigDigit.sizeof == int.sizeof)\n        {\n            if (data.length == n*2 + 1) return data[n*2];\n            return data[n*2] + ((cast(ulong) data[n*2 + 1]) << 32 );\n        }\n        else static if (BigDigit.sizeof == long.sizeof)\n        {\n            return data[n];\n        }\n    }\n\n    uint peekUint(size_t n) pure nothrow const @safe @nogc\n    {\n        static if (BigDigit.sizeof == int.sizeof)\n        {\n            return data[n];\n        }\n        else\n        {\n            immutable x = data[n >> 1];\n            return (n & 1) ? cast(uint)(x >> 32) : cast(uint) x;\n        }\n    }\n\n    ///\n    void opAssign(Tulong)(Tulong u) pure nothrow @safe if (is (Tulong == ulong))\n    {\n        if (u == 0) data = ZERO;\n        else if (u == 1) data = ONE;\n        else if (u == 2) data = TWO;\n        else if (u == 10) data = TEN;\n        else\n        {\n            static if (BigDigit.sizeof == int.sizeof)\n            {\n                uint ulo = cast(uint)(u & 0xFFFF_FFFF);\n                uint uhi = cast(uint)(u >> 32);\n                if (uhi == 0)\n                {\n                    data = [ulo];\n                }\n                else\n                {\n                    data = [ulo, uhi];\n                }\n            }\n            else static if (BigDigit.sizeof == long.sizeof)\n            {\n                data = [u];\n            }\n        }\n    }\n    void opAssign(Tdummy = void)(BigUint y) pure nothrow @nogc @safe\n    {\n        this.data = y.data;\n    }\n\n    ///\n    int opCmp(Tdummy = void)(const BigUint y) pure nothrow @nogc const @safe\n    {\n        if (data.length != y.data.length)\n            return (data.length > y.data.length) ?  1 : -1;\n        size_t k = highestDifferentDigit(data, y.data);\n        if (data[k] == y.data[k])\n            return 0;\n        return data[k] > y.data[k] ? 1 : -1;\n    }\n\n    ///\n    int opCmp(Tulong)(Tulong y) pure nothrow @nogc const @safe if (is (Tulong == ulong))\n    {\n        if (data.length > maxBigDigits!Tulong)\n            return 1;\n\n        foreach_reverse (i; 0 .. maxBigDigits!Tulong)\n        {\n            BigDigit tmp = cast(BigDigit)(y>>(i*BigDigitBits));\n            if (tmp == 0)\n                if (data.length >= i+1)\n                {\n                    // Since ZERO is [0], so we cannot simply return 1 here, as\n                    // data[i] would be 0 for i == 0 in that case.\n                    return (data[i] > 0) ? 1 : 0;\n                }\n                else\n                    continue;\n            else\n                if (i+1 > data.length)\n                    return -1;\n                else if (tmp != data[i])\n                    return data[i] > tmp ? 1 : -1;\n        }\n        return 0;\n    }\n\n    bool opEquals(Tdummy = void)(ref const BigUint y) pure nothrow @nogc const @safe\n    {\n           return y.data[] == data[];\n    }\n\n    bool opEquals(Tdummy = void)(ulong y) pure nothrow @nogc const @safe\n    {\n        if (data.length > 2)\n            return false;\n        uint ylo = cast(uint)(y & 0xFFFF_FFFF);\n        uint yhi = cast(uint)(y >> 32);\n        if (data.length == 2 && data[1]!=yhi)\n            return false;\n        if (data.length == 1 && yhi != 0)\n            return false;\n        return (data[0] == ylo);\n    }\n\n    bool isZero() pure const nothrow @safe @nogc\n    {\n        return data.length == 1 && data[0] == 0;\n    }\n\n    size_t numBytes() pure nothrow const @safe @nogc\n    {\n        return data.length * BigDigit.sizeof;\n    }\n\n    // the extra bytes are added to the start of the string\n    char [] toDecimalString(int frontExtraBytes) const pure nothrow\n    {\n        immutable predictlength = 20+20*(data.length/2); // just over 19\n        char [] buff = new char[frontExtraBytes + predictlength];\n        ptrdiff_t sofar = biguintToDecimal(buff, data.dup);\n        return buff[sofar-frontExtraBytes..$];\n    }\n\n    /** Convert to a hex string, printing a minimum number of digits 'minPadding',\n     *  allocating an additional 'frontExtraBytes' at the start of the string.\n     *  Padding is done with padChar, which may be '0' or ' '.\n     *  'separator' is a digit separation character. If non-zero, it is inserted\n     *  between every 8 digits.\n     *  Separator characters do not contribute to the minPadding.\n     */\n    char [] toHexString(int frontExtraBytes, char separator = 0,\n            int minPadding=0, char padChar = '0',\n            LetterCase letterCase = LetterCase.upper) const pure nothrow @safe\n    {\n        // Calculate number of extra padding bytes\n        size_t extraPad = (minPadding > data.length * 2 * BigDigit.sizeof)\n            ? minPadding - data.length * 2 * BigDigit.sizeof : 0;\n\n        // Length not including separator bytes\n        size_t lenBytes = data.length * 2 * BigDigit.sizeof;\n\n        // Calculate number of separator bytes\n        size_t mainSeparatorBytes = separator ? (lenBytes  / 8) - 1 : 0;\n        immutable totalSeparatorBytes = separator ? ((extraPad + lenBytes + 7) / 8) - 1: 0;\n\n        char [] buff = new char[lenBytes + extraPad + totalSeparatorBytes + frontExtraBytes];\n        biguintToHex(buff[$ - lenBytes - mainSeparatorBytes .. $], data, separator, letterCase);\n        if (extraPad > 0)\n        {\n            if (separator)\n            {\n                size_t start = frontExtraBytes; // first index to pad\n                if (extraPad &7)\n                {\n                    // Do 1 to 7 extra zeros.\n                    buff[frontExtraBytes .. frontExtraBytes + (extraPad & 7)] = padChar;\n                    buff[frontExtraBytes + (extraPad & 7)] = (padChar == ' ' ? ' ' : separator);\n                    start += (extraPad & 7) + 1;\n                }\n                for (int i=0; i< (extraPad >> 3); ++i)\n                {\n                    buff[start .. start + 8] = padChar;\n                    buff[start + 8] = (padChar == ' ' ? ' ' : separator);\n                    start += 9;\n                }\n            }\n            else\n            {\n                buff[frontExtraBytes .. frontExtraBytes + extraPad]=padChar;\n            }\n        }\n        int z = frontExtraBytes;\n        if (lenBytes > minPadding)\n        {\n            // Strip leading zeros.\n            ptrdiff_t maxStrip = lenBytes - minPadding;\n            while (z< buff.length-1 && (buff[z]=='0' || buff[z]==padChar) && maxStrip>0)\n            {\n                ++z;\n                --maxStrip;\n            }\n        }\n        if (padChar!='0')\n        {\n            // Convert leading zeros into padChars.\n            for (size_t k= z; k< buff.length-1 && (buff[k]=='0' || buff[k]==padChar); ++k)\n            {\n                if (buff[k]=='0') buff[k]=padChar;\n            }\n        }\n        return buff[z-frontExtraBytes..$];\n    }\n\n    /**\n     * Convert to an octal string.\n     */\n    char[] toOctalString() const\n    {\n        auto predictLength = 1 + data.length*BigDigitBits / 3;\n        char[] buff = new char[predictLength];\n        size_t firstNonZero = biguintToOctal(buff, data);\n        return buff[firstNonZero .. $];\n    }\n\n    // return false if invalid character found\n    bool fromHexString(Range)(Range s) if (\n        isBidirectionalRange!Range && isSomeChar!(ElementType!Range))\n    {\n        import std.range : walkLength;\n\n        //Strip leading zeros\n        while (!s.empty && s.front == '0')\n            s.popFront;\n\n        if (s.empty)\n        {\n            data = ZERO;\n            return true;\n        }\n\n        immutable len = (s.save.walkLength + 15) / 4;\n        auto tmp = new BigDigit[len + 1];\n        uint part, sofar, partcount;\n\n        foreach_reverse (character; s)\n        {\n            if (character == '_')\n                continue;\n\n            uint x;\n            if (character >= '0' && character <= '9')\n            {\n                x = character - '0';\n            }\n            else if (character >= 'A' && character <= 'F')\n            {\n                x = character - 'A' + 10;\n            }\n            else if (character >= 'a' && character <= 'f')\n            {\n                x = character - 'a' + 10;\n            }\n            else\n            {\n                return false;\n            }\n\n            part >>= 4;\n            part |= (x << (32 - 4));\n            ++partcount;\n\n            if (partcount == 8)\n            {\n                tmp[sofar] = part;\n                ++sofar;\n                partcount = 0;\n                part = 0;\n            }\n        }\n        if (part)\n        {\n            for ( ; partcount != 8; ++partcount) part >>= 4;\n            tmp[sofar] = part;\n            ++sofar;\n        }\n        if (sofar == 0)\n            data = ZERO;\n        else\n            data = trustedAssumeUnique(tmp[0 .. sofar]);\n\n        return true;\n    }\n\n    // return true if OK; false if erroneous characters found\n    bool fromDecimalString(Range)(Range s) if (\n        isForwardRange!Range && isSomeChar!(ElementType!Range))\n    {\n        import std.range : walkLength;\n\n        while (!s.empty && s.front == '0')\n        {\n            s.popFront;\n        }\n\n        if (s.empty)\n        {\n            data = ZERO;\n            return true;\n        }\n\n        auto predict_length = (18 * 2 + 2 * s.save.walkLength) / 19;\n        auto tmp = new BigDigit[predict_length];\n\n        tmp.length = biguintFromDecimal(tmp, s);\n\n        data = trustedAssumeUnique(tmp);\n        return true;\n    }\n\n    ////////////////////////\n    //\n    // All of these member functions create a new BigUint.\n\n    // return x >> y\n    BigUint opShr(Tulong)(Tulong y) pure nothrow const if (is (Tulong == ulong))\n    {\n        assert(y>0);\n        uint bits = cast(uint) y & BIGDIGITSHIFTMASK;\n        if ((y >> LG2BIGDIGITBITS) >= data.length) return BigUint(ZERO);\n        uint words = cast(uint)(y >> LG2BIGDIGITBITS);\n        if (bits == 0)\n        {\n            return BigUint(data[words..$]);\n        }\n        else\n        {\n            uint [] result = new BigDigit[data.length - words];\n            multibyteShr(result, data[words..$], bits);\n\n            if (result.length > 1 && result[$-1] == 0)\n                return BigUint(trustedAssumeUnique(result[0 .. $-1]));\n            else\n                return BigUint(trustedAssumeUnique(result));\n        }\n    }\n\n    // return x << y\n    BigUint opShl(Tulong)(Tulong y) pure nothrow const if (is (Tulong == ulong))\n    {\n        assert(y>0);\n        if (isZero()) return this;\n        uint bits = cast(uint) y & BIGDIGITSHIFTMASK;\n        assert((y >> LG2BIGDIGITBITS) < cast(ulong)(uint.max));\n        uint words = cast(uint)(y >> LG2BIGDIGITBITS);\n        BigDigit [] result = new BigDigit[data.length + words+1];\n        result[0 .. words] = 0;\n        if (bits == 0)\n        {\n            result[words .. words+data.length] = data[];\n            return BigUint(trustedAssumeUnique(result[0 .. words+data.length]));\n        }\n        else\n        {\n            immutable c = multibyteShl(result[words .. words+data.length], data, bits);\n            if (c == 0) return BigUint(trustedAssumeUnique(result[0 .. words+data.length]));\n            result[$-1] = c;\n            return BigUint(trustedAssumeUnique(result));\n        }\n    }\n\n    // If wantSub is false, return x + y, leaving sign unchanged\n    // If wantSub is true, return abs(x - y), negating sign if x < y\n    static BigUint addOrSubInt(Tulong)(const BigUint x, Tulong y,\n            bool wantSub, ref bool sign) pure nothrow if (is(Tulong == ulong))\n    {\n        BigUint r;\n        if (wantSub)\n        {   // perform a subtraction\n            if (x.data.length > 2)\n            {\n                r.data = cast(immutable) subInt(x.data, y);\n            }\n            else\n            {   // could change sign!\n                ulong xx = x.data[0];\n                if (x.data.length > 1)\n                    xx += (cast(ulong) x.data[1]) << 32;\n                ulong d;\n                if (xx <= y)\n                {\n                    d = y - xx;\n                    sign = !sign;\n                }\n                else\n                {\n                    d = xx - y;\n                }\n                if (d == 0)\n                {\n                    r = 0UL;\n                    sign = false;\n                    return r;\n                }\n                if (d > uint.max)\n                {\n                    r.data = [cast(uint)(d & 0xFFFF_FFFF), cast(uint)(d >> 32)];\n                }\n                else\n                {\n                    r.data = [cast(uint)(d & 0xFFFF_FFFF)];\n                }\n            }\n        }\n        else\n        {\n            r.data = cast(immutable) addInt(x.data, y);\n        }\n        return r;\n    }\n\n    // If wantSub is false, return x + y, leaving sign unchanged.\n    // If wantSub is true, return abs(x - y), negating sign if x<y\n    static BigUint addOrSub(BigUint x, BigUint y, bool wantSub, bool *sign)\n        pure nothrow\n    {\n        BigUint r;\n        if (wantSub)\n        {   // perform a subtraction\n            bool negative;\n            r.data = cast(immutable) sub(x.data, y.data, &negative);\n            *sign ^= negative;\n            if (r.isZero())\n            {\n                *sign = false;\n            }\n        }\n        else\n        {\n            r.data = cast(immutable) add(x.data, y.data);\n        }\n        return r;\n    }\n\n\n    //  return x*y.\n    //  y must not be zero.\n    static BigUint mulInt(T = ulong)(BigUint x, T y) pure nothrow\n    {\n        if (y == 0 || x == 0) return BigUint(ZERO);\n        uint hi = cast(uint)(y >>> 32);\n        uint lo = cast(uint)(y & 0xFFFF_FFFF);\n        uint [] result = new BigDigit[x.data.length+1+(hi != 0)];\n        result[x.data.length] = multibyteMul(result[0 .. x.data.length], x.data, lo, 0);\n        if (hi != 0)\n        {\n            result[x.data.length+1] = multibyteMulAdd!('+')(result[1 .. x.data.length+1],\n                x.data, hi, 0);\n        }\n        return BigUint(removeLeadingZeros(trustedAssumeUnique(result)));\n    }\n\n    /*  return x * y.\n     */\n    static BigUint mul(BigUint x, BigUint y) pure nothrow\n    {\n        if (y == 0 || x == 0)\n            return BigUint(ZERO);\n        auto len = x.data.length + y.data.length;\n        BigDigit [] result = new BigDigit[len];\n        if (y.data.length > x.data.length)\n        {\n            mulInternal(result, y.data, x.data);\n        }\n        else\n        {\n            if (x.data[]==y.data[]) squareInternal(result, x.data);\n            else mulInternal(result, x.data, y.data);\n        }\n        // the highest element could be zero,\n        // in which case we need to reduce the length\n        return BigUint(removeLeadingZeros(trustedAssumeUnique(result)));\n    }\n\n    // return x / y\n    static BigUint divInt(T)(BigUint x, T y_) pure nothrow\n    if ( is(Unqual!T == uint) )\n    {\n        uint y = y_;\n        if (y == 1)\n            return x;\n        uint [] result = new BigDigit[x.data.length];\n        if ((y&(-y))==y)\n        {\n            assert(y != 0, \"BigUint division by zero\");\n            // perfect power of 2\n            uint b = 0;\n            for (;y != 1; y>>=1)\n            {\n                ++b;\n            }\n            multibyteShr(result, x.data, b);\n        }\n        else\n        {\n            result[] = x.data[];\n            cast(void) multibyteDivAssign(result, y, 0);\n        }\n        return BigUint(removeLeadingZeros(trustedAssumeUnique(result)));\n    }\n\n    static BigUint divInt(T)(BigUint x, T y) pure nothrow\n    if ( is(Unqual!T == ulong) )\n    {\n        if (y <= uint.max)\n            return divInt!uint(x, cast(uint) y);\n        if (x.data.length < 2)\n            return BigUint(ZERO);\n        uint hi = cast(uint)(y >>> 32);\n        uint lo = cast(uint)(y & 0xFFFF_FFFF);\n        immutable uint[2] z = [lo, hi];\n        BigDigit[] result = new BigDigit[x.data.length - z.length + 1];\n        divModInternal(result, null, x.data, z[]);\n        return BigUint(removeLeadingZeros(trustedAssumeUnique(result)));\n    }\n\n    // return x % y\n    static uint modInt(T)(BigUint x, T y_) pure if ( is(Unqual!T == uint) )\n    {\n        import core.memory : GC;\n        uint y = y_;\n        assert(y != 0);\n        if ((y&(-y)) == y)\n        {   // perfect power of 2\n            return x.data[0] & (y-1);\n        }\n        else\n        {\n            // horribly inefficient - malloc, copy, & store are unnecessary.\n            uint [] wasteful = new BigDigit[x.data.length];\n            wasteful[] = x.data[];\n            immutable rem = multibyteDivAssign(wasteful, y, 0);\n            () @trusted { GC.free(wasteful.ptr); } ();\n            return rem;\n        }\n    }\n\n    // return x / y\n    static BigUint div(BigUint x, BigUint y) pure nothrow\n    {\n        if (y.data.length > x.data.length)\n            return BigUint(ZERO);\n        if (y.data.length == 1)\n            return divInt(x, y.data[0]);\n        BigDigit [] result = new BigDigit[x.data.length - y.data.length + 1];\n           divModInternal(result, null, x.data, y.data);\n        return BigUint(removeLeadingZeros(trustedAssumeUnique(result)));\n    }\n\n    // return x % y\n    static BigUint mod(BigUint x, BigUint y) pure nothrow\n    {\n        if (y.data.length > x.data.length) return x;\n        if (y.data.length == 1)\n        {\n            return BigUint([modInt(x, y.data[0])]);\n        }\n        BigDigit [] result = new BigDigit[x.data.length - y.data.length + 1];\n        BigDigit [] rem = new BigDigit[y.data.length];\n        divModInternal(result, rem, x.data, y.data);\n        return BigUint(removeLeadingZeros(trustedAssumeUnique(rem)));\n    }\n\n    // Return x / y in quotient, x % y in remainder\n    static void divMod(BigUint x, BigUint y, out BigUint quotient, out BigUint remainder) pure nothrow\n    {\n        if (y.data.length > x.data.length)\n        {\n            quotient = 0uL;\n            remainder = x;\n        }\n        else if (y.data.length == 1)\n        {\n            quotient = divInt(x, y.data[0]);\n            remainder = BigUint([modInt(x, y.data[0])]);\n        }\n        else\n        {\n            BigDigit[] quot = new BigDigit[x.data.length - y.data.length + 1];\n            BigDigit[] rem = new BigDigit[y.data.length];\n            divModInternal(quot, rem, x.data, y.data);\n            quotient = BigUint(removeLeadingZeros(trustedAssumeUnique(quot)));\n            remainder = BigUint(removeLeadingZeros(trustedAssumeUnique(rem)));\n        }\n    }\n\n    // return x op y\n    static BigUint bitwiseOp(string op)(BigUint x, BigUint y, bool xSign, bool ySign, ref bool resultSign)\n    pure nothrow @safe if (op == \"|\" || op == \"^\" || op == \"&\")\n    {\n        auto d1 = includeSign(x.data, y.uintLength, xSign);\n        auto d2 = includeSign(y.data, x.uintLength, ySign);\n\n        foreach (i; 0 .. d1.length)\n        {\n            mixin(\"d1[i] \" ~ op ~ \"= d2[i];\");\n        }\n\n        mixin(\"resultSign = xSign \" ~ op ~ \" ySign;\");\n\n        if (resultSign)\n        {\n            twosComplement(d1, d1);\n        }\n\n        return BigUint(removeLeadingZeros(trustedAssumeUnique(d1)));\n    }\n\n    /**\n     * Return a BigUint which is x raised to the power of y.\n     * Method: Powers of 2 are removed from x, then left-to-right binary\n     * exponentiation is used.\n     * Memory allocation is minimized: at most one temporary BigUint is used.\n     */\n    static BigUint pow(BigUint x, ulong y) pure nothrow\n    {\n        // Deal with the degenerate cases first.\n        if (y == 0) return BigUint(ONE);\n        if (y == 1) return x;\n        if (x == 0 || x == 1) return x;\n\n        BigUint result;\n\n        // Simplify, step 1: Remove all powers of 2.\n        uint firstnonzero = firstNonZeroDigit(x.data);\n        // Now we know x = x[firstnonzero..$] * (2^^(firstnonzero*BigDigitBits))\n        // where BigDigitBits = BigDigit.sizeof * 8\n\n        // See if x[firstnonzero..$] can now fit into a single digit.\n        bool singledigit = ((x.data.length - firstnonzero) == 1);\n        // If true, then x0 is that digit\n        // and the result will be (x0 ^^ y) * (2^^(firstnonzero*y*BigDigitBits))\n        BigDigit x0 = x.data[firstnonzero];\n        assert(x0 != 0);\n        // Length of the non-zero portion\n        size_t nonzerolength = x.data.length - firstnonzero;\n        ulong y0;\n        uint evenbits = 0; // number of even bits in the bottom of x\n        while (!(x0 & 1))\n        {\n            x0 >>= 1;\n            ++evenbits;\n        }\n\n        if (x.data.length- firstnonzero == 2)\n        {\n            // Check for a single digit straddling a digit boundary\n            const BigDigit x1 = x.data[firstnonzero+1];\n            if ((x1 >> evenbits) == 0)\n            {\n                x0 |= (x1 << (BigDigit.sizeof * 8 - evenbits));\n                singledigit = true;\n            }\n        }\n        // Now if (singledigit), x^^y  = (x0 ^^ y) * 2^^(evenbits * y) * 2^^(firstnonzero*y*BigDigitBits))\n\n        uint evenshiftbits = 0; // Total powers of 2 to shift by, at the end\n\n        // Simplify, step 2: For singledigits, see if we can trivially reduce y\n\n        BigDigit finalMultiplier = 1UL;\n\n        if (singledigit)\n        {\n            // x fits into a single digit. Raise it to the highest power we can\n            // that still fits into a single digit, then reduce the exponent accordingly.\n            // We're quite likely to have a residual multiply at the end.\n            // For example, 10^^100 = (((5^^13)^^7) * 5^^9) * 2^^100.\n            // and 5^^13 still fits into a uint.\n            evenshiftbits  = cast(uint)( (evenbits * y) & BIGDIGITSHIFTMASK);\n            if (x0 == 1)\n            {   // Perfect power of 2\n                result = 1UL;\n                return result << (evenbits + firstnonzero * 8 * BigDigit.sizeof) * y;\n            }\n            immutable p = highestPowerBelowUintMax(x0);\n            if (y <= p)\n            {   // Just do it with pow\n                result = cast(ulong) intpow(x0, y);\n                if (evenbits + firstnonzero == 0)\n                    return result;\n                return result << (evenbits + firstnonzero * 8 * BigDigit.sizeof) * y;\n            }\n            y0 = y / p;\n            finalMultiplier = intpow(x0, y - y0*p);\n            x0 = intpow(x0, p);\n            // Result is x0\n            nonzerolength = 1;\n        }\n        // Now if (singledigit), x^^y  = finalMultiplier * (x0 ^^ y0) * 2^^(evenbits * y) * 2^^(firstnonzero*y*BigDigitBits))\n\n        // Perform a crude check for overflow and allocate result buffer.\n        // The length required is y * lg2(x) bits.\n        // which will always fit into y*x.length digits. But this is\n        // a gross overestimate if x is small (length 1 or 2) and the highest\n        // digit is nearly empty.\n        // A better estimate is:\n        //   y * lg2(x[$-1]/BigDigit.max) + y * (x.length - 1) digits,\n        //  and the first term is always between\n        //  y * (bsr(x.data[$-1]) + 1) / BIGDIGITBITS and\n        //  y * (bsr(x.data[$-1]) + 2) / BIGDIGITBITS\n        // For single digit payloads, we already have\n        //   x^^y  = finalMultiplier * (x0 ^^ y0) * 2^^(evenbits * y) * 2^^(firstnonzero*y*BigDigitBits))\n        // and x0 is almost a full digit, so it's a tight estimate.\n        // Number of digits is therefore 1 + x0.length*y0 + (evenbits*y)/BIGDIGIT + firstnonzero*y\n        // Note that the divisions must be rounded up.\n\n        // Estimated length in BigDigits\n        immutable estimatelength = singledigit\n            ? 1 + y0 + ((evenbits*y  + BigDigit.sizeof * 8 - 1) / (BigDigit.sizeof *8)) + firstnonzero*y\n            :  x.data.length * y;\n        // Imprecise check for overflow. Makes the extreme cases easier to debug\n        // (less extreme overflow will result in an out of memory error).\n        if (estimatelength > uint.max/(4*BigDigit.sizeof))\n            assert(0, \"Overflow in BigInt.pow\");\n\n        // The result buffer includes space for all the trailing zeros\n        BigDigit [] resultBuffer = new BigDigit[cast(size_t) estimatelength];\n\n        // Do all the powers of 2!\n        size_t result_start = cast(size_t)( firstnonzero * y\n            + (singledigit ? ((evenbits * y) >> LG2BIGDIGITBITS) : 0));\n\n        resultBuffer[0 .. result_start] = 0;\n        BigDigit [] t1 = resultBuffer[result_start..$];\n        BigDigit [] r1;\n\n        if (singledigit)\n        {\n            r1 = t1[0 .. 1];\n            r1[0] = x0;\n            y = y0;\n        }\n        else\n        {\n            // It's not worth right shifting by evenbits unless we also shrink the length after each\n            // multiply or squaring operation. That might still be worthwhile for large y.\n            r1 = t1[0 .. x.data.length - firstnonzero];\n            r1[0..$] = x.data[firstnonzero..$];\n        }\n\n        if (y>1)\n        {   // Set r1 = r1 ^^ y.\n            // The secondary buffer only needs space for the multiplication results\n            BigDigit [] t2 = new BigDigit[resultBuffer.length - result_start];\n            BigDigit [] r2;\n\n            int shifts = 63; // num bits in a long\n            while (!(y & 0x8000_0000_0000_0000L))\n            {\n                y <<= 1;\n                --shifts;\n            }\n            y <<=1;\n\n            while (y != 0)\n            {\n                // For each bit of y: Set r1 =  r1 * r1\n                // If the bit is 1, set r1 = r1 * x\n                // Eg, if y is 0b101, result = ((x^^2)^^2)*x == x^^5.\n                // Optimization opportunity: if more than 2 bits in y are set,\n                // it's usually possible to reduce the number of multiplies\n                // by caching odd powers of x. eg for y = 54,\n                // (0b110110), set u = x^^3, and result is ((u^^8)*u)^^2\n                r2 = t2[0 .. r1.length*2];\n                squareInternal(r2, r1);\n                if (y & 0x8000_0000_0000_0000L)\n                {\n                    r1 = t1[0 .. r2.length + nonzerolength];\n                    if (singledigit)\n                    {\n                        r1[$-1] = multibyteMul(r1[0 .. $-1], r2, x0, 0);\n                    }\n                    else\n                    {\n                        mulInternal(r1, r2, x.data[firstnonzero..$]);\n                    }\n                }\n                else\n                {\n                    r1 = t1[0 .. r2.length];\n                    r1[] = r2[];\n                }\n                y <<=1;\n                shifts--;\n            }\n            while (shifts>0)\n            {\n                r2 = t2[0 .. r1.length * 2];\n                squareInternal(r2, r1);\n                r1 = t1[0 .. r2.length];\n                r1[] = r2[];\n                --shifts;\n            }\n        }\n\n        if (finalMultiplier != 1)\n        {\n            const BigDigit carry = multibyteMul(r1, r1, finalMultiplier, 0);\n            if (carry)\n            {\n                r1 = t1[0 .. r1.length + 1];\n                r1[$-1] = carry;\n            }\n        }\n        if (evenshiftbits)\n        {\n            const BigDigit carry = multibyteShl(r1, r1, evenshiftbits);\n            if (carry != 0)\n            {\n                r1 = t1[0 .. r1.length + 1];\n                r1[$ - 1] = carry;\n            }\n        }\n        while (r1[$ - 1]==0)\n        {\n            r1=r1[0 .. $ - 1];\n        }\n        return BigUint(trustedAssumeUnique(resultBuffer[0 .. result_start + r1.length]));\n    }\n\n    // Implement toHash so that BigUint works properly as an AA key.\n    size_t toHash() const @trusted nothrow\n    {\n        return typeid(data).getHash(&data);\n    }\n\n} // end BigUint\n\n@safe pure nothrow unittest\n{\n    // ulong comparison test\n    BigUint a = [1];\n    assert(a == 1);\n    assert(a < 0x8000_0000_0000_0000UL); // bug 9548\n\n    // bug 12234\n    BigUint z = [0];\n    assert(z == 0UL);\n    assert(!(z > 0UL));\n    assert(!(z < 0UL));\n}\n\n// Remove leading zeros from x, to restore the BigUint invariant\ninout(BigDigit) [] removeLeadingZeros(inout(BigDigit) [] x) pure nothrow @safe\n{\n    size_t k = x.length;\n    while (k>1 && x[k - 1]==0) --k;\n    return x[0 .. k];\n}\n\npure @system unittest\n{\n   BigUint r = BigUint([5]);\n   BigUint t = BigUint([7]);\n   BigUint s = BigUint.mod(r, t);\n   assert(s == 5);\n}\n\n\n@safe pure unittest\n{\n    BigUint r;\n    r = 5UL;\n    assert(r.peekUlong(0) == 5UL);\n    assert(r.peekUint(0) == 5U);\n    r = 0x1234_5678_9ABC_DEF0UL;\n    assert(r.peekUlong(0) == 0x1234_5678_9ABC_DEF0UL);\n    assert(r.peekUint(0) == 0x9ABC_DEF0U);\n}\n\n\n// Pow tests\npure @system unittest\n{\n    BigUint r, s;\n    r.fromHexString(\"80000000_00000001\");\n    s = BigUint.pow(r, 5);\n    r.fromHexString(\"08000000_00000000_50000000_00000001_40000000_00000002_80000000\"\n      ~ \"_00000002_80000000_00000001\");\n    assert(s == r);\n    s = 10UL;\n    s = BigUint.pow(s, 39);\n    r.fromDecimalString(\"1000000000000000000000000000000000000000\");\n    assert(s == r);\n    r.fromHexString(\"1_E1178E81_00000000\");\n    s = BigUint.pow(r, 15); // Regression test: this used to overflow array bounds\n\n    r.fromDecimalString(\"000_000_00\");\n    assert(r == 0);\n    r.fromDecimalString(\"0007\");\n    assert(r == 7);\n    r.fromDecimalString(\"0\");\n    assert(r == 0);\n}\n\n// Radix conversion tests\n@safe pure unittest\n{\n    BigUint r;\n    r.fromHexString(\"1_E1178E81_00000000\");\n    assert(r.toHexString(0, '_', 0) == \"1_E1178E81_00000000\");\n    assert(r.toHexString(0, '_', 20) == \"0001_E1178E81_00000000\");\n    assert(r.toHexString(0, '_', 16+8) == \"00000001_E1178E81_00000000\");\n    assert(r.toHexString(0, '_', 16+9) == \"0_00000001_E1178E81_00000000\");\n    assert(r.toHexString(0, '_', 16+8+8) ==   \"00000000_00000001_E1178E81_00000000\");\n    assert(r.toHexString(0, '_', 16+8+8+1) ==      \"0_00000000_00000001_E1178E81_00000000\");\n    assert(r.toHexString(0, '_', 16+8+8+1, ' ') == \"                  1_E1178E81_00000000\");\n    assert(r.toHexString(0, 0, 16+8+8+1) == \"00000000000000001E1178E8100000000\");\n    r = 0UL;\n    assert(r.toHexString(0, '_', 0) == \"0\");\n    assert(r.toHexString(0, '_', 7) == \"0000000\");\n    assert(r.toHexString(0, '_', 7, ' ') == \"      0\");\n    assert(r.toHexString(0, '#', 9) == \"0#00000000\");\n    assert(r.toHexString(0, 0, 9) == \"000000000\");\n}\n\n//\n@safe pure unittest\n{\n    BigUint r;\n    r.fromHexString(\"1_E1178E81_00000000\");\n    assert(r.toHexString(0, '_', 0, '0', LetterCase.lower) == \"1_e1178e81_00000000\");\n    assert(r.toHexString(0, '_', 20, '0', LetterCase.lower) == \"0001_e1178e81_00000000\");\n    assert(r.toHexString(0, '_', 16+8, '0', LetterCase.lower) == \"00000001_e1178e81_00000000\");\n    assert(r.toHexString(0, '_', 16+9, '0', LetterCase.lower) == \"0_00000001_e1178e81_00000000\");\n    assert(r.toHexString(0, '_', 16+8+8, '0', LetterCase.lower) ==   \"00000000_00000001_e1178e81_00000000\");\n    assert(r.toHexString(0, '_', 16+8+8+1, '0', LetterCase.lower) == \"0_00000000_00000001_e1178e81_00000000\");\n    assert(r.toHexString(0, '_', 16+8+8+1, ' ', LetterCase.lower) == \"                  1_e1178e81_00000000\");\n    assert(r.toHexString(0, 0, 16+8+8+1, '0', LetterCase.lower) == \"00000000000000001e1178e8100000000\");\n    r = 0UL;\n    assert(r.toHexString(0, '_', 0, '0', LetterCase.lower) == \"0\");\n    assert(r.toHexString(0, '_', 7, '0', LetterCase.lower) == \"0000000\");\n    assert(r.toHexString(0, '_', 7, ' ', LetterCase.lower) == \"      0\");\n    assert(r.toHexString(0, '#', 9, '0', LetterCase.lower) == \"0#00000000\");\n    assert(r.toHexString(0, 'Z', 9, '0', LetterCase.lower) == \"0Z00000000\");\n    assert(r.toHexString(0, 0, 9, '0', LetterCase.lower) == \"000000000\");\n}\n\n\nprivate:\nvoid twosComplement(const(BigDigit) [] x, BigDigit[] result)\npure nothrow @safe\n{\n    foreach (i; 0 .. x.length)\n    {\n        result[i] = ~x[i];\n    }\n    result[x.length..$] = BigDigit.max;\n\n    foreach (i; 0 .. result.length)\n    {\n        if (result[i] == BigDigit.max)\n        {\n            result[i] = 0;\n        }\n        else\n        {\n            result[i] += 1;\n            break;\n        }\n    }\n}\n\n// Encode BigInt as BigDigit array (sign and 2's complement)\nBigDigit[] includeSign(const(BigDigit) [] x, size_t minSize, bool sign)\npure nothrow @safe\n{\n    size_t length = (x.length > minSize) ? x.length : minSize;\n    BigDigit [] result = new BigDigit[length];\n    if (sign)\n    {\n        twosComplement(x, result);\n    }\n    else\n    {\n        result[0 .. x.length] = x;\n    }\n    return result;\n}\n\n// works for any type\nT intpow(T)(T x, ulong n) pure nothrow @safe\n{\n    T p;\n\n    switch (n)\n    {\n    case 0:\n        p = 1;\n        break;\n\n    case 1:\n        p = x;\n        break;\n\n    case 2:\n        p = x * x;\n        break;\n\n    default:\n        p = 1;\n        while (1)\n        {\n            if (n & 1)\n                p *= x;\n            n >>= 1;\n            if (!n)\n                break;\n            x *= x;\n        }\n        break;\n    }\n    return p;\n}\n\n\n//  returns the maximum power of x that will fit in a uint.\nint highestPowerBelowUintMax(uint x) pure nothrow @safe\n{\n     assert(x>1);\n     static immutable ubyte [22] maxpwr = [ 31, 20, 15, 13, 12, 11, 10, 10, 9, 9,\n                                          8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7];\n     if (x<24) return maxpwr[x-2];\n     if (x<41) return 6;\n     if (x<85) return 5;\n     if (x<256) return 4;\n     if (x<1626) return 3;\n     if (x<65_536) return 2;\n     return 1;\n}\n\n//  returns the maximum power of x that will fit in a ulong.\nint highestPowerBelowUlongMax(uint x) pure nothrow @safe\n{\n     assert(x>1);\n     static immutable ubyte [39] maxpwr = [ 63, 40, 31, 27, 24, 22, 21, 20, 19, 18,\n                                         17, 17, 16, 16, 15, 15, 15, 15, 14, 14,\n                                         14, 14, 13, 13, 13, 13, 13, 13, 13, 12,\n                                         12, 12, 12, 12, 12, 12, 12, 12, 12];\n     if (x<41) return maxpwr[x-2];\n     if (x<57) return 11;\n     if (x<85) return 10;\n     if (x<139) return 9;\n     if (x<256) return 8;\n     if (x<566) return 7;\n     if (x<1626) return 6;\n     if (x<7132) return 5;\n     if (x<65_536) return 4;\n     if (x<2_642_246) return 3;\n     return 2;\n}\n\nversion (unittest)\n{\n\nprivate int slowHighestPowerBelowUintMax(uint x) pure nothrow @safe\n{\n     int pwr = 1;\n     for (ulong q = x;x*q < cast(ulong) uint.max; )\n     {\n         q*=x; ++pwr;\n     }\n     return pwr;\n}\n\n@safe pure unittest\n{\n    assert(highestPowerBelowUintMax(10)==9);\n    for (int k=82; k<88; ++k)\n    {\n        assert(highestPowerBelowUintMax(k)== slowHighestPowerBelowUintMax(k));\n    }\n}\n\n}\n\n\n/*  General unsigned subtraction routine for bigints.\n *  Sets result = x - y. If the result is negative, negative will be true.\n * Returns:\n *    unique memory\n */\nBigDigit [] sub(const BigDigit [] x, const BigDigit [] y, bool *negative)\npure nothrow\n{\n    if (x.length == y.length)\n    {\n        // There's a possibility of cancellation, if x and y are almost equal.\n        ptrdiff_t last = highestDifferentDigit(x, y);\n        BigDigit [] result = new BigDigit[last+1];\n        if (x[last] < y[last])\n        {   // we know result is negative\n            multibyteSub(result[0 .. last+1], y[0 .. last+1], x[0 .. last+1], 0);\n            *negative = true;\n        }\n        else\n        {   // positive or zero result\n            multibyteSub(result[0 .. last+1], x[0 .. last+1], y[0 .. last+1], 0);\n            *negative = false;\n        }\n        while (result.length > 1 && result[$-1] == 0)\n        {\n            result = result[0..$-1];\n        }\n//        if (result.length >1 && result[$-1]==0) return result[0..$-1];\n        return result;\n    }\n    // Lengths are different\n    const(BigDigit) [] large, small;\n    if (x.length < y.length)\n    {\n        *negative = true;\n        large = y; small = x;\n    }\n    else\n    {\n        *negative = false;\n        large = x; small = y;\n    }\n    // result.length will be equal to larger length, or could decrease by 1.\n\n\n    BigDigit [] result = new BigDigit[large.length];\n    BigDigit carry = multibyteSub(result[0 .. small.length], large[0 .. small.length], small, 0);\n    result[small.length..$] = large[small.length..$];\n    if (carry)\n    {\n        multibyteIncrementAssign!('-')(result[small.length..$], carry);\n    }\n    while (result.length > 1 && result[$-1] == 0)\n    {\n        result = result[0..$-1];\n    }\n    return result;\n}\n\n\n/*\n * return a + b\n * Returns:\n *    unique memory\n */\nBigDigit [] add(const BigDigit [] a, const BigDigit [] b) pure nothrow\n{\n    const(BigDigit) [] x, y;\n    if (a.length < b.length)\n    {\n        x = b; y = a;\n    }\n    else\n    {\n        x = a; y = b;\n    }\n    // now we know x.length > y.length\n    // create result. add 1 in case it overflows\n    BigDigit [] result = new BigDigit[x.length + 1];\n\n    BigDigit carry = multibyteAdd(result[0 .. y.length], x[0 .. y.length], y, 0);\n    if (x.length != y.length)\n    {\n        result[y.length..$-1]= x[y.length..$];\n        carry  = multibyteIncrementAssign!('+')(result[y.length..$-1], carry);\n    }\n    if (carry)\n    {\n        result[$-1] = carry;\n        return result;\n    }\n    else\n        return result[0..$-1];\n}\n\n/**  return x + y\n */\nBigDigit [] addInt(const BigDigit[] x, ulong y) pure nothrow\n{\n    uint hi = cast(uint)(y >>> 32);\n    uint lo = cast(uint)(y& 0xFFFF_FFFF);\n    auto len = x.length;\n    if (x.length < 2 && hi != 0) ++len;\n    BigDigit [] result = new BigDigit[len+1];\n    result[0 .. x.length] = x[];\n    if (x.length < 2 && hi != 0)\n    {\n        result[1]=hi;\n        hi=0;\n    }\n    uint carry = multibyteIncrementAssign!('+')(result[0..$-1], lo);\n    if (hi != 0) carry += multibyteIncrementAssign!('+')(result[1..$-1], hi);\n    if (carry)\n    {\n        result[$-1] = carry;\n        return result;\n    }\n    else\n        return result[0..$-1];\n}\n\n/** Return x - y.\n *  x must be greater than y.\n */\nBigDigit [] subInt(const BigDigit[] x, ulong y) pure nothrow\n{\n    uint hi = cast(uint)(y >>> 32);\n    uint lo = cast(uint)(y & 0xFFFF_FFFF);\n    BigDigit [] result = new BigDigit[x.length];\n    result[] = x[];\n    multibyteIncrementAssign!('-')(result[], lo);\n    if (hi)\n        multibyteIncrementAssign!('-')(result[1..$], hi);\n    if (result[$-1] == 0)\n        return result[0..$-1];\n    else\n        return result;\n}\n\n/**  General unsigned multiply routine for bigints.\n *  Sets result = x * y.\n *\n *  The length of y must not be larger than the length of x.\n *  Different algorithms are used, depending on the lengths of x and y.\n *  TODO: \"Modern Computer Arithmetic\" suggests the OddEvenKaratsuba algorithm for the\n *  unbalanced case. (But I doubt it would be faster in practice).\n *\n */\nvoid mulInternal(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)\n    pure nothrow\n{\n    import core.memory : GC;\n    assert( result.length == x.length + y.length );\n    assert( y.length > 0 );\n    assert( x.length >= y.length);\n    if (y.length <= KARATSUBALIMIT)\n    {\n        // Small multiplier, we'll just use the asm classic multiply.\n        if (y.length == 1)\n        {   // Trivial case, no cache effects to worry about\n            result[x.length] = multibyteMul(result[0 .. x.length], x, y[0], 0);\n            return;\n        }\n\n        immutable CACHELIMIT = getCacheLimit;\n        if (x.length + y.length < CACHELIMIT)\n            return mulSimple(result, x, y);\n\n        // If x is so big that it won't fit into the cache, we divide it into chunks\n        // Every chunk must be greater than y.length.\n        // We make the first chunk shorter, if necessary, to ensure this.\n\n        auto chunksize = CACHELIMIT / y.length;\n        immutable residual  =  x.length % chunksize;\n        if (residual < y.length)\n        {\n            chunksize -= y.length;\n        }\n\n        // Use schoolbook multiply.\n        mulSimple(result[0 .. chunksize + y.length], x[0 .. chunksize], y);\n        auto done = chunksize;\n\n        while (done < x.length)\n        {\n            // result[done .. done+ylength] already has a value.\n            chunksize = (done + (CACHELIMIT / y.length) < x.length) ? (CACHELIMIT / y.length) :  x.length - done;\n            BigDigit [KARATSUBALIMIT] partial;\n            partial[0 .. y.length] = result[done .. done+y.length];\n            mulSimple(result[done .. done+chunksize+y.length], x[done .. done+chunksize], y);\n            addAssignSimple(result[done .. done+chunksize + y.length], partial[0 .. y.length]);\n            done += chunksize;\n        }\n        return;\n    }\n\n    immutable half = (x.length >> 1) + (x.length & 1);\n    if (2*y.length*y.length <= x.length*x.length)\n    {\n        // UNBALANCED MULTIPLY\n        // Use school multiply to cut into quasi-squares of Karatsuba-size\n        // or larger. The ratio of the two sides of the 'square' must be\n        // between 1.414:1 and 1:1. Use Karatsuba on each chunk.\n        //\n        // For maximum performance, we want the ratio to be as close to\n        // 1:1 as possible. To achieve this, we can either pad x or y.\n        // The best choice depends on the modulus x%y.\n        auto numchunks = x.length / y.length;\n        auto chunksize = y.length;\n        auto extra =  x.length % y.length;\n        auto maxchunk = chunksize + extra;\n        bool paddingY; // true = we're padding Y, false = we're padding X.\n        bool isExtraSmall = extra * extra * 2 < y.length * y.length;\n        if (numchunks == 1 && isExtraSmall)\n        {\n            // We divide (x_first_half * y) and (x_last_half * y)\n            // between 1.414:1 and 1.707:1 (1.707 = 1+1/sqrt(2)).\n            // (1.414 ~ 1.707)/2:1 is balanced.\n            BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(y.length) + y.length];\n            BigDigit [] partial = scratchbuff[$ - y.length .. $];\n            mulKaratsuba(result[0 .. half + y.length], y, x[0 .. half], scratchbuff);\n            partial[] = result[half .. half + y.length];\n            mulKaratsuba(result[half .. $], y, x[half .. $], scratchbuff);\n            addAssignSimple(result[half .. half + y.length], partial);\n            () @trusted { GC.free(scratchbuff.ptr); } ();\n        }\n        else\n        {\n            if (isExtraSmall)\n            {\n                // The leftover bit is small enough that it should be incorporated\n                // in the existing chunks.\n                // Make all the chunks a tiny bit bigger\n                // (We're padding y with zeros)\n                chunksize += extra / numchunks;\n                extra = x.length - chunksize*numchunks;\n                // there will probably be a few left over.\n                // Every chunk will either have size chunksize, or chunksize+1.\n                maxchunk = chunksize + 1;\n                paddingY = true;\n                assert(chunksize + extra + chunksize *(numchunks-1) == x.length );\n            }\n            else\n            {\n                // the extra bit is large enough that it's worth making a new chunk.\n                // (This means we're padding x with zeros, when doing the first one).\n                maxchunk = chunksize;\n                ++numchunks;\n                paddingY = false;\n                assert(extra + chunksize *(numchunks-1) == x.length );\n            }\n            // We make the buffer a bit bigger so we have space for the partial sums.\n            BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(maxchunk) + y.length];\n            BigDigit [] partial = scratchbuff[$ - y.length .. $];\n            size_t done; // how much of X have we done so far?\n            if (paddingY)\n            {\n                // If the first chunk is bigger, do it first. We're padding y.\n                mulKaratsuba(result[0 .. y.length + chunksize + (extra > 0 ? 1 : 0 )],\n                    x[0 .. chunksize + (extra>0?1:0)], y, scratchbuff);\n                done = chunksize + (extra > 0 ? 1 : 0);\n                if (extra) --extra;\n            }\n            else\n            {   // We're padding X. Begin with the extra bit.\n                mulKaratsuba(result[0 .. y.length + extra], y, x[0 .. extra], scratchbuff);\n                done = extra;\n                extra = 0;\n            }\n            immutable basechunksize = chunksize;\n            while (done < x.length)\n            {\n                chunksize = basechunksize + (extra > 0 ? 1 : 0);\n                if (extra) --extra;\n                partial[] = result[done .. done+y.length];\n                mulKaratsuba(result[done .. done + y.length + chunksize],\n                        x[done .. done+chunksize], y, scratchbuff);\n                addAssignSimple(result[done .. done + y.length + chunksize], partial);\n                done += chunksize;\n            }\n            () @trusted { GC.free(scratchbuff.ptr); } ();\n        }\n    }\n    else\n    {\n        // Balanced. Use Karatsuba directly.\n        BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(x.length)];\n        mulKaratsuba(result, x, y, scratchbuff);\n        () @trusted { GC.free(scratchbuff.ptr); } ();\n    }\n}\n\n/**  General unsigned squaring routine for BigInts.\n *   Sets result = x*x.\n *   NOTE: If the highest half-digit of x is zero, the highest digit of result will\n *   also be zero.\n */\nvoid squareInternal(BigDigit[] result, const BigDigit[] x) pure nothrow\n{\n  import core.memory : GC;\n  // Squaring is potentially half a multiply, plus add the squares of\n  // the diagonal elements.\n  assert(result.length == 2*x.length);\n  if (x.length <= KARATSUBASQUARELIMIT)\n  {\n      if (x.length == 1)\n      {\n         result[1] = multibyteMul(result[0 .. 1], x, x[0], 0);\n         return;\n      }\n      return squareSimple(result, x);\n  }\n  // The nice thing about squaring is that it always stays balanced\n  BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(x.length)];\n  squareKaratsuba(result, x, scratchbuff);\n  () @trusted { GC.free(scratchbuff.ptr); } ();\n}\n\n\nimport core.bitop : bsr;\n\n/// if remainder is null, only calculate quotient.\nvoid divModInternal(BigDigit [] quotient, BigDigit[] remainder, const BigDigit [] u,\n        const BigDigit [] v) pure nothrow\n{\n    import core.memory : GC;\n    assert(quotient.length == u.length - v.length + 1);\n    assert(remainder == null || remainder.length == v.length);\n    assert(v.length > 1);\n    assert(u.length >= v.length);\n\n    // Normalize by shifting v left just enough so that\n    // its high-order bit is on, and shift u left the\n    // same amount. The highest bit of u will never be set.\n\n    BigDigit [] vn = new BigDigit[v.length];\n    BigDigit [] un = new BigDigit[u.length + 1];\n    // How much to left shift v, so that its MSB is set.\n    uint s = BIGDIGITSHIFTMASK - bsr(v[$-1]);\n    if (s != 0)\n    {\n        multibyteShl(vn, v, s);\n        un[$-1] = multibyteShl(un[0..$-1], u, s);\n    }\n    else\n    {\n        vn[] = v[];\n        un[0..$-1] = u[];\n        un[$-1] = 0;\n    }\n    if (quotient.length<FASTDIVLIMIT)\n    {\n        schoolbookDivMod(quotient, un, vn);\n    }\n    else\n    {\n        blockDivMod(quotient, un, vn);\n    }\n\n    // Unnormalize remainder, if required.\n    if (remainder != null)\n    {\n        if (s == 0) remainder[] = un[0 .. vn.length];\n        else multibyteShr(remainder, un[0 .. vn.length+1], s);\n    }\n    () @trusted { GC.free(un.ptr); GC.free(vn.ptr); } ();\n}\n\npure @system unittest\n{\n    immutable(uint) [] u = [0, 0xFFFF_FFFE, 0x8000_0000];\n    immutable(uint) [] v = [0xFFFF_FFFF, 0x8000_0000];\n    uint [] q = new uint[u.length - v.length + 1];\n    uint [] r = new uint[2];\n    divModInternal(q, r, u, v);\n    assert(q[]==[0xFFFF_FFFFu, 0]);\n    assert(r[]==[0xFFFF_FFFFu, 0x7FFF_FFFF]);\n    u = [0, 0xFFFF_FFFE, 0x8000_0001];\n    v = [0xFFFF_FFFF, 0x8000_0000];\n    divModInternal(q, r, u, v);\n}\n\n\nprivate:\n// Converts a big uint to a hexadecimal string.\n//\n// Optionally, a separator character (eg, an underscore) may be added between\n// every 8 digits.\n// buff.length must be data.length*8 if separator is zero,\n// or data.length*9 if separator is non-zero. It will be completely filled.\nchar [] biguintToHex(char [] buff, const BigDigit [] data, char separator=0,\n        LetterCase letterCase = LetterCase.upper) pure nothrow @safe\n{\n    int x=0;\n    for (ptrdiff_t i=data.length - 1; i >= 0; --i)\n    {\n        toHexZeroPadded(buff[x .. x+8], data[i], letterCase);\n        x+=8;\n        if (separator)\n        {\n            if (i>0) buff[x] = separator;\n            ++x;\n        }\n    }\n    return buff;\n}\n\n/**\n * Convert a big uint into an octal string.\n *\n * Params:\n *  buff = The destination buffer for the octal string. Must be large enough to\n *      store the result, including leading zeroes, which is\n *      ceil(data.length * BigDigitBits / 3) characters.\n *      The buffer is filled from back to front, starting from `buff[$-1]`.\n *  data = The biguint to be converted.\n *\n * Returns: The index of the leading non-zero digit in `buff`. Will be\n * `buff.length - 1` if the entire big uint is zero.\n */\nsize_t biguintToOctal(char[] buff, const(BigDigit)[] data)\n    pure nothrow @safe @nogc\n{\n    ubyte carry = 0;\n    int shift = 0;\n    size_t penPos = buff.length - 1;\n    size_t lastNonZero = buff.length - 1;\n\n    pragma(inline) void output(uint digit) @nogc nothrow\n    {\n        if (digit != 0)\n            lastNonZero = penPos;\n        buff[penPos--] = cast(char)('0' + digit);\n    }\n\n    foreach (bigdigit; data)\n    {\n        if (shift < 0)\n        {\n            // Some bits were carried over from previous word.\n            assert(shift > -3);\n            output(((bigdigit << -shift) | carry) & 0b111);\n            shift += 3;\n            assert(shift > 0);\n        }\n\n        while (shift <= BigDigitBits - 3)\n        {\n            output((bigdigit >>> shift) & 0b111);\n            shift += 3;\n        }\n\n        if (shift < BigDigitBits)\n        {\n            // Some bits need to be carried forward.\n            carry = (bigdigit >>> shift) & 0b11;\n        }\n        shift -= BigDigitBits;\n        assert(shift >= -2 && shift <= 0);\n    }\n\n    if (shift < 0)\n    {\n        // Last word had bits that haven't been output yet.\n        assert(shift > -3);\n        output(carry);\n    }\n\n    return lastNonZero;\n}\n\n/** Convert a big uint into a decimal string.\n *\n * Params:\n *  data    The biguint to be converted. Will be destroyed.\n *  buff    The destination buffer for the decimal string. Must be\n *          large enough to store the result, including leading zeros.\n *          Will be filled backwards, starting from buff[$-1].\n *\n * buff.length must be >= (data.length*32)/log2(10) = 9.63296 * data.length.\n * Returns:\n *    the lowest index of buff which was used.\n */\nsize_t biguintToDecimal(char [] buff, BigDigit [] data) pure nothrow\n{\n    ptrdiff_t sofar = buff.length;\n    // Might be better to divide by (10^38/2^32) since that gives 38 digits for\n    // the price of 3 divisions and a shr; this version only gives 27 digits\n    // for 3 divisions.\n    while (data.length>1)\n    {\n        uint rem = multibyteDivAssign(data, 10_0000_0000, 0);\n        itoaZeroPadded(buff[sofar-9 .. sofar], rem);\n        sofar -= 9;\n        if (data[$-1] == 0 && data.length > 1)\n        {\n            data.length = data.length - 1;\n        }\n    }\n    itoaZeroPadded(buff[sofar-10 .. sofar], data[0]);\n    sofar -= 10;\n    // and strip off the leading zeros\n    while (sofar != buff.length-1 && buff[sofar] == '0')\n        sofar++;\n    return sofar;\n}\n\n/** Convert a decimal string into a big uint.\n *\n * Params:\n *  data    The biguint to be receive the result. Must be large enough to\n *          store the result.\n *  s       The decimal string. May contain _ or 0 .. 9\n *\n * The required length for the destination buffer is slightly less than\n *  1 + s.length/log2(10) = 1 + s.length/3.3219.\n *\n * Returns:\n *    the highest index of data which was used.\n */\nint biguintFromDecimal(Range)(BigDigit[] data, Range s)\nif (\n    isInputRange!Range &&\n    isSomeChar!(ElementType!Range) &&\n    !isInfinite!Range)\nin\n{\n    static if (hasLength!Range)\n        assert((data.length >= 2) || (data.length == 1 && s.length == 1));\n}\ndo\n{\n    import std.conv : ConvException;\n\n    // Convert to base 1e19 = 10_000_000_000_000_000_000.\n    // (this is the largest power of 10 that will fit into a long).\n    // The length will be less than 1 + s.length/log2(10) = 1 + s.length/3.3219.\n    // 485 bits will only just fit into 146 decimal digits.\n    // As we convert the string, we record the number of digits we've seen in base 19:\n    // hi is the number of digits/19, lo is the extra digits (0 to 18).\n    // TODO: This is inefficient for very large strings (it is O(n^^2)).\n    // We should take advantage of fast multiplication once the numbers exceed\n    // Karatsuba size.\n    uint lo = 0; // number of powers of digits, 0 .. 18\n    uint x = 0;\n    ulong y = 0;\n    uint hi = 0; // number of base 1e19 digits\n    data[0] = 0; // initially number is 0.\n    if (data.length > 1)\n        data[1] = 0;\n\n    foreach (character; s)\n    {\n        if (character == '_')\n            continue;\n\n        if (character < '0' || character > '9')\n            throw new ConvException(\"invalid digit\");\n        x *= 10;\n        x += character - '0';\n        ++lo;\n        if (lo == 9)\n        {\n            y = x;\n            x = 0;\n        }\n        if (lo == 18)\n        {\n            y *= 10_0000_0000;\n            y += x;\n            x = 0;\n        }\n        if (lo == 19)\n        {\n            y *= 10;\n            y += x;\n            x = 0;\n            // Multiply existing number by 10^19, then add y1.\n            if (hi>0)\n            {\n                data[hi] = multibyteMul(data[0 .. hi], data[0 .. hi], 1_220_703_125*2u, 0); // 5^13*2 = 0x9184_E72A\n                ++hi;\n                data[hi] = multibyteMul(data[0 .. hi], data[0 .. hi], 15_625*262_144u, 0); // 5^6*2^18 = 0xF424_0000\n                ++hi;\n            }\n            else\n                hi = 2;\n            uint c = multibyteIncrementAssign!('+')(data[0 .. hi], cast(uint)(y&0xFFFF_FFFF));\n            c += multibyteIncrementAssign!('+')(data[1 .. hi], cast(uint)(y >> 32));\n            if (c != 0)\n            {\n                data[hi]=c;\n                ++hi;\n            }\n            y = 0;\n            lo = 0;\n        }\n    }\n    // Now set y = all remaining digits.\n    if (lo >= 18)\n    {\n    }\n    else if (lo >= 9)\n    {\n        for (int k=9; k<lo; ++k) y*=10;\n        y+=x;\n    }\n    else\n    {\n        for (int k=0; k<lo; ++k) y*=10;\n        y+=x;\n    }\n    if (lo != 0)\n    {\n        if (hi == 0)\n        {\n            data[0] = cast(uint) y;\n            if (data.length == 1)\n            {\n                hi = 1;\n            }\n            else\n            {\n                data[1] = cast(uint)(y >>> 32);\n                hi=2;\n            }\n        }\n        else\n        {\n            while (lo>0)\n            {\n                immutable c = multibyteMul(data[0 .. hi], data[0 .. hi], 10, 0);\n                if (c != 0)\n                {\n                    data[hi]=c;\n                    ++hi;\n                }\n                --lo;\n            }\n            uint c = multibyteIncrementAssign!('+')(data[0 .. hi], cast(uint)(y&0xFFFF_FFFF));\n            if (y > 0xFFFF_FFFFL)\n            {\n                c += multibyteIncrementAssign!('+')(data[1 .. hi], cast(uint)(y >> 32));\n            }\n            if (c != 0)\n            {\n                data[hi]=c;\n                ++hi;\n            }\n        }\n    }\n    while (hi>1 && data[hi-1]==0)\n        --hi;\n    return hi;\n}\n\n\nprivate:\n// ------------------------\n// These in-place functions are only for internal use; they are incompatible\n// with COW.\n\n// Classic 'schoolbook' multiplication.\nvoid mulSimple(BigDigit[] result, const(BigDigit) [] left,\n        const(BigDigit)[] right) pure nothrow\nin\n{\n    assert(result.length == left.length + right.length);\n    assert(right.length>1);\n}\ndo\n{\n    result[left.length] = multibyteMul(result[0 .. left.length], left, right[0], 0);\n    multibyteMultiplyAccumulate(result[1..$], left, right[1..$]);\n}\n\n// Classic 'schoolbook' squaring\nvoid squareSimple(BigDigit[] result, const(BigDigit) [] x) pure nothrow\nin\n{\n    assert(result.length == 2*x.length);\n    assert(x.length>1);\n}\ndo\n{\n    multibyteSquare(result, x);\n}\n\n\n// add two uints of possibly different lengths. Result must be as long\n// as the larger length.\n// Returns carry (0 or 1).\nuint addSimple(BigDigit[] result, const BigDigit [] left, const BigDigit [] right)\npure nothrow\nin\n{\n    assert(result.length == left.length);\n    assert(left.length >= right.length);\n    assert(right.length>0);\n}\ndo\n{\n    uint carry = multibyteAdd(result[0 .. right.length],\n            left[0 .. right.length], right, 0);\n    if (right.length < left.length)\n    {\n        result[right.length .. left.length] = left[right.length .. $];\n        carry = multibyteIncrementAssign!('+')(result[right.length..$], carry);\n    }\n    return carry;\n}\n\n//  result = left - right\n// returns carry (0 or 1)\nBigDigit subSimple(BigDigit [] result,const(BigDigit) [] left,\n        const(BigDigit) [] right) pure nothrow\nin\n{\n    assert(result.length == left.length);\n    assert(left.length >= right.length);\n    assert(right.length>0);\n}\ndo\n{\n    BigDigit carry = multibyteSub(result[0 .. right.length],\n            left[0 .. right.length], right, 0);\n    if (right.length < left.length)\n    {\n        result[right.length .. left.length] = left[right.length .. $];\n        carry = multibyteIncrementAssign!('-')(result[right.length..$], carry);\n    } //else if (result.length == left.length+1) { result[$-1] = carry; carry=0; }\n    return carry;\n}\n\n\n/* result = result - right\n * Returns carry = 1 if result was less than right.\n*/\nBigDigit subAssignSimple(BigDigit [] result, const(BigDigit) [] right)\npure nothrow\n{\n    assert(result.length >= right.length);\n    uint c = multibyteSub(result[0 .. right.length], result[0 .. right.length], right, 0);\n    if (c && result.length > right.length)\n        c = multibyteIncrementAssign!('-')(result[right.length .. $], c);\n    return c;\n}\n\n/* result = result + right\n*/\nBigDigit addAssignSimple(BigDigit [] result, const(BigDigit) [] right)\npure nothrow\n{\n    assert(result.length >= right.length);\n    uint c = multibyteAdd(result[0 .. right.length], result[0 .. right.length], right, 0);\n    if (c && result.length > right.length)\n       c = multibyteIncrementAssign!('+')(result[right.length .. $], c);\n    return c;\n}\n\n/* performs result += wantSub? - right : right;\n*/\nBigDigit addOrSubAssignSimple(BigDigit [] result, const(BigDigit) [] right,\n        bool wantSub) pure nothrow\n{\n    if (wantSub)\n        return subAssignSimple(result, right);\n    else\n        return addAssignSimple(result, right);\n}\n\n\n// return true if x<y, considering leading zeros\nbool less(const(BigDigit)[] x, const(BigDigit)[] y) pure nothrow\n{\n    assert(x.length >= y.length);\n    auto k = x.length-1;\n    while (x[k]==0 && k >= y.length)\n        --k;\n    if (k >= y.length)\n        return false;\n    while (k>0 && x[k]==y[k])\n        --k;\n    return x[k] < y[k];\n}\n\n// Set result = abs(x-y), return true if result is negative(x<y), false if x <= y.\nbool inplaceSub(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)\n    pure nothrow\n{\n    assert(result.length == ((x.length >= y.length) ? x.length : y.length));\n\n    size_t minlen;\n    bool negative;\n    if (x.length >= y.length)\n    {\n        minlen = y.length;\n        negative = less(x, y);\n    }\n    else\n    {\n       minlen = x.length;\n       negative = !less(y, x);\n    }\n    const (BigDigit)[] large, small;\n    if (negative)\n    {\n        large = y; small = x;\n    }\n    else\n    {\n        large = x; small = y;\n    }\n\n    BigDigit carry = multibyteSub(result[0 .. minlen], large[0 .. minlen], small[0 .. minlen], 0);\n    if (x.length != y.length)\n    {\n        result[minlen .. large.length]= large[minlen..$];\n        result[large.length..$] = 0;\n        if (carry)\n            multibyteIncrementAssign!('-')(result[minlen..$], carry);\n    }\n    return negative;\n}\n\n/* Determine how much space is required for the temporaries\n * when performing a Karatsuba multiplication.\n */\nsize_t karatsubaRequiredBuffSize(size_t xlen) pure nothrow @safe\n{\n    return xlen <= KARATSUBALIMIT ? 0 : 2*xlen; // - KARATSUBALIMIT+2;\n}\n\n/* Sets result = x*y, using Karatsuba multiplication.\n* x must be longer or equal to y.\n* Valid only for balanced multiplies, where x is not shorter than y.\n* It is superior to schoolbook multiplication if and only if\n*    sqrt(2)*y.length > x.length > y.length.\n* Karatsuba multiplication is O(n^1.59), whereas schoolbook is O(n^2)\n* The maximum allowable length of x and y is uint.max; but better algorithms\n* should be used far before that length is reached.\n* Params:\n* scratchbuff      An array long enough to store all the temporaries. Will be destroyed.\n*/\nvoid mulKaratsuba(BigDigit [] result, const(BigDigit) [] x,\n        const(BigDigit)[] y, BigDigit [] scratchbuff) pure nothrow\n{\n    assert(x.length >= y.length);\n    assert(result.length < uint.max, \"Operands too large\");\n    assert(result.length == x.length + y.length);\n    if (x.length <= KARATSUBALIMIT)\n    {\n        return mulSimple(result, x, y);\n    }\n    // Must be almost square (otherwise, a schoolbook iteration is better)\n    assert(2L * y.length * y.length > (x.length-1) * (x.length-1),\n        \"Bigint Internal Error: Asymmetric Karatsuba\");\n\n    // The subtractive version of Karatsuba multiply uses the following result:\n    // (Nx1 + x0)*(Ny1 + y0) = (N*N)*x1y1 + x0y0 + N * (x0y0 + x1y1 - mid)\n    // where mid = (x0-x1)*(y0-y1)\n    // requiring 3 multiplies of length N, instead of 4.\n    // The advantage of the subtractive over the additive version is that\n    // the mid multiply cannot exceed length N. But there are subtleties:\n    // (x0-x1),(y0-y1) may be negative or zero. To keep it simple, we\n    // retain all of the leading zeros in the subtractions\n\n    // half length, round up.\n    auto half = (x.length >> 1) + (x.length & 1);\n\n    const(BigDigit) [] x0 = x[0 .. half];\n    const(BigDigit) [] x1 = x[half .. $];\n    const(BigDigit) [] y0 = y[0 .. half];\n    const(BigDigit) [] y1 = y[half .. $];\n    BigDigit [] mid = scratchbuff[0 .. half*2];\n    BigDigit [] newscratchbuff = scratchbuff[half*2 .. $];\n    BigDigit [] resultLow = result[0 .. 2*half];\n    BigDigit [] resultHigh = result[2*half .. $];\n     // initially use result to store temporaries\n    BigDigit [] xdiff= result[0 .. half];\n    BigDigit [] ydiff = result[half .. half*2];\n\n    // First, we calculate mid, and sign of mid\n    immutable bool midNegative = inplaceSub(xdiff, x0, x1)\n                      ^ inplaceSub(ydiff, y0, y1);\n    mulKaratsuba(mid, xdiff, ydiff, newscratchbuff);\n\n    // Low half of result gets x0 * y0. High half gets x1 * y1\n\n    mulKaratsuba(resultLow, x0, y0, newscratchbuff);\n\n    if (2L * y1.length * y1.length < x1.length * x1.length)\n    {\n        // an asymmetric situation has been created.\n        // Worst case is if x:y = 1.414 : 1, then x1:y1 = 2.41 : 1.\n        // Applying one schoolbook multiply gives us two pieces each 1.2:1\n        if (y1.length <= KARATSUBALIMIT)\n            mulSimple(resultHigh, x1, y1);\n        else\n        {\n            // divide x1 in two, then use schoolbook multiply on the two pieces.\n            auto quarter = (x1.length >> 1) + (x1.length & 1);\n            immutable ysmaller = (quarter >= y1.length);\n            mulKaratsuba(resultHigh[0 .. quarter+y1.length], ysmaller ? x1[0 .. quarter] : y1,\n                ysmaller ? y1 : x1[0 .. quarter], newscratchbuff);\n            // Save the part which will be overwritten.\n            immutable ysmaller2 = ((x1.length - quarter) >= y1.length);\n            newscratchbuff[0 .. y1.length] = resultHigh[quarter .. quarter + y1.length];\n            mulKaratsuba(resultHigh[quarter..$], ysmaller2 ? x1[quarter..$] : y1,\n                ysmaller2 ? y1 : x1[quarter..$], newscratchbuff[y1.length..$]);\n\n            resultHigh[quarter..$].addAssignSimple(newscratchbuff[0 .. y1.length]);\n        }\n    }\n    else\n        mulKaratsuba(resultHigh, x1, y1, newscratchbuff);\n\n    /* We now have result = x0y0 + (N*N)*x1y1\n       Before adding or subtracting mid, we must calculate\n       result += N * (x0y0 + x1y1)\n       We can do this with three half-length additions. With a = x0y0, b = x1y1:\n                      aHI aLO\n        +       aHI   aLO\n        +       bHI   bLO\n        +  bHI  bLO\n        =  R3   R2    R1   R0\n        R1 = aHI + bLO + aLO\n        R2 = aHI + bLO + aHI + carry_from_R1\n        R3 = bHi + carry_from_R2\n\n     It might actually be quicker to do it in two full-length additions:\n     newscratchbuff[2*half] = addSimple(newscratchbuff[0 .. 2*half], result[0 .. 2*half], result[2*half..$]);\n     addAssignSimple(result[half..$], newscratchbuff[0 .. 2*half+1]);\n   */\n    BigDigit[] R1 = result[half .. half*2];\n    BigDigit[] R2 = result[half*2 .. half*3];\n    BigDigit[] R3 = result[half*3..$];\n    BigDigit c1 = multibyteAdd(R2, R2, R1, 0); // c1:R2 = R2 + R1\n    BigDigit c2 = multibyteAdd(R1, R2, result[0 .. half], 0); // c2:R1 = R2 + R1 + R0\n    BigDigit c3 = addAssignSimple(R2, R3); // R2 = R2 + R1 + R3\n    if (c1+c2)\n        multibyteIncrementAssign!('+')(result[half*2..$], c1+c2);\n    if (c1+c3)\n        multibyteIncrementAssign!('+')(R3, c1+c3);\n\n    // And finally we subtract mid\n    addOrSubAssignSimple(result[half..$], mid, !midNegative);\n}\n\nvoid squareKaratsuba(BigDigit [] result, const BigDigit [] x,\n        BigDigit [] scratchbuff) pure nothrow\n{\n    // See mulKaratsuba for implementation comments.\n    // Squaring is simpler, since it never gets asymmetric.\n    assert(result.length < uint.max, \"Operands too large\");\n    assert(result.length == 2*x.length);\n    if (x.length <= KARATSUBASQUARELIMIT)\n    {\n        return squareSimple(result, x);\n    }\n    // half length, round up.\n    auto half = (x.length >> 1) + (x.length & 1);\n\n    const(BigDigit)[] x0 = x[0 .. half];\n    const(BigDigit)[] x1 = x[half .. $];\n    BigDigit [] mid = scratchbuff[0 .. half*2];\n    BigDigit [] newscratchbuff = scratchbuff[half*2 .. $];\n     // initially use result to store temporaries\n    BigDigit [] xdiff= result[0 .. half];\n    const BigDigit [] ydiff = result[half .. half*2];\n\n    // First, we calculate mid. We don't need its sign\n    inplaceSub(xdiff, x0, x1);\n    squareKaratsuba(mid, xdiff, newscratchbuff);\n\n    // Set result = x0x0 + (N*N)*x1x1\n    squareKaratsuba(result[0 .. 2*half], x0, newscratchbuff);\n    squareKaratsuba(result[2*half .. $], x1, newscratchbuff);\n\n    /* result += N * (x0x0 + x1x1)\n       Do this with three half-length additions. With a = x0x0, b = x1x1:\n        R1 = aHI + bLO + aLO\n        R2 = aHI + bLO + aHI + carry_from_R1\n        R3 = bHi + carry_from_R2\n    */\n    BigDigit[] R1 = result[half .. half*2];\n    BigDigit[] R2 = result[half*2 .. half*3];\n    BigDigit[] R3 = result[half*3..$];\n    BigDigit c1 = multibyteAdd(R2, R2, R1, 0); // c1:R2 = R2 + R1\n    BigDigit c2 = multibyteAdd(R1, R2, result[0 .. half], 0); // c2:R1 = R2 + R1 + R0\n    BigDigit c3 = addAssignSimple(R2, R3); // R2 = R2 + R1 + R3\n    if (c1+c2) multibyteIncrementAssign!('+')(result[half*2..$], c1+c2);\n    if (c1+c3) multibyteIncrementAssign!('+')(R3, c1+c3);\n\n    // And finally we subtract mid, which is always positive\n    subAssignSimple(result[half..$], mid);\n}\n\n/* Knuth's Algorithm D, as presented in\n * H.S. Warren, \"Hacker's Delight\", Addison-Wesley Professional (2002).\n * Also described in \"Modern Computer Arithmetic\" 0.2, Exercise 1.8.18.\n * Given u and v, calculates  quotient  = u / v, u = u % v.\n * v must be normalized (ie, the MSB of v must be 1).\n * The most significant words of quotient and u may be zero.\n * u[0 .. v.length] holds the remainder.\n */\nvoid schoolbookDivMod(BigDigit [] quotient, BigDigit [] u, in BigDigit [] v)\n    pure nothrow\n{\n    assert(quotient.length == u.length - v.length);\n    assert(v.length > 1);\n    assert(u.length >= v.length);\n    assert((v[$-1]&0x8000_0000)!=0);\n    assert(u[$-1] < v[$-1]);\n    // BUG: This code only works if BigDigit is uint.\n    uint vhi = v[$-1];\n    uint vlo = v[$-2];\n\n    for (ptrdiff_t j = u.length - v.length - 1; j >= 0; j--)\n    {\n        // Compute estimate of quotient[j],\n        // qhat = (three most significant words of u)/(two most sig words of v).\n        uint qhat;\n        if (u[j + v.length] == vhi)\n        {\n            // uu/vhi could exceed uint.max (it will be 0x8000_0000 or 0x8000_0001)\n            qhat = uint.max;\n        }\n        else\n        {\n            uint ulo = u[j + v.length - 2];\n            version (D_InlineAsm_X86)\n            {\n                // Note: On DMD, this is only ~10% faster than the non-asm code.\n                uint *p = &u[j + v.length - 1];\n                asm pure nothrow\n                {\n                    mov EAX, p;\n                    mov EDX, [EAX+4];\n                    mov EAX, [EAX];\n                    div dword ptr [vhi];\n                    mov qhat, EAX;\n                    mov ECX, EDX;\ndiv3by2correction:\n                    mul dword ptr [vlo]; // EDX:EAX = qhat * vlo\n                    sub EAX, ulo;\n                    sbb EDX, ECX;\n                    jbe div3by2done;\n                    mov EAX, qhat;\n                    dec EAX;\n                    mov qhat, EAX;\n                    add ECX, dword ptr [vhi];\n                    jnc div3by2correction;\ndiv3by2done:    ;\n                }\n            }\n            else\n            { // version (InlineAsm)\n                ulong uu = (cast(ulong)(u[j + v.length]) << 32) | u[j + v.length - 1];\n                immutable bigqhat = uu / vhi;\n                ulong rhat =  uu - bigqhat * vhi;\n                qhat = cast(uint) bigqhat;\nagain:\n                if (cast(ulong) qhat * vlo > ((rhat << 32) + ulo))\n                {\n                    --qhat;\n                    rhat += vhi;\n                    if (!(rhat & 0xFFFF_FFFF_0000_0000L))\n                        goto again;\n                }\n            } // version (InlineAsm)\n        }\n        // Multiply and subtract.\n        uint carry = multibyteMulAdd!('-')(u[j .. j + v.length], v, qhat, 0);\n\n        if (u[j+v.length] < carry)\n        {\n            // If we subtracted too much, add back\n            --qhat;\n            carry -= multibyteAdd(u[j .. j + v.length],u[j .. j + v.length], v, 0);\n        }\n        quotient[j] = qhat;\n        u[j + v.length] = u[j + v.length] - carry;\n    }\n}\n\nprivate:\n\n// TODO: Replace with a library call\nvoid itoaZeroPadded(char[] output, uint value)\n    pure nothrow @safe @nogc\n{\n    for (auto i = output.length; i--;)\n    {\n        if (value < 10)\n        {\n            output[i] = cast(char)(value + '0');\n            value = 0;\n        }\n        else\n        {\n            output[i] = cast(char)(value % 10 + '0');\n            value /= 10;\n        }\n    }\n}\n\nvoid toHexZeroPadded(char[] output, uint value,\n        LetterCase letterCase = LetterCase.upper) pure nothrow @safe\n{\n    ptrdiff_t x = output.length - 1;\n    static immutable string upperHexDigits = \"0123456789ABCDEF\";\n    static immutable string lowerHexDigits = \"0123456789abcdef\";\n    for ( ; x >= 0; --x)\n    {\n        if (letterCase == LetterCase.upper)\n        {\n            output[x] = upperHexDigits[value & 0xF];\n        }\n        else\n        {\n            output[x] = lowerHexDigits[value & 0xF];\n        }\n        value >>= 4;\n    }\n}\n\nprivate:\n\n// Returns the highest value of i for which left[i]!=right[i],\n// or 0 if left[] == right[]\nsize_t highestDifferentDigit(const BigDigit [] left, const BigDigit [] right)\npure nothrow @nogc @safe\n{\n    assert(left.length == right.length);\n    for (ptrdiff_t i = left.length - 1; i>0; --i)\n    {\n        if (left[i] != right[i])\n            return i;\n    }\n    return 0;\n}\n\n// Returns the lowest value of i for which x[i]!=0.\nint firstNonZeroDigit(const BigDigit [] x) pure nothrow @nogc @safe\n{\n    int k = 0;\n    while (x[k]==0)\n    {\n        ++k;\n        assert(k<x.length);\n    }\n    return k;\n}\n\n/*\n    Calculate quotient and remainder of u / v using fast recursive division.\n    v must be normalised, and must be at least half as long as u.\n    Given u and v, v normalised, calculates  quotient  = u/v, u = u%v.\n    scratch is temporary storage space, length must be >= quotient + 1.\n\nReturns:\n    u[0 .. v.length] is the remainder. u[v.length..$] is corrupted.\n\n    Implements algorithm 1.8 from MCA.\n    This algorithm has an annoying special case. After the first recursion, the\n    highest bit of the quotient may be set. This means that in the second\n    recursive call, the 'in' contract would be violated. (This happens only\n    when the top quarter of u is equal to the top half of v. A base 10\n    equivalent example of this situation is 5517/56; the first step gives\n    55/5 = 11). To maintain the in contract, we pad a zero to the top of both\n    u and the quotient. 'mayOverflow' indicates that that the special case\n    has occurred.\n    (In MCA, a different strategy is used: the in contract is weakened, and\n    schoolbookDivMod is more general: it allows the high bit of u to be set).\n    See also:\n    - C. Burkinel and J. Ziegler, \"Fast Recursive Division\", MPI-I-98-1-022,\n      Max-Planck Institute fuer Informatik, (Oct 1998).\n*/\nvoid recursiveDivMod(BigDigit[] quotient, BigDigit[] u, const(BigDigit)[] v,\n                     BigDigit[] scratch, bool mayOverflow = false)\n                     pure nothrow\nin\n{\n    // v must be normalized\n    assert(v.length > 1);\n    assert((v[$ - 1] & 0x8000_0000) != 0);\n    assert(!(u[$ - 1] & 0x8000_0000));\n    assert(quotient.length == u.length - v.length);\n    if (mayOverflow)\n    {\n        assert(u[$-1] == 0);\n        assert(u[$-2] & 0x8000_0000);\n    }\n\n    // Must be symmetric. Use block schoolbook division if not.\n    assert((mayOverflow ? u.length-1 : u.length) <= 2 * v.length);\n    assert((mayOverflow ? u.length-1 : u.length) >= v.length);\n    assert(scratch.length >= quotient.length + (mayOverflow ? 0 : 1));\n}\ndo\n{\n    if (quotient.length < FASTDIVLIMIT)\n    {\n        return schoolbookDivMod(quotient, u, v);\n    }\n\n    // Split quotient into two halves, but keep padding in the top half\n    auto k = (mayOverflow ?  quotient.length - 1 : quotient.length) >> 1;\n\n    // RECURSION 1: Calculate the high half of the quotient\n\n    // Note that if u and quotient were padded, they remain padded during\n    // this call, so in contract is satisfied.\n    recursiveDivMod(quotient[k .. $], u[2 * k .. $], v[k .. $],\n        scratch, mayOverflow);\n\n    // quotient[k..$] is our guess at the high quotient.\n    // u[2*k .. 2.*k + v.length - k = k + v.length] is the high part of the\n    // first remainder. u[0 .. 2*k] is the low part.\n\n    // Calculate the full first remainder to be\n    //    remainder - highQuotient * lowDivisor\n    // reducing highQuotient until the remainder is positive.\n    // The low part of the remainder, u[0 .. k], cannot be altered by this.\n\n    adjustRemainder(quotient[k .. $], u[k .. k + v.length], v, k,\n            scratch[0 .. quotient.length], mayOverflow);\n\n    // RECURSION 2: Calculate the low half of the quotient\n    // The full first remainder is now in u[0 .. k + v.length].\n\n    if (u[k + v.length - 1] & 0x8000_0000)\n    {\n        // Special case. The high quotient is 0x1_00...000 or 0x1_00...001.\n        // This means we need an extra quotient word for the next recursion.\n        // We need to restore the invariant for the recursive calls.\n        // We do this by padding both u and quotient. Extending u is trivial,\n        // because the higher words will not be used again. But for the\n        // quotient, we're clobbering the low word of the high quotient,\n        // so we need save it, and add it back in after the recursive call.\n\n        auto clobberedQuotient = quotient[k];\n        u[k+v.length] = 0;\n\n        recursiveDivMod(quotient[0 .. k+1], u[k .. k + v.length+1],\n            v[k .. $], scratch, true);\n        adjustRemainder(quotient[0 .. k+1], u[0 .. v.length], v, k,\n            scratch[0 .. 2 * k+1], true);\n\n        // Now add the quotient word that got clobbered earlier.\n        multibyteIncrementAssign!('+')(quotient[k..$], clobberedQuotient);\n    }\n    else\n    {\n        // The special case has NOT happened.\n        recursiveDivMod(quotient[0 .. k], u[k .. k + v.length], v[k .. $],\n            scratch, false);\n\n        // high remainder is in u[k .. k+(v.length-k)] == u[k .. v.length]\n\n        adjustRemainder(quotient[0 .. k], u[0 .. v.length], v, k,\n            scratch[0 .. 2 * k]);\n    }\n}\n\n// rem -= quot * v[0 .. k].\n// If would make rem negative, decrease quot until rem is >= 0.\n// Needs (quot.length * k) scratch space to store the result of the multiply.\nvoid adjustRemainder(BigDigit[] quot, BigDigit[] rem, const(BigDigit)[] v,\n        ptrdiff_t k,\n        BigDigit[] scratch, bool mayOverflow = false) pure nothrow\n{\n    assert(rem.length == v.length);\n    mulInternal(scratch, quot, v[0 .. k]);\n    uint carry = 0;\n    if (mayOverflow)\n        carry = scratch[$-1] + subAssignSimple(rem, scratch[0..$-1]);\n    else\n        carry = subAssignSimple(rem, scratch);\n    while (carry)\n    {\n        multibyteIncrementAssign!('-')(quot, 1); // quot--\n        carry -= multibyteAdd(rem, rem, v, 0);\n    }\n}\n\n// Cope with unbalanced division by performing block schoolbook division.\nvoid blockDivMod(BigDigit [] quotient, BigDigit [] u, in BigDigit [] v)\npure nothrow\n{\n    import core.memory : GC;\n    assert(quotient.length == u.length - v.length);\n    assert(v.length > 1);\n    assert(u.length >= v.length);\n    assert((v[$-1] & 0x8000_0000)!=0);\n    assert((u[$-1] & 0x8000_0000)==0);\n    BigDigit [] scratch = new BigDigit[v.length + 1];\n\n    // Perform block schoolbook division, with 'v.length' blocks.\n    auto m = u.length - v.length;\n    while (m > v.length)\n    {\n        immutable mayOverflow = (u[m + v.length -1 ] & 0x8000_0000)!=0;\n        BigDigit saveq;\n        if (mayOverflow)\n        {\n            u[m + v.length] = 0;\n            saveq = quotient[m];\n        }\n        recursiveDivMod(quotient[m-v.length .. m + (mayOverflow? 1: 0)],\n            u[m - v.length .. m + v.length + (mayOverflow? 1: 0)], v, scratch, mayOverflow);\n        if (mayOverflow)\n        {\n            assert(quotient[m] == 0);\n            quotient[m] = saveq;\n        }\n        m -= v.length;\n    }\n    recursiveDivMod(quotient[0 .. m], u[0 .. m + v.length], v, scratch);\n    () @trusted { GC.free(scratch.ptr); } ();\n}\n\n@system unittest\n{\n    import core.stdc.stdio;\n\n    void printBiguint(const uint [] data)\n    {\n        char [] buff = biguintToHex(new char[data.length*9], data, '_');\n        printf(\"%.*s\\n\", buff.length, buff.ptr);\n    }\n\n    void printDecimalBigUint(BigUint data)\n    {\n        auto str = data.toDecimalString(0);\n        printf(\"%.*s\\n\", str.length, str.ptr);\n    }\n\n    uint [] a, b;\n    a = new uint[43];\n    b = new uint[179];\n    for (int i=0; i<a.length; ++i) a[i] = 0x1234_B6E9 + i;\n    for (int i=0; i<b.length; ++i) b[i] = 0x1BCD_8763 - i*546;\n\n    a[$-1] |= 0x8000_0000;\n    uint [] r = new uint[a.length];\n    uint [] q = new uint[b.length-a.length+1];\n\n    divModInternal(q, r, b, a);\n    q = q[0..$-1];\n    uint [] r1 = r.dup;\n    uint [] q1 = q.dup;\n    blockDivMod(q, b, a);\n    r = b[0 .. a.length];\n    assert(r[] == r1[]);\n    assert(q[] == q1[]);\n}\n\n// biguintToOctal\n@safe unittest\n{\n    enum bufSize = 5 * BigDigitBits / 3 + 1;\n    auto buf = new char[bufSize];\n    size_t i;\n    BigDigit[] data = [ 342391 ];\n\n    // Basic functionality with single word\n    i = biguintToOctal(buf, data);\n    assert(i == bufSize - 7 && buf[i .. $] == \"1234567\");\n\n    // Test carrying bits between words\n    data = [ 0x77053977, 0x39770539, 0x00000005 ];\n    i = biguintToOctal(buf, data);\n    assert(i == bufSize - 23 && buf[i .. $] == \"12345670123456701234567\");\n\n    // Test carried bits in the last word\n    data = [ 0x80000000 ];\n    i = biguintToOctal(buf, data);\n    assert(buf[i .. $] == \"20000000000\");\n\n    // Test boundary between 3rd and 4th word where the number of bits is\n    // divisible by 3 and no bits should be carried.\n    //\n    // The 0xC0000000's are for \"poisoning\" the carry to be non-zero when the\n    // rollover happens, so that if any bugs happen in wrongly adding the carry\n    // to the next word, non-zero bits will show up in the output.\n    data = [ 0xC0000000, 0xC0000000, 0xC0000000, 0x00000010 ];\n    i = biguintToOctal(buf, data);\n    assert(buf[i .. $] == \"2060000000001400000000030000000000\");\n\n    // Boundary case: 0\n    data = [ 0 ];\n    i = biguintToOctal(buf, data);\n    assert(buf[i .. $] == \"0\");\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/math/biguintnoasm.d",
    "content": "/** Arbitrary precision arithmetic ('bignum') for processors with no asm support\n *\n * All functions operate on arrays of uints, stored LSB first.\n * If there is a destination array, it will be the first parameter.\n * Currently, all of these functions are subject to change, and are\n * intended for internal use only.\n * This module is intended only to assist development of high-speed routines\n * on currently unsupported processors.\n * The X86 asm version is about 30 times faster than the D version (DMD).\n */\n\n/*          Copyright Don Clugston 2008 - 2010.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\n\nmodule std.internal.math.biguintnoasm;\n\nnothrow:\n@safe:\n\npublic:\nalias BigDigit = uint; // A Bignum is an array of BigDigits.\n\n    // Limits for when to switch between multiplication algorithms.\nenum int KARATSUBALIMIT = 10; // Minimum value for which Karatsuba is worthwhile.\nenum int KARATSUBASQUARELIMIT = 12; // Minimum value for which square Karatsuba is worthwhile\n\n\n/** Multi-byte addition or subtraction\n *    dest[] = src1[] + src2[] + carry (0 or 1).\n * or dest[] = src1[] - src2[] - carry (0 or 1).\n * Returns carry or borrow (0 or 1).\n * Set op == '+' for addition, '-' for subtraction.\n */\nuint multibyteAddSub(char op)(uint[] dest, const(uint) [] src1,\n    const (uint) [] src2, uint carry) pure @nogc @safe\n{\n    ulong c = carry;\n    for (size_t i = 0; i < src2.length; ++i)\n    {\n        static if (op=='+') c = c  + src1[i] + src2[i];\n             else           c = cast(ulong) src1[i] - src2[i] - c;\n        dest[i] = cast(uint) c;\n        c = (c > 0xFFFF_FFFF);\n    }\n    return cast(uint) c;\n}\n\n@safe unittest\n{\n    uint [] a = new uint[40];\n    uint [] b = new uint[40];\n    uint [] c = new uint[40];\n    for (size_t i = 0; i < a.length; ++i)\n    {\n        if (i&1) a[i]=cast(uint)(0x8000_0000 + i);\n        else a[i]=cast(uint) i;\n        b[i]= 0x8000_0003;\n    }\n    c[19]=0x3333_3333;\n    uint carry = multibyteAddSub!('+')(c[0 .. 18], b[0 .. 18], a[0 .. 18], 0);\n    assert(c[0]==0x8000_0003);\n    assert(c[1]==4);\n    assert(c[19]==0x3333_3333); // check for overrun\n    assert(carry == 1);\n    for (size_t i = 0; i < a.length; ++i)\n    {\n        a[i] = b[i] = c[i] = 0;\n    }\n    a[8]=0x048D159E;\n    b[8]=0x048D159E;\n    a[10]=0x1D950C84;\n    b[10]=0x1D950C84;\n    a[5] =0x44444444;\n    carry = multibyteAddSub!('-')(a[0 .. 12], a[0 .. 12], b[0 .. 12], 0);\n    assert(a[11] == 0);\n    for (size_t i = 0; i < 10; ++i)\n        if (i != 5)\n            assert(a[i] == 0);\n\n    for (size_t q = 3; q < 36; ++q)\n    {\n        for (size_t i = 0; i< a.length; ++i)\n        {\n            a[i] = b[i] = c[i] = 0;\n        }\n        a[q-2]=0x040000;\n        b[q-2]=0x040000;\n       carry = multibyteAddSub!('-')(a[0 .. q], a[0 .. q], b[0 .. q], 0);\n       assert(a[q-2]==0);\n    }\n}\n\n\n\n/** dest[] += carry, or dest[] -= carry.\n *  op must be '+' or '-'\n *  Returns final carry or borrow (0 or 1)\n */\nuint multibyteIncrementAssign(char op)(uint[] dest, uint carry)\n    pure @nogc @safe\n{\n    static if (op=='+')\n    {\n        ulong c = carry;\n        c += dest[0];\n        dest[0] = cast(uint) c;\n        if (c <= 0xFFFF_FFFF)\n            return 0;\n\n        for (size_t i = 1; i < dest.length; ++i)\n        {\n            ++dest[i];\n            if (dest[i] != 0)\n                return 0;\n        }\n        return 1;\n    }\n    else\n    {\n        ulong c = carry;\n        c = dest[0] - c;\n        dest[0] = cast(uint) c;\n        if (c <= 0xFFFF_FFFF)\n            return 0;\n        for (size_t i = 1; i < dest.length; ++i)\n        {\n            --dest[i];\n            if (dest[i] != 0xFFFF_FFFF)\n                return 0;\n        }\n        return 1;\n    }\n}\n\n/** dest[] = src[] << numbits\n *  numbits must be in the range 1 .. 31\n */\nuint multibyteShl(uint [] dest, const(uint) [] src, uint numbits)\n    pure @nogc @safe\n{\n    ulong c = 0;\n    for (size_t i = 0; i < dest.length; ++i)\n    {\n        c += (cast(ulong)(src[i]) << numbits);\n        dest[i] = cast(uint) c;\n        c >>>= 32;\n   }\n   return cast(uint) c;\n}\n\n\n/** dest[] = src[] >> numbits\n *  numbits must be in the range 1 .. 31\n */\nvoid multibyteShr(uint [] dest, const(uint) [] src, uint numbits)\n    pure @nogc @safe\n{\n    ulong c = 0;\n    for (ptrdiff_t i = dest.length; i != 0; --i)\n    {\n        c += (src[i-1] >>numbits) + (cast(ulong)(src[i-1]) << (64 - numbits));\n        dest[i-1] = cast(uint) c;\n        c >>>= 32;\n   }\n}\n\n@safe unittest\n{\n\n    uint [] aa = [0x1222_2223, 0x4555_5556, 0x8999_999A, 0xBCCC_CCCD, 0xEEEE_EEEE];\n    multibyteShr(aa[0..$-2], aa, 4);\n    assert(aa[0] == 0x6122_2222 && aa[1] == 0xA455_5555 && aa[2] == 0x0899_9999);\n    assert(aa[3] == 0xBCCC_CCCD);\n\n    aa = [0x1222_2223, 0x4555_5556, 0x8999_999A, 0xBCCC_CCCD, 0xEEEE_EEEE];\n    multibyteShr(aa[0..$-1], aa, 4);\n    assert(aa[0] == 0x6122_2222 && aa[1] == 0xA455_5555\n        && aa[2] == 0xD899_9999 && aa[3] == 0x0BCC_CCCC);\n\n    aa = [0xF0FF_FFFF, 0x1222_2223, 0x4555_5556, 0x8999_999A, 0xBCCC_CCCD,\n        0xEEEE_EEEE];\n    multibyteShl(aa[1 .. 4], aa[1..$], 4);\n    assert(aa[0] == 0xF0FF_FFFF && aa[1] == 0x2222_2230\n        && aa[2]==0x5555_5561 && aa[3]==0x9999_99A4 && aa[4]==0x0BCCC_CCCD);\n}\n\n/** dest[] = src[] * multiplier + carry.\n * Returns carry.\n */\nuint multibyteMul(uint[] dest, const(uint)[] src, uint multiplier, uint carry)\n    pure @nogc @safe\n{\n    assert(dest.length == src.length);\n    ulong c = carry;\n    for (size_t i = 0; i < src.length; ++i)\n    {\n        c += cast(ulong)(src[i]) * multiplier;\n        dest[i] = cast(uint) c;\n        c>>=32;\n    }\n    return cast(uint) c;\n}\n\n@safe unittest\n{\n    uint [] aa = [0xF0FF_FFFF, 0x1222_2223, 0x4555_5556, 0x8999_999A,\n        0xBCCC_CCCD, 0xEEEE_EEEE];\n    multibyteMul(aa[1 .. 4], aa[1 .. 4], 16, 0);\n    assert(aa[0] == 0xF0FF_FFFF && aa[1] == 0x2222_2230 && aa[2]==0x5555_5561\n        && aa[3]==0x9999_99A4 && aa[4]==0x0BCCC_CCCD);\n}\n\n/**\n * dest[] += src[] * multiplier + carry(0 .. FFFF_FFFF).\n * Returns carry out of MSB (0 .. FFFF_FFFF).\n */\nuint multibyteMulAdd(char op)(uint [] dest, const(uint)[] src,\n    uint multiplier, uint carry) pure @nogc @safe\n{\n    assert(dest.length == src.length);\n    ulong c = carry;\n    for (size_t i = 0; i < src.length; ++i)\n    {\n        static if (op=='+')\n        {\n            c += cast(ulong)(multiplier) * src[i]  + dest[i];\n            dest[i] = cast(uint) c;\n            c >>= 32;\n        }\n        else\n        {\n            c += cast(ulong) multiplier * src[i];\n            ulong t = cast(ulong) dest[i] - cast(uint) c;\n            dest[i] = cast(uint) t;\n            c = cast(uint)((c >> 32) - (t >> 32));\n        }\n    }\n    return cast(uint) c;\n}\n\n@safe unittest\n{\n\n    uint [] aa = [0xF0FF_FFFF, 0x1222_2223, 0x4555_5556, 0x8999_999A,\n        0xBCCC_CCCD, 0xEEEE_EEEE];\n    uint [] bb = [0x1234_1234, 0xF0F0_F0F0, 0x00C0_C0C0, 0xF0F0_F0F0,\n        0xC0C0_C0C0];\n    multibyteMulAdd!('+')(bb[1..$-1], aa[1..$-2], 16, 5);\n    assert(bb[0] == 0x1234_1234 && bb[4] == 0xC0C0_C0C0);\n    assert(bb[1] == 0x2222_2230 + 0xF0F0_F0F0 + 5\n        && bb[2] == 0x5555_5561 + 0x00C0_C0C0 + 1\n        && bb[3] == 0x9999_99A4 + 0xF0F0_F0F0 );\n}\n\n\n/**\n   Sets result = result[0 .. left.length] + left * right\n\n   It is defined in this way to allow cache-efficient multiplication.\n   This function is equivalent to:\n    ----\n    for (size_t i = 0; i< right.length; ++i)\n    {\n        dest[left.length + i] = multibyteMulAdd(dest[i .. left.length+i],\n                left, right[i], 0);\n    }\n    ----\n */\nvoid multibyteMultiplyAccumulate(uint [] dest, const(uint)[] left, const(uint)\n        [] right) pure @nogc @safe\n{\n    for (size_t i = 0; i < right.length; ++i)\n    {\n        dest[left.length + i] = multibyteMulAdd!('+')(dest[i .. left.length+i],\n                left, right[i], 0);\n    }\n}\n\n/**  dest[] /= divisor.\n * overflow is the initial remainder, and must be in the range 0 .. divisor-1.\n */\nuint multibyteDivAssign(uint [] dest, uint divisor, uint overflow)\n    pure @nogc @safe\n{\n    ulong c = cast(ulong) overflow;\n    for (ptrdiff_t i = dest.length-1; i >= 0; --i)\n    {\n        c = (c << 32) + cast(ulong)(dest[i]);\n        uint q = cast(uint)(c/divisor);\n        c -= divisor * q;\n        dest[i] = q;\n    }\n    return cast(uint) c;\n}\n\n@safe unittest\n{\n    uint [] aa = new uint[101];\n    for (uint i = 0; i < aa.length; ++i)\n        aa[i] = 0x8765_4321 * (i+3);\n    uint overflow = multibyteMul(aa, aa, 0x8EFD_FCFB, 0x33FF_7461);\n    uint r = multibyteDivAssign(aa, 0x8EFD_FCFB, overflow);\n    for (uint i=0; i<aa.length; ++i)\n    {\n        assert(aa[i] == 0x8765_4321 * (i+3));\n    }\n    assert(r == 0x33FF_7461);\n\n}\n// Set dest[2*i .. 2*i+1]+=src[i]*src[i]\nvoid multibyteAddDiagonalSquares(uint[] dest, const(uint)[] src)\n    pure @nogc @safe\n{\n    ulong c = 0;\n    for (size_t i = 0; i < src.length; ++i)\n    {\n        // At this point, c is 0 or 1, since FFFF*FFFF+FFFF_FFFF = 1_0000_0000.\n        c += cast(ulong)(src[i]) * src[i] + dest[2*i];\n        dest[2*i] = cast(uint) c;\n        c = (c>>=32) + dest[2*i+1];\n        dest[2*i+1] = cast(uint) c;\n        c >>= 32;\n    }\n}\n\n// Does half a square multiply. (square = diagonal + 2*triangle)\nvoid multibyteTriangleAccumulate(uint[] dest, const(uint)[] x)\n    pure @nogc @safe\n{\n    // x[0]*x[1...$] + x[1]*x[2..$] + ... + x[$-2]x[$-1..$]\n    dest[x.length] = multibyteMul(dest[1 .. x.length], x[1..$], x[0], 0);\n    if (x.length < 4)\n    {\n        if (x.length == 3)\n        {\n            ulong c = cast(ulong)(x[$-1]) * x[$-2]  + dest[2*x.length-3];\n            dest[2*x.length - 3] = cast(uint) c;\n            c >>= 32;\n            dest[2*x.length - 2] = cast(uint) c;\n        }\n        return;\n    }\n    for (size_t i = 2; i < x.length - 2; ++i)\n    {\n        dest[i-1+ x.length] = multibyteMulAdd!('+')(\n             dest[i+i-1 .. i+x.length-1], x[i..$], x[i-1], 0);\n    }\n        // Unroll the last two entries, to reduce loop overhead:\n    ulong  c = cast(ulong)(x[$-3]) * x[$-2] + dest[2*x.length-5];\n    dest[2*x.length-5] = cast(uint) c;\n    c >>= 32;\n    c += cast(ulong)(x[$-3]) * x[$-1] + dest[2*x.length-4];\n    dest[2*x.length-4] = cast(uint) c;\n    c >>= 32;\n    c += cast(ulong)(x[$-1]) * x[$-2];\n    dest[2*x.length-3] = cast(uint) c;\n    c >>= 32;\n    dest[2*x.length-2] = cast(uint) c;\n}\n\nvoid multibyteSquare(BigDigit[] result, const(BigDigit) [] x) pure @nogc @safe\n{\n    multibyteTriangleAccumulate(result, x);\n    result[$-1] = multibyteShl(result[1..$-1], result[1..$-1], 1); // mul by 2\n    result[0] = 0;\n    multibyteAddDiagonalSquares(result, x);\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/math/errorfunction.d",
    "content": "/**\n * Error Functions and Normal Distribution.\n *\n * License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Copyright: Based on the CEPHES math library, which is\n *            Copyright (C) 1994 Stephen L. Moshier (moshier@world.std.com).\n * Authors:   Stephen L. Moshier, ported to D by Don Clugston and David Nadlinger\n */\n/**\n * Macros:\n *  NAN = $(RED NAN)\n *  SUP = <span style=\"vertical-align:super;font-size:smaller\">$0</span>\n *  GAMMA =  &#915;\n *  INTEGRAL = &#8747;\n *  INTEGRATE = $(BIG &#8747;<sub>$(SMALL $1)</sub><sup>$2</sup>)\n *  POWER = $1<sup>$2</sup>\n *  BIGSUM = $(BIG &Sigma; <sup>$2</sup><sub>$(SMALL $1)</sub>)\n *  CHOOSE = $(BIG &#40;) <sup>$(SMALL $1)</sup><sub>$(SMALL $2)</sub> $(BIG &#41;)\n *  TABLE_SV = <table border=\"1\" cellpadding=\"4\" cellspacing=\"0\">\n *      <caption>Special Values</caption>\n *      $0</table>\n *  SVH = $(TR $(TH $1) $(TH $2))\n *  SV  = $(TR $(TD $1) $(TD $2))\n */\nmodule std.internal.math.errorfunction;\nimport std.math;\n\npure:\nnothrow:\n@safe:\n@nogc:\n\nprivate {\nimmutable real EXP_2  = 0.135335283236612691893999494972484403L; /* exp(-2) */\nenum real SQRT2PI = 2.50662827463100050241576528481104525L; // sqrt(2pi)\n\n\nenum real MAXLOG = 0x1.62e42fefa39ef358p+13L;  // log(real.max)\nenum real MINLOG = -0x1.6436716d5406e6d8p+13L; // log(real.min*real.epsilon) = log(smallest denormal)\n}\n\nT rationalPoly(T)(T x, const(T) [] numerator, const(T) [] denominator) pure nothrow\n{\n    return poly(x, numerator)/poly(x, denominator);\n}\n\n\nprivate {\n\n/* erfc(x) = exp(-x^2) P(1/x)/Q(1/x)\n   1/8 <= 1/x <= 1\n   Peak relative error 5.8e-21  */\nimmutable real[10] P = [ -0x1.30dfa809b3cc6676p-17, 0x1.38637cd0913c0288p+18,\n   0x1.2f015e047b4476bp+22, 0x1.24726f46aa9ab08p+25, 0x1.64b13c6395dc9c26p+27,\n   0x1.294c93046ad55b5p+29, 0x1.5962a82f92576dap+30, 0x1.11a709299faba04ap+31,\n   0x1.11028065b087be46p+31, 0x1.0d8ef40735b097ep+30\n];\n\nimmutable real[11] Q = [ 0x1.14d8e2a72dec49f4p+19, 0x1.0c880ff467626e1p+23,\n   0x1.04417ef060b58996p+26, 0x1.404e61ba86df4ebap+28, 0x1.0f81887bc82b873ap+30,\n   0x1.4552a5e39fb49322p+31, 0x1.11779a0ceb2a01cep+32, 0x1.3544dd691b5b1d5cp+32,\n   0x1.a91781f12251f02ep+31, 0x1.0d8ef3da605a1c86p+30, 1.0\n];\n\n// For 128 bit quadruple-precision floats, we use a higher-precision implementation\n// with more polynomial segments.\nenum isIEEEQuadruple = floatTraits!real.realFormat == RealFormat.ieeeQuadruple;\nstatic if (isIEEEQuadruple)\n{\n    // erfc(x + 0.25) = erfc(0.25) + x R(x)\n    // 0 <= x < 0.125\n    // Peak relative error 1.4e-35\n    immutable real[9] RNr13 = [\n        -2.353707097641280550282633036456457014829E3L,\n        3.871159656228743599994116143079870279866E2L,\n        -3.888105134258266192210485617504098426679E2L,\n        -2.129998539120061668038806696199343094971E1L,\n        -8.125462263594034672468446317145384108734E1L,\n        8.151549093983505810118308635926270319660E0L,\n        -5.033362032729207310462422357772568553670E0L,\n        -4.253956621135136090295893547735851168471E-2L,\n        -8.098602878463854789780108161581050357814E-2L\n    ];\n    immutable real[9] RDr13 = [\n        2.220448796306693503549505450626652881752E3L,\n        1.899133258779578688791041599040951431383E2L,\n        1.061906712284961110196427571557149268454E3L,\n        7.497086072306967965180978101974566760042E1L,\n        2.146796115662672795876463568170441327274E2L,\n        1.120156008362573736664338015952284925592E1L,\n        2.211014952075052616409845051695042741074E1L,\n        6.469655675326150785692908453094054988938E-1L,\n        1.0\n    ];\n\n    // erfc(0.25) = C13a + C13b to extra precision.\n    immutable real C13a = 0.723663330078125L;\n    immutable real C13b = 1.0279753638067014931732235184287934646022E-5L;\n\n    // erfc(x + 0.375) = erfc(0.375) + x R(x)\n    // 0 <= x < 0.125\n    // Peak relative error 1.2e-35\n    immutable real[9] RNr14 = [\n        -2.446164016404426277577283038988918202456E3L,\n        6.718753324496563913392217011618096698140E2L,\n        -4.581631138049836157425391886957389240794E2L,\n        -2.382844088987092233033215402335026078208E1L,\n        -7.119237852400600507927038680970936336458E1L,\n        1.313609646108420136332418282286454287146E1L,\n        -6.188608702082264389155862490056401365834E0L,\n        -2.787116601106678287277373011101132659279E-2L,\n        -2.230395570574153963203348263549700967918E-2L\n    ];\n    immutable real[9] RDr14 = [\n        2.495187439241869732696223349840963702875E3L,\n        2.503549449872925580011284635695738412162E2L,\n        1.159033560988895481698051531263861842461E3L,\n        9.493751466542304491261487998684383688622E1L,\n        2.276214929562354328261422263078480321204E2L,\n        1.367697521219069280358984081407807931847E1L,\n        2.276988395995528495055594829206582732682E1L,\n        7.647745753648996559837591812375456641163E-1L,\n        1.0\n    ];\n\n    // erfc(0.375) = C14a + C14b to extra precision.\n    immutable real C14a = 0.5958709716796875L;\n    immutable real C14b = 1.2118885490201676174914080878232469565953E-5L;\n\n    // erfc(x + 0.5) = erfc(0.5) + x R(x)\n    // 0 <= x < 0.125\n    // Peak relative error 4.7e-36\n    immutable real[9] RNr15 = [\n        -2.624212418011181487924855581955853461925E3L,\n        8.473828904647825181073831556439301342756E2L,\n        -5.286207458628380765099405359607331669027E2L,\n        -3.895781234155315729088407259045269652318E1L,\n        -6.200857908065163618041240848728398496256E1L,\n        1.469324610346924001393137895116129204737E1L,\n        -6.961356525370658572800674953305625578903E0L,\n        5.145724386641163809595512876629030548495E-3L,\n        1.990253655948179713415957791776180406812E-2L\n    ];\n    immutable real[9] RDr15 = [\n        2.986190760847974943034021764693341524962E3L,\n        5.288262758961073066335410218650047725985E2L,\n        1.363649178071006978355113026427856008978E3L,\n        1.921707975649915894241864988942255320833E2L,\n        2.588651100651029023069013885900085533226E2L,\n        2.628752920321455606558942309396855629459E1L,\n        2.455649035885114308978333741080991380610E1L,\n        1.378826653595128464383127836412100939126E0L,\n        1.0\n    ];\n    // erfc(0.5) = C15a + C15b to extra precision.\n    immutable real C15a = 0.4794921875L;\n    immutable real C15b = 7.9346869534623172533461080354712635484242E-6L;\n\n    // erfc(x + 0.625) = erfc(0.625) + x R(x)\n    // 0 <= x < 0.125\n    // Peak relative error 5.1e-36\n    immutable real[9] RNr16 = [\n        -2.347887943200680563784690094002722906820E3L,\n        8.008590660692105004780722726421020136482E2L,\n        -5.257363310384119728760181252132311447963E2L,\n        -4.471737717857801230450290232600243795637E1L,\n        -4.849540386452573306708795324759300320304E1L,\n        1.140885264677134679275986782978655952843E1L,\n        -6.731591085460269447926746876983786152300E0L,\n        1.370831653033047440345050025876085121231E-1L,\n        2.022958279982138755020825717073966576670E-2L,\n    ];\n    immutable real[9] RDr16 = [\n        3.075166170024837215399323264868308087281E3L,\n        8.730468942160798031608053127270430036627E2L,\n        1.458472799166340479742581949088453244767E3L,\n        3.230423687568019709453130785873540386217E2L,\n        2.804009872719893612081109617983169474655E2L,\n        4.465334221323222943418085830026979293091E1L,\n        2.612723259683205928103787842214809134746E1L,\n        2.341526751185244109722204018543276124997E0L,\n        1.0\n    ];\n    // erfc(0.625) = C16a + C16b to extra precision.\n    immutable real C16a = 0.3767547607421875L;\n    immutable real C16b = 4.3570693945275513594941232097252997287766E-6L;\n\n    // erfc(x + 0.75) = erfc(0.75) + x R(x)\n    // 0 <= x < 0.125\n    // Peak relative error 1.7e-35\n    immutable real[9] RNr17 = [\n        -1.767068734220277728233364375724380366826E3L,\n        6.693746645665242832426891888805363898707E2L,\n        -4.746224241837275958126060307406616817753E2L,\n        -2.274160637728782675145666064841883803196E1L,\n        -3.541232266140939050094370552538987982637E1L,\n        6.988950514747052676394491563585179503865E0L,\n        -5.807687216836540830881352383529281215100E0L,\n        3.631915988567346438830283503729569443642E-1L,\n        -1.488945487149634820537348176770282391202E-2L\n    ];\n    immutable real[9] RDr17 = [\n        2.748457523498150741964464942246913394647E3L,\n        1.020213390713477686776037331757871252652E3L,\n        1.388857635935432621972601695296561952738E3L,\n        3.903363681143817750895999579637315491087E2L,\n        2.784568344378139499217928969529219886578E2L,\n        5.555800830216764702779238020065345401144E1L,\n        2.646215470959050279430447295801291168941E1L,\n        2.984905282103517497081766758550112011265E0L,\n        1.0\n    ];\n    // erfc(0.75) = C17a + C17b to extra precision.\n    immutable real C17a = 0.2888336181640625L;\n    immutable real C17b = 1.0748182422368401062165408589222625794046E-5L;\n\n\n    // erfc(x + 0.875) = erfc(0.875) + x R(x)\n    // 0 <= x < 0.125\n    // Peak relative error 2.2e-35\n    immutable real[9] RNr18 = [\n        -1.342044899087593397419622771847219619588E3L,\n        6.127221294229172997509252330961641850598E2L,\n        -4.519821356522291185621206350470820610727E2L,\n        1.223275177825128732497510264197915160235E1L,\n        -2.730789571382971355625020710543532867692E1L,\n        4.045181204921538886880171727755445395862E0L,\n        -4.925146477876592723401384464691452700539E0L,\n        5.933878036611279244654299924101068088582E-1L,\n        -5.557645435858916025452563379795159124753E-2L\n    ];\n    immutable real[9] RDr18 = [\n        2.557518000661700588758505116291983092951E3L,\n        1.070171433382888994954602511991940418588E3L,\n        1.344842834423493081054489613250688918709E3L,\n        4.161144478449381901208660598266288188426E2L,\n        2.763670252219855198052378138756906980422E2L,\n        5.998153487868943708236273854747564557632E1L,\n        2.657695108438628847733050476209037025318E1L,\n        3.252140524394421868923289114410336976512E0L,\n        1.0\n    ];\n\n    // erfc(0.875) = C18a + C18b to extra precision.\n    immutable real C18a = 0.215911865234375L;\n    immutable real C18b = 1.3073705765341685464282101150637224028267E-5L;\n\n    // erfc(x + 1.0) = erfc(1.0) + x R(x)\n    // 0 <= x < 0.125\n    // Peak relative error 1.6e-35\n    immutable real[9] RNr19 = [\n        -1.139180936454157193495882956565663294826E3L,\n        6.134903129086899737514712477207945973616E2L,\n        -4.628909024715329562325555164720732868263E2L,\n        4.165702387210732352564932347500364010833E1L,\n        -2.286979913515229747204101330405771801610E1L,\n        1.870695256449872743066783202326943667722E0L,\n        -4.177486601273105752879868187237000032364E0L,\n        7.533980372789646140112424811291782526263E-1L,\n        -8.629945436917752003058064731308767664446E-2L\n    ];\n    immutable real[9] RDr19 = [\n        2.744303447981132701432716278363418643778E3L,\n        1.266396359526187065222528050591302171471E3L,\n        1.466739461422073351497972255511919814273E3L,\n        4.868710570759693955597496520298058147162E2L,\n        2.993694301559756046478189634131722579643E2L,\n        6.868976819510254139741559102693828237440E1L,\n        2.801505816247677193480190483913753613630E1L,\n        3.604439909194350263552750347742663954481E0L,\n        1.0\n    ];\n\n    // erfc(1.0) = C19a + C19b to extra precision.\n    immutable real C19a = 0.15728759765625L;\n    immutable real C19b = 1.1609394035130658779364917390740703933002E-5L;\n\n    // erfc(x + 1.125) = erfc(1.125) + x R(x)\n    // 0 <= x < 0.125\n    // Peak relative error 3.6e-36\n    immutable real[9] RNr20 = [\n        -9.652706916457973956366721379612508047640E2L,\n        5.577066396050932776683469951773643880634E2L,\n        -4.406335508848496713572223098693575485978E2L,\n        5.202893466490242733570232680736966655434E1L,\n        -1.931311847665757913322495948705563937159E1L,\n        -9.364318268748287664267341457164918090611E-2L,\n        -3.306390351286352764891355375882586201069E0L,\n        7.573806045289044647727613003096916516475E-1L,\n        -9.611744011489092894027478899545635991213E-2L\n    ];\n    immutable real[9] RDr20 = [\n        3.032829629520142564106649167182428189014E3L,\n        1.659648470721967719961167083684972196891E3L,\n        1.703545128657284619402511356932569292535E3L,\n        6.393465677731598872500200253155257708763E2L,\n        3.489131397281030947405287112726059221934E2L,\n        8.848641738570783406484348434387611713070E1L,\n        3.132269062552392974833215844236160958502E1L,\n        4.430131663290563523933419966185230513168E0L,\n        1.0\n    ];\n\n    // erfc(1.125) = C20a + C20b to extra precision.\n    immutable real C20a = 0.111602783203125L;\n    immutable real C20b = 8.9850951672359304215530728365232161564636E-6L;\n\n    // erfc(x) = exp(-x^2) 1/x R(1/x^2) / S(1/x^2)\n    // 7/8 <= 1/x < 1\n    // Peak relative error 1.4e-35\n    immutable real[10] RNr8 = [\n        3.587451489255356250759834295199296936784E1L,\n        5.406249749087340431871378009874875889602E2L,\n        2.931301290625250886238822286506381194157E3L,\n        7.359254185241795584113047248898753470923E3L,\n        9.201031849810636104112101947312492532314E3L,\n        5.749697096193191467751650366613289284777E3L,\n        1.710415234419860825710780802678697889231E3L,\n        2.150753982543378580859546706243022719599E2L,\n        8.740953582272147335100537849981160931197E0L,\n        4.876422978828717219629814794707963640913E-2L\n    ];\n    immutable real[10] RDr8 = [\n        6.358593134096908350929496535931630140282E1L,\n        9.900253816552450073757174323424051765523E2L,\n        5.642928777856801020545245437089490805186E3L,\n        1.524195375199570868195152698617273739609E4L,\n        2.113829644500006749947332935305800887345E4L,\n        1.526438562626465706267943737310282977138E4L,\n        5.561370922149241457131421914140039411782E3L,\n        9.394035530179705051609070428036834496942E2L,\n        6.147019596150394577984175188032707343615E1L,\n        1.0L\n    ];\n\n    // erfc(x) = exp(-x^2) 1/x R(1/x^2) / S(1/x^2)\n    // 3/4 <= 1/x < 7/8\n    // Peak relative error 1.7e-36\n    immutable real[10] RNr7 = [\n        1.293515364043117601705535485785956592493E2L,\n        2.474534371269189867053251150063459055230E3L,\n        1.756537563959875738809491329250457486510E4L,\n        5.977479535376639763773153344676726091607E4L,\n        1.054313816139671870123172936972055385049E5L,\n        9.754699773487726957401038094714603033904E4L,\n        4.579131242577671038339922925213209214880E4L,\n        1.000710322164510887997115157797717324370E4L,\n        8.496863250712471449526805271633794700452E2L,\n        1.797349831386892396933210199236530557333E1L\n    ];\n    immutable real[11] RDr7 = [\n        2.292696320307033494820399866075534515002E2L,\n        4.500632608295626968062258401895610053116E3L,\n        3.321218723485498111535866988511716659339E4L,\n        1.196084512221845156596781258490840961462E5L,\n        2.287033883912529843927983406878910939930E5L,\n        2.370223495794642027268482075021298394425E5L,\n        1.305173734022437154610938308944995159199E5L,\n        3.589386258485887630236490009835928559621E4L,\n        4.339996864041074149726360516336773136101E3L,\n        1.753135522665469574605384979152863899099E2L,\n        1.0L\n    ];\n\n    // erfc(x) = exp(-x^2) 1/x R(1/x^2) / S(1/x^2)\n    // 5/8 <= 1/x < 3/4\n    // Peak relative error 1.6e-35\n    immutable real[10] RNr6 = [\n        1.423313561367394923305025174137639124533E1L,\n        3.244462503273003837514629113846075327206E2L,\n        2.784937282403293364911673341412846781934E3L,\n        1.163060685810874867196849890286455473382E4L,\n        2.554141394931962276102205517358731053756E4L,\n        2.982733782500729530503336931258698708782E4L,\n        1.789683564523810605328169719436374742840E4L,\n        5.056032142227470121262177112822018882754E3L,\n        5.605349942234782054561269306895707034586E2L,\n        1.561652599080729507274832243665726064881E1L\n    ];\n    immutable real[11] RDr6 = [\n        2.522757606611479946069351519410222913326E1L,\n        5.876797910931896554014229647006604017806E2L,\n        5.211092128250480712011248211246144751074E3L,\n        2.282679910855404599271496827409168580797E4L,\n        5.371245819205596609986320599133109262447E4L,\n        6.926186102106400355114925675028888924445E4L,\n        4.794366033363621432575096487724913414473E4L,\n        1.673190682734065914573814938835674963896E4L,\n        2.589544846151313120096957014256536236242E3L,\n        1.349438432583208276883323156200117027433E2L,\n        1.0L\n    ];\n\n    // erfc(x) = exp(-x^2) 1/x R(1/x^2) / S(1/x^2)\n    // 1/2 <= 1/x < 5/8\n    // Peak relative error 4.3e-36\n    immutable real[11] RNr5 = [\n        6.743447478279267339131211137241149796763E-2L,\n        2.031339015932962998168472743355874796350E0L,\n        2.369234815713196480221800940201367484379E1L,\n        1.387819614016107433603101545594790875922E2L,\n        4.435600256936515839937720907171966121786E2L,\n        7.881577949936817507981170892417739733047E2L,\n        7.615749099291545976179905281851765734680E2L,\n        3.752484528663442467089606663006771157777E2L,\n        8.279644286027145214308303292537009564726E1L,\n        6.201462983413738162709722770960040042647E0L,\n        6.649631608720062333043506249503378282697E-2L\n    ];\n    immutable real[11] RDr5 = [\n        1.195244945161889822018178270706903972343E-1L,\n        3.660216908153253021384862427197665991311E0L,\n        4.373405883243078019655721779021995159854E1L,\n        2.653305963056235008916733402786877121865E2L,\n        8.921329790491152046318422124415895506335E2L,\n        1.705552231555600759729260640562363304312E3L,\n        1.832711109606893446763174603477244625325E3L,\n        1.056823953275835649973998168744261083316E3L,\n        2.975561981792909722126456997074344895584E2L,\n        3.393149095158232521894537008472203487436E1L,\n        1.0L\n    ];\n\n    // erfc(x) = exp(-x^2) 1/x R(1/x^2) / S(1/x^2)\n    // 3/8 <= 1/x < 1/2\n    // Peak relative error 1.8e-36\n    immutable real[11] RNr4 = [\n        3.558685919236420073872459554885612994007E-2L,\n        1.460223642496950651561817195253277924528E0L,\n        2.379856746555189546876720308841066577268E1L,\n        2.005205521246554860334064698817220160117E2L,\n        9.533374928664989955629120027419490517596E2L,\n        2.623024576994438336130421711314560425373E3L,\n        4.126446434603735586340585027628851620886E3L,\n        3.540675861596687801829655387867654030013E3L,\n        1.506037084891064572653273761987617394259E3L,\n        2.630715699182706745867272452228891752353E2L,\n        1.202476629652900619635409242749750364878E1L\n    ];\n    immutable real[12] RDr4 = [\n        6.307606561714590590399683184410336583739E-2L,\n        2.619717051134271249293056836082721776665E0L,\n        4.344441402681725017630451522968410844608E1L,\n        3.752891116408399440953195184301023399176E2L,\n        1.849305988804654653921972804388006355502E3L,\n        5.358505261991675891835885654499883449403E3L,\n        9.091890995405251314631428721090705475825E3L,\n        8.731418313949291797856351745278287516416E3L,\n        4.420211285043270337492325400764271868740E3L,\n        1.031487363021856106882306509107923200832E3L,\n        8.387036084846046121805145056040429461783E1L,\n        1.0L\n    ];\n\n    // erfc(x) = exp(-x^2) 1/x R(1/x^2) / S(1/x^2)\n    // 1/4 <= 1/x < 3/8\n    // Peak relative error 8.1e-37\n    immutable real[12] RNr3 = [\n        4.584481542956275354582319313040418316755E-5L,\n        2.674923158288848442110883948437930349128E-3L,\n        6.344232532055212248017211243740466847311E-2L,\n        7.985145965992002744933550450451513513963E-1L,\n        5.845078061888281665064746347663123946270E0L,\n        2.566625318816866587482759497608029522596E1L,\n        6.736225182343446605268837827950856640948E1L,\n        1.021796460139598089409347761712730512053E2L,\n        8.344336615515430530929955615400706619764E1L,\n        3.207749011528249356283897356277376306967E1L,\n        4.386185123863412086856423971695142026036E0L,\n        8.971576448581208351826868348023528863856E-2L\n    ];\n    immutable real[12] RDr3 = [\n        8.125781965218112303281657065320409661370E-5L,\n        4.781806762611504685247817818428945295520E-3L,\n        1.147785538413798317790357996845767614561E-1L,\n        1.469285552007088106614218996464752307606E0L,\n        1.101712261349880339221039938999124077650E1L,\n        5.008507527095093413713171655268276861071E1L,\n        1.383058691613468970486425146336829447433E2L,\n        2.264114250278912520501010108736339599752E2L,\n        2.081377197698598680576330179979996940039E2L,\n        9.724438129690013609440151781601781137944E1L,\n        1.907905050771832372089975877589291760121E1L,\n        1.0L\n    ];\n\n    // erfc(x) = exp(-x^2) 1/x R(1/x^2) / S(1/x^2)\n    // 1/8 <= 1/x < 1/4\n    // Peak relative error 1.5e-36\n    immutable real[12] RNr2 = [\n        6.928615158005256885698045840589513728399E-7L,\n        5.616245938942075826026382337922413007879E-5L,\n        1.871624980715261794832358438894219696113E-3L,\n        3.349922063795792371642023765253747563009E-2L,\n        3.531865233974349943956345502463135695834E-1L,\n        2.264714157625072773976468825160906342360E0L,\n        8.810720294489253776747319730638214883026E0L,\n        2.014056685571655833019183248931442888437E1L,\n        2.524586947657190747039554310814128743320E1L,\n        1.520656940937208886246188940244581671609E1L,\n        3.334145500790963675035841482334493680498E0L,\n        1.122108380007109245896534245151140632457E-1L\n    ];\n    immutable real[12] RDr2 = [\n        1.228065061824874795984937092427781089256E-6L,\n        1.001593999520159167559129042893802235969E-4L,\n        3.366527555699367241421450749821030974446E-3L,\n        6.098626947195865254152265585991861150369E-2L,\n        6.541547922508613985813189387198804660235E-1L,\n        4.301130233305371976727117480925676583204E0L,\n        1.737155892350891711527711121692994762909E1L,\n        4.206892112110558214680649401236873828801E1L,\n        5.787487996025016843403524261574779631219E1L,\n        4.094047148590822715163181507813774861621E1L,\n        1.230603930056944875836549716515643997094E1L,\n        1.0L\n    ];\n\n    // erfc(x) = exp(-x^2) 1/x R(1/x^2) / S(1/x^2)\n    // 1/128 <= 1/x < 1/8\n    // Peak relative error 2.2e-36\n    immutable real[10] RNr1 = [\n        1.293111801138199795250035229383033322539E-6L,\n        9.785224720880980456171438759161161816706E-5L,\n        2.932474396233212166056331430621176065943E-3L,\n        4.496429595719847083917435337780697436921E-2L,\n        3.805989855927720844877478869846718877846E-1L,\n        1.789745532222426292126781724570152590071E0L,\n        4.465737379634389318903237306594171764628E0L,\n        5.268535822258082278401240171488850433767E0L,\n        2.258357766807433839494276681092713991651E0L,\n        1.504459334078750002966538036652860809497E-1L\n    ];\n    immutable real[10] RDr1 = [\n        2.291980991578770070179177302906728371406E-6L,\n        1.745845828808028552029674694534934620384E-4L,\n        5.283248841982102317072923869576785278019E-3L,\n        8.221212297078141470944454807434634848018E-2L,\n        7.120500674861902950423510939060230945621E-1L,\n        3.475435367560809622183983439133664598155E0L,\n        9.243253391989233533874386043611304387113E0L,\n        1.227894792475280941511758877318903197188E1L,\n        6.789361410398841316638617624392719077724E0L,\n        1.0L\n    ];\n\n    // erf(z+1)  = erfConst + P(z)/Q(z)\n    // -.125 <= z <= 0\n    // Peak relative error 7.3e-36\n    immutable real erfConst = 0.845062911510467529296875L;\n    immutable real[9] TN2 = [\n        -4.088889697077485301010486931817357000235E1L,\n        7.157046430681808553842307502826960051036E3L,\n        -2.191561912574409865550015485451373731780E3L,\n        2.180174916555316874988981177654057337219E3L,\n        2.848578658049670668231333682379720943455E2L,\n        1.630362490952512836762810462174798925274E2L,\n        6.317712353961866974143739396865293596895E0L,\n        2.450441034183492434655586496522857578066E1L,\n        5.127662277706787664956025545897050896203E-1L\n    ];\n    immutable real[10] TD2 = [\n        1.731026445926834008273768924015161048885E4L,\n        1.209682239007990370796112604286048173750E4L,\n        1.160950290217993641320602282462976163857E4L,\n        5.394294645127126577825507169061355698157E3L,\n        2.791239340533632669442158497532521776093E3L,\n        8.989365571337319032943005387378993827684E2L,\n        2.974016493766349409725385710897298069677E2L,\n        6.148192754590376378740261072533527271947E1L,\n        1.178502892490738445655468927408440847480E1L,\n        1.0L\n    ];\n\n    // erf(x)  = x + x P(x^2)/Q(x^2)\n    // 0 <= x <= 7/8\n    // Peak relative error 1.8e-35\n    immutable real[9] TN1 = [\n        -3.858252324254637124543172907442106422373E10L,\n        9.580319248590464682316366876952214879858E10L,\n        1.302170519734879977595901236693040544854E10L,\n        2.922956950426397417800321486727032845006E9L,\n        1.764317520783319397868923218385468729799E8L,\n        1.573436014601118630105796794840834145120E7L,\n        4.028077380105721388745632295157816229289E5L,\n        1.644056806467289066852135096352853491530E4L,\n        3.390868480059991640235675479463287886081E1L\n    ];\n    immutable real[10] TD1 = [\n        -3.005357030696532927149885530689529032152E11L,\n        -1.342602283126282827411658673839982164042E11L,\n        -2.777153893355340961288511024443668743399E10L,\n        -3.483826391033531996955620074072768276974E9L,\n        -2.906321047071299585682722511260895227921E8L,\n        -1.653347985722154162439387878512427542691E7L,\n        -6.245520581562848778466500301865173123136E5L,\n        -1.402124304177498828590239373389110545142E4L,\n        -1.209368072473510674493129989468348633579E2L,\n        1.0L\n    ];\n}\nelse\n{\n    /* erfc(x) = exp(-x^2) 1/x R(1/x^2) / S(1/x^2)\n       1/128 <= 1/x < 1/8\n       Peak relative error 1.9e-21  */\n    immutable real[5] R = [ 0x1.b9f6d8b78e22459ep-6, 0x1.1b84686b0a4ea43ap-1,\n       0x1.b8f6aebe96000c2ap+1, 0x1.cb1dbedac27c8ec2p+2, 0x1.cf885f8f572a4c14p+1\n    ];\n\n    immutable real[6] S = [\n       0x1.87ae3cae5f65eb5ep-5, 0x1.01616f266f306d08p+0, 0x1.a4abe0411eed6c22p+2,\n       0x1.eac9ce3da600abaap+3, 0x1.5752a9ac2faebbccp+3, 1.0\n    ];\n\n    /* erf(x)  = x P(x^2)/Q(x^2)\n       0 <= x <= 1\n       Peak relative error 7.6e-23  */\n    immutable real[7] T = [ 0x1.0da01654d757888cp+20, 0x1.2eb7497bc8b4f4acp+17,\n       0x1.79078c19530f72a8p+15, 0x1.4eaf2126c0b2c23p+11, 0x1.1f2ea81c9d272a2ep+8,\n       0x1.59ca6e2d866e625p+2, 0x1.c188e0b67435faf4p-4\n    ];\n\n    immutable real[7] U = [ 0x1.dde6025c395ae34ep+19, 0x1.c4bc8b6235df35aap+18,\n       0x1.8465900e88b6903ap+16, 0x1.855877093959ffdp+13, 0x1.e5c44395625ee358p+9,\n       0x1.6a0fed103f1c68a6p+5, 1.0\n    ];\n}\n}\n\n/**\n *  Complementary error function\n *\n * erfc(x) = 1 - erf(x), and has high relative accuracy for\n * values of x far from zero. (For values near zero, use erf(x)).\n *\n *  1 - erf(x) =  2/ $(SQRT)(&pi;)\n *     $(INTEGRAL x, $(INFINITY)) exp( - $(POWER t, 2)) dt\n *\n *\n * For small x, erfc(x) = 1 - erf(x); otherwise rational\n * approximations are computed.\n *\n * A special function expx2(x) is used to suppress error amplification\n * in computing exp(-x^2).\n */\nreal erfc(real a)\n{\n    if (a == real.infinity)\n        return 0.0;\n    if (a == -real.infinity)\n        return 2.0;\n\n    immutable x = (a < 0.0) ? -a : a;\n\n    if (x < (isIEEEQuadruple ? 0.25 : 1.0))\n        return 1.0 - erf(a);\n\n    static if (isIEEEQuadruple)\n    {\n        if (x < 1.25)\n        {\n            real y;\n            final switch (cast(int)(8.0 * x))\n            {\n                case 2:\n                    const z = x - 0.25;\n                    y = C13b + z * rationalPoly(z, RNr13, RDr13);\n                    y += C13a;\n                    break;\n                case 3:\n                    const z = x - 0.375;\n                    y = C14b + z * rationalPoly(z, RNr14, RDr14);\n                    y += C14a;\n                    break;\n                case 4:\n                    const z = x - 0.5;\n                    y = C15b + z * rationalPoly(z, RNr15, RDr15);\n                    y += C15a;\n                    break;\n                case 5:\n                    const z = x - 0.625;\n                    y = C16b + z * rationalPoly(z, RNr16, RDr16);\n                    y += C16a;\n                    break;\n                case 6:\n                    const z = x - 0.75;\n                    y = C17b + z * rationalPoly(z, RNr17, RDr17);\n                    y += C17a;\n                    break;\n                case 7:\n                    const z = x - 0.875;\n                    y = C18b + z * rationalPoly(z, RNr18, RDr18);\n                    y += C18a;\n                    break;\n                case 8:\n                    const z = x - 1.0;\n                    y = C19b + z * rationalPoly(z, RNr19, RDr19);\n                    y += C19a;\n                    break;\n                case 9:\n                    const z = x - 1.125;\n                    y = C20b + z * rationalPoly(z, RNr20, RDr20);\n                    y += C20a;\n                    break;\n            }\n            if (a < 0.0)\n                y = 2.0 - y;\n            return y;\n        }\n    }\n\n    if (-a * a < -MAXLOG)\n    {\n        // underflow\n        if (a < 0.0) return 2.0;\n        else return 0.0;\n    }\n\n    real y;\n    immutable z = expx2(a, -1);\n\n    static if (isIEEEQuadruple)\n    {\n        y = z * erfce(x);\n    }\n    else\n    {\n        y = 1.0 / x;\n        if (x < 8.0)\n            y = z * rationalPoly(y, P, Q);\n        else\n            y = z * y * rationalPoly(y * y, R, S);\n    }\n\n    if (a < 0.0)\n        y = 2.0 - y;\n\n    if (y == 0.0)\n    {\n        // underflow\n        if (a < 0.0) return 2.0;\n        else return 0.0;\n    }\n\n    return y;\n}\n\n\nprivate {\n/* Exponentially scaled erfc function\n   exp(x^2) erfc(x)\n   valid for x > 1.\n   Use with normalDistribution and expx2.  */\nstatic if (isIEEEQuadruple)\n{\n    real erfce(real x)\n    {\n        immutable z = 1.0L / (x * x);\n\n        real p;\n        switch (cast(int)(8.0 / x))\n        {\n            default:\n            case 0:\n                p = rationalPoly(z, RNr1, RDr1);\n                break;\n            case 1:\n                p = rationalPoly(z, RNr2, RDr2);\n                break;\n            case 2:\n                p = rationalPoly(z, RNr3, RDr3);\n                break;\n            case 3:\n                p = rationalPoly(z, RNr4, RDr4);\n                break;\n            case 4:\n                p = rationalPoly(z, RNr5, RDr5);\n                break;\n            case 5:\n                p = rationalPoly(z, RNr6, RDr6);\n                break;\n            case 6:\n                p = rationalPoly(z, RNr7, RDr7);\n                break;\n            case 7:\n                p = rationalPoly(z, RNr8, RDr8);\n                break;\n        }\n        return p / x;\n    }\n}\nelse\n{\n    real erfce(real x)\n    {\n        real y = 1.0/x;\n\n        if (x < 8.0)\n        {\n            return rationalPoly(y, P, Q);\n        }\n        else\n        {\n            return y * rationalPoly(y * y, R, S);\n        }\n    }\n}\n}\n\n/**\n *  Error function\n *\n * The integral is\n *\n *  erf(x) =  2/ $(SQRT)(&pi;)\n *     $(INTEGRAL 0, x) exp( - $(POWER t, 2)) dt\n *\n * The magnitude of x is limited to about 106.56 for IEEE 80-bit\n * arithmetic; 1 or -1 is returned outside this range.\n *\n * For 0 <= |x| < 1, a rational polynomials are used; otherwise\n * erf(x) = 1 - erfc(x).\n *\n * ACCURACY:\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *    IEEE      0,1         50000       2.0e-19     5.7e-20\n */\nreal erf(real x)\n{\n    if (x == 0.0)\n        return x; // deal with negative zero\n    if (x == -real.infinity)\n        return -1.0;\n    if (x == real.infinity)\n        return 1.0;\n    immutable ax = abs(x);\n    if (ax > 1.0L)\n        return 1.0L - erfc(x);\n\n    static if (isIEEEQuadruple)\n    {\n        immutable z = x * x;\n\n        real y;\n        if (ax < 0.875)\n        {\n            y = ax + ax * rationalPoly(x * x, TN1, TD1);\n        }\n        else\n        {\n            y = erfConst + rationalPoly(ax - 1.0L, TN2, TD2);\n        }\n\n        if (x < 0)\n            y = -y;\n        return y;\n    }\n    else\n    {\n        real z = x * x;\n        return x * rationalPoly(x * x, T, U);\n    }\n}\n\n@safe unittest\n{\n    // High resolution test points.\n    enum real erfc0_250 = 0.723663330078125 + 1.0279753638067014931732235184287934646022E-5;\n    enum real erfc0_375 = 0.5958709716796875 + 1.2118885490201676174914080878232469565953E-5;\n    enum real erfc0_500 = 0.4794921875 + 7.9346869534623172533461080354712635484242E-6;\n    enum real erfc0_625 = 0.3767547607421875 + 4.3570693945275513594941232097252997287766E-6;\n    enum real erfc0_750 = 0.2888336181640625 + 1.0748182422368401062165408589222625794046E-5;\n    enum real erfc0_875 = 0.215911865234375 + 1.3073705765341685464282101150637224028267E-5;\n    enum real erfc1_000 = 0.15728759765625 + 1.1609394035130658779364917390740703933002E-5;\n    enum real erfc1_125 = 0.111602783203125 + 8.9850951672359304215530728365232161564636E-6;\n\n    enum real erf0_875  = (1-0.215911865234375) - 1.3073705765341685464282101150637224028267E-5;\n\n    static bool isNaNWithPayload(real x, ulong payload) @safe pure nothrow @nogc\n    {\n      return isNaN(x) && getNaNPayload(x) == payload;\n    }\n\n    assert(feqrel(erfc(0.250L), erfc0_250 )>=real.mant_dig-1);\n    assert(feqrel(erfc(0.375L), erfc0_375 )>=real.mant_dig-0);\n    assert(feqrel(erfc(0.500L), erfc0_500 )>=real.mant_dig-2);\n    assert(feqrel(erfc(0.625L), erfc0_625 )>=real.mant_dig-1);\n    assert(feqrel(erfc(0.750L), erfc0_750 )>=real.mant_dig-1);\n    assert(feqrel(erfc(0.875L), erfc0_875 )>=real.mant_dig-4);\n    assert(feqrel(erfc(1.000L), erfc1_000 )>=real.mant_dig-2);\n    assert(feqrel(erfc(1.125L), erfc1_125 )>=real.mant_dig-2);\n    assert(feqrel(erf(0.875L), erf0_875 )>=real.mant_dig-1);\n    // The DMC implementation of erfc() fails this next test (just).\n    // Test point from Mathematica 11.0.\n    assert(feqrel(erfc(4.1L), 6.70002765408489837272673380763418472e-9L) >= real.mant_dig-5);\n\n    assert(isIdentical(erf(0.0),0.0));\n    assert(isIdentical(erf(-0.0),-0.0));\n    assert(erf(real.infinity) == 1.0);\n    assert(erf(-real.infinity) == -1.0);\n    assert(isNaNWithPayload(erf(NaN(0xDEF)), 0xDEF));\n    assert(isNaNWithPayload(erfc(NaN(0xDEF)), 0xDEF));\n    assert(isIdentical(erfc(real.infinity),0.0));\n    assert(erfc(-real.infinity) == 2.0);\n    assert(erfc(0) == 1.0);\n}\n\n/*\n *  Exponential of squared argument\n *\n * Computes y = exp(x*x) while suppressing error amplification\n * that would ordinarily arise from the inexactness of the\n * exponential argument x*x.\n *\n * If sign < 0, the result is inverted; i.e., y = exp(-x*x) .\n *\n * ACCURACY:\n *                      Relative error:\n * arithmetic      domain        # trials      peak         rms\n *   IEEE     -106.566, 106.566    10^5       1.6e-19     4.4e-20\n */\n\nreal expx2(real x, int sign)\n{\n    /*\n    Cephes Math Library Release 2.9:  June, 2000\n    Copyright 2000 by Stephen L. Moshier\n    */\n    const real M = 32_768.0;\n    const real MINV = 3.0517578125e-5L;\n\n    x = abs(x);\n    if (sign < 0)\n        x = -x;\n\n  /* Represent x as an exact multiple of M plus a residual.\n     M is a power of 2 chosen so that exp(m * m) does not overflow\n     or underflow and so that |x - m| is small.  */\n    real m = MINV * floor(M * x + 0.5L);\n    real f = x - m;\n\n    /* x^2 = m^2 + 2mf + f^2 */\n    real u = m * m;\n    real u1 = 2 * m * f  +  f * f;\n\n    if (sign < 0)\n    {\n        u = -u;\n        u1 = -u1;\n    }\n\n    if ((u+u1) > MAXLOG)\n        return real.infinity;\n\n    /* u is exact, u1 is small.  */\n    return exp(u) * exp(u1);\n}\n\n\n/*\nComputes the normal distribution function.\n\nThe normal (or Gaussian, or bell-shaped) distribution is\ndefined as:\n\nnormalDist(x) = 1/$(SQRT) &pi; $(INTEGRAL -$(INFINITY), x) exp( - $(POWER t, 2)/2) dt\n    = 0.5 + 0.5 * erf(x/sqrt(2))\n    = 0.5 * erfc(- x/sqrt(2))\n\nTo maintain accuracy at high values of x, use\nnormalDistribution(x) = 1 - normalDistribution(-x).\n\nAccuracy:\nWithin a few bits of machine resolution over the entire\nrange.\n\nReferences:\n$(LINK http://www.netlib.org/cephes/ldoubdoc.html),\nG. Marsaglia, \"Evaluating the Normal Distribution\",\nJournal of Statistical Software <b>11</b>, (July 2004).\n*/\nreal normalDistributionImpl(real a)\n{\n    real x = a * SQRT1_2;\n    real z = abs(x);\n\n    if ( z < 1.0 )\n        return 0.5L + 0.5L * erf(x);\n    else\n    {\n        real y = 0.5L * erfce(z);\n        /* Multiply by exp(-x^2 / 2)  */\n        z = expx2(a, -1);\n        y = y * sqrt(z);\n        if ( x > 0.0L )\n            y = 1.0L - y;\n        return y;\n    }\n}\n\n@safe unittest\n{\nassert(fabs(normalDistributionImpl(1L) - (0.841344746068543)) < 0.0000000000000005);\nassert(isIdentical(normalDistributionImpl(NaN(0x325)), NaN(0x325)));\n}\n\n/*\n * Inverse of Normal distribution function\n *\n * Returns the argument, x, for which the area under the\n * Normal probability density function (integrated from\n * minus infinity to x) is equal to p.\n *\n * For small arguments 0 < p < exp(-2), the program computes\n * z = sqrt( -2 log(p) );  then the approximation is\n * x = z - log(z)/z  - (1/z) P(1/z) / Q(1/z) .\n * For larger arguments,  x/sqrt(2 pi) = w + w^3 R(w^2)/S(w^2)) ,\n * where w = p - 0.5.\n */\n// TODO: isIEEEQuadruple (128 bit) real implementation; not available from CEPHES.\nreal normalDistributionInvImpl(real p)\nin {\n  assert(p >= 0.0L && p <= 1.0L, \"Domain error\");\n}\ndo\n{\nstatic immutable real[8] P0 =\n[ -0x1.758f4d969484bfdcp-7, 0x1.53cee17a59259dd2p-3,\n   -0x1.ea01e4400a9427a2p-1,  0x1.61f7504a0105341ap+1, -0x1.09475a594d0399f6p+2,\n    0x1.7c59e7a0df99e3e2p+1, -0x1.87a81da52edcdf14p-1,  0x1.1fb149fd3f83600cp-7\n];\n\nstatic immutable real[8] Q0 =\n[ -0x1.64b92ae791e64bb2p-7, 0x1.7585c7d597298286p-3,\n   -0x1.40011be4f7591ce6p+0, 0x1.1fc067d8430a425ep+2, -0x1.21008ffb1e7ccdf2p+3,\n   0x1.3d1581cf9bc12fccp+3, -0x1.53723a89fd8f083cp+2, 1.0\n];\n\nstatic immutable real[10] P1 =\n[ 0x1.20ceea49ea142f12p-13, 0x1.cbe8a7267aea80bp-7,\n   0x1.79fea765aa787c48p-2, 0x1.d1f59faa1f4c4864p+1, 0x1.1c22e426a013bb96p+4,\n   0x1.a8675a0c51ef3202p+5, 0x1.75782c4f83614164p+6, 0x1.7a2f3d90948f1666p+6,\n   0x1.5cd116ee4c088c3ap+5, 0x1.1361e3eb6e3cc20ap+2\n];\n\nstatic immutable real[10] Q1 =\n[ 0x1.3a4ce1406cea98fap-13, 0x1.f45332623335cda2p-7,\n   0x1.98f28bbd4b98db1p-2, 0x1.ec3b24f9c698091cp+1, 0x1.1cc56ecda7cf58e4p+4,\n   0x1.92c6f7376bf8c058p+5, 0x1.4154c25aa47519b4p+6, 0x1.1b321d3b927849eap+6,\n   0x1.403a5f5a4ce7b202p+4, 1.0\n];\n\nstatic immutable real[8] P2 =\n[ 0x1.8c124a850116a6d8p-21, 0x1.534abda3c2fb90bap-13,\n   0x1.29a055ec93a4718cp-7, 0x1.6468e98aad6dd474p-3, 0x1.3dab2ef4c67a601cp+0,\n   0x1.e1fb3a1e70c67464p+1, 0x1.b6cce8035ff57b02p+2, 0x1.9f4c9e749ff35f62p+1\n];\n\nstatic immutable real[8] Q2 =\n[ 0x1.af03f4fc0655e006p-21, 0x1.713192048d11fb2p-13,\n   0x1.4357e5bbf5fef536p-7, 0x1.7fdac8749985d43cp-3, 0x1.4a080c813a2d8e84p+0,\n   0x1.c3a4b423cdb41bdap+1, 0x1.8160694e24b5557ap+2, 1.0\n];\n\nstatic immutable real[8] P3 =\n[ -0x1.55da447ae3806168p-34, -0x1.145635641f8778a6p-24,\n -0x1.abf46d6b48040128p-17, -0x1.7da550945da790fcp-11, -0x1.aa0b2a31157775fap-8,\n   0x1.b11d97522eed26bcp-3, 0x1.1106d22f9ae89238p+1, 0x1.029a358e1e630f64p+1\n];\n\nstatic immutable real[8] Q3 =\n[ -0x1.74022dd5523e6f84p-34, -0x1.2cb60d61e29ee836p-24,\n   -0x1.d19e6ec03a85e556p-17, -0x1.9ea2a7b4422f6502p-11, -0x1.c54b1e852f107162p-8,\n   0x1.e05268dd3c07989ep-3, 0x1.239c6aff14afbf82p+1, 1.0\n];\n\n    if (p <= 0.0L || p >= 1.0L)\n    {\n        if (p == 0.0L)\n            return -real.infinity;\n        if ( p == 1.0L )\n            return real.infinity;\n        return real.nan; // domain error\n    }\n    int code = 1;\n    real y = p;\n    if ( y > (1.0L - EXP_2) )\n    {\n        y = 1.0L - y;\n        code = 0;\n    }\n\n    real x, z, y2, x0, x1;\n\n    if ( y > EXP_2 )\n    {\n        y = y - 0.5L;\n        y2 = y * y;\n        x = y + y * (y2 * rationalPoly( y2, P0, Q0));\n        return x * SQRT2PI;\n    }\n\n    x = sqrt( -2.0L * log(y) );\n    x0 = x - log(x)/x;\n    z = 1.0L/x;\n    if ( x < 8.0L )\n    {\n        x1 = z * rationalPoly( z, P1, Q1);\n    }\n    else if ( x < 32.0L )\n    {\n        x1 = z * rationalPoly( z, P2, Q2);\n    }\n    else\n    {\n        x1 = z * rationalPoly( z, P3, Q3);\n    }\n    x = x0 - x1;\n    if ( code != 0 )\n    {\n        x = -x;\n    }\n    return x;\n}\n\n\n@safe unittest\n{\n    // TODO: Use verified test points.\n    // The values below are from Excel 2003.\n    assert(fabs(normalDistributionInvImpl(0.001) - (-3.09023230616779)) < 0.00000000000005);\n    assert(fabs(normalDistributionInvImpl(1e-50) - (-14.9333375347885)) < 0.00000000000005);\n    assert(feqrel(normalDistributionInvImpl(0.999), -normalDistributionInvImpl(0.001)) > real.mant_dig-6);\n\n    // Excel 2003 gets all the following values wrong!\n    assert(normalDistributionInvImpl(0.0) == -real.infinity);\n    assert(normalDistributionInvImpl(1.0) == real.infinity);\n    assert(normalDistributionInvImpl(0.5) == 0);\n    // (Excel 2003 returns norminv(p) = -30 for all p < 1e-200).\n    // The value tested here is the one the function returned in Jan 2006.\n    real unknown1 = normalDistributionInvImpl(1e-250L);\n    assert( fabs(unknown1 -(-33.79958617269L) ) < 0.00000005);\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/math/gammafunction.d",
    "content": "/**\n * Implementation of the gamma and beta functions, and their integrals.\n *\n * License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Copyright: Based on the CEPHES math library, which is\n *            Copyright (C) 1994 Stephen L. Moshier (moshier@world.std.com).\n * Authors:   Stephen L. Moshier (original C code). Conversion to D by Don Clugston\n *\n *\nMacros:\n *  TABLE_SV = <table border=\"1\" cellpadding=\"4\" cellspacing=\"0\">\n *      <caption>Special Values</caption>\n *      $0</table>\n *  SVH = $(TR $(TH $1) $(TH $2))\n *  SV  = $(TR $(TD $1) $(TD $2))\n *  GAMMA =  &#915;\n *  INTEGRATE = $(BIG &#8747;<sub>$(SMALL $1)</sub><sup>$2</sup>)\n *  POWER = $1<sup>$2</sup>\n *  NAN = $(RED NAN)\n */\nmodule std.internal.math.gammafunction;\nimport std.internal.math.errorfunction;\nimport std.math;\n\npure:\nnothrow:\n@safe:\n@nogc:\n\nprivate {\n\nenum real SQRT2PI = 2.50662827463100050242E0L; // sqrt(2pi)\nimmutable real EULERGAMMA = 0.57721_56649_01532_86060_65120_90082_40243_10421_59335_93992L; /** Euler-Mascheroni constant 0.57721566.. */\n\n// Polynomial approximations for gamma and loggamma.\n\nimmutable real[8] GammaNumeratorCoeffs = [ 1.0,\n    0x1.acf42d903366539ep-1, 0x1.73a991c8475f1aeap-2, 0x1.c7e918751d6b2a92p-4,\n    0x1.86d162cca32cfe86p-6, 0x1.0c378e2e6eaf7cd8p-8, 0x1.dc5c66b7d05feb54p-12,\n    0x1.616457b47e448694p-15\n];\n\nimmutable real[9] GammaDenominatorCoeffs = [ 1.0,\n  0x1.a8f9faae5d8fc8bp-2,  -0x1.cb7895a6756eebdep-3,  -0x1.7b9bab006d30652ap-5,\n  0x1.c671af78f312082ep-6, -0x1.a11ebbfaf96252dcp-11, -0x1.447b4d2230a77ddap-10,\n  0x1.ec1d45bb85e06696p-13,-0x1.d4ce24d05bd0a8e6p-17\n];\n\nimmutable real[9] GammaSmallCoeffs = [ 1.0,\n    0x1.2788cfc6fb618f52p-1, -0x1.4fcf4026afa2f7ecp-1, -0x1.5815e8fa24d7e306p-5,\n    0x1.5512320aea2ad71ap-3, -0x1.59af0fb9d82e216p-5,  -0x1.3b4b61d3bfdf244ap-7,\n    0x1.d9358e9d9d69fd34p-8, -0x1.38fc4bcbada775d6p-10\n];\n\nimmutable real[9] GammaSmallNegCoeffs = [ -1.0,\n    0x1.2788cfc6fb618f54p-1, 0x1.4fcf4026afa2bc4cp-1, -0x1.5815e8fa2468fec8p-5,\n    -0x1.5512320baedaf4b6p-3, -0x1.59af0fa283baf07ep-5, 0x1.3b4a70de31e05942p-7,\n    0x1.d9398be3bad13136p-8, 0x1.291b73ee05bcbba2p-10\n];\n\nimmutable real[7] logGammaStirlingCoeffs = [\n    0x1.5555555555553f98p-4, -0x1.6c16c16c07509b1p-9, 0x1.a01a012461cbf1e4p-11,\n    -0x1.3813089d3f9d164p-11, 0x1.b911a92555a277b8p-11, -0x1.ed0a7b4206087b22p-10,\n    0x1.402523859811b308p-8\n];\n\nimmutable real[7] logGammaNumerator = [\n    -0x1.0edd25913aaa40a2p+23, -0x1.31c6ce2e58842d1ep+24, -0x1.f015814039477c3p+23,\n    -0x1.74ffe40c4b184b34p+22, -0x1.0d9c6d08f9eab55p+20,  -0x1.54c6b71935f1fc88p+16,\n    -0x1.0e761b42932b2aaep+11\n];\n\nimmutable real[8] logGammaDenominator = [\n    -0x1.4055572d75d08c56p+24, -0x1.deeb6013998e4d76p+24, -0x1.106f7cded5dcc79ep+24,\n    -0x1.25e17184848c66d2p+22, -0x1.301303b99a614a0ap+19, -0x1.09e76ab41ae965p+15,\n    -0x1.00f95ced9e5f54eep+9, 1.0\n];\n\n/*\n * Helper function: Gamma function computed by Stirling's formula.\n *\n * Stirling's formula for the gamma function is:\n *\n * $(GAMMA)(x) = sqrt(2 &pi;) x<sup>x-0.5</sup> exp(-x) (1 + 1/x P(1/x))\n *\n */\nreal gammaStirling(real x)\n{\n    // CEPHES code Copyright 1994 by Stephen L. Moshier\n\n    static immutable real[9] SmallStirlingCoeffs = [\n        0x1.55555555555543aap-4, 0x1.c71c71c720dd8792p-9, -0x1.5f7268f0b5907438p-9,\n        -0x1.e13cd410e0477de6p-13, 0x1.9b0f31643442616ep-11, 0x1.2527623a3472ae08p-14,\n        -0x1.37f6bc8ef8b374dep-11,-0x1.8c968886052b872ap-16, 0x1.76baa9c6d3eeddbcp-11\n    ];\n\n    static immutable real[7] LargeStirlingCoeffs = [ 1.0L,\n        8.33333333333333333333E-2L, 3.47222222222222222222E-3L,\n        -2.68132716049382716049E-3L, -2.29472093621399176955E-4L,\n        7.84039221720066627474E-4L, 6.97281375836585777429E-5L\n    ];\n\n    real w = 1.0L/x;\n    real y = exp(x);\n    if ( x > 1024.0L )\n    {\n        // For large x, use rational coefficients from the analytical expansion.\n        w = poly(w, LargeStirlingCoeffs);\n        // Avoid overflow in pow()\n        real v = pow( x, 0.5L * x - 0.25L );\n        y = v * (v / y);\n    }\n    else\n    {\n        w = 1.0L + w * poly( w, SmallStirlingCoeffs);\n        static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)\n        {\n            // Avoid overflow in pow() for 64-bit reals\n            if (x > 143.0)\n            {\n                real v = pow( x, 0.5 * x - 0.25 );\n                y = v * (v / y);\n            }\n            else\n            {\n                y = pow( x, x - 0.5 ) / y;\n            }\n        }\n        else\n        {\n            y = pow( x, x - 0.5L ) / y;\n        }\n    }\n    y = SQRT2PI * y * w;\n    return  y;\n}\n\n/*\n * Helper function: Incomplete gamma function computed by Temme's expansion.\n *\n * This is a port of igamma_temme_large from Boost.\n *\n */\nreal igammaTemmeLarge(real a, real x)\n{\n    static immutable real[][13] coef = [\n        [ -0.333333333333333333333, 0.0833333333333333333333,\n          -0.0148148148148148148148, 0.00115740740740740740741,\n          0.000352733686067019400353, -0.0001787551440329218107,\n          0.39192631785224377817e-4, -0.218544851067999216147e-5,\n          -0.18540622107151599607e-5, 0.829671134095308600502e-6,\n          -0.176659527368260793044e-6, 0.670785354340149858037e-8,\n          0.102618097842403080426e-7, -0.438203601845335318655e-8,\n          0.914769958223679023418e-9, -0.255141939949462497669e-10,\n          -0.583077213255042506746e-10, 0.243619480206674162437e-10,\n          -0.502766928011417558909e-11 ],\n        [ -0.00185185185185185185185, -0.00347222222222222222222,\n          0.00264550264550264550265, -0.000990226337448559670782,\n          0.000205761316872427983539, -0.40187757201646090535e-6,\n          -0.18098550334489977837e-4, 0.764916091608111008464e-5,\n          -0.161209008945634460038e-5, 0.464712780280743434226e-8,\n          0.137863344691572095931e-6, -0.575254560351770496402e-7,\n          0.119516285997781473243e-7, -0.175432417197476476238e-10,\n          -0.100915437106004126275e-8, 0.416279299184258263623e-9,\n          -0.856390702649298063807e-10 ],\n        [ 0.00413359788359788359788, -0.00268132716049382716049,\n          0.000771604938271604938272, 0.200938786008230452675e-5,\n          -0.000107366532263651605215, 0.529234488291201254164e-4,\n          -0.127606351886187277134e-4, 0.342357873409613807419e-7,\n          0.137219573090629332056e-5, -0.629899213838005502291e-6,\n          0.142806142060642417916e-6, -0.204770984219908660149e-9,\n          -0.140925299108675210533e-7, 0.622897408492202203356e-8,\n          -0.136704883966171134993e-8 ],\n        [ 0.000649434156378600823045, 0.000229472093621399176955,\n          -0.000469189494395255712128, 0.000267720632062838852962,\n          -0.756180167188397641073e-4, -0.239650511386729665193e-6,\n          0.110826541153473023615e-4, -0.56749528269915965675e-5,\n          0.142309007324358839146e-5, -0.278610802915281422406e-10,\n          -0.169584040919302772899e-6, 0.809946490538808236335e-7,\n          -0.191111684859736540607e-7 ],\n        [ -0.000861888290916711698605, 0.000784039221720066627474,\n          -0.000299072480303190179733, -0.146384525788434181781e-5,\n          0.664149821546512218666e-4, -0.396836504717943466443e-4,\n          0.113757269706784190981e-4, 0.250749722623753280165e-9,\n          -0.169541495365583060147e-5, 0.890750753220530968883e-6,\n          -0.229293483400080487057e-6],\n        [ -0.000336798553366358150309, -0.697281375836585777429e-4,\n          0.000277275324495939207873, -0.000199325705161888477003,\n          0.679778047793720783882e-4, 0.141906292064396701483e-6,\n          -0.135940481897686932785e-4, 0.801847025633420153972e-5,\n          -0.229148117650809517038e-5 ],\n        [ 0.000531307936463992223166, -0.000592166437353693882865,\n          0.000270878209671804482771, 0.790235323266032787212e-6,\n          -0.815396936756196875093e-4, 0.561168275310624965004e-4,\n          -0.183291165828433755673e-4, -0.307961345060330478256e-8,\n          0.346515536880360908674e-5, -0.20291327396058603727e-5,\n          0.57887928631490037089e-6 ],\n        [ 0.000344367606892377671254, 0.517179090826059219337e-4,\n          -0.000334931610811422363117, 0.000281269515476323702274,\n          -0.000109765822446847310235, -0.127410090954844853795e-6,\n          0.277444515115636441571e-4, -0.182634888057113326614e-4,\n          0.578769494973505239894e-5 ],\n        [ -0.000652623918595309418922, 0.000839498720672087279993,\n          -0.000438297098541721005061, -0.696909145842055197137e-6,\n          0.000166448466420675478374, -0.000127835176797692185853,\n          0.462995326369130429061e-4 ],\n        [ -0.000596761290192746250124, -0.720489541602001055909e-4,\n          0.000678230883766732836162, -0.0006401475260262758451,\n          0.000277501076343287044992 ],\n        [ 0.00133244544948006563713, -0.0019144384985654775265,\n          0.00110893691345966373396 ],\n        [ 0.00157972766073083495909, 0.000162516262783915816899,\n          -0.00206334210355432762645, 0.00213896861856890981541,\n          -0.00101085593912630031708 ],\n        [ -0.00407251211951401664727, 0.00640336283380806979482,\n          -0.00404101610816766177474 ]\n    ];\n\n    // avoid nans when one of the arguments is inf:\n    if (x == real.infinity && a != real.infinity)\n        return 0;\n\n    if (x != real.infinity && a == real.infinity)\n        return 1;\n\n    real sigma = (x - a) / a;\n    real phi = sigma - log(sigma + 1);\n\n    real y = a * phi;\n    real z = sqrt(2 * phi);\n    if (x < a)\n        z = -z;\n\n    real[13] workspace;\n    foreach (i; 0 .. coef.length)\n        workspace[i] = poly(z, coef[i]);\n\n    real result = poly(1 / a, workspace);\n    result *= exp(-y) / sqrt(2 * PI * a);\n    if (x < a)\n        result = -result;\n\n    result += erfc(sqrt(y)) / 2;\n\n    return result;\n}\n\n} // private\n\npublic:\n/// The maximum value of x for which gamma(x) < real.infinity.\nstatic if (floatTraits!(real).realFormat == RealFormat.ieeeQuadruple)\n    enum real MAXGAMMA = 1755.5483429L;\nelse static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended)\n    enum real MAXGAMMA = 1755.5483429L;\nelse static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)\n    enum real MAXGAMMA = 171.6243769L;\nelse\n    static assert(0, \"missing MAXGAMMA for other real types\");\n\n\n/*****************************************************\n *  The Gamma function, $(GAMMA)(x)\n *\n *  $(GAMMA)(x) is a generalisation of the factorial function\n *  to real and complex numbers.\n *  Like x!, $(GAMMA)(x+1) = x*$(GAMMA)(x).\n *\n *  Mathematically, if z.re > 0 then\n *   $(GAMMA)(z) = $(INTEGRATE 0, &infin;) $(POWER t, z-1)$(POWER e, -t) dt\n *\n *  $(TABLE_SV\n *    $(SVH  x,          $(GAMMA)(x) )\n *    $(SV  $(NAN),      $(NAN)      )\n *    $(SV  &plusmn;0.0, &plusmn;&infin;)\n *    $(SV integer > 0,  (x-1)!      )\n *    $(SV integer < 0,  $(NAN)      )\n *    $(SV +&infin;,     +&infin;    )\n *    $(SV -&infin;,     $(NAN)      )\n *  )\n */\nreal gamma(real x)\n{\n/* Based on code from the CEPHES library.\n * CEPHES code Copyright 1994 by Stephen L. Moshier\n *\n * Arguments |x| <= 13 are reduced by recurrence and the function\n * approximated by a rational function of degree 7/8 in the\n * interval (2,3).  Large arguments are handled by Stirling's\n * formula. Large negative arguments are made positive using\n * a reflection formula.\n */\n\n    real q, z;\n    if (isNaN(x)) return x;\n    if (x == -x.infinity) return real.nan;\n    if ( fabs(x) > MAXGAMMA ) return real.infinity;\n    if (x == 0) return 1.0 / x; // +- infinity depending on sign of x, create an exception.\n\n    q = fabs(x);\n\n    if ( q > 13.0L )\n    {\n        // Large arguments are handled by Stirling's\n        // formula. Large negative arguments are made positive using\n        // the reflection formula.\n\n        if ( x < 0.0L )\n        {\n            if (x < -1/real.epsilon)\n            {\n                // Large negatives lose all precision\n                return real.nan;\n            }\n            int sgngam = 1; // sign of gamma.\n            long intpart = cast(long)(q);\n            if (q == intpart)\n                  return real.nan; // poles for all integers <0.\n            real p = intpart;\n            if ( (intpart & 1) == 0 )\n                sgngam = -1;\n            z = q - p;\n            if ( z > 0.5L )\n            {\n                p += 1.0L;\n                z = q - p;\n            }\n            z = q * sin( PI * z );\n            z = fabs(z) * gammaStirling(q);\n            if ( z <= PI/real.max ) return sgngam * real.infinity;\n            return sgngam * PI/z;\n        }\n        else\n        {\n            return gammaStirling(x);\n        }\n    }\n\n    // Arguments |x| <= 13 are reduced by recurrence and the function\n    // approximated by a rational function of degree 7/8 in the\n    // interval (2,3).\n\n    z = 1.0L;\n    while ( x >= 3.0L )\n    {\n        x -= 1.0L;\n        z *= x;\n    }\n\n    while ( x < -0.03125L )\n    {\n        z /= x;\n        x += 1.0L;\n    }\n\n    if ( x <= 0.03125L )\n    {\n        if ( x == 0.0L )\n            return real.nan;\n        else\n        {\n            if ( x < 0.0L )\n            {\n                x = -x;\n                return z / (x * poly( x, GammaSmallNegCoeffs ));\n            }\n            else\n            {\n                return z / (x * poly( x, GammaSmallCoeffs ));\n            }\n        }\n    }\n\n    while ( x < 2.0L )\n    {\n        z /= x;\n        x += 1.0L;\n    }\n    if ( x == 2.0L ) return z;\n\n    x -= 2.0L;\n    return z * poly( x, GammaNumeratorCoeffs ) / poly( x, GammaDenominatorCoeffs );\n}\n\n@safe unittest\n{\n    // gamma(n) = factorial(n-1) if n is an integer.\n    real fact = 1.0L;\n    for (int i=1; fact<real.max; ++i)\n    {\n        // Require exact equality for small factorials\n        if (i<14) assert(gamma(i*1.0L) == fact);\n        assert(feqrel(gamma(i*1.0L), fact) >= real.mant_dig-15);\n        fact *= (i*1.0L);\n    }\n    assert(gamma(0.0) == real.infinity);\n    assert(gamma(-0.0) == -real.infinity);\n    assert(isNaN(gamma(-1.0)));\n    assert(isNaN(gamma(-15.0)));\n    assert(isIdentical(gamma(NaN(0xABC)), NaN(0xABC)));\n    assert(gamma(real.infinity) == real.infinity);\n    assert(gamma(real.max) == real.infinity);\n    assert(isNaN(gamma(-real.infinity)));\n    assert(gamma(real.min_normal*real.epsilon) == real.infinity);\n    assert(gamma(MAXGAMMA)< real.infinity);\n    assert(gamma(MAXGAMMA*2) == real.infinity);\n\n    // Test some high-precision values (50 decimal digits)\n    real SQRT_PI = 1.77245385090551602729816748334114518279754945612238L;\n\n\n    assert(feqrel(gamma(0.5L), SQRT_PI) >= real.mant_dig-1);\n    assert(feqrel(gamma(17.25L), 4.224986665692703551570937158682064589938e13L) >= real.mant_dig-4);\n\n    assert(feqrel(gamma(1.0 / 3.0L),  2.67893853470774763365569294097467764412868937795730L) >= real.mant_dig-2);\n    assert(feqrel(gamma(0.25L),\n        3.62560990822190831193068515586767200299516768288006L) >= real.mant_dig-1);\n    assert(feqrel(gamma(1.0 / 5.0L),\n        4.59084371199880305320475827592915200343410999829340L) >= real.mant_dig-1);\n}\n\n/*****************************************************\n * Natural logarithm of gamma function.\n *\n * Returns the base e (2.718...) logarithm of the absolute\n * value of the gamma function of the argument.\n *\n * For reals, logGamma is equivalent to log(fabs(gamma(x))).\n *\n *  $(TABLE_SV\n *    $(SVH  x,             logGamma(x)   )\n *    $(SV  $(NAN),         $(NAN)      )\n *    $(SV integer <= 0,    +&infin;    )\n *    $(SV &plusmn;&infin;, +&infin;    )\n *  )\n */\nreal logGamma(real x)\n{\n    /* Based on code from the CEPHES library.\n     * CEPHES code Copyright 1994 by Stephen L. Moshier\n     *\n     * For arguments greater than 33, the logarithm of the gamma\n     * function is approximated by the logarithmic version of\n     * Stirling's formula using a polynomial approximation of\n     * degree 4. Arguments between -33 and +33 are reduced by\n     * recurrence to the interval [2,3] of a rational approximation.\n     * The cosecant reflection formula is employed for arguments\n     * less than -33.\n     */\n    real q, w, z, f, nx;\n\n    if (isNaN(x)) return x;\n    if (fabs(x) == x.infinity) return x.infinity;\n\n    if ( x < -34.0L )\n    {\n        q = -x;\n        w = logGamma(q);\n        real p = floor(q);\n        if ( p == q )\n            return real.infinity;\n        int intpart = cast(int)(p);\n        real sgngam = 1;\n        if ( (intpart & 1) == 0 )\n            sgngam = -1;\n        z = q - p;\n        if ( z > 0.5L )\n        {\n            p += 1.0L;\n            z = p - q;\n        }\n        z = q * sin( PI * z );\n        if ( z == 0.0L )\n            return sgngam * real.infinity;\n    /*  z = LOGPI - logl( z ) - w; */\n        z = log( PI/z ) - w;\n        return z;\n    }\n\n    if ( x < 13.0L )\n    {\n        z = 1.0L;\n        nx = floor( x +  0.5L );\n        f = x - nx;\n        while ( x >= 3.0L )\n        {\n            nx -= 1.0L;\n            x = nx + f;\n            z *= x;\n        }\n        while ( x < 2.0L )\n        {\n            if ( fabs(x) <= 0.03125 )\n            {\n                if ( x == 0.0L )\n                    return real.infinity;\n                if ( x < 0.0L )\n                {\n                    x = -x;\n                    q = z / (x * poly( x, GammaSmallNegCoeffs));\n                } else\n                    q = z / (x * poly( x, GammaSmallCoeffs));\n                return log( fabs(q) );\n            }\n            z /= nx +  f;\n            nx += 1.0L;\n            x = nx + f;\n        }\n        z = fabs(z);\n        if ( x == 2.0L )\n            return log(z);\n        x = (nx - 2.0L) + f;\n        real p = x * rationalPoly( x, logGammaNumerator, logGammaDenominator);\n        return log(z) + p;\n    }\n\n    // const real MAXLGM = 1.04848146839019521116e+4928L;\n    //  if ( x > MAXLGM ) return sgngaml * real.infinity;\n\n    const real LOGSQRT2PI  =  0.91893853320467274178L; // log( sqrt( 2*pi ) )\n\n    q = ( x - 0.5L ) * log(x) - x + LOGSQRT2PI;\n    if (x > 1.0e10L) return q;\n    real p = 1.0L / (x*x);\n    q += poly( p, logGammaStirlingCoeffs ) / x;\n    return q ;\n}\n\n@safe unittest\n{\n    assert(isIdentical(logGamma(NaN(0xDEF)), NaN(0xDEF)));\n    assert(logGamma(real.infinity) == real.infinity);\n    assert(logGamma(-1.0) == real.infinity);\n    assert(logGamma(0.0) == real.infinity);\n    assert(logGamma(-50.0) == real.infinity);\n    assert(isIdentical(0.0L, logGamma(1.0L)));\n    assert(isIdentical(0.0L, logGamma(2.0L)));\n    assert(logGamma(real.min_normal*real.epsilon) == real.infinity);\n    assert(logGamma(-real.min_normal*real.epsilon) == real.infinity);\n\n    // x, correct loggamma(x), correct d/dx loggamma(x).\n    immutable static real[] testpoints = [\n    8.0L,                    8.525146484375L      + 1.48766904143001655310E-5,   2.01564147795560999654E0L,\n    8.99993896484375e-1L,    6.6375732421875e-2L  + 5.11505711292524166220E-6L, -7.54938684259372234258E-1,\n    7.31597900390625e-1L,    2.2369384765625e-1   + 5.21506341809849792422E-6L, -1.13355566660398608343E0L,\n    2.31639862060546875e-1L, 1.3686676025390625L  + 1.12609441752996145670E-5L, -4.56670961813812679012E0,\n    1.73162841796875L,      -8.88214111328125e-2L + 3.36207740803753034508E-6L, 2.33339034686200586920E-1L,\n    1.23162841796875L,      -9.3902587890625e-2L  + 1.28765089229009648104E-5L, -2.49677345775751390414E-1L,\n    7.3786976294838206464e19L,   3.301798506038663053312e21L - 1.656137564136932662487046269677E5L,\n                          4.57477139169563904215E1L,\n    1.08420217248550443401E-19L, 4.36682586669921875e1L + 1.37082843669932230418E-5L,\n                         -9.22337203685477580858E18L,\n    1.0L, 0.0L, -5.77215664901532860607E-1L,\n    2.0L, 0.0L, 4.22784335098467139393E-1L,\n    -0.5L,  1.2655029296875L    + 9.19379714539648894580E-6L, 3.64899739785765205590E-2L,\n    -1.5L,  8.6004638671875e-1L + 6.28657731014510932682E-7L, 7.03156640645243187226E-1L,\n    -2.5L, -5.6243896484375E-2L + 1.79986700949327405470E-7,  1.10315664064524318723E0L,\n    -3.5L,  -1.30902099609375L  + 1.43111007079536392848E-5L, 1.38887092635952890151E0L\n    ];\n   // TODO: test derivatives as well.\n    for (int i=0; i<testpoints.length; i+=3)\n    {\n        assert( feqrel(logGamma(testpoints[i]), testpoints[i+1]) > real.mant_dig-5);\n        if (testpoints[i]<MAXGAMMA)\n        {\n            assert( feqrel(log(fabs(gamma(testpoints[i]))), testpoints[i+1]) > real.mant_dig-5);\n        }\n    }\n    assert(logGamma(-50.2) == log(fabs(gamma(-50.2))));\n    assert(logGamma(-0.008) == log(fabs(gamma(-0.008))));\n    assert(feqrel(logGamma(-38.8),log(fabs(gamma(-38.8)))) > real.mant_dig-4);\n    static if (real.mant_dig >= 64) // incl. 80-bit reals\n        assert(feqrel(logGamma(1500.0L),log(gamma(1500.0L))) > real.mant_dig-2);\n    else static if (real.mant_dig >= 53) // incl. 64-bit reals\n        assert(feqrel(logGamma(150.0L),log(gamma(150.0L))) > real.mant_dig-2);\n}\n\n\nprivate {\n/*\n * These value can be calculated like this:\n * 1) Get exact real.max/min_normal/epsilon from compiler:\n *    writefln!\"%a\"(real.max/min_normal_epsilon)\n * 2) Convert for Wolfram Alpha\n *    0xf.fffffffffffffffp+16380 ==> (f.fffffffffffffff base 16) * 2^16380\n * 3) Calculate result on wofram alpha:\n *    http://www.wolframalpha.com/input/?i=ln((1.ffffffffffffffffffffffffffff+base+16)+*+2%5E16383)+in+base+2\n * 4) Convert to proper format:\n *    string mantissa = \"1.011...\";\n *    write(mantissa[0 .. 2]); mantissa = mantissa[2 .. $];\n *    for (size_t i = 0; i < mantissa.length/4; i++)\n *    {\n *        writef!\"%x\"(to!ubyte(mantissa[0 .. 4], 2)); mantissa = mantissa[4 .. $];\n *    }\n */\nstatic if (floatTraits!(real).realFormat == RealFormat.ieeeQuadruple)\n{\n    enum real MAXLOG = 0x1.62e42fefa39ef35793c7673007e6p+13;  // log(real.max)\n    enum real MINLOG = -0x1.6546282207802c89d24d65e96274p+13; // log(real.min_normal*real.epsilon) = log(smallest denormal)\n}\nelse static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended)\n{\n    enum real MAXLOG = 0x1.62e42fefa39ef358p+13L;  // log(real.max)\n    enum real MINLOG = -0x1.6436716d5406e6d8p+13L; // log(real.min_normal*real.epsilon) = log(smallest denormal)\n}\nelse static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)\n{\n    enum real MAXLOG = 0x1.62e42fefa39efp+9L;  // log(real.max)\n    enum real MINLOG = -0x1.74385446d71c3p+9L; // log(real.min_normal*real.epsilon) = log(smallest denormal)\n}\nelse\n    static assert(0, \"missing MAXLOG and MINLOG for other real types\");\n\nenum real BETA_BIG = 9.223372036854775808e18L;\nenum real BETA_BIGINV = 1.084202172485504434007e-19L;\n}\n\n/** Incomplete beta integral\n *\n * Returns incomplete beta integral of the arguments, evaluated\n * from zero to x. The regularized incomplete beta function is defined as\n *\n * betaIncomplete(a, b, x) = &Gamma;(a+b)/(&Gamma;(a) &Gamma;(b)) *\n * $(INTEGRATE 0, x) $(POWER t, a-1)$(POWER (1-t),b-1) dt\n *\n * and is the same as the the cumulative distribution function.\n *\n * The domain of definition is 0 <= x <= 1.  In this\n * implementation a and b are restricted to positive values.\n * The integral from x to 1 may be obtained by the symmetry\n * relation\n *\n *    betaIncompleteCompl(a, b, x )  =  betaIncomplete( b, a, 1-x )\n *\n * The integral is evaluated by a continued fraction expansion\n * or, when b*x is small, by a power series.\n */\nreal betaIncomplete(real aa, real bb, real xx )\n{\n    if ( !(aa>0 && bb>0) )\n    {\n         if ( isNaN(aa) ) return aa;\n         if ( isNaN(bb) ) return bb;\n         return real.nan; // domain error\n    }\n    if (!(xx>0 && xx<1.0))\n    {\n        if (isNaN(xx)) return xx;\n        if ( xx == 0.0L ) return 0.0;\n        if ( xx == 1.0L )  return 1.0;\n        return real.nan; // domain error\n    }\n    if ( (bb * xx) <= 1.0L && xx <= 0.95L)\n    {\n        return betaDistPowerSeries(aa, bb, xx);\n    }\n    real x;\n    real xc; // = 1 - x\n\n    real a, b;\n    int flag = 0;\n\n    /* Reverse a and b if x is greater than the mean. */\n    if ( xx > (aa/(aa+bb)) )\n    {\n        // here x > aa/(aa+bb) and (bb*x>1 or x>0.95)\n        flag = 1;\n        a = bb;\n        b = aa;\n        xc = xx;\n        x = 1.0L - xx;\n    }\n    else\n    {\n        a = aa;\n        b = bb;\n        xc = 1.0L - xx;\n        x = xx;\n    }\n\n    if ( flag == 1 && (b * x) <= 1.0L && x <= 0.95L)\n    {\n        // here xx > aa/(aa+bb) and  ((bb*xx>1) or xx>0.95) and (aa*(1-xx)<=1) and xx > 0.05\n        return 1.0 - betaDistPowerSeries(a, b, x); // note loss of precision\n    }\n\n    real w;\n    // Choose expansion for optimal convergence\n    // One is for x * (a+b+2) < (a+1),\n    // the other is for x * (a+b+2) > (a+1).\n    real y = x * (a+b-2.0L) - (a-1.0L);\n    if ( y < 0.0L )\n    {\n        w = betaDistExpansion1( a, b, x );\n    }\n    else\n    {\n        w = betaDistExpansion2( a, b, x ) / xc;\n    }\n\n    /* Multiply w by the factor\n         a      b\n        x  (1-x)   Gamma(a+b) / ( a Gamma(a) Gamma(b) ) .   */\n\n    y = a * log(x);\n    real t = b * log(xc);\n    if ( (a+b) < MAXGAMMA && fabs(y) < MAXLOG && fabs(t) < MAXLOG )\n    {\n        t = pow(xc,b);\n        t *= pow(x,a);\n        t /= a;\n        t *= w;\n        t *= gamma(a+b) / (gamma(a) * gamma(b));\n    }\n    else\n    {\n        /* Resort to logarithms.  */\n        y += t + logGamma(a+b) - logGamma(a) - logGamma(b);\n        y += log(w/a);\n\n        t = exp(y);\n/+\n        // There seems to be a bug in Cephes at this point.\n        // Problems occur for y > MAXLOG, not y < MINLOG.\n        if ( y < MINLOG )\n        {\n            t = 0.0L;\n        }\n        else\n        {\n            t = exp(y);\n        }\n+/\n    }\n    if ( flag == 1 )\n    {\n/+   // CEPHES includes this code, but I think it is erroneous.\n        if ( t <= real.epsilon )\n        {\n            t = 1.0L - real.epsilon;\n        } else\n+/\n        t = 1.0L - t;\n    }\n    return t;\n}\n\n/** Inverse of incomplete beta integral\n *\n * Given y, the function finds x such that\n *\n *  betaIncomplete(a, b, x) == y\n *\n *  Newton iterations or interval halving is used.\n */\nreal betaIncompleteInv(real aa, real bb, real yy0 )\n{\n    real a, b, y0, d, y, x, x0, x1, lgm, yp, di, dithresh, yl, yh, xt;\n    int i, rflg, dir, nflg;\n\n    if (isNaN(yy0)) return yy0;\n    if (isNaN(aa)) return aa;\n    if (isNaN(bb)) return bb;\n    if ( yy0 <= 0.0L )\n        return 0.0L;\n    if ( yy0 >= 1.0L )\n        return 1.0L;\n    x0 = 0.0L;\n    yl = 0.0L;\n    x1 = 1.0L;\n    yh = 1.0L;\n    if ( aa <= 1.0L || bb <= 1.0L )\n    {\n        dithresh = 1.0e-7L;\n        rflg = 0;\n        a = aa;\n        b = bb;\n        y0 = yy0;\n        x = a/(a+b);\n        y = betaIncomplete( a, b, x );\n        nflg = 0;\n        goto ihalve;\n    }\n    else\n    {\n        nflg = 0;\n        dithresh = 1.0e-4L;\n    }\n\n    // approximation to inverse function\n\n    yp = -normalDistributionInvImpl( yy0 );\n\n    if ( yy0 > 0.5L )\n    {\n        rflg = 1;\n        a = bb;\n        b = aa;\n        y0 = 1.0L - yy0;\n        yp = -yp;\n    }\n    else\n    {\n        rflg = 0;\n        a = aa;\n        b = bb;\n        y0 = yy0;\n    }\n\n    lgm = (yp * yp - 3.0L)/6.0L;\n    x = 2.0L/( 1.0L/(2.0L * a-1.0L)  +  1.0L/(2.0L * b - 1.0L) );\n    d = yp * sqrt( x + lgm ) / x\n        - ( 1.0L/(2.0L * b - 1.0L) - 1.0L/(2.0L * a - 1.0L) )\n        * (lgm + (5.0L/6.0L) - 2.0L/(3.0L * x));\n    d = 2.0L * d;\n    if ( d < MINLOG )\n    {\n        x = 1.0L;\n        goto under;\n    }\n    x = a/( a + b * exp(d) );\n    y = betaIncomplete( a, b, x );\n    yp = (y - y0)/y0;\n    if ( fabs(yp) < 0.2 )\n        goto newt;\n\n    /* Resort to interval halving if not close enough. */\nihalve:\n\n    dir = 0;\n    di = 0.5L;\n    for ( i=0; i<400; i++ )\n    {\n        if ( i != 0 )\n        {\n            x = x0  +  di * (x1 - x0);\n            if ( x == 1.0L )\n            {\n                x = 1.0L - real.epsilon;\n            }\n            if ( x == 0.0L )\n            {\n                di = 0.5;\n                x = x0  +  di * (x1 - x0);\n                if ( x == 0.0 )\n                    goto under;\n            }\n            y = betaIncomplete( a, b, x );\n            yp = (x1 - x0)/(x1 + x0);\n            if ( fabs(yp) < dithresh )\n                goto newt;\n            yp = (y-y0)/y0;\n            if ( fabs(yp) < dithresh )\n                goto newt;\n        }\n        if ( y < y0 )\n        {\n            x0 = x;\n            yl = y;\n            if ( dir < 0 )\n            {\n                dir = 0;\n                di = 0.5L;\n            } else if ( dir > 3 )\n                di = 1.0L - (1.0L - di) * (1.0L - di);\n            else if ( dir > 1 )\n                di = 0.5L * di + 0.5L;\n            else\n                di = (y0 - y)/(yh - yl);\n            dir += 1;\n            if ( x0 > 0.95L )\n            {\n                if ( rflg == 1 )\n                {\n                    rflg = 0;\n                    a = aa;\n                    b = bb;\n                    y0 = yy0;\n                }\n                else\n                {\n                    rflg = 1;\n                    a = bb;\n                    b = aa;\n                    y0 = 1.0 - yy0;\n                }\n                x = 1.0L - x;\n                y = betaIncomplete( a, b, x );\n                x0 = 0.0;\n                yl = 0.0;\n                x1 = 1.0;\n                yh = 1.0;\n                goto ihalve;\n            }\n        }\n        else\n        {\n            x1 = x;\n            if ( rflg == 1 && x1 < real.epsilon )\n            {\n                x = 0.0L;\n                goto done;\n            }\n            yh = y;\n            if ( dir > 0 )\n            {\n                dir = 0;\n                di = 0.5L;\n            }\n            else if ( dir < -3 )\n                di = di * di;\n            else if ( dir < -1 )\n                di = 0.5L * di;\n            else\n                di = (y - y0)/(yh - yl);\n            dir -= 1;\n            }\n        }\n    if ( x0 >= 1.0L )\n    {\n        // partial loss of precision\n        x = 1.0L - real.epsilon;\n        goto done;\n    }\n    if ( x <= 0.0L )\n    {\nunder:\n        // underflow has occurred\n        x = real.min_normal * real.min_normal;\n        goto done;\n    }\n\nnewt:\n\n    if ( nflg )\n    {\n        goto done;\n    }\n    nflg = 1;\n    lgm = logGamma(a+b) - logGamma(a) - logGamma(b);\n\n    for ( i=0; i<15; i++ )\n    {\n        /* Compute the function at this point. */\n        if ( i != 0 )\n            y = betaIncomplete(a,b,x);\n        if ( y < yl )\n        {\n            x = x0;\n            y = yl;\n        }\n        else if ( y > yh )\n        {\n            x = x1;\n            y = yh;\n        }\n        else if ( y < y0 )\n        {\n            x0 = x;\n            yl = y;\n        }\n        else\n        {\n            x1 = x;\n            yh = y;\n        }\n        if ( x == 1.0L || x == 0.0L )\n            break;\n        /* Compute the derivative of the function at this point. */\n        d = (a - 1.0L) * log(x) + (b - 1.0L) * log(1.0L - x) + lgm;\n        if ( d < MINLOG )\n        {\n            goto done;\n        }\n        if ( d > MAXLOG )\n        {\n            break;\n        }\n        d = exp(d);\n        /* Compute the step to the next approximation of x. */\n        d = (y - y0)/d;\n        xt = x - d;\n        if ( xt <= x0 )\n        {\n            y = (x - x0) / (x1 - x0);\n            xt = x0 + 0.5L * y * (x - x0);\n            if ( xt <= 0.0L )\n                break;\n        }\n        if ( xt >= x1 )\n        {\n            y = (x1 - x) / (x1 - x0);\n            xt = x1 - 0.5L * y * (x1 - x);\n            if ( xt >= 1.0L )\n                break;\n        }\n        x = xt;\n        if ( fabs(d/x) < (128.0L * real.epsilon) )\n            goto done;\n    }\n    /* Did not converge.  */\n    dithresh = 256.0L * real.epsilon;\n    goto ihalve;\n\ndone:\n    if ( rflg )\n    {\n        if ( x <= real.epsilon )\n            x = 1.0L - real.epsilon;\n        else\n            x = 1.0L - x;\n    }\n    return x;\n}\n\n@safe unittest { // also tested by the normal distribution\n    // check NaN propagation\n    assert(isIdentical(betaIncomplete(NaN(0xABC),2,3), NaN(0xABC)));\n    assert(isIdentical(betaIncomplete(7,NaN(0xABC),3), NaN(0xABC)));\n    assert(isIdentical(betaIncomplete(7,15,NaN(0xABC)), NaN(0xABC)));\n    assert(isIdentical(betaIncompleteInv(NaN(0xABC),1,17), NaN(0xABC)));\n    assert(isIdentical(betaIncompleteInv(2,NaN(0xABC),8), NaN(0xABC)));\n    assert(isIdentical(betaIncompleteInv(2,3, NaN(0xABC)), NaN(0xABC)));\n\n    assert(isNaN(betaIncomplete(-1, 2, 3)));\n\n    assert(betaIncomplete(1, 2, 0)==0);\n    assert(betaIncomplete(1, 2, 1)==1);\n    assert(isNaN(betaIncomplete(1, 2, 3)));\n    assert(betaIncompleteInv(1, 1, 0)==0);\n    assert(betaIncompleteInv(1, 1, 1)==1);\n\n    // Test against Mathematica   betaRegularized[z,a,b]\n    // These arbitrary points are chosen to give good code coverage.\n    assert(feqrel(betaIncomplete(8, 10, 0.2), 0.010_934_315_234_099_2L) >=  real.mant_dig - 5);\n    assert(feqrel(betaIncomplete(2, 2.5, 0.9), 0.989_722_597_604_452_767_171_003_59L) >= real.mant_dig - 1);\n    static if (real.mant_dig >= 64) // incl. 80-bit reals\n        assert(feqrel(betaIncomplete(1000, 800, 0.5), 1.179140859734704555102808541457164E-06L) >= real.mant_dig - 13);\n    else\n        assert(feqrel(betaIncomplete(1000, 800, 0.5), 1.179140859734704555102808541457164E-06L) >= real.mant_dig - 14);\n    assert(feqrel(betaIncomplete(0.0001, 10000, 0.0001), 0.999978059362107134278786L) >= real.mant_dig - 18);\n    assert(betaIncomplete(0.01, 327726.7, 0.545113) == 1.0);\n    assert(feqrel(betaIncompleteInv(8, 10, 0.010_934_315_234_099_2L), 0.2L) >= real.mant_dig - 2);\n    assert(feqrel(betaIncomplete(0.01, 498.437, 0.0121433), 0.99999664562033077636065L) >= real.mant_dig - 1);\n    assert(feqrel(betaIncompleteInv(5, 10, 0.2000002972865658842), 0.229121208190918L) >= real.mant_dig - 3);\n    assert(feqrel(betaIncompleteInv(4, 7, 0.8000002209179505L), 0.483657360076904L) >= real.mant_dig - 3);\n\n    // Coverage tests. I don't have correct values for these tests, but\n    // these values cover most of the code, so they are useful for\n    // regression testing.\n    // Extensive testing failed to increase the coverage. It seems likely that about\n    // half the code in this function is unnecessary; there is potential for\n    // significant improvement over the original CEPHES code.\n    static if (real.mant_dig == 64) // 80-bit reals\n    {\n        assert(betaIncompleteInv(0.01, 8e-48, 5.45464e-20) == 1-real.epsilon);\n        assert(betaIncompleteInv(0.01, 8e-48, 9e-26) == 1-real.epsilon);\n\n        // Beware: a one-bit change in pow() changes almost all digits in the result!\n        assert(feqrel(\n            betaIncompleteInv(0x1.b3d151fbba0eb18p+1, 1.2265e-19, 2.44859e-18),\n            0x1.c0110c8531d0952cp-1L\n        ) > 10);\n        // This next case uncovered a one-bit difference in the FYL2X instruction\n        // between Intel and AMD processors. This difference gets magnified by 2^^38.\n        // WolframAlpha crashes attempting to calculate this.\n        assert(feqrel(betaIncompleteInv(0x1.ff1275ae5b939bcap-41, 4.6713e18, 0.0813601),\n            0x1.f97749d90c7adba8p-63L) >= real.mant_dig - 39);\n        real a1 = 3.40483;\n        assert(betaIncompleteInv(a1, 4.0640301659679627772e19L, 0.545113) == 0x1.ba8c08108aaf5d14p-109);\n        real b1 = 2.82847e-25;\n        assert(feqrel(betaIncompleteInv(0.01, b1, 9e-26), 0x1.549696104490aa9p-830L) >= real.mant_dig-10);\n\n        // --- Problematic cases ---\n        // This is a situation where the series expansion fails to converge\n        assert( isNaN(betaIncompleteInv(0.12167, 4.0640301659679627772e19L, 0.0813601)));\n        // This next result is almost certainly erroneous.\n        // Mathematica states: \"(cannot be determined by current methods)\"\n        assert(betaIncomplete(1.16251e20, 2.18e39, 5.45e-20) == -real.infinity);\n        // WolframAlpha gives no result for this, though indicates that it approximately 1.0 - 1.3e-9\n        assert(1 - betaIncomplete(0.01, 328222, 4.0375e-5) == 0x1.5f62926b4p-30);\n    }\n}\n\n\nprivate {\n// Implementation functions\n\n// Continued fraction expansion #1 for incomplete beta integral\n// Use when x < (a+1)/(a+b+2)\nreal betaDistExpansion1(real a, real b, real x )\n{\n    real xk, pk, pkm1, pkm2, qk, qkm1, qkm2;\n    real k1, k2, k3, k4, k5, k6, k7, k8;\n    real r, t, ans;\n    int n;\n\n    k1 = a;\n    k2 = a + b;\n    k3 = a;\n    k4 = a + 1.0L;\n    k5 = 1.0L;\n    k6 = b - 1.0L;\n    k7 = k4;\n    k8 = a + 2.0L;\n\n    pkm2 = 0.0L;\n    qkm2 = 1.0L;\n    pkm1 = 1.0L;\n    qkm1 = 1.0L;\n    ans = 1.0L;\n    r = 1.0L;\n    n = 0;\n    const real thresh = 3.0L * real.epsilon;\n    do\n    {\n        xk = -( x * k1 * k2 )/( k3 * k4 );\n        pk = pkm1 +  pkm2 * xk;\n        qk = qkm1 +  qkm2 * xk;\n        pkm2 = pkm1;\n        pkm1 = pk;\n        qkm2 = qkm1;\n        qkm1 = qk;\n\n        xk = ( x * k5 * k6 )/( k7 * k8 );\n        pk = pkm1 +  pkm2 * xk;\n        qk = qkm1 +  qkm2 * xk;\n        pkm2 = pkm1;\n        pkm1 = pk;\n        qkm2 = qkm1;\n        qkm1 = qk;\n\n        if ( qk != 0.0L )\n            r = pk/qk;\n        if ( r != 0.0L )\n        {\n            t = fabs( (ans - r)/r );\n            ans = r;\n        }\n        else\n        {\n           t = 1.0L;\n        }\n\n        if ( t < thresh )\n            return ans;\n\n        k1 += 1.0L;\n        k2 += 1.0L;\n        k3 += 2.0L;\n        k4 += 2.0L;\n        k5 += 1.0L;\n        k6 -= 1.0L;\n        k7 += 2.0L;\n        k8 += 2.0L;\n\n        if ( (fabs(qk) + fabs(pk)) > BETA_BIG )\n        {\n            pkm2 *= BETA_BIGINV;\n            pkm1 *= BETA_BIGINV;\n            qkm2 *= BETA_BIGINV;\n            qkm1 *= BETA_BIGINV;\n            }\n        if ( (fabs(qk) < BETA_BIGINV) || (fabs(pk) < BETA_BIGINV) )\n        {\n            pkm2 *= BETA_BIG;\n            pkm1 *= BETA_BIG;\n            qkm2 *= BETA_BIG;\n            qkm1 *= BETA_BIG;\n            }\n        }\n    while ( ++n < 400 );\n// loss of precision has occurred\n// mtherr( \"incbetl\", PLOSS );\n    return ans;\n}\n\n// Continued fraction expansion #2 for incomplete beta integral\n// Use when x > (a+1)/(a+b+2)\nreal betaDistExpansion2(real a, real b, real x )\n{\n    real  xk, pk, pkm1, pkm2, qk, qkm1, qkm2;\n    real k1, k2, k3, k4, k5, k6, k7, k8;\n    real r, t, ans, z;\n\n    k1 = a;\n    k2 = b - 1.0L;\n    k3 = a;\n    k4 = a + 1.0L;\n    k5 = 1.0L;\n    k6 = a + b;\n    k7 = a + 1.0L;\n    k8 = a + 2.0L;\n\n    pkm2 = 0.0L;\n    qkm2 = 1.0L;\n    pkm1 = 1.0L;\n    qkm1 = 1.0L;\n    z = x / (1.0L-x);\n    ans = 1.0L;\n    r = 1.0L;\n    int n = 0;\n    const real thresh = 3.0L * real.epsilon;\n    do\n    {\n        xk = -( z * k1 * k2 )/( k3 * k4 );\n        pk = pkm1 +  pkm2 * xk;\n        qk = qkm1 +  qkm2 * xk;\n        pkm2 = pkm1;\n        pkm1 = pk;\n        qkm2 = qkm1;\n        qkm1 = qk;\n\n        xk = ( z * k5 * k6 )/( k7 * k8 );\n        pk = pkm1 +  pkm2 * xk;\n        qk = qkm1 +  qkm2 * xk;\n        pkm2 = pkm1;\n        pkm1 = pk;\n        qkm2 = qkm1;\n        qkm1 = qk;\n\n        if ( qk != 0.0L )\n            r = pk/qk;\n        if ( r != 0.0L )\n        {\n            t = fabs( (ans - r)/r );\n            ans = r;\n        } else\n            t = 1.0L;\n\n        if ( t < thresh )\n            return ans;\n        k1 += 1.0L;\n        k2 -= 1.0L;\n        k3 += 2.0L;\n        k4 += 2.0L;\n        k5 += 1.0L;\n        k6 += 1.0L;\n        k7 += 2.0L;\n        k8 += 2.0L;\n\n        if ( (fabs(qk) + fabs(pk)) > BETA_BIG )\n        {\n            pkm2 *= BETA_BIGINV;\n            pkm1 *= BETA_BIGINV;\n            qkm2 *= BETA_BIGINV;\n            qkm1 *= BETA_BIGINV;\n        }\n        if ( (fabs(qk) < BETA_BIGINV) || (fabs(pk) < BETA_BIGINV) )\n        {\n            pkm2 *= BETA_BIG;\n            pkm1 *= BETA_BIG;\n            qkm2 *= BETA_BIG;\n            qkm1 *= BETA_BIG;\n        }\n    } while ( ++n < 400 );\n// loss of precision has occurred\n//mtherr( \"incbetl\", PLOSS );\n    return ans;\n}\n\n/* Power series for incomplete gamma integral.\n   Use when b*x is small.  */\nreal betaDistPowerSeries(real a, real b, real x )\n{\n    real ai = 1.0L / a;\n    real u = (1.0L - b) * x;\n    real v = u / (a + 1.0L);\n    real t1 = v;\n    real t = u;\n    real n = 2.0L;\n    real s = 0.0L;\n    real z = real.epsilon * ai;\n    while ( fabs(v) > z )\n    {\n        u = (n - b) * x / n;\n        t *= u;\n        v = t / (a + n);\n        s += v;\n        n += 1.0L;\n    }\n    s += t1;\n    s += ai;\n\n    u = a * log(x);\n    if ( (a+b) < MAXGAMMA && fabs(u) < MAXLOG )\n    {\n        t = gamma(a+b)/(gamma(a)*gamma(b));\n        s = s * t * pow(x,a);\n    }\n    else\n    {\n        t = logGamma(a+b) - logGamma(a) - logGamma(b) + u + log(s);\n\n        if ( t < MINLOG )\n        {\n            s = 0.0L;\n        } else\n            s = exp(t);\n    }\n    return s;\n}\n\n}\n\n/***************************************\n *  Incomplete gamma integral and its complement\n *\n * These functions are defined by\n *\n *   gammaIncomplete = ( $(INTEGRATE 0, x) $(POWER e, -t) $(POWER t, a-1) dt )/ $(GAMMA)(a)\n *\n *  gammaIncompleteCompl(a,x)   =   1 - gammaIncomplete(a,x)\n * = ($(INTEGRATE x, &infin;) $(POWER e, -t) $(POWER t, a-1) dt )/ $(GAMMA)(a)\n *\n * In this implementation both arguments must be positive.\n * The integral is evaluated by either a power series or\n * continued fraction expansion, depending on the relative\n * values of a and x.\n */\nreal gammaIncomplete(real a, real x )\nin\n{\n   assert(x >= 0);\n   assert(a > 0);\n}\ndo\n{\n    /* left tail of incomplete gamma function:\n     *\n     *          inf.      k\n     *   a  -x   -       x\n     *  x  e     >   ----------\n     *           -     -\n     *          k=0   | (a+k+1)\n     *\n     */\n    if (x == 0)\n       return 0.0L;\n\n    if ( (x > 1.0L) && (x > a ) )\n        return 1.0L - gammaIncompleteCompl(a,x);\n\n    real ax = a * log(x) - x - logGamma(a);\n/+\n    if ( ax < MINLOGL ) return 0; // underflow\n    //  { mtherr( \"igaml\", UNDERFLOW ); return( 0.0L ); }\n+/\n    ax = exp(ax);\n\n    /* power series */\n    real r = a;\n    real c = 1.0L;\n    real ans = 1.0L;\n\n    do\n    {\n        r += 1.0L;\n        c *= x/r;\n        ans += c;\n    } while ( c/ans > real.epsilon );\n\n    return ans * ax/a;\n}\n\n/** ditto */\nreal gammaIncompleteCompl(real a, real x )\nin\n{\n   assert(x >= 0);\n   assert(a > 0);\n}\ndo\n{\n    if (x == 0)\n        return 1.0L;\n    if ( (x < 1.0L) || (x < a) )\n        return 1.0L - gammaIncomplete(a,x);\n\n    // DAC (Cephes bug fix): This is necessary to avoid\n    // spurious nans, eg\n    // log(x)-x = NaN when x = real.infinity\n    const real MAXLOGL =  1.1356523406294143949492E4L;\n    if (x > MAXLOGL)\n        return igammaTemmeLarge(a, x);\n\n    real ax = a * log(x) - x - logGamma(a);\n//const real MINLOGL = -1.1355137111933024058873E4L;\n//  if ( ax < MINLOGL ) return 0; // underflow;\n    ax = exp(ax);\n\n\n    /* continued fraction */\n    real y = 1.0L - a;\n    real z = x + y + 1.0L;\n    real c = 0.0L;\n\n    real pk, qk, t;\n\n    real pkm2 = 1.0L;\n    real qkm2 = x;\n    real pkm1 = x + 1.0L;\n    real qkm1 = z * x;\n    real ans = pkm1/qkm1;\n\n    do\n    {\n        c += 1.0L;\n        y += 1.0L;\n        z += 2.0L;\n        real yc = y * c;\n        pk = pkm1 * z  -  pkm2 * yc;\n        qk = qkm1 * z  -  qkm2 * yc;\n        if ( qk != 0.0L )\n        {\n            real r = pk/qk;\n            t = fabs( (ans - r)/r );\n            ans = r;\n        }\n        else\n        {\n            t = 1.0L;\n        }\n    pkm2 = pkm1;\n        pkm1 = pk;\n        qkm2 = qkm1;\n        qkm1 = qk;\n\n        const real BIG = 9.223372036854775808e18L;\n\n        if ( fabs(pk) > BIG )\n        {\n            pkm2 /= BIG;\n            pkm1 /= BIG;\n            qkm2 /= BIG;\n            qkm1 /= BIG;\n        }\n    } while ( t > real.epsilon );\n\n    return ans * ax;\n}\n\n/** Inverse of complemented incomplete gamma integral\n *\n * Given a and p, the function finds x such that\n *\n *  gammaIncompleteCompl( a, x ) = p.\n *\n * Starting with the approximate value x = a $(POWER t, 3), where\n * t = 1 - d - normalDistributionInv(p) sqrt(d),\n * and d = 1/9a,\n * the routine performs up to 10 Newton iterations to find the\n * root of incompleteGammaCompl(a,x) - p = 0.\n */\nreal gammaIncompleteComplInv(real a, real p)\nin\n{\n  assert(p >= 0 && p <= 1);\n  assert(a>0);\n}\ndo\n{\n    if (p == 0) return real.infinity;\n\n    real y0 = p;\n    const real MAXLOGL =  1.1356523406294143949492E4L;\n    real x0, x1, x, yl, yh, y, d, lgm, dithresh;\n    int i, dir;\n\n    /* bound the solution */\n    x0 = real.max;\n    yl = 0.0L;\n    x1 = 0.0L;\n    yh = 1.0L;\n    dithresh = 4.0 * real.epsilon;\n\n    /* approximation to inverse function */\n    d = 1.0L/(9.0L*a);\n    y = 1.0L - d - normalDistributionInvImpl(y0) * sqrt(d);\n    x = a * y * y * y;\n\n    lgm = logGamma(a);\n\n    for ( i=0; i<10; i++ )\n    {\n        if ( x > x0 || x < x1 )\n            goto ihalve;\n        y = gammaIncompleteCompl(a,x);\n        if ( y < yl || y > yh )\n            goto ihalve;\n        if ( y < y0 )\n        {\n            x0 = x;\n            yl = y;\n        }\n        else\n        {\n            x1 = x;\n            yh = y;\n        }\n    /* compute the derivative of the function at this point */\n        d = (a - 1.0L) * log(x0) - x0 - lgm;\n        if ( d < -MAXLOGL )\n            goto ihalve;\n        d = -exp(d);\n    /* compute the step to the next approximation of x */\n        d = (y - y0)/d;\n        x = x - d;\n        if ( i < 3 ) continue;\n        if ( fabs(d/x) < dithresh ) return x;\n    }\n\n    /* Resort to interval halving if Newton iteration did not converge. */\nihalve:\n    d = 0.0625L;\n    if ( x0 == real.max )\n    {\n        if ( x <= 0.0L )\n            x = 1.0L;\n        while ( x0 == real.max )\n        {\n            x = (1.0L + d) * x;\n            y = gammaIncompleteCompl( a, x );\n            if ( y < y0 )\n            {\n                x0 = x;\n                yl = y;\n                break;\n            }\n            d = d + d;\n        }\n    }\n    d = 0.5L;\n    dir = 0;\n\n    for ( i=0; i<400; i++ )\n    {\n        x = x1  +  d * (x0 - x1);\n        y = gammaIncompleteCompl( a, x );\n        lgm = (x0 - x1)/(x1 + x0);\n        if ( fabs(lgm) < dithresh )\n            break;\n        lgm = (y - y0)/y0;\n        if ( fabs(lgm) < dithresh )\n            break;\n        if ( x <= 0.0L )\n            break;\n        if ( y > y0 )\n        {\n            x1 = x;\n            yh = y;\n            if ( dir < 0 )\n            {\n                dir = 0;\n                d = 0.5L;\n            } else if ( dir > 1 )\n                d = 0.5L * d + 0.5L;\n            else\n                d = (y0 - yl)/(yh - yl);\n            dir += 1;\n        }\n        else\n        {\n            x0 = x;\n            yl = y;\n            if ( dir > 0 )\n            {\n                dir = 0;\n                d = 0.5L;\n            } else if ( dir < -1 )\n                d = 0.5L * d;\n            else\n                d = (y0 - yl)/(yh - yl);\n            dir -= 1;\n        }\n    }\n    /+\n    if ( x == 0.0L )\n        mtherr( \"igamil\", UNDERFLOW );\n    +/\n    return x;\n}\n\n@safe unittest\n{\n//Values from Excel's GammaInv(1-p, x, 1)\nassert(fabs(gammaIncompleteComplInv(1, 0.5) - 0.693147188044814) < 0.00000005);\nassert(fabs(gammaIncompleteComplInv(12, 0.99) - 5.42818075054289) < 0.00000005);\nassert(fabs(gammaIncompleteComplInv(100, 0.8) - 91.5013985848288L) < 0.000005);\nassert(gammaIncomplete(1, 0)==0);\nassert(gammaIncompleteCompl(1, 0)==1);\nassert(gammaIncomplete(4545, real.infinity)==1);\n\n// Values from Excel's (1-GammaDist(x, alpha, 1, TRUE))\n\nassert(fabs(1.0L-gammaIncompleteCompl(0.5, 2) - 0.954499729507309L) < 0.00000005);\nassert(fabs(gammaIncomplete(0.5, 2) - 0.954499729507309L) < 0.00000005);\n// Fixed Cephes bug:\nassert(gammaIncompleteCompl(384, real.infinity)==0);\nassert(gammaIncompleteComplInv(3, 0)==real.infinity);\n// Fixed a bug that caused gammaIncompleteCompl to return a wrong value when\n// x was larger than a, but not by much, and both were large:\n// The value is from WolframAlpha (Gamma[100000, 100001, inf] / Gamma[100000])\nstatic if (real.mant_dig >= 64) // incl. 80-bit reals\n    assert(fabs(gammaIncompleteCompl(100000, 100001) - 0.49831792109) < 0.000000000005);\nelse\n    assert(fabs(gammaIncompleteCompl(100000, 100001) - 0.49831792109) < 0.00000005);\n}\n\n\n// DAC: These values are Bn / n for n=2,4,6,8,10,12,14.\nimmutable real [7] Bn_n  = [\n    1.0L/(6*2), -1.0L/(30*4), 1.0L/(42*6), -1.0L/(30*8),\n    5.0L/(66*10), -691.0L/(2730*12), 7.0L/(6*14) ];\n\n/** Digamma function\n*\n*  The digamma function is the logarithmic derivative of the gamma function.\n*\n*  digamma(x) = d/dx logGamma(x)\n*\n* References:\n*   1. Abramowitz, M., and Stegun, I. A. (1970).\n*      Handbook of mathematical functions. Dover, New York,\n*      pages 258-259, equations 6.3.6 and 6.3.18.\n*/\nreal digamma(real x)\n{\n   // Based on CEPHES, Stephen L. Moshier.\n\n    real p, q, nz, s, w, y, z;\n    long i, n;\n    int negative;\n\n    negative = 0;\n    nz = 0.0;\n\n    if ( x <= 0.0 )\n    {\n        negative = 1;\n        q = x;\n        p = floor(q);\n        if ( p == q )\n        {\n            return real.nan; // singularity.\n        }\n    /* Remove the zeros of tan(PI x)\n     * by subtracting the nearest integer from x\n     */\n        nz = q - p;\n        if ( nz != 0.5 )\n        {\n            if ( nz > 0.5 )\n            {\n                p += 1.0;\n                nz = q - p;\n            }\n            nz = PI/tan(PI*nz);\n        }\n        else\n        {\n            nz = 0.0;\n        }\n        x = 1.0 - x;\n    }\n\n    // check for small positive integer\n    if ((x <= 13.0) && (x == floor(x)) )\n    {\n        y = 0.0;\n        n = lrint(x);\n        // DAC: CEPHES bugfix. Cephes did this in reverse order, which\n        // created a larger roundoff error.\n        for (i=n-1; i>0; --i)\n        {\n            y+=1.0L/i;\n        }\n        y -= EULERGAMMA;\n        goto done;\n    }\n\n    s = x;\n    w = 0.0;\n    while ( s < 10.0 )\n    {\n        w += 1.0/s;\n        s += 1.0;\n    }\n\n    if ( s < 1.0e17 )\n    {\n        z = 1.0/(s * s);\n        y = z * poly(z, Bn_n);\n    } else\n        y = 0.0;\n\n    y = log(s)  -  0.5L/s  -  y  -  w;\n\ndone:\n    if ( negative )\n    {\n        y -= nz;\n    }\n    return y;\n}\n\n@safe unittest\n{\n    // Exact values\n    assert(digamma(1.0)== -EULERGAMMA);\n    assert(feqrel(digamma(0.25), -PI/2 - 3* LN2 - EULERGAMMA) >= real.mant_dig-7);\n    assert(feqrel(digamma(1.0L/6), -PI/2 *sqrt(3.0L) - 2* LN2 -1.5*log(3.0L) - EULERGAMMA) >= real.mant_dig-7);\n    assert(digamma(-5.0).isNaN());\n    assert(feqrel(digamma(2.5), -EULERGAMMA - 2*LN2 + 2.0 + 2.0L/3) >= real.mant_dig-9);\n    assert(isIdentical(digamma(NaN(0xABC)), NaN(0xABC)));\n\n    for (int k=1; k<40; ++k)\n    {\n        real y=0;\n        for (int u=k; u >= 1; --u)\n        {\n            y += 1.0L/u;\n        }\n        assert(feqrel(digamma(k+1.0), -EULERGAMMA + y) >= real.mant_dig-2);\n    }\n}\n\n/** Log Minus Digamma function\n*\n*  logmdigamma(x) = log(x) - digamma(x)\n*\n* References:\n*   1. Abramowitz, M., and Stegun, I. A. (1970).\n*      Handbook of mathematical functions. Dover, New York,\n*      pages 258-259, equations 6.3.6 and 6.3.18.\n*/\nreal logmdigamma(real x)\n{\n    if (x <= 0.0)\n    {\n        if (x == 0.0)\n        {\n            return real.infinity;\n        }\n        return real.nan;\n    }\n\n    real s = x;\n    real w = 0.0;\n    while ( s < 10.0 )\n    {\n        w += 1.0/s;\n        s += 1.0;\n    }\n\n    real y;\n    if ( s < 1.0e17 )\n    {\n        immutable real z = 1.0/(s * s);\n        y = z * poly(z, Bn_n);\n    } else\n        y = 0.0;\n\n    return x == s ? y + 0.5L/s : (log(x/s) + 0.5L/s + y + w);\n}\n\n@safe unittest\n{\n    assert(logmdigamma(-5.0).isNaN());\n    assert(isIdentical(logmdigamma(NaN(0xABC)), NaN(0xABC)));\n    assert(logmdigamma(0.0) == real.infinity);\n    for (auto x = 0.01; x < 1.0; x += 0.1)\n        assert(approxEqual(digamma(x), log(x) - logmdigamma(x)));\n    for (auto x = 1.0; x < 15.0; x += 1.0)\n        assert(approxEqual(digamma(x), log(x) - logmdigamma(x)));\n}\n\n/** Inverse of the Log Minus Digamma function\n *\n *   Returns x such $(D log(x) - digamma(x) == y).\n *\n * References:\n *   1. Abramowitz, M., and Stegun, I. A. (1970).\n *      Handbook of mathematical functions. Dover, New York,\n *      pages 258-259, equation 6.3.18.\n *\n * Authors: Ilya Yaroshenko\n */\nreal logmdigammaInverse(real y)\n{\n    import std.numeric : findRoot;\n    // FIXME: should be returned back to enum.\n    // Fix requires CTFEable `log` on non-x86 targets (check both LDC and GDC).\n    immutable maxY = logmdigamma(real.min_normal);\n    assert(maxY > 0 && maxY <= real.max);\n\n    if (y >= maxY)\n    {\n        //lim x->0 (log(x)-digamma(x))*x == 1\n        return 1 / y;\n    }\n    if (y < 0)\n    {\n        return real.nan;\n    }\n    if (y < real.min_normal)\n    {\n        //6.3.18\n        return 0.5 / y;\n    }\n    if (y > 0)\n    {\n        // x/2 <= logmdigamma(1 / x) <= x, x > 0\n        // calls logmdigamma ~6 times\n        return 1 / findRoot((real x) => logmdigamma(1 / x) - y, y,  2*y);\n    }\n    return y; //NaN\n}\n\n@safe unittest\n{\n    import std.typecons;\n    //WolframAlpha, 22.02.2015\n    immutable Tuple!(real, real)[5] testData = [\n        tuple(1.0L, 0.615556766479594378978099158335549201923L),\n        tuple(1.0L/8, 4.15937801516894947161054974029150730555L),\n        tuple(1.0L/1024, 512.166612384991507850643277924243523243L),\n        tuple(0.000500083333325000003968249801594877323784632117L, 1000.0L),\n        tuple(1017.644138623741168814449776695062817947092468536L, 1.0L/1024),\n    ];\n    foreach (test; testData)\n        assert(approxEqual(logmdigammaInverse(test[0]), test[1], 2e-15, 0));\n\n    assert(approxEqual(logmdigamma(logmdigammaInverse(1)), 1, 1e-15, 0));\n    assert(approxEqual(logmdigamma(logmdigammaInverse(real.min_normal)), real.min_normal, 1e-15, 0));\n    assert(approxEqual(logmdigamma(logmdigammaInverse(real.max/2)), real.max/2, 1e-15, 0));\n    assert(approxEqual(logmdigammaInverse(logmdigamma(1)), 1, 1e-15, 0));\n    assert(approxEqual(logmdigammaInverse(logmdigamma(real.min_normal)), real.min_normal, 1e-15, 0));\n    assert(approxEqual(logmdigammaInverse(logmdigamma(real.max/2)), real.max/2, 1e-15, 0));\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/scopebuffer.d",
    "content": "/*\n * Copyright: 2014 by Digital Mars\n * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors: Walter Bright\n * Source: $(PHOBOSSRC std/internal/scopebuffer.d)\n */\n\nmodule std.internal.scopebuffer;\n\n\n//debug=ScopeBuffer;\n\nimport core.stdc.stdlib : realloc;\nimport std.traits;\n\n/**************************************\n * ScopeBuffer encapsulates using a local array as a temporary buffer.\n * It is initialized with a local array that should be large enough for\n * most uses. If the need exceeds that size, ScopeBuffer will reallocate\n * the data using its `realloc` function.\n *\n * ScopeBuffer cannot contain more than `(uint.max-16)/2` elements.\n *\n * ScopeBuffer is an Output Range.\n *\n * Since ScopeBuffer may store elements of type `T` in `malloc`'d memory,\n * those elements are not scanned when the GC collects. This can cause\n * memory corruption. Do not use ScopeBuffer when elements of type `T` point\n * to the GC heap, except when a `realloc` function is provided which supports this.\n *\n * Example:\n---\nimport core.stdc.stdio;\nimport std.internal.scopebuffer;\nvoid main()\n{\n    char[2] buf = void;\n    auto textbuf = ScopeBuffer!char(buf);\n    scope(exit) textbuf.free(); // necessary for cleanup\n\n    // Put characters and strings into textbuf, verify they got there\n    textbuf.put('a');\n    textbuf.put('x');\n    textbuf.put(\"abc\");\n    assert(textbuf.length == 5);\n    assert(textbuf[1 .. 3] == \"xa\");\n    assert(textbuf[3] == 'b');\n\n    // Can shrink it\n    textbuf.length = 3;\n    assert(textbuf[0 .. textbuf.length] == \"axa\");\n    assert(textbuf[textbuf.length - 1] == 'a');\n    assert(textbuf[1 .. 3] == \"xa\");\n\n    textbuf.put('z');\n    assert(textbuf[] == \"axaz\");\n\n    // Can shrink it to 0 size, and reuse same memory\n    textbuf.length = 0;\n}\n---\n * It is invalid to access ScopeBuffer's contents when ScopeBuffer goes out of scope.\n * Hence, copying the contents are necessary to keep them around:\n---\nimport std.internal.scopebuffer;\nstring cat(string s1, string s2)\n{\n    char[10] tmpbuf = void;\n    auto textbuf = ScopeBuffer!char(tmpbuf);\n    scope(exit) textbuf.free();\n    textbuf.put(s1);\n    textbuf.put(s2);\n    textbuf.put(\"even more\");\n    return textbuf[].idup;\n}\n---\n * ScopeBuffer is intended for high performance usages in `@system` and `@trusted` code.\n * It is designed to fit into two 64 bit registers, again for high performance use.\n * If used incorrectly, memory leaks and corruption can result. Be sure to use\n * $(D scope(exit) textbuf.free();) for proper cleanup, and do not refer to a ScopeBuffer\n * instance's contents after `ScopeBuffer.free()` has been called.\n *\n * The `realloc` parameter defaults to C's `realloc()`. Another can be supplied to override it.\n *\n * ScopeBuffer instances may be copied, as in:\n---\ntextbuf = doSomething(textbuf, args);\n---\n * which can be very efficent, but these must be regarded as a move rather than a copy.\n * Additionally, the code between passing and returning the instance must not throw\n * exceptions, otherwise when `ScopeBuffer.free()` is called, memory may get corrupted.\n */\n\n@system\nstruct ScopeBuffer(T, alias realloc = /*core.stdc.stdlib*/.realloc)\nif (isAssignable!T &&\n    !hasElaborateDestructor!T &&\n    !hasElaborateCopyConstructor!T &&\n    !hasElaborateAssign!T)\n{\n    import core.exception : onOutOfMemoryError;\n    import core.stdc.string : memcpy;\n\n\n    /**************************\n     * Initialize with buf to use as scratch buffer space.\n     * Params:\n     *  buf = Scratch buffer space, must have length that is even\n     * Example:\n     * ---\n     * ubyte[10] tmpbuf = void;\n     * auto sbuf = ScopeBuffer!ubyte(tmpbuf);\n     * ---\n     * Note:\n     * If buf was created by the same `realloc` passed as a parameter\n     * to `ScopeBuffer`, then the contents of `ScopeBuffer` can be extracted without needing\n     * to copy them, and `ScopeBuffer.free()` will not need to be called.\n     */\n    this(T[] buf)\n        in\n        {\n            assert(!(buf.length & wasResized));    // assure even length of scratch buffer space\n            assert(buf.length <= uint.max);     // because we cast to uint later\n        }\n    do\n    {\n        this.buf = buf.ptr;\n        this.bufLen = cast(uint) buf.length;\n    }\n\n    @system unittest\n    {\n        ubyte[10] tmpbuf = void;\n        auto sbuf = ScopeBuffer!ubyte(tmpbuf);\n    }\n\n    /**************************\n     * Releases any memory used.\n     * This will invalidate any references returned by the `[]` operator.\n     * A destructor is not used, because that would make it not POD\n     * (Plain Old Data) and it could not be placed in registers.\n     */\n    void free()\n    {\n        debug(ScopeBuffer) buf[0 .. bufLen] = 0;\n        if (bufLen & wasResized)\n            realloc(buf, 0);\n        buf = null;\n        bufLen = 0;\n        used = 0;\n    }\n\n    /************************\n     * Append element c to the buffer.\n     * This member function makes `ScopeBuffer` an Output Range.\n     */\n    void put(T c)\n    {\n        /* j will get enregistered, while used will not because resize() may change used\n         */\n        const j = used;\n        if (j == bufLen)\n        {\n            assert(j <= (uint.max - 16) / 2);\n            resize(j * 2 + 16);\n        }\n        buf[j] = c;\n        used = j + 1;\n    }\n\n    /************************\n     * Append array s to the buffer.\n     *\n     * If `const(T)` can be converted to `T`, then put will accept\n     * `const(T)[]` as input. It will accept a `T[]` otherwise.\n     */\n    package alias CT = Select!(is(const(T) : T), const(T), T);\n    /// ditto\n    void put(CT[] s)\n    {\n        const newlen = used + s.length;\n        assert((cast(ulong) used + s.length) <= uint.max);\n        const len = bufLen;\n        if (newlen > len)\n        {\n            assert(len <= uint.max / 2);\n            resize(newlen <= len * 2 ? len * 2 : newlen);\n        }\n        buf[used .. newlen] = s[];\n        used = cast(uint) newlen;\n    }\n\n    /******\n     * Returns:\n     *  A slice into the temporary buffer.\n     * Warning:\n     *  The result is only valid until the next `put()` or `ScopeBuffer` goes out of scope.\n     */\n    @system inout(T)[] opSlice(size_t lower, size_t upper) inout\n        in\n        {\n            assert(lower <= bufLen);\n            assert(upper <= bufLen);\n            assert(lower <= upper);\n        }\n    do\n    {\n        return buf[lower .. upper];\n    }\n\n    /// ditto\n    @system inout(T)[] opSlice() inout\n    {\n        assert(used <= bufLen);\n        return buf[0 .. used];\n    }\n\n    /*******\n     * Returns:\n     *  The element at index i.\n     */\n    ref inout(T) opIndex(size_t i) inout\n    {\n        assert(i < bufLen);\n        return buf[i];\n    }\n\n    /***\n     * Returns:\n     *  The number of elements in the `ScopeBuffer`.\n     */\n    @property size_t length() const\n    {\n        return used;\n    }\n\n    /***\n     * Used to shrink the length of the buffer,\n     * typically to `0` so the buffer can be reused.\n     * Cannot be used to extend the length of the buffer.\n     */\n    @property void length(size_t i)\n        in\n        {\n            assert(i <= this.used);\n        }\n    do\n    {\n        this.used = cast(uint) i;\n    }\n\n    alias opDollar = length;\n\n  private:\n    T* buf;\n    // Using uint instead of size_t so the struct fits in 2 registers in 64 bit code\n    uint bufLen;\n    enum wasResized = 1;         // this bit is set in bufLen if we control the memory\n    uint used;\n\n    void resize(size_t newsize)\n        in\n        {\n            assert(newsize <= uint.max);\n        }\n    do\n    {\n        //writefln(\"%s: oldsize %s newsize %s\", id, buf.length, newsize);\n        newsize |= wasResized;\n        void *newBuf = realloc((bufLen & wasResized) ? buf : null, newsize * T.sizeof);\n        if (!newBuf)\n            onOutOfMemoryError();\n        if (!(bufLen & wasResized))\n        {\n            memcpy(newBuf, buf, used * T.sizeof);\n            debug(ScopeBuffer) buf[0 .. bufLen] = 0;\n        }\n        buf = cast(T*) newBuf;\n        bufLen = cast(uint) newsize;\n\n        /* This function is called only rarely,\n         * inlining results in poorer register allocation.\n         */\n        version (DigitalMars)\n            /* With dmd, a fake loop will prevent inlining.\n             * Using a hack until a language enhancement is implemented.\n             */\n            while (1) { break; }\n    }\n}\n\n@system unittest\n{\n    import core.stdc.stdio;\n    import std.range;\n\n    char[2] tmpbuf = void;\n    {\n    // Exercise all the lines of code except for assert(0)'s\n    auto textbuf = ScopeBuffer!char(tmpbuf);\n    scope(exit) textbuf.free();\n\n    static assert(isOutputRange!(ScopeBuffer!char, char));\n\n    textbuf.put('a');\n    textbuf.put('x');\n    textbuf.put(\"abc\");         // tickle put([])'s resize\n    assert(textbuf.length == 5);\n    assert(textbuf[1 .. 3] == \"xa\");\n    assert(textbuf[3] == 'b');\n\n    textbuf.length = textbuf.length - 1;\n    assert(textbuf[0 .. textbuf.length] == \"axab\");\n\n    textbuf.length = 3;\n    assert(textbuf[0 .. textbuf.length] == \"axa\");\n    assert(textbuf[textbuf.length - 1] == 'a');\n    assert(textbuf[1 .. 3] == \"xa\");\n\n    textbuf.put(cast(dchar)'z');\n    assert(textbuf[] == \"axaz\");\n\n    textbuf.length = 0;                 // reset for reuse\n    assert(textbuf.length == 0);\n\n    foreach (char c; \"asdf;lasdlfaklsdjfalksdjfa;lksdjflkajsfdasdfkja;sdlfj\")\n    {\n        textbuf.put(c); // tickle put(c)'s resize\n    }\n    assert(textbuf[] == \"asdf;lasdlfaklsdjfalksdjfa;lksdjflkajsfdasdfkja;sdlfj\");\n    } // run destructor on textbuf here\n\n}\n\n@system unittest\n{\n    string cat(string s1, string s2)\n    {\n        char[10] tmpbuf = void;\n        auto textbuf = ScopeBuffer!char(tmpbuf);\n        scope(exit) textbuf.free();\n        textbuf.put(s1);\n        textbuf.put(s2);\n        textbuf.put(\"even more\");\n        return textbuf[].idup;\n    }\n\n    auto s = cat(\"hello\", \"betty\");\n    assert(s == \"hellobettyeven more\");\n}\n\n// const\n@system unittest\n{\n    char[10] tmpbuf = void;\n    auto textbuf = ScopeBuffer!char(tmpbuf);\n    scope(exit) textbuf.free();\n    foreach (i; 0 .. 10) textbuf.put('w');\n    const csb = textbuf;\n    const elem = csb[3];\n    const slice0 = csb[0 .. 5];\n    const slice1 = csb[];\n}\n\n/*********************************\n * Creates a `ScopeBuffer` instance using type deduction - see\n * $(LREF .ScopeBuffer.this) for details.\n * Params:\n *      tmpbuf = the initial buffer to use\n * Returns:\n *      An instance of `ScopeBuffer`.\n */\n\nauto scopeBuffer(T)(T[] tmpbuf)\n{\n    return ScopeBuffer!T(tmpbuf);\n}\n\n///\n@system unittest\n{\n    ubyte[10] tmpbuf = void;\n    auto sb = scopeBuffer(tmpbuf);\n    scope(exit) sb.free();\n}\n\n@system unittest\n{\n    ScopeBuffer!(int*) b;\n    int*[] s;\n    b.put(s);\n\n    ScopeBuffer!char c;\n    string s1;\n    char[] s2;\n    c.put(s1);\n    c.put(s2);\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/test/dummyrange.d",
    "content": "/**\nFor testing only.\nUsed with the dummy ranges for testing higher order ranges.\n*/\nmodule std.internal.test.dummyrange;\n\nimport std.meta;\nimport std.range.primitives;\nimport std.typecons;\n\nenum RangeType\n{\n    Input,\n    Forward,\n    Bidirectional,\n    Random\n}\n\nenum Length\n{\n    Yes,\n    No\n}\n\nenum ReturnBy\n{\n    Reference,\n    Value\n}\n\nimport std.traits : isArray;\n\n// Range that's useful for testing other higher order ranges,\n// can be parametrized with attributes.  It just dumbs down an array of\n// numbers 1 .. 10.\nstruct DummyRange(ReturnBy _r, Length _l, RangeType _rt, T = uint[])\nif (isArray!T)\n{\n    private static immutable uinttestData =\n        [1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U];\n    // These enums are so that the template params are visible outside\n    // this instantiation.\n    enum r = _r;\n    enum l = _l;\n    enum rt = _rt;\n\n    static if (is(T == uint[]))\n    {\n        T arr = uinttestData;\n    }\n    else\n    {\n        T arr;\n    }\n\n    alias RetType = ElementType!(T);\n    alias RetTypeNoAutoDecoding = ElementEncodingType!(T);\n\n    void reinit()\n    {\n        // Workaround for DMD bug 4378\n        static if (is(T == uint[]))\n        {\n            arr = uinttestData.dup;\n        }\n    }\n\n    void popFront()\n    {\n        arr = arr[1..$];\n    }\n\n    @property bool empty() const\n    {\n        return arr.length == 0;\n    }\n\n    static if (r == ReturnBy.Reference)\n    {\n        @property ref inout(RetType) front() inout\n        {\n            return arr[0];\n        }\n    }\n    else\n    {\n        @property RetType front() const\n        {\n            return arr[0];\n        }\n\n        @property void front(RetTypeNoAutoDecoding val)\n        {\n            arr[0] = val;\n        }\n    }\n\n    static if (rt >= RangeType.Forward)\n    {\n        @property typeof(this) save()\n        {\n            return this;\n        }\n    }\n\n    static if (rt >= RangeType.Bidirectional)\n    {\n        void popBack()\n        {\n            arr = arr[0..$ - 1];\n        }\n\n        static if (r == ReturnBy.Reference)\n        {\n            @property ref inout(RetType) back() inout\n            {\n                return arr[$ - 1];\n            }\n        }\n        else\n        {\n            @property RetType back() const\n            {\n                return arr[$ - 1];\n            }\n\n            @property void back(RetTypeNoAutoDecoding val)\n            {\n                arr[$ - 1] = val;\n            }\n        }\n    }\n\n    static if (rt >= RangeType.Random)\n    {\n        static if (r == ReturnBy.Reference)\n        {\n            ref inout(RetType) opIndex(size_t index) inout\n            {\n                return arr[index];\n            }\n        }\n        else\n        {\n            RetType opIndex(size_t index) const\n            {\n                return arr[index];\n            }\n\n            RetType opIndexAssign(RetTypeNoAutoDecoding val, size_t index)\n            {\n                return arr[index] = val;\n            }\n\n            RetType opIndexOpAssign(string op)(RetTypeNoAutoDecoding value, size_t index)\n            {\n                mixin(\"return arr[index] \" ~ op ~ \"= value;\");\n            }\n\n            RetType opIndexUnary(string op)(size_t index)\n            {\n                mixin(\"return \" ~ op ~ \"arr[index];\");\n            }\n        }\n\n        typeof(this) opSlice(size_t lower, size_t upper)\n        {\n            auto ret = this;\n            ret.arr = arr[lower .. upper];\n            return ret;\n        }\n\n        typeof(this) opSlice()\n        {\n            return this;\n        }\n    }\n\n    static if (l == Length.Yes)\n    {\n        @property size_t length() const\n        {\n            return arr.length;\n        }\n\n        alias opDollar = length;\n    }\n}\n\nenum dummyLength = 10;\n\nalias AllDummyRanges = AliasSeq!(\n    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Forward),\n    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Bidirectional),\n    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random),\n    DummyRange!(ReturnBy.Reference, Length.No, RangeType.Forward),\n    DummyRange!(ReturnBy.Reference, Length.No, RangeType.Bidirectional),\n    DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Input),\n    DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Forward),\n    DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Bidirectional),\n    DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Random),\n    DummyRange!(ReturnBy.Value, Length.No, RangeType.Input),\n    DummyRange!(ReturnBy.Value, Length.No, RangeType.Forward),\n    DummyRange!(ReturnBy.Value, Length.No, RangeType.Bidirectional)\n);\n\ntemplate AllDummyRangesType(T)\n{\n    alias AllDummyRangesType = AliasSeq!(\n        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Forward, T),\n        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Bidirectional, T),\n        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random, T),\n        DummyRange!(ReturnBy.Reference, Length.No, RangeType.Forward, T),\n        DummyRange!(ReturnBy.Reference, Length.No, RangeType.Bidirectional, T),\n        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Input, T),\n        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Forward, T),\n        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Bidirectional, T),\n        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Random, T),\n        DummyRange!(ReturnBy.Value, Length.No, RangeType.Input, T),\n        DummyRange!(ReturnBy.Value, Length.No, RangeType.Forward, T),\n        DummyRange!(ReturnBy.Value, Length.No, RangeType.Bidirectional, T)\n    );\n}\n\n/**\nTests whether forward, bidirectional and random access properties are\npropagated properly from the base range(s) R to the higher order range\nH.  Useful in combination with DummyRange for testing several higher\norder ranges.\n*/\ntemplate propagatesRangeType(H, R...)\n{\n    static if (allSatisfy!(isRandomAccessRange, R))\n        enum bool propagatesRangeType = isRandomAccessRange!H;\n    else static if (allSatisfy!(isBidirectionalRange, R))\n        enum bool propagatesRangeType = isBidirectionalRange!H;\n    else static if (allSatisfy!(isForwardRange, R))\n        enum bool propagatesRangeType = isForwardRange!H;\n    else\n        enum bool propagatesRangeType = isInputRange!H;\n}\n\ntemplate propagatesLength(H, R...)\n{\n    static if (allSatisfy!(hasLength, R))\n        enum bool propagatesLength = hasLength!H;\n    else\n        enum bool propagatesLength = !hasLength!H;\n}\n\n/**\nReference type input range\n*/\nclass ReferenceInputRange(T)\n{\n    import std.array : array;\n\n    this(Range)(Range r) if (isInputRange!Range) {_payload = array(r);}\n    final @property ref T front(){return _payload.front;}\n    final void popFront(){_payload.popFront();}\n    final @property bool empty(){return _payload.empty;}\n    protected T[] _payload;\n}\n\n/**\nInfinite input range\n*/\nclass ReferenceInfiniteInputRange(T)\n{\n    this(T first = T.init) {_val = first;}\n    final @property T front(){return _val;}\n    final void popFront(){++_val;}\n    enum bool empty = false;\n    protected T _val;\n}\n\n/**\nReference forward range\n*/\nclass ReferenceForwardRange(T) : ReferenceInputRange!T\n{\n    this(Range)(Range r) if (isInputRange!Range) {super(r);}\n    final @property auto save(this This)() {return new This( _payload);}\n}\n\n/**\nInfinite forward range\n*/\nclass ReferenceInfiniteForwardRange(T) : ReferenceInfiniteInputRange!T\n{\n    this(T first = T.init) {super(first);}\n    final @property ReferenceInfiniteForwardRange save()\n    {return new ReferenceInfiniteForwardRange!T(_val);}\n}\n\n/**\nReference bidirectional range\n*/\nclass ReferenceBidirectionalRange(T) : ReferenceForwardRange!T\n{\n    this(Range)(Range r) if (isInputRange!Range) {super(r);}\n    final @property ref T back(){return _payload.back;}\n    final void popBack(){_payload.popBack();}\n}\n\n@safe unittest\n{\n    static assert(isInputRange!(ReferenceInputRange!int));\n    static assert(isInputRange!(ReferenceInfiniteInputRange!int));\n\n    static assert(isForwardRange!(ReferenceForwardRange!int));\n    static assert(isForwardRange!(ReferenceInfiniteForwardRange!int));\n\n    static assert(isBidirectionalRange!(ReferenceBidirectionalRange!int));\n}\n\nprivate:\n\npure struct Cmp(T)\nif (is(T == uint))\n{\n    static auto iota(size_t low = 1, size_t high = 11)\n    {\n        import std.range : iota;\n        return iota(cast(uint) low, cast(uint) high);\n    }\n\n    static void initialize(ref uint[] arr)\n    {\n        import std.array : array;\n        arr = iota().array;\n    }\n\n    static bool function(uint,uint) cmp = function(uint a, uint b) { return a == b; };\n\n    enum dummyValue = 1337U;\n    enum dummyValueRslt = 1337U * 2;\n}\n\npure struct Cmp(T)\nif (is(T == double))\n{\n    import std.math : approxEqual;\n\n    static auto iota(size_t low = 1, size_t high = 11)\n    {\n        import std.range : iota;\n        return iota(cast(double) low, cast(double) high, 1.0);\n    }\n\n    static void initialize(ref double[] arr)\n    {\n        import std.array : array;\n        arr = iota().array;\n    }\n\n    alias cmp = approxEqual!(double,double);\n\n    enum dummyValue = 1337.0;\n    enum dummyValueRslt = 1337.0 * 2.0;\n}\n\nstruct TestFoo\n{\n    int a;\n\n    bool opEquals(const ref TestFoo other) const\n    {\n        return this.a == other.a;\n    }\n\n    TestFoo opBinary(string op)(TestFoo other)\n    {\n        TestFoo ret = this;\n        mixin(\"ret.a \" ~ op ~ \"= other.a;\");\n        return ret;\n    }\n\n    TestFoo opOpAssign(string op)(TestFoo other)\n    {\n        mixin(\"this.a \" ~ op ~ \"= other.a;\");\n        return this;\n    }\n}\n\npure struct Cmp(T)\nif (is(T == TestFoo))\n{\n    import std.math : approxEqual;\n\n    static auto iota(size_t low = 1, size_t high = 11)\n    {\n        import std.algorithm.iteration : map;\n        import std.range : iota;\n        return iota(cast(int) low, cast(int) high).map!(a => TestFoo(a));\n    }\n\n    static void initialize(ref TestFoo[] arr)\n    {\n        import std.array : array;\n        arr = iota().array;\n    }\n\n    static bool function(TestFoo,TestFoo) cmp = function(TestFoo a, TestFoo b)\n    {\n        return a.a == b.a;\n    };\n\n    @property static TestFoo dummyValue()\n    {\n        return TestFoo(1337);\n    }\n\n    @property static TestFoo dummyValueRslt()\n    {\n        return TestFoo(1337 * 2);\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota, retro, repeat;\n    import std.traits : Unqual;\n\n    static void testInputRange(T,Cmp)()\n    {\n        T it;\n        Cmp.initialize(it.arr);\n        for (size_t numRuns = 0; numRuns < 2; ++numRuns)\n        {\n            if (numRuns == 1)\n            {\n                static if (is(Unqual!(ElementType!(T)) == uint))\n                {\n                    it.reinit();\n                }\n\n                Cmp.initialize(it.arr);\n            }\n\n            assert(equal!(Cmp.cmp)(it, Cmp.iota(1, 11)));\n\n            static if (hasLength!T)\n            {\n                assert(it.length == 10);\n            }\n\n            assert(!Cmp.cmp(it.front, Cmp.dummyValue));\n            auto s = it.front;\n            it.front = Cmp.dummyValue;\n            assert(Cmp.cmp(it.front, Cmp.dummyValue));\n            it.front = s;\n\n            auto cmp = Cmp.iota(1,11);\n\n            size_t jdx = 0;\n            while (!it.empty && !cmp.empty)\n            {\n                static if (hasLength!T)\n                {\n                    assert(it.length == 10 - jdx);\n                }\n\n                assert(Cmp.cmp(it.front, cmp.front));\n                it.popFront();\n                cmp.popFront();\n\n                ++jdx;\n            }\n\n            assert(it.empty);\n            assert(cmp.empty);\n        }\n\n    }\n\n    static void testForwardRange(T,Cmp)()\n    {\n        T it;\n        Cmp.initialize(it.arr);\n        auto s = it.save();\n        s.popFront();\n        assert(!Cmp.cmp(s.front, it.front));\n    }\n\n    static void testBidirectionalRange(T,Cmp)()\n    {\n        T it;\n        Cmp.initialize(it.arr);\n        assert(equal!(Cmp.cmp)(it.retro, Cmp.iota().retro));\n\n        auto s = it.back;\n        assert(!Cmp.cmp(s, Cmp.dummyValue));\n        it.back = Cmp.dummyValue;\n        assert( Cmp.cmp(it.back, Cmp.dummyValue));\n        it.back = s;\n    }\n\n    static void testRandomAccessRange(T,Cmp)()\n    {\n        T it;\n        Cmp.initialize(it.arr);\n        size_t idx = 0;\n        foreach (jt; it)\n        {\n            assert(it[idx] == jt);\n\n            T copy = it[idx .. $];\n            auto cmp = Cmp.iota(idx + 1, it.length + 1);\n            assert(equal!(Cmp.cmp)(copy, cmp));\n\n            ++idx;\n        }\n\n        {\n            auto copy = it;\n            copy.arr = it.arr.dup;\n            for (size_t i = 0; i < copy.length; ++i)\n            {\n                copy[i] = Cmp.dummyValue;\n                copy[i] += Cmp.dummyValue;\n            }\n            assert(equal!(Cmp.cmp)(copy, Cmp.dummyValueRslt.repeat(copy.length)));\n        }\n\n        static if (it.r == ReturnBy.Reference)\n        {\n            T copy;\n            copy.arr = it.arr.dup;\n            for (size_t i = 0; i < copy.length; ++i)\n            {\n                copy[i] = Cmp.dummyValue;\n                copy[i] += Cmp.dummyValue;\n            }\n\n            assert(equal!(Cmp.cmp)(copy, Cmp.dummyValueRslt.repeat(copy.length)));\n        }\n    }\n\n    import std.meta : AliasSeq;\n\n    static foreach (S; AliasSeq!(uint, double, TestFoo))\n    {\n        foreach (T; AllDummyRangesType!(S[]))\n        {\n            testInputRange!(T,Cmp!S)();\n\n            static if (isForwardRange!T)\n            {\n                testForwardRange!(T,Cmp!S)();\n            }\n\n            static if (isBidirectionalRange!T)\n            {\n                testBidirectionalRange!(T,Cmp!S)();\n            }\n\n            static if (isRandomAccessRange!T)\n            {\n                testRandomAccessRange!(T,Cmp!S)();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/test/range.d",
    "content": "/**\nFor testing only.\nContains tests related to member privacy that cannot be verified inside\nstd.range itself.\n*/\nmodule std.internal.test.range;\n\n// Note: currently can't be @safe because RefCounted, which is used by chunks,\n// isn't.\n@system /*@safe*/ unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : chunks;\n\n    struct R\n    {\n        int state = 0;\n        @property bool empty() { return state >= 5; }\n        @property int front() { return state; }\n        void popFront() { state++; }\n    }\n\n    auto r = R().chunks(3);\n    assert(r.equal!equal([[ 0, 1, 2 ], [ 3, 4 ]]));\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/test/uda.d",
    "content": "/**\nFor testing only.\nProvides a struct with UDA's defined in an external module.\nUseful for validating behavior with member privacy.\n*/\nmodule std.internal.test.uda;\n\nenum Attr;\n\nstruct HasPrivateMembers\n{\n  @Attr int a;\n  int b;\n  @Attr private int c;\n  private int d;\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/unicode_comp.d",
    "content": "module std.internal.unicode_comp;\nimport std.internal.unicode_tables;\n\n@safe pure nothrow @nogc package(std):\n\nstatic if (size_t.sizeof == 8)\n{\n    //6976 bytes\n    enum combiningClassTrieEntries = TrieEntry!(ubyte, 8, 7, 6)([0x0, 0x20,\n            0x120], [0x100, 0x400, 0x1240], [0x402030202020100,\n            0x206020202020205, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x0, 0x0, 0x0, 0x20001, 0x300000000,\n            0x5000400000000, 0x8000000070006, 0xb0000000a0009, 0xe0000000d000c,\n            0x11000f0010000f, 0x11000f0011000f, 0x1100000011000f,\n            0x11000f00120000, 0x13000000110000, 0x17001600150014,\n            0x1b001a00190018, 0x1d0000001c, 0x0, 0x0, 0x1e0000, 0x0, 0x0, 0x0,\n            0x2000000000001f, 0x2100000000, 0x22, 0x240023, 0x28002700260025,\n            0x2a000000000029, 0x2b000000000000, 0x0, 0x0, 0x2c000000000000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x2d000000000000, 0x2f0000002e0000, 0x0, 0x0, 0x3100000030, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x34003300320000, 0x0, 0x36000000000035, 0x3a003900380037,\n            0x3c003b00000000, 0x3d000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x3e, 0x0, 0x0, 0x3f, 0x0, 0x0, 0x40000000000000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x4200350000, 0x3a000000000043, 0x0, 0x0, 0x0, 0x0, 0x4400000000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x4600450000, 0x470000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6e6e6e6e6e6e6e6,\n            0xe6e6e6e6e6e6e6e6, 0xdcdce8e6e6e6e6e6, 0xdcdcdcdcd8e8dcdc,\n            0xcadcdcdcdccacadc, 0xdcdcdcdcdcdcdcca, 0x1010101dcdcdcdc,\n            0xe6e6e6dcdcdcdc01, 0xdce6f0e6e6e6e6e6, 0xdcdce6e6e6dcdc,\n            0xe6dcdcdcdce6e6e6, 0xe9eaeae9e6dcdce8, 0xe6e6e6e6e6e9eaea,\n            0xe6e6e6e6e6e6e6e6, 0x0, 0x0, 0xe6e6e6e6e6000000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6dce6e6e6e6dc00,\n            0xe6e6e6e6dcdee6e6, 0xdcdcdcdcdcdce6e6, 0xe6e4dee6e6dce6e6,\n            0x11100f0e0d0c0b0a, 0x1700161514131312, 0x1200dce600191800, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6e6e6e6e6e6e6e6,\n            0x201f1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f1e1d1c1b000000,\n            0xe6dcdce6e6222120, 0xdce6e6dce6e6e6e6, 0x0, 0x0, 0x23, 0x0, 0x0,\n            0x0, 0xe6e6000000000000, 0xe60000e6e6e6e6e6, 0xe60000e6dce6e6e6,\n            0xdce6e6dc00e6, 0x0, 0x0, 0x0, 0x0, 0x2400, 0x0, 0x0, 0x0,\n            0xdce6e6dce6e6dce6, 0xe6dce6dcdce6dcdc, 0xe6dce6dce6dce6e6,\n            0xe6e6dc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xe6e6e6e6e6000000, 0xe6dce6e6, 0x0, 0x0, 0x0, 0xe6e6000000000000,\n            0xe6e6e6e6e600e6e6, 0xe6e6e600e6e6e6e6, 0xe6e6e6e6e600, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xdcdcdc00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xe6dce6e600000000, 0xdcdcdce6e6e6dce6, 0xe6dce6e6e61d1c1b,\n            0xe6e6e6e6dcdce6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x700000000,\n            0x0, 0x90000000000, 0xe6e6dce600, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x90000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x90000000000,\n            0x5b540000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x90000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x96767,\n            0x0, 0x6b6b6b6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x7676, 0x0, 0x7a7a7a7a, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xdcdc, 0x0, 0x0, 0xdc00dc0000000000, 0xd800,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8400828100, 0x828282820000,\n            0xe6e60009e6e60082, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xdc000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x700000000000000, 0x90900, 0x0, 0xdc0000000000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6e6e60000000000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x900000000, 0x0, 0x0, 0x0,\n            0x900000000, 0x0, 0x0, 0x0, 0x90000, 0xe60000000000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe400, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xdce6de00, 0x0, 0x0, 0xe600000000000000, 0xdc, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0xe6e6e60000000000,\n            0xdc0000e6e6e6e6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x700000000, 0x0,\n            0x900000000, 0x0, 0x0, 0x0, 0x0, 0xe6e6e6dce6000000, 0xe6e6e6e6,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9090000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x7000000000000, 0x0, 0x9090000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x700000000000000, 0x0, 0x0, 0x0, 0xdcdcdc0100e6e6e6,\n            0xdcdcdcdce6e6dcdc, 0x1010101010100e6, 0xdc0000000001,\n            0xe600000000, 0x0, 0xe6e6e6e6e6dce6e6, 0xdcd6eae6e6dce6e6,\n            0xe6e6e6e6e6e6e6ca, 0xe6e6e6e6e6e6e6e6, 0xe6e6e6e6e6e6e6, 0x0, 0x0,\n            0xdce6dce900000000, 0x0, 0x0, 0xe6e6e6e60101e6e6, 0xe6e6010101,\n            0xe60101000000e600, 0xdcdcdcdc0101e6dc, 0xe6, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xe600000000000000, 0xe6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x900000000000000, 0x0, 0x0, 0x0, 0x0,\n            0xe6e6e6e6e6e6e6e6, 0xe6e6e6e6e6e6e6e6, 0xe6e6e6e6e6e6e6e6,\n            0xe6e6e6e6e6e6e6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0e0dee8e4da0000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x80800, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xe600000000000000, 0xe6e6e6e600000000,\n            0xe6e6e6e6e6e6, 0x0, 0x0, 0x0, 0xe600000000000000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6e6, 0x0, 0x9000000000000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x900000000, 0x0, 0x0, 0x0,\n            0xe6e6e6e6e6e6e6e6, 0xe6e6e6e6e6e6e6e6, 0xe6e6, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xdcdcdc000000, 0x0, 0x0, 0x0, 0x0, 0x9000000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7000000, 0x0, 0x9,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xe60000dce6e600e6, 0xe6e60000000000e6, 0xe600, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x9000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x90000000000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x1a000000000000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xe6e6e6e6e6e6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xdc0000000000, 0x0, 0xe600dc0000000000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x900000000dc01e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x70900, 0xe6e6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x909000000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x709000000000000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x1d8d80000000000, 0xd8d8e20000000101, 0xd8d8d8,\n            0xdcdcdcdcdc000000, 0xe6e6e60000dcdcdc, 0xdcdce6e6, 0x0, 0x0, 0x0,\n            0xe6e6e6e60000, 0x0, 0x0, 0xe6e6e60000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    enum composeIdxMask = (1 << 11) - 1, composeCntShift = 11;\n    enum compositionJumpTrieEntries = TrieEntry!(ushort, 12, 9)([0x0, 0x400],\n            [0x1000, 0x2000], [0x3000200010000, 0x7000600050004,\n            0x7000700070008, 0xa000700090007, 0x70007000c000b, 0x7000700070007,\n            0x700070007000d, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x700070007000e, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffff080208010800,\n            0x281618138003ffff, 0x383308328821301b, 0x285108507841383a,\n            0x8068485f185c3056, 0x3882407affff1078, 0x30a510a398903889,\n            0xffff30b648ad10ab, 0xffffffffffffffff, 0x28cf18cc80bcffff,\n            0x38ec08eb88da30d4, 0x290b110970fb40f3, 0x8122491919163110,\n            0x393c4134ffff1132, 0x3960115e994b4143, 0xffff317351691167,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffff1979,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffff217cffffffff,\n            0x984118209810980, 0xffff2185ffffffff, 0x989ffffffffffff,\n            0xffffffffffffffff, 0xffff0991198e218a, 0xffffffffffff0992,\n            0xffffffffffff2193, 0xffff2197ffffffff, 0x99f119d099c099b,\n            0xffff21a0ffffffff, 0x9a4ffffffffffff, 0xffffffffffffffff,\n            0xffff09ac19a921a5, 0xffffffffffff09ad, 0xffffffffffff21ae,\n            0x21b621b2ffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0x11bc11baffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffff11c011be, 0xffffffffffffffff,\n            0xffffffffffffffff, 0x9c309c2ffffffff, 0xffffffffffffffff,\n            0xffffffff09c509c4, 0xffffffffffffffff, 0x9c909c809c709c6,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0x9caffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffff29d029cb, 0xffffffffffffffff,\n            0xffffffffffffffff, 0x29d5ffffffffffff, 0xffffffffffff29da,\n            0x9dfffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0x9e109e0ffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0x9e309e2ffffffff, 0xffffffff09e509e4,\n            0x9e709e6ffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffff09e8ffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff39e9ffff,\n            0x29f4ffff21f0ffff, 0xffffffff39f9ffff, 0x2200ffffffffffff,\n            0xffffffff0a04ffff, 0xffffffff3205ffff, 0xffffffff2a0bffff,\n            0xffff0a11ffff0a10, 0xffffffff4212ffff, 0x321effff221affff,\n            0xffffffff4224ffff, 0x222cffffffffffff, 0xffffffff1230ffff,\n            0xffffffff4232ffff, 0x1a431a40323affff, 0xffff0a46ffffffff,\n            0xffff1247ffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffff0a49ffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xa4cffffffff124a, 0xa5212501a4dffff,\n            0xffff0a57ffff2253, 0xffff0a58ffffffff, 0x2259ffffffffffff,\n            0xa5dffffffffffff, 0xa5effffffffffff, 0xffffffff0a5fffff,\n            0xa62ffffffff1260, 0xa6812661a63ffff, 0xffff0a6dffff2269,\n            0xffff0a6effffffff, 0x226fffffffffffff, 0xa73ffffffffffff,\n            0xa74ffffffffffff, 0xffffffff0a75ffff, 0xffffffffffffffff,\n            0xffff0a76ffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff0a780a77,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffff0a7a0a79, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffff0a7c0a7b, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0x1a7dffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffff0a81ffff0a80,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff0a82ffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffff0a83ffffffff, 0xffffffff0a84ffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffff0a85, 0xffffffffffffffff, 0xa87ffffffff0a86,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0x1288ffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0x1a8affffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffff0a8dffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xa90128effffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffff0a91ffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xa92ffffffffffff, 0xffffffffffffffff,\n            0xffff1a93ffffffff, 0xffff0a96ffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xa991297ffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffff1a9affff, 0xffffffffffff0a9d, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffff0a9effff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xaa0ffff0a9fffff, 0xaa2ffff0aa1ffff,\n            0xffffffff0aa3ffff, 0xffffffff0aa4ffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffff0aa5ffffffff,\n            0xaa80aa7ffff0aa6, 0xffff0aa9ffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xaab0aaaffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xaad0aacffffffff,\n            0xffffffffffffffff, 0xaaf0aaeffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff12b212b0,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff0ab50ab4,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffff0ab70ab6, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xac10ac022bc22b8,\n            0xac50ac40ac30ac2, 0xacf0ace22ca22c6, 0xad30ad20ad10ad0,\n            0xffffffff12d612d4, 0xffffffffffffffff, 0xffffffff12da12d8,\n            0xffffffffffffffff, 0xae50ae422e022dc, 0xae90ae80ae70ae6,\n            0xaf30af222ee22ea, 0xaf70af60af50af4, 0xffffffff1afb1af8,\n            0xffffffffffffffff, 0xffffffff1b011afe, 0xffffffffffffffff,\n            0xffffffff13061304, 0xffffffffffffffff, 0xffffffff130a1308,\n            0xffffffffffffffff, 0xffffffff1b0f1b0c, 0xffffffffffffffff,\n            0xffffffff1b12ffff, 0xffffffffffffffff, 0xb1e0b1d23192315,\n            0xb220b210b200b1f, 0xb2c0b2b23272323, 0xb300b2f0b2e0b2d,\n            0xffffffffffff0b31, 0xffffffffffff0b32, 0xffffffffffffffff,\n            0xffffffffffff0b33, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffff0b34ffffffff,\n            0xffffffffffffffff, 0x1b35ffffffffffff, 0xffffffffffffffff,\n            0xffff0b38ffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffff0b39ffffffff, 0xffffffffffffffff, 0xffff1b3affffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffff0b3effff0b3d, 0xffffffffffff0b3f,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffff0b41ffff0b40,\n            0xffffffffffff0b42, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xb43ffffffffffff,\n            0xffffffffffffffff, 0xb45ffffffff0b44, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xb46ffffffffffff, 0xffffffff0b47ffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffff0b48,\n            0xb49ffffffffffff, 0xffffffff0b4affff, 0xffffffffffff0b4b,\n            0xffffffff0b4cffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff0b4dffff,\n            0xffffffff0b4f0b4e, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xb510b50ffffffff, 0xb530b52ffffffff, 0xb550b54ffffffff,\n            0xffffffff0b570b56, 0xb590b58ffffffff, 0xb5b0b5affffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffff0b5d0b5cffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffff0b5effffffff, 0xffffffffffffffff, 0xb61ffff0b600b5f,\n            0xffffffffffffffff, 0xb630b62ffffffff, 0xffffffff0b650b64,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffff0b66ffffffff, 0xb67ffffffffffff, 0xb69ffff0b68ffff,\n            0xb6bffff0b6affff, 0xb6dffff0b6cffff, 0xb6fffff0b6effff,\n            0xb71ffff0b70ffff, 0xffffffff0b72ffff, 0xffff0b74ffff0b73,\n            0xffffffffffff0b75, 0x1376ffffffffffff, 0xffff1378ffffffff,\n            0xffffffff137affff, 0x137effffffff137c, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffff0b80ffff, 0xffffffffffffffff,\n            0xffff0b81ffffffff, 0xb82ffffffffffff, 0xb84ffff0b83ffff,\n            0xb86ffff0b85ffff, 0xb88ffff0b87ffff, 0xb8affff0b89ffff,\n            0xb8cffff0b8bffff, 0xffffffff0b8dffff, 0xffff0b8fffff0b8e,\n            0xffffffffffff0b90, 0x1391ffffffffffff, 0xffff1393ffffffff,\n            0xffffffff1395ffff, 0x1399ffffffff1397, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xb9bffffffffffff, 0xffff0b9e0b9d0b9c, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffff0b9fffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xba1ffff0ba0ffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff0ba2ffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffff0ba40ba3ffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff]);\n    @property immutable(CompEntry[]) compositionTable()\n    {\n        alias CE = CompEntry;\n        static immutable CE[] t = [\n            CE(0x00338, 0x0226e), CE(0x00338, 0x02260), CE(0x00338, 0x0226f),\n            CE(0x00300, 0x000c0), CE(0x00301, 0x000c1), CE(0x00302, 0x000c2),\n            CE(0x00303, 0x000c3), CE(0x00304, 0x00100), CE(0x00306, 0x00102),\n            CE(0x00307, 0x00226), CE(0x00308, 0x000c4), CE(0x00309, 0x01ea2),\n            CE(0x0030a, 0x000c5), CE(0x0030c, 0x001cd), CE(0x0030f, 0x00200),\n            CE(0x00311, 0x00202), CE(0x00323, 0x01ea0), CE(0x00325, 0x01e00),\n            CE(0x00328, 0x00104), CE(0x00307, 0x01e02), CE(0x00323, 0x01e04),\n            CE(0x00331, 0x01e06), CE(0x00301, 0x00106), CE(0x00302, 0x00108),\n            CE(0x00307, 0x0010a), CE(0x0030c, 0x0010c), CE(0x00327, 0x000c7),\n            CE(0x00307, 0x01e0a), CE(0x0030c, 0x0010e), CE(0x00323, 0x01e0c),\n            CE(0x00327, 0x01e10), CE(0x0032d, 0x01e12), CE(0x00331, 0x01e0e),\n            CE(0x00300, 0x000c8), CE(0x00301, 0x000c9), CE(0x00302, 0x000ca),\n            CE(0x00303, 0x01ebc), CE(0x00304, 0x00112), CE(0x00306, 0x00114),\n            CE(0x00307, 0x00116), CE(0x00308, 0x000cb), CE(0x00309, 0x01eba),\n            CE(0x0030c, 0x0011a), CE(0x0030f, 0x00204), CE(0x00311, 0x00206),\n            CE(0x00323, 0x01eb8), CE(0x00327, 0x00228), CE(0x00328, 0x00118),\n            CE(0x0032d, 0x01e18), CE(0x00330, 0x01e1a), CE(0x00307, 0x01e1e),\n            CE(0x00301, 0x001f4), CE(0x00302, 0x0011c), CE(0x00304, 0x01e20),\n            CE(0x00306, 0x0011e), CE(0x00307, 0x00120), CE(0x0030c, 0x001e6),\n            CE(0x00327, 0x00122), CE(0x00302, 0x00124), CE(0x00307, 0x01e22),\n            CE(0x00308, 0x01e26), CE(0x0030c, 0x0021e), CE(0x00323, 0x01e24),\n            CE(0x00327, 0x01e28), CE(0x0032e, 0x01e2a), CE(0x00300, 0x000cc),\n            CE(0x00301, 0x000cd), CE(0x00302, 0x000ce), CE(0x00303, 0x00128),\n            CE(0x00304, 0x0012a), CE(0x00306, 0x0012c), CE(0x00307, 0x00130),\n            CE(0x00308, 0x000cf), CE(0x00309, 0x01ec8), CE(0x0030c, 0x001cf),\n            CE(0x0030f, 0x00208), CE(0x00311, 0x0020a), CE(0x00323, 0x01eca),\n            CE(0x00328, 0x0012e), CE(0x00330, 0x01e2c), CE(0x00302, 0x00134),\n            CE(0x00301, 0x01e30), CE(0x0030c, 0x001e8), CE(0x00323, 0x01e32),\n            CE(0x00327, 0x00136), CE(0x00331, 0x01e34), CE(0x00301, 0x00139),\n            CE(0x0030c, 0x0013d), CE(0x00323, 0x01e36), CE(0x00327, 0x0013b),\n            CE(0x0032d, 0x01e3c), CE(0x00331, 0x01e3a), CE(0x00301, 0x01e3e),\n            CE(0x00307, 0x01e40), CE(0x00323, 0x01e42), CE(0x00300, 0x001f8),\n            CE(0x00301, 0x00143), CE(0x00303, 0x000d1), CE(0x00307, 0x01e44),\n            CE(0x0030c, 0x00147), CE(0x00323, 0x01e46), CE(0x00327, 0x00145),\n            CE(0x0032d, 0x01e4a), CE(0x00331, 0x01e48), CE(0x00300, 0x000d2),\n            CE(0x00301, 0x000d3), CE(0x00302, 0x000d4), CE(0x00303, 0x000d5),\n            CE(0x00304, 0x0014c), CE(0x00306, 0x0014e), CE(0x00307, 0x0022e),\n            CE(0x00308, 0x000d6), CE(0x00309, 0x01ece), CE(0x0030b, 0x00150),\n            CE(0x0030c, 0x001d1), CE(0x0030f, 0x0020c), CE(0x00311, 0x0020e),\n            CE(0x0031b, 0x001a0), CE(0x00323, 0x01ecc), CE(0x00328, 0x001ea),\n            CE(0x00301, 0x01e54), CE(0x00307, 0x01e56), CE(0x00301, 0x00154),\n            CE(0x00307, 0x01e58), CE(0x0030c, 0x00158), CE(0x0030f, 0x00210),\n            CE(0x00311, 0x00212), CE(0x00323, 0x01e5a), CE(0x00327, 0x00156),\n            CE(0x00331, 0x01e5e), CE(0x00301, 0x0015a), CE(0x00302, 0x0015c),\n            CE(0x00307, 0x01e60), CE(0x0030c, 0x00160), CE(0x00323, 0x01e62),\n            CE(0x00326, 0x00218), CE(0x00327, 0x0015e), CE(0x00307, 0x01e6a),\n            CE(0x0030c, 0x00164), CE(0x00323, 0x01e6c), CE(0x00326, 0x0021a),\n            CE(0x00327, 0x00162), CE(0x0032d, 0x01e70), CE(0x00331, 0x01e6e),\n            CE(0x00300, 0x000d9), CE(0x00301, 0x000da), CE(0x00302, 0x000db),\n            CE(0x00303, 0x00168), CE(0x00304, 0x0016a), CE(0x00306, 0x0016c),\n            CE(0x00308, 0x000dc), CE(0x00309, 0x01ee6), CE(0x0030a, 0x0016e),\n            CE(0x0030b, 0x00170), CE(0x0030c, 0x001d3), CE(0x0030f, 0x00214),\n            CE(0x00311, 0x00216), CE(0x0031b, 0x001af), CE(0x00323, 0x01ee4),\n            CE(0x00324, 0x01e72), CE(0x00328, 0x00172), CE(0x0032d, 0x01e76),\n            CE(0x00330, 0x01e74), CE(0x00303, 0x01e7c), CE(0x00323, 0x01e7e),\n            CE(0x00300, 0x01e80), CE(0x00301, 0x01e82), CE(0x00302, 0x00174),\n            CE(0x00307, 0x01e86), CE(0x00308, 0x01e84), CE(0x00323, 0x01e88),\n            CE(0x00307, 0x01e8a), CE(0x00308, 0x01e8c), CE(0x00300, 0x01ef2),\n            CE(0x00301, 0x000dd), CE(0x00302, 0x00176), CE(0x00303, 0x01ef8),\n            CE(0x00304, 0x00232), CE(0x00307, 0x01e8e), CE(0x00308, 0x00178),\n            CE(0x00309, 0x01ef6), CE(0x00323, 0x01ef4), CE(0x00301, 0x00179),\n            CE(0x00302, 0x01e90), CE(0x00307, 0x0017b), CE(0x0030c, 0x0017d),\n            CE(0x00323, 0x01e92), CE(0x00331, 0x01e94), CE(0x00300, 0x000e0),\n            CE(0x00301, 0x000e1), CE(0x00302, 0x000e2), CE(0x00303, 0x000e3),\n            CE(0x00304, 0x00101), CE(0x00306, 0x00103), CE(0x00307, 0x00227),\n            CE(0x00308, 0x000e4), CE(0x00309, 0x01ea3), CE(0x0030a, 0x000e5),\n            CE(0x0030c, 0x001ce), CE(0x0030f, 0x00201), CE(0x00311, 0x00203),\n            CE(0x00323, 0x01ea1), CE(0x00325, 0x01e01), CE(0x00328, 0x00105),\n            CE(0x00307, 0x01e03), CE(0x00323, 0x01e05), CE(0x00331, 0x01e07),\n            CE(0x00301, 0x00107), CE(0x00302, 0x00109), CE(0x00307, 0x0010b),\n            CE(0x0030c, 0x0010d), CE(0x00327, 0x000e7), CE(0x00307, 0x01e0b),\n            CE(0x0030c, 0x0010f), CE(0x00323, 0x01e0d), CE(0x00327, 0x01e11),\n            CE(0x0032d, 0x01e13), CE(0x00331, 0x01e0f), CE(0x00300, 0x000e8),\n            CE(0x00301, 0x000e9), CE(0x00302, 0x000ea), CE(0x00303, 0x01ebd),\n            CE(0x00304, 0x00113), CE(0x00306, 0x00115), CE(0x00307, 0x00117),\n            CE(0x00308, 0x000eb), CE(0x00309, 0x01ebb), CE(0x0030c, 0x0011b),\n            CE(0x0030f, 0x00205), CE(0x00311, 0x00207), CE(0x00323, 0x01eb9),\n            CE(0x00327, 0x00229), CE(0x00328, 0x00119), CE(0x0032d, 0x01e19),\n            CE(0x00330, 0x01e1b), CE(0x00307, 0x01e1f), CE(0x00301, 0x001f5),\n            CE(0x00302, 0x0011d), CE(0x00304, 0x01e21), CE(0x00306, 0x0011f),\n            CE(0x00307, 0x00121), CE(0x0030c, 0x001e7), CE(0x00327, 0x00123),\n            CE(0x00302, 0x00125), CE(0x00307, 0x01e23), CE(0x00308, 0x01e27),\n            CE(0x0030c, 0x0021f), CE(0x00323, 0x01e25), CE(0x00327, 0x01e29),\n            CE(0x0032e, 0x01e2b), CE(0x00331, 0x01e96), CE(0x00300, 0x000ec),\n            CE(0x00301, 0x000ed), CE(0x00302, 0x000ee), CE(0x00303, 0x00129),\n            CE(0x00304, 0x0012b), CE(0x00306, 0x0012d), CE(0x00308, 0x000ef),\n            CE(0x00309, 0x01ec9), CE(0x0030c, 0x001d0), CE(0x0030f, 0x00209),\n            CE(0x00311, 0x0020b), CE(0x00323, 0x01ecb), CE(0x00328, 0x0012f),\n            CE(0x00330, 0x01e2d), CE(0x00302, 0x00135), CE(0x0030c, 0x001f0),\n            CE(0x00301, 0x01e31), CE(0x0030c, 0x001e9), CE(0x00323, 0x01e33),\n            CE(0x00327, 0x00137), CE(0x00331, 0x01e35), CE(0x00301, 0x0013a),\n            CE(0x0030c, 0x0013e), CE(0x00323, 0x01e37), CE(0x00327, 0x0013c),\n            CE(0x0032d, 0x01e3d), CE(0x00331, 0x01e3b), CE(0x00301, 0x01e3f),\n            CE(0x00307, 0x01e41), CE(0x00323, 0x01e43), CE(0x00300, 0x001f9),\n            CE(0x00301, 0x00144), CE(0x00303, 0x000f1), CE(0x00307, 0x01e45),\n            CE(0x0030c, 0x00148), CE(0x00323, 0x01e47), CE(0x00327, 0x00146),\n            CE(0x0032d, 0x01e4b), CE(0x00331, 0x01e49), CE(0x00300, 0x000f2),\n            CE(0x00301, 0x000f3), CE(0x00302, 0x000f4), CE(0x00303, 0x000f5),\n            CE(0x00304, 0x0014d), CE(0x00306, 0x0014f), CE(0x00307, 0x0022f),\n            CE(0x00308, 0x000f6), CE(0x00309, 0x01ecf), CE(0x0030b, 0x00151),\n            CE(0x0030c, 0x001d2), CE(0x0030f, 0x0020d), CE(0x00311, 0x0020f),\n            CE(0x0031b, 0x001a1), CE(0x00323, 0x01ecd), CE(0x00328, 0x001eb),\n            CE(0x00301, 0x01e55), CE(0x00307, 0x01e57), CE(0x00301, 0x00155),\n            CE(0x00307, 0x01e59), CE(0x0030c, 0x00159), CE(0x0030f, 0x00211),\n            CE(0x00311, 0x00213), CE(0x00323, 0x01e5b), CE(0x00327, 0x00157),\n            CE(0x00331, 0x01e5f), CE(0x00301, 0x0015b), CE(0x00302, 0x0015d),\n            CE(0x00307, 0x01e61), CE(0x0030c, 0x00161), CE(0x00323, 0x01e63),\n            CE(0x00326, 0x00219), CE(0x00327, 0x0015f), CE(0x00307, 0x01e6b),\n            CE(0x00308, 0x01e97), CE(0x0030c, 0x00165), CE(0x00323, 0x01e6d),\n            CE(0x00326, 0x0021b), CE(0x00327, 0x00163), CE(0x0032d, 0x01e71),\n            CE(0x00331, 0x01e6f), CE(0x00300, 0x000f9), CE(0x00301, 0x000fa),\n            CE(0x00302, 0x000fb), CE(0x00303, 0x00169), CE(0x00304, 0x0016b),\n            CE(0x00306, 0x0016d), CE(0x00308, 0x000fc), CE(0x00309, 0x01ee7),\n            CE(0x0030a, 0x0016f), CE(0x0030b, 0x00171), CE(0x0030c, 0x001d4),\n            CE(0x0030f, 0x00215), CE(0x00311, 0x00217), CE(0x0031b, 0x001b0),\n            CE(0x00323, 0x01ee5), CE(0x00324, 0x01e73), CE(0x00328, 0x00173),\n            CE(0x0032d, 0x01e77), CE(0x00330, 0x01e75), CE(0x00303, 0x01e7d),\n            CE(0x00323, 0x01e7f), CE(0x00300, 0x01e81), CE(0x00301, 0x01e83),\n            CE(0x00302, 0x00175), CE(0x00307, 0x01e87), CE(0x00308, 0x01e85),\n            CE(0x0030a, 0x01e98), CE(0x00323, 0x01e89), CE(0x00307, 0x01e8b),\n            CE(0x00308, 0x01e8d), CE(0x00300, 0x01ef3), CE(0x00301, 0x000fd),\n            CE(0x00302, 0x00177), CE(0x00303, 0x01ef9), CE(0x00304, 0x00233),\n            CE(0x00307, 0x01e8f), CE(0x00308, 0x000ff), CE(0x00309, 0x01ef7),\n            CE(0x0030a, 0x01e99), CE(0x00323, 0x01ef5), CE(0x00301, 0x0017a),\n            CE(0x00302, 0x01e91), CE(0x00307, 0x0017c), CE(0x0030c, 0x0017e),\n            CE(0x00323, 0x01e93), CE(0x00331, 0x01e95), CE(0x00300, 0x01fed),\n            CE(0x00301, 0x00385), CE(0x00342, 0x01fc1), CE(0x00300, 0x01ea6),\n            CE(0x00301, 0x01ea4), CE(0x00303, 0x01eaa), CE(0x00309, 0x01ea8),\n            CE(0x00304, 0x001de), CE(0x00301, 0x001fa), CE(0x00301, 0x001fc),\n            CE(0x00304, 0x001e2), CE(0x00301, 0x01e08), CE(0x00300, 0x01ec0),\n            CE(0x00301, 0x01ebe), CE(0x00303, 0x01ec4), CE(0x00309, 0x01ec2),\n            CE(0x00301, 0x01e2e), CE(0x00300, 0x01ed2), CE(0x00301, 0x01ed0),\n            CE(0x00303, 0x01ed6), CE(0x00309, 0x01ed4), CE(0x00301, 0x01e4c),\n            CE(0x00304, 0x0022c), CE(0x00308, 0x01e4e), CE(0x00304, 0x0022a),\n            CE(0x00301, 0x001fe), CE(0x00300, 0x001db), CE(0x00301, 0x001d7),\n            CE(0x00304, 0x001d5), CE(0x0030c, 0x001d9), CE(0x00300, 0x01ea7),\n            CE(0x00301, 0x01ea5), CE(0x00303, 0x01eab), CE(0x00309, 0x01ea9),\n            CE(0x00304, 0x001df), CE(0x00301, 0x001fb), CE(0x00301, 0x001fd),\n            CE(0x00304, 0x001e3), CE(0x00301, 0x01e09), CE(0x00300, 0x01ec1),\n            CE(0x00301, 0x01ebf), CE(0x00303, 0x01ec5), CE(0x00309, 0x01ec3),\n            CE(0x00301, 0x01e2f), CE(0x00300, 0x01ed3), CE(0x00301, 0x01ed1),\n            CE(0x00303, 0x01ed7), CE(0x00309, 0x01ed5), CE(0x00301, 0x01e4d),\n            CE(0x00304, 0x0022d), CE(0x00308, 0x01e4f), CE(0x00304, 0x0022b),\n            CE(0x00301, 0x001ff), CE(0x00300, 0x001dc), CE(0x00301, 0x001d8),\n            CE(0x00304, 0x001d6), CE(0x0030c, 0x001da), CE(0x00300, 0x01eb0),\n            CE(0x00301, 0x01eae), CE(0x00303, 0x01eb4), CE(0x00309, 0x01eb2),\n            CE(0x00300, 0x01eb1), CE(0x00301, 0x01eaf), CE(0x00303, 0x01eb5),\n            CE(0x00309, 0x01eb3), CE(0x00300, 0x01e14), CE(0x00301, 0x01e16),\n            CE(0x00300, 0x01e15), CE(0x00301, 0x01e17), CE(0x00300, 0x01e50),\n            CE(0x00301, 0x01e52), CE(0x00300, 0x01e51), CE(0x00301, 0x01e53),\n            CE(0x00307, 0x01e64), CE(0x00307, 0x01e65), CE(0x00307, 0x01e66),\n            CE(0x00307, 0x01e67), CE(0x00301, 0x01e78), CE(0x00301, 0x01e79),\n            CE(0x00308, 0x01e7a), CE(0x00308, 0x01e7b), CE(0x00307, 0x01e9b),\n            CE(0x00300, 0x01edc), CE(0x00301, 0x01eda), CE(0x00303, 0x01ee0),\n            CE(0x00309, 0x01ede), CE(0x00323, 0x01ee2), CE(0x00300, 0x01edd),\n            CE(0x00301, 0x01edb), CE(0x00303, 0x01ee1), CE(0x00309, 0x01edf),\n            CE(0x00323, 0x01ee3), CE(0x00300, 0x01eea), CE(0x00301, 0x01ee8),\n            CE(0x00303, 0x01eee), CE(0x00309, 0x01eec), CE(0x00323, 0x01ef0),\n            CE(0x00300, 0x01eeb), CE(0x00301, 0x01ee9), CE(0x00303, 0x01eef),\n            CE(0x00309, 0x01eed), CE(0x00323, 0x01ef1), CE(0x0030c, 0x001ee),\n            CE(0x00304, 0x001ec), CE(0x00304, 0x001ed), CE(0x00304, 0x001e0),\n            CE(0x00304, 0x001e1), CE(0x00306, 0x01e1c), CE(0x00306, 0x01e1d),\n            CE(0x00304, 0x00230), CE(0x00304, 0x00231), CE(0x0030c, 0x001ef),\n            CE(0x00300, 0x01fba), CE(0x00301, 0x00386), CE(0x00304, 0x01fb9),\n            CE(0x00306, 0x01fb8), CE(0x00313, 0x01f08), CE(0x00314, 0x01f09),\n            CE(0x00345, 0x01fbc), CE(0x00300, 0x01fc8), CE(0x00301, 0x00388),\n            CE(0x00313, 0x01f18), CE(0x00314, 0x01f19), CE(0x00300, 0x01fca),\n            CE(0x00301, 0x00389), CE(0x00313, 0x01f28), CE(0x00314, 0x01f29),\n            CE(0x00345, 0x01fcc), CE(0x00300, 0x01fda), CE(0x00301, 0x0038a),\n            CE(0x00304, 0x01fd9), CE(0x00306, 0x01fd8), CE(0x00308, 0x003aa),\n            CE(0x00313, 0x01f38), CE(0x00314, 0x01f39), CE(0x00300, 0x01ff8),\n            CE(0x00301, 0x0038c), CE(0x00313, 0x01f48), CE(0x00314, 0x01f49),\n            CE(0x00314, 0x01fec), CE(0x00300, 0x01fea), CE(0x00301, 0x0038e),\n            CE(0x00304, 0x01fe9), CE(0x00306, 0x01fe8), CE(0x00308, 0x003ab),\n            CE(0x00314, 0x01f59), CE(0x00300, 0x01ffa), CE(0x00301, 0x0038f),\n            CE(0x00313, 0x01f68), CE(0x00314, 0x01f69), CE(0x00345, 0x01ffc),\n            CE(0x00345, 0x01fb4), CE(0x00345, 0x01fc4), CE(0x00300, 0x01f70),\n            CE(0x00301, 0x003ac), CE(0x00304, 0x01fb1), CE(0x00306, 0x01fb0),\n            CE(0x00313, 0x01f00), CE(0x00314, 0x01f01), CE(0x00342, 0x01fb6),\n            CE(0x00345, 0x01fb3), CE(0x00300, 0x01f72), CE(0x00301, 0x003ad),\n            CE(0x00313, 0x01f10), CE(0x00314, 0x01f11), CE(0x00300, 0x01f74),\n            CE(0x00301, 0x003ae), CE(0x00313, 0x01f20), CE(0x00314, 0x01f21),\n            CE(0x00342, 0x01fc6), CE(0x00345, 0x01fc3), CE(0x00300, 0x01f76),\n            CE(0x00301, 0x003af), CE(0x00304, 0x01fd1), CE(0x00306, 0x01fd0),\n            CE(0x00308, 0x003ca), CE(0x00313, 0x01f30), CE(0x00314, 0x01f31),\n            CE(0x00342, 0x01fd6), CE(0x00300, 0x01f78), CE(0x00301, 0x003cc),\n            CE(0x00313, 0x01f40), CE(0x00314, 0x01f41), CE(0x00313, 0x01fe4),\n            CE(0x00314, 0x01fe5), CE(0x00300, 0x01f7a), CE(0x00301, 0x003cd),\n            CE(0x00304, 0x01fe1), CE(0x00306, 0x01fe0), CE(0x00308, 0x003cb),\n            CE(0x00313, 0x01f50), CE(0x00314, 0x01f51), CE(0x00342, 0x01fe6),\n            CE(0x00300, 0x01f7c), CE(0x00301, 0x003ce), CE(0x00313, 0x01f60),\n            CE(0x00314, 0x01f61), CE(0x00342, 0x01ff6), CE(0x00345, 0x01ff3),\n            CE(0x00300, 0x01fd2), CE(0x00301, 0x00390), CE(0x00342, 0x01fd7),\n            CE(0x00300, 0x01fe2), CE(0x00301, 0x003b0), CE(0x00342, 0x01fe7),\n            CE(0x00345, 0x01ff4), CE(0x00301, 0x003d3), CE(0x00308, 0x003d4),\n            CE(0x00308, 0x00407), CE(0x00306, 0x004d0), CE(0x00308, 0x004d2),\n            CE(0x00301, 0x00403), CE(0x00300, 0x00400), CE(0x00306, 0x004d6),\n            CE(0x00308, 0x00401), CE(0x00306, 0x004c1), CE(0x00308, 0x004dc),\n            CE(0x00308, 0x004de), CE(0x00300, 0x0040d), CE(0x00304, 0x004e2),\n            CE(0x00306, 0x00419), CE(0x00308, 0x004e4), CE(0x00301, 0x0040c),\n            CE(0x00308, 0x004e6), CE(0x00304, 0x004ee), CE(0x00306, 0x0040e),\n            CE(0x00308, 0x004f0), CE(0x0030b, 0x004f2), CE(0x00308, 0x004f4),\n            CE(0x00308, 0x004f8), CE(0x00308, 0x004ec), CE(0x00306, 0x004d1),\n            CE(0x00308, 0x004d3), CE(0x00301, 0x00453), CE(0x00300, 0x00450),\n            CE(0x00306, 0x004d7), CE(0x00308, 0x00451), CE(0x00306, 0x004c2),\n            CE(0x00308, 0x004dd), CE(0x00308, 0x004df), CE(0x00300, 0x0045d),\n            CE(0x00304, 0x004e3), CE(0x00306, 0x00439), CE(0x00308, 0x004e5),\n            CE(0x00301, 0x0045c), CE(0x00308, 0x004e7), CE(0x00304, 0x004ef),\n            CE(0x00306, 0x0045e), CE(0x00308, 0x004f1), CE(0x0030b, 0x004f3),\n            CE(0x00308, 0x004f5), CE(0x00308, 0x004f9), CE(0x00308, 0x004ed),\n            CE(0x00308, 0x00457), CE(0x0030f, 0x00476), CE(0x0030f, 0x00477),\n            CE(0x00308, 0x004da), CE(0x00308, 0x004db), CE(0x00308, 0x004ea),\n            CE(0x00308, 0x004eb), CE(0x00653, 0x00622), CE(0x00654, 0x00623),\n            CE(0x00655, 0x00625), CE(0x00654, 0x00624), CE(0x00654, 0x00626),\n            CE(0x00654, 0x006c2), CE(0x00654, 0x006d3), CE(0x00654, 0x006c0),\n            CE(0x0093c, 0x00929), CE(0x0093c, 0x00931), CE(0x0093c, 0x00934),\n            CE(0x009be, 0x009cb), CE(0x009d7, 0x009cc), CE(0x00b3e, 0x00b4b),\n            CE(0x00b56, 0x00b48), CE(0x00b57, 0x00b4c), CE(0x00bd7, 0x00b94),\n            CE(0x00bbe, 0x00bca), CE(0x00bd7, 0x00bcc), CE(0x00bbe, 0x00bcb),\n            CE(0x00c56, 0x00c48), CE(0x00cd5, 0x00cc0), CE(0x00cc2, 0x00cca),\n            CE(0x00cd5, 0x00cc7), CE(0x00cd6, 0x00cc8), CE(0x00cd5, 0x00ccb),\n            CE(0x00d3e, 0x00d4a), CE(0x00d57, 0x00d4c), CE(0x00d3e, 0x00d4b),\n            CE(0x00dca, 0x00dda), CE(0x00dcf, 0x00ddc), CE(0x00ddf, 0x00dde),\n            CE(0x00dca, 0x00ddd), CE(0x0102e, 0x01026), CE(0x01b35, 0x01b06),\n            CE(0x01b35, 0x01b08), CE(0x01b35, 0x01b0a), CE(0x01b35, 0x01b0c),\n            CE(0x01b35, 0x01b0e), CE(0x01b35, 0x01b12), CE(0x01b35, 0x01b3b),\n            CE(0x01b35, 0x01b3d), CE(0x01b35, 0x01b40), CE(0x01b35, 0x01b41),\n            CE(0x01b35, 0x01b43), CE(0x00304, 0x01e38), CE(0x00304, 0x01e39),\n            CE(0x00304, 0x01e5c), CE(0x00304, 0x01e5d), CE(0x00307, 0x01e68),\n            CE(0x00307, 0x01e69), CE(0x00302, 0x01eac), CE(0x00306, 0x01eb6),\n            CE(0x00302, 0x01ead), CE(0x00306, 0x01eb7), CE(0x00302, 0x01ec6),\n            CE(0x00302, 0x01ec7), CE(0x00302, 0x01ed8), CE(0x00302, 0x01ed9),\n            CE(0x00300, 0x01f02), CE(0x00301, 0x01f04), CE(0x00342, 0x01f06),\n            CE(0x00345, 0x01f80), CE(0x00300, 0x01f03), CE(0x00301, 0x01f05),\n            CE(0x00342, 0x01f07), CE(0x00345, 0x01f81), CE(0x00345, 0x01f82),\n            CE(0x00345, 0x01f83), CE(0x00345, 0x01f84), CE(0x00345, 0x01f85),\n            CE(0x00345, 0x01f86), CE(0x00345, 0x01f87), CE(0x00300, 0x01f0a),\n            CE(0x00301, 0x01f0c), CE(0x00342, 0x01f0e), CE(0x00345, 0x01f88),\n            CE(0x00300, 0x01f0b), CE(0x00301, 0x01f0d), CE(0x00342, 0x01f0f),\n            CE(0x00345, 0x01f89), CE(0x00345, 0x01f8a), CE(0x00345, 0x01f8b),\n            CE(0x00345, 0x01f8c), CE(0x00345, 0x01f8d), CE(0x00345, 0x01f8e),\n            CE(0x00345, 0x01f8f), CE(0x00300, 0x01f12), CE(0x00301, 0x01f14),\n            CE(0x00300, 0x01f13), CE(0x00301, 0x01f15), CE(0x00300, 0x01f1a),\n            CE(0x00301, 0x01f1c), CE(0x00300, 0x01f1b), CE(0x00301, 0x01f1d),\n            CE(0x00300, 0x01f22), CE(0x00301, 0x01f24), CE(0x00342, 0x01f26),\n            CE(0x00345, 0x01f90), CE(0x00300, 0x01f23), CE(0x00301, 0x01f25),\n            CE(0x00342, 0x01f27), CE(0x00345, 0x01f91), CE(0x00345, 0x01f92),\n            CE(0x00345, 0x01f93), CE(0x00345, 0x01f94), CE(0x00345, 0x01f95),\n            CE(0x00345, 0x01f96), CE(0x00345, 0x01f97), CE(0x00300, 0x01f2a),\n            CE(0x00301, 0x01f2c), CE(0x00342, 0x01f2e), CE(0x00345, 0x01f98),\n            CE(0x00300, 0x01f2b), CE(0x00301, 0x01f2d), CE(0x00342, 0x01f2f),\n            CE(0x00345, 0x01f99), CE(0x00345, 0x01f9a), CE(0x00345, 0x01f9b),\n            CE(0x00345, 0x01f9c), CE(0x00345, 0x01f9d), CE(0x00345, 0x01f9e),\n            CE(0x00345, 0x01f9f), CE(0x00300, 0x01f32), CE(0x00301, 0x01f34),\n            CE(0x00342, 0x01f36), CE(0x00300, 0x01f33), CE(0x00301, 0x01f35),\n            CE(0x00342, 0x01f37), CE(0x00300, 0x01f3a), CE(0x00301, 0x01f3c),\n            CE(0x00342, 0x01f3e), CE(0x00300, 0x01f3b), CE(0x00301, 0x01f3d),\n            CE(0x00342, 0x01f3f), CE(0x00300, 0x01f42), CE(0x00301, 0x01f44),\n            CE(0x00300, 0x01f43), CE(0x00301, 0x01f45), CE(0x00300, 0x01f4a),\n            CE(0x00301, 0x01f4c), CE(0x00300, 0x01f4b), CE(0x00301, 0x01f4d),\n            CE(0x00300, 0x01f52), CE(0x00301, 0x01f54), CE(0x00342, 0x01f56),\n            CE(0x00300, 0x01f53), CE(0x00301, 0x01f55), CE(0x00342, 0x01f57),\n            CE(0x00300, 0x01f5b), CE(0x00301, 0x01f5d), CE(0x00342, 0x01f5f),\n            CE(0x00300, 0x01f62), CE(0x00301, 0x01f64), CE(0x00342, 0x01f66),\n            CE(0x00345, 0x01fa0), CE(0x00300, 0x01f63), CE(0x00301, 0x01f65),\n            CE(0x00342, 0x01f67), CE(0x00345, 0x01fa1), CE(0x00345, 0x01fa2),\n            CE(0x00345, 0x01fa3), CE(0x00345, 0x01fa4), CE(0x00345, 0x01fa5),\n            CE(0x00345, 0x01fa6), CE(0x00345, 0x01fa7), CE(0x00300, 0x01f6a),\n            CE(0x00301, 0x01f6c), CE(0x00342, 0x01f6e), CE(0x00345, 0x01fa8),\n            CE(0x00300, 0x01f6b), CE(0x00301, 0x01f6d), CE(0x00342, 0x01f6f),\n            CE(0x00345, 0x01fa9), CE(0x00345, 0x01faa), CE(0x00345, 0x01fab),\n            CE(0x00345, 0x01fac), CE(0x00345, 0x01fad), CE(0x00345, 0x01fae),\n            CE(0x00345, 0x01faf), CE(0x00345, 0x01fb2), CE(0x00345, 0x01fc2),\n            CE(0x00345, 0x01ff2), CE(0x00345, 0x01fb7), CE(0x00300, 0x01fcd),\n            CE(0x00301, 0x01fce), CE(0x00342, 0x01fcf), CE(0x00345, 0x01fc7),\n            CE(0x00345, 0x01ff7), CE(0x00300, 0x01fdd), CE(0x00301, 0x01fde),\n            CE(0x00342, 0x01fdf), CE(0x00338, 0x0219a), CE(0x00338, 0x0219b),\n            CE(0x00338, 0x021ae), CE(0x00338, 0x021cd), CE(0x00338, 0x021cf),\n            CE(0x00338, 0x021ce), CE(0x00338, 0x02204), CE(0x00338, 0x02209),\n            CE(0x00338, 0x0220c), CE(0x00338, 0x02224), CE(0x00338, 0x02226),\n            CE(0x00338, 0x02241), CE(0x00338, 0x02244), CE(0x00338, 0x02247),\n            CE(0x00338, 0x02249), CE(0x00338, 0x0226d), CE(0x00338, 0x02262),\n            CE(0x00338, 0x02270), CE(0x00338, 0x02271), CE(0x00338, 0x02274),\n            CE(0x00338, 0x02275), CE(0x00338, 0x02278), CE(0x00338, 0x02279),\n            CE(0x00338, 0x02280), CE(0x00338, 0x02281), CE(0x00338, 0x022e0),\n            CE(0x00338, 0x022e1), CE(0x00338, 0x02284), CE(0x00338, 0x02285),\n            CE(0x00338, 0x02288), CE(0x00338, 0x02289), CE(0x00338, 0x022e2),\n            CE(0x00338, 0x022e3), CE(0x00338, 0x022ac), CE(0x00338, 0x022ad),\n            CE(0x00338, 0x022ae), CE(0x00338, 0x022af), CE(0x00338, 0x022ea),\n            CE(0x00338, 0x022eb), CE(0x00338, 0x022ec), CE(0x00338, 0x022ed),\n            CE(0x03099, 0x03094), CE(0x03099, 0x0304c), CE(0x03099, 0x0304e),\n            CE(0x03099, 0x03050), CE(0x03099, 0x03052), CE(0x03099, 0x03054),\n            CE(0x03099, 0x03056), CE(0x03099, 0x03058), CE(0x03099, 0x0305a),\n            CE(0x03099, 0x0305c), CE(0x03099, 0x0305e), CE(0x03099, 0x03060),\n            CE(0x03099, 0x03062), CE(0x03099, 0x03065), CE(0x03099, 0x03067),\n            CE(0x03099, 0x03069), CE(0x03099, 0x03070), CE(0x0309a, 0x03071),\n            CE(0x03099, 0x03073), CE(0x0309a, 0x03074), CE(0x03099, 0x03076),\n            CE(0x0309a, 0x03077), CE(0x03099, 0x03079), CE(0x0309a, 0x0307a),\n            CE(0x03099, 0x0307c), CE(0x0309a, 0x0307d), CE(0x03099, 0x0309e),\n            CE(0x03099, 0x030f4), CE(0x03099, 0x030ac), CE(0x03099, 0x030ae),\n            CE(0x03099, 0x030b0), CE(0x03099, 0x030b2), CE(0x03099, 0x030b4),\n            CE(0x03099, 0x030b6), CE(0x03099, 0x030b8), CE(0x03099, 0x030ba),\n            CE(0x03099, 0x030bc), CE(0x03099, 0x030be), CE(0x03099, 0x030c0),\n            CE(0x03099, 0x030c2), CE(0x03099, 0x030c5), CE(0x03099, 0x030c7),\n            CE(0x03099, 0x030c9), CE(0x03099, 0x030d0), CE(0x0309a, 0x030d1),\n            CE(0x03099, 0x030d3), CE(0x0309a, 0x030d4), CE(0x03099, 0x030d6),\n            CE(0x0309a, 0x030d7), CE(0x03099, 0x030d9), CE(0x0309a, 0x030da),\n            CE(0x03099, 0x030dc), CE(0x0309a, 0x030dd), CE(0x03099, 0x030f7),\n            CE(0x03099, 0x030f8), CE(0x03099, 0x030f9), CE(0x03099, 0x030fa),\n            CE(0x03099, 0x030fe), CE(0x110ba, 0x1109a), CE(0x110ba, 0x1109c),\n            CE(0x110ba, 0x110ab), CE(0x11127, 0x1112e), CE(0x11127, 0x1112f),\n        ];\n        return t;\n    }\n\n}\n\nstatic if (size_t.sizeof == 4)\n{\n    //6976 bytes\n    enum combiningClassTrieEntries = TrieEntry!(ubyte, 8, 7, 6)([0x0, 0x40,\n            0x240], [0x100, 0x400, 0x1240], [0x2020100, 0x4020302, 0x2020205,\n            0x2060202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20001, 0x0, 0x0, 0x3,\n            0x0, 0x50004, 0x70006, 0x80000, 0xa0009, 0xb0000, 0xd000c, 0xe0000,\n            0x10000f, 0x11000f, 0x11000f, 0x11000f, 0x11000f, 0x110000,\n            0x120000, 0x11000f, 0x110000, 0x130000, 0x150014, 0x170016,\n            0x190018, 0x1b001a, 0x1c, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x1e0000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x200000, 0x0, 0x21, 0x22, 0x0,\n            0x240023, 0x0, 0x260025, 0x280027, 0x29, 0x2a0000, 0x0, 0x2b0000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x2c0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x2d0000, 0x2e0000, 0x2f0000, 0x0, 0x0, 0x0,\n            0x0, 0x30, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x320000, 0x340033, 0x0, 0x0, 0x35,\n            0x360000, 0x380037, 0x3a0039, 0x0, 0x3c003b, 0x0, 0x3d0000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x400000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x350000, 0x42, 0x43, 0x3a0000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x450000, 0x46,\n            0x470000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xe6e6e6e6, 0xe6e6e6e6, 0xe6e6e6e6,\n            0xe6e6e6e6, 0xe6e6e6e6, 0xdcdce8e6, 0xd8e8dcdc, 0xdcdcdcdc,\n            0xdccacadc, 0xcadcdcdc, 0xdcdcdcca, 0xdcdcdcdc, 0xdcdcdcdc,\n            0x1010101, 0xdcdcdc01, 0xe6e6e6dc, 0xe6e6e6e6, 0xdce6f0e6,\n            0xe6e6dcdc, 0xdcdce6, 0xdce6e6e6, 0xe6dcdcdc, 0xe6dcdce8,\n            0xe9eaeae9, 0xe6e9eaea, 0xe6e6e6e6, 0xe6e6e6e6, 0xe6e6e6e6, 0x0,\n            0x0, 0x0, 0x0, 0xe6000000, 0xe6e6e6e6, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xe6e6dc00, 0xe6dce6e6, 0xdcdee6e6, 0xe6e6e6e6, 0xdcdce6e6,\n            0xdcdcdcdc, 0xe6dce6e6, 0xe6e4dee6, 0xd0c0b0a, 0x11100f0e,\n            0x14131312, 0x17001615, 0x191800, 0x1200dce6, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xe6e6e6e6, 0xe6e6e6e6, 0x201f1e, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b000000, 0x1f1e1d1c, 0xe6222120,\n            0xe6dcdce6, 0xe6e6e6e6, 0xdce6e6dc, 0x0, 0x0, 0x0, 0x0, 0x23, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6e60000, 0xe6e6e6e6,\n            0xe60000e6, 0xdce6e6e6, 0xe60000e6, 0xe6dc00e6, 0xdce6, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2400, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xe6e6dce6, 0xdce6e6dc, 0xdce6dcdc, 0xe6dce6dc, 0xe6dce6e6,\n            0xe6dce6dc, 0xe6e6dc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xe6000000, 0xe6e6e6e6, 0xe6dce6e6, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xe6e60000, 0xe600e6e6, 0xe6e6e6e6, 0xe6e6e6e6,\n            0xe6e6e600, 0xe6e6e600, 0xe6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xdcdcdc00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6dce6e6,\n            0xe6e6dce6, 0xdcdcdce6, 0xe61d1c1b, 0xe6dce6e6, 0xe6dcdce6,\n            0xe6e6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x900, 0xe6dce600, 0xe6,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x900, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x900, 0x0, 0x5b5400, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x90000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x96767, 0x0,\n            0x0, 0x0, 0x6b6b6b6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x7676, 0x0, 0x0, 0x0, 0x7a7a7a7a, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xdcdc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xdc00dc00, 0xd800, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x828100, 0x84, 0x82820000, 0x8282, 0xe6e60082,\n            0xe6e60009, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xdc0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7000000, 0x90900, 0x0, 0x0,\n            0x0, 0x0, 0xdc00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6e6e600, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x90000, 0x0, 0x0, 0xe600, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe400,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdce6de00, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xe6000000, 0xdc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0,\n            0xe6e6e600, 0xe6e6e6e6, 0xdc0000e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x9, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6000000, 0xe6e6e6dc,\n            0xe6e6e6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x9090000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x70000, 0x0, 0x0, 0x9090000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x7000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6e6e6, 0xdcdcdc01,\n            0xe6e6dcdc, 0xdcdcdcdc, 0x10100e6, 0x1010101, 0x1, 0xdc00, 0x0,\n            0xe6, 0x0, 0x0, 0xe6dce6e6, 0xe6e6e6e6, 0xe6dce6e6, 0xdcd6eae6,\n            0xe6e6e6ca, 0xe6e6e6e6, 0xe6e6e6e6, 0xe6e6e6e6, 0xe6e6e6e6,\n            0xe6e6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdce6dce9, 0x0, 0x0, 0x0, 0x0,\n            0x101e6e6, 0xe6e6e6e6, 0xe6010101, 0xe6, 0xe600, 0xe6010100,\n            0x101e6dc, 0xdcdcdcdc, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6000000, 0xe6e6, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x9000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xe6e6e6e6, 0xe6e6e6e6, 0xe6e6e6e6, 0xe6e6e6e6, 0xe6e6e6e6,\n            0xe6e6e6e6, 0xe6e6e6e6, 0xe6e6e6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xe4da0000, 0xe0e0dee8, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80800, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xe6000000, 0x0, 0xe6e6e6e6, 0xe6e6e6e6, 0xe6e6, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6000000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xe6e6, 0x0, 0x0, 0x0, 0x0, 0x90000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xe6e6e6e6, 0xe6e6e6e6, 0xe6e6e6e6,\n            0xe6e6e6e6, 0xe6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xdc000000, 0xdcdc, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x9000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x7000000, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6e600e6,\n            0xe60000dc, 0xe6, 0xe6e60000, 0xe600, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x90000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x900, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a0000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xe6e6e6e6, 0xe6e6e6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdc00,\n            0x0, 0x0, 0x0, 0xe600dc00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xdc01e6, 0x9000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x70900, 0x0, 0xe6e6e6, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9000000, 0x9,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x7090000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x1d8d800, 0x101, 0xd8d8e200, 0xd8d8d8, 0x0, 0xdc000000,\n            0xdcdcdcdc, 0xdcdcdc, 0xe6e6e600, 0xdcdce6e6, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xe6e60000, 0xe6e6, 0x0, 0x0, 0x0, 0x0, 0xe6e60000,\n            0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0]);\n    enum composeIdxMask = (1 << 11) - 1, composeCntShift = 11;\n    enum compositionJumpTrieEntries = TrieEntry!(ushort, 12, 9)([0x0, 0x800],\n            [0x1000, 0x2000], [0x10000, 0x30002, 0x50004, 0x70006, 0x70008,\n            0x70007, 0x90007, 0xa0007, 0xc000b, 0x70007, 0x70007, 0x70007,\n            0x7000d, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x7000e, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x8010800,\n            0xffff0802, 0x8003ffff, 0x28161813, 0x8821301b, 0x38330832,\n            0x7841383a, 0x28510850, 0x185c3056, 0x8068485f, 0xffff1078,\n            0x3882407a, 0x98903889, 0x30a510a3, 0x48ad10ab, 0xffff30b6,\n            0xffffffff, 0xffffffff, 0x80bcffff, 0x28cf18cc, 0x88da30d4,\n            0x38ec08eb, 0x70fb40f3, 0x290b1109, 0x19163110, 0x81224919,\n            0xffff1132, 0x393c4134, 0x994b4143, 0x3960115e, 0x51691167,\n            0xffff3173, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffff1979, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffff217c, 0x9810980, 0x9841182, 0xffffffff,\n            0xffff2185, 0xffffffff, 0x989ffff, 0xffffffff, 0xffffffff,\n            0x198e218a, 0xffff0991, 0xffff0992, 0xffffffff, 0xffff2193,\n            0xffffffff, 0xffffffff, 0xffff2197, 0x99c099b, 0x99f119d,\n            0xffffffff, 0xffff21a0, 0xffffffff, 0x9a4ffff, 0xffffffff,\n            0xffffffff, 0x19a921a5, 0xffff09ac, 0xffff09ad, 0xffffffff,\n            0xffff21ae, 0xffffffff, 0xffffffff, 0x21b621b2, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0x11bc11ba, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0x11c011be, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0x9c309c2, 0xffffffff, 0xffffffff,\n            0x9c509c4, 0xffffffff, 0xffffffff, 0xffffffff, 0x9c709c6,\n            0x9c909c8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0x9caffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0x29d029cb, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x29d5ffff,\n            0xffff29da, 0xffffffff, 0xffffffff, 0x9dfffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x9e109e0,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x9e309e2,\n            0x9e509e4, 0xffffffff, 0xffffffff, 0x9e709e6, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffff09e8, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0x39e9ffff, 0xffffffff, 0x21f0ffff, 0x29f4ffff, 0x39f9ffff,\n            0xffffffff, 0xffffffff, 0x2200ffff, 0xa04ffff, 0xffffffff,\n            0x3205ffff, 0xffffffff, 0x2a0bffff, 0xffffffff, 0xffff0a10,\n            0xffff0a11, 0x4212ffff, 0xffffffff, 0x221affff, 0x321effff,\n            0x4224ffff, 0xffffffff, 0xffffffff, 0x222cffff, 0x1230ffff,\n            0xffffffff, 0x4232ffff, 0xffffffff, 0x323affff, 0x1a431a40,\n            0xffffffff, 0xffff0a46, 0xffffffff, 0xffff1247, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0a49,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff124a,\n            0xa4cffff, 0x1a4dffff, 0xa521250, 0xffff2253, 0xffff0a57,\n            0xffffffff, 0xffff0a58, 0xffffffff, 0x2259ffff, 0xffffffff,\n            0xa5dffff, 0xffffffff, 0xa5effff, 0xa5fffff, 0xffffffff,\n            0xffff1260, 0xa62ffff, 0x1a63ffff, 0xa681266, 0xffff2269,\n            0xffff0a6d, 0xffffffff, 0xffff0a6e, 0xffffffff, 0x226fffff,\n            0xffffffff, 0xa73ffff, 0xffffffff, 0xa74ffff, 0xa75ffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0a76,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xa780a77,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xa7a0a79,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xa7c0a7b, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0x1a7dffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffff0a80, 0xffff0a81,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xa82ffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffff0a83, 0xa84ffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffff0a85, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffff0a86, 0xa87ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0x1288ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0x1a8affff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffff0a8d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xa90128e, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffff0a91, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xa92ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff1a93,\n            0xffffffff, 0xffff0a96, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xa991297, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0x1a9affff, 0xffffffff, 0xffff0a9d, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xa9effff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xa9fffff, 0xaa0ffff,\n            0xaa1ffff, 0xaa2ffff, 0xaa3ffff, 0xffffffff, 0xaa4ffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0aa5,\n            0xffff0aa6, 0xaa80aa7, 0xffffffff, 0xffff0aa9, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xaab0aaa, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xaad0aac, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xaaf0aae, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0x12b212b0, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xab50ab4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xab70ab6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0x22bc22b8, 0xac10ac0, 0xac30ac2, 0xac50ac4,\n            0x22ca22c6, 0xacf0ace, 0xad10ad0, 0xad30ad2, 0x12d612d4,\n            0xffffffff, 0xffffffff, 0xffffffff, 0x12da12d8, 0xffffffff,\n            0xffffffff, 0xffffffff, 0x22e022dc, 0xae50ae4, 0xae70ae6,\n            0xae90ae8, 0x22ee22ea, 0xaf30af2, 0xaf50af4, 0xaf70af6, 0x1afb1af8,\n            0xffffffff, 0xffffffff, 0xffffffff, 0x1b011afe, 0xffffffff,\n            0xffffffff, 0xffffffff, 0x13061304, 0xffffffff, 0xffffffff,\n            0xffffffff, 0x130a1308, 0xffffffff, 0xffffffff, 0xffffffff,\n            0x1b0f1b0c, 0xffffffff, 0xffffffff, 0xffffffff, 0x1b12ffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0x23192315, 0xb1e0b1d,\n            0xb200b1f, 0xb220b21, 0x23272323, 0xb2c0b2b, 0xb2e0b2d, 0xb300b2f,\n            0xffff0b31, 0xffffffff, 0xffff0b32, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffff0b33, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffff0b34, 0xffffffff, 0xffffffff, 0xffffffff, 0x1b35ffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffff0b38, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffff0b39, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffff1b3a, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffff0b3d, 0xffff0b3e, 0xffff0b3f,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0b40,\n            0xffff0b41, 0xffff0b42, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xb43ffff,\n            0xffffffff, 0xffffffff, 0xffff0b44, 0xb45ffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xb46ffff, 0xb47ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffff0b48, 0xffffffff,\n            0xffffffff, 0xb49ffff, 0xb4affff, 0xffffffff, 0xffff0b4b,\n            0xffffffff, 0xb4cffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xb4dffff, 0xffffffff, 0xb4f0b4e, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xb510b50, 0xffffffff, 0xb530b52, 0xffffffff, 0xb550b54, 0xb570b56,\n            0xffffffff, 0xffffffff, 0xb590b58, 0xffffffff, 0xb5b0b5a,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xb5cffff,\n            0xffff0b5d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffff0b5e, 0xffffffff,\n            0xffffffff, 0xb600b5f, 0xb61ffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xb630b62, 0xb650b64, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffff0b66, 0xffffffff,\n            0xb67ffff, 0xb68ffff, 0xb69ffff, 0xb6affff, 0xb6bffff, 0xb6cffff,\n            0xb6dffff, 0xb6effff, 0xb6fffff, 0xb70ffff, 0xb71ffff, 0xb72ffff,\n            0xffffffff, 0xffff0b73, 0xffff0b74, 0xffff0b75, 0xffffffff,\n            0xffffffff, 0x1376ffff, 0xffffffff, 0xffff1378, 0x137affff,\n            0xffffffff, 0xffff137c, 0x137effff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xb80ffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0b81,\n            0xffffffff, 0xb82ffff, 0xb83ffff, 0xb84ffff, 0xb85ffff, 0xb86ffff,\n            0xb87ffff, 0xb88ffff, 0xb89ffff, 0xb8affff, 0xb8bffff, 0xb8cffff,\n            0xb8dffff, 0xffffffff, 0xffff0b8e, 0xffff0b8f, 0xffff0b90,\n            0xffffffff, 0xffffffff, 0x1391ffff, 0xffffffff, 0xffff1393,\n            0x1395ffff, 0xffffffff, 0xffff1397, 0x1399ffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xb9bffff, 0xb9d0b9c,\n            0xffff0b9e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xb9fffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xba0ffff, 0xba1ffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xba2ffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xba3ffff, 0xffff0ba4, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff]);\n    @property immutable(CompEntry[]) compositionTable()\n    {\n        alias CE = CompEntry;\n        static immutable CE[] t = [\n            CE(0x00338, 0x0226e), CE(0x00338, 0x02260), CE(0x00338, 0x0226f),\n            CE(0x00300, 0x000c0), CE(0x00301, 0x000c1), CE(0x00302, 0x000c2),\n            CE(0x00303, 0x000c3), CE(0x00304, 0x00100), CE(0x00306, 0x00102),\n            CE(0x00307, 0x00226), CE(0x00308, 0x000c4), CE(0x00309, 0x01ea2),\n            CE(0x0030a, 0x000c5), CE(0x0030c, 0x001cd), CE(0x0030f, 0x00200),\n            CE(0x00311, 0x00202), CE(0x00323, 0x01ea0), CE(0x00325, 0x01e00),\n            CE(0x00328, 0x00104), CE(0x00307, 0x01e02), CE(0x00323, 0x01e04),\n            CE(0x00331, 0x01e06), CE(0x00301, 0x00106), CE(0x00302, 0x00108),\n            CE(0x00307, 0x0010a), CE(0x0030c, 0x0010c), CE(0x00327, 0x000c7),\n            CE(0x00307, 0x01e0a), CE(0x0030c, 0x0010e), CE(0x00323, 0x01e0c),\n            CE(0x00327, 0x01e10), CE(0x0032d, 0x01e12), CE(0x00331, 0x01e0e),\n            CE(0x00300, 0x000c8), CE(0x00301, 0x000c9), CE(0x00302, 0x000ca),\n            CE(0x00303, 0x01ebc), CE(0x00304, 0x00112), CE(0x00306, 0x00114),\n            CE(0x00307, 0x00116), CE(0x00308, 0x000cb), CE(0x00309, 0x01eba),\n            CE(0x0030c, 0x0011a), CE(0x0030f, 0x00204), CE(0x00311, 0x00206),\n            CE(0x00323, 0x01eb8), CE(0x00327, 0x00228), CE(0x00328, 0x00118),\n            CE(0x0032d, 0x01e18), CE(0x00330, 0x01e1a), CE(0x00307, 0x01e1e),\n            CE(0x00301, 0x001f4), CE(0x00302, 0x0011c), CE(0x00304, 0x01e20),\n            CE(0x00306, 0x0011e), CE(0x00307, 0x00120), CE(0x0030c, 0x001e6),\n            CE(0x00327, 0x00122), CE(0x00302, 0x00124), CE(0x00307, 0x01e22),\n            CE(0x00308, 0x01e26), CE(0x0030c, 0x0021e), CE(0x00323, 0x01e24),\n            CE(0x00327, 0x01e28), CE(0x0032e, 0x01e2a), CE(0x00300, 0x000cc),\n            CE(0x00301, 0x000cd), CE(0x00302, 0x000ce), CE(0x00303, 0x00128),\n            CE(0x00304, 0x0012a), CE(0x00306, 0x0012c), CE(0x00307, 0x00130),\n            CE(0x00308, 0x000cf), CE(0x00309, 0x01ec8), CE(0x0030c, 0x001cf),\n            CE(0x0030f, 0x00208), CE(0x00311, 0x0020a), CE(0x00323, 0x01eca),\n            CE(0x00328, 0x0012e), CE(0x00330, 0x01e2c), CE(0x00302, 0x00134),\n            CE(0x00301, 0x01e30), CE(0x0030c, 0x001e8), CE(0x00323, 0x01e32),\n            CE(0x00327, 0x00136), CE(0x00331, 0x01e34), CE(0x00301, 0x00139),\n            CE(0x0030c, 0x0013d), CE(0x00323, 0x01e36), CE(0x00327, 0x0013b),\n            CE(0x0032d, 0x01e3c), CE(0x00331, 0x01e3a), CE(0x00301, 0x01e3e),\n            CE(0x00307, 0x01e40), CE(0x00323, 0x01e42), CE(0x00300, 0x001f8),\n            CE(0x00301, 0x00143), CE(0x00303, 0x000d1), CE(0x00307, 0x01e44),\n            CE(0x0030c, 0x00147), CE(0x00323, 0x01e46), CE(0x00327, 0x00145),\n            CE(0x0032d, 0x01e4a), CE(0x00331, 0x01e48), CE(0x00300, 0x000d2),\n            CE(0x00301, 0x000d3), CE(0x00302, 0x000d4), CE(0x00303, 0x000d5),\n            CE(0x00304, 0x0014c), CE(0x00306, 0x0014e), CE(0x00307, 0x0022e),\n            CE(0x00308, 0x000d6), CE(0x00309, 0x01ece), CE(0x0030b, 0x00150),\n            CE(0x0030c, 0x001d1), CE(0x0030f, 0x0020c), CE(0x00311, 0x0020e),\n            CE(0x0031b, 0x001a0), CE(0x00323, 0x01ecc), CE(0x00328, 0x001ea),\n            CE(0x00301, 0x01e54), CE(0x00307, 0x01e56), CE(0x00301, 0x00154),\n            CE(0x00307, 0x01e58), CE(0x0030c, 0x00158), CE(0x0030f, 0x00210),\n            CE(0x00311, 0x00212), CE(0x00323, 0x01e5a), CE(0x00327, 0x00156),\n            CE(0x00331, 0x01e5e), CE(0x00301, 0x0015a), CE(0x00302, 0x0015c),\n            CE(0x00307, 0x01e60), CE(0x0030c, 0x00160), CE(0x00323, 0x01e62),\n            CE(0x00326, 0x00218), CE(0x00327, 0x0015e), CE(0x00307, 0x01e6a),\n            CE(0x0030c, 0x00164), CE(0x00323, 0x01e6c), CE(0x00326, 0x0021a),\n            CE(0x00327, 0x00162), CE(0x0032d, 0x01e70), CE(0x00331, 0x01e6e),\n            CE(0x00300, 0x000d9), CE(0x00301, 0x000da), CE(0x00302, 0x000db),\n            CE(0x00303, 0x00168), CE(0x00304, 0x0016a), CE(0x00306, 0x0016c),\n            CE(0x00308, 0x000dc), CE(0x00309, 0x01ee6), CE(0x0030a, 0x0016e),\n            CE(0x0030b, 0x00170), CE(0x0030c, 0x001d3), CE(0x0030f, 0x00214),\n            CE(0x00311, 0x00216), CE(0x0031b, 0x001af), CE(0x00323, 0x01ee4),\n            CE(0x00324, 0x01e72), CE(0x00328, 0x00172), CE(0x0032d, 0x01e76),\n            CE(0x00330, 0x01e74), CE(0x00303, 0x01e7c), CE(0x00323, 0x01e7e),\n            CE(0x00300, 0x01e80), CE(0x00301, 0x01e82), CE(0x00302, 0x00174),\n            CE(0x00307, 0x01e86), CE(0x00308, 0x01e84), CE(0x00323, 0x01e88),\n            CE(0x00307, 0x01e8a), CE(0x00308, 0x01e8c), CE(0x00300, 0x01ef2),\n            CE(0x00301, 0x000dd), CE(0x00302, 0x00176), CE(0x00303, 0x01ef8),\n            CE(0x00304, 0x00232), CE(0x00307, 0x01e8e), CE(0x00308, 0x00178),\n            CE(0x00309, 0x01ef6), CE(0x00323, 0x01ef4), CE(0x00301, 0x00179),\n            CE(0x00302, 0x01e90), CE(0x00307, 0x0017b), CE(0x0030c, 0x0017d),\n            CE(0x00323, 0x01e92), CE(0x00331, 0x01e94), CE(0x00300, 0x000e0),\n            CE(0x00301, 0x000e1), CE(0x00302, 0x000e2), CE(0x00303, 0x000e3),\n            CE(0x00304, 0x00101), CE(0x00306, 0x00103), CE(0x00307, 0x00227),\n            CE(0x00308, 0x000e4), CE(0x00309, 0x01ea3), CE(0x0030a, 0x000e5),\n            CE(0x0030c, 0x001ce), CE(0x0030f, 0x00201), CE(0x00311, 0x00203),\n            CE(0x00323, 0x01ea1), CE(0x00325, 0x01e01), CE(0x00328, 0x00105),\n            CE(0x00307, 0x01e03), CE(0x00323, 0x01e05), CE(0x00331, 0x01e07),\n            CE(0x00301, 0x00107), CE(0x00302, 0x00109), CE(0x00307, 0x0010b),\n            CE(0x0030c, 0x0010d), CE(0x00327, 0x000e7), CE(0x00307, 0x01e0b),\n            CE(0x0030c, 0x0010f), CE(0x00323, 0x01e0d), CE(0x00327, 0x01e11),\n            CE(0x0032d, 0x01e13), CE(0x00331, 0x01e0f), CE(0x00300, 0x000e8),\n            CE(0x00301, 0x000e9), CE(0x00302, 0x000ea), CE(0x00303, 0x01ebd),\n            CE(0x00304, 0x00113), CE(0x00306, 0x00115), CE(0x00307, 0x00117),\n            CE(0x00308, 0x000eb), CE(0x00309, 0x01ebb), CE(0x0030c, 0x0011b),\n            CE(0x0030f, 0x00205), CE(0x00311, 0x00207), CE(0x00323, 0x01eb9),\n            CE(0x00327, 0x00229), CE(0x00328, 0x00119), CE(0x0032d, 0x01e19),\n            CE(0x00330, 0x01e1b), CE(0x00307, 0x01e1f), CE(0x00301, 0x001f5),\n            CE(0x00302, 0x0011d), CE(0x00304, 0x01e21), CE(0x00306, 0x0011f),\n            CE(0x00307, 0x00121), CE(0x0030c, 0x001e7), CE(0x00327, 0x00123),\n            CE(0x00302, 0x00125), CE(0x00307, 0x01e23), CE(0x00308, 0x01e27),\n            CE(0x0030c, 0x0021f), CE(0x00323, 0x01e25), CE(0x00327, 0x01e29),\n            CE(0x0032e, 0x01e2b), CE(0x00331, 0x01e96), CE(0x00300, 0x000ec),\n            CE(0x00301, 0x000ed), CE(0x00302, 0x000ee), CE(0x00303, 0x00129),\n            CE(0x00304, 0x0012b), CE(0x00306, 0x0012d), CE(0x00308, 0x000ef),\n            CE(0x00309, 0x01ec9), CE(0x0030c, 0x001d0), CE(0x0030f, 0x00209),\n            CE(0x00311, 0x0020b), CE(0x00323, 0x01ecb), CE(0x00328, 0x0012f),\n            CE(0x00330, 0x01e2d), CE(0x00302, 0x00135), CE(0x0030c, 0x001f0),\n            CE(0x00301, 0x01e31), CE(0x0030c, 0x001e9), CE(0x00323, 0x01e33),\n            CE(0x00327, 0x00137), CE(0x00331, 0x01e35), CE(0x00301, 0x0013a),\n            CE(0x0030c, 0x0013e), CE(0x00323, 0x01e37), CE(0x00327, 0x0013c),\n            CE(0x0032d, 0x01e3d), CE(0x00331, 0x01e3b), CE(0x00301, 0x01e3f),\n            CE(0x00307, 0x01e41), CE(0x00323, 0x01e43), CE(0x00300, 0x001f9),\n            CE(0x00301, 0x00144), CE(0x00303, 0x000f1), CE(0x00307, 0x01e45),\n            CE(0x0030c, 0x00148), CE(0x00323, 0x01e47), CE(0x00327, 0x00146),\n            CE(0x0032d, 0x01e4b), CE(0x00331, 0x01e49), CE(0x00300, 0x000f2),\n            CE(0x00301, 0x000f3), CE(0x00302, 0x000f4), CE(0x00303, 0x000f5),\n            CE(0x00304, 0x0014d), CE(0x00306, 0x0014f), CE(0x00307, 0x0022f),\n            CE(0x00308, 0x000f6), CE(0x00309, 0x01ecf), CE(0x0030b, 0x00151),\n            CE(0x0030c, 0x001d2), CE(0x0030f, 0x0020d), CE(0x00311, 0x0020f),\n            CE(0x0031b, 0x001a1), CE(0x00323, 0x01ecd), CE(0x00328, 0x001eb),\n            CE(0x00301, 0x01e55), CE(0x00307, 0x01e57), CE(0x00301, 0x00155),\n            CE(0x00307, 0x01e59), CE(0x0030c, 0x00159), CE(0x0030f, 0x00211),\n            CE(0x00311, 0x00213), CE(0x00323, 0x01e5b), CE(0x00327, 0x00157),\n            CE(0x00331, 0x01e5f), CE(0x00301, 0x0015b), CE(0x00302, 0x0015d),\n            CE(0x00307, 0x01e61), CE(0x0030c, 0x00161), CE(0x00323, 0x01e63),\n            CE(0x00326, 0x00219), CE(0x00327, 0x0015f), CE(0x00307, 0x01e6b),\n            CE(0x00308, 0x01e97), CE(0x0030c, 0x00165), CE(0x00323, 0x01e6d),\n            CE(0x00326, 0x0021b), CE(0x00327, 0x00163), CE(0x0032d, 0x01e71),\n            CE(0x00331, 0x01e6f), CE(0x00300, 0x000f9), CE(0x00301, 0x000fa),\n            CE(0x00302, 0x000fb), CE(0x00303, 0x00169), CE(0x00304, 0x0016b),\n            CE(0x00306, 0x0016d), CE(0x00308, 0x000fc), CE(0x00309, 0x01ee7),\n            CE(0x0030a, 0x0016f), CE(0x0030b, 0x00171), CE(0x0030c, 0x001d4),\n            CE(0x0030f, 0x00215), CE(0x00311, 0x00217), CE(0x0031b, 0x001b0),\n            CE(0x00323, 0x01ee5), CE(0x00324, 0x01e73), CE(0x00328, 0x00173),\n            CE(0x0032d, 0x01e77), CE(0x00330, 0x01e75), CE(0x00303, 0x01e7d),\n            CE(0x00323, 0x01e7f), CE(0x00300, 0x01e81), CE(0x00301, 0x01e83),\n            CE(0x00302, 0x00175), CE(0x00307, 0x01e87), CE(0x00308, 0x01e85),\n            CE(0x0030a, 0x01e98), CE(0x00323, 0x01e89), CE(0x00307, 0x01e8b),\n            CE(0x00308, 0x01e8d), CE(0x00300, 0x01ef3), CE(0x00301, 0x000fd),\n            CE(0x00302, 0x00177), CE(0x00303, 0x01ef9), CE(0x00304, 0x00233),\n            CE(0x00307, 0x01e8f), CE(0x00308, 0x000ff), CE(0x00309, 0x01ef7),\n            CE(0x0030a, 0x01e99), CE(0x00323, 0x01ef5), CE(0x00301, 0x0017a),\n            CE(0x00302, 0x01e91), CE(0x00307, 0x0017c), CE(0x0030c, 0x0017e),\n            CE(0x00323, 0x01e93), CE(0x00331, 0x01e95), CE(0x00300, 0x01fed),\n            CE(0x00301, 0x00385), CE(0x00342, 0x01fc1), CE(0x00300, 0x01ea6),\n            CE(0x00301, 0x01ea4), CE(0x00303, 0x01eaa), CE(0x00309, 0x01ea8),\n            CE(0x00304, 0x001de), CE(0x00301, 0x001fa), CE(0x00301, 0x001fc),\n            CE(0x00304, 0x001e2), CE(0x00301, 0x01e08), CE(0x00300, 0x01ec0),\n            CE(0x00301, 0x01ebe), CE(0x00303, 0x01ec4), CE(0x00309, 0x01ec2),\n            CE(0x00301, 0x01e2e), CE(0x00300, 0x01ed2), CE(0x00301, 0x01ed0),\n            CE(0x00303, 0x01ed6), CE(0x00309, 0x01ed4), CE(0x00301, 0x01e4c),\n            CE(0x00304, 0x0022c), CE(0x00308, 0x01e4e), CE(0x00304, 0x0022a),\n            CE(0x00301, 0x001fe), CE(0x00300, 0x001db), CE(0x00301, 0x001d7),\n            CE(0x00304, 0x001d5), CE(0x0030c, 0x001d9), CE(0x00300, 0x01ea7),\n            CE(0x00301, 0x01ea5), CE(0x00303, 0x01eab), CE(0x00309, 0x01ea9),\n            CE(0x00304, 0x001df), CE(0x00301, 0x001fb), CE(0x00301, 0x001fd),\n            CE(0x00304, 0x001e3), CE(0x00301, 0x01e09), CE(0x00300, 0x01ec1),\n            CE(0x00301, 0x01ebf), CE(0x00303, 0x01ec5), CE(0x00309, 0x01ec3),\n            CE(0x00301, 0x01e2f), CE(0x00300, 0x01ed3), CE(0x00301, 0x01ed1),\n            CE(0x00303, 0x01ed7), CE(0x00309, 0x01ed5), CE(0x00301, 0x01e4d),\n            CE(0x00304, 0x0022d), CE(0x00308, 0x01e4f), CE(0x00304, 0x0022b),\n            CE(0x00301, 0x001ff), CE(0x00300, 0x001dc), CE(0x00301, 0x001d8),\n            CE(0x00304, 0x001d6), CE(0x0030c, 0x001da), CE(0x00300, 0x01eb0),\n            CE(0x00301, 0x01eae), CE(0x00303, 0x01eb4), CE(0x00309, 0x01eb2),\n            CE(0x00300, 0x01eb1), CE(0x00301, 0x01eaf), CE(0x00303, 0x01eb5),\n            CE(0x00309, 0x01eb3), CE(0x00300, 0x01e14), CE(0x00301, 0x01e16),\n            CE(0x00300, 0x01e15), CE(0x00301, 0x01e17), CE(0x00300, 0x01e50),\n            CE(0x00301, 0x01e52), CE(0x00300, 0x01e51), CE(0x00301, 0x01e53),\n            CE(0x00307, 0x01e64), CE(0x00307, 0x01e65), CE(0x00307, 0x01e66),\n            CE(0x00307, 0x01e67), CE(0x00301, 0x01e78), CE(0x00301, 0x01e79),\n            CE(0x00308, 0x01e7a), CE(0x00308, 0x01e7b), CE(0x00307, 0x01e9b),\n            CE(0x00300, 0x01edc), CE(0x00301, 0x01eda), CE(0x00303, 0x01ee0),\n            CE(0x00309, 0x01ede), CE(0x00323, 0x01ee2), CE(0x00300, 0x01edd),\n            CE(0x00301, 0x01edb), CE(0x00303, 0x01ee1), CE(0x00309, 0x01edf),\n            CE(0x00323, 0x01ee3), CE(0x00300, 0x01eea), CE(0x00301, 0x01ee8),\n            CE(0x00303, 0x01eee), CE(0x00309, 0x01eec), CE(0x00323, 0x01ef0),\n            CE(0x00300, 0x01eeb), CE(0x00301, 0x01ee9), CE(0x00303, 0x01eef),\n            CE(0x00309, 0x01eed), CE(0x00323, 0x01ef1), CE(0x0030c, 0x001ee),\n            CE(0x00304, 0x001ec), CE(0x00304, 0x001ed), CE(0x00304, 0x001e0),\n            CE(0x00304, 0x001e1), CE(0x00306, 0x01e1c), CE(0x00306, 0x01e1d),\n            CE(0x00304, 0x00230), CE(0x00304, 0x00231), CE(0x0030c, 0x001ef),\n            CE(0x00300, 0x01fba), CE(0x00301, 0x00386), CE(0x00304, 0x01fb9),\n            CE(0x00306, 0x01fb8), CE(0x00313, 0x01f08), CE(0x00314, 0x01f09),\n            CE(0x00345, 0x01fbc), CE(0x00300, 0x01fc8), CE(0x00301, 0x00388),\n            CE(0x00313, 0x01f18), CE(0x00314, 0x01f19), CE(0x00300, 0x01fca),\n            CE(0x00301, 0x00389), CE(0x00313, 0x01f28), CE(0x00314, 0x01f29),\n            CE(0x00345, 0x01fcc), CE(0x00300, 0x01fda), CE(0x00301, 0x0038a),\n            CE(0x00304, 0x01fd9), CE(0x00306, 0x01fd8), CE(0x00308, 0x003aa),\n            CE(0x00313, 0x01f38), CE(0x00314, 0x01f39), CE(0x00300, 0x01ff8),\n            CE(0x00301, 0x0038c), CE(0x00313, 0x01f48), CE(0x00314, 0x01f49),\n            CE(0x00314, 0x01fec), CE(0x00300, 0x01fea), CE(0x00301, 0x0038e),\n            CE(0x00304, 0x01fe9), CE(0x00306, 0x01fe8), CE(0x00308, 0x003ab),\n            CE(0x00314, 0x01f59), CE(0x00300, 0x01ffa), CE(0x00301, 0x0038f),\n            CE(0x00313, 0x01f68), CE(0x00314, 0x01f69), CE(0x00345, 0x01ffc),\n            CE(0x00345, 0x01fb4), CE(0x00345, 0x01fc4), CE(0x00300, 0x01f70),\n            CE(0x00301, 0x003ac), CE(0x00304, 0x01fb1), CE(0x00306, 0x01fb0),\n            CE(0x00313, 0x01f00), CE(0x00314, 0x01f01), CE(0x00342, 0x01fb6),\n            CE(0x00345, 0x01fb3), CE(0x00300, 0x01f72), CE(0x00301, 0x003ad),\n            CE(0x00313, 0x01f10), CE(0x00314, 0x01f11), CE(0x00300, 0x01f74),\n            CE(0x00301, 0x003ae), CE(0x00313, 0x01f20), CE(0x00314, 0x01f21),\n            CE(0x00342, 0x01fc6), CE(0x00345, 0x01fc3), CE(0x00300, 0x01f76),\n            CE(0x00301, 0x003af), CE(0x00304, 0x01fd1), CE(0x00306, 0x01fd0),\n            CE(0x00308, 0x003ca), CE(0x00313, 0x01f30), CE(0x00314, 0x01f31),\n            CE(0x00342, 0x01fd6), CE(0x00300, 0x01f78), CE(0x00301, 0x003cc),\n            CE(0x00313, 0x01f40), CE(0x00314, 0x01f41), CE(0x00313, 0x01fe4),\n            CE(0x00314, 0x01fe5), CE(0x00300, 0x01f7a), CE(0x00301, 0x003cd),\n            CE(0x00304, 0x01fe1), CE(0x00306, 0x01fe0), CE(0x00308, 0x003cb),\n            CE(0x00313, 0x01f50), CE(0x00314, 0x01f51), CE(0x00342, 0x01fe6),\n            CE(0x00300, 0x01f7c), CE(0x00301, 0x003ce), CE(0x00313, 0x01f60),\n            CE(0x00314, 0x01f61), CE(0x00342, 0x01ff6), CE(0x00345, 0x01ff3),\n            CE(0x00300, 0x01fd2), CE(0x00301, 0x00390), CE(0x00342, 0x01fd7),\n            CE(0x00300, 0x01fe2), CE(0x00301, 0x003b0), CE(0x00342, 0x01fe7),\n            CE(0x00345, 0x01ff4), CE(0x00301, 0x003d3), CE(0x00308, 0x003d4),\n            CE(0x00308, 0x00407), CE(0x00306, 0x004d0), CE(0x00308, 0x004d2),\n            CE(0x00301, 0x00403), CE(0x00300, 0x00400), CE(0x00306, 0x004d6),\n            CE(0x00308, 0x00401), CE(0x00306, 0x004c1), CE(0x00308, 0x004dc),\n            CE(0x00308, 0x004de), CE(0x00300, 0x0040d), CE(0x00304, 0x004e2),\n            CE(0x00306, 0x00419), CE(0x00308, 0x004e4), CE(0x00301, 0x0040c),\n            CE(0x00308, 0x004e6), CE(0x00304, 0x004ee), CE(0x00306, 0x0040e),\n            CE(0x00308, 0x004f0), CE(0x0030b, 0x004f2), CE(0x00308, 0x004f4),\n            CE(0x00308, 0x004f8), CE(0x00308, 0x004ec), CE(0x00306, 0x004d1),\n            CE(0x00308, 0x004d3), CE(0x00301, 0x00453), CE(0x00300, 0x00450),\n            CE(0x00306, 0x004d7), CE(0x00308, 0x00451), CE(0x00306, 0x004c2),\n            CE(0x00308, 0x004dd), CE(0x00308, 0x004df), CE(0x00300, 0x0045d),\n            CE(0x00304, 0x004e3), CE(0x00306, 0x00439), CE(0x00308, 0x004e5),\n            CE(0x00301, 0x0045c), CE(0x00308, 0x004e7), CE(0x00304, 0x004ef),\n            CE(0x00306, 0x0045e), CE(0x00308, 0x004f1), CE(0x0030b, 0x004f3),\n            CE(0x00308, 0x004f5), CE(0x00308, 0x004f9), CE(0x00308, 0x004ed),\n            CE(0x00308, 0x00457), CE(0x0030f, 0x00476), CE(0x0030f, 0x00477),\n            CE(0x00308, 0x004da), CE(0x00308, 0x004db), CE(0x00308, 0x004ea),\n            CE(0x00308, 0x004eb), CE(0x00653, 0x00622), CE(0x00654, 0x00623),\n            CE(0x00655, 0x00625), CE(0x00654, 0x00624), CE(0x00654, 0x00626),\n            CE(0x00654, 0x006c2), CE(0x00654, 0x006d3), CE(0x00654, 0x006c0),\n            CE(0x0093c, 0x00929), CE(0x0093c, 0x00931), CE(0x0093c, 0x00934),\n            CE(0x009be, 0x009cb), CE(0x009d7, 0x009cc), CE(0x00b3e, 0x00b4b),\n            CE(0x00b56, 0x00b48), CE(0x00b57, 0x00b4c), CE(0x00bd7, 0x00b94),\n            CE(0x00bbe, 0x00bca), CE(0x00bd7, 0x00bcc), CE(0x00bbe, 0x00bcb),\n            CE(0x00c56, 0x00c48), CE(0x00cd5, 0x00cc0), CE(0x00cc2, 0x00cca),\n            CE(0x00cd5, 0x00cc7), CE(0x00cd6, 0x00cc8), CE(0x00cd5, 0x00ccb),\n            CE(0x00d3e, 0x00d4a), CE(0x00d57, 0x00d4c), CE(0x00d3e, 0x00d4b),\n            CE(0x00dca, 0x00dda), CE(0x00dcf, 0x00ddc), CE(0x00ddf, 0x00dde),\n            CE(0x00dca, 0x00ddd), CE(0x0102e, 0x01026), CE(0x01b35, 0x01b06),\n            CE(0x01b35, 0x01b08), CE(0x01b35, 0x01b0a), CE(0x01b35, 0x01b0c),\n            CE(0x01b35, 0x01b0e), CE(0x01b35, 0x01b12), CE(0x01b35, 0x01b3b),\n            CE(0x01b35, 0x01b3d), CE(0x01b35, 0x01b40), CE(0x01b35, 0x01b41),\n            CE(0x01b35, 0x01b43), CE(0x00304, 0x01e38), CE(0x00304, 0x01e39),\n            CE(0x00304, 0x01e5c), CE(0x00304, 0x01e5d), CE(0x00307, 0x01e68),\n            CE(0x00307, 0x01e69), CE(0x00302, 0x01eac), CE(0x00306, 0x01eb6),\n            CE(0x00302, 0x01ead), CE(0x00306, 0x01eb7), CE(0x00302, 0x01ec6),\n            CE(0x00302, 0x01ec7), CE(0x00302, 0x01ed8), CE(0x00302, 0x01ed9),\n            CE(0x00300, 0x01f02), CE(0x00301, 0x01f04), CE(0x00342, 0x01f06),\n            CE(0x00345, 0x01f80), CE(0x00300, 0x01f03), CE(0x00301, 0x01f05),\n            CE(0x00342, 0x01f07), CE(0x00345, 0x01f81), CE(0x00345, 0x01f82),\n            CE(0x00345, 0x01f83), CE(0x00345, 0x01f84), CE(0x00345, 0x01f85),\n            CE(0x00345, 0x01f86), CE(0x00345, 0x01f87), CE(0x00300, 0x01f0a),\n            CE(0x00301, 0x01f0c), CE(0x00342, 0x01f0e), CE(0x00345, 0x01f88),\n            CE(0x00300, 0x01f0b), CE(0x00301, 0x01f0d), CE(0x00342, 0x01f0f),\n            CE(0x00345, 0x01f89), CE(0x00345, 0x01f8a), CE(0x00345, 0x01f8b),\n            CE(0x00345, 0x01f8c), CE(0x00345, 0x01f8d), CE(0x00345, 0x01f8e),\n            CE(0x00345, 0x01f8f), CE(0x00300, 0x01f12), CE(0x00301, 0x01f14),\n            CE(0x00300, 0x01f13), CE(0x00301, 0x01f15), CE(0x00300, 0x01f1a),\n            CE(0x00301, 0x01f1c), CE(0x00300, 0x01f1b), CE(0x00301, 0x01f1d),\n            CE(0x00300, 0x01f22), CE(0x00301, 0x01f24), CE(0x00342, 0x01f26),\n            CE(0x00345, 0x01f90), CE(0x00300, 0x01f23), CE(0x00301, 0x01f25),\n            CE(0x00342, 0x01f27), CE(0x00345, 0x01f91), CE(0x00345, 0x01f92),\n            CE(0x00345, 0x01f93), CE(0x00345, 0x01f94), CE(0x00345, 0x01f95),\n            CE(0x00345, 0x01f96), CE(0x00345, 0x01f97), CE(0x00300, 0x01f2a),\n            CE(0x00301, 0x01f2c), CE(0x00342, 0x01f2e), CE(0x00345, 0x01f98),\n            CE(0x00300, 0x01f2b), CE(0x00301, 0x01f2d), CE(0x00342, 0x01f2f),\n            CE(0x00345, 0x01f99), CE(0x00345, 0x01f9a), CE(0x00345, 0x01f9b),\n            CE(0x00345, 0x01f9c), CE(0x00345, 0x01f9d), CE(0x00345, 0x01f9e),\n            CE(0x00345, 0x01f9f), CE(0x00300, 0x01f32), CE(0x00301, 0x01f34),\n            CE(0x00342, 0x01f36), CE(0x00300, 0x01f33), CE(0x00301, 0x01f35),\n            CE(0x00342, 0x01f37), CE(0x00300, 0x01f3a), CE(0x00301, 0x01f3c),\n            CE(0x00342, 0x01f3e), CE(0x00300, 0x01f3b), CE(0x00301, 0x01f3d),\n            CE(0x00342, 0x01f3f), CE(0x00300, 0x01f42), CE(0x00301, 0x01f44),\n            CE(0x00300, 0x01f43), CE(0x00301, 0x01f45), CE(0x00300, 0x01f4a),\n            CE(0x00301, 0x01f4c), CE(0x00300, 0x01f4b), CE(0x00301, 0x01f4d),\n            CE(0x00300, 0x01f52), CE(0x00301, 0x01f54), CE(0x00342, 0x01f56),\n            CE(0x00300, 0x01f53), CE(0x00301, 0x01f55), CE(0x00342, 0x01f57),\n            CE(0x00300, 0x01f5b), CE(0x00301, 0x01f5d), CE(0x00342, 0x01f5f),\n            CE(0x00300, 0x01f62), CE(0x00301, 0x01f64), CE(0x00342, 0x01f66),\n            CE(0x00345, 0x01fa0), CE(0x00300, 0x01f63), CE(0x00301, 0x01f65),\n            CE(0x00342, 0x01f67), CE(0x00345, 0x01fa1), CE(0x00345, 0x01fa2),\n            CE(0x00345, 0x01fa3), CE(0x00345, 0x01fa4), CE(0x00345, 0x01fa5),\n            CE(0x00345, 0x01fa6), CE(0x00345, 0x01fa7), CE(0x00300, 0x01f6a),\n            CE(0x00301, 0x01f6c), CE(0x00342, 0x01f6e), CE(0x00345, 0x01fa8),\n            CE(0x00300, 0x01f6b), CE(0x00301, 0x01f6d), CE(0x00342, 0x01f6f),\n            CE(0x00345, 0x01fa9), CE(0x00345, 0x01faa), CE(0x00345, 0x01fab),\n            CE(0x00345, 0x01fac), CE(0x00345, 0x01fad), CE(0x00345, 0x01fae),\n            CE(0x00345, 0x01faf), CE(0x00345, 0x01fb2), CE(0x00345, 0x01fc2),\n            CE(0x00345, 0x01ff2), CE(0x00345, 0x01fb7), CE(0x00300, 0x01fcd),\n            CE(0x00301, 0x01fce), CE(0x00342, 0x01fcf), CE(0x00345, 0x01fc7),\n            CE(0x00345, 0x01ff7), CE(0x00300, 0x01fdd), CE(0x00301, 0x01fde),\n            CE(0x00342, 0x01fdf), CE(0x00338, 0x0219a), CE(0x00338, 0x0219b),\n            CE(0x00338, 0x021ae), CE(0x00338, 0x021cd), CE(0x00338, 0x021cf),\n            CE(0x00338, 0x021ce), CE(0x00338, 0x02204), CE(0x00338, 0x02209),\n            CE(0x00338, 0x0220c), CE(0x00338, 0x02224), CE(0x00338, 0x02226),\n            CE(0x00338, 0x02241), CE(0x00338, 0x02244), CE(0x00338, 0x02247),\n            CE(0x00338, 0x02249), CE(0x00338, 0x0226d), CE(0x00338, 0x02262),\n            CE(0x00338, 0x02270), CE(0x00338, 0x02271), CE(0x00338, 0x02274),\n            CE(0x00338, 0x02275), CE(0x00338, 0x02278), CE(0x00338, 0x02279),\n            CE(0x00338, 0x02280), CE(0x00338, 0x02281), CE(0x00338, 0x022e0),\n            CE(0x00338, 0x022e1), CE(0x00338, 0x02284), CE(0x00338, 0x02285),\n            CE(0x00338, 0x02288), CE(0x00338, 0x02289), CE(0x00338, 0x022e2),\n            CE(0x00338, 0x022e3), CE(0x00338, 0x022ac), CE(0x00338, 0x022ad),\n            CE(0x00338, 0x022ae), CE(0x00338, 0x022af), CE(0x00338, 0x022ea),\n            CE(0x00338, 0x022eb), CE(0x00338, 0x022ec), CE(0x00338, 0x022ed),\n            CE(0x03099, 0x03094), CE(0x03099, 0x0304c), CE(0x03099, 0x0304e),\n            CE(0x03099, 0x03050), CE(0x03099, 0x03052), CE(0x03099, 0x03054),\n            CE(0x03099, 0x03056), CE(0x03099, 0x03058), CE(0x03099, 0x0305a),\n            CE(0x03099, 0x0305c), CE(0x03099, 0x0305e), CE(0x03099, 0x03060),\n            CE(0x03099, 0x03062), CE(0x03099, 0x03065), CE(0x03099, 0x03067),\n            CE(0x03099, 0x03069), CE(0x03099, 0x03070), CE(0x0309a, 0x03071),\n            CE(0x03099, 0x03073), CE(0x0309a, 0x03074), CE(0x03099, 0x03076),\n            CE(0x0309a, 0x03077), CE(0x03099, 0x03079), CE(0x0309a, 0x0307a),\n            CE(0x03099, 0x0307c), CE(0x0309a, 0x0307d), CE(0x03099, 0x0309e),\n            CE(0x03099, 0x030f4), CE(0x03099, 0x030ac), CE(0x03099, 0x030ae),\n            CE(0x03099, 0x030b0), CE(0x03099, 0x030b2), CE(0x03099, 0x030b4),\n            CE(0x03099, 0x030b6), CE(0x03099, 0x030b8), CE(0x03099, 0x030ba),\n            CE(0x03099, 0x030bc), CE(0x03099, 0x030be), CE(0x03099, 0x030c0),\n            CE(0x03099, 0x030c2), CE(0x03099, 0x030c5), CE(0x03099, 0x030c7),\n            CE(0x03099, 0x030c9), CE(0x03099, 0x030d0), CE(0x0309a, 0x030d1),\n            CE(0x03099, 0x030d3), CE(0x0309a, 0x030d4), CE(0x03099, 0x030d6),\n            CE(0x0309a, 0x030d7), CE(0x03099, 0x030d9), CE(0x0309a, 0x030da),\n            CE(0x03099, 0x030dc), CE(0x0309a, 0x030dd), CE(0x03099, 0x030f7),\n            CE(0x03099, 0x030f8), CE(0x03099, 0x030f9), CE(0x03099, 0x030fa),\n            CE(0x03099, 0x030fe), CE(0x110ba, 0x1109a), CE(0x110ba, 0x1109c),\n            CE(0x110ba, 0x110ab), CE(0x11127, 0x1112e), CE(0x11127, 0x1112f),\n        ];\n        return t;\n    }\n\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/unicode_decomp.d",
    "content": "module std.internal.unicode_decomp;\nimport std.internal.unicode_tables;\n\n@safe pure nothrow @nogc package(std):\n\nstatic if (size_t.sizeof == 8)\n{\n    //22656 bytes\n    enum compatMappingTrieEntries = TrieEntry!(ushort, 8, 8, 5)([0x0, 0x20,\n            0x2a0], [0x100, 0xa00, 0x21c0], [0x402030202020100,\n            0x706020202020205, 0x802020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x0, 0x3000200010000, 0x7000600050004,\n            0xa000900080000, 0xc000b, 0xf000e000d0000, 0x11001000000000,\n            0x15001400130012, 0x19001800170016, 0x1b001a00000000, 0x0, 0x1c,\n            0x1e0000001d0000, 0x1f00000000, 0x0, 0x0, 0x0, 0x0, 0x2100200000,\n            0x2200000000, 0x2400230000, 0x0, 0x2500000000, 0x2700000026,\n            0x2800000000, 0x2900000000, 0x2a00000000, 0x2b00000000, 0x2c0000,\n            0x2e002d0000, 0x3100300000002f, 0x330032, 0x340000,\n            0x35000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3800370036,\n            0x0, 0x0, 0x0, 0x3b003a00390000, 0x3d003c, 0x410040003f003e,\n            0x45004400430042, 0x49004800470046, 0x4d004c004b004a,\n            0x510050004f004e, 0x530052, 0x57005600550054, 0x5a00590058,\n            0x5e005d005c005b, 0x6100000060005f, 0x620000, 0x0,\n            0x63000000000000, 0x67006600650064, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x69000000000068, 0x6a00000000, 0x0, 0x0,\n            0x6b000000000000, 0x0, 0x6c000000000000, 0x0, 0x0,\n            0x6e00000000006d, 0x7200710070006f, 0x7500740073, 0x79007800770076,\n            0x7d007c007b007a, 0x80007f007e0000, 0x81, 0x85008400830082,\n            0x89008800870086, 0x8d008c008b008a, 0x910090008f008e, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x92000000000000,\n            0x93000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x97009600950094,\n            0x9b009a00990098, 0x9f009e009d009c, 0xa200a100a0, 0xa600a500a400a3,\n            0xaa00a900a800a7, 0xae00ad00ac00ab, 0xb200b100b000af,\n            0xb600b500b400b3, 0xba00b900b800b7, 0xbe00bd00bc00bb,\n            0xc200c100c000bf, 0xc600c500c400c3, 0xca00c900c800c7, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xcc00cb, 0xcd0000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf00ce00000000, 0xd100d00000,\n            0x0, 0x0, 0x0, 0x0, 0xd500d400d300d2, 0xd900d800d700d6,\n            0xdd00dc00db00da, 0xdf00d300d200de, 0xe200e100e000d5,\n            0xe500e400e300d9, 0xe900e800e700e6, 0xed00ec00eb00ea, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xf100f000ef00ee, 0xf300f2, 0x0, 0x0, 0x0, 0x0,\n            0xf700f600f500f4, 0xf8, 0xfb00fa00f9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xff00fe00fd00fc, 0x103010201010100,\n            0x107010601050104, 0x10b010a01090108, 0x10c, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x1, 0x0, 0x69200000015, 0x9000000000000, 0x30f034300000000,\n            0x11b20003, 0x78703140048, 0x49403c603ce, 0x58605730570056d,\n            0x5f8000005b005a6, 0x6580631062e062b, 0x6f906ea06e706e4,\n            0x7a907a6078f0000, 0x7e307bf07ac, 0x8b708b408b10000, 0x95f08cb,\n            0x9c209af09ac09a9, 0xa47000009ec09e2, 0xab30a8c0a890a86,\n            0xb550b490b460b43, 0xc5e0c5b0c410000, 0xc980c740c61,\n            0xd6e0d6b0d680000, 0xe1b00000e0c0d82, 0x9c8058c09c50589,\n            0xa3b05ec0a0a05ce, 0xa4105f20a3e05ef, 0xa6e061a0a4405f5,\n            0xaa2064700000000, 0xab006550aad0652, 0xab9065e0ad00675,\n            0xb0106a00afb069a, 0xb0a06a90b0406a3, 0xb1606ba, 0xb4f06f00b4c06ed,\n            0xb6b070f0b5206f3, 0xb3706d8000006f6, 0xbae072e0b730717,\n            0x7500bcc07430000, 0x7400bcf07460bd9, 0x78c000000000bc9,\n            0x7950c4d079b0c3e, 0xed70c47, 0xc8e07d90c8307ce, 0xca207ed,\n            0xd1d08580d070842, 0xd2b086c0d0d0848, 0xd49088a0d320873,\n            0xd5d08a60d380879, 0xd54089d, 0xd7808c10d7108ba, 0xd9808e10d7f08c8,\n            0xdc4090d0d9b08e4, 0xe0f09620de9093f, 0x97f0e290979096e,\n            0x8400614060d0e2f, 0xcae07f9, 0x0, 0x0, 0x8f0000000000000, 0xda7,\n            0x0, 0x0, 0x0, 0x0, 0x7360a670613060c, 0x78307800bb9073d,\n            0x70309f305b70c32, 0x8e70ca507f00b5f, 0x8d20d8d08d60d9e,\n            0x8ce0d9108da0d89, 0x9e505a900000d85, 0xe630e5a09de05a2,\n            0xb0706a600000000, 0xccc08170ba80728, 0xecc0e7b0ccf081a,\n            0xa64061006090b76, 0xaf80697, 0x9ef05b30c3b0789, 0xe680e5d0e600e57,\n            0x9f905bd09f605ba, 0xabf06640abc0661, 0xb6507090b620706,\n            0xcab07f60ca807f3, 0xd13084e0d10084b, 0xda408ed0da108ea,\n            0xd5a08a30d460887, 0xb1f06c300000000, 0x0, 0x9db059f00000000,\n            0xc9b07e60ac9066e, 0xc9107dc0c7b07c6, 0xe1509680c9407df, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xa11073e0e9a0b0d, 0xde10eb80eb60eb4,\n            0x695, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4b00240012000f,\n            0x270006, 0xb4108400a280e96, 0xecf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x2b00000004001a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xed5, 0x5400000000, 0x54600000000, 0x0,\n            0x7410ee8001c0003, 0xfb40f630f43, 0x103c101600000fed, 0x1185, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x101f0fbd00000000, 0x1175111910f5108f, 0x1213,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x120c117e00000000, 0x124b120311d5,\n            0x10161011116e10ea, 0x11ee123c101f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x11f811f011ae, 0x10f00fad, 0x100d0000, 0x0, 0x12ad000012b612b0,\n            0x12a4000000000000, 0x0, 0x12d712c212ce, 0x0, 0x0, 0x12c80000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x130a0000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x12ef000012f812f2, 0x132d000000000000, 0x0, 0x131b13041310, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x1333133000000000, 0x0, 0x0, 0x12fb12b90000,\n            0x0, 0x0, 0x0, 0x12ec12aa12e912a7, 0x12f512b300000000,\n            0x1339133600000000, 0x130112bf12fe12bc, 0x130712c500000000,\n            0x131512d1130d12cb, 0x133f133c00000000, 0x131812d4132a12e6,\n            0x132112dd131e12da, 0x132412e0, 0x132712e3, 0x0, 0x0,\n            0x1342000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x13e913e600000000, 0x17ca13ec178f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x185b179213ef0000, 0x1811, 0x0,\n            0x18520000186d, 0x0, 0x0, 0x0, 0x186a000000000000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x18820000, 0x0, 0x188b0000, 0x188e, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x1879187618731870, 0x18881885187f187c, 0x0,\n            0x0, 0x189a000000000000, 0x189d, 0x0, 0x0, 0x0, 0x1897000018941891,\n            0x0, 0x0, 0x0, 0x0, 0x18ac000000000000, 0x18af00000000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18a618a318a00000, 0x18a900000000,\n            0x0, 0x0, 0x18b80000000018bb, 0x18be, 0x0, 0x0, 0x0, 0x18b518b2,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x18c1, 0x0, 0x0, 0x0, 0x0,\n            0x18ca18c400000000, 0x18c7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18cd,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x18d0, 0x18da000000000000,\n            0x18d618d3000018dd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x18e618e000000000, 0x18e3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x18e900000000, 0x18f318ef18ec, 0x0, 0x0, 0x0, 0x0,\n            0x18f6000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x18ff000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x18fc18f9, 0x0, 0x0, 0x0, 0x1902, 0x0, 0x0, 0x0, 0x0,\n            0x1907000000000000, 0x0, 0x0, 0x190a0000, 0x190d00000000,\n            0x1910000000000000, 0x0, 0x1913, 0x0, 0x0, 0x19040000, 0x0,\n            0x1916000000000000, 0x1931193519190000, 0x1938193c, 0x0,\n            0x191c0000, 0x0, 0x0, 0x0, 0x1922000000000000, 0x0, 0x0,\n            0x19250000, 0x192800000000, 0x192b000000000000, 0x0, 0x192e, 0x0,\n            0x0, 0x191f0000, 0x0, 0x0, 0x193f00000000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1942, 0x0,\n            0x1a3800000000, 0x1a3e00001a3b, 0x1a4400001a41, 0x1a4700000000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a4a000000000000,\n            0x1a4d0000, 0x1a5600001a531a50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x5d50e550568, 0x6870e75062905e6, 0x71a060706cf06ac,\n            0x77e07230734, 0x82c06af0e7e07a4, 0x6920770056b088d,\n            0x9371a590e840e82, 0xe8e0e8c0a7d0a2e, 0xb79000006020e90,\n            0xe8807870e7105d3, 0xba30cd31a5d1a5b, 0x86a0ea41a610a24,\n            0x10ee10ec10ea1a63, 0xa110ae0123e123c, 0x10ec10ea086a0a24,\n            0x123e123c11f0, 0x0, 0x0, 0x0, 0x1313, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xe86000000000000, 0xe900e660e8a09a0, 0xe980e940e920ad9,\n            0x1a650ea00e9e0e9c, 0xed31a670ea20ed1, 0xeac0eaa0ea60ea8,\n            0xeba0eb20eb00eae, 0xec00ebe0e790ebc, 0x6110ec40ec21a5f,\n            0x116e0eca0ec80ec6, 0xa1305da0a0705cb, 0xa1905e00a1605dd,\n            0xa6b06170a4a05fb, 0xa7a06260a71061d, 0xa7706230a740620,\n            0xaa9064e0aa5064a, 0xad6067b0ad30678, 0xaef06840acc0671,\n            0xb1906bd0afe069d, 0xb1c06c00b2206c6, 0xb2806cc0b2506c9,\n            0xb5806fc0b6e0712, 0xbab072b0ba50725, 0xbd207490bb10731,\n            0xbdf07560bd5074c, 0xc1207720bdc0753, 0xc1807780c150775,\n            0xc4a07980c440792, 0xc50079e0c5307a1, 0xc7f07ca0c7707c2,\n            0xc8a07d50c8607d1, 0xcef08380cec0835, 0xd1608510d0a0845,\n            0xd20085b0d190854, 0xd3f08800d350876, 0xd3b087c0d2e086f,\n            0xd4e089a0d420883, 0xd6308ac0d5708a0, 0xdc1090a0d6008a9,\n            0xdc709100dca0913, 0xd7b08c40d7408bd, 0xdde09270ddb0924,\n            0xde6093c0de30939, 0xdec09420def0945, 0xe0109540df50948,\n            0xe18096b0e040957, 0xe3509850e2c097c, 0xd510b2b0e380988,\n            0xd3509a60e210df2, 0x0, 0x9e905ad09fc05c0, 0x9b2057609b6057a,\n            0x9ba057e09be0582, 0x9cf059309ff05c3, 0x9d7059b09cb058f,\n            0xa0305c709d30597, 0xab6065b0ac20667, 0xa9306380a9f0644,\n            0xa9b06400a8f0634, 0xac5066a0a97063c, 0xb68070c0b5c0700,\n            0xc9f07ea0cc50810, 0xc6407af0c6807b3, 0xc6c07b70c7007bb,\n            0xcb508000cc80813, 0xcbd08080cb107fc, 0xcc1080c0cb90804,\n            0xd9508de0dbe0907, 0xdaa08f30dae08f7, 0xdb208fb0db608ff,\n            0xe09095c0dba0903, 0xe1e09710e240974, 0xe120965, 0x0,\n            0x10c1109f10be109c, 0x10d310b110ca10a8, 0xf160ef40f130ef1,\n            0xf280f060f1f0efd, 0x110610fb110310f8, 0x110a10ff,\n            0xf540f490f510f46, 0xf580f4d, 0x1145112311421120,\n            0x11571135114e112c, 0xf8b0f690f880f66, 0xf9d0f7b0f940f72,\n            0x119f1190119c118d, 0x11a7119811a31194, 0xfd20fc30fcf0fc0,\n            0xfda0fcb0fd60fc7, 0x11e611db11e311d8, 0x11ea11df,\n            0xffe0ff30ffb0ff0, 0x10020ff7, 0x122d121e122a121b,\n            0x1235122612311222, 0x1025000010220000, 0x102d000010290000,\n            0x1277125512741252, 0x128912671280125e, 0x106410421061103f,\n            0x10761054106d104b, 0x10f510f2108f1088, 0x1175117211191112,\n            0x1203120011d511d2, 0x124b1244, 0x10c510a310dc10ba,\n            0x10d710b510ce10ac, 0xf1a0ef80f310f0f, 0xf2c0f0a0f230f01,\n            0x114911271160113e, 0x115b113911521130, 0xf8f0f6d0fa60f84,\n            0xfa10f7f0f980f76, 0x127b125912921270, 0x128d126b12841262,\n            0x10681046107f105d, 0x107a10581071104f, 0x10e7108b10961099,\n            0x10e310e000001092, 0xee80ee50eeb0eee, 0x2a1170002a0f35,\n            0x116b111500200051, 0x116711640000111c, 0xf630f600f430f40,\n            0x350031002d0faa, 0x118511811178117b, 0x118911ab00000000,\n            0xfb40fb10fb70fba, 0x440040003c0000, 0x1213120f12061209,\n            0x1217123911f511f2, 0x101610131019101c, 0x995001c0018100a,\n            0x129d124700000000, 0x129912960000124e, 0x103c10390fed0fea,\n            0x3900031083, 0x1000100010001, 0x1000100010001, 0x100010001, 0x0,\n            0x1a690000, 0x4e000000000000, 0x0, 0x0, 0x0, 0x2ff02fc02fa, 0x0,\n            0x1000000000000, 0x1a6f000000000000, 0x1a7e1a7b00001a72, 0x0,\n            0xc0000008f, 0x0, 0x563000000000000, 0x920560, 0x0, 0x0,\n            0x1a76000000000000, 0x0, 0x1000000000000, 0x0, 0x0, 0x0, 0x0,\n            0xae00305, 0x392038303740365, 0x1aad02f403b003a1,\n            0xb3b00a500a10544, 0x30f034303140305, 0x392038303740365,\n            0x1aad02f403b003a1, 0xa500a10544, 0xb4107870a7d0692,\n            0xa280b790b0d0e8c, 0x8400cd30b3b05d3, 0xba3, 0x0, 0x0, 0x83f, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xe4d05e309a2099e, 0xe770a220a1e0000,\n            0x6ac06020e500000, 0xe6d0b0d06ac06ac, 0xa28073406cf06cf,\n            0x786077e0000, 0x82c083b06af0000, 0x82c082c, 0x897088f0863,\n            0x77c0000060a, 0x5b0071a0000060a, 0xa7d000005e305d5,\n            0x7230000067e0629, 0x136a136213540787, 0x68000000ae0136f,\n            0x10060f3a10ec11ee, 0x1aab, 0xa7d0a2e05e60000, 0x73e0ae0, 0x0,\n            0x3ca03c103e203da, 0x498045903d20455, 0x3de04e703d604cf,\n            0x3be051104eb049c, 0x6de06d406d106cf, 0x91f091b091806b2,\n            0x950094d068206e1, 0x72305e605e30734, 0xb3d0b330b300ae0,\n            0xdd60dd20dcf086a, 0xdfd0dfa0b410b40, 0x5d30a2e09a00a28, 0x0, 0x0,\n            0x30d0000, 0x0, 0x0, 0x0, 0x1a8d1a8600000000, 0x0, 0x0, 0x0, 0x0,\n            0x1a9200000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x1a981a9b1a950000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1aa0, 0x1aa50000,\n            0x1aa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ab200001aaf, 0x0,\n            0x1ac100001ab81ab5, 0x1ac4, 0x0, 0x0, 0x0, 0x1ac80000,\n            0x1ace000000001acb, 0x1ad10000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x1ad700000556, 0x0, 0x0, 0x55b054a1ad40000, 0x1add1ada,\n            0x1ae31ae0, 0x1ae91ae6, 0x0, 0x1aef1aec, 0x1afb1af8, 0x1b011afe,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b131b101b0d1b0a, 0x0,\n            0x0, 0x0, 0x0, 0x1b071b041af51af2, 0x0, 0x1b191b1600000000,\n            0x1b1f1b1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b371b350000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x365030f03430314, 0x3a1039203830374,\n            0x342032f031c03b0, 0x382037303640355, 0x3f703af03a00391,\n            0xe600e200d900a3, 0xf600f200ee00ea, 0xb100ac00a700fa,\n            0xc500c000bb00b6, 0xdd00d400cf00ca, 0x368035903460319,\n            0x3a4039503860377, 0x3450332031f03b3, 0x385037603670358,\n            0x3fa03b203a30394, 0x172016e016a0166, 0x182017e017a0176,\n            0x192018e018a0186, 0x1a2019e019a0196, 0x1b201ae01aa01a6,\n            0x1c201be01ba01b6, 0x5d5056801ca01c6, 0x67e062905e605e3,\n            0x60706cf06ac0687, 0x77e07230734071a, 0x82c083b06af07a4,\n            0x6b2056b088d085e, 0x60a095a06820770, 0xa2e09a009370692,\n            0xb0d06020ad90a7d, 0xa280b79073e0ae0, 0xcd307870b3b05d3,\n            0xba308400a1105d8, 0xb410de1086a0a24, 0x30506110695, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x1abc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x552054f0542, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x1b2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6b2073e, 0x0,\n            0x0, 0x0, 0x1b2f000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x227c000000000000, 0x0, 0x0, 0x0, 0x0,\n            0x26b0000000000000, 0x0, 0x0, 0x0, 0x1f091f011efb1ee9,\n            0x1f1b1f171f131f0d, 0x1f5f1f571f4b1f21, 0x1f871f771f6f1f67,\n            0x1fb91fa51f8b1f89, 0x1fcd1fc71fc51fc1, 0x1feb1fe91fdd1fdb,\n            0x204f20451ff71fef, 0x207f207d2079206f, 0x20b420ae20982087,\n            0x20ce20cc20ca20c4, 0x20f820f220dc20da, 0x210f2108210020fc,\n            0x212f212b21292113, 0x2141213921352131, 0x21972195218b214f,\n            0x21e521e321d921d7, 0x32521f121ed21e9, 0x2260222303292211,\n            0x227a2274226e2266, 0x228422822280227e, 0x230c230622e22286,\n            0x231623122310230e, 0x2334233023222318, 0x235c235a23562354,\n            0x2376237423622360, 0x238a238823862384, 0x23aa23a823a62394,\n            0x23ee23de23dc23bc, 0x241c240a23fa23f6, 0x2452244c2442243e,\n            0x245e245c245a2456, 0x247e247a246c246a, 0x248e248a24842482,\n            0x2498249624922490, 0x250e250c24f224e8, 0x2530252c25282512,\n            0x2558255425522534, 0x25742572255c255a, 0x2592258425822578,\n            0x25ba25aa25982596, 0x25de25c825c425c2, 0x260025fa25e825e0,\n            0x261a261826142608, 0x26262624261e261c, 0x263c263a2638262a,\n            0x2658264e264a2648, 0x26622660265c265a, 0x2670266826662664,\n            0x26862684267e267c, 0x2690268e268a2688, 0x26a0269c26982692,\n            0x26aa26a826a626a2, 0x26b226ae, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b4900000000,\n            0x1fd11fcf1fcd, 0x0, 0x0, 0x0, 0x0, 0x1b8100001b7e, 0x1b8700001b84,\n            0x1b8d00001b8a, 0x1b9300001b90, 0x1b9900001b96, 0x1b9f00001b9c,\n            0x1ba500001ba20000, 0x1ba80000, 0x0, 0x1bb100001bae1bab,\n            0x1bba1bb700001bb4, 0x1bc01bbd0000, 0x1bc91bc6, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x1b7b, 0x87000000000000, 0x1bcc1bd30000008a, 0x0, 0x0, 0x0,\n            0x1c4300001c26, 0x1c9200001bf6, 0x1caf00001c9b, 0x1cca00001cbf,\n            0x1cdc00001ccf, 0x1ceb00001ce1, 0x1cf700001cf20000, 0x1c100000,\n            0x0, 0x1d3b00001d261d1d, 0x1d611d5700001d42, 0x1d7e1d760000,\n            0x1caa1da1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e44000000001c01,\n            0x1e571e521e4d, 0x1ca11e6000000000, 0x0, 0x0, 0x0, 0x0,\n            0x1a10194919440000, 0x19501a141a12194b, 0x1a181a1619571955,\n            0x1a201a1e1a1c1a1a, 0x19661961195c19a6, 0x196f196d196819b0,\n            0x198e198319811977, 0x1947199d19981993, 0x19de19dc19da19d8,\n            0x198c19e419e219e0, 0x19ee19ec19ea19e8, 0x19f619f419f21975,\n            0x19fe197f19fa19f8, 0x1a2219a419a219d4, 0x1a2a1a281a261a24,\n            0x1a3019a81a2e1a2c, 0x19ae19ac19aa1a32, 0x19b819b619b419b2,\n            0x19c019be19bc19ba, 0x19c819c619c419c2, 0x1a361a3419cc19ca,\n            0x1a0019d219d019ce, 0x1a081a061a041a02, 0x1a0e1a0c1a0a,\n            0x1f171ee900000000, 0x1efd1ef120471eef, 0x1ef71f0d23641ef3,\n            0x1f212051208c1eeb, 0x1e901e001d701ce, 0x20d020401fb01f2,\n            0x245023c02330225, 0x1db01d20257024e, 0x1ff01f601ed01e4,\n            0x237022902110208, 0x25b025202490240, 0x21e0216022e,\n            0x2a0026802700260, 0x284026402880274, 0x2c402b00290026c,\n            0x2a402ec02b802c0, 0x2d002b402bc02ac, 0x2d402e402c80298,\n            0x2a8029c0278028c, 0x29402e8027c02cc, 0x2e002dc028002d8,\n            0x23fe21e321112021, 0x0, 0x0, 0x41c04110406082e, 0x440043904320427,\n            0x475046e044e0447, 0x4850482047f047c, 0x19571950194b1944,\n            0x196f19681961195c, 0x1993198e19831977, 0x194d1946199d1998,\n            0x1963195e19591952, 0x198519791971196a, 0x199f199a19951990,\n            0x1974197c1988, 0x20471eef1f171ee9, 0x1f5f1eed1f611f19,\n            0x22e203291fcd1f0f, 0x204f25c822232286, 0x2240221b223b0325,\n            0x23ca255e231c2007, 0x2098236823e21fab, 0x22961fdf1f4925a2,\n            0x208a1f731f2b262c, 0x20fa1ef31efd1ef1, 0x20b220b81fc92001,\n            0x1fd725681f292390, 0x48e048b04882083, 0x4b704b404b10491,\n            0x4c304c004bd04ba, 0x4e404cc04c904c6, 0x4d604a3034e033b,\n            0x5290518050304f2, 0x34d033a0327053a, 0x7390a7f0a8206b4,\n            0x1c0a1bff1bf11bd8, 0x1c731c411c241c1a, 0x1cbd1cad1c991c90,\n            0x1cdf1cda1ccd1c1e, 0x1bde1cf51cf01bfb, 0x1c8e1d111d0f1ca6,\n            0x1d551d391d1b1d0d, 0x1ddc1c311d9f1d74, 0x1e041e001def1c22,\n            0x1c351e1b1e191e11, 0x1e421c5d1e341bed, 0x1e551e501e4b,\n            0x1beb1be51be01bda, 0x1c0c1c041bf91bf3, 0x1c331c201c1c1c13,\n            0x1c2e1c291c3c1c37, 0x1c501c571c4b1c46, 0x1c6d1c661c5f1c5c,\n            0x1c8b1c841c7d1c61, 0x1cb21ca81ca41c95, 0x1cd61cd21cc21cb7,\n            0x1c811d031cfa1ce4, 0x1d291d351d171d0c, 0x1d4c1d451d201d30,\n            0x1d6b1d641d3e1d51, 0x1d811d951d701d5a, 0x1d8f1d8a1d9b1d85,\n            0x1db81da41dac1d79, 0x1dc51dbf1dbb1db2, 0x1dd61dd21dce1dca,\n            0x1df11de61de31dde, 0x1e0b1e061c681df5, 0x1e291e241e1f1e13,\n            0x1c6f1e391e361e2e, 0x3610352033f0311, 0x39d038e037f0370,\n            0x33e032b03bb03ac, 0x37e036f03600351, 0x3ba03ab039c038d,\n            0x4230418040d0402, 0x56a0a530b0f042e, 0xa590ce60c580a0f,\n            0x210a06db0a600a5c, 0x223d21f920892200, 0xbea11b40c260cda,\n            0x689075b071c0b7b, 0xc290cdd0b8c0a26, 0x6010bf611c011b7,\n            0x68c07640b7e068d, 0xa560bfd11c30893, 0x11c60c350aec0b94,\n            0xc030b970a300c00, 0xc070b9a0a340a33, 0xc1b0b9e0a380a37,\n            0x7680b8206910c1f, 0xd000cfa0cf60690, 0xc0f11c90c380ce9,\n            0xbed11ba0c2c0ce0, 0xc2f0ce3076c0b86, 0x76f0b890bf011bd,\n            0x5d70999077b0bb4, 0x5e805ff0a2d0a2a, 0x6ae0b1306940a50,\n            0xba20722071f0b3a, 0xbc60bc20bbf0bbc, 0x8200c0b0bf90bf3,\n            0xd25082b08230cd5, 0x5d1092a09360869, 0x36c035d034a0337,\n            0x3a80399038a037b, 0x3490336032303b7, 0x389037a036b035c,\n            0x3fe03b603a70398, 0x42a041f04140409, 0x44a0443043c0435,\n            0xaf4047804710451, 0x0, 0x0, 0x0, 0x0, 0x26b4, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xe730e6b, 0x0, 0x256a258422132556,\n            0x26ae1ff91eff22c6, 0x202b25c8209226ae, 0x244a238221872090,\n            0x25a8251e250424e6, 0x233c22f0229a2254, 0x1f11265225bc24ca,\n            0x24e42302225e1fe3, 0x24dc22d620e6267a, 0x250a247821a12526,\n            0x232822a6221d211f, 0x1fb31f7d1f3125ae, 0x23922300225a21d5,\n            0x257e24ec24e02456, 0x23b02678266a2610, 0x25d624bc242c23d0,\n            0x212d206d2540267e, 0x23b4231a24682408, 0x20d4206b260c2566,\n            0x242422ca22b02256, 0x246e1fb125ec2438, 0x242e23e61f811f83,\n            0x21a3254e25f024c8, 0x20be1f0525462254, 0x1fc3237223322159,\n            0x1ef5214b1f3923b8, 0x1fed242221e12290, 0x253824cc23982063,\n            0x21ab228c25962276, 0x1f1f237021bb24a8, 0x241822441f7f1f5d,\n            0x1fb725c6253e2494, 0x21ef212720982011, 0x265625e423ba22d8,\n            0x220f1fa5268c2680, 0x217b210d2590226c, 0x22f622d021d12189,\n            0x2464243223e0234e, 0x25d8259c24d02588, 0x22ee201b1fa71f91,\n            0x2155211d25382514, 0x232c2406227221b7, 0x20f020be20491f27,\n            0x24502348233a215b, 0x2612260a25ca2460, 0x25c023da1f332630,\n            0x1f451f15216725fe, 0x225421e720d020c0, 0x25a624d6238022fc,\n            0x1fa325ea220726aa, 0x22be22a22233222d, 0x242023ae236e2340,\n            0x25f221911f612636, 0x258a22b220e21f3d, 0x23322237216b2143,\n            0x20d820091f9525f6, 0x2294224a222521fc, 0x251624462378233e,\n            0x1fcb260425c4251c, 0x235022fe200b22c0, 0x2682266e25f824de,\n            0x23f6247c22ae2231, 0x22ea2326240e23fc, 0x1f9724b01f23254c,\n            0x241421a521151f8f, 0x258e220d229c20b6, 0x2123252c25ee250e,\n            0x20371f4d, 0x220500002061, 0x238c232a1f850000, 0x23d823ce23cc23be,\n            0x245224102616, 0x2544000024e2, 0x25b4259e0000, 0x2642264000000000,\n            0x25fc25b026762644, 0x1faf1f511f471f35, 0x203d202f1fd51fb5,\n            0x20d62065205f2041, 0x21792175216120da, 0x220921f321db2185,\n            0x22ce22b622a82246, 0x23b22342230822f8, 0x23c623c223c42240,\n            0x23d623d423ca23c8, 0x2432240023f223e8, 0x24582444243a2436,\n            0x24ce249a249a2480, 0x254a2548252e2522, 0x259e259a256e256c,\n            0x215d263426282606, 0x248c274b, 0x1f2f1f5b1f7b1ef9,\n            0x1fbb1fad1f651f4f, 0x203b202d2025202f, 0x2094208e20692061,\n            0x2125212120aa20a2, 0x21712165214d213d, 0x2185217321792169,\n            0x21c921c521bf2193, 0x221f221d220521dd, 0x22a22276226e2229,\n            0x22dc22ce22c422c8, 0x2324230a23a422f8, 0x236a2358234a232a,\n            0x238e238c237e237c, 0x23b6239e23a02396, 0x2428240c240023f4,\n            0x24b2245824402432, 0x252a2524250024c6, 0x253c2544253a252e,\n            0x254a254225462548, 0x25a4258c256e2550, 0x260625f425ce25be,\n            0x262e262826202616, 0x272126ae265e2634, 0x1ea11e8d2733271f,\n            0x27a9277927671ea3, 0x26ac26a4, 0x0, 0xade0ae30adf0adb,\n            0xd280d280ae2, 0x0, 0x0, 0x134e000000000000, 0x134b135113481345,\n            0x0, 0x13d2000013850000, 0x1374136f135413a6, 0x13b7139b1360138e,\n            0x13ca13c702f413cd, 0x1359135613c313bf, 0x1371136c1364135c,\n            0x137f137c1376, 0x1390138b13881382, 0x139d00001398,\n            0x13a8000013a313a0, 0x13b413b1000013ab, 0x137913cf13bc13b9,\n            0x135f13ae13931367, 0x181e181e18181818, 0x18201820181e181e,\n            0x1824182418201820, 0x181c181c18241824, 0x18221822181c181c,\n            0x181a181a18221822, 0x183c183c181a181a, 0x183e183e183c183c,\n            0x18281828183e183e, 0x1826182618281828, 0x182a182a18261826,\n            0x182c182c182a182a, 0x18321832182c182c, 0x1834183418301830,\n            0x18381838182e182e, 0x1840184018361836, 0x1844184418401840,\n            0x1848184818441844, 0x1846184618481848, 0x184a184a18461846,\n            0x184c184c184c184c, 0x18501850186d186d, 0x184e184e18501850,\n            0x15911591184e184e, 0x186a186a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x1842000000000000, 0x1803184218421842, 0x180717ff17ff1803,\n            0x18621862185b1807, 0x1860186018551855, 0x180b180b180b180b,\n            0x17cd17cd14151415, 0x17f117f1180d180d, 0x17fd17fd18011801,\n            0x1809180918051805, 0x17f517f517f51809, 0x1864186418641864,\n            0x17f517e517d517d1, 0x13fe13f713f417f9, 0x141e14171414140b,\n            0x146a144d1438142d, 0x1484147b1472146d, 0x14311422148c1487,\n            0x143c14d414d11435, 0x151a150c150514fa, 0x15a515a215931562,\n            0x15c815c515ba15b0, 0x1607157515e415df, 0x16451642163f160a,\n            0x165b16561653164c, 0x1679167416711662, 0x16851682167f167c,\n            0x16aa169616931688, 0x1579158c16c816b9, 0x14591455145116e0,\n            0x172d1461145d1526, 0x17691758174f1740, 0x177f17741771176c,\n            0x17aa17a3179c1782, 0x14e417c717c417b3, 0x64005d179714ee,\n            0x8000790072006b, 0x17e917e517e117dd, 0x140813db17f917f5,\n            0x14171414140e140b, 0x1464144d144a1447, 0x14781475146d146a,\n            0x14871484147e147b, 0x1674167116561653, 0x1693168816851679,\n            0x16e01579158c1696, 0x17551752152616e5, 0x176c176917631758,\n            0x17b317b017ad1797, 0x17d117c717c417be, 0x17ed17e517d917d5,\n            0x140b13fe13f713f4, 0x1438142d141e1411, 0x148c147b1467144d,\n            0x14d1143514311422, 0x150c150514fa143c, 0x1593156d1562151a,\n            0x15ba15b015a515a2, 0x157515e415df15c5, 0x1642163f160a1607,\n            0x1662165b164c1645, 0x16851682167f167c, 0x16c816b916aa1688,\n            0x1455145113e0158c, 0x1740172d15261459, 0x177117661758174f,\n            0x17a3179c17851774, 0x17e515ed17b317aa, 0x144d1411140b17ed,\n            0x151a1481147b1467, 0x16851557154c1529, 0x17661758158c1688,\n            0x162c162515ed17b3, 0x15ff15da15d71633, 0x152c161c16191602,\n            0x1490155d155a152f, 0x1440142a142613fb, 0x15bd159d159a1402,\n            0x1546153b153415c0, 0x157015171549154c, 0x15ff15da15d715b7,\n            0x152c161c16191602, 0x1490155d155a152f, 0x1440142a142613fb,\n            0x15bd159d159a1402, 0x1546153b153415c0, 0x157015171549154c,\n            0x1546153b153415b7, 0x15c815571529154c, 0x1534150c150514fa,\n            0x15df15c81546153b, 0x13e313e3, 0x0, 0x0, 0x0, 0x0,\n            0x1434143014301421, 0x145814541450143b, 0x14c114c514a314a3,\n            0x1521150114fd1508, 0x15251525151d1521, 0x153e159615651565,\n            0x154f154f1537153e, 0x15b315a815531553, 0x15cf15cb15cb15b3,\n            0x15f315f315e715d3, 0x16111615160d15f7, 0x1669166516481648,\n            0x16ad16c016c416bc, 0x16d216cb16cb16ad, 0x170b170216fe16d2,\n            0x1716171216f316eb, 0x177716ef00000000, 0x173417471743177b,\n            0x175b175f17381734, 0x1429140117b617b6, 0x1460143f14431425,\n            0x14a7148f14ab145c, 0x15ac15421569150f, 0x179f17a616d616b5,\n            0x174b166d172117ba, 0x168f15fb16bc1665, 0x168b16b1171a1730,\n            0x14ba1493173016b1, 0x168b13fa164f16f7, 0x173c1513159615e7, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13d913de165e158f,\n            0x15eb14e915731706, 0x1497157c1578158a, 0x14f1, 0x0, 0x0, 0x0, 0x0,\n            0x5401b331b3102f6, 0x1b770093008d0546, 0x2ff1b79, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x9931a6b1a6d02fc, 0xe3b00a500a10993, 0x1b451b4f1b4b0e3f,\n            0x1b351b3b1b391b47, 0x1b411b3f1b3d1b37, 0x98b000000001b43,\n            0xc000c000c098f, 0x99309930993000c, 0x2fa1b3102f6,\n            0x8d009305400546, 0xe3b00a500a11a6d, 0x971b4f1b4b0e3f,\n            0x2f802f402f2009d, 0x54405590548, 0x566009b0099098d, 0x0,\n            0x5a161f0057, 0x1622006800000061, 0x163000761629006f,\n            0x163a00841637007d, 0x13e913e613e613d5, 0x13ec178f178f13e9,\n            0x17ca17ca17ca13ec, 0x13f213d713d717ca, 0x141a13f213f213f2,\n            0x141c141c141c141a, 0x147014701470141c, 0x13f513f513f51470,\n            0x13f813f813f813f5, 0x13ff13ff13ff13f8, 0x14e214e014e013ff,\n            0x140913dc13dc14e2, 0x14f814f814f81409, 0x15321532153214f8,\n            0x1560156015601532, 0x15a015a015a01560, 0x15c315c315c315a0,\n            0x15dd15dd15dd15c3, 0x15e215e215e215dd, 0x16051605160515e2,\n            0x163d163d163d1605, 0x165916591659163d, 0x1677167716771659,\n            0x14ec14ec14ec1677, 0x140c140c140c14ec, 0x140f140f140f140c,\n            0x13e113e113e1140f, 0x14151788178813e1, 0x13fc13fc13fc1415,\n            0x16a2169e169e13fc, 0x169b16a616a616a2, 0x169b, 0x970095008d0000,\n            0x9f009d009b0099, 0x2f402f200a500a1, 0x30302fa02f802f6,\n            0x30f034303140305, 0x392038303740365, 0x546054003b003a1,\n            0x93055905440548, 0x5e305d505680566, 0x687067e062905e6,\n            0x71a060706cf06ac, 0x7a4077e07230734, 0x85e082c083b06af,\n            0x77006b2056b088d, 0x98b060a095a0682, 0x9930991098f098d,\n            0x9a0093706920995, 0x6020ad90a7d0a2e, 0xb79073e0ae00b0d,\n            0x7870b3b05d30a28, 0x8400a1105d80cd3, 0xde1086a0a240ba3,\n            0xe3b061106950b41, 0x1b280e410e3f0e3d, 0x1b3f1b3d1b331b2a,\n            0x1bd61e551e5c1b31, 0x1c181c081bfd1bef, 0x1cee1e171e0f1e02,\n            0x1bff1bf11bd81c16, 0x1c411c241c1a1c0a, 0x1cad1c991c901c73,\n            0x1cda1ccd1c1e1cbd, 0x1cf51cf01bfb1cdf, 0x1d111d0f1ca61bde,\n            0x1d391d1b1d0d1c8e, 0x1c311d9f1d741d55, 0x1e001def1c221ddc,\n            0x1e1b1e191e111e04, 0x1c5d1e341bed1c35, 0x8b00881c061e42,\n            0x1a101949194419d4, 0x19501a141a12194b, 0x1a181a1619571955,\n            0x1a201a1e1a1c1a1a, 0x19661961195c19a6, 0x196f196d196819b0,\n            0x198e198319811977, 0x199d19981993, 0x19d8194700000000,\n            0x19e019de19dc19da, 0x19e419e200000000, 0x19ec19ea19e8198c,\n            0x197519ee00000000, 0x19f819f619f419f2, 0x197f19fa00000000, 0x19fe,\n            0x90e4b0e450e43, 0x1a820e470e49, 0x1a8b1a891a841b22,\n            0x1b261b241a90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x26b600000000, 0x26b9, 0x0, 0x0, 0x26bc000000000000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26c226bf00000000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26c826c500000000,\n            0x26d726d326cf26cb, 0x26db, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x26df000000000000, 0x26e626ed26e226ea, 0x26f1,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5e605e305d50568,\n            0x6ac0687067e0629, 0x734071a060706cf, 0x6af07a4077e0723,\n            0x88d085e082c083b, 0x682077006b2056b, 0x9370692060a095a,\n            0xad90a7d0a2e09a0, 0x73e0ae00b0d0602, 0xb3b05d30a280b79,\n            0xa1105d80cd30787, 0x86a0a240ba30840, 0x61106950b410de1,\n            0x5e605e305d50568, 0x6ac0687067e0629, 0x734071a060706cf,\n            0x6af07a4077e0723, 0x88d085e082c083b, 0x682077006b2056b,\n            0x9370692060a095a, 0xad90a7d0a2e09a0, 0x73e0ae000000602,\n            0xb3b05d30a280b79, 0xa1105d80cd30787, 0x86a0a240ba30840,\n            0x61106950b410de1, 0x5e605e305d50568, 0x6ac0687067e0629,\n            0x734071a060706cf, 0x6af07a4077e0723, 0x88d085e082c083b,\n            0x682077006b2056b, 0x9370692060a095a, 0xad90a7d0a2e09a0,\n            0x73e0ae00b0d0602, 0xb3b05d30a280b79, 0xa1105d80cd30787,\n            0x86a0a240ba30840, 0x61106950b410de1, 0x5e605e300000568,\n            0x68700000000, 0x71a06070000, 0x6af07a4077e0000, 0x88d085e0000083b,\n            0x682077006b2056b, 0x9370692060a095a, 0xad900000a2e09a0,\n            0x73e0ae00b0d0000, 0xb3b05d30a280b79, 0xa1105d80cd30000,\n            0x86a0a240ba30840, 0x61106950b410de1, 0x5e605e305d50568,\n            0x6ac0687067e0629, 0x734071a060706cf, 0x6af07a4077e0723,\n            0x88d085e082c083b, 0x682077006b2056b, 0x9370692060a095a,\n            0xad90a7d0a2e09a0, 0x73e0ae00b0d0602, 0xb3b05d30a280b79,\n            0xa1105d80cd30787, 0x86a0a240ba30840, 0x61106950b410de1,\n            0x5e6000005d50568, 0x687067e0629, 0x734071a06070000,\n            0x6af07a4077e0723, 0x88d085e0000083b, 0x682077006b2056b,\n            0x93706920000095a, 0xad90a7d0a2e09a0, 0x73e0ae00b0d0602,\n            0xb3b05d30a280b79, 0xa1105d80cd30787, 0x86a0a240ba30840,\n            0x61106950b410de1, 0x5e6000005d50568, 0x687067e0629,\n            0x734071a060706cf, 0x7a400000723, 0x88d085e00000000,\n            0x682077006b2056b, 0x93706920000095a, 0xad90a7d0a2e09a0,\n            0x73e0ae00b0d0602, 0xb3b05d30a280b79, 0xa1105d80cd30787,\n            0x86a0a240ba30840, 0x61106950b410de1, 0x5e605e305d50568,\n            0x6ac0687067e0629, 0x734071a060706cf, 0x6af07a4077e0723,\n            0x88d085e082c083b, 0x682077006b2056b, 0x9370692060a095a,\n            0xad90a7d0a2e09a0, 0x73e0ae00b0d0602, 0xb3b05d30a280b79,\n            0xa1105d80cd30787, 0x86a0a240ba30840, 0x61106950b410de1,\n            0x6af07a4077e0723, 0x88d085e082c083b, 0x682077006b2056b,\n            0x9370692060a095a, 0xad90a7d0a2e09a0, 0x73e0ae00b0d0602,\n            0xb3b05d30a280b79, 0xa1105d80cd30787, 0x9370692060a095a,\n            0xad90a7d0a2e09a0, 0x73e0ae00b0d0602, 0xb3b05d30a280b79,\n            0xa1105d80cd30787, 0x86a0a240ba30840, 0x61106950b410de1,\n            0x5e605e305d50568, 0x6ac0687067e0629, 0x734071a060706cf,\n            0x6af07a4077e0723, 0x88d085e082c083b, 0x682077006b2056b,\n            0x9370692060a095a, 0xad90a7d0a2e09a0, 0x73e0ae00b0d0602,\n            0xb3b05d30a280b79, 0xa1105d80cd30787, 0x86a0a240ba30840,\n            0x61106950b410de1, 0x5e605e305d50568, 0x6ac0687067e0629,\n            0x734071a060706cf, 0x6af07a4077e0723, 0x61106950b410de1, 0xe800e6f,\n            0xf3c0f3a0f380ee3, 0xfad0f5e0f5c0f3e, 0xfe20fe00fde0faf,\n            0x10060fe80fe60fe4, 0x100f100d0fad1008, 0x1035103310311011,\n            0x10ea10861aa3077c, 0x110e10f010ee10ec, 0x11ae1170116e1110,\n            0x11ce11cc11b211b0, 0x11f811f011ee11d0, 0x123c11fe11fc11fa,\n            0x1a9e12421240123e, 0x123c11ae116e10f0, 0xf380ee311ee11f0,\n            0xf5c0f3e0f3c0f3a, 0xfde0faf0fad0f5e, 0xfe60fe40fe20fe0,\n            0xfad100810060fe8, 0x10311011100f100d, 0x1aa3077c10351033,\n            0x10ee10ec10ea1086, 0x116e1110110e10f0, 0x11b211b011ae1170,\n            0x11ee11d011ce11cc, 0x11fc11fa11f811f0, 0x1240123e123c11fe,\n            0x116e10f01a9e1242, 0x11ee11f0123c11ae, 0xf3c0f3a0f380ee3,\n            0xfad0f5e0f5c0f3e, 0xfe20fe00fde0faf, 0x10060fe80fe60fe4,\n            0x100f100d0fad1008, 0x1035103310311011, 0x10ea10861aa3077c,\n            0x110e10f010ee10ec, 0x11ae1170116e1110, 0x11ce11cc11b211b0,\n            0x11f811f011ee11d0, 0x123c11fe11fc11fa, 0x1a9e12421240123e,\n            0x123c11ae116e10f0, 0xf380ee311ee11f0, 0xf5c0f3e0f3c0f3a,\n            0xfde0faf0fad0f5e, 0xfe60fe40fe20fe0, 0xfad100810060fe8,\n            0x10311011100f100d, 0x1aa3077c10351033, 0x10ee10ec10ea1086,\n            0x116e1110110e10f0, 0x11b211b011ae1170, 0x11ee11d011ce11cc,\n            0x11fc11fa11f811f0, 0x1240123e123c11fe, 0x116e10f01a9e1242,\n            0x11ee11f0123c11ae, 0xf3c0f3a0f380ee3, 0xfad0f5e0f5c0f3e,\n            0xfe20fe00fde0faf, 0x10060fe80fe60fe4, 0x100f100d0fad1008,\n            0x1035103310311011, 0x10ea10861aa3077c, 0x110e10f010ee10ec,\n            0x11ae1170116e1110, 0x11ce11cc11b211b0, 0x11f811f011ee11d0,\n            0x123c11fe11fc11fa, 0x1a9e12421240123e, 0x123c11ae116e10f0,\n            0x12a212a011ee11f0, 0x314030500000000, 0x3740365030f0343,\n            0x3b003a103920383, 0x30f034303140305, 0x392038303740365,\n            0x314030503b003a1, 0x3740365030f0343, 0x3b003a103920383,\n            0x30f034303140305, 0x392038303740365, 0x314030503b003a1,\n            0x3740365030f0343, 0x3b003a103920383, 0x14e013f513f213d7,\n            0x13f8140917880000, 0x14ec167713fc15c3, 0x15e214f8140f140c,\n            0x13dc16591560163d, 0x13ff1470141c1532, 0x160515dd15a014e2,\n            0x1816183a184a1814, 0x13f513f20000, 0x13f80000000013e1,\n            0x14ec167713fc0000, 0x15e214f8140f140c, 0x16591560163d,\n            0x13ff1470141c1532, 0x1605000015a00000, 0x0, 0x13f500000000,\n            0x13f8000000000000, 0x14ec000013fc0000, 0x15e214f8140f0000,\n            0x165915600000, 0x13ff000000001532, 0x1605000015a00000,\n            0x18160000184a0000, 0x13f513f20000, 0x13f80000000013e1,\n            0x167713fc15c3, 0x15e214f8140f140c, 0x16591560163d,\n            0x13ff1470141c1532, 0x160515dd15a00000, 0x183a00001814,\n            0x14e013f513f213d7, 0x13f81409178813e1, 0x14ec000013fc15c3,\n            0x15e214f8140f140c, 0x13dc16591560163d, 0x13ff1470141c1532,\n            0x160515dd15a014e2, 0x0, 0x14e013f513f20000, 0x13f8140917880000,\n            0x14ec000013fc15c3, 0x15e214f8140f140c, 0x13dc16591560163d,\n            0x13ff1470141c1532, 0x160515dd15a014e2, 0x0, 0x3f103160307030a,\n            0x4fa04de04ab0468, 0x5310520050b, 0x0, 0x10a0106010200fe,\n            0x11a01160112010e, 0x12a01260122011e, 0x13a01360132012e,\n            0x14a01460142013e, 0x15a01560152014e, 0x5e31b4d0162015e,\n            0x93305e5082c, 0x5e605e305d50568, 0x6ac0687067e0629,\n            0x734071a060706cf, 0x6af07a4077e0723, 0x88d085e082c083b,\n            0x682077006b2056b, 0x76c06b1060a095a, 0x930082708660860, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x761075e00000000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x606, 0x0, 0x0, 0x0, 0x1cad1c9e1bc3, 0x0, 0x0,\n            0x0, 0x1cf71ff320b02197, 0x208c253220811f17, 0x21e722f221fe1f1d,\n            0x21eb1f6921451f9d, 0x2560235c24261f93, 0x219d22cc200f2073,\n            0x25a01eef1ee921b3, 0x21ad20011efd20fa, 0x23f023d221992574,\n            0x329221b22bc2005, 0x20351f9f2366, 0x0, 0x1b5d1b551b511b69,\n            0x1b591b711b611b6d, 0x1b65, 0x0, 0x1ffd2147, 0x0, 0x0, 0x0,\n            0x26f51f0b1f031f07, 0x1f3b1f371f351f2d, 0x1f431f471f411f3f,\n            0x1f531f5126fd1e63, 0x1e6526f71f631f55, 0x1f7126fb1f691f59,\n            0x1f7b1f791f251f75, 0x1e691f8d1f8927b9, 0x1fa11f9f1f9b1f99,\n            0x1fb51faf1fad1e6b, 0x1fc31fbf1fbd1fbb, 0x1fe11fd91fd51fd3,\n            0x1fe71fe71fe71fe5, 0x1ff51ff122e42703, 0x20031fff1ffb2705,\n            0x20152013200d2017, 0x2023201f201d2019, 0x202d202920292027,\n            0x204b203920332031, 0x2043203f204d203d, 0x2057205520711f8f,\n            0x205b205d20532059, 0x2077207527072067, 0x209620852081207b,\n            0x209e209c270b2709, 0x1e6d20a4209a20a0, 0x20ac20ac20a81e6f,\n            0x20be20bc20ba270d, 0x20c820c6270f20c2, 0x20d21e7120cc2137,\n            0x271320de20e020da, 0x20e820ea271520e4, 0x1e7320f620f420ec,\n            0x21062104210220fe, 0x21171e7727171e75, 0x27cd211f211b2119,\n            0x2486271b271b212b, 0x27291e7921332133, 0x1e7b213f213b277d,\n            0x2157215321512149, 0x21611e7d1e7f215f, 0x216f216d2163271d,\n            0x21792177216f2171, 0x2183217f217d2181, 0x218f210b21872185,\n            0x21b121a7219f219b, 0x21b521a921af2723, 0x21c7272521c321b9,\n            0x21cb1e8121bd21c1, 0x1e8321cd21d321cf, 0x21f5272721df21db,\n            0x22091e8922032215, 0x1f6d1f6b1e851e87, 0x1ebb2470220b2217,\n            0x222b2221221f221d, 0x22351e8b27312227, 0x273522462242222f,\n            0x1e8d224c22392248, 0x225822522250224e, 0x22621e8f225c2737,\n            0x226a1e9122642739, 0x273b227822762270, 0x273f2288273d2711,\n            0x2298228a2292228e, 0x22a422a222a822a0, 0x229e274122ac22aa,\n            0x22c41e9322ba22b8, 0x22d222b4274322c2, 0x22de22d427472745,\n            0x22e01e9522da22dc, 0x26f922ec22e622e8, 0x274d22fa274922f4,\n            0x274f2314230a2304, 0x275327512320231e, 0x23381e972336232e,\n            0x234623441e991e99, 0x1e9b2352234c234a, 0x2757236c2755235e,\n            0x2759237a27192372, 0x1e9f1e9d275d275b, 0x2763275f27612396,\n            0x239c239c239a2765, 0x1ea523a21ea323a0, 0x23b023ac27691ea7,\n            0x23c8276b1ea923b6, 0x23e423d8276f276d, 0x23ec23ea23e81eab,\n            0x23f8277327732771, 0x2404240227751ead, 0x1eb1241227771eaf,\n            0x277b241e2416241a, 0x243424301eb3242a, 0x2781277f1eb5243c,\n            0x2785244827831eb7, 0x278724582454244e, 0x2466278b24622789,\n            0x247424721eb9272b, 0x278d20a624761ebd, 0x2486272f272d278f,\n            0x249e1ebf25942488, 0x24a21fa924a0249c, 0x279124aa24a624a4,\n            0x24b824b624ac24a8, 0x24ce24c424ba24ae, 0x24c224c024be24b4,\n            0x1ec1279527972793, 0x279f24d824d424d2, 0x1ec51ec3279924da,\n            0x24ea1ec7279d279b, 0x24f624f024ee24ec, 0x250024f824fa24f4,\n            0x1ec9250224fe24fc, 0x25101ecb25082506, 0x251a251827a12512,\n            0x27a31e6725201ecd, 0x25361ed11ecf27a5, 0x27a7255825502542,\n            0x2576257025642562, 0x257a257c26ff27ab, 0x258c258627012580,\n            0x25b225ac27af27ad, 0x25cc25b827b125b6, 0x25da25d025d425d2,\n            0x1ed325e227b325dc, 0x26021ed527b525e6, 0x27bb27b7260e20ee,\n            0x27bd26221ed91ed7, 0x262e262e27bf1edb, 0x1edd263e27c12632,\n            0x26542650264c2646, 0x266c265e27c31edf, 0x26741ee31ee12672,\n            0x27c927c71ee527c5, 0x26901ee7268627cb, 0x269e269a26962694,\n            0x27cf26a2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    //12288 bytes\n    enum canonMappingTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x20,\n            0x120], [0x100, 0x400, 0x1380], [0x302020202020100,\n            0x205020202020204, 0x602020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x1000000000000, 0x5000400030002, 0x6,\n            0x9000800070000, 0xc0000000b000a, 0x0, 0xe00000000000d, 0x0, 0x0,\n            0x1100000010000f, 0x130012, 0x16001500140000, 0x18000000170000,\n            0x1a000000190000, 0x0, 0x1c001b0000, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x1f001e, 0x0, 0x0, 0x23002200210020,\n            0x27002600250024, 0x28, 0x2b002a00000029, 0x2f002e002d002c, 0x30,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31000000000000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x34003300320000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x38003700360035, 0x3c003b003a0039, 0x3e003d, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x3f00000000, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x43004200410000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x47004600450044, 0x4b004a00490048, 0x4c, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x250012000f000c, 0x850000004f0045, 0xcb00a400a1009e,\n            0x13301240121011e, 0x1a0019d01880000, 0x1da01b601a3,\n            0x2730270026d0000, 0x2f30287, 0x33803250322031f, 0x398000003620358,\n            0x3de03b703b403b1, 0x446043a04370434, 0x4b404b1049c0000,\n            0x4ee04ca04b7, 0x58a058705840000, 0x61c0000060d059e,\n            0x33e002b033b0028, 0x38c00790380006d, 0x392007f038f007c,\n            0x3a2008f03950082, 0x3cd00ba00000000, 0x3db00c803d800c5,\n            0x3e400d103fb00e8, 0x41000fd040a00f7, 0x419010604130100, 0x41c0109,\n            0x440012a043d0127, 0x45c01490443012d, 0x130, 0x471015d0462014f,\n            0x170047701630000, 0x47a01660484, 0x185000000000000,\n            0x18e04a801940499, 0x4a2, 0x4e401d004d901c5, 0x4f801e4,\n            0x5450231052f021b, 0x54b023705350221, 0x56902550552023e,\n            0x57b026405580244, 0x572025b, 0x594027d058d0276, 0x5b4029d059b0284,\n            0x5e002c905b702a0, 0x61002f605f502de, 0x3110628030b0302,\n            0x6310314062e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50401f0,\n            0x0, 0x0, 0x2ac000000000000, 0x5c3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x13d036900560000, 0x2a304fb01e70450, 0x28e05a9029205ba,\n            0x28a05ad029605a5, 0x35b0048000005a1, 0x653064a03540041,\n            0x416010300000000, 0x522020e046b0157, 0x65f065c05250211, 0x465,\n            0x40700f4, 0x365005204960182, 0x656064d06500647, 0x36f005c036c0059,\n            0x3ea00d703e700d4, 0x456014304530140, 0x50101ed04fe01ea,\n            0x53b022705380224, 0x5c002a905bd02a6, 0x578026105660252,\n            0x425011200000000, 0x0, 0x351003e00000000, 0x4f101dd03f400e1,\n            0x4e701d304d101bd, 0x61602fc04ea01d6, 0x0, 0x0, 0x0,\n            0x66b00000010000d, 0x137, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x662, 0x0, 0x100000000, 0x0, 0x6450670063d0000,\n            0x72c06df06c3, 0x798077800000759, 0x8d1, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x781073500000000, 0x8c10867084707e9, 0x92f, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x92808ca00000000, 0x95f091f08fd, 0x9b4000000000000, 0x9b7,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x9c3000009cc09c6, 0x9ba000000000000, 0x0, 0x9ed09d809e4, 0x0, 0x0,\n            0x9de0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa200000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xa0500000a0e0a08, 0xa41000000000000, 0x0,\n            0xa2f0a1a0a26, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa470a4400000000, 0x0,\n            0x0, 0xa1109cf0000, 0x0, 0x0, 0x0, 0xa0209c009ff09bd,\n            0xa0b09c900000000, 0xa4d0a4a00000000, 0xa1709d50a1409d2,\n            0xa1d09db00000000, 0xa2909e70a2309e1, 0xa530a5000000000,\n            0xa2c09ea0a3e09fc, 0xa3509f30a3209f0, 0xa3809f6, 0xa3b09f9, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac10abe00000000,\n            0xaca0ac40ac7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xacd00000ad3, 0x0,\n            0x0, 0x0, 0xad0000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xae80000, 0x0, 0xaf10000, 0xaf4, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xadf0adc0ad90ad6, 0xaee0aeb0ae50ae2, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb00000000000000, 0xb03, 0x0,\n            0x0, 0x0, 0xafd00000afa0af7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xb12000000000000, 0xb1500000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xb0c0b090b060000, 0xb0f00000000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb1e000000000b21, 0xb24, 0x0, 0x0,\n            0x0, 0xb1b0b18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xb27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xb300b2a00000000, 0xb2d, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb33, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb36,\n            0xb40000000000000, 0xb3c0b3900000b43, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb4c0b4600000000,\n            0xb49, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb4f00000000, 0xb590b550b52, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb5f000000000000, 0x0, 0x0,\n            0xb620000, 0xb6500000000, 0xb68000000000000, 0x0, 0xb6b, 0x0, 0x0,\n            0xb5c0000, 0x0, 0xb6e000000000000, 0xb890b710000, 0xb8c, 0x0,\n            0xb740000, 0x0, 0x0, 0x0, 0xb7a000000000000, 0x0, 0x0, 0xb7d0000,\n            0xb8000000000, 0xb83000000000000, 0x0, 0xb86, 0x0, 0x0, 0xb770000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb8f00000000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb9200000000, 0xb9800000b95,\n            0xb9e00000b9b, 0xba100000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xba4000000000000, 0xba70000, 0xbb000000bad0baa, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x3830070037d006a, 0x389007603860073, 0x39f008c039b0088,\n            0x3ae009b03a50092, 0x3ab009803a80095, 0x3d400c103d000bd,\n            0x40100ee03fe00eb, 0x40400f103f700e4, 0x41f010c040d00fa,\n            0x422010f04280115, 0x42e011b042b0118, 0x4490136045f014c,\n            0x46e015a04680154, 0x47d016904740160, 0x48a01760480016c,\n            0x48d017904870173, 0x493017f0490017c, 0x4a50191049f018b,\n            0x4ab019704ae019a, 0x4d501c104cd01b9, 0x4e001cc04dc01c8,\n            0x52c021805290215, 0x53e022a0532021e, 0x54802340541022d,\n            0x55f024b05550241, 0x55b0247054e023a, 0x56c02580562024e,\n            0x581026a0575025e, 0x5dd02c6057e0267, 0x5e302cc05e602cf,\n            0x597028005900279, 0x5ec02d505e902d2, 0x5f202db05ef02d8,\n            0x5f802e105fb02e4, 0x60402ea060102e7, 0x61902ff060702ed,\n            0x6340317062b030e, 0x56f04310637031a, 0x6590000062205fe, 0x0,\n            0x35f004c0372005f, 0x3280015032c0019, 0x330001d03340021,\n            0x345003203750062, 0x34d003a0341002e, 0x379006603490036,\n            0x3e100ce03ed00da, 0x3be00ab03ca00b7, 0x3c600b303ba00a7,\n            0x3f000dd03c200af, 0x4590146044d013a, 0x4f501e1051b0207,\n            0x4ba01a604be01aa, 0x4c201ae04c601b2, 0x50b01f7051e020a,\n            0x51301ff050701f3, 0x5170203050f01fb, 0x5b1029a05da02c3,\n            0x5c602af05ca02b3, 0x5ce02b705d202bb, 0x60a02f005d602bf,\n            0x61f030506250308, 0x61302f9, 0x0, 0x81b07f9081807f6,\n            0x82d080b08240802, 0x69e067c069b0679, 0x6b0068e06a70685,\n            0x858084d0855084a, 0x85c0851, 0x6d406c906d106c6, 0x6d806cd,\n            0x89308710890086e, 0x8a50883089c087a, 0x70706e5070406e2,\n            0x71906f7071006ee, 0x8eb08dc08e808d9, 0x8f308e408ef08e0,\n            0x74a073b07470738, 0x7520743074e073f, 0x90e0903090b0900, 0x9120907,\n            0x76a075f0767075c, 0x76e0763, 0x949093a09460937, 0x9510942094d093e,\n            0x787000007840000, 0x78f0000078b0000, 0x98b096909880966,\n            0x99d097b09940972, 0x7c0079e07bd079b, 0x7d207b007c907a7,\n            0x847084407e907e2, 0x8c108be08670860, 0x91f091c08fd08fa, 0x95f0958,\n            0x81f07fd08360814, 0x831080f08280806, 0x6a2068006b90697,\n            0x6b4069206ab0689, 0x897087508ae088c, 0x8a9088708a0087e,\n            0x70b06e907220700, 0x71d06fb071406f2, 0x98f096d09a60984,\n            0x9a1097f09980976, 0x7c407a207db07b9, 0x7d607b407cd07ab,\n            0x84107e507f007f3, 0x83d083a000007ec, 0x670066d06730676,\n            0x8bc000006bd, 0x8b9086306400000, 0x8b508b20000086a,\n            0x6df06dc06c306c0, 0xbb90bb60bb30726, 0x8d108cd08c408c7,\n            0x8d508f700000000, 0x72c0729072f0732, 0xbc20bbf0bbc0000,\n            0x92f092b09220925, 0x933095509190916, 0x7780775077b077e,\n            0x31d063d063a0772, 0x9b1095b00000000, 0x9ad09aa00000962,\n            0x798079507590756, 0x64307df, 0xbc70bc5, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x79300000000, 0x4f015200000000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xbcc0bc900000000, 0x0, 0x0, 0x0, 0x0, 0xbcf00000000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xbd50bd80bd20000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbdb, 0xbde0000,\n            0xbe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbe700000be4, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xbea0000, 0xbf0000000000bed, 0xbf30000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xbf900000006, 0x0, 0x0, 0x900030bf60000, 0xbff0bfc,\n            0xc050c02, 0xc0b0c08, 0x0, 0xc110c0e, 0xc1d0c1a, 0xc230c20, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc350c320c2f0c2c, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xc290c260c170c14, 0x0, 0xc3b0c3800000000, 0xc410c3e, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xc490c470000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xc44, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xc5100000c4e, 0xc5700000c54, 0xc5d00000c5a, 0xc6300000c60,\n            0xc6900000c66, 0xc6f00000c6c, 0xc7500000c720000, 0xc780000, 0x0,\n            0xc8100000c7e0c7b, 0xc8a0c8700000c84, 0xc900c8d0000, 0xc960c93,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xc4b, 0x0, 0xc9900000000, 0x0, 0x0, 0x0,\n            0xca200000c9f, 0xca800000ca5, 0xcae00000cab, 0xcb400000cb1,\n            0xcba00000cb7, 0xcc000000cbd, 0xcc600000cc30000, 0xcc90000, 0x0,\n            0xcd200000ccf0ccc, 0xcdb0cd800000cd5, 0xce10cde0000, 0xce70ce4,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xcea000000000c9c, 0xcf30cf00ced,\n            0xcf600000000, 0x124b125d0fb71241, 0x13270e290d831043,\n            0xe4f12930e991327, 0x116710cd0f550e97, 0x1279121511fd11e3,\n            0x109d106910190feb, 0xd8d12f3128911c7, 0x11e110790ff50e1d,\n            0x11d910510edb1309, 0x120311890f65121d, 0x108d10250fbd0eff,\n            0xe050dd90d9d127d, 0x10d310770ff10f95, 0x125911e711dd1171,\n            0x10e9130712fb12cf, 0x12a111b9114d1107, 0xf0b0e87122f130b,\n            0x10ed1083117d112f, 0xecb0e8512cb1249, 0x11471047102f0fed,\n            0x117f0e0312b11159, 0x114f11150ddd0ddf, 0xf67123d12b511c5,\n            0xebb0d8712350feb, 0xe1110c110950f27, 0xd7f0f1b0da510f1,\n            0xe2311450f9d1011, 0x122711c910d70e7d, 0xf6f100d126d1005,\n            0xd9110bf0f7b11a5, 0x113d0fdb0ddb0dc3, 0xe091291122d1195,\n            0xfa10f070e9f0e37, 0x12f712ab10f31053, 0xfb50df91313130d,\n            0xf490ef312690ffd, 0x106d104b0f910f57, 0x11791153111110af,\n            0x12a3127111cd1261, 0x10670e410dfb0de9, 0xf230efd1227120b,\n            0x1091112d10030f77, 0xee50ebb0e670d97, 0x116b10a9109b0f29,\n            0x12d112c912951175, 0x128d110f0d9f12dd, 0xdb10d8f0f3512c1,\n            0xfeb0f9f0ec70ebd, 0x127711d310cb1073, 0xdf712af0fad1323,\n            0x103b10210fd10fcb, 0x114310e710bd10a1, 0x12b70f5d0dc512e3,\n            0x126310310ed70da9, 0x10950fd50f390f17, 0xecf0e310deb12bb,\n            0x10150fe10fc30fa7, 0x120d116310c3109f, 0xe1312c5128f1213,\n            0x10b110750e33103d, 0x130f12ff12bd11db, 0x1121118b102d0fcf,\n            0x1063108b11331125, 0xded11ad0d93123b, 0x11390f690ef50de7,\n            0x12670fb3101b0eb5, 0xf03122112b31205, 0xe590db5, 0xfab00000e7b,\n            0x10cf108f0de10000, 0x110d1105110310f5, 0x116d113512d3,\n            0x1233000011df, 0x128312730000, 0x12e912e700000000,\n            0x12bf127f130512eb, 0xe010db90db30da1, 0xe5f0e530e170e07,\n            0xecd0e7f0e790e63, 0xf470f430f2f0ed1, 0xfaf0fa30f970f53,\n            0x1049103510270fdd, 0x10eb10a3107d106f, 0x10fd10f910fb10f7,\n            0x110b1109110110ff, 0x11531127111d1117, 0x11731161115b1157,\n            0x11cb11971197118d, 0x1239123712231219, 0x1273126f124f124d,\n            0xf2b12e112d912c7, 0x119313be, 0xd9b0dc10dd70d81,\n            0xe0b0dff0dc90db7, 0xe5d0e510e490e53, 0xe9b0e950e830e7b,\n            0xf050f010eb10ea9, 0xf3f0f330f1d0f13, 0xf530f410f470f37,\n            0xf890f850f7f0f5f, 0xfbf0fbd0fab0f99, 0x102110050fff0fc7,\n            0x1057104910411045, 0x1089107f10e3106f, 0x10b910b510ab108f,\n            0x10d110cf10c910c7, 0x10ef10dd10df10d5, 0x114911311127111f,\n            0x11af1173115f1153, 0x121f121b11f911c3, 0x122b123312291223,\n            0x1239123112351237, 0x12751265124f123f, 0x12c712b91299128b,\n            0x12db12d912d512d3, 0x1394132712f912e1, 0xd370d2313a61392,\n            0x141c13ec13da0d39, 0x13251321, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xabb00000a7a0000,\n            0x0, 0x0, 0xab50ab200000000, 0xa590a560aae0aaa, 0xa680a650a5f0a5c,\n            0xa740a710a6b, 0xa830a800a7d0a77, 0xa8c00000a89, 0xa9500000a920a8f,\n            0xaa10a9e00000a98, 0xa6e0ab80aa70aa4, 0xa9b0a860a62, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x132900000000, 0x132c, 0x0, 0x0, 0x132f000000000000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x1335133200000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x133b133800000000, 0x134a13461342133e,\n            0x134e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1352000000000000,\n            0x135913601355135d, 0x1364, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13680d8b0d850d89,\n            0xda70da30da10d99, 0xdaf0db30dad0dab, 0xdbb0db913700cf9,\n            0xcfb136a0dc70dbd, 0xdd1136e0dcb0dbf, 0xdd70dd50d950dd3,\n            0xcff0de50de3142c, 0xdf50df30df10def, 0xe070e010dff0d01,\n            0xe110e0f0e0d0e0b, 0xe1b0e190e170e15, 0xe210e210e210e1f,\n            0xe270e25105d1376, 0xe2f0e2d0e2b1378, 0xe3b0e390e350e3d,\n            0xe470e450e430e3f, 0xe510e4d0e4d0e4b, 0xe690e5b0e570e55,\n            0xe650e610e6b0e5f, 0xe710e6f0e890de7, 0xe750e770e6d0e73,\n            0xe8d0e8b137a0e81, 0xe9d0e930e910e8f, 0xea50ea3137e137c,\n            0xd030eab0ea10ea7, 0xeb30eb30eaf0d05, 0xebb0eb90eb71380,\n            0xec30ec113820ebf, 0xec90d070ec50f0f, 0x13860ed30ed50ed1,\n            0xedd0edf13880ed9, 0xd090ee90ee70ee1, 0xef10eef0eed0eeb,\n            0xef70d0d138a0d0b, 0x14400eff0efb0ef9, 0x118f138e138e0f09,\n            0x139c0d0f0f0d0f0d, 0xd110f150f1113f0, 0xf250f210f1f0f19,\n            0xf2f0d130d150f2d, 0xf3d0f3b0f311390, 0xf470f450f3d0f3f,\n            0xf510f4d0f4b0f4f, 0xf5b0f590f550f53, 0xf730f6b0f630f61,\n            0xf750f6d0f711396, 0xf8713980f830f79, 0xf8b0d170f7d0f81,\n            0xd190f8d0f930f8f, 0xfa5139a0f9b0f97, 0xfaf0d1f0fa90fb9,\n            0xdcf0dcd0d1b0d1d, 0xd5111810fb10fbb, 0xfc90fc10fbf0fbd,\n            0xfd30d2113a40fc5, 0x13a80fdd0fd90fcd, 0xd230fe30fd70fdf,\n            0xfef0fe90fe70fe5, 0xff70d250ff313aa, 0xffb0d270ff913ac,\n            0x13ae100710051001, 0x13b2100913b01384, 0x1017100b1013100f,\n            0x102310211027101f, 0x101d13b4102b1029, 0x10410d2910391037,\n            0x104d103313b6103f, 0x1059104f13ba13b8, 0x105b0d2b10551057,\n            0x136c1065105f1061, 0x13c0107113bc106b, 0x13c21081107f107b,\n            0x13c613c410871085, 0x10990d2d10971093, 0x10a710a50d2f0d2f,\n            0xd3110b310ad10ab, 0x13ca10bb13c810b7, 0x13cc10c5138c10c1,\n            0xd350d3313d013ce, 0x13d613d213d410d5, 0x10db10db10d913d8,\n            0xd3b10e10d3910df, 0x10e910e513dc0d3d, 0x10ff13de0d3f10ef,\n            0x1113110d13e213e0, 0x111b111911170d41, 0x112313e613e613e4,\n            0x112b112913e80d43, 0xd47113713ea0d45, 0x13ee1141113b113f,\n            0x115511510d49114b, 0x13f413f20d4b115d, 0x13f8116513f60d4d,\n            0x13fa1173116f1169, 0x117b13fe117713fc, 0x118511830d4f139e,\n            0x14000ead11870d53, 0x118f13a213a01402, 0x119b0d55126b1191,\n            0x119f0dfd119d1199, 0x140411a711a311a1, 0x11b511b311a911a5,\n            0x11cb11c111b711ab, 0x11bf11bd11bb11b1, 0xd571408140a1406,\n            0x141211d511d111cf, 0xd5b0d59140c11d7, 0x11e50d5d1410140e,\n            0x11ef11eb11e911e7, 0x11f911f111f311ed, 0xd5f11fb11f711f5,\n            0x12070d61120111ff, 0x1211120f14141209, 0x14160cfd12170d63,\n            0x12250d670d651418, 0x141a1243123f1231, 0x1253125112471245,\n            0x125512571372141e, 0x1265125f1374125b, 0x1281127b14221420,\n            0x1297128714241285, 0x12a5129b129f129d, 0xd6912a9142612a7,\n            0x12c30d6b142812ad, 0x142e142a12cd0ee3, 0x143012d70d6f0d6d,\n            0x12db12db14320d71, 0xd7312e5143412df, 0x12f512f112ef12ed,\n            0x12fd12f914360d75, 0x13030d790d771301, 0x143c143a0d7b1438,\n            0x13150d7d1311143e, 0x131d131b13191317, 0x1442131f, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    @property\n    {\n        private alias _IDCA = immutable(dchar[]);\n        _IDCA decompCanonTable()\n        {\n            static _IDCA t = [\n                0x0, 0x3b, 0x0, 0x3c, 0x338, 0x0, 0x3d, 0x338, 0x0, 0x3e,\n                0x338, 0x0, 0x41, 0x300, 0x0, 0x41, 0x301, 0x0, 0x41, 0x302,\n                0x0, 0x41, 0x302, 0x300, 0x0, 0x41, 0x302, 0x301, 0x0, 0x41,\n                0x302, 0x303, 0x0, 0x41, 0x302, 0x309, 0x0, 0x41, 0x303, 0x0,\n                0x41, 0x304, 0x0, 0x41, 0x306, 0x0, 0x41, 0x306, 0x300, 0x0,\n                0x41, 0x306, 0x301, 0x0, 0x41, 0x306, 0x303, 0x0, 0x41, 0x306,\n                0x309, 0x0, 0x41, 0x307, 0x0, 0x41, 0x307, 0x304, 0x0, 0x41,\n                0x308, 0x0, 0x41, 0x308, 0x304, 0x0, 0x41, 0x309, 0x0, 0x41,\n                0x30a, 0x0, 0x41, 0x30a, 0x301, 0x0, 0x41, 0x30c, 0x0, 0x41,\n                0x30f, 0x0, 0x41, 0x311, 0x0, 0x41, 0x323, 0x0, 0x41, 0x323,\n                0x302, 0x0, 0x41, 0x323, 0x306, 0x0, 0x41, 0x325, 0x0, 0x41,\n                0x328, 0x0, 0x42, 0x307, 0x0, 0x42, 0x323, 0x0, 0x42, 0x331,\n                0x0, 0x43, 0x301, 0x0, 0x43, 0x302, 0x0, 0x43, 0x307, 0x0,\n                0x43, 0x30c, 0x0, 0x43, 0x327, 0x0, 0x43, 0x327, 0x301, 0x0,\n                0x44, 0x307, 0x0, 0x44, 0x30c, 0x0, 0x44, 0x323, 0x0, 0x44,\n                0x327, 0x0, 0x44, 0x32d, 0x0, 0x44, 0x331, 0x0, 0x45, 0x300,\n                0x0, 0x45, 0x301, 0x0, 0x45, 0x302, 0x0, 0x45, 0x302, 0x300,\n                0x0, 0x45, 0x302, 0x301, 0x0, 0x45, 0x302, 0x303, 0x0, 0x45,\n                0x302, 0x309, 0x0, 0x45, 0x303, 0x0, 0x45, 0x304, 0x0, 0x45,\n                0x304, 0x300, 0x0, 0x45, 0x304, 0x301, 0x0, 0x45, 0x306, 0x0,\n                0x45, 0x307, 0x0, 0x45, 0x308, 0x0, 0x45, 0x309, 0x0, 0x45,\n                0x30c, 0x0, 0x45, 0x30f, 0x0, 0x45, 0x311, 0x0, 0x45, 0x323,\n                0x0, 0x45, 0x323, 0x302, 0x0, 0x45, 0x327, 0x0, 0x45, 0x327,\n                0x306, 0x0, 0x45, 0x328, 0x0, 0x45, 0x32d, 0x0, 0x45, 0x330,\n                0x0, 0x46, 0x307, 0x0, 0x47, 0x301, 0x0, 0x47, 0x302, 0x0,\n                0x47, 0x304, 0x0, 0x47, 0x306, 0x0, 0x47, 0x307, 0x0, 0x47,\n                0x30c, 0x0, 0x47, 0x327, 0x0, 0x48, 0x302, 0x0, 0x48, 0x307,\n                0x0, 0x48, 0x308, 0x0, 0x48, 0x30c, 0x0, 0x48, 0x323, 0x0,\n                0x48, 0x327, 0x0, 0x48, 0x32e, 0x0, 0x49, 0x300, 0x0, 0x49,\n                0x301, 0x0, 0x49, 0x302, 0x0, 0x49, 0x303, 0x0, 0x49, 0x304,\n                0x0, 0x49, 0x306, 0x0, 0x49, 0x307, 0x0, 0x49, 0x308, 0x0,\n                0x49, 0x308, 0x301, 0x0, 0x49, 0x309, 0x0, 0x49, 0x30c, 0x0,\n                0x49, 0x30f, 0x0, 0x49, 0x311, 0x0, 0x49, 0x323, 0x0, 0x49,\n                0x328, 0x0, 0x49, 0x330, 0x0, 0x4a, 0x302, 0x0, 0x4b, 0x0,\n                0x4b, 0x301, 0x0, 0x4b, 0x30c, 0x0, 0x4b, 0x323, 0x0, 0x4b,\n                0x327, 0x0, 0x4b, 0x331, 0x0, 0x4c, 0x301, 0x0, 0x4c, 0x30c,\n                0x0, 0x4c, 0x323, 0x0, 0x4c, 0x323, 0x304, 0x0, 0x4c, 0x327,\n                0x0, 0x4c, 0x32d, 0x0, 0x4c, 0x331, 0x0, 0x4d, 0x301, 0x0,\n                0x4d, 0x307, 0x0, 0x4d, 0x323, 0x0, 0x4e, 0x300, 0x0, 0x4e,\n                0x301, 0x0, 0x4e, 0x303, 0x0, 0x4e, 0x307, 0x0, 0x4e, 0x30c,\n                0x0, 0x4e, 0x323, 0x0, 0x4e, 0x327, 0x0, 0x4e, 0x32d, 0x0,\n                0x4e, 0x331, 0x0, 0x4f, 0x300, 0x0, 0x4f, 0x301, 0x0, 0x4f,\n                0x302, 0x0, 0x4f, 0x302, 0x300, 0x0, 0x4f, 0x302, 0x301, 0x0,\n                0x4f, 0x302, 0x303, 0x0, 0x4f, 0x302, 0x309, 0x0, 0x4f, 0x303,\n                0x0, 0x4f, 0x303, 0x301, 0x0, 0x4f, 0x303, 0x304, 0x0, 0x4f,\n                0x303, 0x308, 0x0, 0x4f, 0x304, 0x0, 0x4f, 0x304, 0x300, 0x0,\n                0x4f, 0x304, 0x301, 0x0, 0x4f, 0x306, 0x0, 0x4f, 0x307, 0x0,\n                0x4f, 0x307, 0x304, 0x0, 0x4f, 0x308, 0x0, 0x4f, 0x308, 0x304,\n                0x0, 0x4f, 0x309, 0x0, 0x4f, 0x30b, 0x0, 0x4f, 0x30c, 0x0,\n                0x4f, 0x30f, 0x0, 0x4f, 0x311, 0x0, 0x4f, 0x31b, 0x0, 0x4f,\n                0x31b, 0x300, 0x0, 0x4f, 0x31b, 0x301, 0x0, 0x4f, 0x31b, 0x303,\n                0x0, 0x4f, 0x31b, 0x309, 0x0, 0x4f, 0x31b, 0x323, 0x0, 0x4f,\n                0x323, 0x0, 0x4f, 0x323, 0x302, 0x0, 0x4f, 0x328, 0x0, 0x4f,\n                0x328, 0x304, 0x0, 0x50, 0x301, 0x0, 0x50, 0x307, 0x0, 0x52,\n                0x301, 0x0, 0x52, 0x307, 0x0, 0x52, 0x30c, 0x0, 0x52, 0x30f,\n                0x0, 0x52, 0x311, 0x0, 0x52, 0x323, 0x0, 0x52, 0x323, 0x304,\n                0x0, 0x52, 0x327, 0x0, 0x52, 0x331, 0x0, 0x53, 0x301, 0x0,\n                0x53, 0x301, 0x307, 0x0, 0x53, 0x302, 0x0, 0x53, 0x307, 0x0,\n                0x53, 0x30c, 0x0, 0x53, 0x30c, 0x307, 0x0, 0x53, 0x323, 0x0,\n                0x53, 0x323, 0x307, 0x0, 0x53, 0x326, 0x0, 0x53, 0x327, 0x0,\n                0x54, 0x307, 0x0, 0x54, 0x30c, 0x0, 0x54, 0x323, 0x0, 0x54,\n                0x326, 0x0, 0x54, 0x327, 0x0, 0x54, 0x32d, 0x0, 0x54, 0x331,\n                0x0, 0x55, 0x300, 0x0, 0x55, 0x301, 0x0, 0x55, 0x302, 0x0,\n                0x55, 0x303, 0x0, 0x55, 0x303, 0x301, 0x0, 0x55, 0x304, 0x0,\n                0x55, 0x304, 0x308, 0x0, 0x55, 0x306, 0x0, 0x55, 0x308, 0x0,\n                0x55, 0x308, 0x300, 0x0, 0x55, 0x308, 0x301, 0x0, 0x55, 0x308,\n                0x304, 0x0, 0x55, 0x308, 0x30c, 0x0, 0x55, 0x309, 0x0, 0x55,\n                0x30a, 0x0, 0x55, 0x30b, 0x0, 0x55, 0x30c, 0x0, 0x55, 0x30f,\n                0x0, 0x55, 0x311, 0x0, 0x55, 0x31b, 0x0, 0x55, 0x31b, 0x300,\n                0x0, 0x55, 0x31b, 0x301, 0x0, 0x55, 0x31b, 0x303, 0x0, 0x55,\n                0x31b, 0x309, 0x0, 0x55, 0x31b, 0x323, 0x0, 0x55, 0x323, 0x0,\n                0x55, 0x324, 0x0, 0x55, 0x328, 0x0, 0x55, 0x32d, 0x0, 0x55,\n                0x330, 0x0, 0x56, 0x303, 0x0, 0x56, 0x323, 0x0, 0x57, 0x300,\n                0x0, 0x57, 0x301, 0x0, 0x57, 0x302, 0x0, 0x57, 0x307, 0x0,\n                0x57, 0x308, 0x0, 0x57, 0x323, 0x0, 0x58, 0x307, 0x0, 0x58,\n                0x308, 0x0, 0x59, 0x300, 0x0, 0x59, 0x301, 0x0, 0x59, 0x302,\n                0x0, 0x59, 0x303, 0x0, 0x59, 0x304, 0x0, 0x59, 0x307, 0x0,\n                0x59, 0x308, 0x0, 0x59, 0x309, 0x0, 0x59, 0x323, 0x0, 0x5a,\n                0x301, 0x0, 0x5a, 0x302, 0x0, 0x5a, 0x307, 0x0, 0x5a, 0x30c,\n                0x0, 0x5a, 0x323, 0x0, 0x5a, 0x331, 0x0, 0x60, 0x0, 0x61,\n                0x300, 0x0, 0x61, 0x301, 0x0, 0x61, 0x302, 0x0, 0x61, 0x302,\n                0x300, 0x0, 0x61, 0x302, 0x301, 0x0, 0x61, 0x302, 0x303, 0x0,\n                0x61, 0x302, 0x309, 0x0, 0x61, 0x303, 0x0, 0x61, 0x304, 0x0,\n                0x61, 0x306, 0x0, 0x61, 0x306, 0x300, 0x0, 0x61, 0x306, 0x301,\n                0x0, 0x61, 0x306, 0x303, 0x0, 0x61, 0x306, 0x309, 0x0, 0x61,\n                0x307, 0x0, 0x61, 0x307, 0x304, 0x0, 0x61, 0x308, 0x0, 0x61,\n                0x308, 0x304, 0x0, 0x61, 0x309, 0x0, 0x61, 0x30a, 0x0, 0x61,\n                0x30a, 0x301, 0x0, 0x61, 0x30c, 0x0, 0x61, 0x30f, 0x0, 0x61,\n                0x311, 0x0, 0x61, 0x323, 0x0, 0x61, 0x323, 0x302, 0x0, 0x61,\n                0x323, 0x306, 0x0, 0x61, 0x325, 0x0, 0x61, 0x328, 0x0, 0x62,\n                0x307, 0x0, 0x62, 0x323, 0x0, 0x62, 0x331, 0x0, 0x63, 0x301,\n                0x0, 0x63, 0x302, 0x0, 0x63, 0x307, 0x0, 0x63, 0x30c, 0x0,\n                0x63, 0x327, 0x0, 0x63, 0x327, 0x301, 0x0, 0x64, 0x307, 0x0,\n                0x64, 0x30c, 0x0, 0x64, 0x323, 0x0, 0x64, 0x327, 0x0, 0x64,\n                0x32d, 0x0, 0x64, 0x331, 0x0, 0x65, 0x300, 0x0, 0x65, 0x301,\n                0x0, 0x65, 0x302, 0x0, 0x65, 0x302, 0x300, 0x0, 0x65, 0x302,\n                0x301, 0x0, 0x65, 0x302, 0x303, 0x0, 0x65, 0x302, 0x309, 0x0,\n                0x65, 0x303, 0x0, 0x65, 0x304, 0x0, 0x65, 0x304, 0x300, 0x0,\n                0x65, 0x304, 0x301, 0x0, 0x65, 0x306, 0x0, 0x65, 0x307, 0x0,\n                0x65, 0x308, 0x0, 0x65, 0x309, 0x0, 0x65, 0x30c, 0x0, 0x65,\n                0x30f, 0x0, 0x65, 0x311, 0x0, 0x65, 0x323, 0x0, 0x65, 0x323,\n                0x302, 0x0, 0x65, 0x327, 0x0, 0x65, 0x327, 0x306, 0x0, 0x65,\n                0x328, 0x0, 0x65, 0x32d, 0x0, 0x65, 0x330, 0x0, 0x66, 0x307,\n                0x0, 0x67, 0x301, 0x0, 0x67, 0x302, 0x0, 0x67, 0x304, 0x0,\n                0x67, 0x306, 0x0, 0x67, 0x307, 0x0, 0x67, 0x30c, 0x0, 0x67,\n                0x327, 0x0, 0x68, 0x302, 0x0, 0x68, 0x307, 0x0, 0x68, 0x308,\n                0x0, 0x68, 0x30c, 0x0, 0x68, 0x323, 0x0, 0x68, 0x327, 0x0,\n                0x68, 0x32e, 0x0, 0x68, 0x331, 0x0, 0x69, 0x300, 0x0, 0x69,\n                0x301, 0x0, 0x69, 0x302, 0x0, 0x69, 0x303, 0x0, 0x69, 0x304,\n                0x0, 0x69, 0x306, 0x0, 0x69, 0x308, 0x0, 0x69, 0x308, 0x301,\n                0x0, 0x69, 0x309, 0x0, 0x69, 0x30c, 0x0, 0x69, 0x30f, 0x0,\n                0x69, 0x311, 0x0, 0x69, 0x323, 0x0, 0x69, 0x328, 0x0, 0x69,\n                0x330, 0x0, 0x6a, 0x302, 0x0, 0x6a, 0x30c, 0x0, 0x6b, 0x301,\n                0x0, 0x6b, 0x30c, 0x0, 0x6b, 0x323, 0x0, 0x6b, 0x327, 0x0,\n                0x6b, 0x331, 0x0, 0x6c, 0x301, 0x0, 0x6c, 0x30c, 0x0, 0x6c,\n                0x323, 0x0, 0x6c, 0x323, 0x304, 0x0, 0x6c, 0x327, 0x0, 0x6c,\n                0x32d, 0x0, 0x6c, 0x331, 0x0, 0x6d, 0x301, 0x0, 0x6d, 0x307,\n                0x0, 0x6d, 0x323, 0x0, 0x6e, 0x300, 0x0, 0x6e, 0x301, 0x0,\n                0x6e, 0x303, 0x0, 0x6e, 0x307, 0x0, 0x6e, 0x30c, 0x0, 0x6e,\n                0x323, 0x0, 0x6e, 0x327, 0x0, 0x6e, 0x32d, 0x0, 0x6e, 0x331,\n                0x0, 0x6f, 0x300, 0x0, 0x6f, 0x301, 0x0, 0x6f, 0x302, 0x0,\n                0x6f, 0x302, 0x300, 0x0, 0x6f, 0x302, 0x301, 0x0, 0x6f, 0x302,\n                0x303, 0x0, 0x6f, 0x302, 0x309, 0x0, 0x6f, 0x303, 0x0, 0x6f,\n                0x303, 0x301, 0x0, 0x6f, 0x303, 0x304, 0x0, 0x6f, 0x303, 0x308,\n                0x0, 0x6f, 0x304, 0x0, 0x6f, 0x304, 0x300, 0x0, 0x6f, 0x304,\n                0x301, 0x0, 0x6f, 0x306, 0x0, 0x6f, 0x307, 0x0, 0x6f, 0x307,\n                0x304, 0x0, 0x6f, 0x308, 0x0, 0x6f, 0x308, 0x304, 0x0, 0x6f,\n                0x309, 0x0, 0x6f, 0x30b, 0x0, 0x6f, 0x30c, 0x0, 0x6f, 0x30f,\n                0x0, 0x6f, 0x311, 0x0, 0x6f, 0x31b, 0x0, 0x6f, 0x31b, 0x300,\n                0x0, 0x6f, 0x31b, 0x301, 0x0, 0x6f, 0x31b, 0x303, 0x0, 0x6f,\n                0x31b, 0x309, 0x0, 0x6f, 0x31b, 0x323, 0x0, 0x6f, 0x323, 0x0,\n                0x6f, 0x323, 0x302, 0x0, 0x6f, 0x328, 0x0, 0x6f, 0x328, 0x304,\n                0x0, 0x70, 0x301, 0x0, 0x70, 0x307, 0x0, 0x72, 0x301, 0x0,\n                0x72, 0x307, 0x0, 0x72, 0x30c, 0x0, 0x72, 0x30f, 0x0, 0x72,\n                0x311, 0x0, 0x72, 0x323, 0x0, 0x72, 0x323, 0x304, 0x0, 0x72,\n                0x327, 0x0, 0x72, 0x331, 0x0, 0x73, 0x301, 0x0, 0x73, 0x301,\n                0x307, 0x0, 0x73, 0x302, 0x0, 0x73, 0x307, 0x0, 0x73, 0x30c,\n                0x0, 0x73, 0x30c, 0x307, 0x0, 0x73, 0x323, 0x0, 0x73, 0x323,\n                0x307, 0x0, 0x73, 0x326, 0x0, 0x73, 0x327, 0x0, 0x74, 0x307,\n                0x0, 0x74, 0x308, 0x0, 0x74, 0x30c, 0x0, 0x74, 0x323, 0x0,\n                0x74, 0x326, 0x0, 0x74, 0x327, 0x0, 0x74, 0x32d, 0x0, 0x74,\n                0x331, 0x0, 0x75, 0x300, 0x0, 0x75, 0x301, 0x0, 0x75, 0x302,\n                0x0, 0x75, 0x303, 0x0, 0x75, 0x303, 0x301, 0x0, 0x75, 0x304,\n                0x0, 0x75, 0x304, 0x308, 0x0, 0x75, 0x306, 0x0, 0x75, 0x308,\n                0x0, 0x75, 0x308, 0x300, 0x0, 0x75, 0x308, 0x301, 0x0, 0x75,\n                0x308, 0x304, 0x0, 0x75, 0x308, 0x30c, 0x0, 0x75, 0x309, 0x0,\n                0x75, 0x30a, 0x0, 0x75, 0x30b, 0x0, 0x75, 0x30c, 0x0, 0x75,\n                0x30f, 0x0, 0x75, 0x311, 0x0, 0x75, 0x31b, 0x0, 0x75, 0x31b,\n                0x300, 0x0, 0x75, 0x31b, 0x301, 0x0, 0x75, 0x31b, 0x303, 0x0,\n                0x75, 0x31b, 0x309, 0x0, 0x75, 0x31b, 0x323, 0x0, 0x75, 0x323,\n                0x0, 0x75, 0x324, 0x0, 0x75, 0x328, 0x0, 0x75, 0x32d, 0x0,\n                0x75, 0x330, 0x0, 0x76, 0x303, 0x0, 0x76, 0x323, 0x0, 0x77,\n                0x300, 0x0, 0x77, 0x301, 0x0, 0x77, 0x302, 0x0, 0x77, 0x307,\n                0x0, 0x77, 0x308, 0x0, 0x77, 0x30a, 0x0, 0x77, 0x323, 0x0,\n                0x78, 0x307, 0x0, 0x78, 0x308, 0x0, 0x79, 0x300, 0x0, 0x79,\n                0x301, 0x0, 0x79, 0x302, 0x0, 0x79, 0x303, 0x0, 0x79, 0x304,\n                0x0, 0x79, 0x307, 0x0, 0x79, 0x308, 0x0, 0x79, 0x309, 0x0,\n                0x79, 0x30a, 0x0, 0x79, 0x323, 0x0, 0x7a, 0x301, 0x0, 0x7a,\n                0x302, 0x0, 0x7a, 0x307, 0x0, 0x7a, 0x30c, 0x0, 0x7a, 0x323,\n                0x0, 0x7a, 0x331, 0x0, 0xa8, 0x300, 0x0, 0xa8, 0x301, 0x0,\n                0xa8, 0x342, 0x0, 0xb4, 0x0, 0xb7, 0x0, 0xc6, 0x301, 0x0, 0xc6,\n                0x304, 0x0, 0xd8, 0x301, 0x0, 0xe6, 0x301, 0x0, 0xe6, 0x304,\n                0x0, 0xf8, 0x301, 0x0, 0x17f, 0x307, 0x0, 0x1b7, 0x30c, 0x0,\n                0x292, 0x30c, 0x0, 0x2b9, 0x0, 0x300, 0x0, 0x301, 0x0, 0x308,\n                0x301, 0x0, 0x313, 0x0, 0x391, 0x300, 0x0, 0x391, 0x301, 0x0,\n                0x391, 0x304, 0x0, 0x391, 0x306, 0x0, 0x391, 0x313, 0x0, 0x391,\n                0x313, 0x300, 0x0, 0x391, 0x313, 0x300, 0x345, 0x0, 0x391,\n                0x313, 0x301, 0x0, 0x391, 0x313, 0x301, 0x345, 0x0, 0x391,\n                0x313, 0x342, 0x0, 0x391, 0x313, 0x342, 0x345, 0x0, 0x391,\n                0x313, 0x345, 0x0, 0x391, 0x314, 0x0, 0x391, 0x314, 0x300, 0x0,\n                0x391, 0x314, 0x300, 0x345, 0x0, 0x391, 0x314, 0x301, 0x0,\n                0x391, 0x314, 0x301, 0x345, 0x0, 0x391, 0x314, 0x342, 0x0,\n                0x391, 0x314, 0x342, 0x345, 0x0, 0x391, 0x314, 0x345, 0x0,\n                0x391, 0x345, 0x0, 0x395, 0x300, 0x0, 0x395, 0x301, 0x0, 0x395,\n                0x313, 0x0, 0x395, 0x313, 0x300, 0x0, 0x395, 0x313, 0x301, 0x0,\n                0x395, 0x314, 0x0, 0x395, 0x314, 0x300, 0x0, 0x395, 0x314,\n                0x301, 0x0, 0x397, 0x300, 0x0, 0x397, 0x301, 0x0, 0x397, 0x313,\n                0x0, 0x397, 0x313, 0x300, 0x0, 0x397, 0x313, 0x300, 0x345, 0x0,\n                0x397, 0x313, 0x301, 0x0, 0x397, 0x313, 0x301, 0x345, 0x0,\n                0x397, 0x313, 0x342, 0x0, 0x397, 0x313, 0x342, 0x345, 0x0,\n                0x397, 0x313, 0x345, 0x0, 0x397, 0x314, 0x0, 0x397, 0x314,\n                0x300, 0x0, 0x397, 0x314, 0x300, 0x345, 0x0, 0x397, 0x314,\n                0x301, 0x0, 0x397, 0x314, 0x301, 0x345, 0x0, 0x397, 0x314,\n                0x342, 0x0, 0x397, 0x314, 0x342, 0x345, 0x0, 0x397, 0x314,\n                0x345, 0x0, 0x397, 0x345, 0x0, 0x399, 0x300, 0x0, 0x399, 0x301,\n                0x0, 0x399, 0x304, 0x0, 0x399, 0x306, 0x0, 0x399, 0x308, 0x0,\n                0x399, 0x313, 0x0, 0x399, 0x313, 0x300, 0x0, 0x399, 0x313,\n                0x301, 0x0, 0x399, 0x313, 0x342, 0x0, 0x399, 0x314, 0x0, 0x399,\n                0x314, 0x300, 0x0, 0x399, 0x314, 0x301, 0x0, 0x399, 0x314,\n                0x342, 0x0, 0x39f, 0x300, 0x0, 0x39f, 0x301, 0x0, 0x39f, 0x313,\n                0x0, 0x39f, 0x313, 0x300, 0x0, 0x39f, 0x313, 0x301, 0x0, 0x39f,\n                0x314, 0x0, 0x39f, 0x314, 0x300, 0x0, 0x39f, 0x314, 0x301, 0x0,\n                0x3a1, 0x314, 0x0, 0x3a5, 0x300, 0x0, 0x3a5, 0x301, 0x0, 0x3a5,\n                0x304, 0x0, 0x3a5, 0x306, 0x0, 0x3a5, 0x308, 0x0, 0x3a5, 0x314,\n                0x0, 0x3a5, 0x314, 0x300, 0x0, 0x3a5, 0x314, 0x301, 0x0, 0x3a5,\n                0x314, 0x342, 0x0, 0x3a9, 0x0, 0x3a9, 0x300, 0x0, 0x3a9, 0x301,\n                0x0, 0x3a9, 0x313, 0x0, 0x3a9, 0x313, 0x300, 0x0, 0x3a9, 0x313,\n                0x300, 0x345, 0x0, 0x3a9, 0x313, 0x301, 0x0, 0x3a9, 0x313,\n                0x301, 0x345, 0x0, 0x3a9, 0x313, 0x342, 0x0, 0x3a9, 0x313,\n                0x342, 0x345, 0x0, 0x3a9, 0x313, 0x345, 0x0, 0x3a9, 0x314, 0x0,\n                0x3a9, 0x314, 0x300, 0x0, 0x3a9, 0x314, 0x300, 0x345, 0x0,\n                0x3a9, 0x314, 0x301, 0x0, 0x3a9, 0x314, 0x301, 0x345, 0x0,\n                0x3a9, 0x314, 0x342, 0x0, 0x3a9, 0x314, 0x342, 0x345, 0x0,\n                0x3a9, 0x314, 0x345, 0x0, 0x3a9, 0x345, 0x0, 0x3b1, 0x300, 0x0,\n                0x3b1, 0x300, 0x345, 0x0, 0x3b1, 0x301, 0x0, 0x3b1, 0x301,\n                0x345, 0x0, 0x3b1, 0x304, 0x0, 0x3b1, 0x306, 0x0, 0x3b1, 0x313,\n                0x0, 0x3b1, 0x313, 0x300, 0x0, 0x3b1, 0x313, 0x300, 0x345, 0x0,\n                0x3b1, 0x313, 0x301, 0x0, 0x3b1, 0x313, 0x301, 0x345, 0x0,\n                0x3b1, 0x313, 0x342, 0x0, 0x3b1, 0x313, 0x342, 0x345, 0x0,\n                0x3b1, 0x313, 0x345, 0x0, 0x3b1, 0x314, 0x0, 0x3b1, 0x314,\n                0x300, 0x0, 0x3b1, 0x314, 0x300, 0x345, 0x0, 0x3b1, 0x314,\n                0x301, 0x0, 0x3b1, 0x314, 0x301, 0x345, 0x0, 0x3b1, 0x314,\n                0x342, 0x0, 0x3b1, 0x314, 0x342, 0x345, 0x0, 0x3b1, 0x314,\n                0x345, 0x0, 0x3b1, 0x342, 0x0, 0x3b1, 0x342, 0x345, 0x0, 0x3b1,\n                0x345, 0x0, 0x3b5, 0x300, 0x0, 0x3b5, 0x301, 0x0, 0x3b5, 0x313,\n                0x0, 0x3b5, 0x313, 0x300, 0x0, 0x3b5, 0x313, 0x301, 0x0, 0x3b5,\n                0x314, 0x0, 0x3b5, 0x314, 0x300, 0x0, 0x3b5, 0x314, 0x301, 0x0,\n                0x3b7, 0x300, 0x0, 0x3b7, 0x300, 0x345, 0x0, 0x3b7, 0x301, 0x0,\n                0x3b7, 0x301, 0x345, 0x0, 0x3b7, 0x313, 0x0, 0x3b7, 0x313,\n                0x300, 0x0, 0x3b7, 0x313, 0x300, 0x345, 0x0, 0x3b7, 0x313,\n                0x301, 0x0, 0x3b7, 0x313, 0x301, 0x345, 0x0, 0x3b7, 0x313,\n                0x342, 0x0, 0x3b7, 0x313, 0x342, 0x345, 0x0, 0x3b7, 0x313,\n                0x345, 0x0, 0x3b7, 0x314, 0x0, 0x3b7, 0x314, 0x300, 0x0, 0x3b7,\n                0x314, 0x300, 0x345, 0x0, 0x3b7, 0x314, 0x301, 0x0, 0x3b7,\n                0x314, 0x301, 0x345, 0x0, 0x3b7, 0x314, 0x342, 0x0, 0x3b7,\n                0x314, 0x342, 0x345, 0x0, 0x3b7, 0x314, 0x345, 0x0, 0x3b7,\n                0x342, 0x0, 0x3b7, 0x342, 0x345, 0x0, 0x3b7, 0x345, 0x0, 0x3b9,\n                0x0, 0x3b9, 0x300, 0x0, 0x3b9, 0x301, 0x0, 0x3b9, 0x304, 0x0,\n                0x3b9, 0x306, 0x0, 0x3b9, 0x308, 0x0, 0x3b9, 0x308, 0x300, 0x0,\n                0x3b9, 0x308, 0x301, 0x0, 0x3b9, 0x308, 0x342, 0x0, 0x3b9,\n                0x313, 0x0, 0x3b9, 0x313, 0x300, 0x0, 0x3b9, 0x313, 0x301, 0x0,\n                0x3b9, 0x313, 0x342, 0x0, 0x3b9, 0x314, 0x0, 0x3b9, 0x314,\n                0x300, 0x0, 0x3b9, 0x314, 0x301, 0x0, 0x3b9, 0x314, 0x342, 0x0,\n                0x3b9, 0x342, 0x0, 0x3bf, 0x300, 0x0, 0x3bf, 0x301, 0x0, 0x3bf,\n                0x313, 0x0, 0x3bf, 0x313, 0x300, 0x0, 0x3bf, 0x313, 0x301, 0x0,\n                0x3bf, 0x314, 0x0, 0x3bf, 0x314, 0x300, 0x0, 0x3bf, 0x314,\n                0x301, 0x0, 0x3c1, 0x313, 0x0, 0x3c1, 0x314, 0x0, 0x3c5, 0x300,\n                0x0, 0x3c5, 0x301, 0x0, 0x3c5, 0x304, 0x0, 0x3c5, 0x306, 0x0,\n                0x3c5, 0x308, 0x0, 0x3c5, 0x308, 0x300, 0x0, 0x3c5, 0x308,\n                0x301, 0x0, 0x3c5, 0x308, 0x342, 0x0, 0x3c5, 0x313, 0x0, 0x3c5,\n                0x313, 0x300, 0x0, 0x3c5, 0x313, 0x301, 0x0, 0x3c5, 0x313,\n                0x342, 0x0, 0x3c5, 0x314, 0x0, 0x3c5, 0x314, 0x300, 0x0, 0x3c5,\n                0x314, 0x301, 0x0, 0x3c5, 0x314, 0x342, 0x0, 0x3c5, 0x342, 0x0,\n                0x3c9, 0x300, 0x0, 0x3c9, 0x300, 0x345, 0x0, 0x3c9, 0x301, 0x0,\n                0x3c9, 0x301, 0x345, 0x0, 0x3c9, 0x313, 0x0, 0x3c9, 0x313,\n                0x300, 0x0, 0x3c9, 0x313, 0x300, 0x345, 0x0, 0x3c9, 0x313,\n                0x301, 0x0, 0x3c9, 0x313, 0x301, 0x345, 0x0, 0x3c9, 0x313,\n                0x342, 0x0, 0x3c9, 0x313, 0x342, 0x345, 0x0, 0x3c9, 0x313,\n                0x345, 0x0, 0x3c9, 0x314, 0x0, 0x3c9, 0x314, 0x300, 0x0, 0x3c9,\n                0x314, 0x300, 0x345, 0x0, 0x3c9, 0x314, 0x301, 0x0, 0x3c9,\n                0x314, 0x301, 0x345, 0x0, 0x3c9, 0x314, 0x342, 0x0, 0x3c9,\n                0x314, 0x342, 0x345, 0x0, 0x3c9, 0x314, 0x345, 0x0, 0x3c9,\n                0x342, 0x0, 0x3c9, 0x342, 0x345, 0x0, 0x3c9, 0x345, 0x0, 0x3d2,\n                0x301, 0x0, 0x3d2, 0x308, 0x0, 0x406, 0x308, 0x0, 0x410, 0x306,\n                0x0, 0x410, 0x308, 0x0, 0x413, 0x301, 0x0, 0x415, 0x300, 0x0,\n                0x415, 0x306, 0x0, 0x415, 0x308, 0x0, 0x416, 0x306, 0x0, 0x416,\n                0x308, 0x0, 0x417, 0x308, 0x0, 0x418, 0x300, 0x0, 0x418, 0x304,\n                0x0, 0x418, 0x306, 0x0, 0x418, 0x308, 0x0, 0x41a, 0x301, 0x0,\n                0x41e, 0x308, 0x0, 0x423, 0x304, 0x0, 0x423, 0x306, 0x0, 0x423,\n                0x308, 0x0, 0x423, 0x30b, 0x0, 0x427, 0x308, 0x0, 0x42b, 0x308,\n                0x0, 0x42d, 0x308, 0x0, 0x430, 0x306, 0x0, 0x430, 0x308, 0x0,\n                0x433, 0x301, 0x0, 0x435, 0x300, 0x0, 0x435, 0x306, 0x0, 0x435,\n                0x308, 0x0, 0x436, 0x306, 0x0, 0x436, 0x308, 0x0, 0x437, 0x308,\n                0x0, 0x438, 0x300, 0x0, 0x438, 0x304, 0x0, 0x438, 0x306, 0x0,\n                0x438, 0x308, 0x0, 0x43a, 0x301, 0x0, 0x43e, 0x308, 0x0, 0x443,\n                0x304, 0x0, 0x443, 0x306, 0x0, 0x443, 0x308, 0x0, 0x443, 0x30b,\n                0x0, 0x447, 0x308, 0x0, 0x44b, 0x308, 0x0, 0x44d, 0x308, 0x0,\n                0x456, 0x308, 0x0, 0x474, 0x30f, 0x0, 0x475, 0x30f, 0x0, 0x4d8,\n                0x308, 0x0, 0x4d9, 0x308, 0x0, 0x4e8, 0x308, 0x0, 0x4e9, 0x308,\n                0x0, 0x5d0, 0x5b7, 0x0, 0x5d0, 0x5b8, 0x0, 0x5d0, 0x5bc, 0x0,\n                0x5d1, 0x5bc, 0x0, 0x5d1, 0x5bf, 0x0, 0x5d2, 0x5bc, 0x0, 0x5d3,\n                0x5bc, 0x0, 0x5d4, 0x5bc, 0x0, 0x5d5, 0x5b9, 0x0, 0x5d5, 0x5bc,\n                0x0, 0x5d6, 0x5bc, 0x0, 0x5d8, 0x5bc, 0x0, 0x5d9, 0x5b4, 0x0,\n                0x5d9, 0x5bc, 0x0, 0x5da, 0x5bc, 0x0, 0x5db, 0x5bc, 0x0, 0x5db,\n                0x5bf, 0x0, 0x5dc, 0x5bc, 0x0, 0x5de, 0x5bc, 0x0, 0x5e0, 0x5bc,\n                0x0, 0x5e1, 0x5bc, 0x0, 0x5e3, 0x5bc, 0x0, 0x5e4, 0x5bc, 0x0,\n                0x5e4, 0x5bf, 0x0, 0x5e6, 0x5bc, 0x0, 0x5e7, 0x5bc, 0x0, 0x5e8,\n                0x5bc, 0x0, 0x5e9, 0x5bc, 0x0, 0x5e9, 0x5bc, 0x5c1, 0x0, 0x5e9,\n                0x5bc, 0x5c2, 0x0, 0x5e9, 0x5c1, 0x0, 0x5e9, 0x5c2, 0x0, 0x5ea,\n                0x5bc, 0x0, 0x5f2, 0x5b7, 0x0, 0x627, 0x653, 0x0, 0x627, 0x654,\n                0x0, 0x627, 0x655, 0x0, 0x648, 0x654, 0x0, 0x64a, 0x654, 0x0,\n                0x6c1, 0x654, 0x0, 0x6d2, 0x654, 0x0, 0x6d5, 0x654, 0x0, 0x915,\n                0x93c, 0x0, 0x916, 0x93c, 0x0, 0x917, 0x93c, 0x0, 0x91c, 0x93c,\n                0x0, 0x921, 0x93c, 0x0, 0x922, 0x93c, 0x0, 0x928, 0x93c, 0x0,\n                0x92b, 0x93c, 0x0, 0x92f, 0x93c, 0x0, 0x930, 0x93c, 0x0, 0x933,\n                0x93c, 0x0, 0x9a1, 0x9bc, 0x0, 0x9a2, 0x9bc, 0x0, 0x9af, 0x9bc,\n                0x0, 0x9c7, 0x9be, 0x0, 0x9c7, 0x9d7, 0x0, 0xa16, 0xa3c, 0x0,\n                0xa17, 0xa3c, 0x0, 0xa1c, 0xa3c, 0x0, 0xa2b, 0xa3c, 0x0, 0xa32,\n                0xa3c, 0x0, 0xa38, 0xa3c, 0x0, 0xb21, 0xb3c, 0x0, 0xb22, 0xb3c,\n                0x0, 0xb47, 0xb3e, 0x0, 0xb47, 0xb56, 0x0, 0xb47, 0xb57, 0x0,\n                0xb92, 0xbd7, 0x0, 0xbc6, 0xbbe, 0x0, 0xbc6, 0xbd7, 0x0, 0xbc7,\n                0xbbe, 0x0, 0xc46, 0xc56, 0x0, 0xcbf, 0xcd5, 0x0, 0xcc6, 0xcc2,\n                0x0, 0xcc6, 0xcc2, 0xcd5, 0x0, 0xcc6, 0xcd5, 0x0, 0xcc6, 0xcd6,\n                0x0, 0xd46, 0xd3e, 0x0, 0xd46, 0xd57, 0x0, 0xd47, 0xd3e, 0x0,\n                0xdd9, 0xdca, 0x0, 0xdd9, 0xdcf, 0x0, 0xdd9, 0xdcf, 0xdca, 0x0,\n                0xdd9, 0xddf, 0x0, 0xf40, 0xfb5, 0x0, 0xf42, 0xfb7, 0x0, 0xf4c,\n                0xfb7, 0x0, 0xf51, 0xfb7, 0x0, 0xf56, 0xfb7, 0x0, 0xf5b, 0xfb7,\n                0x0, 0xf71, 0xf72, 0x0, 0xf71, 0xf74, 0x0, 0xf71, 0xf80, 0x0,\n                0xf90, 0xfb5, 0x0, 0xf92, 0xfb7, 0x0, 0xf9c, 0xfb7, 0x0, 0xfa1,\n                0xfb7, 0x0, 0xfa6, 0xfb7, 0x0, 0xfab, 0xfb7, 0x0, 0xfb2, 0xf80,\n                0x0, 0xfb3, 0xf80, 0x0, 0x1025, 0x102e, 0x0, 0x1b05, 0x1b35,\n                0x0, 0x1b07, 0x1b35, 0x0, 0x1b09, 0x1b35, 0x0, 0x1b0b, 0x1b35,\n                0x0, 0x1b0d, 0x1b35, 0x0, 0x1b11, 0x1b35, 0x0, 0x1b3a, 0x1b35,\n                0x0, 0x1b3c, 0x1b35, 0x0, 0x1b3e, 0x1b35, 0x0, 0x1b3f, 0x1b35,\n                0x0, 0x1b42, 0x1b35, 0x0, 0x1fbf, 0x300, 0x0, 0x1fbf, 0x301,\n                0x0, 0x1fbf, 0x342, 0x0, 0x1ffe, 0x300, 0x0, 0x1ffe, 0x301,\n                0x0, 0x1ffe, 0x342, 0x0, 0x2002, 0x0, 0x2003, 0x0, 0x2190,\n                0x338, 0x0, 0x2192, 0x338, 0x0, 0x2194, 0x338, 0x0, 0x21d0,\n                0x338, 0x0, 0x21d2, 0x338, 0x0, 0x21d4, 0x338, 0x0, 0x2203,\n                0x338, 0x0, 0x2208, 0x338, 0x0, 0x220b, 0x338, 0x0, 0x2223,\n                0x338, 0x0, 0x2225, 0x338, 0x0, 0x223c, 0x338, 0x0, 0x2243,\n                0x338, 0x0, 0x2245, 0x338, 0x0, 0x2248, 0x338, 0x0, 0x224d,\n                0x338, 0x0, 0x2261, 0x338, 0x0, 0x2264, 0x338, 0x0, 0x2265,\n                0x338, 0x0, 0x2272, 0x338, 0x0, 0x2273, 0x338, 0x0, 0x2276,\n                0x338, 0x0, 0x2277, 0x338, 0x0, 0x227a, 0x338, 0x0, 0x227b,\n                0x338, 0x0, 0x227c, 0x338, 0x0, 0x227d, 0x338, 0x0, 0x2282,\n                0x338, 0x0, 0x2283, 0x338, 0x0, 0x2286, 0x338, 0x0, 0x2287,\n                0x338, 0x0, 0x2291, 0x338, 0x0, 0x2292, 0x338, 0x0, 0x22a2,\n                0x338, 0x0, 0x22a8, 0x338, 0x0, 0x22a9, 0x338, 0x0, 0x22ab,\n                0x338, 0x0, 0x22b2, 0x338, 0x0, 0x22b3, 0x338, 0x0, 0x22b4,\n                0x338, 0x0, 0x22b5, 0x338, 0x0, 0x2add, 0x338, 0x0, 0x3008,\n                0x0, 0x3009, 0x0, 0x3046, 0x3099, 0x0, 0x304b, 0x3099, 0x0,\n                0x304d, 0x3099, 0x0, 0x304f, 0x3099, 0x0, 0x3051, 0x3099, 0x0,\n                0x3053, 0x3099, 0x0, 0x3055, 0x3099, 0x0, 0x3057, 0x3099, 0x0,\n                0x3059, 0x3099, 0x0, 0x305b, 0x3099, 0x0, 0x305d, 0x3099, 0x0,\n                0x305f, 0x3099, 0x0, 0x3061, 0x3099, 0x0, 0x3064, 0x3099, 0x0,\n                0x3066, 0x3099, 0x0, 0x3068, 0x3099, 0x0, 0x306f, 0x3099, 0x0,\n                0x306f, 0x309a, 0x0, 0x3072, 0x3099, 0x0, 0x3072, 0x309a, 0x0,\n                0x3075, 0x3099, 0x0, 0x3075, 0x309a, 0x0, 0x3078, 0x3099, 0x0,\n                0x3078, 0x309a, 0x0, 0x307b, 0x3099, 0x0, 0x307b, 0x309a, 0x0,\n                0x309d, 0x3099, 0x0, 0x30a6, 0x3099, 0x0, 0x30ab, 0x3099, 0x0,\n                0x30ad, 0x3099, 0x0, 0x30af, 0x3099, 0x0, 0x30b1, 0x3099, 0x0,\n                0x30b3, 0x3099, 0x0, 0x30b5, 0x3099, 0x0, 0x30b7, 0x3099, 0x0,\n                0x30b9, 0x3099, 0x0, 0x30bb, 0x3099, 0x0, 0x30bd, 0x3099, 0x0,\n                0x30bf, 0x3099, 0x0, 0x30c1, 0x3099, 0x0, 0x30c4, 0x3099, 0x0,\n                0x30c6, 0x3099, 0x0, 0x30c8, 0x3099, 0x0, 0x30cf, 0x3099, 0x0,\n                0x30cf, 0x309a, 0x0, 0x30d2, 0x3099, 0x0, 0x30d2, 0x309a, 0x0,\n                0x30d5, 0x3099, 0x0, 0x30d5, 0x309a, 0x0, 0x30d8, 0x3099, 0x0,\n                0x30d8, 0x309a, 0x0, 0x30db, 0x3099, 0x0, 0x30db, 0x309a, 0x0,\n                0x30ef, 0x3099, 0x0, 0x30f0, 0x3099, 0x0, 0x30f1, 0x3099, 0x0,\n                0x30f2, 0x3099, 0x0, 0x30fd, 0x3099, 0x0, 0x349e, 0x0, 0x34b9,\n                0x0, 0x34bb, 0x0, 0x34df, 0x0, 0x3515, 0x0, 0x36ee, 0x0,\n                0x36fc, 0x0, 0x3781, 0x0, 0x382f, 0x0, 0x3862, 0x0, 0x387c,\n                0x0, 0x38c7, 0x0, 0x38e3, 0x0, 0x391c, 0x0, 0x393a, 0x0,\n                0x3a2e, 0x0, 0x3a6c, 0x0, 0x3ae4, 0x0, 0x3b08, 0x0, 0x3b19,\n                0x0, 0x3b49, 0x0, 0x3b9d, 0x0, 0x3c18, 0x0, 0x3c4e, 0x0,\n                0x3d33, 0x0, 0x3d96, 0x0, 0x3eac, 0x0, 0x3eb8, 0x0, 0x3f1b,\n                0x0, 0x3ffc, 0x0, 0x4008, 0x0, 0x4018, 0x0, 0x4039, 0x0,\n                0x4046, 0x0, 0x4096, 0x0, 0x40e3, 0x0, 0x412f, 0x0, 0x4202,\n                0x0, 0x4227, 0x0, 0x42a0, 0x0, 0x4301, 0x0, 0x4334, 0x0,\n                0x4359, 0x0, 0x43d5, 0x0, 0x43d9, 0x0, 0x440b, 0x0, 0x446b,\n                0x0, 0x452b, 0x0, 0x455d, 0x0, 0x4561, 0x0, 0x456b, 0x0,\n                0x45d7, 0x0, 0x45f9, 0x0, 0x4635, 0x0, 0x46be, 0x0, 0x46c7,\n                0x0, 0x4995, 0x0, 0x49e6, 0x0, 0x4a6e, 0x0, 0x4a76, 0x0,\n                0x4ab2, 0x0, 0x4b33, 0x0, 0x4bce, 0x0, 0x4cce, 0x0, 0x4ced,\n                0x0, 0x4cf8, 0x0, 0x4d56, 0x0, 0x4e0d, 0x0, 0x4e26, 0x0,\n                0x4e32, 0x0, 0x4e38, 0x0, 0x4e39, 0x0, 0x4e3d, 0x0, 0x4e41,\n                0x0, 0x4e82, 0x0, 0x4e86, 0x0, 0x4eae, 0x0, 0x4ec0, 0x0,\n                0x4ecc, 0x0, 0x4ee4, 0x0, 0x4f60, 0x0, 0x4f80, 0x0, 0x4f86,\n                0x0, 0x4f8b, 0x0, 0x4fae, 0x0, 0x4fbb, 0x0, 0x4fbf, 0x0,\n                0x5002, 0x0, 0x502b, 0x0, 0x507a, 0x0, 0x5099, 0x0, 0x50cf,\n                0x0, 0x50da, 0x0, 0x50e7, 0x0, 0x5140, 0x0, 0x5145, 0x0,\n                0x514d, 0x0, 0x5154, 0x0, 0x5164, 0x0, 0x5167, 0x0, 0x5168,\n                0x0, 0x5169, 0x0, 0x516d, 0x0, 0x5177, 0x0, 0x5180, 0x0,\n                0x518d, 0x0, 0x5192, 0x0, 0x5195, 0x0, 0x5197, 0x0, 0x51a4,\n                0x0, 0x51ac, 0x0, 0x51b5, 0x0, 0x51b7, 0x0, 0x51c9, 0x0,\n                0x51cc, 0x0, 0x51dc, 0x0, 0x51de, 0x0, 0x51f5, 0x0, 0x5203,\n                0x0, 0x5207, 0x0, 0x5217, 0x0, 0x5229, 0x0, 0x523a, 0x0,\n                0x523b, 0x0, 0x5246, 0x0, 0x5272, 0x0, 0x5277, 0x0, 0x5289,\n                0x0, 0x529b, 0x0, 0x52a3, 0x0, 0x52b3, 0x0, 0x52c7, 0x0,\n                0x52c9, 0x0, 0x52d2, 0x0, 0x52de, 0x0, 0x52e4, 0x0, 0x52f5,\n                0x0, 0x52fa, 0x0, 0x5305, 0x0, 0x5306, 0x0, 0x5317, 0x0,\n                0x533f, 0x0, 0x5349, 0x0, 0x5351, 0x0, 0x535a, 0x0, 0x5373,\n                0x0, 0x5375, 0x0, 0x537d, 0x0, 0x537f, 0x0, 0x53c3, 0x0,\n                0x53ca, 0x0, 0x53df, 0x0, 0x53e5, 0x0, 0x53eb, 0x0, 0x53f1,\n                0x0, 0x5406, 0x0, 0x540f, 0x0, 0x541d, 0x0, 0x5438, 0x0,\n                0x5442, 0x0, 0x5448, 0x0, 0x5468, 0x0, 0x549e, 0x0, 0x54a2,\n                0x0, 0x54bd, 0x0, 0x54f6, 0x0, 0x5510, 0x0, 0x5553, 0x0,\n                0x5555, 0x0, 0x5563, 0x0, 0x5584, 0x0, 0x5587, 0x0, 0x5599,\n                0x0, 0x559d, 0x0, 0x55ab, 0x0, 0x55b3, 0x0, 0x55c0, 0x0,\n                0x55c2, 0x0, 0x55e2, 0x0, 0x5606, 0x0, 0x5651, 0x0, 0x5668,\n                0x0, 0x5674, 0x0, 0x56f9, 0x0, 0x5716, 0x0, 0x5717, 0x0,\n                0x578b, 0x0, 0x57ce, 0x0, 0x57f4, 0x0, 0x580d, 0x0, 0x5831,\n                0x0, 0x5832, 0x0, 0x5840, 0x0, 0x585a, 0x0, 0x585e, 0x0,\n                0x58a8, 0x0, 0x58ac, 0x0, 0x58b3, 0x0, 0x58d8, 0x0, 0x58df,\n                0x0, 0x58ee, 0x0, 0x58f2, 0x0, 0x58f7, 0x0, 0x5906, 0x0,\n                0x591a, 0x0, 0x5922, 0x0, 0x5944, 0x0, 0x5948, 0x0, 0x5951,\n                0x0, 0x5954, 0x0, 0x5962, 0x0, 0x5973, 0x0, 0x59d8, 0x0,\n                0x59ec, 0x0, 0x5a1b, 0x0, 0x5a27, 0x0, 0x5a62, 0x0, 0x5a66,\n                0x0, 0x5ab5, 0x0, 0x5b08, 0x0, 0x5b28, 0x0, 0x5b3e, 0x0,\n                0x5b85, 0x0, 0x5bc3, 0x0, 0x5bd8, 0x0, 0x5be7, 0x0, 0x5bee,\n                0x0, 0x5bf3, 0x0, 0x5bff, 0x0, 0x5c06, 0x0, 0x5c22, 0x0,\n                0x5c3f, 0x0, 0x5c60, 0x0, 0x5c62, 0x0, 0x5c64, 0x0, 0x5c65,\n                0x0, 0x5c6e, 0x0, 0x5c8d, 0x0, 0x5cc0, 0x0, 0x5d19, 0x0,\n                0x5d43, 0x0, 0x5d50, 0x0, 0x5d6b, 0x0, 0x5d6e, 0x0, 0x5d7c,\n                0x0, 0x5db2, 0x0, 0x5dba, 0x0, 0x5de1, 0x0, 0x5de2, 0x0,\n                0x5dfd, 0x0, 0x5e28, 0x0, 0x5e3d, 0x0, 0x5e69, 0x0, 0x5e74,\n                0x0, 0x5ea6, 0x0, 0x5eb0, 0x0, 0x5eb3, 0x0, 0x5eb6, 0x0,\n                0x5ec9, 0x0, 0x5eca, 0x0, 0x5ed2, 0x0, 0x5ed3, 0x0, 0x5ed9,\n                0x0, 0x5eec, 0x0, 0x5efe, 0x0, 0x5f04, 0x0, 0x5f22, 0x0,\n                0x5f53, 0x0, 0x5f62, 0x0, 0x5f69, 0x0, 0x5f6b, 0x0, 0x5f8b,\n                0x0, 0x5f9a, 0x0, 0x5fa9, 0x0, 0x5fad, 0x0, 0x5fcd, 0x0,\n                0x5fd7, 0x0, 0x5ff5, 0x0, 0x5ff9, 0x0, 0x6012, 0x0, 0x601c,\n                0x0, 0x6075, 0x0, 0x6081, 0x0, 0x6094, 0x0, 0x60c7, 0x0,\n                0x60d8, 0x0, 0x60e1, 0x0, 0x6108, 0x0, 0x6144, 0x0, 0x6148,\n                0x0, 0x614c, 0x0, 0x614e, 0x0, 0x6160, 0x0, 0x6168, 0x0,\n                0x617a, 0x0, 0x618e, 0x0, 0x6190, 0x0, 0x61a4, 0x0, 0x61af,\n                0x0, 0x61b2, 0x0, 0x61de, 0x0, 0x61f2, 0x0, 0x61f6, 0x0,\n                0x6200, 0x0, 0x6210, 0x0, 0x621b, 0x0, 0x622e, 0x0, 0x6234,\n                0x0, 0x625d, 0x0, 0x62b1, 0x0, 0x62c9, 0x0, 0x62cf, 0x0,\n                0x62d3, 0x0, 0x62d4, 0x0, 0x62fc, 0x0, 0x62fe, 0x0, 0x633d,\n                0x0, 0x6350, 0x0, 0x6368, 0x0, 0x637b, 0x0, 0x6383, 0x0,\n                0x63a0, 0x0, 0x63a9, 0x0, 0x63c4, 0x0, 0x63c5, 0x0, 0x63e4,\n                0x0, 0x641c, 0x0, 0x6422, 0x0, 0x6452, 0x0, 0x6469, 0x0,\n                0x6477, 0x0, 0x647e, 0x0, 0x649a, 0x0, 0x649d, 0x0, 0x64c4,\n                0x0, 0x654f, 0x0, 0x6556, 0x0, 0x656c, 0x0, 0x6578, 0x0,\n                0x6599, 0x0, 0x65c5, 0x0, 0x65e2, 0x0, 0x65e3, 0x0, 0x6613,\n                0x0, 0x6649, 0x0, 0x6674, 0x0, 0x6688, 0x0, 0x6691, 0x0,\n                0x669c, 0x0, 0x66b4, 0x0, 0x66c6, 0x0, 0x66f4, 0x0, 0x66f8,\n                0x0, 0x6700, 0x0, 0x6717, 0x0, 0x671b, 0x0, 0x6721, 0x0,\n                0x674e, 0x0, 0x6753, 0x0, 0x6756, 0x0, 0x675e, 0x0, 0x677b,\n                0x0, 0x6785, 0x0, 0x6797, 0x0, 0x67f3, 0x0, 0x67fa, 0x0,\n                0x6817, 0x0, 0x681f, 0x0, 0x6852, 0x0, 0x6881, 0x0, 0x6885,\n                0x0, 0x688e, 0x0, 0x68a8, 0x0, 0x6914, 0x0, 0x6942, 0x0,\n                0x69a3, 0x0, 0x69ea, 0x0, 0x6a02, 0x0, 0x6a13, 0x0, 0x6aa8,\n                0x0, 0x6ad3, 0x0, 0x6adb, 0x0, 0x6b04, 0x0, 0x6b21, 0x0,\n                0x6b54, 0x0, 0x6b72, 0x0, 0x6b77, 0x0, 0x6b79, 0x0, 0x6b9f,\n                0x0, 0x6bae, 0x0, 0x6bba, 0x0, 0x6bbb, 0x0, 0x6c4e, 0x0,\n                0x6c67, 0x0, 0x6c88, 0x0, 0x6cbf, 0x0, 0x6ccc, 0x0, 0x6ccd,\n                0x0, 0x6ce5, 0x0, 0x6d16, 0x0, 0x6d1b, 0x0, 0x6d1e, 0x0,\n                0x6d34, 0x0, 0x6d3e, 0x0, 0x6d41, 0x0, 0x6d69, 0x0, 0x6d6a,\n                0x0, 0x6d77, 0x0, 0x6d78, 0x0, 0x6d85, 0x0, 0x6dcb, 0x0,\n                0x6dda, 0x0, 0x6dea, 0x0, 0x6df9, 0x0, 0x6e1a, 0x0, 0x6e2f,\n                0x0, 0x6e6e, 0x0, 0x6e9c, 0x0, 0x6eba, 0x0, 0x6ec7, 0x0,\n                0x6ecb, 0x0, 0x6ed1, 0x0, 0x6edb, 0x0, 0x6f0f, 0x0, 0x6f22,\n                0x0, 0x6f23, 0x0, 0x6f6e, 0x0, 0x6fc6, 0x0, 0x6feb, 0x0,\n                0x6ffe, 0x0, 0x701b, 0x0, 0x701e, 0x0, 0x7039, 0x0, 0x704a,\n                0x0, 0x7070, 0x0, 0x7077, 0x0, 0x707d, 0x0, 0x7099, 0x0,\n                0x70ad, 0x0, 0x70c8, 0x0, 0x70d9, 0x0, 0x7145, 0x0, 0x7149,\n                0x0, 0x716e, 0x0, 0x719c, 0x0, 0x71ce, 0x0, 0x71d0, 0x0,\n                0x7210, 0x0, 0x721b, 0x0, 0x7228, 0x0, 0x722b, 0x0, 0x7235,\n                0x0, 0x7250, 0x0, 0x7262, 0x0, 0x7280, 0x0, 0x7295, 0x0,\n                0x72af, 0x0, 0x72c0, 0x0, 0x72fc, 0x0, 0x732a, 0x0, 0x7375,\n                0x0, 0x737a, 0x0, 0x7387, 0x0, 0x738b, 0x0, 0x73a5, 0x0,\n                0x73b2, 0x0, 0x73de, 0x0, 0x7406, 0x0, 0x7409, 0x0, 0x7422,\n                0x0, 0x7447, 0x0, 0x745c, 0x0, 0x7469, 0x0, 0x7471, 0x0,\n                0x7485, 0x0, 0x7489, 0x0, 0x7498, 0x0, 0x74ca, 0x0, 0x7506,\n                0x0, 0x7524, 0x0, 0x753b, 0x0, 0x753e, 0x0, 0x7559, 0x0,\n                0x7565, 0x0, 0x7570, 0x0, 0x75e2, 0x0, 0x7610, 0x0, 0x761d,\n                0x0, 0x761f, 0x0, 0x7642, 0x0, 0x7669, 0x0, 0x76ca, 0x0,\n                0x76db, 0x0, 0x76e7, 0x0, 0x76f4, 0x0, 0x7701, 0x0, 0x771e,\n                0x0, 0x771f, 0x0, 0x7740, 0x0, 0x774a, 0x0, 0x778b, 0x0,\n                0x77a7, 0x0, 0x784e, 0x0, 0x786b, 0x0, 0x788c, 0x0, 0x7891,\n                0x0, 0x78ca, 0x0, 0x78cc, 0x0, 0x78fb, 0x0, 0x792a, 0x0,\n                0x793c, 0x0, 0x793e, 0x0, 0x7948, 0x0, 0x7949, 0x0, 0x7950,\n                0x0, 0x7956, 0x0, 0x795d, 0x0, 0x795e, 0x0, 0x7965, 0x0,\n                0x797f, 0x0, 0x798d, 0x0, 0x798e, 0x0, 0x798f, 0x0, 0x79ae,\n                0x0, 0x79ca, 0x0, 0x79eb, 0x0, 0x7a1c, 0x0, 0x7a40, 0x0,\n                0x7a4a, 0x0, 0x7a4f, 0x0, 0x7a81, 0x0, 0x7ab1, 0x0, 0x7acb,\n                0x0, 0x7aee, 0x0, 0x7b20, 0x0, 0x7bc0, 0x0, 0x7bc6, 0x0,\n                0x7bc9, 0x0, 0x7c3e, 0x0, 0x7c60, 0x0, 0x7c7b, 0x0, 0x7c92,\n                0x0, 0x7cbe, 0x0, 0x7cd2, 0x0, 0x7cd6, 0x0, 0x7ce3, 0x0,\n                0x7ce7, 0x0, 0x7ce8, 0x0, 0x7d00, 0x0, 0x7d10, 0x0, 0x7d22,\n                0x0, 0x7d2f, 0x0, 0x7d5b, 0x0, 0x7d63, 0x0, 0x7da0, 0x0,\n                0x7dbe, 0x0, 0x7dc7, 0x0, 0x7df4, 0x0, 0x7e02, 0x0, 0x7e09,\n                0x0, 0x7e37, 0x0, 0x7e41, 0x0, 0x7e45, 0x0, 0x7f3e, 0x0,\n                0x7f72, 0x0, 0x7f79, 0x0, 0x7f7a, 0x0, 0x7f85, 0x0, 0x7f95,\n                0x0, 0x7f9a, 0x0, 0x7fbd, 0x0, 0x7ffa, 0x0, 0x8001, 0x0,\n                0x8005, 0x0, 0x8046, 0x0, 0x8060, 0x0, 0x806f, 0x0, 0x8070,\n                0x0, 0x807e, 0x0, 0x808b, 0x0, 0x80ad, 0x0, 0x80b2, 0x0,\n                0x8103, 0x0, 0x813e, 0x0, 0x81d8, 0x0, 0x81e8, 0x0, 0x81ed,\n                0x0, 0x8201, 0x0, 0x8204, 0x0, 0x8218, 0x0, 0x826f, 0x0,\n                0x8279, 0x0, 0x828b, 0x0, 0x8291, 0x0, 0x829d, 0x0, 0x82b1,\n                0x0, 0x82b3, 0x0, 0x82bd, 0x0, 0x82e5, 0x0, 0x82e6, 0x0,\n                0x831d, 0x0, 0x8323, 0x0, 0x8336, 0x0, 0x8352, 0x0, 0x8353,\n                0x0, 0x8363, 0x0, 0x83ad, 0x0, 0x83bd, 0x0, 0x83c9, 0x0,\n                0x83ca, 0x0, 0x83cc, 0x0, 0x83dc, 0x0, 0x83e7, 0x0, 0x83ef,\n                0x0, 0x83f1, 0x0, 0x843d, 0x0, 0x8449, 0x0, 0x8457, 0x0,\n                0x84ee, 0x0, 0x84f1, 0x0, 0x84f3, 0x0, 0x84fc, 0x0, 0x8516,\n                0x0, 0x8564, 0x0, 0x85cd, 0x0, 0x85fa, 0x0, 0x8606, 0x0,\n                0x8612, 0x0, 0x862d, 0x0, 0x863f, 0x0, 0x8650, 0x0, 0x865c,\n                0x0, 0x8667, 0x0, 0x8669, 0x0, 0x8688, 0x0, 0x86a9, 0x0,\n                0x86e2, 0x0, 0x870e, 0x0, 0x8728, 0x0, 0x876b, 0x0, 0x8779,\n                0x0, 0x8786, 0x0, 0x87ba, 0x0, 0x87e1, 0x0, 0x8801, 0x0,\n                0x881f, 0x0, 0x884c, 0x0, 0x8860, 0x0, 0x8863, 0x0, 0x88c2,\n                0x0, 0x88cf, 0x0, 0x88d7, 0x0, 0x88de, 0x0, 0x88e1, 0x0,\n                0x88f8, 0x0, 0x88fa, 0x0, 0x8910, 0x0, 0x8941, 0x0, 0x8964,\n                0x0, 0x8986, 0x0, 0x898b, 0x0, 0x8996, 0x0, 0x8aa0, 0x0,\n                0x8aaa, 0x0, 0x8abf, 0x0, 0x8acb, 0x0, 0x8ad2, 0x0, 0x8ad6,\n                0x0, 0x8aed, 0x0, 0x8af8, 0x0, 0x8afe, 0x0, 0x8b01, 0x0,\n                0x8b39, 0x0, 0x8b58, 0x0, 0x8b80, 0x0, 0x8b8a, 0x0, 0x8c48,\n                0x0, 0x8c55, 0x0, 0x8cab, 0x0, 0x8cc1, 0x0, 0x8cc2, 0x0,\n                0x8cc8, 0x0, 0x8cd3, 0x0, 0x8d08, 0x0, 0x8d1b, 0x0, 0x8d77,\n                0x0, 0x8dbc, 0x0, 0x8dcb, 0x0, 0x8def, 0x0, 0x8df0, 0x0,\n                0x8eca, 0x0, 0x8ed4, 0x0, 0x8f26, 0x0, 0x8f2a, 0x0, 0x8f38,\n                0x0, 0x8f3b, 0x0, 0x8f62, 0x0, 0x8f9e, 0x0, 0x8fb0, 0x0,\n                0x8fb6, 0x0, 0x9023, 0x0, 0x9038, 0x0, 0x9072, 0x0, 0x907c,\n                0x0, 0x908f, 0x0, 0x9094, 0x0, 0x90ce, 0x0, 0x90de, 0x0,\n                0x90f1, 0x0, 0x90fd, 0x0, 0x9111, 0x0, 0x911b, 0x0, 0x916a,\n                0x0, 0x9199, 0x0, 0x91b4, 0x0, 0x91cc, 0x0, 0x91cf, 0x0,\n                0x91d1, 0x0, 0x9234, 0x0, 0x9238, 0x0, 0x9276, 0x0, 0x927c,\n                0x0, 0x92d7, 0x0, 0x92d8, 0x0, 0x9304, 0x0, 0x934a, 0x0,\n                0x93f9, 0x0, 0x9415, 0x0, 0x958b, 0x0, 0x95ad, 0x0, 0x95b7,\n                0x0, 0x962e, 0x0, 0x964b, 0x0, 0x964d, 0x0, 0x9675, 0x0,\n                0x9678, 0x0, 0x967c, 0x0, 0x9686, 0x0, 0x96a3, 0x0, 0x96b7,\n                0x0, 0x96b8, 0x0, 0x96c3, 0x0, 0x96e2, 0x0, 0x96e3, 0x0,\n                0x96f6, 0x0, 0x96f7, 0x0, 0x9723, 0x0, 0x9732, 0x0, 0x9748,\n                0x0, 0x9756, 0x0, 0x97db, 0x0, 0x97e0, 0x0, 0x97ff, 0x0,\n                0x980b, 0x0, 0x9818, 0x0, 0x9829, 0x0, 0x983b, 0x0, 0x985e,\n                0x0, 0x98e2, 0x0, 0x98ef, 0x0, 0x98fc, 0x0, 0x9928, 0x0,\n                0x9929, 0x0, 0x99a7, 0x0, 0x99c2, 0x0, 0x99f1, 0x0, 0x99fe,\n                0x0, 0x9a6a, 0x0, 0x9b12, 0x0, 0x9b6f, 0x0, 0x9c40, 0x0,\n                0x9c57, 0x0, 0x9cfd, 0x0, 0x9d67, 0x0, 0x9db4, 0x0, 0x9dfa,\n                0x0, 0x9e1e, 0x0, 0x9e7f, 0x0, 0x9e97, 0x0, 0x9e9f, 0x0,\n                0x9ebb, 0x0, 0x9ece, 0x0, 0x9ef9, 0x0, 0x9efe, 0x0, 0x9f05,\n                0x0, 0x9f0f, 0x0, 0x9f16, 0x0, 0x9f3b, 0x0, 0x9f43, 0x0,\n                0x9f8d, 0x0, 0x9f8e, 0x0, 0x9f9c, 0x0, 0x11099, 0x110ba, 0x0,\n                0x1109b, 0x110ba, 0x0, 0x110a5, 0x110ba, 0x0, 0x11131, 0x11127,\n                0x0, 0x11132, 0x11127, 0x0, 0x1d157, 0x1d165, 0x0, 0x1d158,\n                0x1d165, 0x0, 0x1d158, 0x1d165, 0x1d16e, 0x0, 0x1d158, 0x1d165,\n                0x1d16f, 0x0, 0x1d158, 0x1d165, 0x1d170, 0x0, 0x1d158, 0x1d165,\n                0x1d171, 0x0, 0x1d158, 0x1d165, 0x1d172, 0x0, 0x1d1b9, 0x1d165,\n                0x0, 0x1d1b9, 0x1d165, 0x1d16e, 0x0, 0x1d1b9, 0x1d165, 0x1d16f,\n                0x0, 0x1d1ba, 0x1d165, 0x0, 0x1d1ba, 0x1d165, 0x1d16e, 0x0,\n                0x1d1ba, 0x1d165, 0x1d16f, 0x0, 0x20122, 0x0, 0x2051c, 0x0,\n                0x20525, 0x0, 0x2054b, 0x0, 0x2063a, 0x0, 0x20804, 0x0,\n                0x208de, 0x0, 0x20a2c, 0x0, 0x20b63, 0x0, 0x214e4, 0x0,\n                0x216a8, 0x0, 0x216ea, 0x0, 0x219c8, 0x0, 0x21b18, 0x0,\n                0x21d0b, 0x0, 0x21de4, 0x0, 0x21de6, 0x0, 0x22183, 0x0,\n                0x2219f, 0x0, 0x22331, 0x0, 0x226d4, 0x0, 0x22844, 0x0,\n                0x2284a, 0x0, 0x22b0c, 0x0, 0x22bf1, 0x0, 0x2300a, 0x0,\n                0x232b8, 0x0, 0x2335f, 0x0, 0x23393, 0x0, 0x2339c, 0x0,\n                0x233c3, 0x0, 0x233d5, 0x0, 0x2346d, 0x0, 0x236a3, 0x0,\n                0x238a7, 0x0, 0x23a8d, 0x0, 0x23afa, 0x0, 0x23cbc, 0x0,\n                0x23d1e, 0x0, 0x23ed1, 0x0, 0x23f5e, 0x0, 0x23f8e, 0x0,\n                0x24263, 0x0, 0x242ee, 0x0, 0x243ab, 0x0, 0x24608, 0x0,\n                0x24735, 0x0, 0x24814, 0x0, 0x24c36, 0x0, 0x24c92, 0x0,\n                0x24fa1, 0x0, 0x24fb8, 0x0, 0x25044, 0x0, 0x250f2, 0x0,\n                0x250f3, 0x0, 0x25119, 0x0, 0x25133, 0x0, 0x25249, 0x0,\n                0x2541d, 0x0, 0x25626, 0x0, 0x2569a, 0x0, 0x256c5, 0x0,\n                0x2597c, 0x0, 0x25aa7, 0x0, 0x25bab, 0x0, 0x25c80, 0x0,\n                0x25cd0, 0x0, 0x25f86, 0x0, 0x261da, 0x0, 0x26228, 0x0,\n                0x26247, 0x0, 0x262d9, 0x0, 0x2633e, 0x0, 0x264da, 0x0,\n                0x26523, 0x0, 0x265a8, 0x0, 0x267a7, 0x0, 0x267b5, 0x0,\n                0x26b3c, 0x0, 0x26c36, 0x0, 0x26cd5, 0x0, 0x26d6b, 0x0,\n                0x26f2c, 0x0, 0x26fb1, 0x0, 0x270d2, 0x0, 0x273ca, 0x0,\n                0x27667, 0x0, 0x278ae, 0x0, 0x27966, 0x0, 0x27ca8, 0x0,\n                0x27ed3, 0x0, 0x27f2f, 0x0, 0x285d2, 0x0, 0x285ed, 0x0,\n                0x2872e, 0x0, 0x28bfa, 0x0, 0x28d77, 0x0, 0x29145, 0x0,\n                0x291df, 0x0, 0x2921a, 0x0, 0x2940a, 0x0, 0x29496, 0x0,\n                0x295b6, 0x0, 0x29b30, 0x0, 0x2a0ce, 0x0, 0x2a105, 0x0,\n                0x2a20e, 0x0, 0x2a291, 0x0, 0x2a392, 0x0, 0x2a600, 0x0\n            ];\n            return t;\n        }\n\n        _IDCA decompCompatTable()\n        {\n            static _IDCA t = [\n                0x0, 0x20, 0x0, 0x20, 0x301, 0x0, 0x20, 0x303, 0x0, 0x20,\n                0x304, 0x0, 0x20, 0x305, 0x0, 0x20, 0x306, 0x0, 0x20, 0x307,\n                0x0, 0x20, 0x308, 0x0, 0x20, 0x308, 0x300, 0x0, 0x20, 0x308,\n                0x301, 0x0, 0x20, 0x308, 0x342, 0x0, 0x20, 0x30a, 0x0, 0x20,\n                0x30b, 0x0, 0x20, 0x313, 0x0, 0x20, 0x313, 0x300, 0x0, 0x20,\n                0x313, 0x301, 0x0, 0x20, 0x313, 0x342, 0x0, 0x20, 0x314, 0x0,\n                0x20, 0x314, 0x300, 0x0, 0x20, 0x314, 0x301, 0x0, 0x20, 0x314,\n                0x342, 0x0, 0x20, 0x327, 0x0, 0x20, 0x328, 0x0, 0x20, 0x333,\n                0x0, 0x20, 0x342, 0x0, 0x20, 0x345, 0x0, 0x20, 0x64b, 0x0,\n                0x20, 0x64c, 0x0, 0x20, 0x64c, 0x651, 0x0, 0x20, 0x64d, 0x0,\n                0x20, 0x64d, 0x651, 0x0, 0x20, 0x64e, 0x0, 0x20, 0x64e, 0x651,\n                0x0, 0x20, 0x64f, 0x0, 0x20, 0x64f, 0x651, 0x0, 0x20, 0x650,\n                0x0, 0x20, 0x650, 0x651, 0x0, 0x20, 0x651, 0x0, 0x20, 0x651,\n                0x670, 0x0, 0x20, 0x652, 0x0, 0x20, 0x3099, 0x0, 0x20, 0x309a,\n                0x0, 0x21, 0x0, 0x21, 0x21, 0x0, 0x21, 0x3f, 0x0, 0x22, 0x0,\n                0x23, 0x0, 0x24, 0x0, 0x25, 0x0, 0x26, 0x0, 0x27, 0x0, 0x28,\n                0x0, 0x28, 0x31, 0x29, 0x0, 0x28, 0x31, 0x30, 0x29, 0x0, 0x28,\n                0x31, 0x31, 0x29, 0x0, 0x28, 0x31, 0x32, 0x29, 0x0, 0x28, 0x31,\n                0x33, 0x29, 0x0, 0x28, 0x31, 0x34, 0x29, 0x0, 0x28, 0x31, 0x35,\n                0x29, 0x0, 0x28, 0x31, 0x36, 0x29, 0x0, 0x28, 0x31, 0x37, 0x29,\n                0x0, 0x28, 0x31, 0x38, 0x29, 0x0, 0x28, 0x31, 0x39, 0x29, 0x0,\n                0x28, 0x32, 0x29, 0x0, 0x28, 0x32, 0x30, 0x29, 0x0, 0x28, 0x33,\n                0x29, 0x0, 0x28, 0x34, 0x29, 0x0, 0x28, 0x35, 0x29, 0x0, 0x28,\n                0x36, 0x29, 0x0, 0x28, 0x37, 0x29, 0x0, 0x28, 0x38, 0x29, 0x0,\n                0x28, 0x39, 0x29, 0x0, 0x28, 0x41, 0x29, 0x0, 0x28, 0x42, 0x29,\n                0x0, 0x28, 0x43, 0x29, 0x0, 0x28, 0x44, 0x29, 0x0, 0x28, 0x45,\n                0x29, 0x0, 0x28, 0x46, 0x29, 0x0, 0x28, 0x47, 0x29, 0x0, 0x28,\n                0x48, 0x29, 0x0, 0x28, 0x49, 0x29, 0x0, 0x28, 0x4a, 0x29, 0x0,\n                0x28, 0x4b, 0x29, 0x0, 0x28, 0x4c, 0x29, 0x0, 0x28, 0x4d, 0x29,\n                0x0, 0x28, 0x4e, 0x29, 0x0, 0x28, 0x4f, 0x29, 0x0, 0x28, 0x50,\n                0x29, 0x0, 0x28, 0x51, 0x29, 0x0, 0x28, 0x52, 0x29, 0x0, 0x28,\n                0x53, 0x29, 0x0, 0x28, 0x54, 0x29, 0x0, 0x28, 0x55, 0x29, 0x0,\n                0x28, 0x56, 0x29, 0x0, 0x28, 0x57, 0x29, 0x0, 0x28, 0x58, 0x29,\n                0x0, 0x28, 0x59, 0x29, 0x0, 0x28, 0x5a, 0x29, 0x0, 0x28, 0x61,\n                0x29, 0x0, 0x28, 0x62, 0x29, 0x0, 0x28, 0x63, 0x29, 0x0, 0x28,\n                0x64, 0x29, 0x0, 0x28, 0x65, 0x29, 0x0, 0x28, 0x66, 0x29, 0x0,\n                0x28, 0x67, 0x29, 0x0, 0x28, 0x68, 0x29, 0x0, 0x28, 0x69, 0x29,\n                0x0, 0x28, 0x6a, 0x29, 0x0, 0x28, 0x6b, 0x29, 0x0, 0x28, 0x6c,\n                0x29, 0x0, 0x28, 0x6d, 0x29, 0x0, 0x28, 0x6e, 0x29, 0x0, 0x28,\n                0x6f, 0x29, 0x0, 0x28, 0x70, 0x29, 0x0, 0x28, 0x71, 0x29, 0x0,\n                0x28, 0x72, 0x29, 0x0, 0x28, 0x73, 0x29, 0x0, 0x28, 0x74, 0x29,\n                0x0, 0x28, 0x75, 0x29, 0x0, 0x28, 0x76, 0x29, 0x0, 0x28, 0x77,\n                0x29, 0x0, 0x28, 0x78, 0x29, 0x0, 0x28, 0x79, 0x29, 0x0, 0x28,\n                0x7a, 0x29, 0x0, 0x28, 0x1100, 0x29, 0x0, 0x28, 0x1100, 0x1161,\n                0x29, 0x0, 0x28, 0x1102, 0x29, 0x0, 0x28, 0x1102, 0x1161, 0x29,\n                0x0, 0x28, 0x1103, 0x29, 0x0, 0x28, 0x1103, 0x1161, 0x29, 0x0,\n                0x28, 0x1105, 0x29, 0x0, 0x28, 0x1105, 0x1161, 0x29, 0x0, 0x28,\n                0x1106, 0x29, 0x0, 0x28, 0x1106, 0x1161, 0x29, 0x0, 0x28,\n                0x1107, 0x29, 0x0, 0x28, 0x1107, 0x1161, 0x29, 0x0, 0x28,\n                0x1109, 0x29, 0x0, 0x28, 0x1109, 0x1161, 0x29, 0x0, 0x28,\n                0x110b, 0x29, 0x0, 0x28, 0x110b, 0x1161, 0x29, 0x0, 0x28,\n                0x110b, 0x1169, 0x110c, 0x1165, 0x11ab, 0x29, 0x0, 0x28,\n                0x110b, 0x1169, 0x1112, 0x116e, 0x29, 0x0, 0x28, 0x110c, 0x29,\n                0x0, 0x28, 0x110c, 0x1161, 0x29, 0x0, 0x28, 0x110c, 0x116e,\n                0x29, 0x0, 0x28, 0x110e, 0x29, 0x0, 0x28, 0x110e, 0x1161, 0x29,\n                0x0, 0x28, 0x110f, 0x29, 0x0, 0x28, 0x110f, 0x1161, 0x29, 0x0,\n                0x28, 0x1110, 0x29, 0x0, 0x28, 0x1110, 0x1161, 0x29, 0x0, 0x28,\n                0x1111, 0x29, 0x0, 0x28, 0x1111, 0x1161, 0x29, 0x0, 0x28,\n                0x1112, 0x29, 0x0, 0x28, 0x1112, 0x1161, 0x29, 0x0, 0x28,\n                0x4e00, 0x29, 0x0, 0x28, 0x4e03, 0x29, 0x0, 0x28, 0x4e09, 0x29,\n                0x0, 0x28, 0x4e5d, 0x29, 0x0, 0x28, 0x4e8c, 0x29, 0x0, 0x28,\n                0x4e94, 0x29, 0x0, 0x28, 0x4ee3, 0x29, 0x0, 0x28, 0x4f01, 0x29,\n                0x0, 0x28, 0x4f11, 0x29, 0x0, 0x28, 0x516b, 0x29, 0x0, 0x28,\n                0x516d, 0x29, 0x0, 0x28, 0x52b4, 0x29, 0x0, 0x28, 0x5341, 0x29,\n                0x0, 0x28, 0x5354, 0x29, 0x0, 0x28, 0x540d, 0x29, 0x0, 0x28,\n                0x547c, 0x29, 0x0, 0x28, 0x56db, 0x29, 0x0, 0x28, 0x571f, 0x29,\n                0x0, 0x28, 0x5b66, 0x29, 0x0, 0x28, 0x65e5, 0x29, 0x0, 0x28,\n                0x6708, 0x29, 0x0, 0x28, 0x6709, 0x29, 0x0, 0x28, 0x6728, 0x29,\n                0x0, 0x28, 0x682a, 0x29, 0x0, 0x28, 0x6c34, 0x29, 0x0, 0x28,\n                0x706b, 0x29, 0x0, 0x28, 0x7279, 0x29, 0x0, 0x28, 0x76e3, 0x29,\n                0x0, 0x28, 0x793e, 0x29, 0x0, 0x28, 0x795d, 0x29, 0x0, 0x28,\n                0x796d, 0x29, 0x0, 0x28, 0x81ea, 0x29, 0x0, 0x28, 0x81f3, 0x29,\n                0x0, 0x28, 0x8ca1, 0x29, 0x0, 0x28, 0x8cc7, 0x29, 0x0, 0x28,\n                0x91d1, 0x29, 0x0, 0x29, 0x0, 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0,\n                0x2d, 0x0, 0x2e, 0x0, 0x2e, 0x2e, 0x0, 0x2e, 0x2e, 0x2e, 0x0,\n                0x2f, 0x0, 0x30, 0x0, 0x30, 0x2c, 0x0, 0x30, 0x2e, 0x0, 0x30,\n                0x2044, 0x33, 0x0, 0x30, 0x70b9, 0x0, 0x31, 0x0, 0x31, 0x2c,\n                0x0, 0x31, 0x2e, 0x0, 0x31, 0x30, 0x0, 0x31, 0x30, 0x2e, 0x0,\n                0x31, 0x30, 0x65e5, 0x0, 0x31, 0x30, 0x6708, 0x0, 0x31, 0x30,\n                0x70b9, 0x0, 0x31, 0x31, 0x0, 0x31, 0x31, 0x2e, 0x0, 0x31,\n                0x31, 0x65e5, 0x0, 0x31, 0x31, 0x6708, 0x0, 0x31, 0x31, 0x70b9,\n                0x0, 0x31, 0x32, 0x0, 0x31, 0x32, 0x2e, 0x0, 0x31, 0x32,\n                0x65e5, 0x0, 0x31, 0x32, 0x6708, 0x0, 0x31, 0x32, 0x70b9, 0x0,\n                0x31, 0x33, 0x0, 0x31, 0x33, 0x2e, 0x0, 0x31, 0x33, 0x65e5,\n                0x0, 0x31, 0x33, 0x70b9, 0x0, 0x31, 0x34, 0x0, 0x31, 0x34,\n                0x2e, 0x0, 0x31, 0x34, 0x65e5, 0x0, 0x31, 0x34, 0x70b9, 0x0,\n                0x31, 0x35, 0x0, 0x31, 0x35, 0x2e, 0x0, 0x31, 0x35, 0x65e5,\n                0x0, 0x31, 0x35, 0x70b9, 0x0, 0x31, 0x36, 0x0, 0x31, 0x36,\n                0x2e, 0x0, 0x31, 0x36, 0x65e5, 0x0, 0x31, 0x36, 0x70b9, 0x0,\n                0x31, 0x37, 0x0, 0x31, 0x37, 0x2e, 0x0, 0x31, 0x37, 0x65e5,\n                0x0, 0x31, 0x37, 0x70b9, 0x0, 0x31, 0x38, 0x0, 0x31, 0x38,\n                0x2e, 0x0, 0x31, 0x38, 0x65e5, 0x0, 0x31, 0x38, 0x70b9, 0x0,\n                0x31, 0x39, 0x0, 0x31, 0x39, 0x2e, 0x0, 0x31, 0x39, 0x65e5,\n                0x0, 0x31, 0x39, 0x70b9, 0x0, 0x31, 0x2044, 0x0, 0x31, 0x2044,\n                0x31, 0x30, 0x0, 0x31, 0x2044, 0x32, 0x0, 0x31, 0x2044, 0x33,\n                0x0, 0x31, 0x2044, 0x34, 0x0, 0x31, 0x2044, 0x35, 0x0, 0x31,\n                0x2044, 0x36, 0x0, 0x31, 0x2044, 0x37, 0x0, 0x31, 0x2044, 0x38,\n                0x0, 0x31, 0x2044, 0x39, 0x0, 0x31, 0x65e5, 0x0, 0x31, 0x6708,\n                0x0, 0x31, 0x70b9, 0x0, 0x32, 0x0, 0x32, 0x2c, 0x0, 0x32, 0x2e,\n                0x0, 0x32, 0x30, 0x0, 0x32, 0x30, 0x2e, 0x0, 0x32, 0x30,\n                0x65e5, 0x0, 0x32, 0x30, 0x70b9, 0x0, 0x32, 0x31, 0x0, 0x32,\n                0x31, 0x65e5, 0x0, 0x32, 0x31, 0x70b9, 0x0, 0x32, 0x32, 0x0,\n                0x32, 0x32, 0x65e5, 0x0, 0x32, 0x32, 0x70b9, 0x0, 0x32, 0x33,\n                0x0, 0x32, 0x33, 0x65e5, 0x0, 0x32, 0x33, 0x70b9, 0x0, 0x32,\n                0x34, 0x0, 0x32, 0x34, 0x65e5, 0x0, 0x32, 0x34, 0x70b9, 0x0,\n                0x32, 0x35, 0x0, 0x32, 0x35, 0x65e5, 0x0, 0x32, 0x36, 0x0,\n                0x32, 0x36, 0x65e5, 0x0, 0x32, 0x37, 0x0, 0x32, 0x37, 0x65e5,\n                0x0, 0x32, 0x38, 0x0, 0x32, 0x38, 0x65e5, 0x0, 0x32, 0x39, 0x0,\n                0x32, 0x39, 0x65e5, 0x0, 0x32, 0x2044, 0x33, 0x0, 0x32, 0x2044,\n                0x35, 0x0, 0x32, 0x65e5, 0x0, 0x32, 0x6708, 0x0, 0x32, 0x70b9,\n                0x0, 0x33, 0x0, 0x33, 0x2c, 0x0, 0x33, 0x2e, 0x0, 0x33, 0x30,\n                0x0, 0x33, 0x30, 0x65e5, 0x0, 0x33, 0x31, 0x0, 0x33, 0x31,\n                0x65e5, 0x0, 0x33, 0x32, 0x0, 0x33, 0x33, 0x0, 0x33, 0x34, 0x0,\n                0x33, 0x35, 0x0, 0x33, 0x36, 0x0, 0x33, 0x37, 0x0, 0x33, 0x38,\n                0x0, 0x33, 0x39, 0x0, 0x33, 0x2044, 0x34, 0x0, 0x33, 0x2044,\n                0x35, 0x0, 0x33, 0x2044, 0x38, 0x0, 0x33, 0x65e5, 0x0, 0x33,\n                0x6708, 0x0, 0x33, 0x70b9, 0x0, 0x34, 0x0, 0x34, 0x2c, 0x0,\n                0x34, 0x2e, 0x0, 0x34, 0x30, 0x0, 0x34, 0x31, 0x0, 0x34, 0x32,\n                0x0, 0x34, 0x33, 0x0, 0x34, 0x34, 0x0, 0x34, 0x35, 0x0, 0x34,\n                0x36, 0x0, 0x34, 0x37, 0x0, 0x34, 0x38, 0x0, 0x34, 0x39, 0x0,\n                0x34, 0x2044, 0x35, 0x0, 0x34, 0x65e5, 0x0, 0x34, 0x6708, 0x0,\n                0x34, 0x70b9, 0x0, 0x35, 0x0, 0x35, 0x2c, 0x0, 0x35, 0x2e, 0x0,\n                0x35, 0x30, 0x0, 0x35, 0x2044, 0x36, 0x0, 0x35, 0x2044, 0x38,\n                0x0, 0x35, 0x65e5, 0x0, 0x35, 0x6708, 0x0, 0x35, 0x70b9, 0x0,\n                0x36, 0x0, 0x36, 0x2c, 0x0, 0x36, 0x2e, 0x0, 0x36, 0x65e5, 0x0,\n                0x36, 0x6708, 0x0, 0x36, 0x70b9, 0x0, 0x37, 0x0, 0x37, 0x2c,\n                0x0, 0x37, 0x2e, 0x0, 0x37, 0x2044, 0x38, 0x0, 0x37, 0x65e5,\n                0x0, 0x37, 0x6708, 0x0, 0x37, 0x70b9, 0x0, 0x38, 0x0, 0x38,\n                0x2c, 0x0, 0x38, 0x2e, 0x0, 0x38, 0x65e5, 0x0, 0x38, 0x6708,\n                0x0, 0x38, 0x70b9, 0x0, 0x39, 0x0, 0x39, 0x2c, 0x0, 0x39, 0x2e,\n                0x0, 0x39, 0x65e5, 0x0, 0x39, 0x6708, 0x0, 0x39, 0x70b9, 0x0,\n                0x3a, 0x0, 0x3a, 0x3a, 0x3d, 0x0, 0x3b, 0x0, 0x3c, 0x0, 0x3c,\n                0x338, 0x0, 0x3d, 0x0, 0x3d, 0x3d, 0x0, 0x3d, 0x3d, 0x3d, 0x0,\n                0x3d, 0x338, 0x0, 0x3e, 0x0, 0x3e, 0x338, 0x0, 0x3f, 0x0, 0x3f,\n                0x21, 0x0, 0x3f, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0, 0x41, 0x55,\n                0x0, 0x41, 0x300, 0x0, 0x41, 0x301, 0x0, 0x41, 0x302, 0x0,\n                0x41, 0x302, 0x300, 0x0, 0x41, 0x302, 0x301, 0x0, 0x41, 0x302,\n                0x303, 0x0, 0x41, 0x302, 0x309, 0x0, 0x41, 0x303, 0x0, 0x41,\n                0x304, 0x0, 0x41, 0x306, 0x0, 0x41, 0x306, 0x300, 0x0, 0x41,\n                0x306, 0x301, 0x0, 0x41, 0x306, 0x303, 0x0, 0x41, 0x306, 0x309,\n                0x0, 0x41, 0x307, 0x0, 0x41, 0x307, 0x304, 0x0, 0x41, 0x308,\n                0x0, 0x41, 0x308, 0x304, 0x0, 0x41, 0x309, 0x0, 0x41, 0x30a,\n                0x0, 0x41, 0x30a, 0x301, 0x0, 0x41, 0x30c, 0x0, 0x41, 0x30f,\n                0x0, 0x41, 0x311, 0x0, 0x41, 0x323, 0x0, 0x41, 0x323, 0x302,\n                0x0, 0x41, 0x323, 0x306, 0x0, 0x41, 0x325, 0x0, 0x41, 0x328,\n                0x0, 0x41, 0x2215, 0x6d, 0x0, 0x42, 0x0, 0x42, 0x71, 0x0, 0x42,\n                0x307, 0x0, 0x42, 0x323, 0x0, 0x42, 0x331, 0x0, 0x43, 0x0,\n                0x43, 0x44, 0x0, 0x43, 0x6f, 0x2e, 0x0, 0x43, 0x301, 0x0, 0x43,\n                0x302, 0x0, 0x43, 0x307, 0x0, 0x43, 0x30c, 0x0, 0x43, 0x327,\n                0x0, 0x43, 0x327, 0x301, 0x0, 0x43, 0x2215, 0x6b, 0x67, 0x0,\n                0x44, 0x0, 0x44, 0x4a, 0x0, 0x44, 0x5a, 0x0, 0x44, 0x5a, 0x30c,\n                0x0, 0x44, 0x7a, 0x0, 0x44, 0x7a, 0x30c, 0x0, 0x44, 0x307, 0x0,\n                0x44, 0x30c, 0x0, 0x44, 0x323, 0x0, 0x44, 0x327, 0x0, 0x44,\n                0x32d, 0x0, 0x44, 0x331, 0x0, 0x45, 0x0, 0x45, 0x300, 0x0,\n                0x45, 0x301, 0x0, 0x45, 0x302, 0x0, 0x45, 0x302, 0x300, 0x0,\n                0x45, 0x302, 0x301, 0x0, 0x45, 0x302, 0x303, 0x0, 0x45, 0x302,\n                0x309, 0x0, 0x45, 0x303, 0x0, 0x45, 0x304, 0x0, 0x45, 0x304,\n                0x300, 0x0, 0x45, 0x304, 0x301, 0x0, 0x45, 0x306, 0x0, 0x45,\n                0x307, 0x0, 0x45, 0x308, 0x0, 0x45, 0x309, 0x0, 0x45, 0x30c,\n                0x0, 0x45, 0x30f, 0x0, 0x45, 0x311, 0x0, 0x45, 0x323, 0x0,\n                0x45, 0x323, 0x302, 0x0, 0x45, 0x327, 0x0, 0x45, 0x327, 0x306,\n                0x0, 0x45, 0x328, 0x0, 0x45, 0x32d, 0x0, 0x45, 0x330, 0x0,\n                0x46, 0x0, 0x46, 0x41, 0x58, 0x0, 0x46, 0x307, 0x0, 0x47, 0x0,\n                0x47, 0x42, 0x0, 0x47, 0x48, 0x7a, 0x0, 0x47, 0x50, 0x61, 0x0,\n                0x47, 0x79, 0x0, 0x47, 0x301, 0x0, 0x47, 0x302, 0x0, 0x47,\n                0x304, 0x0, 0x47, 0x306, 0x0, 0x47, 0x307, 0x0, 0x47, 0x30c,\n                0x0, 0x47, 0x327, 0x0, 0x48, 0x0, 0x48, 0x50, 0x0, 0x48, 0x56,\n                0x0, 0x48, 0x67, 0x0, 0x48, 0x7a, 0x0, 0x48, 0x302, 0x0, 0x48,\n                0x307, 0x0, 0x48, 0x308, 0x0, 0x48, 0x30c, 0x0, 0x48, 0x323,\n                0x0, 0x48, 0x327, 0x0, 0x48, 0x32e, 0x0, 0x49, 0x0, 0x49, 0x49,\n                0x0, 0x49, 0x49, 0x49, 0x0, 0x49, 0x4a, 0x0, 0x49, 0x55, 0x0,\n                0x49, 0x56, 0x0, 0x49, 0x58, 0x0, 0x49, 0x300, 0x0, 0x49,\n                0x301, 0x0, 0x49, 0x302, 0x0, 0x49, 0x303, 0x0, 0x49, 0x304,\n                0x0, 0x49, 0x306, 0x0, 0x49, 0x307, 0x0, 0x49, 0x308, 0x0,\n                0x49, 0x308, 0x301, 0x0, 0x49, 0x309, 0x0, 0x49, 0x30c, 0x0,\n                0x49, 0x30f, 0x0, 0x49, 0x311, 0x0, 0x49, 0x323, 0x0, 0x49,\n                0x328, 0x0, 0x49, 0x330, 0x0, 0x4a, 0x0, 0x4a, 0x302, 0x0,\n                0x4b, 0x0, 0x4b, 0x42, 0x0, 0x4b, 0x4b, 0x0, 0x4b, 0x4d, 0x0,\n                0x4b, 0x301, 0x0, 0x4b, 0x30c, 0x0, 0x4b, 0x323, 0x0, 0x4b,\n                0x327, 0x0, 0x4b, 0x331, 0x0, 0x4c, 0x0, 0x4c, 0x4a, 0x0, 0x4c,\n                0x54, 0x44, 0x0, 0x4c, 0x6a, 0x0, 0x4c, 0xb7, 0x0, 0x4c, 0x301,\n                0x0, 0x4c, 0x30c, 0x0, 0x4c, 0x323, 0x0, 0x4c, 0x323, 0x304,\n                0x0, 0x4c, 0x327, 0x0, 0x4c, 0x32d, 0x0, 0x4c, 0x331, 0x0,\n                0x4d, 0x0, 0x4d, 0x42, 0x0, 0x4d, 0x43, 0x0, 0x4d, 0x44, 0x0,\n                0x4d, 0x48, 0x7a, 0x0, 0x4d, 0x50, 0x61, 0x0, 0x4d, 0x56, 0x0,\n                0x4d, 0x57, 0x0, 0x4d, 0x301, 0x0, 0x4d, 0x307, 0x0, 0x4d,\n                0x323, 0x0, 0x4d, 0x3a9, 0x0, 0x4e, 0x0, 0x4e, 0x4a, 0x0, 0x4e,\n                0x6a, 0x0, 0x4e, 0x6f, 0x0, 0x4e, 0x300, 0x0, 0x4e, 0x301, 0x0,\n                0x4e, 0x303, 0x0, 0x4e, 0x307, 0x0, 0x4e, 0x30c, 0x0, 0x4e,\n                0x323, 0x0, 0x4e, 0x327, 0x0, 0x4e, 0x32d, 0x0, 0x4e, 0x331,\n                0x0, 0x4f, 0x0, 0x4f, 0x300, 0x0, 0x4f, 0x301, 0x0, 0x4f,\n                0x302, 0x0, 0x4f, 0x302, 0x300, 0x0, 0x4f, 0x302, 0x301, 0x0,\n                0x4f, 0x302, 0x303, 0x0, 0x4f, 0x302, 0x309, 0x0, 0x4f, 0x303,\n                0x0, 0x4f, 0x303, 0x301, 0x0, 0x4f, 0x303, 0x304, 0x0, 0x4f,\n                0x303, 0x308, 0x0, 0x4f, 0x304, 0x0, 0x4f, 0x304, 0x300, 0x0,\n                0x4f, 0x304, 0x301, 0x0, 0x4f, 0x306, 0x0, 0x4f, 0x307, 0x0,\n                0x4f, 0x307, 0x304, 0x0, 0x4f, 0x308, 0x0, 0x4f, 0x308, 0x304,\n                0x0, 0x4f, 0x309, 0x0, 0x4f, 0x30b, 0x0, 0x4f, 0x30c, 0x0,\n                0x4f, 0x30f, 0x0, 0x4f, 0x311, 0x0, 0x4f, 0x31b, 0x0, 0x4f,\n                0x31b, 0x300, 0x0, 0x4f, 0x31b, 0x301, 0x0, 0x4f, 0x31b, 0x303,\n                0x0, 0x4f, 0x31b, 0x309, 0x0, 0x4f, 0x31b, 0x323, 0x0, 0x4f,\n                0x323, 0x0, 0x4f, 0x323, 0x302, 0x0, 0x4f, 0x328, 0x0, 0x4f,\n                0x328, 0x304, 0x0, 0x50, 0x0, 0x50, 0x48, 0x0, 0x50, 0x50,\n                0x4d, 0x0, 0x50, 0x50, 0x56, 0x0, 0x50, 0x52, 0x0, 0x50, 0x54,\n                0x45, 0x0, 0x50, 0x61, 0x0, 0x50, 0x301, 0x0, 0x50, 0x307, 0x0,\n                0x51, 0x0, 0x52, 0x0, 0x52, 0x73, 0x0, 0x52, 0x301, 0x0, 0x52,\n                0x307, 0x0, 0x52, 0x30c, 0x0, 0x52, 0x30f, 0x0, 0x52, 0x311,\n                0x0, 0x52, 0x323, 0x0, 0x52, 0x323, 0x304, 0x0, 0x52, 0x327,\n                0x0, 0x52, 0x331, 0x0, 0x53, 0x0, 0x53, 0x44, 0x0, 0x53, 0x4d,\n                0x0, 0x53, 0x53, 0x0, 0x53, 0x76, 0x0, 0x53, 0x301, 0x0, 0x53,\n                0x301, 0x307, 0x0, 0x53, 0x302, 0x0, 0x53, 0x307, 0x0, 0x53,\n                0x30c, 0x0, 0x53, 0x30c, 0x307, 0x0, 0x53, 0x323, 0x0, 0x53,\n                0x323, 0x307, 0x0, 0x53, 0x326, 0x0, 0x53, 0x327, 0x0, 0x54,\n                0x0, 0x54, 0x45, 0x4c, 0x0, 0x54, 0x48, 0x7a, 0x0, 0x54, 0x4d,\n                0x0, 0x54, 0x307, 0x0, 0x54, 0x30c, 0x0, 0x54, 0x323, 0x0,\n                0x54, 0x326, 0x0, 0x54, 0x327, 0x0, 0x54, 0x32d, 0x0, 0x54,\n                0x331, 0x0, 0x55, 0x0, 0x55, 0x300, 0x0, 0x55, 0x301, 0x0,\n                0x55, 0x302, 0x0, 0x55, 0x303, 0x0, 0x55, 0x303, 0x301, 0x0,\n                0x55, 0x304, 0x0, 0x55, 0x304, 0x308, 0x0, 0x55, 0x306, 0x0,\n                0x55, 0x308, 0x0, 0x55, 0x308, 0x300, 0x0, 0x55, 0x308, 0x301,\n                0x0, 0x55, 0x308, 0x304, 0x0, 0x55, 0x308, 0x30c, 0x0, 0x55,\n                0x309, 0x0, 0x55, 0x30a, 0x0, 0x55, 0x30b, 0x0, 0x55, 0x30c,\n                0x0, 0x55, 0x30f, 0x0, 0x55, 0x311, 0x0, 0x55, 0x31b, 0x0,\n                0x55, 0x31b, 0x300, 0x0, 0x55, 0x31b, 0x301, 0x0, 0x55, 0x31b,\n                0x303, 0x0, 0x55, 0x31b, 0x309, 0x0, 0x55, 0x31b, 0x323, 0x0,\n                0x55, 0x323, 0x0, 0x55, 0x324, 0x0, 0x55, 0x328, 0x0, 0x55,\n                0x32d, 0x0, 0x55, 0x330, 0x0, 0x56, 0x0, 0x56, 0x49, 0x0, 0x56,\n                0x49, 0x49, 0x0, 0x56, 0x49, 0x49, 0x49, 0x0, 0x56, 0x303, 0x0,\n                0x56, 0x323, 0x0, 0x56, 0x2215, 0x6d, 0x0, 0x57, 0x0, 0x57,\n                0x43, 0x0, 0x57, 0x5a, 0x0, 0x57, 0x62, 0x0, 0x57, 0x300, 0x0,\n                0x57, 0x301, 0x0, 0x57, 0x302, 0x0, 0x57, 0x307, 0x0, 0x57,\n                0x308, 0x0, 0x57, 0x323, 0x0, 0x58, 0x0, 0x58, 0x49, 0x0, 0x58,\n                0x49, 0x49, 0x0, 0x58, 0x307, 0x0, 0x58, 0x308, 0x0, 0x59, 0x0,\n                0x59, 0x300, 0x0, 0x59, 0x301, 0x0, 0x59, 0x302, 0x0, 0x59,\n                0x303, 0x0, 0x59, 0x304, 0x0, 0x59, 0x307, 0x0, 0x59, 0x308,\n                0x0, 0x59, 0x309, 0x0, 0x59, 0x323, 0x0, 0x5a, 0x0, 0x5a,\n                0x301, 0x0, 0x5a, 0x302, 0x0, 0x5a, 0x307, 0x0, 0x5a, 0x30c,\n                0x0, 0x5a, 0x323, 0x0, 0x5a, 0x331, 0x0, 0x5b, 0x0, 0x5c, 0x0,\n                0x5d, 0x0, 0x5e, 0x0, 0x5f, 0x0, 0x60, 0x0, 0x61, 0x0, 0x61,\n                0x2e, 0x6d, 0x2e, 0x0, 0x61, 0x2f, 0x63, 0x0, 0x61, 0x2f, 0x73,\n                0x0, 0x61, 0x2be, 0x0, 0x61, 0x300, 0x0, 0x61, 0x301, 0x0,\n                0x61, 0x302, 0x0, 0x61, 0x302, 0x300, 0x0, 0x61, 0x302, 0x301,\n                0x0, 0x61, 0x302, 0x303, 0x0, 0x61, 0x302, 0x309, 0x0, 0x61,\n                0x303, 0x0, 0x61, 0x304, 0x0, 0x61, 0x306, 0x0, 0x61, 0x306,\n                0x300, 0x0, 0x61, 0x306, 0x301, 0x0, 0x61, 0x306, 0x303, 0x0,\n                0x61, 0x306, 0x309, 0x0, 0x61, 0x307, 0x0, 0x61, 0x307, 0x304,\n                0x0, 0x61, 0x308, 0x0, 0x61, 0x308, 0x304, 0x0, 0x61, 0x309,\n                0x0, 0x61, 0x30a, 0x0, 0x61, 0x30a, 0x301, 0x0, 0x61, 0x30c,\n                0x0, 0x61, 0x30f, 0x0, 0x61, 0x311, 0x0, 0x61, 0x323, 0x0,\n                0x61, 0x323, 0x302, 0x0, 0x61, 0x323, 0x306, 0x0, 0x61, 0x325,\n                0x0, 0x61, 0x328, 0x0, 0x62, 0x0, 0x62, 0x61, 0x72, 0x0, 0x62,\n                0x307, 0x0, 0x62, 0x323, 0x0, 0x62, 0x331, 0x0, 0x63, 0x0,\n                0x63, 0x2f, 0x6f, 0x0, 0x63, 0x2f, 0x75, 0x0, 0x63, 0x61, 0x6c,\n                0x0, 0x63, 0x63, 0x0, 0x63, 0x64, 0x0, 0x63, 0x6d, 0x0, 0x63,\n                0x6d, 0x32, 0x0, 0x63, 0x6d, 0x33, 0x0, 0x63, 0x301, 0x0, 0x63,\n                0x302, 0x0, 0x63, 0x307, 0x0, 0x63, 0x30c, 0x0, 0x63, 0x327,\n                0x0, 0x63, 0x327, 0x301, 0x0, 0x64, 0x0, 0x64, 0x42, 0x0, 0x64,\n                0x61, 0x0, 0x64, 0x6c, 0x0, 0x64, 0x6d, 0x0, 0x64, 0x6d, 0x32,\n                0x0, 0x64, 0x6d, 0x33, 0x0, 0x64, 0x7a, 0x0, 0x64, 0x7a, 0x30c,\n                0x0, 0x64, 0x307, 0x0, 0x64, 0x30c, 0x0, 0x64, 0x323, 0x0,\n                0x64, 0x327, 0x0, 0x64, 0x32d, 0x0, 0x64, 0x331, 0x0, 0x65,\n                0x0, 0x65, 0x56, 0x0, 0x65, 0x72, 0x67, 0x0, 0x65, 0x300, 0x0,\n                0x65, 0x301, 0x0, 0x65, 0x302, 0x0, 0x65, 0x302, 0x300, 0x0,\n                0x65, 0x302, 0x301, 0x0, 0x65, 0x302, 0x303, 0x0, 0x65, 0x302,\n                0x309, 0x0, 0x65, 0x303, 0x0, 0x65, 0x304, 0x0, 0x65, 0x304,\n                0x300, 0x0, 0x65, 0x304, 0x301, 0x0, 0x65, 0x306, 0x0, 0x65,\n                0x307, 0x0, 0x65, 0x308, 0x0, 0x65, 0x309, 0x0, 0x65, 0x30c,\n                0x0, 0x65, 0x30f, 0x0, 0x65, 0x311, 0x0, 0x65, 0x323, 0x0,\n                0x65, 0x323, 0x302, 0x0, 0x65, 0x327, 0x0, 0x65, 0x327, 0x306,\n                0x0, 0x65, 0x328, 0x0, 0x65, 0x32d, 0x0, 0x65, 0x330, 0x0,\n                0x66, 0x0, 0x66, 0x66, 0x0, 0x66, 0x66, 0x69, 0x0, 0x66, 0x66,\n                0x6c, 0x0, 0x66, 0x69, 0x0, 0x66, 0x6c, 0x0, 0x66, 0x6d, 0x0,\n                0x66, 0x307, 0x0, 0x67, 0x0, 0x67, 0x61, 0x6c, 0x0, 0x67,\n                0x301, 0x0, 0x67, 0x302, 0x0, 0x67, 0x304, 0x0, 0x67, 0x306,\n                0x0, 0x67, 0x307, 0x0, 0x67, 0x30c, 0x0, 0x67, 0x327, 0x0,\n                0x68, 0x0, 0x68, 0x50, 0x61, 0x0, 0x68, 0x61, 0x0, 0x68, 0x302,\n                0x0, 0x68, 0x307, 0x0, 0x68, 0x308, 0x0, 0x68, 0x30c, 0x0,\n                0x68, 0x323, 0x0, 0x68, 0x327, 0x0, 0x68, 0x32e, 0x0, 0x68,\n                0x331, 0x0, 0x69, 0x0, 0x69, 0x69, 0x0, 0x69, 0x69, 0x69, 0x0,\n                0x69, 0x6a, 0x0, 0x69, 0x6e, 0x0, 0x69, 0x76, 0x0, 0x69, 0x78,\n                0x0, 0x69, 0x300, 0x0, 0x69, 0x301, 0x0, 0x69, 0x302, 0x0,\n                0x69, 0x303, 0x0, 0x69, 0x304, 0x0, 0x69, 0x306, 0x0, 0x69,\n                0x308, 0x0, 0x69, 0x308, 0x301, 0x0, 0x69, 0x309, 0x0, 0x69,\n                0x30c, 0x0, 0x69, 0x30f, 0x0, 0x69, 0x311, 0x0, 0x69, 0x323,\n                0x0, 0x69, 0x328, 0x0, 0x69, 0x330, 0x0, 0x6a, 0x0, 0x6a,\n                0x302, 0x0, 0x6a, 0x30c, 0x0, 0x6b, 0x0, 0x6b, 0x41, 0x0, 0x6b,\n                0x48, 0x7a, 0x0, 0x6b, 0x50, 0x61, 0x0, 0x6b, 0x56, 0x0, 0x6b,\n                0x57, 0x0, 0x6b, 0x63, 0x61, 0x6c, 0x0, 0x6b, 0x67, 0x0, 0x6b,\n                0x6c, 0x0, 0x6b, 0x6d, 0x0, 0x6b, 0x6d, 0x32, 0x0, 0x6b, 0x6d,\n                0x33, 0x0, 0x6b, 0x74, 0x0, 0x6b, 0x301, 0x0, 0x6b, 0x30c, 0x0,\n                0x6b, 0x323, 0x0, 0x6b, 0x327, 0x0, 0x6b, 0x331, 0x0, 0x6b,\n                0x3a9, 0x0, 0x6c, 0x0, 0x6c, 0x6a, 0x0, 0x6c, 0x6d, 0x0, 0x6c,\n                0x6e, 0x0, 0x6c, 0x6f, 0x67, 0x0, 0x6c, 0x78, 0x0, 0x6c, 0xb7,\n                0x0, 0x6c, 0x301, 0x0, 0x6c, 0x30c, 0x0, 0x6c, 0x323, 0x0,\n                0x6c, 0x323, 0x304, 0x0, 0x6c, 0x327, 0x0, 0x6c, 0x32d, 0x0,\n                0x6c, 0x331, 0x0, 0x6d, 0x0, 0x6d, 0x32, 0x0, 0x6d, 0x33, 0x0,\n                0x6d, 0x41, 0x0, 0x6d, 0x56, 0x0, 0x6d, 0x57, 0x0, 0x6d, 0x62,\n                0x0, 0x6d, 0x67, 0x0, 0x6d, 0x69, 0x6c, 0x0, 0x6d, 0x6c, 0x0,\n                0x6d, 0x6d, 0x0, 0x6d, 0x6d, 0x32, 0x0, 0x6d, 0x6d, 0x33, 0x0,\n                0x6d, 0x6f, 0x6c, 0x0, 0x6d, 0x73, 0x0, 0x6d, 0x301, 0x0, 0x6d,\n                0x307, 0x0, 0x6d, 0x323, 0x0, 0x6d, 0x2215, 0x73, 0x0, 0x6d,\n                0x2215, 0x73, 0x32, 0x0, 0x6e, 0x0, 0x6e, 0x41, 0x0, 0x6e,\n                0x46, 0x0, 0x6e, 0x56, 0x0, 0x6e, 0x57, 0x0, 0x6e, 0x6a, 0x0,\n                0x6e, 0x6d, 0x0, 0x6e, 0x73, 0x0, 0x6e, 0x300, 0x0, 0x6e,\n                0x301, 0x0, 0x6e, 0x303, 0x0, 0x6e, 0x307, 0x0, 0x6e, 0x30c,\n                0x0, 0x6e, 0x323, 0x0, 0x6e, 0x327, 0x0, 0x6e, 0x32d, 0x0,\n                0x6e, 0x331, 0x0, 0x6f, 0x0, 0x6f, 0x56, 0x0, 0x6f, 0x300, 0x0,\n                0x6f, 0x301, 0x0, 0x6f, 0x302, 0x0, 0x6f, 0x302, 0x300, 0x0,\n                0x6f, 0x302, 0x301, 0x0, 0x6f, 0x302, 0x303, 0x0, 0x6f, 0x302,\n                0x309, 0x0, 0x6f, 0x303, 0x0, 0x6f, 0x303, 0x301, 0x0, 0x6f,\n                0x303, 0x304, 0x0, 0x6f, 0x303, 0x308, 0x0, 0x6f, 0x304, 0x0,\n                0x6f, 0x304, 0x300, 0x0, 0x6f, 0x304, 0x301, 0x0, 0x6f, 0x306,\n                0x0, 0x6f, 0x307, 0x0, 0x6f, 0x307, 0x304, 0x0, 0x6f, 0x308,\n                0x0, 0x6f, 0x308, 0x304, 0x0, 0x6f, 0x309, 0x0, 0x6f, 0x30b,\n                0x0, 0x6f, 0x30c, 0x0, 0x6f, 0x30f, 0x0, 0x6f, 0x311, 0x0,\n                0x6f, 0x31b, 0x0, 0x6f, 0x31b, 0x300, 0x0, 0x6f, 0x31b, 0x301,\n                0x0, 0x6f, 0x31b, 0x303, 0x0, 0x6f, 0x31b, 0x309, 0x0, 0x6f,\n                0x31b, 0x323, 0x0, 0x6f, 0x323, 0x0, 0x6f, 0x323, 0x302, 0x0,\n                0x6f, 0x328, 0x0, 0x6f, 0x328, 0x304, 0x0, 0x70, 0x0, 0x70,\n                0x2e, 0x6d, 0x2e, 0x0, 0x70, 0x41, 0x0, 0x70, 0x46, 0x0, 0x70,\n                0x56, 0x0, 0x70, 0x57, 0x0, 0x70, 0x63, 0x0, 0x70, 0x73, 0x0,\n                0x70, 0x301, 0x0, 0x70, 0x307, 0x0, 0x71, 0x0, 0x72, 0x0, 0x72,\n                0x61, 0x64, 0x0, 0x72, 0x61, 0x64, 0x2215, 0x73, 0x0, 0x72,\n                0x61, 0x64, 0x2215, 0x73, 0x32, 0x0, 0x72, 0x301, 0x0, 0x72,\n                0x307, 0x0, 0x72, 0x30c, 0x0, 0x72, 0x30f, 0x0, 0x72, 0x311,\n                0x0, 0x72, 0x323, 0x0, 0x72, 0x323, 0x304, 0x0, 0x72, 0x327,\n                0x0, 0x72, 0x331, 0x0, 0x73, 0x0, 0x73, 0x72, 0x0, 0x73, 0x74,\n                0x0, 0x73, 0x301, 0x0, 0x73, 0x301, 0x307, 0x0, 0x73, 0x302,\n                0x0, 0x73, 0x307, 0x0, 0x73, 0x30c, 0x0, 0x73, 0x30c, 0x307,\n                0x0, 0x73, 0x323, 0x0, 0x73, 0x323, 0x307, 0x0, 0x73, 0x326,\n                0x0, 0x73, 0x327, 0x0, 0x74, 0x0, 0x74, 0x307, 0x0, 0x74,\n                0x308, 0x0, 0x74, 0x30c, 0x0, 0x74, 0x323, 0x0, 0x74, 0x326,\n                0x0, 0x74, 0x327, 0x0, 0x74, 0x32d, 0x0, 0x74, 0x331, 0x0,\n                0x75, 0x0, 0x75, 0x300, 0x0, 0x75, 0x301, 0x0, 0x75, 0x302,\n                0x0, 0x75, 0x303, 0x0, 0x75, 0x303, 0x301, 0x0, 0x75, 0x304,\n                0x0, 0x75, 0x304, 0x308, 0x0, 0x75, 0x306, 0x0, 0x75, 0x308,\n                0x0, 0x75, 0x308, 0x300, 0x0, 0x75, 0x308, 0x301, 0x0, 0x75,\n                0x308, 0x304, 0x0, 0x75, 0x308, 0x30c, 0x0, 0x75, 0x309, 0x0,\n                0x75, 0x30a, 0x0, 0x75, 0x30b, 0x0, 0x75, 0x30c, 0x0, 0x75,\n                0x30f, 0x0, 0x75, 0x311, 0x0, 0x75, 0x31b, 0x0, 0x75, 0x31b,\n                0x300, 0x0, 0x75, 0x31b, 0x301, 0x0, 0x75, 0x31b, 0x303, 0x0,\n                0x75, 0x31b, 0x309, 0x0, 0x75, 0x31b, 0x323, 0x0, 0x75, 0x323,\n                0x0, 0x75, 0x324, 0x0, 0x75, 0x328, 0x0, 0x75, 0x32d, 0x0,\n                0x75, 0x330, 0x0, 0x76, 0x0, 0x76, 0x69, 0x0, 0x76, 0x69, 0x69,\n                0x0, 0x76, 0x69, 0x69, 0x69, 0x0, 0x76, 0x303, 0x0, 0x76,\n                0x323, 0x0, 0x77, 0x0, 0x77, 0x300, 0x0, 0x77, 0x301, 0x0,\n                0x77, 0x302, 0x0, 0x77, 0x307, 0x0, 0x77, 0x308, 0x0, 0x77,\n                0x30a, 0x0, 0x77, 0x323, 0x0, 0x78, 0x0, 0x78, 0x69, 0x0, 0x78,\n                0x69, 0x69, 0x0, 0x78, 0x307, 0x0, 0x78, 0x308, 0x0, 0x79, 0x0,\n                0x79, 0x300, 0x0, 0x79, 0x301, 0x0, 0x79, 0x302, 0x0, 0x79,\n                0x303, 0x0, 0x79, 0x304, 0x0, 0x79, 0x307, 0x0, 0x79, 0x308,\n                0x0, 0x79, 0x309, 0x0, 0x79, 0x30a, 0x0, 0x79, 0x323, 0x0,\n                0x7a, 0x0, 0x7a, 0x301, 0x0, 0x7a, 0x302, 0x0, 0x7a, 0x307,\n                0x0, 0x7a, 0x30c, 0x0, 0x7a, 0x323, 0x0, 0x7a, 0x331, 0x0,\n                0x7b, 0x0, 0x7c, 0x0, 0x7d, 0x0, 0x7e, 0x0, 0xa2, 0x0, 0xa3,\n                0x0, 0xa5, 0x0, 0xa6, 0x0, 0xac, 0x0, 0xb0, 0x43, 0x0, 0xb0,\n                0x46, 0x0, 0xb7, 0x0, 0xc6, 0x0, 0xc6, 0x301, 0x0, 0xc6, 0x304,\n                0x0, 0xd8, 0x301, 0x0, 0xe6, 0x301, 0x0, 0xe6, 0x304, 0x0,\n                0xf0, 0x0, 0xf8, 0x301, 0x0, 0x126, 0x0, 0x127, 0x0, 0x131,\n                0x0, 0x14b, 0x0, 0x153, 0x0, 0x18e, 0x0, 0x190, 0x0, 0x1ab,\n                0x0, 0x1b7, 0x30c, 0x0, 0x222, 0x0, 0x237, 0x0, 0x250, 0x0,\n                0x251, 0x0, 0x252, 0x0, 0x254, 0x0, 0x255, 0x0, 0x259, 0x0,\n                0x25b, 0x0, 0x25c, 0x0, 0x25f, 0x0, 0x261, 0x0, 0x263, 0x0,\n                0x265, 0x0, 0x266, 0x0, 0x268, 0x0, 0x269, 0x0, 0x26a, 0x0,\n                0x26d, 0x0, 0x26f, 0x0, 0x270, 0x0, 0x271, 0x0, 0x272, 0x0,\n                0x273, 0x0, 0x274, 0x0, 0x275, 0x0, 0x278, 0x0, 0x279, 0x0,\n                0x27b, 0x0, 0x281, 0x0, 0x282, 0x0, 0x283, 0x0, 0x289, 0x0,\n                0x28a, 0x0, 0x28b, 0x0, 0x28c, 0x0, 0x290, 0x0, 0x291, 0x0,\n                0x292, 0x0, 0x292, 0x30c, 0x0, 0x295, 0x0, 0x29d, 0x0, 0x29f,\n                0x0, 0x2b9, 0x0, 0x2bc, 0x6e, 0x0, 0x300, 0x0, 0x301, 0x0,\n                0x308, 0x301, 0x0, 0x313, 0x0, 0x391, 0x0, 0x391, 0x300, 0x0,\n                0x391, 0x301, 0x0, 0x391, 0x304, 0x0, 0x391, 0x306, 0x0, 0x391,\n                0x313, 0x0, 0x391, 0x313, 0x300, 0x0, 0x391, 0x313, 0x300,\n                0x345, 0x0, 0x391, 0x313, 0x301, 0x0, 0x391, 0x313, 0x301,\n                0x345, 0x0, 0x391, 0x313, 0x342, 0x0, 0x391, 0x313, 0x342,\n                0x345, 0x0, 0x391, 0x313, 0x345, 0x0, 0x391, 0x314, 0x0, 0x391,\n                0x314, 0x300, 0x0, 0x391, 0x314, 0x300, 0x345, 0x0, 0x391,\n                0x314, 0x301, 0x0, 0x391, 0x314, 0x301, 0x345, 0x0, 0x391,\n                0x314, 0x342, 0x0, 0x391, 0x314, 0x342, 0x345, 0x0, 0x391,\n                0x314, 0x345, 0x0, 0x391, 0x345, 0x0, 0x392, 0x0, 0x393, 0x0,\n                0x394, 0x0, 0x395, 0x0, 0x395, 0x300, 0x0, 0x395, 0x301, 0x0,\n                0x395, 0x313, 0x0, 0x395, 0x313, 0x300, 0x0, 0x395, 0x313,\n                0x301, 0x0, 0x395, 0x314, 0x0, 0x395, 0x314, 0x300, 0x0, 0x395,\n                0x314, 0x301, 0x0, 0x396, 0x0, 0x397, 0x0, 0x397, 0x300, 0x0,\n                0x397, 0x301, 0x0, 0x397, 0x313, 0x0, 0x397, 0x313, 0x300, 0x0,\n                0x397, 0x313, 0x300, 0x345, 0x0, 0x397, 0x313, 0x301, 0x0,\n                0x397, 0x313, 0x301, 0x345, 0x0, 0x397, 0x313, 0x342, 0x0,\n                0x397, 0x313, 0x342, 0x345, 0x0, 0x397, 0x313, 0x345, 0x0,\n                0x397, 0x314, 0x0, 0x397, 0x314, 0x300, 0x0, 0x397, 0x314,\n                0x300, 0x345, 0x0, 0x397, 0x314, 0x301, 0x0, 0x397, 0x314,\n                0x301, 0x345, 0x0, 0x397, 0x314, 0x342, 0x0, 0x397, 0x314,\n                0x342, 0x345, 0x0, 0x397, 0x314, 0x345, 0x0, 0x397, 0x345, 0x0,\n                0x398, 0x0, 0x399, 0x0, 0x399, 0x300, 0x0, 0x399, 0x301, 0x0,\n                0x399, 0x304, 0x0, 0x399, 0x306, 0x0, 0x399, 0x308, 0x0, 0x399,\n                0x313, 0x0, 0x399, 0x313, 0x300, 0x0, 0x399, 0x313, 0x301, 0x0,\n                0x399, 0x313, 0x342, 0x0, 0x399, 0x314, 0x0, 0x399, 0x314,\n                0x300, 0x0, 0x399, 0x314, 0x301, 0x0, 0x399, 0x314, 0x342, 0x0,\n                0x39a, 0x0, 0x39b, 0x0, 0x39c, 0x0, 0x39d, 0x0, 0x39e, 0x0,\n                0x39f, 0x0, 0x39f, 0x300, 0x0, 0x39f, 0x301, 0x0, 0x39f, 0x313,\n                0x0, 0x39f, 0x313, 0x300, 0x0, 0x39f, 0x313, 0x301, 0x0, 0x39f,\n                0x314, 0x0, 0x39f, 0x314, 0x300, 0x0, 0x39f, 0x314, 0x301, 0x0,\n                0x3a0, 0x0, 0x3a1, 0x0, 0x3a1, 0x314, 0x0, 0x3a3, 0x0, 0x3a4,\n                0x0, 0x3a5, 0x0, 0x3a5, 0x300, 0x0, 0x3a5, 0x301, 0x0, 0x3a5,\n                0x304, 0x0, 0x3a5, 0x306, 0x0, 0x3a5, 0x308, 0x0, 0x3a5, 0x314,\n                0x0, 0x3a5, 0x314, 0x300, 0x0, 0x3a5, 0x314, 0x301, 0x0, 0x3a5,\n                0x314, 0x342, 0x0, 0x3a6, 0x0, 0x3a7, 0x0, 0x3a8, 0x0, 0x3a9,\n                0x0, 0x3a9, 0x300, 0x0, 0x3a9, 0x301, 0x0, 0x3a9, 0x313, 0x0,\n                0x3a9, 0x313, 0x300, 0x0, 0x3a9, 0x313, 0x300, 0x345, 0x0,\n                0x3a9, 0x313, 0x301, 0x0, 0x3a9, 0x313, 0x301, 0x345, 0x0,\n                0x3a9, 0x313, 0x342, 0x0, 0x3a9, 0x313, 0x342, 0x345, 0x0,\n                0x3a9, 0x313, 0x345, 0x0, 0x3a9, 0x314, 0x0, 0x3a9, 0x314,\n                0x300, 0x0, 0x3a9, 0x314, 0x300, 0x345, 0x0, 0x3a9, 0x314,\n                0x301, 0x0, 0x3a9, 0x314, 0x301, 0x345, 0x0, 0x3a9, 0x314,\n                0x342, 0x0, 0x3a9, 0x314, 0x342, 0x345, 0x0, 0x3a9, 0x314,\n                0x345, 0x0, 0x3a9, 0x345, 0x0, 0x3b1, 0x0, 0x3b1, 0x300, 0x0,\n                0x3b1, 0x300, 0x345, 0x0, 0x3b1, 0x301, 0x0, 0x3b1, 0x301,\n                0x345, 0x0, 0x3b1, 0x304, 0x0, 0x3b1, 0x306, 0x0, 0x3b1, 0x313,\n                0x0, 0x3b1, 0x313, 0x300, 0x0, 0x3b1, 0x313, 0x300, 0x345, 0x0,\n                0x3b1, 0x313, 0x301, 0x0, 0x3b1, 0x313, 0x301, 0x345, 0x0,\n                0x3b1, 0x313, 0x342, 0x0, 0x3b1, 0x313, 0x342, 0x345, 0x0,\n                0x3b1, 0x313, 0x345, 0x0, 0x3b1, 0x314, 0x0, 0x3b1, 0x314,\n                0x300, 0x0, 0x3b1, 0x314, 0x300, 0x345, 0x0, 0x3b1, 0x314,\n                0x301, 0x0, 0x3b1, 0x314, 0x301, 0x345, 0x0, 0x3b1, 0x314,\n                0x342, 0x0, 0x3b1, 0x314, 0x342, 0x345, 0x0, 0x3b1, 0x314,\n                0x345, 0x0, 0x3b1, 0x342, 0x0, 0x3b1, 0x342, 0x345, 0x0, 0x3b1,\n                0x345, 0x0, 0x3b2, 0x0, 0x3b3, 0x0, 0x3b4, 0x0, 0x3b5, 0x0,\n                0x3b5, 0x300, 0x0, 0x3b5, 0x301, 0x0, 0x3b5, 0x313, 0x0, 0x3b5,\n                0x313, 0x300, 0x0, 0x3b5, 0x313, 0x301, 0x0, 0x3b5, 0x314, 0x0,\n                0x3b5, 0x314, 0x300, 0x0, 0x3b5, 0x314, 0x301, 0x0, 0x3b6, 0x0,\n                0x3b7, 0x0, 0x3b7, 0x300, 0x0, 0x3b7, 0x300, 0x345, 0x0, 0x3b7,\n                0x301, 0x0, 0x3b7, 0x301, 0x345, 0x0, 0x3b7, 0x313, 0x0, 0x3b7,\n                0x313, 0x300, 0x0, 0x3b7, 0x313, 0x300, 0x345, 0x0, 0x3b7,\n                0x313, 0x301, 0x0, 0x3b7, 0x313, 0x301, 0x345, 0x0, 0x3b7,\n                0x313, 0x342, 0x0, 0x3b7, 0x313, 0x342, 0x345, 0x0, 0x3b7,\n                0x313, 0x345, 0x0, 0x3b7, 0x314, 0x0, 0x3b7, 0x314, 0x300, 0x0,\n                0x3b7, 0x314, 0x300, 0x345, 0x0, 0x3b7, 0x314, 0x301, 0x0,\n                0x3b7, 0x314, 0x301, 0x345, 0x0, 0x3b7, 0x314, 0x342, 0x0,\n                0x3b7, 0x314, 0x342, 0x345, 0x0, 0x3b7, 0x314, 0x345, 0x0,\n                0x3b7, 0x342, 0x0, 0x3b7, 0x342, 0x345, 0x0, 0x3b7, 0x345, 0x0,\n                0x3b8, 0x0, 0x3b9, 0x0, 0x3b9, 0x300, 0x0, 0x3b9, 0x301, 0x0,\n                0x3b9, 0x304, 0x0, 0x3b9, 0x306, 0x0, 0x3b9, 0x308, 0x0, 0x3b9,\n                0x308, 0x300, 0x0, 0x3b9, 0x308, 0x301, 0x0, 0x3b9, 0x308,\n                0x342, 0x0, 0x3b9, 0x313, 0x0, 0x3b9, 0x313, 0x300, 0x0, 0x3b9,\n                0x313, 0x301, 0x0, 0x3b9, 0x313, 0x342, 0x0, 0x3b9, 0x314, 0x0,\n                0x3b9, 0x314, 0x300, 0x0, 0x3b9, 0x314, 0x301, 0x0, 0x3b9,\n                0x314, 0x342, 0x0, 0x3b9, 0x342, 0x0, 0x3ba, 0x0, 0x3bb, 0x0,\n                0x3bc, 0x0, 0x3bc, 0x41, 0x0, 0x3bc, 0x46, 0x0, 0x3bc, 0x56,\n                0x0, 0x3bc, 0x57, 0x0, 0x3bc, 0x67, 0x0, 0x3bc, 0x6c, 0x0,\n                0x3bc, 0x6d, 0x0, 0x3bc, 0x73, 0x0, 0x3bd, 0x0, 0x3be, 0x0,\n                0x3bf, 0x0, 0x3bf, 0x300, 0x0, 0x3bf, 0x301, 0x0, 0x3bf, 0x313,\n                0x0, 0x3bf, 0x313, 0x300, 0x0, 0x3bf, 0x313, 0x301, 0x0, 0x3bf,\n                0x314, 0x0, 0x3bf, 0x314, 0x300, 0x0, 0x3bf, 0x314, 0x301, 0x0,\n                0x3c0, 0x0, 0x3c1, 0x0, 0x3c1, 0x313, 0x0, 0x3c1, 0x314, 0x0,\n                0x3c2, 0x0, 0x3c3, 0x0, 0x3c4, 0x0, 0x3c5, 0x0, 0x3c5, 0x300,\n                0x0, 0x3c5, 0x301, 0x0, 0x3c5, 0x304, 0x0, 0x3c5, 0x306, 0x0,\n                0x3c5, 0x308, 0x0, 0x3c5, 0x308, 0x300, 0x0, 0x3c5, 0x308,\n                0x301, 0x0, 0x3c5, 0x308, 0x342, 0x0, 0x3c5, 0x313, 0x0, 0x3c5,\n                0x313, 0x300, 0x0, 0x3c5, 0x313, 0x301, 0x0, 0x3c5, 0x313,\n                0x342, 0x0, 0x3c5, 0x314, 0x0, 0x3c5, 0x314, 0x300, 0x0, 0x3c5,\n                0x314, 0x301, 0x0, 0x3c5, 0x314, 0x342, 0x0, 0x3c5, 0x342, 0x0,\n                0x3c6, 0x0, 0x3c7, 0x0, 0x3c8, 0x0, 0x3c9, 0x0, 0x3c9, 0x300,\n                0x0, 0x3c9, 0x300, 0x345, 0x0, 0x3c9, 0x301, 0x0, 0x3c9, 0x301,\n                0x345, 0x0, 0x3c9, 0x313, 0x0, 0x3c9, 0x313, 0x300, 0x0, 0x3c9,\n                0x313, 0x300, 0x345, 0x0, 0x3c9, 0x313, 0x301, 0x0, 0x3c9,\n                0x313, 0x301, 0x345, 0x0, 0x3c9, 0x313, 0x342, 0x0, 0x3c9,\n                0x313, 0x342, 0x345, 0x0, 0x3c9, 0x313, 0x345, 0x0, 0x3c9,\n                0x314, 0x0, 0x3c9, 0x314, 0x300, 0x0, 0x3c9, 0x314, 0x300,\n                0x345, 0x0, 0x3c9, 0x314, 0x301, 0x0, 0x3c9, 0x314, 0x301,\n                0x345, 0x0, 0x3c9, 0x314, 0x342, 0x0, 0x3c9, 0x314, 0x342,\n                0x345, 0x0, 0x3c9, 0x314, 0x345, 0x0, 0x3c9, 0x342, 0x0, 0x3c9,\n                0x342, 0x345, 0x0, 0x3c9, 0x345, 0x0, 0x3dc, 0x0, 0x3dd, 0x0,\n                0x406, 0x308, 0x0, 0x410, 0x306, 0x0, 0x410, 0x308, 0x0, 0x413,\n                0x301, 0x0, 0x415, 0x300, 0x0, 0x415, 0x306, 0x0, 0x415, 0x308,\n                0x0, 0x416, 0x306, 0x0, 0x416, 0x308, 0x0, 0x417, 0x308, 0x0,\n                0x418, 0x300, 0x0, 0x418, 0x304, 0x0, 0x418, 0x306, 0x0, 0x418,\n                0x308, 0x0, 0x41a, 0x301, 0x0, 0x41e, 0x308, 0x0, 0x423, 0x304,\n                0x0, 0x423, 0x306, 0x0, 0x423, 0x308, 0x0, 0x423, 0x30b, 0x0,\n                0x427, 0x308, 0x0, 0x42b, 0x308, 0x0, 0x42d, 0x308, 0x0, 0x430,\n                0x306, 0x0, 0x430, 0x308, 0x0, 0x433, 0x301, 0x0, 0x435, 0x300,\n                0x0, 0x435, 0x306, 0x0, 0x435, 0x308, 0x0, 0x436, 0x306, 0x0,\n                0x436, 0x308, 0x0, 0x437, 0x308, 0x0, 0x438, 0x300, 0x0, 0x438,\n                0x304, 0x0, 0x438, 0x306, 0x0, 0x438, 0x308, 0x0, 0x43a, 0x301,\n                0x0, 0x43d, 0x0, 0x43e, 0x308, 0x0, 0x443, 0x304, 0x0, 0x443,\n                0x306, 0x0, 0x443, 0x308, 0x0, 0x443, 0x30b, 0x0, 0x447, 0x308,\n                0x0, 0x44b, 0x308, 0x0, 0x44d, 0x308, 0x0, 0x456, 0x308, 0x0,\n                0x474, 0x30f, 0x0, 0x475, 0x30f, 0x0, 0x4d8, 0x308, 0x0, 0x4d9,\n                0x308, 0x0, 0x4e8, 0x308, 0x0, 0x4e9, 0x308, 0x0, 0x565, 0x582,\n                0x0, 0x574, 0x565, 0x0, 0x574, 0x56b, 0x0, 0x574, 0x56d, 0x0,\n                0x574, 0x576, 0x0, 0x57e, 0x576, 0x0, 0x5d0, 0x0, 0x5d0, 0x5b7,\n                0x0, 0x5d0, 0x5b8, 0x0, 0x5d0, 0x5bc, 0x0, 0x5d0, 0x5dc, 0x0,\n                0x5d1, 0x0, 0x5d1, 0x5bc, 0x0, 0x5d1, 0x5bf, 0x0, 0x5d2, 0x0,\n                0x5d2, 0x5bc, 0x0, 0x5d3, 0x0, 0x5d3, 0x5bc, 0x0, 0x5d4, 0x0,\n                0x5d4, 0x5bc, 0x0, 0x5d5, 0x5b9, 0x0, 0x5d5, 0x5bc, 0x0, 0x5d6,\n                0x5bc, 0x0, 0x5d8, 0x5bc, 0x0, 0x5d9, 0x5b4, 0x0, 0x5d9, 0x5bc,\n                0x0, 0x5da, 0x5bc, 0x0, 0x5db, 0x0, 0x5db, 0x5bc, 0x0, 0x5db,\n                0x5bf, 0x0, 0x5dc, 0x0, 0x5dc, 0x5bc, 0x0, 0x5dd, 0x0, 0x5de,\n                0x5bc, 0x0, 0x5e0, 0x5bc, 0x0, 0x5e1, 0x5bc, 0x0, 0x5e2, 0x0,\n                0x5e3, 0x5bc, 0x0, 0x5e4, 0x5bc, 0x0, 0x5e4, 0x5bf, 0x0, 0x5e6,\n                0x5bc, 0x0, 0x5e7, 0x5bc, 0x0, 0x5e8, 0x0, 0x5e8, 0x5bc, 0x0,\n                0x5e9, 0x5bc, 0x0, 0x5e9, 0x5bc, 0x5c1, 0x0, 0x5e9, 0x5bc,\n                0x5c2, 0x0, 0x5e9, 0x5c1, 0x0, 0x5e9, 0x5c2, 0x0, 0x5ea, 0x0,\n                0x5ea, 0x5bc, 0x0, 0x5f2, 0x5b7, 0x0, 0x621, 0x0, 0x627, 0x0,\n                0x627, 0x643, 0x628, 0x631, 0x0, 0x627, 0x644, 0x644, 0x647,\n                0x0, 0x627, 0x64b, 0x0, 0x627, 0x653, 0x0, 0x627, 0x654, 0x0,\n                0x627, 0x655, 0x0, 0x627, 0x674, 0x0, 0x628, 0x0, 0x628, 0x62c,\n                0x0, 0x628, 0x62d, 0x0, 0x628, 0x62d, 0x64a, 0x0, 0x628, 0x62e,\n                0x0, 0x628, 0x62e, 0x64a, 0x0, 0x628, 0x631, 0x0, 0x628, 0x632,\n                0x0, 0x628, 0x645, 0x0, 0x628, 0x646, 0x0, 0x628, 0x647, 0x0,\n                0x628, 0x649, 0x0, 0x628, 0x64a, 0x0, 0x629, 0x0, 0x62a, 0x0,\n                0x62a, 0x62c, 0x0, 0x62a, 0x62c, 0x645, 0x0, 0x62a, 0x62c,\n                0x649, 0x0, 0x62a, 0x62c, 0x64a, 0x0, 0x62a, 0x62d, 0x0, 0x62a,\n                0x62d, 0x62c, 0x0, 0x62a, 0x62d, 0x645, 0x0, 0x62a, 0x62e, 0x0,\n                0x62a, 0x62e, 0x645, 0x0, 0x62a, 0x62e, 0x649, 0x0, 0x62a,\n                0x62e, 0x64a, 0x0, 0x62a, 0x631, 0x0, 0x62a, 0x632, 0x0, 0x62a,\n                0x645, 0x0, 0x62a, 0x645, 0x62c, 0x0, 0x62a, 0x645, 0x62d, 0x0,\n                0x62a, 0x645, 0x62e, 0x0, 0x62a, 0x645, 0x649, 0x0, 0x62a,\n                0x645, 0x64a, 0x0, 0x62a, 0x646, 0x0, 0x62a, 0x647, 0x0, 0x62a,\n                0x649, 0x0, 0x62a, 0x64a, 0x0, 0x62b, 0x0, 0x62b, 0x62c, 0x0,\n                0x62b, 0x631, 0x0, 0x62b, 0x632, 0x0, 0x62b, 0x645, 0x0, 0x62b,\n                0x646, 0x0, 0x62b, 0x647, 0x0, 0x62b, 0x649, 0x0, 0x62b, 0x64a,\n                0x0, 0x62c, 0x0, 0x62c, 0x62d, 0x0, 0x62c, 0x62d, 0x649, 0x0,\n                0x62c, 0x62d, 0x64a, 0x0, 0x62c, 0x644, 0x20, 0x62c, 0x644,\n                0x627, 0x644, 0x647, 0x0, 0x62c, 0x645, 0x0, 0x62c, 0x645,\n                0x62d, 0x0, 0x62c, 0x645, 0x649, 0x0, 0x62c, 0x645, 0x64a, 0x0,\n                0x62c, 0x649, 0x0, 0x62c, 0x64a, 0x0, 0x62d, 0x0, 0x62d, 0x62c,\n                0x0, 0x62d, 0x62c, 0x64a, 0x0, 0x62d, 0x645, 0x0, 0x62d, 0x645,\n                0x649, 0x0, 0x62d, 0x645, 0x64a, 0x0, 0x62d, 0x649, 0x0, 0x62d,\n                0x64a, 0x0, 0x62e, 0x0, 0x62e, 0x62c, 0x0, 0x62e, 0x62d, 0x0,\n                0x62e, 0x645, 0x0, 0x62e, 0x649, 0x0, 0x62e, 0x64a, 0x0, 0x62f,\n                0x0, 0x630, 0x0, 0x630, 0x670, 0x0, 0x631, 0x0, 0x631, 0x633,\n                0x648, 0x644, 0x0, 0x631, 0x670, 0x0, 0x631, 0x6cc, 0x627,\n                0x644, 0x0, 0x632, 0x0, 0x633, 0x0, 0x633, 0x62c, 0x0, 0x633,\n                0x62c, 0x62d, 0x0, 0x633, 0x62c, 0x649, 0x0, 0x633, 0x62d, 0x0,\n                0x633, 0x62d, 0x62c, 0x0, 0x633, 0x62e, 0x0, 0x633, 0x62e,\n                0x649, 0x0, 0x633, 0x62e, 0x64a, 0x0, 0x633, 0x631, 0x0, 0x633,\n                0x645, 0x0, 0x633, 0x645, 0x62c, 0x0, 0x633, 0x645, 0x62d, 0x0,\n                0x633, 0x645, 0x645, 0x0, 0x633, 0x647, 0x0, 0x633, 0x649, 0x0,\n                0x633, 0x64a, 0x0, 0x634, 0x0, 0x634, 0x62c, 0x0, 0x634, 0x62c,\n                0x64a, 0x0, 0x634, 0x62d, 0x0, 0x634, 0x62d, 0x645, 0x0, 0x634,\n                0x62d, 0x64a, 0x0, 0x634, 0x62e, 0x0, 0x634, 0x631, 0x0, 0x634,\n                0x645, 0x0, 0x634, 0x645, 0x62e, 0x0, 0x634, 0x645, 0x645, 0x0,\n                0x634, 0x647, 0x0, 0x634, 0x649, 0x0, 0x634, 0x64a, 0x0, 0x635,\n                0x0, 0x635, 0x62d, 0x0, 0x635, 0x62d, 0x62d, 0x0, 0x635, 0x62d,\n                0x64a, 0x0, 0x635, 0x62e, 0x0, 0x635, 0x631, 0x0, 0x635, 0x644,\n                0x639, 0x645, 0x0, 0x635, 0x644, 0x649, 0x0, 0x635, 0x644,\n                0x649, 0x20, 0x627, 0x644, 0x644, 0x647, 0x20, 0x639, 0x644,\n                0x64a, 0x647, 0x20, 0x648, 0x633, 0x644, 0x645, 0x0, 0x635,\n                0x644, 0x6d2, 0x0, 0x635, 0x645, 0x0, 0x635, 0x645, 0x645, 0x0,\n                0x635, 0x649, 0x0, 0x635, 0x64a, 0x0, 0x636, 0x0, 0x636, 0x62c,\n                0x0, 0x636, 0x62d, 0x0, 0x636, 0x62d, 0x649, 0x0, 0x636, 0x62d,\n                0x64a, 0x0, 0x636, 0x62e, 0x0, 0x636, 0x62e, 0x645, 0x0, 0x636,\n                0x631, 0x0, 0x636, 0x645, 0x0, 0x636, 0x649, 0x0, 0x636, 0x64a,\n                0x0, 0x637, 0x0, 0x637, 0x62d, 0x0, 0x637, 0x645, 0x0, 0x637,\n                0x645, 0x62d, 0x0, 0x637, 0x645, 0x645, 0x0, 0x637, 0x645,\n                0x64a, 0x0, 0x637, 0x649, 0x0, 0x637, 0x64a, 0x0, 0x638, 0x0,\n                0x638, 0x645, 0x0, 0x639, 0x0, 0x639, 0x62c, 0x0, 0x639, 0x62c,\n                0x645, 0x0, 0x639, 0x644, 0x64a, 0x647, 0x0, 0x639, 0x645, 0x0,\n                0x639, 0x645, 0x645, 0x0, 0x639, 0x645, 0x649, 0x0, 0x639,\n                0x645, 0x64a, 0x0, 0x639, 0x649, 0x0, 0x639, 0x64a, 0x0, 0x63a,\n                0x0, 0x63a, 0x62c, 0x0, 0x63a, 0x645, 0x0, 0x63a, 0x645, 0x645,\n                0x0, 0x63a, 0x645, 0x649, 0x0, 0x63a, 0x645, 0x64a, 0x0, 0x63a,\n                0x649, 0x0, 0x63a, 0x64a, 0x0, 0x640, 0x64b, 0x0, 0x640, 0x64e,\n                0x0, 0x640, 0x64e, 0x651, 0x0, 0x640, 0x64f, 0x0, 0x640, 0x64f,\n                0x651, 0x0, 0x640, 0x650, 0x0, 0x640, 0x650, 0x651, 0x0, 0x640,\n                0x651, 0x0, 0x640, 0x652, 0x0, 0x641, 0x0, 0x641, 0x62c, 0x0,\n                0x641, 0x62d, 0x0, 0x641, 0x62e, 0x0, 0x641, 0x62e, 0x645, 0x0,\n                0x641, 0x645, 0x0, 0x641, 0x645, 0x64a, 0x0, 0x641, 0x649, 0x0,\n                0x641, 0x64a, 0x0, 0x642, 0x0, 0x642, 0x62d, 0x0, 0x642, 0x644,\n                0x6d2, 0x0, 0x642, 0x645, 0x0, 0x642, 0x645, 0x62d, 0x0, 0x642,\n                0x645, 0x645, 0x0, 0x642, 0x645, 0x64a, 0x0, 0x642, 0x649, 0x0,\n                0x642, 0x64a, 0x0, 0x643, 0x0, 0x643, 0x627, 0x0, 0x643, 0x62c,\n                0x0, 0x643, 0x62d, 0x0, 0x643, 0x62e, 0x0, 0x643, 0x644, 0x0,\n                0x643, 0x645, 0x0, 0x643, 0x645, 0x645, 0x0, 0x643, 0x645,\n                0x64a, 0x0, 0x643, 0x649, 0x0, 0x643, 0x64a, 0x0, 0x644, 0x0,\n                0x644, 0x627, 0x0, 0x644, 0x627, 0x653, 0x0, 0x644, 0x627,\n                0x654, 0x0, 0x644, 0x627, 0x655, 0x0, 0x644, 0x62c, 0x0, 0x644,\n                0x62c, 0x62c, 0x0, 0x644, 0x62c, 0x645, 0x0, 0x644, 0x62c,\n                0x64a, 0x0, 0x644, 0x62d, 0x0, 0x644, 0x62d, 0x645, 0x0, 0x644,\n                0x62d, 0x649, 0x0, 0x644, 0x62d, 0x64a, 0x0, 0x644, 0x62e, 0x0,\n                0x644, 0x62e, 0x645, 0x0, 0x644, 0x645, 0x0, 0x644, 0x645,\n                0x62d, 0x0, 0x644, 0x645, 0x64a, 0x0, 0x644, 0x647, 0x0, 0x644,\n                0x649, 0x0, 0x644, 0x64a, 0x0, 0x645, 0x0, 0x645, 0x627, 0x0,\n                0x645, 0x62c, 0x0, 0x645, 0x62c, 0x62d, 0x0, 0x645, 0x62c,\n                0x62e, 0x0, 0x645, 0x62c, 0x645, 0x0, 0x645, 0x62c, 0x64a, 0x0,\n                0x645, 0x62d, 0x0, 0x645, 0x62d, 0x62c, 0x0, 0x645, 0x62d,\n                0x645, 0x0, 0x645, 0x62d, 0x645, 0x62f, 0x0, 0x645, 0x62d,\n                0x64a, 0x0, 0x645, 0x62e, 0x0, 0x645, 0x62e, 0x62c, 0x0, 0x645,\n                0x62e, 0x645, 0x0, 0x645, 0x62e, 0x64a, 0x0, 0x645, 0x645, 0x0,\n                0x645, 0x645, 0x64a, 0x0, 0x645, 0x649, 0x0, 0x645, 0x64a, 0x0,\n                0x646, 0x0, 0x646, 0x62c, 0x0, 0x646, 0x62c, 0x62d, 0x0, 0x646,\n                0x62c, 0x645, 0x0, 0x646, 0x62c, 0x649, 0x0, 0x646, 0x62c,\n                0x64a, 0x0, 0x646, 0x62d, 0x0, 0x646, 0x62d, 0x645, 0x0, 0x646,\n                0x62d, 0x649, 0x0, 0x646, 0x62d, 0x64a, 0x0, 0x646, 0x62e, 0x0,\n                0x646, 0x631, 0x0, 0x646, 0x632, 0x0, 0x646, 0x645, 0x0, 0x646,\n                0x645, 0x649, 0x0, 0x646, 0x645, 0x64a, 0x0, 0x646, 0x646, 0x0,\n                0x646, 0x647, 0x0, 0x646, 0x649, 0x0, 0x646, 0x64a, 0x0, 0x647,\n                0x0, 0x647, 0x62c, 0x0, 0x647, 0x645, 0x0, 0x647, 0x645, 0x62c,\n                0x0, 0x647, 0x645, 0x645, 0x0, 0x647, 0x649, 0x0, 0x647, 0x64a,\n                0x0, 0x647, 0x670, 0x0, 0x648, 0x0, 0x648, 0x633, 0x644, 0x645,\n                0x0, 0x648, 0x654, 0x0, 0x648, 0x674, 0x0, 0x649, 0x0, 0x649,\n                0x670, 0x0, 0x64a, 0x0, 0x64a, 0x62c, 0x0, 0x64a, 0x62c, 0x64a,\n                0x0, 0x64a, 0x62d, 0x0, 0x64a, 0x62d, 0x64a, 0x0, 0x64a, 0x62e,\n                0x0, 0x64a, 0x631, 0x0, 0x64a, 0x632, 0x0, 0x64a, 0x645, 0x0,\n                0x64a, 0x645, 0x645, 0x0, 0x64a, 0x645, 0x64a, 0x0, 0x64a,\n                0x646, 0x0, 0x64a, 0x647, 0x0, 0x64a, 0x649, 0x0, 0x64a, 0x64a,\n                0x0, 0x64a, 0x654, 0x0, 0x64a, 0x654, 0x627, 0x0, 0x64a, 0x654,\n                0x62c, 0x0, 0x64a, 0x654, 0x62d, 0x0, 0x64a, 0x654, 0x62e, 0x0,\n                0x64a, 0x654, 0x631, 0x0, 0x64a, 0x654, 0x632, 0x0, 0x64a,\n                0x654, 0x645, 0x0, 0x64a, 0x654, 0x646, 0x0, 0x64a, 0x654,\n                0x647, 0x0, 0x64a, 0x654, 0x648, 0x0, 0x64a, 0x654, 0x649, 0x0,\n                0x64a, 0x654, 0x64a, 0x0, 0x64a, 0x654, 0x6c6, 0x0, 0x64a,\n                0x654, 0x6c7, 0x0, 0x64a, 0x654, 0x6c8, 0x0, 0x64a, 0x654,\n                0x6d0, 0x0, 0x64a, 0x654, 0x6d5, 0x0, 0x64a, 0x674, 0x0, 0x66e,\n                0x0, 0x66f, 0x0, 0x671, 0x0, 0x679, 0x0, 0x67a, 0x0, 0x67b,\n                0x0, 0x67e, 0x0, 0x67f, 0x0, 0x680, 0x0, 0x683, 0x0, 0x684,\n                0x0, 0x686, 0x0, 0x687, 0x0, 0x688, 0x0, 0x68c, 0x0, 0x68d,\n                0x0, 0x68e, 0x0, 0x691, 0x0, 0x698, 0x0, 0x6a1, 0x0, 0x6a4,\n                0x0, 0x6a6, 0x0, 0x6a9, 0x0, 0x6ad, 0x0, 0x6af, 0x0, 0x6b1,\n                0x0, 0x6b3, 0x0, 0x6ba, 0x0, 0x6bb, 0x0, 0x6be, 0x0, 0x6c1,\n                0x0, 0x6c1, 0x654, 0x0, 0x6c5, 0x0, 0x6c6, 0x0, 0x6c7, 0x0,\n                0x6c7, 0x674, 0x0, 0x6c8, 0x0, 0x6c9, 0x0, 0x6cb, 0x0, 0x6cc,\n                0x0, 0x6d0, 0x0, 0x6d2, 0x0, 0x6d2, 0x654, 0x0, 0x6d5, 0x654,\n                0x0, 0x915, 0x93c, 0x0, 0x916, 0x93c, 0x0, 0x917, 0x93c, 0x0,\n                0x91c, 0x93c, 0x0, 0x921, 0x93c, 0x0, 0x922, 0x93c, 0x0, 0x928,\n                0x93c, 0x0, 0x92b, 0x93c, 0x0, 0x92f, 0x93c, 0x0, 0x930, 0x93c,\n                0x0, 0x933, 0x93c, 0x0, 0x9a1, 0x9bc, 0x0, 0x9a2, 0x9bc, 0x0,\n                0x9af, 0x9bc, 0x0, 0x9c7, 0x9be, 0x0, 0x9c7, 0x9d7, 0x0, 0xa16,\n                0xa3c, 0x0, 0xa17, 0xa3c, 0x0, 0xa1c, 0xa3c, 0x0, 0xa2b, 0xa3c,\n                0x0, 0xa32, 0xa3c, 0x0, 0xa38, 0xa3c, 0x0, 0xb21, 0xb3c, 0x0,\n                0xb22, 0xb3c, 0x0, 0xb47, 0xb3e, 0x0, 0xb47, 0xb56, 0x0, 0xb47,\n                0xb57, 0x0, 0xb92, 0xbd7, 0x0, 0xbc6, 0xbbe, 0x0, 0xbc6, 0xbd7,\n                0x0, 0xbc7, 0xbbe, 0x0, 0xc46, 0xc56, 0x0, 0xcbf, 0xcd5, 0x0,\n                0xcc6, 0xcc2, 0x0, 0xcc6, 0xcc2, 0xcd5, 0x0, 0xcc6, 0xcd5, 0x0,\n                0xcc6, 0xcd6, 0x0, 0xd46, 0xd3e, 0x0, 0xd46, 0xd57, 0x0, 0xd47,\n                0xd3e, 0x0, 0xdd9, 0xdca, 0x0, 0xdd9, 0xdcf, 0x0, 0xdd9, 0xdcf,\n                0xdca, 0x0, 0xdd9, 0xddf, 0x0, 0xe4d, 0xe32, 0x0, 0xeab, 0xe99,\n                0x0, 0xeab, 0xea1, 0x0, 0xecd, 0xeb2, 0x0, 0xf0b, 0x0, 0xf40,\n                0xfb5, 0x0, 0xf42, 0xfb7, 0x0, 0xf4c, 0xfb7, 0x0, 0xf51, 0xfb7,\n                0x0, 0xf56, 0xfb7, 0x0, 0xf5b, 0xfb7, 0x0, 0xf71, 0xf72, 0x0,\n                0xf71, 0xf74, 0x0, 0xf71, 0xf80, 0x0, 0xf90, 0xfb5, 0x0, 0xf92,\n                0xfb7, 0x0, 0xf9c, 0xfb7, 0x0, 0xfa1, 0xfb7, 0x0, 0xfa6, 0xfb7,\n                0x0, 0xfab, 0xfb7, 0x0, 0xfb2, 0xf71, 0xf80, 0x0, 0xfb2, 0xf80,\n                0x0, 0xfb3, 0xf71, 0xf80, 0x0, 0xfb3, 0xf80, 0x0, 0x1025,\n                0x102e, 0x0, 0x10dc, 0x0, 0x1100, 0x0, 0x1100, 0x1161, 0x0,\n                0x1101, 0x0, 0x1102, 0x0, 0x1102, 0x1161, 0x0, 0x1103, 0x0,\n                0x1103, 0x1161, 0x0, 0x1104, 0x0, 0x1105, 0x0, 0x1105, 0x1161,\n                0x0, 0x1106, 0x0, 0x1106, 0x1161, 0x0, 0x1107, 0x0, 0x1107,\n                0x1161, 0x0, 0x1108, 0x0, 0x1109, 0x0, 0x1109, 0x1161, 0x0,\n                0x110a, 0x0, 0x110b, 0x0, 0x110b, 0x1161, 0x0, 0x110b, 0x116e,\n                0x0, 0x110c, 0x0, 0x110c, 0x1161, 0x0, 0x110c, 0x116e, 0x110b,\n                0x1174, 0x0, 0x110d, 0x0, 0x110e, 0x0, 0x110e, 0x1161, 0x0,\n                0x110e, 0x1161, 0x11b7, 0x1100, 0x1169, 0x0, 0x110f, 0x0,\n                0x110f, 0x1161, 0x0, 0x1110, 0x0, 0x1110, 0x1161, 0x0, 0x1111,\n                0x0, 0x1111, 0x1161, 0x0, 0x1112, 0x0, 0x1112, 0x1161, 0x0,\n                0x1114, 0x0, 0x1115, 0x0, 0x111a, 0x0, 0x111c, 0x0, 0x111d,\n                0x0, 0x111e, 0x0, 0x1120, 0x0, 0x1121, 0x0, 0x1122, 0x0,\n                0x1123, 0x0, 0x1127, 0x0, 0x1129, 0x0, 0x112b, 0x0, 0x112c,\n                0x0, 0x112d, 0x0, 0x112e, 0x0, 0x112f, 0x0, 0x1132, 0x0,\n                0x1136, 0x0, 0x1140, 0x0, 0x1147, 0x0, 0x114c, 0x0, 0x1157,\n                0x0, 0x1158, 0x0, 0x1159, 0x0, 0x1160, 0x0, 0x1161, 0x0,\n                0x1162, 0x0, 0x1163, 0x0, 0x1164, 0x0, 0x1165, 0x0, 0x1166,\n                0x0, 0x1167, 0x0, 0x1168, 0x0, 0x1169, 0x0, 0x116a, 0x0,\n                0x116b, 0x0, 0x116c, 0x0, 0x116d, 0x0, 0x116e, 0x0, 0x116f,\n                0x0, 0x1170, 0x0, 0x1171, 0x0, 0x1172, 0x0, 0x1173, 0x0,\n                0x1174, 0x0, 0x1175, 0x0, 0x1184, 0x0, 0x1185, 0x0, 0x1188,\n                0x0, 0x1191, 0x0, 0x1192, 0x0, 0x1194, 0x0, 0x119e, 0x0,\n                0x11a1, 0x0, 0x11aa, 0x0, 0x11ac, 0x0, 0x11ad, 0x0, 0x11b0,\n                0x0, 0x11b1, 0x0, 0x11b2, 0x0, 0x11b3, 0x0, 0x11b4, 0x0,\n                0x11b5, 0x0, 0x11c7, 0x0, 0x11c8, 0x0, 0x11cc, 0x0, 0x11ce,\n                0x0, 0x11d3, 0x0, 0x11d7, 0x0, 0x11d9, 0x0, 0x11dd, 0x0,\n                0x11df, 0x0, 0x11f1, 0x0, 0x11f2, 0x0, 0x1b05, 0x1b35, 0x0,\n                0x1b07, 0x1b35, 0x0, 0x1b09, 0x1b35, 0x0, 0x1b0b, 0x1b35, 0x0,\n                0x1b0d, 0x1b35, 0x0, 0x1b11, 0x1b35, 0x0, 0x1b3a, 0x1b35, 0x0,\n                0x1b3c, 0x1b35, 0x0, 0x1b3e, 0x1b35, 0x0, 0x1b3f, 0x1b35, 0x0,\n                0x1b42, 0x1b35, 0x0, 0x1d02, 0x0, 0x1d16, 0x0, 0x1d17, 0x0,\n                0x1d1c, 0x0, 0x1d1d, 0x0, 0x1d25, 0x0, 0x1d7b, 0x0, 0x1d85,\n                0x0, 0x2010, 0x0, 0x2013, 0x0, 0x2014, 0x0, 0x2032, 0x2032,\n                0x0, 0x2032, 0x2032, 0x2032, 0x0, 0x2032, 0x2032, 0x2032,\n                0x2032, 0x0, 0x2035, 0x2035, 0x0, 0x2035, 0x2035, 0x2035, 0x0,\n                0x20a9, 0x0, 0x2190, 0x0, 0x2190, 0x338, 0x0, 0x2191, 0x0,\n                0x2192, 0x0, 0x2192, 0x338, 0x0, 0x2193, 0x0, 0x2194, 0x338,\n                0x0, 0x21d0, 0x338, 0x0, 0x21d2, 0x338, 0x0, 0x21d4, 0x338,\n                0x0, 0x2202, 0x0, 0x2203, 0x338, 0x0, 0x2207, 0x0, 0x2208,\n                0x338, 0x0, 0x220b, 0x338, 0x0, 0x2211, 0x0, 0x2212, 0x0,\n                0x2223, 0x338, 0x0, 0x2225, 0x338, 0x0, 0x222b, 0x222b, 0x0,\n                0x222b, 0x222b, 0x222b, 0x0, 0x222b, 0x222b, 0x222b, 0x222b,\n                0x0, 0x222e, 0x222e, 0x0, 0x222e, 0x222e, 0x222e, 0x0, 0x223c,\n                0x338, 0x0, 0x2243, 0x338, 0x0, 0x2245, 0x338, 0x0, 0x2248,\n                0x338, 0x0, 0x224d, 0x338, 0x0, 0x2261, 0x338, 0x0, 0x2264,\n                0x338, 0x0, 0x2265, 0x338, 0x0, 0x2272, 0x338, 0x0, 0x2273,\n                0x338, 0x0, 0x2276, 0x338, 0x0, 0x2277, 0x338, 0x0, 0x227a,\n                0x338, 0x0, 0x227b, 0x338, 0x0, 0x227c, 0x338, 0x0, 0x227d,\n                0x338, 0x0, 0x2282, 0x338, 0x0, 0x2283, 0x338, 0x0, 0x2286,\n                0x338, 0x0, 0x2287, 0x338, 0x0, 0x2291, 0x338, 0x0, 0x2292,\n                0x338, 0x0, 0x22a2, 0x338, 0x0, 0x22a8, 0x338, 0x0, 0x22a9,\n                0x338, 0x0, 0x22ab, 0x338, 0x0, 0x22b2, 0x338, 0x0, 0x22b3,\n                0x338, 0x0, 0x22b4, 0x338, 0x0, 0x22b5, 0x338, 0x0, 0x2502,\n                0x0, 0x25a0, 0x0, 0x25cb, 0x0, 0x2985, 0x0, 0x2986, 0x0,\n                0x2add, 0x338, 0x0, 0x2d61, 0x0, 0x3001, 0x0, 0x3002, 0x0,\n                0x3008, 0x0, 0x3009, 0x0, 0x300a, 0x0, 0x300b, 0x0, 0x300c,\n                0x0, 0x300d, 0x0, 0x300e, 0x0, 0x300f, 0x0, 0x3010, 0x0,\n                0x3011, 0x0, 0x3012, 0x0, 0x3014, 0x0, 0x3014, 0x53, 0x3015,\n                0x0, 0x3014, 0x4e09, 0x3015, 0x0, 0x3014, 0x4e8c, 0x3015, 0x0,\n                0x3014, 0x52dd, 0x3015, 0x0, 0x3014, 0x5b89, 0x3015, 0x0,\n                0x3014, 0x6253, 0x3015, 0x0, 0x3014, 0x6557, 0x3015, 0x0,\n                0x3014, 0x672c, 0x3015, 0x0, 0x3014, 0x70b9, 0x3015, 0x0,\n                0x3014, 0x76d7, 0x3015, 0x0, 0x3015, 0x0, 0x3016, 0x0, 0x3017,\n                0x0, 0x3046, 0x3099, 0x0, 0x304b, 0x3099, 0x0, 0x304d, 0x3099,\n                0x0, 0x304f, 0x3099, 0x0, 0x3051, 0x3099, 0x0, 0x3053, 0x3099,\n                0x0, 0x3055, 0x3099, 0x0, 0x3057, 0x3099, 0x0, 0x3059, 0x3099,\n                0x0, 0x305b, 0x3099, 0x0, 0x305d, 0x3099, 0x0, 0x305f, 0x3099,\n                0x0, 0x3061, 0x3099, 0x0, 0x3064, 0x3099, 0x0, 0x3066, 0x3099,\n                0x0, 0x3068, 0x3099, 0x0, 0x306f, 0x3099, 0x0, 0x306f, 0x309a,\n                0x0, 0x3072, 0x3099, 0x0, 0x3072, 0x309a, 0x0, 0x3075, 0x3099,\n                0x0, 0x3075, 0x309a, 0x0, 0x3078, 0x3099, 0x0, 0x3078, 0x309a,\n                0x0, 0x307b, 0x304b, 0x0, 0x307b, 0x3099, 0x0, 0x307b, 0x309a,\n                0x0, 0x3088, 0x308a, 0x0, 0x3099, 0x0, 0x309a, 0x0, 0x309d,\n                0x3099, 0x0, 0x30a1, 0x0, 0x30a2, 0x0, 0x30a2, 0x30cf, 0x309a,\n                0x30fc, 0x30c8, 0x0, 0x30a2, 0x30eb, 0x30d5, 0x30a1, 0x0,\n                0x30a2, 0x30f3, 0x30d8, 0x309a, 0x30a2, 0x0, 0x30a2, 0x30fc,\n                0x30eb, 0x0, 0x30a3, 0x0, 0x30a4, 0x0, 0x30a4, 0x30cb, 0x30f3,\n                0x30af, 0x3099, 0x0, 0x30a4, 0x30f3, 0x30c1, 0x0, 0x30a5, 0x0,\n                0x30a6, 0x0, 0x30a6, 0x3099, 0x0, 0x30a6, 0x30a9, 0x30f3, 0x0,\n                0x30a7, 0x0, 0x30a8, 0x0, 0x30a8, 0x30b9, 0x30af, 0x30fc,\n                0x30c8, 0x3099, 0x0, 0x30a8, 0x30fc, 0x30ab, 0x30fc, 0x0,\n                0x30a9, 0x0, 0x30aa, 0x0, 0x30aa, 0x30f3, 0x30b9, 0x0, 0x30aa,\n                0x30fc, 0x30e0, 0x0, 0x30ab, 0x0, 0x30ab, 0x3099, 0x0, 0x30ab,\n                0x3099, 0x30ed, 0x30f3, 0x0, 0x30ab, 0x3099, 0x30f3, 0x30de,\n                0x0, 0x30ab, 0x30a4, 0x30ea, 0x0, 0x30ab, 0x30e9, 0x30c3,\n                0x30c8, 0x0, 0x30ab, 0x30ed, 0x30ea, 0x30fc, 0x0, 0x30ad, 0x0,\n                0x30ad, 0x3099, 0x0, 0x30ad, 0x3099, 0x30ab, 0x3099, 0x0,\n                0x30ad, 0x3099, 0x30cb, 0x30fc, 0x0, 0x30ad, 0x3099, 0x30eb,\n                0x30bf, 0x3099, 0x30fc, 0x0, 0x30ad, 0x30e5, 0x30ea, 0x30fc,\n                0x0, 0x30ad, 0x30ed, 0x0, 0x30ad, 0x30ed, 0x30af, 0x3099,\n                0x30e9, 0x30e0, 0x0, 0x30ad, 0x30ed, 0x30e1, 0x30fc, 0x30c8,\n                0x30eb, 0x0, 0x30ad, 0x30ed, 0x30ef, 0x30c3, 0x30c8, 0x0,\n                0x30af, 0x0, 0x30af, 0x3099, 0x0, 0x30af, 0x3099, 0x30e9,\n                0x30e0, 0x0, 0x30af, 0x3099, 0x30e9, 0x30e0, 0x30c8, 0x30f3,\n                0x0, 0x30af, 0x30eb, 0x30bb, 0x3099, 0x30a4, 0x30ed, 0x0,\n                0x30af, 0x30ed, 0x30fc, 0x30cd, 0x0, 0x30b1, 0x0, 0x30b1,\n                0x3099, 0x0, 0x30b1, 0x30fc, 0x30b9, 0x0, 0x30b3, 0x0, 0x30b3,\n                0x3099, 0x0, 0x30b3, 0x30b3, 0x0, 0x30b3, 0x30c8, 0x0, 0x30b3,\n                0x30eb, 0x30ca, 0x0, 0x30b3, 0x30fc, 0x30db, 0x309a, 0x0,\n                0x30b5, 0x0, 0x30b5, 0x3099, 0x0, 0x30b5, 0x30a4, 0x30af,\n                0x30eb, 0x0, 0x30b5, 0x30f3, 0x30c1, 0x30fc, 0x30e0, 0x0,\n                0x30b7, 0x0, 0x30b7, 0x3099, 0x0, 0x30b7, 0x30ea, 0x30f3,\n                0x30af, 0x3099, 0x0, 0x30b9, 0x0, 0x30b9, 0x3099, 0x0, 0x30bb,\n                0x0, 0x30bb, 0x3099, 0x0, 0x30bb, 0x30f3, 0x30c1, 0x0, 0x30bb,\n                0x30f3, 0x30c8, 0x0, 0x30bd, 0x0, 0x30bd, 0x3099, 0x0, 0x30bf,\n                0x0, 0x30bf, 0x3099, 0x0, 0x30bf, 0x3099, 0x30fc, 0x30b9, 0x0,\n                0x30c1, 0x0, 0x30c1, 0x3099, 0x0, 0x30c3, 0x0, 0x30c4, 0x0,\n                0x30c4, 0x3099, 0x0, 0x30c6, 0x0, 0x30c6, 0x3099, 0x0, 0x30c6,\n                0x3099, 0x30b7, 0x0, 0x30c8, 0x0, 0x30c8, 0x3099, 0x0, 0x30c8,\n                0x3099, 0x30eb, 0x0, 0x30c8, 0x30f3, 0x0, 0x30ca, 0x0, 0x30ca,\n                0x30ce, 0x0, 0x30cb, 0x0, 0x30cc, 0x0, 0x30cd, 0x0, 0x30ce,\n                0x0, 0x30ce, 0x30c3, 0x30c8, 0x0, 0x30cf, 0x0, 0x30cf, 0x3099,\n                0x0, 0x30cf, 0x3099, 0x30fc, 0x30ec, 0x30eb, 0x0, 0x30cf,\n                0x309a, 0x0, 0x30cf, 0x309a, 0x30fc, 0x30bb, 0x30f3, 0x30c8,\n                0x0, 0x30cf, 0x309a, 0x30fc, 0x30c4, 0x0, 0x30cf, 0x30a4,\n                0x30c4, 0x0, 0x30d2, 0x0, 0x30d2, 0x3099, 0x0, 0x30d2, 0x3099,\n                0x30eb, 0x0, 0x30d2, 0x309a, 0x0, 0x30d2, 0x309a, 0x30a2,\n                0x30b9, 0x30c8, 0x30eb, 0x0, 0x30d2, 0x309a, 0x30af, 0x30eb,\n                0x0, 0x30d2, 0x309a, 0x30b3, 0x0, 0x30d5, 0x0, 0x30d5, 0x3099,\n                0x0, 0x30d5, 0x3099, 0x30c3, 0x30b7, 0x30a7, 0x30eb, 0x0,\n                0x30d5, 0x309a, 0x0, 0x30d5, 0x30a1, 0x30e9, 0x30c3, 0x30c8,\n                0x3099, 0x0, 0x30d5, 0x30a3, 0x30fc, 0x30c8, 0x0, 0x30d5,\n                0x30e9, 0x30f3, 0x0, 0x30d8, 0x0, 0x30d8, 0x3099, 0x0, 0x30d8,\n                0x3099, 0x30fc, 0x30bf, 0x0, 0x30d8, 0x309a, 0x0, 0x30d8,\n                0x309a, 0x30bd, 0x0, 0x30d8, 0x309a, 0x30cb, 0x30d2, 0x0,\n                0x30d8, 0x309a, 0x30f3, 0x30b9, 0x0, 0x30d8, 0x309a, 0x30fc,\n                0x30b7, 0x3099, 0x0, 0x30d8, 0x30af, 0x30bf, 0x30fc, 0x30eb,\n                0x0, 0x30d8, 0x30eb, 0x30c4, 0x0, 0x30db, 0x0, 0x30db, 0x3099,\n                0x0, 0x30db, 0x3099, 0x30eb, 0x30c8, 0x0, 0x30db, 0x309a, 0x0,\n                0x30db, 0x309a, 0x30a4, 0x30f3, 0x30c8, 0x0, 0x30db, 0x309a,\n                0x30f3, 0x30c8, 0x3099, 0x0, 0x30db, 0x30f3, 0x0, 0x30db,\n                0x30fc, 0x30eb, 0x0, 0x30db, 0x30fc, 0x30f3, 0x0, 0x30de, 0x0,\n                0x30de, 0x30a4, 0x30af, 0x30ed, 0x0, 0x30de, 0x30a4, 0x30eb,\n                0x0, 0x30de, 0x30c3, 0x30cf, 0x0, 0x30de, 0x30eb, 0x30af, 0x0,\n                0x30de, 0x30f3, 0x30b7, 0x30e7, 0x30f3, 0x0, 0x30df, 0x0,\n                0x30df, 0x30af, 0x30ed, 0x30f3, 0x0, 0x30df, 0x30ea, 0x0,\n                0x30df, 0x30ea, 0x30cf, 0x3099, 0x30fc, 0x30eb, 0x0, 0x30e0,\n                0x0, 0x30e1, 0x0, 0x30e1, 0x30ab, 0x3099, 0x0, 0x30e1, 0x30ab,\n                0x3099, 0x30c8, 0x30f3, 0x0, 0x30e1, 0x30fc, 0x30c8, 0x30eb,\n                0x0, 0x30e2, 0x0, 0x30e3, 0x0, 0x30e4, 0x0, 0x30e4, 0x30fc,\n                0x30c8, 0x3099, 0x0, 0x30e4, 0x30fc, 0x30eb, 0x0, 0x30e5, 0x0,\n                0x30e6, 0x0, 0x30e6, 0x30a2, 0x30f3, 0x0, 0x30e7, 0x0, 0x30e8,\n                0x0, 0x30e9, 0x0, 0x30ea, 0x0, 0x30ea, 0x30c3, 0x30c8, 0x30eb,\n                0x0, 0x30ea, 0x30e9, 0x0, 0x30eb, 0x0, 0x30eb, 0x30d2, 0x309a,\n                0x30fc, 0x0, 0x30eb, 0x30fc, 0x30d5, 0x3099, 0x30eb, 0x0,\n                0x30ec, 0x0, 0x30ec, 0x30e0, 0x0, 0x30ec, 0x30f3, 0x30c8,\n                0x30b1, 0x3099, 0x30f3, 0x0, 0x30ed, 0x0, 0x30ef, 0x0, 0x30ef,\n                0x3099, 0x0, 0x30ef, 0x30c3, 0x30c8, 0x0, 0x30f0, 0x0, 0x30f0,\n                0x3099, 0x0, 0x30f1, 0x0, 0x30f1, 0x3099, 0x0, 0x30f2, 0x0,\n                0x30f2, 0x3099, 0x0, 0x30f3, 0x0, 0x30fb, 0x0, 0x30fc, 0x0,\n                0x30fd, 0x3099, 0x0, 0x349e, 0x0, 0x34b9, 0x0, 0x34bb, 0x0,\n                0x34df, 0x0, 0x3515, 0x0, 0x36ee, 0x0, 0x36fc, 0x0, 0x3781,\n                0x0, 0x382f, 0x0, 0x3862, 0x0, 0x387c, 0x0, 0x38c7, 0x0,\n                0x38e3, 0x0, 0x391c, 0x0, 0x393a, 0x0, 0x3a2e, 0x0, 0x3a6c,\n                0x0, 0x3ae4, 0x0, 0x3b08, 0x0, 0x3b19, 0x0, 0x3b49, 0x0,\n                0x3b9d, 0x0, 0x3c18, 0x0, 0x3c4e, 0x0, 0x3d33, 0x0, 0x3d96,\n                0x0, 0x3eac, 0x0, 0x3eb8, 0x0, 0x3f1b, 0x0, 0x3ffc, 0x0,\n                0x4008, 0x0, 0x4018, 0x0, 0x4039, 0x0, 0x4046, 0x0, 0x4096,\n                0x0, 0x40e3, 0x0, 0x412f, 0x0, 0x4202, 0x0, 0x4227, 0x0,\n                0x42a0, 0x0, 0x4301, 0x0, 0x4334, 0x0, 0x4359, 0x0, 0x43d5,\n                0x0, 0x43d9, 0x0, 0x440b, 0x0, 0x446b, 0x0, 0x452b, 0x0,\n                0x455d, 0x0, 0x4561, 0x0, 0x456b, 0x0, 0x45d7, 0x0, 0x45f9,\n                0x0, 0x4635, 0x0, 0x46be, 0x0, 0x46c7, 0x0, 0x4995, 0x0,\n                0x49e6, 0x0, 0x4a6e, 0x0, 0x4a76, 0x0, 0x4ab2, 0x0, 0x4b33,\n                0x0, 0x4bce, 0x0, 0x4cce, 0x0, 0x4ced, 0x0, 0x4cf8, 0x0,\n                0x4d56, 0x0, 0x4e00, 0x0, 0x4e01, 0x0, 0x4e03, 0x0, 0x4e09,\n                0x0, 0x4e0a, 0x0, 0x4e0b, 0x0, 0x4e0d, 0x0, 0x4e19, 0x0,\n                0x4e26, 0x0, 0x4e28, 0x0, 0x4e2d, 0x0, 0x4e32, 0x0, 0x4e36,\n                0x0, 0x4e38, 0x0, 0x4e39, 0x0, 0x4e3d, 0x0, 0x4e3f, 0x0,\n                0x4e41, 0x0, 0x4e59, 0x0, 0x4e5d, 0x0, 0x4e82, 0x0, 0x4e85,\n                0x0, 0x4e86, 0x0, 0x4e8c, 0x0, 0x4e94, 0x0, 0x4ea0, 0x0,\n                0x4ea4, 0x0, 0x4eae, 0x0, 0x4eba, 0x0, 0x4ec0, 0x0, 0x4ecc,\n                0x0, 0x4ee4, 0x0, 0x4f01, 0x0, 0x4f11, 0x0, 0x4f60, 0x0,\n                0x4f80, 0x0, 0x4f86, 0x0, 0x4f8b, 0x0, 0x4fae, 0x0, 0x4fbb,\n                0x0, 0x4fbf, 0x0, 0x5002, 0x0, 0x502b, 0x0, 0x507a, 0x0,\n                0x5099, 0x0, 0x50cf, 0x0, 0x50da, 0x0, 0x50e7, 0x0, 0x512a,\n                0x0, 0x513f, 0x0, 0x5140, 0x0, 0x5145, 0x0, 0x514d, 0x0,\n                0x5154, 0x0, 0x5164, 0x0, 0x5165, 0x0, 0x5167, 0x0, 0x5168,\n                0x0, 0x5169, 0x0, 0x516b, 0x0, 0x516d, 0x0, 0x5177, 0x0,\n                0x5180, 0x0, 0x5182, 0x0, 0x518d, 0x0, 0x5192, 0x0, 0x5195,\n                0x0, 0x5196, 0x0, 0x5197, 0x0, 0x5199, 0x0, 0x51a4, 0x0,\n                0x51ab, 0x0, 0x51ac, 0x0, 0x51b5, 0x0, 0x51b7, 0x0, 0x51c9,\n                0x0, 0x51cc, 0x0, 0x51dc, 0x0, 0x51de, 0x0, 0x51e0, 0x0,\n                0x51f5, 0x0, 0x5200, 0x0, 0x5203, 0x0, 0x5207, 0x0, 0x5217,\n                0x0, 0x521d, 0x0, 0x5229, 0x0, 0x523a, 0x0, 0x523b, 0x0,\n                0x5246, 0x0, 0x524d, 0x0, 0x5272, 0x0, 0x5277, 0x0, 0x5289,\n                0x0, 0x529b, 0x0, 0x52a3, 0x0, 0x52b3, 0x0, 0x52b4, 0x0,\n                0x52c7, 0x0, 0x52c9, 0x0, 0x52d2, 0x0, 0x52de, 0x0, 0x52e4,\n                0x0, 0x52f5, 0x0, 0x52f9, 0x0, 0x52fa, 0x0, 0x5305, 0x0,\n                0x5306, 0x0, 0x5315, 0x0, 0x5317, 0x0, 0x531a, 0x0, 0x5338,\n                0x0, 0x533b, 0x0, 0x533f, 0x0, 0x5341, 0x0, 0x5344, 0x0,\n                0x5345, 0x0, 0x5349, 0x0, 0x5351, 0x0, 0x5354, 0x0, 0x535a,\n                0x0, 0x535c, 0x0, 0x5369, 0x0, 0x5370, 0x0, 0x5373, 0x0,\n                0x5375, 0x0, 0x537d, 0x0, 0x537f, 0x0, 0x5382, 0x0, 0x53b6,\n                0x0, 0x53c3, 0x0, 0x53c8, 0x0, 0x53ca, 0x0, 0x53cc, 0x0,\n                0x53df, 0x0, 0x53e3, 0x0, 0x53e5, 0x0, 0x53eb, 0x0, 0x53ef,\n                0x0, 0x53f1, 0x0, 0x53f3, 0x0, 0x5406, 0x0, 0x5408, 0x0,\n                0x540d, 0x0, 0x540f, 0x0, 0x541d, 0x0, 0x5438, 0x0, 0x5439,\n                0x0, 0x5442, 0x0, 0x5448, 0x0, 0x5468, 0x0, 0x549e, 0x0,\n                0x54a2, 0x0, 0x54bd, 0x0, 0x54f6, 0x0, 0x5510, 0x0, 0x554f,\n                0x0, 0x5553, 0x0, 0x5555, 0x0, 0x5563, 0x0, 0x5584, 0x0,\n                0x5587, 0x0, 0x5599, 0x0, 0x559d, 0x0, 0x55ab, 0x0, 0x55b3,\n                0x0, 0x55b6, 0x0, 0x55c0, 0x0, 0x55c2, 0x0, 0x55e2, 0x0,\n                0x5606, 0x0, 0x5651, 0x0, 0x5668, 0x0, 0x5674, 0x0, 0x56d7,\n                0x0, 0x56db, 0x0, 0x56f9, 0x0, 0x5716, 0x0, 0x5717, 0x0,\n                0x571f, 0x0, 0x5730, 0x0, 0x578b, 0x0, 0x57ce, 0x0, 0x57f4,\n                0x0, 0x580d, 0x0, 0x5831, 0x0, 0x5832, 0x0, 0x5840, 0x0,\n                0x585a, 0x0, 0x585e, 0x0, 0x58a8, 0x0, 0x58ac, 0x0, 0x58b3,\n                0x0, 0x58d8, 0x0, 0x58df, 0x0, 0x58eb, 0x0, 0x58ee, 0x0,\n                0x58f0, 0x0, 0x58f2, 0x0, 0x58f7, 0x0, 0x5902, 0x0, 0x5906,\n                0x0, 0x590a, 0x0, 0x5915, 0x0, 0x591a, 0x0, 0x591c, 0x0,\n                0x5922, 0x0, 0x5927, 0x0, 0x5927, 0x6b63, 0x0, 0x5929, 0x0,\n                0x5944, 0x0, 0x5948, 0x0, 0x5951, 0x0, 0x5954, 0x0, 0x5962,\n                0x0, 0x5973, 0x0, 0x59d8, 0x0, 0x59ec, 0x0, 0x5a1b, 0x0,\n                0x5a27, 0x0, 0x5a62, 0x0, 0x5a66, 0x0, 0x5ab5, 0x0, 0x5b08,\n                0x0, 0x5b28, 0x0, 0x5b3e, 0x0, 0x5b50, 0x0, 0x5b57, 0x0,\n                0x5b66, 0x0, 0x5b80, 0x0, 0x5b85, 0x0, 0x5b97, 0x0, 0x5bc3,\n                0x0, 0x5bd8, 0x0, 0x5be7, 0x0, 0x5bee, 0x0, 0x5bf3, 0x0,\n                0x5bf8, 0x0, 0x5bff, 0x0, 0x5c06, 0x0, 0x5c0f, 0x0, 0x5c22,\n                0x0, 0x5c38, 0x0, 0x5c3f, 0x0, 0x5c60, 0x0, 0x5c62, 0x0,\n                0x5c64, 0x0, 0x5c65, 0x0, 0x5c6e, 0x0, 0x5c71, 0x0, 0x5c8d,\n                0x0, 0x5cc0, 0x0, 0x5d19, 0x0, 0x5d43, 0x0, 0x5d50, 0x0,\n                0x5d6b, 0x0, 0x5d6e, 0x0, 0x5d7c, 0x0, 0x5db2, 0x0, 0x5dba,\n                0x0, 0x5ddb, 0x0, 0x5de1, 0x0, 0x5de2, 0x0, 0x5de5, 0x0,\n                0x5de6, 0x0, 0x5df1, 0x0, 0x5dfd, 0x0, 0x5dfe, 0x0, 0x5e28,\n                0x0, 0x5e3d, 0x0, 0x5e69, 0x0, 0x5e72, 0x0, 0x5e73, 0x6210,\n                0x0, 0x5e74, 0x0, 0x5e7a, 0x0, 0x5e7c, 0x0, 0x5e7f, 0x0,\n                0x5ea6, 0x0, 0x5eb0, 0x0, 0x5eb3, 0x0, 0x5eb6, 0x0, 0x5ec9,\n                0x0, 0x5eca, 0x0, 0x5ed2, 0x0, 0x5ed3, 0x0, 0x5ed9, 0x0,\n                0x5eec, 0x0, 0x5ef4, 0x0, 0x5efe, 0x0, 0x5f04, 0x0, 0x5f0b,\n                0x0, 0x5f13, 0x0, 0x5f22, 0x0, 0x5f50, 0x0, 0x5f53, 0x0,\n                0x5f61, 0x0, 0x5f62, 0x0, 0x5f69, 0x0, 0x5f6b, 0x0, 0x5f73,\n                0x0, 0x5f8b, 0x0, 0x5f8c, 0x0, 0x5f97, 0x0, 0x5f9a, 0x0,\n                0x5fa9, 0x0, 0x5fad, 0x0, 0x5fc3, 0x0, 0x5fcd, 0x0, 0x5fd7,\n                0x0, 0x5ff5, 0x0, 0x5ff9, 0x0, 0x6012, 0x0, 0x601c, 0x0,\n                0x6075, 0x0, 0x6081, 0x0, 0x6094, 0x0, 0x60c7, 0x0, 0x60d8,\n                0x0, 0x60e1, 0x0, 0x6108, 0x0, 0x6144, 0x0, 0x6148, 0x0,\n                0x614c, 0x0, 0x614e, 0x0, 0x6160, 0x0, 0x6168, 0x0, 0x617a,\n                0x0, 0x618e, 0x0, 0x6190, 0x0, 0x61a4, 0x0, 0x61af, 0x0,\n                0x61b2, 0x0, 0x61de, 0x0, 0x61f2, 0x0, 0x61f6, 0x0, 0x6200,\n                0x0, 0x6208, 0x0, 0x6210, 0x0, 0x621b, 0x0, 0x622e, 0x0,\n                0x6234, 0x0, 0x6236, 0x0, 0x624b, 0x0, 0x6253, 0x0, 0x625d,\n                0x0, 0x6295, 0x0, 0x62b1, 0x0, 0x62c9, 0x0, 0x62cf, 0x0,\n                0x62d3, 0x0, 0x62d4, 0x0, 0x62fc, 0x0, 0x62fe, 0x0, 0x6307,\n                0x0, 0x633d, 0x0, 0x6350, 0x0, 0x6355, 0x0, 0x6368, 0x0,\n                0x637b, 0x0, 0x6383, 0x0, 0x63a0, 0x0, 0x63a9, 0x0, 0x63c4,\n                0x0, 0x63c5, 0x0, 0x63e4, 0x0, 0x641c, 0x0, 0x6422, 0x0,\n                0x6452, 0x0, 0x6469, 0x0, 0x6477, 0x0, 0x647e, 0x0, 0x649a,\n                0x0, 0x649d, 0x0, 0x64c4, 0x0, 0x652f, 0x0, 0x6534, 0x0,\n                0x654f, 0x0, 0x6556, 0x0, 0x656c, 0x0, 0x6578, 0x0, 0x6587,\n                0x0, 0x6597, 0x0, 0x6599, 0x0, 0x65a4, 0x0, 0x65b0, 0x0,\n                0x65b9, 0x0, 0x65c5, 0x0, 0x65e0, 0x0, 0x65e2, 0x0, 0x65e3,\n                0x0, 0x65e5, 0x0, 0x660e, 0x6cbb, 0x0, 0x6613, 0x0, 0x6620,\n                0x0, 0x662d, 0x548c, 0x0, 0x6649, 0x0, 0x6674, 0x0, 0x6688,\n                0x0, 0x6691, 0x0, 0x669c, 0x0, 0x66b4, 0x0, 0x66c6, 0x0,\n                0x66f0, 0x0, 0x66f4, 0x0, 0x66f8, 0x0, 0x6700, 0x0, 0x6708,\n                0x0, 0x6709, 0x0, 0x6717, 0x0, 0x671b, 0x0, 0x6721, 0x0,\n                0x6728, 0x0, 0x674e, 0x0, 0x6753, 0x0, 0x6756, 0x0, 0x675e,\n                0x0, 0x677b, 0x0, 0x6785, 0x0, 0x6797, 0x0, 0x67f3, 0x0,\n                0x67fa, 0x0, 0x6817, 0x0, 0x681f, 0x0, 0x682a, 0x0, 0x682a,\n                0x5f0f, 0x4f1a, 0x793e, 0x0, 0x6852, 0x0, 0x6881, 0x0, 0x6885,\n                0x0, 0x688e, 0x0, 0x68a8, 0x0, 0x6914, 0x0, 0x6942, 0x0,\n                0x69a3, 0x0, 0x69ea, 0x0, 0x6a02, 0x0, 0x6a13, 0x0, 0x6aa8,\n                0x0, 0x6ad3, 0x0, 0x6adb, 0x0, 0x6b04, 0x0, 0x6b20, 0x0,\n                0x6b21, 0x0, 0x6b54, 0x0, 0x6b62, 0x0, 0x6b63, 0x0, 0x6b72,\n                0x0, 0x6b77, 0x0, 0x6b79, 0x0, 0x6b9f, 0x0, 0x6bae, 0x0,\n                0x6bb3, 0x0, 0x6bba, 0x0, 0x6bbb, 0x0, 0x6bcb, 0x0, 0x6bcd,\n                0x0, 0x6bd4, 0x0, 0x6bdb, 0x0, 0x6c0f, 0x0, 0x6c14, 0x0,\n                0x6c34, 0x0, 0x6c4e, 0x0, 0x6c67, 0x0, 0x6c88, 0x0, 0x6cbf,\n                0x0, 0x6ccc, 0x0, 0x6ccd, 0x0, 0x6ce5, 0x0, 0x6ce8, 0x0,\n                0x6d16, 0x0, 0x6d1b, 0x0, 0x6d1e, 0x0, 0x6d34, 0x0, 0x6d3e,\n                0x0, 0x6d41, 0x0, 0x6d69, 0x0, 0x6d6a, 0x0, 0x6d77, 0x0,\n                0x6d78, 0x0, 0x6d85, 0x0, 0x6dcb, 0x0, 0x6dda, 0x0, 0x6dea,\n                0x0, 0x6df9, 0x0, 0x6e1a, 0x0, 0x6e2f, 0x0, 0x6e6e, 0x0,\n                0x6e80, 0x0, 0x6e9c, 0x0, 0x6eba, 0x0, 0x6ec7, 0x0, 0x6ecb,\n                0x0, 0x6ed1, 0x0, 0x6edb, 0x0, 0x6f0f, 0x0, 0x6f14, 0x0,\n                0x6f22, 0x0, 0x6f23, 0x0, 0x6f6e, 0x0, 0x6fc6, 0x0, 0x6feb,\n                0x0, 0x6ffe, 0x0, 0x701b, 0x0, 0x701e, 0x0, 0x7039, 0x0,\n                0x704a, 0x0, 0x706b, 0x0, 0x7070, 0x0, 0x7077, 0x0, 0x707d,\n                0x0, 0x7099, 0x0, 0x70ad, 0x0, 0x70c8, 0x0, 0x70d9, 0x0,\n                0x7121, 0x0, 0x7145, 0x0, 0x7149, 0x0, 0x716e, 0x0, 0x719c,\n                0x0, 0x71ce, 0x0, 0x71d0, 0x0, 0x7210, 0x0, 0x721b, 0x0,\n                0x7228, 0x0, 0x722a, 0x0, 0x722b, 0x0, 0x7235, 0x0, 0x7236,\n                0x0, 0x723b, 0x0, 0x723f, 0x0, 0x7247, 0x0, 0x7250, 0x0,\n                0x7259, 0x0, 0x725b, 0x0, 0x7262, 0x0, 0x7279, 0x0, 0x7280,\n                0x0, 0x7295, 0x0, 0x72ac, 0x0, 0x72af, 0x0, 0x72c0, 0x0,\n                0x72fc, 0x0, 0x732a, 0x0, 0x7375, 0x0, 0x737a, 0x0, 0x7384,\n                0x0, 0x7387, 0x0, 0x7389, 0x0, 0x738b, 0x0, 0x73a5, 0x0,\n                0x73b2, 0x0, 0x73de, 0x0, 0x7406, 0x0, 0x7409, 0x0, 0x7422,\n                0x0, 0x7447, 0x0, 0x745c, 0x0, 0x7469, 0x0, 0x7471, 0x0,\n                0x7485, 0x0, 0x7489, 0x0, 0x7498, 0x0, 0x74ca, 0x0, 0x74dc,\n                0x0, 0x74e6, 0x0, 0x7506, 0x0, 0x7518, 0x0, 0x751f, 0x0,\n                0x7524, 0x0, 0x7528, 0x0, 0x7530, 0x0, 0x7532, 0x0, 0x7533,\n                0x0, 0x7537, 0x0, 0x753b, 0x0, 0x753e, 0x0, 0x7559, 0x0,\n                0x7565, 0x0, 0x7570, 0x0, 0x758b, 0x0, 0x7592, 0x0, 0x75e2,\n                0x0, 0x7610, 0x0, 0x761d, 0x0, 0x761f, 0x0, 0x7642, 0x0,\n                0x7669, 0x0, 0x7676, 0x0, 0x767d, 0x0, 0x76ae, 0x0, 0x76bf,\n                0x0, 0x76ca, 0x0, 0x76db, 0x0, 0x76e3, 0x0, 0x76e7, 0x0,\n                0x76ee, 0x0, 0x76f4, 0x0, 0x7701, 0x0, 0x771e, 0x0, 0x771f,\n                0x0, 0x7740, 0x0, 0x774a, 0x0, 0x778b, 0x0, 0x77a7, 0x0,\n                0x77db, 0x0, 0x77e2, 0x0, 0x77f3, 0x0, 0x784e, 0x0, 0x786b,\n                0x0, 0x788c, 0x0, 0x7891, 0x0, 0x78ca, 0x0, 0x78cc, 0x0,\n                0x78fb, 0x0, 0x792a, 0x0, 0x793a, 0x0, 0x793c, 0x0, 0x793e,\n                0x0, 0x7948, 0x0, 0x7949, 0x0, 0x7950, 0x0, 0x7956, 0x0,\n                0x795d, 0x0, 0x795e, 0x0, 0x7965, 0x0, 0x797f, 0x0, 0x7981,\n                0x0, 0x798d, 0x0, 0x798e, 0x0, 0x798f, 0x0, 0x79ae, 0x0,\n                0x79b8, 0x0, 0x79be, 0x0, 0x79ca, 0x0, 0x79d8, 0x0, 0x79eb,\n                0x0, 0x7a1c, 0x0, 0x7a40, 0x0, 0x7a4a, 0x0, 0x7a4f, 0x0,\n                0x7a74, 0x0, 0x7a7a, 0x0, 0x7a81, 0x0, 0x7ab1, 0x0, 0x7acb,\n                0x0, 0x7aee, 0x0, 0x7af9, 0x0, 0x7b20, 0x0, 0x7b8f, 0x0,\n                0x7bc0, 0x0, 0x7bc6, 0x0, 0x7bc9, 0x0, 0x7c3e, 0x0, 0x7c60,\n                0x0, 0x7c73, 0x0, 0x7c7b, 0x0, 0x7c92, 0x0, 0x7cbe, 0x0,\n                0x7cd2, 0x0, 0x7cd6, 0x0, 0x7ce3, 0x0, 0x7ce7, 0x0, 0x7ce8,\n                0x0, 0x7cf8, 0x0, 0x7d00, 0x0, 0x7d10, 0x0, 0x7d22, 0x0,\n                0x7d2f, 0x0, 0x7d42, 0x0, 0x7d5b, 0x0, 0x7d63, 0x0, 0x7da0,\n                0x0, 0x7dbe, 0x0, 0x7dc7, 0x0, 0x7df4, 0x0, 0x7e02, 0x0,\n                0x7e09, 0x0, 0x7e37, 0x0, 0x7e41, 0x0, 0x7e45, 0x0, 0x7f36,\n                0x0, 0x7f3e, 0x0, 0x7f51, 0x0, 0x7f72, 0x0, 0x7f79, 0x0,\n                0x7f7a, 0x0, 0x7f85, 0x0, 0x7f8a, 0x0, 0x7f95, 0x0, 0x7f9a,\n                0x0, 0x7fbd, 0x0, 0x7ffa, 0x0, 0x8001, 0x0, 0x8005, 0x0,\n                0x800c, 0x0, 0x8012, 0x0, 0x8033, 0x0, 0x8046, 0x0, 0x8060,\n                0x0, 0x806f, 0x0, 0x8070, 0x0, 0x807e, 0x0, 0x807f, 0x0,\n                0x8089, 0x0, 0x808b, 0x0, 0x80ad, 0x0, 0x80b2, 0x0, 0x8103,\n                0x0, 0x813e, 0x0, 0x81d8, 0x0, 0x81e3, 0x0, 0x81e8, 0x0,\n                0x81ea, 0x0, 0x81ed, 0x0, 0x81f3, 0x0, 0x81fc, 0x0, 0x8201,\n                0x0, 0x8204, 0x0, 0x820c, 0x0, 0x8218, 0x0, 0x821b, 0x0,\n                0x821f, 0x0, 0x826e, 0x0, 0x826f, 0x0, 0x8272, 0x0, 0x8278,\n                0x0, 0x8279, 0x0, 0x828b, 0x0, 0x8291, 0x0, 0x829d, 0x0,\n                0x82b1, 0x0, 0x82b3, 0x0, 0x82bd, 0x0, 0x82e5, 0x0, 0x82e6,\n                0x0, 0x831d, 0x0, 0x8323, 0x0, 0x8336, 0x0, 0x8352, 0x0,\n                0x8353, 0x0, 0x8363, 0x0, 0x83ad, 0x0, 0x83bd, 0x0, 0x83c9,\n                0x0, 0x83ca, 0x0, 0x83cc, 0x0, 0x83dc, 0x0, 0x83e7, 0x0,\n                0x83ef, 0x0, 0x83f1, 0x0, 0x843d, 0x0, 0x8449, 0x0, 0x8457,\n                0x0, 0x84ee, 0x0, 0x84f1, 0x0, 0x84f3, 0x0, 0x84fc, 0x0,\n                0x8516, 0x0, 0x8564, 0x0, 0x85cd, 0x0, 0x85fa, 0x0, 0x8606,\n                0x0, 0x8612, 0x0, 0x862d, 0x0, 0x863f, 0x0, 0x864d, 0x0,\n                0x8650, 0x0, 0x865c, 0x0, 0x8667, 0x0, 0x8669, 0x0, 0x866b,\n                0x0, 0x8688, 0x0, 0x86a9, 0x0, 0x86e2, 0x0, 0x870e, 0x0,\n                0x8728, 0x0, 0x876b, 0x0, 0x8779, 0x0, 0x8786, 0x0, 0x87ba,\n                0x0, 0x87e1, 0x0, 0x8801, 0x0, 0x881f, 0x0, 0x8840, 0x0,\n                0x884c, 0x0, 0x8860, 0x0, 0x8863, 0x0, 0x88c2, 0x0, 0x88cf,\n                0x0, 0x88d7, 0x0, 0x88de, 0x0, 0x88e1, 0x0, 0x88f8, 0x0,\n                0x88fa, 0x0, 0x8910, 0x0, 0x8941, 0x0, 0x8964, 0x0, 0x897e,\n                0x0, 0x8986, 0x0, 0x898b, 0x0, 0x8996, 0x0, 0x89d2, 0x0,\n                0x89e3, 0x0, 0x8a00, 0x0, 0x8aa0, 0x0, 0x8aaa, 0x0, 0x8abf,\n                0x0, 0x8acb, 0x0, 0x8ad2, 0x0, 0x8ad6, 0x0, 0x8aed, 0x0,\n                0x8af8, 0x0, 0x8afe, 0x0, 0x8b01, 0x0, 0x8b39, 0x0, 0x8b58,\n                0x0, 0x8b80, 0x0, 0x8b8a, 0x0, 0x8c37, 0x0, 0x8c46, 0x0,\n                0x8c48, 0x0, 0x8c55, 0x0, 0x8c78, 0x0, 0x8c9d, 0x0, 0x8ca1,\n                0x0, 0x8ca9, 0x0, 0x8cab, 0x0, 0x8cc1, 0x0, 0x8cc2, 0x0,\n                0x8cc7, 0x0, 0x8cc8, 0x0, 0x8cd3, 0x0, 0x8d08, 0x0, 0x8d1b,\n                0x0, 0x8d64, 0x0, 0x8d70, 0x0, 0x8d77, 0x0, 0x8db3, 0x0,\n                0x8dbc, 0x0, 0x8dcb, 0x0, 0x8def, 0x0, 0x8df0, 0x0, 0x8eab,\n                0x0, 0x8eca, 0x0, 0x8ed4, 0x0, 0x8f26, 0x0, 0x8f2a, 0x0,\n                0x8f38, 0x0, 0x8f3b, 0x0, 0x8f62, 0x0, 0x8f9b, 0x0, 0x8f9e,\n                0x0, 0x8fb0, 0x0, 0x8fb5, 0x0, 0x8fb6, 0x0, 0x9023, 0x0,\n                0x9038, 0x0, 0x904a, 0x0, 0x9069, 0x0, 0x9072, 0x0, 0x907c,\n                0x0, 0x908f, 0x0, 0x9091, 0x0, 0x9094, 0x0, 0x90ce, 0x0,\n                0x90de, 0x0, 0x90f1, 0x0, 0x90fd, 0x0, 0x9111, 0x0, 0x911b,\n                0x0, 0x9149, 0x0, 0x916a, 0x0, 0x9199, 0x0, 0x91b4, 0x0,\n                0x91c6, 0x0, 0x91cc, 0x0, 0x91cf, 0x0, 0x91d1, 0x0, 0x9234,\n                0x0, 0x9238, 0x0, 0x9276, 0x0, 0x927c, 0x0, 0x92d7, 0x0,\n                0x92d8, 0x0, 0x9304, 0x0, 0x934a, 0x0, 0x93f9, 0x0, 0x9415,\n                0x0, 0x9577, 0x0, 0x9580, 0x0, 0x958b, 0x0, 0x95ad, 0x0,\n                0x95b7, 0x0, 0x961c, 0x0, 0x962e, 0x0, 0x964b, 0x0, 0x964d,\n                0x0, 0x9675, 0x0, 0x9678, 0x0, 0x967c, 0x0, 0x9686, 0x0,\n                0x96a3, 0x0, 0x96b6, 0x0, 0x96b7, 0x0, 0x96b8, 0x0, 0x96b9,\n                0x0, 0x96c3, 0x0, 0x96e2, 0x0, 0x96e3, 0x0, 0x96e8, 0x0,\n                0x96f6, 0x0, 0x96f7, 0x0, 0x9723, 0x0, 0x9732, 0x0, 0x9748,\n                0x0, 0x9751, 0x0, 0x9756, 0x0, 0x975e, 0x0, 0x9762, 0x0,\n                0x9769, 0x0, 0x97cb, 0x0, 0x97db, 0x0, 0x97e0, 0x0, 0x97ed,\n                0x0, 0x97f3, 0x0, 0x97ff, 0x0, 0x9801, 0x0, 0x9805, 0x0,\n                0x980b, 0x0, 0x9818, 0x0, 0x9829, 0x0, 0x983b, 0x0, 0x985e,\n                0x0, 0x98a8, 0x0, 0x98db, 0x0, 0x98df, 0x0, 0x98e2, 0x0,\n                0x98ef, 0x0, 0x98fc, 0x0, 0x9928, 0x0, 0x9929, 0x0, 0x9996,\n                0x0, 0x9999, 0x0, 0x99a7, 0x0, 0x99ac, 0x0, 0x99c2, 0x0,\n                0x99f1, 0x0, 0x99fe, 0x0, 0x9a6a, 0x0, 0x9aa8, 0x0, 0x9ad8,\n                0x0, 0x9adf, 0x0, 0x9b12, 0x0, 0x9b25, 0x0, 0x9b2f, 0x0,\n                0x9b32, 0x0, 0x9b3c, 0x0, 0x9b5a, 0x0, 0x9b6f, 0x0, 0x9c40,\n                0x0, 0x9c57, 0x0, 0x9ce5, 0x0, 0x9cfd, 0x0, 0x9d67, 0x0,\n                0x9db4, 0x0, 0x9dfa, 0x0, 0x9e1e, 0x0, 0x9e75, 0x0, 0x9e7f,\n                0x0, 0x9e97, 0x0, 0x9e9f, 0x0, 0x9ea5, 0x0, 0x9ebb, 0x0,\n                0x9ec3, 0x0, 0x9ecd, 0x0, 0x9ece, 0x0, 0x9ed1, 0x0, 0x9ef9,\n                0x0, 0x9efd, 0x0, 0x9efe, 0x0, 0x9f05, 0x0, 0x9f0e, 0x0,\n                0x9f0f, 0x0, 0x9f13, 0x0, 0x9f16, 0x0, 0x9f20, 0x0, 0x9f3b,\n                0x0, 0x9f43, 0x0, 0x9f4a, 0x0, 0x9f52, 0x0, 0x9f8d, 0x0,\n                0x9f8e, 0x0, 0x9f9c, 0x0, 0x9f9f, 0x0, 0x9fa0, 0x0, 0xa76f,\n                0x0, 0x11099, 0x110ba, 0x0, 0x1109b, 0x110ba, 0x0, 0x110a5,\n                0x110ba, 0x0, 0x11131, 0x11127, 0x0, 0x11132, 0x11127, 0x0,\n                0x1d157, 0x1d165, 0x0, 0x1d158, 0x1d165, 0x0, 0x1d158, 0x1d165,\n                0x1d16e, 0x0, 0x1d158, 0x1d165, 0x1d16f, 0x0, 0x1d158, 0x1d165,\n                0x1d170, 0x0, 0x1d158, 0x1d165, 0x1d171, 0x0, 0x1d158, 0x1d165,\n                0x1d172, 0x0, 0x1d1b9, 0x1d165, 0x0, 0x1d1b9, 0x1d165, 0x1d16e,\n                0x0, 0x1d1b9, 0x1d165, 0x1d16f, 0x0, 0x1d1ba, 0x1d165, 0x0,\n                0x1d1ba, 0x1d165, 0x1d16e, 0x0, 0x1d1ba, 0x1d165, 0x1d16f, 0x0,\n                0x20122, 0x0, 0x2051c, 0x0, 0x20525, 0x0, 0x2054b, 0x0,\n                0x2063a, 0x0, 0x20804, 0x0, 0x208de, 0x0, 0x20a2c, 0x0,\n                0x20b63, 0x0, 0x214e4, 0x0, 0x216a8, 0x0, 0x216ea, 0x0,\n                0x219c8, 0x0, 0x21b18, 0x0, 0x21d0b, 0x0, 0x21de4, 0x0,\n                0x21de6, 0x0, 0x22183, 0x0, 0x2219f, 0x0, 0x22331, 0x0,\n                0x226d4, 0x0, 0x22844, 0x0, 0x2284a, 0x0, 0x22b0c, 0x0,\n                0x22bf1, 0x0, 0x2300a, 0x0, 0x232b8, 0x0, 0x2335f, 0x0,\n                0x23393, 0x0, 0x2339c, 0x0, 0x233c3, 0x0, 0x233d5, 0x0,\n                0x2346d, 0x0, 0x236a3, 0x0, 0x238a7, 0x0, 0x23a8d, 0x0,\n                0x23afa, 0x0, 0x23cbc, 0x0, 0x23d1e, 0x0, 0x23ed1, 0x0,\n                0x23f5e, 0x0, 0x23f8e, 0x0, 0x24263, 0x0, 0x242ee, 0x0,\n                0x243ab, 0x0, 0x24608, 0x0, 0x24735, 0x0, 0x24814, 0x0,\n                0x24c36, 0x0, 0x24c92, 0x0, 0x24fa1, 0x0, 0x24fb8, 0x0,\n                0x25044, 0x0, 0x250f2, 0x0, 0x250f3, 0x0, 0x25119, 0x0,\n                0x25133, 0x0, 0x25249, 0x0, 0x2541d, 0x0, 0x25626, 0x0,\n                0x2569a, 0x0, 0x256c5, 0x0, 0x2597c, 0x0, 0x25aa7, 0x0,\n                0x25bab, 0x0, 0x25c80, 0x0, 0x25cd0, 0x0, 0x25f86, 0x0,\n                0x261da, 0x0, 0x26228, 0x0, 0x26247, 0x0, 0x262d9, 0x0,\n                0x2633e, 0x0, 0x264da, 0x0, 0x26523, 0x0, 0x265a8, 0x0,\n                0x267a7, 0x0, 0x267b5, 0x0, 0x26b3c, 0x0, 0x26c36, 0x0,\n                0x26cd5, 0x0, 0x26d6b, 0x0, 0x26f2c, 0x0, 0x26fb1, 0x0,\n                0x270d2, 0x0, 0x273ca, 0x0, 0x27667, 0x0, 0x278ae, 0x0,\n                0x27966, 0x0, 0x27ca8, 0x0, 0x27ed3, 0x0, 0x27f2f, 0x0,\n                0x285d2, 0x0, 0x285ed, 0x0, 0x2872e, 0x0, 0x28bfa, 0x0,\n                0x28d77, 0x0, 0x29145, 0x0, 0x291df, 0x0, 0x2921a, 0x0,\n                0x2940a, 0x0, 0x29496, 0x0, 0x295b6, 0x0, 0x29b30, 0x0,\n                0x2a0ce, 0x0, 0x2a105, 0x0, 0x2a20e, 0x0, 0x2a291, 0x0,\n                0x2a392, 0x0, 0x2a600, 0x0\n            ];\n            return t;\n        }\n    }\n\n}\n\nstatic if (size_t.sizeof == 4)\n{\n    //22656 bytes\n    enum compatMappingTrieEntries = TrieEntry!(ushort, 8, 8, 5)([0x0, 0x40,\n            0x540], [0x100, 0xa00, 0x21c0], [0x2020100, 0x4020302, 0x2020205,\n            0x7060202, 0x2020202, 0x8020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x0, 0x0, 0x10000, 0x30002, 0x50004, 0x70006, 0x80000,\n            0xa0009, 0xc000b, 0x0, 0xd0000, 0xf000e, 0x0, 0x110010, 0x130012,\n            0x150014, 0x170016, 0x190018, 0x0, 0x1b001a, 0x0, 0x0, 0x1c, 0x0,\n            0x1d0000, 0x1e0000, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x200000, 0x21, 0x0, 0x22, 0x230000, 0x24, 0x0, 0x0, 0x0,\n            0x25, 0x26, 0x27, 0x0, 0x28, 0x0, 0x29, 0x0, 0x2a, 0x0, 0x2b,\n            0x2c0000, 0x0, 0x2d0000, 0x2e, 0x2f, 0x310030, 0x330032, 0x0,\n            0x340000, 0x0, 0x0, 0x350000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x370036, 0x38, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x390000, 0x3b003a, 0x3d003c, 0x0, 0x3f003e,\n            0x410040, 0x430042, 0x450044, 0x470046, 0x490048, 0x4b004a,\n            0x4d004c, 0x4f004e, 0x510050, 0x530052, 0x0, 0x550054, 0x570056,\n            0x590058, 0x5a, 0x5c005b, 0x5e005d, 0x60005f, 0x610000, 0x620000,\n            0x0, 0x0, 0x0, 0x0, 0x630000, 0x650064, 0x670066, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x68, 0x690000, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x6b0000, 0x0, 0x0, 0x0, 0x6c0000, 0x0, 0x0, 0x0, 0x0, 0x6d,\n            0x6e0000, 0x70006f, 0x720071, 0x740073, 0x75, 0x770076, 0x790078,\n            0x7b007a, 0x7d007c, 0x7e0000, 0x80007f, 0x81, 0x0, 0x830082,\n            0x850084, 0x870086, 0x890088, 0x8b008a, 0x8d008c, 0x8f008e,\n            0x910090, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x920000, 0x0, 0x930000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x950094, 0x970096, 0x990098,\n            0x9b009a, 0x9d009c, 0x9f009e, 0xa100a0, 0xa2, 0xa400a3, 0xa600a5,\n            0xa800a7, 0xaa00a9, 0xac00ab, 0xae00ad, 0xb000af, 0xb200b1,\n            0xb400b3, 0xb600b5, 0xb800b7, 0xba00b9, 0xbc00bb, 0xbe00bd,\n            0xc000bf, 0xc200c1, 0xc400c3, 0xc600c5, 0xc800c7, 0xca00c9, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xcc00cb, 0x0, 0xcd0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xcf00ce, 0xd00000, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xd300d2, 0xd500d4, 0xd700d6, 0xd900d8, 0xdb00da,\n            0xdd00dc, 0xd200de, 0xdf00d3, 0xe000d5, 0xe200e1, 0xe300d9,\n            0xe500e4, 0xe700e6, 0xe900e8, 0xeb00ea, 0xed00ec, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef00ee, 0xf100f0, 0xf300f2,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf500f4, 0xf700f6,\n            0xf8, 0x0, 0xfa00f9, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xfd00fc, 0xff00fe, 0x1010100, 0x1030102, 0x1050104, 0x1070106,\n            0x1090108, 0x10b010a, 0x10c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x15, 0x692, 0x0, 0x90000,\n            0x0, 0x30f0343, 0x11b20003, 0x0, 0x3140048, 0x787, 0x3c603ce,\n            0x494, 0x570056d, 0x5860573, 0x5b005a6, 0x5f80000, 0x62e062b,\n            0x6580631, 0x6e706e4, 0x6f906ea, 0x78f0000, 0x7a907a6, 0x7bf07ac,\n            0x7e3, 0x8b10000, 0x8b708b4, 0x95f08cb, 0x0, 0x9ac09a9, 0x9c209af,\n            0x9ec09e2, 0xa470000, 0xa890a86, 0xab30a8c, 0xb460b43, 0xb550b49,\n            0xc410000, 0xc5e0c5b, 0xc740c61, 0xc98, 0xd680000, 0xd6e0d6b,\n            0xe0c0d82, 0xe1b0000, 0x9c50589, 0x9c8058c, 0xa0a05ce, 0xa3b05ec,\n            0xa3e05ef, 0xa4105f2, 0xa4405f5, 0xa6e061a, 0x0, 0xaa20647,\n            0xaad0652, 0xab00655, 0xad00675, 0xab9065e, 0xafb069a, 0xb0106a0,\n            0xb0406a3, 0xb0a06a9, 0xb1606ba, 0x0, 0xb4c06ed, 0xb4f06f0,\n            0xb5206f3, 0xb6b070f, 0x6f6, 0xb3706d8, 0xb730717, 0xbae072e,\n            0x7430000, 0x7500bcc, 0x7460bd9, 0x7400bcf, 0xbc9, 0x78c0000,\n            0x79b0c3e, 0x7950c4d, 0xed70c47, 0x0, 0xc8307ce, 0xc8e07d9,\n            0xca207ed, 0x0, 0xd070842, 0xd1d0858, 0xd0d0848, 0xd2b086c,\n            0xd320873, 0xd49088a, 0xd380879, 0xd5d08a6, 0xd54089d, 0x0,\n            0xd7108ba, 0xd7808c1, 0xd7f08c8, 0xd9808e1, 0xd9b08e4, 0xdc4090d,\n            0xde9093f, 0xe0f0962, 0x979096e, 0x97f0e29, 0x60d0e2f, 0x8400614,\n            0xcae07f9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f00000, 0xda7, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x613060c, 0x7360a67,\n            0xbb9073d, 0x7830780, 0x5b70c32, 0x70309f3, 0x7f00b5f, 0x8e70ca5,\n            0x8d60d9e, 0x8d20d8d, 0x8da0d89, 0x8ce0d91, 0xd85, 0x9e505a9,\n            0x9de05a2, 0xe630e5a, 0x0, 0xb0706a6, 0xba80728, 0xccc0817,\n            0xccf081a, 0xecc0e7b, 0x6090b76, 0xa640610, 0xaf80697, 0x0,\n            0xc3b0789, 0x9ef05b3, 0xe600e57, 0xe680e5d, 0x9f605ba, 0x9f905bd,\n            0xabc0661, 0xabf0664, 0xb620706, 0xb650709, 0xca807f3, 0xcab07f6,\n            0xd10084b, 0xd13084e, 0xda108ea, 0xda408ed, 0xd460887, 0xd5a08a3,\n            0x0, 0xb1f06c3, 0x0, 0x0, 0x0, 0x9db059f, 0xac9066e, 0xc9b07e6,\n            0xc7b07c6, 0xc9107dc, 0xc9407df, 0xe150968, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe9a0b0d,\n            0xa11073e, 0xeb60eb4, 0xde10eb8, 0x695, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12000f,\n            0x4b0024, 0x270006, 0x0, 0xa280e96, 0xb410840, 0xecf, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4001a,\n            0x2b0000, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xed5, 0x0, 0x0, 0x54, 0x0, 0x546, 0x0, 0x0, 0x1c0003, 0x7410ee8,\n            0xf630f43, 0xfb4, 0xfed, 0x103c1016, 0x1185, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x101f0fbd, 0x10f5108f,\n            0x11751119, 0x1213, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x120c117e, 0x120311d5, 0x124b, 0x116e10ea,\n            0x10161011, 0x123c101f, 0x11ee, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x11f011ae, 0x11f8, 0x10f00fad, 0x0,\n            0x100d0000, 0x0, 0x0, 0x0, 0x12b612b0, 0x12ad0000, 0x0, 0x12a40000,\n            0x0, 0x0, 0x12c212ce, 0x12d7, 0x0, 0x0, 0x0, 0x0, 0x12c80000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x130a0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x12f812f2, 0x12ef0000, 0x0, 0x132d0000, 0x0, 0x0, 0x13041310,\n            0x131b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x13331330, 0x0, 0x0, 0x0, 0x0, 0x12b90000, 0x12fb, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x12e912a7, 0x12ec12aa, 0x0, 0x12f512b3, 0x0,\n            0x13391336, 0x12fe12bc, 0x130112bf, 0x0, 0x130712c5, 0x130d12cb,\n            0x131512d1, 0x0, 0x133f133c, 0x132a12e6, 0x131812d4, 0x131e12da,\n            0x132112dd, 0x132412e0, 0x0, 0x132712e3, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x13420000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x13e913e6, 0x13ec178f, 0x17ca, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x13ef0000, 0x185b1792, 0x1811, 0x0, 0x0,\n            0x0, 0x186d, 0x1852, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x186a0000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18820000, 0x0,\n            0x0, 0x0, 0x188b0000, 0x0, 0x188e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18731870,\n            0x18791876, 0x187f187c, 0x18881885, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x189a0000, 0x189d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18941891,\n            0x18970000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x18ac0000, 0x0, 0x18af, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18a00000, 0x18a618a3,\n            0x0, 0x18a9, 0x0, 0x0, 0x0, 0x0, 0x18bb, 0x18b80000, 0x18be, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18b518b2, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18c1, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x18ca18c4, 0x18c7, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18cd, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18d0, 0x0, 0x0,\n            0x18da0000, 0x18dd, 0x18d618d3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18e618e0, 0x18e3, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18e9, 0x18ef18ec, 0x18f3,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18f60000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x18ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18fc18f9, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x1902, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x19070000, 0x0, 0x0, 0x0, 0x0, 0x190a0000, 0x0,\n            0x0, 0x190d, 0x0, 0x19100000, 0x0, 0x0, 0x1913, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x19040000, 0x0, 0x0, 0x0, 0x0, 0x19160000, 0x19190000,\n            0x19311935, 0x1938193c, 0x0, 0x0, 0x0, 0x191c0000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x19220000, 0x0, 0x0, 0x0, 0x0,\n            0x19250000, 0x0, 0x0, 0x1928, 0x0, 0x192b0000, 0x0, 0x0, 0x192e,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x191f0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x193f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x1942, 0x0, 0x0, 0x0, 0x0, 0x1a38, 0x1a3b, 0x1a3e,\n            0x1a41, 0x1a44, 0x0, 0x1a47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x1a4a0000, 0x1a4d0000, 0x0, 0x1a531a50, 0x1a560000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xe550568, 0x5d5, 0x62905e6, 0x6870e75,\n            0x6cf06ac, 0x71a0607, 0x7230734, 0x77e, 0xe7e07a4, 0x82c06af,\n            0x56b088d, 0x6920770, 0xe840e82, 0x9371a59, 0xa7d0a2e, 0xe8e0e8c,\n            0x6020e90, 0xb790000, 0xe7105d3, 0xe880787, 0x1a5d1a5b, 0xba30cd3,\n            0x1a610a24, 0x86a0ea4, 0x10ea1a63, 0x10ee10ec, 0x123e123c,\n            0xa110ae0, 0x86a0a24, 0x10ec10ea, 0x123c11f0, 0x123e, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x1313, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe860000, 0xe8a09a0,\n            0xe900e66, 0xe920ad9, 0xe980e94, 0xe9e0e9c, 0x1a650ea0, 0xea20ed1,\n            0xed31a67, 0xea60ea8, 0xeac0eaa, 0xeb00eae, 0xeba0eb2, 0xe790ebc,\n            0xec00ebe, 0xec21a5f, 0x6110ec4, 0xec80ec6, 0x116e0eca, 0xa0705cb,\n            0xa1305da, 0xa1605dd, 0xa1905e0, 0xa4a05fb, 0xa6b0617, 0xa71061d,\n            0xa7a0626, 0xa740620, 0xa770623, 0xaa5064a, 0xaa9064e, 0xad30678,\n            0xad6067b, 0xacc0671, 0xaef0684, 0xafe069d, 0xb1906bd, 0xb2206c6,\n            0xb1c06c0, 0xb2506c9, 0xb2806cc, 0xb6e0712, 0xb5806fc, 0xba50725,\n            0xbab072b, 0xbb10731, 0xbd20749, 0xbd5074c, 0xbdf0756, 0xbdc0753,\n            0xc120772, 0xc150775, 0xc180778, 0xc440792, 0xc4a0798, 0xc5307a1,\n            0xc50079e, 0xc7707c2, 0xc7f07ca, 0xc8607d1, 0xc8a07d5, 0xcec0835,\n            0xcef0838, 0xd0a0845, 0xd160851, 0xd190854, 0xd20085b, 0xd350876,\n            0xd3f0880, 0xd2e086f, 0xd3b087c, 0xd420883, 0xd4e089a, 0xd5708a0,\n            0xd6308ac, 0xd6008a9, 0xdc1090a, 0xdca0913, 0xdc70910, 0xd7408bd,\n            0xd7b08c4, 0xddb0924, 0xdde0927, 0xde30939, 0xde6093c, 0xdef0945,\n            0xdec0942, 0xdf50948, 0xe010954, 0xe040957, 0xe18096b, 0xe2c097c,\n            0xe350985, 0xe380988, 0xd510b2b, 0xe210df2, 0xd3509a6, 0x0, 0x0,\n            0x9fc05c0, 0x9e905ad, 0x9b6057a, 0x9b20576, 0x9be0582, 0x9ba057e,\n            0x9ff05c3, 0x9cf0593, 0x9cb058f, 0x9d7059b, 0x9d30597, 0xa0305c7,\n            0xac20667, 0xab6065b, 0xa9f0644, 0xa930638, 0xa8f0634, 0xa9b0640,\n            0xa97063c, 0xac5066a, 0xb5c0700, 0xb68070c, 0xcc50810, 0xc9f07ea,\n            0xc6807b3, 0xc6407af, 0xc7007bb, 0xc6c07b7, 0xcc80813, 0xcb50800,\n            0xcb107fc, 0xcbd0808, 0xcb90804, 0xcc1080c, 0xdbe0907, 0xd9508de,\n            0xdae08f7, 0xdaa08f3, 0xdb608ff, 0xdb208fb, 0xdba0903, 0xe09095c,\n            0xe240974, 0xe1e0971, 0xe120965, 0x0, 0x0, 0x0, 0x10be109c,\n            0x10c1109f, 0x10ca10a8, 0x10d310b1, 0xf130ef1, 0xf160ef4,\n            0xf1f0efd, 0xf280f06, 0x110310f8, 0x110610fb, 0x110a10ff, 0x0,\n            0xf510f46, 0xf540f49, 0xf580f4d, 0x0, 0x11421120, 0x11451123,\n            0x114e112c, 0x11571135, 0xf880f66, 0xf8b0f69, 0xf940f72, 0xf9d0f7b,\n            0x119c118d, 0x119f1190, 0x11a31194, 0x11a71198, 0xfcf0fc0,\n            0xfd20fc3, 0xfd60fc7, 0xfda0fcb, 0x11e311d8, 0x11e611db,\n            0x11ea11df, 0x0, 0xffb0ff0, 0xffe0ff3, 0x10020ff7, 0x0, 0x122a121b,\n            0x122d121e, 0x12311222, 0x12351226, 0x10220000, 0x10250000,\n            0x10290000, 0x102d0000, 0x12741252, 0x12771255, 0x1280125e,\n            0x12891267, 0x1061103f, 0x10641042, 0x106d104b, 0x10761054,\n            0x108f1088, 0x10f510f2, 0x11191112, 0x11751172, 0x11d511d2,\n            0x12031200, 0x124b1244, 0x0, 0x10dc10ba, 0x10c510a3, 0x10ce10ac,\n            0x10d710b5, 0xf310f0f, 0xf1a0ef8, 0xf230f01, 0xf2c0f0a, 0x1160113e,\n            0x11491127, 0x11521130, 0x115b1139, 0xfa60f84, 0xf8f0f6d,\n            0xf980f76, 0xfa10f7f, 0x12921270, 0x127b1259, 0x12841262,\n            0x128d126b, 0x107f105d, 0x10681046, 0x1071104f, 0x107a1058,\n            0x10961099, 0x10e7108b, 0x1092, 0x10e310e0, 0xeeb0eee, 0xee80ee5,\n            0x2a0f35, 0x2a1170, 0x200051, 0x116b1115, 0x111c, 0x11671164,\n            0xf430f40, 0xf630f60, 0x2d0faa, 0x350031, 0x1178117b, 0x11851181,\n            0x0, 0x118911ab, 0xfb70fba, 0xfb40fb1, 0x3c0000, 0x440040,\n            0x12061209, 0x1213120f, 0x11f511f2, 0x12171239, 0x1019101c,\n            0x10161013, 0x18100a, 0x995001c, 0x0, 0x129d1247, 0x124e,\n            0x12991296, 0xfed0fea, 0x103c1039, 0x31083, 0x39, 0x10001, 0x10001,\n            0x10001, 0x10001, 0x10001, 0x1, 0x0, 0x0, 0x1a690000, 0x0, 0x0,\n            0x4e0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2fc02fa, 0x2ff, 0x0, 0x0,\n            0x0, 0x10000, 0x0, 0x1a6f0000, 0x1a72, 0x1a7e1a7b, 0x0, 0x0, 0x8f,\n            0xc, 0x0, 0x0, 0x0, 0x5630000, 0x920560, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x1a760000, 0x0, 0x0, 0x0, 0x10000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xae00305, 0x0, 0x3740365, 0x3920383, 0x3b003a1,\n            0x1aad02f4, 0xa10544, 0xb3b00a5, 0x3140305, 0x30f0343, 0x3740365,\n            0x3920383, 0x3b003a1, 0x1aad02f4, 0xa10544, 0xa5, 0xa7d0692,\n            0xb410787, 0xb0d0e8c, 0xa280b79, 0xb3b05d3, 0x8400cd3, 0xba3, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x83f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x9a2099e, 0xe4d05e3, 0xa1e0000, 0xe770a22,\n            0xe500000, 0x6ac0602, 0x6ac06ac, 0xe6d0b0d, 0x6cf06cf, 0xa280734,\n            0x77e0000, 0x786, 0x6af0000, 0x82c083b, 0x82c082c, 0x0, 0x88f0863,\n            0x897, 0x60a, 0x77c, 0x60a, 0x5b0071a, 0x5e305d5, 0xa7d0000,\n            0x67e0629, 0x7230000, 0x13540787, 0x136a1362, 0xae0136f, 0x6800000,\n            0x10ec11ee, 0x10060f3a, 0x1aab, 0x0, 0x5e60000, 0xa7d0a2e,\n            0x73e0ae0, 0x0, 0x0, 0x0, 0x3e203da, 0x3ca03c1, 0x3d20455,\n            0x4980459, 0x3d604cf, 0x3de04e7, 0x4eb049c, 0x3be0511, 0x6d106cf,\n            0x6de06d4, 0x91806b2, 0x91f091b, 0x68206e1, 0x950094d, 0x5e30734,\n            0x72305e6, 0xb300ae0, 0xb3d0b33, 0xdcf086a, 0xdd60dd2, 0xb410b40,\n            0xdfd0dfa, 0x9a00a28, 0x5d30a2e, 0x0, 0x0, 0x0, 0x0, 0x30d0000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a8d1a86, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a92, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a950000,\n            0x1a981a9b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x1aa0, 0x0, 0x1aa50000, 0x0, 0x1aa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x1aaf, 0x1ab2, 0x0, 0x0, 0x1ab81ab5,\n            0x1ac10000, 0x1ac4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ac80000,\n            0x0, 0x1acb, 0x1ace0000, 0x1ad10000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x556, 0x1ad7, 0x0, 0x0, 0x0, 0x0,\n            0x1ad40000, 0x55b054a, 0x1add1ada, 0x0, 0x1ae31ae0, 0x0,\n            0x1ae91ae6, 0x0, 0x0, 0x0, 0x1aef1aec, 0x0, 0x1afb1af8, 0x0,\n            0x1b011afe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b0d1b0a, 0x1b131b10, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1af51af2, 0x1b071b04, 0x0, 0x0,\n            0x0, 0x1b191b16, 0x1b1f1b1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b350000, 0x1b37, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3430314, 0x365030f, 0x3830374,\n            0x3a10392, 0x31c03b0, 0x342032f, 0x3640355, 0x3820373, 0x3a00391,\n            0x3f703af, 0xd900a3, 0xe600e2, 0xee00ea, 0xf600f2, 0xa700fa,\n            0xb100ac, 0xbb00b6, 0xc500c0, 0xcf00ca, 0xdd00d4, 0x3460319,\n            0x3680359, 0x3860377, 0x3a40395, 0x31f03b3, 0x3450332, 0x3670358,\n            0x3850376, 0x3a30394, 0x3fa03b2, 0x16a0166, 0x172016e, 0x17a0176,\n            0x182017e, 0x18a0186, 0x192018e, 0x19a0196, 0x1a2019e, 0x1aa01a6,\n            0x1b201ae, 0x1ba01b6, 0x1c201be, 0x1ca01c6, 0x5d50568, 0x5e605e3,\n            0x67e0629, 0x6ac0687, 0x60706cf, 0x734071a, 0x77e0723, 0x6af07a4,\n            0x82c083b, 0x88d085e, 0x6b2056b, 0x6820770, 0x60a095a, 0x9370692,\n            0xa2e09a0, 0xad90a7d, 0xb0d0602, 0x73e0ae0, 0xa280b79, 0xb3b05d3,\n            0xcd30787, 0xa1105d8, 0xba30840, 0x86a0a24, 0xb410de1, 0x6110695,\n            0x305, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x1abc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x54f0542, 0x552, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b2c, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x6b2073e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b2f0000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x227c0000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26b00000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x1efb1ee9, 0x1f091f01, 0x1f131f0d, 0x1f1b1f17,\n            0x1f4b1f21, 0x1f5f1f57, 0x1f6f1f67, 0x1f871f77, 0x1f8b1f89,\n            0x1fb91fa5, 0x1fc51fc1, 0x1fcd1fc7, 0x1fdd1fdb, 0x1feb1fe9,\n            0x1ff71fef, 0x204f2045, 0x2079206f, 0x207f207d, 0x20982087,\n            0x20b420ae, 0x20ca20c4, 0x20ce20cc, 0x20dc20da, 0x20f820f2,\n            0x210020fc, 0x210f2108, 0x21292113, 0x212f212b, 0x21352131,\n            0x21412139, 0x218b214f, 0x21972195, 0x21d921d7, 0x21e521e3,\n            0x21ed21e9, 0x32521f1, 0x3292211, 0x22602223, 0x226e2266,\n            0x227a2274, 0x2280227e, 0x22842282, 0x22e22286, 0x230c2306,\n            0x2310230e, 0x23162312, 0x23222318, 0x23342330, 0x23562354,\n            0x235c235a, 0x23622360, 0x23762374, 0x23862384, 0x238a2388,\n            0x23a62394, 0x23aa23a8, 0x23dc23bc, 0x23ee23de, 0x23fa23f6,\n            0x241c240a, 0x2442243e, 0x2452244c, 0x245a2456, 0x245e245c,\n            0x246c246a, 0x247e247a, 0x24842482, 0x248e248a, 0x24922490,\n            0x24982496, 0x24f224e8, 0x250e250c, 0x25282512, 0x2530252c,\n            0x25522534, 0x25582554, 0x255c255a, 0x25742572, 0x25822578,\n            0x25922584, 0x25982596, 0x25ba25aa, 0x25c425c2, 0x25de25c8,\n            0x25e825e0, 0x260025fa, 0x26142608, 0x261a2618, 0x261e261c,\n            0x26262624, 0x2638262a, 0x263c263a, 0x264a2648, 0x2658264e,\n            0x265c265a, 0x26622660, 0x26662664, 0x26702668, 0x267e267c,\n            0x26862684, 0x268a2688, 0x2690268e, 0x26982692, 0x26a0269c,\n            0x26a626a2, 0x26aa26a8, 0x26b226ae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x1b49, 0x1fcf1fcd, 0x1fd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x1b7e, 0x1b81, 0x1b84, 0x1b87, 0x1b8a, 0x1b8d, 0x1b90, 0x1b93,\n            0x1b96, 0x1b99, 0x1b9c, 0x1b9f, 0x1ba20000, 0x1ba50000, 0x1ba80000,\n            0x0, 0x0, 0x0, 0x1bae1bab, 0x1bb10000, 0x1bb4, 0x1bba1bb7,\n            0x1bbd0000, 0x1bc0, 0x1bc91bc6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x1b7b, 0x0, 0x0, 0x870000, 0x8a, 0x1bcc1bd3,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c26, 0x1c43, 0x1bf6, 0x1c92,\n            0x1c9b, 0x1caf, 0x1cbf, 0x1cca, 0x1ccf, 0x1cdc, 0x1ce1, 0x1ceb,\n            0x1cf20000, 0x1cf70000, 0x1c100000, 0x0, 0x0, 0x0, 0x1d261d1d,\n            0x1d3b0000, 0x1d42, 0x1d611d57, 0x1d760000, 0x1d7e, 0x1caa1da1,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c01,\n            0x1e440000, 0x1e521e4d, 0x1e57, 0x0, 0x1ca11e60, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x19440000, 0x1a101949, 0x1a12194b,\n            0x19501a14, 0x19571955, 0x1a181a16, 0x1a1c1a1a, 0x1a201a1e,\n            0x195c19a6, 0x19661961, 0x196819b0, 0x196f196d, 0x19811977,\n            0x198e1983, 0x19981993, 0x1947199d, 0x19da19d8, 0x19de19dc,\n            0x19e219e0, 0x198c19e4, 0x19ea19e8, 0x19ee19ec, 0x19f21975,\n            0x19f619f4, 0x19fa19f8, 0x19fe197f, 0x19a219d4, 0x1a2219a4,\n            0x1a261a24, 0x1a2a1a28, 0x1a2e1a2c, 0x1a3019a8, 0x19aa1a32,\n            0x19ae19ac, 0x19b419b2, 0x19b819b6, 0x19bc19ba, 0x19c019be,\n            0x19c419c2, 0x19c819c6, 0x19cc19ca, 0x1a361a34, 0x19d019ce,\n            0x1a0019d2, 0x1a041a02, 0x1a081a06, 0x1a0c1a0a, 0x1a0e, 0x0,\n            0x1f171ee9, 0x20471eef, 0x1efd1ef1, 0x23641ef3, 0x1ef71f0d,\n            0x208c1eeb, 0x1f212051, 0x1d701ce, 0x1e901e0, 0x1fb01f2, 0x20d0204,\n            0x2330225, 0x245023c, 0x257024e, 0x1db01d2, 0x1ed01e4, 0x1ff01f6,\n            0x2110208, 0x2370229, 0x2490240, 0x25b0252, 0x216022e, 0x21e,\n            0x2700260, 0x2a00268, 0x2880274, 0x2840264, 0x290026c, 0x2c402b0,\n            0x2b802c0, 0x2a402ec, 0x2bc02ac, 0x2d002b4, 0x2c80298, 0x2d402e4,\n            0x278028c, 0x2a8029c, 0x27c02cc, 0x29402e8, 0x28002d8, 0x2e002dc,\n            0x21112021, 0x23fe21e3, 0x0, 0x0, 0x0, 0x0, 0x406082e, 0x41c0411,\n            0x4320427, 0x4400439, 0x44e0447, 0x475046e, 0x47f047c, 0x4850482,\n            0x194b1944, 0x19571950, 0x1961195c, 0x196f1968, 0x19831977,\n            0x1993198e, 0x199d1998, 0x194d1946, 0x19591952, 0x1963195e,\n            0x1971196a, 0x19851979, 0x19951990, 0x199f199a, 0x197c1988, 0x1974,\n            0x1f171ee9, 0x20471eef, 0x1f611f19, 0x1f5f1eed, 0x1fcd1f0f,\n            0x22e20329, 0x22232286, 0x204f25c8, 0x223b0325, 0x2240221b,\n            0x231c2007, 0x23ca255e, 0x23e21fab, 0x20982368, 0x1f4925a2,\n            0x22961fdf, 0x1f2b262c, 0x208a1f73, 0x1efd1ef1, 0x20fa1ef3,\n            0x1fc92001, 0x20b220b8, 0x1f292390, 0x1fd72568, 0x4882083,\n            0x48e048b, 0x4b10491, 0x4b704b4, 0x4bd04ba, 0x4c304c0, 0x4c904c6,\n            0x4e404cc, 0x34e033b, 0x4d604a3, 0x50304f2, 0x5290518, 0x327053a,\n            0x34d033a, 0xa8206b4, 0x7390a7f, 0x1bf11bd8, 0x1c0a1bff,\n            0x1c241c1a, 0x1c731c41, 0x1c991c90, 0x1cbd1cad, 0x1ccd1c1e,\n            0x1cdf1cda, 0x1cf01bfb, 0x1bde1cf5, 0x1d0f1ca6, 0x1c8e1d11,\n            0x1d1b1d0d, 0x1d551d39, 0x1d9f1d74, 0x1ddc1c31, 0x1def1c22,\n            0x1e041e00, 0x1e191e11, 0x1c351e1b, 0x1e341bed, 0x1e421c5d,\n            0x1e501e4b, 0x1e55, 0x1be01bda, 0x1beb1be5, 0x1bf91bf3, 0x1c0c1c04,\n            0x1c1c1c13, 0x1c331c20, 0x1c3c1c37, 0x1c2e1c29, 0x1c4b1c46,\n            0x1c501c57, 0x1c5f1c5c, 0x1c6d1c66, 0x1c7d1c61, 0x1c8b1c84,\n            0x1ca41c95, 0x1cb21ca8, 0x1cc21cb7, 0x1cd61cd2, 0x1cfa1ce4,\n            0x1c811d03, 0x1d171d0c, 0x1d291d35, 0x1d201d30, 0x1d4c1d45,\n            0x1d3e1d51, 0x1d6b1d64, 0x1d701d5a, 0x1d811d95, 0x1d9b1d85,\n            0x1d8f1d8a, 0x1dac1d79, 0x1db81da4, 0x1dbb1db2, 0x1dc51dbf,\n            0x1dce1dca, 0x1dd61dd2, 0x1de31dde, 0x1df11de6, 0x1c681df5,\n            0x1e0b1e06, 0x1e1f1e13, 0x1e291e24, 0x1e361e2e, 0x1c6f1e39,\n            0x33f0311, 0x3610352, 0x37f0370, 0x39d038e, 0x3bb03ac, 0x33e032b,\n            0x3600351, 0x37e036f, 0x39c038d, 0x3ba03ab, 0x40d0402, 0x4230418,\n            0xb0f042e, 0x56a0a53, 0xc580a0f, 0xa590ce6, 0xa600a5c, 0x210a06db,\n            0x20892200, 0x223d21f9, 0xc260cda, 0xbea11b4, 0x71c0b7b, 0x689075b,\n            0xb8c0a26, 0xc290cdd, 0x11c011b7, 0x6010bf6, 0xb7e068d, 0x68c0764,\n            0x11c30893, 0xa560bfd, 0xaec0b94, 0x11c60c35, 0xa300c00, 0xc030b97,\n            0xa340a33, 0xc070b9a, 0xa380a37, 0xc1b0b9e, 0x6910c1f, 0x7680b82,\n            0xcf60690, 0xd000cfa, 0xc380ce9, 0xc0f11c9, 0xc2c0ce0, 0xbed11ba,\n            0x76c0b86, 0xc2f0ce3, 0xbf011bd, 0x76f0b89, 0x77b0bb4, 0x5d70999,\n            0xa2d0a2a, 0x5e805ff, 0x6940a50, 0x6ae0b13, 0x71f0b3a, 0xba20722,\n            0xbbf0bbc, 0xbc60bc2, 0xbf90bf3, 0x8200c0b, 0x8230cd5, 0xd25082b,\n            0x9360869, 0x5d1092a, 0x34a0337, 0x36c035d, 0x38a037b, 0x3a80399,\n            0x32303b7, 0x3490336, 0x36b035c, 0x389037a, 0x3a70398, 0x3fe03b6,\n            0x4140409, 0x42a041f, 0x43c0435, 0x44a0443, 0x4710451, 0xaf40478,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26b4, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xe730e6b, 0x0, 0x0, 0x0, 0x22132556, 0x256a2584,\n            0x1eff22c6, 0x26ae1ff9, 0x209226ae, 0x202b25c8, 0x21872090,\n            0x244a2382, 0x250424e6, 0x25a8251e, 0x229a2254, 0x233c22f0,\n            0x25bc24ca, 0x1f112652, 0x225e1fe3, 0x24e42302, 0x20e6267a,\n            0x24dc22d6, 0x21a12526, 0x250a2478, 0x221d211f, 0x232822a6,\n            0x1f3125ae, 0x1fb31f7d, 0x225a21d5, 0x23922300, 0x24e02456,\n            0x257e24ec, 0x266a2610, 0x23b02678, 0x242c23d0, 0x25d624bc,\n            0x2540267e, 0x212d206d, 0x24682408, 0x23b4231a, 0x260c2566,\n            0x20d4206b, 0x22b02256, 0x242422ca, 0x25ec2438, 0x246e1fb1,\n            0x1f811f83, 0x242e23e6, 0x25f024c8, 0x21a3254e, 0x25462254,\n            0x20be1f05, 0x23322159, 0x1fc32372, 0x1f3923b8, 0x1ef5214b,\n            0x21e12290, 0x1fed2422, 0x23982063, 0x253824cc, 0x25962276,\n            0x21ab228c, 0x21bb24a8, 0x1f1f2370, 0x1f7f1f5d, 0x24182244,\n            0x253e2494, 0x1fb725c6, 0x20982011, 0x21ef2127, 0x23ba22d8,\n            0x265625e4, 0x268c2680, 0x220f1fa5, 0x2590226c, 0x217b210d,\n            0x21d12189, 0x22f622d0, 0x23e0234e, 0x24642432, 0x24d02588,\n            0x25d8259c, 0x1fa71f91, 0x22ee201b, 0x25382514, 0x2155211d,\n            0x227221b7, 0x232c2406, 0x20491f27, 0x20f020be, 0x233a215b,\n            0x24502348, 0x25ca2460, 0x2612260a, 0x1f332630, 0x25c023da,\n            0x216725fe, 0x1f451f15, 0x20d020c0, 0x225421e7, 0x238022fc,\n            0x25a624d6, 0x220726aa, 0x1fa325ea, 0x2233222d, 0x22be22a2,\n            0x236e2340, 0x242023ae, 0x1f612636, 0x25f22191, 0x20e21f3d,\n            0x258a22b2, 0x216b2143, 0x23322237, 0x1f9525f6, 0x20d82009,\n            0x222521fc, 0x2294224a, 0x2378233e, 0x25162446, 0x25c4251c,\n            0x1fcb2604, 0x200b22c0, 0x235022fe, 0x25f824de, 0x2682266e,\n            0x22ae2231, 0x23f6247c, 0x240e23fc, 0x22ea2326, 0x1f23254c,\n            0x1f9724b0, 0x21151f8f, 0x241421a5, 0x229c20b6, 0x258e220d,\n            0x25ee250e, 0x2123252c, 0x20371f4d, 0x0, 0x2061, 0x2205,\n            0x1f850000, 0x238c232a, 0x23cc23be, 0x23d823ce, 0x24102616, 0x2452,\n            0x24e2, 0x2544, 0x259e0000, 0x25b4, 0x0, 0x26422640, 0x26762644,\n            0x25fc25b0, 0x1f471f35, 0x1faf1f51, 0x1fd51fb5, 0x203d202f,\n            0x205f2041, 0x20d62065, 0x216120da, 0x21792175, 0x21db2185,\n            0x220921f3, 0x22a82246, 0x22ce22b6, 0x230822f8, 0x23b22342,\n            0x23c42240, 0x23c623c2, 0x23ca23c8, 0x23d623d4, 0x23f223e8,\n            0x24322400, 0x243a2436, 0x24582444, 0x249a2480, 0x24ce249a,\n            0x252e2522, 0x254a2548, 0x256e256c, 0x259e259a, 0x26282606,\n            0x215d2634, 0x248c274b, 0x0, 0x1f7b1ef9, 0x1f2f1f5b, 0x1f651f4f,\n            0x1fbb1fad, 0x2025202f, 0x203b202d, 0x20692061, 0x2094208e,\n            0x20aa20a2, 0x21252121, 0x214d213d, 0x21712165, 0x21792169,\n            0x21852173, 0x21bf2193, 0x21c921c5, 0x220521dd, 0x221f221d,\n            0x226e2229, 0x22a22276, 0x22c422c8, 0x22dc22ce, 0x23a422f8,\n            0x2324230a, 0x234a232a, 0x236a2358, 0x237e237c, 0x238e238c,\n            0x23a02396, 0x23b6239e, 0x240023f4, 0x2428240c, 0x24402432,\n            0x24b22458, 0x250024c6, 0x252a2524, 0x253a252e, 0x253c2544,\n            0x25462548, 0x254a2542, 0x256e2550, 0x25a4258c, 0x25ce25be,\n            0x260625f4, 0x26202616, 0x262e2628, 0x265e2634, 0x272126ae,\n            0x2733271f, 0x1ea11e8d, 0x27671ea3, 0x27a92779, 0x26ac26a4, 0x0,\n            0x0, 0x0, 0xadf0adb, 0xade0ae3, 0xd280ae2, 0xd28, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x134e0000, 0x13481345, 0x134b1351, 0x0, 0x0, 0x13850000,\n            0x13d20000, 0x135413a6, 0x1374136f, 0x1360138e, 0x13b7139b,\n            0x2f413cd, 0x13ca13c7, 0x13c313bf, 0x13591356, 0x1364135c,\n            0x1371136c, 0x137c1376, 0x137f, 0x13881382, 0x1390138b, 0x1398,\n            0x139d, 0x13a313a0, 0x13a80000, 0x13ab, 0x13b413b1, 0x13bc13b9,\n            0x137913cf, 0x13931367, 0x135f13ae, 0x18181818, 0x181e181e,\n            0x181e181e, 0x18201820, 0x18201820, 0x18241824, 0x18241824,\n            0x181c181c, 0x181c181c, 0x18221822, 0x18221822, 0x181a181a,\n            0x181a181a, 0x183c183c, 0x183c183c, 0x183e183e, 0x183e183e,\n            0x18281828, 0x18281828, 0x18261826, 0x18261826, 0x182a182a,\n            0x182a182a, 0x182c182c, 0x182c182c, 0x18321832, 0x18301830,\n            0x18341834, 0x182e182e, 0x18381838, 0x18361836, 0x18401840,\n            0x18401840, 0x18441844, 0x18441844, 0x18481848, 0x18481848,\n            0x18461846, 0x18461846, 0x184a184a, 0x184c184c, 0x184c184c,\n            0x186d186d, 0x18501850, 0x18501850, 0x184e184e, 0x184e184e,\n            0x15911591, 0x186a186a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18420000, 0x18421842,\n            0x18031842, 0x17ff1803, 0x180717ff, 0x185b1807, 0x18621862,\n            0x18551855, 0x18601860, 0x180b180b, 0x180b180b, 0x14151415,\n            0x17cd17cd, 0x180d180d, 0x17f117f1, 0x18011801, 0x17fd17fd,\n            0x18051805, 0x18091809, 0x17f51809, 0x17f517f5, 0x18641864,\n            0x18641864, 0x17d517d1, 0x17f517e5, 0x13f417f9, 0x13fe13f7,\n            0x1414140b, 0x141e1417, 0x1438142d, 0x146a144d, 0x1472146d,\n            0x1484147b, 0x148c1487, 0x14311422, 0x14d11435, 0x143c14d4,\n            0x150514fa, 0x151a150c, 0x15931562, 0x15a515a2, 0x15ba15b0,\n            0x15c815c5, 0x15e415df, 0x16071575, 0x163f160a, 0x16451642,\n            0x1653164c, 0x165b1656, 0x16711662, 0x16791674, 0x167f167c,\n            0x16851682, 0x16931688, 0x16aa1696, 0x16c816b9, 0x1579158c,\n            0x145116e0, 0x14591455, 0x145d1526, 0x172d1461, 0x174f1740,\n            0x17691758, 0x1771176c, 0x177f1774, 0x179c1782, 0x17aa17a3,\n            0x17c417b3, 0x14e417c7, 0x179714ee, 0x64005d, 0x72006b, 0x800079,\n            0x17e117dd, 0x17e917e5, 0x17f917f5, 0x140813db, 0x140e140b,\n            0x14171414, 0x144a1447, 0x1464144d, 0x146d146a, 0x14781475,\n            0x147e147b, 0x14871484, 0x16561653, 0x16741671, 0x16851679,\n            0x16931688, 0x158c1696, 0x16e01579, 0x152616e5, 0x17551752,\n            0x17631758, 0x176c1769, 0x17ad1797, 0x17b317b0, 0x17c417be,\n            0x17d117c7, 0x17d917d5, 0x17ed17e5, 0x13f713f4, 0x140b13fe,\n            0x141e1411, 0x1438142d, 0x1467144d, 0x148c147b, 0x14311422,\n            0x14d11435, 0x14fa143c, 0x150c1505, 0x1562151a, 0x1593156d,\n            0x15a515a2, 0x15ba15b0, 0x15df15c5, 0x157515e4, 0x160a1607,\n            0x1642163f, 0x164c1645, 0x1662165b, 0x167f167c, 0x16851682,\n            0x16aa1688, 0x16c816b9, 0x13e0158c, 0x14551451, 0x15261459,\n            0x1740172d, 0x1758174f, 0x17711766, 0x17851774, 0x17a3179c,\n            0x17b317aa, 0x17e515ed, 0x140b17ed, 0x144d1411, 0x147b1467,\n            0x151a1481, 0x154c1529, 0x16851557, 0x158c1688, 0x17661758,\n            0x15ed17b3, 0x162c1625, 0x15d71633, 0x15ff15da, 0x16191602,\n            0x152c161c, 0x155a152f, 0x1490155d, 0x142613fb, 0x1440142a,\n            0x159a1402, 0x15bd159d, 0x153415c0, 0x1546153b, 0x1549154c,\n            0x15701517, 0x15d715b7, 0x15ff15da, 0x16191602, 0x152c161c,\n            0x155a152f, 0x1490155d, 0x142613fb, 0x1440142a, 0x159a1402,\n            0x15bd159d, 0x153415c0, 0x1546153b, 0x1549154c, 0x15701517,\n            0x153415b7, 0x1546153b, 0x1529154c, 0x15c81557, 0x150514fa,\n            0x1534150c, 0x1546153b, 0x15df15c8, 0x13e313e3, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x14301421, 0x14341430, 0x1450143b,\n            0x14581454, 0x14a314a3, 0x14c114c5, 0x14fd1508, 0x15211501,\n            0x151d1521, 0x15251525, 0x15651565, 0x153e1596, 0x1537153e,\n            0x154f154f, 0x15531553, 0x15b315a8, 0x15cb15b3, 0x15cf15cb,\n            0x15e715d3, 0x15f315f3, 0x160d15f7, 0x16111615, 0x16481648,\n            0x16691665, 0x16c416bc, 0x16ad16c0, 0x16cb16ad, 0x16d216cb,\n            0x16fe16d2, 0x170b1702, 0x16f316eb, 0x17161712, 0x0, 0x177716ef,\n            0x1743177b, 0x17341747, 0x17381734, 0x175b175f, 0x17b617b6,\n            0x14291401, 0x14431425, 0x1460143f, 0x14ab145c, 0x14a7148f,\n            0x1569150f, 0x15ac1542, 0x16d616b5, 0x179f17a6, 0x172117ba,\n            0x174b166d, 0x16bc1665, 0x168f15fb, 0x171a1730, 0x168b16b1,\n            0x173016b1, 0x14ba1493, 0x164f16f7, 0x168b13fa, 0x159615e7,\n            0x173c1513, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x165e158f,\n            0x13d913de, 0x15731706, 0x15eb14e9, 0x1578158a, 0x1497157c, 0x14f1,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b3102f6, 0x5401b33,\n            0x8d0546, 0x1b770093, 0x2ff1b79, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x1a6d02fc, 0x9931a6b, 0xa10993, 0xe3b00a5,\n            0x1b4b0e3f, 0x1b451b4f, 0x1b391b47, 0x1b351b3b, 0x1b3d1b37,\n            0x1b411b3f, 0x1b43, 0x98b0000, 0xc098f, 0xc000c, 0x993000c,\n            0x9930993, 0x1b3102f6, 0x2fa, 0x5400546, 0x8d0093, 0xa11a6d,\n            0xe3b00a5, 0x1b4b0e3f, 0x971b4f, 0x2f2009d, 0x2f802f4, 0x5590548,\n            0x544, 0x99098d, 0x566009b, 0x0, 0x0, 0x161f0057, 0x5a, 0x61,\n            0x16220068, 0x1629006f, 0x16300076, 0x1637007d, 0x163a0084,\n            0x13e613d5, 0x13e913e6, 0x178f13e9, 0x13ec178f, 0x17ca13ec,\n            0x17ca17ca, 0x13d717ca, 0x13f213d7, 0x13f213f2, 0x141a13f2,\n            0x141c141a, 0x141c141c, 0x1470141c, 0x14701470, 0x13f51470,\n            0x13f513f5, 0x13f813f5, 0x13f813f8, 0x13ff13f8, 0x13ff13ff,\n            0x14e013ff, 0x14e214e0, 0x13dc14e2, 0x140913dc, 0x14f81409,\n            0x14f814f8, 0x153214f8, 0x15321532, 0x15601532, 0x15601560,\n            0x15a01560, 0x15a015a0, 0x15c315a0, 0x15c315c3, 0x15dd15c3,\n            0x15dd15dd, 0x15e215dd, 0x15e215e2, 0x160515e2, 0x16051605,\n            0x163d1605, 0x163d163d, 0x1659163d, 0x16591659, 0x16771659,\n            0x16771677, 0x14ec1677, 0x14ec14ec, 0x140c14ec, 0x140c140c,\n            0x140f140c, 0x140f140f, 0x13e1140f, 0x13e113e1, 0x178813e1,\n            0x14151788, 0x13fc1415, 0x13fc13fc, 0x169e13fc, 0x16a2169e,\n            0x16a616a2, 0x169b16a6, 0x169b, 0x0, 0x8d0000, 0x970095, 0x9b0099,\n            0x9f009d, 0xa500a1, 0x2f402f2, 0x2f802f6, 0x30302fa, 0x3140305,\n            0x30f0343, 0x3740365, 0x3920383, 0x3b003a1, 0x5460540, 0x5440548,\n            0x930559, 0x5680566, 0x5e305d5, 0x62905e6, 0x687067e, 0x6cf06ac,\n            0x71a0607, 0x7230734, 0x7a4077e, 0x83b06af, 0x85e082c, 0x56b088d,\n            0x77006b2, 0x95a0682, 0x98b060a, 0x98f098d, 0x9930991, 0x6920995,\n            0x9a00937, 0xa7d0a2e, 0x6020ad9, 0xae00b0d, 0xb79073e, 0x5d30a28,\n            0x7870b3b, 0x5d80cd3, 0x8400a11, 0xa240ba3, 0xde1086a, 0x6950b41,\n            0xe3b0611, 0xe3f0e3d, 0x1b280e41, 0x1b331b2a, 0x1b3f1b3d,\n            0x1e5c1b31, 0x1bd61e55, 0x1bfd1bef, 0x1c181c08, 0x1e0f1e02,\n            0x1cee1e17, 0x1bd81c16, 0x1bff1bf1, 0x1c1a1c0a, 0x1c411c24,\n            0x1c901c73, 0x1cad1c99, 0x1c1e1cbd, 0x1cda1ccd, 0x1bfb1cdf,\n            0x1cf51cf0, 0x1ca61bde, 0x1d111d0f, 0x1d0d1c8e, 0x1d391d1b,\n            0x1d741d55, 0x1c311d9f, 0x1c221ddc, 0x1e001def, 0x1e111e04,\n            0x1e1b1e19, 0x1bed1c35, 0x1c5d1e34, 0x1c061e42, 0x8b0088,\n            0x194419d4, 0x1a101949, 0x1a12194b, 0x19501a14, 0x19571955,\n            0x1a181a16, 0x1a1c1a1a, 0x1a201a1e, 0x195c19a6, 0x19661961,\n            0x196819b0, 0x196f196d, 0x19811977, 0x198e1983, 0x19981993, 0x199d,\n            0x0, 0x19d81947, 0x19dc19da, 0x19e019de, 0x0, 0x19e419e2,\n            0x19e8198c, 0x19ec19ea, 0x0, 0x197519ee, 0x19f419f2, 0x19f819f6,\n            0x0, 0x197f19fa, 0x19fe, 0x0, 0xe450e43, 0x90e4b, 0xe470e49,\n            0x1a82, 0x1a841b22, 0x1a8b1a89, 0x1b241a90, 0x1b26, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x26b6, 0x26b9, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x26bc0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26c226bf, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26c826c5, 0x26cf26cb, 0x26d726d3,\n            0x26db, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x26df0000, 0x26e226ea, 0x26e626ed, 0x26f1, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x5d50568, 0x5e605e3, 0x67e0629, 0x6ac0687, 0x60706cf, 0x734071a,\n            0x77e0723, 0x6af07a4, 0x82c083b, 0x88d085e, 0x6b2056b, 0x6820770,\n            0x60a095a, 0x9370692, 0xa2e09a0, 0xad90a7d, 0xb0d0602, 0x73e0ae0,\n            0xa280b79, 0xb3b05d3, 0xcd30787, 0xa1105d8, 0xba30840, 0x86a0a24,\n            0xb410de1, 0x6110695, 0x5d50568, 0x5e605e3, 0x67e0629, 0x6ac0687,\n            0x60706cf, 0x734071a, 0x77e0723, 0x6af07a4, 0x82c083b, 0x88d085e,\n            0x6b2056b, 0x6820770, 0x60a095a, 0x9370692, 0xa2e09a0, 0xad90a7d,\n            0x602, 0x73e0ae0, 0xa280b79, 0xb3b05d3, 0xcd30787, 0xa1105d8,\n            0xba30840, 0x86a0a24, 0xb410de1, 0x6110695, 0x5d50568, 0x5e605e3,\n            0x67e0629, 0x6ac0687, 0x60706cf, 0x734071a, 0x77e0723, 0x6af07a4,\n            0x82c083b, 0x88d085e, 0x6b2056b, 0x6820770, 0x60a095a, 0x9370692,\n            0xa2e09a0, 0xad90a7d, 0xb0d0602, 0x73e0ae0, 0xa280b79, 0xb3b05d3,\n            0xcd30787, 0xa1105d8, 0xba30840, 0x86a0a24, 0xb410de1, 0x6110695,\n            0x568, 0x5e605e3, 0x0, 0x687, 0x6070000, 0x71a, 0x77e0000,\n            0x6af07a4, 0x83b, 0x88d085e, 0x6b2056b, 0x6820770, 0x60a095a,\n            0x9370692, 0xa2e09a0, 0xad90000, 0xb0d0000, 0x73e0ae0, 0xa280b79,\n            0xb3b05d3, 0xcd30000, 0xa1105d8, 0xba30840, 0x86a0a24, 0xb410de1,\n            0x6110695, 0x5d50568, 0x5e605e3, 0x67e0629, 0x6ac0687, 0x60706cf,\n            0x734071a, 0x77e0723, 0x6af07a4, 0x82c083b, 0x88d085e, 0x6b2056b,\n            0x6820770, 0x60a095a, 0x9370692, 0xa2e09a0, 0xad90a7d, 0xb0d0602,\n            0x73e0ae0, 0xa280b79, 0xb3b05d3, 0xcd30787, 0xa1105d8, 0xba30840,\n            0x86a0a24, 0xb410de1, 0x6110695, 0x5d50568, 0x5e60000, 0x67e0629,\n            0x687, 0x6070000, 0x734071a, 0x77e0723, 0x6af07a4, 0x83b,\n            0x88d085e, 0x6b2056b, 0x6820770, 0x95a, 0x9370692, 0xa2e09a0,\n            0xad90a7d, 0xb0d0602, 0x73e0ae0, 0xa280b79, 0xb3b05d3, 0xcd30787,\n            0xa1105d8, 0xba30840, 0x86a0a24, 0xb410de1, 0x6110695, 0x5d50568,\n            0x5e60000, 0x67e0629, 0x687, 0x60706cf, 0x734071a, 0x723, 0x7a4,\n            0x0, 0x88d085e, 0x6b2056b, 0x6820770, 0x95a, 0x9370692, 0xa2e09a0,\n            0xad90a7d, 0xb0d0602, 0x73e0ae0, 0xa280b79, 0xb3b05d3, 0xcd30787,\n            0xa1105d8, 0xba30840, 0x86a0a24, 0xb410de1, 0x6110695, 0x5d50568,\n            0x5e605e3, 0x67e0629, 0x6ac0687, 0x60706cf, 0x734071a, 0x77e0723,\n            0x6af07a4, 0x82c083b, 0x88d085e, 0x6b2056b, 0x6820770, 0x60a095a,\n            0x9370692, 0xa2e09a0, 0xad90a7d, 0xb0d0602, 0x73e0ae0, 0xa280b79,\n            0xb3b05d3, 0xcd30787, 0xa1105d8, 0xba30840, 0x86a0a24, 0xb410de1,\n            0x6110695, 0x77e0723, 0x6af07a4, 0x82c083b, 0x88d085e, 0x6b2056b,\n            0x6820770, 0x60a095a, 0x9370692, 0xa2e09a0, 0xad90a7d, 0xb0d0602,\n            0x73e0ae0, 0xa280b79, 0xb3b05d3, 0xcd30787, 0xa1105d8, 0x60a095a,\n            0x9370692, 0xa2e09a0, 0xad90a7d, 0xb0d0602, 0x73e0ae0, 0xa280b79,\n            0xb3b05d3, 0xcd30787, 0xa1105d8, 0xba30840, 0x86a0a24, 0xb410de1,\n            0x6110695, 0x5d50568, 0x5e605e3, 0x67e0629, 0x6ac0687, 0x60706cf,\n            0x734071a, 0x77e0723, 0x6af07a4, 0x82c083b, 0x88d085e, 0x6b2056b,\n            0x6820770, 0x60a095a, 0x9370692, 0xa2e09a0, 0xad90a7d, 0xb0d0602,\n            0x73e0ae0, 0xa280b79, 0xb3b05d3, 0xcd30787, 0xa1105d8, 0xba30840,\n            0x86a0a24, 0xb410de1, 0x6110695, 0x5d50568, 0x5e605e3, 0x67e0629,\n            0x6ac0687, 0x60706cf, 0x734071a, 0x77e0723, 0x6af07a4, 0xb410de1,\n            0x6110695, 0xe800e6f, 0x0, 0xf380ee3, 0xf3c0f3a, 0xf5c0f3e,\n            0xfad0f5e, 0xfde0faf, 0xfe20fe0, 0xfe60fe4, 0x10060fe8, 0xfad1008,\n            0x100f100d, 0x10311011, 0x10351033, 0x1aa3077c, 0x10ea1086,\n            0x10ee10ec, 0x110e10f0, 0x116e1110, 0x11ae1170, 0x11b211b0,\n            0x11ce11cc, 0x11ee11d0, 0x11f811f0, 0x11fc11fa, 0x123c11fe,\n            0x1240123e, 0x1a9e1242, 0x116e10f0, 0x123c11ae, 0x11ee11f0,\n            0xf380ee3, 0xf3c0f3a, 0xf5c0f3e, 0xfad0f5e, 0xfde0faf, 0xfe20fe0,\n            0xfe60fe4, 0x10060fe8, 0xfad1008, 0x100f100d, 0x10311011,\n            0x10351033, 0x1aa3077c, 0x10ea1086, 0x10ee10ec, 0x110e10f0,\n            0x116e1110, 0x11ae1170, 0x11b211b0, 0x11ce11cc, 0x11ee11d0,\n            0x11f811f0, 0x11fc11fa, 0x123c11fe, 0x1240123e, 0x1a9e1242,\n            0x116e10f0, 0x123c11ae, 0x11ee11f0, 0xf380ee3, 0xf3c0f3a,\n            0xf5c0f3e, 0xfad0f5e, 0xfde0faf, 0xfe20fe0, 0xfe60fe4, 0x10060fe8,\n            0xfad1008, 0x100f100d, 0x10311011, 0x10351033, 0x1aa3077c,\n            0x10ea1086, 0x10ee10ec, 0x110e10f0, 0x116e1110, 0x11ae1170,\n            0x11b211b0, 0x11ce11cc, 0x11ee11d0, 0x11f811f0, 0x11fc11fa,\n            0x123c11fe, 0x1240123e, 0x1a9e1242, 0x116e10f0, 0x123c11ae,\n            0x11ee11f0, 0xf380ee3, 0xf3c0f3a, 0xf5c0f3e, 0xfad0f5e, 0xfde0faf,\n            0xfe20fe0, 0xfe60fe4, 0x10060fe8, 0xfad1008, 0x100f100d,\n            0x10311011, 0x10351033, 0x1aa3077c, 0x10ea1086, 0x10ee10ec,\n            0x110e10f0, 0x116e1110, 0x11ae1170, 0x11b211b0, 0x11ce11cc,\n            0x11ee11d0, 0x11f811f0, 0x11fc11fa, 0x123c11fe, 0x1240123e,\n            0x1a9e1242, 0x116e10f0, 0x123c11ae, 0x11ee11f0, 0xf380ee3,\n            0xf3c0f3a, 0xf5c0f3e, 0xfad0f5e, 0xfde0faf, 0xfe20fe0, 0xfe60fe4,\n            0x10060fe8, 0xfad1008, 0x100f100d, 0x10311011, 0x10351033,\n            0x1aa3077c, 0x10ea1086, 0x10ee10ec, 0x110e10f0, 0x116e1110,\n            0x11ae1170, 0x11b211b0, 0x11ce11cc, 0x11ee11d0, 0x11f811f0,\n            0x11fc11fa, 0x123c11fe, 0x1240123e, 0x1a9e1242, 0x116e10f0,\n            0x123c11ae, 0x11ee11f0, 0x12a212a0, 0x0, 0x3140305, 0x30f0343,\n            0x3740365, 0x3920383, 0x3b003a1, 0x3140305, 0x30f0343, 0x3740365,\n            0x3920383, 0x3b003a1, 0x3140305, 0x30f0343, 0x3740365, 0x3920383,\n            0x3b003a1, 0x3140305, 0x30f0343, 0x3740365, 0x3920383, 0x3b003a1,\n            0x3140305, 0x30f0343, 0x3740365, 0x3920383, 0x3b003a1, 0x13f213d7,\n            0x14e013f5, 0x17880000, 0x13f81409, 0x13fc15c3, 0x14ec1677,\n            0x140f140c, 0x15e214f8, 0x1560163d, 0x13dc1659, 0x141c1532,\n            0x13ff1470, 0x15a014e2, 0x160515dd, 0x184a1814, 0x1816183a,\n            0x13f20000, 0x13f5, 0x13e1, 0x13f80000, 0x13fc0000, 0x14ec1677,\n            0x140f140c, 0x15e214f8, 0x1560163d, 0x1659, 0x141c1532, 0x13ff1470,\n            0x15a00000, 0x16050000, 0x0, 0x0, 0x0, 0x13f5, 0x0, 0x13f80000,\n            0x13fc0000, 0x14ec0000, 0x140f0000, 0x15e214f8, 0x15600000, 0x1659,\n            0x1532, 0x13ff0000, 0x15a00000, 0x16050000, 0x184a0000, 0x18160000,\n            0x13f20000, 0x13f5, 0x13e1, 0x13f80000, 0x13fc15c3, 0x1677,\n            0x140f140c, 0x15e214f8, 0x1560163d, 0x1659, 0x141c1532, 0x13ff1470,\n            0x15a00000, 0x160515dd, 0x1814, 0x183a, 0x13f213d7, 0x14e013f5,\n            0x178813e1, 0x13f81409, 0x13fc15c3, 0x14ec0000, 0x140f140c,\n            0x15e214f8, 0x1560163d, 0x13dc1659, 0x141c1532, 0x13ff1470,\n            0x15a014e2, 0x160515dd, 0x0, 0x0, 0x13f20000, 0x14e013f5,\n            0x17880000, 0x13f81409, 0x13fc15c3, 0x14ec0000, 0x140f140c,\n            0x15e214f8, 0x1560163d, 0x13dc1659, 0x141c1532, 0x13ff1470,\n            0x15a014e2, 0x160515dd, 0x0, 0x0, 0x307030a, 0x3f10316, 0x4ab0468,\n            0x4fa04de, 0x520050b, 0x531, 0x0, 0x0, 0x10200fe, 0x10a0106,\n            0x112010e, 0x11a0116, 0x122011e, 0x12a0126, 0x132012e, 0x13a0136,\n            0x142013e, 0x14a0146, 0x152014e, 0x15a0156, 0x162015e, 0x5e31b4d,\n            0x5e5082c, 0x933, 0x5d50568, 0x5e605e3, 0x67e0629, 0x6ac0687,\n            0x60706cf, 0x734071a, 0x77e0723, 0x6af07a4, 0x82c083b, 0x88d085e,\n            0x6b2056b, 0x6820770, 0x60a095a, 0x76c06b1, 0x8660860, 0x9300827,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x761075e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x606, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x1c9e1bc3, 0x1cad, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x20b02197, 0x1cf71ff3, 0x20811f17, 0x208c2532, 0x21fe1f1d,\n            0x21e722f2, 0x21451f9d, 0x21eb1f69, 0x24261f93, 0x2560235c,\n            0x200f2073, 0x219d22cc, 0x1ee921b3, 0x25a01eef, 0x1efd20fa,\n            0x21ad2001, 0x21992574, 0x23f023d2, 0x22bc2005, 0x329221b,\n            0x1f9f2366, 0x2035, 0x0, 0x0, 0x1b511b69, 0x1b5d1b55, 0x1b611b6d,\n            0x1b591b71, 0x1b65, 0x0, 0x0, 0x0, 0x1ffd2147, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x1f031f07, 0x26f51f0b, 0x1f351f2d, 0x1f3b1f37,\n            0x1f411f3f, 0x1f431f47, 0x26fd1e63, 0x1f531f51, 0x1f631f55,\n            0x1e6526f7, 0x1f691f59, 0x1f7126fb, 0x1f251f75, 0x1f7b1f79,\n            0x1f8927b9, 0x1e691f8d, 0x1f9b1f99, 0x1fa11f9f, 0x1fad1e6b,\n            0x1fb51faf, 0x1fbd1fbb, 0x1fc31fbf, 0x1fd51fd3, 0x1fe11fd9,\n            0x1fe71fe5, 0x1fe71fe7, 0x22e42703, 0x1ff51ff1, 0x1ffb2705,\n            0x20031fff, 0x200d2017, 0x20152013, 0x201d2019, 0x2023201f,\n            0x20292027, 0x202d2029, 0x20332031, 0x204b2039, 0x204d203d,\n            0x2043203f, 0x20711f8f, 0x20572055, 0x20532059, 0x205b205d,\n            0x27072067, 0x20772075, 0x2081207b, 0x20962085, 0x270b2709,\n            0x209e209c, 0x209a20a0, 0x1e6d20a4, 0x20a81e6f, 0x20ac20ac,\n            0x20ba270d, 0x20be20bc, 0x270f20c2, 0x20c820c6, 0x20cc2137,\n            0x20d21e71, 0x20e020da, 0x271320de, 0x271520e4, 0x20e820ea,\n            0x20f420ec, 0x1e7320f6, 0x210220fe, 0x21062104, 0x27171e75,\n            0x21171e77, 0x211b2119, 0x27cd211f, 0x271b212b, 0x2486271b,\n            0x21332133, 0x27291e79, 0x213b277d, 0x1e7b213f, 0x21512149,\n            0x21572153, 0x1e7f215f, 0x21611e7d, 0x2163271d, 0x216f216d,\n            0x216f2171, 0x21792177, 0x217d2181, 0x2183217f, 0x21872185,\n            0x218f210b, 0x219f219b, 0x21b121a7, 0x21af2723, 0x21b521a9,\n            0x21c321b9, 0x21c72725, 0x21bd21c1, 0x21cb1e81, 0x21d321cf,\n            0x1e8321cd, 0x21df21db, 0x21f52727, 0x22032215, 0x22091e89,\n            0x1e851e87, 0x1f6d1f6b, 0x220b2217, 0x1ebb2470, 0x221f221d,\n            0x222b2221, 0x27312227, 0x22351e8b, 0x2242222f, 0x27352246,\n            0x22392248, 0x1e8d224c, 0x2250224e, 0x22582252, 0x225c2737,\n            0x22621e8f, 0x22642739, 0x226a1e91, 0x22762270, 0x273b2278,\n            0x273d2711, 0x273f2288, 0x2292228e, 0x2298228a, 0x22a822a0,\n            0x22a422a2, 0x22ac22aa, 0x229e2741, 0x22ba22b8, 0x22c41e93,\n            0x274322c2, 0x22d222b4, 0x27472745, 0x22de22d4, 0x22da22dc,\n            0x22e01e95, 0x22e622e8, 0x26f922ec, 0x274922f4, 0x274d22fa,\n            0x230a2304, 0x274f2314, 0x2320231e, 0x27532751, 0x2336232e,\n            0x23381e97, 0x1e991e99, 0x23462344, 0x234c234a, 0x1e9b2352,\n            0x2755235e, 0x2757236c, 0x27192372, 0x2759237a, 0x275d275b,\n            0x1e9f1e9d, 0x27612396, 0x2763275f, 0x239a2765, 0x239c239c,\n            0x1ea323a0, 0x1ea523a2, 0x27691ea7, 0x23b023ac, 0x1ea923b6,\n            0x23c8276b, 0x276f276d, 0x23e423d8, 0x23e81eab, 0x23ec23ea,\n            0x27732771, 0x23f82773, 0x27751ead, 0x24042402, 0x27771eaf,\n            0x1eb12412, 0x2416241a, 0x277b241e, 0x1eb3242a, 0x24342430,\n            0x1eb5243c, 0x2781277f, 0x27831eb7, 0x27852448, 0x2454244e,\n            0x27872458, 0x24622789, 0x2466278b, 0x1eb9272b, 0x24742472,\n            0x24761ebd, 0x278d20a6, 0x272d278f, 0x2486272f, 0x25942488,\n            0x249e1ebf, 0x24a0249c, 0x24a21fa9, 0x24a624a4, 0x279124aa,\n            0x24ac24a8, 0x24b824b6, 0x24ba24ae, 0x24ce24c4, 0x24be24b4,\n            0x24c224c0, 0x27972793, 0x1ec12795, 0x24d424d2, 0x279f24d8,\n            0x279924da, 0x1ec51ec3, 0x279d279b, 0x24ea1ec7, 0x24ee24ec,\n            0x24f624f0, 0x24fa24f4, 0x250024f8, 0x24fe24fc, 0x1ec92502,\n            0x25082506, 0x25101ecb, 0x27a12512, 0x251a2518, 0x25201ecd,\n            0x27a31e67, 0x1ecf27a5, 0x25361ed1, 0x25502542, 0x27a72558,\n            0x25642562, 0x25762570, 0x26ff27ab, 0x257a257c, 0x27012580,\n            0x258c2586, 0x27af27ad, 0x25b225ac, 0x27b125b6, 0x25cc25b8,\n            0x25d425d2, 0x25da25d0, 0x27b325dc, 0x1ed325e2, 0x27b525e6,\n            0x26021ed5, 0x260e20ee, 0x27bb27b7, 0x1ed91ed7, 0x27bd2622,\n            0x27bf1edb, 0x262e262e, 0x27c12632, 0x1edd263e, 0x264c2646,\n            0x26542650, 0x27c31edf, 0x266c265e, 0x1ee12672, 0x26741ee3,\n            0x1ee527c5, 0x27c927c7, 0x268627cb, 0x26901ee7, 0x26962694,\n            0x269e269a, 0x27cf26a2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    //12288 bytes\n    enum canonMappingTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x40,\n            0x240], [0x100, 0x400, 0x1380], [0x2020100, 0x3020202, 0x2020204,\n            0x2050202, 0x2020202, 0x6020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x0, 0x10000, 0x30002, 0x50004, 0x6, 0x0, 0x70000,\n            0x90008, 0xb000a, 0xc0000, 0x0, 0x0, 0xd, 0xe0000, 0x0, 0x0, 0x0,\n            0x0, 0x10000f, 0x110000, 0x130012, 0x0, 0x140000, 0x160015,\n            0x170000, 0x180000, 0x190000, 0x1a0000, 0x0, 0x0, 0x1b0000, 0x1c,\n            0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f001e, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x210020, 0x230022, 0x250024, 0x270026, 0x28, 0x0,\n            0x29, 0x2b002a, 0x2d002c, 0x2f002e, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x310000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x320000, 0x340033, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x360035, 0x380037, 0x3a0039, 0x3c003b, 0x3e003d, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x3f, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x410000, 0x430042, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x450044, 0x470046, 0x490048, 0x4b004a, 0x4c, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xf000c, 0x250012, 0x4f0045, 0x850000, 0xa1009e, 0xcb00a4,\n            0x121011e, 0x1330124, 0x1880000, 0x1a0019d, 0x1b601a3, 0x1da,\n            0x26d0000, 0x2730270, 0x2f30287, 0x0, 0x322031f, 0x3380325,\n            0x3620358, 0x3980000, 0x3b403b1, 0x3de03b7, 0x4370434, 0x446043a,\n            0x49c0000, 0x4b404b1, 0x4ca04b7, 0x4ee, 0x5840000, 0x58a0587,\n            0x60d059e, 0x61c0000, 0x33b0028, 0x33e002b, 0x380006d, 0x38c0079,\n            0x38f007c, 0x392007f, 0x3950082, 0x3a2008f, 0x0, 0x3cd00ba,\n            0x3d800c5, 0x3db00c8, 0x3fb00e8, 0x3e400d1, 0x40a00f7, 0x41000fd,\n            0x4130100, 0x4190106, 0x41c0109, 0x0, 0x43d0127, 0x440012a,\n            0x443012d, 0x45c0149, 0x130, 0x0, 0x462014f, 0x471015d, 0x1630000,\n            0x1700477, 0x1660484, 0x47a, 0x0, 0x1850000, 0x1940499, 0x18e04a8,\n            0x4a2, 0x0, 0x4d901c5, 0x4e401d0, 0x4f801e4, 0x0, 0x52f021b,\n            0x5450231, 0x5350221, 0x54b0237, 0x552023e, 0x5690255, 0x5580244,\n            0x57b0264, 0x572025b, 0x0, 0x58d0276, 0x594027d, 0x59b0284,\n            0x5b4029d, 0x5b702a0, 0x5e002c9, 0x5f502de, 0x61002f6, 0x30b0302,\n            0x3110628, 0x314062e, 0x631, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50401f0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x2ac0000, 0x5c3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x560000, 0x13d0369, 0x1e70450,\n            0x2a304fb, 0x29205ba, 0x28e05a9, 0x29605a5, 0x28a05ad, 0x5a1,\n            0x35b0048, 0x3540041, 0x653064a, 0x0, 0x4160103, 0x46b0157,\n            0x522020e, 0x5250211, 0x65f065c, 0x465, 0x0, 0x40700f4, 0x0,\n            0x4960182, 0x3650052, 0x6500647, 0x656064d, 0x36c0059, 0x36f005c,\n            0x3e700d4, 0x3ea00d7, 0x4530140, 0x4560143, 0x4fe01ea, 0x50101ed,\n            0x5380224, 0x53b0227, 0x5bd02a6, 0x5c002a9, 0x5660252, 0x5780261,\n            0x0, 0x4250112, 0x0, 0x0, 0x0, 0x351003e, 0x3f400e1, 0x4f101dd,\n            0x4d101bd, 0x4e701d3, 0x4ea01d6, 0x61602fc, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x10000d, 0x66b0000, 0x137, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x662, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0,\n            0x63d0000, 0x6450670, 0x6df06c3, 0x72c, 0x759, 0x7980778, 0x8d1,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x7810735, 0x84707e9, 0x8c10867, 0x92f, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x92808ca, 0x91f08fd, 0x95f,\n            0x0, 0x9b40000, 0x9b7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x9cc09c6, 0x9c30000, 0x0, 0x9ba0000, 0x0, 0x0, 0x9d809e4, 0x9ed,\n            0x0, 0x0, 0x0, 0x0, 0x9de0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa200000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa0e0a08, 0xa050000, 0x0,\n            0xa410000, 0x0, 0x0, 0xa1a0a26, 0xa2f, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa470a44, 0x0, 0x0, 0x0, 0x0,\n            0x9cf0000, 0xa11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9ff09bd,\n            0xa0209c0, 0x0, 0xa0b09c9, 0x0, 0xa4d0a4a, 0xa1409d2, 0xa1709d5,\n            0x0, 0xa1d09db, 0xa2309e1, 0xa2909e7, 0x0, 0xa530a50, 0xa3e09fc,\n            0xa2c09ea, 0xa3209f0, 0xa3509f3, 0xa3809f6, 0x0, 0xa3b09f9, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac10abe, 0xac40ac7, 0xaca, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xad3,\n            0xacd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xad00000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xae80000, 0x0, 0x0, 0x0, 0xaf10000, 0x0, 0xaf4, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xad90ad6, 0xadf0adc, 0xae50ae2, 0xaee0aeb, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xb000000, 0xb03, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xafa0af7, 0xafd0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb120000, 0x0, 0xb15, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xb060000, 0xb0c0b09, 0x0, 0xb0f, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xb21, 0xb1e0000, 0xb24, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xb1b0b18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xb27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb300b2a, 0xb2d, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb33,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xb36, 0x0, 0x0, 0xb400000, 0xb43, 0xb3c0b39, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xb4c0b46, 0xb49, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xb4f, 0xb550b52, 0xb59, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xb5f0000, 0x0, 0x0, 0x0, 0x0, 0xb620000, 0x0, 0x0, 0xb65, 0x0,\n            0xb680000, 0x0, 0x0, 0xb6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb5c0000,\n            0x0, 0x0, 0x0, 0x0, 0xb6e0000, 0xb710000, 0xb89, 0xb8c, 0x0, 0x0,\n            0x0, 0xb740000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb7a0000,\n            0x0, 0x0, 0x0, 0x0, 0xb7d0000, 0x0, 0x0, 0xb80, 0x0, 0xb830000,\n            0x0, 0x0, 0xb86, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb770000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb8f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb92, 0xb95, 0xb98,\n            0xb9b, 0xb9e, 0x0, 0xba1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xba40000,\n            0xba70000, 0x0, 0xbad0baa, 0xbb00000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x37d006a,\n            0x3830070, 0x3860073, 0x3890076, 0x39b0088, 0x39f008c, 0x3a50092,\n            0x3ae009b, 0x3a80095, 0x3ab0098, 0x3d000bd, 0x3d400c1, 0x3fe00eb,\n            0x40100ee, 0x3f700e4, 0x40400f1, 0x40d00fa, 0x41f010c, 0x4280115,\n            0x422010f, 0x42b0118, 0x42e011b, 0x45f014c, 0x4490136, 0x4680154,\n            0x46e015a, 0x4740160, 0x47d0169, 0x480016c, 0x48a0176, 0x4870173,\n            0x48d0179, 0x490017c, 0x493017f, 0x49f018b, 0x4a50191, 0x4ae019a,\n            0x4ab0197, 0x4cd01b9, 0x4d501c1, 0x4dc01c8, 0x4e001cc, 0x5290215,\n            0x52c0218, 0x532021e, 0x53e022a, 0x541022d, 0x5480234, 0x5550241,\n            0x55f024b, 0x54e023a, 0x55b0247, 0x562024e, 0x56c0258, 0x575025e,\n            0x581026a, 0x57e0267, 0x5dd02c6, 0x5e602cf, 0x5e302cc, 0x5900279,\n            0x5970280, 0x5e902d2, 0x5ec02d5, 0x5ef02d8, 0x5f202db, 0x5fb02e4,\n            0x5f802e1, 0x60102e7, 0x60402ea, 0x60702ed, 0x61902ff, 0x62b030e,\n            0x6340317, 0x637031a, 0x56f0431, 0x62205fe, 0x6590000, 0x0, 0x0,\n            0x372005f, 0x35f004c, 0x32c0019, 0x3280015, 0x3340021, 0x330001d,\n            0x3750062, 0x3450032, 0x341002e, 0x34d003a, 0x3490036, 0x3790066,\n            0x3ed00da, 0x3e100ce, 0x3ca00b7, 0x3be00ab, 0x3ba00a7, 0x3c600b3,\n            0x3c200af, 0x3f000dd, 0x44d013a, 0x4590146, 0x51b0207, 0x4f501e1,\n            0x4be01aa, 0x4ba01a6, 0x4c601b2, 0x4c201ae, 0x51e020a, 0x50b01f7,\n            0x50701f3, 0x51301ff, 0x50f01fb, 0x5170203, 0x5da02c3, 0x5b1029a,\n            0x5ca02b3, 0x5c602af, 0x5d202bb, 0x5ce02b7, 0x5d602bf, 0x60a02f0,\n            0x6250308, 0x61f0305, 0x61302f9, 0x0, 0x0, 0x0, 0x81807f6,\n            0x81b07f9, 0x8240802, 0x82d080b, 0x69b0679, 0x69e067c, 0x6a70685,\n            0x6b0068e, 0x855084a, 0x858084d, 0x85c0851, 0x0, 0x6d106c6,\n            0x6d406c9, 0x6d806cd, 0x0, 0x890086e, 0x8930871, 0x89c087a,\n            0x8a50883, 0x70406e2, 0x70706e5, 0x71006ee, 0x71906f7, 0x8e808d9,\n            0x8eb08dc, 0x8ef08e0, 0x8f308e4, 0x7470738, 0x74a073b, 0x74e073f,\n            0x7520743, 0x90b0900, 0x90e0903, 0x9120907, 0x0, 0x767075c,\n            0x76a075f, 0x76e0763, 0x0, 0x9460937, 0x949093a, 0x94d093e,\n            0x9510942, 0x7840000, 0x7870000, 0x78b0000, 0x78f0000, 0x9880966,\n            0x98b0969, 0x9940972, 0x99d097b, 0x7bd079b, 0x7c0079e, 0x7c907a7,\n            0x7d207b0, 0x7e907e2, 0x8470844, 0x8670860, 0x8c108be, 0x8fd08fa,\n            0x91f091c, 0x95f0958, 0x0, 0x8360814, 0x81f07fd, 0x8280806,\n            0x831080f, 0x6b90697, 0x6a20680, 0x6ab0689, 0x6b40692, 0x8ae088c,\n            0x8970875, 0x8a0087e, 0x8a90887, 0x7220700, 0x70b06e9, 0x71406f2,\n            0x71d06fb, 0x9a60984, 0x98f096d, 0x9980976, 0x9a1097f, 0x7db07b9,\n            0x7c407a2, 0x7cd07ab, 0x7d607b4, 0x7f007f3, 0x84107e5, 0x7ec,\n            0x83d083a, 0x6730676, 0x670066d, 0x6bd, 0x8bc, 0x6400000,\n            0x8b90863, 0x86a, 0x8b508b2, 0x6c306c0, 0x6df06dc, 0xbb30726,\n            0xbb90bb6, 0x8c408c7, 0x8d108cd, 0x0, 0x8d508f7, 0x72f0732,\n            0x72c0729, 0xbbc0000, 0xbc20bbf, 0x9220925, 0x92f092b, 0x9190916,\n            0x9330955, 0x77b077e, 0x7780775, 0x63a0772, 0x31d063d, 0x0,\n            0x9b1095b, 0x962, 0x9ad09aa, 0x7590756, 0x7980795, 0x64307df, 0x0,\n            0xbc70bc5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x793, 0x0, 0x4f0152, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xbcc0bc9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbcf,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xbd20000, 0xbd50bd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xbdb, 0x0, 0xbde0000, 0x0, 0xbe1, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbe4, 0xbe7,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xbea0000, 0x0, 0xbed, 0xbf00000, 0xbf30000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xbf9, 0x0, 0x0, 0x0, 0x0,\n            0xbf60000, 0x90003, 0xbff0bfc, 0x0, 0xc050c02, 0x0, 0xc0b0c08, 0x0,\n            0x0, 0x0, 0xc110c0e, 0x0, 0xc1d0c1a, 0x0, 0xc230c20, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xc2f0c2c, 0xc350c32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xc170c14, 0xc290c26, 0x0, 0x0, 0x0, 0xc3b0c38,\n            0xc410c3e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xc470000, 0xc49, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc44, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xc4e, 0xc51, 0xc54, 0xc57, 0xc5a, 0xc5d,\n            0xc60, 0xc63, 0xc66, 0xc69, 0xc6c, 0xc6f, 0xc720000, 0xc750000,\n            0xc780000, 0x0, 0x0, 0x0, 0xc7e0c7b, 0xc810000, 0xc84, 0xc8a0c87,\n            0xc8d0000, 0xc90, 0xc960c93, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xc4b, 0x0, 0x0, 0x0, 0x0, 0xc99, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xc9f, 0xca2, 0xca5, 0xca8, 0xcab, 0xcae,\n            0xcb1, 0xcb4, 0xcb7, 0xcba, 0xcbd, 0xcc0, 0xcc30000, 0xcc60000,\n            0xcc90000, 0x0, 0x0, 0x0, 0xccf0ccc, 0xcd20000, 0xcd5, 0xcdb0cd8,\n            0xcde0000, 0xce1, 0xce70ce4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xc9c, 0xcea0000, 0xcf00ced, 0xcf3, 0x0, 0xcf6,\n            0xfb71241, 0x124b125d, 0xd831043, 0x13270e29, 0xe991327, 0xe4f1293,\n            0xf550e97, 0x116710cd, 0x11fd11e3, 0x12791215, 0x10190feb,\n            0x109d1069, 0x128911c7, 0xd8d12f3, 0xff50e1d, 0x11e11079,\n            0xedb1309, 0x11d91051, 0xf65121d, 0x12031189, 0xfbd0eff,\n            0x108d1025, 0xd9d127d, 0xe050dd9, 0xff10f95, 0x10d31077,\n            0x11dd1171, 0x125911e7, 0x12fb12cf, 0x10e91307, 0x114d1107,\n            0x12a111b9, 0x122f130b, 0xf0b0e87, 0x117d112f, 0x10ed1083,\n            0x12cb1249, 0xecb0e85, 0x102f0fed, 0x11471047, 0x12b11159,\n            0x117f0e03, 0xddd0ddf, 0x114f1115, 0x12b511c5, 0xf67123d,\n            0x12350feb, 0xebb0d87, 0x10950f27, 0xe1110c1, 0xda510f1, 0xd7f0f1b,\n            0xf9d1011, 0xe231145, 0x10d70e7d, 0x122711c9, 0x126d1005,\n            0xf6f100d, 0xf7b11a5, 0xd9110bf, 0xddb0dc3, 0x113d0fdb, 0x122d1195,\n            0xe091291, 0xe9f0e37, 0xfa10f07, 0x10f31053, 0x12f712ab,\n            0x1313130d, 0xfb50df9, 0x12690ffd, 0xf490ef3, 0xf910f57,\n            0x106d104b, 0x111110af, 0x11791153, 0x11cd1261, 0x12a31271,\n            0xdfb0de9, 0x10670e41, 0x1227120b, 0xf230efd, 0x10030f77,\n            0x1091112d, 0xe670d97, 0xee50ebb, 0x109b0f29, 0x116b10a9,\n            0x12951175, 0x12d112c9, 0xd9f12dd, 0x128d110f, 0xf3512c1,\n            0xdb10d8f, 0xec70ebd, 0xfeb0f9f, 0x10cb1073, 0x127711d3, 0xfad1323,\n            0xdf712af, 0xfd10fcb, 0x103b1021, 0x10bd10a1, 0x114310e7,\n            0xdc512e3, 0x12b70f5d, 0xed70da9, 0x12631031, 0xf390f17,\n            0x10950fd5, 0xdeb12bb, 0xecf0e31, 0xfc30fa7, 0x10150fe1,\n            0x10c3109f, 0x120d1163, 0x128f1213, 0xe1312c5, 0xe33103d,\n            0x10b11075, 0x12bd11db, 0x130f12ff, 0x102d0fcf, 0x1121118b,\n            0x11331125, 0x1063108b, 0xd93123b, 0xded11ad, 0xef50de7,\n            0x11390f69, 0x101b0eb5, 0x12670fb3, 0x12b31205, 0xf031221,\n            0xe590db5, 0x0, 0xe7b, 0xfab, 0xde10000, 0x10cf108f, 0x110310f5,\n            0x110d1105, 0x113512d3, 0x116d, 0x11df, 0x1233, 0x12730000, 0x1283,\n            0x0, 0x12e912e7, 0x130512eb, 0x12bf127f, 0xdb30da1, 0xe010db9,\n            0xe170e07, 0xe5f0e53, 0xe790e63, 0xecd0e7f, 0xf2f0ed1, 0xf470f43,\n            0xf970f53, 0xfaf0fa3, 0x10270fdd, 0x10491035, 0x107d106f,\n            0x10eb10a3, 0x10fb10f7, 0x10fd10f9, 0x110110ff, 0x110b1109,\n            0x111d1117, 0x11531127, 0x115b1157, 0x11731161, 0x1197118d,\n            0x11cb1197, 0x12231219, 0x12391237, 0x124f124d, 0x1273126f,\n            0x12d912c7, 0xf2b12e1, 0x119313be, 0x0, 0xdd70d81, 0xd9b0dc1,\n            0xdc90db7, 0xe0b0dff, 0xe490e53, 0xe5d0e51, 0xe830e7b, 0xe9b0e95,\n            0xeb10ea9, 0xf050f01, 0xf1d0f13, 0xf3f0f33, 0xf470f37, 0xf530f41,\n            0xf7f0f5f, 0xf890f85, 0xfab0f99, 0xfbf0fbd, 0xfff0fc7, 0x10211005,\n            0x10411045, 0x10571049, 0x10e3106f, 0x1089107f, 0x10ab108f,\n            0x10b910b5, 0x10c910c7, 0x10d110cf, 0x10df10d5, 0x10ef10dd,\n            0x1127111f, 0x11491131, 0x115f1153, 0x11af1173, 0x11f911c3,\n            0x121f121b, 0x12291223, 0x122b1233, 0x12351237, 0x12391231,\n            0x124f123f, 0x12751265, 0x1299128b, 0x12c712b9, 0x12d512d3,\n            0x12db12d9, 0x12f912e1, 0x13941327, 0x13a61392, 0xd370d23,\n            0x13da0d39, 0x141c13ec, 0x13251321, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xa7a0000, 0xabb0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0xab50ab2,\n            0xaae0aaa, 0xa590a56, 0xa5f0a5c, 0xa680a65, 0xa710a6b, 0xa74,\n            0xa7d0a77, 0xa830a80, 0xa89, 0xa8c, 0xa920a8f, 0xa950000, 0xa98,\n            0xaa10a9e, 0xaa70aa4, 0xa6e0ab8, 0xa860a62, 0xa9b, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1329, 0x132c, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x132f0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x13351332, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x133b1338, 0x1342133e, 0x134a1346, 0x134e, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x13520000, 0x1355135d, 0x13591360, 0x1364, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xd850d89, 0x13680d8b, 0xda10d99, 0xda70da3, 0xdad0dab,\n            0xdaf0db3, 0x13700cf9, 0xdbb0db9, 0xdc70dbd, 0xcfb136a, 0xdcb0dbf,\n            0xdd1136e, 0xd950dd3, 0xdd70dd5, 0xde3142c, 0xcff0de5, 0xdf10def,\n            0xdf50df3, 0xdff0d01, 0xe070e01, 0xe0d0e0b, 0xe110e0f, 0xe170e15,\n            0xe1b0e19, 0xe210e1f, 0xe210e21, 0x105d1376, 0xe270e25, 0xe2b1378,\n            0xe2f0e2d, 0xe350e3d, 0xe3b0e39, 0xe430e3f, 0xe470e45, 0xe4d0e4b,\n            0xe510e4d, 0xe570e55, 0xe690e5b, 0xe6b0e5f, 0xe650e61, 0xe890de7,\n            0xe710e6f, 0xe6d0e73, 0xe750e77, 0x137a0e81, 0xe8d0e8b, 0xe910e8f,\n            0xe9d0e93, 0x137e137c, 0xea50ea3, 0xea10ea7, 0xd030eab, 0xeaf0d05,\n            0xeb30eb3, 0xeb71380, 0xebb0eb9, 0x13820ebf, 0xec30ec1, 0xec50f0f,\n            0xec90d07, 0xed50ed1, 0x13860ed3, 0x13880ed9, 0xedd0edf, 0xee70ee1,\n            0xd090ee9, 0xeed0eeb, 0xef10eef, 0x138a0d0b, 0xef70d0d, 0xefb0ef9,\n            0x14400eff, 0x138e0f09, 0x118f138e, 0xf0d0f0d, 0x139c0d0f,\n            0xf1113f0, 0xd110f15, 0xf1f0f19, 0xf250f21, 0xd150f2d, 0xf2f0d13,\n            0xf311390, 0xf3d0f3b, 0xf3d0f3f, 0xf470f45, 0xf4b0f4f, 0xf510f4d,\n            0xf550f53, 0xf5b0f59, 0xf630f61, 0xf730f6b, 0xf711396, 0xf750f6d,\n            0xf830f79, 0xf871398, 0xf7d0f81, 0xf8b0d17, 0xf930f8f, 0xd190f8d,\n            0xf9b0f97, 0xfa5139a, 0xfa90fb9, 0xfaf0d1f, 0xd1b0d1d, 0xdcf0dcd,\n            0xfb10fbb, 0xd511181, 0xfbf0fbd, 0xfc90fc1, 0x13a40fc5, 0xfd30d21,\n            0xfd90fcd, 0x13a80fdd, 0xfd70fdf, 0xd230fe3, 0xfe70fe5, 0xfef0fe9,\n            0xff313aa, 0xff70d25, 0xff913ac, 0xffb0d27, 0x10051001, 0x13ae1007,\n            0x13b01384, 0x13b21009, 0x1013100f, 0x1017100b, 0x1027101f,\n            0x10231021, 0x102b1029, 0x101d13b4, 0x10391037, 0x10410d29,\n            0x13b6103f, 0x104d1033, 0x13ba13b8, 0x1059104f, 0x10551057,\n            0x105b0d2b, 0x105f1061, 0x136c1065, 0x13bc106b, 0x13c01071,\n            0x107f107b, 0x13c21081, 0x10871085, 0x13c613c4, 0x10971093,\n            0x10990d2d, 0xd2f0d2f, 0x10a710a5, 0x10ad10ab, 0xd3110b3,\n            0x13c810b7, 0x13ca10bb, 0x138c10c1, 0x13cc10c5, 0x13d013ce,\n            0xd350d33, 0x13d410d5, 0x13d613d2, 0x10d913d8, 0x10db10db,\n            0xd3910df, 0xd3b10e1, 0x13dc0d3d, 0x10e910e5, 0xd3f10ef,\n            0x10ff13de, 0x13e213e0, 0x1113110d, 0x11170d41, 0x111b1119,\n            0x13e613e4, 0x112313e6, 0x13e80d43, 0x112b1129, 0x13ea0d45,\n            0xd471137, 0x113b113f, 0x13ee1141, 0xd49114b, 0x11551151,\n            0xd4b115d, 0x13f413f2, 0x13f60d4d, 0x13f81165, 0x116f1169,\n            0x13fa1173, 0x117713fc, 0x117b13fe, 0xd4f139e, 0x11851183,\n            0x11870d53, 0x14000ead, 0x13a01402, 0x118f13a2, 0x126b1191,\n            0x119b0d55, 0x119d1199, 0x119f0dfd, 0x11a311a1, 0x140411a7,\n            0x11a911a5, 0x11b511b3, 0x11b711ab, 0x11cb11c1, 0x11bb11b1,\n            0x11bf11bd, 0x140a1406, 0xd571408, 0x11d111cf, 0x141211d5,\n            0x140c11d7, 0xd5b0d59, 0x1410140e, 0x11e50d5d, 0x11e911e7,\n            0x11ef11eb, 0x11f311ed, 0x11f911f1, 0x11f711f5, 0xd5f11fb,\n            0x120111ff, 0x12070d61, 0x14141209, 0x1211120f, 0x12170d63,\n            0x14160cfd, 0xd651418, 0x12250d67, 0x123f1231, 0x141a1243,\n            0x12471245, 0x12531251, 0x1372141e, 0x12551257, 0x1374125b,\n            0x1265125f, 0x14221420, 0x1281127b, 0x14241285, 0x12971287,\n            0x129f129d, 0x12a5129b, 0x142612a7, 0xd6912a9, 0x142812ad,\n            0x12c30d6b, 0x12cd0ee3, 0x142e142a, 0xd6f0d6d, 0x143012d7,\n            0x14320d71, 0x12db12db, 0x143412df, 0xd7312e5, 0x12ef12ed,\n            0x12f512f1, 0x14360d75, 0x12fd12f9, 0xd771301, 0x13030d79,\n            0xd7b1438, 0x143c143a, 0x1311143e, 0x13150d7d, 0x13191317,\n            0x131d131b, 0x1442131f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    @property\n    {\n        private alias _IDCA = immutable(dchar[]);\n        _IDCA decompCanonTable()\n        {\n            static _IDCA t = [\n                0x0, 0x3b, 0x0, 0x3c, 0x338, 0x0, 0x3d, 0x338, 0x0, 0x3e,\n                0x338, 0x0, 0x41, 0x300, 0x0, 0x41, 0x301, 0x0, 0x41, 0x302,\n                0x0, 0x41, 0x302, 0x300, 0x0, 0x41, 0x302, 0x301, 0x0, 0x41,\n                0x302, 0x303, 0x0, 0x41, 0x302, 0x309, 0x0, 0x41, 0x303, 0x0,\n                0x41, 0x304, 0x0, 0x41, 0x306, 0x0, 0x41, 0x306, 0x300, 0x0,\n                0x41, 0x306, 0x301, 0x0, 0x41, 0x306, 0x303, 0x0, 0x41, 0x306,\n                0x309, 0x0, 0x41, 0x307, 0x0, 0x41, 0x307, 0x304, 0x0, 0x41,\n                0x308, 0x0, 0x41, 0x308, 0x304, 0x0, 0x41, 0x309, 0x0, 0x41,\n                0x30a, 0x0, 0x41, 0x30a, 0x301, 0x0, 0x41, 0x30c, 0x0, 0x41,\n                0x30f, 0x0, 0x41, 0x311, 0x0, 0x41, 0x323, 0x0, 0x41, 0x323,\n                0x302, 0x0, 0x41, 0x323, 0x306, 0x0, 0x41, 0x325, 0x0, 0x41,\n                0x328, 0x0, 0x42, 0x307, 0x0, 0x42, 0x323, 0x0, 0x42, 0x331,\n                0x0, 0x43, 0x301, 0x0, 0x43, 0x302, 0x0, 0x43, 0x307, 0x0,\n                0x43, 0x30c, 0x0, 0x43, 0x327, 0x0, 0x43, 0x327, 0x301, 0x0,\n                0x44, 0x307, 0x0, 0x44, 0x30c, 0x0, 0x44, 0x323, 0x0, 0x44,\n                0x327, 0x0, 0x44, 0x32d, 0x0, 0x44, 0x331, 0x0, 0x45, 0x300,\n                0x0, 0x45, 0x301, 0x0, 0x45, 0x302, 0x0, 0x45, 0x302, 0x300,\n                0x0, 0x45, 0x302, 0x301, 0x0, 0x45, 0x302, 0x303, 0x0, 0x45,\n                0x302, 0x309, 0x0, 0x45, 0x303, 0x0, 0x45, 0x304, 0x0, 0x45,\n                0x304, 0x300, 0x0, 0x45, 0x304, 0x301, 0x0, 0x45, 0x306, 0x0,\n                0x45, 0x307, 0x0, 0x45, 0x308, 0x0, 0x45, 0x309, 0x0, 0x45,\n                0x30c, 0x0, 0x45, 0x30f, 0x0, 0x45, 0x311, 0x0, 0x45, 0x323,\n                0x0, 0x45, 0x323, 0x302, 0x0, 0x45, 0x327, 0x0, 0x45, 0x327,\n                0x306, 0x0, 0x45, 0x328, 0x0, 0x45, 0x32d, 0x0, 0x45, 0x330,\n                0x0, 0x46, 0x307, 0x0, 0x47, 0x301, 0x0, 0x47, 0x302, 0x0,\n                0x47, 0x304, 0x0, 0x47, 0x306, 0x0, 0x47, 0x307, 0x0, 0x47,\n                0x30c, 0x0, 0x47, 0x327, 0x0, 0x48, 0x302, 0x0, 0x48, 0x307,\n                0x0, 0x48, 0x308, 0x0, 0x48, 0x30c, 0x0, 0x48, 0x323, 0x0,\n                0x48, 0x327, 0x0, 0x48, 0x32e, 0x0, 0x49, 0x300, 0x0, 0x49,\n                0x301, 0x0, 0x49, 0x302, 0x0, 0x49, 0x303, 0x0, 0x49, 0x304,\n                0x0, 0x49, 0x306, 0x0, 0x49, 0x307, 0x0, 0x49, 0x308, 0x0,\n                0x49, 0x308, 0x301, 0x0, 0x49, 0x309, 0x0, 0x49, 0x30c, 0x0,\n                0x49, 0x30f, 0x0, 0x49, 0x311, 0x0, 0x49, 0x323, 0x0, 0x49,\n                0x328, 0x0, 0x49, 0x330, 0x0, 0x4a, 0x302, 0x0, 0x4b, 0x0,\n                0x4b, 0x301, 0x0, 0x4b, 0x30c, 0x0, 0x4b, 0x323, 0x0, 0x4b,\n                0x327, 0x0, 0x4b, 0x331, 0x0, 0x4c, 0x301, 0x0, 0x4c, 0x30c,\n                0x0, 0x4c, 0x323, 0x0, 0x4c, 0x323, 0x304, 0x0, 0x4c, 0x327,\n                0x0, 0x4c, 0x32d, 0x0, 0x4c, 0x331, 0x0, 0x4d, 0x301, 0x0,\n                0x4d, 0x307, 0x0, 0x4d, 0x323, 0x0, 0x4e, 0x300, 0x0, 0x4e,\n                0x301, 0x0, 0x4e, 0x303, 0x0, 0x4e, 0x307, 0x0, 0x4e, 0x30c,\n                0x0, 0x4e, 0x323, 0x0, 0x4e, 0x327, 0x0, 0x4e, 0x32d, 0x0,\n                0x4e, 0x331, 0x0, 0x4f, 0x300, 0x0, 0x4f, 0x301, 0x0, 0x4f,\n                0x302, 0x0, 0x4f, 0x302, 0x300, 0x0, 0x4f, 0x302, 0x301, 0x0,\n                0x4f, 0x302, 0x303, 0x0, 0x4f, 0x302, 0x309, 0x0, 0x4f, 0x303,\n                0x0, 0x4f, 0x303, 0x301, 0x0, 0x4f, 0x303, 0x304, 0x0, 0x4f,\n                0x303, 0x308, 0x0, 0x4f, 0x304, 0x0, 0x4f, 0x304, 0x300, 0x0,\n                0x4f, 0x304, 0x301, 0x0, 0x4f, 0x306, 0x0, 0x4f, 0x307, 0x0,\n                0x4f, 0x307, 0x304, 0x0, 0x4f, 0x308, 0x0, 0x4f, 0x308, 0x304,\n                0x0, 0x4f, 0x309, 0x0, 0x4f, 0x30b, 0x0, 0x4f, 0x30c, 0x0,\n                0x4f, 0x30f, 0x0, 0x4f, 0x311, 0x0, 0x4f, 0x31b, 0x0, 0x4f,\n                0x31b, 0x300, 0x0, 0x4f, 0x31b, 0x301, 0x0, 0x4f, 0x31b, 0x303,\n                0x0, 0x4f, 0x31b, 0x309, 0x0, 0x4f, 0x31b, 0x323, 0x0, 0x4f,\n                0x323, 0x0, 0x4f, 0x323, 0x302, 0x0, 0x4f, 0x328, 0x0, 0x4f,\n                0x328, 0x304, 0x0, 0x50, 0x301, 0x0, 0x50, 0x307, 0x0, 0x52,\n                0x301, 0x0, 0x52, 0x307, 0x0, 0x52, 0x30c, 0x0, 0x52, 0x30f,\n                0x0, 0x52, 0x311, 0x0, 0x52, 0x323, 0x0, 0x52, 0x323, 0x304,\n                0x0, 0x52, 0x327, 0x0, 0x52, 0x331, 0x0, 0x53, 0x301, 0x0,\n                0x53, 0x301, 0x307, 0x0, 0x53, 0x302, 0x0, 0x53, 0x307, 0x0,\n                0x53, 0x30c, 0x0, 0x53, 0x30c, 0x307, 0x0, 0x53, 0x323, 0x0,\n                0x53, 0x323, 0x307, 0x0, 0x53, 0x326, 0x0, 0x53, 0x327, 0x0,\n                0x54, 0x307, 0x0, 0x54, 0x30c, 0x0, 0x54, 0x323, 0x0, 0x54,\n                0x326, 0x0, 0x54, 0x327, 0x0, 0x54, 0x32d, 0x0, 0x54, 0x331,\n                0x0, 0x55, 0x300, 0x0, 0x55, 0x301, 0x0, 0x55, 0x302, 0x0,\n                0x55, 0x303, 0x0, 0x55, 0x303, 0x301, 0x0, 0x55, 0x304, 0x0,\n                0x55, 0x304, 0x308, 0x0, 0x55, 0x306, 0x0, 0x55, 0x308, 0x0,\n                0x55, 0x308, 0x300, 0x0, 0x55, 0x308, 0x301, 0x0, 0x55, 0x308,\n                0x304, 0x0, 0x55, 0x308, 0x30c, 0x0, 0x55, 0x309, 0x0, 0x55,\n                0x30a, 0x0, 0x55, 0x30b, 0x0, 0x55, 0x30c, 0x0, 0x55, 0x30f,\n                0x0, 0x55, 0x311, 0x0, 0x55, 0x31b, 0x0, 0x55, 0x31b, 0x300,\n                0x0, 0x55, 0x31b, 0x301, 0x0, 0x55, 0x31b, 0x303, 0x0, 0x55,\n                0x31b, 0x309, 0x0, 0x55, 0x31b, 0x323, 0x0, 0x55, 0x323, 0x0,\n                0x55, 0x324, 0x0, 0x55, 0x328, 0x0, 0x55, 0x32d, 0x0, 0x55,\n                0x330, 0x0, 0x56, 0x303, 0x0, 0x56, 0x323, 0x0, 0x57, 0x300,\n                0x0, 0x57, 0x301, 0x0, 0x57, 0x302, 0x0, 0x57, 0x307, 0x0,\n                0x57, 0x308, 0x0, 0x57, 0x323, 0x0, 0x58, 0x307, 0x0, 0x58,\n                0x308, 0x0, 0x59, 0x300, 0x0, 0x59, 0x301, 0x0, 0x59, 0x302,\n                0x0, 0x59, 0x303, 0x0, 0x59, 0x304, 0x0, 0x59, 0x307, 0x0,\n                0x59, 0x308, 0x0, 0x59, 0x309, 0x0, 0x59, 0x323, 0x0, 0x5a,\n                0x301, 0x0, 0x5a, 0x302, 0x0, 0x5a, 0x307, 0x0, 0x5a, 0x30c,\n                0x0, 0x5a, 0x323, 0x0, 0x5a, 0x331, 0x0, 0x60, 0x0, 0x61,\n                0x300, 0x0, 0x61, 0x301, 0x0, 0x61, 0x302, 0x0, 0x61, 0x302,\n                0x300, 0x0, 0x61, 0x302, 0x301, 0x0, 0x61, 0x302, 0x303, 0x0,\n                0x61, 0x302, 0x309, 0x0, 0x61, 0x303, 0x0, 0x61, 0x304, 0x0,\n                0x61, 0x306, 0x0, 0x61, 0x306, 0x300, 0x0, 0x61, 0x306, 0x301,\n                0x0, 0x61, 0x306, 0x303, 0x0, 0x61, 0x306, 0x309, 0x0, 0x61,\n                0x307, 0x0, 0x61, 0x307, 0x304, 0x0, 0x61, 0x308, 0x0, 0x61,\n                0x308, 0x304, 0x0, 0x61, 0x309, 0x0, 0x61, 0x30a, 0x0, 0x61,\n                0x30a, 0x301, 0x0, 0x61, 0x30c, 0x0, 0x61, 0x30f, 0x0, 0x61,\n                0x311, 0x0, 0x61, 0x323, 0x0, 0x61, 0x323, 0x302, 0x0, 0x61,\n                0x323, 0x306, 0x0, 0x61, 0x325, 0x0, 0x61, 0x328, 0x0, 0x62,\n                0x307, 0x0, 0x62, 0x323, 0x0, 0x62, 0x331, 0x0, 0x63, 0x301,\n                0x0, 0x63, 0x302, 0x0, 0x63, 0x307, 0x0, 0x63, 0x30c, 0x0,\n                0x63, 0x327, 0x0, 0x63, 0x327, 0x301, 0x0, 0x64, 0x307, 0x0,\n                0x64, 0x30c, 0x0, 0x64, 0x323, 0x0, 0x64, 0x327, 0x0, 0x64,\n                0x32d, 0x0, 0x64, 0x331, 0x0, 0x65, 0x300, 0x0, 0x65, 0x301,\n                0x0, 0x65, 0x302, 0x0, 0x65, 0x302, 0x300, 0x0, 0x65, 0x302,\n                0x301, 0x0, 0x65, 0x302, 0x303, 0x0, 0x65, 0x302, 0x309, 0x0,\n                0x65, 0x303, 0x0, 0x65, 0x304, 0x0, 0x65, 0x304, 0x300, 0x0,\n                0x65, 0x304, 0x301, 0x0, 0x65, 0x306, 0x0, 0x65, 0x307, 0x0,\n                0x65, 0x308, 0x0, 0x65, 0x309, 0x0, 0x65, 0x30c, 0x0, 0x65,\n                0x30f, 0x0, 0x65, 0x311, 0x0, 0x65, 0x323, 0x0, 0x65, 0x323,\n                0x302, 0x0, 0x65, 0x327, 0x0, 0x65, 0x327, 0x306, 0x0, 0x65,\n                0x328, 0x0, 0x65, 0x32d, 0x0, 0x65, 0x330, 0x0, 0x66, 0x307,\n                0x0, 0x67, 0x301, 0x0, 0x67, 0x302, 0x0, 0x67, 0x304, 0x0,\n                0x67, 0x306, 0x0, 0x67, 0x307, 0x0, 0x67, 0x30c, 0x0, 0x67,\n                0x327, 0x0, 0x68, 0x302, 0x0, 0x68, 0x307, 0x0, 0x68, 0x308,\n                0x0, 0x68, 0x30c, 0x0, 0x68, 0x323, 0x0, 0x68, 0x327, 0x0,\n                0x68, 0x32e, 0x0, 0x68, 0x331, 0x0, 0x69, 0x300, 0x0, 0x69,\n                0x301, 0x0, 0x69, 0x302, 0x0, 0x69, 0x303, 0x0, 0x69, 0x304,\n                0x0, 0x69, 0x306, 0x0, 0x69, 0x308, 0x0, 0x69, 0x308, 0x301,\n                0x0, 0x69, 0x309, 0x0, 0x69, 0x30c, 0x0, 0x69, 0x30f, 0x0,\n                0x69, 0x311, 0x0, 0x69, 0x323, 0x0, 0x69, 0x328, 0x0, 0x69,\n                0x330, 0x0, 0x6a, 0x302, 0x0, 0x6a, 0x30c, 0x0, 0x6b, 0x301,\n                0x0, 0x6b, 0x30c, 0x0, 0x6b, 0x323, 0x0, 0x6b, 0x327, 0x0,\n                0x6b, 0x331, 0x0, 0x6c, 0x301, 0x0, 0x6c, 0x30c, 0x0, 0x6c,\n                0x323, 0x0, 0x6c, 0x323, 0x304, 0x0, 0x6c, 0x327, 0x0, 0x6c,\n                0x32d, 0x0, 0x6c, 0x331, 0x0, 0x6d, 0x301, 0x0, 0x6d, 0x307,\n                0x0, 0x6d, 0x323, 0x0, 0x6e, 0x300, 0x0, 0x6e, 0x301, 0x0,\n                0x6e, 0x303, 0x0, 0x6e, 0x307, 0x0, 0x6e, 0x30c, 0x0, 0x6e,\n                0x323, 0x0, 0x6e, 0x327, 0x0, 0x6e, 0x32d, 0x0, 0x6e, 0x331,\n                0x0, 0x6f, 0x300, 0x0, 0x6f, 0x301, 0x0, 0x6f, 0x302, 0x0,\n                0x6f, 0x302, 0x300, 0x0, 0x6f, 0x302, 0x301, 0x0, 0x6f, 0x302,\n                0x303, 0x0, 0x6f, 0x302, 0x309, 0x0, 0x6f, 0x303, 0x0, 0x6f,\n                0x303, 0x301, 0x0, 0x6f, 0x303, 0x304, 0x0, 0x6f, 0x303, 0x308,\n                0x0, 0x6f, 0x304, 0x0, 0x6f, 0x304, 0x300, 0x0, 0x6f, 0x304,\n                0x301, 0x0, 0x6f, 0x306, 0x0, 0x6f, 0x307, 0x0, 0x6f, 0x307,\n                0x304, 0x0, 0x6f, 0x308, 0x0, 0x6f, 0x308, 0x304, 0x0, 0x6f,\n                0x309, 0x0, 0x6f, 0x30b, 0x0, 0x6f, 0x30c, 0x0, 0x6f, 0x30f,\n                0x0, 0x6f, 0x311, 0x0, 0x6f, 0x31b, 0x0, 0x6f, 0x31b, 0x300,\n                0x0, 0x6f, 0x31b, 0x301, 0x0, 0x6f, 0x31b, 0x303, 0x0, 0x6f,\n                0x31b, 0x309, 0x0, 0x6f, 0x31b, 0x323, 0x0, 0x6f, 0x323, 0x0,\n                0x6f, 0x323, 0x302, 0x0, 0x6f, 0x328, 0x0, 0x6f, 0x328, 0x304,\n                0x0, 0x70, 0x301, 0x0, 0x70, 0x307, 0x0, 0x72, 0x301, 0x0,\n                0x72, 0x307, 0x0, 0x72, 0x30c, 0x0, 0x72, 0x30f, 0x0, 0x72,\n                0x311, 0x0, 0x72, 0x323, 0x0, 0x72, 0x323, 0x304, 0x0, 0x72,\n                0x327, 0x0, 0x72, 0x331, 0x0, 0x73, 0x301, 0x0, 0x73, 0x301,\n                0x307, 0x0, 0x73, 0x302, 0x0, 0x73, 0x307, 0x0, 0x73, 0x30c,\n                0x0, 0x73, 0x30c, 0x307, 0x0, 0x73, 0x323, 0x0, 0x73, 0x323,\n                0x307, 0x0, 0x73, 0x326, 0x0, 0x73, 0x327, 0x0, 0x74, 0x307,\n                0x0, 0x74, 0x308, 0x0, 0x74, 0x30c, 0x0, 0x74, 0x323, 0x0,\n                0x74, 0x326, 0x0, 0x74, 0x327, 0x0, 0x74, 0x32d, 0x0, 0x74,\n                0x331, 0x0, 0x75, 0x300, 0x0, 0x75, 0x301, 0x0, 0x75, 0x302,\n                0x0, 0x75, 0x303, 0x0, 0x75, 0x303, 0x301, 0x0, 0x75, 0x304,\n                0x0, 0x75, 0x304, 0x308, 0x0, 0x75, 0x306, 0x0, 0x75, 0x308,\n                0x0, 0x75, 0x308, 0x300, 0x0, 0x75, 0x308, 0x301, 0x0, 0x75,\n                0x308, 0x304, 0x0, 0x75, 0x308, 0x30c, 0x0, 0x75, 0x309, 0x0,\n                0x75, 0x30a, 0x0, 0x75, 0x30b, 0x0, 0x75, 0x30c, 0x0, 0x75,\n                0x30f, 0x0, 0x75, 0x311, 0x0, 0x75, 0x31b, 0x0, 0x75, 0x31b,\n                0x300, 0x0, 0x75, 0x31b, 0x301, 0x0, 0x75, 0x31b, 0x303, 0x0,\n                0x75, 0x31b, 0x309, 0x0, 0x75, 0x31b, 0x323, 0x0, 0x75, 0x323,\n                0x0, 0x75, 0x324, 0x0, 0x75, 0x328, 0x0, 0x75, 0x32d, 0x0,\n                0x75, 0x330, 0x0, 0x76, 0x303, 0x0, 0x76, 0x323, 0x0, 0x77,\n                0x300, 0x0, 0x77, 0x301, 0x0, 0x77, 0x302, 0x0, 0x77, 0x307,\n                0x0, 0x77, 0x308, 0x0, 0x77, 0x30a, 0x0, 0x77, 0x323, 0x0,\n                0x78, 0x307, 0x0, 0x78, 0x308, 0x0, 0x79, 0x300, 0x0, 0x79,\n                0x301, 0x0, 0x79, 0x302, 0x0, 0x79, 0x303, 0x0, 0x79, 0x304,\n                0x0, 0x79, 0x307, 0x0, 0x79, 0x308, 0x0, 0x79, 0x309, 0x0,\n                0x79, 0x30a, 0x0, 0x79, 0x323, 0x0, 0x7a, 0x301, 0x0, 0x7a,\n                0x302, 0x0, 0x7a, 0x307, 0x0, 0x7a, 0x30c, 0x0, 0x7a, 0x323,\n                0x0, 0x7a, 0x331, 0x0, 0xa8, 0x300, 0x0, 0xa8, 0x301, 0x0,\n                0xa8, 0x342, 0x0, 0xb4, 0x0, 0xb7, 0x0, 0xc6, 0x301, 0x0, 0xc6,\n                0x304, 0x0, 0xd8, 0x301, 0x0, 0xe6, 0x301, 0x0, 0xe6, 0x304,\n                0x0, 0xf8, 0x301, 0x0, 0x17f, 0x307, 0x0, 0x1b7, 0x30c, 0x0,\n                0x292, 0x30c, 0x0, 0x2b9, 0x0, 0x300, 0x0, 0x301, 0x0, 0x308,\n                0x301, 0x0, 0x313, 0x0, 0x391, 0x300, 0x0, 0x391, 0x301, 0x0,\n                0x391, 0x304, 0x0, 0x391, 0x306, 0x0, 0x391, 0x313, 0x0, 0x391,\n                0x313, 0x300, 0x0, 0x391, 0x313, 0x300, 0x345, 0x0, 0x391,\n                0x313, 0x301, 0x0, 0x391, 0x313, 0x301, 0x345, 0x0, 0x391,\n                0x313, 0x342, 0x0, 0x391, 0x313, 0x342, 0x345, 0x0, 0x391,\n                0x313, 0x345, 0x0, 0x391, 0x314, 0x0, 0x391, 0x314, 0x300, 0x0,\n                0x391, 0x314, 0x300, 0x345, 0x0, 0x391, 0x314, 0x301, 0x0,\n                0x391, 0x314, 0x301, 0x345, 0x0, 0x391, 0x314, 0x342, 0x0,\n                0x391, 0x314, 0x342, 0x345, 0x0, 0x391, 0x314, 0x345, 0x0,\n                0x391, 0x345, 0x0, 0x395, 0x300, 0x0, 0x395, 0x301, 0x0, 0x395,\n                0x313, 0x0, 0x395, 0x313, 0x300, 0x0, 0x395, 0x313, 0x301, 0x0,\n                0x395, 0x314, 0x0, 0x395, 0x314, 0x300, 0x0, 0x395, 0x314,\n                0x301, 0x0, 0x397, 0x300, 0x0, 0x397, 0x301, 0x0, 0x397, 0x313,\n                0x0, 0x397, 0x313, 0x300, 0x0, 0x397, 0x313, 0x300, 0x345, 0x0,\n                0x397, 0x313, 0x301, 0x0, 0x397, 0x313, 0x301, 0x345, 0x0,\n                0x397, 0x313, 0x342, 0x0, 0x397, 0x313, 0x342, 0x345, 0x0,\n                0x397, 0x313, 0x345, 0x0, 0x397, 0x314, 0x0, 0x397, 0x314,\n                0x300, 0x0, 0x397, 0x314, 0x300, 0x345, 0x0, 0x397, 0x314,\n                0x301, 0x0, 0x397, 0x314, 0x301, 0x345, 0x0, 0x397, 0x314,\n                0x342, 0x0, 0x397, 0x314, 0x342, 0x345, 0x0, 0x397, 0x314,\n                0x345, 0x0, 0x397, 0x345, 0x0, 0x399, 0x300, 0x0, 0x399, 0x301,\n                0x0, 0x399, 0x304, 0x0, 0x399, 0x306, 0x0, 0x399, 0x308, 0x0,\n                0x399, 0x313, 0x0, 0x399, 0x313, 0x300, 0x0, 0x399, 0x313,\n                0x301, 0x0, 0x399, 0x313, 0x342, 0x0, 0x399, 0x314, 0x0, 0x399,\n                0x314, 0x300, 0x0, 0x399, 0x314, 0x301, 0x0, 0x399, 0x314,\n                0x342, 0x0, 0x39f, 0x300, 0x0, 0x39f, 0x301, 0x0, 0x39f, 0x313,\n                0x0, 0x39f, 0x313, 0x300, 0x0, 0x39f, 0x313, 0x301, 0x0, 0x39f,\n                0x314, 0x0, 0x39f, 0x314, 0x300, 0x0, 0x39f, 0x314, 0x301, 0x0,\n                0x3a1, 0x314, 0x0, 0x3a5, 0x300, 0x0, 0x3a5, 0x301, 0x0, 0x3a5,\n                0x304, 0x0, 0x3a5, 0x306, 0x0, 0x3a5, 0x308, 0x0, 0x3a5, 0x314,\n                0x0, 0x3a5, 0x314, 0x300, 0x0, 0x3a5, 0x314, 0x301, 0x0, 0x3a5,\n                0x314, 0x342, 0x0, 0x3a9, 0x0, 0x3a9, 0x300, 0x0, 0x3a9, 0x301,\n                0x0, 0x3a9, 0x313, 0x0, 0x3a9, 0x313, 0x300, 0x0, 0x3a9, 0x313,\n                0x300, 0x345, 0x0, 0x3a9, 0x313, 0x301, 0x0, 0x3a9, 0x313,\n                0x301, 0x345, 0x0, 0x3a9, 0x313, 0x342, 0x0, 0x3a9, 0x313,\n                0x342, 0x345, 0x0, 0x3a9, 0x313, 0x345, 0x0, 0x3a9, 0x314, 0x0,\n                0x3a9, 0x314, 0x300, 0x0, 0x3a9, 0x314, 0x300, 0x345, 0x0,\n                0x3a9, 0x314, 0x301, 0x0, 0x3a9, 0x314, 0x301, 0x345, 0x0,\n                0x3a9, 0x314, 0x342, 0x0, 0x3a9, 0x314, 0x342, 0x345, 0x0,\n                0x3a9, 0x314, 0x345, 0x0, 0x3a9, 0x345, 0x0, 0x3b1, 0x300, 0x0,\n                0x3b1, 0x300, 0x345, 0x0, 0x3b1, 0x301, 0x0, 0x3b1, 0x301,\n                0x345, 0x0, 0x3b1, 0x304, 0x0, 0x3b1, 0x306, 0x0, 0x3b1, 0x313,\n                0x0, 0x3b1, 0x313, 0x300, 0x0, 0x3b1, 0x313, 0x300, 0x345, 0x0,\n                0x3b1, 0x313, 0x301, 0x0, 0x3b1, 0x313, 0x301, 0x345, 0x0,\n                0x3b1, 0x313, 0x342, 0x0, 0x3b1, 0x313, 0x342, 0x345, 0x0,\n                0x3b1, 0x313, 0x345, 0x0, 0x3b1, 0x314, 0x0, 0x3b1, 0x314,\n                0x300, 0x0, 0x3b1, 0x314, 0x300, 0x345, 0x0, 0x3b1, 0x314,\n                0x301, 0x0, 0x3b1, 0x314, 0x301, 0x345, 0x0, 0x3b1, 0x314,\n                0x342, 0x0, 0x3b1, 0x314, 0x342, 0x345, 0x0, 0x3b1, 0x314,\n                0x345, 0x0, 0x3b1, 0x342, 0x0, 0x3b1, 0x342, 0x345, 0x0, 0x3b1,\n                0x345, 0x0, 0x3b5, 0x300, 0x0, 0x3b5, 0x301, 0x0, 0x3b5, 0x313,\n                0x0, 0x3b5, 0x313, 0x300, 0x0, 0x3b5, 0x313, 0x301, 0x0, 0x3b5,\n                0x314, 0x0, 0x3b5, 0x314, 0x300, 0x0, 0x3b5, 0x314, 0x301, 0x0,\n                0x3b7, 0x300, 0x0, 0x3b7, 0x300, 0x345, 0x0, 0x3b7, 0x301, 0x0,\n                0x3b7, 0x301, 0x345, 0x0, 0x3b7, 0x313, 0x0, 0x3b7, 0x313,\n                0x300, 0x0, 0x3b7, 0x313, 0x300, 0x345, 0x0, 0x3b7, 0x313,\n                0x301, 0x0, 0x3b7, 0x313, 0x301, 0x345, 0x0, 0x3b7, 0x313,\n                0x342, 0x0, 0x3b7, 0x313, 0x342, 0x345, 0x0, 0x3b7, 0x313,\n                0x345, 0x0, 0x3b7, 0x314, 0x0, 0x3b7, 0x314, 0x300, 0x0, 0x3b7,\n                0x314, 0x300, 0x345, 0x0, 0x3b7, 0x314, 0x301, 0x0, 0x3b7,\n                0x314, 0x301, 0x345, 0x0, 0x3b7, 0x314, 0x342, 0x0, 0x3b7,\n                0x314, 0x342, 0x345, 0x0, 0x3b7, 0x314, 0x345, 0x0, 0x3b7,\n                0x342, 0x0, 0x3b7, 0x342, 0x345, 0x0, 0x3b7, 0x345, 0x0, 0x3b9,\n                0x0, 0x3b9, 0x300, 0x0, 0x3b9, 0x301, 0x0, 0x3b9, 0x304, 0x0,\n                0x3b9, 0x306, 0x0, 0x3b9, 0x308, 0x0, 0x3b9, 0x308, 0x300, 0x0,\n                0x3b9, 0x308, 0x301, 0x0, 0x3b9, 0x308, 0x342, 0x0, 0x3b9,\n                0x313, 0x0, 0x3b9, 0x313, 0x300, 0x0, 0x3b9, 0x313, 0x301, 0x0,\n                0x3b9, 0x313, 0x342, 0x0, 0x3b9, 0x314, 0x0, 0x3b9, 0x314,\n                0x300, 0x0, 0x3b9, 0x314, 0x301, 0x0, 0x3b9, 0x314, 0x342, 0x0,\n                0x3b9, 0x342, 0x0, 0x3bf, 0x300, 0x0, 0x3bf, 0x301, 0x0, 0x3bf,\n                0x313, 0x0, 0x3bf, 0x313, 0x300, 0x0, 0x3bf, 0x313, 0x301, 0x0,\n                0x3bf, 0x314, 0x0, 0x3bf, 0x314, 0x300, 0x0, 0x3bf, 0x314,\n                0x301, 0x0, 0x3c1, 0x313, 0x0, 0x3c1, 0x314, 0x0, 0x3c5, 0x300,\n                0x0, 0x3c5, 0x301, 0x0, 0x3c5, 0x304, 0x0, 0x3c5, 0x306, 0x0,\n                0x3c5, 0x308, 0x0, 0x3c5, 0x308, 0x300, 0x0, 0x3c5, 0x308,\n                0x301, 0x0, 0x3c5, 0x308, 0x342, 0x0, 0x3c5, 0x313, 0x0, 0x3c5,\n                0x313, 0x300, 0x0, 0x3c5, 0x313, 0x301, 0x0, 0x3c5, 0x313,\n                0x342, 0x0, 0x3c5, 0x314, 0x0, 0x3c5, 0x314, 0x300, 0x0, 0x3c5,\n                0x314, 0x301, 0x0, 0x3c5, 0x314, 0x342, 0x0, 0x3c5, 0x342, 0x0,\n                0x3c9, 0x300, 0x0, 0x3c9, 0x300, 0x345, 0x0, 0x3c9, 0x301, 0x0,\n                0x3c9, 0x301, 0x345, 0x0, 0x3c9, 0x313, 0x0, 0x3c9, 0x313,\n                0x300, 0x0, 0x3c9, 0x313, 0x300, 0x345, 0x0, 0x3c9, 0x313,\n                0x301, 0x0, 0x3c9, 0x313, 0x301, 0x345, 0x0, 0x3c9, 0x313,\n                0x342, 0x0, 0x3c9, 0x313, 0x342, 0x345, 0x0, 0x3c9, 0x313,\n                0x345, 0x0, 0x3c9, 0x314, 0x0, 0x3c9, 0x314, 0x300, 0x0, 0x3c9,\n                0x314, 0x300, 0x345, 0x0, 0x3c9, 0x314, 0x301, 0x0, 0x3c9,\n                0x314, 0x301, 0x345, 0x0, 0x3c9, 0x314, 0x342, 0x0, 0x3c9,\n                0x314, 0x342, 0x345, 0x0, 0x3c9, 0x314, 0x345, 0x0, 0x3c9,\n                0x342, 0x0, 0x3c9, 0x342, 0x345, 0x0, 0x3c9, 0x345, 0x0, 0x3d2,\n                0x301, 0x0, 0x3d2, 0x308, 0x0, 0x406, 0x308, 0x0, 0x410, 0x306,\n                0x0, 0x410, 0x308, 0x0, 0x413, 0x301, 0x0, 0x415, 0x300, 0x0,\n                0x415, 0x306, 0x0, 0x415, 0x308, 0x0, 0x416, 0x306, 0x0, 0x416,\n                0x308, 0x0, 0x417, 0x308, 0x0, 0x418, 0x300, 0x0, 0x418, 0x304,\n                0x0, 0x418, 0x306, 0x0, 0x418, 0x308, 0x0, 0x41a, 0x301, 0x0,\n                0x41e, 0x308, 0x0, 0x423, 0x304, 0x0, 0x423, 0x306, 0x0, 0x423,\n                0x308, 0x0, 0x423, 0x30b, 0x0, 0x427, 0x308, 0x0, 0x42b, 0x308,\n                0x0, 0x42d, 0x308, 0x0, 0x430, 0x306, 0x0, 0x430, 0x308, 0x0,\n                0x433, 0x301, 0x0, 0x435, 0x300, 0x0, 0x435, 0x306, 0x0, 0x435,\n                0x308, 0x0, 0x436, 0x306, 0x0, 0x436, 0x308, 0x0, 0x437, 0x308,\n                0x0, 0x438, 0x300, 0x0, 0x438, 0x304, 0x0, 0x438, 0x306, 0x0,\n                0x438, 0x308, 0x0, 0x43a, 0x301, 0x0, 0x43e, 0x308, 0x0, 0x443,\n                0x304, 0x0, 0x443, 0x306, 0x0, 0x443, 0x308, 0x0, 0x443, 0x30b,\n                0x0, 0x447, 0x308, 0x0, 0x44b, 0x308, 0x0, 0x44d, 0x308, 0x0,\n                0x456, 0x308, 0x0, 0x474, 0x30f, 0x0, 0x475, 0x30f, 0x0, 0x4d8,\n                0x308, 0x0, 0x4d9, 0x308, 0x0, 0x4e8, 0x308, 0x0, 0x4e9, 0x308,\n                0x0, 0x5d0, 0x5b7, 0x0, 0x5d0, 0x5b8, 0x0, 0x5d0, 0x5bc, 0x0,\n                0x5d1, 0x5bc, 0x0, 0x5d1, 0x5bf, 0x0, 0x5d2, 0x5bc, 0x0, 0x5d3,\n                0x5bc, 0x0, 0x5d4, 0x5bc, 0x0, 0x5d5, 0x5b9, 0x0, 0x5d5, 0x5bc,\n                0x0, 0x5d6, 0x5bc, 0x0, 0x5d8, 0x5bc, 0x0, 0x5d9, 0x5b4, 0x0,\n                0x5d9, 0x5bc, 0x0, 0x5da, 0x5bc, 0x0, 0x5db, 0x5bc, 0x0, 0x5db,\n                0x5bf, 0x0, 0x5dc, 0x5bc, 0x0, 0x5de, 0x5bc, 0x0, 0x5e0, 0x5bc,\n                0x0, 0x5e1, 0x5bc, 0x0, 0x5e3, 0x5bc, 0x0, 0x5e4, 0x5bc, 0x0,\n                0x5e4, 0x5bf, 0x0, 0x5e6, 0x5bc, 0x0, 0x5e7, 0x5bc, 0x0, 0x5e8,\n                0x5bc, 0x0, 0x5e9, 0x5bc, 0x0, 0x5e9, 0x5bc, 0x5c1, 0x0, 0x5e9,\n                0x5bc, 0x5c2, 0x0, 0x5e9, 0x5c1, 0x0, 0x5e9, 0x5c2, 0x0, 0x5ea,\n                0x5bc, 0x0, 0x5f2, 0x5b7, 0x0, 0x627, 0x653, 0x0, 0x627, 0x654,\n                0x0, 0x627, 0x655, 0x0, 0x648, 0x654, 0x0, 0x64a, 0x654, 0x0,\n                0x6c1, 0x654, 0x0, 0x6d2, 0x654, 0x0, 0x6d5, 0x654, 0x0, 0x915,\n                0x93c, 0x0, 0x916, 0x93c, 0x0, 0x917, 0x93c, 0x0, 0x91c, 0x93c,\n                0x0, 0x921, 0x93c, 0x0, 0x922, 0x93c, 0x0, 0x928, 0x93c, 0x0,\n                0x92b, 0x93c, 0x0, 0x92f, 0x93c, 0x0, 0x930, 0x93c, 0x0, 0x933,\n                0x93c, 0x0, 0x9a1, 0x9bc, 0x0, 0x9a2, 0x9bc, 0x0, 0x9af, 0x9bc,\n                0x0, 0x9c7, 0x9be, 0x0, 0x9c7, 0x9d7, 0x0, 0xa16, 0xa3c, 0x0,\n                0xa17, 0xa3c, 0x0, 0xa1c, 0xa3c, 0x0, 0xa2b, 0xa3c, 0x0, 0xa32,\n                0xa3c, 0x0, 0xa38, 0xa3c, 0x0, 0xb21, 0xb3c, 0x0, 0xb22, 0xb3c,\n                0x0, 0xb47, 0xb3e, 0x0, 0xb47, 0xb56, 0x0, 0xb47, 0xb57, 0x0,\n                0xb92, 0xbd7, 0x0, 0xbc6, 0xbbe, 0x0, 0xbc6, 0xbd7, 0x0, 0xbc7,\n                0xbbe, 0x0, 0xc46, 0xc56, 0x0, 0xcbf, 0xcd5, 0x0, 0xcc6, 0xcc2,\n                0x0, 0xcc6, 0xcc2, 0xcd5, 0x0, 0xcc6, 0xcd5, 0x0, 0xcc6, 0xcd6,\n                0x0, 0xd46, 0xd3e, 0x0, 0xd46, 0xd57, 0x0, 0xd47, 0xd3e, 0x0,\n                0xdd9, 0xdca, 0x0, 0xdd9, 0xdcf, 0x0, 0xdd9, 0xdcf, 0xdca, 0x0,\n                0xdd9, 0xddf, 0x0, 0xf40, 0xfb5, 0x0, 0xf42, 0xfb7, 0x0, 0xf4c,\n                0xfb7, 0x0, 0xf51, 0xfb7, 0x0, 0xf56, 0xfb7, 0x0, 0xf5b, 0xfb7,\n                0x0, 0xf71, 0xf72, 0x0, 0xf71, 0xf74, 0x0, 0xf71, 0xf80, 0x0,\n                0xf90, 0xfb5, 0x0, 0xf92, 0xfb7, 0x0, 0xf9c, 0xfb7, 0x0, 0xfa1,\n                0xfb7, 0x0, 0xfa6, 0xfb7, 0x0, 0xfab, 0xfb7, 0x0, 0xfb2, 0xf80,\n                0x0, 0xfb3, 0xf80, 0x0, 0x1025, 0x102e, 0x0, 0x1b05, 0x1b35,\n                0x0, 0x1b07, 0x1b35, 0x0, 0x1b09, 0x1b35, 0x0, 0x1b0b, 0x1b35,\n                0x0, 0x1b0d, 0x1b35, 0x0, 0x1b11, 0x1b35, 0x0, 0x1b3a, 0x1b35,\n                0x0, 0x1b3c, 0x1b35, 0x0, 0x1b3e, 0x1b35, 0x0, 0x1b3f, 0x1b35,\n                0x0, 0x1b42, 0x1b35, 0x0, 0x1fbf, 0x300, 0x0, 0x1fbf, 0x301,\n                0x0, 0x1fbf, 0x342, 0x0, 0x1ffe, 0x300, 0x0, 0x1ffe, 0x301,\n                0x0, 0x1ffe, 0x342, 0x0, 0x2002, 0x0, 0x2003, 0x0, 0x2190,\n                0x338, 0x0, 0x2192, 0x338, 0x0, 0x2194, 0x338, 0x0, 0x21d0,\n                0x338, 0x0, 0x21d2, 0x338, 0x0, 0x21d4, 0x338, 0x0, 0x2203,\n                0x338, 0x0, 0x2208, 0x338, 0x0, 0x220b, 0x338, 0x0, 0x2223,\n                0x338, 0x0, 0x2225, 0x338, 0x0, 0x223c, 0x338, 0x0, 0x2243,\n                0x338, 0x0, 0x2245, 0x338, 0x0, 0x2248, 0x338, 0x0, 0x224d,\n                0x338, 0x0, 0x2261, 0x338, 0x0, 0x2264, 0x338, 0x0, 0x2265,\n                0x338, 0x0, 0x2272, 0x338, 0x0, 0x2273, 0x338, 0x0, 0x2276,\n                0x338, 0x0, 0x2277, 0x338, 0x0, 0x227a, 0x338, 0x0, 0x227b,\n                0x338, 0x0, 0x227c, 0x338, 0x0, 0x227d, 0x338, 0x0, 0x2282,\n                0x338, 0x0, 0x2283, 0x338, 0x0, 0x2286, 0x338, 0x0, 0x2287,\n                0x338, 0x0, 0x2291, 0x338, 0x0, 0x2292, 0x338, 0x0, 0x22a2,\n                0x338, 0x0, 0x22a8, 0x338, 0x0, 0x22a9, 0x338, 0x0, 0x22ab,\n                0x338, 0x0, 0x22b2, 0x338, 0x0, 0x22b3, 0x338, 0x0, 0x22b4,\n                0x338, 0x0, 0x22b5, 0x338, 0x0, 0x2add, 0x338, 0x0, 0x3008,\n                0x0, 0x3009, 0x0, 0x3046, 0x3099, 0x0, 0x304b, 0x3099, 0x0,\n                0x304d, 0x3099, 0x0, 0x304f, 0x3099, 0x0, 0x3051, 0x3099, 0x0,\n                0x3053, 0x3099, 0x0, 0x3055, 0x3099, 0x0, 0x3057, 0x3099, 0x0,\n                0x3059, 0x3099, 0x0, 0x305b, 0x3099, 0x0, 0x305d, 0x3099, 0x0,\n                0x305f, 0x3099, 0x0, 0x3061, 0x3099, 0x0, 0x3064, 0x3099, 0x0,\n                0x3066, 0x3099, 0x0, 0x3068, 0x3099, 0x0, 0x306f, 0x3099, 0x0,\n                0x306f, 0x309a, 0x0, 0x3072, 0x3099, 0x0, 0x3072, 0x309a, 0x0,\n                0x3075, 0x3099, 0x0, 0x3075, 0x309a, 0x0, 0x3078, 0x3099, 0x0,\n                0x3078, 0x309a, 0x0, 0x307b, 0x3099, 0x0, 0x307b, 0x309a, 0x0,\n                0x309d, 0x3099, 0x0, 0x30a6, 0x3099, 0x0, 0x30ab, 0x3099, 0x0,\n                0x30ad, 0x3099, 0x0, 0x30af, 0x3099, 0x0, 0x30b1, 0x3099, 0x0,\n                0x30b3, 0x3099, 0x0, 0x30b5, 0x3099, 0x0, 0x30b7, 0x3099, 0x0,\n                0x30b9, 0x3099, 0x0, 0x30bb, 0x3099, 0x0, 0x30bd, 0x3099, 0x0,\n                0x30bf, 0x3099, 0x0, 0x30c1, 0x3099, 0x0, 0x30c4, 0x3099, 0x0,\n                0x30c6, 0x3099, 0x0, 0x30c8, 0x3099, 0x0, 0x30cf, 0x3099, 0x0,\n                0x30cf, 0x309a, 0x0, 0x30d2, 0x3099, 0x0, 0x30d2, 0x309a, 0x0,\n                0x30d5, 0x3099, 0x0, 0x30d5, 0x309a, 0x0, 0x30d8, 0x3099, 0x0,\n                0x30d8, 0x309a, 0x0, 0x30db, 0x3099, 0x0, 0x30db, 0x309a, 0x0,\n                0x30ef, 0x3099, 0x0, 0x30f0, 0x3099, 0x0, 0x30f1, 0x3099, 0x0,\n                0x30f2, 0x3099, 0x0, 0x30fd, 0x3099, 0x0, 0x349e, 0x0, 0x34b9,\n                0x0, 0x34bb, 0x0, 0x34df, 0x0, 0x3515, 0x0, 0x36ee, 0x0,\n                0x36fc, 0x0, 0x3781, 0x0, 0x382f, 0x0, 0x3862, 0x0, 0x387c,\n                0x0, 0x38c7, 0x0, 0x38e3, 0x0, 0x391c, 0x0, 0x393a, 0x0,\n                0x3a2e, 0x0, 0x3a6c, 0x0, 0x3ae4, 0x0, 0x3b08, 0x0, 0x3b19,\n                0x0, 0x3b49, 0x0, 0x3b9d, 0x0, 0x3c18, 0x0, 0x3c4e, 0x0,\n                0x3d33, 0x0, 0x3d96, 0x0, 0x3eac, 0x0, 0x3eb8, 0x0, 0x3f1b,\n                0x0, 0x3ffc, 0x0, 0x4008, 0x0, 0x4018, 0x0, 0x4039, 0x0,\n                0x4046, 0x0, 0x4096, 0x0, 0x40e3, 0x0, 0x412f, 0x0, 0x4202,\n                0x0, 0x4227, 0x0, 0x42a0, 0x0, 0x4301, 0x0, 0x4334, 0x0,\n                0x4359, 0x0, 0x43d5, 0x0, 0x43d9, 0x0, 0x440b, 0x0, 0x446b,\n                0x0, 0x452b, 0x0, 0x455d, 0x0, 0x4561, 0x0, 0x456b, 0x0,\n                0x45d7, 0x0, 0x45f9, 0x0, 0x4635, 0x0, 0x46be, 0x0, 0x46c7,\n                0x0, 0x4995, 0x0, 0x49e6, 0x0, 0x4a6e, 0x0, 0x4a76, 0x0,\n                0x4ab2, 0x0, 0x4b33, 0x0, 0x4bce, 0x0, 0x4cce, 0x0, 0x4ced,\n                0x0, 0x4cf8, 0x0, 0x4d56, 0x0, 0x4e0d, 0x0, 0x4e26, 0x0,\n                0x4e32, 0x0, 0x4e38, 0x0, 0x4e39, 0x0, 0x4e3d, 0x0, 0x4e41,\n                0x0, 0x4e82, 0x0, 0x4e86, 0x0, 0x4eae, 0x0, 0x4ec0, 0x0,\n                0x4ecc, 0x0, 0x4ee4, 0x0, 0x4f60, 0x0, 0x4f80, 0x0, 0x4f86,\n                0x0, 0x4f8b, 0x0, 0x4fae, 0x0, 0x4fbb, 0x0, 0x4fbf, 0x0,\n                0x5002, 0x0, 0x502b, 0x0, 0x507a, 0x0, 0x5099, 0x0, 0x50cf,\n                0x0, 0x50da, 0x0, 0x50e7, 0x0, 0x5140, 0x0, 0x5145, 0x0,\n                0x514d, 0x0, 0x5154, 0x0, 0x5164, 0x0, 0x5167, 0x0, 0x5168,\n                0x0, 0x5169, 0x0, 0x516d, 0x0, 0x5177, 0x0, 0x5180, 0x0,\n                0x518d, 0x0, 0x5192, 0x0, 0x5195, 0x0, 0x5197, 0x0, 0x51a4,\n                0x0, 0x51ac, 0x0, 0x51b5, 0x0, 0x51b7, 0x0, 0x51c9, 0x0,\n                0x51cc, 0x0, 0x51dc, 0x0, 0x51de, 0x0, 0x51f5, 0x0, 0x5203,\n                0x0, 0x5207, 0x0, 0x5217, 0x0, 0x5229, 0x0, 0x523a, 0x0,\n                0x523b, 0x0, 0x5246, 0x0, 0x5272, 0x0, 0x5277, 0x0, 0x5289,\n                0x0, 0x529b, 0x0, 0x52a3, 0x0, 0x52b3, 0x0, 0x52c7, 0x0,\n                0x52c9, 0x0, 0x52d2, 0x0, 0x52de, 0x0, 0x52e4, 0x0, 0x52f5,\n                0x0, 0x52fa, 0x0, 0x5305, 0x0, 0x5306, 0x0, 0x5317, 0x0,\n                0x533f, 0x0, 0x5349, 0x0, 0x5351, 0x0, 0x535a, 0x0, 0x5373,\n                0x0, 0x5375, 0x0, 0x537d, 0x0, 0x537f, 0x0, 0x53c3, 0x0,\n                0x53ca, 0x0, 0x53df, 0x0, 0x53e5, 0x0, 0x53eb, 0x0, 0x53f1,\n                0x0, 0x5406, 0x0, 0x540f, 0x0, 0x541d, 0x0, 0x5438, 0x0,\n                0x5442, 0x0, 0x5448, 0x0, 0x5468, 0x0, 0x549e, 0x0, 0x54a2,\n                0x0, 0x54bd, 0x0, 0x54f6, 0x0, 0x5510, 0x0, 0x5553, 0x0,\n                0x5555, 0x0, 0x5563, 0x0, 0x5584, 0x0, 0x5587, 0x0, 0x5599,\n                0x0, 0x559d, 0x0, 0x55ab, 0x0, 0x55b3, 0x0, 0x55c0, 0x0,\n                0x55c2, 0x0, 0x55e2, 0x0, 0x5606, 0x0, 0x5651, 0x0, 0x5668,\n                0x0, 0x5674, 0x0, 0x56f9, 0x0, 0x5716, 0x0, 0x5717, 0x0,\n                0x578b, 0x0, 0x57ce, 0x0, 0x57f4, 0x0, 0x580d, 0x0, 0x5831,\n                0x0, 0x5832, 0x0, 0x5840, 0x0, 0x585a, 0x0, 0x585e, 0x0,\n                0x58a8, 0x0, 0x58ac, 0x0, 0x58b3, 0x0, 0x58d8, 0x0, 0x58df,\n                0x0, 0x58ee, 0x0, 0x58f2, 0x0, 0x58f7, 0x0, 0x5906, 0x0,\n                0x591a, 0x0, 0x5922, 0x0, 0x5944, 0x0, 0x5948, 0x0, 0x5951,\n                0x0, 0x5954, 0x0, 0x5962, 0x0, 0x5973, 0x0, 0x59d8, 0x0,\n                0x59ec, 0x0, 0x5a1b, 0x0, 0x5a27, 0x0, 0x5a62, 0x0, 0x5a66,\n                0x0, 0x5ab5, 0x0, 0x5b08, 0x0, 0x5b28, 0x0, 0x5b3e, 0x0,\n                0x5b85, 0x0, 0x5bc3, 0x0, 0x5bd8, 0x0, 0x5be7, 0x0, 0x5bee,\n                0x0, 0x5bf3, 0x0, 0x5bff, 0x0, 0x5c06, 0x0, 0x5c22, 0x0,\n                0x5c3f, 0x0, 0x5c60, 0x0, 0x5c62, 0x0, 0x5c64, 0x0, 0x5c65,\n                0x0, 0x5c6e, 0x0, 0x5c8d, 0x0, 0x5cc0, 0x0, 0x5d19, 0x0,\n                0x5d43, 0x0, 0x5d50, 0x0, 0x5d6b, 0x0, 0x5d6e, 0x0, 0x5d7c,\n                0x0, 0x5db2, 0x0, 0x5dba, 0x0, 0x5de1, 0x0, 0x5de2, 0x0,\n                0x5dfd, 0x0, 0x5e28, 0x0, 0x5e3d, 0x0, 0x5e69, 0x0, 0x5e74,\n                0x0, 0x5ea6, 0x0, 0x5eb0, 0x0, 0x5eb3, 0x0, 0x5eb6, 0x0,\n                0x5ec9, 0x0, 0x5eca, 0x0, 0x5ed2, 0x0, 0x5ed3, 0x0, 0x5ed9,\n                0x0, 0x5eec, 0x0, 0x5efe, 0x0, 0x5f04, 0x0, 0x5f22, 0x0,\n                0x5f53, 0x0, 0x5f62, 0x0, 0x5f69, 0x0, 0x5f6b, 0x0, 0x5f8b,\n                0x0, 0x5f9a, 0x0, 0x5fa9, 0x0, 0x5fad, 0x0, 0x5fcd, 0x0,\n                0x5fd7, 0x0, 0x5ff5, 0x0, 0x5ff9, 0x0, 0x6012, 0x0, 0x601c,\n                0x0, 0x6075, 0x0, 0x6081, 0x0, 0x6094, 0x0, 0x60c7, 0x0,\n                0x60d8, 0x0, 0x60e1, 0x0, 0x6108, 0x0, 0x6144, 0x0, 0x6148,\n                0x0, 0x614c, 0x0, 0x614e, 0x0, 0x6160, 0x0, 0x6168, 0x0,\n                0x617a, 0x0, 0x618e, 0x0, 0x6190, 0x0, 0x61a4, 0x0, 0x61af,\n                0x0, 0x61b2, 0x0, 0x61de, 0x0, 0x61f2, 0x0, 0x61f6, 0x0,\n                0x6200, 0x0, 0x6210, 0x0, 0x621b, 0x0, 0x622e, 0x0, 0x6234,\n                0x0, 0x625d, 0x0, 0x62b1, 0x0, 0x62c9, 0x0, 0x62cf, 0x0,\n                0x62d3, 0x0, 0x62d4, 0x0, 0x62fc, 0x0, 0x62fe, 0x0, 0x633d,\n                0x0, 0x6350, 0x0, 0x6368, 0x0, 0x637b, 0x0, 0x6383, 0x0,\n                0x63a0, 0x0, 0x63a9, 0x0, 0x63c4, 0x0, 0x63c5, 0x0, 0x63e4,\n                0x0, 0x641c, 0x0, 0x6422, 0x0, 0x6452, 0x0, 0x6469, 0x0,\n                0x6477, 0x0, 0x647e, 0x0, 0x649a, 0x0, 0x649d, 0x0, 0x64c4,\n                0x0, 0x654f, 0x0, 0x6556, 0x0, 0x656c, 0x0, 0x6578, 0x0,\n                0x6599, 0x0, 0x65c5, 0x0, 0x65e2, 0x0, 0x65e3, 0x0, 0x6613,\n                0x0, 0x6649, 0x0, 0x6674, 0x0, 0x6688, 0x0, 0x6691, 0x0,\n                0x669c, 0x0, 0x66b4, 0x0, 0x66c6, 0x0, 0x66f4, 0x0, 0x66f8,\n                0x0, 0x6700, 0x0, 0x6717, 0x0, 0x671b, 0x0, 0x6721, 0x0,\n                0x674e, 0x0, 0x6753, 0x0, 0x6756, 0x0, 0x675e, 0x0, 0x677b,\n                0x0, 0x6785, 0x0, 0x6797, 0x0, 0x67f3, 0x0, 0x67fa, 0x0,\n                0x6817, 0x0, 0x681f, 0x0, 0x6852, 0x0, 0x6881, 0x0, 0x6885,\n                0x0, 0x688e, 0x0, 0x68a8, 0x0, 0x6914, 0x0, 0x6942, 0x0,\n                0x69a3, 0x0, 0x69ea, 0x0, 0x6a02, 0x0, 0x6a13, 0x0, 0x6aa8,\n                0x0, 0x6ad3, 0x0, 0x6adb, 0x0, 0x6b04, 0x0, 0x6b21, 0x0,\n                0x6b54, 0x0, 0x6b72, 0x0, 0x6b77, 0x0, 0x6b79, 0x0, 0x6b9f,\n                0x0, 0x6bae, 0x0, 0x6bba, 0x0, 0x6bbb, 0x0, 0x6c4e, 0x0,\n                0x6c67, 0x0, 0x6c88, 0x0, 0x6cbf, 0x0, 0x6ccc, 0x0, 0x6ccd,\n                0x0, 0x6ce5, 0x0, 0x6d16, 0x0, 0x6d1b, 0x0, 0x6d1e, 0x0,\n                0x6d34, 0x0, 0x6d3e, 0x0, 0x6d41, 0x0, 0x6d69, 0x0, 0x6d6a,\n                0x0, 0x6d77, 0x0, 0x6d78, 0x0, 0x6d85, 0x0, 0x6dcb, 0x0,\n                0x6dda, 0x0, 0x6dea, 0x0, 0x6df9, 0x0, 0x6e1a, 0x0, 0x6e2f,\n                0x0, 0x6e6e, 0x0, 0x6e9c, 0x0, 0x6eba, 0x0, 0x6ec7, 0x0,\n                0x6ecb, 0x0, 0x6ed1, 0x0, 0x6edb, 0x0, 0x6f0f, 0x0, 0x6f22,\n                0x0, 0x6f23, 0x0, 0x6f6e, 0x0, 0x6fc6, 0x0, 0x6feb, 0x0,\n                0x6ffe, 0x0, 0x701b, 0x0, 0x701e, 0x0, 0x7039, 0x0, 0x704a,\n                0x0, 0x7070, 0x0, 0x7077, 0x0, 0x707d, 0x0, 0x7099, 0x0,\n                0x70ad, 0x0, 0x70c8, 0x0, 0x70d9, 0x0, 0x7145, 0x0, 0x7149,\n                0x0, 0x716e, 0x0, 0x719c, 0x0, 0x71ce, 0x0, 0x71d0, 0x0,\n                0x7210, 0x0, 0x721b, 0x0, 0x7228, 0x0, 0x722b, 0x0, 0x7235,\n                0x0, 0x7250, 0x0, 0x7262, 0x0, 0x7280, 0x0, 0x7295, 0x0,\n                0x72af, 0x0, 0x72c0, 0x0, 0x72fc, 0x0, 0x732a, 0x0, 0x7375,\n                0x0, 0x737a, 0x0, 0x7387, 0x0, 0x738b, 0x0, 0x73a5, 0x0,\n                0x73b2, 0x0, 0x73de, 0x0, 0x7406, 0x0, 0x7409, 0x0, 0x7422,\n                0x0, 0x7447, 0x0, 0x745c, 0x0, 0x7469, 0x0, 0x7471, 0x0,\n                0x7485, 0x0, 0x7489, 0x0, 0x7498, 0x0, 0x74ca, 0x0, 0x7506,\n                0x0, 0x7524, 0x0, 0x753b, 0x0, 0x753e, 0x0, 0x7559, 0x0,\n                0x7565, 0x0, 0x7570, 0x0, 0x75e2, 0x0, 0x7610, 0x0, 0x761d,\n                0x0, 0x761f, 0x0, 0x7642, 0x0, 0x7669, 0x0, 0x76ca, 0x0,\n                0x76db, 0x0, 0x76e7, 0x0, 0x76f4, 0x0, 0x7701, 0x0, 0x771e,\n                0x0, 0x771f, 0x0, 0x7740, 0x0, 0x774a, 0x0, 0x778b, 0x0,\n                0x77a7, 0x0, 0x784e, 0x0, 0x786b, 0x0, 0x788c, 0x0, 0x7891,\n                0x0, 0x78ca, 0x0, 0x78cc, 0x0, 0x78fb, 0x0, 0x792a, 0x0,\n                0x793c, 0x0, 0x793e, 0x0, 0x7948, 0x0, 0x7949, 0x0, 0x7950,\n                0x0, 0x7956, 0x0, 0x795d, 0x0, 0x795e, 0x0, 0x7965, 0x0,\n                0x797f, 0x0, 0x798d, 0x0, 0x798e, 0x0, 0x798f, 0x0, 0x79ae,\n                0x0, 0x79ca, 0x0, 0x79eb, 0x0, 0x7a1c, 0x0, 0x7a40, 0x0,\n                0x7a4a, 0x0, 0x7a4f, 0x0, 0x7a81, 0x0, 0x7ab1, 0x0, 0x7acb,\n                0x0, 0x7aee, 0x0, 0x7b20, 0x0, 0x7bc0, 0x0, 0x7bc6, 0x0,\n                0x7bc9, 0x0, 0x7c3e, 0x0, 0x7c60, 0x0, 0x7c7b, 0x0, 0x7c92,\n                0x0, 0x7cbe, 0x0, 0x7cd2, 0x0, 0x7cd6, 0x0, 0x7ce3, 0x0,\n                0x7ce7, 0x0, 0x7ce8, 0x0, 0x7d00, 0x0, 0x7d10, 0x0, 0x7d22,\n                0x0, 0x7d2f, 0x0, 0x7d5b, 0x0, 0x7d63, 0x0, 0x7da0, 0x0,\n                0x7dbe, 0x0, 0x7dc7, 0x0, 0x7df4, 0x0, 0x7e02, 0x0, 0x7e09,\n                0x0, 0x7e37, 0x0, 0x7e41, 0x0, 0x7e45, 0x0, 0x7f3e, 0x0,\n                0x7f72, 0x0, 0x7f79, 0x0, 0x7f7a, 0x0, 0x7f85, 0x0, 0x7f95,\n                0x0, 0x7f9a, 0x0, 0x7fbd, 0x0, 0x7ffa, 0x0, 0x8001, 0x0,\n                0x8005, 0x0, 0x8046, 0x0, 0x8060, 0x0, 0x806f, 0x0, 0x8070,\n                0x0, 0x807e, 0x0, 0x808b, 0x0, 0x80ad, 0x0, 0x80b2, 0x0,\n                0x8103, 0x0, 0x813e, 0x0, 0x81d8, 0x0, 0x81e8, 0x0, 0x81ed,\n                0x0, 0x8201, 0x0, 0x8204, 0x0, 0x8218, 0x0, 0x826f, 0x0,\n                0x8279, 0x0, 0x828b, 0x0, 0x8291, 0x0, 0x829d, 0x0, 0x82b1,\n                0x0, 0x82b3, 0x0, 0x82bd, 0x0, 0x82e5, 0x0, 0x82e6, 0x0,\n                0x831d, 0x0, 0x8323, 0x0, 0x8336, 0x0, 0x8352, 0x0, 0x8353,\n                0x0, 0x8363, 0x0, 0x83ad, 0x0, 0x83bd, 0x0, 0x83c9, 0x0,\n                0x83ca, 0x0, 0x83cc, 0x0, 0x83dc, 0x0, 0x83e7, 0x0, 0x83ef,\n                0x0, 0x83f1, 0x0, 0x843d, 0x0, 0x8449, 0x0, 0x8457, 0x0,\n                0x84ee, 0x0, 0x84f1, 0x0, 0x84f3, 0x0, 0x84fc, 0x0, 0x8516,\n                0x0, 0x8564, 0x0, 0x85cd, 0x0, 0x85fa, 0x0, 0x8606, 0x0,\n                0x8612, 0x0, 0x862d, 0x0, 0x863f, 0x0, 0x8650, 0x0, 0x865c,\n                0x0, 0x8667, 0x0, 0x8669, 0x0, 0x8688, 0x0, 0x86a9, 0x0,\n                0x86e2, 0x0, 0x870e, 0x0, 0x8728, 0x0, 0x876b, 0x0, 0x8779,\n                0x0, 0x8786, 0x0, 0x87ba, 0x0, 0x87e1, 0x0, 0x8801, 0x0,\n                0x881f, 0x0, 0x884c, 0x0, 0x8860, 0x0, 0x8863, 0x0, 0x88c2,\n                0x0, 0x88cf, 0x0, 0x88d7, 0x0, 0x88de, 0x0, 0x88e1, 0x0,\n                0x88f8, 0x0, 0x88fa, 0x0, 0x8910, 0x0, 0x8941, 0x0, 0x8964,\n                0x0, 0x8986, 0x0, 0x898b, 0x0, 0x8996, 0x0, 0x8aa0, 0x0,\n                0x8aaa, 0x0, 0x8abf, 0x0, 0x8acb, 0x0, 0x8ad2, 0x0, 0x8ad6,\n                0x0, 0x8aed, 0x0, 0x8af8, 0x0, 0x8afe, 0x0, 0x8b01, 0x0,\n                0x8b39, 0x0, 0x8b58, 0x0, 0x8b80, 0x0, 0x8b8a, 0x0, 0x8c48,\n                0x0, 0x8c55, 0x0, 0x8cab, 0x0, 0x8cc1, 0x0, 0x8cc2, 0x0,\n                0x8cc8, 0x0, 0x8cd3, 0x0, 0x8d08, 0x0, 0x8d1b, 0x0, 0x8d77,\n                0x0, 0x8dbc, 0x0, 0x8dcb, 0x0, 0x8def, 0x0, 0x8df0, 0x0,\n                0x8eca, 0x0, 0x8ed4, 0x0, 0x8f26, 0x0, 0x8f2a, 0x0, 0x8f38,\n                0x0, 0x8f3b, 0x0, 0x8f62, 0x0, 0x8f9e, 0x0, 0x8fb0, 0x0,\n                0x8fb6, 0x0, 0x9023, 0x0, 0x9038, 0x0, 0x9072, 0x0, 0x907c,\n                0x0, 0x908f, 0x0, 0x9094, 0x0, 0x90ce, 0x0, 0x90de, 0x0,\n                0x90f1, 0x0, 0x90fd, 0x0, 0x9111, 0x0, 0x911b, 0x0, 0x916a,\n                0x0, 0x9199, 0x0, 0x91b4, 0x0, 0x91cc, 0x0, 0x91cf, 0x0,\n                0x91d1, 0x0, 0x9234, 0x0, 0x9238, 0x0, 0x9276, 0x0, 0x927c,\n                0x0, 0x92d7, 0x0, 0x92d8, 0x0, 0x9304, 0x0, 0x934a, 0x0,\n                0x93f9, 0x0, 0x9415, 0x0, 0x958b, 0x0, 0x95ad, 0x0, 0x95b7,\n                0x0, 0x962e, 0x0, 0x964b, 0x0, 0x964d, 0x0, 0x9675, 0x0,\n                0x9678, 0x0, 0x967c, 0x0, 0x9686, 0x0, 0x96a3, 0x0, 0x96b7,\n                0x0, 0x96b8, 0x0, 0x96c3, 0x0, 0x96e2, 0x0, 0x96e3, 0x0,\n                0x96f6, 0x0, 0x96f7, 0x0, 0x9723, 0x0, 0x9732, 0x0, 0x9748,\n                0x0, 0x9756, 0x0, 0x97db, 0x0, 0x97e0, 0x0, 0x97ff, 0x0,\n                0x980b, 0x0, 0x9818, 0x0, 0x9829, 0x0, 0x983b, 0x0, 0x985e,\n                0x0, 0x98e2, 0x0, 0x98ef, 0x0, 0x98fc, 0x0, 0x9928, 0x0,\n                0x9929, 0x0, 0x99a7, 0x0, 0x99c2, 0x0, 0x99f1, 0x0, 0x99fe,\n                0x0, 0x9a6a, 0x0, 0x9b12, 0x0, 0x9b6f, 0x0, 0x9c40, 0x0,\n                0x9c57, 0x0, 0x9cfd, 0x0, 0x9d67, 0x0, 0x9db4, 0x0, 0x9dfa,\n                0x0, 0x9e1e, 0x0, 0x9e7f, 0x0, 0x9e97, 0x0, 0x9e9f, 0x0,\n                0x9ebb, 0x0, 0x9ece, 0x0, 0x9ef9, 0x0, 0x9efe, 0x0, 0x9f05,\n                0x0, 0x9f0f, 0x0, 0x9f16, 0x0, 0x9f3b, 0x0, 0x9f43, 0x0,\n                0x9f8d, 0x0, 0x9f8e, 0x0, 0x9f9c, 0x0, 0x11099, 0x110ba, 0x0,\n                0x1109b, 0x110ba, 0x0, 0x110a5, 0x110ba, 0x0, 0x11131, 0x11127,\n                0x0, 0x11132, 0x11127, 0x0, 0x1d157, 0x1d165, 0x0, 0x1d158,\n                0x1d165, 0x0, 0x1d158, 0x1d165, 0x1d16e, 0x0, 0x1d158, 0x1d165,\n                0x1d16f, 0x0, 0x1d158, 0x1d165, 0x1d170, 0x0, 0x1d158, 0x1d165,\n                0x1d171, 0x0, 0x1d158, 0x1d165, 0x1d172, 0x0, 0x1d1b9, 0x1d165,\n                0x0, 0x1d1b9, 0x1d165, 0x1d16e, 0x0, 0x1d1b9, 0x1d165, 0x1d16f,\n                0x0, 0x1d1ba, 0x1d165, 0x0, 0x1d1ba, 0x1d165, 0x1d16e, 0x0,\n                0x1d1ba, 0x1d165, 0x1d16f, 0x0, 0x20122, 0x0, 0x2051c, 0x0,\n                0x20525, 0x0, 0x2054b, 0x0, 0x2063a, 0x0, 0x20804, 0x0,\n                0x208de, 0x0, 0x20a2c, 0x0, 0x20b63, 0x0, 0x214e4, 0x0,\n                0x216a8, 0x0, 0x216ea, 0x0, 0x219c8, 0x0, 0x21b18, 0x0,\n                0x21d0b, 0x0, 0x21de4, 0x0, 0x21de6, 0x0, 0x22183, 0x0,\n                0x2219f, 0x0, 0x22331, 0x0, 0x226d4, 0x0, 0x22844, 0x0,\n                0x2284a, 0x0, 0x22b0c, 0x0, 0x22bf1, 0x0, 0x2300a, 0x0,\n                0x232b8, 0x0, 0x2335f, 0x0, 0x23393, 0x0, 0x2339c, 0x0,\n                0x233c3, 0x0, 0x233d5, 0x0, 0x2346d, 0x0, 0x236a3, 0x0,\n                0x238a7, 0x0, 0x23a8d, 0x0, 0x23afa, 0x0, 0x23cbc, 0x0,\n                0x23d1e, 0x0, 0x23ed1, 0x0, 0x23f5e, 0x0, 0x23f8e, 0x0,\n                0x24263, 0x0, 0x242ee, 0x0, 0x243ab, 0x0, 0x24608, 0x0,\n                0x24735, 0x0, 0x24814, 0x0, 0x24c36, 0x0, 0x24c92, 0x0,\n                0x24fa1, 0x0, 0x24fb8, 0x0, 0x25044, 0x0, 0x250f2, 0x0,\n                0x250f3, 0x0, 0x25119, 0x0, 0x25133, 0x0, 0x25249, 0x0,\n                0x2541d, 0x0, 0x25626, 0x0, 0x2569a, 0x0, 0x256c5, 0x0,\n                0x2597c, 0x0, 0x25aa7, 0x0, 0x25bab, 0x0, 0x25c80, 0x0,\n                0x25cd0, 0x0, 0x25f86, 0x0, 0x261da, 0x0, 0x26228, 0x0,\n                0x26247, 0x0, 0x262d9, 0x0, 0x2633e, 0x0, 0x264da, 0x0,\n                0x26523, 0x0, 0x265a8, 0x0, 0x267a7, 0x0, 0x267b5, 0x0,\n                0x26b3c, 0x0, 0x26c36, 0x0, 0x26cd5, 0x0, 0x26d6b, 0x0,\n                0x26f2c, 0x0, 0x26fb1, 0x0, 0x270d2, 0x0, 0x273ca, 0x0,\n                0x27667, 0x0, 0x278ae, 0x0, 0x27966, 0x0, 0x27ca8, 0x0,\n                0x27ed3, 0x0, 0x27f2f, 0x0, 0x285d2, 0x0, 0x285ed, 0x0,\n                0x2872e, 0x0, 0x28bfa, 0x0, 0x28d77, 0x0, 0x29145, 0x0,\n                0x291df, 0x0, 0x2921a, 0x0, 0x2940a, 0x0, 0x29496, 0x0,\n                0x295b6, 0x0, 0x29b30, 0x0, 0x2a0ce, 0x0, 0x2a105, 0x0,\n                0x2a20e, 0x0, 0x2a291, 0x0, 0x2a392, 0x0, 0x2a600, 0x0\n            ];\n            return t;\n        }\n\n        _IDCA decompCompatTable()\n        {\n            static _IDCA t = [\n                0x0, 0x20, 0x0, 0x20, 0x301, 0x0, 0x20, 0x303, 0x0, 0x20,\n                0x304, 0x0, 0x20, 0x305, 0x0, 0x20, 0x306, 0x0, 0x20, 0x307,\n                0x0, 0x20, 0x308, 0x0, 0x20, 0x308, 0x300, 0x0, 0x20, 0x308,\n                0x301, 0x0, 0x20, 0x308, 0x342, 0x0, 0x20, 0x30a, 0x0, 0x20,\n                0x30b, 0x0, 0x20, 0x313, 0x0, 0x20, 0x313, 0x300, 0x0, 0x20,\n                0x313, 0x301, 0x0, 0x20, 0x313, 0x342, 0x0, 0x20, 0x314, 0x0,\n                0x20, 0x314, 0x300, 0x0, 0x20, 0x314, 0x301, 0x0, 0x20, 0x314,\n                0x342, 0x0, 0x20, 0x327, 0x0, 0x20, 0x328, 0x0, 0x20, 0x333,\n                0x0, 0x20, 0x342, 0x0, 0x20, 0x345, 0x0, 0x20, 0x64b, 0x0,\n                0x20, 0x64c, 0x0, 0x20, 0x64c, 0x651, 0x0, 0x20, 0x64d, 0x0,\n                0x20, 0x64d, 0x651, 0x0, 0x20, 0x64e, 0x0, 0x20, 0x64e, 0x651,\n                0x0, 0x20, 0x64f, 0x0, 0x20, 0x64f, 0x651, 0x0, 0x20, 0x650,\n                0x0, 0x20, 0x650, 0x651, 0x0, 0x20, 0x651, 0x0, 0x20, 0x651,\n                0x670, 0x0, 0x20, 0x652, 0x0, 0x20, 0x3099, 0x0, 0x20, 0x309a,\n                0x0, 0x21, 0x0, 0x21, 0x21, 0x0, 0x21, 0x3f, 0x0, 0x22, 0x0,\n                0x23, 0x0, 0x24, 0x0, 0x25, 0x0, 0x26, 0x0, 0x27, 0x0, 0x28,\n                0x0, 0x28, 0x31, 0x29, 0x0, 0x28, 0x31, 0x30, 0x29, 0x0, 0x28,\n                0x31, 0x31, 0x29, 0x0, 0x28, 0x31, 0x32, 0x29, 0x0, 0x28, 0x31,\n                0x33, 0x29, 0x0, 0x28, 0x31, 0x34, 0x29, 0x0, 0x28, 0x31, 0x35,\n                0x29, 0x0, 0x28, 0x31, 0x36, 0x29, 0x0, 0x28, 0x31, 0x37, 0x29,\n                0x0, 0x28, 0x31, 0x38, 0x29, 0x0, 0x28, 0x31, 0x39, 0x29, 0x0,\n                0x28, 0x32, 0x29, 0x0, 0x28, 0x32, 0x30, 0x29, 0x0, 0x28, 0x33,\n                0x29, 0x0, 0x28, 0x34, 0x29, 0x0, 0x28, 0x35, 0x29, 0x0, 0x28,\n                0x36, 0x29, 0x0, 0x28, 0x37, 0x29, 0x0, 0x28, 0x38, 0x29, 0x0,\n                0x28, 0x39, 0x29, 0x0, 0x28, 0x41, 0x29, 0x0, 0x28, 0x42, 0x29,\n                0x0, 0x28, 0x43, 0x29, 0x0, 0x28, 0x44, 0x29, 0x0, 0x28, 0x45,\n                0x29, 0x0, 0x28, 0x46, 0x29, 0x0, 0x28, 0x47, 0x29, 0x0, 0x28,\n                0x48, 0x29, 0x0, 0x28, 0x49, 0x29, 0x0, 0x28, 0x4a, 0x29, 0x0,\n                0x28, 0x4b, 0x29, 0x0, 0x28, 0x4c, 0x29, 0x0, 0x28, 0x4d, 0x29,\n                0x0, 0x28, 0x4e, 0x29, 0x0, 0x28, 0x4f, 0x29, 0x0, 0x28, 0x50,\n                0x29, 0x0, 0x28, 0x51, 0x29, 0x0, 0x28, 0x52, 0x29, 0x0, 0x28,\n                0x53, 0x29, 0x0, 0x28, 0x54, 0x29, 0x0, 0x28, 0x55, 0x29, 0x0,\n                0x28, 0x56, 0x29, 0x0, 0x28, 0x57, 0x29, 0x0, 0x28, 0x58, 0x29,\n                0x0, 0x28, 0x59, 0x29, 0x0, 0x28, 0x5a, 0x29, 0x0, 0x28, 0x61,\n                0x29, 0x0, 0x28, 0x62, 0x29, 0x0, 0x28, 0x63, 0x29, 0x0, 0x28,\n                0x64, 0x29, 0x0, 0x28, 0x65, 0x29, 0x0, 0x28, 0x66, 0x29, 0x0,\n                0x28, 0x67, 0x29, 0x0, 0x28, 0x68, 0x29, 0x0, 0x28, 0x69, 0x29,\n                0x0, 0x28, 0x6a, 0x29, 0x0, 0x28, 0x6b, 0x29, 0x0, 0x28, 0x6c,\n                0x29, 0x0, 0x28, 0x6d, 0x29, 0x0, 0x28, 0x6e, 0x29, 0x0, 0x28,\n                0x6f, 0x29, 0x0, 0x28, 0x70, 0x29, 0x0, 0x28, 0x71, 0x29, 0x0,\n                0x28, 0x72, 0x29, 0x0, 0x28, 0x73, 0x29, 0x0, 0x28, 0x74, 0x29,\n                0x0, 0x28, 0x75, 0x29, 0x0, 0x28, 0x76, 0x29, 0x0, 0x28, 0x77,\n                0x29, 0x0, 0x28, 0x78, 0x29, 0x0, 0x28, 0x79, 0x29, 0x0, 0x28,\n                0x7a, 0x29, 0x0, 0x28, 0x1100, 0x29, 0x0, 0x28, 0x1100, 0x1161,\n                0x29, 0x0, 0x28, 0x1102, 0x29, 0x0, 0x28, 0x1102, 0x1161, 0x29,\n                0x0, 0x28, 0x1103, 0x29, 0x0, 0x28, 0x1103, 0x1161, 0x29, 0x0,\n                0x28, 0x1105, 0x29, 0x0, 0x28, 0x1105, 0x1161, 0x29, 0x0, 0x28,\n                0x1106, 0x29, 0x0, 0x28, 0x1106, 0x1161, 0x29, 0x0, 0x28,\n                0x1107, 0x29, 0x0, 0x28, 0x1107, 0x1161, 0x29, 0x0, 0x28,\n                0x1109, 0x29, 0x0, 0x28, 0x1109, 0x1161, 0x29, 0x0, 0x28,\n                0x110b, 0x29, 0x0, 0x28, 0x110b, 0x1161, 0x29, 0x0, 0x28,\n                0x110b, 0x1169, 0x110c, 0x1165, 0x11ab, 0x29, 0x0, 0x28,\n                0x110b, 0x1169, 0x1112, 0x116e, 0x29, 0x0, 0x28, 0x110c, 0x29,\n                0x0, 0x28, 0x110c, 0x1161, 0x29, 0x0, 0x28, 0x110c, 0x116e,\n                0x29, 0x0, 0x28, 0x110e, 0x29, 0x0, 0x28, 0x110e, 0x1161, 0x29,\n                0x0, 0x28, 0x110f, 0x29, 0x0, 0x28, 0x110f, 0x1161, 0x29, 0x0,\n                0x28, 0x1110, 0x29, 0x0, 0x28, 0x1110, 0x1161, 0x29, 0x0, 0x28,\n                0x1111, 0x29, 0x0, 0x28, 0x1111, 0x1161, 0x29, 0x0, 0x28,\n                0x1112, 0x29, 0x0, 0x28, 0x1112, 0x1161, 0x29, 0x0, 0x28,\n                0x4e00, 0x29, 0x0, 0x28, 0x4e03, 0x29, 0x0, 0x28, 0x4e09, 0x29,\n                0x0, 0x28, 0x4e5d, 0x29, 0x0, 0x28, 0x4e8c, 0x29, 0x0, 0x28,\n                0x4e94, 0x29, 0x0, 0x28, 0x4ee3, 0x29, 0x0, 0x28, 0x4f01, 0x29,\n                0x0, 0x28, 0x4f11, 0x29, 0x0, 0x28, 0x516b, 0x29, 0x0, 0x28,\n                0x516d, 0x29, 0x0, 0x28, 0x52b4, 0x29, 0x0, 0x28, 0x5341, 0x29,\n                0x0, 0x28, 0x5354, 0x29, 0x0, 0x28, 0x540d, 0x29, 0x0, 0x28,\n                0x547c, 0x29, 0x0, 0x28, 0x56db, 0x29, 0x0, 0x28, 0x571f, 0x29,\n                0x0, 0x28, 0x5b66, 0x29, 0x0, 0x28, 0x65e5, 0x29, 0x0, 0x28,\n                0x6708, 0x29, 0x0, 0x28, 0x6709, 0x29, 0x0, 0x28, 0x6728, 0x29,\n                0x0, 0x28, 0x682a, 0x29, 0x0, 0x28, 0x6c34, 0x29, 0x0, 0x28,\n                0x706b, 0x29, 0x0, 0x28, 0x7279, 0x29, 0x0, 0x28, 0x76e3, 0x29,\n                0x0, 0x28, 0x793e, 0x29, 0x0, 0x28, 0x795d, 0x29, 0x0, 0x28,\n                0x796d, 0x29, 0x0, 0x28, 0x81ea, 0x29, 0x0, 0x28, 0x81f3, 0x29,\n                0x0, 0x28, 0x8ca1, 0x29, 0x0, 0x28, 0x8cc7, 0x29, 0x0, 0x28,\n                0x91d1, 0x29, 0x0, 0x29, 0x0, 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0,\n                0x2d, 0x0, 0x2e, 0x0, 0x2e, 0x2e, 0x0, 0x2e, 0x2e, 0x2e, 0x0,\n                0x2f, 0x0, 0x30, 0x0, 0x30, 0x2c, 0x0, 0x30, 0x2e, 0x0, 0x30,\n                0x2044, 0x33, 0x0, 0x30, 0x70b9, 0x0, 0x31, 0x0, 0x31, 0x2c,\n                0x0, 0x31, 0x2e, 0x0, 0x31, 0x30, 0x0, 0x31, 0x30, 0x2e, 0x0,\n                0x31, 0x30, 0x65e5, 0x0, 0x31, 0x30, 0x6708, 0x0, 0x31, 0x30,\n                0x70b9, 0x0, 0x31, 0x31, 0x0, 0x31, 0x31, 0x2e, 0x0, 0x31,\n                0x31, 0x65e5, 0x0, 0x31, 0x31, 0x6708, 0x0, 0x31, 0x31, 0x70b9,\n                0x0, 0x31, 0x32, 0x0, 0x31, 0x32, 0x2e, 0x0, 0x31, 0x32,\n                0x65e5, 0x0, 0x31, 0x32, 0x6708, 0x0, 0x31, 0x32, 0x70b9, 0x0,\n                0x31, 0x33, 0x0, 0x31, 0x33, 0x2e, 0x0, 0x31, 0x33, 0x65e5,\n                0x0, 0x31, 0x33, 0x70b9, 0x0, 0x31, 0x34, 0x0, 0x31, 0x34,\n                0x2e, 0x0, 0x31, 0x34, 0x65e5, 0x0, 0x31, 0x34, 0x70b9, 0x0,\n                0x31, 0x35, 0x0, 0x31, 0x35, 0x2e, 0x0, 0x31, 0x35, 0x65e5,\n                0x0, 0x31, 0x35, 0x70b9, 0x0, 0x31, 0x36, 0x0, 0x31, 0x36,\n                0x2e, 0x0, 0x31, 0x36, 0x65e5, 0x0, 0x31, 0x36, 0x70b9, 0x0,\n                0x31, 0x37, 0x0, 0x31, 0x37, 0x2e, 0x0, 0x31, 0x37, 0x65e5,\n                0x0, 0x31, 0x37, 0x70b9, 0x0, 0x31, 0x38, 0x0, 0x31, 0x38,\n                0x2e, 0x0, 0x31, 0x38, 0x65e5, 0x0, 0x31, 0x38, 0x70b9, 0x0,\n                0x31, 0x39, 0x0, 0x31, 0x39, 0x2e, 0x0, 0x31, 0x39, 0x65e5,\n                0x0, 0x31, 0x39, 0x70b9, 0x0, 0x31, 0x2044, 0x0, 0x31, 0x2044,\n                0x31, 0x30, 0x0, 0x31, 0x2044, 0x32, 0x0, 0x31, 0x2044, 0x33,\n                0x0, 0x31, 0x2044, 0x34, 0x0, 0x31, 0x2044, 0x35, 0x0, 0x31,\n                0x2044, 0x36, 0x0, 0x31, 0x2044, 0x37, 0x0, 0x31, 0x2044, 0x38,\n                0x0, 0x31, 0x2044, 0x39, 0x0, 0x31, 0x65e5, 0x0, 0x31, 0x6708,\n                0x0, 0x31, 0x70b9, 0x0, 0x32, 0x0, 0x32, 0x2c, 0x0, 0x32, 0x2e,\n                0x0, 0x32, 0x30, 0x0, 0x32, 0x30, 0x2e, 0x0, 0x32, 0x30,\n                0x65e5, 0x0, 0x32, 0x30, 0x70b9, 0x0, 0x32, 0x31, 0x0, 0x32,\n                0x31, 0x65e5, 0x0, 0x32, 0x31, 0x70b9, 0x0, 0x32, 0x32, 0x0,\n                0x32, 0x32, 0x65e5, 0x0, 0x32, 0x32, 0x70b9, 0x0, 0x32, 0x33,\n                0x0, 0x32, 0x33, 0x65e5, 0x0, 0x32, 0x33, 0x70b9, 0x0, 0x32,\n                0x34, 0x0, 0x32, 0x34, 0x65e5, 0x0, 0x32, 0x34, 0x70b9, 0x0,\n                0x32, 0x35, 0x0, 0x32, 0x35, 0x65e5, 0x0, 0x32, 0x36, 0x0,\n                0x32, 0x36, 0x65e5, 0x0, 0x32, 0x37, 0x0, 0x32, 0x37, 0x65e5,\n                0x0, 0x32, 0x38, 0x0, 0x32, 0x38, 0x65e5, 0x0, 0x32, 0x39, 0x0,\n                0x32, 0x39, 0x65e5, 0x0, 0x32, 0x2044, 0x33, 0x0, 0x32, 0x2044,\n                0x35, 0x0, 0x32, 0x65e5, 0x0, 0x32, 0x6708, 0x0, 0x32, 0x70b9,\n                0x0, 0x33, 0x0, 0x33, 0x2c, 0x0, 0x33, 0x2e, 0x0, 0x33, 0x30,\n                0x0, 0x33, 0x30, 0x65e5, 0x0, 0x33, 0x31, 0x0, 0x33, 0x31,\n                0x65e5, 0x0, 0x33, 0x32, 0x0, 0x33, 0x33, 0x0, 0x33, 0x34, 0x0,\n                0x33, 0x35, 0x0, 0x33, 0x36, 0x0, 0x33, 0x37, 0x0, 0x33, 0x38,\n                0x0, 0x33, 0x39, 0x0, 0x33, 0x2044, 0x34, 0x0, 0x33, 0x2044,\n                0x35, 0x0, 0x33, 0x2044, 0x38, 0x0, 0x33, 0x65e5, 0x0, 0x33,\n                0x6708, 0x0, 0x33, 0x70b9, 0x0, 0x34, 0x0, 0x34, 0x2c, 0x0,\n                0x34, 0x2e, 0x0, 0x34, 0x30, 0x0, 0x34, 0x31, 0x0, 0x34, 0x32,\n                0x0, 0x34, 0x33, 0x0, 0x34, 0x34, 0x0, 0x34, 0x35, 0x0, 0x34,\n                0x36, 0x0, 0x34, 0x37, 0x0, 0x34, 0x38, 0x0, 0x34, 0x39, 0x0,\n                0x34, 0x2044, 0x35, 0x0, 0x34, 0x65e5, 0x0, 0x34, 0x6708, 0x0,\n                0x34, 0x70b9, 0x0, 0x35, 0x0, 0x35, 0x2c, 0x0, 0x35, 0x2e, 0x0,\n                0x35, 0x30, 0x0, 0x35, 0x2044, 0x36, 0x0, 0x35, 0x2044, 0x38,\n                0x0, 0x35, 0x65e5, 0x0, 0x35, 0x6708, 0x0, 0x35, 0x70b9, 0x0,\n                0x36, 0x0, 0x36, 0x2c, 0x0, 0x36, 0x2e, 0x0, 0x36, 0x65e5, 0x0,\n                0x36, 0x6708, 0x0, 0x36, 0x70b9, 0x0, 0x37, 0x0, 0x37, 0x2c,\n                0x0, 0x37, 0x2e, 0x0, 0x37, 0x2044, 0x38, 0x0, 0x37, 0x65e5,\n                0x0, 0x37, 0x6708, 0x0, 0x37, 0x70b9, 0x0, 0x38, 0x0, 0x38,\n                0x2c, 0x0, 0x38, 0x2e, 0x0, 0x38, 0x65e5, 0x0, 0x38, 0x6708,\n                0x0, 0x38, 0x70b9, 0x0, 0x39, 0x0, 0x39, 0x2c, 0x0, 0x39, 0x2e,\n                0x0, 0x39, 0x65e5, 0x0, 0x39, 0x6708, 0x0, 0x39, 0x70b9, 0x0,\n                0x3a, 0x0, 0x3a, 0x3a, 0x3d, 0x0, 0x3b, 0x0, 0x3c, 0x0, 0x3c,\n                0x338, 0x0, 0x3d, 0x0, 0x3d, 0x3d, 0x0, 0x3d, 0x3d, 0x3d, 0x0,\n                0x3d, 0x338, 0x0, 0x3e, 0x0, 0x3e, 0x338, 0x0, 0x3f, 0x0, 0x3f,\n                0x21, 0x0, 0x3f, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0, 0x41, 0x55,\n                0x0, 0x41, 0x300, 0x0, 0x41, 0x301, 0x0, 0x41, 0x302, 0x0,\n                0x41, 0x302, 0x300, 0x0, 0x41, 0x302, 0x301, 0x0, 0x41, 0x302,\n                0x303, 0x0, 0x41, 0x302, 0x309, 0x0, 0x41, 0x303, 0x0, 0x41,\n                0x304, 0x0, 0x41, 0x306, 0x0, 0x41, 0x306, 0x300, 0x0, 0x41,\n                0x306, 0x301, 0x0, 0x41, 0x306, 0x303, 0x0, 0x41, 0x306, 0x309,\n                0x0, 0x41, 0x307, 0x0, 0x41, 0x307, 0x304, 0x0, 0x41, 0x308,\n                0x0, 0x41, 0x308, 0x304, 0x0, 0x41, 0x309, 0x0, 0x41, 0x30a,\n                0x0, 0x41, 0x30a, 0x301, 0x0, 0x41, 0x30c, 0x0, 0x41, 0x30f,\n                0x0, 0x41, 0x311, 0x0, 0x41, 0x323, 0x0, 0x41, 0x323, 0x302,\n                0x0, 0x41, 0x323, 0x306, 0x0, 0x41, 0x325, 0x0, 0x41, 0x328,\n                0x0, 0x41, 0x2215, 0x6d, 0x0, 0x42, 0x0, 0x42, 0x71, 0x0, 0x42,\n                0x307, 0x0, 0x42, 0x323, 0x0, 0x42, 0x331, 0x0, 0x43, 0x0,\n                0x43, 0x44, 0x0, 0x43, 0x6f, 0x2e, 0x0, 0x43, 0x301, 0x0, 0x43,\n                0x302, 0x0, 0x43, 0x307, 0x0, 0x43, 0x30c, 0x0, 0x43, 0x327,\n                0x0, 0x43, 0x327, 0x301, 0x0, 0x43, 0x2215, 0x6b, 0x67, 0x0,\n                0x44, 0x0, 0x44, 0x4a, 0x0, 0x44, 0x5a, 0x0, 0x44, 0x5a, 0x30c,\n                0x0, 0x44, 0x7a, 0x0, 0x44, 0x7a, 0x30c, 0x0, 0x44, 0x307, 0x0,\n                0x44, 0x30c, 0x0, 0x44, 0x323, 0x0, 0x44, 0x327, 0x0, 0x44,\n                0x32d, 0x0, 0x44, 0x331, 0x0, 0x45, 0x0, 0x45, 0x300, 0x0,\n                0x45, 0x301, 0x0, 0x45, 0x302, 0x0, 0x45, 0x302, 0x300, 0x0,\n                0x45, 0x302, 0x301, 0x0, 0x45, 0x302, 0x303, 0x0, 0x45, 0x302,\n                0x309, 0x0, 0x45, 0x303, 0x0, 0x45, 0x304, 0x0, 0x45, 0x304,\n                0x300, 0x0, 0x45, 0x304, 0x301, 0x0, 0x45, 0x306, 0x0, 0x45,\n                0x307, 0x0, 0x45, 0x308, 0x0, 0x45, 0x309, 0x0, 0x45, 0x30c,\n                0x0, 0x45, 0x30f, 0x0, 0x45, 0x311, 0x0, 0x45, 0x323, 0x0,\n                0x45, 0x323, 0x302, 0x0, 0x45, 0x327, 0x0, 0x45, 0x327, 0x306,\n                0x0, 0x45, 0x328, 0x0, 0x45, 0x32d, 0x0, 0x45, 0x330, 0x0,\n                0x46, 0x0, 0x46, 0x41, 0x58, 0x0, 0x46, 0x307, 0x0, 0x47, 0x0,\n                0x47, 0x42, 0x0, 0x47, 0x48, 0x7a, 0x0, 0x47, 0x50, 0x61, 0x0,\n                0x47, 0x79, 0x0, 0x47, 0x301, 0x0, 0x47, 0x302, 0x0, 0x47,\n                0x304, 0x0, 0x47, 0x306, 0x0, 0x47, 0x307, 0x0, 0x47, 0x30c,\n                0x0, 0x47, 0x327, 0x0, 0x48, 0x0, 0x48, 0x50, 0x0, 0x48, 0x56,\n                0x0, 0x48, 0x67, 0x0, 0x48, 0x7a, 0x0, 0x48, 0x302, 0x0, 0x48,\n                0x307, 0x0, 0x48, 0x308, 0x0, 0x48, 0x30c, 0x0, 0x48, 0x323,\n                0x0, 0x48, 0x327, 0x0, 0x48, 0x32e, 0x0, 0x49, 0x0, 0x49, 0x49,\n                0x0, 0x49, 0x49, 0x49, 0x0, 0x49, 0x4a, 0x0, 0x49, 0x55, 0x0,\n                0x49, 0x56, 0x0, 0x49, 0x58, 0x0, 0x49, 0x300, 0x0, 0x49,\n                0x301, 0x0, 0x49, 0x302, 0x0, 0x49, 0x303, 0x0, 0x49, 0x304,\n                0x0, 0x49, 0x306, 0x0, 0x49, 0x307, 0x0, 0x49, 0x308, 0x0,\n                0x49, 0x308, 0x301, 0x0, 0x49, 0x309, 0x0, 0x49, 0x30c, 0x0,\n                0x49, 0x30f, 0x0, 0x49, 0x311, 0x0, 0x49, 0x323, 0x0, 0x49,\n                0x328, 0x0, 0x49, 0x330, 0x0, 0x4a, 0x0, 0x4a, 0x302, 0x0,\n                0x4b, 0x0, 0x4b, 0x42, 0x0, 0x4b, 0x4b, 0x0, 0x4b, 0x4d, 0x0,\n                0x4b, 0x301, 0x0, 0x4b, 0x30c, 0x0, 0x4b, 0x323, 0x0, 0x4b,\n                0x327, 0x0, 0x4b, 0x331, 0x0, 0x4c, 0x0, 0x4c, 0x4a, 0x0, 0x4c,\n                0x54, 0x44, 0x0, 0x4c, 0x6a, 0x0, 0x4c, 0xb7, 0x0, 0x4c, 0x301,\n                0x0, 0x4c, 0x30c, 0x0, 0x4c, 0x323, 0x0, 0x4c, 0x323, 0x304,\n                0x0, 0x4c, 0x327, 0x0, 0x4c, 0x32d, 0x0, 0x4c, 0x331, 0x0,\n                0x4d, 0x0, 0x4d, 0x42, 0x0, 0x4d, 0x43, 0x0, 0x4d, 0x44, 0x0,\n                0x4d, 0x48, 0x7a, 0x0, 0x4d, 0x50, 0x61, 0x0, 0x4d, 0x56, 0x0,\n                0x4d, 0x57, 0x0, 0x4d, 0x301, 0x0, 0x4d, 0x307, 0x0, 0x4d,\n                0x323, 0x0, 0x4d, 0x3a9, 0x0, 0x4e, 0x0, 0x4e, 0x4a, 0x0, 0x4e,\n                0x6a, 0x0, 0x4e, 0x6f, 0x0, 0x4e, 0x300, 0x0, 0x4e, 0x301, 0x0,\n                0x4e, 0x303, 0x0, 0x4e, 0x307, 0x0, 0x4e, 0x30c, 0x0, 0x4e,\n                0x323, 0x0, 0x4e, 0x327, 0x0, 0x4e, 0x32d, 0x0, 0x4e, 0x331,\n                0x0, 0x4f, 0x0, 0x4f, 0x300, 0x0, 0x4f, 0x301, 0x0, 0x4f,\n                0x302, 0x0, 0x4f, 0x302, 0x300, 0x0, 0x4f, 0x302, 0x301, 0x0,\n                0x4f, 0x302, 0x303, 0x0, 0x4f, 0x302, 0x309, 0x0, 0x4f, 0x303,\n                0x0, 0x4f, 0x303, 0x301, 0x0, 0x4f, 0x303, 0x304, 0x0, 0x4f,\n                0x303, 0x308, 0x0, 0x4f, 0x304, 0x0, 0x4f, 0x304, 0x300, 0x0,\n                0x4f, 0x304, 0x301, 0x0, 0x4f, 0x306, 0x0, 0x4f, 0x307, 0x0,\n                0x4f, 0x307, 0x304, 0x0, 0x4f, 0x308, 0x0, 0x4f, 0x308, 0x304,\n                0x0, 0x4f, 0x309, 0x0, 0x4f, 0x30b, 0x0, 0x4f, 0x30c, 0x0,\n                0x4f, 0x30f, 0x0, 0x4f, 0x311, 0x0, 0x4f, 0x31b, 0x0, 0x4f,\n                0x31b, 0x300, 0x0, 0x4f, 0x31b, 0x301, 0x0, 0x4f, 0x31b, 0x303,\n                0x0, 0x4f, 0x31b, 0x309, 0x0, 0x4f, 0x31b, 0x323, 0x0, 0x4f,\n                0x323, 0x0, 0x4f, 0x323, 0x302, 0x0, 0x4f, 0x328, 0x0, 0x4f,\n                0x328, 0x304, 0x0, 0x50, 0x0, 0x50, 0x48, 0x0, 0x50, 0x50,\n                0x4d, 0x0, 0x50, 0x50, 0x56, 0x0, 0x50, 0x52, 0x0, 0x50, 0x54,\n                0x45, 0x0, 0x50, 0x61, 0x0, 0x50, 0x301, 0x0, 0x50, 0x307, 0x0,\n                0x51, 0x0, 0x52, 0x0, 0x52, 0x73, 0x0, 0x52, 0x301, 0x0, 0x52,\n                0x307, 0x0, 0x52, 0x30c, 0x0, 0x52, 0x30f, 0x0, 0x52, 0x311,\n                0x0, 0x52, 0x323, 0x0, 0x52, 0x323, 0x304, 0x0, 0x52, 0x327,\n                0x0, 0x52, 0x331, 0x0, 0x53, 0x0, 0x53, 0x44, 0x0, 0x53, 0x4d,\n                0x0, 0x53, 0x53, 0x0, 0x53, 0x76, 0x0, 0x53, 0x301, 0x0, 0x53,\n                0x301, 0x307, 0x0, 0x53, 0x302, 0x0, 0x53, 0x307, 0x0, 0x53,\n                0x30c, 0x0, 0x53, 0x30c, 0x307, 0x0, 0x53, 0x323, 0x0, 0x53,\n                0x323, 0x307, 0x0, 0x53, 0x326, 0x0, 0x53, 0x327, 0x0, 0x54,\n                0x0, 0x54, 0x45, 0x4c, 0x0, 0x54, 0x48, 0x7a, 0x0, 0x54, 0x4d,\n                0x0, 0x54, 0x307, 0x0, 0x54, 0x30c, 0x0, 0x54, 0x323, 0x0,\n                0x54, 0x326, 0x0, 0x54, 0x327, 0x0, 0x54, 0x32d, 0x0, 0x54,\n                0x331, 0x0, 0x55, 0x0, 0x55, 0x300, 0x0, 0x55, 0x301, 0x0,\n                0x55, 0x302, 0x0, 0x55, 0x303, 0x0, 0x55, 0x303, 0x301, 0x0,\n                0x55, 0x304, 0x0, 0x55, 0x304, 0x308, 0x0, 0x55, 0x306, 0x0,\n                0x55, 0x308, 0x0, 0x55, 0x308, 0x300, 0x0, 0x55, 0x308, 0x301,\n                0x0, 0x55, 0x308, 0x304, 0x0, 0x55, 0x308, 0x30c, 0x0, 0x55,\n                0x309, 0x0, 0x55, 0x30a, 0x0, 0x55, 0x30b, 0x0, 0x55, 0x30c,\n                0x0, 0x55, 0x30f, 0x0, 0x55, 0x311, 0x0, 0x55, 0x31b, 0x0,\n                0x55, 0x31b, 0x300, 0x0, 0x55, 0x31b, 0x301, 0x0, 0x55, 0x31b,\n                0x303, 0x0, 0x55, 0x31b, 0x309, 0x0, 0x55, 0x31b, 0x323, 0x0,\n                0x55, 0x323, 0x0, 0x55, 0x324, 0x0, 0x55, 0x328, 0x0, 0x55,\n                0x32d, 0x0, 0x55, 0x330, 0x0, 0x56, 0x0, 0x56, 0x49, 0x0, 0x56,\n                0x49, 0x49, 0x0, 0x56, 0x49, 0x49, 0x49, 0x0, 0x56, 0x303, 0x0,\n                0x56, 0x323, 0x0, 0x56, 0x2215, 0x6d, 0x0, 0x57, 0x0, 0x57,\n                0x43, 0x0, 0x57, 0x5a, 0x0, 0x57, 0x62, 0x0, 0x57, 0x300, 0x0,\n                0x57, 0x301, 0x0, 0x57, 0x302, 0x0, 0x57, 0x307, 0x0, 0x57,\n                0x308, 0x0, 0x57, 0x323, 0x0, 0x58, 0x0, 0x58, 0x49, 0x0, 0x58,\n                0x49, 0x49, 0x0, 0x58, 0x307, 0x0, 0x58, 0x308, 0x0, 0x59, 0x0,\n                0x59, 0x300, 0x0, 0x59, 0x301, 0x0, 0x59, 0x302, 0x0, 0x59,\n                0x303, 0x0, 0x59, 0x304, 0x0, 0x59, 0x307, 0x0, 0x59, 0x308,\n                0x0, 0x59, 0x309, 0x0, 0x59, 0x323, 0x0, 0x5a, 0x0, 0x5a,\n                0x301, 0x0, 0x5a, 0x302, 0x0, 0x5a, 0x307, 0x0, 0x5a, 0x30c,\n                0x0, 0x5a, 0x323, 0x0, 0x5a, 0x331, 0x0, 0x5b, 0x0, 0x5c, 0x0,\n                0x5d, 0x0, 0x5e, 0x0, 0x5f, 0x0, 0x60, 0x0, 0x61, 0x0, 0x61,\n                0x2e, 0x6d, 0x2e, 0x0, 0x61, 0x2f, 0x63, 0x0, 0x61, 0x2f, 0x73,\n                0x0, 0x61, 0x2be, 0x0, 0x61, 0x300, 0x0, 0x61, 0x301, 0x0,\n                0x61, 0x302, 0x0, 0x61, 0x302, 0x300, 0x0, 0x61, 0x302, 0x301,\n                0x0, 0x61, 0x302, 0x303, 0x0, 0x61, 0x302, 0x309, 0x0, 0x61,\n                0x303, 0x0, 0x61, 0x304, 0x0, 0x61, 0x306, 0x0, 0x61, 0x306,\n                0x300, 0x0, 0x61, 0x306, 0x301, 0x0, 0x61, 0x306, 0x303, 0x0,\n                0x61, 0x306, 0x309, 0x0, 0x61, 0x307, 0x0, 0x61, 0x307, 0x304,\n                0x0, 0x61, 0x308, 0x0, 0x61, 0x308, 0x304, 0x0, 0x61, 0x309,\n                0x0, 0x61, 0x30a, 0x0, 0x61, 0x30a, 0x301, 0x0, 0x61, 0x30c,\n                0x0, 0x61, 0x30f, 0x0, 0x61, 0x311, 0x0, 0x61, 0x323, 0x0,\n                0x61, 0x323, 0x302, 0x0, 0x61, 0x323, 0x306, 0x0, 0x61, 0x325,\n                0x0, 0x61, 0x328, 0x0, 0x62, 0x0, 0x62, 0x61, 0x72, 0x0, 0x62,\n                0x307, 0x0, 0x62, 0x323, 0x0, 0x62, 0x331, 0x0, 0x63, 0x0,\n                0x63, 0x2f, 0x6f, 0x0, 0x63, 0x2f, 0x75, 0x0, 0x63, 0x61, 0x6c,\n                0x0, 0x63, 0x63, 0x0, 0x63, 0x64, 0x0, 0x63, 0x6d, 0x0, 0x63,\n                0x6d, 0x32, 0x0, 0x63, 0x6d, 0x33, 0x0, 0x63, 0x301, 0x0, 0x63,\n                0x302, 0x0, 0x63, 0x307, 0x0, 0x63, 0x30c, 0x0, 0x63, 0x327,\n                0x0, 0x63, 0x327, 0x301, 0x0, 0x64, 0x0, 0x64, 0x42, 0x0, 0x64,\n                0x61, 0x0, 0x64, 0x6c, 0x0, 0x64, 0x6d, 0x0, 0x64, 0x6d, 0x32,\n                0x0, 0x64, 0x6d, 0x33, 0x0, 0x64, 0x7a, 0x0, 0x64, 0x7a, 0x30c,\n                0x0, 0x64, 0x307, 0x0, 0x64, 0x30c, 0x0, 0x64, 0x323, 0x0,\n                0x64, 0x327, 0x0, 0x64, 0x32d, 0x0, 0x64, 0x331, 0x0, 0x65,\n                0x0, 0x65, 0x56, 0x0, 0x65, 0x72, 0x67, 0x0, 0x65, 0x300, 0x0,\n                0x65, 0x301, 0x0, 0x65, 0x302, 0x0, 0x65, 0x302, 0x300, 0x0,\n                0x65, 0x302, 0x301, 0x0, 0x65, 0x302, 0x303, 0x0, 0x65, 0x302,\n                0x309, 0x0, 0x65, 0x303, 0x0, 0x65, 0x304, 0x0, 0x65, 0x304,\n                0x300, 0x0, 0x65, 0x304, 0x301, 0x0, 0x65, 0x306, 0x0, 0x65,\n                0x307, 0x0, 0x65, 0x308, 0x0, 0x65, 0x309, 0x0, 0x65, 0x30c,\n                0x0, 0x65, 0x30f, 0x0, 0x65, 0x311, 0x0, 0x65, 0x323, 0x0,\n                0x65, 0x323, 0x302, 0x0, 0x65, 0x327, 0x0, 0x65, 0x327, 0x306,\n                0x0, 0x65, 0x328, 0x0, 0x65, 0x32d, 0x0, 0x65, 0x330, 0x0,\n                0x66, 0x0, 0x66, 0x66, 0x0, 0x66, 0x66, 0x69, 0x0, 0x66, 0x66,\n                0x6c, 0x0, 0x66, 0x69, 0x0, 0x66, 0x6c, 0x0, 0x66, 0x6d, 0x0,\n                0x66, 0x307, 0x0, 0x67, 0x0, 0x67, 0x61, 0x6c, 0x0, 0x67,\n                0x301, 0x0, 0x67, 0x302, 0x0, 0x67, 0x304, 0x0, 0x67, 0x306,\n                0x0, 0x67, 0x307, 0x0, 0x67, 0x30c, 0x0, 0x67, 0x327, 0x0,\n                0x68, 0x0, 0x68, 0x50, 0x61, 0x0, 0x68, 0x61, 0x0, 0x68, 0x302,\n                0x0, 0x68, 0x307, 0x0, 0x68, 0x308, 0x0, 0x68, 0x30c, 0x0,\n                0x68, 0x323, 0x0, 0x68, 0x327, 0x0, 0x68, 0x32e, 0x0, 0x68,\n                0x331, 0x0, 0x69, 0x0, 0x69, 0x69, 0x0, 0x69, 0x69, 0x69, 0x0,\n                0x69, 0x6a, 0x0, 0x69, 0x6e, 0x0, 0x69, 0x76, 0x0, 0x69, 0x78,\n                0x0, 0x69, 0x300, 0x0, 0x69, 0x301, 0x0, 0x69, 0x302, 0x0,\n                0x69, 0x303, 0x0, 0x69, 0x304, 0x0, 0x69, 0x306, 0x0, 0x69,\n                0x308, 0x0, 0x69, 0x308, 0x301, 0x0, 0x69, 0x309, 0x0, 0x69,\n                0x30c, 0x0, 0x69, 0x30f, 0x0, 0x69, 0x311, 0x0, 0x69, 0x323,\n                0x0, 0x69, 0x328, 0x0, 0x69, 0x330, 0x0, 0x6a, 0x0, 0x6a,\n                0x302, 0x0, 0x6a, 0x30c, 0x0, 0x6b, 0x0, 0x6b, 0x41, 0x0, 0x6b,\n                0x48, 0x7a, 0x0, 0x6b, 0x50, 0x61, 0x0, 0x6b, 0x56, 0x0, 0x6b,\n                0x57, 0x0, 0x6b, 0x63, 0x61, 0x6c, 0x0, 0x6b, 0x67, 0x0, 0x6b,\n                0x6c, 0x0, 0x6b, 0x6d, 0x0, 0x6b, 0x6d, 0x32, 0x0, 0x6b, 0x6d,\n                0x33, 0x0, 0x6b, 0x74, 0x0, 0x6b, 0x301, 0x0, 0x6b, 0x30c, 0x0,\n                0x6b, 0x323, 0x0, 0x6b, 0x327, 0x0, 0x6b, 0x331, 0x0, 0x6b,\n                0x3a9, 0x0, 0x6c, 0x0, 0x6c, 0x6a, 0x0, 0x6c, 0x6d, 0x0, 0x6c,\n                0x6e, 0x0, 0x6c, 0x6f, 0x67, 0x0, 0x6c, 0x78, 0x0, 0x6c, 0xb7,\n                0x0, 0x6c, 0x301, 0x0, 0x6c, 0x30c, 0x0, 0x6c, 0x323, 0x0,\n                0x6c, 0x323, 0x304, 0x0, 0x6c, 0x327, 0x0, 0x6c, 0x32d, 0x0,\n                0x6c, 0x331, 0x0, 0x6d, 0x0, 0x6d, 0x32, 0x0, 0x6d, 0x33, 0x0,\n                0x6d, 0x41, 0x0, 0x6d, 0x56, 0x0, 0x6d, 0x57, 0x0, 0x6d, 0x62,\n                0x0, 0x6d, 0x67, 0x0, 0x6d, 0x69, 0x6c, 0x0, 0x6d, 0x6c, 0x0,\n                0x6d, 0x6d, 0x0, 0x6d, 0x6d, 0x32, 0x0, 0x6d, 0x6d, 0x33, 0x0,\n                0x6d, 0x6f, 0x6c, 0x0, 0x6d, 0x73, 0x0, 0x6d, 0x301, 0x0, 0x6d,\n                0x307, 0x0, 0x6d, 0x323, 0x0, 0x6d, 0x2215, 0x73, 0x0, 0x6d,\n                0x2215, 0x73, 0x32, 0x0, 0x6e, 0x0, 0x6e, 0x41, 0x0, 0x6e,\n                0x46, 0x0, 0x6e, 0x56, 0x0, 0x6e, 0x57, 0x0, 0x6e, 0x6a, 0x0,\n                0x6e, 0x6d, 0x0, 0x6e, 0x73, 0x0, 0x6e, 0x300, 0x0, 0x6e,\n                0x301, 0x0, 0x6e, 0x303, 0x0, 0x6e, 0x307, 0x0, 0x6e, 0x30c,\n                0x0, 0x6e, 0x323, 0x0, 0x6e, 0x327, 0x0, 0x6e, 0x32d, 0x0,\n                0x6e, 0x331, 0x0, 0x6f, 0x0, 0x6f, 0x56, 0x0, 0x6f, 0x300, 0x0,\n                0x6f, 0x301, 0x0, 0x6f, 0x302, 0x0, 0x6f, 0x302, 0x300, 0x0,\n                0x6f, 0x302, 0x301, 0x0, 0x6f, 0x302, 0x303, 0x0, 0x6f, 0x302,\n                0x309, 0x0, 0x6f, 0x303, 0x0, 0x6f, 0x303, 0x301, 0x0, 0x6f,\n                0x303, 0x304, 0x0, 0x6f, 0x303, 0x308, 0x0, 0x6f, 0x304, 0x0,\n                0x6f, 0x304, 0x300, 0x0, 0x6f, 0x304, 0x301, 0x0, 0x6f, 0x306,\n                0x0, 0x6f, 0x307, 0x0, 0x6f, 0x307, 0x304, 0x0, 0x6f, 0x308,\n                0x0, 0x6f, 0x308, 0x304, 0x0, 0x6f, 0x309, 0x0, 0x6f, 0x30b,\n                0x0, 0x6f, 0x30c, 0x0, 0x6f, 0x30f, 0x0, 0x6f, 0x311, 0x0,\n                0x6f, 0x31b, 0x0, 0x6f, 0x31b, 0x300, 0x0, 0x6f, 0x31b, 0x301,\n                0x0, 0x6f, 0x31b, 0x303, 0x0, 0x6f, 0x31b, 0x309, 0x0, 0x6f,\n                0x31b, 0x323, 0x0, 0x6f, 0x323, 0x0, 0x6f, 0x323, 0x302, 0x0,\n                0x6f, 0x328, 0x0, 0x6f, 0x328, 0x304, 0x0, 0x70, 0x0, 0x70,\n                0x2e, 0x6d, 0x2e, 0x0, 0x70, 0x41, 0x0, 0x70, 0x46, 0x0, 0x70,\n                0x56, 0x0, 0x70, 0x57, 0x0, 0x70, 0x63, 0x0, 0x70, 0x73, 0x0,\n                0x70, 0x301, 0x0, 0x70, 0x307, 0x0, 0x71, 0x0, 0x72, 0x0, 0x72,\n                0x61, 0x64, 0x0, 0x72, 0x61, 0x64, 0x2215, 0x73, 0x0, 0x72,\n                0x61, 0x64, 0x2215, 0x73, 0x32, 0x0, 0x72, 0x301, 0x0, 0x72,\n                0x307, 0x0, 0x72, 0x30c, 0x0, 0x72, 0x30f, 0x0, 0x72, 0x311,\n                0x0, 0x72, 0x323, 0x0, 0x72, 0x323, 0x304, 0x0, 0x72, 0x327,\n                0x0, 0x72, 0x331, 0x0, 0x73, 0x0, 0x73, 0x72, 0x0, 0x73, 0x74,\n                0x0, 0x73, 0x301, 0x0, 0x73, 0x301, 0x307, 0x0, 0x73, 0x302,\n                0x0, 0x73, 0x307, 0x0, 0x73, 0x30c, 0x0, 0x73, 0x30c, 0x307,\n                0x0, 0x73, 0x323, 0x0, 0x73, 0x323, 0x307, 0x0, 0x73, 0x326,\n                0x0, 0x73, 0x327, 0x0, 0x74, 0x0, 0x74, 0x307, 0x0, 0x74,\n                0x308, 0x0, 0x74, 0x30c, 0x0, 0x74, 0x323, 0x0, 0x74, 0x326,\n                0x0, 0x74, 0x327, 0x0, 0x74, 0x32d, 0x0, 0x74, 0x331, 0x0,\n                0x75, 0x0, 0x75, 0x300, 0x0, 0x75, 0x301, 0x0, 0x75, 0x302,\n                0x0, 0x75, 0x303, 0x0, 0x75, 0x303, 0x301, 0x0, 0x75, 0x304,\n                0x0, 0x75, 0x304, 0x308, 0x0, 0x75, 0x306, 0x0, 0x75, 0x308,\n                0x0, 0x75, 0x308, 0x300, 0x0, 0x75, 0x308, 0x301, 0x0, 0x75,\n                0x308, 0x304, 0x0, 0x75, 0x308, 0x30c, 0x0, 0x75, 0x309, 0x0,\n                0x75, 0x30a, 0x0, 0x75, 0x30b, 0x0, 0x75, 0x30c, 0x0, 0x75,\n                0x30f, 0x0, 0x75, 0x311, 0x0, 0x75, 0x31b, 0x0, 0x75, 0x31b,\n                0x300, 0x0, 0x75, 0x31b, 0x301, 0x0, 0x75, 0x31b, 0x303, 0x0,\n                0x75, 0x31b, 0x309, 0x0, 0x75, 0x31b, 0x323, 0x0, 0x75, 0x323,\n                0x0, 0x75, 0x324, 0x0, 0x75, 0x328, 0x0, 0x75, 0x32d, 0x0,\n                0x75, 0x330, 0x0, 0x76, 0x0, 0x76, 0x69, 0x0, 0x76, 0x69, 0x69,\n                0x0, 0x76, 0x69, 0x69, 0x69, 0x0, 0x76, 0x303, 0x0, 0x76,\n                0x323, 0x0, 0x77, 0x0, 0x77, 0x300, 0x0, 0x77, 0x301, 0x0,\n                0x77, 0x302, 0x0, 0x77, 0x307, 0x0, 0x77, 0x308, 0x0, 0x77,\n                0x30a, 0x0, 0x77, 0x323, 0x0, 0x78, 0x0, 0x78, 0x69, 0x0, 0x78,\n                0x69, 0x69, 0x0, 0x78, 0x307, 0x0, 0x78, 0x308, 0x0, 0x79, 0x0,\n                0x79, 0x300, 0x0, 0x79, 0x301, 0x0, 0x79, 0x302, 0x0, 0x79,\n                0x303, 0x0, 0x79, 0x304, 0x0, 0x79, 0x307, 0x0, 0x79, 0x308,\n                0x0, 0x79, 0x309, 0x0, 0x79, 0x30a, 0x0, 0x79, 0x323, 0x0,\n                0x7a, 0x0, 0x7a, 0x301, 0x0, 0x7a, 0x302, 0x0, 0x7a, 0x307,\n                0x0, 0x7a, 0x30c, 0x0, 0x7a, 0x323, 0x0, 0x7a, 0x331, 0x0,\n                0x7b, 0x0, 0x7c, 0x0, 0x7d, 0x0, 0x7e, 0x0, 0xa2, 0x0, 0xa3,\n                0x0, 0xa5, 0x0, 0xa6, 0x0, 0xac, 0x0, 0xb0, 0x43, 0x0, 0xb0,\n                0x46, 0x0, 0xb7, 0x0, 0xc6, 0x0, 0xc6, 0x301, 0x0, 0xc6, 0x304,\n                0x0, 0xd8, 0x301, 0x0, 0xe6, 0x301, 0x0, 0xe6, 0x304, 0x0,\n                0xf0, 0x0, 0xf8, 0x301, 0x0, 0x126, 0x0, 0x127, 0x0, 0x131,\n                0x0, 0x14b, 0x0, 0x153, 0x0, 0x18e, 0x0, 0x190, 0x0, 0x1ab,\n                0x0, 0x1b7, 0x30c, 0x0, 0x222, 0x0, 0x237, 0x0, 0x250, 0x0,\n                0x251, 0x0, 0x252, 0x0, 0x254, 0x0, 0x255, 0x0, 0x259, 0x0,\n                0x25b, 0x0, 0x25c, 0x0, 0x25f, 0x0, 0x261, 0x0, 0x263, 0x0,\n                0x265, 0x0, 0x266, 0x0, 0x268, 0x0, 0x269, 0x0, 0x26a, 0x0,\n                0x26d, 0x0, 0x26f, 0x0, 0x270, 0x0, 0x271, 0x0, 0x272, 0x0,\n                0x273, 0x0, 0x274, 0x0, 0x275, 0x0, 0x278, 0x0, 0x279, 0x0,\n                0x27b, 0x0, 0x281, 0x0, 0x282, 0x0, 0x283, 0x0, 0x289, 0x0,\n                0x28a, 0x0, 0x28b, 0x0, 0x28c, 0x0, 0x290, 0x0, 0x291, 0x0,\n                0x292, 0x0, 0x292, 0x30c, 0x0, 0x295, 0x0, 0x29d, 0x0, 0x29f,\n                0x0, 0x2b9, 0x0, 0x2bc, 0x6e, 0x0, 0x300, 0x0, 0x301, 0x0,\n                0x308, 0x301, 0x0, 0x313, 0x0, 0x391, 0x0, 0x391, 0x300, 0x0,\n                0x391, 0x301, 0x0, 0x391, 0x304, 0x0, 0x391, 0x306, 0x0, 0x391,\n                0x313, 0x0, 0x391, 0x313, 0x300, 0x0, 0x391, 0x313, 0x300,\n                0x345, 0x0, 0x391, 0x313, 0x301, 0x0, 0x391, 0x313, 0x301,\n                0x345, 0x0, 0x391, 0x313, 0x342, 0x0, 0x391, 0x313, 0x342,\n                0x345, 0x0, 0x391, 0x313, 0x345, 0x0, 0x391, 0x314, 0x0, 0x391,\n                0x314, 0x300, 0x0, 0x391, 0x314, 0x300, 0x345, 0x0, 0x391,\n                0x314, 0x301, 0x0, 0x391, 0x314, 0x301, 0x345, 0x0, 0x391,\n                0x314, 0x342, 0x0, 0x391, 0x314, 0x342, 0x345, 0x0, 0x391,\n                0x314, 0x345, 0x0, 0x391, 0x345, 0x0, 0x392, 0x0, 0x393, 0x0,\n                0x394, 0x0, 0x395, 0x0, 0x395, 0x300, 0x0, 0x395, 0x301, 0x0,\n                0x395, 0x313, 0x0, 0x395, 0x313, 0x300, 0x0, 0x395, 0x313,\n                0x301, 0x0, 0x395, 0x314, 0x0, 0x395, 0x314, 0x300, 0x0, 0x395,\n                0x314, 0x301, 0x0, 0x396, 0x0, 0x397, 0x0, 0x397, 0x300, 0x0,\n                0x397, 0x301, 0x0, 0x397, 0x313, 0x0, 0x397, 0x313, 0x300, 0x0,\n                0x397, 0x313, 0x300, 0x345, 0x0, 0x397, 0x313, 0x301, 0x0,\n                0x397, 0x313, 0x301, 0x345, 0x0, 0x397, 0x313, 0x342, 0x0,\n                0x397, 0x313, 0x342, 0x345, 0x0, 0x397, 0x313, 0x345, 0x0,\n                0x397, 0x314, 0x0, 0x397, 0x314, 0x300, 0x0, 0x397, 0x314,\n                0x300, 0x345, 0x0, 0x397, 0x314, 0x301, 0x0, 0x397, 0x314,\n                0x301, 0x345, 0x0, 0x397, 0x314, 0x342, 0x0, 0x397, 0x314,\n                0x342, 0x345, 0x0, 0x397, 0x314, 0x345, 0x0, 0x397, 0x345, 0x0,\n                0x398, 0x0, 0x399, 0x0, 0x399, 0x300, 0x0, 0x399, 0x301, 0x0,\n                0x399, 0x304, 0x0, 0x399, 0x306, 0x0, 0x399, 0x308, 0x0, 0x399,\n                0x313, 0x0, 0x399, 0x313, 0x300, 0x0, 0x399, 0x313, 0x301, 0x0,\n                0x399, 0x313, 0x342, 0x0, 0x399, 0x314, 0x0, 0x399, 0x314,\n                0x300, 0x0, 0x399, 0x314, 0x301, 0x0, 0x399, 0x314, 0x342, 0x0,\n                0x39a, 0x0, 0x39b, 0x0, 0x39c, 0x0, 0x39d, 0x0, 0x39e, 0x0,\n                0x39f, 0x0, 0x39f, 0x300, 0x0, 0x39f, 0x301, 0x0, 0x39f, 0x313,\n                0x0, 0x39f, 0x313, 0x300, 0x0, 0x39f, 0x313, 0x301, 0x0, 0x39f,\n                0x314, 0x0, 0x39f, 0x314, 0x300, 0x0, 0x39f, 0x314, 0x301, 0x0,\n                0x3a0, 0x0, 0x3a1, 0x0, 0x3a1, 0x314, 0x0, 0x3a3, 0x0, 0x3a4,\n                0x0, 0x3a5, 0x0, 0x3a5, 0x300, 0x0, 0x3a5, 0x301, 0x0, 0x3a5,\n                0x304, 0x0, 0x3a5, 0x306, 0x0, 0x3a5, 0x308, 0x0, 0x3a5, 0x314,\n                0x0, 0x3a5, 0x314, 0x300, 0x0, 0x3a5, 0x314, 0x301, 0x0, 0x3a5,\n                0x314, 0x342, 0x0, 0x3a6, 0x0, 0x3a7, 0x0, 0x3a8, 0x0, 0x3a9,\n                0x0, 0x3a9, 0x300, 0x0, 0x3a9, 0x301, 0x0, 0x3a9, 0x313, 0x0,\n                0x3a9, 0x313, 0x300, 0x0, 0x3a9, 0x313, 0x300, 0x345, 0x0,\n                0x3a9, 0x313, 0x301, 0x0, 0x3a9, 0x313, 0x301, 0x345, 0x0,\n                0x3a9, 0x313, 0x342, 0x0, 0x3a9, 0x313, 0x342, 0x345, 0x0,\n                0x3a9, 0x313, 0x345, 0x0, 0x3a9, 0x314, 0x0, 0x3a9, 0x314,\n                0x300, 0x0, 0x3a9, 0x314, 0x300, 0x345, 0x0, 0x3a9, 0x314,\n                0x301, 0x0, 0x3a9, 0x314, 0x301, 0x345, 0x0, 0x3a9, 0x314,\n                0x342, 0x0, 0x3a9, 0x314, 0x342, 0x345, 0x0, 0x3a9, 0x314,\n                0x345, 0x0, 0x3a9, 0x345, 0x0, 0x3b1, 0x0, 0x3b1, 0x300, 0x0,\n                0x3b1, 0x300, 0x345, 0x0, 0x3b1, 0x301, 0x0, 0x3b1, 0x301,\n                0x345, 0x0, 0x3b1, 0x304, 0x0, 0x3b1, 0x306, 0x0, 0x3b1, 0x313,\n                0x0, 0x3b1, 0x313, 0x300, 0x0, 0x3b1, 0x313, 0x300, 0x345, 0x0,\n                0x3b1, 0x313, 0x301, 0x0, 0x3b1, 0x313, 0x301, 0x345, 0x0,\n                0x3b1, 0x313, 0x342, 0x0, 0x3b1, 0x313, 0x342, 0x345, 0x0,\n                0x3b1, 0x313, 0x345, 0x0, 0x3b1, 0x314, 0x0, 0x3b1, 0x314,\n                0x300, 0x0, 0x3b1, 0x314, 0x300, 0x345, 0x0, 0x3b1, 0x314,\n                0x301, 0x0, 0x3b1, 0x314, 0x301, 0x345, 0x0, 0x3b1, 0x314,\n                0x342, 0x0, 0x3b1, 0x314, 0x342, 0x345, 0x0, 0x3b1, 0x314,\n                0x345, 0x0, 0x3b1, 0x342, 0x0, 0x3b1, 0x342, 0x345, 0x0, 0x3b1,\n                0x345, 0x0, 0x3b2, 0x0, 0x3b3, 0x0, 0x3b4, 0x0, 0x3b5, 0x0,\n                0x3b5, 0x300, 0x0, 0x3b5, 0x301, 0x0, 0x3b5, 0x313, 0x0, 0x3b5,\n                0x313, 0x300, 0x0, 0x3b5, 0x313, 0x301, 0x0, 0x3b5, 0x314, 0x0,\n                0x3b5, 0x314, 0x300, 0x0, 0x3b5, 0x314, 0x301, 0x0, 0x3b6, 0x0,\n                0x3b7, 0x0, 0x3b7, 0x300, 0x0, 0x3b7, 0x300, 0x345, 0x0, 0x3b7,\n                0x301, 0x0, 0x3b7, 0x301, 0x345, 0x0, 0x3b7, 0x313, 0x0, 0x3b7,\n                0x313, 0x300, 0x0, 0x3b7, 0x313, 0x300, 0x345, 0x0, 0x3b7,\n                0x313, 0x301, 0x0, 0x3b7, 0x313, 0x301, 0x345, 0x0, 0x3b7,\n                0x313, 0x342, 0x0, 0x3b7, 0x313, 0x342, 0x345, 0x0, 0x3b7,\n                0x313, 0x345, 0x0, 0x3b7, 0x314, 0x0, 0x3b7, 0x314, 0x300, 0x0,\n                0x3b7, 0x314, 0x300, 0x345, 0x0, 0x3b7, 0x314, 0x301, 0x0,\n                0x3b7, 0x314, 0x301, 0x345, 0x0, 0x3b7, 0x314, 0x342, 0x0,\n                0x3b7, 0x314, 0x342, 0x345, 0x0, 0x3b7, 0x314, 0x345, 0x0,\n                0x3b7, 0x342, 0x0, 0x3b7, 0x342, 0x345, 0x0, 0x3b7, 0x345, 0x0,\n                0x3b8, 0x0, 0x3b9, 0x0, 0x3b9, 0x300, 0x0, 0x3b9, 0x301, 0x0,\n                0x3b9, 0x304, 0x0, 0x3b9, 0x306, 0x0, 0x3b9, 0x308, 0x0, 0x3b9,\n                0x308, 0x300, 0x0, 0x3b9, 0x308, 0x301, 0x0, 0x3b9, 0x308,\n                0x342, 0x0, 0x3b9, 0x313, 0x0, 0x3b9, 0x313, 0x300, 0x0, 0x3b9,\n                0x313, 0x301, 0x0, 0x3b9, 0x313, 0x342, 0x0, 0x3b9, 0x314, 0x0,\n                0x3b9, 0x314, 0x300, 0x0, 0x3b9, 0x314, 0x301, 0x0, 0x3b9,\n                0x314, 0x342, 0x0, 0x3b9, 0x342, 0x0, 0x3ba, 0x0, 0x3bb, 0x0,\n                0x3bc, 0x0, 0x3bc, 0x41, 0x0, 0x3bc, 0x46, 0x0, 0x3bc, 0x56,\n                0x0, 0x3bc, 0x57, 0x0, 0x3bc, 0x67, 0x0, 0x3bc, 0x6c, 0x0,\n                0x3bc, 0x6d, 0x0, 0x3bc, 0x73, 0x0, 0x3bd, 0x0, 0x3be, 0x0,\n                0x3bf, 0x0, 0x3bf, 0x300, 0x0, 0x3bf, 0x301, 0x0, 0x3bf, 0x313,\n                0x0, 0x3bf, 0x313, 0x300, 0x0, 0x3bf, 0x313, 0x301, 0x0, 0x3bf,\n                0x314, 0x0, 0x3bf, 0x314, 0x300, 0x0, 0x3bf, 0x314, 0x301, 0x0,\n                0x3c0, 0x0, 0x3c1, 0x0, 0x3c1, 0x313, 0x0, 0x3c1, 0x314, 0x0,\n                0x3c2, 0x0, 0x3c3, 0x0, 0x3c4, 0x0, 0x3c5, 0x0, 0x3c5, 0x300,\n                0x0, 0x3c5, 0x301, 0x0, 0x3c5, 0x304, 0x0, 0x3c5, 0x306, 0x0,\n                0x3c5, 0x308, 0x0, 0x3c5, 0x308, 0x300, 0x0, 0x3c5, 0x308,\n                0x301, 0x0, 0x3c5, 0x308, 0x342, 0x0, 0x3c5, 0x313, 0x0, 0x3c5,\n                0x313, 0x300, 0x0, 0x3c5, 0x313, 0x301, 0x0, 0x3c5, 0x313,\n                0x342, 0x0, 0x3c5, 0x314, 0x0, 0x3c5, 0x314, 0x300, 0x0, 0x3c5,\n                0x314, 0x301, 0x0, 0x3c5, 0x314, 0x342, 0x0, 0x3c5, 0x342, 0x0,\n                0x3c6, 0x0, 0x3c7, 0x0, 0x3c8, 0x0, 0x3c9, 0x0, 0x3c9, 0x300,\n                0x0, 0x3c9, 0x300, 0x345, 0x0, 0x3c9, 0x301, 0x0, 0x3c9, 0x301,\n                0x345, 0x0, 0x3c9, 0x313, 0x0, 0x3c9, 0x313, 0x300, 0x0, 0x3c9,\n                0x313, 0x300, 0x345, 0x0, 0x3c9, 0x313, 0x301, 0x0, 0x3c9,\n                0x313, 0x301, 0x345, 0x0, 0x3c9, 0x313, 0x342, 0x0, 0x3c9,\n                0x313, 0x342, 0x345, 0x0, 0x3c9, 0x313, 0x345, 0x0, 0x3c9,\n                0x314, 0x0, 0x3c9, 0x314, 0x300, 0x0, 0x3c9, 0x314, 0x300,\n                0x345, 0x0, 0x3c9, 0x314, 0x301, 0x0, 0x3c9, 0x314, 0x301,\n                0x345, 0x0, 0x3c9, 0x314, 0x342, 0x0, 0x3c9, 0x314, 0x342,\n                0x345, 0x0, 0x3c9, 0x314, 0x345, 0x0, 0x3c9, 0x342, 0x0, 0x3c9,\n                0x342, 0x345, 0x0, 0x3c9, 0x345, 0x0, 0x3dc, 0x0, 0x3dd, 0x0,\n                0x406, 0x308, 0x0, 0x410, 0x306, 0x0, 0x410, 0x308, 0x0, 0x413,\n                0x301, 0x0, 0x415, 0x300, 0x0, 0x415, 0x306, 0x0, 0x415, 0x308,\n                0x0, 0x416, 0x306, 0x0, 0x416, 0x308, 0x0, 0x417, 0x308, 0x0,\n                0x418, 0x300, 0x0, 0x418, 0x304, 0x0, 0x418, 0x306, 0x0, 0x418,\n                0x308, 0x0, 0x41a, 0x301, 0x0, 0x41e, 0x308, 0x0, 0x423, 0x304,\n                0x0, 0x423, 0x306, 0x0, 0x423, 0x308, 0x0, 0x423, 0x30b, 0x0,\n                0x427, 0x308, 0x0, 0x42b, 0x308, 0x0, 0x42d, 0x308, 0x0, 0x430,\n                0x306, 0x0, 0x430, 0x308, 0x0, 0x433, 0x301, 0x0, 0x435, 0x300,\n                0x0, 0x435, 0x306, 0x0, 0x435, 0x308, 0x0, 0x436, 0x306, 0x0,\n                0x436, 0x308, 0x0, 0x437, 0x308, 0x0, 0x438, 0x300, 0x0, 0x438,\n                0x304, 0x0, 0x438, 0x306, 0x0, 0x438, 0x308, 0x0, 0x43a, 0x301,\n                0x0, 0x43d, 0x0, 0x43e, 0x308, 0x0, 0x443, 0x304, 0x0, 0x443,\n                0x306, 0x0, 0x443, 0x308, 0x0, 0x443, 0x30b, 0x0, 0x447, 0x308,\n                0x0, 0x44b, 0x308, 0x0, 0x44d, 0x308, 0x0, 0x456, 0x308, 0x0,\n                0x474, 0x30f, 0x0, 0x475, 0x30f, 0x0, 0x4d8, 0x308, 0x0, 0x4d9,\n                0x308, 0x0, 0x4e8, 0x308, 0x0, 0x4e9, 0x308, 0x0, 0x565, 0x582,\n                0x0, 0x574, 0x565, 0x0, 0x574, 0x56b, 0x0, 0x574, 0x56d, 0x0,\n                0x574, 0x576, 0x0, 0x57e, 0x576, 0x0, 0x5d0, 0x0, 0x5d0, 0x5b7,\n                0x0, 0x5d0, 0x5b8, 0x0, 0x5d0, 0x5bc, 0x0, 0x5d0, 0x5dc, 0x0,\n                0x5d1, 0x0, 0x5d1, 0x5bc, 0x0, 0x5d1, 0x5bf, 0x0, 0x5d2, 0x0,\n                0x5d2, 0x5bc, 0x0, 0x5d3, 0x0, 0x5d3, 0x5bc, 0x0, 0x5d4, 0x0,\n                0x5d4, 0x5bc, 0x0, 0x5d5, 0x5b9, 0x0, 0x5d5, 0x5bc, 0x0, 0x5d6,\n                0x5bc, 0x0, 0x5d8, 0x5bc, 0x0, 0x5d9, 0x5b4, 0x0, 0x5d9, 0x5bc,\n                0x0, 0x5da, 0x5bc, 0x0, 0x5db, 0x0, 0x5db, 0x5bc, 0x0, 0x5db,\n                0x5bf, 0x0, 0x5dc, 0x0, 0x5dc, 0x5bc, 0x0, 0x5dd, 0x0, 0x5de,\n                0x5bc, 0x0, 0x5e0, 0x5bc, 0x0, 0x5e1, 0x5bc, 0x0, 0x5e2, 0x0,\n                0x5e3, 0x5bc, 0x0, 0x5e4, 0x5bc, 0x0, 0x5e4, 0x5bf, 0x0, 0x5e6,\n                0x5bc, 0x0, 0x5e7, 0x5bc, 0x0, 0x5e8, 0x0, 0x5e8, 0x5bc, 0x0,\n                0x5e9, 0x5bc, 0x0, 0x5e9, 0x5bc, 0x5c1, 0x0, 0x5e9, 0x5bc,\n                0x5c2, 0x0, 0x5e9, 0x5c1, 0x0, 0x5e9, 0x5c2, 0x0, 0x5ea, 0x0,\n                0x5ea, 0x5bc, 0x0, 0x5f2, 0x5b7, 0x0, 0x621, 0x0, 0x627, 0x0,\n                0x627, 0x643, 0x628, 0x631, 0x0, 0x627, 0x644, 0x644, 0x647,\n                0x0, 0x627, 0x64b, 0x0, 0x627, 0x653, 0x0, 0x627, 0x654, 0x0,\n                0x627, 0x655, 0x0, 0x627, 0x674, 0x0, 0x628, 0x0, 0x628, 0x62c,\n                0x0, 0x628, 0x62d, 0x0, 0x628, 0x62d, 0x64a, 0x0, 0x628, 0x62e,\n                0x0, 0x628, 0x62e, 0x64a, 0x0, 0x628, 0x631, 0x0, 0x628, 0x632,\n                0x0, 0x628, 0x645, 0x0, 0x628, 0x646, 0x0, 0x628, 0x647, 0x0,\n                0x628, 0x649, 0x0, 0x628, 0x64a, 0x0, 0x629, 0x0, 0x62a, 0x0,\n                0x62a, 0x62c, 0x0, 0x62a, 0x62c, 0x645, 0x0, 0x62a, 0x62c,\n                0x649, 0x0, 0x62a, 0x62c, 0x64a, 0x0, 0x62a, 0x62d, 0x0, 0x62a,\n                0x62d, 0x62c, 0x0, 0x62a, 0x62d, 0x645, 0x0, 0x62a, 0x62e, 0x0,\n                0x62a, 0x62e, 0x645, 0x0, 0x62a, 0x62e, 0x649, 0x0, 0x62a,\n                0x62e, 0x64a, 0x0, 0x62a, 0x631, 0x0, 0x62a, 0x632, 0x0, 0x62a,\n                0x645, 0x0, 0x62a, 0x645, 0x62c, 0x0, 0x62a, 0x645, 0x62d, 0x0,\n                0x62a, 0x645, 0x62e, 0x0, 0x62a, 0x645, 0x649, 0x0, 0x62a,\n                0x645, 0x64a, 0x0, 0x62a, 0x646, 0x0, 0x62a, 0x647, 0x0, 0x62a,\n                0x649, 0x0, 0x62a, 0x64a, 0x0, 0x62b, 0x0, 0x62b, 0x62c, 0x0,\n                0x62b, 0x631, 0x0, 0x62b, 0x632, 0x0, 0x62b, 0x645, 0x0, 0x62b,\n                0x646, 0x0, 0x62b, 0x647, 0x0, 0x62b, 0x649, 0x0, 0x62b, 0x64a,\n                0x0, 0x62c, 0x0, 0x62c, 0x62d, 0x0, 0x62c, 0x62d, 0x649, 0x0,\n                0x62c, 0x62d, 0x64a, 0x0, 0x62c, 0x644, 0x20, 0x62c, 0x644,\n                0x627, 0x644, 0x647, 0x0, 0x62c, 0x645, 0x0, 0x62c, 0x645,\n                0x62d, 0x0, 0x62c, 0x645, 0x649, 0x0, 0x62c, 0x645, 0x64a, 0x0,\n                0x62c, 0x649, 0x0, 0x62c, 0x64a, 0x0, 0x62d, 0x0, 0x62d, 0x62c,\n                0x0, 0x62d, 0x62c, 0x64a, 0x0, 0x62d, 0x645, 0x0, 0x62d, 0x645,\n                0x649, 0x0, 0x62d, 0x645, 0x64a, 0x0, 0x62d, 0x649, 0x0, 0x62d,\n                0x64a, 0x0, 0x62e, 0x0, 0x62e, 0x62c, 0x0, 0x62e, 0x62d, 0x0,\n                0x62e, 0x645, 0x0, 0x62e, 0x649, 0x0, 0x62e, 0x64a, 0x0, 0x62f,\n                0x0, 0x630, 0x0, 0x630, 0x670, 0x0, 0x631, 0x0, 0x631, 0x633,\n                0x648, 0x644, 0x0, 0x631, 0x670, 0x0, 0x631, 0x6cc, 0x627,\n                0x644, 0x0, 0x632, 0x0, 0x633, 0x0, 0x633, 0x62c, 0x0, 0x633,\n                0x62c, 0x62d, 0x0, 0x633, 0x62c, 0x649, 0x0, 0x633, 0x62d, 0x0,\n                0x633, 0x62d, 0x62c, 0x0, 0x633, 0x62e, 0x0, 0x633, 0x62e,\n                0x649, 0x0, 0x633, 0x62e, 0x64a, 0x0, 0x633, 0x631, 0x0, 0x633,\n                0x645, 0x0, 0x633, 0x645, 0x62c, 0x0, 0x633, 0x645, 0x62d, 0x0,\n                0x633, 0x645, 0x645, 0x0, 0x633, 0x647, 0x0, 0x633, 0x649, 0x0,\n                0x633, 0x64a, 0x0, 0x634, 0x0, 0x634, 0x62c, 0x0, 0x634, 0x62c,\n                0x64a, 0x0, 0x634, 0x62d, 0x0, 0x634, 0x62d, 0x645, 0x0, 0x634,\n                0x62d, 0x64a, 0x0, 0x634, 0x62e, 0x0, 0x634, 0x631, 0x0, 0x634,\n                0x645, 0x0, 0x634, 0x645, 0x62e, 0x0, 0x634, 0x645, 0x645, 0x0,\n                0x634, 0x647, 0x0, 0x634, 0x649, 0x0, 0x634, 0x64a, 0x0, 0x635,\n                0x0, 0x635, 0x62d, 0x0, 0x635, 0x62d, 0x62d, 0x0, 0x635, 0x62d,\n                0x64a, 0x0, 0x635, 0x62e, 0x0, 0x635, 0x631, 0x0, 0x635, 0x644,\n                0x639, 0x645, 0x0, 0x635, 0x644, 0x649, 0x0, 0x635, 0x644,\n                0x649, 0x20, 0x627, 0x644, 0x644, 0x647, 0x20, 0x639, 0x644,\n                0x64a, 0x647, 0x20, 0x648, 0x633, 0x644, 0x645, 0x0, 0x635,\n                0x644, 0x6d2, 0x0, 0x635, 0x645, 0x0, 0x635, 0x645, 0x645, 0x0,\n                0x635, 0x649, 0x0, 0x635, 0x64a, 0x0, 0x636, 0x0, 0x636, 0x62c,\n                0x0, 0x636, 0x62d, 0x0, 0x636, 0x62d, 0x649, 0x0, 0x636, 0x62d,\n                0x64a, 0x0, 0x636, 0x62e, 0x0, 0x636, 0x62e, 0x645, 0x0, 0x636,\n                0x631, 0x0, 0x636, 0x645, 0x0, 0x636, 0x649, 0x0, 0x636, 0x64a,\n                0x0, 0x637, 0x0, 0x637, 0x62d, 0x0, 0x637, 0x645, 0x0, 0x637,\n                0x645, 0x62d, 0x0, 0x637, 0x645, 0x645, 0x0, 0x637, 0x645,\n                0x64a, 0x0, 0x637, 0x649, 0x0, 0x637, 0x64a, 0x0, 0x638, 0x0,\n                0x638, 0x645, 0x0, 0x639, 0x0, 0x639, 0x62c, 0x0, 0x639, 0x62c,\n                0x645, 0x0, 0x639, 0x644, 0x64a, 0x647, 0x0, 0x639, 0x645, 0x0,\n                0x639, 0x645, 0x645, 0x0, 0x639, 0x645, 0x649, 0x0, 0x639,\n                0x645, 0x64a, 0x0, 0x639, 0x649, 0x0, 0x639, 0x64a, 0x0, 0x63a,\n                0x0, 0x63a, 0x62c, 0x0, 0x63a, 0x645, 0x0, 0x63a, 0x645, 0x645,\n                0x0, 0x63a, 0x645, 0x649, 0x0, 0x63a, 0x645, 0x64a, 0x0, 0x63a,\n                0x649, 0x0, 0x63a, 0x64a, 0x0, 0x640, 0x64b, 0x0, 0x640, 0x64e,\n                0x0, 0x640, 0x64e, 0x651, 0x0, 0x640, 0x64f, 0x0, 0x640, 0x64f,\n                0x651, 0x0, 0x640, 0x650, 0x0, 0x640, 0x650, 0x651, 0x0, 0x640,\n                0x651, 0x0, 0x640, 0x652, 0x0, 0x641, 0x0, 0x641, 0x62c, 0x0,\n                0x641, 0x62d, 0x0, 0x641, 0x62e, 0x0, 0x641, 0x62e, 0x645, 0x0,\n                0x641, 0x645, 0x0, 0x641, 0x645, 0x64a, 0x0, 0x641, 0x649, 0x0,\n                0x641, 0x64a, 0x0, 0x642, 0x0, 0x642, 0x62d, 0x0, 0x642, 0x644,\n                0x6d2, 0x0, 0x642, 0x645, 0x0, 0x642, 0x645, 0x62d, 0x0, 0x642,\n                0x645, 0x645, 0x0, 0x642, 0x645, 0x64a, 0x0, 0x642, 0x649, 0x0,\n                0x642, 0x64a, 0x0, 0x643, 0x0, 0x643, 0x627, 0x0, 0x643, 0x62c,\n                0x0, 0x643, 0x62d, 0x0, 0x643, 0x62e, 0x0, 0x643, 0x644, 0x0,\n                0x643, 0x645, 0x0, 0x643, 0x645, 0x645, 0x0, 0x643, 0x645,\n                0x64a, 0x0, 0x643, 0x649, 0x0, 0x643, 0x64a, 0x0, 0x644, 0x0,\n                0x644, 0x627, 0x0, 0x644, 0x627, 0x653, 0x0, 0x644, 0x627,\n                0x654, 0x0, 0x644, 0x627, 0x655, 0x0, 0x644, 0x62c, 0x0, 0x644,\n                0x62c, 0x62c, 0x0, 0x644, 0x62c, 0x645, 0x0, 0x644, 0x62c,\n                0x64a, 0x0, 0x644, 0x62d, 0x0, 0x644, 0x62d, 0x645, 0x0, 0x644,\n                0x62d, 0x649, 0x0, 0x644, 0x62d, 0x64a, 0x0, 0x644, 0x62e, 0x0,\n                0x644, 0x62e, 0x645, 0x0, 0x644, 0x645, 0x0, 0x644, 0x645,\n                0x62d, 0x0, 0x644, 0x645, 0x64a, 0x0, 0x644, 0x647, 0x0, 0x644,\n                0x649, 0x0, 0x644, 0x64a, 0x0, 0x645, 0x0, 0x645, 0x627, 0x0,\n                0x645, 0x62c, 0x0, 0x645, 0x62c, 0x62d, 0x0, 0x645, 0x62c,\n                0x62e, 0x0, 0x645, 0x62c, 0x645, 0x0, 0x645, 0x62c, 0x64a, 0x0,\n                0x645, 0x62d, 0x0, 0x645, 0x62d, 0x62c, 0x0, 0x645, 0x62d,\n                0x645, 0x0, 0x645, 0x62d, 0x645, 0x62f, 0x0, 0x645, 0x62d,\n                0x64a, 0x0, 0x645, 0x62e, 0x0, 0x645, 0x62e, 0x62c, 0x0, 0x645,\n                0x62e, 0x645, 0x0, 0x645, 0x62e, 0x64a, 0x0, 0x645, 0x645, 0x0,\n                0x645, 0x645, 0x64a, 0x0, 0x645, 0x649, 0x0, 0x645, 0x64a, 0x0,\n                0x646, 0x0, 0x646, 0x62c, 0x0, 0x646, 0x62c, 0x62d, 0x0, 0x646,\n                0x62c, 0x645, 0x0, 0x646, 0x62c, 0x649, 0x0, 0x646, 0x62c,\n                0x64a, 0x0, 0x646, 0x62d, 0x0, 0x646, 0x62d, 0x645, 0x0, 0x646,\n                0x62d, 0x649, 0x0, 0x646, 0x62d, 0x64a, 0x0, 0x646, 0x62e, 0x0,\n                0x646, 0x631, 0x0, 0x646, 0x632, 0x0, 0x646, 0x645, 0x0, 0x646,\n                0x645, 0x649, 0x0, 0x646, 0x645, 0x64a, 0x0, 0x646, 0x646, 0x0,\n                0x646, 0x647, 0x0, 0x646, 0x649, 0x0, 0x646, 0x64a, 0x0, 0x647,\n                0x0, 0x647, 0x62c, 0x0, 0x647, 0x645, 0x0, 0x647, 0x645, 0x62c,\n                0x0, 0x647, 0x645, 0x645, 0x0, 0x647, 0x649, 0x0, 0x647, 0x64a,\n                0x0, 0x647, 0x670, 0x0, 0x648, 0x0, 0x648, 0x633, 0x644, 0x645,\n                0x0, 0x648, 0x654, 0x0, 0x648, 0x674, 0x0, 0x649, 0x0, 0x649,\n                0x670, 0x0, 0x64a, 0x0, 0x64a, 0x62c, 0x0, 0x64a, 0x62c, 0x64a,\n                0x0, 0x64a, 0x62d, 0x0, 0x64a, 0x62d, 0x64a, 0x0, 0x64a, 0x62e,\n                0x0, 0x64a, 0x631, 0x0, 0x64a, 0x632, 0x0, 0x64a, 0x645, 0x0,\n                0x64a, 0x645, 0x645, 0x0, 0x64a, 0x645, 0x64a, 0x0, 0x64a,\n                0x646, 0x0, 0x64a, 0x647, 0x0, 0x64a, 0x649, 0x0, 0x64a, 0x64a,\n                0x0, 0x64a, 0x654, 0x0, 0x64a, 0x654, 0x627, 0x0, 0x64a, 0x654,\n                0x62c, 0x0, 0x64a, 0x654, 0x62d, 0x0, 0x64a, 0x654, 0x62e, 0x0,\n                0x64a, 0x654, 0x631, 0x0, 0x64a, 0x654, 0x632, 0x0, 0x64a,\n                0x654, 0x645, 0x0, 0x64a, 0x654, 0x646, 0x0, 0x64a, 0x654,\n                0x647, 0x0, 0x64a, 0x654, 0x648, 0x0, 0x64a, 0x654, 0x649, 0x0,\n                0x64a, 0x654, 0x64a, 0x0, 0x64a, 0x654, 0x6c6, 0x0, 0x64a,\n                0x654, 0x6c7, 0x0, 0x64a, 0x654, 0x6c8, 0x0, 0x64a, 0x654,\n                0x6d0, 0x0, 0x64a, 0x654, 0x6d5, 0x0, 0x64a, 0x674, 0x0, 0x66e,\n                0x0, 0x66f, 0x0, 0x671, 0x0, 0x679, 0x0, 0x67a, 0x0, 0x67b,\n                0x0, 0x67e, 0x0, 0x67f, 0x0, 0x680, 0x0, 0x683, 0x0, 0x684,\n                0x0, 0x686, 0x0, 0x687, 0x0, 0x688, 0x0, 0x68c, 0x0, 0x68d,\n                0x0, 0x68e, 0x0, 0x691, 0x0, 0x698, 0x0, 0x6a1, 0x0, 0x6a4,\n                0x0, 0x6a6, 0x0, 0x6a9, 0x0, 0x6ad, 0x0, 0x6af, 0x0, 0x6b1,\n                0x0, 0x6b3, 0x0, 0x6ba, 0x0, 0x6bb, 0x0, 0x6be, 0x0, 0x6c1,\n                0x0, 0x6c1, 0x654, 0x0, 0x6c5, 0x0, 0x6c6, 0x0, 0x6c7, 0x0,\n                0x6c7, 0x674, 0x0, 0x6c8, 0x0, 0x6c9, 0x0, 0x6cb, 0x0, 0x6cc,\n                0x0, 0x6d0, 0x0, 0x6d2, 0x0, 0x6d2, 0x654, 0x0, 0x6d5, 0x654,\n                0x0, 0x915, 0x93c, 0x0, 0x916, 0x93c, 0x0, 0x917, 0x93c, 0x0,\n                0x91c, 0x93c, 0x0, 0x921, 0x93c, 0x0, 0x922, 0x93c, 0x0, 0x928,\n                0x93c, 0x0, 0x92b, 0x93c, 0x0, 0x92f, 0x93c, 0x0, 0x930, 0x93c,\n                0x0, 0x933, 0x93c, 0x0, 0x9a1, 0x9bc, 0x0, 0x9a2, 0x9bc, 0x0,\n                0x9af, 0x9bc, 0x0, 0x9c7, 0x9be, 0x0, 0x9c7, 0x9d7, 0x0, 0xa16,\n                0xa3c, 0x0, 0xa17, 0xa3c, 0x0, 0xa1c, 0xa3c, 0x0, 0xa2b, 0xa3c,\n                0x0, 0xa32, 0xa3c, 0x0, 0xa38, 0xa3c, 0x0, 0xb21, 0xb3c, 0x0,\n                0xb22, 0xb3c, 0x0, 0xb47, 0xb3e, 0x0, 0xb47, 0xb56, 0x0, 0xb47,\n                0xb57, 0x0, 0xb92, 0xbd7, 0x0, 0xbc6, 0xbbe, 0x0, 0xbc6, 0xbd7,\n                0x0, 0xbc7, 0xbbe, 0x0, 0xc46, 0xc56, 0x0, 0xcbf, 0xcd5, 0x0,\n                0xcc6, 0xcc2, 0x0, 0xcc6, 0xcc2, 0xcd5, 0x0, 0xcc6, 0xcd5, 0x0,\n                0xcc6, 0xcd6, 0x0, 0xd46, 0xd3e, 0x0, 0xd46, 0xd57, 0x0, 0xd47,\n                0xd3e, 0x0, 0xdd9, 0xdca, 0x0, 0xdd9, 0xdcf, 0x0, 0xdd9, 0xdcf,\n                0xdca, 0x0, 0xdd9, 0xddf, 0x0, 0xe4d, 0xe32, 0x0, 0xeab, 0xe99,\n                0x0, 0xeab, 0xea1, 0x0, 0xecd, 0xeb2, 0x0, 0xf0b, 0x0, 0xf40,\n                0xfb5, 0x0, 0xf42, 0xfb7, 0x0, 0xf4c, 0xfb7, 0x0, 0xf51, 0xfb7,\n                0x0, 0xf56, 0xfb7, 0x0, 0xf5b, 0xfb7, 0x0, 0xf71, 0xf72, 0x0,\n                0xf71, 0xf74, 0x0, 0xf71, 0xf80, 0x0, 0xf90, 0xfb5, 0x0, 0xf92,\n                0xfb7, 0x0, 0xf9c, 0xfb7, 0x0, 0xfa1, 0xfb7, 0x0, 0xfa6, 0xfb7,\n                0x0, 0xfab, 0xfb7, 0x0, 0xfb2, 0xf71, 0xf80, 0x0, 0xfb2, 0xf80,\n                0x0, 0xfb3, 0xf71, 0xf80, 0x0, 0xfb3, 0xf80, 0x0, 0x1025,\n                0x102e, 0x0, 0x10dc, 0x0, 0x1100, 0x0, 0x1100, 0x1161, 0x0,\n                0x1101, 0x0, 0x1102, 0x0, 0x1102, 0x1161, 0x0, 0x1103, 0x0,\n                0x1103, 0x1161, 0x0, 0x1104, 0x0, 0x1105, 0x0, 0x1105, 0x1161,\n                0x0, 0x1106, 0x0, 0x1106, 0x1161, 0x0, 0x1107, 0x0, 0x1107,\n                0x1161, 0x0, 0x1108, 0x0, 0x1109, 0x0, 0x1109, 0x1161, 0x0,\n                0x110a, 0x0, 0x110b, 0x0, 0x110b, 0x1161, 0x0, 0x110b, 0x116e,\n                0x0, 0x110c, 0x0, 0x110c, 0x1161, 0x0, 0x110c, 0x116e, 0x110b,\n                0x1174, 0x0, 0x110d, 0x0, 0x110e, 0x0, 0x110e, 0x1161, 0x0,\n                0x110e, 0x1161, 0x11b7, 0x1100, 0x1169, 0x0, 0x110f, 0x0,\n                0x110f, 0x1161, 0x0, 0x1110, 0x0, 0x1110, 0x1161, 0x0, 0x1111,\n                0x0, 0x1111, 0x1161, 0x0, 0x1112, 0x0, 0x1112, 0x1161, 0x0,\n                0x1114, 0x0, 0x1115, 0x0, 0x111a, 0x0, 0x111c, 0x0, 0x111d,\n                0x0, 0x111e, 0x0, 0x1120, 0x0, 0x1121, 0x0, 0x1122, 0x0,\n                0x1123, 0x0, 0x1127, 0x0, 0x1129, 0x0, 0x112b, 0x0, 0x112c,\n                0x0, 0x112d, 0x0, 0x112e, 0x0, 0x112f, 0x0, 0x1132, 0x0,\n                0x1136, 0x0, 0x1140, 0x0, 0x1147, 0x0, 0x114c, 0x0, 0x1157,\n                0x0, 0x1158, 0x0, 0x1159, 0x0, 0x1160, 0x0, 0x1161, 0x0,\n                0x1162, 0x0, 0x1163, 0x0, 0x1164, 0x0, 0x1165, 0x0, 0x1166,\n                0x0, 0x1167, 0x0, 0x1168, 0x0, 0x1169, 0x0, 0x116a, 0x0,\n                0x116b, 0x0, 0x116c, 0x0, 0x116d, 0x0, 0x116e, 0x0, 0x116f,\n                0x0, 0x1170, 0x0, 0x1171, 0x0, 0x1172, 0x0, 0x1173, 0x0,\n                0x1174, 0x0, 0x1175, 0x0, 0x1184, 0x0, 0x1185, 0x0, 0x1188,\n                0x0, 0x1191, 0x0, 0x1192, 0x0, 0x1194, 0x0, 0x119e, 0x0,\n                0x11a1, 0x0, 0x11aa, 0x0, 0x11ac, 0x0, 0x11ad, 0x0, 0x11b0,\n                0x0, 0x11b1, 0x0, 0x11b2, 0x0, 0x11b3, 0x0, 0x11b4, 0x0,\n                0x11b5, 0x0, 0x11c7, 0x0, 0x11c8, 0x0, 0x11cc, 0x0, 0x11ce,\n                0x0, 0x11d3, 0x0, 0x11d7, 0x0, 0x11d9, 0x0, 0x11dd, 0x0,\n                0x11df, 0x0, 0x11f1, 0x0, 0x11f2, 0x0, 0x1b05, 0x1b35, 0x0,\n                0x1b07, 0x1b35, 0x0, 0x1b09, 0x1b35, 0x0, 0x1b0b, 0x1b35, 0x0,\n                0x1b0d, 0x1b35, 0x0, 0x1b11, 0x1b35, 0x0, 0x1b3a, 0x1b35, 0x0,\n                0x1b3c, 0x1b35, 0x0, 0x1b3e, 0x1b35, 0x0, 0x1b3f, 0x1b35, 0x0,\n                0x1b42, 0x1b35, 0x0, 0x1d02, 0x0, 0x1d16, 0x0, 0x1d17, 0x0,\n                0x1d1c, 0x0, 0x1d1d, 0x0, 0x1d25, 0x0, 0x1d7b, 0x0, 0x1d85,\n                0x0, 0x2010, 0x0, 0x2013, 0x0, 0x2014, 0x0, 0x2032, 0x2032,\n                0x0, 0x2032, 0x2032, 0x2032, 0x0, 0x2032, 0x2032, 0x2032,\n                0x2032, 0x0, 0x2035, 0x2035, 0x0, 0x2035, 0x2035, 0x2035, 0x0,\n                0x20a9, 0x0, 0x2190, 0x0, 0x2190, 0x338, 0x0, 0x2191, 0x0,\n                0x2192, 0x0, 0x2192, 0x338, 0x0, 0x2193, 0x0, 0x2194, 0x338,\n                0x0, 0x21d0, 0x338, 0x0, 0x21d2, 0x338, 0x0, 0x21d4, 0x338,\n                0x0, 0x2202, 0x0, 0x2203, 0x338, 0x0, 0x2207, 0x0, 0x2208,\n                0x338, 0x0, 0x220b, 0x338, 0x0, 0x2211, 0x0, 0x2212, 0x0,\n                0x2223, 0x338, 0x0, 0x2225, 0x338, 0x0, 0x222b, 0x222b, 0x0,\n                0x222b, 0x222b, 0x222b, 0x0, 0x222b, 0x222b, 0x222b, 0x222b,\n                0x0, 0x222e, 0x222e, 0x0, 0x222e, 0x222e, 0x222e, 0x0, 0x223c,\n                0x338, 0x0, 0x2243, 0x338, 0x0, 0x2245, 0x338, 0x0, 0x2248,\n                0x338, 0x0, 0x224d, 0x338, 0x0, 0x2261, 0x338, 0x0, 0x2264,\n                0x338, 0x0, 0x2265, 0x338, 0x0, 0x2272, 0x338, 0x0, 0x2273,\n                0x338, 0x0, 0x2276, 0x338, 0x0, 0x2277, 0x338, 0x0, 0x227a,\n                0x338, 0x0, 0x227b, 0x338, 0x0, 0x227c, 0x338, 0x0, 0x227d,\n                0x338, 0x0, 0x2282, 0x338, 0x0, 0x2283, 0x338, 0x0, 0x2286,\n                0x338, 0x0, 0x2287, 0x338, 0x0, 0x2291, 0x338, 0x0, 0x2292,\n                0x338, 0x0, 0x22a2, 0x338, 0x0, 0x22a8, 0x338, 0x0, 0x22a9,\n                0x338, 0x0, 0x22ab, 0x338, 0x0, 0x22b2, 0x338, 0x0, 0x22b3,\n                0x338, 0x0, 0x22b4, 0x338, 0x0, 0x22b5, 0x338, 0x0, 0x2502,\n                0x0, 0x25a0, 0x0, 0x25cb, 0x0, 0x2985, 0x0, 0x2986, 0x0,\n                0x2add, 0x338, 0x0, 0x2d61, 0x0, 0x3001, 0x0, 0x3002, 0x0,\n                0x3008, 0x0, 0x3009, 0x0, 0x300a, 0x0, 0x300b, 0x0, 0x300c,\n                0x0, 0x300d, 0x0, 0x300e, 0x0, 0x300f, 0x0, 0x3010, 0x0,\n                0x3011, 0x0, 0x3012, 0x0, 0x3014, 0x0, 0x3014, 0x53, 0x3015,\n                0x0, 0x3014, 0x4e09, 0x3015, 0x0, 0x3014, 0x4e8c, 0x3015, 0x0,\n                0x3014, 0x52dd, 0x3015, 0x0, 0x3014, 0x5b89, 0x3015, 0x0,\n                0x3014, 0x6253, 0x3015, 0x0, 0x3014, 0x6557, 0x3015, 0x0,\n                0x3014, 0x672c, 0x3015, 0x0, 0x3014, 0x70b9, 0x3015, 0x0,\n                0x3014, 0x76d7, 0x3015, 0x0, 0x3015, 0x0, 0x3016, 0x0, 0x3017,\n                0x0, 0x3046, 0x3099, 0x0, 0x304b, 0x3099, 0x0, 0x304d, 0x3099,\n                0x0, 0x304f, 0x3099, 0x0, 0x3051, 0x3099, 0x0, 0x3053, 0x3099,\n                0x0, 0x3055, 0x3099, 0x0, 0x3057, 0x3099, 0x0, 0x3059, 0x3099,\n                0x0, 0x305b, 0x3099, 0x0, 0x305d, 0x3099, 0x0, 0x305f, 0x3099,\n                0x0, 0x3061, 0x3099, 0x0, 0x3064, 0x3099, 0x0, 0x3066, 0x3099,\n                0x0, 0x3068, 0x3099, 0x0, 0x306f, 0x3099, 0x0, 0x306f, 0x309a,\n                0x0, 0x3072, 0x3099, 0x0, 0x3072, 0x309a, 0x0, 0x3075, 0x3099,\n                0x0, 0x3075, 0x309a, 0x0, 0x3078, 0x3099, 0x0, 0x3078, 0x309a,\n                0x0, 0x307b, 0x304b, 0x0, 0x307b, 0x3099, 0x0, 0x307b, 0x309a,\n                0x0, 0x3088, 0x308a, 0x0, 0x3099, 0x0, 0x309a, 0x0, 0x309d,\n                0x3099, 0x0, 0x30a1, 0x0, 0x30a2, 0x0, 0x30a2, 0x30cf, 0x309a,\n                0x30fc, 0x30c8, 0x0, 0x30a2, 0x30eb, 0x30d5, 0x30a1, 0x0,\n                0x30a2, 0x30f3, 0x30d8, 0x309a, 0x30a2, 0x0, 0x30a2, 0x30fc,\n                0x30eb, 0x0, 0x30a3, 0x0, 0x30a4, 0x0, 0x30a4, 0x30cb, 0x30f3,\n                0x30af, 0x3099, 0x0, 0x30a4, 0x30f3, 0x30c1, 0x0, 0x30a5, 0x0,\n                0x30a6, 0x0, 0x30a6, 0x3099, 0x0, 0x30a6, 0x30a9, 0x30f3, 0x0,\n                0x30a7, 0x0, 0x30a8, 0x0, 0x30a8, 0x30b9, 0x30af, 0x30fc,\n                0x30c8, 0x3099, 0x0, 0x30a8, 0x30fc, 0x30ab, 0x30fc, 0x0,\n                0x30a9, 0x0, 0x30aa, 0x0, 0x30aa, 0x30f3, 0x30b9, 0x0, 0x30aa,\n                0x30fc, 0x30e0, 0x0, 0x30ab, 0x0, 0x30ab, 0x3099, 0x0, 0x30ab,\n                0x3099, 0x30ed, 0x30f3, 0x0, 0x30ab, 0x3099, 0x30f3, 0x30de,\n                0x0, 0x30ab, 0x30a4, 0x30ea, 0x0, 0x30ab, 0x30e9, 0x30c3,\n                0x30c8, 0x0, 0x30ab, 0x30ed, 0x30ea, 0x30fc, 0x0, 0x30ad, 0x0,\n                0x30ad, 0x3099, 0x0, 0x30ad, 0x3099, 0x30ab, 0x3099, 0x0,\n                0x30ad, 0x3099, 0x30cb, 0x30fc, 0x0, 0x30ad, 0x3099, 0x30eb,\n                0x30bf, 0x3099, 0x30fc, 0x0, 0x30ad, 0x30e5, 0x30ea, 0x30fc,\n                0x0, 0x30ad, 0x30ed, 0x0, 0x30ad, 0x30ed, 0x30af, 0x3099,\n                0x30e9, 0x30e0, 0x0, 0x30ad, 0x30ed, 0x30e1, 0x30fc, 0x30c8,\n                0x30eb, 0x0, 0x30ad, 0x30ed, 0x30ef, 0x30c3, 0x30c8, 0x0,\n                0x30af, 0x0, 0x30af, 0x3099, 0x0, 0x30af, 0x3099, 0x30e9,\n                0x30e0, 0x0, 0x30af, 0x3099, 0x30e9, 0x30e0, 0x30c8, 0x30f3,\n                0x0, 0x30af, 0x30eb, 0x30bb, 0x3099, 0x30a4, 0x30ed, 0x0,\n                0x30af, 0x30ed, 0x30fc, 0x30cd, 0x0, 0x30b1, 0x0, 0x30b1,\n                0x3099, 0x0, 0x30b1, 0x30fc, 0x30b9, 0x0, 0x30b3, 0x0, 0x30b3,\n                0x3099, 0x0, 0x30b3, 0x30b3, 0x0, 0x30b3, 0x30c8, 0x0, 0x30b3,\n                0x30eb, 0x30ca, 0x0, 0x30b3, 0x30fc, 0x30db, 0x309a, 0x0,\n                0x30b5, 0x0, 0x30b5, 0x3099, 0x0, 0x30b5, 0x30a4, 0x30af,\n                0x30eb, 0x0, 0x30b5, 0x30f3, 0x30c1, 0x30fc, 0x30e0, 0x0,\n                0x30b7, 0x0, 0x30b7, 0x3099, 0x0, 0x30b7, 0x30ea, 0x30f3,\n                0x30af, 0x3099, 0x0, 0x30b9, 0x0, 0x30b9, 0x3099, 0x0, 0x30bb,\n                0x0, 0x30bb, 0x3099, 0x0, 0x30bb, 0x30f3, 0x30c1, 0x0, 0x30bb,\n                0x30f3, 0x30c8, 0x0, 0x30bd, 0x0, 0x30bd, 0x3099, 0x0, 0x30bf,\n                0x0, 0x30bf, 0x3099, 0x0, 0x30bf, 0x3099, 0x30fc, 0x30b9, 0x0,\n                0x30c1, 0x0, 0x30c1, 0x3099, 0x0, 0x30c3, 0x0, 0x30c4, 0x0,\n                0x30c4, 0x3099, 0x0, 0x30c6, 0x0, 0x30c6, 0x3099, 0x0, 0x30c6,\n                0x3099, 0x30b7, 0x0, 0x30c8, 0x0, 0x30c8, 0x3099, 0x0, 0x30c8,\n                0x3099, 0x30eb, 0x0, 0x30c8, 0x30f3, 0x0, 0x30ca, 0x0, 0x30ca,\n                0x30ce, 0x0, 0x30cb, 0x0, 0x30cc, 0x0, 0x30cd, 0x0, 0x30ce,\n                0x0, 0x30ce, 0x30c3, 0x30c8, 0x0, 0x30cf, 0x0, 0x30cf, 0x3099,\n                0x0, 0x30cf, 0x3099, 0x30fc, 0x30ec, 0x30eb, 0x0, 0x30cf,\n                0x309a, 0x0, 0x30cf, 0x309a, 0x30fc, 0x30bb, 0x30f3, 0x30c8,\n                0x0, 0x30cf, 0x309a, 0x30fc, 0x30c4, 0x0, 0x30cf, 0x30a4,\n                0x30c4, 0x0, 0x30d2, 0x0, 0x30d2, 0x3099, 0x0, 0x30d2, 0x3099,\n                0x30eb, 0x0, 0x30d2, 0x309a, 0x0, 0x30d2, 0x309a, 0x30a2,\n                0x30b9, 0x30c8, 0x30eb, 0x0, 0x30d2, 0x309a, 0x30af, 0x30eb,\n                0x0, 0x30d2, 0x309a, 0x30b3, 0x0, 0x30d5, 0x0, 0x30d5, 0x3099,\n                0x0, 0x30d5, 0x3099, 0x30c3, 0x30b7, 0x30a7, 0x30eb, 0x0,\n                0x30d5, 0x309a, 0x0, 0x30d5, 0x30a1, 0x30e9, 0x30c3, 0x30c8,\n                0x3099, 0x0, 0x30d5, 0x30a3, 0x30fc, 0x30c8, 0x0, 0x30d5,\n                0x30e9, 0x30f3, 0x0, 0x30d8, 0x0, 0x30d8, 0x3099, 0x0, 0x30d8,\n                0x3099, 0x30fc, 0x30bf, 0x0, 0x30d8, 0x309a, 0x0, 0x30d8,\n                0x309a, 0x30bd, 0x0, 0x30d8, 0x309a, 0x30cb, 0x30d2, 0x0,\n                0x30d8, 0x309a, 0x30f3, 0x30b9, 0x0, 0x30d8, 0x309a, 0x30fc,\n                0x30b7, 0x3099, 0x0, 0x30d8, 0x30af, 0x30bf, 0x30fc, 0x30eb,\n                0x0, 0x30d8, 0x30eb, 0x30c4, 0x0, 0x30db, 0x0, 0x30db, 0x3099,\n                0x0, 0x30db, 0x3099, 0x30eb, 0x30c8, 0x0, 0x30db, 0x309a, 0x0,\n                0x30db, 0x309a, 0x30a4, 0x30f3, 0x30c8, 0x0, 0x30db, 0x309a,\n                0x30f3, 0x30c8, 0x3099, 0x0, 0x30db, 0x30f3, 0x0, 0x30db,\n                0x30fc, 0x30eb, 0x0, 0x30db, 0x30fc, 0x30f3, 0x0, 0x30de, 0x0,\n                0x30de, 0x30a4, 0x30af, 0x30ed, 0x0, 0x30de, 0x30a4, 0x30eb,\n                0x0, 0x30de, 0x30c3, 0x30cf, 0x0, 0x30de, 0x30eb, 0x30af, 0x0,\n                0x30de, 0x30f3, 0x30b7, 0x30e7, 0x30f3, 0x0, 0x30df, 0x0,\n                0x30df, 0x30af, 0x30ed, 0x30f3, 0x0, 0x30df, 0x30ea, 0x0,\n                0x30df, 0x30ea, 0x30cf, 0x3099, 0x30fc, 0x30eb, 0x0, 0x30e0,\n                0x0, 0x30e1, 0x0, 0x30e1, 0x30ab, 0x3099, 0x0, 0x30e1, 0x30ab,\n                0x3099, 0x30c8, 0x30f3, 0x0, 0x30e1, 0x30fc, 0x30c8, 0x30eb,\n                0x0, 0x30e2, 0x0, 0x30e3, 0x0, 0x30e4, 0x0, 0x30e4, 0x30fc,\n                0x30c8, 0x3099, 0x0, 0x30e4, 0x30fc, 0x30eb, 0x0, 0x30e5, 0x0,\n                0x30e6, 0x0, 0x30e6, 0x30a2, 0x30f3, 0x0, 0x30e7, 0x0, 0x30e8,\n                0x0, 0x30e9, 0x0, 0x30ea, 0x0, 0x30ea, 0x30c3, 0x30c8, 0x30eb,\n                0x0, 0x30ea, 0x30e9, 0x0, 0x30eb, 0x0, 0x30eb, 0x30d2, 0x309a,\n                0x30fc, 0x0, 0x30eb, 0x30fc, 0x30d5, 0x3099, 0x30eb, 0x0,\n                0x30ec, 0x0, 0x30ec, 0x30e0, 0x0, 0x30ec, 0x30f3, 0x30c8,\n                0x30b1, 0x3099, 0x30f3, 0x0, 0x30ed, 0x0, 0x30ef, 0x0, 0x30ef,\n                0x3099, 0x0, 0x30ef, 0x30c3, 0x30c8, 0x0, 0x30f0, 0x0, 0x30f0,\n                0x3099, 0x0, 0x30f1, 0x0, 0x30f1, 0x3099, 0x0, 0x30f2, 0x0,\n                0x30f2, 0x3099, 0x0, 0x30f3, 0x0, 0x30fb, 0x0, 0x30fc, 0x0,\n                0x30fd, 0x3099, 0x0, 0x349e, 0x0, 0x34b9, 0x0, 0x34bb, 0x0,\n                0x34df, 0x0, 0x3515, 0x0, 0x36ee, 0x0, 0x36fc, 0x0, 0x3781,\n                0x0, 0x382f, 0x0, 0x3862, 0x0, 0x387c, 0x0, 0x38c7, 0x0,\n                0x38e3, 0x0, 0x391c, 0x0, 0x393a, 0x0, 0x3a2e, 0x0, 0x3a6c,\n                0x0, 0x3ae4, 0x0, 0x3b08, 0x0, 0x3b19, 0x0, 0x3b49, 0x0,\n                0x3b9d, 0x0, 0x3c18, 0x0, 0x3c4e, 0x0, 0x3d33, 0x0, 0x3d96,\n                0x0, 0x3eac, 0x0, 0x3eb8, 0x0, 0x3f1b, 0x0, 0x3ffc, 0x0,\n                0x4008, 0x0, 0x4018, 0x0, 0x4039, 0x0, 0x4046, 0x0, 0x4096,\n                0x0, 0x40e3, 0x0, 0x412f, 0x0, 0x4202, 0x0, 0x4227, 0x0,\n                0x42a0, 0x0, 0x4301, 0x0, 0x4334, 0x0, 0x4359, 0x0, 0x43d5,\n                0x0, 0x43d9, 0x0, 0x440b, 0x0, 0x446b, 0x0, 0x452b, 0x0,\n                0x455d, 0x0, 0x4561, 0x0, 0x456b, 0x0, 0x45d7, 0x0, 0x45f9,\n                0x0, 0x4635, 0x0, 0x46be, 0x0, 0x46c7, 0x0, 0x4995, 0x0,\n                0x49e6, 0x0, 0x4a6e, 0x0, 0x4a76, 0x0, 0x4ab2, 0x0, 0x4b33,\n                0x0, 0x4bce, 0x0, 0x4cce, 0x0, 0x4ced, 0x0, 0x4cf8, 0x0,\n                0x4d56, 0x0, 0x4e00, 0x0, 0x4e01, 0x0, 0x4e03, 0x0, 0x4e09,\n                0x0, 0x4e0a, 0x0, 0x4e0b, 0x0, 0x4e0d, 0x0, 0x4e19, 0x0,\n                0x4e26, 0x0, 0x4e28, 0x0, 0x4e2d, 0x0, 0x4e32, 0x0, 0x4e36,\n                0x0, 0x4e38, 0x0, 0x4e39, 0x0, 0x4e3d, 0x0, 0x4e3f, 0x0,\n                0x4e41, 0x0, 0x4e59, 0x0, 0x4e5d, 0x0, 0x4e82, 0x0, 0x4e85,\n                0x0, 0x4e86, 0x0, 0x4e8c, 0x0, 0x4e94, 0x0, 0x4ea0, 0x0,\n                0x4ea4, 0x0, 0x4eae, 0x0, 0x4eba, 0x0, 0x4ec0, 0x0, 0x4ecc,\n                0x0, 0x4ee4, 0x0, 0x4f01, 0x0, 0x4f11, 0x0, 0x4f60, 0x0,\n                0x4f80, 0x0, 0x4f86, 0x0, 0x4f8b, 0x0, 0x4fae, 0x0, 0x4fbb,\n                0x0, 0x4fbf, 0x0, 0x5002, 0x0, 0x502b, 0x0, 0x507a, 0x0,\n                0x5099, 0x0, 0x50cf, 0x0, 0x50da, 0x0, 0x50e7, 0x0, 0x512a,\n                0x0, 0x513f, 0x0, 0x5140, 0x0, 0x5145, 0x0, 0x514d, 0x0,\n                0x5154, 0x0, 0x5164, 0x0, 0x5165, 0x0, 0x5167, 0x0, 0x5168,\n                0x0, 0x5169, 0x0, 0x516b, 0x0, 0x516d, 0x0, 0x5177, 0x0,\n                0x5180, 0x0, 0x5182, 0x0, 0x518d, 0x0, 0x5192, 0x0, 0x5195,\n                0x0, 0x5196, 0x0, 0x5197, 0x0, 0x5199, 0x0, 0x51a4, 0x0,\n                0x51ab, 0x0, 0x51ac, 0x0, 0x51b5, 0x0, 0x51b7, 0x0, 0x51c9,\n                0x0, 0x51cc, 0x0, 0x51dc, 0x0, 0x51de, 0x0, 0x51e0, 0x0,\n                0x51f5, 0x0, 0x5200, 0x0, 0x5203, 0x0, 0x5207, 0x0, 0x5217,\n                0x0, 0x521d, 0x0, 0x5229, 0x0, 0x523a, 0x0, 0x523b, 0x0,\n                0x5246, 0x0, 0x524d, 0x0, 0x5272, 0x0, 0x5277, 0x0, 0x5289,\n                0x0, 0x529b, 0x0, 0x52a3, 0x0, 0x52b3, 0x0, 0x52b4, 0x0,\n                0x52c7, 0x0, 0x52c9, 0x0, 0x52d2, 0x0, 0x52de, 0x0, 0x52e4,\n                0x0, 0x52f5, 0x0, 0x52f9, 0x0, 0x52fa, 0x0, 0x5305, 0x0,\n                0x5306, 0x0, 0x5315, 0x0, 0x5317, 0x0, 0x531a, 0x0, 0x5338,\n                0x0, 0x533b, 0x0, 0x533f, 0x0, 0x5341, 0x0, 0x5344, 0x0,\n                0x5345, 0x0, 0x5349, 0x0, 0x5351, 0x0, 0x5354, 0x0, 0x535a,\n                0x0, 0x535c, 0x0, 0x5369, 0x0, 0x5370, 0x0, 0x5373, 0x0,\n                0x5375, 0x0, 0x537d, 0x0, 0x537f, 0x0, 0x5382, 0x0, 0x53b6,\n                0x0, 0x53c3, 0x0, 0x53c8, 0x0, 0x53ca, 0x0, 0x53cc, 0x0,\n                0x53df, 0x0, 0x53e3, 0x0, 0x53e5, 0x0, 0x53eb, 0x0, 0x53ef,\n                0x0, 0x53f1, 0x0, 0x53f3, 0x0, 0x5406, 0x0, 0x5408, 0x0,\n                0x540d, 0x0, 0x540f, 0x0, 0x541d, 0x0, 0x5438, 0x0, 0x5439,\n                0x0, 0x5442, 0x0, 0x5448, 0x0, 0x5468, 0x0, 0x549e, 0x0,\n                0x54a2, 0x0, 0x54bd, 0x0, 0x54f6, 0x0, 0x5510, 0x0, 0x554f,\n                0x0, 0x5553, 0x0, 0x5555, 0x0, 0x5563, 0x0, 0x5584, 0x0,\n                0x5587, 0x0, 0x5599, 0x0, 0x559d, 0x0, 0x55ab, 0x0, 0x55b3,\n                0x0, 0x55b6, 0x0, 0x55c0, 0x0, 0x55c2, 0x0, 0x55e2, 0x0,\n                0x5606, 0x0, 0x5651, 0x0, 0x5668, 0x0, 0x5674, 0x0, 0x56d7,\n                0x0, 0x56db, 0x0, 0x56f9, 0x0, 0x5716, 0x0, 0x5717, 0x0,\n                0x571f, 0x0, 0x5730, 0x0, 0x578b, 0x0, 0x57ce, 0x0, 0x57f4,\n                0x0, 0x580d, 0x0, 0x5831, 0x0, 0x5832, 0x0, 0x5840, 0x0,\n                0x585a, 0x0, 0x585e, 0x0, 0x58a8, 0x0, 0x58ac, 0x0, 0x58b3,\n                0x0, 0x58d8, 0x0, 0x58df, 0x0, 0x58eb, 0x0, 0x58ee, 0x0,\n                0x58f0, 0x0, 0x58f2, 0x0, 0x58f7, 0x0, 0x5902, 0x0, 0x5906,\n                0x0, 0x590a, 0x0, 0x5915, 0x0, 0x591a, 0x0, 0x591c, 0x0,\n                0x5922, 0x0, 0x5927, 0x0, 0x5927, 0x6b63, 0x0, 0x5929, 0x0,\n                0x5944, 0x0, 0x5948, 0x0, 0x5951, 0x0, 0x5954, 0x0, 0x5962,\n                0x0, 0x5973, 0x0, 0x59d8, 0x0, 0x59ec, 0x0, 0x5a1b, 0x0,\n                0x5a27, 0x0, 0x5a62, 0x0, 0x5a66, 0x0, 0x5ab5, 0x0, 0x5b08,\n                0x0, 0x5b28, 0x0, 0x5b3e, 0x0, 0x5b50, 0x0, 0x5b57, 0x0,\n                0x5b66, 0x0, 0x5b80, 0x0, 0x5b85, 0x0, 0x5b97, 0x0, 0x5bc3,\n                0x0, 0x5bd8, 0x0, 0x5be7, 0x0, 0x5bee, 0x0, 0x5bf3, 0x0,\n                0x5bf8, 0x0, 0x5bff, 0x0, 0x5c06, 0x0, 0x5c0f, 0x0, 0x5c22,\n                0x0, 0x5c38, 0x0, 0x5c3f, 0x0, 0x5c60, 0x0, 0x5c62, 0x0,\n                0x5c64, 0x0, 0x5c65, 0x0, 0x5c6e, 0x0, 0x5c71, 0x0, 0x5c8d,\n                0x0, 0x5cc0, 0x0, 0x5d19, 0x0, 0x5d43, 0x0, 0x5d50, 0x0,\n                0x5d6b, 0x0, 0x5d6e, 0x0, 0x5d7c, 0x0, 0x5db2, 0x0, 0x5dba,\n                0x0, 0x5ddb, 0x0, 0x5de1, 0x0, 0x5de2, 0x0, 0x5de5, 0x0,\n                0x5de6, 0x0, 0x5df1, 0x0, 0x5dfd, 0x0, 0x5dfe, 0x0, 0x5e28,\n                0x0, 0x5e3d, 0x0, 0x5e69, 0x0, 0x5e72, 0x0, 0x5e73, 0x6210,\n                0x0, 0x5e74, 0x0, 0x5e7a, 0x0, 0x5e7c, 0x0, 0x5e7f, 0x0,\n                0x5ea6, 0x0, 0x5eb0, 0x0, 0x5eb3, 0x0, 0x5eb6, 0x0, 0x5ec9,\n                0x0, 0x5eca, 0x0, 0x5ed2, 0x0, 0x5ed3, 0x0, 0x5ed9, 0x0,\n                0x5eec, 0x0, 0x5ef4, 0x0, 0x5efe, 0x0, 0x5f04, 0x0, 0x5f0b,\n                0x0, 0x5f13, 0x0, 0x5f22, 0x0, 0x5f50, 0x0, 0x5f53, 0x0,\n                0x5f61, 0x0, 0x5f62, 0x0, 0x5f69, 0x0, 0x5f6b, 0x0, 0x5f73,\n                0x0, 0x5f8b, 0x0, 0x5f8c, 0x0, 0x5f97, 0x0, 0x5f9a, 0x0,\n                0x5fa9, 0x0, 0x5fad, 0x0, 0x5fc3, 0x0, 0x5fcd, 0x0, 0x5fd7,\n                0x0, 0x5ff5, 0x0, 0x5ff9, 0x0, 0x6012, 0x0, 0x601c, 0x0,\n                0x6075, 0x0, 0x6081, 0x0, 0x6094, 0x0, 0x60c7, 0x0, 0x60d8,\n                0x0, 0x60e1, 0x0, 0x6108, 0x0, 0x6144, 0x0, 0x6148, 0x0,\n                0x614c, 0x0, 0x614e, 0x0, 0x6160, 0x0, 0x6168, 0x0, 0x617a,\n                0x0, 0x618e, 0x0, 0x6190, 0x0, 0x61a4, 0x0, 0x61af, 0x0,\n                0x61b2, 0x0, 0x61de, 0x0, 0x61f2, 0x0, 0x61f6, 0x0, 0x6200,\n                0x0, 0x6208, 0x0, 0x6210, 0x0, 0x621b, 0x0, 0x622e, 0x0,\n                0x6234, 0x0, 0x6236, 0x0, 0x624b, 0x0, 0x6253, 0x0, 0x625d,\n                0x0, 0x6295, 0x0, 0x62b1, 0x0, 0x62c9, 0x0, 0x62cf, 0x0,\n                0x62d3, 0x0, 0x62d4, 0x0, 0x62fc, 0x0, 0x62fe, 0x0, 0x6307,\n                0x0, 0x633d, 0x0, 0x6350, 0x0, 0x6355, 0x0, 0x6368, 0x0,\n                0x637b, 0x0, 0x6383, 0x0, 0x63a0, 0x0, 0x63a9, 0x0, 0x63c4,\n                0x0, 0x63c5, 0x0, 0x63e4, 0x0, 0x641c, 0x0, 0x6422, 0x0,\n                0x6452, 0x0, 0x6469, 0x0, 0x6477, 0x0, 0x647e, 0x0, 0x649a,\n                0x0, 0x649d, 0x0, 0x64c4, 0x0, 0x652f, 0x0, 0x6534, 0x0,\n                0x654f, 0x0, 0x6556, 0x0, 0x656c, 0x0, 0x6578, 0x0, 0x6587,\n                0x0, 0x6597, 0x0, 0x6599, 0x0, 0x65a4, 0x0, 0x65b0, 0x0,\n                0x65b9, 0x0, 0x65c5, 0x0, 0x65e0, 0x0, 0x65e2, 0x0, 0x65e3,\n                0x0, 0x65e5, 0x0, 0x660e, 0x6cbb, 0x0, 0x6613, 0x0, 0x6620,\n                0x0, 0x662d, 0x548c, 0x0, 0x6649, 0x0, 0x6674, 0x0, 0x6688,\n                0x0, 0x6691, 0x0, 0x669c, 0x0, 0x66b4, 0x0, 0x66c6, 0x0,\n                0x66f0, 0x0, 0x66f4, 0x0, 0x66f8, 0x0, 0x6700, 0x0, 0x6708,\n                0x0, 0x6709, 0x0, 0x6717, 0x0, 0x671b, 0x0, 0x6721, 0x0,\n                0x6728, 0x0, 0x674e, 0x0, 0x6753, 0x0, 0x6756, 0x0, 0x675e,\n                0x0, 0x677b, 0x0, 0x6785, 0x0, 0x6797, 0x0, 0x67f3, 0x0,\n                0x67fa, 0x0, 0x6817, 0x0, 0x681f, 0x0, 0x682a, 0x0, 0x682a,\n                0x5f0f, 0x4f1a, 0x793e, 0x0, 0x6852, 0x0, 0x6881, 0x0, 0x6885,\n                0x0, 0x688e, 0x0, 0x68a8, 0x0, 0x6914, 0x0, 0x6942, 0x0,\n                0x69a3, 0x0, 0x69ea, 0x0, 0x6a02, 0x0, 0x6a13, 0x0, 0x6aa8,\n                0x0, 0x6ad3, 0x0, 0x6adb, 0x0, 0x6b04, 0x0, 0x6b20, 0x0,\n                0x6b21, 0x0, 0x6b54, 0x0, 0x6b62, 0x0, 0x6b63, 0x0, 0x6b72,\n                0x0, 0x6b77, 0x0, 0x6b79, 0x0, 0x6b9f, 0x0, 0x6bae, 0x0,\n                0x6bb3, 0x0, 0x6bba, 0x0, 0x6bbb, 0x0, 0x6bcb, 0x0, 0x6bcd,\n                0x0, 0x6bd4, 0x0, 0x6bdb, 0x0, 0x6c0f, 0x0, 0x6c14, 0x0,\n                0x6c34, 0x0, 0x6c4e, 0x0, 0x6c67, 0x0, 0x6c88, 0x0, 0x6cbf,\n                0x0, 0x6ccc, 0x0, 0x6ccd, 0x0, 0x6ce5, 0x0, 0x6ce8, 0x0,\n                0x6d16, 0x0, 0x6d1b, 0x0, 0x6d1e, 0x0, 0x6d34, 0x0, 0x6d3e,\n                0x0, 0x6d41, 0x0, 0x6d69, 0x0, 0x6d6a, 0x0, 0x6d77, 0x0,\n                0x6d78, 0x0, 0x6d85, 0x0, 0x6dcb, 0x0, 0x6dda, 0x0, 0x6dea,\n                0x0, 0x6df9, 0x0, 0x6e1a, 0x0, 0x6e2f, 0x0, 0x6e6e, 0x0,\n                0x6e80, 0x0, 0x6e9c, 0x0, 0x6eba, 0x0, 0x6ec7, 0x0, 0x6ecb,\n                0x0, 0x6ed1, 0x0, 0x6edb, 0x0, 0x6f0f, 0x0, 0x6f14, 0x0,\n                0x6f22, 0x0, 0x6f23, 0x0, 0x6f6e, 0x0, 0x6fc6, 0x0, 0x6feb,\n                0x0, 0x6ffe, 0x0, 0x701b, 0x0, 0x701e, 0x0, 0x7039, 0x0,\n                0x704a, 0x0, 0x706b, 0x0, 0x7070, 0x0, 0x7077, 0x0, 0x707d,\n                0x0, 0x7099, 0x0, 0x70ad, 0x0, 0x70c8, 0x0, 0x70d9, 0x0,\n                0x7121, 0x0, 0x7145, 0x0, 0x7149, 0x0, 0x716e, 0x0, 0x719c,\n                0x0, 0x71ce, 0x0, 0x71d0, 0x0, 0x7210, 0x0, 0x721b, 0x0,\n                0x7228, 0x0, 0x722a, 0x0, 0x722b, 0x0, 0x7235, 0x0, 0x7236,\n                0x0, 0x723b, 0x0, 0x723f, 0x0, 0x7247, 0x0, 0x7250, 0x0,\n                0x7259, 0x0, 0x725b, 0x0, 0x7262, 0x0, 0x7279, 0x0, 0x7280,\n                0x0, 0x7295, 0x0, 0x72ac, 0x0, 0x72af, 0x0, 0x72c0, 0x0,\n                0x72fc, 0x0, 0x732a, 0x0, 0x7375, 0x0, 0x737a, 0x0, 0x7384,\n                0x0, 0x7387, 0x0, 0x7389, 0x0, 0x738b, 0x0, 0x73a5, 0x0,\n                0x73b2, 0x0, 0x73de, 0x0, 0x7406, 0x0, 0x7409, 0x0, 0x7422,\n                0x0, 0x7447, 0x0, 0x745c, 0x0, 0x7469, 0x0, 0x7471, 0x0,\n                0x7485, 0x0, 0x7489, 0x0, 0x7498, 0x0, 0x74ca, 0x0, 0x74dc,\n                0x0, 0x74e6, 0x0, 0x7506, 0x0, 0x7518, 0x0, 0x751f, 0x0,\n                0x7524, 0x0, 0x7528, 0x0, 0x7530, 0x0, 0x7532, 0x0, 0x7533,\n                0x0, 0x7537, 0x0, 0x753b, 0x0, 0x753e, 0x0, 0x7559, 0x0,\n                0x7565, 0x0, 0x7570, 0x0, 0x758b, 0x0, 0x7592, 0x0, 0x75e2,\n                0x0, 0x7610, 0x0, 0x761d, 0x0, 0x761f, 0x0, 0x7642, 0x0,\n                0x7669, 0x0, 0x7676, 0x0, 0x767d, 0x0, 0x76ae, 0x0, 0x76bf,\n                0x0, 0x76ca, 0x0, 0x76db, 0x0, 0x76e3, 0x0, 0x76e7, 0x0,\n                0x76ee, 0x0, 0x76f4, 0x0, 0x7701, 0x0, 0x771e, 0x0, 0x771f,\n                0x0, 0x7740, 0x0, 0x774a, 0x0, 0x778b, 0x0, 0x77a7, 0x0,\n                0x77db, 0x0, 0x77e2, 0x0, 0x77f3, 0x0, 0x784e, 0x0, 0x786b,\n                0x0, 0x788c, 0x0, 0x7891, 0x0, 0x78ca, 0x0, 0x78cc, 0x0,\n                0x78fb, 0x0, 0x792a, 0x0, 0x793a, 0x0, 0x793c, 0x0, 0x793e,\n                0x0, 0x7948, 0x0, 0x7949, 0x0, 0x7950, 0x0, 0x7956, 0x0,\n                0x795d, 0x0, 0x795e, 0x0, 0x7965, 0x0, 0x797f, 0x0, 0x7981,\n                0x0, 0x798d, 0x0, 0x798e, 0x0, 0x798f, 0x0, 0x79ae, 0x0,\n                0x79b8, 0x0, 0x79be, 0x0, 0x79ca, 0x0, 0x79d8, 0x0, 0x79eb,\n                0x0, 0x7a1c, 0x0, 0x7a40, 0x0, 0x7a4a, 0x0, 0x7a4f, 0x0,\n                0x7a74, 0x0, 0x7a7a, 0x0, 0x7a81, 0x0, 0x7ab1, 0x0, 0x7acb,\n                0x0, 0x7aee, 0x0, 0x7af9, 0x0, 0x7b20, 0x0, 0x7b8f, 0x0,\n                0x7bc0, 0x0, 0x7bc6, 0x0, 0x7bc9, 0x0, 0x7c3e, 0x0, 0x7c60,\n                0x0, 0x7c73, 0x0, 0x7c7b, 0x0, 0x7c92, 0x0, 0x7cbe, 0x0,\n                0x7cd2, 0x0, 0x7cd6, 0x0, 0x7ce3, 0x0, 0x7ce7, 0x0, 0x7ce8,\n                0x0, 0x7cf8, 0x0, 0x7d00, 0x0, 0x7d10, 0x0, 0x7d22, 0x0,\n                0x7d2f, 0x0, 0x7d42, 0x0, 0x7d5b, 0x0, 0x7d63, 0x0, 0x7da0,\n                0x0, 0x7dbe, 0x0, 0x7dc7, 0x0, 0x7df4, 0x0, 0x7e02, 0x0,\n                0x7e09, 0x0, 0x7e37, 0x0, 0x7e41, 0x0, 0x7e45, 0x0, 0x7f36,\n                0x0, 0x7f3e, 0x0, 0x7f51, 0x0, 0x7f72, 0x0, 0x7f79, 0x0,\n                0x7f7a, 0x0, 0x7f85, 0x0, 0x7f8a, 0x0, 0x7f95, 0x0, 0x7f9a,\n                0x0, 0x7fbd, 0x0, 0x7ffa, 0x0, 0x8001, 0x0, 0x8005, 0x0,\n                0x800c, 0x0, 0x8012, 0x0, 0x8033, 0x0, 0x8046, 0x0, 0x8060,\n                0x0, 0x806f, 0x0, 0x8070, 0x0, 0x807e, 0x0, 0x807f, 0x0,\n                0x8089, 0x0, 0x808b, 0x0, 0x80ad, 0x0, 0x80b2, 0x0, 0x8103,\n                0x0, 0x813e, 0x0, 0x81d8, 0x0, 0x81e3, 0x0, 0x81e8, 0x0,\n                0x81ea, 0x0, 0x81ed, 0x0, 0x81f3, 0x0, 0x81fc, 0x0, 0x8201,\n                0x0, 0x8204, 0x0, 0x820c, 0x0, 0x8218, 0x0, 0x821b, 0x0,\n                0x821f, 0x0, 0x826e, 0x0, 0x826f, 0x0, 0x8272, 0x0, 0x8278,\n                0x0, 0x8279, 0x0, 0x828b, 0x0, 0x8291, 0x0, 0x829d, 0x0,\n                0x82b1, 0x0, 0x82b3, 0x0, 0x82bd, 0x0, 0x82e5, 0x0, 0x82e6,\n                0x0, 0x831d, 0x0, 0x8323, 0x0, 0x8336, 0x0, 0x8352, 0x0,\n                0x8353, 0x0, 0x8363, 0x0, 0x83ad, 0x0, 0x83bd, 0x0, 0x83c9,\n                0x0, 0x83ca, 0x0, 0x83cc, 0x0, 0x83dc, 0x0, 0x83e7, 0x0,\n                0x83ef, 0x0, 0x83f1, 0x0, 0x843d, 0x0, 0x8449, 0x0, 0x8457,\n                0x0, 0x84ee, 0x0, 0x84f1, 0x0, 0x84f3, 0x0, 0x84fc, 0x0,\n                0x8516, 0x0, 0x8564, 0x0, 0x85cd, 0x0, 0x85fa, 0x0, 0x8606,\n                0x0, 0x8612, 0x0, 0x862d, 0x0, 0x863f, 0x0, 0x864d, 0x0,\n                0x8650, 0x0, 0x865c, 0x0, 0x8667, 0x0, 0x8669, 0x0, 0x866b,\n                0x0, 0x8688, 0x0, 0x86a9, 0x0, 0x86e2, 0x0, 0x870e, 0x0,\n                0x8728, 0x0, 0x876b, 0x0, 0x8779, 0x0, 0x8786, 0x0, 0x87ba,\n                0x0, 0x87e1, 0x0, 0x8801, 0x0, 0x881f, 0x0, 0x8840, 0x0,\n                0x884c, 0x0, 0x8860, 0x0, 0x8863, 0x0, 0x88c2, 0x0, 0x88cf,\n                0x0, 0x88d7, 0x0, 0x88de, 0x0, 0x88e1, 0x0, 0x88f8, 0x0,\n                0x88fa, 0x0, 0x8910, 0x0, 0x8941, 0x0, 0x8964, 0x0, 0x897e,\n                0x0, 0x8986, 0x0, 0x898b, 0x0, 0x8996, 0x0, 0x89d2, 0x0,\n                0x89e3, 0x0, 0x8a00, 0x0, 0x8aa0, 0x0, 0x8aaa, 0x0, 0x8abf,\n                0x0, 0x8acb, 0x0, 0x8ad2, 0x0, 0x8ad6, 0x0, 0x8aed, 0x0,\n                0x8af8, 0x0, 0x8afe, 0x0, 0x8b01, 0x0, 0x8b39, 0x0, 0x8b58,\n                0x0, 0x8b80, 0x0, 0x8b8a, 0x0, 0x8c37, 0x0, 0x8c46, 0x0,\n                0x8c48, 0x0, 0x8c55, 0x0, 0x8c78, 0x0, 0x8c9d, 0x0, 0x8ca1,\n                0x0, 0x8ca9, 0x0, 0x8cab, 0x0, 0x8cc1, 0x0, 0x8cc2, 0x0,\n                0x8cc7, 0x0, 0x8cc8, 0x0, 0x8cd3, 0x0, 0x8d08, 0x0, 0x8d1b,\n                0x0, 0x8d64, 0x0, 0x8d70, 0x0, 0x8d77, 0x0, 0x8db3, 0x0,\n                0x8dbc, 0x0, 0x8dcb, 0x0, 0x8def, 0x0, 0x8df0, 0x0, 0x8eab,\n                0x0, 0x8eca, 0x0, 0x8ed4, 0x0, 0x8f26, 0x0, 0x8f2a, 0x0,\n                0x8f38, 0x0, 0x8f3b, 0x0, 0x8f62, 0x0, 0x8f9b, 0x0, 0x8f9e,\n                0x0, 0x8fb0, 0x0, 0x8fb5, 0x0, 0x8fb6, 0x0, 0x9023, 0x0,\n                0x9038, 0x0, 0x904a, 0x0, 0x9069, 0x0, 0x9072, 0x0, 0x907c,\n                0x0, 0x908f, 0x0, 0x9091, 0x0, 0x9094, 0x0, 0x90ce, 0x0,\n                0x90de, 0x0, 0x90f1, 0x0, 0x90fd, 0x0, 0x9111, 0x0, 0x911b,\n                0x0, 0x9149, 0x0, 0x916a, 0x0, 0x9199, 0x0, 0x91b4, 0x0,\n                0x91c6, 0x0, 0x91cc, 0x0, 0x91cf, 0x0, 0x91d1, 0x0, 0x9234,\n                0x0, 0x9238, 0x0, 0x9276, 0x0, 0x927c, 0x0, 0x92d7, 0x0,\n                0x92d8, 0x0, 0x9304, 0x0, 0x934a, 0x0, 0x93f9, 0x0, 0x9415,\n                0x0, 0x9577, 0x0, 0x9580, 0x0, 0x958b, 0x0, 0x95ad, 0x0,\n                0x95b7, 0x0, 0x961c, 0x0, 0x962e, 0x0, 0x964b, 0x0, 0x964d,\n                0x0, 0x9675, 0x0, 0x9678, 0x0, 0x967c, 0x0, 0x9686, 0x0,\n                0x96a3, 0x0, 0x96b6, 0x0, 0x96b7, 0x0, 0x96b8, 0x0, 0x96b9,\n                0x0, 0x96c3, 0x0, 0x96e2, 0x0, 0x96e3, 0x0, 0x96e8, 0x0,\n                0x96f6, 0x0, 0x96f7, 0x0, 0x9723, 0x0, 0x9732, 0x0, 0x9748,\n                0x0, 0x9751, 0x0, 0x9756, 0x0, 0x975e, 0x0, 0x9762, 0x0,\n                0x9769, 0x0, 0x97cb, 0x0, 0x97db, 0x0, 0x97e0, 0x0, 0x97ed,\n                0x0, 0x97f3, 0x0, 0x97ff, 0x0, 0x9801, 0x0, 0x9805, 0x0,\n                0x980b, 0x0, 0x9818, 0x0, 0x9829, 0x0, 0x983b, 0x0, 0x985e,\n                0x0, 0x98a8, 0x0, 0x98db, 0x0, 0x98df, 0x0, 0x98e2, 0x0,\n                0x98ef, 0x0, 0x98fc, 0x0, 0x9928, 0x0, 0x9929, 0x0, 0x9996,\n                0x0, 0x9999, 0x0, 0x99a7, 0x0, 0x99ac, 0x0, 0x99c2, 0x0,\n                0x99f1, 0x0, 0x99fe, 0x0, 0x9a6a, 0x0, 0x9aa8, 0x0, 0x9ad8,\n                0x0, 0x9adf, 0x0, 0x9b12, 0x0, 0x9b25, 0x0, 0x9b2f, 0x0,\n                0x9b32, 0x0, 0x9b3c, 0x0, 0x9b5a, 0x0, 0x9b6f, 0x0, 0x9c40,\n                0x0, 0x9c57, 0x0, 0x9ce5, 0x0, 0x9cfd, 0x0, 0x9d67, 0x0,\n                0x9db4, 0x0, 0x9dfa, 0x0, 0x9e1e, 0x0, 0x9e75, 0x0, 0x9e7f,\n                0x0, 0x9e97, 0x0, 0x9e9f, 0x0, 0x9ea5, 0x0, 0x9ebb, 0x0,\n                0x9ec3, 0x0, 0x9ecd, 0x0, 0x9ece, 0x0, 0x9ed1, 0x0, 0x9ef9,\n                0x0, 0x9efd, 0x0, 0x9efe, 0x0, 0x9f05, 0x0, 0x9f0e, 0x0,\n                0x9f0f, 0x0, 0x9f13, 0x0, 0x9f16, 0x0, 0x9f20, 0x0, 0x9f3b,\n                0x0, 0x9f43, 0x0, 0x9f4a, 0x0, 0x9f52, 0x0, 0x9f8d, 0x0,\n                0x9f8e, 0x0, 0x9f9c, 0x0, 0x9f9f, 0x0, 0x9fa0, 0x0, 0xa76f,\n                0x0, 0x11099, 0x110ba, 0x0, 0x1109b, 0x110ba, 0x0, 0x110a5,\n                0x110ba, 0x0, 0x11131, 0x11127, 0x0, 0x11132, 0x11127, 0x0,\n                0x1d157, 0x1d165, 0x0, 0x1d158, 0x1d165, 0x0, 0x1d158, 0x1d165,\n                0x1d16e, 0x0, 0x1d158, 0x1d165, 0x1d16f, 0x0, 0x1d158, 0x1d165,\n                0x1d170, 0x0, 0x1d158, 0x1d165, 0x1d171, 0x0, 0x1d158, 0x1d165,\n                0x1d172, 0x0, 0x1d1b9, 0x1d165, 0x0, 0x1d1b9, 0x1d165, 0x1d16e,\n                0x0, 0x1d1b9, 0x1d165, 0x1d16f, 0x0, 0x1d1ba, 0x1d165, 0x0,\n                0x1d1ba, 0x1d165, 0x1d16e, 0x0, 0x1d1ba, 0x1d165, 0x1d16f, 0x0,\n                0x20122, 0x0, 0x2051c, 0x0, 0x20525, 0x0, 0x2054b, 0x0,\n                0x2063a, 0x0, 0x20804, 0x0, 0x208de, 0x0, 0x20a2c, 0x0,\n                0x20b63, 0x0, 0x214e4, 0x0, 0x216a8, 0x0, 0x216ea, 0x0,\n                0x219c8, 0x0, 0x21b18, 0x0, 0x21d0b, 0x0, 0x21de4, 0x0,\n                0x21de6, 0x0, 0x22183, 0x0, 0x2219f, 0x0, 0x22331, 0x0,\n                0x226d4, 0x0, 0x22844, 0x0, 0x2284a, 0x0, 0x22b0c, 0x0,\n                0x22bf1, 0x0, 0x2300a, 0x0, 0x232b8, 0x0, 0x2335f, 0x0,\n                0x23393, 0x0, 0x2339c, 0x0, 0x233c3, 0x0, 0x233d5, 0x0,\n                0x2346d, 0x0, 0x236a3, 0x0, 0x238a7, 0x0, 0x23a8d, 0x0,\n                0x23afa, 0x0, 0x23cbc, 0x0, 0x23d1e, 0x0, 0x23ed1, 0x0,\n                0x23f5e, 0x0, 0x23f8e, 0x0, 0x24263, 0x0, 0x242ee, 0x0,\n                0x243ab, 0x0, 0x24608, 0x0, 0x24735, 0x0, 0x24814, 0x0,\n                0x24c36, 0x0, 0x24c92, 0x0, 0x24fa1, 0x0, 0x24fb8, 0x0,\n                0x25044, 0x0, 0x250f2, 0x0, 0x250f3, 0x0, 0x25119, 0x0,\n                0x25133, 0x0, 0x25249, 0x0, 0x2541d, 0x0, 0x25626, 0x0,\n                0x2569a, 0x0, 0x256c5, 0x0, 0x2597c, 0x0, 0x25aa7, 0x0,\n                0x25bab, 0x0, 0x25c80, 0x0, 0x25cd0, 0x0, 0x25f86, 0x0,\n                0x261da, 0x0, 0x26228, 0x0, 0x26247, 0x0, 0x262d9, 0x0,\n                0x2633e, 0x0, 0x264da, 0x0, 0x26523, 0x0, 0x265a8, 0x0,\n                0x267a7, 0x0, 0x267b5, 0x0, 0x26b3c, 0x0, 0x26c36, 0x0,\n                0x26cd5, 0x0, 0x26d6b, 0x0, 0x26f2c, 0x0, 0x26fb1, 0x0,\n                0x270d2, 0x0, 0x273ca, 0x0, 0x27667, 0x0, 0x278ae, 0x0,\n                0x27966, 0x0, 0x27ca8, 0x0, 0x27ed3, 0x0, 0x27f2f, 0x0,\n                0x285d2, 0x0, 0x285ed, 0x0, 0x2872e, 0x0, 0x28bfa, 0x0,\n                0x28d77, 0x0, 0x29145, 0x0, 0x291df, 0x0, 0x2921a, 0x0,\n                0x2940a, 0x0, 0x29496, 0x0, 0x295b6, 0x0, 0x29b30, 0x0,\n                0x2a0ce, 0x0, 0x2a105, 0x0, 0x2a20e, 0x0, 0x2a291, 0x0,\n                0x2a392, 0x0, 0x2a600, 0x0\n            ];\n            return t;\n        }\n    }\n\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/unicode_grapheme.d",
    "content": "module std.internal.unicode_grapheme;\nimport std.internal.unicode_tables;\n\npackage(std):\n\nstatic if (size_t.sizeof == 8)\n{\n    //832 bytes\n    enum hangulLVTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0x40],\n            [0x100, 0x80, 0xa00], [0x2010000000000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x4000300020001, 0x1000700060005, 0x5000400030002, 0x2000100070006,\n            0x6000500040003, 0x3000200010007, 0x7000600050004, 0x4000300020001,\n            0x1000700060005, 0x5000400030002, 0x8000100070006, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x100000010000001, 0x1000000100000, 0x10000001000,\n            0x1000000100000010, 0x10000001000000, 0x100000010000, 0x1000000100,\n            0x100000010000001, 0x1000000100000, 0x10000001000,\n            0x1000000100000010, 0x10000001000000, 0x100000010000, 0x1000000100,\n            0x100000010000001, 0x1000000100000, 0x10000001000,\n            0x1000000100000010, 0x10000001000000, 0x100000010000, 0x1000000100,\n            0x100000010000001, 0x1000000100000, 0x10000001000,\n            0x1000000100000010, 0x10000001000000, 0x100000010000, 0x1000000100,\n            0x10000001000000, 0x100000010000, 0x100, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    //832 bytes\n    enum hangulLVTTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0x40],\n            [0x100, 0x80, 0xa00], [0x2010000000000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x4000300020001, 0x1000700060005, 0x5000400030002, 0x2000100070006,\n            0x6000500040003, 0x3000200010007, 0x7000600050004, 0x4000300020001,\n            0x1000700060005, 0x5000400030002, 0x8000100070006, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xfeffffffeffffffe, 0xfffeffffffefffff, 0xfffffeffffffefff,\n            0xeffffffeffffffef, 0xffeffffffeffffff, 0xffffeffffffeffff,\n            0xffffffeffffffeff, 0xfeffffffeffffffe, 0xfffeffffffefffff,\n            0xfffffeffffffefff, 0xeffffffeffffffef, 0xffeffffffeffffff,\n            0xffffeffffffeffff, 0xffffffeffffffeff, 0xfeffffffeffffffe,\n            0xfffeffffffefffff, 0xfffffeffffffefff, 0xeffffffeffffffef,\n            0xffeffffffeffffff, 0xffffeffffffeffff, 0xffffffeffffffeff,\n            0xfeffffffeffffffe, 0xfffeffffffefffff, 0xfffffeffffffefff,\n            0xeffffffeffffffef, 0xffeffffffeffffff, 0xffffeffffffeffff,\n            0xffffffeffffffeff, 0xffeffffffeffffff, 0xffffeffffffeffff,\n            0xffffffeff, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    //1536 bytes\n    enum mcTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0x60], [0x100,\n            0x100, 0x1800], [0x202030202020100, 0x206020205020204,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x3000200010000, 0x6000000050004, 0x7, 0x8000000000000,\n            0xb000a00090000, 0xc, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x110010000f000e, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x130012, 0x1400000000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x15000000000000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x160000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc800000000000008, 0xde01,\n            0xc00000000000000c, 0x801981, 0xc000000000000008, 0x1,\n            0xc000000000000008, 0x1a01, 0x400000000000000c, 0x801981,\n            0xc000000000000000, 0x801dc6, 0xe, 0x1e, 0x400000000000000c,\n            0x600d9f, 0xc00000000000000c, 0x801dc1, 0xc, 0xc0000ff038000,\n            0xc000000000000000, 0x8000000000000000, 0x0, 0x0,\n            0x1902180000000000, 0x3f9c00c00000, 0x1c009f98, 0x0, 0x0, 0x0,\n            0xc040000000000000, 0x1bf, 0x1fb0e7800000000, 0x0,\n            0xffff000000000000, 0x301, 0x6000000, 0x7e01a00a00000, 0x0, 0x0,\n            0xe820000000000010, 0x1b, 0x34c200000004, 0xc5c8000000000,\n            0x300ff000000000, 0x0, 0x0, 0xc000200000000, 0xc00000000000, 0x0,\n            0x0, 0x0, 0x9800000000, 0x0, 0xfff0000000000003, 0xf, 0x0, 0xc0000,\n            0xec30000000000008, 0x1, 0x19800000000000, 0x800000000002000, 0x0,\n            0x20c80000000000, 0x0, 0x0, 0x0, 0x16d800000000, 0x5, 0x0,\n            0x187000000000004, 0x0, 0x100000000000, 0x0, 0x8038000000000004,\n            0x1, 0x0, 0x0, 0x40d00000000000, 0x0, 0x0, 0x7ffffffffffe0000, 0x0,\n            0x0, 0x0, 0x7e06000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    //2336 bytes\n    enum graphemeExtendTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20,\n            0x70], [0x100, 0x140, 0x2d00], [0x402030202020100,\n            0x207020206020205, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020208, 0x202020202020202,\n            0x202020202020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000, 0x5000400030002,\n            0x9000800070006, 0xd000c000b000a, 0xf00000000000e,\n            0x10000000000000, 0x14001300120011, 0x160015, 0x17, 0x0, 0x0,\n            0x190018, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x1b00000000, 0x1f001e001d001c, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000000, 0x22002100000000,\n            0x230000, 0x0, 0x2400000000, 0x0, 0x260025, 0x2700000000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x28000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x2a00290000, 0x0, 0x0, 0x0, 0x2b0000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xffffffffffffffff, 0xffffffffffff, 0x0, 0x0, 0x0, 0x0,\n            0x3f8, 0x0, 0x0, 0x0, 0xbffffffffffe0000, 0xb6, 0x7ff0000,\n            0x10000fffff800, 0x0, 0x3d9f9fc00000, 0xffff000000020000, 0x7ff,\n            0x1ffc000000000, 0xff80000000000, 0x3eeffbc00000, 0xe000000, 0x0,\n            0x7ffffff000000000, 0x1400000000000007, 0xc00fe21fe,\n            0x5000000000000002, 0xc0080201e, 0x1000000000000006,\n            0x23000000023986, 0x1000000000000006, 0xc000021be,\n            0xd000000000000002, 0xc00c0201e, 0x4000000000000004, 0x802001,\n            0xc000000000000000, 0xc00603dc1, 0x9000000000000000, 0xc00603044,\n            0x4000000000000000, 0xc0080201e, 0x0, 0x805c8400,\n            0x7f2000000000000, 0x7f80, 0x1bf2000000000000, 0x3f00,\n            0x2a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df, 0x40,\n            0x66fde00000000000, 0x1e0001c3000000, 0x20002064, 0x0, 0x0,\n            0xe0000000, 0x0, 0x0, 0x1c0000001c0000, 0xc0000000c0000,\n            0x3fb0000000000000, 0x200ffe40, 0x3800, 0x0, 0x20000000000, 0x0,\n            0xe04018700000000, 0x0, 0x0, 0x0, 0x9800000, 0x9ff81fe57f400000,\n            0x0, 0x0, 0x17d000000000000f, 0xff80000000004, 0xb3c00000003,\n            0x3a34000000000, 0xcff00000000000, 0x0, 0x0, 0x1021fdfff70000, 0x0,\n            0x0, 0x0, 0xf000007fffffffff, 0x3000, 0x0, 0x0, 0x1ffffffff0000,\n            0x0, 0x0, 0x0, 0x3800000000000, 0x0, 0x8000000000000000, 0x0,\n            0xffffffff00000000, 0xfc0000000000, 0x0, 0x6000000, 0x0, 0x0,\n            0x3ff7800000000000, 0x80000000, 0x3000000000000, 0x6000000844, 0x0,\n            0x0, 0x3ffff00000010, 0x3fc000000000, 0x3ff80, 0x13c8000000000007,\n            0x0, 0x667e0000000000, 0x1008, 0xc19d000000000000,\n            0x40300000000002, 0x0, 0x0, 0x0, 0x212000000000, 0x40000000, 0x0,\n            0x0, 0x0, 0x7f0000ffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0000000, 0x0,\n            0x0, 0x0, 0x0, 0x2000000000000000, 0x870000000000f06e, 0x0, 0x0,\n            0x0, 0xff00000000000002, 0x7f, 0x678000000000003, 0x0,\n            0x1fef8000000007, 0x0, 0x7fc0000000000003, 0x0, 0x0, 0x0,\n            0xbf280000000000, 0x0, 0x0, 0x0, 0x78000, 0x0, 0x0,\n            0xf807c3a000000000, 0x3c0000000fe7, 0x0, 0x0, 0x1c, 0x0, 0x0,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffff, 0x0, 0x0, 0x0, 0x0]);\n\n}\n\nstatic if (size_t.sizeof == 4)\n{\n    //832 bytes\n    enum hangulLVTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0x80],\n            [0x100, 0x80, 0xa00], [0x0, 0x20100, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006,\n            0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006,\n            0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006,\n            0x80001, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x10000001, 0x1000000, 0x100000, 0x10000,\n            0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000,\n            0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000,\n            0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000,\n            0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000,\n            0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000,\n            0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000,\n            0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000,\n            0x1000, 0x100, 0x10, 0x1000000, 0x100000, 0x10000, 0x1000, 0x100,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    //832 bytes\n    enum hangulLVTTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0x80],\n            [0x100, 0x80, 0xa00], [0x0, 0x20100, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006,\n            0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006,\n            0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006,\n            0x80001, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff,\n            0xffffefff, 0xfffffeff, 0xffffffef, 0xeffffffe, 0xfeffffff,\n            0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff, 0xffffffef,\n            0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff,\n            0xfffffeff, 0xffffffef, 0xeffffffe, 0xfeffffff, 0xffefffff,\n            0xfffeffff, 0xffffefff, 0xfffffeff, 0xffffffef, 0xeffffffe,\n            0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff,\n            0xffffffef, 0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff,\n            0xffffefff, 0xfffffeff, 0xffffffef, 0xeffffffe, 0xfeffffff,\n            0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff, 0xffffffef,\n            0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff,\n            0xfffffeff, 0xffffffef, 0xfeffffff, 0xffefffff, 0xfffeffff,\n            0xffffefff, 0xfffffeff, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0]);\n    //1536 bytes\n    enum mcTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0xc0], [0x100,\n            0x100, 0x1800], [0x2020100, 0x2020302, 0x5020204, 0x2060202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x30002, 0x50004,\n            0x60000, 0x7, 0x0, 0x0, 0x80000, 0x90000, 0xb000a, 0xc, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf000e, 0x110010,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x130012, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x150000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x160000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xc8000000, 0xde01, 0x0,\n            0xc, 0xc0000000, 0x801981, 0x0, 0x8, 0xc0000000, 0x1, 0x0, 0x8,\n            0xc0000000, 0x1a01, 0x0, 0xc, 0x40000000, 0x801981, 0x0, 0x0,\n            0xc0000000, 0x801dc6, 0x0, 0xe, 0x0, 0x1e, 0x0, 0xc, 0x40000000,\n            0x600d9f, 0x0, 0xc, 0xc0000000, 0x801dc1, 0x0, 0xc, 0x0,\n            0xff038000, 0xc0000, 0x0, 0xc0000000, 0x0, 0x80000000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x19021800, 0xc00000, 0x3f9c, 0x1c009f98, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0400000, 0x1bf, 0x0, 0x0,\n            0x1fb0e78, 0x0, 0x0, 0x0, 0xffff0000, 0x301, 0x0, 0x6000000, 0x0,\n            0xa00000, 0x7e01a, 0x0, 0x0, 0x0, 0x0, 0x10, 0xe8200000, 0x1b, 0x0,\n            0x4, 0x34c2, 0x0, 0xc5c80, 0x0, 0x300ff0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xc0002, 0x0, 0xc000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x98, 0x0,\n            0x0, 0x3, 0xfff00000, 0xf, 0x0, 0x0, 0x0, 0xc0000, 0x0, 0x8,\n            0xec300000, 0x1, 0x0, 0x0, 0x198000, 0x2000, 0x8000000, 0x0, 0x0,\n            0x0, 0x20c800, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16d8, 0x5, 0x0,\n            0x0, 0x0, 0x4, 0x1870000, 0x0, 0x0, 0x0, 0x1000, 0x0, 0x0, 0x4,\n            0x80380000, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40d000, 0x0, 0x0,\n            0x0, 0x0, 0xfffe0000, 0x7fffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x7e060, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    //2336 bytes\n    enum graphemeExtendTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40,\n            0xe0], [0x100, 0x140, 0x2d00], [0x2020100, 0x4020302, 0x6020205,\n            0x2070202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020208, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x30002, 0x50004,\n            0x70006, 0x90008, 0xb000a, 0xd000c, 0xe, 0xf0000, 0x0, 0x100000,\n            0x120011, 0x140013, 0x160015, 0x0, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x190018, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x1b, 0x1d001c, 0x1f001e, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000, 0x0, 0x220021, 0x230000,\n            0x0, 0x0, 0x0, 0x0, 0x24, 0x0, 0x0, 0x260025, 0x0, 0x0, 0x27, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x280000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x290000, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b0000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffff, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x3f8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xfffe0000, 0xbfffffff, 0xb6, 0x0, 0x7ff0000, 0x0, 0xfffff800,\n            0x10000, 0x0, 0x0, 0x9fc00000, 0x3d9f, 0x20000, 0xffff0000, 0x7ff,\n            0x0, 0x0, 0x1ffc0, 0x0, 0xff800, 0xfbc00000, 0x3eef, 0xe000000,\n            0x0, 0x0, 0x0, 0x0, 0x7ffffff0, 0x7, 0x14000000, 0xfe21fe, 0xc,\n            0x2, 0x50000000, 0x80201e, 0xc, 0x6, 0x10000000, 0x23986, 0x230000,\n            0x6, 0x10000000, 0x21be, 0xc, 0x2, 0xd0000000, 0xc0201e, 0xc, 0x4,\n            0x40000000, 0x802001, 0x0, 0x0, 0xc0000000, 0x603dc1, 0xc, 0x0,\n            0x90000000, 0x603044, 0xc, 0x0, 0x40000000, 0x80201e, 0xc, 0x0,\n            0x0, 0x805c8400, 0x0, 0x0, 0x7f20000, 0x7f80, 0x0, 0x0, 0x1bf20000,\n            0x3f00, 0x0, 0x3000000, 0x2a00000, 0x0, 0x7ffe0000, 0xfeffe0df,\n            0x1fffffff, 0x40, 0x0, 0x0, 0x66fde000, 0xc3000000, 0x1e0001,\n            0x20002064, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0000000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x1c0000, 0x1c0000, 0xc0000, 0xc0000, 0x0, 0x3fb00000,\n            0x200ffe40, 0x0, 0x3800, 0x0, 0x0, 0x0, 0x0, 0x200, 0x0, 0x0, 0x0,\n            0xe040187, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9800000, 0x0,\n            0x7f400000, 0x9ff81fe5, 0x0, 0x0, 0x0, 0x0, 0xf, 0x17d00000, 0x4,\n            0xff800, 0x3, 0xb3c, 0x0, 0x3a340, 0x0, 0xcff000, 0x0, 0x0, 0x0,\n            0x0, 0xfff70000, 0x1021fd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xffffffff, 0xf000007f, 0x3000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xffff0000, 0x1ffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38000,\n            0x0, 0x0, 0x0, 0x80000000, 0x0, 0x0, 0x0, 0xffffffff, 0x0, 0xfc00,\n            0x0, 0x0, 0x6000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff78000,\n            0x80000000, 0x0, 0x0, 0x30000, 0x844, 0x60, 0x0, 0x0, 0x0, 0x0,\n            0x10, 0x3ffff, 0x0, 0x3fc0, 0x3ff80, 0x0, 0x7, 0x13c80000, 0x0,\n            0x0, 0x0, 0x667e00, 0x1008, 0x0, 0x0, 0xc19d0000, 0x2, 0x403000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2120, 0x40000000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xffff, 0x7f, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0xc0000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x20000000, 0xf06e, 0x87000000, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x2, 0xff000000, 0x7f, 0x0, 0x3, 0x6780000, 0x0,\n            0x0, 0x7, 0x1fef80, 0x0, 0x0, 0x3, 0x7fc00000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xbf2800, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf807c3a0, 0xfe7, 0x3c00, 0x0, 0x0,\n            0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/unicode_norm.d",
    "content": "module std.internal.unicode_norm;\nimport std.internal.unicode_tables;\n\npackage(std):\n\nstatic if (size_t.sizeof == 8)\n{\n    //1600 bytes\n    enum nfcQCTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0x60],\n            [0x100, 0x100, 0x1a00], [0x302020202020100, 0x205020202020204,\n            0x602020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x1000000000000, 0x200000000, 0x5000400030000, 0x8000000070006,\n            0xa0009, 0x0, 0xb000000000000, 0xc000000000000, 0xf0000000e000d,\n            0x0, 0x1000000000, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14001300120000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x160015, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x170000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x1800120012, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x10361f8081a9fdf, 0x401000000000003f, 0x80, 0x0,\n            0x0, 0x380000, 0x0, 0x0, 0x1000000000000000, 0xff000000,\n            0x4000000000000000, 0xb0800000, 0x48000000000000, 0x4e000000, 0x0,\n            0x0, 0x4000000000000000, 0x30c00000, 0x4000000000000000, 0x800000,\n            0x0, 0x400000, 0x0, 0x600004, 0x4000000000000000, 0x800000, 0x0,\n            0x80008400, 0x0, 0x168020010842008, 0x200108420080002, 0x0,\n            0x400000000000, 0x0, 0x0, 0x0, 0x0, 0x3ffffe00000000,\n            0xffffff0000000000, 0x7, 0x20000000000000, 0x0, 0x0, 0x0, 0x0,\n            0x2aaa000000000000, 0x4800000000000000, 0x2a00c80808080a00, 0x3,\n            0x0, 0x0, 0x0, 0xc4000000000, 0x0, 0x0, 0x0, 0x60000000000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000, 0x0, 0x0, 0x6000000, 0x0,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xfffffc657fe53fff, 0xffff3fffffffffff,\n            0xffffffffffffffff, 0x3ffffff, 0x5f7ffc00a0000000, 0x7fdb, 0x0,\n            0x0, 0x0, 0x0, 0x400000000000000, 0x0, 0x8000000000, 0x0, 0x0, 0x0,\n            0x0, 0x1fc0000000, 0xf800000000000000, 0x1, 0x3fffffff, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0]);\n    //1920 bytes\n    enum nfdQCTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0x70],\n            [0x100, 0x140, 0x2000], [0x504030202020100, 0x207020202020206,\n            0x802020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x3000200010000, 0x5000600050004, 0x9000800070005, 0xc0005000b000a,\n            0x500050005000d, 0x5000500050005, 0xe000500050005,\n            0x10000f00050005, 0x14001300120011, 0x5000500050005,\n            0x5001500050005, 0x5000500050005, 0x5000500050016, 0x5000500050005,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x5000500050005,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x5000500050005,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x5000500050005,\n            0x5000500050005, 0x17001700170017, 0x17001700170017,\n            0x17001700170017, 0x17001700170017, 0x17001700170017,\n            0x17001700170017, 0x17001700170017, 0x17001700170017,\n            0x17001700170017, 0x17001700170017, 0x18001700170017,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x5000500050005,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x5000500050005,\n            0x1a001900170005, 0x5000500050005, 0x5000500050005,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x50005001c001b,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x5000500050005,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x50005001d0005,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x5000500050005,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x5000500050005,\n            0x5000500050005, 0x5001e00170017, 0x5000500050005, 0x5000500050005,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x5000500050005,\n            0x5000500050005, 0x5000500050005, 0x5000500050005, 0x0, 0x0, 0x0,\n            0xbe7effbf3e7effbf, 0x7ef1ff3ffffcffff, 0x7fffff3ffff3f1f8,\n            0x1800300000000, 0xff31ffcfdfffe000, 0xfffc0cfffffff, 0x0, 0x0,\n            0x0, 0x0, 0x401000000000001b, 0x1fc000001d7e0, 0x187c00,\n            0x20000000200708b, 0xc00000708b0000, 0x0, 0x33ffcfcfccf0006, 0x0,\n            0x0, 0x0, 0x0, 0x7c00000000, 0x0, 0x0, 0x80005, 0x12020000000000,\n            0xff000000, 0x0, 0xb0001800, 0x48000000000000, 0x4e000000, 0x0,\n            0x0, 0x0, 0x30001900, 0x100000, 0x1c00, 0x0, 0x100, 0x0, 0xd81,\n            0x0, 0x1c00, 0x0, 0x74000000, 0x0, 0x168020010842008,\n            0x200108420080002, 0x0, 0x4000000000, 0x0, 0x0, 0x0,\n            0x2800000000045540, 0xb, 0x0, 0x0, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffff0bffffff, 0x3ffffffffffffff,\n            0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff,\n            0x3fdcffffefcfffde, 0x3, 0x0, 0x0, 0x0, 0xc4000000000, 0x0,\n            0x40000c000000, 0xe000, 0x5000001210, 0x333e00500000292,\n            0xf00000000333, 0x3c0f00000000, 0x60000000000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x10000000, 0x0, 0x36db02a555555000, 0x5555500040100000,\n            0x4790000036db02a5, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xfffffffff, 0x0, 0xfffffc657fe53fff,\n            0xffff3fffffffffff, 0xffffffffffffffff, 0x3ffffff,\n            0x5f7ffc00a0000000, 0x7fdb, 0x0, 0x0, 0x0, 0x0, 0x80014000000, 0x0,\n            0xc00000000000, 0x0, 0x0, 0x0, 0x0, 0x1fc0000000,\n            0xf800000000000000, 0x1, 0x3fffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    //2560 bytes\n    enum nfkcQCTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0x70],\n            [0x100, 0x140, 0x3400], [0x402030202020100, 0x706020202020205,\n            0x802020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x3000200010000, 0x4000600050004, 0x9000800070004, 0xd000c000b000a,\n            0x40004000f000e, 0x4000400040004, 0x10000400040004,\n            0x13001200110004, 0x17001600150014, 0x4000400040018,\n            0x4001900040004, 0x1d001c001b001a, 0x210020001f001e,\n            0x4000400040004, 0x4000400040004, 0x4000400040004, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x4000400040004, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x4000400040004, 0x4000400040004,\n            0x22000400040004, 0x4000400040004, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x4000400040004, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x4000400040004, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x24002300210004,\n            0x27002600250021, 0x4000400040004, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x4000400290028, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x4000400040004, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x40004002a0004,\n            0x2e002d002c002b, 0x4000400040004, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x4000400040004, 0x4002f00040004,\n            0x4003100300004, 0x4000400040004, 0x4000400040004, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x4000400040004, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x4003200210021, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x4000400040004, 0x4000400040004,\n            0x4000400040004, 0x4000400040004, 0x4000400040004, 0x4000400040004,\n            0x0, 0x0, 0x773c850100000000, 0x0, 0x800c000000000000,\n            0x8000000000000201, 0x0, 0xe000000001ff0, 0x0, 0x0,\n            0x1ff000000000000, 0x1f3f000000, 0x10361f8081a9fdf,\n            0x441000000000003f, 0xb0, 0x2370000007f0000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x80, 0x0, 0x0, 0x1e0000000380000, 0x0, 0x0,\n            0x1000000000000000, 0xff000000, 0x4000000000000000, 0xb0800000,\n            0x48000000000000, 0x4e000000, 0x0, 0x0, 0x4000000000000000,\n            0x30c00000, 0x4000000000000000, 0x800000, 0x0, 0x400000, 0x0,\n            0x600004, 0x4000000000000000, 0x800000, 0x0, 0x80008400,\n            0x8000000000000, 0x0, 0x8000000000000, 0x30000000, 0x1000,\n            0x3e8020010842008, 0x200108420080002, 0x0, 0x400000000000, 0x0,\n            0x0, 0x1000000000000000, 0x0, 0x3ffffe00000000, 0xffffff0000000000,\n            0x7, 0x20000000000000, 0x0, 0x0, 0x0, 0xf7ff700000000000,\n            0x10007ffffffbfff, 0xfffffffff8000000, 0x0, 0x0, 0x0, 0xc000000,\n            0x0, 0x0, 0x2aaa000000000000, 0xe800000000000000,\n            0x6a00e808e808ea03, 0x50d88070008207ff, 0xfff3000080800380,\n            0x1001fff7fff, 0x0, 0xfbfbbd573e6ffeef, 0xffffffffffff03e1, 0x200,\n            0x0, 0x1b00000000000, 0x0, 0x0, 0x0, 0x60000000000, 0x0, 0x0, 0x0,\n            0x0, 0xffffffff00000000, 0xffffffffffffffff, 0x7ffffffffff, 0x1000,\n            0x70000000000000, 0x0, 0x10000000, 0x0, 0x3000000000000000, 0x0,\n            0x0, 0x0, 0x800000000000, 0x0, 0x0, 0x0, 0x0, 0x80000000,\n            0x8000000000000, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0x3fffff, 0x740000000000001, 0x0, 0x9e000000,\n            0x8000000000000000, 0xfffe000000000000, 0xffffffffffffffff,\n            0xfffc7fff, 0x0, 0xffffffff7fffffff, 0x7fffffffffff00ff,\n            0xffffffffffffffff, 0x7fffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0,\n            0x1000000000000, 0x0, 0x300000000000000, 0xfffffc657fe53fff,\n            0xffff3fffffffffff, 0xffffffffffffffff, 0x3ffffff,\n            0x5f7fffffa0f8007f, 0xffffffffffffffdb, 0x3ffffffffffff,\n            0xfffffffffff80000, 0x3fffffffffffffff, 0xffffffffffff0000,\n            0xfffffffffffcffff, 0x1fff0000000000ff, 0xffff000003ff0000,\n            0xffd70f7ffff7ff9f, 0xffffffffffffffff, 0x1fffffffffffffff,\n            0xfffffffffffffffe, 0xffffffffffffffff, 0x7fffffffffffffff,\n            0x7f7f1cfcfcfc, 0x0, 0x0, 0x400000000000000, 0x0, 0x8000000000,\n            0x0, 0x0, 0x0, 0x0, 0x1fc0000000, 0xf800000000000000, 0x1,\n            0xffffffffffffffff, 0xffffffffffdfffff, 0xebffde64dfffffff,\n            0xffffffffffffffef, 0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffff3fffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffcfff, 0xaf7fe96ffffffef, 0x5ef7f796aa96ea84,\n            0xffffbee0ffffbff, 0x0, 0xffff7fffffff07ff, 0xc000000ffff, 0x10000,\n            0x0, 0x7ffffffffff0007, 0x301ff, 0x0, 0x0, 0x3fffffff, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0]);\n    //2656 bytes\n    enum nfkdQCTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0x78],\n            [0x100, 0x160, 0x3500], [0x504030202020100, 0x807020202020206,\n            0x902020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202,\n            0x202020202020202, 0x202020202020202, 0x202020202020202, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x3000200010000, 0x7000600050004, 0xa000900080007, 0xe000d000c000b,\n            0x700070007000f, 0x7000700070007, 0x10000700070007,\n            0x13001200110007, 0x17001600150014, 0x7000700070018,\n            0x7001900070007, 0x1d001c001b001a, 0x210020001f001e,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x22000700070007, 0x7000700070007, 0x21002100210021,\n            0x21002100210021, 0x21002100210021, 0x21002100210021,\n            0x21002100210021, 0x21002100210021, 0x21002100210021,\n            0x21002100210021, 0x21002100210021, 0x21002100210021,\n            0x23002100210021, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x25002400210007,\n            0x28002700260021, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x70007002a0029, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x70007002b0007,\n            0x2f002e002d002c, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7003000070007,\n            0x7003200310007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7003300210021, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x7000700070007, 0x7000700070007, 0x7000700070007, 0x7000700070007,\n            0x0, 0x0, 0x773c850100000000, 0xbe7effbf3e7effbf,\n            0xfefdff3ffffcffff, 0xffffff3ffff3f3f9, 0x1800300000000,\n            0xff3fffcfdffffff0, 0xfffc0cfffffff, 0x0, 0x1ff000000000000,\n            0x1f3f000000, 0x0, 0x441000000000001b, 0x1fc000001d7f0,\n            0x2370000007f7c00, 0x20000000200708b, 0xc00000708b0000, 0x0,\n            0x33ffcfcfccf0006, 0x0, 0x0, 0x80, 0x0, 0x7c00000000,\n            0x1e0000000000000, 0x0, 0x80005, 0x0, 0x0, 0x0, 0x0,\n            0x12020000000000, 0xff000000, 0x0, 0xb0001800, 0x48000000000000,\n            0x4e000000, 0x0, 0x0, 0x0, 0x30001900, 0x100000, 0x1c00, 0x0,\n            0x100, 0x0, 0xd81, 0x0, 0x1c00, 0x0, 0x74000000, 0x8000000000000,\n            0x0, 0x8000000000000, 0x30000000, 0x1000, 0x3e8020010842008,\n            0x200108420080002, 0x0, 0x4000000000, 0x0, 0x0, 0x1000000000000000,\n            0x2800000000045540, 0xb, 0x0, 0x0, 0xf7ff700000000000,\n            0x10007ffffffbfff, 0xfffffffff8000000, 0x0, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffff0fffffff, 0x3ffffffffffffff,\n            0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0xffdfffffffffffff,\n            0x7fdcffffefcfffdf, 0x50d88070008207ff, 0xfff3000080800380,\n            0x1001fff7fff, 0x0, 0xfbfbbd573e6ffeef, 0xffffffffffff03e1,\n            0x40000c000200, 0xe000, 0x1b05000001210, 0x333e00500000292,\n            0xf00000000333, 0x3c0f00000000, 0x60000000000, 0x0, 0x0, 0x0, 0x0,\n            0xffffffff00000000, 0xffffffffffffffff, 0x7ffffffffff, 0x1000,\n            0x70000000000000, 0x0, 0x10000000, 0x0, 0x3000000000000000, 0x0,\n            0x0, 0x0, 0x800000000000, 0x0, 0x0, 0x0, 0x0, 0x80000000,\n            0x8000000000000, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0x3fffff, 0x740000000000001,\n            0x36db02a555555000, 0x55555000d8100000, 0xc790000036db02a5,\n            0xfffe000000000000, 0xffffffffffffffff, 0xfffc7fff, 0x0,\n            0xffffffff7fffffff, 0x7fffffffffff00ff, 0xffffffffffffffff,\n            0x7fffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x1000000000000, 0x0,\n            0x300000000000000, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xfffffffff, 0x0, 0xfffffc657fe53fff, 0xffff3fffffffffff,\n            0xffffffffffffffff, 0x3ffffff, 0x5f7fffffa0f8007f,\n            0xffffffffffffffdb, 0x3ffffffffffff, 0xfffffffffff80000,\n            0x3fffffffffffffff, 0xffffffffffff0000, 0xfffffffffffcffff,\n            0x1fff0000000000ff, 0xffff000003ff0000, 0xffd70f7ffff7ff9f,\n            0xffffffffffffffff, 0x1fffffffffffffff, 0xfffffffffffffffe,\n            0xffffffffffffffff, 0x7fffffffffffffff, 0x7f7f1cfcfcfc, 0x0, 0x0,\n            0x80014000000, 0x0, 0xc00000000000, 0x0, 0x0, 0x0, 0x0,\n            0x1fc0000000, 0xf800000000000000, 0x1, 0xffffffffffffffff,\n            0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef,\n            0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffff3fffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffcfff,\n            0xaf7fe96ffffffef, 0x5ef7f796aa96ea84, 0xffffbee0ffffbff, 0x0,\n            0xffff7fffffff07ff, 0xc000000ffff, 0x10000, 0x0, 0x7ffffffffff0007,\n            0x301ff, 0x0, 0x0, 0x3fffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n\n}\n\nstatic if (size_t.sizeof == 4)\n{\n    //1600 bytes\n    enum nfcQCTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0xc0],\n            [0x100, 0x100, 0x1a00], [0x2020100, 0x3020202, 0x2020204,\n            0x2050202, 0x2020202, 0x6020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x0, 0x2, 0x30000,\n            0x50004, 0x70006, 0x80000, 0xa0009, 0x0, 0x0, 0x0, 0x0, 0xb0000,\n            0x0, 0xc0000, 0xe000d, 0xf0000, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0,\n            0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x120000,\n            0x140013, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x160015, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x170000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x120012, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x81a9fdf, 0x10361f8, 0x3f, 0x40100000, 0x80, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x380000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x10000000, 0xff000000, 0x0, 0x0, 0x40000000, 0xb0800000, 0x0, 0x0,\n            0x480000, 0x4e000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000,\n            0x30c00000, 0x0, 0x0, 0x40000000, 0x800000, 0x0, 0x0, 0x0,\n            0x400000, 0x0, 0x0, 0x0, 0x600004, 0x0, 0x0, 0x40000000, 0x800000,\n            0x0, 0x0, 0x0, 0x80008400, 0x0, 0x0, 0x0, 0x10842008, 0x1680200,\n            0x20080002, 0x2001084, 0x0, 0x0, 0x0, 0x4000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x3ffffe, 0x0, 0xffffff00, 0x7, 0x0, 0x0,\n            0x200000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2aaa0000,\n            0x0, 0x48000000, 0x8080a00, 0x2a00c808, 0x3, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xc40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x600, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x10000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6000000, 0x0, 0x0, 0x0,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0x7fe53fff, 0xfffffc65,\n            0xffffffff, 0xffff3fff, 0xffffffff, 0xffffffff, 0x3ffffff, 0x0,\n            0xa0000000, 0x5f7ffc00, 0x7fdb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x4000000, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0xc0000000, 0x1f, 0x0, 0xf8000000, 0x1, 0x0,\n            0x3fffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0]);\n    //1920 bytes\n    enum nfdQCTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0xe0],\n            [0x100, 0x140, 0x2000], [0x2020100, 0x5040302, 0x2020206,\n            0x2070202, 0x2020202, 0x8020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x30002, 0x50004, 0x50006,\n            0x70005, 0x90008, 0xb000a, 0xc0005, 0x5000d, 0x50005, 0x50005,\n            0x50005, 0x50005, 0xe0005, 0x50005, 0x10000f, 0x120011, 0x140013,\n            0x50005, 0x50005, 0x50005, 0x50015, 0x50005, 0x50005, 0x50016,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x50005, 0x170017, 0x170017, 0x170017, 0x170017, 0x170017,\n            0x170017, 0x170017, 0x170017, 0x170017, 0x170017, 0x170017,\n            0x170017, 0x170017, 0x170017, 0x170017, 0x170017, 0x170017,\n            0x170017, 0x170017, 0x170017, 0x170017, 0x180017, 0x50005, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x170005, 0x1a0019, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x1c001b, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x1d0005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x170017,\n            0x5001e, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x50005,\n            0x50005, 0x50005, 0x50005, 0x50005, 0x50005, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x3e7effbf, 0xbe7effbf, 0xfffcffff, 0x7ef1ff3f,\n            0xfff3f1f8, 0x7fffff3f, 0x0, 0x18003, 0xdfffe000, 0xff31ffcf,\n            0xcfffffff, 0xfffc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b,\n            0x40100000, 0x1d7e0, 0x1fc00, 0x187c00, 0x0, 0x200708b, 0x2000000,\n            0x708b0000, 0xc00000, 0x0, 0x0, 0xfccf0006, 0x33ffcfc, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, 0x0,\n            0x80005, 0x0, 0x0, 0x120200, 0xff000000, 0x0, 0x0, 0x0, 0xb0001800,\n            0x0, 0x0, 0x480000, 0x4e000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x30001900, 0x0, 0x100000, 0x0, 0x1c00, 0x0, 0x0, 0x0, 0x100, 0x0,\n            0x0, 0x0, 0xd81, 0x0, 0x0, 0x0, 0x1c00, 0x0, 0x0, 0x0, 0x74000000,\n            0x0, 0x0, 0x0, 0x10842008, 0x1680200, 0x20080002, 0x2001084, 0x0,\n            0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x45540, 0x28000000,\n            0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xbffffff, 0xffffffff, 0xffffffff, 0x3ffffff,\n            0x3f3fffff, 0xffffffff, 0xaaff3f3f, 0x3fffffff, 0xffffffff,\n            0x5fdfffff, 0xefcfffde, 0x3fdcffff, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xc40, 0x0, 0x0, 0xc000000, 0x4000, 0xe000, 0x0,\n            0x1210, 0x50, 0x292, 0x333e005, 0x333, 0xf000, 0x0, 0x3c0f, 0x0,\n            0x600, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x10000000, 0x0, 0x0, 0x0, 0x55555000, 0x36db02a5, 0x40100000,\n            0x55555000, 0x36db02a5, 0x47900000, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xf, 0x0, 0x0, 0x7fe53fff, 0xfffffc65, 0xffffffff,\n            0xffff3fff, 0xffffffff, 0xffffffff, 0x3ffffff, 0x0, 0xa0000000,\n            0x5f7ffc00, 0x7fdb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x14000000, 0x800, 0x0, 0x0, 0x0, 0xc000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0xc0000000, 0x1f, 0x0, 0xf8000000, 0x1, 0x0,\n            0x3fffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0]);\n    //2560 bytes\n    enum nfkcQCTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0xe0],\n            [0x100, 0x140, 0x3400], [0x2020100, 0x4020302, 0x2020205,\n            0x7060202, 0x2020202, 0x8020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x30002, 0x50004, 0x40006,\n            0x70004, 0x90008, 0xb000a, 0xd000c, 0xf000e, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x100004, 0x110004, 0x130012, 0x150014, 0x170016,\n            0x40018, 0x40004, 0x40004, 0x40019, 0x1b001a, 0x1d001c, 0x1f001e,\n            0x210020, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x220004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x210004, 0x240023, 0x250021, 0x270026, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x290028, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x2a0004, 0x40004, 0x2c002b, 0x2e002d, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x4002f, 0x300004, 0x40031, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x210021, 0x40032, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004, 0x40004,\n            0x40004, 0x40004, 0x0, 0x0, 0x0, 0x0, 0x0, 0x773c8501, 0x0, 0x0,\n            0x0, 0x800c0000, 0x201, 0x80000000, 0x0, 0x0, 0x1ff0, 0xe0000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x1ff0000, 0x3f000000, 0x1f, 0x81a9fdf,\n            0x10361f8, 0x3f, 0x44100000, 0xb0, 0x0, 0x7f0000, 0x2370000, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x380000, 0x1e00000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x10000000, 0xff000000, 0x0, 0x0, 0x40000000, 0xb0800000, 0x0, 0x0,\n            0x480000, 0x4e000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000,\n            0x30c00000, 0x0, 0x0, 0x40000000, 0x800000, 0x0, 0x0, 0x0,\n            0x400000, 0x0, 0x0, 0x0, 0x600004, 0x0, 0x0, 0x40000000, 0x800000,\n            0x0, 0x0, 0x0, 0x80008400, 0x0, 0x0, 0x80000, 0x0, 0x0, 0x0,\n            0x80000, 0x30000000, 0x0, 0x1000, 0x0, 0x10842008, 0x3e80200,\n            0x20080002, 0x2001084, 0x0, 0x0, 0x0, 0x4000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x10000000, 0x0, 0x0, 0x0, 0x3ffffe, 0x0, 0xffffff00, 0x7,\n            0x0, 0x0, 0x200000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf7ff7000,\n            0xffffbfff, 0x10007ff, 0xf8000000, 0xffffffff, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0xc000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2aaa0000, 0x0,\n            0xe8000000, 0xe808ea03, 0x6a00e808, 0x8207ff, 0x50d88070,\n            0x80800380, 0xfff30000, 0x1fff7fff, 0x100, 0x0, 0x0, 0x3e6ffeef,\n            0xfbfbbd57, 0xffff03e1, 0xffffffff, 0x200, 0x0, 0x0, 0x0, 0x0,\n            0x1b000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x600, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0x7ff, 0x1000, 0x0, 0x0, 0x700000, 0x0, 0x0,\n            0x10000000, 0x0, 0x0, 0x0, 0x0, 0x30000000, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x80000000, 0x0, 0x0, 0x80000, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0x3fffff, 0x0, 0x1, 0x7400000,\n            0x0, 0x0, 0x9e000000, 0x0, 0x0, 0x80000000, 0x0, 0xfffe0000,\n            0xffffffff, 0xffffffff, 0xfffc7fff, 0x0, 0x0, 0x0, 0x7fffffff,\n            0xffffffff, 0xffff00ff, 0x7fffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0,\n            0x0, 0x0, 0x10000, 0x0, 0x0, 0x0, 0x3000000, 0x7fe53fff,\n            0xfffffc65, 0xffffffff, 0xffff3fff, 0xffffffff, 0xffffffff,\n            0x3ffffff, 0x0, 0xa0f8007f, 0x5f7fffff, 0xffffffdb, 0xffffffff,\n            0xffffffff, 0x3ffff, 0xfff80000, 0xffffffff, 0xffffffff,\n            0x3fffffff, 0xffff0000, 0xffffffff, 0xfffcffff, 0xffffffff, 0xff,\n            0x1fff0000, 0x3ff0000, 0xffff0000, 0xfff7ff9f, 0xffd70f7f,\n            0xffffffff, 0xffffffff, 0xffffffff, 0x1fffffff, 0xfffffffe,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff,\n            0x1cfcfcfc, 0x7f7f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000, 0x0, 0x0,\n            0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0000000,\n            0x1f, 0x0, 0xf8000000, 0x1, 0x0, 0xffffffff, 0xffffffff,\n            0xffdfffff, 0xffffffff, 0xdfffffff, 0xebffde64, 0xffffffef,\n            0xffffffff, 0xdfdfe7bf, 0x7bffffff, 0xfffdfc5f, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff3f,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffcfff, 0xffffffff,\n            0xffffffef, 0xaf7fe96, 0xaa96ea84, 0x5ef7f796, 0xffffbff,\n            0xffffbee, 0x0, 0x0, 0xffff07ff, 0xffff7fff, 0xffff, 0xc00,\n            0x10000, 0x0, 0x0, 0x0, 0xffff0007, 0x7ffffff, 0x301ff, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x3fffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n    //2656 bytes\n    enum nfkdQCTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0xf0],\n            [0x100, 0x160, 0x3500], [0x2020100, 0x5040302, 0x2020206,\n            0x8070202, 0x2020202, 0x9020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n            0x2020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x30002, 0x50004, 0x70006,\n            0x80007, 0xa0009, 0xc000b, 0xe000d, 0x7000f, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x100007, 0x110007, 0x130012, 0x150014, 0x170016,\n            0x70018, 0x70007, 0x70007, 0x70019, 0x1b001a, 0x1d001c, 0x1f001e,\n            0x210020, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x220007, 0x70007,\n            0x70007, 0x210021, 0x210021, 0x210021, 0x210021, 0x210021,\n            0x210021, 0x210021, 0x210021, 0x210021, 0x210021, 0x210021,\n            0x210021, 0x210021, 0x210021, 0x210021, 0x210021, 0x210021,\n            0x210021, 0x210021, 0x210021, 0x210021, 0x230021, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x210007, 0x250024, 0x260021, 0x280027, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x2a0029, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x2b0007, 0x70007, 0x2d002c, 0x2f002e, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70030, 0x310007, 0x70032, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x210021, 0x70033, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007,\n            0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x70007, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x773c8501, 0x3e7effbf, 0xbe7effbf, 0xfffcffff,\n            0xfefdff3f, 0xfff3f3f9, 0xffffff3f, 0x0, 0x18003, 0xdffffff0,\n            0xff3fffcf, 0xcfffffff, 0xfffc0, 0x0, 0x0, 0x0, 0x1ff0000,\n            0x3f000000, 0x1f, 0x0, 0x0, 0x1b, 0x44100000, 0x1d7f0, 0x1fc00,\n            0x7f7c00, 0x2370000, 0x200708b, 0x2000000, 0x708b0000, 0xc00000,\n            0x0, 0x0, 0xfccf0006, 0x33ffcfc, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0,\n            0x0, 0x0, 0x0, 0x7c, 0x0, 0x1e00000, 0x0, 0x0, 0x80005, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x120200, 0xff000000, 0x0,\n            0x0, 0x0, 0xb0001800, 0x0, 0x0, 0x480000, 0x4e000000, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x30001900, 0x0, 0x100000, 0x0, 0x1c00,\n            0x0, 0x0, 0x0, 0x100, 0x0, 0x0, 0x0, 0xd81, 0x0, 0x0, 0x0, 0x1c00,\n            0x0, 0x0, 0x0, 0x74000000, 0x0, 0x0, 0x80000, 0x0, 0x0, 0x0,\n            0x80000, 0x30000000, 0x0, 0x1000, 0x0, 0x10842008, 0x3e80200,\n            0x20080002, 0x2001084, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x10000000, 0x45540, 0x28000000, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0xf7ff7000, 0xffffbfff, 0x10007ff, 0xf8000000, 0xffffffff,\n            0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xfffffff, 0xffffffff, 0xffffffff, 0x3ffffff, 0x3f3fffff,\n            0xffffffff, 0xaaff3f3f, 0x3fffffff, 0xffffffff, 0xffdfffff,\n            0xefcfffdf, 0x7fdcffff, 0x8207ff, 0x50d88070, 0x80800380,\n            0xfff30000, 0x1fff7fff, 0x100, 0x0, 0x0, 0x3e6ffeef, 0xfbfbbd57,\n            0xffff03e1, 0xffffffff, 0xc000200, 0x4000, 0xe000, 0x0, 0x1210,\n            0x1b050, 0x292, 0x333e005, 0x333, 0xf000, 0x0, 0x3c0f, 0x0, 0x600,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0x7ff, 0x1000, 0x0, 0x0,\n            0x700000, 0x0, 0x0, 0x10000000, 0x0, 0x0, 0x0, 0x0, 0x30000000,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x80000000, 0x0, 0x0, 0x80000, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0x3fffff, 0x0, 0x1, 0x7400000, 0x55555000, 0x36db02a5, 0xd8100000,\n            0x55555000, 0x36db02a5, 0xc7900000, 0x0, 0xfffe0000, 0xffffffff,\n            0xffffffff, 0xfffc7fff, 0x0, 0x0, 0x0, 0x7fffffff, 0xffffffff,\n            0xffff00ff, 0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0, 0x0, 0x0,\n            0x10000, 0x0, 0x0, 0x0, 0x3000000, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xf, 0x0, 0x0, 0x7fe53fff,\n            0xfffffc65, 0xffffffff, 0xffff3fff, 0xffffffff, 0xffffffff,\n            0x3ffffff, 0x0, 0xa0f8007f, 0x5f7fffff, 0xffffffdb, 0xffffffff,\n            0xffffffff, 0x3ffff, 0xfff80000, 0xffffffff, 0xffffffff,\n            0x3fffffff, 0xffff0000, 0xffffffff, 0xfffcffff, 0xffffffff, 0xff,\n            0x1fff0000, 0x3ff0000, 0xffff0000, 0xfff7ff9f, 0xffd70f7f,\n            0xffffffff, 0xffffffff, 0xffffffff, 0x1fffffff, 0xfffffffe,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff,\n            0x1cfcfcfc, 0x7f7f, 0x0, 0x0, 0x0, 0x0, 0x14000000, 0x800, 0x0,\n            0x0, 0x0, 0xc000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0xc0000000, 0x1f, 0x0, 0xf8000000, 0x1, 0x0, 0xffffffff,\n            0xffffffff, 0xffdfffff, 0xffffffff, 0xdfffffff, 0xebffde64,\n            0xffffffef, 0xffffffff, 0xdfdfe7bf, 0x7bffffff, 0xfffdfc5f,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffff3f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n            0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffcfff,\n            0xffffffff, 0xffffffef, 0xaf7fe96, 0xaa96ea84, 0x5ef7f796,\n            0xffffbff, 0xffffbee, 0x0, 0x0, 0xffff07ff, 0xffff7fff, 0xffff,\n            0xc00, 0x10000, 0x0, 0x0, 0x0, 0xffff0007, 0x7ffffff, 0x301ff, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x3fffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n\n}\n"
  },
  {
    "path": "libphobos/src/std/internal/unicode_tables.d",
    "content": "//Written in the D programming language\n/**\n * License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n *\n * Authors: Dmitry Olshansky\n *\n */\n//Automatically generated from Unicode Character Database files\n\n//dfmt off\nmodule std.internal.unicode_tables;\n@safe pure nothrow @nogc package(std):\n\n\nstruct SimpleCaseEntry\n{\n    uint ch;\n    ubyte n, bucket;// n - number in bucket\n\npure nothrow @nogc:\n\n    @property ubyte size() const\n    {\n        return bucket & 0x3F;\n    }\n    @property auto isLower() const\n    {\n        return bucket & 0x40;\n    }\n    @property auto isUpper() const\n    {\n        return bucket & 0x80;\n    }\n}\n\nstruct FullCaseEntry\n{\n    dchar[3] seq;\n    ubyte n, size;// n number in batch, size - size of batch\n    ubyte entry_len;\n\n    @property auto value() const @trusted pure nothrow @nogc return\n    {\n        return seq[0 .. entry_len];\n    }\n}\n\nstruct CompEntry\n{\n    dchar rhs, composed;\n}\n\nstruct UnicodeProperty\n{\n    string name;\n    ubyte[] compressed;\n}\n\nstruct TrieEntry(T...)\n{\n    size_t[] offsets;\n    size_t[] sizes;\n    size_t[] data;\n}\n\n@property immutable(SimpleCaseEntry[]) simpleCaseTable()\n{\nalias SCE = SimpleCaseEntry;\nstatic immutable SCE[] t = [\nSCE(0x2c00, 0, 0x82),\nSCE(0x2c30, 1, 0x42),SCE(0x24c3, 0, 0x82),SCE(0x24dd, 1, 0x42),SCE(0x2c01, 0, 0x82),\nSCE(0x2c31, 1, 0x42),SCE(0x2c1d, 0, 0x82),SCE(0x2c4d, 1, 0x42),SCE(0x2c02, 0, 0x82),\nSCE(0x2c32, 1, 0x42),SCE(0x2c03, 0, 0x82),SCE(0x2c33, 1, 0x42),SCE(0x2c04, 0, 0x82),\nSCE(0x2c34, 1, 0x42),SCE(0x2c05, 0, 0x82),SCE(0x2c35, 1, 0x42),SCE(0x2c06, 0, 0x82),\nSCE(0x2c36, 1, 0x42),SCE(0x10400, 0, 0x82),SCE(0x10428, 1, 0x42),SCE(0x2cc2, 0, 0x82),\nSCE(0x2cc3, 1, 0x42),SCE(0x2c07, 0, 0x82),SCE(0x2c37, 1, 0x42),SCE(0x2c08, 0, 0x82),\nSCE(0x2c38, 1, 0x42),SCE(0x2c09, 0, 0x82),SCE(0x2c39, 1, 0x42),SCE(0x2c0a, 0, 0x82),\nSCE(0x2c3a, 1, 0x42),SCE(0xa68c, 0, 0x82),SCE(0xa68d, 1, 0x42),SCE(0x0041, 0, 0x82),\nSCE(0x0061, 1, 0x42),SCE(0x0042, 0, 0x82),SCE(0x0062, 1, 0x42),SCE(0x0043, 0, 0x82),\nSCE(0x0063, 1, 0x42),SCE(0x0044, 0, 0x82),SCE(0x0064, 1, 0x42),SCE(0x0045, 0, 0x82),\nSCE(0x0065, 1, 0x42),SCE(0x0046, 0, 0x82),SCE(0x0066, 1, 0x42),SCE(0x0047, 0, 0x82),\nSCE(0x0067, 1, 0x42),SCE(0x0048, 0, 0x82),SCE(0x0068, 1, 0x42),SCE(0x0049, 0, 0x82),\nSCE(0x0069, 1, 0x42),SCE(0x004a, 0, 0x82),SCE(0x006a, 1, 0x42),SCE(0x004b, 0, 0x83),\nSCE(0x006b, 1, 0x43),SCE(0x212a, 2, 0x83),SCE(0x004c, 0, 0x82),SCE(0x006c, 1, 0x42),\nSCE(0x004d, 0, 0x82),SCE(0x006d, 1, 0x42),SCE(0x004e, 0, 0x82),SCE(0x006e, 1, 0x42),\nSCE(0x004f, 0, 0x82),SCE(0x006f, 1, 0x42),SCE(0x0050, 0, 0x82),SCE(0x0070, 1, 0x42),\nSCE(0x0051, 0, 0x82),SCE(0x0071, 1, 0x42),SCE(0x0052, 0, 0x82),SCE(0x0072, 1, 0x42),\nSCE(0x0053, 0, 0x83),SCE(0x0073, 1, 0x43),SCE(0x017f, 2, 0x43),SCE(0x0054, 0, 0x82),\nSCE(0x0074, 1, 0x42),SCE(0x0055, 0, 0x82),SCE(0x0075, 1, 0x42),SCE(0x0056, 0, 0x82),\nSCE(0x0076, 1, 0x42),SCE(0x0057, 0, 0x82),SCE(0x0077, 1, 0x42),SCE(0x0058, 0, 0x82),\nSCE(0x0078, 1, 0x42),SCE(0x0059, 0, 0x82),SCE(0x0079, 1, 0x42),SCE(0x005a, 0, 0x82),\nSCE(0x007a, 1, 0x42),SCE(0x2c0f, 0, 0x82),SCE(0x2c3f, 1, 0x42),SCE(0x2c10, 0, 0x82),\nSCE(0x2c40, 1, 0x42),SCE(0x10402, 0, 0x82),SCE(0x1042a, 1, 0x42),SCE(0x2cc4, 0, 0x82),\nSCE(0x2cc5, 1, 0x42),SCE(0x2166, 0, 0x82),SCE(0x2176, 1, 0x42),SCE(0x2c11, 0, 0x82),\nSCE(0x2c41, 1, 0x42),SCE(0x2c12, 0, 0x82),SCE(0x2c42, 1, 0x42),SCE(0x2168, 0, 0x82),\nSCE(0x2178, 1, 0x42),SCE(0x2c13, 0, 0x82),SCE(0x2c43, 1, 0x42),SCE(0xa682, 0, 0x82),\nSCE(0xa683, 1, 0x42),SCE(0x2c14, 0, 0x82),SCE(0x2c44, 1, 0x42),SCE(0x216a, 0, 0x82),\nSCE(0x217a, 1, 0x42),SCE(0x24c7, 0, 0x82),SCE(0x24e1, 1, 0x42),SCE(0x2c15, 0, 0x82),\nSCE(0x2c45, 1, 0x42),SCE(0x10403, 0, 0x82),SCE(0x1042b, 1, 0x42),SCE(0x2c16, 0, 0x82),\nSCE(0x2c46, 1, 0x42),SCE(0x216c, 0, 0x82),SCE(0x217c, 1, 0x42),SCE(0x2c17, 0, 0x82),\nSCE(0x2c47, 1, 0x42),SCE(0xff38, 0, 0x82),SCE(0xff58, 1, 0x42),SCE(0x2c18, 0, 0x82),\nSCE(0x2c48, 1, 0x42),SCE(0x216e, 0, 0x82),SCE(0x217e, 1, 0x42),SCE(0x2c19, 0, 0x82),\nSCE(0x2c49, 1, 0x42),SCE(0x2c1a, 0, 0x82),SCE(0x2c4a, 1, 0x42),SCE(0x2c1e, 0, 0x82),\nSCE(0x2c4e, 1, 0x42),SCE(0x10a0, 0, 0x82),SCE(0x2d00, 1, 0x42),SCE(0x10a1, 0, 0x82),\nSCE(0x2d01, 1, 0x42),SCE(0x10a2, 0, 0x82),SCE(0x2d02, 1, 0x42),SCE(0x10a3, 0, 0x82),\nSCE(0x2d03, 1, 0x42),SCE(0x10a4, 0, 0x82),SCE(0x2d04, 1, 0x42),SCE(0x10a5, 0, 0x82),\nSCE(0x2d05, 1, 0x42),SCE(0x10a6, 0, 0x82),SCE(0x2d06, 1, 0x42),SCE(0x10a7, 0, 0x82),\nSCE(0x2d07, 1, 0x42),SCE(0x10a8, 0, 0x82),SCE(0x2d08, 1, 0x42),SCE(0x10a9, 0, 0x82),\nSCE(0x2d09, 1, 0x42),SCE(0x10aa, 0, 0x82),SCE(0x2d0a, 1, 0x42),SCE(0x10ab, 0, 0x82),\nSCE(0x2d0b, 1, 0x42),SCE(0x10ac, 0, 0x82),SCE(0x2d0c, 1, 0x42),SCE(0x10ad, 0, 0x82),\nSCE(0x2d0d, 1, 0x42),SCE(0x10ae, 0, 0x82),SCE(0x2d0e, 1, 0x42),SCE(0x10af, 0, 0x82),\nSCE(0x2d0f, 1, 0x42),SCE(0x10b0, 0, 0x82),SCE(0x2d10, 1, 0x42),SCE(0x10b1, 0, 0x82),\nSCE(0x2d11, 1, 0x42),SCE(0x10b2, 0, 0x82),SCE(0x2d12, 1, 0x42),SCE(0x10b3, 0, 0x82),\nSCE(0x2d13, 1, 0x42),SCE(0x10b4, 0, 0x82),SCE(0x2d14, 1, 0x42),SCE(0x10b5, 0, 0x82),\nSCE(0x2d15, 1, 0x42),SCE(0x10b6, 0, 0x82),SCE(0x2d16, 1, 0x42),SCE(0x10b7, 0, 0x82),\nSCE(0x2d17, 1, 0x42),SCE(0x10b8, 0, 0x82),SCE(0x2d18, 1, 0x42),SCE(0x10b9, 0, 0x82),\nSCE(0x2d19, 1, 0x42),SCE(0x10ba, 0, 0x82),SCE(0x2d1a, 1, 0x42),SCE(0x10bb, 0, 0x82),\nSCE(0x2d1b, 1, 0x42),SCE(0x10bc, 0, 0x82),SCE(0x2d1c, 1, 0x42),SCE(0x10bd, 0, 0x82),\nSCE(0x2d1d, 1, 0x42),SCE(0x10be, 0, 0x82),SCE(0x2d1e, 1, 0x42),SCE(0x10bf, 0, 0x82),\nSCE(0x2d1f, 1, 0x42),SCE(0x00c0, 0, 0x82),SCE(0x00e0, 1, 0x42),SCE(0x00c1, 0, 0x82),\nSCE(0x00e1, 1, 0x42),SCE(0x10c2, 0, 0x82),SCE(0x2d22, 1, 0x42),SCE(0x00c3, 0, 0x82),\nSCE(0x00e3, 1, 0x42),SCE(0x10c4, 0, 0x82),SCE(0x2d24, 1, 0x42),SCE(0x00c5, 0, 0x83),\nSCE(0x00e5, 1, 0x43),SCE(0x212b, 2, 0x83),SCE(0x00c6, 0, 0x82),SCE(0x00e6, 1, 0x42),\nSCE(0x00c7, 0, 0x82),SCE(0x00e7, 1, 0x42),SCE(0x00c8, 0, 0x82),SCE(0x00e8, 1, 0x42),\nSCE(0x00c9, 0, 0x82),SCE(0x00e9, 1, 0x42),SCE(0x00ca, 0, 0x82),SCE(0x00ea, 1, 0x42),\nSCE(0x00cb, 0, 0x82),SCE(0x00eb, 1, 0x42),SCE(0x00cc, 0, 0x82),SCE(0x00ec, 1, 0x42),\nSCE(0x00cd, 0, 0x82),SCE(0x00ed, 1, 0x42),SCE(0x00ce, 0, 0x82),SCE(0x00ee, 1, 0x42),\nSCE(0x00cf, 0, 0x82),SCE(0x00ef, 1, 0x42),SCE(0x00d0, 0, 0x82),SCE(0x00f0, 1, 0x42),\nSCE(0x00d1, 0, 0x82),SCE(0x00f1, 1, 0x42),SCE(0x00d2, 0, 0x82),SCE(0x00f2, 1, 0x42),\nSCE(0x00d3, 0, 0x82),SCE(0x00f3, 1, 0x42),SCE(0x00d4, 0, 0x82),SCE(0x00f4, 1, 0x42),\nSCE(0x00d5, 0, 0x82),SCE(0x00f5, 1, 0x42),SCE(0x00d6, 0, 0x82),SCE(0x00f6, 1, 0x42),\nSCE(0x00d8, 0, 0x82),SCE(0x00f8, 1, 0x42),SCE(0x00d9, 0, 0x82),SCE(0x00f9, 1, 0x42),\nSCE(0x00da, 0, 0x82),SCE(0x00fa, 1, 0x42),SCE(0x00db, 0, 0x82),SCE(0x00fb, 1, 0x42),\nSCE(0x00dc, 0, 0x82),SCE(0x00fc, 1, 0x42),SCE(0x00dd, 0, 0x82),SCE(0x00fd, 1, 0x42),\nSCE(0x00de, 0, 0x82),SCE(0x00fe, 1, 0x42),SCE(0x2c25, 0, 0x82),SCE(0x2c55, 1, 0x42),\nSCE(0x2c26, 0, 0x82),SCE(0x2c56, 1, 0x42),SCE(0x2c27, 0, 0x82),SCE(0x2c57, 1, 0x42),\nSCE(0x2c28, 0, 0x82),SCE(0x2c58, 1, 0x42),SCE(0x1040f, 0, 0x82),SCE(0x10437, 1, 0x42),\nSCE(0x24cb, 0, 0x82),SCE(0x24e5, 1, 0x42),SCE(0x2c29, 0, 0x82),SCE(0x2c59, 1, 0x42),\nSCE(0x10407, 0, 0x82),SCE(0x1042f, 1, 0x42),SCE(0x2c2a, 0, 0x82),SCE(0x2c5a, 1, 0x42),\nSCE(0x0100, 0, 0x82),SCE(0x0101, 1, 0x42),SCE(0x0102, 0, 0x82),SCE(0x0103, 1, 0x42),\nSCE(0x2c2b, 0, 0x82),SCE(0x2c5b, 1, 0x42),SCE(0x0104, 0, 0x82),SCE(0x0105, 1, 0x42),\nSCE(0x0106, 0, 0x82),SCE(0x0107, 1, 0x42),SCE(0x0108, 0, 0x82),SCE(0x0109, 1, 0x42),\nSCE(0x2c2c, 0, 0x82),SCE(0x2c5c, 1, 0x42),SCE(0x010a, 0, 0x82),SCE(0x010b, 1, 0x42),\nSCE(0x010c, 0, 0x82),SCE(0x010d, 1, 0x42),SCE(0x010e, 0, 0x82),SCE(0x010f, 1, 0x42),\nSCE(0x2c2d, 0, 0x82),SCE(0x2c5d, 1, 0x42),SCE(0x0110, 0, 0x82),SCE(0x0111, 1, 0x42),\nSCE(0x0112, 0, 0x82),SCE(0x0113, 1, 0x42),SCE(0x0114, 0, 0x82),SCE(0x0115, 1, 0x42),\nSCE(0x2c2e, 0, 0x82),SCE(0x2c5e, 1, 0x42),SCE(0x0116, 0, 0x82),SCE(0x0117, 1, 0x42),\nSCE(0x0118, 0, 0x82),SCE(0x0119, 1, 0x42),SCE(0x011a, 0, 0x82),SCE(0x011b, 1, 0x42),\nSCE(0x011c, 0, 0x82),SCE(0x011d, 1, 0x42),SCE(0x011e, 0, 0x82),SCE(0x011f, 1, 0x42),\nSCE(0x0120, 0, 0x82),SCE(0x0121, 1, 0x42),SCE(0x0122, 0, 0x82),SCE(0x0123, 1, 0x42),\nSCE(0x0124, 0, 0x82),SCE(0x0125, 1, 0x42),SCE(0x0126, 0, 0x82),SCE(0x0127, 1, 0x42),\nSCE(0x0128, 0, 0x82),SCE(0x0129, 1, 0x42),SCE(0x012a, 0, 0x82),SCE(0x012b, 1, 0x42),\nSCE(0x00c5, 0, 0x83),SCE(0x00e5, 1, 0x43),SCE(0x212b, 2, 0x83),SCE(0x012c, 0, 0x82),\nSCE(0x012d, 1, 0x42),SCE(0x012e, 0, 0x82),SCE(0x012f, 1, 0x42),SCE(0x0132, 0, 0x82),\nSCE(0x0133, 1, 0x42),SCE(0x0134, 0, 0x82),SCE(0x0135, 1, 0x42),SCE(0x0136, 0, 0x82),\nSCE(0x0137, 1, 0x42),SCE(0x0139, 0, 0x82),SCE(0x013a, 1, 0x42),SCE(0x013b, 0, 0x82),\nSCE(0x013c, 1, 0x42),SCE(0x2cde, 0, 0x82),SCE(0x2cdf, 1, 0x42),SCE(0x013d, 0, 0x82),\nSCE(0x013e, 1, 0x42),SCE(0x013f, 0, 0x82),SCE(0x0140, 1, 0x42),SCE(0x0141, 0, 0x82),\nSCE(0x0142, 1, 0x42),SCE(0x0143, 0, 0x82),SCE(0x0144, 1, 0x42),SCE(0x0145, 0, 0x82),\nSCE(0x0146, 1, 0x42),SCE(0x0147, 0, 0x82),SCE(0x0148, 1, 0x42),SCE(0x014a, 0, 0x82),\nSCE(0x014b, 1, 0x42),SCE(0x014c, 0, 0x82),SCE(0x014d, 1, 0x42),SCE(0x014e, 0, 0x82),\nSCE(0x014f, 1, 0x42),SCE(0x0150, 0, 0x82),SCE(0x0151, 1, 0x42),SCE(0x0152, 0, 0x82),\nSCE(0x0153, 1, 0x42),SCE(0x0154, 0, 0x82),SCE(0x0155, 1, 0x42),SCE(0x0156, 0, 0x82),\nSCE(0x0157, 1, 0x42),SCE(0x0158, 0, 0x82),SCE(0x0159, 1, 0x42),SCE(0x015a, 0, 0x82),\nSCE(0x015b, 1, 0x42),SCE(0x015c, 0, 0x82),SCE(0x015d, 1, 0x42),SCE(0x015e, 0, 0x82),\nSCE(0x015f, 1, 0x42),SCE(0x0160, 0, 0x82),SCE(0x0161, 1, 0x42),SCE(0x2161, 0, 0x82),\nSCE(0x2171, 1, 0x42),SCE(0x0162, 0, 0x82),SCE(0x0163, 1, 0x42),SCE(0x2163, 0, 0x82),\nSCE(0x2173, 1, 0x42),SCE(0x0164, 0, 0x82),SCE(0x0165, 1, 0x42),SCE(0x2165, 0, 0x82),\nSCE(0x2175, 1, 0x42),SCE(0x0166, 0, 0x82),SCE(0x0167, 1, 0x42),SCE(0x2167, 0, 0x82),\nSCE(0x2177, 1, 0x42),SCE(0x0168, 0, 0x82),SCE(0x0169, 1, 0x42),SCE(0x2169, 0, 0x82),\nSCE(0x2179, 1, 0x42),SCE(0x016a, 0, 0x82),SCE(0x016b, 1, 0x42),SCE(0x216b, 0, 0x82),\nSCE(0x217b, 1, 0x42),SCE(0x016c, 0, 0x82),SCE(0x016d, 1, 0x42),SCE(0x216d, 0, 0x82),\nSCE(0x217d, 1, 0x42),SCE(0x016e, 0, 0x82),SCE(0x016f, 1, 0x42),SCE(0x216f, 0, 0x82),\nSCE(0x217f, 1, 0x42),SCE(0x0170, 0, 0x82),SCE(0x0171, 1, 0x42),SCE(0x2ccc, 0, 0x82),\nSCE(0x2ccd, 1, 0x42),SCE(0x0172, 0, 0x82),SCE(0x0173, 1, 0x42),SCE(0x0174, 0, 0x82),\nSCE(0x0175, 1, 0x42),SCE(0x0176, 0, 0x82),SCE(0x0177, 1, 0x42),SCE(0x00ff, 0, 0x42),\nSCE(0x0178, 1, 0x82),SCE(0x0179, 0, 0x82),SCE(0x017a, 1, 0x42),SCE(0x017b, 0, 0x82),\nSCE(0x017c, 1, 0x42),SCE(0x017d, 0, 0x82),SCE(0x017e, 1, 0x42),SCE(0x0053, 0, 0x83),\nSCE(0x0073, 1, 0x43),SCE(0x017f, 2, 0x43),SCE(0x0181, 0, 0x82),SCE(0x0253, 1, 0x42),\nSCE(0x0182, 0, 0x82),SCE(0x0183, 1, 0x42),SCE(0x2183, 0, 0x82),SCE(0x2184, 1, 0x42),\nSCE(0x0184, 0, 0x82),SCE(0x0185, 1, 0x42),SCE(0x0186, 0, 0x82),SCE(0x0254, 1, 0x42),\nSCE(0x0187, 0, 0x82),SCE(0x0188, 1, 0x42),SCE(0x0189, 0, 0x82),SCE(0x0256, 1, 0x42),\nSCE(0x018a, 0, 0x82),SCE(0x0257, 1, 0x42),SCE(0x018b, 0, 0x82),SCE(0x018c, 1, 0x42),\nSCE(0x018e, 0, 0x82),SCE(0x01dd, 1, 0x42),SCE(0x018f, 0, 0x82),SCE(0x0259, 1, 0x42),\nSCE(0x0190, 0, 0x82),SCE(0x025b, 1, 0x42),SCE(0x0191, 0, 0x82),SCE(0x0192, 1, 0x42),\nSCE(0x0193, 0, 0x82),SCE(0x0260, 1, 0x42),SCE(0x0194, 0, 0x82),SCE(0x0263, 1, 0x42),\nSCE(0x0196, 0, 0x82),SCE(0x0269, 1, 0x42),SCE(0x0197, 0, 0x82),SCE(0x0268, 1, 0x42),\nSCE(0x0198, 0, 0x82),SCE(0x0199, 1, 0x42),SCE(0x019c, 0, 0x82),SCE(0x026f, 1, 0x42),\nSCE(0x019d, 0, 0x82),SCE(0x0272, 1, 0x42),SCE(0x019f, 0, 0x82),SCE(0x0275, 1, 0x42),\nSCE(0x01a0, 0, 0x82),SCE(0x01a1, 1, 0x42),SCE(0x01a2, 0, 0x82),SCE(0x01a3, 1, 0x42),\nSCE(0x01a4, 0, 0x82),SCE(0x01a5, 1, 0x42),SCE(0x01a6, 0, 0x82),SCE(0x0280, 1, 0x42),\nSCE(0x01a7, 0, 0x82),SCE(0x01a8, 1, 0x42),SCE(0x01a9, 0, 0x82),SCE(0x0283, 1, 0x42),\nSCE(0x01ac, 0, 0x82),SCE(0x01ad, 1, 0x42),SCE(0x01ae, 0, 0x82),SCE(0x0288, 1, 0x42),\nSCE(0x01af, 0, 0x82),SCE(0x01b0, 1, 0x42),SCE(0x01b1, 0, 0x82),SCE(0x028a, 1, 0x42),\nSCE(0x01b2, 0, 0x82),SCE(0x028b, 1, 0x42),SCE(0x01b3, 0, 0x82),SCE(0x01b4, 1, 0x42),\nSCE(0x01b5, 0, 0x82),SCE(0x01b6, 1, 0x42),SCE(0x01b7, 0, 0x82),SCE(0x0292, 1, 0x42),\nSCE(0x01b8, 0, 0x82),SCE(0x01b9, 1, 0x42),SCE(0x01bc, 0, 0x82),SCE(0x01bd, 1, 0x42),\nSCE(0x01c4, 0, 0x83),SCE(0x01c5, 1, 0x3),SCE(0x01c6, 2, 0x43),SCE(0x01c4, 0, 0x83),\nSCE(0x01c5, 1, 0x3),SCE(0x01c6, 2, 0x43),SCE(0x01c7, 0, 0x83),SCE(0x01c8, 1, 0x3),\nSCE(0x01c9, 2, 0x43),SCE(0x01c7, 0, 0x83),SCE(0x01c8, 1, 0x3),SCE(0x01c9, 2, 0x43),\nSCE(0x01ca, 0, 0x83),SCE(0x01cb, 1, 0x3),SCE(0x01cc, 2, 0x43),SCE(0x01ca, 0, 0x83),\nSCE(0x01cb, 1, 0x3),SCE(0x01cc, 2, 0x43),SCE(0x01cd, 0, 0x82),SCE(0x01ce, 1, 0x42),\nSCE(0x01cf, 0, 0x82),SCE(0x01d0, 1, 0x42),SCE(0x01d1, 0, 0x82),SCE(0x01d2, 1, 0x42),\nSCE(0x01d3, 0, 0x82),SCE(0x01d4, 1, 0x42),SCE(0x01d5, 0, 0x82),SCE(0x01d6, 1, 0x42),\nSCE(0x01d7, 0, 0x82),SCE(0x01d8, 1, 0x42),SCE(0x01d9, 0, 0x82),SCE(0x01da, 1, 0x42),\nSCE(0x01db, 0, 0x82),SCE(0x01dc, 1, 0x42),SCE(0x01de, 0, 0x82),SCE(0x01df, 1, 0x42),\nSCE(0xff36, 0, 0x82),SCE(0xff56, 1, 0x42),SCE(0x01e0, 0, 0x82),SCE(0x01e1, 1, 0x42),\nSCE(0x01e2, 0, 0x82),SCE(0x01e3, 1, 0x42),SCE(0x01e4, 0, 0x82),SCE(0x01e5, 1, 0x42),\nSCE(0x01e6, 0, 0x82),SCE(0x01e7, 1, 0x42),SCE(0x01e8, 0, 0x82),SCE(0x01e9, 1, 0x42),\nSCE(0x01ea, 0, 0x82),SCE(0x01eb, 1, 0x42),SCE(0x01ec, 0, 0x82),SCE(0x01ed, 1, 0x42),\nSCE(0x01ee, 0, 0x82),SCE(0x01ef, 1, 0x42),SCE(0x01f1, 0, 0x83),SCE(0x01f2, 1, 0x3),\nSCE(0x01f3, 2, 0x43),SCE(0x01f1, 0, 0x83),SCE(0x01f2, 1, 0x3),SCE(0x01f3, 2, 0x43),\nSCE(0x01f4, 0, 0x82),SCE(0x01f5, 1, 0x42),SCE(0x0195, 0, 0x42),SCE(0x01f6, 1, 0x82),\nSCE(0x01bf, 0, 0x42),SCE(0x01f7, 1, 0x82),SCE(0x01f8, 0, 0x82),SCE(0x01f9, 1, 0x42),\nSCE(0x1041d, 0, 0x82),SCE(0x10445, 1, 0x42),SCE(0x01fa, 0, 0x82),SCE(0x01fb, 1, 0x42),\nSCE(0x01fc, 0, 0x82),SCE(0x01fd, 1, 0x42),SCE(0x01fe, 0, 0x82),SCE(0x01ff, 1, 0x42),\nSCE(0x0200, 0, 0x82),SCE(0x0201, 1, 0x42),SCE(0x0202, 0, 0x82),SCE(0x0203, 1, 0x42),\nSCE(0x0204, 0, 0x82),SCE(0x0205, 1, 0x42),SCE(0x0206, 0, 0x82),SCE(0x0207, 1, 0x42),\nSCE(0x0208, 0, 0x82),SCE(0x0209, 1, 0x42),SCE(0x020a, 0, 0x82),SCE(0x020b, 1, 0x42),\nSCE(0x020c, 0, 0x82),SCE(0x020d, 1, 0x42),SCE(0x020e, 0, 0x82),SCE(0x020f, 1, 0x42),\nSCE(0x0210, 0, 0x82),SCE(0x0211, 1, 0x42),SCE(0x0212, 0, 0x82),SCE(0x0213, 1, 0x42),\nSCE(0x0214, 0, 0x82),SCE(0x0215, 1, 0x42),SCE(0x0216, 0, 0x82),SCE(0x0217, 1, 0x42),\nSCE(0x0218, 0, 0x82),SCE(0x0219, 1, 0x42),SCE(0x021a, 0, 0x82),SCE(0x021b, 1, 0x42),\nSCE(0x021c, 0, 0x82),SCE(0x021d, 1, 0x42),SCE(0x021e, 0, 0x82),SCE(0x021f, 1, 0x42),\nSCE(0x019e, 0, 0x42),SCE(0x0220, 1, 0x82),SCE(0x0222, 0, 0x82),SCE(0x0223, 1, 0x42),\nSCE(0x0224, 0, 0x82),SCE(0x0225, 1, 0x42),SCE(0x0226, 0, 0x82),SCE(0x0227, 1, 0x42),\nSCE(0x0228, 0, 0x82),SCE(0x0229, 1, 0x42),SCE(0x022a, 0, 0x82),SCE(0x022b, 1, 0x42),\nSCE(0x022c, 0, 0x82),SCE(0x022d, 1, 0x42),SCE(0x022e, 0, 0x82),SCE(0x022f, 1, 0x42),\nSCE(0x0230, 0, 0x82),SCE(0x0231, 1, 0x42),SCE(0x0232, 0, 0x82),SCE(0x0233, 1, 0x42),\nSCE(0xa684, 0, 0x82),SCE(0xa685, 1, 0x42),SCE(0x023a, 0, 0x82),SCE(0x2c65, 1, 0x42),\nSCE(0x023b, 0, 0x82),SCE(0x023c, 1, 0x42),SCE(0x019a, 0, 0x42),SCE(0x023d, 1, 0x82),\nSCE(0x023e, 0, 0x82),SCE(0x2c66, 1, 0x42),SCE(0x0241, 0, 0x82),SCE(0x0242, 1, 0x42),\nSCE(0x10412, 0, 0x82),SCE(0x1043a, 1, 0x42),SCE(0x0180, 0, 0x42),SCE(0x0243, 1, 0x82),\nSCE(0x0244, 0, 0x82),SCE(0x0289, 1, 0x42),SCE(0x0245, 0, 0x82),SCE(0x028c, 1, 0x42),\nSCE(0x0246, 0, 0x82),SCE(0x0247, 1, 0x42),SCE(0x0248, 0, 0x82),SCE(0x0249, 1, 0x42),\nSCE(0x024a, 0, 0x82),SCE(0x024b, 1, 0x42),SCE(0x024c, 0, 0x82),SCE(0x024d, 1, 0x42),\nSCE(0x2c1b, 0, 0x82),SCE(0x2c4b, 1, 0x42),SCE(0x024e, 0, 0x82),SCE(0x024f, 1, 0x42),\nSCE(0x1040a, 0, 0x82),SCE(0x10432, 1, 0x42),SCE(0x2160, 0, 0x82),SCE(0x2170, 1, 0x42),\nSCE(0xa692, 0, 0x82),SCE(0xa693, 1, 0x42),SCE(0x027d, 0, 0x42),SCE(0x2c64, 1, 0x82),\nSCE(0x10410, 0, 0x82),SCE(0x10438, 1, 0x42),SCE(0x2c21, 0, 0x82),SCE(0x2c51, 1, 0x42),\nSCE(0x2c69, 0, 0x82),SCE(0x2c6a, 1, 0x42),SCE(0x10409, 0, 0x82),SCE(0x10431, 1, 0x42),\nSCE(0x10414, 0, 0x82),SCE(0x1043c, 1, 0x42),SCE(0x2162, 0, 0x82),SCE(0x2172, 1, 0x42),\nSCE(0x1041e, 0, 0x82),SCE(0x10446, 1, 0x42),SCE(0x0271, 0, 0x42),SCE(0x2c6e, 1, 0x82),\nSCE(0x10415, 0, 0x82),SCE(0x1043d, 1, 0x42),SCE(0x0252, 0, 0x42),SCE(0x2c70, 1, 0x82),\nSCE(0x2c72, 0, 0x82),SCE(0x2c73, 1, 0x42),SCE(0x2c0b, 0, 0x82),SCE(0x2c3b, 1, 0x42),\nSCE(0x10416, 0, 0x82),SCE(0x1043e, 1, 0x42),SCE(0x2c75, 0, 0x82),SCE(0x2c76, 1, 0x42),\nSCE(0x2164, 0, 0x82),SCE(0x2174, 1, 0x42),SCE(0xa640, 0, 0x82),SCE(0xa641, 1, 0x42),\nSCE(0xff22, 0, 0x82),SCE(0xff42, 1, 0x42),SCE(0x2c0c, 0, 0x82),SCE(0x2c3c, 1, 0x42),\nSCE(0x10417, 0, 0x82),SCE(0x1043f, 1, 0x42),SCE(0xff24, 0, 0x82),SCE(0xff44, 1, 0x42),\nSCE(0xff25, 0, 0x82),SCE(0xff45, 1, 0x42),SCE(0xff26, 0, 0x82),SCE(0xff46, 1, 0x42),\nSCE(0x2c0d, 0, 0x82),SCE(0x2c3d, 1, 0x42),SCE(0x24c1, 0, 0x82),SCE(0x24db, 1, 0x42),\nSCE(0xa728, 0, 0x82),SCE(0xa729, 1, 0x42),SCE(0x023f, 0, 0x42),SCE(0x2c7e, 1, 0x82),\nSCE(0x10411, 0, 0x82),SCE(0x10439, 1, 0x42),SCE(0xff29, 0, 0x82),SCE(0xff49, 1, 0x42),\nSCE(0x1040b, 0, 0x82),SCE(0x10433, 1, 0x42),SCE(0xa72a, 0, 0x82),SCE(0xa72b, 1, 0x42),\nSCE(0x2c80, 0, 0x82),SCE(0x2c81, 1, 0x42),SCE(0xff2b, 0, 0x82),SCE(0xff4b, 1, 0x42),\nSCE(0xa72c, 0, 0x82),SCE(0xa72d, 1, 0x42),SCE(0x2c0e, 0, 0x82),SCE(0x2c3e, 1, 0x42),\nSCE(0xff2d, 0, 0x82),SCE(0xff4d, 1, 0x42),SCE(0x10419, 0, 0x82),SCE(0x10441, 1, 0x42),\nSCE(0xa72e, 0, 0x82),SCE(0xa72f, 1, 0x42),SCE(0x1040d, 0, 0x82),SCE(0x10435, 1, 0x42),\nSCE(0xff2f, 0, 0x82),SCE(0xff4f, 1, 0x42),SCE(0xff31, 0, 0x82),SCE(0xff51, 1, 0x42),\nSCE(0xff32, 0, 0x82),SCE(0xff52, 1, 0x42),SCE(0x1041a, 0, 0x82),SCE(0x10442, 1, 0x42),\nSCE(0xff34, 0, 0x82),SCE(0xff54, 1, 0x42),SCE(0x2c98, 0, 0x82),SCE(0x2c99, 1, 0x42),\nSCE(0x2c8a, 0, 0x82),SCE(0x2c8b, 1, 0x42),SCE(0x0345, 0, 0x44),SCE(0x0399, 1, 0x84),\nSCE(0x03b9, 2, 0x44),SCE(0x1fbe, 3, 0x44),SCE(0x2c8c, 0, 0x82),SCE(0x2c8d, 1, 0x42),\nSCE(0xff37, 0, 0x82),SCE(0xff57, 1, 0x42),SCE(0xa656, 0, 0x82),SCE(0xa657, 1, 0x42),\nSCE(0x1041b, 0, 0x82),SCE(0x10443, 1, 0x42),SCE(0xa738, 0, 0x82),SCE(0xa739, 1, 0x42),\nSCE(0x2c8e, 0, 0x82),SCE(0x2c8f, 1, 0x42),SCE(0xff39, 0, 0x82),SCE(0xff59, 1, 0x42),\nSCE(0x10404, 0, 0x82),SCE(0x1042c, 1, 0x42),SCE(0xa73a, 0, 0x82),SCE(0xa73b, 1, 0x42),\nSCE(0x2c90, 0, 0x82),SCE(0x2c91, 1, 0x42),SCE(0xa73c, 0, 0x82),SCE(0xa73d, 1, 0x42),\nSCE(0x2c92, 0, 0x82),SCE(0x2c93, 1, 0x42),SCE(0x1041c, 0, 0x82),SCE(0x10444, 1, 0x42),\nSCE(0x0370, 0, 0x82),SCE(0x0371, 1, 0x42),SCE(0x0372, 0, 0x82),SCE(0x0373, 1, 0x42),\nSCE(0xa73e, 0, 0x82),SCE(0xa73f, 1, 0x42),SCE(0x0376, 0, 0x82),SCE(0x0377, 1, 0x42),\nSCE(0x2c94, 0, 0x82),SCE(0x2c95, 1, 0x42),SCE(0x2c96, 0, 0x82),SCE(0x2c97, 1, 0x42),\nSCE(0x0386, 0, 0x82),SCE(0x03ac, 1, 0x42),SCE(0x10405, 0, 0x82),SCE(0x1042d, 1, 0x42),\nSCE(0x0388, 0, 0x82),SCE(0x03ad, 1, 0x42),SCE(0x0389, 0, 0x82),SCE(0x03ae, 1, 0x42),\nSCE(0x038a, 0, 0x82),SCE(0x03af, 1, 0x42),SCE(0x038c, 0, 0x82),SCE(0x03cc, 1, 0x42),\nSCE(0x038e, 0, 0x82),SCE(0x03cd, 1, 0x42),SCE(0x038f, 0, 0x82),SCE(0x03ce, 1, 0x42),\nSCE(0x0391, 0, 0x82),SCE(0x03b1, 1, 0x42),SCE(0x0392, 0, 0x83),SCE(0x03b2, 1, 0x43),\nSCE(0x03d0, 2, 0x43),SCE(0x0393, 0, 0x82),SCE(0x03b3, 1, 0x42),SCE(0x0394, 0, 0x82),\nSCE(0x03b4, 1, 0x42),SCE(0x0395, 0, 0x83),SCE(0x03b5, 1, 0x43),SCE(0x03f5, 2, 0x43),\nSCE(0x0396, 0, 0x82),SCE(0x03b6, 1, 0x42),SCE(0x0397, 0, 0x82),SCE(0x03b7, 1, 0x42),\nSCE(0x0398, 0, 0x84),SCE(0x03b8, 1, 0x44),SCE(0x03d1, 2, 0x44),SCE(0x03f4, 3, 0x84),\nSCE(0x0345, 0, 0x44),SCE(0x0399, 1, 0x84),SCE(0x03b9, 2, 0x44),SCE(0x1fbe, 3, 0x44),\nSCE(0x039a, 0, 0x83),SCE(0x03ba, 1, 0x43),SCE(0x03f0, 2, 0x43),SCE(0x039b, 0, 0x82),\nSCE(0x03bb, 1, 0x42),SCE(0x00b5, 0, 0x43),SCE(0x039c, 1, 0x83),SCE(0x03bc, 2, 0x43),\nSCE(0x039d, 0, 0x82),SCE(0x03bd, 1, 0x42),SCE(0x039e, 0, 0x82),SCE(0x03be, 1, 0x42),\nSCE(0x039f, 0, 0x82),SCE(0x03bf, 1, 0x42),SCE(0x03a0, 0, 0x83),SCE(0x03c0, 1, 0x43),\nSCE(0x03d6, 2, 0x43),SCE(0x03a1, 0, 0x83),SCE(0x03c1, 1, 0x43),SCE(0x03f1, 2, 0x43),\nSCE(0x03a3, 0, 0x83),SCE(0x03c2, 1, 0x43),SCE(0x03c3, 2, 0x43),SCE(0x03a4, 0, 0x82),\nSCE(0x03c4, 1, 0x42),SCE(0x03a5, 0, 0x82),SCE(0x03c5, 1, 0x42),SCE(0x03a6, 0, 0x83),\nSCE(0x03c6, 1, 0x43),SCE(0x03d5, 2, 0x43),SCE(0x03a7, 0, 0x82),SCE(0x03c7, 1, 0x42),\nSCE(0x03a8, 0, 0x82),SCE(0x03c8, 1, 0x42),SCE(0x03a9, 0, 0x83),SCE(0x03c9, 1, 0x43),\nSCE(0x2126, 2, 0x83),SCE(0x03aa, 0, 0x82),SCE(0x03ca, 1, 0x42),SCE(0x03ab, 0, 0x82),\nSCE(0x03cb, 1, 0x42),SCE(0x24c9, 0, 0x82),SCE(0x24e3, 1, 0x42),SCE(0x2ce0, 0, 0x82),\nSCE(0x2ce1, 1, 0x42),SCE(0xa748, 0, 0x82),SCE(0xa749, 1, 0x42),SCE(0x2c9c, 0, 0x82),\nSCE(0x2c9d, 1, 0x42),SCE(0x2c9e, 0, 0x82),SCE(0x2c9f, 1, 0x42),SCE(0xa74a, 0, 0x82),\nSCE(0xa74b, 1, 0x42),SCE(0x2ca0, 0, 0x82),SCE(0x2ca1, 1, 0x42),SCE(0x03a3, 0, 0x83),\nSCE(0x03c2, 1, 0x43),SCE(0x03c3, 2, 0x43),SCE(0x1041f, 0, 0x82),SCE(0x10447, 1, 0x42),\nSCE(0xa74c, 0, 0x82),SCE(0xa74d, 1, 0x42),SCE(0xa68a, 0, 0x82),SCE(0xa68b, 1, 0x42),\nSCE(0x2ca2, 0, 0x82),SCE(0x2ca3, 1, 0x42),SCE(0x03cf, 0, 0x82),SCE(0x03d7, 1, 0x42),\nSCE(0x0392, 0, 0x83),SCE(0x03b2, 1, 0x43),SCE(0x03d0, 2, 0x43),SCE(0x0398, 0, 0x84),\nSCE(0x03b8, 1, 0x44),SCE(0x03d1, 2, 0x44),SCE(0x03f4, 3, 0x84),SCE(0x03a6, 0, 0x83),\nSCE(0x03c6, 1, 0x43),SCE(0x03d5, 2, 0x43),SCE(0x03a0, 0, 0x83),SCE(0x03c0, 1, 0x43),\nSCE(0x03d6, 2, 0x43),SCE(0x03d8, 0, 0x82),SCE(0x03d9, 1, 0x42),SCE(0x2ca4, 0, 0x82),\nSCE(0x2ca5, 1, 0x42),SCE(0x03da, 0, 0x82),SCE(0x03db, 1, 0x42),SCE(0x03dc, 0, 0x82),\nSCE(0x03dd, 1, 0x42),SCE(0x03de, 0, 0x82),SCE(0x03df, 1, 0x42),SCE(0x03e0, 0, 0x82),\nSCE(0x03e1, 1, 0x42),SCE(0x03e2, 0, 0x82),SCE(0x03e3, 1, 0x42),SCE(0x03e4, 0, 0x82),\nSCE(0x03e5, 1, 0x42),SCE(0x2ca6, 0, 0x82),SCE(0x2ca7, 1, 0x42),SCE(0x03e6, 0, 0x82),\nSCE(0x03e7, 1, 0x42),SCE(0x10420, 0, 0x82),SCE(0x10448, 1, 0x42),SCE(0x03e8, 0, 0x82),\nSCE(0x03e9, 1, 0x42),SCE(0x2ce2, 0, 0x82),SCE(0x2ce3, 1, 0x42),SCE(0x03ea, 0, 0x82),\nSCE(0x03eb, 1, 0x42),SCE(0x03ec, 0, 0x82),SCE(0x03ed, 1, 0x42),SCE(0x03ee, 0, 0x82),\nSCE(0x03ef, 1, 0x42),SCE(0x039a, 0, 0x83),SCE(0x03ba, 1, 0x43),SCE(0x03f0, 2, 0x43),\nSCE(0x03a1, 0, 0x83),SCE(0x03c1, 1, 0x43),SCE(0x03f1, 2, 0x43),SCE(0x0398, 0, 0x84),\nSCE(0x03b8, 1, 0x44),SCE(0x03d1, 2, 0x44),SCE(0x03f4, 3, 0x84),SCE(0x0395, 0, 0x83),\nSCE(0x03b5, 1, 0x43),SCE(0x03f5, 2, 0x43),SCE(0x03f7, 0, 0x82),SCE(0x03f8, 1, 0x42),\nSCE(0x03f2, 0, 0x42),SCE(0x03f9, 1, 0x82),SCE(0x03fa, 0, 0x82),SCE(0x03fb, 1, 0x42),\nSCE(0x037b, 0, 0x42),SCE(0x03fd, 1, 0x82),SCE(0x037c, 0, 0x42),SCE(0x03fe, 1, 0x82),\nSCE(0x037d, 0, 0x42),SCE(0x03ff, 1, 0x82),SCE(0x0400, 0, 0x82),SCE(0x0450, 1, 0x42),\nSCE(0x0401, 0, 0x82),SCE(0x0451, 1, 0x42),SCE(0x0402, 0, 0x82),SCE(0x0452, 1, 0x42),\nSCE(0x0403, 0, 0x82),SCE(0x0453, 1, 0x42),SCE(0x0404, 0, 0x82),SCE(0x0454, 1, 0x42),\nSCE(0x0405, 0, 0x82),SCE(0x0455, 1, 0x42),SCE(0x0406, 0, 0x82),SCE(0x0456, 1, 0x42),\nSCE(0x0407, 0, 0x82),SCE(0x0457, 1, 0x42),SCE(0x0408, 0, 0x82),SCE(0x0458, 1, 0x42),\nSCE(0x0409, 0, 0x82),SCE(0x0459, 1, 0x42),SCE(0x040a, 0, 0x82),SCE(0x045a, 1, 0x42),\nSCE(0x040b, 0, 0x82),SCE(0x045b, 1, 0x42),SCE(0x040c, 0, 0x82),SCE(0x045c, 1, 0x42),\nSCE(0x040d, 0, 0x82),SCE(0x045d, 1, 0x42),SCE(0x040e, 0, 0x82),SCE(0x045e, 1, 0x42),\nSCE(0x040f, 0, 0x82),SCE(0x045f, 1, 0x42),SCE(0x0410, 0, 0x82),SCE(0x0430, 1, 0x42),\nSCE(0x0411, 0, 0x82),SCE(0x0431, 1, 0x42),SCE(0x0412, 0, 0x82),SCE(0x0432, 1, 0x42),\nSCE(0x0413, 0, 0x82),SCE(0x0433, 1, 0x42),SCE(0x0414, 0, 0x82),SCE(0x0434, 1, 0x42),\nSCE(0x0415, 0, 0x82),SCE(0x0435, 1, 0x42),SCE(0x0416, 0, 0x82),SCE(0x0436, 1, 0x42),\nSCE(0x0417, 0, 0x82),SCE(0x0437, 1, 0x42),SCE(0x0418, 0, 0x82),SCE(0x0438, 1, 0x42),\nSCE(0x0419, 0, 0x82),SCE(0x0439, 1, 0x42),SCE(0x041a, 0, 0x82),SCE(0x043a, 1, 0x42),\nSCE(0x041b, 0, 0x82),SCE(0x043b, 1, 0x42),SCE(0x041c, 0, 0x82),SCE(0x043c, 1, 0x42),\nSCE(0x041d, 0, 0x82),SCE(0x043d, 1, 0x42),SCE(0x041e, 0, 0x82),SCE(0x043e, 1, 0x42),\nSCE(0x041f, 0, 0x82),SCE(0x043f, 1, 0x42),SCE(0x0420, 0, 0x82),SCE(0x0440, 1, 0x42),\nSCE(0x0421, 0, 0x82),SCE(0x0441, 1, 0x42),SCE(0x0422, 0, 0x82),SCE(0x0442, 1, 0x42),\nSCE(0x0423, 0, 0x82),SCE(0x0443, 1, 0x42),SCE(0x0424, 0, 0x82),SCE(0x0444, 1, 0x42),\nSCE(0x0425, 0, 0x82),SCE(0x0445, 1, 0x42),SCE(0x0426, 0, 0x82),SCE(0x0446, 1, 0x42),\nSCE(0x0427, 0, 0x82),SCE(0x0447, 1, 0x42),SCE(0x0428, 0, 0x82),SCE(0x0448, 1, 0x42),\nSCE(0x0429, 0, 0x82),SCE(0x0449, 1, 0x42),SCE(0x042a, 0, 0x82),SCE(0x044a, 1, 0x42),\nSCE(0x042b, 0, 0x82),SCE(0x044b, 1, 0x42),SCE(0x042c, 0, 0x82),SCE(0x044c, 1, 0x42),\nSCE(0x042d, 0, 0x82),SCE(0x044d, 1, 0x42),SCE(0x042e, 0, 0x82),SCE(0x044e, 1, 0x42),\nSCE(0x042f, 0, 0x82),SCE(0x044f, 1, 0x42),SCE(0xff3a, 0, 0x82),SCE(0xff5a, 1, 0x42),\nSCE(0x2cb4, 0, 0x82),SCE(0x2cb5, 1, 0x42),SCE(0x00b5, 0, 0x43),SCE(0x039c, 1, 0x83),\nSCE(0x03bc, 2, 0x43),SCE(0x10423, 0, 0x82),SCE(0x1044b, 1, 0x42),SCE(0x24b6, 0, 0x82),\nSCE(0x24d0, 1, 0x42),SCE(0x24b8, 0, 0x82),SCE(0x24d2, 1, 0x42),SCE(0xff2c, 0, 0x82),\nSCE(0xff4c, 1, 0x42),SCE(0x10421, 0, 0x82),SCE(0x10449, 1, 0x42),SCE(0x24ba, 0, 0x82),\nSCE(0x24d4, 1, 0x42),SCE(0x10424, 0, 0x82),SCE(0x1044c, 1, 0x42),SCE(0x0460, 0, 0x82),\nSCE(0x0461, 1, 0x42),SCE(0x0462, 0, 0x82),SCE(0x0463, 1, 0x42),SCE(0x1d7d, 0, 0x42),\nSCE(0x2c63, 1, 0x82),SCE(0x0464, 0, 0x82),SCE(0x0465, 1, 0x42),SCE(0x0466, 0, 0x82),\nSCE(0x0467, 1, 0x42),SCE(0x2c67, 0, 0x82),SCE(0x2c68, 1, 0x42),SCE(0x0468, 0, 0x82),\nSCE(0x0469, 1, 0x42),SCE(0x24bc, 0, 0x82),SCE(0x24d6, 1, 0x42),SCE(0x046a, 0, 0x82),\nSCE(0x046b, 1, 0x42),SCE(0x2c6b, 0, 0x82),SCE(0x2c6c, 1, 0x42),SCE(0x046c, 0, 0x82),\nSCE(0x046d, 1, 0x42),SCE(0x0251, 0, 0x42),SCE(0x2c6d, 1, 0x82),SCE(0x046e, 0, 0x82),\nSCE(0x046f, 1, 0x42),SCE(0x0250, 0, 0x42),SCE(0x2c6f, 1, 0x82),SCE(0x0470, 0, 0x82),\nSCE(0x0471, 1, 0x42),SCE(0xa768, 0, 0x82),SCE(0xa769, 1, 0x42),SCE(0x0472, 0, 0x82),\nSCE(0x0473, 1, 0x42),SCE(0x0474, 0, 0x82),SCE(0x0475, 1, 0x42),SCE(0x24be, 0, 0x82),\nSCE(0x24d8, 1, 0x42),SCE(0x0476, 0, 0x82),SCE(0x0477, 1, 0x42),SCE(0x0478, 0, 0x82),\nSCE(0x0479, 1, 0x42),SCE(0x047a, 0, 0x82),SCE(0x047b, 1, 0x42),SCE(0x047c, 0, 0x82),\nSCE(0x047d, 1, 0x42),SCE(0xa76a, 0, 0x82),SCE(0xa76b, 1, 0x42),SCE(0x047e, 0, 0x82),\nSCE(0x047f, 1, 0x42),SCE(0x0240, 0, 0x42),SCE(0x2c7f, 1, 0x82),SCE(0x0480, 0, 0x82),\nSCE(0x0481, 1, 0x42),SCE(0x10c0, 0, 0x82),SCE(0x2d20, 1, 0x42),SCE(0x2c82, 0, 0x82),\nSCE(0x2c83, 1, 0x42),SCE(0x2c84, 0, 0x82),SCE(0x2c85, 1, 0x42),SCE(0x2c86, 0, 0x82),\nSCE(0x2c87, 1, 0x42),SCE(0x10c1, 0, 0x82),SCE(0x2d21, 1, 0x42),SCE(0x2c88, 0, 0x82),\nSCE(0x2c89, 1, 0x42),SCE(0xa76c, 0, 0x82),SCE(0xa76d, 1, 0x42),SCE(0x048a, 0, 0x82),\nSCE(0x048b, 1, 0x42),SCE(0x048c, 0, 0x82),SCE(0x048d, 1, 0x42),SCE(0x00c2, 0, 0x82),\nSCE(0x00e2, 1, 0x42),SCE(0x048e, 0, 0x82),SCE(0x048f, 1, 0x42),SCE(0x0490, 0, 0x82),\nSCE(0x0491, 1, 0x42),SCE(0x0492, 0, 0x82),SCE(0x0493, 1, 0x42),SCE(0x10c3, 0, 0x82),\nSCE(0x2d23, 1, 0x42),SCE(0x0494, 0, 0x82),SCE(0x0495, 1, 0x42),SCE(0xa76e, 0, 0x82),\nSCE(0xa76f, 1, 0x42),SCE(0x0496, 0, 0x82),SCE(0x0497, 1, 0x42),SCE(0x0498, 0, 0x82),\nSCE(0x0499, 1, 0x42),SCE(0x00c4, 0, 0x82),SCE(0x00e4, 1, 0x42),SCE(0x049a, 0, 0x82),\nSCE(0x049b, 1, 0x42),SCE(0x10426, 0, 0x82),SCE(0x1044e, 1, 0x42),SCE(0x049c, 0, 0x82),\nSCE(0x049d, 1, 0x42),SCE(0x049e, 0, 0x82),SCE(0x049f, 1, 0x42),SCE(0x10c5, 0, 0x82),\nSCE(0x2d25, 1, 0x42),SCE(0x04a0, 0, 0x82),SCE(0x04a1, 1, 0x42),SCE(0x04a2, 0, 0x82),\nSCE(0x04a3, 1, 0x42),SCE(0x04a4, 0, 0x82),SCE(0x04a5, 1, 0x42),SCE(0x2cc6, 0, 0x82),\nSCE(0x2cc7, 1, 0x42),SCE(0x04a6, 0, 0x82),SCE(0x04a7, 1, 0x42),SCE(0x04a8, 0, 0x82),\nSCE(0x04a9, 1, 0x42),SCE(0x2c60, 0, 0x82),SCE(0x2c61, 1, 0x42),SCE(0x04aa, 0, 0x82),\nSCE(0x04ab, 1, 0x42),SCE(0x10c7, 0, 0x82),SCE(0x2d27, 1, 0x42),SCE(0x04ac, 0, 0x82),\nSCE(0x04ad, 1, 0x42),SCE(0x10413, 0, 0x82),SCE(0x1043b, 1, 0x42),SCE(0x04ae, 0, 0x82),\nSCE(0x04af, 1, 0x42),SCE(0x04b0, 0, 0x82),SCE(0x04b1, 1, 0x42),SCE(0x2cc8, 0, 0x82),\nSCE(0x2cc9, 1, 0x42),SCE(0x04b2, 0, 0x82),SCE(0x04b3, 1, 0x42),SCE(0x04b4, 0, 0x82),\nSCE(0x04b5, 1, 0x42),SCE(0x04b6, 0, 0x82),SCE(0x04b7, 1, 0x42),SCE(0x24b7, 0, 0x82),\nSCE(0x24d1, 1, 0x42),SCE(0x04b8, 0, 0x82),SCE(0x04b9, 1, 0x42),SCE(0x24b9, 0, 0x82),\nSCE(0x24d3, 1, 0x42),SCE(0x04ba, 0, 0x82),SCE(0x04bb, 1, 0x42),SCE(0x24bb, 0, 0x82),\nSCE(0x24d5, 1, 0x42),SCE(0x04bc, 0, 0x82),SCE(0x04bd, 1, 0x42),SCE(0x24bd, 0, 0x82),\nSCE(0x24d7, 1, 0x42),SCE(0x04be, 0, 0x82),SCE(0x04bf, 1, 0x42),SCE(0x24bf, 0, 0x82),\nSCE(0x24d9, 1, 0x42),SCE(0x04c0, 0, 0x82),SCE(0x04cf, 1, 0x42),SCE(0x04c1, 0, 0x82),\nSCE(0x04c2, 1, 0x42),SCE(0x24c2, 0, 0x82),SCE(0x24dc, 1, 0x42),SCE(0x04c3, 0, 0x82),\nSCE(0x04c4, 1, 0x42),SCE(0x24c4, 0, 0x82),SCE(0x24de, 1, 0x42),SCE(0x04c5, 0, 0x82),\nSCE(0x04c6, 1, 0x42),SCE(0x24c6, 0, 0x82),SCE(0x24e0, 1, 0x42),SCE(0x04c7, 0, 0x82),\nSCE(0x04c8, 1, 0x42),SCE(0x24c8, 0, 0x82),SCE(0x24e2, 1, 0x42),SCE(0x04c9, 0, 0x82),\nSCE(0x04ca, 1, 0x42),SCE(0x24ca, 0, 0x82),SCE(0x24e4, 1, 0x42),SCE(0x04cb, 0, 0x82),\nSCE(0x04cc, 1, 0x42),SCE(0x24cc, 0, 0x82),SCE(0x24e6, 1, 0x42),SCE(0x04cd, 0, 0x82),\nSCE(0x04ce, 1, 0x42),SCE(0x24ce, 0, 0x82),SCE(0x24e8, 1, 0x42),SCE(0x10cd, 0, 0x82),\nSCE(0x2d2d, 1, 0x42),SCE(0x04d0, 0, 0x82),SCE(0x04d1, 1, 0x42),SCE(0x04d2, 0, 0x82),\nSCE(0x04d3, 1, 0x42),SCE(0x04d4, 0, 0x82),SCE(0x04d5, 1, 0x42),SCE(0x2cce, 0, 0x82),\nSCE(0x2ccf, 1, 0x42),SCE(0x04d6, 0, 0x82),SCE(0x04d7, 1, 0x42),SCE(0xa779, 0, 0x82),\nSCE(0xa77a, 1, 0x42),SCE(0x04d8, 0, 0x82),SCE(0x04d9, 1, 0x42),SCE(0x04da, 0, 0x82),\nSCE(0x04db, 1, 0x42),SCE(0x24cf, 0, 0x82),SCE(0x24e9, 1, 0x42),SCE(0x04dc, 0, 0x82),\nSCE(0x04dd, 1, 0x42),SCE(0x04de, 0, 0x82),SCE(0x04df, 1, 0x42),SCE(0x04e0, 0, 0x82),\nSCE(0x04e1, 1, 0x42),SCE(0x2cd0, 0, 0x82),SCE(0x2cd1, 1, 0x42),SCE(0x04e2, 0, 0x82),\nSCE(0x04e3, 1, 0x42),SCE(0x04e4, 0, 0x82),SCE(0x04e5, 1, 0x42),SCE(0x026b, 0, 0x42),\nSCE(0x2c62, 1, 0x82),SCE(0x04e6, 0, 0x82),SCE(0x04e7, 1, 0x42),SCE(0x04e8, 0, 0x82),\nSCE(0x04e9, 1, 0x42),SCE(0x04ea, 0, 0x82),SCE(0x04eb, 1, 0x42),SCE(0x2132, 0, 0x82),\nSCE(0x214e, 1, 0x42),SCE(0x04ec, 0, 0x82),SCE(0x04ed, 1, 0x42),SCE(0x2cd2, 0, 0x82),\nSCE(0x2cd3, 1, 0x42),SCE(0x04ee, 0, 0x82),SCE(0x04ef, 1, 0x42),SCE(0x04f0, 0, 0x82),\nSCE(0x04f1, 1, 0x42),SCE(0x10422, 0, 0x82),SCE(0x1044a, 1, 0x42),SCE(0x04f2, 0, 0x82),\nSCE(0x04f3, 1, 0x42),SCE(0x04f4, 0, 0x82),SCE(0x04f5, 1, 0x42),SCE(0x04f6, 0, 0x82),\nSCE(0x04f7, 1, 0x42),SCE(0x04f8, 0, 0x82),SCE(0x04f9, 1, 0x42),SCE(0x2cd4, 0, 0x82),\nSCE(0x2cd5, 1, 0x42),SCE(0x04fa, 0, 0x82),SCE(0x04fb, 1, 0x42),SCE(0x04fc, 0, 0x82),\nSCE(0x04fd, 1, 0x42),SCE(0x04fe, 0, 0x82),SCE(0x04ff, 1, 0x42),SCE(0x0500, 0, 0x82),\nSCE(0x0501, 1, 0x42),SCE(0x0502, 0, 0x82),SCE(0x0503, 1, 0x42),SCE(0x0504, 0, 0x82),\nSCE(0x0505, 1, 0x42),SCE(0x2cd6, 0, 0x82),SCE(0x2cd7, 1, 0x42),SCE(0x0506, 0, 0x82),\nSCE(0x0507, 1, 0x42),SCE(0x0508, 0, 0x82),SCE(0x0509, 1, 0x42),SCE(0x050a, 0, 0x82),\nSCE(0x050b, 1, 0x42),SCE(0x050c, 0, 0x82),SCE(0x050d, 1, 0x42),SCE(0x050e, 0, 0x82),\nSCE(0x050f, 1, 0x42),SCE(0x0510, 0, 0x82),SCE(0x0511, 1, 0x42),SCE(0x2cd8, 0, 0x82),\nSCE(0x2cd9, 1, 0x42),SCE(0x0512, 0, 0x82),SCE(0x0513, 1, 0x42),SCE(0x0514, 0, 0x82),\nSCE(0x0515, 1, 0x42),SCE(0x0516, 0, 0x82),SCE(0x0517, 1, 0x42),SCE(0x0518, 0, 0x82),\nSCE(0x0519, 1, 0x42),SCE(0x051a, 0, 0x82),SCE(0x051b, 1, 0x42),SCE(0x2ca8, 0, 0x82),\nSCE(0x2ca9, 1, 0x42),SCE(0x051c, 0, 0x82),SCE(0x051d, 1, 0x42),SCE(0x2cda, 0, 0x82),\nSCE(0x2cdb, 1, 0x42),SCE(0x051e, 0, 0x82),SCE(0x051f, 1, 0x42),SCE(0x0520, 0, 0x82),\nSCE(0x0521, 1, 0x42),SCE(0x0522, 0, 0x82),SCE(0x0523, 1, 0x42),SCE(0x0524, 0, 0x82),\nSCE(0x0525, 1, 0x42),SCE(0x0526, 0, 0x82),SCE(0x0527, 1, 0x42),SCE(0x2c20, 0, 0x82),\nSCE(0x2c50, 1, 0x42),SCE(0x2cdc, 0, 0x82),SCE(0x2cdd, 1, 0x42),SCE(0x0531, 0, 0x82),\nSCE(0x0561, 1, 0x42),SCE(0x0532, 0, 0x82),SCE(0x0562, 1, 0x42),SCE(0x0533, 0, 0x82),\nSCE(0x0563, 1, 0x42),SCE(0x0534, 0, 0x82),SCE(0x0564, 1, 0x42),SCE(0x0535, 0, 0x82),\nSCE(0x0565, 1, 0x42),SCE(0x0536, 0, 0x82),SCE(0x0566, 1, 0x42),SCE(0x0537, 0, 0x82),\nSCE(0x0567, 1, 0x42),SCE(0x0538, 0, 0x82),SCE(0x0568, 1, 0x42),SCE(0x0539, 0, 0x82),\nSCE(0x0569, 1, 0x42),SCE(0x053a, 0, 0x82),SCE(0x056a, 1, 0x42),SCE(0x053b, 0, 0x82),\nSCE(0x056b, 1, 0x42),SCE(0x053c, 0, 0x82),SCE(0x056c, 1, 0x42),SCE(0x053d, 0, 0x82),\nSCE(0x056d, 1, 0x42),SCE(0x053e, 0, 0x82),SCE(0x056e, 1, 0x42),SCE(0x053f, 0, 0x82),\nSCE(0x056f, 1, 0x42),SCE(0x0540, 0, 0x82),SCE(0x0570, 1, 0x42),SCE(0x0541, 0, 0x82),\nSCE(0x0571, 1, 0x42),SCE(0x0542, 0, 0x82),SCE(0x0572, 1, 0x42),SCE(0x0543, 0, 0x82),\nSCE(0x0573, 1, 0x42),SCE(0x0544, 0, 0x82),SCE(0x0574, 1, 0x42),SCE(0x0545, 0, 0x82),\nSCE(0x0575, 1, 0x42),SCE(0x0546, 0, 0x82),SCE(0x0576, 1, 0x42),SCE(0x0547, 0, 0x82),\nSCE(0x0577, 1, 0x42),SCE(0x0548, 0, 0x82),SCE(0x0578, 1, 0x42),SCE(0x0549, 0, 0x82),\nSCE(0x0579, 1, 0x42),SCE(0x054a, 0, 0x82),SCE(0x057a, 1, 0x42),SCE(0x054b, 0, 0x82),\nSCE(0x057b, 1, 0x42),SCE(0x054c, 0, 0x82),SCE(0x057c, 1, 0x42),SCE(0x054d, 0, 0x82),\nSCE(0x057d, 1, 0x42),SCE(0x054e, 0, 0x82),SCE(0x057e, 1, 0x42),SCE(0x054f, 0, 0x82),\nSCE(0x057f, 1, 0x42),SCE(0x0550, 0, 0x82),SCE(0x0580, 1, 0x42),SCE(0x0551, 0, 0x82),\nSCE(0x0581, 1, 0x42),SCE(0x0552, 0, 0x82),SCE(0x0582, 1, 0x42),SCE(0x0553, 0, 0x82),\nSCE(0x0583, 1, 0x42),SCE(0x0554, 0, 0x82),SCE(0x0584, 1, 0x42),SCE(0x0555, 0, 0x82),\nSCE(0x0585, 1, 0x42),SCE(0x0556, 0, 0x82),SCE(0x0586, 1, 0x42),SCE(0x2caa, 0, 0x82),\nSCE(0x2cab, 1, 0x42),SCE(0x2c22, 0, 0x82),SCE(0x2c52, 1, 0x42),SCE(0x2c23, 0, 0x82),\nSCE(0x2c53, 1, 0x42),SCE(0x2ceb, 0, 0x82),SCE(0x2cec, 1, 0x42),SCE(0x2cca, 0, 0x82),\nSCE(0x2ccb, 1, 0x42),SCE(0xa642, 0, 0x82),SCE(0xa643, 1, 0x42),SCE(0x2ced, 0, 0x82),\nSCE(0x2cee, 1, 0x42),SCE(0x2cac, 0, 0x82),SCE(0x2cad, 1, 0x42),SCE(0xa644, 0, 0x82),\nSCE(0xa645, 1, 0x42),SCE(0x2c24, 0, 0x82),SCE(0x2c54, 1, 0x42),SCE(0xa646, 0, 0x82),\nSCE(0xa647, 1, 0x42),SCE(0x2cf2, 0, 0x82),SCE(0x2cf3, 1, 0x42),SCE(0x10408, 0, 0x82),\nSCE(0x10430, 1, 0x42),SCE(0xa648, 0, 0x82),SCE(0xa649, 1, 0x42),SCE(0xa64a, 0, 0x82),\nSCE(0xa64b, 1, 0x42),SCE(0xa64c, 0, 0x82),SCE(0xa64d, 1, 0x42),SCE(0x2cae, 0, 0x82),\nSCE(0x2caf, 1, 0x42),SCE(0xa64e, 0, 0x82),SCE(0xa64f, 1, 0x42),SCE(0xa650, 0, 0x82),\nSCE(0xa651, 1, 0x42),SCE(0xa78b, 0, 0x82),SCE(0xa78c, 1, 0x42),SCE(0xa652, 0, 0x82),\nSCE(0xa653, 1, 0x42),SCE(0xa7a8, 0, 0x82),SCE(0xa7a9, 1, 0x42),SCE(0xa654, 0, 0x82),\nSCE(0xa655, 1, 0x42),SCE(0x0266, 0, 0x42),SCE(0xa7aa, 1, 0x82),SCE(0x1e00, 0, 0x82),\nSCE(0x1e01, 1, 0x42),SCE(0x1e02, 0, 0x82),SCE(0x1e03, 1, 0x42),SCE(0x1e04, 0, 0x82),\nSCE(0x1e05, 1, 0x42),SCE(0x2c1f, 0, 0x82),SCE(0x2c4f, 1, 0x42),SCE(0x1e06, 0, 0x82),\nSCE(0x1e07, 1, 0x42),SCE(0x1040e, 0, 0x82),SCE(0x10436, 1, 0x42),SCE(0x1e08, 0, 0x82),\nSCE(0x1e09, 1, 0x42),SCE(0x1e0a, 0, 0x82),SCE(0x1e0b, 1, 0x42),SCE(0x2cb0, 0, 0x82),\nSCE(0x2cb1, 1, 0x42),SCE(0x1e0c, 0, 0x82),SCE(0x1e0d, 1, 0x42),SCE(0x1e0e, 0, 0x82),\nSCE(0x1e0f, 1, 0x42),SCE(0x1e10, 0, 0x82),SCE(0x1e11, 1, 0x42),SCE(0xa658, 0, 0x82),\nSCE(0xa659, 1, 0x42),SCE(0x1e12, 0, 0x82),SCE(0x1e13, 1, 0x42),SCE(0x1e14, 0, 0x82),\nSCE(0x1e15, 1, 0x42),SCE(0x24cd, 0, 0x82),SCE(0x24e7, 1, 0x42),SCE(0x1e16, 0, 0x82),\nSCE(0x1e17, 1, 0x42),SCE(0x1e18, 0, 0x82),SCE(0x1e19, 1, 0x42),SCE(0x1e1a, 0, 0x82),\nSCE(0x1e1b, 1, 0x42),SCE(0x1e1c, 0, 0x82),SCE(0x1e1d, 1, 0x42),SCE(0xa65a, 0, 0x82),\nSCE(0xa65b, 1, 0x42),SCE(0x1e1e, 0, 0x82),SCE(0x1e1f, 1, 0x42),SCE(0x1e20, 0, 0x82),\nSCE(0x1e21, 1, 0x42),SCE(0x1e22, 0, 0x82),SCE(0x1e23, 1, 0x42),SCE(0x1e24, 0, 0x82),\nSCE(0x1e25, 1, 0x42),SCE(0x1e26, 0, 0x82),SCE(0x1e27, 1, 0x42),SCE(0x1e28, 0, 0x82),\nSCE(0x1e29, 1, 0x42),SCE(0xa65c, 0, 0x82),SCE(0xa65d, 1, 0x42),SCE(0x1e2a, 0, 0x82),\nSCE(0x1e2b, 1, 0x42),SCE(0x1e2c, 0, 0x82),SCE(0x1e2d, 1, 0x42),SCE(0x1e2e, 0, 0x82),\nSCE(0x1e2f, 1, 0x42),SCE(0x1e30, 0, 0x82),SCE(0x1e31, 1, 0x42),SCE(0x1e32, 0, 0x82),\nSCE(0x1e33, 1, 0x42),SCE(0x1e34, 0, 0x82),SCE(0x1e35, 1, 0x42),SCE(0xa65e, 0, 0x82),\nSCE(0xa65f, 1, 0x42),SCE(0x1e36, 0, 0x82),SCE(0x1e37, 1, 0x42),SCE(0x1e38, 0, 0x82),\nSCE(0x1e39, 1, 0x42),SCE(0x1e3a, 0, 0x82),SCE(0x1e3b, 1, 0x42),SCE(0x1e3c, 0, 0x82),\nSCE(0x1e3d, 1, 0x42),SCE(0x1e3e, 0, 0x82),SCE(0x1e3f, 1, 0x42),SCE(0x1e40, 0, 0x82),\nSCE(0x1e41, 1, 0x42),SCE(0xa660, 0, 0x82),SCE(0xa661, 1, 0x42),SCE(0x1e42, 0, 0x82),\nSCE(0x1e43, 1, 0x42),SCE(0x1e44, 0, 0x82),SCE(0x1e45, 1, 0x42),SCE(0x1e46, 0, 0x82),\nSCE(0x1e47, 1, 0x42),SCE(0x2cb2, 0, 0x82),SCE(0x2cb3, 1, 0x42),SCE(0x1e48, 0, 0x82),\nSCE(0x1e49, 1, 0x42),SCE(0x2cc0, 0, 0x82),SCE(0x2cc1, 1, 0x42),SCE(0x1e4a, 0, 0x82),\nSCE(0x1e4b, 1, 0x42),SCE(0x1e4c, 0, 0x82),SCE(0x1e4d, 1, 0x42),SCE(0xa662, 0, 0x82),\nSCE(0xa663, 1, 0x42),SCE(0x1e4e, 0, 0x82),SCE(0x1e4f, 1, 0x42),SCE(0x1e50, 0, 0x82),\nSCE(0x1e51, 1, 0x42),SCE(0x1e52, 0, 0x82),SCE(0x1e53, 1, 0x42),SCE(0x1e54, 0, 0x82),\nSCE(0x1e55, 1, 0x42),SCE(0x1e56, 0, 0x82),SCE(0x1e57, 1, 0x42),SCE(0x1e58, 0, 0x82),\nSCE(0x1e59, 1, 0x42),SCE(0xa664, 0, 0x82),SCE(0xa665, 1, 0x42),SCE(0x1e5a, 0, 0x82),\nSCE(0x1e5b, 1, 0x42),SCE(0x1e5c, 0, 0x82),SCE(0x1e5d, 1, 0x42),SCE(0x1e5e, 0, 0x82),\nSCE(0x1e5f, 1, 0x42),SCE(0x1e60, 0, 0x83),SCE(0x1e61, 1, 0x43),SCE(0x1e9b, 2, 0x43),\nSCE(0x1e62, 0, 0x82),SCE(0x1e63, 1, 0x42),SCE(0x1e64, 0, 0x82),SCE(0x1e65, 1, 0x42),\nSCE(0xa666, 0, 0x82),SCE(0xa667, 1, 0x42),SCE(0x1e66, 0, 0x82),SCE(0x1e67, 1, 0x42),\nSCE(0x1e68, 0, 0x82),SCE(0x1e69, 1, 0x42),SCE(0x1e6a, 0, 0x82),SCE(0x1e6b, 1, 0x42),\nSCE(0x1e6c, 0, 0x82),SCE(0x1e6d, 1, 0x42),SCE(0x1e6e, 0, 0x82),SCE(0x1e6f, 1, 0x42),\nSCE(0x1e70, 0, 0x82),SCE(0x1e71, 1, 0x42),SCE(0xa668, 0, 0x82),SCE(0xa669, 1, 0x42),\nSCE(0x1e72, 0, 0x82),SCE(0x1e73, 1, 0x42),SCE(0x1e74, 0, 0x82),SCE(0x1e75, 1, 0x42),\nSCE(0x1e76, 0, 0x82),SCE(0x1e77, 1, 0x42),SCE(0x2cbe, 0, 0x82),SCE(0x2cbf, 1, 0x42),\nSCE(0x1e78, 0, 0x82),SCE(0x1e79, 1, 0x42),SCE(0x1e7a, 0, 0x82),SCE(0x1e7b, 1, 0x42),\nSCE(0x1e7c, 0, 0x82),SCE(0x1e7d, 1, 0x42),SCE(0xa66a, 0, 0x82),SCE(0xa66b, 1, 0x42),\nSCE(0x1e7e, 0, 0x82),SCE(0x1e7f, 1, 0x42),SCE(0x1e80, 0, 0x82),SCE(0x1e81, 1, 0x42),\nSCE(0x1e82, 0, 0x82),SCE(0x1e83, 1, 0x42),SCE(0x1e84, 0, 0x82),SCE(0x1e85, 1, 0x42),\nSCE(0x1e86, 0, 0x82),SCE(0x1e87, 1, 0x42),SCE(0x1e88, 0, 0x82),SCE(0x1e89, 1, 0x42),\nSCE(0xa66c, 0, 0x82),SCE(0xa66d, 1, 0x42),SCE(0x1e8a, 0, 0x82),SCE(0x1e8b, 1, 0x42),\nSCE(0x1e8c, 0, 0x82),SCE(0x1e8d, 1, 0x42),SCE(0x1e8e, 0, 0x82),SCE(0x1e8f, 1, 0x42),\nSCE(0x1e90, 0, 0x82),SCE(0x1e91, 1, 0x42),SCE(0x1e92, 0, 0x82),SCE(0x1e93, 1, 0x42),\nSCE(0x1e94, 0, 0x82),SCE(0x1e95, 1, 0x42),SCE(0xa696, 0, 0x82),SCE(0xa697, 1, 0x42),\nSCE(0x10406, 0, 0x82),SCE(0x1042e, 1, 0x42),SCE(0x1e60, 0, 0x83),SCE(0x1e61, 1, 0x43),\nSCE(0x1e9b, 2, 0x43),SCE(0x00df, 0, 0x42),SCE(0x1e9e, 1, 0x82),SCE(0x1ea0, 0, 0x82),\nSCE(0x1ea1, 1, 0x42),SCE(0x1ea2, 0, 0x82),SCE(0x1ea3, 1, 0x42),SCE(0x1ea4, 0, 0x82),\nSCE(0x1ea5, 1, 0x42),SCE(0x24c5, 0, 0x82),SCE(0x24df, 1, 0x42),SCE(0x1ea6, 0, 0x82),\nSCE(0x1ea7, 1, 0x42),SCE(0x1ea8, 0, 0x82),SCE(0x1ea9, 1, 0x42),SCE(0x1eaa, 0, 0x82),\nSCE(0x1eab, 1, 0x42),SCE(0x1eac, 0, 0x82),SCE(0x1ead, 1, 0x42),SCE(0x1eae, 0, 0x82),\nSCE(0x1eaf, 1, 0x42),SCE(0xff28, 0, 0x82),SCE(0xff48, 1, 0x42),SCE(0x1eb0, 0, 0x82),\nSCE(0x1eb1, 1, 0x42),SCE(0x1eb2, 0, 0x82),SCE(0x1eb3, 1, 0x42),SCE(0x10425, 0, 0x82),\nSCE(0x1044d, 1, 0x42),SCE(0x1eb4, 0, 0x82),SCE(0x1eb5, 1, 0x42),SCE(0x1eb6, 0, 0x82),\nSCE(0x1eb7, 1, 0x42),SCE(0x1eb8, 0, 0x82),SCE(0x1eb9, 1, 0x42),SCE(0x1eba, 0, 0x82),\nSCE(0x1ebb, 1, 0x42),SCE(0x1ebc, 0, 0x82),SCE(0x1ebd, 1, 0x42),SCE(0x1ebe, 0, 0x82),\nSCE(0x1ebf, 1, 0x42),SCE(0x2cb6, 0, 0x82),SCE(0x2cb7, 1, 0x42),SCE(0x1ec0, 0, 0x82),\nSCE(0x1ec1, 1, 0x42),SCE(0x1ec2, 0, 0x82),SCE(0x1ec3, 1, 0x42),SCE(0x2c9a, 0, 0x82),\nSCE(0x2c9b, 1, 0x42),SCE(0x1ec4, 0, 0x82),SCE(0x1ec5, 1, 0x42),SCE(0x1ec6, 0, 0x82),\nSCE(0x1ec7, 1, 0x42),SCE(0x1ec8, 0, 0x82),SCE(0x1ec9, 1, 0x42),SCE(0x1eca, 0, 0x82),\nSCE(0x1ecb, 1, 0x42),SCE(0x1ecc, 0, 0x82),SCE(0x1ecd, 1, 0x42),SCE(0x1ece, 0, 0x82),\nSCE(0x1ecf, 1, 0x42),SCE(0x1ed0, 0, 0x82),SCE(0x1ed1, 1, 0x42),SCE(0x1ed2, 0, 0x82),\nSCE(0x1ed3, 1, 0x42),SCE(0x1ed4, 0, 0x82),SCE(0x1ed5, 1, 0x42),SCE(0x1ed6, 0, 0x82),\nSCE(0x1ed7, 1, 0x42),SCE(0x1ed8, 0, 0x82),SCE(0x1ed9, 1, 0x42),SCE(0x1eda, 0, 0x82),\nSCE(0x1edb, 1, 0x42),SCE(0x1edc, 0, 0x82),SCE(0x1edd, 1, 0x42),SCE(0x1ede, 0, 0x82),\nSCE(0x1edf, 1, 0x42),SCE(0x1ee0, 0, 0x82),SCE(0x1ee1, 1, 0x42),SCE(0x1ee2, 0, 0x82),\nSCE(0x1ee3, 1, 0x42),SCE(0x1ee4, 0, 0x82),SCE(0x1ee5, 1, 0x42),SCE(0x03a9, 0, 0x83),\nSCE(0x03c9, 1, 0x43),SCE(0x2126, 2, 0x83),SCE(0x1ee6, 0, 0x82),SCE(0x1ee7, 1, 0x42),\nSCE(0x1ee8, 0, 0x82),SCE(0x1ee9, 1, 0x42),SCE(0x1eea, 0, 0x82),SCE(0x1eeb, 1, 0x42),\nSCE(0xff2a, 0, 0x82),SCE(0xff4a, 1, 0x42),SCE(0x1eec, 0, 0x82),SCE(0x1eed, 1, 0x42),\nSCE(0x1eee, 0, 0x82),SCE(0x1eef, 1, 0x42),SCE(0x1ef0, 0, 0x82),SCE(0x1ef1, 1, 0x42),\nSCE(0x1ef2, 0, 0x82),SCE(0x1ef3, 1, 0x42),SCE(0x1ef4, 0, 0x82),SCE(0x1ef5, 1, 0x42),\nSCE(0x1ef6, 0, 0x82),SCE(0x1ef7, 1, 0x42),SCE(0x1ef8, 0, 0x82),SCE(0x1ef9, 1, 0x42),\nSCE(0x1efa, 0, 0x82),SCE(0x1efb, 1, 0x42),SCE(0x2cb8, 0, 0x82),SCE(0x2cb9, 1, 0x42),\nSCE(0x1efc, 0, 0x82),SCE(0x1efd, 1, 0x42),SCE(0x004b, 0, 0x83),SCE(0x006b, 1, 0x43),\nSCE(0x212a, 2, 0x83),SCE(0x1efe, 0, 0x82),SCE(0x1eff, 1, 0x42),SCE(0xa680, 0, 0x82),\nSCE(0xa681, 1, 0x42),SCE(0x1f00, 0, 0x42),SCE(0x1f08, 1, 0x82),SCE(0x1f01, 0, 0x42),\nSCE(0x1f09, 1, 0x82),SCE(0x1f02, 0, 0x42),SCE(0x1f0a, 1, 0x82),SCE(0x1f03, 0, 0x42),\nSCE(0x1f0b, 1, 0x82),SCE(0x1f04, 0, 0x42),SCE(0x1f0c, 1, 0x82),SCE(0x1f05, 0, 0x42),\nSCE(0x1f0d, 1, 0x82),SCE(0x1f06, 0, 0x42),SCE(0x1f0e, 1, 0x82),SCE(0x1f07, 0, 0x42),\nSCE(0x1f0f, 1, 0x82),SCE(0x10418, 0, 0x82),SCE(0x10440, 1, 0x42),SCE(0x0265, 0, 0x42),\nSCE(0xa78d, 1, 0x82),SCE(0x1f10, 0, 0x42),SCE(0x1f18, 1, 0x82),SCE(0x1f11, 0, 0x42),\nSCE(0x1f19, 1, 0x82),SCE(0x1f12, 0, 0x42),SCE(0x1f1a, 1, 0x82),SCE(0x1f13, 0, 0x42),\nSCE(0x1f1b, 1, 0x82),SCE(0x1f14, 0, 0x42),SCE(0x1f1c, 1, 0x82),SCE(0x1f15, 0, 0x42),\nSCE(0x1f1d, 1, 0x82),SCE(0xff21, 0, 0x82),SCE(0xff41, 1, 0x42),SCE(0xa722, 0, 0x82),\nSCE(0xa723, 1, 0x42),SCE(0xff23, 0, 0x82),SCE(0xff43, 1, 0x42),SCE(0xa724, 0, 0x82),\nSCE(0xa725, 1, 0x42),SCE(0xa686, 0, 0x82),SCE(0xa687, 1, 0x42),SCE(0xa726, 0, 0x82),\nSCE(0xa727, 1, 0x42),SCE(0xff27, 0, 0x82),SCE(0xff47, 1, 0x42),SCE(0x1f20, 0, 0x42),\nSCE(0x1f28, 1, 0x82),SCE(0x1f21, 0, 0x42),SCE(0x1f29, 1, 0x82),SCE(0x1f22, 0, 0x42),\nSCE(0x1f2a, 1, 0x82),SCE(0x1f23, 0, 0x42),SCE(0x1f2b, 1, 0x82),SCE(0x1f24, 0, 0x42),\nSCE(0x1f2c, 1, 0x82),SCE(0x1f25, 0, 0x42),SCE(0x1f2d, 1, 0x82),SCE(0x1f26, 0, 0x42),\nSCE(0x1f2e, 1, 0x82),SCE(0x1f27, 0, 0x42),SCE(0x1f2f, 1, 0x82),SCE(0xff30, 0, 0x82),\nSCE(0xff50, 1, 0x42),SCE(0xa688, 0, 0x82),SCE(0xa689, 1, 0x42),SCE(0xa732, 0, 0x82),\nSCE(0xa733, 1, 0x42),SCE(0xff33, 0, 0x82),SCE(0xff53, 1, 0x42),SCE(0xa734, 0, 0x82),\nSCE(0xa735, 1, 0x42),SCE(0xff35, 0, 0x82),SCE(0xff55, 1, 0x42),SCE(0xa736, 0, 0x82),\nSCE(0xa737, 1, 0x42),SCE(0x2cba, 0, 0x82),SCE(0x2cbb, 1, 0x42),SCE(0x1f30, 0, 0x42),\nSCE(0x1f38, 1, 0x82),SCE(0x1f31, 0, 0x42),SCE(0x1f39, 1, 0x82),SCE(0x1f32, 0, 0x42),\nSCE(0x1f3a, 1, 0x82),SCE(0x1f33, 0, 0x42),SCE(0x1f3b, 1, 0x82),SCE(0x1f34, 0, 0x42),\nSCE(0x1f3c, 1, 0x82),SCE(0x1f35, 0, 0x42),SCE(0x1f3d, 1, 0x82),SCE(0x1f36, 0, 0x42),\nSCE(0x1f3e, 1, 0x82),SCE(0x1f37, 0, 0x42),SCE(0x1f3f, 1, 0x82),SCE(0xa740, 0, 0x82),\nSCE(0xa741, 1, 0x42),SCE(0xa742, 0, 0x82),SCE(0xa743, 1, 0x42),SCE(0xa744, 0, 0x82),\nSCE(0xa745, 1, 0x42),SCE(0xa746, 0, 0x82),SCE(0xa747, 1, 0x42),SCE(0x1f40, 0, 0x42),\nSCE(0x1f48, 1, 0x82),SCE(0x1f41, 0, 0x42),SCE(0x1f49, 1, 0x82),SCE(0x1f42, 0, 0x42),\nSCE(0x1f4a, 1, 0x82),SCE(0x1f43, 0, 0x42),SCE(0x1f4b, 1, 0x82),SCE(0x1f44, 0, 0x42),\nSCE(0x1f4c, 1, 0x82),SCE(0x1f45, 0, 0x42),SCE(0x1f4d, 1, 0x82),SCE(0xa74e, 0, 0x82),\nSCE(0xa74f, 1, 0x42),SCE(0xa750, 0, 0x82),SCE(0xa751, 1, 0x42),SCE(0xa752, 0, 0x82),\nSCE(0xa753, 1, 0x42),SCE(0xa754, 0, 0x82),SCE(0xa755, 1, 0x42),SCE(0xa68e, 0, 0x82),\nSCE(0xa68f, 1, 0x42),SCE(0xa756, 0, 0x82),SCE(0xa757, 1, 0x42),SCE(0xa758, 0, 0x82),\nSCE(0xa759, 1, 0x42),SCE(0x1f51, 0, 0x42),SCE(0x1f59, 1, 0x82),SCE(0xa75a, 0, 0x82),\nSCE(0xa75b, 1, 0x42),SCE(0x1f53, 0, 0x42),SCE(0x1f5b, 1, 0x82),SCE(0xa75c, 0, 0x82),\nSCE(0xa75d, 1, 0x42),SCE(0x1f55, 0, 0x42),SCE(0x1f5d, 1, 0x82),SCE(0xa75e, 0, 0x82),\nSCE(0xa75f, 1, 0x42),SCE(0x1f57, 0, 0x42),SCE(0x1f5f, 1, 0x82),SCE(0xa760, 0, 0x82),\nSCE(0xa761, 1, 0x42),SCE(0xa690, 0, 0x82),SCE(0xa691, 1, 0x42),SCE(0xa762, 0, 0x82),\nSCE(0xa763, 1, 0x42),SCE(0xff2e, 0, 0x82),SCE(0xff4e, 1, 0x42),SCE(0xa764, 0, 0x82),\nSCE(0xa765, 1, 0x42),SCE(0xa766, 0, 0x82),SCE(0xa767, 1, 0x42),SCE(0x1f60, 0, 0x42),\nSCE(0x1f68, 1, 0x82),SCE(0x1f61, 0, 0x42),SCE(0x1f69, 1, 0x82),SCE(0x1f62, 0, 0x42),\nSCE(0x1f6a, 1, 0x82),SCE(0x1f63, 0, 0x42),SCE(0x1f6b, 1, 0x82),SCE(0x1f64, 0, 0x42),\nSCE(0x1f6c, 1, 0x82),SCE(0x1f65, 0, 0x42),SCE(0x1f6d, 1, 0x82),SCE(0x1f66, 0, 0x42),\nSCE(0x1f6e, 1, 0x82),SCE(0x1f67, 0, 0x42),SCE(0x1f6f, 1, 0x82),SCE(0x2c1c, 0, 0x82),\nSCE(0x2c4c, 1, 0x42),SCE(0x2cbc, 0, 0x82),SCE(0x2cbd, 1, 0x42),SCE(0xa694, 0, 0x82),\nSCE(0xa695, 1, 0x42),SCE(0xa77b, 0, 0x82),SCE(0xa77c, 1, 0x42),SCE(0x1d79, 0, 0x42),\nSCE(0xa77d, 1, 0x82),SCE(0xa77e, 0, 0x82),SCE(0xa77f, 1, 0x42),SCE(0xa780, 0, 0x82),\nSCE(0xa781, 1, 0x42),SCE(0xa782, 0, 0x82),SCE(0xa783, 1, 0x42),SCE(0xa784, 0, 0x82),\nSCE(0xa785, 1, 0x42),SCE(0xa786, 0, 0x82),SCE(0xa787, 1, 0x42),SCE(0x1f80, 0, 0x42),\nSCE(0x1f88, 1, 0x2),SCE(0x1f81, 0, 0x42),SCE(0x1f89, 1, 0x2),SCE(0x1f82, 0, 0x42),\nSCE(0x1f8a, 1, 0x2),SCE(0x1f83, 0, 0x42),SCE(0x1f8b, 1, 0x2),SCE(0x1f84, 0, 0x42),\nSCE(0x1f8c, 1, 0x2),SCE(0x1f85, 0, 0x42),SCE(0x1f8d, 1, 0x2),SCE(0x1f86, 0, 0x42),\nSCE(0x1f8e, 1, 0x2),SCE(0x1f87, 0, 0x42),SCE(0x1f8f, 1, 0x2),SCE(0xa790, 0, 0x82),\nSCE(0xa791, 1, 0x42),SCE(0xa792, 0, 0x82),SCE(0xa793, 1, 0x42),SCE(0x1f90, 0, 0x42),\nSCE(0x1f98, 1, 0x2),SCE(0x1f91, 0, 0x42),SCE(0x1f99, 1, 0x2),SCE(0x1f92, 0, 0x42),\nSCE(0x1f9a, 1, 0x2),SCE(0x1f93, 0, 0x42),SCE(0x1f9b, 1, 0x2),SCE(0x1f94, 0, 0x42),\nSCE(0x1f9c, 1, 0x2),SCE(0x1f95, 0, 0x42),SCE(0x1f9d, 1, 0x2),SCE(0x1f96, 0, 0x42),\nSCE(0x1f9e, 1, 0x2),SCE(0x1f97, 0, 0x42),SCE(0x1f9f, 1, 0x2),SCE(0xa7a0, 0, 0x82),\nSCE(0xa7a1, 1, 0x42),SCE(0xa7a2, 0, 0x82),SCE(0xa7a3, 1, 0x42),SCE(0xa7a4, 0, 0x82),\nSCE(0xa7a5, 1, 0x42),SCE(0xa7a6, 0, 0x82),SCE(0xa7a7, 1, 0x42),SCE(0x1fa0, 0, 0x42),\nSCE(0x1fa8, 1, 0x2),SCE(0x1fa1, 0, 0x42),SCE(0x1fa9, 1, 0x2),SCE(0x1fa2, 0, 0x42),\nSCE(0x1faa, 1, 0x2),SCE(0x1fa3, 0, 0x42),SCE(0x1fab, 1, 0x2),SCE(0x1fa4, 0, 0x42),\nSCE(0x1fac, 1, 0x2),SCE(0x1fa5, 0, 0x42),SCE(0x1fad, 1, 0x2),SCE(0x1fa6, 0, 0x42),\nSCE(0x1fae, 1, 0x2),SCE(0x1fa7, 0, 0x42),SCE(0x1faf, 1, 0x2),SCE(0x1fb0, 0, 0x42),\nSCE(0x1fb8, 1, 0x82),SCE(0x1fb1, 0, 0x42),SCE(0x1fb9, 1, 0x82),SCE(0x1f70, 0, 0x42),\nSCE(0x1fba, 1, 0x82),SCE(0x1f71, 0, 0x42),SCE(0x1fbb, 1, 0x82),SCE(0x1fb3, 0, 0x42),\nSCE(0x1fbc, 1, 0x2),SCE(0x0345, 0, 0x44),SCE(0x0399, 1, 0x84),SCE(0x03b9, 2, 0x44),\nSCE(0x1fbe, 3, 0x44),SCE(0x1f72, 0, 0x42),SCE(0x1fc8, 1, 0x82),SCE(0x1f73, 0, 0x42),\nSCE(0x1fc9, 1, 0x82),SCE(0x1f74, 0, 0x42),SCE(0x1fca, 1, 0x82),SCE(0x1f75, 0, 0x42),\nSCE(0x1fcb, 1, 0x82),SCE(0x1fc3, 0, 0x42),SCE(0x1fcc, 1, 0x2),SCE(0x1fd0, 0, 0x42),\nSCE(0x1fd8, 1, 0x82),SCE(0x1fd1, 0, 0x42),SCE(0x1fd9, 1, 0x82),SCE(0x1f76, 0, 0x42),\nSCE(0x1fda, 1, 0x82),SCE(0x1f77, 0, 0x42),SCE(0x1fdb, 1, 0x82),SCE(0x10427, 0, 0x82),\nSCE(0x1044f, 1, 0x42),SCE(0x1fe0, 0, 0x42),SCE(0x1fe8, 1, 0x82),SCE(0x1fe1, 0, 0x42),\nSCE(0x1fe9, 1, 0x82),SCE(0x1f7a, 0, 0x42),SCE(0x1fea, 1, 0x82),SCE(0x1f7b, 0, 0x42),\nSCE(0x1feb, 1, 0x82),SCE(0x1fe5, 0, 0x42),SCE(0x1fec, 1, 0x82),SCE(0x10401, 0, 0x82),\nSCE(0x10429, 1, 0x42),SCE(0x1040c, 0, 0x82),SCE(0x10434, 1, 0x42),SCE(0x1f78, 0, 0x42),\nSCE(0x1ff8, 1, 0x82),SCE(0x1f79, 0, 0x42),SCE(0x1ff9, 1, 0x82),SCE(0x1f7c, 0, 0x42),\nSCE(0x1ffa, 1, 0x82),SCE(0x1f7d, 0, 0x42),SCE(0x1ffb, 1, 0x82),SCE(0x1ff3, 0, 0x42),\nSCE(0x1ffc, 1, 0x2),SCE(0x24c0, 0, 0x82),SCE(0x24da, 1, 0x42),];\nreturn t;\n}\n@property immutable(FullCaseEntry[]) fullCaseTable()\n{\nalias FCE = FullCaseEntry;\nstatic immutable FCE[] t = [\nFCE(\"Ⰰ\", 0, 2, 1),\nFCE(\"ⰰ\", 1, 2, 1),FCE(\"Ⓝ\", 0, 2, 1),FCE(\"ⓝ\", 1, 2, 1),FCE(\"Ⰱ\", 0, 2, 1),\nFCE(\"ⰱ\", 1, 2, 1),FCE(\"Ⱍ\", 0, 2, 1),FCE(\"ⱍ\", 1, 2, 1),FCE(\"Ⰲ\", 0, 2, 1),\nFCE(\"ⰲ\", 1, 2, 1),FCE(\"Ⰳ\", 0, 2, 1),FCE(\"ⰳ\", 1, 2, 1),FCE(\"Ⰴ\", 0, 2, 1),\nFCE(\"ⰴ\", 1, 2, 1),FCE(\"Ⰵ\", 0, 2, 1),FCE(\"ⰵ\", 1, 2, 1),FCE(\"Ⰶ\", 0, 2, 1),\nFCE(\"ⰶ\", 1, 2, 1),FCE(\"𐐀\", 0, 2, 1),FCE(\"𐐨\", 1, 2, 1),FCE(\"Ⳃ\", 0, 2, 1),\nFCE(\"ⳃ\", 1, 2, 1),FCE(\"Ⰷ\", 0, 2, 1),FCE(\"ⰷ\", 1, 2, 1),FCE(\"Ⰸ\", 0, 2, 1),\nFCE(\"ⰸ\", 1, 2, 1),FCE(\"Ⰹ\", 0, 2, 1),FCE(\"ⰹ\", 1, 2, 1),FCE(\"Ⰺ\", 0, 2, 1),\nFCE(\"ⰺ\", 1, 2, 1),FCE(\"Ꚍ\", 0, 2, 1),FCE(\"ꚍ\", 1, 2, 1),FCE(\"A\", 0, 2, 1),\nFCE(\"a\", 1, 2, 1),FCE(\"B\", 0, 2, 1),FCE(\"b\", 1, 2, 1),FCE(\"C\", 0, 2, 1),\nFCE(\"c\", 1, 2, 1),FCE(\"D\", 0, 2, 1),FCE(\"d\", 1, 2, 1),FCE(\"E\", 0, 2, 1),\nFCE(\"e\", 1, 2, 1),FCE(\"F\", 0, 2, 1),FCE(\"f\", 1, 2, 1),FCE(\"G\", 0, 2, 1),\nFCE(\"g\", 1, 2, 1),FCE(\"H\", 0, 2, 1),FCE(\"h\", 1, 2, 1),FCE(\"I\", 0, 2, 1),\nFCE(\"i\", 1, 2, 1),FCE(\"J\", 0, 2, 1),FCE(\"j\", 1, 2, 1),FCE(\"K\", 0, 3, 1),\nFCE(\"k\", 1, 3, 1),FCE(\"K\", 2, 3, 1),FCE(\"L\", 0, 2, 1),FCE(\"l\", 1, 2, 1),\nFCE(\"M\", 0, 2, 1),FCE(\"m\", 1, 2, 1),FCE(\"N\", 0, 2, 1),FCE(\"n\", 1, 2, 1),\nFCE(\"O\", 0, 2, 1),FCE(\"o\", 1, 2, 1),FCE(\"P\", 0, 2, 1),FCE(\"p\", 1, 2, 1),\nFCE(\"Q\", 0, 2, 1),FCE(\"q\", 1, 2, 1),FCE(\"R\", 0, 2, 1),FCE(\"r\", 1, 2, 1),\nFCE(\"S\", 0, 3, 1),FCE(\"s\", 1, 3, 1),FCE(\"ſ\", 2, 3, 1),FCE(\"T\", 0, 2, 1),\nFCE(\"t\", 1, 2, 1),FCE(\"U\", 0, 2, 1),FCE(\"u\", 1, 2, 1),FCE(\"V\", 0, 2, 1),\nFCE(\"v\", 1, 2, 1),FCE(\"W\", 0, 2, 1),FCE(\"w\", 1, 2, 1),FCE(\"X\", 0, 2, 1),\nFCE(\"x\", 1, 2, 1),FCE(\"Y\", 0, 2, 1),FCE(\"y\", 1, 2, 1),FCE(\"Z\", 0, 2, 1),\nFCE(\"z\", 1, 2, 1),FCE(\"Ⰿ\", 0, 2, 1),FCE(\"ⰿ\", 1, 2, 1),FCE(\"Ⱀ\", 0, 2, 1),\nFCE(\"ⱀ\", 1, 2, 1),FCE(\"𐐂\", 0, 2, 1),FCE(\"𐐪\", 1, 2, 1),FCE(\"Ⳅ\", 0, 2, 1),\nFCE(\"ⳅ\", 1, 2, 1),FCE(\"Ⅶ\", 0, 2, 1),FCE(\"ⅶ\", 1, 2, 1),FCE(\"Ⱁ\", 0, 2, 1),\nFCE(\"ⱁ\", 1, 2, 1),FCE(\"Ⱂ\", 0, 2, 1),FCE(\"ⱂ\", 1, 2, 1),FCE(\"Ⅸ\", 0, 2, 1),\nFCE(\"ⅸ\", 1, 2, 1),FCE(\"Ⱃ\", 0, 2, 1),FCE(\"ⱃ\", 1, 2, 1),FCE(\"Ꚃ\", 0, 2, 1),\nFCE(\"ꚃ\", 1, 2, 1),FCE(\"Ⱄ\", 0, 2, 1),FCE(\"ⱄ\", 1, 2, 1),FCE(\"Ⅺ\", 0, 2, 1),\nFCE(\"ⅺ\", 1, 2, 1),FCE(\"Ⓡ\", 0, 2, 1),FCE(\"ⓡ\", 1, 2, 1),FCE(\"Ⱅ\", 0, 2, 1),\nFCE(\"ⱅ\", 1, 2, 1),FCE(\"𐐃\", 0, 2, 1),FCE(\"𐐫\", 1, 2, 1),FCE(\"Ⱆ\", 0, 2, 1),\nFCE(\"ⱆ\", 1, 2, 1),FCE(\"Ⅼ\", 0, 2, 1),FCE(\"ⅼ\", 1, 2, 1),FCE(\"Ⱇ\", 0, 2, 1),\nFCE(\"ⱇ\", 1, 2, 1),FCE(\"Ｘ\", 0, 2, 1),FCE(\"ｘ\", 1, 2, 1),FCE(\"Ⱈ\", 0, 2, 1),\nFCE(\"ⱈ\", 1, 2, 1),FCE(\"Ⅾ\", 0, 2, 1),FCE(\"ⅾ\", 1, 2, 1),FCE(\"Ⱉ\", 0, 2, 1),\nFCE(\"ⱉ\", 1, 2, 1),FCE(\"Ⱊ\", 0, 2, 1),FCE(\"ⱊ\", 1, 2, 1),FCE(\"Ⱎ\", 0, 2, 1),\nFCE(\"ⱎ\", 1, 2, 1),FCE(\"Ⴀ\", 0, 2, 1),FCE(\"ⴀ\", 1, 2, 1),FCE(\"Ⴁ\", 0, 2, 1),\nFCE(\"ⴁ\", 1, 2, 1),FCE(\"Ⴂ\", 0, 2, 1),FCE(\"ⴂ\", 1, 2, 1),FCE(\"Ⴃ\", 0, 2, 1),\nFCE(\"ⴃ\", 1, 2, 1),FCE(\"Ⴄ\", 0, 2, 1),FCE(\"ⴄ\", 1, 2, 1),FCE(\"Ⴅ\", 0, 2, 1),\nFCE(\"ⴅ\", 1, 2, 1),FCE(\"Ⴆ\", 0, 2, 1),FCE(\"ⴆ\", 1, 2, 1),FCE(\"Ⴇ\", 0, 2, 1),\nFCE(\"ⴇ\", 1, 2, 1),FCE(\"Ⴈ\", 0, 2, 1),FCE(\"ⴈ\", 1, 2, 1),FCE(\"Ⴉ\", 0, 2, 1),\nFCE(\"ⴉ\", 1, 2, 1),FCE(\"Ⴊ\", 0, 2, 1),FCE(\"ⴊ\", 1, 2, 1),FCE(\"Ⴋ\", 0, 2, 1),\nFCE(\"ⴋ\", 1, 2, 1),FCE(\"Ⴌ\", 0, 2, 1),FCE(\"ⴌ\", 1, 2, 1),FCE(\"Ⴍ\", 0, 2, 1),\nFCE(\"ⴍ\", 1, 2, 1),FCE(\"Ⴎ\", 0, 2, 1),FCE(\"ⴎ\", 1, 2, 1),FCE(\"Ⴏ\", 0, 2, 1),\nFCE(\"ⴏ\", 1, 2, 1),FCE(\"Ⴐ\", 0, 2, 1),FCE(\"ⴐ\", 1, 2, 1),FCE(\"Ⴑ\", 0, 2, 1),\nFCE(\"ⴑ\", 1, 2, 1),FCE(\"Ⴒ\", 0, 2, 1),FCE(\"ⴒ\", 1, 2, 1),FCE(\"Ⴓ\", 0, 2, 1),\nFCE(\"ⴓ\", 1, 2, 1),FCE(\"Ⴔ\", 0, 2, 1),FCE(\"ⴔ\", 1, 2, 1),FCE(\"Ⴕ\", 0, 2, 1),\nFCE(\"ⴕ\", 1, 2, 1),FCE(\"Ⴖ\", 0, 2, 1),FCE(\"ⴖ\", 1, 2, 1),FCE(\"Ⴗ\", 0, 2, 1),\nFCE(\"ⴗ\", 1, 2, 1),FCE(\"Ⴘ\", 0, 2, 1),FCE(\"ⴘ\", 1, 2, 1),FCE(\"Ⴙ\", 0, 2, 1),\nFCE(\"ⴙ\", 1, 2, 1),FCE(\"Ⴚ\", 0, 2, 1),FCE(\"ⴚ\", 1, 2, 1),FCE(\"Ⴛ\", 0, 2, 1),\nFCE(\"ⴛ\", 1, 2, 1),FCE(\"Ⴜ\", 0, 2, 1),FCE(\"ⴜ\", 1, 2, 1),FCE(\"Ⴝ\", 0, 2, 1),\nFCE(\"ⴝ\", 1, 2, 1),FCE(\"Ⴞ\", 0, 2, 1),FCE(\"ⴞ\", 1, 2, 1),FCE(\"Ⴟ\", 0, 2, 1),\nFCE(\"ⴟ\", 1, 2, 1),FCE(\"À\", 0, 2, 1),FCE(\"à\", 1, 2, 1),FCE(\"Á\", 0, 2, 1),\nFCE(\"á\", 1, 2, 1),FCE(\"Ⴢ\", 0, 2, 1),FCE(\"ⴢ\", 1, 2, 1),FCE(\"Ã\", 0, 2, 1),\nFCE(\"ã\", 1, 2, 1),FCE(\"Ⴤ\", 0, 2, 1),FCE(\"ⴤ\", 1, 2, 1),FCE(\"Å\", 0, 3, 1),\nFCE(\"å\", 1, 3, 1),FCE(\"Å\", 2, 3, 1),FCE(\"Æ\", 0, 2, 1),FCE(\"æ\", 1, 2, 1),\nFCE(\"Ç\", 0, 2, 1),FCE(\"ç\", 1, 2, 1),FCE(\"È\", 0, 2, 1),FCE(\"è\", 1, 2, 1),\nFCE(\"É\", 0, 2, 1),FCE(\"é\", 1, 2, 1),FCE(\"Ê\", 0, 2, 1),FCE(\"ê\", 1, 2, 1),\nFCE(\"Ë\", 0, 2, 1),FCE(\"ë\", 1, 2, 1),FCE(\"Ì\", 0, 2, 1),FCE(\"ì\", 1, 2, 1),\nFCE(\"Í\", 0, 2, 1),FCE(\"í\", 1, 2, 1),FCE(\"Î\", 0, 2, 1),FCE(\"î\", 1, 2, 1),\nFCE(\"Ï\", 0, 2, 1),FCE(\"ï\", 1, 2, 1),FCE(\"Ð\", 0, 2, 1),FCE(\"ð\", 1, 2, 1),\nFCE(\"Ñ\", 0, 2, 1),FCE(\"ñ\", 1, 2, 1),FCE(\"Ò\", 0, 2, 1),FCE(\"ò\", 1, 2, 1),\nFCE(\"Ó\", 0, 2, 1),FCE(\"ó\", 1, 2, 1),FCE(\"Ô\", 0, 2, 1),FCE(\"ô\", 1, 2, 1),\nFCE(\"Õ\", 0, 2, 1),FCE(\"õ\", 1, 2, 1),FCE(\"Ö\", 0, 2, 1),FCE(\"ö\", 1, 2, 1),\nFCE(\"Ø\", 0, 2, 1),FCE(\"ø\", 1, 2, 1),FCE(\"Ù\", 0, 2, 1),FCE(\"ù\", 1, 2, 1),\nFCE(\"Ú\", 0, 2, 1),FCE(\"ú\", 1, 2, 1),FCE(\"Û\", 0, 2, 1),FCE(\"û\", 1, 2, 1),\nFCE(\"Ü\", 0, 2, 1),FCE(\"ü\", 1, 2, 1),FCE(\"Ý\", 0, 2, 1),FCE(\"ý\", 1, 2, 1),\nFCE(\"Þ\", 0, 2, 1),FCE(\"þ\", 1, 2, 1),FCE(\"ß\", 0, 3, 1),FCE(\"ẞ\", 1, 3, 1),\nFCE(\"ss\", 2, 3, 2),FCE(\"Ⱖ\", 0, 2, 1),FCE(\"ⱖ\", 1, 2, 1),FCE(\"Ⱗ\", 0, 2, 1),\nFCE(\"ⱗ\", 1, 2, 1),FCE(\"Ⱘ\", 0, 2, 1),FCE(\"ⱘ\", 1, 2, 1),FCE(\"𐐆\", 0, 2, 1),\nFCE(\"𐐮\", 1, 2, 1),FCE(\"𐐏\", 0, 2, 1),FCE(\"𐐷\", 1, 2, 1),FCE(\"Ⓥ\", 0, 2, 1),\nFCE(\"ⓥ\", 1, 2, 1),FCE(\"Ⱙ\", 0, 2, 1),FCE(\"ⱙ\", 1, 2, 1),FCE(\"𐐇\", 0, 2, 1),\nFCE(\"𐐯\", 1, 2, 1),FCE(\"Ⱚ\", 0, 2, 1),FCE(\"ⱚ\", 1, 2, 1),FCE(\"Ā\", 0, 2, 1),\nFCE(\"ā\", 1, 2, 1),FCE(\"Ă\", 0, 2, 1),FCE(\"ă\", 1, 2, 1),FCE(\"Ⱛ\", 0, 2, 1),\nFCE(\"ⱛ\", 1, 2, 1),FCE(\"Ą\", 0, 2, 1),FCE(\"ą\", 1, 2, 1),FCE(\"Ć\", 0, 2, 1),\nFCE(\"ć\", 1, 2, 1),FCE(\"Ĉ\", 0, 2, 1),FCE(\"ĉ\", 1, 2, 1),FCE(\"Ⱜ\", 0, 2, 1),\nFCE(\"ⱜ\", 1, 2, 1),FCE(\"Ċ\", 0, 2, 1),FCE(\"ċ\", 1, 2, 1),FCE(\"Č\", 0, 2, 1),\nFCE(\"č\", 1, 2, 1),FCE(\"Ď\", 0, 2, 1),FCE(\"ď\", 1, 2, 1),FCE(\"Ⱝ\", 0, 2, 1),\nFCE(\"ⱝ\", 1, 2, 1),FCE(\"Đ\", 0, 2, 1),FCE(\"đ\", 1, 2, 1),FCE(\"Ē\", 0, 2, 1),\nFCE(\"ē\", 1, 2, 1),FCE(\"Ĕ\", 0, 2, 1),FCE(\"ĕ\", 1, 2, 1),FCE(\"Ⱞ\", 0, 2, 1),\nFCE(\"ⱞ\", 1, 2, 1),FCE(\"Ė\", 0, 2, 1),FCE(\"ė\", 1, 2, 1),FCE(\"Ę\", 0, 2, 1),\nFCE(\"ę\", 1, 2, 1),FCE(\"Ě\", 0, 2, 1),FCE(\"ě\", 1, 2, 1),FCE(\"Ĝ\", 0, 2, 1),\nFCE(\"ĝ\", 1, 2, 1),FCE(\"Ğ\", 0, 2, 1),FCE(\"ğ\", 1, 2, 1),FCE(\"Ġ\", 0, 2, 1),\nFCE(\"ġ\", 1, 2, 1),FCE(\"Ģ\", 0, 2, 1),FCE(\"ģ\", 1, 2, 1),FCE(\"Ｋ\", 0, 2, 1),\nFCE(\"ｋ\", 1, 2, 1),FCE(\"Ĥ\", 0, 2, 1),FCE(\"ĥ\", 1, 2, 1),FCE(\"Ħ\", 0, 2, 1),\nFCE(\"ħ\", 1, 2, 1),FCE(\"Ĩ\", 0, 2, 1),FCE(\"ĩ\", 1, 2, 1),FCE(\"Ī\", 0, 2, 1),\nFCE(\"ī\", 1, 2, 1),FCE(\"Å\", 0, 3, 1),FCE(\"å\", 1, 3, 1),FCE(\"Å\", 2, 3, 1),\nFCE(\"Ĭ\", 0, 2, 1),FCE(\"ĭ\", 1, 2, 1),FCE(\"Į\", 0, 2, 1),FCE(\"į\", 1, 2, 1),\nFCE(\"İ\", 0, 2, 1),FCE(\"i̇\", 1, 2, 2),FCE(\"Ĳ\", 0, 2, 1),FCE(\"ĳ\", 1, 2, 1),\nFCE(\"Ĵ\", 0, 2, 1),FCE(\"ĵ\", 1, 2, 1),FCE(\"Ķ\", 0, 2, 1),FCE(\"ķ\", 1, 2, 1),\nFCE(\"Ĺ\", 0, 2, 1),FCE(\"ĺ\", 1, 2, 1),FCE(\"Ļ\", 0, 2, 1),FCE(\"ļ\", 1, 2, 1),\nFCE(\"Ⳟ\", 0, 2, 1),FCE(\"ⳟ\", 1, 2, 1),FCE(\"Ľ\", 0, 2, 1),FCE(\"ľ\", 1, 2, 1),\nFCE(\"Ŀ\", 0, 2, 1),FCE(\"ŀ\", 1, 2, 1),FCE(\"Ł\", 0, 2, 1),FCE(\"ł\", 1, 2, 1),\nFCE(\"Ń\", 0, 2, 1),FCE(\"ń\", 1, 2, 1),FCE(\"Ņ\", 0, 2, 1),FCE(\"ņ\", 1, 2, 1),\nFCE(\"Ň\", 0, 2, 1),FCE(\"ň\", 1, 2, 1),FCE(\"ŉ\", 0, 2, 1),FCE(\"ʼn\", 1, 2, 2),\nFCE(\"Ŋ\", 0, 2, 1),FCE(\"ŋ\", 1, 2, 1),FCE(\"Ō\", 0, 2, 1),FCE(\"ō\", 1, 2, 1),\nFCE(\"Ŏ\", 0, 2, 1),FCE(\"ŏ\", 1, 2, 1),FCE(\"Ő\", 0, 2, 1),FCE(\"ő\", 1, 2, 1),\nFCE(\"Œ\", 0, 2, 1),FCE(\"œ\", 1, 2, 1),FCE(\"Ŕ\", 0, 2, 1),FCE(\"ŕ\", 1, 2, 1),\nFCE(\"Ŗ\", 0, 2, 1),FCE(\"ŗ\", 1, 2, 1),FCE(\"Ř\", 0, 2, 1),FCE(\"ř\", 1, 2, 1),\nFCE(\"Ś\", 0, 2, 1),FCE(\"ś\", 1, 2, 1),FCE(\"Ŝ\", 0, 2, 1),FCE(\"ŝ\", 1, 2, 1),\nFCE(\"Ş\", 0, 2, 1),FCE(\"ş\", 1, 2, 1),FCE(\"Š\", 0, 2, 1),FCE(\"š\", 1, 2, 1),\nFCE(\"Ⅱ\", 0, 2, 1),FCE(\"ⅱ\", 1, 2, 1),FCE(\"Ţ\", 0, 2, 1),FCE(\"ţ\", 1, 2, 1),\nFCE(\"Ⅳ\", 0, 2, 1),FCE(\"ⅳ\", 1, 2, 1),FCE(\"Ť\", 0, 2, 1),FCE(\"ť\", 1, 2, 1),\nFCE(\"Ⅵ\", 0, 2, 1),FCE(\"ⅵ\", 1, 2, 1),FCE(\"Ŧ\", 0, 2, 1),FCE(\"ŧ\", 1, 2, 1),\nFCE(\"Ⅷ\", 0, 2, 1),FCE(\"ⅷ\", 1, 2, 1),FCE(\"Ũ\", 0, 2, 1),FCE(\"ũ\", 1, 2, 1),\nFCE(\"Ⅹ\", 0, 2, 1),FCE(\"ⅹ\", 1, 2, 1),FCE(\"Ū\", 0, 2, 1),FCE(\"ū\", 1, 2, 1),\nFCE(\"Ⅻ\", 0, 2, 1),FCE(\"ⅻ\", 1, 2, 1),FCE(\"Ŭ\", 0, 2, 1),FCE(\"ŭ\", 1, 2, 1),\nFCE(\"Ⅽ\", 0, 2, 1),FCE(\"ⅽ\", 1, 2, 1),FCE(\"Ů\", 0, 2, 1),FCE(\"ů\", 1, 2, 1),\nFCE(\"Ⅿ\", 0, 2, 1),FCE(\"ⅿ\", 1, 2, 1),FCE(\"Ű\", 0, 2, 1),FCE(\"ű\", 1, 2, 1),\nFCE(\"Ⳍ\", 0, 2, 1),FCE(\"ⳍ\", 1, 2, 1),FCE(\"Ų\", 0, 2, 1),FCE(\"ų\", 1, 2, 1),\nFCE(\"Ŵ\", 0, 2, 1),FCE(\"ŵ\", 1, 2, 1),FCE(\"Ŷ\", 0, 2, 1),FCE(\"ŷ\", 1, 2, 1),\nFCE(\"ÿ\", 0, 2, 1),FCE(\"Ÿ\", 1, 2, 1),FCE(\"Ź\", 0, 2, 1),FCE(\"ź\", 1, 2, 1),\nFCE(\"Ż\", 0, 2, 1),FCE(\"ż\", 1, 2, 1),FCE(\"Ž\", 0, 2, 1),FCE(\"ž\", 1, 2, 1),\nFCE(\"S\", 0, 3, 1),FCE(\"s\", 1, 3, 1),FCE(\"ſ\", 2, 3, 1),FCE(\"Ɓ\", 0, 2, 1),\nFCE(\"ɓ\", 1, 2, 1),FCE(\"Ƃ\", 0, 2, 1),FCE(\"ƃ\", 1, 2, 1),FCE(\"Ↄ\", 0, 2, 1),\nFCE(\"ↄ\", 1, 2, 1),FCE(\"Ƅ\", 0, 2, 1),FCE(\"ƅ\", 1, 2, 1),FCE(\"Ɔ\", 0, 2, 1),\nFCE(\"ɔ\", 1, 2, 1),FCE(\"Ƈ\", 0, 2, 1),FCE(\"ƈ\", 1, 2, 1),FCE(\"Ɖ\", 0, 2, 1),\nFCE(\"ɖ\", 1, 2, 1),FCE(\"Ɗ\", 0, 2, 1),FCE(\"ɗ\", 1, 2, 1),FCE(\"Ƌ\", 0, 2, 1),\nFCE(\"ƌ\", 1, 2, 1),FCE(\"Ǝ\", 0, 2, 1),FCE(\"ǝ\", 1, 2, 1),FCE(\"Ə\", 0, 2, 1),\nFCE(\"ə\", 1, 2, 1),FCE(\"Ɛ\", 0, 2, 1),FCE(\"ɛ\", 1, 2, 1),FCE(\"Ƒ\", 0, 2, 1),\nFCE(\"ƒ\", 1, 2, 1),FCE(\"Ɠ\", 0, 2, 1),FCE(\"ɠ\", 1, 2, 1),FCE(\"Ɣ\", 0, 2, 1),\nFCE(\"ɣ\", 1, 2, 1),FCE(\"Ɩ\", 0, 2, 1),FCE(\"ɩ\", 1, 2, 1),FCE(\"Ɨ\", 0, 2, 1),\nFCE(\"ɨ\", 1, 2, 1),FCE(\"Ƙ\", 0, 2, 1),FCE(\"ƙ\", 1, 2, 1),FCE(\"Ɯ\", 0, 2, 1),\nFCE(\"ɯ\", 1, 2, 1),FCE(\"Ɲ\", 0, 2, 1),FCE(\"ɲ\", 1, 2, 1),FCE(\"Ꙋ\", 0, 2, 1),\nFCE(\"ꙋ\", 1, 2, 1),FCE(\"Ɵ\", 0, 2, 1),FCE(\"ɵ\", 1, 2, 1),FCE(\"Ơ\", 0, 2, 1),\nFCE(\"ơ\", 1, 2, 1),FCE(\"Ƣ\", 0, 2, 1),FCE(\"ƣ\", 1, 2, 1),FCE(\"Ƥ\", 0, 2, 1),\nFCE(\"ƥ\", 1, 2, 1),FCE(\"Ʀ\", 0, 2, 1),FCE(\"ʀ\", 1, 2, 1),FCE(\"Ƨ\", 0, 2, 1),\nFCE(\"ƨ\", 1, 2, 1),FCE(\"Ʃ\", 0, 2, 1),FCE(\"ʃ\", 1, 2, 1),FCE(\"Ƭ\", 0, 2, 1),\nFCE(\"ƭ\", 1, 2, 1),FCE(\"Ʈ\", 0, 2, 1),FCE(\"ʈ\", 1, 2, 1),FCE(\"Ư\", 0, 2, 1),\nFCE(\"ư\", 1, 2, 1),FCE(\"Ʊ\", 0, 2, 1),FCE(\"ʊ\", 1, 2, 1),FCE(\"Ʋ\", 0, 2, 1),\nFCE(\"ʋ\", 1, 2, 1),FCE(\"Ƴ\", 0, 2, 1),FCE(\"ƴ\", 1, 2, 1),FCE(\"Ƶ\", 0, 2, 1),\nFCE(\"ƶ\", 1, 2, 1),FCE(\"Ʒ\", 0, 2, 1),FCE(\"ʒ\", 1, 2, 1),FCE(\"Ƹ\", 0, 2, 1),\nFCE(\"ƹ\", 1, 2, 1),FCE(\"Ƽ\", 0, 2, 1),FCE(\"ƽ\", 1, 2, 1),FCE(\"Ǆ\", 0, 3, 1),\nFCE(\"ǅ\", 1, 3, 1),FCE(\"ǆ\", 2, 3, 1),FCE(\"Ǆ\", 0, 3, 1),FCE(\"ǅ\", 1, 3, 1),\nFCE(\"ǆ\", 2, 3, 1),FCE(\"Ǉ\", 0, 3, 1),FCE(\"ǈ\", 1, 3, 1),FCE(\"ǉ\", 2, 3, 1),\nFCE(\"Ǉ\", 0, 3, 1),FCE(\"ǈ\", 1, 3, 1),FCE(\"ǉ\", 2, 3, 1),FCE(\"Ǌ\", 0, 3, 1),\nFCE(\"ǋ\", 1, 3, 1),FCE(\"ǌ\", 2, 3, 1),FCE(\"Ǌ\", 0, 3, 1),FCE(\"ǋ\", 1, 3, 1),\nFCE(\"ǌ\", 2, 3, 1),FCE(\"Ǎ\", 0, 2, 1),FCE(\"ǎ\", 1, 2, 1),FCE(\"Ǐ\", 0, 2, 1),\nFCE(\"ǐ\", 1, 2, 1),FCE(\"Ǒ\", 0, 2, 1),FCE(\"ǒ\", 1, 2, 1),FCE(\"Ǔ\", 0, 2, 1),\nFCE(\"ǔ\", 1, 2, 1),FCE(\"Ǖ\", 0, 2, 1),FCE(\"ǖ\", 1, 2, 1),FCE(\"Ǘ\", 0, 2, 1),\nFCE(\"ǘ\", 1, 2, 1),FCE(\"Ǚ\", 0, 2, 1),FCE(\"ǚ\", 1, 2, 1),FCE(\"Ǜ\", 0, 2, 1),\nFCE(\"ǜ\", 1, 2, 1),FCE(\"Ǟ\", 0, 2, 1),FCE(\"ǟ\", 1, 2, 1),FCE(\"Ｖ\", 0, 2, 1),\nFCE(\"ｖ\", 1, 2, 1),FCE(\"Ǡ\", 0, 2, 1),FCE(\"ǡ\", 1, 2, 1),FCE(\"Ǣ\", 0, 2, 1),\nFCE(\"ǣ\", 1, 2, 1),FCE(\"Ǥ\", 0, 2, 1),FCE(\"ǥ\", 1, 2, 1),FCE(\"Ǧ\", 0, 2, 1),\nFCE(\"ǧ\", 1, 2, 1),FCE(\"Ǩ\", 0, 2, 1),FCE(\"ǩ\", 1, 2, 1),FCE(\"Ǫ\", 0, 2, 1),\nFCE(\"ǫ\", 1, 2, 1),FCE(\"Ǭ\", 0, 2, 1),FCE(\"ǭ\", 1, 2, 1),FCE(\"Ǯ\", 0, 2, 1),\nFCE(\"ǯ\", 1, 2, 1),FCE(\"ǰ\", 0, 2, 1),FCE(\"ǰ\", 1, 2, 2),FCE(\"Ǳ\", 0, 3, 1),\nFCE(\"ǲ\", 1, 3, 1),FCE(\"ǳ\", 2, 3, 1),FCE(\"Ǳ\", 0, 3, 1),FCE(\"ǲ\", 1, 3, 1),\nFCE(\"ǳ\", 2, 3, 1),FCE(\"Ǵ\", 0, 2, 1),FCE(\"ǵ\", 1, 2, 1),FCE(\"ƕ\", 0, 2, 1),\nFCE(\"Ƕ\", 1, 2, 1),FCE(\"ƿ\", 0, 2, 1),FCE(\"Ƿ\", 1, 2, 1),FCE(\"Ǹ\", 0, 2, 1),\nFCE(\"ǹ\", 1, 2, 1),FCE(\"𐐝\", 0, 2, 1),FCE(\"𐑅\", 1, 2, 1),FCE(\"Ǻ\", 0, 2, 1),\nFCE(\"ǻ\", 1, 2, 1),FCE(\"Ǽ\", 0, 2, 1),FCE(\"ǽ\", 1, 2, 1),FCE(\"Ǿ\", 0, 2, 1),\nFCE(\"ǿ\", 1, 2, 1),FCE(\"Ȁ\", 0, 2, 1),FCE(\"ȁ\", 1, 2, 1),FCE(\"Ȃ\", 0, 2, 1),\nFCE(\"ȃ\", 1, 2, 1),FCE(\"Ȅ\", 0, 2, 1),FCE(\"ȅ\", 1, 2, 1),FCE(\"Ȇ\", 0, 2, 1),\nFCE(\"ȇ\", 1, 2, 1),FCE(\"ﬁ\", 0, 2, 1),FCE(\"fi\", 1, 2, 2),FCE(\"Ȉ\", 0, 2, 1),\nFCE(\"ȉ\", 1, 2, 1),FCE(\"Ȋ\", 0, 2, 1),FCE(\"ȋ\", 1, 2, 1),FCE(\"Ȍ\", 0, 2, 1),\nFCE(\"ȍ\", 1, 2, 1),FCE(\"Ȏ\", 0, 2, 1),FCE(\"ȏ\", 1, 2, 1),FCE(\"Ȑ\", 0, 2, 1),\nFCE(\"ȑ\", 1, 2, 1),FCE(\"Ȓ\", 0, 2, 1),FCE(\"ȓ\", 1, 2, 1),FCE(\"Ȕ\", 0, 2, 1),\nFCE(\"ȕ\", 1, 2, 1),FCE(\"Ȗ\", 0, 2, 1),FCE(\"ȗ\", 1, 2, 1),FCE(\"Ș\", 0, 2, 1),\nFCE(\"ș\", 1, 2, 1),FCE(\"Ț\", 0, 2, 1),FCE(\"ț\", 1, 2, 1),FCE(\"Ȝ\", 0, 2, 1),\nFCE(\"ȝ\", 1, 2, 1),FCE(\"Ȟ\", 0, 2, 1),FCE(\"ȟ\", 1, 2, 1),FCE(\"ƞ\", 0, 2, 1),\nFCE(\"Ƞ\", 1, 2, 1),FCE(\"Ȣ\", 0, 2, 1),FCE(\"ȣ\", 1, 2, 1),FCE(\"Ȥ\", 0, 2, 1),\nFCE(\"ȥ\", 1, 2, 1),FCE(\"Ȧ\", 0, 2, 1),FCE(\"ȧ\", 1, 2, 1),FCE(\"Ȩ\", 0, 2, 1),\nFCE(\"ȩ\", 1, 2, 1),FCE(\"Ꝗ\", 0, 2, 1),FCE(\"ꝗ\", 1, 2, 1),FCE(\"Ȫ\", 0, 2, 1),\nFCE(\"ȫ\", 1, 2, 1),FCE(\"Ȭ\", 0, 2, 1),FCE(\"ȭ\", 1, 2, 1),FCE(\"Ȯ\", 0, 2, 1),\nFCE(\"ȯ\", 1, 2, 1),FCE(\"Ȱ\", 0, 2, 1),FCE(\"ȱ\", 1, 2, 1),FCE(\"Ȳ\", 0, 2, 1),\nFCE(\"ȳ\", 1, 2, 1),FCE(\"Ꚅ\", 0, 2, 1),FCE(\"ꚅ\", 1, 2, 1),FCE(\"Ⱥ\", 0, 2, 1),\nFCE(\"ⱥ\", 1, 2, 1),FCE(\"Ȼ\", 0, 2, 1),FCE(\"ȼ\", 1, 2, 1),FCE(\"ƚ\", 0, 2, 1),\nFCE(\"Ƚ\", 1, 2, 1),FCE(\"Ⱦ\", 0, 2, 1),FCE(\"ⱦ\", 1, 2, 1),FCE(\"Ɂ\", 0, 2, 1),\nFCE(\"ɂ\", 1, 2, 1),FCE(\"𐐒\", 0, 2, 1),FCE(\"𐐺\", 1, 2, 1),FCE(\"ƀ\", 0, 2, 1),\nFCE(\"Ƀ\", 1, 2, 1),FCE(\"Ʉ\", 0, 2, 1),FCE(\"ʉ\", 1, 2, 1),FCE(\"Ʌ\", 0, 2, 1),\nFCE(\"ʌ\", 1, 2, 1),FCE(\"Ɇ\", 0, 2, 1),FCE(\"ɇ\", 1, 2, 1),FCE(\"Ɉ\", 0, 2, 1),\nFCE(\"ɉ\", 1, 2, 1),FCE(\"Ɋ\", 0, 2, 1),FCE(\"ɋ\", 1, 2, 1),FCE(\"Ɍ\", 0, 2, 1),\nFCE(\"ɍ\", 1, 2, 1),FCE(\"Ⱋ\", 0, 2, 1),FCE(\"ⱋ\", 1, 2, 1),FCE(\"Ɏ\", 0, 2, 1),\nFCE(\"ɏ\", 1, 2, 1),FCE(\"𐐊\", 0, 2, 1),FCE(\"𐐲\", 1, 2, 1),FCE(\"Ⅰ\", 0, 2, 1),\nFCE(\"ⅰ\", 1, 2, 1),FCE(\"Ꚓ\", 0, 2, 1),FCE(\"ꚓ\", 1, 2, 1),FCE(\"ɽ\", 0, 2, 1),\nFCE(\"Ɽ\", 1, 2, 1),FCE(\"𐐐\", 0, 2, 1),FCE(\"𐐸\", 1, 2, 1),FCE(\"Ⱑ\", 0, 2, 1),\nFCE(\"ⱑ\", 1, 2, 1),FCE(\"Ⱪ\", 0, 2, 1),FCE(\"ⱪ\", 1, 2, 1),FCE(\"𐐉\", 0, 2, 1),\nFCE(\"𐐱\", 1, 2, 1),FCE(\"𐐔\", 0, 2, 1),FCE(\"𐐼\", 1, 2, 1),FCE(\"ﬕ\", 0, 2, 1),\nFCE(\"մի\", 1, 2, 2),FCE(\"Ⅲ\", 0, 2, 1),FCE(\"ⅲ\", 1, 2, 1),FCE(\"𐐞\", 0, 2, 1),\nFCE(\"𐑆\", 1, 2, 1),FCE(\"ɱ\", 0, 2, 1),FCE(\"Ɱ\", 1, 2, 1),FCE(\"𐐕\", 0, 2, 1),\nFCE(\"𐐽\", 1, 2, 1),FCE(\"ɒ\", 0, 2, 1),FCE(\"Ɒ\", 1, 2, 1),FCE(\"Ⱳ\", 0, 2, 1),\nFCE(\"ⱳ\", 1, 2, 1),FCE(\"Ⰻ\", 0, 2, 1),FCE(\"ⰻ\", 1, 2, 1),FCE(\"𐐖\", 0, 2, 1),\nFCE(\"𐐾\", 1, 2, 1),FCE(\"Ꚗ\", 0, 2, 1),FCE(\"ꚗ\", 1, 2, 1),FCE(\"Ⱶ\", 0, 2, 1),\nFCE(\"ⱶ\", 1, 2, 1),FCE(\"Ⅴ\", 0, 2, 1),FCE(\"ⅴ\", 1, 2, 1),FCE(\"Ꙁ\", 0, 2, 1),\nFCE(\"ꙁ\", 1, 2, 1),FCE(\"Ｂ\", 0, 2, 1),FCE(\"ｂ\", 1, 2, 1),FCE(\"Ⰼ\", 0, 2, 1),\nFCE(\"ⰼ\", 1, 2, 1),FCE(\"𐐗\", 0, 2, 1),FCE(\"𐐿\", 1, 2, 1),FCE(\"Ｄ\", 0, 2, 1),\nFCE(\"ｄ\", 1, 2, 1),FCE(\"Ｅ\", 0, 2, 1),FCE(\"ｅ\", 1, 2, 1),FCE(\"Ｆ\", 0, 2, 1),\nFCE(\"ｆ\", 1, 2, 1),FCE(\"Ⰽ\", 0, 2, 1),FCE(\"ⰽ\", 1, 2, 1),FCE(\"Ⓛ\", 0, 2, 1),\nFCE(\"ⓛ\", 1, 2, 1),FCE(\"Ꜩ\", 0, 2, 1),FCE(\"ꜩ\", 1, 2, 1),FCE(\"ȿ\", 0, 2, 1),\nFCE(\"Ȿ\", 1, 2, 1),FCE(\"𐐑\", 0, 2, 1),FCE(\"𐐹\", 1, 2, 1),FCE(\"Ｉ\", 0, 2, 1),\nFCE(\"ｉ\", 1, 2, 1),FCE(\"𐐋\", 0, 2, 1),FCE(\"𐐳\", 1, 2, 1),FCE(\"Ꜫ\", 0, 2, 1),\nFCE(\"ꜫ\", 1, 2, 1),FCE(\"ﬀ\", 0, 2, 1),FCE(\"ff\", 1, 2, 2),FCE(\"Ⲁ\", 0, 2, 1),\nFCE(\"ⲁ\", 1, 2, 1),FCE(\"ﬂ\", 0, 2, 1),FCE(\"fl\", 1, 2, 2),FCE(\"ﬃ\", 0, 2, 1),\nFCE(\"ffi\", 1, 2, 3),FCE(\"ﬄ\", 0, 2, 1),FCE(\"ffl\", 1, 2, 3),FCE(\"ﬅ\", 0, 3, 1),\nFCE(\"ﬆ\", 1, 3, 1),FCE(\"st\", 2, 3, 2),FCE(\"ﬅ\", 0, 3, 1),FCE(\"ﬆ\", 1, 3, 1),\nFCE(\"st\", 2, 3, 2),FCE(\"Ꜭ\", 0, 2, 1),FCE(\"ꜭ\", 1, 2, 1),FCE(\"Ⰾ\", 0, 2, 1),\nFCE(\"ⰾ\", 1, 2, 1),FCE(\"Ｍ\", 0, 2, 1),FCE(\"ｍ\", 1, 2, 1),FCE(\"ﬓ\", 0, 2, 1),\nFCE(\"մն\", 1, 2, 2),FCE(\"ﬔ\", 0, 2, 1),FCE(\"մե\", 1, 2, 2),FCE(\"Ꜯ\", 0, 2, 1),\nFCE(\"ꜯ\", 1, 2, 1),FCE(\"ﬖ\", 0, 2, 1),FCE(\"վն\", 1, 2, 2),FCE(\"ﬗ\", 0, 2, 1),\nFCE(\"մխ\", 1, 2, 2),FCE(\"𐐍\", 0, 2, 1),FCE(\"𐐵\", 1, 2, 1),FCE(\"Ｏ\", 0, 2, 1),\nFCE(\"ｏ\", 1, 2, 1),FCE(\"Ｑ\", 0, 2, 1),FCE(\"ｑ\", 1, 2, 1),FCE(\"Ｒ\", 0, 2, 1),\nFCE(\"ｒ\", 1, 2, 1),FCE(\"𐐚\", 0, 2, 1),FCE(\"𐑂\", 1, 2, 1),FCE(\"Ｔ\", 0, 2, 1),\nFCE(\"ｔ\", 1, 2, 1),FCE(\"Ⲙ\", 0, 2, 1),FCE(\"ⲙ\", 1, 2, 1),FCE(\"Ⲋ\", 0, 2, 1),\nFCE(\"ⲋ\", 1, 2, 1),FCE(\"ͅ\", 0, 4, 1),FCE(\"Ι\", 1, 4, 1),FCE(\"ι\", 2, 4, 1),\nFCE(\"ι\", 3, 4, 1),FCE(\"Ⲍ\", 0, 2, 1),FCE(\"ⲍ\", 1, 2, 1),FCE(\"Ｗ\", 0, 2, 1),\nFCE(\"ｗ\", 1, 2, 1),FCE(\"Ꙗ\", 0, 2, 1),FCE(\"ꙗ\", 1, 2, 1),FCE(\"𐐛\", 0, 2, 1),\nFCE(\"𐑃\", 1, 2, 1),FCE(\"Ꜹ\", 0, 2, 1),FCE(\"ꜹ\", 1, 2, 1),FCE(\"Ⲏ\", 0, 2, 1),\nFCE(\"ⲏ\", 1, 2, 1),FCE(\"Ｙ\", 0, 2, 1),FCE(\"ｙ\", 1, 2, 1),FCE(\"𐐄\", 0, 2, 1),\nFCE(\"𐐬\", 1, 2, 1),FCE(\"Ꜻ\", 0, 2, 1),FCE(\"ꜻ\", 1, 2, 1),FCE(\"Ⲑ\", 0, 2, 1),\nFCE(\"ⲑ\", 1, 2, 1),FCE(\"Ꜽ\", 0, 2, 1),FCE(\"ꜽ\", 1, 2, 1),FCE(\"Ⲓ\", 0, 2, 1),\nFCE(\"ⲓ\", 1, 2, 1),FCE(\"𐐜\", 0, 2, 1),FCE(\"𐑄\", 1, 2, 1),FCE(\"Ͱ\", 0, 2, 1),\nFCE(\"ͱ\", 1, 2, 1),FCE(\"Ͳ\", 0, 2, 1),FCE(\"ͳ\", 1, 2, 1),FCE(\"Ꜿ\", 0, 2, 1),\nFCE(\"ꜿ\", 1, 2, 1),FCE(\"Ͷ\", 0, 2, 1),FCE(\"ͷ\", 1, 2, 1),FCE(\"Ⲕ\", 0, 2, 1),\nFCE(\"ⲕ\", 1, 2, 1),FCE(\"Ⲗ\", 0, 2, 1),FCE(\"ⲗ\", 1, 2, 1),FCE(\"Ά\", 0, 2, 1),\nFCE(\"ά\", 1, 2, 1),FCE(\"𐐅\", 0, 2, 1),FCE(\"𐐭\", 1, 2, 1),FCE(\"Έ\", 0, 2, 1),\nFCE(\"έ\", 1, 2, 1),FCE(\"Ή\", 0, 2, 1),FCE(\"ή\", 1, 2, 1),FCE(\"Ί\", 0, 2, 1),\nFCE(\"ί\", 1, 2, 1),FCE(\"Ό\", 0, 2, 1),FCE(\"ό\", 1, 2, 1),FCE(\"Ύ\", 0, 2, 1),\nFCE(\"ύ\", 1, 2, 1),FCE(\"Ώ\", 0, 2, 1),FCE(\"ώ\", 1, 2, 1),FCE(\"ΐ\", 0, 3, 1),\nFCE(\"ΐ\", 1, 3, 1),FCE(\"ΐ\", 2, 3, 3),FCE(\"Α\", 0, 2, 1),FCE(\"α\", 1, 2, 1),\nFCE(\"Β\", 0, 3, 1),FCE(\"β\", 1, 3, 1),FCE(\"ϐ\", 2, 3, 1),FCE(\"Γ\", 0, 2, 1),\nFCE(\"γ\", 1, 2, 1),FCE(\"Δ\", 0, 2, 1),FCE(\"δ\", 1, 2, 1),FCE(\"Ε\", 0, 3, 1),\nFCE(\"ε\", 1, 3, 1),FCE(\"ϵ\", 2, 3, 1),FCE(\"Ζ\", 0, 2, 1),FCE(\"ζ\", 1, 2, 1),\nFCE(\"Η\", 0, 2, 1),FCE(\"η\", 1, 2, 1),FCE(\"Θ\", 0, 4, 1),FCE(\"θ\", 1, 4, 1),\nFCE(\"ϑ\", 2, 4, 1),FCE(\"ϴ\", 3, 4, 1),FCE(\"ͅ\", 0, 4, 1),FCE(\"Ι\", 1, 4, 1),\nFCE(\"ι\", 2, 4, 1),FCE(\"ι\", 3, 4, 1),FCE(\"Κ\", 0, 3, 1),FCE(\"κ\", 1, 3, 1),\nFCE(\"ϰ\", 2, 3, 1),FCE(\"Λ\", 0, 2, 1),FCE(\"λ\", 1, 2, 1),FCE(\"µ\", 0, 3, 1),\nFCE(\"Μ\", 1, 3, 1),FCE(\"μ\", 2, 3, 1),FCE(\"Ν\", 0, 2, 1),FCE(\"ν\", 1, 2, 1),\nFCE(\"Ξ\", 0, 2, 1),FCE(\"ξ\", 1, 2, 1),FCE(\"Ο\", 0, 2, 1),FCE(\"ο\", 1, 2, 1),\nFCE(\"Π\", 0, 3, 1),FCE(\"π\", 1, 3, 1),FCE(\"ϖ\", 2, 3, 1),FCE(\"Ρ\", 0, 3, 1),\nFCE(\"ρ\", 1, 3, 1),FCE(\"ϱ\", 2, 3, 1),FCE(\"Σ\", 0, 3, 1),FCE(\"ς\", 1, 3, 1),\nFCE(\"σ\", 2, 3, 1),FCE(\"Τ\", 0, 2, 1),FCE(\"τ\", 1, 2, 1),FCE(\"Υ\", 0, 2, 1),\nFCE(\"υ\", 1, 2, 1),FCE(\"Φ\", 0, 3, 1),FCE(\"φ\", 1, 3, 1),FCE(\"ϕ\", 2, 3, 1),\nFCE(\"Χ\", 0, 2, 1),FCE(\"χ\", 1, 2, 1),FCE(\"Ψ\", 0, 2, 1),FCE(\"ψ\", 1, 2, 1),\nFCE(\"Ω\", 0, 3, 1),FCE(\"ω\", 1, 3, 1),FCE(\"Ω\", 2, 3, 1),FCE(\"Ϊ\", 0, 2, 1),\nFCE(\"ϊ\", 1, 2, 1),FCE(\"Ϋ\", 0, 2, 1),FCE(\"ϋ\", 1, 2, 1),FCE(\"Ⓣ\", 0, 2, 1),\nFCE(\"ⓣ\", 1, 2, 1),FCE(\"Ⳡ\", 0, 2, 1),FCE(\"ⳡ\", 1, 2, 1),FCE(\"ΰ\", 0, 3, 1),\nFCE(\"ΰ\", 1, 3, 1),FCE(\"ΰ\", 2, 3, 3),FCE(\"Ꝉ\", 0, 2, 1),FCE(\"ꝉ\", 1, 2, 1),\nFCE(\"Ⲝ\", 0, 2, 1),FCE(\"ⲝ\", 1, 2, 1),FCE(\"Ⲟ\", 0, 2, 1),FCE(\"ⲟ\", 1, 2, 1),\nFCE(\"Ꝋ\", 0, 2, 1),FCE(\"ꝋ\", 1, 2, 1),FCE(\"Ⲡ\", 0, 2, 1),FCE(\"ⲡ\", 1, 2, 1),\nFCE(\"Σ\", 0, 3, 1),FCE(\"ς\", 1, 3, 1),FCE(\"σ\", 2, 3, 1),FCE(\"𐐟\", 0, 2, 1),\nFCE(\"𐑇\", 1, 2, 1),FCE(\"Ꝍ\", 0, 2, 1),FCE(\"ꝍ\", 1, 2, 1),FCE(\"Ꚋ\", 0, 2, 1),\nFCE(\"ꚋ\", 1, 2, 1),FCE(\"Ⲣ\", 0, 2, 1),FCE(\"ⲣ\", 1, 2, 1),FCE(\"Ϗ\", 0, 2, 1),\nFCE(\"ϗ\", 1, 2, 1),FCE(\"Β\", 0, 3, 1),FCE(\"β\", 1, 3, 1),FCE(\"ϐ\", 2, 3, 1),\nFCE(\"Θ\", 0, 4, 1),FCE(\"θ\", 1, 4, 1),FCE(\"ϑ\", 2, 4, 1),FCE(\"ϴ\", 3, 4, 1),\nFCE(\"Φ\", 0, 3, 1),FCE(\"φ\", 1, 3, 1),FCE(\"ϕ\", 2, 3, 1),FCE(\"Π\", 0, 3, 1),\nFCE(\"π\", 1, 3, 1),FCE(\"ϖ\", 2, 3, 1),FCE(\"Ϙ\", 0, 2, 1),FCE(\"ϙ\", 1, 2, 1),\nFCE(\"Ⲥ\", 0, 2, 1),FCE(\"ⲥ\", 1, 2, 1),FCE(\"Ϛ\", 0, 2, 1),FCE(\"ϛ\", 1, 2, 1),\nFCE(\"Ϝ\", 0, 2, 1),FCE(\"ϝ\", 1, 2, 1),FCE(\"Ϟ\", 0, 2, 1),FCE(\"ϟ\", 1, 2, 1),\nFCE(\"Ϡ\", 0, 2, 1),FCE(\"ϡ\", 1, 2, 1),FCE(\"Ꝑ\", 0, 2, 1),FCE(\"ꝑ\", 1, 2, 1),\nFCE(\"Ϣ\", 0, 2, 1),FCE(\"ϣ\", 1, 2, 1),FCE(\"Ϥ\", 0, 2, 1),FCE(\"ϥ\", 1, 2, 1),\nFCE(\"Ⲧ\", 0, 2, 1),FCE(\"ⲧ\", 1, 2, 1),FCE(\"Ϧ\", 0, 2, 1),FCE(\"ϧ\", 1, 2, 1),\nFCE(\"𐐠\", 0, 2, 1),FCE(\"𐑈\", 1, 2, 1),FCE(\"Ϩ\", 0, 2, 1),FCE(\"ϩ\", 1, 2, 1),\nFCE(\"Ⳣ\", 0, 2, 1),FCE(\"ⳣ\", 1, 2, 1),FCE(\"Ϫ\", 0, 2, 1),FCE(\"ϫ\", 1, 2, 1),\nFCE(\"Ϭ\", 0, 2, 1),FCE(\"ϭ\", 1, 2, 1),FCE(\"Ꝓ\", 0, 2, 1),FCE(\"ꝓ\", 1, 2, 1),\nFCE(\"Ϯ\", 0, 2, 1),FCE(\"ϯ\", 1, 2, 1),FCE(\"Κ\", 0, 3, 1),FCE(\"κ\", 1, 3, 1),\nFCE(\"ϰ\", 2, 3, 1),FCE(\"Ρ\", 0, 3, 1),FCE(\"ρ\", 1, 3, 1),FCE(\"ϱ\", 2, 3, 1),\nFCE(\"Θ\", 0, 4, 1),FCE(\"θ\", 1, 4, 1),FCE(\"ϑ\", 2, 4, 1),FCE(\"ϴ\", 3, 4, 1),\nFCE(\"Ε\", 0, 3, 1),FCE(\"ε\", 1, 3, 1),FCE(\"ϵ\", 2, 3, 1),FCE(\"Ϸ\", 0, 2, 1),\nFCE(\"ϸ\", 1, 2, 1),FCE(\"ϲ\", 0, 2, 1),FCE(\"Ϲ\", 1, 2, 1),FCE(\"Ϻ\", 0, 2, 1),\nFCE(\"ϻ\", 1, 2, 1),FCE(\"ͻ\", 0, 2, 1),FCE(\"Ͻ\", 1, 2, 1),FCE(\"ͼ\", 0, 2, 1),\nFCE(\"Ͼ\", 1, 2, 1),FCE(\"ͽ\", 0, 2, 1),FCE(\"Ͽ\", 1, 2, 1),FCE(\"Ѐ\", 0, 2, 1),\nFCE(\"ѐ\", 1, 2, 1),FCE(\"Ё\", 0, 2, 1),FCE(\"ё\", 1, 2, 1),FCE(\"Ђ\", 0, 2, 1),\nFCE(\"ђ\", 1, 2, 1),FCE(\"Ѓ\", 0, 2, 1),FCE(\"ѓ\", 1, 2, 1),FCE(\"Є\", 0, 2, 1),\nFCE(\"є\", 1, 2, 1),FCE(\"Ѕ\", 0, 2, 1),FCE(\"ѕ\", 1, 2, 1),FCE(\"І\", 0, 2, 1),\nFCE(\"і\", 1, 2, 1),FCE(\"Ї\", 0, 2, 1),FCE(\"ї\", 1, 2, 1),FCE(\"Ј\", 0, 2, 1),\nFCE(\"ј\", 1, 2, 1),FCE(\"Љ\", 0, 2, 1),FCE(\"љ\", 1, 2, 1),FCE(\"Њ\", 0, 2, 1),\nFCE(\"њ\", 1, 2, 1),FCE(\"Ћ\", 0, 2, 1),FCE(\"ћ\", 1, 2, 1),FCE(\"Ќ\", 0, 2, 1),\nFCE(\"ќ\", 1, 2, 1),FCE(\"Ѝ\", 0, 2, 1),FCE(\"ѝ\", 1, 2, 1),FCE(\"Ў\", 0, 2, 1),\nFCE(\"ў\", 1, 2, 1),FCE(\"Џ\", 0, 2, 1),FCE(\"џ\", 1, 2, 1),FCE(\"А\", 0, 2, 1),\nFCE(\"а\", 1, 2, 1),FCE(\"Б\", 0, 2, 1),FCE(\"б\", 1, 2, 1),FCE(\"В\", 0, 2, 1),\nFCE(\"в\", 1, 2, 1),FCE(\"Г\", 0, 2, 1),FCE(\"г\", 1, 2, 1),FCE(\"Д\", 0, 2, 1),\nFCE(\"д\", 1, 2, 1),FCE(\"Е\", 0, 2, 1),FCE(\"е\", 1, 2, 1),FCE(\"Ж\", 0, 2, 1),\nFCE(\"ж\", 1, 2, 1),FCE(\"З\", 0, 2, 1),FCE(\"з\", 1, 2, 1),FCE(\"И\", 0, 2, 1),\nFCE(\"и\", 1, 2, 1),FCE(\"Й\", 0, 2, 1),FCE(\"й\", 1, 2, 1),FCE(\"К\", 0, 2, 1),\nFCE(\"к\", 1, 2, 1),FCE(\"Л\", 0, 2, 1),FCE(\"л\", 1, 2, 1),FCE(\"М\", 0, 2, 1),\nFCE(\"м\", 1, 2, 1),FCE(\"Н\", 0, 2, 1),FCE(\"н\", 1, 2, 1),FCE(\"О\", 0, 2, 1),\nFCE(\"о\", 1, 2, 1),FCE(\"П\", 0, 2, 1),FCE(\"п\", 1, 2, 1),FCE(\"Р\", 0, 2, 1),\nFCE(\"р\", 1, 2, 1),FCE(\"С\", 0, 2, 1),FCE(\"с\", 1, 2, 1),FCE(\"Т\", 0, 2, 1),\nFCE(\"т\", 1, 2, 1),FCE(\"У\", 0, 2, 1),FCE(\"у\", 1, 2, 1),FCE(\"Ф\", 0, 2, 1),\nFCE(\"ф\", 1, 2, 1),FCE(\"Х\", 0, 2, 1),FCE(\"х\", 1, 2, 1),FCE(\"Ц\", 0, 2, 1),\nFCE(\"ц\", 1, 2, 1),FCE(\"Ч\", 0, 2, 1),FCE(\"ч\", 1, 2, 1),FCE(\"Ш\", 0, 2, 1),\nFCE(\"ш\", 1, 2, 1),FCE(\"Щ\", 0, 2, 1),FCE(\"щ\", 1, 2, 1),FCE(\"Ъ\", 0, 2, 1),\nFCE(\"ъ\", 1, 2, 1),FCE(\"Ы\", 0, 2, 1),FCE(\"ы\", 1, 2, 1),FCE(\"Ь\", 0, 2, 1),\nFCE(\"ь\", 1, 2, 1),FCE(\"Э\", 0, 2, 1),FCE(\"э\", 1, 2, 1),FCE(\"Ю\", 0, 2, 1),\nFCE(\"ю\", 1, 2, 1),FCE(\"Я\", 0, 2, 1),FCE(\"я\", 1, 2, 1),FCE(\"Ｚ\", 0, 2, 1),\nFCE(\"ｚ\", 1, 2, 1),FCE(\"Ⲵ\", 0, 2, 1),FCE(\"ⲵ\", 1, 2, 1),FCE(\"µ\", 0, 3, 1),\nFCE(\"Μ\", 1, 3, 1),FCE(\"μ\", 2, 3, 1),FCE(\"𐐣\", 0, 2, 1),FCE(\"𐑋\", 1, 2, 1),\nFCE(\"Ⓐ\", 0, 2, 1),FCE(\"ⓐ\", 1, 2, 1),FCE(\"Ⓒ\", 0, 2, 1),FCE(\"ⓒ\", 1, 2, 1),\nFCE(\"Ｌ\", 0, 2, 1),FCE(\"ｌ\", 1, 2, 1),FCE(\"𐐡\", 0, 2, 1),FCE(\"𐑉\", 1, 2, 1),\nFCE(\"Ⓔ\", 0, 2, 1),FCE(\"ⓔ\", 1, 2, 1),FCE(\"𐐙\", 0, 2, 1),FCE(\"𐑁\", 1, 2, 1),\nFCE(\"Ѡ\", 0, 2, 1),FCE(\"ѡ\", 1, 2, 1),FCE(\"Ѣ\", 0, 2, 1),FCE(\"ѣ\", 1, 2, 1),\nFCE(\"ᵽ\", 0, 2, 1),FCE(\"Ᵽ\", 1, 2, 1),FCE(\"Ѥ\", 0, 2, 1),FCE(\"ѥ\", 1, 2, 1),\nFCE(\"Ѧ\", 0, 2, 1),FCE(\"ѧ\", 1, 2, 1),FCE(\"Ⱨ\", 0, 2, 1),FCE(\"ⱨ\", 1, 2, 1),\nFCE(\"Ѩ\", 0, 2, 1),FCE(\"ѩ\", 1, 2, 1),FCE(\"Ⓖ\", 0, 2, 1),FCE(\"ⓖ\", 1, 2, 1),\nFCE(\"Ѫ\", 0, 2, 1),FCE(\"ѫ\", 1, 2, 1),FCE(\"Ⱬ\", 0, 2, 1),FCE(\"ⱬ\", 1, 2, 1),\nFCE(\"Ѭ\", 0, 2, 1),FCE(\"ѭ\", 1, 2, 1),FCE(\"ɑ\", 0, 2, 1),FCE(\"Ɑ\", 1, 2, 1),\nFCE(\"Ѯ\", 0, 2, 1),FCE(\"ѯ\", 1, 2, 1),FCE(\"ɐ\", 0, 2, 1),FCE(\"Ɐ\", 1, 2, 1),\nFCE(\"Ѱ\", 0, 2, 1),FCE(\"ѱ\", 1, 2, 1),FCE(\"Ꝩ\", 0, 2, 1),FCE(\"ꝩ\", 1, 2, 1),\nFCE(\"Ѳ\", 0, 2, 1),FCE(\"ѳ\", 1, 2, 1),FCE(\"Ѵ\", 0, 2, 1),FCE(\"ѵ\", 1, 2, 1),\nFCE(\"Ⓘ\", 0, 2, 1),FCE(\"ⓘ\", 1, 2, 1),FCE(\"Ѷ\", 0, 2, 1),FCE(\"ѷ\", 1, 2, 1),\nFCE(\"Ѹ\", 0, 2, 1),FCE(\"ѹ\", 1, 2, 1),FCE(\"Ѻ\", 0, 2, 1),FCE(\"ѻ\", 1, 2, 1),\nFCE(\"Ѽ\", 0, 2, 1),FCE(\"ѽ\", 1, 2, 1),FCE(\"Ꝫ\", 0, 2, 1),FCE(\"ꝫ\", 1, 2, 1),\nFCE(\"Ѿ\", 0, 2, 1),FCE(\"ѿ\", 1, 2, 1),FCE(\"ɀ\", 0, 2, 1),FCE(\"Ɀ\", 1, 2, 1),\nFCE(\"Ҁ\", 0, 2, 1),FCE(\"ҁ\", 1, 2, 1),FCE(\"Ⴠ\", 0, 2, 1),FCE(\"ⴠ\", 1, 2, 1),\nFCE(\"Ⲃ\", 0, 2, 1),FCE(\"ⲃ\", 1, 2, 1),FCE(\"Ⲅ\", 0, 2, 1),FCE(\"ⲅ\", 1, 2, 1),\nFCE(\"Ⲇ\", 0, 2, 1),FCE(\"ⲇ\", 1, 2, 1),FCE(\"Ⴡ\", 0, 2, 1),FCE(\"ⴡ\", 1, 2, 1),\nFCE(\"Ⲉ\", 0, 2, 1),FCE(\"ⲉ\", 1, 2, 1),FCE(\"Ꝭ\", 0, 2, 1),FCE(\"ꝭ\", 1, 2, 1),\nFCE(\"Ҋ\", 0, 2, 1),FCE(\"ҋ\", 1, 2, 1),FCE(\"Ҍ\", 0, 2, 1),FCE(\"ҍ\", 1, 2, 1),\nFCE(\"Â\", 0, 2, 1),FCE(\"â\", 1, 2, 1),FCE(\"Ҏ\", 0, 2, 1),FCE(\"ҏ\", 1, 2, 1),\nFCE(\"Ґ\", 0, 2, 1),FCE(\"ґ\", 1, 2, 1),FCE(\"Ғ\", 0, 2, 1),FCE(\"ғ\", 1, 2, 1),\nFCE(\"Ⴣ\", 0, 2, 1),FCE(\"ⴣ\", 1, 2, 1),FCE(\"Ҕ\", 0, 2, 1),FCE(\"ҕ\", 1, 2, 1),\nFCE(\"Ꝯ\", 0, 2, 1),FCE(\"ꝯ\", 1, 2, 1),FCE(\"Җ\", 0, 2, 1),FCE(\"җ\", 1, 2, 1),\nFCE(\"Ҙ\", 0, 2, 1),FCE(\"ҙ\", 1, 2, 1),FCE(\"Ä\", 0, 2, 1),FCE(\"ä\", 1, 2, 1),\nFCE(\"Қ\", 0, 2, 1),FCE(\"қ\", 1, 2, 1),FCE(\"𐐦\", 0, 2, 1),FCE(\"𐑎\", 1, 2, 1),\nFCE(\"Ҝ\", 0, 2, 1),FCE(\"ҝ\", 1, 2, 1),FCE(\"Ҟ\", 0, 2, 1),FCE(\"ҟ\", 1, 2, 1),\nFCE(\"Ⴥ\", 0, 2, 1),FCE(\"ⴥ\", 1, 2, 1),FCE(\"Ҡ\", 0, 2, 1),FCE(\"ҡ\", 1, 2, 1),\nFCE(\"Ң\", 0, 2, 1),FCE(\"ң\", 1, 2, 1),FCE(\"Ҥ\", 0, 2, 1),FCE(\"ҥ\", 1, 2, 1),\nFCE(\"Ⳇ\", 0, 2, 1),FCE(\"ⳇ\", 1, 2, 1),FCE(\"Ҧ\", 0, 2, 1),FCE(\"ҧ\", 1, 2, 1),\nFCE(\"Ҩ\", 0, 2, 1),FCE(\"ҩ\", 1, 2, 1),FCE(\"Ⱡ\", 0, 2, 1),FCE(\"ⱡ\", 1, 2, 1),\nFCE(\"Ҫ\", 0, 2, 1),FCE(\"ҫ\", 1, 2, 1),FCE(\"Ⴧ\", 0, 2, 1),FCE(\"ⴧ\", 1, 2, 1),\nFCE(\"Ҭ\", 0, 2, 1),FCE(\"ҭ\", 1, 2, 1),FCE(\"𐐓\", 0, 2, 1),FCE(\"𐐻\", 1, 2, 1),\nFCE(\"Ү\", 0, 2, 1),FCE(\"ү\", 1, 2, 1),FCE(\"Ұ\", 0, 2, 1),FCE(\"ұ\", 1, 2, 1),\nFCE(\"Ⳉ\", 0, 2, 1),FCE(\"ⳉ\", 1, 2, 1),FCE(\"Ҳ\", 0, 2, 1),FCE(\"ҳ\", 1, 2, 1),\nFCE(\"Ҵ\", 0, 2, 1),FCE(\"ҵ\", 1, 2, 1),FCE(\"Ҷ\", 0, 2, 1),FCE(\"ҷ\", 1, 2, 1),\nFCE(\"Ⓑ\", 0, 2, 1),FCE(\"ⓑ\", 1, 2, 1),FCE(\"Ҹ\", 0, 2, 1),FCE(\"ҹ\", 1, 2, 1),\nFCE(\"Ⓓ\", 0, 2, 1),FCE(\"ⓓ\", 1, 2, 1),FCE(\"Һ\", 0, 2, 1),FCE(\"һ\", 1, 2, 1),\nFCE(\"Ⓕ\", 0, 2, 1),FCE(\"ⓕ\", 1, 2, 1),FCE(\"Ҽ\", 0, 2, 1),FCE(\"ҽ\", 1, 2, 1),\nFCE(\"Ⓗ\", 0, 2, 1),FCE(\"ⓗ\", 1, 2, 1),FCE(\"Ҿ\", 0, 2, 1),FCE(\"ҿ\", 1, 2, 1),\nFCE(\"Ⓙ\", 0, 2, 1),FCE(\"ⓙ\", 1, 2, 1),FCE(\"Ӏ\", 0, 2, 1),FCE(\"ӏ\", 1, 2, 1),\nFCE(\"Ӂ\", 0, 2, 1),FCE(\"ӂ\", 1, 2, 1),FCE(\"Ⓜ\", 0, 2, 1),FCE(\"ⓜ\", 1, 2, 1),\nFCE(\"Ӄ\", 0, 2, 1),FCE(\"ӄ\", 1, 2, 1),FCE(\"Ⓞ\", 0, 2, 1),FCE(\"ⓞ\", 1, 2, 1),\nFCE(\"Ӆ\", 0, 2, 1),FCE(\"ӆ\", 1, 2, 1),FCE(\"Ⓠ\", 0, 2, 1),FCE(\"ⓠ\", 1, 2, 1),\nFCE(\"Ӈ\", 0, 2, 1),FCE(\"ӈ\", 1, 2, 1),FCE(\"Ⓢ\", 0, 2, 1),FCE(\"ⓢ\", 1, 2, 1),\nFCE(\"Ӊ\", 0, 2, 1),FCE(\"ӊ\", 1, 2, 1),FCE(\"Ⓤ\", 0, 2, 1),FCE(\"ⓤ\", 1, 2, 1),\nFCE(\"Ӌ\", 0, 2, 1),FCE(\"ӌ\", 1, 2, 1),FCE(\"Ⓦ\", 0, 2, 1),FCE(\"ⓦ\", 1, 2, 1),\nFCE(\"Ӎ\", 0, 2, 1),FCE(\"ӎ\", 1, 2, 1),FCE(\"Ⓨ\", 0, 2, 1),FCE(\"ⓨ\", 1, 2, 1),\nFCE(\"Ⴭ\", 0, 2, 1),FCE(\"ⴭ\", 1, 2, 1),FCE(\"Ӑ\", 0, 2, 1),FCE(\"ӑ\", 1, 2, 1),\nFCE(\"Ӓ\", 0, 2, 1),FCE(\"ӓ\", 1, 2, 1),FCE(\"Ӕ\", 0, 2, 1),FCE(\"ӕ\", 1, 2, 1),\nFCE(\"Ⳏ\", 0, 2, 1),FCE(\"ⳏ\", 1, 2, 1),FCE(\"Ӗ\", 0, 2, 1),FCE(\"ӗ\", 1, 2, 1),\nFCE(\"Ꝺ\", 0, 2, 1),FCE(\"ꝺ\", 1, 2, 1),FCE(\"Ә\", 0, 2, 1),FCE(\"ә\", 1, 2, 1),\nFCE(\"Ӛ\", 0, 2, 1),FCE(\"ӛ\", 1, 2, 1),FCE(\"Ⓩ\", 0, 2, 1),FCE(\"ⓩ\", 1, 2, 1),\nFCE(\"Ӝ\", 0, 2, 1),FCE(\"ӝ\", 1, 2, 1),FCE(\"Ӟ\", 0, 2, 1),FCE(\"ӟ\", 1, 2, 1),\nFCE(\"Ӡ\", 0, 2, 1),FCE(\"ӡ\", 1, 2, 1),FCE(\"Ⳑ\", 0, 2, 1),FCE(\"ⳑ\", 1, 2, 1),\nFCE(\"Ӣ\", 0, 2, 1),FCE(\"ӣ\", 1, 2, 1),FCE(\"Ӥ\", 0, 2, 1),FCE(\"ӥ\", 1, 2, 1),\nFCE(\"ɫ\", 0, 2, 1),FCE(\"Ɫ\", 1, 2, 1),FCE(\"Ӧ\", 0, 2, 1),FCE(\"ӧ\", 1, 2, 1),\nFCE(\"Ө\", 0, 2, 1),FCE(\"ө\", 1, 2, 1),FCE(\"Ӫ\", 0, 2, 1),FCE(\"ӫ\", 1, 2, 1),\nFCE(\"Ⅎ\", 0, 2, 1),FCE(\"ⅎ\", 1, 2, 1),FCE(\"Ӭ\", 0, 2, 1),FCE(\"ӭ\", 1, 2, 1),\nFCE(\"Ⳓ\", 0, 2, 1),FCE(\"ⳓ\", 1, 2, 1),FCE(\"Ӯ\", 0, 2, 1),FCE(\"ӯ\", 1, 2, 1),\nFCE(\"Ӱ\", 0, 2, 1),FCE(\"ӱ\", 1, 2, 1),FCE(\"𐐢\", 0, 2, 1),FCE(\"𐑊\", 1, 2, 1),\nFCE(\"Ӳ\", 0, 2, 1),FCE(\"ӳ\", 1, 2, 1),FCE(\"Ӵ\", 0, 2, 1),FCE(\"ӵ\", 1, 2, 1),\nFCE(\"Ӷ\", 0, 2, 1),FCE(\"ӷ\", 1, 2, 1),FCE(\"Ӹ\", 0, 2, 1),FCE(\"ӹ\", 1, 2, 1),\nFCE(\"Ⳕ\", 0, 2, 1),FCE(\"ⳕ\", 1, 2, 1),FCE(\"Ӻ\", 0, 2, 1),FCE(\"ӻ\", 1, 2, 1),\nFCE(\"Ӽ\", 0, 2, 1),FCE(\"ӽ\", 1, 2, 1),FCE(\"Ӿ\", 0, 2, 1),FCE(\"ӿ\", 1, 2, 1),\nFCE(\"Ԁ\", 0, 2, 1),FCE(\"ԁ\", 1, 2, 1),FCE(\"Ꞁ\", 0, 2, 1),FCE(\"ꞁ\", 1, 2, 1),\nFCE(\"Ԃ\", 0, 2, 1),FCE(\"ԃ\", 1, 2, 1),FCE(\"Ԅ\", 0, 2, 1),FCE(\"ԅ\", 1, 2, 1),\nFCE(\"Ⳗ\", 0, 2, 1),FCE(\"ⳗ\", 1, 2, 1),FCE(\"Ԇ\", 0, 2, 1),FCE(\"ԇ\", 1, 2, 1),\nFCE(\"Ԉ\", 0, 2, 1),FCE(\"ԉ\", 1, 2, 1),FCE(\"Ԋ\", 0, 2, 1),FCE(\"ԋ\", 1, 2, 1),\nFCE(\"Ԍ\", 0, 2, 1),FCE(\"ԍ\", 1, 2, 1),FCE(\"Ꞃ\", 0, 2, 1),FCE(\"ꞃ\", 1, 2, 1),\nFCE(\"Ԏ\", 0, 2, 1),FCE(\"ԏ\", 1, 2, 1),FCE(\"Ԑ\", 0, 2, 1),FCE(\"ԑ\", 1, 2, 1),\nFCE(\"Ⳙ\", 0, 2, 1),FCE(\"ⳙ\", 1, 2, 1),FCE(\"Ԓ\", 0, 2, 1),FCE(\"ԓ\", 1, 2, 1),\nFCE(\"Ԕ\", 0, 2, 1),FCE(\"ԕ\", 1, 2, 1),FCE(\"Ԗ\", 0, 2, 1),FCE(\"ԗ\", 1, 2, 1),\nFCE(\"Ԙ\", 0, 2, 1),FCE(\"ԙ\", 1, 2, 1),FCE(\"Ꞅ\", 0, 2, 1),FCE(\"ꞅ\", 1, 2, 1),\nFCE(\"Ԛ\", 0, 2, 1),FCE(\"ԛ\", 1, 2, 1),FCE(\"Ⲩ\", 0, 2, 1),FCE(\"ⲩ\", 1, 2, 1),\nFCE(\"Ԝ\", 0, 2, 1),FCE(\"ԝ\", 1, 2, 1),FCE(\"Ⳛ\", 0, 2, 1),FCE(\"ⳛ\", 1, 2, 1),\nFCE(\"Ԟ\", 0, 2, 1),FCE(\"ԟ\", 1, 2, 1),FCE(\"Ԡ\", 0, 2, 1),FCE(\"ԡ\", 1, 2, 1),\nFCE(\"Ԣ\", 0, 2, 1),FCE(\"ԣ\", 1, 2, 1),FCE(\"Ԥ\", 0, 2, 1),FCE(\"ԥ\", 1, 2, 1),\nFCE(\"Ꞇ\", 0, 2, 1),FCE(\"ꞇ\", 1, 2, 1),FCE(\"Ԧ\", 0, 2, 1),FCE(\"ԧ\", 1, 2, 1),\nFCE(\"Ⱐ\", 0, 2, 1),FCE(\"ⱐ\", 1, 2, 1),FCE(\"Ⳝ\", 0, 2, 1),FCE(\"ⳝ\", 1, 2, 1),\nFCE(\"Ա\", 0, 2, 1),FCE(\"ա\", 1, 2, 1),FCE(\"Բ\", 0, 2, 1),FCE(\"բ\", 1, 2, 1),\nFCE(\"Գ\", 0, 2, 1),FCE(\"գ\", 1, 2, 1),FCE(\"Դ\", 0, 2, 1),FCE(\"դ\", 1, 2, 1),\nFCE(\"Ե\", 0, 2, 1),FCE(\"ե\", 1, 2, 1),FCE(\"Զ\", 0, 2, 1),FCE(\"զ\", 1, 2, 1),\nFCE(\"Է\", 0, 2, 1),FCE(\"է\", 1, 2, 1),FCE(\"Ը\", 0, 2, 1),FCE(\"ը\", 1, 2, 1),\nFCE(\"Թ\", 0, 2, 1),FCE(\"թ\", 1, 2, 1),FCE(\"Ժ\", 0, 2, 1),FCE(\"ժ\", 1, 2, 1),\nFCE(\"Ի\", 0, 2, 1),FCE(\"ի\", 1, 2, 1),FCE(\"Լ\", 0, 2, 1),FCE(\"լ\", 1, 2, 1),\nFCE(\"Խ\", 0, 2, 1),FCE(\"խ\", 1, 2, 1),FCE(\"Ծ\", 0, 2, 1),FCE(\"ծ\", 1, 2, 1),\nFCE(\"Կ\", 0, 2, 1),FCE(\"կ\", 1, 2, 1),FCE(\"Հ\", 0, 2, 1),FCE(\"հ\", 1, 2, 1),\nFCE(\"Ձ\", 0, 2, 1),FCE(\"ձ\", 1, 2, 1),FCE(\"Ղ\", 0, 2, 1),FCE(\"ղ\", 1, 2, 1),\nFCE(\"Ճ\", 0, 2, 1),FCE(\"ճ\", 1, 2, 1),FCE(\"Մ\", 0, 2, 1),FCE(\"մ\", 1, 2, 1),\nFCE(\"Յ\", 0, 2, 1),FCE(\"յ\", 1, 2, 1),FCE(\"Ն\", 0, 2, 1),FCE(\"ն\", 1, 2, 1),\nFCE(\"Շ\", 0, 2, 1),FCE(\"շ\", 1, 2, 1),FCE(\"Ո\", 0, 2, 1),FCE(\"ո\", 1, 2, 1),\nFCE(\"Չ\", 0, 2, 1),FCE(\"չ\", 1, 2, 1),FCE(\"Պ\", 0, 2, 1),FCE(\"պ\", 1, 2, 1),\nFCE(\"Ջ\", 0, 2, 1),FCE(\"ջ\", 1, 2, 1),FCE(\"Ռ\", 0, 2, 1),FCE(\"ռ\", 1, 2, 1),\nFCE(\"Ս\", 0, 2, 1),FCE(\"ս\", 1, 2, 1),FCE(\"Վ\", 0, 2, 1),FCE(\"վ\", 1, 2, 1),\nFCE(\"Տ\", 0, 2, 1),FCE(\"տ\", 1, 2, 1),FCE(\"Ր\", 0, 2, 1),FCE(\"ր\", 1, 2, 1),\nFCE(\"Ց\", 0, 2, 1),FCE(\"ց\", 1, 2, 1),FCE(\"Ւ\", 0, 2, 1),FCE(\"ւ\", 1, 2, 1),\nFCE(\"Փ\", 0, 2, 1),FCE(\"փ\", 1, 2, 1),FCE(\"Ք\", 0, 2, 1),FCE(\"ք\", 1, 2, 1),\nFCE(\"Օ\", 0, 2, 1),FCE(\"օ\", 1, 2, 1),FCE(\"Ֆ\", 0, 2, 1),FCE(\"ֆ\", 1, 2, 1),\nFCE(\"Ⲫ\", 0, 2, 1),FCE(\"ⲫ\", 1, 2, 1),FCE(\"Ꞑ\", 0, 2, 1),FCE(\"ꞑ\", 1, 2, 1),\nFCE(\"Ⱒ\", 0, 2, 1),FCE(\"ⱒ\", 1, 2, 1),FCE(\"Ꞓ\", 0, 2, 1),FCE(\"ꞓ\", 1, 2, 1),\nFCE(\"Ⱓ\", 0, 2, 1),FCE(\"ⱓ\", 1, 2, 1),FCE(\"Ⳬ\", 0, 2, 1),FCE(\"ⳬ\", 1, 2, 1),\nFCE(\"Ⳋ\", 0, 2, 1),FCE(\"ⳋ\", 1, 2, 1),FCE(\"և\", 0, 2, 1),FCE(\"եւ\", 1, 2, 2),\nFCE(\"Ꙃ\", 0, 2, 1),FCE(\"ꙃ\", 1, 2, 1),FCE(\"Ⳮ\", 0, 2, 1),FCE(\"ⳮ\", 1, 2, 1),\nFCE(\"Ⲭ\", 0, 2, 1),FCE(\"ⲭ\", 1, 2, 1),FCE(\"Ꙅ\", 0, 2, 1),FCE(\"ꙅ\", 1, 2, 1),\nFCE(\"Ⱔ\", 0, 2, 1),FCE(\"ⱔ\", 1, 2, 1),FCE(\"Ꝕ\", 0, 2, 1),FCE(\"ꝕ\", 1, 2, 1),\nFCE(\"Ꙇ\", 0, 2, 1),FCE(\"ꙇ\", 1, 2, 1),FCE(\"Ⳳ\", 0, 2, 1),FCE(\"ⳳ\", 1, 2, 1),\nFCE(\"𐐈\", 0, 2, 1),FCE(\"𐐰\", 1, 2, 1),FCE(\"Ꙉ\", 0, 2, 1),FCE(\"ꙉ\", 1, 2, 1),\nFCE(\"Ⱕ\", 0, 2, 1),FCE(\"ⱕ\", 1, 2, 1),FCE(\"Ꞡ\", 0, 2, 1),FCE(\"ꞡ\", 1, 2, 1),\nFCE(\"Ꙍ\", 0, 2, 1),FCE(\"ꙍ\", 1, 2, 1),FCE(\"Ꞣ\", 0, 2, 1),FCE(\"ꞣ\", 1, 2, 1),\nFCE(\"Ⲯ\", 0, 2, 1),FCE(\"ⲯ\", 1, 2, 1),FCE(\"Ꙏ\", 0, 2, 1),FCE(\"ꙏ\", 1, 2, 1),\nFCE(\"Ꞥ\", 0, 2, 1),FCE(\"ꞥ\", 1, 2, 1),FCE(\"Ꙑ\", 0, 2, 1),FCE(\"ꙑ\", 1, 2, 1),\nFCE(\"Ꞧ\", 0, 2, 1),FCE(\"ꞧ\", 1, 2, 1),FCE(\"Ꞌ\", 0, 2, 1),FCE(\"ꞌ\", 1, 2, 1),\nFCE(\"Ꙓ\", 0, 2, 1),FCE(\"ꙓ\", 1, 2, 1),FCE(\"Ꞩ\", 0, 2, 1),FCE(\"ꞩ\", 1, 2, 1),\nFCE(\"Ꙕ\", 0, 2, 1),FCE(\"ꙕ\", 1, 2, 1),FCE(\"ɦ\", 0, 2, 1),FCE(\"Ɦ\", 1, 2, 1),\nFCE(\"Ḁ\", 0, 2, 1),FCE(\"ḁ\", 1, 2, 1),FCE(\"Ḃ\", 0, 2, 1),FCE(\"ḃ\", 1, 2, 1),\nFCE(\"Ḅ\", 0, 2, 1),FCE(\"ḅ\", 1, 2, 1),FCE(\"Ⱏ\", 0, 2, 1),FCE(\"ⱏ\", 1, 2, 1),\nFCE(\"Ḇ\", 0, 2, 1),FCE(\"ḇ\", 1, 2, 1),FCE(\"𐐎\", 0, 2, 1),FCE(\"𐐶\", 1, 2, 1),\nFCE(\"Ḉ\", 0, 2, 1),FCE(\"ḉ\", 1, 2, 1),FCE(\"Ḋ\", 0, 2, 1),FCE(\"ḋ\", 1, 2, 1),\nFCE(\"Ⲱ\", 0, 2, 1),FCE(\"ⲱ\", 1, 2, 1),FCE(\"Ḍ\", 0, 2, 1),FCE(\"ḍ\", 1, 2, 1),\nFCE(\"Ḏ\", 0, 2, 1),FCE(\"ḏ\", 1, 2, 1),FCE(\"Ḑ\", 0, 2, 1),FCE(\"ḑ\", 1, 2, 1),\nFCE(\"Ꙙ\", 0, 2, 1),FCE(\"ꙙ\", 1, 2, 1),FCE(\"Ḓ\", 0, 2, 1),FCE(\"ḓ\", 1, 2, 1),\nFCE(\"Ḕ\", 0, 2, 1),FCE(\"ḕ\", 1, 2, 1),FCE(\"Ⓧ\", 0, 2, 1),FCE(\"ⓧ\", 1, 2, 1),\nFCE(\"Ḗ\", 0, 2, 1),FCE(\"ḗ\", 1, 2, 1),FCE(\"Ḙ\", 0, 2, 1),FCE(\"ḙ\", 1, 2, 1),\nFCE(\"Ḛ\", 0, 2, 1),FCE(\"ḛ\", 1, 2, 1),FCE(\"Ḝ\", 0, 2, 1),FCE(\"ḝ\", 1, 2, 1),\nFCE(\"Ꙛ\", 0, 2, 1),FCE(\"ꙛ\", 1, 2, 1),FCE(\"Ḟ\", 0, 2, 1),FCE(\"ḟ\", 1, 2, 1),\nFCE(\"Ḡ\", 0, 2, 1),FCE(\"ḡ\", 1, 2, 1),FCE(\"Ḣ\", 0, 2, 1),FCE(\"ḣ\", 1, 2, 1),\nFCE(\"Ḥ\", 0, 2, 1),FCE(\"ḥ\", 1, 2, 1),FCE(\"Ḧ\", 0, 2, 1),FCE(\"ḧ\", 1, 2, 1),\nFCE(\"Ḩ\", 0, 2, 1),FCE(\"ḩ\", 1, 2, 1),FCE(\"Ꙝ\", 0, 2, 1),FCE(\"ꙝ\", 1, 2, 1),\nFCE(\"Ḫ\", 0, 2, 1),FCE(\"ḫ\", 1, 2, 1),FCE(\"Ḭ\", 0, 2, 1),FCE(\"ḭ\", 1, 2, 1),\nFCE(\"Ḯ\", 0, 2, 1),FCE(\"ḯ\", 1, 2, 1),FCE(\"Ḱ\", 0, 2, 1),FCE(\"ḱ\", 1, 2, 1),\nFCE(\"Ḳ\", 0, 2, 1),FCE(\"ḳ\", 1, 2, 1),FCE(\"Ḵ\", 0, 2, 1),FCE(\"ḵ\", 1, 2, 1),\nFCE(\"Ꙟ\", 0, 2, 1),FCE(\"ꙟ\", 1, 2, 1),FCE(\"Ḷ\", 0, 2, 1),FCE(\"ḷ\", 1, 2, 1),\nFCE(\"Ḹ\", 0, 2, 1),FCE(\"ḹ\", 1, 2, 1),FCE(\"Ḻ\", 0, 2, 1),FCE(\"ḻ\", 1, 2, 1),\nFCE(\"Ḽ\", 0, 2, 1),FCE(\"ḽ\", 1, 2, 1),FCE(\"Ḿ\", 0, 2, 1),FCE(\"ḿ\", 1, 2, 1),\nFCE(\"Ṁ\", 0, 2, 1),FCE(\"ṁ\", 1, 2, 1),FCE(\"Ꙡ\", 0, 2, 1),FCE(\"ꙡ\", 1, 2, 1),\nFCE(\"Ṃ\", 0, 2, 1),FCE(\"ṃ\", 1, 2, 1),FCE(\"Ṅ\", 0, 2, 1),FCE(\"ṅ\", 1, 2, 1),\nFCE(\"Ṇ\", 0, 2, 1),FCE(\"ṇ\", 1, 2, 1),FCE(\"Ⲳ\", 0, 2, 1),FCE(\"ⲳ\", 1, 2, 1),\nFCE(\"Ṉ\", 0, 2, 1),FCE(\"ṉ\", 1, 2, 1),FCE(\"Ⳁ\", 0, 2, 1),FCE(\"ⳁ\", 1, 2, 1),\nFCE(\"Ṋ\", 0, 2, 1),FCE(\"ṋ\", 1, 2, 1),FCE(\"Ṍ\", 0, 2, 1),FCE(\"ṍ\", 1, 2, 1),\nFCE(\"Ꙣ\", 0, 2, 1),FCE(\"ꙣ\", 1, 2, 1),FCE(\"Ṏ\", 0, 2, 1),FCE(\"ṏ\", 1, 2, 1),\nFCE(\"Ṑ\", 0, 2, 1),FCE(\"ṑ\", 1, 2, 1),FCE(\"Ṓ\", 0, 2, 1),FCE(\"ṓ\", 1, 2, 1),\nFCE(\"Ṕ\", 0, 2, 1),FCE(\"ṕ\", 1, 2, 1),FCE(\"Ṗ\", 0, 2, 1),FCE(\"ṗ\", 1, 2, 1),\nFCE(\"Ṙ\", 0, 2, 1),FCE(\"ṙ\", 1, 2, 1),FCE(\"Ꙥ\", 0, 2, 1),FCE(\"ꙥ\", 1, 2, 1),\nFCE(\"Ṛ\", 0, 2, 1),FCE(\"ṛ\", 1, 2, 1),FCE(\"Ṝ\", 0, 2, 1),FCE(\"ṝ\", 1, 2, 1),\nFCE(\"Ṟ\", 0, 2, 1),FCE(\"ṟ\", 1, 2, 1),FCE(\"Ṡ\", 0, 3, 1),FCE(\"ṡ\", 1, 3, 1),\nFCE(\"ẛ\", 2, 3, 1),FCE(\"Ṣ\", 0, 2, 1),FCE(\"ṣ\", 1, 2, 1),FCE(\"𐐤\", 0, 2, 1),\nFCE(\"𐑌\", 1, 2, 1),FCE(\"Ṥ\", 0, 2, 1),FCE(\"ṥ\", 1, 2, 1),FCE(\"Ꙧ\", 0, 2, 1),\nFCE(\"ꙧ\", 1, 2, 1),FCE(\"Ṧ\", 0, 2, 1),FCE(\"ṧ\", 1, 2, 1),FCE(\"Ṩ\", 0, 2, 1),\nFCE(\"ṩ\", 1, 2, 1),FCE(\"Ṫ\", 0, 2, 1),FCE(\"ṫ\", 1, 2, 1),FCE(\"Ṭ\", 0, 2, 1),\nFCE(\"ṭ\", 1, 2, 1),FCE(\"Ṯ\", 0, 2, 1),FCE(\"ṯ\", 1, 2, 1),FCE(\"Ṱ\", 0, 2, 1),\nFCE(\"ṱ\", 1, 2, 1),FCE(\"Ꙩ\", 0, 2, 1),FCE(\"ꙩ\", 1, 2, 1),FCE(\"Ṳ\", 0, 2, 1),\nFCE(\"ṳ\", 1, 2, 1),FCE(\"Ṵ\", 0, 2, 1),FCE(\"ṵ\", 1, 2, 1),FCE(\"Ṷ\", 0, 2, 1),\nFCE(\"ṷ\", 1, 2, 1),FCE(\"Ⲿ\", 0, 2, 1),FCE(\"ⲿ\", 1, 2, 1),FCE(\"Ṹ\", 0, 2, 1),\nFCE(\"ṹ\", 1, 2, 1),FCE(\"Ṻ\", 0, 2, 1),FCE(\"ṻ\", 1, 2, 1),FCE(\"Ṽ\", 0, 2, 1),\nFCE(\"ṽ\", 1, 2, 1),FCE(\"Ꙫ\", 0, 2, 1),FCE(\"ꙫ\", 1, 2, 1),FCE(\"Ṿ\", 0, 2, 1),\nFCE(\"ṿ\", 1, 2, 1),FCE(\"Ẁ\", 0, 2, 1),FCE(\"ẁ\", 1, 2, 1),FCE(\"Ẃ\", 0, 2, 1),\nFCE(\"ẃ\", 1, 2, 1),FCE(\"Ẅ\", 0, 2, 1),FCE(\"ẅ\", 1, 2, 1),FCE(\"Ẇ\", 0, 2, 1),\nFCE(\"ẇ\", 1, 2, 1),FCE(\"Ẉ\", 0, 2, 1),FCE(\"ẉ\", 1, 2, 1),FCE(\"Ꙭ\", 0, 2, 1),\nFCE(\"ꙭ\", 1, 2, 1),FCE(\"Ẋ\", 0, 2, 1),FCE(\"ẋ\", 1, 2, 1),FCE(\"Ẍ\", 0, 2, 1),\nFCE(\"ẍ\", 1, 2, 1),FCE(\"Ẏ\", 0, 2, 1),FCE(\"ẏ\", 1, 2, 1),FCE(\"Ẑ\", 0, 2, 1),\nFCE(\"ẑ\", 1, 2, 1),FCE(\"Ẓ\", 0, 2, 1),FCE(\"ẓ\", 1, 2, 1),FCE(\"Ẕ\", 0, 2, 1),\nFCE(\"ẕ\", 1, 2, 1),FCE(\"ẖ\", 0, 2, 1),FCE(\"ẖ\", 1, 2, 2),FCE(\"ẗ\", 0, 2, 1),\nFCE(\"ẗ\", 1, 2, 2),FCE(\"ẘ\", 0, 2, 1),FCE(\"ẘ\", 1, 2, 2),FCE(\"ẙ\", 0, 2, 1),\nFCE(\"ẙ\", 1, 2, 2),FCE(\"ẚ\", 0, 2, 1),FCE(\"aʾ\", 1, 2, 2),FCE(\"Ṡ\", 0, 3, 1),\nFCE(\"ṡ\", 1, 3, 1),FCE(\"ẛ\", 2, 3, 1),FCE(\"ß\", 0, 3, 1),FCE(\"ẞ\", 1, 3, 1),\nFCE(\"ss\", 2, 3, 2),FCE(\"Ạ\", 0, 2, 1),FCE(\"ạ\", 1, 2, 1),FCE(\"Ả\", 0, 2, 1),\nFCE(\"ả\", 1, 2, 1),FCE(\"Ấ\", 0, 2, 1),FCE(\"ấ\", 1, 2, 1),FCE(\"Ⓟ\", 0, 2, 1),\nFCE(\"ⓟ\", 1, 2, 1),FCE(\"Ầ\", 0, 2, 1),FCE(\"ầ\", 1, 2, 1),FCE(\"Ẩ\", 0, 2, 1),\nFCE(\"ẩ\", 1, 2, 1),FCE(\"Ẫ\", 0, 2, 1),FCE(\"ẫ\", 1, 2, 1),FCE(\"Ậ\", 0, 2, 1),\nFCE(\"ậ\", 1, 2, 1),FCE(\"Ắ\", 0, 2, 1),FCE(\"ắ\", 1, 2, 1),FCE(\"Ｈ\", 0, 2, 1),\nFCE(\"ｈ\", 1, 2, 1),FCE(\"Ằ\", 0, 2, 1),FCE(\"ằ\", 1, 2, 1),FCE(\"Ẳ\", 0, 2, 1),\nFCE(\"ẳ\", 1, 2, 1),FCE(\"𐐥\", 0, 2, 1),FCE(\"𐑍\", 1, 2, 1),FCE(\"Ẵ\", 0, 2, 1),\nFCE(\"ẵ\", 1, 2, 1),FCE(\"Ặ\", 0, 2, 1),FCE(\"ặ\", 1, 2, 1),FCE(\"Ẹ\", 0, 2, 1),\nFCE(\"ẹ\", 1, 2, 1),FCE(\"Ẻ\", 0, 2, 1),FCE(\"ẻ\", 1, 2, 1),FCE(\"Ẽ\", 0, 2, 1),\nFCE(\"ẽ\", 1, 2, 1),FCE(\"Ế\", 0, 2, 1),FCE(\"ế\", 1, 2, 1),FCE(\"Ⲷ\", 0, 2, 1),\nFCE(\"ⲷ\", 1, 2, 1),FCE(\"Ề\", 0, 2, 1),FCE(\"ề\", 1, 2, 1),FCE(\"Ể\", 0, 2, 1),\nFCE(\"ể\", 1, 2, 1),FCE(\"Ⲛ\", 0, 2, 1),FCE(\"ⲛ\", 1, 2, 1),FCE(\"Ễ\", 0, 2, 1),\nFCE(\"ễ\", 1, 2, 1),FCE(\"Ệ\", 0, 2, 1),FCE(\"ệ\", 1, 2, 1),FCE(\"Ỉ\", 0, 2, 1),\nFCE(\"ỉ\", 1, 2, 1),FCE(\"Ị\", 0, 2, 1),FCE(\"ị\", 1, 2, 1),FCE(\"Ọ\", 0, 2, 1),\nFCE(\"ọ\", 1, 2, 1),FCE(\"Ỏ\", 0, 2, 1),FCE(\"ỏ\", 1, 2, 1),FCE(\"Ố\", 0, 2, 1),\nFCE(\"ố\", 1, 2, 1),FCE(\"Ồ\", 0, 2, 1),FCE(\"ồ\", 1, 2, 1),FCE(\"Ổ\", 0, 2, 1),\nFCE(\"ổ\", 1, 2, 1),FCE(\"Ỗ\", 0, 2, 1),FCE(\"ỗ\", 1, 2, 1),FCE(\"Ộ\", 0, 2, 1),\nFCE(\"ộ\", 1, 2, 1),FCE(\"Ớ\", 0, 2, 1),FCE(\"ớ\", 1, 2, 1),FCE(\"Ờ\", 0, 2, 1),\nFCE(\"ờ\", 1, 2, 1),FCE(\"Ở\", 0, 2, 1),FCE(\"ở\", 1, 2, 1),FCE(\"Ỡ\", 0, 2, 1),\nFCE(\"ỡ\", 1, 2, 1),FCE(\"Ợ\", 0, 2, 1),FCE(\"ợ\", 1, 2, 1),FCE(\"Ụ\", 0, 2, 1),\nFCE(\"ụ\", 1, 2, 1),FCE(\"Ω\", 0, 3, 1),FCE(\"ω\", 1, 3, 1),FCE(\"Ω\", 2, 3, 1),\nFCE(\"Ủ\", 0, 2, 1),FCE(\"ủ\", 1, 2, 1),FCE(\"Ứ\", 0, 2, 1),FCE(\"ứ\", 1, 2, 1),\nFCE(\"Ừ\", 0, 2, 1),FCE(\"ừ\", 1, 2, 1),FCE(\"Ｊ\", 0, 2, 1),FCE(\"ｊ\", 1, 2, 1),\nFCE(\"Ử\", 0, 2, 1),FCE(\"ử\", 1, 2, 1),FCE(\"Ữ\", 0, 2, 1),FCE(\"ữ\", 1, 2, 1),\nFCE(\"Ự\", 0, 2, 1),FCE(\"ự\", 1, 2, 1),FCE(\"Ỳ\", 0, 2, 1),FCE(\"ỳ\", 1, 2, 1),\nFCE(\"Ỵ\", 0, 2, 1),FCE(\"ỵ\", 1, 2, 1),FCE(\"Ỷ\", 0, 2, 1),FCE(\"ỷ\", 1, 2, 1),\nFCE(\"Ỹ\", 0, 2, 1),FCE(\"ỹ\", 1, 2, 1),FCE(\"Ỻ\", 0, 2, 1),FCE(\"ỻ\", 1, 2, 1),\nFCE(\"Ⲹ\", 0, 2, 1),FCE(\"ⲹ\", 1, 2, 1),FCE(\"Ỽ\", 0, 2, 1),FCE(\"ỽ\", 1, 2, 1),\nFCE(\"K\", 0, 3, 1),FCE(\"k\", 1, 3, 1),FCE(\"K\", 2, 3, 1),FCE(\"Ỿ\", 0, 2, 1),\nFCE(\"ỿ\", 1, 2, 1),FCE(\"Ꚁ\", 0, 2, 1),FCE(\"ꚁ\", 1, 2, 1),FCE(\"ἀ\", 0, 2, 1),\nFCE(\"Ἀ\", 1, 2, 1),FCE(\"ἁ\", 0, 2, 1),FCE(\"Ἁ\", 1, 2, 1),FCE(\"ἂ\", 0, 2, 1),\nFCE(\"Ἂ\", 1, 2, 1),FCE(\"ἃ\", 0, 2, 1),FCE(\"Ἃ\", 1, 2, 1),FCE(\"ἄ\", 0, 2, 1),\nFCE(\"Ἄ\", 1, 2, 1),FCE(\"ἅ\", 0, 2, 1),FCE(\"Ἅ\", 1, 2, 1),FCE(\"ἆ\", 0, 2, 1),\nFCE(\"Ἆ\", 1, 2, 1),FCE(\"ἇ\", 0, 2, 1),FCE(\"Ἇ\", 1, 2, 1),FCE(\"𐐘\", 0, 2, 1),\nFCE(\"𐑀\", 1, 2, 1),FCE(\"ɥ\", 0, 2, 1),FCE(\"Ɥ\", 1, 2, 1),FCE(\"ἐ\", 0, 2, 1),\nFCE(\"Ἐ\", 1, 2, 1),FCE(\"ἑ\", 0, 2, 1),FCE(\"Ἑ\", 1, 2, 1),FCE(\"ἒ\", 0, 2, 1),\nFCE(\"Ἒ\", 1, 2, 1),FCE(\"ἓ\", 0, 2, 1),FCE(\"Ἓ\", 1, 2, 1),FCE(\"ἔ\", 0, 2, 1),\nFCE(\"Ἔ\", 1, 2, 1),FCE(\"ἕ\", 0, 2, 1),FCE(\"Ἕ\", 1, 2, 1),FCE(\"Ａ\", 0, 2, 1),\nFCE(\"ａ\", 1, 2, 1),FCE(\"Ꜣ\", 0, 2, 1),FCE(\"ꜣ\", 1, 2, 1),FCE(\"Ｃ\", 0, 2, 1),\nFCE(\"ｃ\", 1, 2, 1),FCE(\"Ꜥ\", 0, 2, 1),FCE(\"ꜥ\", 1, 2, 1),FCE(\"Ꚇ\", 0, 2, 1),\nFCE(\"ꚇ\", 1, 2, 1),FCE(\"Ꜧ\", 0, 2, 1),FCE(\"ꜧ\", 1, 2, 1),FCE(\"Ｇ\", 0, 2, 1),\nFCE(\"ｇ\", 1, 2, 1),FCE(\"ἠ\", 0, 2, 1),FCE(\"Ἠ\", 1, 2, 1),FCE(\"ἡ\", 0, 2, 1),\nFCE(\"Ἡ\", 1, 2, 1),FCE(\"ἢ\", 0, 2, 1),FCE(\"Ἢ\", 1, 2, 1),FCE(\"ἣ\", 0, 2, 1),\nFCE(\"Ἣ\", 1, 2, 1),FCE(\"ἤ\", 0, 2, 1),FCE(\"Ἤ\", 1, 2, 1),FCE(\"ἥ\", 0, 2, 1),\nFCE(\"Ἥ\", 1, 2, 1),FCE(\"ἦ\", 0, 2, 1),FCE(\"Ἦ\", 1, 2, 1),FCE(\"ἧ\", 0, 2, 1),\nFCE(\"Ἧ\", 1, 2, 1),FCE(\"Ｐ\", 0, 2, 1),FCE(\"ｐ\", 1, 2, 1),FCE(\"Ꚉ\", 0, 2, 1),\nFCE(\"ꚉ\", 1, 2, 1),FCE(\"Ꜳ\", 0, 2, 1),FCE(\"ꜳ\", 1, 2, 1),FCE(\"Ｓ\", 0, 2, 1),\nFCE(\"ｓ\", 1, 2, 1),FCE(\"Ꜵ\", 0, 2, 1),FCE(\"ꜵ\", 1, 2, 1),FCE(\"Ｕ\", 0, 2, 1),\nFCE(\"ｕ\", 1, 2, 1),FCE(\"Ꜷ\", 0, 2, 1),FCE(\"ꜷ\", 1, 2, 1),FCE(\"Ⲻ\", 0, 2, 1),\nFCE(\"ⲻ\", 1, 2, 1),FCE(\"ἰ\", 0, 2, 1),FCE(\"Ἰ\", 1, 2, 1),FCE(\"ἱ\", 0, 2, 1),\nFCE(\"Ἱ\", 1, 2, 1),FCE(\"ἲ\", 0, 2, 1),FCE(\"Ἲ\", 1, 2, 1),FCE(\"ἳ\", 0, 2, 1),\nFCE(\"Ἳ\", 1, 2, 1),FCE(\"ἴ\", 0, 2, 1),FCE(\"Ἴ\", 1, 2, 1),FCE(\"ἵ\", 0, 2, 1),\nFCE(\"Ἵ\", 1, 2, 1),FCE(\"ἶ\", 0, 2, 1),FCE(\"Ἶ\", 1, 2, 1),FCE(\"ἷ\", 0, 2, 1),\nFCE(\"Ἷ\", 1, 2, 1),FCE(\"Ꝁ\", 0, 2, 1),FCE(\"ꝁ\", 1, 2, 1),FCE(\"Ꝃ\", 0, 2, 1),\nFCE(\"ꝃ\", 1, 2, 1),FCE(\"Ꝅ\", 0, 2, 1),FCE(\"ꝅ\", 1, 2, 1),FCE(\"Ꝇ\", 0, 2, 1),\nFCE(\"ꝇ\", 1, 2, 1),FCE(\"ὀ\", 0, 2, 1),FCE(\"Ὀ\", 1, 2, 1),FCE(\"ὁ\", 0, 2, 1),\nFCE(\"Ὁ\", 1, 2, 1),FCE(\"ὂ\", 0, 2, 1),FCE(\"Ὂ\", 1, 2, 1),FCE(\"ὃ\", 0, 2, 1),\nFCE(\"Ὃ\", 1, 2, 1),FCE(\"ὄ\", 0, 2, 1),FCE(\"Ὄ\", 1, 2, 1),FCE(\"ὅ\", 0, 2, 1),\nFCE(\"Ὅ\", 1, 2, 1),FCE(\"Ꝏ\", 0, 2, 1),FCE(\"ꝏ\", 1, 2, 1),FCE(\"ὐ\", 0, 2, 1),\nFCE(\"ὐ\", 1, 2, 2),FCE(\"ὒ\", 0, 2, 1),FCE(\"ὒ\", 1, 2, 3),FCE(\"ὔ\", 0, 2, 1),\nFCE(\"ὔ\", 1, 2, 3),FCE(\"Ꚏ\", 0, 2, 1),FCE(\"ꚏ\", 1, 2, 1),FCE(\"ὖ\", 0, 2, 1),\nFCE(\"ὖ\", 1, 2, 3),FCE(\"Ꝙ\", 0, 2, 1),FCE(\"ꝙ\", 1, 2, 1),FCE(\"ὑ\", 0, 2, 1),\nFCE(\"Ὑ\", 1, 2, 1),FCE(\"Ꝛ\", 0, 2, 1),FCE(\"ꝛ\", 1, 2, 1),FCE(\"ὓ\", 0, 2, 1),\nFCE(\"Ὓ\", 1, 2, 1),FCE(\"Ꝝ\", 0, 2, 1),FCE(\"ꝝ\", 1, 2, 1),FCE(\"ὕ\", 0, 2, 1),\nFCE(\"Ὕ\", 1, 2, 1),FCE(\"Ꝟ\", 0, 2, 1),FCE(\"ꝟ\", 1, 2, 1),FCE(\"ὗ\", 0, 2, 1),\nFCE(\"Ὗ\", 1, 2, 1),FCE(\"Ꝡ\", 0, 2, 1),FCE(\"ꝡ\", 1, 2, 1),FCE(\"Ꚑ\", 0, 2, 1),\nFCE(\"ꚑ\", 1, 2, 1),FCE(\"Ꝣ\", 0, 2, 1),FCE(\"ꝣ\", 1, 2, 1),FCE(\"Ｎ\", 0, 2, 1),\nFCE(\"ｎ\", 1, 2, 1),FCE(\"Ꝥ\", 0, 2, 1),FCE(\"ꝥ\", 1, 2, 1),FCE(\"Ꝧ\", 0, 2, 1),\nFCE(\"ꝧ\", 1, 2, 1),FCE(\"ὠ\", 0, 2, 1),FCE(\"Ὠ\", 1, 2, 1),FCE(\"ὡ\", 0, 2, 1),\nFCE(\"Ὡ\", 1, 2, 1),FCE(\"ὢ\", 0, 2, 1),FCE(\"Ὢ\", 1, 2, 1),FCE(\"ὣ\", 0, 2, 1),\nFCE(\"Ὣ\", 1, 2, 1),FCE(\"ὤ\", 0, 2, 1),FCE(\"Ὤ\", 1, 2, 1),FCE(\"ὥ\", 0, 2, 1),\nFCE(\"Ὥ\", 1, 2, 1),FCE(\"ὦ\", 0, 2, 1),FCE(\"Ὦ\", 1, 2, 1),FCE(\"ὧ\", 0, 2, 1),\nFCE(\"Ὧ\", 1, 2, 1),FCE(\"Ⱌ\", 0, 2, 1),FCE(\"ⱌ\", 1, 2, 1),FCE(\"Ⲽ\", 0, 2, 1),\nFCE(\"ⲽ\", 1, 2, 1),FCE(\"Ꚕ\", 0, 2, 1),FCE(\"ꚕ\", 1, 2, 1),FCE(\"Ꝼ\", 0, 2, 1),\nFCE(\"ꝼ\", 1, 2, 1),FCE(\"ᵹ\", 0, 2, 1),FCE(\"Ᵹ\", 1, 2, 1),FCE(\"Ꝿ\", 0, 2, 1),\nFCE(\"ꝿ\", 1, 2, 1),FCE(\"ᾀ\", 0, 3, 1),FCE(\"ᾈ\", 1, 3, 1),FCE(\"ἀι\", 2, 3, 2),\nFCE(\"ᾁ\", 0, 3, 1),FCE(\"ᾉ\", 1, 3, 1),FCE(\"ἁι\", 2, 3, 2),FCE(\"ᾂ\", 0, 3, 1),\nFCE(\"ᾊ\", 1, 3, 1),FCE(\"ἂι\", 2, 3, 2),FCE(\"ᾃ\", 0, 3, 1),FCE(\"ᾋ\", 1, 3, 1),\nFCE(\"ἃι\", 2, 3, 2),FCE(\"ᾄ\", 0, 3, 1),FCE(\"ᾌ\", 1, 3, 1),FCE(\"ἄι\", 2, 3, 2),\nFCE(\"ᾅ\", 0, 3, 1),FCE(\"ᾍ\", 1, 3, 1),FCE(\"ἅι\", 2, 3, 2),FCE(\"ᾆ\", 0, 3, 1),\nFCE(\"ᾎ\", 1, 3, 1),FCE(\"ἆι\", 2, 3, 2),FCE(\"ᾇ\", 0, 3, 1),FCE(\"ᾏ\", 1, 3, 1),\nFCE(\"ἇι\", 2, 3, 2),FCE(\"ᾀ\", 0, 3, 1),FCE(\"ᾈ\", 1, 3, 1),FCE(\"ἀι\", 2, 3, 2),\nFCE(\"ᾁ\", 0, 3, 1),FCE(\"ᾉ\", 1, 3, 1),FCE(\"ἁι\", 2, 3, 2),FCE(\"ᾂ\", 0, 3, 1),\nFCE(\"ᾊ\", 1, 3, 1),FCE(\"ἂι\", 2, 3, 2),FCE(\"ᾃ\", 0, 3, 1),FCE(\"ᾋ\", 1, 3, 1),\nFCE(\"ἃι\", 2, 3, 2),FCE(\"ᾄ\", 0, 3, 1),FCE(\"ᾌ\", 1, 3, 1),FCE(\"ἄι\", 2, 3, 2),\nFCE(\"ᾅ\", 0, 3, 1),FCE(\"ᾍ\", 1, 3, 1),FCE(\"ἅι\", 2, 3, 2),FCE(\"ᾆ\", 0, 3, 1),\nFCE(\"ᾎ\", 1, 3, 1),FCE(\"ἆι\", 2, 3, 2),FCE(\"ᾇ\", 0, 3, 1),FCE(\"ᾏ\", 1, 3, 1),\nFCE(\"ἇι\", 2, 3, 2),FCE(\"ᾐ\", 0, 3, 1),FCE(\"ᾘ\", 1, 3, 1),FCE(\"ἠι\", 2, 3, 2),\nFCE(\"ᾑ\", 0, 3, 1),FCE(\"ᾙ\", 1, 3, 1),FCE(\"ἡι\", 2, 3, 2),FCE(\"ᾒ\", 0, 3, 1),\nFCE(\"ᾚ\", 1, 3, 1),FCE(\"ἢι\", 2, 3, 2),FCE(\"ᾓ\", 0, 3, 1),FCE(\"ᾛ\", 1, 3, 1),\nFCE(\"ἣι\", 2, 3, 2),FCE(\"ᾔ\", 0, 3, 1),FCE(\"ᾜ\", 1, 3, 1),FCE(\"ἤι\", 2, 3, 2),\nFCE(\"ᾕ\", 0, 3, 1),FCE(\"ᾝ\", 1, 3, 1),FCE(\"ἥι\", 2, 3, 2),FCE(\"ᾖ\", 0, 3, 1),\nFCE(\"ᾞ\", 1, 3, 1),FCE(\"ἦι\", 2, 3, 2),FCE(\"ᾗ\", 0, 3, 1),FCE(\"ᾟ\", 1, 3, 1),\nFCE(\"ἧι\", 2, 3, 2),FCE(\"ᾐ\", 0, 3, 1),FCE(\"ᾘ\", 1, 3, 1),FCE(\"ἠι\", 2, 3, 2),\nFCE(\"ᾑ\", 0, 3, 1),FCE(\"ᾙ\", 1, 3, 1),FCE(\"ἡι\", 2, 3, 2),FCE(\"ᾒ\", 0, 3, 1),\nFCE(\"ᾚ\", 1, 3, 1),FCE(\"ἢι\", 2, 3, 2),FCE(\"ᾓ\", 0, 3, 1),FCE(\"ᾛ\", 1, 3, 1),\nFCE(\"ἣι\", 2, 3, 2),FCE(\"ᾔ\", 0, 3, 1),FCE(\"ᾜ\", 1, 3, 1),FCE(\"ἤι\", 2, 3, 2),\nFCE(\"ᾕ\", 0, 3, 1),FCE(\"ᾝ\", 1, 3, 1),FCE(\"ἥι\", 2, 3, 2),FCE(\"ᾖ\", 0, 3, 1),\nFCE(\"ᾞ\", 1, 3, 1),FCE(\"ἦι\", 2, 3, 2),FCE(\"ᾗ\", 0, 3, 1),FCE(\"ᾟ\", 1, 3, 1),\nFCE(\"ἧι\", 2, 3, 2),FCE(\"ᾠ\", 0, 3, 1),FCE(\"ᾨ\", 1, 3, 1),FCE(\"ὠι\", 2, 3, 2),\nFCE(\"ᾡ\", 0, 3, 1),FCE(\"ᾩ\", 1, 3, 1),FCE(\"ὡι\", 2, 3, 2),FCE(\"ᾢ\", 0, 3, 1),\nFCE(\"ᾪ\", 1, 3, 1),FCE(\"ὢι\", 2, 3, 2),FCE(\"ᾣ\", 0, 3, 1),FCE(\"ᾫ\", 1, 3, 1),\nFCE(\"ὣι\", 2, 3, 2),FCE(\"ᾤ\", 0, 3, 1),FCE(\"ᾬ\", 1, 3, 1),FCE(\"ὤι\", 2, 3, 2),\nFCE(\"ᾥ\", 0, 3, 1),FCE(\"ᾭ\", 1, 3, 1),FCE(\"ὥι\", 2, 3, 2),FCE(\"ᾦ\", 0, 3, 1),\nFCE(\"ᾮ\", 1, 3, 1),FCE(\"ὦι\", 2, 3, 2),FCE(\"ᾧ\", 0, 3, 1),FCE(\"ᾯ\", 1, 3, 1),\nFCE(\"ὧι\", 2, 3, 2),FCE(\"ᾠ\", 0, 3, 1),FCE(\"ᾨ\", 1, 3, 1),FCE(\"ὠι\", 2, 3, 2),\nFCE(\"ᾡ\", 0, 3, 1),FCE(\"ᾩ\", 1, 3, 1),FCE(\"ὡι\", 2, 3, 2),FCE(\"ᾢ\", 0, 3, 1),\nFCE(\"ᾪ\", 1, 3, 1),FCE(\"ὢι\", 2, 3, 2),FCE(\"ᾣ\", 0, 3, 1),FCE(\"ᾫ\", 1, 3, 1),\nFCE(\"ὣι\", 2, 3, 2),FCE(\"ᾤ\", 0, 3, 1),FCE(\"ᾬ\", 1, 3, 1),FCE(\"ὤι\", 2, 3, 2),\nFCE(\"ᾥ\", 0, 3, 1),FCE(\"ᾭ\", 1, 3, 1),FCE(\"ὥι\", 2, 3, 2),FCE(\"ᾦ\", 0, 3, 1),\nFCE(\"ᾮ\", 1, 3, 1),FCE(\"ὦι\", 2, 3, 2),FCE(\"ᾧ\", 0, 3, 1),FCE(\"ᾯ\", 1, 3, 1),\nFCE(\"ὧι\", 2, 3, 2),FCE(\"ᾲ\", 0, 2, 1),FCE(\"ὰι\", 1, 2, 2),FCE(\"ᾳ\", 0, 3, 1),\nFCE(\"ᾼ\", 1, 3, 1),FCE(\"αι\", 2, 3, 2),FCE(\"ᾴ\", 0, 2, 1),FCE(\"άι\", 1, 2, 2),\nFCE(\"ᾶ\", 0, 2, 1),FCE(\"ᾶ\", 1, 2, 2),FCE(\"ᾷ\", 0, 2, 1),FCE(\"ᾶι\", 1, 2, 3),\nFCE(\"ᾰ\", 0, 2, 1),FCE(\"Ᾰ\", 1, 2, 1),FCE(\"ᾱ\", 0, 2, 1),FCE(\"Ᾱ\", 1, 2, 1),\nFCE(\"ὰ\", 0, 2, 1),FCE(\"Ὰ\", 1, 2, 1),FCE(\"ά\", 0, 2, 1),FCE(\"Ά\", 1, 2, 1),\nFCE(\"ᾳ\", 0, 3, 1),FCE(\"ᾼ\", 1, 3, 1),FCE(\"αι\", 2, 3, 2),FCE(\"ͅ\", 0, 4, 1),\nFCE(\"Ι\", 1, 4, 1),FCE(\"ι\", 2, 4, 1),FCE(\"ι\", 3, 4, 1),FCE(\"ῂ\", 0, 2, 1),\nFCE(\"ὴι\", 1, 2, 2),FCE(\"ῃ\", 0, 3, 1),FCE(\"ῌ\", 1, 3, 1),FCE(\"ηι\", 2, 3, 2),\nFCE(\"ῄ\", 0, 2, 1),FCE(\"ήι\", 1, 2, 2),FCE(\"𐐌\", 0, 2, 1),FCE(\"𐐴\", 1, 2, 1),\nFCE(\"ῆ\", 0, 2, 1),FCE(\"ῆ\", 1, 2, 2),FCE(\"ῇ\", 0, 2, 1),FCE(\"ῆι\", 1, 2, 3),\nFCE(\"ὲ\", 0, 2, 1),FCE(\"Ὲ\", 1, 2, 1),FCE(\"έ\", 0, 2, 1),FCE(\"Έ\", 1, 2, 1),\nFCE(\"ὴ\", 0, 2, 1),FCE(\"Ὴ\", 1, 2, 1),FCE(\"ή\", 0, 2, 1),FCE(\"Ή\", 1, 2, 1),\nFCE(\"ῃ\", 0, 3, 1),FCE(\"ῌ\", 1, 3, 1),FCE(\"ηι\", 2, 3, 2),FCE(\"ῒ\", 0, 2, 1),\nFCE(\"ῒ\", 1, 2, 3),FCE(\"ΐ\", 0, 3, 1),FCE(\"ΐ\", 1, 3, 1),FCE(\"ΐ\", 2, 3, 3),\nFCE(\"ῖ\", 0, 2, 1),FCE(\"ῖ\", 1, 2, 2),FCE(\"ῗ\", 0, 2, 1),FCE(\"ῗ\", 1, 2, 3),\nFCE(\"ῐ\", 0, 2, 1),FCE(\"Ῐ\", 1, 2, 1),FCE(\"ῑ\", 0, 2, 1),FCE(\"Ῑ\", 1, 2, 1),\nFCE(\"ὶ\", 0, 2, 1),FCE(\"Ὶ\", 1, 2, 1),FCE(\"ί\", 0, 2, 1),FCE(\"Ί\", 1, 2, 1),\nFCE(\"𐐧\", 0, 2, 1),FCE(\"𐑏\", 1, 2, 1),FCE(\"ῢ\", 0, 2, 1),FCE(\"ῢ\", 1, 2, 3),\nFCE(\"ΰ\", 0, 3, 1),FCE(\"ΰ\", 1, 3, 1),FCE(\"ΰ\", 2, 3, 3),FCE(\"ῤ\", 0, 2, 1),\nFCE(\"ῤ\", 1, 2, 2),FCE(\"ῦ\", 0, 2, 1),FCE(\"ῦ\", 1, 2, 2),FCE(\"ῧ\", 0, 2, 1),\nFCE(\"ῧ\", 1, 2, 3),FCE(\"ῠ\", 0, 2, 1),FCE(\"Ῠ\", 1, 2, 1),FCE(\"ῡ\", 0, 2, 1),\nFCE(\"Ῡ\", 1, 2, 1),FCE(\"ὺ\", 0, 2, 1),FCE(\"Ὺ\", 1, 2, 1),FCE(\"ύ\", 0, 2, 1),\nFCE(\"Ύ\", 1, 2, 1),FCE(\"ῥ\", 0, 2, 1),FCE(\"Ῥ\", 1, 2, 1),FCE(\"𐐁\", 0, 2, 1),\nFCE(\"𐐩\", 1, 2, 1),FCE(\"ῲ\", 0, 2, 1),FCE(\"ὼι\", 1, 2, 2),FCE(\"ῳ\", 0, 3, 1),\nFCE(\"ῼ\", 1, 3, 1),FCE(\"ωι\", 2, 3, 2),FCE(\"ῴ\", 0, 2, 1),FCE(\"ώι\", 1, 2, 2),\nFCE(\"ῶ\", 0, 2, 1),FCE(\"ῶ\", 1, 2, 2),FCE(\"ῷ\", 0, 2, 1),FCE(\"ῶι\", 1, 2, 3),\nFCE(\"ὸ\", 0, 2, 1),FCE(\"Ὸ\", 1, 2, 1),FCE(\"ό\", 0, 2, 1),FCE(\"Ό\", 1, 2, 1),\nFCE(\"ὼ\", 0, 2, 1),FCE(\"Ὼ\", 1, 2, 1),FCE(\"ώ\", 0, 2, 1),FCE(\"Ώ\", 1, 2, 1),\nFCE(\"ῳ\", 0, 3, 1),FCE(\"ῼ\", 1, 3, 1),FCE(\"ωι\", 2, 3, 2),FCE(\"Ⓚ\", 0, 2, 1),\nFCE(\"ⓚ\", 1, 2, 1),];\nreturn t;\n}\n\nstruct uniProps\n{\nprivate alias _U = immutable(UnicodeProperty);\n@property static _U[] tab() pure { return _tab; }\nstatic immutable:\nprivate alias _T = ubyte[];\n_T So = [0x80, 0xa6, 0x1, 0x2, 0x1, 0x4, 0x1, 0x1, 0x1, 0x83, 0xd1, 0x1, 0x81,\n    0x8b, 0x2, 0x80, 0xce, 0x1, 0xa, 0x1, 0x13, 0x2, 0x80, 0xf7, 0x1, 0x82,\n    0x3, 0x1, 0x81, 0x75, 0x1, 0x80, 0x82, 0x6, 0x1, 0x1, 0x80, 0x84, 0x1,\n    0x80, 0xf9, 0x1, 0x81, 0x87, 0x3, 0xf, 0x1, 0x1, 0x3, 0x2, 0x6, 0x14, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x80, 0x85, 0x8, 0x1, 0x6, 0x1, 0x2, 0x5, 0x4, 0x80,\n    0xc5, 0x2, 0x82, 0xf0, 0xa, 0x85, 0xa6, 0x1, 0x80, 0x9d, 0x22, 0x81,\n    0x61, 0xa, 0x9, 0x9, 0x85, 0x83, 0x2, 0x1, 0x4, 0x1, 0x2, 0xa, 0x1, 0x1,\n    0x2, 0x6, 0x6, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x1, 0xb, 0x2, 0xe, 0x1,\n    0x1, 0x2, 0x1, 0x1, 0x45, 0x5, 0x2, 0x4, 0x1, 0x2, 0x1, 0x2, 0x1, 0x7,\n    0x1, 0x1f, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1f, 0x81, 0xc, 0x8, 0x4, 0x14, 0x2,\n    0x7, 0x2, 0x51, 0x1, 0x1e, 0x19, 0x28, 0x6, 0x12, 0xc, 0x27, 0x19, 0xb,\n    0x51, 0x4e, 0x16, 0x80, 0xb7, 0x1, 0x9, 0x1, 0x36, 0x8, 0x6f, 0x1, 0x80,\n    0x90, 0x1, 0x67, 0x2c, 0x2c, 0x40, 0x81, 0x0, 0x82, 0x0, 0x30, 0x15, 0x2,\n    0x9, 0xa, 0x81, 0x8b, 0x6, 0x81, 0x95, 0x1a, 0x1, 0x59, 0xc, 0x80, 0xd6,\n    0x1a, 0xc, 0x8, 0x1, 0xd, 0x2, 0xc, 0x1, 0x15, 0x2, 0x6, 0x2, 0x81, 0x50,\n    0x2, 0x4, 0xa, 0x20, 0x24, 0x1c, 0x1f, 0xb, 0x1e, 0x8, 0x1, 0xf, 0x20, 0xa,\n    0x27, 0xf, 0x3f, 0x1, 0x81, 0x0, 0x99, 0xc0, 0x40, 0xa0, 0x56, 0x90,\n    0x37, 0x83, 0x61, 0x4, 0xa, 0x2, 0x1, 0x1, 0x82, 0x3d, 0x3, 0xa0, 0x53,\n    0x83, 0x1, 0x81, 0xe6, 0x1, 0x3, 0x1, 0x4, 0x2, 0xd, 0x2, 0x81, 0x39,\n    0x9, 0x39, 0x11, 0x6, 0xc, 0x34, 0x2d, 0xa0, 0xce, 0x3, 0x80, 0xf6, 0xa,\n    0x27, 0x2, 0x3c, 0x5, 0x3, 0x16, 0x2, 0x7, 0x1e, 0x4, 0x30, 0x22, 0x42,\n    0x3, 0x1, 0x80, 0xba, 0x57, 0x9c, 0xa9, 0x2c, 0x4, 0x64, 0xc, 0xf, 0x2,\n    0xe, 0x2, 0xf, 0x1, 0xf, 0x30, 0x1f, 0x1, 0x3c, 0x4, 0x2b, 0x4b, 0x1d,\n    0xd, 0x2b, 0x5, 0x9, 0x7, 0x2, 0x80, 0xae, 0x21, 0xf, 0x6, 0x1, 0x46,\n    0x3, 0x14, 0xc, 0x25, 0x1, 0x5, 0x15, 0x11, 0xf, 0x3f, 0x1, 0x1, 0x1,\n    0x80, 0xb6, 0x1, 0x4, 0x3, 0x3e, 0x2, 0x4, 0xc, 0x18, 0x80, 0x93, 0x46,\n    0x4, 0xb, 0x30, 0x46, 0x3a, 0x74];\n_T Pf = [0x80, 0xbb, 0x1, 0x9f, 0x5d, 0x1, 0x3, 0x1, 0x1c, 0x1, 0x8d, 0xc8,\n    0x1, 0x1, 0x1, 0x4, 0x1, 0x2, 0x1, 0xf, 0x1, 0x3, 0x1];\n_T Bidi_Control = [0x86, 0x1c, 0x1, 0x99, 0xf1, 0x2, 0x1a, 0x5, 0x37, 0x4];\n_T Hex_Digit = [0x30, 0xa, 0x7, 0x6, 0x1a, 0x6, 0xa0, 0xfe, 0xa9, 0xa, 0x7, 0x6, 0x1a,\n    0x6];\n_T Other_Lowercase = [\n    0x80, 0xaa, 0x1, 0xf, 0x1, 0x81, 0xf5, 0x9, 0x7, 0x2, 0x1e, 0x5, 0x60, 0x1,\n    0x34, 0x1, 0x99, 0xb1, 0x3f, 0xd, 0x1, 0x22, 0x25, 0x82, 0xb1, 0x1, 0xd,\n    0x1, 0x10, 0xd, 0x80, 0xd3, 0x10, 0x83, 0x50, 0x1a, 0x87, 0x92, 0x2, 0xa0,\n    0x7a, 0xf2, 0x1, 0x80, 0x87, 0x2\n];\n_T Quotation_Mark = [\n    0x22, 0x1, 0x4, 0x1, 0x80, 0x83, 0x1, 0xf, 0x1, 0x9f, 0x5c, 0x8, 0x19, 0x2,\n    0x8f, 0xd1, 0x4, 0xd, 0x3, 0xa0, 0xce, 0x21, 0x4, 0x80, 0xbd, 0x1, 0x4, 0x1, 0x5a,\n    0x2\n];\n_T XID_Start = [\n    0x41, 0x1a, 0x6, 0x1a, 0x2f, 0x1, 0xa, 0x1, 0x4, 0x1, 0x5, 0x17, 0x1, 0x1f,\n    0x1, 0x81, 0xca, 0x4, 0xc, 0xe, 0x5, 0x7, 0x1, 0x1, 0x1, 0x80, 0x81, 0x5,\n    0x1, 0x2, 0x3, 0x3, 0x8, 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x14, 0x1, 0x53,\n    0x1, 0x80, 0x8b, 0x8, 0x80, 0x9e, 0x9, 0x26, 0x2, 0x1, 0x7, 0x27, 0x48,\n    0x1b, 0x5, 0x3, 0x2d, 0x2b, 0x23, 0x2, 0x1, 0x63, 0x1, 0x1, 0xf, 0x2, 0x7,\n    0x2, 0xa, 0x3, 0x2, 0x1, 0x10, 0x1, 0x1, 0x1e, 0x1d, 0x59, 0xb, 0x1,\n    0x18, 0x21, 0x9, 0x2, 0x4, 0x1, 0x5, 0x16, 0x4, 0x1, 0x9, 0x1, 0x3, 0x1,\n    0x17, 0x19, 0x47, 0x1, 0x1, 0xb, 0x57, 0x36, 0x3, 0x1, 0x12, 0x1, 0x7,\n    0xa, 0xf, 0x7, 0x1, 0x7, 0x5, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1,\n    0x1, 0x3, 0x4, 0x3, 0x1, 0x10, 0x1, 0xd, 0x2, 0x1, 0x3, 0xe, 0x2, 0x13,\n    0x6, 0x4, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1f,\n    0x4, 0x1, 0x1, 0x13, 0x3, 0x10, 0x9, 0x1, 0x3, 0x1, 0x16, 0x1, 0x7, 0x1,\n    0x2, 0x1, 0x5, 0x3, 0x1, 0x12, 0x1, 0xf, 0x2, 0x23, 0x8, 0x2, 0x2, 0x2,\n    0x16, 0x1, 0x7, 0x1, 0x2, 0x1, 0x5, 0x3, 0x1, 0x1e, 0x2, 0x1, 0x3, 0xf,\n    0x1, 0x11, 0x1, 0x1, 0x6, 0x3, 0x3, 0x1, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1,\n    0x2, 0x3, 0x2, 0x3, 0x3, 0x3, 0xc, 0x16, 0x1, 0x34, 0x8, 0x1, 0x3, 0x1,\n    0x17, 0x1, 0xa, 0x1, 0x5, 0x3, 0x1, 0x1a, 0x2, 0x6, 0x2, 0x23, 0x8, 0x1,\n    0x3, 0x1, 0x17, 0x1, 0xa, 0x1, 0x5, 0x3, 0x1, 0x20, 0x1, 0x1, 0x2, 0xf,\n    0x2, 0x12, 0x8, 0x1, 0x3, 0x1, 0x29, 0x2, 0x1, 0x10, 0x1, 0x11, 0x2,\n    0x18, 0x6, 0x5, 0x12, 0x3, 0x18, 0x1, 0x9, 0x1, 0x1, 0x2, 0x7, 0x3a, 0x30,\n    0x1, 0x1, 0xd, 0x7, 0x3a, 0x2, 0x1, 0x1, 0x2, 0x2, 0x1, 0x1, 0x2, 0x1,\n    0x6, 0x4, 0x1, 0x7, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x1, 0x4, 0x1,\n    0x1, 0xa, 0x1, 0x2, 0x5, 0x1, 0x1, 0x15, 0x4, 0x20, 0x1, 0x3f, 0x8, 0x1,\n    0x24, 0x1b, 0x5, 0x73, 0x2b, 0x14, 0x1, 0x10, 0x6, 0x4, 0x4, 0x3, 0x1,\n    0x3, 0x2, 0x7, 0x3, 0x4, 0xd, 0xc, 0x1, 0x11, 0x26, 0x1, 0x1, 0x5, 0x1,\n    0x2, 0x2b, 0x1, 0x81, 0x4d, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2,\n    0x29, 0x1, 0x4, 0x2, 0x21, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2,\n    0xf, 0x1, 0x39, 0x1, 0x4, 0x2, 0x43, 0x25, 0x10, 0x10, 0x55, 0xc, 0x82,\n    0x6c, 0x2, 0x11, 0x1, 0x1a, 0x5, 0x4b, 0x3, 0x3, 0xf, 0xd, 0x1, 0x4, 0xe,\n    0x12, 0xe, 0x12, 0xe, 0xd, 0x1, 0x3, 0xf, 0x34, 0x23, 0x1, 0x4, 0x1,\n    0x43, 0x58, 0x8, 0x29, 0x1, 0x1, 0x5, 0x46, 0xa, 0x1d, 0x33, 0x1e, 0x2,\n    0x5, 0xb, 0x2c, 0x15, 0x7, 0x38, 0x17, 0x9, 0x35, 0x52, 0x1, 0x5d, 0x2f,\n    0x11, 0x7, 0x37, 0x1e, 0xd, 0x2, 0xa, 0x2c, 0x1a, 0x24, 0x29, 0x3, 0xa,\n    0x24, 0x6b, 0x4, 0x1, 0x4, 0x3, 0x2, 0x9, 0x80, 0xc0, 0x40, 0x81, 0x16,\n    0x2, 0x6, 0x2, 0x26, 0x2, 0x6, 0x2, 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1f, 0x2, 0x35, 0x1, 0x7, 0x1, 0x1, 0x3, 0x3, 0x1, 0x7, 0x3, 0x4, 0x2,\n    0x6, 0x4, 0xd, 0x5, 0x3, 0x1, 0x7, 0x74, 0x1, 0xd, 0x1, 0x10, 0xd, 0x65,\n    0x1, 0x4, 0x1, 0x2, 0xa, 0x1, 0x1, 0x2, 0x6, 0x6, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x10, 0x2, 0x4, 0x5, 0x5, 0x4, 0x1, 0x11, 0x29, 0x8a, 0x77, 0x2f,\n    0x1, 0x2f, 0x1, 0x80, 0x85, 0x6, 0x4, 0x3, 0x2, 0xc, 0x26, 0x1, 0x1, 0x5,\n    0x1, 0x2, 0x38, 0x7, 0x1, 0x10, 0x17, 0x9, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1,\n    0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x82, 0x26, 0x3, 0x19, 0x9,\n    0x7, 0x5, 0x2, 0x5, 0x4, 0x56, 0x6, 0x3, 0x1, 0x5a, 0x1, 0x4, 0x5, 0x29,\n    0x3, 0x5e, 0x11, 0x1b, 0x35, 0x10, 0x82, 0x0, 0x99, 0xb6, 0x4a, 0xa0, 0x51,\n    0xcd, 0x33, 0x84, 0x8d, 0x43, 0x2e, 0x2, 0x81, 0xd, 0x3, 0x10, 0xa, 0x2,\n    0x14, 0x2f, 0x10, 0x19, 0x8, 0x50, 0x27, 0x9, 0x2, 0x67, 0x2, 0x4, 0x1,\n    0x4, 0xc, 0xb, 0x4d, 0xa, 0x1, 0x3, 0x1, 0x4, 0x1, 0x17, 0x1d, 0x34, 0xe,\n    0x32, 0x3e, 0x6, 0x3, 0x1, 0xe, 0x1c, 0xa, 0x17, 0x19, 0x1d, 0x7, 0x2f,\n    0x1c, 0x1, 0x30, 0x29, 0x17, 0x3, 0x1, 0x8, 0x14, 0x17, 0x3, 0x1, 0x5,\n    0x30, 0x1, 0x1, 0x3, 0x2, 0x2, 0x5, 0x2, 0x1, 0x1, 0x1, 0x18, 0x3, 0x2,\n    0xb, 0x7, 0x3, 0xc, 0x6, 0x2, 0x6, 0x2, 0x6, 0x9, 0x7, 0x1, 0x7, 0x80,\n    0x91, 0x23, 0x1d, 0xa0, 0x2b, 0xa4, 0xc, 0x17, 0x4, 0x31, 0xa0, 0x21, 0x4,\n    0x81, 0x6e, 0x2, 0x6a, 0x26, 0x7, 0xc, 0x5, 0x5, 0x1, 0x1, 0xa, 0x1, 0xd,\n    0x1, 0x5, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x6c, 0x21, 0x80, 0x8b, 0x6,\n    0x80, 0xda, 0x12, 0x40, 0x2, 0x36, 0x28, 0xa, 0x77, 0x1, 0x1, 0x1, 0x3,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x7e, 0x24, 0x1a, 0x6, 0x1a, 0xb,\n    0x38, 0x2, 0x1f, 0x3, 0x6, 0x2, 0x6, 0x2, 0x6, 0x2, 0x3, 0x23, 0xc, 0x1,\n    0x1a, 0x1, 0x13, 0x1, 0x2, 0x1, 0xf, 0x2, 0xe, 0x22, 0x7b, 0x45, 0x35,\n    0x81, 0xb, 0x1d, 0x3, 0x31, 0x2f, 0x1f, 0x11, 0x1b, 0x35, 0x1e, 0x2, 0x24,\n    0x4, 0x8, 0x1, 0x5, 0x2a, 0x80, 0x9e, 0x83, 0x62, 0x6, 0x2, 0x1, 0x1,\n    0x2c, 0x1, 0x2, 0x3, 0x1, 0x2, 0x17, 0x80, 0xaa, 0x16, 0xa, 0x1a, 0x46,\n    0x38, 0x6, 0x2, 0x40, 0x1, 0xf, 0x4, 0x1, 0x3, 0x1, 0x1b, 0x2c, 0x1d, 0x80,\n    0x83, 0x36, 0xa, 0x16, 0xa, 0x13, 0x80, 0x8d, 0x49, 0x83, 0xba, 0x35, 0x4b,\n    0x2d, 0x20, 0x19, 0x1a, 0x24, 0x5c, 0x30, 0xe, 0x4, 0x84, 0xbb, 0x2b, 0x89,\n    0x55, 0x83, 0x6f, 0x80, 0x91, 0x63, 0x8b, 0x9d, 0x84, 0x2f, 0xa0, 0x33,\n    0xd1, 0x82, 0x39, 0x84, 0xc7, 0x45, 0xb, 0x1, 0x42, 0xd, 0xa0, 0x40, 0x60,\n    0x2, 0xa0, 0x23, 0xfe, 0x55, 0x1, 0x47, 0x1, 0x2, 0x2, 0x1, 0x2, 0x2, 0x2,\n    0x4, 0x1, 0xc, 0x1, 0x1, 0x1, 0x7, 0x1, 0x41, 0x1, 0x4, 0x2, 0x8, 0x1,\n    0x7, 0x1, 0x1c, 0x1, 0x4, 0x1, 0x5, 0x1, 0x1, 0x3, 0x7, 0x1, 0x81, 0x54,\n    0x2, 0x19, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1,\n    0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x8, 0x96, 0x34, 0x4, 0x1,\n    0x1b, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0xa, 0x1, 0x4, 0x1, 0x1, 0x1,\n    0x1, 0x6, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3, 0x1, 0x2, 0x1, 0x1,\n    0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2,\n    0x4, 0x1, 0x7, 0x1, 0x4, 0x1, 0x4, 0x1, 0x1, 0x1, 0xa, 0x1, 0x11, 0x5,\n    0x3, 0x1, 0x5, 0x1, 0x11, 0x91, 0x44, 0xa0, 0xa6, 0xd7, 0x29, 0x90, 0x35,\n    0xb, 0x80, 0xde, 0xa0, 0x3f, 0xe2, 0x82, 0x1e\n];\n_T Terminal_Punctuation = [\n    0x21, 0x1, 0xa, 0x1, 0x1, 0x1, 0xb, 0x2, 0x3, 0x1, 0x83, 0x3e, 0x1, 0x8,\n    0x1, 0x82, 0x1, 0x1, 0x39, 0x1, 0x48, 0x1, 0xe, 0x1, 0x3, 0x1, 0x80,\n    0xb4, 0x1, 0x2b, 0xb, 0x1, 0x1, 0x80, 0xeb, 0x2, 0x36, 0xf, 0x1f, 0x1,\n    0x81, 0x5, 0x2, 0x84, 0xf4, 0x2, 0x80, 0xac, 0x1, 0x4, 0x6, 0x81, 0x37,\n    0x2, 0x83, 0x15, 0x8, 0x83, 0x4, 0x2, 0x7c, 0x3, 0x80, 0xe6, 0x3, 0x3,\n    0x1, 0x27, 0x4, 0x2, 0x2, 0x81, 0x3a, 0x2, 0x81, 0x62, 0x4, 0x80, 0xae,\n    0x2, 0x1, 0x3, 0x80, 0xdb, 0x5, 0x3e, 0x2, 0x83, 0xbc, 0x2, 0x9, 0x3, 0x8d,\n    0xe4, 0x1, 0x81, 0xd2, 0x2, 0xa0, 0x74, 0xfb, 0x2, 0x81, 0xd, 0x3, 0x80,\n    0xe3, 0x5, 0x81, 0x7e, 0x2, 0x56, 0x2, 0x5f, 0x1, 0x80, 0x97, 0x3, 0x80,\n    0x93, 0x3, 0x7f, 0x1, 0x10, 0x2, 0x80, 0xf9, 0x1, 0xa0, 0x52, 0x64, 0x3,\n    0x1, 0x4, 0x80, 0xa9, 0x1, 0xa, 0x1, 0x1, 0x1, 0xb, 0x2, 0x3, 0x1, 0x41,\n    0x1, 0x2, 0x1, 0x84, 0x3a, 0x1, 0x30, 0x1, 0x84, 0x86, 0x1, 0x80, 0xc7,\n    0x1, 0x82, 0x1a, 0x6, 0x85, 0x7, 0x7, 0x70, 0x4, 0x7f, 0x3, 0x80, 0x81, 0x2, 0x92,\n    0xa9, 0x4\n];\n_T Math = [0x2b, 0x1, 0x10, 0x3, 0x1f, 0x1, 0x1d, 0x1, 0x1, 0x1, 0x2d, 0x1,\n    0x4, 0x1, 0x25, 0x1, 0x1f, 0x1, 0x82, 0xd8, 0x3, 0x2, 0x1, 0x1a, 0x2,\n    0x2, 0x3, 0x82, 0xf, 0x3, 0x9a, 0xd, 0x1, 0x1b, 0x3, 0xb, 0x1, 0x3, 0x1,\n    0xd, 0x1, 0xe, 0x4, 0x15, 0x5, 0xb, 0x5, 0x41, 0xd, 0x4, 0x1, 0x3, 0x2,\n    0x4, 0x5, 0x12, 0x1, 0x4, 0x1, 0x2, 0xa, 0x1, 0x1, 0x2, 0x6, 0x6, 0x1,\n    0x3, 0x2, 0x2, 0x2, 0x1, 0x3, 0x1, 0x6, 0x3, 0xe, 0x1, 0x1, 0x44, 0x18,\n    0x1, 0x6, 0x1, 0x2, 0x4, 0x2, 0x4, 0x20, 0x1, 0x1, 0x6, 0x2, 0xe, 0x81,\n    0xc, 0x8, 0x4, 0x14, 0x2, 0x5a, 0x1, 0x1e, 0x1b, 0x1, 0x1, 0x18, 0x1,\n    0xb, 0x7, 0x81, 0xbd, 0x2, 0xc, 0xa, 0x4, 0x6, 0x4, 0x2, 0x2, 0x2, 0x3,\n    0x5, 0xe, 0x1, 0x1, 0x1, 0x2, 0x6, 0xb, 0x8, 0x5, 0x2, 0x39, 0x1, 0x1,\n    0x1, 0x1d, 0x4, 0x9, 0x3, 0x81, 0x50, 0x40, 0x81, 0x0, 0x82, 0x0, 0x30,\n    0x15, 0x2, 0x6, 0xa0, 0xcf, 0xdc, 0x1, 0x83, 0x37, 0x6, 0x1, 0x1, 0x80,\n    0xa2, 0x1, 0x10, 0x3, 0x1d, 0x1, 0x1, 0x1, 0x1d, 0x1, 0x1, 0x1, 0x80,\n    0x83, 0x1, 0x6, 0x4, 0xa0, 0xd4, 0x13, 0x55, 0x1, 0x47, 0x1, 0x2, 0x2,\n    0x1, 0x2, 0x2, 0x2, 0x4, 0x1, 0xc, 0x1, 0x1, 0x1, 0x7, 0x1, 0x41, 0x1,\n    0x4, 0x2, 0x8, 0x1, 0x7, 0x1, 0x1c, 0x1, 0x4, 0x1, 0x5, 0x1, 0x1, 0x3, 0x7,\n    0x1, 0x81, 0x54, 0x2, 0x81, 0x24, 0x2, 0x32, 0x96, 0x0, 0x4, 0x1, 0x1b,\n    0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0xa, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x6,\n    0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x4, 0x1,\n    0x7, 0x1, 0x4, 0x1, 0x4, 0x1, 0x1, 0x1, 0xa, 0x1, 0x11, 0x5, 0x3, 0x1, 0x5,\n    0x1, 0x11, 0x34, 0x2];\n_T Lu = [0x41, 0x1a, 0x65, 0x17, 0x1, 0x7, 0x21, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x3, 0x2, 0x1,\n    0x1, 0x1, 0x2, 0x1, 0x3, 0x2, 0x4, 0x1, 0x2, 0x1, 0x3, 0x3, 0x2, 0x1, 0x2,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x3, 0x1,\n    0x1, 0x1, 0x2, 0x3, 0x1, 0x7, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x2, 0x1, 0x2, 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x7, 0x2, 0x1, 0x2, 0x2, 0x1, 0x1, 0x4, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x81, 0x21, 0x1, 0x1, 0x1, 0x3, 0x1, 0xf, 0x1,\n    0x1, 0x3, 0x1, 0x1, 0x1, 0x2, 0x1, 0x11, 0x1, 0x9, 0x23, 0x1, 0x2, 0x3,\n    0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x5, 0x1, 0x2, 0x1, 0x1,\n    0x2, 0x2, 0x33, 0x30, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x9, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0xa,\n    0x26, 0x8b, 0x49, 0x26, 0x1, 0x1, 0x5, 0x1, 0x8d, 0x32, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x9, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x9, 0x8, 0x8, 0x6, 0xa, 0x8, 0x8, 0x8, 0x8, 0x6, 0xb,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x8, 0x8, 0x48, 0x4, 0xc, 0x4, 0xc,\n    0x4, 0xc, 0x5, 0xb, 0x4, 0x81, 0x6, 0x1, 0x4, 0x1, 0x3, 0x3, 0x2, 0x3,\n    0x2, 0x1, 0x3, 0x5, 0x6, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x2, 0x4,\n    0xa, 0x2, 0x5, 0x1, 0x3d, 0x1, 0x8a, 0x7c, 0x2f, 0x31, 0x1, 0x1, 0x3, 0x2,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x1, 0x1, 0x2, 0x1, 0x8, 0x3, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x8, 0x1, 0x1, 0x1, 0x4, 0x1, 0xa0, 0x79,\n    0x4d, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x13, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x80,\n    0x8b, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0xa, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x4, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0xd, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0xa0, 0x57, 0x76, 0x1a, 0x84, 0xc5, 0x28,\n    0xa0, 0xcf, 0xd8, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1, 0x1, 0x2, 0x2,\n    0x1, 0x2, 0x2, 0x2, 0x4, 0x1, 0x8, 0x1a, 0x1a, 0x1a, 0x2, 0x1, 0x4, 0x2,\n    0x8, 0x1, 0x7, 0x1b, 0x2, 0x1, 0x4, 0x1, 0x5, 0x1, 0x1, 0x3, 0x7, 0x1b,\n    0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1e,\n    0x19, 0x21, 0x19, 0x21, 0x19, 0x21, 0x19, 0x21, 0x19, 0x21, 0x1];\n_T Other_Uppercase = [0xa0, 0x21, 0x60, 0x10, 0x83, 0x46, 0x1a];\n_T Sk = [0x5e, 0x1, 0x1, 0x1, 0x47, 0x1, 0x6, 0x1, 0x4, 0x1, 0x3, 0x1, 0x82,\n    0x9, 0x4, 0xc, 0xe, 0x5, 0x7, 0x1, 0x1, 0x1, 0x11, 0x75, 0x1, 0xe, 0x2,\n    0x9c, 0x37, 0x1, 0x1, 0x3, 0xb, 0x3, 0xd, 0x3, 0xd, 0x3, 0xd, 0x2, 0x90,\n    0x9c, 0x2, 0xa0, 0x76, 0x63, 0x17, 0x9, 0x2, 0x67, 0x2, 0xa0, 0x54, 0x27,\n    0x10, 0x83, 0x7c, 0x1, 0x1, 0x1, 0x80, 0xa2, 0x1];\n_T Other_ID_Start = [0xa0, 0x21, 0x18, 0x1, 0x15, 0x1, 0x8f, 0x6c, 0x2];\n_T Nl = [0x96, 0xee, 0x3, 0x8a, 0x6f, 0x23, 0x2, 0x4, 0x8e, 0x7e, 0x1, 0x19,\n    0x9, 0xe, 0x3, 0xa0, 0x76, 0xab, 0xa, 0xa0, 0x5a, 0x50, 0x35, 0x81, 0xcc,\n    0x1, 0x8, 0x1, 0x80, 0x86, 0x5, 0xa0, 0x20, 0x2a, 0x63];\n_T Other_Alphabetic = [\n    0x83, 0x45, 0x1, 0x82, 0x6a, 0xe, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x1,\n    0x48, 0xb, 0x30, 0xd, 0x1, 0x7, 0x10, 0x1, 0x65, 0x7, 0x4, 0x4, 0x2, 0x2,\n    0x4, 0x1, 0x23, 0x1, 0x1e, 0x10, 0x66, 0xb, 0x65, 0x2, 0x3, 0x9, 0x1,\n    0x3, 0x1, 0x4, 0x80, 0xb7, 0x6, 0x6, 0xf, 0x1, 0x4, 0x36, 0x2, 0x2, 0xf,\n    0x1, 0x2, 0x5, 0x3, 0xa, 0x2, 0x1d, 0x3, 0x3a, 0x7, 0x2, 0x2, 0x2, 0x2,\n    0xa, 0x1, 0xa, 0x2, 0x1d, 0x3, 0x3a, 0x5, 0x4, 0x2, 0x2, 0x2, 0x4, 0x1,\n    0x1e, 0x2, 0x3, 0x1, 0xb, 0x3, 0x3a, 0x8, 0x1, 0x3, 0x1, 0x2, 0x15, 0x2,\n    0x1d, 0x3, 0x3a, 0x7, 0x2, 0x2, 0x2, 0x2, 0x9, 0x2, 0xa, 0x2, 0x1e, 0x1,\n    0x3b, 0x5, 0x3, 0x3, 0x1, 0x3, 0xa, 0x1, 0x29, 0x3, 0x3a, 0x7, 0x1, 0x3,\n    0x1, 0x3, 0x8, 0x2, 0xb, 0x2, 0x1e, 0x2, 0x3a, 0x7, 0x1, 0x3, 0x1, 0x3,\n    0x8, 0x2, 0xb, 0x2, 0x1e, 0x2, 0x3a, 0x7, 0x1, 0x3, 0x1, 0x3, 0xa, 0x1,\n    0xa, 0x2, 0x1e, 0x2, 0x4b, 0x6, 0x1, 0x1, 0x1, 0x8, 0x12, 0x2, 0x3d, 0x1,\n    0x2, 0x7, 0x12, 0x1, 0x63, 0x1, 0x2, 0x6, 0x1, 0x2, 0x10, 0x1, 0x80,\n    0xa3, 0x11, 0xb, 0xb, 0x1, 0x24, 0x6e, 0xc, 0x1, 0x1, 0x2, 0x4, 0x17, 0x4,\n    0x4, 0x3, 0x1, 0x1, 0x4, 0x2, 0x8, 0x4, 0xd, 0x5, 0x15, 0x2, 0x82, 0xc1,\n    0x1, 0x83, 0xb2, 0x2, 0x1e, 0x2, 0x1e, 0x2, 0x1e, 0x2, 0x42, 0x13, 0x80,\n    0xe0, 0x1, 0x76, 0xc, 0x4, 0x9, 0x77, 0x11, 0x7, 0x2, 0x4d, 0x5, 0x39, 0xa,\n    0x2, 0x14, 0x80, 0x8b, 0x5, 0x30, 0xf, 0x3c, 0x3, 0x1e, 0x9, 0x2, 0x2,\n    0x39, 0xb, 0x32, 0x12, 0x80, 0xbc, 0x2, 0x87, 0xc2, 0x34, 0x88, 0xf6, 0x20,\n    0xa0, 0x78, 0x74, 0x8, 0x23, 0x1, 0x81, 0x83, 0x5, 0x58, 0x2, 0x32, 0x10,\n    0x62, 0x5, 0x1c, 0xc, 0x2d, 0x4, 0x30, 0xc, 0x69, 0xe, 0xc, 0x1, 0x8,\n    0x2, 0x62, 0x1, 0x1, 0x3, 0x2, 0x2, 0x5, 0x1, 0x2c, 0x5, 0x5, 0x1, 0x80,\n    0xed, 0x8, 0xa0, 0x4f, 0x33, 0x1, 0x8e, 0xe2, 0x3, 0x1, 0x2, 0x5, 0x4,\n    0x85, 0xf0, 0x3, 0x35, 0xe, 0x3c, 0x1, 0x2d, 0x9, 0x47, 0x3, 0x24, 0xc,\n    0x4d, 0x3, 0x30, 0xd, 0x84, 0xeb, 0xb, 0xa0, 0x58, 0x9b, 0x2e\n];\n_T Alphabetic = [\n    0x41, 0x1a, 0x6, 0x1a, 0x2f, 0x1, 0xa, 0x1, 0x4, 0x1, 0x5, 0x17, 0x1, 0x1f,\n    0x1, 0x81, 0xca, 0x4, 0xc, 0xe, 0x5, 0x7, 0x1, 0x1, 0x1, 0x56, 0x1, 0x2a,\n    0x5, 0x1, 0x2, 0x2, 0x4, 0x8, 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x14, 0x1,\n    0x53, 0x1, 0x80, 0x8b, 0x8, 0x80, 0x9e, 0x9, 0x26, 0x2, 0x1, 0x7, 0x27,\n    0x28, 0xe, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x1, 0x8, 0x1b, 0x5, 0x3,\n    0x1d, 0xb, 0x5, 0x38, 0x1, 0x7, 0xe, 0x66, 0x1, 0x8, 0x4, 0x8, 0x4, 0x3,\n    0xa, 0x3, 0x2, 0x1, 0x10, 0x30, 0xd, 0x65, 0x18, 0x21, 0x9, 0x2, 0x4,\n    0x1, 0x5, 0x18, 0x2, 0x13, 0x13, 0x19, 0x47, 0x1, 0x1, 0xb, 0x37, 0x6,\n    0x6, 0xf, 0x1, 0x3c, 0x1, 0x10, 0x1, 0x3, 0x4, 0xf, 0xd, 0x7, 0x1, 0x7,\n    0x1, 0x3, 0x1, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x1, 0x3, 0x4,\n    0x3, 0x8, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x8, 0x1, 0x4, 0x2, 0x1, 0x5, 0xc,\n    0x2, 0xf, 0x3, 0x1, 0x6, 0x4, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x2, 0x1,\n    0x2, 0x1, 0x2, 0x4, 0x5, 0x4, 0x2, 0x2, 0x2, 0x4, 0x1, 0x7, 0x4, 0x1,\n    0x1, 0x11, 0x6, 0xb, 0x3, 0x1, 0x9, 0x1, 0x3, 0x1, 0x16, 0x1, 0x7, 0x1,\n    0x2, 0x1, 0x5, 0x3, 0x9, 0x1, 0x3, 0x1, 0x2, 0x3, 0x1, 0xf, 0x4, 0x1d,\n    0x3, 0x1, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x2, 0x1, 0x5, 0x3,\n    0x8, 0x2, 0x2, 0x2, 0x2, 0x9, 0x2, 0x4, 0x2, 0x1, 0x5, 0xd, 0x1, 0x10,\n    0x2, 0x1, 0x6, 0x3, 0x3, 0x1, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x2, 0x3, 0x2,\n    0x3, 0x3, 0x3, 0xc, 0x4, 0x5, 0x3, 0x3, 0x1, 0x3, 0x3, 0x1, 0x6, 0x1,\n    0x29, 0x3, 0x1, 0x8, 0x1, 0x3, 0x1, 0x17, 0x1, 0xa, 0x1, 0x5, 0x3, 0x8,\n    0x1, 0x3, 0x1, 0x3, 0x8, 0x2, 0x1, 0x2, 0x6, 0x4, 0x1e, 0x2, 0x1, 0x8,\n    0x1, 0x3, 0x1, 0x17, 0x1, 0xa, 0x1, 0x5, 0x3, 0x8, 0x1, 0x3, 0x1, 0x3,\n    0x8, 0x2, 0x7, 0x1, 0x1, 0x4, 0xd, 0x2, 0xf, 0x2, 0x1, 0x8, 0x1, 0x3,\n    0x1, 0x29, 0x2, 0x8, 0x1, 0x3, 0x1, 0x3, 0x1, 0x1, 0x8, 0x1, 0x8, 0x4,\n    0x16, 0x6, 0x2, 0x2, 0x1, 0x12, 0x3, 0x18, 0x1, 0x9, 0x1, 0x1, 0x2, 0x7,\n    0x8, 0x6, 0x1, 0x1, 0x1, 0x8, 0x12, 0x2, 0xd, 0x3a, 0x5, 0x7, 0x6, 0x1,\n    0x33, 0x2, 0x1, 0x1, 0x2, 0x2, 0x1, 0x1, 0x2, 0x1, 0x6, 0x4, 0x1, 0x7,\n    0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x1, 0xd, 0x1, 0x3, 0x2, 0x5, 0x1,\n    0x1, 0x6, 0x1, 0xe, 0x4, 0x20, 0x1, 0x3f, 0x8, 0x1, 0x24, 0x4, 0x11, 0x6,\n    0x10, 0x1, 0x24, 0x43, 0x37, 0x1, 0x1, 0x2, 0x5, 0x10, 0x13, 0x2, 0x4,\n    0x5, 0x19, 0x7, 0x1, 0xd, 0x2, 0x2, 0x26, 0x1, 0x1, 0x5, 0x1, 0x2, 0x2b,\n    0x1, 0x81, 0x4d, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0x29, 0x1,\n    0x4, 0x2, 0x21, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0xf, 0x1,\n    0x39, 0x1, 0x4, 0x2, 0x43, 0x4, 0x1, 0x20, 0x10, 0x10, 0x55, 0xc, 0x82,\n    0x6c, 0x2, 0x11, 0x1, 0x1a, 0x5, 0x4b, 0x3, 0x3, 0xf, 0xd, 0x1, 0x6, 0xc,\n    0x14, 0xc, 0x14, 0xc, 0xd, 0x1, 0x3, 0x1, 0x2, 0xc, 0x34, 0x2, 0x13, 0xe,\n    0x1, 0x4, 0x1, 0x43, 0x58, 0x8, 0x2b, 0x5, 0x46, 0xa, 0x1d, 0x3, 0xc,\n    0x4, 0x9, 0x17, 0x1e, 0x2, 0x5, 0xb, 0x2c, 0x4, 0x1a, 0x36, 0x1c, 0x4,\n    0x3f, 0x2, 0x14, 0x32, 0x1, 0x58, 0x34, 0x1, 0xf, 0x1, 0x7, 0x34, 0x2a,\n    0x2, 0x4, 0xa, 0x2c, 0x1, 0xb, 0xe, 0x36, 0x17, 0x3, 0xa, 0x24, 0x6b, 0x4,\n    0x1, 0x6, 0x1, 0x2, 0x9, 0x80, 0xc0, 0x40, 0x81, 0x16, 0x2, 0x6, 0x2,\n    0x26, 0x2, 0x6, 0x2, 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1f, 0x2,\n    0x35, 0x1, 0x7, 0x1, 0x1, 0x3, 0x3, 0x1, 0x7, 0x3, 0x4, 0x2, 0x6, 0x4,\n    0xd, 0x5, 0x3, 0x1, 0x7, 0x74, 0x1, 0xd, 0x1, 0x10, 0xd, 0x65, 0x1, 0x4,\n    0x1, 0x2, 0xa, 0x1, 0x1, 0x3, 0x5, 0x6, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4,\n    0x1, 0xb, 0x2, 0x4, 0x5, 0x5, 0x4, 0x1, 0x11, 0x29, 0x83, 0x2d, 0x34, 0x87,\n    0x16, 0x2f, 0x1, 0x2f, 0x1, 0x80, 0x85, 0x6, 0x4, 0x3, 0x2, 0xc, 0x26,\n    0x1, 0x1, 0x5, 0x1, 0x2, 0x38, 0x7, 0x1, 0x10, 0x17, 0x9, 0x7, 0x1, 0x7,\n    0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x20,\n    0x2f, 0x1, 0x81, 0xd5, 0x3, 0x19, 0x9, 0x7, 0x5, 0x2, 0x5, 0x4, 0x56,\n    0x6, 0x3, 0x1, 0x5a, 0x1, 0x4, 0x5, 0x29, 0x3, 0x5e, 0x11, 0x1b, 0x35,\n    0x10, 0x82, 0x0, 0x99, 0xb6, 0x4a, 0xa0, 0x51, 0xcd, 0x33, 0x84, 0x8d,\n    0x43, 0x2e, 0x2, 0x81, 0xd, 0x3, 0x10, 0xa, 0x2, 0x14, 0x2f, 0x5, 0x8, 0x3,\n    0x19, 0x7, 0x51, 0x27, 0x9, 0x2, 0x67, 0x2, 0x4, 0x1, 0x4, 0xc, 0xb, 0x4d,\n    0xa, 0x1, 0x3, 0x1, 0x4, 0x1, 0x1c, 0x18, 0x34, 0xc, 0x44, 0x2e, 0x6,\n    0x3, 0x1, 0xe, 0x21, 0x5, 0x23, 0xd, 0x1d, 0x3, 0x33, 0x1, 0xc, 0xf, 0x1,\n    0x30, 0x37, 0x9, 0xe, 0x12, 0x17, 0x3, 0x1, 0x5, 0x3f, 0x1, 0x1, 0x1,\n    0x1, 0x18, 0x3, 0x2, 0x10, 0x2, 0x4, 0xb, 0x6, 0x2, 0x6, 0x2, 0x6, 0x9,\n    0x7, 0x1, 0x7, 0x80, 0x91, 0x2b, 0x15, 0xa0, 0x2b, 0xa4, 0xc, 0x17, 0x4,\n    0x31, 0xa0, 0x21, 0x4, 0x81, 0x6e, 0x2, 0x6a, 0x26, 0x7, 0xc, 0x5, 0x5,\n    0xc, 0x1, 0xd, 0x1, 0x5, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x6c, 0x21,\n    0x81, 0x6b, 0x12, 0x40, 0x2, 0x36, 0x28, 0xc, 0x74, 0x5, 0x1, 0x80, 0x87,\n    0x24, 0x1a, 0x6, 0x1a, 0xb, 0x59, 0x3, 0x6, 0x2, 0x6, 0x2, 0x6, 0x2, 0x3,\n    0x23, 0xc, 0x1, 0x1a, 0x1, 0x13, 0x1, 0x2, 0x1, 0xf, 0x2, 0xe, 0x22, 0x7b,\n    0x45, 0x35, 0x81, 0xb, 0x1d, 0x3, 0x31, 0x2f, 0x1f, 0x11, 0x1b, 0x35,\n    0x1e, 0x2, 0x24, 0x4, 0x8, 0x1, 0x5, 0x2a, 0x80, 0x9e, 0x83, 0x62, 0x6,\n    0x2, 0x1, 0x1, 0x2c, 0x1, 0x2, 0x3, 0x1, 0x2, 0x17, 0x80, 0xaa, 0x16, 0xa,\n    0x1a, 0x46, 0x38, 0x6, 0x2, 0x40, 0x4, 0x1, 0x2, 0x5, 0x8, 0x1, 0x3, 0x1,\n    0x1b, 0x2c, 0x1d, 0x80, 0x83, 0x36, 0xa, 0x16, 0xa, 0x13, 0x80, 0x8d, 0x49,\n    0x83, 0xb7, 0x46, 0x3c, 0x37, 0x17, 0x19, 0x17, 0x33, 0x4d, 0x40, 0x1, 0x4,\n    0x84, 0xbb, 0x36, 0x89, 0x4a, 0x83, 0x6f, 0x80, 0x91, 0x63, 0x8b, 0x9d,\n    0x84, 0x2f, 0xa0, 0x33, 0xd1, 0x82, 0x39, 0x84, 0xc7, 0x45, 0xb, 0x2f,\n    0x14, 0xd, 0xa0, 0x40, 0x60, 0x2, 0xa0, 0x23, 0xfe, 0x55, 0x1, 0x47, 0x1,\n    0x2, 0x2, 0x1, 0x2, 0x2, 0x2, 0x4, 0x1, 0xc, 0x1, 0x1, 0x1, 0x7, 0x1,\n    0x41, 0x1, 0x4, 0x2, 0x8, 0x1, 0x7, 0x1, 0x1c, 0x1, 0x4, 0x1, 0x5, 0x1,\n    0x1, 0x3, 0x7, 0x1, 0x81, 0x54, 0x2, 0x19, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19,\n    0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x8,\n    0x96, 0x34, 0x4, 0x1, 0x1b, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0xa, 0x1,\n    0x4, 0x1, 0x1, 0x1, 0x1, 0x6, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3,\n    0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x2, 0x1, 0x1, 0x2, 0x4, 0x1, 0x7, 0x1, 0x4, 0x1, 0x4, 0x1, 0x1, 0x1,\n    0xa, 0x1, 0x11, 0x5, 0x3, 0x1, 0x5, 0x1, 0x11, 0x91, 0x44, 0xa0, 0xa6,\n    0xd7, 0x29, 0x90, 0x35, 0xb, 0x80, 0xde, 0xa0, 0x3f, 0xe2, 0x82, 0x1e\n];\n_T Zs = [0x20, 0x1, 0x7f, 0x1, 0x95, 0xdf, 0x1, 0x89, 0x7f, 0xb, 0x24, 0x1,\n    0x2f, 0x1, 0x8f, 0xa0, 0x1];\n_T Variation_Selector = [0x98, 0xb, 0x3, 0xa0, 0xe5, 0xf2, 0x10, 0xad, 0x2, 0xf0, 0x80,\n    0xf0];\n_T Other_Default_Ignorable_Code_Point = [\n    0x83, 0x4f, 0x1, 0x8e, 0xf, 0x2, 0x86, 0x53, 0x2, 0x88, 0xaf, 0x1, 0x90,\n    0xfe, 0x1, 0xa0, 0xce, 0x3b, 0x1, 0x4f, 0x9, 0xad, 0x0, 0x7, 0x1, 0x1,\n    0x1e, 0x60, 0x80, 0x80, 0x80, 0xf0, 0x8e, 0x10\n];\n_T IDS_Binary_Operator = [0xa0, 0x2f, 0xf0, 0x2, 0x2, 0x8];\n_T Grapheme_Base = [\n    0x20, 0x5f, 0x21, 0xd, 0x1, 0x82, 0x52, 0x70, 0x8, 0x2, 0x5, 0x5, 0x7,\n    0x1, 0x1, 0x1, 0x14, 0x1, 0x80, 0xe0, 0x7, 0x80, 0x9e, 0x9, 0x26, 0x2,\n    0x7, 0x1, 0x27, 0x1, 0x2, 0x4, 0x1, 0x2e, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2,\n    0x1, 0x9, 0x1b, 0x5, 0x5, 0x11, 0xa, 0xb, 0x1, 0x2, 0x2d, 0x15, 0x10,\n    0x1, 0x65, 0x8, 0x1, 0x6, 0x2, 0x2, 0x1, 0x4, 0x20, 0x2, 0x1, 0x1, 0x1e,\n    0x1d, 0x59, 0xb, 0x1, 0xe, 0x2b, 0x9, 0x7, 0x5, 0x16, 0x4, 0x1, 0x9, 0x1,\n    0x3, 0x1, 0x7, 0xf, 0x1, 0x19, 0x5, 0x1, 0x41, 0x1, 0x1, 0xb, 0x56, 0x37,\n    0x1, 0x1, 0x1, 0x4, 0x8, 0x4, 0x1, 0x3, 0x7, 0xa, 0x2, 0x14, 0x1, 0x7,\n    0x2, 0x2, 0x1, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x1, 0x3, 0x4,\n    0x3, 0x1, 0x1, 0x2, 0x6, 0x2, 0x2, 0x2, 0x1, 0x1, 0xd, 0x2, 0x1, 0x3,\n    0x4, 0x16, 0x7, 0x1, 0x1, 0x6, 0x4, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x2,\n    0x1, 0x2, 0x1, 0x2, 0x4, 0x3, 0x18, 0x4, 0x1, 0x1, 0x7, 0xa, 0x2, 0x3,\n    0xe, 0x1, 0x1, 0x9, 0x1, 0x3, 0x1, 0x16, 0x1, 0x7, 0x1, 0x2, 0x1, 0x5,\n    0x3, 0x4, 0x8, 0x1, 0x1, 0x2, 0x3, 0x1, 0xf, 0x2, 0x4, 0xc, 0x10, 0x2,\n    0x1, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x2, 0x1, 0x5, 0x3, 0x1,\n    0x2, 0x1, 0x6, 0x2, 0x2, 0x2, 0xf, 0x2, 0x1, 0x3, 0x4, 0x12, 0xb, 0x1,\n    0x1, 0x6, 0x3, 0x3, 0x1, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x2, 0x3, 0x2, 0x3,\n    0x3, 0x3, 0xc, 0x5, 0x1, 0x1, 0x2, 0x3, 0x3, 0x1, 0x3, 0x3, 0x1, 0x15,\n    0x15, 0x6, 0x3, 0x1, 0x8, 0x1, 0x3, 0x1, 0x17, 0x1, 0xa, 0x1, 0x5, 0x3,\n    0x1, 0x3, 0x4, 0x13, 0x2, 0x6, 0x2, 0x4, 0xa, 0x8, 0x8, 0x2, 0x2, 0x1,\n    0x8, 0x1, 0x3, 0x1, 0x17, 0x1, 0xa, 0x1, 0x5, 0x3, 0x2, 0x1, 0x2, 0x1,\n    0x2, 0x2, 0x2, 0x1, 0x2, 0x12, 0x1, 0x1, 0x2, 0x4, 0xa, 0x1, 0x2, 0xf,\n    0x2, 0x1, 0x8, 0x1, 0x3, 0x1, 0x29, 0x2, 0x1, 0x1, 0x2, 0x5, 0x3, 0x1,\n    0x3, 0x1, 0x1, 0x11, 0x2, 0x4, 0x10, 0x3, 0x7, 0x2, 0x2, 0x1, 0x12, 0x3,\n    0x18, 0x1, 0x9, 0x1, 0x1, 0x2, 0x7, 0x9, 0x2, 0x6, 0x7, 0x13, 0x3, 0xc,\n    0x30, 0x1, 0x2, 0xb, 0x8, 0x8, 0xd, 0x25, 0x2, 0x1, 0x1, 0x2, 0x2, 0x1,\n    0x1, 0x2, 0x1, 0x6, 0x4, 0x1, 0x7, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2,\n    0x1, 0x4, 0x1, 0x2, 0x9, 0x1, 0x2, 0x5, 0x1, 0x1, 0x9, 0xa, 0x2, 0x4, 0x20,\n    0x18, 0x2, 0x1b, 0x1, 0x1, 0x1, 0x1, 0x1, 0xe, 0x1, 0x24, 0x12, 0x1, 0x5,\n    0x1, 0x2, 0x5, 0x31, 0x8, 0x1, 0x6, 0x1, 0xd, 0x25, 0x2d, 0x4, 0x1, 0x6,\n    0x1, 0x2, 0x2, 0x2, 0x19, 0x2, 0x4, 0x3, 0x10, 0x4, 0xd, 0x1, 0x2, 0x2,\n    0x6, 0x1, 0xf, 0x1, 0x28, 0x1, 0x1, 0x5, 0x1, 0x2, 0x81, 0x79, 0x1, 0x4,\n    0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0x29, 0x1, 0x4, 0x2, 0x21, 0x1, 0x4,\n    0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0xf, 0x1, 0x39, 0x1, 0x4, 0x2, 0x43,\n    0x5, 0x1d, 0x3, 0x1a, 0x6, 0x55, 0xb, 0x82, 0x9d, 0x3, 0x51, 0xf, 0xd,\n    0x1, 0x4, 0xe, 0x12, 0x3, 0x2, 0x9, 0x12, 0xe, 0xd, 0x1, 0x3, 0xf, 0x34,\n    0x2, 0x1, 0x7, 0x8, 0x1, 0x2, 0xb, 0x9, 0x3, 0xa, 0x6, 0xa, 0x6, 0xb,\n    0x5, 0xa, 0x6, 0x58, 0x8, 0x29, 0x1, 0x1, 0x5, 0x46, 0xa, 0x1d, 0x6, 0x4,\n    0x2, 0x3, 0x4, 0x2, 0x1, 0x6, 0x7, 0x1, 0x3, 0x2a, 0x2, 0x5, 0xb, 0x2c,\n    0x4, 0x1a, 0x6, 0xb, 0x3, 0x39, 0x2, 0x2, 0x3, 0x38, 0x1, 0x1, 0x9, 0x1,\n    0x1, 0x2, 0x8, 0x6, 0xd, 0xa, 0x6, 0xa, 0x6, 0xe, 0x56, 0x30, 0x1, 0x1,\n    0x5, 0x1, 0x1, 0x5, 0x1, 0x9, 0x4, 0x1b, 0x9, 0x9, 0x5, 0x20, 0x4, 0x2,\n    0x2, 0x1, 0x1, 0x3a, 0x1, 0x1, 0x2, 0x3, 0x1, 0x1, 0x3, 0x2, 0x8, 0x30,\n    0x8, 0x2, 0x5, 0xf, 0x3, 0x33, 0x40, 0x8, 0xb, 0x1, 0xd, 0x1, 0x7, 0x4,\n    0x1, 0x6, 0x1, 0x2, 0x9, 0x80, 0xc0, 0x40, 0x81, 0x16, 0x2, 0x6, 0x2,\n    0x26, 0x2, 0x6, 0x2, 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1f, 0x2,\n    0x35, 0x1, 0xf, 0x1, 0xe, 0x2, 0x6, 0x1, 0x13, 0x2, 0x3, 0x1, 0x9, 0x1,\n    0xb, 0x5, 0x18, 0x7, 0x31, 0x10, 0x2, 0x2, 0x1b, 0x1, 0xd, 0x3, 0x1b, 0x45,\n    0x80, 0x8a, 0x6, 0x82, 0x64, 0xc, 0x27, 0x19, 0xb, 0x15, 0x82, 0xa0, 0x1,\n    0x84, 0x4c, 0x3, 0xa, 0x80, 0xa6, 0x2f, 0x1, 0x2f, 0x1, 0x80, 0x8f, 0x3,\n    0x2, 0x5, 0x2d, 0x1, 0x1, 0x5, 0x1, 0x2, 0x38, 0x7, 0x2, 0xf, 0x17, 0x9,\n    0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7,\n    0x21, 0x3c, 0x44, 0x1a, 0x1, 0x59, 0xc, 0x80, 0xd6, 0x1a, 0xc, 0x4, 0x2a,\n    0x6, 0x10, 0x1, 0x56, 0x4, 0x65, 0x5, 0x29, 0x3, 0x5e, 0x1, 0x2b, 0x5,\n    0x24, 0xc, 0x2f, 0x1, 0x80, 0xdf, 0x1, 0x9a, 0xb6, 0xa, 0xa0, 0x52, 0xd,\n    0x33, 0x84, 0x8d, 0x3, 0x37, 0x9, 0x81, 0x5c, 0x14, 0x2f, 0x4, 0x1, 0xa,\n    0x1a, 0x8, 0x50, 0x2, 0x6, 0x8, 0x80, 0x8f, 0x1, 0x4, 0xc, 0xb, 0x4d, 0xa,\n    0x1, 0x3, 0x1, 0x4, 0x1, 0x19, 0x2, 0x5, 0x4, 0xa, 0x6, 0x38, 0x8, 0x44,\n    0xa, 0xc, 0x18, 0xa, 0x4, 0x26, 0x8, 0x19, 0xb, 0x2, 0xb, 0x1e, 0x6, 0x30,\n    0x1, 0x2, 0x4, 0x2, 0x1, 0x11, 0x1, 0xb, 0x4, 0x2, 0x20, 0x29, 0x6, 0x2,\n    0x2, 0x2, 0xb, 0x3, 0x1, 0x8, 0x1, 0x1, 0x2, 0xa, 0x2, 0x20, 0x4, 0x30,\n    0x1, 0x1, 0x3, 0x2, 0x2, 0x5, 0x2, 0x1, 0x1, 0x1, 0x18, 0x11, 0x2, 0x8,\n    0xb, 0x6, 0x2, 0x6, 0x2, 0x6, 0x9, 0x7, 0x1, 0x7, 0x80, 0x91, 0x25, 0x1,\n    0x2, 0x1, 0x4, 0x3, 0xa, 0x6, 0xa0, 0x2b, 0xa4, 0xc, 0x17, 0x4, 0x31, 0xa0,\n    0x21, 0x4, 0x81, 0x6e, 0x2, 0x6a, 0x26, 0x7, 0xc, 0x5, 0x5, 0x1, 0x1,\n    0x18, 0x1, 0x5, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x7c, 0x11, 0x81, 0x6d,\n    0x10, 0x40, 0x2, 0x36, 0x28, 0xe, 0x12, 0xa, 0x16, 0x23, 0x1, 0x13, 0x1,\n    0x4, 0x4, 0x5, 0x1, 0x80, 0x87, 0x4, 0x80, 0x9d, 0x2, 0x1f, 0x3, 0x6, 0x2,\n    0x6, 0x2, 0x6, 0x2, 0x3, 0x3, 0x7, 0x1, 0x7, 0xd, 0x2, 0x2, 0xc, 0x1,\n    0x1a, 0x1, 0x13, 0x1, 0x2, 0x1, 0xf, 0x2, 0xe, 0x22, 0x7b, 0x5, 0x3, 0x4,\n    0x2d, 0x3, 0x54, 0x5, 0xc, 0x34, 0x2d, 0x80, 0x83, 0x1d, 0x3, 0x31, 0x2f,\n    0x1f, 0x1, 0x4, 0xc, 0x1b, 0x35, 0x1e, 0x1, 0x25, 0x4, 0xe, 0x2a, 0x80,\n    0x9e, 0x2, 0xa, 0x83, 0x56, 0x6, 0x2, 0x1, 0x1, 0x2c, 0x1, 0x2, 0x3, 0x1,\n    0x2, 0x17, 0x1, 0x9, 0x80, 0xa0, 0x1c, 0x3, 0x1b, 0x5, 0x1, 0x40, 0x38,\n    0x6, 0x2, 0x40, 0x1, 0xf, 0x4, 0x1, 0x3, 0x1, 0x1b, 0xc, 0x8, 0x8, 0x9,\n    0x7, 0x20, 0x80, 0x80, 0x36, 0x3, 0x1d, 0x2, 0x1b, 0x5, 0x8, 0x80, 0x80,\n    0x49, 0x82, 0x17, 0x1f, 0x81, 0x81, 0x1, 0x1, 0x36, 0xf, 0x7, 0x4, 0x1e,\n    0x12, 0x31, 0x4, 0x2, 0x2, 0x2, 0x1, 0x4, 0xe, 0x19, 0x7, 0xa, 0x9, 0x24,\n    0x5, 0x1, 0x9, 0xe, 0x3e, 0x34, 0x9, 0xa, 0x7, 0xa, 0x84, 0xa6, 0x2b, 0x1,\n    0x1, 0x1, 0x2, 0x6, 0x1, 0x9, 0xa, 0x89, 0x36, 0x83, 0x6f, 0x80, 0x91,\n    0x63, 0xd, 0x4, 0x8b, 0x8c, 0x84, 0x2f, 0xa0, 0x33, 0xd1, 0x82, 0x39, 0x84,\n    0xc7, 0x45, 0xb, 0x2f, 0x14, 0xd, 0xa0, 0x40, 0x60, 0x2, 0x9f, 0xfe,\n    0x80, 0xf6, 0xa, 0x27, 0x2, 0x3c, 0x1, 0x1, 0x3, 0x4, 0x15, 0x2, 0x7, 0x1e,\n    0x4, 0x30, 0x22, 0x42, 0x3, 0x1, 0x80, 0xba, 0x57, 0x9, 0x12, 0x80, 0x8e,\n    0x55, 0x1, 0x47, 0x1, 0x2, 0x2, 0x1, 0x2, 0x2, 0x2, 0x4, 0x1, 0xc, 0x1,\n    0x1, 0x1, 0x7, 0x1, 0x41, 0x1, 0x4, 0x2, 0x8, 0x1, 0x7, 0x1, 0x1c, 0x1,\n    0x4, 0x1, 0x5, 0x1, 0x1, 0x3, 0x7, 0x1, 0x81, 0x54, 0x2, 0x81, 0x24, 0x2,\n    0x32, 0x96, 0x0, 0x4, 0x1, 0x1b, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0xa,\n    0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x6, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x3, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x2, 0x1, 0x1, 0x2, 0x4, 0x1, 0x7, 0x1, 0x4, 0x1, 0x4, 0x1, 0x1,\n    0x1, 0xa, 0x1, 0x11, 0x5, 0x3, 0x1, 0x5, 0x1, 0x11, 0x34, 0x2, 0x81, 0xe,\n    0x2c, 0x4, 0x64, 0xc, 0xf, 0x2, 0xe, 0x2, 0xf, 0x1, 0xf, 0x20, 0xb, 0x5,\n    0x1f, 0x1, 0x3c, 0x4, 0x2b, 0x4b, 0x1d, 0xd, 0x2b, 0x5, 0x9, 0x7, 0x2,\n    0x80, 0xae, 0x21, 0xf, 0x6, 0x1, 0x46, 0x3, 0x14, 0xc, 0x25, 0x1, 0x5,\n    0x15, 0x11, 0xf, 0x3f, 0x1, 0x1, 0x1, 0x80, 0xb6, 0x1, 0x4, 0x3, 0x3e, 0x2,\n    0x4, 0xc, 0x18, 0x80, 0x93, 0x46, 0x4, 0xb, 0x30, 0x46, 0x3a, 0x74, 0x88,\n    0x8c, 0xa0, 0xa6, 0xd7, 0x29, 0x90, 0x35, 0xb, 0x80, 0xde, 0xa0, 0x3f, 0xe2, 0x82,\n    0x1e\n];\n_T Case_Ignorable = [\n    0x27, 0x1, 0x6, 0x1, 0xb, 0x1, 0x23, 0x1, 0x1, 0x1, 0x47, 0x1, 0x4, 0x1,\n    0x1, 0x1, 0x4, 0x1, 0x2, 0x2, 0x81, 0xf7, 0x80, 0xc0, 0x4, 0x2, 0x4, 0x1,\n    0x9, 0x2, 0x1, 0x1, 0x80, 0xfb, 0x7, 0x80, 0xcf, 0x1, 0x37, 0x2d, 0x1,\n    0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x1, 0x2c, 0x1, 0xb, 0x5, 0xb, 0xb, 0x1, 0x1,\n    0x23, 0x1, 0xa, 0x15, 0x10, 0x1, 0x65, 0x8, 0x1, 0xa, 0x1, 0x4, 0x21,\n    0x1, 0x1, 0x1, 0x1e, 0x1b, 0x5b, 0xb, 0x3a, 0xb, 0x4, 0x1, 0x1b, 0x18,\n    0x2b, 0x3, 0x80, 0x88, 0x1b, 0x1, 0x3, 0x37, 0x1, 0x1, 0x1, 0x4, 0x8, 0x4,\n    0x1, 0x3, 0x7, 0xa, 0x2, 0xd, 0x1, 0xf, 0x1, 0x3a, 0x1, 0x4, 0x4, 0x8, 0x1,\n    0x14, 0x2, 0x1d, 0x2, 0x39, 0x1, 0x4, 0x2, 0x4, 0x2, 0x2, 0x3, 0x3, 0x1,\n    0x1e, 0x2, 0x3, 0x1, 0xb, 0x2, 0x39, 0x1, 0x4, 0x5, 0x1, 0x2, 0x4, 0x1,\n    0x14, 0x2, 0x1d, 0x1, 0x3a, 0x1, 0x2, 0x1, 0x1, 0x4, 0x8, 0x1, 0x8, 0x1,\n    0xb, 0x2, 0x1e, 0x1, 0x3d, 0x1, 0xc, 0x1, 0x70, 0x3, 0x5, 0x3, 0x1, 0x4,\n    0x7, 0x2, 0xb, 0x2, 0x58, 0x1, 0x2, 0x1, 0x6, 0x1, 0x5, 0x2, 0x14, 0x2,\n    0x5d, 0x4, 0x8, 0x1, 0x14, 0x2, 0x66, 0x1, 0x7, 0x3, 0x1, 0x1, 0x5a, 0x1,\n    0x2, 0x7, 0xb, 0x9, 0x62, 0x1, 0x2, 0x6, 0x1, 0x2, 0x9, 0x1, 0x1, 0x6,\n    0x4a, 0x2, 0x1b, 0x1, 0x1, 0x1, 0x1, 0x1, 0x37, 0xe, 0x1, 0x5, 0x1, 0x2,\n    0x5, 0xb, 0x1, 0x24, 0x9, 0x1, 0x66, 0x4, 0x1, 0x6, 0x1, 0x2, 0x2, 0x2,\n    0x19, 0x2, 0x4, 0x3, 0x10, 0x4, 0xd, 0x1, 0x2, 0x2, 0x6, 0x1, 0xf, 0x1,\n    0x5e, 0x1, 0x82, 0x60, 0x3, 0x83, 0xb2, 0x3, 0x1d, 0x3, 0x1d, 0x2, 0x1e,\n    0x2, 0x40, 0x2, 0x1, 0x7, 0x8, 0x1, 0x2, 0xb, 0x3, 0x1, 0x5, 0x1, 0x2d,\n    0x4, 0x34, 0x1, 0x65, 0x1, 0x76, 0x3, 0x4, 0x2, 0x9, 0x1, 0x6, 0x3, 0x80,\n    0xdb, 0x2, 0x2, 0x1, 0x3a, 0x1, 0x1, 0x7, 0x1, 0x1, 0x1, 0x1, 0x2, 0x8,\n    0x6, 0xa, 0x2, 0x1, 0x27, 0x1, 0x58, 0x4, 0x30, 0x1, 0x1, 0x5, 0x1, 0x1,\n    0x5, 0x1, 0x28, 0x9, 0xc, 0x2, 0x20, 0x4, 0x2, 0x2, 0x1, 0x1, 0x3a, 0x1,\n    0x1, 0x2, 0x3, 0x1, 0x1, 0x3, 0x3a, 0x8, 0x2, 0x2, 0x40, 0x6, 0x52, 0x3,\n    0x1, 0xd, 0x1, 0x7, 0x4, 0x1, 0x6, 0x1, 0x37, 0x3f, 0xd, 0x1, 0x22, 0x4c,\n    0x15, 0x4, 0x81, 0xbd, 0x1, 0x1, 0x3, 0xb, 0x3, 0xd, 0x3, 0xd, 0x3, 0xd,\n    0x2, 0xc, 0x5, 0x8, 0x2, 0xa, 0x1, 0x2, 0x1, 0x2, 0x5, 0x31, 0x5, 0x1,\n    0xa, 0x1, 0x1, 0xd, 0x1, 0x10, 0xd, 0x33, 0x21, 0x8b, 0x8b, 0x2, 0x71,\n    0x3, 0x7d, 0x1, 0xf, 0x1, 0x60, 0x20, 0x2f, 0x1, 0x81, 0xd5, 0x1, 0x24,\n    0x4, 0x3, 0x5, 0x5, 0x1, 0x5d, 0x6, 0x5d, 0x3, 0xa0, 0x6f, 0x16, 0x1, 0x84,\n    0xe2, 0x6, 0x81, 0xe, 0x1, 0x62, 0x4, 0x1, 0xa, 0x1, 0x1, 0x1f, 0x1,\n    0x50, 0x2, 0xe, 0x22, 0x4e, 0x1, 0x17, 0x3, 0x6d, 0x2, 0x8, 0x1, 0x3,\n    0x1, 0x4, 0x1, 0x19, 0x2, 0x80, 0x9d, 0x1, 0x1b, 0x12, 0x34, 0x8, 0x19,\n    0xb, 0x2e, 0x3, 0x30, 0x1, 0x2, 0x4, 0x2, 0x1, 0x12, 0x1, 0x59, 0x6, 0x2,\n    0x2, 0x2, 0x2, 0xc, 0x1, 0x8, 0x1, 0x23, 0x1, 0x3f, 0x1, 0x1, 0x3, 0x2,\n    0x2, 0x5, 0x2, 0x1, 0x1, 0x1b, 0x1, 0xe, 0x2, 0x5, 0x2, 0x1, 0x1, 0x80,\n    0xee, 0x1, 0x2, 0x1, 0x4, 0x1, 0xa0, 0x4f, 0x30, 0x1, 0x80, 0x93, 0x10,\n    0x82, 0x3e, 0x10, 0x3, 0x1, 0xc, 0x7, 0x2b, 0x1, 0x2, 0x1, 0x80, 0xa9,\n    0x1, 0x7, 0x1, 0x6, 0x1, 0xb, 0x1, 0x23, 0x1, 0x1, 0x1, 0x2f, 0x1, 0x2d,\n    0x2, 0x43, 0x1, 0x15, 0x3, 0x82, 0x1, 0x1, 0x88, 0x3, 0x3, 0x1, 0x2, 0x5,\n    0x4, 0x28, 0x3, 0x4, 0x1, 0x85, 0xc1, 0x1, 0x36, 0xf, 0x39, 0x2, 0x31,\n    0x4, 0x2, 0x2, 0x2, 0x1, 0x42, 0x3, 0x24, 0x5, 0x1, 0x8, 0x4b, 0x2, 0x34,\n    0x9, 0x84, 0xec, 0x1, 0x1, 0x1, 0x2, 0x6, 0x1, 0x1, 0xa0, 0x58, 0xd7, 0x11,\n    0xa0, 0x61, 0xc7, 0x3, 0x9, 0x10, 0x2, 0x7, 0x1e, 0x4, 0x80, 0x94, 0x3,\n    0xac, 0x2d, 0xbc, 0x1, 0x1e, 0x60, 0x80, 0x80, 0x80, 0xf0\n];\n_T STerm = [0x21, 0x1, 0xc, 0x1, 0x10, 0x1, 0x85, 0x1c, 0x1, 0x1, 0x1, 0x2a,\n    0x1, 0x80, 0x95, 0x1, 0x80, 0xb4, 0x1, 0x2b, 0x3, 0x80, 0xf6, 0x1, 0x81,\n    0x6a, 0x2, 0x86, 0xe4, 0x2, 0x83, 0x16, 0x1, 0x4, 0x2, 0x83, 0x5, 0x1,\n    0x80, 0xc6, 0x2, 0x80, 0xcc, 0x1, 0x5, 0x1, 0x81, 0x3a, 0x2, 0x81, 0x62,\n    0x4, 0x80, 0xae, 0x2, 0x2, 0x2, 0x80, 0xdb, 0x2, 0x41, 0x2, 0x83, 0xbc,\n    0x2, 0x9, 0x3, 0x8d, 0xe4, 0x1, 0x81, 0xd3, 0x1, 0xa0, 0x74, 0xfc, 0x1,\n    0x81, 0xe, 0x2, 0x80, 0xe3, 0x1, 0x3, 0x1, 0x81, 0x7e, 0x2, 0x56, 0x2,\n    0x5f, 0x1, 0x80, 0x98, 0x2, 0x80, 0x93, 0x3, 0x80, 0x90, 0x2, 0x80, 0xf9,\n    0x1, 0xa0, 0x52, 0x66, 0x1, 0x3, 0x2, 0x80, 0xa9, 0x1, 0xc, 0x1, 0x10, 0x1,\n    0x41, 0x1, 0x8a, 0xf4, 0x2, 0x85, 0xef, 0x2, 0x75, 0x4, 0x7f, 0x3, 0x80, 0x81,\n    0x2];\n_T Diacritic = [\n    0x5e, 0x1, 0x1, 0x1, 0x47, 0x1, 0x6, 0x1, 0x4, 0x1, 0x2, 0x2, 0x81, 0xf7,\n    0x80, 0x9f, 0x1, 0x8, 0x5, 0x6, 0x11, 0x2, 0x4, 0x1, 0x9, 0x2, 0x80,\n    0xfd, 0x5, 0x80, 0xd1, 0x1, 0x37, 0x11, 0x1, 0x1b, 0x1, 0x1, 0x1, 0x2, 0x1,\n    0x1, 0x80, 0x86, 0x8, 0x4, 0x2, 0x80, 0x86, 0x2, 0x4, 0x2, 0x3, 0x3, 0x43,\n    0x1b, 0x5b, 0xb, 0x3a, 0xb, 0x22, 0x2, 0x80, 0xca, 0x1b, 0x3d, 0x1, 0x10,\n    0x1, 0x3, 0x4, 0x1c, 0x1, 0x4a, 0x1, 0x10, 0x1, 0x6e, 0x1, 0x10, 0x1, 0x6e,\n    0x1, 0x10, 0x1, 0x6e, 0x1, 0x10, 0x1, 0x7f, 0x1, 0x7f, 0x1, 0x6e, 0x1,\n    0x10, 0x1, 0x7f, 0x1, 0x7c, 0x1, 0x7c, 0x6, 0x1, 0x1, 0x79, 0x5, 0x4b,\n    0x2, 0x1b, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x2, 0x42, 0x3, 0x1, 0x2, 0x3e,\n    0x1, 0x70, 0x1, 0x1, 0x2, 0x4c, 0x7, 0x1, 0x1, 0xa, 0x2, 0x87, 0x2d, 0xb,\n    0x9, 0x1, 0x81, 0x5b, 0x3, 0x81, 0x39, 0x8, 0x2, 0x1, 0x80, 0xb4, 0x1, 0xf,\n    0x1, 0x26, 0x9, 0x36, 0x2, 0x80, 0x8a, 0x2, 0x40, 0x6, 0x52, 0x19, 0x4,\n    0x1, 0x6, 0x1, 0x37, 0x3f, 0x59, 0xc, 0x2d, 0x3, 0x81, 0xbd, 0x1, 0x1,\n    0x3, 0xb, 0x3, 0xd, 0x3, 0xd, 0x3, 0xd, 0x2, 0x8c, 0xf0, 0x3, 0x81, 0x3d,\n    0x1, 0x81, 0xfa, 0x6, 0x69, 0x4, 0x5f, 0x1, 0xa0, 0x75, 0x72, 0x1, 0xc,\n    0x2, 0x1, 0x1, 0x70, 0x2, 0x25, 0xb, 0x66, 0x1, 0x6f, 0x2, 0x80, 0xca, 0x1,\n    0x1b, 0x12, 0x39, 0x4, 0x24, 0x1, 0x5f, 0x1, 0xc, 0x1, 0x80, 0xba, 0x1,\n    0x43, 0x4, 0x33, 0x1, 0x80, 0xf5, 0x2, 0xa0, 0x4f, 0x30, 0x1, 0x83, 0x1,\n    0x7, 0x81, 0x17, 0x1, 0x1, 0x1, 0x2f, 0x1, 0x2d, 0x2, 0x43, 0x1, 0x90,\n    0xd5, 0x2, 0x78, 0x2, 0x80, 0x8b, 0x1, 0x84, 0xf5, 0x2, 0xa0, 0x58, 0xd7,\n    0x11, 0xa0, 0x61, 0xc7, 0x3, 0x3, 0x6, 0x8, 0x8, 0x2, 0x7, 0x1e, 0x4\n];\n_T Lm = [0x82, 0xb0, 0x12, 0x4, 0xc, 0xe, 0x5, 0x7, 0x1, 0x1, 0x1, 0x80,\n    0x85, 0x1, 0x5, 0x1, 0x81, 0xde, 0x1, 0x80, 0xe6, 0x1, 0x80, 0xa4, 0x2,\n    0x81, 0xd, 0x2, 0x4, 0x1, 0x1f, 0x1, 0x9, 0x1, 0x3, 0x1, 0x81, 0x48, 0x1,\n    0x84, 0xd4, 0x1, 0x7f, 0x1, 0x82, 0x35, 0x1, 0x86, 0xda, 0x1, 0x6b, 0x1,\n    0x82, 0x63, 0x1, 0x81, 0xd0, 0x6, 0x80, 0xae, 0x3f, 0xd, 0x1, 0x22, 0x25,\n    0x82, 0xb1, 0x1, 0xd, 0x1, 0x10, 0xd, 0x8b, 0xdf, 0x2, 0x80, 0xf1, 0x1,\n    0x80, 0xbf, 0x1, 0x81, 0xd5, 0x1, 0x2b, 0x5, 0x5, 0x1, 0x61, 0x2, 0x5d,\n    0x3, 0xa0, 0x6f, 0x16, 0x1, 0x84, 0xe2, 0x6, 0x81, 0xe, 0x1, 0x72, 0x1,\n    0x80, 0x97, 0x9, 0x50, 0x1, 0x17, 0x1, 0x6f, 0x2, 0x81, 0xd5, 0x1, 0x80,\n    0xa0, 0x1, 0x6c, 0x1, 0x15, 0x2, 0xa0, 0x54, 0x7b, 0x1, 0x2d, 0x2, 0xa0, 0x6f,\n    0xf3, 0xd];\n_T Mc = [0x89, 0x3, 0x1, 0x37, 0x1, 0x2, 0x3, 0x8, 0x4, 0x1, 0x2, 0x32, 0x2,\n    0x3a, 0x3, 0x6, 0x2, 0x2, 0x2, 0xa, 0x1, 0x2b, 0x1, 0x3a, 0x3, 0x42, 0x1,\n    0x3a, 0x3, 0x8, 0x1, 0x1, 0x2, 0x35, 0x2, 0x3a, 0x1, 0x1, 0x1, 0x6, 0x2,\n    0x2, 0x2, 0xa, 0x1, 0x66, 0x2, 0x1, 0x2, 0x3, 0x3, 0x1, 0x3, 0xa, 0x1,\n    0x29, 0x3, 0x3d, 0x4, 0x3d, 0x2, 0x3a, 0x1, 0x1, 0x5, 0x2, 0x2, 0x1, 0x2,\n    0x9, 0x2, 0x2b, 0x2, 0x3a, 0x3, 0x5, 0x3, 0x1, 0x3, 0xa, 0x1, 0x2a, 0x2,\n    0x4b, 0x3, 0x6, 0x8, 0x12, 0x2, 0x81, 0x4a, 0x2, 0x3f, 0x1, 0x80, 0xab,\n    0x2, 0x4, 0x1, 0x6, 0x1, 0x2, 0x2, 0x19, 0x2, 0xa, 0x3, 0x2, 0x7, 0x15,\n    0x2, 0x2, 0x6, 0x2, 0x1, 0xa, 0x3, 0x87, 0x19, 0x1, 0x7, 0x8, 0x1, 0x2,\n    0x81, 0x5a, 0x4, 0x2, 0x3, 0x4, 0x2, 0x1, 0x6, 0x77, 0x11, 0x7, 0x2,\n    0x4f, 0x2, 0x3a, 0x1, 0x1, 0x1, 0x9, 0x1, 0x1, 0x2, 0x8, 0x6, 0x80, 0x91,\n    0x1, 0x30, 0x1, 0x5, 0x1, 0x1, 0x5, 0x1, 0x2, 0x3d, 0x1, 0x1e, 0x1, 0x4,\n    0x2, 0x2, 0x1, 0x1, 0x2, 0x39, 0x1, 0x2, 0x3, 0x1, 0x1, 0x3, 0x2, 0x30,\n    0x8, 0x8, 0x2, 0x80, 0xab, 0x1, 0x10, 0x2, 0x93, 0x3a, 0x2, 0xa0, 0x77,\n    0xf3, 0x2, 0x2, 0x1, 0x58, 0x2, 0x32, 0x10, 0x80, 0x8e, 0x2, 0x2f, 0x1,\n    0x30, 0x2, 0x4, 0x2, 0x1, 0x4, 0x6e, 0x2, 0x2, 0x2, 0x18, 0x1, 0x2d, 0x1,\n    0x6f, 0x1, 0x2, 0x2, 0x5, 0x1, 0x80, 0xed, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1,\n    0x1, 0xa0, 0x64, 0x13, 0x1, 0x1, 0x1, 0x7f, 0x1, 0x2d, 0x3, 0x4, 0x2, 0x73,\n    0x1, 0x55, 0x1, 0x30, 0x3, 0x9, 0x2, 0x84, 0xeb, 0x1, 0x1, 0x2, 0x6, 0x1,\n    0xa0, 0x58, 0x9a, 0x2e, 0xa0, 0x61, 0xe6, 0x2, 0x6, 0x6];\n_T Lo = [0x80, 0xaa, 0x1, 0xf, 0x1, 0x81, 0x0, 0x1, 0x4, 0x4, 0x80, 0xd0, 0x1,\n    0x83, 0x3b, 0x1b, 0x5, 0x3, 0x2d, 0x20, 0x1, 0xa, 0x23, 0x2, 0x1, 0x63,\n    0x1, 0x1, 0x18, 0x2, 0xa, 0x3, 0x2, 0x1, 0x10, 0x1, 0x1, 0x1e, 0x1d,\n    0x59, 0xb, 0x1, 0x18, 0x21, 0x15, 0x16, 0x2a, 0x19, 0x47, 0x1, 0x1, 0xb,\n    0x57, 0x36, 0x3, 0x1, 0x12, 0x1, 0x7, 0xa, 0x10, 0x6, 0x1, 0x7, 0x5, 0x8,\n    0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x1, 0x3, 0x4, 0x3, 0x1, 0x10, 0x1,\n    0xd, 0x2, 0x1, 0x3, 0xe, 0x2, 0x13, 0x6, 0x4, 0x2, 0x2, 0x16, 0x1, 0x7,\n    0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1f, 0x4, 0x1, 0x1, 0x13, 0x3, 0x10, 0x9,\n    0x1, 0x3, 0x1, 0x16, 0x1, 0x7, 0x1, 0x2, 0x1, 0x5, 0x3, 0x1, 0x12, 0x1,\n    0xf, 0x2, 0x23, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x2, 0x1, 0x5,\n    0x3, 0x1, 0x1e, 0x2, 0x1, 0x3, 0xf, 0x1, 0x11, 0x1, 0x1, 0x6, 0x3, 0x3,\n    0x1, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x2, 0x3, 0x2, 0x3, 0x3, 0x3, 0xc,\n    0x16, 0x1, 0x34, 0x8, 0x1, 0x3, 0x1, 0x17, 0x1, 0xa, 0x1, 0x5, 0x3, 0x1,\n    0x1a, 0x2, 0x6, 0x2, 0x23, 0x8, 0x1, 0x3, 0x1, 0x17, 0x1, 0xa, 0x1, 0x5,\n    0x3, 0x1, 0x20, 0x1, 0x1, 0x2, 0xf, 0x2, 0x12, 0x8, 0x1, 0x3, 0x1, 0x29,\n    0x2, 0x1, 0x10, 0x1, 0x11, 0x2, 0x18, 0x6, 0x5, 0x12, 0x3, 0x18, 0x1, 0x9,\n    0x1, 0x1, 0x2, 0x7, 0x3a, 0x30, 0x1, 0x2, 0xc, 0x6, 0x3b, 0x2, 0x1, 0x1,\n    0x2, 0x2, 0x1, 0x1, 0x2, 0x1, 0x6, 0x4, 0x1, 0x7, 0x1, 0x3, 0x1, 0x1, 0x1,\n    0x1, 0x2, 0x2, 0x1, 0x4, 0x1, 0x2, 0x9, 0x1, 0x2, 0x5, 0x17, 0x4, 0x20,\n    0x1, 0x3f, 0x8, 0x1, 0x24, 0x1b, 0x5, 0x73, 0x2b, 0x14, 0x1, 0x10, 0x6,\n    0x4, 0x4, 0x3, 0x1, 0x3, 0x2, 0x7, 0x3, 0x4, 0xd, 0xc, 0x1, 0x41, 0x2b,\n    0x2, 0x81, 0x4c, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0x29, 0x1,\n    0x4, 0x2, 0x21, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0xf, 0x1,\n    0x39, 0x1, 0x4, 0x2, 0x43, 0x25, 0x10, 0x10, 0x55, 0xc, 0x82, 0x6c, 0x2,\n    0x11, 0x1, 0x1a, 0x5, 0x4b, 0x15, 0xd, 0x1, 0x4, 0xe, 0x12, 0xe, 0x12,\n    0xe, 0xd, 0x1, 0x3, 0xf, 0x34, 0x28, 0x1, 0x43, 0x23, 0x1, 0x34, 0x8,\n    0x29, 0x1, 0x1, 0x5, 0x46, 0xa, 0x1d, 0x33, 0x1e, 0x2, 0x5, 0xb, 0x2c,\n    0x15, 0x7, 0x38, 0x17, 0x9, 0x35, 0x80, 0xb0, 0x2f, 0x11, 0x7, 0x37,\n    0x1e, 0xd, 0x2, 0xa, 0x2c, 0x1a, 0x24, 0x29, 0x3, 0xa, 0x1e, 0x71, 0x4,\n    0x1, 0x4, 0x3, 0x2, 0x84, 0x3e, 0x4, 0x8b, 0xf7, 0x38, 0x18, 0x17, 0x9,\n    0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7,\n    0x82, 0x27, 0x1, 0x35, 0x1, 0x4, 0x56, 0x8, 0x1, 0x1, 0x5a, 0x4, 0x1, 0x5,\n    0x29, 0x3, 0x5e, 0x11, 0x1b, 0x35, 0x10, 0x82, 0x0, 0x99, 0xb6, 0x4a, 0xa0,\n    0x51, 0xcd, 0x33, 0x15, 0x1, 0x84, 0x77, 0x43, 0x28, 0x8, 0x81, 0xc, 0x4,\n    0x10, 0xa, 0x2, 0x42, 0x1, 0x31, 0x46, 0x81, 0x15, 0x7, 0x1, 0x3, 0x1, 0x4,\n    0x1, 0x17, 0x1d, 0x34, 0xe, 0x32, 0x3e, 0x6, 0x3, 0x1, 0xe, 0x1c, 0xa,\n    0x17, 0x19, 0x1d, 0x7, 0x2f, 0x4d, 0x29, 0x17, 0x3, 0x1, 0x8, 0x14, 0x10,\n    0x1, 0x6, 0x3, 0x1, 0x5, 0x30, 0x1, 0x1, 0x3, 0x2, 0x2, 0x5, 0x2, 0x1,\n    0x1, 0x1, 0x18, 0x2, 0x3, 0xb, 0x7, 0x1, 0xe, 0x6, 0x2, 0x6, 0x2, 0x6,\n    0x9, 0x7, 0x1, 0x7, 0x80, 0x91, 0x23, 0x1d, 0xa0, 0x2b, 0xa4, 0xc, 0x17,\n    0x4, 0x31, 0xa0, 0x21, 0x4, 0x81, 0x6e, 0x2, 0x6a, 0x43, 0x1, 0x1, 0xa,\n    0x1, 0xd, 0x1, 0x5, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x6c, 0x21, 0x81,\n    0x6b, 0x12, 0x40, 0x2, 0x36, 0x28, 0xc, 0x74, 0x5, 0x1, 0x80, 0x87, 0x69,\n    0xa, 0x1, 0x2d, 0x2, 0x1f, 0x3, 0x6, 0x2, 0x6, 0x2, 0x6, 0x2, 0x3, 0x23,\n    0xc, 0x1, 0x1a, 0x1, 0x13, 0x1, 0x2, 0x1, 0xf, 0x2, 0xe, 0x22, 0x7b, 0x81,\n    0x85, 0x1d, 0x3, 0x31, 0x2f, 0x1f, 0x11, 0x11, 0x1, 0x8, 0x36, 0x1e, 0x2,\n    0x24, 0x4, 0x8, 0x80, 0x80, 0x4e, 0x83, 0x62, 0x6, 0x2, 0x1, 0x1, 0x2c,\n    0x1, 0x2, 0x3, 0x1, 0x2, 0x17, 0x80, 0xaa, 0x16, 0xa, 0x1a, 0x46, 0x38,\n    0x6, 0x2, 0x40, 0x1, 0xf, 0x4, 0x1, 0x3, 0x1, 0x1b, 0x2c, 0x1d, 0x80, 0x83,\n    0x36, 0xa, 0x16, 0xa, 0x13, 0x80, 0x8d, 0x49, 0x83, 0xba, 0x35, 0x4b, 0x2d,\n    0x20, 0x19, 0x1a, 0x24, 0x5c, 0x30, 0xe, 0x4, 0x84, 0xbb, 0x2b, 0x89, 0x55,\n    0x83, 0x6f, 0x8c, 0x91, 0x84, 0x2f, 0xa0, 0x33, 0xd1, 0x82, 0x39, 0x84,\n    0xc7, 0x45, 0xb, 0x1, 0xa0, 0x40, 0xaf, 0x2, 0xa0, 0x3d, 0xfe, 0x4, 0x1,\n    0x1b, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0xa, 0x1, 0x4, 0x1, 0x1, 0x1,\n    0x1, 0x6, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3, 0x1, 0x2, 0x1, 0x1,\n    0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2,\n    0x4, 0x1, 0x7, 0x1, 0x4, 0x1, 0x4, 0x1, 0x1, 0x1, 0xa, 0x1, 0x11, 0x5,\n    0x3, 0x1, 0x5, 0x1, 0x11, 0x91, 0x44, 0xa0, 0xa6, 0xd7, 0x29, 0x90, 0x35,\n    0xb, 0x80, 0xde, 0xa0, 0x3f, 0xe2, 0x82, 0x1e];\n_T Me = [0x84, 0x88, 0x2, 0x9c, 0x53, 0x4, 0x1, 0x3, 0xa0, 0x85, 0x8b, 0x3];\n_T ID_Start = [\n    0x41, 0x1a, 0x6, 0x1a, 0x2f, 0x1, 0xa, 0x1, 0x4, 0x1, 0x5, 0x17, 0x1, 0x1f,\n    0x1, 0x81, 0xca, 0x4, 0xc, 0xe, 0x5, 0x7, 0x1, 0x1, 0x1, 0x80, 0x81, 0x5,\n    0x1, 0x2, 0x2, 0x4, 0x8, 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x14, 0x1, 0x53,\n    0x1, 0x80, 0x8b, 0x8, 0x80, 0x9e, 0x9, 0x26, 0x2, 0x1, 0x7, 0x27, 0x48,\n    0x1b, 0x5, 0x3, 0x2d, 0x2b, 0x23, 0x2, 0x1, 0x63, 0x1, 0x1, 0xf, 0x2, 0x7,\n    0x2, 0xa, 0x3, 0x2, 0x1, 0x10, 0x1, 0x1, 0x1e, 0x1d, 0x59, 0xb, 0x1,\n    0x18, 0x21, 0x9, 0x2, 0x4, 0x1, 0x5, 0x16, 0x4, 0x1, 0x9, 0x1, 0x3, 0x1,\n    0x17, 0x19, 0x47, 0x1, 0x1, 0xb, 0x57, 0x36, 0x3, 0x1, 0x12, 0x1, 0x7,\n    0xa, 0xf, 0x7, 0x1, 0x7, 0x5, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1,\n    0x1, 0x3, 0x4, 0x3, 0x1, 0x10, 0x1, 0xd, 0x2, 0x1, 0x3, 0xe, 0x2, 0x13,\n    0x6, 0x4, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1f,\n    0x4, 0x1, 0x1, 0x13, 0x3, 0x10, 0x9, 0x1, 0x3, 0x1, 0x16, 0x1, 0x7, 0x1,\n    0x2, 0x1, 0x5, 0x3, 0x1, 0x12, 0x1, 0xf, 0x2, 0x23, 0x8, 0x2, 0x2, 0x2,\n    0x16, 0x1, 0x7, 0x1, 0x2, 0x1, 0x5, 0x3, 0x1, 0x1e, 0x2, 0x1, 0x3, 0xf,\n    0x1, 0x11, 0x1, 0x1, 0x6, 0x3, 0x3, 0x1, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1,\n    0x2, 0x3, 0x2, 0x3, 0x3, 0x3, 0xc, 0x16, 0x1, 0x34, 0x8, 0x1, 0x3, 0x1,\n    0x17, 0x1, 0xa, 0x1, 0x5, 0x3, 0x1, 0x1a, 0x2, 0x6, 0x2, 0x23, 0x8, 0x1,\n    0x3, 0x1, 0x17, 0x1, 0xa, 0x1, 0x5, 0x3, 0x1, 0x20, 0x1, 0x1, 0x2, 0xf,\n    0x2, 0x12, 0x8, 0x1, 0x3, 0x1, 0x29, 0x2, 0x1, 0x10, 0x1, 0x11, 0x2,\n    0x18, 0x6, 0x5, 0x12, 0x3, 0x18, 0x1, 0x9, 0x1, 0x1, 0x2, 0x7, 0x3a, 0x30,\n    0x1, 0x2, 0xc, 0x7, 0x3a, 0x2, 0x1, 0x1, 0x2, 0x2, 0x1, 0x1, 0x2, 0x1,\n    0x6, 0x4, 0x1, 0x7, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x1, 0x4, 0x1,\n    0x2, 0x9, 0x1, 0x2, 0x5, 0x1, 0x1, 0x15, 0x4, 0x20, 0x1, 0x3f, 0x8, 0x1,\n    0x24, 0x1b, 0x5, 0x73, 0x2b, 0x14, 0x1, 0x10, 0x6, 0x4, 0x4, 0x3, 0x1,\n    0x3, 0x2, 0x7, 0x3, 0x4, 0xd, 0xc, 0x1, 0x11, 0x26, 0x1, 0x1, 0x5, 0x1,\n    0x2, 0x2b, 0x1, 0x81, 0x4d, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2,\n    0x29, 0x1, 0x4, 0x2, 0x21, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2,\n    0xf, 0x1, 0x39, 0x1, 0x4, 0x2, 0x43, 0x25, 0x10, 0x10, 0x55, 0xc, 0x82,\n    0x6c, 0x2, 0x11, 0x1, 0x1a, 0x5, 0x4b, 0x3, 0x3, 0xf, 0xd, 0x1, 0x4, 0xe,\n    0x12, 0xe, 0x12, 0xe, 0xd, 0x1, 0x3, 0xf, 0x34, 0x23, 0x1, 0x4, 0x1,\n    0x43, 0x58, 0x8, 0x29, 0x1, 0x1, 0x5, 0x46, 0xa, 0x1d, 0x33, 0x1e, 0x2,\n    0x5, 0xb, 0x2c, 0x15, 0x7, 0x38, 0x17, 0x9, 0x35, 0x52, 0x1, 0x5d, 0x2f,\n    0x11, 0x7, 0x37, 0x1e, 0xd, 0x2, 0xa, 0x2c, 0x1a, 0x24, 0x29, 0x3, 0xa,\n    0x24, 0x6b, 0x4, 0x1, 0x4, 0x3, 0x2, 0x9, 0x80, 0xc0, 0x40, 0x81, 0x16,\n    0x2, 0x6, 0x2, 0x26, 0x2, 0x6, 0x2, 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1f, 0x2, 0x35, 0x1, 0x7, 0x1, 0x1, 0x3, 0x3, 0x1, 0x7, 0x3, 0x4, 0x2,\n    0x6, 0x4, 0xd, 0x5, 0x3, 0x1, 0x7, 0x74, 0x1, 0xd, 0x1, 0x10, 0xd, 0x65,\n    0x1, 0x4, 0x1, 0x2, 0xa, 0x1, 0x1, 0x2, 0x6, 0x6, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x10, 0x2, 0x4, 0x5, 0x5, 0x4, 0x1, 0x11, 0x29, 0x8a, 0x77, 0x2f,\n    0x1, 0x2f, 0x1, 0x80, 0x85, 0x6, 0x4, 0x3, 0x2, 0xc, 0x26, 0x1, 0x1, 0x5,\n    0x1, 0x2, 0x38, 0x7, 0x1, 0x10, 0x17, 0x9, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1,\n    0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x82, 0x26, 0x3, 0x19, 0x9,\n    0x7, 0x5, 0x2, 0x5, 0x4, 0x56, 0x4, 0x5, 0x1, 0x5a, 0x1, 0x4, 0x5, 0x29,\n    0x3, 0x5e, 0x11, 0x1b, 0x35, 0x10, 0x82, 0x0, 0x99, 0xb6, 0x4a, 0xa0, 0x51,\n    0xcd, 0x33, 0x84, 0x8d, 0x43, 0x2e, 0x2, 0x81, 0xd, 0x3, 0x10, 0xa, 0x2,\n    0x14, 0x2f, 0x10, 0x19, 0x8, 0x50, 0x27, 0x9, 0x2, 0x67, 0x2, 0x4, 0x1,\n    0x4, 0xc, 0xb, 0x4d, 0xa, 0x1, 0x3, 0x1, 0x4, 0x1, 0x17, 0x1d, 0x34, 0xe,\n    0x32, 0x3e, 0x6, 0x3, 0x1, 0xe, 0x1c, 0xa, 0x17, 0x19, 0x1d, 0x7, 0x2f,\n    0x1c, 0x1, 0x30, 0x29, 0x17, 0x3, 0x1, 0x8, 0x14, 0x17, 0x3, 0x1, 0x5,\n    0x30, 0x1, 0x1, 0x3, 0x2, 0x2, 0x5, 0x2, 0x1, 0x1, 0x1, 0x18, 0x3, 0x2,\n    0xb, 0x7, 0x3, 0xc, 0x6, 0x2, 0x6, 0x2, 0x6, 0x9, 0x7, 0x1, 0x7, 0x80,\n    0x91, 0x23, 0x1d, 0xa0, 0x2b, 0xa4, 0xc, 0x17, 0x4, 0x31, 0xa0, 0x21, 0x4,\n    0x81, 0x6e, 0x2, 0x6a, 0x26, 0x7, 0xc, 0x5, 0x5, 0x1, 0x1, 0xa, 0x1, 0xd,\n    0x1, 0x5, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x6c, 0x21, 0x81, 0x6b, 0x12,\n    0x40, 0x2, 0x36, 0x28, 0xc, 0x74, 0x5, 0x1, 0x80, 0x87, 0x24, 0x1a, 0x6,\n    0x1a, 0xb, 0x59, 0x3, 0x6, 0x2, 0x6, 0x2, 0x6, 0x2, 0x3, 0x23, 0xc, 0x1,\n    0x1a, 0x1, 0x13, 0x1, 0x2, 0x1, 0xf, 0x2, 0xe, 0x22, 0x7b, 0x45, 0x35,\n    0x81, 0xb, 0x1d, 0x3, 0x31, 0x2f, 0x1f, 0x11, 0x1b, 0x35, 0x1e, 0x2, 0x24,\n    0x4, 0x8, 0x1, 0x5, 0x2a, 0x80, 0x9e, 0x83, 0x62, 0x6, 0x2, 0x1, 0x1,\n    0x2c, 0x1, 0x2, 0x3, 0x1, 0x2, 0x17, 0x80, 0xaa, 0x16, 0xa, 0x1a, 0x46,\n    0x38, 0x6, 0x2, 0x40, 0x1, 0xf, 0x4, 0x1, 0x3, 0x1, 0x1b, 0x2c, 0x1d, 0x80,\n    0x83, 0x36, 0xa, 0x16, 0xa, 0x13, 0x80, 0x8d, 0x49, 0x83, 0xba, 0x35, 0x4b,\n    0x2d, 0x20, 0x19, 0x1a, 0x24, 0x5c, 0x30, 0xe, 0x4, 0x84, 0xbb, 0x2b, 0x89,\n    0x55, 0x83, 0x6f, 0x80, 0x91, 0x63, 0x8b, 0x9d, 0x84, 0x2f, 0xa0, 0x33,\n    0xd1, 0x82, 0x39, 0x84, 0xc7, 0x45, 0xb, 0x1, 0x42, 0xd, 0xa0, 0x40, 0x60,\n    0x2, 0xa0, 0x23, 0xfe, 0x55, 0x1, 0x47, 0x1, 0x2, 0x2, 0x1, 0x2, 0x2, 0x2,\n    0x4, 0x1, 0xc, 0x1, 0x1, 0x1, 0x7, 0x1, 0x41, 0x1, 0x4, 0x2, 0x8, 0x1,\n    0x7, 0x1, 0x1c, 0x1, 0x4, 0x1, 0x5, 0x1, 0x1, 0x3, 0x7, 0x1, 0x81, 0x54,\n    0x2, 0x19, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1,\n    0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x8, 0x96, 0x34, 0x4, 0x1,\n    0x1b, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0xa, 0x1, 0x4, 0x1, 0x1, 0x1,\n    0x1, 0x6, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3, 0x1, 0x2, 0x1, 0x1,\n    0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2,\n    0x4, 0x1, 0x7, 0x1, 0x4, 0x1, 0x4, 0x1, 0x1, 0x1, 0xa, 0x1, 0x11, 0x5,\n    0x3, 0x1, 0x5, 0x1, 0x11, 0x91, 0x44, 0xa0, 0xa6, 0xd7, 0x29, 0x90, 0x35,\n    0xb, 0x80, 0xde, 0xa0, 0x3f, 0xe2, 0x82, 0x1e\n];\n_T Other_Grapheme_Extend = [\n    0x89, 0xbe, 0x1, 0x18, 0x1, 0x81, 0x66, 0x1, 0x18, 0x1, 0x66, 0x1, 0x18,\n    0x1, 0x80, 0xea, 0x1, 0x12, 0x2, 0x67, 0x1, 0x18, 0x1, 0x77, 0x1, 0xf, 0x1,\n    0x92, 0x2c, 0x2, 0x90, 0x20, 0x2, 0xa0, 0xcf, 0x6e, 0x2, 0xa0, 0xd1, 0xc5, 0x1,\n    0x8, 0x5\n];\n_T Lt = [0x81, 0xc5, 0x1, 0x2, 0x1, 0x2, 0x1, 0x26, 0x1, 0x9d, 0x95, 0x8, 0x8,\n    0x8, 0x8, 0x8, 0xc, 0x1, 0xf, 0x1, 0x2f, 0x1];\n_T Pattern_White_Space = [0x9, 0x5, 0x12, 0x1, 0x64, 0x1, 0x9f, 0x88, 0x2, 0x18, 0x2];\n_T Cased = [0x41, 0x1a, 0x6, 0x1a, 0x2f, 0x1, 0xa, 0x1, 0x4, 0x1, 0x5, 0x17,\n    0x1, 0x1f, 0x1, 0x80, 0xc3, 0x1, 0x4, 0x4, 0x80, 0xd0, 0x1, 0x24, 0x7, 0x2,\n    0x1e, 0x5, 0x60, 0x1, 0x2a, 0x4, 0x2, 0x2, 0x2, 0x4, 0x8, 0x1, 0x1, 0x3,\n    0x1, 0x1, 0x1, 0x14, 0x1, 0x53, 0x1, 0x80, 0x8b, 0x8, 0x80, 0x9e, 0x9,\n    0x26, 0xa, 0x27, 0x8b, 0x18, 0x26, 0x1, 0x1, 0x5, 0x1, 0x8c, 0x32, 0x80,\n    0xc0, 0x40, 0x81, 0x16, 0x2, 0x6, 0x2, 0x26, 0x2, 0x6, 0x2, 0x8, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1f, 0x2, 0x35, 0x1, 0x7, 0x1, 0x1, 0x3, 0x3,\n    0x1, 0x7, 0x3, 0x4, 0x2, 0x6, 0x4, 0xd, 0x5, 0x3, 0x1, 0x7, 0x74, 0x1, 0xd,\n    0x1, 0x10, 0xd, 0x65, 0x1, 0x4, 0x1, 0x2, 0xa, 0x1, 0x1, 0x3, 0x5, 0x6,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x1, 0x6, 0x4, 0x1, 0x2, 0x4, 0x5,\n    0x5, 0x4, 0x1, 0x11, 0x20, 0x3, 0x2, 0x83, 0x31, 0x34, 0x87, 0x16, 0x2f,\n    0x1, 0x2f, 0x1, 0x80, 0x85, 0x6, 0x4, 0x3, 0x2, 0xc, 0x26, 0x1, 0x1, 0x5,\n    0x1, 0xa0, 0x79, 0x12, 0x2e, 0x12, 0x18, 0x80, 0x8a, 0x66, 0x3, 0x4, 0x1,\n    0x4, 0xc, 0xb, 0x4d, 0x3, 0xa0, 0x53, 0x5, 0x7, 0xc, 0x5, 0x84, 0x9, 0x1a,\n    0x6, 0x1a, 0x84, 0xa5, 0x50, 0xa0, 0xcf, 0xb0, 0x55, 0x1, 0x47, 0x1, 0x2,\n    0x2, 0x1, 0x2, 0x2, 0x2, 0x4, 0x1, 0xc, 0x1, 0x1, 0x1, 0x7, 0x1, 0x41,\n    0x1, 0x4, 0x2, 0x8, 0x1, 0x7, 0x1, 0x1c, 0x1, 0x4, 0x1, 0x5, 0x1, 0x1, 0x3,\n    0x7, 0x1, 0x81, 0x54, 0x2, 0x19, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1,\n    0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x8];\n_T Mn = [0x83, 0x0, 0x70, 0x81, 0x13, 0x5, 0x81, 0x9, 0x2d, 0x1, 0x1, 0x1,\n    0x2, 0x1, 0x2, 0x1, 0x1, 0x48, 0xb, 0x30, 0x15, 0x10, 0x1, 0x65, 0x7, 0x2,\n    0x6, 0x2, 0x2, 0x1, 0x4, 0x23, 0x1, 0x1e, 0x1b, 0x5b, 0xb, 0x3a, 0x9,\n    0x22, 0x4, 0x1, 0x9, 0x1, 0x3, 0x1, 0x5, 0x2b, 0x3, 0x80, 0x88, 0x1b,\n    0x1, 0x3, 0x37, 0x1, 0x1, 0x1, 0x4, 0x8, 0x4, 0x1, 0x3, 0x7, 0xa, 0x2,\n    0x1d, 0x1, 0x3a, 0x1, 0x4, 0x4, 0x8, 0x1, 0x14, 0x2, 0x1d, 0x2, 0x39, 0x1,\n    0x4, 0x2, 0x4, 0x2, 0x2, 0x3, 0x3, 0x1, 0x1e, 0x2, 0x3, 0x1, 0xb, 0x2,\n    0x39, 0x1, 0x4, 0x5, 0x1, 0x2, 0x4, 0x1, 0x14, 0x2, 0x1d, 0x1, 0x3a, 0x1,\n    0x2, 0x1, 0x1, 0x4, 0x8, 0x1, 0x8, 0x1, 0xb, 0x2, 0x1e, 0x1, 0x3d, 0x1,\n    0xc, 0x1, 0x70, 0x3, 0x5, 0x3, 0x1, 0x4, 0x7, 0x2, 0xb, 0x2, 0x58, 0x1,\n    0x2, 0x1, 0x6, 0x1, 0x5, 0x2, 0x14, 0x2, 0x5d, 0x4, 0x8, 0x1, 0x14, 0x2,\n    0x66, 0x1, 0x7, 0x3, 0x1, 0x1, 0x5a, 0x1, 0x2, 0x7, 0xc, 0x8, 0x62, 0x1,\n    0x2, 0x6, 0x1, 0x2, 0xb, 0x6, 0x4a, 0x2, 0x1b, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x37, 0xe, 0x1, 0x5, 0x1, 0x2, 0x5, 0xb, 0x1, 0x24, 0x9, 0x1, 0x66, 0x4,\n    0x1, 0x6, 0x1, 0x2, 0x2, 0x2, 0x19, 0x2, 0x4, 0x3, 0x10, 0x4, 0xd, 0x1,\n    0x2, 0x2, 0x6, 0x1, 0xf, 0x1, 0x82, 0xbf, 0x3, 0x83, 0xb2, 0x3, 0x1d,\n    0x3, 0x1d, 0x2, 0x1e, 0x2, 0x40, 0x2, 0x1, 0x7, 0x8, 0x1, 0x2, 0xb, 0x9,\n    0x1, 0x2d, 0x3, 0x80, 0x9b, 0x1, 0x76, 0x3, 0x4, 0x2, 0x9, 0x1, 0x6, 0x3,\n    0x80, 0xdb, 0x2, 0x2, 0x1, 0x3a, 0x1, 0x1, 0x7, 0x1, 0x1, 0x1, 0x1, 0x2,\n    0x8, 0x6, 0xa, 0x2, 0x1, 0x80, 0x80, 0x4, 0x30, 0x1, 0x1, 0x5, 0x1, 0x1,\n    0x5, 0x1, 0x28, 0x9, 0xc, 0x2, 0x20, 0x4, 0x2, 0x2, 0x1, 0x1, 0x3a, 0x1,\n    0x1, 0x2, 0x3, 0x1, 0x1, 0x3, 0x3a, 0x8, 0x2, 0x2, 0x80, 0x98, 0x3, 0x1,\n    0xd, 0x1, 0x7, 0x4, 0x1, 0x6, 0x1, 0x80, 0xcb, 0x27, 0x15, 0x4, 0x82,\n    0xd0, 0xd, 0x4, 0x1, 0x3, 0xc, 0x8b, 0xfe, 0x3, 0x80, 0x8d, 0x1, 0x60,\n    0x20, 0x82, 0x2a, 0x4, 0x6b, 0x2, 0xa0, 0x75, 0xd4, 0x1, 0x4, 0xa, 0x21,\n    0x1, 0x50, 0x2, 0x81, 0x10, 0x1, 0x3, 0x1, 0x4, 0x1, 0x19, 0x2, 0x80, 0x9d,\n    0x1, 0x1b, 0x12, 0x34, 0x8, 0x19, 0xb, 0x2e, 0x3, 0x30, 0x1, 0x2, 0x4,\n    0x2, 0x1, 0x6c, 0x6, 0x2, 0x2, 0x2, 0x2, 0xc, 0x1, 0x8, 0x1, 0x63, 0x1,\n    0x1, 0x3, 0x2, 0x2, 0x5, 0x2, 0x1, 0x1, 0x2a, 0x2, 0x8, 0x1, 0x80, 0xee,\n    0x1, 0x2, 0x1, 0x4, 0x1, 0xa0, 0x4f, 0x30, 0x1, 0x82, 0xe1, 0x10, 0x10,\n    0x7, 0x83, 0xd6, 0x1, 0x88, 0x3, 0x3, 0x1, 0x2, 0x5, 0x4, 0x28, 0x3, 0x4,\n    0x1, 0x85, 0xc1, 0x1, 0x36, 0xf, 0x39, 0x2, 0x31, 0x4, 0x2, 0x2, 0x45,\n    0x3, 0x24, 0x5, 0x1, 0x8, 0x4b, 0x2, 0x34, 0x9, 0x84, 0xec, 0x1, 0x1, 0x1,\n    0x2, 0x6, 0x1, 0x1, 0xa0, 0x58, 0xd7, 0x4, 0xa0, 0x61, 0xd4, 0x3, 0x11,\n    0x8, 0x2, 0x7, 0x1e, 0x4, 0x80, 0x94, 0x3, 0xac, 0x2e, 0xbb, 0x80, 0xf0];\n_T Dash = [0x2d, 0x1, 0x85, 0x5c, 0x1, 0x33, 0x1, 0x8e, 0x41, 0x1, 0x84, 0x5,\n    0x1, 0x88, 0x9, 0x6, 0x3d, 0x1, 0x27, 0x1, 0xf, 0x1, 0x81, 0x86, 0x1,\n    0x8c, 0x4, 0x1, 0x2, 0x1, 0x1f, 0x2, 0x81, 0xe0, 0x1, 0x13, 0x1, 0x6f, 0x1,\n    0xa0, 0xcd, 0x90, 0x2, 0x25, 0x1, 0xa, 0x1, 0x80, 0xa9, 0x1];\n_T ID_Continue = [\n    0x30, 0xa, 0x7, 0x1a, 0x4, 0x1, 0x1, 0x1a, 0x2f, 0x1, 0xa, 0x1, 0x1, 0x1,\n    0x2, 0x1, 0x5, 0x17, 0x1, 0x1f, 0x1, 0x81, 0xca, 0x4, 0xc, 0xe, 0x5, 0x7,\n    0x1, 0x1, 0x1, 0x11, 0x75, 0x1, 0x2, 0x2, 0x4, 0x8, 0x5, 0x1, 0x1, 0x1,\n    0x14, 0x1, 0x53, 0x1, 0x80, 0x8b, 0x1, 0x5, 0x2, 0x80, 0x9e, 0x9, 0x26,\n    0x2, 0x1, 0x7, 0x27, 0x9, 0x2d, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x1,\n    0x8, 0x1b, 0x5, 0x3, 0x1d, 0xb, 0x5, 0x4a, 0x4, 0x66, 0x1, 0x8, 0x2, 0xa,\n    0x1, 0x13, 0x2, 0x1, 0x10, 0x3b, 0x2, 0x65, 0xe, 0x36, 0x4, 0x1, 0x5, 0x2e,\n    0x12, 0x1c, 0x44, 0x1, 0x1, 0xb, 0x37, 0x1b, 0x1, 0x64, 0x2, 0xa, 0x1,\n    0x7, 0x1, 0x7, 0x1, 0x3, 0x1, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1,\n    0x1, 0x3, 0x4, 0x2, 0x9, 0x2, 0x2, 0x2, 0x4, 0x8, 0x1, 0x4, 0x2, 0x1, 0x5,\n    0x2, 0xc, 0xf, 0x3, 0x1, 0x6, 0x4, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x2,\n    0x1, 0x2, 0x1, 0x2, 0x2, 0x1, 0x1, 0x5, 0x4, 0x2, 0x2, 0x3, 0x3, 0x1, 0x7,\n    0x4, 0x1, 0x1, 0x7, 0x10, 0xb, 0x3, 0x1, 0x9, 0x1, 0x3, 0x1, 0x16, 0x1,\n    0x7, 0x1, 0x2, 0x1, 0x5, 0x2, 0xa, 0x1, 0x3, 0x1, 0x3, 0x2, 0x1, 0xf,\n    0x4, 0x2, 0xa, 0x11, 0x3, 0x1, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1,\n    0x2, 0x1, 0x5, 0x2, 0x9, 0x2, 0x2, 0x2, 0x3, 0x8, 0x2, 0x4, 0x2, 0x1, 0x5,\n    0x2, 0xa, 0x1, 0x1, 0x10, 0x2, 0x1, 0x6, 0x3, 0x3, 0x1, 0x4, 0x3, 0x2,\n    0x1, 0x1, 0x1, 0x2, 0x3, 0x2, 0x3, 0x3, 0x3, 0xc, 0x4, 0x5, 0x3, 0x3, 0x1,\n    0x4, 0x2, 0x1, 0x6, 0x1, 0xe, 0xa, 0x11, 0x3, 0x1, 0x8, 0x1, 0x3, 0x1,\n    0x17, 0x1, 0xa, 0x1, 0x5, 0x3, 0x8, 0x1, 0x3, 0x1, 0x4, 0x7, 0x2, 0x1,\n    0x2, 0x6, 0x4, 0x2, 0xa, 0x12, 0x2, 0x1, 0x8, 0x1, 0x3, 0x1, 0x17, 0x1,\n    0xa, 0x1, 0x5, 0x2, 0x9, 0x1, 0x3, 0x1, 0x4, 0x7, 0x2, 0x7, 0x1, 0x1, 0x4,\n    0x2, 0xa, 0x1, 0x2, 0xf, 0x2, 0x1, 0x8, 0x1, 0x3, 0x1, 0x29, 0x2, 0x8,\n    0x1, 0x3, 0x1, 0x5, 0x8, 0x1, 0x8, 0x4, 0x2, 0xa, 0xa, 0x6, 0x2, 0x2,\n    0x1, 0x12, 0x3, 0x18, 0x1, 0x9, 0x1, 0x1, 0x2, 0x7, 0x3, 0x1, 0x4, 0x6,\n    0x1, 0x1, 0x1, 0x8, 0x12, 0x2, 0xd, 0x3a, 0x5, 0xf, 0x1, 0xa, 0x27, 0x2,\n    0x1, 0x1, 0x2, 0x2, 0x1, 0x1, 0x2, 0x1, 0x6, 0x4, 0x1, 0x7, 0x1, 0x3, 0x1,\n    0x1, 0x1, 0x1, 0x2, 0x2, 0x1, 0xd, 0x1, 0x3, 0x2, 0x5, 0x1, 0x1, 0x1, 0x6,\n    0x2, 0xa, 0x2, 0x4, 0x20, 0x1, 0x17, 0x2, 0x6, 0xa, 0xb, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x4, 0xa, 0x1, 0x24, 0x4, 0x14, 0x1, 0x12, 0x1, 0x24, 0x9, 0x1,\n    0x39, 0x4a, 0x6, 0x4e, 0x2, 0x26, 0x1, 0x1, 0x5, 0x1, 0x2, 0x2b, 0x1,\n    0x81, 0x4d, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0x29, 0x1, 0x4,\n    0x2, 0x21, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0xf, 0x1, 0x39,\n    0x1, 0x4, 0x2, 0x43, 0x2, 0x3, 0x9, 0x9, 0xe, 0x10, 0x10, 0x55, 0xc,\n    0x82, 0x6c, 0x2, 0x11, 0x1, 0x1a, 0x5, 0x4b, 0x3, 0x3, 0xf, 0xd, 0x1,\n    0x7, 0xb, 0x15, 0xb, 0x14, 0xc, 0xd, 0x1, 0x3, 0x1, 0x2, 0xc, 0x54, 0x3,\n    0x1, 0x4, 0x2, 0x2, 0xa, 0x21, 0x3, 0x2, 0xa, 0x6, 0x58, 0x8, 0x2b, 0x5,\n    0x46, 0xa, 0x1d, 0x3, 0xc, 0x4, 0xc, 0xa, 0x28, 0x2, 0x5, 0xb, 0x2c, 0x4,\n    0x1a, 0x6, 0xb, 0x25, 0x1c, 0x4, 0x3f, 0x1, 0x1d, 0x2, 0xb, 0x6, 0xa,\n    0xd, 0x1, 0x58, 0x4c, 0x4, 0xa, 0x11, 0x9, 0xc, 0x74, 0xc, 0x38, 0x8,\n    0xa, 0x3, 0x31, 0x52, 0x3, 0x1, 0x23, 0x9, 0x80, 0xe7, 0x15, 0x81, 0x1a,\n    0x2, 0x6, 0x2, 0x26, 0x2, 0x6, 0x2, 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1f, 0x2, 0x35, 0x1, 0x7, 0x1, 0x1, 0x3, 0x3, 0x1, 0x7, 0x3, 0x4, 0x2,\n    0x6, 0x4, 0xd, 0x5, 0x3, 0x1, 0x7, 0x42, 0x2, 0x13, 0x1, 0x1c, 0x1, 0xd,\n    0x1, 0x10, 0xd, 0x33, 0xd, 0x4, 0x1, 0x3, 0xc, 0x11, 0x1, 0x4, 0x1, 0x2,\n    0xa, 0x1, 0x1, 0x2, 0x6, 0x6, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x10, 0x2,\n    0x4, 0x5, 0x5, 0x4, 0x1, 0x11, 0x29, 0x8a, 0x77, 0x2f, 0x1, 0x2f, 0x1,\n    0x80, 0x85, 0x6, 0x9, 0xc, 0x26, 0x1, 0x1, 0x5, 0x1, 0x2, 0x38, 0x7, 0x1,\n    0xf, 0x18, 0x9, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7,\n    0x1, 0x7, 0x1, 0x7, 0x1, 0x20, 0x82, 0x5, 0x3, 0x19, 0xf, 0x1, 0x5, 0x2,\n    0x5, 0x4, 0x56, 0x2, 0x7, 0x1, 0x5a, 0x1, 0x4, 0x5, 0x29, 0x3, 0x5e, 0x11,\n    0x1b, 0x35, 0x10, 0x82, 0x0, 0x99, 0xb6, 0x4a, 0xa0, 0x51, 0xcd, 0x33,\n    0x84, 0x8d, 0x43, 0x2e, 0x2, 0x81, 0xd, 0x3, 0x1c, 0x14, 0x30, 0x4, 0xa,\n    0x1, 0x19, 0x7, 0x53, 0x25, 0x9, 0x2, 0x67, 0x2, 0x4, 0x1, 0x4, 0xc, 0xb,\n    0x4d, 0x30, 0x18, 0x34, 0xc, 0x45, 0xb, 0xa, 0x6, 0x18, 0x3, 0x1, 0x4,\n    0x2e, 0x2, 0x24, 0xc, 0x1d, 0x3, 0x41, 0xe, 0xb, 0x26, 0x37, 0x9, 0xe,\n    0x2, 0xa, 0x6, 0x17, 0x3, 0x2, 0x4, 0x43, 0x18, 0x3, 0x2, 0x10, 0x2, 0x5,\n    0xa, 0x6, 0x2, 0x6, 0x2, 0x6, 0x9, 0x7, 0x1, 0x7, 0x80, 0x91, 0x2b, 0x1,\n    0x2, 0x2, 0xa, 0x6, 0xa0, 0x2b, 0xa4, 0xc, 0x17, 0x4, 0x31, 0xa0, 0x21,\n    0x4, 0x81, 0x6e, 0x2, 0x6a, 0x26, 0x7, 0xc, 0x5, 0x5, 0xc, 0x1, 0xd, 0x1,\n    0x5, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x6c, 0x21, 0x81, 0x6b, 0x12, 0x40,\n    0x2, 0x36, 0x28, 0xc, 0x4, 0x10, 0x10, 0x7, 0xc, 0x2, 0x18, 0x3, 0x20, 0x5,\n    0x1, 0x80, 0x87, 0x13, 0xa, 0x7, 0x1a, 0x4, 0x1, 0x1, 0x1a, 0xb, 0x59,\n    0x3, 0x6, 0x2, 0x6, 0x2, 0x6, 0x2, 0x3, 0x23, 0xc, 0x1, 0x1a, 0x1, 0x13,\n    0x1, 0x2, 0x1, 0xf, 0x2, 0xe, 0x22, 0x7b, 0x45, 0x35, 0x80, 0x88, 0x1,\n    0x80, 0x82, 0x1d, 0x3, 0x31, 0x2f, 0x1f, 0x11, 0x1b, 0x35, 0x1e, 0x2,\n    0x24, 0x4, 0x8, 0x1, 0x5, 0x2a, 0x80, 0x9e, 0x2, 0xa, 0x83, 0x56, 0x6,\n    0x2, 0x1, 0x1, 0x2c, 0x1, 0x2, 0x3, 0x1, 0x2, 0x17, 0x80, 0xaa, 0x16, 0xa,\n    0x1a, 0x46, 0x38, 0x6, 0x2, 0x40, 0x4, 0x1, 0x2, 0x5, 0x8, 0x1, 0x3, 0x1,\n    0x1b, 0x4, 0x3, 0x4, 0x1, 0x20, 0x1d, 0x80, 0x83, 0x36, 0xa, 0x16, 0xa,\n    0x13, 0x80, 0x8d, 0x49, 0x83, 0xb7, 0x47, 0x1f, 0xa, 0x10, 0x3b, 0x15,\n    0x19, 0x7, 0xa, 0x6, 0x35, 0x1, 0xa, 0x40, 0x45, 0xb, 0xa, 0x84, 0xa6,\n    0x38, 0x8, 0xa, 0x89, 0x36, 0x83, 0x6f, 0x80, 0x91, 0x63, 0x8b, 0x9d, 0x84,\n    0x2f, 0xa0, 0x33, 0xd1, 0x82, 0x39, 0x84, 0xc7, 0x45, 0xb, 0x2f, 0x10,\n    0x11, 0xa0, 0x40, 0x60, 0x2, 0xa0, 0x21, 0x63, 0x5, 0x3, 0x6, 0x8, 0x8,\n    0x2, 0x7, 0x1e, 0x4, 0x80, 0x94, 0x3, 0x81, 0xbb, 0x55, 0x1, 0x47, 0x1,\n    0x2, 0x2, 0x1, 0x2, 0x2, 0x2, 0x4, 0x1, 0xc, 0x1, 0x1, 0x1, 0x7, 0x1,\n    0x41, 0x1, 0x4, 0x2, 0x8, 0x1, 0x7, 0x1, 0x1c, 0x1, 0x4, 0x1, 0x5, 0x1,\n    0x1, 0x3, 0x7, 0x1, 0x81, 0x54, 0x2, 0x19, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19,\n    0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x8,\n    0x2, 0x32, 0x96, 0x0, 0x4, 0x1, 0x1b, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1,\n    0xa, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x6, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x3, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x4, 0x1, 0x7, 0x1, 0x4, 0x1, 0x4, 0x1,\n    0x1, 0x1, 0xa, 0x1, 0x11, 0x5, 0x3, 0x1, 0x5, 0x1, 0x11, 0x91, 0x44, 0xa0,\n    0xa6, 0xd7, 0x29, 0x90, 0x35, 0xb, 0x80, 0xde, 0xa0, 0x3f, 0xe2, 0x82,\n    0x1e, 0xab, 0x6, 0xe2, 0x80, 0xf0\n];\n_T White_Space = [\n    0x9, 0x5, 0x12, 0x1, 0x64, 0x1, 0x1a, 0x1, 0x95, 0xdf, 0x1, 0x89, 0x7f,\n    0xb, 0x1d, 0x2, 0x5, 0x1, 0x2f, 0x1, 0x8f, 0xa0, 0x1\n];\n_T Grapheme_Link = [\n    0x89, 0x4d, 0x1, 0x7f, 0x1, 0x7f, 0x1, 0x7f, 0x1, 0x7f, 0x1, 0x7f, 0x1,\n    0x7f, 0x1, 0x7f, 0x1, 0x7f, 0x1, 0x7c, 0x1, 0x6f, 0x1, 0x81, 0x49, 0x1,\n    0x80, 0xb4, 0x2, 0x86, 0xd9, 0x1, 0x1f, 0x1, 0x80, 0x9d, 0x1, 0x82, 0x8d,\n    0x1, 0x80, 0xe3, 0x1, 0x65, 0x2, 0x46, 0x2, 0x91, 0x8b, 0x1, 0xa0, 0x7a,\n    0x86, 0x1, 0x80, 0xbd, 0x1, 0x80, 0x8e, 0x1, 0x6c, 0x1, 0x81, 0x35, 0x1,\n    0x80, 0xf6, 0x1, 0xa0, 0x5e, 0x51, 0x1, 0x86, 0x6, 0x1, 0x72, 0x1, 0x79,\n    0x2, 0x80, 0x8b, 0x1, 0x84, 0xf5, 0x1\n];\n_T Ll = [0x61, 0x1a, 0x3a, 0x1, 0x29, 0x18, 0x1, 0x8, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x3, 0x2,\n    0x1, 0x1, 0x1, 0x2, 0x1, 0x3, 0x2, 0x4, 0x1, 0x2, 0x1, 0x3, 0x3, 0x2, 0x1,\n    0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x3,\n    0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x3, 0x6, 0x1, 0x2, 0x1, 0x2, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x2, 0x2, 0x1, 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x7, 0x2, 0x1, 0x2, 0x2, 0x1, 0x1, 0x4, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x45, 0x1, 0x1b, 0x80, 0xc1, 0x1, 0x1, 0x1,\n    0x3, 0x1, 0x3, 0x3, 0x12, 0x1, 0x1b, 0x23, 0x1, 0x2, 0x3, 0x3, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x5, 0x1, 0x1, 0x2, 0x1, 0x2, 0x2, 0x33,\n    0x30, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x9, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x39, 0x27,\n    0x97, 0x78, 0x2c, 0x3f, 0xd, 0x1, 0x22, 0x66, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x9, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x9, 0x8, 0x6, 0xa, 0x8, 0x8, 0x8, 0x8, 0x6, 0xa, 0x8, 0x8, 0x8, 0x8,\n    0xe, 0x2, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x5, 0x1, 0x2, 0x6, 0x1, 0x3, 0x3,\n    0x1, 0x2, 0x8, 0x4, 0x2, 0x2, 0x8, 0x8, 0xa, 0x3, 0x1, 0x2, 0x81, 0x12,\n    0x1, 0x3, 0x2, 0x3, 0x1, 0x1b, 0x1, 0x4, 0x1, 0x4, 0x1, 0x2, 0x2, 0x8,\n    0x4, 0x4, 0x1, 0x35, 0x1, 0x8a, 0xab, 0x2f, 0x2, 0x1, 0x3, 0x2, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x4, 0x1, 0x1, 0x2, 0x1, 0x6, 0x5, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x1, 0xc, 0x26, 0x1, 0x1,\n    0x5, 0x1, 0xa0, 0x79, 0x13, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x13, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x80, 0x8b, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x8, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0xd,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x50, 0x1, 0xa0, 0x53, 0x5,\n    0x7, 0xc, 0x5, 0x84, 0x29, 0x1a, 0x84, 0xcd, 0x28, 0xa0, 0xcf, 0xca,\n    0x1a, 0x1a, 0x7, 0x1, 0x12, 0x1a, 0x1a, 0x1a, 0x4, 0x1, 0x1, 0x1, 0x7, 0x1,\n    0xb, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,\n    0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1c, 0x1c, 0x19, 0x1, 0x6, 0x1a, 0x19,\n    0x1, 0x6, 0x1a, 0x19, 0x1, 0x6, 0x1a, 0x19, 0x1, 0x6, 0x1a, 0x19, 0x1, 0x6, 0x1,\n    0x1];\n_T Cc = [0x0, 0x20, 0x5f, 0x21];\n_T Pattern_Syntax = [\n    0x21, 0xf, 0xa, 0x7, 0x1a, 0x4, 0x1, 0x1, 0x1a, 0x4, 0x22, 0x7, 0x1, 0x1,\n    0x1, 0x2, 0x1, 0x1, 0x1, 0x2, 0x4, 0x1, 0x4, 0x1, 0x3, 0x1, 0x17, 0x1,\n    0x1f, 0x1, 0x9f, 0x18, 0x18, 0x8, 0xf, 0x2, 0x13, 0x1, 0xa, 0x81, 0x31,\n    0x82, 0xd0, 0x80, 0xa0, 0x82, 0x76, 0x1e, 0x84, 0x6c, 0x82, 0x0, 0x80,\n    0x80, 0x81, 0x81, 0x3, 0x4, 0x19, 0xf, 0x1, 0xa0, 0xcd, 0xd, 0x2, 0x81, 0x5, 0x2\n];\n_T XID_Continue = [\n    0x30, 0xa, 0x7, 0x1a, 0x4, 0x1, 0x1, 0x1a, 0x2f, 0x1, 0xa, 0x1, 0x1, 0x1,\n    0x2, 0x1, 0x5, 0x17, 0x1, 0x1f, 0x1, 0x81, 0xca, 0x4, 0xc, 0xe, 0x5, 0x7,\n    0x1, 0x1, 0x1, 0x11, 0x75, 0x1, 0x2, 0x3, 0x3, 0x8, 0x5, 0x1, 0x1, 0x1,\n    0x14, 0x1, 0x53, 0x1, 0x80, 0x8b, 0x1, 0x5, 0x2, 0x80, 0x9e, 0x9, 0x26,\n    0x2, 0x1, 0x7, 0x27, 0x9, 0x2d, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x1,\n    0x8, 0x1b, 0x5, 0x3, 0x1d, 0xb, 0x5, 0x4a, 0x4, 0x66, 0x1, 0x8, 0x2, 0xa,\n    0x1, 0x13, 0x2, 0x1, 0x10, 0x3b, 0x2, 0x65, 0xe, 0x36, 0x4, 0x1, 0x5, 0x2e,\n    0x12, 0x1c, 0x44, 0x1, 0x1, 0xb, 0x37, 0x1b, 0x1, 0x64, 0x2, 0xa, 0x1,\n    0x7, 0x1, 0x7, 0x1, 0x3, 0x1, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1,\n    0x1, 0x3, 0x4, 0x2, 0x9, 0x2, 0x2, 0x2, 0x4, 0x8, 0x1, 0x4, 0x2, 0x1, 0x5,\n    0x2, 0xc, 0xf, 0x3, 0x1, 0x6, 0x4, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x2,\n    0x1, 0x2, 0x1, 0x2, 0x2, 0x1, 0x1, 0x5, 0x4, 0x2, 0x2, 0x3, 0x3, 0x1, 0x7,\n    0x4, 0x1, 0x1, 0x7, 0x10, 0xb, 0x3, 0x1, 0x9, 0x1, 0x3, 0x1, 0x16, 0x1,\n    0x7, 0x1, 0x2, 0x1, 0x5, 0x2, 0xa, 0x1, 0x3, 0x1, 0x3, 0x2, 0x1, 0xf,\n    0x4, 0x2, 0xa, 0x11, 0x3, 0x1, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1,\n    0x2, 0x1, 0x5, 0x2, 0x9, 0x2, 0x2, 0x2, 0x3, 0x8, 0x2, 0x4, 0x2, 0x1, 0x5,\n    0x2, 0xa, 0x1, 0x1, 0x10, 0x2, 0x1, 0x6, 0x3, 0x3, 0x1, 0x4, 0x3, 0x2,\n    0x1, 0x1, 0x1, 0x2, 0x3, 0x2, 0x3, 0x3, 0x3, 0xc, 0x4, 0x5, 0x3, 0x3, 0x1,\n    0x4, 0x2, 0x1, 0x6, 0x1, 0xe, 0xa, 0x11, 0x3, 0x1, 0x8, 0x1, 0x3, 0x1,\n    0x17, 0x1, 0xa, 0x1, 0x5, 0x3, 0x8, 0x1, 0x3, 0x1, 0x4, 0x7, 0x2, 0x1,\n    0x2, 0x6, 0x4, 0x2, 0xa, 0x12, 0x2, 0x1, 0x8, 0x1, 0x3, 0x1, 0x17, 0x1,\n    0xa, 0x1, 0x5, 0x2, 0x9, 0x1, 0x3, 0x1, 0x4, 0x7, 0x2, 0x7, 0x1, 0x1, 0x4,\n    0x2, 0xa, 0x1, 0x2, 0xf, 0x2, 0x1, 0x8, 0x1, 0x3, 0x1, 0x29, 0x2, 0x8,\n    0x1, 0x3, 0x1, 0x5, 0x8, 0x1, 0x8, 0x4, 0x2, 0xa, 0xa, 0x6, 0x2, 0x2,\n    0x1, 0x12, 0x3, 0x18, 0x1, 0x9, 0x1, 0x1, 0x2, 0x7, 0x3, 0x1, 0x4, 0x6,\n    0x1, 0x1, 0x1, 0x8, 0x12, 0x2, 0xd, 0x3a, 0x5, 0xf, 0x1, 0xa, 0x27, 0x2,\n    0x1, 0x1, 0x2, 0x2, 0x1, 0x1, 0x2, 0x1, 0x6, 0x4, 0x1, 0x7, 0x1, 0x3, 0x1,\n    0x1, 0x1, 0x1, 0x2, 0x2, 0x1, 0xd, 0x1, 0x3, 0x2, 0x5, 0x1, 0x1, 0x1, 0x6,\n    0x2, 0xa, 0x2, 0x4, 0x20, 0x1, 0x17, 0x2, 0x6, 0xa, 0xb, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x4, 0xa, 0x1, 0x24, 0x4, 0x14, 0x1, 0x12, 0x1, 0x24, 0x9, 0x1,\n    0x39, 0x4a, 0x6, 0x4e, 0x2, 0x26, 0x1, 0x1, 0x5, 0x1, 0x2, 0x2b, 0x1,\n    0x81, 0x4d, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0x29, 0x1, 0x4,\n    0x2, 0x21, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0xf, 0x1, 0x39,\n    0x1, 0x4, 0x2, 0x43, 0x2, 0x3, 0x9, 0x9, 0xe, 0x10, 0x10, 0x55, 0xc,\n    0x82, 0x6c, 0x2, 0x11, 0x1, 0x1a, 0x5, 0x4b, 0x3, 0x3, 0xf, 0xd, 0x1,\n    0x7, 0xb, 0x15, 0xb, 0x14, 0xc, 0xd, 0x1, 0x3, 0x1, 0x2, 0xc, 0x54, 0x3,\n    0x1, 0x4, 0x2, 0x2, 0xa, 0x21, 0x3, 0x2, 0xa, 0x6, 0x58, 0x8, 0x2b, 0x5,\n    0x46, 0xa, 0x1d, 0x3, 0xc, 0x4, 0xc, 0xa, 0x28, 0x2, 0x5, 0xb, 0x2c, 0x4,\n    0x1a, 0x6, 0xb, 0x25, 0x1c, 0x4, 0x3f, 0x1, 0x1d, 0x2, 0xb, 0x6, 0xa,\n    0xd, 0x1, 0x58, 0x4c, 0x4, 0xa, 0x11, 0x9, 0xc, 0x74, 0xc, 0x38, 0x8,\n    0xa, 0x3, 0x31, 0x52, 0x3, 0x1, 0x23, 0x9, 0x80, 0xe7, 0x15, 0x81, 0x1a,\n    0x2, 0x6, 0x2, 0x26, 0x2, 0x6, 0x2, 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1f, 0x2, 0x35, 0x1, 0x7, 0x1, 0x1, 0x3, 0x3, 0x1, 0x7, 0x3, 0x4, 0x2,\n    0x6, 0x4, 0xd, 0x5, 0x3, 0x1, 0x7, 0x42, 0x2, 0x13, 0x1, 0x1c, 0x1, 0xd,\n    0x1, 0x10, 0xd, 0x33, 0xd, 0x4, 0x1, 0x3, 0xc, 0x11, 0x1, 0x4, 0x1, 0x2,\n    0xa, 0x1, 0x1, 0x2, 0x6, 0x6, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x10, 0x2,\n    0x4, 0x5, 0x5, 0x4, 0x1, 0x11, 0x29, 0x8a, 0x77, 0x2f, 0x1, 0x2f, 0x1,\n    0x80, 0x85, 0x6, 0x9, 0xc, 0x26, 0x1, 0x1, 0x5, 0x1, 0x2, 0x38, 0x7, 0x1,\n    0xf, 0x18, 0x9, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7,\n    0x1, 0x7, 0x1, 0x7, 0x1, 0x20, 0x82, 0x5, 0x3, 0x19, 0xf, 0x1, 0x5, 0x2,\n    0x5, 0x4, 0x56, 0x2, 0x2, 0x2, 0x3, 0x1, 0x5a, 0x1, 0x4, 0x5, 0x29, 0x3,\n    0x5e, 0x11, 0x1b, 0x35, 0x10, 0x82, 0x0, 0x99, 0xb6, 0x4a, 0xa0, 0x51,\n    0xcd, 0x33, 0x84, 0x8d, 0x43, 0x2e, 0x2, 0x81, 0xd, 0x3, 0x1c, 0x14,\n    0x30, 0x4, 0xa, 0x1, 0x19, 0x7, 0x53, 0x25, 0x9, 0x2, 0x67, 0x2, 0x4,\n    0x1, 0x4, 0xc, 0xb, 0x4d, 0x30, 0x18, 0x34, 0xc, 0x45, 0xb, 0xa, 0x6,\n    0x18, 0x3, 0x1, 0x4, 0x2e, 0x2, 0x24, 0xc, 0x1d, 0x3, 0x41, 0xe, 0xb,\n    0x26, 0x37, 0x9, 0xe, 0x2, 0xa, 0x6, 0x17, 0x3, 0x2, 0x4, 0x43, 0x18,\n    0x3, 0x2, 0x10, 0x2, 0x5, 0xa, 0x6, 0x2, 0x6, 0x2, 0x6, 0x9, 0x7, 0x1, 0x7,\n    0x80, 0x91, 0x2b, 0x1, 0x2, 0x2, 0xa, 0x6, 0xa0, 0x2b, 0xa4, 0xc, 0x17,\n    0x4, 0x31, 0xa0, 0x21, 0x4, 0x81, 0x6e, 0x2, 0x6a, 0x26, 0x7, 0xc, 0x5,\n    0x5, 0xc, 0x1, 0xd, 0x1, 0x5, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x6c,\n    0x21, 0x80, 0x8b, 0x6, 0x80, 0xda, 0x12, 0x40, 0x2, 0x36, 0x28, 0xa, 0x6,\n    0x10, 0x10, 0x7, 0xc, 0x2, 0x18, 0x3, 0x21, 0x1, 0x1, 0x1, 0x3, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x7e, 0x13, 0xa, 0x7, 0x1a, 0x4, 0x1, 0x1,\n    0x1a, 0xb, 0x59, 0x3, 0x6, 0x2, 0x6, 0x2, 0x6, 0x2, 0x3, 0x23, 0xc, 0x1,\n    0x1a, 0x1, 0x13, 0x1, 0x2, 0x1, 0xf, 0x2, 0xe, 0x22, 0x7b, 0x45, 0x35,\n    0x80, 0x88, 0x1, 0x80, 0x82, 0x1d, 0x3, 0x31, 0x2f, 0x1f, 0x11, 0x1b, 0x35,\n    0x1e, 0x2, 0x24, 0x4, 0x8, 0x1, 0x5, 0x2a, 0x80, 0x9e, 0x2, 0xa, 0x83,\n    0x56, 0x6, 0x2, 0x1, 0x1, 0x2c, 0x1, 0x2, 0x3, 0x1, 0x2, 0x17, 0x80, 0xaa,\n    0x16, 0xa, 0x1a, 0x46, 0x38, 0x6, 0x2, 0x40, 0x4, 0x1, 0x2, 0x5, 0x8,\n    0x1, 0x3, 0x1, 0x1b, 0x4, 0x3, 0x4, 0x1, 0x20, 0x1d, 0x80, 0x83, 0x36, 0xa,\n    0x16, 0xa, 0x13, 0x80, 0x8d, 0x49, 0x83, 0xb7, 0x47, 0x1f, 0xa, 0x10, 0x3b,\n    0x15, 0x19, 0x7, 0xa, 0x6, 0x35, 0x1, 0xa, 0x40, 0x45, 0xb, 0xa, 0x84,\n    0xa6, 0x38, 0x8, 0xa, 0x89, 0x36, 0x83, 0x6f, 0x80, 0x91, 0x63, 0x8b, 0x9d,\n    0x84, 0x2f, 0xa0, 0x33, 0xd1, 0x82, 0x39, 0x84, 0xc7, 0x45, 0xb, 0x2f,\n    0x10, 0x11, 0xa0, 0x40, 0x60, 0x2, 0xa0, 0x21, 0x63, 0x5, 0x3, 0x6, 0x8,\n    0x8, 0x2, 0x7, 0x1e, 0x4, 0x80, 0x94, 0x3, 0x81, 0xbb, 0x55, 0x1, 0x47,\n    0x1, 0x2, 0x2, 0x1, 0x2, 0x2, 0x2, 0x4, 0x1, 0xc, 0x1, 0x1, 0x1, 0x7,\n    0x1, 0x41, 0x1, 0x4, 0x2, 0x8, 0x1, 0x7, 0x1, 0x1c, 0x1, 0x4, 0x1, 0x5,\n    0x1, 0x1, 0x3, 0x7, 0x1, 0x81, 0x54, 0x2, 0x19, 0x1, 0x19, 0x1, 0x1f,\n    0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1,\n    0x19, 0x1, 0x8, 0x2, 0x32, 0x96, 0x0, 0x4, 0x1, 0x1b, 0x1, 0x2, 0x1, 0x1,\n    0x2, 0x1, 0x1, 0xa, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x6, 0x1, 0x4, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x3, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x4, 0x1, 0x7, 0x1, 0x4, 0x1,\n    0x4, 0x1, 0x1, 0x1, 0xa, 0x1, 0x11, 0x5, 0x3, 0x1, 0x5, 0x1, 0x11, 0x91,\n    0x44, 0xa0, 0xa6, 0xd7, 0x29, 0x90, 0x35, 0xb, 0x80, 0xde, 0xa0, 0x3f,\n    0xe2, 0x82, 0x1e, 0xab, 0x6, 0xe2, 0x80, 0xf0\n];\n_T Lowercase = [0x61, 0x1a, 0x2f, 0x1, 0xa, 0x1, 0x4, 0x1, 0x24, 0x18, 0x1,\n    0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2,\n    0x1, 0x1, 0x1, 0x1, 0x3, 0x2, 0x1, 0x1, 0x1, 0x2, 0x1, 0x3, 0x2, 0x4, 0x1,\n    0x2, 0x1, 0x3, 0x3, 0x2, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1,\n    0x2, 0x1, 0x1, 0x2, 0x1, 0x3, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x3, 0x6, 0x1,\n    0x2, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x1, 0x1, 0x1, 0x3, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x7, 0x2, 0x1, 0x2,\n    0x2, 0x1, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x45, 0x1,\n    0x24, 0x7, 0x2, 0x1e, 0x5, 0x60, 0x1, 0x2b, 0x1, 0x1, 0x1, 0x3, 0x1, 0x2,\n    0x4, 0x12, 0x1, 0x1b, 0x23, 0x1, 0x2, 0x3, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x5, 0x1, 0x1, 0x2, 0x1, 0x2, 0x2, 0x33, 0x30, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x9, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x39, 0x27, 0x97, 0x78, 0x80,\n    0xc0, 0x41, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x9, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x9, 0x8, 0x6, 0xa, 0x8, 0x8,\n    0x8, 0x8, 0x6, 0xa, 0x8, 0x8, 0x8, 0x8, 0xe, 0x2, 0x8, 0x8, 0x8, 0x8, 0x8,\n    0x8, 0x5, 0x1, 0x2, 0x6, 0x1, 0x3, 0x3, 0x1, 0x2, 0x8, 0x4, 0x2, 0x2, 0x8,\n    0x8, 0xa, 0x3, 0x1, 0x2, 0x79, 0x1, 0xd, 0x1, 0x10, 0xd, 0x6d, 0x1, 0x3,\n    0x2, 0x3, 0x1, 0x1b, 0x1, 0x4, 0x1, 0x4, 0x1, 0x2, 0x2, 0x8, 0x4, 0x4, 0x1,\n    0x21, 0x10, 0x4, 0x1, 0x83, 0x4b, 0x1a, 0x87, 0x46, 0x2f, 0x2, 0x1, 0x3,\n    0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x1, 0x1, 0x2, 0x1, 0x8, 0x3, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x1,\n    0xc, 0x26, 0x1, 0x1, 0x5, 0x1, 0xa0, 0x79, 0x13, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x13, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x80, 0x8b, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0xa, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1,\n    0xd, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4e, 0x3, 0xa0, 0x53,\n    0x5, 0x7, 0xc, 0x5, 0x84, 0x29, 0x1a, 0x84, 0xcd, 0x28, 0xa0, 0xcf, 0xca,\n    0x1a, 0x1a, 0x7, 0x1, 0x12, 0x1a, 0x1a, 0x1a, 0x4, 0x1, 0x1, 0x1, 0x7, 0x1,\n    0xb, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,\n    0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1c, 0x1c, 0x19, 0x1, 0x6, 0x1a, 0x19,\n    0x1, 0x6, 0x1a, 0x19, 0x1, 0x6, 0x1a, 0x19, 0x1, 0x6, 0x1a, 0x19, 0x1, 0x6, 0x1,\n    0x1];\n_T Zl = [0xa0, 0x20, 0x28, 0x1];\n_T Zp = [0xa0, 0x20, 0x29, 0x1];\n_T Radical = [0xa0, 0x2e, 0x80, 0x1a, 0x1, 0x59, 0xc, 0x80, 0xd6];\n_T Extender = [\n    0x80, 0xb7, 0x1, 0x82, 0x18, 0x2, 0x83, 0x6e, 0x1, 0x81, 0xb9, 0x1, 0x86,\n    0x4b, 0x1, 0x7f, 0x1, 0x89, 0x43, 0x1, 0x38, 0x1, 0x82, 0x63, 0x1, 0x81,\n    0x8e, 0x1, 0x44, 0x1, 0x93, 0x89, 0x1, 0x2b, 0x5, 0x67, 0x2, 0x5d, 0x3,\n    0xa0, 0x6f, 0x16, 0x1, 0x85, 0xf6, 0x1, 0x83, 0xc2, 0x1, 0x80, 0xa0, 0x1,\n    0x6c, 0x1, 0x15, 0x2, 0xa0, 0x54, 0x7b, 0x1\n];\n_T Co = [0xa0, 0xe0, 0x0, 0x99, 0x0, 0xae, 0x7, 0x0, 0xa0, 0xff, 0xfe, 0x2, 0xa0, 0xff,\n    0xfe];\n_T Unified_Ideograph = [\n    0xa0, 0x34, 0x0, 0x99, 0xb6, 0x4a, 0xa0, 0x51, 0xcd, 0xa0, 0x5a, 0x41,\n    0x2, 0x1, 0x1, 0x1, 0x2, 0xa, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x3, 0xa1, 0x5,\n    0xd6, 0xa0, 0xa6, 0xd7, 0x29, 0x90, 0x35, 0xb, 0x80, 0xde\n];\n_T Pc = [0x5f, 0x1, 0x9f, 0xdf, 0x2, 0x13, 0x1, 0xa0, 0xdd, 0xde, 0x2, 0x18, 0x3, 0x80,\n    0xef, 0x1];\n_T Cs = [0xa0, 0xd8, 0x0, 0x88, 0x0];\n_T Noncharacter_Code_Point = [\n    0xa0, 0xfd, 0xd0, 0x20, 0x82, 0xe, 0x2, 0xa0, 0xff, 0xfe, 0x2, 0xa0, 0xff,\n    0xfe, 0x2, 0xa0, 0xff, 0xfe, 0x2, 0xa0, 0xff, 0xfe, 0x2, 0xa0, 0xff, 0xfe,\n    0x2, 0xa0, 0xff, 0xfe, 0x2, 0xa0, 0xff, 0xfe, 0x2, 0xa0, 0xff, 0xfe, 0x2,\n    0xa0, 0xff, 0xfe, 0x2, 0xa0, 0xff, 0xfe, 0x2, 0xa0, 0xff, 0xfe, 0x2, 0xa0,\n    0xff, 0xfe, 0x2, 0xa0, 0xff, 0xfe, 0x2, 0xa0, 0xff, 0xfe, 0x2, 0xa0, 0xff,\n    0xfe, 0x2, 0xa0, 0xff, 0xfe\n];\n_T Uppercase = [0x41, 0x1a, 0x65, 0x17, 0x1, 0x7, 0x21, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x3,\n    0x2, 0x1, 0x1, 0x1, 0x2, 0x1, 0x3, 0x2, 0x4, 0x1, 0x2, 0x1, 0x3, 0x3, 0x2,\n    0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1,\n    0x3, 0x1, 0x1, 0x1, 0x2, 0x3, 0x1, 0x7, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x7, 0x2, 0x1, 0x2, 0x2, 0x1, 0x1, 0x4, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x81, 0x21, 0x1, 0x1, 0x1, 0x3, 0x1,\n    0xf, 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x2, 0x1, 0x11, 0x1, 0x9, 0x23, 0x1,\n    0x2, 0x3, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x5, 0x1, 0x2,\n    0x1, 0x1, 0x2, 0x2, 0x33, 0x30, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x9, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0xa, 0x26, 0x8b, 0x49, 0x26, 0x1, 0x1, 0x5, 0x1, 0x8d, 0x32,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x9,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x9, 0x8, 0x8, 0x6, 0xa, 0x8, 0x8, 0x8,\n    0x8, 0x6, 0xb, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x8, 0x8, 0x48, 0x4,\n    0xc, 0x4, 0xc, 0x4, 0xc, 0x5, 0xb, 0x4, 0x81, 0x6, 0x1, 0x4, 0x1, 0x3,\n    0x3, 0x2, 0x3, 0x2, 0x1, 0x3, 0x5, 0x6, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4,\n    0x2, 0x4, 0xa, 0x2, 0x5, 0x1, 0x1a, 0x10, 0x13, 0x1, 0x83, 0x32, 0x1a,\n    0x87, 0x30, 0x2f, 0x31, 0x1, 0x1, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x4, 0x1, 0x1, 0x2, 0x1, 0x8, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x8, 0x1, 0x1, 0x1, 0x4, 0x1, 0xa0, 0x79, 0x4d, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x13, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x80, 0x8b, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0xa, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1,\n    0xd, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0xa0, 0x57,\n    0x76, 0x1a, 0x84, 0xc5, 0x28, 0xa0, 0xcf, 0xd8, 0x1a, 0x1a, 0x1a, 0x1a,\n    0x1a, 0x1a, 0x1, 0x1, 0x2, 0x2, 0x1, 0x2, 0x2, 0x2, 0x4, 0x1, 0x8, 0x1a,\n    0x1a, 0x1a, 0x2, 0x1, 0x4, 0x2, 0x8, 0x1, 0x7, 0x1b, 0x2, 0x1, 0x4, 0x1,\n    0x5, 0x1, 0x1, 0x3, 0x7, 0x1b, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,\n    0x1a, 0x1a, 0x1a, 0x1a, 0x1e, 0x19, 0x21, 0x19, 0x21, 0x19, 0x21, 0x19, 0x21, 0x19,\n    0x21, 0x1];\n_T IDS_Trinary_Operator = [0xa0, 0x2f, 0xf2, 0x2];\n_T Logical_Order_Exception = [0x8e, 0x40, 0x5, 0x7b, 0x5, 0xa0, 0x9b, 0xf0,\n    0x2, 0x2, 0x1, 0x1, 0x2];\n_T Pi = [0x80, 0xab, 0x1, 0x9f, 0x6c, 0x1, 0x2, 0x2, 0x2, 0x1, 0x19, 0x1,\n    0x8d, 0xc8, 0x1, 0x1, 0x1, 0x4, 0x1, 0x2, 0x1, 0xf, 0x1, 0x3, 0x1];\n_T Soft_Dotted = [\n    0x69, 0x2, 0x80, 0xc4, 0x1, 0x81, 0x19, 0x1, 0x1e, 0x1, 0x34, 0x1, 0x14,\n    0x1, 0x81, 0x40, 0x1, 0x62, 0x1, 0x1, 0x1, 0x99, 0x9, 0x1, 0x33, 0x1,\n    0xd, 0x1, 0x3, 0x1, 0x80, 0x84, 0x1, 0x80, 0x9d, 0x1, 0x81, 0xa5, 0x1,\n    0x80, 0xd6, 0x2, 0x8b, 0x32, 0x1, 0xa1, 0xa7, 0xa5, 0x2, 0x32, 0x2, 0x32,\n    0x2, 0x32, 0x2, 0x32, 0x2, 0x32, 0x2, 0x32, 0x2, 0x32, 0x2, 0x32, 0x2,\n    0x32, 0x2, 0x32, 0x2, 0x32, 0x2, 0x32, 0x2\n];\n_T Po = [0x21, 0x3, 0x1, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, 0x2, 0xa, 0x2, 0x3, 0x2,\n    0x1b, 0x1, 0x44, 0x1, 0x5, 0x1, 0xe, 0x2, 0x7, 0x1, 0x82, 0xbe, 0x1, 0x8,\n    0x1, 0x81, 0xd2, 0x6, 0x29, 0x1, 0x36, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2c,\n    0x2, 0x14, 0x2, 0x1, 0x2, 0xd, 0x1, 0x2, 0x2, 0x4a, 0x4, 0x66, 0x1, 0x2b,\n    0xe, 0x80, 0xe9, 0x3, 0x36, 0xf, 0x1f, 0x1, 0x81, 0x5, 0x2, 0xa, 0x1, 0x81,\n    0x7f, 0x1, 0x83, 0x3, 0x1, 0x5a, 0x1, 0xa, 0x2, 0x80, 0xa8, 0xf, 0x1,\n    0x1, 0x70, 0x1, 0x4a, 0x5, 0x4, 0x2, 0x6f, 0x6, 0x80, 0xab, 0x1, 0x82,\n    0x64, 0x9, 0x83, 0x4, 0x2, 0x7c, 0x3, 0x47, 0x2, 0x80, 0x9d, 0x3, 0x1,\n    0x3, 0x25, 0x6, 0x1, 0x4, 0x81, 0x39, 0x2, 0x80, 0xd8, 0x2, 0x80, 0x80,\n    0x7, 0x1, 0x6, 0x80, 0xac, 0x7, 0x80, 0x9b, 0x4, 0x3b, 0x5, 0x3e, 0x2,\n    0x40, 0x8, 0xb, 0x1, 0x83, 0x42, 0x2, 0x8, 0x8, 0x8, 0x9, 0x2, 0x4, 0x2,\n    0x3, 0x3, 0xb, 0x1, 0x1, 0x1, 0xa, 0x8c, 0x9a, 0x4, 0x1, 0x2, 0x70, 0x1,\n    0x80, 0x8f, 0x2, 0x4, 0x3, 0x2, 0x1, 0x2, 0x9, 0x1, 0x2, 0x1, 0x1, 0x2,\n    0x2, 0xa, 0x5, 0x1, 0xa, 0x81, 0xc7, 0x3, 0x39, 0x1, 0x80, 0xbd, 0x1, 0xa0,\n    0x74, 0x2, 0x2, 0x81, 0xd, 0x3, 0x63, 0x1, 0xa, 0x1, 0x73, 0x6, 0x81, 0x7c,\n    0x4, 0x56, 0x2, 0x28, 0x3, 0x33, 0x2, 0x2f, 0x1, 0x61, 0xd, 0x10, 0x2,\n    0x7c, 0x4, 0x7e, 0x2, 0x10, 0x2, 0x80, 0xf9, 0x1, 0xa0, 0x52, 0x24, 0x7,\n    0x2, 0x1, 0x16, 0x1, 0x14, 0x2, 0x2, 0x4, 0x3, 0x3, 0x1, 0x4, 0x7, 0x3,\n    0x6, 0x1, 0x1, 0x2, 0x80, 0x95, 0x3, 0x1, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1,\n    0x2, 0xa, 0x2, 0x3, 0x2, 0x1b, 0x1, 0x24, 0x1, 0x2, 0x2, 0x81, 0x9a, 0x3,\n    0x82, 0x9c, 0x1, 0x30, 0x1, 0x84, 0x86, 0x1, 0x80, 0xc7, 0x1, 0x1f, 0x1,\n    0x81, 0x10, 0x9, 0x26, 0x1, 0x80, 0xb9, 0x7, 0x85, 0x7, 0x7, 0x6d, 0x2,\n    0x1, 0x4, 0x7e, 0x4, 0x80, 0x81, 0x4, 0x92, 0xa7, 0x4];\n_T Cn = [0x83, 0x78, 0x2, 0x5, 0x5, 0x7, 0x1, 0x1, 0x1, 0x14, 0x1, 0x81,\n    0x85, 0x9, 0x26, 0x2, 0x7, 0x1, 0x27, 0x1, 0x2, 0x4, 0x1, 0x1, 0x37, 0x8,\n    0x1b, 0x5, 0x5, 0xb, 0x5, 0x1, 0x17, 0x1, 0x80, 0xf0, 0x1, 0x3c, 0x2, 0x65,\n    0xe, 0x3b, 0x5, 0x2e, 0x2, 0xf, 0x1, 0x1c, 0x2, 0x1, 0x41, 0x1, 0x1, 0xb,\n    0x37, 0x1b, 0x1, 0x78, 0x1, 0x7, 0x1, 0x3, 0x1, 0x8, 0x2, 0x2, 0x2, 0x16,\n    0x1, 0x7, 0x1, 0x1, 0x3, 0x4, 0x2, 0x9, 0x2, 0x2, 0x2, 0x4, 0x8, 0x1, 0x4,\n    0x2, 0x1, 0x5, 0x2, 0x16, 0x5, 0x3, 0x1, 0x6, 0x4, 0x2, 0x2, 0x16, 0x1,\n    0x7, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x2, 0x1, 0x1, 0x5, 0x4, 0x2, 0x2, 0x3,\n    0x3, 0x1, 0x7, 0x4, 0x1, 0x1, 0x7, 0x10, 0xb, 0x3, 0x1, 0x9, 0x1, 0x3,\n    0x1, 0x16, 0x1, 0x7, 0x1, 0x2, 0x1, 0x5, 0x2, 0xa, 0x1, 0x3, 0x1, 0x3,\n    0x2, 0x1, 0xf, 0x4, 0x2, 0xc, 0xf, 0x3, 0x1, 0x8, 0x2, 0x2, 0x2, 0x16,\n    0x1, 0x7, 0x1, 0x2, 0x1, 0x5, 0x2, 0x9, 0x2, 0x2, 0x2, 0x3, 0x8, 0x2, 0x4,\n    0x2, 0x1, 0x5, 0x2, 0x12, 0xa, 0x2, 0x1, 0x6, 0x3, 0x3, 0x1, 0x4, 0x3,\n    0x2, 0x1, 0x1, 0x1, 0x2, 0x3, 0x2, 0x3, 0x3, 0x3, 0xc, 0x4, 0x5, 0x3, 0x3,\n    0x1, 0x4, 0x2, 0x1, 0x6, 0x1, 0xe, 0x15, 0x6, 0x3, 0x1, 0x8, 0x1, 0x3,\n    0x1, 0x17, 0x1, 0xa, 0x1, 0x5, 0x3, 0x8, 0x1, 0x3, 0x1, 0x4, 0x7, 0x2,\n    0x1, 0x2, 0x6, 0x4, 0x2, 0xa, 0x8, 0x8, 0x2, 0x2, 0x1, 0x8, 0x1, 0x3,\n    0x1, 0x17, 0x1, 0xa, 0x1, 0x5, 0x2, 0x9, 0x1, 0x3, 0x1, 0x4, 0x7, 0x2,\n    0x7, 0x1, 0x1, 0x4, 0x2, 0xa, 0x1, 0x2, 0xf, 0x2, 0x1, 0x8, 0x1, 0x3,\n    0x1, 0x29, 0x2, 0x8, 0x1, 0x3, 0x1, 0x5, 0x8, 0x1, 0x8, 0x4, 0x2, 0x10,\n    0x3, 0x7, 0x2, 0x2, 0x1, 0x12, 0x3, 0x18, 0x1, 0x9, 0x1, 0x1, 0x2, 0x7,\n    0x3, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x8, 0x12, 0x3, 0xc, 0x3a, 0x4, 0x1d,\n    0x25, 0x2, 0x1, 0x1, 0x2, 0x2, 0x1, 0x1, 0x2, 0x1, 0x6, 0x4, 0x1, 0x7,\n    0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x1, 0xd, 0x1, 0x3, 0x2, 0x5, 0x1,\n    0x1, 0x1, 0x6, 0x2, 0xa, 0x2, 0x4, 0x20, 0x48, 0x1, 0x24, 0x4, 0x27, 0x1,\n    0x24, 0x1, 0xf, 0x1, 0xd, 0x25, 0x80, 0xc6, 0x1, 0x1, 0x5, 0x1, 0x2,\n    0x81, 0x79, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0x29, 0x1, 0x4,\n    0x2, 0x21, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2, 0xf, 0x1, 0x39,\n    0x1, 0x4, 0x2, 0x43, 0x2, 0x20, 0x3, 0x1a, 0x6, 0x55, 0xb, 0x82, 0x9d,\n    0x3, 0x51, 0xf, 0xd, 0x1, 0x7, 0xb, 0x17, 0x9, 0x14, 0xc, 0xd, 0x1, 0x3,\n    0x1, 0x2, 0xc, 0x5e, 0x2, 0xa, 0x6, 0xa, 0x6, 0xf, 0x1, 0xa, 0x6, 0x58,\n    0x8, 0x2b, 0x5, 0x46, 0xa, 0x1d, 0x3, 0xc, 0x4, 0xc, 0x4, 0x1, 0x3, 0x2a,\n    0x2, 0x5, 0xb, 0x2c, 0x4, 0x1a, 0x6, 0xb, 0x3, 0x3e, 0x2, 0x41, 0x1, 0x1d,\n    0x2, 0xb, 0x6, 0xa, 0x6, 0xe, 0x52, 0x4c, 0x4, 0x2d, 0x3, 0x74, 0x8,\n    0x3c, 0x3, 0xf, 0x3, 0x33, 0x40, 0x8, 0x8, 0x27, 0x9, 0x80, 0xe7, 0x15,\n    0x81, 0x1a, 0x2, 0x6, 0x2, 0x26, 0x2, 0x6, 0x2, 0x8, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1f, 0x2, 0x35, 0x1, 0xf, 0x1, 0xe, 0x2, 0x6, 0x1, 0x13,\n    0x2, 0x3, 0x1, 0x9, 0x1, 0x65, 0x1, 0xc, 0x2, 0x1b, 0x1, 0xd, 0x3, 0x1b,\n    0x15, 0x21, 0xf, 0x80, 0x8a, 0x6, 0x82, 0x64, 0xc, 0x27, 0x19, 0xb, 0x15,\n    0x82, 0xa0, 0x1, 0x84, 0x4c, 0x3, 0xa, 0x80, 0xa6, 0x2f, 0x1, 0x2f, 0x1,\n    0x80, 0x94, 0x5, 0x2d, 0x1, 0x1, 0x5, 0x1, 0x2, 0x38, 0x7, 0x2, 0xe, 0x18,\n    0x9, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7,\n    0x1, 0x7, 0x1, 0x5c, 0x44, 0x1a, 0x1, 0x59, 0xc, 0x80, 0xd6, 0x1a, 0xc,\n    0x4, 0x40, 0x1, 0x56, 0x2, 0x67, 0x5, 0x29, 0x3, 0x5e, 0x1, 0x2b, 0x5,\n    0x24, 0xc, 0x2f, 0x1, 0x80, 0xdf, 0x1, 0x9a, 0xb6, 0xa, 0xa0, 0x52, 0xd,\n    0x33, 0x84, 0x8d, 0x3, 0x37, 0x9, 0x81, 0x5c, 0x14, 0x58, 0x7, 0x59, 0x8,\n    0x80, 0x8f, 0x1, 0x4, 0xc, 0xb, 0x4d, 0x34, 0x4, 0xa, 0x6, 0x38, 0x8,\n    0x45, 0x9, 0xc, 0x6, 0x1c, 0x4, 0x54, 0xb, 0x1e, 0x3, 0x4e, 0x1, 0xb,\n    0x4, 0x2, 0x20, 0x37, 0x9, 0xe, 0x2, 0xa, 0x2, 0x20, 0x4, 0x43, 0x18,\n    0x1c, 0xa, 0x6, 0x2, 0x6, 0x2, 0x6, 0x9, 0x7, 0x1, 0x7, 0x80, 0x91, 0x2e,\n    0x2, 0xa, 0x6, 0xa0, 0x2b, 0xa4, 0xc, 0x17, 0x4, 0x31, 0x4, 0xa0, 0x22,\n    0x6e, 0x2, 0x6a, 0x26, 0x7, 0xc, 0x5, 0x5, 0x1a, 0x1, 0x5, 0x1, 0x1, 0x1,\n    0x2, 0x1, 0x2, 0x1, 0x7c, 0x11, 0x81, 0x6d, 0x10, 0x40, 0x2, 0x36, 0x28,\n    0xe, 0x2, 0x1a, 0x6, 0x7, 0x9, 0x23, 0x1, 0x13, 0x1, 0x4, 0x4, 0x5, 0x1,\n    0x80, 0x87, 0x2, 0x1, 0x1, 0x80, 0xbe, 0x3, 0x6, 0x2, 0x6, 0x2, 0x6, 0x2,\n    0x3, 0x3, 0x7, 0x1, 0x7, 0xa, 0x5, 0x2, 0xc, 0x1, 0x1a, 0x1, 0x13, 0x1,\n    0x2, 0x1, 0xf, 0x2, 0xe, 0x22, 0x7b, 0x5, 0x3, 0x4, 0x2d, 0x3, 0x54, 0x5,\n    0xc, 0x34, 0x2e, 0x80, 0x82, 0x1d, 0x3, 0x31, 0x2f, 0x1f, 0x1, 0x4, 0xc,\n    0x1b, 0x35, 0x1e, 0x1, 0x25, 0x4, 0xe, 0x2a, 0x80, 0x9e, 0x2, 0xa, 0x83,\n    0x56, 0x6, 0x2, 0x1, 0x1, 0x2c, 0x1, 0x2, 0x3, 0x1, 0x2, 0x17, 0x1, 0x9,\n    0x80, 0xa0, 0x1c, 0x3, 0x1b, 0x5, 0x1, 0x40, 0x38, 0x6, 0x2, 0x40, 0x4,\n    0x1, 0x2, 0x5, 0x8, 0x1, 0x3, 0x1, 0x1b, 0x4, 0x3, 0x4, 0x9, 0x8, 0x9, 0x7,\n    0x20, 0x80, 0x80, 0x36, 0x3, 0x1d, 0x2, 0x1b, 0x5, 0x8, 0x80, 0x80, 0x49,\n    0x82, 0x17, 0x1f, 0x81, 0x81, 0x4e, 0x4, 0x1e, 0x10, 0x42, 0xe, 0x19,\n    0x7, 0xa, 0x6, 0x35, 0x1, 0xe, 0x3c, 0x49, 0x7, 0xa, 0x84, 0xa6, 0x38, 0x8,\n    0xa, 0x89, 0x36, 0x83, 0x6f, 0x80, 0x91, 0x63, 0xd, 0x4, 0x8b, 0x8c, 0x84,\n    0x2f, 0xa0, 0x33, 0xd1, 0x82, 0x39, 0x84, 0xc7, 0x45, 0xb, 0x2f, 0x10,\n    0x11, 0xa0, 0x40, 0x60, 0x2, 0x9f, 0xfe, 0x80, 0xf6, 0xa, 0x27, 0x2, 0x80,\n    0xb5, 0x22, 0x46, 0x80, 0xba, 0x57, 0x9, 0x12, 0x80, 0x8e, 0x55, 0x1,\n    0x47, 0x1, 0x2, 0x2, 0x1, 0x2, 0x2, 0x2, 0x4, 0x1, 0xc, 0x1, 0x1, 0x1,\n    0x7, 0x1, 0x41, 0x1, 0x4, 0x2, 0x8, 0x1, 0x7, 0x1, 0x1c, 0x1, 0x4, 0x1,\n    0x5, 0x1, 0x1, 0x3, 0x7, 0x1, 0x81, 0x54, 0x2, 0x81, 0x24, 0x2, 0x32,\n    0x96, 0x0, 0x4, 0x1, 0x1b, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0xa, 0x1,\n    0x4, 0x1, 0x1, 0x1, 0x1, 0x6, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3,\n    0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x2, 0x1, 0x1, 0x2, 0x4, 0x1, 0x7, 0x1, 0x4, 0x1, 0x4, 0x1, 0x1, 0x1,\n    0xa, 0x1, 0x11, 0x5, 0x3, 0x1, 0x5, 0x1, 0x11, 0x34, 0x2, 0x81, 0xe,\n    0x2c, 0x4, 0x64, 0xc, 0xf, 0x2, 0xe, 0x2, 0xf, 0x1, 0xf, 0x20, 0xb, 0x5,\n    0x1f, 0x1, 0x3c, 0x4, 0x2b, 0x4b, 0x1d, 0xd, 0x2b, 0x5, 0x9, 0x7, 0x2,\n    0x80, 0xae, 0x21, 0xf, 0x6, 0x1, 0x46, 0x3, 0x14, 0xc, 0x25, 0x1, 0x5,\n    0x15, 0x11, 0xf, 0x3f, 0x1, 0x1, 0x1, 0x80, 0xb6, 0x1, 0x4, 0x3, 0x3e, 0x2,\n    0x4, 0xc, 0x18, 0x80, 0x93, 0x46, 0x4, 0xb, 0x30, 0x46, 0x3a, 0x74, 0x88,\n    0x8c, 0xa0, 0xa6, 0xd7, 0x29, 0x90, 0x35, 0xb, 0x80, 0xde, 0xa0, 0x3f,\n    0xe2, 0x82, 0x1e, 0xab, 0x5, 0xe3, 0x1, 0x1e, 0x60, 0x80, 0x80, 0x80, 0xf0,\n    0xa0, 0xfe, 0x10, 0xa0, 0xff, 0xfe, 0x2, 0xa0, 0xff, 0xfe];\n_T Ps = [0x28, 0x1, 0x32, 0x1, 0x1f, 0x1, 0x8e, 0xbe, 0x1, 0x1, 0x1, 0x87,\n    0x5e, 0x1, 0x89, 0x7e, 0x1, 0x3, 0x1, 0x26, 0x1, 0x37, 0x1, 0xf, 0x1,\n    0x82, 0x7a, 0x1, 0x1, 0x1, 0x1e, 0x1, 0x84, 0x3e, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x50, 0x1, 0x20, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x81, 0x94, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x40, 0x1, 0x1, 0x1, 0x21, 0x1, 0x84, 0x25, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x81, 0xdf, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0xa0, 0xcd, 0x20, 0x1, 0x80,\n    0xd8, 0x1, 0x1d, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x3, 0x1, 0x11, 0x1, 0x1, 0x1, 0x1, 0x1, 0x80, 0xaa,\n    0x1, 0x32, 0x1, 0x1f, 0x1, 0x3, 0x1, 0x2, 0x1];\n_T ASCII_Hex_Digit = [0x30, 0xa, 0x7, 0x6, 0x1a, 0x6];\n_T No = [0x80, 0xb2, 0x2, 0x5, 0x1, 0x2, 0x3, 0x89, 0x35, 0x6, 0x81, 0x78, 0x6,\n    0x78, 0x3, 0x80, 0x85, 0x7, 0x80, 0xf1, 0x6, 0x81, 0xb4, 0xa, 0x84, 0x35,\n    0x14, 0x84, 0x73, 0xa, 0x81, 0xe0, 0x1, 0x86, 0x95, 0x1, 0x3, 0x6, 0x6,\n    0xa, 0x80, 0xc6, 0x10, 0x29, 0x1, 0x82, 0xd6, 0x3c, 0x4e, 0x16, 0x82, 0x76,\n    0x1e, 0x85, 0x69, 0x1, 0x84, 0x94, 0x4, 0x80, 0x8a, 0xa, 0x1e, 0x8, 0x1,\n    0xf, 0x20, 0xa, 0x27, 0xf, 0xa0, 0x75, 0x70, 0x6, 0xa0, 0x58, 0xd1, 0x2d,\n    0x41, 0x4, 0x11, 0x1, 0x81, 0x95, 0x4, 0x85, 0x34, 0x8, 0x80, 0xb6, 0x6,\n    0x81, 0x24, 0x8, 0x35, 0x2, 0x80, 0xd9, 0x8, 0x18, 0x8, 0x82, 0xe0, 0x1f,\n    0x81, 0xd3, 0x14, 0xa0, 0xc2, 0xfa, 0x12, 0x9d, 0x8e, 0xb];\n_T Sm = [0x2b, 0x1, 0x10, 0x3, 0x3d, 0x1, 0x1, 0x1, 0x2d, 0x1, 0x4, 0x1,\n    0x25, 0x1, 0x1f, 0x1, 0x82, 0xfe, 0x1, 0x82, 0xf, 0x3, 0x9a, 0x3b, 0x1,\n    0xd, 0x1, 0x27, 0x3, 0xd, 0x3, 0x80, 0x8b, 0x1, 0x27, 0x5, 0x6, 0x1, 0x44,\n    0x5, 0x5, 0x2, 0x4, 0x1, 0x2, 0x1, 0x2, 0x1, 0x7, 0x1, 0x1f, 0x2, 0x2, 0x1,\n    0x1, 0x1, 0x1f, 0x81, 0xc, 0x20, 0x2, 0x5a, 0x1, 0x1e, 0x19, 0x28, 0x6,\n    0x81, 0xd5, 0x1, 0x9, 0x1, 0x36, 0x8, 0x6f, 0x1, 0x81, 0x50, 0x5, 0x2,\n    0x1f, 0xa, 0x10, 0x81, 0x0, 0x80, 0x83, 0x16, 0x3f, 0x4, 0x20, 0x2, 0x81,\n    0x2, 0x30, 0x15, 0x2, 0x6, 0xa0, 0xcf, 0xdc, 0x1, 0x83, 0x38, 0x1, 0x1,\n    0x3, 0x80, 0xa4, 0x1, 0x10, 0x3, 0x3d, 0x1, 0x1, 0x1, 0x80, 0x83, 0x1, 0x6,\n    0x4, 0xa0, 0xd6, 0xd4, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1,\n    0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x97, 0x2c, 0x2];\n_T Other_Math = [\n    0x5e, 0x1, 0x83, 0x71, 0x3, 0x2, 0x1, 0x1a, 0x2, 0x2, 0x2, 0x9c, 0x20,\n    0x1, 0x1b, 0x3, 0xb, 0x1, 0x20, 0x4, 0x18, 0x2, 0xe, 0x2, 0x41, 0xd, 0x4,\n    0x1, 0x3, 0x2, 0x4, 0x5, 0x12, 0x1, 0x4, 0x1, 0x2, 0xa, 0x1, 0x1, 0x3,\n    0x5, 0x6, 0x1, 0x3, 0x2, 0x2, 0x2, 0x1, 0x3, 0x1, 0x6, 0x3, 0x4, 0x5,\n    0x5, 0x4b, 0x5, 0x2, 0x4, 0x1, 0x2, 0x1, 0x2, 0x1, 0x1, 0x1, 0x5, 0x2,\n    0x2, 0x4, 0x2, 0x4, 0x12, 0x2, 0x2, 0x1, 0x1, 0x1, 0x7, 0x1, 0x1, 0x6, 0x2,\n    0x81, 0x22, 0x4, 0x80, 0xa8, 0x2, 0x1, 0x1, 0x18, 0x1, 0x11, 0x1, 0x81,\n    0xbd, 0x2, 0xc, 0x9, 0x5, 0x5, 0x5, 0x2, 0x2, 0x2, 0x3, 0x5, 0xe, 0x1,\n    0x1, 0x1, 0x2, 0x6, 0x18, 0x2, 0x39, 0x1, 0x1, 0x1, 0x1d, 0x4, 0x9, 0x2,\n    0x81, 0x56, 0x2, 0x1f, 0xa, 0x81, 0x93, 0x16, 0x3f, 0x4, 0x20, 0x2, 0xa0,\n    0xd4, 0x63, 0x1, 0x1, 0x1, 0x4, 0x1, 0x80, 0xd3, 0x1, 0x1, 0x1, 0xa0, 0xd4,\n    0xc1, 0x55, 0x1, 0x47, 0x1, 0x2, 0x2, 0x1, 0x2, 0x2, 0x2, 0x4, 0x1, 0xc,\n    0x1, 0x1, 0x1, 0x7, 0x1, 0x41, 0x1, 0x4, 0x2, 0x8, 0x1, 0x7, 0x1, 0x1c,\n    0x1, 0x4, 0x1, 0x5, 0x1, 0x1, 0x3, 0x7, 0x1, 0x81, 0x54, 0x2, 0x19, 0x1,\n    0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19, 0x1, 0x1f, 0x1, 0x19,\n    0x1, 0x1f, 0x1, 0x19, 0x1, 0x8, 0x2, 0x32, 0x96, 0x0, 0x4, 0x1, 0x1b, 0x1,\n    0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0xa, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x6, 0x1,\n    0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x4, 0x1, 0x7,\n    0x1, 0x4, 0x1, 0x4, 0x1, 0x1, 0x1, 0xa, 0x1, 0x11, 0x5, 0x3, 0x1, 0x5, 0x1, 0x11\n];\n_T Join_Control = [0xa0, 0x20, 0xc, 0x2];\n_T Cf = [0x80, 0xad, 0x1, 0x85, 0x52, 0x5, 0x17, 0x1, 0x80, 0xc0, 0x1, 0x31,\n    0x1, 0x90, 0xfe, 0x1, 0x87, 0xfc, 0x5, 0x1a, 0x5, 0x31, 0x5, 0x1, 0xa,\n    0xa0, 0xde, 0x8f, 0x1, 0x80, 0xf9, 0x3, 0x90, 0xc1, 0x1, 0xa0, 0xc0, 0xb5,\n    0x8, 0xac, 0x2e, 0x86, 0x1, 0x1e, 0x60];\n_T Ideographic = [\n    0xa0, 0x30, 0x6, 0x2, 0x19, 0x9, 0xe, 0x3, 0x83, 0xc5, 0x99, 0xb6, 0x4a,\n    0xa0, 0x51, 0xcd, 0xa0, 0x59, 0x33, 0x81, 0x6e, 0x2, 0x6a, 0xa1, 0x5, 0x26,\n    0xa0, 0xa6, 0xd7, 0x29, 0x90, 0x35, 0xb, 0x80, 0xde, 0xa0, 0x3f, 0xe2, 0x82, 0x1e\n];\n_T Sc = [0x24, 0x1, 0x7d, 0x4, 0x84, 0xe9, 0x1, 0x7b, 0x1, 0x83, 0xe6, 0x2,\n    0x7, 0x1, 0x80, 0xf5, 0x1, 0x81, 0x7, 0x1, 0x82, 0x45, 0x1, 0x89, 0x9b,\n    0x1, 0x88, 0xc4, 0x1b, 0xa0, 0x87, 0x7d, 0x1, 0xa0, 0x55, 0xc3, 0x1,\n    0x6c, 0x1, 0x80, 0x9a, 0x1, 0x80, 0xdb, 0x2, 0x3, 0x2];\n_T Nd = [0x30, 0xa, 0x86, 0x26, 0xa, 0x80, 0x86, 0xa, 0x80, 0xc6, 0xa, 0x81,\n    0x9c, 0xa, 0x76, 0xa, 0x76, 0xa, 0x76, 0xa, 0x76, 0xa, 0x76, 0xa, 0x76,\n    0xa, 0x76, 0xa, 0x76, 0xa, 0x80, 0xe0, 0xa, 0x76, 0xa, 0x46, 0xa, 0x81,\n    0x16, 0xa, 0x46, 0xa, 0x87, 0x46, 0xa, 0x26, 0xa, 0x81, 0x2c, 0xa, 0x80,\n    0x80, 0xa, 0x80, 0xa6, 0xa, 0x6, 0xa, 0x80, 0xb6, 0xa, 0x56, 0xa, 0x80,\n    0x86, 0xa, 0x6, 0xa, 0xa0, 0x89, 0xc6, 0xa, 0x82, 0xa6, 0xa, 0x26, 0xa,\n    0x80, 0xc6, 0xa, 0x76, 0xa, 0x81, 0x96, 0xa, 0xa0, 0x53, 0x16, 0xa, 0x85,\n    0x86, 0xa, 0x8b, 0xbc, 0xa, 0x80, 0x80, 0xa, 0x3c, 0xa, 0x80, 0x90, 0xa,\n    0x84, 0xe6, 0xa, 0xa0, 0xc1, 0x4, 0x32];\n_T Default_Ignorable_Code_Point = [\n    0x80, 0xad, 0x1, 0x82, 0xa1, 0x1, 0x82, 0xcc, 0x1, 0x8b, 0x42, 0x2, 0x86,\n    0x53, 0x2, 0x55, 0x4, 0x87, 0xfc, 0x5, 0x1a, 0x5, 0x31, 0x10, 0x90, 0xf4,\n    0x1, 0xa0, 0xcc, 0x9b, 0x10, 0x80, 0xef, 0x1, 0x80, 0xa0, 0x1, 0x4f, 0x9,\n    0xa0, 0xd1, 0x7a, 0x8, 0xac, 0x2e, 0x85, 0x90, 0x0\n];\n_T Other_ID_Continue = [0x80, 0xb7, 0x1, 0x82, 0xcf, 0x1, 0x8f, 0xe1, 0x9, 0x86, 0x68,\n    0x1];\n_T Pd = [0x2d, 0x1, 0x85, 0x5c, 0x1, 0x33, 0x1, 0x8e, 0x41, 0x1, 0x84, 0x5,\n    0x1, 0x88, 0x9, 0x6, 0x8e, 0x1, 0x1, 0x2, 0x1, 0x1f, 0x2, 0x81, 0xe0,\n    0x1, 0x13, 0x1, 0x6f, 0x1, 0xa0, 0xcd, 0x90, 0x2, 0x25, 0x1, 0xa, 0x1, 0x80, 0xa9,\n    0x1];\n_T Deprecated = [\n    0x81, 0x49, 0x1, 0x85, 0x29, 0x1, 0x89, 0x3, 0x1, 0x1, 0x1, 0x88, 0x29,\n    0x2, 0x88, 0xc5, 0x6, 0x82, 0xb9, 0x2, 0xad, 0xdc, 0xd6, 0x1, 0x1e, 0x60\n];\n_T Grapheme_Extend = [\n    0x83, 0x0, 0x70, 0x81, 0x13, 0x7, 0x81, 0x7, 0x2d, 0x1, 0x1, 0x1, 0x2,\n    0x1, 0x2, 0x1, 0x1, 0x48, 0xb, 0x30, 0x15, 0x10, 0x1, 0x65, 0x7, 0x2, 0x6,\n    0x2, 0x2, 0x1, 0x4, 0x23, 0x1, 0x1e, 0x1b, 0x5b, 0xb, 0x3a, 0x9, 0x22,\n    0x4, 0x1, 0x9, 0x1, 0x3, 0x1, 0x5, 0x2b, 0x3, 0x80, 0x88, 0x1b, 0x1, 0x3,\n    0x37, 0x1, 0x1, 0x1, 0x4, 0x8, 0x4, 0x1, 0x3, 0x7, 0xa, 0x2, 0x1d, 0x1,\n    0x3a, 0x1, 0x1, 0x1, 0x2, 0x4, 0x8, 0x1, 0x9, 0x1, 0xa, 0x2, 0x1d, 0x2,\n    0x39, 0x1, 0x4, 0x2, 0x4, 0x2, 0x2, 0x3, 0x3, 0x1, 0x1e, 0x2, 0x3, 0x1,\n    0xb, 0x2, 0x39, 0x1, 0x4, 0x5, 0x1, 0x2, 0x4, 0x1, 0x14, 0x2, 0x1d, 0x1,\n    0x3a, 0x1, 0x1, 0x2, 0x1, 0x4, 0x8, 0x1, 0x8, 0x2, 0xa, 0x2, 0x1e, 0x1,\n    0x3b, 0x1, 0x1, 0x1, 0xc, 0x1, 0x9, 0x1, 0x66, 0x3, 0x5, 0x3, 0x1, 0x4,\n    0x7, 0x2, 0xb, 0x2, 0x58, 0x1, 0x2, 0x1, 0x2, 0x1, 0x3, 0x1, 0x5, 0x2,\n    0x7, 0x2, 0xb, 0x2, 0x5a, 0x1, 0x2, 0x4, 0x8, 0x1, 0x9, 0x1, 0xa, 0x2,\n    0x66, 0x1, 0x4, 0x1, 0x2, 0x3, 0x1, 0x1, 0x8, 0x1, 0x51, 0x1, 0x2, 0x7,\n    0xc, 0x8, 0x62, 0x1, 0x2, 0x6, 0x1, 0x2, 0xb, 0x6, 0x4a, 0x2, 0x1b, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x37, 0xe, 0x1, 0x5, 0x1, 0x2, 0x5, 0xb, 0x1, 0x24,\n    0x9, 0x1, 0x66, 0x4, 0x1, 0x6, 0x1, 0x2, 0x2, 0x2, 0x19, 0x2, 0x4, 0x3,\n    0x10, 0x4, 0xd, 0x1, 0x2, 0x2, 0x6, 0x1, 0xf, 0x1, 0x82, 0xbf, 0x3, 0x83,\n    0xb2, 0x3, 0x1d, 0x3, 0x1d, 0x2, 0x1e, 0x2, 0x40, 0x2, 0x1, 0x7, 0x8, 0x1,\n    0x2, 0xb, 0x9, 0x1, 0x2d, 0x3, 0x80, 0x9b, 0x1, 0x76, 0x3, 0x4, 0x2, 0x9,\n    0x1, 0x6, 0x3, 0x80, 0xdb, 0x2, 0x2, 0x1, 0x3a, 0x1, 0x1, 0x7, 0x1, 0x1,\n    0x1, 0x1, 0x2, 0x8, 0x6, 0xa, 0x2, 0x1, 0x80, 0x80, 0x4, 0x30, 0x1, 0x1,\n    0x5, 0x1, 0x1, 0x5, 0x1, 0x28, 0x9, 0xc, 0x2, 0x20, 0x4, 0x2, 0x2, 0x1,\n    0x1, 0x3a, 0x1, 0x1, 0x2, 0x3, 0x1, 0x1, 0x3, 0x3a, 0x8, 0x2, 0x2, 0x80,\n    0x98, 0x3, 0x1, 0xd, 0x1, 0x7, 0x4, 0x1, 0x6, 0x1, 0x80, 0xcb, 0x27,\n    0x15, 0x4, 0x82, 0xc, 0x2, 0x80, 0xc2, 0x21, 0x8b, 0xfe, 0x3, 0x80, 0x8d,\n    0x1, 0x60, 0x20, 0x82, 0x2a, 0x6, 0x69, 0x2, 0xa0, 0x75, 0xd4, 0x4, 0x1,\n    0xa, 0x21, 0x1, 0x50, 0x2, 0x81, 0x10, 0x1, 0x3, 0x1, 0x4, 0x1, 0x19, 0x2,\n    0x80, 0x9d, 0x1, 0x1b, 0x12, 0x34, 0x8, 0x19, 0xb, 0x2e, 0x3, 0x30, 0x1,\n    0x2, 0x4, 0x2, 0x1, 0x6c, 0x6, 0x2, 0x2, 0x2, 0x2, 0xc, 0x1, 0x8, 0x1,\n    0x63, 0x1, 0x1, 0x3, 0x2, 0x2, 0x5, 0x2, 0x1, 0x1, 0x2a, 0x2, 0x8, 0x1,\n    0x80, 0xee, 0x1, 0x2, 0x1, 0x4, 0x1, 0xa0, 0x4f, 0x30, 0x1, 0x82, 0xe1,\n    0x10, 0x10, 0x7, 0x81, 0x77, 0x2, 0x82, 0x5d, 0x1, 0x88, 0x3, 0x3, 0x1,\n    0x2, 0x5, 0x4, 0x28, 0x3, 0x4, 0x1, 0x85, 0xc1, 0x1, 0x36, 0xf, 0x39,\n    0x2, 0x31, 0x4, 0x2, 0x2, 0x45, 0x3, 0x24, 0x5, 0x1, 0x8, 0x4b, 0x2,\n    0x34, 0x9, 0x84, 0xec, 0x1, 0x1, 0x1, 0x2, 0x6, 0x1, 0x1, 0xa0, 0x58, 0xd7,\n    0x4, 0xa0, 0x61, 0xd2, 0x1, 0x1, 0x3, 0x4, 0x5, 0x8, 0x8, 0x2, 0x7, 0x1e,\n    0x4, 0x80, 0x94, 0x3, 0xac, 0x2e, 0xbb, 0x80, 0xf0\n];\n_T Hyphen = [0x2d, 0x1, 0x7f, 0x1, 0x84, 0xdc, 0x1, 0x92, 0x7b, 0x1, 0x88, 0x9,\n    0x2, 0x8e, 0x5, 0x1, 0x82, 0xe3, 0x1, 0xa0, 0xcd, 0x67, 0x1, 0x80, 0xa9, 0x1, 0x57,\n    0x1];\n_T Pe = [0x29, 0x1, 0x33, 0x1, 0x1f, 0x1, 0x8e, 0xbd, 0x1, 0x1, 0x1, 0x87,\n    0x5e, 0x1, 0x89, 0xa9, 0x1, 0x37, 0x1, 0xf, 0x1, 0x82, 0x7a, 0x1, 0x1, 0x1,\n    0x1e, 0x1, 0x84, 0x3e, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x50, 0x1, 0x20, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x81, 0x94, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x40, 0x1, 0x1, 0x1,\n    0x21, 0x1, 0x84, 0x25, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x81, 0xdf, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x2, 0x2, 0xa0, 0xcd, 0x1f, 0x1, 0x80, 0xd8, 0x1, 0x1d, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x3, 0x1, 0x11, 0x1, 0x1, 0x1, 0x1, 0x1, 0x80, 0xaa, 0x1, 0x33, 0x1, 0x1f,\n    0x1, 0x2, 0x1, 0x2, 0x1];\n_U[] _tab = [\n_U(\"Alphabetic\", Alphabetic),\n_U(\"ASCII_Hex_Digit\", ASCII_Hex_Digit),\n_U(\"Bidi_Control\", Bidi_Control),\n_U(\"Cased\", Cased),\n_U(\"Case_Ignorable\", Case_Ignorable),\n_U(\"Cc\", Cc),\n_U(\"Cf\", Cf),\n_U(\"Close_Punctuation\", Pe),\n_U(\"Cn\", Cn),\n_U(\"Co\", Co),\n_U(\"Connector_Punctuation\", Pc),\n_U(\"Control\", Cc),\n_U(\"Cs\", Cs),\n_U(\"Currency_Symbol\", Sc),\n_U(\"Dash\", Dash),\n_U(\"Dash_Punctuation\", Pd),\n_U(\"Decimal_Number\", Nd),\n_U(\"Default_Ignorable_Code_Point\", Default_Ignorable_Code_Point),\n_U(\"Deprecated\", Deprecated),\n_U(\"Diacritic\", Diacritic),\n_U(\"Enclosing_Mark\", Me),\n_U(\"Extender\", Extender),\n_U(\"Final_Punctuation\", Pf),\n_U(\"Format\", Cf),\n_U(\"Grapheme_Base\", Grapheme_Base),\n_U(\"Grapheme_Extend\", Grapheme_Extend),\n_U(\"Grapheme_Link\", Grapheme_Link),\n_U(\"Hex_Digit\", Hex_Digit),\n_U(\"Hyphen\", Hyphen),\n_U(\"ID_Continue\", ID_Continue),\n_U(\"Ideographic\", Ideographic),\n_U(\"IDS_Binary_Operator\", IDS_Binary_Operator),\n_U(\"ID_Start\", ID_Start),\n_U(\"IDS_Trinary_Operator\", IDS_Trinary_Operator),\n_U(\"Initial_Punctuation\", Pi),\n_U(\"Join_Control\", Join_Control),\n_U(\"Letter_Number\", Nl),\n_U(\"Line_Separator\", Zl),\n_U(\"Ll\", Ll),\n_U(\"Lm\", Lm),\n_U(\"Lo\", Lo),\n_U(\"Logical_Order_Exception\", Logical_Order_Exception),\n_U(\"Lowercase\", Lowercase),\n_U(\"Lowercase_Letter\", Ll),\n_U(\"Lt\", Lt),\n_U(\"Lu\", Lu),\n_U(\"Math\", Math),\n_U(\"Math_Symbol\", Sm),\n_U(\"Mc\", Mc),\n_U(\"Me\", Me),\n_U(\"Mn\", Mn),\n_U(\"Modifier_Letter\", Lm),\n_U(\"Modifier_Symbol\", Sk),\n_U(\"Nd\", Nd),\n_U(\"Nl\", Nl),\n_U(\"No\", No),\n_U(\"Noncharacter_Code_Point\", Noncharacter_Code_Point),\n_U(\"Nonspacing_Mark\", Mn),\n_U(\"Open_Punctuation\", Ps),\n_U(\"Other_Alphabetic\", Other_Alphabetic),\n_U(\"Other_Default_Ignorable_Code_Point\", Other_Default_Ignorable_Code_Point),\n_U(\"Other_Grapheme_Extend\", Other_Grapheme_Extend),\n_U(\"Other_ID_Continue\", Other_ID_Continue),\n_U(\"Other_ID_Start\", Other_ID_Start),\n_U(\"Other_Letter\", Lo),\n_U(\"Other_Lowercase\", Other_Lowercase),\n_U(\"Other_Math\", Other_Math),\n_U(\"Other_Number\", No),\n_U(\"Other_Punctuation\", Po),\n_U(\"Other_Symbol\", So),\n_U(\"Other_Uppercase\", Other_Uppercase),\n_U(\"Paragraph_Separator\", Zp),\n_U(\"Pattern_Syntax\", Pattern_Syntax),\n_U(\"Pattern_White_Space\", Pattern_White_Space),\n_U(\"Pc\", Pc),\n_U(\"Pd\", Pd),\n_U(\"Pe\", Pe),\n_U(\"Pf\", Pf),\n_U(\"Pi\", Pi),\n_U(\"Po\", Po),\n_U(\"Private_Use\", Co),\n_U(\"Ps\", Ps),\n_U(\"Quotation_Mark\", Quotation_Mark),\n_U(\"Radical\", Radical),\n_U(\"Sc\", Sc),\n_U(\"Sk\", Sk),\n_U(\"Sm\", Sm),\n_U(\"So\", So),\n_U(\"Soft_Dotted\", Soft_Dotted),\n_U(\"Space_Separator\", Zs),\n_U(\"Spacing_Mark\", Mc),\n_U(\"STerm\", STerm),\n_U(\"Surrogate\", Cs),\n_U(\"Terminal_Punctuation\", Terminal_Punctuation),\n_U(\"Titlecase_Letter\", Lt),\n_U(\"Unassigned\", Cn),\n_U(\"Unified_Ideograph\", Unified_Ideograph),\n_U(\"Uppercase\", Uppercase),\n_U(\"Uppercase_Letter\", Lu),\n_U(\"Variation_Selector\", Variation_Selector),\n_U(\"White_Space\", White_Space),\n_U(\"XID_Continue\", XID_Continue),\n_U(\"XID_Start\", XID_Start),\n_U(\"Zl\", Zl),\n_U(\"Zp\", Zp),\n_U(\"Zs\", Zs),\n];\n}\n\nstruct blocks\n{\nprivate alias _U = immutable(UnicodeProperty);\n@property static _U[] tab() pure { return _tab; }\nstatic immutable:\nprivate alias _T = ubyte[];\n_T Number_Forms = [0xa0, 0x21, 0x50, 0x40];\n_T Sinhala = [0x8d, 0x80, 0x80, 0x80];\n_T Domino_Tiles = [0xa1, 0xf0, 0x30, 0x70];\n_T Oriya = [0x8b, 0x0, 0x80, 0x80];\n_T Thaana = [0x87, 0x80, 0x40];\n_T New_Tai_Lue = [0x99, 0x80, 0x60];\n_T Byzantine_Musical_Symbols = [0xa1, 0xd0, 0x0, 0x81, 0x0];\n_T Cham = [0xa0, 0xaa, 0x0, 0x60];\n_T IPA_Extensions = [0x82, 0x50, 0x60];\n_T Bopomofo = [0xa0, 0x31, 0x0, 0x30];\n_T Katakana_Phonetic_Extensions = [0xa0, 0x31, 0xf0, 0x10];\n_T Khmer_Symbols = [0x99, 0xe0, 0x20];\n_T Hebrew = [0x85, 0x90, 0x70];\n_T Saurashtra = [0xa0, 0xa8, 0x80, 0x60];\n_T Inscriptional_Parthian = [0xa1, 0xb, 0x40, 0x20];\n_T Lisu = [0xa0, 0xa4, 0xd0, 0x30];\n_T Latin_1_Supplement = [0x80, 0x80, 0x80, 0x80];\n_T Arabic_Extended_A = [0x88, 0xa0, 0x60];\n_T Tai_Tham = [0x9a, 0x20, 0x80, 0x90];\n_T Latin_Extended_A = [0x81, 0x0, 0x80, 0x80];\n_T Latin_Extended_B = [0x81, 0x80, 0x80, 0xd0];\n_T Latin_Extended_C = [0xa0, 0x2c, 0x60, 0x20];\n_T Latin_Extended_D = [0xa0, 0xa7, 0x20, 0x80, 0xe0];\n_T CJK_Radicals_Supplement = [0xa0, 0x2e, 0x80, 0x80, 0x80];\n_T Meroitic_Hieroglyphs = [0xa1, 0x9, 0x80, 0x20];\n_T Linear_B_Syllabary = [0xa1, 0x0, 0x0, 0x80, 0x80];\n_T Phonetic_Extensions_Supplement = [0x9d, 0x80, 0x40];\n_T Meroitic_Cursive = [0xa1, 0x9, 0xa0, 0x60];\n_T Enclosed_Ideographic_Supplement = [0xa1, 0xf2, 0x0, 0x81, 0x0];\n_T Halfwidth_and_Fullwidth_Forms = [0xa0, 0xff, 0x0, 0x80, 0xf0];\n_T Takri = [0xa1, 0x16, 0x80, 0x50];\n_T Supplemental_Punctuation = [0xa0, 0x2e, 0x0, 0x80, 0x80];\n_T Malayalam = [0x8d, 0x0, 0x80, 0x80];\n_T Lepcha = [0x9c, 0x0, 0x50];\n_T Miscellaneous_Symbols_And_Pictographs = [0xa1, 0xf3, 0x0, 0x83, 0x0];\n_T Arabic_Presentation_Forms_A = [0xa0, 0xfb, 0x50, 0x82, 0xb0];\n_T Sora_Sompeng = [0xa1, 0x10, 0xd0, 0x30];\n_T Lydian = [0xa1, 0x9, 0x20, 0x20];\n_T Hangul_Jamo_Extended_B = [0xa0, 0xd7, 0xb0, 0x50];\n_T Private_Use_Area = [0xa0, 0xe0, 0x0, 0x99, 0x0];\n_T Coptic = [0xa0, 0x2c, 0x80, 0x80, 0x80];\n_T Phaistos_Disc = [0xa1, 0x1, 0xd0, 0x30];\n_T Batak = [0x9b, 0xc0, 0x40];\n_T Khmer = [0x97, 0x80, 0x80, 0x80];\n_T Counting_Rod_Numerals = [0xa1, 0xd3, 0x60, 0x20];\n_T Old_South_Arabian = [0xa1, 0xa, 0x60, 0x20];\n_T Kannada = [0x8c, 0x80, 0x80, 0x80];\n_T Arrows = [0xa0, 0x21, 0x90, 0x70];\n_T CJK_Compatibility_Ideographs_Supplement = [0xa2, 0xf8, 0x0, 0x82, 0x20];\n_T Combining_Half_Marks = [0xa0, 0xfe, 0x20, 0x10];\n_T Miscellaneous_Technical = [0xa0, 0x23, 0x0, 0x81, 0x0];\n_T Thai = [0x8e, 0x0, 0x80, 0x80];\n_T Alphabetic_Presentation_Forms = [0xa0, 0xfb, 0x0, 0x50];\n_T CJK_Unified_Ideographs = [0xa0, 0x4e, 0x0, 0xa0, 0x52, 0x0];\n_T Phonetic_Extensions = [0x9d, 0x0, 0x80, 0x80];\n_T Kayah_Li = [0xa0, 0xa9, 0x0, 0x30];\n_T Supplementary_Private_Use_Area_B = [0xb0, 0x0, 0x0];\n_T Gujarati = [0x8a, 0x80, 0x80, 0x80];\n_T Unified_Canadian_Aboriginal_Syllabics_Extended = [0x98, 0xb0, 0x50];\n_T Hangul_Syllables = [0xa0, 0xac, 0x0, 0xa0, 0x2b, 0xb0];\n_T Vertical_Forms = [0xa0, 0xfe, 0x10, 0x10];\n_T Inscriptional_Pahlavi = [0xa1, 0xb, 0x60, 0x20];\n_T Control_Pictures = [0xa0, 0x24, 0x0, 0x40];\n_T Carian = [0xa1, 0x2, 0xa0, 0x40];\n_T Mahjong_Tiles = [0xa1, 0xf0, 0x0, 0x30];\n_T Geometric_Shapes = [0xa0, 0x25, 0xa0, 0x60];\n_T Cherokee = [0x93, 0xa0, 0x60];\n_T Imperial_Aramaic = [0xa1, 0x8, 0x40, 0x20];\n_T Rumi_Numeral_Symbols = [0xa1, 0xe, 0x60, 0x20];\n_T Combining_Diacritical_Marks = [0x83, 0x0, 0x70];\n_T Specials = [0xa0, 0xff, 0xf0, 0x10];\n_T Greek_Extended = [0x9f, 0x0, 0x81, 0x0];\n_T Ethiopic_Supplement = [0x93, 0x80, 0x20];\n_T Limbu = [0x99, 0x0, 0x50];\n_T Basic_Latin = [0x0, 0x80, 0x80];\n_T Enclosed_Alphanumeric_Supplement = [0xa1, 0xf1, 0x0, 0x81, 0x0];\n_T Cyrillic_Supplement = [0x85, 0x0, 0x30];\n_T Hangul_Compatibility_Jamo = [0xa0, 0x31, 0x30, 0x60];\n_T Supplemental_Arrows_A = [0xa0, 0x27, 0xf0, 0x10];\n_T Supplemental_Arrows_B = [0xa0, 0x29, 0x0, 0x80, 0x80];\n_T Katakana = [0xa0, 0x30, 0xa0, 0x60];\n_T Ancient_Greek_Musical_Notation = [0xa1, 0xd2, 0x0, 0x50];\n_T CJK_Compatibility = [0xa0, 0x33, 0x0, 0x81, 0x0];\n_T Old_Persian = [0xa1, 0x3, 0xa0, 0x40];\n_T Small_Form_Variants = [0xa0, 0xfe, 0x50, 0x20];\n_T General_Punctuation = [0xa0, 0x20, 0x0, 0x70];\n_T Miscellaneous_Mathematical_Symbols_A = [0xa0, 0x27, 0xc0, 0x30];\n_T Latin_Extended_Additional = [0x9e, 0x0, 0x81, 0x0];\n_T Playing_Cards = [0xa1, 0xf0, 0xa0, 0x60];\n_T Syriac = [0x87, 0x0, 0x50];\n_T Alchemical_Symbols = [0xa1, 0xf7, 0x0, 0x80, 0x80];\n_T Tibetan = [0x8f, 0x0, 0x81, 0x0];\n_T CJK_Strokes = [0xa0, 0x31, 0xc0, 0x30];\n_T Tamil = [0x8b, 0x80, 0x80, 0x80];\n_T Balinese = [0x9b, 0x0, 0x80, 0x80];\n_T Shavian = [0xa1, 0x4, 0x50, 0x30];\n_T Greek_and_Coptic = [0x83, 0x70, 0x80, 0x90];\n_T Telugu = [0x8c, 0x0, 0x80, 0x80];\n_T Runic = [0x96, 0xa0, 0x60];\n_T Javanese = [0xa0, 0xa9, 0x80, 0x60];\n_T Bopomofo_Extended = [0xa0, 0x31, 0xa0, 0x20];\n_T Ideographic_Description_Characters = [0xa0, 0x2f, 0xf0, 0x10];\n_T Old_Turkic = [0xa1, 0xc, 0x0, 0x50];\n_T Unified_Canadian_Aboriginal_Syllabics = [0x94, 0x0, 0x82, 0x80];\n_T Ugaritic = [0xa1, 0x3, 0x80, 0x20];\n_T Egyptian_Hieroglyphs = [0xa1, 0x30, 0x0, 0x84, 0x30];\n_T Buginese = [0x9a, 0x0, 0x20];\n_T Kangxi_Radicals = [0xa0, 0x2f, 0x0, 0x80, 0xe0];\n_T Cuneiform = [0xa1, 0x20, 0x0, 0x84, 0x0];\n_T NKo = [0x87, 0xc0, 0x40];\n_T Sundanese_Supplement = [0x9c, 0xc0, 0x10];\n_T Buhid = [0x97, 0x40, 0x20];\n_T Modifier_Tone_Letters = [0xa0, 0xa7, 0x0, 0x20];\n_T Kanbun = [0xa0, 0x31, 0x90, 0x10];\n_T Superscripts_and_Subscripts = [0xa0, 0x20, 0x70, 0x30];\n_T Lao = [0x8e, 0x80, 0x80, 0x80];\n_T Ol_Chiki = [0x9c, 0x50, 0x30];\n_T Common_Indic_Number_Forms = [0xa0, 0xa8, 0x30, 0x10];\n_T Hangul_Jamo_Extended_A = [0xa0, 0xa9, 0x60, 0x20];\n_T Arabic_Presentation_Forms_B = [0xa0, 0xfe, 0x70, 0x80, 0x90];\n_T Sharada = [0xa1, 0x11, 0x80, 0x60];\n_T Miscellaneous_Symbols = [0xa0, 0x26, 0x0, 0x81, 0x0];\n_T Variation_Selectors_Supplement = [0xae, 0x1, 0x0, 0x80, 0xf0];\n_T Rejang = [0xa0, 0xa9, 0x30, 0x30];\n_T Georgian_Supplement = [0xa0, 0x2d, 0x0, 0x30];\n_T Braille_Patterns = [0xa0, 0x28, 0x0, 0x81, 0x0];\n_T Lycian = [0xa1, 0x2, 0x80, 0x20];\n_T Tai_Le = [0x99, 0x50, 0x30];\n_T Miscellaneous_Mathematical_Symbols_B = [0xa0, 0x29, 0x80, 0x80, 0x80];\n_T Musical_Symbols = [0xa1, 0xd1, 0x0, 0x81, 0x0];\n_T Avestan = [0xa1, 0xb, 0x0, 0x40];\n_T Ethiopic = [0x92, 0x0, 0x81, 0x80];\n_T Arabic_Supplement = [0x87, 0x50, 0x30];\n_T Samaritan = [0x88, 0x0, 0x40];\n_T Cuneiform_Numbers_and_Punctuation = [0xa1, 0x24, 0x0, 0x80, 0x80];\n_T Mongolian = [0x98, 0x0, 0x80, 0xb0];\n_T Arabic = [0x86, 0x0, 0x81, 0x0];\n_T Vai = [0xa0, 0xa5, 0x0, 0x81, 0x40];\n_T Tifinagh = [0xa0, 0x2d, 0x30, 0x50];\n_T Bamum_Supplement = [0xa1, 0x68, 0x0, 0x82, 0x40];\n_T Tai_Viet = [0xa0, 0xaa, 0x80, 0x60];\n_T Mandaic = [0x88, 0x40, 0x20];\n_T Sundanese = [0x9b, 0x80, 0x40];\n_T Block_Elements = [0xa0, 0x25, 0x80, 0x20];\n_T Phoenician = [0xa1, 0x9, 0x0, 0x20];\n_T Hanunoo = [0x97, 0x20, 0x20];\n_T Supplemental_Mathematical_Operators = [0xa0, 0x2a, 0x0, 0x81, 0x0];\n_T Deseret = [0xa1, 0x4, 0x0, 0x50];\n_T Brahmi = [0xa1, 0x10, 0x0, 0x80, 0x80];\n_T Devanagari_Extended = [0xa0, 0xa8, 0xe0, 0x20];\n_T Supplementary_Private_Use_Area_A = [0xaf, 0x0, 0x0, 0xa1, 0x0, 0x0];\n_T Box_Drawing = [0xa0, 0x25, 0x0, 0x80, 0x80];\n_T Mathematical_Operators = [0xa0, 0x22, 0x0, 0x81, 0x0];\n_T Ogham = [0x96, 0x80, 0x20];\n_T Meetei_Mayek_Extensions = [0xa0, 0xaa, 0xe0, 0x20];\n_T Hangul_Jamo = [0x91, 0x0, 0x81, 0x0];\n_T Miao = [0xa1, 0x6f, 0x0, 0x80, 0xa0];\n_T Emoticons = [0xa1, 0xf6, 0x0, 0x50];\n_T Tags = [0xae, 0x0, 0x0, 0x80, 0x80];\n_T Yi_Syllables = [0xa0, 0xa0, 0x0, 0x84, 0x90];\n_T Gurmukhi = [0x8a, 0x0, 0x80, 0x80];\n_T Syloti_Nagri = [0xa0, 0xa8, 0x0, 0x30];\n_T Spacing_Modifier_Letters = [0x82, 0xb0, 0x50];\n_T Yi_Radicals = [0xa0, 0xa4, 0x90, 0x40];\n_T Ancient_Greek_Numbers = [0xa1, 0x1, 0x40, 0x50];\n_T Glagolitic = [0xa0, 0x2c, 0x0, 0x60];\n_T Georgian = [0x90, 0xa0, 0x60];\n_T Osmanya = [0xa1, 0x4, 0x80, 0x30];\n_T Variation_Selectors = [0xa0, 0xfe, 0x0, 0x10];\n_T Mathematical_Alphanumeric_Symbols = [0xa1, 0xd4, 0x0, 0x84, 0x0];\n_T Yijing_Hexagram_Symbols = [0xa0, 0x4d, 0xc0, 0x40];\n_T Ethiopic_Extended = [0xa0, 0x2d, 0x80, 0x60];\n_T Transport_And_Map_Symbols = [0xa1, 0xf6, 0x80, 0x80, 0x80];\n_T High_Private_Use_Surrogates = [0xa0, 0xdb, 0x80, 0x80, 0x80];\n_T Meetei_Mayek = [0xa0, 0xab, 0xc0, 0x40];\n_T CJK_Compatibility_Forms = [0xa0, 0xfe, 0x30, 0x20];\n_T Enclosed_Alphanumerics = [0xa0, 0x24, 0x60, 0x80, 0xa0];\n_T Ancient_Symbols = [0xa1, 0x1, 0x90, 0x40];\n_T Ethiopic_Extended_A = [0xa0, 0xab, 0x0, 0x30];\n_T Bengali = [0x89, 0x80, 0x80, 0x80];\n_T Currency_Symbols = [0xa0, 0x20, 0xa0, 0x30];\n_T Myanmar = [0x90, 0x0, 0x80, 0xa0];\n_T Cyrillic_Extended_A = [0xa0, 0x2d, 0xe0, 0x20];\n_T Cyrillic_Extended_B = [0xa0, 0xa6, 0x40, 0x60];\n_T Myanmar_Extended_A = [0xa0, 0xaa, 0x60, 0x20];\n_T Hiragana = [0xa0, 0x30, 0x40, 0x60];\n_T Dingbats = [0xa0, 0x27, 0x0, 0x80, 0xc0];\n_T Armenian = [0x85, 0x30, 0x60];\n_T Tai_Xuan_Jing_Symbols = [0xa1, 0xd3, 0x0, 0x60];\n_T Linear_B_Ideograms = [0xa1, 0x0, 0x80, 0x80, 0x80];\n_T Kharoshthi = [0xa1, 0xa, 0x0, 0x60];\n_T Optical_Character_Recognition = [0xa0, 0x24, 0x40, 0x20];\n_T Enclosed_CJK_Letters_and_Months = [0xa0, 0x32, 0x0, 0x81, 0x0];\n_T Cypriot_Syllabary = [0xa1, 0x8, 0x0, 0x40];\n_T Vedic_Extensions = [0x9c, 0xd0, 0x30];\n_T Kaithi = [0xa1, 0x10, 0x80, 0x50];\n_T Low_Surrogates = [0xa0, 0xdc, 0x0, 0x84, 0x0];\n_T Letterlike_Symbols = [0xa0, 0x21, 0x0, 0x50];\n_T Combining_Diacritical_Marks_for_Symbols = [0xa0, 0x20, 0xd0, 0x30];\n_T Aegean_Numbers = [0xa1, 0x1, 0x0, 0x40];\n_T High_Surrogates = [0xa0, 0xd8, 0x0, 0x83, 0x80];\n_T CJK_Compatibility_Ideographs = [0xa0, 0xf9, 0x0, 0x82, 0x0];\n_T CJK_Symbols_and_Punctuation = [0xa0, 0x30, 0x0, 0x40];\n_T Gothic = [0xa1, 0x3, 0x30, 0x20];\n_T Combining_Diacritical_Marks_Supplement = [0x9d, 0xc0, 0x40];\n_T Phags_pa = [0xa0, 0xa8, 0x40, 0x40];\n_T Miscellaneous_Symbols_and_Arrows = [0xa0, 0x2b, 0x0, 0x81, 0x0];\n_T Bamum = [0xa0, 0xa6, 0xa0, 0x60];\n_T Chakma = [0xa1, 0x11, 0x0, 0x50];\n_T Kana_Supplement = [0xa1, 0xb0, 0x0, 0x81, 0x0];\n_T Tagalog = [0x97, 0x0, 0x20];\n_T Tagbanwa = [0x97, 0x60, 0x20];\n_T Devanagari = [0x89, 0x0, 0x80, 0x80];\n_T Old_Italic = [0xa1, 0x3, 0x0, 0x30];\n_T Arabic_Mathematical_Alphabetic_Symbols = [0xa1, 0xee, 0x0, 0x81, 0x0];\n_T CJK_Unified_Ideographs_Extension_D = [0xa2, 0xb7, 0x40, 0x80, 0xe0];\n_T CJK_Unified_Ideographs_Extension_A = [0xa0, 0x34, 0x0, 0x99, 0xc0];\n_T CJK_Unified_Ideographs_Extension_B = [0xa2, 0x0, 0x0, 0xa0, 0xa6, 0xe0];\n_T CJK_Unified_Ideographs_Extension_C = [0xa2, 0xa7, 0x0, 0x90, 0x40];\n_T Cyrillic = [0x84, 0x0, 0x81, 0x0];\n_U[] _tab = [\n_U(\"Aegean Numbers\", Aegean_Numbers),\n_U(\"Alchemical Symbols\", Alchemical_Symbols),\n_U(\"Alphabetic Presentation Forms\", Alphabetic_Presentation_Forms),\n_U(\"Ancient Greek Musical Notation\", Ancient_Greek_Musical_Notation),\n_U(\"Ancient Greek Numbers\", Ancient_Greek_Numbers),\n_U(\"Ancient Symbols\", Ancient_Symbols),\n_U(\"Arabic\", Arabic),\n_U(\"Arabic Extended-A\", Arabic_Extended_A),\n_U(\"Arabic Mathematical Alphabetic Symbols\", Arabic_Mathematical_Alphabetic_Symbols),\n_U(\"Arabic Presentation Forms-A\", Arabic_Presentation_Forms_A),\n_U(\"Arabic Presentation Forms-B\", Arabic_Presentation_Forms_B),\n_U(\"Arabic Supplement\", Arabic_Supplement),\n_U(\"Armenian\", Armenian),\n_U(\"Arrows\", Arrows),\n_U(\"Avestan\", Avestan),\n_U(\"Balinese\", Balinese),\n_U(\"Bamum\", Bamum),\n_U(\"Bamum Supplement\", Bamum_Supplement),\n_U(\"Basic Latin\", Basic_Latin),\n_U(\"Batak\", Batak),\n_U(\"Bengali\", Bengali),\n_U(\"Block Elements\", Block_Elements),\n_U(\"Bopomofo\", Bopomofo),\n_U(\"Bopomofo Extended\", Bopomofo_Extended),\n_U(\"Box Drawing\", Box_Drawing),\n_U(\"Brahmi\", Brahmi),\n_U(\"Braille Patterns\", Braille_Patterns),\n_U(\"Buginese\", Buginese),\n_U(\"Buhid\", Buhid),\n_U(\"Byzantine Musical Symbols\", Byzantine_Musical_Symbols),\n_U(\"Carian\", Carian),\n_U(\"Chakma\", Chakma),\n_U(\"Cham\", Cham),\n_U(\"Cherokee\", Cherokee),\n_U(\"CJK Compatibility\", CJK_Compatibility),\n_U(\"CJK Compatibility Forms\", CJK_Compatibility_Forms),\n_U(\"CJK Compatibility Ideographs\", CJK_Compatibility_Ideographs),\n_U(\"CJK Compatibility Ideographs Supplement\", CJK_Compatibility_Ideographs_Supplement),\n_U(\"CJK Radicals Supplement\", CJK_Radicals_Supplement),\n_U(\"CJK Strokes\", CJK_Strokes),\n_U(\"CJK Symbols and Punctuation\", CJK_Symbols_and_Punctuation),\n_U(\"CJK Unified Ideographs\", CJK_Unified_Ideographs),\n_U(\"CJK Unified Ideographs Extension A\", CJK_Unified_Ideographs_Extension_A),\n_U(\"CJK Unified Ideographs Extension B\", CJK_Unified_Ideographs_Extension_B),\n_U(\"CJK Unified Ideographs Extension C\", CJK_Unified_Ideographs_Extension_C),\n_U(\"CJK Unified Ideographs Extension D\", CJK_Unified_Ideographs_Extension_D),\n_U(\"Combining Diacritical Marks\", Combining_Diacritical_Marks),\n_U(\"Combining Diacritical Marks for Symbols\", Combining_Diacritical_Marks_for_Symbols),\n_U(\"Combining Diacritical Marks Supplement\", Combining_Diacritical_Marks_Supplement),\n_U(\"Combining Half Marks\", Combining_Half_Marks),\n_U(\"Common Indic Number Forms\", Common_Indic_Number_Forms),\n_U(\"Control Pictures\", Control_Pictures),\n_U(\"Coptic\", Coptic),\n_U(\"Counting Rod Numerals\", Counting_Rod_Numerals),\n_U(\"Cuneiform\", Cuneiform),\n_U(\"Cuneiform Numbers and Punctuation\", Cuneiform_Numbers_and_Punctuation),\n_U(\"Currency Symbols\", Currency_Symbols),\n_U(\"Cypriot Syllabary\", Cypriot_Syllabary),\n_U(\"Cyrillic\", Cyrillic),\n_U(\"Cyrillic Extended-A\", Cyrillic_Extended_A),\n_U(\"Cyrillic Extended-B\", Cyrillic_Extended_B),\n_U(\"Cyrillic Supplement\", Cyrillic_Supplement),\n_U(\"Deseret\", Deseret),\n_U(\"Devanagari\", Devanagari),\n_U(\"Devanagari Extended\", Devanagari_Extended),\n_U(\"Dingbats\", Dingbats),\n_U(\"Domino Tiles\", Domino_Tiles),\n_U(\"Egyptian Hieroglyphs\", Egyptian_Hieroglyphs),\n_U(\"Emoticons\", Emoticons),\n_U(\"Enclosed Alphanumerics\", Enclosed_Alphanumerics),\n_U(\"Enclosed Alphanumeric Supplement\", Enclosed_Alphanumeric_Supplement),\n_U(\"Enclosed CJK Letters and Months\", Enclosed_CJK_Letters_and_Months),\n_U(\"Enclosed Ideographic Supplement\", Enclosed_Ideographic_Supplement),\n_U(\"Ethiopic\", Ethiopic),\n_U(\"Ethiopic Extended\", Ethiopic_Extended),\n_U(\"Ethiopic Extended-A\", Ethiopic_Extended_A),\n_U(\"Ethiopic Supplement\", Ethiopic_Supplement),\n_U(\"General Punctuation\", General_Punctuation),\n_U(\"Geometric Shapes\", Geometric_Shapes),\n_U(\"Georgian\", Georgian),\n_U(\"Georgian Supplement\", Georgian_Supplement),\n_U(\"Glagolitic\", Glagolitic),\n_U(\"Gothic\", Gothic),\n_U(\"Greek and Coptic\", Greek_and_Coptic),\n_U(\"Greek Extended\", Greek_Extended),\n_U(\"Gujarati\", Gujarati),\n_U(\"Gurmukhi\", Gurmukhi),\n_U(\"Halfwidth and Fullwidth Forms\", Halfwidth_and_Fullwidth_Forms),\n_U(\"Hangul Compatibility Jamo\", Hangul_Compatibility_Jamo),\n_U(\"Hangul Jamo\", Hangul_Jamo),\n_U(\"Hangul Jamo Extended-A\", Hangul_Jamo_Extended_A),\n_U(\"Hangul Jamo Extended-B\", Hangul_Jamo_Extended_B),\n_U(\"Hangul Syllables\", Hangul_Syllables),\n_U(\"Hanunoo\", Hanunoo),\n_U(\"Hebrew\", Hebrew),\n_U(\"High Private Use Surrogates\", High_Private_Use_Surrogates),\n_U(\"High Surrogates\", High_Surrogates),\n_U(\"Hiragana\", Hiragana),\n_U(\"Ideographic Description Characters\", Ideographic_Description_Characters),\n_U(\"Imperial Aramaic\", Imperial_Aramaic),\n_U(\"Inscriptional Pahlavi\", Inscriptional_Pahlavi),\n_U(\"Inscriptional Parthian\", Inscriptional_Parthian),\n_U(\"IPA Extensions\", IPA_Extensions),\n_U(\"Javanese\", Javanese),\n_U(\"Kaithi\", Kaithi),\n_U(\"Kana Supplement\", Kana_Supplement),\n_U(\"Kanbun\", Kanbun),\n_U(\"Kangxi Radicals\", Kangxi_Radicals),\n_U(\"Kannada\", Kannada),\n_U(\"Katakana\", Katakana),\n_U(\"Katakana Phonetic Extensions\", Katakana_Phonetic_Extensions),\n_U(\"Kayah Li\", Kayah_Li),\n_U(\"Kharoshthi\", Kharoshthi),\n_U(\"Khmer\", Khmer),\n_U(\"Khmer Symbols\", Khmer_Symbols),\n_U(\"Lao\", Lao),\n_U(\"Latin-1 Supplement\", Latin_1_Supplement),\n_U(\"Latin Extended-A\", Latin_Extended_A),\n_U(\"Latin Extended Additional\", Latin_Extended_Additional),\n_U(\"Latin Extended-B\", Latin_Extended_B),\n_U(\"Latin Extended-C\", Latin_Extended_C),\n_U(\"Latin Extended-D\", Latin_Extended_D),\n_U(\"Lepcha\", Lepcha),\n_U(\"Letterlike Symbols\", Letterlike_Symbols),\n_U(\"Limbu\", Limbu),\n_U(\"Linear B Ideograms\", Linear_B_Ideograms),\n_U(\"Linear B Syllabary\", Linear_B_Syllabary),\n_U(\"Lisu\", Lisu),\n_U(\"Low Surrogates\", Low_Surrogates),\n_U(\"Lycian\", Lycian),\n_U(\"Lydian\", Lydian),\n_U(\"Mahjong Tiles\", Mahjong_Tiles),\n_U(\"Malayalam\", Malayalam),\n_U(\"Mandaic\", Mandaic),\n_U(\"Mathematical Alphanumeric Symbols\", Mathematical_Alphanumeric_Symbols),\n_U(\"Mathematical Operators\", Mathematical_Operators),\n_U(\"Meetei Mayek\", Meetei_Mayek),\n_U(\"Meetei Mayek Extensions\", Meetei_Mayek_Extensions),\n_U(\"Meroitic Cursive\", Meroitic_Cursive),\n_U(\"Meroitic Hieroglyphs\", Meroitic_Hieroglyphs),\n_U(\"Miao\", Miao),\n_U(\"Miscellaneous Mathematical Symbols-A\", Miscellaneous_Mathematical_Symbols_A),\n_U(\"Miscellaneous Mathematical Symbols-B\", Miscellaneous_Mathematical_Symbols_B),\n_U(\"Miscellaneous Symbols\", Miscellaneous_Symbols),\n_U(\"Miscellaneous Symbols and Arrows\", Miscellaneous_Symbols_and_Arrows),\n_U(\"Miscellaneous Symbols And Pictographs\", Miscellaneous_Symbols_And_Pictographs),\n_U(\"Miscellaneous Technical\", Miscellaneous_Technical),\n_U(\"Modifier Tone Letters\", Modifier_Tone_Letters),\n_U(\"Mongolian\", Mongolian),\n_U(\"Musical Symbols\", Musical_Symbols),\n_U(\"Myanmar\", Myanmar),\n_U(\"Myanmar Extended-A\", Myanmar_Extended_A),\n_U(\"New Tai Lue\", New_Tai_Lue),\n_U(\"NKo\", NKo),\n_U(\"Number Forms\", Number_Forms),\n_U(\"Ogham\", Ogham),\n_U(\"Ol Chiki\", Ol_Chiki),\n_U(\"Old Italic\", Old_Italic),\n_U(\"Old Persian\", Old_Persian),\n_U(\"Old South Arabian\", Old_South_Arabian),\n_U(\"Old Turkic\", Old_Turkic),\n_U(\"Optical Character Recognition\", Optical_Character_Recognition),\n_U(\"Oriya\", Oriya),\n_U(\"Osmanya\", Osmanya),\n_U(\"Phags-pa\", Phags_pa),\n_U(\"Phaistos Disc\", Phaistos_Disc),\n_U(\"Phoenician\", Phoenician),\n_U(\"Phonetic Extensions\", Phonetic_Extensions),\n_U(\"Phonetic Extensions Supplement\", Phonetic_Extensions_Supplement),\n_U(\"Playing Cards\", Playing_Cards),\n_U(\"Private Use Area\", Private_Use_Area),\n_U(\"Rejang\", Rejang),\n_U(\"Rumi Numeral Symbols\", Rumi_Numeral_Symbols),\n_U(\"Runic\", Runic),\n_U(\"Samaritan\", Samaritan),\n_U(\"Saurashtra\", Saurashtra),\n_U(\"Sharada\", Sharada),\n_U(\"Shavian\", Shavian),\n_U(\"Sinhala\", Sinhala),\n_U(\"Small Form Variants\", Small_Form_Variants),\n_U(\"Sora Sompeng\", Sora_Sompeng),\n_U(\"Spacing Modifier Letters\", Spacing_Modifier_Letters),\n_U(\"Specials\", Specials),\n_U(\"Sundanese\", Sundanese),\n_U(\"Sundanese Supplement\", Sundanese_Supplement),\n_U(\"Superscripts and Subscripts\", Superscripts_and_Subscripts),\n_U(\"Supplemental Arrows-A\", Supplemental_Arrows_A),\n_U(\"Supplemental Arrows-B\", Supplemental_Arrows_B),\n_U(\"Supplemental Mathematical Operators\", Supplemental_Mathematical_Operators),\n_U(\"Supplemental Punctuation\", Supplemental_Punctuation),\n_U(\"Supplementary Private Use Area-A\", Supplementary_Private_Use_Area_A),\n_U(\"Supplementary Private Use Area-B\", Supplementary_Private_Use_Area_B),\n_U(\"Syloti Nagri\", Syloti_Nagri),\n_U(\"Syriac\", Syriac),\n_U(\"Tagalog\", Tagalog),\n_U(\"Tagbanwa\", Tagbanwa),\n_U(\"Tags\", Tags),\n_U(\"Tai Le\", Tai_Le),\n_U(\"Tai Tham\", Tai_Tham),\n_U(\"Tai Viet\", Tai_Viet),\n_U(\"Tai Xuan Jing Symbols\", Tai_Xuan_Jing_Symbols),\n_U(\"Takri\", Takri),\n_U(\"Tamil\", Tamil),\n_U(\"Telugu\", Telugu),\n_U(\"Thaana\", Thaana),\n_U(\"Thai\", Thai),\n_U(\"Tibetan\", Tibetan),\n_U(\"Tifinagh\", Tifinagh),\n_U(\"Transport And Map Symbols\", Transport_And_Map_Symbols),\n_U(\"Ugaritic\", Ugaritic),\n_U(\"Unified Canadian Aboriginal Syllabics\", Unified_Canadian_Aboriginal_Syllabics),\n_U(\"Unified Canadian Aboriginal Syllabics Extended\", Unified_Canadian_Aboriginal_Syllabics_Extended),\n_U(\"Vai\", Vai),\n_U(\"Variation Selectors\", Variation_Selectors),\n_U(\"Variation Selectors Supplement\", Variation_Selectors_Supplement),\n_U(\"Vedic Extensions\", Vedic_Extensions),\n_U(\"Vertical Forms\", Vertical_Forms),\n_U(\"Yijing Hexagram Symbols\", Yijing_Hexagram_Symbols),\n_U(\"Yi Radicals\", Yi_Radicals),\n_U(\"Yi Syllables\", Yi_Syllables),\n];\n}\n\nstruct scripts\n{\nprivate alias _U = immutable(UnicodeProperty);\n@property static _U[] tab() pure nothrow @nogc { return _tab; }\nstatic immutable:\nprivate alias _T = ubyte[];\n_T Buhid = [0x97, 0x40, 0x14];\n_T Sinhala = [0x8d, 0x82, 0x2, 0x1, 0x12, 0x3, 0x18, 0x1, 0x9, 0x1, 0x1, 0x2,\n    0x7, 0x3, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x8, 0x12, 0x3];\n_T Phags_Pa = [0xa0, 0xa8, 0x40, 0x38];\n_T Old_Turkic = [0xa1, 0xc, 0x0, 0x49];\n_T Oriya = [0x8b, 0x1, 0x3, 0x1, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1, 0x2,\n    0x1, 0x5, 0x2, 0x9, 0x2, 0x2, 0x2, 0x3, 0x8, 0x2, 0x4, 0x2, 0x1, 0x5, 0x2, 0x12];\n_T Thaana = [0x87, 0x80, 0x32];\n_T Inherited = [\n    0x83, 0x0, 0x70, 0x81, 0x15, 0x2, 0x81, 0xc4, 0xb, 0x1a, 0x1, 0x82, 0xe0,\n    0x2, 0x93, 0x7d, 0x3, 0x1, 0xd, 0x1, 0x7, 0x4, 0x1, 0x6, 0x1, 0x80, 0xcb,\n    0x27, 0x15, 0x4, 0x82, 0xc, 0x2, 0x80, 0xc2, 0x21, 0x8f, 0x39, 0x4, 0x6b,\n    0x2, 0xa0, 0xcd, 0x65, 0x10, 0x10, 0x7, 0x83, 0xd6, 0x1, 0xa0, 0xcf,\n    0x69, 0x3, 0x11, 0x8, 0x2, 0x7, 0x1e, 0x4, 0xac, 0x2f, 0x52, 0x80, 0xf0\n];\n_T Sharada = [0xa1, 0x11, 0x80, 0x49, 0x7, 0xa];\n_T Rejang = [0xa0, 0xa9, 0x30, 0x24, 0xb, 0x1];\n_T Imperial_Aramaic = [0xa1, 0x8, 0x40, 0x16, 0x1, 0x9];\n_T Cham = [0xa0, 0xaa, 0x0, 0x37, 0x9, 0xe, 0x2, 0xa, 0x2, 0x4];\n_T Kaithi = [0xa1, 0x10, 0x80, 0x42];\n_T Bopomofo = [0x82, 0xea, 0x2, 0xa0, 0x2e, 0x19, 0x29, 0x72, 0x1b];\n_T Deseret = [0xa1, 0x4, 0x0, 0x50];\n_T Syloti_Nagri = [0xa0, 0xa8, 0x0, 0x2c];\n_T Lycian = [0xa1, 0x2, 0x80, 0x1d];\n_T Linear_B = [0xa1, 0x0, 0x0, 0xc, 0x1, 0x1a, 0x1, 0x13, 0x1, 0x2, 0x1, 0xf,\n    0x2, 0xe, 0x22, 0x7b];\n_T Hebrew = [0x85, 0x91, 0x37, 0x8, 0x1b, 0x5, 0x5, 0xa0, 0xf5, 0x28, 0x1a,\n    0x1, 0x5, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0xa];\n_T Saurashtra = [0xa0, 0xa8, 0x80, 0x45, 0x9, 0xc];\n_T Avestan = [0xa1, 0xb, 0x0, 0x36, 0x3, 0x7];\n_T Ethiopic = [0x92, 0x0, 0x49, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2,\n    0x29, 0x1, 0x4, 0x2, 0x21, 0x1, 0x4, 0x2, 0x7, 0x1, 0x1, 0x1, 0x4, 0x2,\n    0xf, 0x1, 0x39, 0x1, 0x4, 0x2, 0x43, 0x2, 0x20, 0x3, 0x1a, 0x99, 0xe6,\n    0x17, 0x9, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x7,\n    0x1, 0x7, 0xa0, 0x7d, 0x22, 0x6, 0x2, 0x6, 0x2, 0x6, 0x9, 0x7, 0x1, 0x7];\n_T Braille = [0xa0, 0x28, 0x0, 0x81, 0x0];\n_T Lisu = [0xa0, 0xa4, 0xd0, 0x30];\n_T Samaritan = [0x88, 0x0, 0x2e, 0x2, 0xf];\n_T Mongolian = [0x98, 0x0, 0x2, 0x2, 0x1, 0x1, 0x9, 0x1, 0xa, 0x6, 0x58, 0x8, 0x2b];\n_T Hangul = [\n    0x91, 0x0, 0x81, 0x0, 0x9e, 0x2e, 0x2, 0x81, 0x1, 0x5e, 0x71, 0x1f, 0x41,\n    0x1f, 0xa0, 0x76, 0xe1, 0x1d, 0x82, 0x83, 0xa0, 0x2b, 0xa4, 0xc, 0x17, 0x4,\n    0x31, 0xa0, 0x27, 0xa4, 0x1f, 0x3, 0x6, 0x2, 0x6, 0x2, 0x6, 0x2, 0x3\n];\n_T Takri = [0xa1, 0x16, 0x80, 0x38, 0x8, 0xa];\n_T Phoenician = [0xa1, 0x9, 0x0, 0x1c, 0x3, 0x1];\n_T Vai = [0xa0, 0xa5, 0x0, 0x81, 0x2c];\n_T Batak = [0x9b, 0xc0, 0x34, 0x8, 0x4];\n_T Yi = [0xa0, 0xa0, 0x0, 0x84, 0x8d, 0x3, 0x37];\n_T Tifinagh = [0xa0, 0x2d, 0x30, 0x38, 0x7, 0x2, 0xe, 0x1];\n_T Glagolitic = [0xa0, 0x2c, 0x0, 0x2f, 0x1, 0x2f];\n_T Tai_Tham = [0x9a, 0x20, 0x3f, 0x1, 0x1d, 0x2, 0xb, 0x6, 0xa, 0x6, 0xe];\n_T Canadian_Aboriginal = [0x94, 0x0, 0x82, 0x80, 0x82, 0x30, 0x46];\n_T Meetei_Mayek = [0xa0, 0xaa, 0xe0, 0x17, 0x80, 0xc9, 0x2e, 0x2, 0xa];\n_T Balinese = [0x9b, 0x0, 0x4c, 0x4, 0x2d];\n_T Kayah_Li = [0xa0, 0xa9, 0x0, 0x30];\n_T Kharoshthi = [0xa1, 0xa, 0x0, 0x4, 0x1, 0x2, 0x5, 0x8, 0x1, 0x3, 0x1, 0x1b,\n    0x4, 0x3, 0x4, 0x9, 0x8, 0x9];\n_T Lepcha = [0x9c, 0x0, 0x38, 0x3, 0xf, 0x3, 0x3];\n_T New_Tai_Lue = [0x99, 0x80, 0x2c, 0x4, 0x1a, 0x6, 0xb, 0x3, 0x2];\n_T Sora_Sompeng = [0xa1, 0x10, 0xd0, 0x19, 0x7, 0xa];\n_T Arabic = [0x86, 0x0, 0x5, 0x1, 0x6, 0x1, 0xe, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x20, 0x1, 0xa, 0xb, 0xa, 0xa, 0x6, 0x1, 0x6c, 0x1, 0x22, 0x50, 0x30,\n    0x81, 0x20, 0x1, 0x1, 0xb, 0x37, 0x1b, 0xa0, 0xf2, 0x51, 0x72, 0x11, 0x81,\n    0x6b, 0x12, 0x40, 0x2, 0x36, 0x28, 0xd, 0x73, 0x5, 0x1, 0x80, 0x87, 0x8f,\n    0x63, 0x1f, 0xa0, 0xdf, 0x81, 0x4, 0x1, 0x1b, 0x1, 0x2, 0x1, 0x1, 0x2,\n    0x1, 0x1, 0xa, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x6, 0x1, 0x4, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x3, 0x1, 0x2, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,\n    0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x4, 0x1, 0x7, 0x1, 0x4, 0x1, 0x4,\n    0x1, 0x1, 0x1, 0xa, 0x1, 0x11, 0x5, 0x3, 0x1, 0x5, 0x1, 0x11, 0x34, 0x2];\n_T Hanunoo = [0x97, 0x20, 0x15];\n_T Lydian = [0xa1, 0x9, 0x20, 0x1a, 0x5, 0x1];\n_T Tai_Viet = [0xa0, 0xaa, 0x80, 0x43, 0x18, 0x5];\n_T Coptic = [0x83, 0xe2, 0xe, 0xa0, 0x28, 0x90, 0x74, 0x5, 0x7];\n_T Brahmi = [0xa1, 0x10, 0x0, 0x4e, 0x4, 0x1e];\n_T Runic = [0x96, 0xa0, 0x4b, 0x3, 0x3];\n_T Egyptian_Hieroglyphs = [0xa1, 0x30, 0x0, 0x84, 0x2f];\n_T Khmer = [0x97, 0x80, 0x5e, 0x2, 0xa, 0x6, 0xa, 0x81, 0xe6, 0x20];\n_T Ogham = [0x96, 0x80, 0x1d];\n_T Gothic = [0xa1, 0x3, 0x30, 0x1b];\n_T Katakana = [\n    0xa0, 0x30, 0xa1, 0x5a, 0x2, 0x3, 0x80, 0xf0, 0x10, 0x80, 0xd0, 0x2f, 0x1,\n    0x58, 0xa0, 0xcc, 0xe, 0xa, 0x1, 0x2d, 0xa0, 0xb0, 0x62, 0x1\n];\n_T Miao = [0xa1, 0x6f, 0x0, 0x45, 0xb, 0x2f, 0x10, 0x11];\n_T Meroitic_Hieroglyphs = [0xa1, 0x9, 0x80, 0x20];\n_T Thai = [0x8e, 0x1, 0x3a, 0x5, 0x1c];\n_T Cypriot = [0xa1, 0x8, 0x0, 0x6, 0x2, 0x1, 0x1, 0x2c, 0x1, 0x2, 0x3, 0x1, 0x2, 0x1];\n_T Meroitic_Cursive = [0xa1, 0x9, 0xa0, 0x18, 0x6, 0x2];\n_T Gujarati = [0x8a, 0x81, 0x3, 0x1, 0x9, 0x1, 0x3, 0x1, 0x16, 0x1, 0x7, 0x1,\n    0x2, 0x1, 0x5, 0x2, 0xa, 0x1, 0x3, 0x1, 0x3, 0x2, 0x1, 0xf, 0x4, 0x2, 0xc];\n_T Lao = [0x8e, 0x81, 0x2, 0x1, 0x1, 0x2, 0x2, 0x1, 0x1, 0x2, 0x1, 0x6, 0x4,\n    0x1, 0x7, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x1, 0xd, 0x1, 0x3, 0x2,\n    0x5, 0x1, 0x1, 0x1, 0x6, 0x2, 0xa, 0x2, 0x4];\n_T Georgian = [0x90, 0xa0, 0x26, 0x1, 0x1, 0x5, 0x1, 0x2, 0x2b, 0x1, 0x4, 0x9c,\n    0x0, 0x26, 0x1, 0x1, 0x5, 0x1];\n_T Osmanya = [0xa1, 0x4, 0x80, 0x1e, 0x2, 0xa];\n_T Inscriptional_Pahlavi = [0xa1, 0xb, 0x60, 0x13, 0x5, 0x8];\n_T Shavian = [0xa1, 0x4, 0x50, 0x30];\n_T Carian = [0xa1, 0x2, 0xa0, 0x31];\n_T Cherokee = [0x93, 0xa0, 0x55];\n_T Mandaic = [0x88, 0x40, 0x1c, 0x2, 0x1];\n_T Han = [0xa0, 0x2e, 0x80, 0x1a, 0x1, 0x59, 0xc, 0x80, 0xd6, 0x2f, 0x1, 0x1,\n    0x1, 0x19, 0x9, 0xe, 0x4, 0x83, 0xc4, 0x99, 0xb6, 0x4a, 0xa0, 0x51, 0xcd,\n    0xa0, 0x59, 0x33, 0x81, 0x6e, 0x2, 0x6a, 0xa1, 0x5, 0x26, 0xa0, 0xa6, 0xd7,\n    0x29, 0x90, 0x35, 0xb, 0x80, 0xde, 0xa0, 0x3f, 0xe2, 0x82, 0x1e];\n_T Latin = [0x41, 0x1a, 0x6, 0x1a, 0x2f, 0x1, 0xf, 0x1, 0x5, 0x17, 0x1, 0x1f,\n    0x1, 0x81, 0xc1, 0x27, 0x5, 0x9a, 0x1b, 0x26, 0x6, 0x31, 0x5, 0x4, 0x5,\n    0xd, 0x1, 0x46, 0x41, 0x81, 0x0, 0x81, 0x71, 0x1, 0xd, 0x1, 0x10, 0xd,\n    0x80, 0x8d, 0x2, 0x6, 0x1, 0x1b, 0x1, 0x11, 0x29, 0x8a, 0xd7, 0x20, 0xa0,\n    0x7a, 0xa2, 0x66, 0x3, 0x4, 0x1, 0x4, 0xc, 0xb, 0x4d, 0x8, 0xa0, 0x53, 0x0,\n    0x7, 0x84, 0x1a, 0x1a, 0x6, 0x1a];\n_T Limbu = [0x99, 0x0, 0x1d, 0x3, 0xc, 0x4, 0xc, 0x4, 0x1, 0x3, 0xc];\n_T Ol_Chiki = [0x9c, 0x50, 0x30];\n_T Bengali = [0x89, 0x81, 0x3, 0x1, 0x8, 0x2, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1,\n    0x1, 0x3, 0x4, 0x2, 0x9, 0x2, 0x2, 0x2, 0x4, 0x8, 0x1, 0x4, 0x2, 0x1, 0x5, 0x2,\n    0x16];\n_T Myanmar = [0x90, 0x0, 0x80, 0xa0, 0xa0, 0x99, 0xc0, 0x1c];\n_T Malayalam = [0x8d, 0x2, 0x2, 0x1, 0x8, 0x1, 0x3, 0x1, 0x29, 0x2, 0x8, 0x1,\n    0x3, 0x1, 0x5, 0x8, 0x1, 0x8, 0x4, 0x2, 0x10, 0x3, 0x7];\n_T Hiragana = [0xa0, 0x30, 0x41, 0x56, 0x6, 0x3, 0xa1, 0x7f, 0x61, 0x1, 0xa0, 0x41,\n    0xfe, 0x1];\n_T Kannada = [0x8c, 0x82, 0x2, 0x1, 0x8, 0x1, 0x3, 0x1, 0x17, 0x1, 0xa, 0x1,\n    0x5, 0x2, 0x9, 0x1, 0x3, 0x1, 0x4, 0x7, 0x2, 0x7, 0x1, 0x1, 0x4, 0x2, 0xa, 0x1,\n    0x2];\n_T Armenian = [0x85, 0x31, 0x26, 0x2, 0x7, 0x1, 0x27, 0x2, 0x1, 0x4, 0x1, 0xa0, 0xf5,\n    0x83, 0x5];\n_T Common = [0x0, 0x41, 0x1a, 0x6, 0x1a, 0x2f, 0x1, 0xf, 0x1, 0x5, 0x17, 0x1,\n    0x1f, 0x1, 0x81, 0xc1, 0x27, 0x5, 0x5, 0x2, 0x14, 0x74, 0x1, 0x9, 0x1,\n    0x6, 0x1, 0x1, 0x1, 0x82, 0x1, 0x1, 0x80, 0x82, 0x1, 0xe, 0x1, 0x3, 0x1,\n    0x20, 0x1, 0x1f, 0xa, 0x73, 0x1, 0x82, 0x86, 0x2, 0x84, 0xd9, 0x1, 0x81,\n    0x95, 0x4, 0x81, 0x22, 0x1, 0x85, 0xef, 0x3, 0x47, 0x2, 0x80, 0xcb, 0x2,\n    0x1, 0x1, 0x84, 0xcd, 0x1, 0xd, 0x1, 0x7, 0x4, 0x1, 0x6, 0x1, 0x2, 0x83,\n    0x9, 0xc, 0x2, 0x57, 0x1, 0xb, 0x3, 0xb, 0x1, 0xf, 0x11, 0x1b, 0x45, 0x26,\n    0x1, 0x3, 0x2, 0x6, 0x1, 0x1b, 0x1, 0x11, 0x29, 0x1, 0x6, 0x82, 0x64, 0xc,\n    0x27, 0x19, 0xb, 0x15, 0x82, 0xa0, 0x1, 0x80, 0xff, 0x81, 0x0, 0x82,\n    0x4d, 0x3, 0xa, 0x82, 0xa6, 0x3c, 0x81, 0xb4, 0xc, 0x4, 0x5, 0x1, 0x1,\n    0x1, 0x19, 0xf, 0x8, 0x4, 0x4, 0x5b, 0x2, 0x3, 0x1, 0x5a, 0x2, 0x80, 0x93,\n    0x10, 0x20, 0x24, 0x3c, 0x40, 0x1f, 0x51, 0x80, 0x88, 0x80, 0xa8, 0x99,\n    0xc0, 0x40, 0xa0, 0x59, 0x0, 0x22, 0x66, 0x3, 0x80, 0xa5, 0xa, 0x81, 0x95,\n    0x1, 0xa0, 0x53, 0x6e, 0x2, 0x80, 0xbd, 0x1, 0x12, 0xa, 0x16, 0x23, 0x1,\n    0x13, 0x1, 0x4, 0x80, 0x93, 0x1, 0x1, 0x20, 0x1a, 0x6, 0x1a, 0xb, 0xa, 0x1,\n    0x2d, 0x2, 0x40, 0x7, 0x1, 0x7, 0xa, 0x5, 0x81, 0x2, 0x3, 0x4, 0x2d, 0x3,\n    0x9, 0x50, 0xc, 0x34, 0x2d, 0xa0, 0xce, 0x3, 0x80, 0xf6, 0xa, 0x27, 0x2,\n    0x3e, 0x3, 0x11, 0x8, 0x2, 0x7, 0x1e, 0x4, 0x30, 0x81, 0x22, 0x57, 0x9,\n    0x12, 0x80, 0x8e, 0x55, 0x1, 0x47, 0x1, 0x2, 0x2, 0x1, 0x2, 0x2, 0x2, 0x4,\n    0x1, 0xc, 0x1, 0x1, 0x1, 0x7, 0x1, 0x41, 0x1, 0x4, 0x2, 0x8, 0x1, 0x7,\n    0x1, 0x1c, 0x1, 0x4, 0x1, 0x5, 0x1, 0x1, 0x3, 0x7, 0x1, 0x81, 0x54, 0x2,\n    0x81, 0x24, 0x2, 0x32, 0x98, 0x0, 0x2c, 0x4, 0x64, 0xc, 0xf, 0x2, 0xe,\n    0x2, 0xf, 0x1, 0xf, 0x20, 0xb, 0x5, 0x1f, 0x1, 0x3c, 0x4, 0x2b, 0x4b,\n    0x1a, 0x1, 0x2, 0xd, 0x2b, 0x5, 0x9, 0x7, 0x2, 0x80, 0xae, 0x21, 0xf,\n    0x6, 0x1, 0x46, 0x3, 0x14, 0xc, 0x25, 0x1, 0x5, 0x15, 0x11, 0xf, 0x3f, 0x1,\n    0x1, 0x1, 0x80, 0xb6, 0x1, 0x4, 0x3, 0x3e, 0x2, 0x4, 0xc, 0x18, 0x80, 0x93,\n    0x46, 0x4, 0xb, 0x30, 0x46, 0x3a, 0x74, 0xac, 0x8, 0x8d, 0x1, 0x1e, 0x60];\n_T Old_Italic = [0xa1, 0x3, 0x0, 0x1f, 0x1, 0x4];\n_T Old_Persian = [0xa1, 0x3, 0xa0, 0x24, 0x4, 0xe];\n_T Greek = [0x83, 0x70, 0x4, 0x1, 0x3, 0x2, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,\n    0x3, 0x1, 0x1, 0x1, 0x14, 0x1, 0x3f, 0xe, 0x10, 0x99, 0x26, 0x5, 0x32,\n    0x5, 0x4, 0x5, 0x54, 0x1, 0x81, 0x40, 0x16, 0x2, 0x6, 0x2, 0x26, 0x2, 0x6,\n    0x2, 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1f, 0x2, 0x35, 0x1, 0xf,\n    0x1, 0xe, 0x2, 0x6, 0x1, 0x13, 0x2, 0x3, 0x1, 0x9, 0x81, 0x27, 0x1, 0xa0,\n    0xe0, 0x19, 0x4b, 0xa0, 0xd0, 0x75, 0x46];\n_T Sundanese = [0x9b, 0x80, 0x40, 0x81, 0x0, 0x8];\n_T Syriac = [0x87, 0x0, 0xe, 0x1, 0x3c, 0x2, 0x3];\n_T Gurmukhi = [0x8a, 0x1, 0x3, 0x1, 0x6, 0x4, 0x2, 0x2, 0x16, 0x1, 0x7, 0x1,\n    0x2, 0x1, 0x2, 0x1, 0x2, 0x2, 0x1, 0x1, 0x5, 0x4, 0x2, 0x2, 0x3, 0x3, 0x1,\n    0x7, 0x4, 0x1, 0x1, 0x7, 0x10];\n_T Tibetan = [0x8f, 0x0, 0x48, 0x1, 0x24, 0x4, 0x27, 0x1, 0x24, 0x1, 0xf, 0x1, 0x7,\n    0x4, 0x2];\n_T Tamil = [0x8b, 0x82, 0x2, 0x1, 0x6, 0x3, 0x3, 0x1, 0x4, 0x3, 0x2, 0x1, 0x1,\n    0x1, 0x2, 0x3, 0x2, 0x3, 0x3, 0x3, 0xc, 0x4, 0x5, 0x3, 0x3, 0x1, 0x4, 0x2,\n    0x1, 0x6, 0x1, 0xe, 0x15];\n_T Telugu = [0x8c, 0x1, 0x3, 0x1, 0x8, 0x1, 0x3, 0x1, 0x17, 0x1, 0xa, 0x1,\n    0x5, 0x3, 0x8, 0x1, 0x3, 0x1, 0x4, 0x7, 0x2, 0x1, 0x2, 0x6, 0x4, 0x2, 0xa, 0x8,\n    0x8];\n_T Inscriptional_Parthian = [0xa1, 0xb, 0x40, 0x16, 0x2, 0x8];\n_T Nko = [0x87, 0xc0, 0x3b];\n_T Javanese = [0xa0, 0xa9, 0x80, 0x4e, 0x2, 0xa, 0x4, 0x2];\n_T Tai_Le = [0x99, 0x50, 0x1e, 0x2, 0x5];\n_T Old_South_Arabian = [0xa1, 0xa, 0x60, 0x20];\n_T Bamum = [0xa0, 0xa6, 0xa0, 0x58, 0xa0, 0xc1, 0x8, 0x82, 0x39];\n_T Chakma = [0xa1, 0x11, 0x0, 0x35, 0x1, 0xe];\n_T Ugaritic = [0xa1, 0x3, 0x80, 0x1e, 0x1, 0x1];\n_T Tagalog = [0x97, 0x0, 0xd, 0x1, 0x7];\n_T Tagbanwa = [0x97, 0x60, 0xd, 0x1, 0x3, 0x1, 0x2];\n_T Devanagari = [0x89, 0x0, 0x51, 0x2, 0x11, 0x2, 0x12, 0x1, 0x7, 0xa0, 0x9f, 0x60,\n    0x1c];\n_T Buginese = [0x9a, 0x0, 0x1c, 0x2, 0x2];\n_T Cuneiform = [0xa1, 0x20, 0x0, 0x83, 0x6f, 0x80, 0x91, 0x63, 0xd, 0x4];\n_T Cyrillic = [\n    0x84, 0x0, 0x80, 0x85, 0x2, 0x80, 0xa1, 0x98, 0x3, 0x1, 0x4c, 0x1, 0x90,\n    0x67, 0x20, 0xa0, 0x78, 0x40, 0x58, 0x7, 0x1\n];\n_U[] _tab = [\n_U(\"Arabic\", Arabic),\n_U(\"Armenian\", Armenian),\n_U(\"Avestan\", Avestan),\n_U(\"Balinese\", Balinese),\n_U(\"Bamum\", Bamum),\n_U(\"Batak\", Batak),\n_U(\"Bengali\", Bengali),\n_U(\"Bopomofo\", Bopomofo),\n_U(\"Brahmi\", Brahmi),\n_U(\"Braille\", Braille),\n_U(\"Buginese\", Buginese),\n_U(\"Buhid\", Buhid),\n_U(\"Canadian_Aboriginal\", Canadian_Aboriginal),\n_U(\"Carian\", Carian),\n_U(\"Chakma\", Chakma),\n_U(\"Cham\", Cham),\n_U(\"Cherokee\", Cherokee),\n_U(\"Common\", Common),\n_U(\"Coptic\", Coptic),\n_U(\"Cuneiform\", Cuneiform),\n_U(\"Cypriot\", Cypriot),\n_U(\"Cyrillic\", Cyrillic),\n_U(\"Deseret\", Deseret),\n_U(\"Devanagari\", Devanagari),\n_U(\"Egyptian_Hieroglyphs\", Egyptian_Hieroglyphs),\n_U(\"Ethiopic\", Ethiopic),\n_U(\"Georgian\", Georgian),\n_U(\"Glagolitic\", Glagolitic),\n_U(\"Gothic\", Gothic),\n_U(\"Greek\", Greek),\n_U(\"Gujarati\", Gujarati),\n_U(\"Gurmukhi\", Gurmukhi),\n_U(\"Han\", Han),\n_U(\"Hangul\", Hangul),\n_U(\"Hanunoo\", Hanunoo),\n_U(\"Hebrew\", Hebrew),\n_U(\"Hiragana\", Hiragana),\n_U(\"Imperial_Aramaic\", Imperial_Aramaic),\n_U(\"Inherited\", Inherited),\n_U(\"Inscriptional_Pahlavi\", Inscriptional_Pahlavi),\n_U(\"Inscriptional_Parthian\", Inscriptional_Parthian),\n_U(\"Javanese\", Javanese),\n_U(\"Kaithi\", Kaithi),\n_U(\"Kannada\", Kannada),\n_U(\"Katakana\", Katakana),\n_U(\"Kayah_Li\", Kayah_Li),\n_U(\"Kharoshthi\", Kharoshthi),\n_U(\"Khmer\", Khmer),\n_U(\"Lao\", Lao),\n_U(\"Latin\", Latin),\n_U(\"Lepcha\", Lepcha),\n_U(\"Limbu\", Limbu),\n_U(\"Linear_B\", Linear_B),\n_U(\"Lisu\", Lisu),\n_U(\"Lycian\", Lycian),\n_U(\"Lydian\", Lydian),\n_U(\"Malayalam\", Malayalam),\n_U(\"Mandaic\", Mandaic),\n_U(\"Meetei_Mayek\", Meetei_Mayek),\n_U(\"Meroitic_Cursive\", Meroitic_Cursive),\n_U(\"Meroitic_Hieroglyphs\", Meroitic_Hieroglyphs),\n_U(\"Miao\", Miao),\n_U(\"Mongolian\", Mongolian),\n_U(\"Myanmar\", Myanmar),\n_U(\"New_Tai_Lue\", New_Tai_Lue),\n_U(\"Nko\", Nko),\n_U(\"Ogham\", Ogham),\n_U(\"Ol_Chiki\", Ol_Chiki),\n_U(\"Old_Italic\", Old_Italic),\n_U(\"Old_Persian\", Old_Persian),\n_U(\"Old_South_Arabian\", Old_South_Arabian),\n_U(\"Old_Turkic\", Old_Turkic),\n_U(\"Oriya\", Oriya),\n_U(\"Osmanya\", Osmanya),\n_U(\"Phags_Pa\", Phags_Pa),\n_U(\"Phoenician\", Phoenician),\n_U(\"Rejang\", Rejang),\n_U(\"Runic\", Runic),\n_U(\"Samaritan\", Samaritan),\n_U(\"Saurashtra\", Saurashtra),\n_U(\"Sharada\", Sharada),\n_U(\"Shavian\", Shavian),\n_U(\"Sinhala\", Sinhala),\n_U(\"Sora_Sompeng\", Sora_Sompeng),\n_U(\"Sundanese\", Sundanese),\n_U(\"Syloti_Nagri\", Syloti_Nagri),\n_U(\"Syriac\", Syriac),\n_U(\"Tagalog\", Tagalog),\n_U(\"Tagbanwa\", Tagbanwa),\n_U(\"Tai_Le\", Tai_Le),\n_U(\"Tai_Tham\", Tai_Tham),\n_U(\"Tai_Viet\", Tai_Viet),\n_U(\"Takri\", Takri),\n_U(\"Tamil\", Tamil),\n_U(\"Telugu\", Telugu),\n_U(\"Thaana\", Thaana),\n_U(\"Thai\", Thai),\n_U(\"Tibetan\", Tibetan),\n_U(\"Tifinagh\", Tifinagh),\n_U(\"Ugaritic\", Ugaritic),\n_U(\"Vai\", Vai),\n_U(\"Yi\", Yi),\n];\n}\n\nstruct hangul\n{\nprivate alias _U = immutable(UnicodeProperty);\n@property static _U[] tab() pure nothrow @nogc { return _tab; }\nstatic immutable:\nprivate alias _T = ubyte[];\n_T LVT = [0xa0, 0xac, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b];\n_T T = [0x91, 0xa8, 0x58, 0xa0, 0xc5, 0xcb, 0x31];\n_T V = [0x91, 0x60, 0x48, 0xa0, 0xc6, 0x8, 0x17];\n_T LV = [0xa0, 0xac, 0x0, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b,\n    0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1,\n    0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1, 0x1b, 0x1];\n_T L = [0x91, 0x0, 0x60, 0xa0, 0x98, 0x0, 0x1d];\n_U[] _tab = [\n_U(\"L\", L),\n_U(\"Leading_Jamo\", L),\n_U(\"LV\", LV),\n_U(\"LV_Syllable\", LV),\n_U(\"LVT\", LVT),\n_U(\"LVT_Syllable\", LVT),\n_U(\"T\", T),\n_U(\"Trailing_Jamo\", T),\n_U(\"V\", V),\n_U(\"Vowel_Jamo\", V),\n];\n}\nbool isFormatGen(dchar ch) @safe pure nothrow\n{\n    if (ch < 8288)\n    {\n        if (ch < 1807)\n        {\n            if (ch < 1564)\n            {\n                if (ch == 173) return true;\n                if (ch < 1536) return false;\n                if (ch < 1541) return true;\n                return false;\n            }\n            else if (ch < 1565) return true;\n            else\n            {\n                if (ch == 1757) return true;\n                return false;\n            }\n        }\n        else if (ch < 1808) return true;\n        else\n        {\n            if (ch < 8203)\n            {\n                if (ch == 6158) return true;\n                return false;\n            }\n            else if (ch < 8208) return true;\n            else\n            {\n                if (ch < 8234) return false;\n                if (ch < 8239) return true;\n                return false;\n            }\n        }\n    }\n    else if (ch < 8293) return true;\n    else\n    {\n        if (ch < 69_821)\n        {\n            if (ch < 65_279)\n            {\n                if (ch < 8294) return false;\n                if (ch < 8304) return true;\n                return false;\n            }\n            else if (ch < 65_280) return true;\n            else\n            {\n                if (ch < 65_529) return false;\n                if (ch < 65_532) return true;\n                return false;\n            }\n        }\n        else if (ch < 69_822) return true;\n        else\n        {\n            if (ch < 917_505)\n            {\n                if (ch < 119_155) return false;\n                if (ch < 119_163) return true;\n                return false;\n            }\n            else if (ch < 917_506) return true;\n            else\n            {\n                if (ch < 917_536) return false;\n                if (ch < 917_632) return true;\n                return false;\n            }\n        }\n    }\n}\n\nbool isControlGen(dchar ch) @safe pure nothrow\n{\n    if (ch < 32) return true;\n    if (ch < 127) return false;\n    if (ch < 160) return true;\n    return false;\n}\n\nbool isSpaceGen(dchar ch) @safe pure nothrow\n{\n    if (ch < 160)\n    {\n        if (ch == 32) return true;\n        return false;\n    }\n    else if (ch < 161) return true;\n    else\n    {\n        if (ch < 8239)\n        {\n            if (ch == 5760) return true;\n            if (ch < 8192) return false;\n            if (ch < 8203) return true;\n            return false;\n        }\n        else if (ch < 8240) return true;\n        else\n        {\n            if (ch == 8287) return true;\n            if (ch == 12_288) return true;\n            return false;\n        }\n    }\n}\n\nbool isWhiteGen(dchar ch) @safe pure nothrow @nogc\n{\n    if (ch < 133)\n    {\n        if (ch < 9) return false;\n        if (ch < 14) return true;\n        if (ch == 32) return true;\n        return false;\n    }\n    else if (ch < 134) return true;\n    else\n    {\n        if (ch < 8232)\n        {\n            if (ch < 5760)\n            {\n                if (ch == 160) return true;\n                return false;\n            }\n            else if (ch < 5761) return true;\n            else\n            {\n                if (ch < 8192) return false;\n                if (ch < 8203) return true;\n                return false;\n            }\n        }\n        else if (ch < 8234) return true;\n        else\n        {\n            if (ch < 8287)\n            {\n                if (ch == 8239) return true;\n                return false;\n            }\n            else if (ch < 8288) return true;\n            else\n            {\n                if (ch == 12_288) return true;\n                return false;\n            }\n        }\n    }\n}\n\nbool isHangL(dchar ch) @safe pure nothrow\n{\n    if (ch < 4352) return false;\n    if (ch < 4448) return true;\n    if (ch < 43_360) return false;\n    if (ch < 43_389) return true;\n    return false;\n}\n\nbool isHangV(dchar ch) @safe pure nothrow\n{\n    if (ch < 4448) return false;\n    if (ch < 4520) return true;\n    if (ch < 55_216) return false;\n    if (ch < 55_239) return true;\n    return false;\n}\n\nbool isHangT(dchar ch) @safe pure nothrow\n{\n    if (ch < 4520) return false;\n    if (ch < 4608) return true;\n    if (ch < 55_243) return false;\n    if (ch < 55_292) return true;\n    return false;\n}\n\nstatic if (size_t.sizeof == 8)\n{\n//1536 bytes\nenum lowerCaseTrieEntries = TrieEntry!(bool, 8, 4, 9)([0x0, 0x20, 0x40],\n        [0x100, 0x80, 0x2000], [0x402030202020100, 0x206020202020205,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x3000200010000, 0x3000300030003, 0x3000300030003, 0x5000400030003,\n        0x3000700030006, 0x3000800030003, 0x3000300030003, 0x3000300030003,\n        0x3000300030003, 0x3000300030003, 0x3000300030003, 0x3000300030003,\n        0x9000300030003, 0x3000300030003, 0x3000300030003, 0x3000300030003,\n        0x3000300030003, 0x3000300030003, 0x3000300030003, 0xb0003000a0003,\n        0x3000c00030003, 0x3000300030003, 0x3000300030003, 0x3000300030003,\n        0x3000300030003, 0x3000300030003, 0xe000d00030003, 0x3000300030003,\n        0x3000300030003, 0x3000300030003, 0x3000300030003, 0x3000300030003,\n        0x0, 0x7fffffe00000000, 0x420040000000000, 0xff7fffff80000000,\n        0x55aaaaaaaaaaaaaa, 0xd4aaaaaaaaaaab55, 0xe6512d2a4e243129,\n        0xaa29aaaab5555240, 0x93faaaaaaaaaaaaa, 0xffffffffffffaa85,\n        0x1ffffffffefffff, 0x1f00000003, 0x0, 0x3c8a000000000020,\n        0xfffff00000010000, 0x192faaaaaae37fff, 0xffff000000000000,\n        0xaaaaaaaaffffffff, 0xaaaaaaaaaaaaa802, 0xaaaaaaaaaaaad554,\n        0xaaaaaaaaaa, 0xfffffffe00000000, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0xaaaaaaaaaaaaaaaa,\n        0xaaaaaaaaaaaaaaaa, 0xaaaaaaaabfeaaaaa, 0xaaaaaaaaaaaaaaaa,\n        0xff00ff003f00ff, 0x3fff00ff00ff003f, 0x40df00ff00ff00ff,\n        0xdc00ff00cf00dc, 0x0, 0x8002000000000000, 0x1fff0000, 0x0,\n        0x321080000008c400, 0xffff0000000043c0, 0x10, 0x0, 0x0, 0x0, 0x0,\n        0x3ffffff0000, 0x0, 0x0, 0x0, 0x0, 0xffff000000000000,\n        0x3fda15627fffffff, 0xaaaaaaaaaaaaaaaa, 0x8501aaaaaaaaa,\n        0x20bfffffffff, 0x0, 0x0, 0x0, 0x0, 0x2aaaaaaaaaaa, 0xaaaaaa, 0x0,\n        0xaaabaaa800000000, 0x95ffaaaaaaaaaaaa, 0x2aa000a50aa,\n        0x700000000000000, 0x0, 0x0, 0x0, 0x0, 0xf8007f, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x7fffffe, 0x0, 0x0, 0xffffff0000000000, 0xffff,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffc000000, 0xffffdfc000,\n        0xebc000000ffffffc, 0xfffffc000000ffef, 0xffffffc000000f,\n        0xffffffc0000, 0xfc000000ffffffc0, 0xffffc000000fffff,\n        0xffffffc000000ff, 0xffffffc00000, 0x3ffffffc00, 0xf0000003f7fffffc,\n        0xffc000000fdfffff, 0xffff0000003f7fff, 0xfffffc000000fdff, 0xbf7, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n//1472 bytes\nenum upperCaseTrieEntries = TrieEntry!(bool, 8, 4, 9)([0x0, 0x20, 0x40],\n        [0x100, 0x80, 0x1e00], [0x402030202020100, 0x206020202020205,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x3000200010000, 0x3000300030003, 0x3000300030004, 0x5000300030003,\n        0x3000700030006, 0x3000800030003, 0x3000300030003, 0x3000300030003,\n        0x3000300030003, 0x3000300030003, 0x3000300030003, 0x3000300030003,\n        0x9000300030003, 0x3000300030003, 0x3000300030003, 0x3000300030003,\n        0x3000300030003, 0x3000300030003, 0x3000300030003, 0xa000300030003,\n        0x3000b00030003, 0x3000300030003, 0x3000300030003, 0x3000300030003,\n        0x3000300030003, 0x3000300030003, 0xd000c00030003, 0x3000300030003,\n        0x3000300030003, 0x3000300030003, 0x3000300030003, 0x3000300030003,\n        0x0, 0x7fffffe, 0x0, 0x7f7fffff, 0xaa55555555555555,\n        0x2b555555555554aa, 0x11aed2d5b1dbced6, 0x55d255554aaaa490,\n        0x6c05555555555555, 0x557a, 0x0, 0x0, 0x0, 0x45000000000000,\n        0xffbfffed740, 0xe6905555551c8000, 0xffffffffffff, 0x5555555500000000,\n        0x5555555555555401, 0x5555555555552aab, 0xfffe005555555555, 0x7fffff,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xffffffff00000000, 0x20bf, 0x0, 0x0, 0x0, 0x0, 0x5555555555555555,\n        0x5555555555555555, 0x5555555540155555, 0x5555555555555555,\n        0xff00ff003f00ff00, 0xff00aa003f00, 0xf00000000000000,\n        0xf001f000f000f00, 0x0, 0x0, 0x0, 0x0, 0xc00f3d503e273884,\n        0xffff00000020, 0x8, 0x0, 0x0, 0x0, 0xffc0000000000000, 0xffff, 0x0,\n        0x0, 0x0, 0x0, 0x7fffffffffff, 0xc025ea9d00000000, 0x5555555555555555,\n        0x4280555555555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x155555555555, 0x555555,\n        0x0, 0x5554555400000000, 0x6a00555555555555, 0x55500052855, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x7fffffe00000000, 0x0, 0x0, 0x0, 0xffffffffff, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfff0000003ffffff, 0xffffff0000003fff,\n        0x3fde64d0000003, 0x3ffffff0000, 0x7b0000001fdfe7b0,\n        0xfffff0000001fc5f, 0x3ffffff0000003f, 0x3ffffff00000,\n        0xf0000003ffffff00, 0xffff0000003fffff, 0xffffff00000003ff,\n        0x7fffffc00000001, 0x1ffffff0000000, 0x7fffffc00000, 0x1ffffff0000,\n        0x400, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n//8704 bytes\nenum simpleCaseTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x20, 0x100],\n        [0x100, 0x380, 0xd00], [0x402030202020100, 0x202020202020205,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x3000200010000, 0x7000600050004, 0xa00090008, 0xd000c000b0000,\n        0x110010000f000e, 0x1400130012, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x16001500000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x170000, 0x1b001a00190018, 0x1f001e001d001c, 0x0,\n        0x2200210020, 0x0, 0x0, 0x24002300000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x28002700260025, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b002a0000, 0x2e002d002c, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30002f, 0x0,\n        0x0, 0x0, 0x0, 0x320031, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x2400220020ffff, 0x2c002a00280026, 0x72f00320030002e,\n        0x3d003b00390037, 0x1b000430041003f, 0x4e004c004a0048,\n        0xffff005400520050, 0xffffffffffffffff, 0x2500230021ffff,\n        0x2d002b00290027, 0x73000330031002f, 0x3e003c003a0038,\n        0x1b1004400420040, 0x4f004d004b0049, 0xffff005500530051,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff043fffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xcc049800c800c6,\n        0xd500d3014904aa, 0xdd00db00d900d7, 0xe500e300e100df, 0xed00eb00e900e7,\n        0xffff00f300f100ef, 0xfb00f900f700f5, 0x6be010100ff00fd,\n        0xcd049900c900c7, 0xd600d4014a04ab, 0xde00dc00da00d8, 0xe600e400e200e0,\n        0xee00ec00ea00e8, 0xffff00f400f200f0, 0xfc00fa00f800f6,\n        0x1a80102010000fe, 0x118011701160115, 0x11e011d011c011b,\n        0x12401230120011f, 0x128012701260125, 0x12e012d012c012b,\n        0x13401330130012f, 0x138013701360135, 0x13c013b013a0139,\n        0x140013f013e013d, 0x144014301420141, 0x148014701460145,\n        0x14f014e014d014c, 0x1510150ffffffff, 0x155015401530152,\n        0x15801570156ffff, 0x15e015d015c0159, 0x16201610160015f,\n        0x166016501640163, 0x1690168ffff0167, 0x16d016c016b016a,\n        0x1710170016f016e, 0x175017401730172, 0x179017801770176,\n        0x17d017c017b017a, 0x1830182017f017e, 0x18b018a01870186,\n        0x1930192018f018e, 0x19b019a01970196, 0x1a301a2019f019e,\n        0x1a701a601a501a4, 0x1ac01ab01aa01a9, 0x1b201af01ae01ad,\n        0x1b601b501b3028b, 0x1bd01bb01ba01b9, 0x1c301c101bf01be,\n        0x1c701c5ffff01c4, 0x1cd01cc01cb01c9, 0x1d301d1023b01cf,\n        0xffff028301d601d5, 0x1db026901d901d7, 0x1e001df01de01dd,\n        0x1e501e301e201e1, 0xffffffff01e701e6, 0x1ed01eb01ea01e9,\n        0x1f301f101ef01ee, 0x1f701f601f501f4, 0xffffffff01fa01f9,\n        0x23dffff01fc01fb, 0xffffffffffffffff, 0x206020202010200,\n        0x20d020c02080207, 0x2110210020f020e, 0x215021402130212,\n        0x219021802170216, 0x21d021c021b021a, 0x220021f01c6021e,\n        0x226022502240223, 0x22a022902280227, 0x22e022d022c022b,\n        0x23202310230022f, 0x23802370236ffff, 0x23e023c023a0239,\n        0x24402430240023f, 0x248024702460245, 0x24c024b024a0249,\n        0x250024f024e024d, 0x254025302520251, 0x258025702560255,\n        0x25c025b025a0259, 0x260025f025e025d, 0x264026302620261,\n        0x268026702660265, 0x26c026bffff026a, 0x270026f026e026d,\n        0x274027302720271, 0x278027702760275, 0x27c027b027a0279,\n        0xffffffffffffffff, 0x281027fffffffff, 0x2d7028502840282,\n        0x28c028802870482, 0x2920291028f028d, 0x296029502940293,\n        0x29c029b02980297, 0x1b402b70466046a, 0x1c201c0ffff01bc,\n        0x1caffff01c8ffff, 0xffffffffffffffff, 0x1d0ffffffff01ce,\n        0xffff05fa0748ffff, 0x528ffff01d201d4, 0x1d8ffffffffffff,\n        0xffff01da02b3ffff, 0xffffffff01dcffff, 0xffffffffffffffff,\n        0xffffffff02a3ffff, 0x1e8ffffffff01e4, 0xffffffffffffffff,\n        0x1f201f0028e01ec, 0xffffffffffff0290, 0xffff01f8ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffff083affff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x320031f031e031d,\n        0x3240323ffffffff, 0x3d5ffffffffffff, 0xffffffff03d903d7,\n        0xffffffffffffffff, 0xffff0329ffffffff, 0xffff0331032f032d,\n        0x3370335ffff0333, 0x33e03950339ffff, 0x347034503cc0340,\n        0x35403c2083b03c8, 0x35d035b03590440, 0x388ffff03c5039f,\n        0x36f039c036a0368, 0x378037607100371, 0x3320330032e032a,\n        0x33f0396033affff, 0x348034603cd0341, 0x35503c3083c03c9,\n        0x35e035c035a0441, 0x38a038903c603a0, 0x370039d036b0369,\n        0x379037707110372, 0x393033803360334, 0xffffffff03ca0397,\n        0x39403a1039effff, 0x3a703a603a303a2, 0x3ab03aa03a903a8,\n        0x3af03ae03ad03ac, 0x3b503b403b103b0, 0x3bd03bc03b903b8,\n        0x3c103c003bf03be, 0xffff03d103c703c4, 0x3cfffff03ce03cb,\n        0x3d403d303d203d0, 0x3da03d803d6ffff, 0x3e103df03dd03db,\n        0x3e903e703e503e3, 0x3f103ef03ed03eb, 0x3f903f703f503f3,\n        0x40103ff03fd03fb, 0x409040704050403, 0x411040f040d040b,\n        0x419041704150413, 0x421041f041d041b, 0x429042704250423,\n        0x431042f042d042b, 0x439043704350433, 0x402040003fe03fc,\n        0x40a040804060404, 0x4120410040e040c, 0x41a041804160414,\n        0x4220420041e041c, 0x42a042804260424, 0x4320430042e042c,\n        0x43a043804360434, 0x3e203e003de03dc, 0x3ea03e803e603e4,\n        0x3f203f003ee03ec, 0x3fa03f803f603f4, 0x453045204510450,\n        0x459045804570456, 0x4610460045d045c, 0x469046804650464,\n        0x4710470046d046c, 0x477047604730472, 0x47b047a04790478,\n        0x4810480047d047c, 0xffffffff04850484, 0xffffffffffffffff,\n        0x4950494ffffffff, 0x49b049a04970496, 0x49f049e049d049c,\n        0x4a704a604a304a2, 0x4ad04ac04a904a8, 0x4b304b204b104b0,\n        0x4b904b804b704b6, 0x4bf04be04bb04ba, 0x4c504c404c104c0,\n        0x4cd04cc04c904c8, 0x4d304d204cf04ce, 0x4d704d604d504d4,\n        0x4df04de04db04da, 0x4e704e604e304e2, 0x4f004ed04ec04ea,\n        0x4f804f504f404f1, 0x50004fd04fc04f9, 0x4eb050505040501,\n        0x50d050c050b050a, 0x5130512050f050e, 0x519051805170516,\n        0x51f051e051d051c, 0x525052405210520, 0x52b052a05270526,\n        0x52f052e052d052c, 0x537053605330532, 0x53d053c05390538,\n        0x5410540053f053e, 0x547054605430542, 0x54b054a05490548,\n        0x54f054e054d054c, 0x555055405510550, 0x559055805570556,\n        0x55d055c055b055a, 0x5630562055f055e, 0x567056605650564,\n        0x56b056a05690568, 0x5730572056f056e, 0x577057605750574,\n        0x57b057a05790578, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x58405820580ffff, 0x58c058a05880586, 0x59405920590058e,\n        0x59c059a05980596, 0x5a405a205a0059e, 0x5ac05aa05a805a6,\n        0x5b405b205b005ae, 0x5bc05ba05b805b6, 0x5c405c205c005be,\n        0xffff05ca05c805c6, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x58505830581ffff, 0x58d058b05890587, 0x59505930591058f,\n        0x59d059b05990597, 0x5a505a305a1059f, 0x5ad05ab05a905a7,\n        0x5b505b305b105af, 0x5bd05bb05b905b7, 0x5c505c305c105bf,\n        0xffff05cb05c905c7, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x8c008a00880086,\n        0x9400920090008e, 0x9c009a00980096, 0xa400a200a0009e, 0xac00aa00a800a6,\n        0xb400b200b000ae, 0xbc00ba00b800b6, 0xc400c200c000be,\n        0x4a000ca048e0486, 0x4c6ffff04b400ce, 0xffffffffffffffff,\n        0xffffffff0508ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffff07e8ffff, 0xffffffff0454ffff, 0x5ff05fe05fd05fc,\n        0x605060406010600, 0x60b060a06090608, 0x6110610060f060e,\n        0x617061606130612, 0x61d061c06190618, 0x6210620061f061e,\n        0x627062606230622, 0x62b062a06290628, 0x62f062e062d062c,\n        0x635063406310630, 0x639063806370636, 0x63d063c063b063a,\n        0x6430642063f063e, 0x647064606450644, 0x64b064a06490648,\n        0x6510650064d064c, 0x655065406530652, 0x65d065c06590658,\n        0x6630662065f065e, 0x667066606650664, 0x66b066a06690668,\n        0x6710670066d066c, 0x675067406730672, 0x67a067906bc06bb,\n        0x680067f067c067b, 0x684068306820681, 0x688068706860685,\n        0x68e068d068a0689, 0x69206910690068f, 0x698069706960695,\n        0x69e069d069a0699, 0x6a206a106a0069f, 0x6a606a506a406a3,\n        0x6ac06ab06a806a7, 0x6b006af06ae06ad, 0x6b406b306b206b1,\n        0xffffffff06b606b5, 0x6bdffffffffffff, 0xffff06bfffffffff,\n        0x6c306c206c106c0, 0x6c906c806c506c4, 0x6cd06cc06cb06ca,\n        0x6d106d006cf06ce, 0x6d706d606d506d4, 0x6dd06dc06db06da,\n        0x6e106e006df06de, 0x6e506e406e306e2, 0x6eb06ea06e906e8,\n        0x6f106f006ef06ee, 0x6f506f406f306f2, 0x6f906f806f706f6,\n        0x6fd06fc06fb06fa, 0x701070006ff06fe, 0x705070407030702,\n        0x709070807070706, 0x70d070c070b070a, 0x7140713070f070e,\n        0x718071707160715, 0x71e071d071c071b, 0x72207210720071f,\n        0x726072507240723, 0x72a072907280727, 0x7330732072e072d,\n        0x73c073a07380736, 0x74407420740073e, 0x73d073b07390737,\n        0x74507430741073f, 0x750074e074c074a, 0xffffffff07540752,\n        0x751074f074d074b, 0xffffffff07550753, 0x76a076807660764,\n        0x7720770076e076c, 0x76b076907670765, 0x7730771076f076d,\n        0x78a078807860784, 0x7920790078e078c, 0x78b078907870785,\n        0x7930791078f078d, 0x7a207a0079e079c, 0xffffffff07a607a4,\n        0x7a307a1079f079d, 0xffffffff07a707a5, 0x7baffff07b6ffff,\n        0x7c2ffff07beffff, 0x7bbffff07b7ffff, 0x7c3ffff07bfffff,\n        0x7d607d407d207d0, 0x7de07dc07da07d8, 0x7d707d507d307d1,\n        0x7df07dd07db07d9, 0x840083e08360834, 0x84e084c08440842,\n        0x858085608620860, 0xffffffff08660864, 0x7fa07f807f607f4,\n        0x802080007fe07fc, 0x7fb07f907f707f5, 0x803080107ff07fd,\n        0x80e080c080a0808, 0x816081408120810, 0x80f080d080b0809,\n        0x817081508130811, 0x826082408220820, 0x82e082c082a0828,\n        0x827082508230821, 0x82f082d082b0829, 0x838ffff08320830,\n        0xffffffffffffffff, 0x837083508330831, 0xffff083dffff0839,\n        0x846ffffffffffff, 0xffffffffffffffff, 0x84508430841083f,\n        0xffffffffffff0847, 0xffffffff084a0848, 0xffffffffffffffff,\n        0x84f084d084b0849, 0xffffffffffffffff, 0xffffffff08540852,\n        0xffffffff085affff, 0x859085708550853, 0xffffffffffff085b,\n        0x868ffffffffffff, 0xffffffffffffffff, 0x867086508630861,\n        0xffffffffffff0869, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff0712ffffffff, 0x14b0731ffffffff,\n        0xffffffffffffffff, 0xffff0530ffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff0531ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x18402af0180029f, 0x18c005e018802c1,\n        0x194006c01900064, 0x19c007e01980076, 0x18502b0018102a0,\n        0x18d005f018902c2, 0x195006d01910065, 0x19d007f01990077,\n        0x1b7ffffffffffff, 0xffffffffffff01b8, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x4d80444ffffffff,\n        0x4e0044c04dc0446, 0x4e8047404e4045e, 0x204ee02d3086a,\n        0x6e04f606c604f2, 0x10d04fe037a04fa, 0x51a0506061a0502,\n        0x4dd044704d90445, 0x4e5045f04e1044d, 0x2d4086b04e90475,\n        0x6c704f3000304ef, 0x37b04fb006f04f7, 0x61b0503010e04ff,\n        0xffffffff051b0507, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xa000800040000, 0x160010000e000c, 0x2bb001c001a0018, 0x5602e702d102c7,\n        0x66006200600058, 0x7800740070006a, 0x29900820080007c,\n        0x6020084000607e0, 0x5d005ce02a7057c, 0x1070105010305de,\n        0x1190113010f0109, 0xffff013101290121, 0xb000900050001,\n        0x170011000f000d, 0x2bc001d001b0019, 0x5702e802d202c8,\n        0x67006300610059, 0x7900750071006b, 0x29a00830081007d,\n        0x6030085000707e1, 0x5d105cf02a8057d, 0x1080106010405df,\n        0x11a01140110010a, 0xffff0132012a0122, 0x455052904c304c2,\n        0x45a0286028002a4, 0x46202aa02a9045b, 0x46b02b404670463,\n        0x2ba02b9ffff02b8, 0xffff02c002bfffff, 0xffffffffffffffff,\n        0x48302d8ffffffff, 0x489048802e202e1, 0x48d048c048b048a,\n        0x2fe02fd04910490, 0x30e030d03040303, 0x31a031903160315,\n        0x328032703260325, 0x6ed06ec02fc02fb, 0x383038203810380,\n        0x392039103870386, 0x3b303b203a503a4, 0x5cd05cc056d056c,\n        0x5ed05ec05db05da, 0x6570656060d060c, 0x6e706e6043e043d,\n        0x7830782072c072b, 0x694069307e307e2, 0x150014065b065a,\n        0x4bd04bc005d005c, 0x5d505d404d104d0, 0x511051001a101a0,\n        0x535053405230522, 0x553055205450544, 0x571057005610560,\n        0x15b015a057f057e, 0x3bb03ba037d037c, 0xffffffffffffffff,\n        0x5d2ffffffffffff, 0xffff05d905d805d3, 0x5e305e2ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x8d008b00890087, 0x9500930091008f, 0x9d009b00990097, 0xa500a300a1009f,\n        0xad00ab00a900a7, 0xb500b300b100af, 0xbd00bb00b900b7, 0xc500c300c100bf,\n        0x4a100cb048f0487, 0x4c7ffff04b500cf, 0xffffffffffffffff,\n        0xffffffff0509ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x5d705d602c402c3,\n        0x5e105e005dd05dc, 0x5e905e805e705e6, 0x5ef05ee05eb05ea,\n        0x5f505f405f105f0, 0x308030705f905f8, 0x625062406150614,\n        0x641064006330632, 0x6610660064f064e, 0x67e067d066f066e,\n        0x69c069b068c068b, 0xffffffff06aa06a9, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x69006807350734, 0x75f075e027e027d, 0x390038f07770776,\n        0x7b107b0001f001e, 0x2a202a107c707c6, 0x6b806b707e507e4,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x7590758ffffffff, 0x7610760075d075c, 0x2e002df02d602d5,\n        0x2ee02ed02e602e5, 0x7790778ffffffff, 0x7810780077d077c,\n        0x3140313030c030b, 0x322032103180317, 0x797079607950794,\n        0x79b079a07990798, 0x3850384037f037e, 0x7a907a8038e038d,\n        0x7ad07ac07ab07aa, 0x7b307b207af07ae, 0x7b907b807b507b4,\n        0x7c107c007bd07bc, 0x7c907c807c507c4, 0x7cf07ce07cd07cc,\n        0x47f047e046f046e, 0x4a504a404930492, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x7e605150514ffff, 0x7eb07ea07e907e7,\n        0x7ef07ee07ed07ec, 0x7f307f207f107f0, 0x5f2ffffffffffff,\n        0xffffffff074905f3, 0x807080608050804, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x81b081a08190818,\n        0x81f081e081d081c, 0xffff05fb05f705f6, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x75a02c50756ffff, 0x76202cf02cd02cb, 0x2e3071902db06d2,\n        0x2f107ca02e90448, 0x77a02f502f30774, 0x3050221077e02f9,\n        0xffff043b030f007a, 0xffffffffffffffff, 0x75b02c60757ffff,\n        0x76302d002ce02cc, 0x2e4071a02dc06d3, 0x2f207cb02ea0449,\n        0x77b02f602f40775, 0x3060222077f02fa, 0xffff043c0310007b,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x72005a085c0012, 0x11106b9032b0311, 0x2dd029d02ab05e4,\n        0x10b060602ef085e, 0x4ca028902d902a5, 0x2c902bd02b502ad,\n        0x30902f702eb0746, 0x38b02b10241031b, 0x442053a044a03b6,\n        0x85004ae06d8044e, 0x73005b085d0013, 0x11206ba032c0312,\n        0x2de029e02ac05e5, 0x10c060702f0085f, 0x4cb028a02da02a6,\n        0x2ca02be02b602ae, 0x30a02f802ec0747, 0x38c02b20242031c,\n        0x443053b044b03b7, 0x85104af06d9044f, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff]);\n//8832 bytes\nenum fullCaseTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x20, 0x100],\n        [0x100, 0x380, 0xd40], [0x402030202020100, 0x202020202020205,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x3000200010000, 0x7000600050004, 0xa00090008, 0xd000c000b0000,\n        0x110010000f000e, 0x1400130012, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x16001500000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x170000, 0x1b001a00190018, 0x1f001e001d001c, 0x0,\n        0x2200210020, 0x0, 0x0, 0x24002300000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x28002700260025, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b002a0000, 0x2e002d002c, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, 0x310030, 0x0,\n        0x0, 0x0, 0x0, 0x330032, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x2400220020ffff, 0x2c002a00280026, 0x78100320030002e,\n        0x3d003b00390037, 0x1b900430041003f, 0x4e004c004a0048,\n        0xffff005400520050, 0xffffffffffffffff, 0x2500230021ffff,\n        0x2d002b00290027, 0x78200330031002f, 0x3e003c003a0038,\n        0x1ba004400420040, 0x4f004d004b0049, 0xffff005500530051,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff0470ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xcc04c900c800c6,\n        0xd500d3014e04db, 0xdd00db00d900d7, 0xe500e300e100df, 0xed00eb00e900e7,\n        0xffff00f300f100ef, 0xfb00f900f700f5, 0x70f010100ff00fd,\n        0xcd04ca00c900c7, 0xd600d4014f04dc, 0xde00dc00da00d8, 0xe600e400e200e0,\n        0xee00ec00ea00e8, 0xffff00f400f200f0, 0xfc00fa00f800f6,\n        0x1b10102010000fe, 0x11b011a01190118, 0x1210120011f011e,\n        0x127012601230122, 0x12b012a01290128, 0x1310130012f012e,\n        0x137013601330132, 0x13b013a01390138, 0x13f013e013d013c,\n        0x143014201410140, 0x149014801470146, 0x14d014c014b014a,\n        0x154015301520151, 0x1580157ffff0155, 0x15c015b015a0159,\n        0x15f015e015dffff, 0x165016401630160, 0x169016801670166,\n        0x16d016c016b016a, 0x1720171016f016e, 0x176017501740173,\n        0x17a017901780177, 0x17e017d017c017b, 0x18201810180017f,\n        0x186018501840183, 0x18c018b01880187, 0x19401930190018f,\n        0x19c019b01980197, 0x1a401a301a0019f, 0x1ac01ab01a801a7,\n        0x1b001af01ae01ad, 0x1b501b401b301b2, 0x1bb01b801b701b6,\n        0x1bf01be01bc029c, 0x1c601c401c301c2, 0x1cc01ca01c801c7,\n        0x1d001ceffff01cd, 0x1d601d501d401d2, 0x1dc01da024801d8,\n        0xffff029401df01de, 0x1e6027801e201e0, 0x1eb01ea01e901e8,\n        0x1f001ee01ed01ec, 0xffffffff01f201f1, 0x1f801f601f501f4,\n        0x1fe01fc01fa01f9, 0x2020201020001ff, 0xffffffff02050204,\n        0x24affff02070206, 0xffffffffffffffff, 0x211020d020c020b,\n        0x218021702130212, 0x21c021b021a0219, 0x220021f021e021d,\n        0x224022302220221, 0x228022702260225, 0x22b022a01cf0229,\n        0x2310230022f022e, 0x235023402330232, 0x239023802370236,\n        0x23d023c023b023a, 0x24502440243023e, 0x24b024902470246,\n        0x2510250024d024c, 0x255025402530252, 0x259025802570256,\n        0x25d025c025b025a, 0x263026202610260, 0x267026602650264,\n        0x26b026a02690268, 0x26f026e026d026c, 0x273027202710270,\n        0x277027602750274, 0x27b027affff0279, 0x27f027e027d027c,\n        0x285028402810280, 0x289028802870286, 0x28d028c028b028a,\n        0xffffffffffffffff, 0x2920290ffffffff, 0x2ec029602950293,\n        0x29d0299029804b3, 0x2a302a202a0029e, 0x2a702a602a502a4,\n        0x2ad02ac02a902a8, 0x1bd02ca0497049b, 0x1cb01c9ffff01c5,\n        0x1d3ffff01d1ffff, 0xffffffffffffffff, 0x1d9ffffffff01d7,\n        0xffff0643079affff, 0x559ffff01db01dd, 0x1e1ffffffffffff,\n        0xffff01e302c6ffff, 0xffffffff01e7ffff, 0xffffffffffffffff,\n        0xffffffff02b4ffff, 0x1f3ffffffff01ef, 0xffffffffffffffff,\n        0x1fd01fb029f01f7, 0xffffffffffff02a1, 0xffff0203ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffff08e4ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x347034603450344,\n        0x34b034affffffff, 0x406ffffffffffff, 0xffffffff040a0408,\n        0xffffffffffffffff, 0xffff0350ffffffff, 0xffff035803560354,\n        0x35e035cffff035a, 0x36803c203630902, 0x371036f03fd036a,\n        0x37e03f308e503f9, 0x387038503830471, 0x3b5ffff03f603cc,\n        0x39903c903940392, 0x3a203a00762039b, 0x359035703550351,\n        0x36903c303640915, 0x372037003fe036b, 0x37f03f408e603fa,\n        0x388038603840472, 0x3b703b603f703cd, 0x39a03ca03950393,\n        0x3a303a10763039c, 0x3c0035f035d035b, 0xffffffff03fb03c4,\n        0x3c103ce03cbffff, 0x3d403d303d003cf, 0x3d803d703d603d5,\n        0x3de03dd03da03d9, 0x3e403e303e003df, 0x3ec03eb03e803e7,\n        0x3f203f103ee03ed, 0xffff040203f803f5, 0x400ffff03ff03fc,\n        0x405040404030401, 0x40b04090407ffff, 0x4120410040e040c,\n        0x41a041804160414, 0x4220420041e041c, 0x42a042804260424,\n        0x4320430042e042c, 0x43a043804360434, 0x4420440043e043c,\n        0x44a044804460444, 0x4520450044e044c, 0x45a045804560454,\n        0x4620460045e045c, 0x46a046804660464, 0x4330431042f042d,\n        0x43b043904370435, 0x4430441043f043d, 0x44b044904470445,\n        0x4530451044f044d, 0x45b045904570455, 0x4630461045f045d,\n        0x46b046904670465, 0x4130411040f040d, 0x41b041904170415,\n        0x4230421041f041d, 0x42b042904270425, 0x484048304820481,\n        0x48a048904880487, 0x4920491048e048d, 0x49a049904960495,\n        0x4a204a1049e049d, 0x4a804a704a404a3, 0x4ac04ab04aa04a9,\n        0x4b204b104ae04ad, 0xffffffff04b604b5, 0xffffffffffffffff,\n        0x4c604c5ffffffff, 0x4cc04cb04c804c7, 0x4d004cf04ce04cd,\n        0x4d804d704d404d3, 0x4de04dd04da04d9, 0x4e404e304e204e1,\n        0x4ea04e904e804e7, 0x4f004ef04ec04eb, 0x4f604f504f204f1,\n        0x4fe04fd04fa04f9, 0x5040503050004ff, 0x508050705060505,\n        0x510050f050c050b, 0x518051705140513, 0x521051e051d051b,\n        0x529052605250522, 0x531052e052d052a, 0x51c053605350532,\n        0x53e053d053c053b, 0x54405430540053f, 0x54a054905480547,\n        0x550054f054e054d, 0x556055505520551, 0x55c055b05580557,\n        0x560055f055e055d, 0x568056705640563, 0x56e056d056a0569,\n        0x57205710570056f, 0x578057705740573, 0x57c057b057a0579,\n        0x5820581057e057d, 0x588058705840583, 0x58c058b058a0589,\n        0x5920591058e058d, 0x598059705940593, 0x59c059b059a0599,\n        0x5a205a1059e059d, 0x5aa05a905a605a5, 0x5ae05ad05ac05ab,\n        0x5b405b305b005af, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x5bd05bb05b9ffff, 0x5c505c305c105bf, 0x5cd05cb05c905c7,\n        0x5d505d305d105cf, 0x5dd05db05d905d7, 0x5e505e305e105df,\n        0x5ed05eb05e905e7, 0x5f505f305f105ef, 0x5fd05fb05f905f7,\n        0xffff0603060105ff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x5be05bc05baffff, 0x5c605c405c205c0, 0x5ce05cc05ca05c8,\n        0x5d605d405d205d0, 0x5de05dc05da05d8, 0x5e605e405e205e0,\n        0x5ee05ec05ea05e8, 0x5f605f405f205f0, 0x5fe05fc05fa05f8,\n        0x613060406020600, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x8c008a00880086,\n        0x9400920090008e, 0x9c009a00980096, 0xa400a200a0009e, 0xac00aa00a800a6,\n        0xb400b200b000ae, 0xbc00ba00b800b6, 0xc400c200c000be,\n        0x4d100ca04bf04b7, 0x4f7ffff04e500ce, 0xffffffffffffffff,\n        0xffffffff0539ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffff083affff, 0xffffffff0485ffff, 0x648064706460645,\n        0x64e064d064a0649, 0x654065306520651, 0x65a065906580657,\n        0x660065f065c065b, 0x666066506620661, 0x66a066906680667,\n        0x670066f066c066b, 0x674067306720671, 0x678067706760675,\n        0x67e067d067a0679, 0x68206810680067f, 0x686068506840683,\n        0x68c068b06880687, 0x690068f068e068d, 0x694069306920691,\n        0x69a069906960695, 0x69e069d069c069b, 0x6a606a506a206a1,\n        0x6ac06ab06a806a7, 0x6b006af06ae06ad, 0x6b406b306b206b1,\n        0x6ba06b906b606b5, 0x6be06bd06bc06bb, 0x6c306c2070d070c,\n        0x6cb06ca06c706c6, 0x6cf06ce06cd06cc, 0x6d306d206d106d0,\n        0x6d906d806d506d4, 0x6dd06dc06db06da, 0x6e306e206e106e0,\n        0x6e906e806e506e4, 0x6ed06ec06eb06ea, 0x6f106f006ef06ee,\n        0x6f706f606f306f2, 0x6fb06fa06f906f8, 0x6ff06fe06fd06fc,\n        0x704070207010700, 0x70e070a07080706, 0xffff0710ffffffff,\n        0x715071407130712, 0x71b071a07170716, 0x71f071e071d071c,\n        0x723072207210720, 0x729072807270726, 0x72f072e072d072c,\n        0x733073207310730, 0x737073607350734, 0x73d073c073b073a,\n        0x743074207410740, 0x747074607450744, 0x74b074a07490748,\n        0x74f074e074d074c, 0x753075207510750, 0x757075607550754,\n        0x75b075a07590758, 0x75f075e075d075c, 0x766076507610760,\n        0x76a076907680767, 0x770076f076e076d, 0x774077307720771,\n        0x778077707760775, 0x77c077b077a0779, 0x78507840780077f,\n        0x78e078c078a0788, 0x796079407920790, 0x78f078d078b0789,\n        0x797079507930791, 0x7a207a0079e079c, 0xffffffff07a607a4,\n        0x7a307a1079f079d, 0xffffffff07a707a5, 0x7bc07ba07b807b6,\n        0x7c407c207c007be, 0x7bd07bb07b907b7, 0x7c507c307c107bf,\n        0x7dc07da07d807d6, 0x7e407e207e007de, 0x7dd07db07d907d7,\n        0x7e507e307e107df, 0x7f407f207f007ee, 0xffffffff07f807f6,\n        0x7f507f307f107ef, 0xffffffff07f907f7, 0x80c07fe080807fc,\n        0x814080408100800, 0x80dffff0809ffff, 0x815ffff0811ffff,\n        0x828082608240822, 0x830082e082c082a, 0x829082708250823,\n        0x831082f082d082b, 0x8f708f508df08dd, 0x90f090d08fb08f9,\n        0x924092209370935, 0xffffffff093b0939, 0x85f085c08590856,\n        0x86b086808650862, 0x860085d085a0857, 0x86c086908660863,\n        0x88f088c08890886, 0x89b089808950892, 0x890088d088a0887,\n        0x89c089908960893, 0x8bf08bc08b908b6, 0x8cb08c808c508c2,\n        0x8c008bd08ba08b7, 0x8cc08c908c608c3, 0x8e108ce08db08d9,\n        0x8d708d5ffff08d3, 0x8e008de08dc08da, 0xffff08e7ffff08e2,\n        0x8fd08e8ffffffff, 0x8f308f1ffff08ed, 0x8fc08fa08f808f6,\n        0xffffffffffff08fe, 0x9030900090b0909, 0x9070905ffffffff,\n        0x910090e090c090a, 0xffffffffffffffff, 0x91609130920091e,\n        0x91c091a09260918, 0x92509230921091f, 0xffffffffffff0927,\n        0x93d092affffffff, 0x9330931ffff092f, 0x93c093a09380936,\n        0xffffffffffff093e, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff0764ffffffff, 0x1500783ffffffff,\n        0xffffffffffffffff, 0xffff0561ffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff0562ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x18d02c2018902b0, 0x195005e019102d6,\n        0x19d006c01990064, 0x1a5007e01a10076, 0x18e02c3018a02b1,\n        0x196005f019202d7, 0x19e006d019a0065, 0x1a6007f01a20077,\n        0x1c0ffffffffffff, 0xffffffffffff01c1, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x5090475ffffffff,\n        0x511047d050d0477, 0x51904a50515048f, 0x2051f02e80940,\n        0x6e052707180523, 0x110052f03a4052b, 0x54b053706630533,\n        0x50e0478050a0476, 0x51604900512047e, 0x2e90941051a04a6,\n        0x719052400030520, 0x3a5052c006f0528, 0x664053401110530,\n        0xffffffff054c0538, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xa000800040000, 0x160010000e000c, 0x2ce001c001a0018, 0x56030802e602dc,\n        0x66006200600058, 0x7800740070006a, 0x2aa00820080007c,\n        0x64b008400060832, 0x60d060902b805b5, 0x10801060629061d,\n        0x11c01160112010a, 0xffff0134012c0124, 0xb000900050001,\n        0x170011000f000d, 0x2cf001d001b0019, 0x57030902e702dd,\n        0x67006300610059, 0x7900750071006b, 0x2ab00830081007d,\n        0x64c008500070833, 0x60e060a02b905b6, 0x1090107062a061e,\n        0x11d01170113010b, 0xffff0135012d0125, 0x486055a04f404f3,\n        0x48b0297029102b5, 0x49302bb02ba048c, 0x49c02c704980494,\n        0x2cd02ccffff02cb, 0xffff02d502d4ffff, 0xffffffffffffffff,\n        0x4b402edffffffff, 0x4ba04b902f902f8, 0x4be04bd04bc04bb,\n        0x325032404c204c1, 0x3350334032b032a, 0x3410340033d033c,\n        0x34f034e034d034c, 0x73f073e03230322, 0x3b003af03ae03ad,\n        0x3bf03be03b403b3, 0x3e203e103d203d1, 0x606060505a405a3,\n        0x6320631061a0619, 0x6a0069f06560655, 0x7390738046f046e,\n        0x7d507d4077e077d, 0x6df06de08350834, 0x15001406a406a3,\n        0x4ee04ed005d005c, 0x612061105020501, 0x542054101aa01a9,\n        0x566056505540553, 0x586058505760575, 0x5a805a705960595,\n        0x162016105b805b7, 0x3ea03e903a703a6, 0xffffffffffffffff,\n        0x60fffffffffffff, 0xffff061806170610, 0x6240623ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x8d008b00890087, 0x9500930091008f, 0x9d009b00990097, 0xa500a300a1009f,\n        0xad00ab00a900a7, 0xb500b300b100af, 0xbd00bb00b900b7, 0xc500c300c100bf,\n        0x4d200cb04c004b8, 0x4f8ffff04e600cf, 0xffffffffffffffff,\n        0xffffffff053affff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x616061502d902d8,\n        0x6220621061c061b, 0x1e501e406280627, 0x6340633062e062d,\n        0x63e063d06380637, 0x32f032e06420641, 0x66e066d065e065d,\n        0x68a0689067c067b, 0x6aa06a906980697, 0x6c906c806b806b7,\n        0x6e706e606d706d6, 0xffffffff06f506f4, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x69006807870786, 0x7b107b0028f028e, 0x3bd03bc07c907c8,\n        0x8030802001f001e, 0x2b302b208190818, 0x2d302d208370836,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x7ab07aaffffffff, 0x7b307b207af07ae, 0x2f502f402eb02ea,\n        0x311031003070306, 0x7cb07caffffffff, 0x7d307d207cf07ce,\n        0x33b033a03330332, 0x3490348033f033e, 0x7e907e807e707e6,\n        0x7ed07ec07eb07ea, 0x3b203b103ac03ab, 0x7fb07fa03bb03ba,\n        0x3f003ef03dc03db, 0x28302820620061f, 0x80b080a08070806,\n        0x8130812080f080e, 0x81b081a08170816, 0x8210820081f081e,\n        0x4b004af04a0049f, 0x4d604d504c404c3, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x83805460545ffff, 0x83d083c083b0839,\n        0x590058f0580057f, 0x5b205b105a0059f, 0x63bffffffffffff,\n        0xffffffff079b063c, 0x60c060b06080607, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x630062f062c062b,\n        0x63a063906360635, 0xffff06440640063f, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x2fc02fa025e02f6, 0xffff0304030302fe,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x30cffffffffffff,\n        0x314031202c0030e, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x7ac02da07a8ffff, 0x7b402e402e202e0,\n        0x144076b02f00724, 0x318081c030a0479, 0x7cc031c031a07c6,\n        0x32c022c07d00320, 0xffff046c0336007a, 0xffffffffffffffff,\n        0x7ad02db07a9ffff, 0x7b502e502e302e1, 0x145076c02f10725,\n        0x319081d030b047a, 0x7cd031d031b07c7, 0x32d022d07d10321,\n        0xffff046d0337007b, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x72005a09280012, 0x114010c03520338,\n        0x2f202ae02bc0625, 0x10e064f031608ef, 0x4fb029a02ee02b6,\n        0x2de02d002c802be, 0x330031e047f0798, 0x3b802c4024e0342,\n        0x473056b047b03e5, 0x91104df072a06c4, 0x73005b09290013,\n        0x115010d03530339, 0x2f302af02bd0626, 0x10f0650031708f0,\n        0x4fc029b02ef02b7, 0x2df02d102c902bf, 0x331031f04800799,\n        0x3b902c5024f0343, 0x474056c047c03e6, 0x91204e0072b06c5,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff]);\n//4000 bytes\nenum alphaTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0xb0], [0x100,\n        0x240, 0x5100], [0x706050403020100, 0xe0d0c0a0b0a0908,\n        0x100a0f0303030303, 0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a,\n        0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a,\n        0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a,\n        0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a,\n        0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x3000200010000, 0x7000600050004, 0xb000a00090008, 0xf000e000d000c,\n        0x12001100010010, 0x15001400010013, 0x19001800170016, 0x1c0001001b001a,\n        0x1f001f001e001d, 0x1f001f001f0020, 0x1f001f001f001f, 0x1f002300220021,\n        0x1f001f00250024, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100260001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x27000100010001,\n        0x1000100010001, 0x2a002900010028, 0x2e002d002c002b, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x2f000100010001, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x3100300001001f, 0x34003300320001,\n        0x38003700360035, 0x1f001f001f0039, 0x3d003c003b003a, 0x1f001f001f003e,\n        0x1f001f0040003f, 0x1f0041001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x42000100010001, 0x1f001f001f0043, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1000100010001, 0x1f001f001f0044, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f004500010001, 0x46001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f0047, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x4b004a00490048, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f004c001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1000100010001, 0x1004d00010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x4e000100010001, 0x1f001f001f004f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f004f00010001, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f, 0x1f001f001f001f,\n        0x0, 0x7fffffe07fffffe, 0x420040000000000, 0xff7fffffff7fffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x501f0003ffc3, 0x0, 0x3cdf000000000020,\n        0xfffffffbffffd740, 0xffbfffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff,\n        0xfffe00ffffffffff, 0xfffffffe027fffff, 0xbfff0000000000ff,\n        0x707ffffff00b6, 0xffffffff07ff0000, 0xffffc000feffffff,\n        0xffffffffffffffff, 0x9c00e1fe1fefffff, 0xffffffffffff0000,\n        0xffffffffffffe000, 0x3ffffffffffff, 0x43007fffffffc00, 0x1ffffcffffff,\n        0x1ffffff, 0x1ffd00000000, 0x7fff03f000000000, 0xefffffffffffffff,\n        0xfefe000fffe1dfff, 0xe3c5fdfffff99fee, 0x3000fb080599f,\n        0xc36dfdfffff987ee, 0x3f00005e021987, 0xe3edfdfffffbbfee, 0xf00011bbf,\n        0xe3edfdfffff99fee, 0x2000fb0c0199f, 0xc3ffc718d63dc7ec, 0x811dc7,\n        0xe3effdfffffddfee, 0xf03601ddf, 0xe3effdfffffddfec, 0x6000f40601ddf,\n        0xe7fffffffffddfec, 0xfc00000f00805ddf, 0x2ffbfffffc7fffec,\n        0xc0000ff5f807f, 0x7fffffffffffffe, 0x207f, 0x3bffecaefef02596,\n        0xf000205f, 0x1, 0xfffe1ffffffffeff, 0x1ffffffffeffff03, 0x0,\n        0xf97fffffffffffff, 0xffffc1e7ffff0000, 0xffffffff3000407f,\n        0xf7ffffffffff20bf, 0xffffffffffffffff, 0xffffffff3d7f3dff,\n        0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x87ffffff,\n        0xffffffff0000ffff, 0x1fffffffffffff, 0xfffffffffffffffe,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff9fffffffffff, 0xffffffff07fffffe,\n        0x1c7ffffffffff, 0xfffff000fdfff, 0xddfff000fffff, 0xffcfffffffffffff,\n        0x108001ff, 0xffffffff00000000, 0xffffffffffffff, 0xffff07ffffffffff,\n        0x3fffffffffffff, 0x1ff0fff1fffffff, 0x1f3fffffff0000,\n        0xffff0fffffffffff, 0x3ff, 0xffffffff0fffffff, 0x1ffffe7fffffff,\n        0x8000000000, 0x0, 0xffefffffffffffff, 0xfef, 0xfc00f3ffffffffff,\n        0x3ffbfffffffff, 0x3fffffffffffff, 0x3ffffffffc00e000, 0x0,\n        0x6fde0000000000, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x0, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f,\n        0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, 0x0, 0x8002000000000000,\n        0x1fff0000, 0x0, 0xf3ffbd503e2ffc84, 0xffffffff000043e0, 0x1ff, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffc0000000000000, 0x3ffffffffff,\n        0xffff7fffffffffff, 0xffffffff7fffffff, 0xffffffffffffffff,\n        0xc781fffffffff, 0xffff20bfffffffff, 0x80ffffffffff,\n        0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x800000000000, 0x0, 0x0, 0x0,\n        0x1f3e03fe000000e0, 0xfffffffffffffffe, 0xfffffffee07fffff,\n        0xf7ffffffffffffff, 0xfffe3fffffffffe0, 0xffffffffffffffff,\n        0x7ffffff00007fff, 0xffff000000000000, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3fffffffffffff, 0x0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x1fff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x1fff, 0x3fffffffffff0000, 0xc00ffff1fff,\n        0x8ff07fffffffffff, 0xffffffff80ffffff, 0xffffffffffff,\n        0xfffffffcff800000, 0xffffffffffffffff, 0x7ff000f79ff,\n        0xff00000000000000, 0xfffffff7bb, 0xfffffffffffff, 0xffffffffffffffff,\n        0x8fc00000000000f, 0xffff07fffffffc00, 0x1fffffff0007ffff,\n        0xfff7ffffffffffff, 0x8000, 0x7fffffffffffff, 0x47fffff00003fff,\n        0x7fffffffffffffff, 0x3cffff38000005, 0x7f7f007e7e7e, 0x0, 0x0,\n        0x7ffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff000fffffffff, 0xffffffffffff87f, 0xffffffffffffffff,\n        0xffff3fffffffffff, 0xffffffffffffffff, 0x3ffffff, 0x5f7ffdffe0f8007f,\n        0xffffffffffffffdb, 0x3ffffffffffff, 0xfffffffffff80000,\n        0x3fffffffffffffff, 0xffffffffffff0000, 0xfffffffffffcffff,\n        0xfff0000000000ff, 0x0, 0xffdf000000000000, 0xffffffffffffffff,\n        0x1fffffffffffffff, 0x7fffffe00000000, 0xffffffc007fffffe,\n        0x7fffffffffffffff, 0x1cfcfcfc, 0xb7ffff7fffffefff, 0x3fff3fff,\n        0xffffffffffffffff, 0x7ffffffffffffff, 0x0, 0x1fffffffffffff, 0x0, 0x0,\n        0x0, 0x0, 0xffffffff1fffffff, 0x1ffff, 0xffff00007fffffff, 0x7ff,\n        0xffffffff3fffffff, 0x3eff0f, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x3fffffff, 0x0, 0x91bffffffffffd3f, 0x3fffff, 0x0, 0x0,\n        0x3ffffff003fffff, 0x0, 0xc0ffffffffffffff, 0x0, 0xffffffeeff06f,\n        0x1fffffff00000000, 0x0, 0x0, 0x3fffffffffffff, 0x7ffff003fffff, 0x0,\n        0x0, 0xffffffffffffffff, 0x1ff, 0x0, 0x0, 0xffffffffffffffff, 0x3f,\n        0x1fffffffffffffc, 0x1ffffff0000, 0x7ffffffffffff, 0x0,\n        0xffffffffffffffff, 0x1e, 0x0, 0x0, 0x3fffffffffffff, 0x0,\n        0xffffffffffffffff, 0x7fffffffffff, 0x0, 0x0, 0xffffffffffffffff,\n        0x7ffffffff, 0x0, 0x0, 0x7fffffffffff, 0x0, 0x0, 0x0,\n        0x1ffffffffffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff,\n        0x7fffffffffff001f, 0xfff80000, 0x0, 0x3, 0x0, 0x0, 0x0,\n        0xffffffffffffffff, 0xffffffffffdfffff, 0xebffde64dfffffff,\n        0xffffffffffffffef, 0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffff3fffffffff, 0xf7fffffff7fffffd,\n        0xffdfffffffdfffff, 0xffff7fffffff7fff, 0xfffffdfffffffdff, 0xff7,\n        0xaf7fe96ffffffef, 0x5ef7f796aa96ea84, 0xffffbee0ffffbff, 0x0,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffff,\n        0x1fffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3fffffff, 0x0, 0x0, 0x0, 0x3fffffff, 0x0, 0x0, 0x0]);\n//2304 bytes\nenum markTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0x70], [0x100,\n        0x140, 0x2c00], [0x402030202020100, 0x207020206020205,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020208, 0x202020202020202, 0x202020202020202, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x1000000000000, 0x5000400030002, 0x9000800070006, 0xd000c000b000a,\n        0xf00000000000e, 0x10000000000000, 0x14001300120011, 0x160015, 0x17,\n        0x0, 0x0, 0x190018, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x1b00000000, 0x1f001e001d001c, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000000, 0x2100000000, 0x220000,\n        0x0, 0x2300000000, 0x0, 0x250024, 0x2600000000, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x27000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x2900280000, 0x0, 0x0, 0x0, 0x2a0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xffffffffffffffff, 0xffffffffffff, 0x0, 0x0, 0x0, 0x0, 0x3f8, 0x0,\n        0x0, 0x0, 0xbffffffffffe0000, 0xb6, 0x7ff0000, 0x10000fffff800, 0x0,\n        0x3d9f9fc00000, 0xffff000000020000, 0x7ff, 0x1ffc000000000,\n        0xff80000000000, 0x3eeffbc00000, 0xe000000, 0x0, 0x7ffffff000000000,\n        0xdc0000000000000f, 0xc00feffff, 0xd00000000000000e, 0xc0080399f,\n        0xd00000000000000e, 0x23000000023987, 0xd00000000000000e, 0xc00003bbf,\n        0xd00000000000000e, 0xc00c0399f, 0xc000000000000004, 0x803dc7,\n        0xc00000000000000e, 0xc00603ddf, 0xd00000000000000c, 0xc00603ddf,\n        0xc00000000000000c, 0xc00803ddf, 0xc, 0xc0000ff5f8400,\n        0x7f2000000000000, 0x7f80, 0x1bf2000000000000, 0x3f00,\n        0xc2a0000003000000, 0xfffe000000000000, 0x1ffffffffeffe0df, 0x40,\n        0x7ffff80000000000, 0x1e3f9dc3c00000, 0x3c00bffc, 0x0, 0x0, 0xe0000000,\n        0x0, 0x0, 0x1c0000001c0000, 0xc0000000c0000, 0xfff0000000000000,\n        0x200fffff, 0x3800, 0x0, 0x20000000000, 0x0, 0xfff0fff00000000, 0x0,\n        0xffff000000000000, 0x301, 0xf800000, 0x9fffffff7fe00000, 0x0, 0x0,\n        0xfff000000000001f, 0xff8000000001f, 0x3ffe00000007, 0xfffc000000000,\n        0xfffff000000000, 0x0, 0x0, 0x1c21fffff70000, 0x0, 0x0, 0x0,\n        0xf000007fffffffff, 0x0, 0x0, 0x0, 0x1ffffffff0000, 0x0, 0x0, 0x0,\n        0x3800000000000, 0x0, 0x8000000000000000, 0x0, 0xffffffff00000000,\n        0xfc0000000000, 0x0, 0x6000000, 0x0, 0x0, 0x3ff7800000000000,\n        0x80000000, 0x3000000000000, 0xf800000844, 0x0, 0xfff0000000000003,\n        0x3ffff0000001f, 0x3fc000000000, 0xfff80, 0xfff800000000000f, 0x1,\n        0x7ffe0000000000, 0x800000000003008, 0xc19d000000000000,\n        0x60f80000000002, 0x0, 0x0, 0x0, 0x37f800000000, 0x40000000, 0x0, 0x0,\n        0x0, 0x7f0000ffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000000,\n        0x870000000000f06e, 0x0, 0x0, 0x0, 0xff00000000000007, 0x7f,\n        0x7ff000000000007, 0x0, 0x1fff8000000007, 0x0, 0xfff8000000000007, 0x1,\n        0x0, 0x0, 0xfff80000000000, 0x0, 0x0, 0x7ffffffffffe0000, 0x78000, 0x0,\n        0x0, 0xf807e3e000000000, 0x3c0000000fe7, 0x0, 0x0, 0x1c, 0x0, 0x0,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffff, 0x0, 0x0, 0x0, 0x0]);\n//2384 bytes\nenum numberTrieEntries = TrieEntry!(bool, 8, 6, 7)([0x0, 0x20, 0xc0], [0x100,\n        0x280, 0x1a80], [0x402030202020100, 0x807020202020605,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x2000200010000, 0x2000200020002, 0x2000200020002, 0x5000200040003,\n        0x7000600020002, 0x9000800060006, 0x2000b0006000a, 0x2000d000c000c,\n        0x20002000e0005, 0x2000f00020002, 0x2000200020002, 0x11000200100002,\n        0x1300120002000e, 0xc00140002, 0x2000200020015, 0x2000200020002,\n        0x19001800170016, 0x2000200020002, 0x20002001b001a, 0x1d001c00020002,\n        0x2000200020002, 0x2000200020002, 0x20002001e0002, 0x2000200020002,\n        0x2000020002001f, 0x2000200220021, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200060023,\n        0xc0017000c0024, 0x400020002000c, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000e00020002,\n        0x26002500020002, 0x28002700020002, 0x2000200230002, 0x2000200020002,\n        0x2002a00020029, 0x2002c0002002b, 0x2000200020002, 0x200020002002d,\n        0xc002f0004002e, 0x2000200020002, 0x2000200020002, 0x2000200050002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020030, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2003100020002, 0x2000200020002, 0x32000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2003300020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x2000200020002, 0x2000200020002, 0x2000200020002, 0x2000200020002,\n        0x3ff000000000000, 0x0, 0x720c000000000000, 0x0, 0x0, 0x0, 0x0,\n        0x3ff00000000, 0x0, 0x3ff000000000000, 0x0, 0x3ff, 0x0, 0xffc000000000,\n        0x0, 0x3f0ffc000000000, 0x0, 0xfcffc000000000, 0x0, 0x7ffc000000000,\n        0x0, 0x7f00ffc000000000, 0x0, 0x3fffc000000000, 0x0, 0x3ff0000,\n        0xfffff00000000, 0x0, 0x3ff0000, 0x0, 0x0, 0x1ffffe0000000000, 0x0,\n        0x1c00000000000, 0x0, 0x3ff03ff00000000, 0x0, 0xffc0, 0x0, 0x7ff0000,\n        0x3ff03ff, 0x0, 0x0, 0x3ff03ff, 0x0, 0x3f1000000000000, 0x3ff, 0x0,\n        0x0, 0xffffffffffff0000, 0x3e7, 0x0, 0x0, 0xffffffff00000000,\n        0xfffffff, 0xfffffc0000000000, 0x0, 0xffc0000000000000, 0xfffff, 0x0,\n        0x0, 0x2000000000000000, 0x70003fe00000080, 0x0, 0x3c0000, 0x0,\n        0x3ff00000000, 0xfffeff00, 0xfffe0000000003ff, 0x0, 0x3ff00000000, 0x0,\n        0x3f000000000000, 0x0, 0xfffffffffff80, 0x1ffffffffffffff, 0x400, 0x0,\n        0xf00000000, 0x402, 0x0, 0x3e0000, 0x0, 0xff000000, 0xfc00000, 0x0,\n        0x0, 0x60000000000000ff, 0x0, 0xff000000ff000000, 0x0,\n        0x7fffffff00000000, 0x0, 0xfffffffc0000, 0xffc0000000000000, 0x0,\n        0xffffffffffffffff, 0x7ffffffff, 0x0, 0x3ffff00000000, 0x0,\n        0xffffffffffffc000, 0x7ff, 0x0, 0x0, 0x0]);\n//2336 bytes\nenum punctuationTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0x60],\n        [0x100, 0x100, 0x3100], [0x402030202020100, 0x202020202020605,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x2000100010000, 0x5000400030001, 0x1000800070006, 0xb000a00090001,\n        0xd00010001000c, 0x10000f0001000e, 0x14001300120011, 0x1000100010015,\n        0x17000100010016, 0x18000100010001, 0x1000100190001, 0x1001c001b001a,\n        0x100010001001d, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1001f0001001e, 0x23002200210020, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x26002500240001,\n        0x28000100270001, 0x1000100010001, 0x2c002b002a0029, 0x1000100010001,\n        0x10001002e002d, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x100010001002f, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x8c00f7ee00000000, 0x28000000b8000001, 0x88c0088200000000, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x4000000000000000, 0x80, 0x0, 0x0, 0xfc000000,\n        0x4000000000000600, 0x18000000000049, 0xc8003600, 0x3c0000000000, 0x0,\n        0x100000, 0x3fff, 0x0, 0x0, 0x380000000000000, 0x7fff000000000000,\n        0x40000000, 0x0, 0x0, 0x0, 0x1003000000000, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x1000000000000, 0x0, 0x0, 0x0, 0x10000000000000, 0x0, 0xc008000, 0x0,\n        0x0, 0x3c0000000017fff0, 0x0, 0x20, 0x61f0000, 0x0, 0xfc00, 0x0,\n        0x800000000000000, 0x0, 0x1ff00000000, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,\n        0x0, 0x600000000000, 0x18000000, 0x380000000000, 0x60000000000000, 0x0,\n        0x0, 0x7700000, 0x7ff, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0xc0000000,\n        0x0, 0x3f7f00000000, 0x0, 0x0, 0x1fc000000, 0x0, 0xf000000000000000,\n        0xf800000000000000, 0xc000000000000000, 0x0, 0x800ff,\n        0xffff00ffffff0000, 0x600000007ffbffef, 0x6000, 0x0, 0x60000000f00,\n        0x0, 0x0, 0x0, 0x0, 0x3fff0000000000, 0x0, 0xffc000000060, 0x0, 0x0,\n        0x1fffff8, 0x300000000f000000, 0x0, 0x0, 0x0, 0xde00000000000000, 0x0,\n        0x1000000000000, 0x0, 0x0, 0xfff7fffffffffff, 0x0, 0x0, 0x0,\n        0x20010000fff3ff0e, 0x0, 0x100000000, 0x800000000000000, 0x0, 0x0, 0x0,\n        0xc000000000000000, 0xe000, 0x4008000000000000, 0x0, 0xfc000000000000,\n        0x0, 0xf0000000000000, 0x0, 0x70000000000c000, 0xc00000000000,\n        0x80000000, 0x0, 0xc0003ffe, 0x0, 0xf0000000, 0x0, 0x30000c0000000,\n        0x0, 0x0, 0x0, 0x80000000000, 0xc000000000000000, 0x0, 0x0, 0x0,\n        0xffff000003ff0000, 0xd0bfff7ffff, 0x0, 0x0, 0xb80000018c00f7ee,\n        0x3fa8000000, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000,\n        0x10000, 0x0, 0x800000, 0x0, 0x0, 0x8000000080000000, 0x0, 0x0, 0x0,\n        0x0, 0x8000000001ff0000, 0x0, 0x0, 0xfe00000000000000, 0x0, 0x0, 0x0,\n        0x0, 0x3f80, 0xd800000000000000, 0x3, 0x0, 0xf, 0x0, 0x1e0, 0x0,\n        0xf000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n//2848 bytes\nenum symbolTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0x70], [0x100,\n        0x140, 0x3d00], [0x503040303020100, 0x807030303030306,\n        0x303030303030303, 0x303030303030303, 0x303030303030303,\n        0x303030303030303, 0x303030303030303, 0x303030303030303,\n        0x303030303030303, 0x303030303030303, 0x303030303030303,\n        0x303030303030303, 0x303030303030303, 0x303030303030303,\n        0x303030303030303, 0x303030303030303, 0x303030303030303, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x3000200010000, 0x7000600050004, 0xa000900080001, 0xe000d000c000b,\n        0x1000010001000f, 0x11000100010001, 0x13000100120001, 0x14000100010001,\n        0x18001700160015, 0x1a001700170019, 0x1c0017001b0017, 0x1f001e0001001d,\n        0x17002200210020, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100230001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x25000100010024, 0x1002700010026, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x28000100010001, 0x2b002a00290001,\n        0x10001002c0001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x30002f002e002d, 0x32003100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1003300010001,\n        0x37003600350034, 0x3b003a00390038, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x7000081000000000, 0x5000000140000000, 0x113d37c00000000,\n        0x80000000800000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xffffafe0fffc003c, 0x0, 0x20000000000000, 0x30, 0x40000000000000, 0x0,\n        0x0, 0x4, 0x0, 0x0, 0x0, 0x8000, 0x0, 0xc9c0, 0x0, 0x0,\n        0x6000020040000000, 0x0, 0x0, 0x0, 0x40000000000000, 0x0, 0x0, 0x0,\n        0xc0c000000000000, 0x0, 0x0, 0x0, 0x2000000000000, 0x0,\n        0x1000000000000, 0x0, 0x7f8000000000000, 0x0, 0x8000000000000000, 0x0,\n        0x0, 0x0, 0x200000000000000, 0x0, 0x0, 0x8000000000000000, 0x0, 0x0,\n        0x0, 0x1500000fce8000e, 0x0, 0xc000000000000000, 0x1e0dfbf, 0x0, 0x0,\n        0xc0000000, 0x0, 0x0, 0x0, 0x3ff0000, 0x0, 0x0, 0x0, 0x0, 0x8000000,\n        0x0, 0x1, 0x0, 0xffffffffc0000000, 0x0, 0x1ff007fe00000000, 0x0, 0x0,\n        0x0, 0x0, 0xa000000000000000, 0x6000e000e000e003, 0x0,\n        0x1c00000000040010, 0x7ffffff00001c00, 0x0, 0xc0042afc1d0037b, 0xbc1f,\n        0xffffffffffff0000, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xfffff9fffffff0ff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xfffffffffffff, 0x7fffffffff, 0x7ff, 0xfffffffff0000000,\n        0x3ffffffffff, 0xfffffffffffffffe, 0xffffffffff, 0xfffffffffff00000,\n        0xffff003fffffff9f, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xfffffffffe000007, 0xcffffffff0ffffff, 0xffffffffffffffff, 0x3ff1fff,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x7e000000000, 0x0, 0x0, 0xfffffffffbffffff,\n        0xfffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xfff0000003fffff, 0xc0c00001000c0010, 0x0,\n        0x18000000, 0x0, 0x0, 0x0, 0xffc30000, 0xfffffffff, 0xfffffc007fffffff,\n        0xffffffff000100ff, 0x1fffffffffc00, 0x7fffffffffffffff, 0x0, 0x0, 0x0,\n        0xffffffffffffffff, 0x0, 0x0, 0xffffffffffff0000, 0x7f, 0x3007fffff,\n        0x0, 0x600, 0x0, 0x3c00f0000000000, 0x0, 0x0, 0x0, 0x0,\n        0x380000000000000, 0x0, 0x0, 0x20000000000, 0x0, 0xfffc000000000000,\n        0x3, 0x0, 0x0, 0x0, 0x3000000000000000, 0x0, 0x27400000000, 0x0, 0x0,\n        0x4000000070000810, 0x50000001, 0x0, 0x30007f7f00000000,\n        0xff80000000000000, 0xfe00000000000000, 0xfff03ff, 0x1fffffffffff0000,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x3fffffffffffff, 0xfffffe7fffffffff, 0x1c1fffffffff,\n        0xffffc3fffffff018, 0x3fffffff, 0xffffffffffffffff, 0x23, 0x0, 0x0,\n        0xffffffffffffffff, 0x7fffff, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x800000008000002, 0x20000000200000, 0x800000008000, 0x20000000200,\n        0x8, 0x0, 0x0, 0x0, 0x3000000000000, 0xffff0fffffffffff,\n        0xffffffffffffffff, 0x7ffe7fff000fffff, 0xfffefffe, 0xffff7fffffff0000,\n        0xffff0fffffffffff, 0x7ffffff, 0xffffffc000000000, 0x7ffffffffff0007,\n        0x301ff, 0x0, 0x0, 0xffbf0001ffffffff, 0x1fffffffffffffff,\n        0xffffffff000fffff, 0x1ffff000007df, 0x7fffffffffffffff,\n        0xfffffffffffffffd, 0xffffffffffffffff, 0x1effffffffffffff,\n        0x3fffffffffffffff, 0xffffff000f, 0x0, 0xf800000000000000,\n        0xffffffffffffffff, 0xffe1, 0xffffffffffffffff, 0x3f,\n        0xffffffffffffffff, 0xfffffffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n//4576 bytes\nenum graphicalTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x20, 0xb8],\n        [0x100, 0x260, 0x6100], [0x706050403020100, 0xe0d0c0a0b0a0908,\n        0x100a0f0303030303, 0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a,\n        0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a,\n        0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a,\n        0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a,\n        0xa0a0a0a0a0a0a11, 0xa0a0a0a0a0a0a0a, 0xa0a0a0a0a0a0a0a, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x2000100010000, 0x5000400030001, 0x9000800070006, 0xd000c000b000a,\n        0x10000f0001000e, 0x12001100010001, 0x16001500140013, 0x19000100180017,\n        0x1c0001001b001a, 0x1e00010001001d, 0x1f000100010001, 0x23002200210020,\n        0x1002600250024, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100270001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x28000100010001,\n        0x1000100010001, 0x2b002a00010029, 0x2f002e002d002c, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x30000100010001, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x33003200010031, 0x36003500340001,\n        0x3a003900380037, 0x3100310031003b, 0x3f003e003d003c, 0x31004100310040,\n        0x31003100430042, 0x31004400310031, 0x31003100310031, 0x31003100310031,\n        0x45000100010001, 0x31003100310046, 0x31003100310031, 0x31003100310031,\n        0x1000100010001, 0x31003100310047, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31004800010001, 0x49003100310031,\n        0x31003100310031, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0x3100310031004a, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0x4e004d004c004b, 0x5200510050004f, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31003100310031, 0x31005300310031,\n        0x57005600550054, 0x5b005a00590058, 0x31003100310031, 0x31003100310031,\n        0x1000100010001, 0x1005c00010001, 0x1000100010001, 0x1000100010001,\n        0x1000100010001, 0x5d000100010001, 0x3100310031005e, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31005e00010001, 0x31003100310031,\n        0x310031005f0031, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0x31003100310031, 0x31003100310031, 0x31003100310031, 0x31003100310031,\n        0xffffffff00000000, 0x7fffffffffffffff, 0xffffdfff00000000,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x7cffffffffffffff, 0xfffffffbffffd7f0, 0xffffffffffffffff,\n        0xfffe00ffffffffff, 0xfffffffefe7fffff, 0xfffffffffffe86ff,\n        0x1f07ffffff00ff, 0xffffffffcfffffc0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffdfffffff, 0xffffffffffff3fff,\n        0xffffffffffffe7ff, 0x3ffffffffffff, 0x7ffffffffffffff,\n        0x7fff3fffffffffff, 0x4fffffff, 0x1ffd00000000, 0x7ffffff000000000,\n        0xffffffffffffffff, 0xfeffffffffffffff, 0xf3c5fdfffff99fee,\n        0xfffffcfb080799f, 0xd36dfdfffff987ee, 0x3fffc05e023987,\n        0xf3edfdfffffbbfee, 0x3ffcf00013bbf, 0xf3edfdfffff99fee,\n        0xffffcfb0c0399f, 0xc3ffc718d63dc7ec, 0x7ffffc000813dc7,\n        0xe3effdfffffddfee, 0xff00ffcf03603ddf, 0xf3effdfffffddfec,\n        0x6ffcf40603ddf, 0xe7fffffffffddfec, 0xfe3fffcf00807ddf,\n        0x2ffbfffffc7fffec, 0x1c0000ff5f847f, 0x87fffffffffffffe, 0xfffffff,\n        0x3bffecaefef02596, 0xf3ff3f5f, 0xffffffffffffffff, 0xfffe1ffffffffeff,\n        0xdffffffffeffffff, 0x7ffdfff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffff20bf, 0xffffffffffffffff,\n        0xffffffff3d7f3dff, 0x7f3dffffffff3dff, 0xffffffffff7fff3d,\n        0xffffffffff3dffff, 0x1fffffffe7ffffff, 0xffffffff03ffffff,\n        0x1fffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffff1fffffff, 0x1ffffffffffff, 0x7fffff001fdfff, 0xddfff000fffff,\n        0xffffffffffffffff, 0x3ff03ff3fffffff, 0xffffffff03ff3fff,\n        0xffffffffffffff, 0xffff07ffffffffff, 0x3fffffffffffff,\n        0xfff0fff1fffffff, 0x1f3ffffffffff1, 0xffff0fffffffffff,\n        0xffffffffc7ff03ff, 0xffffffffcfffffff, 0x9fffffff7fffffff,\n        0x3fff03ff03ff, 0x0, 0xffffffffffffffff, 0x1fffffffffff0fff,\n        0xffffffffffffffff, 0xf00fffffffffffff, 0xf8ffffffffffffff,\n        0xffffffffffffe3ff, 0x0, 0x7fffffffff00ff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xf000007fffffffff,\n        0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0xffdfffffffffffff,\n        0x7fdcffffefcfffdf, 0xffff80ffffff07ff, 0xfff30000ffffffff,\n        0x7ffffff1fff7fff, 0x1ffffffff0000, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffff03ff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xfffffffffffff, 0x7fffffffff, 0xffffffff000007ff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xfffffffffffffffe, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3ff1fff,\n        0x0, 0x0, 0xffff7fffffffffff, 0xffffffff7fffffff, 0xffffffffffffffff,\n        0xfe0fffffffffffff, 0xffff20bfffffffff, 0x800180ffffffffff,\n        0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0xfffffffffffffff, 0x0,\n        0xfffffffffbffffff, 0xfffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xfff0000003fffff,\n        0xffffffffffffffff, 0xfffffffffffffffe, 0xfffffffffe7fffff,\n        0xffffffffffffffff, 0xfffe3fffffffffe0, 0xffffffffffffffff,\n        0x7ffffffffff7fff, 0xffff000fffffffff, 0xffffffff7fffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x1fff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffff1fff, 0xffffffffffff007f, 0xfffffffffff,\n        0xffffffffffffffff, 0xffffffff80ffffff, 0xffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x7ff000f7fff,\n        0xff00000000000000, 0x3ff0fffffffffff, 0xffffffffffffff,\n        0xffffffffffffffff, 0xfffffff03ffc01f, 0xffffffffffffffff,\n        0x1fffffff800fffff, 0xffffffffffffffff, 0xc3ffbfff, 0x7fffffffffffff,\n        0xffffffff3ff3fff, 0xffffffffffffffff, 0x7ffffff8000007,\n        0x7f7f007e7e7e, 0x0, 0x0, 0x3ff3fffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff000fffffffff, 0xffffffffffff87f, 0x0, 0x0,\n        0x0, 0x0, 0xffffffffffffffff, 0xffff3fffffffffff, 0xffffffffffffffff,\n        0x3ffffff, 0x5f7fffffe0f8007f, 0xffffffffffffffdb, 0xffffffffffffffff,\n        0xfffffffffff80003, 0xffffffffffffffff, 0xffffffffffff0000,\n        0xfffffffffffcffff, 0x3fff0000000000ff, 0xffff007f03ffffff,\n        0xffdf0f7ffff7ffff, 0xffffffffffffffff, 0x1fffffffffffffff,\n        0xfffffffffffffffe, 0xffffffffffffffff, 0x7fffffffffffffff,\n        0x30007f7f1cfcfcfc, 0xb7ffff7fffffefff, 0x3fff3fff, 0xffffffffffffffff,\n        0x7ffffffffffffff, 0xff8fffffffffff87, 0xffffffffffffffff, 0xfff07ff,\n        0x3fffffffffff0000, 0x0, 0x0, 0xffffffff1fffffff, 0x1ffff,\n        0xffff000f7fffffff, 0x7ff, 0xffffffffbfffffff, 0x3fff0f,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x3ff3fffffff, 0x0,\n        0x91bffffffffffd3f, 0xffbfffff, 0x0, 0x0, 0x83ffffff8fffffff, 0x0,\n        0xc0ffffffffffffff, 0x0, 0x870ffffffeeff06f, 0xffffffff01ff00ff, 0x0,\n        0x0, 0xfe3fffffffffffff, 0xff07ffffff3fffff, 0x0, 0x0,\n        0xffffffffffffffff, 0x1ff, 0x0, 0x0, 0x0, 0x7fffffff00000000, 0x0, 0x0,\n        0xffffffffffffffff, 0xfffffffc3fff, 0xdfffffffffffffff,\n        0x3ff01ffffff0003, 0xffdfffffffffffff, 0xf, 0xffffffffffffffff,\n        0x3ff01ff, 0x0, 0x0, 0xffffffffffffff, 0x3ff, 0xffffffffffffffff,\n        0x7fffffffffff, 0x0, 0x0, 0xffffffffffffffff, 0xf0007ffffffff, 0x0,\n        0x0, 0x7fffffffffff, 0x0, 0x0, 0x0, 0x1ffffffffffffff, 0x0, 0x0, 0x0,\n        0xffffffffffffffff, 0x7fffffffffff001f, 0xffff8000, 0x0, 0x3, 0x0, 0x0,\n        0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x3fffffffffffff, 0xfffffe7fffffffff, 0xf807ffffffffffff,\n        0xffffffffffffffff, 0x3fffffff, 0xffffffffffffffff, 0x3f, 0x0, 0x0,\n        0xffffffffffffffff, 0x3ffff007fffff, 0x0, 0x0, 0xffffffffffffffff,\n        0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef,\n        0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffff3fffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffcfff,\n        0xaf7fe96ffffffef, 0x5ef7f796aa96ea84, 0xffffbee0ffffbff,\n        0x3000000000000, 0xffff0fffffffffff, 0xffffffffffffffff,\n        0x7ffe7fff000fffff, 0xfffefffe, 0xffff7fffffff07ff, 0xffff0fffffffffff,\n        0x7ffffff, 0xffffffc000000000, 0x7ffffffffff0007, 0x301ff, 0x0, 0x0,\n        0xffbf0001ffffffff, 0x1fffffffffffffff, 0xffffffff000fffff,\n        0x1ffff000007df, 0x7fffffffffffffff, 0xfffffffffffffffd,\n        0xffffffffffffffff, 0x1effffffffffffff, 0x3fffffffffffffff,\n        0xffffff000f, 0x0, 0xf800000000000000, 0xffffffffffffffff, 0xffe1,\n        0xffffffffffffffff, 0x3f, 0xffffffffffffffff, 0xfffffffffffff, 0x0,\n        0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x7fffff, 0x1fffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3fffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffff, 0x0, 0x0, 0x0, 0x0]);\n//3664 bytes\nenum nonCharacterTrieEntries = TrieEntry!(bool, 7, 4, 4, 6)([0x0, 0x10, 0x4c,\n        0x104], [0x80, 0xf0, 0x2e0, 0x3180], [0x706050403020100,\n        0xb0b0b0b0a090808, 0xb0b0b0b0b0b0b0b, 0xb0b0b0b0b0b0b0b,\n        0xb0b0b0b0b0b0b0b, 0xb0b0b0b0b0b0b0b, 0xb0b0b0b0b0b0b0b,\n        0xd0808080b0b0b0c, 0xd080808, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x3000200010000, 0x7000600050004, 0xb000a00090008, 0xd000d000d000c,\n        0xe000d000d000d, 0xd000d000d000d, 0xd000d000d000d, 0xd000d000d000d,\n        0xd000d000d000d, 0xf000d000d000d, 0xd00110010000d, 0xd000d000d000d,\n        0xd000d000d000d, 0xd000d0012000d, 0xd000d000d000d, 0x140013000d000d,\n        0x18001700160015, 0x1b001b001a0019, 0x1b001b001d001c, 0x1b001b001e000d,\n        0x1b001b001b001b, 0x1b001b001b001b, 0x20001f001b001b, 0x1b001b001b001b,\n        0x1b001b001b001b, 0x1b001b001b001b, 0x1b001b001b001b, 0x1b001b001b0021,\n        0x1b001b001b001b, 0x1b001b00230022, 0x24001b001b001b, 0x1b001b00260025,\n        0xd000d000d000d, 0xd000d000d000d, 0xd000d000d000d, 0xd000d000d000d,\n        0xd000d000d000d, 0xd000d000d000d, 0xd000d0027000d, 0x1b00290028000d,\n        0x1b001b001b001b, 0x1b001b001b001b, 0x1b001b001b001b, 0x1b002a001b001b,\n        0x1b001b001b001b, 0x1b001b001b001b, 0x1b001b001b001b, 0x1b001b001b001b,\n        0x1b001b001b002b, 0x1b001b001b001b, 0x1b001b001b001b, 0x1b001b001b001b,\n        0xd000d000d000d, 0xd000d000d000d, 0xd000d000d000d, 0x2c000d000d000d,\n        0xd000d000d000d, 0xd000d000d000d, 0xd000d000d000d, 0x2c000d000d000d,\n        0x0, 0x0, 0x0, 0x200010000, 0x0, 0x6000500040003, 0x7, 0xb000a00090008,\n        0xf000e000d000c, 0x12001100100000, 0x16001500140013, 0x1a001900180017,\n        0x1e001d001c001b, 0x2200210020001f, 0x26002500240023, 0x29002800270000,\n        0x2a000000000000, 0x0, 0x2d002c002b0000, 0x310030002f002e, 0x0, 0x0,\n        0x33003200000000, 0x36000000350034, 0x3a003900380037, 0x3e003d003c003b,\n        0x4200410040003f, 0x44000000430000, 0x47004200460045, 0x48000000000000,\n        0x0, 0x4c004b004a0049, 0x4f004e004d0000, 0x5000000000, 0x0,\n        0x51000000000000, 0x530052, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0,\n        0x42004200550000, 0x58000000570056, 0x5c005b005a0059, 0x51005e0042005d,\n        0x5f000000000000, 0x6000540000, 0x63006200000061, 0x64000000000057,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a00000000, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x65000000000000, 0x67006600000000, 0x0, 0x38006900000068,\n        0x6b006a00000000, 0x6d00000038006c, 0x6f0000006e0000, 0x72000000710070,\n        0x74004200420073, 0x0, 0x0, 0x0, 0x75006300000000, 0x0, 0x0,\n        0x77000000760000, 0x7a000000790078, 0x0, 0x7d007c007b0000,\n        0x800000007f007e, 0x81006400000054, 0xb000000830082, 0x86008500000084,\n        0x87003200420042, 0x8b008a00890088, 0x42008c00000000, 0x42004200420042,\n        0x42004200420042, 0x42004200420042, 0x420042008e008d, 0x4200900042008f,\n        0x42004200920091, 0x42004200940093, 0x42004200950000, 0x42004200420042,\n        0x42004200960042, 0x42004200420042, 0x98000000970000, 0x9a00000099004b,\n        0x42004200420042, 0x42004200420042, 0x42004200420042, 0x42004200420042,\n        0x9b003800420042, 0x42004200420042, 0x42004200420042, 0x42004200420042,\n        0x42004200420042, 0x42004200420042, 0x0, 0x0, 0x0, 0x420042009c0000,\n        0x420042009d0000, 0x42004200420042, 0x42004200420042, 0x42004200420042,\n        0x4200420042009c, 0x42004200420042, 0x42004200420042, 0x42004200420042,\n        0x0, 0x0, 0x4200420042009e, 0x42004200420042, 0x42004200420042,\n        0x42004200420042, 0x42004200420042, 0x4200a0009f0000, 0x420042004200a1,\n        0x42004200420042, 0x42004200420042, 0x42004200420042, 0x3a000000000000,\n        0xa30000000000a2, 0x42004200a40000, 0x42004200a50000, 0xa800a700a60000,\n        0xaa00a9, 0xab00000000, 0xac000000000000, 0x42004200420042,\n        0x42004200420042, 0xb000af00ae00ad, 0x42004200420042, 0xb200b10000003d,\n        0xb500b4003d00b3, 0x42004200b700b6, 0xbb00ba00b900b8, 0xbd000000bc0064,\n        0xc0004200bf00be, 0xa4000000c10000, 0x42004200510000, 0x0, 0x0,\n        0xc2000000000000, 0x0, 0x0, 0x0, 0x0, 0x31, 0x420042004200a3,\n        0x42004200420042, 0x42004200420042, 0x42004200420042, 0x0, 0x0,\n        0x420042004200a3, 0x42004200420042, 0x420042000000c3, 0xc4000000000000,\n        0x42004200420042, 0x42004200420042, 0x0, 0x0, 0x0, 0xbe000000000000,\n        0x0, 0x0, 0x0, 0xbe000000000000, 0x0, 0x8300000000000000, 0x40000280f,\n        0x1ff0000000000, 0x101800000, 0x17900, 0xffe0f8000000ff00, 0x20000020,\n        0x4000, 0x1800, 0xfffc000000000000, 0xf800000000000000,\n        0x8000c00000000000, 0xffffffffb0000000, 0xffffe002ffffffff,\n        0x8000000fffffffff, 0x100000000000000, 0xc3a020000066011,\n        0xf00000304f7f8660, 0x2c92020000067811, 0xffc0003fa1fdc678,\n        0xc12020000044011, 0xfffc0030fffec440, 0xc12020000066011,\n        0xff0000304f3fc660, 0x3c0038e729c23813, 0xf800003fff7ec238,\n        0x1c10020000022011, 0xff0030fc9fc220, 0xc10020000022013,\n        0xfff90030bf9fc220, 0x1800000000022013, 0x1c00030ff7f8220,\n        0xd004000003800013, 0xffe3ffff00a07b80, 0x7800000000000001,\n        0xfffffffff0000000, 0xc4001351010fda69, 0xffffffff0c00c0a0,\n        0x1e00000000100, 0x2000000001000000, 0xfffffffff8002000, 0xdf40,\n        0xc280c200, 0x80c200000000c200, 0x8000c2, 0xc20000, 0xe000000018000000,\n        0xfc000000, 0xffe0000000000000, 0xe0000000, 0xfffe000000000000,\n        0xff800000ffe02000, 0xfff22000fff00000, 0xfc00fc00c0000000, 0xfc008000,\n        0xff00000000000000, 0xf80000000000, 0xffc0000000000000,\n        0xf000f000e0000000, 0xffe0c0000000000e, 0xf00000000000, 0x3800fc00,\n        0x30000000, 0x6000000080000000, 0xffffc000fc00fc00, 0xffffffffffffffff,\n        0xe00000000000f000, 0xff0000000000000, 0x700000000000000, 0x1c00,\n        0xff8000000000ff00, 0xfffff8000000000, 0xc0c00000, 0xc00000005500c0c0,\n        0x20000000000000, 0x8023000010300020, 0xc002000000000,\n        0xf8000000e0008000, 0xfffe00000000ffff, 0xfc00, 0xfff0000000000000,\n        0xffffff8000000000, 0xfffff800, 0x1, 0xfffffffffc00e000,\n        0x800000000000, 0x80000000, 0x1f0000000000000, 0xdf4000000000,\n        0x7ffe7f0000000000, 0x80808080ff800000, 0x80808080, 0xf000000000000000,\n        0x4000000, 0xf000ffffffc00000, 0x1800000, 0x1c0000000001f,\n        0xf800000000008000, 0xfff000000000, 0x8000000000000000,\n        0xffffffffffffe000, 0xe000, 0xff80, 0xfffff00000000000, 0x7f000000,\n        0xfffff800fff08000, 0xffffffffffffff, 0xfc00f00000000000,\n        0xf0000000fc003fe0, 0xe00000007ff00000, 0xffffffff3c004000,\n        0xff80000000000000, 0xf00000000c00c000, 0xff80000007fffff8,\n        0xffff8080ff818181, 0xfc00c00000000000, 0xf000000000000780,\n        0xc00000000000, 0xfffffffffc000000, 0xa08000001f07ff80, 0x24, 0x7fffc,\n        0xffff, 0x30000, 0xc000ffffffffff00, 0xff80fc000000, 0x20f08000080000,\n        0x6000000000000000, 0xc1ff8080e3030303, 0x4800008000001000,\n        0xffffffffc000c000, 0x70000000000078, 0xfffffffff000f800,\n        0xc00000000000ffff, 0xfffffffffffe0000, 0xfff080000000,\n        0xfffffffffffff800, 0x40000000, 0xffffffffffc000f0, 0xfffffc00c0000000,\n        0x6e400000000002c0, 0xffffffff00400000, 0x7c00000070000000,\n        0x3f00000000000000, 0x78f0000001100f90, 0xfe00ff00, 0x1c0000000000000,\n        0xf8000000c00000, 0xfffffffffffffe00, 0x80000000ffffffff,\n        0xffff00000003c000, 0xfc00fe000000fffc, 0xfffffffffffffff0,\n        0xfffffffffc00fe00, 0xfffffffffffffc00, 0xffff800000000000,\n        0xfff0fff800000000, 0xfe00000000000000, 0x800000000000ffe0,\n        0xffffffff00007fff, 0xfffffffffffffffc, 0x18000000000,\n        0xffffffffc0000000, 0xffffffffffffffc0, 0xfffc0000ff800000, 0x200000,\n        0x1400219b20000000, 0x10, 0x8400000020201840, 0x203a0, 0xc000000000,\n        0x3000, 0xf508016900000010, 0xa10808695569157b, 0xf0000411f0000400,\n        0xfffcffffffffffff, 0x80018000fff00000, 0xffffffff00010001,\n        0x80000000f800, 0xfffffffff8000000, 0x3fffffffff, 0xf80000000000fff8,\n        0xfffffffffffcfe00, 0x40fffe00000000, 0xe000000000000000, 0xfff00000,\n        0xfffe0000fffff820, 0x2, 0xe100000000000000, 0xc000000000000000,\n        0xffffff000000fff0, 0x7ffffffffffffff, 0xffffffffffff001e,\n        0xffffffffff800000, 0xfffffffd, 0xffff000000000000, 0xc000000000000000]);\nenum MAX_SIMPLE_LOWER = 1043;\nenum MAX_SIMPLE_UPPER = 1051;\nenum MAX_SIMPLE_TITLE = 1055;\n//8192 bytes\nenum toUpperIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x20, 0x100],\n        [0x100, 0x380, 0xc00], [0x402030202020100, 0x202020202020205,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x3000200010000, 0x7000600050004, 0xa00090008, 0xd000c000b0000,\n        0x110010000f000e, 0x1400130012, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x150000, 0x19001800170016, 0x1d001c001b001a, 0x0, 0x1f001e0000,\n        0x0, 0x0, 0x20000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x24002300220021, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x2700260000, 0x2a00290028, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x2c0000, 0x0, 0x0,\n        0x0, 0x0, 0x2e002d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x200010000ffff,\n        0x6000500040003, 0xa000900080007, 0xe000d000c000b, 0x1200110010000f,\n        0x16001500140013, 0xffff001900180017, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffff001affff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x41bffffffffffff,\n        0x1e001d001c001b, 0x2200210020001f, 0x26002500240023, 0x2a002900280027,\n        0x2e002d002c002b, 0xffff00310030002f, 0x35003400330032,\n        0x39003800370036, 0x3bffff003affff, 0x3dffff003cffff, 0x3fffff003effff,\n        0x41ffff0040ffff, 0x43ffff0042ffff, 0x45ffff0044ffff, 0x47ffff0046ffff,\n        0x49ffff0048ffff, 0x4bffff004affff, 0x4dffff004cffff, 0x4fffff004effff,\n        0x51ffff0050ffff, 0x53ffff0052041d, 0x55ffff0054ffff,\n        0xffff0056ffffffff, 0xffff0058ffff0057, 0xffff005affff0059,\n        0xffff005cffff005b, 0x5effff043a005d, 0x60ffff005fffff,\n        0x62ffff0061ffff, 0x64ffff0063ffff, 0x66ffff0065ffff, 0x68ffff0067ffff,\n        0x6affff0069ffff, 0x6cffff006bffff, 0x6effff006dffff, 0x70ffff006fffff,\n        0x72ffff0071ffff, 0x74ffff0073ffff, 0xffff0075ffffffff,\n        0x780077ffff0076, 0x7affffffff0079, 0xffffffff007bffff,\n        0xffffffffffff007c, 0xffffffffffff007d, 0xffff007effffffff,\n        0xffffffff007fffff, 0xffff00810080ffff, 0xffff0082ffffffff,\n        0x84ffff0083ffff, 0xffffffff0085ffff, 0xffffffffffff0086,\n        0xffffffff0087ffff, 0xffffffffffff0088, 0xffff008affff0089,\n        0xffffffff008bffff, 0x8dffff008cffff, 0xffffffffffffffff,\n        0xffff008f008effff, 0x92ffff00910090, 0xffff0094ffff0093,\n        0xffff0096ffff0095, 0xffff0098ffff0097, 0xffff009affff0099,\n        0x9dffff009c009b, 0x9fffff009effff, 0xa1ffff00a0ffff, 0xa3ffff00a2ffff,\n        0xa5ffff00a4ffff, 0xa700a6ffff0442, 0xffffffff00a8ffff,\n        0xaaffff00a9ffff, 0xacffff00abffff, 0xaeffff00adffff, 0xb0ffff00afffff,\n        0xb2ffff00b1ffff, 0xb4ffff00b3ffff, 0xb6ffff00b5ffff, 0xb8ffff00b7ffff,\n        0xbaffff00b9ffff, 0xbcffff00bbffff, 0xbdffffffffffff, 0xbfffff00beffff,\n        0xc1ffff00c0ffff, 0xc3ffff00c2ffff, 0xc5ffff00c4ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xc7ffffffff00c6,\n        0xffff00c9ffff00c8, 0xcaffffffffffff, 0xccffff00cbffff,\n        0xceffff00cdffff, 0xd200d100d000cf, 0xd500d4ffff00d3, 0xd7ffff00d6ffff,\n        0xffffffffffffffff, 0xd9ffffffff00d8, 0xffff00db00daffff,\n        0xdeffff00dd00dc, 0xdfffffffffffff, 0xffff00e100e0ffff,\n        0xffffffff00e2ffff, 0xffffffffffffffff, 0xffffffff00e3ffff,\n        0xe5ffffffff00e4, 0xffffffffffffffff, 0xe900e800e700e6,\n        0xffffffffffff00ea, 0xffff00ebffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff00ecffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xeeffff00edffff, 0xefffffffffffff,\n        0xf0ffffffffffff, 0xffffffff00f200f1, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffff043c, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xf600f500f400f3, 0xf900f800f7043f,\n        0xfd00fc00fb00fa, 0x101010000ff00fe, 0x105010401030102,\n        0x109010801070106, 0x10d010c010b010a, 0x1110110010f010e,\n        0xffff011401130112, 0xffffffff01160115, 0x11901180117ffff,\n        0x11bffff011affff, 0x11dffff011cffff, 0x11fffff011effff,\n        0x121ffff0120ffff, 0x123ffff0122ffff, 0x125ffff0124ffff,\n        0xffff012801270126, 0xffffffff0129ffff, 0x12bffffffff012a,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x12f012e012d012c, 0x133013201310130,\n        0x137013601350134, 0x13b013a01390138, 0x13f013e013d013c,\n        0x143014201410140, 0x147014601450144, 0x14b014a01490148,\n        0x14f014e014d014c, 0x153015201510150, 0x157015601550154,\n        0x15b015a01590158, 0x15dffff015cffff, 0x15fffff015effff,\n        0x161ffff0160ffff, 0x163ffff0162ffff, 0x165ffff0164ffff,\n        0x167ffff0166ffff, 0x169ffff0168ffff, 0x16bffff016affff,\n        0xffffffff016cffff, 0xffffffffffffffff, 0x16dffffffffffff,\n        0x16fffff016effff, 0x171ffff0170ffff, 0x173ffff0172ffff,\n        0x175ffff0174ffff, 0x177ffff0176ffff, 0x179ffff0178ffff,\n        0x17bffff017affff, 0x17dffff017cffff, 0x17fffff017effff,\n        0x181ffff0180ffff, 0x183ffff0182ffff, 0x185ffff0184ffff,\n        0x187ffff0186ffff, 0xffff0188ffffffff, 0xffff018affff0189,\n        0xffff018cffff018b, 0x18f018effff018d, 0x191ffff0190ffff,\n        0x193ffff0192ffff, 0x195ffff0194ffff, 0x197ffff0196ffff,\n        0x199ffff0198ffff, 0x19bffff019affff, 0x19dffff019cffff,\n        0x19fffff019effff, 0x1a1ffff01a0ffff, 0x1a3ffff01a2ffff,\n        0x1a5ffff01a4ffff, 0x1a7ffff01a6ffff, 0x1a9ffff01a8ffff,\n        0x1abffff01aaffff, 0x1adffff01acffff, 0x1afffff01aeffff,\n        0x1b1ffff01b0ffff, 0x1b3ffff01b2ffff, 0x1b5ffff01b4ffff,\n        0x1b7ffff01b6ffff, 0x1b9ffff01b8ffff, 0x1bbffff01baffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x1be01bd01bcffff,\n        0x1c201c101c001bf, 0x1c601c501c401c3, 0x1ca01c901c801c7,\n        0x1ce01cd01cc01cb, 0x1d201d101d001cf, 0x1d601d501d401d3,\n        0x1da01d901d801d7, 0x1de01dd01dc01db, 0x42e01e101e001df,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffff01e2ffff, 0xffffffff01e3ffff,\n        0x1e5ffff01e4ffff, 0x1e7ffff01e6ffff, 0x1e9ffff01e8ffff,\n        0x1ebffff01eaffff, 0x1edffff01ecffff, 0x1efffff01eeffff,\n        0x1f1ffff01f0ffff, 0x1f3ffff01f2ffff, 0x1f5ffff01f4ffff,\n        0x1f7ffff01f6ffff, 0x1f9ffff01f8ffff, 0x1fbffff01faffff,\n        0x1fdffff01fcffff, 0x1ffffff01feffff, 0x201ffff0200ffff,\n        0x203ffff0202ffff, 0x205ffff0204ffff, 0x207ffff0206ffff,\n        0x209ffff0208ffff, 0x20bffff020affff, 0x20dffff020cffff,\n        0x20fffff020effff, 0x211ffff0210ffff, 0x213ffff0212ffff,\n        0x215ffff0214ffff, 0x217ffff0216ffff, 0x219ffff0218ffff,\n        0x21bffff021affff, 0x21dffff021cffff, 0x21fffff021effff,\n        0x221ffff0220ffff, 0x223ffff0222ffff, 0x225ffff0224ffff,\n        0x227ffff0226ffff, 0x229ffff0228ffff, 0x22bffff022affff,\n        0x22dffff022cffff, 0x4460444022effff, 0x22f044c044a0448,\n        0xffffffffffffffff, 0x231ffff0230ffff, 0x233ffff0232ffff,\n        0x235ffff0234ffff, 0x237ffff0236ffff, 0x239ffff0238ffff,\n        0x23bffff023affff, 0x23dffff023cffff, 0x23fffff023effff,\n        0x241ffff0240ffff, 0x243ffff0242ffff, 0x245ffff0244ffff,\n        0x247ffff0246ffff, 0x249ffff0248ffff, 0x24bffff024affff,\n        0x24dffff024cffff, 0x24fffff024effff, 0x251ffff0250ffff,\n        0x253ffff0252ffff, 0x255ffff0254ffff, 0x257ffff0256ffff,\n        0x259ffff0258ffff, 0x25bffff025affff, 0x25dffff025cffff,\n        0x25fffff025effff, 0x263026202610260, 0x267026602650264,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x26b026a02690268,\n        0xffffffff026d026c, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x2710270026f026e, 0x275027402730272, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x279027802770276, 0x27d027c027b027a,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2810280027f027e,\n        0xffffffff02830282, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x28504500284044e, 0x287045602860453, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x28b028a02890288, 0x28f028e028d028c,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x293029202910290,\n        0x297029602950294, 0x29b029a02990298, 0xffffffff029d029c,\n        0x47d047b04790477, 0x48504830481047f, 0x48d048b04890487,\n        0x49504930491048f, 0x49d049b04990497, 0x4a504a304a1049f,\n        0x4ad04ab04a904a7, 0x4b504b304b104af, 0x4bd04bb04b904b7,\n        0x4c504c304c104bf, 0x4cd04cb04c904c7, 0x4d504d304d104cf,\n        0x4d704e302b702b6, 0x4ef0459ffff04e5, 0xffffffffffffffff,\n        0xffff02b9ffff04d9, 0x4db04e7ffffffff, 0x4f2045bffff04e9,\n        0xffffffffffffffff, 0xffffffffffff04dd, 0x460045d02bc02bb,\n        0x4650463ffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x46b046802be02bd, 0x472047002bf046e, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x4df04ebffffffff, 0x4f50475ffff04ed,\n        0xffffffffffffffff, 0xffffffffffff04e1, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff02c1ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2c502c402c302c2,\n        0x2c902c802c702c6, 0x2cd02cc02cb02ca, 0x2d102d002cf02ce,\n        0xffffffffffffffff, 0xffffffffffff02d2, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2d602d502d402d3,\n        0x2da02d902d802d7, 0x2de02dd02dc02db, 0x2e202e102e002df,\n        0x2e602e502e402e3, 0x2ea02e902e802e7, 0xffffffff02ec02eb,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2f002ef02ee02ed,\n        0x2f402f302f202f1, 0x2f802f702f602f5, 0x2fc02fb02fa02f9,\n        0x30002ff02fe02fd, 0x304030303020301, 0x308030703060305,\n        0x30c030b030a0309, 0x310030f030e030d, 0x314031303120311,\n        0x318031703160315, 0xffff031b031a0319, 0xffffffff031cffff,\n        0xffff031e031dffff, 0xffff0320ffff031f, 0xffffffffffff0321,\n        0x322ffffffffffff, 0xffff0323ffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x325ffff0324ffff, 0x327ffff0326ffff,\n        0x329ffff0328ffff, 0x32bffff032affff, 0x32dffff032cffff,\n        0x32fffff032effff, 0x331ffff0330ffff, 0x333ffff0332ffff,\n        0x335ffff0334ffff, 0x337ffff0336ffff, 0x339ffff0338ffff,\n        0x33bffff033affff, 0x33dffff033cffff, 0x33fffff033effff,\n        0x341ffff0340ffff, 0x343ffff0342ffff, 0x345ffff0344ffff,\n        0x347ffff0346ffff, 0x349ffff0348ffff, 0x34bffff034affff,\n        0x34dffff034cffff, 0x34fffff034effff, 0x351ffff0350ffff,\n        0x353ffff0352ffff, 0x355ffff0354ffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff0357ffff0356, 0x358ffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x35c035b035a0359, 0x360035f035e035d, 0x364036303620361,\n        0x368036703660365, 0x36c036b036a0369, 0x370036f036e036d,\n        0x374037303720371, 0x378037703760375, 0x37c037b037a0379,\n        0x37fffff037e037d, 0xffffffffffffffff, 0xffffffff0380ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x382ffff0381ffff, 0x384ffff0383ffff,\n        0x386ffff0385ffff, 0x388ffff0387ffff, 0x38affff0389ffff,\n        0x38cffff038bffff, 0x38effff038dffff, 0x390ffff038fffff,\n        0x392ffff0391ffff, 0x394ffff0393ffff, 0x396ffff0395ffff,\n        0xffffffff0397ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x399ffff0398ffff,\n        0x39bffff039affff, 0x39dffff039cffff, 0x39fffff039effff,\n        0x3a1ffff03a0ffff, 0x3a3ffff03a2ffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x3a4ffffffffffff,\n        0x3a6ffff03a5ffff, 0x3a8ffff03a7ffff, 0x3aaffff03a9ffff,\n        0x3abffffffffffff, 0x3adffff03acffff, 0x3afffff03aeffff,\n        0x3b1ffff03b0ffff, 0x3b3ffff03b2ffff, 0x3b5ffff03b4ffff,\n        0x3b7ffff03b6ffff, 0x3b9ffff03b8ffff, 0x3bbffff03baffff,\n        0x3bdffff03bcffff, 0x3bfffff03beffff, 0x3c1ffff03c0ffff,\n        0x3c3ffff03c2ffff, 0x3c5ffff03c4ffff, 0x3c7ffff03c6ffff,\n        0x3c9ffff03c8ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff03caffffffff, 0x3ccffffffff03cb, 0x3ceffff03cdffff,\n        0x3d0ffff03cfffff, 0xffffffffffffffff, 0xffffffffffff03d1,\n        0x3d3ffff03d2ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3d5ffff03d4ffff, 0x3d7ffff03d6ffff,\n        0xffffffff03d8ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x42404220420041e, 0xffff042c042a0427, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x430ffffffffffff, 0x438043604340432,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3db03da03d9ffff, 0x3df03de03dd03dc,\n        0x3e303e203e103e0, 0x3e703e603e503e4, 0x3eb03ea03e903e8,\n        0x3ef03ee03ed03ec, 0xffff03f203f103f0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x3f603f503f403f3, 0x3fa03f903f803f7, 0x3fe03fd03fc03fb,\n        0x4020401040003ff, 0x406040504040403, 0x40a040904080407,\n        0x40e040d040c040b, 0x41204110410040f, 0x416041504140413,\n        0x41a041904180417, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff]);\n//8064 bytes\nenum toLowerIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x20, 0x100],\n        [0x100, 0x380, 0xbc0], [0x402030202020100, 0x202020202020205,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x2000000010000, 0x6000500040003, 0x80007, 0xb000a00090000,\n        0xf000e000d000c, 0x1200110010, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x14001300000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x18001700160015, 0x1c001b001a0019, 0x0,\n        0x1f001e001d, 0x0, 0x0, 0x21002000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x25002400230022, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2700260000, 0x2a00290028, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x2c, 0x0,\n        0x0, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x200010000ffff, 0x6000500040003, 0xa000900080007, 0xe000d000c000b,\n        0x1200110010000f, 0x16001500140013, 0xffff001900180017,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x1d001c001b001a, 0x210020001f001e, 0x25002400230022, 0x29002800270026,\n        0x2d002c002b002a, 0xffff0030002f002e, 0x34003300320031,\n        0x413003700360035, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff0039ffff0038, 0xffff003bffff003a, 0xffff003dffff003c,\n        0xffff003fffff003e, 0xffff0041ffff0040, 0xffff0043ffff0042,\n        0xffff0045ffff0044, 0xffff0047ffff0046, 0xffff0049ffff0048,\n        0xffff004bffff004a, 0xffff004dffff004c, 0xffff004fffff004e,\n        0xffff0051ffff0414, 0xffff0053ffff0052, 0x55ffff0054ffff,\n        0x57ffff0056ffff, 0x59ffff0058ffff, 0x5bffff005affff,\n        0xffff005c0423ffff, 0xffff005effff005d, 0xffff0060ffff005f,\n        0xffff0062ffff0061, 0xffff0064ffff0063, 0xffff0066ffff0065,\n        0xffff0068ffff0067, 0xffff006affff0069, 0xffff006cffff006b,\n        0xffff006effff006d, 0xffff0070ffff006f, 0xffff0072ffff0071,\n        0x75ffff00740073, 0xffffffff0076ffff, 0xffff00780077ffff,\n        0x7b007affff0079, 0x7e007d007cffff, 0x80007fffffffff, 0x83ffff00820081,\n        0x860085ffff0084, 0xffffffffffff0087, 0x8affff00890088,\n        0xffff008cffff008b, 0x8f008effff008d, 0xffffffff0090ffff,\n        0x930092ffff0091, 0x9600950094ffff, 0x98ffff0097ffff,\n        0xffffffffffff0099, 0xffffffffffff009a, 0xffffffffffffffff,\n        0x9dffff009c009b, 0xa0009fffff009e, 0xa2ffff00a1ffff, 0xa4ffff00a3ffff,\n        0xa6ffff00a5ffff, 0xa8ffff00a7ffff, 0xffff00a9ffffffff,\n        0xffff00abffff00aa, 0xffff00adffff00ac, 0xffff00afffff00ae,\n        0xffff00b1ffff00b0, 0xffff00b300b20426, 0xb600b5ffff00b4,\n        0xffff00b8ffff00b7, 0xffff00baffff00b9, 0xffff00bcffff00bb,\n        0xffff00beffff00bd, 0xffff00c0ffff00bf, 0xffff00c2ffff00c1,\n        0xffff00c4ffff00c3, 0xffff00c6ffff00c5, 0xffff00c8ffff00c7,\n        0xffff00caffff00c9, 0xffff00ccffff00cb, 0xffff00ceffff00cd,\n        0xffff00d0ffff00cf, 0xffff00d2ffff00d1, 0xffff00d4ffff00d3,\n        0xffffffffffffffff, 0xd600d5ffffffff, 0xffff00d800d7ffff,\n        0xdaffff00d9ffff, 0xffff00dd00dc00db, 0xffff00dfffff00de,\n        0xffff00e1ffff00e0, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff00e3ffff00e2, 0xffff00e4ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff00e5ffffffff, 0xffff00e800e700e6, 0xeb00eaffff00e9,\n        0xee00ed00ec0424, 0xf200f100f000ef, 0xf600f500f400f3, 0xfa00f900f800f7,\n        0xfdffff00fc00fb, 0x101010000ff00fe, 0x105010401030102,\n        0xffffffffffffffff, 0xffffffffffff0425, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x106ffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff0108ffff0107,\n        0xffff010affff0109, 0xffff010cffff010b, 0xffff010effff010d,\n        0xffff0110ffff010f, 0xffff0112ffff0111, 0xffffffffffffffff,\n        0x114ffffffff0113, 0xffff01160115ffff, 0x11901180117ffff,\n        0x11d011c011b011a, 0x1210120011f011e, 0x125012401230122,\n        0x129012801270126, 0x12d012c012b012a, 0x1310130012f012e,\n        0x135013401330132, 0x139013801370136, 0x13d013c013b013a,\n        0x1410140013f013e, 0x145014401430142, 0x149014801470146,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff014bffff014a, 0xffff014dffff014c, 0xffff014fffff014e,\n        0xffff0151ffff0150, 0xffff0153ffff0152, 0xffff0155ffff0154,\n        0xffff0157ffff0156, 0xffff0159ffff0158, 0xffffffffffff015a,\n        0xffffffffffffffff, 0xffff015bffffffff, 0xffff015dffff015c,\n        0xffff015fffff015e, 0xffff0161ffff0160, 0xffff0163ffff0162,\n        0xffff0165ffff0164, 0xffff0167ffff0166, 0xffff0169ffff0168,\n        0xffff016bffff016a, 0xffff016dffff016c, 0xffff016fffff016e,\n        0xffff0171ffff0170, 0xffff0173ffff0172, 0xffff0175ffff0174,\n        0x178ffff01770176, 0x17affff0179ffff, 0x17cffff017bffff,\n        0xffffffff017dffff, 0xffff017fffff017e, 0xffff0181ffff0180,\n        0xffff0183ffff0182, 0xffff0185ffff0184, 0xffff0187ffff0186,\n        0xffff0189ffff0188, 0xffff018bffff018a, 0xffff018dffff018c,\n        0xffff018fffff018e, 0xffff0191ffff0190, 0xffff0193ffff0192,\n        0xffff0195ffff0194, 0xffff0197ffff0196, 0xffff0199ffff0198,\n        0xffff019bffff019a, 0xffff019dffff019c, 0xffff019fffff019e,\n        0xffff01a1ffff01a0, 0xffff01a3ffff01a2, 0xffff01a5ffff01a4,\n        0xffff01a7ffff01a6, 0xffff01a9ffff01a8, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x1ac01ab01aaffff, 0x1b001af01ae01ad,\n        0x1b401b301b201b1, 0x1b801b701b601b5, 0x1bc01bb01ba01b9,\n        0x1c001bf01be01bd, 0x1c401c301c201c1, 0x1c801c701c601c5,\n        0x1cc01cb01ca01c9, 0xffff01cf01ce01cd, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x41dffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x1d301d201d101d0, 0x1d701d601d501d4, 0x1db01da01d901d8,\n        0x1df01de01dd01dc, 0x1e301e201e101e0, 0x1e701e601e501e4,\n        0x1eb01ea01e901e8, 0x1ef01ee01ed01ec, 0x1f301f201f101f0,\n        0x1f6ffff01f501f4, 0xffffffffffffffff, 0xffffffff01f7ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff01f9ffff01f8, 0xffff01fbffff01fa, 0xffff01fdffff01fc,\n        0xffff01ffffff01fe, 0xffff0201ffff0200, 0xffff0203ffff0202,\n        0xffff0205ffff0204, 0xffff0207ffff0206, 0xffff0209ffff0208,\n        0xffff020bffff020a, 0xffff020dffff020c, 0xffff020fffff020e,\n        0xffff0211ffff0210, 0xffff0213ffff0212, 0xffff0215ffff0214,\n        0xffff0217ffff0216, 0xffff0219ffff0218, 0xffff021bffff021a,\n        0xffff021dffff021c, 0xffff021fffff021e, 0xffff0221ffff0220,\n        0xffff0223ffff0222, 0xffff0225ffff0224, 0xffff0227ffff0226,\n        0xffff0229ffff0228, 0xffff022bffff022a, 0xffff022dffff022c,\n        0xffff022fffff022e, 0xffff0231ffff0230, 0xffff0233ffff0232,\n        0xffff0235ffff0234, 0xffff0237ffff0236, 0xffff0239ffff0238,\n        0xffff023bffff023a, 0xffff023dffff023c, 0xffff023fffff023e,\n        0xffff0241ffff0240, 0x4280427ffff0242, 0xffff042b042a0429,\n        0xffff0243ffffffff, 0xffff0245ffff0244, 0xffff0247ffff0246,\n        0xffff0249ffff0248, 0xffff024bffff024a, 0xffff024dffff024c,\n        0xffff024fffff024e, 0xffff0251ffff0250, 0xffff0253ffff0252,\n        0xffff0255ffff0254, 0xffff0257ffff0256, 0xffff0259ffff0258,\n        0xffff025bffff025a, 0xffff025dffff025c, 0xffff025fffff025e,\n        0xffff0261ffff0260, 0xffff0263ffff0262, 0xffff0265ffff0264,\n        0xffff0267ffff0266, 0xffff0269ffff0268, 0xffff026bffff026a,\n        0xffff026dffff026c, 0xffff026fffff026e, 0xffff0271ffff0270,\n        0xffff0273ffff0272, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x277027602750274, 0x27b027a02790278, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x27f027e027d027c, 0xffffffff02810280,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x285028402830282,\n        0x289028802870286, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x28d028c028b028a, 0x2910290028f028e, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x295029402930292, 0xffffffff02970296,\n        0xffff042dffff042c, 0xffff042fffff042e, 0x299ffff0298ffff,\n        0x29bffff029affff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x29f029e029d029c, 0x2a302a202a102a0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x43f043e043d043c, 0x443044204410440, 0x447044604450444,\n        0x44b044a04490448, 0x44f044e044d044c, 0x453045204510450,\n        0x457045604550454, 0x45b045a04590458, 0x45f045e045d045c,\n        0x463046204610460, 0x467046604650464, 0x46b046a04690468,\n        0x46c0472ffffffff, 0x4780430ffff0473, 0x2bf02be02bd02bc,\n        0xffffffffffff046d, 0x46e0474ffffffff, 0x4790431ffff0475,\n        0x2c402c302c202c1, 0xffffffffffff046f, 0x4330432ffffffff,\n        0x4350434ffffffff, 0x2c902c802c702c6, 0xffffffffffffffff,\n        0x4370436ffffffff, 0x43a0439ffff0438, 0x2cd02cc02cb02ca,\n        0xffffffffffff02ce, 0x4700476ffffffff, 0x47a043bffff0477,\n        0x2d202d102d002cf, 0xffffffffffff0471, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff02d4ffffffff,\n        0x2d602d5ffffffff, 0xffffffffffffffff, 0xffff02d7ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2db02da02d902d8,\n        0x2df02de02dd02dc, 0x2e302e202e102e0, 0x2e702e602e502e4,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x2e8ffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x2ea02e9ffffffff, 0x2ee02ed02ec02eb, 0x2f202f102f002ef,\n        0x2f602f502f402f3, 0x2fa02f902f802f7, 0x2fe02fd02fc02fb,\n        0x3020301030002ff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x306030503040303, 0x30a030903080307,\n        0x30e030d030c030b, 0x31203110310030f, 0x316031503140313,\n        0x31a031903180317, 0x31e031d031c031b, 0x32203210320031f,\n        0x326032503240323, 0x32a032903280327, 0x32e032d032c032b,\n        0xffff03310330032f, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3340333ffff0332, 0x336ffffffff0335,\n        0x338ffff0337ffff, 0x33b033a0339ffff, 0xffff033dffff033c,\n        0xffffffff033effff, 0xffffffffffffffff, 0x340033fffffffff,\n        0xffff0342ffff0341, 0xffff0344ffff0343, 0xffff0346ffff0345,\n        0xffff0348ffff0347, 0xffff034affff0349, 0xffff034cffff034b,\n        0xffff034effff034d, 0xffff0350ffff034f, 0xffff0352ffff0351,\n        0xffff0354ffff0353, 0xffff0356ffff0355, 0xffff0358ffff0357,\n        0xffff035affff0359, 0xffff035cffff035b, 0xffff035effff035d,\n        0xffff0360ffff035f, 0xffff0362ffff0361, 0xffff0364ffff0363,\n        0xffff0366ffff0365, 0xffff0368ffff0367, 0xffff036affff0369,\n        0xffff036cffff036b, 0xffff036effff036d, 0xffff0370ffff036f,\n        0xffff0372ffff0371, 0xffffffffffffffff, 0x373ffffffffffff,\n        0xffffffff0374ffff, 0xffff0375ffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff0377ffff0376,\n        0xffff0379ffff0378, 0xffff037bffff037a, 0xffff037dffff037c,\n        0xffff037fffff037e, 0xffff0381ffff0380, 0xffff0383ffff0382,\n        0xffff0385ffff0384, 0xffff0387ffff0386, 0xffff0389ffff0388,\n        0xffff038bffff038a, 0xffffffffffff038c, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff038effff038d, 0xffff0390ffff038f, 0xffff0392ffff0391,\n        0xffff0394ffff0393, 0xffff0396ffff0395, 0xffff0398ffff0397,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff0399ffffffff, 0xffff039bffff039a, 0xffff039dffff039c,\n        0xffff039fffff039e, 0xffff03a0ffffffff, 0xffff03a2ffff03a1,\n        0xffff03a4ffff03a3, 0xffff03a6ffff03a5, 0xffff03a8ffff03a7,\n        0xffff03aaffff03a9, 0xffff03acffff03ab, 0xffff03aeffff03ad,\n        0xffff03b0ffff03af, 0xffff03b2ffff03b1, 0xffff03b4ffff03b3,\n        0xffff03b6ffff03b5, 0xffff03b8ffff03b7, 0xffff03baffff03b9,\n        0xffff03bcffff03bb, 0xffff03beffff03bd, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3c0ffff03bfffff, 0xffff03c203c1ffff,\n        0xffff03c4ffff03c3, 0xffff03c6ffff03c5, 0x3c7ffffffffffff,\n        0xffffffff03c8ffff, 0xffff03caffff03c9, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff03ccffff03cb,\n        0xffff03ceffff03cd, 0xffff03d0ffff03cf, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x419041804170416, 0xffff041c041b041a,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x41effffffffffff,\n        0x42204210420041f, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3d303d203d1ffff, 0x3d703d603d503d4,\n        0x3db03da03d903d8, 0x3df03de03dd03dc, 0x3e303e203e103e0,\n        0x3e703e603e503e4, 0xffff03ea03e903e8, 0xffffffffffffffff,\n        0x3ee03ed03ec03eb, 0x3f203f103f003ef, 0x3f603f503f403f3,\n        0x3fa03f903f803f7, 0x3fe03fd03fc03fb, 0x4020401040003ff,\n        0x406040504040403, 0x40a040904080407, 0x40e040d040c040b,\n        0x41204110410040f, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff]);\n//8192 bytes\nenum toTitleIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x20, 0x100],\n        [0x100, 0x380, 0xc00], [0x402030202020100, 0x202020202020205,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x3000200010000, 0x7000600050004, 0xa00090008, 0xd000c000b0000,\n        0x110010000f000e, 0x1400130012, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x150000, 0x19001800170016, 0x1d001c001b001a, 0x0, 0x1f001e0000,\n        0x0, 0x0, 0x20000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x24002300220021, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x2700260000, 0x2a00290028, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x2c0000, 0x0, 0x0,\n        0x0, 0x0, 0x2e002d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x200010000ffff,\n        0x6000500040003, 0xa000900080007, 0xe000d000c000b, 0x1200110010000f,\n        0x16001500140013, 0xffff001900180017, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffff001affff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x41fffffffffffff,\n        0x1e001d001c001b, 0x2200210020001f, 0x26002500240023, 0x2a002900280027,\n        0x2e002d002c002b, 0xffff00310030002f, 0x35003400330032,\n        0x39003800370036, 0x3bffff003affff, 0x3dffff003cffff, 0x3fffff003effff,\n        0x41ffff0040ffff, 0x43ffff0042ffff, 0x45ffff0044ffff, 0x47ffff0046ffff,\n        0x49ffff0048ffff, 0x4bffff004affff, 0x4dffff004cffff, 0x4fffff004effff,\n        0x51ffff0050ffff, 0x53ffff00520421, 0x55ffff0054ffff,\n        0xffff0056ffffffff, 0xffff0058ffff0057, 0xffff005affff0059,\n        0xffff005cffff005b, 0x5effff043e005d, 0x60ffff005fffff,\n        0x62ffff0061ffff, 0x64ffff0063ffff, 0x66ffff0065ffff, 0x68ffff0067ffff,\n        0x6affff0069ffff, 0x6cffff006bffff, 0x6effff006dffff, 0x70ffff006fffff,\n        0x72ffff0071ffff, 0x74ffff0073ffff, 0xffff0075ffffffff,\n        0x780077ffff0076, 0x7affffffff0079, 0xffffffff007bffff,\n        0xffffffffffff007c, 0xffffffffffff007d, 0xffff007effffffff,\n        0xffffffff007fffff, 0xffff00810080ffff, 0xffff0082ffffffff,\n        0x84ffff0083ffff, 0xffffffff0085ffff, 0xffffffffffff0086,\n        0xffffffff0087ffff, 0xffffffffffff0088, 0xffff008affff0089,\n        0xffffffff008bffff, 0x8dffff008cffff, 0xffffffffffffffff,\n        0x910090008f008e, 0x95009400930092, 0xffff0097ffff0096,\n        0xffff0099ffff0098, 0xffff009bffff009a, 0xffff009dffff009c,\n        0xa0ffff009f009e, 0xa2ffff00a1ffff, 0xa4ffff00a3ffff, 0xa6ffff00a5ffff,\n        0xa8ffff00a7ffff, 0xab00aa00a90446, 0xffffffff00acffff,\n        0xaeffff00adffff, 0xb0ffff00afffff, 0xb2ffff00b1ffff, 0xb4ffff00b3ffff,\n        0xb6ffff00b5ffff, 0xb8ffff00b7ffff, 0xbaffff00b9ffff, 0xbcffff00bbffff,\n        0xbeffff00bdffff, 0xc0ffff00bfffff, 0xc1ffffffffffff, 0xc3ffff00c2ffff,\n        0xc5ffff00c4ffff, 0xc7ffff00c6ffff, 0xc9ffff00c8ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xcbffffffff00ca,\n        0xffff00cdffff00cc, 0xceffffffffffff, 0xd0ffff00cfffff,\n        0xd2ffff00d1ffff, 0xd600d500d400d3, 0xd900d8ffff00d7, 0xdbffff00daffff,\n        0xffffffffffffffff, 0xddffffffff00dc, 0xffff00df00deffff,\n        0xe2ffff00e100e0, 0xe3ffffffffffff, 0xffff00e500e4ffff,\n        0xffffffff00e6ffff, 0xffffffffffffffff, 0xffffffff00e7ffff,\n        0xe9ffffffff00e8, 0xffffffffffffffff, 0xed00ec00eb00ea,\n        0xffffffffffff00ee, 0xffff00efffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff00f0ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xf2ffff00f1ffff, 0xf3ffffffffffff,\n        0xf4ffffffffffff, 0xffffffff00f600f5, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffff0440, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xfa00f900f800f7, 0xfd00fc00fb0443,\n        0x101010000ff00fe, 0x105010401030102, 0x109010801070106,\n        0x10d010c010b010a, 0x1110110010f010e, 0x115011401130112,\n        0xffff011801170116, 0xffffffff011a0119, 0x11d011c011bffff,\n        0x11fffff011effff, 0x121ffff0120ffff, 0x123ffff0122ffff,\n        0x125ffff0124ffff, 0x127ffff0126ffff, 0x129ffff0128ffff,\n        0xffff012c012b012a, 0xffffffff012dffff, 0x12fffffffff012e,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x133013201310130, 0x137013601350134,\n        0x13b013a01390138, 0x13f013e013d013c, 0x143014201410140,\n        0x147014601450144, 0x14b014a01490148, 0x14f014e014d014c,\n        0x153015201510150, 0x157015601550154, 0x15b015a01590158,\n        0x15f015e015d015c, 0x161ffff0160ffff, 0x163ffff0162ffff,\n        0x165ffff0164ffff, 0x167ffff0166ffff, 0x169ffff0168ffff,\n        0x16bffff016affff, 0x16dffff016cffff, 0x16fffff016effff,\n        0xffffffff0170ffff, 0xffffffffffffffff, 0x171ffffffffffff,\n        0x173ffff0172ffff, 0x175ffff0174ffff, 0x177ffff0176ffff,\n        0x179ffff0178ffff, 0x17bffff017affff, 0x17dffff017cffff,\n        0x17fffff017effff, 0x181ffff0180ffff, 0x183ffff0182ffff,\n        0x185ffff0184ffff, 0x187ffff0186ffff, 0x189ffff0188ffff,\n        0x18bffff018affff, 0xffff018cffffffff, 0xffff018effff018d,\n        0xffff0190ffff018f, 0x1930192ffff0191, 0x195ffff0194ffff,\n        0x197ffff0196ffff, 0x199ffff0198ffff, 0x19bffff019affff,\n        0x19dffff019cffff, 0x19fffff019effff, 0x1a1ffff01a0ffff,\n        0x1a3ffff01a2ffff, 0x1a5ffff01a4ffff, 0x1a7ffff01a6ffff,\n        0x1a9ffff01a8ffff, 0x1abffff01aaffff, 0x1adffff01acffff,\n        0x1afffff01aeffff, 0x1b1ffff01b0ffff, 0x1b3ffff01b2ffff,\n        0x1b5ffff01b4ffff, 0x1b7ffff01b6ffff, 0x1b9ffff01b8ffff,\n        0x1bbffff01baffff, 0x1bdffff01bcffff, 0x1bfffff01beffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x1c201c101c0ffff,\n        0x1c601c501c401c3, 0x1ca01c901c801c7, 0x1ce01cd01cc01cb,\n        0x1d201d101d001cf, 0x1d601d501d401d3, 0x1da01d901d801d7,\n        0x1de01dd01dc01db, 0x1e201e101e001df, 0x43201e501e401e3,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffff01e6ffff, 0xffffffff01e7ffff,\n        0x1e9ffff01e8ffff, 0x1ebffff01eaffff, 0x1edffff01ecffff,\n        0x1efffff01eeffff, 0x1f1ffff01f0ffff, 0x1f3ffff01f2ffff,\n        0x1f5ffff01f4ffff, 0x1f7ffff01f6ffff, 0x1f9ffff01f8ffff,\n        0x1fbffff01faffff, 0x1fdffff01fcffff, 0x1ffffff01feffff,\n        0x201ffff0200ffff, 0x203ffff0202ffff, 0x205ffff0204ffff,\n        0x207ffff0206ffff, 0x209ffff0208ffff, 0x20bffff020affff,\n        0x20dffff020cffff, 0x20fffff020effff, 0x211ffff0210ffff,\n        0x213ffff0212ffff, 0x215ffff0214ffff, 0x217ffff0216ffff,\n        0x219ffff0218ffff, 0x21bffff021affff, 0x21dffff021cffff,\n        0x21fffff021effff, 0x221ffff0220ffff, 0x223ffff0222ffff,\n        0x225ffff0224ffff, 0x227ffff0226ffff, 0x229ffff0228ffff,\n        0x22bffff022affff, 0x22dffff022cffff, 0x22fffff022effff,\n        0x231ffff0230ffff, 0x44a04480232ffff, 0x2330450044e044c,\n        0xffffffffffffffff, 0x235ffff0234ffff, 0x237ffff0236ffff,\n        0x239ffff0238ffff, 0x23bffff023affff, 0x23dffff023cffff,\n        0x23fffff023effff, 0x241ffff0240ffff, 0x243ffff0242ffff,\n        0x245ffff0244ffff, 0x247ffff0246ffff, 0x249ffff0248ffff,\n        0x24bffff024affff, 0x24dffff024cffff, 0x24fffff024effff,\n        0x251ffff0250ffff, 0x253ffff0252ffff, 0x255ffff0254ffff,\n        0x257ffff0256ffff, 0x259ffff0258ffff, 0x25bffff025affff,\n        0x25dffff025cffff, 0x25fffff025effff, 0x261ffff0260ffff,\n        0x263ffff0262ffff, 0x267026602650264, 0x26b026a02690268,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x26f026e026d026c,\n        0xffffffff02710270, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x275027402730272, 0x279027802770276, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x27d027c027b027a, 0x2810280027f027e,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x285028402830282,\n        0xffffffff02870286, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x289045402880452, 0x28b045a028a0457, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x28f028e028d028c, 0x293029202910290,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x297029602950294,\n        0x29b029a02990298, 0x29f029e029d029c, 0xffffffff02a102a0,\n        0x47e047d047c047b, 0x48204810480047f, 0x486048504840483,\n        0x48a048904880487, 0x48e048d048c048b, 0x49204910490048f,\n        0x496049504940493, 0x49a049904980497, 0x49e049d049c049b,\n        0x4a204a104a0049f, 0x4a604a504a404a3, 0x4aa04a904a804a7,\n        0x4ab04b102bb02ba, 0x4bd045dffff04b3, 0xffffffffffffffff,\n        0xffff02bdffff04ac, 0x4ad04b5ffffffff, 0x4c0045fffff04b7,\n        0xffffffffffffffff, 0xffffffffffff04ae, 0x464046102c002bf,\n        0x4690467ffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x46f046c02c202c1, 0x476047402c30472, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x4af04b9ffffffff, 0x4c30479ffff04bb,\n        0xffffffffffffffff, 0xffffffffffff04b0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff02c5ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2c902c802c702c6,\n        0x2cd02cc02cb02ca, 0x2d102d002cf02ce, 0x2d502d402d302d2,\n        0xffffffffffffffff, 0xffffffffffff02d6, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2da02d902d802d7,\n        0x2de02dd02dc02db, 0x2e202e102e002df, 0x2e602e502e402e3,\n        0x2ea02e902e802e7, 0x2ee02ed02ec02eb, 0xffffffff02f002ef,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2f402f302f202f1,\n        0x2f802f702f602f5, 0x2fc02fb02fa02f9, 0x30002ff02fe02fd,\n        0x304030303020301, 0x308030703060305, 0x30c030b030a0309,\n        0x310030f030e030d, 0x314031303120311, 0x318031703160315,\n        0x31c031b031a0319, 0xffff031f031e031d, 0xffffffff0320ffff,\n        0xffff03220321ffff, 0xffff0324ffff0323, 0xffffffffffff0325,\n        0x326ffffffffffff, 0xffff0327ffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x329ffff0328ffff, 0x32bffff032affff,\n        0x32dffff032cffff, 0x32fffff032effff, 0x331ffff0330ffff,\n        0x333ffff0332ffff, 0x335ffff0334ffff, 0x337ffff0336ffff,\n        0x339ffff0338ffff, 0x33bffff033affff, 0x33dffff033cffff,\n        0x33fffff033effff, 0x341ffff0340ffff, 0x343ffff0342ffff,\n        0x345ffff0344ffff, 0x347ffff0346ffff, 0x349ffff0348ffff,\n        0x34bffff034affff, 0x34dffff034cffff, 0x34fffff034effff,\n        0x351ffff0350ffff, 0x353ffff0352ffff, 0x355ffff0354ffff,\n        0x357ffff0356ffff, 0x359ffff0358ffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff035bffff035a, 0x35cffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x360035f035e035d, 0x364036303620361, 0x368036703660365,\n        0x36c036b036a0369, 0x370036f036e036d, 0x374037303720371,\n        0x378037703760375, 0x37c037b037a0379, 0x380037f037e037d,\n        0x383ffff03820381, 0xffffffffffffffff, 0xffffffff0384ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x386ffff0385ffff, 0x388ffff0387ffff,\n        0x38affff0389ffff, 0x38cffff038bffff, 0x38effff038dffff,\n        0x390ffff038fffff, 0x392ffff0391ffff, 0x394ffff0393ffff,\n        0x396ffff0395ffff, 0x398ffff0397ffff, 0x39affff0399ffff,\n        0xffffffff039bffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x39dffff039cffff,\n        0x39fffff039effff, 0x3a1ffff03a0ffff, 0x3a3ffff03a2ffff,\n        0x3a5ffff03a4ffff, 0x3a7ffff03a6ffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x3a8ffffffffffff,\n        0x3aaffff03a9ffff, 0x3acffff03abffff, 0x3aeffff03adffff,\n        0x3afffffffffffff, 0x3b1ffff03b0ffff, 0x3b3ffff03b2ffff,\n        0x3b5ffff03b4ffff, 0x3b7ffff03b6ffff, 0x3b9ffff03b8ffff,\n        0x3bbffff03baffff, 0x3bdffff03bcffff, 0x3bfffff03beffff,\n        0x3c1ffff03c0ffff, 0x3c3ffff03c2ffff, 0x3c5ffff03c4ffff,\n        0x3c7ffff03c6ffff, 0x3c9ffff03c8ffff, 0x3cbffff03caffff,\n        0x3cdffff03ccffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff03ceffffffff, 0x3d0ffffffff03cf, 0x3d2ffff03d1ffff,\n        0x3d4ffff03d3ffff, 0xffffffffffffffff, 0xffffffffffff03d5,\n        0x3d7ffff03d6ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3d9ffff03d8ffff, 0x3dbffff03daffff,\n        0xffffffff03dcffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x428042604240422, 0xffff0430042e042b, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x434ffffffffffff, 0x43c043a04380436,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3df03de03ddffff, 0x3e303e203e103e0,\n        0x3e703e603e503e4, 0x3eb03ea03e903e8, 0x3ef03ee03ed03ec,\n        0x3f303f203f103f0, 0xffff03f603f503f4, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x3fa03f903f803f7, 0x3fe03fd03fc03fb, 0x4020401040003ff,\n        0x406040504040403, 0x40a040904080407, 0x40e040d040c040b,\n        0x41204110410040f, 0x416041504140413, 0x41a041904180417,\n        0x41e041d041c041b, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff]);\n//8064 bytes\nenum toUpperSimpleIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x20,\n        0x100], [0x100, 0x380, 0xbc0], [0x402030202020100, 0x202020202020205,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x3000200010000, 0x7000600050004, 0xa00090008, 0xd000c000b0000,\n        0x110010000f000e, 0x1400130012, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x150000, 0x19001800170016, 0x1d001c001b001a, 0x0, 0x1f001e0000,\n        0x0, 0x0, 0x20000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x24002300220021, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x2700260000, 0x2a00290028, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b0000, 0x0, 0x0,\n        0x0, 0x0, 0x2d002c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x200010000ffff,\n        0x6000500040003, 0xa000900080007, 0xe000d000c000b, 0x1200110010000f,\n        0x16001500140013, 0xffff001900180017, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffff001affff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x1e001d001c001b, 0x2200210020001f, 0x26002500240023, 0x2a002900280027,\n        0x2e002d002c002b, 0xffff00310030002f, 0x35003400330032,\n        0x39003800370036, 0x3bffff003affff, 0x3dffff003cffff, 0x3fffff003effff,\n        0x41ffff0040ffff, 0x43ffff0042ffff, 0x45ffff0044ffff, 0x47ffff0046ffff,\n        0x49ffff0048ffff, 0x4bffff004affff, 0x4dffff004cffff, 0x4fffff004effff,\n        0x51ffff0050ffff, 0x53ffff0052ffff, 0x55ffff0054ffff,\n        0xffff0056ffffffff, 0xffff0058ffff0057, 0xffff005affff0059,\n        0xffff005cffff005b, 0x5effffffff005d, 0x60ffff005fffff,\n        0x62ffff0061ffff, 0x64ffff0063ffff, 0x66ffff0065ffff, 0x68ffff0067ffff,\n        0x6affff0069ffff, 0x6cffff006bffff, 0x6effff006dffff, 0x70ffff006fffff,\n        0x72ffff0071ffff, 0x74ffff0073ffff, 0xffff0075ffffffff,\n        0x780077ffff0076, 0x7affffffff0079, 0xffffffff007bffff,\n        0xffffffffffff007c, 0xffffffffffff007d, 0xffff007effffffff,\n        0xffffffff007fffff, 0xffff00810080ffff, 0xffff0082ffffffff,\n        0x84ffff0083ffff, 0xffffffff0085ffff, 0xffffffffffff0086,\n        0xffffffff0087ffff, 0xffffffffffff0088, 0xffff008affff0089,\n        0xffffffff008bffff, 0x8dffff008cffff, 0xffffffffffffffff,\n        0xffff008f008effff, 0x92ffff00910090, 0xffff0094ffff0093,\n        0xffff0096ffff0095, 0xffff0098ffff0097, 0xffff009affff0099,\n        0x9dffff009c009b, 0x9fffff009effff, 0xa1ffff00a0ffff, 0xa3ffff00a2ffff,\n        0xa5ffff00a4ffff, 0xa700a6ffffffff, 0xffffffff00a8ffff,\n        0xaaffff00a9ffff, 0xacffff00abffff, 0xaeffff00adffff, 0xb0ffff00afffff,\n        0xb2ffff00b1ffff, 0xb4ffff00b3ffff, 0xb6ffff00b5ffff, 0xb8ffff00b7ffff,\n        0xbaffff00b9ffff, 0xbcffff00bbffff, 0xbdffffffffffff, 0xbfffff00beffff,\n        0xc1ffff00c0ffff, 0xc3ffff00c2ffff, 0xc5ffff00c4ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xc7ffffffff00c6,\n        0xffff00c9ffff00c8, 0xcaffffffffffff, 0xccffff00cbffff,\n        0xceffff00cdffff, 0xd200d100d000cf, 0xd500d4ffff00d3, 0xd7ffff00d6ffff,\n        0xffffffffffffffff, 0xd9ffffffff00d8, 0xffff00db00daffff,\n        0xdeffff00dd00dc, 0xdfffffffffffff, 0xffff00e100e0ffff,\n        0xffffffff00e2ffff, 0xffffffffffffffff, 0xffffffff00e3ffff,\n        0xe5ffffffff00e4, 0xffffffffffffffff, 0xe900e800e700e6,\n        0xffffffffffff00ea, 0xffff00ebffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff00ecffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xeeffff00edffff, 0xefffffffffffff,\n        0xf0ffffffffffff, 0xffffffff00f200f1, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xf600f500f400f3, 0xf900f800f7ffff,\n        0xfd00fc00fb00fa, 0x101010000ff00fe, 0x105010401030102,\n        0x109010801070106, 0x10d010c010b010a, 0x1110110010f010e,\n        0xffff011401130112, 0xffffffff01160115, 0x11901180117ffff,\n        0x11bffff011affff, 0x11dffff011cffff, 0x11fffff011effff,\n        0x121ffff0120ffff, 0x123ffff0122ffff, 0x125ffff0124ffff,\n        0xffff012801270126, 0xffffffff0129ffff, 0x12bffffffff012a,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x12f012e012d012c, 0x133013201310130,\n        0x137013601350134, 0x13b013a01390138, 0x13f013e013d013c,\n        0x143014201410140, 0x147014601450144, 0x14b014a01490148,\n        0x14f014e014d014c, 0x153015201510150, 0x157015601550154,\n        0x15b015a01590158, 0x15dffff015cffff, 0x15fffff015effff,\n        0x161ffff0160ffff, 0x163ffff0162ffff, 0x165ffff0164ffff,\n        0x167ffff0166ffff, 0x169ffff0168ffff, 0x16bffff016affff,\n        0xffffffff016cffff, 0xffffffffffffffff, 0x16dffffffffffff,\n        0x16fffff016effff, 0x171ffff0170ffff, 0x173ffff0172ffff,\n        0x175ffff0174ffff, 0x177ffff0176ffff, 0x179ffff0178ffff,\n        0x17bffff017affff, 0x17dffff017cffff, 0x17fffff017effff,\n        0x181ffff0180ffff, 0x183ffff0182ffff, 0x185ffff0184ffff,\n        0x187ffff0186ffff, 0xffff0188ffffffff, 0xffff018affff0189,\n        0xffff018cffff018b, 0x18f018effff018d, 0x191ffff0190ffff,\n        0x193ffff0192ffff, 0x195ffff0194ffff, 0x197ffff0196ffff,\n        0x199ffff0198ffff, 0x19bffff019affff, 0x19dffff019cffff,\n        0x19fffff019effff, 0x1a1ffff01a0ffff, 0x1a3ffff01a2ffff,\n        0x1a5ffff01a4ffff, 0x1a7ffff01a6ffff, 0x1a9ffff01a8ffff,\n        0x1abffff01aaffff, 0x1adffff01acffff, 0x1afffff01aeffff,\n        0x1b1ffff01b0ffff, 0x1b3ffff01b2ffff, 0x1b5ffff01b4ffff,\n        0x1b7ffff01b6ffff, 0x1b9ffff01b8ffff, 0x1bbffff01baffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x1be01bd01bcffff,\n        0x1c201c101c001bf, 0x1c601c501c401c3, 0x1ca01c901c801c7,\n        0x1ce01cd01cc01cb, 0x1d201d101d001cf, 0x1d601d501d401d3,\n        0x1da01d901d801d7, 0x1de01dd01dc01db, 0xffff01e101e001df,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffff01e2ffff, 0xffffffff01e3ffff,\n        0x1e5ffff01e4ffff, 0x1e7ffff01e6ffff, 0x1e9ffff01e8ffff,\n        0x1ebffff01eaffff, 0x1edffff01ecffff, 0x1efffff01eeffff,\n        0x1f1ffff01f0ffff, 0x1f3ffff01f2ffff, 0x1f5ffff01f4ffff,\n        0x1f7ffff01f6ffff, 0x1f9ffff01f8ffff, 0x1fbffff01faffff,\n        0x1fdffff01fcffff, 0x1ffffff01feffff, 0x201ffff0200ffff,\n        0x203ffff0202ffff, 0x205ffff0204ffff, 0x207ffff0206ffff,\n        0x209ffff0208ffff, 0x20bffff020affff, 0x20dffff020cffff,\n        0x20fffff020effff, 0x211ffff0210ffff, 0x213ffff0212ffff,\n        0x215ffff0214ffff, 0x217ffff0216ffff, 0x219ffff0218ffff,\n        0x21bffff021affff, 0x21dffff021cffff, 0x21fffff021effff,\n        0x221ffff0220ffff, 0x223ffff0222ffff, 0x225ffff0224ffff,\n        0x227ffff0226ffff, 0x229ffff0228ffff, 0x22bffff022affff,\n        0x22dffff022cffff, 0xffffffff022effff, 0x22fffffffffffff,\n        0xffffffffffffffff, 0x231ffff0230ffff, 0x233ffff0232ffff,\n        0x235ffff0234ffff, 0x237ffff0236ffff, 0x239ffff0238ffff,\n        0x23bffff023affff, 0x23dffff023cffff, 0x23fffff023effff,\n        0x241ffff0240ffff, 0x243ffff0242ffff, 0x245ffff0244ffff,\n        0x247ffff0246ffff, 0x249ffff0248ffff, 0x24bffff024affff,\n        0x24dffff024cffff, 0x24fffff024effff, 0x251ffff0250ffff,\n        0x253ffff0252ffff, 0x255ffff0254ffff, 0x257ffff0256ffff,\n        0x259ffff0258ffff, 0x25bffff025affff, 0x25dffff025cffff,\n        0x25fffff025effff, 0x263026202610260, 0x267026602650264,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x26b026a02690268,\n        0xffffffff026d026c, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x2710270026f026e, 0x275027402730272, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x279027802770276, 0x27d027c027b027a,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2810280027f027e,\n        0xffffffff02830282, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x285ffff0284ffff, 0x287ffff0286ffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x28b028a02890288, 0x28f028e028d028c,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x293029202910290,\n        0x297029602950294, 0x29b029a02990298, 0xffffffff029d029c,\n        0x2a102a0029f029e, 0x2a502a402a302a2, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x2a902a802a702a6, 0x2ad02ac02ab02aa,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2b102b002af02ae,\n        0x2b502b402b302b2, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x2b8ffff02b702b6, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff02b9ffffffff, 0x2baffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff02bc02bb,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffff02be02bd, 0xffffffff02bfffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x2c0ffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff02c1ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2c502c402c302c2,\n        0x2c902c802c702c6, 0x2cd02cc02cb02ca, 0x2d102d002cf02ce,\n        0xffffffffffffffff, 0xffffffffffff02d2, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2d602d502d402d3,\n        0x2da02d902d802d7, 0x2de02dd02dc02db, 0x2e202e102e002df,\n        0x2e602e502e402e3, 0x2ea02e902e802e7, 0xffffffff02ec02eb,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2f002ef02ee02ed,\n        0x2f402f302f202f1, 0x2f802f702f602f5, 0x2fc02fb02fa02f9,\n        0x30002ff02fe02fd, 0x304030303020301, 0x308030703060305,\n        0x30c030b030a0309, 0x310030f030e030d, 0x314031303120311,\n        0x318031703160315, 0xffff031b031a0319, 0xffffffff031cffff,\n        0xffff031e031dffff, 0xffff0320ffff031f, 0xffffffffffff0321,\n        0x322ffffffffffff, 0xffff0323ffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x325ffff0324ffff, 0x327ffff0326ffff,\n        0x329ffff0328ffff, 0x32bffff032affff, 0x32dffff032cffff,\n        0x32fffff032effff, 0x331ffff0330ffff, 0x333ffff0332ffff,\n        0x335ffff0334ffff, 0x337ffff0336ffff, 0x339ffff0338ffff,\n        0x33bffff033affff, 0x33dffff033cffff, 0x33fffff033effff,\n        0x341ffff0340ffff, 0x343ffff0342ffff, 0x345ffff0344ffff,\n        0x347ffff0346ffff, 0x349ffff0348ffff, 0x34bffff034affff,\n        0x34dffff034cffff, 0x34fffff034effff, 0x351ffff0350ffff,\n        0x353ffff0352ffff, 0x355ffff0354ffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff0357ffff0356, 0x358ffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x35c035b035a0359, 0x360035f035e035d, 0x364036303620361,\n        0x368036703660365, 0x36c036b036a0369, 0x370036f036e036d,\n        0x374037303720371, 0x378037703760375, 0x37c037b037a0379,\n        0x37fffff037e037d, 0xffffffffffffffff, 0xffffffff0380ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x382ffff0381ffff, 0x384ffff0383ffff,\n        0x386ffff0385ffff, 0x388ffff0387ffff, 0x38affff0389ffff,\n        0x38cffff038bffff, 0x38effff038dffff, 0x390ffff038fffff,\n        0x392ffff0391ffff, 0x394ffff0393ffff, 0x396ffff0395ffff,\n        0xffffffff0397ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x399ffff0398ffff,\n        0x39bffff039affff, 0x39dffff039cffff, 0x39fffff039effff,\n        0x3a1ffff03a0ffff, 0x3a3ffff03a2ffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x3a4ffffffffffff,\n        0x3a6ffff03a5ffff, 0x3a8ffff03a7ffff, 0x3aaffff03a9ffff,\n        0x3abffffffffffff, 0x3adffff03acffff, 0x3afffff03aeffff,\n        0x3b1ffff03b0ffff, 0x3b3ffff03b2ffff, 0x3b5ffff03b4ffff,\n        0x3b7ffff03b6ffff, 0x3b9ffff03b8ffff, 0x3bbffff03baffff,\n        0x3bdffff03bcffff, 0x3bfffff03beffff, 0x3c1ffff03c0ffff,\n        0x3c3ffff03c2ffff, 0x3c5ffff03c4ffff, 0x3c7ffff03c6ffff,\n        0x3c9ffff03c8ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff03caffffffff, 0x3ccffffffff03cb, 0x3ceffff03cdffff,\n        0x3d0ffff03cfffff, 0xffffffffffffffff, 0xffffffffffff03d1,\n        0x3d3ffff03d2ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3d5ffff03d4ffff, 0x3d7ffff03d6ffff,\n        0xffffffff03d8ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x3db03da03d9ffff, 0x3df03de03dd03dc, 0x3e303e203e103e0,\n        0x3e703e603e503e4, 0x3eb03ea03e903e8, 0x3ef03ee03ed03ec,\n        0xffff03f203f103f0, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x3f603f503f403f3,\n        0x3fa03f903f803f7, 0x3fe03fd03fc03fb, 0x4020401040003ff,\n        0x406040504040403, 0x40a040904080407, 0x40e040d040c040b,\n        0x41204110410040f, 0x416041504140413, 0x41a041904180417,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff]);\n//7808 bytes\nenum toLowerSimpleIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x20,\n        0x100], [0x100, 0x380, 0xb40], [0x402030202020100, 0x202020202020205,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x2000000010000, 0x6000500040003, 0x80007, 0xb000a00090000,\n        0xf000e000d000c, 0x110010, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x13001200000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x17001600150014, 0x1b001a00190018, 0x0,\n        0x1e001d001c, 0x0, 0x0, 0x20001f00000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x24002300220021, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2600250000, 0x2900280027, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x0,\n        0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x200010000ffff, 0x6000500040003, 0xa000900080007, 0xe000d000c000b,\n        0x1200110010000f, 0x16001500140013, 0xffff001900180017,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x1d001c001b001a, 0x210020001f001e, 0x25002400230022, 0x29002800270026,\n        0x2d002c002b002a, 0xffff0030002f002e, 0x34003300320031,\n        0xffff003700360035, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff0039ffff0038, 0xffff003bffff003a, 0xffff003dffff003c,\n        0xffff003fffff003e, 0xffff0041ffff0040, 0xffff0043ffff0042,\n        0xffff0045ffff0044, 0xffff0047ffff0046, 0xffff0049ffff0048,\n        0xffff004bffff004a, 0xffff004dffff004c, 0xffff004fffff004e,\n        0xffff0051ffff0050, 0xffff0053ffff0052, 0x55ffff0054ffff,\n        0x57ffff0056ffff, 0x59ffff0058ffff, 0x5bffff005affff,\n        0xffff005cffffffff, 0xffff005effff005d, 0xffff0060ffff005f,\n        0xffff0062ffff0061, 0xffff0064ffff0063, 0xffff0066ffff0065,\n        0xffff0068ffff0067, 0xffff006affff0069, 0xffff006cffff006b,\n        0xffff006effff006d, 0xffff0070ffff006f, 0xffff0072ffff0071,\n        0x75ffff00740073, 0xffffffff0076ffff, 0xffff00780077ffff,\n        0x7b007affff0079, 0x7e007d007cffff, 0x80007fffffffff, 0x83ffff00820081,\n        0x860085ffff0084, 0xffffffffffff0087, 0x8affff00890088,\n        0xffff008cffff008b, 0x8f008effff008d, 0xffffffff0090ffff,\n        0x930092ffff0091, 0x9600950094ffff, 0x98ffff0097ffff,\n        0xffffffffffff0099, 0xffffffffffff009a, 0xffffffffffffffff,\n        0x9dffff009c009b, 0xa0009fffff009e, 0xa2ffff00a1ffff, 0xa4ffff00a3ffff,\n        0xa6ffff00a5ffff, 0xa8ffff00a7ffff, 0xffff00a9ffffffff,\n        0xffff00abffff00aa, 0xffff00adffff00ac, 0xffff00afffff00ae,\n        0xffff00b1ffff00b0, 0xffff00b300b2ffff, 0xb600b5ffff00b4,\n        0xffff00b8ffff00b7, 0xffff00baffff00b9, 0xffff00bcffff00bb,\n        0xffff00beffff00bd, 0xffff00c0ffff00bf, 0xffff00c2ffff00c1,\n        0xffff00c4ffff00c3, 0xffff00c6ffff00c5, 0xffff00c8ffff00c7,\n        0xffff00caffff00c9, 0xffff00ccffff00cb, 0xffff00ceffff00cd,\n        0xffff00d0ffff00cf, 0xffff00d2ffff00d1, 0xffff00d4ffff00d3,\n        0xffffffffffffffff, 0xd600d5ffffffff, 0xffff00d800d7ffff,\n        0xdaffff00d9ffff, 0xffff00dd00dc00db, 0xffff00dfffff00de,\n        0xffff00e1ffff00e0, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff00e3ffff00e2, 0xffff00e4ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff00e5ffffffff, 0xffff00e800e700e6, 0xeb00eaffff00e9,\n        0xee00ed00ecffff, 0xf200f100f000ef, 0xf600f500f400f3, 0xfa00f900f800f7,\n        0xfdffff00fc00fb, 0x101010000ff00fe, 0x105010401030102,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x106ffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff0108ffff0107,\n        0xffff010affff0109, 0xffff010cffff010b, 0xffff010effff010d,\n        0xffff0110ffff010f, 0xffff0112ffff0111, 0xffffffffffffffff,\n        0x114ffffffff0113, 0xffff01160115ffff, 0x11901180117ffff,\n        0x11d011c011b011a, 0x1210120011f011e, 0x125012401230122,\n        0x129012801270126, 0x12d012c012b012a, 0x1310130012f012e,\n        0x135013401330132, 0x139013801370136, 0x13d013c013b013a,\n        0x1410140013f013e, 0x145014401430142, 0x149014801470146,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff014bffff014a, 0xffff014dffff014c, 0xffff014fffff014e,\n        0xffff0151ffff0150, 0xffff0153ffff0152, 0xffff0155ffff0154,\n        0xffff0157ffff0156, 0xffff0159ffff0158, 0xffffffffffff015a,\n        0xffffffffffffffff, 0xffff015bffffffff, 0xffff015dffff015c,\n        0xffff015fffff015e, 0xffff0161ffff0160, 0xffff0163ffff0162,\n        0xffff0165ffff0164, 0xffff0167ffff0166, 0xffff0169ffff0168,\n        0xffff016bffff016a, 0xffff016dffff016c, 0xffff016fffff016e,\n        0xffff0171ffff0170, 0xffff0173ffff0172, 0xffff0175ffff0174,\n        0x178ffff01770176, 0x17affff0179ffff, 0x17cffff017bffff,\n        0xffffffff017dffff, 0xffff017fffff017e, 0xffff0181ffff0180,\n        0xffff0183ffff0182, 0xffff0185ffff0184, 0xffff0187ffff0186,\n        0xffff0189ffff0188, 0xffff018bffff018a, 0xffff018dffff018c,\n        0xffff018fffff018e, 0xffff0191ffff0190, 0xffff0193ffff0192,\n        0xffff0195ffff0194, 0xffff0197ffff0196, 0xffff0199ffff0198,\n        0xffff019bffff019a, 0xffff019dffff019c, 0xffff019fffff019e,\n        0xffff01a1ffff01a0, 0xffff01a3ffff01a2, 0xffff01a5ffff01a4,\n        0xffff01a7ffff01a6, 0xffff01a9ffff01a8, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x1ac01ab01aaffff, 0x1b001af01ae01ad,\n        0x1b401b301b201b1, 0x1b801b701b601b5, 0x1bc01bb01ba01b9,\n        0x1c001bf01be01bd, 0x1c401c301c201c1, 0x1c801c701c601c5,\n        0x1cc01cb01ca01c9, 0xffff01cf01ce01cd, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x1d301d201d101d0,\n        0x1d701d601d501d4, 0x1db01da01d901d8, 0x1df01de01dd01dc,\n        0x1e301e201e101e0, 0x1e701e601e501e4, 0x1eb01ea01e901e8,\n        0x1ef01ee01ed01ec, 0x1f301f201f101f0, 0x1f6ffff01f501f4,\n        0xffffffffffffffff, 0xffffffff01f7ffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff01f9ffff01f8,\n        0xffff01fbffff01fa, 0xffff01fdffff01fc, 0xffff01ffffff01fe,\n        0xffff0201ffff0200, 0xffff0203ffff0202, 0xffff0205ffff0204,\n        0xffff0207ffff0206, 0xffff0209ffff0208, 0xffff020bffff020a,\n        0xffff020dffff020c, 0xffff020fffff020e, 0xffff0211ffff0210,\n        0xffff0213ffff0212, 0xffff0215ffff0214, 0xffff0217ffff0216,\n        0xffff0219ffff0218, 0xffff021bffff021a, 0xffff021dffff021c,\n        0xffff021fffff021e, 0xffff0221ffff0220, 0xffff0223ffff0222,\n        0xffff0225ffff0224, 0xffff0227ffff0226, 0xffff0229ffff0228,\n        0xffff022bffff022a, 0xffff022dffff022c, 0xffff022fffff022e,\n        0xffff0231ffff0230, 0xffff0233ffff0232, 0xffff0235ffff0234,\n        0xffff0237ffff0236, 0xffff0239ffff0238, 0xffff023bffff023a,\n        0xffff023dffff023c, 0xffff023fffff023e, 0xffff0241ffff0240,\n        0xffffffffffff0242, 0xffffffffffffffff, 0xffff0243ffffffff,\n        0xffff0245ffff0244, 0xffff0247ffff0246, 0xffff0249ffff0248,\n        0xffff024bffff024a, 0xffff024dffff024c, 0xffff024fffff024e,\n        0xffff0251ffff0250, 0xffff0253ffff0252, 0xffff0255ffff0254,\n        0xffff0257ffff0256, 0xffff0259ffff0258, 0xffff025bffff025a,\n        0xffff025dffff025c, 0xffff025fffff025e, 0xffff0261ffff0260,\n        0xffff0263ffff0262, 0xffff0265ffff0264, 0xffff0267ffff0266,\n        0xffff0269ffff0268, 0xffff026bffff026a, 0xffff026dffff026c,\n        0xffff026fffff026e, 0xffff0271ffff0270, 0xffff0273ffff0272,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x277027602750274,\n        0x27b027a02790278, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x27f027e027d027c, 0xffffffff02810280, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x285028402830282, 0x289028802870286,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x28d028c028b028a,\n        0x2910290028f028e, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x295029402930292, 0xffffffff02970296, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x299ffff0298ffff, 0x29bffff029affff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x29f029e029d029c,\n        0x2a302a202a102a0, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x2a702a602a502a4, 0x2ab02aa02a902a8,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2af02ae02ad02ac,\n        0x2b302b202b102b0, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x2b702b602b502b4, 0x2bb02ba02b902b8, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x2bf02be02bd02bc, 0xffffffffffff02c0,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2c402c302c202c1,\n        0xffffffffffff02c5, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x2c902c802c702c6, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x2cd02cc02cb02ca, 0xffffffffffff02ce,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2d202d102d002cf,\n        0xffffffffffff02d3, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff02d4ffffffff, 0x2d602d5ffffffff,\n        0xffffffffffffffff, 0xffff02d7ffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x2db02da02d902d8, 0x2df02de02dd02dc,\n        0x2e302e202e102e0, 0x2e702e602e502e4, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x2e8ffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2ea02e9ffffffff,\n        0x2ee02ed02ec02eb, 0x2f202f102f002ef, 0x2f602f502f402f3,\n        0x2fa02f902f802f7, 0x2fe02fd02fc02fb, 0x3020301030002ff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x306030503040303, 0x30a030903080307, 0x30e030d030c030b,\n        0x31203110310030f, 0x316031503140313, 0x31a031903180317,\n        0x31e031d031c031b, 0x32203210320031f, 0x326032503240323,\n        0x32a032903280327, 0x32e032d032c032b, 0xffff03310330032f,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x3340333ffff0332, 0x336ffffffff0335, 0x338ffff0337ffff,\n        0x33b033a0339ffff, 0xffff033dffff033c, 0xffffffff033effff,\n        0xffffffffffffffff, 0x340033fffffffff, 0xffff0342ffff0341,\n        0xffff0344ffff0343, 0xffff0346ffff0345, 0xffff0348ffff0347,\n        0xffff034affff0349, 0xffff034cffff034b, 0xffff034effff034d,\n        0xffff0350ffff034f, 0xffff0352ffff0351, 0xffff0354ffff0353,\n        0xffff0356ffff0355, 0xffff0358ffff0357, 0xffff035affff0359,\n        0xffff035cffff035b, 0xffff035effff035d, 0xffff0360ffff035f,\n        0xffff0362ffff0361, 0xffff0364ffff0363, 0xffff0366ffff0365,\n        0xffff0368ffff0367, 0xffff036affff0369, 0xffff036cffff036b,\n        0xffff036effff036d, 0xffff0370ffff036f, 0xffff0372ffff0371,\n        0xffffffffffffffff, 0x373ffffffffffff, 0xffffffff0374ffff,\n        0xffff0375ffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff0377ffff0376, 0xffff0379ffff0378,\n        0xffff037bffff037a, 0xffff037dffff037c, 0xffff037fffff037e,\n        0xffff0381ffff0380, 0xffff0383ffff0382, 0xffff0385ffff0384,\n        0xffff0387ffff0386, 0xffff0389ffff0388, 0xffff038bffff038a,\n        0xffffffffffff038c, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff038effff038d,\n        0xffff0390ffff038f, 0xffff0392ffff0391, 0xffff0394ffff0393,\n        0xffff0396ffff0395, 0xffff0398ffff0397, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff0399ffffffff,\n        0xffff039bffff039a, 0xffff039dffff039c, 0xffff039fffff039e,\n        0xffff03a0ffffffff, 0xffff03a2ffff03a1, 0xffff03a4ffff03a3,\n        0xffff03a6ffff03a5, 0xffff03a8ffff03a7, 0xffff03aaffff03a9,\n        0xffff03acffff03ab, 0xffff03aeffff03ad, 0xffff03b0ffff03af,\n        0xffff03b2ffff03b1, 0xffff03b4ffff03b3, 0xffff03b6ffff03b5,\n        0xffff03b8ffff03b7, 0xffff03baffff03b9, 0xffff03bcffff03bb,\n        0xffff03beffff03bd, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x3c0ffff03bfffff, 0xffff03c203c1ffff, 0xffff03c4ffff03c3,\n        0xffff03c6ffff03c5, 0x3c7ffffffffffff, 0xffffffff03c8ffff,\n        0xffff03caffff03c9, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff03ccffff03cb, 0xffff03ceffff03cd,\n        0xffff03d0ffff03cf, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x3d303d203d1ffff,\n        0x3d703d603d503d4, 0x3db03da03d903d8, 0x3df03de03dd03dc,\n        0x3e303e203e103e0, 0x3e703e603e503e4, 0xffff03ea03e903e8,\n        0xffffffffffffffff, 0x3ee03ed03ec03eb, 0x3f203f103f003ef,\n        0x3f603f503f403f3, 0x3fa03f903f803f7, 0x3fe03fd03fc03fb,\n        0x4020401040003ff, 0x406040504040403, 0x40a040904080407,\n        0x40e040d040c040b, 0x41204110410040f, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff]);\n//8064 bytes\nenum toTitleSimpleIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x20,\n        0x100], [0x100, 0x380, 0xbc0], [0x402030202020100, 0x202020202020205,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x202020202020202, 0x202020202020202, 0x202020202020202,\n        0x3000200010000, 0x7000600050004, 0xa00090008, 0xd000c000b0000,\n        0x110010000f000e, 0x1400130012, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x150000, 0x19001800170016, 0x1d001c001b001a, 0x0, 0x1f001e0000,\n        0x0, 0x0, 0x20000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x24002300220021, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x2700260000, 0x2a00290028, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b0000, 0x0, 0x0,\n        0x0, 0x0, 0x2d002c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x200010000ffff,\n        0x6000500040003, 0xa000900080007, 0xe000d000c000b, 0x1200110010000f,\n        0x16001500140013, 0xffff001900180017, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffff001affff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x1e001d001c001b, 0x2200210020001f, 0x26002500240023, 0x2a002900280027,\n        0x2e002d002c002b, 0xffff00310030002f, 0x35003400330032,\n        0x39003800370036, 0x3bffff003affff, 0x3dffff003cffff, 0x3fffff003effff,\n        0x41ffff0040ffff, 0x43ffff0042ffff, 0x45ffff0044ffff, 0x47ffff0046ffff,\n        0x49ffff0048ffff, 0x4bffff004affff, 0x4dffff004cffff, 0x4fffff004effff,\n        0x51ffff0050ffff, 0x53ffff0052ffff, 0x55ffff0054ffff,\n        0xffff0056ffffffff, 0xffff0058ffff0057, 0xffff005affff0059,\n        0xffff005cffff005b, 0x5effffffff005d, 0x60ffff005fffff,\n        0x62ffff0061ffff, 0x64ffff0063ffff, 0x66ffff0065ffff, 0x68ffff0067ffff,\n        0x6affff0069ffff, 0x6cffff006bffff, 0x6effff006dffff, 0x70ffff006fffff,\n        0x72ffff0071ffff, 0x74ffff0073ffff, 0xffff0075ffffffff,\n        0x780077ffff0076, 0x7affffffff0079, 0xffffffff007bffff,\n        0xffffffffffff007c, 0xffffffffffff007d, 0xffff007effffffff,\n        0xffffffff007fffff, 0xffff00810080ffff, 0xffff0082ffffffff,\n        0x84ffff0083ffff, 0xffffffff0085ffff, 0xffffffffffff0086,\n        0xffffffff0087ffff, 0xffffffffffff0088, 0xffff008affff0089,\n        0xffffffff008bffff, 0x8dffff008cffff, 0xffffffffffffffff,\n        0x910090008f008e, 0x95009400930092, 0xffff0097ffff0096,\n        0xffff0099ffff0098, 0xffff009bffff009a, 0xffff009dffff009c,\n        0xa0ffff009f009e, 0xa2ffff00a1ffff, 0xa4ffff00a3ffff, 0xa6ffff00a5ffff,\n        0xa8ffff00a7ffff, 0xab00aa00a9ffff, 0xffffffff00acffff,\n        0xaeffff00adffff, 0xb0ffff00afffff, 0xb2ffff00b1ffff, 0xb4ffff00b3ffff,\n        0xb6ffff00b5ffff, 0xb8ffff00b7ffff, 0xbaffff00b9ffff, 0xbcffff00bbffff,\n        0xbeffff00bdffff, 0xc0ffff00bfffff, 0xc1ffffffffffff, 0xc3ffff00c2ffff,\n        0xc5ffff00c4ffff, 0xc7ffff00c6ffff, 0xc9ffff00c8ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xcbffffffff00ca,\n        0xffff00cdffff00cc, 0xceffffffffffff, 0xd0ffff00cfffff,\n        0xd2ffff00d1ffff, 0xd600d500d400d3, 0xd900d8ffff00d7, 0xdbffff00daffff,\n        0xffffffffffffffff, 0xddffffffff00dc, 0xffff00df00deffff,\n        0xe2ffff00e100e0, 0xe3ffffffffffff, 0xffff00e500e4ffff,\n        0xffffffff00e6ffff, 0xffffffffffffffff, 0xffffffff00e7ffff,\n        0xe9ffffffff00e8, 0xffffffffffffffff, 0xed00ec00eb00ea,\n        0xffffffffffff00ee, 0xffff00efffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff00f0ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xf2ffff00f1ffff, 0xf3ffffffffffff,\n        0xf4ffffffffffff, 0xffffffff00f600f5, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xfa00f900f800f7, 0xfd00fc00fbffff,\n        0x101010000ff00fe, 0x105010401030102, 0x109010801070106,\n        0x10d010c010b010a, 0x1110110010f010e, 0x115011401130112,\n        0xffff011801170116, 0xffffffff011a0119, 0x11d011c011bffff,\n        0x11fffff011effff, 0x121ffff0120ffff, 0x123ffff0122ffff,\n        0x125ffff0124ffff, 0x127ffff0126ffff, 0x129ffff0128ffff,\n        0xffff012c012b012a, 0xffffffff012dffff, 0x12fffffffff012e,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x133013201310130, 0x137013601350134,\n        0x13b013a01390138, 0x13f013e013d013c, 0x143014201410140,\n        0x147014601450144, 0x14b014a01490148, 0x14f014e014d014c,\n        0x153015201510150, 0x157015601550154, 0x15b015a01590158,\n        0x15f015e015d015c, 0x161ffff0160ffff, 0x163ffff0162ffff,\n        0x165ffff0164ffff, 0x167ffff0166ffff, 0x169ffff0168ffff,\n        0x16bffff016affff, 0x16dffff016cffff, 0x16fffff016effff,\n        0xffffffff0170ffff, 0xffffffffffffffff, 0x171ffffffffffff,\n        0x173ffff0172ffff, 0x175ffff0174ffff, 0x177ffff0176ffff,\n        0x179ffff0178ffff, 0x17bffff017affff, 0x17dffff017cffff,\n        0x17fffff017effff, 0x181ffff0180ffff, 0x183ffff0182ffff,\n        0x185ffff0184ffff, 0x187ffff0186ffff, 0x189ffff0188ffff,\n        0x18bffff018affff, 0xffff018cffffffff, 0xffff018effff018d,\n        0xffff0190ffff018f, 0x1930192ffff0191, 0x195ffff0194ffff,\n        0x197ffff0196ffff, 0x199ffff0198ffff, 0x19bffff019affff,\n        0x19dffff019cffff, 0x19fffff019effff, 0x1a1ffff01a0ffff,\n        0x1a3ffff01a2ffff, 0x1a5ffff01a4ffff, 0x1a7ffff01a6ffff,\n        0x1a9ffff01a8ffff, 0x1abffff01aaffff, 0x1adffff01acffff,\n        0x1afffff01aeffff, 0x1b1ffff01b0ffff, 0x1b3ffff01b2ffff,\n        0x1b5ffff01b4ffff, 0x1b7ffff01b6ffff, 0x1b9ffff01b8ffff,\n        0x1bbffff01baffff, 0x1bdffff01bcffff, 0x1bfffff01beffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x1c201c101c0ffff,\n        0x1c601c501c401c3, 0x1ca01c901c801c7, 0x1ce01cd01cc01cb,\n        0x1d201d101d001cf, 0x1d601d501d401d3, 0x1da01d901d801d7,\n        0x1de01dd01dc01db, 0x1e201e101e001df, 0xffff01e501e401e3,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffff01e6ffff, 0xffffffff01e7ffff,\n        0x1e9ffff01e8ffff, 0x1ebffff01eaffff, 0x1edffff01ecffff,\n        0x1efffff01eeffff, 0x1f1ffff01f0ffff, 0x1f3ffff01f2ffff,\n        0x1f5ffff01f4ffff, 0x1f7ffff01f6ffff, 0x1f9ffff01f8ffff,\n        0x1fbffff01faffff, 0x1fdffff01fcffff, 0x1ffffff01feffff,\n        0x201ffff0200ffff, 0x203ffff0202ffff, 0x205ffff0204ffff,\n        0x207ffff0206ffff, 0x209ffff0208ffff, 0x20bffff020affff,\n        0x20dffff020cffff, 0x20fffff020effff, 0x211ffff0210ffff,\n        0x213ffff0212ffff, 0x215ffff0214ffff, 0x217ffff0216ffff,\n        0x219ffff0218ffff, 0x21bffff021affff, 0x21dffff021cffff,\n        0x21fffff021effff, 0x221ffff0220ffff, 0x223ffff0222ffff,\n        0x225ffff0224ffff, 0x227ffff0226ffff, 0x229ffff0228ffff,\n        0x22bffff022affff, 0x22dffff022cffff, 0x22fffff022effff,\n        0x231ffff0230ffff, 0xffffffff0232ffff, 0x233ffffffffffff,\n        0xffffffffffffffff, 0x235ffff0234ffff, 0x237ffff0236ffff,\n        0x239ffff0238ffff, 0x23bffff023affff, 0x23dffff023cffff,\n        0x23fffff023effff, 0x241ffff0240ffff, 0x243ffff0242ffff,\n        0x245ffff0244ffff, 0x247ffff0246ffff, 0x249ffff0248ffff,\n        0x24bffff024affff, 0x24dffff024cffff, 0x24fffff024effff,\n        0x251ffff0250ffff, 0x253ffff0252ffff, 0x255ffff0254ffff,\n        0x257ffff0256ffff, 0x259ffff0258ffff, 0x25bffff025affff,\n        0x25dffff025cffff, 0x25fffff025effff, 0x261ffff0260ffff,\n        0x263ffff0262ffff, 0x267026602650264, 0x26b026a02690268,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x26f026e026d026c,\n        0xffffffff02710270, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x275027402730272, 0x279027802770276, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x27d027c027b027a, 0x2810280027f027e,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x285028402830282,\n        0xffffffff02870286, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x289ffff0288ffff, 0x28bffff028affff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x28f028e028d028c, 0x293029202910290,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x297029602950294,\n        0x29b029a02990298, 0x29f029e029d029c, 0xffffffff02a102a0,\n        0x2a502a402a302a2, 0x2a902a802a702a6, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x2ad02ac02ab02aa, 0x2b102b002af02ae,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2b502b402b302b2,\n        0x2b902b802b702b6, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x2bcffff02bb02ba, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff02bdffffffff, 0x2beffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff02c002bf,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffff02c202c1, 0xffffffff02c3ffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x2c4ffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffff02c5ffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2c902c802c702c6,\n        0x2cd02cc02cb02ca, 0x2d102d002cf02ce, 0x2d502d402d302d2,\n        0xffffffffffffffff, 0xffffffffffff02d6, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2da02d902d802d7,\n        0x2de02dd02dc02db, 0x2e202e102e002df, 0x2e602e502e402e3,\n        0x2ea02e902e802e7, 0x2ee02ed02ec02eb, 0xffffffff02f002ef,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x2f402f302f202f1,\n        0x2f802f702f602f5, 0x2fc02fb02fa02f9, 0x30002ff02fe02fd,\n        0x304030303020301, 0x308030703060305, 0x30c030b030a0309,\n        0x310030f030e030d, 0x314031303120311, 0x318031703160315,\n        0x31c031b031a0319, 0xffff031f031e031d, 0xffffffff0320ffff,\n        0xffff03220321ffff, 0xffff0324ffff0323, 0xffffffffffff0325,\n        0x326ffffffffffff, 0xffff0327ffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x329ffff0328ffff, 0x32bffff032affff,\n        0x32dffff032cffff, 0x32fffff032effff, 0x331ffff0330ffff,\n        0x333ffff0332ffff, 0x335ffff0334ffff, 0x337ffff0336ffff,\n        0x339ffff0338ffff, 0x33bffff033affff, 0x33dffff033cffff,\n        0x33fffff033effff, 0x341ffff0340ffff, 0x343ffff0342ffff,\n        0x345ffff0344ffff, 0x347ffff0346ffff, 0x349ffff0348ffff,\n        0x34bffff034affff, 0x34dffff034cffff, 0x34fffff034effff,\n        0x351ffff0350ffff, 0x353ffff0352ffff, 0x355ffff0354ffff,\n        0x357ffff0356ffff, 0x359ffff0358ffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffff035bffff035a, 0x35cffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x360035f035e035d, 0x364036303620361, 0x368036703660365,\n        0x36c036b036a0369, 0x370036f036e036d, 0x374037303720371,\n        0x378037703760375, 0x37c037b037a0379, 0x380037f037e037d,\n        0x383ffff03820381, 0xffffffffffffffff, 0xffffffff0384ffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x386ffff0385ffff, 0x388ffff0387ffff,\n        0x38affff0389ffff, 0x38cffff038bffff, 0x38effff038dffff,\n        0x390ffff038fffff, 0x392ffff0391ffff, 0x394ffff0393ffff,\n        0x396ffff0395ffff, 0x398ffff0397ffff, 0x39affff0399ffff,\n        0xffffffff039bffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x39dffff039cffff,\n        0x39fffff039effff, 0x3a1ffff03a0ffff, 0x3a3ffff03a2ffff,\n        0x3a5ffff03a4ffff, 0x3a7ffff03a6ffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x3a8ffffffffffff,\n        0x3aaffff03a9ffff, 0x3acffff03abffff, 0x3aeffff03adffff,\n        0x3afffffffffffff, 0x3b1ffff03b0ffff, 0x3b3ffff03b2ffff,\n        0x3b5ffff03b4ffff, 0x3b7ffff03b6ffff, 0x3b9ffff03b8ffff,\n        0x3bbffff03baffff, 0x3bdffff03bcffff, 0x3bfffff03beffff,\n        0x3c1ffff03c0ffff, 0x3c3ffff03c2ffff, 0x3c5ffff03c4ffff,\n        0x3c7ffff03c6ffff, 0x3c9ffff03c8ffff, 0x3cbffff03caffff,\n        0x3cdffff03ccffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffff03ceffffffff, 0x3d0ffffffff03cf, 0x3d2ffff03d1ffff,\n        0x3d4ffff03d3ffff, 0xffffffffffffffff, 0xffffffffffff03d5,\n        0x3d7ffff03d6ffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0x3d9ffff03d8ffff, 0x3dbffff03daffff,\n        0xffffffff03dcffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0x3df03de03ddffff, 0x3e303e203e103e0, 0x3e703e603e503e4,\n        0x3eb03ea03e903e8, 0x3ef03ee03ed03ec, 0x3f303f203f103f0,\n        0xffff03f603f503f4, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0x3fa03f903f803f7,\n        0x3fe03fd03fc03fb, 0x4020401040003ff, 0x406040504040403,\n        0x40a040904080407, 0x40e040d040c040b, 0x41204110410040f,\n        0x416041504140413, 0x41a041904180417, 0x41e041d041c041b,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,\n        0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff]);\n@property\n{\n    private alias _IUA = immutable(uint[]);\n    _IUA toUpperTable()\n    {\n        static _IUA t = [\n            0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,\n            0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,\n            0x57, 0x58, 0x59, 0x5a, 0x39c, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5,\n            0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,\n            0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd8, 0xd9, 0xda, 0xdb, 0xdc,\n            0xdd, 0xde, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c,\n            0x10e, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11a, 0x11c, 0x11e,\n            0x120, 0x122, 0x124, 0x126, 0x128, 0x12a, 0x12c, 0x12e, 0x49,\n            0x132, 0x134, 0x136, 0x139, 0x13b, 0x13d, 0x13f, 0x141, 0x143,\n            0x145, 0x147, 0x14a, 0x14c, 0x14e, 0x150, 0x152, 0x154, 0x156,\n            0x158, 0x15a, 0x15c, 0x15e, 0x160, 0x162, 0x164, 0x166, 0x168,\n            0x16a, 0x16c, 0x16e, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17b,\n            0x17d, 0x53, 0x243, 0x182, 0x184, 0x187, 0x18b, 0x191, 0x1f6,\n            0x198, 0x23d, 0x220, 0x1a0, 0x1a2, 0x1a4, 0x1a7, 0x1ac, 0x1af,\n            0x1b3, 0x1b5, 0x1b8, 0x1bc, 0x1f7, 0x1c4, 0x1c4, 0x1c7, 0x1c7,\n            0x1ca, 0x1ca, 0x1cd, 0x1cf, 0x1d1, 0x1d3, 0x1d5, 0x1d7, 0x1d9,\n            0x1db, 0x18e, 0x1de, 0x1e0, 0x1e2, 0x1e4, 0x1e6, 0x1e8, 0x1ea,\n            0x1ec, 0x1ee, 0x1f1, 0x1f1, 0x1f4, 0x1f8, 0x1fa, 0x1fc, 0x1fe,\n            0x200, 0x202, 0x204, 0x206, 0x208, 0x20a, 0x20c, 0x20e, 0x210,\n            0x212, 0x214, 0x216, 0x218, 0x21a, 0x21c, 0x21e, 0x222, 0x224,\n            0x226, 0x228, 0x22a, 0x22c, 0x22e, 0x230, 0x232, 0x23b, 0x2c7e,\n            0x2c7f, 0x241, 0x246, 0x248, 0x24a, 0x24c, 0x24e, 0x2c6f, 0x2c6d,\n            0x2c70, 0x181, 0x186, 0x189, 0x18a, 0x18f, 0x190, 0x193, 0x194,\n            0xa78d, 0xa7aa, 0x197, 0x196, 0x2c62, 0x19c, 0x2c6e, 0x19d, 0x19f,\n            0x2c64, 0x1a6, 0x1a9, 0x1ae, 0x244, 0x1b1, 0x1b2, 0x245, 0x1b7,\n            0x399, 0x370, 0x372, 0x376, 0x3fd, 0x3fe, 0x3ff, 0x386, 0x388,\n            0x389, 0x38a, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397,\n            0x398, 0x399, 0x39a, 0x39b, 0x39c, 0x39d, 0x39e, 0x39f, 0x3a0,\n            0x3a1, 0x3a3, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7, 0x3a8, 0x3a9,\n            0x3aa, 0x3ab, 0x38c, 0x38e, 0x38f, 0x392, 0x398, 0x3a6, 0x3a0,\n            0x3cf, 0x3d8, 0x3da, 0x3dc, 0x3de, 0x3e0, 0x3e2, 0x3e4, 0x3e6,\n            0x3e8, 0x3ea, 0x3ec, 0x3ee, 0x39a, 0x3a1, 0x3f9, 0x395, 0x3f7,\n            0x3fa, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417,\n            0x418, 0x419, 0x41a, 0x41b, 0x41c, 0x41d, 0x41e, 0x41f, 0x420,\n            0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429,\n            0x42a, 0x42b, 0x42c, 0x42d, 0x42e, 0x42f, 0x400, 0x401, 0x402,\n            0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40a, 0x40b,\n            0x40c, 0x40d, 0x40e, 0x40f, 0x460, 0x462, 0x464, 0x466, 0x468,\n            0x46a, 0x46c, 0x46e, 0x470, 0x472, 0x474, 0x476, 0x478, 0x47a,\n            0x47c, 0x47e, 0x480, 0x48a, 0x48c, 0x48e, 0x490, 0x492, 0x494,\n            0x496, 0x498, 0x49a, 0x49c, 0x49e, 0x4a0, 0x4a2, 0x4a4, 0x4a6,\n            0x4a8, 0x4aa, 0x4ac, 0x4ae, 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8,\n            0x4ba, 0x4bc, 0x4be, 0x4c1, 0x4c3, 0x4c5, 0x4c7, 0x4c9, 0x4cb,\n            0x4cd, 0x4c0, 0x4d0, 0x4d2, 0x4d4, 0x4d6, 0x4d8, 0x4da, 0x4dc,\n            0x4de, 0x4e0, 0x4e2, 0x4e4, 0x4e6, 0x4e8, 0x4ea, 0x4ec, 0x4ee,\n            0x4f0, 0x4f2, 0x4f4, 0x4f6, 0x4f8, 0x4fa, 0x4fc, 0x4fe, 0x500,\n            0x502, 0x504, 0x506, 0x508, 0x50a, 0x50c, 0x50e, 0x510, 0x512,\n            0x514, 0x516, 0x518, 0x51a, 0x51c, 0x51e, 0x520, 0x522, 0x524,\n            0x526, 0x531, 0x532, 0x533, 0x534, 0x535, 0x536, 0x537, 0x538,\n            0x539, 0x53a, 0x53b, 0x53c, 0x53d, 0x53e, 0x53f, 0x540, 0x541,\n            0x542, 0x543, 0x544, 0x545, 0x546, 0x547, 0x548, 0x549, 0x54a,\n            0x54b, 0x54c, 0x54d, 0x54e, 0x54f, 0x550, 0x551, 0x552, 0x553,\n            0x554, 0x555, 0x556, 0xa77d, 0x2c63, 0x1e00, 0x1e02, 0x1e04,\n            0x1e06, 0x1e08, 0x1e0a, 0x1e0c, 0x1e0e, 0x1e10, 0x1e12, 0x1e14,\n            0x1e16, 0x1e18, 0x1e1a, 0x1e1c, 0x1e1e, 0x1e20, 0x1e22, 0x1e24,\n            0x1e26, 0x1e28, 0x1e2a, 0x1e2c, 0x1e2e, 0x1e30, 0x1e32, 0x1e34,\n            0x1e36, 0x1e38, 0x1e3a, 0x1e3c, 0x1e3e, 0x1e40, 0x1e42, 0x1e44,\n            0x1e46, 0x1e48, 0x1e4a, 0x1e4c, 0x1e4e, 0x1e50, 0x1e52, 0x1e54,\n            0x1e56, 0x1e58, 0x1e5a, 0x1e5c, 0x1e5e, 0x1e60, 0x1e62, 0x1e64,\n            0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e, 0x1e70, 0x1e72, 0x1e74,\n            0x1e76, 0x1e78, 0x1e7a, 0x1e7c, 0x1e7e, 0x1e80, 0x1e82, 0x1e84,\n            0x1e86, 0x1e88, 0x1e8a, 0x1e8c, 0x1e8e, 0x1e90, 0x1e92, 0x1e94,\n            0x1e60, 0x1ea0, 0x1ea2, 0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac,\n            0x1eae, 0x1eb0, 0x1eb2, 0x1eb4, 0x1eb6, 0x1eb8, 0x1eba, 0x1ebc,\n            0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ec8, 0x1eca, 0x1ecc,\n            0x1ece, 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, 0x1eda, 0x1edc,\n            0x1ede, 0x1ee0, 0x1ee2, 0x1ee4, 0x1ee6, 0x1ee8, 0x1eea, 0x1eec,\n            0x1eee, 0x1ef0, 0x1ef2, 0x1ef4, 0x1ef6, 0x1ef8, 0x1efa, 0x1efc,\n            0x1efe, 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e,\n            0x1f0f, 0x1f18, 0x1f19, 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0x1f28,\n            0x1f29, 0x1f2a, 0x1f2b, 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 0x1f38,\n            0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, 0x1f3e, 0x1f3f, 0x1f48,\n            0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0x1f59, 0x1f5b, 0x1f5d,\n            0x1f5f, 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e,\n            0x1f6f, 0x1fba, 0x1fbb, 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda,\n            0x1fdb, 0x1ff8, 0x1ff9, 0x1fea, 0x1feb, 0x1ffa, 0x1ffb, 0x1f88,\n            0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f98,\n            0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa8,\n            0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fb8,\n            0x1fb9, 0x1fbc, 0x399, 0x1fcc, 0x1fd8, 0x1fd9, 0x1fe8, 0x1fe9,\n            0x1fec, 0x1ffc, 0x2132, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164,\n            0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216a, 0x216b, 0x216c,\n            0x216d, 0x216e, 0x216f, 0x2183, 0x24b6, 0x24b7, 0x24b8, 0x24b9,\n            0x24ba, 0x24bb, 0x24bc, 0x24bd, 0x24be, 0x24bf, 0x24c0, 0x24c1,\n            0x24c2, 0x24c3, 0x24c4, 0x24c5, 0x24c6, 0x24c7, 0x24c8, 0x24c9,\n            0x24ca, 0x24cb, 0x24cc, 0x24cd, 0x24ce, 0x24cf, 0x2c00, 0x2c01,\n            0x2c02, 0x2c03, 0x2c04, 0x2c05, 0x2c06, 0x2c07, 0x2c08, 0x2c09,\n            0x2c0a, 0x2c0b, 0x2c0c, 0x2c0d, 0x2c0e, 0x2c0f, 0x2c10, 0x2c11,\n            0x2c12, 0x2c13, 0x2c14, 0x2c15, 0x2c16, 0x2c17, 0x2c18, 0x2c19,\n            0x2c1a, 0x2c1b, 0x2c1c, 0x2c1d, 0x2c1e, 0x2c1f, 0x2c20, 0x2c21,\n            0x2c22, 0x2c23, 0x2c24, 0x2c25, 0x2c26, 0x2c27, 0x2c28, 0x2c29,\n            0x2c2a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e, 0x2c60, 0x23a, 0x23e,\n            0x2c67, 0x2c69, 0x2c6b, 0x2c72, 0x2c75, 0x2c80, 0x2c82, 0x2c84,\n            0x2c86, 0x2c88, 0x2c8a, 0x2c8c, 0x2c8e, 0x2c90, 0x2c92, 0x2c94,\n            0x2c96, 0x2c98, 0x2c9a, 0x2c9c, 0x2c9e, 0x2ca0, 0x2ca2, 0x2ca4,\n            0x2ca6, 0x2ca8, 0x2caa, 0x2cac, 0x2cae, 0x2cb0, 0x2cb2, 0x2cb4,\n            0x2cb6, 0x2cb8, 0x2cba, 0x2cbc, 0x2cbe, 0x2cc0, 0x2cc2, 0x2cc4,\n            0x2cc6, 0x2cc8, 0x2cca, 0x2ccc, 0x2cce, 0x2cd0, 0x2cd2, 0x2cd4,\n            0x2cd6, 0x2cd8, 0x2cda, 0x2cdc, 0x2cde, 0x2ce0, 0x2ce2, 0x2ceb,\n            0x2ced, 0x2cf2, 0x10a0, 0x10a1, 0x10a2, 0x10a3, 0x10a4, 0x10a5,\n            0x10a6, 0x10a7, 0x10a8, 0x10a9, 0x10aa, 0x10ab, 0x10ac, 0x10ad,\n            0x10ae, 0x10af, 0x10b0, 0x10b1, 0x10b2, 0x10b3, 0x10b4, 0x10b5,\n            0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10ba, 0x10bb, 0x10bc, 0x10bd,\n            0x10be, 0x10bf, 0x10c0, 0x10c1, 0x10c2, 0x10c3, 0x10c4, 0x10c5,\n            0x10c7, 0x10cd, 0xa640, 0xa642, 0xa644, 0xa646, 0xa648, 0xa64a,\n            0xa64c, 0xa64e, 0xa650, 0xa652, 0xa654, 0xa656, 0xa658, 0xa65a,\n            0xa65c, 0xa65e, 0xa660, 0xa662, 0xa664, 0xa666, 0xa668, 0xa66a,\n            0xa66c, 0xa680, 0xa682, 0xa684, 0xa686, 0xa688, 0xa68a, 0xa68c,\n            0xa68e, 0xa690, 0xa692, 0xa694, 0xa696, 0xa722, 0xa724, 0xa726,\n            0xa728, 0xa72a, 0xa72c, 0xa72e, 0xa732, 0xa734, 0xa736, 0xa738,\n            0xa73a, 0xa73c, 0xa73e, 0xa740, 0xa742, 0xa744, 0xa746, 0xa748,\n            0xa74a, 0xa74c, 0xa74e, 0xa750, 0xa752, 0xa754, 0xa756, 0xa758,\n            0xa75a, 0xa75c, 0xa75e, 0xa760, 0xa762, 0xa764, 0xa766, 0xa768,\n            0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b, 0xa77e, 0xa780, 0xa782,\n            0xa784, 0xa786, 0xa78b, 0xa790, 0xa792, 0xa7a0, 0xa7a2, 0xa7a4,\n            0xa7a6, 0xa7a8, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26,\n            0xff27, 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e,\n            0xff2f, 0xff30, 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36,\n            0xff37, 0xff38, 0xff39, 0xff3a, 0x10400, 0x10401, 0x10402, 0x10403,\n            0x10404, 0x10405, 0x10406, 0x10407, 0x10408, 0x10409, 0x1040a,\n            0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f, 0x10410, 0x10411,\n            0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417, 0x10418,\n            0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f,\n            0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426,\n            0x10427, 0x2000053, 0x53, 0x130, 0x2000046, 0x46, 0x2000046, 0x49,\n            0x2000046, 0x4c, 0x3000046, 0x46, 0x49, 0x3000046, 0x46, 0x4c,\n            0x2000053, 0x54, 0x2000053, 0x54, 0x2000535, 0x552, 0x2000544,\n            0x546, 0x2000544, 0x535, 0x2000544, 0x53b, 0x200054e, 0x546,\n            0x2000544, 0x53d, 0x20002bc, 0x4e, 0x3000399, 0x308, 0x301,\n            0x30003a5, 0x308, 0x301, 0x200004a, 0x30c, 0x2000048, 0x331,\n            0x2000054, 0x308, 0x2000057, 0x30a, 0x2000059, 0x30a, 0x2000041,\n            0x2be, 0x20003a5, 0x313, 0x30003a5, 0x313, 0x300, 0x30003a5, 0x313,\n            0x301, 0x30003a5, 0x313, 0x342, 0x2000391, 0x342, 0x2000397, 0x342,\n            0x3000399, 0x308, 0x300, 0x3000399, 0x308, 0x301, 0x2000399, 0x342,\n            0x3000399, 0x308, 0x342, 0x30003a5, 0x308, 0x300, 0x30003a5, 0x308,\n            0x301, 0x20003a1, 0x313, 0x20003a5, 0x342, 0x30003a5, 0x308, 0x342,\n            0x20003a9, 0x342, 0x2001f08, 0x399, 0x2001f09, 0x399, 0x2001f0a,\n            0x399, 0x2001f0b, 0x399, 0x2001f0c, 0x399, 0x2001f0d, 0x399,\n            0x2001f0e, 0x399, 0x2001f0f, 0x399, 0x2001f08, 0x399, 0x2001f09,\n            0x399, 0x2001f0a, 0x399, 0x2001f0b, 0x399, 0x2001f0c, 0x399,\n            0x2001f0d, 0x399, 0x2001f0e, 0x399, 0x2001f0f, 0x399, 0x2001f28,\n            0x399, 0x2001f29, 0x399, 0x2001f2a, 0x399, 0x2001f2b, 0x399,\n            0x2001f2c, 0x399, 0x2001f2d, 0x399, 0x2001f2e, 0x399, 0x2001f2f,\n            0x399, 0x2001f28, 0x399, 0x2001f29, 0x399, 0x2001f2a, 0x399,\n            0x2001f2b, 0x399, 0x2001f2c, 0x399, 0x2001f2d, 0x399, 0x2001f2e,\n            0x399, 0x2001f2f, 0x399, 0x2001f68, 0x399, 0x2001f69, 0x399,\n            0x2001f6a, 0x399, 0x2001f6b, 0x399, 0x2001f6c, 0x399, 0x2001f6d,\n            0x399, 0x2001f6e, 0x399, 0x2001f6f, 0x399, 0x2001f68, 0x399,\n            0x2001f69, 0x399, 0x2001f6a, 0x399, 0x2001f6b, 0x399, 0x2001f6c,\n            0x399, 0x2001f6d, 0x399, 0x2001f6e, 0x399, 0x2001f6f, 0x399,\n            0x2000391, 0x399, 0x2000391, 0x399, 0x2000397, 0x399, 0x2000397,\n            0x399, 0x20003a9, 0x399, 0x20003a9, 0x399, 0x2001fba, 0x399,\n            0x2000386, 0x399, 0x2001fca, 0x399, 0x2000389, 0x399, 0x2001ffa,\n            0x399, 0x200038f, 0x399, 0x3000391, 0x342, 0x399, 0x3000397, 0x342,\n            0x399, 0x30003a9, 0x342, 0x399\n        ];\n        return t;\n    }\n\n    _IUA toLowerTable()\n    {\n        static _IUA t = [\n            0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,\n            0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,\n            0x77, 0x78, 0x79, 0x7a, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,\n            0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1,\n            0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd,\n            0xfe, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10b, 0x10d, 0x10f,\n            0x111, 0x113, 0x115, 0x117, 0x119, 0x11b, 0x11d, 0x11f, 0x121,\n            0x123, 0x125, 0x127, 0x129, 0x12b, 0x12d, 0x12f, 0x69, 0x133,\n            0x135, 0x137, 0x13a, 0x13c, 0x13e, 0x140, 0x142, 0x144, 0x146,\n            0x148, 0x14b, 0x14d, 0x14f, 0x151, 0x153, 0x155, 0x157, 0x159,\n            0x15b, 0x15d, 0x15f, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16b,\n            0x16d, 0x16f, 0x171, 0x173, 0x175, 0x177, 0xff, 0x17a, 0x17c,\n            0x17e, 0x253, 0x183, 0x185, 0x254, 0x188, 0x256, 0x257, 0x18c,\n            0x1dd, 0x259, 0x25b, 0x192, 0x260, 0x263, 0x269, 0x268, 0x199,\n            0x26f, 0x272, 0x275, 0x1a1, 0x1a3, 0x1a5, 0x280, 0x1a8, 0x283,\n            0x1ad, 0x288, 0x1b0, 0x28a, 0x28b, 0x1b4, 0x1b6, 0x292, 0x1b9,\n            0x1bd, 0x1c6, 0x1c6, 0x1c9, 0x1c9, 0x1cc, 0x1cc, 0x1ce, 0x1d0,\n            0x1d2, 0x1d4, 0x1d6, 0x1d8, 0x1da, 0x1dc, 0x1df, 0x1e1, 0x1e3,\n            0x1e5, 0x1e7, 0x1e9, 0x1eb, 0x1ed, 0x1ef, 0x1f3, 0x1f3, 0x1f5,\n            0x195, 0x1bf, 0x1f9, 0x1fb, 0x1fd, 0x1ff, 0x201, 0x203, 0x205,\n            0x207, 0x209, 0x20b, 0x20d, 0x20f, 0x211, 0x213, 0x215, 0x217,\n            0x219, 0x21b, 0x21d, 0x21f, 0x19e, 0x223, 0x225, 0x227, 0x229,\n            0x22b, 0x22d, 0x22f, 0x231, 0x233, 0x2c65, 0x23c, 0x19a, 0x2c66,\n            0x242, 0x180, 0x289, 0x28c, 0x247, 0x249, 0x24b, 0x24d, 0x24f,\n            0x371, 0x373, 0x377, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3cc, 0x3cd,\n            0x3ce, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b7, 0x3b8,\n            0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd, 0x3be, 0x3bf, 0x3c0, 0x3c1,\n            0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7, 0x3c8, 0x3c9, 0x3ca, 0x3cb,\n            0x3d7, 0x3d9, 0x3db, 0x3dd, 0x3df, 0x3e1, 0x3e3, 0x3e5, 0x3e7,\n            0x3e9, 0x3eb, 0x3ed, 0x3ef, 0x3b8, 0x3f8, 0x3f2, 0x3fb, 0x37b,\n            0x37c, 0x37d, 0x450, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456,\n            0x457, 0x458, 0x459, 0x45a, 0x45b, 0x45c, 0x45d, 0x45e, 0x45f,\n            0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438,\n            0x439, 0x43a, 0x43b, 0x43c, 0x43d, 0x43e, 0x43f, 0x440, 0x441,\n            0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44a,\n            0x44b, 0x44c, 0x44d, 0x44e, 0x44f, 0x461, 0x463, 0x465, 0x467,\n            0x469, 0x46b, 0x46d, 0x46f, 0x471, 0x473, 0x475, 0x477, 0x479,\n            0x47b, 0x47d, 0x47f, 0x481, 0x48b, 0x48d, 0x48f, 0x491, 0x493,\n            0x495, 0x497, 0x499, 0x49b, 0x49d, 0x49f, 0x4a1, 0x4a3, 0x4a5,\n            0x4a7, 0x4a9, 0x4ab, 0x4ad, 0x4af, 0x4b1, 0x4b3, 0x4b5, 0x4b7,\n            0x4b9, 0x4bb, 0x4bd, 0x4bf, 0x4cf, 0x4c2, 0x4c4, 0x4c6, 0x4c8,\n            0x4ca, 0x4cc, 0x4ce, 0x4d1, 0x4d3, 0x4d5, 0x4d7, 0x4d9, 0x4db,\n            0x4dd, 0x4df, 0x4e1, 0x4e3, 0x4e5, 0x4e7, 0x4e9, 0x4eb, 0x4ed,\n            0x4ef, 0x4f1, 0x4f3, 0x4f5, 0x4f7, 0x4f9, 0x4fb, 0x4fd, 0x4ff,\n            0x501, 0x503, 0x505, 0x507, 0x509, 0x50b, 0x50d, 0x50f, 0x511,\n            0x513, 0x515, 0x517, 0x519, 0x51b, 0x51d, 0x51f, 0x521, 0x523,\n            0x525, 0x527, 0x561, 0x562, 0x563, 0x564, 0x565, 0x566, 0x567,\n            0x568, 0x569, 0x56a, 0x56b, 0x56c, 0x56d, 0x56e, 0x56f, 0x570,\n            0x571, 0x572, 0x573, 0x574, 0x575, 0x576, 0x577, 0x578, 0x579,\n            0x57a, 0x57b, 0x57c, 0x57d, 0x57e, 0x57f, 0x580, 0x581, 0x582,\n            0x583, 0x584, 0x585, 0x586, 0x2d00, 0x2d01, 0x2d02, 0x2d03, 0x2d04,\n            0x2d05, 0x2d06, 0x2d07, 0x2d08, 0x2d09, 0x2d0a, 0x2d0b, 0x2d0c,\n            0x2d0d, 0x2d0e, 0x2d0f, 0x2d10, 0x2d11, 0x2d12, 0x2d13, 0x2d14,\n            0x2d15, 0x2d16, 0x2d17, 0x2d18, 0x2d19, 0x2d1a, 0x2d1b, 0x2d1c,\n            0x2d1d, 0x2d1e, 0x2d1f, 0x2d20, 0x2d21, 0x2d22, 0x2d23, 0x2d24,\n            0x2d25, 0x2d27, 0x2d2d, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09,\n            0x1e0b, 0x1e0d, 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19,\n            0x1e1b, 0x1e1d, 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29,\n            0x1e2b, 0x1e2d, 0x1e2f, 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39,\n            0x1e3b, 0x1e3d, 0x1e3f, 0x1e41, 0x1e43, 0x1e45, 0x1e47, 0x1e49,\n            0x1e4b, 0x1e4d, 0x1e4f, 0x1e51, 0x1e53, 0x1e55, 0x1e57, 0x1e59,\n            0x1e5b, 0x1e5d, 0x1e5f, 0x1e61, 0x1e63, 0x1e65, 0x1e67, 0x1e69,\n            0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 0x1e79,\n            0x1e7b, 0x1e7d, 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89,\n            0x1e8b, 0x1e8d, 0x1e8f, 0x1e91, 0x1e93, 0x1e95, 0xdf, 0x1ea1,\n            0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9, 0x1eab, 0x1ead, 0x1eaf, 0x1eb1,\n            0x1eb3, 0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb, 0x1ebd, 0x1ebf, 0x1ec1,\n            0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9, 0x1ecb, 0x1ecd, 0x1ecf, 0x1ed1,\n            0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb, 0x1edd, 0x1edf, 0x1ee1,\n            0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, 0x1eed, 0x1eef, 0x1ef1,\n            0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1efb, 0x1efd, 0x1eff, 0x1f00,\n            0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 0x1f10,\n            0x1f11, 0x1f12, 0x1f13, 0x1f14, 0x1f15, 0x1f20, 0x1f21, 0x1f22,\n            0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27, 0x1f30, 0x1f31, 0x1f32,\n            0x1f33, 0x1f34, 0x1f35, 0x1f36, 0x1f37, 0x1f40, 0x1f41, 0x1f42,\n            0x1f43, 0x1f44, 0x1f45, 0x1f51, 0x1f53, 0x1f55, 0x1f57, 0x1f60,\n            0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, 0x1f80,\n            0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, 0x1f90,\n            0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, 0x1fa0,\n            0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, 0x1fb0,\n            0x1fb1, 0x1f70, 0x1f71, 0x1fb3, 0x1f72, 0x1f73, 0x1f74, 0x1f75,\n            0x1fc3, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0x1fe0, 0x1fe1, 0x1f7a,\n            0x1f7b, 0x1fe5, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x1ff3, 0x3c9,\n            0x6b, 0xe5, 0x214e, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175,\n            0x2176, 0x2177, 0x2178, 0x2179, 0x217a, 0x217b, 0x217c, 0x217d,\n            0x217e, 0x217f, 0x2184, 0x24d0, 0x24d1, 0x24d2, 0x24d3, 0x24d4,\n            0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9, 0x24da, 0x24db, 0x24dc,\n            0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1, 0x24e2, 0x24e3, 0x24e4,\n            0x24e5, 0x24e6, 0x24e7, 0x24e8, 0x24e9, 0x2c30, 0x2c31, 0x2c32,\n            0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37, 0x2c38, 0x2c39, 0x2c3a,\n            0x2c3b, 0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f, 0x2c40, 0x2c41, 0x2c42,\n            0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47, 0x2c48, 0x2c49, 0x2c4a,\n            0x2c4b, 0x2c4c, 0x2c4d, 0x2c4e, 0x2c4f, 0x2c50, 0x2c51, 0x2c52,\n            0x2c53, 0x2c54, 0x2c55, 0x2c56, 0x2c57, 0x2c58, 0x2c59, 0x2c5a,\n            0x2c5b, 0x2c5c, 0x2c5d, 0x2c5e, 0x2c61, 0x26b, 0x1d7d, 0x27d,\n            0x2c68, 0x2c6a, 0x2c6c, 0x251, 0x271, 0x250, 0x252, 0x2c73, 0x2c76,\n            0x23f, 0x240, 0x2c81, 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b,\n            0x2c8d, 0x2c8f, 0x2c91, 0x2c93, 0x2c95, 0x2c97, 0x2c99, 0x2c9b,\n            0x2c9d, 0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab,\n            0x2cad, 0x2caf, 0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7, 0x2cb9, 0x2cbb,\n            0x2cbd, 0x2cbf, 0x2cc1, 0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9, 0x2ccb,\n            0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3, 0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb,\n            0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2cec, 0x2cee, 0x2cf3, 0xa641,\n            0xa643, 0xa645, 0xa647, 0xa649, 0xa64b, 0xa64d, 0xa64f, 0xa651,\n            0xa653, 0xa655, 0xa657, 0xa659, 0xa65b, 0xa65d, 0xa65f, 0xa661,\n            0xa663, 0xa665, 0xa667, 0xa669, 0xa66b, 0xa66d, 0xa681, 0xa683,\n            0xa685, 0xa687, 0xa689, 0xa68b, 0xa68d, 0xa68f, 0xa691, 0xa693,\n            0xa695, 0xa697, 0xa723, 0xa725, 0xa727, 0xa729, 0xa72b, 0xa72d,\n            0xa72f, 0xa733, 0xa735, 0xa737, 0xa739, 0xa73b, 0xa73d, 0xa73f,\n            0xa741, 0xa743, 0xa745, 0xa747, 0xa749, 0xa74b, 0xa74d, 0xa74f,\n            0xa751, 0xa753, 0xa755, 0xa757, 0xa759, 0xa75b, 0xa75d, 0xa75f,\n            0xa761, 0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d, 0xa76f,\n            0xa77a, 0xa77c, 0x1d79, 0xa77f, 0xa781, 0xa783, 0xa785, 0xa787,\n            0xa78c, 0x265, 0xa791, 0xa793, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7,\n            0xa7a9, 0x266, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46,\n            0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e,\n            0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56,\n            0xff57, 0xff58, 0xff59, 0xff5a, 0x10428, 0x10429, 0x1042a, 0x1042b,\n            0x1042c, 0x1042d, 0x1042e, 0x1042f, 0x10430, 0x10431, 0x10432,\n            0x10433, 0x10434, 0x10435, 0x10436, 0x10437, 0x10438, 0x10439,\n            0x1043a, 0x1043b, 0x1043c, 0x1043d, 0x1043e, 0x1043f, 0x10440,\n            0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447,\n            0x10448, 0x10449, 0x1044a, 0x1044b, 0x1044c, 0x1044d, 0x1044e,\n            0x1044f, 0xdf, 0x2000069, 0x307, 0xfb00, 0xfb01, 0xfb02, 0xfb03,\n            0xfb04, 0xfb05, 0xfb06, 0x587, 0xfb13, 0xfb14, 0xfb15, 0xfb16,\n            0xfb17, 0x149, 0x390, 0x3b0, 0x1f0, 0x1e96, 0x1e97, 0x1e98, 0x1e99,\n            0x1e9a, 0x1f50, 0x1f52, 0x1f54, 0x1f56, 0x1fb6, 0x1fc6, 0x1fd2,\n            0x1fd3, 0x1fd6, 0x1fd7, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe6, 0x1fe7,\n            0x1ff6, 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86,\n            0x1f87, 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86,\n            0x1f87, 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96,\n            0x1f97, 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96,\n            0x1f97, 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6,\n            0x1fa7, 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6,\n            0x1fa7, 0x1fb3, 0x1fb3, 0x1fc3, 0x1fc3, 0x1ff3, 0x1ff3, 0x1fb2,\n            0x1fb4, 0x1fc2, 0x1fc4, 0x1ff2, 0x1ff4, 0x1fb7, 0x1fc7, 0x1ff7\n        ];\n        return t;\n    }\n\n    _IUA toTitleTable()\n    {\n        static _IUA t = [\n            0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,\n            0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,\n            0x57, 0x58, 0x59, 0x5a, 0x39c, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5,\n            0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,\n            0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd8, 0xd9, 0xda, 0xdb, 0xdc,\n            0xdd, 0xde, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c,\n            0x10e, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11a, 0x11c, 0x11e,\n            0x120, 0x122, 0x124, 0x126, 0x128, 0x12a, 0x12c, 0x12e, 0x49,\n            0x132, 0x134, 0x136, 0x139, 0x13b, 0x13d, 0x13f, 0x141, 0x143,\n            0x145, 0x147, 0x14a, 0x14c, 0x14e, 0x150, 0x152, 0x154, 0x156,\n            0x158, 0x15a, 0x15c, 0x15e, 0x160, 0x162, 0x164, 0x166, 0x168,\n            0x16a, 0x16c, 0x16e, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17b,\n            0x17d, 0x53, 0x243, 0x182, 0x184, 0x187, 0x18b, 0x191, 0x1f6,\n            0x198, 0x23d, 0x220, 0x1a0, 0x1a2, 0x1a4, 0x1a7, 0x1ac, 0x1af,\n            0x1b3, 0x1b5, 0x1b8, 0x1bc, 0x1f7, 0x1c5, 0x1c5, 0x1c5, 0x1c8,\n            0x1c8, 0x1c8, 0x1cb, 0x1cb, 0x1cb, 0x1cd, 0x1cf, 0x1d1, 0x1d3,\n            0x1d5, 0x1d7, 0x1d9, 0x1db, 0x18e, 0x1de, 0x1e0, 0x1e2, 0x1e4,\n            0x1e6, 0x1e8, 0x1ea, 0x1ec, 0x1ee, 0x1f2, 0x1f2, 0x1f2, 0x1f4,\n            0x1f8, 0x1fa, 0x1fc, 0x1fe, 0x200, 0x202, 0x204, 0x206, 0x208,\n            0x20a, 0x20c, 0x20e, 0x210, 0x212, 0x214, 0x216, 0x218, 0x21a,\n            0x21c, 0x21e, 0x222, 0x224, 0x226, 0x228, 0x22a, 0x22c, 0x22e,\n            0x230, 0x232, 0x23b, 0x2c7e, 0x2c7f, 0x241, 0x246, 0x248, 0x24a,\n            0x24c, 0x24e, 0x2c6f, 0x2c6d, 0x2c70, 0x181, 0x186, 0x189, 0x18a,\n            0x18f, 0x190, 0x193, 0x194, 0xa78d, 0xa7aa, 0x197, 0x196, 0x2c62,\n            0x19c, 0x2c6e, 0x19d, 0x19f, 0x2c64, 0x1a6, 0x1a9, 0x1ae, 0x244,\n            0x1b1, 0x1b2, 0x245, 0x1b7, 0x399, 0x370, 0x372, 0x376, 0x3fd,\n            0x3fe, 0x3ff, 0x386, 0x388, 0x389, 0x38a, 0x391, 0x392, 0x393,\n            0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39a, 0x39b, 0x39c,\n            0x39d, 0x39e, 0x39f, 0x3a0, 0x3a1, 0x3a3, 0x3a3, 0x3a4, 0x3a5,\n            0x3a6, 0x3a7, 0x3a8, 0x3a9, 0x3aa, 0x3ab, 0x38c, 0x38e, 0x38f,\n            0x392, 0x398, 0x3a6, 0x3a0, 0x3cf, 0x3d8, 0x3da, 0x3dc, 0x3de,\n            0x3e0, 0x3e2, 0x3e4, 0x3e6, 0x3e8, 0x3ea, 0x3ec, 0x3ee, 0x39a,\n            0x3a1, 0x3f9, 0x395, 0x3f7, 0x3fa, 0x410, 0x411, 0x412, 0x413,\n            0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41a, 0x41b, 0x41c,\n            0x41d, 0x41e, 0x41f, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425,\n            0x426, 0x427, 0x428, 0x429, 0x42a, 0x42b, 0x42c, 0x42d, 0x42e,\n            0x42f, 0x400, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407,\n            0x408, 0x409, 0x40a, 0x40b, 0x40c, 0x40d, 0x40e, 0x40f, 0x460,\n            0x462, 0x464, 0x466, 0x468, 0x46a, 0x46c, 0x46e, 0x470, 0x472,\n            0x474, 0x476, 0x478, 0x47a, 0x47c, 0x47e, 0x480, 0x48a, 0x48c,\n            0x48e, 0x490, 0x492, 0x494, 0x496, 0x498, 0x49a, 0x49c, 0x49e,\n            0x4a0, 0x4a2, 0x4a4, 0x4a6, 0x4a8, 0x4aa, 0x4ac, 0x4ae, 0x4b0,\n            0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x4bc, 0x4be, 0x4c1, 0x4c3,\n            0x4c5, 0x4c7, 0x4c9, 0x4cb, 0x4cd, 0x4c0, 0x4d0, 0x4d2, 0x4d4,\n            0x4d6, 0x4d8, 0x4da, 0x4dc, 0x4de, 0x4e0, 0x4e2, 0x4e4, 0x4e6,\n            0x4e8, 0x4ea, 0x4ec, 0x4ee, 0x4f0, 0x4f2, 0x4f4, 0x4f6, 0x4f8,\n            0x4fa, 0x4fc, 0x4fe, 0x500, 0x502, 0x504, 0x506, 0x508, 0x50a,\n            0x50c, 0x50e, 0x510, 0x512, 0x514, 0x516, 0x518, 0x51a, 0x51c,\n            0x51e, 0x520, 0x522, 0x524, 0x526, 0x531, 0x532, 0x533, 0x534,\n            0x535, 0x536, 0x537, 0x538, 0x539, 0x53a, 0x53b, 0x53c, 0x53d,\n            0x53e, 0x53f, 0x540, 0x541, 0x542, 0x543, 0x544, 0x545, 0x546,\n            0x547, 0x548, 0x549, 0x54a, 0x54b, 0x54c, 0x54d, 0x54e, 0x54f,\n            0x550, 0x551, 0x552, 0x553, 0x554, 0x555, 0x556, 0xa77d, 0x2c63,\n            0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08, 0x1e0a, 0x1e0c, 0x1e0e,\n            0x1e10, 0x1e12, 0x1e14, 0x1e16, 0x1e18, 0x1e1a, 0x1e1c, 0x1e1e,\n            0x1e20, 0x1e22, 0x1e24, 0x1e26, 0x1e28, 0x1e2a, 0x1e2c, 0x1e2e,\n            0x1e30, 0x1e32, 0x1e34, 0x1e36, 0x1e38, 0x1e3a, 0x1e3c, 0x1e3e,\n            0x1e40, 0x1e42, 0x1e44, 0x1e46, 0x1e48, 0x1e4a, 0x1e4c, 0x1e4e,\n            0x1e50, 0x1e52, 0x1e54, 0x1e56, 0x1e58, 0x1e5a, 0x1e5c, 0x1e5e,\n            0x1e60, 0x1e62, 0x1e64, 0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e,\n            0x1e70, 0x1e72, 0x1e74, 0x1e76, 0x1e78, 0x1e7a, 0x1e7c, 0x1e7e,\n            0x1e80, 0x1e82, 0x1e84, 0x1e86, 0x1e88, 0x1e8a, 0x1e8c, 0x1e8e,\n            0x1e90, 0x1e92, 0x1e94, 0x1e60, 0x1ea0, 0x1ea2, 0x1ea4, 0x1ea6,\n            0x1ea8, 0x1eaa, 0x1eac, 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4, 0x1eb6,\n            0x1eb8, 0x1eba, 0x1ebc, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6,\n            0x1ec8, 0x1eca, 0x1ecc, 0x1ece, 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6,\n            0x1ed8, 0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2, 0x1ee4, 0x1ee6,\n            0x1ee8, 0x1eea, 0x1eec, 0x1eee, 0x1ef0, 0x1ef2, 0x1ef4, 0x1ef6,\n            0x1ef8, 0x1efa, 0x1efc, 0x1efe, 0x1f08, 0x1f09, 0x1f0a, 0x1f0b,\n            0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, 0x1f18, 0x1f19, 0x1f1a, 0x1f1b,\n            0x1f1c, 0x1f1d, 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, 0x1f2c, 0x1f2d,\n            0x1f2e, 0x1f2f, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d,\n            0x1f3e, 0x1f3f, 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d,\n            0x1f59, 0x1f5b, 0x1f5d, 0x1f5f, 0x1f68, 0x1f69, 0x1f6a, 0x1f6b,\n            0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, 0x1fba, 0x1fbb, 0x1fc8, 0x1fc9,\n            0x1fca, 0x1fcb, 0x1fda, 0x1fdb, 0x1ff8, 0x1ff9, 0x1fea, 0x1feb,\n            0x1ffa, 0x1ffb, 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d,\n            0x1f8e, 0x1f8f, 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d,\n            0x1f9e, 0x1f9f, 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad,\n            0x1fae, 0x1faf, 0x1fb8, 0x1fb9, 0x1fbc, 0x399, 0x1fcc, 0x1fd8,\n            0x1fd9, 0x1fe8, 0x1fe9, 0x1fec, 0x1ffc, 0x2132, 0x2160, 0x2161,\n            0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169,\n            0x216a, 0x216b, 0x216c, 0x216d, 0x216e, 0x216f, 0x2183, 0x24b6,\n            0x24b7, 0x24b8, 0x24b9, 0x24ba, 0x24bb, 0x24bc, 0x24bd, 0x24be,\n            0x24bf, 0x24c0, 0x24c1, 0x24c2, 0x24c3, 0x24c4, 0x24c5, 0x24c6,\n            0x24c7, 0x24c8, 0x24c9, 0x24ca, 0x24cb, 0x24cc, 0x24cd, 0x24ce,\n            0x24cf, 0x2c00, 0x2c01, 0x2c02, 0x2c03, 0x2c04, 0x2c05, 0x2c06,\n            0x2c07, 0x2c08, 0x2c09, 0x2c0a, 0x2c0b, 0x2c0c, 0x2c0d, 0x2c0e,\n            0x2c0f, 0x2c10, 0x2c11, 0x2c12, 0x2c13, 0x2c14, 0x2c15, 0x2c16,\n            0x2c17, 0x2c18, 0x2c19, 0x2c1a, 0x2c1b, 0x2c1c, 0x2c1d, 0x2c1e,\n            0x2c1f, 0x2c20, 0x2c21, 0x2c22, 0x2c23, 0x2c24, 0x2c25, 0x2c26,\n            0x2c27, 0x2c28, 0x2c29, 0x2c2a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e,\n            0x2c60, 0x23a, 0x23e, 0x2c67, 0x2c69, 0x2c6b, 0x2c72, 0x2c75,\n            0x2c80, 0x2c82, 0x2c84, 0x2c86, 0x2c88, 0x2c8a, 0x2c8c, 0x2c8e,\n            0x2c90, 0x2c92, 0x2c94, 0x2c96, 0x2c98, 0x2c9a, 0x2c9c, 0x2c9e,\n            0x2ca0, 0x2ca2, 0x2ca4, 0x2ca6, 0x2ca8, 0x2caa, 0x2cac, 0x2cae,\n            0x2cb0, 0x2cb2, 0x2cb4, 0x2cb6, 0x2cb8, 0x2cba, 0x2cbc, 0x2cbe,\n            0x2cc0, 0x2cc2, 0x2cc4, 0x2cc6, 0x2cc8, 0x2cca, 0x2ccc, 0x2cce,\n            0x2cd0, 0x2cd2, 0x2cd4, 0x2cd6, 0x2cd8, 0x2cda, 0x2cdc, 0x2cde,\n            0x2ce0, 0x2ce2, 0x2ceb, 0x2ced, 0x2cf2, 0x10a0, 0x10a1, 0x10a2,\n            0x10a3, 0x10a4, 0x10a5, 0x10a6, 0x10a7, 0x10a8, 0x10a9, 0x10aa,\n            0x10ab, 0x10ac, 0x10ad, 0x10ae, 0x10af, 0x10b0, 0x10b1, 0x10b2,\n            0x10b3, 0x10b4, 0x10b5, 0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10ba,\n            0x10bb, 0x10bc, 0x10bd, 0x10be, 0x10bf, 0x10c0, 0x10c1, 0x10c2,\n            0x10c3, 0x10c4, 0x10c5, 0x10c7, 0x10cd, 0xa640, 0xa642, 0xa644,\n            0xa646, 0xa648, 0xa64a, 0xa64c, 0xa64e, 0xa650, 0xa652, 0xa654,\n            0xa656, 0xa658, 0xa65a, 0xa65c, 0xa65e, 0xa660, 0xa662, 0xa664,\n            0xa666, 0xa668, 0xa66a, 0xa66c, 0xa680, 0xa682, 0xa684, 0xa686,\n            0xa688, 0xa68a, 0xa68c, 0xa68e, 0xa690, 0xa692, 0xa694, 0xa696,\n            0xa722, 0xa724, 0xa726, 0xa728, 0xa72a, 0xa72c, 0xa72e, 0xa732,\n            0xa734, 0xa736, 0xa738, 0xa73a, 0xa73c, 0xa73e, 0xa740, 0xa742,\n            0xa744, 0xa746, 0xa748, 0xa74a, 0xa74c, 0xa74e, 0xa750, 0xa752,\n            0xa754, 0xa756, 0xa758, 0xa75a, 0xa75c, 0xa75e, 0xa760, 0xa762,\n            0xa764, 0xa766, 0xa768, 0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b,\n            0xa77e, 0xa780, 0xa782, 0xa784, 0xa786, 0xa78b, 0xa790, 0xa792,\n            0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xff21, 0xff22, 0xff23,\n            0xff24, 0xff25, 0xff26, 0xff27, 0xff28, 0xff29, 0xff2a, 0xff2b,\n            0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, 0xff31, 0xff32, 0xff33,\n            0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, 0xff3a, 0x10400,\n            0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407,\n            0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e,\n            0x1040f, 0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415,\n            0x10416, 0x10417, 0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c,\n            0x1041d, 0x1041e, 0x1041f, 0x10420, 0x10421, 0x10422, 0x10423,\n            0x10424, 0x10425, 0x10426, 0x10427, 0x2000053, 0x73, 0x130,\n            0x2000046, 0x66, 0x2000046, 0x69, 0x2000046, 0x6c, 0x3000046, 0x66,\n            0x69, 0x3000046, 0x66, 0x6c, 0x2000053, 0x74, 0x2000053, 0x74,\n            0x2000535, 0x582, 0x2000544, 0x576, 0x2000544, 0x565, 0x2000544,\n            0x56b, 0x200054e, 0x576, 0x2000544, 0x56d, 0x20002bc, 0x4e,\n            0x3000399, 0x308, 0x301, 0x30003a5, 0x308, 0x301, 0x200004a, 0x30c,\n            0x2000048, 0x331, 0x2000054, 0x308, 0x2000057, 0x30a, 0x2000059,\n            0x30a, 0x2000041, 0x2be, 0x20003a5, 0x313, 0x30003a5, 0x313, 0x300,\n            0x30003a5, 0x313, 0x301, 0x30003a5, 0x313, 0x342, 0x2000391, 0x342,\n            0x2000397, 0x342, 0x3000399, 0x308, 0x300, 0x3000399, 0x308, 0x301,\n            0x2000399, 0x342, 0x3000399, 0x308, 0x342, 0x30003a5, 0x308, 0x300,\n            0x30003a5, 0x308, 0x301, 0x20003a1, 0x313, 0x20003a5, 0x342,\n            0x30003a5, 0x308, 0x342, 0x20003a9, 0x342, 0x1f88, 0x1f89, 0x1f8a,\n            0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f88, 0x1f89, 0x1f8a,\n            0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f98, 0x1f99, 0x1f9a,\n            0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1f98, 0x1f99, 0x1f9a,\n            0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa8, 0x1fa9, 0x1faa,\n            0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fa8, 0x1fa9, 0x1faa,\n            0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fbc, 0x1fbc, 0x1fcc,\n            0x1fcc, 0x1ffc, 0x1ffc, 0x2001fba, 0x345, 0x2000386, 0x345,\n            0x2001fca, 0x345, 0x2000389, 0x345, 0x2001ffa, 0x345, 0x200038f,\n            0x345, 0x3000391, 0x342, 0x345, 0x3000397, 0x342, 0x345, 0x30003a9, 0x342,\n            0x345\n        ];\n        return t;\n    }\n}\n\n}\n\nstatic if (size_t.sizeof == 4)\n{\n//1536 bytes\nenum lowerCaseTrieEntries = TrieEntry!(bool, 8, 4, 9)([0x0, 0x40, 0x80],\n        [0x100, 0x80, 0x2000], [0x2020100, 0x4020302, 0x2020205, 0x2060202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x10000, 0x30002, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003,\n        0x50004, 0x30006, 0x30007, 0x30003, 0x30008, 0x30003, 0x30003, 0x30003,\n        0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003,\n        0x30003, 0x30003, 0x90003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003,\n        0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0xa0003,\n        0xb0003, 0x30003, 0x3000c, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003,\n        0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0xe000d, 0x30003,\n        0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003,\n        0x30003, 0x0, 0x0, 0x0, 0x7fffffe, 0x0, 0x4200400, 0x80000000,\n        0xff7fffff, 0xaaaaaaaa, 0x55aaaaaa, 0xaaaaab55, 0xd4aaaaaa, 0x4e243129,\n        0xe6512d2a, 0xb5555240, 0xaa29aaaa, 0xaaaaaaaa, 0x93faaaaa, 0xffffaa85,\n        0xffffffff, 0xffefffff, 0x1ffffff, 0x3, 0x1f, 0x0, 0x0, 0x20,\n        0x3c8a0000, 0x10000, 0xfffff000, 0xaae37fff, 0x192faaaa, 0x0,\n        0xffff0000, 0xffffffff, 0xaaaaaaaa, 0xaaaaa802, 0xaaaaaaaa, 0xaaaad554,\n        0xaaaaaaaa, 0xaaaaaaaa, 0xaa, 0x0, 0xfffffffe, 0xff, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0, 0x0,\n        0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xbfeaaaaa, 0xaaaaaaaa,\n        0xaaaaaaaa, 0xaaaaaaaa, 0x3f00ff, 0xff00ff, 0xff003f, 0x3fff00ff,\n        0xff00ff, 0x40df00ff, 0xcf00dc, 0xdc00ff, 0x0, 0x0, 0x0, 0x80020000,\n        0x1fff0000, 0x0, 0x0, 0x0, 0x8c400, 0x32108000, 0x43c0, 0xffff0000,\n        0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff0000, 0x3ff,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff0000, 0x7fffffff,\n        0x3fda1562, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x8501a, 0xffffffff,\n        0x20bf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaaaaaaaa, 0x2aaa,\n        0xaaaaaa, 0x0, 0x0, 0x0, 0x0, 0xaaabaaa8, 0xaaaaaaaa, 0x95ffaaaa,\n        0xa50aa, 0x2aa, 0x0, 0x7000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xf8007f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x7fffffe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xffffff00, 0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0xfc000000, 0xfffff, 0xffdfc000, 0xff, 0xffffffc,\n        0xebc00000, 0xffef, 0xfffffc00, 0xc000000f, 0xffffff, 0xfffc0000,\n        0xfff, 0xffffffc0, 0xfc000000, 0xfffff, 0xffffc000, 0xff, 0xffffffc,\n        0xffc00000, 0xffff, 0xfffffc00, 0x3f, 0xf7fffffc, 0xf0000003,\n        0xfdfffff, 0xffc00000, 0x3f7fff, 0xffff0000, 0xfdff, 0xfffffc00, 0xbf7,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0]);\n//1472 bytes\nenum upperCaseTrieEntries = TrieEntry!(bool, 8, 4, 9)([0x0, 0x40, 0x80],\n        [0x100, 0x80, 0x1e00], [0x2020100, 0x4020302, 0x2020205, 0x2060202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x10000, 0x30002, 0x30003, 0x30003, 0x30004, 0x30003, 0x30003,\n        0x50003, 0x30006, 0x30007, 0x30003, 0x30008, 0x30003, 0x30003, 0x30003,\n        0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003,\n        0x30003, 0x30003, 0x90003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003,\n        0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003,\n        0xa0003, 0x30003, 0x3000b, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003,\n        0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0xd000c, 0x30003,\n        0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003, 0x30003,\n        0x30003, 0x0, 0x0, 0x7fffffe, 0x0, 0x0, 0x0, 0x7f7fffff, 0x0,\n        0x55555555, 0xaa555555, 0x555554aa, 0x2b555555, 0xb1dbced6, 0x11aed2d5,\n        0x4aaaa490, 0x55d25555, 0x55555555, 0x6c055555, 0x557a, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x450000, 0xfffed740, 0xffb, 0x551c8000,\n        0xe6905555, 0xffffffff, 0xffff, 0x0, 0x55555555, 0x55555401,\n        0x55555555, 0x55552aab, 0x55555555, 0x55555555, 0xfffe0055, 0x7fffff,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0x20bf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55555555,\n        0x55555555, 0x55555555, 0x55555555, 0x40155555, 0x55555555, 0x55555555,\n        0x55555555, 0x3f00ff00, 0xff00ff00, 0xaa003f00, 0xff00, 0x0, 0xf000000,\n        0xf000f00, 0xf001f00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x3e273884, 0xc00f3d50, 0x20, 0xffff, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0xffc00000, 0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0xffffffff, 0x7fff, 0x0, 0xc025ea9d, 0x55555555, 0x55555555,\n        0x55555555, 0x42805, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x55555555, 0x1555, 0x555555, 0x0, 0x0, 0x0, 0x0, 0x55545554,\n        0x55555555, 0x6a005555, 0x52855, 0x555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x7fffffe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xffffffff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x3ffffff, 0xfff00000, 0x3fff, 0xffffff00,\n        0xd0000003, 0x3fde64, 0xffff0000, 0x3ff, 0x1fdfe7b0, 0x7b000000,\n        0x1fc5f, 0xfffff000, 0x3f, 0x3ffffff, 0xfff00000, 0x3fff, 0xffffff00,\n        0xf0000003, 0x3fffff, 0xffff0000, 0x3ff, 0xffffff00, 0x1, 0x7fffffc,\n        0xf0000000, 0x1fffff, 0xffc00000, 0x7fff, 0xffff0000, 0x1ff, 0x400,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0]);\n//8704 bytes\nenum simpleCaseTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x40, 0x200],\n        [0x100, 0x380, 0xd00], [0x2020100, 0x4020302, 0x2020205, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x10000, 0x30002, 0x50004, 0x70006, 0x90008, 0xa, 0xb0000, 0xd000c,\n        0xf000e, 0x110010, 0x130012, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x160015, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x170000,\n        0x0, 0x190018, 0x1b001a, 0x1d001c, 0x1f001e, 0x0, 0x0, 0x210020, 0x22,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x240023, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x260025, 0x280027, 0x29, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x2a0000, 0x2b, 0x2d002c, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x30002f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x320031, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x20ffff, 0x240022, 0x280026, 0x2c002a, 0x30002e,\n        0x72f0032, 0x390037, 0x3d003b, 0x41003f, 0x1b00043, 0x4a0048, 0x4e004c,\n        0x520050, 0xffff0054, 0xffffffff, 0xffffffff, 0x21ffff, 0x250023,\n        0x290027, 0x2d002b, 0x31002f, 0x7300033, 0x3a0038, 0x3e003c, 0x420040,\n        0x1b10044, 0x4b0049, 0x4f004d, 0x530051, 0xffff0055, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x43fffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xc800c6, 0xcc0498, 0x14904aa,\n        0xd500d3, 0xd900d7, 0xdd00db, 0xe100df, 0xe500e3, 0xe900e7, 0xed00eb,\n        0xf100ef, 0xffff00f3, 0xf700f5, 0xfb00f9, 0xff00fd, 0x6be0101,\n        0xc900c7, 0xcd0499, 0x14a04ab, 0xd600d4, 0xda00d8, 0xde00dc, 0xe200e0,\n        0xe600e4, 0xea00e8, 0xee00ec, 0xf200f0, 0xffff00f4, 0xf800f6, 0xfc00fa,\n        0x10000fe, 0x1a80102, 0x1160115, 0x1180117, 0x11c011b, 0x11e011d,\n        0x120011f, 0x1240123, 0x1260125, 0x1280127, 0x12c012b, 0x12e012d,\n        0x130012f, 0x1340133, 0x1360135, 0x1380137, 0x13a0139, 0x13c013b,\n        0x13e013d, 0x140013f, 0x1420141, 0x1440143, 0x1460145, 0x1480147,\n        0x14d014c, 0x14f014e, 0xffffffff, 0x1510150, 0x1530152, 0x1550154,\n        0x156ffff, 0x1580157, 0x15c0159, 0x15e015d, 0x160015f, 0x1620161,\n        0x1640163, 0x1660165, 0xffff0167, 0x1690168, 0x16b016a, 0x16d016c,\n        0x16f016e, 0x1710170, 0x1730172, 0x1750174, 0x1770176, 0x1790178,\n        0x17b017a, 0x17d017c, 0x17f017e, 0x1830182, 0x1870186, 0x18b018a,\n        0x18f018e, 0x1930192, 0x1970196, 0x19b019a, 0x19f019e, 0x1a301a2,\n        0x1a501a4, 0x1a701a6, 0x1aa01a9, 0x1ac01ab, 0x1ae01ad, 0x1b201af,\n        0x1b3028b, 0x1b601b5, 0x1ba01b9, 0x1bd01bb, 0x1bf01be, 0x1c301c1,\n        0xffff01c4, 0x1c701c5, 0x1cb01c9, 0x1cd01cc, 0x23b01cf, 0x1d301d1,\n        0x1d601d5, 0xffff0283, 0x1d901d7, 0x1db0269, 0x1de01dd, 0x1e001df,\n        0x1e201e1, 0x1e501e3, 0x1e701e6, 0xffffffff, 0x1ea01e9, 0x1ed01eb,\n        0x1ef01ee, 0x1f301f1, 0x1f501f4, 0x1f701f6, 0x1fa01f9, 0xffffffff,\n        0x1fc01fb, 0x23dffff, 0xffffffff, 0xffffffff, 0x2010200, 0x2060202,\n        0x2080207, 0x20d020c, 0x20f020e, 0x2110210, 0x2130212, 0x2150214,\n        0x2170216, 0x2190218, 0x21b021a, 0x21d021c, 0x1c6021e, 0x220021f,\n        0x2240223, 0x2260225, 0x2280227, 0x22a0229, 0x22c022b, 0x22e022d,\n        0x230022f, 0x2320231, 0x236ffff, 0x2380237, 0x23a0239, 0x23e023c,\n        0x240023f, 0x2440243, 0x2460245, 0x2480247, 0x24a0249, 0x24c024b,\n        0x24e024d, 0x250024f, 0x2520251, 0x2540253, 0x2560255, 0x2580257,\n        0x25a0259, 0x25c025b, 0x25e025d, 0x260025f, 0x2620261, 0x2640263,\n        0x2660265, 0x2680267, 0xffff026a, 0x26c026b, 0x26e026d, 0x270026f,\n        0x2720271, 0x2740273, 0x2760275, 0x2780277, 0x27a0279, 0x27c027b,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x281027f, 0x2840282, 0x2d70285,\n        0x2870482, 0x28c0288, 0x28f028d, 0x2920291, 0x2940293, 0x2960295,\n        0x2980297, 0x29c029b, 0x466046a, 0x1b402b7, 0xffff01bc, 0x1c201c0,\n        0x1c8ffff, 0x1caffff, 0xffffffff, 0xffffffff, 0xffff01ce, 0x1d0ffff,\n        0x748ffff, 0xffff05fa, 0x1d201d4, 0x528ffff, 0xffffffff, 0x1d8ffff,\n        0x2b3ffff, 0xffff01da, 0x1dcffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x2a3ffff, 0xffffffff, 0xffff01e4, 0x1e8ffff, 0xffffffff, 0xffffffff,\n        0x28e01ec, 0x1f201f0, 0xffff0290, 0xffffffff, 0xffffffff, 0xffff01f8,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x83affff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x31e031d, 0x320031f,\n        0xffffffff, 0x3240323, 0xffffffff, 0x3d5ffff, 0x3d903d7, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff0329, 0x32f032d, 0xffff0331,\n        0xffff0333, 0x3370335, 0x339ffff, 0x33e0395, 0x3cc0340, 0x3470345,\n        0x83b03c8, 0x35403c2, 0x3590440, 0x35d035b, 0x3c5039f, 0x388ffff,\n        0x36a0368, 0x36f039c, 0x7100371, 0x3780376, 0x32e032a, 0x3320330,\n        0x33affff, 0x33f0396, 0x3cd0341, 0x3480346, 0x83c03c9, 0x35503c3,\n        0x35a0441, 0x35e035c, 0x3c603a0, 0x38a0389, 0x36b0369, 0x370039d,\n        0x7110372, 0x3790377, 0x3360334, 0x3930338, 0x3ca0397, 0xffffffff,\n        0x39effff, 0x39403a1, 0x3a303a2, 0x3a703a6, 0x3a903a8, 0x3ab03aa,\n        0x3ad03ac, 0x3af03ae, 0x3b103b0, 0x3b503b4, 0x3b903b8, 0x3bd03bc,\n        0x3bf03be, 0x3c103c0, 0x3c703c4, 0xffff03d1, 0x3ce03cb, 0x3cfffff,\n        0x3d203d0, 0x3d403d3, 0x3d6ffff, 0x3da03d8, 0x3dd03db, 0x3e103df,\n        0x3e503e3, 0x3e903e7, 0x3ed03eb, 0x3f103ef, 0x3f503f3, 0x3f903f7,\n        0x3fd03fb, 0x40103ff, 0x4050403, 0x4090407, 0x40d040b, 0x411040f,\n        0x4150413, 0x4190417, 0x41d041b, 0x421041f, 0x4250423, 0x4290427,\n        0x42d042b, 0x431042f, 0x4350433, 0x4390437, 0x3fe03fc, 0x4020400,\n        0x4060404, 0x40a0408, 0x40e040c, 0x4120410, 0x4160414, 0x41a0418,\n        0x41e041c, 0x4220420, 0x4260424, 0x42a0428, 0x42e042c, 0x4320430,\n        0x4360434, 0x43a0438, 0x3de03dc, 0x3e203e0, 0x3e603e4, 0x3ea03e8,\n        0x3ee03ec, 0x3f203f0, 0x3f603f4, 0x3fa03f8, 0x4510450, 0x4530452,\n        0x4570456, 0x4590458, 0x45d045c, 0x4610460, 0x4650464, 0x4690468,\n        0x46d046c, 0x4710470, 0x4730472, 0x4770476, 0x4790478, 0x47b047a,\n        0x47d047c, 0x4810480, 0x4850484, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x4950494, 0x4970496, 0x49b049a, 0x49d049c, 0x49f049e,\n        0x4a304a2, 0x4a704a6, 0x4a904a8, 0x4ad04ac, 0x4b104b0, 0x4b304b2,\n        0x4b704b6, 0x4b904b8, 0x4bb04ba, 0x4bf04be, 0x4c104c0, 0x4c504c4,\n        0x4c904c8, 0x4cd04cc, 0x4cf04ce, 0x4d304d2, 0x4d504d4, 0x4d704d6,\n        0x4db04da, 0x4df04de, 0x4e304e2, 0x4e704e6, 0x4ec04ea, 0x4f004ed,\n        0x4f404f1, 0x4f804f5, 0x4fc04f9, 0x50004fd, 0x5040501, 0x4eb0505,\n        0x50b050a, 0x50d050c, 0x50f050e, 0x5130512, 0x5170516, 0x5190518,\n        0x51d051c, 0x51f051e, 0x5210520, 0x5250524, 0x5270526, 0x52b052a,\n        0x52d052c, 0x52f052e, 0x5330532, 0x5370536, 0x5390538, 0x53d053c,\n        0x53f053e, 0x5410540, 0x5430542, 0x5470546, 0x5490548, 0x54b054a,\n        0x54d054c, 0x54f054e, 0x5510550, 0x5550554, 0x5570556, 0x5590558,\n        0x55b055a, 0x55d055c, 0x55f055e, 0x5630562, 0x5650564, 0x5670566,\n        0x5690568, 0x56b056a, 0x56f056e, 0x5730572, 0x5750574, 0x5770576,\n        0x5790578, 0x57b057a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x580ffff, 0x5840582, 0x5880586, 0x58c058a, 0x590058e, 0x5940592,\n        0x5980596, 0x59c059a, 0x5a0059e, 0x5a405a2, 0x5a805a6, 0x5ac05aa,\n        0x5b005ae, 0x5b405b2, 0x5b805b6, 0x5bc05ba, 0x5c005be, 0x5c405c2,\n        0x5c805c6, 0xffff05ca, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x581ffff, 0x5850583, 0x5890587, 0x58d058b, 0x591058f, 0x5950593,\n        0x5990597, 0x59d059b, 0x5a1059f, 0x5a505a3, 0x5a905a7, 0x5ad05ab,\n        0x5b105af, 0x5b505b3, 0x5b905b7, 0x5bd05bb, 0x5c105bf, 0x5c505c3,\n        0x5c905c7, 0xffff05cb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x880086, 0x8c008a,\n        0x90008e, 0x940092, 0x980096, 0x9c009a, 0xa0009e, 0xa400a2, 0xa800a6,\n        0xac00aa, 0xb000ae, 0xb400b2, 0xb800b6, 0xbc00ba, 0xc000be, 0xc400c2,\n        0x48e0486, 0x4a000ca, 0x4b400ce, 0x4c6ffff, 0xffffffff, 0xffffffff,\n        0x508ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x7e8ffff, 0xffffffff, 0x454ffff, 0xffffffff, 0x5fd05fc, 0x5ff05fe,\n        0x6010600, 0x6050604, 0x6090608, 0x60b060a, 0x60f060e, 0x6110610,\n        0x6130612, 0x6170616, 0x6190618, 0x61d061c, 0x61f061e, 0x6210620,\n        0x6230622, 0x6270626, 0x6290628, 0x62b062a, 0x62d062c, 0x62f062e,\n        0x6310630, 0x6350634, 0x6370636, 0x6390638, 0x63b063a, 0x63d063c,\n        0x63f063e, 0x6430642, 0x6450644, 0x6470646, 0x6490648, 0x64b064a,\n        0x64d064c, 0x6510650, 0x6530652, 0x6550654, 0x6590658, 0x65d065c,\n        0x65f065e, 0x6630662, 0x6650664, 0x6670666, 0x6690668, 0x66b066a,\n        0x66d066c, 0x6710670, 0x6730672, 0x6750674, 0x6bc06bb, 0x67a0679,\n        0x67c067b, 0x680067f, 0x6820681, 0x6840683, 0x6860685, 0x6880687,\n        0x68a0689, 0x68e068d, 0x690068f, 0x6920691, 0x6960695, 0x6980697,\n        0x69a0699, 0x69e069d, 0x6a0069f, 0x6a206a1, 0x6a406a3, 0x6a606a5,\n        0x6a806a7, 0x6ac06ab, 0x6ae06ad, 0x6b006af, 0x6b206b1, 0x6b406b3,\n        0x6b606b5, 0xffffffff, 0xffffffff, 0x6bdffff, 0xffffffff, 0xffff06bf,\n        0x6c106c0, 0x6c306c2, 0x6c506c4, 0x6c906c8, 0x6cb06ca, 0x6cd06cc,\n        0x6cf06ce, 0x6d106d0, 0x6d506d4, 0x6d706d6, 0x6db06da, 0x6dd06dc,\n        0x6df06de, 0x6e106e0, 0x6e306e2, 0x6e506e4, 0x6e906e8, 0x6eb06ea,\n        0x6ef06ee, 0x6f106f0, 0x6f306f2, 0x6f506f4, 0x6f706f6, 0x6f906f8,\n        0x6fb06fa, 0x6fd06fc, 0x6ff06fe, 0x7010700, 0x7030702, 0x7050704,\n        0x7070706, 0x7090708, 0x70b070a, 0x70d070c, 0x70f070e, 0x7140713,\n        0x7160715, 0x7180717, 0x71c071b, 0x71e071d, 0x720071f, 0x7220721,\n        0x7240723, 0x7260725, 0x7280727, 0x72a0729, 0x72e072d, 0x7330732,\n        0x7380736, 0x73c073a, 0x740073e, 0x7440742, 0x7390737, 0x73d073b,\n        0x741073f, 0x7450743, 0x74c074a, 0x750074e, 0x7540752, 0xffffffff,\n        0x74d074b, 0x751074f, 0x7550753, 0xffffffff, 0x7660764, 0x76a0768,\n        0x76e076c, 0x7720770, 0x7670765, 0x76b0769, 0x76f076d, 0x7730771,\n        0x7860784, 0x78a0788, 0x78e078c, 0x7920790, 0x7870785, 0x78b0789,\n        0x78f078d, 0x7930791, 0x79e079c, 0x7a207a0, 0x7a607a4, 0xffffffff,\n        0x79f079d, 0x7a307a1, 0x7a707a5, 0xffffffff, 0x7b6ffff, 0x7baffff,\n        0x7beffff, 0x7c2ffff, 0x7b7ffff, 0x7bbffff, 0x7bfffff, 0x7c3ffff,\n        0x7d207d0, 0x7d607d4, 0x7da07d8, 0x7de07dc, 0x7d307d1, 0x7d707d5,\n        0x7db07d9, 0x7df07dd, 0x8360834, 0x840083e, 0x8440842, 0x84e084c,\n        0x8620860, 0x8580856, 0x8660864, 0xffffffff, 0x7f607f4, 0x7fa07f8,\n        0x7fe07fc, 0x8020800, 0x7f707f5, 0x7fb07f9, 0x7ff07fd, 0x8030801,\n        0x80a0808, 0x80e080c, 0x8120810, 0x8160814, 0x80b0809, 0x80f080d,\n        0x8130811, 0x8170815, 0x8220820, 0x8260824, 0x82a0828, 0x82e082c,\n        0x8230821, 0x8270825, 0x82b0829, 0x82f082d, 0x8320830, 0x838ffff,\n        0xffffffff, 0xffffffff, 0x8330831, 0x8370835, 0xffff0839, 0xffff083d,\n        0xffffffff, 0x846ffff, 0xffffffff, 0xffffffff, 0x841083f, 0x8450843,\n        0xffff0847, 0xffffffff, 0x84a0848, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x84b0849, 0x84f084d, 0xffffffff, 0xffffffff, 0x8540852, 0xffffffff,\n        0x85affff, 0xffffffff, 0x8550853, 0x8590857, 0xffff085b, 0xffffffff,\n        0xffffffff, 0x868ffff, 0xffffffff, 0xffffffff, 0x8630861, 0x8670865,\n        0xffff0869, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff0712, 0xffffffff, 0x14b0731,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff0530, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0531,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x180029f, 0x18402af, 0x18802c1, 0x18c005e,\n        0x1900064, 0x194006c, 0x1980076, 0x19c007e, 0x18102a0, 0x18502b0,\n        0x18902c2, 0x18d005f, 0x1910065, 0x195006d, 0x1990077, 0x19d007f,\n        0xffffffff, 0x1b7ffff, 0xffff01b8, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x4d80444,\n        0x4dc0446, 0x4e0044c, 0x4e4045e, 0x4e80474, 0x2d3086a, 0x204ee,\n        0x6c604f2, 0x6e04f6, 0x37a04fa, 0x10d04fe, 0x61a0502, 0x51a0506,\n        0x4d90445, 0x4dd0447, 0x4e1044d, 0x4e5045f, 0x4e90475, 0x2d4086b,\n        0x304ef, 0x6c704f3, 0x6f04f7, 0x37b04fb, 0x10e04ff, 0x61b0503,\n        0x51b0507, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x40000, 0xa0008, 0xe000c, 0x160010, 0x1a0018, 0x2bb001c, 0x2d102c7,\n        0x5602e7, 0x600058, 0x660062, 0x70006a, 0x780074, 0x80007c, 0x2990082,\n        0x607e0, 0x6020084, 0x2a7057c, 0x5d005ce, 0x10305de, 0x1070105,\n        0x10f0109, 0x1190113, 0x1290121, 0xffff0131, 0x50001, 0xb0009, 0xf000d,\n        0x170011, 0x1b0019, 0x2bc001d, 0x2d202c8, 0x5702e8, 0x610059, 0x670063,\n        0x71006b, 0x790075, 0x81007d, 0x29a0083, 0x707e1, 0x6030085, 0x2a8057d,\n        0x5d105cf, 0x10405df, 0x1080106, 0x110010a, 0x11a0114, 0x12a0122,\n        0xffff0132, 0x4c304c2, 0x4550529, 0x28002a4, 0x45a0286, 0x2a9045b,\n        0x46202aa, 0x4670463, 0x46b02b4, 0xffff02b8, 0x2ba02b9, 0x2bfffff,\n        0xffff02c0, 0xffffffff, 0xffffffff, 0xffffffff, 0x48302d8, 0x2e202e1,\n        0x4890488, 0x48b048a, 0x48d048c, 0x4910490, 0x2fe02fd, 0x3040303,\n        0x30e030d, 0x3160315, 0x31a0319, 0x3260325, 0x3280327, 0x2fc02fb,\n        0x6ed06ec, 0x3810380, 0x3830382, 0x3870386, 0x3920391, 0x3a503a4,\n        0x3b303b2, 0x56d056c, 0x5cd05cc, 0x5db05da, 0x5ed05ec, 0x60d060c,\n        0x6570656, 0x43e043d, 0x6e706e6, 0x72c072b, 0x7830782, 0x7e307e2,\n        0x6940693, 0x65b065a, 0x150014, 0x5d005c, 0x4bd04bc, 0x4d104d0,\n        0x5d505d4, 0x1a101a0, 0x5110510, 0x5230522, 0x5350534, 0x5450544,\n        0x5530552, 0x5610560, 0x5710570, 0x57f057e, 0x15b015a, 0x37d037c,\n        0x3bb03ba, 0xffffffff, 0xffffffff, 0xffffffff, 0x5d2ffff, 0x5d805d3,\n        0xffff05d9, 0xffffffff, 0x5e305e2, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x890087, 0x8d008b, 0x91008f,\n        0x950093, 0x990097, 0x9d009b, 0xa1009f, 0xa500a3, 0xa900a7, 0xad00ab,\n        0xb100af, 0xb500b3, 0xb900b7, 0xbd00bb, 0xc100bf, 0xc500c3, 0x48f0487,\n        0x4a100cb, 0x4b500cf, 0x4c7ffff, 0xffffffff, 0xffffffff, 0x509ffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2c402c3, 0x5d705d6, 0x5dd05dc,\n        0x5e105e0, 0x5e705e6, 0x5e905e8, 0x5eb05ea, 0x5ef05ee, 0x5f105f0,\n        0x5f505f4, 0x5f905f8, 0x3080307, 0x6150614, 0x6250624, 0x6330632,\n        0x6410640, 0x64f064e, 0x6610660, 0x66f066e, 0x67e067d, 0x68c068b,\n        0x69c069b, 0x6aa06a9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7350734,\n        0x690068, 0x27e027d, 0x75f075e, 0x7770776, 0x390038f, 0x1f001e,\n        0x7b107b0, 0x7c707c6, 0x2a202a1, 0x7e507e4, 0x6b806b7, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x7590758, 0x75d075c, 0x7610760, 0x2d602d5, 0x2e002df, 0x2e602e5,\n        0x2ee02ed, 0xffffffff, 0x7790778, 0x77d077c, 0x7810780, 0x30c030b,\n        0x3140313, 0x3180317, 0x3220321, 0x7950794, 0x7970796, 0x7990798,\n        0x79b079a, 0x37f037e, 0x3850384, 0x38e038d, 0x7a907a8, 0x7ab07aa,\n        0x7ad07ac, 0x7af07ae, 0x7b307b2, 0x7b507b4, 0x7b907b8, 0x7bd07bc,\n        0x7c107c0, 0x7c507c4, 0x7c907c8, 0x7cd07cc, 0x7cf07ce, 0x46f046e,\n        0x47f047e, 0x4930492, 0x4a504a4, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x514ffff, 0x7e60515, 0x7e907e7, 0x7eb07ea, 0x7ed07ec,\n        0x7ef07ee, 0x7f107f0, 0x7f307f2, 0xffffffff, 0x5f2ffff, 0x74905f3,\n        0xffffffff, 0x8050804, 0x8070806, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x8190818, 0x81b081a, 0x81d081c,\n        0x81f081e, 0x5f705f6, 0xffff05fb, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x756ffff,\n        0x75a02c5, 0x2cd02cb, 0x76202cf, 0x2db06d2, 0x2e30719, 0x2e90448,\n        0x2f107ca, 0x2f30774, 0x77a02f5, 0x77e02f9, 0x3050221, 0x30f007a,\n        0xffff043b, 0xffffffff, 0xffffffff, 0x757ffff, 0x75b02c6, 0x2ce02cc,\n        0x76302d0, 0x2dc06d3, 0x2e4071a, 0x2ea0449, 0x2f207cb, 0x2f40775,\n        0x77b02f6, 0x77f02fa, 0x3060222, 0x310007b, 0xffff043c, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x85c0012,\n        0x72005a, 0x32b0311, 0x11106b9, 0x2ab05e4, 0x2dd029d, 0x2ef085e,\n        0x10b0606, 0x2d902a5, 0x4ca0289, 0x2b502ad, 0x2c902bd, 0x2eb0746,\n        0x30902f7, 0x241031b, 0x38b02b1, 0x44a03b6, 0x442053a, 0x6d8044e,\n        0x85004ae, 0x85d0013, 0x73005b, 0x32c0312, 0x11206ba, 0x2ac05e5,\n        0x2de029e, 0x2f0085f, 0x10c0607, 0x2da02a6, 0x4cb028a, 0x2b602ae,\n        0x2ca02be, 0x2ec0747, 0x30a02f8, 0x242031c, 0x38c02b2, 0x44b03b7,\n        0x443053b, 0x6d9044f, 0x85104af, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff]);\n//8832 bytes\nenum fullCaseTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x40, 0x200],\n        [0x100, 0x380, 0xd40], [0x2020100, 0x4020302, 0x2020205, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x10000, 0x30002, 0x50004, 0x70006, 0x90008, 0xa, 0xb0000, 0xd000c,\n        0xf000e, 0x110010, 0x130012, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x160015, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x170000,\n        0x0, 0x190018, 0x1b001a, 0x1d001c, 0x1f001e, 0x0, 0x0, 0x210020, 0x22,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x240023, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x260025, 0x280027, 0x29, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x2a0000, 0x2b, 0x2d002c, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x310030, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x330032, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x20ffff, 0x240022, 0x280026, 0x2c002a, 0x30002e,\n        0x7810032, 0x390037, 0x3d003b, 0x41003f, 0x1b90043, 0x4a0048, 0x4e004c,\n        0x520050, 0xffff0054, 0xffffffff, 0xffffffff, 0x21ffff, 0x250023,\n        0x290027, 0x2d002b, 0x31002f, 0x7820033, 0x3a0038, 0x3e003c, 0x420040,\n        0x1ba0044, 0x4b0049, 0x4f004d, 0x530051, 0xffff0055, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x470ffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xc800c6, 0xcc04c9, 0x14e04db,\n        0xd500d3, 0xd900d7, 0xdd00db, 0xe100df, 0xe500e3, 0xe900e7, 0xed00eb,\n        0xf100ef, 0xffff00f3, 0xf700f5, 0xfb00f9, 0xff00fd, 0x70f0101,\n        0xc900c7, 0xcd04ca, 0x14f04dc, 0xd600d4, 0xda00d8, 0xde00dc, 0xe200e0,\n        0xe600e4, 0xea00e8, 0xee00ec, 0xf200f0, 0xffff00f4, 0xf800f6, 0xfc00fa,\n        0x10000fe, 0x1b10102, 0x1190118, 0x11b011a, 0x11f011e, 0x1210120,\n        0x1230122, 0x1270126, 0x1290128, 0x12b012a, 0x12f012e, 0x1310130,\n        0x1330132, 0x1370136, 0x1390138, 0x13b013a, 0x13d013c, 0x13f013e,\n        0x1410140, 0x1430142, 0x1470146, 0x1490148, 0x14b014a, 0x14d014c,\n        0x1520151, 0x1540153, 0xffff0155, 0x1580157, 0x15a0159, 0x15c015b,\n        0x15dffff, 0x15f015e, 0x1630160, 0x1650164, 0x1670166, 0x1690168,\n        0x16b016a, 0x16d016c, 0x16f016e, 0x1720171, 0x1740173, 0x1760175,\n        0x1780177, 0x17a0179, 0x17c017b, 0x17e017d, 0x180017f, 0x1820181,\n        0x1840183, 0x1860185, 0x1880187, 0x18c018b, 0x190018f, 0x1940193,\n        0x1980197, 0x19c019b, 0x1a0019f, 0x1a401a3, 0x1a801a7, 0x1ac01ab,\n        0x1ae01ad, 0x1b001af, 0x1b301b2, 0x1b501b4, 0x1b701b6, 0x1bb01b8,\n        0x1bc029c, 0x1bf01be, 0x1c301c2, 0x1c601c4, 0x1c801c7, 0x1cc01ca,\n        0xffff01cd, 0x1d001ce, 0x1d401d2, 0x1d601d5, 0x24801d8, 0x1dc01da,\n        0x1df01de, 0xffff0294, 0x1e201e0, 0x1e60278, 0x1e901e8, 0x1eb01ea,\n        0x1ed01ec, 0x1f001ee, 0x1f201f1, 0xffffffff, 0x1f501f4, 0x1f801f6,\n        0x1fa01f9, 0x1fe01fc, 0x20001ff, 0x2020201, 0x2050204, 0xffffffff,\n        0x2070206, 0x24affff, 0xffffffff, 0xffffffff, 0x20c020b, 0x211020d,\n        0x2130212, 0x2180217, 0x21a0219, 0x21c021b, 0x21e021d, 0x220021f,\n        0x2220221, 0x2240223, 0x2260225, 0x2280227, 0x1cf0229, 0x22b022a,\n        0x22f022e, 0x2310230, 0x2330232, 0x2350234, 0x2370236, 0x2390238,\n        0x23b023a, 0x23d023c, 0x243023e, 0x2450244, 0x2470246, 0x24b0249,\n        0x24d024c, 0x2510250, 0x2530252, 0x2550254, 0x2570256, 0x2590258,\n        0x25b025a, 0x25d025c, 0x2610260, 0x2630262, 0x2650264, 0x2670266,\n        0x2690268, 0x26b026a, 0x26d026c, 0x26f026e, 0x2710270, 0x2730272,\n        0x2750274, 0x2770276, 0xffff0279, 0x27b027a, 0x27d027c, 0x27f027e,\n        0x2810280, 0x2850284, 0x2870286, 0x2890288, 0x28b028a, 0x28d028c,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2920290, 0x2950293, 0x2ec0296,\n        0x29804b3, 0x29d0299, 0x2a0029e, 0x2a302a2, 0x2a502a4, 0x2a702a6,\n        0x2a902a8, 0x2ad02ac, 0x497049b, 0x1bd02ca, 0xffff01c5, 0x1cb01c9,\n        0x1d1ffff, 0x1d3ffff, 0xffffffff, 0xffffffff, 0xffff01d7, 0x1d9ffff,\n        0x79affff, 0xffff0643, 0x1db01dd, 0x559ffff, 0xffffffff, 0x1e1ffff,\n        0x2c6ffff, 0xffff01e3, 0x1e7ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x2b4ffff, 0xffffffff, 0xffff01ef, 0x1f3ffff, 0xffffffff, 0xffffffff,\n        0x29f01f7, 0x1fd01fb, 0xffff02a1, 0xffffffff, 0xffffffff, 0xffff0203,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x8e4ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3450344, 0x3470346,\n        0xffffffff, 0x34b034a, 0xffffffff, 0x406ffff, 0x40a0408, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff0350, 0x3560354, 0xffff0358,\n        0xffff035a, 0x35e035c, 0x3630902, 0x36803c2, 0x3fd036a, 0x371036f,\n        0x8e503f9, 0x37e03f3, 0x3830471, 0x3870385, 0x3f603cc, 0x3b5ffff,\n        0x3940392, 0x39903c9, 0x762039b, 0x3a203a0, 0x3550351, 0x3590357,\n        0x3640915, 0x36903c3, 0x3fe036b, 0x3720370, 0x8e603fa, 0x37f03f4,\n        0x3840472, 0x3880386, 0x3f703cd, 0x3b703b6, 0x3950393, 0x39a03ca,\n        0x763039c, 0x3a303a1, 0x35d035b, 0x3c0035f, 0x3fb03c4, 0xffffffff,\n        0x3cbffff, 0x3c103ce, 0x3d003cf, 0x3d403d3, 0x3d603d5, 0x3d803d7,\n        0x3da03d9, 0x3de03dd, 0x3e003df, 0x3e403e3, 0x3e803e7, 0x3ec03eb,\n        0x3ee03ed, 0x3f203f1, 0x3f803f5, 0xffff0402, 0x3ff03fc, 0x400ffff,\n        0x4030401, 0x4050404, 0x407ffff, 0x40b0409, 0x40e040c, 0x4120410,\n        0x4160414, 0x41a0418, 0x41e041c, 0x4220420, 0x4260424, 0x42a0428,\n        0x42e042c, 0x4320430, 0x4360434, 0x43a0438, 0x43e043c, 0x4420440,\n        0x4460444, 0x44a0448, 0x44e044c, 0x4520450, 0x4560454, 0x45a0458,\n        0x45e045c, 0x4620460, 0x4660464, 0x46a0468, 0x42f042d, 0x4330431,\n        0x4370435, 0x43b0439, 0x43f043d, 0x4430441, 0x4470445, 0x44b0449,\n        0x44f044d, 0x4530451, 0x4570455, 0x45b0459, 0x45f045d, 0x4630461,\n        0x4670465, 0x46b0469, 0x40f040d, 0x4130411, 0x4170415, 0x41b0419,\n        0x41f041d, 0x4230421, 0x4270425, 0x42b0429, 0x4820481, 0x4840483,\n        0x4880487, 0x48a0489, 0x48e048d, 0x4920491, 0x4960495, 0x49a0499,\n        0x49e049d, 0x4a204a1, 0x4a404a3, 0x4a804a7, 0x4aa04a9, 0x4ac04ab,\n        0x4ae04ad, 0x4b204b1, 0x4b604b5, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x4c604c5, 0x4c804c7, 0x4cc04cb, 0x4ce04cd, 0x4d004cf,\n        0x4d404d3, 0x4d804d7, 0x4da04d9, 0x4de04dd, 0x4e204e1, 0x4e404e3,\n        0x4e804e7, 0x4ea04e9, 0x4ec04eb, 0x4f004ef, 0x4f204f1, 0x4f604f5,\n        0x4fa04f9, 0x4fe04fd, 0x50004ff, 0x5040503, 0x5060505, 0x5080507,\n        0x50c050b, 0x510050f, 0x5140513, 0x5180517, 0x51d051b, 0x521051e,\n        0x5250522, 0x5290526, 0x52d052a, 0x531052e, 0x5350532, 0x51c0536,\n        0x53c053b, 0x53e053d, 0x540053f, 0x5440543, 0x5480547, 0x54a0549,\n        0x54e054d, 0x550054f, 0x5520551, 0x5560555, 0x5580557, 0x55c055b,\n        0x55e055d, 0x560055f, 0x5640563, 0x5680567, 0x56a0569, 0x56e056d,\n        0x570056f, 0x5720571, 0x5740573, 0x5780577, 0x57a0579, 0x57c057b,\n        0x57e057d, 0x5820581, 0x5840583, 0x5880587, 0x58a0589, 0x58c058b,\n        0x58e058d, 0x5920591, 0x5940593, 0x5980597, 0x59a0599, 0x59c059b,\n        0x59e059d, 0x5a205a1, 0x5a605a5, 0x5aa05a9, 0x5ac05ab, 0x5ae05ad,\n        0x5b005af, 0x5b405b3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x5b9ffff, 0x5bd05bb, 0x5c105bf, 0x5c505c3, 0x5c905c7, 0x5cd05cb,\n        0x5d105cf, 0x5d505d3, 0x5d905d7, 0x5dd05db, 0x5e105df, 0x5e505e3,\n        0x5e905e7, 0x5ed05eb, 0x5f105ef, 0x5f505f3, 0x5f905f7, 0x5fd05fb,\n        0x60105ff, 0xffff0603, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x5baffff, 0x5be05bc, 0x5c205c0, 0x5c605c4, 0x5ca05c8, 0x5ce05cc,\n        0x5d205d0, 0x5d605d4, 0x5da05d8, 0x5de05dc, 0x5e205e0, 0x5e605e4,\n        0x5ea05e8, 0x5ee05ec, 0x5f205f0, 0x5f605f4, 0x5fa05f8, 0x5fe05fc,\n        0x6020600, 0x6130604, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x880086, 0x8c008a,\n        0x90008e, 0x940092, 0x980096, 0x9c009a, 0xa0009e, 0xa400a2, 0xa800a6,\n        0xac00aa, 0xb000ae, 0xb400b2, 0xb800b6, 0xbc00ba, 0xc000be, 0xc400c2,\n        0x4bf04b7, 0x4d100ca, 0x4e500ce, 0x4f7ffff, 0xffffffff, 0xffffffff,\n        0x539ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x83affff, 0xffffffff, 0x485ffff, 0xffffffff, 0x6460645, 0x6480647,\n        0x64a0649, 0x64e064d, 0x6520651, 0x6540653, 0x6580657, 0x65a0659,\n        0x65c065b, 0x660065f, 0x6620661, 0x6660665, 0x6680667, 0x66a0669,\n        0x66c066b, 0x670066f, 0x6720671, 0x6740673, 0x6760675, 0x6780677,\n        0x67a0679, 0x67e067d, 0x680067f, 0x6820681, 0x6840683, 0x6860685,\n        0x6880687, 0x68c068b, 0x68e068d, 0x690068f, 0x6920691, 0x6940693,\n        0x6960695, 0x69a0699, 0x69c069b, 0x69e069d, 0x6a206a1, 0x6a606a5,\n        0x6a806a7, 0x6ac06ab, 0x6ae06ad, 0x6b006af, 0x6b206b1, 0x6b406b3,\n        0x6b606b5, 0x6ba06b9, 0x6bc06bb, 0x6be06bd, 0x70d070c, 0x6c306c2,\n        0x6c706c6, 0x6cb06ca, 0x6cd06cc, 0x6cf06ce, 0x6d106d0, 0x6d306d2,\n        0x6d506d4, 0x6d906d8, 0x6db06da, 0x6dd06dc, 0x6e106e0, 0x6e306e2,\n        0x6e506e4, 0x6e906e8, 0x6eb06ea, 0x6ed06ec, 0x6ef06ee, 0x6f106f0,\n        0x6f306f2, 0x6f706f6, 0x6f906f8, 0x6fb06fa, 0x6fd06fc, 0x6ff06fe,\n        0x7010700, 0x7040702, 0x7080706, 0x70e070a, 0xffffffff, 0xffff0710,\n        0x7130712, 0x7150714, 0x7170716, 0x71b071a, 0x71d071c, 0x71f071e,\n        0x7210720, 0x7230722, 0x7270726, 0x7290728, 0x72d072c, 0x72f072e,\n        0x7310730, 0x7330732, 0x7350734, 0x7370736, 0x73b073a, 0x73d073c,\n        0x7410740, 0x7430742, 0x7450744, 0x7470746, 0x7490748, 0x74b074a,\n        0x74d074c, 0x74f074e, 0x7510750, 0x7530752, 0x7550754, 0x7570756,\n        0x7590758, 0x75b075a, 0x75d075c, 0x75f075e, 0x7610760, 0x7660765,\n        0x7680767, 0x76a0769, 0x76e076d, 0x770076f, 0x7720771, 0x7740773,\n        0x7760775, 0x7780777, 0x77a0779, 0x77c077b, 0x780077f, 0x7850784,\n        0x78a0788, 0x78e078c, 0x7920790, 0x7960794, 0x78b0789, 0x78f078d,\n        0x7930791, 0x7970795, 0x79e079c, 0x7a207a0, 0x7a607a4, 0xffffffff,\n        0x79f079d, 0x7a307a1, 0x7a707a5, 0xffffffff, 0x7b807b6, 0x7bc07ba,\n        0x7c007be, 0x7c407c2, 0x7b907b7, 0x7bd07bb, 0x7c107bf, 0x7c507c3,\n        0x7d807d6, 0x7dc07da, 0x7e007de, 0x7e407e2, 0x7d907d7, 0x7dd07db,\n        0x7e107df, 0x7e507e3, 0x7f007ee, 0x7f407f2, 0x7f807f6, 0xffffffff,\n        0x7f107ef, 0x7f507f3, 0x7f907f7, 0xffffffff, 0x80807fc, 0x80c07fe,\n        0x8100800, 0x8140804, 0x809ffff, 0x80dffff, 0x811ffff, 0x815ffff,\n        0x8240822, 0x8280826, 0x82c082a, 0x830082e, 0x8250823, 0x8290827,\n        0x82d082b, 0x831082f, 0x8df08dd, 0x8f708f5, 0x8fb08f9, 0x90f090d,\n        0x9370935, 0x9240922, 0x93b0939, 0xffffffff, 0x8590856, 0x85f085c,\n        0x8650862, 0x86b0868, 0x85a0857, 0x860085d, 0x8660863, 0x86c0869,\n        0x8890886, 0x88f088c, 0x8950892, 0x89b0898, 0x88a0887, 0x890088d,\n        0x8960893, 0x89c0899, 0x8b908b6, 0x8bf08bc, 0x8c508c2, 0x8cb08c8,\n        0x8ba08b7, 0x8c008bd, 0x8c608c3, 0x8cc08c9, 0x8db08d9, 0x8e108ce,\n        0xffff08d3, 0x8d708d5, 0x8dc08da, 0x8e008de, 0xffff08e2, 0xffff08e7,\n        0xffffffff, 0x8fd08e8, 0xffff08ed, 0x8f308f1, 0x8f808f6, 0x8fc08fa,\n        0xffff08fe, 0xffffffff, 0x90b0909, 0x9030900, 0xffffffff, 0x9070905,\n        0x90c090a, 0x910090e, 0xffffffff, 0xffffffff, 0x920091e, 0x9160913,\n        0x9260918, 0x91c091a, 0x921091f, 0x9250923, 0xffff0927, 0xffffffff,\n        0xffffffff, 0x93d092a, 0xffff092f, 0x9330931, 0x9380936, 0x93c093a,\n        0xffff093e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff0764, 0xffffffff, 0x1500783,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff0561, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0562,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x18902b0, 0x18d02c2, 0x19102d6, 0x195005e,\n        0x1990064, 0x19d006c, 0x1a10076, 0x1a5007e, 0x18a02b1, 0x18e02c3,\n        0x19202d7, 0x196005f, 0x19a0065, 0x19e006d, 0x1a20077, 0x1a6007f,\n        0xffffffff, 0x1c0ffff, 0xffff01c1, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x5090475,\n        0x50d0477, 0x511047d, 0x515048f, 0x51904a5, 0x2e80940, 0x2051f,\n        0x7180523, 0x6e0527, 0x3a4052b, 0x110052f, 0x6630533, 0x54b0537,\n        0x50a0476, 0x50e0478, 0x512047e, 0x5160490, 0x51a04a6, 0x2e90941,\n        0x30520, 0x7190524, 0x6f0528, 0x3a5052c, 0x1110530, 0x6640534,\n        0x54c0538, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x40000, 0xa0008, 0xe000c, 0x160010, 0x1a0018, 0x2ce001c, 0x2e602dc,\n        0x560308, 0x600058, 0x660062, 0x70006a, 0x780074, 0x80007c, 0x2aa0082,\n        0x60832, 0x64b0084, 0x2b805b5, 0x60d0609, 0x629061d, 0x1080106,\n        0x112010a, 0x11c0116, 0x12c0124, 0xffff0134, 0x50001, 0xb0009, 0xf000d,\n        0x170011, 0x1b0019, 0x2cf001d, 0x2e702dd, 0x570309, 0x610059, 0x670063,\n        0x71006b, 0x790075, 0x81007d, 0x2ab0083, 0x70833, 0x64c0085, 0x2b905b6,\n        0x60e060a, 0x62a061e, 0x1090107, 0x113010b, 0x11d0117, 0x12d0125,\n        0xffff0135, 0x4f404f3, 0x486055a, 0x29102b5, 0x48b0297, 0x2ba048c,\n        0x49302bb, 0x4980494, 0x49c02c7, 0xffff02cb, 0x2cd02cc, 0x2d4ffff,\n        0xffff02d5, 0xffffffff, 0xffffffff, 0xffffffff, 0x4b402ed, 0x2f902f8,\n        0x4ba04b9, 0x4bc04bb, 0x4be04bd, 0x4c204c1, 0x3250324, 0x32b032a,\n        0x3350334, 0x33d033c, 0x3410340, 0x34d034c, 0x34f034e, 0x3230322,\n        0x73f073e, 0x3ae03ad, 0x3b003af, 0x3b403b3, 0x3bf03be, 0x3d203d1,\n        0x3e203e1, 0x5a405a3, 0x6060605, 0x61a0619, 0x6320631, 0x6560655,\n        0x6a0069f, 0x46f046e, 0x7390738, 0x77e077d, 0x7d507d4, 0x8350834,\n        0x6df06de, 0x6a406a3, 0x150014, 0x5d005c, 0x4ee04ed, 0x5020501,\n        0x6120611, 0x1aa01a9, 0x5420541, 0x5540553, 0x5660565, 0x5760575,\n        0x5860585, 0x5960595, 0x5a805a7, 0x5b805b7, 0x1620161, 0x3a703a6,\n        0x3ea03e9, 0xffffffff, 0xffffffff, 0xffffffff, 0x60fffff, 0x6170610,\n        0xffff0618, 0xffffffff, 0x6240623, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x890087, 0x8d008b, 0x91008f,\n        0x950093, 0x990097, 0x9d009b, 0xa1009f, 0xa500a3, 0xa900a7, 0xad00ab,\n        0xb100af, 0xb500b3, 0xb900b7, 0xbd00bb, 0xc100bf, 0xc500c3, 0x4c004b8,\n        0x4d200cb, 0x4e600cf, 0x4f8ffff, 0xffffffff, 0xffffffff, 0x53affff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2d902d8, 0x6160615, 0x61c061b,\n        0x6220621, 0x6280627, 0x1e501e4, 0x62e062d, 0x6340633, 0x6380637,\n        0x63e063d, 0x6420641, 0x32f032e, 0x65e065d, 0x66e066d, 0x67c067b,\n        0x68a0689, 0x6980697, 0x6aa06a9, 0x6b806b7, 0x6c906c8, 0x6d706d6,\n        0x6e706e6, 0x6f506f4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7870786,\n        0x690068, 0x28f028e, 0x7b107b0, 0x7c907c8, 0x3bd03bc, 0x1f001e,\n        0x8030802, 0x8190818, 0x2b302b2, 0x8370836, 0x2d302d2, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x7ab07aa, 0x7af07ae, 0x7b307b2, 0x2eb02ea, 0x2f502f4, 0x3070306,\n        0x3110310, 0xffffffff, 0x7cb07ca, 0x7cf07ce, 0x7d307d2, 0x3330332,\n        0x33b033a, 0x33f033e, 0x3490348, 0x7e707e6, 0x7e907e8, 0x7eb07ea,\n        0x7ed07ec, 0x3ac03ab, 0x3b203b1, 0x3bb03ba, 0x7fb07fa, 0x3dc03db,\n        0x3f003ef, 0x620061f, 0x2830282, 0x8070806, 0x80b080a, 0x80f080e,\n        0x8130812, 0x8170816, 0x81b081a, 0x81f081e, 0x8210820, 0x4a0049f,\n        0x4b004af, 0x4c404c3, 0x4d604d5, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x545ffff, 0x8380546, 0x83b0839, 0x83d083c, 0x580057f,\n        0x590058f, 0x5a0059f, 0x5b205b1, 0xffffffff, 0x63bffff, 0x79b063c,\n        0xffffffff, 0x6080607, 0x60c060b, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x62c062b, 0x630062f, 0x6360635,\n        0x63a0639, 0x640063f, 0xffff0644, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x25e02f6, 0x2fc02fa, 0x30302fe, 0xffff0304, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x30cffff, 0x2c0030e,\n        0x3140312, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x7a8ffff, 0x7ac02da, 0x2e202e0, 0x7b402e4, 0x2f00724,\n        0x144076b, 0x30a0479, 0x318081c, 0x31a07c6, 0x7cc031c, 0x7d00320,\n        0x32c022c, 0x336007a, 0xffff046c, 0xffffffff, 0xffffffff, 0x7a9ffff,\n        0x7ad02db, 0x2e302e1, 0x7b502e5, 0x2f10725, 0x145076c, 0x30b047a,\n        0x319081d, 0x31b07c7, 0x7cd031d, 0x7d10321, 0x32d022d, 0x337007b,\n        0xffff046d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x9280012, 0x72005a, 0x3520338, 0x114010c, 0x2bc0625,\n        0x2f202ae, 0x31608ef, 0x10e064f, 0x2ee02b6, 0x4fb029a, 0x2c802be,\n        0x2de02d0, 0x47f0798, 0x330031e, 0x24e0342, 0x3b802c4, 0x47b03e5,\n        0x473056b, 0x72a06c4, 0x91104df, 0x9290013, 0x73005b, 0x3530339,\n        0x115010d, 0x2bd0626, 0x2f302af, 0x31708f0, 0x10f0650, 0x2ef02b7,\n        0x4fc029b, 0x2c902bf, 0x2df02d1, 0x4800799, 0x331031f, 0x24f0343,\n        0x3b902c5, 0x47c03e6, 0x474056c, 0x72b06c5, 0x91204e0, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff]);\n//4000 bytes\nenum alphaTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0x160], [0x100,\n        0x240, 0x5100], [0x3020100, 0x7060504, 0xb0a0908, 0xe0d0c0a, 0x3030303,\n        0x100a0f03, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a,\n        0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a,\n        0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a,\n        0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a,\n        0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x10000, 0x30002, 0x50004, 0x70006, 0x90008, 0xb000a, 0xd000c, 0xf000e,\n        0x10010, 0x120011, 0x10013, 0x150014, 0x170016, 0x190018, 0x1b001a,\n        0x1c0001, 0x1e001d, 0x1f001f, 0x1f0020, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x220021, 0x1f0023, 0x250024, 0x1f001f, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x260001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x270001, 0x10001, 0x10001, 0x10028,\n        0x2a0029, 0x2c002b, 0x2e002d, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x2f0001, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1001f, 0x310030, 0x320001,\n        0x340033, 0x360035, 0x380037, 0x1f0039, 0x1f001f, 0x3b003a, 0x3d003c,\n        0x1f003e, 0x1f001f, 0x40003f, 0x1f001f, 0x1f001f, 0x1f0041, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x10001, 0x420001, 0x1f0043, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x10001, 0x10001, 0x1f0044,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x10001, 0x1f0045, 0x1f001f,\n        0x46001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f0047, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x490048, 0x4b004a, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f004c,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x10001, 0x10001, 0x10001, 0x1004d, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x4e0001, 0x1f004f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x10001, 0x1f004f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f, 0x1f001f,\n        0x0, 0x0, 0x7fffffe, 0x7fffffe, 0x0, 0x4200400, 0xff7fffff, 0xff7fffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x3ffc3, 0x501f, 0x0, 0x0, 0x20, 0x3cdf0000,\n        0xffffd740, 0xfffffffb, 0xffffffff, 0xffbfffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xfffffc03, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xfffe00ff, 0x27fffff, 0xfffffffe, 0xff, 0xbfff0000,\n        0xffff00b6, 0x707ff, 0x7ff0000, 0xffffffff, 0xfeffffff, 0xffffc000,\n        0xffffffff, 0xffffffff, 0x1fefffff, 0x9c00e1fe, 0xffff0000, 0xffffffff,\n        0xffffe000, 0xffffffff, 0xffffffff, 0x3ffff, 0xfffffc00, 0x43007ff,\n        0xfcffffff, 0x1fff, 0x1ffffff, 0x0, 0x0, 0x1ffd, 0x0, 0x7fff03f0,\n        0xffffffff, 0xefffffff, 0xffe1dfff, 0xfefe000f, 0xfff99fee, 0xe3c5fdff,\n        0xb080599f, 0x3000f, 0xfff987ee, 0xc36dfdff, 0x5e021987, 0x3f0000,\n        0xfffbbfee, 0xe3edfdff, 0x11bbf, 0xf, 0xfff99fee, 0xe3edfdff,\n        0xb0c0199f, 0x2000f, 0xd63dc7ec, 0xc3ffc718, 0x811dc7, 0x0, 0xfffddfee,\n        0xe3effdff, 0x3601ddf, 0xf, 0xfffddfec, 0xe3effdff, 0x40601ddf,\n        0x6000f, 0xfffddfec, 0xe7ffffff, 0x805ddf, 0xfc00000f, 0xfc7fffec,\n        0x2ffbffff, 0xff5f807f, 0xc0000, 0xfffffffe, 0x7ffffff, 0x207f, 0x0,\n        0xfef02596, 0x3bffecae, 0xf000205f, 0x0, 0x1, 0x0, 0xfffffeff,\n        0xfffe1fff, 0xfeffff03, 0x1fffffff, 0x0, 0x0, 0xffffffff, 0xf97fffff,\n        0xffff0000, 0xffffc1e7, 0x3000407f, 0xffffffff, 0xffff20bf, 0xf7ffffff,\n        0xffffffff, 0xffffffff, 0x3d7f3dff, 0xffffffff, 0xffff3dff, 0x7f3dffff,\n        0xff7fff3d, 0xffffffff, 0xff3dffff, 0xffffffff, 0x87ffffff, 0x0,\n        0xffff, 0xffffffff, 0xffffffff, 0x1fffff, 0xfffffffe, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff9fff, 0x7fffffe, 0xffffffff,\n        0xffffffff, 0x1c7ff, 0xfdfff, 0xfffff, 0xfffff, 0xddfff, 0xffffffff,\n        0xffcfffff, 0x108001ff, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffff,\n        0xffffffff, 0xffff07ff, 0xffffffff, 0x3fffff, 0x1fffffff, 0x1ff0fff,\n        0xffff0000, 0x1f3fff, 0xffffffff, 0xffff0fff, 0x3ff, 0x0, 0xfffffff,\n        0xffffffff, 0x7fffffff, 0x1ffffe, 0x0, 0x80, 0x0, 0x0, 0xffffffff,\n        0xffefffff, 0xfef, 0x0, 0xffffffff, 0xfc00f3ff, 0xffffffff, 0x3ffbf,\n        0xffffffff, 0x3fffff, 0xfc00e000, 0x3fffffff, 0x0, 0x0, 0x0, 0x6fde00,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x0, 0x0, 0x3f3fffff, 0xffffffff, 0xaaff3f3f, 0x3fffffff, 0xffffffff,\n        0x5fdfffff, 0xfcf1fdc, 0x1fdc1fff, 0x0, 0x0, 0x0, 0x80020000,\n        0x1fff0000, 0x0, 0x0, 0x0, 0x3e2ffc84, 0xf3ffbd50, 0x43e0, 0xffffffff,\n        0x1ff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0xffc00000, 0xffffffff, 0x3ff, 0xffffffff, 0xffff7fff,\n        0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xc781f,\n        0xffffffff, 0xffff20bf, 0xffffffff, 0x80ff, 0x7fffff, 0x7f7f7f7f,\n        0x7f7f7f7f, 0xffffffff, 0x0, 0x8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xe0, 0x1f3e03fe, 0xfffffffe, 0xffffffff, 0xe07fffff, 0xfffffffe,\n        0xffffffff, 0xf7ffffff, 0xffffffe0, 0xfffe3fff, 0xffffffff, 0xffffffff,\n        0x7fff, 0x7ffffff, 0x0, 0xffff0000, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x3fffff, 0x0, 0x0, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1fff, 0x0,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1fff, 0x0,\n        0xffff0000, 0x3fffffff, 0xffff1fff, 0xc00, 0xffffffff, 0x8ff07fff,\n        0x80ffffff, 0xffffffff, 0xffffffff, 0xffff, 0xff800000, 0xfffffffc,\n        0xffffffff, 0xffffffff, 0xf79ff, 0x7ff, 0x0, 0xff000000, 0xfffff7bb,\n        0xff, 0xffffffff, 0xfffff, 0xffffffff, 0xffffffff, 0xf, 0x8fc0000,\n        0xfffffc00, 0xffff07ff, 0x7ffff, 0x1fffffff, 0xffffffff, 0xfff7ffff,\n        0x8000, 0x0, 0xffffffff, 0x7fffff, 0x3fff, 0x47fffff, 0xffffffff,\n        0x7fffffff, 0x38000005, 0x3cffff, 0x7e7e7e, 0x7f7f, 0x0, 0x0, 0x0, 0x0,\n        0xffffffff, 0x7ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff000f, 0xfffff87f, 0xfffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff3fff, 0xffffffff, 0xffffffff, 0x3ffffff, 0x0,\n        0xe0f8007f, 0x5f7ffdff, 0xffffffdb, 0xffffffff, 0xffffffff, 0x3ffff,\n        0xfff80000, 0xffffffff, 0xffffffff, 0x3fffffff, 0xffff0000, 0xffffffff,\n        0xfffcffff, 0xffffffff, 0xff, 0xfff0000, 0x0, 0x0, 0x0, 0xffdf0000,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x1fffffff, 0x0, 0x7fffffe,\n        0x7fffffe, 0xffffffc0, 0xffffffff, 0x7fffffff, 0x1cfcfcfc, 0x0,\n        0xffffefff, 0xb7ffff7f, 0x3fff3fff, 0x0, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x7ffffff, 0x0, 0x0, 0xffffffff, 0x1fffff, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x1fffffff, 0xffffffff, 0x1ffff, 0x0,\n        0x7fffffff, 0xffff0000, 0x7ff, 0x0, 0x3fffffff, 0xffffffff, 0x3eff0f,\n        0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffffff, 0x0,\n        0x0, 0x0, 0xfffffd3f, 0x91bfffff, 0x3fffff, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x3fffff, 0x3ffffff, 0x0, 0x0, 0xffffffff, 0xc0ffffff, 0x0, 0x0,\n        0xfeeff06f, 0xfffff, 0x0, 0x1fffffff, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0x3fffff, 0x3fffff, 0x7ffff, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0xffffffff, 0x1ff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff,\n        0x3f, 0x0, 0xfffffffc, 0x1ffffff, 0xffff0000, 0x1ff, 0xffffffff,\n        0x7ffff, 0x0, 0x0, 0xffffffff, 0xffffffff, 0x1e, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0xffffffff, 0x3fffff, 0x0, 0x0, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x7fff, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x7, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0x7fff, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0xffffffff, 0x1ffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xffffffff, 0xffffffff, 0xffff001f, 0x7fffffff, 0xfff80000, 0x0, 0x0,\n        0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff,\n        0xffdfffff, 0xffffffff, 0xdfffffff, 0xebffde64, 0xffffffef, 0xffffffff,\n        0xdfdfe7bf, 0x7bffffff, 0xfffdfc5f, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffff3f, 0xf7fffffd, 0xf7ffffff, 0xffdfffff, 0xffdfffff,\n        0xffff7fff, 0xffff7fff, 0xfffffdff, 0xfffffdff, 0xff7, 0x0, 0xffffffef,\n        0xaf7fe96, 0xaa96ea84, 0x5ef7f796, 0xffffbff, 0xffffbee, 0x0, 0x0,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x7fffff, 0x0, 0xffffffff, 0x1fffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffffff, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x3fffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n//2304 bytes\nenum markTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0xe0], [0x100,\n        0x140, 0x2c00], [0x2020100, 0x4020302, 0x6020205, 0x2070202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020208,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x10000, 0x30002, 0x50004, 0x70006, 0x90008, 0xb000a, 0xd000c, 0xe,\n        0xf0000, 0x0, 0x100000, 0x120011, 0x140013, 0x160015, 0x0, 0x17, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x190018, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x1d001c, 0x1f001e, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000, 0x0, 0x21, 0x220000, 0x0, 0x0,\n        0x0, 0x0, 0x23, 0x0, 0x0, 0x250024, 0x0, 0x0, 0x26, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x270000, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x280000,\n        0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a0000, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f8, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0xfffe0000, 0xbfffffff, 0xb6, 0x0, 0x7ff0000, 0x0,\n        0xfffff800, 0x10000, 0x0, 0x0, 0x9fc00000, 0x3d9f, 0x20000, 0xffff0000,\n        0x7ff, 0x0, 0x0, 0x1ffc0, 0x0, 0xff800, 0xfbc00000, 0x3eef, 0xe000000,\n        0x0, 0x0, 0x0, 0x0, 0x7ffffff0, 0xf, 0xdc000000, 0xfeffff, 0xc, 0xe,\n        0xd0000000, 0x80399f, 0xc, 0xe, 0xd0000000, 0x23987, 0x230000, 0xe,\n        0xd0000000, 0x3bbf, 0xc, 0xe, 0xd0000000, 0xc0399f, 0xc, 0x4,\n        0xc0000000, 0x803dc7, 0x0, 0xe, 0xc0000000, 0x603ddf, 0xc, 0xc,\n        0xd0000000, 0x603ddf, 0xc, 0xc, 0xc0000000, 0x803ddf, 0xc, 0xc, 0x0,\n        0xff5f8400, 0xc0000, 0x0, 0x7f20000, 0x7f80, 0x0, 0x0, 0x1bf20000,\n        0x3f00, 0x0, 0x3000000, 0xc2a00000, 0x0, 0xfffe0000, 0xfeffe0df,\n        0x1fffffff, 0x40, 0x0, 0x0, 0x7ffff800, 0xc3c00000, 0x1e3f9d,\n        0x3c00bffc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0000000, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x1c0000, 0x1c0000, 0xc0000, 0xc0000, 0x0, 0xfff00000, 0x200fffff,\n        0x0, 0x3800, 0x0, 0x0, 0x0, 0x0, 0x200, 0x0, 0x0, 0x0, 0xfff0fff, 0x0,\n        0x0, 0x0, 0xffff0000, 0x301, 0x0, 0xf800000, 0x0, 0x7fe00000,\n        0x9fffffff, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xfff00000, 0x1f, 0xff800, 0x7,\n        0x3ffe, 0x0, 0xfffc0, 0x0, 0xfffff0, 0x0, 0x0, 0x0, 0x0, 0xfff70000,\n        0x1c21ff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xf000007f, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0xffff0000, 0x1ffff, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x38000, 0x0, 0x0, 0x0, 0x80000000, 0x0, 0x0, 0x0,\n        0xffffffff, 0x0, 0xfc00, 0x0, 0x0, 0x6000000, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x3ff78000, 0x80000000, 0x0, 0x0, 0x30000, 0x844, 0xf8, 0x0, 0x0,\n        0x3, 0xfff00000, 0x1f, 0x3ffff, 0x0, 0x3fc0, 0xfff80, 0x0, 0xf,\n        0xfff80000, 0x1, 0x0, 0x0, 0x7ffe00, 0x3008, 0x8000000, 0x0,\n        0xc19d0000, 0x2, 0x60f800, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x37f8,\n        0x40000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff, 0x7f, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000,\n        0xf06e, 0x87000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff000000,\n        0x7f, 0x0, 0x7, 0x7ff0000, 0x0, 0x0, 0x7, 0x1fff80, 0x0, 0x0, 0x7,\n        0xfff80000, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfff800, 0x0, 0x0, 0x0,\n        0x0, 0xfffe0000, 0x7fffffff, 0x78000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xf807e3e0, 0xfe7, 0x3c00, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n//2384 bytes\nenum numberTrieEntries = TrieEntry!(bool, 8, 6, 7)([0x0, 0x40, 0x180], [0x100,\n        0x280, 0x1a80], [0x2020100, 0x4020302, 0x2020605, 0x8070202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x10000, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x40003, 0x50002,\n        0x20002, 0x70006, 0x60006, 0x90008, 0x6000a, 0x2000b, 0xc000c, 0x2000d,\n        0xe0005, 0x20002, 0x20002, 0x2000f, 0x20002, 0x20002, 0x100002,\n        0x110002, 0x2000e, 0x130012, 0x140002, 0xc, 0x20015, 0x20002, 0x20002,\n        0x20002, 0x170016, 0x190018, 0x20002, 0x20002, 0x1b001a, 0x20002,\n        0x20002, 0x1d001c, 0x20002, 0x20002, 0x20002, 0x20002, 0x1e0002,\n        0x20002, 0x20002, 0x20002, 0x2001f, 0x200002, 0x220021, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x60023, 0x20002, 0xc0024, 0xc0017, 0x2000c, 0x40002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x2000e, 0x20002, 0x260025, 0x20002,\n        0x280027, 0x230002, 0x20002, 0x20002, 0x20002, 0x20029, 0x2002a,\n        0x2002b, 0x2002c, 0x20002, 0x20002, 0x2002d, 0x20002, 0x4002e, 0xc002f,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x50002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20030, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20031, 0x20002, 0x20002, 0x20002, 0x320002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20033, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002,\n        0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x20002, 0x0,\n        0x3ff0000, 0x0, 0x0, 0x0, 0x720c0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x3ff, 0x0, 0x0, 0x0, 0x3ff0000, 0x0, 0x0, 0x3ff, 0x0,\n        0x0, 0x0, 0x0, 0xffc0, 0x0, 0x0, 0x0, 0x3f0ffc0, 0x0, 0x0, 0x0,\n        0xfcffc0, 0x0, 0x0, 0x0, 0x7ffc0, 0x0, 0x0, 0x0, 0x7f00ffc0, 0x0, 0x0,\n        0x0, 0x3fffc0, 0x0, 0x0, 0x3ff0000, 0x0, 0x0, 0xfffff, 0x0, 0x0,\n        0x3ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1ffffe00, 0x0, 0x0, 0x0,\n        0x1c000, 0x0, 0x0, 0x0, 0x3ff03ff, 0x0, 0x0, 0xffc0, 0x0, 0x0, 0x0,\n        0x7ff0000, 0x0, 0x3ff03ff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff03ff, 0x0,\n        0x0, 0x0, 0x0, 0x3f10000, 0x3ff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff0000,\n        0xffffffff, 0x3e7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xfffffff,\n        0x0, 0x0, 0xfffffc00, 0x0, 0x0, 0x0, 0xffc00000, 0xfffff, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x20000000, 0x80, 0x70003fe, 0x0, 0x0, 0x3c0000,\n        0x0, 0x0, 0x0, 0x0, 0x3ff, 0xfffeff00, 0x0, 0x3ff, 0xfffe0000, 0x0,\n        0x0, 0x0, 0x3ff, 0x0, 0x0, 0x0, 0x3f0000, 0x0, 0x0, 0xffffff80,\n        0xfffff, 0xffffffff, 0x1ffffff, 0x400, 0x0, 0x0, 0x0, 0x0, 0xf, 0x402,\n        0x0, 0x0, 0x0, 0x3e0000, 0x0, 0x0, 0x0, 0xff000000, 0x0, 0xfc00000,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x60000000, 0x0, 0x0, 0xff000000,\n        0xff000000, 0x0, 0x0, 0x0, 0x7fffffff, 0x0, 0x0, 0xfffc0000, 0xffff,\n        0x0, 0xffc00000, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0x7,\n        0x0, 0x0, 0x0, 0x3ffff, 0x0, 0x0, 0xffffc000, 0xffffffff, 0x7ff, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n//2336 bytes\nenum punctuationTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0xc0],\n        [0x100, 0x100, 0x3100], [0x2020100, 0x4020302, 0x2020605, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x10000, 0x20001, 0x30001, 0x50004, 0x70006, 0x10008, 0x90001,\n        0xb000a, 0x1000c, 0xd0001, 0x1000e, 0x10000f, 0x120011, 0x140013,\n        0x10015, 0x10001, 0x10016, 0x170001, 0x10001, 0x180001, 0x190001,\n        0x10001, 0x1b001a, 0x1001c, 0x1001d, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x1001e, 0x1001f,\n        0x210020, 0x230022, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x240001, 0x260025, 0x270001, 0x280001,\n        0x10001, 0x10001, 0x2a0029, 0x2c002b, 0x10001, 0x10001, 0x2e002d,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x1002f, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x0,\n        0x8c00f7ee, 0xb8000001, 0x28000000, 0x0, 0x88c00882, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000, 0x80,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0xfc000000, 0x0, 0x600, 0x40000000, 0x49,\n        0x180000, 0xc8003600, 0x0, 0x0, 0x3c00, 0x0, 0x0, 0x100000, 0x0,\n        0x3fff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3800000, 0x0, 0x7fff0000,\n        0x40000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10030, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x100000, 0x0, 0x0, 0xc008000, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x17fff0, 0x3c000000, 0x0, 0x0, 0x20, 0x0, 0x61f0000, 0x0, 0x0,\n        0x0, 0xfc00, 0x0, 0x0, 0x0, 0x0, 0x8000000, 0x0, 0x0, 0x0, 0x1ff, 0x0,\n        0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x6000, 0x18000000, 0x0, 0x0, 0x3800, 0x0, 0x600000, 0x0, 0x0, 0x0,\n        0x0, 0x7700000, 0x0, 0x7ff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0000000, 0x0, 0x0, 0x0, 0x0,\n        0x3f7f, 0x0, 0x0, 0x0, 0x0, 0xfc000000, 0x1, 0x0, 0x0, 0x0, 0xf0000000,\n        0x0, 0xf8000000, 0x0, 0xc0000000, 0x0, 0x0, 0x800ff, 0x0, 0xffff0000,\n        0xffff00ff, 0x7ffbffef, 0x60000000, 0x6000, 0x0, 0x0, 0x0, 0xf00,\n        0x600, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff00, 0x0, 0x0,\n        0x60, 0xffc0, 0x0, 0x0, 0x0, 0x0, 0x1fffff8, 0x0, 0xf000000,\n        0x30000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xde000000, 0x0, 0x0,\n        0x0, 0x10000, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xfff7fff, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0xfff3ff0e, 0x20010000, 0x0, 0x0, 0x0, 0x1, 0x0,\n        0x8000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0000000, 0xe000, 0x0,\n        0x0, 0x40080000, 0x0, 0x0, 0x0, 0xfc0000, 0x0, 0x0, 0x0, 0xf00000, 0x0,\n        0x0, 0xc000, 0x7000000, 0x0, 0xc000, 0x80000000, 0x0, 0x0, 0x0,\n        0xc0003ffe, 0x0, 0x0, 0x0, 0xf0000000, 0x0, 0x0, 0x0, 0xc0000000,\n        0x30000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800, 0x0, 0xc0000000,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff0000, 0xffff0000, 0xfff7ffff, 0xd0b,\n        0x0, 0x0, 0x0, 0x0, 0x8c00f7ee, 0xb8000001, 0xa8000000, 0x3f, 0x0, 0x0,\n        0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x80000000, 0x0, 0x10000, 0x0, 0x0, 0x0, 0x800000, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x80000000, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x1ff0000, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe000000, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f80, 0x0, 0x0, 0xd8000000, 0x3, 0x0,\n        0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x1e0, 0x0, 0x0, 0x0, 0x0, 0xf0000, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n//2848 bytes\nenum symbolTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0xe0], [0x100,\n        0x140, 0x3d00], [0x3020100, 0x5030403, 0x3030306, 0x8070303, 0x3030303,\n        0x3030303, 0x3030303, 0x3030303, 0x3030303, 0x3030303, 0x3030303,\n        0x3030303, 0x3030303, 0x3030303, 0x3030303, 0x3030303, 0x3030303,\n        0x3030303, 0x3030303, 0x3030303, 0x3030303, 0x3030303, 0x3030303,\n        0x3030303, 0x3030303, 0x3030303, 0x3030303, 0x3030303, 0x3030303,\n        0x3030303, 0x3030303, 0x3030303, 0x3030303, 0x3030303, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x10000, 0x30002, 0x50004, 0x70006, 0x80001, 0xa0009, 0xc000b, 0xe000d,\n        0x1000f, 0x100001, 0x10001, 0x110001, 0x120001, 0x130001, 0x10001,\n        0x140001, 0x160015, 0x180017, 0x170019, 0x1a0017, 0x1b0017, 0x1c0017,\n        0x1001d, 0x1f001e, 0x210020, 0x170022, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x230001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10024,\n        0x250001, 0x10026, 0x10027, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x280001, 0x290001, 0x2b002a, 0x2c0001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x2e002d, 0x30002f, 0x10001, 0x320031, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10033, 0x350034, 0x370036, 0x390038, 0x3b003a, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x0, 0x70000810, 0x40000000, 0x50000001, 0x0,\n        0x113d37c, 0x800000, 0x800000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfffc003c, 0xffffafe0, 0x0, 0x0, 0x0,\n        0x200000, 0x30, 0x0, 0x0, 0x400000, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x8000, 0x0, 0x0, 0x0, 0xc9c0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x40000000, 0x60000200, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x400000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0c0000, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x20000, 0x0, 0x0, 0x0, 0x10000, 0x0, 0x0, 0x0,\n        0x7f80000, 0x0, 0x0, 0x0, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x2000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0xfce8000e, 0x1500000, 0x0, 0x0, 0x0, 0xc0000000,\n        0x1e0dfbf, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0000000, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x3ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x8000000, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xc0000000, 0xffffffff,\n        0x0, 0x0, 0x0, 0x1ff007fe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xa0000000, 0xe000e003, 0x6000e000, 0x0, 0x0, 0x40010, 0x1c000000,\n        0x1c00, 0x7ffffff, 0x0, 0x0, 0xc1d0037b, 0xc0042af, 0xbc1f, 0x0,\n        0xffff0000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xfffff0ff, 0xfffff9ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xfffff, 0xffffffff, 0x7f, 0x7ff, 0x0, 0xf0000000,\n        0xffffffff, 0xffffffff, 0x3ff, 0xfffffffe, 0xffffffff, 0xffffffff,\n        0xff, 0xfff00000, 0xffffffff, 0xffffff9f, 0xffff003f, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xfe000007, 0xffffffff, 0xf0ffffff,\n        0xcfffffff, 0xffffffff, 0xffffffff, 0x3ff1fff, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7e0, 0x0, 0x0, 0x0, 0x0,\n        0xfbffffff, 0xffffffff, 0xffffffff, 0xfffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffff, 0xfff0000,\n        0xc0010, 0xc0c00001, 0x0, 0x0, 0x18000000, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0xffc30000, 0x0, 0xffffffff, 0xf, 0x7fffffff, 0xfffffc00,\n        0x100ff, 0xffffffff, 0xfffffc00, 0x1ffff, 0xffffffff, 0x7fffffff, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0x0, 0x0, 0x0, 0x0,\n        0xffff0000, 0xffffffff, 0x7f, 0x0, 0x7fffff, 0x3, 0x0, 0x0, 0x600, 0x0,\n        0x0, 0x0, 0x0, 0x3c00f00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x3800000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200, 0x0, 0x0, 0x0, 0xfffc0000,\n        0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30000000, 0x0, 0x0, 0x0,\n        0x274, 0x0, 0x0, 0x0, 0x0, 0x70000810, 0x40000000, 0x50000001, 0x0,\n        0x0, 0x0, 0x0, 0x30007f7f, 0x0, 0xff800000, 0x0, 0xfe000000, 0xfff03ff,\n        0x0, 0xffff0000, 0x1fffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffff, 0xffffffff,\n        0xfffffe7f, 0xffffffff, 0x1c1f, 0xfffff018, 0xffffc3ff, 0x3fffffff,\n        0x0, 0xffffffff, 0xffffffff, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0xffffffff, 0x7fffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x8000002, 0x8000000, 0x200000, 0x200000, 0x8000, 0x8000, 0x200,\n        0x200, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30000,\n        0xffffffff, 0xffff0fff, 0xffffffff, 0xffffffff, 0xfffff, 0x7ffe7fff,\n        0xfffefffe, 0x0, 0xffff0000, 0xffff7fff, 0xffffffff, 0xffff0fff,\n        0x7ffffff, 0x0, 0x0, 0xffffffc0, 0xffff0007, 0x7ffffff, 0x301ff, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffbf0001, 0xffffffff, 0x1fffffff,\n        0xfffff, 0xffffffff, 0x7df, 0x1ffff, 0xffffffff, 0x7fffffff,\n        0xfffffffd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1effffff,\n        0xffffffff, 0x3fffffff, 0xffff000f, 0xff, 0x0, 0x0, 0x0, 0xf8000000,\n        0xffffffff, 0xffffffff, 0xffe1, 0x0, 0xffffffff, 0xffffffff, 0x3f, 0x0,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xfffff, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n//4576 bytes\nenum graphicalTrieEntries = TrieEntry!(bool, 8, 5, 8)([0x0, 0x40, 0x170],\n        [0x100, 0x260, 0x6100], [0x3020100, 0x7060504, 0xb0a0908, 0xe0d0c0a,\n        0x3030303, 0x100a0f03, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a,\n        0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a,\n        0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a,\n        0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a,\n        0xa0a0a11, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0xa0a0a0a, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x10000, 0x20001, 0x30001, 0x50004, 0x70006, 0x90008, 0xb000a,\n        0xd000c, 0x1000e, 0x10000f, 0x10001, 0x120011, 0x140013, 0x160015,\n        0x180017, 0x190001, 0x1b001a, 0x1c0001, 0x1001d, 0x1e0001, 0x10001,\n        0x1f0001, 0x210020, 0x230022, 0x250024, 0x10026, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x270001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x280001, 0x10001, 0x10001,\n        0x10029, 0x2b002a, 0x2d002c, 0x2f002e, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001,\n        0x10001, 0x10001, 0x300001, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x10031, 0x330032,\n        0x340001, 0x360035, 0x380037, 0x3a0039, 0x31003b, 0x310031, 0x3d003c,\n        0x3f003e, 0x310040, 0x310041, 0x430042, 0x310031, 0x310031, 0x310044,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x10001, 0x450001, 0x310046,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x10001, 0x10001,\n        0x310047, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x10001, 0x310048,\n        0x310031, 0x490031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x31004a, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x4c004b,\n        0x4e004d, 0x50004f, 0x520051, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310053, 0x550054, 0x570056, 0x590058, 0x5b005a, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x10001, 0x10001, 0x10001, 0x1005c, 0x10001,\n        0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x5d0001,\n        0x31005e, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x10001, 0x31005e, 0x310031, 0x310031, 0x5f0031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031, 0x310031,\n        0x310031, 0x310031, 0x310031, 0x0, 0xffffffff, 0xffffffff, 0x7fffffff,\n        0x0, 0xffffdfff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x7cffffff, 0xffffd7f0, 0xfffffffb,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xfffe00ff, 0xfe7fffff, 0xfffffffe,\n        0xfffe86ff, 0xffffffff, 0xffff00ff, 0x1f07ff, 0xcfffffc0, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xdfffffff, 0xffffffff,\n        0xffff3fff, 0xffffffff, 0xffffe7ff, 0xffffffff, 0xffffffff, 0x3ffff,\n        0xffffffff, 0x7ffffff, 0xffffffff, 0x7fff3fff, 0x4fffffff, 0x0, 0x0,\n        0x1ffd, 0x0, 0x7ffffff0, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xfeffffff, 0xfff99fee, 0xf3c5fdff, 0xb080799f, 0xfffffcf, 0xfff987ee,\n        0xd36dfdff, 0x5e023987, 0x3fffc0, 0xfffbbfee, 0xf3edfdff, 0x13bbf,\n        0x3ffcf, 0xfff99fee, 0xf3edfdff, 0xb0c0399f, 0xffffcf, 0xd63dc7ec,\n        0xc3ffc718, 0x813dc7, 0x7ffffc0, 0xfffddfee, 0xe3effdff, 0x3603ddf,\n        0xff00ffcf, 0xfffddfec, 0xf3effdff, 0x40603ddf, 0x6ffcf, 0xfffddfec,\n        0xe7ffffff, 0x807ddf, 0xfe3fffcf, 0xfc7fffec, 0x2ffbffff, 0xff5f847f,\n        0x1c0000, 0xfffffffe, 0x87ffffff, 0xfffffff, 0x0, 0xfef02596,\n        0x3bffecae, 0xf3ff3f5f, 0x0, 0xffffffff, 0xffffffff, 0xfffffeff,\n        0xfffe1fff, 0xfeffffff, 0xdfffffff, 0x7ffdfff, 0x0, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff20bf,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x3d7f3dff, 0xffffffff, 0xffff3dff,\n        0x7f3dffff, 0xff7fff3d, 0xffffffff, 0xff3dffff, 0xffffffff, 0xe7ffffff,\n        0x1fffffff, 0x3ffffff, 0xffffffff, 0xffffffff, 0x1fffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x1fffffff, 0xffffffff, 0xffffffff,\n        0x1ffff, 0x1fdfff, 0x7fffff, 0xfffff, 0xddfff, 0xffffffff, 0xffffffff,\n        0x3fffffff, 0x3ff03ff, 0x3ff3fff, 0xffffffff, 0xffffffff, 0xffffff,\n        0xffffffff, 0xffff07ff, 0xffffffff, 0x3fffff, 0x1fffffff, 0xfff0fff,\n        0xfffffff1, 0x1f3fff, 0xffffffff, 0xffff0fff, 0xc7ff03ff, 0xffffffff,\n        0xcfffffff, 0xffffffff, 0x7fffffff, 0x9fffffff, 0x3ff03ff, 0x3fff, 0x0,\n        0x0, 0xffffffff, 0xffffffff, 0xffff0fff, 0x1fffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xf00fffff, 0xffffffff, 0xf8ffffff, 0xffffe3ff,\n        0xffffffff, 0x0, 0x0, 0xffff00ff, 0x7fffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xf000007f,\n        0x3f3fffff, 0xffffffff, 0xaaff3f3f, 0x3fffffff, 0xffffffff, 0xffdfffff,\n        0xefcfffdf, 0x7fdcffff, 0xffff07ff, 0xffff80ff, 0xffffffff, 0xfff30000,\n        0x1fff7fff, 0x7ffffff, 0xffff0000, 0x1ffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffff03ff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xfffff, 0xffffffff, 0x7f, 0x7ff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x3ff1fff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffff7fff,\n        0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfe0fffff,\n        0xffffffff, 0xffff20bf, 0xffffffff, 0x800180ff, 0x7fffff, 0x7f7f7f7f,\n        0x7f7f7f7f, 0xffffffff, 0xffffffff, 0xfffffff, 0x0, 0x0, 0xfbffffff,\n        0xffffffff, 0xffffffff, 0xfffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x3fffff, 0xfff0000, 0xffffffff,\n        0xffffffff, 0xfffffffe, 0xffffffff, 0xfe7fffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffe0, 0xfffe3fff, 0xffffffff, 0xffffffff, 0xffff7fff,\n        0x7ffffff, 0xffffffff, 0xffff000f, 0x7fffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x1fff, 0x0, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff1fff, 0xffffffff, 0xffff007f, 0xffffffff, 0xffffffff,\n        0xfff, 0xffffffff, 0xffffffff, 0x80ffffff, 0xffffffff, 0xffffffff,\n        0xffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xf7fff,\n        0x7ff, 0x0, 0xff000000, 0xffffffff, 0x3ff0fff, 0xffffffff, 0xffffff,\n        0xffffffff, 0xffffffff, 0x3ffc01f, 0xfffffff, 0xffffffff, 0xffffffff,\n        0x800fffff, 0x1fffffff, 0xffffffff, 0xffffffff, 0xc3ffbfff, 0x0,\n        0xffffffff, 0x7fffff, 0xf3ff3fff, 0xfffffff, 0xffffffff, 0xffffffff,\n        0xf8000007, 0x7fffff, 0x7e7e7e, 0x7f7f, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0x3ff3fff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff000f, 0xfffff87f, 0xfffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff3fff, 0xffffffff,\n        0xffffffff, 0x3ffffff, 0x0, 0xe0f8007f, 0x5f7fffff, 0xffffffdb,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xfff80003, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff0000, 0xffffffff, 0xfffcffff, 0xffffffff, 0xff,\n        0x3fff0000, 0x3ffffff, 0xffff007f, 0xfff7ffff, 0xffdf0f7f, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x1fffffff, 0xfffffffe, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x7fffffff, 0x1cfcfcfc, 0x30007f7f, 0xffffefff,\n        0xb7ffff7f, 0x3fff3fff, 0x0, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x7ffffff, 0xffffff87, 0xff8fffff, 0xffffffff, 0xffffffff, 0xfff07ff,\n        0x0, 0xffff0000, 0x3fffffff, 0x0, 0x0, 0x0, 0x0, 0x1fffffff,\n        0xffffffff, 0x1ffff, 0x0, 0x7fffffff, 0xffff000f, 0x7ff, 0x0,\n        0xbfffffff, 0xffffffff, 0x3fff0f, 0x0, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x3fffffff, 0x3ff, 0x0, 0x0, 0xfffffd3f,\n        0x91bfffff, 0xffbfffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8fffffff,\n        0x83ffffff, 0x0, 0x0, 0xffffffff, 0xc0ffffff, 0x0, 0x0, 0xfeeff06f,\n        0x870fffff, 0x1ff00ff, 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0xfe3fffff, 0xff3fffff, 0xff07ffff, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0xffffffff, 0x1ff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7fffffff,\n        0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xfffc3fff, 0xffff,\n        0xffffffff, 0xdfffffff, 0xffff0003, 0x3ff01ff, 0xffffffff, 0xffdfffff,\n        0xf, 0x0, 0xffffffff, 0xffffffff, 0x3ff01ff, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xffffffff, 0xffffff, 0x3ff, 0x0, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x7fff, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xf0007, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0x7fff, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0xffffffff, 0x1ffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xffffffff, 0xffffffff, 0xffff001f, 0x7fffffff, 0xffff8000, 0x0, 0x0,\n        0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffff,\n        0xffffffff, 0xfffffe7f, 0xffffffff, 0xf807ffff, 0xffffffff, 0xffffffff,\n        0x3fffffff, 0x0, 0xffffffff, 0xffffffff, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xffffffff, 0xffffffff, 0x7fffff, 0x3ffff, 0x0, 0x0, 0x0, 0x0,\n        0xffffffff, 0xffffffff, 0xffdfffff, 0xffffffff, 0xdfffffff, 0xebffde64,\n        0xffffffef, 0xffffffff, 0xdfdfe7bf, 0x7bffffff, 0xfffdfc5f, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffff3f, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffcfff, 0xffffffff, 0xffffffef, 0xaf7fe96, 0xaa96ea84, 0x5ef7f796,\n        0xffffbff, 0xffffbee, 0x0, 0x30000, 0xffffffff, 0xffff0fff, 0xffffffff,\n        0xffffffff, 0xfffff, 0x7ffe7fff, 0xfffefffe, 0x0, 0xffff07ff,\n        0xffff7fff, 0xffffffff, 0xffff0fff, 0x7ffffff, 0x0, 0x0, 0xffffffc0,\n        0xffff0007, 0x7ffffff, 0x301ff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0xffbf0001, 0xffffffff, 0x1fffffff, 0xfffff, 0xffffffff, 0x7df,\n        0x1ffff, 0xffffffff, 0x7fffffff, 0xfffffffd, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x1effffff, 0xffffffff, 0x3fffffff, 0xffff000f,\n        0xff, 0x0, 0x0, 0x0, 0xf8000000, 0xffffffff, 0xffffffff, 0xffe1, 0x0,\n        0xffffffff, 0xffffffff, 0x3f, 0x0, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xfffff, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x7fffff, 0x0, 0xffffffff,\n        0x1fffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x3fffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);\n//3664 bytes\nenum nonCharacterTrieEntries = TrieEntry!(bool, 7, 4, 4, 6)([0x0, 0x20, 0x98,\n        0x208], [0x80, 0xf0, 0x2e0, 0x3180], [0x3020100, 0x7060504, 0xa090808,\n        0xb0b0b0b, 0xb0b0b0b, 0xb0b0b0b, 0xb0b0b0b, 0xb0b0b0b, 0xb0b0b0b,\n        0xb0b0b0b, 0xb0b0b0b, 0xb0b0b0b, 0xb0b0b0b, 0xb0b0b0b, 0xb0b0b0c,\n        0xd080808, 0xd080808, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x30002, 0x50004, 0x70006, 0x90008,\n        0xb000a, 0xd000c, 0xd000d, 0xd000d, 0xe000d, 0xd000d, 0xd000d, 0xd000d,\n        0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xf000d,\n        0x10000d, 0xd0011, 0xd000d, 0xd000d, 0xd000d, 0xd000d, 0x12000d,\n        0xd000d, 0xd000d, 0xd000d, 0xd000d, 0x140013, 0x160015, 0x180017,\n        0x1a0019, 0x1b001b, 0x1d001c, 0x1b001b, 0x1e000d, 0x1b001b, 0x1b001b,\n        0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b, 0x20001f, 0x1b001b, 0x1b001b,\n        0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b, 0x1b0021,\n        0x1b001b, 0x1b001b, 0x1b001b, 0x230022, 0x1b001b, 0x1b001b, 0x24001b,\n        0x260025, 0x1b001b, 0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d,\n        0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d,\n        0x27000d, 0xd000d, 0x28000d, 0x1b0029, 0x1b001b, 0x1b001b, 0x1b001b,\n        0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b, 0x1b002a, 0x1b001b, 0x1b001b,\n        0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b, 0x1b002b,\n        0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b, 0x1b001b,\n        0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d,\n        0x2c000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d, 0xd000d,\n        0xd000d, 0x2c000d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x2, 0x0,\n        0x0, 0x40003, 0x60005, 0x7, 0x0, 0x90008, 0xb000a, 0xd000c, 0xf000e,\n        0x100000, 0x120011, 0x140013, 0x160015, 0x180017, 0x1a0019, 0x1c001b,\n        0x1e001d, 0x20001f, 0x220021, 0x240023, 0x260025, 0x270000, 0x290028,\n        0x0, 0x2a0000, 0x0, 0x0, 0x2b0000, 0x2d002c, 0x2f002e, 0x310030, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x330032, 0x350034, 0x360000, 0x380037, 0x3a0039,\n        0x3c003b, 0x3e003d, 0x40003f, 0x420041, 0x430000, 0x440000, 0x460045,\n        0x470042, 0x0, 0x480000, 0x0, 0x0, 0x4a0049, 0x4c004b, 0x4d0000,\n        0x4f004e, 0x0, 0x50, 0x0, 0x0, 0x0, 0x510000, 0x530052, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x550000, 0x420042,\n        0x570056, 0x580000, 0x5a0059, 0x5c005b, 0x42005d, 0x51005e, 0x0,\n        0x5f0000, 0x540000, 0x60, 0x61, 0x630062, 0x57, 0x640000, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x650000, 0x0, 0x670066,\n        0x0, 0x0, 0x68, 0x380069, 0x0, 0x6b006a, 0x38006c, 0x6d0000, 0x6e0000,\n        0x6f0000, 0x710070, 0x720000, 0x420073, 0x740042, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x750063, 0x0, 0x0, 0x0, 0x0, 0x760000, 0x770000,\n        0x790078, 0x7a0000, 0x0, 0x0, 0x7b0000, 0x7d007c, 0x7f007e, 0x800000,\n        0x54, 0x810064, 0x830082, 0xb0000, 0x84, 0x860085, 0x420042, 0x870032,\n        0x890088, 0x8b008a, 0x0, 0x42008c, 0x420042, 0x420042, 0x420042,\n        0x420042, 0x420042, 0x420042, 0x8e008d, 0x420042, 0x42008f, 0x420090,\n        0x920091, 0x420042, 0x940093, 0x420042, 0x950000, 0x420042, 0x420042,\n        0x420042, 0x960042, 0x420042, 0x420042, 0x420042, 0x970000, 0x980000,\n        0x99004b, 0x9a0000, 0x420042, 0x420042, 0x420042, 0x420042, 0x420042,\n        0x420042, 0x420042, 0x420042, 0x420042, 0x9b0038, 0x420042, 0x420042,\n        0x420042, 0x420042, 0x420042, 0x420042, 0x420042, 0x420042, 0x420042,\n        0x420042, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9c0000, 0x420042, 0x9d0000,\n        0x420042, 0x420042, 0x420042, 0x420042, 0x420042, 0x420042, 0x420042,\n        0x42009c, 0x420042, 0x420042, 0x420042, 0x420042, 0x420042, 0x420042,\n        0x420042, 0x0, 0x0, 0x0, 0x0, 0x42009e, 0x420042, 0x420042, 0x420042,\n        0x420042, 0x420042, 0x420042, 0x420042, 0x420042, 0x420042, 0x9f0000,\n        0x4200a0, 0x4200a1, 0x420042, 0x420042, 0x420042, 0x420042, 0x420042,\n        0x420042, 0x420042, 0x0, 0x3a0000, 0xa2, 0xa30000, 0xa40000, 0x420042,\n        0xa50000, 0x420042, 0xa60000, 0xa800a7, 0xaa00a9, 0x0, 0x0, 0xab, 0x0,\n        0xac0000, 0x420042, 0x420042, 0x420042, 0x420042, 0xae00ad, 0xb000af,\n        0x420042, 0x420042, 0x3d, 0xb200b1, 0x3d00b3, 0xb500b4, 0xb700b6,\n        0x420042, 0xb900b8, 0xbb00ba, 0xbc0064, 0xbd0000, 0xbf00be, 0xc00042,\n        0xc10000, 0xa40000, 0x510000, 0x420042, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0xc20000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x4200a3,\n        0x420042, 0x420042, 0x420042, 0x420042, 0x420042, 0x420042, 0x420042,\n        0x0, 0x0, 0x0, 0x0, 0x4200a3, 0x420042, 0x420042, 0x420042, 0xc3,\n        0x420042, 0x0, 0xc40000, 0x420042, 0x420042, 0x420042, 0x420042, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbe0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0xbe0000, 0x0, 0x0, 0x0, 0x83000000, 0x280f, 0x4, 0x0, 0x1ff00,\n        0x1800000, 0x1, 0x17900, 0x0, 0xff00, 0xffe0f800, 0x20000020, 0x0,\n        0x4000, 0x0, 0x1800, 0x0, 0x0, 0xfffc0000, 0x0, 0xf8000000, 0x0,\n        0x8000c000, 0xb0000000, 0xffffffff, 0xffffffff, 0xffffe002, 0xffffffff,\n        0x8000000f, 0x0, 0x1000000, 0x66011, 0xc3a0200, 0x4f7f8660, 0xf0000030,\n        0x67811, 0x2c920200, 0xa1fdc678, 0xffc0003f, 0x44011, 0xc120200,\n        0xfffec440, 0xfffc0030, 0x66011, 0xc120200, 0x4f3fc660, 0xff000030,\n        0x29c23813, 0x3c0038e7, 0xff7ec238, 0xf800003f, 0x22011, 0x1c100200,\n        0xfc9fc220, 0xff0030, 0x22013, 0xc100200, 0xbf9fc220, 0xfff90030,\n        0x22013, 0x18000000, 0xff7f8220, 0x1c00030, 0x3800013, 0xd0040000,\n        0xa07b80, 0xffe3ffff, 0x1, 0x78000000, 0xf0000000, 0xffffffff,\n        0x10fda69, 0xc4001351, 0xc00c0a0, 0xffffffff, 0x100, 0x1e000,\n        0x1000000, 0x20000000, 0xf8002000, 0xffffffff, 0xdf40, 0x0, 0xc280c200,\n        0x0, 0xc200, 0x80c20000, 0x8000c2, 0x0, 0xc20000, 0x0, 0x18000000,\n        0xe0000000, 0xfc000000, 0x0, 0x0, 0xffe00000, 0xe0000000, 0x0, 0x0,\n        0xfffe0000, 0xffe02000, 0xff800000, 0xfff00000, 0xfff22000, 0xc0000000,\n        0xfc00fc00, 0xfc008000, 0x0, 0x0, 0xff000000, 0x0, 0xf800, 0x0,\n        0xffc00000, 0xe0000000, 0xf000f000, 0xe, 0xffe0c000, 0x0, 0xf000,\n        0x3800fc00, 0x0, 0x30000000, 0x0, 0x80000000, 0x60000000, 0xfc00fc00,\n        0xffffc000, 0xffffffff, 0xffffffff, 0xf000, 0xe0000000, 0x0, 0xff00000,\n        0x0, 0x7000000, 0x1c00, 0x0, 0xff00, 0xff800000, 0x0, 0xfffff80,\n        0xc0c00000, 0x0, 0x5500c0c0, 0xc0000000, 0x0, 0x200000, 0x10300020,\n        0x80230000, 0x0, 0xc0020, 0xe0008000, 0xf8000000, 0xffff, 0xfffe0000,\n        0xfc00, 0x0, 0x0, 0xfff00000, 0x0, 0xffffff80, 0xfffff800, 0x0, 0x1,\n        0x0, 0xfc00e000, 0xffffffff, 0x0, 0x8000, 0x80000000, 0x0, 0x0,\n        0x1f00000, 0x0, 0xdf40, 0x0, 0x7ffe7f00, 0xff800000, 0x80808080,\n        0x80808080, 0x0, 0x0, 0xf0000000, 0x4000000, 0x0, 0xffc00000,\n        0xf000ffff, 0x1800000, 0x0, 0x1f, 0x1c000, 0x8000, 0xf8000000, 0x0,\n        0xfff0, 0x0, 0x80000000, 0xffffe000, 0xffffffff, 0xe000, 0x0, 0xff80,\n        0x0, 0x0, 0xfffff000, 0x7f000000, 0x0, 0xfff08000, 0xfffff800,\n        0xffffffff, 0xffffff, 0x0, 0xfc00f000, 0xfc003fe0, 0xf0000000,\n        0x7ff00000, 0xe0000000, 0x3c004000, 0xffffffff, 0x0, 0xff800000,\n        0xc00c000, 0xf0000000, 0x7fffff8, 0xff800000, 0xff818181, 0xffff8080,\n        0x0, 0xfc00c000, 0x780, 0xf0000000, 0x0, 0xc000, 0xfc000000,\n        0xffffffff, 0x1f07ff80, 0xa0800000, 0x24, 0x0, 0x7fffc, 0x0, 0xffff,\n        0x0, 0x30000, 0x0, 0xffffff00, 0xc000ffff, 0xfc000000, 0xff80, 0x80000,\n        0x20f080, 0x0, 0x60000000, 0xe3030303, 0xc1ff8080, 0x1000, 0x48000080,\n        0xc000c000, 0xffffffff, 0x78, 0x700000, 0xf000f800, 0xffffffff, 0xffff,\n        0xc0000000, 0xfffe0000, 0xffffffff, 0x80000000, 0xfff0, 0xfffff800,\n        0xffffffff, 0x40000000, 0x0, 0xffc000f0, 0xffffffff, 0xc0000000,\n        0xfffffc00, 0x2c0, 0x6e400000, 0x400000, 0xffffffff, 0x70000000,\n        0x7c000000, 0x0, 0x3f000000, 0x1100f90, 0x78f00000, 0xfe00ff00, 0x0,\n        0x0, 0x1c00000, 0xc00000, 0xf80000, 0xfffffe00, 0xffffffff, 0xffffffff,\n        0x80000000, 0x3c000, 0xffff0000, 0xfffc, 0xfc00fe00, 0xfffffff0,\n        0xffffffff, 0xfc00fe00, 0xffffffff, 0xfffffc00, 0xffffffff, 0x0,\n        0xffff8000, 0x0, 0xfff0fff8, 0x0, 0xfe000000, 0xffe0, 0x80000000,\n        0x7fff, 0xffffffff, 0xfffffffc, 0xffffffff, 0x0, 0x180, 0xc0000000,\n        0xffffffff, 0xffffffc0, 0xffffffff, 0xff800000, 0xfffc0000, 0x200000,\n        0x0, 0x20000000, 0x1400219b, 0x10, 0x0, 0x20201840, 0x84000000,\n        0x203a0, 0x0, 0x0, 0xc0, 0x3000, 0x0, 0x10, 0xf5080169, 0x5569157b,\n        0xa1080869, 0xf0000400, 0xf0000411, 0xffffffff, 0xfffcffff, 0xfff00000,\n        0x80018000, 0x10001, 0xffffffff, 0xf800, 0x8000, 0xf8000000,\n        0xffffffff, 0xffffffff, 0x3f, 0xfff8, 0xf8000000, 0xfffcfe00,\n        0xffffffff, 0x0, 0x40fffe, 0x0, 0xe0000000, 0xfff00000, 0x0,\n        0xfffff820, 0xfffe0000, 0x2, 0x0, 0x0, 0xe1000000, 0x0, 0xc0000000,\n        0xfff0, 0xffffff00, 0xffffffff, 0x7ffffff, 0xffff001e, 0xffffffff,\n        0xff800000, 0xffffffff, 0xfffffffd, 0x0, 0x0, 0xffff0000, 0x0, 0xc0000000]);\nenum MAX_SIMPLE_LOWER = 1043;\nenum MAX_SIMPLE_UPPER = 1051;\nenum MAX_SIMPLE_TITLE = 1055;\n//8192 bytes\nenum toUpperIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x40, 0x200],\n        [0x100, 0x380, 0xc00], [0x2020100, 0x4020302, 0x2020205, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x10000, 0x30002, 0x50004, 0x70006, 0x90008, 0xa, 0xb0000, 0xd000c,\n        0xf000e, 0x110010, 0x130012, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x150000, 0x0,\n        0x170016, 0x190018, 0x1b001a, 0x1d001c, 0x0, 0x0, 0x1e0000, 0x1f, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x200000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x220021, 0x240023, 0x25, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x260000,\n        0x27, 0x290028, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x2c0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x2e002d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff, 0x20001,\n        0x40003, 0x60005, 0x80007, 0xa0009, 0xc000b, 0xe000d, 0x10000f,\n        0x120011, 0x140013, 0x160015, 0x180017, 0xffff0019, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x1affff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x41bffff, 0x1c001b, 0x1e001d, 0x20001f, 0x220021, 0x240023, 0x260025,\n        0x280027, 0x2a0029, 0x2c002b, 0x2e002d, 0x30002f, 0xffff0031, 0x330032,\n        0x350034, 0x370036, 0x390038, 0x3affff, 0x3bffff, 0x3cffff, 0x3dffff,\n        0x3effff, 0x3fffff, 0x40ffff, 0x41ffff, 0x42ffff, 0x43ffff, 0x44ffff,\n        0x45ffff, 0x46ffff, 0x47ffff, 0x48ffff, 0x49ffff, 0x4affff, 0x4bffff,\n        0x4cffff, 0x4dffff, 0x4effff, 0x4fffff, 0x50ffff, 0x51ffff, 0x52041d,\n        0x53ffff, 0x54ffff, 0x55ffff, 0xffffffff, 0xffff0056, 0xffff0057,\n        0xffff0058, 0xffff0059, 0xffff005a, 0xffff005b, 0xffff005c, 0x43a005d,\n        0x5effff, 0x5fffff, 0x60ffff, 0x61ffff, 0x62ffff, 0x63ffff, 0x64ffff,\n        0x65ffff, 0x66ffff, 0x67ffff, 0x68ffff, 0x69ffff, 0x6affff, 0x6bffff,\n        0x6cffff, 0x6dffff, 0x6effff, 0x6fffff, 0x70ffff, 0x71ffff, 0x72ffff,\n        0x73ffff, 0x74ffff, 0xffffffff, 0xffff0075, 0xffff0076, 0x780077,\n        0xffff0079, 0x7affff, 0x7bffff, 0xffffffff, 0xffff007c, 0xffffffff,\n        0xffff007d, 0xffffffff, 0xffffffff, 0xffff007e, 0x7fffff, 0xffffffff,\n        0x80ffff, 0xffff0081, 0xffffffff, 0xffff0082, 0x83ffff, 0x84ffff,\n        0x85ffff, 0xffffffff, 0xffff0086, 0xffffffff, 0x87ffff, 0xffffffff,\n        0xffff0088, 0xffffffff, 0xffff0089, 0xffff008a, 0x8bffff, 0xffffffff,\n        0x8cffff, 0x8dffff, 0xffffffff, 0xffffffff, 0x8effff, 0xffff008f,\n        0x910090, 0x92ffff, 0xffff0093, 0xffff0094, 0xffff0095, 0xffff0096,\n        0xffff0097, 0xffff0098, 0xffff0099, 0xffff009a, 0x9c009b, 0x9dffff,\n        0x9effff, 0x9fffff, 0xa0ffff, 0xa1ffff, 0xa2ffff, 0xa3ffff, 0xa4ffff,\n        0xa5ffff, 0xffff0442, 0xa700a6, 0xa8ffff, 0xffffffff, 0xa9ffff,\n        0xaaffff, 0xabffff, 0xacffff, 0xadffff, 0xaeffff, 0xafffff, 0xb0ffff,\n        0xb1ffff, 0xb2ffff, 0xb3ffff, 0xb4ffff, 0xb5ffff, 0xb6ffff, 0xb7ffff,\n        0xb8ffff, 0xb9ffff, 0xbaffff, 0xbbffff, 0xbcffff, 0xffffffff, 0xbdffff,\n        0xbeffff, 0xbfffff, 0xc0ffff, 0xc1ffff, 0xc2ffff, 0xc3ffff, 0xc4ffff,\n        0xc5ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff00c6,\n        0xc7ffff, 0xffff00c8, 0xffff00c9, 0xffffffff, 0xcaffff, 0xcbffff,\n        0xccffff, 0xcdffff, 0xceffff, 0xd000cf, 0xd200d1, 0xffff00d3, 0xd500d4,\n        0xd6ffff, 0xd7ffff, 0xffffffff, 0xffffffff, 0xffff00d8, 0xd9ffff,\n        0xdaffff, 0xffff00db, 0xdd00dc, 0xdeffff, 0xffffffff, 0xdfffff,\n        0xe0ffff, 0xffff00e1, 0xe2ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xe3ffff, 0xffffffff, 0xffff00e4, 0xe5ffff, 0xffffffff, 0xffffffff,\n        0xe700e6, 0xe900e8, 0xffff00ea, 0xffffffff, 0xffffffff, 0xffff00eb,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xecffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xedffff, 0xeeffff,\n        0xffffffff, 0xefffff, 0xffffffff, 0xf0ffff, 0xf200f1, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffff043c, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xf400f3, 0xf600f5,\n        0xf7043f, 0xf900f8, 0xfb00fa, 0xfd00fc, 0xff00fe, 0x1010100, 0x1030102,\n        0x1050104, 0x1070106, 0x1090108, 0x10b010a, 0x10d010c, 0x10f010e,\n        0x1110110, 0x1130112, 0xffff0114, 0x1160115, 0xffffffff, 0x117ffff,\n        0x1190118, 0x11affff, 0x11bffff, 0x11cffff, 0x11dffff, 0x11effff,\n        0x11fffff, 0x120ffff, 0x121ffff, 0x122ffff, 0x123ffff, 0x124ffff,\n        0x125ffff, 0x1270126, 0xffff0128, 0x129ffff, 0xffffffff, 0xffff012a,\n        0x12bffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x12d012c, 0x12f012e, 0x1310130,\n        0x1330132, 0x1350134, 0x1370136, 0x1390138, 0x13b013a, 0x13d013c,\n        0x13f013e, 0x1410140, 0x1430142, 0x1450144, 0x1470146, 0x1490148,\n        0x14b014a, 0x14d014c, 0x14f014e, 0x1510150, 0x1530152, 0x1550154,\n        0x1570156, 0x1590158, 0x15b015a, 0x15cffff, 0x15dffff, 0x15effff,\n        0x15fffff, 0x160ffff, 0x161ffff, 0x162ffff, 0x163ffff, 0x164ffff,\n        0x165ffff, 0x166ffff, 0x167ffff, 0x168ffff, 0x169ffff, 0x16affff,\n        0x16bffff, 0x16cffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x16dffff, 0x16effff, 0x16fffff, 0x170ffff, 0x171ffff, 0x172ffff,\n        0x173ffff, 0x174ffff, 0x175ffff, 0x176ffff, 0x177ffff, 0x178ffff,\n        0x179ffff, 0x17affff, 0x17bffff, 0x17cffff, 0x17dffff, 0x17effff,\n        0x17fffff, 0x180ffff, 0x181ffff, 0x182ffff, 0x183ffff, 0x184ffff,\n        0x185ffff, 0x186ffff, 0x187ffff, 0xffffffff, 0xffff0188, 0xffff0189,\n        0xffff018a, 0xffff018b, 0xffff018c, 0xffff018d, 0x18f018e, 0x190ffff,\n        0x191ffff, 0x192ffff, 0x193ffff, 0x194ffff, 0x195ffff, 0x196ffff,\n        0x197ffff, 0x198ffff, 0x199ffff, 0x19affff, 0x19bffff, 0x19cffff,\n        0x19dffff, 0x19effff, 0x19fffff, 0x1a0ffff, 0x1a1ffff, 0x1a2ffff,\n        0x1a3ffff, 0x1a4ffff, 0x1a5ffff, 0x1a6ffff, 0x1a7ffff, 0x1a8ffff,\n        0x1a9ffff, 0x1aaffff, 0x1abffff, 0x1acffff, 0x1adffff, 0x1aeffff,\n        0x1afffff, 0x1b0ffff, 0x1b1ffff, 0x1b2ffff, 0x1b3ffff, 0x1b4ffff,\n        0x1b5ffff, 0x1b6ffff, 0x1b7ffff, 0x1b8ffff, 0x1b9ffff, 0x1baffff,\n        0x1bbffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1bcffff,\n        0x1be01bd, 0x1c001bf, 0x1c201c1, 0x1c401c3, 0x1c601c5, 0x1c801c7,\n        0x1ca01c9, 0x1cc01cb, 0x1ce01cd, 0x1d001cf, 0x1d201d1, 0x1d401d3,\n        0x1d601d5, 0x1d801d7, 0x1da01d9, 0x1dc01db, 0x1de01dd, 0x1e001df,\n        0x42e01e1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x1e2ffff, 0xffffffff, 0x1e3ffff,\n        0xffffffff, 0x1e4ffff, 0x1e5ffff, 0x1e6ffff, 0x1e7ffff, 0x1e8ffff,\n        0x1e9ffff, 0x1eaffff, 0x1ebffff, 0x1ecffff, 0x1edffff, 0x1eeffff,\n        0x1efffff, 0x1f0ffff, 0x1f1ffff, 0x1f2ffff, 0x1f3ffff, 0x1f4ffff,\n        0x1f5ffff, 0x1f6ffff, 0x1f7ffff, 0x1f8ffff, 0x1f9ffff, 0x1faffff,\n        0x1fbffff, 0x1fcffff, 0x1fdffff, 0x1feffff, 0x1ffffff, 0x200ffff,\n        0x201ffff, 0x202ffff, 0x203ffff, 0x204ffff, 0x205ffff, 0x206ffff,\n        0x207ffff, 0x208ffff, 0x209ffff, 0x20affff, 0x20bffff, 0x20cffff,\n        0x20dffff, 0x20effff, 0x20fffff, 0x210ffff, 0x211ffff, 0x212ffff,\n        0x213ffff, 0x214ffff, 0x215ffff, 0x216ffff, 0x217ffff, 0x218ffff,\n        0x219ffff, 0x21affff, 0x21bffff, 0x21cffff, 0x21dffff, 0x21effff,\n        0x21fffff, 0x220ffff, 0x221ffff, 0x222ffff, 0x223ffff, 0x224ffff,\n        0x225ffff, 0x226ffff, 0x227ffff, 0x228ffff, 0x229ffff, 0x22affff,\n        0x22bffff, 0x22cffff, 0x22dffff, 0x22effff, 0x4460444, 0x44a0448,\n        0x22f044c, 0xffffffff, 0xffffffff, 0x230ffff, 0x231ffff, 0x232ffff,\n        0x233ffff, 0x234ffff, 0x235ffff, 0x236ffff, 0x237ffff, 0x238ffff,\n        0x239ffff, 0x23affff, 0x23bffff, 0x23cffff, 0x23dffff, 0x23effff,\n        0x23fffff, 0x240ffff, 0x241ffff, 0x242ffff, 0x243ffff, 0x244ffff,\n        0x245ffff, 0x246ffff, 0x247ffff, 0x248ffff, 0x249ffff, 0x24affff,\n        0x24bffff, 0x24cffff, 0x24dffff, 0x24effff, 0x24fffff, 0x250ffff,\n        0x251ffff, 0x252ffff, 0x253ffff, 0x254ffff, 0x255ffff, 0x256ffff,\n        0x257ffff, 0x258ffff, 0x259ffff, 0x25affff, 0x25bffff, 0x25cffff,\n        0x25dffff, 0x25effff, 0x25fffff, 0x2610260, 0x2630262, 0x2650264,\n        0x2670266, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2690268,\n        0x26b026a, 0x26d026c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x26f026e, 0x2710270, 0x2730272, 0x2750274, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2770276, 0x2790278, 0x27b027a,\n        0x27d027c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x27f027e,\n        0x2810280, 0x2830282, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x284044e, 0x2850450, 0x2860453, 0x2870456, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2890288, 0x28b028a, 0x28d028c,\n        0x28f028e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2910290,\n        0x2930292, 0x2950294, 0x2970296, 0x2990298, 0x29b029a, 0x29d029c,\n        0xffffffff, 0x4790477, 0x47d047b, 0x481047f, 0x4850483, 0x4890487,\n        0x48d048b, 0x491048f, 0x4950493, 0x4990497, 0x49d049b, 0x4a1049f,\n        0x4a504a3, 0x4a904a7, 0x4ad04ab, 0x4b104af, 0x4b504b3, 0x4b904b7,\n        0x4bd04bb, 0x4c104bf, 0x4c504c3, 0x4c904c7, 0x4cd04cb, 0x4d104cf,\n        0x4d504d3, 0x2b702b6, 0x4d704e3, 0xffff04e5, 0x4ef0459, 0xffffffff,\n        0xffffffff, 0xffff04d9, 0xffff02b9, 0xffffffff, 0x4db04e7, 0xffff04e9,\n        0x4f2045b, 0xffffffff, 0xffffffff, 0xffff04dd, 0xffffffff, 0x2bc02bb,\n        0x460045d, 0xffffffff, 0x4650463, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2be02bd, 0x46b0468, 0x2bf046e, 0x4720470, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x4df04eb, 0xffff04ed,\n        0x4f50475, 0xffffffff, 0xffffffff, 0xffff04e1, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff02c1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2c302c2,\n        0x2c502c4, 0x2c702c6, 0x2c902c8, 0x2cb02ca, 0x2cd02cc, 0x2cf02ce,\n        0x2d102d0, 0xffffffff, 0xffffffff, 0xffff02d2, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2d402d3,\n        0x2d602d5, 0x2d802d7, 0x2da02d9, 0x2dc02db, 0x2de02dd, 0x2e002df,\n        0x2e202e1, 0x2e402e3, 0x2e602e5, 0x2e802e7, 0x2ea02e9, 0x2ec02eb,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2ee02ed,\n        0x2f002ef, 0x2f202f1, 0x2f402f3, 0x2f602f5, 0x2f802f7, 0x2fa02f9,\n        0x2fc02fb, 0x2fe02fd, 0x30002ff, 0x3020301, 0x3040303, 0x3060305,\n        0x3080307, 0x30a0309, 0x30c030b, 0x30e030d, 0x310030f, 0x3120311,\n        0x3140313, 0x3160315, 0x3180317, 0x31a0319, 0xffff031b, 0x31cffff,\n        0xffffffff, 0x31dffff, 0xffff031e, 0xffff031f, 0xffff0320, 0xffff0321,\n        0xffffffff, 0xffffffff, 0x322ffff, 0xffffffff, 0xffff0323, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x324ffff, 0x325ffff, 0x326ffff,\n        0x327ffff, 0x328ffff, 0x329ffff, 0x32affff, 0x32bffff, 0x32cffff,\n        0x32dffff, 0x32effff, 0x32fffff, 0x330ffff, 0x331ffff, 0x332ffff,\n        0x333ffff, 0x334ffff, 0x335ffff, 0x336ffff, 0x337ffff, 0x338ffff,\n        0x339ffff, 0x33affff, 0x33bffff, 0x33cffff, 0x33dffff, 0x33effff,\n        0x33fffff, 0x340ffff, 0x341ffff, 0x342ffff, 0x343ffff, 0x344ffff,\n        0x345ffff, 0x346ffff, 0x347ffff, 0x348ffff, 0x349ffff, 0x34affff,\n        0x34bffff, 0x34cffff, 0x34dffff, 0x34effff, 0x34fffff, 0x350ffff,\n        0x351ffff, 0x352ffff, 0x353ffff, 0x354ffff, 0x355ffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff0356, 0xffff0357, 0xffffffff,\n        0x358ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x35a0359, 0x35c035b, 0x35e035d, 0x360035f, 0x3620361,\n        0x3640363, 0x3660365, 0x3680367, 0x36a0369, 0x36c036b, 0x36e036d,\n        0x370036f, 0x3720371, 0x3740373, 0x3760375, 0x3780377, 0x37a0379,\n        0x37c037b, 0x37e037d, 0x37fffff, 0xffffffff, 0xffffffff, 0x380ffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x381ffff, 0x382ffff, 0x383ffff,\n        0x384ffff, 0x385ffff, 0x386ffff, 0x387ffff, 0x388ffff, 0x389ffff,\n        0x38affff, 0x38bffff, 0x38cffff, 0x38dffff, 0x38effff, 0x38fffff,\n        0x390ffff, 0x391ffff, 0x392ffff, 0x393ffff, 0x394ffff, 0x395ffff,\n        0x396ffff, 0x397ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x398ffff,\n        0x399ffff, 0x39affff, 0x39bffff, 0x39cffff, 0x39dffff, 0x39effff,\n        0x39fffff, 0x3a0ffff, 0x3a1ffff, 0x3a2ffff, 0x3a3ffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x3a4ffff, 0x3a5ffff, 0x3a6ffff, 0x3a7ffff, 0x3a8ffff, 0x3a9ffff,\n        0x3aaffff, 0xffffffff, 0x3abffff, 0x3acffff, 0x3adffff, 0x3aeffff,\n        0x3afffff, 0x3b0ffff, 0x3b1ffff, 0x3b2ffff, 0x3b3ffff, 0x3b4ffff,\n        0x3b5ffff, 0x3b6ffff, 0x3b7ffff, 0x3b8ffff, 0x3b9ffff, 0x3baffff,\n        0x3bbffff, 0x3bcffff, 0x3bdffff, 0x3beffff, 0x3bfffff, 0x3c0ffff,\n        0x3c1ffff, 0x3c2ffff, 0x3c3ffff, 0x3c4ffff, 0x3c5ffff, 0x3c6ffff,\n        0x3c7ffff, 0x3c8ffff, 0x3c9ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffff03ca, 0xffff03cb, 0x3ccffff, 0x3cdffff,\n        0x3ceffff, 0x3cfffff, 0x3d0ffff, 0xffffffff, 0xffffffff, 0xffff03d1,\n        0xffffffff, 0x3d2ffff, 0x3d3ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x3d4ffff, 0x3d5ffff, 0x3d6ffff,\n        0x3d7ffff, 0x3d8ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x420041e, 0x4240422, 0x42a0427, 0xffff042c, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x430ffff, 0x4340432,\n        0x4380436, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x3d9ffff, 0x3db03da, 0x3dd03dc,\n        0x3df03de, 0x3e103e0, 0x3e303e2, 0x3e503e4, 0x3e703e6, 0x3e903e8,\n        0x3eb03ea, 0x3ed03ec, 0x3ef03ee, 0x3f103f0, 0xffff03f2, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x3f403f3, 0x3f603f5, 0x3f803f7, 0x3fa03f9, 0x3fc03fb,\n        0x3fe03fd, 0x40003ff, 0x4020401, 0x4040403, 0x4060405, 0x4080407,\n        0x40a0409, 0x40c040b, 0x40e040d, 0x410040f, 0x4120411, 0x4140413,\n        0x4160415, 0x4180417, 0x41a0419, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff]);\n//8064 bytes\nenum toLowerIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x40, 0x200],\n        [0x100, 0x380, 0xbc0], [0x2020100, 0x4020302, 0x2020205, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x10000, 0x20000, 0x40003, 0x60005, 0x80007, 0x0, 0x90000, 0xb000a,\n        0xd000c, 0xf000e, 0x110010, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x140013, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x160015, 0x180017, 0x1a0019, 0x1c001b, 0x0, 0x0, 0x1e001d, 0x1f, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x210020, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x230022, 0x250024, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x260000,\n        0x27, 0x290028, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff, 0x20001, 0x40003, 0x60005, 0x80007, 0xa0009, 0xc000b, 0xe000d,\n        0x10000f, 0x120011, 0x140013, 0x160015, 0x180017, 0xffff0019,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x1b001a, 0x1d001c, 0x1f001e, 0x210020, 0x230022, 0x250024, 0x270026,\n        0x290028, 0x2b002a, 0x2d002c, 0x2f002e, 0xffff0030, 0x320031, 0x340033,\n        0x360035, 0x4130037, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff0038, 0xffff0039, 0xffff003a, 0xffff003b, 0xffff003c, 0xffff003d,\n        0xffff003e, 0xffff003f, 0xffff0040, 0xffff0041, 0xffff0042, 0xffff0043,\n        0xffff0044, 0xffff0045, 0xffff0046, 0xffff0047, 0xffff0048, 0xffff0049,\n        0xffff004a, 0xffff004b, 0xffff004c, 0xffff004d, 0xffff004e, 0xffff004f,\n        0xffff0414, 0xffff0051, 0xffff0052, 0xffff0053, 0x54ffff, 0x55ffff,\n        0x56ffff, 0x57ffff, 0x58ffff, 0x59ffff, 0x5affff, 0x5bffff, 0x423ffff,\n        0xffff005c, 0xffff005d, 0xffff005e, 0xffff005f, 0xffff0060, 0xffff0061,\n        0xffff0062, 0xffff0063, 0xffff0064, 0xffff0065, 0xffff0066, 0xffff0067,\n        0xffff0068, 0xffff0069, 0xffff006a, 0xffff006b, 0xffff006c, 0xffff006d,\n        0xffff006e, 0xffff006f, 0xffff0070, 0xffff0071, 0xffff0072, 0x740073,\n        0x75ffff, 0x76ffff, 0xffffffff, 0x77ffff, 0xffff0078, 0xffff0079,\n        0x7b007a, 0x7cffff, 0x7e007d, 0xffffffff, 0x80007f, 0x820081, 0x83ffff,\n        0xffff0084, 0x860085, 0xffff0087, 0xffffffff, 0x890088, 0x8affff,\n        0xffff008b, 0xffff008c, 0xffff008d, 0x8f008e, 0x90ffff, 0xffffffff,\n        0xffff0091, 0x930092, 0x94ffff, 0x960095, 0x97ffff, 0x98ffff,\n        0xffff0099, 0xffffffff, 0xffff009a, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x9c009b, 0x9dffff, 0xffff009e, 0xa0009f, 0xa1ffff, 0xa2ffff, 0xa3ffff,\n        0xa4ffff, 0xa5ffff, 0xa6ffff, 0xa7ffff, 0xa8ffff, 0xffffffff,\n        0xffff00a9, 0xffff00aa, 0xffff00ab, 0xffff00ac, 0xffff00ad, 0xffff00ae,\n        0xffff00af, 0xffff00b0, 0xffff00b1, 0xb20426, 0xffff00b3, 0xffff00b4,\n        0xb600b5, 0xffff00b7, 0xffff00b8, 0xffff00b9, 0xffff00ba, 0xffff00bb,\n        0xffff00bc, 0xffff00bd, 0xffff00be, 0xffff00bf, 0xffff00c0, 0xffff00c1,\n        0xffff00c2, 0xffff00c3, 0xffff00c4, 0xffff00c5, 0xffff00c6, 0xffff00c7,\n        0xffff00c8, 0xffff00c9, 0xffff00ca, 0xffff00cb, 0xffff00cc, 0xffff00cd,\n        0xffff00ce, 0xffff00cf, 0xffff00d0, 0xffff00d1, 0xffff00d2, 0xffff00d3,\n        0xffff00d4, 0xffffffff, 0xffffffff, 0xffffffff, 0xd600d5, 0xd7ffff,\n        0xffff00d8, 0xd9ffff, 0xdaffff, 0xdc00db, 0xffff00dd, 0xffff00de,\n        0xffff00df, 0xffff00e0, 0xffff00e1, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff00e2, 0xffff00e3, 0xffffffff,\n        0xffff00e4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffff00e5, 0xe700e6, 0xffff00e8, 0xffff00e9,\n        0xeb00ea, 0xec0424, 0xee00ed, 0xf000ef, 0xf200f1, 0xf400f3, 0xf600f5,\n        0xf800f7, 0xfa00f9, 0xfc00fb, 0xfdffff, 0xff00fe, 0x1010100, 0x1030102,\n        0x1050104, 0xffffffff, 0xffffffff, 0xffff0425, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x106ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0107,\n        0xffff0108, 0xffff0109, 0xffff010a, 0xffff010b, 0xffff010c, 0xffff010d,\n        0xffff010e, 0xffff010f, 0xffff0110, 0xffff0111, 0xffff0112, 0xffffffff,\n        0xffffffff, 0xffff0113, 0x114ffff, 0x115ffff, 0xffff0116, 0x117ffff,\n        0x1190118, 0x11b011a, 0x11d011c, 0x11f011e, 0x1210120, 0x1230122,\n        0x1250124, 0x1270126, 0x1290128, 0x12b012a, 0x12d012c, 0x12f012e,\n        0x1310130, 0x1330132, 0x1350134, 0x1370136, 0x1390138, 0x13b013a,\n        0x13d013c, 0x13f013e, 0x1410140, 0x1430142, 0x1450144, 0x1470146,\n        0x1490148, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff014a, 0xffff014b, 0xffff014c, 0xffff014d, 0xffff014e,\n        0xffff014f, 0xffff0150, 0xffff0151, 0xffff0152, 0xffff0153, 0xffff0154,\n        0xffff0155, 0xffff0156, 0xffff0157, 0xffff0158, 0xffff0159, 0xffff015a,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff015b, 0xffff015c,\n        0xffff015d, 0xffff015e, 0xffff015f, 0xffff0160, 0xffff0161, 0xffff0162,\n        0xffff0163, 0xffff0164, 0xffff0165, 0xffff0166, 0xffff0167, 0xffff0168,\n        0xffff0169, 0xffff016a, 0xffff016b, 0xffff016c, 0xffff016d, 0xffff016e,\n        0xffff016f, 0xffff0170, 0xffff0171, 0xffff0172, 0xffff0173, 0xffff0174,\n        0xffff0175, 0x1770176, 0x178ffff, 0x179ffff, 0x17affff, 0x17bffff,\n        0x17cffff, 0x17dffff, 0xffffffff, 0xffff017e, 0xffff017f, 0xffff0180,\n        0xffff0181, 0xffff0182, 0xffff0183, 0xffff0184, 0xffff0185, 0xffff0186,\n        0xffff0187, 0xffff0188, 0xffff0189, 0xffff018a, 0xffff018b, 0xffff018c,\n        0xffff018d, 0xffff018e, 0xffff018f, 0xffff0190, 0xffff0191, 0xffff0192,\n        0xffff0193, 0xffff0194, 0xffff0195, 0xffff0196, 0xffff0197, 0xffff0198,\n        0xffff0199, 0xffff019a, 0xffff019b, 0xffff019c, 0xffff019d, 0xffff019e,\n        0xffff019f, 0xffff01a0, 0xffff01a1, 0xffff01a2, 0xffff01a3, 0xffff01a4,\n        0xffff01a5, 0xffff01a6, 0xffff01a7, 0xffff01a8, 0xffff01a9, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x1aaffff, 0x1ac01ab, 0x1ae01ad,\n        0x1b001af, 0x1b201b1, 0x1b401b3, 0x1b601b5, 0x1b801b7, 0x1ba01b9,\n        0x1bc01bb, 0x1be01bd, 0x1c001bf, 0x1c201c1, 0x1c401c3, 0x1c601c5,\n        0x1c801c7, 0x1ca01c9, 0x1cc01cb, 0x1ce01cd, 0xffff01cf, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x41dffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x1d101d0, 0x1d301d2, 0x1d501d4, 0x1d701d6, 0x1d901d8,\n        0x1db01da, 0x1dd01dc, 0x1df01de, 0x1e101e0, 0x1e301e2, 0x1e501e4,\n        0x1e701e6, 0x1e901e8, 0x1eb01ea, 0x1ed01ec, 0x1ef01ee, 0x1f101f0,\n        0x1f301f2, 0x1f501f4, 0x1f6ffff, 0xffffffff, 0xffffffff, 0x1f7ffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff01f8, 0xffff01f9, 0xffff01fa, 0xffff01fb, 0xffff01fc,\n        0xffff01fd, 0xffff01fe, 0xffff01ff, 0xffff0200, 0xffff0201, 0xffff0202,\n        0xffff0203, 0xffff0204, 0xffff0205, 0xffff0206, 0xffff0207, 0xffff0208,\n        0xffff0209, 0xffff020a, 0xffff020b, 0xffff020c, 0xffff020d, 0xffff020e,\n        0xffff020f, 0xffff0210, 0xffff0211, 0xffff0212, 0xffff0213, 0xffff0214,\n        0xffff0215, 0xffff0216, 0xffff0217, 0xffff0218, 0xffff0219, 0xffff021a,\n        0xffff021b, 0xffff021c, 0xffff021d, 0xffff021e, 0xffff021f, 0xffff0220,\n        0xffff0221, 0xffff0222, 0xffff0223, 0xffff0224, 0xffff0225, 0xffff0226,\n        0xffff0227, 0xffff0228, 0xffff0229, 0xffff022a, 0xffff022b, 0xffff022c,\n        0xffff022d, 0xffff022e, 0xffff022f, 0xffff0230, 0xffff0231, 0xffff0232,\n        0xffff0233, 0xffff0234, 0xffff0235, 0xffff0236, 0xffff0237, 0xffff0238,\n        0xffff0239, 0xffff023a, 0xffff023b, 0xffff023c, 0xffff023d, 0xffff023e,\n        0xffff023f, 0xffff0240, 0xffff0241, 0xffff0242, 0x4280427, 0x42a0429,\n        0xffff042b, 0xffffffff, 0xffff0243, 0xffff0244, 0xffff0245, 0xffff0246,\n        0xffff0247, 0xffff0248, 0xffff0249, 0xffff024a, 0xffff024b, 0xffff024c,\n        0xffff024d, 0xffff024e, 0xffff024f, 0xffff0250, 0xffff0251, 0xffff0252,\n        0xffff0253, 0xffff0254, 0xffff0255, 0xffff0256, 0xffff0257, 0xffff0258,\n        0xffff0259, 0xffff025a, 0xffff025b, 0xffff025c, 0xffff025d, 0xffff025e,\n        0xffff025f, 0xffff0260, 0xffff0261, 0xffff0262, 0xffff0263, 0xffff0264,\n        0xffff0265, 0xffff0266, 0xffff0267, 0xffff0268, 0xffff0269, 0xffff026a,\n        0xffff026b, 0xffff026c, 0xffff026d, 0xffff026e, 0xffff026f, 0xffff0270,\n        0xffff0271, 0xffff0272, 0xffff0273, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2750274, 0x2770276, 0x2790278, 0x27b027a, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x27d027c, 0x27f027e, 0x2810280,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2830282,\n        0x2850284, 0x2870286, 0x2890288, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x28b028a, 0x28d028c, 0x28f028e, 0x2910290, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2930292, 0x2950294, 0x2970296,\n        0xffffffff, 0xffff042c, 0xffff042d, 0xffff042e, 0xffff042f, 0x298ffff,\n        0x299ffff, 0x29affff, 0x29bffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x29d029c, 0x29f029e, 0x2a102a0, 0x2a302a2, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x43d043c, 0x43f043e, 0x4410440, 0x4430442, 0x4450444,\n        0x4470446, 0x4490448, 0x44b044a, 0x44d044c, 0x44f044e, 0x4510450,\n        0x4530452, 0x4550454, 0x4570456, 0x4590458, 0x45b045a, 0x45d045c,\n        0x45f045e, 0x4610460, 0x4630462, 0x4650464, 0x4670466, 0x4690468,\n        0x46b046a, 0xffffffff, 0x46c0472, 0xffff0473, 0x4780430, 0x2bd02bc,\n        0x2bf02be, 0xffff046d, 0xffffffff, 0xffffffff, 0x46e0474, 0xffff0475,\n        0x4790431, 0x2c202c1, 0x2c402c3, 0xffff046f, 0xffffffff, 0xffffffff,\n        0x4330432, 0xffffffff, 0x4350434, 0x2c702c6, 0x2c902c8, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x4370436, 0xffff0438, 0x43a0439, 0x2cb02ca,\n        0x2cd02cc, 0xffff02ce, 0xffffffff, 0xffffffff, 0x4700476, 0xffff0477,\n        0x47a043b, 0x2d002cf, 0x2d202d1, 0xffff0471, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff02d4, 0xffffffff, 0x2d602d5, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff02d7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2d902d8,\n        0x2db02da, 0x2dd02dc, 0x2df02de, 0x2e102e0, 0x2e302e2, 0x2e502e4,\n        0x2e702e6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2e8ffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x2ea02e9, 0x2ec02eb, 0x2ee02ed, 0x2f002ef,\n        0x2f202f1, 0x2f402f3, 0x2f602f5, 0x2f802f7, 0x2fa02f9, 0x2fc02fb,\n        0x2fe02fd, 0x30002ff, 0x3020301, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x3040303, 0x3060305, 0x3080307,\n        0x30a0309, 0x30c030b, 0x30e030d, 0x310030f, 0x3120311, 0x3140313,\n        0x3160315, 0x3180317, 0x31a0319, 0x31c031b, 0x31e031d, 0x320031f,\n        0x3220321, 0x3240323, 0x3260325, 0x3280327, 0x32a0329, 0x32c032b,\n        0x32e032d, 0x330032f, 0xffff0331, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff0332, 0x3340333, 0xffff0335,\n        0x336ffff, 0x337ffff, 0x338ffff, 0x339ffff, 0x33b033a, 0xffff033c,\n        0xffff033d, 0x33effff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x340033f, 0xffff0341, 0xffff0342, 0xffff0343, 0xffff0344, 0xffff0345,\n        0xffff0346, 0xffff0347, 0xffff0348, 0xffff0349, 0xffff034a, 0xffff034b,\n        0xffff034c, 0xffff034d, 0xffff034e, 0xffff034f, 0xffff0350, 0xffff0351,\n        0xffff0352, 0xffff0353, 0xffff0354, 0xffff0355, 0xffff0356, 0xffff0357,\n        0xffff0358, 0xffff0359, 0xffff035a, 0xffff035b, 0xffff035c, 0xffff035d,\n        0xffff035e, 0xffff035f, 0xffff0360, 0xffff0361, 0xffff0362, 0xffff0363,\n        0xffff0364, 0xffff0365, 0xffff0366, 0xffff0367, 0xffff0368, 0xffff0369,\n        0xffff036a, 0xffff036b, 0xffff036c, 0xffff036d, 0xffff036e, 0xffff036f,\n        0xffff0370, 0xffff0371, 0xffff0372, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x373ffff, 0x374ffff, 0xffffffff, 0xffffffff, 0xffff0375, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0376,\n        0xffff0377, 0xffff0378, 0xffff0379, 0xffff037a, 0xffff037b, 0xffff037c,\n        0xffff037d, 0xffff037e, 0xffff037f, 0xffff0380, 0xffff0381, 0xffff0382,\n        0xffff0383, 0xffff0384, 0xffff0385, 0xffff0386, 0xffff0387, 0xffff0388,\n        0xffff0389, 0xffff038a, 0xffff038b, 0xffff038c, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff038d, 0xffff038e, 0xffff038f, 0xffff0390, 0xffff0391,\n        0xffff0392, 0xffff0393, 0xffff0394, 0xffff0395, 0xffff0396, 0xffff0397,\n        0xffff0398, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffff0399, 0xffff039a, 0xffff039b, 0xffff039c,\n        0xffff039d, 0xffff039e, 0xffff039f, 0xffffffff, 0xffff03a0, 0xffff03a1,\n        0xffff03a2, 0xffff03a3, 0xffff03a4, 0xffff03a5, 0xffff03a6, 0xffff03a7,\n        0xffff03a8, 0xffff03a9, 0xffff03aa, 0xffff03ab, 0xffff03ac, 0xffff03ad,\n        0xffff03ae, 0xffff03af, 0xffff03b0, 0xffff03b1, 0xffff03b2, 0xffff03b3,\n        0xffff03b4, 0xffff03b5, 0xffff03b6, 0xffff03b7, 0xffff03b8, 0xffff03b9,\n        0xffff03ba, 0xffff03bb, 0xffff03bc, 0xffff03bd, 0xffff03be, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x3bfffff, 0x3c0ffff, 0x3c1ffff,\n        0xffff03c2, 0xffff03c3, 0xffff03c4, 0xffff03c5, 0xffff03c6, 0xffffffff,\n        0x3c7ffff, 0x3c8ffff, 0xffffffff, 0xffff03c9, 0xffff03ca, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff03cb,\n        0xffff03cc, 0xffff03cd, 0xffff03ce, 0xffff03cf, 0xffff03d0, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x4170416, 0x4190418, 0x41b041a,\n        0xffff041c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x41effff, 0x420041f, 0x4220421, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x3d1ffff, 0x3d303d2, 0x3d503d4,\n        0x3d703d6, 0x3d903d8, 0x3db03da, 0x3dd03dc, 0x3df03de, 0x3e103e0,\n        0x3e303e2, 0x3e503e4, 0x3e703e6, 0x3e903e8, 0xffff03ea, 0xffffffff,\n        0xffffffff, 0x3ec03eb, 0x3ee03ed, 0x3f003ef, 0x3f203f1, 0x3f403f3,\n        0x3f603f5, 0x3f803f7, 0x3fa03f9, 0x3fc03fb, 0x3fe03fd, 0x40003ff,\n        0x4020401, 0x4040403, 0x4060405, 0x4080407, 0x40a0409, 0x40c040b,\n        0x40e040d, 0x410040f, 0x4120411, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff]);\n//8192 bytes\nenum toTitleIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x40, 0x200],\n        [0x100, 0x380, 0xc00], [0x2020100, 0x4020302, 0x2020205, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x10000, 0x30002, 0x50004, 0x70006, 0x90008, 0xa, 0xb0000, 0xd000c,\n        0xf000e, 0x110010, 0x130012, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x150000, 0x0,\n        0x170016, 0x190018, 0x1b001a, 0x1d001c, 0x0, 0x0, 0x1e0000, 0x1f, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x200000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x220021, 0x240023, 0x25, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x260000,\n        0x27, 0x290028, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x2c0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x2e002d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff, 0x20001,\n        0x40003, 0x60005, 0x80007, 0xa0009, 0xc000b, 0xe000d, 0x10000f,\n        0x120011, 0x140013, 0x160015, 0x180017, 0xffff0019, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x1affff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x41fffff, 0x1c001b, 0x1e001d, 0x20001f, 0x220021, 0x240023, 0x260025,\n        0x280027, 0x2a0029, 0x2c002b, 0x2e002d, 0x30002f, 0xffff0031, 0x330032,\n        0x350034, 0x370036, 0x390038, 0x3affff, 0x3bffff, 0x3cffff, 0x3dffff,\n        0x3effff, 0x3fffff, 0x40ffff, 0x41ffff, 0x42ffff, 0x43ffff, 0x44ffff,\n        0x45ffff, 0x46ffff, 0x47ffff, 0x48ffff, 0x49ffff, 0x4affff, 0x4bffff,\n        0x4cffff, 0x4dffff, 0x4effff, 0x4fffff, 0x50ffff, 0x51ffff, 0x520421,\n        0x53ffff, 0x54ffff, 0x55ffff, 0xffffffff, 0xffff0056, 0xffff0057,\n        0xffff0058, 0xffff0059, 0xffff005a, 0xffff005b, 0xffff005c, 0x43e005d,\n        0x5effff, 0x5fffff, 0x60ffff, 0x61ffff, 0x62ffff, 0x63ffff, 0x64ffff,\n        0x65ffff, 0x66ffff, 0x67ffff, 0x68ffff, 0x69ffff, 0x6affff, 0x6bffff,\n        0x6cffff, 0x6dffff, 0x6effff, 0x6fffff, 0x70ffff, 0x71ffff, 0x72ffff,\n        0x73ffff, 0x74ffff, 0xffffffff, 0xffff0075, 0xffff0076, 0x780077,\n        0xffff0079, 0x7affff, 0x7bffff, 0xffffffff, 0xffff007c, 0xffffffff,\n        0xffff007d, 0xffffffff, 0xffffffff, 0xffff007e, 0x7fffff, 0xffffffff,\n        0x80ffff, 0xffff0081, 0xffffffff, 0xffff0082, 0x83ffff, 0x84ffff,\n        0x85ffff, 0xffffffff, 0xffff0086, 0xffffffff, 0x87ffff, 0xffffffff,\n        0xffff0088, 0xffffffff, 0xffff0089, 0xffff008a, 0x8bffff, 0xffffffff,\n        0x8cffff, 0x8dffff, 0xffffffff, 0xffffffff, 0x8f008e, 0x910090,\n        0x930092, 0x950094, 0xffff0096, 0xffff0097, 0xffff0098, 0xffff0099,\n        0xffff009a, 0xffff009b, 0xffff009c, 0xffff009d, 0x9f009e, 0xa0ffff,\n        0xa1ffff, 0xa2ffff, 0xa3ffff, 0xa4ffff, 0xa5ffff, 0xa6ffff, 0xa7ffff,\n        0xa8ffff, 0xa90446, 0xab00aa, 0xacffff, 0xffffffff, 0xadffff, 0xaeffff,\n        0xafffff, 0xb0ffff, 0xb1ffff, 0xb2ffff, 0xb3ffff, 0xb4ffff, 0xb5ffff,\n        0xb6ffff, 0xb7ffff, 0xb8ffff, 0xb9ffff, 0xbaffff, 0xbbffff, 0xbcffff,\n        0xbdffff, 0xbeffff, 0xbfffff, 0xc0ffff, 0xffffffff, 0xc1ffff, 0xc2ffff,\n        0xc3ffff, 0xc4ffff, 0xc5ffff, 0xc6ffff, 0xc7ffff, 0xc8ffff, 0xc9ffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff00ca, 0xcbffff,\n        0xffff00cc, 0xffff00cd, 0xffffffff, 0xceffff, 0xcfffff, 0xd0ffff,\n        0xd1ffff, 0xd2ffff, 0xd400d3, 0xd600d5, 0xffff00d7, 0xd900d8, 0xdaffff,\n        0xdbffff, 0xffffffff, 0xffffffff, 0xffff00dc, 0xddffff, 0xdeffff,\n        0xffff00df, 0xe100e0, 0xe2ffff, 0xffffffff, 0xe3ffff, 0xe4ffff,\n        0xffff00e5, 0xe6ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xe7ffff,\n        0xffffffff, 0xffff00e8, 0xe9ffff, 0xffffffff, 0xffffffff, 0xeb00ea,\n        0xed00ec, 0xffff00ee, 0xffffffff, 0xffffffff, 0xffff00ef, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xf0ffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xf1ffff, 0xf2ffff, 0xffffffff,\n        0xf3ffff, 0xffffffff, 0xf4ffff, 0xf600f5, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff0440, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xf800f7, 0xfa00f9, 0xfb0443,\n        0xfd00fc, 0xff00fe, 0x1010100, 0x1030102, 0x1050104, 0x1070106,\n        0x1090108, 0x10b010a, 0x10d010c, 0x10f010e, 0x1110110, 0x1130112,\n        0x1150114, 0x1170116, 0xffff0118, 0x11a0119, 0xffffffff, 0x11bffff,\n        0x11d011c, 0x11effff, 0x11fffff, 0x120ffff, 0x121ffff, 0x122ffff,\n        0x123ffff, 0x124ffff, 0x125ffff, 0x126ffff, 0x127ffff, 0x128ffff,\n        0x129ffff, 0x12b012a, 0xffff012c, 0x12dffff, 0xffffffff, 0xffff012e,\n        0x12fffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x1310130, 0x1330132, 0x1350134,\n        0x1370136, 0x1390138, 0x13b013a, 0x13d013c, 0x13f013e, 0x1410140,\n        0x1430142, 0x1450144, 0x1470146, 0x1490148, 0x14b014a, 0x14d014c,\n        0x14f014e, 0x1510150, 0x1530152, 0x1550154, 0x1570156, 0x1590158,\n        0x15b015a, 0x15d015c, 0x15f015e, 0x160ffff, 0x161ffff, 0x162ffff,\n        0x163ffff, 0x164ffff, 0x165ffff, 0x166ffff, 0x167ffff, 0x168ffff,\n        0x169ffff, 0x16affff, 0x16bffff, 0x16cffff, 0x16dffff, 0x16effff,\n        0x16fffff, 0x170ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x171ffff, 0x172ffff, 0x173ffff, 0x174ffff, 0x175ffff, 0x176ffff,\n        0x177ffff, 0x178ffff, 0x179ffff, 0x17affff, 0x17bffff, 0x17cffff,\n        0x17dffff, 0x17effff, 0x17fffff, 0x180ffff, 0x181ffff, 0x182ffff,\n        0x183ffff, 0x184ffff, 0x185ffff, 0x186ffff, 0x187ffff, 0x188ffff,\n        0x189ffff, 0x18affff, 0x18bffff, 0xffffffff, 0xffff018c, 0xffff018d,\n        0xffff018e, 0xffff018f, 0xffff0190, 0xffff0191, 0x1930192, 0x194ffff,\n        0x195ffff, 0x196ffff, 0x197ffff, 0x198ffff, 0x199ffff, 0x19affff,\n        0x19bffff, 0x19cffff, 0x19dffff, 0x19effff, 0x19fffff, 0x1a0ffff,\n        0x1a1ffff, 0x1a2ffff, 0x1a3ffff, 0x1a4ffff, 0x1a5ffff, 0x1a6ffff,\n        0x1a7ffff, 0x1a8ffff, 0x1a9ffff, 0x1aaffff, 0x1abffff, 0x1acffff,\n        0x1adffff, 0x1aeffff, 0x1afffff, 0x1b0ffff, 0x1b1ffff, 0x1b2ffff,\n        0x1b3ffff, 0x1b4ffff, 0x1b5ffff, 0x1b6ffff, 0x1b7ffff, 0x1b8ffff,\n        0x1b9ffff, 0x1baffff, 0x1bbffff, 0x1bcffff, 0x1bdffff, 0x1beffff,\n        0x1bfffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1c0ffff,\n        0x1c201c1, 0x1c401c3, 0x1c601c5, 0x1c801c7, 0x1ca01c9, 0x1cc01cb,\n        0x1ce01cd, 0x1d001cf, 0x1d201d1, 0x1d401d3, 0x1d601d5, 0x1d801d7,\n        0x1da01d9, 0x1dc01db, 0x1de01dd, 0x1e001df, 0x1e201e1, 0x1e401e3,\n        0x43201e5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x1e6ffff, 0xffffffff, 0x1e7ffff,\n        0xffffffff, 0x1e8ffff, 0x1e9ffff, 0x1eaffff, 0x1ebffff, 0x1ecffff,\n        0x1edffff, 0x1eeffff, 0x1efffff, 0x1f0ffff, 0x1f1ffff, 0x1f2ffff,\n        0x1f3ffff, 0x1f4ffff, 0x1f5ffff, 0x1f6ffff, 0x1f7ffff, 0x1f8ffff,\n        0x1f9ffff, 0x1faffff, 0x1fbffff, 0x1fcffff, 0x1fdffff, 0x1feffff,\n        0x1ffffff, 0x200ffff, 0x201ffff, 0x202ffff, 0x203ffff, 0x204ffff,\n        0x205ffff, 0x206ffff, 0x207ffff, 0x208ffff, 0x209ffff, 0x20affff,\n        0x20bffff, 0x20cffff, 0x20dffff, 0x20effff, 0x20fffff, 0x210ffff,\n        0x211ffff, 0x212ffff, 0x213ffff, 0x214ffff, 0x215ffff, 0x216ffff,\n        0x217ffff, 0x218ffff, 0x219ffff, 0x21affff, 0x21bffff, 0x21cffff,\n        0x21dffff, 0x21effff, 0x21fffff, 0x220ffff, 0x221ffff, 0x222ffff,\n        0x223ffff, 0x224ffff, 0x225ffff, 0x226ffff, 0x227ffff, 0x228ffff,\n        0x229ffff, 0x22affff, 0x22bffff, 0x22cffff, 0x22dffff, 0x22effff,\n        0x22fffff, 0x230ffff, 0x231ffff, 0x232ffff, 0x44a0448, 0x44e044c,\n        0x2330450, 0xffffffff, 0xffffffff, 0x234ffff, 0x235ffff, 0x236ffff,\n        0x237ffff, 0x238ffff, 0x239ffff, 0x23affff, 0x23bffff, 0x23cffff,\n        0x23dffff, 0x23effff, 0x23fffff, 0x240ffff, 0x241ffff, 0x242ffff,\n        0x243ffff, 0x244ffff, 0x245ffff, 0x246ffff, 0x247ffff, 0x248ffff,\n        0x249ffff, 0x24affff, 0x24bffff, 0x24cffff, 0x24dffff, 0x24effff,\n        0x24fffff, 0x250ffff, 0x251ffff, 0x252ffff, 0x253ffff, 0x254ffff,\n        0x255ffff, 0x256ffff, 0x257ffff, 0x258ffff, 0x259ffff, 0x25affff,\n        0x25bffff, 0x25cffff, 0x25dffff, 0x25effff, 0x25fffff, 0x260ffff,\n        0x261ffff, 0x262ffff, 0x263ffff, 0x2650264, 0x2670266, 0x2690268,\n        0x26b026a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x26d026c,\n        0x26f026e, 0x2710270, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2730272, 0x2750274, 0x2770276, 0x2790278, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x27b027a, 0x27d027c, 0x27f027e,\n        0x2810280, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2830282,\n        0x2850284, 0x2870286, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2880452, 0x2890454, 0x28a0457, 0x28b045a, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x28d028c, 0x28f028e, 0x2910290,\n        0x2930292, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2950294,\n        0x2970296, 0x2990298, 0x29b029a, 0x29d029c, 0x29f029e, 0x2a102a0,\n        0xffffffff, 0x47c047b, 0x47e047d, 0x480047f, 0x4820481, 0x4840483,\n        0x4860485, 0x4880487, 0x48a0489, 0x48c048b, 0x48e048d, 0x490048f,\n        0x4920491, 0x4940493, 0x4960495, 0x4980497, 0x49a0499, 0x49c049b,\n        0x49e049d, 0x4a0049f, 0x4a204a1, 0x4a404a3, 0x4a604a5, 0x4a804a7,\n        0x4aa04a9, 0x2bb02ba, 0x4ab04b1, 0xffff04b3, 0x4bd045d, 0xffffffff,\n        0xffffffff, 0xffff04ac, 0xffff02bd, 0xffffffff, 0x4ad04b5, 0xffff04b7,\n        0x4c0045f, 0xffffffff, 0xffffffff, 0xffff04ae, 0xffffffff, 0x2c002bf,\n        0x4640461, 0xffffffff, 0x4690467, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2c202c1, 0x46f046c, 0x2c30472, 0x4760474, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x4af04b9, 0xffff04bb,\n        0x4c30479, 0xffffffff, 0xffffffff, 0xffff04b0, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff02c5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2c702c6,\n        0x2c902c8, 0x2cb02ca, 0x2cd02cc, 0x2cf02ce, 0x2d102d0, 0x2d302d2,\n        0x2d502d4, 0xffffffff, 0xffffffff, 0xffff02d6, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2d802d7,\n        0x2da02d9, 0x2dc02db, 0x2de02dd, 0x2e002df, 0x2e202e1, 0x2e402e3,\n        0x2e602e5, 0x2e802e7, 0x2ea02e9, 0x2ec02eb, 0x2ee02ed, 0x2f002ef,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2f202f1,\n        0x2f402f3, 0x2f602f5, 0x2f802f7, 0x2fa02f9, 0x2fc02fb, 0x2fe02fd,\n        0x30002ff, 0x3020301, 0x3040303, 0x3060305, 0x3080307, 0x30a0309,\n        0x30c030b, 0x30e030d, 0x310030f, 0x3120311, 0x3140313, 0x3160315,\n        0x3180317, 0x31a0319, 0x31c031b, 0x31e031d, 0xffff031f, 0x320ffff,\n        0xffffffff, 0x321ffff, 0xffff0322, 0xffff0323, 0xffff0324, 0xffff0325,\n        0xffffffff, 0xffffffff, 0x326ffff, 0xffffffff, 0xffff0327, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x328ffff, 0x329ffff, 0x32affff,\n        0x32bffff, 0x32cffff, 0x32dffff, 0x32effff, 0x32fffff, 0x330ffff,\n        0x331ffff, 0x332ffff, 0x333ffff, 0x334ffff, 0x335ffff, 0x336ffff,\n        0x337ffff, 0x338ffff, 0x339ffff, 0x33affff, 0x33bffff, 0x33cffff,\n        0x33dffff, 0x33effff, 0x33fffff, 0x340ffff, 0x341ffff, 0x342ffff,\n        0x343ffff, 0x344ffff, 0x345ffff, 0x346ffff, 0x347ffff, 0x348ffff,\n        0x349ffff, 0x34affff, 0x34bffff, 0x34cffff, 0x34dffff, 0x34effff,\n        0x34fffff, 0x350ffff, 0x351ffff, 0x352ffff, 0x353ffff, 0x354ffff,\n        0x355ffff, 0x356ffff, 0x357ffff, 0x358ffff, 0x359ffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff035a, 0xffff035b, 0xffffffff,\n        0x35cffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x35e035d, 0x360035f, 0x3620361, 0x3640363, 0x3660365,\n        0x3680367, 0x36a0369, 0x36c036b, 0x36e036d, 0x370036f, 0x3720371,\n        0x3740373, 0x3760375, 0x3780377, 0x37a0379, 0x37c037b, 0x37e037d,\n        0x380037f, 0x3820381, 0x383ffff, 0xffffffff, 0xffffffff, 0x384ffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x385ffff, 0x386ffff, 0x387ffff,\n        0x388ffff, 0x389ffff, 0x38affff, 0x38bffff, 0x38cffff, 0x38dffff,\n        0x38effff, 0x38fffff, 0x390ffff, 0x391ffff, 0x392ffff, 0x393ffff,\n        0x394ffff, 0x395ffff, 0x396ffff, 0x397ffff, 0x398ffff, 0x399ffff,\n        0x39affff, 0x39bffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x39cffff,\n        0x39dffff, 0x39effff, 0x39fffff, 0x3a0ffff, 0x3a1ffff, 0x3a2ffff,\n        0x3a3ffff, 0x3a4ffff, 0x3a5ffff, 0x3a6ffff, 0x3a7ffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x3a8ffff, 0x3a9ffff, 0x3aaffff, 0x3abffff, 0x3acffff, 0x3adffff,\n        0x3aeffff, 0xffffffff, 0x3afffff, 0x3b0ffff, 0x3b1ffff, 0x3b2ffff,\n        0x3b3ffff, 0x3b4ffff, 0x3b5ffff, 0x3b6ffff, 0x3b7ffff, 0x3b8ffff,\n        0x3b9ffff, 0x3baffff, 0x3bbffff, 0x3bcffff, 0x3bdffff, 0x3beffff,\n        0x3bfffff, 0x3c0ffff, 0x3c1ffff, 0x3c2ffff, 0x3c3ffff, 0x3c4ffff,\n        0x3c5ffff, 0x3c6ffff, 0x3c7ffff, 0x3c8ffff, 0x3c9ffff, 0x3caffff,\n        0x3cbffff, 0x3ccffff, 0x3cdffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffff03ce, 0xffff03cf, 0x3d0ffff, 0x3d1ffff,\n        0x3d2ffff, 0x3d3ffff, 0x3d4ffff, 0xffffffff, 0xffffffff, 0xffff03d5,\n        0xffffffff, 0x3d6ffff, 0x3d7ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x3d8ffff, 0x3d9ffff, 0x3daffff,\n        0x3dbffff, 0x3dcffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x4240422, 0x4280426, 0x42e042b, 0xffff0430, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x434ffff, 0x4380436,\n        0x43c043a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x3ddffff, 0x3df03de, 0x3e103e0,\n        0x3e303e2, 0x3e503e4, 0x3e703e6, 0x3e903e8, 0x3eb03ea, 0x3ed03ec,\n        0x3ef03ee, 0x3f103f0, 0x3f303f2, 0x3f503f4, 0xffff03f6, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x3f803f7, 0x3fa03f9, 0x3fc03fb, 0x3fe03fd, 0x40003ff,\n        0x4020401, 0x4040403, 0x4060405, 0x4080407, 0x40a0409, 0x40c040b,\n        0x40e040d, 0x410040f, 0x4120411, 0x4140413, 0x4160415, 0x4180417,\n        0x41a0419, 0x41c041b, 0x41e041d, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff]);\n//8064 bytes\nenum toUpperSimpleIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x40,\n        0x200], [0x100, 0x380, 0xbc0], [0x2020100, 0x4020302, 0x2020205,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x10000, 0x30002, 0x50004, 0x70006, 0x90008, 0xa, 0xb0000,\n        0xd000c, 0xf000e, 0x110010, 0x130012, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x150000, 0x0, 0x170016, 0x190018, 0x1b001a, 0x1d001c, 0x0, 0x0,\n        0x1e0000, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x220021, 0x240023,\n        0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x260000, 0x27, 0x290028, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x2d002c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff,\n        0x20001, 0x40003, 0x60005, 0x80007, 0xa0009, 0xc000b, 0xe000d,\n        0x10000f, 0x120011, 0x140013, 0x160015, 0x180017, 0xffff0019,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1affff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x1c001b, 0x1e001d, 0x20001f, 0x220021,\n        0x240023, 0x260025, 0x280027, 0x2a0029, 0x2c002b, 0x2e002d, 0x30002f,\n        0xffff0031, 0x330032, 0x350034, 0x370036, 0x390038, 0x3affff, 0x3bffff,\n        0x3cffff, 0x3dffff, 0x3effff, 0x3fffff, 0x40ffff, 0x41ffff, 0x42ffff,\n        0x43ffff, 0x44ffff, 0x45ffff, 0x46ffff, 0x47ffff, 0x48ffff, 0x49ffff,\n        0x4affff, 0x4bffff, 0x4cffff, 0x4dffff, 0x4effff, 0x4fffff, 0x50ffff,\n        0x51ffff, 0x52ffff, 0x53ffff, 0x54ffff, 0x55ffff, 0xffffffff,\n        0xffff0056, 0xffff0057, 0xffff0058, 0xffff0059, 0xffff005a, 0xffff005b,\n        0xffff005c, 0xffff005d, 0x5effff, 0x5fffff, 0x60ffff, 0x61ffff,\n        0x62ffff, 0x63ffff, 0x64ffff, 0x65ffff, 0x66ffff, 0x67ffff, 0x68ffff,\n        0x69ffff, 0x6affff, 0x6bffff, 0x6cffff, 0x6dffff, 0x6effff, 0x6fffff,\n        0x70ffff, 0x71ffff, 0x72ffff, 0x73ffff, 0x74ffff, 0xffffffff,\n        0xffff0075, 0xffff0076, 0x780077, 0xffff0079, 0x7affff, 0x7bffff,\n        0xffffffff, 0xffff007c, 0xffffffff, 0xffff007d, 0xffffffff, 0xffffffff,\n        0xffff007e, 0x7fffff, 0xffffffff, 0x80ffff, 0xffff0081, 0xffffffff,\n        0xffff0082, 0x83ffff, 0x84ffff, 0x85ffff, 0xffffffff, 0xffff0086,\n        0xffffffff, 0x87ffff, 0xffffffff, 0xffff0088, 0xffffffff, 0xffff0089,\n        0xffff008a, 0x8bffff, 0xffffffff, 0x8cffff, 0x8dffff, 0xffffffff,\n        0xffffffff, 0x8effff, 0xffff008f, 0x910090, 0x92ffff, 0xffff0093,\n        0xffff0094, 0xffff0095, 0xffff0096, 0xffff0097, 0xffff0098, 0xffff0099,\n        0xffff009a, 0x9c009b, 0x9dffff, 0x9effff, 0x9fffff, 0xa0ffff, 0xa1ffff,\n        0xa2ffff, 0xa3ffff, 0xa4ffff, 0xa5ffff, 0xffffffff, 0xa700a6, 0xa8ffff,\n        0xffffffff, 0xa9ffff, 0xaaffff, 0xabffff, 0xacffff, 0xadffff, 0xaeffff,\n        0xafffff, 0xb0ffff, 0xb1ffff, 0xb2ffff, 0xb3ffff, 0xb4ffff, 0xb5ffff,\n        0xb6ffff, 0xb7ffff, 0xb8ffff, 0xb9ffff, 0xbaffff, 0xbbffff, 0xbcffff,\n        0xffffffff, 0xbdffff, 0xbeffff, 0xbfffff, 0xc0ffff, 0xc1ffff, 0xc2ffff,\n        0xc3ffff, 0xc4ffff, 0xc5ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff00c6, 0xc7ffff, 0xffff00c8, 0xffff00c9, 0xffffffff,\n        0xcaffff, 0xcbffff, 0xccffff, 0xcdffff, 0xceffff, 0xd000cf, 0xd200d1,\n        0xffff00d3, 0xd500d4, 0xd6ffff, 0xd7ffff, 0xffffffff, 0xffffffff,\n        0xffff00d8, 0xd9ffff, 0xdaffff, 0xffff00db, 0xdd00dc, 0xdeffff,\n        0xffffffff, 0xdfffff, 0xe0ffff, 0xffff00e1, 0xe2ffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xe3ffff, 0xffffffff, 0xffff00e4, 0xe5ffff,\n        0xffffffff, 0xffffffff, 0xe700e6, 0xe900e8, 0xffff00ea, 0xffffffff,\n        0xffffffff, 0xffff00eb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xecffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xedffff, 0xeeffff, 0xffffffff, 0xefffff, 0xffffffff, 0xf0ffff,\n        0xf200f1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xf400f3, 0xf600f5, 0xf7ffff, 0xf900f8, 0xfb00fa, 0xfd00fc, 0xff00fe,\n        0x1010100, 0x1030102, 0x1050104, 0x1070106, 0x1090108, 0x10b010a,\n        0x10d010c, 0x10f010e, 0x1110110, 0x1130112, 0xffff0114, 0x1160115,\n        0xffffffff, 0x117ffff, 0x1190118, 0x11affff, 0x11bffff, 0x11cffff,\n        0x11dffff, 0x11effff, 0x11fffff, 0x120ffff, 0x121ffff, 0x122ffff,\n        0x123ffff, 0x124ffff, 0x125ffff, 0x1270126, 0xffff0128, 0x129ffff,\n        0xffffffff, 0xffff012a, 0x12bffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x12d012c,\n        0x12f012e, 0x1310130, 0x1330132, 0x1350134, 0x1370136, 0x1390138,\n        0x13b013a, 0x13d013c, 0x13f013e, 0x1410140, 0x1430142, 0x1450144,\n        0x1470146, 0x1490148, 0x14b014a, 0x14d014c, 0x14f014e, 0x1510150,\n        0x1530152, 0x1550154, 0x1570156, 0x1590158, 0x15b015a, 0x15cffff,\n        0x15dffff, 0x15effff, 0x15fffff, 0x160ffff, 0x161ffff, 0x162ffff,\n        0x163ffff, 0x164ffff, 0x165ffff, 0x166ffff, 0x167ffff, 0x168ffff,\n        0x169ffff, 0x16affff, 0x16bffff, 0x16cffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x16dffff, 0x16effff, 0x16fffff, 0x170ffff,\n        0x171ffff, 0x172ffff, 0x173ffff, 0x174ffff, 0x175ffff, 0x176ffff,\n        0x177ffff, 0x178ffff, 0x179ffff, 0x17affff, 0x17bffff, 0x17cffff,\n        0x17dffff, 0x17effff, 0x17fffff, 0x180ffff, 0x181ffff, 0x182ffff,\n        0x183ffff, 0x184ffff, 0x185ffff, 0x186ffff, 0x187ffff, 0xffffffff,\n        0xffff0188, 0xffff0189, 0xffff018a, 0xffff018b, 0xffff018c, 0xffff018d,\n        0x18f018e, 0x190ffff, 0x191ffff, 0x192ffff, 0x193ffff, 0x194ffff,\n        0x195ffff, 0x196ffff, 0x197ffff, 0x198ffff, 0x199ffff, 0x19affff,\n        0x19bffff, 0x19cffff, 0x19dffff, 0x19effff, 0x19fffff, 0x1a0ffff,\n        0x1a1ffff, 0x1a2ffff, 0x1a3ffff, 0x1a4ffff, 0x1a5ffff, 0x1a6ffff,\n        0x1a7ffff, 0x1a8ffff, 0x1a9ffff, 0x1aaffff, 0x1abffff, 0x1acffff,\n        0x1adffff, 0x1aeffff, 0x1afffff, 0x1b0ffff, 0x1b1ffff, 0x1b2ffff,\n        0x1b3ffff, 0x1b4ffff, 0x1b5ffff, 0x1b6ffff, 0x1b7ffff, 0x1b8ffff,\n        0x1b9ffff, 0x1baffff, 0x1bbffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x1bcffff, 0x1be01bd, 0x1c001bf, 0x1c201c1, 0x1c401c3,\n        0x1c601c5, 0x1c801c7, 0x1ca01c9, 0x1cc01cb, 0x1ce01cd, 0x1d001cf,\n        0x1d201d1, 0x1d401d3, 0x1d601d5, 0x1d801d7, 0x1da01d9, 0x1dc01db,\n        0x1de01dd, 0x1e001df, 0xffff01e1, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1e2ffff,\n        0xffffffff, 0x1e3ffff, 0xffffffff, 0x1e4ffff, 0x1e5ffff, 0x1e6ffff,\n        0x1e7ffff, 0x1e8ffff, 0x1e9ffff, 0x1eaffff, 0x1ebffff, 0x1ecffff,\n        0x1edffff, 0x1eeffff, 0x1efffff, 0x1f0ffff, 0x1f1ffff, 0x1f2ffff,\n        0x1f3ffff, 0x1f4ffff, 0x1f5ffff, 0x1f6ffff, 0x1f7ffff, 0x1f8ffff,\n        0x1f9ffff, 0x1faffff, 0x1fbffff, 0x1fcffff, 0x1fdffff, 0x1feffff,\n        0x1ffffff, 0x200ffff, 0x201ffff, 0x202ffff, 0x203ffff, 0x204ffff,\n        0x205ffff, 0x206ffff, 0x207ffff, 0x208ffff, 0x209ffff, 0x20affff,\n        0x20bffff, 0x20cffff, 0x20dffff, 0x20effff, 0x20fffff, 0x210ffff,\n        0x211ffff, 0x212ffff, 0x213ffff, 0x214ffff, 0x215ffff, 0x216ffff,\n        0x217ffff, 0x218ffff, 0x219ffff, 0x21affff, 0x21bffff, 0x21cffff,\n        0x21dffff, 0x21effff, 0x21fffff, 0x220ffff, 0x221ffff, 0x222ffff,\n        0x223ffff, 0x224ffff, 0x225ffff, 0x226ffff, 0x227ffff, 0x228ffff,\n        0x229ffff, 0x22affff, 0x22bffff, 0x22cffff, 0x22dffff, 0x22effff,\n        0xffffffff, 0xffffffff, 0x22fffff, 0xffffffff, 0xffffffff, 0x230ffff,\n        0x231ffff, 0x232ffff, 0x233ffff, 0x234ffff, 0x235ffff, 0x236ffff,\n        0x237ffff, 0x238ffff, 0x239ffff, 0x23affff, 0x23bffff, 0x23cffff,\n        0x23dffff, 0x23effff, 0x23fffff, 0x240ffff, 0x241ffff, 0x242ffff,\n        0x243ffff, 0x244ffff, 0x245ffff, 0x246ffff, 0x247ffff, 0x248ffff,\n        0x249ffff, 0x24affff, 0x24bffff, 0x24cffff, 0x24dffff, 0x24effff,\n        0x24fffff, 0x250ffff, 0x251ffff, 0x252ffff, 0x253ffff, 0x254ffff,\n        0x255ffff, 0x256ffff, 0x257ffff, 0x258ffff, 0x259ffff, 0x25affff,\n        0x25bffff, 0x25cffff, 0x25dffff, 0x25effff, 0x25fffff, 0x2610260,\n        0x2630262, 0x2650264, 0x2670266, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2690268, 0x26b026a, 0x26d026c, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x26f026e, 0x2710270, 0x2730272,\n        0x2750274, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2770276,\n        0x2790278, 0x27b027a, 0x27d027c, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x27f027e, 0x2810280, 0x2830282, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x284ffff, 0x285ffff, 0x286ffff,\n        0x287ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2890288,\n        0x28b028a, 0x28d028c, 0x28f028e, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2910290, 0x2930292, 0x2950294, 0x2970296, 0x2990298,\n        0x29b029a, 0x29d029c, 0xffffffff, 0x29f029e, 0x2a102a0, 0x2a302a2,\n        0x2a502a4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2a702a6,\n        0x2a902a8, 0x2ab02aa, 0x2ad02ac, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2af02ae, 0x2b102b0, 0x2b302b2, 0x2b502b4, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2b702b6, 0x2b8ffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff02b9, 0xffffffff,\n        0x2baffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2bc02bb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2be02bd, 0xffffffff, 0x2bfffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x2c0ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffff02c1, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2c302c2, 0x2c502c4, 0x2c702c6, 0x2c902c8, 0x2cb02ca,\n        0x2cd02cc, 0x2cf02ce, 0x2d102d0, 0xffffffff, 0xffffffff, 0xffff02d2,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2d402d3, 0x2d602d5, 0x2d802d7, 0x2da02d9, 0x2dc02db,\n        0x2de02dd, 0x2e002df, 0x2e202e1, 0x2e402e3, 0x2e602e5, 0x2e802e7,\n        0x2ea02e9, 0x2ec02eb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2ee02ed, 0x2f002ef, 0x2f202f1, 0x2f402f3, 0x2f602f5,\n        0x2f802f7, 0x2fa02f9, 0x2fc02fb, 0x2fe02fd, 0x30002ff, 0x3020301,\n        0x3040303, 0x3060305, 0x3080307, 0x30a0309, 0x30c030b, 0x30e030d,\n        0x310030f, 0x3120311, 0x3140313, 0x3160315, 0x3180317, 0x31a0319,\n        0xffff031b, 0x31cffff, 0xffffffff, 0x31dffff, 0xffff031e, 0xffff031f,\n        0xffff0320, 0xffff0321, 0xffffffff, 0xffffffff, 0x322ffff, 0xffffffff,\n        0xffff0323, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x324ffff,\n        0x325ffff, 0x326ffff, 0x327ffff, 0x328ffff, 0x329ffff, 0x32affff,\n        0x32bffff, 0x32cffff, 0x32dffff, 0x32effff, 0x32fffff, 0x330ffff,\n        0x331ffff, 0x332ffff, 0x333ffff, 0x334ffff, 0x335ffff, 0x336ffff,\n        0x337ffff, 0x338ffff, 0x339ffff, 0x33affff, 0x33bffff, 0x33cffff,\n        0x33dffff, 0x33effff, 0x33fffff, 0x340ffff, 0x341ffff, 0x342ffff,\n        0x343ffff, 0x344ffff, 0x345ffff, 0x346ffff, 0x347ffff, 0x348ffff,\n        0x349ffff, 0x34affff, 0x34bffff, 0x34cffff, 0x34dffff, 0x34effff,\n        0x34fffff, 0x350ffff, 0x351ffff, 0x352ffff, 0x353ffff, 0x354ffff,\n        0x355ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0356,\n        0xffff0357, 0xffffffff, 0x358ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x35a0359, 0x35c035b, 0x35e035d,\n        0x360035f, 0x3620361, 0x3640363, 0x3660365, 0x3680367, 0x36a0369,\n        0x36c036b, 0x36e036d, 0x370036f, 0x3720371, 0x3740373, 0x3760375,\n        0x3780377, 0x37a0379, 0x37c037b, 0x37e037d, 0x37fffff, 0xffffffff,\n        0xffffffff, 0x380ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x381ffff,\n        0x382ffff, 0x383ffff, 0x384ffff, 0x385ffff, 0x386ffff, 0x387ffff,\n        0x388ffff, 0x389ffff, 0x38affff, 0x38bffff, 0x38cffff, 0x38dffff,\n        0x38effff, 0x38fffff, 0x390ffff, 0x391ffff, 0x392ffff, 0x393ffff,\n        0x394ffff, 0x395ffff, 0x396ffff, 0x397ffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x398ffff, 0x399ffff, 0x39affff, 0x39bffff, 0x39cffff,\n        0x39dffff, 0x39effff, 0x39fffff, 0x3a0ffff, 0x3a1ffff, 0x3a2ffff,\n        0x3a3ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x3a4ffff, 0x3a5ffff, 0x3a6ffff, 0x3a7ffff,\n        0x3a8ffff, 0x3a9ffff, 0x3aaffff, 0xffffffff, 0x3abffff, 0x3acffff,\n        0x3adffff, 0x3aeffff, 0x3afffff, 0x3b0ffff, 0x3b1ffff, 0x3b2ffff,\n        0x3b3ffff, 0x3b4ffff, 0x3b5ffff, 0x3b6ffff, 0x3b7ffff, 0x3b8ffff,\n        0x3b9ffff, 0x3baffff, 0x3bbffff, 0x3bcffff, 0x3bdffff, 0x3beffff,\n        0x3bfffff, 0x3c0ffff, 0x3c1ffff, 0x3c2ffff, 0x3c3ffff, 0x3c4ffff,\n        0x3c5ffff, 0x3c6ffff, 0x3c7ffff, 0x3c8ffff, 0x3c9ffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff03ca, 0xffff03cb,\n        0x3ccffff, 0x3cdffff, 0x3ceffff, 0x3cfffff, 0x3d0ffff, 0xffffffff,\n        0xffffffff, 0xffff03d1, 0xffffffff, 0x3d2ffff, 0x3d3ffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3d4ffff,\n        0x3d5ffff, 0x3d6ffff, 0x3d7ffff, 0x3d8ffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x3d9ffff, 0x3db03da, 0x3dd03dc,\n        0x3df03de, 0x3e103e0, 0x3e303e2, 0x3e503e4, 0x3e703e6, 0x3e903e8,\n        0x3eb03ea, 0x3ed03ec, 0x3ef03ee, 0x3f103f0, 0xffff03f2, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x3f403f3, 0x3f603f5, 0x3f803f7, 0x3fa03f9, 0x3fc03fb,\n        0x3fe03fd, 0x40003ff, 0x4020401, 0x4040403, 0x4060405, 0x4080407,\n        0x40a0409, 0x40c040b, 0x40e040d, 0x410040f, 0x4120411, 0x4140413,\n        0x4160415, 0x4180417, 0x41a0419, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff]);\n//7808 bytes\nenum toLowerSimpleIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x40,\n        0x200], [0x100, 0x380, 0xb40], [0x2020100, 0x4020302, 0x2020205,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x10000, 0x20000, 0x40003, 0x60005, 0x80007, 0x0, 0x90000,\n        0xb000a, 0xd000c, 0xf000e, 0x110010, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x130012, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x150014, 0x170016, 0x190018, 0x1b001a, 0x0, 0x0, 0x1d001c, 0x1e,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x20001f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x220021, 0x240023, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x250000, 0x26, 0x280027, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff, 0x20001, 0x40003, 0x60005, 0x80007, 0xa0009, 0xc000b, 0xe000d,\n        0x10000f, 0x120011, 0x140013, 0x160015, 0x180017, 0xffff0019,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x1b001a, 0x1d001c, 0x1f001e, 0x210020, 0x230022, 0x250024, 0x270026,\n        0x290028, 0x2b002a, 0x2d002c, 0x2f002e, 0xffff0030, 0x320031, 0x340033,\n        0x360035, 0xffff0037, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff0038, 0xffff0039, 0xffff003a, 0xffff003b, 0xffff003c, 0xffff003d,\n        0xffff003e, 0xffff003f, 0xffff0040, 0xffff0041, 0xffff0042, 0xffff0043,\n        0xffff0044, 0xffff0045, 0xffff0046, 0xffff0047, 0xffff0048, 0xffff0049,\n        0xffff004a, 0xffff004b, 0xffff004c, 0xffff004d, 0xffff004e, 0xffff004f,\n        0xffff0050, 0xffff0051, 0xffff0052, 0xffff0053, 0x54ffff, 0x55ffff,\n        0x56ffff, 0x57ffff, 0x58ffff, 0x59ffff, 0x5affff, 0x5bffff, 0xffffffff,\n        0xffff005c, 0xffff005d, 0xffff005e, 0xffff005f, 0xffff0060, 0xffff0061,\n        0xffff0062, 0xffff0063, 0xffff0064, 0xffff0065, 0xffff0066, 0xffff0067,\n        0xffff0068, 0xffff0069, 0xffff006a, 0xffff006b, 0xffff006c, 0xffff006d,\n        0xffff006e, 0xffff006f, 0xffff0070, 0xffff0071, 0xffff0072, 0x740073,\n        0x75ffff, 0x76ffff, 0xffffffff, 0x77ffff, 0xffff0078, 0xffff0079,\n        0x7b007a, 0x7cffff, 0x7e007d, 0xffffffff, 0x80007f, 0x820081, 0x83ffff,\n        0xffff0084, 0x860085, 0xffff0087, 0xffffffff, 0x890088, 0x8affff,\n        0xffff008b, 0xffff008c, 0xffff008d, 0x8f008e, 0x90ffff, 0xffffffff,\n        0xffff0091, 0x930092, 0x94ffff, 0x960095, 0x97ffff, 0x98ffff,\n        0xffff0099, 0xffffffff, 0xffff009a, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x9c009b, 0x9dffff, 0xffff009e, 0xa0009f, 0xa1ffff, 0xa2ffff, 0xa3ffff,\n        0xa4ffff, 0xa5ffff, 0xa6ffff, 0xa7ffff, 0xa8ffff, 0xffffffff,\n        0xffff00a9, 0xffff00aa, 0xffff00ab, 0xffff00ac, 0xffff00ad, 0xffff00ae,\n        0xffff00af, 0xffff00b0, 0xffff00b1, 0xb2ffff, 0xffff00b3, 0xffff00b4,\n        0xb600b5, 0xffff00b7, 0xffff00b8, 0xffff00b9, 0xffff00ba, 0xffff00bb,\n        0xffff00bc, 0xffff00bd, 0xffff00be, 0xffff00bf, 0xffff00c0, 0xffff00c1,\n        0xffff00c2, 0xffff00c3, 0xffff00c4, 0xffff00c5, 0xffff00c6, 0xffff00c7,\n        0xffff00c8, 0xffff00c9, 0xffff00ca, 0xffff00cb, 0xffff00cc, 0xffff00cd,\n        0xffff00ce, 0xffff00cf, 0xffff00d0, 0xffff00d1, 0xffff00d2, 0xffff00d3,\n        0xffff00d4, 0xffffffff, 0xffffffff, 0xffffffff, 0xd600d5, 0xd7ffff,\n        0xffff00d8, 0xd9ffff, 0xdaffff, 0xdc00db, 0xffff00dd, 0xffff00de,\n        0xffff00df, 0xffff00e0, 0xffff00e1, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff00e2, 0xffff00e3, 0xffffffff,\n        0xffff00e4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffff00e5, 0xe700e6, 0xffff00e8, 0xffff00e9,\n        0xeb00ea, 0xecffff, 0xee00ed, 0xf000ef, 0xf200f1, 0xf400f3, 0xf600f5,\n        0xf800f7, 0xfa00f9, 0xfc00fb, 0xfdffff, 0xff00fe, 0x1010100, 0x1030102,\n        0x1050104, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x106ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0107,\n        0xffff0108, 0xffff0109, 0xffff010a, 0xffff010b, 0xffff010c, 0xffff010d,\n        0xffff010e, 0xffff010f, 0xffff0110, 0xffff0111, 0xffff0112, 0xffffffff,\n        0xffffffff, 0xffff0113, 0x114ffff, 0x115ffff, 0xffff0116, 0x117ffff,\n        0x1190118, 0x11b011a, 0x11d011c, 0x11f011e, 0x1210120, 0x1230122,\n        0x1250124, 0x1270126, 0x1290128, 0x12b012a, 0x12d012c, 0x12f012e,\n        0x1310130, 0x1330132, 0x1350134, 0x1370136, 0x1390138, 0x13b013a,\n        0x13d013c, 0x13f013e, 0x1410140, 0x1430142, 0x1450144, 0x1470146,\n        0x1490148, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff014a, 0xffff014b, 0xffff014c, 0xffff014d, 0xffff014e,\n        0xffff014f, 0xffff0150, 0xffff0151, 0xffff0152, 0xffff0153, 0xffff0154,\n        0xffff0155, 0xffff0156, 0xffff0157, 0xffff0158, 0xffff0159, 0xffff015a,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff015b, 0xffff015c,\n        0xffff015d, 0xffff015e, 0xffff015f, 0xffff0160, 0xffff0161, 0xffff0162,\n        0xffff0163, 0xffff0164, 0xffff0165, 0xffff0166, 0xffff0167, 0xffff0168,\n        0xffff0169, 0xffff016a, 0xffff016b, 0xffff016c, 0xffff016d, 0xffff016e,\n        0xffff016f, 0xffff0170, 0xffff0171, 0xffff0172, 0xffff0173, 0xffff0174,\n        0xffff0175, 0x1770176, 0x178ffff, 0x179ffff, 0x17affff, 0x17bffff,\n        0x17cffff, 0x17dffff, 0xffffffff, 0xffff017e, 0xffff017f, 0xffff0180,\n        0xffff0181, 0xffff0182, 0xffff0183, 0xffff0184, 0xffff0185, 0xffff0186,\n        0xffff0187, 0xffff0188, 0xffff0189, 0xffff018a, 0xffff018b, 0xffff018c,\n        0xffff018d, 0xffff018e, 0xffff018f, 0xffff0190, 0xffff0191, 0xffff0192,\n        0xffff0193, 0xffff0194, 0xffff0195, 0xffff0196, 0xffff0197, 0xffff0198,\n        0xffff0199, 0xffff019a, 0xffff019b, 0xffff019c, 0xffff019d, 0xffff019e,\n        0xffff019f, 0xffff01a0, 0xffff01a1, 0xffff01a2, 0xffff01a3, 0xffff01a4,\n        0xffff01a5, 0xffff01a6, 0xffff01a7, 0xffff01a8, 0xffff01a9, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x1aaffff, 0x1ac01ab, 0x1ae01ad,\n        0x1b001af, 0x1b201b1, 0x1b401b3, 0x1b601b5, 0x1b801b7, 0x1ba01b9,\n        0x1bc01bb, 0x1be01bd, 0x1c001bf, 0x1c201c1, 0x1c401c3, 0x1c601c5,\n        0x1c801c7, 0x1ca01c9, 0x1cc01cb, 0x1ce01cd, 0xffff01cf, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1d101d0,\n        0x1d301d2, 0x1d501d4, 0x1d701d6, 0x1d901d8, 0x1db01da, 0x1dd01dc,\n        0x1df01de, 0x1e101e0, 0x1e301e2, 0x1e501e4, 0x1e701e6, 0x1e901e8,\n        0x1eb01ea, 0x1ed01ec, 0x1ef01ee, 0x1f101f0, 0x1f301f2, 0x1f501f4,\n        0x1f6ffff, 0xffffffff, 0xffffffff, 0x1f7ffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff01f8,\n        0xffff01f9, 0xffff01fa, 0xffff01fb, 0xffff01fc, 0xffff01fd, 0xffff01fe,\n        0xffff01ff, 0xffff0200, 0xffff0201, 0xffff0202, 0xffff0203, 0xffff0204,\n        0xffff0205, 0xffff0206, 0xffff0207, 0xffff0208, 0xffff0209, 0xffff020a,\n        0xffff020b, 0xffff020c, 0xffff020d, 0xffff020e, 0xffff020f, 0xffff0210,\n        0xffff0211, 0xffff0212, 0xffff0213, 0xffff0214, 0xffff0215, 0xffff0216,\n        0xffff0217, 0xffff0218, 0xffff0219, 0xffff021a, 0xffff021b, 0xffff021c,\n        0xffff021d, 0xffff021e, 0xffff021f, 0xffff0220, 0xffff0221, 0xffff0222,\n        0xffff0223, 0xffff0224, 0xffff0225, 0xffff0226, 0xffff0227, 0xffff0228,\n        0xffff0229, 0xffff022a, 0xffff022b, 0xffff022c, 0xffff022d, 0xffff022e,\n        0xffff022f, 0xffff0230, 0xffff0231, 0xffff0232, 0xffff0233, 0xffff0234,\n        0xffff0235, 0xffff0236, 0xffff0237, 0xffff0238, 0xffff0239, 0xffff023a,\n        0xffff023b, 0xffff023c, 0xffff023d, 0xffff023e, 0xffff023f, 0xffff0240,\n        0xffff0241, 0xffff0242, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff0243, 0xffff0244, 0xffff0245, 0xffff0246, 0xffff0247, 0xffff0248,\n        0xffff0249, 0xffff024a, 0xffff024b, 0xffff024c, 0xffff024d, 0xffff024e,\n        0xffff024f, 0xffff0250, 0xffff0251, 0xffff0252, 0xffff0253, 0xffff0254,\n        0xffff0255, 0xffff0256, 0xffff0257, 0xffff0258, 0xffff0259, 0xffff025a,\n        0xffff025b, 0xffff025c, 0xffff025d, 0xffff025e, 0xffff025f, 0xffff0260,\n        0xffff0261, 0xffff0262, 0xffff0263, 0xffff0264, 0xffff0265, 0xffff0266,\n        0xffff0267, 0xffff0268, 0xffff0269, 0xffff026a, 0xffff026b, 0xffff026c,\n        0xffff026d, 0xffff026e, 0xffff026f, 0xffff0270, 0xffff0271, 0xffff0272,\n        0xffff0273, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2750274,\n        0x2770276, 0x2790278, 0x27b027a, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x27d027c, 0x27f027e, 0x2810280, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2830282, 0x2850284, 0x2870286,\n        0x2890288, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x28b028a,\n        0x28d028c, 0x28f028e, 0x2910290, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2930292, 0x2950294, 0x2970296, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x298ffff, 0x299ffff, 0x29affff,\n        0x29bffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x29d029c,\n        0x29f029e, 0x2a102a0, 0x2a302a2, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2a502a4, 0x2a702a6, 0x2a902a8,\n        0x2ab02aa, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2ad02ac,\n        0x2af02ae, 0x2b102b0, 0x2b302b2, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2b502b4, 0x2b702b6, 0x2b902b8, 0x2bb02ba, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2bd02bc, 0x2bf02be, 0xffff02c0,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2c202c1,\n        0x2c402c3, 0xffff02c5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2c702c6, 0x2c902c8, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2cb02ca, 0x2cd02cc, 0xffff02ce,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2d002cf,\n        0x2d202d1, 0xffff02d3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff02d4, 0xffffffff,\n        0x2d602d5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff02d7, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2d902d8, 0x2db02da, 0x2dd02dc,\n        0x2df02de, 0x2e102e0, 0x2e302e2, 0x2e502e4, 0x2e702e6, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x2e8ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x2ea02e9, 0x2ec02eb, 0x2ee02ed, 0x2f002ef, 0x2f202f1, 0x2f402f3,\n        0x2f602f5, 0x2f802f7, 0x2fa02f9, 0x2fc02fb, 0x2fe02fd, 0x30002ff,\n        0x3020301, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x3040303, 0x3060305, 0x3080307, 0x30a0309, 0x30c030b,\n        0x30e030d, 0x310030f, 0x3120311, 0x3140313, 0x3160315, 0x3180317,\n        0x31a0319, 0x31c031b, 0x31e031d, 0x320031f, 0x3220321, 0x3240323,\n        0x3260325, 0x3280327, 0x32a0329, 0x32c032b, 0x32e032d, 0x330032f,\n        0xffff0331, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff0332, 0x3340333, 0xffff0335, 0x336ffff, 0x337ffff,\n        0x338ffff, 0x339ffff, 0x33b033a, 0xffff033c, 0xffff033d, 0x33effff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x340033f, 0xffff0341,\n        0xffff0342, 0xffff0343, 0xffff0344, 0xffff0345, 0xffff0346, 0xffff0347,\n        0xffff0348, 0xffff0349, 0xffff034a, 0xffff034b, 0xffff034c, 0xffff034d,\n        0xffff034e, 0xffff034f, 0xffff0350, 0xffff0351, 0xffff0352, 0xffff0353,\n        0xffff0354, 0xffff0355, 0xffff0356, 0xffff0357, 0xffff0358, 0xffff0359,\n        0xffff035a, 0xffff035b, 0xffff035c, 0xffff035d, 0xffff035e, 0xffff035f,\n        0xffff0360, 0xffff0361, 0xffff0362, 0xffff0363, 0xffff0364, 0xffff0365,\n        0xffff0366, 0xffff0367, 0xffff0368, 0xffff0369, 0xffff036a, 0xffff036b,\n        0xffff036c, 0xffff036d, 0xffff036e, 0xffff036f, 0xffff0370, 0xffff0371,\n        0xffff0372, 0xffffffff, 0xffffffff, 0xffffffff, 0x373ffff, 0x374ffff,\n        0xffffffff, 0xffffffff, 0xffff0375, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff0376, 0xffff0377, 0xffff0378,\n        0xffff0379, 0xffff037a, 0xffff037b, 0xffff037c, 0xffff037d, 0xffff037e,\n        0xffff037f, 0xffff0380, 0xffff0381, 0xffff0382, 0xffff0383, 0xffff0384,\n        0xffff0385, 0xffff0386, 0xffff0387, 0xffff0388, 0xffff0389, 0xffff038a,\n        0xffff038b, 0xffff038c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff038d,\n        0xffff038e, 0xffff038f, 0xffff0390, 0xffff0391, 0xffff0392, 0xffff0393,\n        0xffff0394, 0xffff0395, 0xffff0396, 0xffff0397, 0xffff0398, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffff0399, 0xffff039a, 0xffff039b, 0xffff039c, 0xffff039d, 0xffff039e,\n        0xffff039f, 0xffffffff, 0xffff03a0, 0xffff03a1, 0xffff03a2, 0xffff03a3,\n        0xffff03a4, 0xffff03a5, 0xffff03a6, 0xffff03a7, 0xffff03a8, 0xffff03a9,\n        0xffff03aa, 0xffff03ab, 0xffff03ac, 0xffff03ad, 0xffff03ae, 0xffff03af,\n        0xffff03b0, 0xffff03b1, 0xffff03b2, 0xffff03b3, 0xffff03b4, 0xffff03b5,\n        0xffff03b6, 0xffff03b7, 0xffff03b8, 0xffff03b9, 0xffff03ba, 0xffff03bb,\n        0xffff03bc, 0xffff03bd, 0xffff03be, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x3bfffff, 0x3c0ffff, 0x3c1ffff, 0xffff03c2, 0xffff03c3,\n        0xffff03c4, 0xffff03c5, 0xffff03c6, 0xffffffff, 0x3c7ffff, 0x3c8ffff,\n        0xffffffff, 0xffff03c9, 0xffff03ca, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffff03cb, 0xffff03cc, 0xffff03cd,\n        0xffff03ce, 0xffff03cf, 0xffff03d0, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3d1ffff,\n        0x3d303d2, 0x3d503d4, 0x3d703d6, 0x3d903d8, 0x3db03da, 0x3dd03dc,\n        0x3df03de, 0x3e103e0, 0x3e303e2, 0x3e503e4, 0x3e703e6, 0x3e903e8,\n        0xffff03ea, 0xffffffff, 0xffffffff, 0x3ec03eb, 0x3ee03ed, 0x3f003ef,\n        0x3f203f1, 0x3f403f3, 0x3f603f5, 0x3f803f7, 0x3fa03f9, 0x3fc03fb,\n        0x3fe03fd, 0x40003ff, 0x4020401, 0x4040403, 0x4060405, 0x4080407,\n        0x40a0409, 0x40c040b, 0x40e040d, 0x410040f, 0x4120411, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff]);\n//8064 bytes\nenum toTitleSimpleIndexTrieEntries = TrieEntry!(ushort, 8, 7, 6)([0x0, 0x40,\n        0x200], [0x100, 0x380, 0xbc0], [0x2020100, 0x4020302, 0x2020205,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202,\n        0x2020202, 0x10000, 0x30002, 0x50004, 0x70006, 0x90008, 0xa, 0xb0000,\n        0xd000c, 0xf000e, 0x110010, 0x130012, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x150000, 0x0, 0x170016, 0x190018, 0x1b001a, 0x1d001c, 0x0, 0x0,\n        0x1e0000, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x220021, 0x240023,\n        0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x260000, 0x27, 0x290028, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x2d002c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff,\n        0x20001, 0x40003, 0x60005, 0x80007, 0xa0009, 0xc000b, 0xe000d,\n        0x10000f, 0x120011, 0x140013, 0x160015, 0x180017, 0xffff0019,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1affff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x1c001b, 0x1e001d, 0x20001f, 0x220021,\n        0x240023, 0x260025, 0x280027, 0x2a0029, 0x2c002b, 0x2e002d, 0x30002f,\n        0xffff0031, 0x330032, 0x350034, 0x370036, 0x390038, 0x3affff, 0x3bffff,\n        0x3cffff, 0x3dffff, 0x3effff, 0x3fffff, 0x40ffff, 0x41ffff, 0x42ffff,\n        0x43ffff, 0x44ffff, 0x45ffff, 0x46ffff, 0x47ffff, 0x48ffff, 0x49ffff,\n        0x4affff, 0x4bffff, 0x4cffff, 0x4dffff, 0x4effff, 0x4fffff, 0x50ffff,\n        0x51ffff, 0x52ffff, 0x53ffff, 0x54ffff, 0x55ffff, 0xffffffff,\n        0xffff0056, 0xffff0057, 0xffff0058, 0xffff0059, 0xffff005a, 0xffff005b,\n        0xffff005c, 0xffff005d, 0x5effff, 0x5fffff, 0x60ffff, 0x61ffff,\n        0x62ffff, 0x63ffff, 0x64ffff, 0x65ffff, 0x66ffff, 0x67ffff, 0x68ffff,\n        0x69ffff, 0x6affff, 0x6bffff, 0x6cffff, 0x6dffff, 0x6effff, 0x6fffff,\n        0x70ffff, 0x71ffff, 0x72ffff, 0x73ffff, 0x74ffff, 0xffffffff,\n        0xffff0075, 0xffff0076, 0x780077, 0xffff0079, 0x7affff, 0x7bffff,\n        0xffffffff, 0xffff007c, 0xffffffff, 0xffff007d, 0xffffffff, 0xffffffff,\n        0xffff007e, 0x7fffff, 0xffffffff, 0x80ffff, 0xffff0081, 0xffffffff,\n        0xffff0082, 0x83ffff, 0x84ffff, 0x85ffff, 0xffffffff, 0xffff0086,\n        0xffffffff, 0x87ffff, 0xffffffff, 0xffff0088, 0xffffffff, 0xffff0089,\n        0xffff008a, 0x8bffff, 0xffffffff, 0x8cffff, 0x8dffff, 0xffffffff,\n        0xffffffff, 0x8f008e, 0x910090, 0x930092, 0x950094, 0xffff0096,\n        0xffff0097, 0xffff0098, 0xffff0099, 0xffff009a, 0xffff009b, 0xffff009c,\n        0xffff009d, 0x9f009e, 0xa0ffff, 0xa1ffff, 0xa2ffff, 0xa3ffff, 0xa4ffff,\n        0xa5ffff, 0xa6ffff, 0xa7ffff, 0xa8ffff, 0xa9ffff, 0xab00aa, 0xacffff,\n        0xffffffff, 0xadffff, 0xaeffff, 0xafffff, 0xb0ffff, 0xb1ffff, 0xb2ffff,\n        0xb3ffff, 0xb4ffff, 0xb5ffff, 0xb6ffff, 0xb7ffff, 0xb8ffff, 0xb9ffff,\n        0xbaffff, 0xbbffff, 0xbcffff, 0xbdffff, 0xbeffff, 0xbfffff, 0xc0ffff,\n        0xffffffff, 0xc1ffff, 0xc2ffff, 0xc3ffff, 0xc4ffff, 0xc5ffff, 0xc6ffff,\n        0xc7ffff, 0xc8ffff, 0xc9ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffff00ca, 0xcbffff, 0xffff00cc, 0xffff00cd, 0xffffffff,\n        0xceffff, 0xcfffff, 0xd0ffff, 0xd1ffff, 0xd2ffff, 0xd400d3, 0xd600d5,\n        0xffff00d7, 0xd900d8, 0xdaffff, 0xdbffff, 0xffffffff, 0xffffffff,\n        0xffff00dc, 0xddffff, 0xdeffff, 0xffff00df, 0xe100e0, 0xe2ffff,\n        0xffffffff, 0xe3ffff, 0xe4ffff, 0xffff00e5, 0xe6ffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xe7ffff, 0xffffffff, 0xffff00e8, 0xe9ffff,\n        0xffffffff, 0xffffffff, 0xeb00ea, 0xed00ec, 0xffff00ee, 0xffffffff,\n        0xffffffff, 0xffff00ef, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xf0ffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xf1ffff, 0xf2ffff, 0xffffffff, 0xf3ffff, 0xffffffff, 0xf4ffff,\n        0xf600f5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xf800f7, 0xfa00f9, 0xfbffff, 0xfd00fc, 0xff00fe, 0x1010100, 0x1030102,\n        0x1050104, 0x1070106, 0x1090108, 0x10b010a, 0x10d010c, 0x10f010e,\n        0x1110110, 0x1130112, 0x1150114, 0x1170116, 0xffff0118, 0x11a0119,\n        0xffffffff, 0x11bffff, 0x11d011c, 0x11effff, 0x11fffff, 0x120ffff,\n        0x121ffff, 0x122ffff, 0x123ffff, 0x124ffff, 0x125ffff, 0x126ffff,\n        0x127ffff, 0x128ffff, 0x129ffff, 0x12b012a, 0xffff012c, 0x12dffff,\n        0xffffffff, 0xffff012e, 0x12fffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1310130,\n        0x1330132, 0x1350134, 0x1370136, 0x1390138, 0x13b013a, 0x13d013c,\n        0x13f013e, 0x1410140, 0x1430142, 0x1450144, 0x1470146, 0x1490148,\n        0x14b014a, 0x14d014c, 0x14f014e, 0x1510150, 0x1530152, 0x1550154,\n        0x1570156, 0x1590158, 0x15b015a, 0x15d015c, 0x15f015e, 0x160ffff,\n        0x161ffff, 0x162ffff, 0x163ffff, 0x164ffff, 0x165ffff, 0x166ffff,\n        0x167ffff, 0x168ffff, 0x169ffff, 0x16affff, 0x16bffff, 0x16cffff,\n        0x16dffff, 0x16effff, 0x16fffff, 0x170ffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x171ffff, 0x172ffff, 0x173ffff, 0x174ffff,\n        0x175ffff, 0x176ffff, 0x177ffff, 0x178ffff, 0x179ffff, 0x17affff,\n        0x17bffff, 0x17cffff, 0x17dffff, 0x17effff, 0x17fffff, 0x180ffff,\n        0x181ffff, 0x182ffff, 0x183ffff, 0x184ffff, 0x185ffff, 0x186ffff,\n        0x187ffff, 0x188ffff, 0x189ffff, 0x18affff, 0x18bffff, 0xffffffff,\n        0xffff018c, 0xffff018d, 0xffff018e, 0xffff018f, 0xffff0190, 0xffff0191,\n        0x1930192, 0x194ffff, 0x195ffff, 0x196ffff, 0x197ffff, 0x198ffff,\n        0x199ffff, 0x19affff, 0x19bffff, 0x19cffff, 0x19dffff, 0x19effff,\n        0x19fffff, 0x1a0ffff, 0x1a1ffff, 0x1a2ffff, 0x1a3ffff, 0x1a4ffff,\n        0x1a5ffff, 0x1a6ffff, 0x1a7ffff, 0x1a8ffff, 0x1a9ffff, 0x1aaffff,\n        0x1abffff, 0x1acffff, 0x1adffff, 0x1aeffff, 0x1afffff, 0x1b0ffff,\n        0x1b1ffff, 0x1b2ffff, 0x1b3ffff, 0x1b4ffff, 0x1b5ffff, 0x1b6ffff,\n        0x1b7ffff, 0x1b8ffff, 0x1b9ffff, 0x1baffff, 0x1bbffff, 0x1bcffff,\n        0x1bdffff, 0x1beffff, 0x1bfffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x1c0ffff, 0x1c201c1, 0x1c401c3, 0x1c601c5, 0x1c801c7,\n        0x1ca01c9, 0x1cc01cb, 0x1ce01cd, 0x1d001cf, 0x1d201d1, 0x1d401d3,\n        0x1d601d5, 0x1d801d7, 0x1da01d9, 0x1dc01db, 0x1de01dd, 0x1e001df,\n        0x1e201e1, 0x1e401e3, 0xffff01e5, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1e6ffff,\n        0xffffffff, 0x1e7ffff, 0xffffffff, 0x1e8ffff, 0x1e9ffff, 0x1eaffff,\n        0x1ebffff, 0x1ecffff, 0x1edffff, 0x1eeffff, 0x1efffff, 0x1f0ffff,\n        0x1f1ffff, 0x1f2ffff, 0x1f3ffff, 0x1f4ffff, 0x1f5ffff, 0x1f6ffff,\n        0x1f7ffff, 0x1f8ffff, 0x1f9ffff, 0x1faffff, 0x1fbffff, 0x1fcffff,\n        0x1fdffff, 0x1feffff, 0x1ffffff, 0x200ffff, 0x201ffff, 0x202ffff,\n        0x203ffff, 0x204ffff, 0x205ffff, 0x206ffff, 0x207ffff, 0x208ffff,\n        0x209ffff, 0x20affff, 0x20bffff, 0x20cffff, 0x20dffff, 0x20effff,\n        0x20fffff, 0x210ffff, 0x211ffff, 0x212ffff, 0x213ffff, 0x214ffff,\n        0x215ffff, 0x216ffff, 0x217ffff, 0x218ffff, 0x219ffff, 0x21affff,\n        0x21bffff, 0x21cffff, 0x21dffff, 0x21effff, 0x21fffff, 0x220ffff,\n        0x221ffff, 0x222ffff, 0x223ffff, 0x224ffff, 0x225ffff, 0x226ffff,\n        0x227ffff, 0x228ffff, 0x229ffff, 0x22affff, 0x22bffff, 0x22cffff,\n        0x22dffff, 0x22effff, 0x22fffff, 0x230ffff, 0x231ffff, 0x232ffff,\n        0xffffffff, 0xffffffff, 0x233ffff, 0xffffffff, 0xffffffff, 0x234ffff,\n        0x235ffff, 0x236ffff, 0x237ffff, 0x238ffff, 0x239ffff, 0x23affff,\n        0x23bffff, 0x23cffff, 0x23dffff, 0x23effff, 0x23fffff, 0x240ffff,\n        0x241ffff, 0x242ffff, 0x243ffff, 0x244ffff, 0x245ffff, 0x246ffff,\n        0x247ffff, 0x248ffff, 0x249ffff, 0x24affff, 0x24bffff, 0x24cffff,\n        0x24dffff, 0x24effff, 0x24fffff, 0x250ffff, 0x251ffff, 0x252ffff,\n        0x253ffff, 0x254ffff, 0x255ffff, 0x256ffff, 0x257ffff, 0x258ffff,\n        0x259ffff, 0x25affff, 0x25bffff, 0x25cffff, 0x25dffff, 0x25effff,\n        0x25fffff, 0x260ffff, 0x261ffff, 0x262ffff, 0x263ffff, 0x2650264,\n        0x2670266, 0x2690268, 0x26b026a, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x26d026c, 0x26f026e, 0x2710270, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2730272, 0x2750274, 0x2770276,\n        0x2790278, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x27b027a,\n        0x27d027c, 0x27f027e, 0x2810280, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2830282, 0x2850284, 0x2870286, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x288ffff, 0x289ffff, 0x28affff,\n        0x28bffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x28d028c,\n        0x28f028e, 0x2910290, 0x2930292, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2950294, 0x2970296, 0x2990298, 0x29b029a, 0x29d029c,\n        0x29f029e, 0x2a102a0, 0xffffffff, 0x2a302a2, 0x2a502a4, 0x2a702a6,\n        0x2a902a8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2ab02aa,\n        0x2ad02ac, 0x2af02ae, 0x2b102b0, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2b302b2, 0x2b502b4, 0x2b702b6, 0x2b902b8, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2bb02ba, 0x2bcffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff02bd, 0xffffffff,\n        0x2beffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2c002bf, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x2c202c1, 0xffffffff, 0x2c3ffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0x2c4ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffff02c5, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2c702c6, 0x2c902c8, 0x2cb02ca, 0x2cd02cc, 0x2cf02ce,\n        0x2d102d0, 0x2d302d2, 0x2d502d4, 0xffffffff, 0xffffffff, 0xffff02d6,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2d802d7, 0x2da02d9, 0x2dc02db, 0x2de02dd, 0x2e002df,\n        0x2e202e1, 0x2e402e3, 0x2e602e5, 0x2e802e7, 0x2ea02e9, 0x2ec02eb,\n        0x2ee02ed, 0x2f002ef, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x2f202f1, 0x2f402f3, 0x2f602f5, 0x2f802f7, 0x2fa02f9,\n        0x2fc02fb, 0x2fe02fd, 0x30002ff, 0x3020301, 0x3040303, 0x3060305,\n        0x3080307, 0x30a0309, 0x30c030b, 0x30e030d, 0x310030f, 0x3120311,\n        0x3140313, 0x3160315, 0x3180317, 0x31a0319, 0x31c031b, 0x31e031d,\n        0xffff031f, 0x320ffff, 0xffffffff, 0x321ffff, 0xffff0322, 0xffff0323,\n        0xffff0324, 0xffff0325, 0xffffffff, 0xffffffff, 0x326ffff, 0xffffffff,\n        0xffff0327, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x328ffff,\n        0x329ffff, 0x32affff, 0x32bffff, 0x32cffff, 0x32dffff, 0x32effff,\n        0x32fffff, 0x330ffff, 0x331ffff, 0x332ffff, 0x333ffff, 0x334ffff,\n        0x335ffff, 0x336ffff, 0x337ffff, 0x338ffff, 0x339ffff, 0x33affff,\n        0x33bffff, 0x33cffff, 0x33dffff, 0x33effff, 0x33fffff, 0x340ffff,\n        0x341ffff, 0x342ffff, 0x343ffff, 0x344ffff, 0x345ffff, 0x346ffff,\n        0x347ffff, 0x348ffff, 0x349ffff, 0x34affff, 0x34bffff, 0x34cffff,\n        0x34dffff, 0x34effff, 0x34fffff, 0x350ffff, 0x351ffff, 0x352ffff,\n        0x353ffff, 0x354ffff, 0x355ffff, 0x356ffff, 0x357ffff, 0x358ffff,\n        0x359ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff035a,\n        0xffff035b, 0xffffffff, 0x35cffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x35e035d, 0x360035f, 0x3620361,\n        0x3640363, 0x3660365, 0x3680367, 0x36a0369, 0x36c036b, 0x36e036d,\n        0x370036f, 0x3720371, 0x3740373, 0x3760375, 0x3780377, 0x37a0379,\n        0x37c037b, 0x37e037d, 0x380037f, 0x3820381, 0x383ffff, 0xffffffff,\n        0xffffffff, 0x384ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x385ffff,\n        0x386ffff, 0x387ffff, 0x388ffff, 0x389ffff, 0x38affff, 0x38bffff,\n        0x38cffff, 0x38dffff, 0x38effff, 0x38fffff, 0x390ffff, 0x391ffff,\n        0x392ffff, 0x393ffff, 0x394ffff, 0x395ffff, 0x396ffff, 0x397ffff,\n        0x398ffff, 0x399ffff, 0x39affff, 0x39bffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x39cffff, 0x39dffff, 0x39effff, 0x39fffff, 0x3a0ffff,\n        0x3a1ffff, 0x3a2ffff, 0x3a3ffff, 0x3a4ffff, 0x3a5ffff, 0x3a6ffff,\n        0x3a7ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0x3a8ffff, 0x3a9ffff, 0x3aaffff, 0x3abffff,\n        0x3acffff, 0x3adffff, 0x3aeffff, 0xffffffff, 0x3afffff, 0x3b0ffff,\n        0x3b1ffff, 0x3b2ffff, 0x3b3ffff, 0x3b4ffff, 0x3b5ffff, 0x3b6ffff,\n        0x3b7ffff, 0x3b8ffff, 0x3b9ffff, 0x3baffff, 0x3bbffff, 0x3bcffff,\n        0x3bdffff, 0x3beffff, 0x3bfffff, 0x3c0ffff, 0x3c1ffff, 0x3c2ffff,\n        0x3c3ffff, 0x3c4ffff, 0x3c5ffff, 0x3c6ffff, 0x3c7ffff, 0x3c8ffff,\n        0x3c9ffff, 0x3caffff, 0x3cbffff, 0x3ccffff, 0x3cdffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff03ce, 0xffff03cf,\n        0x3d0ffff, 0x3d1ffff, 0x3d2ffff, 0x3d3ffff, 0x3d4ffff, 0xffffffff,\n        0xffffffff, 0xffff03d5, 0xffffffff, 0x3d6ffff, 0x3d7ffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3d8ffff,\n        0x3d9ffff, 0x3daffff, 0x3dbffff, 0x3dcffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0x3ddffff, 0x3df03de, 0x3e103e0,\n        0x3e303e2, 0x3e503e4, 0x3e703e6, 0x3e903e8, 0x3eb03ea, 0x3ed03ec,\n        0x3ef03ee, 0x3f103f0, 0x3f303f2, 0x3f503f4, 0xffff03f6, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0x3f803f7, 0x3fa03f9, 0x3fc03fb, 0x3fe03fd, 0x40003ff,\n        0x4020401, 0x4040403, 0x4060405, 0x4080407, 0x40a0409, 0x40c040b,\n        0x40e040d, 0x410040f, 0x4120411, 0x4140413, 0x4160415, 0x4180417,\n        0x41a0419, 0x41c041b, 0x41e041d, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,\n        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff]);\n@property\n{\nprivate alias _IUA = immutable(uint[]);\n_IUA toUpperTable()\n{\n    static _IUA t = [\n        0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c,\n        0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,\n        0x59, 0x5a, 0x39c, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,\n        0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,\n        0xd4, 0xd5, 0xd6, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x178,\n        0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e, 0x110, 0x112,\n        0x114, 0x116, 0x118, 0x11a, 0x11c, 0x11e, 0x120, 0x122, 0x124, 0x126,\n        0x128, 0x12a, 0x12c, 0x12e, 0x49, 0x132, 0x134, 0x136, 0x139, 0x13b,\n        0x13d, 0x13f, 0x141, 0x143, 0x145, 0x147, 0x14a, 0x14c, 0x14e, 0x150,\n        0x152, 0x154, 0x156, 0x158, 0x15a, 0x15c, 0x15e, 0x160, 0x162, 0x164,\n        0x166, 0x168, 0x16a, 0x16c, 0x16e, 0x170, 0x172, 0x174, 0x176, 0x179,\n        0x17b, 0x17d, 0x53, 0x243, 0x182, 0x184, 0x187, 0x18b, 0x191, 0x1f6,\n        0x198, 0x23d, 0x220, 0x1a0, 0x1a2, 0x1a4, 0x1a7, 0x1ac, 0x1af, 0x1b3,\n        0x1b5, 0x1b8, 0x1bc, 0x1f7, 0x1c4, 0x1c4, 0x1c7, 0x1c7, 0x1ca, 0x1ca,\n        0x1cd, 0x1cf, 0x1d1, 0x1d3, 0x1d5, 0x1d7, 0x1d9, 0x1db, 0x18e, 0x1de,\n        0x1e0, 0x1e2, 0x1e4, 0x1e6, 0x1e8, 0x1ea, 0x1ec, 0x1ee, 0x1f1, 0x1f1,\n        0x1f4, 0x1f8, 0x1fa, 0x1fc, 0x1fe, 0x200, 0x202, 0x204, 0x206, 0x208,\n        0x20a, 0x20c, 0x20e, 0x210, 0x212, 0x214, 0x216, 0x218, 0x21a, 0x21c,\n        0x21e, 0x222, 0x224, 0x226, 0x228, 0x22a, 0x22c, 0x22e, 0x230, 0x232,\n        0x23b, 0x2c7e, 0x2c7f, 0x241, 0x246, 0x248, 0x24a, 0x24c, 0x24e,\n        0x2c6f, 0x2c6d, 0x2c70, 0x181, 0x186, 0x189, 0x18a, 0x18f, 0x190,\n        0x193, 0x194, 0xa78d, 0xa7aa, 0x197, 0x196, 0x2c62, 0x19c, 0x2c6e,\n        0x19d, 0x19f, 0x2c64, 0x1a6, 0x1a9, 0x1ae, 0x244, 0x1b1, 0x1b2, 0x245,\n        0x1b7, 0x399, 0x370, 0x372, 0x376, 0x3fd, 0x3fe, 0x3ff, 0x386, 0x388,\n        0x389, 0x38a, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398,\n        0x399, 0x39a, 0x39b, 0x39c, 0x39d, 0x39e, 0x39f, 0x3a0, 0x3a1, 0x3a3,\n        0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7, 0x3a8, 0x3a9, 0x3aa, 0x3ab, 0x38c,\n        0x38e, 0x38f, 0x392, 0x398, 0x3a6, 0x3a0, 0x3cf, 0x3d8, 0x3da, 0x3dc,\n        0x3de, 0x3e0, 0x3e2, 0x3e4, 0x3e6, 0x3e8, 0x3ea, 0x3ec, 0x3ee, 0x39a,\n        0x3a1, 0x3f9, 0x395, 0x3f7, 0x3fa, 0x410, 0x411, 0x412, 0x413, 0x414,\n        0x415, 0x416, 0x417, 0x418, 0x419, 0x41a, 0x41b, 0x41c, 0x41d, 0x41e,\n        0x41f, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428,\n        0x429, 0x42a, 0x42b, 0x42c, 0x42d, 0x42e, 0x42f, 0x400, 0x401, 0x402,\n        0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40a, 0x40b, 0x40c,\n        0x40d, 0x40e, 0x40f, 0x460, 0x462, 0x464, 0x466, 0x468, 0x46a, 0x46c,\n        0x46e, 0x470, 0x472, 0x474, 0x476, 0x478, 0x47a, 0x47c, 0x47e, 0x480,\n        0x48a, 0x48c, 0x48e, 0x490, 0x492, 0x494, 0x496, 0x498, 0x49a, 0x49c,\n        0x49e, 0x4a0, 0x4a2, 0x4a4, 0x4a6, 0x4a8, 0x4aa, 0x4ac, 0x4ae, 0x4b0,\n        0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x4bc, 0x4be, 0x4c1, 0x4c3, 0x4c5,\n        0x4c7, 0x4c9, 0x4cb, 0x4cd, 0x4c0, 0x4d0, 0x4d2, 0x4d4, 0x4d6, 0x4d8,\n        0x4da, 0x4dc, 0x4de, 0x4e0, 0x4e2, 0x4e4, 0x4e6, 0x4e8, 0x4ea, 0x4ec,\n        0x4ee, 0x4f0, 0x4f2, 0x4f4, 0x4f6, 0x4f8, 0x4fa, 0x4fc, 0x4fe, 0x500,\n        0x502, 0x504, 0x506, 0x508, 0x50a, 0x50c, 0x50e, 0x510, 0x512, 0x514,\n        0x516, 0x518, 0x51a, 0x51c, 0x51e, 0x520, 0x522, 0x524, 0x526, 0x531,\n        0x532, 0x533, 0x534, 0x535, 0x536, 0x537, 0x538, 0x539, 0x53a, 0x53b,\n        0x53c, 0x53d, 0x53e, 0x53f, 0x540, 0x541, 0x542, 0x543, 0x544, 0x545,\n        0x546, 0x547, 0x548, 0x549, 0x54a, 0x54b, 0x54c, 0x54d, 0x54e, 0x54f,\n        0x550, 0x551, 0x552, 0x553, 0x554, 0x555, 0x556, 0xa77d, 0x2c63,\n        0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08, 0x1e0a, 0x1e0c, 0x1e0e, 0x1e10,\n        0x1e12, 0x1e14, 0x1e16, 0x1e18, 0x1e1a, 0x1e1c, 0x1e1e, 0x1e20, 0x1e22,\n        0x1e24, 0x1e26, 0x1e28, 0x1e2a, 0x1e2c, 0x1e2e, 0x1e30, 0x1e32, 0x1e34,\n        0x1e36, 0x1e38, 0x1e3a, 0x1e3c, 0x1e3e, 0x1e40, 0x1e42, 0x1e44, 0x1e46,\n        0x1e48, 0x1e4a, 0x1e4c, 0x1e4e, 0x1e50, 0x1e52, 0x1e54, 0x1e56, 0x1e58,\n        0x1e5a, 0x1e5c, 0x1e5e, 0x1e60, 0x1e62, 0x1e64, 0x1e66, 0x1e68, 0x1e6a,\n        0x1e6c, 0x1e6e, 0x1e70, 0x1e72, 0x1e74, 0x1e76, 0x1e78, 0x1e7a, 0x1e7c,\n        0x1e7e, 0x1e80, 0x1e82, 0x1e84, 0x1e86, 0x1e88, 0x1e8a, 0x1e8c, 0x1e8e,\n        0x1e90, 0x1e92, 0x1e94, 0x1e60, 0x1ea0, 0x1ea2, 0x1ea4, 0x1ea6, 0x1ea8,\n        0x1eaa, 0x1eac, 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4, 0x1eb6, 0x1eb8, 0x1eba,\n        0x1ebc, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ec8, 0x1eca, 0x1ecc,\n        0x1ece, 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, 0x1eda, 0x1edc, 0x1ede,\n        0x1ee0, 0x1ee2, 0x1ee4, 0x1ee6, 0x1ee8, 0x1eea, 0x1eec, 0x1eee, 0x1ef0,\n        0x1ef2, 0x1ef4, 0x1ef6, 0x1ef8, 0x1efa, 0x1efc, 0x1efe, 0x1f08, 0x1f09,\n        0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, 0x1f18, 0x1f19, 0x1f1a,\n        0x1f1b, 0x1f1c, 0x1f1d, 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, 0x1f2c, 0x1f2d,\n        0x1f2e, 0x1f2f, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, 0x1f3e,\n        0x1f3f, 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0x1f59, 0x1f5b,\n        0x1f5d, 0x1f5f, 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e,\n        0x1f6f, 0x1fba, 0x1fbb, 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda, 0x1fdb,\n        0x1ff8, 0x1ff9, 0x1fea, 0x1feb, 0x1ffa, 0x1ffb, 0x1f88, 0x1f89, 0x1f8a,\n        0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f98, 0x1f99, 0x1f9a, 0x1f9b,\n        0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac,\n        0x1fad, 0x1fae, 0x1faf, 0x1fb8, 0x1fb9, 0x1fbc, 0x399, 0x1fcc, 0x1fd8,\n        0x1fd9, 0x1fe8, 0x1fe9, 0x1fec, 0x1ffc, 0x2132, 0x2160, 0x2161, 0x2162,\n        0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216a, 0x216b,\n        0x216c, 0x216d, 0x216e, 0x216f, 0x2183, 0x24b6, 0x24b7, 0x24b8, 0x24b9,\n        0x24ba, 0x24bb, 0x24bc, 0x24bd, 0x24be, 0x24bf, 0x24c0, 0x24c1, 0x24c2,\n        0x24c3, 0x24c4, 0x24c5, 0x24c6, 0x24c7, 0x24c8, 0x24c9, 0x24ca, 0x24cb,\n        0x24cc, 0x24cd, 0x24ce, 0x24cf, 0x2c00, 0x2c01, 0x2c02, 0x2c03, 0x2c04,\n        0x2c05, 0x2c06, 0x2c07, 0x2c08, 0x2c09, 0x2c0a, 0x2c0b, 0x2c0c, 0x2c0d,\n        0x2c0e, 0x2c0f, 0x2c10, 0x2c11, 0x2c12, 0x2c13, 0x2c14, 0x2c15, 0x2c16,\n        0x2c17, 0x2c18, 0x2c19, 0x2c1a, 0x2c1b, 0x2c1c, 0x2c1d, 0x2c1e, 0x2c1f,\n        0x2c20, 0x2c21, 0x2c22, 0x2c23, 0x2c24, 0x2c25, 0x2c26, 0x2c27, 0x2c28,\n        0x2c29, 0x2c2a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e, 0x2c60, 0x23a, 0x23e,\n        0x2c67, 0x2c69, 0x2c6b, 0x2c72, 0x2c75, 0x2c80, 0x2c82, 0x2c84, 0x2c86,\n        0x2c88, 0x2c8a, 0x2c8c, 0x2c8e, 0x2c90, 0x2c92, 0x2c94, 0x2c96, 0x2c98,\n        0x2c9a, 0x2c9c, 0x2c9e, 0x2ca0, 0x2ca2, 0x2ca4, 0x2ca6, 0x2ca8, 0x2caa,\n        0x2cac, 0x2cae, 0x2cb0, 0x2cb2, 0x2cb4, 0x2cb6, 0x2cb8, 0x2cba, 0x2cbc,\n        0x2cbe, 0x2cc0, 0x2cc2, 0x2cc4, 0x2cc6, 0x2cc8, 0x2cca, 0x2ccc, 0x2cce,\n        0x2cd0, 0x2cd2, 0x2cd4, 0x2cd6, 0x2cd8, 0x2cda, 0x2cdc, 0x2cde, 0x2ce0,\n        0x2ce2, 0x2ceb, 0x2ced, 0x2cf2, 0x10a0, 0x10a1, 0x10a2, 0x10a3, 0x10a4,\n        0x10a5, 0x10a6, 0x10a7, 0x10a8, 0x10a9, 0x10aa, 0x10ab, 0x10ac, 0x10ad,\n        0x10ae, 0x10af, 0x10b0, 0x10b1, 0x10b2, 0x10b3, 0x10b4, 0x10b5, 0x10b6,\n        0x10b7, 0x10b8, 0x10b9, 0x10ba, 0x10bb, 0x10bc, 0x10bd, 0x10be, 0x10bf,\n        0x10c0, 0x10c1, 0x10c2, 0x10c3, 0x10c4, 0x10c5, 0x10c7, 0x10cd, 0xa640,\n        0xa642, 0xa644, 0xa646, 0xa648, 0xa64a, 0xa64c, 0xa64e, 0xa650, 0xa652,\n        0xa654, 0xa656, 0xa658, 0xa65a, 0xa65c, 0xa65e, 0xa660, 0xa662, 0xa664,\n        0xa666, 0xa668, 0xa66a, 0xa66c, 0xa680, 0xa682, 0xa684, 0xa686, 0xa688,\n        0xa68a, 0xa68c, 0xa68e, 0xa690, 0xa692, 0xa694, 0xa696, 0xa722, 0xa724,\n        0xa726, 0xa728, 0xa72a, 0xa72c, 0xa72e, 0xa732, 0xa734, 0xa736, 0xa738,\n        0xa73a, 0xa73c, 0xa73e, 0xa740, 0xa742, 0xa744, 0xa746, 0xa748, 0xa74a,\n        0xa74c, 0xa74e, 0xa750, 0xa752, 0xa754, 0xa756, 0xa758, 0xa75a, 0xa75c,\n        0xa75e, 0xa760, 0xa762, 0xa764, 0xa766, 0xa768, 0xa76a, 0xa76c, 0xa76e,\n        0xa779, 0xa77b, 0xa77e, 0xa780, 0xa782, 0xa784, 0xa786, 0xa78b, 0xa790,\n        0xa792, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xff21, 0xff22, 0xff23,\n        0xff24, 0xff25, 0xff26, 0xff27, 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c,\n        0xff2d, 0xff2e, 0xff2f, 0xff30, 0xff31, 0xff32, 0xff33, 0xff34, 0xff35,\n        0xff36, 0xff37, 0xff38, 0xff39, 0xff3a, 0x10400, 0x10401, 0x10402,\n        0x10403, 0x10404, 0x10405, 0x10406, 0x10407, 0x10408, 0x10409, 0x1040a,\n        0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f, 0x10410, 0x10411, 0x10412,\n        0x10413, 0x10414, 0x10415, 0x10416, 0x10417, 0x10418, 0x10419, 0x1041a,\n        0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f, 0x10420, 0x10421, 0x10422,\n        0x10423, 0x10424, 0x10425, 0x10426, 0x10427, 0x2000053, 0x53, 0x130,\n        0x2000046, 0x46, 0x2000046, 0x49, 0x2000046, 0x4c, 0x3000046, 0x46,\n        0x49, 0x3000046, 0x46, 0x4c, 0x2000053, 0x54, 0x2000053, 0x54,\n        0x2000535, 0x552, 0x2000544, 0x546, 0x2000544, 0x535, 0x2000544, 0x53b,\n        0x200054e, 0x546, 0x2000544, 0x53d, 0x20002bc, 0x4e, 0x3000399, 0x308,\n        0x301, 0x30003a5, 0x308, 0x301, 0x200004a, 0x30c, 0x2000048, 0x331,\n        0x2000054, 0x308, 0x2000057, 0x30a, 0x2000059, 0x30a, 0x2000041, 0x2be,\n        0x20003a5, 0x313, 0x30003a5, 0x313, 0x300, 0x30003a5, 0x313, 0x301,\n        0x30003a5, 0x313, 0x342, 0x2000391, 0x342, 0x2000397, 0x342, 0x3000399,\n        0x308, 0x300, 0x3000399, 0x308, 0x301, 0x2000399, 0x342, 0x3000399,\n        0x308, 0x342, 0x30003a5, 0x308, 0x300, 0x30003a5, 0x308, 0x301,\n        0x20003a1, 0x313, 0x20003a5, 0x342, 0x30003a5, 0x308, 0x342, 0x20003a9,\n        0x342, 0x2001f08, 0x399, 0x2001f09, 0x399, 0x2001f0a, 0x399, 0x2001f0b,\n        0x399, 0x2001f0c, 0x399, 0x2001f0d, 0x399, 0x2001f0e, 0x399, 0x2001f0f,\n        0x399, 0x2001f08, 0x399, 0x2001f09, 0x399, 0x2001f0a, 0x399, 0x2001f0b,\n        0x399, 0x2001f0c, 0x399, 0x2001f0d, 0x399, 0x2001f0e, 0x399, 0x2001f0f,\n        0x399, 0x2001f28, 0x399, 0x2001f29, 0x399, 0x2001f2a, 0x399, 0x2001f2b,\n        0x399, 0x2001f2c, 0x399, 0x2001f2d, 0x399, 0x2001f2e, 0x399, 0x2001f2f,\n        0x399, 0x2001f28, 0x399, 0x2001f29, 0x399, 0x2001f2a, 0x399, 0x2001f2b,\n        0x399, 0x2001f2c, 0x399, 0x2001f2d, 0x399, 0x2001f2e, 0x399, 0x2001f2f,\n        0x399, 0x2001f68, 0x399, 0x2001f69, 0x399, 0x2001f6a, 0x399, 0x2001f6b,\n        0x399, 0x2001f6c, 0x399, 0x2001f6d, 0x399, 0x2001f6e, 0x399, 0x2001f6f,\n        0x399, 0x2001f68, 0x399, 0x2001f69, 0x399, 0x2001f6a, 0x399, 0x2001f6b,\n        0x399, 0x2001f6c, 0x399, 0x2001f6d, 0x399, 0x2001f6e, 0x399, 0x2001f6f,\n        0x399, 0x2000391, 0x399, 0x2000391, 0x399, 0x2000397, 0x399, 0x2000397,\n        0x399, 0x20003a9, 0x399, 0x20003a9, 0x399, 0x2001fba, 0x399, 0x2000386,\n        0x399, 0x2001fca, 0x399, 0x2000389, 0x399, 0x2001ffa, 0x399, 0x200038f,\n        0x399, 0x3000391, 0x342, 0x399, 0x3000397, 0x342, 0x399, 0x30003a9, 0x342,\n        0x399\n    ];\n    return t;\n}\n_IUA toLowerTable()\n{\n    static _IUA t = [\n        0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,\n        0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,\n        0x79, 0x7a, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,\n        0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,\n        0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x101, 0x103, 0x105,\n        0x107, 0x109, 0x10b, 0x10d, 0x10f, 0x111, 0x113, 0x115, 0x117, 0x119,\n        0x11b, 0x11d, 0x11f, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12b, 0x12d,\n        0x12f, 0x69, 0x133, 0x135, 0x137, 0x13a, 0x13c, 0x13e, 0x140, 0x142,\n        0x144, 0x146, 0x148, 0x14b, 0x14d, 0x14f, 0x151, 0x153, 0x155, 0x157,\n        0x159, 0x15b, 0x15d, 0x15f, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16b,\n        0x16d, 0x16f, 0x171, 0x173, 0x175, 0x177, 0xff, 0x17a, 0x17c, 0x17e,\n        0x253, 0x183, 0x185, 0x254, 0x188, 0x256, 0x257, 0x18c, 0x1dd, 0x259,\n        0x25b, 0x192, 0x260, 0x263, 0x269, 0x268, 0x199, 0x26f, 0x272, 0x275,\n        0x1a1, 0x1a3, 0x1a5, 0x280, 0x1a8, 0x283, 0x1ad, 0x288, 0x1b0, 0x28a,\n        0x28b, 0x1b4, 0x1b6, 0x292, 0x1b9, 0x1bd, 0x1c6, 0x1c6, 0x1c9, 0x1c9,\n        0x1cc, 0x1cc, 0x1ce, 0x1d0, 0x1d2, 0x1d4, 0x1d6, 0x1d8, 0x1da, 0x1dc,\n        0x1df, 0x1e1, 0x1e3, 0x1e5, 0x1e7, 0x1e9, 0x1eb, 0x1ed, 0x1ef, 0x1f3,\n        0x1f3, 0x1f5, 0x195, 0x1bf, 0x1f9, 0x1fb, 0x1fd, 0x1ff, 0x201, 0x203,\n        0x205, 0x207, 0x209, 0x20b, 0x20d, 0x20f, 0x211, 0x213, 0x215, 0x217,\n        0x219, 0x21b, 0x21d, 0x21f, 0x19e, 0x223, 0x225, 0x227, 0x229, 0x22b,\n        0x22d, 0x22f, 0x231, 0x233, 0x2c65, 0x23c, 0x19a, 0x2c66, 0x242, 0x180,\n        0x289, 0x28c, 0x247, 0x249, 0x24b, 0x24d, 0x24f, 0x371, 0x373, 0x377,\n        0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3cc, 0x3cd, 0x3ce, 0x3b1, 0x3b2, 0x3b3,\n        0x3b4, 0x3b5, 0x3b6, 0x3b7, 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd,\n        0x3be, 0x3bf, 0x3c0, 0x3c1, 0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7, 0x3c8,\n        0x3c9, 0x3ca, 0x3cb, 0x3d7, 0x3d9, 0x3db, 0x3dd, 0x3df, 0x3e1, 0x3e3,\n        0x3e5, 0x3e7, 0x3e9, 0x3eb, 0x3ed, 0x3ef, 0x3b8, 0x3f8, 0x3f2, 0x3fb,\n        0x37b, 0x37c, 0x37d, 0x450, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456,\n        0x457, 0x458, 0x459, 0x45a, 0x45b, 0x45c, 0x45d, 0x45e, 0x45f, 0x430,\n        0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43a,\n        0x43b, 0x43c, 0x43d, 0x43e, 0x43f, 0x440, 0x441, 0x442, 0x443, 0x444,\n        0x445, 0x446, 0x447, 0x448, 0x449, 0x44a, 0x44b, 0x44c, 0x44d, 0x44e,\n        0x44f, 0x461, 0x463, 0x465, 0x467, 0x469, 0x46b, 0x46d, 0x46f, 0x471,\n        0x473, 0x475, 0x477, 0x479, 0x47b, 0x47d, 0x47f, 0x481, 0x48b, 0x48d,\n        0x48f, 0x491, 0x493, 0x495, 0x497, 0x499, 0x49b, 0x49d, 0x49f, 0x4a1,\n        0x4a3, 0x4a5, 0x4a7, 0x4a9, 0x4ab, 0x4ad, 0x4af, 0x4b1, 0x4b3, 0x4b5,\n        0x4b7, 0x4b9, 0x4bb, 0x4bd, 0x4bf, 0x4cf, 0x4c2, 0x4c4, 0x4c6, 0x4c8,\n        0x4ca, 0x4cc, 0x4ce, 0x4d1, 0x4d3, 0x4d5, 0x4d7, 0x4d9, 0x4db, 0x4dd,\n        0x4df, 0x4e1, 0x4e3, 0x4e5, 0x4e7, 0x4e9, 0x4eb, 0x4ed, 0x4ef, 0x4f1,\n        0x4f3, 0x4f5, 0x4f7, 0x4f9, 0x4fb, 0x4fd, 0x4ff, 0x501, 0x503, 0x505,\n        0x507, 0x509, 0x50b, 0x50d, 0x50f, 0x511, 0x513, 0x515, 0x517, 0x519,\n        0x51b, 0x51d, 0x51f, 0x521, 0x523, 0x525, 0x527, 0x561, 0x562, 0x563,\n        0x564, 0x565, 0x566, 0x567, 0x568, 0x569, 0x56a, 0x56b, 0x56c, 0x56d,\n        0x56e, 0x56f, 0x570, 0x571, 0x572, 0x573, 0x574, 0x575, 0x576, 0x577,\n        0x578, 0x579, 0x57a, 0x57b, 0x57c, 0x57d, 0x57e, 0x57f, 0x580, 0x581,\n        0x582, 0x583, 0x584, 0x585, 0x586, 0x2d00, 0x2d01, 0x2d02, 0x2d03,\n        0x2d04, 0x2d05, 0x2d06, 0x2d07, 0x2d08, 0x2d09, 0x2d0a, 0x2d0b, 0x2d0c,\n        0x2d0d, 0x2d0e, 0x2d0f, 0x2d10, 0x2d11, 0x2d12, 0x2d13, 0x2d14, 0x2d15,\n        0x2d16, 0x2d17, 0x2d18, 0x2d19, 0x2d1a, 0x2d1b, 0x2d1c, 0x2d1d, 0x2d1e,\n        0x2d1f, 0x2d20, 0x2d21, 0x2d22, 0x2d23, 0x2d24, 0x2d25, 0x2d27, 0x2d2d,\n        0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b, 0x1e0d, 0x1e0f, 0x1e11,\n        0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d, 0x1e1f, 0x1e21, 0x1e23,\n        0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d, 0x1e2f, 0x1e31, 0x1e33, 0x1e35,\n        0x1e37, 0x1e39, 0x1e3b, 0x1e3d, 0x1e3f, 0x1e41, 0x1e43, 0x1e45, 0x1e47,\n        0x1e49, 0x1e4b, 0x1e4d, 0x1e4f, 0x1e51, 0x1e53, 0x1e55, 0x1e57, 0x1e59,\n        0x1e5b, 0x1e5d, 0x1e5f, 0x1e61, 0x1e63, 0x1e65, 0x1e67, 0x1e69, 0x1e6b,\n        0x1e6d, 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 0x1e79, 0x1e7b, 0x1e7d,\n        0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89, 0x1e8b, 0x1e8d, 0x1e8f,\n        0x1e91, 0x1e93, 0x1e95, 0xdf, 0x1ea1, 0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9,\n        0x1eab, 0x1ead, 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb,\n        0x1ebd, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9, 0x1ecb, 0x1ecd,\n        0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb, 0x1edd, 0x1edf,\n        0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, 0x1eed, 0x1eef, 0x1ef1,\n        0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1efb, 0x1efd, 0x1eff, 0x1f00, 0x1f01,\n        0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 0x1f10, 0x1f11, 0x1f12,\n        0x1f13, 0x1f14, 0x1f15, 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25,\n        0x1f26, 0x1f27, 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36,\n        0x1f37, 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x1f51, 0x1f53,\n        0x1f55, 0x1f57, 0x1f60, 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66,\n        0x1f67, 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87,\n        0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, 0x1fa0,\n        0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, 0x1fb0, 0x1fb1,\n        0x1f70, 0x1f71, 0x1fb3, 0x1f72, 0x1f73, 0x1f74, 0x1f75, 0x1fc3, 0x1fd0,\n        0x1fd1, 0x1f76, 0x1f77, 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0x1f78,\n        0x1f79, 0x1f7c, 0x1f7d, 0x1ff3, 0x3c9, 0x6b, 0xe5, 0x214e, 0x2170,\n        0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179,\n        0x217a, 0x217b, 0x217c, 0x217d, 0x217e, 0x217f, 0x2184, 0x24d0, 0x24d1,\n        0x24d2, 0x24d3, 0x24d4, 0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9, 0x24da,\n        0x24db, 0x24dc, 0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1, 0x24e2, 0x24e3,\n        0x24e4, 0x24e5, 0x24e6, 0x24e7, 0x24e8, 0x24e9, 0x2c30, 0x2c31, 0x2c32,\n        0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37, 0x2c38, 0x2c39, 0x2c3a, 0x2c3b,\n        0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f, 0x2c40, 0x2c41, 0x2c42, 0x2c43, 0x2c44,\n        0x2c45, 0x2c46, 0x2c47, 0x2c48, 0x2c49, 0x2c4a, 0x2c4b, 0x2c4c, 0x2c4d,\n        0x2c4e, 0x2c4f, 0x2c50, 0x2c51, 0x2c52, 0x2c53, 0x2c54, 0x2c55, 0x2c56,\n        0x2c57, 0x2c58, 0x2c59, 0x2c5a, 0x2c5b, 0x2c5c, 0x2c5d, 0x2c5e, 0x2c61,\n        0x26b, 0x1d7d, 0x27d, 0x2c68, 0x2c6a, 0x2c6c, 0x251, 0x271, 0x250,\n        0x252, 0x2c73, 0x2c76, 0x23f, 0x240, 0x2c81, 0x2c83, 0x2c85, 0x2c87,\n        0x2c89, 0x2c8b, 0x2c8d, 0x2c8f, 0x2c91, 0x2c93, 0x2c95, 0x2c97, 0x2c99,\n        0x2c9b, 0x2c9d, 0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab,\n        0x2cad, 0x2caf, 0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7, 0x2cb9, 0x2cbb, 0x2cbd,\n        0x2cbf, 0x2cc1, 0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9, 0x2ccb, 0x2ccd, 0x2ccf,\n        0x2cd1, 0x2cd3, 0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb, 0x2cdd, 0x2cdf, 0x2ce1,\n        0x2ce3, 0x2cec, 0x2cee, 0x2cf3, 0xa641, 0xa643, 0xa645, 0xa647, 0xa649,\n        0xa64b, 0xa64d, 0xa64f, 0xa651, 0xa653, 0xa655, 0xa657, 0xa659, 0xa65b,\n        0xa65d, 0xa65f, 0xa661, 0xa663, 0xa665, 0xa667, 0xa669, 0xa66b, 0xa66d,\n        0xa681, 0xa683, 0xa685, 0xa687, 0xa689, 0xa68b, 0xa68d, 0xa68f, 0xa691,\n        0xa693, 0xa695, 0xa697, 0xa723, 0xa725, 0xa727, 0xa729, 0xa72b, 0xa72d,\n        0xa72f, 0xa733, 0xa735, 0xa737, 0xa739, 0xa73b, 0xa73d, 0xa73f, 0xa741,\n        0xa743, 0xa745, 0xa747, 0xa749, 0xa74b, 0xa74d, 0xa74f, 0xa751, 0xa753,\n        0xa755, 0xa757, 0xa759, 0xa75b, 0xa75d, 0xa75f, 0xa761, 0xa763, 0xa765,\n        0xa767, 0xa769, 0xa76b, 0xa76d, 0xa76f, 0xa77a, 0xa77c, 0x1d79, 0xa77f,\n        0xa781, 0xa783, 0xa785, 0xa787, 0xa78c, 0x265, 0xa791, 0xa793, 0xa7a1,\n        0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9, 0x266, 0xff41, 0xff42, 0xff43, 0xff44,\n        0xff45, 0xff46, 0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d,\n        0xff4e, 0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56,\n        0xff57, 0xff58, 0xff59, 0xff5a, 0x10428, 0x10429, 0x1042a, 0x1042b,\n        0x1042c, 0x1042d, 0x1042e, 0x1042f, 0x10430, 0x10431, 0x10432, 0x10433,\n        0x10434, 0x10435, 0x10436, 0x10437, 0x10438, 0x10439, 0x1043a, 0x1043b,\n        0x1043c, 0x1043d, 0x1043e, 0x1043f, 0x10440, 0x10441, 0x10442, 0x10443,\n        0x10444, 0x10445, 0x10446, 0x10447, 0x10448, 0x10449, 0x1044a, 0x1044b,\n        0x1044c, 0x1044d, 0x1044e, 0x1044f, 0xdf, 0x2000069, 0x307, 0xfb00,\n        0xfb01, 0xfb02, 0xfb03, 0xfb04, 0xfb05, 0xfb06, 0x587, 0xfb13, 0xfb14,\n        0xfb15, 0xfb16, 0xfb17, 0x149, 0x390, 0x3b0, 0x1f0, 0x1e96, 0x1e97,\n        0x1e98, 0x1e99, 0x1e9a, 0x1f50, 0x1f52, 0x1f54, 0x1f56, 0x1fb6, 0x1fc6,\n        0x1fd2, 0x1fd3, 0x1fd6, 0x1fd7, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe6, 0x1fe7,\n        0x1ff6, 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87,\n        0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, 0x1f90,\n        0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, 0x1f90, 0x1f91,\n        0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, 0x1fa0, 0x1fa1, 0x1fa2,\n        0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3,\n        0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, 0x1fb3, 0x1fb3, 0x1fc3, 0x1fc3, 0x1ff3,\n        0x1ff3, 0x1fb2, 0x1fb4, 0x1fc2, 0x1fc4, 0x1ff2, 0x1ff4, 0x1fb7, 0x1fc7, 0x1ff7\n    ];\n    return t;\n}\n\n_IUA toTitleTable()\n{\n    static _IUA t = [\n        0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c,\n        0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,\n        0x59, 0x5a, 0x39c, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,\n        0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,\n        0xd4, 0xd5, 0xd6, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x178,\n        0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e, 0x110, 0x112,\n        0x114, 0x116, 0x118, 0x11a, 0x11c, 0x11e, 0x120, 0x122, 0x124, 0x126,\n        0x128, 0x12a, 0x12c, 0x12e, 0x49, 0x132, 0x134, 0x136, 0x139, 0x13b,\n        0x13d, 0x13f, 0x141, 0x143, 0x145, 0x147, 0x14a, 0x14c, 0x14e, 0x150,\n        0x152, 0x154, 0x156, 0x158, 0x15a, 0x15c, 0x15e, 0x160, 0x162, 0x164,\n        0x166, 0x168, 0x16a, 0x16c, 0x16e, 0x170, 0x172, 0x174, 0x176, 0x179,\n        0x17b, 0x17d, 0x53, 0x243, 0x182, 0x184, 0x187, 0x18b, 0x191, 0x1f6,\n        0x198, 0x23d, 0x220, 0x1a0, 0x1a2, 0x1a4, 0x1a7, 0x1ac, 0x1af, 0x1b3,\n        0x1b5, 0x1b8, 0x1bc, 0x1f7, 0x1c5, 0x1c5, 0x1c5, 0x1c8, 0x1c8, 0x1c8,\n        0x1cb, 0x1cb, 0x1cb, 0x1cd, 0x1cf, 0x1d1, 0x1d3, 0x1d5, 0x1d7, 0x1d9,\n        0x1db, 0x18e, 0x1de, 0x1e0, 0x1e2, 0x1e4, 0x1e6, 0x1e8, 0x1ea, 0x1ec,\n        0x1ee, 0x1f2, 0x1f2, 0x1f2, 0x1f4, 0x1f8, 0x1fa, 0x1fc, 0x1fe, 0x200,\n        0x202, 0x204, 0x206, 0x208, 0x20a, 0x20c, 0x20e, 0x210, 0x212, 0x214,\n        0x216, 0x218, 0x21a, 0x21c, 0x21e, 0x222, 0x224, 0x226, 0x228, 0x22a,\n        0x22c, 0x22e, 0x230, 0x232, 0x23b, 0x2c7e, 0x2c7f, 0x241, 0x246, 0x248,\n        0x24a, 0x24c, 0x24e, 0x2c6f, 0x2c6d, 0x2c70, 0x181, 0x186, 0x189,\n        0x18a, 0x18f, 0x190, 0x193, 0x194, 0xa78d, 0xa7aa, 0x197, 0x196,\n        0x2c62, 0x19c, 0x2c6e, 0x19d, 0x19f, 0x2c64, 0x1a6, 0x1a9, 0x1ae,\n        0x244, 0x1b1, 0x1b2, 0x245, 0x1b7, 0x399, 0x370, 0x372, 0x376, 0x3fd,\n        0x3fe, 0x3ff, 0x386, 0x388, 0x389, 0x38a, 0x391, 0x392, 0x393, 0x394,\n        0x395, 0x396, 0x397, 0x398, 0x399, 0x39a, 0x39b, 0x39c, 0x39d, 0x39e,\n        0x39f, 0x3a0, 0x3a1, 0x3a3, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7, 0x3a8,\n        0x3a9, 0x3aa, 0x3ab, 0x38c, 0x38e, 0x38f, 0x392, 0x398, 0x3a6, 0x3a0,\n        0x3cf, 0x3d8, 0x3da, 0x3dc, 0x3de, 0x3e0, 0x3e2, 0x3e4, 0x3e6, 0x3e8,\n        0x3ea, 0x3ec, 0x3ee, 0x39a, 0x3a1, 0x3f9, 0x395, 0x3f7, 0x3fa, 0x410,\n        0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41a,\n        0x41b, 0x41c, 0x41d, 0x41e, 0x41f, 0x420, 0x421, 0x422, 0x423, 0x424,\n        0x425, 0x426, 0x427, 0x428, 0x429, 0x42a, 0x42b, 0x42c, 0x42d, 0x42e,\n        0x42f, 0x400, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408,\n        0x409, 0x40a, 0x40b, 0x40c, 0x40d, 0x40e, 0x40f, 0x460, 0x462, 0x464,\n        0x466, 0x468, 0x46a, 0x46c, 0x46e, 0x470, 0x472, 0x474, 0x476, 0x478,\n        0x47a, 0x47c, 0x47e, 0x480, 0x48a, 0x48c, 0x48e, 0x490, 0x492, 0x494,\n        0x496, 0x498, 0x49a, 0x49c, 0x49e, 0x4a0, 0x4a2, 0x4a4, 0x4a6, 0x4a8,\n        0x4aa, 0x4ac, 0x4ae, 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x4bc,\n        0x4be, 0x4c1, 0x4c3, 0x4c5, 0x4c7, 0x4c9, 0x4cb, 0x4cd, 0x4c0, 0x4d0,\n        0x4d2, 0x4d4, 0x4d6, 0x4d8, 0x4da, 0x4dc, 0x4de, 0x4e0, 0x4e2, 0x4e4,\n        0x4e6, 0x4e8, 0x4ea, 0x4ec, 0x4ee, 0x4f0, 0x4f2, 0x4f4, 0x4f6, 0x4f8,\n        0x4fa, 0x4fc, 0x4fe, 0x500, 0x502, 0x504, 0x506, 0x508, 0x50a, 0x50c,\n        0x50e, 0x510, 0x512, 0x514, 0x516, 0x518, 0x51a, 0x51c, 0x51e, 0x520,\n        0x522, 0x524, 0x526, 0x531, 0x532, 0x533, 0x534, 0x535, 0x536, 0x537,\n        0x538, 0x539, 0x53a, 0x53b, 0x53c, 0x53d, 0x53e, 0x53f, 0x540, 0x541,\n        0x542, 0x543, 0x544, 0x545, 0x546, 0x547, 0x548, 0x549, 0x54a, 0x54b,\n        0x54c, 0x54d, 0x54e, 0x54f, 0x550, 0x551, 0x552, 0x553, 0x554, 0x555,\n        0x556, 0xa77d, 0x2c63, 0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08, 0x1e0a,\n        0x1e0c, 0x1e0e, 0x1e10, 0x1e12, 0x1e14, 0x1e16, 0x1e18, 0x1e1a, 0x1e1c,\n        0x1e1e, 0x1e20, 0x1e22, 0x1e24, 0x1e26, 0x1e28, 0x1e2a, 0x1e2c, 0x1e2e,\n        0x1e30, 0x1e32, 0x1e34, 0x1e36, 0x1e38, 0x1e3a, 0x1e3c, 0x1e3e, 0x1e40,\n        0x1e42, 0x1e44, 0x1e46, 0x1e48, 0x1e4a, 0x1e4c, 0x1e4e, 0x1e50, 0x1e52,\n        0x1e54, 0x1e56, 0x1e58, 0x1e5a, 0x1e5c, 0x1e5e, 0x1e60, 0x1e62, 0x1e64,\n        0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e, 0x1e70, 0x1e72, 0x1e74, 0x1e76,\n        0x1e78, 0x1e7a, 0x1e7c, 0x1e7e, 0x1e80, 0x1e82, 0x1e84, 0x1e86, 0x1e88,\n        0x1e8a, 0x1e8c, 0x1e8e, 0x1e90, 0x1e92, 0x1e94, 0x1e60, 0x1ea0, 0x1ea2,\n        0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac, 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4,\n        0x1eb6, 0x1eb8, 0x1eba, 0x1ebc, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6,\n        0x1ec8, 0x1eca, 0x1ecc, 0x1ece, 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8,\n        0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2, 0x1ee4, 0x1ee6, 0x1ee8, 0x1eea,\n        0x1eec, 0x1eee, 0x1ef0, 0x1ef2, 0x1ef4, 0x1ef6, 0x1ef8, 0x1efa, 0x1efc,\n        0x1efe, 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f,\n        0x1f18, 0x1f19, 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0x1f28, 0x1f29, 0x1f2a,\n        0x1f2b, 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b,\n        0x1f3c, 0x1f3d, 0x1f3e, 0x1f3f, 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c,\n        0x1f4d, 0x1f59, 0x1f5b, 0x1f5d, 0x1f5f, 0x1f68, 0x1f69, 0x1f6a, 0x1f6b,\n        0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, 0x1fba, 0x1fbb, 0x1fc8, 0x1fc9, 0x1fca,\n        0x1fcb, 0x1fda, 0x1fdb, 0x1ff8, 0x1ff9, 0x1fea, 0x1feb, 0x1ffa, 0x1ffb,\n        0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f98,\n        0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa8, 0x1fa9,\n        0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fb8, 0x1fb9, 0x1fbc,\n        0x399, 0x1fcc, 0x1fd8, 0x1fd9, 0x1fe8, 0x1fe9, 0x1fec, 0x1ffc, 0x2132,\n        0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168,\n        0x2169, 0x216a, 0x216b, 0x216c, 0x216d, 0x216e, 0x216f, 0x2183, 0x24b6,\n        0x24b7, 0x24b8, 0x24b9, 0x24ba, 0x24bb, 0x24bc, 0x24bd, 0x24be, 0x24bf,\n        0x24c0, 0x24c1, 0x24c2, 0x24c3, 0x24c4, 0x24c5, 0x24c6, 0x24c7, 0x24c8,\n        0x24c9, 0x24ca, 0x24cb, 0x24cc, 0x24cd, 0x24ce, 0x24cf, 0x2c00, 0x2c01,\n        0x2c02, 0x2c03, 0x2c04, 0x2c05, 0x2c06, 0x2c07, 0x2c08, 0x2c09, 0x2c0a,\n        0x2c0b, 0x2c0c, 0x2c0d, 0x2c0e, 0x2c0f, 0x2c10, 0x2c11, 0x2c12, 0x2c13,\n        0x2c14, 0x2c15, 0x2c16, 0x2c17, 0x2c18, 0x2c19, 0x2c1a, 0x2c1b, 0x2c1c,\n        0x2c1d, 0x2c1e, 0x2c1f, 0x2c20, 0x2c21, 0x2c22, 0x2c23, 0x2c24, 0x2c25,\n        0x2c26, 0x2c27, 0x2c28, 0x2c29, 0x2c2a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e,\n        0x2c60, 0x23a, 0x23e, 0x2c67, 0x2c69, 0x2c6b, 0x2c72, 0x2c75, 0x2c80,\n        0x2c82, 0x2c84, 0x2c86, 0x2c88, 0x2c8a, 0x2c8c, 0x2c8e, 0x2c90, 0x2c92,\n        0x2c94, 0x2c96, 0x2c98, 0x2c9a, 0x2c9c, 0x2c9e, 0x2ca0, 0x2ca2, 0x2ca4,\n        0x2ca6, 0x2ca8, 0x2caa, 0x2cac, 0x2cae, 0x2cb0, 0x2cb2, 0x2cb4, 0x2cb6,\n        0x2cb8, 0x2cba, 0x2cbc, 0x2cbe, 0x2cc0, 0x2cc2, 0x2cc4, 0x2cc6, 0x2cc8,\n        0x2cca, 0x2ccc, 0x2cce, 0x2cd0, 0x2cd2, 0x2cd4, 0x2cd6, 0x2cd8, 0x2cda,\n        0x2cdc, 0x2cde, 0x2ce0, 0x2ce2, 0x2ceb, 0x2ced, 0x2cf2, 0x10a0, 0x10a1,\n        0x10a2, 0x10a3, 0x10a4, 0x10a5, 0x10a6, 0x10a7, 0x10a8, 0x10a9, 0x10aa,\n        0x10ab, 0x10ac, 0x10ad, 0x10ae, 0x10af, 0x10b0, 0x10b1, 0x10b2, 0x10b3,\n        0x10b4, 0x10b5, 0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10ba, 0x10bb, 0x10bc,\n        0x10bd, 0x10be, 0x10bf, 0x10c0, 0x10c1, 0x10c2, 0x10c3, 0x10c4, 0x10c5,\n        0x10c7, 0x10cd, 0xa640, 0xa642, 0xa644, 0xa646, 0xa648, 0xa64a, 0xa64c,\n        0xa64e, 0xa650, 0xa652, 0xa654, 0xa656, 0xa658, 0xa65a, 0xa65c, 0xa65e,\n        0xa660, 0xa662, 0xa664, 0xa666, 0xa668, 0xa66a, 0xa66c, 0xa680, 0xa682,\n        0xa684, 0xa686, 0xa688, 0xa68a, 0xa68c, 0xa68e, 0xa690, 0xa692, 0xa694,\n        0xa696, 0xa722, 0xa724, 0xa726, 0xa728, 0xa72a, 0xa72c, 0xa72e, 0xa732,\n        0xa734, 0xa736, 0xa738, 0xa73a, 0xa73c, 0xa73e, 0xa740, 0xa742, 0xa744,\n        0xa746, 0xa748, 0xa74a, 0xa74c, 0xa74e, 0xa750, 0xa752, 0xa754, 0xa756,\n        0xa758, 0xa75a, 0xa75c, 0xa75e, 0xa760, 0xa762, 0xa764, 0xa766, 0xa768,\n        0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b, 0xa77e, 0xa780, 0xa782, 0xa784,\n        0xa786, 0xa78b, 0xa790, 0xa792, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8,\n        0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, 0xff29,\n        0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, 0xff31, 0xff32,\n        0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, 0xff3a,\n        0x10400, 0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407,\n        0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f,\n        0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417,\n        0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f,\n        0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426, 0x10427,\n        0x2000053, 0x73, 0x130, 0x2000046, 0x66, 0x2000046, 0x69, 0x2000046,\n        0x6c, 0x3000046, 0x66, 0x69, 0x3000046, 0x66, 0x6c, 0x2000053, 0x74,\n        0x2000053, 0x74, 0x2000535, 0x582, 0x2000544, 0x576, 0x2000544, 0x565,\n        0x2000544, 0x56b, 0x200054e, 0x576, 0x2000544, 0x56d, 0x20002bc, 0x4e,\n        0x3000399, 0x308, 0x301, 0x30003a5, 0x308, 0x301, 0x200004a, 0x30c,\n        0x2000048, 0x331, 0x2000054, 0x308, 0x2000057, 0x30a, 0x2000059, 0x30a,\n        0x2000041, 0x2be, 0x20003a5, 0x313, 0x30003a5, 0x313, 0x300, 0x30003a5,\n        0x313, 0x301, 0x30003a5, 0x313, 0x342, 0x2000391, 0x342, 0x2000397,\n        0x342, 0x3000399, 0x308, 0x300, 0x3000399, 0x308, 0x301, 0x2000399,\n        0x342, 0x3000399, 0x308, 0x342, 0x30003a5, 0x308, 0x300, 0x30003a5,\n        0x308, 0x301, 0x20003a1, 0x313, 0x20003a5, 0x342, 0x30003a5, 0x308,\n        0x342, 0x20003a9, 0x342, 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c,\n        0x1f8d, 0x1f8e, 0x1f8f, 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d,\n        0x1f8e, 0x1f8f, 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e,\n        0x1f9f, 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f,\n        0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fa8,\n        0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fbc, 0x1fbc,\n        0x1fcc, 0x1fcc, 0x1ffc, 0x1ffc, 0x2001fba, 0x345, 0x2000386, 0x345,\n        0x2001fca, 0x345, 0x2000389, 0x345, 0x2001ffa, 0x345, 0x200038f, 0x345,\n        0x3000391, 0x342, 0x345, 0x3000397, 0x342, 0x345, 0x30003a9, 0x342, 0x345\n    ];\n    return t;\n}\n}\n}"
  },
  {
    "path": "libphobos/src/std/internal/windows/advapi32.d",
    "content": "// Written in the D programming language.\n\n/**\n * The only purpose of this module is to do the static construction for\n * std.windows.registry, to eliminate cyclic construction errors.\n *\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Kenji Hara\n * Source:    $(PHOBOSSRC std/internal/windows/advapi32.d)\n */\nmodule std.internal.windows.advapi32;\n\nversion (Windows):\n\nimport core.sys.windows.windows;\n\npragma(lib, \"advapi32.lib\");\n\nimmutable bool isWow64;\n\nshared static this()\n{\n    // WOW64 is the x86 emulator that allows 32-bit Windows-based applications to run seamlessly on 64-bit Windows\n    // IsWow64Process Function - Minimum supported client - Windows Vista, Windows XP with SP2\n    alias fptr_t = extern(Windows) BOOL function(HANDLE, PBOOL);\n    auto hKernel = GetModuleHandleA(\"kernel32\");\n    auto IsWow64Process = cast(fptr_t) GetProcAddress(hKernel, \"IsWow64Process\");\n    BOOL bIsWow64;\n    isWow64 = IsWow64Process && IsWow64Process(GetCurrentProcess(), &bIsWow64) && bIsWow64;\n}\n\nHMODULE hAdvapi32 = null;\nextern (Windows)\n{\n    LONG function(in HKEY hkey, in LPCWSTR lpSubKey, in REGSAM samDesired, in DWORD reserved) pRegDeleteKeyExW;\n}\n\nvoid loadAdvapi32()\n{\n    if (!hAdvapi32)\n    {\n        hAdvapi32 = LoadLibraryA(\"Advapi32.dll\");\n        if (!hAdvapi32)\n            throw new Exception(`LoadLibraryA(\"Advapi32.dll\")`);\n\n        pRegDeleteKeyExW = cast(typeof(pRegDeleteKeyExW)) GetProcAddress(hAdvapi32 , \"RegDeleteKeyExW\");\n        if (!pRegDeleteKeyExW)\n            throw new Exception(`GetProcAddress(hAdvapi32 , \"RegDeleteKeyExW\")`);\n    }\n}\n\n// It will free Advapi32.dll, which may be loaded for RegDeleteKeyEx function\nprivate void freeAdvapi32()\n{\n    if (hAdvapi32)\n    {\n        if (!FreeLibrary(hAdvapi32))\n            throw new Exception(`FreeLibrary(\"Advapi32.dll\")`);\n        hAdvapi32 = null;\n\n        pRegDeleteKeyExW = null;\n    }\n}\n\nstatic ~this()\n{\n    freeAdvapi32();\n}\n"
  },
  {
    "path": "libphobos/src/std/json.d",
    "content": "// Written in the D programming language.\n\n/**\nJavaScript Object Notation\n\nCopyright: Copyright Jeremie Pelletier 2008 - 2009.\nLicense:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   Jeremie Pelletier, David Herberth\nReferences: $(LINK http://json.org/), $(LINK http://seriot.ch/parsing_json.html)\nSource:    $(PHOBOSSRC std/json.d)\n*/\n/*\n         Copyright Jeremie Pelletier 2008 - 2009.\nDistributed under the Boost Software License, Version 1.0.\n   (See accompanying file LICENSE_1_0.txt or copy at\n         http://www.boost.org/LICENSE_1_0.txt)\n*/\nmodule std.json;\n\nimport std.array;\nimport std.conv;\nimport std.range.primitives;\nimport std.traits;\n\n///\n@system unittest\n{\n    import std.conv : to;\n\n    // parse a file or string of json into a usable structure\n    string s = `{ \"language\": \"D\", \"rating\": 3.5, \"code\": \"42\" }`;\n    JSONValue j = parseJSON(s);\n    // j and j[\"language\"] return JSONValue,\n    // j[\"language\"].str returns a string\n    assert(j[\"language\"].str == \"D\");\n    assert(j[\"rating\"].floating == 3.5);\n\n    // check a type\n    long x;\n    if (const(JSONValue)* code = \"code\" in j)\n    {\n        if (code.type() == JSONType.integer)\n            x = code.integer;\n        else\n            x = to!int(code.str);\n    }\n\n    // create a json struct\n    JSONValue jj = [ \"language\": \"D\" ];\n    // rating doesnt exist yet, so use .object to assign\n    jj.object[\"rating\"] = JSONValue(3.5);\n    // create an array to assign to list\n    jj.object[\"list\"] = JSONValue( [\"a\", \"b\", \"c\"] );\n    // list already exists, so .object optional\n    jj[\"list\"].array ~= JSONValue(\"D\");\n\n    string jjStr = `{\"language\":\"D\",\"list\":[\"a\",\"b\",\"c\",\"D\"],\"rating\":3.5}`;\n    assert(jj.toString == jjStr);\n}\n\n/**\nString literals used to represent special float values within JSON strings.\n*/\nenum JSONFloatLiteral : string\n{\n    nan         = \"NaN\",       /// string representation of floating-point NaN\n    inf         = \"Infinite\",  /// string representation of floating-point Infinity\n    negativeInf = \"-Infinite\", /// string representation of floating-point negative Infinity\n}\n\n/**\nFlags that control how json is encoded and parsed.\n*/\nenum JSONOptions\n{\n    none,                       /// standard parsing\n    specialFloatLiterals = 0x1, /// encode NaN and Inf float values as strings\n    escapeNonAsciiChars = 0x2,  /// encode non ascii characters with an unicode escape sequence\n    doNotEscapeSlashes = 0x4,   /// do not escape slashes ('/')\n    strictParsing = 0x8,        /// Strictly follow RFC-8259 grammar when parsing\n}\n\n/**\nJSON type enumeration\n*/\nenum JSONType : byte\n{\n    /// Indicates the type of a `JSONValue`.\n    null_,\n    string,   /// ditto\n    integer,  /// ditto\n    uinteger, /// ditto\n    float_,   /// ditto\n    array,    /// ditto\n    object,   /// ditto\n    true_,    /// ditto\n    false_,   /// ditto\n    /// These symbols will be deprecated after 2.082.\n    NULL = null_,\n    STRING = string,\n    INTEGER = integer,\n    UINTEGER = uinteger,\n    FLOAT = float_,\n    ARRAY = array,\n    OBJECT = object,\n    TRUE = true_,\n    FALSE = false_,\n}\n\n/// This alias will be deprecated after 2.082.\nalias JSON_TYPE = JSONType;\n\n/**\nJSON value node\n*/\nstruct JSONValue\n{\n    import std.exception : enforce;\n\n    union Store\n    {\n        string                          str;\n        long                            integer;\n        ulong                           uinteger;\n        double                          floating;\n        JSONValue[string]               object;\n        JSONValue[]                     array;\n    }\n    private Store store;\n    private JSONType type_tag;\n\n    /**\n      Returns the JSONType of the value stored in this structure.\n    */\n    @property JSONType type() const pure nothrow @safe @nogc\n    {\n        return type_tag;\n    }\n    ///\n    @safe unittest\n    {\n          string s = \"{ \\\"language\\\": \\\"D\\\" }\";\n          JSONValue j = parseJSON(s);\n          assert(j.type == JSONType.object);\n          assert(j[\"language\"].type == JSONType.string);\n    }\n\n    /***\n     * Value getter/setter for `JSONType.string`.\n     * Throws: `JSONException` for read access if `type` is not\n     * `JSONType.string`.\n     */\n    @property string str() const pure @trusted\n    {\n        enforce!JSONException(type == JSONType.string,\n                                \"JSONValue is not a string\");\n        return store.str;\n    }\n    /// ditto\n    @property string str(string v) pure nothrow @nogc @safe\n    {\n        assign(v);\n        return v;\n    }\n    ///\n    @safe unittest\n    {\n        JSONValue j = [ \"language\": \"D\" ];\n\n        // get value\n        assert(j[\"language\"].str == \"D\");\n\n        // change existing key to new string\n        j[\"language\"].str = \"Perl\";\n        assert(j[\"language\"].str == \"Perl\");\n    }\n\n    /***\n     * Value getter/setter for `JSONType.integer`.\n     * Throws: `JSONException` for read access if `type` is not\n     * `JSONType.integer`.\n     */\n    @property long integer() const pure @safe\n    {\n        enforce!JSONException(type == JSONType.integer,\n                                \"JSONValue is not an integer\");\n        return store.integer;\n    }\n    /// ditto\n    @property long integer(long v) pure nothrow @safe @nogc\n    {\n        assign(v);\n        return store.integer;\n    }\n\n    /***\n     * Value getter/setter for `JSONType.uinteger`.\n     * Throws: `JSONException` for read access if `type` is not\n     * `JSONType.uinteger`.\n     */\n    @property ulong uinteger() const pure @safe\n    {\n        enforce!JSONException(type == JSONType.uinteger,\n                                \"JSONValue is not an unsigned integer\");\n        return store.uinteger;\n    }\n    /// ditto\n    @property ulong uinteger(ulong v) pure nothrow @safe @nogc\n    {\n        assign(v);\n        return store.uinteger;\n    }\n\n    /***\n     * Value getter/setter for `JSONType.float_`. Note that despite\n     * the name, this is a $(B 64)-bit `double`, not a 32-bit `float`.\n     * Throws: `JSONException` for read access if `type` is not\n     * `JSONType.float_`.\n     */\n    @property double floating() const pure @safe\n    {\n        enforce!JSONException(type == JSONType.float_,\n                                \"JSONValue is not a floating type\");\n        return store.floating;\n    }\n    /// ditto\n    @property double floating(double v) pure nothrow @safe @nogc\n    {\n        assign(v);\n        return store.floating;\n    }\n\n    /***\n     * Value getter/setter for boolean stored in JSON.\n     * Throws: `JSONException` for read access if `this.type` is not\n     * `JSONType.true_` or `JSONType.false_`.\n     */\n    @property bool boolean() const pure @safe\n    {\n        if (type == JSONType.true_) return true;\n        if (type == JSONType.false_) return false;\n\n        throw new JSONException(\"JSONValue is not a boolean type\");\n    }\n    /// ditto\n    @property bool boolean(bool v) pure nothrow @safe @nogc\n    {\n        assign(v);\n        return v;\n    }\n    ///\n    @safe unittest\n    {\n        JSONValue j = true;\n        assert(j.boolean == true);\n\n        j.boolean = false;\n        assert(j.boolean == false);\n\n        j.integer = 12;\n        import std.exception : assertThrown;\n        assertThrown!JSONException(j.boolean);\n    }\n\n    /***\n     * Value getter/setter for `JSONType.object`.\n     * Throws: `JSONException` for read access if `type` is not\n     * `JSONType.object`.\n     * Note: this is @system because of the following pattern:\n       ---\n       auto a = &(json.object());\n       json.uinteger = 0;        // overwrite AA pointer\n       (*a)[\"hello\"] = \"world\";  // segmentation fault\n       ---\n     */\n    @property ref inout(JSONValue[string]) object() inout pure @system\n    {\n        enforce!JSONException(type == JSONType.object,\n                                \"JSONValue is not an object\");\n        return store.object;\n    }\n    /// ditto\n    @property JSONValue[string] object(JSONValue[string] v) pure nothrow @nogc @safe\n    {\n        assign(v);\n        return v;\n    }\n\n    /***\n     * Value getter for `JSONType.object`.\n     * Unlike `object`, this retrieves the object by value and can be used in @safe code.\n     *\n     * A caveat is that, if the returned value is null, modifications will not be visible:\n     * ---\n     * JSONValue json;\n     * json.object = null;\n     * json.objectNoRef[\"hello\"] = JSONValue(\"world\");\n     * assert(\"hello\" !in json.object);\n     * ---\n     *\n     * Throws: `JSONException` for read access if `type` is not\n     * `JSONType.object`.\n     */\n    @property inout(JSONValue[string]) objectNoRef() inout pure @trusted\n    {\n        enforce!JSONException(type == JSONType.object,\n                                \"JSONValue is not an object\");\n        return store.object;\n    }\n\n    /***\n     * Value getter/setter for `JSONType.array`.\n     * Throws: `JSONException` for read access if `type` is not\n     * `JSONType.array`.\n     * Note: this is @system because of the following pattern:\n       ---\n       auto a = &(json.array());\n       json.uinteger = 0;  // overwrite array pointer\n       (*a)[0] = \"world\";  // segmentation fault\n       ---\n     */\n    @property ref inout(JSONValue[]) array() inout pure @system\n    {\n        enforce!JSONException(type == JSONType.array,\n                                \"JSONValue is not an array\");\n        return store.array;\n    }\n    /// ditto\n    @property JSONValue[] array(JSONValue[] v) pure nothrow @nogc @safe\n    {\n        assign(v);\n        return v;\n    }\n\n    /***\n     * Value getter for `JSONType.array`.\n     * Unlike `array`, this retrieves the array by value and can be used in @safe code.\n     *\n     * A caveat is that, if you append to the returned array, the new values aren't visible in the\n     * JSONValue:\n     * ---\n     * JSONValue json;\n     * json.array = [JSONValue(\"hello\")];\n     * json.arrayNoRef ~= JSONValue(\"world\");\n     * assert(json.array.length == 1);\n     * ---\n     *\n     * Throws: `JSONException` for read access if `type` is not\n     * `JSONType.array`.\n     */\n    @property inout(JSONValue[]) arrayNoRef() inout pure @trusted\n    {\n        enforce!JSONException(type == JSONType.array,\n                                \"JSONValue is not an array\");\n        return store.array;\n    }\n\n    /// Test whether the type is `JSONType.null_`\n    @property bool isNull() const pure nothrow @safe @nogc\n    {\n        return type == JSONType.null_;\n    }\n\n    private void assign(T)(T arg) @safe\n    {\n        static if (is(T : typeof(null)))\n        {\n            type_tag = JSONType.null_;\n        }\n        else static if (is(T : string))\n        {\n            type_tag = JSONType.string;\n            string t = arg;\n            () @trusted { store.str = t; }();\n        }\n        else static if (isSomeString!T) // issue 15884\n        {\n            type_tag = JSONType.string;\n            // FIXME: std.Array.Array(Range) is not deduced as 'pure'\n            () @trusted {\n                import std.utf : byUTF;\n                store.str = cast(immutable)(arg.byUTF!char.array);\n            }();\n        }\n        else static if (is(T : bool))\n        {\n            type_tag = arg ? JSONType.true_ : JSONType.false_;\n        }\n        else static if (is(T : ulong) && isUnsigned!T)\n        {\n            type_tag = JSONType.uinteger;\n            store.uinteger = arg;\n        }\n        else static if (is(T : long))\n        {\n            type_tag = JSONType.integer;\n            store.integer = arg;\n        }\n        else static if (isFloatingPoint!T)\n        {\n            type_tag = JSONType.float_;\n            store.floating = arg;\n        }\n        else static if (is(T : Value[Key], Key, Value))\n        {\n            static assert(is(Key : string), \"AA key must be string\");\n            type_tag = JSONType.object;\n            static if (is(Value : JSONValue))\n            {\n                JSONValue[string] t = arg;\n                () @trusted { store.object = t; }();\n            }\n            else\n            {\n                JSONValue[string] aa;\n                foreach (key, value; arg)\n                    aa[key] = JSONValue(value);\n                () @trusted { store.object = aa; }();\n            }\n        }\n        else static if (isArray!T)\n        {\n            type_tag = JSONType.array;\n            static if (is(ElementEncodingType!T : JSONValue))\n            {\n                JSONValue[] t = arg;\n                () @trusted { store.array = t; }();\n            }\n            else\n            {\n                JSONValue[] new_arg = new JSONValue[arg.length];\n                foreach (i, e; arg)\n                    new_arg[i] = JSONValue(e);\n                () @trusted { store.array = new_arg; }();\n            }\n        }\n        else static if (is(T : JSONValue))\n        {\n            type_tag = arg.type;\n            store = arg.store;\n        }\n        else\n        {\n            static assert(false, text(`unable to convert type \"`, T.Stringof, `\" to json`));\n        }\n    }\n\n    private void assignRef(T)(ref T arg) if (isStaticArray!T)\n    {\n        type_tag = JSONType.array;\n        static if (is(ElementEncodingType!T : JSONValue))\n        {\n            store.array = arg;\n        }\n        else\n        {\n            JSONValue[] new_arg = new JSONValue[arg.length];\n            foreach (i, e; arg)\n                new_arg[i] = JSONValue(e);\n            store.array = new_arg;\n        }\n    }\n\n    /**\n     * Constructor for `JSONValue`. If `arg` is a `JSONValue`\n     * its value and type will be copied to the new `JSONValue`.\n     * Note that this is a shallow copy: if type is `JSONType.object`\n     * or `JSONType.array` then only the reference to the data will\n     * be copied.\n     * Otherwise, `arg` must be implicitly convertible to one of the\n     * following types: `typeof(null)`, `string`, `ulong`,\n     * `long`, `double`, an associative array `V[K]` for any `V`\n     * and `K` i.e. a JSON object, any array or `bool`. The type will\n     * be set accordingly.\n     */\n    this(T)(T arg) if (!isStaticArray!T)\n    {\n        assign(arg);\n    }\n    /// Ditto\n    this(T)(ref T arg) if (isStaticArray!T)\n    {\n        assignRef(arg);\n    }\n    /// Ditto\n    this(T : JSONValue)(inout T arg) inout\n    {\n        store = arg.store;\n        type_tag = arg.type;\n    }\n    ///\n    @safe unittest\n    {\n        JSONValue j = JSONValue( \"a string\" );\n        j = JSONValue(42);\n\n        j = JSONValue( [1, 2, 3] );\n        assert(j.type == JSONType.array);\n\n        j = JSONValue( [\"language\": \"D\"] );\n        assert(j.type == JSONType.object);\n    }\n\n    void opAssign(T)(T arg) if (!isStaticArray!T && !is(T : JSONValue))\n    {\n        assign(arg);\n    }\n\n    void opAssign(T)(ref T arg) if (isStaticArray!T)\n    {\n        assignRef(arg);\n    }\n\n    /***\n     * Array syntax for json arrays.\n     * Throws: `JSONException` if `type` is not `JSONType.array`.\n     */\n    ref inout(JSONValue) opIndex(size_t i) inout pure @safe\n    {\n        auto a = this.arrayNoRef;\n        enforce!JSONException(i < a.length,\n                                \"JSONValue array index is out of range\");\n        return a[i];\n    }\n    ///\n    @safe unittest\n    {\n        JSONValue j = JSONValue( [42, 43, 44] );\n        assert( j[0].integer == 42 );\n        assert( j[1].integer == 43 );\n    }\n\n    /***\n     * Hash syntax for json objects.\n     * Throws: `JSONException` if `type` is not `JSONType.object`.\n     */\n    ref inout(JSONValue) opIndex(string k) inout pure @safe\n    {\n        auto o = this.objectNoRef;\n        return *enforce!JSONException(k in o,\n                                        \"Key not found: \" ~ k);\n    }\n    ///\n    @safe unittest\n    {\n        JSONValue j = JSONValue( [\"language\": \"D\"] );\n        assert( j[\"language\"].str == \"D\" );\n    }\n\n    /***\n     * Operator sets `value` for element of JSON object by `key`.\n     *\n     * If JSON value is null, then operator initializes it with object and then\n     * sets `value` for it.\n     *\n     * Throws: `JSONException` if `type` is not `JSONType.object`\n     * or `JSONType.null_`.\n     */\n    void opIndexAssign(T)(auto ref T value, string key) pure\n    {\n        enforce!JSONException(type == JSONType.object || type == JSONType.null_,\n                                \"JSONValue must be object or null\");\n        JSONValue[string] aa = null;\n        if (type == JSONType.object)\n        {\n            aa = this.objectNoRef;\n        }\n\n        aa[key] = value;\n        this.object = aa;\n    }\n    ///\n    @safe unittest\n    {\n            JSONValue j = JSONValue( [\"language\": \"D\"] );\n            j[\"language\"].str = \"Perl\";\n            assert( j[\"language\"].str == \"Perl\" );\n    }\n\n    void opIndexAssign(T)(T arg, size_t i) pure\n    {\n        auto a = this.arrayNoRef;\n        enforce!JSONException(i < a.length,\n                                \"JSONValue array index is out of range\");\n        a[i] = arg;\n        this.array = a;\n    }\n    ///\n    @safe unittest\n    {\n            JSONValue j = JSONValue( [\"Perl\", \"C\"] );\n            j[1].str = \"D\";\n            assert( j[1].str == \"D\" );\n    }\n\n    JSONValue opBinary(string op : \"~\", T)(T arg) @safe\n    {\n        auto a = this.arrayNoRef;\n        static if (isArray!T)\n        {\n            return JSONValue(a ~ JSONValue(arg).arrayNoRef);\n        }\n        else static if (is(T : JSONValue))\n        {\n            return JSONValue(a ~ arg.arrayNoRef);\n        }\n        else\n        {\n            static assert(false, \"argument is not an array or a JSONValue array\");\n        }\n    }\n\n    void opOpAssign(string op : \"~\", T)(T arg) @safe\n    {\n        auto a = this.arrayNoRef;\n        static if (isArray!T)\n        {\n            a ~= JSONValue(arg).arrayNoRef;\n        }\n        else static if (is(T : JSONValue))\n        {\n            a ~= arg.arrayNoRef;\n        }\n        else\n        {\n            static assert(false, \"argument is not an array or a JSONValue array\");\n        }\n        this.array = a;\n    }\n\n    /**\n     * Support for the `in` operator.\n     *\n     * Tests wether a key can be found in an object.\n     *\n     * Returns:\n     *      when found, the `const(JSONValue)*` that matches to the key,\n     *      otherwise `null`.\n     *\n     * Throws: `JSONException` if the right hand side argument `JSONType`\n     * is not `object`.\n     */\n    auto opBinaryRight(string op : \"in\")(string k) const @safe\n    {\n        return k in this.objectNoRef;\n    }\n    ///\n    @safe unittest\n    {\n        JSONValue j = [ \"language\": \"D\", \"author\": \"walter\" ];\n        string a = (\"author\" in j).str;\n    }\n\n    bool opEquals(const JSONValue rhs) const @nogc nothrow pure @safe\n    {\n        return opEquals(rhs);\n    }\n\n    bool opEquals(ref const JSONValue rhs) const @nogc nothrow pure @trusted\n    {\n        // Default doesn't work well since store is a union.  Compare only\n        // what should be in store.\n        // This is @trusted to remain nogc, nothrow, fast, and usable from @safe code.\n\n        final switch (type_tag)\n        {\n        case JSONType.integer:\n            switch (rhs.type_tag)\n            {\n                case JSONType.integer:\n                    return store.integer == rhs.store.integer;\n                case JSONType.uinteger:\n                    return store.integer == rhs.store.uinteger;\n                case JSONType.float_:\n                    return store.integer == rhs.store.floating;\n                default:\n                    return false;\n            }\n        case JSONType.uinteger:\n            switch (rhs.type_tag)\n            {\n                case JSONType.integer:\n                    return store.uinteger == rhs.store.integer;\n                case JSONType.uinteger:\n                    return store.uinteger == rhs.store.uinteger;\n                case JSONType.float_:\n                    return store.uinteger == rhs.store.floating;\n                default:\n                    return false;\n            }\n        case JSONType.float_:\n            switch (rhs.type_tag)\n            {\n                case JSONType.integer:\n                    return store.floating == rhs.store.integer;\n                case JSONType.uinteger:\n                    return store.floating == rhs.store.uinteger;\n                case JSONType.float_:\n                    return store.floating == rhs.store.floating;\n                default:\n                    return false;\n            }\n        case JSONType.string:\n            return type_tag == rhs.type_tag && store.str == rhs.store.str;\n        case JSONType.object:\n            return type_tag == rhs.type_tag && store.object == rhs.store.object;\n        case JSONType.array:\n            return type_tag == rhs.type_tag && store.array == rhs.store.array;\n        case JSONType.true_:\n        case JSONType.false_:\n        case JSONType.null_:\n            return type_tag == rhs.type_tag;\n        }\n    }\n\n    ///\n    @safe unittest\n    {\n        assert(JSONValue(0u) == JSONValue(0));\n        assert(JSONValue(0u) == JSONValue(0.0));\n        assert(JSONValue(0) == JSONValue(0.0));\n    }\n\n    /// Implements the foreach `opApply` interface for json arrays.\n    int opApply(scope int delegate(size_t index, ref JSONValue) dg) @system\n    {\n        int result;\n\n        foreach (size_t index, ref value; array)\n        {\n            result = dg(index, value);\n            if (result)\n                break;\n        }\n\n        return result;\n    }\n\n    /// Implements the foreach `opApply` interface for json objects.\n    int opApply(scope int delegate(string key, ref JSONValue) dg) @system\n    {\n        enforce!JSONException(type == JSONType.object,\n                                \"JSONValue is not an object\");\n        int result;\n\n        foreach (string key, ref value; object)\n        {\n            result = dg(key, value);\n            if (result)\n                break;\n        }\n\n        return result;\n    }\n\n    /***\n     * Implicitly calls `toJSON` on this JSONValue.\n     *\n     * $(I options) can be used to tweak the conversion behavior.\n     */\n    string toString(in JSONOptions options = JSONOptions.none) const @safe\n    {\n        return toJSON(this, false, options);\n    }\n\n    /***\n     * Implicitly calls `toJSON` on this JSONValue, like `toString`, but\n     * also passes $(I true) as $(I pretty) argument.\n     *\n     * $(I options) can be used to tweak the conversion behavior\n     */\n    string toPrettyString(in JSONOptions options = JSONOptions.none) const @safe\n    {\n        return toJSON(this, true, options);\n    }\n}\n\n/**\nParses a serialized string and returns a tree of JSON values.\nThrows: $(LREF JSONException) if string does not follow the JSON grammar or the depth exceeds the max depth,\n        $(LREF ConvException) if a number in the input cannot be represented by a native D type.\nParams:\n    json = json-formatted string to parse\n    maxDepth = maximum depth of nesting allowed, -1 disables depth checking\n    options = enable decoding string representations of NaN/Inf as float values\n*/\nJSONValue parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none)\nif (isInputRange!T && !isInfinite!T && isSomeChar!(ElementEncodingType!T))\n{\n    import std.ascii : isDigit, isHexDigit, toUpper, toLower;\n    import std.typecons : Nullable, Yes;\n    JSONValue root;\n    root.type_tag = JSONType.null_;\n\n    // Avoid UTF decoding when possible, as it is unnecessary when\n    // processing JSON.\n    static if (is(T : const(char)[]))\n        alias Char = char;\n    else\n        alias Char = Unqual!(ElementType!T);\n\n    int depth = -1;\n    Nullable!Char next;\n    int line = 1, pos = 0;\n    immutable bool strict = (options & JSONOptions.strictParsing) != 0;\n\n    void error(string msg)\n    {\n        throw new JSONException(msg, line, pos);\n    }\n\n    if (json.empty)\n    {\n        if (strict)\n        {\n            error(\"Empty JSON body\");\n        }\n        return root;\n    }\n\n    bool isWhite(dchar c)\n    {\n        if (strict)\n        {\n            // RFC 7159 has a stricter definition of whitespace than general ASCII.\n            return c == ' ' || c == '\\t' || c == '\\n' || c == '\\r';\n        }\n        import std.ascii : isWhite;\n        // Accept ASCII NUL as whitespace in non-strict mode.\n        return c == 0 || isWhite(c);\n    }\n\n    Char popChar()\n    {\n        if (json.empty) error(\"Unexpected end of data.\");\n        static if (is(T : const(char)[]))\n        {\n            Char c = json[0];\n            json = json[1..$];\n        }\n        else\n        {\n            Char c = json.front;\n            json.popFront();\n        }\n\n        if (c == '\\n')\n        {\n            line++;\n            pos = 0;\n        }\n        else\n        {\n            pos++;\n        }\n\n        return c;\n    }\n\n    Char peekChar()\n    {\n        if (next.isNull)\n        {\n            if (json.empty) return '\\0';\n            next = popChar();\n        }\n        return next.get;\n    }\n\n    Nullable!Char peekCharNullable()\n    {\n        if (next.isNull && !json.empty)\n        {\n            next = popChar();\n        }\n        return next;\n    }\n\n    void skipWhitespace()\n    {\n        while (true)\n        {\n            auto c = peekCharNullable();\n            if (c.isNull ||\n                !isWhite(c.get))\n            {\n                return;\n            }\n            next.nullify();\n        }\n    }\n\n    Char getChar(bool SkipWhitespace = false)()\n    {\n        static if (SkipWhitespace) skipWhitespace();\n\n        Char c;\n        if (!next.isNull)\n        {\n            c = next.get;\n            next.nullify();\n        }\n        else\n            c = popChar();\n\n        return c;\n    }\n\n    void checkChar(bool SkipWhitespace = true)(char c, bool caseSensitive = true)\n    {\n        static if (SkipWhitespace) skipWhitespace();\n        auto c2 = getChar();\n        if (!caseSensitive) c2 = toLower(c2);\n\n        if (c2 != c) error(text(\"Found '\", c2, \"' when expecting '\", c, \"'.\"));\n    }\n\n    bool testChar(bool SkipWhitespace = true, bool CaseSensitive = true)(char c)\n    {\n        static if (SkipWhitespace) skipWhitespace();\n        auto c2 = peekChar();\n        static if (!CaseSensitive) c2 = toLower(c2);\n\n        if (c2 != c) return false;\n\n        getChar();\n        return true;\n    }\n\n    wchar parseWChar()\n    {\n        wchar val = 0;\n        foreach_reverse (i; 0 .. 4)\n        {\n            auto hex = toUpper(getChar());\n            if (!isHexDigit(hex)) error(\"Expecting hex character\");\n            val += (isDigit(hex) ? hex - '0' : hex - ('A' - 10)) << (4 * i);\n        }\n        return val;\n    }\n\n    string parseString()\n    {\n        import std.uni : isSurrogateHi, isSurrogateLo;\n        import std.utf : encode, decode;\n\n        auto str = appender!string();\n\n    Next:\n        switch (peekChar())\n        {\n            case '\"':\n                getChar();\n                break;\n\n            case '\\\\':\n                getChar();\n                auto c = getChar();\n                switch (c)\n                {\n                    case '\"':       str.put('\"');   break;\n                    case '\\\\':      str.put('\\\\');  break;\n                    case '/':       str.put('/');   break;\n                    case 'b':       str.put('\\b');  break;\n                    case 'f':       str.put('\\f');  break;\n                    case 'n':       str.put('\\n');  break;\n                    case 'r':       str.put('\\r');  break;\n                    case 't':       str.put('\\t');  break;\n                    case 'u':\n                        wchar wc = parseWChar();\n                        dchar val;\n                        // Non-BMP characters are escaped as a pair of\n                        // UTF-16 surrogate characters (see RFC 4627).\n                        if (isSurrogateHi(wc))\n                        {\n                            wchar[2] pair;\n                            pair[0] = wc;\n                            if (getChar() != '\\\\') error(\"Expected escaped low surrogate after escaped high surrogate\");\n                            if (getChar() != 'u') error(\"Expected escaped low surrogate after escaped high surrogate\");\n                            pair[1] = parseWChar();\n                            size_t index = 0;\n                            val = decode(pair[], index);\n                            if (index != 2) error(\"Invalid escaped surrogate pair\");\n                        }\n                        else\n                        if (isSurrogateLo(wc))\n                            error(text(\"Unexpected low surrogate\"));\n                        else\n                            val = wc;\n\n                        char[4] buf;\n                        immutable len = encode!(Yes.useReplacementDchar)(buf, val);\n                        str.put(buf[0 .. len]);\n                        break;\n\n                    default:\n                        error(text(\"Invalid escape sequence '\\\\\", c, \"'.\"));\n                }\n                goto Next;\n\n            default:\n                // RFC 7159 states that control characters U+0000 through\n                // U+001F must not appear unescaped in a JSON string.\n                // Note: std.ascii.isControl can't be used for this test\n                // because it considers ASCII DEL (0x7f) to be a control\n                // character but RFC 7159 does not.\n                // Accept unescaped ASCII NULs in non-strict mode.\n                auto c = getChar();\n                if (c < 0x20 && (strict || c != 0))\n                    error(\"Illegal control character.\");\n                str.put(c);\n                goto Next;\n        }\n\n        return str.data.length ? str.data : \"\";\n    }\n\n    bool tryGetSpecialFloat(string str, out double val) {\n        switch (str)\n        {\n            case JSONFloatLiteral.nan:\n                val = double.nan;\n                return true;\n            case JSONFloatLiteral.inf:\n                val = double.infinity;\n                return true;\n            case JSONFloatLiteral.negativeInf:\n                val = -double.infinity;\n                return true;\n            default:\n                return false;\n        }\n    }\n\n    void parseValue(ref JSONValue value)\n    {\n        depth++;\n\n        if (maxDepth != -1 && depth > maxDepth) error(\"Nesting too deep.\");\n\n        auto c = getChar!true();\n\n        switch (c)\n        {\n            case '{':\n                if (testChar('}'))\n                {\n                    value.object = null;\n                    break;\n                }\n\n                JSONValue[string] obj;\n                do\n                {\n                    checkChar('\"');\n                    string name = parseString();\n                    checkChar(':');\n                    JSONValue member;\n                    parseValue(member);\n                    obj[name] = member;\n                }\n                while (testChar(','));\n                value.object = obj;\n\n                checkChar('}');\n                break;\n\n            case '[':\n                if (testChar(']'))\n                {\n                    value.type_tag = JSONType.array;\n                    break;\n                }\n\n                JSONValue[] arr;\n                do\n                {\n                    JSONValue element;\n                    parseValue(element);\n                    arr ~= element;\n                }\n                while (testChar(','));\n\n                checkChar(']');\n                value.array = arr;\n                break;\n\n            case '\"':\n                auto str = parseString();\n\n                // if special float parsing is enabled, check if string represents NaN/Inf\n                if ((options & JSONOptions.specialFloatLiterals) &&\n                    tryGetSpecialFloat(str, value.store.floating))\n                {\n                    // found a special float, its value was placed in value.store.floating\n                    value.type_tag = JSONType.float_;\n                    break;\n                }\n\n                value.type_tag = JSONType.string;\n                value.store.str = str;\n                break;\n\n            case '0': .. case '9':\n            case '-':\n                auto number = appender!string();\n                bool isFloat, isNegative;\n\n                void readInteger()\n                {\n                    if (!isDigit(c)) error(\"Digit expected\");\n\n                Next: number.put(c);\n\n                    if (isDigit(peekChar()))\n                    {\n                        c = getChar();\n                        goto Next;\n                    }\n                }\n\n                if (c == '-')\n                {\n                    number.put('-');\n                    c = getChar();\n                    isNegative = true;\n                }\n\n                if (strict && c == '0')\n                {\n                    number.put('0');\n                    if (isDigit(peekChar()))\n                    {\n                        error(\"Additional digits not allowed after initial zero digit\");\n                    }\n                }\n                else\n                {\n                    readInteger();\n                }\n\n                if (testChar('.'))\n                {\n                    isFloat = true;\n                    number.put('.');\n                    c = getChar();\n                    readInteger();\n                }\n                if (testChar!(false, false)('e'))\n                {\n                    isFloat = true;\n                    number.put('e');\n                    if (testChar('+')) number.put('+');\n                    else if (testChar('-')) number.put('-');\n                    c = getChar();\n                    readInteger();\n                }\n\n                string data = number.data;\n                if (isFloat)\n                {\n                    value.type_tag = JSONType.float_;\n                    value.store.floating = parse!double(data);\n                }\n                else\n                {\n                    if (isNegative)\n                        value.store.integer = parse!long(data);\n                    else\n                        value.store.uinteger = parse!ulong(data);\n\n                    value.type_tag = !isNegative && value.store.uinteger & (1UL << 63) ?\n                        JSONType.uinteger : JSONType.integer;\n                }\n                break;\n\n            case 'T':\n                if (strict) goto default;\n                goto case;\n            case 't':\n                value.type_tag = JSONType.true_;\n                checkChar!false('r', strict);\n                checkChar!false('u', strict);\n                checkChar!false('e', strict);\n                break;\n\n            case 'F':\n                if (strict) goto default;\n                goto case;\n            case 'f':\n                value.type_tag = JSONType.false_;\n                checkChar!false('a', strict);\n                checkChar!false('l', strict);\n                checkChar!false('s', strict);\n                checkChar!false('e', strict);\n                break;\n\n            case 'N':\n                if (strict) goto default;\n                goto case;\n            case 'n':\n                value.type_tag = JSONType.null_;\n                checkChar!false('u', strict);\n                checkChar!false('l', strict);\n                checkChar!false('l', strict);\n                break;\n\n            default:\n                error(text(\"Unexpected character '\", c, \"'.\"));\n        }\n\n        depth--;\n    }\n\n    parseValue(root);\n    if (strict)\n    {\n        skipWhitespace();\n        if (!peekCharNullable().isNull) error(\"Trailing non-whitespace characters\");\n    }\n    return root;\n}\n\n@safe unittest\n{\n    enum issue15742objectOfObject = `{ \"key1\": { \"key2\": 1 }}`;\n    static assert(parseJSON(issue15742objectOfObject).type == JSONType.object);\n\n    enum issue15742arrayOfArray = `[[1]]`;\n    static assert(parseJSON(issue15742arrayOfArray).type == JSONType.array);\n}\n\n@safe unittest\n{\n    // Ensure we can parse and use JSON from @safe code\n    auto a = `{ \"key1\": { \"key2\": 1 }}`.parseJSON;\n    assert(a[\"key1\"][\"key2\"].integer == 1);\n    assert(a.toString == `{\"key1\":{\"key2\":1}}`);\n}\n\n@system unittest\n{\n    // Ensure we can parse JSON from a @system range.\n    struct Range\n    {\n        string s;\n        size_t index;\n        @system\n        {\n            bool empty() { return index >= s.length; }\n            void popFront() { index++; }\n            char front() { return s[index]; }\n        }\n    }\n    auto s = Range(`{ \"key1\": { \"key2\": 1 }}`);\n    auto json = parseJSON(s);\n    assert(json[\"key1\"][\"key2\"].integer == 1);\n}\n\n/**\nParses a serialized string and returns a tree of JSON values.\nThrows: $(LREF JSONException) if the depth exceeds the max depth.\nParams:\n    json = json-formatted string to parse\n    options = enable decoding string representations of NaN/Inf as float values\n*/\nJSONValue parseJSON(T)(T json, JSONOptions options)\nif (isInputRange!T && !isInfinite!T && isSomeChar!(ElementEncodingType!T))\n{\n    return parseJSON!T(json, -1, options);\n}\n\n/**\nTakes a tree of JSON values and returns the serialized string.\n\nAny Object types will be serialized in a key-sorted order.\n\nIf `pretty` is false no whitespaces are generated.\nIf `pretty` is true serialized string is formatted to be human-readable.\nSet the $(LREF JSONOptions.specialFloatLiterals) flag is set in `options` to encode NaN/Infinity as strings.\n*/\nstring toJSON(const ref JSONValue root, in bool pretty = false, in JSONOptions options = JSONOptions.none) @safe\n{\n    auto json = appender!string();\n\n    void toStringImpl(Char)(string str) @safe\n    {\n        json.put('\"');\n\n        foreach (Char c; str)\n        {\n            switch (c)\n            {\n                case '\"':       json.put(\"\\\\\\\"\");       break;\n                case '\\\\':      json.put(\"\\\\\\\\\");       break;\n\n                case '/':\n                    if (!(options & JSONOptions.doNotEscapeSlashes))\n                        json.put('\\\\');\n                    json.put('/');\n                    break;\n\n                case '\\b':      json.put(\"\\\\b\");        break;\n                case '\\f':      json.put(\"\\\\f\");        break;\n                case '\\n':      json.put(\"\\\\n\");        break;\n                case '\\r':      json.put(\"\\\\r\");        break;\n                case '\\t':      json.put(\"\\\\t\");        break;\n                default:\n                {\n                    import std.ascii : isControl;\n                    import std.utf : encode;\n\n                    // Make sure we do UTF decoding iff we want to\n                    // escape Unicode characters.\n                    assert(((options & JSONOptions.escapeNonAsciiChars) != 0)\n                        == is(Char == dchar), \"JSONOptions.escapeNonAsciiChars needs dchar strings\");\n\n                    with (JSONOptions) if (isControl(c) ||\n                        ((options & escapeNonAsciiChars) >= escapeNonAsciiChars && c >= 0x80))\n                    {\n                        // Ensure non-BMP characters are encoded as a pair\n                        // of UTF-16 surrogate characters, as per RFC 4627.\n                        wchar[2] wchars; // 1 or 2 UTF-16 code units\n                        size_t wNum = encode(wchars, c); // number of UTF-16 code units\n                        foreach (wc; wchars[0 .. wNum])\n                        {\n                            json.put(\"\\\\u\");\n                            foreach_reverse (i; 0 .. 4)\n                            {\n                                char ch = (wc >>> (4 * i)) & 0x0f;\n                                ch += ch < 10 ? '0' : 'A' - 10;\n                                json.put(ch);\n                            }\n                        }\n                    }\n                    else\n                    {\n                        json.put(c);\n                    }\n                }\n            }\n        }\n\n        json.put('\"');\n    }\n\n    void toString(string str) @safe\n    {\n        // Avoid UTF decoding when possible, as it is unnecessary when\n        // processing JSON.\n        if (options & JSONOptions.escapeNonAsciiChars)\n            toStringImpl!dchar(str);\n        else\n            toStringImpl!char(str);\n    }\n\n    void toValue(ref in JSONValue value, ulong indentLevel) @safe\n    {\n        void putTabs(ulong additionalIndent = 0)\n        {\n            if (pretty)\n                foreach (i; 0 .. indentLevel + additionalIndent)\n                    json.put(\"    \");\n        }\n        void putEOL()\n        {\n            if (pretty)\n                json.put('\\n');\n        }\n        void putCharAndEOL(char ch)\n        {\n            json.put(ch);\n            putEOL();\n        }\n\n        final switch (value.type)\n        {\n            case JSONType.object:\n                auto obj = value.objectNoRef;\n                if (!obj.length)\n                {\n                    json.put(\"{}\");\n                }\n                else\n                {\n                    putCharAndEOL('{');\n                    bool first = true;\n\n                    void emit(R)(R names)\n                    {\n                        foreach (name; names)\n                        {\n                            auto member = obj[name];\n                            if (!first)\n                                putCharAndEOL(',');\n                            first = false;\n                            putTabs(1);\n                            toString(name);\n                            json.put(':');\n                            if (pretty)\n                                json.put(' ');\n                            toValue(member, indentLevel + 1);\n                        }\n                    }\n\n                    import std.algorithm.sorting : sort;\n                    // @@@BUG@@@ 14439\n                    // auto names = obj.keys;  // aa.keys can't be called in @safe code\n                    auto names = new string[obj.length];\n                    size_t i = 0;\n                    foreach (k, v; obj)\n                    {\n                        names[i] = k;\n                        i++;\n                    }\n                    sort(names);\n                    emit(names);\n\n                    putEOL();\n                    putTabs();\n                    json.put('}');\n                }\n                break;\n\n            case JSONType.array:\n                auto arr = value.arrayNoRef;\n                if (arr.empty)\n                {\n                    json.put(\"[]\");\n                }\n                else\n                {\n                    putCharAndEOL('[');\n                    foreach (i, el; arr)\n                    {\n                        if (i)\n                            putCharAndEOL(',');\n                        putTabs(1);\n                        toValue(el, indentLevel + 1);\n                    }\n                    putEOL();\n                    putTabs();\n                    json.put(']');\n                }\n                break;\n\n            case JSONType.string:\n                toString(value.str);\n                break;\n\n            case JSONType.integer:\n                json.put(to!string(value.store.integer));\n                break;\n\n            case JSONType.uinteger:\n                json.put(to!string(value.store.uinteger));\n                break;\n\n            case JSONType.float_:\n                import std.math : isNaN, isInfinity;\n\n                auto val = value.store.floating;\n\n                if (val.isNaN)\n                {\n                    if (options & JSONOptions.specialFloatLiterals)\n                    {\n                        toString(JSONFloatLiteral.nan);\n                    }\n                    else\n                    {\n                        throw new JSONException(\n                            \"Cannot encode NaN. Consider passing the specialFloatLiterals flag.\");\n                    }\n                }\n                else if (val.isInfinity)\n                {\n                    if (options & JSONOptions.specialFloatLiterals)\n                    {\n                        toString((val > 0) ?  JSONFloatLiteral.inf : JSONFloatLiteral.negativeInf);\n                    }\n                    else\n                    {\n                        throw new JSONException(\n                            \"Cannot encode Infinity. Consider passing the specialFloatLiterals flag.\");\n                    }\n                }\n                else\n                {\n                    import std.format : format;\n                    // The correct formula for the number of decimal digits needed for lossless round\n                    // trips is actually:\n                    //     ceil(log(pow(2.0, double.mant_dig - 1)) / log(10.0) + 1) == (double.dig + 2)\n                    // Anything less will round off (1 + double.epsilon)\n                    json.put(\"%.18g\".format(val));\n                }\n                break;\n\n            case JSONType.true_:\n                json.put(\"true\");\n                break;\n\n            case JSONType.false_:\n                json.put(\"false\");\n                break;\n\n            case JSONType.null_:\n                json.put(\"null\");\n                break;\n        }\n    }\n\n    toValue(root, 0);\n    return json.data;\n}\n\n@safe unittest // bugzilla 12897\n{\n    JSONValue jv0 = JSONValue(\"test测试\");\n    assert(toJSON(jv0, false, JSONOptions.escapeNonAsciiChars) == `\"test\\u6D4B\\u8BD5\"`);\n    JSONValue jv00 = JSONValue(\"test\\u6D4B\\u8BD5\");\n    assert(toJSON(jv00, false, JSONOptions.none) == `\"test测试\"`);\n    assert(toJSON(jv0, false, JSONOptions.none) == `\"test测试\"`);\n    JSONValue jv1 = JSONValue(\"été\");\n    assert(toJSON(jv1, false, JSONOptions.escapeNonAsciiChars) == `\"\\u00E9t\\u00E9\"`);\n    JSONValue jv11 = JSONValue(\"\\u00E9t\\u00E9\");\n    assert(toJSON(jv11, false, JSONOptions.none) == `\"été\"`);\n    assert(toJSON(jv1, false, JSONOptions.none) == `\"été\"`);\n}\n\n/**\nException thrown on JSON errors\n*/\nclass JSONException : Exception\n{\n    this(string msg, int line = 0, int pos = 0) pure nothrow @safe\n    {\n        if (line)\n            super(text(msg, \" (Line \", line, \":\", pos, \")\"));\n        else\n            super(msg);\n    }\n\n    this(string msg, string file, size_t line) pure nothrow @safe\n    {\n        super(msg, file, line);\n    }\n}\n\n\n@system unittest\n{\n    import std.exception;\n    JSONValue jv = \"123\";\n    assert(jv.type == JSONType.string);\n    assertNotThrown(jv.str);\n    assertThrown!JSONException(jv.integer);\n    assertThrown!JSONException(jv.uinteger);\n    assertThrown!JSONException(jv.floating);\n    assertThrown!JSONException(jv.object);\n    assertThrown!JSONException(jv.array);\n    assertThrown!JSONException(jv[\"aa\"]);\n    assertThrown!JSONException(jv[2]);\n\n    jv = -3;\n    assert(jv.type == JSONType.integer);\n    assertNotThrown(jv.integer);\n\n    jv = cast(uint) 3;\n    assert(jv.type == JSONType.uinteger);\n    assertNotThrown(jv.uinteger);\n\n    jv = 3.0;\n    assert(jv.type == JSONType.float_);\n    assertNotThrown(jv.floating);\n\n    jv = [\"key\" : \"value\"];\n    assert(jv.type == JSONType.object);\n    assertNotThrown(jv.object);\n    assertNotThrown(jv[\"key\"]);\n    assert(\"key\" in jv);\n    assert(\"notAnElement\" !in jv);\n    assertThrown!JSONException(jv[\"notAnElement\"]);\n    const cjv = jv;\n    assert(\"key\" in cjv);\n    assertThrown!JSONException(cjv[\"notAnElement\"]);\n\n    foreach (string key, value; jv)\n    {\n        static assert(is(typeof(value) == JSONValue));\n        assert(key == \"key\");\n        assert(value.type == JSONType.string);\n        assertNotThrown(value.str);\n        assert(value.str == \"value\");\n    }\n\n    jv = [3, 4, 5];\n    assert(jv.type == JSONType.array);\n    assertNotThrown(jv.array);\n    assertNotThrown(jv[2]);\n    foreach (size_t index, value; jv)\n    {\n        static assert(is(typeof(value) == JSONValue));\n        assert(value.type == JSONType.integer);\n        assertNotThrown(value.integer);\n        assert(index == (value.integer-3));\n    }\n\n    jv = null;\n    assert(jv.type == JSONType.null_);\n    assert(jv.isNull);\n    jv = \"foo\";\n    assert(!jv.isNull);\n\n    jv = JSONValue(\"value\");\n    assert(jv.type == JSONType.string);\n    assert(jv.str == \"value\");\n\n    JSONValue jv2 = JSONValue(\"value\");\n    assert(jv2.type == JSONType.string);\n    assert(jv2.str == \"value\");\n\n    JSONValue jv3 = JSONValue(\"\\u001c\");\n    assert(jv3.type == JSONType.string);\n    assert(jv3.str == \"\\u001C\");\n}\n\n@system unittest\n{\n    // Bugzilla 11504\n\n    JSONValue jv = 1;\n    assert(jv.type == JSONType.integer);\n\n    jv.str = \"123\";\n    assert(jv.type == JSONType.string);\n    assert(jv.str == \"123\");\n\n    jv.integer = 1;\n    assert(jv.type == JSONType.integer);\n    assert(jv.integer == 1);\n\n    jv.uinteger = 2u;\n    assert(jv.type == JSONType.uinteger);\n    assert(jv.uinteger == 2u);\n\n    jv.floating = 1.5;\n    assert(jv.type == JSONType.float_);\n    assert(jv.floating == 1.5);\n\n    jv.object = [\"key\" : JSONValue(\"value\")];\n    assert(jv.type == JSONType.object);\n    assert(jv.object == [\"key\" : JSONValue(\"value\")]);\n\n    jv.array = [JSONValue(1), JSONValue(2), JSONValue(3)];\n    assert(jv.type == JSONType.array);\n    assert(jv.array == [JSONValue(1), JSONValue(2), JSONValue(3)]);\n\n    jv = true;\n    assert(jv.type == JSONType.true_);\n\n    jv = false;\n    assert(jv.type == JSONType.false_);\n\n    enum E{True = true}\n    jv = E.True;\n    assert(jv.type == JSONType.true_);\n}\n\n@system pure unittest\n{\n    // Adding new json element via array() / object() directly\n\n    JSONValue jarr = JSONValue([10]);\n    foreach (i; 0 .. 9)\n        jarr.array ~= JSONValue(i);\n    assert(jarr.array.length == 10);\n\n    JSONValue jobj = JSONValue([\"key\" : JSONValue(\"value\")]);\n    foreach (i; 0 .. 9)\n        jobj.object[text(\"key\", i)] = JSONValue(text(\"value\", i));\n    assert(jobj.object.length == 10);\n}\n\n@system pure unittest\n{\n    // Adding new json element without array() / object() access\n\n    JSONValue jarr = JSONValue([10]);\n    foreach (i; 0 .. 9)\n        jarr ~= [JSONValue(i)];\n    assert(jarr.array.length == 10);\n\n    JSONValue jobj = JSONValue([\"key\" : JSONValue(\"value\")]);\n    foreach (i; 0 .. 9)\n        jobj[text(\"key\", i)] = JSONValue(text(\"value\", i));\n    assert(jobj.object.length == 10);\n\n    // No array alias\n    auto jarr2 = jarr ~ [1,2,3];\n    jarr2[0] = 999;\n    assert(jarr[0] == JSONValue(10));\n}\n\n@system unittest\n{\n    // @system because JSONValue.array is @system\n    import std.exception;\n\n    // An overly simple test suite, if it can parse a serializated string and\n    // then use the resulting values tree to generate an identical\n    // serialization, both the decoder and encoder works.\n\n    auto jsons = [\n        `null`,\n        `true`,\n        `false`,\n        `0`,\n        `123`,\n        `-4321`,\n        `0.25`,\n        `-0.25`,\n        `\"\"`,\n        `\"hello\\nworld\"`,\n        `\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"`,\n        `[]`,\n        `[12,\"foo\",true,false]`,\n        `{}`,\n        `{\"a\":1,\"b\":null}`,\n        `{\"goodbye\":[true,\"or\",false,[\"test\",42,{\"nested\":{\"a\":23.5,\"b\":0.140625}}]],`\n        ~`\"hello\":{\"array\":[12,null,{}],\"json\":\"is great\"}}`,\n    ];\n\n    enum dbl1_844 = `1.8446744073709568`;\n    version (MinGW)\n        jsons ~= dbl1_844 ~ `e+019`;\n    else\n        jsons ~= dbl1_844 ~ `e+19`;\n\n    JSONValue val;\n    string result;\n    foreach (json; jsons)\n    {\n        try\n        {\n            val = parseJSON(json);\n            enum pretty = false;\n            result = toJSON(val, pretty);\n            assert(result == json, text(result, \" should be \", json));\n        }\n        catch (JSONException e)\n        {\n            import std.stdio : writefln;\n            writefln(text(json, \"\\n\", e.toString()));\n        }\n    }\n\n    // Should be able to correctly interpret unicode entities\n    val = parseJSON(`\"\\u003C\\u003E\"`);\n    assert(toJSON(val) == \"\\\"\\&lt;\\&gt;\\\"\");\n    assert(val.to!string() == \"\\\"\\&lt;\\&gt;\\\"\");\n    val = parseJSON(`\"\\u0391\\u0392\\u0393\"`);\n    assert(toJSON(val) == \"\\\"\\&Alpha;\\&Beta;\\&Gamma;\\\"\");\n    assert(val.to!string() == \"\\\"\\&Alpha;\\&Beta;\\&Gamma;\\\"\");\n    val = parseJSON(`\"\\u2660\\u2666\"`);\n    assert(toJSON(val) == \"\\\"\\&spades;\\&diams;\\\"\");\n    assert(val.to!string() == \"\\\"\\&spades;\\&diams;\\\"\");\n\n    //0x7F is a control character (see Unicode spec)\n    val = parseJSON(`\"\\u007F\"`);\n    assert(toJSON(val) == \"\\\"\\\\u007F\\\"\");\n    assert(val.to!string() == \"\\\"\\\\u007F\\\"\");\n\n    with(parseJSON(`\"\"`))\n        assert(str == \"\" && str !is null);\n    with(parseJSON(`[]`))\n        assert(!array.length);\n\n    // Formatting\n    val = parseJSON(`{\"a\":[null,{\"x\":1},{},[]]}`);\n    assert(toJSON(val, true) == `{\n    \"a\": [\n        null,\n        {\n            \"x\": 1\n        },\n        {},\n        []\n    ]\n}`);\n}\n\n@safe unittest\n{\n  auto json = `\"hello\\nworld\"`;\n  const jv = parseJSON(json);\n  assert(jv.toString == json);\n  assert(jv.toPrettyString == json);\n}\n\n@system pure unittest\n{\n    // Bugzilla 12969\n\n    JSONValue jv;\n    jv[\"int\"] = 123;\n\n    assert(jv.type == JSONType.object);\n    assert(\"int\" in jv);\n    assert(jv[\"int\"].integer == 123);\n\n    jv[\"array\"] = [1, 2, 3, 4, 5];\n\n    assert(jv[\"array\"].type == JSONType.array);\n    assert(jv[\"array\"][2].integer == 3);\n\n    jv[\"str\"] = \"D language\";\n    assert(jv[\"str\"].type == JSONType.string);\n    assert(jv[\"str\"].str == \"D language\");\n\n    jv[\"bool\"] = false;\n    assert(jv[\"bool\"].type == JSONType.false_);\n\n    assert(jv.object.length == 4);\n\n    jv = [5, 4, 3, 2, 1];\n    assert(jv.type == JSONType.array);\n    assert(jv[3].integer == 2);\n}\n\n@safe unittest\n{\n    auto s = q\"EOF\n[\n  1,\n  2,\n  3,\n  potato\n]\nEOF\";\n\n    import std.exception;\n\n    auto e = collectException!JSONException(parseJSON(s));\n    assert(e.msg == \"Unexpected character 'p'. (Line 5:3)\", e.msg);\n}\n\n// handling of special float values (NaN, Inf, -Inf)\n@safe unittest\n{\n    import std.exception : assertThrown;\n    import std.math : isNaN, isInfinity;\n\n    // expected representations of NaN and Inf\n    enum {\n        nanString         = '\"' ~ JSONFloatLiteral.nan         ~ '\"',\n        infString         = '\"' ~ JSONFloatLiteral.inf         ~ '\"',\n        negativeInfString = '\"' ~ JSONFloatLiteral.negativeInf ~ '\"',\n    }\n\n    // with the specialFloatLiterals option, encode NaN/Inf as strings\n    assert(JSONValue(float.nan).toString(JSONOptions.specialFloatLiterals)       == nanString);\n    assert(JSONValue(double.infinity).toString(JSONOptions.specialFloatLiterals) == infString);\n    assert(JSONValue(-real.infinity).toString(JSONOptions.specialFloatLiterals)  == negativeInfString);\n\n    // without the specialFloatLiterals option, throw on encoding NaN/Inf\n    assertThrown!JSONException(JSONValue(float.nan).toString);\n    assertThrown!JSONException(JSONValue(double.infinity).toString);\n    assertThrown!JSONException(JSONValue(-real.infinity).toString);\n\n    // when parsing json with specialFloatLiterals option, decode special strings as floats\n    JSONValue jvNan    = parseJSON(nanString, JSONOptions.specialFloatLiterals);\n    JSONValue jvInf    = parseJSON(infString, JSONOptions.specialFloatLiterals);\n    JSONValue jvNegInf = parseJSON(negativeInfString, JSONOptions.specialFloatLiterals);\n\n    assert(jvNan.floating.isNaN);\n    assert(jvInf.floating.isInfinity    && jvInf.floating > 0);\n    assert(jvNegInf.floating.isInfinity && jvNegInf.floating < 0);\n\n    // when parsing json without the specialFloatLiterals option, decode special strings as strings\n    jvNan    = parseJSON(nanString);\n    jvInf    = parseJSON(infString);\n    jvNegInf = parseJSON(negativeInfString);\n\n    assert(jvNan.str    == JSONFloatLiteral.nan);\n    assert(jvInf.str    == JSONFloatLiteral.inf);\n    assert(jvNegInf.str == JSONFloatLiteral.negativeInf);\n}\n\npure nothrow @safe @nogc unittest\n{\n    JSONValue testVal;\n    testVal = \"test\";\n    testVal = 10;\n    testVal = 10u;\n    testVal = 1.0;\n    testVal = (JSONValue[string]).init;\n    testVal = JSONValue[].init;\n    testVal = null;\n    assert(testVal.isNull);\n}\n\npure nothrow @safe unittest // issue 15884\n{\n    import std.typecons;\n    void Test(C)() {\n        C[] a = ['x'];\n        JSONValue testVal = a;\n        assert(testVal.type == JSONType.string);\n        testVal = a.idup;\n        assert(testVal.type == JSONType.string);\n    }\n    Test!char();\n    Test!wchar();\n    Test!dchar();\n}\n\n@safe unittest // issue 15885\n{\n    enum bool realInDoublePrecision = real.mant_dig == double.mant_dig;\n\n    static bool test(const double num0)\n    {\n        import std.math : feqrel;\n        const json0 = JSONValue(num0);\n        const num1 = to!double(toJSON(json0));\n        static if (realInDoublePrecision)\n            return feqrel(num1, num0) >= (double.mant_dig - 1);\n        else\n            return num1 == num0;\n    }\n\n    assert(test( 0.23));\n    assert(test(-0.23));\n    assert(test(1.223e+24));\n    assert(test(23.4));\n    assert(test(0.0012));\n    assert(test(30738.22));\n\n    assert(test(1 + double.epsilon));\n    assert(test(double.min_normal));\n    static if (realInDoublePrecision)\n        assert(test(-double.max / 2));\n    else\n        assert(test(-double.max));\n\n    const minSub = double.min_normal * double.epsilon;\n    assert(test(minSub));\n    assert(test(3*minSub));\n}\n\n@safe unittest // issue 17555\n{\n    import std.exception : assertThrown;\n\n    assertThrown!JSONException(parseJSON(\"\\\"a\\nb\\\"\"));\n}\n\n@safe unittest // issue 17556\n{\n    auto v = JSONValue(\"\\U0001D11E\");\n    auto j = toJSON(v, false, JSONOptions.escapeNonAsciiChars);\n    assert(j == `\"\\uD834\\uDD1E\"`);\n}\n\n@safe unittest // issue 5904\n{\n    string s = `\"\\uD834\\uDD1E\"`;\n    auto j = parseJSON(s);\n    assert(j.str == \"\\U0001D11E\");\n}\n\n@safe unittest // issue 17557\n{\n    assert(parseJSON(\"\\\"\\xFF\\\"\").str == \"\\xFF\");\n    assert(parseJSON(\"\\\"\\U0001D11E\\\"\").str == \"\\U0001D11E\");\n}\n\n@safe unittest // issue 17553\n{\n    auto v = JSONValue(\"\\xFF\");\n    assert(toJSON(v) == \"\\\"\\xFF\\\"\");\n}\n\n@safe unittest\n{\n    import std.utf;\n    assert(parseJSON(\"\\\"\\xFF\\\"\".byChar).str == \"\\xFF\");\n    assert(parseJSON(\"\\\"\\U0001D11E\\\"\".byChar).str == \"\\U0001D11E\");\n}\n\n@safe unittest // JSONOptions.doNotEscapeSlashes (issue 17587)\n{\n    assert(parseJSON(`\"/\"`).toString == `\"\\/\"`);\n    assert(parseJSON(`\"\\/\"`).toString == `\"\\/\"`);\n    assert(parseJSON(`\"/\"`).toString(JSONOptions.doNotEscapeSlashes) == `\"/\"`);\n    assert(parseJSON(`\"\\/\"`).toString(JSONOptions.doNotEscapeSlashes) == `\"/\"`);\n}\n\n@safe unittest // JSONOptions.strictParsing (issue 16639)\n{\n    import std.exception : assertThrown;\n\n    // Unescaped ASCII NULs\n    assert(parseJSON(\"[\\0]\").type == JSONType.array);\n    assertThrown!JSONException(parseJSON(\"[\\0]\", JSONOptions.strictParsing));\n    assert(parseJSON(\"\\\"\\0\\\"\").str == \"\\0\");\n    assertThrown!JSONException(parseJSON(\"\\\"\\0\\\"\", JSONOptions.strictParsing));\n\n    // Unescaped ASCII DEL (0x7f) in strings\n    assert(parseJSON(\"\\\"\\x7f\\\"\").str == \"\\x7f\");\n    assert(parseJSON(\"\\\"\\x7f\\\"\", JSONOptions.strictParsing).str == \"\\x7f\");\n\n    // \"true\", \"false\", \"null\" case sensitivity\n    assert(parseJSON(\"true\").type == JSONType.true_);\n    assert(parseJSON(\"true\", JSONOptions.strictParsing).type == JSONType.true_);\n    assert(parseJSON(\"True\").type == JSONType.true_);\n    assertThrown!JSONException(parseJSON(\"True\", JSONOptions.strictParsing));\n    assert(parseJSON(\"tRUE\").type == JSONType.true_);\n    assertThrown!JSONException(parseJSON(\"tRUE\", JSONOptions.strictParsing));\n\n    assert(parseJSON(\"false\").type == JSONType.false_);\n    assert(parseJSON(\"false\", JSONOptions.strictParsing).type == JSONType.false_);\n    assert(parseJSON(\"False\").type == JSONType.false_);\n    assertThrown!JSONException(parseJSON(\"False\", JSONOptions.strictParsing));\n    assert(parseJSON(\"fALSE\").type == JSONType.false_);\n    assertThrown!JSONException(parseJSON(\"fALSE\", JSONOptions.strictParsing));\n\n    assert(parseJSON(\"null\").type == JSONType.null_);\n    assert(parseJSON(\"null\", JSONOptions.strictParsing).type == JSONType.null_);\n    assert(parseJSON(\"Null\").type == JSONType.null_);\n    assertThrown!JSONException(parseJSON(\"Null\", JSONOptions.strictParsing));\n    assert(parseJSON(\"nULL\").type == JSONType.null_);\n    assertThrown!JSONException(parseJSON(\"nULL\", JSONOptions.strictParsing));\n\n    // Whitespace characters\n    assert(parseJSON(\"[\\f\\v]\").type == JSONType.array);\n    assertThrown!JSONException(parseJSON(\"[\\f\\v]\", JSONOptions.strictParsing));\n    assert(parseJSON(\"[ \\t\\r\\n]\").type == JSONType.array);\n    assert(parseJSON(\"[ \\t\\r\\n]\", JSONOptions.strictParsing).type == JSONType.array);\n\n    // Empty input\n    assert(parseJSON(\"\").type == JSONType.null_);\n    assertThrown!JSONException(parseJSON(\"\", JSONOptions.strictParsing));\n\n    // Numbers with leading '0's\n    assert(parseJSON(\"01\").integer == 1);\n    assertThrown!JSONException(parseJSON(\"01\", JSONOptions.strictParsing));\n    assert(parseJSON(\"-01\").integer == -1);\n    assertThrown!JSONException(parseJSON(\"-01\", JSONOptions.strictParsing));\n    assert(parseJSON(\"0.01\").floating == 0.01);\n    assert(parseJSON(\"0.01\", JSONOptions.strictParsing).floating == 0.01);\n    assert(parseJSON(\"0e1\").floating == 0);\n    assert(parseJSON(\"0e1\", JSONOptions.strictParsing).floating == 0);\n\n    // Trailing characters after JSON value\n    assert(parseJSON(`\"\"asdf`).str == \"\");\n    assertThrown!JSONException(parseJSON(`\"\"asdf`, JSONOptions.strictParsing));\n    assert(parseJSON(\"987\\0\").integer == 987);\n    assertThrown!JSONException(parseJSON(\"987\\0\", JSONOptions.strictParsing));\n    assert(parseJSON(\"987\\0\\0\").integer == 987);\n    assertThrown!JSONException(parseJSON(\"987\\0\\0\", JSONOptions.strictParsing));\n    assert(parseJSON(\"[]]\").type == JSONType.array);\n    assertThrown!JSONException(parseJSON(\"[]]\", JSONOptions.strictParsing));\n    assert(parseJSON(\"123 \\t\\r\\n\").integer == 123); // Trailing whitespace is OK\n    assert(parseJSON(\"123 \\t\\r\\n\", JSONOptions.strictParsing).integer == 123);\n}\n"
  },
  {
    "path": "libphobos/src/std/math.d",
    "content": "// Written in the D programming language.\n\n/**\n * Contains the elementary mathematical functions (powers, roots,\n * and trigonometric functions), and low-level floating-point operations.\n * Mathematical special functions are available in `std.mathspecial`.\n *\n$(SCRIPT inhibitQuickIndex = 1;)\n\n$(DIVC quickindex,\n$(BOOKTABLE ,\n$(TR $(TH Category) $(TH Members) )\n$(TR $(TDNW Constants) $(TD\n    $(MYREF E) $(MYREF PI) $(MYREF PI_2) $(MYREF PI_4) $(MYREF M_1_PI)\n    $(MYREF M_2_PI) $(MYREF M_2_SQRTPI) $(MYREF LN10) $(MYREF LN2)\n    $(MYREF LOG2) $(MYREF LOG2E) $(MYREF LOG2T) $(MYREF LOG10E)\n    $(MYREF SQRT2) $(MYREF SQRT1_2)\n))\n$(TR $(TDNW Classics) $(TD\n    $(MYREF abs) $(MYREF fabs) $(MYREF sqrt) $(MYREF cbrt) $(MYREF hypot)\n    $(MYREF poly) $(MYREF nextPow2) $(MYREF truncPow2)\n))\n$(TR $(TDNW Trigonometry) $(TD\n    $(MYREF sin) $(MYREF cos) $(MYREF tan) $(MYREF asin) $(MYREF acos)\n    $(MYREF atan) $(MYREF atan2) $(MYREF sinh) $(MYREF cosh) $(MYREF tanh)\n    $(MYREF asinh) $(MYREF acosh) $(MYREF atanh) $(MYREF expi)\n))\n$(TR $(TDNW Rounding) $(TD\n    $(MYREF ceil) $(MYREF floor) $(MYREF round) $(MYREF lround)\n    $(MYREF trunc) $(MYREF rint) $(MYREF lrint) $(MYREF nearbyint)\n    $(MYREF rndtol) $(MYREF quantize)\n))\n$(TR $(TDNW Exponentiation & Logarithms) $(TD\n    $(MYREF pow) $(MYREF exp) $(MYREF exp2) $(MYREF expm1) $(MYREF ldexp)\n    $(MYREF frexp) $(MYREF log) $(MYREF log2) $(MYREF log10) $(MYREF logb)\n    $(MYREF ilogb) $(MYREF log1p) $(MYREF scalbn)\n))\n$(TR $(TDNW Modulus) $(TD\n    $(MYREF fmod) $(MYREF modf) $(MYREF remainder)\n))\n$(TR $(TDNW Floating-point operations) $(TD\n    $(MYREF approxEqual) $(MYREF feqrel) $(MYREF fdim) $(MYREF fmax)\n    $(MYREF fmin) $(MYREF fma) $(MYREF nextDown) $(MYREF nextUp)\n    $(MYREF nextafter) $(MYREF NaN) $(MYREF getNaNPayload)\n    $(MYREF cmp)\n))\n$(TR $(TDNW Introspection) $(TD\n    $(MYREF isFinite) $(MYREF isIdentical) $(MYREF isInfinity) $(MYREF isNaN)\n    $(MYREF isNormal) $(MYREF isSubnormal) $(MYREF signbit) $(MYREF sgn)\n    $(MYREF copysign) $(MYREF isPowerOf2)\n))\n$(TR $(TDNW Hardware Control) $(TD\n    $(MYREF IeeeFlags) $(MYREF FloatingPointControl)\n))\n)\n)\n\n * The functionality closely follows the IEEE754-2008 standard for\n * floating-point arithmetic, including the use of camelCase names rather\n * than C99-style lower case names. All of these functions behave correctly\n * when presented with an infinity or NaN.\n *\n * The following IEEE 'real' formats are currently supported:\n * $(UL\n * $(LI 64 bit Big-endian  'double' (eg PowerPC))\n * $(LI 128 bit Big-endian 'quadruple' (eg SPARC))\n * $(LI 64 bit Little-endian 'double' (eg x86-SSE2))\n * $(LI 80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium))\n * $(LI 128 bit Little-endian 'quadruple' (not implemented on any known processor!))\n * $(LI Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support)\n * )\n * Unlike C, there is no global 'errno' variable. Consequently, almost all of\n * these functions are pure nothrow.\n *\n * Macros:\n *      TABLE_SV = <table border=\"1\" cellpadding=\"4\" cellspacing=\"0\">\n *              <caption>Special Values</caption>\n *              $0</table>\n *      SVH = $(TR $(TH $1) $(TH $2))\n *      SV  = $(TR $(TD $1) $(TD $2))\n *      TH3 = $(TR $(TH $1) $(TH $2) $(TH $3))\n *      TD3 = $(TR $(TD $1) $(TD $2) $(TD $3))\n *      TABLE_DOMRG = <table border=\"1\" cellpadding=\"4\" cellspacing=\"0\">\n *              $(SVH Domain X, Range Y)\n                $(SV $1, $2)\n *              </table>\n *      DOMAIN=$1\n *      RANGE=$1\n\n *      NAN = $(RED NAN)\n *      SUP = <span style=\"vertical-align:super;font-size:smaller\">$0</span>\n *      GAMMA = &#915;\n *      THETA = &theta;\n *      INTEGRAL = &#8747;\n *      INTEGRATE = $(BIG &#8747;<sub>$(SMALL $1)</sub><sup>$2</sup>)\n *      POWER = $1<sup>$2</sup>\n *      SUB = $1<sub>$2</sub>\n *      BIGSUM = $(BIG &Sigma; <sup>$2</sup><sub>$(SMALL $1)</sub>)\n *      CHOOSE = $(BIG &#40;) <sup>$(SMALL $1)</sup><sub>$(SMALL $2)</sub> $(BIG &#41;)\n *      PLUSMN = &plusmn;\n *      INFIN = &infin;\n *      PLUSMNINF = &plusmn;&infin;\n *      PI = &pi;\n *      LT = &lt;\n *      GT = &gt;\n *      SQRT = &radic;\n *      HALF = &frac12;\n *\n * Copyright: Copyright The D Language Foundation 2000 - 2011.\n *            D implementations of tan, atan, atan2, exp, expm1, exp2, log, log10, log1p,\n *            log2, floor, ceil and lrint functions are based on the CEPHES math library,\n *            which is Copyright (C) 2001 Stephen L. Moshier $(LT)steve@moshier.net$(GT)\n *            and are incorporated herein by permission of the author.  The author\n *            reserves the right to distribute this material elsewhere under different\n *            copying permissions.  These modifications are distributed here under\n *            the following terms:\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright), Don Clugston,\n *            Conversion of CEPHES math library to D by Iain Buclaw and David Nadlinger\n * Source: $(PHOBOSSRC std/math.d)\n */\n\n/* NOTE: This file has been patched from the original DMD distribution to\n * work with the GDC compiler.\n */\nmodule std.math;\n\nversion (Win64)\n{\n    version (D_InlineAsm_X86_64)\n        version = Win64_DMD_InlineAsm;\n}\n\nstatic import core.math;\nstatic import core.stdc.math;\nstatic import core.stdc.fenv;\nimport std.traits; // CommonType, isFloatingPoint, isIntegral, isSigned, isUnsigned, Largest, Unqual\n\nversion (LDC)\n{\n    import ldc.intrinsics;\n}\n\nversion (DigitalMars)\n{\n    version = INLINE_YL2X;        // x87 has opcodes for these\n}\n\nversion (X86)       version = X86_Any;\nversion (X86_64)    version = X86_Any;\nversion (PPC)       version = PPC_Any;\nversion (PPC64)     version = PPC_Any;\nversion (MIPS32)    version = MIPS_Any;\nversion (MIPS64)    version = MIPS_Any;\nversion (AArch64)   version = ARM_Any;\nversion (ARM)       version = ARM_Any;\nversion (SPARC)     version = SPARC_Any;\nversion (SPARC64)   version = SPARC_Any;\n\nversion (D_InlineAsm_X86)\n{\n    version = InlineAsm_X86_Any;\n}\nelse version (D_InlineAsm_X86_64)\n{\n    version = InlineAsm_X86_Any;\n}\n\nversion (X86_64) version = StaticallyHaveSSE;\nversion (X86) version (OSX) version = StaticallyHaveSSE;\n\nversion (StaticallyHaveSSE)\n{\n    private enum bool haveSSE = true;\n}\nelse version (X86)\n{\n    static import core.cpuid;\n    private alias haveSSE = core.cpuid.sse;\n}\n\nversion (unittest) private\n{\n    static if (real.sizeof > double.sizeof)\n        enum uint useDigits = 16;\n    else\n        enum uint useDigits = 15;\n\n    /******************************************\n     * Compare floating point numbers to n decimal digits of precision.\n     * Returns:\n     *  1       match\n     *  0       nomatch\n     */\n\n    private bool equalsDigit(real x, real y, uint ndigits) @safe nothrow @nogc\n    {\n        import core.stdc.stdio : sprintf;\n\n        if (signbit(x) != signbit(y))\n            return 0;\n\n        if (isInfinity(x) && isInfinity(y))\n            return 1;\n        if (isInfinity(x) || isInfinity(y))\n            return 0;\n\n        if (isNaN(x) && isNaN(y))\n            return 1;\n        if (isNaN(x) || isNaN(y))\n            return 0;\n\n        char[30] bufx;\n        char[30] bufy;\n        assert(ndigits < bufx.length);\n\n        int ix;\n        int iy;\n        version (CRuntime_Microsoft)\n            alias real_t = double;\n        else\n            alias real_t = real;\n\n        () @trusted {\n            ix = sprintf(bufx.ptr, \"%.*Lg\", ndigits, cast(real_t) x);\n            iy = sprintf(bufy.ptr, \"%.*Lg\", ndigits, cast(real_t) y);\n        } ();\n\n        assert(ix < bufx.length && ix > 0);\n        assert(ix < bufy.length && ix > 0);\n\n        return bufx[0 .. ix] == bufy[0 .. iy];\n    }\n}\n\n\n\npackage:\n// The following IEEE 'real' formats are currently supported.\nversion (LittleEndian)\n{\n    static assert(real.mant_dig == 53 || real.mant_dig == 64\n               || real.mant_dig == 113,\n      \"Only 64-bit, 80-bit, and 128-bit reals\"~\n      \" are supported for LittleEndian CPUs\");\n}\nelse\n{\n    static assert(real.mant_dig == 53 || real.mant_dig == 113,\n    \"Only 64-bit and 128-bit reals are supported for BigEndian CPUs.\");\n}\n\n// Underlying format exposed through floatTraits\nenum RealFormat\n{\n    ieeeHalf,\n    ieeeSingle,\n    ieeeDouble,\n    ieeeExtended,   // x87 80-bit real\n    ieeeExtended53, // x87 real rounded to precision of double.\n    ibmExtended,    // IBM 128-bit extended\n    ieeeQuadruple,\n}\n\n// Constants used for extracting the components of the representation.\n// They supplement the built-in floating point properties.\ntemplate floatTraits(T)\n{\n    // EXPMASK is a ushort mask to select the exponent portion (without sign)\n    // EXPSHIFT is the number of bits the exponent is left-shifted by in its ushort\n    // EXPBIAS is the exponent bias - 1 (exp == EXPBIAS yields ×2^-1).\n    // EXPPOS_SHORT is the index of the exponent when represented as a ushort array.\n    // SIGNPOS_BYTE is the index of the sign when represented as a ubyte array.\n    // RECIP_EPSILON is the value such that (smallest_subnormal) * RECIP_EPSILON == T.min_normal\n    enum T RECIP_EPSILON = (1/T.epsilon);\n    static if (T.mant_dig == 24)\n    {\n        // Single precision float\n        enum ushort EXPMASK = 0x7F80;\n        enum ushort EXPSHIFT = 7;\n        enum ushort EXPBIAS = 0x3F00;\n        enum uint EXPMASK_INT = 0x7F80_0000;\n        enum uint MANTISSAMASK_INT = 0x007F_FFFF;\n        enum realFormat = RealFormat.ieeeSingle;\n        version (LittleEndian)\n        {\n            enum EXPPOS_SHORT = 1;\n            enum SIGNPOS_BYTE = 3;\n        }\n        else\n        {\n            enum EXPPOS_SHORT = 0;\n            enum SIGNPOS_BYTE = 0;\n        }\n    }\n    else static if (T.mant_dig == 53)\n    {\n        static if (T.sizeof == 8)\n        {\n            // Double precision float, or real == double\n            enum ushort EXPMASK = 0x7FF0;\n            enum ushort EXPSHIFT = 4;\n            enum ushort EXPBIAS = 0x3FE0;\n            enum uint EXPMASK_INT = 0x7FF0_0000;\n            enum uint MANTISSAMASK_INT = 0x000F_FFFF; // for the MSB only\n            enum realFormat = RealFormat.ieeeDouble;\n            version (LittleEndian)\n            {\n                enum EXPPOS_SHORT = 3;\n                enum SIGNPOS_BYTE = 7;\n            }\n            else\n            {\n                enum EXPPOS_SHORT = 0;\n                enum SIGNPOS_BYTE = 0;\n            }\n        }\n        else static if (T.sizeof == 12)\n        {\n            // Intel extended real80 rounded to double\n            enum ushort EXPMASK = 0x7FFF;\n            enum ushort EXPSHIFT = 0;\n            enum ushort EXPBIAS = 0x3FFE;\n            enum realFormat = RealFormat.ieeeExtended53;\n            version (LittleEndian)\n            {\n                enum EXPPOS_SHORT = 4;\n                enum SIGNPOS_BYTE = 9;\n            }\n            else\n            {\n                enum EXPPOS_SHORT = 0;\n                enum SIGNPOS_BYTE = 0;\n            }\n        }\n        else\n            static assert(false, \"No traits support for \" ~ T.stringof);\n    }\n    else static if (T.mant_dig == 64)\n    {\n        // Intel extended real80\n        enum ushort EXPMASK = 0x7FFF;\n        enum ushort EXPSHIFT = 0;\n        enum ushort EXPBIAS = 0x3FFE;\n        enum realFormat = RealFormat.ieeeExtended;\n        version (LittleEndian)\n        {\n            enum EXPPOS_SHORT = 4;\n            enum SIGNPOS_BYTE = 9;\n        }\n        else\n        {\n            enum EXPPOS_SHORT = 0;\n            enum SIGNPOS_BYTE = 0;\n        }\n    }\n    else static if (T.mant_dig == 113)\n    {\n        // Quadruple precision float\n        enum ushort EXPMASK = 0x7FFF;\n        enum ushort EXPSHIFT = 0;\n        enum ushort EXPBIAS = 0x3FFE;\n        enum realFormat = RealFormat.ieeeQuadruple;\n        version (LittleEndian)\n        {\n            enum EXPPOS_SHORT = 7;\n            enum SIGNPOS_BYTE = 15;\n        }\n        else\n        {\n            enum EXPPOS_SHORT = 0;\n            enum SIGNPOS_BYTE = 0;\n        }\n    }\n    else static if (T.mant_dig == 106)\n    {\n        // IBM Extended doubledouble\n        enum ushort EXPMASK = 0x7FF0;\n        enum ushort EXPSHIFT = 4;\n        enum realFormat = RealFormat.ibmExtended;\n\n        // For IBM doubledouble the larger magnitude double comes first.\n        // It's really a double[2] and arrays don't index differently\n        // between little and big-endian targets.\n        enum DOUBLEPAIR_MSB = 0;\n        enum DOUBLEPAIR_LSB = 1;\n\n        // The exponent/sign byte is for most significant part.\n        version (LittleEndian)\n        {\n            enum EXPPOS_SHORT = 3;\n            enum SIGNPOS_BYTE = 7;\n        }\n        else\n        {\n            enum EXPPOS_SHORT = 0;\n            enum SIGNPOS_BYTE = 0;\n        }\n    }\n    else\n        static assert(false, \"No traits support for \" ~ T.stringof);\n}\n\n// These apply to all floating-point types\nversion (LittleEndian)\n{\n    enum MANTISSA_LSB = 0;\n    enum MANTISSA_MSB = 1;\n}\nelse\n{\n    enum MANTISSA_LSB = 1;\n    enum MANTISSA_MSB = 0;\n}\n\n// Common code for math implementations.\n\n// Helper for floor/ceil\nT floorImpl(T)(const T x) @trusted pure nothrow @nogc\n{\n    alias F = floatTraits!(T);\n    // Take care not to trigger library calls from the compiler,\n    // while ensuring that we don't get defeated by some optimizers.\n    union floatBits\n    {\n        T rv;\n        ushort[T.sizeof/2] vu;\n\n        // Other kinds of extractors for real formats.\n        static if (F.realFormat == RealFormat.ieeeSingle)\n            int vi;\n    }\n    floatBits y = void;\n    y.rv = x;\n\n    // Find the exponent (power of 2)\n    // Do this by shifting the raw value so that the exponent lies in the low bits,\n    // then mask out the sign bit, and subtract the bias.\n    static if (F.realFormat == RealFormat.ieeeSingle)\n    {\n        int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;\n    }\n    else static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;\n\n        version (LittleEndian)\n            int pos = 0;\n        else\n            int pos = 3;\n    }\n    else static if (F.realFormat == RealFormat.ieeeExtended)\n    {\n        int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;\n\n        version (LittleEndian)\n            int pos = 0;\n        else\n            int pos = 4;\n    }\n    else static if (F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;\n\n        version (LittleEndian)\n            int pos = 0;\n        else\n            int pos = 7;\n    }\n    else\n        static assert(false, \"Not implemented for this architecture\");\n\n    if (exp < 0)\n    {\n        if (x < 0.0)\n            return -1.0;\n        else\n            return 0.0;\n    }\n\n    static if (F.realFormat == RealFormat.ieeeSingle)\n    {\n        if (exp < (T.mant_dig - 1))\n        {\n            // Clear all bits representing the fraction part.\n            const uint fraction_mask = F.MANTISSAMASK_INT >> exp;\n\n            if ((y.vi & fraction_mask) != 0)\n            {\n                // If 'x' is negative, then first substract 1.0 from the value.\n                if (y.vi < 0)\n                    y.vi += 0x00800000 >> exp;\n                y.vi &= ~fraction_mask;\n            }\n        }\n    }\n    else\n    {\n        exp = (T.mant_dig - 1) - exp;\n\n        // Zero 16 bits at a time.\n        while (exp >= 16)\n        {\n            version (LittleEndian)\n                y.vu[pos++] = 0;\n            else\n                y.vu[pos--] = 0;\n            exp -= 16;\n        }\n\n        // Clear the remaining bits.\n        if (exp > 0)\n            y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);\n\n        if ((x < 0.0) && (x != y.rv))\n            y.rv -= 1.0;\n    }\n\n    return y.rv;\n}\n\npublic:\n\n// Values obtained from Wolfram Alpha. 116 bits ought to be enough for anybody.\n// Wolfram Alpha LLC. 2011. Wolfram|Alpha. http://www.wolframalpha.com/input/?i=e+in+base+16 (access July 6, 2011).\nenum real E =          0x1.5bf0a8b1457695355fb8ac404e7a8p+1L; /** e = 2.718281... */\nenum real LOG2T =      0x1.a934f0979a3715fc9257edfe9b5fbp+1L; /** $(SUB log, 2)10 = 3.321928... */\nenum real LOG2E =      0x1.71547652b82fe1777d0ffda0d23a8p+0L; /** $(SUB log, 2)e = 1.442695... */\nenum real LOG2 =       0x1.34413509f79fef311f12b35816f92p-2L; /** $(SUB log, 10)2 = 0.301029... */\nenum real LOG10E =     0x1.bcb7b1526e50e32a6ab7555f5a67cp-2L; /** $(SUB log, 10)e = 0.434294... */\nenum real LN2 =        0x1.62e42fefa39ef35793c7673007e5fp-1L; /** ln 2  = 0.693147... */\nenum real LN10 =       0x1.26bb1bbb5551582dd4adac5705a61p+1L; /** ln 10 = 2.302585... */\nenum real PI =         0x1.921fb54442d18469898cc51701b84p+1L; /** &pi; = 3.141592... */\nenum real PI_2 =       PI/2;                                  /** $(PI) / 2 = 1.570796... */\nenum real PI_4 =       PI/4;                                  /** $(PI) / 4 = 0.785398... */\nenum real M_1_PI =     0x1.45f306dc9c882a53f84eafa3ea69cp-2L; /** 1 / $(PI) = 0.318309... */\nenum real M_2_PI =     2*M_1_PI;                              /** 2 / $(PI) = 0.636619... */\nenum real M_2_SQRTPI = 0x1.20dd750429b6d11ae3a914fed7fd8p+0L; /** 2 / $(SQRT)$(PI) = 1.128379... */\nenum real SQRT2 =      0x1.6a09e667f3bcc908b2fb1366ea958p+0L; /** $(SQRT)2 = 1.414213... */\nenum real SQRT1_2 =    SQRT2/2;                               /** $(SQRT)$(HALF) = 0.707106... */\n// Note: Make sure the magic numbers in compiler backend for x87 match these.\n\n// it's quite tricky check for a type who will trigger a deprecation when accessed\ntemplate isDeprecatedComplex(T)\n{\n    static if (__traits(isDeprecated, T))\n    {\n        enum isDeprecatedComplex = true;\n    }\n    else\n    {\n        enum m = T.mangleof;\n        // cfloat, cdouble, creal\n        // ifloat, idouble, ireal\n        enum isDeprecatedComplex = m == \"q\" || m == \"r\" || m == \"c\" ||\n                                   m == \"o\" || m == \"p\" || m == \"j\";\n    }\n}\n\n@safe deprecated unittest\n{\n    static assert(isDeprecatedComplex!cfloat);\n    static assert(isDeprecatedComplex!cdouble);\n    static assert(isDeprecatedComplex!creal);\n    static assert(isDeprecatedComplex!ifloat);\n    static assert(isDeprecatedComplex!idouble);\n    static assert(isDeprecatedComplex!ireal);\n\n    static assert(!isDeprecatedComplex!float);\n    static assert(!isDeprecatedComplex!double);\n    static assert(!isDeprecatedComplex!real);\n}\n\n/***********************************\n * Calculates the absolute value of a number\n *\n * Params:\n *     Num = (template parameter) type of number\n *       x = real number value\n *\n * Returns:\n *     The absolute value of the number.  If floating-point or integral,\n *     the return type will be the same as the input;\n */\nauto abs(Num)(Num x)\nif ((is(Unqual!Num == short) || is(Unqual!Num == byte)) ||\n    (is(typeof(Num.init >= 0)) && is(typeof(-Num.init))))\n{\n    static if (isFloatingPoint!(Num))\n        return fabs(x);\n    else\n    {\n        static if (is(Unqual!Num == short) || is(Unqual!Num == byte))\n            return x >= 0 ? x : cast(Num) -int(x);\n        else\n            return x >= 0 ? x : -x;\n    }\n}\n\n/// ditto\n@safe pure nothrow @nogc unittest\n{\n    assert(isIdentical(abs(-0.0L), 0.0L));\n    assert(isNaN(abs(real.nan)));\n    assert(abs(-real.infinity) == real.infinity);\n    assert(abs(-56) == 56);\n    assert(abs(2321312L)  == 2321312L);\n}\n\nversion (TestComplex)\ndeprecated\n@safe pure nothrow @nogc unittest\n{\n    assert(abs(-3.2Li) == 3.2L);\n    assert(abs(71.6Li) == 71.6L);\n    assert(abs(-1L+1i) == sqrt(2.0L));\n}\n\n@safe pure nothrow @nogc unittest\n{\n    short s = -8;\n    byte b = -8;\n    assert(abs(s) == 8);\n    assert(abs(b) == 8);\n    immutable(byte) c = -8;\n    assert(abs(c) == 8);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(float, double, real))\n    {{\n        T f = 3;\n        assert(abs(f) == f);\n        assert(abs(-f) == f);\n    }}\n}\n\nversion (TestComplex)\ndeprecated\n@safe pure nothrow @nogc unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(cfloat, cdouble, creal))\n    {{\n        T f = -12+3i;\n        assert(abs(f) == hypot(f.re, f.im));\n        assert(abs(-f) == hypot(f.re, f.im));\n    }}\n}\n\nimport std.meta : AliasSeq;\ndeprecated(\"Please use std.complex\")\nstatic foreach (Num; AliasSeq!(cfloat, cdouble, creal, ifloat, idouble, ireal))\n{\n    auto abs(Num z) @safe pure nothrow @nogc\n    {\n        enum m = Num.mangleof;\n        // cfloat, cdouble, creal\n        static if (m == \"q\" || m == \"r\" || m == \"c\")\n            return hypot(z.re, z.im);\n        // ifloat, idouble, ireal\n        else static if (m == \"o\" || m == \"p\" || m == \"j\")\n            return fabs(z.im);\n        else\n            static assert(0, \"Unsupported type: \" ~ Num.stringof);\n    }\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=19162\n@safe unittest\n{\n    struct Vector(T, int size)\n    {\n        T x, y, z;\n    }\n\n    static auto abs(T, int size)(auto ref const Vector!(T, size) v)\n    {\n        return v;\n    }\n    Vector!(int, 3) v;\n    assert(abs(v) == v);\n}\n\n/*\n * Complex conjugate\n *\n *  conj(x + iy) = x - iy\n *\n * Note that z * conj(z) = $(POWER z.re, 2) - $(POWER z.im, 2)\n * is always a real number\n */\ndeprecated(\"Please use std.complex.conj\")\nauto conj(Num)(Num z) @safe pure nothrow @nogc\nif (is(Num* : const(cfloat*)) || is(Num* : const(cdouble*))\n    || is(Num* : const(creal*)))\n{\n    //FIXME\n    //Issue 14206\n    static if (is(Num* : const(cdouble*)))\n        return cast(cdouble) conj(cast(creal) z);\n    else\n        return z.re - z.im*1fi;\n}\n\ndeprecated(\"Please use std.complex.conj\")\nauto conj(Num)(Num y) @safe pure nothrow @nogc\nif (is(Num* : const(ifloat*)) || is(Num* : const(idouble*))\n    || is(Num* : const(ireal*)))\n{\n    return -y;\n}\n\ndeprecated\n@safe pure nothrow @nogc unittest\n{\n    creal c = 7 + 3Li;\n    assert(conj(c) == 7-3Li);\n    ireal z = -3.2Li;\n    assert(conj(z) == -z);\n}\n//Issue 14206\ndeprecated\n@safe pure nothrow @nogc unittest\n{\n    cdouble c = 7 + 3i;\n    assert(conj(c) == 7-3i);\n    idouble z = -3.2i;\n    assert(conj(z) == -z);\n}\n//Issue 14206\ndeprecated\n@safe pure nothrow @nogc unittest\n{\n    cfloat c = 7f + 3fi;\n    assert(conj(c) == 7f-3fi);\n    ifloat z = -3.2fi;\n    assert(conj(z) == -z);\n}\n\n/***********************************\n * Returns cosine of x. x is in radians.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)                 $(TH cos(x)) $(TH invalid?))\n *      $(TR $(TD $(NAN))            $(TD $(NAN)) $(TD yes)     )\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(NAN)) $(TD yes)     )\n *      )\n * Bugs:\n *      Results are undefined if |x| >= $(POWER 2,64).\n */\n\nreal cos(real x) @safe pure nothrow @nogc { pragma(inline, true); return core.math.cos(x); }\n//FIXME\n///ditto\ndouble cos(double x) @safe pure nothrow @nogc { return cos(cast(real) x); }\n//FIXME\n///ditto\nfloat cos(float x) @safe pure nothrow @nogc { return cos(cast(real) x); }\n\n///\n@safe unittest\n{\n    assert(cos(0.0) == 1.0);\n    assert(cos(1.0).approxEqual(0.540));\n    assert(cos(3.0).approxEqual(-0.989));\n}\n\n@safe unittest\n{\n    real function(real) pcos = &cos;\n    assert(pcos != null);\n}\n\n/***********************************\n * Returns $(HTTP en.wikipedia.org/wiki/Sine, sine) of x. x is in $(HTTP en.wikipedia.org/wiki/Radian, radians).\n *\n *      $(TABLE_SV\n *      $(TH3 x           ,  sin(x)      ,  invalid?)\n *      $(TD3 $(NAN)      ,  $(NAN)      ,  yes     )\n *      $(TD3 $(PLUSMN)0.0,  $(PLUSMN)0.0,  no      )\n *      $(TD3 $(PLUSMNINF),  $(NAN)      ,  yes     )\n *      )\n *\n * Params:\n *      x = angle in radians (not degrees)\n * Returns:\n *      sine of x\n * See_Also:\n *      $(MYREF cos), $(MYREF tan), $(MYREF asin)\n * Bugs:\n *      Results are undefined if |x| >= $(POWER 2,64).\n */\n\nreal sin(real x) @safe pure nothrow @nogc { pragma(inline, true); return core.math.sin(x); }\n//FIXME\n///ditto\ndouble sin(double x) @safe pure nothrow @nogc { return sin(cast(real) x); }\n//FIXME\n///ditto\nfloat sin(float x) @safe pure nothrow @nogc { return sin(cast(real) x); }\n\n///\n@safe unittest\n{\n    import std.math : sin, PI;\n    import std.stdio : writefln;\n\n    void someFunc()\n    {\n      real x = 30.0;\n      auto result = sin(x * (PI / 180)); // convert degrees to radians\n      writefln(\"The sine of %s degrees is %s\", x, result);\n    }\n}\n\n@safe unittest\n{\n    real function(real) psin = &sin;\n    assert(psin != null);\n}\n\n/*\n *  Returns sine for complex and imaginary arguments.\n *\n *  sin(z) = sin(z.re)*cosh(z.im) + cos(z.re)*sinh(z.im)i\n *\n * If both sin($(THETA)) and cos($(THETA)) are required,\n * it is most efficient to use expi($(THETA)).\n */\ndeprecated(\"Use std.complex.sin\")\nauto sin(creal z) @safe pure nothrow @nogc\n{\n    const creal cs = expi(z.re);\n    const creal csh = coshisinh(z.im);\n    return cs.im * csh.re + cs.re * csh.im * 1i;\n}\n\n/* ditto */\ndeprecated(\"Use std.complex.sin\")\nauto sin(ireal y) @safe pure nothrow @nogc\n{\n    return cosh(y.im)*1i;\n}\n\ndeprecated\n@safe pure nothrow @nogc unittest\n{\n  assert(sin(0.0+0.0i) == 0.0);\n  assert(sin(2.0+0.0i) == sin(2.0L) );\n}\n\n/*\n *  cosine, complex and imaginary\n *\n *  cos(z) = cos(z.re)*cosh(z.im) - sin(z.re)*sinh(z.im)i\n */\ndeprecated(\"Use std.complex.cos\")\nauto cos(creal z) @safe pure nothrow @nogc\n{\n    const creal cs = expi(z.re);\n    const creal csh = coshisinh(z.im);\n    return cs.re * csh.re - cs.im * csh.im * 1i;\n}\n\n/* ditto */\ndeprecated(\"Use std.complex.cos\")\nreal cos(ireal y) @safe pure nothrow @nogc\n{\n    return cosh(y.im);\n}\n\ndeprecated\n@safe pure nothrow @nogc unittest\n{\n    assert(cos(0.0+0.0i)==1.0);\n    assert(cos(1.3L+0.0i)==cos(1.3L));\n    assert(cos(5.2Li)== cosh(5.2L));\n}\n\n/****************************************************************************\n * Returns tangent of x. x is in radians.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)             $(TH tan(x))       $(TH invalid?))\n *      $(TR $(TD $(NAN))        $(TD $(NAN))       $(TD yes))\n *      $(TR $(TD $(PLUSMN)0.0)  $(TD $(PLUSMN)0.0) $(TD no))\n *      $(TR $(TD $(PLUSMNINF))  $(TD $(NAN))       $(TD yes))\n *      )\n */\nreal tan(real x) @trusted pure nothrow @nogc // TODO: @safe\n{\n    version (InlineAsm_X86_Any)\n    {\n        if (!__ctfe)\n            return tanAsm(x);\n    }\n    return tanImpl(x);\n}\n\n/// ditto\ndouble tan(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) tan(cast(real) x) : tanImpl(x); }\n\n/// ditto\nfloat tan(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) tan(cast(real) x) : tanImpl(x); }\n\n///\n@safe unittest\n{\n    assert(isIdentical(tan(0.0), 0.0));\n    assert(tan(PI).approxEqual(0));\n    assert(tan(PI / 3).approxEqual(sqrt(3.0)));\n}\n\nversion (InlineAsm_X86_Any)\nprivate real tanAsm(real x) @trusted pure nothrow @nogc\n{\n    version (D_InlineAsm_X86)\n    {\n    asm pure nothrow @nogc\n    {\n        fld     x[EBP]                  ; // load theta\n        fxam                            ; // test for oddball values\n        fstsw   AX                      ;\n        sahf                            ;\n        jc      trigerr                 ; // x is NAN, infinity, or empty\n                                          // 387's can handle subnormals\nSC18:   fptan                           ;\n        fstsw   AX                      ;\n        sahf                            ;\n        jnp     Clear1                  ; // C2 = 1 (x is out of range)\n\n        // Do argument reduction to bring x into range\n        fldpi                           ;\n        fxch                            ;\nSC17:   fprem1                          ;\n        fstsw   AX                      ;\n        sahf                            ;\n        jp      SC17                    ;\n        fstp    ST(1)                   ; // remove pi from stack\n        jmp     SC18                    ;\n\ntrigerr:\n        jnp     Lret                    ; // if theta is NAN, return theta\n        fstp    ST(0)                   ; // dump theta\n    }\n    return real.nan;\n\nClear1: asm pure nothrow @nogc{\n        fstp    ST(0)                   ; // dump X, which is always 1\n    }\n\nLret: {}\n    }\n    else version (D_InlineAsm_X86_64)\n    {\n        version (Win64)\n        {\n            asm pure nothrow @nogc\n            {\n                fld     real ptr [RCX]  ; // load theta\n            }\n        }\n        else\n        {\n            asm pure nothrow @nogc\n            {\n                fld     x[RBP]          ; // load theta\n            }\n        }\n    asm pure nothrow @nogc\n    {\n        fxam                            ; // test for oddball values\n        fstsw   AX                      ;\n        test    AH,1                    ;\n        jnz     trigerr                 ; // x is NAN, infinity, or empty\n                                          // 387's can handle subnormals\nSC18:   fptan                           ;\n        fstsw   AX                      ;\n        test    AH,4                    ;\n        jz      Clear1                  ; // C2 = 1 (x is out of range)\n\n        // Do argument reduction to bring x into range\n        fldpi                           ;\n        fxch                            ;\nSC17:   fprem1                          ;\n        fstsw   AX                      ;\n        test    AH,4                    ;\n        jnz     SC17                    ;\n        fstp    ST(1)                   ; // remove pi from stack\n        jmp     SC18                    ;\n\ntrigerr:\n        test    AH,4                    ;\n        jz      Lret                    ; // if theta is NAN, return theta\n        fstp    ST(0)                   ; // dump theta\n    }\n    return real.nan;\n\nClear1: asm pure nothrow @nogc{\n        fstp    ST(0)                   ; // dump X, which is always 1\n    }\n\nLret: {}\n    }\n    else\n        static assert(0);\n}\n\nprivate T tanImpl(T)(T x) @safe pure nothrow @nogc\n{\n    // Coefficients for tan(x) and PI/4 split into three parts.\n    enum realFormat = floatTraits!T.realFormat;\n    static if (realFormat == RealFormat.ieeeQuadruple)\n    {\n        static immutable T[6] P = [\n            2.883414728874239697964612246732416606301E10L,\n            -2.307030822693734879744223131873392503321E9L,\n            5.160188250214037865511600561074819366815E7L,\n            -4.249691853501233575668486667664718192660E5L,\n            1.272297782199996882828849455156962260810E3L,\n            -9.889929415807650724957118893791829849557E-1L\n        ];\n        static immutable T[7] Q = [\n            8.650244186622719093893836740197250197602E10L,\n            -4.152206921457208101480801635640958361612E10L,\n            2.758476078803232151774723646710890525496E9L,\n            -5.733709132766856723608447733926138506824E7L,\n            4.529422062441341616231663543669583527923E5L,\n            -1.317243702830553658702531997959756728291E3L,\n            1.0\n        ];\n\n        enum T P1 =\n            7.853981633974483067550664827649598009884357452392578125E-1L;\n        enum T P2 =\n            2.8605943630549158983813312792950660807511260829685741796657E-18L;\n        enum T P3 =\n            2.1679525325309452561992610065108379921905808E-35L;\n    }\n    else static if (realFormat == RealFormat.ieeeExtended ||\n                    realFormat == RealFormat.ieeeDouble)\n    {\n        static immutable T[3] P = [\n           -1.7956525197648487798769E7L,\n            1.1535166483858741613983E6L,\n           -1.3093693918138377764608E4L,\n        ];\n        static immutable T[5] Q = [\n           -5.3869575592945462988123E7L,\n            2.5008380182335791583922E7L,\n           -1.3208923444021096744731E6L,\n            1.3681296347069295467845E4L,\n            1.0000000000000000000000E0L,\n        ];\n\n        enum T P1 = 7.853981554508209228515625E-1L;\n        enum T P2 = 7.946627356147928367136046290398E-9L;\n        enum T P3 = 3.061616997868382943065164830688E-17L;\n    }\n    else static if (realFormat == RealFormat.ieeeSingle)\n    {\n        static immutable T[6] P = [\n            3.33331568548E-1,\n            1.33387994085E-1,\n            5.34112807005E-2,\n            2.44301354525E-2,\n            3.11992232697E-3,\n            9.38540185543E-3,\n        ];\n\n        enum T P1 = 0.78515625;\n        enum T P2 = 2.4187564849853515625E-4;\n        enum T P3 = 3.77489497744594108E-8;\n    }\n    else\n        static assert(0, \"no coefficients for tan()\");\n\n    // Special cases.\n    if (x == cast(T) 0.0 || isNaN(x))\n        return x;\n    if (isInfinity(x))\n        return T.nan;\n\n    // Make argument positive but save the sign.\n    bool sign = false;\n    if (signbit(x))\n    {\n        sign = true;\n        x = -x;\n    }\n\n    // Compute x mod PI/4.\n    static if (realFormat == RealFormat.ieeeSingle)\n    {\n        enum T FOPI = 4 / PI;\n        int j = cast(int) (FOPI * x);\n        T y = j;\n        T z;\n    }\n    else\n    {\n        T y = floor(x / cast(T) PI_4);\n        // Strip high bits of integer part.\n        enum T highBitsFactor = (realFormat == RealFormat.ieeeDouble ? 0x1p3 : 0x1p4);\n        enum T highBitsInv = 1.0 / highBitsFactor;\n        T z = y * highBitsInv;\n        // Compute y - 2^numHighBits * (y / 2^numHighBits).\n        z = y - highBitsFactor * floor(z);\n\n        // Integer and fraction part modulo one octant.\n        int j = cast(int)(z);\n    }\n\n    // Map zeros and singularities to origin.\n    if (j & 1)\n    {\n        j += 1;\n        y += cast(T) 1.0;\n    }\n\n    z = ((x - y * P1) - y * P2) - y * P3;\n    const T zz = z * z;\n\n    enum T zzThreshold = (realFormat == RealFormat.ieeeSingle ? 1.0e-4L :\n                          realFormat == RealFormat.ieeeDouble ? 1.0e-14L : 1.0e-20L);\n    if (zz > zzThreshold)\n    {\n        static if (realFormat == RealFormat.ieeeSingle)\n            y = z + z * (zz * poly(zz, P));\n        else\n            y = z + z * (zz * poly(zz, P) / poly(zz, Q));\n    }\n    else\n        y = z;\n\n    if (j & 2)\n        y = (cast(T) -1.0) / y;\n\n    return (sign) ? -y : y;\n}\n\n@safe @nogc nothrow unittest\n{\n    static void testTan(T)()\n    {\n        // ±0\n        const T zero = 0.0;\n        assert(isIdentical(tan(zero), zero));\n        assert(isIdentical(tan(-zero), -zero));\n        // ±∞\n        const T inf = T.infinity;\n        assert(isNaN(tan(inf)));\n        assert(isNaN(tan(-inf)));\n        // NaN\n        const T specialNaN = NaN(0x0123L);\n        assert(isIdentical(tan(specialNaN), specialNaN));\n\n        static immutable T[2][] vals =\n        [\n            // angle, tan\n            [   .5,  .5463024898],\n            [   1,   1.557407725],\n            [   1.5, 14.10141995],\n            [   2,  -2.185039863],\n            [   2.5,-.7470222972],\n            [   3,  -.1425465431],\n            [   3.5, .3745856402],\n            [   4,   1.157821282],\n            [   4.5, 4.637332055],\n            [   5,  -3.380515006],\n            [   5.5,-.9955840522],\n            [   6,  -.2910061914],\n            [   6.5, .2202772003],\n            [   10,  .6483608275],\n\n            // special angles\n            [   PI_4,   1],\n            //[   PI_2,   T.infinity], // PI_2 is not _exactly_ pi/2.\n            [   3*PI_4, -1],\n            [   PI,     0],\n            [   5*PI_4, 1],\n            //[   3*PI_2, -T.infinity],\n            [   7*PI_4, -1],\n            [   2*PI,   0],\n         ];\n\n        foreach (ref val; vals)\n        {\n            T x = val[0];\n            T r = val[1];\n            T t = tan(x);\n\n            //printf(\"tan(%Lg) = %Lg, should be %Lg\\n\", cast(real) x, cast(real) t, cast(real) r);\n            assert(approxEqual(r, t));\n\n            x = -x;\n            r = -r;\n            t = tan(x);\n            //printf(\"tan(%Lg) = %Lg, should be %Lg\\n\", cast(real) x, cast(real) t, cast(real) r);\n            assert(approxEqual(r, t));\n        }\n    }\n\n    import std.meta : AliasSeq;\n    foreach (T; AliasSeq!(real, double, float))\n        testTan!T();\n\n    assert(equalsDigit(tan(PI / 3), std.math.sqrt(3.0L), useDigits));\n}\n\n/***************\n * Calculates the arc cosine of x,\n * returning a value ranging from 0 to $(PI).\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)         $(TH acos(x)) $(TH invalid?))\n *      $(TR $(TD $(GT)1.0)  $(TD $(NAN))  $(TD yes))\n *      $(TR $(TD $(LT)-1.0) $(TD $(NAN))  $(TD yes))\n *      $(TR $(TD $(NAN))    $(TD $(NAN))  $(TD yes))\n *  )\n */\nreal acos(real x) @safe pure nothrow @nogc\n{\n    return atan2(sqrt(1-x*x), x);\n}\n\n/// ditto\ndouble acos(double x) @safe pure nothrow @nogc { return acos(cast(real) x); }\n\n/// ditto\nfloat acos(float x) @safe pure nothrow @nogc  { return acos(cast(real) x); }\n\n///\n@safe unittest\n{\n    assert(acos(0.0).approxEqual(1.570));\n    assert(acos(0.5).approxEqual(std.math.PI / 3));\n    assert(acos(PI).isNaN);\n}\n\n@safe @nogc nothrow unittest\n{\n    assert(equalsDigit(acos(0.5), std.math.PI / 3, useDigits));\n}\n\n/***************\n * Calculates the arc sine of x,\n * returning a value ranging from -$(PI)/2 to $(PI)/2.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)            $(TH asin(x))      $(TH invalid?))\n *      $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no))\n *      $(TR $(TD $(GT)1.0)     $(TD $(NAN))       $(TD yes))\n *      $(TR $(TD $(LT)-1.0)    $(TD $(NAN))       $(TD yes))\n *  )\n */\nreal asin(real x) @safe pure nothrow @nogc\n{\n    return atan2(x, sqrt(1-x*x));\n}\n\n/// ditto\ndouble asin(double x) @safe pure nothrow @nogc { return asin(cast(real) x); }\n\n/// ditto\nfloat asin(float x) @safe pure nothrow @nogc  { return asin(cast(real) x); }\n\n///\n@safe unittest\n{\n    assert(isIdentical(asin(0.0), 0.0));\n    assert(asin(0.5).approxEqual(PI / 6));\n    assert(asin(PI).isNaN);\n}\n\n@safe @nogc nothrow unittest\n{\n    assert(equalsDigit(asin(0.5), PI / 6, useDigits));\n}\n\n/***************\n * Calculates the arc tangent of x,\n * returning a value ranging from -$(PI)/2 to $(PI)/2.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)                 $(TH atan(x))      $(TH invalid?))\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(PLUSMN)0.0) $(TD no))\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(NAN))       $(TD yes))\n *  )\n */\nreal atan(real x) @safe pure nothrow @nogc\n{\n    version (InlineAsm_X86_Any)\n    {\n        if (!__ctfe)\n            return atan2Asm(x, 1.0L);\n    }\n    return atanImpl(x);\n}\n\n/// ditto\ndouble atan(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) atan(cast(real) x) : atanImpl(x); }\n\n/// ditto\nfloat atan(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) atan(cast(real) x) : atanImpl(x); }\n\n///\n@safe unittest\n{\n    assert(isIdentical(atan(0.0), 0.0));\n    assert(atan(sqrt(3.0)).approxEqual(PI / 3));\n}\n\nprivate T atanImpl(T)(T x) @safe pure nothrow @nogc\n{\n    // Coefficients for atan(x)\n    enum realFormat = floatTraits!T.realFormat;\n    static if (realFormat == RealFormat.ieeeQuadruple)\n    {\n        static immutable T[9] P = [\n            -6.880597774405940432145577545328795037141E2L,\n            -2.514829758941713674909996882101723647996E3L,\n            -3.696264445691821235400930243493001671932E3L,\n            -2.792272753241044941703278827346430350236E3L,\n            -1.148164399808514330375280133523543970854E3L,\n            -2.497759878476618348858065206895055957104E2L,\n            -2.548067867495502632615671450650071218995E1L,\n            -8.768423468036849091777415076702113400070E-1L,\n            -6.635810778635296712545011270011752799963E-4L\n        ];\n        static immutable T[9] Q = [\n            2.064179332321782129643673263598686441900E3L,\n            8.782996876218210302516194604424986107121E3L,\n            1.547394317752562611786521896296215170819E4L,\n            1.458510242529987155225086911411015961174E4L,\n            7.928572347062145288093560392463784743935E3L,\n            2.494680540950601626662048893678584497900E3L,\n            4.308348370818927353321556740027020068897E2L,\n            3.566239794444800849656497338030115886153E1L,\n            1.0\n        ];\n    }\n    else static if (realFormat == RealFormat.ieeeExtended)\n    {\n        static immutable T[5] P = [\n           -5.0894116899623603312185E1L,\n           -9.9988763777265819915721E1L,\n           -6.3976888655834347413154E1L,\n           -1.4683508633175792446076E1L,\n           -8.6863818178092187535440E-1L,\n        ];\n        static immutable T[6] Q = [\n            1.5268235069887081006606E2L,\n            3.9157570175111990631099E2L,\n            3.6144079386152023162701E2L,\n            1.4399096122250781605352E2L,\n            2.2981886733594175366172E1L,\n            1.0000000000000000000000E0L,\n        ];\n    }\n    else static if (realFormat == RealFormat.ieeeDouble)\n    {\n        static immutable T[5] P = [\n           -6.485021904942025371773E1L,\n           -1.228866684490136173410E2L,\n           -7.500855792314704667340E1L,\n           -1.615753718733365076637E1L,\n           -8.750608600031904122785E-1L,\n        ];\n        static immutable T[6] Q = [\n            1.945506571482613964425E2L,\n            4.853903996359136964868E2L,\n            4.328810604912902668951E2L,\n            1.650270098316988542046E2L,\n            2.485846490142306297962E1L,\n            1.000000000000000000000E0L,\n        ];\n\n        enum T MOREBITS = 6.123233995736765886130E-17L;\n    }\n    else static if (realFormat == RealFormat.ieeeSingle)\n    {\n        static immutable T[4] P = [\n           -3.33329491539E-1,\n            1.99777106478E-1,\n           -1.38776856032E-1,\n            8.05374449538E-2,\n        ];\n    }\n    else\n        static assert(0, \"no coefficients for atan()\");\n\n    // tan(PI/8)\n    enum T TAN_PI_8 = 0.414213562373095048801688724209698078569672L;\n    // tan(3 * PI/8)\n    enum T TAN3_PI_8 = 2.414213562373095048801688724209698078569672L;\n\n    // Special cases.\n    if (x == cast(T) 0.0)\n        return x;\n    if (isInfinity(x))\n        return copysign(cast(T) PI_2, x);\n\n    // Make argument positive but save the sign.\n    bool sign = false;\n    if (signbit(x))\n    {\n        sign = true;\n        x = -x;\n    }\n\n    static if (realFormat == RealFormat.ieeeDouble) // special case for double precision\n    {\n        short flag = 0;\n        T y;\n        if (x > TAN3_PI_8)\n        {\n            y = PI_2;\n            flag = 1;\n            x = -(1.0 / x);\n        }\n        else if (x <= 0.66)\n        {\n            y = 0.0;\n        }\n        else\n        {\n            y = PI_4;\n            flag = 2;\n            x = (x - 1.0)/(x + 1.0);\n        }\n\n        T z = x * x;\n        z = z * poly(z, P) / poly(z, Q);\n        z = x * z + x;\n        if (flag == 2)\n            z += 0.5 * MOREBITS;\n        else if (flag == 1)\n            z += MOREBITS;\n        y = y + z;\n    }\n    else\n    {\n        // Range reduction.\n        T y;\n        if (x > TAN3_PI_8)\n        {\n            y = PI_2;\n            x = -((cast(T) 1.0) / x);\n        }\n        else if (x > TAN_PI_8)\n        {\n            y = PI_4;\n            x = (x - cast(T) 1.0)/(x + cast(T) 1.0);\n        }\n        else\n            y = 0.0;\n\n        // Rational form in x^^2.\n        const T z = x * x;\n        static if (realFormat == RealFormat.ieeeSingle)\n            y += poly(z, P) * z * x + x;\n        else\n            y = y + (poly(z, P) / poly(z, Q)) * z * x + x;\n    }\n\n    return (sign) ? -y : y;\n}\n\n@safe @nogc nothrow unittest\n{\n    static void testAtan(T)()\n    {\n        // ±0\n        const T zero = 0.0;\n        assert(isIdentical(atan(zero), zero));\n        assert(isIdentical(atan(-zero), -zero));\n        // ±∞\n        const T inf = T.infinity;\n        assert(approxEqual(atan(inf), cast(T) PI_2));\n        assert(approxEqual(atan(-inf), cast(T) -PI_2));\n        // NaN\n        const T specialNaN = NaN(0x0123L);\n        assert(isIdentical(atan(specialNaN), specialNaN));\n\n        static immutable T[2][] vals =\n        [\n            // x, atan(x)\n            [ 0.25, 0.2449786631 ],\n            [ 0.5,  0.4636476090 ],\n            [ 1,    PI_4         ],\n            [ 1.5,  0.9827937232 ],\n            [ 10,   1.4711276743 ],\n        ];\n\n        foreach (ref val; vals)\n        {\n            T x = val[0];\n            T r = val[1];\n            T a = atan(x);\n\n            //printf(\"atan(%Lg) = %Lg, should be %Lg\\n\", cast(real) x, cast(real) a, cast(real) r);\n            assert(approxEqual(r, a));\n\n            x = -x;\n            r = -r;\n            a = atan(x);\n            //printf(\"atan(%Lg) = %Lg, should be %Lg\\n\", cast(real) x, cast(real) a, cast(real) r);\n            assert(approxEqual(r, a));\n        }\n    }\n\n    import std.meta : AliasSeq;\n    foreach (T; AliasSeq!(real, double, float))\n        testAtan!T();\n\n    assert(equalsDigit(atan(std.math.sqrt(3.0L)), PI / 3, useDigits));\n}\n\n/***************\n * Calculates the arc tangent of y / x,\n * returning a value ranging from -$(PI) to $(PI).\n *\n *      $(TABLE_SV\n *      $(TR $(TH y)                 $(TH x)            $(TH atan(y, x)))\n *      $(TR $(TD $(NAN))            $(TD anything)     $(TD $(NAN)) )\n *      $(TR $(TD anything)          $(TD $(NAN))       $(TD $(NAN)) )\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(GT)0.0)     $(TD $(PLUSMN)0.0) )\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD +0.0)         $(TD $(PLUSMN)0.0) )\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(LT)0.0)     $(TD $(PLUSMN)$(PI)))\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD -0.0)         $(TD $(PLUSMN)$(PI)))\n *      $(TR $(TD $(GT)0.0)          $(TD $(PLUSMN)0.0) $(TD $(PI)/2) )\n *      $(TR $(TD $(LT)0.0)          $(TD $(PLUSMN)0.0) $(TD -$(PI)/2) )\n *      $(TR $(TD $(GT)0.0)          $(TD $(INFIN))     $(TD $(PLUSMN)0.0) )\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD anything)     $(TD $(PLUSMN)$(PI)/2))\n *      $(TR $(TD $(GT)0.0)          $(TD -$(INFIN))    $(TD $(PLUSMN)$(PI)) )\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(INFIN))     $(TD $(PLUSMN)$(PI)/4))\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD -$(INFIN))    $(TD $(PLUSMN)3$(PI)/4))\n *      )\n */\nreal atan2(real y, real x) @trusted pure nothrow @nogc // TODO: @safe\n{\n    version (InlineAsm_X86_Any)\n    {\n        if (!__ctfe)\n            return atan2Asm(y, x);\n    }\n    return atan2Impl(y, x);\n}\n\n/// ditto\ndouble atan2(double y, double x) @safe pure nothrow @nogc\n{\n    return __ctfe ? cast(double) atan2(cast(real) y, cast(real) x) : atan2Impl(y, x);\n}\n\n/// ditto\nfloat atan2(float y, float x) @safe pure nothrow @nogc\n{\n    return __ctfe ? cast(float) atan2(cast(real) y, cast(real) x) : atan2Impl(y, x);\n}\n\n///\n@safe unittest\n{\n    assert(atan2(1.0, sqrt(3.0)).approxEqual(PI / 6));\n}\n\nversion (InlineAsm_X86_Any)\nprivate real atan2Asm(real y, real x) @trusted pure nothrow @nogc\n{\n    version (Win64)\n    {\n        asm pure nothrow @nogc {\n            naked;\n            fld real ptr [RDX]; // y\n            fld real ptr [RCX]; // x\n            fpatan;\n            ret;\n        }\n    }\n    else\n    {\n        asm pure nothrow @nogc {\n            fld y;\n            fld x;\n            fpatan;\n        }\n    }\n}\n\nprivate T atan2Impl(T)(T y, T x) @safe pure nothrow @nogc\n{\n    // Special cases.\n    if (isNaN(x) || isNaN(y))\n        return T.nan;\n    if (y == cast(T) 0.0)\n    {\n        if (x >= 0 && !signbit(x))\n            return copysign(0, y);\n        else\n            return copysign(cast(T) PI, y);\n    }\n    if (x == cast(T) 0.0)\n        return copysign(cast(T) PI_2, y);\n    if (isInfinity(x))\n    {\n        if (signbit(x))\n        {\n            if (isInfinity(y))\n                return copysign(3 * cast(T) PI_4, y);\n            else\n                return copysign(cast(T) PI, y);\n        }\n        else\n        {\n            if (isInfinity(y))\n                return copysign(cast(T) PI_4, y);\n            else\n                return copysign(cast(T) 0.0, y);\n        }\n    }\n    if (isInfinity(y))\n        return copysign(cast(T) PI_2, y);\n\n    // Call atan and determine the quadrant.\n    T z = atan(y / x);\n\n    if (signbit(x))\n    {\n        if (signbit(y))\n            z = z - cast(T) PI;\n        else\n            z = z + cast(T) PI;\n    }\n\n    if (z == cast(T) 0.0)\n        return copysign(z, y);\n\n    return z;\n}\n\n@safe @nogc nothrow unittest\n{\n    static void testAtan2(T)()\n    {\n        // NaN\n        const T nan = T.nan;\n        assert(isNaN(atan2(nan, cast(T) 1)));\n        assert(isNaN(atan2(cast(T) 1, nan)));\n\n        const T inf = T.infinity;\n        static immutable T[3][] vals =\n        [\n            // y, x, atan2(y, x)\n\n            // ±0\n            [  0.0,  1.0,  0.0 ],\n            [ -0.0,  1.0, -0.0 ],\n            [  0.0,  0.0,  0.0 ],\n            [ -0.0,  0.0, -0.0 ],\n            [  0.0, -1.0,  PI ],\n            [ -0.0, -1.0, -PI ],\n            [  0.0, -0.0,  PI ],\n            [ -0.0, -0.0, -PI ],\n            [  1.0,  0.0,  PI_2 ],\n            [  1.0, -0.0,  PI_2 ],\n            [ -1.0,  0.0, -PI_2 ],\n            [ -1.0, -0.0, -PI_2 ],\n\n            // ±∞\n            [  1.0,  inf,  0.0 ],\n            [ -1.0,  inf, -0.0 ],\n            [  1.0, -inf,  PI ],\n            [ -1.0, -inf, -PI ],\n            [  inf,  1.0,  PI_2 ],\n            [  inf, -1.0,  PI_2 ],\n            [ -inf,  1.0, -PI_2 ],\n            [ -inf, -1.0, -PI_2 ],\n            [  inf,  inf,  PI_4 ],\n            [ -inf,  inf, -PI_4 ],\n            [  inf, -inf,  3 * PI_4 ],\n            [ -inf, -inf, -3 * PI_4 ],\n\n            [  1.0,  1.0,  PI_4 ],\n            [ -2.0,  2.0, -PI_4 ],\n            [  3.0, -3.0,  3 * PI_4 ],\n            [ -4.0, -4.0, -3 * PI_4 ],\n\n            [  0.75,  0.25,   1.249045772398 ],\n            [ -0.5,   0.375, -0.927295218002 ],\n            [  0.5,  -0.125,  1.815774989922 ],\n            [ -0.75, -0.5,   -2.158798930342 ],\n        ];\n\n        foreach (ref val; vals)\n        {\n            const T y = val[0];\n            const T x = val[1];\n            const T r = val[2];\n            const T a = atan2(y, x);\n\n            //printf(\"atan2(%Lg, %Lg) = %Lg, should be %Lg\\n\", cast(real) y, cast(real) x, cast(real) a, cast(real) r);\n            if (r == 0)\n                assert(isIdentical(r, a)); // check sign\n            else\n                assert(approxEqual(r, a));\n        }\n    }\n\n    import std.meta : AliasSeq;\n    foreach (T; AliasSeq!(real, double, float))\n        testAtan2!T();\n\n    assert(equalsDigit(atan2(1.0L, std.math.sqrt(3.0L)), PI / 6, useDigits));\n}\n\n/***********************************\n * Calculates the hyperbolic cosine of x.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)                 $(TH cosh(x))      $(TH invalid?))\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)0.0) $(TD no) )\n *      )\n */\nreal cosh(real x) @safe pure nothrow @nogc\n{\n    //  cosh = (exp(x)+exp(-x))/2.\n    // The naive implementation works correctly.\n    const real y = exp(x);\n    return (y + 1.0/y) * 0.5;\n}\n\n/// ditto\ndouble cosh(double x) @safe pure nothrow @nogc { return cosh(cast(real) x); }\n\n/// ditto\nfloat cosh(float x) @safe pure nothrow @nogc  { return cosh(cast(real) x); }\n\n///\n@safe unittest\n{\n    assert(cosh(0.0) == 1.0);\n    assert(cosh(1.0).approxEqual((E + 1.0 / E) / 2));\n}\n\n@safe @nogc nothrow unittest\n{\n    assert(equalsDigit(cosh(1.0), (E + 1.0 / E) / 2, useDigits));\n}\n\n/***********************************\n * Calculates the hyperbolic sine of x.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)                 $(TH sinh(x))           $(TH invalid?))\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(PLUSMN)0.0)      $(TD no))\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)$(INFIN)) $(TD no))\n *      )\n */\nreal sinh(real x) @safe pure nothrow @nogc\n{\n    //  sinh(x) =  (exp(x)-exp(-x))/2;\n    // Very large arguments could cause an overflow, but\n    // the maximum value of x for which exp(x) + exp(-x)) != exp(x)\n    // is x = 0.5 * (real.mant_dig) * LN2. // = 22.1807 for real80.\n    if (fabs(x) > real.mant_dig * LN2)\n    {\n        return copysign(0.5 * exp(fabs(x)), x);\n    }\n\n    const real y = expm1(x);\n    return 0.5 * y / (y+1) * (y+2);\n}\n\n/// ditto\ndouble sinh(double x) @safe pure nothrow @nogc { return sinh(cast(real) x); }\n\n/// ditto\nfloat sinh(float x) @safe pure nothrow @nogc  { return sinh(cast(real) x); }\n\n///\n@safe unittest\n{\n    assert(isIdentical(sinh(0.0), 0.0));\n    assert(sinh(1.0).approxEqual((E - 1.0 / E) / 2));\n}\n\n@safe @nogc nothrow unittest\n{\n    assert(equalsDigit(sinh(1.0), (E - 1.0 / E) / 2, useDigits));\n}\n\n/***********************************\n * Calculates the hyperbolic tangent of x.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)                 $(TH tanh(x))      $(TH invalid?))\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(PLUSMN)0.0) $(TD no) )\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)1.0) $(TD no))\n *      )\n */\nreal tanh(real x) @safe pure nothrow @nogc\n{\n    //  tanh(x) = (exp(x) - exp(-x))/(exp(x)+exp(-x))\n    if (fabs(x) > real.mant_dig * LN2)\n    {\n        return copysign(1, x);\n    }\n\n    const real y = expm1(2*x);\n    return y / (y + 2);\n}\n\n/// ditto\ndouble tanh(double x) @safe pure nothrow @nogc { return tanh(cast(real) x); }\n\n/// ditto\nfloat tanh(float x) @safe pure nothrow @nogc { return tanh(cast(real) x); }\n\n///\n@safe unittest\n{\n    assert(isIdentical(tanh(0.0), 0.0));\n    assert(tanh(1.0).approxEqual(sinh(1.0) / cosh(1.0)));\n}\n\n@safe @nogc nothrow unittest\n{\n    assert(equalsDigit(tanh(1.0), sinh(1.0) / cosh(1.0), 15));\n}\n\npackage:\n\n/* Returns cosh(x) + I * sinh(x)\n * Only one call to exp() is performed.\n */\ndeprecated(\"Use std.complex\")\nauto coshisinh(real x) @safe pure nothrow @nogc\n{\n    // See comments for cosh, sinh.\n    if (fabs(x) > real.mant_dig * LN2)\n    {\n        const real y = exp(fabs(x));\n        return y * 0.5 + 0.5i * copysign(y, x);\n    }\n    else\n    {\n        const real y = expm1(x);\n        return (y + 1.0 + 1.0/(y + 1.0)) * 0.5 + 0.5i * y / (y+1) * (y+2);\n    }\n}\n\ndeprecated\n@safe pure nothrow @nogc unittest\n{\n    creal c = coshisinh(3.0L);\n    assert(c.re == cosh(3.0L));\n    assert(c.im == sinh(3.0L));\n}\n\npublic:\n\n/***********************************\n * Calculates the inverse hyperbolic cosine of x.\n *\n *  Mathematically, acosh(x) = log(x + sqrt( x*x - 1))\n *\n * $(TABLE_DOMRG\n *    $(DOMAIN 1..$(INFIN)),\n *    $(RANGE  0..$(INFIN))\n * )\n *\n *  $(TABLE_SV\n *    $(SVH  x,     acosh(x) )\n *    $(SV  $(NAN), $(NAN) )\n *    $(SV  $(LT)1,     $(NAN) )\n *    $(SV  1,      0       )\n *    $(SV  +$(INFIN),+$(INFIN))\n *  )\n */\nreal acosh(real x) @safe pure nothrow @nogc\n{\n    if (x > 1/real.epsilon)\n        return LN2 + log(x);\n    else\n        return log(x + sqrt(x*x - 1));\n}\n\n/// ditto\ndouble acosh(double x) @safe pure nothrow @nogc { return acosh(cast(real) x); }\n\n/// ditto\nfloat acosh(float x) @safe pure nothrow @nogc  { return acosh(cast(real) x); }\n\n///\n@safe @nogc nothrow unittest\n{\n    assert(isNaN(acosh(0.9)));\n    assert(isNaN(acosh(real.nan)));\n    assert(isIdentical(acosh(1.0), 0.0));\n    assert(acosh(real.infinity) == real.infinity);\n    assert(isNaN(acosh(0.5)));\n}\n\n@safe @nogc nothrow unittest\n{\n    assert(equalsDigit(acosh(cosh(3.0)), 3, useDigits));\n}\n\n/***********************************\n * Calculates the inverse hyperbolic sine of x.\n *\n *  Mathematically,\n *  ---------------\n *  asinh(x) =  log( x + sqrt( x*x + 1 )) // if x >= +0\n *  asinh(x) = -log(-x + sqrt( x*x + 1 )) // if x <= -0\n *  -------------\n *\n *    $(TABLE_SV\n *    $(SVH x,                asinh(x)       )\n *    $(SV  $(NAN),           $(NAN)         )\n *    $(SV  $(PLUSMN)0,       $(PLUSMN)0      )\n *    $(SV  $(PLUSMN)$(INFIN),$(PLUSMN)$(INFIN))\n *    )\n */\nreal asinh(real x) @safe pure nothrow @nogc\n{\n    return (fabs(x) > 1 / real.epsilon)\n       // beyond this point, x*x + 1 == x*x\n       ?  copysign(LN2 + log(fabs(x)), x)\n       // sqrt(x*x + 1) ==  1 + x * x / ( 1 + sqrt(x*x + 1) )\n       : copysign(log1p(fabs(x) + x*x / (1 + sqrt(x*x + 1)) ), x);\n}\n\n/// ditto\ndouble asinh(double x) @safe pure nothrow @nogc { return asinh(cast(real) x); }\n\n/// ditto\nfloat asinh(float x) @safe pure nothrow @nogc { return asinh(cast(real) x); }\n\n///\n@safe @nogc nothrow unittest\n{\n    assert(isIdentical(asinh(0.0), 0.0));\n    assert(isIdentical(asinh(-0.0), -0.0));\n    assert(asinh(real.infinity) == real.infinity);\n    assert(asinh(-real.infinity) == -real.infinity);\n    assert(isNaN(asinh(real.nan)));\n}\n\n@safe unittest\n{\n    assert(equalsDigit(asinh(sinh(3.0)), 3, useDigits));\n}\n\n/***********************************\n * Calculates the inverse hyperbolic tangent of x,\n * returning a value from ranging from -1 to 1.\n *\n * Mathematically, atanh(x) = log( (1+x)/(1-x) ) / 2\n *\n * $(TABLE_DOMRG\n *    $(DOMAIN -$(INFIN)..$(INFIN)),\n *    $(RANGE  -1 .. 1)\n * )\n * $(BR)\n * $(TABLE_SV\n *    $(SVH  x,     acosh(x) )\n *    $(SV  $(NAN), $(NAN) )\n *    $(SV  $(PLUSMN)0, $(PLUSMN)0)\n *    $(SV  -$(INFIN), -0)\n * )\n */\nreal atanh(real x) @safe pure nothrow @nogc\n{\n    // log( (1+x)/(1-x) ) == log ( 1 + (2*x)/(1-x) )\n    return  0.5 * log1p( 2 * x / (1 - x) );\n}\n\n/// ditto\ndouble atanh(double x) @safe pure nothrow @nogc { return atanh(cast(real) x); }\n\n/// ditto\nfloat atanh(float x) @safe pure nothrow @nogc { return atanh(cast(real) x); }\n\n///\n@safe @nogc nothrow unittest\n{\n    assert(isIdentical(atanh(0.0), 0.0));\n    assert(isIdentical(atanh(-0.0),-0.0));\n    assert(isNaN(atanh(real.nan)));\n    assert(isNaN(atanh(-real.infinity)));\n    assert(atanh(0.0) == 0);\n}\n\n@safe unittest\n{\n    assert(equalsDigit(atanh(tanh(0.5L)), 0.5, useDigits));\n}\n\n/*****************************************\n * Returns x rounded to a long value using the current rounding mode.\n * If the integer value of x is\n * greater than long.max, the result is\n * indeterminate.\n */\nlong rndtol(real x) @nogc @safe pure nothrow { pragma(inline, true); return core.math.rndtol(x); }\n//FIXME\n///ditto\nlong rndtol(double x) @safe pure nothrow @nogc { return rndtol(cast(real) x); }\n//FIXME\n///ditto\nlong rndtol(float x) @safe pure nothrow @nogc { return rndtol(cast(real) x); }\n\n///\n@safe unittest\n{\n    assert(rndtol(1.0) == 1L);\n    assert(rndtol(1.2) == 1L);\n    assert(rndtol(1.7) == 2L);\n    assert(rndtol(1.0001) == 1L);\n}\n\n@safe unittest\n{\n    long function(real) prndtol = &rndtol;\n    assert(prndtol != null);\n}\n\n/**\n$(RED Deprecated. Please use $(LREF round) instead.)\n\nReturns `x` rounded to a `long` value using the `FE_TONEAREST` rounding mode.\nIf the integer value of `x` is greater than `long.max`, the result is\nindeterminate.\n\nOnly works with the Digital Mars C Runtime.\n\nParams:\n    x = the number to round\nReturns:\n    `x` rounded to an integer value\n */\ndeprecated(\"rndtonl is to be removed by 2.089. Please use round instead\")\nextern (C) real rndtonl(real x);\n\n///\ndeprecated @system unittest\n{\n    version (CRuntime_DigitalMars)\n    {\n        assert(rndtonl(1.0) is -real.nan);\n        assert(rndtonl(1.2) is -real.nan);\n        assert(rndtonl(1.7) is -real.nan);\n        assert(rndtonl(1.0001) is -real.nan);\n    }\n}\n\n/***************************************\n * Compute square root of x.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)         $(TH sqrt(x))   $(TH invalid?))\n *      $(TR $(TD -0.0)      $(TD -0.0)      $(TD no))\n *      $(TR $(TD $(LT)0.0)  $(TD $(NAN))    $(TD yes))\n *      $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no))\n *      )\n */\nfloat sqrt(float x) @nogc @safe pure nothrow { pragma(inline, true); return core.math.sqrt(x); }\n\n/// ditto\ndouble sqrt(double x) @nogc @safe pure nothrow { pragma(inline, true); return core.math.sqrt(x); }\n\n/// ditto\nreal sqrt(real x) @nogc @safe pure nothrow { pragma(inline, true); return core.math.sqrt(x); }\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(sqrt(2.0).feqrel(1.4142) > 16);\n    assert(sqrt(9.0).feqrel(3.0) > 16);\n\n    assert(isNaN(sqrt(-1.0f)));\n    assert(isNaN(sqrt(-1.0)));\n    assert(isNaN(sqrt(-1.0L)));\n}\n\n@safe unittest\n{\n    float function(float) psqrtf = &sqrt;\n    assert(psqrtf != null);\n    double function(double) psqrtd = &sqrt;\n    assert(psqrtd != null);\n    real function(real) psqrtr = &sqrt;\n    assert(psqrtr != null);\n\n    //ctfe\n    enum ZX80 = sqrt(7.0f);\n    enum ZX81 = sqrt(7.0);\n    enum ZX82 = sqrt(7.0L);\n}\n\ndeprecated(\"Use std.complex.sqrt\")\nauto sqrt(creal z) @nogc @safe pure nothrow\n{\n    creal c;\n    real x,y,w,r;\n\n    if (z == 0)\n    {\n        c = 0 + 0i;\n    }\n    else\n    {\n        const real z_re = z.re;\n        const real z_im = z.im;\n\n        x = fabs(z_re);\n        y = fabs(z_im);\n        if (x >= y)\n        {\n            r = y / x;\n            w = sqrt(x) * sqrt(0.5 * (1 + sqrt(1 + r * r)));\n        }\n        else\n        {\n            r = x / y;\n            w = sqrt(y) * sqrt(0.5 * (r + sqrt(1 + r * r)));\n        }\n\n        if (z_re >= 0)\n        {\n            c = w + (z_im / (w + w)) * 1.0i;\n        }\n        else\n        {\n            if (z_im < 0)\n                w = -w;\n            c = z_im / (w + w) + w * 1.0i;\n        }\n    }\n    return c;\n}\n\n/**\n * Calculates e$(SUPERSCRIPT x).\n *\n *  $(TABLE_SV\n *    $(TR $(TH x)             $(TH e$(SUPERSCRIPT x)) )\n *    $(TR $(TD +$(INFIN))     $(TD +$(INFIN)) )\n *    $(TR $(TD -$(INFIN))     $(TD +0.0)      )\n *    $(TR $(TD $(NAN))        $(TD $(NAN))    )\n *  )\n */\nreal exp(real x) @trusted pure nothrow @nogc // TODO: @safe\n{\n    version (D_InlineAsm_X86)\n    {\n        //  e^^x = 2^^(LOG2E*x)\n        // (This is valid because the overflow & underflow limits for exp\n        // and exp2 are so similar).\n        if (!__ctfe)\n            return exp2Asm(LOG2E*x);\n    }\n    else version (D_InlineAsm_X86_64)\n    {\n        //  e^^x = 2^^(LOG2E*x)\n        // (This is valid because the overflow & underflow limits for exp\n        // and exp2 are so similar).\n        if (!__ctfe)\n            return exp2Asm(LOG2E*x);\n    }\n    return expImpl(x);\n}\n\n/// ditto\ndouble exp(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) exp(cast(real) x) : expImpl(x); }\n\n/// ditto\nfloat exp(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) exp(cast(real) x) : expImpl(x); }\n\n///\n@safe unittest\n{\n    assert(exp(0.0) == 1.0);\n    assert(exp(3.0).feqrel(E * E * E) > 16);\n}\n\nprivate T expImpl(T)(T x) @safe pure nothrow @nogc\n{\n    alias F = floatTraits!T;\n    static if (F.realFormat == RealFormat.ieeeSingle)\n    {\n        static immutable T[6] P = [\n            5.0000001201E-1,\n            1.6666665459E-1,\n            4.1665795894E-2,\n            8.3334519073E-3,\n            1.3981999507E-3,\n            1.9875691500E-4,\n        ];\n\n        enum T C1 = 0.693359375;\n        enum T C2 = -2.12194440e-4;\n\n        // Overflow and Underflow limits.\n        enum T OF = 88.72283905206835;\n        enum T UF = -103.278929903431851103; // ln(2^-149)\n    }\n    else static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        // Coefficients for exp(x)\n        static immutable T[3] P = [\n            9.99999999999999999910E-1L,\n            3.02994407707441961300E-2L,\n            1.26177193074810590878E-4L,\n        ];\n        static immutable T[4] Q = [\n            2.00000000000000000009E0L,\n            2.27265548208155028766E-1L,\n            2.52448340349684104192E-3L,\n            3.00198505138664455042E-6L,\n        ];\n\n        // C1 + C2 = LN2.\n        enum T C1 = 6.93145751953125E-1;\n        enum T C2 = 1.42860682030941723212E-6;\n\n        // Overflow and Underflow limits.\n        enum T OF =  7.09782712893383996732E2;  // ln((1-2^-53) * 2^1024)\n        enum T UF = -7.451332191019412076235E2; // ln(2^-1075)\n    }\n    else static if (F.realFormat == RealFormat.ieeeExtended)\n    {\n        // Coefficients for exp(x)\n        static immutable T[3] P = [\n            9.9999999999999999991025E-1L,\n            3.0299440770744196129956E-2L,\n            1.2617719307481059087798E-4L,\n        ];\n        static immutable T[4] Q = [\n            2.0000000000000000000897E0L,\n            2.2726554820815502876593E-1L,\n            2.5244834034968410419224E-3L,\n            3.0019850513866445504159E-6L,\n        ];\n\n        // C1 + C2 = LN2.\n        enum T C1 = 6.9314575195312500000000E-1L;\n        enum T C2 = 1.4286068203094172321215E-6L;\n\n        // Overflow and Underflow limits.\n        enum T OF =  1.1356523406294143949492E4L;  // ln((1-2^-64) * 2^16384)\n        enum T UF = -1.13994985314888605586758E4L; // ln(2^-16446)\n    }\n    else static if (F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        // Coefficients for exp(x) - 1\n        static immutable T[5] P = [\n            9.999999999999999999999999999999999998502E-1L,\n            3.508710990737834361215404761139478627390E-2L,\n            2.708775201978218837374512615596512792224E-4L,\n            6.141506007208645008909088812338454698548E-7L,\n            3.279723985560247033712687707263393506266E-10L\n        ];\n        static immutable T[6] Q = [\n            2.000000000000000000000000000000000000150E0,\n            2.368408864814233538909747618894558968880E-1L,\n            3.611828913847589925056132680618007270344E-3L,\n            1.504792651814944826817779302637284053660E-5L,\n            1.771372078166251484503904874657985291164E-8L,\n            2.980756652081995192255342779918052538681E-12L\n        ];\n\n        // C1 + C2 = LN2.\n        enum T C1 = 6.93145751953125E-1L;\n        enum T C2 = 1.428606820309417232121458176568075500134E-6L;\n\n        // Overflow and Underflow limits.\n        enum T OF =  1.135583025911358400418251384584930671458833e4L;\n        enum T UF = -1.143276959615573793352782661133116431383730e4L;\n    }\n    else\n        static assert(0, \"Not implemented for this architecture\");\n\n    // Special cases.\n    if (isNaN(x))\n        return x;\n    if (x > OF)\n        return real.infinity;\n    if (x < UF)\n        return 0.0;\n\n    // Express: e^^x = e^^g * 2^^n\n    //   = e^^g * e^^(n * LOG2E)\n    //   = e^^(g + n * LOG2E)\n    T xx = floor((cast(T) LOG2E) * x + cast(T) 0.5);\n    const int n = cast(int) xx;\n    x -= xx * C1;\n    x -= xx * C2;\n\n    static if (F.realFormat == RealFormat.ieeeSingle)\n    {\n        xx = x * x;\n        x = poly(x, P) * xx + x + 1.0f;\n    }\n    else\n    {\n        // Rational approximation for exponential of the fractional part:\n        //  e^^x = 1 + 2x P(x^^2) / (Q(x^^2) - P(x^^2))\n        xx = x * x;\n        const T px = x * poly(xx, P);\n        x = px / (poly(xx, Q) - px);\n        x = (cast(T) 1.0) + (cast(T) 2.0) * x;\n    }\n\n    // Scale by power of 2.\n    x = ldexp(x, n);\n\n    return x;\n}\n\n@safe @nogc nothrow unittest\n{\n    FloatingPointControl ctrl;\n    if (FloatingPointControl.hasExceptionTraps)\n        ctrl.disableExceptions(FloatingPointControl.allExceptions);\n    ctrl.rounding = FloatingPointControl.roundToNearest;\n\n    static void testExp(T)()\n    {\n        enum realFormat = floatTraits!T.realFormat;\n        static if (realFormat == RealFormat.ieeeQuadruple)\n        {\n            static immutable T[2][] exptestpoints =\n            [ //  x               exp(x)\n                [ 1.0L,           E                                        ],\n                [ 0.5L,           0x1.a61298e1e069bc972dfefab6df34p+0L     ],\n                [ 3.0L,           E*E*E                                    ],\n                [ 0x1.6p+13L,     0x1.6e509d45728655cdb4840542acb5p+16250L ], // near overflow\n                [ 0x1.7p+13L,     T.infinity                               ], // close overflow\n                [ 0x1p+80L,       T.infinity                               ], // far overflow\n                [ T.infinity,     T.infinity                               ],\n                [-0x1.18p+13L,    0x1.5e4bf54b4807034ea97fef0059a6p-12927L ], // near underflow\n                [-0x1.625p+13L,   0x1.a6bd68a39d11fec3a250cd97f524p-16358L ], // ditto\n                [-0x1.62dafp+13L, 0x0.cb629e9813b80ed4d639e875be6cp-16382L ], // near underflow - subnormal\n                [-0x1.6549p+13L,  0x0.0000000000000000000000000001p-16382L ], // ditto\n                [-0x1.655p+13L,   0                                        ], // close underflow\n                [-0x1p+30L,       0                                        ], // far underflow\n            ];\n        }\n        else static if (realFormat == RealFormat.ieeeExtended)\n        {\n            static immutable T[2][] exptestpoints =\n            [ //  x               exp(x)\n                [ 1.0L,           E                            ],\n                [ 0.5L,           0x1.a61298e1e069bc97p+0L     ],\n                [ 3.0L,           E*E*E                        ],\n                [ 0x1.1p+13L,     0x1.29aeffefc8ec645p+12557L  ], // near overflow\n                [ 0x1.7p+13L,     T.infinity                   ], // close overflow\n                [ 0x1p+80L,       T.infinity                   ], // far overflow\n                [ T.infinity,     T.infinity                   ],\n                [-0x1.18p+13L,    0x1.5e4bf54b4806db9p-12927L  ], // near underflow\n                [-0x1.625p+13L,   0x1.a6bd68a39d11f35cp-16358L ], // ditto\n                [-0x1.62dafp+13L, 0x1.96c53d30277021dp-16383L  ], // near underflow - subnormal\n                [-0x1.643p+13L,   0x1p-16444L                  ], // ditto\n                [-0x1.645p+13L,   0                            ], // close underflow\n                [-0x1p+30L,       0                            ], // far underflow\n            ];\n        }\n        else static if (realFormat == RealFormat.ieeeDouble)\n        {\n            static immutable T[2][] exptestpoints =\n            [ //  x,             exp(x)\n                [ 1.0L,          E                        ],\n                [ 0.5L,          0x1.a61298e1e069cp+0L    ],\n                [ 3.0L,          E*E*E                    ],\n                [ 0x1.6p+9L,     0x1.93bf4ec282efbp+1015L ], // near overflow\n                [ 0x1.7p+9L,     T.infinity               ], // close overflow\n                [ 0x1p+80L,      T.infinity               ], // far overflow\n                [ T.infinity,    T.infinity               ],\n                [-0x1.6p+9L,     0x1.44a3824e5285fp-1016L ], // near underflow\n                [-0x1.64p+9L,    0x0.06f84920bb2d4p-1022L ], // near underflow - subnormal\n                [-0x1.743p+9L,   0x0.0000000000001p-1022L ], // ditto\n                [-0x1.8p+9L,     0                        ], // close underflow\n                [-0x1p+30L,      0                        ], // far underflow\n            ];\n        }\n        else static if (realFormat == RealFormat.ieeeSingle)\n        {\n            static immutable T[2][] exptestpoints =\n            [ //  x,             exp(x)\n                [ 1.0L,          E                ],\n                [ 0.5L,          0x1.a61299p+0L   ],\n                [ 3.0L,          E*E*E            ],\n                [ 0x1.62p+6L,    0x1.99b988p+127L ], // near overflow\n                [ 0x1.7p+6L,     T.infinity       ], // close overflow\n                [ 0x1p+80L,      T.infinity       ], // far overflow\n                [ T.infinity,    T.infinity       ],\n                [-0x1.5cp+6L,    0x1.666d0ep-126L ], // near underflow\n                [-0x1.7p+6L,     0x0.026a42p-126L ], // near underflow - subnormal\n                [-0x1.9cp+6L,    0x0.000002p-126L ], // ditto\n                [-0x1.ap+6L,     0                ], // close underflow\n                [-0x1p+30L,      0                ], // far underflow\n            ];\n        }\n        else\n            static assert(0, \"No exp() tests for real type!\");\n\n        const minEqualMantissaBits = T.mant_dig - 13;\n        T x;\n        IeeeFlags f;\n        foreach (ref pair; exptestpoints)\n        {\n            resetIeeeFlags();\n            x = exp(pair[0]);\n            //printf(\"exp(%La) = %La, should be %La\\n\", cast(real) pair[0], cast(real) x, cast(real) pair[1]);\n            assert(feqrel(x, pair[1]) >= minEqualMantissaBits);\n        }\n\n        // Ideally, exp(0) would not set the inexact flag.\n        // Unfortunately, fldl2e sets it!\n        // So it's not realistic to avoid setting it.\n        assert(exp(cast(T) 0.0) == 1.0);\n\n        // NaN propagation. Doesn't set flags, bcos was already NaN.\n        resetIeeeFlags();\n        x = exp(T.nan);\n        f = ieeeFlags;\n        assert(isIdentical(abs(x), T.nan));\n        assert(f.flags == 0);\n\n        resetIeeeFlags();\n        x = exp(-T.nan);\n        f = ieeeFlags;\n        assert(isIdentical(abs(x), T.nan));\n        assert(f.flags == 0);\n\n        x = exp(NaN(0x123));\n        assert(isIdentical(x, NaN(0x123)));\n    }\n\n    import std.meta : AliasSeq;\n    foreach (T; AliasSeq!(real, double, float))\n        testExp!T();\n\n    // High resolution test (verified against GNU MPFR/Mathematica).\n    assert(exp(0.5L) == 0x1.A612_98E1_E069_BC97_2DFE_FAB6_DF34p+0L);\n\n    assert(equalsDigit(exp(3.0L), E * E * E, useDigits));\n}\n\n/**\n * Calculates the value of the natural logarithm base (e)\n * raised to the power of x, minus 1.\n *\n * For very small x, expm1(x) is more accurate\n * than exp(x)-1.\n *\n *  $(TABLE_SV\n *    $(TR $(TH x)             $(TH e$(SUPERSCRIPT x)-1)  )\n *    $(TR $(TD $(PLUSMN)0.0)  $(TD $(PLUSMN)0.0) )\n *    $(TR $(TD +$(INFIN))     $(TD +$(INFIN))    )\n *    $(TR $(TD -$(INFIN))     $(TD -1.0)         )\n *    $(TR $(TD $(NAN))        $(TD $(NAN))       )\n *  )\n */\nreal expm1(real x) @trusted pure nothrow @nogc // TODO: @safe\n{\n    version (InlineAsm_X86_Any)\n    {\n        if (!__ctfe)\n            return expm1Asm(x);\n    }\n    return expm1Impl(x);\n}\n\n/// ditto\ndouble expm1(double x) @safe pure nothrow @nogc\n{\n    return __ctfe ? cast(double) expm1(cast(real) x) : expm1Impl(x);\n}\n\n/// ditto\nfloat expm1(float x) @safe pure nothrow @nogc\n{\n    // no single-precision version in Cephes => use double precision\n    return __ctfe ? cast(float) expm1(cast(real) x) : cast(float) expm1Impl(cast(double) x);\n}\n\n///\n@safe unittest\n{\n    assert(isIdentical(expm1(0.0), 0.0));\n    assert(expm1(1.0).feqrel(1.71828) > 16);\n    assert(expm1(2.0).feqrel(6.3890) > 16);\n}\n\nversion (InlineAsm_X86_Any)\nprivate real expm1Asm(real x) @trusted pure nothrow @nogc\n{\n    version (D_InlineAsm_X86)\n    {\n        enum PARAMSIZE = (real.sizeof+3)&(0xFFFF_FFFC); // always a multiple of 4\n        asm pure nothrow @nogc\n        {\n            /*  expm1() for x87 80-bit reals, IEEE754-2008 conformant.\n             * Author: Don Clugston.\n             *\n             *    expm1(x) = 2^^(rndint(y))* 2^^(y-rndint(y)) - 1 where y = LN2*x.\n             *    = 2rndy * 2ym1 + 2rndy - 1, where 2rndy = 2^^(rndint(y))\n             *     and 2ym1 = (2^^(y-rndint(y))-1).\n             *    If 2rndy  < 0.5*real.epsilon, result is -1.\n             *    Implementation is otherwise the same as for exp2()\n             */\n            naked;\n            fld real ptr [ESP+4] ; // x\n            mov AX, [ESP+4+8]; // AX = exponent and sign\n            sub ESP, 12+8; // Create scratch space on the stack\n            // [ESP,ESP+2] = scratchint\n            // [ESP+4..+6, +8..+10, +10] = scratchreal\n            // set scratchreal mantissa = 1.0\n            mov dword ptr [ESP+8], 0;\n            mov dword ptr [ESP+8+4], 0x80000000;\n            and AX, 0x7FFF; // drop sign bit\n            cmp AX, 0x401D; // avoid InvalidException in fist\n            jae L_extreme;\n            fldl2e;\n            fmulp ST(1), ST; // y = x*log2(e)\n            fist dword ptr [ESP]; // scratchint = rndint(y)\n            fisub dword ptr [ESP]; // y - rndint(y)\n            // and now set scratchreal exponent\n            mov EAX, [ESP];\n            add EAX, 0x3fff;\n            jle short L_largenegative;\n            cmp EAX,0x8000;\n            jge short L_largepositive;\n            mov [ESP+8+8],AX;\n            f2xm1; // 2ym1 = 2^^(y-rndint(y)) -1\n            fld real ptr [ESP+8] ; // 2rndy = 2^^rndint(y)\n            fmul ST(1), ST;  // ST=2rndy, ST(1)=2rndy*2ym1\n            fld1;\n            fsubp ST(1), ST; // ST = 2rndy-1, ST(1) = 2rndy * 2ym1 - 1\n            faddp ST(1), ST; // ST = 2rndy * 2ym1 + 2rndy - 1\n            add ESP,12+8;\n            ret PARAMSIZE;\n\nL_extreme:  // Extreme exponent. X is very large positive, very\n            // large negative, infinity, or NaN.\n            fxam;\n            fstsw AX;\n            test AX, 0x0400; // NaN_or_zero, but we already know x != 0\n            jz L_was_nan;  // if x is NaN, returns x\n            test AX, 0x0200;\n            jnz L_largenegative;\nL_largepositive:\n            // Set scratchreal = real.max.\n            // squaring it will create infinity, and set overflow flag.\n            mov word  ptr [ESP+8+8], 0x7FFE;\n            fstp ST(0);\n            fld real ptr [ESP+8];  // load scratchreal\n            fmul ST(0), ST;        // square it, to create havoc!\nL_was_nan:\n            add ESP,12+8;\n            ret PARAMSIZE;\nL_largenegative:\n            fstp ST(0);\n            fld1;\n            fchs; // return -1. Underflow flag is not set.\n            add ESP,12+8;\n            ret PARAMSIZE;\n        }\n    }\n    else version (D_InlineAsm_X86_64)\n    {\n        asm pure nothrow @nogc\n        {\n            naked;\n        }\n        version (Win64)\n        {\n            asm pure nothrow @nogc\n            {\n                fld   real ptr [RCX];  // x\n                mov   AX,[RCX+8];      // AX = exponent and sign\n            }\n        }\n        else\n        {\n            asm pure nothrow @nogc\n            {\n                fld   real ptr [RSP+8];  // x\n                mov   AX,[RSP+8+8];      // AX = exponent and sign\n            }\n        }\n        asm pure nothrow @nogc\n        {\n            /*  expm1() for x87 80-bit reals, IEEE754-2008 conformant.\n             * Author: Don Clugston.\n             *\n             *    expm1(x) = 2^(rndint(y))* 2^(y-rndint(y)) - 1 where y = LN2*x.\n             *    = 2rndy * 2ym1 + 2rndy - 1, where 2rndy = 2^(rndint(y))\n             *     and 2ym1 = (2^(y-rndint(y))-1).\n             *    If 2rndy  < 0.5*real.epsilon, result is -1.\n             *    Implementation is otherwise the same as for exp2()\n             */\n            sub RSP, 24;       // Create scratch space on the stack\n            // [RSP,RSP+2] = scratchint\n            // [RSP+4..+6, +8..+10, +10] = scratchreal\n            // set scratchreal mantissa = 1.0\n            mov dword ptr [RSP+8], 0;\n            mov dword ptr [RSP+8+4], 0x80000000;\n            and AX, 0x7FFF; // drop sign bit\n            cmp AX, 0x401D; // avoid InvalidException in fist\n            jae L_extreme;\n            fldl2e;\n            fmul ; // y = x*log2(e)\n            fist dword ptr [RSP]; // scratchint = rndint(y)\n            fisub dword ptr [RSP]; // y - rndint(y)\n            // and now set scratchreal exponent\n            mov EAX, [RSP];\n            add EAX, 0x3fff;\n            jle short L_largenegative;\n            cmp EAX,0x8000;\n            jge short L_largepositive;\n            mov [RSP+8+8],AX;\n            f2xm1; // 2^(y-rndint(y)) -1\n            fld real ptr [RSP+8] ; // 2^rndint(y)\n            fmul ST(1), ST;\n            fld1;\n            fsubp ST(1), ST;\n            fadd;\n            add RSP,24;\n            ret;\n\nL_extreme:  // Extreme exponent. X is very large positive, very\n            // large negative, infinity, or NaN.\n            fxam;\n            fstsw AX;\n            test AX, 0x0400; // NaN_or_zero, but we already know x != 0\n            jz L_was_nan;  // if x is NaN, returns x\n            test AX, 0x0200;\n            jnz L_largenegative;\nL_largepositive:\n            // Set scratchreal = real.max.\n            // squaring it will create infinity, and set overflow flag.\n            mov word  ptr [RSP+8+8], 0x7FFE;\n            fstp ST(0);\n            fld real ptr [RSP+8];  // load scratchreal\n            fmul ST(0), ST;        // square it, to create havoc!\nL_was_nan:\n            add RSP,24;\n            ret;\n\nL_largenegative:\n            fstp ST(0);\n            fld1;\n            fchs; // return -1. Underflow flag is not set.\n            add RSP,24;\n            ret;\n        }\n    }\n    else\n        static assert(0);\n}\n\nprivate T expm1Impl(T)(T x) @safe pure nothrow @nogc\n{\n    // Coefficients for exp(x) - 1 and overflow/underflow limits.\n    enum realFormat = floatTraits!T.realFormat;\n    static if (realFormat == RealFormat.ieeeQuadruple)\n    {\n        static immutable T[8] P = [\n            2.943520915569954073888921213330863757240E8L,\n            -5.722847283900608941516165725053359168840E7L,\n            8.944630806357575461578107295909719817253E6L,\n            -7.212432713558031519943281748462837065308E5L,\n            4.578962475841642634225390068461943438441E4L,\n            -1.716772506388927649032068540558788106762E3L,\n            4.401308817383362136048032038528753151144E1L,\n            -4.888737542888633647784737721812546636240E-1L\n        ];\n\n        static immutable T[9] Q = [\n            1.766112549341972444333352727998584753865E9L,\n            -7.848989743695296475743081255027098295771E8L,\n            1.615869009634292424463780387327037251069E8L,\n            -2.019684072836541751428967854947019415698E7L,\n            1.682912729190313538934190635536631941751E6L,\n            -9.615511549171441430850103489315371768998E4L,\n            3.697714952261803935521187272204485251835E3L,\n            -8.802340681794263968892934703309274564037E1L,\n            1.0\n        ];\n\n        enum T OF = 1.1356523406294143949491931077970764891253E4L;\n        enum T UF = -1.143276959615573793352782661133116431383730e4L;\n    }\n    else static if (realFormat == RealFormat.ieeeExtended)\n    {\n        static immutable T[5] P = [\n           -1.586135578666346600772998894928250240826E4L,\n            2.642771505685952966904660652518429479531E3L,\n           -3.423199068835684263987132888286791620673E2L,\n            1.800826371455042224581246202420972737840E1L,\n           -5.238523121205561042771939008061958820811E-1L,\n        ];\n        static immutable T[6] Q = [\n           -9.516813471998079611319047060563358064497E4L,\n            3.964866271411091674556850458227710004570E4L,\n           -7.207678383830091850230366618190187434796E3L,\n            7.206038318724600171970199625081491823079E2L,\n           -4.002027679107076077238836622982900945173E1L,\n            1.0\n        ];\n\n        enum T OF =  1.1356523406294143949492E4L;\n        enum T UF = -4.5054566736396445112120088E1L;\n    }\n    else static if (realFormat == RealFormat.ieeeDouble)\n    {\n        static immutable T[3] P = [\n            9.9999999999999999991025E-1,\n            3.0299440770744196129956E-2,\n            1.2617719307481059087798E-4,\n        ];\n        static immutable T[4] Q = [\n            2.0000000000000000000897E0,\n            2.2726554820815502876593E-1,\n            2.5244834034968410419224E-3,\n            3.0019850513866445504159E-6,\n        ];\n    }\n    else\n        static assert(0, \"no coefficients for expm1()\");\n\n    static if (realFormat == RealFormat.ieeeDouble) // special case for double precision\n    {\n        if (x < -0.5 || x > 0.5)\n            return exp(x) - 1.0;\n        if (x == 0.0)\n            return x;\n\n        const T xx = x * x;\n        x = x * poly(xx, P);\n        x = x / (poly(xx, Q) - x);\n        return x + x;\n    }\n    else\n    {\n        // C1 + C2 = LN2.\n        enum T C1 = 6.9314575195312500000000E-1L;\n        enum T C2 = 1.428606820309417232121458176568075500134E-6L;\n\n        // Special cases.\n        if (x > OF)\n            return real.infinity;\n        if (x == cast(T) 0.0)\n            return x;\n        if (x < UF)\n            return -1.0;\n\n        // Express x = LN2 (n + remainder), remainder not exceeding 1/2.\n        int n = cast(int) floor((cast(T) 0.5) + x / cast(T) LN2);\n        x -= n * C1;\n        x -= n * C2;\n\n        // Rational approximation:\n        //  exp(x) - 1 = x + 0.5 x^^2 + x^^3 P(x) / Q(x)\n        T px = x * poly(x, P);\n        T qx = poly(x, Q);\n        const T xx = x * x;\n        qx = x + ((cast(T) 0.5) * xx + xx * px / qx);\n\n        // We have qx = exp(remainder LN2) - 1, so:\n        //  exp(x) - 1 = 2^^n (qx + 1) - 1 = 2^^n qx + 2^^n - 1.\n        px = ldexp(cast(T) 1.0, n);\n        x = px * qx + (px - cast(T) 1.0);\n\n        return x;\n    }\n}\n\n@safe @nogc nothrow unittest\n{\n    static void testExpm1(T)()\n    {\n        // NaN\n        assert(isNaN(expm1(cast(T) T.nan)));\n\n        static immutable T[] xs = [ -2, -0.75, -0.3, 0.0, 0.1, 0.2, 0.5, 1.0 ];\n        foreach (x; xs)\n        {\n            const T e = expm1(x);\n            const T r = exp(x) - 1;\n\n            //printf(\"expm1(%Lg) = %Lg, should approximately be %Lg\\n\", cast(real) x, cast(real) e, cast(real) r);\n            assert(approxEqual(r, e));\n        }\n    }\n\n    import std.meta : AliasSeq;\n    foreach (T; AliasSeq!(real, double))\n        testExpm1!T();\n}\n\n/**\n * Calculates 2$(SUPERSCRIPT x).\n *\n *  $(TABLE_SV\n *    $(TR $(TH x)             $(TH exp2(x))   )\n *    $(TR $(TD +$(INFIN))     $(TD +$(INFIN)) )\n *    $(TR $(TD -$(INFIN))     $(TD +0.0)      )\n *    $(TR $(TD $(NAN))        $(TD $(NAN))    )\n *  )\n */\nreal exp2(real x) @nogc @trusted pure nothrow // TODO: @safe\n{\n    version (InlineAsm_X86_Any)\n    {\n        if (!__ctfe)\n            return exp2Asm(x);\n    }\n    return exp2Impl(x);\n}\n\n/// ditto\ndouble exp2(double x) @nogc @safe pure nothrow { return __ctfe ? cast(double) exp2(cast(real) x) : exp2Impl(x); }\n\n/// ditto\nfloat exp2(float x) @nogc @safe pure nothrow { return __ctfe ? cast(float) exp2(cast(real) x) : exp2Impl(x); }\n\n///\n@safe unittest\n{\n    assert(isIdentical(exp2(0.0), 1.0));\n    assert(exp2(2.0).feqrel(4.0) > 16);\n    assert(exp2(8.0).feqrel(256.0) > 16);\n}\n\n@safe unittest\n{\n    version (CRuntime_Microsoft) {} else // aexp2/exp2f/exp2l not implemented\n    {\n        assert( core.stdc.math.exp2f(0.0f) == 1 );\n        assert( core.stdc.math.exp2 (0.0)  == 1 );\n        assert( core.stdc.math.exp2l(0.0L) == 1 );\n    }\n}\n\nversion (InlineAsm_X86_Any)\nprivate real exp2Asm(real x) @nogc @trusted pure nothrow\n{\n    version (D_InlineAsm_X86)\n    {\n        enum PARAMSIZE = (real.sizeof+3)&(0xFFFF_FFFC); // always a multiple of 4\n\n        asm pure nothrow @nogc\n        {\n            /*  exp2() for x87 80-bit reals, IEEE754-2008 conformant.\n             * Author: Don Clugston.\n             *\n             * exp2(x) = 2^^(rndint(x))* 2^^(y-rndint(x))\n             * The trick for high performance is to avoid the fscale(28cycles on core2),\n             * frndint(19 cycles), leaving f2xm1(19 cycles) as the only slow instruction.\n             *\n             * We can do frndint by using fist. BUT we can't use it for huge numbers,\n             * because it will set the Invalid Operation flag if overflow or NaN occurs.\n             * Fortunately, whenever this happens the result would be zero or infinity.\n             *\n             * We can perform fscale by directly poking into the exponent. BUT this doesn't\n             * work for the (very rare) cases where the result is subnormal. So we fall back\n             * to the slow method in that case.\n             */\n            naked;\n            fld real ptr [ESP+4] ; // x\n            mov AX, [ESP+4+8]; // AX = exponent and sign\n            sub ESP, 12+8; // Create scratch space on the stack\n            // [ESP,ESP+2] = scratchint\n            // [ESP+4..+6, +8..+10, +10] = scratchreal\n            // set scratchreal mantissa = 1.0\n            mov dword ptr [ESP+8], 0;\n            mov dword ptr [ESP+8+4], 0x80000000;\n            and AX, 0x7FFF; // drop sign bit\n            cmp AX, 0x401D; // avoid InvalidException in fist\n            jae L_extreme;\n            fist dword ptr [ESP]; // scratchint = rndint(x)\n            fisub dword ptr [ESP]; // x - rndint(x)\n            // and now set scratchreal exponent\n            mov EAX, [ESP];\n            add EAX, 0x3fff;\n            jle short L_subnormal;\n            cmp EAX,0x8000;\n            jge short L_overflow;\n            mov [ESP+8+8],AX;\nL_normal:\n            f2xm1;\n            fld1;\n            faddp ST(1), ST; // 2^^(x-rndint(x))\n            fld real ptr [ESP+8] ; // 2^^rndint(x)\n            add ESP,12+8;\n            fmulp ST(1), ST;\n            ret PARAMSIZE;\n\nL_subnormal:\n            // Result will be subnormal.\n            // In this rare case, the simple poking method doesn't work.\n            // The speed doesn't matter, so use the slow fscale method.\n            fild dword ptr [ESP];  // scratchint\n            fld1;\n            fscale;\n            fstp real ptr [ESP+8]; // scratchreal = 2^^scratchint\n            fstp ST(0);         // drop scratchint\n            jmp L_normal;\n\nL_extreme:  // Extreme exponent. X is very large positive, very\n            // large negative, infinity, or NaN.\n            fxam;\n            fstsw AX;\n            test AX, 0x0400; // NaN_or_zero, but we already know x != 0\n            jz L_was_nan;  // if x is NaN, returns x\n            // set scratchreal = real.min_normal\n            // squaring it will return 0, setting underflow flag\n            mov word  ptr [ESP+8+8], 1;\n            test AX, 0x0200;\n            jnz L_waslargenegative;\nL_overflow:\n            // Set scratchreal = real.max.\n            // squaring it will create infinity, and set overflow flag.\n            mov word  ptr [ESP+8+8], 0x7FFE;\nL_waslargenegative:\n            fstp ST(0);\n            fld real ptr [ESP+8];  // load scratchreal\n            fmul ST(0), ST;        // square it, to create havoc!\nL_was_nan:\n            add ESP,12+8;\n            ret PARAMSIZE;\n        }\n    }\n    else version (D_InlineAsm_X86_64)\n    {\n        asm pure nothrow @nogc\n        {\n            naked;\n        }\n        version (Win64)\n        {\n            asm pure nothrow @nogc\n            {\n                fld   real ptr [RCX];  // x\n                mov   AX,[RCX+8];      // AX = exponent and sign\n            }\n        }\n        else\n        {\n            asm pure nothrow @nogc\n            {\n                fld   real ptr [RSP+8];  // x\n                mov   AX,[RSP+8+8];      // AX = exponent and sign\n            }\n        }\n        asm pure nothrow @nogc\n        {\n            /*  exp2() for x87 80-bit reals, IEEE754-2008 conformant.\n             * Author: Don Clugston.\n             *\n             * exp2(x) = 2^(rndint(x))* 2^(y-rndint(x))\n             * The trick for high performance is to avoid the fscale(28cycles on core2),\n             * frndint(19 cycles), leaving f2xm1(19 cycles) as the only slow instruction.\n             *\n             * We can do frndint by using fist. BUT we can't use it for huge numbers,\n             * because it will set the Invalid Operation flag is overflow or NaN occurs.\n             * Fortunately, whenever this happens the result would be zero or infinity.\n             *\n             * We can perform fscale by directly poking into the exponent. BUT this doesn't\n             * work for the (very rare) cases where the result is subnormal. So we fall back\n             * to the slow method in that case.\n             */\n            sub RSP, 24; // Create scratch space on the stack\n            // [RSP,RSP+2] = scratchint\n            // [RSP+4..+6, +8..+10, +10] = scratchreal\n            // set scratchreal mantissa = 1.0\n            mov dword ptr [RSP+8], 0;\n            mov dword ptr [RSP+8+4], 0x80000000;\n            and AX, 0x7FFF; // drop sign bit\n            cmp AX, 0x401D; // avoid InvalidException in fist\n            jae L_extreme;\n            fist dword ptr [RSP]; // scratchint = rndint(x)\n            fisub dword ptr [RSP]; // x - rndint(x)\n            // and now set scratchreal exponent\n            mov EAX, [RSP];\n            add EAX, 0x3fff;\n            jle short L_subnormal;\n            cmp EAX,0x8000;\n            jge short L_overflow;\n            mov [RSP+8+8],AX;\nL_normal:\n            f2xm1;\n            fld1;\n            fadd; // 2^(x-rndint(x))\n            fld real ptr [RSP+8] ; // 2^rndint(x)\n            add RSP,24;\n            fmulp ST(1), ST;\n            ret;\n\nL_subnormal:\n            // Result will be subnormal.\n            // In this rare case, the simple poking method doesn't work.\n            // The speed doesn't matter, so use the slow fscale method.\n            fild dword ptr [RSP];  // scratchint\n            fld1;\n            fscale;\n            fstp real ptr [RSP+8]; // scratchreal = 2^scratchint\n            fstp ST(0);         // drop scratchint\n            jmp L_normal;\n\nL_extreme:  // Extreme exponent. X is very large positive, very\n            // large negative, infinity, or NaN.\n            fxam;\n            fstsw AX;\n            test AX, 0x0400; // NaN_or_zero, but we already know x != 0\n            jz L_was_nan;  // if x is NaN, returns x\n            // set scratchreal = real.min\n            // squaring it will return 0, setting underflow flag\n            mov word  ptr [RSP+8+8], 1;\n            test AX, 0x0200;\n            jnz L_waslargenegative;\nL_overflow:\n            // Set scratchreal = real.max.\n            // squaring it will create infinity, and set overflow flag.\n            mov word  ptr [RSP+8+8], 0x7FFE;\nL_waslargenegative:\n            fstp ST(0);\n            fld real ptr [RSP+8];  // load scratchreal\n            fmul ST(0), ST;        // square it, to create havoc!\nL_was_nan:\n            add RSP,24;\n            ret;\n        }\n    }\n    else\n        static assert(0);\n}\n\nprivate T exp2Impl(T)(T x) @nogc @safe pure nothrow\n{\n    // Coefficients for exp2(x)\n    enum realFormat = floatTraits!T.realFormat;\n    static if (realFormat == RealFormat.ieeeQuadruple)\n    {\n        static immutable T[5] P = [\n            9.079594442980146270952372234833529694788E12L,\n            1.530625323728429161131811299626419117557E11L,\n            5.677513871931844661829755443994214173883E8L,\n            6.185032670011643762127954396427045467506E5L,\n            1.587171580015525194694938306936721666031E2L\n        ];\n\n        static immutable T[6] Q = [\n            2.619817175234089411411070339065679229869E13L,\n            1.490560994263653042761789432690793026977E12L,\n            1.092141473886177435056423606755843616331E10L,\n            2.186249607051644894762167991800811827835E7L,\n            1.236602014442099053716561665053645270207E4L,\n            1.0\n        ];\n    }\n    else static if (realFormat == RealFormat.ieeeExtended)\n    {\n        static immutable T[3] P = [\n            2.0803843631901852422887E6L,\n            3.0286971917562792508623E4L,\n            6.0614853552242266094567E1L,\n        ];\n        static immutable T[4] Q = [\n            6.0027204078348487957118E6L,\n            3.2772515434906797273099E5L,\n            1.7492876999891839021063E3L,\n            1.0000000000000000000000E0L,\n        ];\n    }\n    else static if (realFormat == RealFormat.ieeeDouble)\n    {\n        static immutable T[3] P = [\n            1.51390680115615096133E3L,\n            2.02020656693165307700E1L,\n            2.30933477057345225087E-2L,\n        ];\n        static immutable T[3] Q = [\n            4.36821166879210612817E3L,\n            2.33184211722314911771E2L,\n            1.00000000000000000000E0L,\n        ];\n    }\n    else static if (realFormat == RealFormat.ieeeSingle)\n    {\n        static immutable T[6] P = [\n            6.931472028550421E-001L,\n            2.402264791363012E-001L,\n            5.550332471162809E-002L,\n            9.618437357674640E-003L,\n            1.339887440266574E-003L,\n            1.535336188319500E-004L,\n        ];\n    }\n    else\n        static assert(0, \"no coefficients for exp2()\");\n\n    // Overflow and Underflow limits.\n    enum T OF = T.max_exp;\n    enum T UF = T.min_exp - 1;\n\n    // Special cases.\n    if (isNaN(x))\n        return x;\n    if (x > OF)\n        return real.infinity;\n    if (x < UF)\n        return 0.0;\n\n    static if (realFormat == RealFormat.ieeeSingle) // special case for single precision\n    {\n        // The following is necessary because range reduction blows up.\n        if (x == 0.0f)\n            return 1.0f;\n\n        // Separate into integer and fractional parts.\n        const T i = floor(x);\n        int n = cast(int) i;\n        x -= i;\n        if (x > 0.5f)\n        {\n            n += 1;\n            x -= 1.0f;\n        }\n\n        // Rational approximation:\n        //  exp2(x) = 1.0 + x P(x)\n        x = 1.0f + x * poly(x, P);\n    }\n    else\n    {\n        // Separate into integer and fractional parts.\n        const T i = floor(x + cast(T) 0.5);\n        int n = cast(int) i;\n        x -= i;\n\n        // Rational approximation:\n        //  exp2(x) = 1.0 + 2x P(x^^2) / (Q(x^^2) - P(x^^2))\n        const T xx = x * x;\n        const T px = x * poly(xx, P);\n        x = px / (poly(xx, Q) - px);\n        x = (cast(T) 1.0) + (cast(T) 2.0) * x;\n    }\n\n    // Scale by power of 2.\n    x = ldexp(x, n);\n\n    return x;\n}\n\n@safe @nogc nothrow unittest\n{\n    assert(feqrel(exp2(0.5L), SQRT2) >= real.mant_dig -1);\n    assert(exp2(8.0L) == 256.0);\n    assert(exp2(-9.0L)== 1.0L/512.0);\n\n    static void testExp2(T)()\n    {\n        // NaN\n        const T specialNaN = NaN(0x0123L);\n        assert(isIdentical(exp2(specialNaN), specialNaN));\n\n        // over-/underflow\n        enum T OF = T.max_exp;\n        enum T UF = T.min_exp - T.mant_dig;\n        assert(isIdentical(exp2(OF + 1), cast(T) T.infinity));\n        assert(isIdentical(exp2(UF - 1), cast(T) 0.0));\n\n        static immutable T[2][] vals =\n        [\n            // x, exp2(x)\n            [  0.0, 1.0 ],\n            [ -0.0, 1.0 ],\n            [  0.5, SQRT2 ],\n            [  8.0, 256.0 ],\n            [ -9.0, 1.0 / 512 ],\n        ];\n\n        foreach (ref val; vals)\n        {\n            const T x = val[0];\n            const T r = val[1];\n            const T e = exp2(x);\n\n            //printf(\"exp2(%Lg) = %Lg, should be %Lg\\n\", cast(real) x, cast(real) e, cast(real) r);\n            assert(approxEqual(r, e));\n        }\n    }\n\n    import std.meta : AliasSeq;\n    foreach (T; AliasSeq!(real, double, float))\n        testExp2!T();\n}\n\n/*\n * Calculate cos(y) + i sin(y).\n *\n * On many CPUs (such as x86), this is a very efficient operation;\n * almost twice as fast as calculating sin(y) and cos(y) separately,\n * and is the preferred method when both are required.\n */\ndeprecated(\"Use std.complex.expi\")\ncreal expi(real y) @trusted pure nothrow @nogc\n{\n    version (InlineAsm_X86_Any)\n    {\n        version (Win64)\n        {\n            asm pure nothrow @nogc\n            {\n                naked;\n                fld     real ptr [ECX];\n                fsincos;\n                fxch    ST(1), ST(0);\n                ret;\n            }\n        }\n        else\n        {\n            asm pure nothrow @nogc\n            {\n                fld y;\n                fsincos;\n                fxch ST(1), ST(0);\n            }\n        }\n    }\n    else\n    {\n        return cos(y) + sin(y)*1i;\n    }\n}\n\ndeprecated\n@safe pure nothrow @nogc unittest\n{\n    assert(expi(1.3e5L) == cos(1.3e5L) + sin(1.3e5L) * 1i);\n    assert(expi(0.0L) == 1L + 0.0Li);\n}\n\n/*********************************************************************\n * Separate floating point value into significand and exponent.\n *\n * Returns:\n *      Calculate and return $(I x) and $(I exp) such that\n *      value =$(I x)*2$(SUPERSCRIPT exp) and\n *      .5 $(LT)= |$(I x)| $(LT) 1.0\n *\n *      $(I x) has same sign as value.\n *\n *      $(TABLE_SV\n *      $(TR $(TH value)           $(TH returns)         $(TH exp))\n *      $(TR $(TD $(PLUSMN)0.0)    $(TD $(PLUSMN)0.0)    $(TD 0))\n *      $(TR $(TD +$(INFIN))       $(TD +$(INFIN))       $(TD int.max))\n *      $(TR $(TD -$(INFIN))       $(TD -$(INFIN))       $(TD int.min))\n *      $(TR $(TD $(PLUSMN)$(NAN)) $(TD $(PLUSMN)$(NAN)) $(TD int.min))\n *      )\n */\nT frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc\nif (isFloatingPoint!T)\n{\n    Unqual!T vf = value;\n    ushort* vu = cast(ushort*)&vf;\n    static if (is(Unqual!T == float))\n        int* vi = cast(int*)&vf;\n    else\n        long* vl = cast(long*)&vf;\n    int ex;\n    alias F = floatTraits!T;\n\n    ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;\n    static if (F.realFormat == RealFormat.ieeeExtended)\n    {\n        if (ex)\n        {   // If exponent is non-zero\n            if (ex == F.EXPMASK) // infinity or NaN\n            {\n                if (*vl &  0x7FFF_FFFF_FFFF_FFFF)  // NaN\n                {\n                    *vl |= 0xC000_0000_0000_0000;  // convert NaNS to NaNQ\n                    exp = int.min;\n                }\n                else if (vu[F.EXPPOS_SHORT] & 0x8000)   // negative infinity\n                    exp = int.min;\n                else   // positive infinity\n                    exp = int.max;\n\n            }\n            else\n            {\n                exp = ex - F.EXPBIAS;\n                vu[F.EXPPOS_SHORT] = (0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE;\n            }\n        }\n        else if (!*vl)\n        {\n            // vf is +-0.0\n            exp = 0;\n        }\n        else\n        {\n            // subnormal\n\n            vf *= F.RECIP_EPSILON;\n            ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;\n            exp = ex - F.EXPBIAS - T.mant_dig + 1;\n            vu[F.EXPPOS_SHORT] = ((-1 - F.EXPMASK) & vu[F.EXPPOS_SHORT]) | 0x3FFE;\n        }\n        return vf;\n    }\n    else static if (F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        if (ex)     // If exponent is non-zero\n        {\n            if (ex == F.EXPMASK)\n            {\n                // infinity or NaN\n                if (vl[MANTISSA_LSB] |\n                    (vl[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF))  // NaN\n                {\n                    // convert NaNS to NaNQ\n                    vl[MANTISSA_MSB] |= 0x0000_8000_0000_0000;\n                    exp = int.min;\n                }\n                else if (vu[F.EXPPOS_SHORT] & 0x8000)   // negative infinity\n                    exp = int.min;\n                else   // positive infinity\n                    exp = int.max;\n            }\n            else\n            {\n                exp = ex - F.EXPBIAS;\n                vu[F.EXPPOS_SHORT] = F.EXPBIAS | (0x8000 & vu[F.EXPPOS_SHORT]);\n            }\n        }\n        else if ((vl[MANTISSA_LSB] |\n            (vl[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF)) == 0)\n        {\n            // vf is +-0.0\n            exp = 0;\n        }\n        else\n        {\n            // subnormal\n            vf *= F.RECIP_EPSILON;\n            ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;\n            exp = ex - F.EXPBIAS - T.mant_dig + 1;\n            vu[F.EXPPOS_SHORT] = F.EXPBIAS | (0x8000 & vu[F.EXPPOS_SHORT]);\n        }\n        return vf;\n    }\n    else static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        if (ex) // If exponent is non-zero\n        {\n            if (ex == F.EXPMASK)   // infinity or NaN\n            {\n                if (*vl == 0x7FF0_0000_0000_0000)  // positive infinity\n                {\n                    exp = int.max;\n                }\n                else if (*vl == 0xFFF0_0000_0000_0000) // negative infinity\n                    exp = int.min;\n                else\n                { // NaN\n                    *vl |= 0x0008_0000_0000_0000;  // convert NaNS to NaNQ\n                    exp = int.min;\n                }\n            }\n            else\n            {\n                exp = (ex - F.EXPBIAS) >> 4;\n                vu[F.EXPPOS_SHORT] = cast(ushort)((0x800F & vu[F.EXPPOS_SHORT]) | 0x3FE0);\n            }\n        }\n        else if (!(*vl & 0x7FFF_FFFF_FFFF_FFFF))\n        {\n            // vf is +-0.0\n            exp = 0;\n        }\n        else\n        {\n            // subnormal\n            vf *= F.RECIP_EPSILON;\n            ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;\n            exp = ((ex - F.EXPBIAS) >> 4) - T.mant_dig + 1;\n            vu[F.EXPPOS_SHORT] =\n                cast(ushort)(((-1 - F.EXPMASK) & vu[F.EXPPOS_SHORT]) | 0x3FE0);\n        }\n        return vf;\n    }\n    else static if (F.realFormat == RealFormat.ieeeSingle)\n    {\n        if (ex) // If exponent is non-zero\n        {\n            if (ex == F.EXPMASK)   // infinity or NaN\n            {\n                if (*vi == 0x7F80_0000)  // positive infinity\n                {\n                    exp = int.max;\n                }\n                else if (*vi == 0xFF80_0000) // negative infinity\n                    exp = int.min;\n                else\n                { // NaN\n                    *vi |= 0x0040_0000;  // convert NaNS to NaNQ\n                    exp = int.min;\n                }\n            }\n            else\n            {\n                exp = (ex - F.EXPBIAS) >> 7;\n                vu[F.EXPPOS_SHORT] = cast(ushort)((0x807F & vu[F.EXPPOS_SHORT]) | 0x3F00);\n            }\n        }\n        else if (!(*vi & 0x7FFF_FFFF))\n        {\n            // vf is +-0.0\n            exp = 0;\n        }\n        else\n        {\n            // subnormal\n            vf *= F.RECIP_EPSILON;\n            ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;\n            exp = ((ex - F.EXPBIAS) >> 7) - T.mant_dig + 1;\n            vu[F.EXPPOS_SHORT] =\n                cast(ushort)(((-1 - F.EXPMASK) & vu[F.EXPPOS_SHORT]) | 0x3F00);\n        }\n        return vf;\n    }\n    else // static if (F.realFormat == RealFormat.ibmExtended)\n    {\n        assert(0, \"frexp not implemented\");\n    }\n}\n\n///\n@safe unittest\n{\n    int exp;\n    real mantissa = frexp(123.456L, exp);\n\n    assert(approxEqual(mantissa * pow(2.0L, cast(real) exp), 123.456L));\n\n    assert(frexp(-real.nan, exp) && exp == int.min);\n    assert(frexp(real.nan, exp) && exp == int.min);\n    assert(frexp(-real.infinity, exp) == -real.infinity && exp == int.min);\n    assert(frexp(real.infinity, exp) == real.infinity && exp == int.max);\n    assert(frexp(-0.0, exp) == -0.0 && exp == 0);\n    assert(frexp(0.0, exp) == 0.0 && exp == 0);\n}\n\n@safe @nogc nothrow unittest\n{\n    int exp;\n    real mantissa = frexp(123.456L, exp);\n\n    // check if values are equal to 19 decimal digits of precision\n    assert(equalsDigit(mantissa * pow(2.0L, cast(real) exp), 123.456L, 19));\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    import std.typecons : tuple, Tuple;\n\n    static foreach (T; AliasSeq!(real, double, float))\n    {{\n        Tuple!(T, T, int)[] vals =     // x,frexp,exp\n            [\n             tuple(T(0.0),  T( 0.0 ), 0),\n             tuple(T(-0.0), T( -0.0), 0),\n             tuple(T(1.0),  T( .5  ), 1),\n             tuple(T(-1.0), T( -.5 ), 1),\n             tuple(T(2.0),  T( .5  ), 2),\n             tuple(T(float.min_normal/2.0f), T(.5), -126),\n             tuple(T.infinity, T.infinity, int.max),\n             tuple(-T.infinity, -T.infinity, int.min),\n             tuple(T.nan, T.nan, int.min),\n             tuple(-T.nan, -T.nan, int.min),\n\n             // Phobos issue #16026:\n             tuple(3 * (T.min_normal * T.epsilon), T( .75), (T.min_exp - T.mant_dig) + 2)\n             ];\n\n        foreach (elem; vals)\n        {\n            T x = elem[0];\n            T e = elem[1];\n            int exp = elem[2];\n            int eptr;\n            T v = frexp(x, eptr);\n            assert(isIdentical(e, v));\n            assert(exp == eptr);\n\n        }\n\n        static if (floatTraits!(T).realFormat == RealFormat.ieeeExtended)\n        {\n            static T[3][] extendedvals = [ // x,frexp,exp\n                [0x1.a5f1c2eb3fe4efp+73L,    0x1.A5F1C2EB3FE4EFp-1L,     74],    // normal\n                [0x1.fa01712e8f0471ap-1064L, 0x1.fa01712e8f0471ap-1L, -1063],\n                [T.min_normal,      .5, -16381],\n                [T.min_normal/2.0L, .5, -16382]    // subnormal\n            ];\n            foreach (elem; extendedvals)\n            {\n                T x = elem[0];\n                T e = elem[1];\n                int exp = cast(int) elem[2];\n                int eptr;\n                T v = frexp(x, eptr);\n                assert(isIdentical(e, v));\n                assert(exp == eptr);\n\n            }\n        }\n    }}\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    void foo() {\n        static foreach (T; AliasSeq!(real, double, float))\n        {{\n            int exp;\n            const T a = 1;\n            immutable T b = 2;\n            auto c = frexp(a, exp);\n            auto d = frexp(b, exp);\n        }}\n    }\n}\n\n/******************************************\n * Extracts the exponent of x as a signed integral value.\n *\n * If x is not a special value, the result is the same as\n * $(D cast(int) logb(x)).\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)                $(TH ilogb(x))     $(TH Range error?))\n *      $(TR $(TD 0)                 $(TD FP_ILOGB0)   $(TD yes))\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD int.max)     $(TD no))\n *      $(TR $(TD $(NAN))            $(TD FP_ILOGBNAN) $(TD no))\n *      )\n */\nint ilogb(T)(const T x) @trusted pure nothrow @nogc\nif (isFloatingPoint!T)\n{\n    import core.bitop : bsr;\n    alias F = floatTraits!T;\n\n    union floatBits\n    {\n        T rv;\n        ushort[T.sizeof/2] vu;\n        uint[T.sizeof/4] vui;\n        static if (T.sizeof >= 8)\n            ulong[T.sizeof/8] vul;\n    }\n    floatBits y = void;\n    y.rv = x;\n\n    int ex = y.vu[F.EXPPOS_SHORT] & F.EXPMASK;\n    static if (F.realFormat == RealFormat.ieeeExtended)\n    {\n        if (ex)\n        {\n            // If exponent is non-zero\n            if (ex == F.EXPMASK) // infinity or NaN\n            {\n                if (y.vul[0] &  0x7FFF_FFFF_FFFF_FFFF)  // NaN\n                    return FP_ILOGBNAN;\n                else // +-infinity\n                    return int.max;\n            }\n            else\n            {\n                return ex - F.EXPBIAS - 1;\n            }\n        }\n        else if (!y.vul[0])\n        {\n            // vf is +-0.0\n            return FP_ILOGB0;\n        }\n        else\n        {\n            // subnormal\n            return ex - F.EXPBIAS - T.mant_dig + 1 + bsr(y.vul[0]);\n        }\n    }\n    else static if (F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        if (ex)    // If exponent is non-zero\n        {\n            if (ex == F.EXPMASK)\n            {\n                // infinity or NaN\n                if (y.vul[MANTISSA_LSB] | ( y.vul[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF))  // NaN\n                    return FP_ILOGBNAN;\n                else // +- infinity\n                    return int.max;\n            }\n            else\n            {\n                return ex - F.EXPBIAS - 1;\n            }\n        }\n        else if ((y.vul[MANTISSA_LSB] | (y.vul[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF)) == 0)\n        {\n            // vf is +-0.0\n            return FP_ILOGB0;\n        }\n        else\n        {\n            // subnormal\n            const ulong msb = y.vul[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF;\n            const ulong lsb = y.vul[MANTISSA_LSB];\n            if (msb)\n                return ex - F.EXPBIAS - T.mant_dig + 1 + bsr(msb) + 64;\n            else\n                return ex - F.EXPBIAS - T.mant_dig + 1 + bsr(lsb);\n        }\n    }\n    else static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        if (ex) // If exponent is non-zero\n        {\n            if (ex == F.EXPMASK)   // infinity or NaN\n            {\n                if ((y.vul[0] & 0x7FFF_FFFF_FFFF_FFFF) == 0x7FF0_0000_0000_0000)  // +- infinity\n                    return int.max;\n                else // NaN\n                    return FP_ILOGBNAN;\n            }\n            else\n            {\n                return ((ex - F.EXPBIAS) >> 4) - 1;\n            }\n        }\n        else if (!(y.vul[0] & 0x7FFF_FFFF_FFFF_FFFF))\n        {\n            // vf is +-0.0\n            return FP_ILOGB0;\n        }\n        else\n        {\n            // subnormal\n            enum MANTISSAMASK_64 = ((cast(ulong) F.MANTISSAMASK_INT) << 32) | 0xFFFF_FFFF;\n            return ((ex - F.EXPBIAS) >> 4) - T.mant_dig + 1 + bsr(y.vul[0] & MANTISSAMASK_64);\n        }\n    }\n    else static if (F.realFormat == RealFormat.ieeeSingle)\n    {\n        if (ex) // If exponent is non-zero\n        {\n            if (ex == F.EXPMASK)   // infinity or NaN\n            {\n                if ((y.vui[0] & 0x7FFF_FFFF) == 0x7F80_0000)  // +- infinity\n                    return int.max;\n                else // NaN\n                    return FP_ILOGBNAN;\n            }\n            else\n            {\n                return ((ex - F.EXPBIAS) >> 7) - 1;\n            }\n        }\n        else if (!(y.vui[0] & 0x7FFF_FFFF))\n        {\n            // vf is +-0.0\n            return FP_ILOGB0;\n        }\n        else\n        {\n            // subnormal\n            const uint mantissa = y.vui[0] & F.MANTISSAMASK_INT;\n            return ((ex - F.EXPBIAS) >> 7) - T.mant_dig + 1 + bsr(mantissa);\n        }\n    }\n    else // static if (F.realFormat == RealFormat.ibmExtended)\n    {\n        assert(0, \"ilogb not implemented\");\n    }\n}\n/// ditto\nint ilogb(T)(const T x) @safe pure nothrow @nogc\nif (isIntegral!T && isUnsigned!T)\n{\n    import core.bitop : bsr;\n    if (x == 0)\n        return FP_ILOGB0;\n    else\n    {\n        static assert(T.sizeof <= ulong.sizeof, \"integer size too large for the current ilogb implementation\");\n        return bsr(x);\n    }\n}\n/// ditto\nint ilogb(T)(const T x) @safe pure nothrow @nogc\nif (isIntegral!T && isSigned!T)\n{\n    import std.traits : Unsigned;\n    // Note: abs(x) can not be used because the return type is not Unsigned and\n    //       the return value would be wrong for x == int.min\n    Unsigned!T absx =  x >= 0 ? x : -x;\n    return ilogb(absx);\n}\n\n///\n@safe pure unittest\n{\n    assert(ilogb(1) == 0);\n    assert(ilogb(3) == 1);\n    assert(ilogb(3.0) == 1);\n    assert(ilogb(100_000_000) == 26);\n\n    assert(ilogb(0) == FP_ILOGB0);\n    assert(ilogb(0.0) == FP_ILOGB0);\n    assert(ilogb(double.nan) == FP_ILOGBNAN);\n    assert(ilogb(double.infinity) == int.max);\n}\n\n/**\nSpecial return values of $(LREF ilogb).\n */\nalias FP_ILOGB0   = core.stdc.math.FP_ILOGB0;\n/// ditto\nalias FP_ILOGBNAN = core.stdc.math.FP_ILOGBNAN;\n\n///\n@safe pure unittest\n{\n    assert(ilogb(0) == FP_ILOGB0);\n    assert(ilogb(0.0) == FP_ILOGB0);\n    assert(ilogb(double.nan) == FP_ILOGBNAN);\n}\n\n@safe nothrow @nogc unittest\n{\n    import std.meta : AliasSeq;\n    import std.typecons : Tuple;\n    static foreach (F; AliasSeq!(float, double, real))\n    {{\n        alias T = Tuple!(F, int);\n        T[13] vals =   // x, ilogb(x)\n        [\n            T(  F.nan     , FP_ILOGBNAN ),\n            T( -F.nan     , FP_ILOGBNAN ),\n            T(  F.infinity, int.max     ),\n            T( -F.infinity, int.max     ),\n            T(  0.0       , FP_ILOGB0   ),\n            T( -0.0       , FP_ILOGB0   ),\n            T(  2.0       , 1           ),\n            T(  2.0001    , 1           ),\n            T(  1.9999    , 0           ),\n            T(  0.5       , -1          ),\n            T(  123.123   , 6           ),\n            T( -123.123   , 6           ),\n            T(  0.123     , -4          ),\n        ];\n\n        foreach (elem; vals)\n        {\n            assert(ilogb(elem[0]) == elem[1]);\n        }\n    }}\n\n    // min_normal and subnormals\n    assert(ilogb(-float.min_normal) == -126);\n    assert(ilogb(nextUp(-float.min_normal)) == -127);\n    assert(ilogb(nextUp(-float(0.0))) == -149);\n    assert(ilogb(-double.min_normal) == -1022);\n    assert(ilogb(nextUp(-double.min_normal)) == -1023);\n    assert(ilogb(nextUp(-double(0.0))) == -1074);\n    static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended)\n    {\n        assert(ilogb(-real.min_normal) == -16382);\n        assert(ilogb(nextUp(-real.min_normal)) == -16383);\n        assert(ilogb(nextUp(-real(0.0))) == -16445);\n    }\n    else static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)\n    {\n        assert(ilogb(-real.min_normal) == -1022);\n        assert(ilogb(nextUp(-real.min_normal)) == -1023);\n        assert(ilogb(nextUp(-real(0.0))) == -1074);\n    }\n\n    // test integer types\n    assert(ilogb(0) == FP_ILOGB0);\n    assert(ilogb(int.max) == 30);\n    assert(ilogb(int.min) == 31);\n    assert(ilogb(uint.max) == 31);\n    assert(ilogb(long.max) == 62);\n    assert(ilogb(long.min) == 63);\n    assert(ilogb(ulong.max) == 63);\n}\n\n/*******************************************\n * Compute n * 2$(SUPERSCRIPT exp)\n * References: frexp\n */\n\nreal ldexp(real n, int exp) @nogc @safe pure nothrow { pragma(inline, true); return core.math.ldexp(n, exp); }\n//FIXME\n///ditto\ndouble ldexp(double n, int exp) @safe pure nothrow @nogc { return ldexp(cast(real) n, exp); }\n//FIXME\n///ditto\nfloat ldexp(float n, int exp) @safe pure nothrow @nogc { return ldexp(cast(real) n, exp); }\n\n///\n@nogc @safe pure nothrow unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(float, double, real))\n    {{\n        T r;\n\n        r = ldexp(3.0L, 3);\n        assert(r == 24);\n\n        r = ldexp(cast(T) 3.0, cast(int) 3);\n        assert(r == 24);\n\n        T n = 3.0;\n        int exp = 3;\n        r = ldexp(n, exp);\n        assert(r == 24);\n    }}\n}\n\n@safe pure nothrow @nogc unittest\n{\n    static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended ||\n               floatTraits!(real).realFormat == RealFormat.ieeeQuadruple)\n    {\n        assert(ldexp(1.0L, -16384) == 0x1p-16384L);\n        assert(ldexp(1.0L, -16382) == 0x1p-16382L);\n        int x;\n        real n = frexp(0x1p-16384L, x);\n        assert(n == 0.5L);\n        assert(x==-16383);\n        assert(ldexp(n, x)==0x1p-16384L);\n    }\n    else static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)\n    {\n        assert(ldexp(1.0L, -1024) == 0x1p-1024L);\n        assert(ldexp(1.0L, -1022) == 0x1p-1022L);\n        int x;\n        real n = frexp(0x1p-1024L, x);\n        assert(n == 0.5L);\n        assert(x==-1023);\n        assert(ldexp(n, x)==0x1p-1024L);\n    }\n    else static assert(false, \"Floating point type real not supported\");\n}\n\n/* workaround Issue 14718, float parsing depends on platform strtold\n@safe pure nothrow @nogc unittest\n{\n    assert(ldexp(1.0, -1024) == 0x1p-1024);\n    assert(ldexp(1.0, -1022) == 0x1p-1022);\n    int x;\n    double n = frexp(0x1p-1024, x);\n    assert(n == 0.5);\n    assert(x==-1023);\n    assert(ldexp(n, x)==0x1p-1024);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    assert(ldexp(1.0f, -128) == 0x1p-128f);\n    assert(ldexp(1.0f, -126) == 0x1p-126f);\n    int x;\n    float n = frexp(0x1p-128f, x);\n    assert(n == 0.5f);\n    assert(x==-127);\n    assert(ldexp(n, x)==0x1p-128f);\n}\n*/\n\n@safe @nogc nothrow unittest\n{\n    static real[3][] vals =    // value,exp,ldexp\n    [\n    [    0,    0,    0],\n    [    1,    0,    1],\n    [    -1,    0,    -1],\n    [    1,    1,    2],\n    [    123,    10,    125952],\n    [    real.max,    int.max,    real.infinity],\n    [    real.max,    -int.max,    0],\n    [    real.min_normal,    -int.max,    0],\n    ];\n    int i;\n\n    for (i = 0; i < vals.length; i++)\n    {\n        real x = vals[i][0];\n        int exp = cast(int) vals[i][1];\n        real z = vals[i][2];\n        real l = ldexp(x, exp);\n\n        assert(equalsDigit(z, l, 7));\n    }\n\n    real function(real, int) pldexp = &ldexp;\n    assert(pldexp != null);\n}\n\nprivate\n{\n    version (INLINE_YL2X) {} else\n    {\n        static if (floatTraits!real.realFormat == RealFormat.ieeeQuadruple)\n        {\n            // Coefficients for log(1 + x) = x - x**2/2 + x**3 P(x)/Q(x)\n            static immutable real[13] logCoeffsP = [\n                1.313572404063446165910279910527789794488E4L,\n                7.771154681358524243729929227226708890930E4L,\n                2.014652742082537582487669938141683759923E5L,\n                3.007007295140399532324943111654767187848E5L,\n                2.854829159639697837788887080758954924001E5L,\n                1.797628303815655343403735250238293741397E5L,\n                7.594356839258970405033155585486712125861E4L,\n                2.128857716871515081352991964243375186031E4L,\n                3.824952356185897735160588078446136783779E3L,\n                4.114517881637811823002128927449878962058E2L,\n                2.321125933898420063925789532045674660756E1L,\n                4.998469661968096229986658302195402690910E-1L,\n                1.538612243596254322971797716843006400388E-6L\n            ];\n            static immutable real[13] logCoeffsQ = [\n                3.940717212190338497730839731583397586124E4L,\n                2.626900195321832660448791748036714883242E5L,\n                7.777690340007566932935753241556479363645E5L,\n                1.347518538384329112529391120390701166528E6L,\n                1.514882452993549494932585972882995548426E6L,\n                1.158019977462989115839826904108208787040E6L,\n                6.132189329546557743179177159925690841200E5L,\n                2.248234257620569139969141618556349415120E5L,\n                5.605842085972455027590989944010492125825E4L,\n                9.147150349299596453976674231612674085381E3L,\n                9.104928120962988414618126155557301584078E2L,\n                4.839208193348159620282142911143429644326E1L,\n                1.0\n            ];\n\n            // Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2)\n            // where z = 2(x-1)/(x+1)\n            static immutable real[6] logCoeffsR = [\n                -8.828896441624934385266096344596648080902E-1L,\n                8.057002716646055371965756206836056074715E1L,\n                -2.024301798136027039250415126250455056397E3L,\n                2.048819892795278657810231591630928516206E4L,\n                -8.977257995689735303686582344659576526998E4L,\n                1.418134209872192732479751274970992665513E5L\n            ];\n            static immutable real[6] logCoeffsS = [\n                1.701761051846631278975701529965589676574E6L\n                -1.332535117259762928288745111081235577029E6L,\n                4.001557694070773974936904547424676279307E5L,\n                -5.748542087379434595104154610899551484314E4L,\n                3.998526750980007367835804959888064681098E3L,\n                -1.186359407982897997337150403816839480438E2L,\n                1.0\n            ];\n        }\n        else\n        {\n            // Coefficients for log(1 + x) = x - x**2/2 + x**3 P(x)/Q(x)\n            static immutable real[7] logCoeffsP = [\n                2.0039553499201281259648E1L,\n                5.7112963590585538103336E1L,\n                6.0949667980987787057556E1L,\n                2.9911919328553073277375E1L,\n                6.5787325942061044846969E0L,\n                4.9854102823193375972212E-1L,\n                4.5270000862445199635215E-5L,\n            ];\n            static immutable real[7] logCoeffsQ = [\n                6.0118660497603843919306E1L,\n                2.1642788614495947685003E2L,\n                3.0909872225312059774938E2L,\n                2.2176239823732856465394E2L,\n                8.3047565967967209469434E1L,\n                1.5062909083469192043167E1L,\n                1.0000000000000000000000E0L,\n            ];\n\n            // Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2)\n            // where z = 2(x-1)/(x+1)\n            static immutable real[4] logCoeffsR = [\n               -3.5717684488096787370998E1L,\n                1.0777257190312272158094E1L,\n               -7.1990767473014147232598E-1L,\n                1.9757429581415468984296E-3L,\n            ];\n            static immutable real[4] logCoeffsS = [\n               -4.2861221385716144629696E2L,\n                1.9361891836232102174846E2L,\n               -2.6201045551331104417768E1L,\n                1.0000000000000000000000E0L,\n            ];\n        }\n    }\n}\n\n/**************************************\n * Calculate the natural logarithm of x.\n *\n *    $(TABLE_SV\n *    $(TR $(TH x)            $(TH log(x))    $(TH divide by 0?) $(TH invalid?))\n *    $(TR $(TD $(PLUSMN)0.0) $(TD -$(INFIN)) $(TD yes)          $(TD no))\n *    $(TR $(TD $(LT)0.0)     $(TD $(NAN))    $(TD no)           $(TD yes))\n *    $(TR $(TD +$(INFIN))    $(TD +$(INFIN)) $(TD no)           $(TD no))\n *    )\n */\nreal log(real x) @safe pure nothrow @nogc\n{\n    version (INLINE_YL2X)\n        return core.math.yl2x(x, LN2);\n    else\n    {\n        // C1 + C2 = LN2.\n        enum real C1 = 6.93145751953125E-1L;\n        enum real C2 = 1.428606820309417232121458176568075500134E-6L;\n\n        // Special cases.\n        if (isNaN(x))\n            return x;\n        if (isInfinity(x) && !signbit(x))\n            return x;\n        if (x == 0.0)\n            return -real.infinity;\n        if (x < 0.0)\n            return real.nan;\n\n        // Separate mantissa from exponent.\n        // Note, frexp is used so that denormal numbers will be handled properly.\n        real y, z;\n        int exp;\n\n        x = frexp(x, exp);\n\n        // Logarithm using log(x) = z + z^^3 R(z) / S(z),\n        // where z = 2(x - 1)/(x + 1)\n        if ((exp > 2) || (exp < -2))\n        {\n            if (x < SQRT1_2)\n            {   // 2(2x - 1)/(2x + 1)\n                exp -= 1;\n                z = x - 0.5;\n                y = 0.5 * z + 0.5;\n            }\n            else\n            {   // 2(x - 1)/(x + 1)\n                z = x - 0.5;\n                z -= 0.5;\n                y = 0.5 * x  + 0.5;\n            }\n            x = z / y;\n            z = x * x;\n            z = x * (z * poly(z, logCoeffsR) / poly(z, logCoeffsS));\n            z += exp * C2;\n            z += x;\n            z += exp * C1;\n\n            return z;\n        }\n\n        // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)\n        if (x < SQRT1_2)\n        {   // 2x - 1\n            exp -= 1;\n            x = ldexp(x, 1) - 1.0;\n        }\n        else\n        {\n            x = x - 1.0;\n        }\n        z = x * x;\n        y = x * (z * poly(x, logCoeffsP) / poly(x, logCoeffsQ));\n        y += exp * C2;\n        z = y - ldexp(z, -1);\n\n        // Note, the sum of above terms does not exceed x/4,\n        // so it contributes at most about 1/4 lsb to the error.\n        z += x;\n        z += exp * C1;\n\n        return z;\n    }\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(log(E) == 1);\n}\n\n/**************************************\n * Calculate the base-10 logarithm of x.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)            $(TH log10(x))  $(TH divide by 0?) $(TH invalid?))\n *      $(TR $(TD $(PLUSMN)0.0) $(TD -$(INFIN)) $(TD yes)          $(TD no))\n *      $(TR $(TD $(LT)0.0)     $(TD $(NAN))    $(TD no)           $(TD yes))\n *      $(TR $(TD +$(INFIN))    $(TD +$(INFIN)) $(TD no)           $(TD no))\n *      )\n */\nreal log10(real x) @safe pure nothrow @nogc\n{\n    version (INLINE_YL2X)\n        return core.math.yl2x(x, LOG2);\n    else\n    {\n        // log10(2) split into two parts.\n        enum real L102A =  0.3125L;\n        enum real L102B = -1.14700043360188047862611052755069732318101185E-2L;\n\n        // log10(e) split into two parts.\n        enum real L10EA =  0.5L;\n        enum real L10EB = -6.570551809674817234887108108339491770560299E-2L;\n\n        // Special cases are the same as for log.\n        if (isNaN(x))\n            return x;\n        if (isInfinity(x) && !signbit(x))\n            return x;\n        if (x == 0.0)\n            return -real.infinity;\n        if (x < 0.0)\n            return real.nan;\n\n        // Separate mantissa from exponent.\n        // Note, frexp is used so that denormal numbers will be handled properly.\n        real y, z;\n        int exp;\n\n        x = frexp(x, exp);\n\n        // Logarithm using log(x) = z + z^^3 R(z) / S(z),\n        // where z = 2(x - 1)/(x + 1)\n        if ((exp > 2) || (exp < -2))\n        {\n            if (x < SQRT1_2)\n            {   // 2(2x - 1)/(2x + 1)\n                exp -= 1;\n                z = x - 0.5;\n                y = 0.5 * z + 0.5;\n            }\n            else\n            {   // 2(x - 1)/(x + 1)\n                z = x - 0.5;\n                z -= 0.5;\n                y = 0.5 * x  + 0.5;\n            }\n            x = z / y;\n            z = x * x;\n            y = x * (z * poly(z, logCoeffsR) / poly(z, logCoeffsS));\n            goto Ldone;\n        }\n\n        // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)\n        if (x < SQRT1_2)\n        {   // 2x - 1\n            exp -= 1;\n            x = ldexp(x, 1) - 1.0;\n        }\n        else\n            x = x - 1.0;\n\n        z = x * x;\n        y = x * (z * poly(x, logCoeffsP) / poly(x, logCoeffsQ));\n        y = y - ldexp(z, -1);\n\n        // Multiply log of fraction by log10(e) and base 2 exponent by log10(2).\n        // This sequence of operations is critical and it may be horribly\n        // defeated by some compiler optimizers.\n    Ldone:\n        z = y * L10EB;\n        z += x * L10EB;\n        z += exp * L102B;\n        z += y * L10EA;\n        z += x * L10EA;\n        z += exp * L102A;\n\n        return z;\n    }\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(fabs(log10(1000) - 3) < .000001);\n}\n\n/**\n * Calculates the natural logarithm of 1 + x.\n *\n * For very small x, log1p(x) will be more accurate than\n * log(1 + x).\n *\n *  $(TABLE_SV\n *  $(TR $(TH x)            $(TH log1p(x))     $(TH divide by 0?) $(TH invalid?))\n *  $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no)           $(TD no))\n *  $(TR $(TD -1.0)         $(TD -$(INFIN))    $(TD yes)          $(TD no))\n *  $(TR $(TD $(LT)-1.0)    $(TD -$(NAN))      $(TD no)           $(TD yes))\n *  $(TR $(TD +$(INFIN))    $(TD +$(INFIN))    $(TD no)           $(TD no))\n *  )\n */\nreal log1p(real x) @safe pure nothrow @nogc\n{\n    version (INLINE_YL2X)\n    {\n        // On x87, yl2xp1 is valid if and only if -0.5 <= lg(x) <= 0.5,\n        //    ie if -0.29 <= x <= 0.414\n        return (fabs(x) <= 0.25)  ? core.math.yl2xp1(x, LN2) : core.math.yl2x(x+1, LN2);\n    }\n    else\n    {\n        // Special cases.\n        if (isNaN(x) || x == 0.0)\n            return x;\n        if (isInfinity(x) && !signbit(x))\n            return x;\n        if (x == -1.0)\n            return -real.infinity;\n        if (x < -1.0)\n            return real.nan;\n\n        return log(x + 1.0);\n    }\n}\n\n///\n@safe pure unittest\n{\n    assert(isIdentical(log1p(0.0), 0.0));\n    assert(log1p(1.0).feqrel(0.69314) > 16);\n\n    assert(log1p(-1.0) == -real.infinity);\n    assert(isNaN(log1p(-2.0)));\n    assert(log1p(real.nan) is real.nan);\n    assert(log1p(-real.nan) is -real.nan);\n    assert(log1p(real.infinity) == real.infinity);\n}\n\n/***************************************\n * Calculates the base-2 logarithm of x:\n * $(SUB log, 2)x\n *\n *  $(TABLE_SV\n *  $(TR $(TH x)            $(TH log2(x))   $(TH divide by 0?) $(TH invalid?))\n *  $(TR $(TD $(PLUSMN)0.0) $(TD -$(INFIN)) $(TD yes)          $(TD no) )\n *  $(TR $(TD $(LT)0.0)     $(TD $(NAN))    $(TD no)           $(TD yes) )\n *  $(TR $(TD +$(INFIN))    $(TD +$(INFIN)) $(TD no)           $(TD no) )\n *  )\n */\nreal log2(real x) @safe pure nothrow @nogc\n{\n    version (INLINE_YL2X)\n        return core.math.yl2x(x, 1);\n    else\n    {\n        // Special cases are the same as for log.\n        if (isNaN(x))\n            return x;\n        if (isInfinity(x) && !signbit(x))\n            return x;\n        if (x == 0.0)\n            return -real.infinity;\n        if (x < 0.0)\n            return real.nan;\n\n        // Separate mantissa from exponent.\n        // Note, frexp is used so that denormal numbers will be handled properly.\n        real y, z;\n        int exp;\n\n        x = frexp(x, exp);\n\n        // Logarithm using log(x) = z + z^^3 R(z) / S(z),\n        // where z = 2(x - 1)/(x + 1)\n        if ((exp > 2) || (exp < -2))\n        {\n            if (x < SQRT1_2)\n            {   // 2(2x - 1)/(2x + 1)\n                exp -= 1;\n                z = x - 0.5;\n                y = 0.5 * z + 0.5;\n            }\n            else\n            {   // 2(x - 1)/(x + 1)\n                z = x - 0.5;\n                z -= 0.5;\n                y = 0.5 * x  + 0.5;\n            }\n            x = z / y;\n            z = x * x;\n            y = x * (z * poly(z, logCoeffsR) / poly(z, logCoeffsS));\n            goto Ldone;\n        }\n\n        // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)\n        if (x < SQRT1_2)\n        {   // 2x - 1\n            exp -= 1;\n            x = ldexp(x, 1) - 1.0;\n        }\n        else\n            x = x - 1.0;\n\n        z = x * x;\n        y = x * (z * poly(x, logCoeffsP) / poly(x, logCoeffsQ));\n        y = y - ldexp(z, -1);\n\n        // Multiply log of fraction by log10(e) and base 2 exponent by log10(2).\n        // This sequence of operations is critical and it may be horribly\n        // defeated by some compiler optimizers.\n    Ldone:\n        z = y * (LOG2E - 1.0);\n        z += x * (LOG2E - 1.0);\n        z += y;\n        z += x;\n        z += exp;\n\n        return z;\n    }\n}\n\n///\n@safe unittest\n{\n    assert(approxEqual(log2(1024.0L), 10));\n}\n\n@safe @nogc nothrow unittest\n{\n    // check if values are equal to 19 decimal digits of precision\n    assert(equalsDigit(log2(1024.0L), 10, 19));\n}\n\n/*****************************************\n * Extracts the exponent of x as a signed integral value.\n *\n * If x is subnormal, it is treated as if it were normalized.\n * For a positive, finite x:\n *\n * 1 $(LT)= $(I x) * FLT_RADIX$(SUPERSCRIPT -logb(x)) $(LT) FLT_RADIX\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)                 $(TH logb(x))   $(TH divide by 0?) )\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD +$(INFIN)) $(TD no))\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD -$(INFIN)) $(TD yes) )\n *      )\n */\nreal logb(real x) @trusted nothrow @nogc\n{\n    version (Win64_DMD_InlineAsm)\n    {\n        asm pure nothrow @nogc\n        {\n            naked                       ;\n            fld     real ptr [RCX]      ;\n            fxtract                     ;\n            fstp    ST(0)               ;\n            ret                         ;\n        }\n    }\n    else version (CRuntime_Microsoft)\n    {\n        asm pure nothrow @nogc\n        {\n            fld     x                   ;\n            fxtract                     ;\n            fstp    ST(0)               ;\n        }\n    }\n    else\n        return core.stdc.math.logbl(x);\n}\n\n///\n@safe @nogc nothrow unittest\n{\n    assert(logb(1.0) == 0);\n    assert(logb(100.0) == 6);\n\n    assert(logb(0.0) == -real.infinity);\n    assert(logb(real.infinity) == real.infinity);\n    assert(logb(-real.infinity) == real.infinity);\n}\n\n/************************************\n * Calculates the remainder from the calculation x/y.\n * Returns:\n * The value of x - i * y, where i is the number of times that y can\n * be completely subtracted from x. The result has the same sign as x.\n *\n * $(TABLE_SV\n *  $(TR $(TH x)              $(TH y)             $(TH fmod(x, y))   $(TH invalid?))\n *  $(TR $(TD $(PLUSMN)0.0)   $(TD not 0.0)       $(TD $(PLUSMN)0.0) $(TD no))\n *  $(TR $(TD $(PLUSMNINF))   $(TD anything)      $(TD $(NAN))       $(TD yes))\n *  $(TR $(TD anything)       $(TD $(PLUSMN)0.0)  $(TD $(NAN))       $(TD yes))\n *  $(TR $(TD !=$(PLUSMNINF)) $(TD $(PLUSMNINF))  $(TD x)            $(TD no))\n * )\n */\nreal fmod(real x, real y) @trusted nothrow @nogc\n{\n    version (CRuntime_Microsoft)\n    {\n        return x % y;\n    }\n    else\n        return core.stdc.math.fmodl(x, y);\n}\n\n///\n@safe unittest\n{\n    assert(isIdentical(fmod(0.0, 1.0), 0.0));\n    assert(fmod(5.0, 3.0).feqrel(2.0) > 16);\n    assert(isNaN(fmod(5.0, 0.0)));\n}\n\n/************************************\n * Breaks x into an integral part and a fractional part, each of which has\n * the same sign as x. The integral part is stored in i.\n * Returns:\n * The fractional part of x.\n *\n * $(TABLE_SV\n *  $(TR $(TH x)              $(TH i (on input))  $(TH modf(x, i))   $(TH i (on return)))\n *  $(TR $(TD $(PLUSMNINF))   $(TD anything)      $(TD $(PLUSMN)0.0) $(TD $(PLUSMNINF)))\n * )\n */\nreal modf(real x, ref real i) @trusted nothrow @nogc\n{\n    version (CRuntime_Microsoft)\n    {\n        i = trunc(x);\n        return copysign(isInfinity(x) ? 0.0 : x - i, x);\n    }\n    else\n        return core.stdc.math.modfl(x,&i);\n}\n\n///\n@safe unittest\n{\n    real frac;\n    real intpart;\n\n    frac = modf(3.14159, intpart);\n    assert(intpart.feqrel(3.0) > 16);\n    assert(frac.feqrel(0.14159) > 16);\n}\n\n/*************************************\n * Efficiently calculates x * 2$(SUPERSCRIPT n).\n *\n * scalbn handles underflow and overflow in\n * the same fashion as the basic arithmetic operators.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)                 $(TH scalb(x)))\n *      $(TR $(TD $(PLUSMNINF))      $(TD $(PLUSMNINF)) )\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(PLUSMN)0.0) )\n *      )\n */\nreal scalbn(real x, int n) @trusted nothrow @nogc\n{\n    version (InlineAsm_X86_Any)\n    {\n        // scalbnl is not supported on DMD-Windows, so use asm pure nothrow @nogc.\n        version (Win64)\n        {\n            asm pure nothrow @nogc {\n                naked                           ;\n                mov     16[RSP],RCX             ;\n                fild    word ptr 16[RSP]        ;\n                fld     real ptr [RDX]          ;\n                fscale                          ;\n                fstp    ST(1)                   ;\n                ret                             ;\n            }\n        }\n        else\n        {\n            asm pure nothrow @nogc {\n                fild n;\n                fld x;\n                fscale;\n                fstp ST(1);\n            }\n        }\n    }\n    else\n    {\n        return core.stdc.math.scalbnl(x, n);\n    }\n}\n\n///\n@safe nothrow @nogc unittest\n{\n    assert(scalbn(-real.infinity, 5) == -real.infinity);\n}\n\n/***************\n * Calculates the cube root of x.\n *\n *      $(TABLE_SV\n *      $(TR $(TH $(I x))            $(TH cbrt(x))           $(TH invalid?))\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(PLUSMN)0.0)      $(TD no) )\n *      $(TR $(TD $(NAN))            $(TD $(NAN))            $(TD yes) )\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)$(INFIN)) $(TD no) )\n *      )\n */\nreal cbrt(real x) @trusted nothrow @nogc\n{\n    version (CRuntime_Microsoft)\n    {\n        version (INLINE_YL2X)\n            return copysign(exp2(core.math.yl2x(fabs(x), 1.0L/3.0L)), x);\n        else\n            return core.stdc.math.cbrtl(x);\n    }\n    else\n        return core.stdc.math.cbrtl(x);\n}\n\n///\n@safe unittest\n{\n    assert(cbrt(1.0).feqrel(1.0) > 16);\n    assert(cbrt(27.0).feqrel(3.0) > 16);\n    assert(cbrt(15.625).feqrel(2.5) > 16);\n}\n\n/*******************************\n * Returns |x|\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)                 $(TH fabs(x)))\n *      $(TR $(TD $(PLUSMN)0.0)      $(TD +0.0) )\n *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD +$(INFIN)) )\n *      )\n */\nreal fabs(real x) @safe pure nothrow @nogc { pragma(inline, true); return core.math.fabs(x); }\n//FIXME\n///ditto\ndouble fabs(double x) @safe pure nothrow @nogc { return fabs(cast(real) x); }\n//FIXME\n///ditto\nfloat fabs(float x) @safe pure nothrow @nogc { return fabs(cast(real) x); }\n\n///\n@safe unittest\n{\n    assert(isIdentical(fabs(0.0), 0.0));\n    assert(isIdentical(fabs(-0.0), 0.0));\n    assert(fabs(-10.0) == 10.0);\n}\n\n@safe unittest\n{\n    real function(real) pfabs = &fabs;\n    assert(pfabs != null);\n}\n\n/***********************************************************************\n * Calculates the length of the\n * hypotenuse of a right-angled triangle with sides of length x and y.\n * The hypotenuse is the value of the square root of\n * the sums of the squares of x and y:\n *\n *      sqrt($(POWER x, 2) + $(POWER y, 2))\n *\n * Note that hypot(x, y), hypot(y, x) and\n * hypot(x, -y) are equivalent.\n *\n *  $(TABLE_SV\n *  $(TR $(TH x)            $(TH y)            $(TH hypot(x, y)) $(TH invalid?))\n *  $(TR $(TD x)            $(TD $(PLUSMN)0.0) $(TD |x|)         $(TD no))\n *  $(TR $(TD $(PLUSMNINF)) $(TD y)            $(TD +$(INFIN))   $(TD no))\n *  $(TR $(TD $(PLUSMNINF)) $(TD $(NAN))       $(TD +$(INFIN))   $(TD no))\n *  )\n */\n\nreal hypot(real x, real y) @safe pure nothrow @nogc\n{\n    // Scale x and y to avoid underflow and overflow.\n    // If one is huge and the other tiny, return the larger.\n    // If both are huge, avoid overflow by scaling by 1/sqrt(real.max/2).\n    // If both are tiny, avoid underflow by scaling by sqrt(real.min_normal*real.epsilon).\n\n    enum real SQRTMIN = 0.5 * sqrt(real.min_normal); // This is a power of 2.\n    enum real SQRTMAX = 1.0L / SQRTMIN; // 2^^((max_exp)/2) = nextUp(sqrt(real.max))\n\n    static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);\n\n    // Proves that sqrt(real.max) ~~  0.5/sqrt(real.min_normal)\n    static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);\n\n    real u = fabs(x);\n    real v = fabs(y);\n    if (!(u >= v))  // check for NaN as well.\n    {\n        v = u;\n        u = fabs(y);\n        if (u == real.infinity) return u; // hypot(inf, nan) == inf\n        if (v == real.infinity) return v; // hypot(nan, inf) == inf\n    }\n\n    // Now u >= v, or else one is NaN.\n    if (v >= SQRTMAX*0.5)\n    {\n            // hypot(huge, huge) -- avoid overflow\n        u *= SQRTMIN*0.5;\n        v *= SQRTMIN*0.5;\n        return sqrt(u*u + v*v) * SQRTMAX * 2.0;\n    }\n\n    if (u <= SQRTMIN)\n    {\n        // hypot (tiny, tiny) -- avoid underflow\n        // This is only necessary to avoid setting the underflow\n        // flag.\n        u *= SQRTMAX / real.epsilon;\n        v *= SQRTMAX / real.epsilon;\n        return sqrt(u*u + v*v) * SQRTMIN * real.epsilon;\n    }\n\n    if (u * real.epsilon > v)\n    {\n        // hypot (huge, tiny) = huge\n        return u;\n    }\n\n    // both are in the normal range\n    return sqrt(u*u + v*v);\n}\n\n///\n@safe unittest\n{\n    assert(hypot(1.0, 1.0).feqrel(1.4142) > 16);\n    assert(hypot(3.0, 4.0).feqrel(5.0) > 16);\n    assert(hypot(real.infinity, 1.0) == real.infinity);\n    assert(hypot(real.infinity, real.nan) == real.infinity);\n}\n\n@safe unittest\n{\n    static real[3][] vals =     // x,y,hypot\n        [\n            [ 0.0,     0.0,   0.0],\n            [ 0.0,    -0.0,   0.0],\n            [ -0.0,   -0.0,   0.0],\n            [ 3.0,     4.0,   5.0],\n            [ -300,   -400,   500],\n            [0.0,      7.0,   7.0],\n            [9.0,   9*real.epsilon,   9.0],\n            [88/(64*sqrt(real.min_normal)), 105/(64*sqrt(real.min_normal)), 137/(64*sqrt(real.min_normal))],\n            [88/(128*sqrt(real.min_normal)), 105/(128*sqrt(real.min_normal)), 137/(128*sqrt(real.min_normal))],\n            [3*real.min_normal*real.epsilon, 4*real.min_normal*real.epsilon, 5*real.min_normal*real.epsilon],\n            [ real.min_normal, real.min_normal, sqrt(2.0L)*real.min_normal],\n            [ real.max/sqrt(2.0L), real.max/sqrt(2.0L), real.max],\n            [ real.infinity, real.nan, real.infinity],\n            [ real.nan, real.infinity, real.infinity],\n            [ real.nan, real.nan, real.nan],\n            [ real.nan, real.max, real.nan],\n            [ real.max, real.nan, real.nan],\n        ];\n        for (int i = 0; i < vals.length; i++)\n        {\n            real x = vals[i][0];\n            real y = vals[i][1];\n            real z = vals[i][2];\n            real h = hypot(x, y);\n            assert(isIdentical(z,h) || feqrel(z, h) >= real.mant_dig - 1);\n        }\n}\n\n/**************************************\n * Returns the value of x rounded upward to the next integer\n * (toward positive infinity).\n */\nreal ceil(real x) @trusted pure nothrow @nogc\n{\n    version (Win64_DMD_InlineAsm)\n    {\n        asm pure nothrow @nogc\n        {\n            naked                       ;\n            fld     real ptr [RCX]      ;\n            fstcw   8[RSP]              ;\n            mov     AL,9[RSP]           ;\n            mov     DL,AL               ;\n            and     AL,0xC3             ;\n            or      AL,0x08             ; // round to +infinity\n            mov     9[RSP],AL           ;\n            fldcw   8[RSP]              ;\n            frndint                     ;\n            mov     9[RSP],DL           ;\n            fldcw   8[RSP]              ;\n            ret                         ;\n        }\n    }\n    else version (CRuntime_Microsoft)\n    {\n        short cw;\n        asm pure nothrow @nogc\n        {\n            fld     x                   ;\n            fstcw   cw                  ;\n            mov     AL,byte ptr cw+1    ;\n            mov     DL,AL               ;\n            and     AL,0xC3             ;\n            or      AL,0x08             ; // round to +infinity\n            mov     byte ptr cw+1,AL    ;\n            fldcw   cw                  ;\n            frndint                     ;\n            mov     byte ptr cw+1,DL    ;\n            fldcw   cw                  ;\n        }\n    }\n    else\n    {\n        // Special cases.\n        if (isNaN(x) || isInfinity(x))\n            return x;\n\n        real y = floorImpl(x);\n        if (y < x)\n            y += 1.0;\n\n        return y;\n    }\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(ceil(+123.456L) == +124);\n    assert(ceil(-123.456L) == -123);\n    assert(ceil(-1.234L) == -1);\n    assert(ceil(-0.123L) == 0);\n    assert(ceil(0.0L) == 0);\n    assert(ceil(+0.123L) == 1);\n    assert(ceil(+1.234L) == 2);\n    assert(ceil(real.infinity) == real.infinity);\n    assert(isNaN(ceil(real.nan)));\n    assert(isNaN(ceil(real.init)));\n}\n\n/// ditto\ndouble ceil(double x) @trusted pure nothrow @nogc\n{\n    // Special cases.\n    if (isNaN(x) || isInfinity(x))\n        return x;\n\n    double y = floorImpl(x);\n    if (y < x)\n        y += 1.0;\n\n    return y;\n}\n\n@safe pure nothrow @nogc unittest\n{\n    assert(ceil(+123.456) == +124);\n    assert(ceil(-123.456) == -123);\n    assert(ceil(-1.234) == -1);\n    assert(ceil(-0.123) == 0);\n    assert(ceil(0.0) == 0);\n    assert(ceil(+0.123) == 1);\n    assert(ceil(+1.234) == 2);\n    assert(ceil(double.infinity) == double.infinity);\n    assert(isNaN(ceil(double.nan)));\n    assert(isNaN(ceil(double.init)));\n}\n\n/// ditto\nfloat ceil(float x) @trusted pure nothrow @nogc\n{\n    // Special cases.\n    if (isNaN(x) || isInfinity(x))\n        return x;\n\n    float y = floorImpl(x);\n    if (y < x)\n        y += 1.0;\n\n    return y;\n}\n\n@safe pure nothrow @nogc unittest\n{\n    assert(ceil(+123.456f) == +124);\n    assert(ceil(-123.456f) == -123);\n    assert(ceil(-1.234f) == -1);\n    assert(ceil(-0.123f) == 0);\n    assert(ceil(0.0f) == 0);\n    assert(ceil(+0.123f) == 1);\n    assert(ceil(+1.234f) == 2);\n    assert(ceil(float.infinity) == float.infinity);\n    assert(isNaN(ceil(float.nan)));\n    assert(isNaN(ceil(float.init)));\n}\n\n/**************************************\n * Returns the value of x rounded downward to the next integer\n * (toward negative infinity).\n */\nreal floor(real x) @trusted pure nothrow @nogc\n{\n    version (Win64_DMD_InlineAsm)\n    {\n        asm pure nothrow @nogc\n        {\n            naked                       ;\n            fld     real ptr [RCX]      ;\n            fstcw   8[RSP]              ;\n            mov     AL,9[RSP]           ;\n            mov     DL,AL               ;\n            and     AL,0xC3             ;\n            or      AL,0x04             ; // round to -infinity\n            mov     9[RSP],AL           ;\n            fldcw   8[RSP]              ;\n            frndint                     ;\n            mov     9[RSP],DL           ;\n            fldcw   8[RSP]              ;\n            ret                         ;\n        }\n    }\n    else version (CRuntime_Microsoft)\n    {\n        short cw;\n        asm pure nothrow @nogc\n        {\n            fld     x                   ;\n            fstcw   cw                  ;\n            mov     AL,byte ptr cw+1    ;\n            mov     DL,AL               ;\n            and     AL,0xC3             ;\n            or      AL,0x04             ; // round to -infinity\n            mov     byte ptr cw+1,AL    ;\n            fldcw   cw                  ;\n            frndint                     ;\n            mov     byte ptr cw+1,DL    ;\n            fldcw   cw                  ;\n        }\n    }\n    else\n    {\n        // Special cases.\n        if (isNaN(x) || isInfinity(x) || x == 0.0)\n            return x;\n\n        return floorImpl(x);\n    }\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(floor(+123.456L) == +123);\n    assert(floor(-123.456L) == -124);\n    assert(floor(+123.0L) == +123);\n    assert(floor(-124.0L) == -124);\n    assert(floor(-1.234L) == -2);\n    assert(floor(-0.123L) == -1);\n    assert(floor(0.0L) == 0);\n    assert(floor(+0.123L) == 0);\n    assert(floor(+1.234L) == 1);\n    assert(floor(real.infinity) == real.infinity);\n    assert(isNaN(floor(real.nan)));\n    assert(isNaN(floor(real.init)));\n}\n\n/// ditto\ndouble floor(double x) @trusted pure nothrow @nogc\n{\n    // Special cases.\n    if (isNaN(x) || isInfinity(x) || x == 0.0)\n        return x;\n\n    return floorImpl(x);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    assert(floor(+123.456) == +123);\n    assert(floor(-123.456) == -124);\n    assert(floor(+123.0) == +123);\n    assert(floor(-124.0) == -124);\n    assert(floor(-1.234) == -2);\n    assert(floor(-0.123) == -1);\n    assert(floor(0.0) == 0);\n    assert(floor(+0.123) == 0);\n    assert(floor(+1.234) == 1);\n    assert(floor(double.infinity) == double.infinity);\n    assert(isNaN(floor(double.nan)));\n    assert(isNaN(floor(double.init)));\n}\n\n/// ditto\nfloat floor(float x) @trusted pure nothrow @nogc\n{\n    // Special cases.\n    if (isNaN(x) || isInfinity(x) || x == 0.0)\n        return x;\n\n    return floorImpl(x);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    assert(floor(+123.456f) == +123);\n    assert(floor(-123.456f) == -124);\n    assert(floor(+123.0f) == +123);\n    assert(floor(-124.0f) == -124);\n    assert(floor(-1.234f) == -2);\n    assert(floor(-0.123f) == -1);\n    assert(floor(0.0f) == 0);\n    assert(floor(+0.123f) == 0);\n    assert(floor(+1.234f) == 1);\n    assert(floor(float.infinity) == float.infinity);\n    assert(isNaN(floor(float.nan)));\n    assert(isNaN(floor(float.init)));\n}\n\n/**\n * Round `val` to a multiple of `unit`. `rfunc` specifies the rounding\n * function to use; by default this is `rint`, which uses the current\n * rounding mode.\n */\nUnqual!F quantize(alias rfunc = rint, F)(const F val, const F unit)\nif (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F)\n{\n    typeof(return) ret = val;\n    if (unit != 0)\n    {\n        const scaled = val / unit;\n        if (!scaled.isInfinity)\n            ret = rfunc(scaled) * unit;\n    }\n    return ret;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(12345.6789L.quantize(0.01L) == 12345.68L);\n    assert(12345.6789L.quantize!floor(0.01L) == 12345.67L);\n    assert(12345.6789L.quantize(22.0L) == 12342.0L);\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(12345.6789L.quantize(0) == 12345.6789L);\n    assert(12345.6789L.quantize(real.infinity).isNaN);\n    assert(12345.6789L.quantize(real.nan).isNaN);\n    assert(real.infinity.quantize(0.01L) == real.infinity);\n    assert(real.infinity.quantize(real.nan).isNaN);\n    assert(real.nan.quantize(0.01L).isNaN);\n    assert(real.nan.quantize(real.infinity).isNaN);\n    assert(real.nan.quantize(real.nan).isNaN);\n}\n\n/**\n * Round `val` to a multiple of `pow(base, exp)`. `rfunc` specifies the\n * rounding function to use; by default this is `rint`, which uses the\n * current rounding mode.\n */\nUnqual!F quantize(real base, alias rfunc = rint, F, E)(const F val, const E exp)\nif (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F && isIntegral!E)\n{\n    // TODO: Compile-time optimization for power-of-two bases?\n    return quantize!rfunc(val, pow(cast(F) base, exp));\n}\n\n/// ditto\nUnqual!F quantize(real base, long exp = 1, alias rfunc = rint, F)(const F val)\nif (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F)\n{\n    enum unit = cast(F) pow(base, exp);\n    return quantize!rfunc(val, unit);\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(12345.6789L.quantize!10(-2) == 12345.68L);\n    assert(12345.6789L.quantize!(10, -2) == 12345.68L);\n    assert(12345.6789L.quantize!(10, floor)(-2) == 12345.67L);\n    assert(12345.6789L.quantize!(10, -2, floor) == 12345.67L);\n\n    assert(12345.6789L.quantize!22(1) == 12342.0L);\n    assert(12345.6789L.quantize!22 == 12342.0L);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    import std.meta : AliasSeq;\n\n    static foreach (F; AliasSeq!(real, double, float))\n    {{\n        const maxL10 = cast(int) F.max.log10.floor;\n        const maxR10 = pow(cast(F) 10, maxL10);\n        assert((cast(F) 0.9L * maxR10).quantize!10(maxL10) ==  maxR10);\n        assert((cast(F)-0.9L * maxR10).quantize!10(maxL10) == -maxR10);\n\n        assert(F.max.quantize(F.min_normal) == F.max);\n        assert((-F.max).quantize(F.min_normal) == -F.max);\n        assert(F.min_normal.quantize(F.max) == 0);\n        assert((-F.min_normal).quantize(F.max) == 0);\n        assert(F.min_normal.quantize(F.min_normal) == F.min_normal);\n        assert((-F.min_normal).quantize(F.min_normal) == -F.min_normal);\n    }}\n}\n\n/******************************************\n * Rounds x to the nearest integer value, using the current rounding\n * mode.\n *\n * Unlike the rint functions, nearbyint does not raise the\n * FE_INEXACT exception.\n *\n * Note:\n *     Not implemented for Microsoft C Runtime\n */\nreal nearbyint(real x) @safe pure nothrow @nogc\n{\n    version (CRuntime_Microsoft)\n        assert(0, \"nearbyintl not implemented in Microsoft C library\");\n    else\n        return core.stdc.math.nearbyintl(x);\n}\n\n///\n@safe pure unittest\n{\n    version (CRuntime_Microsoft) {}\n    else\n    {\n        assert(nearbyint(0.4) == 0);\n        assert(nearbyint(0.5) == 0);\n        assert(nearbyint(0.6) == 1);\n        assert(nearbyint(100.0) == 100);\n\n        assert(isNaN(nearbyint(real.nan)));\n        assert(nearbyint(real.infinity) == real.infinity);\n        assert(nearbyint(-real.infinity) == -real.infinity);\n    }\n}\n\n/**********************************\n * Rounds x to the nearest integer value, using the current rounding\n * mode.\n *\n * If the return value is not equal to x, the FE_INEXACT\n * exception is raised.\n *\n * $(LREF nearbyint) performs the same operation, but does\n * not set the FE_INEXACT exception.\n */\nreal rint(real x) @safe pure nothrow @nogc { pragma(inline, true); return core.math.rint(x); }\n//FIXME\n///ditto\ndouble rint(double x) @safe pure nothrow @nogc { return rint(cast(real) x); }\n//FIXME\n///ditto\nfloat rint(float x) @safe pure nothrow @nogc { return rint(cast(real) x); }\n\n///\n@safe unittest\n{\n    resetIeeeFlags();\n    assert(rint(0.4) == 0);\n    assert(ieeeFlags.inexact);\n\n    assert(rint(0.5) == 0);\n    assert(rint(0.6) == 1);\n    assert(rint(100.0) == 100);\n\n    assert(isNaN(rint(real.nan)));\n    assert(rint(real.infinity) == real.infinity);\n    assert(rint(-real.infinity) == -real.infinity);\n}\n\n@safe unittest\n{\n    real function(real) print = &rint;\n    assert(print != null);\n}\n\n/***************************************\n * Rounds x to the nearest integer value, using the current rounding\n * mode.\n *\n * This is generally the fastest method to convert a floating-point number\n * to an integer. Note that the results from this function\n * depend on the rounding mode, if the fractional part of x is exactly 0.5.\n * If using the default rounding mode (ties round to even integers)\n * lrint(4.5) == 4, lrint(5.5)==6.\n */\nlong lrint(real x) @trusted pure nothrow @nogc\n{\n    version (InlineAsm_X86_Any)\n    {\n        version (Win64)\n        {\n            asm pure nothrow @nogc\n            {\n                naked;\n                fld     real ptr [RCX];\n                fistp   qword ptr 8[RSP];\n                mov     RAX,8[RSP];\n                ret;\n            }\n        }\n        else\n        {\n            long n;\n            asm pure nothrow @nogc\n            {\n                fld x;\n                fistp n;\n            }\n            return n;\n        }\n    }\n    else\n    {\n        alias F = floatTraits!(real);\n        static if (F.realFormat == RealFormat.ieeeDouble)\n        {\n            long result;\n\n            // Rounding limit when casting from real(double) to ulong.\n            enum real OF = 4.50359962737049600000E15L;\n\n            uint* vi = cast(uint*)(&x);\n\n            // Find the exponent and sign\n            uint msb = vi[MANTISSA_MSB];\n            uint lsb = vi[MANTISSA_LSB];\n            int exp = ((msb >> 20) & 0x7ff) - 0x3ff;\n            const int sign = msb >> 31;\n            msb &= 0xfffff;\n            msb |= 0x100000;\n\n            if (exp < 63)\n            {\n                if (exp >= 52)\n                    result = (cast(long) msb << (exp - 20)) | (lsb << (exp - 52));\n                else\n                {\n                    // Adjust x and check result.\n                    const real j = sign ? -OF : OF;\n                    x = (j + x) - j;\n                    msb = vi[MANTISSA_MSB];\n                    lsb = vi[MANTISSA_LSB];\n                    exp = ((msb >> 20) & 0x7ff) - 0x3ff;\n                    msb &= 0xfffff;\n                    msb |= 0x100000;\n\n                    if (exp < 0)\n                        result = 0;\n                    else if (exp < 20)\n                        result = cast(long) msb >> (20 - exp);\n                    else if (exp == 20)\n                        result = cast(long) msb;\n                    else\n                        result = (cast(long) msb << (exp - 20)) | (lsb >> (52 - exp));\n                }\n            }\n            else\n            {\n                // It is left implementation defined when the number is too large.\n                return cast(long) x;\n            }\n\n            return sign ? -result : result;\n        }\n        else static if (F.realFormat == RealFormat.ieeeExtended)\n        {\n            long result;\n\n            // Rounding limit when casting from real(80-bit) to ulong.\n            enum real OF = 9.22337203685477580800E18L;\n\n            ushort* vu = cast(ushort*)(&x);\n            uint* vi = cast(uint*)(&x);\n\n            // Find the exponent and sign\n            int exp = (vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;\n            const int sign = (vu[F.EXPPOS_SHORT] >> 15) & 1;\n\n            if (exp < 63)\n            {\n                // Adjust x and check result.\n                const real j = sign ? -OF : OF;\n                x = (j + x) - j;\n                exp = (vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;\n\n                version (LittleEndian)\n                {\n                    if (exp < 0)\n                        result = 0;\n                    else if (exp <= 31)\n                        result = vi[1] >> (31 - exp);\n                    else\n                        result = (cast(long) vi[1] << (exp - 31)) | (vi[0] >> (63 - exp));\n                }\n                else\n                {\n                    if (exp < 0)\n                        result = 0;\n                    else if (exp <= 31)\n                        result = vi[1] >> (31 - exp);\n                    else\n                        result = (cast(long) vi[1] << (exp - 31)) | (vi[2] >> (63 - exp));\n                }\n            }\n            else\n            {\n                // It is left implementation defined when the number is too large\n                // to fit in a 64bit long.\n                return cast(long) x;\n            }\n\n            return sign ? -result : result;\n        }\n        else static if (F.realFormat == RealFormat.ieeeQuadruple)\n        {\n            const vu = cast(ushort*)(&x);\n\n            // Find the exponent and sign\n            const sign = (vu[F.EXPPOS_SHORT] >> 15) & 1;\n            if ((vu[F.EXPPOS_SHORT] & F.EXPMASK) - (F.EXPBIAS + 1) > 63)\n            {\n                // The result is left implementation defined when the number is\n                // too large to fit in a 64 bit long.\n                return cast(long) x;\n            }\n\n            // Force rounding of lower bits according to current rounding\n            // mode by adding ±2^-112 and subtracting it again.\n            enum OF = 5.19229685853482762853049632922009600E33L;\n            const j = sign ? -OF : OF;\n            x = (j + x) - j;\n\n            const exp = (vu[F.EXPPOS_SHORT] & F.EXPMASK) - (F.EXPBIAS + 1);\n            const implicitOne = 1UL << 48;\n            auto vl = cast(ulong*)(&x);\n            vl[MANTISSA_MSB] &= implicitOne - 1;\n            vl[MANTISSA_MSB] |= implicitOne;\n\n            long result;\n\n            if (exp < 0)\n                result = 0;\n            else if (exp <= 48)\n                result = vl[MANTISSA_MSB] >> (48 - exp);\n            else\n                result = (vl[MANTISSA_MSB] << (exp - 48)) | (vl[MANTISSA_LSB] >> (112 - exp));\n\n            return sign ? -result : result;\n        }\n        else\n        {\n            static assert(false, \"real type not supported by lrint()\");\n        }\n    }\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(lrint(4.5) == 4);\n    assert(lrint(5.5) == 6);\n    assert(lrint(-4.5) == -4);\n    assert(lrint(-5.5) == -6);\n\n    assert(lrint(int.max - 0.5) == 2147483646L);\n    assert(lrint(int.max + 0.5) == 2147483648L);\n    assert(lrint(int.min - 0.5) == -2147483648L);\n    assert(lrint(int.min + 0.5) == -2147483648L);\n}\n\nstatic if (real.mant_dig >= long.sizeof * 8)\n{\n    @safe pure nothrow @nogc unittest\n    {\n        assert(lrint(long.max - 1.5L) == long.max - 1);\n        assert(lrint(long.max - 0.5L) == long.max - 1);\n        assert(lrint(long.min + 0.5L) == long.min);\n        assert(lrint(long.min + 1.5L) == long.min + 2);\n    }\n}\n\n/*******************************************\n * Return the value of x rounded to the nearest integer.\n * If the fractional part of x is exactly 0.5, the return value is\n * rounded away from zero.\n *\n * Returns:\n *     A `real`.\n */\nauto round(real x) @trusted nothrow @nogc\n{\n    version (CRuntime_Microsoft)\n    {\n        auto old = FloatingPointControl.getControlState();\n        FloatingPointControl.setControlState(\n            (old & (-1 - FloatingPointControl.roundingMask)) | FloatingPointControl.roundToZero\n        );\n        x = rint((x >= 0) ? x + 0.5 : x - 0.5);\n        FloatingPointControl.setControlState(old);\n        return x;\n    }\n    else\n        return core.stdc.math.roundl(x);\n}\n\n///\n@safe nothrow @nogc unittest\n{\n    assert(round(4.5) == 5);\n    assert(round(5.4) == 5);\n    assert(round(-4.5) == -5);\n    assert(round(-5.1) == -5);\n}\n\n// assure purity on Posix\nversion (Posix)\n{\n    @safe pure nothrow @nogc unittest\n    {\n        assert(round(4.5) == 5);\n    }\n}\n\n/**********************************************\n * Return the value of x rounded to the nearest integer.\n *\n * If the fractional part of x is exactly 0.5, the return value is rounded\n * away from zero.\n *\n * $(BLUE This function is Posix-Only.)\n */\nlong lround(real x) @trusted nothrow @nogc\n{\n    version (Posix)\n        return core.stdc.math.llroundl(x);\n    else\n        assert(0, \"lround not implemented\");\n}\n\n///\n@safe nothrow @nogc unittest\n{\n    version (Posix)\n    {\n        assert(lround(0.49) == 0);\n        assert(lround(0.5) == 1);\n        assert(lround(1.5) == 2);\n    }\n}\n\n/**\n Returns the integer portion of x, dropping the fractional portion.\n This is also known as \"chop\" rounding.\n `pure` on all platforms.\n */\nreal trunc(real x) @trusted nothrow @nogc pure\n{\n    version (Win64_DMD_InlineAsm)\n    {\n        asm pure nothrow @nogc\n        {\n            naked                       ;\n            fld     real ptr [RCX]      ;\n            fstcw   8[RSP]              ;\n            mov     AL,9[RSP]           ;\n            mov     DL,AL               ;\n            and     AL,0xC3             ;\n            or      AL,0x0C             ; // round to 0\n            mov     9[RSP],AL           ;\n            fldcw   8[RSP]              ;\n            frndint                     ;\n            mov     9[RSP],DL           ;\n            fldcw   8[RSP]              ;\n            ret                         ;\n        }\n    }\n    else version (CRuntime_Microsoft)\n    {\n        short cw;\n        asm pure nothrow @nogc\n        {\n            fld     x                   ;\n            fstcw   cw                  ;\n            mov     AL,byte ptr cw+1    ;\n            mov     DL,AL               ;\n            and     AL,0xC3             ;\n            or      AL,0x0C             ; // round to 0\n            mov     byte ptr cw+1,AL    ;\n            fldcw   cw                  ;\n            frndint                     ;\n            mov     byte ptr cw+1,DL    ;\n            fldcw   cw                  ;\n        }\n    }\n    else\n        return core.stdc.math.truncl(x);\n}\n\n///\n@safe pure unittest\n{\n    assert(trunc(0.01) == 0);\n    assert(trunc(0.49) == 0);\n    assert(trunc(0.5) == 0);\n    assert(trunc(1.5) == 1);\n}\n\n/****************************************************\n * Calculate the remainder x REM y, following IEC 60559.\n *\n * REM is the value of x - y * n, where n is the integer nearest the exact\n * value of x / y.\n * If |n - x / y| == 0.5, n is even.\n * If the result is zero, it has the same sign as x.\n * Otherwise, the sign of the result is the sign of x / y.\n * Precision mode has no effect on the remainder functions.\n *\n * remquo returns `n` in the parameter `n`.\n *\n * $(TABLE_SV\n *  $(TR $(TH x)               $(TH y)            $(TH remainder(x, y)) $(TH n)   $(TH invalid?))\n *  $(TR $(TD $(PLUSMN)0.0)    $(TD not 0.0)      $(TD $(PLUSMN)0.0)    $(TD 0.0) $(TD no))\n *  $(TR $(TD $(PLUSMNINF))    $(TD anything)     $(TD -$(NAN))         $(TD ?)   $(TD yes))\n *  $(TR $(TD anything)        $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)$(NAN)) $(TD ?)   $(TD yes))\n *  $(TR $(TD != $(PLUSMNINF)) $(TD $(PLUSMNINF)) $(TD x)               $(TD ?)   $(TD no))\n * )\n *\n * $(BLUE `remquo` and `remainder` not supported on Windows.)\n */\nreal remainder(real x, real y) @trusted nothrow @nogc\n{\n    version (CRuntime_Microsoft)\n    {\n        int n;\n        return remquo(x, y, n);\n    }\n    else\n        return core.stdc.math.remainderl(x, y);\n}\n\n/// ditto\nreal remquo(real x, real y, out int n) @trusted nothrow @nogc  /// ditto\n{\n    version (Posix)\n        return core.stdc.math.remquol(x, y, &n);\n    else\n        assert(0, \"remquo not implemented\");\n}\n\n///\n@safe @nogc nothrow unittest\n{\n    version (Posix)\n    {\n        assert(remainder(5.1, 3.0).feqrel(-0.9) > 16);\n        assert(remainder(-5.1, 3.0).feqrel(0.9) > 16);\n        assert(remainder(0.0, 3.0) == 0.0);\n\n        assert(isNaN(remainder(1.0, 0.0)));\n        assert(isNaN(remainder(-1.0, 0.0)));\n    }\n}\n\n///\n@safe @nogc nothrow unittest\n{\n    version (Posix)\n    {\n        int n;\n\n        assert(remquo(5.1, 3.0, n).feqrel(-0.9) > 16 && n == 2);\n        assert(remquo(-5.1, 3.0, n).feqrel(0.9) > 16 && n == -2);\n        assert(remquo(0.0, 3.0, n) == 0.0 && n == 0);\n    }\n}\n\n/** IEEE exception status flags ('sticky bits')\n\n These flags indicate that an exceptional floating-point condition has occurred.\n They indicate that a NaN or an infinity has been generated, that a result\n is inexact, or that a signalling NaN has been encountered. If floating-point\n exceptions are enabled (unmasked), a hardware exception will be generated\n instead of setting these flags.\n */\nstruct IeeeFlags\n{\nnothrow @nogc:\n\nprivate:\n    // The x87 FPU status register is 16 bits.\n    // The Pentium SSE2 status register is 32 bits.\n    // The ARM and PowerPC FPSCR is a 32-bit register.\n    // The SPARC FSR is a 32bit register (64 bits for SPARC 7 & 8, but high bits are uninteresting).\n    uint flags;\n\n    version (CRuntime_Microsoft)\n    {\n        // Microsoft uses hardware-incompatible custom constants in fenv.h (core.stdc.fenv).\n        // Applies to both x87 status word (16 bits) and SSE2 status word(32 bits).\n        enum : int\n        {\n            INEXACT_MASK   = 0x20,\n            UNDERFLOW_MASK = 0x10,\n            OVERFLOW_MASK  = 0x08,\n            DIVBYZERO_MASK = 0x04,\n            INVALID_MASK   = 0x01,\n\n            EXCEPTIONS_MASK = 0b11_1111\n        }\n        // Don't bother about subnormals, they are not supported on most CPUs.\n        //  SUBNORMAL_MASK = 0x02;\n    }\n    else\n    {\n        enum : int\n        {\n            INEXACT_MASK    = core.stdc.fenv.FE_INEXACT,\n            UNDERFLOW_MASK  = core.stdc.fenv.FE_UNDERFLOW,\n            OVERFLOW_MASK   = core.stdc.fenv.FE_OVERFLOW,\n            DIVBYZERO_MASK  = core.stdc.fenv.FE_DIVBYZERO,\n            INVALID_MASK    = core.stdc.fenv.FE_INVALID,\n            EXCEPTIONS_MASK = core.stdc.fenv.FE_ALL_EXCEPT,\n        }\n    }\n\nprivate:\n    static uint getIeeeFlags() @trusted pure\n    {\n        version (GNU)\n        {\n            version (X86_Any)\n            {\n                ushort sw;\n                asm pure nothrow @nogc\n                {\n                    \"fstsw %0\" : \"=a\" (sw);\n                }\n                // OR the result with the SSE2 status register (MXCSR).\n                if (haveSSE)\n                {\n                    uint mxcsr;\n                    asm pure nothrow @nogc\n                    {\n                        \"stmxcsr %0\" : \"=m\" (mxcsr);\n                    }\n                    return (sw | mxcsr) & EXCEPTIONS_MASK;\n                }\n                else\n                    return sw & EXCEPTIONS_MASK;\n            }\n            else version (ARM)\n            {\n                version (ARM_SoftFloat)\n                    return 0;\n                else\n                {\n                    uint result = void;\n                    asm pure nothrow @nogc\n                    {\n                        \"vmrs %0, FPSCR; and %0, %0, #0x1F;\" : \"=r\" result;\n                    }\n                    return result;\n                }\n            }\n            else\n                assert(0, \"Not yet supported\");\n        }\n        else\n        version (InlineAsm_X86_Any)\n        {\n            ushort sw;\n            asm pure nothrow @nogc { fstsw sw; }\n\n            // OR the result with the SSE2 status register (MXCSR).\n            if (haveSSE)\n            {\n                uint mxcsr;\n                asm pure nothrow @nogc { stmxcsr mxcsr; }\n                return (sw | mxcsr) & EXCEPTIONS_MASK;\n            }\n            else return sw & EXCEPTIONS_MASK;\n        }\n        else version (SPARC)\n        {\n           /*\n               int retval;\n               asm pure nothrow @nogc { st %fsr, retval; }\n               return retval;\n            */\n           assert(0, \"Not yet supported\");\n        }\n        else version (ARM)\n        {\n            assert(false, \"Not yet supported.\");\n        }\n        else\n            assert(0, \"Not yet supported\");\n    }\n\n    static void resetIeeeFlags() @trusted\n    {\n        version (GNU)\n        {\n            version (X86_Any)\n            {\n                asm nothrow @nogc\n                {\n                    \"fnclex\";\n                }\n\n                // Also clear exception flags in MXCSR, SSE's control register.\n                if (haveSSE)\n                {\n                    uint mxcsr;\n                    asm nothrow @nogc\n                    {\n                        \"stmxcsr %0\" : \"=m\" (mxcsr);\n                    }\n                    mxcsr &= ~EXCEPTIONS_MASK;\n                    asm nothrow @nogc\n                    {\n                        \"ldmxcsr %0\" : : \"m\" (mxcsr);\n                    }\n                }\n            }\n            else version (ARM)\n            {\n                version (ARM_SoftFloat)\n                    return;\n                else\n                {\n                    uint old = FloatingPointControl.getControlState();\n                    old &= ~0b11111; // http://infocenter.arm.com/help/topic/com.arm.doc.ddi0408i/Chdfifdc.html\n                    asm nothrow @nogc\n                    {\n                        \"vmsr FPSCR, %0\" : : \"r\" (old);\n                    }\n                }\n            }\n            else\n                assert(0, \"Not yet supported\");\n        }\n        else\n        version (InlineAsm_X86_Any)\n        {\n            asm nothrow @nogc\n            {\n                fnclex;\n            }\n\n            // Also clear exception flags in MXCSR, SSE's control register.\n            if (haveSSE)\n            {\n                uint mxcsr;\n                asm nothrow @nogc { stmxcsr mxcsr; }\n                mxcsr &= ~EXCEPTIONS_MASK;\n                asm nothrow @nogc { ldmxcsr mxcsr; }\n            }\n        }\n        else\n        {\n            /* SPARC:\n              int tmpval;\n              asm pure nothrow @nogc { st %fsr, tmpval; }\n              tmpval &=0xFFFF_FC00;\n              asm pure nothrow @nogc { ld tmpval, %fsr; }\n            */\n           assert(0, \"Not yet supported\");\n        }\n    }\npublic:\n    version (IeeeFlagsSupport)\n    {\n\n     /**\n      * The result cannot be represented exactly, so rounding occurred.\n      * Example: `x = sin(0.1);`\n      */\n     @property bool inexact() @safe const { return (flags & INEXACT_MASK) != 0; }\n\n     /**\n      * A zero was generated by underflow\n      * Example: `x = real.min*real.epsilon/2;`\n      */\n     @property bool underflow() @safe const { return (flags & UNDERFLOW_MASK) != 0; }\n\n     /**\n      * An infinity was generated by overflow\n      * Example: `x = real.max*2;`\n      */\n     @property bool overflow() @safe const { return (flags & OVERFLOW_MASK) != 0; }\n\n     /**\n      * An infinity was generated by division by zero\n      * Example: `x = 3/0.0;`\n      */\n     @property bool divByZero() @safe const { return (flags & DIVBYZERO_MASK) != 0; }\n\n     /**\n      * A machine NaN was generated.\n      * Example: `x = real.infinity * 0.0;`\n      */\n     @property bool invalid() @safe const { return (flags & INVALID_MASK) != 0; }\n\n     }\n}\n\n///\nversion (GNU)\n{\n    unittest\n    {\n        pragma(msg, \"ieeeFlags test disabled, see LDC Issue #888\");\n    }\n}\nelse\n@safe unittest\n{\n    static void func() {\n        int a = 10 * 10;\n    }\n\n    real a = 3.5;\n    // Set all the flags to zero\n    resetIeeeFlags();\n    assert(!ieeeFlags.divByZero);\n    // Perform a division by zero.\n    a /= 0.0L;\n    assert(a == real.infinity);\n    assert(ieeeFlags.divByZero);\n    // Create a NaN\n    a *= 0.0L;\n    assert(ieeeFlags.invalid);\n    assert(isNaN(a));\n\n    // Check that calling func() has no effect on the\n    // status flags.\n    IeeeFlags f = ieeeFlags;\n    func();\n    assert(ieeeFlags == f);\n}\n\nversion (GNU)\n{\n    unittest\n    {\n        pragma(msg, \"ieeeFlags test disabled, see LDC Issue #888\");\n    }\n}\nelse\n@safe unittest\n{\n    import std.meta : AliasSeq;\n\n    static struct Test\n    {\n        void delegate() @trusted action;\n        bool function() @trusted ieeeCheck;\n    }\n\n    static foreach (T; AliasSeq!(float, double, real))\n    {{\n        T x; /* Needs to be here to trick -O. It would optimize away the\n            calculations if x were local to the function literals. */\n        auto tests = [\n            Test(\n                () { x = 1; x += 0.1; },\n                () => ieeeFlags.inexact\n            ),\n            Test(\n                () { x = T.min_normal; x /= T.max; },\n                () => ieeeFlags.underflow\n            ),\n            Test(\n                () { x = T.max; x += T.max; },\n                () => ieeeFlags.overflow\n            ),\n            Test(\n                () { x = 1; x /= 0; },\n                () => ieeeFlags.divByZero\n            ),\n            Test(\n                () { x = 0; x /= 0; },\n                () => ieeeFlags.invalid\n            )\n        ];\n        foreach (test; tests)\n        {\n            resetIeeeFlags();\n            assert(!test.ieeeCheck());\n            test.action();\n            assert(test.ieeeCheck());\n        }\n    }}\n}\n\nversion (X86_Any)\n{\n    version = IeeeFlagsSupport;\n}\nelse version (PPC_Any)\n{\n    version = IeeeFlagsSupport;\n}\nelse version (MIPS_Any)\n{\n    version = IeeeFlagsSupport;\n}\nelse version (ARM_Any)\n{\n    version = IeeeFlagsSupport;\n}\n\n/// Set all of the floating-point status flags to false.\nvoid resetIeeeFlags() @trusted nothrow @nogc\n{\n    IeeeFlags.resetIeeeFlags();\n}\n\n///\n@safe unittest\n{\n    resetIeeeFlags();\n    real a = 3.5;\n    a /= 0.0L;\n    assert(a == real.infinity);\n    assert(ieeeFlags.divByZero);\n\n    resetIeeeFlags();\n    assert(!ieeeFlags.divByZero);\n}\n\n/// Returns: snapshot of the current state of the floating-point status flags\n@property IeeeFlags ieeeFlags() @trusted pure nothrow @nogc\n{\n   return IeeeFlags(IeeeFlags.getIeeeFlags());\n}\n\n///\n@safe nothrow unittest\n{\n    resetIeeeFlags();\n    real a = 3.5;\n\n    a /= 0.0L;\n    assert(a == real.infinity);\n    assert(ieeeFlags.divByZero);\n\n    a *= 0.0L;\n    assert(isNaN(a));\n    assert(ieeeFlags.invalid);\n}\n\n/** Control the Floating point hardware\n\n  Change the IEEE754 floating-point rounding mode and the floating-point\n  hardware exceptions.\n\n  By default, the rounding mode is roundToNearest and all hardware exceptions\n  are disabled. For most applications, debugging is easier if the $(I division\n  by zero), $(I overflow), and $(I invalid operation) exceptions are enabled.\n  These three are combined into a $(I severeExceptions) value for convenience.\n  Note in particular that if $(I invalidException) is enabled, a hardware trap\n  will be generated whenever an uninitialized floating-point variable is used.\n\n  All changes are temporary. The previous state is restored at the\n  end of the scope.\n\n\nExample:\n----\n{\n    FloatingPointControl fpctrl;\n\n    // Enable hardware exceptions for division by zero, overflow to infinity,\n    // invalid operations, and uninitialized floating-point variables.\n    fpctrl.enableExceptions(FloatingPointControl.severeExceptions);\n\n    // This will generate a hardware exception, if x is a\n    // default-initialized floating point variable:\n    real x; // Add `= 0` or even `= real.nan` to not throw the exception.\n    real y = x * 3.0;\n\n    // The exception is only thrown for default-uninitialized NaN-s.\n    // NaN-s with other payload are valid:\n    real z = y * real.nan; // ok\n\n    // The set hardware exceptions and rounding modes will be disabled when\n    // leaving this scope.\n}\n----\n\n */\nstruct FloatingPointControl\n{\nnothrow @nogc:\n\n    alias RoundingMode = uint; ///\n\n    version (StdDdoc)\n    {\n        enum : RoundingMode\n        {\n            /** IEEE rounding modes.\n             * The default mode is roundToNearest.\n             *\n             *  roundingMask = A mask of all rounding modes.\n             */\n            roundToNearest,\n            roundDown, /// ditto\n            roundUp, /// ditto\n            roundToZero, /// ditto\n            roundingMask, /// ditto\n        }\n    }\n    else version (CRuntime_Microsoft)\n    {\n        // Microsoft uses hardware-incompatible custom constants in fenv.h (core.stdc.fenv).\n        enum : RoundingMode\n        {\n            roundToNearest = 0x0000,\n            roundDown      = 0x0400,\n            roundUp        = 0x0800,\n            roundToZero    = 0x0C00,\n            roundingMask   = roundToNearest | roundDown\n                             | roundUp | roundToZero,\n        }\n    }\n    else\n    {\n        enum : RoundingMode\n        {\n            roundToNearest = core.stdc.fenv.FE_TONEAREST,\n            roundDown      = core.stdc.fenv.FE_DOWNWARD,\n            roundUp        = core.stdc.fenv.FE_UPWARD,\n            roundToZero    = core.stdc.fenv.FE_TOWARDZERO,\n            roundingMask   = roundToNearest | roundDown\n                             | roundUp | roundToZero,\n        }\n    }\n\n    //// Change the floating-point hardware rounding mode\n    @property void rounding(RoundingMode newMode) @trusted\n    {\n        initialize();\n        setControlState((getControlState() & (-1 - roundingMask)) | (newMode & roundingMask));\n    }\n\n    /// Returns: the currently active rounding mode\n    @property static RoundingMode rounding() @trusted pure\n    {\n        return cast(RoundingMode)(getControlState() & roundingMask);\n    }\n\n    alias ExceptionMask = uint; ///\n\n    version (StdDdoc)\n    {\n        enum : ExceptionMask\n        {\n            /** IEEE hardware exceptions.\n             *  By default, all exceptions are masked (disabled).\n             *\n             *  severeExceptions = The overflow, division by zero, and invalid\n             *  exceptions.\n             */\n            subnormalException,\n            inexactException, /// ditto\n            underflowException, /// ditto\n            overflowException, /// ditto\n            divByZeroException, /// ditto\n            invalidException, /// ditto\n            severeExceptions, /// ditto\n            allExceptions, /// ditto\n        }\n    }\n    else version (ARM_Any)\n    {\n        enum : ExceptionMask\n        {\n            subnormalException    = 0x8000,\n            inexactException      = 0x1000,\n            underflowException    = 0x0800,\n            overflowException     = 0x0400,\n            divByZeroException    = 0x0200,\n            invalidException      = 0x0100,\n            severeExceptions   = overflowException | divByZeroException\n                                 | invalidException,\n            allExceptions      = severeExceptions | underflowException\n                                 | inexactException | subnormalException,\n        }\n    }\n    else version (PPC_Any)\n    {\n        enum : ExceptionMask\n        {\n            inexactException      = 0x0008,\n            divByZeroException    = 0x0010,\n            underflowException    = 0x0020,\n            overflowException     = 0x0040,\n            invalidException      = 0x0080,\n            severeExceptions   = overflowException | divByZeroException\n                                 | invalidException,\n            allExceptions      = severeExceptions | underflowException\n                                 | inexactException,\n        }\n    }\n    else version (MIPS_Any)\n    {\n        enum : ExceptionMask\n        {\n            inexactException      = 0x0080,\n            divByZeroException    = 0x0400,\n            overflowException     = 0x0200,\n            underflowException    = 0x0100,\n            invalidException      = 0x0800,\n            severeExceptions   = overflowException | divByZeroException\n                                 | invalidException,\n            allExceptions      = severeExceptions | underflowException\n                                 | inexactException,\n        }\n    }\n    else version (SPARC_Any)\n    {\n        enum : ExceptionMask\n        {\n            inexactException      = 0x0800000,\n            divByZeroException    = 0x1000000,\n            overflowException     = 0x4000000,\n            underflowException    = 0x2000000,\n            invalidException      = 0x8000000,\n            severeExceptions   = overflowException | divByZeroException\n                                 | invalidException,\n            allExceptions      = severeExceptions | underflowException\n                                 | inexactException,\n        }\n    }\n    else version (SystemZ)\n    {\n        enum : ExceptionMask\n        {\n            inexactException      = 0x08000000,\n            divByZeroException    = 0x40000000,\n            overflowException     = 0x20000000,\n            underflowException    = 0x10000000,\n            invalidException      = 0x80000000,\n            severeExceptions   = overflowException | divByZeroException\n                                 | invalidException,\n            allExceptions      = severeExceptions | underflowException\n                                 | inexactException,\n        }\n    }\n    else version (X86_Any)\n    {\n        enum : ExceptionMask\n        {\n            inexactException      = 0x20,\n            underflowException    = 0x10,\n            overflowException     = 0x08,\n            divByZeroException    = 0x04,\n            subnormalException    = 0x02,\n            invalidException      = 0x01,\n            severeExceptions   = overflowException | divByZeroException\n                                 | invalidException,\n            allExceptions      = severeExceptions | underflowException\n                                 | inexactException | subnormalException,\n        }\n    }\n    else\n        static assert(false, \"Not implemented for this architecture\");\n\n    version (ARM_Any)\n    {\n        static bool hasExceptionTraps_impl() @safe\n        {\n            auto oldState = getControlState();\n            // If exceptions are not supported, we set the bit but read it back as zero\n            // https://sourceware.org/ml/libc-ports/2012-06/msg00091.html\n            setControlState(oldState | divByZeroException);\n            immutable result = (getControlState() & allExceptions) != 0;\n            setControlState(oldState);\n            return result;\n        }\n    }\n\npublic:\n    /// Returns: true if the current FPU supports exception trapping\n    @property static bool hasExceptionTraps() @safe pure\n    {\n        version (X86_Any)\n            return true;\n        else version (PPC_Any)\n            return true;\n        else version (MIPS_Any)\n            return true;\n        else version (ARM_Any)\n        {\n            // The hasExceptionTraps_impl function is basically pure,\n            // as it restores all global state\n            auto fptr = ( () @trusted => cast(bool function() @safe\n                pure nothrow @nogc)&hasExceptionTraps_impl)();\n            return fptr();\n        }\n        else\n            assert(0, \"Not yet supported\");\n    }\n\n    /// Enable (unmask) specific hardware exceptions. Multiple exceptions may be ORed together.\n    void enableExceptions(ExceptionMask exceptions) @trusted\n    {\n        assert(hasExceptionTraps);\n        initialize();\n        version (X86_Any)\n            setControlState(getControlState() & ~(exceptions & allExceptions));\n        else\n            setControlState(getControlState() | (exceptions & allExceptions));\n    }\n\n    /// Disable (mask) specific hardware exceptions. Multiple exceptions may be ORed together.\n    void disableExceptions(ExceptionMask exceptions) @trusted\n    {\n        assert(hasExceptionTraps);\n        initialize();\n        version (X86_Any)\n            setControlState(getControlState() | (exceptions & allExceptions));\n        else\n            setControlState(getControlState() & ~(exceptions & allExceptions));\n    }\n\n    /// Returns: the exceptions which are currently enabled (unmasked)\n    @property static ExceptionMask enabledExceptions() @trusted pure\n    {\n        assert(hasExceptionTraps);\n        version (X86_Any)\n            return (getControlState() & allExceptions) ^ allExceptions;\n        else\n            return (getControlState() & allExceptions);\n    }\n\n    ///  Clear all pending exceptions, then restore the original exception state and rounding mode.\n    ~this() @trusted\n    {\n        clearExceptions();\n        if (initialized)\n            setControlState(savedState);\n    }\n\nprivate:\n    ControlState savedState;\n\n    bool initialized = false;\n\n    version (ARM_Any)\n    {\n        alias ControlState = uint;\n    }\n    else version (PPC_Any)\n    {\n        alias ControlState = uint;\n    }\n    else version (MIPS_Any)\n    {\n        alias ControlState = uint;\n    }\n    else version (SPARC_Any)\n    {\n        alias ControlState = ulong;\n    }\n    else version (SystemZ)\n    {\n        alias ControlState = uint;\n    }\n    else version (X86_Any)\n    {\n        alias ControlState = ushort;\n    }\n    else\n        static assert(false, \"Not implemented for this architecture\");\n\n    void initialize() @safe\n    {\n        // BUG: This works around the absence of this() constructors.\n        if (initialized) return;\n        clearExceptions();\n        savedState = getControlState();\n        initialized = true;\n    }\n\n    // Clear all pending exceptions\n    static void clearExceptions() @safe\n    {\n        resetIeeeFlags();\n    }\n\n    // Read from the control register\n    static ControlState getControlState() @trusted pure\n    {\n        version (GNU)\n        {\n            version (X86_Any)\n            {\n                ControlState cont;\n                asm pure nothrow @nogc\n                {\n                    \"fstcw %0\" : \"=m\" cont;\n                }\n                return cont;\n            }\n            else version (AArch64)\n            {\n                asm pure nothrow @nogc\n                {\n                    \"mrs %0, FPCR;\" : \"=r\" cont;\n                }\n                return cont;\n            }\n            else version (ARM)\n            {\n                ControlState cont;\n                version (ARM_SoftFloat)\n                   cont = 0;\n                else\n                {\n                    asm pure nothrow @nogc\n                    {\n                        \"vmrs %0, FPSCR\" : \"=r\" cont;\n                    }\n                }\n                return cont;\n            }\n            else\n                assert(0, \"Not yet supported\");\n        }\n        else\n        version (D_InlineAsm_X86)\n        {\n            short cont;\n            asm pure nothrow @nogc\n            {\n                xor EAX, EAX;\n                fstcw cont;\n            }\n            return cont;\n        }\n        else\n        version (D_InlineAsm_X86_64)\n        {\n            short cont;\n            asm pure nothrow @nogc\n            {\n                xor RAX, RAX;\n                fstcw cont;\n            }\n            return cont;\n        }\n        else\n            assert(0, \"Not yet supported\");\n    }\n\n    // Set the control register\n    static void setControlState(ControlState newState) @trusted\n    {\n        version (GNU)\n        {\n            version (X86_Any)\n            {\n                asm pure nothrow @nogc\n                {\n                    \"fclex; fldcw %0\" : : \"m\" newState;\n                }\n\n                // Also update MXCSR, SSE's control register.\n                if (haveSSE)\n                {\n                    uint mxcsr;\n                    asm pure nothrow @nogc\n                    {\n                        \"stmxcsr %0\" : \"=m\" mxcsr;\n                    }\n\n                    /* In the FPU control register, rounding mode is in bits 10 and\n                       11. In MXCSR it's in bits 13 and 14. */\n                    mxcsr &= ~(roundingMask << 3);             // delete old rounding mode\n                    mxcsr |= (newState & roundingMask) << 3;   // write new rounding mode\n\n                    /* In the FPU control register, masks are bits 0 through 5.\n                       In MXCSR they're 7 through 12. */\n                    mxcsr &= ~(allExceptions << 7);            // delete old masks\n                    mxcsr |= (newState & allExceptions) << 7;  // write new exception masks\n\n                    asm pure nothrow @nogc\n                    {\n                        \"ldmxcsr %0\" : : \"m\" mxcsr;\n                    }\n                }\n            }\n            else version (AArch64)\n            {\n                asm pure nothrow @nogc\n                {\n                    \"msr FPCR, %0;\" : : \"r\" (newState);\n                }\n            }\n            else version (ARM)\n            {\n                version (ARM_SoftFloat)\n                   return;\n                else\n                {\n                    asm pure nothrow @nogc\n                    {\n                        \"vmsr FPSCR, %0\" : : \"r\" (newState);\n                    }\n                }\n            }\n            else\n                assert(0, \"Not yet supported\");\n        }\n        else\n        version (InlineAsm_X86_Any)\n        {\n            asm nothrow @nogc\n            {\n                fclex;\n                fldcw newState;\n            }\n\n            // Also update MXCSR, SSE's control register.\n            if (haveSSE)\n            {\n                uint mxcsr;\n                asm nothrow @nogc { stmxcsr mxcsr; }\n\n                /* In the FPU control register, rounding mode is in bits 10 and\n                11. In MXCSR it's in bits 13 and 14. */\n                mxcsr &= ~(roundingMask << 3);             // delete old rounding mode\n                mxcsr |= (newState & roundingMask) << 3;   // write new rounding mode\n\n                /* In the FPU control register, masks are bits 0 through 5.\n                In MXCSR they're 7 through 12. */\n                mxcsr &= ~(allExceptions << 7);            // delete old masks\n                mxcsr |= (newState & allExceptions) << 7;  // write new exception masks\n\n                asm nothrow @nogc { ldmxcsr mxcsr; }\n            }\n        }\n        else\n            assert(0, \"Not yet supported\");\n    }\n}\n\n///\n@safe unittest\n{\n    version (D_HardFloat)\n    {\n        FloatingPointControl fpctrl;\n\n        fpctrl.rounding = FloatingPointControl.roundDown;\n        assert(lrint(1.5) == 1.0);\n\n        fpctrl.rounding = FloatingPointControl.roundUp;\n        assert(lrint(1.4) == 2.0);\n\n        fpctrl.rounding = FloatingPointControl.roundToNearest;\n        assert(lrint(1.5) == 2.0);\n    }\n}\n\nversion (D_HardFloat) @safe unittest\n{\n    void ensureDefaults()\n    {\n        assert(FloatingPointControl.rounding\n               == FloatingPointControl.roundToNearest);\n        if (FloatingPointControl.hasExceptionTraps)\n            assert(FloatingPointControl.enabledExceptions == 0);\n    }\n\n    {\n        FloatingPointControl ctrl;\n    }\n    ensureDefaults();\n\n    {\n        FloatingPointControl ctrl;\n        ctrl.rounding = FloatingPointControl.roundDown;\n        assert(FloatingPointControl.rounding == FloatingPointControl.roundDown);\n    }\n    ensureDefaults();\n\n    if (FloatingPointControl.hasExceptionTraps)\n    {\n        FloatingPointControl ctrl;\n        ctrl.enableExceptions(FloatingPointControl.divByZeroException\n                              | FloatingPointControl.overflowException);\n        assert(ctrl.enabledExceptions ==\n               (FloatingPointControl.divByZeroException\n                | FloatingPointControl.overflowException));\n\n        ctrl.rounding = FloatingPointControl.roundUp;\n        assert(FloatingPointControl.rounding == FloatingPointControl.roundUp);\n    }\n    ensureDefaults();\n}\n\nversion (D_HardFloat) @safe unittest // rounding\n{\n    import std.meta : AliasSeq;\n\n    static foreach (T; AliasSeq!(float, double, real))\n    {{\n        FloatingPointControl fpctrl;\n\n        fpctrl.rounding = FloatingPointControl.roundUp;\n        T u = 1;\n        u += 0.1;\n\n        fpctrl.rounding = FloatingPointControl.roundDown;\n        T d = 1;\n        d += 0.1;\n\n        fpctrl.rounding = FloatingPointControl.roundToZero;\n        T z = 1;\n        z += 0.1;\n\n        assert(u > d);\n        assert(z == d);\n\n        fpctrl.rounding = FloatingPointControl.roundUp;\n        u = -1;\n        u -= 0.1;\n\n        fpctrl.rounding = FloatingPointControl.roundDown;\n        d = -1;\n        d -= 0.1;\n\n        fpctrl.rounding = FloatingPointControl.roundToZero;\n        z = -1;\n        z -= 0.1;\n\n        assert(u > d);\n        assert(z == u);\n    }}\n}\n\n\n/*********************************\n * Determines if $(D_PARAM x) is NaN.\n * Params:\n *  x = a floating point number.\n * Returns:\n *  `true` if $(D_PARAM x) is Nan.\n */\nbool isNaN(X)(X x) @nogc @trusted pure nothrow\nif (isFloatingPoint!(X))\n{\n    alias F = floatTraits!(X);\n    static if (F.realFormat == RealFormat.ieeeSingle)\n    {\n        const uint p = *cast(uint *)&x;\n        return ((p & 0x7F80_0000) == 0x7F80_0000)\n            && p & 0x007F_FFFF; // not infinity\n    }\n    else static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        const ulong  p = *cast(ulong *)&x;\n        return ((p & 0x7FF0_0000_0000_0000) == 0x7FF0_0000_0000_0000)\n            && p & 0x000F_FFFF_FFFF_FFFF; // not infinity\n    }\n    else static if (F.realFormat == RealFormat.ieeeExtended)\n    {\n        const ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];\n        const ulong ps = *cast(ulong *)&x;\n        return e == F.EXPMASK &&\n            ps & 0x7FFF_FFFF_FFFF_FFFF; // not infinity\n    }\n    else static if (F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        const ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];\n        const ulong psLsb = (cast(ulong *)&x)[MANTISSA_LSB];\n        const ulong psMsb = (cast(ulong *)&x)[MANTISSA_MSB];\n        return e == F.EXPMASK &&\n            (psLsb | (psMsb& 0x0000_FFFF_FFFF_FFFF)) != 0;\n    }\n    else\n    {\n        return x != x;\n    }\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isNaN(float.init));\n    assert( isNaN(-double.init));\n    assert( isNaN(real.nan));\n    assert( isNaN(-real.nan));\n    assert(!isNaN(cast(float) 53.6));\n    assert(!isNaN(cast(real)-53.6));\n}\n\n@safe pure nothrow @nogc unittest\n{\n    import std.meta : AliasSeq;\n\n    static foreach (T; AliasSeq!(float, double, real))\n    {{\n        // CTFE-able tests\n        assert(isNaN(T.init));\n        assert(isNaN(-T.init));\n        assert(isNaN(T.nan));\n        assert(isNaN(-T.nan));\n        assert(!isNaN(T.infinity));\n        assert(!isNaN(-T.infinity));\n        assert(!isNaN(cast(T) 53.6));\n        assert(!isNaN(cast(T)-53.6));\n\n        // Runtime tests\n        shared T f;\n        f = T.init;\n        assert(isNaN(f));\n        assert(isNaN(-f));\n        f = T.nan;\n        assert(isNaN(f));\n        assert(isNaN(-f));\n        f = T.infinity;\n        assert(!isNaN(f));\n        assert(!isNaN(-f));\n        f = cast(T) 53.6;\n        assert(!isNaN(f));\n        assert(!isNaN(-f));\n    }}\n}\n\n/*********************************\n * Determines if $(D_PARAM x) is finite.\n * Params:\n *  x = a floating point number.\n * Returns:\n *  `true` if $(D_PARAM x) is finite.\n */\nbool isFinite(X)(X x) @trusted pure nothrow @nogc\n{\n    alias F = floatTraits!(X);\n    ushort* pe = cast(ushort *)&x;\n    return (pe[F.EXPPOS_SHORT] & F.EXPMASK) != F.EXPMASK;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( isFinite(1.23f));\n    assert( isFinite(float.max));\n    assert( isFinite(float.min_normal));\n    assert(!isFinite(float.nan));\n    assert(!isFinite(float.infinity));\n}\n\n@safe pure nothrow @nogc unittest\n{\n    assert(isFinite(1.23));\n    assert(isFinite(double.max));\n    assert(isFinite(double.min_normal));\n    assert(!isFinite(double.nan));\n    assert(!isFinite(double.infinity));\n\n    assert(isFinite(1.23L));\n    assert(isFinite(real.max));\n    assert(isFinite(real.min_normal));\n    assert(!isFinite(real.nan));\n    assert(!isFinite(real.infinity));\n}\n\n\n/*********************************\n * Determines if $(D_PARAM x) is normalized.\n *\n * A normalized number must not be zero, subnormal, infinite nor $(NAN).\n *\n * Params:\n *  x = a floating point number.\n * Returns:\n *  `true` if $(D_PARAM x) is normalized.\n */\n\n/* Need one for each format because subnormal floats might\n * be converted to normal reals.\n */\nbool isNormal(X)(X x) @trusted pure nothrow @nogc\n{\n    alias F = floatTraits!(X);\n    ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];\n    return (e != F.EXPMASK && e != 0);\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    float f = 3;\n    double d = 500;\n    real e = 10e+48;\n\n    assert(isNormal(f));\n    assert(isNormal(d));\n    assert(isNormal(e));\n    f = d = e = 0;\n    assert(!isNormal(f));\n    assert(!isNormal(d));\n    assert(!isNormal(e));\n    assert(!isNormal(real.infinity));\n    assert(isNormal(-real.max));\n    assert(!isNormal(real.min_normal/4));\n\n}\n\n/*********************************\n * Determines if $(D_PARAM x) is subnormal.\n *\n * Subnormals (also known as \"denormal number\"), have a 0 exponent\n * and a 0 most significant mantissa bit.\n *\n * Params:\n *  x = a floating point number.\n * Returns:\n *  `true` if $(D_PARAM x) is a denormal number.\n */\nbool isSubnormal(X)(X x) @trusted pure nothrow @nogc\n{\n    /*\n        Need one for each format because subnormal floats might\n        be converted to normal reals.\n    */\n    alias F = floatTraits!(X);\n    static if (F.realFormat == RealFormat.ieeeSingle)\n    {\n        uint *p = cast(uint *)&x;\n        return (*p & F.EXPMASK_INT) == 0 && *p & F.MANTISSAMASK_INT;\n    }\n    else static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        uint *p = cast(uint *)&x;\n        return (p[MANTISSA_MSB] & F.EXPMASK_INT) == 0\n            && (p[MANTISSA_LSB] || p[MANTISSA_MSB] & F.MANTISSAMASK_INT);\n    }\n    else static if (F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];\n        long*   ps = cast(long *)&x;\n        return (e == 0 &&\n          ((ps[MANTISSA_LSB]|(ps[MANTISSA_MSB]& 0x0000_FFFF_FFFF_FFFF)) != 0));\n    }\n    else static if (F.realFormat == RealFormat.ieeeExtended)\n    {\n        ushort* pe = cast(ushort *)&x;\n        long*   ps = cast(long *)&x;\n\n        return (pe[F.EXPPOS_SHORT] & F.EXPMASK) == 0 && *ps > 0;\n    }\n    else\n    {\n        static assert(false, \"Not implemented for this architecture\");\n    }\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    import std.meta : AliasSeq;\n\n    static foreach (T; AliasSeq!(float, double, real))\n    {{\n        T f;\n        for (f = 1.0; !isSubnormal(f); f /= 2)\n            assert(f != 0);\n    }}\n}\n\n/*********************************\n * Determines if $(D_PARAM x) is $(PLUSMN)$(INFIN).\n * Params:\n *  x = a floating point number.\n * Returns:\n *  `true` if $(D_PARAM x) is $(PLUSMN)$(INFIN).\n */\nbool isInfinity(X)(X x) @nogc @trusted pure nothrow\nif (isFloatingPoint!(X))\n{\n    alias F = floatTraits!(X);\n    static if (F.realFormat == RealFormat.ieeeSingle)\n    {\n        return ((*cast(uint *)&x) & 0x7FFF_FFFF) == 0x7F80_0000;\n    }\n    else static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        return ((*cast(ulong *)&x) & 0x7FFF_FFFF_FFFF_FFFF)\n            == 0x7FF0_0000_0000_0000;\n    }\n    else static if (F.realFormat == RealFormat.ieeeExtended)\n    {\n        const ushort e = cast(ushort)(F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT]);\n        const ulong ps = *cast(ulong *)&x;\n\n        // On Motorola 68K, infinity can have hidden bit = 1 or 0. On x86, it is always 1.\n        return e == F.EXPMASK && (ps & 0x7FFF_FFFF_FFFF_FFFF) == 0;\n    }\n    else static if (F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        const long psLsb = (cast(long *)&x)[MANTISSA_LSB];\n        const long psMsb = (cast(long *)&x)[MANTISSA_MSB];\n        return (psLsb == 0)\n            && (psMsb & 0x7FFF_FFFF_FFFF_FFFF) == 0x7FFF_0000_0000_0000;\n    }\n    else\n    {\n        return (x < -X.max) || (X.max < x);\n    }\n}\n\n///\n@nogc @safe pure nothrow unittest\n{\n    assert(!isInfinity(float.init));\n    assert(!isInfinity(-float.init));\n    assert(!isInfinity(float.nan));\n    assert(!isInfinity(-float.nan));\n    assert(isInfinity(float.infinity));\n    assert(isInfinity(-float.infinity));\n    assert(isInfinity(-1.0f / 0.0f));\n}\n\n@safe pure nothrow @nogc unittest\n{\n    // CTFE-able tests\n    assert(!isInfinity(double.init));\n    assert(!isInfinity(-double.init));\n    assert(!isInfinity(double.nan));\n    assert(!isInfinity(-double.nan));\n    assert(isInfinity(double.infinity));\n    assert(isInfinity(-double.infinity));\n    assert(isInfinity(-1.0 / 0.0));\n\n    assert(!isInfinity(real.init));\n    assert(!isInfinity(-real.init));\n    assert(!isInfinity(real.nan));\n    assert(!isInfinity(-real.nan));\n    assert(isInfinity(real.infinity));\n    assert(isInfinity(-real.infinity));\n    assert(isInfinity(-1.0L / 0.0L));\n\n    // Runtime tests\n    shared float f;\n    f = float.init;\n    assert(!isInfinity(f));\n    assert(!isInfinity(-f));\n    f = float.nan;\n    assert(!isInfinity(f));\n    assert(!isInfinity(-f));\n    f = float.infinity;\n    assert(isInfinity(f));\n    assert(isInfinity(-f));\n    f = (-1.0f / 0.0f);\n    assert(isInfinity(f));\n\n    shared double d;\n    d = double.init;\n    assert(!isInfinity(d));\n    assert(!isInfinity(-d));\n    d = double.nan;\n    assert(!isInfinity(d));\n    assert(!isInfinity(-d));\n    d = double.infinity;\n    assert(isInfinity(d));\n    assert(isInfinity(-d));\n    d = (-1.0 / 0.0);\n    assert(isInfinity(d));\n\n    shared real e;\n    e = real.init;\n    assert(!isInfinity(e));\n    assert(!isInfinity(-e));\n    e = real.nan;\n    assert(!isInfinity(e));\n    assert(!isInfinity(-e));\n    e = real.infinity;\n    assert(isInfinity(e));\n    assert(isInfinity(-e));\n    e = (-1.0L / 0.0L);\n    assert(isInfinity(e));\n}\n\n/*********************************\n * Is the binary representation of x identical to y?\n *\n * Same as ==, except that positive and negative zero are not identical,\n * and two $(NAN)s are identical if they have the same 'payload'.\n */\nbool isIdentical(real x, real y) @trusted pure nothrow @nogc\n{\n    // We're doing a bitwise comparison so the endianness is irrelevant.\n    long*   pxs = cast(long *)&x;\n    long*   pys = cast(long *)&y;\n    alias F = floatTraits!(real);\n    static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        return pxs[0] == pys[0];\n    }\n    else static if (F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        return pxs[0] == pys[0] && pxs[1] == pys[1];\n    }\n    else static if (F.realFormat == RealFormat.ieeeExtended)\n    {\n        ushort* pxe = cast(ushort *)&x;\n        ushort* pye = cast(ushort *)&y;\n        return pxe[4] == pye[4] && pxs[0] == pys[0];\n    }\n    else\n    {\n        assert(0, \"isIdentical not implemented\");\n    }\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    assert( isIdentical(0.0, 0.0));\n    assert( isIdentical(1.0, 1.0));\n    assert( isIdentical(real.infinity, real.infinity));\n    assert( isIdentical(-real.infinity, -real.infinity));\n\n    assert(!isIdentical(0.0, -0.0));\n    assert(!isIdentical(real.nan, -real.nan));\n    assert(!isIdentical(real.infinity, -real.infinity));\n}\n\n/*********************************\n * Return 1 if sign bit of e is set, 0 if not.\n */\nint signbit(X)(X x) @nogc @trusted pure nothrow\n{\n    alias F = floatTraits!(X);\n    return ((cast(ubyte *)&x)[F.SIGNPOS_BYTE] & 0x80) != 0;\n}\n\n///\n@nogc @safe pure nothrow unittest\n{\n    assert(!signbit(float.nan));\n    assert(signbit(-float.nan));\n    assert(!signbit(168.1234f));\n    assert(signbit(-168.1234f));\n    assert(!signbit(0.0f));\n    assert(signbit(-0.0f));\n    assert(signbit(-float.max));\n    assert(!signbit(float.max));\n\n    assert(!signbit(double.nan));\n    assert(signbit(-double.nan));\n    assert(!signbit(168.1234));\n    assert(signbit(-168.1234));\n    assert(!signbit(0.0));\n    assert(signbit(-0.0));\n    assert(signbit(-double.max));\n    assert(!signbit(double.max));\n\n    assert(!signbit(real.nan));\n    assert(signbit(-real.nan));\n    assert(!signbit(168.1234L));\n    assert(signbit(-168.1234L));\n    assert(!signbit(0.0L));\n    assert(signbit(-0.0L));\n    assert(signbit(-real.max));\n    assert(!signbit(real.max));\n}\n\n\n/**\nParams:\n    to = the numeric value to use\n    from = the sign value to use\nReturns:\n    a value composed of to with from's sign bit.\n */\nR copysign(R, X)(R to, X from) @trusted pure nothrow @nogc\nif (isFloatingPoint!(R) && isFloatingPoint!(X))\n{\n    ubyte* pto   = cast(ubyte *)&to;\n    const ubyte* pfrom = cast(ubyte *)&from;\n\n    alias T = floatTraits!(R);\n    alias F = floatTraits!(X);\n    pto[T.SIGNPOS_BYTE] &= 0x7F;\n    pto[T.SIGNPOS_BYTE] |= pfrom[F.SIGNPOS_BYTE] & 0x80;\n    return to;\n}\n\n/// ditto\nR copysign(R, X)(X to, R from) @trusted pure nothrow @nogc\nif (isIntegral!(X) && isFloatingPoint!(R))\n{\n    return copysign(cast(R) to, from);\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(copysign(1.0, 1.0) == 1.0);\n    assert(copysign(1.0, -0.0) == -1.0);\n    assert(copysign(1UL, -1.0) == -1.0);\n    assert(copysign(-1.0, -1.0) == -1.0);\n\n    assert(copysign(real.infinity, -1.0) == -real.infinity);\n    assert(copysign(real.nan, 1.0) is real.nan);\n    assert(copysign(-real.nan, 1.0) is real.nan);\n    assert(copysign(real.nan, -1.0) is -real.nan);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    import std.meta : AliasSeq;\n\n    static foreach (X; AliasSeq!(float, double, real, int, long))\n    {\n        static foreach (Y; AliasSeq!(float, double, real))\n        {{\n            X x = 21;\n            Y y = 23.8;\n            Y e = void;\n\n            e = copysign(x, y);\n            assert(e == 21.0);\n\n            e = copysign(-x, y);\n            assert(e == 21.0);\n\n            e = copysign(x, -y);\n            assert(e == -21.0);\n\n            e = copysign(-x, -y);\n            assert(e == -21.0);\n\n            static if (isFloatingPoint!X)\n            {\n                e = copysign(X.nan, y);\n                assert(isNaN(e) && !signbit(e));\n\n                e = copysign(X.nan, -y);\n                assert(isNaN(e) && signbit(e));\n            }\n        }}\n    }\n}\n\n/*********************************\nReturns `-1` if $(D x < 0), `x` if $(D x == 0), `1` if\n$(D x > 0), and $(NAN) if x==$(NAN).\n */\nF sgn(F)(F x) @safe pure nothrow @nogc\n{\n    // @@@TODO@@@: make this faster\n    return x > 0 ? 1 : x < 0 ? -1 : x;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(sgn(168.1234) == 1);\n    assert(sgn(-168.1234) == -1);\n    assert(sgn(0.0) == 0);\n    assert(sgn(-0.0) == 0);\n}\n\n// Functions for NaN payloads\n/*\n * A 'payload' can be stored in the significand of a $(NAN). One bit is required\n * to distinguish between a quiet and a signalling $(NAN). This leaves 22 bits\n * of payload for a float; 51 bits for a double; 62 bits for an 80-bit real;\n * and 111 bits for a 128-bit quad.\n*/\n/**\n * Create a quiet $(NAN), storing an integer inside the payload.\n *\n * For floats, the largest possible payload is 0x3F_FFFF.\n * For doubles, it is 0x3_FFFF_FFFF_FFFF.\n * For 80-bit or 128-bit reals, it is 0x3FFF_FFFF_FFFF_FFFF.\n */\nreal NaN(ulong payload) @trusted pure nothrow @nogc\n{\n    alias F = floatTraits!(real);\n    static if (F.realFormat == RealFormat.ieeeExtended)\n    {\n        // real80 (in x86 real format, the implied bit is actually\n        // not implied but a real bit which is stored in the real)\n        ulong v = 3; // implied bit = 1, quiet bit = 1\n    }\n    else\n    {\n        ulong v = 1; // no implied bit. quiet bit = 1\n    }\n\n    ulong a = payload;\n\n    // 22 Float bits\n    ulong w = a & 0x3F_FFFF;\n    a -= w;\n\n    v <<=22;\n    v |= w;\n    a >>=22;\n\n    // 29 Double bits\n    v <<=29;\n    w = a & 0xFFF_FFFF;\n    v |= w;\n    a -= w;\n    a >>=29;\n\n    static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        v |= 0x7FF0_0000_0000_0000;\n        real x;\n        * cast(ulong *)(&x) = v;\n        return x;\n    }\n    else\n    {\n        v <<=11;\n        a &= 0x7FF;\n        v |= a;\n        real x = real.nan;\n\n        // Extended real bits\n        static if (F.realFormat == RealFormat.ieeeQuadruple)\n        {\n            v <<= 1; // there's no implicit bit\n\n            version (LittleEndian)\n            {\n                *cast(ulong*)(6+cast(ubyte*)(&x)) = v;\n            }\n            else\n            {\n                *cast(ulong*)(2+cast(ubyte*)(&x)) = v;\n            }\n        }\n        else\n        {\n            *cast(ulong *)(&x) = v;\n        }\n        return x;\n    }\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    real a = NaN(1_000_000);\n    assert(isNaN(a));\n    assert(getNaNPayload(a) == 1_000_000);\n}\n\n@system pure nothrow @nogc unittest // not @safe because taking address of local.\n{\n    static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)\n    {\n        auto x = NaN(1);\n        auto xl = *cast(ulong*)&x;\n        assert(xl & 0x8_0000_0000_0000UL); //non-signaling bit, bit 52\n        assert((xl & 0x7FF0_0000_0000_0000UL) == 0x7FF0_0000_0000_0000UL); //all exp bits set\n    }\n}\n\n/**\n * Extract an integral payload from a $(NAN).\n *\n * Returns:\n * the integer payload as a ulong.\n *\n * For floats, the largest possible payload is 0x3F_FFFF.\n * For doubles, it is 0x3_FFFF_FFFF_FFFF.\n * For 80-bit or 128-bit reals, it is 0x3FFF_FFFF_FFFF_FFFF.\n */\nulong getNaNPayload(real x) @trusted pure nothrow @nogc\n{\n    //  assert(isNaN(x));\n    alias F = floatTraits!(real);\n    static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        ulong m = *cast(ulong *)(&x);\n        // Make it look like an 80-bit significand.\n        // Skip exponent, and quiet bit\n        m &= 0x0007_FFFF_FFFF_FFFF;\n        m <<= 11;\n    }\n    else static if (F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        version (LittleEndian)\n        {\n            ulong m = *cast(ulong*)(6+cast(ubyte*)(&x));\n        }\n        else\n        {\n            ulong m = *cast(ulong*)(2+cast(ubyte*)(&x));\n        }\n\n        m >>= 1; // there's no implicit bit\n    }\n    else\n    {\n        ulong m = *cast(ulong *)(&x);\n    }\n\n    // ignore implicit bit and quiet bit\n\n    const ulong f = m & 0x3FFF_FF00_0000_0000L;\n\n    ulong w = f >>> 40;\n            w |= (m & 0x00FF_FFFF_F800L) << (22 - 11);\n            w |= (m & 0x7FF) << 51;\n            return w;\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    real a = NaN(1_000_000);\n    assert(isNaN(a));\n    assert(getNaNPayload(a) == 1_000_000);\n}\n\ndebug(UnitTest)\n{\n    @safe pure nothrow @nogc unittest\n    {\n        real nan4 = NaN(0x789_ABCD_EF12_3456);\n        static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended\n                || floatTraits!(real).realFormat == RealFormat.ieeeQuadruple)\n        {\n            assert(getNaNPayload(nan4) == 0x789_ABCD_EF12_3456);\n        }\n        else\n        {\n            assert(getNaNPayload(nan4) == 0x1_ABCD_EF12_3456);\n        }\n        double nan5 = nan4;\n        assert(getNaNPayload(nan5) == 0x1_ABCD_EF12_3456);\n        float nan6 = nan4;\n        assert(getNaNPayload(nan6) == 0x12_3456);\n        nan4 = NaN(0xFABCD);\n        assert(getNaNPayload(nan4) == 0xFABCD);\n        nan6 = nan4;\n        assert(getNaNPayload(nan6) == 0xFABCD);\n        nan5 = NaN(0x100_0000_0000_3456);\n        assert(getNaNPayload(nan5) == 0x0000_0000_3456);\n    }\n}\n\n/**\n * Calculate the next largest floating point value after x.\n *\n * Return the least number greater than x that is representable as a real;\n * thus, it gives the next point on the IEEE number line.\n *\n *  $(TABLE_SV\n *    $(SVH x,            nextUp(x)   )\n *    $(SV  -$(INFIN),    -real.max   )\n *    $(SV  $(PLUSMN)0.0, real.min_normal*real.epsilon )\n *    $(SV  real.max,     $(INFIN) )\n *    $(SV  $(INFIN),     $(INFIN) )\n *    $(SV  $(NAN),       $(NAN)   )\n * )\n */\nreal nextUp(real x) @trusted pure nothrow @nogc\n{\n    alias F = floatTraits!(real);\n    static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        return nextUp(cast(double) x);\n    }\n    else static if (F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];\n        if (e == F.EXPMASK)\n        {\n            // NaN or Infinity\n            if (x == -real.infinity) return -real.max;\n            return x; // +Inf and NaN are unchanged.\n        }\n\n        auto ps = cast(ulong *)&x;\n        if (ps[MANTISSA_MSB] & 0x8000_0000_0000_0000)\n        {\n            // Negative number\n            if (ps[MANTISSA_LSB] == 0 && ps[MANTISSA_MSB] == 0x8000_0000_0000_0000)\n            {\n                // it was negative zero, change to smallest subnormal\n                ps[MANTISSA_LSB] = 1;\n                ps[MANTISSA_MSB] = 0;\n                return x;\n            }\n            if (ps[MANTISSA_LSB] == 0) --ps[MANTISSA_MSB];\n            --ps[MANTISSA_LSB];\n        }\n        else\n        {\n            // Positive number\n            ++ps[MANTISSA_LSB];\n            if (ps[MANTISSA_LSB] == 0) ++ps[MANTISSA_MSB];\n        }\n        return x;\n    }\n    else static if (F.realFormat == RealFormat.ieeeExtended)\n    {\n        // For 80-bit reals, the \"implied bit\" is a nuisance...\n        ushort *pe = cast(ushort *)&x;\n        ulong  *ps = cast(ulong  *)&x;\n\n        if ((pe[F.EXPPOS_SHORT] & F.EXPMASK) == F.EXPMASK)\n        {\n            // First, deal with NANs and infinity\n            if (x == -real.infinity) return -real.max;\n            return x; // +Inf and NaN are unchanged.\n        }\n        if (pe[F.EXPPOS_SHORT] & 0x8000)\n        {\n            // Negative number -- need to decrease the significand\n            --*ps;\n            // Need to mask with 0x7FFF... so subnormals are treated correctly.\n            if ((*ps & 0x7FFF_FFFF_FFFF_FFFF) == 0x7FFF_FFFF_FFFF_FFFF)\n            {\n                if (pe[F.EXPPOS_SHORT] == 0x8000)   // it was negative zero\n                {\n                    *ps = 1;\n                    pe[F.EXPPOS_SHORT] = 0; // smallest subnormal.\n                    return x;\n                }\n\n                --pe[F.EXPPOS_SHORT];\n\n                if (pe[F.EXPPOS_SHORT] == 0x8000)\n                    return x; // it's become a subnormal, implied bit stays low.\n\n                *ps = 0xFFFF_FFFF_FFFF_FFFF; // set the implied bit\n                return x;\n            }\n            return x;\n        }\n        else\n        {\n            // Positive number -- need to increase the significand.\n            // Works automatically for positive zero.\n            ++*ps;\n            if ((*ps & 0x7FFF_FFFF_FFFF_FFFF) == 0)\n            {\n                // change in exponent\n                ++pe[F.EXPPOS_SHORT];\n                *ps = 0x8000_0000_0000_0000; // set the high bit\n            }\n        }\n        return x;\n    }\n    else // static if (F.realFormat == RealFormat.ibmExtended)\n    {\n        assert(0, \"nextUp not implemented\");\n    }\n}\n\n/** ditto */\ndouble nextUp(double x) @trusted pure nothrow @nogc\n{\n    ulong *ps = cast(ulong *)&x;\n\n    if ((*ps & 0x7FF0_0000_0000_0000) == 0x7FF0_0000_0000_0000)\n    {\n        // First, deal with NANs and infinity\n        if (x == -x.infinity) return -x.max;\n        return x; // +INF and NAN are unchanged.\n    }\n    if (*ps & 0x8000_0000_0000_0000)    // Negative number\n    {\n        if (*ps == 0x8000_0000_0000_0000) // it was negative zero\n        {\n            *ps = 0x0000_0000_0000_0001; // change to smallest subnormal\n            return x;\n        }\n        --*ps;\n    }\n    else\n    {   // Positive number\n        ++*ps;\n    }\n    return x;\n}\n\n/** ditto */\nfloat nextUp(float x) @trusted pure nothrow @nogc\n{\n    uint *ps = cast(uint *)&x;\n\n    if ((*ps & 0x7F80_0000) == 0x7F80_0000)\n    {\n        // First, deal with NANs and infinity\n        if (x == -x.infinity) return -x.max;\n\n        return x; // +INF and NAN are unchanged.\n    }\n    if (*ps & 0x8000_0000)   // Negative number\n    {\n        if (*ps == 0x8000_0000) // it was negative zero\n        {\n            *ps = 0x0000_0001; // change to smallest subnormal\n            return x;\n        }\n\n        --*ps;\n    }\n    else\n    {\n        // Positive number\n        ++*ps;\n    }\n    return x;\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    assert(nextUp(1.0 - 1.0e-6).feqrel(0.999999) > 16);\n    assert(nextUp(1.0 - real.epsilon).feqrel(1.0) > 16);\n}\n\n/**\n * Calculate the next smallest floating point value before x.\n *\n * Return the greatest number less than x that is representable as a real;\n * thus, it gives the previous point on the IEEE number line.\n *\n *  $(TABLE_SV\n *    $(SVH x,            nextDown(x)   )\n *    $(SV  $(INFIN),     real.max  )\n *    $(SV  $(PLUSMN)0.0, -real.min_normal*real.epsilon )\n *    $(SV  -real.max,    -$(INFIN) )\n *    $(SV  -$(INFIN),    -$(INFIN) )\n *    $(SV  $(NAN),       $(NAN)    )\n * )\n */\nreal nextDown(real x) @safe pure nothrow @nogc\n{\n    return -nextUp(-x);\n}\n\n/** ditto */\ndouble nextDown(double x) @safe pure nothrow @nogc\n{\n    return -nextUp(-x);\n}\n\n/** ditto */\nfloat nextDown(float x) @safe pure nothrow @nogc\n{\n    return -nextUp(-x);\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert( nextDown(1.0 + real.epsilon) == 1.0);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended)\n    {\n\n        // Tests for 80-bit reals\n        assert(isIdentical(nextUp(NaN(0xABC)), NaN(0xABC)));\n        // negative numbers\n        assert( nextUp(-real.infinity) == -real.max );\n        assert( nextUp(-1.0L-real.epsilon) == -1.0 );\n        assert( nextUp(-2.0L) == -2.0 + real.epsilon);\n        // subnormals and zero\n        assert( nextUp(-real.min_normal) == -real.min_normal*(1-real.epsilon) );\n        assert( nextUp(-real.min_normal*(1-real.epsilon)) == -real.min_normal*(1-2*real.epsilon) );\n        assert( isIdentical(-0.0L, nextUp(-real.min_normal*real.epsilon)) );\n        assert( nextUp(-0.0L) == real.min_normal*real.epsilon );\n        assert( nextUp(0.0L) == real.min_normal*real.epsilon );\n        assert( nextUp(real.min_normal*(1-real.epsilon)) == real.min_normal );\n        assert( nextUp(real.min_normal) == real.min_normal*(1+real.epsilon) );\n        // positive numbers\n        assert( nextUp(1.0L) == 1.0 + real.epsilon );\n        assert( nextUp(2.0L-real.epsilon) == 2.0 );\n        assert( nextUp(real.max) == real.infinity );\n        assert( nextUp(real.infinity)==real.infinity );\n    }\n\n    double n = NaN(0xABC);\n    assert(isIdentical(nextUp(n), n));\n    // negative numbers\n    assert( nextUp(-double.infinity) == -double.max );\n    assert( nextUp(-1-double.epsilon) == -1.0 );\n    assert( nextUp(-2.0) == -2.0 + double.epsilon);\n    // subnormals and zero\n\n    assert( nextUp(-double.min_normal) == -double.min_normal*(1-double.epsilon) );\n    assert( nextUp(-double.min_normal*(1-double.epsilon)) == -double.min_normal*(1-2*double.epsilon) );\n    assert( isIdentical(-0.0, nextUp(-double.min_normal*double.epsilon)) );\n    assert( nextUp(0.0) == double.min_normal*double.epsilon );\n    assert( nextUp(-0.0) == double.min_normal*double.epsilon );\n    assert( nextUp(double.min_normal*(1-double.epsilon)) == double.min_normal );\n    assert( nextUp(double.min_normal) == double.min_normal*(1+double.epsilon) );\n    // positive numbers\n    assert( nextUp(1.0) == 1.0 + double.epsilon );\n    assert( nextUp(2.0-double.epsilon) == 2.0 );\n    assert( nextUp(double.max) == double.infinity );\n\n    float fn = NaN(0xABC);\n    assert(isIdentical(nextUp(fn), fn));\n    float f = -float.min_normal*(1-float.epsilon);\n    float f1 = -float.min_normal;\n    assert( nextUp(f1) ==  f);\n    f = 1.0f+float.epsilon;\n    f1 = 1.0f;\n    assert( nextUp(f1) == f );\n    f1 = -0.0f;\n    assert( nextUp(f1) == float.min_normal*float.epsilon);\n    assert( nextUp(float.infinity)==float.infinity );\n\n    assert(nextDown(1.0L+real.epsilon)==1.0);\n    assert(nextDown(1.0+double.epsilon)==1.0);\n    f = 1.0f+float.epsilon;\n    assert(nextDown(f)==1.0);\n    assert(nextafter(1.0+real.epsilon, -real.infinity)==1.0);\n}\n\n\n\n/******************************************\n * Calculates the next representable value after x in the direction of y.\n *\n * If y > x, the result will be the next largest floating-point value;\n * if y < x, the result will be the next smallest value.\n * If x == y, the result is y.\n *\n * Remarks:\n * This function is not generally very useful; it's almost always better to use\n * the faster functions nextUp() or nextDown() instead.\n *\n * The FE_INEXACT and FE_OVERFLOW exceptions will be raised if x is finite and\n * the function result is infinite. The FE_INEXACT and FE_UNDERFLOW\n * exceptions will be raised if the function value is subnormal, and x is\n * not equal to y.\n */\nT nextafter(T)(const T x, const T y) @safe pure nothrow @nogc\n{\n    if (x == y) return y;\n    return ((y>x) ? nextUp(x) :  nextDown(x));\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    float a = 1;\n    assert(is(typeof(nextafter(a, a)) == float));\n    assert(nextafter(a, a.infinity) > a);\n\n    double b = 2;\n    assert(is(typeof(nextafter(b, b)) == double));\n    assert(nextafter(b, b.infinity) > b);\n\n    real c = 3;\n    assert(is(typeof(nextafter(c, c)) == real));\n    assert(nextafter(c, c.infinity) > c);\n}\n\n//real nexttoward(real x, real y) { return core.stdc.math.nexttowardl(x, y); }\n\n/**\n * Returns the positive difference between x and y.\n *\n * Equivalent to `fmax(x-y, 0)`.\n *\n * Returns:\n *      $(TABLE_SV\n *      $(TR $(TH x, y)       $(TH fdim(x, y)))\n *      $(TR $(TD x $(GT) y)  $(TD x - y))\n *      $(TR $(TD x $(LT)= y) $(TD +0.0))\n *      )\n */\nreal fdim(real x, real y) @safe pure nothrow @nogc { return (x > y) ? x - y : +0.0; }\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(fdim(2.0, 0.0) == 2.0);\n    assert(fdim(-2.0, 0.0) == 0.0);\n    assert(fdim(real.infinity, 2.0) == real.infinity);\n    assert(fdim(real.nan, 2.0) == 0.0);\n    assert(fdim(2.0, real.nan) == 0.0);\n}\n\n/**\n * Returns the larger of x and y.\n *\n * If one of the arguments is a NaN, the other is returned.\n */\nreal fmax(real x, real y) @safe pure nothrow @nogc\n{\n    return (y > x || isNaN(x)) ? y : x;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(fmax(0.0, 2.0) == 2.0);\n    assert(fmax(-2.0, 0.0) == 0.0);\n    assert(fmax(real.infinity, 2.0) == real.infinity);\n    assert(fmax(real.nan, 2.0) == 2.0);\n    assert(fmax(2.0, real.nan) == 2.0);\n}\n\n/**\n * Returns the smaller of x and y.\n *\n * If one of the arguments is a NaN, the other is returned.\n */\nreal fmin(real x, real y) @safe pure nothrow @nogc\n{\n    return (y < x || isNaN(x)) ? y : x;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(fmin(0.0, 2.0) == 0.0);\n    assert(fmin(-2.0, 0.0) == -2.0);\n    assert(fmin(real.infinity, 2.0) == 2.0);\n    assert(fmin(real.nan, 2.0) == 2.0);\n    assert(fmin(2.0, real.nan) == 2.0);\n}\n\n/**************************************\n * Returns (x * y) + z, rounding only once according to the\n * current rounding mode.\n *\n * BUGS: Not currently implemented - rounds twice.\n */\nreal fma(real x, real y, real z) @safe pure nothrow @nogc { return (x * y) + z; }\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(fma(0.0, 2.0, 2.0) == 2.0);\n    assert(fma(2.0, 2.0, 2.0) == 6.0);\n    assert(fma(real.infinity, 2.0, 2.0) == real.infinity);\n    assert(fma(real.nan, 2.0, 2.0) is real.nan);\n    assert(fma(2.0, 2.0, real.nan) is real.nan);\n}\n\n/**\n * Compute the value of x $(SUPERSCRIPT n), where n is an integer\n */\nUnqual!F pow(F, G)(F x, G n) @nogc @trusted pure nothrow\nif (isFloatingPoint!(F) && isIntegral!(G))\n{\n    import std.traits : Unsigned;\n    real p = 1.0, v = void;\n    Unsigned!(Unqual!G) m = n;\n    if (n < 0)\n    {\n        switch (n)\n        {\n        case -1:\n            return 1 / x;\n        case -2:\n            return 1 / (x * x);\n        default:\n        }\n\n        m = cast(typeof(m))(0 - n);\n        v = p / x;\n    }\n    else\n    {\n        switch (n)\n        {\n        case 0:\n            return 1.0;\n        case 1:\n            return x;\n        case 2:\n            return x * x;\n        default:\n        }\n\n        v = x;\n    }\n\n    while (1)\n    {\n        if (m & 1)\n            p *= v;\n        m >>= 1;\n        if (!m)\n            break;\n        v *= v;\n    }\n    return p;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(pow(2.0, 5) == 32.0);\n    assert(pow(1.5, 9).feqrel(38.4433) > 16);\n    assert(pow(real.nan, 2) is real.nan);\n    assert(pow(real.infinity, 2) == real.infinity);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    // Make sure it instantiates and works properly on immutable values and\n    // with various integer and float types.\n    immutable real x = 46;\n    immutable float xf = x;\n    immutable double xd = x;\n    immutable uint one = 1;\n    immutable ushort two = 2;\n    immutable ubyte three = 3;\n    immutable ulong eight = 8;\n\n    immutable int neg1 = -1;\n    immutable short neg2 = -2;\n    immutable byte neg3 = -3;\n    immutable long neg8 = -8;\n\n\n    assert(pow(x,0) == 1.0);\n    assert(pow(xd,one) == x);\n    assert(pow(xf,two) == x * x);\n    assert(pow(x,three) == x * x * x);\n    assert(pow(x,eight) == (x * x) * (x * x) * (x * x) * (x * x));\n\n    assert(pow(x, neg1) == 1 / x);\n\n    version (X86_64)\n    {\n        pragma(msg, \"test disabled on x86_64, see bug 5628\");\n    }\n    else version (ARM)\n    {\n        pragma(msg, \"test disabled on ARM, see bug 5628\");\n    }\n    else\n    {\n        assert(pow(xd, neg2) == 1 / (x * x));\n        assert(pow(xf, neg8) == 1 / ((x * x) * (x * x) * (x * x) * (x * x)));\n    }\n\n    assert(feqrel(pow(x, neg3),  1 / (x * x * x)) >= real.mant_dig - 1);\n}\n\n@safe @nogc nothrow unittest\n{\n    assert(equalsDigit(pow(2.0L, 10.0L), 1024, 19));\n}\n\n/** Compute the value of an integer x, raised to the power of a positive\n * integer n.\n *\n *  If both x and n are 0, the result is 1.\n *  If n is negative, an integer divide error will occur at runtime,\n * regardless of the value of x.\n */\ntypeof(Unqual!(F).init * Unqual!(G).init) pow(F, G)(F x, G n) @nogc @trusted pure nothrow\nif (isIntegral!(F) && isIntegral!(G))\n{\n    if (n<0) return x/0; // Only support positive powers\n    typeof(return) p, v = void;\n    Unqual!G m = n;\n\n    switch (m)\n    {\n    case 0:\n        p = 1;\n        break;\n\n    case 1:\n        p = x;\n        break;\n\n    case 2:\n        p = x * x;\n        break;\n\n    default:\n        v = x;\n        p = 1;\n        while (1)\n        {\n            if (m & 1)\n                p *= v;\n            m >>= 1;\n            if (!m)\n                break;\n            v *= v;\n        }\n        break;\n    }\n    return p;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    immutable int one = 1;\n    immutable byte two = 2;\n    immutable ubyte three = 3;\n    immutable short four = 4;\n    immutable long ten = 10;\n\n    assert(pow(two, three) == 8);\n    assert(pow(two, ten) == 1024);\n    assert(pow(one, ten) == 1);\n    assert(pow(ten, four) == 10_000);\n    assert(pow(four, 10) == 1_048_576);\n    assert(pow(three, four) == 81);\n\n}\n\n/**Computes integer to floating point powers.*/\nreal pow(I, F)(I x, F y) @nogc @trusted pure nothrow\nif (isIntegral!I && isFloatingPoint!F)\n{\n    return pow(cast(real) x, cast(Unqual!F) y);\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(pow(2, 5.0) == 32.0);\n    assert(pow(7, 3.0) == 343.0);\n    assert(pow(2, real.nan) is real.nan);\n    assert(pow(2, real.infinity) == real.infinity);\n}\n\n/**\n * Calculates x$(SUPERSCRIPT y).\n *\n * $(TABLE_SV\n * $(TR $(TH x) $(TH y) $(TH pow(x, y))\n *      $(TH div 0) $(TH invalid?))\n * $(TR $(TD anything)      $(TD $(PLUSMN)0.0)                $(TD 1.0)\n *      $(TD no)        $(TD no) )\n * $(TR $(TD |x| $(GT) 1)    $(TD +$(INFIN))                  $(TD +$(INFIN))\n *      $(TD no)        $(TD no) )\n * $(TR $(TD |x| $(LT) 1)    $(TD +$(INFIN))                  $(TD +0.0)\n *      $(TD no)        $(TD no) )\n * $(TR $(TD |x| $(GT) 1)    $(TD -$(INFIN))                  $(TD +0.0)\n *      $(TD no)        $(TD no) )\n * $(TR $(TD |x| $(LT) 1)    $(TD -$(INFIN))                  $(TD +$(INFIN))\n *      $(TD no)        $(TD no) )\n * $(TR $(TD +$(INFIN))      $(TD $(GT) 0.0)                  $(TD +$(INFIN))\n *      $(TD no)        $(TD no) )\n * $(TR $(TD +$(INFIN))      $(TD $(LT) 0.0)                  $(TD +0.0)\n *      $(TD no)        $(TD no) )\n * $(TR $(TD -$(INFIN))      $(TD odd integer $(GT) 0.0)      $(TD -$(INFIN))\n *      $(TD no)        $(TD no) )\n * $(TR $(TD -$(INFIN))      $(TD $(GT) 0.0, not odd integer) $(TD +$(INFIN))\n *      $(TD no)        $(TD no))\n * $(TR $(TD -$(INFIN))      $(TD odd integer $(LT) 0.0)      $(TD -0.0)\n *      $(TD no)        $(TD no) )\n * $(TR $(TD -$(INFIN))      $(TD $(LT) 0.0, not odd integer) $(TD +0.0)\n *      $(TD no)        $(TD no) )\n * $(TR $(TD $(PLUSMN)1.0)   $(TD $(PLUSMN)$(INFIN))          $(TD -$(NAN))\n *      $(TD no)        $(TD yes) )\n * $(TR $(TD $(LT) 0.0)      $(TD finite, nonintegral)        $(TD $(NAN))\n *      $(TD no)        $(TD yes))\n * $(TR $(TD $(PLUSMN)0.0)   $(TD odd integer $(LT) 0.0)      $(TD $(PLUSMNINF))\n *      $(TD yes)       $(TD no) )\n * $(TR $(TD $(PLUSMN)0.0)   $(TD $(LT) 0.0, not odd integer) $(TD +$(INFIN))\n *      $(TD yes)       $(TD no))\n * $(TR $(TD $(PLUSMN)0.0)   $(TD odd integer $(GT) 0.0)      $(TD $(PLUSMN)0.0)\n *      $(TD no)        $(TD no) )\n * $(TR $(TD $(PLUSMN)0.0)   $(TD $(GT) 0.0, not odd integer) $(TD +0.0)\n *      $(TD no)        $(TD no) )\n * )\n */\nUnqual!(Largest!(F, G)) pow(F, G)(F x, G y) @nogc @trusted pure nothrow\nif (isFloatingPoint!(F) && isFloatingPoint!(G))\n{\n    alias Float = typeof(return);\n\n    static real impl(real x, real y) @nogc pure nothrow\n    {\n        // Special cases.\n        if (isNaN(y))\n            return y;\n        if (isNaN(x) && y != 0.0)\n            return x;\n\n        // Even if x is NaN.\n        if (y == 0.0)\n            return 1.0;\n        if (y == 1.0)\n            return x;\n\n        if (isInfinity(y))\n        {\n            if (fabs(x) > 1)\n            {\n                if (signbit(y))\n                    return +0.0;\n                else\n                    return F.infinity;\n            }\n            else if (fabs(x) == 1)\n            {\n                return y * 0; // generate NaN.\n            }\n            else // < 1\n            {\n                if (signbit(y))\n                    return F.infinity;\n                else\n                    return +0.0;\n            }\n        }\n        if (isInfinity(x))\n        {\n            if (signbit(x))\n            {\n                long i = cast(long) y;\n                if (y > 0.0)\n                {\n                    if (i == y && i & 1)\n                        return -F.infinity;\n                    else\n                        return F.infinity;\n                }\n                else if (y < 0.0)\n                {\n                    if (i == y && i & 1)\n                        return -0.0;\n                    else\n                        return +0.0;\n                }\n            }\n            else\n            {\n                if (y > 0.0)\n                    return F.infinity;\n                else if (y < 0.0)\n                    return +0.0;\n            }\n        }\n\n        if (x == 0.0)\n        {\n            if (signbit(x))\n            {\n                long i = cast(long) y;\n                if (y > 0.0)\n                {\n                    if (i == y && i & 1)\n                        return -0.0;\n                    else\n                        return +0.0;\n                }\n                else if (y < 0.0)\n                {\n                    if (i == y && i & 1)\n                        return -F.infinity;\n                    else\n                        return F.infinity;\n                }\n            }\n            else\n            {\n                if (y > 0.0)\n                    return +0.0;\n                else if (y < 0.0)\n                    return F.infinity;\n            }\n        }\n        if (x == 1.0)\n            return 1.0;\n\n        if (y >= F.max)\n        {\n            if ((x > 0.0 && x < 1.0) || (x > -1.0 && x < 0.0))\n                return 0.0;\n            if (x > 1.0 || x < -1.0)\n                return F.infinity;\n        }\n        if (y <= -F.max)\n        {\n            if ((x > 0.0 && x < 1.0) || (x > -1.0 && x < 0.0))\n                return F.infinity;\n            if (x > 1.0 || x < -1.0)\n                return 0.0;\n        }\n\n        if (x >= F.max)\n        {\n            if (y > 0.0)\n                return F.infinity;\n            else\n                return 0.0;\n        }\n        if (x <= -F.max)\n        {\n            long i = cast(long) y;\n            if (y > 0.0)\n            {\n                if (i == y && i & 1)\n                    return -F.infinity;\n                else\n                    return F.infinity;\n            }\n            else if (y < 0.0)\n            {\n                if (i == y && i & 1)\n                    return -0.0;\n                else\n                    return +0.0;\n            }\n        }\n\n        // Integer power of x.\n        long iy = cast(long) y;\n        if (iy == y && fabs(y) < 32_768.0)\n            return pow(x, iy);\n\n        real sign = 1.0;\n        if (x < 0)\n        {\n            // Result is real only if y is an integer\n            // Check for a non-zero fractional part\n            enum maxOdd = pow(2.0L, real.mant_dig) - 1.0L;\n            static if (maxOdd > ulong.max)\n            {\n                // Generic method, for any FP type\n                if (floor(y) != y)\n                    return sqrt(x); // Complex result -- create a NaN\n\n                const hy = ldexp(y, -1);\n                if (floor(hy) != hy)\n                    sign = -1.0;\n            }\n            else\n            {\n                // Much faster, if ulong has enough precision\n                const absY = fabs(y);\n                if (absY <= maxOdd)\n                {\n                    const uy = cast(ulong) absY;\n                    if (uy != absY)\n                        return sqrt(x); // Complex result -- create a NaN\n\n                    if (uy & 1)\n                        sign = -1.0;\n                }\n            }\n            x = -x;\n        }\n        version (INLINE_YL2X)\n        {\n            // If x > 0, x ^^ y == 2 ^^ ( y * log2(x) )\n            // TODO: This is not accurate in practice. A fast and accurate\n            // (though complicated) method is described in:\n            // \"An efficient rounding boundary test for pow(x, y)\n            // in double precision\", C.Q. Lauter and V. Lefèvre, INRIA (2007).\n            return sign * exp2( core.math.yl2x(x, y) );\n        }\n        else\n        {\n            // If x > 0, x ^^ y == 2 ^^ ( y * log2(x) )\n            // TODO: This is not accurate in practice. A fast and accurate\n            // (though complicated) method is described in:\n            // \"An efficient rounding boundary test for pow(x, y)\n            // in double precision\", C.Q. Lauter and V. Lefèvre, INRIA (2007).\n            Float w = exp2(y * log2(x));\n            return sign * w;\n        }\n    }\n    return impl(x, y);\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(pow(1.0, 2.0) == 1.0);\n    assert(pow(0.0, 0.0) == 1.0);\n    assert(pow(1.5, 10.0).feqrel(57.665) > 16);\n\n    // special values\n    assert(pow(1.5, real.infinity) == real.infinity);\n    assert(pow(0.5, real.infinity) == 0.0);\n    assert(pow(1.5, -real.infinity) == 0.0);\n    assert(pow(0.5, -real.infinity) == real.infinity);\n    assert(pow(real.infinity, 1.0) == real.infinity);\n    assert(pow(real.infinity, -1.0) == 0.0);\n    assert(pow(-real.infinity, 1.0) == -real.infinity);\n    assert(pow(-real.infinity, 2.0) == real.infinity);\n    assert(pow(-real.infinity, -1.0) == -0.0);\n    assert(pow(-real.infinity, -2.0) == 0.0);\n    assert(pow(1.0, real.infinity) is -real.nan);\n    assert(pow(0.0, -1.0) == real.infinity);\n    assert(pow(real.nan, 0.0) == 1.0);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    // Test all the special values.  These unittests can be run on Windows\n    // by temporarily changing the version (linux) to version (all).\n    immutable float zero = 0;\n    immutable real one = 1;\n    immutable double two = 2;\n    immutable float three = 3;\n    immutable float fnan = float.nan;\n    immutable double dnan = double.nan;\n    immutable real rnan = real.nan;\n    immutable dinf = double.infinity;\n    immutable rninf = -real.infinity;\n\n    assert(pow(fnan, zero) == 1);\n    assert(pow(dnan, zero) == 1);\n    assert(pow(rnan, zero) == 1);\n\n    assert(pow(two, dinf) == double.infinity);\n    assert(isIdentical(pow(0.2f, dinf), +0.0));\n    assert(pow(0.99999999L, rninf) == real.infinity);\n    assert(isIdentical(pow(1.000000001, rninf), +0.0));\n    assert(pow(dinf, 0.001) == dinf);\n    assert(isIdentical(pow(dinf, -0.001), +0.0));\n    assert(pow(rninf, 3.0L) == rninf);\n    assert(pow(rninf, 2.0L) == real.infinity);\n    assert(isIdentical(pow(rninf, -3.0), -0.0));\n    assert(isIdentical(pow(rninf, -2.0), +0.0));\n\n    // @@@BUG@@@ somewhere\n    version (OSX) {} else assert(isNaN(pow(one, dinf)));\n    version (OSX) {} else assert(isNaN(pow(-one, dinf)));\n    assert(isNaN(pow(-0.2, PI)));\n    // boundary cases. Note that epsilon == 2^^-n for some n,\n    // so 1/epsilon == 2^^n is always even.\n    assert(pow(-1.0L, 1/real.epsilon - 1.0L) == -1.0L);\n    assert(pow(-1.0L, 1/real.epsilon) == 1.0L);\n    assert(isNaN(pow(-1.0L, 1/real.epsilon-0.5L)));\n    assert(isNaN(pow(-1.0L, -1/real.epsilon+0.5L)));\n\n    assert(pow(0.0, -3.0) == double.infinity);\n    assert(pow(-0.0, -3.0) == -double.infinity);\n    assert(pow(0.0, -PI) == double.infinity);\n    assert(pow(-0.0, -PI) == double.infinity);\n    assert(isIdentical(pow(0.0, 5.0), 0.0));\n    assert(isIdentical(pow(-0.0, 5.0), -0.0));\n    assert(isIdentical(pow(0.0, 6.0), 0.0));\n    assert(isIdentical(pow(-0.0, 6.0), 0.0));\n\n    // Issue #14786 fixed\n    immutable real maxOdd = pow(2.0L, real.mant_dig) - 1.0L;\n    assert(pow(-1.0L,  maxOdd) == -1.0L);\n    assert(pow(-1.0L, -maxOdd) == -1.0L);\n    assert(pow(-1.0L, maxOdd + 1.0L) == 1.0L);\n    assert(pow(-1.0L, -maxOdd + 1.0L) == 1.0L);\n    assert(pow(-1.0L, maxOdd - 1.0L) == 1.0L);\n    assert(pow(-1.0L, -maxOdd - 1.0L) == 1.0L);\n\n    // Now, actual numbers.\n    assert(approxEqual(pow(two, three), 8.0));\n    assert(approxEqual(pow(two, -2.5), 0.1767767));\n\n    // Test integer to float power.\n    immutable uint twoI = 2;\n    assert(approxEqual(pow(twoI, three), 8.0));\n}\n\n/** Computes the value of a positive integer `x`, raised to the power `n`, modulo `m`.\n *\n *  Params:\n *      x = base\n *      n = exponent\n *      m = modulus\n *\n *  Returns:\n *      `x` to the power `n`, modulo `m`.\n *      The return type is the largest of `x`'s and `m`'s type.\n *\n * The function requires that all values have unsigned types.\n */\nUnqual!(Largest!(F, H)) powmod(F, G, H)(F x, G n, H m)\nif (isUnsigned!F && isUnsigned!G && isUnsigned!H)\n{\n    import std.meta : AliasSeq;\n\n    alias T = Unqual!(Largest!(F, H));\n    static if (T.sizeof <= 4)\n    {\n        alias DoubleT = AliasSeq!(void, ushort, uint, void, ulong)[T.sizeof];\n    }\n\n    static T mulmod(T a, T b, T c)\n    {\n        static if (T.sizeof == 8)\n        {\n            static T addmod(T a, T b, T c)\n            {\n                b = c - b;\n                if (a >= b)\n                    return a - b;\n                else\n                    return c - b + a;\n            }\n\n            T result = 0, tmp;\n\n            b %= c;\n            while (a > 0)\n            {\n                if (a & 1)\n                    result = addmod(result, b, c);\n\n                a >>= 1;\n                b = addmod(b, b, c);\n            }\n\n            return result;\n        }\n        else\n        {\n            DoubleT result = cast(DoubleT) (cast(DoubleT) a * cast(DoubleT) b);\n            return result % c;\n        }\n    }\n\n    T base = x, result = 1, modulus = m;\n    Unqual!G exponent = n;\n\n    while (exponent > 0)\n    {\n        if (exponent & 1)\n            result = mulmod(result, base, modulus);\n\n        base = mulmod(base, base, modulus);\n        exponent >>= 1;\n    }\n\n    return result;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(powmod(1U, 10U, 3U) == 1);\n    assert(powmod(3U, 2U, 6U) == 3);\n    assert(powmod(5U, 5U, 15U) == 5);\n    assert(powmod(2U, 3U, 5U) == 3);\n    assert(powmod(2U, 4U, 5U) == 1);\n    assert(powmod(2U, 5U, 5U) == 2);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    ulong a = 18446744073709551615u, b = 20u, c = 18446744073709551610u;\n    assert(powmod(a, b, c) == 95367431640625u);\n    a = 100; b = 7919; c = 18446744073709551557u;\n    assert(powmod(a, b, c) == 18223853583554725198u);\n    a = 117; b = 7919; c = 18446744073709551557u;\n    assert(powmod(a, b, c) == 11493139548346411394u);\n    a = 134; b = 7919; c = 18446744073709551557u;\n    assert(powmod(a, b, c) == 10979163786734356774u);\n    a = 151; b = 7919; c = 18446744073709551557u;\n    assert(powmod(a, b, c) == 7023018419737782840u);\n    a = 168; b = 7919; c = 18446744073709551557u;\n    assert(powmod(a, b, c) == 58082701842386811u);\n    a = 185; b = 7919; c = 18446744073709551557u;\n    assert(powmod(a, b, c) == 17423478386299876798u);\n    a = 202; b = 7919; c = 18446744073709551557u;\n    assert(powmod(a, b, c) == 5522733478579799075u);\n    a = 219; b = 7919; c = 18446744073709551557u;\n    assert(powmod(a, b, c) == 15230218982491623487u);\n    a = 236; b = 7919; c = 18446744073709551557u;\n    assert(powmod(a, b, c) == 5198328724976436000u);\n\n    a = 0; b = 7919; c = 18446744073709551557u;\n    assert(powmod(a, b, c) == 0);\n    a = 123; b = 0; c = 18446744073709551557u;\n    assert(powmod(a, b, c) == 1);\n\n    immutable ulong a1 = 253, b1 = 7919, c1 = 18446744073709551557u;\n    assert(powmod(a1, b1, c1) == 3883707345459248860u);\n\n    uint x = 100 ,y = 7919, z = 1844674407u;\n    assert(powmod(x, y, z) == 1613100340u);\n    x = 134; y = 7919; z = 1844674407u;\n    assert(powmod(x, y, z) == 734956622u);\n    x = 151; y = 7919; z = 1844674407u;\n    assert(powmod(x, y, z) == 1738696945u);\n    x = 168; y = 7919; z = 1844674407u;\n    assert(powmod(x, y, z) == 1247580927u);\n    x = 185; y = 7919; z = 1844674407u;\n    assert(powmod(x, y, z) == 1293855176u);\n    x = 202; y = 7919; z = 1844674407u;\n    assert(powmod(x, y, z) == 1566963682u);\n    x = 219; y = 7919; z = 1844674407u;\n    assert(powmod(x, y, z) == 181227807u);\n    x = 236; y = 7919; z = 1844674407u;\n    assert(powmod(x, y, z) == 217988321u);\n    x = 253; y = 7919; z = 1844674407u;\n    assert(powmod(x, y, z) == 1588843243u);\n\n    x = 0; y = 7919; z = 184467u;\n    assert(powmod(x, y, z) == 0);\n    x = 123; y = 0; z = 1844674u;\n    assert(powmod(x, y, z) == 1);\n\n    immutable ubyte x1 = 117;\n    immutable uint y1 = 7919;\n    immutable uint z1 = 1844674407u;\n    auto res = powmod(x1, y1, z1);\n    assert(is(typeof(res) == uint));\n    assert(res == 9479781u);\n\n    immutable ushort x2 = 123;\n    immutable uint y2 = 203;\n    immutable ubyte z2 = 113;\n    auto res2 = powmod(x2, y2, z2);\n    assert(is(typeof(res2) == ushort));\n    assert(res2 == 42u);\n}\n\n/**************************************\n * To what precision is x equal to y?\n *\n * Returns: the number of mantissa bits which are equal in x and y.\n * eg, 0x1.F8p+60 and 0x1.F1p+60 are equal to 5 bits of precision.\n *\n *      $(TABLE_SV\n *      $(TR $(TH x)      $(TH y)          $(TH feqrel(x, y)))\n *      $(TR $(TD x)      $(TD x)          $(TD real.mant_dig))\n *      $(TR $(TD x)      $(TD $(GT)= 2*x) $(TD 0))\n *      $(TR $(TD x)      $(TD $(LT)= x/2) $(TD 0))\n *      $(TR $(TD $(NAN)) $(TD any)        $(TD 0))\n *      $(TR $(TD any)    $(TD $(NAN))     $(TD 0))\n *      )\n */\nint feqrel(X)(const X x, const X y) @trusted pure nothrow @nogc\nif (isFloatingPoint!(X))\n{\n    /* Public Domain. Author: Don Clugston, 18 Aug 2005.\n     */\n    alias F = floatTraits!(X);\n    static if (F.realFormat == RealFormat.ieeeSingle\n            || F.realFormat == RealFormat.ieeeDouble\n            || F.realFormat == RealFormat.ieeeExtended\n            || F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        if (x == y)\n            return X.mant_dig; // ensure diff != 0, cope with INF.\n\n        Unqual!X diff = fabs(x - y);\n\n        ushort *pa = cast(ushort *)(&x);\n        ushort *pb = cast(ushort *)(&y);\n        ushort *pd = cast(ushort *)(&diff);\n\n\n        // The difference in abs(exponent) between x or y and abs(x-y)\n        // is equal to the number of significand bits of x which are\n        // equal to y. If negative, x and y have different exponents.\n        // If positive, x and y are equal to 'bitsdiff' bits.\n        // AND with 0x7FFF to form the absolute value.\n        // To avoid out-by-1 errors, we subtract 1 so it rounds down\n        // if the exponents were different. This means 'bitsdiff' is\n        // always 1 lower than we want, except that if bitsdiff == 0,\n        // they could have 0 or 1 bits in common.\n\n        int bitsdiff = (((  (pa[F.EXPPOS_SHORT] & F.EXPMASK)\n                          + (pb[F.EXPPOS_SHORT] & F.EXPMASK)\n                          - (1 << F.EXPSHIFT)) >> 1)\n                        - (pd[F.EXPPOS_SHORT] & F.EXPMASK)) >> F.EXPSHIFT;\n        if ( (pd[F.EXPPOS_SHORT] & F.EXPMASK) == 0)\n        {   // Difference is subnormal\n            // For subnormals, we need to add the number of zeros that\n            // lie at the start of diff's significand.\n            // We do this by multiplying by 2^^real.mant_dig\n            diff *= F.RECIP_EPSILON;\n            return bitsdiff + X.mant_dig - ((pd[F.EXPPOS_SHORT] & F.EXPMASK) >> F.EXPSHIFT);\n        }\n\n        if (bitsdiff > 0)\n            return bitsdiff + 1; // add the 1 we subtracted before\n\n        // Avoid out-by-1 errors when factor is almost 2.\n        if (bitsdiff == 0\n            && ((pa[F.EXPPOS_SHORT] ^ pb[F.EXPPOS_SHORT]) & F.EXPMASK) == 0)\n        {\n            return 1;\n        } else return 0;\n    }\n    else\n    {\n        static assert(false, \"Not implemented for this architecture\");\n    }\n}\n\n///\n@safe pure unittest\n{\n    assert(feqrel(2.0, 2.0) == 53);\n    assert(feqrel(2.0f, 2.0f) == 24);\n    assert(feqrel(2.0, double.nan) == 0);\n\n    // Test that numbers are within n digits of each\n    // other by testing if feqrel > n * log2(10)\n\n    // five digits\n    assert(feqrel(2.0, 2.00001) > 16);\n    // ten digits\n    assert(feqrel(2.0, 2.00000000001) > 33);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    void testFeqrel(F)()\n    {\n       // Exact equality\n       assert(feqrel(F.max, F.max) == F.mant_dig);\n       assert(feqrel!(F)(0.0, 0.0) == F.mant_dig);\n       assert(feqrel(F.infinity, F.infinity) == F.mant_dig);\n\n       // a few bits away from exact equality\n       F w=1;\n       for (int i = 1; i < F.mant_dig - 1; ++i)\n       {\n          assert(feqrel!(F)(1.0 + w * F.epsilon, 1.0) == F.mant_dig-i);\n          assert(feqrel!(F)(1.0 - w * F.epsilon, 1.0) == F.mant_dig-i);\n          assert(feqrel!(F)(1.0, 1 + (w-1) * F.epsilon) == F.mant_dig - i + 1);\n          w*=2;\n       }\n\n       assert(feqrel!(F)(1.5+F.epsilon, 1.5) == F.mant_dig-1);\n       assert(feqrel!(F)(1.5-F.epsilon, 1.5) == F.mant_dig-1);\n       assert(feqrel!(F)(1.5-F.epsilon, 1.5+F.epsilon) == F.mant_dig-2);\n\n\n       // Numbers that are close\n       assert(feqrel!(F)(0x1.Bp+84, 0x1.B8p+84) == 5);\n       assert(feqrel!(F)(0x1.8p+10, 0x1.Cp+10) == 2);\n       assert(feqrel!(F)(1.5 * (1 - F.epsilon), 1.0L) == 2);\n       assert(feqrel!(F)(1.5, 1.0) == 1);\n       assert(feqrel!(F)(2 * (1 - F.epsilon), 1.0L) == 1);\n\n       // Factors of 2\n       assert(feqrel(F.max, F.infinity) == 0);\n       assert(feqrel!(F)(2 * (1 - F.epsilon), 1.0L) == 1);\n       assert(feqrel!(F)(1.0, 2.0) == 0);\n       assert(feqrel!(F)(4.0, 1.0) == 0);\n\n       // Extreme inequality\n       assert(feqrel(F.nan, F.nan) == 0);\n       assert(feqrel!(F)(0.0L, -F.nan) == 0);\n       assert(feqrel(F.nan, F.infinity) == 0);\n       assert(feqrel(F.infinity, -F.infinity) == 0);\n       assert(feqrel(F.max, -F.max) == 0);\n\n       assert(feqrel(F.min_normal / 8, F.min_normal / 17) == 3);\n\n       const F Const = 2;\n       immutable F Immutable = 2;\n       auto Compiles = feqrel(Const, Immutable);\n    }\n\n    assert(feqrel(7.1824L, 7.1824L) == real.mant_dig);\n\n    testFeqrel!(real)();\n    testFeqrel!(double)();\n    testFeqrel!(float)();\n}\n\npackage: // Not public yet\n/* Return the value that lies halfway between x and y on the IEEE number line.\n *\n * Formally, the result is the arithmetic mean of the binary significands of x\n * and y, multiplied by the geometric mean of the binary exponents of x and y.\n * x and y must have the same sign, and must not be NaN.\n * Note: this function is useful for ensuring O(log n) behaviour in algorithms\n * involving a 'binary chop'.\n *\n * Special cases:\n * If x and y are within a factor of 2, (ie, feqrel(x, y) > 0), the return value\n * is the arithmetic mean (x + y) / 2.\n * If x and y are even powers of 2, the return value is the geometric mean,\n *   ieeeMean(x, y) = sqrt(x * y).\n *\n */\nT ieeeMean(T)(const T x, const T y)  @trusted pure nothrow @nogc\nin\n{\n    // both x and y must have the same sign, and must not be NaN.\n    assert(signbit(x) == signbit(y));\n    assert(x == x && y == y);\n}\ndo\n{\n    // Runtime behaviour for contract violation:\n    // If signs are opposite, or one is a NaN, return 0.\n    if (!((x >= 0 && y >= 0) || (x <= 0 && y <= 0))) return 0.0;\n\n    // The implementation is simple: cast x and y to integers,\n    // average them (avoiding overflow), and cast the result back to a floating-point number.\n\n    alias F = floatTraits!(T);\n    T u;\n    static if (F.realFormat == RealFormat.ieeeExtended)\n    {\n        // There's slight additional complexity because they are actually\n        // 79-bit reals...\n        ushort *ue = cast(ushort *)&u;\n        ulong *ul = cast(ulong *)&u;\n        ushort *xe = cast(ushort *)&x;\n        ulong *xl = cast(ulong *)&x;\n        ushort *ye = cast(ushort *)&y;\n        ulong *yl = cast(ulong *)&y;\n\n        // Ignore the useless implicit bit. (Bonus: this prevents overflows)\n        ulong m = ((*xl) & 0x7FFF_FFFF_FFFF_FFFFL) + ((*yl) & 0x7FFF_FFFF_FFFF_FFFFL);\n\n        // @@@ BUG? @@@\n        // Cast shouldn't be here\n        ushort e = cast(ushort) ((xe[F.EXPPOS_SHORT] & F.EXPMASK)\n                                 + (ye[F.EXPPOS_SHORT] & F.EXPMASK));\n        if (m & 0x8000_0000_0000_0000L)\n        {\n            ++e;\n            m &= 0x7FFF_FFFF_FFFF_FFFFL;\n        }\n        // Now do a multi-byte right shift\n        const uint c = e & 1; // carry\n        e >>= 1;\n        m >>>= 1;\n        if (c)\n            m |= 0x4000_0000_0000_0000L; // shift carry into significand\n        if (e)\n            *ul = m | 0x8000_0000_0000_0000L; // set implicit bit...\n        else\n            *ul = m; // ... unless exponent is 0 (subnormal or zero).\n\n        ue[4]= e | (xe[F.EXPPOS_SHORT]& 0x8000); // restore sign bit\n    }\n    else static if (F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        // This would be trivial if 'ucent' were implemented...\n        ulong *ul = cast(ulong *)&u;\n        ulong *xl = cast(ulong *)&x;\n        ulong *yl = cast(ulong *)&y;\n\n        // Multi-byte add, then multi-byte right shift.\n        import core.checkedint : addu;\n        bool carry;\n        ulong ml = addu(xl[MANTISSA_LSB], yl[MANTISSA_LSB], carry);\n\n        ulong mh = carry + (xl[MANTISSA_MSB] & 0x7FFF_FFFF_FFFF_FFFFL) +\n            (yl[MANTISSA_MSB] & 0x7FFF_FFFF_FFFF_FFFFL);\n\n        ul[MANTISSA_MSB] = (mh >>> 1) | (xl[MANTISSA_MSB] & 0x8000_0000_0000_0000);\n        ul[MANTISSA_LSB] = (ml >>> 1) | (mh & 1) << 63;\n    }\n    else static if (F.realFormat == RealFormat.ieeeDouble)\n    {\n        ulong *ul = cast(ulong *)&u;\n        ulong *xl = cast(ulong *)&x;\n        ulong *yl = cast(ulong *)&y;\n        ulong m = (((*xl) & 0x7FFF_FFFF_FFFF_FFFFL)\n                   + ((*yl) & 0x7FFF_FFFF_FFFF_FFFFL)) >>> 1;\n        m |= ((*xl) & 0x8000_0000_0000_0000L);\n        *ul = m;\n    }\n    else static if (F.realFormat == RealFormat.ieeeSingle)\n    {\n        uint *ul = cast(uint *)&u;\n        uint *xl = cast(uint *)&x;\n        uint *yl = cast(uint *)&y;\n        uint m = (((*xl) & 0x7FFF_FFFF) + ((*yl) & 0x7FFF_FFFF)) >>> 1;\n        m |= ((*xl) & 0x8000_0000);\n        *ul = m;\n    }\n    else\n    {\n        assert(0, \"Not implemented\");\n    }\n    return u;\n}\n\n@safe pure nothrow @nogc unittest\n{\n    assert(ieeeMean(-0.0,-1e-20)<0);\n    assert(ieeeMean(0.0,1e-20)>0);\n\n    assert(ieeeMean(1.0L,4.0L)==2L);\n    assert(ieeeMean(2.0*1.013,8.0*1.013)==4*1.013);\n    assert(ieeeMean(-1.0L,-4.0L)==-2L);\n    assert(ieeeMean(-1.0,-4.0)==-2);\n    assert(ieeeMean(-1.0f,-4.0f)==-2f);\n    assert(ieeeMean(-1.0,-2.0)==-1.5);\n    assert(ieeeMean(-1*(1+8*real.epsilon),-2*(1+8*real.epsilon))\n                 ==-1.5*(1+5*real.epsilon));\n    assert(ieeeMean(0x1p60,0x1p-10)==0x1p25);\n\n    static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended)\n    {\n      assert(ieeeMean(1.0L,real.infinity)==0x1p8192L);\n      assert(ieeeMean(0.0L,real.infinity)==1.5);\n    }\n    assert(ieeeMean(0.5*real.min_normal*(1-4*real.epsilon),0.5*real.min_normal)\n           == 0.5*real.min_normal*(1-2*real.epsilon));\n}\n\npublic:\n\n\n/***********************************\n * Evaluate polynomial A(x) = $(SUB a, 0) + $(SUB a, 1)x + $(SUB a, 2)$(POWER x,2)\n *                          + $(SUB a,3)$(POWER x,3); ...\n *\n * Uses Horner's rule A(x) = $(SUB a, 0) + x($(SUB a, 1) + x($(SUB a, 2)\n *                         + x($(SUB a, 3) + ...)))\n * Params:\n *      x =     the value to evaluate.\n *      A =     array of coefficients $(SUB a, 0), $(SUB a, 1), etc.\n */\nUnqual!(CommonType!(T1, T2)) poly(T1, T2)(T1 x, in T2[] A) @trusted pure nothrow @nogc\nif (isFloatingPoint!T1 && isFloatingPoint!T2)\nin\n{\n    assert(A.length > 0);\n}\ndo\n{\n    static if (is(Unqual!T2 == real))\n    {\n        return polyImpl(x, A);\n    }\n    else\n    {\n        return polyImplBase(x, A);\n    }\n}\n\n/// ditto\nUnqual!(CommonType!(T1, T2)) poly(T1, T2, int N)(T1 x, ref const T2[N] A) @safe pure nothrow @nogc\nif (isFloatingPoint!T1 && isFloatingPoint!T2 && N > 0 && N <= 10)\n{\n    // statically unrolled version for up to 10 coefficients\n    typeof(return) r = A[N - 1];\n    static foreach (i; 1 .. N)\n    {\n        r *= x;\n        r += A[N - 1 - i];\n    }\n    return r;\n}\n\n///\n@safe nothrow @nogc unittest\n{\n    real x = 3.1;\n    static real[] pp = [56.1, 32.7, 6];\n\n    assert(poly(x, pp) == (56.1L + (32.7L + 6.0L * x) * x));\n}\n\n@safe nothrow @nogc unittest\n{\n    double x = 3.1;\n    static double[] pp = [56.1, 32.7, 6];\n    double y = x;\n    y *= 6.0;\n    y += 32.7;\n    y *= x;\n    y += 56.1;\n    assert(poly(x, pp) == y);\n}\n\n@safe unittest\n{\n    static assert(poly(3.0, [1.0, 2.0, 3.0]) == 34);\n}\n\nprivate Unqual!(CommonType!(T1, T2)) polyImplBase(T1, T2)(T1 x, in T2[] A) @trusted pure nothrow @nogc\nif (isFloatingPoint!T1 && isFloatingPoint!T2)\n{\n    ptrdiff_t i = A.length - 1;\n    typeof(return) r = A[i];\n    while (--i >= 0)\n    {\n        r *= x;\n        r += A[i];\n    }\n    return r;\n}\n\nprivate real polyImpl(real x, in real[] A) @trusted pure nothrow @nogc\n{\n    version (D_InlineAsm_X86)\n    {\n        if (__ctfe)\n        {\n            return polyImplBase(x, A);\n        }\n        version (Windows)\n        {\n        // BUG: This code assumes a frame pointer in EBP.\n            asm pure nothrow @nogc // assembler by W. Bright\n            {\n                // EDX = (A.length - 1) * real.sizeof\n                mov     ECX,A[EBP]              ; // ECX = A.length\n                dec     ECX                     ;\n                lea     EDX,[ECX][ECX*8]        ;\n                add     EDX,ECX                 ;\n                add     EDX,A+4[EBP]            ;\n                fld     real ptr [EDX]          ; // ST0 = coeff[ECX]\n                jecxz   return_ST               ;\n                fld     x[EBP]                  ; // ST0 = x\n                fxch    ST(1)                   ; // ST1 = x, ST0 = r\n                align   4                       ;\n        L2:     fmul    ST,ST(1)                ; // r *= x\n                fld     real ptr -10[EDX]       ;\n                sub     EDX,10                  ; // deg--\n                faddp   ST(1),ST                ;\n                dec     ECX                     ;\n                jne     L2                      ;\n                fxch    ST(1)                   ; // ST1 = r, ST0 = x\n                fstp    ST(0)                   ; // dump x\n                align   4                       ;\n        return_ST:                              ;\n                ;\n            }\n        }\n        else version (linux)\n        {\n            asm pure nothrow @nogc // assembler by W. Bright\n            {\n                // EDX = (A.length - 1) * real.sizeof\n                mov     ECX,A[EBP]              ; // ECX = A.length\n                dec     ECX                     ;\n                lea     EDX,[ECX*8]             ;\n                lea     EDX,[EDX][ECX*4]        ;\n                add     EDX,A+4[EBP]            ;\n                fld     real ptr [EDX]          ; // ST0 = coeff[ECX]\n                jecxz   return_ST               ;\n                fld     x[EBP]                  ; // ST0 = x\n                fxch    ST(1)                   ; // ST1 = x, ST0 = r\n                align   4                       ;\n        L2:     fmul    ST,ST(1)                ; // r *= x\n                fld     real ptr -12[EDX]       ;\n                sub     EDX,12                  ; // deg--\n                faddp   ST(1),ST                ;\n                dec     ECX                     ;\n                jne     L2                      ;\n                fxch    ST(1)                   ; // ST1 = r, ST0 = x\n                fstp    ST(0)                   ; // dump x\n                align   4                       ;\n        return_ST:                              ;\n                ;\n            }\n        }\n        else version (OSX)\n        {\n            asm pure nothrow @nogc // assembler by W. Bright\n            {\n                // EDX = (A.length - 1) * real.sizeof\n                mov     ECX,A[EBP]              ; // ECX = A.length\n                dec     ECX                     ;\n                lea     EDX,[ECX*8]             ;\n                add     EDX,EDX                 ;\n                add     EDX,A+4[EBP]            ;\n                fld     real ptr [EDX]          ; // ST0 = coeff[ECX]\n                jecxz   return_ST               ;\n                fld     x[EBP]                  ; // ST0 = x\n                fxch    ST(1)                   ; // ST1 = x, ST0 = r\n                align   4                       ;\n        L2:     fmul    ST,ST(1)                ; // r *= x\n                fld     real ptr -16[EDX]       ;\n                sub     EDX,16                  ; // deg--\n                faddp   ST(1),ST                ;\n                dec     ECX                     ;\n                jne     L2                      ;\n                fxch    ST(1)                   ; // ST1 = r, ST0 = x\n                fstp    ST(0)                   ; // dump x\n                align   4                       ;\n        return_ST:                              ;\n                ;\n            }\n        }\n        else version (FreeBSD)\n        {\n            asm pure nothrow @nogc // assembler by W. Bright\n            {\n                // EDX = (A.length - 1) * real.sizeof\n                mov     ECX,A[EBP]              ; // ECX = A.length\n                dec     ECX                     ;\n                lea     EDX,[ECX*8]             ;\n                lea     EDX,[EDX][ECX*4]        ;\n                add     EDX,A+4[EBP]            ;\n                fld     real ptr [EDX]          ; // ST0 = coeff[ECX]\n                jecxz   return_ST               ;\n                fld     x[EBP]                  ; // ST0 = x\n                fxch    ST(1)                   ; // ST1 = x, ST0 = r\n                align   4                       ;\n        L2:     fmul    ST,ST(1)                ; // r *= x\n                fld     real ptr -12[EDX]       ;\n                sub     EDX,12                  ; // deg--\n                faddp   ST(1),ST                ;\n                dec     ECX                     ;\n                jne     L2                      ;\n                fxch    ST(1)                   ; // ST1 = r, ST0 = x\n                fstp    ST(0)                   ; // dump x\n                align   4                       ;\n        return_ST:                              ;\n                ;\n            }\n        }\n        else version (Solaris)\n        {\n            asm pure nothrow @nogc // assembler by W. Bright\n            {\n                // EDX = (A.length - 1) * real.sizeof\n                mov     ECX,A[EBP]              ; // ECX = A.length\n                dec     ECX                     ;\n                lea     EDX,[ECX*8]             ;\n                lea     EDX,[EDX][ECX*4]        ;\n                add     EDX,A+4[EBP]            ;\n                fld     real ptr [EDX]          ; // ST0 = coeff[ECX]\n                jecxz   return_ST               ;\n                fld     x[EBP]                  ; // ST0 = x\n                fxch    ST(1)                   ; // ST1 = x, ST0 = r\n                align   4                       ;\n        L2:     fmul    ST,ST(1)                ; // r *= x\n                fld     real ptr -12[EDX]       ;\n                sub     EDX,12                  ; // deg--\n                faddp   ST(1),ST                ;\n                dec     ECX                     ;\n                jne     L2                      ;\n                fxch    ST(1)                   ; // ST1 = r, ST0 = x\n                fstp    ST(0)                   ; // dump x\n                align   4                       ;\n        return_ST:                              ;\n                ;\n            }\n        }\n        else version (DragonFlyBSD)\n        {\n            asm pure nothrow @nogc // assembler by W. Bright\n            {\n                // EDX = (A.length - 1) * real.sizeof\n                mov     ECX,A[EBP]              ; // ECX = A.length\n                dec     ECX                     ;\n                lea     EDX,[ECX*8]             ;\n                lea     EDX,[EDX][ECX*4]        ;\n                add     EDX,A+4[EBP]            ;\n                fld     real ptr [EDX]          ; // ST0 = coeff[ECX]\n                jecxz   return_ST               ;\n                fld     x[EBP]                  ; // ST0 = x\n                fxch    ST(1)                   ; // ST1 = x, ST0 = r\n                align   4                       ;\n        L2:     fmul    ST,ST(1)                ; // r *= x\n                fld     real ptr -12[EDX]       ;\n                sub     EDX,12                  ; // deg--\n                faddp   ST(1),ST                ;\n                dec     ECX                     ;\n                jne     L2                      ;\n                fxch    ST(1)                   ; // ST1 = r, ST0 = x\n                fstp    ST(0)                   ; // dump x\n                align   4                       ;\n        return_ST:                              ;\n                ;\n            }\n        }\n        else\n        {\n            static assert(0);\n        }\n    }\n    else\n    {\n        return polyImplBase(x, A);\n    }\n}\n\n\n/**\n   Computes whether two values are approximately equal, admitting a maximum\n   relative difference, and a maximum absolute difference.\n\n   Params:\n        lhs = First item to compare.\n        rhs = Second item to compare.\n        maxRelDiff = Maximum allowable difference relative to `rhs`.\n        Defaults to `1e-2`.\n        maxAbsDiff = Maximum absolute difference. Defaults to `1e-5`.\n\n   Returns:\n       `true` if the two items are approximately equal under either criterium.\n       If one item is a range, and the other is a single value, then the result\n       is the logical and-ing of calling `approxEqual` on each element of the\n       ranged item against the single item. If both items are ranges, then\n       `approxEqual` returns `true` if and only if the ranges have the same\n       number of elements and if `approxEqual` evaluates to `true` for each\n       pair of elements.\n\n    See_Also:\n        Use $(LREF feqrel) to get the number of equal bits in the mantissa.\n */\nbool approxEqual(T, U, V)(T lhs, U rhs, V maxRelDiff, V maxAbsDiff = 1e-5)\n{\n    import std.range.primitives : empty, front, isInputRange, popFront;\n    static if (isInputRange!T)\n    {\n        static if (isInputRange!U)\n        {\n            // Two ranges\n            for (;; lhs.popFront(), rhs.popFront())\n            {\n                if (lhs.empty) return rhs.empty;\n                if (rhs.empty) return lhs.empty;\n                if (!approxEqual(lhs.front, rhs.front, maxRelDiff, maxAbsDiff))\n                    return false;\n            }\n        }\n        else static if (isIntegral!U)\n        {\n            // convert rhs to real\n            return approxEqual(lhs, real(rhs), maxRelDiff, maxAbsDiff);\n        }\n        else\n        {\n            // lhs is range, rhs is number\n            for (; !lhs.empty; lhs.popFront())\n            {\n                if (!approxEqual(lhs.front, rhs, maxRelDiff, maxAbsDiff))\n                    return false;\n            }\n            return true;\n        }\n    }\n    else\n    {\n        static if (isInputRange!U)\n        {\n            // lhs is number, rhs is range\n            for (; !rhs.empty; rhs.popFront())\n            {\n                if (!approxEqual(lhs, rhs.front, maxRelDiff, maxAbsDiff))\n                    return false;\n            }\n            return true;\n        }\n        else static if (isIntegral!T || isIntegral!U)\n        {\n            // convert both lhs and rhs to real\n            return approxEqual(real(lhs), real(rhs), maxRelDiff, maxAbsDiff);\n        }\n        else\n        {\n            // two numbers\n            //static assert(is(T : real) && is(U : real));\n            if (rhs == 0)\n            {\n                return fabs(lhs) <= maxAbsDiff;\n            }\n            static if (is(typeof(lhs.infinity)) && is(typeof(rhs.infinity)))\n            {\n                if (lhs == lhs.infinity && rhs == rhs.infinity ||\n                    lhs == -lhs.infinity && rhs == -rhs.infinity) return true;\n            }\n            return fabs((lhs - rhs) / rhs) <= maxRelDiff\n                || maxAbsDiff != 0 && fabs(lhs - rhs) <= maxAbsDiff;\n        }\n    }\n}\n\n/// ditto\nbool approxEqual(T, U)(T lhs, U rhs)\n{\n    return approxEqual(lhs, rhs, 1e-2, 1e-5);\n}\n\n///\n@safe pure nothrow unittest\n{\n    assert(approxEqual(1.0, 1.0099));\n    assert(!approxEqual(1.0, 1.011));\n    float[] arr1 = [ 1.0, 2.0, 3.0 ];\n    double[] arr2 = [ 1.001, 1.999, 3 ];\n    assert(approxEqual(arr1, arr2));\n\n    real num = real.infinity;\n    assert(num == real.infinity);  // Passes.\n    assert(approxEqual(num, real.infinity));  // Fails.\n    num = -real.infinity;\n    assert(num == -real.infinity);  // Passes.\n    assert(approxEqual(num, -real.infinity));  // Fails.\n\n    assert(!approxEqual(3, 0));\n    assert(approxEqual(3, 3));\n    assert(approxEqual(3.0, 3));\n    assert(approxEqual([3, 3, 3], 3.0));\n    assert(approxEqual([3.0, 3.0, 3.0], 3));\n    int a = 10;\n    assert(approxEqual(10, a));\n}\n\n@safe pure nothrow @nogc unittest\n{\n    real num = real.infinity;\n    assert(num == real.infinity);  // Passes.\n    assert(approxEqual(num, real.infinity));  // Fails.\n}\n\n\n@safe pure nothrow @nogc unittest\n{\n    float f = sqrt(2.0f);\n    assert(fabs(f * f - 2.0f) < .00001);\n\n    double d = sqrt(2.0);\n    assert(fabs(d * d - 2.0) < .00001);\n\n    real r = sqrt(2.0L);\n    assert(fabs(r * r - 2.0) < .00001);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    float f = fabs(-2.0f);\n    assert(f == 2);\n\n    double d = fabs(-2.0);\n    assert(d == 2);\n\n    real r = fabs(-2.0L);\n    assert(r == 2);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    float f = sin(-2.0f);\n    assert(fabs(f - -0.909297f) < .00001);\n\n    double d = sin(-2.0);\n    assert(fabs(d - -0.909297f) < .00001);\n\n    real r = sin(-2.0L);\n    assert(fabs(r - -0.909297f) < .00001);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    float f = cos(-2.0f);\n    assert(fabs(f - -0.416147f) < .00001);\n\n    double d = cos(-2.0);\n    assert(fabs(d - -0.416147f) < .00001);\n\n    real r = cos(-2.0L);\n    assert(fabs(r - -0.416147f) < .00001);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    float f = tan(-2.0f);\n    assert(fabs(f - 2.18504f) < .00001);\n\n    double d = tan(-2.0);\n    assert(fabs(d - 2.18504f) < .00001);\n\n    real r = tan(-2.0L);\n    assert(fabs(r - 2.18504f) < .00001);\n\n    // Verify correct behavior for large inputs\n    assert(!isNaN(tan(0x1p63)));\n    assert(!isNaN(tan(-0x1p63)));\n    static if (real.mant_dig >= 64)\n    {\n        assert(!isNaN(tan(0x1p300L)));\n        assert(!isNaN(tan(-0x1p300L)));\n    }\n}\n\n@safe pure nothrow unittest\n{\n    // issue 6381: floor/ceil should be usable in pure function.\n    auto x = floor(1.2);\n    auto y = ceil(1.2);\n}\n\n@safe pure nothrow unittest\n{\n    // relative comparison depends on rhs, make sure proper side is used when\n    // comparing range to single value. Based on bugzilla issue 15763\n    auto a = [2e-3 - 1e-5];\n    auto b = 2e-3 + 1e-5;\n    assert(a[0].approxEqual(b));\n    assert(!b.approxEqual(a[0]));\n    assert(a.approxEqual(b));\n    assert(!b.approxEqual(a));\n}\n\n/***********************************\n * Defines a total order on all floating-point numbers.\n *\n * The order is defined as follows:\n * $(UL\n *      $(LI All numbers in [-$(INFIN), +$(INFIN)] are ordered\n *          the same way as by built-in comparison, with the exception of\n *          -0.0, which is less than +0.0;)\n *      $(LI If the sign bit is set (that is, it's 'negative'), $(NAN) is less\n *          than any number; if the sign bit is not set (it is 'positive'),\n *          $(NAN) is greater than any number;)\n *      $(LI $(NAN)s of the same sign are ordered by the payload ('negative'\n *          ones - in reverse order).)\n * )\n *\n * Returns:\n *      negative value if `x` precedes `y` in the order specified above;\n *      0 if `x` and `y` are identical, and positive value otherwise.\n *\n * See_Also:\n *      $(MYREF isIdentical)\n * Standards: Conforms to IEEE 754-2008\n */\nint cmp(T)(const(T) x, const(T) y) @nogc @trusted pure nothrow\nif (isFloatingPoint!T)\n{\n    alias F = floatTraits!T;\n\n    static if (F.realFormat == RealFormat.ieeeSingle\n               || F.realFormat == RealFormat.ieeeDouble)\n    {\n        static if (T.sizeof == 4)\n            alias UInt = uint;\n        else\n            alias UInt = ulong;\n\n        union Repainter\n        {\n            T number;\n            UInt bits;\n        }\n\n        enum msb = ~(UInt.max >>> 1);\n\n        import std.typecons : Tuple;\n        Tuple!(Repainter, Repainter) vars = void;\n        vars[0].number = x;\n        vars[1].number = y;\n\n        foreach (ref var; vars)\n            if (var.bits & msb)\n                var.bits = ~var.bits;\n            else\n                var.bits |= msb;\n\n        if (vars[0].bits < vars[1].bits)\n            return -1;\n        else if (vars[0].bits > vars[1].bits)\n            return 1;\n        else\n            return 0;\n    }\n    else static if (F.realFormat == RealFormat.ieeeExtended53\n                    || F.realFormat == RealFormat.ieeeExtended\n                    || F.realFormat == RealFormat.ieeeQuadruple)\n    {\n        static if (F.realFormat == RealFormat.ieeeQuadruple)\n            alias RemT = ulong;\n        else\n            alias RemT = ushort;\n\n        struct Bits\n        {\n            ulong bulk;\n            RemT rem;\n        }\n\n        union Repainter\n        {\n            T number;\n            Bits bits;\n            ubyte[T.sizeof] bytes;\n        }\n\n        import std.typecons : Tuple;\n        Tuple!(Repainter, Repainter) vars = void;\n        vars[0].number = x;\n        vars[1].number = y;\n\n        foreach (ref var; vars)\n            if (var.bytes[F.SIGNPOS_BYTE] & 0x80)\n            {\n                var.bits.bulk = ~var.bits.bulk;\n                var.bits.rem = cast(typeof(var.bits.rem))(-1 - var.bits.rem); // ~var.bits.rem\n            }\n            else\n            {\n                var.bytes[F.SIGNPOS_BYTE] |= 0x80;\n            }\n\n        version (LittleEndian)\n        {\n            if (vars[0].bits.rem < vars[1].bits.rem)\n                return -1;\n            else if (vars[0].bits.rem > vars[1].bits.rem)\n                return 1;\n            else if (vars[0].bits.bulk < vars[1].bits.bulk)\n                return -1;\n            else if (vars[0].bits.bulk > vars[1].bits.bulk)\n                return 1;\n            else\n                return 0;\n        }\n        else\n        {\n            if (vars[0].bits.bulk < vars[1].bits.bulk)\n                return -1;\n            else if (vars[0].bits.bulk > vars[1].bits.bulk)\n                return 1;\n            else if (vars[0].bits.rem < vars[1].bits.rem)\n                return -1;\n            else if (vars[0].bits.rem > vars[1].bits.rem)\n                return 1;\n            else\n                return 0;\n        }\n    }\n    else\n    {\n        // IBM Extended doubledouble does not follow the general\n        // sign-exponent-significand layout, so has to be handled generically\n\n        const int xSign = signbit(x),\n            ySign = signbit(y);\n\n        if (xSign == 1 && ySign == 1)\n            return cmp(-y, -x);\n        else if (xSign == 1)\n            return -1;\n        else if (ySign == 1)\n            return 1;\n        else if (x < y)\n            return -1;\n        else if (x == y)\n            return 0;\n        else if (x > y)\n            return 1;\n        else if (isNaN(x) && !isNaN(y))\n            return 1;\n        else if (isNaN(y) && !isNaN(x))\n            return -1;\n        else if (getNaNPayload(x) < getNaNPayload(y))\n            return -1;\n        else if (getNaNPayload(x) > getNaNPayload(y))\n            return 1;\n        else\n            return 0;\n    }\n}\n\n/// Most numbers are ordered naturally.\n@safe unittest\n{\n    assert(cmp(-double.infinity, -double.max) < 0);\n    assert(cmp(-double.max, -100.0) < 0);\n    assert(cmp(-100.0, -0.5) < 0);\n    assert(cmp(-0.5, 0.0) < 0);\n    assert(cmp(0.0, 0.5) < 0);\n    assert(cmp(0.5, 100.0) < 0);\n    assert(cmp(100.0, double.max) < 0);\n    assert(cmp(double.max, double.infinity) < 0);\n\n    assert(cmp(1.0, 1.0) == 0);\n}\n\n/// Positive and negative zeroes are distinct.\n@safe unittest\n{\n    assert(cmp(-0.0, +0.0) < 0);\n    assert(cmp(+0.0, -0.0) > 0);\n}\n\n/// Depending on the sign, $(NAN)s go to either end of the spectrum.\n@safe unittest\n{\n    assert(cmp(-double.nan, -double.infinity) < 0);\n    assert(cmp(double.infinity, double.nan) < 0);\n    assert(cmp(-double.nan, double.nan) < 0);\n}\n\n/// $(NAN)s of the same sign are ordered by the payload.\n@safe unittest\n{\n    assert(cmp(NaN(10), NaN(20)) < 0);\n    assert(cmp(-NaN(20), -NaN(10)) < 0);\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(float, double, real))\n    {{\n        T[] values = [-cast(T) NaN(20), -cast(T) NaN(10), -T.nan, -T.infinity,\n                      -T.max, -T.max / 2, T(-16.0), T(-1.0).nextDown,\n                      T(-1.0), T(-1.0).nextUp,\n                      T(-0.5), -T.min_normal, (-T.min_normal).nextUp,\n                      -2 * T.min_normal * T.epsilon,\n                      -T.min_normal * T.epsilon,\n                      T(-0.0), T(0.0),\n                      T.min_normal * T.epsilon,\n                      2 * T.min_normal * T.epsilon,\n                      T.min_normal.nextDown, T.min_normal, T(0.5),\n                      T(1.0).nextDown, T(1.0),\n                      T(1.0).nextUp, T(16.0), T.max / 2, T.max,\n                      T.infinity, T.nan, cast(T) NaN(10), cast(T) NaN(20)];\n\n        foreach (i, x; values)\n        {\n            foreach (y; values[i + 1 .. $])\n            {\n                assert(cmp(x, y) < 0);\n                assert(cmp(y, x) > 0);\n            }\n            assert(cmp(x, x) == 0);\n        }\n    }}\n}\n\nprivate enum PowType\n{\n    floor,\n    ceil\n}\n\npragma(inline, true)\nprivate T powIntegralImpl(PowType type, T)(T val)\n{\n    import core.bitop : bsr;\n\n    if (val == 0 || (type == PowType.ceil && (val > T.max / 2 || val == T.min)))\n        return 0;\n    else\n    {\n        static if (isSigned!T)\n            return cast(Unqual!T) (val < 0 ? -(T(1) << bsr(0 - val) + type) : T(1) << bsr(val) + type);\n        else\n            return cast(Unqual!T) (T(1) << bsr(val) + type);\n    }\n}\n\nprivate T powFloatingPointImpl(PowType type, T)(T x)\n{\n    if (!x.isFinite)\n        return x;\n\n    if (!x)\n        return x;\n\n    int exp;\n    auto y = frexp(x, exp);\n\n    static if (type == PowType.ceil)\n        y = ldexp(cast(T) 0.5, exp + 1);\n    else\n        y = ldexp(cast(T) 0.5, exp);\n\n    if (!y.isFinite)\n        return cast(T) 0.0;\n\n    y = copysign(y, x);\n\n    return y;\n}\n\n/**\n * Gives the next power of two after `val`. `T` can be any built-in\n * numerical type.\n *\n * If the operation would lead to an over/underflow, this function will\n * return `0`.\n *\n * Params:\n *     val = any number\n *\n * Returns:\n *     the next power of two after `val`\n */\nT nextPow2(T)(const T val)\nif (isIntegral!T)\n{\n    return powIntegralImpl!(PowType.ceil)(val);\n}\n\n/// ditto\nT nextPow2(T)(const T val)\nif (isFloatingPoint!T)\n{\n    return powFloatingPointImpl!(PowType.ceil)(val);\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    assert(nextPow2(2) == 4);\n    assert(nextPow2(10) == 16);\n    assert(nextPow2(4000) == 4096);\n\n    assert(nextPow2(-2) == -4);\n    assert(nextPow2(-10) == -16);\n\n    assert(nextPow2(uint.max) == 0);\n    assert(nextPow2(uint.min) == 0);\n    assert(nextPow2(size_t.max) == 0);\n    assert(nextPow2(size_t.min) == 0);\n\n    assert(nextPow2(int.max) == 0);\n    assert(nextPow2(int.min) == 0);\n    assert(nextPow2(long.max) == 0);\n    assert(nextPow2(long.min) == 0);\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    assert(nextPow2(2.1) == 4.0);\n    assert(nextPow2(-2.0) == -4.0);\n    assert(nextPow2(0.25) == 0.5);\n    assert(nextPow2(-4.0) == -8.0);\n\n    assert(nextPow2(double.max) == 0.0);\n    assert(nextPow2(double.infinity) == double.infinity);\n}\n\n@safe @nogc pure nothrow unittest\n{\n    assert(nextPow2(ubyte(2)) == 4);\n    assert(nextPow2(ubyte(10)) == 16);\n\n    assert(nextPow2(byte(2)) == 4);\n    assert(nextPow2(byte(10)) == 16);\n\n    assert(nextPow2(short(2)) == 4);\n    assert(nextPow2(short(10)) == 16);\n    assert(nextPow2(short(4000)) == 4096);\n\n    assert(nextPow2(ushort(2)) == 4);\n    assert(nextPow2(ushort(10)) == 16);\n    assert(nextPow2(ushort(4000)) == 4096);\n}\n\n@safe @nogc pure nothrow unittest\n{\n    foreach (ulong i; 1 .. 62)\n    {\n        assert(nextPow2(1UL << i) == 2UL << i);\n        assert(nextPow2((1UL << i) - 1) == 1UL << i);\n        assert(nextPow2((1UL << i) + 1) == 2UL << i);\n        assert(nextPow2((1UL << i) + (1UL<<(i-1))) == 2UL << i);\n    }\n}\n\n@safe @nogc pure nothrow unittest\n{\n    import std.meta : AliasSeq;\n\n    static foreach (T; AliasSeq!(float, double, real))\n    {{\n        enum T subNormal = T.min_normal / 2;\n\n        static if (subNormal) assert(nextPow2(subNormal) == T.min_normal);\n\n        assert(nextPow2(T(0.0)) == 0.0);\n\n        assert(nextPow2(T(2.0)) == 4.0);\n        assert(nextPow2(T(2.1)) == 4.0);\n        assert(nextPow2(T(3.1)) == 4.0);\n        assert(nextPow2(T(4.0)) == 8.0);\n        assert(nextPow2(T(0.25)) == 0.5);\n\n        assert(nextPow2(T(-2.0)) == -4.0);\n        assert(nextPow2(T(-2.1)) == -4.0);\n        assert(nextPow2(T(-3.1)) == -4.0);\n        assert(nextPow2(T(-4.0)) == -8.0);\n        assert(nextPow2(T(-0.25)) == -0.5);\n\n        assert(nextPow2(T.max) == 0);\n        assert(nextPow2(-T.max) == 0);\n\n        assert(nextPow2(T.infinity) == T.infinity);\n        assert(nextPow2(T.init).isNaN);\n    }}\n}\n\n@safe @nogc pure nothrow unittest // Issue 15973\n{\n    assert(nextPow2(uint.max / 2) == uint.max / 2 + 1);\n    assert(nextPow2(uint.max / 2 + 2) == 0);\n    assert(nextPow2(int.max / 2) == int.max / 2 + 1);\n    assert(nextPow2(int.max / 2 + 2) == 0);\n    assert(nextPow2(int.min + 1) == int.min);\n}\n\n/**\n * Gives the last power of two before `val`. $(T) can be any built-in\n * numerical type.\n *\n * Params:\n *     val = any number\n *\n * Returns:\n *     the last power of two before `val`\n */\nT truncPow2(T)(const T val)\nif (isIntegral!T)\n{\n    return powIntegralImpl!(PowType.floor)(val);\n}\n\n/// ditto\nT truncPow2(T)(const T val)\nif (isFloatingPoint!T)\n{\n    return powFloatingPointImpl!(PowType.floor)(val);\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    assert(truncPow2(3) == 2);\n    assert(truncPow2(4) == 4);\n    assert(truncPow2(10) == 8);\n    assert(truncPow2(4000) == 2048);\n\n    assert(truncPow2(-5) == -4);\n    assert(truncPow2(-20) == -16);\n\n    assert(truncPow2(uint.max) == int.max + 1);\n    assert(truncPow2(uint.min) == 0);\n    assert(truncPow2(ulong.max) == long.max + 1);\n    assert(truncPow2(ulong.min) == 0);\n\n    assert(truncPow2(int.max) == (int.max / 2) + 1);\n    assert(truncPow2(int.min) == int.min);\n    assert(truncPow2(long.max) == (long.max / 2) + 1);\n    assert(truncPow2(long.min) == long.min);\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    assert(truncPow2(2.1) == 2.0);\n    assert(truncPow2(7.0) == 4.0);\n    assert(truncPow2(-1.9) == -1.0);\n    assert(truncPow2(0.24) == 0.125);\n    assert(truncPow2(-7.0) == -4.0);\n\n    assert(truncPow2(double.infinity) == double.infinity);\n}\n\n@safe @nogc pure nothrow unittest\n{\n    assert(truncPow2(ubyte(3)) == 2);\n    assert(truncPow2(ubyte(4)) == 4);\n    assert(truncPow2(ubyte(10)) == 8);\n\n    assert(truncPow2(byte(3)) == 2);\n    assert(truncPow2(byte(4)) == 4);\n    assert(truncPow2(byte(10)) == 8);\n\n    assert(truncPow2(ushort(3)) == 2);\n    assert(truncPow2(ushort(4)) == 4);\n    assert(truncPow2(ushort(10)) == 8);\n    assert(truncPow2(ushort(4000)) == 2048);\n\n    assert(truncPow2(short(3)) == 2);\n    assert(truncPow2(short(4)) == 4);\n    assert(truncPow2(short(10)) == 8);\n    assert(truncPow2(short(4000)) == 2048);\n}\n\n@safe @nogc pure nothrow unittest\n{\n    foreach (ulong i; 1 .. 62)\n    {\n        assert(truncPow2(2UL << i) == 2UL << i);\n        assert(truncPow2((2UL << i) + 1) == 2UL << i);\n        assert(truncPow2((2UL << i) - 1) == 1UL << i);\n        assert(truncPow2((2UL << i) - (2UL<<(i-1))) == 1UL << i);\n    }\n}\n\n@safe @nogc pure nothrow unittest\n{\n    import std.meta : AliasSeq;\n\n    static foreach (T; AliasSeq!(float, double, real))\n    {\n        assert(truncPow2(T(0.0)) == 0.0);\n\n        assert(truncPow2(T(4.0)) == 4.0);\n        assert(truncPow2(T(2.1)) == 2.0);\n        assert(truncPow2(T(3.5)) == 2.0);\n        assert(truncPow2(T(7.0)) == 4.0);\n        assert(truncPow2(T(0.24)) == 0.125);\n\n        assert(truncPow2(T(-2.0)) == -2.0);\n        assert(truncPow2(T(-2.1)) == -2.0);\n        assert(truncPow2(T(-3.1)) == -2.0);\n        assert(truncPow2(T(-7.0)) == -4.0);\n        assert(truncPow2(T(-0.24)) == -0.125);\n\n        assert(truncPow2(T.infinity) == T.infinity);\n        assert(truncPow2(T.init).isNaN);\n    }\n}\n\n/**\nCheck whether a number is an integer power of two.\n\nNote that only positive numbers can be integer powers of two. This\nfunction always return `false` if `x` is negative or zero.\n\nParams:\n    x = the number to test\n\nReturns:\n    `true` if `x` is an integer power of two.\n*/\nbool isPowerOf2(X)(const X x) pure @safe nothrow @nogc\nif (isNumeric!X)\n{\n    static if (isFloatingPoint!X)\n    {\n        int exp;\n        const X sig = frexp(x, exp);\n\n        return (exp != int.min) && (sig is cast(X) 0.5L);\n    }\n    else\n    {\n        static if (isSigned!X)\n        {\n            auto y = cast(typeof(x + 0))x;\n            return y > 0 && !(y & (y - 1));\n        }\n        else\n        {\n            auto y = cast(typeof(x + 0u))x;\n            return (y & -y) > (y - 1);\n        }\n    }\n}\n///\n@safe unittest\n{\n    assert( isPowerOf2(1.0L));\n    assert( isPowerOf2(2.0L));\n    assert( isPowerOf2(0.5L));\n    assert( isPowerOf2(pow(2.0L, 96)));\n    assert( isPowerOf2(pow(2.0L, -77)));\n\n    assert(!isPowerOf2(-2.0L));\n    assert(!isPowerOf2(-0.5L));\n    assert(!isPowerOf2(0.0L));\n    assert(!isPowerOf2(4.315));\n    assert(!isPowerOf2(1.0L / 3.0L));\n\n    assert(!isPowerOf2(real.nan));\n    assert(!isPowerOf2(real.infinity));\n}\n///\n@safe unittest\n{\n    assert( isPowerOf2(1));\n    assert( isPowerOf2(2));\n    assert( isPowerOf2(1uL << 63));\n\n    assert(!isPowerOf2(-4));\n    assert(!isPowerOf2(0));\n    assert(!isPowerOf2(1337u));\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n\n    immutable smallP2 = pow(2.0L, -62);\n    immutable bigP2 = pow(2.0L, 50);\n    immutable smallP7 = pow(7.0L, -35);\n    immutable bigP7 = pow(7.0L, 30);\n\n    static foreach (X; AliasSeq!(float, double, real))\n    {{\n        immutable min_sub = X.min_normal * X.epsilon;\n\n        foreach (x; [smallP2, min_sub, X.min_normal, .25L, 0.5L, 1.0L,\n                              2.0L, 8.0L, pow(2.0L, X.max_exp - 1), bigP2])\n        {\n            assert( isPowerOf2(cast(X) x));\n            assert(!isPowerOf2(cast(X)-x));\n        }\n\n        foreach (x; [0.0L, 3 * min_sub, smallP7, 0.1L, 1337.0L, bigP7, X.max, real.nan, real.infinity])\n        {\n            assert(!isPowerOf2(cast(X) x));\n            assert(!isPowerOf2(cast(X)-x));\n        }\n    }}\n\n    static foreach (X; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))\n    {{\n        foreach (x; [1, 2, 4, 8, (X.max >>> 1) + 1])\n        {\n            assert( isPowerOf2(cast(X) x));\n            static if (isSigned!X)\n                assert(!isPowerOf2(cast(X)-x));\n        }\n\n        foreach (x; [0, 3, 5, 13, 77, X.min, X.max])\n            assert(!isPowerOf2(cast(X) x));\n    }}\n}\n"
  },
  {
    "path": "libphobos/src/std/mathspecial.d",
    "content": "// Written in the D programming language.\n\n/**\n * Mathematical Special Functions\n *\n * The technical term 'Special Functions' includes several families of\n * transcendental functions, which have important applications in particular\n * branches of mathematics and physics.\n *\n * The gamma and related functions, and the error function are crucial for\n * mathematical statistics.\n * The Bessel and related functions arise in problems involving wave propagation\n * (especially in optics).\n * Other major categories of special functions include the elliptic integrals\n * (related to the arc length of an ellipse), and the hypergeometric functions.\n *\n * Status:\n *  Many more functions will be added to this module.\n *  The naming convention for the distribution functions (gammaIncomplete, etc)\n *  is not yet finalized and will probably change.\n *\n * Macros:\n *      TABLE_SV = <table border=\"1\" cellpadding=\"4\" cellspacing=\"0\">\n *              <caption>Special Values</caption>\n *              $0</table>\n *      SVH = $(TR $(TH $1) $(TH $2))\n *      SV  = $(TR $(TD $1) $(TD $2))\n *\n *      NAN = $(RED NAN)\n *      SUP = <span style=\"vertical-align:super;font-size:smaller\">$0</span>\n *      GAMMA = &#915;\n *      THETA = &theta;\n *      INTEGRAL = &#8747;\n *      INTEGRATE = $(BIG &#8747;<sub>$(SMALL $1)</sub><sup>$2</sup>)\n *      POWER = $1<sup>$2</sup>\n *      SUB = $1<sub>$2</sub>\n *      BIGSUM = $(BIG &Sigma; <sup>$2</sup><sub>$(SMALL $1)</sub>)\n *      CHOOSE = $(BIG &#40;) <sup>$(SMALL $1)</sup><sub>$(SMALL $2)</sub> $(BIG &#41;)\n *      PLUSMN = &plusmn;\n *      INFIN = &infin;\n *      PLUSMNINF = &plusmn;&infin;\n *      PI = &pi;\n *      LT = &lt;\n *      GT = &gt;\n *      SQRT = &radic;\n *      HALF = &frac12;\n *\n *\n * Copyright: Based on the CEPHES math library, which is\n *            Copyright (C) 1994 Stephen L. Moshier (moshier@world.std.com).\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Stephen L. Moshier (original C code). Conversion to D by Don Clugston\n * Source:    $(PHOBOSSRC std/mathspecial.d)\n */\nmodule std.mathspecial;\nimport std.internal.math.errorfunction;\nimport std.internal.math.gammafunction;\npublic import std.math;\n\n/* ***********************************************\n *            GAMMA AND RELATED FUNCTIONS        *\n * ***********************************************/\n\npure:\nnothrow:\n@safe:\n@nogc:\n\n/** The Gamma function, $(GAMMA)(x)\n *\n *  $(GAMMA)(x) is a generalisation of the factorial function\n *  to real and complex numbers.\n *  Like x!, $(GAMMA)(x+1) = x * $(GAMMA)(x).\n *\n *  Mathematically, if z.re > 0 then\n *   $(GAMMA)(z) = $(INTEGRATE 0, $(INFIN)) $(POWER t, z-1)$(POWER e, -t) dt\n *\n *  $(TABLE_SV\n *    $(SVH  x,           $(GAMMA)(x) )\n *    $(SV  $(NAN),       $(NAN)      )\n *    $(SV  $(PLUSMN)0.0, $(PLUSMNINF))\n *    $(SV integer > 0,   (x-1)!      )\n *    $(SV integer < 0,   $(NAN)      )\n *    $(SV +$(INFIN),      +$(INFIN)   )\n *    $(SV -$(INFIN),      $(NAN)      )\n *  )\n */\nreal gamma(real x)\n{\n    return std.internal.math.gammafunction.gamma(x);\n}\n\n/** Natural logarithm of the gamma function, $(GAMMA)(x)\n *\n * Returns the base e (2.718...) logarithm of the absolute\n * value of the gamma function of the argument.\n *\n * For reals, logGamma is equivalent to log(fabs(gamma(x))).\n *\n *  $(TABLE_SV\n *    $(SVH  x,             logGamma(x)   )\n *    $(SV  $(NAN),         $(NAN)      )\n *    $(SV integer <= 0,    +$(INFIN)    )\n *    $(SV $(PLUSMNINF),    +$(INFIN)    )\n *  )\n */\nreal logGamma(real x)\n{\n    return std.internal.math.gammafunction.logGamma(x);\n}\n\n/** The sign of $(GAMMA)(x).\n *\n * Returns -1 if $(GAMMA)(x) < 0,  +1 if $(GAMMA)(x) > 0,\n * $(NAN) if sign is indeterminate.\n *\n * Note that this function can be used in conjunction with logGamma(x) to\n * evaluate gamma for very large values of x.\n */\nreal sgnGamma(real x)\n{\n    /* Author: Don Clugston. */\n    if (isNaN(x)) return x;\n    if (x > 0) return 1.0;\n    if (x < -1/real.epsilon)\n    {\n        // Large negatives lose all precision\n        return real.nan;\n    }\n    long n = rndtol(x);\n    if (x == n)\n    {\n        return x == 0 ?  copysign(1, x) : real.nan;\n    }\n    return n & 1 ? 1.0 : -1.0;\n}\n\n@safe unittest\n{\n    assert(sgnGamma(5.0) == 1.0);\n    assert(isNaN(sgnGamma(-3.0)));\n    assert(sgnGamma(-0.1) == -1.0);\n    assert(sgnGamma(-55.1) == 1.0);\n    assert(isNaN(sgnGamma(-real.infinity)));\n    assert(isIdentical(sgnGamma(NaN(0xABC)), NaN(0xABC)));\n}\n\n/** Beta function\n *\n * The beta function is defined as\n *\n * beta(x, y) = ($(GAMMA)(x) * $(GAMMA)(y)) / $(GAMMA)(x + y)\n */\nreal beta(real x, real y)\n{\n    if ((x+y)> MAXGAMMA)\n    {\n        return exp(logGamma(x) + logGamma(y) - logGamma(x+y));\n    } else return gamma(x) * gamma(y) / gamma(x+y);\n}\n\n@safe unittest\n{\n    assert(isIdentical(beta(NaN(0xABC), 4), NaN(0xABC)));\n    assert(isIdentical(beta(2, NaN(0xABC)), NaN(0xABC)));\n}\n\n/** Digamma function\n *\n *  The digamma function is the logarithmic derivative of the gamma function.\n *\n *  digamma(x) = d/dx logGamma(x)\n *\n *  See_Also: $(LREF logmdigamma), $(LREF logmdigammaInverse).\n */\nreal digamma(real x)\n{\n    return std.internal.math.gammafunction.digamma(x);\n}\n\n/** Log Minus Digamma function\n *\n *  logmdigamma(x) = log(x) - digamma(x)\n *\n *  See_Also: $(LREF digamma), $(LREF logmdigammaInverse).\n */\nreal logmdigamma(real x)\n{\n    return std.internal.math.gammafunction.logmdigamma(x);\n}\n\n/** Inverse of the Log Minus Digamma function\n *\n *  Given y, the function finds x such log(x) - digamma(x) = y.\n *\n *  See_Also: $(LREF logmdigamma), $(LREF digamma).\n */\nreal logmdigammaInverse(real x)\n{\n    return std.internal.math.gammafunction.logmdigammaInverse(x);\n}\n\n/** Incomplete beta integral\n *\n * Returns incomplete beta integral of the arguments, evaluated\n * from zero to x. The regularized incomplete beta function is defined as\n *\n * betaIncomplete(a, b, x) = $(GAMMA)(a + b) / ( $(GAMMA)(a) $(GAMMA)(b) ) *\n * $(INTEGRATE 0, x) $(POWER t, a-1)$(POWER (1-t), b-1) dt\n *\n * and is the same as the the cumulative distribution function.\n *\n * The domain of definition is 0 <= x <= 1.  In this\n * implementation a and b are restricted to positive values.\n * The integral from x to 1 may be obtained by the symmetry\n * relation\n *\n *    betaIncompleteCompl(a, b, x )  =  betaIncomplete( b, a, 1-x )\n *\n * The integral is evaluated by a continued fraction expansion\n * or, when b * x is small, by a power series.\n */\nreal betaIncomplete(real a, real b, real x )\n{\n    return std.internal.math.gammafunction.betaIncomplete(a, b, x);\n}\n\n/** Inverse of incomplete beta integral\n *\n * Given y, the function finds x such that\n *\n *  betaIncomplete(a, b, x) == y\n *\n *  Newton iterations or interval halving is used.\n */\nreal betaIncompleteInverse(real a, real b, real y )\n{\n    return std.internal.math.gammafunction.betaIncompleteInv(a, b, y);\n}\n\n/** Incomplete gamma integral and its complement\n *\n * These functions are defined by\n *\n *   gammaIncomplete = ( $(INTEGRATE 0, x) $(POWER e, -t) $(POWER t, a-1) dt )/ $(GAMMA)(a)\n *\n *  gammaIncompleteCompl(a,x)   =   1 - gammaIncomplete(a,x)\n * = ($(INTEGRATE x, $(INFIN)) $(POWER e, -t) $(POWER t, a-1) dt )/ $(GAMMA)(a)\n *\n * In this implementation both arguments must be positive.\n * The integral is evaluated by either a power series or\n * continued fraction expansion, depending on the relative\n * values of a and x.\n */\nreal gammaIncomplete(real a, real x )\nin\n{\n   assert(x >= 0);\n   assert(a > 0);\n}\ndo\n{\n    return std.internal.math.gammafunction.gammaIncomplete(a, x);\n}\n\n/** ditto */\nreal gammaIncompleteCompl(real a, real x )\nin\n{\n   assert(x >= 0);\n   assert(a > 0);\n}\ndo\n{\n    return std.internal.math.gammafunction.gammaIncompleteCompl(a, x);\n}\n\n/** Inverse of complemented incomplete gamma integral\n *\n * Given a and p, the function finds x such that\n *\n *  gammaIncompleteCompl( a, x ) = p.\n */\nreal gammaIncompleteComplInverse(real a, real p)\nin\n{\n  assert(p >= 0 && p <= 1);\n  assert(a > 0);\n}\ndo\n{\n    return std.internal.math.gammafunction.gammaIncompleteComplInv(a, p);\n}\n\n\n/* ***********************************************\n *     ERROR FUNCTIONS & NORMAL DISTRIBUTION     *\n * ***********************************************/\n\n /** Error function\n *\n * The integral is\n *\n *  erf(x) =  2/ $(SQRT)($(PI))\n *     $(INTEGRATE 0, x) exp( - $(POWER t, 2)) dt\n *\n * The magnitude of x is limited to about 106.56 for IEEE 80-bit\n * arithmetic; 1 or -1 is returned outside this range.\n */\nreal erf(real x)\n{\n    return std.internal.math.errorfunction.erf(x);\n}\n\n/** Complementary error function\n *\n * erfc(x) = 1 - erf(x)\n *         = 2/ $(SQRT)($(PI))\n *     $(INTEGRATE x, $(INFIN)) exp( - $(POWER t, 2)) dt\n *\n * This function has high relative accuracy for\n * values of x far from zero. (For values near zero, use erf(x)).\n */\nreal erfc(real x)\n{\n    return std.internal.math.errorfunction.erfc(x);\n}\n\n\n/** Normal distribution function.\n *\n * The normal (or Gaussian, or bell-shaped) distribution is\n * defined as:\n *\n * normalDist(x) = 1/$(SQRT)(2$(PI)) $(INTEGRATE -$(INFIN), x) exp( - $(POWER t, 2)/2) dt\n *   = 0.5 + 0.5 * erf(x/sqrt(2))\n *   = 0.5 * erfc(- x/sqrt(2))\n *\n * To maintain accuracy at values of x near 1.0, use\n *      normalDistribution(x) = 1.0 - normalDistribution(-x).\n *\n * References:\n * $(LINK http://www.netlib.org/cephes/ldoubdoc.html),\n * G. Marsaglia, \"Evaluating the Normal Distribution\",\n * Journal of Statistical Software <b>11</b>, (July 2004).\n */\nreal normalDistribution(real x)\n{\n    return std.internal.math.errorfunction.normalDistributionImpl(x);\n}\n\n/** Inverse of Normal distribution function\n *\n * Returns the argument, x, for which the area under the\n * Normal probability density function (integrated from\n * minus infinity to x) is equal to p.\n *\n * Note: This function is only implemented to 80 bit precision.\n */\nreal normalDistributionInverse(real p)\nin\n{\n  assert(p >= 0.0L && p <= 1.0L, \"Domain error\");\n}\ndo\n{\n    return std.internal.math.errorfunction.normalDistributionInvImpl(p);\n}\n"
  },
  {
    "path": "libphobos/src/std/meta.d",
    "content": "// Written in the D programming language.\n\n/**\n * Templates to manipulate\n * $(DDSUBLINK spec/template, variadic-templates, template parameter sequences)\n * (also known as $(I alias sequences)).\n *\n * Some operations on alias sequences are built into the language,\n * such as `S[i]`, which accesses the element at index `i` in the\n * sequence. `S[low .. high]` returns a new alias\n * sequence that is a slice of the old one.\n *\n * For more information, see $(DDLINK ctarguments, Compile-time Sequences, Compile-time Sequences).\n *\n * $(B Note:) Several templates in this module use or operate on eponymous templates that\n * take a single argument and evaluate to a boolean constant. Such templates\n * are referred to as $(I template predicates).\n *\n * $(SCRIPT inhibitQuickIndex = 1;)\n * $(DIVC quickindex,\n * $(BOOKTABLE ,\n * $(TR $(TH Category) $(TH Templates))\n * $(TR $(TD Building blocks) $(TD\n *           $(LREF Alias)\n *           $(LREF AliasSeq)\n *           $(LREF aliasSeqOf)\n * ))\n * $(TR $(TD Alias sequence filtering) $(TD\n *           $(LREF Erase)\n *           $(LREF EraseAll)\n *           $(LREF Filter)\n *           $(LREF NoDuplicates)\n *           $(LREF Stride)\n * ))\n * $(TR $(TD Alias sequence type hierarchy) $(TD\n *           $(LREF DerivedToFront)\n *           $(LREF MostDerived)\n * ))\n * $(TR $(TD Alias sequence transformation) $(TD\n *           $(LREF Repeat)\n *           $(LREF Replace)\n *           $(LREF ReplaceAll)\n *           $(LREF Reverse)\n *           $(LREF staticMap)\n *           $(LREF staticSort)\n * ))\n * $(TR $(TD Alias sequence searching) $(TD\n *           $(LREF allSatisfy)\n *           $(LREF anySatisfy)\n *           $(LREF staticIndexOf)\n * ))\n * $(TR $(TD Template predicates) $(TD\n *           $(LREF templateAnd)\n *           $(LREF templateNot)\n *           $(LREF templateOr)\n *           $(LREF staticIsSorted)\n * ))\n * $(TR $(TD Template instantiation) $(TD\n *           $(LREF ApplyLeft)\n *           $(LREF ApplyRight)\n *           $(LREF Instantiate)\n * ))\n * ))\n *\n * References:\n *  Based on ideas in Table 3.1 from\n *  $(LINK2 http://amazon.com/exec/obidos/ASIN/0201704315/ref=ase_classicempire/102-2957199-2585768,\n *      Modern C++ Design),\n *   Andrei Alexandrescu (Addison-Wesley Professional, 2001)\n * Copyright: Copyright The D Language Foundation 2005 - 2015.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:\n *     $(HTTP digitalmars.com, Walter Bright),\n *     $(HTTP klickverbot.at, David Nadlinger)\n * Source:    $(PHOBOSSRC std/meta.d)\n */\n\nmodule std.meta;\n\n/**\n * Creates a sequence of zero or more aliases. This is most commonly\n * used as template parameters or arguments.\n *\n * In previous versions of Phobos, this was known as `TypeTuple`.\n */\ntemplate AliasSeq(TList...)\n{\n    alias AliasSeq = TList;\n}\n\n///\n@safe unittest\n{\n    import std.meta;\n    alias TL = AliasSeq!(int, double);\n\n    int foo(TL td)  // same as int foo(int, double);\n    {\n        return td[0] + cast(int) td[1];\n    }\n}\n\n///\n@safe unittest\n{\n    alias TL = AliasSeq!(int, double);\n\n    alias Types = AliasSeq!(TL, char);\n    static assert(is(Types == AliasSeq!(int, double, char)));\n}\n\n\n/**\n  Returns an `AliasSeq` expression of `Func` being\n  applied to every variadic template argument.\n */\n\n///\n@safe unittest\n{\n    auto ref ArgCall(alias Func, alias arg)()\n    {\n        return Func(arg);\n    }\n\n    template Map(alias Func, args...)\n    {\n        static if (args.length > 1)\n        {\n            alias Map = AliasSeq!(ArgCall!(Func, args[0]), Map!(Func, args[1 .. $]));\n        }\n        else\n        {\n            alias Map = ArgCall!(Func, args[0]);\n        }\n    }\n\n    static int square(int arg)\n    {\n        return arg * arg;\n    }\n\n    static int refSquare(ref int arg)\n    {\n        arg *= arg;\n        return arg;\n    }\n\n    static ref int refRetSquare(ref int arg)\n    {\n        arg *= arg;\n        return arg;\n    }\n\n    static void test(int a, int b)\n    {\n        assert(a == 4);\n        assert(b == 16);\n    }\n\n    static void testRef(ref int a, ref int b)\n    {\n        assert(a++ == 16);\n        assert(b++ == 256);\n    }\n\n    static int a = 2;\n    static int b = 4;\n\n    test(Map!(square, a, b));\n\n    test(Map!(refSquare, a, b));\n    assert(a == 4);\n    assert(b == 16);\n\n    testRef(Map!(refRetSquare, a, b));\n    assert(a == 17);\n    assert(b == 257);\n}\n\n/**\n * Allows `alias`ing of any single symbol, type or compile-time expression.\n *\n * Not everything can be directly aliased. An alias cannot be declared\n * of - for example - a literal:\n * ---\n * alias a = 4; //Error\n * ---\n * With this template any single entity can be aliased:\n * ---\n * alias b = Alias!4; //OK\n * ---\n * See_Also:\n * To alias more than one thing at once, use $(LREF AliasSeq).\n */\nalias Alias(alias a) = a;\n\n/// Ditto\nalias Alias(T) = T;\n\n///\n@safe unittest\n{\n    // Without Alias this would fail if Args[0] was e.g. a value and\n    // some logic would be needed to detect when to use enum instead\n    alias Head(Args ...) = Alias!(Args[0]);\n    alias Tail(Args ...) = Args[1 .. $];\n\n    alias Blah = AliasSeq!(3, int, \"hello\");\n    static assert(Head!Blah == 3);\n    static assert(is(Head!(Tail!Blah) == int));\n    static assert((Tail!Blah)[1] == \"hello\");\n}\n\n///\n@safe unittest\n{\n    alias a = Alias!(123);\n    static assert(a == 123);\n\n    enum abc = 1;\n    alias b = Alias!(abc);\n    static assert(b == 1);\n\n    alias c = Alias!(3 + 4);\n    static assert(c == 7);\n\n    alias concat = (s0, s1) => s0 ~ s1;\n    alias d = Alias!(concat(\"Hello\", \" World!\"));\n    static assert(d == \"Hello World!\");\n\n    alias e = Alias!(int);\n    static assert(is(e == int));\n\n    alias f = Alias!(AliasSeq!(int));\n    static assert(!is(typeof(f[0]))); //not an AliasSeq\n    static assert(is(f == int));\n\n    auto g = 6;\n    alias h = Alias!g;\n    ++h;\n    assert(g == 7);\n}\n\npackage template OldAlias(alias a)\n{\n    static if (__traits(compiles, { alias x = a; }))\n        alias OldAlias = a;\n    else static if (__traits(compiles, { enum x = a; }))\n        enum OldAlias = a;\n    else\n        static assert(0, \"Cannot alias \" ~ a.stringof);\n}\n\nimport std.traits : isAggregateType, Unqual;\n\npackage template OldAlias(T)\nif (!isAggregateType!T || is(Unqual!T == T))\n{\n    alias OldAlias = T;\n}\n\n@safe unittest\n{\n    static struct Foo {}\n    static assert(is(OldAlias!(const(Foo)) == Foo));\n    static assert(is(OldAlias!(const(int)) == const(int)));\n    static assert(OldAlias!123 == 123);\n    enum abc = 123;\n    static assert(OldAlias!abc == 123);\n}\n\n/**\n * Returns the index of the first occurrence of type T in the\n * sequence of zero or more types TList.\n * If not found, -1 is returned.\n */\ntemplate staticIndexOf(T, TList...)\n{\n    enum staticIndexOf = genericIndexOf!(T, TList);\n}\n\n/// Ditto\ntemplate staticIndexOf(alias T, TList...)\n{\n    enum staticIndexOf = genericIndexOf!(T, TList);\n}\n\n///\n@safe unittest\n{\n    import std.stdio;\n\n    void foo()\n    {\n        writefln(\"The index of long is %s\",\n                 staticIndexOf!(long, AliasSeq!(int, long, double)));\n        // prints: The index of long is 1\n    }\n}\n\n// [internal]\nprivate template genericIndexOf(args...)\nif (args.length >= 1)\n{\n    static foreach (idx, arg; args[1 .. $])\n    {\n        static if (is(typeof(genericIndexOf) == void) && // not yet defined\n                   isSame!(args[0], arg))\n        {\n            enum genericIndexOf = idx;\n        }\n    }\n    static if (is(typeof(genericIndexOf) == void)) // no hit\n    {\n        enum genericIndexOf = -1;\n    }\n}\n\n@safe unittest\n{\n    static assert(staticIndexOf!( byte, byte, short, int, long) ==  0);\n    static assert(staticIndexOf!(short, byte, short, int, long) ==  1);\n    static assert(staticIndexOf!(  int, byte, short, int, long) ==  2);\n    static assert(staticIndexOf!( long, byte, short, int, long) ==  3);\n    static assert(staticIndexOf!( char, byte, short, int, long) == -1);\n    static assert(staticIndexOf!(   -1, byte, short, int, long) == -1);\n    static assert(staticIndexOf!(void) == -1);\n\n    static assert(staticIndexOf!(\"abc\", \"abc\", \"def\", \"ghi\", \"jkl\") ==  0);\n    static assert(staticIndexOf!(\"def\", \"abc\", \"def\", \"ghi\", \"jkl\") ==  1);\n    static assert(staticIndexOf!(\"ghi\", \"abc\", \"def\", \"ghi\", \"jkl\") ==  2);\n    static assert(staticIndexOf!(\"jkl\", \"abc\", \"def\", \"ghi\", \"jkl\") ==  3);\n    static assert(staticIndexOf!(\"mno\", \"abc\", \"def\", \"ghi\", \"jkl\") == -1);\n    static assert(staticIndexOf!( void, \"abc\", \"def\", \"ghi\", \"jkl\") == -1);\n    static assert(staticIndexOf!(42) == -1);\n\n    static assert(staticIndexOf!(void, 0, \"void\", void) == 2);\n    static assert(staticIndexOf!(\"void\", 0, void, \"void\") == 2);\n}\n\n/**\n * Returns an `AliasSeq` created from TList with the first occurrence,\n * if any, of T removed.\n */\ntemplate Erase(T, TList...)\n{\n    alias Erase = GenericErase!(T, TList).result;\n}\n\n/// Ditto\ntemplate Erase(alias T, TList...)\n{\n    alias Erase = GenericErase!(T, TList).result;\n}\n\n///\n@safe unittest\n{\n    alias Types = AliasSeq!(int, long, double, char);\n    alias TL = Erase!(long, Types);\n    static assert(is(TL == AliasSeq!(int, double, char)));\n}\n\n// [internal]\nprivate template GenericErase(args...)\nif (args.length >= 1)\n{\n    alias e     = OldAlias!(args[0]);\n    alias tuple = args[1 .. $] ;\n\n    static if (tuple.length)\n    {\n        alias head = OldAlias!(tuple[0]);\n        alias tail = tuple[1 .. $];\n\n        static if (isSame!(e, head))\n            alias result = tail;\n        else\n            alias result = AliasSeq!(head, GenericErase!(e, tail).result);\n    }\n    else\n    {\n        alias result = AliasSeq!();\n    }\n}\n\n@safe unittest\n{\n    static assert(Pack!(Erase!(int,\n                short, int, int, 4)).\n        equals!(short,      int, 4));\n\n    static assert(Pack!(Erase!(1,\n                real, 3, 1, 4, 1, 5, 9)).\n        equals!(real, 3,    4, 1, 5, 9));\n}\n\n\n/**\n * Returns an `AliasSeq` created from TList with the all occurrences,\n * if any, of T removed.\n */\ntemplate EraseAll(T, TList...)\n{\n    alias EraseAll = GenericEraseAll!(T, TList).result;\n}\n\n/// Ditto\ntemplate EraseAll(alias T, TList...)\n{\n    alias EraseAll = GenericEraseAll!(T, TList).result;\n}\n\n///\n@safe unittest\n{\n    alias Types = AliasSeq!(int, long, long, int);\n\n    alias TL = EraseAll!(long, Types);\n    static assert(is(TL == AliasSeq!(int, int)));\n}\n\n// [internal]\nprivate template GenericEraseAll(args...)\nif (args.length >= 1)\n{\n    alias e     = OldAlias!(args[0]);\n    alias tuple = args[1 .. $];\n\n    static if (tuple.length)\n    {\n        alias head = OldAlias!(tuple[0]);\n        alias tail = tuple[1 .. $];\n        alias next = AliasSeq!(\n            GenericEraseAll!(e, tail[0..$/2]).result,\n            GenericEraseAll!(e, tail[$/2..$]).result\n            );\n\n        static if (isSame!(e, head))\n            alias result = next;\n        else\n            alias result = AliasSeq!(head, next);\n    }\n    else\n    {\n        alias result = AliasSeq!();\n    }\n}\n\n@safe unittest\n{\n    static assert(Pack!(EraseAll!(int,\n                short, int, int, 4)).\n        equals!(short,           4));\n\n    static assert(Pack!(EraseAll!(1,\n                real, 3, 1, 4, 1, 5, 9)).\n        equals!(real, 3,    4,    5, 9));\n}\n\n/*\n * Erase any occurrence of the first `TList[0 .. N]` elements from `TList[N .. $]`.\n *\n * Params:\n *   N = number of elements to delete from the `TList`\n *   TList = sequence of aliases\n *\n * See_Also: $(LREF EraseAll)\n */\nprivate template EraseAllN(uint N, TList...)\n{\n    static if (N == 1)\n    {\n        alias EraseAllN = EraseAll!(TList[0], TList[1 .. $]);\n    }\n    else\n    {\n        static if (N & 1)\n            alias EraseAllN = EraseAllN!(N / 2, TList[N / 2 + 1 .. N],\n                    EraseAllN!(N / 2 + 1, TList[0 .. N / 2 + 1], TList[N .. $]));\n        else\n            alias EraseAllN = EraseAllN!(N / 2, TList[N / 2 .. N],\n                    EraseAllN!(N / 2, TList[0 .. N / 2], TList[N .. $]));\n    }\n}\n\n/**\n * Returns an `AliasSeq` created from TList with the all duplicate\n * types removed.\n */\ntemplate NoDuplicates(TList...)\n{\n    static if (TList.length >= 2)\n    {\n        alias fst = NoDuplicates!(TList[0 .. $/2]);\n        alias snd = NoDuplicates!(TList[$/2 .. $]);\n        alias NoDuplicates = AliasSeq!(fst, EraseAllN!(fst.length, fst, snd));\n    }\n    else\n    {\n        alias NoDuplicates = TList;\n    }\n}\n\n///\n@safe unittest\n{\n    alias Types = AliasSeq!(int, long, long, int, float);\n\n    alias TL = NoDuplicates!(Types);\n    static assert(is(TL == AliasSeq!(int, long, float)));\n}\n\n@safe unittest\n{\n    import std.range : iota;\n\n    // Bugzilla 14561: huge enums\n    alias LongList = Repeat!(1500, int);\n    static assert(NoDuplicates!LongList.length == 1);\n    // Bugzilla 17995: huge enums, revisited\n\n    alias a = NoDuplicates!(AliasSeq!(1, Repeat!(1000, 3)));\n    alias b = NoDuplicates!(AliasSeq!(1, Repeat!(10, 3)));\n    static assert(a.length == b.length);\n\n    static assert(NoDuplicates!(aliasSeqOf!(iota(7)), aliasSeqOf!(iota(7))) == aliasSeqOf!(iota(7)));\n    static assert(NoDuplicates!(aliasSeqOf!(iota(8)), aliasSeqOf!(iota(8))) == aliasSeqOf!(iota(8)));\n}\n\n@safe unittest\n{\n    static assert(\n        Pack!(\n            NoDuplicates!(1, int, 1, NoDuplicates, int, NoDuplicates, real))\n        .equals!(1, int,    NoDuplicates,                    real));\n}\n\n\n/**\n * Returns an `AliasSeq` created from TList with the first occurrence\n * of type T, if found, replaced with type U.\n */\ntemplate Replace(T, U, TList...)\n{\n    alias Replace = GenericReplace!(T, U, TList).result;\n}\n\n/// Ditto\ntemplate Replace(alias T, U, TList...)\n{\n    alias Replace = GenericReplace!(T, U, TList).result;\n}\n\n/// Ditto\ntemplate Replace(T, alias U, TList...)\n{\n    alias Replace = GenericReplace!(T, U, TList).result;\n}\n\n/// Ditto\ntemplate Replace(alias T, alias U, TList...)\n{\n    alias Replace = GenericReplace!(T, U, TList).result;\n}\n\n///\n@safe unittest\n{\n    alias Types = AliasSeq!(int, long, long, int, float);\n\n    alias TL = Replace!(long, char, Types);\n    static assert(is(TL == AliasSeq!(int, char, long, int, float)));\n}\n\n// [internal]\nprivate template GenericReplace(args...)\nif (args.length >= 2)\n{\n    alias from  = OldAlias!(args[0]);\n    alias to    = OldAlias!(args[1]);\n    alias tuple = args[2 .. $];\n\n    static if (tuple.length)\n    {\n        alias head = OldAlias!(tuple[0]);\n        alias tail = tuple[1 .. $];\n\n        static if (isSame!(from, head))\n            alias result = AliasSeq!(to, tail);\n        else\n            alias result = AliasSeq!(head,\n                GenericReplace!(from, to, tail).result);\n    }\n    else\n    {\n        alias result = AliasSeq!();\n    }\n }\n\n@safe unittest\n{\n    static assert(Pack!(Replace!(byte, ubyte,\n                short,  byte, byte, byte)).\n        equals!(short, ubyte, byte, byte));\n\n    static assert(Pack!(Replace!(1111, byte,\n                2222, 1111, 1111, 1111)).\n        equals!(2222, byte, 1111, 1111));\n\n    static assert(Pack!(Replace!(byte, 1111,\n                short, byte, byte, byte)).\n        equals!(short, 1111, byte, byte));\n\n    static assert(Pack!(Replace!(1111, \"11\",\n                2222, 1111, 1111, 1111)).\n        equals!(2222, \"11\", 1111, 1111));\n}\n\n/**\n * Returns an `AliasSeq` created from TList with all occurrences\n * of type T, if found, replaced with type U.\n */\ntemplate ReplaceAll(T, U, TList...)\n{\n    alias ReplaceAll = GenericReplaceAll!(T, U, TList).result;\n}\n\n/// Ditto\ntemplate ReplaceAll(alias T, U, TList...)\n{\n    alias ReplaceAll = GenericReplaceAll!(T, U, TList).result;\n}\n\n/// Ditto\ntemplate ReplaceAll(T, alias U, TList...)\n{\n    alias ReplaceAll = GenericReplaceAll!(T, U, TList).result;\n}\n\n/// Ditto\ntemplate ReplaceAll(alias T, alias U, TList...)\n{\n    alias ReplaceAll = GenericReplaceAll!(T, U, TList).result;\n}\n\n///\n@safe unittest\n{\n    alias Types = AliasSeq!(int, long, long, int, float);\n\n    alias TL = ReplaceAll!(long, char, Types);\n    static assert(is(TL == AliasSeq!(int, char, char, int, float)));\n}\n\n// [internal]\nprivate template GenericReplaceAll(args...)\nif (args.length >= 2)\n{\n    alias from  = OldAlias!(args[0]);\n    alias to    = OldAlias!(args[1]);\n    alias tuple = args[2 .. $];\n\n    static if (tuple.length)\n    {\n        alias head = OldAlias!(tuple[0]);\n        alias tail = tuple[1 .. $];\n        alias next = GenericReplaceAll!(from, to, tail).result;\n\n        static if (isSame!(from, head))\n            alias result = AliasSeq!(to, next);\n        else\n            alias result = AliasSeq!(head, next);\n    }\n    else\n    {\n        alias result = AliasSeq!();\n    }\n}\n\n@safe unittest\n{\n    static assert(Pack!(ReplaceAll!(byte, ubyte,\n                 byte, short,  byte,  byte)).\n        equals!(ubyte, short, ubyte, ubyte));\n\n    static assert(Pack!(ReplaceAll!(1111, byte,\n                1111, 2222, 1111, 1111)).\n        equals!(byte, 2222, byte, byte));\n\n    static assert(Pack!(ReplaceAll!(byte, 1111,\n                byte, short, byte, byte)).\n        equals!(1111, short, 1111, 1111));\n\n    static assert(Pack!(ReplaceAll!(1111, \"11\",\n                1111, 2222, 1111, 1111)).\n        equals!(\"11\", 2222, \"11\", \"11\"));\n}\n\n/**\n * Returns an `AliasSeq` created from TList with the order reversed.\n */\ntemplate Reverse(TList...)\n{\n    static if (TList.length <= 1)\n    {\n        alias Reverse = TList;\n    }\n    else\n    {\n        alias Reverse =\n            AliasSeq!(\n                Reverse!(TList[$/2 ..  $ ]),\n                Reverse!(TList[ 0  .. $/2]));\n    }\n}\n\n///\n@safe unittest\n{\n    alias Types = AliasSeq!(int, long, long, int, float);\n\n    alias TL = Reverse!(Types);\n    static assert(is(TL == AliasSeq!(float, int, long, long, int)));\n}\n\n/**\n * Returns the type from TList that is the most derived from type T.\n * If none are found, T is returned.\n */\ntemplate MostDerived(T, TList...)\n{\n    static if (TList.length == 0)\n        alias MostDerived = T;\n    else static if (is(TList[0] : T))\n        alias MostDerived = MostDerived!(TList[0], TList[1 .. $]);\n    else\n        alias MostDerived = MostDerived!(T, TList[1 .. $]);\n}\n\n///\n@safe unittest\n{\n    class A { }\n    class B : A { }\n    class C : B { }\n    alias Types = AliasSeq!(A, C, B);\n\n    MostDerived!(Object, Types) x;  // x is declared as type C\n    static assert(is(typeof(x) == C));\n}\n\n/**\n * Returns an `AliasSeq` with the elements of TList sorted so that the most\n * derived types come first.\n */\ntemplate DerivedToFront(TList...)\n{\n    static if (TList.length == 0)\n        alias DerivedToFront = TList;\n    else\n        alias DerivedToFront =\n            AliasSeq!(MostDerived!(TList[0], TList[1 .. $]),\n                       DerivedToFront!(ReplaceAll!(MostDerived!(TList[0], TList[1 .. $]),\n                                TList[0],\n                                TList[1 .. $])));\n}\n\n///\n@safe unittest\n{\n    class A { }\n    class B : A { }\n    class C : B { }\n    alias Types = AliasSeq!(A, C, B);\n\n    alias TL = DerivedToFront!(Types);\n    static assert(is(TL == AliasSeq!(C, B, A)));\n}\n\n/**\nEvaluates to $(D AliasSeq!(F!(T[0]), F!(T[1]), ..., F!(T[$ - 1]))).\n */\ntemplate staticMap(alias F, T...)\n{\n    static if (T.length == 0)\n    {\n        alias staticMap = AliasSeq!();\n    }\n    else static if (T.length == 1)\n    {\n        alias staticMap = AliasSeq!(F!(T[0]));\n    }\n    else\n    {\n        alias staticMap =\n            AliasSeq!(\n                staticMap!(F, T[ 0  .. $/2]),\n                staticMap!(F, T[$/2 ..  $ ]));\n    }\n}\n\n///\n@safe unittest\n{\n    import std.traits : Unqual;\n    alias TL = staticMap!(Unqual, int, const int, immutable int);\n    static assert(is(TL == AliasSeq!(int, int, int)));\n}\n\n@safe unittest\n{\n    import std.traits : Unqual;\n\n    // empty\n    alias Empty = staticMap!(Unqual);\n    static assert(Empty.length == 0);\n\n    // single\n    alias Single = staticMap!(Unqual, const int);\n    static assert(is(Single == AliasSeq!int));\n\n    alias T = staticMap!(Unqual, int, const int, immutable int);\n    static assert(is(T == AliasSeq!(int, int, int)));\n}\n\n/**\nTests whether all given items satisfy a template predicate, i.e. evaluates to\n$(D F!(T[0]) && F!(T[1]) && ... && F!(T[$ - 1])).\n\nEvaluation is $(I not) short-circuited if a false result is encountered; the\ntemplate predicate must be instantiable with all the given items.\n */\ntemplate allSatisfy(alias F, T...)\n{\n    static foreach (Ti; T)\n    {\n        static if (!is(typeof(allSatisfy) == bool) && // not yet defined\n                   !F!(Ti))\n        {\n            enum allSatisfy = false;\n        }\n    }\n    static if (!is(typeof(allSatisfy) == bool)) // if not yet defined\n    {\n        enum allSatisfy = true;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.traits : isIntegral;\n\n    static assert(!allSatisfy!(isIntegral, int, double));\n    static assert( allSatisfy!(isIntegral, int, long));\n}\n\n/**\nTests whether any given items satisfy a template predicate, i.e. evaluates to\n$(D F!(T[0]) || F!(T[1]) || ... || F!(T[$ - 1])).\n\nEvaluation is short-circuited if a true result is encountered; the\ntemplate predicate must be instantiable with one of the given items.\n */\ntemplate anySatisfy(alias F, T...)\n{\n    static foreach (Ti; T)\n    {\n        static if (!is(typeof(anySatisfy) == bool) && // not yet defined\n                   F!(Ti))\n        {\n            enum anySatisfy = true;\n        }\n    }\n    static if (!is(typeof(anySatisfy) == bool)) // if not yet defined\n    {\n        enum anySatisfy = false;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.traits : isIntegral;\n\n    static assert(!anySatisfy!(isIntegral, string, double));\n    static assert( anySatisfy!(isIntegral, int, double));\n}\n\n\n/**\n * Filters an `AliasSeq` using a template predicate. Returns an\n * `AliasSeq` of the elements which satisfy the predicate.\n */\ntemplate Filter(alias pred, TList...)\n{\n    static if (TList.length == 0)\n    {\n        alias Filter = AliasSeq!();\n    }\n    else static if (TList.length == 1)\n    {\n        static if (pred!(TList[0]))\n            alias Filter = AliasSeq!(TList[0]);\n        else\n            alias Filter = AliasSeq!();\n    }\n    else\n    {\n        alias Filter =\n            AliasSeq!(\n                Filter!(pred, TList[ 0  .. $/2]),\n                Filter!(pred, TList[$/2 ..  $ ]));\n    }\n}\n\n///\n@safe unittest\n{\n    import std.traits : isNarrowString, isUnsigned;\n\n    alias Types1 = AliasSeq!(string, wstring, dchar[], char[], dstring, int);\n    alias TL1 = Filter!(isNarrowString, Types1);\n    static assert(is(TL1 == AliasSeq!(string, wstring, char[])));\n\n    alias Types2 = AliasSeq!(int, byte, ubyte, dstring, dchar, uint, ulong);\n    alias TL2 = Filter!(isUnsigned, Types2);\n    static assert(is(TL2 == AliasSeq!(ubyte, uint, ulong)));\n}\n\n@safe unittest\n{\n    import std.traits : isPointer;\n\n    static assert(is(Filter!(isPointer, int, void*, char[], int*) == AliasSeq!(void*, int*)));\n    static assert(is(Filter!isPointer == AliasSeq!()));\n}\n\n\n// Used in template predicate unit tests below.\nprivate version (unittest)\n{\n    template testAlways(T...)\n    {\n        enum testAlways = true;\n    }\n\n    template testNever(T...)\n    {\n        enum testNever = false;\n    }\n\n    template testError(T...)\n    {\n        static assert(false, \"Should never be instantiated.\");\n    }\n}\n\n\n/**\n * Negates the passed template predicate.\n */\ntemplate templateNot(alias pred)\n{\n    enum templateNot(T...) = !pred!T;\n}\n\n///\n@safe unittest\n{\n    import std.traits : isPointer;\n\n    alias isNoPointer = templateNot!isPointer;\n    static assert(!isNoPointer!(int*));\n    static assert(allSatisfy!(isNoPointer, string, char, float));\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(int, staticMap, 42))\n    {\n        static assert(!Instantiate!(templateNot!testAlways, T));\n        static assert(Instantiate!(templateNot!testNever, T));\n    }\n}\n\n\n/**\n * Combines several template predicates using logical AND, i.e. constructs a new\n * predicate which evaluates to true for a given input T if and only if all of\n * the passed predicates are true for T.\n *\n * The predicates are evaluated from left to right, aborting evaluation in a\n * short-cut manner if a false result is encountered, in which case the latter\n * instantiations do not need to compile.\n */\ntemplate templateAnd(Preds...)\n{\n    template templateAnd(T...)\n    {\n        static if (Preds.length == 0)\n        {\n            enum templateAnd = true;\n        }\n        else\n        {\n            static if (Instantiate!(Preds[0], T))\n                alias templateAnd = Instantiate!(.templateAnd!(Preds[1 .. $]), T);\n            else\n                enum templateAnd = false;\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    import std.traits : isNumeric, isUnsigned;\n\n    alias storesNegativeNumbers = templateAnd!(isNumeric, templateNot!isUnsigned);\n    static assert(storesNegativeNumbers!int);\n    static assert(!storesNegativeNumbers!string && !storesNegativeNumbers!uint);\n\n    // An empty sequence of predicates always yields true.\n    alias alwaysTrue = templateAnd!();\n    static assert(alwaysTrue!int);\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(int, staticMap, 42))\n    {\n        static assert( Instantiate!(templateAnd!(), T));\n        static assert( Instantiate!(templateAnd!(testAlways), T));\n        static assert( Instantiate!(templateAnd!(testAlways, testAlways), T));\n        static assert(!Instantiate!(templateAnd!(testNever), T));\n        static assert(!Instantiate!(templateAnd!(testAlways, testNever), T));\n        static assert(!Instantiate!(templateAnd!(testNever, testAlways), T));\n\n        static assert(!Instantiate!(templateAnd!(testNever, testError), T));\n        static assert(!is(typeof(Instantiate!(templateAnd!(testAlways, testError), T))));\n    }\n}\n\n\n/**\n * Combines several template predicates using logical OR, i.e. constructs a new\n * predicate which evaluates to true for a given input T if and only at least\n * one of the passed predicates is true for T.\n *\n * The predicates are evaluated from left to right, aborting evaluation in a\n * short-cut manner if a true result is encountered, in which case the latter\n * instantiations do not need to compile.\n */\ntemplate templateOr(Preds...)\n{\n    template templateOr(T...)\n    {\n        static if (Preds.length == 0)\n        {\n            enum templateOr = false;\n        }\n        else\n        {\n            static if (Instantiate!(Preds[0], T))\n                enum templateOr = true;\n            else\n                alias templateOr = Instantiate!(.templateOr!(Preds[1 .. $]), T);\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    import std.traits : isPointer, isUnsigned;\n\n    alias isPtrOrUnsigned = templateOr!(isPointer, isUnsigned);\n    static assert( isPtrOrUnsigned!uint &&  isPtrOrUnsigned!(short*));\n    static assert(!isPtrOrUnsigned!int  && !isPtrOrUnsigned!(string));\n\n    // An empty sequence of predicates never yields true.\n    alias alwaysFalse = templateOr!();\n    static assert(!alwaysFalse!int);\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(int, staticMap, 42))\n    {\n        static assert( Instantiate!(templateOr!(testAlways), T));\n        static assert( Instantiate!(templateOr!(testAlways, testAlways), T));\n        static assert( Instantiate!(templateOr!(testAlways, testNever), T));\n        static assert( Instantiate!(templateOr!(testNever, testAlways), T));\n        static assert(!Instantiate!(templateOr!(), T));\n        static assert(!Instantiate!(templateOr!(testNever), T));\n\n        static assert( Instantiate!(templateOr!(testAlways, testError), T));\n        static assert( Instantiate!(templateOr!(testNever, testAlways, testError), T));\n        // DMD @@BUG@@: Assertion fails for int, seems like a error gagging\n        // problem. The bug goes away when removing some of the other template\n        // instantiations in the module.\n        // static assert(!is(typeof(Instantiate!(templateOr!(testNever, testError), T))));\n    }\n}\n\n/**\n * Converts an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n * `range` to an alias sequence.\n */\ntemplate aliasSeqOf(alias range)\n{\n    import std.traits : isArray, isNarrowString;\n\n    alias ArrT = typeof(range);\n    static if (isArray!ArrT && !isNarrowString!ArrT)\n    {\n        static if (range.length == 0)\n        {\n            alias aliasSeqOf = AliasSeq!();\n        }\n        else static if (range.length == 1)\n        {\n            alias aliasSeqOf = AliasSeq!(range[0]);\n        }\n        else\n        {\n            alias aliasSeqOf = AliasSeq!(aliasSeqOf!(range[0 .. $/2]), aliasSeqOf!(range[$/2 .. $]));\n        }\n    }\n    else\n    {\n        import std.range.primitives : isInputRange;\n        static if (isInputRange!ArrT)\n        {\n            import std.array : array;\n            alias aliasSeqOf = aliasSeqOf!(array(range));\n        }\n        else\n        {\n            static assert(false, \"Cannot transform range of type \" ~ ArrT.stringof ~ \" into a AliasSeq.\");\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.iteration : map;\n    import std.algorithm.sorting : sort;\n    import std.string : capitalize;\n\n    struct S\n    {\n        int a;\n        int c;\n        int b;\n    }\n\n    alias capMembers = aliasSeqOf!([__traits(allMembers, S)].sort().map!capitalize());\n    static assert(capMembers[0] == \"A\");\n    static assert(capMembers[1] == \"B\");\n    static assert(capMembers[2] == \"C\");\n}\n\n///\n@safe unittest\n{\n    static immutable REF = [0, 1, 2, 3];\n    foreach (I, V; aliasSeqOf!([0, 1, 2, 3]))\n    {\n        static assert(V == I);\n        static assert(V == REF[I]);\n    }\n}\n\n@safe unittest\n{\n    import std.conv : to, octal;\n    import std.range : iota;\n    //Testing compile time octal\n    foreach (I2; aliasSeqOf!(iota(0, 8)))\n        foreach (I1; aliasSeqOf!(iota(0, 8)))\n        {\n            enum oct = I2 *  8 + I1;\n            enum dec = I2 * 10 + I1;\n            enum str = to!string(dec);\n            static assert(octal!dec == oct);\n            static assert(octal!str == oct);\n        }\n}\n\n@safe unittest\n{\n    enum REF = \"日本語\"d;\n    foreach (I, V; aliasSeqOf!\"日本語\"c)\n    {\n        static assert(V == REF[I]);\n    }\n}\n\n/**\n  * $(LINK2 http://en.wikipedia.org/wiki/Partial_application, Partially applies)\n  * $(D_PARAM Template) by binding its first (left) or last (right) arguments\n  * to $(D_PARAM args).\n  *\n  * Behaves like the identity function when $(D_PARAM args) is empty.\n  * Params:\n  *    Template = template to partially apply\n  *    args     = arguments to bind\n  * Returns:\n  *    _Template with arity smaller than or equal to $(D_PARAM Template)\n  */\ntemplate ApplyLeft(alias Template, args...)\n{\n    alias ApplyLeft(right...) = SmartAlias!(Template!(args, right));\n}\n\n/// Ditto\ntemplate ApplyRight(alias Template, args...)\n{\n    alias ApplyRight(left...) = SmartAlias!(Template!(left, args));\n}\n\n///\n@safe unittest\n{\n    // enum bool isImplicitlyConvertible(From, To)\n    import std.traits : isImplicitlyConvertible;\n\n    static assert(allSatisfy!(\n        ApplyLeft!(isImplicitlyConvertible, ubyte),\n        short, ushort, int, uint, long, ulong));\n\n    static assert(is(Filter!(ApplyRight!(isImplicitlyConvertible, short),\n        ubyte, string, short, float, int) == AliasSeq!(ubyte, short)));\n}\n\n///\n@safe unittest\n{\n    import std.traits : hasMember, ifTestable;\n\n    struct T1\n    {\n        bool foo;\n    }\n\n    struct T2\n    {\n        struct Test\n        {\n            bool opCast(T : bool)() { return true; }\n        }\n\n        Test foo;\n    }\n\n    static assert(allSatisfy!(ApplyRight!(hasMember, \"foo\"), T1, T2));\n    static assert(allSatisfy!(ApplyRight!(ifTestable, a => a.foo), T1, T2));\n}\n\n///\n@safe unittest\n{\n    import std.traits : Largest;\n\n    alias Types = AliasSeq!(byte, short, int, long);\n\n    static assert(is(staticMap!(ApplyLeft!(Largest, short), Types) ==\n                AliasSeq!(short, short, int, long)));\n    static assert(is(staticMap!(ApplyLeft!(Largest, int), Types) ==\n                AliasSeq!(int, int, int, long)));\n}\n\n///\n@safe unittest\n{\n    import std.traits : FunctionAttribute, SetFunctionAttributes;\n\n    static void foo() @system;\n    static int bar(int) @system;\n\n    alias SafeFunctions = AliasSeq!(\n        void function() @safe,\n        int function(int) @safe);\n\n    static assert(is(staticMap!(ApplyRight!(\n        SetFunctionAttributes, \"D\", FunctionAttribute.safe),\n        typeof(&foo), typeof(&bar)) == SafeFunctions));\n}\n\nprivate template SmartAlias(T...)\n{\n    static if (T.length == 1)\n    {\n        alias SmartAlias = Alias!T;\n    }\n    else\n    {\n        alias SmartAlias = AliasSeq!T;\n    }\n}\n\n@safe unittest\n{\n    static assert(is(typeof({\n        alias T(T0, int a, double b, alias T1, string c) = AliasSeq!(T0, a, b, T1, c);\n        alias T0 = ApplyRight!(ApplyLeft, ApplyRight);\n        alias T1 = T0!ApplyLeft;\n        alias T2 = T1!T;\n        alias T3 = T2!(3, \"foo\");\n        alias T4 = T3!(short, 3, 3.3);\n        static assert(Pack!T4.equals!(short, 3, 3.3, 3, \"foo\"));\n\n        import std.traits : isImplicitlyConvertible;\n        alias U1 = ApplyLeft!(ApplyRight, isImplicitlyConvertible);\n        alias U2 = U1!int;\n        enum U3 = U2!short;\n        static assert(U3);\n    })));\n}\n\n/**\n * Creates an `AliasSeq` which repeats `TList` exactly `n` times.\n */\ntemplate Repeat(size_t n, TList...)\n{\n    static if (n == 0)\n    {\n        alias Repeat = AliasSeq!();\n    }\n    else static if (n == 1)\n    {\n        alias Repeat = AliasSeq!TList;\n    }\n    else static if (n == 2)\n    {\n        alias Repeat = AliasSeq!(TList, TList);\n    }\n    else\n    {\n        alias R = Repeat!((n - 1) / 2, TList);\n        static if ((n - 1) % 2 == 0)\n        {\n            alias Repeat = AliasSeq!(TList, R, R);\n        }\n        else\n        {\n            alias Repeat = AliasSeq!(TList, TList, R, R);\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    alias ImInt0 = Repeat!(0, int);\n    static assert(is(ImInt0 == AliasSeq!()));\n\n    alias ImInt1 = Repeat!(1, immutable(int));\n    static assert(is(ImInt1 == AliasSeq!(immutable(int))));\n\n    alias Real3 = Repeat!(3, real);\n    static assert(is(Real3 == AliasSeq!(real, real, real)));\n\n    alias Real12 = Repeat!(4, Real3);\n    static assert(is(Real12 == AliasSeq!(real, real, real, real, real, real,\n        real, real, real, real, real, real)));\n\n    alias Composite = AliasSeq!(uint, int);\n    alias Composite2 = Repeat!(2, Composite);\n    static assert(is(Composite2 == AliasSeq!(uint, int, uint, int)));\n}\n\n\n///\n@safe unittest\n{\n    auto staticArray(T, size_t n)(Repeat!(n, T) elems)\n    {\n        T[n] a = [elems];\n        return a;\n    }\n\n    auto a = staticArray!(long, 3)(3, 1, 4);\n    assert(is(typeof(a) == long[3]));\n    assert(a == [3, 1, 4]);\n}\n\n/**\n * Sorts an $(LREF AliasSeq) using `cmp`.\n *\n * Parameters:\n *     cmp = A template that returns a `bool` (if its first argument is less than the second one)\n *         or an `int` (-1 means less than, 0 means equal, 1 means greater than)\n *\n *     Seq = The  $(LREF AliasSeq) to sort\n *\n * Returns: The sorted alias sequence\n */\ntemplate staticSort(alias cmp, Seq...)\n{\n    static if (Seq.length < 2)\n    {\n        alias staticSort = Seq;\n    }\n    else\n    {\n        private alias btm = staticSort!(cmp, Seq[0 .. $ / 2]);\n        private alias top = staticSort!(cmp, Seq[$ / 2 .. $]);\n\n        static if (isLessEq!(cmp, btm[$ - 1], top[0]))\n            alias staticSort = AliasSeq!(btm, top); // already ascending\n        else static if (isLessEq!(cmp, top[$ - 1], btm[0]))\n            alias staticSort = AliasSeq!(top, btm); // already descending\n        else\n            alias staticSort = staticMerge!(cmp, Seq.length / 2, btm, top);\n    }\n}\n\n///\n@safe unittest\n{\n    alias Nums = AliasSeq!(7, 2, 3, 23);\n    enum Comp(int N1, int N2) = N1 < N2;\n    static assert(AliasSeq!(2, 3, 7, 23) == staticSort!(Comp, Nums));\n}\n\n///\n@safe unittest\n{\n    alias Types = AliasSeq!(uint, short, ubyte, long, ulong);\n    enum Comp(T1, T2) = __traits(isUnsigned, T2) - __traits(isUnsigned, T1);\n    static assert(is(AliasSeq!(uint, ubyte, ulong, short, long) == staticSort!(Comp,\n        Types)));\n}\n\nprivate template staticMerge(alias cmp, int half, Seq...)\n{\n    static if (half == 0 || half == Seq.length)\n    {\n        alias staticMerge = Seq;\n    }\n    else\n    {\n        static if (isLessEq!(cmp, Seq[0], Seq[half]))\n        {\n            alias staticMerge = AliasSeq!(Seq[0],\n                staticMerge!(cmp, half - 1, Seq[1 .. $]));\n        }\n        else\n        {\n            alias staticMerge = AliasSeq!(Seq[half],\n                staticMerge!(cmp, half, Seq[0 .. half], Seq[half + 1 .. $]));\n        }\n    }\n}\n\nprivate template isLessEq(alias cmp, Seq...)\nif (Seq.length == 2)\n{\n    private enum Result = cmp!(Seq[1], Seq[0]);\n    static if (is(typeof(Result) == bool))\n        enum isLessEq = !Result;\n    else static if (is(typeof(Result) : int))\n        enum isLessEq = Result >= 0;\n    else\n        static assert(0, typeof(Result).stringof ~ \" is not a value comparison type\");\n}\n\n/**\n * Checks if an $(LREF AliasSeq) is sorted according to `cmp`.\n *\n * Parameters:\n *     cmp = A template that returns a `bool` (if its first argument is less than the second one)\n *         or an `int` (-1 means less than, 0 means equal, 1 means greater than)\n *\n *     Seq = The  $(LREF AliasSeq) to check\n *\n * Returns: `true` if `Seq` is sorted; otherwise `false`\n */\ntemplate staticIsSorted(alias cmp, Seq...)\n{\n    static if (Seq.length <= 1)\n        enum staticIsSorted = true;\n    else static if (Seq.length == 2)\n        enum staticIsSorted = isLessEq!(cmp, Seq[0], Seq[1]);\n    else\n    {\n        enum staticIsSorted =\n            isLessEq!(cmp, Seq[($ / 2) - 1], Seq[$ / 2]) &&\n            staticIsSorted!(cmp, Seq[0 .. $ / 2]) &&\n            staticIsSorted!(cmp, Seq[$ / 2 .. $]);\n    }\n}\n\n///\n@safe unittest\n{\n    enum Comp(int N1, int N2) = N1 < N2;\n    static assert( staticIsSorted!(Comp, 2, 2));\n    static assert( staticIsSorted!(Comp, 2, 3, 7, 23));\n    static assert(!staticIsSorted!(Comp, 7, 2, 3, 23));\n}\n\n///\n@safe unittest\n{\n    enum Comp(T1, T2) = __traits(isUnsigned, T2) - __traits(isUnsigned, T1);\n    static assert( staticIsSorted!(Comp, uint, ubyte, ulong, short, long));\n    static assert(!staticIsSorted!(Comp, uint, short, ubyte, long, ulong));\n}\n\n/**\nSelects a subset of `Args` by stepping with fixed `stepSize` over the sequence.\nA negative `stepSize` starts iteration with the last element.\n\nParams:\n    stepSize = Number of elements to increment on each iteration. Can't be `0`.\n    Args = Template arguments.\n\nReturns: An `AliasSeq` filtered by the selected stride.\n*/\ntemplate Stride(int stepSize, Args...)\nif (stepSize != 0)\n{\n    static if (Args.length == 0)\n    {\n        alias Stride = AliasSeq!();\n    }\n    else static if (stepSize > 0)\n    {\n        static if (stepSize >= Args.length)\n            alias Stride = AliasSeq!(Args[0]);\n        else\n            alias Stride = AliasSeq!(Args[0], Stride!(stepSize, Args[stepSize .. $]));\n    }\n    else\n    {\n        static if (-stepSize >= Args.length)\n            alias Stride = AliasSeq!(Args[$ - 1]);\n        else\n            alias Stride = AliasSeq!(Args[$ - 1], Stride!(stepSize, Args[0 .. $ + stepSize]));\n    }\n}\n\n///\n@safe unittest\n{\n    static assert(is(Stride!(1, short, int, long) == AliasSeq!(short, int, long)));\n    static assert(is(Stride!(2, short, int, long) == AliasSeq!(short, long)));\n    static assert(is(Stride!(-1, short, int, long) == AliasSeq!(long, int, short)));\n    static assert(is(Stride!(-2, short, int, long) == AliasSeq!(long, short)));\n\n    alias attribs = AliasSeq!(short, int, long, ushort, uint, ulong);\n    static assert(is(Stride!(3, attribs) == AliasSeq!(short, ushort)));\n    static assert(is(Stride!(3, attribs[1 .. $]) == AliasSeq!(int, uint)));\n    static assert(is(Stride!(-3, attribs) == AliasSeq!(ulong, long)));\n}\n\n@safe unittest\n{\n    static assert(Pack!(Stride!(5, int)).equals!(int));\n    static assert(Pack!(Stride!(-5, int)).equals!(int));\n    static assert(!__traits(compiles, Stride!(0, int)));\n}\n\n/**\n * Instantiates the given template with the given parameters.\n *\n * Used to work around syntactic limitations of D with regard to instantiating\n * a template from an alias sequence (e.g. `T[0]!(...)` is not valid) or a\n * template returning another template (e.g. `Foo!(Bar)!(Baz)` is not allowed).\n *\n * Params:\n *    Template = The template to instantiate.\n *    Params = The parameters with which to instantiate the template.\n * Returns:\n *    The instantiated template.\n */\nalias Instantiate(alias Template, Params...) = Template!Params;\n\n///\n@safe unittest\n{\n    // ApplyRight combined with Instantiate can be used to apply various\n    // templates to the same parameters.\n    import std.string : leftJustify, center, rightJustify;\n    alias functions = staticMap!(ApplyRight!(Instantiate, string),\n                                 leftJustify, center, rightJustify);\n    string result = \"\";\n    static foreach (f; functions)\n    {\n        {\n            auto x = &f; // not a template, but a function instantiation\n            result ~= x(\"hello\", 7);\n            result ~= \";\";\n        }\n    }\n\n    assert(result == \"hello  ; hello ;  hello;\");\n}\n\n// : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : //\nprivate:\n\n/*\n * [internal] Returns true if a and b are the same thing, or false if\n * not. Both a and b can be types, literals, or symbols.\n *\n * How:                     When:\n *      is(a == b)        - both are types\n *        a == b          - both are literals (true literals, enums)\n * __traits(isSame, a, b) - other cases (variables, functions,\n *                          templates, etc.)\n */\nprivate template isSame(ab...)\nif (ab.length == 2)\n{\n    static if (__traits(compiles, expectType!(ab[0]),\n                                  expectType!(ab[1])))\n    {\n        enum isSame = is(ab[0] == ab[1]);\n    }\n    else static if (!__traits(compiles, expectType!(ab[0])) &&\n                    !__traits(compiles, expectType!(ab[1])) &&\n                     __traits(compiles, expectBool!(ab[0] == ab[1])))\n    {\n        static if (!__traits(compiles, &ab[0]) ||\n                   !__traits(compiles, &ab[1]))\n            enum isSame = (ab[0] == ab[1]);\n        else\n            enum isSame = __traits(isSame, ab[0], ab[1]);\n    }\n    else\n    {\n        enum isSame = __traits(isSame, ab[0], ab[1]);\n    }\n}\nprivate template expectType(T) {}\nprivate template expectBool(bool b) {}\n\n@safe unittest\n{\n    static assert( isSame!(int, int));\n    static assert(!isSame!(int, short));\n\n    enum a = 1, b = 1, c = 2, s = \"a\", t = \"a\";\n    static assert( isSame!(1, 1));\n    static assert( isSame!(a, 1));\n    static assert( isSame!(a, b));\n    static assert(!isSame!(b, c));\n    static assert( isSame!(\"a\", \"a\"));\n    static assert( isSame!(s, \"a\"));\n    static assert( isSame!(s, t));\n    static assert(!isSame!(1, \"1\"));\n    static assert(!isSame!(a, \"a\"));\n    static assert( isSame!(isSame, isSame));\n    static assert(!isSame!(isSame, a));\n\n    static assert(!isSame!(byte, a));\n    static assert(!isSame!(short, isSame));\n    static assert(!isSame!(a, int));\n    static assert(!isSame!(long, isSame));\n\n    static immutable X = 1, Y = 1, Z = 2;\n    static assert( isSame!(X, X));\n    static assert(!isSame!(X, Y));\n    static assert(!isSame!(Y, Z));\n\n    int  foo();\n    int  bar();\n    real baz(int);\n    static assert( isSame!(foo, foo));\n    static assert(!isSame!(foo, bar));\n    static assert(!isSame!(bar, baz));\n    static assert( isSame!(baz, baz));\n    static assert(!isSame!(foo, 0));\n\n    int  x, y;\n    real z;\n    static assert( isSame!(x, x));\n    static assert(!isSame!(x, y));\n    static assert(!isSame!(y, z));\n    static assert( isSame!(z, z));\n    static assert(!isSame!(x, 0));\n}\n\n/*\n * [internal] Confines a tuple within a template.\n */\nprivate template Pack(T...)\n{\n    alias tuple = T;\n\n    // For convenience\n    template equals(U...)\n    {\n        static if (T.length == U.length)\n        {\n            static if (T.length == 0)\n                enum equals = true;\n            else\n                enum equals = isSame!(T[0], U[0]) &&\n                    Pack!(T[1 .. $]).equals!(U[1 .. $]);\n        }\n        else\n        {\n            enum equals = false;\n        }\n    }\n}\n\n@safe unittest\n{\n    static assert( Pack!(1, int, \"abc\").equals!(1, int, \"abc\"));\n    static assert(!Pack!(1, int, \"abc\").equals!(1, int, \"cba\"));\n}\n"
  },
  {
    "path": "libphobos/src/std/mmfile.d",
    "content": "// Written in the D programming language.\n\n/**\n * Read and write memory mapped files.\n * Copyright: Copyright The D Language Foundation 2004 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright),\n *            Matthew Wilson\n * Source:    $(PHOBOSSRC std/mmfile.d)\n *\n * $(SCRIPT inhibitQuickIndex = 1;)\n */\n/*          Copyright The D Language Foundation 2004 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.mmfile;\n\nimport core.stdc.errno;\nimport core.stdc.stdio;\nimport core.stdc.stdlib;\nimport std.conv, std.exception, std.stdio;\nimport std.file;\nimport std.path;\nimport std.string;\n\nimport std.internal.cstring;\n\n//debug = MMFILE;\n\nversion (Windows)\n{\n    import core.sys.windows.windows;\n    import std.utf;\n    import std.windows.syserror;\n}\nelse version (Posix)\n{\n    import core.sys.posix.fcntl;\n    import core.sys.posix.sys.mman;\n    import core.sys.posix.sys.stat;\n    import core.sys.posix.unistd;\n}\nelse\n{\n    static assert(0);\n}\n\n/**\n * MmFile objects control the memory mapped file resource.\n */\nclass MmFile\n{\n    /**\n     * The mode the memory mapped file is opened with.\n     */\n    enum Mode\n    {\n        read,            /// Read existing file\n        readWriteNew,    /// Delete existing file, write new file\n        readWrite,       /// Read/Write existing file, create if not existing\n        readCopyOnWrite, /// Read/Write existing file, copy on write\n    }\n\n    /**\n     * Open memory mapped file filename for reading.\n     * File is closed when the object instance is deleted.\n     * Throws:\n     *  std.file.FileException\n     */\n    this(string filename)\n    {\n        this(filename, Mode.read, 0, null);\n    }\n\n    version (linux) this(File file, Mode mode = Mode.read, ulong size = 0,\n            void* address = null, size_t window = 0)\n    {\n        // Save a copy of the File to make sure the fd stays open.\n        this.file = file;\n        this(file.fileno, mode, size, address, window);\n    }\n\n    version (linux) private this(int fildes, Mode mode, ulong size,\n            void* address, size_t window)\n    {\n        int oflag;\n        int fmode;\n\n        final switch (mode)\n        {\n        case Mode.read:\n            flags = MAP_SHARED;\n            prot = PROT_READ;\n            oflag = O_RDONLY;\n            fmode = 0;\n            break;\n\n        case Mode.readWriteNew:\n            assert(size != 0);\n            flags = MAP_SHARED;\n            prot = PROT_READ | PROT_WRITE;\n            oflag = O_CREAT | O_RDWR | O_TRUNC;\n            fmode = octal!660;\n            break;\n\n        case Mode.readWrite:\n            flags = MAP_SHARED;\n            prot = PROT_READ | PROT_WRITE;\n            oflag = O_CREAT | O_RDWR;\n            fmode = octal!660;\n            break;\n\n        case Mode.readCopyOnWrite:\n            flags = MAP_PRIVATE;\n            prot = PROT_READ | PROT_WRITE;\n            oflag = O_RDWR;\n            fmode = 0;\n            break;\n        }\n\n        fd = fildes;\n\n        // Adjust size\n        stat_t statbuf = void;\n        errnoEnforce(fstat(fd, &statbuf) == 0);\n        if (prot & PROT_WRITE && size > statbuf.st_size)\n        {\n            // Need to make the file size bytes big\n            lseek(fd, cast(off_t)(size - 1), SEEK_SET);\n            char c = 0;\n            core.sys.posix.unistd.write(fd, &c, 1);\n        }\n        else if (prot & PROT_READ && size == 0)\n            size = statbuf.st_size;\n        this.size = size;\n\n        // Map the file into memory!\n        size_t initial_map = (window && 2*window<size)\n            ? 2*window : cast(size_t) size;\n        auto p = mmap(address, initial_map, prot, flags, fd, 0);\n        if (p == MAP_FAILED)\n        {\n            errnoEnforce(false, \"Could not map file into memory\");\n        }\n        data = p[0 .. initial_map];\n    }\n\n    /**\n     * Open memory mapped file filename in mode.\n     * File is closed when the object instance is deleted.\n     * Params:\n     *  filename = name of the file.\n     *      If null, an anonymous file mapping is created.\n     *  mode = access mode defined above.\n     *  size =  the size of the file. If 0, it is taken to be the\n     *      size of the existing file.\n     *  address = the preferred address to map the file to,\n     *      although the system is not required to honor it.\n     *      If null, the system selects the most convenient address.\n     *  window = preferred block size of the amount of data to map at one time\n     *      with 0 meaning map the entire file. The window size must be a\n     *      multiple of the memory allocation page size.\n     * Throws:\n     *  std.file.FileException\n     */\n    this(string filename, Mode mode, ulong size, void* address,\n            size_t window = 0)\n    {\n        this.filename = filename;\n        this.mMode = mode;\n        this.window = window;\n        this.address = address;\n\n        version (Windows)\n        {\n            void* p;\n            uint dwDesiredAccess2;\n            uint dwShareMode;\n            uint dwCreationDisposition;\n            uint flProtect;\n\n            final switch (mode)\n            {\n            case Mode.read:\n                dwDesiredAccess2 = GENERIC_READ;\n                dwShareMode = FILE_SHARE_READ;\n                dwCreationDisposition = OPEN_EXISTING;\n                flProtect = PAGE_READONLY;\n                dwDesiredAccess = FILE_MAP_READ;\n                break;\n\n            case Mode.readWriteNew:\n                assert(size != 0);\n                dwDesiredAccess2 = GENERIC_READ | GENERIC_WRITE;\n                dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;\n                dwCreationDisposition = CREATE_ALWAYS;\n                flProtect = PAGE_READWRITE;\n                dwDesiredAccess = FILE_MAP_WRITE;\n                break;\n\n            case Mode.readWrite:\n                dwDesiredAccess2 = GENERIC_READ | GENERIC_WRITE;\n                dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;\n                dwCreationDisposition = OPEN_ALWAYS;\n                flProtect = PAGE_READWRITE;\n                dwDesiredAccess = FILE_MAP_WRITE;\n                break;\n\n            case Mode.readCopyOnWrite:\n                dwDesiredAccess2 = GENERIC_READ | GENERIC_WRITE;\n                dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;\n                dwCreationDisposition = OPEN_EXISTING;\n                flProtect = PAGE_WRITECOPY;\n                dwDesiredAccess = FILE_MAP_COPY;\n                break;\n            }\n\n            if (filename != null)\n            {\n                hFile = CreateFileW(filename.tempCStringW(),\n                        dwDesiredAccess2,\n                        dwShareMode,\n                        null,\n                        dwCreationDisposition,\n                        FILE_ATTRIBUTE_NORMAL,\n                        cast(HANDLE) null);\n                wenforce(hFile != INVALID_HANDLE_VALUE, \"CreateFileW\");\n            }\n            else\n                hFile = INVALID_HANDLE_VALUE;\n\n            scope(failure)\n            {\n                if (hFile != INVALID_HANDLE_VALUE)\n                {\n                    CloseHandle(hFile);\n                    hFile = INVALID_HANDLE_VALUE;\n                }\n            }\n\n            int hi = cast(int)(size >> 32);\n            hFileMap = CreateFileMappingW(hFile, null, flProtect,\n                    hi, cast(uint) size, null);\n            wenforce(hFileMap, \"CreateFileMapping\");\n            scope(failure)\n            {\n                CloseHandle(hFileMap);\n                hFileMap = null;\n            }\n\n            if (size == 0 && filename != null)\n            {\n                uint sizehi;\n                uint sizelow = GetFileSize(hFile, &sizehi);\n                wenforce(sizelow != INVALID_FILE_SIZE || GetLastError() != ERROR_SUCCESS,\n                    \"GetFileSize\");\n                size = (cast(ulong) sizehi << 32) + sizelow;\n            }\n            this.size = size;\n\n            size_t initial_map = (window && 2*window<size)\n                ? 2*window : cast(size_t) size;\n            p = MapViewOfFileEx(hFileMap, dwDesiredAccess, 0, 0,\n                    initial_map, address);\n            wenforce(p, \"MapViewOfFileEx\");\n            data = p[0 .. initial_map];\n\n            debug (MMFILE) printf(\"MmFile.this(): p = %p, size = %d\\n\", p, size);\n        }\n        else version (Posix)\n        {\n            void* p;\n            int oflag;\n            int fmode;\n\n            final switch (mode)\n            {\n            case Mode.read:\n                flags = MAP_SHARED;\n                prot = PROT_READ;\n                oflag = O_RDONLY;\n                fmode = 0;\n                break;\n\n            case Mode.readWriteNew:\n                assert(size != 0);\n                flags = MAP_SHARED;\n                prot = PROT_READ | PROT_WRITE;\n                oflag = O_CREAT | O_RDWR | O_TRUNC;\n                fmode = octal!660;\n                break;\n\n            case Mode.readWrite:\n                flags = MAP_SHARED;\n                prot = PROT_READ | PROT_WRITE;\n                oflag = O_CREAT | O_RDWR;\n                fmode = octal!660;\n                break;\n\n            case Mode.readCopyOnWrite:\n                flags = MAP_PRIVATE;\n                prot = PROT_READ | PROT_WRITE;\n                oflag = O_RDWR;\n                fmode = 0;\n                break;\n            }\n\n            if (filename.length)\n            {\n                fd = .open(filename.tempCString(), oflag, fmode);\n                errnoEnforce(fd != -1, \"Could not open file \"~filename);\n\n                stat_t statbuf;\n                if (fstat(fd, &statbuf))\n                {\n                    //printf(\"\\tfstat error, errno = %d\\n\", errno);\n                    .close(fd);\n                    fd = -1;\n                    errnoEnforce(false, \"Could not stat file \"~filename);\n                }\n\n                if (prot & PROT_WRITE && size > statbuf.st_size)\n                {\n                    // Need to make the file size bytes big\n                    .lseek(fd, cast(off_t)(size - 1), SEEK_SET);\n                    char c = 0;\n                    core.sys.posix.unistd.write(fd, &c, 1);\n                }\n                else if (prot & PROT_READ && size == 0)\n                    size = statbuf.st_size;\n            }\n            else\n            {\n                fd = -1;\n                version (CRuntime_Glibc) import core.sys.linux.sys.mman : MAP_ANON;\n                flags |= MAP_ANON;\n            }\n            this.size = size;\n            size_t initial_map = (window && 2*window<size)\n                ? 2*window : cast(size_t) size;\n            p = mmap(address, initial_map, prot, flags, fd, 0);\n            if (p == MAP_FAILED)\n            {\n                if (fd != -1)\n                {\n                    .close(fd);\n                    fd = -1;\n                }\n                errnoEnforce(false, \"Could not map file \"~filename);\n            }\n\n            data = p[0 .. initial_map];\n        }\n        else\n        {\n            static assert(0);\n        }\n    }\n\n    /**\n     * Flushes pending output and closes the memory mapped file.\n     */\n    ~this()\n    {\n        debug (MMFILE) printf(\"MmFile.~this()\\n\");\n        unmap();\n        data = null;\n        version (Windows)\n        {\n            wenforce(hFileMap == null || CloseHandle(hFileMap) == TRUE,\n                    \"Could not close file handle\");\n            hFileMap = null;\n\n            wenforce(!hFile || hFile == INVALID_HANDLE_VALUE\n                    || CloseHandle(hFile) == TRUE,\n                    \"Could not close handle\");\n            hFile = INVALID_HANDLE_VALUE;\n        }\n        else version (Posix)\n        {\n            version (linux)\n            {\n                if (file !is File.init)\n                {\n                    // The File destructor will close the file,\n                    // if it is the only remaining reference.\n                    return;\n                }\n            }\n            errnoEnforce(fd == -1 || fd <= 2\n                    || .close(fd) != -1,\n                    \"Could not close handle\");\n            fd = -1;\n        }\n        else\n        {\n            static assert(0);\n        }\n    }\n\n    /* Flush any pending output.\n     */\n    void flush()\n    {\n        debug (MMFILE) printf(\"MmFile.flush()\\n\");\n        version (Windows)\n        {\n            FlushViewOfFile(data.ptr, data.length);\n        }\n        else version (Posix)\n        {\n            int i;\n            i = msync(cast(void*) data, data.length, MS_SYNC);   // sys/mman.h\n            errnoEnforce(i == 0, \"msync failed\");\n        }\n        else\n        {\n            static assert(0);\n        }\n    }\n\n    /**\n     * Gives size in bytes of the memory mapped file.\n     */\n    @property ulong length() const\n    {\n        debug (MMFILE) printf(\"MmFile.length()\\n\");\n        return size;\n    }\n\n    /**\n     * Forwards `length`.\n     */\n    alias opDollar = length;\n\n    /**\n     * Read-only property returning the file mode.\n     */\n    Mode mode()\n    {\n        debug (MMFILE) printf(\"MmFile.mode()\\n\");\n        return mMode;\n    }\n\n    /**\n     * Returns entire file contents as an array.\n     */\n    void[] opSlice()\n    {\n        debug (MMFILE) printf(\"MmFile.opSlice()\\n\");\n        return opSlice(0,size);\n    }\n\n    /**\n     * Returns slice of file contents as an array.\n     */\n    void[] opSlice(ulong i1, ulong i2)\n    {\n        debug (MMFILE) printf(\"MmFile.opSlice(%lld, %lld)\\n\", i1, i2);\n        ensureMapped(i1,i2);\n        size_t off1 = cast(size_t)(i1-start);\n        size_t off2 = cast(size_t)(i2-start);\n        return data[off1 .. off2];\n    }\n\n    /**\n     * Returns byte at index i in file.\n     */\n    ubyte opIndex(ulong i)\n    {\n        debug (MMFILE) printf(\"MmFile.opIndex(%lld)\\n\", i);\n        ensureMapped(i);\n        size_t off = cast(size_t)(i-start);\n        return (cast(ubyte[]) data)[off];\n    }\n\n    /**\n     * Sets and returns byte at index i in file to value.\n     */\n    ubyte opIndexAssign(ubyte value, ulong i)\n    {\n        debug (MMFILE) printf(\"MmFile.opIndex(%lld, %d)\\n\", i, value);\n        ensureMapped(i);\n        size_t off = cast(size_t)(i-start);\n        return (cast(ubyte[]) data)[off] = value;\n    }\n\n\n    // return true if the given position is currently mapped\n    private int mapped(ulong i)\n    {\n        debug (MMFILE) printf(\"MmFile.mapped(%lld, %lld, %d)\\n\", i,start,\n                data.length);\n        return i >= start && i < start+data.length;\n    }\n\n    // unmap the current range\n    private void unmap()\n    {\n        debug (MMFILE) printf(\"MmFile.unmap()\\n\");\n        version (Windows)\n        {\n            wenforce(!data.ptr || UnmapViewOfFile(data.ptr) != FALSE, \"UnmapViewOfFile\");\n        }\n        else\n        {\n            errnoEnforce(!data.ptr || munmap(cast(void*) data, data.length) == 0,\n                    \"munmap failed\");\n        }\n        data = null;\n    }\n\n    // map range\n    private void map(ulong start, size_t len)\n    {\n        debug (MMFILE) printf(\"MmFile.map(%lld, %d)\\n\", start, len);\n        void* p;\n        if (start+len > size)\n            len = cast(size_t)(size-start);\n        version (Windows)\n        {\n            uint hi = cast(uint)(start >> 32);\n            p = MapViewOfFileEx(hFileMap, dwDesiredAccess, hi, cast(uint) start, len, address);\n            wenforce(p, \"MapViewOfFileEx\");\n        }\n        else\n        {\n            p = mmap(address, len, prot, flags, fd, cast(off_t) start);\n            errnoEnforce(p != MAP_FAILED);\n        }\n        data = p[0 .. len];\n        this.start = start;\n    }\n\n    // ensure a given position is mapped\n    private void ensureMapped(ulong i)\n    {\n        debug (MMFILE) printf(\"MmFile.ensureMapped(%lld)\\n\", i);\n        if (!mapped(i))\n        {\n            unmap();\n            if (window == 0)\n            {\n                map(0,cast(size_t) size);\n            }\n            else\n            {\n                ulong block = i/window;\n                if (block == 0)\n                    map(0,2*window);\n                else\n                    map(window*(block-1),3*window);\n            }\n        }\n    }\n\n    // ensure a given range is mapped\n    private void ensureMapped(ulong i, ulong j)\n    {\n        debug (MMFILE) printf(\"MmFile.ensureMapped(%lld, %lld)\\n\", i, j);\n        if (!mapped(i) || !mapped(j-1))\n        {\n            unmap();\n            if (window == 0)\n            {\n                map(0,cast(size_t) size);\n            }\n            else\n            {\n                ulong iblock = i/window;\n                ulong jblock = (j-1)/window;\n                if (iblock == 0)\n                {\n                    map(0,cast(size_t)(window*(jblock+2)));\n                }\n                else\n                {\n                    map(window*(iblock-1),cast(size_t)(window*(jblock-iblock+3)));\n                }\n            }\n        }\n    }\n\nprivate:\n    string filename;\n    void[] data;\n    ulong  start;\n    size_t window;\n    ulong  size;\n    Mode   mMode;\n    void*  address;\n    version (linux) File file;\n\n    version (Windows)\n    {\n        HANDLE hFile = INVALID_HANDLE_VALUE;\n        HANDLE hFileMap = null;\n        uint dwDesiredAccess;\n    }\n    else version (Posix)\n    {\n        int fd;\n        int prot;\n        int flags;\n        int fmode;\n    }\n    else\n    {\n        static assert(0);\n    }\n\n    // Report error, where errno gives the error number\n    // void errNo()\n    // {\n    //     version (Windows)\n    //     {\n    //         throw new FileException(filename, GetLastError());\n    //     }\n    //     else version (linux)\n    //     {\n    //         throw new FileException(filename, errno);\n    //     }\n    //     else\n    //     {\n    //         static assert(0);\n    //     }\n    // }\n}\n\n@system unittest\n{\n    import core.memory : GC;\n    import std.file : deleteme;\n\n    const size_t K = 1024;\n    size_t win = 64*K; // assume the page size is 64K\n    version (Windows)\n    {\n        /+ these aren't defined in core.sys.windows.windows so let's use default\n         SYSTEM_INFO sysinfo;\n         GetSystemInfo(&sysinfo);\n         win = sysinfo.dwAllocationGranularity;\n         +/\n    }\n    else version (linux)\n    {\n        // getpagesize() is not defined in the unix D headers so use the guess\n    }\n    string test_file = std.file.deleteme ~ \"-testing.txt\";\n    MmFile mf = new MmFile(test_file,MmFile.Mode.readWriteNew,\n            100*K,null,win);\n    ubyte[] str = cast(ubyte[])\"1234567890\";\n    ubyte[] data = cast(ubyte[]) mf[0 .. 10];\n    data[] = str[];\n    assert( mf[0 .. 10] == str );\n    data = cast(ubyte[]) mf[50 .. 60];\n    data[] = str[];\n    assert( mf[50 .. 60] == str );\n    ubyte[] data2 = cast(ubyte[]) mf[20*K .. 60*K];\n    assert( data2.length == 40*K );\n    assert( data2[$-1] == 0 );\n    mf[100*K-1] = cast(ubyte)'b';\n    data2 = cast(ubyte[]) mf[21*K .. 100*K];\n    assert( data2.length == 79*K );\n    assert( data2[$-1] == 'b' );\n\n    destroy(mf);\n    GC.free(&mf);\n\n    std.file.remove(test_file);\n    // Create anonymous mapping\n    auto test = new MmFile(null, MmFile.Mode.readWriteNew, 1024*1024, null);\n}\n\nversion (linux)\n@system unittest // Issue 14868\n{\n    import std.file : deleteme;\n    import std.typecons : scoped;\n\n    // Test retaining ownership of File/fd\n\n    auto fn = std.file.deleteme ~ \"-testing.txt\";\n    scope(exit) std.file.remove(fn);\n    File(fn, \"wb\").writeln(\"Testing!\");\n    scoped!MmFile(File(fn));\n\n    // Test that unique ownership of File actually leads to the fd being closed\n\n    auto f = File(fn);\n    auto fd = f.fileno;\n    {\n        auto mf = scoped!MmFile(f);\n        f = File.init;\n    }\n    assert(.close(fd) == -1);\n}\n\n@system unittest // Issue 14994, 14995\n{\n    import std.file : deleteme;\n    import std.typecons : scoped;\n\n    // Zero-length map may or may not be valid on OSX and NetBSD\n    version (OSX)\n        import std.exception : verifyThrown = collectException;\n    version (NetBSD)\n        import std.exception : verifyThrown = collectException;\n    else\n        import std.exception : verifyThrown = assertThrown;\n\n    auto fn = std.file.deleteme ~ \"-testing.txt\";\n    scope(exit) std.file.remove(fn);\n    verifyThrown(scoped!MmFile(fn, MmFile.Mode.readWrite, 0, null));\n}\n\n@system unittest\n{\n    MmFile shar = new MmFile(null, MmFile.Mode.readWrite, 10, null, 0);\n    void[] output = shar[0 .. $];\n}\n"
  },
  {
    "path": "libphobos/src/std/net/curl.d",
    "content": "// Written in the D programming language.\n\n/**\nNetworking client functionality as provided by $(HTTP curl.haxx.se/libcurl,\nlibcurl). The libcurl library must be installed on the system in order to use\nthis module.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n\n$(DIVC quickindex,\n$(BOOKTABLE ,\n$(TR $(TH Category) $(TH Functions)\n)\n$(TR $(TDNW High level) $(TD $(MYREF download) $(MYREF upload) $(MYREF get)\n$(MYREF post) $(MYREF put) $(MYREF del) $(MYREF options) $(MYREF trace)\n$(MYREF connect) $(MYREF byLine) $(MYREF byChunk)\n$(MYREF byLineAsync) $(MYREF byChunkAsync) )\n)\n$(TR $(TDNW Low level) $(TD $(MYREF HTTP) $(MYREF FTP) $(MYREF\nSMTP) )\n)\n)\n)\n\nNote:\nYou may need to link to the $(B curl) library, e.g. by adding $(D \"libs\": [\"curl\"])\nto your $(B dub.json) file if you are using $(LINK2 http://code.dlang.org, DUB).\n\nWindows x86 note:\nA DMD compatible libcurl static library can be downloaded from the dlang.org\n$(LINK2 http://downloads.dlang.org/other/index.html, download archive page).\n\nCompared to using libcurl directly this module allows simpler client code for\ncommon uses, requires no unsafe operations, and integrates better with the rest\nof the language. Futhermore it provides $(MREF_ALTTEXT range, std,range)\naccess to protocols supported by libcurl both synchronously and asynchronously.\n\nA high level and a low level API are available. The high level API is built\nentirely on top of the low level one.\n\nThe high level API is for commonly used functionality such as HTTP/FTP get. The\n$(LREF byLineAsync) and $(LREF byChunkAsync) provides asynchronous\n$(MREF_ALTTEXT range, std,range) that performs the request in another\nthread while handling a line/chunk in the current thread.\n\nThe low level API allows for streaming and other advanced features.\n\n$(BOOKTABLE Cheat Sheet,\n$(TR $(TH Function Name) $(TH Description)\n)\n$(LEADINGROW High level)\n$(TR $(TDNW $(LREF download)) $(TD $(D\ndownload(\"ftp.digitalmars.com/sieve.ds\", \"/tmp/downloaded-ftp-file\"))\ndownloads file from URL to file system.)\n)\n$(TR $(TDNW $(LREF upload)) $(TD $(D\nupload(\"/tmp/downloaded-ftp-file\", \"ftp.digitalmars.com/sieve.ds\");)\nuploads file from file system to URL.)\n)\n$(TR $(TDNW $(LREF get)) $(TD $(D\nget(\"dlang.org\")) returns a char[] containing the dlang.org web page.)\n)\n$(TR $(TDNW $(LREF put)) $(TD $(D\nput(\"dlang.org\", \"Hi\")) returns a char[] containing\nthe dlang.org web page. after a HTTP PUT of \"hi\")\n)\n$(TR $(TDNW $(LREF post)) $(TD $(D\npost(\"dlang.org\", \"Hi\")) returns a char[] containing\nthe dlang.org web page. after a HTTP POST of \"hi\")\n)\n$(TR $(TDNW $(LREF byLine)) $(TD $(D\nbyLine(\"dlang.org\")) returns a range of char[] containing the\ndlang.org web page.)\n)\n$(TR $(TDNW $(LREF byChunk)) $(TD $(D\nbyChunk(\"dlang.org\", 10)) returns a range of ubyte[10] containing the\ndlang.org web page.)\n)\n$(TR $(TDNW $(LREF byLineAsync)) $(TD $(D\nbyLineAsync(\"dlang.org\")) returns a range of char[] containing the dlang.org web\n page asynchronously.)\n)\n$(TR $(TDNW $(LREF byChunkAsync)) $(TD $(D\nbyChunkAsync(\"dlang.org\", 10)) returns a range of ubyte[10] containing the\ndlang.org web page asynchronously.)\n)\n$(LEADINGROW Low level\n)\n$(TR $(TDNW $(LREF HTTP)) $(TD `HTTP` struct for advanced usage))\n$(TR $(TDNW $(LREF FTP)) $(TD `FTP` struct for advanced usage))\n$(TR $(TDNW $(LREF SMTP)) $(TD `SMTP` struct for advanced usage))\n)\n\n\nExample:\n---\nimport std.net.curl, std.stdio;\n\n// Return a char[] containing the content specified by a URL\nauto content = get(\"dlang.org\");\n\n// Post data and return a char[] containing the content specified by a URL\nauto content = post(\"mydomain.com/here.cgi\", [\"name1\" : \"value1\", \"name2\" : \"value2\"]);\n\n// Get content of file from ftp server\nauto content = get(\"ftp.digitalmars.com/sieve.ds\");\n\n// Post and print out content line by line. The request is done in another thread.\nforeach (line; byLineAsync(\"dlang.org\", \"Post data\"))\n    writeln(line);\n\n// Get using a line range and proxy settings\nauto client = HTTP();\nclient.proxy = \"1.2.3.4\";\nforeach (line; byLine(\"dlang.org\", client))\n    writeln(line);\n---\n\nFor more control than the high level functions provide, use the low level API:\n\nExample:\n---\nimport std.net.curl, std.stdio;\n\n// GET with custom data receivers\nauto http = HTTP(\"dlang.org\");\nhttp.onReceiveHeader =\n    (in char[] key, in char[] value) { writeln(key, \": \", value); };\nhttp.onReceive = (ubyte[] data) { /+ drop +/ return data.length; };\nhttp.perform();\n---\n\nFirst, an instance of the reference-counted HTTP struct is created. Then the\ncustom delegates are set. These will be called whenever the HTTP instance\nreceives a header and a data buffer, respectively. In this simple example, the\nheaders are written to stdout and the data is ignored. If the request should be\nstopped before it has finished then return something less than data.length from\nthe onReceive callback. See $(LREF onReceiveHeader)/$(LREF onReceive) for more\ninformation. Finally the HTTP request is effected by calling perform(), which is\nsynchronous.\n\nSource: $(PHOBOSSRC std/net/curl.d)\n\nCopyright: Copyright Jonas Drewsen 2011-2012\nLicense: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors: Jonas Drewsen. Some of the SMTP code contributed by Jimmy Cao.\n\nCredits: The functionally is based on $(HTTP curl.haxx.se/libcurl, libcurl).\n         LibCurl is licensed under an MIT/X derivative license.\n*/\n/*\n         Copyright Jonas Drewsen 2011 - 2012.\nDistributed under the Boost Software License, Version 1.0.\n   (See accompanying file LICENSE_1_0.txt or copy at\n         http://www.boost.org/LICENSE_1_0.txt)\n*/\nmodule std.net.curl;\n\npublic import etc.c.curl : CurlOption;\nimport core.time : dur;\nimport etc.c.curl : CURLcode;\nimport std.range.primitives;\nimport std.encoding : EncodingScheme;\nimport std.traits : isSomeChar;\nimport std.typecons : Flag, Yes, No, Tuple;\n\n// Curl tests for FreeBSD 32-bit are temporarily disabled.\n// https://github.com/braddr/d-tester/issues/70\n// https://issues.dlang.org/show_bug.cgi?id=18519\nversion (unittest)\nversion (FreeBSD)\nversion (X86)\n    version = DisableCurlTests;\n\nversion (DisableCurlTests) {} else:\n\nversion (unittest)\n{\n    import std.socket : Socket;\n\n    private struct TestServer\n    {\n        import std.concurrency : Tid;\n\n        import std.socket : Socket, TcpSocket;\n\n        string addr() { return _addr; }\n\n        void handle(void function(Socket s) dg)\n        {\n            import std.concurrency : send;\n            tid.send(dg);\n        }\n\n    private:\n        string _addr;\n        Tid tid;\n        TcpSocket sock;\n\n        static void loop(shared TcpSocket listener)\n        {\n            import std.concurrency : OwnerTerminated, receiveOnly;\n            import std.stdio : stderr;\n\n            try while (true)\n            {\n                void function(Socket) handler = void;\n                try\n                    handler = receiveOnly!(typeof(handler));\n                catch (OwnerTerminated)\n                    return;\n                handler((cast() listener).accept);\n            }\n            catch (Throwable e)\n            {\n                import core.stdc.stdlib : exit, EXIT_FAILURE;\n                stderr.writeln(e);\n                exit(EXIT_FAILURE); // Bugzilla 7018\n            }\n        }\n    }\n\n    private TestServer startServer()\n    {\n        import std.concurrency : spawn;\n        import std.socket : INADDR_LOOPBACK, InternetAddress, TcpSocket;\n\n        tlsInit = true;\n        auto sock = new TcpSocket;\n        sock.bind(new InternetAddress(INADDR_LOOPBACK, InternetAddress.PORT_ANY));\n        sock.listen(1);\n        auto addr = sock.localAddress.toString();\n        auto tid = spawn(&TestServer.loop, cast(shared) sock);\n        return TestServer(addr, tid, sock);\n    }\n\n    __gshared TestServer server;\n    bool tlsInit;\n\n    private ref TestServer testServer()\n    {\n        import std.concurrency : initOnce;\n        return initOnce!server(startServer());\n    }\n\n    static ~this()\n    {\n        // terminate server from a thread local dtor of the thread that started it,\n        //  because thread_joinall is called before shared module dtors\n        if (tlsInit && server.sock)\n            server.sock.close();\n    }\n\n    private struct Request(T)\n    {\n        string hdrs;\n        immutable(T)[] bdy;\n    }\n\n    private Request!T recvReq(T=char)(Socket s)\n    {\n        import std.algorithm.comparison : min;\n        import std.algorithm.searching : find, canFind;\n        import std.conv : to;\n        import std.regex : ctRegex, matchFirst;\n\n        ubyte[1024] tmp=void;\n        ubyte[] buf;\n\n        while (true)\n        {\n            auto nbytes = s.receive(tmp[]);\n            assert(nbytes >= 0);\n\n            immutable beg = buf.length > 3 ? buf.length - 3 : 0;\n            buf ~= tmp[0 .. nbytes];\n            auto bdy = buf[beg .. $].find(cast(ubyte[])\"\\r\\n\\r\\n\");\n            if (bdy.empty)\n                continue;\n\n            auto hdrs = cast(string) buf[0 .. $ - bdy.length];\n            bdy.popFrontN(4);\n            // no support for chunked transfer-encoding\n            if (auto m = hdrs.matchFirst(ctRegex!(`Content-Length: ([0-9]+)`, \"i\")))\n            {\n                import std.uni : asUpperCase;\n                if (hdrs.asUpperCase.canFind(\"EXPECT: 100-CONTINUE\"))\n                    s.send(httpContinue);\n\n                size_t remain = m.captures[1].to!size_t - bdy.length;\n                while (remain)\n                {\n                    nbytes = s.receive(tmp[0 .. min(remain, $)]);\n                    assert(nbytes >= 0);\n                    buf ~= tmp[0 .. nbytes];\n                    remain -= nbytes;\n                }\n            }\n            else\n            {\n                assert(bdy.empty);\n            }\n            bdy = buf[hdrs.length + 4 .. $];\n            return typeof(return)(hdrs, cast(immutable(T)[])bdy);\n        }\n    }\n\n    private string httpOK(string msg)\n    {\n        import std.conv : to;\n\n        return \"HTTP/1.1 200 OK\\r\\n\"~\n            \"Content-Type: text/plain\\r\\n\"~\n            \"Content-Length: \"~msg.length.to!string~\"\\r\\n\"~\n            \"\\r\\n\"~\n            msg;\n    }\n\n    private string httpOK()\n    {\n        return \"HTTP/1.1 200 OK\\r\\n\"~\n            \"Content-Length: 0\\r\\n\"~\n            \"\\r\\n\";\n    }\n\n    private string httpNotFound()\n    {\n        return \"HTTP/1.1 404 Not Found\\r\\n\"~\n            \"Content-Length: 0\\r\\n\"~\n            \"\\r\\n\";\n    }\n\n    private enum httpContinue = \"HTTP/1.1 100 Continue\\r\\n\\r\\n\";\n}\nversion (StdDdoc) import std.stdio;\n\n// Default data timeout for Protocols\nprivate enum _defaultDataTimeout = dur!\"minutes\"(2);\n\n/**\nMacros:\n\nCALLBACK_PARAMS = $(TABLE ,\n    $(DDOC_PARAM_ROW\n        $(DDOC_PARAM_ID $(DDOC_PARAM dlTotal))\n        $(DDOC_PARAM_DESC total bytes to download)\n        )\n    $(DDOC_PARAM_ROW\n        $(DDOC_PARAM_ID $(DDOC_PARAM dlNow))\n        $(DDOC_PARAM_DESC currently downloaded bytes)\n        )\n    $(DDOC_PARAM_ROW\n        $(DDOC_PARAM_ID $(DDOC_PARAM ulTotal))\n        $(DDOC_PARAM_DESC total bytes to upload)\n        )\n    $(DDOC_PARAM_ROW\n        $(DDOC_PARAM_ID $(DDOC_PARAM ulNow))\n        $(DDOC_PARAM_DESC currently uploaded bytes)\n        )\n)\n*/\n\n/** Connection type used when the URL should be used to auto detect the protocol.\n  *\n  * This struct is used as placeholder for the connection parameter when calling\n  * the high level API and the connection type (HTTP/FTP) should be guessed by\n  * inspecting the URL parameter.\n  *\n  * The rules for guessing the protocol are:\n  * 1, if URL starts with ftp://, ftps:// or ftp. then FTP connection is assumed.\n  * 2, HTTP connection otherwise.\n  *\n  * Example:\n  * ---\n  * import std.net.curl;\n  * // Two requests below will do the same.\n  * char[] content;\n  *\n  * // Explicit connection provided\n  * content = get!HTTP(\"dlang.org\");\n  *\n  * // Guess connection type by looking at the URL\n  * content = get!AutoProtocol(\"ftp://foo.com/file\");\n  * // and since AutoProtocol is default this is the same as\n  * content = get(\"ftp://foo.com/file\");\n  * // and will end up detecting FTP from the url and be the same as\n  * content = get!FTP(\"ftp://foo.com/file\");\n  * ---\n  */\nstruct AutoProtocol { }\n\n// Returns true if the url points to an FTP resource\nprivate bool isFTPUrl(const(char)[] url)\n{\n    import std.algorithm.searching : startsWith;\n    import std.uni : toLower;\n\n    return startsWith(url.toLower(), \"ftp://\", \"ftps://\", \"ftp.\") != 0;\n}\n\n// Is true if the Conn type is a valid Curl Connection type.\nprivate template isCurlConn(Conn)\n{\n    enum auto isCurlConn = is(Conn : HTTP) ||\n        is(Conn : FTP) || is(Conn : AutoProtocol);\n}\n\n/** HTTP/FTP download to local file system.\n *\n * Params:\n * url = resource to download\n * saveToPath = path to store the downloaded content on local disk\n * conn = connection to use e.g. FTP or HTTP. The default AutoProtocol will\n *        guess connection type and create a new instance for this call only.\n *\n * Example:\n * ----\n * import std.net.curl;\n * download(\"https://httpbin.org/get\", \"/tmp/downloaded-http-file\");\n * ----\n */\nvoid download(Conn = AutoProtocol)(const(char)[] url, string saveToPath, Conn conn = Conn())\nif (isCurlConn!Conn)\n{\n    static if (is(Conn : HTTP) || is(Conn : FTP))\n    {\n        import std.stdio : File;\n        conn.url = url;\n        auto f = File(saveToPath, \"wb\");\n        conn.onReceive = (ubyte[] data) { f.rawWrite(data); return data.length; };\n        conn.perform();\n    }\n    else\n    {\n        if (isFTPUrl(url))\n            return download!FTP(url, saveToPath, FTP());\n        else\n            return download!HTTP(url, saveToPath, HTTP());\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n    static import std.file;\n\n    foreach (host; [testServer.addr, \"http://\"~testServer.addr])\n    {\n        testServer.handle((s) {\n            assert(s.recvReq.hdrs.canFind(\"GET /\"));\n            s.send(httpOK(\"Hello world\"));\n        });\n        auto fn = std.file.deleteme;\n        scope (exit) std.file.remove(fn);\n        download(host, fn);\n        assert(std.file.readText(fn) == \"Hello world\");\n    }\n}\n\n/** Upload file from local files system using the HTTP or FTP protocol.\n *\n * Params:\n * loadFromPath = path load data from local disk.\n * url = resource to upload to\n * conn = connection to use e.g. FTP or HTTP. The default AutoProtocol will\n *        guess connection type and create a new instance for this call only.\n *\n * Example:\n * ----\n * import std.net.curl;\n * upload(\"/tmp/downloaded-ftp-file\", \"ftp.digitalmars.com/sieve.ds\");\n * upload(\"/tmp/downloaded-http-file\", \"https://httpbin.org/post\");\n * ----\n */\nvoid upload(Conn = AutoProtocol)(string loadFromPath, const(char)[] url, Conn conn = Conn())\nif (isCurlConn!Conn)\n{\n    static if (is(Conn : HTTP))\n    {\n        conn.url = url;\n        conn.method = HTTP.Method.put;\n    }\n    else static if (is(Conn : FTP))\n    {\n        conn.url = url;\n        conn.handle.set(CurlOption.upload, 1L);\n    }\n    else\n    {\n        if (isFTPUrl(url))\n            return upload!FTP(loadFromPath, url, FTP());\n        else\n            return upload!HTTP(loadFromPath, url, HTTP());\n    }\n\n    static if (is(Conn : HTTP) || is(Conn : FTP))\n    {\n        import std.stdio : File;\n        auto f = File(loadFromPath, \"rb\");\n        conn.onSend = buf => f.rawRead(buf).length;\n        immutable sz = f.size;\n        if (sz != ulong.max)\n            conn.contentLength = sz;\n        conn.perform();\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n    static import std.file;\n\n    foreach (host; [testServer.addr, \"http://\"~testServer.addr])\n    {\n        auto fn = std.file.deleteme;\n        scope (exit) std.file.remove(fn);\n        std.file.write(fn, \"upload data\\n\");\n        testServer.handle((s) {\n            auto req = s.recvReq;\n            assert(req.hdrs.canFind(\"PUT /path\"));\n            assert(req.bdy.canFind(\"upload data\"));\n            s.send(httpOK());\n        });\n        upload(fn, host ~ \"/path\");\n    }\n}\n\n/** HTTP/FTP get content.\n *\n * Params:\n * url = resource to get\n * conn = connection to use e.g. FTP or HTTP. The default AutoProtocol will\n *        guess connection type and create a new instance for this call only.\n *\n * The template parameter `T` specifies the type to return. Possible values\n * are `char` and `ubyte` to return `char[]` or `ubyte[]`. If asking\n * for `char`, content will be converted from the connection character set\n * (specified in HTTP response headers or FTP connection properties, both ISO-8859-1\n * by default) to UTF-8.\n *\n * Example:\n * ----\n * import std.net.curl;\n * auto content = get(\"https://httpbin.org/get\");\n * ----\n *\n * Returns:\n * A T[] range containing the content of the resource pointed to by the URL.\n *\n * Throws:\n *\n * `CurlException` on error.\n *\n * See_Also: $(LREF HTTP.Method)\n */\nT[] get(Conn = AutoProtocol, T = char)(const(char)[] url, Conn conn = Conn())\nif ( isCurlConn!Conn && (is(T == char) || is(T == ubyte)) )\n{\n    static if (is(Conn : HTTP))\n    {\n        conn.method = HTTP.Method.get;\n        return _basicHTTP!(T)(url, \"\", conn);\n\n    }\n    else static if (is(Conn : FTP))\n    {\n        return _basicFTP!(T)(url, \"\", conn);\n    }\n    else\n    {\n        if (isFTPUrl(url))\n            return get!(FTP,T)(url, FTP());\n        else\n            return get!(HTTP,T)(url, HTTP());\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n\n    foreach (host; [testServer.addr, \"http://\"~testServer.addr])\n    {\n        testServer.handle((s) {\n            assert(s.recvReq.hdrs.canFind(\"GET /path\"));\n            s.send(httpOK(\"GETRESPONSE\"));\n        });\n        auto res = get(host ~ \"/path\");\n        assert(res == \"GETRESPONSE\");\n    }\n}\n\n\n/** HTTP post content.\n *\n * Params:\n *     url = resource to post to\n *     postDict = data to send as the body of the request. An associative array\n *                of `string` is accepted and will be encoded using\n *                www-form-urlencoding\n *     postData = data to send as the body of the request. An array\n *                of an arbitrary type is accepted and will be cast to ubyte[]\n *                before sending it.\n *     conn = HTTP connection to use\n *     T    = The template parameter `T` specifies the type to return. Possible values\n *            are `char` and `ubyte` to return `char[]` or `ubyte[]`. If asking\n *            for `char`, content will be converted from the connection character set\n *            (specified in HTTP response headers or FTP connection properties, both ISO-8859-1\n *            by default) to UTF-8.\n *\n * Examples:\n * ----\n * import std.net.curl;\n *\n * auto content1 = post(\"https://httpbin.org/post\", [\"name1\" : \"value1\", \"name2\" : \"value2\"]);\n * auto content2 = post(\"https://httpbin.org/post\", [1,2,3,4]);\n * ----\n *\n * Returns:\n * A T[] range containing the content of the resource pointed to by the URL.\n *\n * See_Also: $(LREF HTTP.Method)\n */\nT[] post(T = char, PostUnit)(const(char)[] url, const(PostUnit)[] postData, HTTP conn = HTTP())\nif (is(T == char) || is(T == ubyte))\n{\n    conn.method = HTTP.Method.post;\n    return _basicHTTP!(T)(url, postData, conn);\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n\n    foreach (host; [testServer.addr, \"http://\"~testServer.addr])\n    {\n        testServer.handle((s) {\n            auto req = s.recvReq;\n            assert(req.hdrs.canFind(\"POST /path\"));\n            assert(req.bdy.canFind(\"POSTBODY\"));\n            s.send(httpOK(\"POSTRESPONSE\"));\n        });\n        auto res = post(host ~ \"/path\", \"POSTBODY\");\n        assert(res == \"POSTRESPONSE\");\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n\n    auto data = new ubyte[](256);\n    foreach (i, ref ub; data)\n        ub = cast(ubyte) i;\n\n    testServer.handle((s) {\n        auto req = s.recvReq!ubyte;\n        assert(req.bdy.canFind(cast(ubyte[])[0, 1, 2, 3, 4]));\n        assert(req.bdy.canFind(cast(ubyte[])[253, 254, 255]));\n        s.send(httpOK(cast(ubyte[])[17, 27, 35, 41]));\n    });\n    auto res = post!ubyte(testServer.addr, data);\n    assert(res == cast(ubyte[])[17, 27, 35, 41]);\n}\n\n/// ditto\nT[] post(T = char)(const(char)[] url, string[string] postDict, HTTP conn = HTTP())\nif (is(T == char) || is(T == ubyte))\n{\n    import std.uri : urlEncode;\n\n    return post!T(url, urlEncode(postDict), conn);\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n    import std.meta : AliasSeq;\n\n    static immutable expected = [\"name1=value1&name2=value2\", \"name2=value2&name1=value1\"];\n\n    foreach (host; [testServer.addr, \"http://\" ~ testServer.addr])\n    {\n        foreach (T; AliasSeq!(char, ubyte))\n        {\n            testServer.handle((s) {\n                auto req = s.recvReq!char;\n                s.send(httpOK(req.bdy));\n            });\n            auto res = post!T(host ~ \"/path\", [\"name1\" : \"value1\", \"name2\" : \"value2\"]);\n            assert(canFind(expected, res));\n        }\n    }\n}\n\n/** HTTP/FTP put content.\n *\n * Params:\n * url = resource to put\n * putData = data to send as the body of the request. An array\n *           of an arbitrary type is accepted and will be cast to ubyte[]\n *           before sending it.\n * conn = connection to use e.g. FTP or HTTP. The default AutoProtocol will\n *        guess connection type and create a new instance for this call only.\n *\n * The template parameter `T` specifies the type to return. Possible values\n * are `char` and `ubyte` to return `char[]` or `ubyte[]`. If asking\n * for `char`, content will be converted from the connection character set\n * (specified in HTTP response headers or FTP connection properties, both ISO-8859-1\n * by default) to UTF-8.\n *\n * Example:\n * ----\n * import std.net.curl;\n * auto content = put(\"https://httpbin.org/put\",\n *                      \"Putting this data\");\n * ----\n *\n * Returns:\n * A T[] range containing the content of the resource pointed to by the URL.\n *\n * See_Also: $(LREF HTTP.Method)\n */\nT[] put(Conn = AutoProtocol, T = char, PutUnit)(const(char)[] url, const(PutUnit)[] putData,\n                                                  Conn conn = Conn())\nif ( isCurlConn!Conn && (is(T == char) || is(T == ubyte)) )\n{\n    static if (is(Conn : HTTP))\n    {\n        conn.method = HTTP.Method.put;\n        return _basicHTTP!(T)(url, putData, conn);\n    }\n    else static if (is(Conn : FTP))\n    {\n        return _basicFTP!(T)(url, putData, conn);\n    }\n    else\n    {\n        if (isFTPUrl(url))\n            return put!(FTP,T)(url, putData, FTP());\n        else\n            return put!(HTTP,T)(url, putData, HTTP());\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n\n    foreach (host; [testServer.addr, \"http://\"~testServer.addr])\n    {\n        testServer.handle((s) {\n            auto req = s.recvReq;\n            assert(req.hdrs.canFind(\"PUT /path\"));\n            assert(req.bdy.canFind(\"PUTBODY\"));\n            s.send(httpOK(\"PUTRESPONSE\"));\n        });\n        auto res = put(host ~ \"/path\", \"PUTBODY\");\n        assert(res == \"PUTRESPONSE\");\n    }\n}\n\n\n/** HTTP/FTP delete content.\n *\n * Params:\n * url = resource to delete\n * conn = connection to use e.g. FTP or HTTP. The default AutoProtocol will\n *        guess connection type and create a new instance for this call only.\n *\n * Example:\n * ----\n * import std.net.curl;\n * del(\"https://httpbin.org/delete\");\n * ----\n *\n * See_Also: $(LREF HTTP.Method)\n */\nvoid del(Conn = AutoProtocol)(const(char)[] url, Conn conn = Conn())\nif (isCurlConn!Conn)\n{\n    static if (is(Conn : HTTP))\n    {\n        conn.method = HTTP.Method.del;\n        _basicHTTP!char(url, cast(void[]) null, conn);\n    }\n    else static if (is(Conn : FTP))\n    {\n        import std.algorithm.searching : findSplitAfter;\n        import std.conv : text;\n        import std.exception : enforce;\n\n        auto trimmed = url.findSplitAfter(\"ftp://\")[1];\n        auto t = trimmed.findSplitAfter(\"/\");\n        enum minDomainNameLength = 3;\n        enforce!CurlException(t[0].length > minDomainNameLength,\n                                text(\"Invalid FTP URL for delete \", url));\n        conn.url = t[0];\n\n        enforce!CurlException(!t[1].empty,\n                                text(\"No filename specified to delete for URL \", url));\n        conn.addCommand(\"DELE \" ~ t[1]);\n        conn.perform();\n    }\n    else\n    {\n        if (isFTPUrl(url))\n            return del!FTP(url, FTP());\n        else\n            return del!HTTP(url, HTTP());\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n\n    foreach (host; [testServer.addr, \"http://\"~testServer.addr])\n    {\n        testServer.handle((s) {\n            auto req = s.recvReq;\n            assert(req.hdrs.canFind(\"DELETE /path\"));\n            s.send(httpOK());\n        });\n        del(host ~ \"/path\");\n    }\n}\n\n\n/** HTTP options request.\n *\n * Params:\n * url = resource make a option call to\n * conn = connection to use e.g. FTP or HTTP. The default AutoProtocol will\n *        guess connection type and create a new instance for this call only.\n *\n * The template parameter `T` specifies the type to return. Possible values\n * are `char` and `ubyte` to return `char[]` or `ubyte[]`.\n *\n * Example:\n * ----\n * import std.net.curl;\n * auto http = HTTP();\n * options(\"https://httpbin.org/headers\", http);\n * writeln(\"Allow set to \" ~ http.responseHeaders[\"Allow\"]);\n * ----\n *\n * Returns:\n * A T[] range containing the options of the resource pointed to by the URL.\n *\n * See_Also: $(LREF HTTP.Method)\n */\nT[] options(T = char)(const(char)[] url, HTTP conn = HTTP())\nif (is(T == char) || is(T == ubyte))\n{\n    conn.method = HTTP.Method.options;\n    return _basicHTTP!(T)(url, null, conn);\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n\n    testServer.handle((s) {\n        auto req = s.recvReq;\n        assert(req.hdrs.canFind(\"OPTIONS /path\"));\n        s.send(httpOK(\"OPTIONSRESPONSE\"));\n    });\n    auto res = options(testServer.addr ~ \"/path\");\n    assert(res == \"OPTIONSRESPONSE\");\n}\n\n\n/** HTTP trace request.\n *\n * Params:\n * url = resource make a trace call to\n * conn = connection to use e.g. FTP or HTTP. The default AutoProtocol will\n *        guess connection type and create a new instance for this call only.\n *\n * The template parameter `T` specifies the type to return. Possible values\n * are `char` and `ubyte` to return `char[]` or `ubyte[]`.\n *\n * Example:\n * ----\n * import std.net.curl;\n * trace(\"https://httpbin.org/headers\");\n * ----\n *\n * Returns:\n * A T[] range containing the trace info of the resource pointed to by the URL.\n *\n * See_Also: $(LREF HTTP.Method)\n */\nT[] trace(T = char)(const(char)[] url, HTTP conn = HTTP())\nif (is(T == char) || is(T == ubyte))\n{\n    conn.method = HTTP.Method.trace;\n    return _basicHTTP!(T)(url, cast(void[]) null, conn);\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n\n    testServer.handle((s) {\n        auto req = s.recvReq;\n        assert(req.hdrs.canFind(\"TRACE /path\"));\n        s.send(httpOK(\"TRACERESPONSE\"));\n    });\n    auto res = trace(testServer.addr ~ \"/path\");\n    assert(res == \"TRACERESPONSE\");\n}\n\n\n/** HTTP connect request.\n *\n * Params:\n * url = resource make a connect to\n * conn = HTTP connection to use\n *\n * The template parameter `T` specifies the type to return. Possible values\n * are `char` and `ubyte` to return `char[]` or `ubyte[]`.\n *\n * Example:\n * ----\n * import std.net.curl;\n * connect(\"https://httpbin.org/headers\");\n * ----\n *\n * Returns:\n * A T[] range containing the connect info of the resource pointed to by the URL.\n *\n * See_Also: $(LREF HTTP.Method)\n */\nT[] connect(T = char)(const(char)[] url, HTTP conn = HTTP())\nif (is(T == char) || is(T == ubyte))\n{\n    conn.method = HTTP.Method.connect;\n    return _basicHTTP!(T)(url, cast(void[]) null, conn);\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n\n    testServer.handle((s) {\n        auto req = s.recvReq;\n        assert(req.hdrs.canFind(\"CONNECT /path\"));\n        s.send(httpOK(\"CONNECTRESPONSE\"));\n    });\n    auto res = connect(testServer.addr ~ \"/path\");\n    assert(res == \"CONNECTRESPONSE\");\n}\n\n\n/** HTTP patch content.\n *\n * Params:\n * url = resource to patch\n * patchData = data to send as the body of the request. An array\n *           of an arbitrary type is accepted and will be cast to ubyte[]\n *           before sending it.\n * conn = HTTP connection to use\n *\n * The template parameter `T` specifies the type to return. Possible values\n * are `char` and `ubyte` to return `char[]` or `ubyte[]`.\n *\n * Example:\n * ----\n * auto http = HTTP();\n * http.addRequestHeader(\"Content-Type\", \"application/json\");\n * auto content = patch(\"https://httpbin.org/patch\", `{\"title\": \"Patched Title\"}`, http);\n * ----\n *\n * Returns:\n * A T[] range containing the content of the resource pointed to by the URL.\n *\n * See_Also: $(LREF HTTP.Method)\n */\nT[] patch(T = char, PatchUnit)(const(char)[] url, const(PatchUnit)[] patchData,\n                               HTTP conn = HTTP())\nif (is(T == char) || is(T == ubyte))\n{\n    conn.method = HTTP.Method.patch;\n    return _basicHTTP!(T)(url, patchData, conn);\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n\n    testServer.handle((s) {\n        auto req = s.recvReq;\n        assert(req.hdrs.canFind(\"PATCH /path\"));\n        assert(req.bdy.canFind(\"PATCHBODY\"));\n        s.send(httpOK(\"PATCHRESPONSE\"));\n    });\n    auto res = patch(testServer.addr ~ \"/path\", \"PATCHBODY\");\n    assert(res == \"PATCHRESPONSE\");\n}\n\n\n/*\n * Helper function for the high level interface.\n *\n * It performs an HTTP request using the client which must have\n * been setup correctly before calling this function.\n */\nprivate auto _basicHTTP(T)(const(char)[] url, const(void)[] sendData, HTTP client)\n{\n    import std.algorithm.comparison : min;\n    import std.format : format;\n    import std.exception : enforce;\n    import etc.c.curl : CurlSeek, CurlSeekPos;\n\n    immutable doSend = sendData !is null &&\n        (client.method == HTTP.Method.post ||\n         client.method == HTTP.Method.put ||\n         client.method == HTTP.Method.patch);\n\n    scope (exit)\n    {\n        client.onReceiveHeader = null;\n        client.onReceiveStatusLine = null;\n        client.onReceive = null;\n\n        if (doSend)\n        {\n            client.onSend = null;\n            client.handle.onSeek = null;\n            client.contentLength = 0;\n        }\n    }\n    client.url = url;\n    HTTP.StatusLine statusLine;\n    import std.array : appender;\n    auto content = appender!(ubyte[])();\n    client.onReceive = (ubyte[] data)\n    {\n        content ~= data;\n        return data.length;\n    };\n\n    if (doSend)\n    {\n        client.contentLength = sendData.length;\n        auto remainingData = sendData;\n        client.onSend = delegate size_t(void[] buf)\n        {\n            size_t minLen = min(buf.length, remainingData.length);\n            if (minLen == 0) return 0;\n            buf[0 .. minLen] = remainingData[0 .. minLen];\n            remainingData = remainingData[minLen..$];\n            return minLen;\n        };\n        client.handle.onSeek = delegate(long offset, CurlSeekPos mode)\n        {\n            switch (mode)\n            {\n                case CurlSeekPos.set:\n                    remainingData = sendData[cast(size_t) offset..$];\n                    return CurlSeek.ok;\n                default:\n                    // As of curl 7.18.0, libcurl will not pass\n                    // anything other than CurlSeekPos.set.\n                    return CurlSeek.cantseek;\n            }\n        };\n    }\n\n    client.onReceiveHeader = (in char[] key,\n                              in char[] value)\n    {\n        if (key == \"content-length\")\n        {\n            import std.conv : to;\n            content.reserve(value.to!size_t);\n        }\n    };\n    client.onReceiveStatusLine = (HTTP.StatusLine l) { statusLine = l; };\n    client.perform();\n    enforce(statusLine.code / 100 == 2, new HTTPStatusException(statusLine.code,\n            format(\"HTTP request returned status code %d (%s)\", statusLine.code, statusLine.reason)));\n\n    return _decodeContent!T(content.data, client.p.charset);\n}\n\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n    import std.exception : collectException;\n\n    testServer.handle((s) {\n        auto req = s.recvReq;\n        assert(req.hdrs.canFind(\"GET /path\"));\n        s.send(httpNotFound());\n    });\n    auto e = collectException!HTTPStatusException(get(testServer.addr ~ \"/path\"));\n    assert(e.msg == \"HTTP request returned status code 404 (Not Found)\");\n    assert(e.status == 404);\n}\n\n// Bugzilla 14760 - content length must be reset after post\n@system unittest\n{\n    import std.algorithm.searching : canFind;\n\n    testServer.handle((s) {\n        auto req = s.recvReq;\n        assert(req.hdrs.canFind(\"POST /\"));\n        assert(req.bdy.canFind(\"POSTBODY\"));\n        s.send(httpOK(\"POSTRESPONSE\"));\n\n        req = s.recvReq;\n        assert(req.hdrs.canFind(\"TRACE /\"));\n        assert(req.bdy.empty);\n        s.blocking = false;\n        ubyte[6] buf = void;\n        assert(s.receive(buf[]) < 0);\n        s.send(httpOK(\"TRACERESPONSE\"));\n    });\n    auto http = HTTP();\n    auto res = post(testServer.addr, \"POSTBODY\", http);\n    assert(res == \"POSTRESPONSE\");\n    res = trace(testServer.addr, http);\n    assert(res == \"TRACERESPONSE\");\n}\n\n@system unittest // charset detection and transcoding to T\n{\n    testServer.handle((s) {\n        s.send(\"HTTP/1.1 200 OK\\r\\n\"~\n        \"Content-Length: 4\\r\\n\"~\n        \"Content-Type: text/plain; charset=utf-8\\r\\n\" ~\n        \"\\r\\n\" ~\n        \"äbc\");\n    });\n    auto client = HTTP();\n    auto result = _basicHTTP!char(testServer.addr, \"\", client);\n    assert(result == \"äbc\");\n\n    testServer.handle((s) {\n        s.send(\"HTTP/1.1 200 OK\\r\\n\"~\n        \"Content-Length: 3\\r\\n\"~\n        \"Content-Type: text/plain; charset=iso-8859-1\\r\\n\" ~\n        \"\\r\\n\" ~\n        0xE4 ~ \"bc\");\n    });\n    client = HTTP();\n    result = _basicHTTP!char(testServer.addr, \"\", client);\n    assert(result == \"äbc\");\n}\n\n/*\n * Helper function for the high level interface.\n *\n * It performs an FTP request using the client which must have\n * been setup correctly before calling this function.\n */\nprivate auto _basicFTP(T)(const(char)[] url, const(void)[] sendData, FTP client)\n{\n    import std.algorithm.comparison : min;\n\n    scope (exit)\n    {\n        client.onReceive = null;\n        if (!sendData.empty)\n            client.onSend = null;\n    }\n\n    ubyte[] content;\n\n    if (client.encoding.empty)\n        client.encoding = \"ISO-8859-1\";\n\n    client.url = url;\n    client.onReceive = (ubyte[] data)\n    {\n        content ~= data;\n        return data.length;\n    };\n\n    if (!sendData.empty)\n    {\n        client.handle.set(CurlOption.upload, 1L);\n        client.onSend = delegate size_t(void[] buf)\n        {\n            size_t minLen = min(buf.length, sendData.length);\n            if (minLen == 0) return 0;\n            buf[0 .. minLen] = sendData[0 .. minLen];\n            sendData = sendData[minLen..$];\n            return minLen;\n        };\n    }\n\n    client.perform();\n\n    return _decodeContent!T(content, client.encoding);\n}\n\n/* Used by _basicHTTP() and _basicFTP() to decode ubyte[] to\n * correct string format\n */\nprivate auto _decodeContent(T)(ubyte[] content, string encoding)\n{\n    static if (is(T == ubyte))\n    {\n        return content;\n    }\n    else\n    {\n        import std.exception : enforce;\n        import std.format : format;\n\n        // Optimally just return the utf8 encoded content\n        if (encoding == \"UTF-8\")\n            return cast(char[])(content);\n\n        // The content has to be re-encoded to utf8\n        auto scheme = EncodingScheme.create(encoding);\n        enforce!CurlException(scheme !is null,\n                                format(\"Unknown encoding '%s'\", encoding));\n\n        auto strInfo = decodeString(content, scheme);\n        enforce!CurlException(strInfo[0] != size_t.max,\n                                format(\"Invalid encoding sequence for encoding '%s'\",\n                                       encoding));\n\n        return strInfo[1];\n    }\n}\n\nalias KeepTerminator = Flag!\"keepTerminator\";\n/+\nstruct ByLineBuffer(Char)\n{\n    bool linePresent;\n    bool EOF;\n    Char[] buffer;\n    ubyte[] decodeRemainder;\n\n    bool append(const(ubyte)[] data)\n    {\n        byLineBuffer ~= data;\n    }\n\n    @property bool linePresent()\n    {\n        return byLinePresent;\n    }\n\n    Char[] get()\n    {\n        if (!linePresent)\n        {\n            // Decode ubyte[] into Char[] until a Terminator is found.\n            // If not Terminator is found and EOF is false then raise an\n            // exception.\n        }\n        return byLineBuffer;\n    }\n\n}\n++/\n/** HTTP/FTP fetch content as a range of lines.\n *\n * A range of lines is returned when the request is complete. If the method or\n * other request properties is to be customized then set the `conn` parameter\n * with a HTTP/FTP instance that has these properties set.\n *\n * Example:\n * ----\n * import std.net.curl, std.stdio;\n * foreach (line; byLine(\"dlang.org\"))\n *     writeln(line);\n * ----\n *\n * Params:\n * url = The url to receive content from\n * keepTerminator = `Yes.keepTerminator` signals that the line terminator should be\n *                  returned as part of the lines in the range.\n * terminator = The character that terminates a line\n * conn = The connection to use e.g. HTTP or FTP.\n *\n * Returns:\n * A range of Char[] with the content of the resource pointer to by the URL\n */\nauto byLine(Conn = AutoProtocol, Terminator = char, Char = char)\n           (const(char)[] url, KeepTerminator keepTerminator = No.keepTerminator,\n            Terminator terminator = '\\n', Conn conn = Conn())\nif (isCurlConn!Conn && isSomeChar!Char && isSomeChar!Terminator)\n{\n    static struct SyncLineInputRange\n    {\n\n        private Char[] lines;\n        private Char[] current;\n        private bool currentValid;\n        private bool keepTerminator;\n        private Terminator terminator;\n\n        this(Char[] lines, bool kt, Terminator terminator)\n        {\n            this.lines = lines;\n            this.keepTerminator = kt;\n            this.terminator = terminator;\n            currentValid = true;\n            popFront();\n        }\n\n        @property @safe bool empty()\n        {\n            return !currentValid;\n        }\n\n        @property @safe Char[] front()\n        {\n            import std.exception : enforce;\n            enforce!CurlException(currentValid, \"Cannot call front() on empty range\");\n            return current;\n        }\n\n        void popFront()\n        {\n            import std.algorithm.searching : findSplitAfter, findSplit;\n            import std.exception : enforce;\n\n            enforce!CurlException(currentValid, \"Cannot call popFront() on empty range\");\n            if (lines.empty)\n            {\n                currentValid = false;\n                return;\n            }\n\n            if (keepTerminator)\n            {\n                auto r = findSplitAfter(lines, [ terminator ]);\n                if (r[0].empty)\n                {\n                    current = r[1];\n                    lines = r[0];\n                }\n                else\n                {\n                    current = r[0];\n                    lines = r[1];\n                }\n            }\n            else\n            {\n                auto r = findSplit(lines, [ terminator ]);\n                current = r[0];\n                lines = r[2];\n            }\n        }\n    }\n\n    auto result = _getForRange!Char(url, conn);\n    return SyncLineInputRange(result, keepTerminator == Yes.keepTerminator, terminator);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    foreach (host; [testServer.addr, \"http://\"~testServer.addr])\n    {\n        testServer.handle((s) {\n            auto req = s.recvReq;\n            s.send(httpOK(\"Line1\\nLine2\\nLine3\"));\n        });\n        assert(byLine(host).equal([\"Line1\", \"Line2\", \"Line3\"]));\n    }\n}\n\n/** HTTP/FTP fetch content as a range of chunks.\n *\n * A range of chunks is returned when the request is complete. If the method or\n * other request properties is to be customized then set the `conn` parameter\n * with a HTTP/FTP instance that has these properties set.\n *\n * Example:\n * ----\n * import std.net.curl, std.stdio;\n * foreach (chunk; byChunk(\"dlang.org\", 100))\n *     writeln(chunk); // chunk is ubyte[100]\n * ----\n *\n * Params:\n * url = The url to receive content from\n * chunkSize = The size of each chunk\n * conn = The connection to use e.g. HTTP or FTP.\n *\n * Returns:\n * A range of ubyte[chunkSize] with the content of the resource pointer to by the URL\n */\nauto byChunk(Conn = AutoProtocol)\n            (const(char)[] url, size_t chunkSize = 1024, Conn conn = Conn())\nif (isCurlConn!(Conn))\n{\n    static struct SyncChunkInputRange\n    {\n        private size_t chunkSize;\n        private ubyte[] _bytes;\n        private size_t offset;\n\n        this(ubyte[] bytes, size_t chunkSize)\n        {\n            this._bytes = bytes;\n            this.chunkSize = chunkSize;\n        }\n\n        @property @safe auto empty()\n        {\n            return offset == _bytes.length;\n        }\n\n        @property ubyte[] front()\n        {\n            size_t nextOffset = offset + chunkSize;\n            if (nextOffset > _bytes.length) nextOffset = _bytes.length;\n            return _bytes[offset .. nextOffset];\n        }\n\n        @safe void popFront()\n        {\n            offset += chunkSize;\n            if (offset > _bytes.length) offset = _bytes.length;\n        }\n    }\n\n    auto result = _getForRange!ubyte(url, conn);\n    return SyncChunkInputRange(result, chunkSize);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    foreach (host; [testServer.addr, \"http://\"~testServer.addr])\n    {\n        testServer.handle((s) {\n            auto req = s.recvReq;\n            s.send(httpOK(cast(ubyte[])[0, 1, 2, 3, 4, 5]));\n        });\n        assert(byChunk(host, 2).equal([[0, 1], [2, 3], [4, 5]]));\n    }\n}\n\nprivate T[] _getForRange(T,Conn)(const(char)[] url, Conn conn)\n{\n    static if (is(Conn : HTTP))\n    {\n        conn.method = conn.method == HTTP.Method.undefined ? HTTP.Method.get : conn.method;\n        return _basicHTTP!(T)(url, null, conn);\n    }\n    else static if (is(Conn : FTP))\n    {\n        return _basicFTP!(T)(url, null, conn);\n    }\n    else\n    {\n        if (isFTPUrl(url))\n            return get!(FTP,T)(url, FTP());\n        else\n            return get!(HTTP,T)(url, HTTP());\n    }\n}\n\n/*\n  Main thread part of the message passing protocol used for all async\n  curl protocols.\n */\nprivate mixin template WorkerThreadProtocol(Unit, alias units)\n{\n    import core.time : Duration;\n\n    @property bool empty()\n    {\n        tryEnsureUnits();\n        return state == State.done;\n    }\n\n    @property Unit[] front()\n    {\n        import std.format : format;\n        tryEnsureUnits();\n        assert(state == State.gotUnits,\n               format(\"Expected %s but got $s\",\n                      State.gotUnits, state));\n        return units;\n    }\n\n    void popFront()\n    {\n        import std.concurrency : send;\n        import std.format : format;\n\n        tryEnsureUnits();\n        assert(state == State.gotUnits,\n               format(\"Expected %s but got $s\",\n                      State.gotUnits, state));\n        state = State.needUnits;\n        // Send to worker thread for buffer reuse\n        workerTid.send(cast(immutable(Unit)[]) units);\n        units = null;\n    }\n\n    /** Wait for duration or until data is available and return true if data is\n         available\n    */\n    bool wait(Duration d)\n    {\n        import core.time : dur;\n        import std.datetime.stopwatch : StopWatch;\n        import std.concurrency : receiveTimeout;\n\n        if (state == State.gotUnits)\n            return true;\n\n        enum noDur = dur!\"hnsecs\"(0);\n        StopWatch sw;\n        sw.start();\n        while (state != State.gotUnits && d > noDur)\n        {\n            final switch (state)\n            {\n            case State.needUnits:\n                receiveTimeout(d,\n                        (Tid origin, CurlMessage!(immutable(Unit)[]) _data)\n                        {\n                            if (origin != workerTid)\n                                return false;\n                            units = cast(Unit[]) _data.data;\n                            state = State.gotUnits;\n                            return true;\n                        },\n                        (Tid origin, CurlMessage!bool f)\n                        {\n                            if (origin != workerTid)\n                                return false;\n                            state = state.done;\n                            return true;\n                        }\n                        );\n                break;\n            case State.gotUnits: return true;\n            case State.done:\n                return false;\n            }\n            d -= sw.peek();\n            sw.reset();\n        }\n        return state == State.gotUnits;\n    }\n\n    enum State\n    {\n        needUnits,\n        gotUnits,\n        done\n    }\n    State state;\n\n    void tryEnsureUnits()\n    {\n        import std.concurrency : receive;\n        while (true)\n        {\n            final switch (state)\n            {\n            case State.needUnits:\n                receive(\n                        (Tid origin, CurlMessage!(immutable(Unit)[]) _data)\n                        {\n                            if (origin != workerTid)\n                                return false;\n                            units = cast(Unit[]) _data.data;\n                            state = State.gotUnits;\n                            return true;\n                        },\n                        (Tid origin, CurlMessage!bool f)\n                        {\n                            if (origin != workerTid)\n                                return false;\n                            state = state.done;\n                            return true;\n                        }\n                        );\n                break;\n            case State.gotUnits: return;\n            case State.done:\n                return;\n            }\n        }\n    }\n}\n\n/** HTTP/FTP fetch content as a range of lines asynchronously.\n *\n * A range of lines is returned immediately and the request that fetches the\n * lines is performed in another thread. If the method or other request\n * properties is to be customized then set the `conn` parameter with a\n * HTTP/FTP instance that has these properties set.\n *\n * If `postData` is non-_null the method will be set to `post` for HTTP\n * requests.\n *\n * The background thread will buffer up to transmitBuffers number of lines\n * before it stops receiving data from network. When the main thread reads the\n * lines from the range it frees up buffers and allows for the background thread\n * to receive more data from the network.\n *\n * If no data is available and the main thread accesses the range it will block\n * until data becomes available. An exception to this is the `wait(Duration)` method on\n * the $(LREF LineInputRange). This method will wait at maximum for the\n * specified duration and return true if data is available.\n *\n * Example:\n * ----\n * import std.net.curl, std.stdio;\n * // Get some pages in the background\n * auto range1 = byLineAsync(\"www.google.com\");\n * auto range2 = byLineAsync(\"www.wikipedia.org\");\n * foreach (line; byLineAsync(\"dlang.org\"))\n *     writeln(line);\n *\n * // Lines already fetched in the background and ready\n * foreach (line; range1) writeln(line);\n * foreach (line; range2) writeln(line);\n * ----\n *\n * ----\n * import std.net.curl, std.stdio;\n * // Get a line in a background thread and wait in\n * // main thread for 2 seconds for it to arrive.\n * auto range3 = byLineAsync(\"dlang.com\");\n * if (range3.wait(dur!\"seconds\"(2)))\n *     writeln(range3.front);\n * else\n *     writeln(\"No line received after 2 seconds!\");\n * ----\n *\n * Params:\n * url = The url to receive content from\n * postData = Data to HTTP Post\n * keepTerminator = `Yes.keepTerminator` signals that the line terminator should be\n *                  returned as part of the lines in the range.\n * terminator = The character that terminates a line\n * transmitBuffers = The number of lines buffered asynchronously\n * conn = The connection to use e.g. HTTP or FTP.\n *\n * Returns:\n * A range of Char[] with the content of the resource pointer to by the\n * URL.\n */\nauto byLineAsync(Conn = AutoProtocol, Terminator = char, Char = char, PostUnit)\n            (const(char)[] url, const(PostUnit)[] postData,\n             KeepTerminator keepTerminator = No.keepTerminator,\n             Terminator terminator = '\\n',\n             size_t transmitBuffers = 10, Conn conn = Conn())\nif (isCurlConn!Conn && isSomeChar!Char && isSomeChar!Terminator)\n{\n    static if (is(Conn : AutoProtocol))\n    {\n        if (isFTPUrl(url))\n            return byLineAsync(url, postData, keepTerminator,\n                               terminator, transmitBuffers, FTP());\n        else\n            return byLineAsync(url, postData, keepTerminator,\n                               terminator, transmitBuffers, HTTP());\n    }\n    else\n    {\n        import std.concurrency : OnCrowding, send, setMaxMailboxSize, spawn, thisTid, Tid;\n        // 50 is just an arbitrary number for now\n        setMaxMailboxSize(thisTid, 50, OnCrowding.block);\n        auto tid = spawn(&_async!().spawn!(Conn, Char, Terminator));\n        tid.send(thisTid);\n        tid.send(terminator);\n        tid.send(keepTerminator == Yes.keepTerminator);\n\n        _async!().duplicateConnection(url, conn, postData, tid);\n\n        return _async!().LineInputRange!Char(tid, transmitBuffers,\n                                             Conn.defaultAsyncStringBufferSize);\n    }\n}\n\n/// ditto\nauto byLineAsync(Conn = AutoProtocol, Terminator = char, Char = char)\n            (const(char)[] url, KeepTerminator keepTerminator = No.keepTerminator,\n             Terminator terminator = '\\n',\n             size_t transmitBuffers = 10, Conn conn = Conn())\n{\n    static if (is(Conn : AutoProtocol))\n    {\n        if (isFTPUrl(url))\n            return byLineAsync(url, cast(void[]) null, keepTerminator,\n                               terminator, transmitBuffers, FTP());\n        else\n            return byLineAsync(url, cast(void[]) null, keepTerminator,\n                               terminator, transmitBuffers, HTTP());\n    }\n    else\n    {\n        return byLineAsync(url, cast(void[]) null, keepTerminator,\n                           terminator, transmitBuffers, conn);\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    foreach (host; [testServer.addr, \"http://\"~testServer.addr])\n    {\n        testServer.handle((s) {\n            auto req = s.recvReq;\n            s.send(httpOK(\"Line1\\nLine2\\nLine3\"));\n        });\n        assert(byLineAsync(host).equal([\"Line1\", \"Line2\", \"Line3\"]));\n    }\n}\n\n/** HTTP/FTP fetch content as a range of chunks asynchronously.\n *\n * A range of chunks is returned immediately and the request that fetches the\n * chunks is performed in another thread. If the method or other request\n * properties is to be customized then set the `conn` parameter with a\n * HTTP/FTP instance that has these properties set.\n *\n * If `postData` is non-_null the method will be set to `post` for HTTP\n * requests.\n *\n * The background thread will buffer up to transmitBuffers number of chunks\n * before is stops receiving data from network. When the main thread reads the\n * chunks from the range it frees up buffers and allows for the background\n * thread to receive more data from the network.\n *\n * If no data is available and the main thread access the range it will block\n * until data becomes available. An exception to this is the `wait(Duration)`\n * method on the $(LREF ChunkInputRange). This method will wait at maximum for the specified\n * duration and return true if data is available.\n *\n * Example:\n * ----\n * import std.net.curl, std.stdio;\n * // Get some pages in the background\n * auto range1 = byChunkAsync(\"www.google.com\", 100);\n * auto range2 = byChunkAsync(\"www.wikipedia.org\");\n * foreach (chunk; byChunkAsync(\"dlang.org\"))\n *     writeln(chunk); // chunk is ubyte[100]\n *\n * // Chunks already fetched in the background and ready\n * foreach (chunk; range1) writeln(chunk);\n * foreach (chunk; range2) writeln(chunk);\n * ----\n *\n * ----\n * import std.net.curl, std.stdio;\n * // Get a line in a background thread and wait in\n * // main thread for 2 seconds for it to arrive.\n * auto range3 = byChunkAsync(\"dlang.com\", 10);\n * if (range3.wait(dur!\"seconds\"(2)))\n *     writeln(range3.front);\n * else\n *     writeln(\"No chunk received after 2 seconds!\");\n * ----\n *\n * Params:\n * url = The url to receive content from\n * postData = Data to HTTP Post\n * chunkSize = The size of the chunks\n * transmitBuffers = The number of chunks buffered asynchronously\n * conn = The connection to use e.g. HTTP or FTP.\n *\n * Returns:\n * A range of ubyte[chunkSize] with the content of the resource pointer to by\n * the URL.\n */\nauto byChunkAsync(Conn = AutoProtocol, PostUnit)\n           (const(char)[] url, const(PostUnit)[] postData,\n            size_t chunkSize = 1024, size_t transmitBuffers = 10,\n            Conn conn = Conn())\nif (isCurlConn!(Conn))\n{\n    static if (is(Conn : AutoProtocol))\n    {\n        if (isFTPUrl(url))\n            return byChunkAsync(url, postData, chunkSize,\n                                transmitBuffers, FTP());\n        else\n            return byChunkAsync(url, postData, chunkSize,\n                                transmitBuffers, HTTP());\n    }\n    else\n    {\n        import std.concurrency : OnCrowding, send, setMaxMailboxSize, spawn, thisTid, Tid;\n        // 50 is just an arbitrary number for now\n        setMaxMailboxSize(thisTid, 50, OnCrowding.block);\n        auto tid = spawn(&_async!().spawn!(Conn, ubyte));\n        tid.send(thisTid);\n\n        _async!().duplicateConnection(url, conn, postData, tid);\n\n        return _async!().ChunkInputRange(tid, transmitBuffers, chunkSize);\n    }\n}\n\n/// ditto\nauto byChunkAsync(Conn = AutoProtocol)\n           (const(char)[] url,\n            size_t chunkSize = 1024, size_t transmitBuffers = 10,\n            Conn conn = Conn())\nif (isCurlConn!(Conn))\n{\n    static if (is(Conn : AutoProtocol))\n    {\n        if (isFTPUrl(url))\n            return byChunkAsync(url, cast(void[]) null, chunkSize,\n                                transmitBuffers, FTP());\n        else\n            return byChunkAsync(url, cast(void[]) null, chunkSize,\n                                transmitBuffers, HTTP());\n    }\n    else\n    {\n        return byChunkAsync(url, cast(void[]) null, chunkSize,\n                            transmitBuffers, conn);\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    foreach (host; [testServer.addr, \"http://\"~testServer.addr])\n    {\n        testServer.handle((s) {\n            auto req = s.recvReq;\n            s.send(httpOK(cast(ubyte[])[0, 1, 2, 3, 4, 5]));\n        });\n        assert(byChunkAsync(host, 2).equal([[0, 1], [2, 3], [4, 5]]));\n    }\n}\n\n\n/*\n  Mixin template for all supported curl protocols. This is the commom\n  functionallity such as timeouts and network interface settings. This should\n  really be in the HTTP/FTP/SMTP structs but the documentation tool does not\n  support a mixin to put its doc strings where a mixin is done. Therefore docs\n  in this template is copied into each of HTTP/FTP/SMTP below.\n*/\nprivate mixin template Protocol()\n{\n    import etc.c.curl : CurlReadFunc, RawCurlProxy = CurlProxy;\n    import core.time : Duration;\n    import std.socket : InternetAddress;\n\n    /// Value to return from `onSend`/`onReceive` delegates in order to\n    /// pause a request\n    alias requestPause = CurlReadFunc.pause;\n\n    /// Value to return from onSend delegate in order to abort a request\n    alias requestAbort = CurlReadFunc.abort;\n\n    static uint defaultAsyncStringBufferSize = 100;\n\n    /**\n       The curl handle used by this connection.\n    */\n    @property ref Curl handle() return\n    {\n        return p.curl;\n    }\n\n    /**\n       True if the instance is stopped. A stopped instance is not usable.\n    */\n    @property bool isStopped()\n    {\n        return p.curl.stopped;\n    }\n\n    /// Stop and invalidate this instance.\n    void shutdown()\n    {\n        p.curl.shutdown();\n    }\n\n    /** Set verbose.\n        This will print request information to stderr.\n     */\n    @property void verbose(bool on)\n    {\n        p.curl.set(CurlOption.verbose, on ? 1L : 0L);\n    }\n\n    // Connection settings\n\n    /// Set timeout for activity on connection.\n    @property void dataTimeout(Duration d)\n    {\n        p.curl.set(CurlOption.low_speed_limit, 1);\n        p.curl.set(CurlOption.low_speed_time, d.total!\"seconds\");\n    }\n\n    /** Set maximum time an operation is allowed to take.\n        This includes dns resolution, connecting, data transfer, etc.\n     */\n    @property void operationTimeout(Duration d)\n    {\n        p.curl.set(CurlOption.timeout_ms, d.total!\"msecs\");\n    }\n\n    /// Set timeout for connecting.\n    @property void connectTimeout(Duration d)\n    {\n        p.curl.set(CurlOption.connecttimeout_ms, d.total!\"msecs\");\n    }\n\n    // Network settings\n\n    /** Proxy\n     *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXY, _proxy)\n     */\n    @property void proxy(const(char)[] host)\n    {\n        p.curl.set(CurlOption.proxy, host);\n    }\n\n    /** Proxy port\n     *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXYPORT, _proxy_port)\n     */\n    @property void proxyPort(ushort port)\n    {\n        p.curl.set(CurlOption.proxyport, cast(long) port);\n    }\n\n    /// Type of proxy\n    alias CurlProxy = RawCurlProxy;\n\n    /** Proxy type\n     *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXY, _proxy_type)\n     */\n    @property void proxyType(CurlProxy type)\n    {\n        p.curl.set(CurlOption.proxytype, cast(long) type);\n    }\n\n    /// DNS lookup timeout.\n    @property void dnsTimeout(Duration d)\n    {\n        p.curl.set(CurlOption.dns_cache_timeout, d.total!\"msecs\");\n    }\n\n    /**\n     * The network interface to use in form of the the IP of the interface.\n     *\n     * Example:\n     * ----\n     * theprotocol.netInterface = \"192.168.1.32\";\n     * theprotocol.netInterface = [ 192, 168, 1, 32 ];\n     * ----\n     *\n     * See: $(REF InternetAddress, std,socket)\n     */\n    @property void netInterface(const(char)[] i)\n    {\n        p.curl.set(CurlOption.intrface, i);\n    }\n\n    /// ditto\n    @property void netInterface(const(ubyte)[4] i)\n    {\n        import std.format : format;\n        const str = format(\"%d.%d.%d.%d\", i[0], i[1], i[2], i[3]);\n        netInterface = str;\n    }\n\n    /// ditto\n    @property void netInterface(InternetAddress i)\n    {\n        netInterface = i.toAddrString();\n    }\n\n    /**\n       Set the local outgoing port to use.\n       Params:\n       port = the first outgoing port number to try and use\n    */\n    @property void localPort(ushort port)\n    {\n        p.curl.set(CurlOption.localport, cast(long) port);\n    }\n\n    /**\n       Set the no proxy flag for the specified host names.\n       Params:\n       test = a list of comma host names that do not require\n              proxy to get reached\n    */\n    void setNoProxy(string hosts)\n    {\n        p.curl.set(CurlOption.noproxy, hosts);\n    }\n\n    /**\n       Set the local outgoing port range to use.\n       This can be used together with the localPort property.\n       Params:\n       range = if the first port is occupied then try this many\n               port number forwards\n    */\n    @property void localPortRange(ushort range)\n    {\n        p.curl.set(CurlOption.localportrange, cast(long) range);\n    }\n\n    /** Set the tcp no-delay socket option on or off.\n        See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTTCPNODELAY, nodelay)\n    */\n    @property void tcpNoDelay(bool on)\n    {\n        p.curl.set(CurlOption.tcp_nodelay, cast(long) (on ? 1 : 0) );\n    }\n\n    /** Sets whether SSL peer certificates should be verified.\n        See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTSSLVERIFYPEER, verifypeer)\n    */\n    @property void verifyPeer(bool on)\n    {\n      p.curl.set(CurlOption.ssl_verifypeer, on ? 1 : 0);\n    }\n\n    /** Sets whether the host within an SSL certificate should be verified.\n        See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTSSLVERIFYHOST, verifypeer)\n    */\n    @property void verifyHost(bool on)\n    {\n      p.curl.set(CurlOption.ssl_verifyhost, on ? 2 : 0);\n    }\n\n    // Authentication settings\n\n    /**\n       Set the user name, password and optionally domain for authentication\n       purposes.\n\n       Some protocols may need authentication in some cases. Use this\n       function to provide credentials.\n\n       Params:\n       username = the username\n       password = the password\n       domain = used for NTLM authentication only and is set to the NTLM domain\n                name\n    */\n    void setAuthentication(const(char)[] username, const(char)[] password,\n                           const(char)[] domain = \"\")\n    {\n        import std.format : format;\n        if (!domain.empty)\n            username = format(\"%s/%s\", domain, username);\n        p.curl.set(CurlOption.userpwd, format(\"%s:%s\", username, password));\n    }\n\n    @system unittest\n    {\n        import std.algorithm.searching : canFind;\n\n        testServer.handle((s) {\n            auto req = s.recvReq;\n            assert(req.hdrs.canFind(\"GET /\"));\n            assert(req.hdrs.canFind(\"Basic dXNlcjpwYXNz\"));\n            s.send(httpOK());\n        });\n\n        auto http = HTTP(testServer.addr);\n        http.onReceive = (ubyte[] data) { return data.length; };\n        http.setAuthentication(\"user\", \"pass\");\n        http.perform();\n\n        // Bugzilla 17540\n        http.setNoProxy(\"www.example.com\");\n    }\n\n    /**\n       Set the user name and password for proxy authentication.\n\n       Params:\n       username = the username\n       password = the password\n    */\n    void setProxyAuthentication(const(char)[] username, const(char)[] password)\n    {\n        import std.array : replace;\n        import std.format : format;\n\n        p.curl.set(CurlOption.proxyuserpwd,\n            format(\"%s:%s\",\n                username.replace(\":\", \"%3A\"),\n                password.replace(\":\", \"%3A\"))\n        );\n    }\n\n    /**\n     * The event handler that gets called when data is needed for sending. The\n     * length of the `void[]` specifies the maximum number of bytes that can\n     * be sent.\n     *\n     * Returns:\n     * The callback returns the number of elements in the buffer that have been\n     * filled and are ready to send.\n     * The special value `.abortRequest` can be returned in order to abort the\n     * current request.\n     * The special value `.pauseRequest` can be returned in order to pause the\n     * current request.\n     *\n     * Example:\n     * ----\n     * import std.net.curl;\n     * string msg = \"Hello world\";\n     * auto client = HTTP(\"dlang.org\");\n     * client.onSend = delegate size_t(void[] data)\n     * {\n     *     auto m = cast(void[]) msg;\n     *     size_t length = m.length > data.length ? data.length : m.length;\n     *     if (length == 0) return 0;\n     *     data[0 .. length] = m[0 .. length];\n     *     msg = msg[length..$];\n     *     return length;\n     * };\n     * client.perform();\n     * ----\n     */\n    @property void onSend(size_t delegate(void[]) callback)\n    {\n        p.curl.clear(CurlOption.postfields); // cannot specify data when using callback\n        p.curl.onSend = callback;\n    }\n\n    /**\n      * The event handler that receives incoming data. Be sure to copy the\n      * incoming ubyte[] since it is not guaranteed to be valid after the\n      * callback returns.\n      *\n      * Returns:\n      * The callback returns the number of incoming bytes read. If the entire array is\n      * not read the request will abort.\n      * The special value .pauseRequest can be returned in order to pause the\n      * current request.\n      *\n      * Example:\n      * ----\n      * import std.net.curl, std.stdio;\n      * auto client = HTTP(\"dlang.org\");\n      * client.onReceive = (ubyte[] data)\n      * {\n      *     writeln(\"Got data\", to!(const(char)[])(data));\n      *     return data.length;\n      * };\n      * client.perform();\n      * ----\n      */\n    @property void onReceive(size_t delegate(ubyte[]) callback)\n    {\n        p.curl.onReceive = callback;\n    }\n\n    /**\n      * The event handler that gets called to inform of upload/download progress.\n      *\n      * Params:\n      * dlTotal = total bytes to download\n      * dlNow = currently downloaded bytes\n      * ulTotal = total bytes to upload\n      * ulNow = currently uploaded bytes\n      *\n      * Returns:\n      * Return 0 from the callback to signal success, return non-zero to abort\n      *          transfer\n      *\n      * Example:\n      * ----\n      * import std.net.curl, std.stdio;\n      * auto client = HTTP(\"dlang.org\");\n      * client.onProgress = delegate int(size_t dl, size_t dln, size_t ul, size_t ult)\n      * {\n      *     writeln(\"Progress: downloaded \", dln, \" of \", dl);\n      *     writeln(\"Progress: uploaded \", uln, \" of \", ul);\n      * };\n      * client.perform();\n      * ----\n      */\n    @property void onProgress(int delegate(size_t dlTotal, size_t dlNow,\n                                           size_t ulTotal, size_t ulNow) callback)\n    {\n        p.curl.onProgress = callback;\n    }\n}\n\n/*\n  Decode `ubyte[]` array using the provided EncodingScheme up to maxChars\n  Returns: Tuple of ubytes read and the `Char[]` characters decoded.\n           Not all ubytes are guaranteed to be read in case of decoding error.\n*/\nprivate Tuple!(size_t,Char[])\ndecodeString(Char = char)(const(ubyte)[] data,\n                          EncodingScheme scheme,\n                          size_t maxChars = size_t.max)\n{\n    import std.encoding : INVALID_SEQUENCE;\n    Char[] res;\n    immutable startLen = data.length;\n    size_t charsDecoded = 0;\n    while (data.length && charsDecoded < maxChars)\n    {\n        immutable dchar dc = scheme.safeDecode(data);\n        if (dc == INVALID_SEQUENCE)\n        {\n            return typeof(return)(size_t.max, cast(Char[]) null);\n        }\n        charsDecoded++;\n        res ~= dc;\n    }\n    return typeof(return)(startLen-data.length, res);\n}\n\n/*\n  Decode `ubyte[]` array using the provided `EncodingScheme` until a the\n  line terminator specified is found. The basesrc parameter is effectively\n  prepended to src as the first thing.\n\n  This function is used for decoding as much of the src buffer as\n  possible until either the terminator is found or decoding fails. If\n  it fails as the last data in the src it may mean that the src buffer\n  were missing some bytes in order to represent a correct code\n  point. Upon the next call to this function more bytes have been\n  received from net and the failing bytes should be given as the\n  basesrc parameter. It is done this way to minimize data copying.\n\n  Returns: true if a terminator was found\n           Not all ubytes are guaranteed to be read in case of decoding error.\n           any decoded chars will be inserted into dst.\n*/\nprivate bool decodeLineInto(Terminator, Char = char)(ref const(ubyte)[] basesrc,\n                                                     ref const(ubyte)[] src,\n                                                     ref Char[] dst,\n                                                     EncodingScheme scheme,\n                                                     Terminator terminator)\n{\n    import std.algorithm.searching : endsWith;\n    import std.encoding : INVALID_SEQUENCE;\n    import std.exception : enforce;\n\n    // if there is anything in the basesrc then try to decode that\n    // first.\n    if (basesrc.length != 0)\n    {\n        // Try to ensure 4 entries in the basesrc by copying from src.\n        immutable blen = basesrc.length;\n        immutable len = (basesrc.length + src.length) >= 4 ?\n                     4 : basesrc.length + src.length;\n        basesrc.length = len;\n\n        immutable dchar dc = scheme.safeDecode(basesrc);\n        if (dc == INVALID_SEQUENCE)\n        {\n            enforce!CurlException(len != 4, \"Invalid code sequence\");\n            return false;\n        }\n        dst ~= dc;\n        src = src[len-basesrc.length-blen .. $]; // remove used ubytes from src\n        basesrc.length = 0;\n    }\n\n    while (src.length)\n    {\n        const lsrc = src;\n        dchar dc = scheme.safeDecode(src);\n        if (dc == INVALID_SEQUENCE)\n        {\n            if (src.empty)\n            {\n                // The invalid sequence was in the end of the src.  Maybe there\n                // just need to be more bytes available so these last bytes are\n                // put back to src for later use.\n                src = lsrc;\n                return false;\n            }\n            dc = '?';\n        }\n        dst ~= dc;\n\n        if (dst.endsWith(terminator))\n            return true;\n    }\n    return false; // no terminator found\n}\n\n/**\n  * HTTP client functionality.\n  *\n  * Example:\n  * ---\n  * import std.net.curl, std.stdio;\n  *\n  * // Get with custom data receivers\n  * auto http = HTTP(\"dlang.org\");\n  * http.onReceiveHeader =\n  *     (in char[] key, in char[] value) { writeln(key ~ \": \" ~ value); };\n  * http.onReceive = (ubyte[] data) { /+ drop +/ return data.length; };\n  * http.perform();\n  *\n  * // Put with data senders\n  * auto msg = \"Hello world\";\n  * http.contentLength = msg.length;\n  * http.onSend = (void[] data)\n  * {\n  *     auto m = cast(void[]) msg;\n  *     size_t len = m.length > data.length ? data.length : m.length;\n  *     if (len == 0) return len;\n  *     data[0 .. len] = m[0 .. len];\n  *     msg = msg[len..$];\n  *     return len;\n  * };\n  * http.perform();\n  *\n  * // Track progress\n  * http.method = HTTP.Method.get;\n  * http.url = \"http://upload.wikimedia.org/wikipedia/commons/\"\n  *            \"5/53/Wikipedia-logo-en-big.png\";\n  * http.onReceive = (ubyte[] data) { return data.length; };\n  * http.onProgress = (size_t dltotal, size_t dlnow,\n  *                    size_t ultotal, size_t ulnow)\n  * {\n  *     writeln(\"Progress \", dltotal, \", \", dlnow, \", \", ultotal, \", \", ulnow);\n  *     return 0;\n  * };\n  * http.perform();\n  * ---\n  *\n  * See_Also: $(LINK2 http://www.ietf.org/rfc/rfc2616.txt, RFC2616)\n  *\n  */\nstruct HTTP\n{\n    mixin Protocol;\n\n    import std.datetime.systime : SysTime;\n    import std.typecons : RefCounted;\n    import etc.c.curl : CurlAuth, CurlInfo, curl_slist, CURLVERSION_NOW, curl_off_t;\n\n    /// Authentication method equal to $(REF CurlAuth, etc,c,curl)\n    alias AuthMethod = CurlAuth;\n\n    static private uint defaultMaxRedirects = 10;\n\n    private struct Impl\n    {\n        ~this()\n        {\n            if (headersOut !is null)\n                Curl.curl.slist_free_all(headersOut);\n            if (curl.handle !is null) // work around RefCounted/emplace bug\n                curl.shutdown();\n        }\n        Curl curl;\n        curl_slist* headersOut;\n        string[string] headersIn;\n        string charset;\n\n        /// The status line of the final sub-request in a request.\n        StatusLine status;\n        private void delegate(StatusLine) onReceiveStatusLine;\n\n        /// The HTTP method to use.\n        Method method = Method.undefined;\n\n        @system @property void onReceiveHeader(void delegate(in char[] key,\n                                                     in char[] value) callback)\n        {\n            import std.algorithm.searching : startsWith;\n            import std.conv : to;\n            import std.regex : regex, match;\n            import std.uni : toLower;\n\n            // Wrap incoming callback in order to separate http status line from\n            // http headers.  On redirected requests there may be several such\n            // status lines. The last one is the one recorded.\n            auto dg = (in char[] header)\n            {\n                import std.utf : UTFException;\n                try\n                {\n                    if (header.empty)\n                    {\n                        // header delimiter\n                        return;\n                    }\n                    if (header.startsWith(\"HTTP/\"))\n                    {\n                        headersIn.clear();\n\n                        const m = match(header, regex(r\"^HTTP/(\\d+)\\.(\\d+) (\\d+) (.*)$\"));\n                        if (m.empty)\n                        {\n                            // Invalid status line\n                        }\n                        else\n                        {\n                            status.majorVersion = to!ushort(m.captures[1]);\n                            status.minorVersion = to!ushort(m.captures[2]);\n                            status.code = to!ushort(m.captures[3]);\n                            status.reason = m.captures[4].idup;\n                            if (onReceiveStatusLine != null)\n                                onReceiveStatusLine(status);\n                        }\n                        return;\n                    }\n\n                    // Normal http header\n                    auto m = match(cast(char[]) header, regex(\"(.*?): (.*)$\"));\n\n                    auto fieldName = m.captures[1].toLower().idup;\n                    if (fieldName == \"content-type\")\n                    {\n                        auto mct = match(cast(char[]) m.captures[2],\n                                         regex(\"charset=([^;]*)\", \"i\"));\n                        if (!mct.empty && mct.captures.length > 1)\n                            charset = mct.captures[1].idup;\n                    }\n\n                    if (!m.empty && callback !is null)\n                        callback(fieldName, m.captures[2]);\n                    headersIn[fieldName] = m.captures[2].idup;\n                }\n                catch (UTFException e)\n                {\n                    //munch it - a header should be all ASCII, any \"wrong UTF\" is broken header\n                }\n            };\n\n            curl.onReceiveHeader = dg;\n        }\n    }\n\n    private RefCounted!Impl p;\n    import etc.c.curl : CurlTimeCond;\n\n    /** Time condition enumeration as an alias of $(REF CurlTimeCond, etc,c,curl)\n\n        $(HTTP www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25, _RFC2616 Section 14.25)\n    */\n    alias TimeCond = CurlTimeCond;\n\n    /**\n       Constructor taking the url as parameter.\n    */\n    static HTTP opCall(const(char)[] url)\n    {\n        HTTP http;\n        http.initialize();\n        http.url = url;\n        return http;\n    }\n\n    ///\n    static HTTP opCall()\n    {\n        HTTP http;\n        http.initialize();\n        return http;\n    }\n\n    ///\n    HTTP dup()\n    {\n        HTTP copy;\n        copy.initialize();\n        copy.p.method = p.method;\n        curl_slist* cur = p.headersOut;\n        curl_slist* newlist = null;\n        while (cur)\n        {\n            newlist = Curl.curl.slist_append(newlist, cur.data);\n            cur = cur.next;\n        }\n        copy.p.headersOut = newlist;\n        copy.p.curl.set(CurlOption.httpheader, copy.p.headersOut);\n        copy.p.curl = p.curl.dup();\n        copy.dataTimeout = _defaultDataTimeout;\n        copy.onReceiveHeader = null;\n        return copy;\n    }\n\n    private void initialize()\n    {\n        p.curl.initialize();\n        maxRedirects = HTTP.defaultMaxRedirects;\n        p.charset = \"ISO-8859-1\"; // Default charset defined in HTTP RFC\n        p.method = Method.undefined;\n        setUserAgent(HTTP.defaultUserAgent);\n        dataTimeout = _defaultDataTimeout;\n        onReceiveHeader = null;\n        verifyPeer = true;\n        verifyHost = true;\n    }\n\n    /**\n       Perform a http request.\n\n       After the HTTP client has been setup and possibly assigned callbacks the\n       `perform()` method will start performing the request towards the\n       specified server.\n\n       Params:\n       throwOnError = whether to throw an exception or return a CurlCode on error\n    */\n    CurlCode perform(ThrowOnError throwOnError = Yes.throwOnError)\n    {\n        p.status.reset();\n\n        CurlOption opt;\n        final switch (p.method)\n        {\n        case Method.head:\n            p.curl.set(CurlOption.nobody, 1L);\n            opt = CurlOption.nobody;\n            break;\n        case Method.undefined:\n        case Method.get:\n            p.curl.set(CurlOption.httpget, 1L);\n            opt = CurlOption.httpget;\n            break;\n        case Method.post:\n            p.curl.set(CurlOption.post, 1L);\n            opt = CurlOption.post;\n            break;\n        case Method.put:\n            p.curl.set(CurlOption.upload, 1L);\n            opt = CurlOption.upload;\n            break;\n        case Method.del:\n            p.curl.set(CurlOption.customrequest, \"DELETE\");\n            opt = CurlOption.customrequest;\n            break;\n        case Method.options:\n            p.curl.set(CurlOption.customrequest, \"OPTIONS\");\n            opt = CurlOption.customrequest;\n            break;\n        case Method.trace:\n            p.curl.set(CurlOption.customrequest, \"TRACE\");\n            opt = CurlOption.customrequest;\n            break;\n        case Method.connect:\n            p.curl.set(CurlOption.customrequest, \"CONNECT\");\n            opt = CurlOption.customrequest;\n            break;\n        case Method.patch:\n            p.curl.set(CurlOption.customrequest, \"PATCH\");\n            opt = CurlOption.customrequest;\n            break;\n        }\n\n        scope (exit) p.curl.clear(opt);\n        return p.curl.perform(throwOnError);\n    }\n\n    /// The URL to specify the location of the resource.\n    @property void url(const(char)[] url)\n    {\n        import std.algorithm.searching : startsWith;\n        import std.uni : toLower;\n        if (!startsWith(url.toLower(), \"http://\", \"https://\"))\n            url = \"http://\" ~ url;\n        p.curl.set(CurlOption.url, url);\n    }\n\n    /// Set the CA certificate bundle file to use for SSL peer verification\n    @property void caInfo(const(char)[] caFile)\n    {\n        p.curl.set(CurlOption.cainfo, caFile);\n    }\n\n    // This is a workaround for mixed in content not having its\n    // docs mixed in.\n    version (StdDdoc)\n    {\n        static import etc.c.curl;\n\n        /// Value to return from `onSend`/`onReceive` delegates in order to\n        /// pause a request\n        alias requestPause = CurlReadFunc.pause;\n\n        /// Value to return from onSend delegate in order to abort a request\n        alias requestAbort = CurlReadFunc.abort;\n\n        /**\n           True if the instance is stopped. A stopped instance is not usable.\n        */\n        @property bool isStopped();\n\n        /// Stop and invalidate this instance.\n        void shutdown();\n\n        /** Set verbose.\n            This will print request information to stderr.\n        */\n        @property void verbose(bool on);\n\n        // Connection settings\n\n        /// Set timeout for activity on connection.\n        @property void dataTimeout(Duration d);\n\n        /** Set maximum time an operation is allowed to take.\n            This includes dns resolution, connecting, data transfer, etc.\n          */\n        @property void operationTimeout(Duration d);\n\n        /// Set timeout for connecting.\n        @property void connectTimeout(Duration d);\n\n        // Network settings\n\n        /** Proxy\n         *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXY, _proxy)\n         */\n        @property void proxy(const(char)[] host);\n\n        /** Proxy port\n         *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXYPORT, _proxy_port)\n         */\n        @property void proxyPort(ushort port);\n\n        /// Type of proxy\n        alias CurlProxy = etc.c.curl.CurlProxy;\n\n        /** Proxy type\n         *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXY, _proxy_type)\n         */\n        @property void proxyType(CurlProxy type);\n\n        /// DNS lookup timeout.\n        @property void dnsTimeout(Duration d);\n\n        /**\n         * The network interface to use in form of the the IP of the interface.\n         *\n         * Example:\n         * ----\n         * theprotocol.netInterface = \"192.168.1.32\";\n         * theprotocol.netInterface = [ 192, 168, 1, 32 ];\n         * ----\n         *\n         * See: $(REF InternetAddress, std,socket)\n         */\n        @property void netInterface(const(char)[] i);\n\n        /// ditto\n        @property void netInterface(const(ubyte)[4] i);\n\n        /// ditto\n        @property void netInterface(InternetAddress i);\n\n        /**\n           Set the local outgoing port to use.\n           Params:\n           port = the first outgoing port number to try and use\n        */\n        @property void localPort(ushort port);\n\n        /**\n           Set the local outgoing port range to use.\n           This can be used together with the localPort property.\n           Params:\n           range = if the first port is occupied then try this many\n           port number forwards\n        */\n        @property void localPortRange(ushort range);\n\n        /** Set the tcp no-delay socket option on or off.\n            See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTTCPNODELAY, nodelay)\n        */\n        @property void tcpNoDelay(bool on);\n\n        // Authentication settings\n\n        /**\n           Set the user name, password and optionally domain for authentication\n           purposes.\n\n           Some protocols may need authentication in some cases. Use this\n           function to provide credentials.\n\n           Params:\n           username = the username\n           password = the password\n           domain = used for NTLM authentication only and is set to the NTLM domain\n           name\n        */\n        void setAuthentication(const(char)[] username, const(char)[] password,\n                               const(char)[] domain = \"\");\n\n        /**\n           Set the user name and password for proxy authentication.\n\n           Params:\n           username = the username\n           password = the password\n        */\n        void setProxyAuthentication(const(char)[] username, const(char)[] password);\n\n        /**\n         * The event handler that gets called when data is needed for sending. The\n         * length of the `void[]` specifies the maximum number of bytes that can\n         * be sent.\n         *\n         * Returns:\n         * The callback returns the number of elements in the buffer that have been\n         * filled and are ready to send.\n         * The special value `.abortRequest` can be returned in order to abort the\n         * current request.\n         * The special value `.pauseRequest` can be returned in order to pause the\n         * current request.\n         *\n         * Example:\n         * ----\n         * import std.net.curl;\n         * string msg = \"Hello world\";\n         * auto client = HTTP(\"dlang.org\");\n         * client.onSend = delegate size_t(void[] data)\n         * {\n         *     auto m = cast(void[]) msg;\n         *     size_t length = m.length > data.length ? data.length : m.length;\n         *     if (length == 0) return 0;\n         *     data[0 .. length] = m[0 .. length];\n         *     msg = msg[length..$];\n         *     return length;\n         * };\n         * client.perform();\n         * ----\n         */\n        @property void onSend(size_t delegate(void[]) callback);\n\n        /**\n         * The event handler that receives incoming data. Be sure to copy the\n         * incoming ubyte[] since it is not guaranteed to be valid after the\n         * callback returns.\n         *\n         * Returns:\n         * The callback returns the incoming bytes read. If not the entire array is\n         * the request will abort.\n         * The special value .pauseRequest can be returned in order to pause the\n         * current request.\n         *\n         * Example:\n         * ----\n         * import std.net.curl, std.stdio;\n         * auto client = HTTP(\"dlang.org\");\n         * client.onReceive = (ubyte[] data)\n         * {\n         *     writeln(\"Got data\", to!(const(char)[])(data));\n         *     return data.length;\n         * };\n         * client.perform();\n         * ----\n         */\n        @property void onReceive(size_t delegate(ubyte[]) callback);\n\n        /**\n         * Register an event handler that gets called to inform of\n         * upload/download progress.\n         *\n         * Callback_parameters:\n         * $(CALLBACK_PARAMS)\n         *\n         * Callback_returns: Return 0 to signal success, return non-zero to\n         * abort transfer.\n         *\n         * Example:\n         * ----\n         * import std.net.curl, std.stdio;\n         * auto client = HTTP(\"dlang.org\");\n         * client.onProgress = delegate int(size_t dl, size_t dln, size_t ul, size_t ult)\n         * {\n         *     writeln(\"Progress: downloaded \", dln, \" of \", dl);\n         *     writeln(\"Progress: uploaded \", uln, \" of \", ul);\n         * };\n         * client.perform();\n         * ----\n         */\n        @property void onProgress(int delegate(size_t dlTotal, size_t dlNow,\n                                               size_t ulTotal, size_t ulNow) callback);\n    }\n\n    /** Clear all outgoing headers.\n    */\n    void clearRequestHeaders()\n    {\n        if (p.headersOut !is null)\n            Curl.curl.slist_free_all(p.headersOut);\n        p.headersOut = null;\n        p.curl.clear(CurlOption.httpheader);\n    }\n\n    /** Add a header e.g. \"X-CustomField: Something is fishy\".\n     *\n     * There is no remove header functionality. Do a $(LREF clearRequestHeaders)\n     * and set the needed headers instead.\n     *\n     * Example:\n     * ---\n     * import std.net.curl;\n     * auto client = HTTP();\n     * client.addRequestHeader(\"X-Custom-ABC\", \"This is the custom value\");\n     * auto content = get(\"dlang.org\", client);\n     * ---\n     */\n    void addRequestHeader(const(char)[] name, const(char)[] value)\n    {\n        import std.format : format;\n        import std.internal.cstring : tempCString;\n        import std.uni : icmp;\n\n        if (icmp(name, \"User-Agent\") == 0)\n            return setUserAgent(value);\n        string nv = format(\"%s: %s\", name, value);\n        p.headersOut = Curl.curl.slist_append(p.headersOut,\n                                              nv.tempCString().buffPtr);\n        p.curl.set(CurlOption.httpheader, p.headersOut);\n    }\n\n    /**\n     * The default \"User-Agent\" value send with a request.\n     * It has the form \"Phobos-std.net.curl/$(I PHOBOS_VERSION) (libcurl/$(I CURL_VERSION))\"\n     */\n    static string defaultUserAgent() @property\n    {\n        import std.compiler : version_major, version_minor;\n        import std.format : format, sformat;\n\n        // http://curl.haxx.se/docs/versions.html\n        enum fmt = \"Phobos-std.net.curl/%d.%03d (libcurl/%d.%d.%d)\";\n        enum maxLen = fmt.length - \"%d%03d%d%d%d\".length + 10 + 10 + 3 + 3 + 3;\n\n        static char[maxLen] buf = void;\n        static string userAgent;\n\n        if (!userAgent.length)\n        {\n            auto curlVer = Curl.curl.version_info(CURLVERSION_NOW).version_num;\n            userAgent = cast(immutable) sformat(\n                buf, fmt, version_major, version_minor,\n                curlVer >> 16 & 0xFF, curlVer >> 8 & 0xFF, curlVer & 0xFF);\n        }\n        return userAgent;\n    }\n\n    /** Set the value of the user agent request header field.\n     *\n     * By default a request has it's \"User-Agent\" field set to $(LREF\n     * defaultUserAgent) even if `setUserAgent` was never called.  Pass\n     * an empty string to suppress the \"User-Agent\" field altogether.\n     */\n    void setUserAgent(const(char)[] userAgent)\n    {\n        p.curl.set(CurlOption.useragent, userAgent);\n    }\n\n    /**\n     * Get various timings defined in $(REF CurlInfo, etc, c, curl).\n     * The value is usable only if the return value is equal to `etc.c.curl.CurlError.ok`.\n     *\n     * Params:\n     *      timing = one of the timings defined in $(REF CurlInfo, etc, c, curl).\n     *               The values are:\n     *               `etc.c.curl.CurlInfo.namelookup_time`,\n     *               `etc.c.curl.CurlInfo.connect_time`,\n     *               `etc.c.curl.CurlInfo.pretransfer_time`,\n     *               `etc.c.curl.CurlInfo.starttransfer_time`,\n     *               `etc.c.curl.CurlInfo.redirect_time`,\n     *               `etc.c.curl.CurlInfo.appconnect_time`,\n     *               `etc.c.curl.CurlInfo.total_time`.\n     *      val    = the actual value of the inquired timing.\n     *\n     * Returns:\n     *      The return code of the operation. The value stored in val\n     *      should be used only if the return value is `etc.c.curl.CurlInfo.ok`.\n     *\n     * Example:\n     * ---\n     * import std.net.curl;\n     * import etc.c.curl : CurlError, CurlInfo;\n     *\n     * auto client = HTTP(\"dlang.org\");\n     * client.perform();\n     *\n     * double val;\n     * CurlCode code;\n     *\n     * code = client.getTiming(CurlInfo.namelookup_time, val);\n     * assert(code == CurlError.ok);\n     * ---\n     */\n    CurlCode getTiming(CurlInfo timing, ref double val)\n    {\n        return p.curl.getTiming(timing, val);\n    }\n\n    /** The headers read from a successful response.\n     *\n     */\n    @property string[string] responseHeaders()\n    {\n        return p.headersIn;\n    }\n\n    /// HTTP method used.\n    @property void method(Method m)\n    {\n        p.method = m;\n    }\n\n    /// ditto\n    @property Method method()\n    {\n        return p.method;\n    }\n\n    /**\n       HTTP status line of last response. One call to perform may\n       result in several requests because of redirection.\n    */\n    @property StatusLine statusLine()\n    {\n        return p.status;\n    }\n\n    /// Set the active cookie string e.g. \"name1=value1;name2=value2\"\n    void setCookie(const(char)[] cookie)\n    {\n        p.curl.set(CurlOption.cookie, cookie);\n    }\n\n    /// Set a file path to where a cookie jar should be read/stored.\n    void setCookieJar(const(char)[] path)\n    {\n        p.curl.set(CurlOption.cookiefile, path);\n        if (path.length)\n            p.curl.set(CurlOption.cookiejar, path);\n    }\n\n    /// Flush cookie jar to disk.\n    void flushCookieJar()\n    {\n        p.curl.set(CurlOption.cookielist, \"FLUSH\");\n    }\n\n    /// Clear session cookies.\n    void clearSessionCookies()\n    {\n        p.curl.set(CurlOption.cookielist, \"SESS\");\n    }\n\n    /// Clear all cookies.\n    void clearAllCookies()\n    {\n        p.curl.set(CurlOption.cookielist, \"ALL\");\n    }\n\n    /**\n       Set time condition on the request.\n\n       Params:\n       cond =  `CurlTimeCond.{none,ifmodsince,ifunmodsince,lastmod}`\n       timestamp = Timestamp for the condition\n\n       $(HTTP www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25, _RFC2616 Section 14.25)\n    */\n    void setTimeCondition(HTTP.TimeCond cond, SysTime timestamp)\n    {\n        p.curl.set(CurlOption.timecondition, cond);\n        p.curl.set(CurlOption.timevalue, timestamp.toUnixTime());\n    }\n\n    /** Specifying data to post when not using the onSend callback.\n      *\n      * The data is NOT copied by the library.  Content-Type will default to\n      * application/octet-stream.  Data is not converted or encoded by this\n      * method.\n      *\n      * Example:\n      * ----\n      * import std.net.curl, std.stdio;\n      * auto http = HTTP(\"http://www.mydomain.com\");\n      * http.onReceive = (ubyte[] data) { writeln(to!(const(char)[])(data)); return data.length; };\n      * http.postData = [1,2,3,4,5];\n      * http.perform();\n      * ----\n      */\n    @property void postData(const(void)[] data)\n    {\n        setPostData(data, \"application/octet-stream\");\n    }\n\n    /** Specifying data to post when not using the onSend callback.\n      *\n      * The data is NOT copied by the library.  Content-Type will default to\n      * text/plain.  Data is not converted or encoded by this method.\n      *\n      * Example:\n      * ----\n      * import std.net.curl, std.stdio;\n      * auto http = HTTP(\"http://www.mydomain.com\");\n      * http.onReceive = (ubyte[] data) { writeln(to!(const(char)[])(data)); return data.length; };\n      * http.postData = \"The quick....\";\n      * http.perform();\n      * ----\n      */\n    @property void postData(const(char)[] data)\n    {\n        setPostData(data, \"text/plain\");\n    }\n\n    /**\n     * Specify data to post when not using the onSend callback, with\n     * user-specified Content-Type.\n     * Params:\n     *  data = Data to post.\n     *  contentType = MIME type of the data, for example, \"text/plain\" or\n     *      \"application/octet-stream\". See also:\n     *      $(LINK2 http://en.wikipedia.org/wiki/Internet_media_type,\n     *      Internet media type) on Wikipedia.\n     * -----\n     * import std.net.curl;\n     * auto http = HTTP(\"http://onlineform.example.com\");\n     * auto data = \"app=login&username=bob&password=s00perS3kret\";\n     * http.setPostData(data, \"application/x-www-form-urlencoded\");\n     * http.onReceive = (ubyte[] data) { return data.length; };\n     * http.perform();\n     * -----\n     */\n    void setPostData(const(void)[] data, string contentType)\n    {\n        // cannot use callback when specifying data directly so it is disabled here.\n        p.curl.clear(CurlOption.readfunction);\n        addRequestHeader(\"Content-Type\", contentType);\n        p.curl.set(CurlOption.postfields, cast(void*) data.ptr);\n        p.curl.set(CurlOption.postfieldsize, data.length);\n        if (method == Method.undefined)\n            method = Method.post;\n    }\n\n    @system unittest\n    {\n        import std.algorithm.searching : canFind;\n\n        testServer.handle((s) {\n            auto req = s.recvReq!ubyte;\n            assert(req.hdrs.canFind(\"POST /path\"));\n            assert(req.bdy.canFind(cast(ubyte[])[0, 1, 2, 3, 4]));\n            assert(req.bdy.canFind(cast(ubyte[])[253, 254, 255]));\n            s.send(httpOK(cast(ubyte[])[17, 27, 35, 41]));\n        });\n        auto data = new ubyte[](256);\n        foreach (i, ref ub; data)\n            ub = cast(ubyte) i;\n\n        auto http = HTTP(testServer.addr~\"/path\");\n        http.postData = data;\n        ubyte[] res;\n        http.onReceive = (data) { res ~= data; return data.length; };\n        http.perform();\n        assert(res == cast(ubyte[])[17, 27, 35, 41]);\n    }\n\n    /**\n      * Set the event handler that receives incoming headers.\n      *\n      * The callback will receive a header field key, value as parameter. The\n      * `const(char)[]` arrays are not valid after the delegate has returned.\n      *\n      * Example:\n      * ----\n      * import std.net.curl, std.stdio;\n      * auto http = HTTP(\"dlang.org\");\n      * http.onReceive = (ubyte[] data) { writeln(to!(const(char)[])(data)); return data.length; };\n      * http.onReceiveHeader = (in char[] key, in char[] value) { writeln(key, \" = \", value); };\n      * http.perform();\n      * ----\n      */\n    @property void onReceiveHeader(void delegate(in char[] key,\n                                                 in char[] value) callback)\n    {\n        p.onReceiveHeader = callback;\n    }\n\n    /**\n       Callback for each received StatusLine.\n\n       Notice that several callbacks can be done for each call to\n       `perform()` due to redirections.\n\n       See_Also: $(LREF StatusLine)\n     */\n    @property void onReceiveStatusLine(void delegate(StatusLine) callback)\n    {\n        p.onReceiveStatusLine = callback;\n    }\n\n    /**\n       The content length in bytes when using request that has content\n       e.g. POST/PUT and not using chunked transfer. Is set as the\n       \"Content-Length\" header.  Set to ulong.max to reset to chunked transfer.\n    */\n    @property void contentLength(ulong len)\n    {\n        import std.conv : to;\n\n        CurlOption lenOpt;\n\n        // Force post if necessary\n        if (p.method != Method.put && p.method != Method.post &&\n            p.method != Method.patch)\n            p.method = Method.post;\n\n        if (p.method == Method.post || p.method == Method.patch)\n            lenOpt = CurlOption.postfieldsize_large;\n        else\n            lenOpt = CurlOption.infilesize_large;\n\n        if (size_t.max != ulong.max && len == size_t.max)\n            len = ulong.max; // check size_t.max for backwards compat, turn into error\n\n        if (len == ulong.max)\n        {\n            // HTTP 1.1 supports requests with no length header set.\n            addRequestHeader(\"Transfer-Encoding\", \"chunked\");\n            addRequestHeader(\"Expect\", \"100-continue\");\n        }\n        else\n        {\n            p.curl.set(lenOpt, to!curl_off_t(len));\n        }\n    }\n\n    /**\n       Authentication method as specified in $(LREF AuthMethod).\n    */\n    @property void authenticationMethod(AuthMethod authMethod)\n    {\n        p.curl.set(CurlOption.httpauth, cast(long) authMethod);\n    }\n\n    /**\n       Set max allowed redirections using the location header.\n       uint.max for infinite.\n    */\n    @property void maxRedirects(uint maxRedirs)\n    {\n        if (maxRedirs == uint.max)\n        {\n            // Disable\n            p.curl.set(CurlOption.followlocation, 0);\n        }\n        else\n        {\n            p.curl.set(CurlOption.followlocation, 1);\n            p.curl.set(CurlOption.maxredirs, maxRedirs);\n        }\n    }\n\n    /** <a name=\"HTTP.Method\"/>The standard HTTP methods :\n     *  $(HTTP www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.1, _RFC2616 Section 5.1.1)\n     */\n    enum Method\n    {\n        undefined,\n        head, ///\n        get,  ///\n        post, ///\n        put,  ///\n        del,  ///\n        options, ///\n        trace,   ///\n        connect,  ///\n        patch, ///\n    }\n\n    /**\n       HTTP status line ie. the first line returned in an HTTP response.\n\n       If authentication or redirections are done then the status will be for\n       the last response received.\n    */\n    struct StatusLine\n    {\n        ushort majorVersion; /// Major HTTP version ie. 1 in HTTP/1.0.\n        ushort minorVersion; /// Minor HTTP version ie. 0 in HTTP/1.0.\n        ushort code;         /// HTTP status line code e.g. 200.\n        string reason;       /// HTTP status line reason string.\n\n        /// Reset this status line\n        @safe void reset()\n        {\n            majorVersion = 0;\n            minorVersion = 0;\n            code = 0;\n            reason = \"\";\n        }\n\n        ///\n        string toString() const\n        {\n            import std.format : format;\n            return format(\"%s %s (%s.%s)\",\n                          code, reason, majorVersion, minorVersion);\n        }\n    }\n\n} // HTTP\n\n@system unittest // charset/Charset/CHARSET/...\n{\n    import etc.c.curl;\n\n    static foreach (c; [\"charset\", \"Charset\", \"CHARSET\", \"CharSet\", \"charSet\",\n        \"ChArSeT\", \"cHaRsEt\"])\n    {{\n        testServer.handle((s) {\n            s.send(\"HTTP/1.1 200 OK\\r\\n\"~\n                \"Content-Length: 0\\r\\n\"~\n                \"Content-Type: text/plain; \" ~ c ~ \"=foo\\r\\n\" ~\n                \"\\r\\n\");\n        });\n\n        auto http = HTTP(testServer.addr);\n        http.perform();\n        assert(http.p.charset == \"foo\");\n\n        // Bugzilla 16736\n        double val;\n        CurlCode code;\n\n        code = http.getTiming(CurlInfo.total_time, val);\n        assert(code == CurlError.ok);\n        code = http.getTiming(CurlInfo.namelookup_time, val);\n        assert(code == CurlError.ok);\n        code = http.getTiming(CurlInfo.connect_time, val);\n        assert(code == CurlError.ok);\n        code = http.getTiming(CurlInfo.pretransfer_time, val);\n        assert(code == CurlError.ok);\n        code = http.getTiming(CurlInfo.starttransfer_time, val);\n        assert(code == CurlError.ok);\n        code = http.getTiming(CurlInfo.redirect_time, val);\n        assert(code == CurlError.ok);\n        code = http.getTiming(CurlInfo.appconnect_time, val);\n        assert(code == CurlError.ok);\n    }}\n}\n\n/**\n   FTP client functionality.\n\n   See_Also: $(HTTP tools.ietf.org/html/rfc959, RFC959)\n*/\nstruct FTP\n{\n\n    mixin Protocol;\n\n    import std.typecons : RefCounted;\n    import etc.c.curl : CurlError, CurlInfo, curl_off_t, curl_slist;\n\n    private struct Impl\n    {\n        ~this()\n        {\n            if (commands !is null)\n                Curl.curl.slist_free_all(commands);\n            if (curl.handle !is null) // work around RefCounted/emplace bug\n                curl.shutdown();\n        }\n        curl_slist* commands;\n        Curl curl;\n        string encoding;\n    }\n\n    private RefCounted!Impl p;\n\n    /**\n       FTP access to the specified url.\n    */\n    static FTP opCall(const(char)[] url)\n    {\n        FTP ftp;\n        ftp.initialize();\n        ftp.url = url;\n        return ftp;\n    }\n\n    ///\n    static FTP opCall()\n    {\n        FTP ftp;\n        ftp.initialize();\n        return ftp;\n    }\n\n    ///\n    FTP dup()\n    {\n        FTP copy = FTP();\n        copy.initialize();\n        copy.p.encoding = p.encoding;\n        copy.p.curl = p.curl.dup();\n        curl_slist* cur = p.commands;\n        curl_slist* newlist = null;\n        while (cur)\n        {\n            newlist = Curl.curl.slist_append(newlist, cur.data);\n            cur = cur.next;\n        }\n        copy.p.commands = newlist;\n        copy.p.curl.set(CurlOption.postquote, copy.p.commands);\n        copy.dataTimeout = _defaultDataTimeout;\n        return copy;\n    }\n\n    private void initialize()\n    {\n        p.curl.initialize();\n        p.encoding = \"ISO-8859-1\";\n        dataTimeout = _defaultDataTimeout;\n    }\n\n    /**\n       Performs the ftp request as it has been configured.\n\n       After a FTP client has been setup and possibly assigned callbacks the $(D\n       perform()) method will start performing the actual communication with the\n       server.\n\n       Params:\n       throwOnError = whether to throw an exception or return a CurlCode on error\n    */\n    CurlCode perform(ThrowOnError throwOnError = Yes.throwOnError)\n    {\n        return p.curl.perform(throwOnError);\n    }\n\n    /// The URL to specify the location of the resource.\n    @property void url(const(char)[] url)\n    {\n        import std.algorithm.searching : startsWith;\n        import std.uni : toLower;\n\n        if (!startsWith(url.toLower(), \"ftp://\", \"ftps://\"))\n            url = \"ftp://\" ~ url;\n        p.curl.set(CurlOption.url, url);\n    }\n\n    // This is a workaround for mixed in content not having its\n    // docs mixed in.\n    version (StdDdoc)\n    {\n        static import etc.c.curl;\n\n        /// Value to return from `onSend`/`onReceive` delegates in order to\n        /// pause a request\n        alias requestPause = CurlReadFunc.pause;\n\n        /// Value to return from onSend delegate in order to abort a request\n        alias requestAbort = CurlReadFunc.abort;\n\n        /**\n           True if the instance is stopped. A stopped instance is not usable.\n        */\n        @property bool isStopped();\n\n        /// Stop and invalidate this instance.\n        void shutdown();\n\n        /** Set verbose.\n            This will print request information to stderr.\n        */\n        @property void verbose(bool on);\n\n        // Connection settings\n\n        /// Set timeout for activity on connection.\n        @property void dataTimeout(Duration d);\n\n        /** Set maximum time an operation is allowed to take.\n            This includes dns resolution, connecting, data transfer, etc.\n          */\n        @property void operationTimeout(Duration d);\n\n        /// Set timeout for connecting.\n        @property void connectTimeout(Duration d);\n\n        // Network settings\n\n        /** Proxy\n         *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXY, _proxy)\n         */\n        @property void proxy(const(char)[] host);\n\n        /** Proxy port\n         *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXYPORT, _proxy_port)\n         */\n        @property void proxyPort(ushort port);\n\n        /// Type of proxy\n        alias CurlProxy = etc.c.curl.CurlProxy;\n\n        /** Proxy type\n         *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXY, _proxy_type)\n         */\n        @property void proxyType(CurlProxy type);\n\n        /// DNS lookup timeout.\n        @property void dnsTimeout(Duration d);\n\n        /**\n         * The network interface to use in form of the the IP of the interface.\n         *\n         * Example:\n         * ----\n         * theprotocol.netInterface = \"192.168.1.32\";\n         * theprotocol.netInterface = [ 192, 168, 1, 32 ];\n         * ----\n         *\n         * See: $(REF InternetAddress, std,socket)\n         */\n        @property void netInterface(const(char)[] i);\n\n        /// ditto\n        @property void netInterface(const(ubyte)[4] i);\n\n        /// ditto\n        @property void netInterface(InternetAddress i);\n\n        /**\n           Set the local outgoing port to use.\n           Params:\n           port = the first outgoing port number to try and use\n        */\n        @property void localPort(ushort port);\n\n        /**\n           Set the local outgoing port range to use.\n           This can be used together with the localPort property.\n           Params:\n           range = if the first port is occupied then try this many\n           port number forwards\n        */\n        @property void localPortRange(ushort range);\n\n        /** Set the tcp no-delay socket option on or off.\n            See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTTCPNODELAY, nodelay)\n        */\n        @property void tcpNoDelay(bool on);\n\n        // Authentication settings\n\n        /**\n           Set the user name, password and optionally domain for authentication\n           purposes.\n\n           Some protocols may need authentication in some cases. Use this\n           function to provide credentials.\n\n           Params:\n           username = the username\n           password = the password\n           domain = used for NTLM authentication only and is set to the NTLM domain\n           name\n        */\n        void setAuthentication(const(char)[] username, const(char)[] password,\n                               const(char)[] domain = \"\");\n\n        /**\n           Set the user name and password for proxy authentication.\n\n           Params:\n           username = the username\n           password = the password\n        */\n        void setProxyAuthentication(const(char)[] username, const(char)[] password);\n\n        /**\n         * The event handler that gets called when data is needed for sending. The\n         * length of the `void[]` specifies the maximum number of bytes that can\n         * be sent.\n         *\n         * Returns:\n         * The callback returns the number of elements in the buffer that have been\n         * filled and are ready to send.\n         * The special value `.abortRequest` can be returned in order to abort the\n         * current request.\n         * The special value `.pauseRequest` can be returned in order to pause the\n         * current request.\n         *\n         */\n        @property void onSend(size_t delegate(void[]) callback);\n\n        /**\n         * The event handler that receives incoming data. Be sure to copy the\n         * incoming ubyte[] since it is not guaranteed to be valid after the\n         * callback returns.\n         *\n         * Returns:\n         * The callback returns the incoming bytes read. If not the entire array is\n         * the request will abort.\n         * The special value .pauseRequest can be returned in order to pause the\n         * current request.\n         *\n         */\n        @property void onReceive(size_t delegate(ubyte[]) callback);\n\n        /**\n         * The event handler that gets called to inform of upload/download progress.\n         *\n         * Callback_parameters:\n         * $(CALLBACK_PARAMS)\n         *\n         * Callback_returns:\n         * Return 0 from the callback to signal success, return non-zero to\n         * abort transfer.\n         */\n        @property void onProgress(int delegate(size_t dlTotal, size_t dlNow,\n                                               size_t ulTotal, size_t ulNow) callback);\n    }\n\n    /** Clear all commands send to ftp server.\n    */\n    void clearCommands()\n    {\n        if (p.commands !is null)\n            Curl.curl.slist_free_all(p.commands);\n        p.commands = null;\n        p.curl.clear(CurlOption.postquote);\n    }\n\n    /** Add a command to send to ftp server.\n     *\n     * There is no remove command functionality. Do a $(LREF clearCommands) and\n     * set the needed commands instead.\n     *\n     * Example:\n     * ---\n     * import std.net.curl;\n     * auto client = FTP();\n     * client.addCommand(\"RNFR my_file.txt\");\n     * client.addCommand(\"RNTO my_renamed_file.txt\");\n     * upload(\"my_file.txt\", \"ftp.digitalmars.com\", client);\n     * ---\n     */\n    void addCommand(const(char)[] command)\n    {\n        import std.internal.cstring : tempCString;\n        p.commands = Curl.curl.slist_append(p.commands,\n                                            command.tempCString().buffPtr);\n        p.curl.set(CurlOption.postquote, p.commands);\n    }\n\n    /// Connection encoding. Defaults to ISO-8859-1.\n    @property void encoding(string name)\n    {\n        p.encoding = name;\n    }\n\n    /// ditto\n    @property string encoding()\n    {\n        return p.encoding;\n    }\n\n    /**\n       The content length in bytes of the ftp data.\n    */\n    @property void contentLength(ulong len)\n    {\n        import std.conv : to;\n        p.curl.set(CurlOption.infilesize_large, to!curl_off_t(len));\n    }\n\n    /**\n     * Get various timings defined in $(REF CurlInfo, etc, c, curl).\n     * The value is usable only if the return value is equal to `etc.c.curl.CurlError.ok`.\n     *\n     * Params:\n     *      timing = one of the timings defined in $(REF CurlInfo, etc, c, curl).\n     *               The values are:\n     *               `etc.c.curl.CurlInfo.namelookup_time`,\n     *               `etc.c.curl.CurlInfo.connect_time`,\n     *               `etc.c.curl.CurlInfo.pretransfer_time`,\n     *               `etc.c.curl.CurlInfo.starttransfer_time`,\n     *               `etc.c.curl.CurlInfo.redirect_time`,\n     *               `etc.c.curl.CurlInfo.appconnect_time`,\n     *               `etc.c.curl.CurlInfo.total_time`.\n     *      val    = the actual value of the inquired timing.\n     *\n     * Returns:\n     *      The return code of the operation. The value stored in val\n     *      should be used only if the return value is `etc.c.curl.CurlInfo.ok`.\n     *\n     * Example:\n     * ---\n     * import std.net.curl;\n     * import etc.c.curl : CurlError, CurlInfo;\n     *\n     * auto client = FTP();\n     * client.addCommand(\"RNFR my_file.txt\");\n     * client.addCommand(\"RNTO my_renamed_file.txt\");\n     * upload(\"my_file.txt\", \"ftp.digitalmars.com\", client);\n     *\n     * double val;\n     * CurlCode code;\n     *\n     * code = client.getTiming(CurlInfo.namelookup_time, val);\n     * assert(code == CurlError.ok);\n     * ---\n     */\n    CurlCode getTiming(CurlInfo timing, ref double val)\n    {\n        return p.curl.getTiming(timing, val);\n    }\n\n    @system unittest\n    {\n        auto client = FTP();\n\n        double val;\n        CurlCode code;\n\n        code = client.getTiming(CurlInfo.total_time, val);\n        assert(code == CurlError.ok);\n        code = client.getTiming(CurlInfo.namelookup_time, val);\n        assert(code == CurlError.ok);\n        code = client.getTiming(CurlInfo.connect_time, val);\n        assert(code == CurlError.ok);\n        code = client.getTiming(CurlInfo.pretransfer_time, val);\n        assert(code == CurlError.ok);\n        code = client.getTiming(CurlInfo.starttransfer_time, val);\n        assert(code == CurlError.ok);\n        code = client.getTiming(CurlInfo.redirect_time, val);\n        assert(code == CurlError.ok);\n        code = client.getTiming(CurlInfo.appconnect_time, val);\n        assert(code == CurlError.ok);\n    }\n}\n\n/**\n  * Basic SMTP protocol support.\n  *\n  * Example:\n  * ---\n  * import std.net.curl;\n  *\n  * // Send an email with SMTPS\n  * auto smtp = SMTP(\"smtps://smtp.gmail.com\");\n  * smtp.setAuthentication(\"from.addr@gmail.com\", \"password\");\n  * smtp.mailTo = [\"<to.addr@gmail.com>\"];\n  * smtp.mailFrom = \"<from.addr@gmail.com>\";\n  * smtp.message = \"Example Message\";\n  * smtp.perform();\n  * ---\n  *\n  * See_Also: $(HTTP www.ietf.org/rfc/rfc2821.txt, RFC2821)\n  */\nstruct SMTP\n{\n    mixin Protocol;\n    import std.typecons : RefCounted;\n    import etc.c.curl : CurlUseSSL, curl_slist;\n\n    private struct Impl\n    {\n        ~this()\n        {\n            if (curl.handle !is null) // work around RefCounted/emplace bug\n                curl.shutdown();\n        }\n        Curl curl;\n\n        @property void message(string msg)\n        {\n            import std.algorithm.comparison : min;\n\n            auto _message = msg;\n            /**\n                This delegate reads the message text and copies it.\n            */\n            curl.onSend = delegate size_t(void[] data)\n            {\n                if (!msg.length) return 0;\n                size_t to_copy = min(data.length, _message.length);\n                data[0 .. to_copy] = (cast(void[])_message)[0 .. to_copy];\n                _message = _message[to_copy..$];\n                return to_copy;\n            };\n        }\n    }\n\n    private RefCounted!Impl p;\n\n    /**\n        Sets to the URL of the SMTP server.\n    */\n    static SMTP opCall(const(char)[] url)\n    {\n        SMTP smtp;\n        smtp.initialize();\n        smtp.url = url;\n        return smtp;\n    }\n\n    ///\n    static SMTP opCall()\n    {\n        SMTP smtp;\n        smtp.initialize();\n        return smtp;\n    }\n\n    /+ TODO: The other structs have this function.\n    SMTP dup()\n    {\n        SMTP copy = SMTP();\n        copy.initialize();\n        copy.p.encoding = p.encoding;\n        copy.p.curl = p.curl.dup();\n        curl_slist* cur = p.commands;\n        curl_slist* newlist = null;\n        while (cur)\n        {\n            newlist = Curl.curl.slist_append(newlist, cur.data);\n            cur = cur.next;\n        }\n        copy.p.commands = newlist;\n        copy.p.curl.set(CurlOption.postquote, copy.p.commands);\n        copy.dataTimeout = _defaultDataTimeout;\n        return copy;\n    }\n    +/\n\n    /**\n        Performs the request as configured.\n        Params:\n        throwOnError = whether to throw an exception or return a CurlCode on error\n    */\n    CurlCode perform(ThrowOnError throwOnError = Yes.throwOnError)\n    {\n        return p.curl.perform(throwOnError);\n    }\n\n    /// The URL to specify the location of the resource.\n    @property void url(const(char)[] url)\n    {\n        import std.algorithm.searching : startsWith;\n        import std.exception : enforce;\n        import std.uni : toLower;\n\n        auto lowered = url.toLower();\n\n        if (lowered.startsWith(\"smtps://\"))\n        {\n            p.curl.set(CurlOption.use_ssl, CurlUseSSL.all);\n        }\n        else\n        {\n            enforce!CurlException(lowered.startsWith(\"smtp://\"),\n                                    \"The url must be for the smtp protocol.\");\n        }\n        p.curl.set(CurlOption.url, url);\n    }\n\n    private void initialize()\n    {\n        p.curl.initialize();\n        p.curl.set(CurlOption.upload, 1L);\n        dataTimeout = _defaultDataTimeout;\n        verifyPeer = true;\n        verifyHost = true;\n    }\n\n    // This is a workaround for mixed in content not having its\n    // docs mixed in.\n    version (StdDdoc)\n    {\n        static import etc.c.curl;\n\n        /// Value to return from `onSend`/`onReceive` delegates in order to\n        /// pause a request\n        alias requestPause = CurlReadFunc.pause;\n\n        /// Value to return from onSend delegate in order to abort a request\n        alias requestAbort = CurlReadFunc.abort;\n\n        /**\n           True if the instance is stopped. A stopped instance is not usable.\n        */\n        @property bool isStopped();\n\n        /// Stop and invalidate this instance.\n        void shutdown();\n\n        /** Set verbose.\n            This will print request information to stderr.\n        */\n        @property void verbose(bool on);\n\n        // Connection settings\n\n        /// Set timeout for activity on connection.\n        @property void dataTimeout(Duration d);\n\n        /** Set maximum time an operation is allowed to take.\n            This includes dns resolution, connecting, data transfer, etc.\n          */\n        @property void operationTimeout(Duration d);\n\n        /// Set timeout for connecting.\n        @property void connectTimeout(Duration d);\n\n        // Network settings\n\n        /** Proxy\n         *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXY, _proxy)\n         */\n        @property void proxy(const(char)[] host);\n\n        /** Proxy port\n         *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXYPORT, _proxy_port)\n         */\n        @property void proxyPort(ushort port);\n\n        /// Type of proxy\n        alias CurlProxy = etc.c.curl.CurlProxy;\n\n        /** Proxy type\n         *  See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXY, _proxy_type)\n         */\n        @property void proxyType(CurlProxy type);\n\n        /// DNS lookup timeout.\n        @property void dnsTimeout(Duration d);\n\n        /**\n         * The network interface to use in form of the the IP of the interface.\n         *\n         * Example:\n         * ----\n         * theprotocol.netInterface = \"192.168.1.32\";\n         * theprotocol.netInterface = [ 192, 168, 1, 32 ];\n         * ----\n         *\n         * See: $(REF InternetAddress, std,socket)\n         */\n        @property void netInterface(const(char)[] i);\n\n        /// ditto\n        @property void netInterface(const(ubyte)[4] i);\n\n        /// ditto\n        @property void netInterface(InternetAddress i);\n\n        /**\n           Set the local outgoing port to use.\n           Params:\n           port = the first outgoing port number to try and use\n        */\n        @property void localPort(ushort port);\n\n        /**\n           Set the local outgoing port range to use.\n           This can be used together with the localPort property.\n           Params:\n           range = if the first port is occupied then try this many\n           port number forwards\n        */\n        @property void localPortRange(ushort range);\n\n        /** Set the tcp no-delay socket option on or off.\n            See: $(HTTP curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTTCPNODELAY, nodelay)\n        */\n        @property void tcpNoDelay(bool on);\n\n        // Authentication settings\n\n        /**\n           Set the user name, password and optionally domain for authentication\n           purposes.\n\n           Some protocols may need authentication in some cases. Use this\n           function to provide credentials.\n\n           Params:\n           username = the username\n           password = the password\n           domain = used for NTLM authentication only and is set to the NTLM domain\n           name\n        */\n        void setAuthentication(const(char)[] username, const(char)[] password,\n                               const(char)[] domain = \"\");\n\n        /**\n           Set the user name and password for proxy authentication.\n\n           Params:\n           username = the username\n           password = the password\n        */\n        void setProxyAuthentication(const(char)[] username, const(char)[] password);\n\n        /**\n         * The event handler that gets called when data is needed for sending. The\n         * length of the `void[]` specifies the maximum number of bytes that can\n         * be sent.\n         *\n         * Returns:\n         * The callback returns the number of elements in the buffer that have been\n         * filled and are ready to send.\n         * The special value `.abortRequest` can be returned in order to abort the\n         * current request.\n         * The special value `.pauseRequest` can be returned in order to pause the\n         * current request.\n         */\n        @property void onSend(size_t delegate(void[]) callback);\n\n        /**\n         * The event handler that receives incoming data. Be sure to copy the\n         * incoming ubyte[] since it is not guaranteed to be valid after the\n         * callback returns.\n         *\n         * Returns:\n         * The callback returns the incoming bytes read. If not the entire array is\n         * the request will abort.\n         * The special value .pauseRequest can be returned in order to pause the\n         * current request.\n         */\n        @property void onReceive(size_t delegate(ubyte[]) callback);\n\n        /**\n         * The event handler that gets called to inform of upload/download progress.\n         *\n         * Callback_parameters:\n         * $(CALLBACK_PARAMS)\n         *\n         * Callback_returns:\n         * Return 0 from the callback to signal success, return non-zero to\n         * abort transfer.\n         */\n        @property void onProgress(int delegate(size_t dlTotal, size_t dlNow,\n                                               size_t ulTotal, size_t ulNow) callback);\n    }\n\n    /**\n        Setter for the sender's email address.\n    */\n    @property void mailFrom()(const(char)[] sender)\n    {\n        assert(!sender.empty, \"Sender must not be empty\");\n        p.curl.set(CurlOption.mail_from, sender);\n    }\n\n    /**\n        Setter for the recipient email addresses.\n    */\n    void mailTo()(const(char)[][] recipients...)\n    {\n        import std.internal.cstring : tempCString;\n        assert(!recipients.empty, \"Recipient must not be empty\");\n        curl_slist* recipients_list = null;\n        foreach (recipient; recipients)\n        {\n            recipients_list =\n                Curl.curl.slist_append(recipients_list,\n                                  recipient.tempCString().buffPtr);\n        }\n        p.curl.set(CurlOption.mail_rcpt, recipients_list);\n    }\n\n    /**\n        Sets the message body text.\n    */\n\n    @property void message(string msg)\n    {\n        p.message = msg;\n    }\n}\n\n@system unittest\n{\n    import std.net.curl;\n\n    // Send an email with SMTPS\n    auto smtp = SMTP(\"smtps://smtp.gmail.com\");\n    smtp.setAuthentication(\"from.addr@gmail.com\", \"password\");\n    smtp.mailTo = [\"<to.addr@gmail.com>\"];\n    smtp.mailFrom = \"<from.addr@gmail.com>\";\n    smtp.message = \"Example Message\";\n    //smtp.perform();\n}\n\n\n/++\n    Exception thrown on errors in std.net.curl functions.\n+/\nclass CurlException : Exception\n{\n    /++\n        Params:\n            msg  = The message for the exception.\n            file = The file where the exception occurred.\n            line = The line number where the exception occurred.\n            next = The previous exception in the chain of exceptions, if any.\n      +/\n    @safe pure nothrow\n    this(string msg,\n         string file = __FILE__,\n         size_t line = __LINE__,\n         Throwable next = null)\n    {\n        super(msg, file, line, next);\n    }\n}\n\n/++\n    Exception thrown on timeout errors in std.net.curl functions.\n+/\nclass CurlTimeoutException : CurlException\n{\n    /++\n        Params:\n            msg  = The message for the exception.\n            file = The file where the exception occurred.\n            line = The line number where the exception occurred.\n            next = The previous exception in the chain of exceptions, if any.\n      +/\n    @safe pure nothrow\n    this(string msg,\n         string file = __FILE__,\n         size_t line = __LINE__,\n         Throwable next = null)\n    {\n        super(msg, file, line, next);\n    }\n}\n\n/++\n    Exception thrown on HTTP request failures, e.g. 404 Not Found.\n+/\nclass HTTPStatusException : CurlException\n{\n    /++\n        Params:\n            status = The HTTP status code.\n            msg  = The message for the exception.\n            file = The file where the exception occurred.\n            line = The line number where the exception occurred.\n            next = The previous exception in the chain of exceptions, if any.\n      +/\n    @safe pure nothrow\n    this(int status,\n         string msg,\n         string file = __FILE__,\n         size_t line = __LINE__,\n         Throwable next = null)\n    {\n        super(msg, file, line, next);\n        this.status = status;\n    }\n\n    immutable int status; /// The HTTP status code\n}\n\n/// Equal to $(REF CURLcode, etc,c,curl)\nalias CurlCode = CURLcode;\n\n/// Flag to specify whether or not an exception is thrown on error.\nalias ThrowOnError = Flag!\"throwOnError\";\n\nprivate struct CurlAPI\n{\n    import etc.c.curl : CurlGlobal;\n    static struct API\n    {\n    import etc.c.curl : curl_version_info, curl_version_info_data,\n                        CURL, CURLcode, CURLINFO, CURLoption, CURLversion, curl_slist;\n    extern(C):\n        import core.stdc.config : c_long;\n        CURLcode function(c_long flags) global_init;\n        void function() global_cleanup;\n        curl_version_info_data * function(CURLversion) version_info;\n        CURL* function() easy_init;\n        CURLcode function(CURL *curl, CURLoption option,...) easy_setopt;\n        CURLcode function(CURL *curl) easy_perform;\n        CURLcode function(CURL *curl, CURLINFO info,...) easy_getinfo;\n        CURL* function(CURL *curl) easy_duphandle;\n        char* function(CURLcode) easy_strerror;\n        CURLcode function(CURL *handle, int bitmask) easy_pause;\n        void function(CURL *curl) easy_cleanup;\n        curl_slist* function(curl_slist *, char *) slist_append;\n        void function(curl_slist *) slist_free_all;\n    }\n    __gshared API _api;\n    __gshared void* _handle;\n\n    static ref API instance() @property\n    {\n        import std.concurrency : initOnce;\n        initOnce!_handle(loadAPI());\n        return _api;\n    }\n\n    static void* loadAPI()\n    {\n        import std.exception : enforce;\n\n        version (Posix)\n        {\n            import core.sys.posix.dlfcn : dlsym, dlopen, dlclose, RTLD_LAZY;\n            alias loadSym = dlsym;\n        }\n        else version (Windows)\n        {\n            import core.sys.windows.windows : GetProcAddress, GetModuleHandleA,\n                LoadLibraryA;\n            alias loadSym = GetProcAddress;\n        }\n        else\n            static assert(0, \"unimplemented\");\n\n        void* handle;\n        version (Posix)\n            handle = dlopen(null, RTLD_LAZY);\n        else version (Windows)\n            handle = GetModuleHandleA(null);\n        assert(handle !is null);\n\n        // try to load curl from the executable to allow static linking\n        if (loadSym(handle, \"curl_global_init\") is null)\n        {\n            import std.format : format;\n            version (Posix)\n                dlclose(handle);\n\n            version (OSX)\n                static immutable names = [\"libcurl.4.dylib\"];\n            else version (Posix)\n            {\n                static immutable names = [\"libcurl.so\", \"libcurl.so.4\",\n                \"libcurl-gnutls.so.4\", \"libcurl-nss.so.4\", \"libcurl.so.3\"];\n            }\n            else version (Windows)\n                static immutable names = [\"libcurl.dll\", \"curl.dll\"];\n\n            foreach (name; names)\n            {\n                version (Posix)\n                    handle = dlopen(name.ptr, RTLD_LAZY);\n                else version (Windows)\n                    handle = LoadLibraryA(name.ptr);\n                if (handle !is null) break;\n            }\n\n            enforce!CurlException(handle !is null, \"Failed to load curl, tried %(%s, %).\".format(names));\n        }\n\n        foreach (i, FP; typeof(API.tupleof))\n        {\n            enum name = __traits(identifier, _api.tupleof[i]);\n            auto p = enforce!CurlException(loadSym(handle, \"curl_\"~name),\n                                           \"Couldn't load curl_\"~name~\" from libcurl.\");\n            _api.tupleof[i] = cast(FP) p;\n        }\n\n        enforce!CurlException(!_api.global_init(CurlGlobal.all),\n                              \"Failed to initialize libcurl\");\n\n        static extern(C) void cleanup()\n        {\n            if (_handle is null) return;\n            _api.global_cleanup();\n            version (Posix)\n            {\n                import core.sys.posix.dlfcn : dlclose;\n                dlclose(_handle);\n            }\n            else version (Windows)\n            {\n                import core.sys.windows.windows : FreeLibrary;\n                FreeLibrary(_handle);\n            }\n            else\n                static assert(0, \"unimplemented\");\n            _api = API.init;\n            _handle = null;\n        }\n\n        import core.stdc.stdlib : atexit;\n        atexit(&cleanup);\n\n        return handle;\n    }\n}\n\n/**\n  Wrapper to provide a better interface to libcurl than using the plain C API.\n  It is recommended to use the `HTTP`/`FTP` etc. structs instead unless\n  raw access to libcurl is needed.\n\n  Warning: This struct uses interior pointers for callbacks. Only allocate it\n  on the stack if you never move or copy it. This also means passing by reference\n  when passing Curl to other functions. Otherwise always allocate on\n  the heap.\n*/\nstruct Curl\n{\n    import etc.c.curl : CURL, CurlError, CurlPause, CurlSeek, CurlSeekPos,\n                        curl_socket_t, CurlSockType,\n                        CurlReadFunc, CurlInfo, curlsocktype, curl_off_t,\n                        LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR, LIBCURL_VERSION_PATCH;\n\n    alias OutData = void[];\n    alias InData = ubyte[];\n    private bool _stopped;\n\n    private static auto ref curl() @property { return CurlAPI.instance; }\n\n    // A handle should not be used by two threads simultaneously\n    private CURL* handle;\n\n    // May also return `CURL_READFUNC_ABORT` or `CURL_READFUNC_PAUSE`\n    private size_t delegate(OutData) _onSend;\n    private size_t delegate(InData) _onReceive;\n    private void delegate(in char[]) _onReceiveHeader;\n    private CurlSeek delegate(long,CurlSeekPos) _onSeek;\n    private int delegate(curl_socket_t,CurlSockType) _onSocketOption;\n    private int delegate(size_t dltotal, size_t dlnow,\n                         size_t ultotal, size_t ulnow) _onProgress;\n\n    alias requestPause = CurlReadFunc.pause;\n    alias requestAbort = CurlReadFunc.abort;\n\n    /**\n       Initialize the instance by creating a working curl handle.\n    */\n    void initialize()\n    {\n        import std.exception : enforce;\n        enforce!CurlException(!handle, \"Curl instance already initialized\");\n        handle = curl.easy_init();\n        enforce!CurlException(handle, \"Curl instance couldn't be initialized\");\n        _stopped = false;\n        set(CurlOption.nosignal, 1);\n    }\n\n    ///\n    @property bool stopped() const\n    {\n        return _stopped;\n    }\n\n    /**\n       Duplicate this handle.\n\n       The new handle will have all options set as the one it was duplicated\n       from. An exception to this is that all options that cannot be shared\n       across threads are reset thereby making it safe to use the duplicate\n       in a new thread.\n    */\n    Curl dup()\n    {\n        import std.meta : AliasSeq;\n        Curl copy;\n        copy.handle = curl.easy_duphandle(handle);\n        copy._stopped = false;\n\n        with (CurlOption) {\n            auto tt = AliasSeq!(file, writefunction, writeheader,\n                headerfunction, infile, readfunction, ioctldata, ioctlfunction,\n                seekdata, seekfunction, sockoptdata, sockoptfunction,\n                opensocketdata, opensocketfunction, progressdata,\n                progressfunction, debugdata, debugfunction, interleavedata,\n                interleavefunction, chunk_data, chunk_bgn_function,\n                chunk_end_function, fnmatch_data, fnmatch_function, cookiejar, postfields);\n\n            foreach (option; tt)\n                copy.clear(option);\n        }\n\n        // The options are only supported by libcurl when it has been built\n        // against certain versions of OpenSSL - if your libcurl uses an old\n        // OpenSSL, or uses an entirely different SSL engine, attempting to\n        // clear these normally will raise an exception\n        copy.clearIfSupported(CurlOption.ssl_ctx_function);\n        copy.clearIfSupported(CurlOption.ssh_keydata);\n\n        // Enable for curl version > 7.21.7\n        static if (LIBCURL_VERSION_MAJOR >= 7 &&\n                   LIBCURL_VERSION_MINOR >= 21 &&\n                   LIBCURL_VERSION_PATCH >= 7)\n        {\n            copy.clear(CurlOption.closesocketdata);\n            copy.clear(CurlOption.closesocketfunction);\n        }\n\n        copy.set(CurlOption.nosignal, 1);\n\n        // copy.clear(CurlOption.ssl_ctx_data); Let ssl function be shared\n        // copy.clear(CurlOption.ssh_keyfunction); Let key function be shared\n\n        /*\n          Allow sharing of conv functions\n          copy.clear(CurlOption.conv_to_network_function);\n          copy.clear(CurlOption.conv_from_network_function);\n          copy.clear(CurlOption.conv_from_utf8_function);\n        */\n\n        return copy;\n    }\n\n    private void _check(CurlCode code)\n    {\n        import std.exception : enforce;\n        enforce!CurlTimeoutException(code != CurlError.operation_timedout,\n                                       errorString(code));\n\n        enforce!CurlException(code == CurlError.ok,\n                                errorString(code));\n    }\n\n    private string errorString(CurlCode code)\n    {\n        import core.stdc.string : strlen;\n        import std.format : format;\n\n        auto msgZ = curl.easy_strerror(code);\n        // doing the following (instead of just using std.conv.to!string) avoids 1 allocation\n        return format(\"%s on handle %s\", msgZ[0 .. strlen(msgZ)], handle);\n    }\n\n    private void throwOnStopped(string message = null)\n    {\n        import std.exception : enforce;\n        auto def = \"Curl instance called after being cleaned up\";\n        enforce!CurlException(!stopped,\n                                message == null ? def : message);\n    }\n\n    /**\n        Stop and invalidate this curl instance.\n        Warning: Do not call this from inside a callback handler e.g. `onReceive`.\n    */\n    void shutdown()\n    {\n        throwOnStopped();\n        _stopped = true;\n        curl.easy_cleanup(this.handle);\n        this.handle = null;\n    }\n\n    /**\n       Pausing and continuing transfers.\n    */\n    void pause(bool sendingPaused, bool receivingPaused)\n    {\n        throwOnStopped();\n        _check(curl.easy_pause(this.handle,\n                               (sendingPaused ? CurlPause.send_cont : CurlPause.send) |\n                               (receivingPaused ? CurlPause.recv_cont : CurlPause.recv)));\n    }\n\n    /**\n       Set a string curl option.\n       Params:\n       option = A $(REF CurlOption, etc,c,curl) as found in the curl documentation\n       value = The string\n    */\n    void set(CurlOption option, const(char)[] value)\n    {\n        import std.internal.cstring : tempCString;\n        throwOnStopped();\n        _check(curl.easy_setopt(this.handle, option, value.tempCString().buffPtr));\n    }\n\n    /**\n       Set a long curl option.\n       Params:\n       option = A $(REF CurlOption, etc,c,curl) as found in the curl documentation\n       value = The long\n    */\n    void set(CurlOption option, long value)\n    {\n        throwOnStopped();\n        _check(curl.easy_setopt(this.handle, option, value));\n    }\n\n    /**\n       Set a void* curl option.\n       Params:\n       option = A $(REF CurlOption, etc,c,curl) as found in the curl documentation\n       value = The pointer\n    */\n    void set(CurlOption option, void* value)\n    {\n        throwOnStopped();\n        _check(curl.easy_setopt(this.handle, option, value));\n    }\n\n    /**\n       Clear a pointer option.\n       Params:\n       option = A $(REF CurlOption, etc,c,curl) as found in the curl documentation\n    */\n    void clear(CurlOption option)\n    {\n        throwOnStopped();\n        _check(curl.easy_setopt(this.handle, option, null));\n    }\n\n    /**\n       Clear a pointer option. Does not raise an exception if the underlying\n       libcurl does not support the option. Use sparingly.\n       Params:\n       option = A $(REF CurlOption, etc,c,curl) as found in the curl documentation\n    */\n    void clearIfSupported(CurlOption option)\n    {\n        throwOnStopped();\n        auto rval = curl.easy_setopt(this.handle, option, null);\n        if (rval != CurlError.unknown_option && rval != CurlError.not_built_in)\n            _check(rval);\n    }\n\n    /**\n       perform the curl request by doing the HTTP,FTP etc. as it has\n       been setup beforehand.\n\n       Params:\n       throwOnError = whether to throw an exception or return a CurlCode on error\n    */\n    CurlCode perform(ThrowOnError throwOnError = Yes.throwOnError)\n    {\n        throwOnStopped();\n        CurlCode code = curl.easy_perform(this.handle);\n        if (throwOnError)\n            _check(code);\n        return code;\n    }\n\n    /**\n       Get the various timings like name lookup time, total time, connect time etc.\n       The timed category is passed through the timing parameter while the timing\n       value is stored at val. The value is usable only if res is equal to\n       `etc.c.curl.CurlError.ok`.\n    */\n    CurlCode getTiming(CurlInfo timing, ref double val)\n    {\n        CurlCode code;\n        code = curl.easy_getinfo(handle, timing, &val);\n        return code;\n    }\n\n    /**\n      * The event handler that receives incoming data.\n      *\n      * Params:\n      * callback = the callback that receives the `ubyte[]` data.\n      * Be sure to copy the incoming data and not store\n      * a slice.\n      *\n      * Returns:\n      * The callback returns the incoming bytes read. If not the entire array is\n      * the request will abort.\n      * The special value HTTP.pauseRequest can be returned in order to pause the\n      * current request.\n      *\n      * Example:\n      * ----\n      * import std.net.curl, std.stdio;\n      * Curl curl;\n      * curl.initialize();\n      * curl.set(CurlOption.url, \"http://dlang.org\");\n      * curl.onReceive = (ubyte[] data) { writeln(\"Got data\", to!(const(char)[])(data)); return data.length;};\n      * curl.perform();\n      * ----\n      */\n    @property void onReceive(size_t delegate(InData) callback)\n    {\n        _onReceive = (InData id)\n        {\n            throwOnStopped(\"Receive callback called on cleaned up Curl instance\");\n            return callback(id);\n        };\n        set(CurlOption.file, cast(void*) &this);\n        set(CurlOption.writefunction, cast(void*) &Curl._receiveCallback);\n    }\n\n    /**\n      * The event handler that receives incoming headers for protocols\n      * that uses headers.\n      *\n      * Params:\n      * callback = the callback that receives the header string.\n      * Make sure the callback copies the incoming params if\n      * it needs to store it because they are references into\n      * the backend and may very likely change.\n      *\n      * Example:\n      * ----\n      * import std.net.curl, std.stdio;\n      * Curl curl;\n      * curl.initialize();\n      * curl.set(CurlOption.url, \"http://dlang.org\");\n      * curl.onReceiveHeader = (in char[] header) { writeln(header); };\n      * curl.perform();\n      * ----\n      */\n    @property void onReceiveHeader(void delegate(in char[]) callback)\n    {\n        _onReceiveHeader = (in char[] od)\n        {\n            throwOnStopped(\"Receive header callback called on \"~\n                           \"cleaned up Curl instance\");\n            callback(od);\n        };\n        set(CurlOption.writeheader, cast(void*) &this);\n        set(CurlOption.headerfunction,\n            cast(void*) &Curl._receiveHeaderCallback);\n    }\n\n    /**\n      * The event handler that gets called when data is needed for sending.\n      *\n      * Params:\n      * callback = the callback that has a `void[]` buffer to be filled\n      *\n      * Returns:\n      * The callback returns the number of elements in the buffer that have been\n      * filled and are ready to send.\n      * The special value `Curl.abortRequest` can be returned in\n      * order to abort the current request.\n      * The special value `Curl.pauseRequest` can be returned in order to\n      * pause the current request.\n      *\n      * Example:\n      * ----\n      * import std.net.curl;\n      * Curl curl;\n      * curl.initialize();\n      * curl.set(CurlOption.url, \"http://dlang.org\");\n      *\n      * string msg = \"Hello world\";\n      * curl.onSend = (void[] data)\n      * {\n      *     auto m = cast(void[]) msg;\n      *     size_t length = m.length > data.length ? data.length : m.length;\n      *     if (length == 0) return 0;\n      *     data[0 .. length] = m[0 .. length];\n      *     msg = msg[length..$];\n      *     return length;\n      * };\n      * curl.perform();\n      * ----\n      */\n    @property void onSend(size_t delegate(OutData) callback)\n    {\n        _onSend = (OutData od)\n        {\n            throwOnStopped(\"Send callback called on cleaned up Curl instance\");\n            return callback(od);\n        };\n        set(CurlOption.infile, cast(void*) &this);\n        set(CurlOption.readfunction, cast(void*) &Curl._sendCallback);\n    }\n\n    /**\n      * The event handler that gets called when the curl backend needs to seek\n      * the data to be sent.\n      *\n      * Params:\n      * callback = the callback that receives a seek offset and a seek position\n      *            $(REF CurlSeekPos, etc,c,curl)\n      *\n      * Returns:\n      * The callback returns the success state of the seeking\n      * $(REF CurlSeek, etc,c,curl)\n      *\n      * Example:\n      * ----\n      * import std.net.curl;\n      * Curl curl;\n      * curl.initialize();\n      * curl.set(CurlOption.url, \"http://dlang.org\");\n      * curl.onSeek = (long p, CurlSeekPos sp)\n      * {\n      *     return CurlSeek.cantseek;\n      * };\n      * curl.perform();\n      * ----\n      */\n    @property void onSeek(CurlSeek delegate(long, CurlSeekPos) callback)\n    {\n        _onSeek = (long ofs, CurlSeekPos sp)\n        {\n            throwOnStopped(\"Seek callback called on cleaned up Curl instance\");\n            return callback(ofs, sp);\n        };\n        set(CurlOption.seekdata, cast(void*) &this);\n        set(CurlOption.seekfunction, cast(void*) &Curl._seekCallback);\n    }\n\n    /**\n      * The event handler that gets called when the net socket has been created\n      * but a `connect()` call has not yet been done. This makes it possible to set\n      * misc. socket options.\n      *\n      * Params:\n      * callback = the callback that receives the socket and socket type\n      * $(REF CurlSockType, etc,c,curl)\n      *\n      * Returns:\n      * Return 0 from the callback to signal success, return 1 to signal error\n      * and make curl close the socket\n      *\n      * Example:\n      * ----\n      * import std.net.curl;\n      * Curl curl;\n      * curl.initialize();\n      * curl.set(CurlOption.url, \"http://dlang.org\");\n      * curl.onSocketOption = delegate int(curl_socket_t s, CurlSockType t) { /+ do stuff +/ };\n      * curl.perform();\n      * ----\n      */\n    @property void onSocketOption(int delegate(curl_socket_t,\n                                               CurlSockType) callback)\n    {\n        _onSocketOption = (curl_socket_t sock, CurlSockType st)\n        {\n            throwOnStopped(\"Socket option callback called on \"~\n                           \"cleaned up Curl instance\");\n            return callback(sock, st);\n        };\n        set(CurlOption.sockoptdata, cast(void*) &this);\n        set(CurlOption.sockoptfunction,\n            cast(void*) &Curl._socketOptionCallback);\n    }\n\n    /**\n      * The event handler that gets called to inform of upload/download progress.\n      *\n      * Params:\n      * callback = the callback that receives the (total bytes to download,\n      * currently downloaded bytes, total bytes to upload, currently uploaded\n      * bytes).\n      *\n      * Returns:\n      * Return 0 from the callback to signal success, return non-zero to abort\n      * transfer\n      *\n      * Example:\n      * ----\n      * import std.net.curl;\n      * Curl curl;\n      * curl.initialize();\n      * curl.set(CurlOption.url, \"http://dlang.org\");\n      * curl.onProgress = delegate int(size_t dltotal, size_t dlnow, size_t ultotal, size_t uln)\n      * {\n      *     writeln(\"Progress: downloaded bytes \", dlnow, \" of \", dltotal);\n      *     writeln(\"Progress: uploaded bytes \", ulnow, \" of \", ultotal);\n      *     curl.perform();\n      * };\n      * ----\n      */\n    @property void onProgress(int delegate(size_t dlTotal,\n                                           size_t dlNow,\n                                           size_t ulTotal,\n                                           size_t ulNow) callback)\n    {\n        _onProgress = (size_t dlt, size_t dln, size_t ult, size_t uln)\n        {\n            throwOnStopped(\"Progress callback called on cleaned \"~\n                           \"up Curl instance\");\n            return callback(dlt, dln, ult, uln);\n        };\n        set(CurlOption.noprogress, 0);\n        set(CurlOption.progressdata, cast(void*) &this);\n        set(CurlOption.progressfunction, cast(void*) &Curl._progressCallback);\n    }\n\n    // Internal C callbacks to register with libcurl\n    extern (C) private static\n    size_t _receiveCallback(const char* str,\n                            size_t size, size_t nmemb, void* ptr)\n    {\n        auto b = cast(Curl*) ptr;\n        if (b._onReceive != null)\n            return b._onReceive(cast(InData)(str[0 .. size*nmemb]));\n        return size*nmemb;\n    }\n\n    extern (C) private static\n    size_t _receiveHeaderCallback(const char* str,\n                                  size_t size, size_t nmemb, void* ptr)\n    {\n        import std.string : chomp;\n\n        auto b = cast(Curl*) ptr;\n        auto s = str[0 .. size*nmemb].chomp();\n        if (b._onReceiveHeader != null)\n            b._onReceiveHeader(s);\n\n        return size*nmemb;\n    }\n\n    extern (C) private static\n    size_t _sendCallback(char *str, size_t size, size_t nmemb, void *ptr)\n    {\n        Curl* b = cast(Curl*) ptr;\n        auto a = cast(void[]) str[0 .. size*nmemb];\n        if (b._onSend == null)\n            return 0;\n        return b._onSend(a);\n    }\n\n    extern (C) private static\n    int _seekCallback(void *ptr, curl_off_t offset, int origin)\n    {\n        auto b = cast(Curl*) ptr;\n        if (b._onSeek == null)\n            return CurlSeek.cantseek;\n\n        // origin: CurlSeekPos.set/current/end\n        // return: CurlSeek.ok/fail/cantseek\n        return b._onSeek(cast(long) offset, cast(CurlSeekPos) origin);\n    }\n\n    extern (C) private static\n    int _socketOptionCallback(void *ptr,\n                              curl_socket_t curlfd, curlsocktype purpose)\n    {\n        auto b = cast(Curl*) ptr;\n        if (b._onSocketOption == null)\n            return 0;\n\n        // return: 0 ok, 1 fail\n        return b._onSocketOption(curlfd, cast(CurlSockType) purpose);\n    }\n\n    extern (C) private static\n    int _progressCallback(void *ptr,\n                          double dltotal, double dlnow,\n                          double ultotal, double ulnow)\n    {\n        auto b = cast(Curl*) ptr;\n        if (b._onProgress == null)\n            return 0;\n\n        // return: 0 ok, 1 fail\n        return b._onProgress(cast(size_t) dltotal, cast(size_t) dlnow,\n                             cast(size_t) ultotal, cast(size_t) ulnow);\n    }\n\n}\n\n// Internal messages send between threads.\n// The data is wrapped in this struct in order to ensure that\n// other std.concurrency.receive calls does not pick up our messages\n// by accident.\nprivate struct CurlMessage(T)\n{\n    public T data;\n}\n\nprivate static CurlMessage!T curlMessage(T)(T data)\n{\n    return CurlMessage!T(data);\n}\n\n// Pool of to be used for reusing buffers\nprivate struct Pool(Data)\n{\n    private struct Entry\n    {\n        Data data;\n        Entry* next;\n    }\n    private Entry*  root;\n    private Entry* freeList;\n\n    @safe @property bool empty()\n    {\n        return root == null;\n    }\n\n    @safe nothrow void push(Data d)\n    {\n        if (freeList == null)\n        {\n            // Allocate new Entry since there is no one\n            // available in the freeList\n            freeList = new Entry;\n        }\n        freeList.data = d;\n        Entry* oldroot = root;\n        root = freeList;\n        freeList = freeList.next;\n        root.next = oldroot;\n    }\n\n    @safe Data pop()\n    {\n        import std.exception : enforce;\n        enforce!Exception(root != null, \"pop() called on empty pool\");\n        auto d = root.data;\n        auto n = root.next;\n        root.next = freeList;\n        freeList = root;\n        root = n;\n        return d;\n    }\n}\n\n// Lazily-instantiated namespace to avoid importing std.concurrency until needed.\nprivate struct _async()\n{\nstatic:\n    // @@@@BUG 15831@@@@\n    // this should be inside byLineAsync\n    // Range that reads one chunk at a time asynchronously.\n    private struct ChunkInputRange\n    {\n        import std.concurrency : Tid, send;\n\n        private ubyte[] chunk;\n        mixin WorkerThreadProtocol!(ubyte, chunk);\n\n        private Tid workerTid;\n        private State running;\n\n        private this(Tid tid, size_t transmitBuffers, size_t chunkSize)\n        {\n            workerTid = tid;\n            state = State.needUnits;\n\n            // Send buffers to other thread for it to use.  Since no mechanism is in\n            // place for moving ownership a cast to shared is done here and a cast\n            // back to non-shared in the receiving end.\n            foreach (i ; 0 .. transmitBuffers)\n            {\n                ubyte[] arr = new ubyte[](chunkSize);\n                workerTid.send(cast(immutable(ubyte[]))arr);\n            }\n        }\n    }\n\n    // @@@@BUG 15831@@@@\n    // this should be inside byLineAsync\n    // Range that reads one line at a time asynchronously.\n    private static struct LineInputRange(Char)\n    {\n        private Char[] line;\n        mixin WorkerThreadProtocol!(Char, line);\n\n        private Tid workerTid;\n        private State running;\n\n        private this(Tid tid, size_t transmitBuffers, size_t bufferSize)\n        {\n            import std.concurrency : send;\n\n            workerTid = tid;\n            state = State.needUnits;\n\n            // Send buffers to other thread for it to use.  Since no mechanism is in\n            // place for moving ownership a cast to shared is done here and casted\n            // back to non-shared in the receiving end.\n            foreach (i ; 0 .. transmitBuffers)\n            {\n                auto arr = new Char[](bufferSize);\n                workerTid.send(cast(immutable(Char[]))arr);\n            }\n        }\n    }\n\n    import std.concurrency : Tid;\n\n    // Shared function for reading incoming chunks of data and\n    // sending the to a parent thread\n    private size_t receiveChunks(ubyte[] data, ref ubyte[] outdata,\n                                 Pool!(ubyte[]) freeBuffers,\n                                 ref ubyte[] buffer, Tid fromTid,\n                                 ref bool aborted)\n    {\n        import std.concurrency : receive, send, thisTid;\n\n        immutable datalen = data.length;\n\n        // Copy data to fill active buffer\n        while (!data.empty)\n        {\n\n            // Make sure a buffer is present\n            while ( outdata.empty && freeBuffers.empty)\n            {\n                // Active buffer is invalid and there are no\n                // available buffers in the pool. Wait for buffers\n                // to return from main thread in order to reuse\n                // them.\n                receive((immutable(ubyte)[] buf)\n                        {\n                            buffer = cast(ubyte[]) buf;\n                            outdata = buffer[];\n                        },\n                        (bool flag) { aborted = true; }\n                        );\n                if (aborted) return cast(size_t) 0;\n            }\n            if (outdata.empty)\n            {\n                buffer = freeBuffers.pop();\n                outdata = buffer[];\n            }\n\n            // Copy data\n            auto copyBytes = outdata.length < data.length ?\n                outdata.length : data.length;\n\n            outdata[0 .. copyBytes] = data[0 .. copyBytes];\n            outdata = outdata[copyBytes..$];\n            data = data[copyBytes..$];\n\n            if (outdata.empty)\n                fromTid.send(thisTid, curlMessage(cast(immutable(ubyte)[])buffer));\n        }\n\n        return datalen;\n    }\n\n    // ditto\n    private void finalizeChunks(ubyte[] outdata, ref ubyte[] buffer,\n                                Tid fromTid)\n    {\n        import std.concurrency : send, thisTid;\n        if (!outdata.empty)\n        {\n            // Resize the last buffer\n            buffer.length = buffer.length - outdata.length;\n            fromTid.send(thisTid, curlMessage(cast(immutable(ubyte)[])buffer));\n        }\n    }\n\n\n    // Shared function for reading incoming lines of data and sending the to a\n    // parent thread\n    private static size_t receiveLines(Terminator, Unit)\n        (const(ubyte)[] data, ref EncodingScheme encodingScheme,\n         bool keepTerminator, Terminator terminator,\n         ref const(ubyte)[] leftOverBytes, ref bool bufferValid,\n         ref Pool!(Unit[]) freeBuffers, ref Unit[] buffer,\n         Tid fromTid, ref bool aborted)\n    {\n        import std.concurrency : prioritySend, receive, send, thisTid;\n        import std.exception : enforce;\n        import std.format : format;\n        import std.traits : isArray;\n\n        immutable datalen = data.length;\n\n        // Terminator is specified and buffers should be resized as determined by\n        // the terminator\n\n        // Copy data to active buffer until terminator is found.\n\n        // Decode as many lines as possible\n        while (true)\n        {\n\n            // Make sure a buffer is present\n            while (!bufferValid && freeBuffers.empty)\n            {\n                // Active buffer is invalid and there are no available buffers in\n                // the pool. Wait for buffers to return from main thread in order to\n                // reuse them.\n                receive((immutable(Unit)[] buf)\n                        {\n                            buffer = cast(Unit[]) buf;\n                            buffer.length = 0;\n                            buffer.assumeSafeAppend();\n                            bufferValid = true;\n                        },\n                        (bool flag) { aborted = true; }\n                        );\n                if (aborted) return cast(size_t) 0;\n            }\n            if (!bufferValid)\n            {\n                buffer = freeBuffers.pop();\n                bufferValid = true;\n            }\n\n            // Try to read a line from left over bytes from last onReceive plus the\n            // newly received bytes.\n            try\n            {\n                if (decodeLineInto(leftOverBytes, data, buffer,\n                                   encodingScheme, terminator))\n                {\n                    if (keepTerminator)\n                    {\n                        fromTid.send(thisTid,\n                                     curlMessage(cast(immutable(Unit)[])buffer));\n                    }\n                    else\n                    {\n                        static if (isArray!Terminator)\n                            fromTid.send(thisTid,\n                                         curlMessage(cast(immutable(Unit)[])\n                                                 buffer[0..$-terminator.length]));\n                        else\n                            fromTid.send(thisTid,\n                                         curlMessage(cast(immutable(Unit)[])\n                                                 buffer[0..$-1]));\n                    }\n                    bufferValid = false;\n                }\n                else\n                {\n                    // Could not decode an entire line. Save\n                    // bytes left in data for next call to\n                    // onReceive. Can be up to a max of 4 bytes.\n                    enforce!CurlException(data.length <= 4,\n                                            format(\n                                            \"Too many bytes left not decoded %s\"~\n                                            \" > 4. Maybe the charset specified in\"~\n                                            \" headers does not match \"~\n                                            \"the actual content downloaded?\",\n                                            data.length));\n                    leftOverBytes ~= data;\n                    break;\n                }\n            }\n            catch (CurlException ex)\n            {\n                prioritySend(fromTid, cast(immutable(CurlException))ex);\n                return cast(size_t) 0;\n            }\n        }\n        return datalen;\n    }\n\n    // ditto\n    private static\n    void finalizeLines(Unit)(bool bufferValid, Unit[] buffer, Tid fromTid)\n    {\n        import std.concurrency : send, thisTid;\n        if (bufferValid && buffer.length != 0)\n            fromTid.send(thisTid, curlMessage(cast(immutable(Unit)[])buffer[0..$]));\n    }\n\n    /* Used by byLineAsync/byChunkAsync to duplicate an existing connection\n     * that can be used exclusively in a spawned thread.\n     */\n    private void duplicateConnection(Conn, PostData)\n        (const(char)[] url, Conn conn, PostData postData, Tid tid)\n    {\n        import std.concurrency : send;\n        import std.exception : enforce;\n\n        // no move semantic available in std.concurrency ie. must use casting.\n        auto connDup = conn.dup();\n        connDup.url = url;\n\n        static if ( is(Conn : HTTP) )\n        {\n            connDup.p.headersOut = null;\n            connDup.method = conn.method == HTTP.Method.undefined ?\n                HTTP.Method.get : conn.method;\n            if (postData !is null)\n            {\n                if (connDup.method == HTTP.Method.put)\n                {\n                    connDup.handle.set(CurlOption.infilesize_large,\n                                       postData.length);\n                }\n                else\n                {\n                    // post\n                    connDup.method = HTTP.Method.post;\n                    connDup.handle.set(CurlOption.postfieldsize_large,\n                                       postData.length);\n                }\n                connDup.handle.set(CurlOption.copypostfields,\n                                   cast(void*) postData.ptr);\n            }\n            tid.send(cast(ulong) connDup.handle.handle);\n            tid.send(connDup.method);\n        }\n        else\n        {\n            enforce!CurlException(postData is null,\n                                    \"Cannot put ftp data using byLineAsync()\");\n            tid.send(cast(ulong) connDup.handle.handle);\n            tid.send(HTTP.Method.undefined);\n        }\n        connDup.p.curl.handle = null; // make sure handle is not freed\n    }\n\n    // Spawn a thread for handling the reading of incoming data in the\n    // background while the delegate is executing.  This will optimize\n    // throughput by allowing simultaneous input (this struct) and\n    // output (e.g. AsyncHTTPLineOutputRange).\n    private static void spawn(Conn, Unit, Terminator = void)()\n    {\n        import std.concurrency : Tid, prioritySend, receiveOnly, send, thisTid;\n        import etc.c.curl : CURL, CurlError;\n        Tid fromTid = receiveOnly!Tid();\n\n        // Get buffer to read into\n        Pool!(Unit[]) freeBuffers;  // Free list of buffer objects\n\n        // Number of bytes filled into active buffer\n        Unit[] buffer;\n        bool aborted = false;\n\n        EncodingScheme encodingScheme;\n        static if ( !is(Terminator == void))\n        {\n            // Only lines reading will receive a terminator\n            const terminator = receiveOnly!Terminator();\n            const keepTerminator = receiveOnly!bool();\n\n            // max number of bytes to carry over from an onReceive\n            // callback. This is 4 because it is the max code units to\n            // decode a code point in the supported encodings.\n            auto leftOverBytes =  new const(ubyte)[4];\n            leftOverBytes.length = 0;\n            auto bufferValid = false;\n        }\n        else\n        {\n            Unit[] outdata;\n        }\n\n        // no move semantic available in std.concurrency ie. must use casting.\n        auto connDup = cast(CURL*) receiveOnly!ulong();\n        auto client = Conn();\n        client.p.curl.handle = connDup;\n\n        // receive a method for both ftp and http but just use it for http\n        auto method = receiveOnly!(HTTP.Method)();\n\n        client.onReceive = (ubyte[] data)\n        {\n            // If no terminator is specified the chunk size is fixed.\n            static if ( is(Terminator == void) )\n                return receiveChunks(data, outdata, freeBuffers, buffer,\n                                     fromTid, aborted);\n            else\n                return receiveLines(data, encodingScheme,\n                                    keepTerminator, terminator, leftOverBytes,\n                                    bufferValid, freeBuffers, buffer,\n                                    fromTid, aborted);\n        };\n\n        static if ( is(Conn == HTTP) )\n        {\n            client.method = method;\n            // register dummy header handler\n            client.onReceiveHeader = (in char[] key, in char[] value)\n            {\n                if (key == \"content-type\")\n                    encodingScheme = EncodingScheme.create(client.p.charset);\n            };\n        }\n        else\n        {\n            encodingScheme = EncodingScheme.create(client.encoding);\n        }\n\n        // Start the request\n        CurlCode code;\n        try\n        {\n            code = client.perform(No.throwOnError);\n        }\n        catch (Exception ex)\n        {\n            prioritySend(fromTid, cast(immutable(Exception)) ex);\n            fromTid.send(thisTid, curlMessage(true)); // signal done\n            return;\n        }\n\n        if (code != CurlError.ok)\n        {\n            if (aborted && (code == CurlError.aborted_by_callback ||\n                            code == CurlError.write_error))\n            {\n                fromTid.send(thisTid, curlMessage(true)); // signal done\n                return;\n            }\n            prioritySend(fromTid, cast(immutable(CurlException))\n                         new CurlException(client.p.curl.errorString(code)));\n\n            fromTid.send(thisTid, curlMessage(true)); // signal done\n            return;\n        }\n\n        // Send remaining data that is not a full chunk size\n        static if ( is(Terminator == void) )\n            finalizeChunks(outdata, buffer, fromTid);\n        else\n            finalizeLines(bufferValid, buffer, fromTid);\n\n        fromTid.send(thisTid, curlMessage(true)); // signal done\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/net/isemail.d",
    "content": "/**\n * Validates an email address according to RFCs 5321, 5322 and others.\n *\n * Authors: Dominic Sayers $(LT)dominic@sayers.cc$(GT), Jacob Carlborg\n * Copyright: Dominic Sayers, Jacob Carlborg 2008-.\n * Test schema documentation: Copyright © 2011, Daniel Marschall\n * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)\n * Dominic Sayers graciously granted permission to use the Boost license via email on Feb 22, 2011.\n * Version: 3.0.13 - Version 3.0 of the original PHP implementation: $(LINK http://www.dominicsayers.com/isemail)\n *\n * Standards:\n *         $(UL\n *             $(LI RFC 5321)\n *             $(LI RFC 5322)\n *          )\n *\n * References:\n *         $(UL\n *             $(LI $(LINK http://www.dominicsayers.com/isemail))\n *             $(LI $(LINK http://tools.ietf.org/html/rfc5321))\n *             $(LI $(LINK http://tools.ietf.org/html/rfc5322))\n *          )\n *\n * Source: $(PHOBOSSRC std/net/isemail.d)\n */\nmodule std.net.isemail;\n\n// FIXME\nimport std.range.primitives; // : ElementType;\nimport std.traits;\nimport std.typecons : Flag, Yes, No;\n\n/**\n * Check that an email address conforms to RFCs 5321, 5322 and others.\n *\n * Distinguishes between a Mailbox as defined  by RFC 5321 and an addr-spec as\n * defined by RFC 5322. Depending on the context, either can be regarded as a\n * valid email address.\n *\n * Note: The DNS check is currently not implemented.\n *\n * Params:\n *     email = The email address to check\n *     checkDNS = If `Yes.checkDns` then a DNS check for MX records will be made\n *     errorLevel = Determines the boundary between valid and invalid addresses.\n *                  Status codes above this number will be returned as-is,\n *                  status codes below will be returned as EmailStatusCode.valid.\n *                  Thus the calling program can simply look for EmailStatusCode.valid\n *                  if it is only interested in whether an address is valid or not. The\n *                  $(D_PARAM errorLevel) will determine how \"picky\" isEmail() is about\n *                  the address.\n *\n *                  If omitted or passed as EmailStatusCode.none then isEmail() will\n *                  not perform any finer grained error checking and an address is\n *                  either considered valid or not. Email status code will either be\n *                  EmailStatusCode.valid or EmailStatusCode.error.\n *\n * Returns:\n *     An $(LREF EmailStatus), indicating the status of the email address.\n */\nEmailStatus isEmail(Char)(const(Char)[] email, CheckDns checkDNS = No.checkDns,\nEmailStatusCode errorLevel = EmailStatusCode.none)\nif (isSomeChar!(Char))\n{\n    import std.algorithm.iteration : uniq, filter, map;\n    import std.algorithm.searching : canFind, maxElement;\n    import std.array : array, split;\n    import std.conv : to;\n    import std.exception : enforce;\n    import std.string : indexOf, lastIndexOf;\n    import std.uni : isNumber;\n\n    alias tstring = const(Char)[];\n    alias Token = TokenImpl!(Char);\n\n    enum defaultThreshold = 16;\n    int threshold;\n    bool diagnose;\n\n    if (errorLevel == EmailStatusCode.any)\n    {\n        threshold = EmailStatusCode.valid;\n        diagnose = true;\n    }\n\n    else if (errorLevel == EmailStatusCode.none)\n        threshold = defaultThreshold;\n\n    else\n    {\n        diagnose = true;\n\n        switch (errorLevel)\n        {\n            case EmailStatusCode.warning: threshold = defaultThreshold; break;\n            case EmailStatusCode.error: threshold = EmailStatusCode.valid; break;\n            default: threshold = errorLevel;\n        }\n    }\n\n    auto returnStatus = [EmailStatusCode.valid];\n    auto context = EmailPart.componentLocalPart;\n    auto contextStack = [context];\n    auto contextPrior = context;\n    tstring token = \"\";\n    tstring tokenPrior = \"\";\n    tstring[EmailPart] parseData = [EmailPart.componentLocalPart : \"\", EmailPart.componentDomain : \"\"];\n    tstring[][EmailPart] atomList = [EmailPart.componentLocalPart : [\"\"], EmailPart.componentDomain : [\"\"]];\n    auto elementCount = 0;\n    auto elementLength = 0;\n    auto hyphenFlag = false;\n    auto endOrDie = false;\n    auto crlfCount = int.min; // int.min == not defined\n\n    foreach (ref i, e ; email)\n    {\n        token = email.get(i, e);\n\n        switch (context)\n        {\n            case EmailPart.componentLocalPart:\n                switch (token)\n                {\n                    case Token.openParenthesis:\n                        if (elementLength == 0)\n                            returnStatus ~= elementCount == 0 ? EmailStatusCode.comment :\n                                EmailStatusCode.deprecatedComment;\n\n                        else\n                        {\n                            returnStatus ~= EmailStatusCode.comment;\n                            endOrDie = true;\n                        }\n\n                        contextStack ~= context;\n                        context = EmailPart.contextComment;\n                    break;\n\n                    case Token.dot:\n                        if (elementLength == 0)\n                            returnStatus ~= elementCount == 0 ? EmailStatusCode.errorDotStart :\n                                EmailStatusCode.errorConsecutiveDots;\n\n                        else\n                        {\n                            if (endOrDie)\n                                returnStatus ~= EmailStatusCode.deprecatedLocalPart;\n                        }\n\n                        endOrDie = false;\n                        elementLength = 0;\n                        elementCount++;\n                        parseData[EmailPart.componentLocalPart] ~= token;\n\n                        if (elementCount >= atomList[EmailPart.componentLocalPart].length)\n                            atomList[EmailPart.componentLocalPart] ~= \"\";\n\n                        else\n                            atomList[EmailPart.componentLocalPart][elementCount] = \"\";\n                    break;\n\n                    case Token.doubleQuote:\n                        if (elementLength == 0)\n                        {\n                            returnStatus ~= elementCount == 0 ? EmailStatusCode.rfc5321QuotedString :\n                                EmailStatusCode.deprecatedLocalPart;\n\n                            parseData[EmailPart.componentLocalPart] ~= token;\n                            atomList[EmailPart.componentLocalPart][elementCount] ~= token;\n                            elementLength++;\n                            endOrDie = true;\n                            contextStack ~= context;\n                            context = EmailPart.contextQuotedString;\n                        }\n\n                        else\n                            returnStatus ~= EmailStatusCode.errorExpectingText;\n                    break;\n\n                    case Token.cr:\n                    case Token.space:\n                    case Token.tab:\n                        if ((token == Token.cr) && ((++i == email.length) || (email.get(i, e) != Token.lf)))\n                        {\n                            returnStatus ~= EmailStatusCode.errorCrNoLf;\n                            break;\n                        }\n\n                        if (elementLength == 0)\n                            returnStatus ~= elementCount == 0 ? EmailStatusCode.foldingWhitespace :\n                                EmailStatusCode.deprecatedFoldingWhitespace;\n\n                        else\n                            endOrDie = true;\n\n                        contextStack ~= context;\n                        context = EmailPart.contextFoldingWhitespace;\n                        tokenPrior = token;\n                    break;\n\n                    case Token.at:\n                        enforce(contextStack.length == 1, \"Unexpected item on context stack\");\n\n                        if (parseData[EmailPart.componentLocalPart] == \"\")\n                            returnStatus ~= EmailStatusCode.errorNoLocalPart;\n\n                        else if (elementLength == 0)\n                            returnStatus ~= EmailStatusCode.errorDotEnd;\n\n                        else if (parseData[EmailPart.componentLocalPart].length > 64)\n                            returnStatus ~= EmailStatusCode.rfc5322LocalTooLong;\n\n                        else if (contextPrior == EmailPart.contextComment ||\n                            contextPrior == EmailPart.contextFoldingWhitespace)\n                                returnStatus ~= EmailStatusCode.deprecatedCommentFoldingWhitespaceNearAt;\n\n                        context = EmailPart.componentDomain;\n                        contextStack = [context];\n                        elementCount = 0;\n                        elementLength = 0;\n                        endOrDie = false;\n                    break;\n\n                    default:\n                        if (endOrDie)\n                        {\n                            switch (contextPrior)\n                            {\n                                case EmailPart.contextComment:\n                                case EmailPart.contextFoldingWhitespace:\n                                    returnStatus ~= EmailStatusCode.errorTextAfterCommentFoldingWhitespace;\n                                break;\n\n                                case EmailPart.contextQuotedString:\n                                    returnStatus ~= EmailStatusCode.errorTextAfterQuotedString;\n                                break;\n\n                                default:\n                                    throw new Exception(\"More text found where none is allowed, but \"\n                                        ~\"unrecognised prior context: \" ~ to!(string)(contextPrior));\n                            }\n                        }\n\n                        else\n                        {\n                            contextPrior = context;\n                            immutable c = token.front;\n\n                            if (c < '!' || c > '~' || c == '\\n' || Token.specials.canFind(token))\n                                returnStatus ~= EmailStatusCode.errorExpectingText;\n\n                            parseData[EmailPart.componentLocalPart] ~= token;\n                            atomList[EmailPart.componentLocalPart][elementCount] ~= token;\n                            elementLength++;\n                        }\n                }\n            break;\n\n            case EmailPart.componentDomain:\n                switch (token)\n                {\n                    case Token.openParenthesis:\n                        if (elementLength == 0)\n                        {\n                            returnStatus ~= elementCount == 0 ?\n                                EmailStatusCode.deprecatedCommentFoldingWhitespaceNearAt\n                                : EmailStatusCode.deprecatedComment;\n                        }\n                        else\n                        {\n                            returnStatus ~= EmailStatusCode.comment;\n                            endOrDie = true;\n                        }\n\n                        contextStack ~= context;\n                        context = EmailPart.contextComment;\n                    break;\n\n                    case Token.dot:\n                        if (elementLength == 0)\n                            returnStatus ~= elementCount == 0 ? EmailStatusCode.errorDotStart :\n                                EmailStatusCode.errorConsecutiveDots;\n\n                        else if (hyphenFlag)\n                            returnStatus ~= EmailStatusCode.errorDomainHyphenEnd;\n\n                        else\n                        {\n                            if (elementLength > 63)\n                                returnStatus ~= EmailStatusCode.rfc5322LabelTooLong;\n                        }\n\n                        endOrDie = false;\n                        elementLength = 0;\n                        elementCount++;\n\n                        //atomList[EmailPart.componentDomain][elementCount] = \"\";\n                        atomList[EmailPart.componentDomain] ~= \"\";\n                        parseData[EmailPart.componentDomain] ~= token;\n                    break;\n\n                    case Token.openBracket:\n                        if (parseData[EmailPart.componentDomain] == \"\")\n                        {\n                            endOrDie = true;\n                            elementLength++;\n                            contextStack ~= context;\n                            context = EmailPart.componentLiteral;\n                            parseData[EmailPart.componentDomain] ~= token;\n                            atomList[EmailPart.componentDomain][elementCount] ~= token;\n                            parseData[EmailPart.componentLiteral] = \"\";\n                        }\n\n                        else\n                            returnStatus ~= EmailStatusCode.errorExpectingText;\n                    break;\n\n                    case Token.cr:\n                    case Token.space:\n                    case Token.tab:\n                        if (token == Token.cr && (++i == email.length || email.get(i, e) != Token.lf))\n                        {\n                            returnStatus ~= EmailStatusCode.errorCrNoLf;\n                            break;\n                        }\n\n                        if (elementLength == 0)\n                        {\n                            returnStatus ~= elementCount == 0 ?\n                                EmailStatusCode.deprecatedCommentFoldingWhitespaceNearAt\n                                : EmailStatusCode.deprecatedFoldingWhitespace;\n                        }\n                        else\n                        {\n                            returnStatus ~= EmailStatusCode.foldingWhitespace;\n                            endOrDie = true;\n                        }\n\n                        contextStack ~= context;\n                        context = EmailPart.contextFoldingWhitespace;\n                        tokenPrior = token;\n                    break;\n\n                    default:\n                        if (endOrDie)\n                        {\n                            switch (contextPrior)\n                            {\n                                case EmailPart.contextComment:\n                                case EmailPart.contextFoldingWhitespace:\n                                    returnStatus ~= EmailStatusCode.errorTextAfterCommentFoldingWhitespace;\n                                break;\n\n                                case EmailPart.componentLiteral:\n                                    returnStatus ~= EmailStatusCode.errorTextAfterDomainLiteral;\n                                break;\n\n                                default:\n                                    throw new Exception(\"More text found where none is allowed, but \"\n                                        ~\"unrecognised prior context: \" ~ to!(string)(contextPrior));\n                            }\n\n                        }\n\n                        immutable c = token.front;\n                        hyphenFlag = false;\n\n                        if (c < '!' || c > '~' || Token.specials.canFind(token))\n                            returnStatus ~= EmailStatusCode.errorExpectingText;\n\n                        else if (token == Token.hyphen)\n                        {\n                            if (elementLength == 0)\n                                returnStatus ~= EmailStatusCode.errorDomainHyphenStart;\n\n                            hyphenFlag = true;\n                        }\n\n                        else if (!((c > '/' && c < ':') || (c > '@' && c < '[') || (c > '`' && c < '{')))\n                            returnStatus ~= EmailStatusCode.rfc5322Domain;\n\n                        parseData[EmailPart.componentDomain] ~= token;\n                        atomList[EmailPart.componentDomain][elementCount] ~= token;\n                        elementLength++;\n                }\n            break;\n\n            case EmailPart.componentLiteral:\n                switch (token)\n                {\n                    case Token.closeBracket:\n                        if (returnStatus.maxElement() < EmailStatusCode.deprecated_)\n                        {\n                            auto maxGroups = 8;\n                            size_t index = -1;\n                            auto addressLiteral = parseData[EmailPart.componentLiteral];\n                            const(Char)[] ipSuffix = matchIPSuffix(addressLiteral);\n\n                            if (ipSuffix.length)\n                            {\n                                index = addressLiteral.length - ipSuffix.length;\n                                if (index != 0)\n                                    addressLiteral = addressLiteral[0 .. index] ~ \"0:0\";\n                            }\n\n                            if (index == 0)\n                                returnStatus ~= EmailStatusCode.rfc5321AddressLiteral;\n\n                            else if (addressLiteral.compareFirstN(Token.ipV6Tag, 5))\n                                returnStatus ~= EmailStatusCode.rfc5322DomainLiteral;\n\n                            else\n                            {\n                                auto ipV6 = addressLiteral[5 .. $];\n                                auto matchesIp = ipV6.split(Token.colon);\n                                immutable groupCount = matchesIp.length;\n                                index = ipV6.indexOf(Token.doubleColon);\n\n                                if (index == -1)\n                                {\n                                    if (groupCount != maxGroups)\n                                        returnStatus ~= EmailStatusCode.rfc5322IpV6GroupCount;\n                                }\n\n                                else\n                                {\n                                    if (index != ipV6.lastIndexOf(Token.doubleColon))\n                                        returnStatus ~= EmailStatusCode.rfc5322IpV6TooManyDoubleColons;\n\n                                    else\n                                    {\n                                        if (index == 0 || index == (ipV6.length - 2))\n                                            maxGroups++;\n\n                                        if (groupCount > maxGroups)\n                                            returnStatus ~= EmailStatusCode.rfc5322IpV6MaxGroups;\n\n                                        else if (groupCount == maxGroups)\n                                            returnStatus ~= EmailStatusCode.rfc5321IpV6Deprecated;\n                                    }\n                                }\n\n                                if (ipV6[0 .. 1] == Token.colon && ipV6[1 .. 2] != Token.colon)\n                                    returnStatus ~= EmailStatusCode.rfc5322IpV6ColonStart;\n\n                                else if (ipV6[$ - 1 .. $] == Token.colon && ipV6[$ - 2 .. $ - 1] != Token.colon)\n                                    returnStatus ~= EmailStatusCode.rfc5322IpV6ColonEnd;\n\n                                else if (!matchesIp\n                                        .filter!(a => !isUpToFourHexChars(a))\n                                        .empty)\n                                    returnStatus ~= EmailStatusCode.rfc5322IpV6BadChar;\n\n                                else\n                                    returnStatus ~= EmailStatusCode.rfc5321AddressLiteral;\n                            }\n                        }\n\n                        else\n                            returnStatus ~= EmailStatusCode.rfc5322DomainLiteral;\n\n                        parseData[EmailPart.componentDomain] ~= token;\n                        atomList[EmailPart.componentDomain][elementCount] ~= token;\n                        elementLength++;\n                        contextPrior = context;\n                        context = contextStack.pop();\n                    break;\n\n                    case Token.backslash:\n                        returnStatus ~= EmailStatusCode.rfc5322DomainLiteralObsoleteText;\n                        contextStack ~= context;\n                        context = EmailPart.contextQuotedPair;\n                    break;\n\n                    case Token.cr:\n                    case Token.space:\n                    case Token.tab:\n                        if (token == Token.cr && (++i == email.length || email.get(i, e) != Token.lf))\n                        {\n                            returnStatus ~= EmailStatusCode.errorCrNoLf;\n                            break;\n                        }\n\n                        returnStatus ~= EmailStatusCode.foldingWhitespace;\n                        contextStack ~= context;\n                        context = EmailPart.contextFoldingWhitespace;\n                        tokenPrior = token;\n                    break;\n\n                    default:\n                        immutable c = token.front;\n\n                        if (c > AsciiToken.delete_ || c == '\\0' || token == Token.openBracket)\n                        {\n                            returnStatus ~= EmailStatusCode.errorExpectingDomainText;\n                            break;\n                        }\n\n                        else if (c < '!' || c == AsciiToken.delete_ )\n                            returnStatus ~= EmailStatusCode.rfc5322DomainLiteralObsoleteText;\n\n                        parseData[EmailPart.componentLiteral] ~= token;\n                        parseData[EmailPart.componentDomain] ~= token;\n                        atomList[EmailPart.componentDomain][elementCount] ~= token;\n                        elementLength++;\n                }\n            break;\n\n            case EmailPart.contextQuotedString:\n                switch (token)\n                {\n                    case Token.backslash:\n                        contextStack ~= context;\n                        context = EmailPart.contextQuotedPair;\n                    break;\n\n                    case Token.cr:\n                    case Token.tab:\n                        if (token == Token.cr && (++i == email.length || email.get(i, e) != Token.lf))\n                        {\n                            returnStatus ~= EmailStatusCode.errorCrNoLf;\n                            break;\n                        }\n\n                        parseData[EmailPart.componentLocalPart] ~= Token.space;\n                        atomList[EmailPart.componentLocalPart][elementCount] ~= Token.space;\n                        elementLength++;\n\n                        returnStatus ~= EmailStatusCode.foldingWhitespace;\n                        contextStack ~= context;\n                        context = EmailPart.contextFoldingWhitespace;\n                        tokenPrior = token;\n                    break;\n\n                    case Token.doubleQuote:\n                        parseData[EmailPart.componentLocalPart] ~= token;\n                        atomList[EmailPart.componentLocalPart][elementCount] ~= token;\n                        elementLength++;\n                        contextPrior = context;\n                        context = contextStack.pop();\n                    break;\n\n                    default:\n                        immutable c = token.front;\n\n                        if (c > AsciiToken.delete_ || c == '\\0' || c == '\\n')\n                            returnStatus ~= EmailStatusCode.errorExpectingQuotedText;\n\n                        else if (c < ' ' || c == AsciiToken.delete_)\n                            returnStatus ~= EmailStatusCode.deprecatedQuotedText;\n\n                        parseData[EmailPart.componentLocalPart] ~= token;\n                        atomList[EmailPart.componentLocalPart][elementCount] ~= token;\n                        elementLength++;\n                }\n            break;\n\n            case EmailPart.contextQuotedPair:\n                immutable c = token.front;\n\n                if (c > AsciiToken.delete_)\n                    returnStatus ~= EmailStatusCode.errorExpectingQuotedPair;\n\n                else if (c < AsciiToken.unitSeparator && c != AsciiToken.horizontalTab || c == AsciiToken.delete_)\n                    returnStatus ~= EmailStatusCode.deprecatedQuotedPair;\n\n                contextPrior = context;\n                context = contextStack.pop();\n                token = Token.backslash ~ token;\n\n                switch (context)\n                {\n                    case EmailPart.contextComment: break;\n\n                    case EmailPart.contextQuotedString:\n                        parseData[EmailPart.componentLocalPart] ~= token;\n                        atomList[EmailPart.componentLocalPart][elementCount] ~= token;\n                        elementLength += 2;\n                    break;\n\n                    case EmailPart.componentLiteral:\n                        parseData[EmailPart.componentDomain] ~= token;\n                        atomList[EmailPart.componentDomain][elementCount] ~= token;\n                        elementLength += 2;\n                    break;\n\n                    default:\n                        throw new Exception(\"Quoted pair logic invoked in an invalid context: \" ~ to!(string)(context));\n                }\n            break;\n\n            case EmailPart.contextComment:\n                switch (token)\n                {\n                    case Token.openParenthesis:\n                        contextStack ~= context;\n                        context = EmailPart.contextComment;\n                    break;\n\n                    case Token.closeParenthesis:\n                        contextPrior = context;\n                        context = contextStack.pop();\n                    break;\n\n                    case Token.backslash:\n                        contextStack ~= context;\n                        context = EmailPart.contextQuotedPair;\n                    break;\n\n                    case Token.cr:\n                    case Token.space:\n                    case Token.tab:\n                        if (token == Token.cr && (++i == email.length || email.get(i, e) != Token.lf))\n                        {\n                            returnStatus ~= EmailStatusCode.errorCrNoLf;\n                            break;\n                        }\n\n                        returnStatus ~= EmailStatusCode.foldingWhitespace;\n\n                        contextStack ~= context;\n                        context = EmailPart.contextFoldingWhitespace;\n                        tokenPrior = token;\n                    break;\n\n                    default:\n                        immutable c = token.front;\n\n                        if (c > AsciiToken.delete_ || c == '\\0' || c == '\\n')\n                        {\n                            returnStatus ~= EmailStatusCode.errorExpectingCommentText;\n                            break;\n                        }\n\n                        else if (c < ' ' || c == AsciiToken.delete_)\n                            returnStatus ~= EmailStatusCode.deprecatedCommentText;\n                }\n            break;\n\n            case EmailPart.contextFoldingWhitespace:\n                if (tokenPrior == Token.cr)\n                {\n                    if (token == Token.cr)\n                    {\n                        returnStatus ~= EmailStatusCode.errorFoldingWhitespaceCrflX2;\n                        break;\n                    }\n\n                    if (crlfCount != int.min) // int.min == not defined\n                    {\n                        if (++crlfCount > 1)\n                            returnStatus ~= EmailStatusCode.deprecatedFoldingWhitespace;\n                    }\n\n                    else\n                        crlfCount = 1;\n                }\n\n                switch (token)\n                {\n                    case Token.cr:\n                        if (++i == email.length || email.get(i, e) != Token.lf)\n                            returnStatus ~= EmailStatusCode.errorCrNoLf;\n                    break;\n\n                    case Token.space:\n                    case Token.tab:\n                    break;\n\n                    default:\n                        if (tokenPrior == Token.cr)\n                        {\n                            returnStatus ~= EmailStatusCode.errorFoldingWhitespaceCrLfEnd;\n                            break;\n                        }\n\n                        crlfCount = int.min; // int.min == not defined\n                        contextPrior = context;\n                        context = contextStack.pop();\n                        i--;\n                    break;\n                }\n\n                tokenPrior = token;\n            break;\n\n            default:\n                throw new Exception(\"Unkown context: \" ~ to!(string)(context));\n        }\n\n        if (returnStatus.maxElement() > EmailStatusCode.rfc5322)\n            break;\n    }\n\n    if (returnStatus.maxElement() < EmailStatusCode.rfc5322)\n    {\n        if (context == EmailPart.contextQuotedString)\n            returnStatus ~= EmailStatusCode.errorUnclosedQuotedString;\n\n        else if (context == EmailPart.contextQuotedPair)\n            returnStatus ~= EmailStatusCode.errorBackslashEnd;\n\n        else if (context == EmailPart.contextComment)\n            returnStatus ~= EmailStatusCode.errorUnclosedComment;\n\n        else if (context == EmailPart.componentLiteral)\n            returnStatus ~= EmailStatusCode.errorUnclosedDomainLiteral;\n\n        else if (token == Token.cr)\n            returnStatus ~= EmailStatusCode.errorFoldingWhitespaceCrLfEnd;\n\n        else if (parseData[EmailPart.componentDomain] == \"\")\n            returnStatus ~= EmailStatusCode.errorNoDomain;\n\n        else if (elementLength == 0)\n            returnStatus ~= EmailStatusCode.errorDotEnd;\n\n        else if (hyphenFlag)\n            returnStatus ~= EmailStatusCode.errorDomainHyphenEnd;\n\n        else if (parseData[EmailPart.componentDomain].length > 255)\n            returnStatus ~= EmailStatusCode.rfc5322DomainTooLong;\n\n        else if ((parseData[EmailPart.componentLocalPart] ~ Token.at ~ parseData[EmailPart.componentDomain]).length >\n            254)\n                returnStatus ~= EmailStatusCode.rfc5322TooLong;\n\n        else if (elementLength > 63)\n            returnStatus ~= EmailStatusCode.rfc5322LabelTooLong;\n    }\n\n    auto dnsChecked = false;\n\n    if (checkDNS == Yes.checkDns && returnStatus.maxElement() < EmailStatusCode.dnsWarning)\n    {\n        assert(false, \"DNS check is currently not implemented\");\n    }\n\n    if (!dnsChecked && returnStatus.maxElement() < EmailStatusCode.dnsWarning)\n    {\n        if (elementCount == 0)\n            returnStatus ~= EmailStatusCode.rfc5321TopLevelDomain;\n\n        if (isNumber(atomList[EmailPart.componentDomain][elementCount].front))\n            returnStatus ~= EmailStatusCode.rfc5321TopLevelDomainNumeric;\n    }\n\n    returnStatus = array(uniq(returnStatus));\n    auto finalStatus = returnStatus.maxElement();\n\n    if (returnStatus.length != 1)\n        returnStatus.popFront();\n\n    parseData[EmailPart.status] = to!(tstring)(returnStatus);\n\n    if (finalStatus < threshold)\n        finalStatus = EmailStatusCode.valid;\n\n    if (!diagnose)\n        finalStatus = finalStatus < threshold ? EmailStatusCode.valid : EmailStatusCode.error;\n\n    auto valid = finalStatus == EmailStatusCode.valid;\n    tstring localPart = \"\";\n    tstring domainPart = \"\";\n\n    if (auto value = EmailPart.componentLocalPart in parseData)\n        localPart = *value;\n\n    if (auto value = EmailPart.componentDomain in parseData)\n        domainPart = *value;\n\n    return EmailStatus(valid, to!(string)(localPart), to!(string)(domainPart), finalStatus);\n}\n\n@safe unittest\n{\n    assert(`test.test@iana.org`.isEmail(No.checkDns).statusCode == EmailStatusCode.valid);\n    assert(`test.test@iana.org`.isEmail(No.checkDns, EmailStatusCode.none).statusCode == EmailStatusCode.valid);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555:6666::8888]`.isEmail(No.checkDns,\n        EmailStatusCode.none).statusCode == EmailStatusCode.valid);\n\n    assert(`test`.isEmail(No.checkDns, EmailStatusCode.none).statusCode == EmailStatusCode.error);\n    assert(`(comment)test@iana.org`.isEmail(No.checkDns, EmailStatusCode.none).statusCode == EmailStatusCode.error);\n\n    assert(``.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorNoDomain);\n    assert(`test`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorNoDomain);\n    assert(`@`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorNoLocalPart);\n    assert(`test@`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorNoDomain);\n\n    // assert(`test@io`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid,\n    //     `io. currently has an MX-record (Feb 2011). Some DNS setups seem to find it, some don't.`\n    //     ` If you don't see the MX for io. then try setting your DNS server to 8.8.8.8 (the Google DNS server)`);\n\n    assert(`@io`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorNoLocalPart,\n        `io. currently has an MX-record (Feb 2011)`);\n\n    assert(`@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorNoLocalPart);\n    assert(`test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid);\n    assert(`test@nominet.org.uk`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid);\n    assert(`test@about.museum`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid);\n    assert(`a@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid);\n\n    //assert(`test@e.com`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.dnsWarningNoRecord);\n        // DNS check is currently not implemented\n\n    //assert(`test@iana.a`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.dnsWarningNoRecord);\n        // DNS check is currently not implemented\n\n    assert(`test.test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid);\n    assert(`.test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorDotStart);\n    assert(`test.@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorDotEnd);\n\n    assert(`test .. iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorConsecutiveDots);\n\n    assert(`test_exa-mple.com`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorNoDomain);\n    assert(\"!#$%&`*+/=?^`{|}~@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid);\n\n    assert(`test\\@test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingText);\n\n    assert(`123@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid);\n    assert(`test@123.com`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid);\n\n    assert(`test@iana.123`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5321TopLevelDomainNumeric);\n    assert(`test@255.255.255.255`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5321TopLevelDomainNumeric);\n\n    assert(`abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@iana.org`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.valid);\n\n    assert(`abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklmn@iana.org`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322LocalTooLong);\n\n    // assert(`test@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.com`.isEmail(No.checkDns,\n    //     EmailStatusCode.any).statusCode == EmailStatusCode.dnsWarningNoRecord);\n        // DNS check is currently not implemented\n\n    assert(`test@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm.com`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322LabelTooLong);\n\n    assert(`test@mason-dixon.com`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid);\n\n    assert(`test@-iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorDomainHyphenStart);\n\n    assert(`test@iana-.com`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorDomainHyphenEnd);\n\n    assert(`test@g--a.com`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid);\n\n    //assert(`test@iana.co-uk`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        //EmailStatusCode.dnsWarningNoRecord); // DNS check is currently not implemented\n\n    assert(`test@.iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorDotStart);\n    assert(`test@iana.org.`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorDotEnd);\n    assert(`test@iana .. com`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorConsecutiveDots);\n\n    //assert(`a@a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z`\n    //        `.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z`\n    //        `.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n    //        EmailStatusCode.dnsWarningNoRecord); // DNS check is currently not implemented\n\n    // assert(`abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@abcdefghijklmnopqrstuvwxyz`\n    //         `abcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.`\n    //         `abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi`.isEmail(No.checkDns,\n    //         EmailStatusCode.any).statusCode == EmailStatusCode.dnsWarningNoRecord);\n        // DNS check is currently not implemented\n\n    assert((`abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@abcdefghijklmnopqrstuvwxyz`~\n        `abcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.`~\n        `abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij`).isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322TooLong);\n\n    assert((`a@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyz`~\n        `abcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.`~\n        `abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.hij`).isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322TooLong);\n\n    assert((`a@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyz`~\n        `abcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.`~\n        `abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.hijk`).isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322DomainTooLong);\n\n    assert(`\"test\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5321QuotedString);\n\n    assert(`\"\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.rfc5321QuotedString);\n    assert(`\"\"\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorExpectingText);\n    assert(`\"\\a\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.rfc5321QuotedString);\n    assert(`\"\\\"\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.rfc5321QuotedString);\n\n    assert(`\"\\\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorUnclosedQuotedString);\n\n    assert(`\"\\\\\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.rfc5321QuotedString);\n    assert(`test\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorExpectingText);\n\n    assert(`\"test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorUnclosedQuotedString);\n\n    assert(`\"test\"test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorTextAfterQuotedString);\n\n    assert(`test\"text\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingText);\n\n    assert(`\"test\"\"test\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingText);\n\n    assert(`\"test\".\"test\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedLocalPart);\n\n    assert(`\"test\\ test\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5321QuotedString);\n\n    assert(`\"test\".test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedLocalPart);\n\n    assert(\"\\\"test\\u0000\\\"@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingQuotedText);\n\n    assert(\"\\\"test\\\\\\u0000\\\"@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedQuotedPair);\n\n    assert(`\"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghj\"@iana.org`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322LocalTooLong,\n        `Quotes are still part of the length restriction`);\n\n    assert(`\"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefg\\h\"@iana.org`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322LocalTooLong,\n        `Quoted pair is still part of the length restriction`);\n\n    assert(`test@[255.255.255.255]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5321AddressLiteral);\n\n    assert(`test@a[255.255.255.255]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingText);\n\n    assert(`test@[255.255.255]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322DomainLiteral);\n\n    assert(`test@[255.255.255.255.255]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322DomainLiteral);\n\n    assert(`test@[255.255.255.256]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322DomainLiteral);\n\n    assert(`test@[1111:2222:3333:4444:5555:6666:7777:8888]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322DomainLiteral);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555:6666:7777]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322IpV6GroupCount);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode\n        == EmailStatusCode.rfc5321AddressLiteral);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999]`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322IpV6GroupCount);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555:6666:7777:888G]`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322IpV6BadChar);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555:6666::8888]`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5321IpV6Deprecated);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555::8888]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5321AddressLiteral);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555:6666::7777:8888]`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322IpV6MaxGroups);\n\n    assert(`test@[IPv6::3333:4444:5555:6666:7777:8888]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322IpV6ColonStart);\n\n    assert(`test@[IPv6:::3333:4444:5555:6666:7777:8888]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5321AddressLiteral);\n\n    assert(`test@[IPv6:1111::4444:5555::8888]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322IpV6TooManyDoubleColons);\n\n    assert(`test@[IPv6:::]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5321AddressLiteral);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555:255.255.255.255]`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322IpV6GroupCount);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555:6666:255.255.255.255]`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5321AddressLiteral);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555:6666:7777:255.255.255.255]`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322IpV6GroupCount);\n\n    assert(`test@[IPv6:1111:2222:3333:4444::255.255.255.255]`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5321AddressLiteral);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:5555:6666::255.255.255.255]`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322IpV6MaxGroups);\n\n    assert(`test@[IPv6:1111:2222:3333:4444:::255.255.255.255]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode\n        == EmailStatusCode.rfc5322IpV6TooManyDoubleColons);\n\n    assert(`test@[IPv6::255.255.255.255]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322IpV6ColonStart);\n\n    assert(` test @iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedCommentFoldingWhitespaceNearAt);\n\n    assert(`test@ iana .com`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedCommentFoldingWhitespaceNearAt);\n\n    assert(`test . test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedFoldingWhitespace);\n\n    assert(\"\\u000D\\u000A test@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.foldingWhitespace, `Folding whitespace`);\n\n    assert(\"\\u000D\\u000A \\u000D\\u000A test@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedFoldingWhitespace, `FWS with one line composed entirely of WSP`~\n        ` -- only allowed as obsolete FWS (someone might allow only non-obsolete FWS)`);\n\n    assert(`(comment)test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.comment);\n    assert(`((comment)test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorUnclosedComment);\n\n    assert(`(comment(comment))test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.comment);\n\n    assert(`test@(comment)iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedCommentFoldingWhitespaceNearAt);\n\n    assert(`test(comment)test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorTextAfterCommentFoldingWhitespace);\n\n    assert(`test@(comment)[255.255.255.255]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedCommentFoldingWhitespaceNearAt);\n\n    assert(`(comment)abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@iana.org`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.comment);\n\n    assert(`test@(comment)abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.com`.isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.deprecatedCommentFoldingWhitespaceNearAt);\n\n    assert((`(comment)test@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghik.abcdefghijklmnopqrstuvwxyz`~\n        `abcdefghijklmnopqrstuvwxyzabcdefghik.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.`~\n        `abcdefghijklmnopqrstuvwxyzabcdefghijk.abcdefghijklmnopqrstu`).isEmail(No.checkDns,\n        EmailStatusCode.any).statusCode == EmailStatusCode.comment);\n\n    assert(\"test@iana.org\\u000A\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingText);\n\n    assert(`test@xn--hxajbheg2az3al.xn--jxalpdlp`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.valid, `A valid IDN from ICANN's <a href=\"http://idn.icann.org/#The_example.test_names\">`~\n        `IDN TLD evaluation gateway</a>`);\n\n    assert(`xn--test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.valid,\n        `RFC 3490: \"unless the email standards are revised to invite the use of IDNA for local parts, a domain label`~\n        ` that holds the local part of an email address SHOULD NOT begin with the ACE prefix, and even if it does,`~\n        ` it is to be interpreted literally as a local part that happens to begin with the ACE prefix\"`);\n\n    assert(`test@iana.org-`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorDomainHyphenEnd);\n\n    assert(`\"test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorUnclosedQuotedString);\n\n    assert(`(test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorUnclosedComment);\n\n    assert(`test@(iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorUnclosedComment);\n\n    assert(`test@[1.2.3.4`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorUnclosedDomainLiteral);\n\n    assert(`\"test\\\"@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorUnclosedQuotedString);\n\n    assert(`(comment\\)test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorUnclosedComment);\n\n    assert(`test@iana.org(comment\\)`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorUnclosedComment);\n\n    assert(`test@iana.org(comment\\`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorBackslashEnd);\n\n    assert(`test@[RFC-5322-domain-literal]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322DomainLiteral);\n\n    assert(`test@[RFC-5322]-domain-literal]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorTextAfterDomainLiteral);\n\n    assert(`test@[RFC-5322-[domain-literal]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingDomainText);\n\n    assert(\"test@[RFC-5322-\\\\\\u0007-domain-literal]\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322DomainLiteralObsoleteText, `obs-dtext <strong>and</strong> obs-qp`);\n\n    assert(\"test@[RFC-5322-\\\\\\u0009-domain-literal]\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322DomainLiteralObsoleteText);\n\n    assert(`test@[RFC-5322-\\]-domain-literal]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322DomainLiteralObsoleteText);\n\n    assert(`test@[RFC-5322-domain-literal\\]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorUnclosedDomainLiteral);\n\n    assert(`test@[RFC-5322-domain-literal\\`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorBackslashEnd);\n\n    assert(`test@[RFC 5322 domain literal]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322DomainLiteral, `Spaces are FWS in a domain literal`);\n\n    assert(`test@[RFC-5322-domain-literal] (comment)`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322DomainLiteral);\n\n    assert(\"\\u007F@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingText);\n    assert(\"test@\\u007F.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingText);\n    assert(\"\\\"\\u007F\\\"@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedQuotedText);\n\n    assert(\"\\\"\\\\\\u007F\\\"@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n            EmailStatusCode.deprecatedQuotedPair);\n\n    assert(\"(\\u007F)test@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedCommentText);\n\n    assert(\"test@iana.org\\u000D\".isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorCrNoLf,\n        `No LF after the CR`);\n\n    assert(\"\\u000Dtest@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorCrNoLf,\n        `No LF after the CR`);\n\n    assert(\"\\\"\\u000Dtest\\\"@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorCrNoLf, `No LF after the CR`);\n\n    assert(\"(\\u000D)test@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorCrNoLf,\n        `No LF after the CR`);\n\n    assert(\"(\\u000D\".isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorCrNoLf,\n        `No LF after the CR`);\n\n    assert(\"test@iana.org(\\u000D)\".isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.errorCrNoLf,\n        `No LF after the CR`);\n\n    assert(\"\\u000Atest@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingText);\n\n    assert(\"\\\"\\u000A\\\"@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingQuotedText);\n\n    assert(\"\\\"\\\\\\u000A\\\"@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedQuotedPair);\n\n    assert(\"(\\u000A)test@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingCommentText);\n\n    assert(\"\\u0007@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingText);\n\n    assert(\"test@\\u0007.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingText);\n\n    assert(\"\\\"\\u0007\\\"@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedQuotedText);\n\n    assert(\"\\\"\\\\\\u0007\\\"@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedQuotedPair);\n\n    assert(\"(\\u0007)test@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedCommentText);\n\n    assert(\"\\u000D\\u000Atest@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrLfEnd, `Not FWS because no actual white space`);\n\n    assert(\"\\u000D\\u000A \\u000D\\u000Atest@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrLfEnd, `Not obs-FWS because there must be white space on each \"fold\"`);\n\n    assert(\" \\u000D\\u000Atest@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrLfEnd, `Not FWS because no white space after the fold`);\n\n    assert(\" \\u000D\\u000A test@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.foldingWhitespace, `FWS`);\n\n    assert(\" \\u000D\\u000A \\u000D\\u000Atest@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrLfEnd, `Not FWS because no white space after the second fold`);\n\n    assert(\" \\u000D\\u000A\\u000D\\u000Atest@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrflX2, `Not FWS because no white space after either fold`);\n\n    assert(\" \\u000D\\u000A\\u000D\\u000A test@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrflX2, `Not FWS because no white space after the first fold`);\n\n    assert(\"test@iana.org\\u000D\\u000A \".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.foldingWhitespace, `FWS`);\n\n    assert(\"test@iana.org\\u000D\\u000A \\u000D\\u000A \".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedFoldingWhitespace, `FWS with one line composed entirely of WSP -- `~\n        `only allowed as obsolete FWS (someone might allow only non-obsolete FWS)`);\n\n    assert(\"test@iana.org\\u000D\\u000A\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrLfEnd, `Not FWS because no actual white space`);\n\n    assert(\"test@iana.org\\u000D\\u000A \\u000D\\u000A\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrLfEnd, `Not obs-FWS because there must be white space on each \"fold\"`);\n\n    assert(\"test@iana.org \\u000D\\u000A\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrLfEnd, `Not FWS because no white space after the fold`);\n\n    assert(\"test@iana.org \\u000D\\u000A \".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.foldingWhitespace, `FWS`);\n\n    assert(\"test@iana.org \\u000D\\u000A \\u000D\\u000A\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrLfEnd, `Not FWS because no white space after the second fold`);\n\n    assert(\"test@iana.org \\u000D\\u000A\\u000D\\u000A\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrflX2, `Not FWS because no white space after either fold`);\n\n    assert(\"test@iana.org \\u000D\\u000A\\u000D\\u000A \".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorFoldingWhitespaceCrflX2, `Not FWS because no white space after the first fold`);\n\n    assert(\" test@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.foldingWhitespace);\n    assert(`test@iana.org `.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.foldingWhitespace);\n\n    assert(`test@[IPv6:1::2:]`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.rfc5322IpV6ColonEnd);\n\n    assert(\"\\\"test\\\\\\u00A9\\\"@iana.org\".isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.errorExpectingQuotedPair);\n\n    assert(`test@iana/icann.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.rfc5322Domain);\n\n    assert(`test.(comment)test@iana.org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n        EmailStatusCode.deprecatedComment);\n\n    assert(`test@org`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.rfc5321TopLevelDomain);\n\n    // assert(`test@test.com`.isEmail(No.checkDns, EmailStatusCode.any).statusCode ==\n            //EmailStatusCode.dnsWarningNoMXRecord, `test.com has an A-record but not an MX-record`);\n            // DNS check is currently not implemented\n    //\n    // assert(`test@nic.no`.isEmail(No.checkDns, EmailStatusCode.any).statusCode == EmailStatusCode.dnsWarningNoRecord,\n    //     `nic.no currently has no MX-records or A-records (Feb 2011). If you are seeing an A-record for nic.io then`\n    //       ` try setting your DNS server to 8.8.8.8 (the Google DNS server) - your DNS server may be faking an A-record`\n    //     ` (OpenDNS does this, for instance).`); // DNS check is currently not implemented\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17217\n@safe unittest\n{\n    wstring a = `test.test@iana.org`w;\n    dstring b = `test.test@iana.org`d;\n    const(wchar)[] c = `test.test@iana.org`w;\n    const(dchar)[] d = `test.test@iana.org`d;\n\n    assert(a.isEmail(No.checkDns).statusCode == EmailStatusCode.valid);\n    assert(b.isEmail(No.checkDns).statusCode == EmailStatusCode.valid);\n    assert(c.isEmail(No.checkDns).statusCode == EmailStatusCode.valid);\n    assert(d.isEmail(No.checkDns).statusCode == EmailStatusCode.valid);\n}\n\n/**\n * Flag for indicating if the isEmail function should perform a DNS check or not.\n *\n * If set to `CheckDns.no`, isEmail does not perform DNS checking.\n *\n * Otherwise if set to `CheckDns.yes`, isEmail performs DNS checking.\n */\nalias CheckDns = Flag!\"checkDns\";\n\n/// Represents the status of an email address\nstruct EmailStatus\n{\n    private\n    {\n        bool valid_;\n        string localPart_;\n        string domainPart_;\n        EmailStatusCode statusCode_;\n    }\n\n    /// Self aliases to a `bool` representing if the email is valid or not\n    alias valid this;\n\n    /*\n     * Params:\n     *     valid = indicates if the email address is valid or not\n     *     localPart = the local part of the email address\n     *     domainPart = the domain part of the email address\n     *        statusCode = the status code\n     */\n    private this (bool valid, string localPart, string domainPart, EmailStatusCode statusCode) @safe @nogc pure nothrow\n    {\n        this.valid_ = valid;\n        this.localPart_ = localPart;\n        this.domainPart_ = domainPart;\n        this.statusCode_ = statusCode;\n    }\n\n    /// Returns: If the email address is valid or not.\n    @property bool valid() const @safe @nogc pure nothrow\n    {\n        return valid_;\n    }\n\n    /// Returns: The local part of the email address, that is, the part before the @ sign.\n    @property string localPart() const @safe @nogc pure nothrow\n    {\n        return localPart_;\n    }\n\n    /// Returns: The domain part of the email address, that is, the part after the @ sign.\n    @property string domainPart() const @safe @nogc pure nothrow\n    {\n        return domainPart_;\n    }\n\n    /// Returns: The email status code\n    @property EmailStatusCode statusCode() const @safe @nogc pure nothrow\n    {\n        return statusCode_;\n    }\n\n    /// Returns: A describing string of the status code\n    @property string status() const @safe @nogc pure nothrow\n    {\n        return statusCodeDescription(statusCode_);\n    }\n\n    /// Returns: A textual representation of the email status\n    string toString() const @safe pure\n    {\n        import std.format : format;\n        return format(\"EmailStatus\\n{\\n\\tvalid: %s\\n\\tlocalPart: %s\\n\\tdomainPart: %s\\n\\tstatusCode: %s\\n}\", valid,\n            localPart, domainPart, statusCode);\n    }\n}\n\n/**\n * Params:\n *     statusCode = The $(LREF EmailStatusCode) to read\n * Returns:\n *     A detailed string describing the given status code\n */\nstring statusCodeDescription(EmailStatusCode statusCode) @safe @nogc pure nothrow\n{\n    final switch (statusCode)\n    {\n        // Categories\n        case EmailStatusCode.validCategory: return \"Address is valid\";\n        case EmailStatusCode.dnsWarning: return \"Address is valid but a DNS check was not successful\";\n        case EmailStatusCode.rfc5321: return \"Address is valid for SMTP but has unusual elements\";\n\n        case EmailStatusCode.cFoldingWhitespace: return \"Address is valid within the message but cannot be used\"~\n            \" unmodified for the envelope\";\n\n        case EmailStatusCode.deprecated_: return \"Address contains deprecated elements but may still be valid in\"~\n            \" restricted contexts\";\n\n        case EmailStatusCode.rfc5322: return \"The address is only valid according to the broad definition of RFC 5322.\"~\n            \" It is otherwise invalid\";\n\n        case EmailStatusCode.any: return \"\";\n        case EmailStatusCode.none: return \"\";\n        case EmailStatusCode.warning: return \"\";\n        case EmailStatusCode.error: return \"Address is invalid for any purpose\";\n\n        // Diagnoses\n        case EmailStatusCode.valid: return \"Address is valid\";\n\n        // Address is valid but a DNS check was not successful\n        case EmailStatusCode.dnsWarningNoMXRecord: return \"Could not find an MX record for this domain but an A-record\"~\n            \" does exist\";\n\n        case EmailStatusCode.dnsWarningNoRecord: return \"Could not find an MX record or an A-record for this domain\";\n\n        // Address is valid for SMTP but has unusual elements\n        case EmailStatusCode.rfc5321TopLevelDomain: return \"Address is valid but at a Top Level Domain\";\n\n        case EmailStatusCode.rfc5321TopLevelDomainNumeric: return \"Address is valid but the Top Level Domain begins\"~\n            \" with a number\";\n\n        case EmailStatusCode.rfc5321QuotedString: return \"Address is valid but contains a quoted string\";\n        case EmailStatusCode.rfc5321AddressLiteral: return \"Address is valid but at a literal address not a domain\";\n\n        case EmailStatusCode.rfc5321IpV6Deprecated: return \"Address is valid but contains a :: that only elides one\"~\n            \" zero group\";\n\n\n        // Address is valid within the message but cannot be used unmodified for the envelope\n        case EmailStatusCode.comment: return \"Address contains comments\";\n        case EmailStatusCode.foldingWhitespace: return \"Address contains Folding White Space\";\n\n        // Address contains deprecated elements but may still be valid in restricted contexts\n        case EmailStatusCode.deprecatedLocalPart: return \"The local part is in a deprecated form\";\n\n        case EmailStatusCode.deprecatedFoldingWhitespace: return \"Address contains an obsolete form of\"~\n            \" Folding White Space\";\n\n        case EmailStatusCode.deprecatedQuotedText: return \"A quoted string contains a deprecated character\";\n        case EmailStatusCode.deprecatedQuotedPair: return \"A quoted pair contains a deprecated character\";\n        case EmailStatusCode.deprecatedComment: return \"Address contains a comment in a position that is deprecated\";\n        case EmailStatusCode.deprecatedCommentText: return \"A comment contains a deprecated character\";\n\n        case EmailStatusCode.deprecatedCommentFoldingWhitespaceNearAt: return \"Address contains a comment or\"~\n            \" Folding White Space around the @ sign\";\n\n        // The address is only valid according to the broad definition of RFC 5322\n        case EmailStatusCode.rfc5322Domain: return \"Address is RFC 5322 compliant but contains domain characters that\"~\n        \" are not allowed by DNS\";\n\n        case EmailStatusCode.rfc5322TooLong: return \"Address is too long\";\n        case EmailStatusCode.rfc5322LocalTooLong: return \"The local part of the address is too long\";\n        case EmailStatusCode.rfc5322DomainTooLong: return \"The domain part is too long\";\n        case EmailStatusCode.rfc5322LabelTooLong: return \"The domain part contains an element that is too long\";\n        case EmailStatusCode.rfc5322DomainLiteral: return \"The domain literal is not a valid RFC 5321 address literal\";\n\n        case EmailStatusCode.rfc5322DomainLiteralObsoleteText: return \"The domain literal is not a valid RFC 5321\"~\n            \" address literal and it contains obsolete characters\";\n\n        case EmailStatusCode.rfc5322IpV6GroupCount:\n            return \"The IPv6 literal address contains the wrong number of groups\";\n\n        case EmailStatusCode.rfc5322IpV6TooManyDoubleColons:\n            return \"The IPv6 literal address contains too many :: sequences\";\n\n        case EmailStatusCode.rfc5322IpV6BadChar: return \"The IPv6 address contains an illegal group of characters\";\n        case EmailStatusCode.rfc5322IpV6MaxGroups: return \"The IPv6 address has too many groups\";\n        case EmailStatusCode.rfc5322IpV6ColonStart: return \"IPv6 address starts with a single colon\";\n        case EmailStatusCode.rfc5322IpV6ColonEnd: return \"IPv6 address ends with a single colon\";\n\n        // Address is invalid for any purpose\n        case EmailStatusCode.errorExpectingDomainText:\n            return \"A domain literal contains a character that is not allowed\";\n\n        case EmailStatusCode.errorNoLocalPart: return \"Address has no local part\";\n        case EmailStatusCode.errorNoDomain: return \"Address has no domain part\";\n        case EmailStatusCode.errorConsecutiveDots: return \"The address may not contain consecutive dots\";\n\n        case EmailStatusCode.errorTextAfterCommentFoldingWhitespace:\n            return \"Address contains text after a comment or Folding White Space\";\n\n        case EmailStatusCode.errorTextAfterQuotedString: return \"Address contains text after a quoted string\";\n\n        case EmailStatusCode.errorTextAfterDomainLiteral: return \"Extra characters were found after the end of\"~\n            \" the domain literal\";\n\n        case EmailStatusCode.errorExpectingQuotedPair:\n            return \"The address contains a character that is not allowed in a quoted pair\";\n\n        case EmailStatusCode.errorExpectingText: return \"Address contains a character that is not allowed\";\n\n        case EmailStatusCode.errorExpectingQuotedText:\n            return \"A quoted string contains a character that is not allowed\";\n\n        case EmailStatusCode.errorExpectingCommentText: return \"A comment contains a character that is not allowed\";\n        case EmailStatusCode.errorBackslashEnd: return \"The address cannot end with a backslash\";\n        case EmailStatusCode.errorDotStart: return \"Neither part of the address may begin with a dot\";\n        case EmailStatusCode.errorDotEnd: return \"Neither part of the address may end with a dot\";\n        case EmailStatusCode.errorDomainHyphenStart: return \"A domain or subdomain cannot begin with a hyphen\";\n        case EmailStatusCode.errorDomainHyphenEnd: return \"A domain or subdomain cannot end with a hyphen\";\n        case EmailStatusCode.errorUnclosedQuotedString: return \"Unclosed quoted string\";\n        case EmailStatusCode.errorUnclosedComment: return \"Unclosed comment\";\n        case EmailStatusCode.errorUnclosedDomainLiteral: return \"Domain literal is missing its closing bracket\";\n\n        case EmailStatusCode.errorFoldingWhitespaceCrflX2:\n            return \"Folding White Space contains consecutive CRLF sequences\";\n\n        case EmailStatusCode.errorFoldingWhitespaceCrLfEnd: return \"Folding White Space ends with a CRLF sequence\";\n\n        case EmailStatusCode.errorCrNoLf:\n            return \"Address contains a carriage return that is not followed by a line feed\";\n    }\n}\n\n/**\n * An email status code, indicating if an email address is valid or not.\n * If it is invalid it also indicates why.\n */\nenum EmailStatusCode\n{\n    // Categories\n\n    /// Address is valid\n    validCategory = 1,\n\n    /// Address is valid but a DNS check was not successful\n    dnsWarning = 7,\n\n    /// Address is valid for SMTP but has unusual elements\n    rfc5321 = 15,\n\n    /// Address is valid within the message but cannot be used unmodified for the envelope\n    cFoldingWhitespace = 31,\n\n    /// Address contains deprecated elements but may still be valid in restricted contexts\n    deprecated_ = 63,\n\n    /// The address is only valid according to the broad definition of RFC 5322. It is otherwise invalid\n    rfc5322 = 127,\n\n    /**\n     * All finer grained error checking is turned on. Address containing errors or\n     * warnings is considered invalid. A specific email status code will be\n     * returned indicating the error/warning of the address.\n     */\n    any = 252,\n\n    /**\n     * Address is either considered valid or not, no finer grained error checking\n     * is performed. Returned email status code will be either Error or Valid.\n     */\n    none = 253,\n\n    /**\n     * Address containing warnings is considered valid, that is,\n     * any status code below 16 is considered valid.\n     */\n    warning = 254,\n\n    /// Address is invalid for any purpose\n    error = 255,\n\n\n\n    // Diagnoses\n\n    /// Address is valid\n    valid = 0,\n\n    // Address is valid but a DNS check was not successful\n\n    /// Could not find an MX record for this domain but an A-record does exist\n    dnsWarningNoMXRecord = 5,\n\n    /// Could not find an MX record or an A-record for this domain\n    dnsWarningNoRecord = 6,\n\n\n\n    // Address is valid for SMTP but has unusual elements\n\n    /// Address is valid but at a Top Level Domain\n    rfc5321TopLevelDomain = 9,\n\n    /// Address is valid but the Top Level Domain begins with a number\n    rfc5321TopLevelDomainNumeric = 10,\n\n    /// Address is valid but contains a quoted string\n    rfc5321QuotedString = 11,\n\n    /// Address is valid but at a literal address not a domain\n    rfc5321AddressLiteral = 12,\n\n    /// Address is valid but contains a :: that only elides one zero group\n    rfc5321IpV6Deprecated = 13,\n\n\n\n    // Address is valid within the message but cannot be used unmodified for the envelope\n\n    /// Address contains comments\n    comment = 17,\n\n    /// Address contains Folding White Space\n    foldingWhitespace = 18,\n\n\n\n    // Address contains deprecated elements but may still be valid in restricted contexts\n\n    /// The local part is in a deprecated form\n    deprecatedLocalPart = 33,\n\n    /// Address contains an obsolete form of Folding White Space\n    deprecatedFoldingWhitespace = 34,\n\n    /// A quoted string contains a deprecated character\n    deprecatedQuotedText = 35,\n\n    /// A quoted pair contains a deprecated character\n    deprecatedQuotedPair = 36,\n\n    /// Address contains a comment in a position that is deprecated\n    deprecatedComment = 37,\n\n    /// A comment contains a deprecated character\n    deprecatedCommentText = 38,\n\n    /// Address contains a comment or Folding White Space around the @ sign\n    deprecatedCommentFoldingWhitespaceNearAt = 49,\n\n\n\n    // The address is only valid according to the broad definition of RFC 5322\n\n    /// Address is RFC 5322 compliant but contains domain characters that are not allowed by DNS\n    rfc5322Domain = 65,\n\n    /// Address is too long\n    rfc5322TooLong = 66,\n\n    /// The local part of the address is too long\n    rfc5322LocalTooLong = 67,\n\n    /// The domain part is too long\n    rfc5322DomainTooLong = 68,\n\n    /// The domain part contains an element that is too long\n    rfc5322LabelTooLong = 69,\n\n    /// The domain literal is not a valid RFC 5321 address literal\n    rfc5322DomainLiteral = 70,\n\n    /// The domain literal is not a valid RFC 5321 address literal and it contains obsolete characters\n    rfc5322DomainLiteralObsoleteText = 71,\n\n    /// The IPv6 literal address contains the wrong number of groups\n    rfc5322IpV6GroupCount = 72,\n\n    /// The IPv6 literal address contains too many :: sequences\n    rfc5322IpV6TooManyDoubleColons = 73,\n\n    /// The IPv6 address contains an illegal group of characters\n    rfc5322IpV6BadChar = 74,\n\n    /// The IPv6 address has too many groups\n    rfc5322IpV6MaxGroups = 75,\n\n    /// IPv6 address starts with a single colon\n    rfc5322IpV6ColonStart = 76,\n\n    /// IPv6 address ends with a single colon\n    rfc5322IpV6ColonEnd = 77,\n\n\n\n    // Address is invalid for any purpose\n\n    /// A domain literal contains a character that is not allowed\n    errorExpectingDomainText = 129,\n\n    /// Address has no local part\n    errorNoLocalPart = 130,\n\n    /// Address has no domain part\n    errorNoDomain = 131,\n\n    /// The address may not contain consecutive dots\n    errorConsecutiveDots = 132,\n\n    /// Address contains text after a comment or Folding White Space\n    errorTextAfterCommentFoldingWhitespace = 133,\n\n    /// Address contains text after a quoted string\n    errorTextAfterQuotedString = 134,\n\n    /// Extra characters were found after the end of the domain literal\n    errorTextAfterDomainLiteral = 135,\n\n    /// The address contains a character that is not allowed in a quoted pair\n    errorExpectingQuotedPair = 136,\n\n    /// Address contains a character that is not allowed\n    errorExpectingText = 137,\n\n    /// A quoted string contains a character that is not allowed\n    errorExpectingQuotedText = 138,\n\n    /// A comment contains a character that is not allowed\n    errorExpectingCommentText = 139,\n\n    /// The address cannot end with a backslash\n    errorBackslashEnd = 140,\n\n    /// Neither part of the address may begin with a dot\n    errorDotStart = 141,\n\n    /// Neither part of the address may end with a dot\n    errorDotEnd = 142,\n\n    /// A domain or subdomain cannot begin with a hyphen\n    errorDomainHyphenStart = 143,\n\n    /// A domain or subdomain cannot end with a hyphen\n    errorDomainHyphenEnd = 144,\n\n    /// Unclosed quoted string\n    errorUnclosedQuotedString = 145,\n\n    /// Unclosed comment\n    errorUnclosedComment = 146,\n\n    /// Domain literal is missing its closing bracket\n    errorUnclosedDomainLiteral = 147,\n\n    /// Folding White Space contains consecutive CRLF sequences\n    errorFoldingWhitespaceCrflX2 = 148,\n\n    /// Folding White Space ends with a CRLF sequence\n    errorFoldingWhitespaceCrLfEnd = 149,\n\n    /// Address contains a carriage return that is not followed by a line feed\n    errorCrNoLf = 150,\n}\n\nprivate:\n\n// Email parts for the isEmail function\nenum EmailPart\n{\n    // The local part of the email address, that is, the part before the @ sign\n    componentLocalPart,\n\n    // The domain part of the email address, that is, the part after the @ sign.\n    componentDomain,\n\n    componentLiteral,\n    contextComment,\n    contextFoldingWhitespace,\n    contextQuotedString,\n    contextQuotedPair,\n    status\n}\n\n// Miscellaneous string constants\nstruct TokenImpl(Char)\n{\n    enum : const(Char)[]\n    {\n        at = \"@\",\n        backslash = `\\`,\n        dot = \".\",\n        doubleQuote = `\"`,\n        openParenthesis = \"(\",\n        closeParenthesis = \")\",\n        openBracket = \"[\",\n        closeBracket = \"]\",\n        hyphen = \"-\",\n        colon = \":\",\n        doubleColon = \"::\",\n        space = \" \",\n        tab = \"\\t\",\n        cr = \"\\r\",\n        lf = \"\\n\",\n        ipV6Tag = \"IPV6:\",\n\n        // US-ASCII visible characters not valid for atext (http://tools.ietf.org/html/rfc5322#section-3.2.3)\n        specials = `()<>[]:;@\\\\,.\"`\n    }\n}\n\nenum AsciiToken\n{\n    horizontalTab = 9,\n    unitSeparator = 31,\n    delete_ = 127\n}\n\n/*\n * Compare the two given strings lexicographically. An upper limit of the number of\n * characters, that will be used in the comparison, can be specified. Supports both\n * case-sensitive and case-insensitive comparison.\n *\n * Params:\n *     s1 = the first string to be compared\n *     s2 = the second string to be compared\n *     length = the length of strings to be used in the comparison.\n *     caseInsensitive = if true, a case-insensitive comparison will be made,\n *                       otherwise a case-sensitive comparison will be made\n *\n * Returns: (for $(D pred = \"a < b\")):\n *\n * $(BOOKTABLE,\n * $(TR $(TD $(D < 0))  $(TD $(D s1 < s2) ))\n * $(TR $(TD $(D = 0))  $(TD $(D s1 == s2)))\n * $(TR $(TD $(D > 0))  $(TD $(D s1 > s2)))\n * )\n */\nint compareFirstN(alias pred = \"a < b\", S1, S2) (S1 s1, S2 s2, size_t length)\nif (is(Unqual!(ElementType!(S1)) == dchar) && is(Unqual!(ElementType!(S2)) == dchar))\n{\n    import std.uni : icmp;\n    auto s1End = length <= s1.length ? length : s1.length;\n    auto s2End = length <= s2.length ? length : s2.length;\n\n    auto slice1 = s1[0 .. s1End];\n    auto slice2 = s2[0 .. s2End];\n\n    return slice1.icmp(slice2);\n}\n\n@safe unittest\n{\n    assert(\"abc\".compareFirstN(\"abcdef\", 3) == 0);\n    assert(\"abc\".compareFirstN(\"Abc\", 3) == 0);\n    assert(\"abc\".compareFirstN(\"abcdef\", 6) < 0);\n    assert(\"abcdef\".compareFirstN(\"abc\", 6) > 0);\n}\n\n/*\n * Pops the last element of the given range and returns the element.\n *\n * Params:\n *     range = the range to pop the element from\n *\n * Returns: the popped element\n */\nElementType!(A) pop (A) (ref A a)\nif (isDynamicArray!(A) && !isNarrowString!(A) && isMutable!(A) && !is(A == void[]))\n{\n    auto e = a.back;\n    a.popBack();\n    return e;\n}\n\n@safe unittest\n{\n    auto array = [0, 1, 2, 3];\n    auto result = array.pop();\n\n    assert(array == [0, 1, 2]);\n    assert(result == 3);\n}\n\n/*\n * Returns the character at the given index as a string. The returned string will be a\n * slice of the original string.\n *\n * Params:\n *     str = the string to get the character from\n *     index = the index of the character to get\n *     c = the character to return, or any other of the same length\n *\n * Returns: the character at the given index as a string\n */\nconst(T)[] get (T) (const(T)[] str, size_t index, dchar c)\n{\n    import std.utf : codeLength;\n    return str[index .. index + codeLength!(T)(c)];\n}\n\n@safe unittest\n{\n    assert(\"abc\".get(1, 'b') == \"b\");\n    assert(\"löv\".get(1, 'ö') == \"ö\");\n}\n\n@safe unittest\n{\n    assert(\"abc\".get(1, 'b') == \"b\");\n    assert(\"löv\".get(1, 'ö') == \"ö\");\n}\n\n/+\nReplacement for:\n---\nstatic fourChars = ctRegex!(`^[0-9A-Fa-f]{0,4}$`.to!(const(Char)[]));\n...\na => a.matchFirst(fourChars).empty\n---\n+/\nbool isUpToFourHexChars(Char)(scope const(Char)[] s)\n{\n    import std.ascii : isHexDigit;\n    if (s.length > 4) return false;\n    foreach (c; s)\n        if (!isHexDigit(c)) return false;\n    return true;\n}\n\n@nogc nothrow pure @safe unittest\n{\n    assert(!isUpToFourHexChars(\"12345\"));\n    assert(!isUpToFourHexChars(\"defg\"));\n    assert(isUpToFourHexChars(\"1A0a\"));\n}\n\n/+\nReplacement for:\n---\nstatic ipRegex = ctRegex!(`\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}`~\n                    `(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`.to!(const(Char)[]));\n...\nauto matchesIp = addressLiteral.matchAll(ipRegex).map!(a => a.hit).array;\n----\nNote that only the first item of \"matchAll\" was ever used in practice\nso we can return `const(Char)[]` instead of `const(Char)[][]` using a\nzero-length string to indicate no match.\n+/\nconst(Char)[] matchIPSuffix(Char)(return const(Char)[] s) @nogc nothrow pure @safe\n{\n    size_t end = s.length;\n    if (end < 7) return null;\n    // Check the first three `[.]\\d{1,3}`\n    foreach (_; 0 .. 3)\n    {\n        size_t start = void;\n        if (end >= 2 && s[end-2] == '.')\n            start = end - 2;\n        else if (end >= 3 && s[end-3] == '.')\n            start = end - 3;\n        else if (end >= 4 && s[end-4] == '.')\n            start = end - 4;\n        else\n            return null;\n        uint x = 0;\n        foreach (i; start + 1 .. end)\n        {\n            uint c = cast(uint) s[i] - '0';\n            if (c > 9) return null;\n            x = x * 10 + c;\n        }\n        if (x > 255) return null;\n        end = start;\n    }\n    // Check the final `\\d{1,3}`.\n    if (end < 1) return null;\n    size_t start = end - 1;\n    uint x = cast(uint) s[start] - '0';\n    if (x > 9) return null;\n    if (start > 0 && cast(uint) s[start-1] - '0' <= 9)\n    {\n        --start;\n        x += 10 * (cast(uint) s[start] - '0');\n        if (start > 0 && cast(uint) s[start-1] - '0' <= 9)\n        {\n            --start;\n            x += 100 * (cast(uint) s[start] - '0');\n        }\n    }\n    if (x > 255) return null;\n    // Must either be at start of string or preceded by a non-word character.\n    // (TO DETERMINE: is the definition of \"word character\" ASCII only?)\n    if (start == 0) return s;\n    const b = s[start - 1];\n    import std.ascii : isAlphaNum;\n    if (isAlphaNum(b) || b == '_') return null;\n    return s[start .. $];\n}\n\n@nogc nothrow pure @safe unittest\n{\n    assert(matchIPSuffix(\"255.255.255.255\") == \"255.255.255.255\");\n    assert(matchIPSuffix(\"babaev 176.16.0.1\") == \"176.16.0.1\");\n}\n"
  },
  {
    "path": "libphobos/src/std/numeric.d",
    "content": "// Written in the D programming language.\n\n/**\nThis module is a port of a growing fragment of the $(D_PARAM numeric)\nheader in Alexander Stepanov's $(LINK2 https://en.wikipedia.org/wiki/Standard_Template_Library,\nStandard Template Library), with a few additions.\n\nMacros:\nCopyright: Copyright Andrei Alexandrescu 2008 - 2009.\nLicense:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   $(HTTP erdani.org, Andrei Alexandrescu),\n                   Don Clugston, Robert Jacques, Ilya Yaroshenko\nSource:    $(PHOBOSSRC std/numeric.d)\n*/\n/*\n         Copyright Andrei Alexandrescu 2008 - 2009.\nDistributed under the Boost Software License, Version 1.0.\n   (See accompanying file LICENSE_1_0.txt or copy at\n         http://www.boost.org/LICENSE_1_0.txt)\n*/\nmodule std.numeric;\n\nimport std.complex;\nimport std.math;\nimport std.range.primitives;\nimport std.traits;\nimport std.typecons;\n\n/// Format flags for CustomFloat.\npublic enum CustomFloatFlags\n{\n    /// Adds a sign bit to allow for signed numbers.\n    signed = 1,\n\n    /**\n     * Store values in normalized form by default. The actual precision of the\n     * significand is extended by 1 bit by assuming an implicit leading bit of 1\n     * instead of 0. i.e. `1.nnnn` instead of `0.nnnn`.\n     * True for all $(LINK2 https://en.wikipedia.org/wiki/IEEE_floating_point, IEE754) types\n     */\n    storeNormalized = 2,\n\n    /**\n     * Stores the significand in $(LINK2 https://en.wikipedia.org/wiki/IEEE_754-1985#Denormalized_numbers,\n     * IEEE754 denormalized) form when the exponent is 0. Required to express the value 0.\n     */\n    allowDenorm = 4,\n\n    /**\n      * Allows the storage of $(LINK2 https://en.wikipedia.org/wiki/IEEE_754-1985#Positive_and_negative_infinity,\n      * IEEE754 _infinity) values.\n      */\n    infinity = 8,\n\n    /// Allows the storage of $(LINK2 https://en.wikipedia.org/wiki/NaN, IEEE754 Not a Number) values.\n    nan = 16,\n\n    /**\n     * If set, select an exponent bias such that max_exp = 1.\n     * i.e. so that the maximum value is >= 1.0 and < 2.0.\n     * Ignored if the exponent bias is manually specified.\n     */\n    probability = 32,\n\n    /// If set, unsigned custom floats are assumed to be negative.\n    negativeUnsigned = 64,\n\n    /**If set, 0 is the only allowed $(LINK2 https://en.wikipedia.org/wiki/IEEE_754-1985#Denormalized_numbers,\n     * IEEE754 denormalized) number.\n     * Requires allowDenorm and storeNormalized.\n     */\n    allowDenormZeroOnly = 128 | allowDenorm | storeNormalized,\n\n    /// Include _all of the $(LINK2 https://en.wikipedia.org/wiki/IEEE_floating_point, IEEE754) options.\n    ieee = signed | storeNormalized | allowDenorm | infinity | nan ,\n\n    /// Include none of the above options.\n    none = 0\n}\n\nprivate template CustomFloatParams(uint bits)\n{\n    enum CustomFloatFlags flags = CustomFloatFlags.ieee\n                ^ ((bits == 80) ? CustomFloatFlags.storeNormalized : CustomFloatFlags.none);\n    static if (bits ==  8) alias CustomFloatParams = CustomFloatParams!( 4,  3, flags);\n    static if (bits == 16) alias CustomFloatParams = CustomFloatParams!(10,  5, flags);\n    static if (bits == 32) alias CustomFloatParams = CustomFloatParams!(23,  8, flags);\n    static if (bits == 64) alias CustomFloatParams = CustomFloatParams!(52, 11, flags);\n    static if (bits == 80) alias CustomFloatParams = CustomFloatParams!(64, 15, flags);\n}\n\nprivate template CustomFloatParams(uint precision, uint exponentWidth, CustomFloatFlags flags)\n{\n    import std.meta : AliasSeq;\n    alias CustomFloatParams =\n        AliasSeq!(\n            precision,\n            exponentWidth,\n            flags,\n            (1 << (exponentWidth - ((flags & flags.probability) == 0)))\n             - ((flags & (flags.nan | flags.infinity)) != 0) - ((flags & flags.probability) != 0)\n        ); // ((flags & CustomFloatFlags.probability) == 0)\n}\n\n/**\n * Allows user code to define custom floating-point formats. These formats are\n * for storage only; all operations on them are performed by first implicitly\n * extracting them to `real` first. After the operation is completed the\n * result can be stored in a custom floating-point value via assignment.\n */\ntemplate CustomFloat(uint bits)\nif (bits == 8 || bits == 16 || bits == 32 || bits == 64 || bits == 80)\n{\n    alias CustomFloat = CustomFloat!(CustomFloatParams!(bits));\n}\n\n/// ditto\ntemplate CustomFloat(uint precision, uint exponentWidth, CustomFloatFlags flags = CustomFloatFlags.ieee)\nif (((flags & flags.signed) + precision + exponentWidth) % 8 == 0 && precision + exponentWidth > 0)\n{\n    alias CustomFloat = CustomFloat!(CustomFloatParams!(precision, exponentWidth, flags));\n}\n\n///\n@safe unittest\n{\n    import std.math : sin, cos;\n\n    // Define a 16-bit floating point values\n    CustomFloat!16                                x;     // Using the number of bits\n    CustomFloat!(10, 5)                           y;     // Using the precision and exponent width\n    CustomFloat!(10, 5,CustomFloatFlags.ieee)     z;     // Using the precision, exponent width and format flags\n    CustomFloat!(10, 5,CustomFloatFlags.ieee, 15) w;     // Using the precision, exponent width, format flags and exponent offset bias\n\n    // Use the 16-bit floats mostly like normal numbers\n    w = x*y - 1;\n\n    // Functions calls require conversion\n    z = sin(+x)           + cos(+y);                     // Use unary plus to concisely convert to a real\n    z = sin(x.get!float)  + cos(y.get!float);            // Or use get!T\n    z = sin(cast(float) x) + cos(cast(float) y);           // Or use cast(T) to explicitly convert\n\n    // Define a 8-bit custom float for storing probabilities\n    alias Probability = CustomFloat!(4, 4, CustomFloatFlags.ieee^CustomFloatFlags.probability^CustomFloatFlags.signed );\n    auto p = Probability(0.5);\n}\n\n/// ditto\nstruct CustomFloat(uint             precision,  // fraction bits (23 for float)\n                   uint             exponentWidth,  // exponent bits (8 for float)  Exponent width\n                   CustomFloatFlags flags,\n                   uint             bias)\nif (((flags & flags.signed)  + precision + exponentWidth) % 8 == 0 &&\n    precision + exponentWidth > 0)\n{\n    import std.bitmanip : bitfields;\n    import std.meta : staticIndexOf;\nprivate:\n    // get the correct unsigned bitfield type to support > 32 bits\n    template uType(uint bits)\n    {\n        static if (bits <= size_t.sizeof*8)  alias uType = size_t;\n        else                                alias uType = ulong ;\n    }\n\n    // get the correct signed   bitfield type to support > 32 bits\n    template sType(uint bits)\n    {\n        static if (bits <= ptrdiff_t.sizeof*8-1) alias sType = ptrdiff_t;\n        else                                    alias sType = long;\n    }\n\n    alias T_sig = uType!precision;\n    alias T_exp = uType!exponentWidth;\n    alias T_signed_exp = sType!exponentWidth;\n\n    alias Flags = CustomFloatFlags;\n\n    // Facilitate converting numeric types to custom float\n    union ToBinary(F)\n        if (is(typeof(CustomFloatParams!(F.sizeof*8))) || is(F == real))\n    {\n        F set;\n\n        // If on Linux or Mac, where 80-bit reals are padded, ignore the\n        // padding.\n        import std.algorithm.comparison : min;\n        CustomFloat!(CustomFloatParams!(min(F.sizeof*8, 80))) get;\n\n        // Convert F to the correct binary type.\n        static typeof(get) opCall(F value)\n        {\n            ToBinary r;\n            r.set = value;\n            return r.get;\n        }\n        alias get this;\n    }\n\n    // Perform IEEE rounding with round to nearest detection\n    void roundedShift(T,U)(ref T sig, U shift)\n    {\n        if (sig << (T.sizeof*8 - shift) == cast(T) 1uL << (T.sizeof*8 - 1))\n        {\n            // round to even\n            sig >>= shift;\n            sig  += sig & 1;\n        }\n        else\n        {\n            sig >>= shift - 1;\n            sig  += sig & 1;\n            // Perform standard rounding\n            sig >>= 1;\n        }\n    }\n\n    // Convert the current value to signed exponent, normalized form\n    void toNormalized(T,U)(ref T sig, ref U exp)\n    {\n        sig = significand;\n        auto shift = (T.sizeof*8) - precision;\n        exp = exponent;\n        static if (flags&(Flags.infinity|Flags.nan))\n        {\n            // Handle inf or nan\n            if (exp == exponent_max)\n            {\n                exp = exp.max;\n                sig <<= shift;\n                static if (flags&Flags.storeNormalized)\n                {\n                    // Save inf/nan in denormalized format\n                    sig >>= 1;\n                    sig  += cast(T) 1uL << (T.sizeof*8 - 1);\n                }\n                return;\n            }\n        }\n        if ((~flags&Flags.storeNormalized) ||\n            // Convert denormalized form to normalized form\n            ((flags&Flags.allowDenorm) && exp == 0))\n        {\n            if (sig > 0)\n            {\n                import core.bitop : bsr;\n                auto shift2 = precision - bsr(sig);\n                exp  -= shift2-1;\n                shift += shift2;\n            }\n            else                                // value = 0.0\n            {\n                exp = exp.min;\n                return;\n            }\n        }\n        sig <<= shift;\n        exp -= bias;\n    }\n\n    // Set the current value from signed exponent, normalized form\n    void fromNormalized(T,U)(ref T sig, ref U exp)\n    {\n        auto shift = (T.sizeof*8) - precision;\n        if (exp == exp.max)\n        {\n            // infinity or nan\n            exp = exponent_max;\n            static if (flags & Flags.storeNormalized)\n                sig <<= 1;\n\n            // convert back to normalized form\n            static if (~flags & Flags.infinity)\n                // No infinity support?\n                assert(sig != 0, \"Infinity floating point value assigned to a \"\n                        ~ typeof(this).stringof ~ \" (no infinity support).\");\n\n            static if (~flags & Flags.nan)  // No NaN support?\n                assert(sig == 0, \"NaN floating point value assigned to a \" ~\n                        typeof(this).stringof ~ \" (no nan support).\");\n            sig >>= shift;\n            return;\n        }\n        if (exp == exp.min)     // 0.0\n        {\n             exp = 0;\n             sig = 0;\n             return;\n        }\n\n        exp += bias;\n        if (exp <= 0)\n        {\n            static if ((flags&Flags.allowDenorm) ||\n                       // Convert from normalized form to denormalized\n                       (~flags&Flags.storeNormalized))\n            {\n                shift += -exp;\n                roundedShift(sig,1);\n                sig   += cast(T) 1uL << (T.sizeof*8 - 1);\n                // Add the leading 1\n                exp    = 0;\n            }\n            else\n                assert((flags&Flags.storeNormalized) && exp == 0,\n                    \"Underflow occured assigning to a \" ~\n                    typeof(this).stringof ~ \" (no denormal support).\");\n        }\n        else\n        {\n            static if (~flags&Flags.storeNormalized)\n            {\n                // Convert from normalized form to denormalized\n                roundedShift(sig,1);\n                sig  += cast(T) 1uL << (T.sizeof*8 - 1);\n                // Add the leading 1\n            }\n        }\n\n        if (shift > 0)\n            roundedShift(sig,shift);\n        if (sig > significand_max)\n        {\n            // handle significand overflow (should only be 1 bit)\n            static if (~flags&Flags.storeNormalized)\n            {\n                sig >>= 1;\n            }\n            else\n                sig &= significand_max;\n            exp++;\n        }\n        static if ((flags&Flags.allowDenormZeroOnly)==Flags.allowDenormZeroOnly)\n        {\n            // disallow non-zero denormals\n            if (exp == 0)\n            {\n                sig <<= 1;\n                if (sig > significand_max && (sig&significand_max) > 0)\n                    // Check and round to even\n                    exp++;\n                sig = 0;\n            }\n        }\n\n        if (exp >= exponent_max)\n        {\n            static if (flags&(Flags.infinity|Flags.nan))\n            {\n                sig         = 0;\n                exp         = exponent_max;\n                static if (~flags&(Flags.infinity))\n                    assert(0, \"Overflow occured assigning to a \" ~\n                        typeof(this).stringof ~ \" (no infinity support).\");\n            }\n            else\n                assert(exp == exponent_max, \"Overflow occured assigning to a \"\n                    ~ typeof(this).stringof ~ \" (no infinity support).\");\n        }\n    }\n\npublic:\n    static if (precision == 64) // CustomFloat!80 support hack\n    {\n        ulong significand;\n        enum ulong significand_max = ulong.max;\n        mixin(bitfields!(\n            T_exp , \"exponent\", exponentWidth,\n            bool  , \"sign\"    , flags & flags.signed ));\n    }\n    else\n    {\n        mixin(bitfields!(\n            T_sig, \"significand\", precision,\n            T_exp, \"exponent\"   , exponentWidth,\n            bool , \"sign\"       , flags & flags.signed ));\n    }\n\n    /// Returns: infinity value\n    static if (flags & Flags.infinity)\n        static @property CustomFloat infinity()\n        {\n            CustomFloat value;\n            static if (flags & Flags.signed)\n            value.sign          = 0;\n            value.significand   = 0;\n            value.exponent      = exponent_max;\n            return value;\n        }\n\n    /// Returns: NaN value\n    static if (flags & Flags.nan)\n        static @property CustomFloat nan()\n        {\n            CustomFloat value;\n            static if (flags & Flags.signed)\n            value.sign          = 0;\n            value.significand   = cast(typeof(significand_max)) 1L << (precision-1);\n            value.exponent      = exponent_max;\n            return value;\n        }\n\n    /// Returns: number of decimal digits of precision\n    static @property size_t dig()\n    {\n        auto shiftcnt =  precision - ((flags&Flags.storeNormalized) != 0);\n        immutable x = (shiftcnt == 64) ? 0 : 1uL << shiftcnt;\n        return cast(size_t) log10(x);\n    }\n\n    /// Returns: smallest increment to the value 1\n    static @property CustomFloat epsilon()\n    {\n        CustomFloat value;\n        static if (flags & Flags.signed)\n        value.sign       = 0;\n        T_signed_exp exp = -precision;\n        T_sig        sig = 0;\n\n        value.fromNormalized(sig,exp);\n        if (exp == 0 && sig == 0) // underflowed to zero\n        {\n            static if ((flags&Flags.allowDenorm) ||\n                       (~flags&Flags.storeNormalized))\n                sig = 1;\n            else\n                sig = cast(T) 1uL << (precision - 1);\n        }\n        value.exponent     = cast(value.T_exp) exp;\n        value.significand  = cast(value.T_sig) sig;\n        return value;\n    }\n\n    /// the number of bits in mantissa\n    enum mant_dig = precision + ((flags&Flags.storeNormalized) != 0);\n\n    /// Returns: maximum int value such that 10<sup>max_10_exp</sup> is representable\n    static @property int max_10_exp(){ return cast(int) log10( +max ); }\n\n    /// maximum int value such that 2<sup>max_exp-1</sup> is representable\n    enum max_exp = exponent_max-bias+((~flags&(Flags.infinity|flags.nan))!=0);\n\n    /// Returns: minimum int value such that 10<sup>min_10_exp</sup> is representable\n    static @property int min_10_exp(){ return cast(int) log10( +min_normal ); }\n\n    /// minimum int value such that 2<sup>min_exp-1</sup> is representable as a normalized value\n    enum min_exp = cast(T_signed_exp)-bias +1+ ((flags&Flags.allowDenorm)!=0);\n\n    /// Returns: largest representable value that's not infinity\n    static @property CustomFloat max()\n    {\n        CustomFloat value;\n        static if (flags & Flags.signed)\n        value.sign        = 0;\n        value.exponent    = exponent_max - ((flags&(flags.infinity|flags.nan)) != 0);\n        value.significand = significand_max;\n        return value;\n    }\n\n    /// Returns: smallest representable normalized value that's not 0\n    static @property CustomFloat min_normal() {\n        CustomFloat value;\n        static if (flags & Flags.signed)\n        value.sign        = 0;\n        value.exponent    = 1;\n        static if (flags&Flags.storeNormalized)\n            value.significand = 0;\n        else\n            value.significand = cast(T_sig) 1uL << (precision - 1);\n        return value;\n    }\n\n    /// Returns: real part\n    @property CustomFloat re() { return this; }\n\n    /// Returns: imaginary part\n    static @property CustomFloat im() { return CustomFloat(0.0f); }\n\n    /// Initialize from any `real` compatible type.\n    this(F)(F input) if (__traits(compiles, cast(real) input ))\n    {\n        this = input;\n    }\n\n    /// Self assignment\n    void opAssign(F:CustomFloat)(F input)\n    {\n        static if (flags & Flags.signed)\n        sign        = input.sign;\n        exponent    = input.exponent;\n        significand = input.significand;\n    }\n\n    /// Assigns from any `real` compatible type.\n    void opAssign(F)(F input)\n        if (__traits(compiles, cast(real) input))\n    {\n        import std.conv : text;\n\n        static if (staticIndexOf!(Unqual!F, float, double, real) >= 0)\n            auto value = ToBinary!(Unqual!F)(input);\n        else\n            auto value = ToBinary!(real    )(input);\n\n        // Assign the sign bit\n        static if (~flags & Flags.signed)\n            assert((!value.sign) ^ ((flags&flags.negativeUnsigned) > 0),\n                \"Incorrectly signed floating point value assigned to a \" ~\n                typeof(this).stringof ~ \" (no sign support).\");\n        else\n            sign = value.sign;\n\n        CommonType!(T_signed_exp ,value.T_signed_exp) exp = value.exponent;\n        CommonType!(T_sig,        value.T_sig       ) sig = value.significand;\n\n        value.toNormalized(sig,exp);\n        fromNormalized(sig,exp);\n\n        assert(exp <= exponent_max,    text(typeof(this).stringof ~\n            \" exponent too large: \"   ,exp,\" > \",exponent_max,   \"\\t\",input,\"\\t\",sig));\n        assert(sig <= significand_max, text(typeof(this).stringof ~\n            \" significand too large: \",sig,\" > \",significand_max,\n            \"\\t\",input,\"\\t\",exp,\" \",exponent_max));\n        exponent    = cast(T_exp) exp;\n        significand = cast(T_sig) sig;\n    }\n\n    /// Fetches the stored value either as a `float`, `double` or `real`.\n    @property F get(F)()\n        if (staticIndexOf!(Unqual!F, float, double, real) >= 0)\n    {\n        import std.conv : text;\n\n        ToBinary!F result;\n\n        static if (flags&Flags.signed)\n            result.sign = sign;\n        else\n            result.sign = (flags&flags.negativeUnsigned) > 0;\n\n        CommonType!(T_signed_exp ,result.get.T_signed_exp ) exp = exponent; // Assign the exponent and fraction\n        CommonType!(T_sig,        result.get.T_sig        ) sig = significand;\n\n        toNormalized(sig,exp);\n        result.fromNormalized(sig,exp);\n        assert(exp <= result.exponent_max,    text(\"get exponent too large: \"   ,exp,\" > \",result.exponent_max) );\n        assert(sig <= result.significand_max, text(\"get significand too large: \",sig,\" > \",result.significand_max) );\n        result.exponent     = cast(result.get.T_exp) exp;\n        result.significand  = cast(result.get.T_sig) sig;\n        return result.set;\n    }\n\n    ///ditto\n    T opCast(T)() if (__traits(compiles, get!T )) { return get!T; }\n\n    /// Convert the CustomFloat to a real and perform the relavent operator on the result\n    real opUnary(string op)()\n        if (__traits(compiles, mixin(op~`(get!real)`)) || op==\"++\" || op==\"--\")\n    {\n        static if (op==\"++\" || op==\"--\")\n        {\n            auto result = get!real;\n            this = mixin(op~`result`);\n            return result;\n        }\n        else\n            return mixin(op~`get!real`);\n    }\n\n    /// ditto\n    real opBinary(string op,T)(T b)\n        if (__traits(compiles, mixin(`get!real`~op~`b`)))\n    {\n        return mixin(`get!real`~op~`b`);\n    }\n\n    /// ditto\n    real opBinaryRight(string op,T)(T a)\n        if ( __traits(compiles, mixin(`a`~op~`get!real`)) &&\n            !__traits(compiles, mixin(`get!real`~op~`b`)))\n    {\n        return mixin(`a`~op~`get!real`);\n    }\n\n    /// ditto\n    int opCmp(T)(auto ref T b)\n        if (__traits(compiles, cast(real) b))\n    {\n        auto x = get!real;\n        auto y = cast(real) b;\n        return  (x >= y)-(x <= y);\n    }\n\n    /// ditto\n    void opOpAssign(string op, T)(auto ref T b)\n        if (__traits(compiles, mixin(`get!real`~op~`cast(real) b`)))\n    {\n        return mixin(`this = this `~op~` cast(real) b`);\n    }\n\n    /// ditto\n    template toString()\n    {\n        import std.format : FormatSpec, formatValue;\n        // Needs to be a template because of DMD @@BUG@@ 13737.\n        void toString()(scope void delegate(const(char)[]) sink, FormatSpec!char fmt)\n        {\n            sink.formatValue(get!real, fmt);\n        }\n    }\n}\n\n@safe unittest\n{\n    import std.meta;\n    alias FPTypes =\n        AliasSeq!(\n            CustomFloat!(5, 10),\n            CustomFloat!(5, 11, CustomFloatFlags.ieee ^ CustomFloatFlags.signed),\n            CustomFloat!(1, 15, CustomFloatFlags.ieee ^ CustomFloatFlags.signed),\n            CustomFloat!(4, 3, CustomFloatFlags.ieee | CustomFloatFlags.probability ^ CustomFloatFlags.signed)\n        );\n\n    foreach (F; FPTypes)\n    {\n        auto x = F(0.125);\n        assert(x.get!float == 0.125F);\n        assert(x.get!double == 0.125);\n\n        x -= 0.0625;\n        assert(x.get!float == 0.0625F);\n        assert(x.get!double == 0.0625);\n\n        x *= 2;\n        assert(x.get!float == 0.125F);\n        assert(x.get!double == 0.125);\n\n        x /= 4;\n        assert(x.get!float == 0.03125);\n        assert(x.get!double == 0.03125);\n\n        x = 0.5;\n        x ^^= 4;\n        assert(x.get!float == 1 / 16.0F);\n        assert(x.get!double == 1 / 16.0);\n    }\n}\n\n@system unittest\n{\n    // @system due to to!string(CustomFloat)\n    import std.conv;\n    CustomFloat!(5, 10) y = CustomFloat!(5, 10)(0.125);\n    assert(y.to!string == \"0.125\");\n}\n\n/**\nDefines the fastest type to use when storing temporaries of a\ncalculation intended to ultimately yield a result of type `F`\n(where `F` must be one of `float`, `double`, or $(D\nreal)). When doing a multi-step computation, you may want to store\nintermediate results as `FPTemporary!F`.\n\nThe necessity of `FPTemporary` stems from the optimized\nfloating-point operations and registers present in virtually all\nprocessors. When adding numbers in the example above, the addition may\nin fact be done in `real` precision internally. In that case,\nstoring the intermediate `result` in $(D double format) is not only\nless precise, it is also (surprisingly) slower, because a conversion\nfrom `real` to `double` is performed every pass through the\nloop. This being a lose-lose situation, `FPTemporary!F` has been\ndefined as the $(I fastest) type to use for calculations at precision\n`F`. There is no need to define a type for the $(I most accurate)\ncalculations, as that is always `real`.\n\nFinally, there is no guarantee that using `FPTemporary!F` will\nalways be fastest, as the speed of floating-point calculations depends\non very many factors.\n */\ntemplate FPTemporary(F)\nif (isFloatingPoint!F)\n{\n    version (X86)\n        alias FPTemporary = real;\n    else\n        alias FPTemporary = Unqual!F;\n}\n\n///\n@safe unittest\n{\n    import std.math : approxEqual;\n\n    // Average numbers in an array\n    double avg(in double[] a)\n    {\n        if (a.length == 0) return 0;\n        FPTemporary!double result = 0;\n        foreach (e; a) result += e;\n        return result / a.length;\n    }\n\n    auto a = [1.0, 2.0, 3.0];\n    assert(approxEqual(avg(a), 2));\n}\n\n/**\nImplements the $(HTTP tinyurl.com/2zb9yr, secant method) for finding a\nroot of the function `fun` starting from points $(D [xn_1, x_n])\n(ideally close to the root). `Num` may be `float`, `double`,\nor `real`.\n*/\ntemplate secantMethod(alias fun)\n{\n    import std.functional : unaryFun;\n    Num secantMethod(Num)(Num xn_1, Num xn)\n    {\n        auto fxn = unaryFun!(fun)(xn_1), d = xn_1 - xn;\n        typeof(fxn) fxn_1;\n\n        xn = xn_1;\n        while (!approxEqual(d, 0) && isFinite(d))\n        {\n            xn_1 = xn;\n            xn -= d;\n            fxn_1 = fxn;\n            fxn = unaryFun!(fun)(xn);\n            d *= -fxn / (fxn - fxn_1);\n        }\n        return xn;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.math : approxEqual, cos;\n\n    float f(float x)\n    {\n        return cos(x) - x*x*x;\n    }\n    auto x = secantMethod!(f)(0f, 1f);\n    assert(approxEqual(x, 0.865474));\n}\n\n@system unittest\n{\n    // @system because of __gshared stderr\n    import std.stdio;\n    scope(failure) stderr.writeln(\"Failure testing secantMethod\");\n    float f(float x)\n    {\n        return cos(x) - x*x*x;\n    }\n    immutable x = secantMethod!(f)(0f, 1f);\n    assert(approxEqual(x, 0.865474));\n    auto d = &f;\n    immutable y = secantMethod!(d)(0f, 1f);\n    assert(approxEqual(y, 0.865474));\n}\n\n\n/**\n * Return true if a and b have opposite sign.\n */\nprivate bool oppositeSigns(T1, T2)(T1 a, T2 b)\n{\n    return signbit(a) != signbit(b);\n}\n\npublic:\n\n/**  Find a real root of a real function f(x) via bracketing.\n *\n * Given a function `f` and a range `[a .. b]` such that `f(a)`\n * and `f(b)` have opposite signs or at least one of them equals ±0,\n * returns the value of `x` in\n * the range which is closest to a root of `f(x)`.  If `f(x)`\n * has more than one root in the range, one will be chosen\n * arbitrarily.  If `f(x)` returns NaN, NaN will be returned;\n * otherwise, this algorithm is guaranteed to succeed.\n *\n * Uses an algorithm based on TOMS748, which uses inverse cubic\n * interpolation whenever possible, otherwise reverting to parabolic\n * or secant interpolation. Compared to TOMS748, this implementation\n * improves worst-case performance by a factor of more than 100, and\n * typical performance by a factor of 2. For 80-bit reals, most\n * problems require 8 to 15 calls to `f(x)` to achieve full machine\n * precision. The worst-case performance (pathological cases) is\n * approximately twice the number of bits.\n *\n * References: \"On Enclosing Simple Roots of Nonlinear Equations\",\n * G. Alefeld, F.A. Potra, Yixun Shi, Mathematics of Computation 61,\n * pp733-744 (1993).  Fortran code available from $(HTTP\n * www.netlib.org,www.netlib.org) as algorithm TOMS478.\n *\n */\nT findRoot(T, DF, DT)(scope DF f, in T a, in T b,\n    scope DT tolerance) //= (T a, T b) => false)\nif (\n    isFloatingPoint!T &&\n    is(typeof(tolerance(T.init, T.init)) : bool) &&\n    is(typeof(f(T.init)) == R, R) && isFloatingPoint!R\n    )\n{\n    immutable fa = f(a);\n    if (fa == 0)\n        return a;\n    immutable fb = f(b);\n    if (fb == 0)\n        return b;\n    immutable r = findRoot(f, a, b, fa, fb, tolerance);\n    // Return the first value if it is smaller or NaN\n    return !(fabs(r[2]) > fabs(r[3])) ? r[0] : r[1];\n}\n\n///ditto\nT findRoot(T, DF)(scope DF f, in T a, in T b)\n{\n    return findRoot(f, a, b, (T a, T b) => false);\n}\n\n/** Find root of a real function f(x) by bracketing, allowing the\n * termination condition to be specified.\n *\n * Params:\n *\n * f = Function to be analyzed\n *\n * ax = Left bound of initial range of `f` known to contain the\n * root.\n *\n * bx = Right bound of initial range of `f` known to contain the\n * root.\n *\n * fax = Value of `f(ax)`.\n *\n * fbx = Value of `f(bx)`. `fax` and `fbx` should have opposite signs.\n * (`f(ax)` and `f(bx)` are commonly known in advance.)\n *\n *\n * tolerance = Defines an early termination condition. Receives the\n *             current upper and lower bounds on the root. The\n *             delegate must return `true` when these bounds are\n *             acceptable. If this function always returns `false`,\n *             full machine precision will be achieved.\n *\n * Returns:\n *\n * A tuple consisting of two ranges. The first two elements are the\n * range (in `x`) of the root, while the second pair of elements\n * are the corresponding function values at those points. If an exact\n * root was found, both of the first two elements will contain the\n * root, and the second pair of elements will be 0.\n */\nTuple!(T, T, R, R) findRoot(T, R, DF, DT)(scope DF f, in T ax, in T bx, in R fax, in R fbx,\n    scope DT tolerance) // = (T a, T b) => false)\nif (\n    isFloatingPoint!T &&\n    is(typeof(tolerance(T.init, T.init)) : bool) &&\n    is(typeof(f(T.init)) == R) && isFloatingPoint!R\n    )\nin\n{\n    assert(!ax.isNaN() && !bx.isNaN(), \"Limits must not be NaN\");\n    assert(signbit(fax) != signbit(fbx), \"Parameters must bracket the root.\");\n}\ndo\n{\n    // Author: Don Clugston. This code is (heavily) modified from TOMS748\n    // (www.netlib.org).  The changes to improve the worst-cast performance are\n    // entirely original.\n\n    T a, b, d;  // [a .. b] is our current bracket. d is the third best guess.\n    R fa, fb, fd; // Values of f at a, b, d.\n    bool done = false; // Has a root been found?\n\n    // Allow ax and bx to be provided in reverse order\n    if (ax <= bx)\n    {\n        a = ax; fa = fax;\n        b = bx; fb = fbx;\n    }\n    else\n    {\n        a = bx; fa = fbx;\n        b = ax; fb = fax;\n    }\n\n    // Test the function at point c; update brackets accordingly\n    void bracket(T c)\n    {\n        R fc = f(c);\n        if (fc == 0 || fc.isNaN()) // Exact solution, or NaN\n        {\n            a = c;\n            fa = fc;\n            d = c;\n            fd = fc;\n            done = true;\n            return;\n        }\n\n        // Determine new enclosing interval\n        if (signbit(fa) != signbit(fc))\n        {\n            d = b;\n            fd = fb;\n            b = c;\n            fb = fc;\n        }\n        else\n        {\n            d = a;\n            fd = fa;\n            a = c;\n            fa = fc;\n        }\n    }\n\n   /* Perform a secant interpolation. If the result would lie on a or b, or if\n     a and b differ so wildly in magnitude that the result would be meaningless,\n     perform a bisection instead.\n    */\n    static T secant_interpolate(T a, T b, R fa, R fb)\n    {\n        if (( ((a - b) == a) && b != 0) || (a != 0 && ((b - a) == b)))\n        {\n            // Catastrophic cancellation\n            if (a == 0)\n                a = copysign(T(0), b);\n            else if (b == 0)\n                b = copysign(T(0), a);\n            else if (signbit(a) != signbit(b))\n                return 0;\n            T c = ieeeMean(a, b);\n            return c;\n        }\n        // avoid overflow\n        if (b - a > T.max)\n            return b / 2 + a / 2;\n        if (fb - fa > R.max)\n            return a - (b - a) / 2;\n        T c = a - (fa / (fb - fa)) * (b - a);\n        if (c == a || c == b)\n            return (a + b) / 2;\n        return c;\n    }\n\n    /* Uses 'numsteps' newton steps to approximate the zero in [a .. b] of the\n       quadratic polynomial interpolating f(x) at a, b, and d.\n       Returns:\n         The approximate zero in [a .. b] of the quadratic polynomial.\n    */\n    T newtonQuadratic(int numsteps)\n    {\n        // Find the coefficients of the quadratic polynomial.\n        immutable T a0 = fa;\n        immutable T a1 = (fb - fa)/(b - a);\n        immutable T a2 = ((fd - fb)/(d - b) - a1)/(d - a);\n\n        // Determine the starting point of newton steps.\n        T c = oppositeSigns(a2, fa) ? a  : b;\n\n        // start the safeguarded newton steps.\n        foreach (int i; 0 .. numsteps)\n        {\n            immutable T pc = a0 + (a1 + a2 * (c - b))*(c - a);\n            immutable T pdc = a1 + a2*((2 * c) - (a + b));\n            if (pdc == 0)\n                return a - a0 / a1;\n            else\n                c = c - pc / pdc;\n        }\n        return c;\n    }\n\n    // On the first iteration we take a secant step:\n    if (fa == 0 || fa.isNaN())\n    {\n        done = true;\n        b = a;\n        fb = fa;\n    }\n    else if (fb == 0 || fb.isNaN())\n    {\n        done = true;\n        a = b;\n        fa = fb;\n    }\n    else\n    {\n        bracket(secant_interpolate(a, b, fa, fb));\n    }\n\n    // Starting with the second iteration, higher-order interpolation can\n    // be used.\n    int itnum = 1;   // Iteration number\n    int baditer = 1; // Num bisections to take if an iteration is bad.\n    T c, e;  // e is our fourth best guess\n    R fe;\n\nwhileloop:\n    while (!done && (b != nextUp(a)) && !tolerance(a, b))\n    {\n        T a0 = a, b0 = b; // record the brackets\n\n        // Do two higher-order (cubic or parabolic) interpolation steps.\n        foreach (int QQ; 0 .. 2)\n        {\n            // Cubic inverse interpolation requires that\n            // all four function values fa, fb, fd, and fe are distinct;\n            // otherwise use quadratic interpolation.\n            bool distinct = (fa != fb) && (fa != fd) && (fa != fe)\n                         && (fb != fd) && (fb != fe) && (fd != fe);\n            // The first time, cubic interpolation is impossible.\n            if (itnum<2) distinct = false;\n            bool ok = distinct;\n            if (distinct)\n            {\n                // Cubic inverse interpolation of f(x) at a, b, d, and e\n                immutable q11 = (d - e) * fd / (fe - fd);\n                immutable q21 = (b - d) * fb / (fd - fb);\n                immutable q31 = (a - b) * fa / (fb - fa);\n                immutable d21 = (b - d) * fd / (fd - fb);\n                immutable d31 = (a - b) * fb / (fb - fa);\n\n                immutable q22 = (d21 - q11) * fb / (fe - fb);\n                immutable q32 = (d31 - q21) * fa / (fd - fa);\n                immutable d32 = (d31 - q21) * fd / (fd - fa);\n                immutable q33 = (d32 - q22) * fa / (fe - fa);\n                c = a + (q31 + q32 + q33);\n                if (c.isNaN() || (c <= a) || (c >= b))\n                {\n                    // DAC: If the interpolation predicts a or b, it's\n                    // probable that it's the actual root. Only allow this if\n                    // we're already close to the root.\n                    if (c == a && a - b != a)\n                    {\n                        c = nextUp(a);\n                    }\n                    else if (c == b && a - b != -b)\n                    {\n                        c = nextDown(b);\n                    }\n                    else\n                    {\n                        ok = false;\n                    }\n                }\n            }\n            if (!ok)\n            {\n                // DAC: Alefeld doesn't explain why the number of newton steps\n                // should vary.\n                c = newtonQuadratic(distinct ? 3 : 2);\n                if (c.isNaN() || (c <= a) || (c >= b))\n                {\n                    // Failure, try a secant step:\n                    c = secant_interpolate(a, b, fa, fb);\n                }\n            }\n            ++itnum;\n            e = d;\n            fe = fd;\n            bracket(c);\n            if (done || ( b == nextUp(a)) || tolerance(a, b))\n                break whileloop;\n            if (itnum == 2)\n                continue whileloop;\n        }\n\n        // Now we take a double-length secant step:\n        T u;\n        R fu;\n        if (fabs(fa) < fabs(fb))\n        {\n            u = a;\n            fu = fa;\n        }\n        else\n        {\n            u = b;\n            fu = fb;\n        }\n        c = u - 2 * (fu / (fb - fa)) * (b - a);\n\n        // DAC: If the secant predicts a value equal to an endpoint, it's\n        // probably false.\n        if (c == a || c == b || c.isNaN() || fabs(c - u) > (b - a) / 2)\n        {\n            if ((a-b) == a || (b-a) == b)\n            {\n                if ((a>0 && b<0) || (a<0 && b>0))\n                    c = 0;\n                else\n                {\n                    if (a == 0)\n                        c = ieeeMean(copysign(T(0), b), b);\n                    else if (b == 0)\n                        c = ieeeMean(copysign(T(0), a), a);\n                    else\n                        c = ieeeMean(a, b);\n                }\n            }\n            else\n            {\n                c = a + (b - a) / 2;\n            }\n        }\n        e = d;\n        fe = fd;\n        bracket(c);\n        if (done || (b == nextUp(a)) || tolerance(a, b))\n            break;\n\n        // IMPROVE THE WORST-CASE PERFORMANCE\n        // We must ensure that the bounds reduce by a factor of 2\n        // in binary space! every iteration. If we haven't achieved this\n        // yet, or if we don't yet know what the exponent is,\n        // perform a binary chop.\n\n        if ((a == 0 || b == 0 ||\n            (fabs(a) >= T(0.5) * fabs(b) && fabs(b) >= T(0.5) * fabs(a)))\n            &&  (b - a) < T(0.25) * (b0 - a0))\n        {\n            baditer = 1;\n            continue;\n        }\n\n        // DAC: If this happens on consecutive iterations, we probably have a\n        // pathological function. Perform a number of bisections equal to the\n        // total number of consecutive bad iterations.\n\n        if ((b - a) < T(0.25) * (b0 - a0))\n            baditer = 1;\n        foreach (int QQ; 0 .. baditer)\n        {\n            e = d;\n            fe = fd;\n\n            T w;\n            if ((a>0 && b<0) || (a<0 && b>0))\n                w = 0;\n            else\n            {\n                T usea = a;\n                T useb = b;\n                if (a == 0)\n                    usea = copysign(T(0), b);\n                else if (b == 0)\n                    useb = copysign(T(0), a);\n                w = ieeeMean(usea, useb);\n            }\n            bracket(w);\n        }\n        ++baditer;\n    }\n    return Tuple!(T, T, R, R)(a, b, fa, fb);\n}\n\n///ditto\nTuple!(T, T, R, R) findRoot(T, R, DF)(scope DF f, in T ax, in T bx, in R fax, in R fbx)\n{\n    return findRoot(f, ax, bx, fax, fbx, (T a, T b) => false);\n}\n\n///ditto\nT findRoot(T, R)(scope R delegate(T) f, in T a, in T b,\n    scope bool delegate(T lo, T hi) tolerance = (T a, T b) => false)\n{\n    return findRoot!(T, R delegate(T), bool delegate(T lo, T hi))(f, a, b, tolerance);\n}\n\n@safe nothrow unittest\n{\n    int numProblems = 0;\n    int numCalls;\n\n    void testFindRoot(real delegate(real) @nogc @safe nothrow pure f , real x1, real x2) @nogc @safe nothrow pure\n    {\n        //numCalls=0;\n        //++numProblems;\n        assert(!x1.isNaN() && !x2.isNaN());\n        assert(signbit(x1) != signbit(x2));\n        auto result = findRoot(f, x1, x2, f(x1), f(x2),\n          (real lo, real hi) { return false; });\n\n        auto flo = f(result[0]);\n        auto fhi = f(result[1]);\n        if (flo != 0)\n        {\n            assert(oppositeSigns(flo, fhi));\n        }\n    }\n\n    // Test functions\n    real cubicfn(real x) @nogc @safe nothrow pure\n    {\n        //++numCalls;\n        if (x>float.max)\n            x = float.max;\n        if (x<-double.max)\n            x = -double.max;\n        // This has a single real root at -59.286543284815\n        return 0.386*x*x*x + 23*x*x + 15.7*x + 525.2;\n    }\n    // Test a function with more than one root.\n    real multisine(real x) { ++numCalls; return sin(x); }\n    //testFindRoot( &multisine, 6, 90);\n    //testFindRoot(&cubicfn, -100, 100);\n    //testFindRoot( &cubicfn, -double.max, real.max);\n\n\n/* Tests from the paper:\n * \"On Enclosing Simple Roots of Nonlinear Equations\", G. Alefeld, F.A. Potra,\n *   Yixun Shi, Mathematics of Computation 61, pp733-744 (1993).\n */\n    // Parameters common to many alefeld tests.\n    int n;\n    real ale_a, ale_b;\n\n    int powercalls = 0;\n\n    real power(real x)\n    {\n        ++powercalls;\n        ++numCalls;\n        return pow(x, n) + double.min_normal;\n    }\n    int [] power_nvals = [3, 5, 7, 9, 19, 25];\n    // Alefeld paper states that pow(x,n) is a very poor case, where bisection\n    // outperforms his method, and gives total numcalls =\n    // 921 for bisection (2.4 calls per bit), 1830 for Alefeld (4.76/bit),\n    // 2624 for brent (6.8/bit)\n    // ... but that is for double, not real80.\n    // This poor performance seems mainly due to catastrophic cancellation,\n    // which is avoided here by the use of ieeeMean().\n    // I get: 231 (0.48/bit).\n    // IE this is 10X faster in Alefeld's worst case\n    numProblems=0;\n    foreach (k; power_nvals)\n    {\n        n = k;\n        //testFindRoot(&power, -1, 10);\n    }\n\n    int powerProblems = numProblems;\n\n    // Tests from Alefeld paper\n\n    int [9] alefeldSums;\n    real alefeld0(real x)\n    {\n        ++alefeldSums[0];\n        ++numCalls;\n        real q =  sin(x) - x/2;\n        for (int i=1; i<20; ++i)\n            q+=(2*i-5.0)*(2*i-5.0)/((x-i*i)*(x-i*i)*(x-i*i));\n        return q;\n    }\n    real alefeld1(real x)\n    {\n        ++numCalls;\n        ++alefeldSums[1];\n        return ale_a*x + exp(ale_b * x);\n    }\n    real alefeld2(real x)\n    {\n        ++numCalls;\n        ++alefeldSums[2];\n        return pow(x, n) - ale_a;\n    }\n    real alefeld3(real x)\n    {\n        ++numCalls;\n        ++alefeldSums[3];\n        return (1.0 +pow(1.0L-n, 2))*x - pow(1.0L-n*x, 2);\n    }\n    real alefeld4(real x)\n    {\n        ++numCalls;\n        ++alefeldSums[4];\n        return x*x - pow(1-x, n);\n    }\n    real alefeld5(real x)\n    {\n        ++numCalls;\n        ++alefeldSums[5];\n        return (1+pow(1.0L-n, 4))*x - pow(1.0L-n*x, 4);\n    }\n    real alefeld6(real x)\n    {\n        ++numCalls;\n        ++alefeldSums[6];\n        return exp(-n*x)*(x-1.01L) + pow(x, n);\n    }\n    real alefeld7(real x)\n    {\n        ++numCalls;\n        ++alefeldSums[7];\n        return (n*x-1)/((n-1)*x);\n    }\n\n    numProblems=0;\n    //testFindRoot(&alefeld0, PI_2, PI);\n    for (n=1; n <= 10; ++n)\n    {\n        //testFindRoot(&alefeld0, n*n+1e-9L, (n+1)*(n+1)-1e-9L);\n    }\n    ale_a = -40; ale_b = -1;\n    //testFindRoot(&alefeld1, -9, 31);\n    ale_a = -100; ale_b = -2;\n    //testFindRoot(&alefeld1, -9, 31);\n    ale_a = -200; ale_b = -3;\n    //testFindRoot(&alefeld1, -9, 31);\n    int [] nvals_3 = [1, 2, 5, 10, 15, 20];\n    int [] nvals_5 = [1, 2, 4, 5, 8, 15, 20];\n    int [] nvals_6 = [1, 5, 10, 15, 20];\n    int [] nvals_7 = [2, 5, 15, 20];\n\n    for (int i=4; i<12; i+=2)\n    {\n       n = i;\n       ale_a = 0.2;\n       //testFindRoot(&alefeld2, 0, 5);\n       ale_a=1;\n       //testFindRoot(&alefeld2, 0.95, 4.05);\n       //testFindRoot(&alefeld2, 0, 1.5);\n    }\n    foreach (i; nvals_3)\n    {\n        n=i;\n        //testFindRoot(&alefeld3, 0, 1);\n    }\n    foreach (i; nvals_3)\n    {\n        n=i;\n        //testFindRoot(&alefeld4, 0, 1);\n    }\n    foreach (i; nvals_5)\n    {\n        n=i;\n        //testFindRoot(&alefeld5, 0, 1);\n    }\n    foreach (i; nvals_6)\n    {\n        n=i;\n        //testFindRoot(&alefeld6, 0, 1);\n    }\n    foreach (i; nvals_7)\n    {\n        n=i;\n        //testFindRoot(&alefeld7, 0.01L, 1);\n    }\n    real worstcase(real x)\n    {\n        ++numCalls;\n        return x<0.3*real.max? -0.999e-3 : 1.0;\n    }\n    //testFindRoot(&worstcase, -real.max, real.max);\n\n    // just check that the double + float cases compile\n    //findRoot((double x){ return 0.0; }, -double.max, double.max);\n    //findRoot((float x){ return 0.0f; }, -float.max, float.max);\n\n/*\n   int grandtotal=0;\n   foreach (calls; alefeldSums)\n   {\n       grandtotal+=calls;\n   }\n   grandtotal-=2*numProblems;\n   printf(\"\\nALEFELD TOTAL = %d avg = %f (alefeld avg=19.3 for double)\\n\",\n   grandtotal, (1.0*grandtotal)/numProblems);\n   powercalls -= 2*powerProblems;\n   printf(\"POWER TOTAL = %d avg = %f \", powercalls,\n        (1.0*powercalls)/powerProblems);\n*/\n    //Issue 14231\n    auto xp = findRoot((float x) => x, 0f, 1f);\n    auto xn = findRoot((float x) => x, -1f, -0f);\n}\n\n//regression control\n@system unittest\n{\n    // @system due to the case in the 2nd line\n    static assert(__traits(compiles, findRoot((float x)=>cast(real) x, float.init, float.init)));\n    static assert(__traits(compiles, findRoot!real((x)=>cast(double) x, real.init, real.init)));\n    static assert(__traits(compiles, findRoot((real x)=>cast(double) x, real.init, real.init)));\n}\n\n/++\nFind a real minimum of a real function `f(x)` via bracketing.\nGiven a function `f` and a range `(ax .. bx)`,\nreturns the value of `x` in the range which is closest to a minimum of `f(x)`.\n`f` is never evaluted at the endpoints of `ax` and `bx`.\nIf `f(x)` has more than one minimum in the range, one will be chosen arbitrarily.\nIf `f(x)` returns NaN or -Infinity, `(x, f(x), NaN)` will be returned;\notherwise, this algorithm is guaranteed to succeed.\n\nParams:\n    f = Function to be analyzed\n    ax = Left bound of initial range of f known to contain the minimum.\n    bx = Right bound of initial range of f known to contain the minimum.\n    relTolerance = Relative tolerance.\n    absTolerance = Absolute tolerance.\n\nPreconditions:\n    `ax` and `bx` shall be finite reals. $(BR)\n    `relTolerance` shall be normal positive real. $(BR)\n    `absTolerance` shall be normal positive real no less then `T.epsilon*2`.\n\nReturns:\n    A tuple consisting of `x`, `y = f(x)` and `error = 3 * (absTolerance * fabs(x) + relTolerance)`.\n\n    The method used is a combination of golden section search and\nsuccessive parabolic interpolation. Convergence is never much slower\nthan that for a Fibonacci search.\n\nReferences:\n    \"Algorithms for Minimization without Derivatives\", Richard Brent, Prentice-Hall, Inc. (1973)\n\nSee_Also: $(LREF findRoot), $(REF isNormal, std,math)\n+/\nTuple!(T, \"x\", Unqual!(ReturnType!DF), \"y\", T, \"error\")\nfindLocalMin(T, DF)(\n        scope DF f,\n        in T ax,\n        in T bx,\n        in T relTolerance = sqrt(T.epsilon),\n        in T absTolerance = sqrt(T.epsilon),\n        )\nif (isFloatingPoint!T\n    && __traits(compiles, {T _ = DF.init(T.init);}))\nin\n{\n    assert(isFinite(ax), \"ax is not finite\");\n    assert(isFinite(bx), \"bx is not finite\");\n    assert(isNormal(relTolerance), \"relTolerance is not normal floating point number\");\n    assert(isNormal(absTolerance), \"absTolerance is not normal floating point number\");\n    assert(relTolerance >= 0, \"absTolerance is not positive\");\n    assert(absTolerance >= T.epsilon*2, \"absTolerance is not greater then `2*T.epsilon`\");\n}\nout (result)\n{\n    assert(isFinite(result.x));\n}\ndo\n{\n    alias R = Unqual!(CommonType!(ReturnType!DF, T));\n    // c is the squared inverse of the golden ratio\n    // (3 - sqrt(5))/2\n    // Value obtained from Wolfram Alpha.\n    enum T c = 0x0.61c8864680b583ea0c633f9fa31237p+0L;\n    enum T cm1 = 0x0.9e3779b97f4a7c15f39cc0605cedc8p+0L;\n    R tolerance;\n    T a = ax > bx ? bx : ax;\n    T b = ax > bx ? ax : bx;\n    // sequence of declarations suitable for SIMD instructions\n    T  v = a * cm1 + b * c;\n    assert(isFinite(v));\n    R fv = f(v);\n    if (isNaN(fv) || fv == -T.infinity)\n    {\n        return typeof(return)(v, fv, T.init);\n    }\n    T  w = v;\n    R fw = fv;\n    T  x = v;\n    R fx = fv;\n    size_t i;\n    for (R d = 0, e = 0;;)\n    {\n        i++;\n        T m = (a + b) / 2;\n        // This fix is not part of the original algorithm\n        if (!isFinite(m)) // fix infinity loop. Issue can be reproduced in R.\n        {\n            m = a / 2 + b / 2;\n            if (!isFinite(m)) // fast-math compiler switch is enabled\n            {\n                //SIMD instructions can be used by compiler, do not reduce declarations\n                int a_exp = void;\n                int b_exp = void;\n                immutable an = frexp(a, a_exp);\n                immutable bn = frexp(b, b_exp);\n                immutable am = ldexp(an, a_exp-1);\n                immutable bm = ldexp(bn, b_exp-1);\n                m = am + bm;\n                if (!isFinite(m)) // wrong input: constraints are disabled in release mode\n                {\n                    return typeof(return).init;\n                }\n            }\n        }\n        tolerance = absTolerance * fabs(x) + relTolerance;\n        immutable t2 = tolerance * 2;\n        // check stopping criterion\n        if (!(fabs(x - m) > t2 - (b - a) / 2))\n        {\n            break;\n        }\n        R p = 0;\n        R q = 0;\n        R r = 0;\n        // fit parabola\n        if (fabs(e) > tolerance)\n        {\n            immutable  xw =  x -  w;\n            immutable fxw = fx - fw;\n            immutable  xv =  x -  v;\n            immutable fxv = fx - fv;\n            immutable xwfxv = xw * fxv;\n            immutable xvfxw = xv * fxw;\n            p = xv * xvfxw - xw * xwfxv;\n            q = (xvfxw - xwfxv) * 2;\n            if (q > 0)\n                p = -p;\n            else\n                q = -q;\n            r = e;\n            e = d;\n        }\n        T u;\n        // a parabolic-interpolation step\n        if (fabs(p) < fabs(q * r / 2) && p > q * (a - x) && p < q * (b - x))\n        {\n            d = p / q;\n            u = x + d;\n            // f must not be evaluated too close to a or b\n            if (u - a < t2 || b - u < t2)\n                d = x < m ? tolerance : -tolerance;\n        }\n        // a golden-section step\n        else\n        {\n            e = (x < m ? b : a) - x;\n            d = c * e;\n        }\n        // f must not be evaluated too close to x\n        u = x + (fabs(d) >= tolerance ? d : d > 0 ? tolerance : -tolerance);\n        immutable fu = f(u);\n        if (isNaN(fu) || fu == -T.infinity)\n        {\n            return typeof(return)(u, fu, T.init);\n        }\n        //  update  a, b, v, w, and x\n        if (fu <= fx)\n        {\n            (u < x ? b : a) = x;\n            v = w; fv = fw;\n            w = x; fw = fx;\n            x = u; fx = fu;\n        }\n        else\n        {\n            (u < x ? a : b) = u;\n            if (fu <= fw || w == x)\n            {\n                v = w; fv = fw;\n                w = u; fw = fu;\n            }\n            else if (fu <= fv || v == x || v == w)\n            { // do not remove this braces\n                v = u; fv = fu;\n            }\n        }\n    }\n    return typeof(return)(x, fx, tolerance * 3);\n}\n\n///\n@safe unittest\n{\n    import std.math : approxEqual;\n\n    auto ret = findLocalMin((double x) => (x-4)^^2, -1e7, 1e7);\n    assert(ret.x.approxEqual(4.0));\n    assert(ret.y.approxEqual(0.0));\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(double, float, real))\n    {\n        {\n            auto ret = findLocalMin!T((T x) => (x-4)^^2, T.min_normal, 1e7);\n            assert(ret.x.approxEqual(T(4)));\n            assert(ret.y.approxEqual(T(0)));\n        }\n        {\n            auto ret = findLocalMin!T((T x) => fabs(x-1), -T.max/4, T.max/4, T.min_normal, 2*T.epsilon);\n            assert(approxEqual(ret.x, T(1)));\n            assert(approxEqual(ret.y, T(0)));\n            assert(ret.error <= 10 * T.epsilon);\n        }\n        {\n            auto ret = findLocalMin!T((T x) => T.init, 0, 1, T.min_normal, 2*T.epsilon);\n            assert(!ret.x.isNaN);\n            assert(ret.y.isNaN);\n            assert(ret.error.isNaN);\n        }\n        {\n            auto ret = findLocalMin!T((T x) => log(x), 0, 1, T.min_normal, 2*T.epsilon);\n            assert(ret.error < 3.00001 * ((2*T.epsilon)*fabs(ret.x)+ T.min_normal));\n            assert(ret.x >= 0 && ret.x <= ret.error);\n        }\n        {\n            auto ret = findLocalMin!T((T x) => log(x), 0, T.max, T.min_normal, 2*T.epsilon);\n            assert(ret.y < -18);\n            assert(ret.error < 5e-08);\n            assert(ret.x >= 0 && ret.x <= ret.error);\n        }\n        {\n            auto ret = findLocalMin!T((T x) => -fabs(x), -1, 1, T.min_normal, 2*T.epsilon);\n            assert(ret.x.fabs.approxEqual(T(1)));\n            assert(ret.y.fabs.approxEqual(T(1)));\n            assert(ret.error.approxEqual(T(0)));\n        }\n    }\n}\n\n/**\nComputes $(LINK2 https://en.wikipedia.org/wiki/Euclidean_distance,\nEuclidean distance) between input ranges `a` and\n`b`. The two ranges must have the same length. The three-parameter\nversion stops computation as soon as the distance is greater than or\nequal to `limit` (this is useful to save computation if a small\ndistance is sought).\n */\nCommonType!(ElementType!(Range1), ElementType!(Range2))\neuclideanDistance(Range1, Range2)(Range1 a, Range2 b)\nif (isInputRange!(Range1) && isInputRange!(Range2))\n{\n    enum bool haveLen = hasLength!(Range1) && hasLength!(Range2);\n    static if (haveLen) assert(a.length == b.length);\n    Unqual!(typeof(return)) result = 0;\n    for (; !a.empty; a.popFront(), b.popFront())\n    {\n        immutable t = a.front - b.front;\n        result += t * t;\n    }\n    static if (!haveLen) assert(b.empty);\n    return sqrt(result);\n}\n\n/// Ditto\nCommonType!(ElementType!(Range1), ElementType!(Range2))\neuclideanDistance(Range1, Range2, F)(Range1 a, Range2 b, F limit)\nif (isInputRange!(Range1) && isInputRange!(Range2))\n{\n    limit *= limit;\n    enum bool haveLen = hasLength!(Range1) && hasLength!(Range2);\n    static if (haveLen) assert(a.length == b.length);\n    Unqual!(typeof(return)) result = 0;\n    for (; ; a.popFront(), b.popFront())\n    {\n        if (a.empty)\n        {\n            static if (!haveLen) assert(b.empty);\n            break;\n        }\n        immutable t = a.front - b.front;\n        result += t * t;\n        if (result >= limit) break;\n    }\n    return sqrt(result);\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(double, const double, immutable double))\n    {{\n        T[] a = [ 1.0, 2.0, ];\n        T[] b = [ 4.0, 6.0, ];\n        assert(euclideanDistance(a, b) == 5);\n        assert(euclideanDistance(a, b, 5) == 5);\n        assert(euclideanDistance(a, b, 4) == 5);\n        assert(euclideanDistance(a, b, 2) == 3);\n    }}\n}\n\n/**\nComputes the $(LINK2 https://en.wikipedia.org/wiki/Dot_product,\ndot product) of input ranges `a` and $(D\nb). The two ranges must have the same length. If both ranges define\nlength, the check is done once; otherwise, it is done at each\niteration.\n */\nCommonType!(ElementType!(Range1), ElementType!(Range2))\ndotProduct(Range1, Range2)(Range1 a, Range2 b)\nif (isInputRange!(Range1) && isInputRange!(Range2) &&\n    !(isArray!(Range1) && isArray!(Range2)))\n{\n    enum bool haveLen = hasLength!(Range1) && hasLength!(Range2);\n    static if (haveLen) assert(a.length == b.length);\n    Unqual!(typeof(return)) result = 0;\n    for (; !a.empty; a.popFront(), b.popFront())\n    {\n        result += a.front * b.front;\n    }\n    static if (!haveLen) assert(b.empty);\n    return result;\n}\n\n/// Ditto\nCommonType!(F1, F2)\ndotProduct(F1, F2)(in F1[] avector, in F2[] bvector)\n{\n    immutable n = avector.length;\n    assert(n == bvector.length);\n    auto avec = avector.ptr, bvec = bvector.ptr;\n    Unqual!(typeof(return)) sum0 = 0, sum1 = 0;\n\n    const all_endp = avec + n;\n    const smallblock_endp = avec + (n & ~3);\n    const bigblock_endp = avec + (n & ~15);\n\n    for (; avec != bigblock_endp; avec += 16, bvec += 16)\n    {\n        sum0 += avec[0] * bvec[0];\n        sum1 += avec[1] * bvec[1];\n        sum0 += avec[2] * bvec[2];\n        sum1 += avec[3] * bvec[3];\n        sum0 += avec[4] * bvec[4];\n        sum1 += avec[5] * bvec[5];\n        sum0 += avec[6] * bvec[6];\n        sum1 += avec[7] * bvec[7];\n        sum0 += avec[8] * bvec[8];\n        sum1 += avec[9] * bvec[9];\n        sum0 += avec[10] * bvec[10];\n        sum1 += avec[11] * bvec[11];\n        sum0 += avec[12] * bvec[12];\n        sum1 += avec[13] * bvec[13];\n        sum0 += avec[14] * bvec[14];\n        sum1 += avec[15] * bvec[15];\n    }\n\n    for (; avec != smallblock_endp; avec += 4, bvec += 4)\n    {\n        sum0 += avec[0] * bvec[0];\n        sum1 += avec[1] * bvec[1];\n        sum0 += avec[2] * bvec[2];\n        sum1 += avec[3] * bvec[3];\n    }\n\n    sum0 += sum1;\n\n    /* Do trailing portion in naive loop. */\n    while (avec != all_endp)\n    {\n        sum0 += *avec * *bvec;\n        ++avec;\n        ++bvec;\n    }\n\n    return sum0;\n}\n\n@system unittest\n{\n    // @system due to dotProduct and assertCTFEable\n    import std.exception : assertCTFEable;\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(double, const double, immutable double))\n    {{\n        T[] a = [ 1.0, 2.0, ];\n        T[] b = [ 4.0, 6.0, ];\n        assert(dotProduct(a, b) == 16);\n        assert(dotProduct([1, 3, -5], [4, -2, -1]) == 3);\n    }}\n\n    // Make sure the unrolled loop codepath gets tested.\n    static const x =\n        [1.0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];\n    static const y =\n        [2.0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];\n    assertCTFEable!({ assert(dotProduct(x, y) == 2280); });\n}\n\n/**\nComputes the $(LINK2 https://en.wikipedia.org/wiki/Cosine_similarity,\ncosine similarity) of input ranges `a` and $(D\nb). The two ranges must have the same length. If both ranges define\nlength, the check is done once; otherwise, it is done at each\niteration. If either range has all-zero elements, return 0.\n */\nCommonType!(ElementType!(Range1), ElementType!(Range2))\ncosineSimilarity(Range1, Range2)(Range1 a, Range2 b)\nif (isInputRange!(Range1) && isInputRange!(Range2))\n{\n    enum bool haveLen = hasLength!(Range1) && hasLength!(Range2);\n    static if (haveLen) assert(a.length == b.length);\n    Unqual!(typeof(return)) norma = 0, normb = 0, dotprod = 0;\n    for (; !a.empty; a.popFront(), b.popFront())\n    {\n        immutable t1 = a.front, t2 = b.front;\n        norma += t1 * t1;\n        normb += t2 * t2;\n        dotprod += t1 * t2;\n    }\n    static if (!haveLen) assert(b.empty);\n    if (norma == 0 || normb == 0) return 0;\n    return dotprod / sqrt(norma * normb);\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(double, const double, immutable double))\n    {{\n        T[] a = [ 1.0, 2.0, ];\n        T[] b = [ 4.0, 3.0, ];\n        assert(approxEqual(\n                    cosineSimilarity(a, b), 10.0 / sqrt(5.0 * 25),\n                    0.01));\n    }}\n}\n\n/**\nNormalizes values in `range` by multiplying each element with a\nnumber chosen such that values sum up to `sum`. If elements in $(D\nrange) sum to zero, assigns $(D sum / range.length) to\nall. Normalization makes sense only if all elements in `range` are\npositive. `normalize` assumes that is the case without checking it.\n\nReturns: `true` if normalization completed normally, `false` if\nall elements in `range` were zero or if `range` is empty.\n */\nbool normalize(R)(R range, ElementType!(R) sum = 1)\nif (isForwardRange!(R))\n{\n    ElementType!(R) s = 0;\n    // Step 1: Compute sum and length of the range\n    static if (hasLength!(R))\n    {\n        const length = range.length;\n        foreach (e; range)\n        {\n            s += e;\n        }\n    }\n    else\n    {\n        uint length = 0;\n        foreach (e; range)\n        {\n            s += e;\n            ++length;\n        }\n    }\n    // Step 2: perform normalization\n    if (s == 0)\n    {\n        if (length)\n        {\n            immutable f = sum / range.length;\n            foreach (ref e; range) e = f;\n        }\n        return false;\n    }\n    // The path most traveled\n    assert(s >= 0);\n    immutable f = sum / s;\n    foreach (ref e; range)\n        e *= f;\n    return true;\n}\n\n///\n@safe unittest\n{\n    double[] a = [];\n    assert(!normalize(a));\n    a = [ 1.0, 3.0 ];\n    assert(normalize(a));\n    assert(a == [ 0.25, 0.75 ]);\n    a = [ 0.0, 0.0 ];\n    assert(!normalize(a));\n    assert(a == [ 0.5, 0.5 ]);\n}\n\n/**\nCompute the sum of binary logarithms of the input range `r`.\nThe error of this method is much smaller than with a naive sum of log2.\n */\nElementType!Range sumOfLog2s(Range)(Range r)\nif (isInputRange!Range && isFloatingPoint!(ElementType!Range))\n{\n    long exp = 0;\n    Unqual!(typeof(return)) x = 1;\n    foreach (e; r)\n    {\n        if (e < 0)\n            return typeof(return).nan;\n        int lexp = void;\n        x *= frexp(e, lexp);\n        exp += lexp;\n        if (x < 0.5)\n        {\n            x *= 2;\n            exp--;\n        }\n    }\n    return exp + log2(x);\n}\n\n///\n@safe unittest\n{\n    import std.math : isNaN;\n\n    assert(sumOfLog2s(new double[0]) == 0);\n    assert(sumOfLog2s([0.0L]) == -real.infinity);\n    assert(sumOfLog2s([-0.0L]) == -real.infinity);\n    assert(sumOfLog2s([2.0L]) == 1);\n    assert(sumOfLog2s([-2.0L]).isNaN());\n    assert(sumOfLog2s([real.nan]).isNaN());\n    assert(sumOfLog2s([-real.nan]).isNaN());\n    assert(sumOfLog2s([real.infinity]) == real.infinity);\n    assert(sumOfLog2s([-real.infinity]).isNaN());\n    assert(sumOfLog2s([ 0.25, 0.25, 0.25, 0.125 ]) == -9);\n}\n\n/**\nComputes $(LINK2 https://en.wikipedia.org/wiki/Entropy_(information_theory),\n_entropy) of input range `r` in bits. This\nfunction assumes (without checking) that the values in `r` are all\nin $(D [0, 1]). For the entropy to be meaningful, often `r` should\nbe normalized too (i.e., its values should sum to 1). The\ntwo-parameter version stops evaluating as soon as the intermediate\nresult is greater than or equal to `max`.\n */\nElementType!Range entropy(Range)(Range r)\nif (isInputRange!Range)\n{\n    Unqual!(typeof(return)) result = 0.0;\n    for (;!r.empty; r.popFront)\n    {\n        if (!r.front) continue;\n        result -= r.front * log2(r.front);\n    }\n    return result;\n}\n\n/// Ditto\nElementType!Range entropy(Range, F)(Range r, F max)\nif (isInputRange!Range &&\n    !is(CommonType!(ElementType!Range, F) == void))\n{\n    Unqual!(typeof(return)) result = 0.0;\n    for (;!r.empty; r.popFront)\n    {\n        if (!r.front) continue;\n        result -= r.front * log2(r.front);\n        if (result >= max) break;\n    }\n    return result;\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(double, const double, immutable double))\n    {{\n        T[] p = [ 0.0, 0, 0, 1 ];\n        assert(entropy(p) == 0);\n        p = [ 0.25, 0.25, 0.25, 0.25 ];\n        assert(entropy(p) == 2);\n        assert(entropy(p, 1) == 1);\n    }}\n}\n\n/**\nComputes the $(LINK2 https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence,\nKullback-Leibler divergence) between input ranges\n`a` and `b`, which is the sum $(D ai * log(ai / bi)). The base\nof logarithm is 2. The ranges are assumed to contain elements in $(D\n[0, 1]). Usually the ranges are normalized probability distributions,\nbut this is not required or checked by $(D\nkullbackLeiblerDivergence). If any element `bi` is zero and the\ncorresponding element `ai` nonzero, returns infinity. (Otherwise,\nif $(D ai == 0 && bi == 0), the term $(D ai * log(ai / bi)) is\nconsidered zero.) If the inputs are normalized, the result is\npositive.\n */\nCommonType!(ElementType!Range1, ElementType!Range2)\nkullbackLeiblerDivergence(Range1, Range2)(Range1 a, Range2 b)\nif (isInputRange!(Range1) && isInputRange!(Range2))\n{\n    enum bool haveLen = hasLength!(Range1) && hasLength!(Range2);\n    static if (haveLen) assert(a.length == b.length);\n    Unqual!(typeof(return)) result = 0;\n    for (; !a.empty; a.popFront(), b.popFront())\n    {\n        immutable t1 = a.front;\n        if (t1 == 0) continue;\n        immutable t2 = b.front;\n        if (t2 == 0) return result.infinity;\n        assert(t1 > 0 && t2 > 0);\n        result += t1 * log2(t1 / t2);\n    }\n    static if (!haveLen) assert(b.empty);\n    return result;\n}\n\n///\n@safe unittest\n{\n    import std.math : approxEqual;\n\n    double[] p = [ 0.0, 0, 0, 1 ];\n    assert(kullbackLeiblerDivergence(p, p) == 0);\n    double[] p1 = [ 0.25, 0.25, 0.25, 0.25 ];\n    assert(kullbackLeiblerDivergence(p1, p1) == 0);\n    assert(kullbackLeiblerDivergence(p, p1) == 2);\n    assert(kullbackLeiblerDivergence(p1, p) == double.infinity);\n    double[] p2 = [ 0.2, 0.2, 0.2, 0.4 ];\n    assert(approxEqual(kullbackLeiblerDivergence(p1, p2), 0.0719281));\n    assert(approxEqual(kullbackLeiblerDivergence(p2, p1), 0.0780719));\n}\n\n/**\nComputes the $(LINK2 https://en.wikipedia.org/wiki/Jensen%E2%80%93Shannon_divergence,\nJensen-Shannon divergence) between `a` and $(D\nb), which is the sum $(D (ai * log(2 * ai / (ai + bi)) + bi * log(2 *\nbi / (ai + bi))) / 2). The base of logarithm is 2. The ranges are\nassumed to contain elements in $(D [0, 1]). Usually the ranges are\nnormalized probability distributions, but this is not required or\nchecked by `jensenShannonDivergence`. If the inputs are normalized,\nthe result is bounded within $(D [0, 1]). The three-parameter version\nstops evaluations as soon as the intermediate result is greater than\nor equal to `limit`.\n */\nCommonType!(ElementType!Range1, ElementType!Range2)\njensenShannonDivergence(Range1, Range2)(Range1 a, Range2 b)\nif (isInputRange!Range1 && isInputRange!Range2 &&\n    is(CommonType!(ElementType!Range1, ElementType!Range2)))\n{\n    enum bool haveLen = hasLength!(Range1) && hasLength!(Range2);\n    static if (haveLen) assert(a.length == b.length);\n    Unqual!(typeof(return)) result = 0;\n    for (; !a.empty; a.popFront(), b.popFront())\n    {\n        immutable t1 = a.front;\n        immutable t2 = b.front;\n        immutable avg = (t1 + t2) / 2;\n        if (t1 != 0)\n        {\n            result += t1 * log2(t1 / avg);\n        }\n        if (t2 != 0)\n        {\n            result += t2 * log2(t2 / avg);\n        }\n    }\n    static if (!haveLen) assert(b.empty);\n    return result / 2;\n}\n\n/// Ditto\nCommonType!(ElementType!Range1, ElementType!Range2)\njensenShannonDivergence(Range1, Range2, F)(Range1 a, Range2 b, F limit)\nif (isInputRange!Range1 && isInputRange!Range2 &&\n    is(typeof(CommonType!(ElementType!Range1, ElementType!Range2).init\n    >= F.init) : bool))\n{\n    enum bool haveLen = hasLength!(Range1) && hasLength!(Range2);\n    static if (haveLen) assert(a.length == b.length);\n    Unqual!(typeof(return)) result = 0;\n    limit *= 2;\n    for (; !a.empty; a.popFront(), b.popFront())\n    {\n        immutable t1 = a.front;\n        immutable t2 = b.front;\n        immutable avg = (t1 + t2) / 2;\n        if (t1 != 0)\n        {\n            result += t1 * log2(t1 / avg);\n        }\n        if (t2 != 0)\n        {\n            result += t2 * log2(t2 / avg);\n        }\n        if (result >= limit) break;\n    }\n    static if (!haveLen) assert(b.empty);\n    return result / 2;\n}\n\n///\n@safe unittest\n{\n    import std.math : approxEqual;\n\n    double[] p = [ 0.0, 0, 0, 1 ];\n    assert(jensenShannonDivergence(p, p) == 0);\n    double[] p1 = [ 0.25, 0.25, 0.25, 0.25 ];\n    assert(jensenShannonDivergence(p1, p1) == 0);\n    assert(approxEqual(jensenShannonDivergence(p1, p), 0.548795));\n    double[] p2 = [ 0.2, 0.2, 0.2, 0.4 ];\n    assert(approxEqual(jensenShannonDivergence(p1, p2), 0.0186218));\n    assert(approxEqual(jensenShannonDivergence(p2, p1), 0.0186218));\n    assert(approxEqual(jensenShannonDivergence(p2, p1, 0.005), 0.00602366));\n}\n\n/**\nThe so-called \"all-lengths gap-weighted string kernel\" computes a\nsimilarity measure between `s` and `t` based on all of their\ncommon subsequences of all lengths. Gapped subsequences are also\nincluded.\n\nTo understand what $(D gapWeightedSimilarity(s, t, lambda)) computes,\nconsider first the case $(D lambda = 1) and the strings $(D s =\n[\"Hello\", \"brave\", \"new\", \"world\"]) and $(D t = [\"Hello\", \"new\",\n\"world\"]). In that case, `gapWeightedSimilarity` counts the\nfollowing matches:\n\n$(OL $(LI three matches of length 1, namely `\"Hello\"`, `\"new\"`,\nand `\"world\"`;) $(LI three matches of length 2, namely ($(D\n\"Hello\", \"new\")), ($(D \"Hello\", \"world\")), and ($(D \"new\", \"world\"));)\n$(LI one match of length 3, namely ($(D \"Hello\", \"new\", \"world\")).))\n\nThe call $(D gapWeightedSimilarity(s, t, 1)) simply counts all of\nthese matches and adds them up, returning 7.\n\n----\nstring[] s = [\"Hello\", \"brave\", \"new\", \"world\"];\nstring[] t = [\"Hello\", \"new\", \"world\"];\nassert(gapWeightedSimilarity(s, t, 1) == 7);\n----\n\nNote how the gaps in matching are simply ignored, for example ($(D\n\"Hello\", \"new\")) is deemed as good a match as ($(D \"new\",\n\"world\")). This may be too permissive for some applications. To\neliminate gapped matches entirely, use $(D lambda = 0):\n\n----\nstring[] s = [\"Hello\", \"brave\", \"new\", \"world\"];\nstring[] t = [\"Hello\", \"new\", \"world\"];\nassert(gapWeightedSimilarity(s, t, 0) == 4);\n----\n\nThe call above eliminated the gapped matches ($(D \"Hello\", \"new\")),\n($(D \"Hello\", \"world\")), and ($(D \"Hello\", \"new\", \"world\")) from the\ntally. That leaves only 4 matches.\n\nThe most interesting case is when gapped matches still participate in\nthe result, but not as strongly as ungapped matches. The result will\nbe a smooth, fine-grained similarity measure between the input\nstrings. This is where values of `lambda` between 0 and 1 enter\ninto play: gapped matches are $(I exponentially penalized with the\nnumber of gaps) with base `lambda`. This means that an ungapped\nmatch adds 1 to the return value; a match with one gap in either\nstring adds `lambda` to the return value; ...; a match with a total\nof `n` gaps in both strings adds $(D pow(lambda, n)) to the return\nvalue. In the example above, we have 4 matches without gaps, 2 matches\nwith one gap, and 1 match with three gaps. The latter match is ($(D\n\"Hello\", \"world\")), which has two gaps in the first string and one gap\nin the second string, totaling to three gaps. Summing these up we get\n$(D 4 + 2 * lambda + pow(lambda, 3)).\n\n----\nstring[] s = [\"Hello\", \"brave\", \"new\", \"world\"];\nstring[] t = [\"Hello\", \"new\", \"world\"];\nassert(gapWeightedSimilarity(s, t, 0.5) == 4 + 0.5 * 2 + 0.125);\n----\n\n`gapWeightedSimilarity` is useful wherever a smooth similarity\nmeasure between sequences allowing for approximate matches is\nneeded. The examples above are given with words, but any sequences\nwith elements comparable for equality are allowed, e.g. characters or\nnumbers. `gapWeightedSimilarity` uses a highly optimized dynamic\nprogramming implementation that needs $(D 16 * min(s.length,\nt.length)) extra bytes of memory and $(BIGOH s.length * t.length) time\nto complete.\n */\nF gapWeightedSimilarity(alias comp = \"a == b\", R1, R2, F)(R1 s, R2 t, F lambda)\nif (isRandomAccessRange!(R1) && hasLength!(R1) &&\n    isRandomAccessRange!(R2) && hasLength!(R2))\n{\n    import core.exception : onOutOfMemoryError;\n    import core.stdc.stdlib : malloc, free;\n    import std.algorithm.mutation : swap;\n    import std.functional : binaryFun;\n\n    if (s.length < t.length) return gapWeightedSimilarity(t, s, lambda);\n    if (!t.length) return 0;\n\n    auto dpvi = cast(F*) malloc(F.sizeof * 2 * t.length);\n    if (!dpvi)\n        onOutOfMemoryError();\n\n    auto dpvi1 = dpvi + t.length;\n    scope(exit) free(dpvi < dpvi1 ? dpvi : dpvi1);\n    dpvi[0 .. t.length] = 0;\n    dpvi1[0] = 0;\n    immutable lambda2 = lambda * lambda;\n\n    F result = 0;\n    foreach (i; 0 .. s.length)\n    {\n        const si = s[i];\n        for (size_t j = 0;;)\n        {\n            F dpsij = void;\n            if (binaryFun!(comp)(si, t[j]))\n            {\n                dpsij = 1 + dpvi[j];\n                result += dpsij;\n            }\n            else\n            {\n                dpsij = 0;\n            }\n            immutable j1 = j + 1;\n            if (j1 == t.length) break;\n            dpvi1[j1] = dpsij + lambda * (dpvi1[j] + dpvi[j1]) -\n                        lambda2 * dpvi[j];\n            j = j1;\n        }\n        swap(dpvi, dpvi1);\n    }\n    return result;\n}\n\n@system unittest\n{\n    string[] s = [\"Hello\", \"brave\", \"new\", \"world\"];\n    string[] t = [\"Hello\", \"new\", \"world\"];\n    assert(gapWeightedSimilarity(s, t, 1) == 7);\n    assert(gapWeightedSimilarity(s, t, 0) == 4);\n    assert(gapWeightedSimilarity(s, t, 0.5) == 4 + 2 * 0.5 + 0.125);\n}\n\n/**\nThe similarity per `gapWeightedSimilarity` has an issue in that it\ngrows with the lengths of the two strings, even though the strings are\nnot actually very similar. For example, the range $(D [\"Hello\",\n\"world\"]) is increasingly similar with the range $(D [\"Hello\",\n\"world\", \"world\", \"world\",...]) as more instances of `\"world\"` are\nappended. To prevent that, `gapWeightedSimilarityNormalized`\ncomputes a normalized version of the similarity that is computed as\n$(D gapWeightedSimilarity(s, t, lambda) /\nsqrt(gapWeightedSimilarity(s, t, lambda) * gapWeightedSimilarity(s, t,\nlambda))). The function `gapWeightedSimilarityNormalized` (a\nso-called normalized kernel) is bounded in $(D [0, 1]), reaches `0`\nonly for ranges that don't match in any position, and `1` only for\nidentical ranges.\n\nThe optional parameters `sSelfSim` and `tSelfSim` are meant for\navoiding duplicate computation. Many applications may have already\ncomputed $(D gapWeightedSimilarity(s, s, lambda)) and/or $(D\ngapWeightedSimilarity(t, t, lambda)). In that case, they can be passed\nas `sSelfSim` and `tSelfSim`, respectively.\n */\nSelect!(isFloatingPoint!(F), F, double)\ngapWeightedSimilarityNormalized(alias comp = \"a == b\", R1, R2, F)\n        (R1 s, R2 t, F lambda, F sSelfSim = F.init, F tSelfSim = F.init)\nif (isRandomAccessRange!(R1) && hasLength!(R1) &&\n    isRandomAccessRange!(R2) && hasLength!(R2))\n{\n    static bool uncomputed(F n)\n    {\n        static if (isFloatingPoint!(F))\n            return isNaN(n);\n        else\n            return n == n.init;\n    }\n    if (uncomputed(sSelfSim))\n        sSelfSim = gapWeightedSimilarity!(comp)(s, s, lambda);\n    if (sSelfSim == 0) return 0;\n    if (uncomputed(tSelfSim))\n        tSelfSim = gapWeightedSimilarity!(comp)(t, t, lambda);\n    if (tSelfSim == 0) return 0;\n\n    return gapWeightedSimilarity!(comp)(s, t, lambda) /\n           sqrt(cast(typeof(return)) sSelfSim * tSelfSim);\n}\n\n///\n@system unittest\n{\n    import std.math : approxEqual, sqrt;\n\n    string[] s = [\"Hello\", \"brave\", \"new\", \"world\"];\n    string[] t = [\"Hello\", \"new\", \"world\"];\n    assert(gapWeightedSimilarity(s, s, 1) == 15);\n    assert(gapWeightedSimilarity(t, t, 1) == 7);\n    assert(gapWeightedSimilarity(s, t, 1) == 7);\n    assert(approxEqual(gapWeightedSimilarityNormalized(s, t, 1),\n                    7.0 / sqrt(15.0 * 7), 0.01));\n}\n\n/**\nSimilar to `gapWeightedSimilarity`, just works in an incremental\nmanner by first revealing the matches of length 1, then gapped matches\nof length 2, and so on. The memory requirement is $(BIGOH s.length *\nt.length). The time complexity is $(BIGOH s.length * t.length) time\nfor computing each step. Continuing on the previous example:\n\nThe implementation is based on the pseudocode in Fig. 4 of the paper\n$(HTTP jmlr.csail.mit.edu/papers/volume6/rousu05a/rousu05a.pdf,\n\"Efﬁcient Computation of Gapped Substring Kernels on Large Alphabets\")\nby Rousu et al., with additional algorithmic and systems-level\noptimizations.\n */\nstruct GapWeightedSimilarityIncremental(Range, F = double)\nif (isRandomAccessRange!(Range) && hasLength!(Range))\n{\n    import core.stdc.stdlib : malloc, realloc, alloca, free;\n\nprivate:\n    Range s, t;\n    F currentValue = 0;\n    F* kl;\n    size_t gram = void;\n    F lambda = void, lambda2 = void;\n\npublic:\n/**\nConstructs an object given two ranges `s` and `t` and a penalty\n`lambda`. Constructor completes in $(BIGOH s.length * t.length)\ntime and computes all matches of length 1.\n */\n    this(Range s, Range t, F lambda)\n    {\n        import core.exception : onOutOfMemoryError;\n\n        assert(lambda > 0);\n        this.gram = 0;\n        this.lambda = lambda;\n        this.lambda2 = lambda * lambda; // for efficiency only\n\n        size_t iMin = size_t.max, jMin = size_t.max,\n            iMax = 0, jMax = 0;\n        /* initialize */\n        Tuple!(size_t, size_t) * k0;\n        size_t k0len;\n        scope(exit) free(k0);\n        currentValue = 0;\n        foreach (i, si; s)\n        {\n            foreach (j; 0 .. t.length)\n            {\n                if (si != t[j]) continue;\n                k0 = cast(typeof(k0)) realloc(k0, ++k0len * (*k0).sizeof);\n                with (k0[k0len - 1])\n                {\n                    field[0] = i;\n                    field[1] = j;\n                }\n                // Maintain the minimum and maximum i and j\n                if (iMin > i) iMin = i;\n                if (iMax < i) iMax = i;\n                if (jMin > j) jMin = j;\n                if (jMax < j) jMax = j;\n            }\n        }\n\n        if (iMin > iMax) return;\n        assert(k0len);\n\n        currentValue = k0len;\n        // Chop strings down to the useful sizes\n        s = s[iMin .. iMax + 1];\n        t = t[jMin .. jMax + 1];\n        this.s = s;\n        this.t = t;\n\n        kl = cast(F*) malloc(s.length * t.length * F.sizeof);\n        if (!kl)\n            onOutOfMemoryError();\n\n        kl[0 .. s.length * t.length] = 0;\n        foreach (pos; 0 .. k0len)\n        {\n            with (k0[pos])\n            {\n                kl[(field[0] - iMin) * t.length + field[1] -jMin] = lambda2;\n            }\n        }\n    }\n\n    /**\n    Returns: `this`.\n     */\n    ref GapWeightedSimilarityIncremental opSlice()\n    {\n        return this;\n    }\n\n    /**\n    Computes the match of the popFront length. Completes in $(BIGOH s.length *\n    t.length) time.\n     */\n    void popFront()\n    {\n        import std.algorithm.mutation : swap;\n\n        // This is a large source of optimization: if similarity at\n        // the gram-1 level was 0, then we can safely assume\n        // similarity at the gram level is 0 as well.\n        if (empty) return;\n\n        // Now attempt to match gapped substrings of length `gram'\n        ++gram;\n        currentValue = 0;\n\n        auto Si = cast(F*) alloca(t.length * F.sizeof);\n        Si[0 .. t.length] = 0;\n        foreach (i; 0 .. s.length)\n        {\n            const si = s[i];\n            F Sij_1 = 0;\n            F Si_1j_1 = 0;\n            auto kli = kl + i * t.length;\n            for (size_t j = 0;;)\n            {\n                const klij = kli[j];\n                const Si_1j = Si[j];\n                const tmp = klij + lambda * (Si_1j + Sij_1) - lambda2 * Si_1j_1;\n                // now update kl and currentValue\n                if (si == t[j])\n                    currentValue += kli[j] = lambda2 * Si_1j_1;\n                else\n                    kli[j] = 0;\n                // commit to Si\n                Si[j] = tmp;\n                if (++j == t.length) break;\n                // get ready for the popFront step; virtually increment j,\n                // so essentially stuffj_1 <-- stuffj\n                Si_1j_1 = Si_1j;\n                Sij_1 = tmp;\n            }\n        }\n        currentValue /= pow(lambda, 2 * (gram + 1));\n\n        version (none)\n        {\n            Si_1[0 .. t.length] = 0;\n            kl[0 .. min(t.length, maxPerimeter + 1)] = 0;\n            foreach (i; 1 .. min(s.length, maxPerimeter + 1))\n            {\n                auto kli = kl + i * t.length;\n                assert(s.length > i);\n                const si = s[i];\n                auto kl_1i_1 = kl_1 + (i - 1) * t.length;\n                kli[0] = 0;\n                F lastS = 0;\n                foreach (j; 1 .. min(maxPerimeter - i + 1, t.length))\n                {\n                    immutable j_1 = j - 1;\n                    immutable tmp = kl_1i_1[j_1]\n                        + lambda * (Si_1[j] + lastS)\n                        - lambda2 * Si_1[j_1];\n                    kl_1i_1[j_1] = float.nan;\n                    Si_1[j_1] = lastS;\n                    lastS = tmp;\n                    if (si == t[j])\n                    {\n                        currentValue += kli[j] = lambda2 * lastS;\n                    }\n                    else\n                    {\n                        kli[j] = 0;\n                    }\n                }\n                Si_1[t.length - 1] = lastS;\n            }\n            currentValue /= pow(lambda, 2 * (gram + 1));\n            // get ready for the popFront computation\n            swap(kl, kl_1);\n        }\n    }\n\n    /**\n    Returns: The gapped similarity at the current match length (initially\n    1, grows with each call to `popFront`).\n    */\n    @property F front() { return currentValue; }\n\n    /**\n    Returns: Whether there are more matches.\n     */\n    @property bool empty()\n    {\n        if (currentValue) return false;\n        if (kl)\n        {\n            free(kl);\n            kl = null;\n        }\n        return true;\n    }\n}\n\n/**\nDitto\n */\nGapWeightedSimilarityIncremental!(R, F) gapWeightedSimilarityIncremental(R, F)\n(R r1, R r2, F penalty)\n{\n    return typeof(return)(r1, r2, penalty);\n}\n\n///\n@system unittest\n{\n    string[] s = [\"Hello\", \"brave\", \"new\", \"world\"];\n    string[] t = [\"Hello\", \"new\", \"world\"];\n    auto simIter = gapWeightedSimilarityIncremental(s, t, 1.0);\n    assert(simIter.front == 3); // three 1-length matches\n    simIter.popFront();\n    assert(simIter.front == 3); // three 2-length matches\n    simIter.popFront();\n    assert(simIter.front == 1); // one 3-length match\n    simIter.popFront();\n    assert(simIter.empty);     // no more match\n}\n\n@system unittest\n{\n    import std.conv : text;\n    string[] s = [\"Hello\", \"brave\", \"new\", \"world\"];\n    string[] t = [\"Hello\", \"new\", \"world\"];\n    auto simIter = gapWeightedSimilarityIncremental(s, t, 1.0);\n    //foreach (e; simIter) writeln(e);\n    assert(simIter.front == 3); // three 1-length matches\n    simIter.popFront();\n    assert(simIter.front == 3, text(simIter.front)); // three 2-length matches\n    simIter.popFront();\n    assert(simIter.front == 1); // one 3-length matches\n    simIter.popFront();\n    assert(simIter.empty);     // no more match\n\n    s = [\"Hello\"];\n    t = [\"bye\"];\n    simIter = gapWeightedSimilarityIncremental(s, t, 0.5);\n    assert(simIter.empty);\n\n    s = [\"Hello\"];\n    t = [\"Hello\"];\n    simIter = gapWeightedSimilarityIncremental(s, t, 0.5);\n    assert(simIter.front == 1); // one match\n    simIter.popFront();\n    assert(simIter.empty);\n\n    s = [\"Hello\", \"world\"];\n    t = [\"Hello\"];\n    simIter = gapWeightedSimilarityIncremental(s, t, 0.5);\n    assert(simIter.front == 1); // one match\n    simIter.popFront();\n    assert(simIter.empty);\n\n    s = [\"Hello\", \"world\"];\n    t = [\"Hello\", \"yah\", \"world\"];\n    simIter = gapWeightedSimilarityIncremental(s, t, 0.5);\n    assert(simIter.front == 2); // two 1-gram matches\n    simIter.popFront();\n    assert(simIter.front == 0.5, text(simIter.front)); // one 2-gram match, 1 gap\n}\n\n@system unittest\n{\n    GapWeightedSimilarityIncremental!(string[]) sim =\n        GapWeightedSimilarityIncremental!(string[])(\n            [\"nyuk\", \"I\", \"have\", \"no\", \"chocolate\", \"giba\"],\n            [\"wyda\", \"I\", \"have\", \"I\", \"have\", \"have\", \"I\", \"have\", \"hehe\"],\n            0.5);\n    double[] witness = [ 7.0, 4.03125, 0, 0 ];\n    foreach (e; sim)\n    {\n        //writeln(e);\n        assert(e == witness.front);\n        witness.popFront();\n    }\n    witness = [ 3.0, 1.3125, 0.25 ];\n    sim = GapWeightedSimilarityIncremental!(string[])(\n        [\"I\", \"have\", \"no\", \"chocolate\"],\n        [\"I\", \"have\", \"some\", \"chocolate\"],\n        0.5);\n    foreach (e; sim)\n    {\n        //writeln(e);\n        assert(e == witness.front);\n        witness.popFront();\n    }\n    assert(witness.empty);\n}\n\n/**\nComputes the greatest common divisor of `a` and `b` by using\nan efficient algorithm such as $(HTTPS en.wikipedia.org/wiki/Euclidean_algorithm, Euclid's)\nor $(HTTPS en.wikipedia.org/wiki/Binary_GCD_algorithm, Stein's) algorithm.\n\nParams:\n    T = Any numerical type that supports the modulo operator `%`. If\n        bit-shifting `<<` and `>>` are also supported, Stein's algorithm will\n        be used; otherwise, Euclid's algorithm is used as _a fallback.\nReturns:\n    The greatest common divisor of the given arguments.\n */\nT gcd(T)(T a, T b)\nif (isIntegral!T)\n{\n    static if (is(T == const) || is(T == immutable))\n    {\n        return gcd!(Unqual!T)(a, b);\n    }\n    else version (DigitalMars)\n    {\n        static if (T.min < 0)\n        {\n            assert(a >= 0 && b >= 0);\n        }\n        while (b)\n        {\n            immutable t = b;\n            b = a % b;\n            a = t;\n        }\n        return a;\n    }\n    else\n    {\n        if (a == 0)\n            return b;\n        if (b == 0)\n            return a;\n\n        import core.bitop : bsf;\n        import std.algorithm.mutation : swap;\n\n        immutable uint shift = bsf(a | b);\n        a >>= a.bsf;\n\n        do\n        {\n            b >>= b.bsf;\n            if (a > b)\n                swap(a, b);\n            b -= a;\n        } while (b);\n\n        return a << shift;\n    }\n}\n\n///\n@safe unittest\n{\n    assert(gcd(2 * 5 * 7 * 7, 5 * 7 * 11) == 5 * 7);\n    const int a = 5 * 13 * 23 * 23, b = 13 * 59;\n    assert(gcd(a, b) == 13);\n}\n\n// This overload is for non-builtin numerical types like BigInt or\n// user-defined types.\n/// ditto\nT gcd(T)(T a, T b)\nif (!isIntegral!T &&\n        is(typeof(T.init % T.init)) &&\n        is(typeof(T.init == 0 || T.init > 0)))\n{\n    import std.algorithm.mutation : swap;\n\n    enum canUseBinaryGcd = is(typeof(() {\n        T t, u;\n        t <<= 1;\n        t >>= 1;\n        t -= u;\n        bool b = (t & 1) == 0;\n        swap(t, u);\n    }));\n\n    assert(a >= 0 && b >= 0);\n\n    // Special cases.\n    if (a == 0)\n        return b;\n    if (b == 0)\n        return a;\n\n    static if (canUseBinaryGcd)\n    {\n        uint shift = 0;\n        while ((a & 1) == 0 && (b & 1) == 0)\n        {\n            a >>= 1;\n            b >>= 1;\n            shift++;\n        }\n\n        do\n        {\n            assert((a & 1) != 0);\n            while ((b & 1) == 0)\n                b >>= 1;\n            if (a > b)\n                swap(a, b);\n            b -= a;\n        } while (b);\n\n        return a << shift;\n    }\n    else\n    {\n        // The only thing we have is %; fallback to Euclidean algorithm.\n        while (b != 0)\n        {\n            auto t = b;\n            b = a % b;\n            a = t;\n        }\n        return a;\n    }\n}\n\n// Issue 7102\n@system pure unittest\n{\n    import std.bigint : BigInt;\n    assert(gcd(BigInt(\"71_000_000_000_000_000_000\"),\n               BigInt(\"31_000_000_000_000_000_000\")) ==\n           BigInt(\"1_000_000_000_000_000_000\"));\n\n    assert(gcd(BigInt(0), BigInt(1234567)) == BigInt(1234567));\n    assert(gcd(BigInt(1234567), BigInt(0)) == BigInt(1234567));\n}\n\n@safe pure nothrow unittest\n{\n    // A numerical type that only supports % and - (to force gcd implementation\n    // to use Euclidean algorithm).\n    struct CrippledInt\n    {\n        int impl;\n        CrippledInt opBinary(string op : \"%\")(CrippledInt i)\n        {\n            return CrippledInt(impl % i.impl);\n        }\n        int opEquals(CrippledInt i) { return impl == i.impl; }\n        int opEquals(int i) { return impl == i; }\n        int opCmp(int i) { return (impl < i) ? -1 : (impl > i) ? 1 : 0; }\n    }\n    assert(gcd(CrippledInt(2310), CrippledInt(1309)) == CrippledInt(77));\n}\n\n// This is to make tweaking the speed/size vs. accuracy tradeoff easy,\n// though floats seem accurate enough for all practical purposes, since\n// they pass the \"approxEqual(inverseFft(fft(arr)), arr)\" test even for\n// size 2 ^^ 22.\nprivate alias lookup_t = float;\n\n/**A class for performing fast Fourier transforms of power of two sizes.\n * This class encapsulates a large amount of state that is reusable when\n * performing multiple FFTs of sizes smaller than or equal to that specified\n * in the constructor.  This results in substantial speedups when performing\n * multiple FFTs with a known maximum size.  However,\n * a free function API is provided for convenience if you need to perform a\n * one-off FFT.\n *\n * References:\n * $(HTTP en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm)\n */\nfinal class Fft\n{\n    import core.bitop : bsf;\n    import std.algorithm.iteration : map;\n    import std.array : uninitializedArray;\n\nprivate:\n    immutable lookup_t[][] negSinLookup;\n\n    void enforceSize(R)(R range) const\n    {\n        import std.conv : text;\n        assert(range.length <= size, text(\n            \"FFT size mismatch.  Expected \", size, \", got \", range.length));\n    }\n\n    void fftImpl(Ret, R)(Stride!R range, Ret buf) const\n    in\n    {\n        assert(range.length >= 4);\n        assert(isPowerOf2(range.length));\n    }\n    do\n    {\n        auto recurseRange = range;\n        recurseRange.doubleSteps();\n\n        if (buf.length > 4)\n        {\n            fftImpl(recurseRange, buf[0..$ / 2]);\n            recurseRange.popHalf();\n            fftImpl(recurseRange, buf[$ / 2..$]);\n        }\n        else\n        {\n            // Do this here instead of in another recursion to save on\n            // recursion overhead.\n            slowFourier2(recurseRange, buf[0..$ / 2]);\n            recurseRange.popHalf();\n            slowFourier2(recurseRange, buf[$ / 2..$]);\n        }\n\n        butterfly(buf);\n    }\n\n    // This algorithm works by performing the even and odd parts of our FFT\n    // using the \"two for the price of one\" method mentioned at\n    // http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM#Head521\n    // by making the odd terms into the imaginary components of our new FFT,\n    // and then using symmetry to recombine them.\n    void fftImplPureReal(Ret, R)(R range, Ret buf) const\n    in\n    {\n        assert(range.length >= 4);\n        assert(isPowerOf2(range.length));\n    }\n    do\n    {\n        alias E = ElementType!R;\n\n        // Converts odd indices of range to the imaginary components of\n        // a range half the size.  The even indices become the real components.\n        static if (isArray!R && isFloatingPoint!E)\n        {\n            // Then the memory layout of complex numbers provides a dirt\n            // cheap way to convert.  This is a common case, so take advantage.\n            auto oddsImag = cast(Complex!E[]) range;\n        }\n        else\n        {\n            // General case:  Use a higher order range.  We can assume\n            // source.length is even because it has to be a power of 2.\n            static struct OddToImaginary\n            {\n                R source;\n                alias C = Complex!(CommonType!(E, typeof(buf[0].re)));\n\n                @property\n                {\n                    C front()\n                    {\n                        return C(source[0], source[1]);\n                    }\n\n                    C back()\n                    {\n                        immutable n = source.length;\n                        return C(source[n - 2], source[n - 1]);\n                    }\n\n                    typeof(this) save()\n                    {\n                        return typeof(this)(source.save);\n                    }\n\n                    bool empty()\n                    {\n                        return source.empty;\n                    }\n\n                    size_t length()\n                    {\n                        return source.length / 2;\n                    }\n                }\n\n                void popFront()\n                {\n                    source.popFront();\n                    source.popFront();\n                }\n\n                void popBack()\n                {\n                    source.popBack();\n                    source.popBack();\n                }\n\n                C opIndex(size_t index)\n                {\n                    return C(source[index * 2], source[index * 2 + 1]);\n                }\n\n                typeof(this) opSlice(size_t lower, size_t upper)\n                {\n                    return typeof(this)(source[lower * 2 .. upper * 2]);\n                }\n            }\n\n            auto oddsImag = OddToImaginary(range);\n        }\n\n        fft(oddsImag, buf[0..$ / 2]);\n        auto evenFft = buf[0..$ / 2];\n        auto oddFft = buf[$ / 2..$];\n        immutable halfN = evenFft.length;\n        oddFft[0].re = buf[0].im;\n        oddFft[0].im = 0;\n        evenFft[0].im = 0;\n        // evenFft[0].re is already right b/c it's aliased with buf[0].re.\n\n        foreach (k; 1 .. halfN / 2 + 1)\n        {\n            immutable bufk = buf[k];\n            immutable bufnk = buf[buf.length / 2 - k];\n            evenFft[k].re = 0.5 * (bufk.re + bufnk.re);\n            evenFft[halfN - k].re = evenFft[k].re;\n            evenFft[k].im = 0.5 * (bufk.im - bufnk.im);\n            evenFft[halfN - k].im = -evenFft[k].im;\n\n            oddFft[k].re = 0.5 * (bufk.im + bufnk.im);\n            oddFft[halfN - k].re = oddFft[k].re;\n            oddFft[k].im = 0.5 * (bufnk.re - bufk.re);\n            oddFft[halfN - k].im = -oddFft[k].im;\n        }\n\n        butterfly(buf);\n    }\n\n    void butterfly(R)(R buf) const\n    in\n    {\n        assert(isPowerOf2(buf.length));\n    }\n    do\n    {\n        immutable n = buf.length;\n        immutable localLookup = negSinLookup[bsf(n)];\n        assert(localLookup.length == n);\n\n        immutable cosMask = n - 1;\n        immutable cosAdd = n / 4 * 3;\n\n        lookup_t negSinFromLookup(size_t index) pure nothrow\n        {\n            return localLookup[index];\n        }\n\n        lookup_t cosFromLookup(size_t index) pure nothrow\n        {\n            // cos is just -sin shifted by PI * 3 / 2.\n            return localLookup[(index + cosAdd) & cosMask];\n        }\n\n        immutable halfLen = n / 2;\n\n        // This loop is unrolled and the two iterations are interleaved\n        // relative to the textbook FFT to increase ILP.  This gives roughly 5%\n        // speedups on DMD.\n        for (size_t k = 0; k < halfLen; k += 2)\n        {\n            immutable cosTwiddle1 = cosFromLookup(k);\n            immutable sinTwiddle1 = negSinFromLookup(k);\n            immutable cosTwiddle2 = cosFromLookup(k + 1);\n            immutable sinTwiddle2 = negSinFromLookup(k + 1);\n\n            immutable realLower1 = buf[k].re;\n            immutable imagLower1 = buf[k].im;\n            immutable realLower2 = buf[k + 1].re;\n            immutable imagLower2 = buf[k + 1].im;\n\n            immutable upperIndex1 = k + halfLen;\n            immutable upperIndex2 = upperIndex1 + 1;\n            immutable realUpper1 = buf[upperIndex1].re;\n            immutable imagUpper1 = buf[upperIndex1].im;\n            immutable realUpper2 = buf[upperIndex2].re;\n            immutable imagUpper2 = buf[upperIndex2].im;\n\n            immutable realAdd1 = cosTwiddle1 * realUpper1\n                               - sinTwiddle1 * imagUpper1;\n            immutable imagAdd1 = sinTwiddle1 * realUpper1\n                               + cosTwiddle1 * imagUpper1;\n            immutable realAdd2 = cosTwiddle2 * realUpper2\n                               - sinTwiddle2 * imagUpper2;\n            immutable imagAdd2 = sinTwiddle2 * realUpper2\n                               + cosTwiddle2 * imagUpper2;\n\n            buf[k].re += realAdd1;\n            buf[k].im += imagAdd1;\n            buf[k + 1].re += realAdd2;\n            buf[k + 1].im += imagAdd2;\n\n            buf[upperIndex1].re = realLower1 - realAdd1;\n            buf[upperIndex1].im = imagLower1 - imagAdd1;\n            buf[upperIndex2].re = realLower2 - realAdd2;\n            buf[upperIndex2].im = imagLower2 - imagAdd2;\n        }\n    }\n\n    // This constructor is used within this module for allocating the\n    // buffer space elsewhere besides the GC heap.  It's definitely **NOT**\n    // part of the public API and definitely **IS** subject to change.\n    //\n    // Also, this is unsafe because the memSpace buffer will be cast\n    // to immutable.\n    public this(lookup_t[] memSpace)  // Public b/c of bug 4636.\n    {\n        immutable size = memSpace.length / 2;\n\n        /* Create a lookup table of all negative sine values at a resolution of\n         * size and all smaller power of two resolutions.  This may seem\n         * inefficient, but having all the lookups be next to each other in\n         * memory at every level of iteration is a huge win performance-wise.\n         */\n        if (size == 0)\n        {\n            return;\n        }\n\n        assert(isPowerOf2(size),\n            \"Can only do FFTs on ranges with a size that is a power of two.\");\n\n        auto table = new lookup_t[][bsf(size) + 1];\n\n        table[$ - 1] = memSpace[$ - size..$];\n        memSpace = memSpace[0 .. size];\n\n        auto lastRow = table[$ - 1];\n        lastRow[0] = 0;  // -sin(0) == 0.\n        foreach (ptrdiff_t i; 1 .. size)\n        {\n            // The hard coded cases are for improved accuracy and to prevent\n            // annoying non-zeroness when stuff should be zero.\n\n            if (i == size / 4)\n                lastRow[i] = -1;  // -sin(pi / 2) == -1.\n            else if (i == size / 2)\n                lastRow[i] = 0;   // -sin(pi) == 0.\n            else if (i == size * 3 / 4)\n                lastRow[i] = 1;  // -sin(pi * 3 / 2) == 1\n            else\n                lastRow[i] = -sin(i * 2.0L * PI / size);\n        }\n\n        // Fill in all the other rows with strided versions.\n        foreach (i; 1 .. table.length - 1)\n        {\n            immutable strideLength = size / (2 ^^ i);\n            auto strided = Stride!(lookup_t[])(lastRow, strideLength);\n            table[i] = memSpace[$ - strided.length..$];\n            memSpace = memSpace[0..$ - strided.length];\n\n            size_t copyIndex;\n            foreach (elem; strided)\n            {\n                table[i][copyIndex++] = elem;\n            }\n        }\n\n        negSinLookup = cast(immutable) table;\n    }\n\npublic:\n    /**Create an `Fft` object for computing fast Fourier transforms of\n     * power of two sizes of `size` or smaller.  `size` must be a\n     * power of two.\n     */\n    this(size_t size)\n    {\n        // Allocate all twiddle factor buffers in one contiguous block so that,\n        // when one is done being used, the next one is next in cache.\n        auto memSpace = uninitializedArray!(lookup_t[])(2 * size);\n        this(memSpace);\n    }\n\n    @property size_t size() const\n    {\n        return (negSinLookup is null) ? 0 : negSinLookup[$ - 1].length;\n    }\n\n    /**Compute the Fourier transform of range using the $(BIGOH N log N)\n     * Cooley-Tukey Algorithm.  `range` must be a random-access range with\n     * slicing and a length equal to `size` as provided at the construction of\n     * this object.  The contents of range can be either  numeric types,\n     * which will be interpreted as pure real values, or complex types with\n     * properties or members `.re` and `.im` that can be read.\n     *\n     * Note:  Pure real FFTs are automatically detected and the relevant\n     *        optimizations are performed.\n     *\n     * Returns:  An array of complex numbers representing the transformed data in\n     *           the frequency domain.\n     *\n     * Conventions: The exponent is negative and the factor is one,\n     *              i.e., output[j] := sum[ exp(-2 PI i j k / N) input[k] ].\n     */\n    Complex!F[] fft(F = double, R)(R range) const\n        if (isFloatingPoint!F && isRandomAccessRange!R)\n    {\n        enforceSize(range);\n        Complex!F[] ret;\n        if (range.length == 0)\n        {\n            return ret;\n        }\n\n        // Don't waste time initializing the memory for ret.\n        ret = uninitializedArray!(Complex!F[])(range.length);\n\n        fft(range,  ret);\n        return ret;\n    }\n\n    /**Same as the overload, but allows for the results to be stored in a user-\n     * provided buffer.  The buffer must be of the same length as range, must be\n     * a random-access range, must have slicing, and must contain elements that are\n     * complex-like.  This means that they must have a .re and a .im member or\n     * property that can be both read and written and are floating point numbers.\n     */\n    void fft(Ret, R)(R range, Ret buf) const\n        if (isRandomAccessRange!Ret && isComplexLike!(ElementType!Ret) && hasSlicing!Ret)\n    {\n        assert(buf.length == range.length);\n        enforceSize(range);\n\n        if (range.length == 0)\n        {\n            return;\n        }\n        else if (range.length == 1)\n        {\n            buf[0] = range[0];\n            return;\n        }\n        else if (range.length == 2)\n        {\n            slowFourier2(range, buf);\n            return;\n        }\n        else\n        {\n            alias E = ElementType!R;\n            static if (is(E : real))\n            {\n                return fftImplPureReal(range, buf);\n            }\n            else\n            {\n                static if (is(R : Stride!R))\n                    return fftImpl(range, buf);\n                else\n                    return fftImpl(Stride!R(range, 1), buf);\n            }\n        }\n    }\n\n    /**\n     * Computes the inverse Fourier transform of a range.  The range must be a\n     * random access range with slicing, have a length equal to the size\n     * provided at construction of this object, and contain elements that are\n     * either of type std.complex.Complex or have essentially\n     * the same compile-time interface.\n     *\n     * Returns:  The time-domain signal.\n     *\n     * Conventions: The exponent is positive and the factor is 1/N, i.e.,\n     *              output[j] := (1 / N) sum[ exp(+2 PI i j k / N) input[k] ].\n     */\n    Complex!F[] inverseFft(F = double, R)(R range) const\n        if (isRandomAccessRange!R && isComplexLike!(ElementType!R) && isFloatingPoint!F)\n    {\n        enforceSize(range);\n        Complex!F[] ret;\n        if (range.length == 0)\n        {\n            return ret;\n        }\n\n        // Don't waste time initializing the memory for ret.\n        ret = uninitializedArray!(Complex!F[])(range.length);\n\n        inverseFft(range, ret);\n        return ret;\n    }\n\n    /**\n     * Inverse FFT that allows a user-supplied buffer to be provided.  The buffer\n     * must be a random access range with slicing, and its elements\n     * must be some complex-like type.\n     */\n    void inverseFft(Ret, R)(R range, Ret buf) const\n        if (isRandomAccessRange!Ret && isComplexLike!(ElementType!Ret) && hasSlicing!Ret)\n    {\n        enforceSize(range);\n\n        auto swapped = map!swapRealImag(range);\n        fft(swapped,  buf);\n\n        immutable lenNeg1 = 1.0 / buf.length;\n        foreach (ref elem; buf)\n        {\n            immutable temp = elem.re * lenNeg1;\n            elem.re = elem.im * lenNeg1;\n            elem.im = temp;\n        }\n    }\n}\n\n// This mixin creates an Fft object in the scope it's mixed into such that all\n// memory owned by the object is deterministically destroyed at the end of that\n// scope.\nprivate enum string MakeLocalFft = q{\n    import core.stdc.stdlib;\n    import core.exception : onOutOfMemoryError;\n\n    auto lookupBuf = (cast(lookup_t*) malloc(range.length * 2 * lookup_t.sizeof))\n                     [0 .. 2 * range.length];\n    if (!lookupBuf.ptr)\n        onOutOfMemoryError();\n\n    scope(exit) free(cast(void*) lookupBuf.ptr);\n    auto fftObj = scoped!Fft(lookupBuf);\n};\n\n/**Convenience functions that create an `Fft` object, run the FFT or inverse\n * FFT and return the result.  Useful for one-off FFTs.\n *\n * Note:  In addition to convenience, these functions are slightly more\n *        efficient than manually creating an Fft object for a single use,\n *        as the Fft object is deterministically destroyed before these\n *        functions return.\n */\nComplex!F[] fft(F = double, R)(R range)\n{\n    mixin(MakeLocalFft);\n    return fftObj.fft!(F, R)(range);\n}\n\n/// ditto\nvoid fft(Ret, R)(R range, Ret buf)\n{\n    mixin(MakeLocalFft);\n    return fftObj.fft!(Ret, R)(range, buf);\n}\n\n/// ditto\nComplex!F[] inverseFft(F = double, R)(R range)\n{\n    mixin(MakeLocalFft);\n    return fftObj.inverseFft!(F, R)(range);\n}\n\n/// ditto\nvoid inverseFft(Ret, R)(R range, Ret buf)\n{\n    mixin(MakeLocalFft);\n    return fftObj.inverseFft!(Ret, R)(range, buf);\n}\n\n@system unittest\n{\n    import std.algorithm;\n    import std.conv;\n    import std.range;\n    // Test values from R and Octave.\n    auto arr = [1,2,3,4,5,6,7,8];\n    auto fft1 = fft(arr);\n    assert(approxEqual(map!\"a.re\"(fft1),\n        [36.0, -4, -4, -4, -4, -4, -4, -4]));\n    assert(approxEqual(map!\"a.im\"(fft1),\n        [0, 9.6568, 4, 1.6568, 0, -1.6568, -4, -9.6568]));\n\n    auto fft1Retro = fft(retro(arr));\n    assert(approxEqual(map!\"a.re\"(fft1Retro),\n        [36.0, 4, 4, 4, 4, 4, 4, 4]));\n    assert(approxEqual(map!\"a.im\"(fft1Retro),\n        [0, -9.6568, -4, -1.6568, 0, 1.6568, 4, 9.6568]));\n\n    auto fft1Float = fft(to!(float[])(arr));\n    assert(approxEqual(map!\"a.re\"(fft1), map!\"a.re\"(fft1Float)));\n    assert(approxEqual(map!\"a.im\"(fft1), map!\"a.im\"(fft1Float)));\n\n    alias C = Complex!float;\n    auto arr2 = [C(1,2), C(3,4), C(5,6), C(7,8), C(9,10),\n        C(11,12), C(13,14), C(15,16)];\n    auto fft2 = fft(arr2);\n    assert(approxEqual(map!\"a.re\"(fft2),\n        [64.0, -27.3137, -16, -11.3137, -8, -4.6862, 0, 11.3137]));\n    assert(approxEqual(map!\"a.im\"(fft2),\n        [72, 11.3137, 0, -4.686, -8, -11.3137, -16, -27.3137]));\n\n    auto inv1 = inverseFft(fft1);\n    assert(approxEqual(map!\"a.re\"(inv1), arr));\n    assert(reduce!max(map!\"a.im\"(inv1)) < 1e-10);\n\n    auto inv2 = inverseFft(fft2);\n    assert(approxEqual(map!\"a.re\"(inv2), map!\"a.re\"(arr2)));\n    assert(approxEqual(map!\"a.im\"(inv2), map!\"a.im\"(arr2)));\n\n    // FFTs of size 0, 1 and 2 are handled as special cases.  Test them here.\n    ushort[] empty;\n    assert(fft(empty) == null);\n    assert(inverseFft(fft(empty)) == null);\n\n    real[] oneElem = [4.5L];\n    auto oneFft = fft(oneElem);\n    assert(oneFft.length == 1);\n    assert(oneFft[0].re == 4.5L);\n    assert(oneFft[0].im == 0);\n\n    auto oneInv = inverseFft(oneFft);\n    assert(oneInv.length == 1);\n    assert(approxEqual(oneInv[0].re, 4.5));\n    assert(approxEqual(oneInv[0].im, 0));\n\n    long[2] twoElems = [8, 4];\n    auto twoFft = fft(twoElems[]);\n    assert(twoFft.length == 2);\n    assert(approxEqual(twoFft[0].re, 12));\n    assert(approxEqual(twoFft[0].im, 0));\n    assert(approxEqual(twoFft[1].re, 4));\n    assert(approxEqual(twoFft[1].im, 0));\n    auto twoInv = inverseFft(twoFft);\n    assert(approxEqual(twoInv[0].re, 8));\n    assert(approxEqual(twoInv[0].im, 0));\n    assert(approxEqual(twoInv[1].re, 4));\n    assert(approxEqual(twoInv[1].im, 0));\n}\n\n// Swaps the real and imaginary parts of a complex number.  This is useful\n// for inverse FFTs.\nC swapRealImag(C)(C input)\n{\n    return C(input.im, input.re);\n}\n\nprivate:\n// The reasons I couldn't use std.algorithm were b/c its stride length isn't\n// modifiable on the fly and because range has grown some performance hacks\n// for powers of 2.\nstruct Stride(R)\n{\n    import core.bitop : bsf;\n    Unqual!R range;\n    size_t _nSteps;\n    size_t _length;\n    alias E = ElementType!(R);\n\n    this(R range, size_t nStepsIn)\n    {\n        this.range = range;\n       _nSteps = nStepsIn;\n       _length = (range.length + _nSteps - 1) / nSteps;\n    }\n\n    size_t length() const @property\n    {\n        return _length;\n    }\n\n    typeof(this) save() @property\n    {\n        auto ret = this;\n        ret.range = ret.range.save;\n        return ret;\n    }\n\n    E opIndex(size_t index)\n    {\n        return range[index * _nSteps];\n    }\n\n    E front() @property\n    {\n        return range[0];\n    }\n\n    void popFront()\n    {\n        if (range.length >= _nSteps)\n        {\n            range = range[_nSteps .. range.length];\n            _length--;\n        }\n        else\n        {\n            range = range[0 .. 0];\n            _length = 0;\n        }\n    }\n\n    // Pops half the range's stride.\n    void popHalf()\n    {\n        range = range[_nSteps / 2 .. range.length];\n    }\n\n    bool empty() const @property\n    {\n        return length == 0;\n    }\n\n    size_t nSteps() const @property\n    {\n        return _nSteps;\n    }\n\n    void doubleSteps()\n    {\n        _nSteps *= 2;\n        _length /= 2;\n    }\n\n    size_t nSteps(size_t newVal) @property\n    {\n        _nSteps = newVal;\n\n        // Using >> bsf(nSteps) is a few cycles faster than / nSteps.\n        _length = (range.length + _nSteps - 1)  >> bsf(nSteps);\n        return newVal;\n    }\n}\n\n// Hard-coded base case for FFT of size 2.  This is actually a TON faster than\n// using a generic slow DFT.  This seems to be the best base case.  (Size 1\n// can be coded inline as buf[0] = range[0]).\nvoid slowFourier2(Ret, R)(R range, Ret buf)\n{\n    assert(range.length == 2);\n    assert(buf.length == 2);\n    buf[0] = range[0] + range[1];\n    buf[1] = range[0] - range[1];\n}\n\n// Hard-coded base case for FFT of size 4.  Doesn't work as well as the size\n// 2 case.\nvoid slowFourier4(Ret, R)(R range, Ret buf)\n{\n    alias C = ElementType!Ret;\n\n    assert(range.length == 4);\n    assert(buf.length == 4);\n    buf[0] = range[0] + range[1] + range[2] + range[3];\n    buf[1] = range[0] - range[1] * C(0, 1) - range[2] + range[3] * C(0, 1);\n    buf[2] = range[0] - range[1] + range[2] - range[3];\n    buf[3] = range[0] + range[1] * C(0, 1) - range[2] - range[3] * C(0, 1);\n}\n\nN roundDownToPowerOf2(N)(N num)\nif (isScalarType!N && !isFloatingPoint!N)\n{\n    import core.bitop : bsr;\n    return num & (cast(N) 1 << bsr(num));\n}\n\n@safe unittest\n{\n    assert(roundDownToPowerOf2(7) == 4);\n    assert(roundDownToPowerOf2(4) == 4);\n}\n\ntemplate isComplexLike(T)\n{\n    enum bool isComplexLike = is(typeof(T.init.re)) &&\n        is(typeof(T.init.im));\n}\n\n@safe unittest\n{\n    static assert(isComplexLike!(Complex!double));\n    static assert(!isComplexLike!(uint));\n}\n"
  },
  {
    "path": "libphobos/src/std/outbuffer.d",
    "content": "// Written in the D programming language.\n\n/**\nSerialize data to `ubyte` arrays.\n\n * Copyright: Copyright The D Language Foundation 2000 - 2015.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright)\n * Source:    $(PHOBOSSRC std/outbuffer.d)\n *\n * $(SCRIPT inhibitQuickIndex = 1;)\n */\nmodule std.outbuffer;\n\nimport core.stdc.stdarg; // : va_list;\n\n/*********************************************\n * OutBuffer provides a way to build up an array of bytes out\n * of raw data. It is useful for things like preparing an\n * array of bytes to write out to a file.\n * OutBuffer's byte order is the format native to the computer.\n * To control the byte order (endianness), use a class derived\n * from OutBuffer.\n * OutBuffer's internal buffer is allocated with the GC. Pointers\n * stored into the buffer are scanned by the GC, but you have to\n * ensure proper alignment, e.g. by using alignSize((void*).sizeof).\n */\n\nclass OutBuffer\n{\n    ubyte[] data;\n    size_t offset;\n\n    invariant()\n    {\n        assert(offset <= data.length);\n    }\n\n  pure nothrow @safe\n  {\n    /*********************************\n     * Convert to array of bytes.\n     */\n    inout(ubyte)[] toBytes() scope inout { return data[0 .. offset]; }\n\n    /***********************************\n     * Preallocate nbytes more to the size of the internal buffer.\n     *\n     * This is a\n     * speed optimization, a good guess at the maximum size of the resulting\n     * buffer will improve performance by eliminating reallocations and copying.\n     */\n    void reserve(size_t nbytes) @trusted\n        in\n        {\n            assert(offset + nbytes >= offset);\n        }\n        out\n        {\n            assert(offset + nbytes <= data.length);\n        }\n        do\n        {\n            if (data.length < offset + nbytes)\n            {\n                void[] vdata = data;\n                vdata.length = (offset + nbytes + 7) * 2; // allocates as void[] to not set BlkAttr.NO_SCAN\n                data = cast(ubyte[]) vdata;\n            }\n        }\n\n    /**********************************\n     * put enables OutBuffer to be used as an OutputRange.\n     */\n    alias put = write;\n\n    /*************************************\n     * Append data to the internal buffer.\n     */\n\n    void write(scope const(ubyte)[] bytes)\n        {\n            reserve(bytes.length);\n            data[offset .. offset + bytes.length] = bytes[];\n            offset += bytes.length;\n        }\n\n    void write(scope const(wchar)[] chars) @trusted\n        {\n        write(cast(ubyte[]) chars);\n        }\n\n    void write(scope const(dchar)[] chars) @trusted\n        {\n        write(cast(ubyte[]) chars);\n        }\n\n    void write(ubyte b)         /// ditto\n        {\n            reserve(ubyte.sizeof);\n            this.data[offset] = b;\n            offset += ubyte.sizeof;\n        }\n\n    void write(byte b) { write(cast(ubyte) b); }         /// ditto\n    void write(char c) { write(cast(ubyte) c); }         /// ditto\n    void write(dchar c) { write(cast(uint) c); }         /// ditto\n\n    void write(ushort w) @trusted                /// ditto\n    {\n        reserve(ushort.sizeof);\n        *cast(ushort *)&data[offset] = w;\n        offset += ushort.sizeof;\n    }\n\n    void write(short s) { write(cast(ushort) s); }               /// ditto\n\n    void write(wchar c) @trusted        /// ditto\n    {\n        reserve(wchar.sizeof);\n        *cast(wchar *)&data[offset] = c;\n        offset += wchar.sizeof;\n    }\n\n    void write(uint w) @trusted         /// ditto\n    {\n        reserve(uint.sizeof);\n        *cast(uint *)&data[offset] = w;\n        offset += uint.sizeof;\n    }\n\n    void write(int i) { write(cast(uint) i); }           /// ditto\n\n    void write(ulong l) @trusted         /// ditto\n    {\n        reserve(ulong.sizeof);\n        *cast(ulong *)&data[offset] = l;\n        offset += ulong.sizeof;\n    }\n\n    void write(long l) { write(cast(ulong) l); }         /// ditto\n\n    void write(float f) @trusted         /// ditto\n    {\n        reserve(float.sizeof);\n        *cast(float *)&data[offset] = f;\n        offset += float.sizeof;\n    }\n\n    void write(double f) @trusted               /// ditto\n    {\n        reserve(double.sizeof);\n        *cast(double *)&data[offset] = f;\n        offset += double.sizeof;\n    }\n\n    void write(real f) @trusted         /// ditto\n    {\n        reserve(real.sizeof);\n        *cast(real *)&data[offset] = f;\n        offset += real.sizeof;\n    }\n\n    void write(scope const(char)[] s) @trusted             /// ditto\n    {\n        write(cast(ubyte[]) s);\n    }\n\n    void write(scope const OutBuffer buf)           /// ditto\n    {\n        write(buf.toBytes());\n    }\n\n    /****************************************\n     * Append nbytes of 0 to the internal buffer.\n     */\n\n    void fill0(size_t nbytes)\n    {\n        reserve(nbytes);\n        data[offset .. offset + nbytes] = 0;\n        offset += nbytes;\n    }\n\n    /**********************************\n     * 0-fill to align on power of 2 boundary.\n     */\n\n    void alignSize(size_t alignsize)\n    in\n    {\n        assert(alignsize && (alignsize & (alignsize - 1)) == 0);\n    }\n    out\n    {\n        assert((offset & (alignsize - 1)) == 0);\n    }\n    do\n    {\n        auto nbytes = offset & (alignsize - 1);\n        if (nbytes)\n            fill0(alignsize - nbytes);\n    }\n\n    /// Clear the data in the buffer\n    void clear()\n    {\n        offset = 0;\n    }\n\n    /****************************************\n     * Optimize common special case alignSize(2)\n     */\n\n    void align2()\n    {\n        if (offset & 1)\n            write(cast(byte) 0);\n    }\n\n    /****************************************\n     * Optimize common special case alignSize(4)\n     */\n\n    void align4()\n    {\n        if (offset & 3)\n        {   auto nbytes = (4 - offset) & 3;\n            fill0(nbytes);\n        }\n    }\n\n    /**************************************\n     * Convert internal buffer to array of chars.\n     */\n\n    override string toString() const\n    {\n        //printf(\"OutBuffer.toString()\\n\");\n        return cast(string) data[0 .. offset].idup;\n    }\n  }\n\n    /*****************************************\n     * Append output of C's vprintf() to internal buffer.\n     */\n\n    void vprintf(scope string format, va_list args) @trusted nothrow\n    {\n        import core.stdc.stdio : vsnprintf;\n        import core.stdc.stdlib : alloca;\n        import std.string : toStringz;\n\n        version (unittest)\n            char[3] buffer = void;      // trigger reallocation\n        else\n            char[128] buffer = void;\n        int count;\n\n        // Can't use `tempCString()` here as it will result in compilation error:\n        // \"cannot mix core.std.stdlib.alloca() and exception handling\".\n        auto f = toStringz(format);\n        auto p = buffer.ptr;\n        auto psize = buffer.length;\n        for (;;)\n        {\n            va_list args2;\n            va_copy(args2, args);\n            count = vsnprintf(p, psize, f, args2);\n            va_end(args2);\n            if (count == -1)\n            {\n                if (psize > psize.max / 2) assert(0); // overflow check\n                psize *= 2;\n            }\n            else if (count >= psize)\n            {\n                if (count == count.max) assert(0); // overflow check\n                psize = count + 1;\n            }\n            else\n                break;\n\n            p = cast(char *) alloca(psize); // buffer too small, try again with larger size\n        }\n        write(cast(ubyte[]) p[0 .. count]);\n    }\n\n    /*****************************************\n     * Append output of C's printf() to internal buffer.\n     */\n\n    void printf(scope string format, ...) @trusted\n    {\n        va_list ap;\n        va_start(ap, format);\n        vprintf(format, ap);\n        va_end(ap);\n    }\n\n    /**\n     * Formats and writes its arguments in text format to the OutBuffer.\n     *\n     * Params:\n     *  fmt = format string as described in $(REF formattedWrite, std,format)\n     *  args = arguments to be formatted\n     *\n     * See_Also:\n     *  $(REF _writef, std,stdio);\n     *  $(REF formattedWrite, std,format);\n     */\n    void writef(Char, A...)(scope const(Char)[] fmt, A args)\n    {\n        import std.format : formattedWrite;\n        formattedWrite(this, fmt, args);\n    }\n\n    ///\n    @safe unittest\n    {\n        OutBuffer b = new OutBuffer();\n        b.writef(\"a%sb\", 16);\n        assert(b.toString() == \"a16b\");\n    }\n\n    /**\n     * Formats and writes its arguments in text format to the OutBuffer,\n     * followed by a newline.\n     *\n     * Params:\n     *  fmt = format string as described in $(REF formattedWrite, std,format)\n     *  args = arguments to be formatted\n     *\n     * See_Also:\n     *  $(REF _writefln, std,stdio);\n     *  $(REF formattedWrite, std,format);\n     */\n    void writefln(Char, A...)(scope const(Char)[] fmt, A args)\n    {\n        import std.format : formattedWrite;\n        formattedWrite(this, fmt, args);\n        put('\\n');\n    }\n\n    ///\n    @safe unittest\n    {\n        OutBuffer b = new OutBuffer();\n        b.writefln(\"a%sb\", 16);\n        assert(b.toString() == \"a16b\\n\");\n    }\n\n    /*****************************************\n     * At offset index into buffer, create nbytes of space by shifting upwards\n     * all data past index.\n     */\n\n    void spread(size_t index, size_t nbytes) pure nothrow @safe\n        in\n        {\n            assert(index <= offset);\n        }\n        do\n        {\n            reserve(nbytes);\n\n            // This is an overlapping copy - should use memmove()\n            for (size_t i = offset; i > index; )\n            {\n                --i;\n                data[i + nbytes] = data[i];\n            }\n            offset += nbytes;\n        }\n}\n\n///\n@safe unittest\n{\n    import std.string : cmp;\n\n    OutBuffer buf = new OutBuffer();\n\n    assert(buf.offset == 0);\n    buf.write(\"hello\");\n    buf.write(cast(byte) 0x20);\n    buf.write(\"world\");\n    buf.printf(\" %d\", 62665);\n    assert(cmp(buf.toString(), \"hello world 62665\") == 0);\n\n    buf.clear();\n    assert(cmp(buf.toString(), \"\") == 0);\n    buf.write(\"New data\");\n    assert(cmp(buf.toString(),\"New data\") == 0);\n}\n\n@safe unittest\n{\n    import std.range;\n    static assert(isOutputRange!(OutBuffer, char));\n\n    import std.algorithm;\n  {\n    OutBuffer buf = new OutBuffer();\n    \"hello\".copy(buf);\n    assert(buf.toBytes() == \"hello\");\n  }\n  {\n    OutBuffer buf = new OutBuffer();\n    \"hello\"w.copy(buf);\n    assert(buf.toBytes() == \"h\\x00e\\x00l\\x00l\\x00o\\x00\");\n  }\n  {\n    OutBuffer buf = new OutBuffer();\n    \"hello\"d.copy(buf);\n    assert(buf.toBytes() == \"h\\x00\\x00\\x00e\\x00\\x00\\x00l\\x00\\x00\\x00l\\x00\\x00\\x00o\\x00\\x00\\x00\");\n  }\n}\n"
  },
  {
    "path": "libphobos/src/std/parallelism.d",
    "content": "/**\n`std.parallelism` implements high-level primitives for SMP parallelism.\nThese include parallel foreach, parallel reduce, parallel eager map, pipelining\nand future/promise parallelism.  `std.parallelism` is recommended when the\nsame operation is to be executed in parallel on different data, or when a\nfunction is to be executed in a background thread and its result returned to a\nwell-defined main thread.  For communication between arbitrary threads, see\n`std.concurrency`.\n\n`std.parallelism` is based on the concept of a `Task`.  A `Task` is an\nobject that represents the fundamental unit of work in this library and may be\nexecuted in parallel with any other `Task`.  Using `Task`\ndirectly allows programming with a future/promise paradigm.  All other\nsupported parallelism paradigms (parallel foreach, map, reduce, pipelining)\nrepresent an additional level of abstraction over `Task`.  They\nautomatically create one or more `Task` objects, or closely related types\nthat are conceptually identical but not part of the public API.\n\nAfter creation, a `Task` may be executed in a new thread, or submitted\nto a `TaskPool` for execution.  A `TaskPool` encapsulates a task queue\nand its worker threads.  Its purpose is to efficiently map a large\nnumber of `Task`s onto a smaller number of threads.  A task queue is a\nFIFO queue of `Task` objects that have been submitted to the\n`TaskPool` and are awaiting execution.  A worker thread is a thread that\nis associated with exactly one task queue.  It executes the `Task` at the\nfront of its queue when the queue has work available, or sleeps when\nno work is available.  Each task queue is associated with zero or\nmore worker threads.  If the result of a `Task` is needed before execution\nby a worker thread has begun, the `Task` can be removed from the task queue\nand executed immediately in the thread where the result is needed.\n\nWarning:  Unless marked as `@trusted` or `@safe`, artifacts in\n          this module allow implicit data sharing between threads and cannot\n          guarantee that client code is free from low level data races.\n\nSource:    $(PHOBOSSRC std/parallelism.d)\nAuthor:  David Simcha\nCopyright:  Copyright (c) 2009-2011, David Simcha.\nLicense:    $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)\n*/\nmodule std.parallelism;\n\n///\n@system unittest\n{\n    import std.algorithm.iteration : map;\n    import std.math : approxEqual;\n    import std.parallelism : taskPool;\n    import std.range : iota;\n\n    // Parallel reduce can be combined with\n    // std.algorithm.iteration.map to interesting effect.\n    // The following example (thanks to Russel Winder)\n    // calculates pi by quadrature  using\n    // std.algorithm.map and TaskPool.reduce.\n    // getTerm is evaluated in parallel as needed by\n    // TaskPool.reduce.\n    //\n    // Timings on an Intel i5-3450 quad core machine\n    // for n = 1_000_000_000:\n    //\n    // TaskPool.reduce:       1.067 s\n    // std.algorithm.reduce:  4.011 s\n\n    enum n = 1_000_000;\n    enum delta = 1.0 / n;\n\n    alias getTerm = (int i)\n    {\n        immutable x = ( i - 0.5 ) * delta;\n        return delta / ( 1.0 + x * x ) ;\n    };\n\n    immutable pi = 4.0 * taskPool.reduce!\"a + b\"(n.iota.map!getTerm);\n\n    assert(pi.approxEqual(3.1415926));\n}\n\nimport core.atomic;\nimport core.memory;\nimport core.sync.condition;\nimport core.thread;\n\nimport std.functional;\nimport std.meta;\nimport std.range.primitives;\nimport std.traits;\n\nversion (OSX)\n{\n    version = useSysctlbyname;\n}\nelse version (FreeBSD)\n{\n    version = useSysctlbyname;\n}\nelse version (DragonFlyBSD)\n{\n    version = useSysctlbyname;\n}\nelse version (NetBSD)\n{\n    version = useSysctlbyname;\n}\n\n/*\n(For now public undocumented with reserved name.)\n\nA lazily initialized global constant. The underlying value is a shared global\nstatically initialized to `outOfBandValue` which must not be a legit value of\nthe constant. Upon the first call the situation is detected and the global is\ninitialized by calling `initializer`. The initializer is assumed to be pure\n(even if not marked as such), i.e. return the same value upon repeated calls.\nFor that reason, no special precautions are taken so `initializer` may be called\nmore than one time leading to benign races on the cached value.\n\nIn the quiescent state the cost of the function is an atomic load from a global.\n\nParams:\n    T = The type of the pseudo-constant (may be qualified)\n    outOfBandValue = A value that cannot be valid, it is used for initialization\n    initializer = The function performing initialization; must be `nothrow`\n\nReturns:\n    The lazily initialized value\n*/\n@property pure\nT __lazilyInitializedConstant(T, alias outOfBandValue, alias initializer)()\nif (is(Unqual!T : T)\n    && is(typeof(initializer()) : T)\n    && is(typeof(outOfBandValue) : T))\n{\n    static T impl() nothrow\n    {\n        // Thread-local cache\n        static Unqual!T tls = outOfBandValue;\n        auto local = tls;\n        // Shortest path, no atomic operations\n        if (local != outOfBandValue) return local;\n        // Process-level cache\n        static shared Unqual!T result = outOfBandValue;\n        // Initialize both process-level cache and tls\n        local = atomicLoad(result);\n        if (local == outOfBandValue)\n        {\n            local = initializer();\n            atomicStore(result, local);\n        }\n        tls = local;\n        return local;\n    }\n\n    import std.traits : SetFunctionAttributes;\n    alias Fun = SetFunctionAttributes!(typeof(&impl), \"D\",\n        functionAttributes!(typeof(&impl)) | FunctionAttribute.pure_);\n    auto purified = (() @trusted => cast(Fun) &impl)();\n    return purified();\n}\n\n// Returns the size of a cache line.\nalias cacheLineSize =\n    __lazilyInitializedConstant!(immutable(size_t), size_t.max, cacheLineSizeImpl);\n\nprivate size_t cacheLineSizeImpl() @nogc nothrow @trusted\n{\n    size_t result = 0;\n    import core.cpuid : datacache;\n    foreach (ref const cachelevel; datacache)\n    {\n        if (cachelevel.lineSize > result && cachelevel.lineSize < uint.max)\n        {\n            result = cachelevel.lineSize;\n        }\n    }\n    return result;\n}\n\n@nogc @safe nothrow unittest\n{\n    assert(cacheLineSize == cacheLineSizeImpl);\n}\n\n/* Atomics code.  These forward to core.atomic, but are written like this\n   for two reasons:\n\n   1.  They used to actually contain ASM code and I don' want to have to change\n       to directly calling core.atomic in a zillion different places.\n\n   2.  core.atomic has some misc. issues that make my use cases difficult\n       without wrapping it.  If I didn't wrap it, casts would be required\n       basically everywhere.\n*/\nprivate void atomicSetUbyte(T)(ref T stuff, T newVal)\nif (__traits(isIntegral, T) && is(T : ubyte))\n{\n    //core.atomic.cas(cast(shared) &stuff, stuff, newVal);\n    atomicStore(*(cast(shared) &stuff), newVal);\n}\n\nprivate ubyte atomicReadUbyte(T)(ref T val)\nif (__traits(isIntegral, T) && is(T : ubyte))\n{\n    return atomicLoad(*(cast(shared) &val));\n}\n\n// This gets rid of the need for a lot of annoying casts in other parts of the\n// code, when enums are involved.\nprivate bool atomicCasUbyte(T)(ref T stuff, T testVal, T newVal)\nif (__traits(isIntegral, T) && is(T : ubyte))\n{\n    return core.atomic.cas(cast(shared) &stuff, testVal, newVal);\n}\n\n/*--------------------- Generic helper functions, etc.------------------------*/\nprivate template MapType(R, functions...)\n{\n    static assert(functions.length);\n\n    ElementType!R e = void;\n    alias MapType =\n        typeof(adjoin!(staticMap!(unaryFun, functions))(e));\n}\n\nprivate template ReduceType(alias fun, R, E)\n{\n    alias ReduceType = typeof(binaryFun!fun(E.init, ElementType!R.init));\n}\n\nprivate template noUnsharedAliasing(T)\n{\n    enum bool noUnsharedAliasing = !hasUnsharedAliasing!T;\n}\n\n// This template tests whether a function may be executed in parallel from\n// @safe code via Task.executeInNewThread().  There is an additional\n// requirement for executing it via a TaskPool.  (See isSafeReturn).\nprivate template isSafeTask(F)\n{\n    enum bool isSafeTask =\n        (functionAttributes!F & (FunctionAttribute.safe | FunctionAttribute.trusted)) != 0 &&\n        (functionAttributes!F & FunctionAttribute.ref_) == 0 &&\n        (isFunctionPointer!F || !hasUnsharedAliasing!F) &&\n        allSatisfy!(noUnsharedAliasing, Parameters!F);\n}\n\n@safe unittest\n{\n    alias F1 = void function() @safe;\n    alias F2 = void function();\n    alias F3 = void function(uint, string) @trusted;\n    alias F4 = void function(uint, char[]);\n\n    static assert( isSafeTask!F1);\n    static assert(!isSafeTask!F2);\n    static assert( isSafeTask!F3);\n    static assert(!isSafeTask!F4);\n\n    alias F5 = uint[] function(uint, string) pure @trusted;\n    static assert( isSafeTask!F5);\n}\n\n// This function decides whether Tasks that meet all of the other requirements\n// for being executed from @safe code can be executed on a TaskPool.\n// When executing via TaskPool, it's theoretically possible\n// to return a value that is also pointed to by a worker thread's thread local\n// storage.  When executing from executeInNewThread(), the thread that executed\n// the Task is terminated by the time the return value is visible in the calling\n// thread, so this is a non-issue.  It's also a non-issue for pure functions\n// since they can't read global state.\nprivate template isSafeReturn(T)\n{\n    static if (!hasUnsharedAliasing!(T.ReturnType))\n    {\n        enum isSafeReturn = true;\n    }\n    else static if (T.isPure)\n    {\n        enum isSafeReturn = true;\n    }\n    else\n    {\n        enum isSafeReturn = false;\n    }\n}\n\nprivate template randAssignable(R)\n{\n    enum randAssignable = isRandomAccessRange!R && hasAssignableElements!R;\n}\n\nprivate enum TaskStatus : ubyte\n{\n    notStarted,\n    inProgress,\n    done\n}\n\nprivate template AliasReturn(alias fun, T...)\n{\n    alias AliasReturn = typeof({ T args; return fun(args); });\n}\n\n// Should be private, but std.algorithm.reduce is used in the zero-thread case\n// and won't work w/ private.\ntemplate reduceAdjoin(functions...)\n{\n    static if (functions.length == 1)\n    {\n        alias reduceAdjoin = binaryFun!(functions[0]);\n    }\n    else\n    {\n        T reduceAdjoin(T, U)(T lhs, U rhs)\n        {\n            alias funs = staticMap!(binaryFun, functions);\n\n            foreach (i, Unused; typeof(lhs.expand))\n            {\n                lhs.expand[i] = funs[i](lhs.expand[i], rhs);\n            }\n\n            return lhs;\n        }\n    }\n}\n\nprivate template reduceFinish(functions...)\n{\n    static if (functions.length == 1)\n    {\n        alias reduceFinish = binaryFun!(functions[0]);\n    }\n    else\n    {\n        T reduceFinish(T)(T lhs, T rhs)\n        {\n            alias funs = staticMap!(binaryFun, functions);\n\n            foreach (i, Unused; typeof(lhs.expand))\n            {\n                lhs.expand[i] = funs[i](lhs.expand[i], rhs.expand[i]);\n            }\n\n            return lhs;\n        }\n    }\n}\n\nprivate template isRoundRobin(R : RoundRobinBuffer!(C1, C2), C1, C2)\n{\n    enum isRoundRobin = true;\n}\n\nprivate template isRoundRobin(T)\n{\n    enum isRoundRobin = false;\n}\n\n@safe unittest\n{\n    static assert( isRoundRobin!(RoundRobinBuffer!(void delegate(char[]), bool delegate())));\n    static assert(!isRoundRobin!(uint));\n}\n\n// This is the base \"class\" for all of the other tasks.  Using C-style\n// polymorphism to allow more direct control over memory allocation, etc.\nprivate struct AbstractTask\n{\n    AbstractTask* prev;\n    AbstractTask* next;\n\n    // Pointer to a function that executes this task.\n    void function(void*) runTask;\n\n    Throwable exception;\n    ubyte taskStatus = TaskStatus.notStarted;\n\n    bool done() @property\n    {\n        if (atomicReadUbyte(taskStatus) == TaskStatus.done)\n        {\n            if (exception)\n            {\n                throw exception;\n            }\n\n            return true;\n        }\n\n        return false;\n    }\n\n    void job()\n    {\n        runTask(&this);\n    }\n}\n\n/**\n`Task` represents the fundamental unit of work.  A `Task` may be\nexecuted in parallel with any other `Task`.  Using this struct directly\nallows future/promise parallelism.  In this paradigm, a function (or delegate\nor other callable) is executed in a thread other than the one it was called\nfrom.  The calling thread does not block while the function is being executed.\nA call to `workForce`, `yieldForce`, or `spinForce` is used to\nensure that the `Task` has finished executing and to obtain the return\nvalue, if any.  These functions and `done` also act as full memory barriers,\nmeaning that any memory writes made in the thread that executed the `Task`\nare guaranteed to be visible in the calling thread after one of these functions\nreturns.\n\nThe $(REF task, std,parallelism) and $(REF scopedTask, std,parallelism) functions can\nbe used to create an instance of this struct.  See `task` for usage examples.\n\nFunction results are returned from `yieldForce`, `spinForce` and\n`workForce` by ref.  If `fun` returns by ref, the reference will point\nto the returned reference of `fun`.  Otherwise it will point to a\nfield in this struct.\n\nCopying of this struct is disabled, since it would provide no useful semantics.\nIf you want to pass this struct around, you should do so by reference or\npointer.\n\nBugs:  Changes to `ref` and `out` arguments are not propagated to the\n       call site, only to `args` in this struct.\n*/\nstruct Task(alias fun, Args...)\n{\n    AbstractTask base = {runTask : &impl};\n    alias base this;\n\n    private @property AbstractTask* basePtr()\n    {\n        return &base;\n    }\n\n    private static void impl(void* myTask)\n    {\n        import std.algorithm.internal : addressOf;\n\n        Task* myCastedTask = cast(typeof(this)*) myTask;\n        static if (is(ReturnType == void))\n        {\n            fun(myCastedTask._args);\n        }\n        else static if (is(typeof(addressOf(fun(myCastedTask._args)))))\n        {\n            myCastedTask.returnVal = addressOf(fun(myCastedTask._args));\n        }\n        else\n        {\n            myCastedTask.returnVal = fun(myCastedTask._args);\n        }\n    }\n\n    private TaskPool pool;\n    private bool isScoped;  // True if created with scopedTask.\n\n    Args _args;\n\n    /**\n    The arguments the function was called with.  Changes to `out` and\n    `ref` arguments will be visible here.\n    */\n    static if (__traits(isSame, fun, run))\n    {\n        alias args = _args[1..$];\n    }\n    else\n    {\n        alias args = _args;\n    }\n\n\n    // The purpose of this code is to decide whether functions whose\n    // return values have unshared aliasing can be executed via\n    // TaskPool from @safe code.  See isSafeReturn.\n    static if (__traits(isSame, fun, run))\n    {\n        static if (isFunctionPointer!(_args[0]))\n        {\n            private enum bool isPure =\n            functionAttributes!(Args[0]) & FunctionAttribute.pure_;\n        }\n        else\n        {\n            // BUG:  Should check this for delegates too, but std.traits\n            //       apparently doesn't allow this.  isPure is irrelevant\n            //       for delegates, at least for now since shared delegates\n            //       don't work.\n            private enum bool isPure = false;\n        }\n\n    }\n    else\n    {\n        // We already know that we can't execute aliases in @safe code, so\n        // just put a dummy value here.\n        private enum bool isPure = false;\n    }\n\n\n    /**\n    The return type of the function called by this `Task`.  This can be\n    `void`.\n    */\n    alias ReturnType = typeof(fun(_args));\n\n    static if (!is(ReturnType == void))\n    {\n        static if (is(typeof(&fun(_args))))\n        {\n            // Ref return.\n            ReturnType* returnVal;\n\n            ref ReturnType fixRef(ReturnType* val)\n            {\n                return *val;\n            }\n\n        }\n        else\n        {\n            ReturnType returnVal;\n\n            ref ReturnType fixRef(ref ReturnType val)\n            {\n                return val;\n            }\n        }\n    }\n\n    private void enforcePool()\n    {\n        import std.exception : enforce;\n        enforce(this.pool !is null, \"Job not submitted yet.\");\n    }\n\n    static if (Args.length > 0)\n    {\n        private this(Args args)\n        {\n            _args = args;\n        }\n    }\n\n    // Work around DMD bug 6588, allow immutable elements.\n    static if (allSatisfy!(isAssignable, Args))\n    {\n        typeof(this) opAssign(typeof(this) rhs)\n        {\n            foreach (i, Type; typeof(this.tupleof))\n            {\n                this.tupleof[i] = rhs.tupleof[i];\n            }\n            return this;\n        }\n    }\n    else\n    {\n        @disable typeof(this) opAssign(typeof(this) rhs)\n        {\n            assert(0);\n        }\n    }\n\n    /**\n    If the `Task` isn't started yet, execute it in the current thread.\n    If it's done, return its return value, if any.  If it's in progress,\n    busy spin until it's done, then return the return value.  If it threw\n    an exception, rethrow that exception.\n\n    This function should be used when you expect the result of the\n    `Task` to be available on a timescale shorter than that of an OS\n    context switch.\n     */\n    @property ref ReturnType spinForce() @trusted\n    {\n        enforcePool();\n\n        this.pool.tryDeleteExecute(basePtr);\n\n        while (atomicReadUbyte(this.taskStatus) != TaskStatus.done) {}\n\n        if (exception)\n        {\n            throw exception;\n        }\n\n        static if (!is(ReturnType == void))\n        {\n            return fixRef(this.returnVal);\n        }\n    }\n\n    /**\n    If the `Task` isn't started yet, execute it in the current thread.\n    If it's done, return its return value, if any.  If it's in progress,\n    wait on a condition variable.  If it threw an exception, rethrow that\n    exception.\n\n    This function should be used for expensive functions, as waiting on a\n    condition variable introduces latency, but avoids wasted CPU cycles.\n     */\n    @property ref ReturnType yieldForce() @trusted\n    {\n        enforcePool();\n        this.pool.tryDeleteExecute(basePtr);\n\n        if (done)\n        {\n            static if (is(ReturnType == void))\n            {\n                return;\n            }\n            else\n            {\n                return fixRef(this.returnVal);\n            }\n        }\n\n        pool.waiterLock();\n        scope(exit) pool.waiterUnlock();\n\n        while (atomicReadUbyte(this.taskStatus) != TaskStatus.done)\n        {\n            pool.waitUntilCompletion();\n        }\n\n        if (exception)\n        {\n            throw exception; // nocoverage\n        }\n\n        static if (!is(ReturnType == void))\n        {\n            return fixRef(this.returnVal);\n        }\n    }\n\n    /**\n    If this `Task` was not started yet, execute it in the current\n    thread.  If it is finished, return its result.  If it is in progress,\n    execute any other `Task` from the `TaskPool` instance that\n    this `Task` was submitted to until this one\n    is finished.  If it threw an exception, rethrow that exception.\n    If no other tasks are available or this `Task` was executed using\n    `executeInNewThread`, wait on a condition variable.\n     */\n    @property ref ReturnType workForce() @trusted\n    {\n        enforcePool();\n        this.pool.tryDeleteExecute(basePtr);\n\n        while (true)\n        {\n            if (done)    // done() implicitly checks for exceptions.\n            {\n                static if (is(ReturnType == void))\n                {\n                    return;\n                }\n                else\n                {\n                    return fixRef(this.returnVal);\n                }\n            }\n\n            AbstractTask* job;\n            {\n                // Locking explicitly and calling popNoSync() because\n                // pop() waits on a condition variable if there are no Tasks\n                // in the queue.\n\n                pool.queueLock();\n                scope(exit) pool.queueUnlock();\n                job = pool.popNoSync();\n            }\n\n\n            if (job !is null)\n            {\n\n                version (verboseUnittest)\n                {\n                    stderr.writeln(\"Doing workForce work.\");\n                }\n\n                pool.doJob(job);\n\n                if (done)\n                {\n                    static if (is(ReturnType == void))\n                    {\n                        return;\n                    }\n                    else\n                    {\n                        return fixRef(this.returnVal);\n                    }\n                }\n            }\n            else\n            {\n                version (verboseUnittest)\n                {\n                    stderr.writeln(\"Yield from workForce.\");\n                }\n\n                return yieldForce;\n            }\n        }\n    }\n\n    /**\n    Returns `true` if the `Task` is finished executing.\n\n    Throws:  Rethrows any exception thrown during the execution of the\n             `Task`.\n    */\n    @property bool done() @trusted\n    {\n        // Explicitly forwarded for documentation purposes.\n        return base.done;\n    }\n\n    /**\n    Create a new thread for executing this `Task`, execute it in the\n    newly created thread, then terminate the thread.  This can be used for\n    future/promise parallelism.  An explicit priority may be given\n    to the `Task`.  If one is provided, its value is forwarded to\n    `core.thread.Thread.priority`. See $(REF task, std,parallelism) for\n    usage example.\n    */\n    void executeInNewThread() @trusted\n    {\n        pool = new TaskPool(basePtr);\n    }\n\n    /// Ditto\n    void executeInNewThread(int priority) @trusted\n    {\n        pool = new TaskPool(basePtr, priority);\n    }\n\n    @safe ~this()\n    {\n        if (isScoped && pool !is null && taskStatus != TaskStatus.done)\n        {\n            yieldForce;\n        }\n    }\n\n    // When this is uncommented, it somehow gets called on returning from\n    // scopedTask even though the struct shouldn't be getting copied.\n    //@disable this(this) {}\n}\n\n// Calls `fpOrDelegate` with `args`.  This is an\n// adapter that makes `Task` work with delegates, function pointers and\n// functors instead of just aliases.\nReturnType!F run(F, Args...)(F fpOrDelegate, ref Args args)\n{\n    return fpOrDelegate(args);\n}\n\n/**\nCreates a `Task` on the GC heap that calls an alias.  This may be executed\nvia `Task.executeInNewThread` or by submitting to a\n$(REF TaskPool, std,parallelism).  A globally accessible instance of\n`TaskPool` is provided by $(REF taskPool, std,parallelism).\n\nReturns:  A pointer to the `Task`.\n\nExample:\n---\n// Read two files into memory at the same time.\nimport std.file;\n\nvoid main()\n{\n    // Create and execute a Task for reading\n    // foo.txt.\n    auto file1Task = task!read(\"foo.txt\");\n    file1Task.executeInNewThread();\n\n    // Read bar.txt in parallel.\n    auto file2Data = read(\"bar.txt\");\n\n    // Get the results of reading foo.txt.\n    auto file1Data = file1Task.yieldForce;\n}\n---\n\n---\n// Sorts an array using a parallel quick sort algorithm.\n// The first partition is done serially.  Both recursion\n// branches are then executed in parallel.\n//\n// Timings for sorting an array of 1,000,000 doubles on\n// an Athlon 64 X2 dual core machine:\n//\n// This implementation:               176 milliseconds.\n// Equivalent serial implementation:  280 milliseconds\nvoid parallelSort(T)(T[] data)\n{\n    // Sort small subarrays serially.\n    if (data.length < 100)\n    {\n         std.algorithm.sort(data);\n         return;\n    }\n\n    // Partition the array.\n    swap(data[$ / 2], data[$ - 1]);\n    auto pivot = data[$ - 1];\n    bool lessThanPivot(T elem) { return elem < pivot; }\n\n    auto greaterEqual = partition!lessThanPivot(data[0..$ - 1]);\n    swap(data[$ - greaterEqual.length - 1], data[$ - 1]);\n\n    auto less = data[0..$ - greaterEqual.length - 1];\n    greaterEqual = data[$ - greaterEqual.length..$];\n\n    // Execute both recursion branches in parallel.\n    auto recurseTask = task!parallelSort(greaterEqual);\n    taskPool.put(recurseTask);\n    parallelSort(less);\n    recurseTask.yieldForce;\n}\n---\n*/\nauto task(alias fun, Args...)(Args args)\n{\n    return new Task!(fun, Args)(args);\n}\n\n/**\nCreates a `Task` on the GC heap that calls a function pointer, delegate, or\nclass/struct with overloaded opCall.\n\nExample:\n---\n// Read two files in at the same time again,\n// but this time use a function pointer instead\n// of an alias to represent std.file.read.\nimport std.file;\n\nvoid main()\n{\n    // Create and execute a Task for reading\n    // foo.txt.\n    auto file1Task = task(&read, \"foo.txt\");\n    file1Task.executeInNewThread();\n\n    // Read bar.txt in parallel.\n    auto file2Data = read(\"bar.txt\");\n\n    // Get the results of reading foo.txt.\n    auto file1Data = file1Task.yieldForce;\n}\n---\n\nNotes: This function takes a non-scope delegate, meaning it can be\n       used with closures.  If you can't allocate a closure due to objects\n       on the stack that have scoped destruction, see `scopedTask`, which\n       takes a scope delegate.\n */\nauto task(F, Args...)(F delegateOrFp, Args args)\nif (is(typeof(delegateOrFp(args))) && !isSafeTask!F)\n{\n    return new Task!(run, F, Args)(delegateOrFp, args);\n}\n\n/**\nVersion of `task` usable from `@safe` code.  Usage mechanics are\nidentical to the non-@safe case, but safety introduces some restrictions:\n\n1.  `fun` must be @safe or @trusted.\n\n2.  `F` must not have any unshared aliasing as defined by\n    $(REF hasUnsharedAliasing, std,traits).  This means it\n    may not be an unshared delegate or a non-shared class or struct\n    with overloaded `opCall`.  This also precludes accepting template\n    alias parameters.\n\n3.  `Args` must not have unshared aliasing.\n\n4.  `fun` must not return by reference.\n\n5.  The return type must not have unshared aliasing unless `fun` is\n    `pure` or the `Task` is executed via `executeInNewThread` instead\n    of using a `TaskPool`.\n\n*/\n@trusted auto task(F, Args...)(F fun, Args args)\nif (is(typeof(fun(args))) && isSafeTask!F)\n{\n    return new Task!(run, F, Args)(fun, args);\n}\n\n/**\nThese functions allow the creation of `Task` objects on the stack rather\nthan the GC heap.  The lifetime of a `Task` created by `scopedTask`\ncannot exceed the lifetime of the scope it was created in.\n\n`scopedTask` might be preferred over `task`:\n\n1.  When a `Task` that calls a delegate is being created and a closure\n    cannot be allocated due to objects on the stack that have scoped\n    destruction.  The delegate overload of `scopedTask` takes a `scope`\n    delegate.\n\n2.  As a micro-optimization, to avoid the heap allocation associated with\n    `task` or with the creation of a closure.\n\nUsage is otherwise identical to `task`.\n\nNotes:  `Task` objects created using `scopedTask` will automatically\ncall `Task.yieldForce` in their destructor if necessary to ensure\nthe `Task` is complete before the stack frame they reside on is destroyed.\n*/\nauto scopedTask(alias fun, Args...)(Args args)\n{\n    auto ret = Task!(fun, Args)(args);\n    ret.isScoped = true;\n    return ret;\n}\n\n/// Ditto\nauto scopedTask(F, Args...)(scope F delegateOrFp, Args args)\nif (is(typeof(delegateOrFp(args))) && !isSafeTask!F)\n{\n    auto ret = Task!(run, F, Args)(delegateOrFp, args);\n    ret.isScoped = true;\n    return ret;\n}\n\n/// Ditto\n@trusted auto scopedTask(F, Args...)(F fun, Args args)\nif (is(typeof(fun(args))) && isSafeTask!F)\n{\n    auto ret = Task!(run, F, Args)(fun, args);\n    ret.isScoped = true;\n    return ret;\n}\n\nversion (useSysctlbyname)\n    private extern(C) int sysctlbyname(\n        const char *, void *, size_t *, void *, size_t\n    ) @nogc nothrow;\n\n/**\nThe total number of CPU cores available on the current machine, as reported by\nthe operating system.\n*/\nalias totalCPUs =\n    __lazilyInitializedConstant!(immutable(uint), uint.max, totalCPUsImpl);\n\nuint totalCPUsImpl() @nogc nothrow @trusted\n{\n    version (Windows)\n    {\n        // BUGS:  Only works on Windows 2000 and above.\n        import core.sys.windows.windows : SYSTEM_INFO, GetSystemInfo;\n        import std.algorithm.comparison : max;\n        SYSTEM_INFO si;\n        GetSystemInfo(&si);\n        return max(1, cast(uint) si.dwNumberOfProcessors);\n    }\n    else version (linux)\n    {\n        import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf;\n        return cast(uint) sysconf(_SC_NPROCESSORS_ONLN);\n    }\n    else version (Solaris)\n    {\n        import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf;\n        return cast(uint) sysconf(_SC_NPROCESSORS_ONLN);\n    }\n    else version (useSysctlbyname)\n    {\n        version (OSX)\n        {\n            auto nameStr = \"machdep.cpu.core_count\\0\".ptr;\n        }\n        else version (FreeBSD)\n        {\n            auto nameStr = \"hw.ncpu\\0\".ptr;\n        }\n        else version (DragonFlyBSD)\n        {\n            auto nameStr = \"hw.ncpu\\0\".ptr;\n        }\n        else version (NetBSD)\n        {\n            auto nameStr = \"hw.ncpu\\0\".ptr;\n        }\n\n        uint result;\n        size_t len = result.sizeof;\n        sysctlbyname(nameStr, &result, &len, null, 0);\n        return result;\n    }\n    else\n    {\n        static assert(0, \"Don't know how to get N CPUs on this OS.\");\n    }\n}\n\n/*\nThis class serves two purposes:\n\n1.  It distinguishes std.parallelism threads from other threads so that\n    the std.parallelism daemon threads can be terminated.\n\n2.  It adds a reference to the pool that the thread is a member of,\n    which is also necessary to allow the daemon threads to be properly\n    terminated.\n*/\nprivate final class ParallelismThread : Thread\n{\n    this(void delegate() dg)\n    {\n        super(dg);\n    }\n\n    TaskPool pool;\n}\n\n// Kill daemon threads.\nshared static ~this()\n{\n    foreach (ref thread; Thread)\n    {\n        auto pthread = cast(ParallelismThread) thread;\n        if (pthread is null) continue;\n        auto pool = pthread.pool;\n        if (!pool.isDaemon) continue;\n        pool.stop();\n        pthread.join();\n    }\n}\n\n/**\nThis class encapsulates a task queue and a set of worker threads.  Its purpose\nis to efficiently map a large number of `Task`s onto a smaller number of\nthreads.  A task queue is a FIFO queue of `Task` objects that have been\nsubmitted to the `TaskPool` and are awaiting execution.  A worker thread is a\nthread that executes the `Task` at the front of the queue when one is\navailable and sleeps when the queue is empty.\n\nThis class should usually be used via the global instantiation\navailable via the $(REF taskPool, std,parallelism) property.\nOccasionally it is useful to explicitly instantiate a `TaskPool`:\n\n1.  When you want `TaskPool` instances with multiple priorities, for example\n    a low priority pool and a high priority pool.\n\n2.  When the threads in the global task pool are waiting on a synchronization\n    primitive (for example a mutex), and you want to parallelize the code that\n    needs to run before these threads can be resumed.\n */\nfinal class TaskPool\n{\nprivate:\n\n    // A pool can either be a regular pool or a single-task pool.  A\n    // single-task pool is a dummy pool that's fired up for\n    // Task.executeInNewThread().\n    bool isSingleTask;\n\n    ParallelismThread[] pool;\n    Thread singleTaskThread;\n\n    AbstractTask* head;\n    AbstractTask* tail;\n    PoolState status = PoolState.running;\n    Condition workerCondition;\n    Condition waiterCondition;\n    Mutex queueMutex;\n    Mutex waiterMutex;  // For waiterCondition\n\n    // The instanceStartIndex of the next instance that will be created.\n    __gshared size_t nextInstanceIndex = 1;\n\n    // The index of the current thread.\n    static size_t threadIndex;\n\n    // The index of the first thread in this instance.\n    immutable size_t instanceStartIndex;\n\n    // The index that the next thread to be initialized in this pool will have.\n    size_t nextThreadIndex;\n\n    enum PoolState : ubyte\n    {\n        running,\n        finishing,\n        stopNow\n    }\n\n    void doJob(AbstractTask* job)\n    {\n        assert(job.taskStatus == TaskStatus.inProgress);\n        assert(job.next is null);\n        assert(job.prev is null);\n\n        scope(exit)\n        {\n            if (!isSingleTask)\n            {\n                waiterLock();\n                scope(exit) waiterUnlock();\n                notifyWaiters();\n            }\n        }\n\n        try\n        {\n            job.job();\n        }\n        catch (Throwable e)\n        {\n            job.exception = e;\n        }\n\n        atomicSetUbyte(job.taskStatus, TaskStatus.done);\n    }\n\n    // This function is used for dummy pools created by Task.executeInNewThread().\n    void doSingleTask()\n    {\n        // No synchronization.  Pool is guaranteed to only have one thread,\n        // and the queue is submitted to before this thread is created.\n        assert(head);\n        auto t = head;\n        t.next = t.prev = head = null;\n        doJob(t);\n    }\n\n    // This function performs initialization for each thread that affects\n    // thread local storage and therefore must be done from within the\n    // worker thread.  It then calls executeWorkLoop().\n    void startWorkLoop()\n    {\n        // Initialize thread index.\n        {\n            queueLock();\n            scope(exit) queueUnlock();\n            threadIndex = nextThreadIndex;\n            nextThreadIndex++;\n        }\n\n        executeWorkLoop();\n    }\n\n    // This is the main work loop that worker threads spend their time in\n    // until they terminate.  It's also entered by non-worker threads when\n    // finish() is called with the blocking variable set to true.\n    void executeWorkLoop()\n    {\n        while (atomicReadUbyte(status) != PoolState.stopNow)\n        {\n            AbstractTask* task = pop();\n            if (task is null)\n            {\n                if (atomicReadUbyte(status) == PoolState.finishing)\n                {\n                    atomicSetUbyte(status, PoolState.stopNow);\n                    return;\n                }\n            }\n            else\n            {\n                doJob(task);\n            }\n        }\n    }\n\n    // Pop a task off the queue.\n    AbstractTask* pop()\n    {\n        queueLock();\n        scope(exit) queueUnlock();\n        auto ret = popNoSync();\n        while (ret is null && status == PoolState.running)\n        {\n            wait();\n            ret = popNoSync();\n        }\n        return ret;\n    }\n\n    AbstractTask* popNoSync()\n    out(returned)\n    {\n        /* If task.prev and task.next aren't null, then another thread\n         * can try to delete this task from the pool after it's\n         * alreadly been deleted/popped.\n         */\n        if (returned !is null)\n        {\n            assert(returned.next is null);\n            assert(returned.prev is null);\n        }\n    }\n    do\n    {\n        if (isSingleTask) return null;\n\n        AbstractTask* returned = head;\n        if (head !is null)\n        {\n            head = head.next;\n            returned.prev = null;\n            returned.next = null;\n            returned.taskStatus = TaskStatus.inProgress;\n        }\n        if (head !is null)\n        {\n            head.prev = null;\n        }\n\n        return returned;\n    }\n\n    // Push a task onto the queue.\n    void abstractPut(AbstractTask* task)\n    {\n        queueLock();\n        scope(exit) queueUnlock();\n        abstractPutNoSync(task);\n    }\n\n    void abstractPutNoSync(AbstractTask* task)\n    in\n    {\n        assert(task);\n    }\n    out\n    {\n        import std.conv : text;\n\n        assert(tail.prev !is tail);\n        assert(tail.next is null, text(tail.prev, '\\t', tail.next));\n        if (tail.prev !is null)\n        {\n            assert(tail.prev.next is tail, text(tail.prev, '\\t', tail.next));\n        }\n    }\n    do\n    {\n        // Not using enforce() to save on function call overhead since this\n        // is a performance critical function.\n        if (status != PoolState.running)\n        {\n            throw new Error(\n                \"Cannot submit a new task to a pool after calling \" ~\n                \"finish() or stop().\"\n            );\n        }\n\n        task.next = null;\n        if (head is null)   //Queue is empty.\n        {\n            head = task;\n            tail = task;\n            tail.prev = null;\n        }\n        else\n        {\n            assert(tail);\n            task.prev = tail;\n            tail.next = task;\n            tail = task;\n        }\n        notify();\n    }\n\n    void abstractPutGroupNoSync(AbstractTask* h, AbstractTask* t)\n    {\n        if (status != PoolState.running)\n        {\n            throw new Error(\n                \"Cannot submit a new task to a pool after calling \" ~\n                \"finish() or stop().\"\n            );\n        }\n\n        if (head is null)\n        {\n            head = h;\n            tail = t;\n        }\n        else\n        {\n            h.prev = tail;\n            tail.next = h;\n            tail = t;\n        }\n\n        notifyAll();\n    }\n\n    void tryDeleteExecute(AbstractTask* toExecute)\n    {\n        if (isSingleTask) return;\n\n        if ( !deleteItem(toExecute) )\n        {\n            return;\n        }\n\n        try\n        {\n            toExecute.job();\n        }\n        catch (Exception e)\n        {\n            toExecute.exception = e;\n        }\n\n        atomicSetUbyte(toExecute.taskStatus, TaskStatus.done);\n    }\n\n    bool deleteItem(AbstractTask* item)\n    {\n        queueLock();\n        scope(exit) queueUnlock();\n        return deleteItemNoSync(item);\n    }\n\n    bool deleteItemNoSync(AbstractTask* item)\n    {\n        if (item.taskStatus != TaskStatus.notStarted)\n        {\n            return false;\n        }\n        item.taskStatus = TaskStatus.inProgress;\n\n        if (item is head)\n        {\n            // Make sure head gets set properly.\n            popNoSync();\n            return true;\n        }\n        if (item is tail)\n        {\n            tail = tail.prev;\n            if (tail !is null)\n            {\n                tail.next = null;\n            }\n            item.next = null;\n            item.prev = null;\n            return true;\n        }\n        if (item.next !is null)\n        {\n            assert(item.next.prev is item);  // Check queue consistency.\n            item.next.prev = item.prev;\n        }\n        if (item.prev !is null)\n        {\n            assert(item.prev.next is item);  // Check queue consistency.\n            item.prev.next = item.next;\n        }\n        item.next = null;\n        item.prev = null;\n        return true;\n    }\n\n    void queueLock()\n    {\n        assert(queueMutex);\n        if (!isSingleTask) queueMutex.lock();\n    }\n\n    void queueUnlock()\n    {\n        assert(queueMutex);\n        if (!isSingleTask) queueMutex.unlock();\n    }\n\n    void waiterLock()\n    {\n        if (!isSingleTask) waiterMutex.lock();\n    }\n\n    void waiterUnlock()\n    {\n        if (!isSingleTask) waiterMutex.unlock();\n    }\n\n    void wait()\n    {\n        if (!isSingleTask) workerCondition.wait();\n    }\n\n    void notify()\n    {\n        if (!isSingleTask) workerCondition.notify();\n    }\n\n    void notifyAll()\n    {\n        if (!isSingleTask) workerCondition.notifyAll();\n    }\n\n    void waitUntilCompletion()\n    {\n        if (isSingleTask)\n        {\n            singleTaskThread.join();\n        }\n        else\n        {\n            waiterCondition.wait();\n        }\n    }\n\n    void notifyWaiters()\n    {\n        if (!isSingleTask) waiterCondition.notifyAll();\n    }\n\n    // Private constructor for creating dummy pools that only have one thread,\n    // only execute one Task, and then terminate.  This is used for\n    // Task.executeInNewThread().\n    this(AbstractTask* task, int priority = int.max)\n    {\n        assert(task);\n\n        // Dummy value, not used.\n        instanceStartIndex = 0;\n\n        this.isSingleTask = true;\n        task.taskStatus = TaskStatus.inProgress;\n        this.head = task;\n        singleTaskThread = new Thread(&doSingleTask);\n        singleTaskThread.start();\n\n        // Disabled until writing code to support\n        // running thread with specified priority\n        // See https://d.puremagic.com/issues/show_bug.cgi?id=8960\n\n        /*if (priority != int.max)\n        {\n            singleTaskThread.priority = priority;\n        }*/\n    }\n\npublic:\n    // This is used in parallel_algorithm but is too unstable to document\n    // as public API.\n    size_t defaultWorkUnitSize(size_t rangeLen) const @safe pure nothrow\n    {\n        import std.algorithm.comparison : max;\n\n        if (this.size == 0)\n        {\n            return rangeLen;\n        }\n\n        immutable size_t eightSize = 4 * (this.size + 1);\n        auto ret = (rangeLen / eightSize) + ((rangeLen % eightSize == 0) ? 0 : 1);\n        return max(ret, 1);\n    }\n\n    /**\n    Default constructor that initializes a `TaskPool` with\n    `totalCPUs` - 1 worker threads.  The minus 1 is included because the\n    main thread will also be available to do work.\n\n    Note:  On single-core machines, the primitives provided by `TaskPool`\n           operate transparently in single-threaded mode.\n     */\n    this() @trusted\n    {\n        this(totalCPUs - 1);\n    }\n\n    /**\n    Allows for custom number of worker threads.\n    */\n    this(size_t nWorkers) @trusted\n    {\n        synchronized(typeid(TaskPool))\n        {\n            instanceStartIndex = nextInstanceIndex;\n\n            // The first worker thread to be initialized will have this index,\n            // and will increment it.  The second worker to be initialized will\n            // have this index plus 1.\n            nextThreadIndex = instanceStartIndex;\n            nextInstanceIndex += nWorkers;\n        }\n\n        queueMutex = new Mutex(this);\n        waiterMutex = new Mutex();\n        workerCondition = new Condition(queueMutex);\n        waiterCondition = new Condition(waiterMutex);\n\n        pool = new ParallelismThread[nWorkers];\n        foreach (ref poolThread; pool)\n        {\n            poolThread = new ParallelismThread(&startWorkLoop);\n            poolThread.pool = this;\n            poolThread.start();\n        }\n    }\n\n    /**\n    Implements a parallel foreach loop over a range.  This works by implicitly\n    creating and submitting one `Task` to the `TaskPool` for each worker\n    thread.  A work unit is a set of consecutive elements of `range` to\n    be processed by a worker thread between communication with any other\n    thread.  The number of elements processed per work unit is controlled by the\n    `workUnitSize` parameter.  Smaller work units provide better load\n    balancing, but larger work units avoid the overhead of communicating\n    with other threads frequently to fetch the next work unit.  Large work\n    units also avoid false sharing in cases where the range is being modified.\n    The less time a single iteration of the loop takes, the larger\n    `workUnitSize` should be.  For very expensive loop bodies,\n    `workUnitSize` should  be 1.  An overload that chooses a default work\n    unit size is also available.\n\n    Example:\n    ---\n    // Find the logarithm of every number from 1 to\n    // 10_000_000 in parallel.\n    auto logs = new double[10_000_000];\n\n    // Parallel foreach works with or without an index\n    // variable.  It can be iterate by ref if range.front\n    // returns by ref.\n\n    // Iterate over logs using work units of size 100.\n    foreach (i, ref elem; taskPool.parallel(logs, 100))\n    {\n        elem = log(i + 1.0);\n    }\n\n    // Same thing, but use the default work unit size.\n    //\n    // Timings on an Athlon 64 X2 dual core machine:\n    //\n    // Parallel foreach:  388 milliseconds\n    // Regular foreach:   619 milliseconds\n    foreach (i, ref elem; taskPool.parallel(logs))\n    {\n        elem = log(i + 1.0);\n    }\n    ---\n\n    Notes:\n\n    The memory usage of this implementation is guaranteed to be constant\n    in `range.length`.\n\n    Breaking from a parallel foreach loop via a break, labeled break,\n    labeled continue, return or goto statement throws a\n    `ParallelForeachError`.\n\n    In the case of non-random access ranges, parallel foreach buffers lazily\n    to an array of size `workUnitSize` before executing the parallel portion\n    of the loop.  The exception is that, if a parallel foreach is executed\n    over a range returned by `asyncBuf` or `map`, the copying is elided\n    and the buffers are simply swapped.  In this case `workUnitSize` is\n    ignored and the work unit size is set to the  buffer size of `range`.\n\n    A memory barrier is guaranteed to be executed on exit from the loop,\n    so that results produced by all threads are visible in the calling thread.\n\n    $(B Exception Handling):\n\n    When at least one exception is thrown from inside a parallel foreach loop,\n    the submission of additional `Task` objects is terminated as soon as\n    possible, in a non-deterministic manner.  All executing or\n    enqueued work units are allowed to complete.  Then, all exceptions that\n    were thrown by any work unit are chained using `Throwable.next` and\n    rethrown.  The order of the exception chaining is non-deterministic.\n    */\n    ParallelForeach!R parallel(R)(R range, size_t workUnitSize)\n    {\n        import std.exception : enforce;\n        enforce(workUnitSize > 0, \"workUnitSize must be > 0.\");\n        alias RetType = ParallelForeach!R;\n        return RetType(this, range, workUnitSize);\n    }\n\n\n    /// Ditto\n    ParallelForeach!R parallel(R)(R range)\n    {\n        static if (hasLength!R)\n        {\n            // Default work unit size is such that we would use 4x as many\n            // slots as are in this thread pool.\n            size_t workUnitSize = defaultWorkUnitSize(range.length);\n            return parallel(range, workUnitSize);\n        }\n        else\n        {\n            // Just use a really, really dumb guess if the user is too lazy to\n            // specify.\n            return parallel(range, 512);\n        }\n    }\n\n    ///\n    template amap(functions...)\n    {\n        /**\n        Eager parallel map.  The eagerness of this function means it has less\n        overhead than the lazily evaluated `TaskPool.map` and should be\n        preferred where the memory requirements of eagerness are acceptable.\n        `functions` are the functions to be evaluated, passed as template\n        alias parameters in a style similar to\n        $(REF map, std,algorithm,iteration).\n        The first argument must be a random access range. For performance\n        reasons, amap will assume the range elements have not yet been\n        initialized. Elements will be overwritten without calling a destructor\n        nor doing an assignment. As such, the range must not contain meaningful\n        data$(DDOC_COMMENT not a section): either un-initialized objects, or\n        objects in their `.init` state.\n\n        ---\n        auto numbers = iota(100_000_000.0);\n\n        // Find the square roots of numbers.\n        //\n        // Timings on an Athlon 64 X2 dual core machine:\n        //\n        // Parallel eager map:                   0.802 s\n        // Equivalent serial implementation:     1.768 s\n        auto squareRoots = taskPool.amap!sqrt(numbers);\n        ---\n\n        Immediately after the range argument, an optional work unit size argument\n        may be provided.  Work units as used by `amap` are identical to those\n        defined for parallel foreach.  If no work unit size is provided, the\n        default work unit size is used.\n\n        ---\n        // Same thing, but make work unit size 100.\n        auto squareRoots = taskPool.amap!sqrt(numbers, 100);\n        ---\n\n        An output range for returning the results may be provided as the last\n        argument.  If one is not provided, an array of the proper type will be\n        allocated on the garbage collected heap.  If one is provided, it must be a\n        random access range with assignable elements, must have reference\n        semantics with respect to assignment to its elements, and must have the\n        same length as the input range.  Writing to adjacent elements from\n        different threads must be safe.\n\n        ---\n        // Same thing, but explicitly allocate an array\n        // to return the results in.  The element type\n        // of the array may be either the exact type\n        // returned by functions or an implicit conversion\n        // target.\n        auto squareRoots = new float[numbers.length];\n        taskPool.amap!sqrt(numbers, squareRoots);\n\n        // Multiple functions, explicit output range, and\n        // explicit work unit size.\n        auto results = new Tuple!(float, real)[numbers.length];\n        taskPool.amap!(sqrt, log)(numbers, 100, results);\n        ---\n\n        Note:\n\n        A memory barrier is guaranteed to be executed after all results are written\n        but before returning so that results produced by all threads are visible\n        in the calling thread.\n\n        Tips:\n\n        To perform the mapping operation in place, provide the same range for the\n        input and output range.\n\n        To parallelize the copying of a range with expensive to evaluate elements\n        to an array, pass an identity function (a function that just returns\n        whatever argument is provided to it) to `amap`.\n\n        $(B Exception Handling):\n\n        When at least one exception is thrown from inside the map functions,\n        the submission of additional `Task` objects is terminated as soon as\n        possible, in a non-deterministic manner.  All currently executing or\n        enqueued work units are allowed to complete.  Then, all exceptions that\n        were thrown from any work unit are chained using `Throwable.next` and\n        rethrown.  The order of the exception chaining is non-deterministic.\n        */\n        auto amap(Args...)(Args args)\n        if (isRandomAccessRange!(Args[0]))\n        {\n            import std.conv : emplaceRef;\n\n            alias fun = adjoin!(staticMap!(unaryFun, functions));\n\n            alias range = args[0];\n            immutable len = range.length;\n\n            static if (\n                Args.length > 1 &&\n                randAssignable!(Args[$ - 1]) &&\n                is(MapType!(Args[0], functions) : ElementType!(Args[$ - 1]))\n                )\n            {\n                import std.conv : text;\n                import std.exception : enforce;\n\n                alias buf = args[$ - 1];\n                alias args2 = args[0..$ - 1];\n                alias Args2 = Args[0..$ - 1];\n                enforce(buf.length == len,\n                        text(\"Can't use a user supplied buffer that's the wrong \",\n                             \"size.  (Expected  :\", len, \" Got:  \", buf.length));\n            }\n            else static if (randAssignable!(Args[$ - 1]) && Args.length > 1)\n            {\n                static assert(0, \"Wrong buffer type.\");\n            }\n            else\n            {\n                import std.array : uninitializedArray;\n\n                auto buf = uninitializedArray!(MapType!(Args[0], functions)[])(len);\n                alias args2 = args;\n                alias Args2 = Args;\n            }\n\n            if (!len) return buf;\n\n            static if (isIntegral!(Args2[$ - 1]))\n            {\n                static assert(args2.length == 2);\n                auto workUnitSize = cast(size_t) args2[1];\n            }\n            else\n            {\n                static assert(args2.length == 1, Args);\n                auto workUnitSize = defaultWorkUnitSize(range.length);\n            }\n\n            alias R = typeof(range);\n\n            if (workUnitSize > len)\n            {\n                workUnitSize = len;\n            }\n\n            // Handle as a special case:\n            if (size == 0)\n            {\n                size_t index = 0;\n                foreach (elem; range)\n                {\n                    emplaceRef(buf[index++], fun(elem));\n                }\n                return buf;\n            }\n\n            // Effectively -1:  chunkIndex + 1 == 0:\n            shared size_t workUnitIndex = size_t.max;\n            shared bool shouldContinue = true;\n\n            void doIt()\n            {\n                import std.algorithm.comparison : min;\n\n                scope(failure)\n                {\n                    // If an exception is thrown, all threads should bail.\n                    atomicStore(shouldContinue, false);\n                }\n\n                while (atomicLoad(shouldContinue))\n                {\n                    immutable myUnitIndex = atomicOp!\"+=\"(workUnitIndex, 1);\n                    immutable start = workUnitSize * myUnitIndex;\n                    if (start >= len)\n                    {\n                        atomicStore(shouldContinue, false);\n                        break;\n                    }\n\n                    immutable end = min(len, start + workUnitSize);\n\n                    static if (hasSlicing!R)\n                    {\n                        auto subrange = range[start .. end];\n                        foreach (i; start .. end)\n                        {\n                            emplaceRef(buf[i], fun(subrange.front));\n                            subrange.popFront();\n                        }\n                    }\n                    else\n                    {\n                        foreach (i; start .. end)\n                        {\n                            emplaceRef(buf[i], fun(range[i]));\n                        }\n                    }\n                }\n            }\n\n            submitAndExecute(this, &doIt);\n            return buf;\n        }\n    }\n\n    ///\n    template map(functions...)\n    {\n        /**\n        A semi-lazy parallel map that can be used for pipelining.  The map\n        functions are evaluated for the first `bufSize` elements and stored in a\n        buffer and made available to `popFront`.  Meanwhile, in the\n        background a second buffer of the same size is filled.  When the first\n        buffer is exhausted, it is swapped with the second buffer and filled while\n        the values from what was originally the second buffer are read.  This\n        implementation allows for elements to be written to the buffer without\n        the need for atomic operations or synchronization for each write, and\n        enables the mapping function to be evaluated efficiently in parallel.\n\n        `map` has more overhead than the simpler procedure used by `amap`\n        but avoids the need to keep all results in memory simultaneously and works\n        with non-random access ranges.\n\n        Params:\n\n        source = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n        to be mapped.  If `source` is not random\n        access it will be lazily buffered to an array of size `bufSize` before\n        the map function is evaluated.  (For an exception to this rule, see Notes.)\n\n        bufSize = The size of the buffer to store the evaluated elements.\n\n        workUnitSize = The number of elements to evaluate in a single\n        `Task`.  Must be less than or equal to `bufSize`, and\n        should be a fraction of `bufSize` such that all worker threads can be\n        used.  If the default of size_t.max is used, workUnitSize will be set to\n        the pool-wide default.\n\n        Returns:  An input range representing the results of the map.  This range\n                  has a length iff `source` has a length.\n\n        Notes:\n\n        If a range returned by `map` or `asyncBuf` is used as an input to\n        `map`, then as an optimization the copying from the output buffer\n        of the first range to the input buffer of the second range is elided, even\n        though the ranges returned by `map` and `asyncBuf` are non-random\n        access ranges.  This means that the `bufSize` parameter passed to the\n        current call to `map` will be ignored and the size of the buffer\n        will be the buffer size of `source`.\n\n        Example:\n        ---\n        // Pipeline reading a file, converting each line\n        // to a number, taking the logarithms of the numbers,\n        // and performing the additions necessary to find\n        // the sum of the logarithms.\n\n        auto lineRange = File(\"numberList.txt\").byLine();\n        auto dupedLines = std.algorithm.map!\"a.idup\"(lineRange);\n        auto nums = taskPool.map!(to!double)(dupedLines);\n        auto logs = taskPool.map!log10(nums);\n\n        double sum = 0;\n        foreach (elem; logs)\n        {\n            sum += elem;\n        }\n        ---\n\n        $(B Exception Handling):\n\n        Any exceptions thrown while iterating over `source`\n        or computing the map function are re-thrown on a call to `popFront` or,\n        if thrown during construction, are simply allowed to propagate to the\n        caller.  In the case of exceptions thrown while computing the map function,\n        the exceptions are chained as in `TaskPool.amap`.\n        */\n        auto\n        map(S)(S source, size_t bufSize = 100, size_t workUnitSize = size_t.max)\n        if (isInputRange!S)\n        {\n            import std.exception : enforce;\n\n            enforce(workUnitSize == size_t.max || workUnitSize <= bufSize,\n                    \"Work unit size must be smaller than buffer size.\");\n            alias fun = adjoin!(staticMap!(unaryFun, functions));\n\n            static final class Map\n            {\n                // This is a class because the task needs to be located on the\n                // heap and in the non-random access case source needs to be on\n                // the heap, too.\n\n            private:\n                enum bufferTrick = is(typeof(source.buf1)) &&\n                is(typeof(source.bufPos)) &&\n                is(typeof(source.doBufSwap()));\n\n                alias E = MapType!(S, functions);\n                E[] buf1, buf2;\n                S source;\n                TaskPool pool;\n                Task!(run, E[] delegate(E[]), E[]) nextBufTask;\n                size_t workUnitSize;\n                size_t bufPos;\n                bool lastTaskWaited;\n\n            static if (isRandomAccessRange!S)\n            {\n                alias FromType = S;\n\n                void popSource()\n                {\n                    import std.algorithm.comparison : min;\n\n                    static if (__traits(compiles, source[0 .. source.length]))\n                    {\n                        source = source[min(buf1.length, source.length)..source.length];\n                    }\n                    else static if (__traits(compiles, source[0..$]))\n                    {\n                        source = source[min(buf1.length, source.length)..$];\n                    }\n                    else\n                    {\n                        static assert(0, \"S must have slicing for Map.\"\n                                      ~ \"  \" ~ S.stringof ~ \" doesn't.\");\n                    }\n                }\n            }\n            else static if (bufferTrick)\n            {\n                // Make sure we don't have the buffer recycling overload of\n                // asyncBuf.\n                static if (\n                    is(typeof(source.source)) &&\n                    isRoundRobin!(typeof(source.source))\n                )\n                {\n                    static assert(0, \"Cannot execute a parallel map on \" ~\n                                  \"the buffer recycling overload of asyncBuf.\"\n                                 );\n                }\n\n                alias FromType = typeof(source.buf1);\n                FromType from;\n\n                // Just swap our input buffer with source's output buffer.\n                // No need to copy element by element.\n                FromType dumpToFrom()\n                {\n                    import std.algorithm.mutation : swap;\n\n                    assert(source.buf1.length <= from.length);\n                    from.length = source.buf1.length;\n                    swap(source.buf1, from);\n\n                    // Just in case this source has been popped before\n                    // being sent to map:\n                    from = from[source.bufPos..$];\n\n                    static if (is(typeof(source._length)))\n                    {\n                        source._length -= (from.length - source.bufPos);\n                    }\n\n                    source.doBufSwap();\n\n                    return from;\n                }\n            }\n            else\n            {\n                alias FromType = ElementType!S[];\n\n                // The temporary array that data is copied to before being\n                // mapped.\n                FromType from;\n\n                FromType dumpToFrom()\n                {\n                    assert(from !is null);\n\n                    size_t i;\n                    for (; !source.empty && i < from.length; source.popFront())\n                    {\n                        from[i++] = source.front;\n                    }\n\n                    from = from[0 .. i];\n                    return from;\n                }\n            }\n\n            static if (hasLength!S)\n            {\n                size_t _length;\n\n                public @property size_t length() const @safe pure nothrow\n                {\n                    return _length;\n                }\n            }\n\n                this(S source, size_t bufSize, size_t workUnitSize, TaskPool pool)\n                {\n                    static if (bufferTrick)\n                    {\n                        bufSize = source.buf1.length;\n                    }\n\n                    buf1.length = bufSize;\n                    buf2.length = bufSize;\n\n                    static if (!isRandomAccessRange!S)\n                    {\n                        from.length = bufSize;\n                    }\n\n                    this.workUnitSize = (workUnitSize == size_t.max) ?\n                            pool.defaultWorkUnitSize(bufSize) : workUnitSize;\n                    this.source = source;\n                    this.pool = pool;\n\n                    static if (hasLength!S)\n                    {\n                        _length = source.length;\n                    }\n\n                    buf1 = fillBuf(buf1);\n                    submitBuf2();\n                }\n\n                // The from parameter is a dummy and ignored in the random access\n                // case.\n                E[] fillBuf(E[] buf)\n                {\n                    import std.algorithm.comparison : min;\n\n                    static if (isRandomAccessRange!S)\n                    {\n                        import std.range : take;\n                        auto toMap = take(source, buf.length);\n                        scope(success) popSource();\n                    }\n                    else\n                    {\n                        auto toMap = dumpToFrom();\n                    }\n\n                    buf = buf[0 .. min(buf.length, toMap.length)];\n\n                    // Handle as a special case:\n                    if (pool.size == 0)\n                    {\n                        size_t index = 0;\n                        foreach (elem; toMap)\n                        {\n                            buf[index++] = fun(elem);\n                        }\n                        return buf;\n                    }\n\n                    pool.amap!functions(toMap, workUnitSize, buf);\n\n                    return buf;\n                }\n\n                void submitBuf2()\n                in\n                {\n                    assert(nextBufTask.prev is null);\n                    assert(nextBufTask.next is null);\n                }\n                do\n                {\n                    // Hack to reuse the task object.\n\n                    nextBufTask = typeof(nextBufTask).init;\n                    nextBufTask._args[0] = &fillBuf;\n                    nextBufTask._args[1] = buf2;\n                    pool.put(nextBufTask);\n                }\n\n                void doBufSwap()\n                {\n                    if (lastTaskWaited)\n                    {\n                        // Then the source is empty.  Signal it here.\n                        buf1 = null;\n                        buf2 = null;\n\n                        static if (!isRandomAccessRange!S)\n                        {\n                            from = null;\n                        }\n\n                        return;\n                    }\n\n                    buf2 = buf1;\n                    buf1 = nextBufTask.yieldForce;\n                    bufPos = 0;\n\n                    if (source.empty)\n                    {\n                        lastTaskWaited = true;\n                    }\n                    else\n                    {\n                        submitBuf2();\n                    }\n                }\n\n            public:\n                @property auto front()\n                {\n                    return buf1[bufPos];\n                }\n\n                void popFront()\n                {\n                    static if (hasLength!S)\n                    {\n                        _length--;\n                    }\n\n                    bufPos++;\n                    if (bufPos >= buf1.length)\n                    {\n                        doBufSwap();\n                    }\n                }\n\n                static if (isInfinite!S)\n                {\n                    enum bool empty = false;\n                }\n                else\n                {\n\n                    bool empty() const @property\n                    {\n                        // popFront() sets this when source is empty\n                        return buf1.length == 0;\n                    }\n                }\n            }\n            return new Map(source, bufSize, workUnitSize, this);\n        }\n    }\n\n    /**\n    Given a `source` range that is expensive to iterate over, returns an\n    $(REF_ALTTEXT input range, isInputRange, std,range,primitives) that\n    asynchronously buffers the contents of `source` into a buffer of `bufSize` elements in a worker thread,\n    while making previously buffered elements from a second buffer, also of size\n    `bufSize`, available via the range interface of the returned\n    object.  The returned range has a length iff `hasLength!S`.\n    `asyncBuf` is useful, for example, when performing expensive operations\n    on the elements of ranges that represent data on a disk or network.\n\n    Example:\n    ---\n    import std.conv, std.stdio;\n\n    void main()\n    {\n        // Fetch lines of a file in a background thread\n        // while processing previously fetched lines,\n        // dealing with byLine's buffer recycling by\n        // eagerly duplicating every line.\n        auto lines = File(\"foo.txt\").byLine();\n        auto duped = std.algorithm.map!\"a.idup\"(lines);\n\n        // Fetch more lines in the background while we\n        // process the lines already read into memory\n        // into a matrix of doubles.\n        double[][] matrix;\n        auto asyncReader = taskPool.asyncBuf(duped);\n\n        foreach (line; asyncReader)\n        {\n            auto ls = line.split(\"\\t\");\n            matrix ~= to!(double[])(ls);\n        }\n    }\n    ---\n\n    $(B Exception Handling):\n\n    Any exceptions thrown while iterating over `source` are re-thrown on a\n    call to `popFront` or, if thrown during construction, simply\n    allowed to propagate to the caller.\n    */\n    auto asyncBuf(S)(S source, size_t bufSize = 100) if (isInputRange!S)\n    {\n        static final class AsyncBuf\n        {\n            // This is a class because the task and source both need to be on\n            // the heap.\n\n            // The element type of S.\n            alias E = ElementType!S;  // Needs to be here b/c of forward ref bugs.\n\n        private:\n            E[] buf1, buf2;\n            S source;\n            TaskPool pool;\n            Task!(run, E[] delegate(E[]), E[]) nextBufTask;\n            size_t bufPos;\n            bool lastTaskWaited;\n\n            static if (hasLength!S)\n            {\n                size_t _length;\n\n                // Available if hasLength!S.\n                public @property size_t length() const @safe pure nothrow\n                {\n                    return _length;\n                }\n            }\n\n            this(S source, size_t bufSize, TaskPool pool)\n            {\n                buf1.length = bufSize;\n                buf2.length = bufSize;\n\n                this.source = source;\n                this.pool = pool;\n\n                static if (hasLength!S)\n                {\n                    _length = source.length;\n                }\n\n                buf1 = fillBuf(buf1);\n                submitBuf2();\n            }\n\n            E[] fillBuf(E[] buf)\n            {\n                assert(buf !is null);\n\n                size_t i;\n                for (; !source.empty && i < buf.length; source.popFront())\n                {\n                    buf[i++] = source.front;\n                }\n\n                buf = buf[0 .. i];\n                return buf;\n            }\n\n            void submitBuf2()\n            in\n            {\n                assert(nextBufTask.prev is null);\n                assert(nextBufTask.next is null);\n            }\n            do\n            {\n                // Hack to reuse the task object.\n\n                nextBufTask = typeof(nextBufTask).init;\n                nextBufTask._args[0] = &fillBuf;\n                nextBufTask._args[1] = buf2;\n                pool.put(nextBufTask);\n            }\n\n            void doBufSwap()\n            {\n                if (lastTaskWaited)\n                {\n                    // Then source is empty.  Signal it here.\n                    buf1 = null;\n                    buf2 = null;\n                    return;\n                }\n\n                buf2 = buf1;\n                buf1 = nextBufTask.yieldForce;\n                bufPos = 0;\n\n                if (source.empty)\n                {\n                    lastTaskWaited = true;\n                }\n                else\n                {\n                    submitBuf2();\n                }\n            }\n\n        public:\n            E front() @property\n            {\n                return buf1[bufPos];\n            }\n\n            void popFront()\n            {\n                static if (hasLength!S)\n                {\n                    _length--;\n                }\n\n                bufPos++;\n                if (bufPos >= buf1.length)\n                {\n                    doBufSwap();\n                }\n            }\n\n            static if (isInfinite!S)\n            {\n                enum bool empty = false;\n            }\n\n            else\n            {\n                ///\n                bool empty() @property\n                {\n                    // popFront() sets this when source is empty:\n                    return buf1.length == 0;\n                }\n            }\n        }\n        return new AsyncBuf(source, bufSize, this);\n    }\n\n    /**\n    Given a callable object `next` that writes to a user-provided buffer and\n    a second callable object `empty` that determines whether more data is\n    available to write via `next`, returns an input range that\n    asynchronously calls `next` with a set of size `nBuffers` of buffers\n    and makes the results available in the order they were obtained via the\n    input range interface of the returned object.  Similarly to the\n    input range overload of `asyncBuf`, the first half of the buffers\n    are made available via the range interface while the second half are\n    filled and vice-versa.\n\n    Params:\n\n    next = A callable object that takes a single argument that must be an array\n           with mutable elements.  When called, `next` writes data to\n           the array provided by the caller.\n\n    empty = A callable object that takes no arguments and returns a type\n            implicitly convertible to `bool`.  This is used to signify\n            that no more data is available to be obtained by calling `next`.\n\n    initialBufSize = The initial size of each buffer.  If `next` takes its\n                     array by reference, it may resize the buffers.\n\n    nBuffers = The number of buffers to cycle through when calling `next`.\n\n    Example:\n    ---\n    // Fetch lines of a file in a background\n    // thread while processing previously fetched\n    // lines, without duplicating any lines.\n    auto file = File(\"foo.txt\");\n\n    void next(ref char[] buf)\n    {\n        file.readln(buf);\n    }\n\n    // Fetch more lines in the background while we\n    // process the lines already read into memory\n    // into a matrix of doubles.\n    double[][] matrix;\n    auto asyncReader = taskPool.asyncBuf(&next, &file.eof);\n\n    foreach (line; asyncReader)\n    {\n        auto ls = line.split(\"\\t\");\n        matrix ~= to!(double[])(ls);\n    }\n    ---\n\n    $(B Exception Handling):\n\n    Any exceptions thrown while iterating over `range` are re-thrown on a\n    call to `popFront`.\n\n    Warning:\n\n    Using the range returned by this function in a parallel foreach loop\n    will not work because buffers may be overwritten while the task that\n    processes them is in queue.  This is checked for at compile time\n    and will result in a static assertion failure.\n    */\n    auto asyncBuf(C1, C2)(C1 next, C2 empty, size_t initialBufSize = 0, size_t nBuffers = 100)\n    if (is(typeof(C2.init()) : bool) &&\n        Parameters!C1.length == 1 &&\n        Parameters!C2.length == 0 &&\n        isArray!(Parameters!C1[0])\n    ) {\n        auto roundRobin = RoundRobinBuffer!(C1, C2)(next, empty, initialBufSize, nBuffers);\n        return asyncBuf(roundRobin, nBuffers / 2);\n    }\n\n    ///\n    template reduce(functions...)\n    {\n        /**\n        Parallel reduce on a random access range.  Except as otherwise noted,\n        usage is similar to $(REF _reduce, std,algorithm,iteration).  There is\n        also $(LREF fold) which does the same thing with a different parameter\n        order.\n\n        This function works by splitting the range to be reduced into work\n        units, which are slices to be reduced in parallel.  Once the results\n        from all work units are computed, a final serial reduction is performed\n        on these results to compute the final answer. Therefore, care must be\n        taken to choose the seed value appropriately.\n\n        Because the reduction is being performed in parallel, `functions`\n        must be associative.  For notational simplicity, let # be an\n        infix operator representing `functions`.  Then, (a # b) # c must equal\n        a # (b # c).  Floating point addition is not associative\n        even though addition in exact arithmetic is.  Summing floating\n        point numbers using this function may give different results than summing\n        serially.  However, for many practical purposes floating point addition\n        can be treated as associative.\n\n        Note that, since `functions` are assumed to be associative,\n        additional optimizations are made to the serial portion of the reduction\n        algorithm. These take advantage of the instruction level parallelism of\n        modern CPUs, in addition to the thread-level parallelism that the rest\n        of this module exploits.  This can lead to better than linear speedups\n        relative to $(REF _reduce, std,algorithm,iteration), especially for\n        fine-grained benchmarks like dot products.\n\n        An explicit seed may be provided as the first argument.  If\n        provided, it is used as the seed for all work units and for the final\n        reduction of results from all work units.  Therefore, if it is not the\n        identity value for the operation being performed, results may differ\n        from those generated by $(REF _reduce, std,algorithm,iteration) or\n        depending on how many work units are used.  The next argument must be\n        the range to be reduced.\n        ---\n        // Find the sum of squares of a range in parallel, using\n        // an explicit seed.\n        //\n        // Timings on an Athlon 64 X2 dual core machine:\n        //\n        // Parallel reduce:                     72 milliseconds\n        // Using std.algorithm.reduce instead:  181 milliseconds\n        auto nums = iota(10_000_000.0f);\n        auto sumSquares = taskPool.reduce!\"a + b\"(\n            0.0, std.algorithm.map!\"a * a\"(nums)\n        );\n        ---\n\n        If no explicit seed is provided, the first element of each work unit\n        is used as a seed.  For the final reduction, the result from the first\n        work unit is used as the seed.\n        ---\n        // Find the sum of a range in parallel, using the first\n        // element of each work unit as the seed.\n        auto sum = taskPool.reduce!\"a + b\"(nums);\n        ---\n\n        An explicit work unit size may be specified as the last argument.\n        Specifying too small a work unit size will effectively serialize the\n        reduction, as the final reduction of the result of each work unit will\n        dominate computation time.  If `TaskPool.size` for this instance\n        is zero, this parameter is ignored and one work unit is used.\n        ---\n        // Use a work unit size of 100.\n        auto sum2 = taskPool.reduce!\"a + b\"(nums, 100);\n\n        // Work unit size of 100 and explicit seed.\n        auto sum3 = taskPool.reduce!\"a + b\"(0.0, nums, 100);\n        ---\n\n        Parallel reduce supports multiple functions, like\n        `std.algorithm.reduce`.\n        ---\n        // Find both the min and max of nums.\n        auto minMax = taskPool.reduce!(min, max)(nums);\n        assert(minMax[0] == reduce!min(nums));\n        assert(minMax[1] == reduce!max(nums));\n        ---\n\n        $(B Exception Handling):\n\n        After this function is finished executing, any exceptions thrown\n        are chained together via `Throwable.next` and rethrown.  The chaining\n        order is non-deterministic.\n\n        See_Also:\n\n            $(LREF fold) is functionally equivalent to $(LREF _reduce) except the\n            range parameter comes first and there is no need to use\n            $(REF_ALTTEXT `tuple`,tuple,std,typecons) for multiple seeds.\n         */\n        auto reduce(Args...)(Args args)\n        {\n            import core.exception : OutOfMemoryError;\n            import std.conv : emplaceRef;\n            import std.exception : enforce;\n\n            alias fun = reduceAdjoin!functions;\n            alias finishFun = reduceFinish!functions;\n\n            static if (isIntegral!(Args[$ - 1]))\n            {\n                size_t workUnitSize = cast(size_t) args[$ - 1];\n                alias args2 = args[0..$ - 1];\n                alias Args2 = Args[0..$ - 1];\n            }\n            else\n            {\n                alias args2 = args;\n                alias Args2 = Args;\n            }\n\n            auto makeStartValue(Type)(Type e)\n            {\n                static if (functions.length == 1)\n                {\n                    return e;\n                }\n                else\n                {\n                    typeof(adjoin!(staticMap!(binaryFun, functions))(e, e)) seed = void;\n                    foreach (i, T; seed.Types)\n                    {\n                        emplaceRef(seed.expand[i], e);\n                    }\n\n                    return seed;\n                }\n            }\n\n            static if (args2.length == 2)\n            {\n                static assert(isInputRange!(Args2[1]));\n                alias range = args2[1];\n                alias seed = args2[0];\n                enum explicitSeed = true;\n\n                static if (!is(typeof(workUnitSize)))\n                {\n                    size_t workUnitSize = defaultWorkUnitSize(range.length);\n                }\n            }\n            else\n            {\n                static assert(args2.length == 1);\n                alias range = args2[0];\n\n                static if (!is(typeof(workUnitSize)))\n                {\n                    size_t workUnitSize = defaultWorkUnitSize(range.length);\n                }\n\n                enforce(!range.empty,\n                    \"Cannot reduce an empty range with first element as start value.\");\n\n                auto seed = makeStartValue(range.front);\n                enum explicitSeed = false;\n                range.popFront();\n            }\n\n            alias E = typeof(seed);\n            alias R = typeof(range);\n\n            E reduceOnRange(R range, size_t lowerBound, size_t upperBound)\n            {\n                // This is for exploiting instruction level parallelism by\n                // using multiple accumulator variables within each thread,\n                // since we're assuming functions are associative anyhow.\n\n                // This is so that loops can be unrolled automatically.\n                enum ilpTuple = AliasSeq!(0, 1, 2, 3, 4, 5);\n                enum nILP = ilpTuple.length;\n                immutable subSize = (upperBound - lowerBound) / nILP;\n\n                if (subSize <= 1)\n                {\n                    // Handle as a special case.\n                    static if (explicitSeed)\n                    {\n                        E result = seed;\n                    }\n                    else\n                    {\n                        E result = makeStartValue(range[lowerBound]);\n                        lowerBound++;\n                    }\n\n                    foreach (i; lowerBound .. upperBound)\n                    {\n                        result = fun(result, range[i]);\n                    }\n\n                    return result;\n                }\n\n                assert(subSize > 1);\n                E[nILP] results;\n                size_t[nILP] offsets;\n\n                foreach (i; ilpTuple)\n                {\n                    offsets[i] = lowerBound + subSize * i;\n\n                    static if (explicitSeed)\n                    {\n                        results[i] = seed;\n                    }\n                    else\n                    {\n                        results[i] = makeStartValue(range[offsets[i]]);\n                        offsets[i]++;\n                    }\n                }\n\n                immutable nLoop = subSize - (!explicitSeed);\n                foreach (i; 0 .. nLoop)\n                {\n                    foreach (j; ilpTuple)\n                    {\n                        results[j] = fun(results[j], range[offsets[j]]);\n                        offsets[j]++;\n                    }\n                }\n\n                // Finish the remainder.\n                foreach (i; nILP * subSize + lowerBound .. upperBound)\n                {\n                    results[$ - 1] = fun(results[$ - 1], range[i]);\n                }\n\n                foreach (i; ilpTuple[1..$])\n                {\n                    results[0] = finishFun(results[0], results[i]);\n                }\n\n                return results[0];\n            }\n\n            immutable len = range.length;\n            if (len == 0)\n            {\n                return seed;\n            }\n\n            if (this.size == 0)\n            {\n                return finishFun(seed, reduceOnRange(range, 0, len));\n            }\n\n            // Unlike the rest of the functions here, I can't use the Task object\n            // recycling trick here because this has to work on non-commutative\n            // operations.  After all the tasks are done executing, fun() has to\n            // be applied on the results of these to get a final result, but\n            // it can't be evaluated out of order.\n\n            if (workUnitSize > len)\n            {\n                workUnitSize = len;\n            }\n\n            immutable size_t nWorkUnits = (len / workUnitSize) + ((len % workUnitSize == 0) ? 0 : 1);\n            assert(nWorkUnits * workUnitSize >= len);\n\n            alias RTask = Task!(run, typeof(&reduceOnRange), R, size_t, size_t);\n            RTask[] tasks;\n\n            // Can't use alloca() due to Bug 3753.  Use a fixed buffer\n            // backed by malloc().\n            enum maxStack = 2_048;\n            byte[maxStack] buf = void;\n            immutable size_t nBytesNeeded = nWorkUnits * RTask.sizeof;\n\n            import core.stdc.stdlib : malloc, free;\n            if (nBytesNeeded < maxStack)\n            {\n                tasks = (cast(RTask*) buf.ptr)[0 .. nWorkUnits];\n            }\n            else\n            {\n                auto ptr = cast(RTask*) malloc(nBytesNeeded);\n                if (!ptr)\n                {\n                    throw new OutOfMemoryError(\n                        \"Out of memory in std.parallelism.\"\n                    );\n                }\n\n                tasks = ptr[0 .. nWorkUnits];\n            }\n\n            scope(exit)\n            {\n                if (nBytesNeeded > maxStack)\n                {\n                    free(tasks.ptr);\n                }\n            }\n\n            foreach (ref t; tasks[])\n                emplaceRef(t, RTask());\n\n            // Hack to take the address of a nested function w/o\n            // making a closure.\n            static auto scopedAddress(D)(scope D del) @system\n            {\n                auto tmp = del;\n                return tmp;\n            }\n\n            size_t curPos = 0;\n            void useTask(ref RTask task)\n            {\n                import std.algorithm.comparison : min;\n\n                task.pool = this;\n                task._args[0] = scopedAddress(&reduceOnRange);\n                task._args[3] = min(len, curPos + workUnitSize);  // upper bound.\n                task._args[1] = range;  // range\n                task._args[2] = curPos; // lower bound.\n\n                curPos += workUnitSize;\n            }\n\n            foreach (ref task; tasks)\n            {\n                useTask(task);\n            }\n\n            foreach (i; 1 .. tasks.length - 1)\n            {\n                tasks[i].next = tasks[i + 1].basePtr;\n                tasks[i + 1].prev = tasks[i].basePtr;\n            }\n\n            if (tasks.length > 1)\n            {\n                queueLock();\n                scope(exit) queueUnlock();\n\n                abstractPutGroupNoSync(\n                    tasks[1].basePtr,\n                    tasks[$ - 1].basePtr\n                );\n            }\n\n            if (tasks.length > 0)\n            {\n                try\n                {\n                    tasks[0].job();\n                }\n                catch (Throwable e)\n                {\n                    tasks[0].exception = e;\n                }\n                tasks[0].taskStatus = TaskStatus.done;\n\n                // Try to execute each of these in the current thread\n                foreach (ref task; tasks[1..$])\n                {\n                    tryDeleteExecute(task.basePtr);\n                }\n            }\n\n            // Now that we've tried to execute every task, they're all either\n            // done or in progress.  Force all of them.\n            E result = seed;\n\n            Throwable firstException;\n\n            foreach (ref task; tasks)\n            {\n                try\n                {\n                    task.yieldForce;\n                }\n                catch (Throwable e)\n                {\n                    /* Chain e to front because order doesn't matter and because\n                     * e is not likely to be a chain itself (so fewer traversals)\n                     */\n                    firstException = Throwable.chainTogether(e, firstException);\n                    continue;\n                }\n\n                if (!firstException) result = finishFun(result, task.returnVal);\n            }\n\n            if (firstException) throw firstException;\n\n            return result;\n        }\n    }\n\n    ///\n    template fold(functions...)\n    {\n        /** Implements the homonym function (also known as `accumulate`, `compress`,\n            `inject`, or `foldl`) present in various programming languages of\n            functional flavor.\n\n            `fold` is functionally equivalent to $(LREF reduce) except the range\n            parameter comes first and there is no need to use $(REF_ALTTEXT\n            `tuple`,tuple,std,typecons) for multiple seeds.\n\n            There may be one or more callable entities (`functions` argument) to\n            apply.\n\n            Params:\n                args = Just the range to _fold over; or the range and one seed\n                       per function; or the range, one seed per function, and\n                       the work unit size\n\n            Returns:\n                The accumulated result as a single value for single function and\n                as a tuple of values for multiple functions\n\n            See_Also:\n            Similar to $(REF _fold, std,algorithm,iteration), `fold` is a wrapper around $(LREF reduce).\n\n            Example:\n            ---\n            static int adder(int a, int b)\n            {\n                return a + b;\n            }\n            static int multiplier(int a, int b)\n            {\n                return a * b;\n            }\n\n            // Just the range\n            auto x = taskPool.fold!adder([1, 2, 3, 4]);\n            assert(x == 10);\n\n            // The range and the seeds (0 and 1 below; also note multiple\n            // functions in this example)\n            auto y = taskPool.fold!(adder, multiplier)([1, 2, 3, 4], 0, 1);\n            assert(y[0] == 10);\n            assert(y[1] == 24);\n\n            // The range, the seed (0), and the work unit size (20)\n            auto z = taskPool.fold!adder([1, 2, 3, 4], 0, 20);\n            assert(z == 10);\n            ---\n        */\n        auto fold(Args...)(Args args)\n        {\n            static assert(isInputRange!(Args[0]), \"First argument must be an InputRange\");\n\n            alias range = args[0];\n\n            static if (Args.length == 1)\n            {\n                // Just the range\n                return reduce!functions(range);\n            }\n            else static if (Args.length == 1 + functions.length ||\n                            Args.length == 1 + functions.length + 1)\n            {\n                static if (functions.length == 1)\n                {\n                    alias seeds = args[1];\n                }\n                else\n                {\n                    auto seeds()\n                    {\n                        import std.typecons : tuple;\n                        return tuple(args[1 .. functions.length+1]);\n                    }\n                }\n\n                static if (Args.length == 1 + functions.length)\n                {\n                    // The range and the seeds\n                    return reduce!functions(seeds, range);\n                }\n                else static if (Args.length == 1 + functions.length + 1)\n                {\n                    // The range, the seeds, and the work unit size\n                    static assert(isIntegral!(Args[$-1]), \"Work unit size must be an integral type\");\n                    return reduce!functions(seeds, range, args[$-1]);\n                }\n            }\n            else\n            {\n                import std.conv : text;\n                static assert(0, \"Invalid number of arguments (\" ~ Args.length.text ~ \"): Should be an input range, \"\n                              ~ functions.length.text ~ \" optional seed(s), and an optional work unit size.\");\n            }\n        }\n    }\n\n    // This test is not included in the documentation because even though these\n    // examples are for the inner fold() template, with their current location,\n    // they would appear under the outer one. (We can't move this inside the\n    // outer fold() template because then dmd runs out of memory possibly due to\n    // recursive template instantiation, which is surprisingly not caught.)\n    @system unittest\n    {\n        // Just the range\n        auto x = taskPool.fold!\"a + b\"([1, 2, 3, 4]);\n        assert(x == 10);\n\n        // The range and the seeds (0 and 1 below; also note multiple\n        // functions in this example)\n        auto y = taskPool.fold!(\"a + b\", \"a * b\")([1, 2, 3, 4], 0, 1);\n        assert(y[0] == 10);\n        assert(y[1] == 24);\n\n        // The range, the seed (0), and the work unit size (20)\n        auto z = taskPool.fold!\"a + b\"([1, 2, 3, 4], 0, 20);\n        assert(z == 10);\n    }\n\n    /**\n    Gets the index of the current thread relative to this `TaskPool`.  Any\n    thread not in this pool will receive an index of 0.  The worker threads in\n    this pool receive unique indices of 1 through `this.size`.\n\n    This function is useful for maintaining worker-local resources.\n\n    Example:\n    ---\n    // Execute a loop that computes the greatest common\n    // divisor of every number from 0 through 999 with\n    // 42 in parallel.  Write the results out to\n    // a set of files, one for each thread.  This allows\n    // results to be written out without any synchronization.\n\n    import std.conv, std.range, std.numeric, std.stdio;\n\n    void main()\n    {\n        auto filesHandles = new File[taskPool.size + 1];\n        scope(exit) {\n            foreach (ref handle; fileHandles)\n            {\n                handle.close();\n            }\n        }\n\n        foreach (i, ref handle; fileHandles)\n        {\n            handle = File(\"workerResults\" ~ to!string(i) ~ \".txt\");\n        }\n\n        foreach (num; parallel(iota(1_000)))\n        {\n            auto outHandle = fileHandles[taskPool.workerIndex];\n            outHandle.writeln(num, '\\t', gcd(num, 42));\n        }\n    }\n    ---\n    */\n    size_t workerIndex() @property @safe const nothrow\n    {\n        immutable rawInd = threadIndex;\n        return (rawInd >= instanceStartIndex && rawInd < instanceStartIndex + size) ?\n                (rawInd - instanceStartIndex + 1) : 0;\n    }\n\n    /**\n    Struct for creating worker-local storage.  Worker-local storage is\n    thread-local storage that exists only for worker threads in a given\n    `TaskPool` plus a single thread outside the pool.  It is allocated on the\n    garbage collected heap in a way that avoids _false sharing, and doesn't\n    necessarily have global scope within any thread.  It can be accessed from\n    any worker thread in the `TaskPool` that created it, and one thread\n    outside this `TaskPool`.  All threads outside the pool that created a\n    given instance of worker-local storage share a single slot.\n\n    Since the underlying data for this struct is heap-allocated, this struct\n    has reference semantics when passed between functions.\n\n    The main uses cases for `WorkerLocalStorageStorage` are:\n\n    1.  Performing parallel reductions with an imperative, as opposed to\n    functional, programming style.  In this case, it's useful to treat\n    `WorkerLocalStorageStorage` as local to each thread for only the parallel\n    portion of an algorithm.\n\n    2.  Recycling temporary buffers across iterations of a parallel foreach loop.\n\n    Example:\n    ---\n    // Calculate pi as in our synopsis example, but\n    // use an imperative instead of a functional style.\n    immutable n = 1_000_000_000;\n    immutable delta = 1.0L / n;\n\n    auto sums = taskPool.workerLocalStorage(0.0L);\n    foreach (i; parallel(iota(n)))\n    {\n        immutable x = ( i - 0.5L ) * delta;\n        immutable toAdd = delta / ( 1.0 + x * x );\n        sums.get += toAdd;\n    }\n\n    // Add up the results from each worker thread.\n    real pi = 0;\n    foreach (threadResult; sums.toRange)\n    {\n        pi += 4.0L * threadResult;\n    }\n    ---\n     */\n    static struct WorkerLocalStorage(T)\n    {\n    private:\n        TaskPool pool;\n        size_t size;\n\n        size_t elemSize;\n        bool* stillThreadLocal;\n\n        static size_t roundToLine(size_t num) pure nothrow\n        {\n            if (num % cacheLineSize == 0)\n            {\n                return num;\n            }\n            else\n            {\n                return ((num / cacheLineSize) + 1) * cacheLineSize;\n            }\n        }\n\n        void* data;\n\n        void initialize(TaskPool pool)\n        {\n            this.pool = pool;\n            size = pool.size + 1;\n            stillThreadLocal = new bool;\n            *stillThreadLocal = true;\n\n            // Determines whether the GC should scan the array.\n            auto blkInfo = (typeid(T).flags & 1) ?\n                           cast(GC.BlkAttr) 0 :\n                           GC.BlkAttr.NO_SCAN;\n\n            immutable nElem = pool.size + 1;\n            elemSize = roundToLine(T.sizeof);\n\n            // The + 3 is to pad one full cache line worth of space on either side\n            // of the data structure to make sure false sharing with completely\n            // unrelated heap data is prevented, and to provide enough padding to\n            // make sure that data is cache line-aligned.\n            data = GC.malloc(elemSize * (nElem + 3), blkInfo) + elemSize;\n\n            // Cache line align data ptr.\n            data = cast(void*) roundToLine(cast(size_t) data);\n\n            foreach (i; 0 .. nElem)\n            {\n                this.opIndex(i) = T.init;\n            }\n        }\n\n        ref opIndex(this Qualified)(size_t index)\n        {\n            import std.conv : text;\n            assert(index < size, text(index, '\\t', uint.max));\n            return *(cast(CopyTypeQualifiers!(Qualified, T)*) (data + elemSize * index));\n        }\n\n        void opIndexAssign(T val, size_t index)\n        {\n            assert(index < size);\n            *(cast(T*) (data + elemSize * index)) = val;\n        }\n\n    public:\n        /**\n        Get the current thread's instance.  Returns by ref.\n        Note that calling `get` from any thread\n        outside the `TaskPool` that created this instance will return the\n        same reference, so an instance of worker-local storage should only be\n        accessed from one thread outside the pool that created it.  If this\n        rule is violated, undefined behavior will result.\n\n        If assertions are enabled and `toRange` has been called, then this\n        WorkerLocalStorage instance is no longer worker-local and an assertion\n        failure will result when calling this method.  This is not checked\n        when assertions are disabled for performance reasons.\n         */\n        ref get(this Qualified)() @property\n        {\n            assert(*stillThreadLocal,\n                \"Cannot call get() on this instance of WorkerLocalStorage \" ~\n                \"because it is no longer worker-local.\"\n            );\n            return opIndex(pool.workerIndex);\n        }\n\n        /**\n        Assign a value to the current thread's instance.  This function has\n        the same caveats as its overload.\n        */\n        void get(T val) @property\n        {\n            assert(*stillThreadLocal,\n                \"Cannot call get() on this instance of WorkerLocalStorage \" ~\n                \"because it is no longer worker-local.\"\n            );\n\n            opIndexAssign(val, pool.workerIndex);\n        }\n\n        /**\n        Returns a range view of the values for all threads, which can be used\n        to further process the results of each thread after running the parallel\n        part of your algorithm.  Do not use this method in the parallel portion\n        of your algorithm.\n\n        Calling this function sets a flag indicating that this struct is no\n        longer worker-local, and attempting to use the `get` method again\n        will result in an assertion failure if assertions are enabled.\n         */\n        WorkerLocalStorageRange!T toRange() @property\n        {\n            if (*stillThreadLocal)\n            {\n                *stillThreadLocal = false;\n\n                // Make absolutely sure results are visible to all threads.\n                // This is probably not necessary since some other\n                // synchronization primitive will be used to signal that the\n                // parallel part of the algorithm is done, but the\n                // performance impact should be negligible, so it's better\n                // to be safe.\n                ubyte barrierDummy;\n                atomicSetUbyte(barrierDummy, 1);\n            }\n\n            return WorkerLocalStorageRange!T(this);\n        }\n    }\n\n    /**\n    Range primitives for worker-local storage.  The purpose of this is to\n    access results produced by each worker thread from a single thread once you\n    are no longer using the worker-local storage from multiple threads.\n    Do not use this struct in the parallel portion of your algorithm.\n\n    The proper way to instantiate this object is to call\n    `WorkerLocalStorage.toRange`.  Once instantiated, this object behaves\n    as a finite random-access range with assignable, lvalue elements and\n    a length equal to the number of worker threads in the `TaskPool` that\n    created it plus 1.\n     */\n    static struct WorkerLocalStorageRange(T)\n    {\n    private:\n        WorkerLocalStorage!T workerLocalStorage;\n\n        size_t _length;\n        size_t beginOffset;\n\n        this(WorkerLocalStorage!T wl)\n        {\n            this.workerLocalStorage = wl;\n            _length = wl.size;\n        }\n\n    public:\n        ref front(this Qualified)() @property\n        {\n            return this[0];\n        }\n\n        ref back(this Qualified)() @property\n        {\n            return this[_length - 1];\n        }\n\n        void popFront()\n        {\n            if (_length > 0)\n            {\n                beginOffset++;\n                _length--;\n            }\n        }\n\n        void popBack()\n        {\n            if (_length > 0)\n            {\n                _length--;\n            }\n        }\n\n        typeof(this) save() @property\n        {\n            return this;\n        }\n\n        ref opIndex(this Qualified)(size_t index)\n        {\n            assert(index < _length);\n            return workerLocalStorage[index + beginOffset];\n        }\n\n        void opIndexAssign(T val, size_t index)\n        {\n            assert(index < _length);\n            workerLocalStorage[index] = val;\n        }\n\n        typeof(this) opSlice(size_t lower, size_t upper)\n        {\n            assert(upper <= _length);\n            auto newWl = this.workerLocalStorage;\n            newWl.data += lower * newWl.elemSize;\n            newWl.size = upper - lower;\n            return typeof(this)(newWl);\n        }\n\n        bool empty() const @property\n        {\n            return length == 0;\n        }\n\n        size_t length() const @property\n        {\n            return _length;\n        }\n    }\n\n    /**\n    Creates an instance of worker-local storage, initialized with a given\n    value.  The value is `lazy` so that you can, for example, easily\n    create one instance of a class for each worker.  For usage example,\n    see the `WorkerLocalStorage` struct.\n     */\n    WorkerLocalStorage!T workerLocalStorage(T)(lazy T initialVal = T.init)\n    {\n        WorkerLocalStorage!T ret;\n        ret.initialize(this);\n        foreach (i; 0 .. size + 1)\n        {\n            ret[i] = initialVal;\n        }\n\n        // Memory barrier to make absolutely sure that what we wrote is\n        // visible to worker threads.\n        ubyte barrierDummy;\n        atomicSetUbyte(barrierDummy, 0);\n\n        return ret;\n    }\n\n    /**\n    Signals to all worker threads to terminate as soon as they are finished\n    with their current `Task`, or immediately if they are not executing a\n    `Task`.  `Task`s that were in queue will not be executed unless\n    a call to `Task.workForce`, `Task.yieldForce` or `Task.spinForce`\n    causes them to be executed.\n\n    Use only if you have waited on every `Task` and therefore know the\n    queue is empty, or if you speculatively executed some tasks and no longer\n    need the results.\n     */\n    void stop() @trusted\n    {\n        queueLock();\n        scope(exit) queueUnlock();\n        atomicSetUbyte(status, PoolState.stopNow);\n        notifyAll();\n    }\n\n    /**\n    Signals worker threads to terminate when the queue becomes empty.\n\n    If blocking argument is true, wait for all worker threads to terminate\n    before returning.  This option might be used in applications where\n    task results are never consumed-- e.g. when `TaskPool` is employed as a\n    rudimentary scheduler for tasks which communicate by means other than\n    return values.\n\n    Warning:  Calling this function with $(D blocking = true) from a worker\n              thread that is a member of the same `TaskPool` that\n              `finish` is being called on will result in a deadlock.\n     */\n    void finish(bool blocking = false) @trusted\n    {\n        {\n            queueLock();\n            scope(exit) queueUnlock();\n            atomicCasUbyte(status, PoolState.running, PoolState.finishing);\n            notifyAll();\n        }\n        if (blocking)\n        {\n            // Use this thread as a worker until everything is finished.\n            executeWorkLoop();\n\n            foreach (t; pool)\n            {\n                // Maybe there should be something here to prevent a thread\n                // from calling join() on itself if this function is called\n                // from a worker thread in the same pool, but:\n                //\n                // 1.  Using an if statement to skip join() would result in\n                //     finish() returning without all tasks being finished.\n                //\n                // 2.  If an exception were thrown, it would bubble up to the\n                //     Task from which finish() was called and likely be\n                //     swallowed.\n                t.join();\n            }\n        }\n    }\n\n    /// Returns the number of worker threads in the pool.\n    @property size_t size() @safe const pure nothrow\n    {\n        return pool.length;\n    }\n\n    /**\n    Put a `Task` object on the back of the task queue.  The `Task`\n    object may be passed by pointer or reference.\n\n    Example:\n    ---\n    import std.file;\n\n    // Create a task.\n    auto t = task!read(\"foo.txt\");\n\n    // Add it to the queue to be executed.\n    taskPool.put(t);\n    ---\n\n    Notes:\n\n    @trusted overloads of this function are called for `Task`s if\n    $(REF hasUnsharedAliasing, std,traits) is false for the `Task`'s\n    return type or the function the `Task` executes is `pure`.\n    `Task` objects that meet all other requirements specified in the\n    `@trusted` overloads of `task` and `scopedTask` may be created\n    and executed from `@safe` code via `Task.executeInNewThread` but\n    not via `TaskPool`.\n\n    While this function takes the address of variables that may\n    be on the stack, some overloads are marked as @trusted.\n    `Task` includes a destructor that waits for the task to complete\n    before destroying the stack frame it is allocated on.  Therefore,\n    it is impossible for the stack frame to be destroyed before the task is\n    complete and no longer referenced by a `TaskPool`.\n    */\n    void put(alias fun, Args...)(ref Task!(fun, Args) task)\n    if (!isSafeReturn!(typeof(task)))\n    {\n        task.pool = this;\n        abstractPut(task.basePtr);\n    }\n\n    /// Ditto\n    void put(alias fun, Args...)(Task!(fun, Args)* task)\n    if (!isSafeReturn!(typeof(*task)))\n    {\n        import std.exception : enforce;\n        enforce(task !is null, \"Cannot put a null Task on a TaskPool queue.\");\n        put(*task);\n    }\n\n    @trusted void put(alias fun, Args...)(ref Task!(fun, Args) task)\n    if (isSafeReturn!(typeof(task)))\n    {\n        task.pool = this;\n        abstractPut(task.basePtr);\n    }\n\n    @trusted void put(alias fun, Args...)(Task!(fun, Args)* task)\n    if (isSafeReturn!(typeof(*task)))\n    {\n        import std.exception : enforce;\n        enforce(task !is null, \"Cannot put a null Task on a TaskPool queue.\");\n        put(*task);\n    }\n\n    /**\n    These properties control whether the worker threads are daemon threads.\n    A daemon thread is automatically terminated when all non-daemon threads\n    have terminated.  A non-daemon thread will prevent a program from\n    terminating as long as it has not terminated.\n\n    If any `TaskPool` with non-daemon threads is active, either `stop`\n    or `finish` must be called on it before the program can terminate.\n\n    The worker treads in the `TaskPool` instance returned by the\n    `taskPool` property are daemon by default.  The worker threads of\n    manually instantiated task pools are non-daemon by default.\n\n    Note:  For a size zero pool, the getter arbitrarily returns true and the\n           setter has no effect.\n    */\n    bool isDaemon() @property @trusted\n    {\n        queueLock();\n        scope(exit) queueUnlock();\n        return (size == 0) ? true : pool[0].isDaemon;\n    }\n\n    /// Ditto\n    void isDaemon(bool newVal) @property @trusted\n    {\n        queueLock();\n        scope(exit) queueUnlock();\n        foreach (thread; pool)\n        {\n            thread.isDaemon = newVal;\n        }\n    }\n\n    /**\n    These functions allow getting and setting the OS scheduling priority of\n    the worker threads in this `TaskPool`.  They forward to\n    `core.thread.Thread.priority`, so a given priority value here means the\n    same thing as an identical priority value in `core.thread`.\n\n    Note:  For a size zero pool, the getter arbitrarily returns\n           `core.thread.Thread.PRIORITY_MIN` and the setter has no effect.\n    */\n    int priority() @property @trusted\n    {\n        return (size == 0) ? core.thread.Thread.PRIORITY_MIN :\n        pool[0].priority;\n    }\n\n    /// Ditto\n    void priority(int newPriority) @property @trusted\n    {\n        if (size > 0)\n        {\n            foreach (t; pool)\n            {\n                t.priority = newPriority;\n            }\n        }\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.iteration : sum;\n    import std.range : iota;\n    import std.typecons : tuple;\n\n    enum N = 100;\n    auto r = iota(1, N + 1);\n    const expected = r.sum();\n\n    // Just the range\n    assert(taskPool.fold!\"a + b\"(r) == expected);\n\n    // Range and seeds\n    assert(taskPool.fold!\"a + b\"(r, 0) == expected);\n    assert(taskPool.fold!(\"a + b\", \"a + b\")(r, 0, 0) == tuple(expected, expected));\n\n    // Range, seeds, and work unit size\n    assert(taskPool.fold!\"a + b\"(r, 0, 42) == expected);\n    assert(taskPool.fold!(\"a + b\", \"a + b\")(r, 0, 0, 42) == tuple(expected, expected));\n}\n\n/**\nReturns a lazily initialized global instantiation of `TaskPool`.\nThis function can safely be called concurrently from multiple non-worker\nthreads.  The worker threads in this pool are daemon threads, meaning that it\nis not necessary to call `TaskPool.stop` or `TaskPool.finish` before\nterminating the main thread.\n*/\n@property TaskPool taskPool() @trusted\n{\n    import std.concurrency : initOnce;\n    __gshared TaskPool pool;\n    return initOnce!pool({\n        auto p = new TaskPool(defaultPoolThreads);\n        p.isDaemon = true;\n        return p;\n    }());\n}\n\nprivate shared uint _defaultPoolThreads = uint.max;\n\n/**\nThese properties get and set the number of worker threads in the `TaskPool`\ninstance returned by `taskPool`.  The default value is `totalCPUs` - 1.\nCalling the setter after the first call to `taskPool` does not changes\nnumber of worker threads in the instance returned by `taskPool`.\n*/\n@property uint defaultPoolThreads() @trusted\n{\n    const local = atomicLoad(_defaultPoolThreads);\n    return local < uint.max ? local : totalCPUs - 1;\n}\n\n/// Ditto\n@property void defaultPoolThreads(uint newVal) @trusted\n{\n    atomicStore(_defaultPoolThreads, newVal);\n}\n\n/**\nConvenience functions that forwards to `taskPool.parallel`.  The\npurpose of these is to make parallel foreach less verbose and more\nreadable.\n\nExample:\n---\n// Find the logarithm of every number from\n// 1 to 1_000_000 in parallel, using the\n// default TaskPool instance.\nauto logs = new double[1_000_000];\n\nforeach (i, ref elem; parallel(logs))\n{\n    elem = log(i + 1.0);\n}\n---\n\n*/\nParallelForeach!R parallel(R)(R range)\n{\n    return taskPool.parallel(range);\n}\n\n/// Ditto\nParallelForeach!R parallel(R)(R range, size_t workUnitSize)\n{\n    return taskPool.parallel(range, workUnitSize);\n}\n\n// #17019: `each` should be usable with parallel\n@system unittest\n{\n    import std.algorithm.iteration : each, sum;\n    import std.range : iota;\n\n    // check behavior with parallel\n    auto arr = new int[10];\n    parallel(arr).each!((ref e) => e += 1);\n    assert(arr.sum == 10);\n\n    auto arrIndex = new int[10];\n    parallel(arrIndex).each!((i, ref e) => e += i);\n    assert(arrIndex.sum == 10.iota.sum);\n}\n\n// Thrown when a parallel foreach loop is broken from.\nclass ParallelForeachError : Error\n{\n    this()\n    {\n        super(\"Cannot break from a parallel foreach loop using break, return, \"\n              ~ \"labeled break/continue or goto statements.\");\n    }\n}\n\n/*------Structs that implement opApply for parallel foreach.------------------*/\nprivate template randLen(R)\n{\n    enum randLen = isRandomAccessRange!R && hasLength!R;\n}\n\nprivate void submitAndExecute(\n    TaskPool pool,\n    scope void delegate() doIt\n)\n{\n    import core.exception : OutOfMemoryError;\n    immutable nThreads = pool.size + 1;\n\n    alias PTask = typeof(scopedTask(doIt));\n    import core.stdc.stdlib : malloc, free;\n    import core.stdc.string : memcpy;\n\n    // The logical thing to do would be to just use alloca() here, but that\n    // causes problems on Windows for reasons that I don't understand\n    // (tentatively a compiler bug) and definitely doesn't work on Posix due\n    // to Bug 3753.  Therefore, allocate a fixed buffer and fall back to\n    // malloc() if someone's using a ridiculous amount of threads.  Also,\n    // the using a byte array instead of a PTask array as the fixed buffer\n    // is to prevent d'tors from being called on uninitialized excess PTask\n    // instances.\n    enum nBuf = 64;\n    byte[nBuf * PTask.sizeof] buf = void;\n    PTask[] tasks;\n    if (nThreads <= nBuf)\n    {\n        tasks = (cast(PTask*) buf.ptr)[0 .. nThreads];\n    }\n    else\n    {\n        auto ptr = cast(PTask*) malloc(nThreads * PTask.sizeof);\n        if (!ptr) throw new OutOfMemoryError(\"Out of memory in std.parallelism.\");\n        tasks = ptr[0 .. nThreads];\n    }\n\n    scope(exit)\n    {\n        if (nThreads > nBuf)\n        {\n            free(tasks.ptr);\n        }\n    }\n\n    foreach (ref t; tasks)\n    {\n        import core.stdc.string : memcpy;\n\n        // This silly looking code is necessary to prevent d'tors from being\n        // called on uninitialized objects.\n        auto temp = scopedTask(doIt);\n        memcpy(&t, &temp, PTask.sizeof);\n\n        // This has to be done to t after copying, not temp before copying.\n        // Otherwise, temp's destructor will sit here and wait for the\n        // task to finish.\n        t.pool = pool;\n    }\n\n    foreach (i; 1 .. tasks.length - 1)\n    {\n        tasks[i].next = tasks[i + 1].basePtr;\n        tasks[i + 1].prev = tasks[i].basePtr;\n    }\n\n    if (tasks.length > 1)\n    {\n        pool.queueLock();\n        scope(exit) pool.queueUnlock();\n\n        pool.abstractPutGroupNoSync(\n            tasks[1].basePtr,\n            tasks[$ - 1].basePtr\n        );\n    }\n\n    if (tasks.length > 0)\n    {\n        try\n        {\n            tasks[0].job();\n        }\n        catch (Throwable e)\n        {\n            tasks[0].exception = e; // nocoverage\n        }\n        tasks[0].taskStatus = TaskStatus.done;\n\n        // Try to execute each of these in the current thread\n        foreach (ref task; tasks[1..$])\n        {\n            pool.tryDeleteExecute(task.basePtr);\n        }\n    }\n\n    Throwable firstException;\n\n    foreach (i, ref task; tasks)\n    {\n        try\n        {\n            task.yieldForce;\n        }\n        catch (Throwable e)\n        {\n            /* Chain e to front because order doesn't matter and because\n             * e is not likely to be a chain itself (so fewer traversals)\n             */\n            firstException = Throwable.chainTogether(e, firstException);\n            continue;\n        }\n    }\n\n    if (firstException) throw firstException;\n}\n\nvoid foreachErr()\n{\n    throw new ParallelForeachError();\n}\n\nint doSizeZeroCase(R, Delegate)(ref ParallelForeach!R p, Delegate dg)\n{\n    with(p)\n    {\n        int res = 0;\n        size_t index = 0;\n\n        // The explicit ElementType!R in the foreach loops is necessary for\n        // correct behavior when iterating over strings.\n        static if (hasLvalueElements!R)\n        {\n            foreach (ref ElementType!R elem; range)\n            {\n                static if (Parameters!dg.length == 2)\n                {\n                    res = dg(index, elem);\n                }\n                else\n                {\n                    res = dg(elem);\n                }\n                if (res) break;\n                index++;\n            }\n        }\n        else\n        {\n            foreach (ElementType!R elem; range)\n            {\n                static if (Parameters!dg.length == 2)\n                {\n                    res = dg(index, elem);\n                }\n                else\n                {\n                    res = dg(elem);\n                }\n                if (res) break;\n                index++;\n            }\n        }\n        if (res) foreachErr;\n        return res;\n    }\n}\n\nprivate enum string parallelApplyMixinRandomAccess = q{\n    // Handle empty thread pool as special case.\n    if (pool.size == 0)\n    {\n        return doSizeZeroCase(this, dg);\n    }\n\n    // Whether iteration is with or without an index variable.\n    enum withIndex = Parameters!(typeof(dg)).length == 2;\n\n    shared size_t workUnitIndex = size_t.max;  // Effectively -1:  chunkIndex + 1 == 0\n    immutable len = range.length;\n    if (!len) return 0;\n\n    shared bool shouldContinue = true;\n\n    void doIt()\n    {\n        import std.algorithm.comparison : min;\n\n        scope(failure)\n        {\n            // If an exception is thrown, all threads should bail.\n            atomicStore(shouldContinue, false);\n        }\n\n        while (atomicLoad(shouldContinue))\n        {\n            immutable myUnitIndex = atomicOp!\"+=\"(workUnitIndex, 1);\n            immutable start = workUnitSize * myUnitIndex;\n            if (start >= len)\n            {\n                atomicStore(shouldContinue, false);\n                break;\n            }\n\n            immutable end = min(len, start + workUnitSize);\n\n            foreach (i; start .. end)\n            {\n                static if (withIndex)\n                {\n                    if (dg(i, range[i])) foreachErr();\n                }\n                else\n                {\n                    if (dg(range[i])) foreachErr();\n                }\n            }\n        }\n    }\n\n    submitAndExecute(pool, &doIt);\n\n    return 0;\n};\n\nenum string parallelApplyMixinInputRange = q{\n    // Handle empty thread pool as special case.\n    if (pool.size == 0)\n    {\n        return doSizeZeroCase(this, dg);\n    }\n\n    // Whether iteration is with or without an index variable.\n    enum withIndex = Parameters!(typeof(dg)).length == 2;\n\n    // This protects the range while copying it.\n    auto rangeMutex = new Mutex();\n\n    shared bool shouldContinue = true;\n\n    // The total number of elements that have been popped off range.\n    // This is updated only while protected by rangeMutex;\n    size_t nPopped = 0;\n\n    static if (\n        is(typeof(range.buf1)) &&\n        is(typeof(range.bufPos)) &&\n        is(typeof(range.doBufSwap()))\n    )\n    {\n        // Make sure we don't have the buffer recycling overload of\n        // asyncBuf.\n        static if (\n            is(typeof(range.source)) &&\n            isRoundRobin!(typeof(range.source))\n        )\n        {\n            static assert(0, \"Cannot execute a parallel foreach loop on \" ~\n            \"the buffer recycling overload of asyncBuf.\");\n        }\n\n        enum bool bufferTrick = true;\n    }\n    else\n    {\n        enum bool bufferTrick = false;\n    }\n\n    void doIt()\n    {\n        scope(failure)\n        {\n            // If an exception is thrown, all threads should bail.\n            atomicStore(shouldContinue, false);\n        }\n\n        static if (hasLvalueElements!R)\n        {\n            alias Temp = ElementType!R*[];\n            Temp temp;\n\n            // Returns:  The previous value of nPopped.\n            size_t makeTemp()\n            {\n                import std.algorithm.internal : addressOf;\n                import std.array : uninitializedArray;\n\n                if (temp is null)\n                {\n                    temp = uninitializedArray!Temp(workUnitSize);\n                }\n\n                rangeMutex.lock();\n                scope(exit) rangeMutex.unlock();\n\n                size_t i = 0;\n                for (; i < workUnitSize && !range.empty; range.popFront(), i++)\n                {\n                    temp[i] = addressOf(range.front);\n                }\n\n                temp = temp[0 .. i];\n                auto ret = nPopped;\n                nPopped += temp.length;\n                return ret;\n            }\n\n        }\n        else\n        {\n\n            alias Temp = ElementType!R[];\n            Temp temp;\n\n            // Returns:  The previous value of nPopped.\n            static if (!bufferTrick) size_t makeTemp()\n            {\n                import std.array : uninitializedArray;\n\n                if (temp is null)\n                {\n                    temp = uninitializedArray!Temp(workUnitSize);\n                }\n\n                rangeMutex.lock();\n                scope(exit) rangeMutex.unlock();\n\n                size_t i = 0;\n                for (; i < workUnitSize && !range.empty; range.popFront(), i++)\n                {\n                    temp[i] = range.front;\n                }\n\n                temp = temp[0 .. i];\n                auto ret = nPopped;\n                nPopped += temp.length;\n                return ret;\n            }\n\n            static if (bufferTrick) size_t makeTemp()\n            {\n                import std.algorithm.mutation : swap;\n                rangeMutex.lock();\n                scope(exit) rangeMutex.unlock();\n\n                // Elide copying by just swapping buffers.\n                temp.length = range.buf1.length;\n                swap(range.buf1, temp);\n\n                // This is necessary in case popFront() has been called on\n                // range before entering the parallel foreach loop.\n                temp = temp[range.bufPos..$];\n\n                static if (is(typeof(range._length)))\n                {\n                    range._length -= (temp.length - range.bufPos);\n                }\n\n                range.doBufSwap();\n                auto ret = nPopped;\n                nPopped += temp.length;\n                return ret;\n            }\n        }\n\n        while (atomicLoad(shouldContinue))\n        {\n            auto overallIndex = makeTemp();\n            if (temp.empty)\n            {\n                atomicStore(shouldContinue, false);\n                break;\n            }\n\n            foreach (i; 0 .. temp.length)\n            {\n                scope(success) overallIndex++;\n\n                static if (hasLvalueElements!R)\n                {\n                    static if (withIndex)\n                    {\n                        if (dg(overallIndex, *temp[i])) foreachErr();\n                    }\n                    else\n                    {\n                        if (dg(*temp[i])) foreachErr();\n                    }\n                }\n                else\n                {\n                    static if (withIndex)\n                    {\n                        if (dg(overallIndex, temp[i])) foreachErr();\n                    }\n                    else\n                    {\n                        if (dg(temp[i])) foreachErr();\n                    }\n                }\n            }\n        }\n    }\n\n    submitAndExecute(pool, &doIt);\n\n    return 0;\n};\n\n\nprivate struct ParallelForeach(R)\n{\n    TaskPool pool;\n    R range;\n    size_t workUnitSize;\n    alias E = ElementType!R;\n\n    static if (hasLvalueElements!R)\n    {\n        alias NoIndexDg = int delegate(ref E);\n        alias IndexDg = int delegate(size_t, ref E);\n    }\n    else\n    {\n        alias NoIndexDg = int delegate(E);\n        alias IndexDg = int delegate(size_t, E);\n    }\n\n    int opApply(scope NoIndexDg dg)\n    {\n        static if (randLen!R)\n        {\n            mixin(parallelApplyMixinRandomAccess);\n        }\n        else\n        {\n            mixin(parallelApplyMixinInputRange);\n        }\n    }\n\n    int opApply(scope IndexDg dg)\n    {\n        static if (randLen!R)\n        {\n            mixin(parallelApplyMixinRandomAccess);\n        }\n        else\n        {\n            mixin(parallelApplyMixinInputRange);\n        }\n    }\n}\n\n/*\nThis struct buffers the output of a callable that outputs data into a\nuser-supplied buffer into a set of buffers of some fixed size.  It allows these\nbuffers to be accessed with an input range interface.  This is used internally\nin the buffer-recycling overload of TaskPool.asyncBuf, which creates an\ninstance and forwards it to the input range overload of asyncBuf.\n*/\nprivate struct RoundRobinBuffer(C1, C2)\n{\n    // No need for constraints because they're already checked for in asyncBuf.\n\n    alias Array = Parameters!(C1.init)[0];\n    alias T = typeof(Array.init[0]);\n\n    T[][] bufs;\n    size_t index;\n    C1 nextDel;\n    C2 emptyDel;\n    bool _empty;\n    bool primed;\n\n    this(\n        C1 nextDel,\n        C2 emptyDel,\n        size_t initialBufSize,\n        size_t nBuffers\n    ) {\n        this.nextDel = nextDel;\n        this.emptyDel = emptyDel;\n        bufs.length = nBuffers;\n\n        foreach (ref buf; bufs)\n        {\n            buf.length = initialBufSize;\n        }\n    }\n\n    void prime()\n    in\n    {\n        assert(!empty);\n    }\n    do\n    {\n        scope(success) primed = true;\n        nextDel(bufs[index]);\n    }\n\n\n    T[] front() @property\n    in\n    {\n        assert(!empty);\n    }\n    do\n    {\n        if (!primed) prime();\n        return bufs[index];\n    }\n\n    void popFront()\n    {\n        if (empty || emptyDel())\n        {\n            _empty = true;\n            return;\n        }\n\n        index = (index + 1) % bufs.length;\n        primed = false;\n    }\n\n    bool empty() @property const @safe pure nothrow\n    {\n        return _empty;\n    }\n}\n\nversion (unittest)\n{\n    // This was the only way I could get nested maps to work.\n    private __gshared TaskPool poolInstance;\n}\n\n// These test basic functionality but don't stress test for threading bugs.\n// These are the tests that should be run every time Phobos is compiled.\n@system unittest\n{\n    import std.algorithm.comparison : equal, min, max;\n    import std.algorithm.iteration : filter, map, reduce;\n    import std.array : split;\n    import std.conv : text;\n    import std.exception : assertThrown;\n    import std.math : approxEqual, sqrt, log;\n    import std.range : indexed, iota, join;\n    import std.typecons : Tuple, tuple;\n    import std.stdio;\n\n    poolInstance = new TaskPool(2);\n    scope(exit) poolInstance.stop();\n\n    // The only way this can be verified is manually.\n    debug(std_parallelism) stderr.writeln(\"totalCPUs = \", totalCPUs);\n\n    auto oldPriority = poolInstance.priority;\n    poolInstance.priority = Thread.PRIORITY_MAX;\n    assert(poolInstance.priority == Thread.PRIORITY_MAX);\n\n    poolInstance.priority = Thread.PRIORITY_MIN;\n    assert(poolInstance.priority == Thread.PRIORITY_MIN);\n\n    poolInstance.priority = oldPriority;\n    assert(poolInstance.priority == oldPriority);\n\n    static void refFun(ref uint num)\n    {\n        num++;\n    }\n\n    uint x;\n\n    // Test task().\n    auto t = task!refFun(x);\n    poolInstance.put(t);\n    t.yieldForce;\n    assert(t.args[0] == 1);\n\n    auto t2 = task(&refFun, x);\n    poolInstance.put(t2);\n    t2.yieldForce;\n    assert(t2.args[0] == 1);\n\n    // Test scopedTask().\n    auto st = scopedTask!refFun(x);\n    poolInstance.put(st);\n    st.yieldForce;\n    assert(st.args[0] == 1);\n\n    auto st2 = scopedTask(&refFun, x);\n    poolInstance.put(st2);\n    st2.yieldForce;\n    assert(st2.args[0] == 1);\n\n    // Test executeInNewThread().\n    auto ct = scopedTask!refFun(x);\n    ct.executeInNewThread(Thread.PRIORITY_MAX);\n    ct.yieldForce;\n    assert(ct.args[0] == 1);\n\n    // Test ref return.\n    uint toInc = 0;\n    static ref T makeRef(T)(ref T num)\n    {\n        return num;\n    }\n\n    auto t3 = task!makeRef(toInc);\n    taskPool.put(t3);\n    assert(t3.args[0] == 0);\n    t3.spinForce++;\n    assert(t3.args[0] == 1);\n\n    static void testSafe() @safe {\n        static int bump(int num)\n        {\n            return num + 1;\n        }\n\n        auto safePool = new TaskPool(0);\n        auto t = task(&bump, 1);\n        taskPool.put(t);\n        assert(t.yieldForce == 2);\n\n        auto st = scopedTask(&bump, 1);\n        taskPool.put(st);\n        assert(st.yieldForce == 2);\n        safePool.stop();\n    }\n\n    auto arr = [1,2,3,4,5];\n    auto nums = new uint[5];\n    auto nums2 = new uint[5];\n\n    foreach (i, ref elem; poolInstance.parallel(arr))\n    {\n        elem++;\n        nums[i] = cast(uint) i + 2;\n        nums2[i] = elem;\n    }\n\n    assert(nums == [2,3,4,5,6], text(nums));\n    assert(nums2 == nums, text(nums2));\n    assert(arr == nums, text(arr));\n\n    // Test const/immutable arguments.\n    static int add(int lhs, int rhs)\n    {\n        return lhs + rhs;\n    }\n    immutable addLhs = 1;\n    immutable addRhs = 2;\n    auto addTask = task(&add, addLhs, addRhs);\n    auto addScopedTask = scopedTask(&add, addLhs, addRhs);\n    poolInstance.put(addTask);\n    poolInstance.put(addScopedTask);\n    assert(addTask.yieldForce == 3);\n    assert(addScopedTask.yieldForce == 3);\n\n    // Test parallel foreach with non-random access range.\n    auto range = filter!\"a != 666\"([0, 1, 2, 3, 4]);\n\n    foreach (i, elem; poolInstance.parallel(range))\n    {\n        nums[i] = cast(uint) i;\n    }\n\n    assert(nums == [0,1,2,3,4]);\n\n    auto logs = new double[1_000_000];\n    foreach (i, ref elem; poolInstance.parallel(logs))\n    {\n        elem = log(i + 1.0);\n    }\n\n    foreach (i, elem; logs)\n    {\n        assert(approxEqual(elem, cast(double) log(i + 1)));\n    }\n\n    assert(poolInstance.amap!\"a * a\"([1,2,3,4,5]) == [1,4,9,16,25]);\n    assert(poolInstance.amap!\"a * a\"([1,2,3,4,5], new long[5]) == [1,4,9,16,25]);\n    assert(poolInstance.amap!(\"a * a\", \"-a\")([1,2,3]) ==\n           [tuple(1, -1), tuple(4, -2), tuple(9, -3)]);\n\n    auto tupleBuf = new Tuple!(int, int)[3];\n    poolInstance.amap!(\"a * a\", \"-a\")([1,2,3], tupleBuf);\n    assert(tupleBuf == [tuple(1, -1), tuple(4, -2), tuple(9, -3)]);\n    poolInstance.amap!(\"a * a\", \"-a\")([1,2,3], 5, tupleBuf);\n    assert(tupleBuf == [tuple(1, -1), tuple(4, -2), tuple(9, -3)]);\n\n    // Test amap with a non-array buffer.\n    auto toIndex = new int[5];\n    auto ind = indexed(toIndex, [3, 1, 4, 0, 2]);\n    poolInstance.amap!\"a * 2\"([1, 2, 3, 4, 5], ind);\n    assert(equal(ind, [2, 4, 6, 8, 10]));\n    assert(equal(toIndex, [8, 4, 10, 2, 6]));\n    poolInstance.amap!\"a / 2\"(ind, ind);\n    assert(equal(ind, [1, 2, 3, 4, 5]));\n    assert(equal(toIndex, [4, 2, 5, 1, 3]));\n\n    auto buf = new int[5];\n    poolInstance.amap!\"a * a\"([1,2,3,4,5], buf);\n    assert(buf == [1,4,9,16,25]);\n    poolInstance.amap!\"a * a\"([1,2,3,4,5], 4, buf);\n    assert(buf == [1,4,9,16,25]);\n\n    assert(poolInstance.reduce!\"a + b\"([1]) == 1);\n    assert(poolInstance.reduce!\"a + b\"([1,2,3,4]) == 10);\n    assert(poolInstance.reduce!\"a + b\"(0.0, [1,2,3,4]) == 10);\n    assert(poolInstance.reduce!\"a + b\"(0.0, [1,2,3,4], 1) == 10);\n    assert(poolInstance.reduce!(min, max)([1,2,3,4]) == tuple(1, 4));\n    assert(poolInstance.reduce!(\"a + b\", \"a * b\")(tuple(0, 1), [1,2,3,4]) ==\n           tuple(10, 24));\n\n    immutable serialAns = reduce!\"a + b\"(iota(1000));\n    assert(poolInstance.reduce!\"a + b\"(0, iota(1000)) == serialAns);\n    assert(poolInstance.reduce!\"a + b\"(iota(1000)) == serialAns);\n\n    // Test worker-local storage.\n    auto wl = poolInstance.workerLocalStorage(0);\n    foreach (i; poolInstance.parallel(iota(1000), 1))\n    {\n        wl.get = wl.get + i;\n    }\n\n    auto wlRange = wl.toRange;\n    auto parallelSum = poolInstance.reduce!\"a + b\"(wlRange);\n    assert(parallelSum == 499500);\n    assert(wlRange[0 .. 1][0] == wlRange[0]);\n    assert(wlRange[1 .. 2][0] == wlRange[1]);\n\n    // Test finish()\n    {\n        static void slowFun() { Thread.sleep(dur!\"msecs\"(1)); }\n\n        auto pool1 = new TaskPool();\n        auto tSlow = task!slowFun();\n        pool1.put(tSlow);\n        pool1.finish();\n        tSlow.yieldForce;\n        // Can't assert that pool1.status == PoolState.stopNow because status\n        // doesn't change until after the \"done\" flag is set and the waiting\n        // thread is woken up.\n\n        auto pool2 = new TaskPool();\n        auto tSlow2 = task!slowFun();\n        pool2.put(tSlow2);\n        pool2.finish(true); // blocking\n        assert(tSlow2.done);\n\n        // Test fix for Bug 8582 by making pool size zero.\n        auto pool3 = new TaskPool(0);\n        auto tSlow3 = task!slowFun();\n        pool3.put(tSlow3);\n        pool3.finish(true); // blocking\n        assert(tSlow3.done);\n\n        // This is correct because no thread will terminate unless pool2.status\n        // and pool3.status have already been set to stopNow.\n        assert(pool2.status == TaskPool.PoolState.stopNow);\n        assert(pool3.status == TaskPool.PoolState.stopNow);\n    }\n\n    // Test default pool stuff.\n    assert(taskPool.size == totalCPUs - 1);\n\n    nums = new uint[1000];\n    foreach (i; parallel(iota(1000)))\n    {\n        nums[i] = cast(uint) i;\n    }\n    assert(equal(nums, iota(1000)));\n\n    assert(equal(\n               poolInstance.map!\"a * a\"(iota(30_000_001), 10_000),\n               map!\"a * a\"(iota(30_000_001))\n           ));\n\n    // The filter is to kill random access and test the non-random access\n    // branch.\n    assert(equal(\n               poolInstance.map!\"a * a\"(\n                   filter!\"a == a\"(iota(30_000_001)\n                                  ), 10_000, 1000),\n               map!\"a * a\"(iota(30_000_001))\n           ));\n\n    assert(\n        reduce!\"a + b\"(0UL,\n                       poolInstance.map!\"a * a\"(iota(3_000_001), 10_000)\n                      ) ==\n        reduce!\"a + b\"(0UL,\n                       map!\"a * a\"(iota(3_000_001))\n                      )\n    );\n\n    assert(equal(\n               iota(1_000_002),\n               poolInstance.asyncBuf(filter!\"a == a\"(iota(1_000_002)))\n           ));\n\n    {\n        import std.conv : to;\n        import std.file : deleteme;\n\n        string temp_file = deleteme ~ \"-tempDelMe.txt\";\n        auto file = File(temp_file, \"wb\");\n        scope(exit)\n        {\n            file.close();\n            import std.file;\n            remove(temp_file);\n        }\n\n        auto written = [[1.0, 2, 3], [4.0, 5, 6], [7.0, 8, 9]];\n        foreach (row; written)\n        {\n            file.writeln(join(to!(string[])(row), \"\\t\"));\n        }\n\n        file = File(temp_file);\n\n        void next(ref char[] buf)\n        {\n            file.readln(buf);\n            import std.string : chomp;\n            buf = chomp(buf);\n        }\n\n        double[][] read;\n        auto asyncReader = taskPool.asyncBuf(&next, &file.eof);\n\n        foreach (line; asyncReader)\n        {\n            if (line.length == 0) continue;\n            auto ls = line.split(\"\\t\");\n            read ~= to!(double[])(ls);\n        }\n\n        assert(read == written);\n        file.close();\n    }\n\n    // Test Map/AsyncBuf chaining.\n\n    auto abuf = poolInstance.asyncBuf(iota(-1.0, 3_000_000), 100);\n    auto temp = poolInstance.map!sqrt(\n                    abuf, 100, 5\n                );\n    auto lmchain = poolInstance.map!\"a * a\"(temp, 100, 5);\n    lmchain.popFront();\n\n    int ii;\n    foreach ( elem; (lmchain))\n    {\n        if (!approxEqual(elem, ii))\n        {\n            stderr.writeln(ii, '\\t', elem);\n        }\n        ii++;\n    }\n\n    // Test buffer trick in parallel foreach.\n    abuf = poolInstance.asyncBuf(iota(-1.0, 1_000_000), 100);\n    abuf.popFront();\n    auto bufTrickTest = new size_t[abuf.length];\n    foreach (i, elem; parallel(abuf))\n    {\n        bufTrickTest[i] = i;\n    }\n\n    assert(equal(iota(1_000_000), bufTrickTest));\n\n    auto myTask = task!(std.math.abs)(-1);\n    taskPool.put(myTask);\n    assert(myTask.spinForce == 1);\n\n    // Test that worker local storage from one pool receives an index of 0\n    // when the index is queried w.r.t. another pool.  The only way to do this\n    // is non-deterministically.\n    foreach (i; parallel(iota(1000), 1))\n    {\n        assert(poolInstance.workerIndex == 0);\n    }\n\n    foreach (i; poolInstance.parallel(iota(1000), 1))\n    {\n        assert(taskPool.workerIndex == 0);\n    }\n\n    // Test exception handling.\n    static void parallelForeachThrow()\n    {\n        foreach (elem; parallel(iota(10)))\n        {\n            throw new Exception(\"\");\n        }\n    }\n\n    assertThrown!Exception(parallelForeachThrow());\n\n    static int reduceException(int a, int b)\n    {\n        throw new Exception(\"\");\n    }\n\n    assertThrown!Exception(\n        poolInstance.reduce!reduceException(iota(3))\n    );\n\n    static int mapException(int a)\n    {\n        throw new Exception(\"\");\n    }\n\n    assertThrown!Exception(\n        poolInstance.amap!mapException(iota(3))\n    );\n\n    static void mapThrow()\n    {\n        auto m = poolInstance.map!mapException(iota(3));\n        m.popFront();\n    }\n\n    assertThrown!Exception(mapThrow());\n\n    struct ThrowingRange\n    {\n        @property int front()\n        {\n            return 1;\n        }\n        void popFront()\n        {\n            throw new Exception(\"\");\n        }\n        enum bool empty = false;\n    }\n\n    assertThrown!Exception(poolInstance.asyncBuf(ThrowingRange.init));\n}\n\n//version = parallelismStressTest;\n\n// These are more like stress tests than real unit tests.  They print out\n// tons of stuff and should not be run every time make unittest is run.\nversion (parallelismStressTest)\n{\n    @safe unittest\n    {\n        size_t attempt;\n        for (; attempt < 10; attempt++)\n            foreach (poolSize; [0, 4])\n        {\n\n            poolInstance = new TaskPool(poolSize);\n\n            uint[] numbers = new uint[1_000];\n\n            foreach (i; poolInstance.parallel( iota(0, numbers.length)) )\n            {\n                numbers[i] = cast(uint) i;\n            }\n\n            // Make sure it works.\n            foreach (i; 0 .. numbers.length)\n            {\n                assert(numbers[i] == i);\n            }\n\n            stderr.writeln(\"Done creating nums.\");\n\n\n            auto myNumbers = filter!\"a % 7 > 0\"( iota(0, 1000));\n            foreach (num; poolInstance.parallel(myNumbers))\n            {\n                assert(num % 7 > 0 && num < 1000);\n            }\n            stderr.writeln(\"Done modulus test.\");\n\n            uint[] squares = poolInstance.amap!\"a * a\"(numbers, 100);\n            assert(squares.length == numbers.length);\n            foreach (i, number; numbers)\n            {\n                assert(squares[i] == number * number);\n            }\n            stderr.writeln(\"Done squares.\");\n\n            auto sumFuture = task!( reduce!\"a + b\" )(numbers);\n            poolInstance.put(sumFuture);\n\n            ulong sumSquares = 0;\n            foreach (elem; numbers)\n            {\n                sumSquares += elem * elem;\n            }\n\n            uint mySum = sumFuture.spinForce();\n            assert(mySum == 999 * 1000 / 2);\n\n            auto mySumParallel = poolInstance.reduce!\"a + b\"(numbers);\n            assert(mySum == mySumParallel);\n            stderr.writeln(\"Done sums.\");\n\n            auto myTask = task(\n            {\n                synchronized writeln(\"Our lives are parallel...Our lives are parallel.\");\n            });\n            poolInstance.put(myTask);\n\n            auto nestedOuter = \"abcd\";\n            auto nestedInner =  iota(0, 10, 2);\n\n            foreach (i, letter; poolInstance.parallel(nestedOuter, 1))\n            {\n                foreach (j, number; poolInstance.parallel(nestedInner, 1))\n                {\n                    synchronized writeln(i, \": \", letter, \"  \", j, \": \", number);\n                }\n            }\n\n            poolInstance.stop();\n        }\n\n        assert(attempt == 10);\n        writeln(\"Press enter to go to next round of unittests.\");\n        readln();\n    }\n\n    // These unittests are intended more for actual testing and not so much\n    // as examples.\n    @safe unittest\n    {\n        foreach (attempt; 0 .. 10)\n        foreach (poolSize; [0, 4])\n        {\n            poolInstance = new TaskPool(poolSize);\n\n            // Test indexing.\n            stderr.writeln(\"Creator Raw Index:  \", poolInstance.threadIndex);\n            assert(poolInstance.workerIndex() == 0);\n\n            // Test worker-local storage.\n            auto workerLocalStorage = poolInstance.workerLocalStorage!uint(1);\n            foreach (i; poolInstance.parallel(iota(0U, 1_000_000)))\n            {\n                workerLocalStorage.get++;\n            }\n            assert(reduce!\"a + b\"(workerLocalStorage.toRange) ==\n            1_000_000 + poolInstance.size + 1);\n\n            // Make sure work is reasonably balanced among threads.  This test is\n            // non-deterministic and is more of a sanity check than something that\n            // has an absolute pass/fail.\n            shared(uint)[void*] nJobsByThread;\n            foreach (thread; poolInstance.pool)\n            {\n                nJobsByThread[cast(void*) thread] = 0;\n            }\n            nJobsByThread[ cast(void*) Thread.getThis()] = 0;\n\n            foreach (i; poolInstance.parallel( iota(0, 1_000_000), 100 ))\n            {\n                atomicOp!\"+=\"( nJobsByThread[ cast(void*) Thread.getThis() ], 1);\n            }\n\n            stderr.writeln(\"\\nCurrent thread is:  \",\n            cast(void*) Thread.getThis());\n            stderr.writeln(\"Workload distribution:  \");\n            foreach (k, v; nJobsByThread)\n            {\n                stderr.writeln(k, '\\t', v);\n            }\n\n            // Test whether amap can be nested.\n            real[][] matrix = new real[][](1000, 1000);\n            foreach (i; poolInstance.parallel( iota(0, matrix.length) ))\n            {\n                foreach (j; poolInstance.parallel( iota(0, matrix[0].length) ))\n                {\n                    matrix[i][j] = i * j;\n                }\n            }\n\n            // Get around weird bugs having to do w/ sqrt being an intrinsic:\n            static real mySqrt(real num)\n            {\n                return sqrt(num);\n            }\n\n            static real[] parallelSqrt(real[] nums)\n            {\n                return poolInstance.amap!mySqrt(nums);\n            }\n\n            real[][] sqrtMatrix = poolInstance.amap!parallelSqrt(matrix);\n\n            foreach (i, row; sqrtMatrix)\n            {\n                foreach (j, elem; row)\n                {\n                    real shouldBe = sqrt( cast(real) i * j);\n                    assert(approxEqual(shouldBe, elem));\n                    sqrtMatrix[i][j] = shouldBe;\n                }\n            }\n\n            auto saySuccess = task(\n            {\n                stderr.writeln(\n                    \"Success doing matrix stuff that involves nested pool use.\");\n            });\n            poolInstance.put(saySuccess);\n            saySuccess.workForce();\n\n            // A more thorough test of amap, reduce:  Find the sum of the square roots of\n            // matrix.\n\n            static real parallelSum(real[] input)\n            {\n                return poolInstance.reduce!\"a + b\"(input);\n            }\n\n            auto sumSqrt = poolInstance.reduce!\"a + b\"(\n                               poolInstance.amap!parallelSum(\n                                   sqrtMatrix\n                               )\n                           );\n\n            assert(approxEqual(sumSqrt, 4.437e8));\n            stderr.writeln(\"Done sum of square roots.\");\n\n            // Test whether tasks work with function pointers.\n            auto nanTask = task(&isNaN, 1.0L);\n            poolInstance.put(nanTask);\n            assert(nanTask.spinForce == false);\n\n            if (poolInstance.size > 0)\n            {\n                // Test work waiting.\n                static void uselessFun()\n                {\n                    foreach (i; 0 .. 1_000_000) {}\n                }\n\n                auto uselessTasks = new typeof(task(&uselessFun))[1000];\n                foreach (ref uselessTask; uselessTasks)\n                {\n                    uselessTask = task(&uselessFun);\n                }\n                foreach (ref uselessTask; uselessTasks)\n                {\n                    poolInstance.put(uselessTask);\n                }\n                foreach (ref uselessTask; uselessTasks)\n                {\n                    uselessTask.workForce();\n                }\n            }\n\n            // Test the case of non-random access + ref returns.\n            int[] nums = [1,2,3,4,5];\n            static struct RemoveRandom\n            {\n                int[] arr;\n\n                ref int front()\n                {\n                    return arr.front;\n                }\n                void popFront()\n                {\n                    arr.popFront();\n                }\n                bool empty()\n                {\n                    return arr.empty;\n                }\n            }\n\n            auto refRange = RemoveRandom(nums);\n            foreach (ref elem; poolInstance.parallel(refRange))\n            {\n                elem++;\n            }\n            assert(nums == [2,3,4,5,6], text(nums));\n            stderr.writeln(\"Nums:  \", nums);\n\n            poolInstance.stop();\n        }\n    }\n}\n\n@system unittest\n{\n    static struct __S_12733\n    {\n        invariant() { assert(checksum == 1_234_567_890); }\n        this(ulong u){n = u;}\n        void opAssign(__S_12733 s){this.n = s.n;}\n        ulong n;\n        ulong checksum = 1_234_567_890;\n    }\n\n    static auto __genPair_12733(ulong n) { return __S_12733(n); }\n    immutable ulong[] data = [ 2UL^^59-1, 2UL^^59-1, 2UL^^59-1, 112_272_537_195_293UL ];\n\n    auto result = taskPool.amap!__genPair_12733(data);\n}\n\n@safe unittest\n{\n    import std.range : iota;\n\n    // this test was in std.range, but caused cycles.\n    assert(__traits(compiles, { foreach (i; iota(0, 100UL).parallel) {} }));\n}\n\n@safe unittest\n{\n    import std.algorithm.iteration : each;\n\n    long[] arr;\n    static assert(is(typeof({\n        arr.parallel.each!\"a++\";\n    })));\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17539\n@system unittest\n{\n    import std.random : rndGen;\n    // ensure compilation\n    try foreach (rnd; rndGen.parallel) break;\n    catch (ParallelForeachError e) {}\n}\n"
  },
  {
    "path": "libphobos/src/std/path.d",
    "content": "// Written in the D programming language.\n\n/** This module is used to manipulate path strings.\n\n    All functions, with the exception of $(LREF expandTilde) (and in some\n    cases $(LREF absolutePath) and $(LREF relativePath)), are pure\n    string manipulation functions; they don't depend on any state outside\n    the program, nor do they perform any actual file system actions.\n    This has the consequence that the module does not make any distinction\n    between a path that points to a directory and a path that points to a\n    file, and it does not know whether or not the object pointed to by the\n    path actually exists in the file system.\n    To differentiate between these cases, use $(REF isDir, std,file) and\n    $(REF exists, std,file).\n\n    Note that on Windows, both the backslash ($(D `\\`)) and the slash ($(D `/`))\n    are in principle valid directory separators.  This module treats them\n    both on equal footing, but in cases where a $(I new) separator is\n    added, a backslash will be used.  Furthermore, the $(LREF buildNormalizedPath)\n    function will replace all slashes with backslashes on that platform.\n\n    In general, the functions in this module assume that the input paths\n    are well-formed.  (That is, they should not contain invalid characters,\n    they should follow the file system's path format, etc.)  The result\n    of calling a function on an ill-formed path is undefined.  When there\n    is a chance that a path or a file name is invalid (for instance, when it\n    has been input by the user), it may sometimes be desirable to use the\n    $(LREF isValidFilename) and $(LREF isValidPath) functions to check\n    this.\n\n    Most functions do not perform any memory allocations, and if a string is\n    returned, it is usually a slice of an input string.  If a function\n    allocates, this is explicitly mentioned in the documentation.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(DIVC quickindex,\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Normalization) $(TD\n          $(LREF absolutePath)\n          $(LREF asAbsolutePath)\n          $(LREF asNormalizedPath)\n          $(LREF asRelativePath)\n          $(LREF buildNormalizedPath)\n          $(LREF buildPath)\n          $(LREF chainPath)\n          $(LREF expandTilde)\n))\n$(TR $(TD Partitioning) $(TD\n          $(LREF baseName)\n          $(LREF dirName)\n          $(LREF dirSeparator)\n          $(LREF driveName)\n          $(LREF pathSeparator)\n          $(LREF pathSplitter)\n          $(LREF relativePath)\n          $(LREF rootName)\n          $(LREF stripDrive)\n))\n$(TR $(TD Validation) $(TD\n          $(LREF isAbsolute)\n          $(LREF isDirSeparator)\n          $(LREF isRooted)\n          $(LREF isValidFilename)\n          $(LREF isValidPath)\n))\n$(TR $(TD Extension) $(TD\n          $(LREF defaultExtension)\n          $(LREF extension)\n          $(LREF setExtension)\n          $(LREF stripExtension)\n          $(LREF withDefaultExtension)\n          $(LREF withExtension)\n))\n$(TR $(TD Other) $(TD\n          $(LREF filenameCharCmp)\n          $(LREF filenameCmp)\n          $(LREF globMatch)\n          $(LREF CaseSensitive)\n))\n))\n\n    Authors:\n        Lars Tandle Kyllingstad,\n        $(HTTP digitalmars.com, Walter Bright),\n        Grzegorz Adam Hankiewicz,\n        Thomas K$(UUML)hne,\n        $(HTTP erdani.org, Andrei Alexandrescu)\n    Copyright:\n        Copyright (c) 2000-2014, the authors. All rights reserved.\n    License:\n        $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)\n    Source:\n        $(PHOBOSSRC std/path.d)\n*/\nmodule std.path;\n\n\n// FIXME\nimport std.file; //: getcwd;\nstatic import std.meta;\nimport std.range.primitives;\nimport std.traits;\n\nversion (unittest)\n{\nprivate:\n    struct TestAliasedString\n    {\n        string get() @safe @nogc pure nothrow { return _s; }\n        alias get this;\n        @disable this(this);\n        string _s;\n    }\n\n    bool testAliasedString(alias func, Args...)(string s, Args args)\n    {\n        return func(TestAliasedString(s), args) == func(s, args);\n    }\n}\n\n/** String used to separate directory names in a path.  Under\n    POSIX this is a slash, under Windows a backslash.\n*/\nversion (Posix)          enum string dirSeparator = \"/\";\nelse version (Windows)   enum string dirSeparator = \"\\\\\";\nelse static assert(0, \"unsupported platform\");\n\n\n\n\n/** Path separator string.  A colon under POSIX, a semicolon\n    under Windows.\n*/\nversion (Posix)          enum string pathSeparator = \":\";\nelse version (Windows)   enum string pathSeparator = \";\";\nelse static assert(0, \"unsupported platform\");\n\n\n\n\n/** Determines whether the given character is a directory separator.\n\n    On Windows, this includes both $(D `\\`) and $(D `/`).\n    On POSIX, it's just $(D `/`).\n*/\nbool isDirSeparator(dchar c)  @safe pure nothrow @nogc\n{\n    if (c == '/') return true;\n    version (Windows) if (c == '\\\\') return true;\n    return false;\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    version (Windows)\n    {\n        assert( '/'.isDirSeparator);\n        assert( '\\\\'.isDirSeparator);\n    }\n    else\n    {\n        assert( '/'.isDirSeparator);\n        assert(!'\\\\'.isDirSeparator);\n    }\n}\n\n\n/*  Determines whether the given character is a drive separator.\n\n    On Windows, this is true if c is the ':' character that separates\n    the drive letter from the rest of the path.  On POSIX, this always\n    returns false.\n*/\nprivate bool isDriveSeparator(dchar c)  @safe pure nothrow @nogc\n{\n    version (Windows) return c == ':';\n    else return false;\n}\n\n\n/*  Combines the isDirSeparator and isDriveSeparator tests. */\nversion (Windows) private bool isSeparator(dchar c)  @safe pure nothrow @nogc\n{\n    return isDirSeparator(c) || isDriveSeparator(c);\n}\nversion (Posix) private alias isSeparator = isDirSeparator;\n\n\n/*  Helper function that determines the position of the last\n    drive/directory separator in a string.  Returns -1 if none\n    is found.\n*/\nprivate ptrdiff_t lastSeparator(R)(R path)\nif (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||\n    isNarrowString!R)\n{\n    auto i = (cast(ptrdiff_t) path.length) - 1;\n    while (i >= 0 && !isSeparator(path[i])) --i;\n    return i;\n}\n\n\nversion (Windows)\n{\n    private bool isUNC(R)(R path)\n    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||\n        isNarrowString!R)\n    {\n        return path.length >= 3 && isDirSeparator(path[0]) && isDirSeparator(path[1])\n            && !isDirSeparator(path[2]);\n    }\n\n    private ptrdiff_t uncRootLength(R)(R path)\n    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||\n        isNarrowString!R)\n        in { assert(isUNC(path)); }\n        do\n    {\n        ptrdiff_t i = 3;\n        while (i < path.length && !isDirSeparator(path[i])) ++i;\n        if (i < path.length)\n        {\n            auto j = i;\n            do { ++j; } while (j < path.length && isDirSeparator(path[j]));\n            if (j < path.length)\n            {\n                do { ++j; } while (j < path.length && !isDirSeparator(path[j]));\n                i = j;\n            }\n        }\n        return i;\n    }\n\n    private bool hasDrive(R)(R path)\n    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||\n        isNarrowString!R)\n    {\n        return path.length >= 2 && isDriveSeparator(path[1]);\n    }\n\n    private bool isDriveRoot(R)(R path)\n    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||\n        isNarrowString!R)\n    {\n        return path.length >= 3 && isDriveSeparator(path[1])\n            && isDirSeparator(path[2]);\n    }\n}\n\n\n/*  Helper functions that strip leading/trailing slashes and backslashes\n    from a path.\n*/\nprivate auto ltrimDirSeparators(R)(R path)\nif (isInputRange!R && !isInfinite!R && isSomeChar!(ElementType!R) ||\n    isNarrowString!R)\n{\n    static if (isRandomAccessRange!R && hasSlicing!R || isNarrowString!R)\n    {\n        int i = 0;\n        while (i < path.length && isDirSeparator(path[i]))\n            ++i;\n        return path[i .. path.length];\n    }\n    else\n    {\n        while (!path.empty && isDirSeparator(path.front))\n            path.popFront();\n        return path;\n    }\n}\n\n@safe unittest\n{\n    import std.array;\n    import std.utf : byDchar;\n\n    assert(ltrimDirSeparators(\"//abc//\").array == \"abc//\");\n    assert(ltrimDirSeparators(\"//abc//\"d).array == \"abc//\"d);\n    assert(ltrimDirSeparators(\"//abc//\".byDchar).array == \"abc//\"d);\n}\n\nprivate auto rtrimDirSeparators(R)(R path)\nif (isBidirectionalRange!R && isSomeChar!(ElementType!R) ||\n    isNarrowString!R)\n{\n    static if (isRandomAccessRange!R && hasSlicing!R && hasLength!R || isNarrowString!R)\n    {\n        auto i = (cast(ptrdiff_t) path.length) - 1;\n        while (i >= 0 && isDirSeparator(path[i]))\n            --i;\n        return path[0 .. i+1];\n    }\n    else\n    {\n        while (!path.empty && isDirSeparator(path.back))\n            path.popBack();\n        return path;\n    }\n}\n\n@safe unittest\n{\n    import std.array;\n    import std.utf : byDchar;\n\n    assert(rtrimDirSeparators(\"//abc//\").array == \"//abc\");\n    assert(rtrimDirSeparators(\"//abc//\"d).array == \"//abc\"d);\n\n    assert(rtrimDirSeparators(MockBiRange!char(\"//abc//\")).array == \"//abc\");\n}\n\nprivate auto trimDirSeparators(R)(R path)\nif (isBidirectionalRange!R && isSomeChar!(ElementType!R) ||\n    isNarrowString!R)\n{\n    return ltrimDirSeparators(rtrimDirSeparators(path));\n}\n\n@safe unittest\n{\n    import std.array;\n    import std.utf : byDchar;\n\n    assert(trimDirSeparators(\"//abc//\").array == \"abc\");\n    assert(trimDirSeparators(\"//abc//\"d).array == \"abc\"d);\n\n    assert(trimDirSeparators(MockBiRange!char(\"//abc//\")).array == \"abc\");\n}\n\n/** This `enum` is used as a template argument to functions which\n    compare file names, and determines whether the comparison is\n    case sensitive or not.\n*/\nenum CaseSensitive : bool\n{\n    /// File names are case insensitive\n    no = false,\n\n    /// File names are case sensitive\n    yes = true,\n\n    /** The default (or most common) setting for the current platform.\n        That is, `no` on Windows and Mac OS X, and `yes` on all\n        POSIX systems except OS X (Linux, *BSD, etc.).\n    */\n    osDefault = osDefaultCaseSensitivity\n}\n\n///\n@safe unittest\n{\n    assert(baseName!(CaseSensitive.no)(\"dir/file.EXT\", \".ext\") == \"file\");\n    assert(baseName!(CaseSensitive.yes)(\"dir/file.EXT\", \".ext\") != \"file\");\n\n    version (Posix)\n        assert(relativePath!(CaseSensitive.no)(\"/FOO/bar\", \"/foo/baz\") == \"../bar\");\n    else\n        assert(relativePath!(CaseSensitive.no)(`c:\\FOO\\bar`, `c:\\foo\\baz`) == `..\\bar`);\n}\n\nversion (Windows)    private enum osDefaultCaseSensitivity = false;\nelse version (OSX)   private enum osDefaultCaseSensitivity = false;\nelse version (Posix) private enum osDefaultCaseSensitivity = true;\nelse static assert(0);\n\n/**\n    Params:\n        cs = Whether or not suffix matching is case-sensitive.\n        path = A path name. It can be a string, or any random-access range of\n            characters.\n        suffix = An optional suffix to be removed from the file name.\n    Returns: The name of the file in the path name, without any leading\n        directory and with an optional suffix chopped off.\n\n    If `suffix` is specified, it will be compared to `path`\n    using `filenameCmp!cs`,\n    where `cs` is an optional template parameter determining whether\n    the comparison is case sensitive or not.  See the\n    $(LREF filenameCmp) documentation for details.\n\n    Note:\n    This function $(I only) strips away the specified suffix, which\n    doesn't necessarily have to represent an extension.\n    To remove the extension from a path, regardless of what the extension\n    is, use $(LREF stripExtension).\n    To obtain the filename without leading directories and without\n    an extension, combine the functions like this:\n    ---\n    assert(baseName(stripExtension(\"dir/file.ext\")) == \"file\");\n    ---\n\n    Standards:\n    This function complies with\n    $(LINK2 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/basename.html,\n    the POSIX requirements for the 'basename' shell utility)\n    (with suitable adaptations for Windows paths).\n*/\nauto baseName(R)(R path)\nif (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) && !isSomeString!R)\n{\n    return _baseName(path);\n}\n\n/// ditto\nauto baseName(C)(C[] path)\nif (isSomeChar!C)\n{\n    return _baseName(path);\n}\n\n/// ditto\ninout(C)[] baseName(CaseSensitive cs = CaseSensitive.osDefault, C, C1)\n    (inout(C)[] path, in C1[] suffix)\n    @safe pure //TODO: nothrow (because of filenameCmp())\nif (isSomeChar!C && isSomeChar!C1)\n{\n    auto p = baseName(path);\n    if (p.length > suffix.length\n        && filenameCmp!cs(cast(const(C)[])p[$-suffix.length .. $], suffix) == 0)\n    {\n        return p[0 .. $-suffix.length];\n    }\n    else return p;\n}\n\n///\n@safe unittest\n{\n    assert(baseName(\"dir/file.ext\") == \"file.ext\");\n    assert(baseName(\"dir/file.ext\", \".ext\") == \"file\");\n    assert(baseName(\"dir/file.ext\", \".xyz\") == \"file.ext\");\n    assert(baseName(\"dir/filename\", \"name\") == \"file\");\n    assert(baseName(\"dir/subdir/\") == \"subdir\");\n\n    version (Windows)\n    {\n        assert(baseName(`d:file.ext`) == \"file.ext\");\n        assert(baseName(`d:\\dir\\file.ext`) == \"file.ext\");\n    }\n}\n\n@safe unittest\n{\n    assert(baseName(\"\").empty);\n    assert(baseName(\"file.ext\"w) == \"file.ext\");\n    assert(baseName(\"file.ext\"d, \".ext\") == \"file\");\n    assert(baseName(\"file\", \"file\"w.dup) == \"file\");\n    assert(baseName(\"dir/file.ext\"d.dup) == \"file.ext\");\n    assert(baseName(\"dir/file.ext\", \".ext\"d) == \"file\");\n    assert(baseName(\"dir/file\"w, \"file\"d) == \"file\");\n    assert(baseName(\"dir///subdir////\") == \"subdir\");\n    assert(baseName(\"dir/subdir.ext/\", \".ext\") == \"subdir\");\n    assert(baseName(\"dir/subdir/\".dup, \"subdir\") == \"subdir\");\n    assert(baseName(\"/\"w.dup) == \"/\");\n    assert(baseName(\"//\"d.dup) == \"/\");\n    assert(baseName(\"///\") == \"/\");\n\n    assert(baseName!(CaseSensitive.yes)(\"file.ext\", \".EXT\") == \"file.ext\");\n    assert(baseName!(CaseSensitive.no)(\"file.ext\", \".EXT\") == \"file\");\n\n    {\n        auto r = MockRange!(immutable(char))(`dir/file.ext`);\n        auto s = r.baseName();\n        foreach (i, c; `file`)\n            assert(s[i] == c);\n    }\n\n    version (Windows)\n    {\n        assert(baseName(`dir\\file.ext`) == `file.ext`);\n        assert(baseName(`dir\\file.ext`, `.ext`) == `file`);\n        assert(baseName(`dir\\file`, `file`) == `file`);\n        assert(baseName(`d:file.ext`) == `file.ext`);\n        assert(baseName(`d:file.ext`, `.ext`) == `file`);\n        assert(baseName(`d:file`, `file`) == `file`);\n        assert(baseName(`dir\\\\subdir\\\\\\`) == `subdir`);\n        assert(baseName(`dir\\subdir.ext\\`, `.ext`) == `subdir`);\n        assert(baseName(`dir\\subdir\\`, `subdir`) == `subdir`);\n        assert(baseName(`\\`) == `\\`);\n        assert(baseName(`\\\\`) == `\\`);\n        assert(baseName(`\\\\\\`) == `\\`);\n        assert(baseName(`d:\\`) == `\\`);\n        assert(baseName(`d:`).empty);\n        assert(baseName(`\\\\server\\share\\file`) == `file`);\n        assert(baseName(`\\\\server\\share\\`) == `\\`);\n        assert(baseName(`\\\\server\\share`) == `\\`);\n\n        auto r = MockRange!(immutable(char))(`\\\\server\\share`);\n        auto s = r.baseName();\n        foreach (i, c; `\\`)\n            assert(s[i] == c);\n    }\n\n    assert(baseName(stripExtension(\"dir/file.ext\")) == \"file\");\n\n    static assert(baseName(\"dir/file.ext\") == \"file.ext\");\n    static assert(baseName(\"dir/file.ext\", \".ext\") == \"file\");\n\n    static struct DirEntry { string s; alias s this; }\n    assert(baseName(DirEntry(\"dir/file.ext\")) == \"file.ext\");\n}\n\n@safe unittest\n{\n    assert(testAliasedString!baseName(\"file\"));\n\n    enum S : string { a = \"file/path/to/test\" }\n    assert(S.a.baseName == \"test\");\n\n    char[S.a.length] sa = S.a[];\n    assert(sa.baseName == \"test\");\n}\n\nprivate R _baseName(R)(R path)\nif (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) || isNarrowString!R)\n{\n    auto p1 = stripDrive(path);\n    if (p1.empty)\n    {\n        version (Windows) if (isUNC(path))\n            return path[0 .. 1];\n        static if (isSomeString!R)\n            return null;\n        else\n            return p1; // which is empty\n    }\n\n    auto p2 = rtrimDirSeparators(p1);\n    if (p2.empty) return p1[0 .. 1];\n\n    return p2[lastSeparator(p2)+1 .. p2.length];\n}\n\n/** Returns the parent directory of path. On Windows, this\n    includes the drive letter if present.\n\n    Params:\n        path = A path name.\n\n    Returns:\n        A slice of `path` or \".\".\n\n    Standards:\n    This function complies with\n    $(LINK2 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/dirname.html,\n    the POSIX requirements for the 'dirname' shell utility)\n    (with suitable adaptations for Windows paths).\n*/\nauto dirName(R)(R path)\nif (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R)\n{\n    return _dirName(path);\n}\n\n/// ditto\nauto dirName(C)(C[] path)\nif (isSomeChar!C)\n{\n    return _dirName(path);\n}\n\n///\n@safe unittest\n{\n    assert(dirName(\"\") == \".\");\n    assert(dirName(\"file\"w) == \".\");\n    assert(dirName(\"dir/\"d) == \".\");\n    assert(dirName(\"dir///\") == \".\");\n    assert(dirName(\"dir/file\"w.dup) == \"dir\");\n    assert(dirName(\"dir///file\"d.dup) == \"dir\");\n    assert(dirName(\"dir/subdir/\") == \"dir\");\n    assert(dirName(\"/dir/file\"w) == \"/dir\");\n    assert(dirName(\"/file\"d) == \"/\");\n    assert(dirName(\"/\") == \"/\");\n    assert(dirName(\"///\") == \"/\");\n\n    version (Windows)\n    {\n        assert(dirName(`dir\\`) == `.`);\n        assert(dirName(`dir\\\\\\`) == `.`);\n        assert(dirName(`dir\\file`) == `dir`);\n        assert(dirName(`dir\\\\\\file`) == `dir`);\n        assert(dirName(`dir\\subdir\\`) == `dir`);\n        assert(dirName(`\\dir\\file`) == `\\dir`);\n        assert(dirName(`\\file`) == `\\`);\n        assert(dirName(`\\`) == `\\`);\n        assert(dirName(`\\\\\\`) == `\\`);\n        assert(dirName(`d:`) == `d:`);\n        assert(dirName(`d:file`) == `d:`);\n        assert(dirName(`d:\\`) == `d:\\`);\n        assert(dirName(`d:\\file`) == `d:\\`);\n        assert(dirName(`d:\\dir\\file`) == `d:\\dir`);\n        assert(dirName(`\\\\server\\share\\dir\\file`) == `\\\\server\\share\\dir`);\n        assert(dirName(`\\\\server\\share\\file`) == `\\\\server\\share`);\n        assert(dirName(`\\\\server\\share\\`) == `\\\\server\\share`);\n        assert(dirName(`\\\\server\\share`) == `\\\\server\\share`);\n    }\n}\n\n@safe unittest\n{\n    assert(testAliasedString!dirName(\"file\"));\n\n    enum S : string { a = \"file/path/to/test\" }\n    assert(S.a.dirName == \"file/path/to\");\n\n    char[S.a.length] sa = S.a[];\n    assert(sa.dirName == \"file/path/to\");\n}\n\n@safe unittest\n{\n    static assert(dirName(\"dir/file\") == \"dir\");\n\n    import std.array;\n    import std.utf : byChar, byWchar, byDchar;\n\n    assert(dirName(\"\".byChar).array == \".\");\n    assert(dirName(\"file\"w.byWchar).array == \".\"w);\n    assert(dirName(\"dir/\"d.byDchar).array == \".\"d);\n    assert(dirName(\"dir///\".byChar).array == \".\");\n    assert(dirName(\"dir/subdir/\".byChar).array == \"dir\");\n    assert(dirName(\"/dir/file\"w.byWchar).array == \"/dir\"w);\n    assert(dirName(\"/file\"d.byDchar).array == \"/\"d);\n    assert(dirName(\"/\".byChar).array == \"/\");\n    assert(dirName(\"///\".byChar).array == \"/\");\n\n    version (Windows)\n    {\n        assert(dirName(`dir\\`.byChar).array == `.`);\n        assert(dirName(`dir\\\\\\`.byChar).array == `.`);\n        assert(dirName(`dir\\file`.byChar).array == `dir`);\n        assert(dirName(`dir\\\\\\file`.byChar).array == `dir`);\n        assert(dirName(`dir\\subdir\\`.byChar).array == `dir`);\n        assert(dirName(`\\dir\\file`.byChar).array == `\\dir`);\n        assert(dirName(`\\file`.byChar).array == `\\`);\n        assert(dirName(`\\`.byChar).array == `\\`);\n        assert(dirName(`\\\\\\`.byChar).array == `\\`);\n        assert(dirName(`d:`.byChar).array == `d:`);\n        assert(dirName(`d:file`.byChar).array == `d:`);\n        assert(dirName(`d:\\`.byChar).array == `d:\\`);\n        assert(dirName(`d:\\file`.byChar).array == `d:\\`);\n        assert(dirName(`d:\\dir\\file`.byChar).array == `d:\\dir`);\n        assert(dirName(`\\\\server\\share\\dir\\file`.byChar).array == `\\\\server\\share\\dir`);\n        assert(dirName(`\\\\server\\share\\file`) == `\\\\server\\share`);\n        assert(dirName(`\\\\server\\share\\`.byChar).array == `\\\\server\\share`);\n        assert(dirName(`\\\\server\\share`.byChar).array == `\\\\server\\share`);\n    }\n\n    //static assert(dirName(\"dir/file\".byChar).array == \"dir\");\n}\n\nprivate auto _dirName(R)(R path)\n{\n    static auto result(bool dot, typeof(path[0 .. 1]) p)\n    {\n        static if (isSomeString!R)\n            return dot ? \".\" : p;\n        else\n        {\n            import std.range : choose, only;\n            return choose(dot, only(cast(ElementEncodingType!R)'.'), p);\n        }\n    }\n\n    if (path.empty)\n        return result(true, path[0 .. 0]);\n\n    auto p = rtrimDirSeparators(path);\n    if (p.empty)\n        return result(false, path[0 .. 1]);\n\n    version (Windows)\n    {\n        if (isUNC(p) && uncRootLength(p) == p.length)\n            return result(false, p);\n\n        if (p.length == 2 && isDriveSeparator(p[1]) && path.length > 2)\n            return result(false, path[0 .. 3]);\n    }\n\n    auto i = lastSeparator(p);\n    if (i == -1)\n        return result(true, p);\n    if (i == 0)\n        return result(false, p[0 .. 1]);\n\n    version (Windows)\n    {\n        // If the directory part is either d: or d:\\\n        // do not chop off the last symbol.\n        if (isDriveSeparator(p[i]) || isDriveSeparator(p[i-1]))\n            return result(false, p[0 .. i+1]);\n    }\n    // Remove any remaining trailing (back)slashes.\n    return result(false, rtrimDirSeparators(p[0 .. i]));\n}\n\n/** Returns the root directory of the specified path, or `null` if the\n    path is not rooted.\n\n    Params:\n        path = A path name.\n\n    Returns:\n        A slice of `path`.\n*/\nauto rootName(R)(R path)\nif (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R)\n{\n    return _rootName(path);\n}\n\n/// ditto\nauto rootName(C)(C[] path)\nif (isSomeChar!C)\n{\n    return _rootName(path);\n}\n\n///\n@safe unittest\n{\n    assert(rootName(\"\") is null);\n    assert(rootName(\"foo\") is null);\n    assert(rootName(\"/\") == \"/\");\n    assert(rootName(\"/foo/bar\") == \"/\");\n\n    version (Windows)\n    {\n        assert(rootName(\"d:foo\") is null);\n        assert(rootName(`d:\\foo`) == `d:\\`);\n        assert(rootName(`\\\\server\\share\\foo`) == `\\\\server\\share`);\n        assert(rootName(`\\\\server\\share`) == `\\\\server\\share`);\n    }\n}\n\n@safe unittest\n{\n    assert(testAliasedString!rootName(\"/foo/bar\"));\n\n    enum S : string { a = \"/foo/bar\" }\n    assert(S.a.rootName == \"/\");\n\n    char[S.a.length] sa = S.a[];\n    assert(sa.rootName == \"/\");\n}\n\n@safe unittest\n{\n    import std.array;\n    import std.utf : byChar;\n\n    assert(rootName(\"\".byChar).array == \"\");\n    assert(rootName(\"foo\".byChar).array == \"\");\n    assert(rootName(\"/\".byChar).array == \"/\");\n    assert(rootName(\"/foo/bar\".byChar).array == \"/\");\n\n    version (Windows)\n    {\n        assert(rootName(\"d:foo\".byChar).array == \"\");\n        assert(rootName(`d:\\foo`.byChar).array == `d:\\`);\n        assert(rootName(`\\\\server\\share\\foo`.byChar).array == `\\\\server\\share`);\n        assert(rootName(`\\\\server\\share`.byChar).array == `\\\\server\\share`);\n    }\n}\n\nprivate auto _rootName(R)(R path)\n{\n    if (path.empty)\n        goto Lnull;\n\n    version (Posix)\n    {\n        if (isDirSeparator(path[0])) return path[0 .. 1];\n    }\n    else version (Windows)\n    {\n        if (isDirSeparator(path[0]))\n        {\n            if (isUNC(path)) return path[0 .. uncRootLength(path)];\n            else return path[0 .. 1];\n        }\n        else if (path.length >= 3 && isDriveSeparator(path[1]) &&\n            isDirSeparator(path[2]))\n        {\n            return path[0 .. 3];\n        }\n    }\n    else static assert(0, \"unsupported platform\");\n\n    assert(!isRooted(path));\nLnull:\n    static if (is(StringTypeOf!R))\n        return null; // legacy code may rely on null return rather than slice\n    else\n        return path[0 .. 0];\n}\n\n/**\n    Get the drive portion of a path.\n\n    Params:\n        path = string or range of characters\n\n    Returns:\n        A slice of `path` that is the drive, or an empty range if the drive\n        is not specified.  In the case of UNC paths, the network share\n        is returned.\n\n        Always returns an empty range on POSIX.\n*/\nauto driveName(R)(R path)\nif (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R)\n{\n    return _driveName(path);\n}\n\n/// ditto\nauto driveName(C)(C[] path)\nif (isSomeChar!C)\n{\n    return _driveName(path);\n}\n\n///\n@safe unittest\n{\n    import std.range : empty;\n    version (Posix)  assert(driveName(\"c:/foo\").empty);\n    version (Windows)\n    {\n        assert(driveName(`dir\\file`).empty);\n        assert(driveName(`d:file`) == \"d:\");\n        assert(driveName(`d:\\file`) == \"d:\");\n        assert(driveName(\"d:\") == \"d:\");\n        assert(driveName(`\\\\server\\share\\file`) == `\\\\server\\share`);\n        assert(driveName(`\\\\server\\share\\`) == `\\\\server\\share`);\n        assert(driveName(`\\\\server\\share`) == `\\\\server\\share`);\n\n        static assert(driveName(`d:\\file`) == \"d:\");\n    }\n}\n\n@safe unittest\n{\n    assert(testAliasedString!driveName(\"d:/file\"));\n\n    version (Posix)\n        immutable result = \"\";\n    else version (Windows)\n        immutable result = \"d:\";\n\n    enum S : string { a = \"d:/file\" }\n    assert(S.a.driveName == result);\n\n    char[S.a.length] sa = S.a[];\n    assert(sa.driveName == result);\n}\n\n@safe unittest\n{\n    import std.array;\n    import std.utf : byChar;\n\n    version (Posix)  assert(driveName(\"c:/foo\".byChar).empty);\n    version (Windows)\n    {\n        assert(driveName(`dir\\file`.byChar).empty);\n        assert(driveName(`d:file`.byChar).array == \"d:\");\n        assert(driveName(`d:\\file`.byChar).array == \"d:\");\n        assert(driveName(\"d:\".byChar).array == \"d:\");\n        assert(driveName(`\\\\server\\share\\file`.byChar).array == `\\\\server\\share`);\n        assert(driveName(`\\\\server\\share\\`.byChar).array == `\\\\server\\share`);\n        assert(driveName(`\\\\server\\share`.byChar).array == `\\\\server\\share`);\n\n        static assert(driveName(`d:\\file`).array == \"d:\");\n    }\n}\n\nprivate auto _driveName(R)(R path)\n{\n    version (Windows)\n    {\n        if (hasDrive(path))\n            return path[0 .. 2];\n        else if (isUNC(path))\n            return path[0 .. uncRootLength(path)];\n    }\n    static if (isSomeString!R)\n        return cast(ElementEncodingType!R[]) null; // legacy code may rely on null return rather than slice\n    else\n        return path[0 .. 0];\n}\n\n/** Strips the drive from a Windows path.  On POSIX, the path is returned\n    unaltered.\n\n    Params:\n        path = A pathname\n\n    Returns: A slice of path without the drive component.\n*/\nauto stripDrive(R)(R path)\nif (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) && !isSomeString!R)\n{\n    return _stripDrive(path);\n}\n\n/// ditto\nauto stripDrive(C)(C[] path)\nif (isSomeChar!C)\n{\n    return _stripDrive(path);\n}\n\n///\n@safe unittest\n{\n    version (Windows)\n    {\n        assert(stripDrive(`d:\\dir\\file`) == `\\dir\\file`);\n        assert(stripDrive(`\\\\server\\share\\dir\\file`) == `\\dir\\file`);\n    }\n}\n\n@safe unittest\n{\n    assert(testAliasedString!stripDrive(\"d:/dir/file\"));\n\n    version (Posix)\n        immutable result = \"d:/dir/file\";\n    else version (Windows)\n        immutable result = \"/dir/file\";\n\n    enum S : string { a = \"d:/dir/file\" }\n    assert(S.a.stripDrive == result);\n\n    char[S.a.length] sa = S.a[];\n    assert(sa.stripDrive == result);\n}\n\n@safe unittest\n{\n    version (Windows)\n    {\n        assert(stripDrive(`d:\\dir\\file`) == `\\dir\\file`);\n        assert(stripDrive(`\\\\server\\share\\dir\\file`) == `\\dir\\file`);\n        static assert(stripDrive(`d:\\dir\\file`) == `\\dir\\file`);\n\n        auto r = MockRange!(immutable(char))(`d:\\dir\\file`);\n        auto s = r.stripDrive();\n        foreach (i, c; `\\dir\\file`)\n            assert(s[i] == c);\n    }\n    version (Posix)\n    {\n        assert(stripDrive(`d:\\dir\\file`) == `d:\\dir\\file`);\n\n        auto r = MockRange!(immutable(char))(`d:\\dir\\file`);\n        auto s = r.stripDrive();\n        foreach (i, c; `d:\\dir\\file`)\n            assert(s[i] == c);\n    }\n}\n\nprivate auto _stripDrive(R)(R path)\n{\n    version (Windows)\n    {\n        if (hasDrive!(BaseOf!R)(path))      return path[2 .. path.length];\n        else if (isUNC!(BaseOf!R)(path))    return path[uncRootLength!(BaseOf!R)(path) .. path.length];\n    }\n    return path;\n}\n\n\n/*  Helper function that returns the position of the filename/extension\n    separator dot in path.\n\n    Params:\n        path = file spec as string or indexable range\n    Returns:\n        index of extension separator (the dot), or -1 if not found\n*/\nprivate ptrdiff_t extSeparatorPos(R)(const R path)\nif (isRandomAccessRange!R && hasLength!R && isSomeChar!(ElementType!R) ||\n    isNarrowString!R)\n{\n    for (auto i = path.length; i-- > 0 && !isSeparator(path[i]); )\n    {\n        if (path[i] == '.' && i > 0 && !isSeparator(path[i-1]))\n            return i;\n    }\n    return -1;\n}\n\n@safe unittest\n{\n    assert(extSeparatorPos(\"file\") == -1);\n    assert(extSeparatorPos(\"file.ext\"w) == 4);\n    assert(extSeparatorPos(\"file.ext1.ext2\"d) == 9);\n    assert(extSeparatorPos(\".foo\".dup) == -1);\n    assert(extSeparatorPos(\".foo.ext\"w.dup) == 4);\n}\n\n@safe unittest\n{\n    assert(extSeparatorPos(\"dir/file\"d.dup) == -1);\n    assert(extSeparatorPos(\"dir/file.ext\") == 8);\n    assert(extSeparatorPos(\"dir/file.ext1.ext2\"w) == 13);\n    assert(extSeparatorPos(\"dir/.foo\"d) == -1);\n    assert(extSeparatorPos(\"dir/.foo.ext\".dup) == 8);\n\n    version (Windows)\n    {\n        assert(extSeparatorPos(\"dir\\\\file\") == -1);\n        assert(extSeparatorPos(\"dir\\\\file.ext\") == 8);\n        assert(extSeparatorPos(\"dir\\\\file.ext1.ext2\") == 13);\n        assert(extSeparatorPos(\"dir\\\\.foo\") == -1);\n        assert(extSeparatorPos(\"dir\\\\.foo.ext\") == 8);\n\n        assert(extSeparatorPos(\"d:file\") == -1);\n        assert(extSeparatorPos(\"d:file.ext\") == 6);\n        assert(extSeparatorPos(\"d:file.ext1.ext2\") == 11);\n        assert(extSeparatorPos(\"d:.foo\") == -1);\n        assert(extSeparatorPos(\"d:.foo.ext\") == 6);\n    }\n\n    static assert(extSeparatorPos(\"file\") == -1);\n    static assert(extSeparatorPos(\"file.ext\"w) == 4);\n}\n\n\n/**\n    Params: path = A path name.\n    Returns: The _extension part of a file name, including the dot.\n\n    If there is no _extension, `null` is returned.\n*/\nauto extension(R)(R path)\nif (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) ||\n    is(StringTypeOf!R))\n{\n    auto i = extSeparatorPos!(BaseOf!R)(path);\n    if (i == -1)\n    {\n        static if (is(StringTypeOf!R))\n            return StringTypeOf!R.init[];   // which is null\n        else\n            return path[0 .. 0];\n    }\n    else return path[i .. path.length];\n}\n\n///\n@safe unittest\n{\n    import std.range : empty;\n    assert(extension(\"file\").empty);\n    assert(extension(\"file.\") == \".\");\n    assert(extension(\"file.ext\"w) == \".ext\");\n    assert(extension(\"file.ext1.ext2\"d) == \".ext2\");\n    assert(extension(\".foo\".dup).empty);\n    assert(extension(\".foo.ext\"w.dup) == \".ext\");\n\n    static assert(extension(\"file\").empty);\n    static assert(extension(\"file.ext\") == \".ext\");\n}\n\n@safe unittest\n{\n    {\n        auto r = MockRange!(immutable(char))(`file.ext1.ext2`);\n        auto s = r.extension();\n        foreach (i, c; `.ext2`)\n            assert(s[i] == c);\n    }\n\n    static struct DirEntry { string s; alias s this; }\n    assert(extension(DirEntry(\"file\")).empty);\n}\n\n\n/** Remove extension from path.\n\n    Params:\n        path = string or range to be sliced\n\n    Returns:\n        slice of path with the extension (if any) stripped off\n*/\nauto stripExtension(R)(R path)\nif (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R)\n{\n    return _stripExtension(path);\n}\n\n/// Ditto\nauto stripExtension(C)(C[] path)\nif (isSomeChar!C)\n{\n    return _stripExtension(path);\n}\n\n///\n@safe unittest\n{\n    assert(stripExtension(\"file\")           == \"file\");\n    assert(stripExtension(\"file.ext\")       == \"file\");\n    assert(stripExtension(\"file.ext1.ext2\") == \"file.ext1\");\n    assert(stripExtension(\"file.\")          == \"file\");\n    assert(stripExtension(\".file\")          == \".file\");\n    assert(stripExtension(\".file.ext\")      == \".file\");\n    assert(stripExtension(\"dir/file.ext\")   == \"dir/file\");\n}\n\n@safe unittest\n{\n    assert(testAliasedString!stripExtension(\"file\"));\n\n    enum S : string { a = \"foo.bar\" }\n    assert(S.a.stripExtension == \"foo\");\n\n    char[S.a.length] sa = S.a[];\n    assert(sa.stripExtension == \"foo\");\n}\n\n@safe unittest\n{\n    assert(stripExtension(\"file.ext\"w) == \"file\");\n    assert(stripExtension(\"file.ext1.ext2\"d) == \"file.ext1\");\n\n    import std.array;\n    import std.utf : byChar, byWchar, byDchar;\n\n    assert(stripExtension(\"file\".byChar).array == \"file\");\n    assert(stripExtension(\"file.ext\"w.byWchar).array == \"file\");\n    assert(stripExtension(\"file.ext1.ext2\"d.byDchar).array == \"file.ext1\");\n}\n\nprivate auto _stripExtension(R)(R path)\n{\n    immutable i = extSeparatorPos(path);\n    return i == -1 ? path : path[0 .. i];\n}\n\n/** Sets or replaces an extension.\n\n    If the filename already has an extension, it is replaced. If not, the\n    extension is simply appended to the filename. Including a leading dot\n    in `ext` is optional.\n\n    If the extension is empty, this function is equivalent to\n    $(LREF stripExtension).\n\n    This function normally allocates a new string (the possible exception\n    being the case when path is immutable and doesn't already have an\n    extension).\n\n    Params:\n        path = A path name\n        ext = The new extension\n\n    Returns: A string containing the path given by `path`, but where\n    the extension has been set to `ext`.\n\n    See_Also:\n        $(LREF withExtension) which does not allocate and returns a lazy range.\n*/\nimmutable(Unqual!C1)[] setExtension(C1, C2)(in C1[] path, in C2[] ext)\nif (isSomeChar!C1 && !is(C1 == immutable) && is(Unqual!C1 == Unqual!C2))\n{\n    try\n    {\n        import std.conv : to;\n        return withExtension(path, ext).to!(typeof(return));\n    }\n    catch (Exception e)\n    {\n        assert(0);\n    }\n}\n\n///ditto\nimmutable(C1)[] setExtension(C1, C2)(immutable(C1)[] path, const(C2)[] ext)\nif (isSomeChar!C1 && is(Unqual!C1 == Unqual!C2))\n{\n    if (ext.length == 0)\n        return stripExtension(path);\n\n    try\n    {\n        import std.conv : to;\n        return withExtension(path, ext).to!(typeof(return));\n    }\n    catch (Exception e)\n    {\n        assert(0);\n    }\n}\n\n///\n@safe unittest\n{\n    assert(setExtension(\"file\", \"ext\") == \"file.ext\");\n    assert(setExtension(\"file\"w, \".ext\"w) == \"file.ext\");\n    assert(setExtension(\"file.\"d, \"ext\"d) == \"file.ext\");\n    assert(setExtension(\"file.\", \".ext\") == \"file.ext\");\n    assert(setExtension(\"file.old\"w, \"new\"w) == \"file.new\");\n    assert(setExtension(\"file.old\"d, \".new\"d) == \"file.new\");\n}\n\n@safe unittest\n{\n    assert(setExtension(\"file\"w.dup, \"ext\"w) == \"file.ext\");\n    assert(setExtension(\"file\"w.dup, \".ext\"w) == \"file.ext\");\n    assert(setExtension(\"file.\"w, \"ext\"w.dup) == \"file.ext\");\n    assert(setExtension(\"file.\"w, \".ext\"w.dup) == \"file.ext\");\n    assert(setExtension(\"file.old\"d.dup, \"new\"d) == \"file.new\");\n    assert(setExtension(\"file.old\"d.dup, \".new\"d) == \"file.new\");\n\n    static assert(setExtension(\"file\", \"ext\") == \"file.ext\");\n    static assert(setExtension(\"file.old\", \"new\") == \"file.new\");\n\n    static assert(setExtension(\"file\"w.dup, \"ext\"w) == \"file.ext\");\n    static assert(setExtension(\"file.old\"d.dup, \"new\"d) == \"file.new\");\n\n    // Issue 10601\n    assert(setExtension(\"file\", \"\") == \"file\");\n    assert(setExtension(\"file.ext\", \"\") == \"file\");\n}\n\n/************\n * Replace existing extension on filespec with new one.\n *\n * Params:\n *      path = string or random access range representing a filespec\n *      ext = the new extension\n * Returns:\n *      Range with `path`'s extension (if any) replaced with `ext`.\n *      The element encoding type of the returned range will be the same as `path`'s.\n * See_Also:\n *      $(LREF setExtension)\n */\nauto withExtension(R, C)(R path, C[] ext)\nif (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) &&\n    !isSomeString!R && isSomeChar!C)\n{\n    return _withExtension(path, ext);\n}\n\n/// Ditto\nauto withExtension(C1, C2)(C1[] path, C2[] ext)\nif (isSomeChar!C1 && isSomeChar!C2)\n{\n    return _withExtension(path, ext);\n}\n\n///\n@safe unittest\n{\n    import std.array;\n    assert(withExtension(\"file\", \"ext\").array == \"file.ext\");\n    assert(withExtension(\"file\"w, \".ext\"w).array == \"file.ext\");\n    assert(withExtension(\"file.ext\"w, \".\").array == \"file.\");\n\n    import std.utf : byChar, byWchar;\n    assert(withExtension(\"file\".byChar, \"ext\").array == \"file.ext\");\n    assert(withExtension(\"file\"w.byWchar, \".ext\"w).array == \"file.ext\"w);\n    assert(withExtension(\"file.ext\"w.byWchar, \".\").array == \"file.\"w);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(testAliasedString!withExtension(\"file\", \"ext\"));\n\n    enum S : string { a = \"foo.bar\" }\n    assert(equal(S.a.withExtension(\".txt\"), \"foo.txt\"));\n\n    char[S.a.length] sa = S.a[];\n    assert(equal(sa.withExtension(\".txt\"), \"foo.txt\"));\n}\n\nprivate auto _withExtension(R, C)(R path, C[] ext)\n{\n    import std.range : only, chain;\n    import std.utf : byUTF;\n\n    alias CR = Unqual!(ElementEncodingType!R);\n    auto dot = only(CR('.'));\n    if (ext.length == 0 || ext[0] == '.')\n        dot.popFront();                 // so dot is an empty range, too\n    return chain(stripExtension(path).byUTF!CR, dot, ext.byUTF!CR);\n}\n\n/** Params:\n        path = A path name.\n        ext = The default extension to use.\n\n    Returns: The path given by `path`, with the extension given by `ext`\n    appended if the path doesn't already have one.\n\n    Including the dot in the extension is optional.\n\n    This function always allocates a new string, except in the case when\n    path is immutable and already has an extension.\n*/\nimmutable(Unqual!C1)[] defaultExtension(C1, C2)(in C1[] path, in C2[] ext)\nif (isSomeChar!C1 && is(Unqual!C1 == Unqual!C2))\n{\n    import std.conv : to;\n    return withDefaultExtension(path, ext).to!(typeof(return));\n}\n\n///\n@safe unittest\n{\n    assert(defaultExtension(\"file\", \"ext\") == \"file.ext\");\n    assert(defaultExtension(\"file\", \".ext\") == \"file.ext\");\n    assert(defaultExtension(\"file.\", \"ext\")     == \"file.\");\n    assert(defaultExtension(\"file.old\", \"new\") == \"file.old\");\n    assert(defaultExtension(\"file.old\", \".new\") == \"file.old\");\n}\n\n@safe unittest\n{\n    assert(defaultExtension(\"file\"w.dup, \"ext\"w) == \"file.ext\");\n    assert(defaultExtension(\"file.old\"d.dup, \"new\"d) == \"file.old\");\n\n    static assert(defaultExtension(\"file\", \"ext\") == \"file.ext\");\n    static assert(defaultExtension(\"file.old\", \"new\") == \"file.old\");\n\n    static assert(defaultExtension(\"file\"w.dup, \"ext\"w) == \"file.ext\");\n    static assert(defaultExtension(\"file.old\"d.dup, \"new\"d) == \"file.old\");\n}\n\n\n/********************************\n * Set the extension of `path` to `ext` if `path` doesn't have one.\n *\n * Params:\n *      path = filespec as string or range\n *      ext = extension, may have leading '.'\n * Returns:\n *      range with the result\n */\nauto withDefaultExtension(R, C)(R path, C[] ext)\nif (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) &&\n    !isSomeString!R && isSomeChar!C)\n{\n    return _withDefaultExtension(path, ext);\n}\n\n/// Ditto\nauto withDefaultExtension(C1, C2)(C1[] path, C2[] ext)\nif (isSomeChar!C1 && isSomeChar!C2)\n{\n    return _withDefaultExtension(path, ext);\n}\n\n///\n@safe unittest\n{\n    import std.array;\n    assert(withDefaultExtension(\"file\", \"ext\").array == \"file.ext\");\n    assert(withDefaultExtension(\"file\"w, \".ext\").array == \"file.ext\"w);\n    assert(withDefaultExtension(\"file.\", \"ext\").array == \"file.\");\n    assert(withDefaultExtension(\"file\", \"\").array == \"file.\");\n\n    import std.utf : byChar, byWchar;\n    assert(withDefaultExtension(\"file\".byChar, \"ext\").array == \"file.ext\");\n    assert(withDefaultExtension(\"file\"w.byWchar, \".ext\").array == \"file.ext\"w);\n    assert(withDefaultExtension(\"file.\".byChar, \"ext\"d).array == \"file.\");\n    assert(withDefaultExtension(\"file\".byChar, \"\").array == \"file.\");\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(testAliasedString!withDefaultExtension(\"file\", \"ext\"));\n\n    enum S : string { a = \"foo\" }\n    assert(equal(S.a.withDefaultExtension(\".txt\"), \"foo.txt\"));\n\n    char[S.a.length] sa = S.a[];\n    assert(equal(sa.withDefaultExtension(\".txt\"), \"foo.txt\"));\n}\n\nprivate auto _withDefaultExtension(R, C)(R path, C[] ext)\n{\n    import std.range : only, chain;\n    import std.utf : byUTF;\n\n    alias CR = Unqual!(ElementEncodingType!R);\n    auto dot = only(CR('.'));\n    immutable i = extSeparatorPos(path);\n    if (i == -1)\n    {\n        if (ext.length > 0 && ext[0] == '.')\n            ext = ext[1 .. $];              // remove any leading . from ext[]\n    }\n    else\n    {\n        // path already has an extension, so make these empty\n        ext = ext[0 .. 0];\n        dot.popFront();\n    }\n    return chain(path.byUTF!CR, dot, ext.byUTF!CR);\n}\n\n/** Combines one or more path segments.\n\n    This function takes a set of path segments, given as an input\n    range of string elements or as a set of string arguments,\n    and concatenates them with each other.  Directory separators\n    are inserted between segments if necessary.  If any of the\n    path segments are absolute (as defined by $(LREF isAbsolute)), the\n    preceding segments will be dropped.\n\n    On Windows, if one of the path segments are rooted, but not absolute\n    (e.g. $(D `\\foo`)), all preceding path segments down to the previous\n    root will be dropped.  (See below for an example.)\n\n    This function always allocates memory to hold the resulting path.\n    The variadic overload is guaranteed to only perform a single\n    allocation, as is the range version if `paths` is a forward\n    range.\n\n    Params:\n        segments = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n        of segments to assemble the path from.\n    Returns: The assembled path.\n*/\nimmutable(ElementEncodingType!(ElementType!Range))[]\n    buildPath(Range)(Range segments)\n    if (isInputRange!Range && !isInfinite!Range && isSomeString!(ElementType!Range))\n{\n    if (segments.empty) return null;\n\n    // If this is a forward range, we can pre-calculate a maximum length.\n    static if (isForwardRange!Range)\n    {\n        auto segments2 = segments.save;\n        size_t precalc = 0;\n        foreach (segment; segments2) precalc += segment.length + 1;\n    }\n    // Otherwise, just venture a guess and resize later if necessary.\n    else size_t precalc = 255;\n\n    auto buf = new Unqual!(ElementEncodingType!(ElementType!Range))[](precalc);\n    size_t pos = 0;\n    foreach (segment; segments)\n    {\n        if (segment.empty) continue;\n        static if (!isForwardRange!Range)\n        {\n            immutable neededLength = pos + segment.length + 1;\n            if (buf.length < neededLength)\n                buf.length = reserve(buf, neededLength + buf.length/2);\n        }\n        auto r = chainPath(buf[0 .. pos], segment);\n        size_t i;\n        foreach (c; r)\n        {\n            buf[i] = c;\n            ++i;\n        }\n        pos = i;\n    }\n    static U trustedCast(U, V)(V v) @trusted pure nothrow { return cast(U) v; }\n    return trustedCast!(typeof(return))(buf[0 .. pos]);\n}\n\n/// ditto\nimmutable(C)[] buildPath(C)(const(C)[][] paths...)\n    @safe pure nothrow\nif (isSomeChar!C)\n{\n    return buildPath!(typeof(paths))(paths);\n}\n\n///\n@safe unittest\n{\n    version (Posix)\n    {\n        assert(buildPath(\"foo\", \"bar\", \"baz\") == \"foo/bar/baz\");\n        assert(buildPath(\"/foo/\", \"bar/baz\")  == \"/foo/bar/baz\");\n        assert(buildPath(\"/foo\", \"/bar\")      == \"/bar\");\n    }\n\n    version (Windows)\n    {\n        assert(buildPath(\"foo\", \"bar\", \"baz\") == `foo\\bar\\baz`);\n        assert(buildPath(`c:\\foo`, `bar\\baz`) == `c:\\foo\\bar\\baz`);\n        assert(buildPath(\"foo\", `d:\\bar`)     == `d:\\bar`);\n        assert(buildPath(\"foo\", `\\bar`)       == `\\bar`);\n        assert(buildPath(`c:\\foo`, `\\bar`)    == `c:\\bar`);\n    }\n}\n\n@system unittest // non-documented\n{\n    import std.range;\n    // ir() wraps an array in a plain (i.e. non-forward) input range, so that\n    // we can test both code paths\n    InputRange!(C[]) ir(C)(C[][] p...) { return inputRangeObject(p); }\n    version (Posix)\n    {\n        assert(buildPath(\"foo\") == \"foo\");\n        assert(buildPath(\"/foo/\") == \"/foo/\");\n        assert(buildPath(\"foo\", \"bar\") == \"foo/bar\");\n        assert(buildPath(\"foo\", \"bar\", \"baz\") == \"foo/bar/baz\");\n        assert(buildPath(\"foo/\".dup, \"bar\") == \"foo/bar\");\n        assert(buildPath(\"foo///\", \"bar\".dup) == \"foo///bar\");\n        assert(buildPath(\"/foo\"w, \"bar\"w) == \"/foo/bar\");\n        assert(buildPath(\"foo\"w.dup, \"/bar\"w) == \"/bar\");\n        assert(buildPath(\"foo\"w, \"bar/\"w.dup) == \"foo/bar/\");\n        assert(buildPath(\"/\"d, \"foo\"d) == \"/foo\");\n        assert(buildPath(\"\"d.dup, \"foo\"d) == \"foo\");\n        assert(buildPath(\"foo\"d, \"\"d.dup) == \"foo\");\n        assert(buildPath(\"foo\", \"bar\".dup, \"baz\") == \"foo/bar/baz\");\n        assert(buildPath(\"foo\"w, \"/bar\"w, \"baz\"w.dup) == \"/bar/baz\");\n\n        static assert(buildPath(\"foo\", \"bar\", \"baz\") == \"foo/bar/baz\");\n        static assert(buildPath(\"foo\", \"/bar\", \"baz\") == \"/bar/baz\");\n\n        // The following are mostly duplicates of the above, except that the\n        // range version does not accept mixed constness.\n        assert(buildPath(ir(\"foo\")) == \"foo\");\n        assert(buildPath(ir(\"/foo/\")) == \"/foo/\");\n        assert(buildPath(ir(\"foo\", \"bar\")) == \"foo/bar\");\n        assert(buildPath(ir(\"foo\", \"bar\", \"baz\")) == \"foo/bar/baz\");\n        assert(buildPath(ir(\"foo/\".dup, \"bar\".dup)) == \"foo/bar\");\n        assert(buildPath(ir(\"foo///\".dup, \"bar\".dup)) == \"foo///bar\");\n        assert(buildPath(ir(\"/foo\"w, \"bar\"w)) == \"/foo/bar\");\n        assert(buildPath(ir(\"foo\"w.dup, \"/bar\"w.dup)) == \"/bar\");\n        assert(buildPath(ir(\"foo\"w.dup, \"bar/\"w.dup)) == \"foo/bar/\");\n        assert(buildPath(ir(\"/\"d, \"foo\"d)) == \"/foo\");\n        assert(buildPath(ir(\"\"d.dup, \"foo\"d.dup)) == \"foo\");\n        assert(buildPath(ir(\"foo\"d, \"\"d)) == \"foo\");\n        assert(buildPath(ir(\"foo\", \"bar\", \"baz\")) == \"foo/bar/baz\");\n        assert(buildPath(ir(\"foo\"w.dup, \"/bar\"w.dup, \"baz\"w.dup)) == \"/bar/baz\");\n    }\n    version (Windows)\n    {\n        assert(buildPath(\"foo\") == \"foo\");\n        assert(buildPath(`\\foo/`) == `\\foo/`);\n        assert(buildPath(\"foo\", \"bar\", \"baz\") == `foo\\bar\\baz`);\n        assert(buildPath(\"foo\", `\\bar`) == `\\bar`);\n        assert(buildPath(`c:\\foo`, \"bar\") == `c:\\foo\\bar`);\n        assert(buildPath(\"foo\"w, `d:\\bar`w.dup) ==  `d:\\bar`);\n        assert(buildPath(`c:\\foo\\bar`, `\\baz`) == `c:\\baz`);\n        assert(buildPath(`\\\\foo\\bar\\baz`d, `foo`d, `\\bar`d) == `\\\\foo\\bar\\bar`d);\n\n        static assert(buildPath(\"foo\", \"bar\", \"baz\") == `foo\\bar\\baz`);\n        static assert(buildPath(\"foo\", `c:\\bar`, \"baz\") == `c:\\bar\\baz`);\n\n        assert(buildPath(ir(\"foo\")) == \"foo\");\n        assert(buildPath(ir(`\\foo/`)) == `\\foo/`);\n        assert(buildPath(ir(\"foo\", \"bar\", \"baz\")) == `foo\\bar\\baz`);\n        assert(buildPath(ir(\"foo\", `\\bar`)) == `\\bar`);\n        assert(buildPath(ir(`c:\\foo`, \"bar\")) == `c:\\foo\\bar`);\n        assert(buildPath(ir(\"foo\"w.dup, `d:\\bar`w.dup)) ==  `d:\\bar`);\n        assert(buildPath(ir(`c:\\foo\\bar`, `\\baz`)) == `c:\\baz`);\n        assert(buildPath(ir(`\\\\foo\\bar\\baz`d, `foo`d, `\\bar`d)) == `\\\\foo\\bar\\bar`d);\n    }\n\n    // Test that allocation works as it should.\n    auto manyShort = \"aaa\".repeat(1000).array();\n    auto manyShortCombined = join(manyShort, dirSeparator);\n    assert(buildPath(manyShort) == manyShortCombined);\n    assert(buildPath(ir(manyShort)) == manyShortCombined);\n\n    auto fewLong = 'b'.repeat(500).array().repeat(10).array();\n    auto fewLongCombined = join(fewLong, dirSeparator);\n    assert(buildPath(fewLong) == fewLongCombined);\n    assert(buildPath(ir(fewLong)) == fewLongCombined);\n}\n\n@safe unittest\n{\n    // Test for issue 7397\n    string[] ary = [\"a\", \"b\"];\n    version (Posix)\n    {\n        assert(buildPath(ary) == \"a/b\");\n    }\n    else version (Windows)\n    {\n        assert(buildPath(ary) == `a\\b`);\n    }\n}\n\n\n/**\n * Concatenate path segments together to form one path.\n *\n * Params:\n *      r1 = first segment\n *      r2 = second segment\n *      ranges = 0 or more segments\n * Returns:\n *      Lazy range which is the concatenation of r1, r2 and ranges with path separators.\n *      The resulting element type is that of r1.\n * See_Also:\n *      $(LREF buildPath)\n */\nauto chainPath(R1, R2, Ranges...)(R1 r1, R2 r2, Ranges ranges)\nif ((isRandomAccessRange!R1 && hasSlicing!R1 && hasLength!R1 && isSomeChar!(ElementType!R1) ||\n    isNarrowString!R1 &&\n    !isConvertibleToString!R1) &&\n    (isRandomAccessRange!R2 && hasSlicing!R2 && hasLength!R2 && isSomeChar!(ElementType!R2) ||\n    isNarrowString!R2 &&\n    !isConvertibleToString!R2) &&\n    (Ranges.length == 0 || is(typeof(chainPath(r2, ranges))))\n    )\n{\n    static if (Ranges.length)\n    {\n        return chainPath(chainPath(r1, r2), ranges);\n    }\n    else\n    {\n        import std.range : only, chain;\n        import std.utf : byUTF;\n\n        alias CR = Unqual!(ElementEncodingType!R1);\n        auto sep = only(CR(dirSeparator[0]));\n        bool usesep = false;\n\n        auto pos = r1.length;\n\n        if (pos)\n        {\n            if (isRooted(r2))\n            {\n                version (Posix)\n                {\n                    pos = 0;\n                }\n                else version (Windows)\n                {\n                    if (isAbsolute(r2))\n                        pos = 0;\n                    else\n                    {\n                        pos = rootName(r1).length;\n                        if (pos > 0 && isDirSeparator(r1[pos - 1]))\n                            --pos;\n                    }\n                }\n                else\n                    static assert(0);\n            }\n            else if (!isDirSeparator(r1[pos - 1]))\n                usesep = true;\n        }\n        if (!usesep)\n            sep.popFront();\n        // Return r1 ~ '/' ~ r2\n        return chain(r1[0 .. pos].byUTF!CR, sep, r2.byUTF!CR);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.array;\n    version (Posix)\n    {\n        assert(chainPath(\"foo\", \"bar\", \"baz\").array == \"foo/bar/baz\");\n        assert(chainPath(\"/foo/\", \"bar/baz\").array  == \"/foo/bar/baz\");\n        assert(chainPath(\"/foo\", \"/bar\").array      == \"/bar\");\n    }\n\n    version (Windows)\n    {\n        assert(chainPath(\"foo\", \"bar\", \"baz\").array == `foo\\bar\\baz`);\n        assert(chainPath(`c:\\foo`, `bar\\baz`).array == `c:\\foo\\bar\\baz`);\n        assert(chainPath(\"foo\", `d:\\bar`).array     == `d:\\bar`);\n        assert(chainPath(\"foo\", `\\bar`).array       == `\\bar`);\n        assert(chainPath(`c:\\foo`, `\\bar`).array    == `c:\\bar`);\n    }\n\n    import std.utf : byChar;\n    version (Posix)\n    {\n        assert(chainPath(\"foo\", \"bar\", \"baz\").array == \"foo/bar/baz\");\n        assert(chainPath(\"/foo/\".byChar, \"bar/baz\").array  == \"/foo/bar/baz\");\n        assert(chainPath(\"/foo\", \"/bar\".byChar).array      == \"/bar\");\n    }\n\n    version (Windows)\n    {\n        assert(chainPath(\"foo\", \"bar\", \"baz\").array == `foo\\bar\\baz`);\n        assert(chainPath(`c:\\foo`.byChar, `bar\\baz`).array == `c:\\foo\\bar\\baz`);\n        assert(chainPath(\"foo\", `d:\\bar`).array     == `d:\\bar`);\n        assert(chainPath(\"foo\", `\\bar`.byChar).array       == `\\bar`);\n        assert(chainPath(`c:\\foo`, `\\bar`w).array    == `c:\\bar`);\n    }\n}\n\nauto chainPath(Ranges...)(auto ref Ranges ranges)\nif (Ranges.length >= 2 &&\n    std.meta.anySatisfy!(isConvertibleToString, Ranges))\n{\n    import std.meta : staticMap;\n    alias Types = staticMap!(convertToString, Ranges);\n    return chainPath!Types(ranges);\n}\n\n@safe unittest\n{\n    assert(chainPath(TestAliasedString(null), TestAliasedString(null), TestAliasedString(null)).empty);\n    assert(chainPath(TestAliasedString(null), TestAliasedString(null), \"\").empty);\n    assert(chainPath(TestAliasedString(null), \"\", TestAliasedString(null)).empty);\n    static struct S { string s; }\n    static assert(!__traits(compiles, chainPath(TestAliasedString(null), S(\"\"), TestAliasedString(null))));\n}\n\n/** Performs the same task as $(LREF buildPath),\n    while at the same time resolving current/parent directory\n    symbols (`\".\"` and `\"..\"`) and removing superfluous\n    directory separators.\n    It will return \".\" if the path leads to the starting directory.\n    On Windows, slashes are replaced with backslashes.\n\n    Using buildNormalizedPath on null paths will always return null.\n\n    Note that this function does not resolve symbolic links.\n\n    This function always allocates memory to hold the resulting path.\n    Use $(LREF asNormalizedPath) to not allocate memory.\n\n    Params:\n        paths = An array of paths to assemble.\n\n    Returns: The assembled path.\n*/\nimmutable(C)[] buildNormalizedPath(C)(const(C[])[] paths...)\n    @safe pure nothrow\nif (isSomeChar!C)\n{\n    import std.array : array;\n    import std.exception : assumeUnique;\n\n    const(C)[] chained;\n    foreach (path; paths)\n    {\n        if (chained)\n            chained = chainPath(chained, path).array;\n        else\n            chained = path;\n    }\n    auto result = asNormalizedPath(chained);\n    // .array returns a copy, so it is unique\n    return () @trusted { return assumeUnique(result.array); } ();\n}\n\n///\n@safe unittest\n{\n    assert(buildNormalizedPath(\"foo\", \"..\") == \".\");\n\n    version (Posix)\n    {\n        assert(buildNormalizedPath(\"/foo/./bar/..//baz/\") == \"/foo/baz\");\n        assert(buildNormalizedPath(\"../foo/.\") == \"../foo\");\n        assert(buildNormalizedPath(\"/foo\", \"bar/baz/\") == \"/foo/bar/baz\");\n        assert(buildNormalizedPath(\"/foo\", \"/bar/..\", \"baz\") == \"/baz\");\n        assert(buildNormalizedPath(\"foo/./bar\", \"../../\", \"../baz\") == \"../baz\");\n        assert(buildNormalizedPath(\"/foo/./bar\", \"../../baz\") == \"/baz\");\n    }\n\n    version (Windows)\n    {\n        assert(buildNormalizedPath(`c:\\foo\\.\\bar/..\\\\baz\\`) == `c:\\foo\\baz`);\n        assert(buildNormalizedPath(`..\\foo\\.`) == `..\\foo`);\n        assert(buildNormalizedPath(`c:\\foo`, `bar\\baz\\`) == `c:\\foo\\bar\\baz`);\n        assert(buildNormalizedPath(`c:\\foo`, `bar/..`) == `c:\\foo`);\n        assert(buildNormalizedPath(`\\\\server\\share\\foo`, `..\\bar`) ==\n                `\\\\server\\share\\bar`);\n    }\n}\n\n@safe unittest\n{\n    assert(buildNormalizedPath(\".\", \".\") == \".\");\n    assert(buildNormalizedPath(\"foo\", \"..\") == \".\");\n    assert(buildNormalizedPath(\"\", \"\") is null);\n    assert(buildNormalizedPath(\"\", \".\") == \".\");\n    assert(buildNormalizedPath(\".\", \"\") == \".\");\n    assert(buildNormalizedPath(null, \"foo\") == \"foo\");\n    assert(buildNormalizedPath(\"\", \"foo\") == \"foo\");\n    assert(buildNormalizedPath(\"\", \"\") == \"\");\n    assert(buildNormalizedPath(\"\", null) == \"\");\n    assert(buildNormalizedPath(null, \"\") == \"\");\n    assert(buildNormalizedPath!(char)(null, null) == \"\");\n\n    version (Posix)\n    {\n        assert(buildNormalizedPath(\"/\", \"foo\", \"bar\") == \"/foo/bar\");\n        assert(buildNormalizedPath(\"foo\", \"bar\", \"baz\") == \"foo/bar/baz\");\n        assert(buildNormalizedPath(\"foo\", \"bar/baz\") == \"foo/bar/baz\");\n        assert(buildNormalizedPath(\"foo\", \"bar//baz///\") == \"foo/bar/baz\");\n        assert(buildNormalizedPath(\"/foo\", \"bar/baz\") == \"/foo/bar/baz\");\n        assert(buildNormalizedPath(\"/foo\", \"/bar/baz\") == \"/bar/baz\");\n        assert(buildNormalizedPath(\"/foo/..\", \"/bar/./baz\") == \"/bar/baz\");\n        assert(buildNormalizedPath(\"/foo/..\", \"bar/baz\") == \"/bar/baz\");\n        assert(buildNormalizedPath(\"/foo/../../\", \"bar/baz\") == \"/bar/baz\");\n        assert(buildNormalizedPath(\"/foo/bar\", \"../baz\") == \"/foo/baz\");\n        assert(buildNormalizedPath(\"/foo/bar\", \"../../baz\") == \"/baz\");\n        assert(buildNormalizedPath(\"/foo/bar\", \".././/baz/..\", \"wee/\") == \"/foo/wee\");\n        assert(buildNormalizedPath(\"//foo/bar\", \"baz///wee\") == \"/foo/bar/baz/wee\");\n        static assert(buildNormalizedPath(\"/foo/..\", \"/bar/./baz\") == \"/bar/baz\");\n    }\n    else version (Windows)\n    {\n        assert(buildNormalizedPath(`\\`, `foo`, `bar`) == `\\foo\\bar`);\n        assert(buildNormalizedPath(`foo`, `bar`, `baz`) == `foo\\bar\\baz`);\n        assert(buildNormalizedPath(`foo`, `bar\\baz`) == `foo\\bar\\baz`);\n        assert(buildNormalizedPath(`foo`, `bar\\\\baz\\\\\\`) == `foo\\bar\\baz`);\n        assert(buildNormalizedPath(`\\foo`, `bar\\baz`) == `\\foo\\bar\\baz`);\n        assert(buildNormalizedPath(`\\foo`, `\\bar\\baz`) == `\\bar\\baz`);\n        assert(buildNormalizedPath(`\\foo\\..`, `\\bar\\.\\baz`) == `\\bar\\baz`);\n        assert(buildNormalizedPath(`\\foo\\..`, `bar\\baz`) == `\\bar\\baz`);\n        assert(buildNormalizedPath(`\\foo\\..\\..\\`, `bar\\baz`) == `\\bar\\baz`);\n        assert(buildNormalizedPath(`\\foo\\bar`, `..\\baz`) == `\\foo\\baz`);\n        assert(buildNormalizedPath(`\\foo\\bar`, `../../baz`) == `\\baz`);\n        assert(buildNormalizedPath(`\\foo\\bar`, `..\\.\\/baz\\..`, `wee\\`) == `\\foo\\wee`);\n\n        assert(buildNormalizedPath(`c:\\`, `foo`, `bar`) == `c:\\foo\\bar`);\n        assert(buildNormalizedPath(`c:foo`, `bar`, `baz`) == `c:foo\\bar\\baz`);\n        assert(buildNormalizedPath(`c:foo`, `bar\\baz`) == `c:foo\\bar\\baz`);\n        assert(buildNormalizedPath(`c:foo`, `bar\\\\baz\\\\\\`) == `c:foo\\bar\\baz`);\n        assert(buildNormalizedPath(`c:\\foo`, `bar\\baz`) == `c:\\foo\\bar\\baz`);\n        assert(buildNormalizedPath(`c:\\foo`, `\\bar\\baz`) == `c:\\bar\\baz`);\n        assert(buildNormalizedPath(`c:\\foo\\..`, `\\bar\\.\\baz`) == `c:\\bar\\baz`);\n        assert(buildNormalizedPath(`c:\\foo\\..`, `bar\\baz`) == `c:\\bar\\baz`);\n        assert(buildNormalizedPath(`c:\\foo\\..\\..\\`, `bar\\baz`) == `c:\\bar\\baz`);\n        assert(buildNormalizedPath(`c:\\foo\\bar`, `..\\baz`) == `c:\\foo\\baz`);\n        assert(buildNormalizedPath(`c:\\foo\\bar`, `..\\..\\baz`) == `c:\\baz`);\n        assert(buildNormalizedPath(`c:\\foo\\bar`, `..\\.\\\\baz\\..`, `wee\\`) == `c:\\foo\\wee`);\n\n        assert(buildNormalizedPath(`\\\\server\\share`, `foo`, `bar`) == `\\\\server\\share\\foo\\bar`);\n        assert(buildNormalizedPath(`\\\\server\\share\\`, `foo`, `bar`) == `\\\\server\\share\\foo\\bar`);\n        assert(buildNormalizedPath(`\\\\server\\share\\foo`, `bar\\baz`) == `\\\\server\\share\\foo\\bar\\baz`);\n        assert(buildNormalizedPath(`\\\\server\\share\\foo`, `\\bar\\baz`) == `\\\\server\\share\\bar\\baz`);\n        assert(buildNormalizedPath(`\\\\server\\share\\foo\\..`, `\\bar\\.\\baz`) == `\\\\server\\share\\bar\\baz`);\n        assert(buildNormalizedPath(`\\\\server\\share\\foo\\..`, `bar\\baz`) == `\\\\server\\share\\bar\\baz`);\n        assert(buildNormalizedPath(`\\\\server\\share\\foo\\..\\..\\`, `bar\\baz`) == `\\\\server\\share\\bar\\baz`);\n        assert(buildNormalizedPath(`\\\\server\\share\\foo\\bar`, `..\\baz`) == `\\\\server\\share\\foo\\baz`);\n        assert(buildNormalizedPath(`\\\\server\\share\\foo\\bar`, `..\\..\\baz`) == `\\\\server\\share\\baz`);\n        assert(buildNormalizedPath(`\\\\server\\share\\foo\\bar`, `..\\.\\\\baz\\..`, `wee\\`) == `\\\\server\\share\\foo\\wee`);\n\n        static assert(buildNormalizedPath(`\\foo\\..\\..\\`, `bar\\baz`) == `\\bar\\baz`);\n    }\n    else static assert(0);\n}\n\n@safe unittest\n{\n    // Test for issue 7397\n    string[] ary = [\"a\", \"b\"];\n    version (Posix)\n    {\n        assert(buildNormalizedPath(ary) == \"a/b\");\n    }\n    else version (Windows)\n    {\n        assert(buildNormalizedPath(ary) == `a\\b`);\n    }\n}\n\n\n/** Normalize a path by resolving current/parent directory\n    symbols (`\".\"` and `\"..\"`) and removing superfluous\n    directory separators.\n    It will return \".\" if the path leads to the starting directory.\n    On Windows, slashes are replaced with backslashes.\n\n    Using asNormalizedPath on empty paths will always return an empty path.\n\n    Does not resolve symbolic links.\n\n    This function always allocates memory to hold the resulting path.\n    Use $(LREF buildNormalizedPath) to allocate memory and return a string.\n\n    Params:\n        path = string or random access range representing the path to normalize\n\n    Returns:\n        normalized path as a forward range\n*/\n\nauto asNormalizedPath(R)(R path)\nif (isSomeChar!(ElementEncodingType!R) &&\n    (isRandomAccessRange!R && hasSlicing!R && hasLength!R || isNarrowString!R) &&\n    !isConvertibleToString!R)\n{\n    alias C = Unqual!(ElementEncodingType!R);\n    alias S = typeof(path[0 .. 0]);\n\n    static struct Result\n    {\n        @property bool empty()\n        {\n            return c == c.init;\n        }\n\n        @property C front()\n        {\n            return c;\n        }\n\n        void popFront()\n        {\n            C lastc = c;\n            c = c.init;\n            if (!element.empty)\n            {\n                c = getElement0();\n                return;\n            }\n          L1:\n            while (1)\n            {\n                if (elements.empty)\n                {\n                    element = element[0 .. 0];\n                    return;\n                }\n                element = elements.front;\n                elements.popFront();\n                if (isDot(element) || (rooted && isDotDot(element)))\n                    continue;\n\n                if (rooted || !isDotDot(element))\n                {\n                    int n = 1;\n                    auto elements2 = elements.save;\n                    while (!elements2.empty)\n                    {\n                        auto e = elements2.front;\n                        elements2.popFront();\n                        if (isDot(e))\n                            continue;\n                        if (isDotDot(e))\n                        {\n                            --n;\n                            if (n == 0)\n                            {\n                                elements = elements2;\n                                element = element[0 .. 0];\n                                continue L1;\n                            }\n                        }\n                        else\n                            ++n;\n                    }\n                }\n                break;\n            }\n\n            static assert(dirSeparator.length == 1);\n            if (lastc == dirSeparator[0] || lastc == lastc.init)\n                c = getElement0();\n            else\n                c = dirSeparator[0];\n        }\n\n        static if (isForwardRange!R)\n        {\n            @property auto save()\n            {\n                auto result = this;\n                result.element = element.save;\n                result.elements = elements.save;\n                return result;\n            }\n        }\n\n      private:\n        this(R path)\n        {\n            element = rootName(path);\n            auto i = element.length;\n            while (i < path.length && isDirSeparator(path[i]))\n                ++i;\n            rooted = i > 0;\n            elements = pathSplitter(path[i .. $]);\n            popFront();\n            if (c == c.init && path.length)\n                c = C('.');\n        }\n\n        C getElement0()\n        {\n            static if (isNarrowString!S)  // avoid autodecode\n            {\n                C c = element[0];\n                element = element[1 .. $];\n            }\n            else\n            {\n                C c = element.front;\n                element.popFront();\n            }\n            version (Windows)\n            {\n                if (c == '/')   // can appear in root element\n                    c = '\\\\';   // use native Windows directory separator\n            }\n            return c;\n        }\n\n        // See if elem is \".\"\n        static bool isDot(S elem)\n        {\n            return elem.length == 1 && elem[0] == '.';\n        }\n\n        // See if elem is \"..\"\n        static bool isDotDot(S elem)\n        {\n            return elem.length == 2 && elem[0] == '.' && elem[1] == '.';\n        }\n\n        bool rooted;    // the path starts with a root directory\n        C c;\n        S element;\n        typeof(pathSplitter(path[0 .. 0])) elements;\n    }\n\n    return Result(path);\n}\n\n///\n@safe unittest\n{\n    import std.array;\n    assert(asNormalizedPath(\"foo/..\").array == \".\");\n\n    version (Posix)\n    {\n        assert(asNormalizedPath(\"/foo/./bar/..//baz/\").array == \"/foo/baz\");\n        assert(asNormalizedPath(\"../foo/.\").array == \"../foo\");\n        assert(asNormalizedPath(\"/foo/bar/baz/\").array == \"/foo/bar/baz\");\n        assert(asNormalizedPath(\"/foo/./bar/../../baz\").array == \"/baz\");\n    }\n\n    version (Windows)\n    {\n        assert(asNormalizedPath(`c:\\foo\\.\\bar/..\\\\baz\\`).array == `c:\\foo\\baz`);\n        assert(asNormalizedPath(`..\\foo\\.`).array == `..\\foo`);\n        assert(asNormalizedPath(`c:\\foo\\bar\\baz\\`).array == `c:\\foo\\bar\\baz`);\n        assert(asNormalizedPath(`c:\\foo\\bar/..`).array == `c:\\foo`);\n        assert(asNormalizedPath(`\\\\server\\share\\foo\\..\\bar`).array ==\n                `\\\\server\\share\\bar`);\n    }\n}\n\nauto asNormalizedPath(R)(auto ref R path)\nif (isConvertibleToString!R)\n{\n    return asNormalizedPath!(StringTypeOf!R)(path);\n}\n\n@safe unittest\n{\n    assert(testAliasedString!asNormalizedPath(null));\n}\n\n@safe unittest\n{\n    import std.array;\n    import std.utf : byChar;\n\n    assert(asNormalizedPath(\"\").array is null);\n    assert(asNormalizedPath(\"foo\").array == \"foo\");\n    assert(asNormalizedPath(\".\").array == \".\");\n    assert(asNormalizedPath(\"./.\").array == \".\");\n    assert(asNormalizedPath(\"foo/..\").array == \".\");\n\n    auto save = asNormalizedPath(\"fob\").save;\n    save.popFront();\n    assert(save.front == 'o');\n\n    version (Posix)\n    {\n        assert(asNormalizedPath(\"/foo/bar\").array == \"/foo/bar\");\n        assert(asNormalizedPath(\"foo/bar/baz\").array == \"foo/bar/baz\");\n        assert(asNormalizedPath(\"foo/bar/baz\").array == \"foo/bar/baz\");\n        assert(asNormalizedPath(\"foo/bar//baz///\").array == \"foo/bar/baz\");\n        assert(asNormalizedPath(\"/foo/bar/baz\").array == \"/foo/bar/baz\");\n        assert(asNormalizedPath(\"/foo/../bar/baz\").array == \"/bar/baz\");\n        assert(asNormalizedPath(\"/foo/../..//bar/baz\").array == \"/bar/baz\");\n        assert(asNormalizedPath(\"/foo/bar/../baz\").array == \"/foo/baz\");\n        assert(asNormalizedPath(\"/foo/bar/../../baz\").array == \"/baz\");\n        assert(asNormalizedPath(\"/foo/bar/.././/baz/../wee/\").array == \"/foo/wee\");\n        assert(asNormalizedPath(\"//foo/bar/baz///wee\").array == \"/foo/bar/baz/wee\");\n\n        assert(asNormalizedPath(\"foo//bar\").array == \"foo/bar\");\n        assert(asNormalizedPath(\"foo/bar\").array == \"foo/bar\");\n\n        //Curent dir path\n        assert(asNormalizedPath(\"./\").array == \".\");\n        assert(asNormalizedPath(\"././\").array == \".\");\n        assert(asNormalizedPath(\"./foo/..\").array == \".\");\n        assert(asNormalizedPath(\"foo/..\").array == \".\");\n    }\n    else version (Windows)\n    {\n        assert(asNormalizedPath(`\\foo\\bar`).array == `\\foo\\bar`);\n        assert(asNormalizedPath(`foo\\bar\\baz`).array == `foo\\bar\\baz`);\n        assert(asNormalizedPath(`foo\\bar\\baz`).array == `foo\\bar\\baz`);\n        assert(asNormalizedPath(`foo\\bar\\\\baz\\\\\\`).array == `foo\\bar\\baz`);\n        assert(asNormalizedPath(`\\foo\\bar\\baz`).array == `\\foo\\bar\\baz`);\n        assert(asNormalizedPath(`\\foo\\..\\\\bar\\.\\baz`).array == `\\bar\\baz`);\n        assert(asNormalizedPath(`\\foo\\..\\bar\\baz`).array == `\\bar\\baz`);\n        assert(asNormalizedPath(`\\foo\\..\\..\\\\bar\\baz`).array == `\\bar\\baz`);\n\n        assert(asNormalizedPath(`\\foo\\bar\\..\\baz`).array == `\\foo\\baz`);\n        assert(asNormalizedPath(`\\foo\\bar\\../../baz`).array == `\\baz`);\n        assert(asNormalizedPath(`\\foo\\bar\\..\\.\\/baz\\..\\wee\\`).array == `\\foo\\wee`);\n\n        assert(asNormalizedPath(`c:\\foo\\bar`).array == `c:\\foo\\bar`);\n        assert(asNormalizedPath(`c:foo\\bar\\baz`).array == `c:foo\\bar\\baz`);\n        assert(asNormalizedPath(`c:foo\\bar\\baz`).array == `c:foo\\bar\\baz`);\n        assert(asNormalizedPath(`c:foo\\bar\\\\baz\\\\\\`).array == `c:foo\\bar\\baz`);\n        assert(asNormalizedPath(`c:\\foo\\bar\\baz`).array == `c:\\foo\\bar\\baz`);\n\n        assert(asNormalizedPath(`c:\\foo\\..\\\\bar\\.\\baz`).array == `c:\\bar\\baz`);\n        assert(asNormalizedPath(`c:\\foo\\..\\bar\\baz`).array == `c:\\bar\\baz`);\n        assert(asNormalizedPath(`c:\\foo\\..\\..\\\\bar\\baz`).array == `c:\\bar\\baz`);\n        assert(asNormalizedPath(`c:\\foo\\bar\\..\\baz`).array == `c:\\foo\\baz`);\n        assert(asNormalizedPath(`c:\\foo\\bar\\..\\..\\baz`).array == `c:\\baz`);\n        assert(asNormalizedPath(`c:\\foo\\bar\\..\\.\\\\baz\\..\\wee\\`).array == `c:\\foo\\wee`);\n        assert(asNormalizedPath(`\\\\server\\share\\foo\\bar`).array == `\\\\server\\share\\foo\\bar`);\n        assert(asNormalizedPath(`\\\\server\\share\\\\foo\\bar`).array == `\\\\server\\share\\foo\\bar`);\n        assert(asNormalizedPath(`\\\\server\\share\\foo\\bar\\baz`).array == `\\\\server\\share\\foo\\bar\\baz`);\n        assert(asNormalizedPath(`\\\\server\\share\\foo\\..\\\\bar\\.\\baz`).array == `\\\\server\\share\\bar\\baz`);\n        assert(asNormalizedPath(`\\\\server\\share\\foo\\..\\bar\\baz`).array == `\\\\server\\share\\bar\\baz`);\n        assert(asNormalizedPath(`\\\\server\\share\\foo\\..\\..\\\\bar\\baz`).array == `\\\\server\\share\\bar\\baz`);\n        assert(asNormalizedPath(`\\\\server\\share\\foo\\bar\\..\\baz`).array == `\\\\server\\share\\foo\\baz`);\n        assert(asNormalizedPath(`\\\\server\\share\\foo\\bar\\..\\..\\baz`).array == `\\\\server\\share\\baz`);\n        assert(asNormalizedPath(`\\\\server\\share\\foo\\bar\\..\\.\\\\baz\\..\\wee\\`).array == `\\\\server\\share\\foo\\wee`);\n\n        static assert(asNormalizedPath(`\\foo\\..\\..\\\\bar\\baz`).array == `\\bar\\baz`);\n\n        assert(asNormalizedPath(\"foo//bar\").array == `foo\\bar`);\n\n        //Curent dir path\n        assert(asNormalizedPath(`.\\`).array == \".\");\n        assert(asNormalizedPath(`.\\.\\`).array == \".\");\n        assert(asNormalizedPath(`.\\foo\\..`).array == \".\");\n        assert(asNormalizedPath(`foo\\..`).array == \".\");\n    }\n    else static assert(0);\n}\n\n@safe unittest\n{\n    import std.array;\n\n    version (Posix)\n    {\n        // Trivial\n        assert(asNormalizedPath(\"\").empty);\n        assert(asNormalizedPath(\"foo/bar\").array == \"foo/bar\");\n\n        // Correct handling of leading slashes\n        assert(asNormalizedPath(\"/\").array == \"/\");\n        assert(asNormalizedPath(\"///\").array == \"/\");\n        assert(asNormalizedPath(\"////\").array == \"/\");\n        assert(asNormalizedPath(\"/foo/bar\").array == \"/foo/bar\");\n        assert(asNormalizedPath(\"//foo/bar\").array == \"/foo/bar\");\n        assert(asNormalizedPath(\"///foo/bar\").array == \"/foo/bar\");\n        assert(asNormalizedPath(\"////foo/bar\").array == \"/foo/bar\");\n\n        // Correct handling of single-dot symbol (current directory)\n        assert(asNormalizedPath(\"/./foo\").array == \"/foo\");\n        assert(asNormalizedPath(\"/foo/./bar\").array == \"/foo/bar\");\n\n        assert(asNormalizedPath(\"./foo\").array == \"foo\");\n        assert(asNormalizedPath(\"././foo\").array == \"foo\");\n        assert(asNormalizedPath(\"foo/././bar\").array == \"foo/bar\");\n\n        // Correct handling of double-dot symbol (previous directory)\n        assert(asNormalizedPath(\"/foo/../bar\").array == \"/bar\");\n        assert(asNormalizedPath(\"/foo/../../bar\").array == \"/bar\");\n        assert(asNormalizedPath(\"/../foo\").array == \"/foo\");\n        assert(asNormalizedPath(\"/../../foo\").array == \"/foo\");\n        assert(asNormalizedPath(\"/foo/..\").array == \"/\");\n        assert(asNormalizedPath(\"/foo/../..\").array == \"/\");\n\n        assert(asNormalizedPath(\"foo/../bar\").array == \"bar\");\n        assert(asNormalizedPath(\"foo/../../bar\").array == \"../bar\");\n        assert(asNormalizedPath(\"../foo\").array == \"../foo\");\n        assert(asNormalizedPath(\"../../foo\").array == \"../../foo\");\n        assert(asNormalizedPath(\"../foo/../bar\").array == \"../bar\");\n        assert(asNormalizedPath(\".././../foo\").array == \"../../foo\");\n        assert(asNormalizedPath(\"foo/bar/..\").array == \"foo\");\n        assert(asNormalizedPath(\"/foo/../..\").array == \"/\");\n\n        // The ultimate path\n        assert(asNormalizedPath(\"/foo/../bar//./../...///baz//\").array == \"/.../baz\");\n        static assert(asNormalizedPath(\"/foo/../bar//./../...///baz//\").array == \"/.../baz\");\n    }\n    else version (Windows)\n    {\n        // Trivial\n        assert(asNormalizedPath(\"\").empty);\n        assert(asNormalizedPath(`foo\\bar`).array == `foo\\bar`);\n        assert(asNormalizedPath(\"foo/bar\").array == `foo\\bar`);\n\n        // Correct handling of absolute paths\n        assert(asNormalizedPath(\"/\").array == `\\`);\n        assert(asNormalizedPath(`\\`).array == `\\`);\n        assert(asNormalizedPath(`\\\\\\`).array == `\\`);\n        assert(asNormalizedPath(`\\\\\\\\`).array == `\\`);\n        assert(asNormalizedPath(`\\foo\\bar`).array == `\\foo\\bar`);\n        assert(asNormalizedPath(`\\\\foo`).array == `\\\\foo`);\n        assert(asNormalizedPath(`\\\\foo\\\\`).array == `\\\\foo`);\n        assert(asNormalizedPath(`\\\\foo/bar`).array == `\\\\foo\\bar`);\n        assert(asNormalizedPath(`\\\\\\foo\\bar`).array == `\\foo\\bar`);\n        assert(asNormalizedPath(`\\\\\\\\foo\\bar`).array == `\\foo\\bar`);\n        assert(asNormalizedPath(`c:\\`).array == `c:\\`);\n        assert(asNormalizedPath(`c:\\foo\\bar`).array == `c:\\foo\\bar`);\n        assert(asNormalizedPath(`c:\\\\foo\\bar`).array == `c:\\foo\\bar`);\n\n        // Correct handling of single-dot symbol (current directory)\n        assert(asNormalizedPath(`\\./foo`).array == `\\foo`);\n        assert(asNormalizedPath(`\\foo/.\\bar`).array == `\\foo\\bar`);\n\n        assert(asNormalizedPath(`.\\foo`).array == `foo`);\n        assert(asNormalizedPath(`./.\\foo`).array == `foo`);\n        assert(asNormalizedPath(`foo\\.\\./bar`).array == `foo\\bar`);\n\n        // Correct handling of double-dot symbol (previous directory)\n        assert(asNormalizedPath(`\\foo\\..\\bar`).array == `\\bar`);\n        assert(asNormalizedPath(`\\foo\\../..\\bar`).array == `\\bar`);\n        assert(asNormalizedPath(`\\..\\foo`).array == `\\foo`);\n        assert(asNormalizedPath(`\\..\\..\\foo`).array == `\\foo`);\n        assert(asNormalizedPath(`\\foo\\..`).array == `\\`);\n        assert(asNormalizedPath(`\\foo\\../..`).array == `\\`);\n\n        assert(asNormalizedPath(`foo\\..\\bar`).array == `bar`);\n        assert(asNormalizedPath(`foo\\..\\../bar`).array == `..\\bar`);\n\n        assert(asNormalizedPath(`..\\foo`).array == `..\\foo`);\n        assert(asNormalizedPath(`..\\..\\foo`).array == `..\\..\\foo`);\n        assert(asNormalizedPath(`..\\foo\\..\\bar`).array == `..\\bar`);\n        assert(asNormalizedPath(`..\\.\\..\\foo`).array == `..\\..\\foo`);\n        assert(asNormalizedPath(`foo\\bar\\..`).array == `foo`);\n        assert(asNormalizedPath(`\\foo\\..\\..`).array == `\\`);\n        assert(asNormalizedPath(`c:\\foo\\..\\..`).array == `c:\\`);\n\n        // Correct handling of non-root path with drive specifier\n        assert(asNormalizedPath(`c:foo`).array == `c:foo`);\n        assert(asNormalizedPath(`c:..\\foo\\.\\..\\bar`).array == `c:..\\bar`);\n\n        // The ultimate path\n        assert(asNormalizedPath(`c:\\foo\\..\\bar\\\\.\\..\\...\\\\\\baz\\\\`).array == `c:\\...\\baz`);\n        static assert(asNormalizedPath(`c:\\foo\\..\\bar\\\\.\\..\\...\\\\\\baz\\\\`).array == `c:\\...\\baz`);\n    }\n    else static assert(false);\n}\n\n/** Slice up a path into its elements.\n\n    Params:\n        path = string or slicable random access range\n\n    Returns:\n        bidirectional range of slices of `path`\n*/\nauto pathSplitter(R)(R path)\nif ((isRandomAccessRange!R && hasSlicing!R ||\n    isNarrowString!R) &&\n    !isConvertibleToString!R)\n{\n    static struct PathSplitter\n    {\n        @property bool empty() const { return pe == 0; }\n\n        @property R front()\n        {\n            assert(!empty);\n            return _path[fs .. fe];\n        }\n\n        void popFront()\n        {\n            assert(!empty);\n            if (ps == pe)\n            {\n                if (fs == bs && fe == be)\n                {\n                    pe = 0;\n                }\n                else\n                {\n                    fs = bs;\n                    fe = be;\n                }\n            }\n            else\n            {\n                fs = ps;\n                fe = fs;\n                while (fe < pe && !isDirSeparator(_path[fe]))\n                    ++fe;\n                ps = ltrim(fe, pe);\n            }\n        }\n\n        @property R back()\n        {\n            assert(!empty);\n            return _path[bs .. be];\n        }\n\n        void popBack()\n        {\n            assert(!empty);\n            if (ps == pe)\n            {\n                if (fs == bs && fe == be)\n                {\n                    pe = 0;\n                }\n                else\n                {\n                    bs = fs;\n                    be = fe;\n                }\n            }\n            else\n            {\n                bs = pe;\n                be = bs;\n                while (bs > ps && !isDirSeparator(_path[bs - 1]))\n                    --bs;\n                pe = rtrim(ps, bs);\n            }\n        }\n        @property auto save() { return this; }\n\n\n    private:\n        R _path;\n        size_t ps, pe;\n        size_t fs, fe;\n        size_t bs, be;\n\n        this(R p)\n        {\n            if (p.empty)\n            {\n                pe = 0;\n                return;\n            }\n            _path = p;\n\n            ps = 0;\n            pe = _path.length;\n\n            // If path is rooted, first element is special\n            version (Windows)\n            {\n                if (isUNC(_path))\n                {\n                    auto i = uncRootLength(_path);\n                    fs = 0;\n                    fe = i;\n                    ps = ltrim(fe, pe);\n                }\n                else if (isDriveRoot(_path))\n                {\n                    fs = 0;\n                    fe = 3;\n                    ps = ltrim(fe, pe);\n                }\n                else if (_path.length >= 1 && isDirSeparator(_path[0]))\n                {\n                    fs = 0;\n                    fe = 1;\n                    ps = ltrim(fe, pe);\n                }\n                else\n                {\n                    assert(!isRooted(_path));\n                    popFront();\n                }\n            }\n            else version (Posix)\n            {\n                if (_path.length >= 1 && isDirSeparator(_path[0]))\n                {\n                    fs = 0;\n                    fe = 1;\n                    ps = ltrim(fe, pe);\n                }\n                else\n                {\n                    popFront();\n                }\n            }\n            else static assert(0);\n\n            if (ps == pe)\n            {\n                bs = fs;\n                be = fe;\n            }\n            else\n            {\n                pe = rtrim(ps, pe);\n                popBack();\n            }\n        }\n\n        size_t ltrim(size_t s, size_t e)\n        {\n            while (s < e && isDirSeparator(_path[s]))\n                ++s;\n            return s;\n        }\n\n        size_t rtrim(size_t s, size_t e)\n        {\n            while (s < e && isDirSeparator(_path[e - 1]))\n                --e;\n            return e;\n        }\n    }\n\n    return PathSplitter(path);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : to;\n\n    assert(equal(pathSplitter(\"/\"), [\"/\"]));\n    assert(equal(pathSplitter(\"/foo/bar\"), [\"/\", \"foo\", \"bar\"]));\n    assert(equal(pathSplitter(\"foo/../bar//./\"), [\"foo\", \"..\", \"bar\", \".\"]));\n\n    version (Posix)\n    {\n        assert(equal(pathSplitter(\"//foo/bar\"), [\"/\", \"foo\", \"bar\"]));\n    }\n\n    version (Windows)\n    {\n        assert(equal(pathSplitter(`foo\\..\\bar\\/.\\`), [\"foo\", \"..\", \"bar\", \".\"]));\n        assert(equal(pathSplitter(\"c:\"), [\"c:\"]));\n        assert(equal(pathSplitter(`c:\\foo\\bar`), [`c:\\`, \"foo\", \"bar\"]));\n        assert(equal(pathSplitter(`c:foo\\bar`), [\"c:foo\", \"bar\"]));\n    }\n}\n\nauto pathSplitter(R)(auto ref R path)\nif (isConvertibleToString!R)\n{\n    return pathSplitter!(StringTypeOf!R)(path);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    assert(testAliasedString!pathSplitter(\"/\"));\n}\n\n@safe unittest\n{\n    // equal2 verifies that the range is the same both ways, i.e.\n    // through front/popFront and back/popBack.\n    import std.algorithm;\n    import std.range;\n    bool equal2(R1, R2)(R1 r1, R2 r2)\n    {\n        static assert(isBidirectionalRange!R1);\n        return equal(r1, r2) && equal(retro(r1), retro(r2));\n    }\n\n    assert(pathSplitter(\"\").empty);\n\n    // Root directories\n    assert(equal2(pathSplitter(\"/\"), [\"/\"]));\n    assert(equal2(pathSplitter(\"//\"), [\"/\"]));\n    assert(equal2(pathSplitter(\"///\"w), [\"/\"w]));\n\n    // Absolute paths\n    assert(equal2(pathSplitter(\"/foo/bar\".dup), [\"/\", \"foo\", \"bar\"]));\n\n    // General\n    assert(equal2(pathSplitter(\"foo/bar\"d.dup), [\"foo\"d, \"bar\"d]));\n    assert(equal2(pathSplitter(\"foo//bar\"), [\"foo\", \"bar\"]));\n    assert(equal2(pathSplitter(\"foo/bar//\"w), [\"foo\"w, \"bar\"w]));\n    assert(equal2(pathSplitter(\"foo/../bar//./\"d), [\"foo\"d, \"..\"d, \"bar\"d, \".\"d]));\n\n    // save()\n    auto ps1 = pathSplitter(\"foo/bar/baz\");\n    auto ps2 = ps1.save;\n    ps1.popFront();\n    assert(equal2(ps1, [\"bar\", \"baz\"]));\n    assert(equal2(ps2, [\"foo\", \"bar\", \"baz\"]));\n\n    // Platform specific\n    version (Posix)\n    {\n        assert(equal2(pathSplitter(\"//foo/bar\"w.dup), [\"/\"w, \"foo\"w, \"bar\"w]));\n    }\n    version (Windows)\n    {\n        assert(equal2(pathSplitter(`\\`), [`\\`]));\n        assert(equal2(pathSplitter(`foo\\..\\bar\\/.\\`), [\"foo\", \"..\", \"bar\", \".\"]));\n        assert(equal2(pathSplitter(\"c:\"), [\"c:\"]));\n        assert(equal2(pathSplitter(`c:\\foo\\bar`), [`c:\\`, \"foo\", \"bar\"]));\n        assert(equal2(pathSplitter(`c:foo\\bar`), [\"c:foo\", \"bar\"]));\n        assert(equal2(pathSplitter(`\\\\foo\\bar`), [`\\\\foo\\bar`]));\n        assert(equal2(pathSplitter(`\\\\foo\\bar\\\\`), [`\\\\foo\\bar`]));\n        assert(equal2(pathSplitter(`\\\\foo\\bar\\baz`), [`\\\\foo\\bar`, \"baz\"]));\n    }\n\n    import std.exception;\n    assertCTFEable!(\n    {\n        assert(equal(pathSplitter(\"/foo/bar\".dup), [\"/\", \"foo\", \"bar\"]));\n    });\n\n    static assert(is(typeof(pathSplitter!(const(char)[])(null).front) == const(char)[]));\n\n    import std.utf : byDchar;\n    assert(equal2(pathSplitter(\"foo/bar\"d.byDchar), [\"foo\"d, \"bar\"d]));\n}\n\n\n\n\n/** Determines whether a path starts at a root directory.\n\nParams:\n    path = A path name.\nReturns:\n    Whether a path starts at a root directory.\n\n    On POSIX, this function returns true if and only if the path starts\n    with a slash (/).\n\n    On Windows, this function returns true if the path starts at\n    the root directory of the current drive, of some other drive,\n    or of a network drive.\n*/\nbool isRooted(R)(R path)\nif (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||\n    is(StringTypeOf!R))\n{\n    if (path.length >= 1 && isDirSeparator(path[0])) return true;\n    version (Posix)         return false;\n    else version (Windows)  return isAbsolute!(BaseOf!R)(path);\n}\n\n///\n@safe unittest\n{\n    version (Posix)\n    {\n        assert( isRooted(\"/\"));\n        assert( isRooted(\"/foo\"));\n        assert(!isRooted(\"foo\"));\n        assert(!isRooted(\"../foo\"));\n    }\n\n    version (Windows)\n    {\n        assert( isRooted(`\\`));\n        assert( isRooted(`\\foo`));\n        assert( isRooted(`d:\\foo`));\n        assert( isRooted(`\\\\foo\\bar`));\n        assert(!isRooted(\"foo\"));\n        assert(!isRooted(\"d:foo\"));\n    }\n}\n\n@safe unittest\n{\n    assert(isRooted(\"/\"));\n    assert(isRooted(\"/foo\"));\n    assert(!isRooted(\"foo\"));\n    assert(!isRooted(\"../foo\"));\n\n    version (Windows)\n    {\n    assert(isRooted(`\\`));\n    assert(isRooted(`\\foo`));\n    assert(isRooted(`d:\\foo`));\n    assert(isRooted(`\\\\foo\\bar`));\n    assert(!isRooted(\"foo\"));\n    assert(!isRooted(\"d:foo\"));\n    }\n\n    static assert(isRooted(\"/foo\"));\n    static assert(!isRooted(\"foo\"));\n\n    static struct DirEntry { string s; alias s this; }\n    assert(!isRooted(DirEntry(\"foo\")));\n}\n\n/** Determines whether a path is absolute or not.\n\n    Params: path = A path name.\n\n    Returns: Whether a path is absolute or not.\n\n    Example:\n    On POSIX, an absolute path starts at the root directory.\n    (In fact, `_isAbsolute` is just an alias for $(LREF isRooted).)\n    ---\n    version (Posix)\n    {\n        assert(isAbsolute(\"/\"));\n        assert(isAbsolute(\"/foo\"));\n        assert(!isAbsolute(\"foo\"));\n        assert(!isAbsolute(\"../foo\"));\n    }\n    ---\n\n    On Windows, an absolute path starts at the root directory of\n    a specific drive.  Hence, it must start with $(D `d:\\`) or $(D `d:/`),\n    where `d` is the drive letter.  Alternatively, it may be a\n    network path, i.e. a path starting with a double (back)slash.\n    ---\n    version (Windows)\n    {\n        assert(isAbsolute(`d:\\`));\n        assert(isAbsolute(`d:\\foo`));\n        assert(isAbsolute(`\\\\foo\\bar`));\n        assert(!isAbsolute(`\\`));\n        assert(!isAbsolute(`\\foo`));\n        assert(!isAbsolute(\"d:foo\"));\n    }\n    ---\n*/\nversion (StdDdoc)\n{\n    bool isAbsolute(R)(R path) pure nothrow @safe\n    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||\n        is(StringTypeOf!R));\n}\nelse version (Windows)\n{\n    bool isAbsolute(R)(R path)\n    if (isRandomAccessRange!R && isSomeChar!(ElementType!R) ||\n        is(StringTypeOf!R))\n    {\n        return isDriveRoot!(BaseOf!R)(path) || isUNC!(BaseOf!R)(path);\n    }\n}\nelse version (Posix)\n{\n    alias isAbsolute = isRooted;\n}\n\n\n@safe unittest\n{\n    assert(!isAbsolute(\"foo\"));\n    assert(!isAbsolute(\"../foo\"w));\n    static assert(!isAbsolute(\"foo\"));\n\n    version (Posix)\n    {\n    assert(isAbsolute(\"/\"d));\n    assert(isAbsolute(\"/foo\".dup));\n    static assert(isAbsolute(\"/foo\"));\n    }\n\n    version (Windows)\n    {\n    assert(isAbsolute(\"d:\\\\\"w));\n    assert(isAbsolute(\"d:\\\\foo\"d));\n    assert(isAbsolute(\"\\\\\\\\foo\\\\bar\"));\n    assert(!isAbsolute(\"\\\\\"w.dup));\n    assert(!isAbsolute(\"\\\\foo\"d.dup));\n    assert(!isAbsolute(\"d:\"));\n    assert(!isAbsolute(\"d:foo\"));\n    static assert(isAbsolute(`d:\\foo`));\n    }\n\n    {\n        auto r = MockRange!(immutable(char))(`../foo`);\n        assert(!r.isAbsolute());\n    }\n\n    static struct DirEntry { string s; alias s this; }\n    assert(!isAbsolute(DirEntry(\"foo\")));\n}\n\n\n\n\n/** Transforms `path` into an absolute path.\n\n    The following algorithm is used:\n    $(OL\n        $(LI If `path` is empty, return `null`.)\n        $(LI If `path` is already absolute, return it.)\n        $(LI Otherwise, append `path` to `base` and return\n            the result. If `base` is not specified, the current\n            working directory is used.)\n    )\n    The function allocates memory if and only if it gets to the third stage\n    of this algorithm.\n\n    Params:\n        path = the relative path to transform\n        base = the base directory of the relative path\n\n    Returns:\n        string of transformed path\n\n    Throws:\n    `Exception` if the specified _base directory is not absolute.\n\n    See_Also:\n        $(LREF asAbsolutePath) which does not allocate\n*/\nstring absolutePath(string path, lazy string base = getcwd())\n    @safe pure\n{\n    import std.array : array;\n    if (path.empty)  return null;\n    if (isAbsolute(path))  return path;\n    auto baseVar = base;\n    if (!isAbsolute(baseVar)) throw new Exception(\"Base directory must be absolute\");\n    return chainPath(baseVar, path).array;\n}\n\n///\n@safe unittest\n{\n    version (Posix)\n    {\n        assert(absolutePath(\"some/file\", \"/foo/bar\")  == \"/foo/bar/some/file\");\n        assert(absolutePath(\"../file\", \"/foo/bar\")    == \"/foo/bar/../file\");\n        assert(absolutePath(\"/some/file\", \"/foo/bar\") == \"/some/file\");\n    }\n\n    version (Windows)\n    {\n        assert(absolutePath(`some\\file`, `c:\\foo\\bar`)    == `c:\\foo\\bar\\some\\file`);\n        assert(absolutePath(`..\\file`, `c:\\foo\\bar`)      == `c:\\foo\\bar\\..\\file`);\n        assert(absolutePath(`c:\\some\\file`, `c:\\foo\\bar`) == `c:\\some\\file`);\n        assert(absolutePath(`\\`, `c:\\`)                   == `c:\\`);\n        assert(absolutePath(`\\some\\file`, `c:\\foo\\bar`)   == `c:\\some\\file`);\n    }\n}\n\n@safe unittest\n{\n    version (Posix)\n    {\n        static assert(absolutePath(\"some/file\", \"/foo/bar\") == \"/foo/bar/some/file\");\n    }\n\n    version (Windows)\n    {\n        static assert(absolutePath(`some\\file`, `c:\\foo\\bar`) == `c:\\foo\\bar\\some\\file`);\n    }\n\n    import std.exception;\n    assertThrown(absolutePath(\"bar\", \"foo\"));\n}\n\n/** Transforms `path` into an absolute path.\n\n    The following algorithm is used:\n    $(OL\n        $(LI If `path` is empty, return `null`.)\n        $(LI If `path` is already absolute, return it.)\n        $(LI Otherwise, append `path` to the current working directory,\n        which allocates memory.)\n    )\n\n    Params:\n        path = the relative path to transform\n\n    Returns:\n        the transformed path as a lazy range\n\n    See_Also:\n        $(LREF absolutePath) which returns an allocated string\n*/\nauto asAbsolutePath(R)(R path)\nif ((isRandomAccessRange!R && isSomeChar!(ElementType!R) ||\n    isNarrowString!R) &&\n    !isConvertibleToString!R)\n{\n    import std.file : getcwd;\n    string base = null;\n    if (!path.empty && !isAbsolute(path))\n        base = getcwd();\n    return chainPath(base, path);\n}\n\n///\n@system unittest\n{\n    import std.array;\n    assert(asAbsolutePath(cast(string) null).array == \"\");\n    version (Posix)\n    {\n        assert(asAbsolutePath(\"/foo\").array == \"/foo\");\n    }\n    version (Windows)\n    {\n        assert(asAbsolutePath(\"c:/foo\").array == \"c:/foo\");\n    }\n    asAbsolutePath(\"foo\");\n}\n\nauto asAbsolutePath(R)(auto ref R path)\nif (isConvertibleToString!R)\n{\n    return asAbsolutePath!(StringTypeOf!R)(path);\n}\n\n@system unittest\n{\n    assert(testAliasedString!asAbsolutePath(null));\n}\n\n/** Translates `path` into a relative path.\n\n    The returned path is relative to `base`, which is by default\n    taken to be the current working directory.  If specified,\n    `base` must be an absolute path, and it is always assumed\n    to refer to a directory.  If `path` and `base` refer to\n    the same directory, the function returns $(D `.`).\n\n    The following algorithm is used:\n    $(OL\n        $(LI If `path` is a relative directory, return it unaltered.)\n        $(LI Find a common root between `path` and `base`.\n            If there is no common root, return `path` unaltered.)\n        $(LI Prepare a string with as many $(D `../`) or $(D `..\\`) as\n            necessary to reach the common root from base path.)\n        $(LI Append the remaining segments of `path` to the string\n            and return.)\n    )\n\n    In the second step, path components are compared using `filenameCmp!cs`,\n    where `cs` is an optional template parameter determining whether\n    the comparison is case sensitive or not.  See the\n    $(LREF filenameCmp) documentation for details.\n\n    This function allocates memory.\n\n    Params:\n        cs = Whether matching path name components against the base path should\n            be case-sensitive or not.\n        path = A path name.\n        base = The base path to construct the relative path from.\n\n    Returns: The relative path.\n\n    See_Also:\n        $(LREF asRelativePath) which does not allocate memory\n\n    Throws:\n    `Exception` if the specified _base directory is not absolute.\n*/\nstring relativePath(CaseSensitive cs = CaseSensitive.osDefault)\n    (string path, lazy string base = getcwd())\n{\n    if (!isAbsolute(path))\n        return path;\n    auto baseVar = base;\n    if (!isAbsolute(baseVar))\n        throw new Exception(\"Base directory must be absolute\");\n\n    import std.conv : to;\n    return asRelativePath!cs(path, baseVar).to!string;\n}\n\n///\n@safe unittest\n{\n    assert(relativePath(\"foo\") == \"foo\");\n\n    version (Posix)\n    {\n        assert(relativePath(\"foo\", \"/bar\") == \"foo\");\n        assert(relativePath(\"/foo/bar\", \"/foo/bar\") == \".\");\n        assert(relativePath(\"/foo/bar\", \"/foo/baz\") == \"../bar\");\n        assert(relativePath(\"/foo/bar/baz\", \"/foo/woo/wee\") == \"../../bar/baz\");\n        assert(relativePath(\"/foo/bar/baz\", \"/foo/bar\") == \"baz\");\n    }\n    version (Windows)\n    {\n        assert(relativePath(\"foo\", `c:\\bar`) == \"foo\");\n        assert(relativePath(`c:\\foo\\bar`, `c:\\foo\\bar`) == \".\");\n        assert(relativePath(`c:\\foo\\bar`, `c:\\foo\\baz`) == `..\\bar`);\n        assert(relativePath(`c:\\foo\\bar\\baz`, `c:\\foo\\woo\\wee`) == `..\\..\\bar\\baz`);\n        assert(relativePath(`c:\\foo\\bar\\baz`, `c:\\foo\\bar`) == \"baz\");\n        assert(relativePath(`c:\\foo\\bar`, `d:\\foo`) == `c:\\foo\\bar`);\n    }\n}\n\n@safe unittest\n{\n    import std.exception;\n    assert(relativePath(\"foo\") == \"foo\");\n    version (Posix)\n    {\n        relativePath(\"/foo\");\n        assert(relativePath(\"/foo/bar\", \"/foo/baz\") == \"../bar\");\n        assertThrown(relativePath(\"/foo\", \"bar\"));\n    }\n    else version (Windows)\n    {\n        relativePath(`\\foo`);\n        assert(relativePath(`c:\\foo\\bar\\baz`, `c:\\foo\\bar`) == \"baz\");\n        assertThrown(relativePath(`c:\\foo`, \"bar\"));\n    }\n    else static assert(0);\n}\n\n/** Transforms `path` into a path relative to `base`.\n\n    The returned path is relative to `base`, which is usually\n    the current working directory.\n    `base` must be an absolute path, and it is always assumed\n    to refer to a directory.  If `path` and `base` refer to\n    the same directory, the function returns `'.'`.\n\n    The following algorithm is used:\n    $(OL\n        $(LI If `path` is a relative directory, return it unaltered.)\n        $(LI Find a common root between `path` and `base`.\n            If there is no common root, return `path` unaltered.)\n        $(LI Prepare a string with as many `../` or `..\\` as\n            necessary to reach the common root from base path.)\n        $(LI Append the remaining segments of `path` to the string\n            and return.)\n    )\n\n    In the second step, path components are compared using `filenameCmp!cs`,\n    where `cs` is an optional template parameter determining whether\n    the comparison is case sensitive or not.  See the\n    $(LREF filenameCmp) documentation for details.\n\n    Params:\n        path = path to transform\n        base = absolute path\n        cs = whether filespec comparisons are sensitive or not; defaults to\n         `CaseSensitive.osDefault`\n\n    Returns:\n        a random access range of the transformed path\n\n    See_Also:\n        $(LREF relativePath)\n*/\nauto asRelativePath(CaseSensitive cs = CaseSensitive.osDefault, R1, R2)\n    (R1 path, R2 base)\nif ((isNarrowString!R1 ||\n    (isRandomAccessRange!R1 && hasSlicing!R1 && isSomeChar!(ElementType!R1)) &&\n    !isConvertibleToString!R1) &&\n    (isNarrowString!R2 ||\n    (isRandomAccessRange!R2 && hasSlicing!R2 && isSomeChar!(ElementType!R2)) &&\n    !isConvertibleToString!R2))\n{\n    bool choosePath = !isAbsolute(path);\n\n    // Find common root with current working directory\n\n    auto basePS = pathSplitter(base);\n    auto pathPS = pathSplitter(path);\n    choosePath |= filenameCmp!cs(basePS.front, pathPS.front) != 0;\n\n    basePS.popFront();\n    pathPS.popFront();\n\n    import std.algorithm.comparison : mismatch;\n    import std.algorithm.iteration : joiner;\n    import std.array : array;\n    import std.range.primitives : walkLength;\n    import std.range : repeat, chain, choose;\n    import std.utf : byCodeUnit, byChar;\n\n    // Remove matching prefix from basePS and pathPS\n    auto tup = mismatch!((a, b) => filenameCmp!cs(a, b) == 0)(basePS, pathPS);\n    basePS = tup[0];\n    pathPS = tup[1];\n\n    string sep;\n    if (basePS.empty && pathPS.empty)\n        sep = \".\";              // if base == path, this is the return\n    else if (!basePS.empty && !pathPS.empty)\n        sep = dirSeparator;\n\n    // Append as many \"../\" as necessary to reach common base from path\n    auto r1 = \"..\"\n        .byChar\n        .repeat(basePS.walkLength())\n        .joiner(dirSeparator.byChar);\n\n    auto r2 = pathPS\n        .joiner(dirSeparator.byChar)\n        .byChar;\n\n    // Return (r1 ~ sep ~ r2)\n    return choose(choosePath, path.byCodeUnit, chain(r1, sep.byChar, r2));\n}\n\n///\n@safe unittest\n{\n    import std.array;\n    version (Posix)\n    {\n        assert(asRelativePath(\"foo\", \"/bar\").array == \"foo\");\n        assert(asRelativePath(\"/foo/bar\", \"/foo/bar\").array == \".\");\n        assert(asRelativePath(\"/foo/bar\", \"/foo/baz\").array == \"../bar\");\n        assert(asRelativePath(\"/foo/bar/baz\", \"/foo/woo/wee\").array == \"../../bar/baz\");\n        assert(asRelativePath(\"/foo/bar/baz\", \"/foo/bar\").array == \"baz\");\n    }\n    else version (Windows)\n    {\n        assert(asRelativePath(\"foo\", `c:\\bar`).array == \"foo\");\n        assert(asRelativePath(`c:\\foo\\bar`, `c:\\foo\\bar`).array == \".\");\n        assert(asRelativePath(`c:\\foo\\bar`, `c:\\foo\\baz`).array == `..\\bar`);\n        assert(asRelativePath(`c:\\foo\\bar\\baz`, `c:\\foo\\woo\\wee`).array == `..\\..\\bar\\baz`);\n        assert(asRelativePath(`c:/foo/bar/baz`, `c:\\foo\\woo\\wee`).array == `..\\..\\bar\\baz`);\n        assert(asRelativePath(`c:\\foo\\bar\\baz`, `c:\\foo\\bar`).array == \"baz\");\n        assert(asRelativePath(`c:\\foo\\bar`, `d:\\foo`).array == `c:\\foo\\bar`);\n        assert(asRelativePath(`\\\\foo\\bar`, `c:\\foo`).array == `\\\\foo\\bar`);\n    }\n    else\n        static assert(0);\n}\n\nauto asRelativePath(CaseSensitive cs = CaseSensitive.osDefault, R1, R2)\n    (auto ref R1 path, auto ref R2 base)\nif (isConvertibleToString!R1 || isConvertibleToString!R2)\n{\n    import std.meta : staticMap;\n    alias Types = staticMap!(convertToString, R1, R2);\n    return asRelativePath!(cs, Types)(path, base);\n}\n\n@safe unittest\n{\n    import std.array;\n    version (Posix)\n        assert(asRelativePath(TestAliasedString(\"foo\"), TestAliasedString(\"/bar\")).array == \"foo\");\n    else version (Windows)\n        assert(asRelativePath(TestAliasedString(\"foo\"), TestAliasedString(`c:\\bar`)).array == \"foo\");\n    assert(asRelativePath(TestAliasedString(\"foo\"), \"bar\").array == \"foo\");\n    assert(asRelativePath(\"foo\", TestAliasedString(\"bar\")).array == \"foo\");\n    assert(asRelativePath(TestAliasedString(\"foo\"), TestAliasedString(\"bar\")).array == \"foo\");\n    import std.utf : byDchar;\n    assert(asRelativePath(\"foo\"d.byDchar, TestAliasedString(\"bar\")).array == \"foo\");\n}\n\n@safe unittest\n{\n    import std.array, std.utf : bCU=byCodeUnit;\n    version (Posix)\n    {\n        assert(asRelativePath(\"/foo/bar/baz\".bCU, \"/foo/bar\".bCU).array == \"baz\");\n        assert(asRelativePath(\"/foo/bar/baz\"w.bCU, \"/foo/bar\"w.bCU).array == \"baz\"w);\n        assert(asRelativePath(\"/foo/bar/baz\"d.bCU, \"/foo/bar\"d.bCU).array == \"baz\"d);\n    }\n    else version (Windows)\n    {\n        assert(asRelativePath(`\\\\foo\\bar`.bCU, `c:\\foo`.bCU).array == `\\\\foo\\bar`);\n        assert(asRelativePath(`\\\\foo\\bar`w.bCU, `c:\\foo`w.bCU).array == `\\\\foo\\bar`w);\n        assert(asRelativePath(`\\\\foo\\bar`d.bCU, `c:\\foo`d.bCU).array == `\\\\foo\\bar`d);\n    }\n}\n\n/** Compares filename characters.\n\n    This function can perform a case-sensitive or a case-insensitive\n    comparison.  This is controlled through the `cs` template parameter\n    which, if not specified, is given by $(LREF CaseSensitive)`.osDefault`.\n\n    On Windows, the backslash and slash characters ($(D `\\`) and $(D `/`))\n    are considered equal.\n\n    Params:\n        cs = Case-sensitivity of the comparison.\n        a = A filename character.\n        b = A filename character.\n\n    Returns:\n        $(D < 0) if $(D a < b),\n        `0` if $(D a == b), and\n        $(D > 0) if $(D a > b).\n*/\nint filenameCharCmp(CaseSensitive cs = CaseSensitive.osDefault)(dchar a, dchar b)\n    @safe pure nothrow\n{\n    if (isDirSeparator(a) && isDirSeparator(b)) return 0;\n    static if (!cs)\n    {\n        import std.uni : toLower;\n        a = toLower(a);\n        b = toLower(b);\n    }\n    return cast(int)(a - b);\n}\n\n///\n@safe unittest\n{\n    assert(filenameCharCmp('a', 'a') == 0);\n    assert(filenameCharCmp('a', 'b') < 0);\n    assert(filenameCharCmp('b', 'a') > 0);\n\n    version (linux)\n    {\n        // Same as calling filenameCharCmp!(CaseSensitive.yes)(a, b)\n        assert(filenameCharCmp('A', 'a') < 0);\n        assert(filenameCharCmp('a', 'A') > 0);\n    }\n    version (Windows)\n    {\n        // Same as calling filenameCharCmp!(CaseSensitive.no)(a, b)\n        assert(filenameCharCmp('a', 'A') == 0);\n        assert(filenameCharCmp('a', 'B') < 0);\n        assert(filenameCharCmp('A', 'b') < 0);\n    }\n}\n\n@safe unittest\n{\n    assert(filenameCharCmp!(CaseSensitive.yes)('A', 'a') < 0);\n    assert(filenameCharCmp!(CaseSensitive.yes)('a', 'A') > 0);\n\n    assert(filenameCharCmp!(CaseSensitive.no)('a', 'a') == 0);\n    assert(filenameCharCmp!(CaseSensitive.no)('a', 'b') < 0);\n    assert(filenameCharCmp!(CaseSensitive.no)('b', 'a') > 0);\n    assert(filenameCharCmp!(CaseSensitive.no)('A', 'a') == 0);\n    assert(filenameCharCmp!(CaseSensitive.no)('a', 'A') == 0);\n    assert(filenameCharCmp!(CaseSensitive.no)('a', 'B') < 0);\n    assert(filenameCharCmp!(CaseSensitive.no)('B', 'a') > 0);\n    assert(filenameCharCmp!(CaseSensitive.no)('A', 'b') < 0);\n    assert(filenameCharCmp!(CaseSensitive.no)('b', 'A') > 0);\n\n    version (Posix)   assert(filenameCharCmp('\\\\', '/') != 0);\n    version (Windows) assert(filenameCharCmp('\\\\', '/') == 0);\n}\n\n\n/** Compares file names and returns\n\n    Individual characters are compared using `filenameCharCmp!cs`,\n    where `cs` is an optional template parameter determining whether\n    the comparison is case sensitive or not.\n\n    Treatment of invalid UTF encodings is implementation defined.\n\n    Params:\n        cs = case sensitivity\n        filename1 = range for first file name\n        filename2 = range for second file name\n\n    Returns:\n        $(D < 0) if $(D filename1 < filename2),\n        `0` if $(D filename1 == filename2) and\n        $(D > 0) if $(D filename1 > filename2).\n\n    See_Also:\n        $(LREF filenameCharCmp)\n*/\nint filenameCmp(CaseSensitive cs = CaseSensitive.osDefault, Range1, Range2)\n    (Range1 filename1, Range2 filename2)\nif (isInputRange!Range1 && !isInfinite!Range1 &&\n    isSomeChar!(ElementEncodingType!Range1) &&\n    !isConvertibleToString!Range1 &&\n    isInputRange!Range2 && !isInfinite!Range2 &&\n    isSomeChar!(ElementEncodingType!Range2) &&\n    !isConvertibleToString!Range2)\n{\n    alias C1 = Unqual!(ElementEncodingType!Range1);\n    alias C2 = Unqual!(ElementEncodingType!Range2);\n\n    static if (!cs && (C1.sizeof < 4 || C2.sizeof < 4) ||\n               C1.sizeof != C2.sizeof)\n    {\n        // Case insensitive - decode so case is checkable\n        // Different char sizes - decode to bring to common type\n        import std.utf : byDchar;\n        return filenameCmp!cs(filename1.byDchar, filename2.byDchar);\n    }\n    else static if (isSomeString!Range1 && C1.sizeof < 4 ||\n                    isSomeString!Range2 && C2.sizeof < 4)\n    {\n        // Avoid autodecoding\n        import std.utf : byCodeUnit;\n        return filenameCmp!cs(filename1.byCodeUnit, filename2.byCodeUnit);\n    }\n    else\n    {\n        for (;;)\n        {\n            if (filename1.empty) return -(cast(int) !filename2.empty);\n            if (filename2.empty) return  1;\n            const c = filenameCharCmp!cs(filename1.front, filename2.front);\n            if (c != 0) return c;\n            filename1.popFront();\n            filename2.popFront();\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    assert(filenameCmp(\"abc\", \"abc\") == 0);\n    assert(filenameCmp(\"abc\", \"abd\") < 0);\n    assert(filenameCmp(\"abc\", \"abb\") > 0);\n    assert(filenameCmp(\"abc\", \"abcd\") < 0);\n    assert(filenameCmp(\"abcd\", \"abc\") > 0);\n\n    version (linux)\n    {\n        // Same as calling filenameCmp!(CaseSensitive.yes)(filename1, filename2)\n        assert(filenameCmp(\"Abc\", \"abc\") < 0);\n        assert(filenameCmp(\"abc\", \"Abc\") > 0);\n    }\n    version (Windows)\n    {\n        // Same as calling filenameCmp!(CaseSensitive.no)(filename1, filename2)\n        assert(filenameCmp(\"Abc\", \"abc\") == 0);\n        assert(filenameCmp(\"abc\", \"Abc\") == 0);\n        assert(filenameCmp(\"Abc\", \"abD\") < 0);\n        assert(filenameCmp(\"abc\", \"AbB\") > 0);\n    }\n}\n\nint filenameCmp(CaseSensitive cs = CaseSensitive.osDefault, Range1, Range2)\n    (auto ref Range1 filename1, auto ref Range2 filename2)\nif (isConvertibleToString!Range1 || isConvertibleToString!Range2)\n{\n    import std.meta : staticMap;\n    alias Types = staticMap!(convertToString, Range1, Range2);\n    return filenameCmp!(cs, Types)(filename1, filename2);\n}\n\n@safe unittest\n{\n    assert(filenameCmp!(CaseSensitive.yes)(TestAliasedString(\"Abc\"), \"abc\") < 0);\n    assert(filenameCmp!(CaseSensitive.yes)(\"Abc\", TestAliasedString(\"abc\")) < 0);\n    assert(filenameCmp!(CaseSensitive.yes)(TestAliasedString(\"Abc\"), TestAliasedString(\"abc\")) < 0);\n}\n\n@safe unittest\n{\n    assert(filenameCmp!(CaseSensitive.yes)(\"Abc\", \"abc\") < 0);\n    assert(filenameCmp!(CaseSensitive.yes)(\"abc\", \"Abc\") > 0);\n\n    assert(filenameCmp!(CaseSensitive.no)(\"abc\", \"abc\") == 0);\n    assert(filenameCmp!(CaseSensitive.no)(\"abc\", \"abd\") < 0);\n    assert(filenameCmp!(CaseSensitive.no)(\"abc\", \"abb\") > 0);\n    assert(filenameCmp!(CaseSensitive.no)(\"abc\", \"abcd\") < 0);\n    assert(filenameCmp!(CaseSensitive.no)(\"abcd\", \"abc\") > 0);\n    assert(filenameCmp!(CaseSensitive.no)(\"Abc\", \"abc\") == 0);\n    assert(filenameCmp!(CaseSensitive.no)(\"abc\", \"Abc\") == 0);\n    assert(filenameCmp!(CaseSensitive.no)(\"Abc\", \"abD\") < 0);\n    assert(filenameCmp!(CaseSensitive.no)(\"abc\", \"AbB\") > 0);\n\n    version (Posix)   assert(filenameCmp(`abc\\def`, `abc/def`) != 0);\n    version (Windows) assert(filenameCmp(`abc\\def`, `abc/def`) == 0);\n}\n\n/** Matches a pattern against a path.\n\n    Some characters of pattern have a special meaning (they are\n    $(I meta-characters)) and can't be escaped. These are:\n\n    $(BOOKTABLE,\n    $(TR $(TD `*`)\n         $(TD Matches 0 or more instances of any character.))\n    $(TR $(TD `?`)\n         $(TD Matches exactly one instance of any character.))\n    $(TR $(TD `[`$(I chars)`]`)\n         $(TD Matches one instance of any character that appears\n              between the brackets.))\n    $(TR $(TD `[!`$(I chars)`]`)\n         $(TD Matches one instance of any character that does not\n              appear between the brackets after the exclamation mark.))\n    $(TR $(TD `{`$(I string1)`,`$(I string2)`,`&hellip;`}`)\n         $(TD Matches either of the specified strings.))\n    )\n\n    Individual characters are compared using `filenameCharCmp!cs`,\n    where `cs` is an optional template parameter determining whether\n    the comparison is case sensitive or not.  See the\n    $(LREF filenameCharCmp) documentation for details.\n\n    Note that directory\n    separators and dots don't stop a meta-character from matching\n    further portions of the path.\n\n    Params:\n        cs = Whether the matching should be case-sensitive\n        path = The path to be matched against\n        pattern = The glob pattern\n\n    Returns:\n    `true` if pattern matches path, `false` otherwise.\n\n    See_also:\n    $(LINK2 http://en.wikipedia.org/wiki/Glob_%28programming%29,Wikipedia: _glob (programming))\n */\nbool globMatch(CaseSensitive cs = CaseSensitive.osDefault, C, Range)\n    (Range path, const(C)[] pattern)\n    @safe pure nothrow\nif (isForwardRange!Range && !isInfinite!Range &&\n    isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range &&\n    isSomeChar!C && is(Unqual!C == Unqual!(ElementEncodingType!Range)))\nin\n{\n    // Verify that pattern[] is valid\n    import std.algorithm.searching : balancedParens;\n    assert(balancedParens(pattern, '[', ']', 0));\n    assert(balancedParens(pattern, '{', '}', 0));\n}\ndo\n{\n    alias RC = Unqual!(ElementEncodingType!Range);\n\n    static if (RC.sizeof == 1 && isSomeString!Range)\n    {\n        import std.utf : byChar;\n        return globMatch!cs(path.byChar, pattern);\n    }\n    else static if (RC.sizeof == 2 && isSomeString!Range)\n    {\n        import std.utf : byWchar;\n        return globMatch!cs(path.byWchar, pattern);\n    }\n    else\n    {\n        C[] pattmp;\n        foreach (ref pi; 0 .. pattern.length)\n        {\n            const pc = pattern[pi];\n            switch (pc)\n            {\n                case '*':\n                    if (pi + 1 == pattern.length)\n                        return true;\n                    for (; !path.empty; path.popFront())\n                    {\n                        auto p = path.save;\n                        if (globMatch!(cs, C)(p,\n                                        pattern[pi + 1 .. pattern.length]))\n                            return true;\n                    }\n                    return false;\n\n                case '?':\n                    if (path.empty)\n                        return false;\n                    path.popFront();\n                    break;\n\n                case '[':\n                    if (path.empty)\n                        return false;\n                    auto nc = path.front;\n                    path.popFront();\n                    auto not = false;\n                    ++pi;\n                    if (pattern[pi] == '!')\n                    {\n                        not = true;\n                        ++pi;\n                    }\n                    auto anymatch = false;\n                    while (1)\n                    {\n                        const pc2 = pattern[pi];\n                        if (pc2 == ']')\n                            break;\n                        if (!anymatch && (filenameCharCmp!cs(nc, pc2) == 0))\n                            anymatch = true;\n                        ++pi;\n                    }\n                    if (anymatch == not)\n                        return false;\n                    break;\n\n                case '{':\n                    // find end of {} section\n                    auto piRemain = pi;\n                    for (; piRemain < pattern.length\n                             && pattern[piRemain] != '}'; ++piRemain)\n                    {   }\n\n                    if (piRemain < pattern.length)\n                        ++piRemain;\n                    ++pi;\n\n                    while (pi < pattern.length)\n                    {\n                        const pi0 = pi;\n                        C pc3 = pattern[pi];\n                        // find end of current alternative\n                        for (; pi < pattern.length && pc3 != '}' && pc3 != ','; ++pi)\n                        {\n                            pc3 = pattern[pi];\n                        }\n\n                        auto p = path.save;\n                        if (pi0 == pi)\n                        {\n                            if (globMatch!(cs, C)(p, pattern[piRemain..$]))\n                            {\n                                return true;\n                            }\n                            ++pi;\n                        }\n                        else\n                        {\n                            /* Match for:\n                             *   pattern[pi0 .. pi-1] ~ pattern[piRemain..$]\n                             */\n                            if (pattmp is null)\n                                // Allocate this only once per function invocation.\n                                // Should do it with malloc/free, but that would make it impure.\n                                pattmp = new C[pattern.length];\n\n                            const len1 = pi - 1 - pi0;\n                            pattmp[0 .. len1] = pattern[pi0 .. pi - 1];\n\n                            const len2 = pattern.length - piRemain;\n                            pattmp[len1 .. len1 + len2] = pattern[piRemain .. $];\n\n                            if (globMatch!(cs, C)(p, pattmp[0 .. len1 + len2]))\n                            {\n                                return true;\n                            }\n                        }\n                        if (pc3 == '}')\n                        {\n                            break;\n                        }\n                    }\n                    return false;\n\n                default:\n                    if (path.empty)\n                        return false;\n                    if (filenameCharCmp!cs(pc, path.front) != 0)\n                        return false;\n                    path.popFront();\n                    break;\n            }\n        }\n        return path.empty;\n    }\n}\n\n///\n@safe unittest\n{\n    assert(globMatch(\"foo.bar\", \"*\"));\n    assert(globMatch(\"foo.bar\", \"*.*\"));\n    assert(globMatch(`foo/foo\\bar`, \"f*b*r\"));\n    assert(globMatch(\"foo.bar\", \"f???bar\"));\n    assert(globMatch(\"foo.bar\", \"[fg]???bar\"));\n    assert(globMatch(\"foo.bar\", \"[!gh]*bar\"));\n    assert(globMatch(\"bar.fooz\", \"bar.{foo,bif}z\"));\n    assert(globMatch(\"bar.bifz\", \"bar.{foo,bif}z\"));\n\n    version (Windows)\n    {\n        // Same as calling globMatch!(CaseSensitive.no)(path, pattern)\n        assert(globMatch(\"foo\", \"Foo\"));\n        assert(globMatch(\"Goo.bar\", \"[fg]???bar\"));\n    }\n    version (linux)\n    {\n        // Same as calling globMatch!(CaseSensitive.yes)(path, pattern)\n        assert(!globMatch(\"foo\", \"Foo\"));\n        assert(!globMatch(\"Goo.bar\", \"[fg]???bar\"));\n    }\n}\n\nbool globMatch(CaseSensitive cs = CaseSensitive.osDefault, C, Range)\n    (auto ref Range path, const(C)[] pattern)\n    @safe pure nothrow\nif (isConvertibleToString!Range)\n{\n    return globMatch!(cs, C, StringTypeOf!Range)(path, pattern);\n}\n\n@safe unittest\n{\n    assert(testAliasedString!globMatch(\"foo.bar\", \"*\"));\n}\n\n@safe unittest\n{\n    assert(globMatch!(CaseSensitive.no)(\"foo\", \"Foo\"));\n    assert(!globMatch!(CaseSensitive.yes)(\"foo\", \"Foo\"));\n\n    assert(globMatch(\"foo\", \"*\"));\n    assert(globMatch(\"foo.bar\"w, \"*\"w));\n    assert(globMatch(\"foo.bar\"d, \"*.*\"d));\n    assert(globMatch(\"foo.bar\", \"foo*\"));\n    assert(globMatch(\"foo.bar\"w, \"f*bar\"w));\n    assert(globMatch(\"foo.bar\"d, \"f*b*r\"d));\n    assert(globMatch(\"foo.bar\", \"f???bar\"));\n    assert(globMatch(\"foo.bar\"w, \"[fg]???bar\"w));\n    assert(globMatch(\"foo.bar\"d, \"[!gh]*bar\"d));\n\n    assert(!globMatch(\"foo\", \"bar\"));\n    assert(!globMatch(\"foo\"w, \"*.*\"w));\n    assert(!globMatch(\"foo.bar\"d, \"f*baz\"d));\n    assert(!globMatch(\"foo.bar\", \"f*b*x\"));\n    assert(!globMatch(\"foo.bar\", \"[gh]???bar\"));\n    assert(!globMatch(\"foo.bar\"w, \"[!fg]*bar\"w));\n    assert(!globMatch(\"foo.bar\"d, \"[fg]???baz\"d));\n    assert(!globMatch(\"foo.di\", \"*.d\")); // test issue 6634: triggered bad assertion\n\n    assert(globMatch(\"foo.bar\", \"{foo,bif}.bar\"));\n    assert(globMatch(\"bif.bar\"w, \"{foo,bif}.bar\"w));\n\n    assert(globMatch(\"bar.foo\"d, \"bar.{foo,bif}\"d));\n    assert(globMatch(\"bar.bif\", \"bar.{foo,bif}\"));\n\n    assert(globMatch(\"bar.fooz\"w, \"bar.{foo,bif}z\"w));\n    assert(globMatch(\"bar.bifz\"d, \"bar.{foo,bif}z\"d));\n\n    assert(globMatch(\"bar.foo\", \"bar.{biz,,baz}foo\"));\n    assert(globMatch(\"bar.foo\"w, \"bar.{biz,}foo\"w));\n    assert(globMatch(\"bar.foo\"d, \"bar.{,biz}foo\"d));\n    assert(globMatch(\"bar.foo\", \"bar.{}foo\"));\n\n    assert(globMatch(\"bar.foo\"w, \"bar.{ar,,fo}o\"w));\n    assert(globMatch(\"bar.foo\"d, \"bar.{,ar,fo}o\"d));\n    assert(globMatch(\"bar.o\", \"bar.{,ar,fo}o\"));\n\n    assert(!globMatch(\"foo\", \"foo?\"));\n    assert(!globMatch(\"foo\", \"foo[]\"));\n    assert(!globMatch(\"foo\", \"foob\"));\n    assert(!globMatch(\"foo\", \"foo{b}\"));\n\n\n    static assert(globMatch(\"foo.bar\", \"[!gh]*bar\"));\n}\n\n\n\n\n/** Checks that the given file or directory name is valid.\n\n    The maximum length of `filename` is given by the constant\n    `core.stdc.stdio.FILENAME_MAX`.  (On Windows, this number is\n    defined as the maximum number of UTF-16 code points, and the\n    test will therefore only yield strictly correct results when\n    `filename` is a string of `wchar`s.)\n\n    On Windows, the following criteria must be satisfied\n    ($(LINK2 http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx,source)):\n    $(UL\n        $(LI `filename` must not contain any characters whose integer\n            representation is in the range 0-31.)\n        $(LI `filename` must not contain any of the following $(I reserved\n            characters): <>:\"/\\|?*)\n        $(LI `filename` may not end with a space ($(D ' ')) or a period\n            (`'.'`).)\n    )\n\n    On POSIX, `filename` may not contain a forward slash (`'/'`) or\n    the null character (`'\\0'`).\n\n    Params:\n        filename = string to check\n\n    Returns:\n        `true` if and only if `filename` is not\n        empty, not too long, and does not contain invalid characters.\n\n*/\nbool isValidFilename(Range)(Range filename)\nif ((isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && isSomeChar!(ElementEncodingType!Range) ||\n    isNarrowString!Range) &&\n    !isConvertibleToString!Range)\n{\n    import core.stdc.stdio : FILENAME_MAX;\n    if (filename.length == 0 || filename.length >= FILENAME_MAX) return false;\n    foreach (c; filename)\n    {\n        version (Windows)\n        {\n            switch (c)\n            {\n                case 0:\n                ..\n                case 31:\n                case '<':\n                case '>':\n                case ':':\n                case '\"':\n                case '/':\n                case '\\\\':\n                case '|':\n                case '?':\n                case '*':\n                    return false;\n\n                default:\n                    break;\n            }\n        }\n        else version (Posix)\n        {\n            if (c == 0 || c == '/') return false;\n        }\n        else static assert(0);\n    }\n    version (Windows)\n    {\n        auto last = filename[filename.length - 1];\n        if (last == '.' || last == ' ') return false;\n    }\n\n    // All criteria passed\n    return true;\n}\n\n///\n@safe pure @nogc nothrow\nunittest\n{\n    import std.utf : byCodeUnit;\n\n    assert(isValidFilename(\"hello.exe\".byCodeUnit));\n}\n\nbool isValidFilename(Range)(auto ref Range filename)\nif (isConvertibleToString!Range)\n{\n    return isValidFilename!(StringTypeOf!Range)(filename);\n}\n\n@safe unittest\n{\n    assert(testAliasedString!isValidFilename(\"hello.exe\"));\n}\n\n@safe pure\nunittest\n{\n    import std.conv;\n    auto valid = [\"foo\"];\n    auto invalid = [\"\", \"foo\\0bar\", \"foo/bar\"];\n    auto pfdep = [`foo\\bar`, \"*.txt\"];\n    version (Windows) invalid ~= pfdep;\n    else version (Posix) valid ~= pfdep;\n    else static assert(0);\n\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(char[], const(char)[], string, wchar[],\n        const(wchar)[], wstring, dchar[], const(dchar)[], dstring))\n    {\n        foreach (fn; valid)\n            assert(isValidFilename(to!T(fn)));\n        foreach (fn; invalid)\n            assert(!isValidFilename(to!T(fn)));\n    }\n\n    {\n        auto r = MockRange!(immutable(char))(`dir/file.d`);\n        assert(!isValidFilename(r));\n    }\n\n    static struct DirEntry { string s; alias s this; }\n    assert(isValidFilename(DirEntry(\"file.ext\")));\n\n    version (Windows)\n    {\n        immutable string cases = \"<>:\\\"/\\\\|?*\";\n        foreach (i; 0 .. 31 + cases.length)\n        {\n            char[3] buf;\n            buf[0] = 'a';\n            buf[1] = i <= 31 ? cast(char) i : cases[i - 32];\n            buf[2] = 'b';\n            assert(!isValidFilename(buf[]));\n        }\n    }\n}\n\n\n\n/** Checks whether `path` is a valid path.\n\n    Generally, this function checks that `path` is not empty, and that\n    each component of the path either satisfies $(LREF isValidFilename)\n    or is equal to `\".\"` or `\"..\"`.\n\n    $(B It does $(I not) check whether the path points to an existing file\n    or directory; use $(REF exists, std,file) for this purpose.)\n\n    On Windows, some special rules apply:\n    $(UL\n        $(LI If the second character of `path` is a colon (`':'`),\n            the first character is interpreted as a drive letter, and\n            must be in the range A-Z (case insensitive).)\n        $(LI If `path` is on the form $(D `\\\\$(I server)\\$(I share)\\...`)\n            (UNC path), $(LREF isValidFilename) is applied to $(I server)\n            and $(I share) as well.)\n        $(LI If `path` starts with $(D `\\\\?\\`) (long UNC path), the\n            only requirement for the rest of the string is that it does\n            not contain the null character.)\n        $(LI If `path` starts with $(D `\\\\.\\`) (Win32 device namespace)\n            this function returns `false`; such paths are beyond the scope\n            of this module.)\n    )\n\n    Params:\n        path = string or Range of characters to check\n\n    Returns:\n        true if `path` is a valid path.\n*/\nbool isValidPath(Range)(Range path)\nif ((isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && isSomeChar!(ElementEncodingType!Range) ||\n    isNarrowString!Range) &&\n    !isConvertibleToString!Range)\n{\n    alias C = Unqual!(ElementEncodingType!Range);\n\n    if (path.empty) return false;\n\n    // Check whether component is \".\" or \"..\", or whether it satisfies\n    // isValidFilename.\n    bool isValidComponent(Range component)\n    {\n        assert(component.length > 0);\n        if (component[0] == '.')\n        {\n            if (component.length == 1) return true;\n            else if (component.length == 2 && component[1] == '.') return true;\n        }\n        return isValidFilename(component);\n    }\n\n    if (path.length == 1)\n        return isDirSeparator(path[0]) || isValidComponent(path);\n\n    Range remainder;\n    version (Windows)\n    {\n        if (isDirSeparator(path[0]) && isDirSeparator(path[1]))\n        {\n            // Some kind of UNC path\n            if (path.length < 5)\n            {\n                // All valid UNC paths must have at least 5 characters\n                return false;\n            }\n            else if (path[2] == '?')\n            {\n                // Long UNC path\n                if (!isDirSeparator(path[3])) return false;\n                foreach (c; path[4 .. $])\n                {\n                    if (c == '\\0') return false;\n                }\n                return true;\n            }\n            else if (path[2] == '.')\n            {\n                // Win32 device namespace not supported\n                return false;\n            }\n            else\n            {\n                // Normal UNC path, i.e. \\\\server\\share\\...\n                size_t i = 2;\n                while (i < path.length && !isDirSeparator(path[i])) ++i;\n                if (i == path.length || !isValidFilename(path[2 .. i]))\n                    return false;\n                ++i; // Skip a single dir separator\n                size_t j = i;\n                while (j < path.length && !isDirSeparator(path[j])) ++j;\n                if (!isValidFilename(path[i .. j])) return false;\n                remainder = path[j .. $];\n            }\n        }\n        else if (isDriveSeparator(path[1]))\n        {\n            import std.ascii : isAlpha;\n            if (!isAlpha(path[0])) return false;\n            remainder = path[2 .. $];\n        }\n        else\n        {\n            remainder = path;\n        }\n    }\n    else version (Posix)\n    {\n        remainder = path;\n    }\n    else static assert(0);\n    remainder = ltrimDirSeparators(remainder);\n\n    // Check that each component satisfies isValidComponent.\n    while (!remainder.empty)\n    {\n        size_t i = 0;\n        while (i < remainder.length && !isDirSeparator(remainder[i])) ++i;\n        assert(i > 0);\n        if (!isValidComponent(remainder[0 .. i])) return false;\n        remainder = ltrimDirSeparators(remainder[i .. $]);\n    }\n\n    // All criteria passed\n    return true;\n}\n\n///\n@safe pure @nogc nothrow\nunittest\n{\n    assert(isValidPath(\"/foo/bar\"));\n    assert(!isValidPath(\"/foo\\0/bar\"));\n    assert(isValidPath(\"/\"));\n    assert(isValidPath(\"a\"));\n\n    version (Windows)\n    {\n        assert(isValidPath(`c:\\`));\n        assert(isValidPath(`c:\\foo`));\n        assert(isValidPath(`c:\\foo\\.\\bar\\\\\\..\\`));\n        assert(!isValidPath(`!:\\foo`));\n        assert(!isValidPath(`c::\\foo`));\n        assert(!isValidPath(`c:\\foo?`));\n        assert(!isValidPath(`c:\\foo.`));\n\n        assert(isValidPath(`\\\\server\\share`));\n        assert(isValidPath(`\\\\server\\share\\foo`));\n        assert(isValidPath(`\\\\server\\share\\\\foo`));\n        assert(!isValidPath(`\\\\\\server\\share\\foo`));\n        assert(!isValidPath(`\\\\server\\\\share\\foo`));\n        assert(!isValidPath(`\\\\ser*er\\share\\foo`));\n        assert(!isValidPath(`\\\\server\\sha?e\\foo`));\n        assert(!isValidPath(`\\\\server\\share\\|oo`));\n\n        assert(isValidPath(`\\\\?\\<>:\"?*|/\\..\\.`));\n        assert(!isValidPath(\"\\\\\\\\?\\\\foo\\0bar\"));\n\n        assert(!isValidPath(`\\\\.\\PhysicalDisk1`));\n        assert(!isValidPath(`\\\\`));\n    }\n\n    import std.utf : byCodeUnit;\n    assert(isValidPath(\"/foo/bar\".byCodeUnit));\n}\n\nbool isValidPath(Range)(auto ref Range path)\nif (isConvertibleToString!Range)\n{\n    return isValidPath!(StringTypeOf!Range)(path);\n}\n\n@safe unittest\n{\n    assert(testAliasedString!isValidPath(\"/foo/bar\"));\n}\n\n/** Performs tilde expansion in paths on POSIX systems.\n    On Windows, this function does nothing.\n\n    There are two ways of using tilde expansion in a path. One\n    involves using the tilde alone or followed by a path separator. In\n    this case, the tilde will be expanded with the value of the\n    environment variable `HOME`.  The second way is putting\n    a username after the tilde (i.e. `~john/Mail`). Here,\n    the username will be searched for in the user database\n    (i.e. `/etc/passwd` on Unix systems) and will expand to\n    whatever path is stored there.  The username is considered the\n    string after the tilde ending at the first instance of a path\n    separator.\n\n    Note that using the `~user` syntax may give different\n    values from just `~` if the environment variable doesn't\n    match the value stored in the user database.\n\n    When the environment variable version is used, the path won't\n    be modified if the environment variable doesn't exist or it\n    is empty. When the database version is used, the path won't be\n    modified if the user doesn't exist in the database or there is\n    not enough memory to perform the query.\n\n    This function performs several memory allocations.\n\n    Params:\n        inputPath = The path name to expand.\n\n    Returns:\n    `inputPath` with the tilde expanded, or just `inputPath`\n    if it could not be expanded.\n    For Windows, `expandTilde` merely returns its argument `inputPath`.\n\n    Example:\n    -----\n    void processFile(string path)\n    {\n        // Allow calling this function with paths such as ~/foo\n        auto fullPath = expandTilde(path);\n        ...\n    }\n    -----\n*/\nstring expandTilde(string inputPath) @safe nothrow\n{\n    version (Posix)\n    {\n        import core.exception : onOutOfMemoryError;\n        import core.stdc.errno : errno, ERANGE;\n        import core.stdc.stdlib : malloc, free, realloc;\n\n        /*  Joins a path from a C string to the remainder of path.\n\n            The last path separator from c_path is discarded. The result\n            is joined to path[char_pos .. length] if char_pos is smaller\n            than length, otherwise path is not appended to c_path.\n        */\n        static string combineCPathWithDPath(char* c_path, string path, size_t char_pos) @trusted nothrow\n        {\n            import core.stdc.string : strlen;\n            import std.exception : assumeUnique;\n\n            assert(c_path != null);\n            assert(path.length > 0);\n            assert(char_pos >= 0);\n\n            // Search end of C string\n            size_t end = strlen(c_path);\n\n            // Remove trailing path separator, if any\n            if (end && isDirSeparator(c_path[end - 1]))\n                end--;\n\n            string cp;\n            if (char_pos < path.length)\n                // Append something from path\n                cp = assumeUnique(c_path[0 .. end] ~ path[char_pos .. $]);\n            else\n                // Create our own copy, as lifetime of c_path is undocumented\n                cp = c_path[0 .. end].idup;\n\n            return cp;\n        }\n\n        // Replaces the tilde from path with the environment variable HOME.\n        static string expandFromEnvironment(string path) @safe nothrow\n        {\n            import core.stdc.stdlib : getenv;\n\n            assert(path.length >= 1);\n            assert(path[0] == '~');\n\n            // Get HOME and use that to replace the tilde.\n            auto home = () @trusted { return getenv(\"HOME\"); } ();\n            if (home == null)\n                return path;\n\n            return combineCPathWithDPath(home, path, 1);\n        }\n\n        // Replaces the tilde from path with the path from the user database.\n        static string expandFromDatabase(string path) @safe nothrow\n        {\n            // bionic doesn't really support this, as getpwnam_r\n            // isn't provided and getpwnam is basically just a stub\n            version (CRuntime_Bionic)\n            {\n                return path;\n            }\n            else\n            {\n                import core.sys.posix.pwd : passwd, getpwnam_r;\n                import std.string : indexOf;\n\n                assert(path.length > 2 || (path.length == 2 && !isDirSeparator(path[1])));\n                assert(path[0] == '~');\n\n                // Extract username, searching for path separator.\n                auto last_char = indexOf(path, dirSeparator[0]);\n\n                size_t username_len = (last_char == -1) ? path.length : last_char;\n                char[] username = new char[username_len * char.sizeof];\n\n                if (last_char == -1)\n                {\n                    username[0 .. username_len - 1] = path[1 .. $];\n                    last_char = path.length + 1;\n                }\n                else\n                {\n                    username[0 .. username_len - 1] = path[1 .. last_char];\n                }\n                username[username_len - 1] = 0;\n\n                assert(last_char > 1);\n\n                // Reserve C memory for the getpwnam_r() function.\n                version (unittest)\n                    uint extra_memory_size = 2;\n                else\n                    uint extra_memory_size = 5 * 1024;\n                char[] extra_memory;\n\n                passwd result;\n                while (1)\n                {\n                    extra_memory.length += extra_memory_size;\n\n                    // Obtain info from database.\n                    passwd *verify;\n                    errno = 0;\n                    auto passResult = () @trusted { return getpwnam_r(\n                        &username[0],\n                        &result,\n                        &extra_memory[0],\n                        extra_memory.length,\n                        &verify\n                    ); } ();\n                    if (passResult == 0)\n                    {\n                        // Succeeded if verify points at result\n                        if (verify == () @trusted { return &result; } ())\n                            // username is found\n                            path = combineCPathWithDPath(result.pw_dir, path, last_char);\n                        break;\n                    }\n\n                    if (errno != ERANGE &&\n                        // On BSD and OSX, errno can be left at 0 instead of set to ERANGE\n                        errno != 0)\n                        onOutOfMemoryError();\n\n                    // extra_memory isn't large enough\n                    import core.checkedint : mulu;\n                    bool overflow;\n                    extra_memory_size = mulu(extra_memory_size, 2, overflow);\n                    if (overflow) assert(0);\n                }\n                return path;\n            }\n        }\n\n        // Return early if there is no tilde in path.\n        if (inputPath.length < 1 || inputPath[0] != '~')\n            return inputPath;\n\n        if (inputPath.length == 1 || isDirSeparator(inputPath[1]))\n            return expandFromEnvironment(inputPath);\n        else\n            return expandFromDatabase(inputPath);\n    }\n    else version (Windows)\n    {\n        // Put here real windows implementation.\n        return inputPath;\n    }\n    else\n    {\n        static assert(0); // Guard. Implement on other platforms.\n    }\n}\n\n///\n@system unittest\n{\n    version (Posix)\n    {\n        import std.process : environment;\n\n        auto oldHome = environment[\"HOME\"];\n        scope(exit) environment[\"HOME\"] = oldHome;\n\n        environment[\"HOME\"] = \"dmd/test\";\n        assert(expandTilde(\"~/\") == \"dmd/test/\");\n        assert(expandTilde(\"~\") == \"dmd/test\");\n    }\n}\n\n@system unittest\n{\n    version (Posix)\n    {\n        import std.process : executeShell, environment;\n        import std.string : strip;\n\n        // Retrieve the current home variable.\n        auto oldHome = environment.get(\"HOME\");\n\n        // Testing when there is no environment variable.\n        environment.remove(\"HOME\");\n        assert(expandTilde(\"~/\") == \"~/\");\n        assert(expandTilde(\"~\") == \"~\");\n\n        // Testing when an environment variable is set.\n        environment[\"HOME\"] = \"dmd/test\";\n        assert(expandTilde(\"~/\") == \"dmd/test/\");\n        assert(expandTilde(\"~\") == \"dmd/test\");\n\n        // The same, but with a variable ending in a slash.\n        environment[\"HOME\"] = \"dmd/test/\";\n        assert(expandTilde(\"~/\") == \"dmd/test/\");\n        assert(expandTilde(\"~\") == \"dmd/test\");\n\n        // Recover original HOME variable before continuing.\n        if (oldHome !is null) environment[\"HOME\"] = oldHome;\n        else environment.remove(\"HOME\");\n\n        immutable tildeUser = \"~\" ~ environment.get(\"USER\");\n        immutable path = executeShell(\"echo \" ~ tildeUser).output.strip();\n        immutable expTildeUser = expandTilde(tildeUser);\n        assert(expTildeUser == path, expTildeUser);\n        immutable expTildeUserSlash = expandTilde(tildeUser ~ \"/\");\n        assert(expTildeUserSlash == path ~ \"/\", expTildeUserSlash);\n\n        assert(expandTilde(\"~Idontexist/hey\") == \"~Idontexist/hey\");\n    }\n}\n\nversion (unittest)\n{\nprivate:\n    /* Define a mock RandomAccessRange to use for unittesting.\n     */\n\n    struct MockRange(C)\n    {\n        this(C[] array) { this.array = array; }\n      const\n      {\n        @property size_t length() { return array.length; }\n        @property bool empty() { return array.length == 0; }\n        @property C front() { return array[0]; }\n        @property C back()  { return array[$ - 1]; }\n        @property size_t opDollar() { return length; }\n        C opIndex(size_t i) { return array[i]; }\n      }\n        void popFront() { array = array[1 .. $]; }\n        void popBack()  { array = array[0 .. $-1]; }\n        MockRange!C opSlice( size_t lwr, size_t upr) const\n        {\n            return MockRange!C(array[lwr .. upr]);\n        }\n        @property MockRange save() { return this; }\n      private:\n        C[] array;\n    }\n\n    /* Define a mock BidirectionalRange to use for unittesting.\n     */\n\n    struct MockBiRange(C)\n    {\n        this(const(C)[] array) { this.array = array; }\n        const\n        {\n            @property bool empty() { return array.length == 0; }\n            @property C front() { return array[0]; }\n            @property C back()  { return array[$ - 1]; }\n            @property size_t opDollar() { return array.length; }\n        }\n        void popFront() { array = array[1 .. $]; }\n        void popBack()  { array = array[0 .. $-1]; }\n        @property MockBiRange save() { return this; }\n      private:\n        const(C)[] array;\n    }\n\n}\n\n@safe unittest\n{\n    static assert( isRandomAccessRange!(MockRange!(const(char))) );\n    static assert( isBidirectionalRange!(MockBiRange!(const(char))) );\n}\n\nprivate template BaseOf(R)\n{\n    static if (isRandomAccessRange!R && isSomeChar!(ElementType!R))\n        alias BaseOf = R;\n    else\n        alias BaseOf = StringTypeOf!R;\n}\n"
  },
  {
    "path": "libphobos/src/std/process.d",
    "content": "// Written in the D programming language.\n\n/**\nFunctions for starting and interacting with other processes, and for\nworking with the current process' execution environment.\n\nProcess_handling:\n$(UL $(LI\n    $(LREF spawnProcess) spawns a new process, optionally assigning it an\n    arbitrary set of standard input, output, and error streams.\n    The function returns immediately, leaving the child process to execute\n    in parallel with its parent.  All other functions in this module that\n    spawn processes are built around `spawnProcess`.)\n$(LI\n    $(LREF wait) makes the parent process wait for a child process to\n    terminate.  In general one should always do this, to avoid\n    child processes becoming \"zombies\" when the parent process exits.\n    Scope guards are perfect for this – see the $(LREF spawnProcess)\n    documentation for examples.  $(LREF tryWait) is similar to `wait`,\n    but does not block if the process has not yet terminated.)\n$(LI\n    $(LREF pipeProcess) also spawns a child process which runs\n    in parallel with its parent.  However, instead of taking\n    arbitrary streams, it automatically creates a set of\n    pipes that allow the parent to communicate with the child\n    through the child's standard input, output, and/or error streams.\n    This function corresponds roughly to C's `popen` function.)\n$(LI\n    $(LREF execute) starts a new process and waits for it\n    to complete before returning.  Additionally, it captures\n    the process' standard output and error streams and returns\n    the output of these as a string.)\n$(LI\n    $(LREF spawnShell), $(LREF pipeShell) and $(LREF executeShell) work like\n    `spawnProcess`, `pipeProcess` and `execute`, respectively,\n    except that they take a single command string and run it through\n    the current user's default command interpreter.\n    `executeShell` corresponds roughly to C's `system` function.)\n$(LI\n    $(LREF kill) attempts to terminate a running process.)\n)\n\nThe following table compactly summarises the different process creation\nfunctions and how they relate to each other:\n$(BOOKTABLE,\n    $(TR $(TH )\n         $(TH Runs program directly)\n         $(TH Runs shell command))\n    $(TR $(TD Low-level process creation)\n         $(TD $(LREF spawnProcess))\n         $(TD $(LREF spawnShell)))\n    $(TR $(TD Automatic input/output redirection using pipes)\n         $(TD $(LREF pipeProcess))\n         $(TD $(LREF pipeShell)))\n    $(TR $(TD Execute and wait for completion, collect output)\n         $(TD $(LREF execute))\n         $(TD $(LREF executeShell)))\n)\n\nOther_functionality:\n$(UL\n$(LI\n    $(LREF pipe) is used to create unidirectional pipes.)\n$(LI\n    $(LREF environment) is an interface through which the current process'\n    environment variables can be read and manipulated.)\n$(LI\n    $(LREF escapeShellCommand) and $(LREF escapeShellFileName) are useful\n    for constructing shell command lines in a portable way.)\n)\n\nAuthors:\n    $(LINK2 https://github.com/kyllingstad, Lars Tandle Kyllingstad),\n    $(LINK2 https://github.com/schveiguy, Steven Schveighoffer),\n    $(HTTP thecybershadow.net, Vladimir Panteleev)\nCopyright:\n    Copyright (c) 2013, the authors. All rights reserved.\nLicense:\n   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nSource:\n    $(PHOBOSSRC std/process.d)\nMacros:\n    OBJECTREF=$(REF1 $0, object)\n*/\nmodule std.process;\n\nversion (Posix)\n{\n    import core.sys.posix.sys.wait;\n    import core.sys.posix.unistd;\n}\nversion (Windows)\n{\n    import core.stdc.stdio;\n    import core.sys.windows.windows;\n    import std.utf;\n    import std.windows.syserror;\n}\n\nimport std.internal.cstring;\nimport std.range.primitives;\nimport std.stdio;\n\n\n// When the DMC runtime is used, we have to use some custom functions\n// to convert between Windows file handles and FILE*s.\nversion (Win32) version (CRuntime_DigitalMars) version = DMC_RUNTIME;\n\n\n// Some of the following should be moved to druntime.\nprivate\n{\n    // Microsoft Visual C Runtime (MSVCRT) declarations.\n    version (Windows)\n    {\n        version (DMC_RUNTIME) { } else\n        {\n            import core.stdc.stdint;\n            enum\n            {\n                STDIN_FILENO  = 0,\n                STDOUT_FILENO = 1,\n                STDERR_FILENO = 2,\n            }\n        }\n    }\n\n    // POSIX API declarations.\n    version (Posix)\n    {\n        version (OSX)\n        {\n            extern(C) char*** _NSGetEnviron() nothrow;\n            const(char**) getEnvironPtr() @trusted\n            {\n                return *_NSGetEnviron;\n            }\n        }\n        else\n        {\n            // Made available by the C runtime:\n            extern(C) extern __gshared const char** environ;\n            const(char**) getEnvironPtr() @trusted\n            {\n                return environ;\n            }\n        }\n\n        @system unittest\n        {\n            new Thread({assert(getEnvironPtr !is null);}).start();\n        }\n    }\n} // private\n\n\n// =============================================================================\n// Functions and classes for process management.\n// =============================================================================\n\n\n/**\nSpawns a new process, optionally assigning it an arbitrary set of standard\ninput, output, and error streams.\n\nThe function returns immediately, leaving the child process to execute\nin parallel with its parent.  It is recommended to always call $(LREF wait)\non the returned $(LREF Pid) unless the process was spawned with\n`Config.detached` flag, as detailed in the documentation for `wait`.\n\nCommand_line:\nThere are four overloads of this function.  The first two take an array\nof strings, `args`, which should contain the program name as the\nzeroth element and any command-line arguments in subsequent elements.\nThe third and fourth versions are included for convenience, and may be\nused when there are no command-line arguments.  They take a single string,\n`program`, which specifies the program name.\n\nUnless a directory is specified in `args[0]` or `program`,\n`spawnProcess` will search for the program in a platform-dependent\nmanner.  On POSIX systems, it will look for the executable in the\ndirectories listed in the PATH environment variable, in the order\nthey are listed.  On Windows, it will search for the executable in\nthe following sequence:\n$(OL\n    $(LI The directory from which the application loaded.)\n    $(LI The current directory for the parent process.)\n    $(LI The 32-bit Windows system directory.)\n    $(LI The 16-bit Windows system directory.)\n    $(LI The Windows directory.)\n    $(LI The directories listed in the PATH environment variable.)\n)\n---\n// Run an executable called \"prog\" located in the current working\n// directory:\nauto pid = spawnProcess(\"./prog\");\nscope(exit) wait(pid);\n// We can do something else while the program runs.  The scope guard\n// ensures that the process is waited for at the end of the scope.\n...\n\n// Run DMD on the file \"myprog.d\", specifying a few compiler switches:\nauto dmdPid = spawnProcess([\"dmd\", \"-O\", \"-release\", \"-inline\", \"myprog.d\" ]);\nif (wait(dmdPid) != 0)\n    writeln(\"Compilation failed!\");\n---\n\nEnvironment_variables:\nBy default, the child process inherits the environment of the parent\nprocess, along with any additional variables specified in the `env`\nparameter.  If the same variable exists in both the parent's environment\nand in `env`, the latter takes precedence.\n\nIf the $(LREF Config.newEnv) flag is set in `config`, the child\nprocess will $(I not) inherit the parent's environment.  Its entire\nenvironment will then be determined by `env`.\n---\nwait(spawnProcess(\"myapp\", [\"foo\" : \"bar\"], Config.newEnv));\n---\n\nStandard_streams:\nThe optional arguments `stdin`, `stdout` and `stderr` may\nbe used to assign arbitrary $(REF File, std,stdio) objects as the standard\ninput, output and error streams, respectively, of the child process.  The\nformer must be opened for reading, while the latter two must be opened for\nwriting.  The default is for the child process to inherit the standard\nstreams of its parent.\n---\n// Run DMD on the file myprog.d, logging any error messages to a\n// file named errors.log.\nauto logFile = File(\"errors.log\", \"w\");\nauto pid = spawnProcess([\"dmd\", \"myprog.d\"],\n                        std.stdio.stdin,\n                        std.stdio.stdout,\n                        logFile);\nif (wait(pid) != 0)\n    writeln(\"Compilation failed. See errors.log for details.\");\n---\n\nNote that if you pass a `File` object that is $(I not)\none of the standard input/output/error streams of the parent process,\nthat stream will by default be $(I closed) in the parent process when\nthis function returns.  See the $(LREF Config) documentation below for\ninformation about how to disable this behaviour.\n\nBeware of buffering issues when passing `File` objects to\n`spawnProcess`.  The child process will inherit the low-level raw\nread/write offset associated with the underlying file descriptor, but\nit will not be aware of any buffered data.  In cases where this matters\n(e.g. when a file should be aligned before being passed on to the\nchild process), it may be a good idea to use unbuffered streams, or at\nleast ensure all relevant buffers are flushed.\n\nParams:\nargs    = An array which contains the program name as the zeroth element\n          and any command-line arguments in the following elements.\nstdin   = The standard input stream of the child process.\n          This can be any $(REF File, std,stdio) that is opened for reading.\n          By default the child process inherits the parent's input\n          stream.\nstdout  = The standard output stream of the child process.\n          This can be any $(REF File, std,stdio) that is opened for writing.\n          By default the child process inherits the parent's output stream.\nstderr  = The standard error stream of the child process.\n          This can be any $(REF File, std,stdio) that is opened for writing.\n          By default the child process inherits the parent's error stream.\nenv     = Additional environment variables for the child process.\nconfig  = Flags that control process creation. See $(LREF Config)\n          for an overview of available flags.\nworkDir = The working directory for the new process.\n          By default the child process inherits the parent's working\n          directory.\n\nReturns:\nA $(LREF Pid) object that corresponds to the spawned process.\n\nThrows:\n$(LREF ProcessException) on failure to start the process.$(BR)\n$(REF StdioException, std,stdio) on failure to pass one of the streams\n    to the child process (Windows only).$(BR)\n$(REF RangeError, core,exception) if `args` is empty.\n*/\nPid spawnProcess(scope const(char[])[] args,\n                 File stdin = std.stdio.stdin,\n                 File stdout = std.stdio.stdout,\n                 File stderr = std.stdio.stderr,\n                 const string[string] env = null,\n                 Config config = Config.none,\n                 scope const char[] workDir = null)\n    @trusted // TODO: Should be @safe\n{\n    version (Windows)    auto  args2 = escapeShellArguments(args);\n    else version (Posix) alias args2 = args;\n    return spawnProcessImpl(args2, stdin, stdout, stderr, env, config, workDir);\n}\n\n/// ditto\nPid spawnProcess(scope const(char[])[] args,\n                 const string[string] env,\n                 Config config = Config.none,\n                 scope const(char)[] workDir = null)\n    @trusted // TODO: Should be @safe\n{\n    return spawnProcess(args,\n                        std.stdio.stdin,\n                        std.stdio.stdout,\n                        std.stdio.stderr,\n                        env,\n                        config,\n                        workDir);\n}\n\n/// ditto\nPid spawnProcess(scope const(char)[] program,\n                 File stdin = std.stdio.stdin,\n                 File stdout = std.stdio.stdout,\n                 File stderr = std.stdio.stderr,\n                 const string[string] env = null,\n                 Config config = Config.none,\n                 scope const(char)[] workDir = null)\n    @trusted\n{\n    return spawnProcess((&program)[0 .. 1],\n                        stdin, stdout, stderr, env, config, workDir);\n}\n\n/// ditto\nPid spawnProcess(scope const(char)[] program,\n                 const string[string] env,\n                 Config config = Config.none,\n                 scope const(char)[] workDir = null)\n    @trusted\n{\n    return spawnProcess((&program)[0 .. 1], env, config, workDir);\n}\n\nversion (Posix) private enum InternalError : ubyte\n{\n    noerror,\n    exec,\n    chdir,\n    getrlimit,\n    doubleFork,\n}\n\n/*\nImplementation of spawnProcess() for POSIX.\n\nenvz should be a zero-terminated array of zero-terminated strings\non the form \"var=value\".\n*/\nversion (Posix)\nprivate Pid spawnProcessImpl(scope const(char[])[] args,\n                             File stdin,\n                             File stdout,\n                             File stderr,\n                             scope const string[string] env,\n                             Config config,\n                             scope const(char)[] workDir)\n    @trusted // TODO: Should be @safe\n{\n    import core.exception : RangeError;\n    import std.algorithm.searching : any;\n    import std.conv : text;\n    import std.path : isDirSeparator;\n    import std.string : toStringz;\n\n    if (args.empty) throw new RangeError();\n    const(char)[] name = args[0];\n    if (any!isDirSeparator(name))\n    {\n        if (!isExecutable(name))\n            throw new ProcessException(text(\"Not an executable file: \", name));\n    }\n    else\n    {\n        name = searchPathFor(name);\n        if (name is null)\n            throw new ProcessException(text(\"Executable file not found: \", args[0]));\n    }\n\n    // Convert program name and arguments to C-style strings.\n    auto argz = new const(char)*[args.length+1];\n    argz[0] = toStringz(name);\n    foreach (i; 1 .. args.length) argz[i] = toStringz(args[i]);\n    argz[$-1] = null;\n\n    // Prepare environment.\n    auto envz = createEnv(env, !(config & Config.newEnv));\n\n    // Open the working directory.\n    // We use open in the parent and fchdir in the child\n    // so that most errors (directory doesn't exist, not a directory)\n    // can be propagated as exceptions before forking.\n    int workDirFD = -1;\n    scope(exit) if (workDirFD >= 0) close(workDirFD);\n    if (workDir.length)\n    {\n        import core.sys.posix.fcntl : open, O_RDONLY, stat_t, fstat, S_ISDIR;\n        workDirFD = open(workDir.tempCString(), O_RDONLY);\n        if (workDirFD < 0)\n            throw ProcessException.newFromErrno(\"Failed to open working directory\");\n        stat_t s;\n        if (fstat(workDirFD, &s) < 0)\n            throw ProcessException.newFromErrno(\"Failed to stat working directory\");\n        if (!S_ISDIR(s.st_mode))\n            throw new ProcessException(\"Not a directory: \" ~ cast(string) workDir);\n    }\n\n    static int getFD(ref File f) { return core.stdc.stdio.fileno(f.getFP()); }\n\n    // Get the file descriptors of the streams.\n    // These could potentially be invalid, but that is OK.  If so, later calls\n    // to dup2() and close() will just silently fail without causing any harm.\n    auto stdinFD  = getFD(stdin);\n    auto stdoutFD = getFD(stdout);\n    auto stderrFD = getFD(stderr);\n\n    // We don't have direct access to the errors that may happen in a child process.\n    // So we use this pipe to deliver them.\n    int[2] forkPipe;\n    if (core.sys.posix.unistd.pipe(forkPipe) == 0)\n        setCLOEXEC(forkPipe[1], true);\n    else\n        throw ProcessException.newFromErrno(\"Could not create pipe to check startup of child\");\n    scope(exit) close(forkPipe[0]);\n\n    /*\n    To create detached process, we use double fork technique\n    but we don't have a direct access to the second fork pid from the caller side thus use a pipe.\n    We also can't reuse forkPipe for that purpose\n    because we can't predict the order in which pid and possible error will be written\n    since the first and the second forks will run in parallel.\n    */\n    int[2] pidPipe;\n    if (config & Config.detached)\n    {\n        if (core.sys.posix.unistd.pipe(pidPipe) != 0)\n            throw ProcessException.newFromErrno(\"Could not create pipe to get process pid\");\n        setCLOEXEC(pidPipe[1], true);\n    }\n    scope(exit) if (config & Config.detached) close(pidPipe[0]);\n\n    static void abortOnError(int forkPipeOut, InternalError errorType, int error) nothrow\n    {\n        core.sys.posix.unistd.write(forkPipeOut, &errorType, errorType.sizeof);\n        core.sys.posix.unistd.write(forkPipeOut, &error, error.sizeof);\n        close(forkPipeOut);\n        core.sys.posix.unistd._exit(1);\n        assert(0);\n    }\n\n    void closePipeWriteEnds()\n    {\n        close(forkPipe[1]);\n        if (config & Config.detached)\n            close(pidPipe[1]);\n    }\n\n    auto id = core.sys.posix.unistd.fork();\n    if (id < 0)\n    {\n        closePipeWriteEnds();\n        throw ProcessException.newFromErrno(\"Failed to spawn new process\");\n    }\n\n    void forkChild() nothrow @nogc\n    {\n        static import core.sys.posix.stdio;\n        pragma(inline, true);\n\n        // Child process\n\n        // no need for the read end of pipe on child side\n        if (config & Config.detached)\n            close(pidPipe[0]);\n        close(forkPipe[0]);\n        immutable forkPipeOut = forkPipe[1];\n        immutable pidPipeOut = pidPipe[1];\n\n        // Set the working directory.\n        if (workDirFD >= 0)\n        {\n            if (fchdir(workDirFD) < 0)\n            {\n                // Fail. It is dangerous to run a program\n                // in an unexpected working directory.\n                abortOnError(forkPipeOut, InternalError.chdir, .errno);\n            }\n            close(workDirFD);\n        }\n\n        void execProcess()\n        {\n            // Redirect streams and close the old file descriptors.\n            // In the case that stderr is redirected to stdout, we need\n            // to backup the file descriptor since stdout may be redirected\n            // as well.\n            if (stderrFD == STDOUT_FILENO) stderrFD = dup(stderrFD);\n            dup2(stdinFD,  STDIN_FILENO);\n            dup2(stdoutFD, STDOUT_FILENO);\n            dup2(stderrFD, STDERR_FILENO);\n\n            // Ensure that the standard streams aren't closed on execute, and\n            // optionally close all other file descriptors.\n            setCLOEXEC(STDIN_FILENO, false);\n            setCLOEXEC(STDOUT_FILENO, false);\n            setCLOEXEC(STDERR_FILENO, false);\n\n            if (!(config & Config.inheritFDs))\n            {\n                import core.stdc.stdlib : malloc;\n                import core.sys.posix.poll : pollfd, poll, POLLNVAL;\n                import core.sys.posix.sys.resource : rlimit, getrlimit, RLIMIT_NOFILE;\n\n                // Get the maximum number of file descriptors that could be open.\n                rlimit r;\n                if (getrlimit(RLIMIT_NOFILE, &r) != 0)\n                {\n                    abortOnError(forkPipeOut, InternalError.getrlimit, .errno);\n                }\n                immutable maxDescriptors = cast(int) r.rlim_cur;\n\n                // The above, less stdin, stdout, and stderr\n                immutable maxToClose = maxDescriptors - 3;\n\n                // Call poll() to see which ones are actually open:\n                auto pfds = cast(pollfd*) malloc(pollfd.sizeof * maxToClose);\n                foreach (i; 0 .. maxToClose)\n                {\n                    pfds[i].fd = i + 3;\n                    pfds[i].events = 0;\n                    pfds[i].revents = 0;\n                }\n                if (poll(pfds, maxToClose, 0) >= 0)\n                {\n                    foreach (i; 0 .. maxToClose)\n                    {\n                        // don't close pipe write end\n                        if (pfds[i].fd == forkPipeOut) continue;\n                        // POLLNVAL will be set if the file descriptor is invalid.\n                        if (!(pfds[i].revents & POLLNVAL)) close(pfds[i].fd);\n                    }\n                }\n                else\n                {\n                    // Fall back to closing everything.\n                    foreach (i; 3 .. maxDescriptors)\n                    {\n                        if (i == forkPipeOut) continue;\n                        close(i);\n                    }\n                }\n            }\n            else // This is already done if we don't inherit descriptors.\n            {\n                // Close the old file descriptors, unless they are\n                // either of the standard streams.\n                if (stdinFD  > STDERR_FILENO)  close(stdinFD);\n                if (stdoutFD > STDERR_FILENO)  close(stdoutFD);\n                if (stderrFD > STDERR_FILENO)  close(stderrFD);\n            }\n\n            // Execute program.\n            core.sys.posix.unistd.execve(argz[0], argz.ptr, envz);\n\n            // If execution fails, exit as quickly as possible.\n            abortOnError(forkPipeOut, InternalError.exec, .errno);\n        }\n\n        if (config & Config.detached)\n        {\n            auto secondFork = core.sys.posix.unistd.fork();\n            if (secondFork == 0)\n            {\n                close(pidPipeOut);\n                execProcess();\n            }\n            else if (secondFork == -1)\n            {\n                auto secondForkErrno = .errno;\n                close(pidPipeOut);\n                abortOnError(forkPipeOut, InternalError.doubleFork, secondForkErrno);\n            }\n            else\n            {\n                core.sys.posix.unistd.write(pidPipeOut, &secondFork, pid_t.sizeof);\n                close(pidPipeOut);\n                close(forkPipeOut);\n                _exit(0);\n            }\n        }\n        else\n        {\n            execProcess();\n        }\n    }\n\n    if (id == 0)\n    {\n        forkChild();\n        assert(0);\n    }\n    else\n    {\n        closePipeWriteEnds();\n        auto status = InternalError.noerror;\n        auto readExecResult = core.sys.posix.unistd.read(forkPipe[0], &status, status.sizeof);\n        // Save error number just in case if subsequent \"waitpid\" fails and overrides errno\n        immutable lastError = .errno;\n\n        if (config & Config.detached)\n        {\n            // Forked child exits right after creating second fork. So it should be safe to wait here.\n            import core.sys.posix.sys.wait : waitpid;\n            int waitResult;\n            waitpid(id, &waitResult, 0);\n        }\n\n        if (readExecResult == -1)\n            throw ProcessException.newFromErrno(lastError, \"Could not read from pipe to get child status\");\n\n        bool owned = true;\n        if (status != InternalError.noerror)\n        {\n            int error;\n            readExecResult = read(forkPipe[0], &error, error.sizeof);\n            string errorMsg;\n            final switch (status)\n            {\n                case InternalError.chdir:\n                    errorMsg = \"Failed to set working directory\";\n                    break;\n                case InternalError.getrlimit:\n                    errorMsg = \"getrlimit failed\";\n                    break;\n                case InternalError.exec:\n                    errorMsg = \"Failed to execute program\";\n                    break;\n                case InternalError.doubleFork:\n                    // Can happen only when starting detached process\n                    assert(config & Config.detached);\n                    errorMsg = \"Failed to fork twice\";\n                    break;\n                case InternalError.noerror:\n                    assert(false);\n            }\n            if (readExecResult == error.sizeof)\n                throw ProcessException.newFromErrno(error, errorMsg);\n            throw new ProcessException(errorMsg);\n        }\n        else if (config & Config.detached)\n        {\n            owned = false;\n            if (read(pidPipe[0], &id, id.sizeof) != id.sizeof)\n                throw ProcessException.newFromErrno(\"Could not read from pipe to get detached process id\");\n        }\n\n        // Parent process:  Close streams and return.\n        if (!(config & Config.retainStdin ) && stdinFD  > STDERR_FILENO\n                                            && stdinFD  != getFD(std.stdio.stdin ))\n            stdin.close();\n        if (!(config & Config.retainStdout) && stdoutFD > STDERR_FILENO\n                                            && stdoutFD != getFD(std.stdio.stdout))\n            stdout.close();\n        if (!(config & Config.retainStderr) && stderrFD > STDERR_FILENO\n                                            && stderrFD != getFD(std.stdio.stderr))\n            stderr.close();\n        return new Pid(id, owned);\n    }\n}\n\n/*\nImplementation of spawnProcess() for Windows.\n\ncommandLine must contain the entire command line, properly\nquoted/escaped as required by CreateProcessW().\n\nenvz must be a pointer to a block of UTF-16 characters on the form\n\"var1=value1\\0var2=value2\\0...varN=valueN\\0\\0\".\n*/\nversion (Windows)\nprivate Pid spawnProcessImpl(scope const(char)[] commandLine,\n                             File stdin,\n                             File stdout,\n                             File stderr,\n                             const string[string] env,\n                             Config config,\n                             scope const(char)[] workDir)\n    @trusted\n{\n    import core.exception : RangeError;\n\n    if (commandLine.empty) throw new RangeError(\"Command line is empty\");\n\n    // Prepare environment.\n    auto envz = createEnv(env, !(config & Config.newEnv));\n\n    // Startup info for CreateProcessW().\n    STARTUPINFO_W startinfo;\n    startinfo.cb = startinfo.sizeof;\n    static int getFD(ref File f) { return f.isOpen ? f.fileno : -1; }\n\n    // Extract file descriptors and HANDLEs from the streams and make the\n    // handles inheritable.\n    static void prepareStream(ref File file, DWORD stdHandle, string which,\n                              out int fileDescriptor, out HANDLE handle)\n    {\n        enum _NO_CONSOLE_FILENO = cast(HANDLE)-2;\n        fileDescriptor = getFD(file);\n        handle = null;\n        if (fileDescriptor >= 0)\n            handle = file.windowsHandle;\n        // Windows GUI applications have a fd but not a valid Windows HANDLE.\n        if (handle is null || handle == INVALID_HANDLE_VALUE || handle == _NO_CONSOLE_FILENO)\n            handle = GetStdHandle(stdHandle);\n\n        DWORD dwFlags;\n        if (GetHandleInformation(handle, &dwFlags))\n        {\n            if (!(dwFlags & HANDLE_FLAG_INHERIT))\n            {\n                if (!SetHandleInformation(handle,\n                                          HANDLE_FLAG_INHERIT,\n                                          HANDLE_FLAG_INHERIT))\n                {\n                    throw new StdioException(\n                        \"Failed to make \"~which~\" stream inheritable by child process (\"\n                        ~sysErrorString(GetLastError()) ~ ')',\n                        0);\n                }\n            }\n        }\n    }\n    int stdinFD = -1, stdoutFD = -1, stderrFD = -1;\n    prepareStream(stdin,  STD_INPUT_HANDLE,  \"stdin\" , stdinFD,  startinfo.hStdInput );\n    prepareStream(stdout, STD_OUTPUT_HANDLE, \"stdout\", stdoutFD, startinfo.hStdOutput);\n    prepareStream(stderr, STD_ERROR_HANDLE,  \"stderr\", stderrFD, startinfo.hStdError );\n\n    if ((startinfo.hStdInput  != null && startinfo.hStdInput  != INVALID_HANDLE_VALUE)\n     || (startinfo.hStdOutput != null && startinfo.hStdOutput != INVALID_HANDLE_VALUE)\n     || (startinfo.hStdError  != null && startinfo.hStdError  != INVALID_HANDLE_VALUE))\n        startinfo.dwFlags = STARTF_USESTDHANDLES;\n\n    // Create process.\n    PROCESS_INFORMATION pi;\n    DWORD dwCreationFlags =\n        CREATE_UNICODE_ENVIRONMENT |\n        ((config & Config.suppressConsole) ? CREATE_NO_WINDOW : 0);\n    auto pworkDir = workDir.tempCStringW();     // workaround until Bugzilla 14696 is fixed\n    if (!CreateProcessW(null, commandLine.tempCStringW().buffPtr, null, null, true, dwCreationFlags,\n                        envz, workDir.length ? pworkDir : null, &startinfo, &pi))\n        throw ProcessException.newFromLastError(\"Failed to spawn new process\");\n\n    // figure out if we should close any of the streams\n    if (!(config & Config.retainStdin ) && stdinFD  > STDERR_FILENO\n                                        && stdinFD  != getFD(std.stdio.stdin ))\n        stdin.close();\n    if (!(config & Config.retainStdout) && stdoutFD > STDERR_FILENO\n                                        && stdoutFD != getFD(std.stdio.stdout))\n        stdout.close();\n    if (!(config & Config.retainStderr) && stderrFD > STDERR_FILENO\n                                        && stderrFD != getFD(std.stdio.stderr))\n        stderr.close();\n\n    // close the thread handle in the process info structure\n    CloseHandle(pi.hThread);\n    if (config & Config.detached)\n    {\n        CloseHandle(pi.hProcess);\n        return new Pid(pi.dwProcessId);\n    }\n    return new Pid(pi.dwProcessId, pi.hProcess);\n}\n\n// Converts childEnv to a zero-terminated array of zero-terminated strings\n// on the form \"name=value\", optionally adding those of the current process'\n// environment strings that are not present in childEnv.  If the parent's\n// environment should be inherited without modification, this function\n// returns environ directly.\nversion (Posix)\nprivate const(char*)* createEnv(const string[string] childEnv,\n                                bool mergeWithParentEnv)\n{\n    // Determine the number of strings in the parent's environment.\n    int parentEnvLength = 0;\n    auto environ = getEnvironPtr;\n    if (mergeWithParentEnv)\n    {\n        if (childEnv.length == 0) return environ;\n        while (environ[parentEnvLength] != null) ++parentEnvLength;\n    }\n\n    // Convert the \"new\" variables to C-style strings.\n    auto envz = new const(char)*[parentEnvLength + childEnv.length + 1];\n    int pos = 0;\n    foreach (var, val; childEnv)\n        envz[pos++] = (var~'='~val~'\\0').ptr;\n\n    // Add the parent's environment.\n    foreach (environStr; environ[0 .. parentEnvLength])\n    {\n        int eqPos = 0;\n        while (environStr[eqPos] != '=' && environStr[eqPos] != '\\0') ++eqPos;\n        if (environStr[eqPos] != '=') continue;\n        auto var = environStr[0 .. eqPos];\n        if (var in childEnv) continue;\n        envz[pos++] = environStr;\n    }\n    envz[pos] = null;\n    return envz.ptr;\n}\n\nversion (Posix) @system unittest\n{\n    auto e1 = createEnv(null, false);\n    assert(e1 != null && *e1 == null);\n\n    auto e2 = createEnv(null, true);\n    assert(e2 != null);\n    int i = 0;\n    auto environ = getEnvironPtr;\n    for (; environ[i] != null; ++i)\n    {\n        assert(e2[i] != null);\n        import core.stdc.string;\n        assert(strcmp(e2[i], environ[i]) == 0);\n    }\n    assert(e2[i] == null);\n\n    auto e3 = createEnv([\"foo\" : \"bar\", \"hello\" : \"world\"], false);\n    assert(e3 != null && e3[0] != null && e3[1] != null && e3[2] == null);\n    assert((e3[0][0 .. 8] == \"foo=bar\\0\" && e3[1][0 .. 12] == \"hello=world\\0\")\n         || (e3[0][0 .. 12] == \"hello=world\\0\" && e3[1][0 .. 8] == \"foo=bar\\0\"));\n}\n\n\n// Converts childEnv to a Windows environment block, which is on the form\n// \"name1=value1\\0name2=value2\\0...nameN=valueN\\0\\0\", optionally adding\n// those of the current process' environment strings that are not present\n// in childEnv.  Returns null if the parent's environment should be\n// inherited without modification, as this is what is expected by\n// CreateProcess().\nversion (Windows)\nprivate LPVOID createEnv(const string[string] childEnv,\n                         bool mergeWithParentEnv)\n{\n    if (mergeWithParentEnv && childEnv.length == 0) return null;\n    import std.array : appender;\n    import std.uni : toUpper;\n    auto envz = appender!(wchar[])();\n    void put(string var, string val)\n    {\n        envz.put(var);\n        envz.put('=');\n        envz.put(val);\n        envz.put(cast(wchar) '\\0');\n    }\n\n    // Add the variables in childEnv, removing them from parentEnv\n    // if they exist there too.\n    auto parentEnv = mergeWithParentEnv ? environment.toAA() : null;\n    foreach (k, v; childEnv)\n    {\n        auto uk = toUpper(k);\n        put(uk, v);\n        if (uk in parentEnv) parentEnv.remove(uk);\n    }\n\n    // Add remaining parent environment variables.\n    foreach (k, v; parentEnv) put(k, v);\n\n    // Two final zeros are needed in case there aren't any environment vars,\n    // and the last one does no harm when there are.\n    envz.put(\"\\0\\0\"w);\n    return envz.data.ptr;\n}\n\nversion (Windows) @system unittest\n{\n    assert(createEnv(null, true) == null);\n    assert((cast(wchar*) createEnv(null, false))[0 .. 2] == \"\\0\\0\"w);\n    auto e1 = (cast(wchar*) createEnv([\"foo\":\"bar\", \"ab\":\"c\"], false))[0 .. 14];\n    assert(e1 == \"FOO=bar\\0AB=c\\0\\0\"w || e1 == \"AB=c\\0FOO=bar\\0\\0\"w);\n}\n\n// Searches the PATH variable for the given executable file,\n// (checking that it is in fact executable).\nversion (Posix)\nprivate string searchPathFor(scope const(char)[] executable)\n    @trusted //TODO: @safe nothrow\n{\n    import std.algorithm.iteration : splitter;\n    import std.conv : to;\n    import std.path : buildPath;\n\n    auto pathz = core.stdc.stdlib.getenv(\"PATH\");\n    if (pathz == null)  return null;\n\n    foreach (dir; splitter(to!string(pathz), ':'))\n    {\n        auto execPath = buildPath(dir, executable);\n        if (isExecutable(execPath))  return execPath;\n    }\n\n    return null;\n}\n\n// Checks whether the file exists and can be executed by the\n// current user.\nversion (Posix)\nprivate bool isExecutable(scope const(char)[] path) @trusted nothrow @nogc //TODO: @safe\n{\n    return (access(path.tempCString(), X_OK) == 0);\n}\n\nversion (Posix) @safe unittest\n{\n    import std.algorithm;\n    auto lsPath = searchPathFor(\"ls\");\n    assert(!lsPath.empty);\n    assert(lsPath[0] == '/');\n    assert(lsPath.endsWith(\"ls\"));\n    auto unlikely = searchPathFor(\"lkmqwpoialhggyaofijadsohufoiqezm\");\n    assert(unlikely is null, \"Are you kidding me?\");\n}\n\n// Sets or unsets the FD_CLOEXEC flag on the given file descriptor.\nversion (Posix)\nprivate void setCLOEXEC(int fd, bool on) nothrow @nogc\n{\n    import core.sys.posix.fcntl : fcntl, F_GETFD, FD_CLOEXEC, F_SETFD;\n    auto flags = fcntl(fd, F_GETFD);\n    if (flags >= 0)\n    {\n        if (on) flags |= FD_CLOEXEC;\n        else    flags &= ~(cast(typeof(flags)) FD_CLOEXEC);\n        flags = fcntl(fd, F_SETFD, flags);\n    }\n    assert(flags != -1 || .errno == EBADF);\n}\n\n@system unittest // Command line arguments in spawnProcess().\n{\n    version (Windows) TestScript prog =\n       \"if not [%~1]==[foo] ( exit 1 )\n        if not [%~2]==[bar] ( exit 2 )\n        exit 0\";\n    else version (Posix) TestScript prog =\n       `if test \"$1\" != \"foo\"; then exit 1; fi\n        if test \"$2\" != \"bar\"; then exit 2; fi\n        exit 0`;\n    assert(wait(spawnProcess(prog.path)) == 1);\n    assert(wait(spawnProcess([prog.path])) == 1);\n    assert(wait(spawnProcess([prog.path, \"foo\"])) == 2);\n    assert(wait(spawnProcess([prog.path, \"foo\", \"baz\"])) == 2);\n    assert(wait(spawnProcess([prog.path, \"foo\", \"bar\"])) == 0);\n}\n\n// test that file descriptors are correctly closed / left open.\n// ideally this would be done by the child process making libc\n// calls, but we make do...\nversion (Posix) @system unittest\n{\n    import core.sys.posix.fcntl : open, O_RDONLY;\n    import core.sys.posix.unistd : close;\n    import std.algorithm.searching : canFind, findSplitBefore;\n    import std.array : split;\n    import std.conv : to;\n    static import std.file;\n    import std.functional : reverseArgs;\n    import std.path : buildPath;\n\n    auto directory = uniqueTempPath();\n    std.file.mkdir(directory);\n    scope(exit) std.file.rmdirRecurse(directory);\n    auto path = buildPath(directory, \"tmp\");\n    std.file.write(path, null);\n    auto fd = open(path.tempCString, O_RDONLY);\n    scope(exit) close(fd);\n\n    // command >&2 (or any other number) checks whethether that number\n    // file descriptor is open.\n    // Can't use this for arbitrary descriptors as many shells only support\n    // single digit fds.\n    TestScript testDefaults = `command >&0 && command >&1 && command >&2`;\n    assert(execute(testDefaults.path).status == 0);\n    assert(execute(testDefaults.path, null, Config.inheritFDs).status == 0);\n\n    // Try a few different methods to check whether there are any\n    // incorrectly-open files.\n    void testFDs()\n    {\n        // try /proc/<pid>/fd/ on linux\n        version (linux)\n        {\n            TestScript proc = \"ls /proc/$$/fd\";\n            auto procRes = execute(proc.path, null);\n            if (procRes.status == 0)\n            {\n                auto fdStr = fd.to!string;\n                assert(!procRes.output.split.canFind(fdStr));\n                assert(execute(proc.path, null, Config.inheritFDs)\n                        .output.split.canFind(fdStr));\n                return;\n            }\n        }\n\n        // try fuser (might sometimes need permissions)\n        TestScript fuser = \"echo $$ && fuser -f \" ~ path;\n        auto fuserRes = execute(fuser.path, null);\n        if (fuserRes.status == 0)\n        {\n            assert(!reverseArgs!canFind(fuserRes\n                        .output.findSplitBefore(\"\\n\").expand));\n            assert(reverseArgs!canFind(execute(fuser.path, null, Config.inheritFDs)\n                        .output.findSplitBefore(\"\\n\").expand));\n            return;\n        }\n\n        // last resort, try lsof (not available on all Posix)\n        TestScript lsof = \"lsof -p$$\";\n        auto lsofRes = execute(lsof.path, null);\n        if (lsofRes.status == 0)\n        {\n            assert(!lsofRes.output.canFind(path));\n            assert(execute(lsof.path, null, Config.inheritFDs).output.canFind(path));\n            return;\n        }\n\n        std.stdio.stderr.writeln(__FILE__, ':', __LINE__,\n                \": Warning: Couldn't find any way to check open files\");\n    }\n    testFDs();\n}\n\n@system unittest // Environment variables in spawnProcess().\n{\n    // We really should use set /a on Windows, but Wine doesn't support it.\n    version (Windows) TestScript envProg =\n       `if [%STD_PROCESS_UNITTEST1%] == [1] (\n            if [%STD_PROCESS_UNITTEST2%] == [2] (exit 3)\n            exit 1\n        )\n        if [%STD_PROCESS_UNITTEST1%] == [4] (\n            if [%STD_PROCESS_UNITTEST2%] == [2] (exit 6)\n            exit 4\n        )\n        if [%STD_PROCESS_UNITTEST2%] == [2] (exit 2)\n        exit 0`;\n    version (Posix) TestScript envProg =\n       `if test \"$std_process_unittest1\" = \"\"; then\n            std_process_unittest1=0\n        fi\n        if test \"$std_process_unittest2\" = \"\"; then\n            std_process_unittest2=0\n        fi\n        exit $(($std_process_unittest1+$std_process_unittest2))`;\n\n    environment.remove(\"std_process_unittest1\"); // Just in case.\n    environment.remove(\"std_process_unittest2\");\n    assert(wait(spawnProcess(envProg.path)) == 0);\n    assert(wait(spawnProcess(envProg.path, null, Config.newEnv)) == 0);\n\n    environment[\"std_process_unittest1\"] = \"1\";\n    assert(wait(spawnProcess(envProg.path)) == 1);\n    assert(wait(spawnProcess(envProg.path, null, Config.newEnv)) == 0);\n\n    auto env = [\"std_process_unittest2\" : \"2\"];\n    assert(wait(spawnProcess(envProg.path, env)) == 3);\n    assert(wait(spawnProcess(envProg.path, env, Config.newEnv)) == 2);\n\n    env[\"std_process_unittest1\"] = \"4\";\n    assert(wait(spawnProcess(envProg.path, env)) == 6);\n    assert(wait(spawnProcess(envProg.path, env, Config.newEnv)) == 6);\n\n    environment.remove(\"std_process_unittest1\");\n    assert(wait(spawnProcess(envProg.path, env)) == 6);\n    assert(wait(spawnProcess(envProg.path, env, Config.newEnv)) == 6);\n}\n\n@system unittest // Stream redirection in spawnProcess().\n{\n    import std.path : buildPath;\n    import std.string;\n    version (Windows) TestScript prog =\n       \"set /p INPUT=\n        echo %INPUT% output %~1\n        echo %INPUT% error %~2 1>&2\";\n    else version (Posix) TestScript prog =\n       \"read INPUT\n        echo $INPUT output $1\n        echo $INPUT error $2 >&2\";\n\n    // Pipes\n    void testPipes(Config config)\n    {\n        auto pipei = pipe();\n        auto pipeo = pipe();\n        auto pipee = pipe();\n        auto pid = spawnProcess([prog.path, \"foo\", \"bar\"],\n                                    pipei.readEnd, pipeo.writeEnd, pipee.writeEnd, null, config);\n        pipei.writeEnd.writeln(\"input\");\n        pipei.writeEnd.flush();\n        assert(pipeo.readEnd.readln().chomp() == \"input output foo\");\n        assert(pipee.readEnd.readln().chomp().stripRight() == \"input error bar\");\n        if (!(config & Config.detached))\n            wait(pid);\n    }\n\n    // Files\n    void testFiles(Config config)\n    {\n        import std.ascii, std.file, std.uuid, core.thread;\n        auto pathi = buildPath(tempDir(), randomUUID().toString());\n        auto patho = buildPath(tempDir(), randomUUID().toString());\n        auto pathe = buildPath(tempDir(), randomUUID().toString());\n        std.file.write(pathi, \"INPUT\"~std.ascii.newline);\n        auto filei = File(pathi, \"r\");\n        auto fileo = File(patho, \"w\");\n        auto filee = File(pathe, \"w\");\n        auto pid = spawnProcess([prog.path, \"bar\", \"baz\" ], filei, fileo, filee, null, config);\n        if (!(config & Config.detached))\n            wait(pid);\n        else\n            // We need to wait a little to ensure that the process has finished and data was written to files\n            Thread.sleep(2.seconds);\n        assert(readText(patho).chomp() == \"INPUT output bar\");\n        assert(readText(pathe).chomp().stripRight() == \"INPUT error baz\");\n        remove(pathi);\n        remove(patho);\n        remove(pathe);\n    }\n\n    testPipes(Config.none);\n    testFiles(Config.none);\n    testPipes(Config.detached);\n    testFiles(Config.detached);\n}\n\n@system unittest // Error handling in spawnProcess()\n{\n    import std.exception : assertThrown;\n    assertThrown!ProcessException(spawnProcess(\"ewrgiuhrifuheiohnmnvqweoijwf\"));\n    assertThrown!ProcessException(spawnProcess(\"./rgiuhrifuheiohnmnvqweoijwf\"));\n    assertThrown!ProcessException(spawnProcess(\"ewrgiuhrifuheiohnmnvqweoijwf\", null, Config.detached));\n    assertThrown!ProcessException(spawnProcess(\"./rgiuhrifuheiohnmnvqweoijwf\", null, Config.detached));\n\n    // can't execute malformed file with executable permissions\n    version (Posix)\n    {\n        import std.path : buildPath;\n        import std.file : remove, write, setAttributes;\n        import core.sys.posix.sys.stat : S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IXGRP, S_IROTH, S_IXOTH;\n        string deleteme = buildPath(tempDir(), \"deleteme.std.process.unittest.pid\") ~ to!string(thisProcessID);\n        write(deleteme, \"\");\n        scope(exit) remove(deleteme);\n        setAttributes(deleteme, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);\n        assertThrown!ProcessException(spawnProcess(deleteme));\n        assertThrown!ProcessException(spawnProcess(deleteme, null, Config.detached));\n    }\n}\n\n@system unittest // Specifying a working directory.\n{\n    import std.path;\n    TestScript prog = \"echo foo>bar\";\n\n    auto directory = uniqueTempPath();\n    mkdir(directory);\n    scope(exit) rmdirRecurse(directory);\n\n    auto pid = spawnProcess([prog.path], null, Config.none, directory);\n    wait(pid);\n    assert(exists(buildPath(directory, \"bar\")));\n}\n\n@system unittest // Specifying a bad working directory.\n{\n    import std.exception : assertThrown;\n    TestScript prog = \"echo\";\n\n    auto directory = uniqueTempPath();\n    assertThrown!ProcessException(spawnProcess([prog.path], null, Config.none, directory));\n    assertThrown!ProcessException(spawnProcess([prog.path], null, Config.detached, directory));\n\n    std.file.write(directory, \"foo\");\n    scope(exit) remove(directory);\n    assertThrown!ProcessException(spawnProcess([prog.path], null, Config.none, directory));\n    assertThrown!ProcessException(spawnProcess([prog.path], null, Config.detached, directory));\n\n    // can't run in directory if user does not have search permission on this directory\n    version (Posix)\n    {\n        if (core.sys.posix.unistd.getuid() != 0)\n        {\n            import core.sys.posix.sys.stat : S_IRUSR;\n            auto directoryNoSearch = uniqueTempPath();\n            mkdir(directoryNoSearch);\n            scope(exit) rmdirRecurse(directoryNoSearch);\n            setAttributes(directoryNoSearch, S_IRUSR);\n            assertThrown!ProcessException(spawnProcess(prog.path, null, Config.none, directoryNoSearch));\n            assertThrown!ProcessException(spawnProcess(prog.path, null, Config.detached, directoryNoSearch));\n        }\n    }\n}\n\n@system unittest // Specifying empty working directory.\n{\n    TestScript prog = \"\";\n\n    string directory = \"\";\n    assert(directory.ptr && !directory.length);\n    spawnProcess([prog.path], null, Config.none, directory).wait();\n}\n\n@system unittest // Reopening the standard streams (issue 13258)\n{\n    import std.string;\n    void fun()\n    {\n        spawnShell(\"echo foo\").wait();\n        spawnShell(\"echo bar\").wait();\n    }\n\n    auto tmpFile = uniqueTempPath();\n    scope(exit) if (exists(tmpFile)) remove(tmpFile);\n\n    {\n        auto oldOut = std.stdio.stdout;\n        scope(exit) std.stdio.stdout = oldOut;\n\n        std.stdio.stdout = File(tmpFile, \"w\");\n        fun();\n        std.stdio.stdout.close();\n    }\n\n    auto lines = readText(tmpFile).splitLines();\n    assert(lines == [\"foo\", \"bar\"]);\n}\n\nversion (Windows)\n@system unittest // MSVCRT workaround (issue 14422)\n{\n    auto fn = uniqueTempPath();\n    std.file.write(fn, \"AAAAAAAAAA\");\n\n    auto f = File(fn, \"a\");\n    spawnProcess([\"cmd\", \"/c\", \"echo BBBBB\"], std.stdio.stdin, f).wait();\n\n    auto data = readText(fn);\n    assert(data == \"AAAAAAAAAABBBBB\\r\\n\", data);\n}\n\n/**\nA variation on $(LREF spawnProcess) that runs the given _command through\nthe current user's preferred _command interpreter (aka. shell).\n\nThe string `command` is passed verbatim to the shell, and is therefore\nsubject to its rules about _command structure, argument/filename quoting\nand escaping of special characters.\nThe path to the shell executable defaults to $(LREF nativeShell).\n\nIn all other respects this function works just like `spawnProcess`.\nPlease refer to the $(LREF spawnProcess) documentation for descriptions\nof the other function parameters, the return value and any exceptions\nthat may be thrown.\n---\n// Run the command/program \"foo\" on the file named \"my file.txt\", and\n// redirect its output into foo.log.\nauto pid = spawnShell(`foo \"my file.txt\" > foo.log`);\nwait(pid);\n---\n\nSee_also:\n$(LREF escapeShellCommand), which may be helpful in constructing a\nproperly quoted and escaped shell _command line for the current platform.\n*/\nPid spawnShell(scope const(char)[] command,\n               File stdin = std.stdio.stdin,\n               File stdout = std.stdio.stdout,\n               File stderr = std.stdio.stderr,\n               scope const string[string] env = null,\n               Config config = Config.none,\n               scope const(char)[] workDir = null,\n               scope string shellPath = nativeShell)\n    @trusted // TODO: Should be @safe\n{\n    version (Windows)\n    {\n        // CMD does not parse its arguments like other programs.\n        // It does not use CommandLineToArgvW.\n        // Instead, it treats the first and last quote specially.\n        // See CMD.EXE /? for details.\n        auto args = escapeShellFileName(shellPath)\n                    ~ ` ` ~ shellSwitch ~ ` \"` ~ command ~ `\"`;\n    }\n    else version (Posix)\n    {\n        const(char)[][3] args;\n        args[0] = shellPath;\n        args[1] = shellSwitch;\n        args[2] = command;\n    }\n    return spawnProcessImpl(args, stdin, stdout, stderr, env, config, workDir);\n}\n\n/// ditto\nPid spawnShell(scope const(char)[] command,\n               scope const string[string] env,\n               Config config = Config.none,\n               scope const(char)[] workDir = null,\n               scope string shellPath = nativeShell)\n    @trusted // TODO: Should be @safe\n{\n    return spawnShell(command,\n                      std.stdio.stdin,\n                      std.stdio.stdout,\n                      std.stdio.stderr,\n                      env,\n                      config,\n                      workDir,\n                      shellPath);\n}\n\n@system unittest\n{\n    version (Windows)\n        auto cmd = \"echo %FOO%\";\n    else version (Posix)\n        auto cmd = \"echo $foo\";\n    import std.file;\n    auto tmpFile = uniqueTempPath();\n    scope(exit) if (exists(tmpFile)) remove(tmpFile);\n    auto redir = \"> \\\"\"~tmpFile~'\"';\n    auto env = [\"foo\" : \"bar\"];\n    assert(wait(spawnShell(cmd~redir, env)) == 0);\n    auto f = File(tmpFile, \"a\");\n    version (CRuntime_Microsoft) f.seek(0, SEEK_END); // MSVCRT probably seeks to the end when writing, not before\n    assert(wait(spawnShell(cmd, std.stdio.stdin, f, std.stdio.stderr, env)) == 0);\n    f.close();\n    auto output = std.file.readText(tmpFile);\n    assert(output == \"bar\\nbar\\n\" || output == \"bar\\r\\nbar\\r\\n\");\n}\n\nversion (Windows)\n@system unittest\n{\n    import std.string;\n    TestScript prog = \"echo %0 %*\";\n    auto outputFn = uniqueTempPath();\n    scope(exit) if (exists(outputFn)) remove(outputFn);\n    auto args = [`a b c`, `a\\b\\c\\`, `a\"b\"c\"`];\n    auto result = executeShell(\n        escapeShellCommand([prog.path] ~ args)\n        ~ \" > \" ~\n        escapeShellFileName(outputFn));\n    assert(result.status == 0);\n    auto args2 = outputFn.readText().strip().parseCommandLine()[1..$];\n    assert(args == args2, text(args2));\n}\n\n\n/**\nFlags that control the behaviour of process creation functions in this\nmodule. Most flags only apply to $(LREF spawnProcess) and\n$(LREF spawnShell).\n\nUse bitwise OR to combine flags.\n\nExample:\n---\nauto logFile = File(\"myapp_error.log\", \"w\");\n\n// Start program, suppressing the console window (Windows only),\n// redirect its error stream to logFile, and leave logFile open\n// in the parent process as well.\nauto pid = spawnProcess(\"myapp\", stdin, stdout, logFile,\n                        Config.retainStderr | Config.suppressConsole);\nscope(exit)\n{\n    auto exitCode = wait(pid);\n    logFile.writeln(\"myapp exited with code \", exitCode);\n    logFile.close();\n}\n---\n*/\nenum Config\n{\n    none = 0,\n\n    /**\n    By default, the child process inherits the parent's environment,\n    and any environment variables passed to $(LREF spawnProcess) will\n    be added to it.  If this flag is set, the only variables in the\n    child process' environment will be those given to spawnProcess.\n    */\n    newEnv = 1,\n\n    /**\n    Unless the child process inherits the standard input/output/error\n    streams of its parent, one almost always wants the streams closed\n    in the parent when $(LREF spawnProcess) returns.  Therefore, by\n    default, this is done.  If this is not desirable, pass any of these\n    options to spawnProcess.\n    */\n    retainStdin  = 2,\n    retainStdout = 4,                                  /// ditto\n    retainStderr = 8,                                  /// ditto\n\n    /**\n    On Windows, if the child process is a console application, this\n    flag will prevent the creation of a console window.  Otherwise,\n    it will be ignored. On POSIX, `suppressConsole` has no effect.\n    */\n    suppressConsole = 16,\n\n    /**\n    On POSIX, open $(LINK2 http://en.wikipedia.org/wiki/File_descriptor,file descriptors)\n    are by default inherited by the child process.  As this may lead\n    to subtle bugs when pipes or multiple threads are involved,\n    $(LREF spawnProcess) ensures that all file descriptors except the\n    ones that correspond to standard input/output/error are closed\n    in the child process when it starts.  Use `inheritFDs` to prevent\n    this.\n\n    On Windows, this option has no effect, and any handles which have been\n    explicitly marked as inheritable will always be inherited by the child\n    process.\n    */\n    inheritFDs = 32,\n\n    /**\n    Spawn process in detached state. This removes the need in calling\n    $(LREF wait) to clean up the process resources.\n\n    Note:\n    Calling $(LREF wait) or $(LREF kill) with the resulting `Pid` is invalid.\n    */\n    detached = 64,\n\n    /**\n    By default, the $(LREF execute) and $(LREF executeShell) functions\n    will capture child processes' both stdout and stderr. This can be\n    undesirable if the standard output is to be processed or otherwise\n    used by the invoking program, as `execute`'s result would then\n    contain a mix of output and warning/error messages.\n\n    Specify this flag when calling `execute` or `executeShell` to\n    cause invoked processes' stderr stream to be sent to $(REF stderr,\n    std,stdio), and only capture and return standard output.\n\n    This flag has no effect on $(LREF spawnProcess) or $(LREF spawnShell).\n    */\n    stderrPassThrough = 128,\n}\n\n\n/// A handle that corresponds to a spawned process.\nfinal class Pid\n{\n    /**\n    The process ID number.\n\n    This is a number that uniquely identifies the process on the operating\n    system, for at least as long as the process is running.  Once $(LREF wait)\n    has been called on the $(LREF Pid), this method will return an\n    invalid (negative) process ID.\n    */\n    @property int processID() const @safe pure nothrow\n    {\n        return _processID;\n    }\n\n    /**\n    An operating system handle to the process.\n\n    This handle is used to specify the process in OS-specific APIs.\n    On POSIX, this function returns a `core.sys.posix.sys.types.pid_t`\n    with the same value as $(LREF Pid.processID), while on Windows it returns\n    a `core.sys.windows.windows.HANDLE`.\n\n    Once $(LREF wait) has been called on the $(LREF Pid), this method\n    will return an invalid handle.\n    */\n    // Note: Since HANDLE is a reference, this function cannot be const.\n    version (Windows)\n    @property HANDLE osHandle() @safe pure nothrow\n    {\n        return _handle;\n    }\n    else version (Posix)\n    @property pid_t osHandle() @safe pure nothrow\n    {\n        return _processID;\n    }\n\nprivate:\n    /*\n    Pid.performWait() does the dirty work for wait() and nonBlockingWait().\n\n    If block == true, this function blocks until the process terminates,\n    sets _processID to terminated, and returns the exit code or terminating\n    signal as described in the wait() documentation.\n\n    If block == false, this function returns immediately, regardless\n    of the status of the process.  If the process has terminated, the\n    function has the exact same effect as the blocking version.  If not,\n    it returns 0 and does not modify _processID.\n    */\n    version (Posix)\n    int performWait(bool block) @trusted\n    {\n        import std.exception : enforce;\n        enforce!ProcessException(owned, \"Can't wait on a detached process\");\n        if (_processID == terminated) return _exitCode;\n        int exitCode;\n        while (true)\n        {\n            int status;\n            auto check = waitpid(_processID, &status, block ? 0 : WNOHANG);\n            if (check == -1)\n            {\n                if (errno == ECHILD)\n                {\n                    throw new ProcessException(\n                        \"Process does not exist or is not a child process.\");\n                }\n                else\n                {\n                    // waitpid() was interrupted by a signal.  We simply\n                    // restart it.\n                    assert(errno == EINTR);\n                    continue;\n                }\n            }\n            if (!block && check == 0) return 0;\n            if (WIFEXITED(status))\n            {\n                exitCode = WEXITSTATUS(status);\n                break;\n            }\n            else if (WIFSIGNALED(status))\n            {\n                exitCode = -WTERMSIG(status);\n                break;\n            }\n            // We check again whether the call should be blocking,\n            // since we don't care about other status changes besides\n            // \"exited\" and \"terminated by signal\".\n            if (!block) return 0;\n\n            // Process has stopped, but not terminated, so we continue waiting.\n        }\n        // Mark Pid as terminated, and cache and return exit code.\n        _processID = terminated;\n        _exitCode = exitCode;\n        return exitCode;\n    }\n    else version (Windows)\n    {\n        int performWait(bool block) @trusted\n        {\n            import std.exception : enforce;\n            enforce!ProcessException(owned, \"Can't wait on a detached process\");\n            if (_processID == terminated) return _exitCode;\n            assert(_handle != INVALID_HANDLE_VALUE);\n            if (block)\n            {\n                auto result = WaitForSingleObject(_handle, INFINITE);\n                if (result != WAIT_OBJECT_0)\n                    throw ProcessException.newFromLastError(\"Wait failed.\");\n            }\n            if (!GetExitCodeProcess(_handle, cast(LPDWORD)&_exitCode))\n                throw ProcessException.newFromLastError();\n            if (!block && _exitCode == STILL_ACTIVE) return 0;\n            CloseHandle(_handle);\n            _handle = INVALID_HANDLE_VALUE;\n            _processID = terminated;\n            return _exitCode;\n        }\n\n        ~this()\n        {\n            if (_handle != INVALID_HANDLE_VALUE)\n            {\n                CloseHandle(_handle);\n                _handle = INVALID_HANDLE_VALUE;\n            }\n        }\n    }\n\n    // Special values for _processID.\n    enum invalid = -1, terminated = -2;\n\n    // OS process ID number.  Only nonnegative IDs correspond to\n    // running processes.\n    int _processID = invalid;\n\n    // Exit code cached by wait().  This is only expected to hold a\n    // sensible value if _processID == terminated.\n    int _exitCode;\n\n    // Whether the process can be waited for by wait() for or killed by kill().\n    // False if process was started as detached. True otherwise.\n    bool owned;\n\n    // Pids are only meant to be constructed inside this module, so\n    // we make the constructor private.\n    version (Windows)\n    {\n        HANDLE _handle = INVALID_HANDLE_VALUE;\n        this(int pid, HANDLE handle) @safe pure nothrow\n        {\n            _processID = pid;\n            _handle = handle;\n            this.owned = true;\n        }\n        this(int pid) @safe pure nothrow\n        {\n            _processID = pid;\n            this.owned = false;\n        }\n    }\n    else\n    {\n        this(int id, bool owned) @safe pure nothrow\n        {\n            _processID = id;\n            this.owned = owned;\n        }\n    }\n}\n\n\n/**\nWaits for the process associated with `pid` to terminate, and returns\nits exit status.\n\nIn general one should always _wait for child processes to terminate\nbefore exiting the parent process unless the process was spawned as detached\n(that was spawned with `Config.detached` flag).\nOtherwise, they may become \"$(HTTP en.wikipedia.org/wiki/Zombie_process,zombies)\"\n– processes that are defunct, yet still occupy a slot in the OS process table.\nYou should not and must not wait for detached processes, since you don't own them.\n\nIf the process has already terminated, this function returns directly.\nThe exit code is cached, so that if wait() is called multiple times on\nthe same $(LREF Pid) it will always return the same value.\n\nPOSIX_specific:\nIf the process is terminated by a signal, this function returns a\nnegative number whose absolute value is the signal number.\nSince POSIX restricts normal exit codes to the range 0-255, a\nnegative return value will always indicate termination by signal.\nSignal codes are defined in the `core.sys.posix.signal` module\n(which corresponds to the `signal.h` POSIX header).\n\nThrows:\n$(LREF ProcessException) on failure or on attempt to wait for detached process.\n\nExample:\nSee the $(LREF spawnProcess) documentation.\n\nSee_also:\n$(LREF tryWait), for a non-blocking function.\n*/\nint wait(Pid pid) @safe\n{\n    assert(pid !is null, \"Called wait on a null Pid.\");\n    return pid.performWait(true);\n}\n\n\n@system unittest // Pid and wait()\n{\n    version (Windows)    TestScript prog = \"exit %~1\";\n    else version (Posix) TestScript prog = \"exit $1\";\n    assert(wait(spawnProcess([prog.path, \"0\"])) == 0);\n    assert(wait(spawnProcess([prog.path, \"123\"])) == 123);\n    auto pid = spawnProcess([prog.path, \"10\"]);\n    assert(pid.processID > 0);\n    version (Windows)    assert(pid.osHandle != INVALID_HANDLE_VALUE);\n    else version (Posix) assert(pid.osHandle == pid.processID);\n    assert(wait(pid) == 10);\n    assert(wait(pid) == 10); // cached exit code\n    assert(pid.processID < 0);\n    version (Windows)    assert(pid.osHandle == INVALID_HANDLE_VALUE);\n    else version (Posix) assert(pid.osHandle < 0);\n}\n\n\n/**\nA non-blocking version of $(LREF wait).\n\nIf the process associated with `pid` has already terminated,\n`tryWait` has the exact same effect as `wait`.\nIn this case, it returns a tuple where the `terminated` field\nis set to `true` and the `status` field has the same\ninterpretation as the return value of `wait`.\n\nIf the process has $(I not) yet terminated, this function differs\nfrom `wait` in that does not wait for this to happen, but instead\nreturns immediately.  The `terminated` field of the returned\ntuple will then be set to `false`, while the `status` field\nwill always be 0 (zero).  `wait` or `tryWait` should then be\ncalled again on the same `Pid` at some later time; not only to\nget the exit code, but also to avoid the process becoming a \"zombie\"\nwhen it finally terminates.  (See $(LREF wait) for details).\n\nReturns:\nAn $(D std.typecons.Tuple!(bool, \"terminated\", int, \"status\")).\n\nThrows:\n$(LREF ProcessException) on failure or on attempt to wait for detached process.\n\nExample:\n---\nauto pid = spawnProcess(\"dmd myapp.d\");\nscope(exit) wait(pid);\n...\nauto dmd = tryWait(pid);\nif (dmd.terminated)\n{\n    if (dmd.status == 0) writeln(\"Compilation succeeded!\");\n    else writeln(\"Compilation failed\");\n}\nelse writeln(\"Still compiling...\");\n...\n---\nNote that in this example, the first `wait` call will have no\neffect if the process has already terminated by the time `tryWait`\nis called.  In the opposite case, however, the `scope` statement\nensures that we always wait for the process if it hasn't terminated\nby the time we reach the end of the scope.\n*/\nauto tryWait(Pid pid) @safe\n{\n    import std.typecons : Tuple;\n    assert(pid !is null, \"Called tryWait on a null Pid.\");\n    auto code = pid.performWait(false);\n    return Tuple!(bool, \"terminated\", int, \"status\")(pid._processID == Pid.terminated, code);\n}\n// unittest: This function is tested together with kill() below.\n\n\n/**\nAttempts to terminate the process associated with `pid`.\n\nThe effect of this function, as well as the meaning of `codeOrSignal`,\nis highly platform dependent.  Details are given below.  Common to all\nplatforms is that this function only $(I initiates) termination of the process,\nand returns immediately.  It does not wait for the process to end,\nnor does it guarantee that the process does in fact get terminated.\n\nAlways call $(LREF wait) to wait for a process to complete, even if `kill`\nhas been called on it.\n\nWindows_specific:\nThe process will be\n$(LINK2 http://msdn.microsoft.com/en-us/library/windows/desktop/ms686714%28v=vs.100%29.aspx,\nforcefully and abruptly terminated).  If `codeOrSignal` is specified, it\nmust be a nonnegative number which will be used as the exit code of the process.\nIf not, the process wil exit with code 1.  Do not use $(D codeOrSignal = 259),\nas this is a special value (aka. $(LINK2 http://msdn.microsoft.com/en-us/library/windows/desktop/ms683189.aspx,STILL_ACTIVE))\nused by Windows to signal that a process has in fact $(I not) terminated yet.\n---\nauto pid = spawnProcess(\"some_app\");\nkill(pid, 10);\nassert(wait(pid) == 10);\n---\n\nPOSIX_specific:\nA $(LINK2 http://en.wikipedia.org/wiki/Unix_signal,signal) will be sent to\nthe process, whose value is given by `codeOrSignal`.  Depending on the\nsignal sent, this may or may not terminate the process.  Symbolic constants\nfor various $(LINK2 http://en.wikipedia.org/wiki/Unix_signal#POSIX_signals,\nPOSIX signals) are defined in `core.sys.posix.signal`, which corresponds to the\n$(LINK2 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html,\n`signal.h` POSIX header).  If `codeOrSignal` is omitted, the\n`SIGTERM` signal will be sent.  (This matches the behaviour of the\n$(LINK2 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/kill.html,\n`_kill`) shell command.)\n---\nimport core.sys.posix.signal : SIGKILL;\nauto pid = spawnProcess(\"some_app\");\nkill(pid, SIGKILL);\nassert(wait(pid) == -SIGKILL); // Negative return value on POSIX!\n---\n\nThrows:\n$(LREF ProcessException) on error (e.g. if codeOrSignal is invalid).\n    or on attempt to kill detached process.\n    Note that failure to terminate the process is considered a \"normal\"\n    outcome, not an error.$(BR)\n*/\nvoid kill(Pid pid)\n{\n    version (Windows) kill(pid, 1);\n    else version (Posix)\n    {\n        import core.sys.posix.signal : SIGTERM;\n        kill(pid, SIGTERM);\n    }\n}\n\n/// ditto\nvoid kill(Pid pid, int codeOrSignal)\n{\n    import std.exception : enforce;\n    enforce!ProcessException(pid.owned, \"Can't kill detached process\");\n    version (Windows)\n    {\n        if (codeOrSignal < 0) throw new ProcessException(\"Invalid exit code\");\n        // On Windows, TerminateProcess() appears to terminate the\n        // *current* process if it is passed an invalid handle...\n        if (pid.osHandle == INVALID_HANDLE_VALUE)\n            throw new ProcessException(\"Invalid process handle\");\n        if (!TerminateProcess(pid.osHandle, codeOrSignal))\n            throw ProcessException.newFromLastError();\n    }\n    else version (Posix)\n    {\n        import core.sys.posix.signal : kill;\n        if (kill(pid.osHandle, codeOrSignal) == -1)\n            throw ProcessException.newFromErrno();\n    }\n}\n\n@system unittest // tryWait() and kill()\n{\n    import core.thread;\n    import std.exception : assertThrown;\n    // The test script goes into an infinite loop.\n    version (Windows)\n    {\n        TestScript prog = \":loop\n                           goto loop\";\n    }\n    else version (Posix)\n    {\n        import core.sys.posix.signal : SIGTERM, SIGKILL;\n        TestScript prog = \"while true; do sleep 1; done\";\n    }\n    auto pid = spawnProcess(prog.path);\n    // Android appears to automatically kill sleeping processes very quickly,\n    // so shorten the wait before killing here.\n    version (Android)\n        Thread.sleep(dur!\"msecs\"(5));\n    else\n        Thread.sleep(dur!\"seconds\"(1));\n    kill(pid);\n    version (Windows)    assert(wait(pid) == 1);\n    else version (Posix) assert(wait(pid) == -SIGTERM);\n\n    pid = spawnProcess(prog.path);\n    Thread.sleep(dur!\"seconds\"(1));\n    auto s = tryWait(pid);\n    assert(!s.terminated && s.status == 0);\n    assertThrown!ProcessException(kill(pid, -123)); // Negative code not allowed.\n    version (Windows)    kill(pid, 123);\n    else version (Posix) kill(pid, SIGKILL);\n    do { s = tryWait(pid); } while (!s.terminated);\n    version (Windows)    assert(s.status == 123);\n    else version (Posix) assert(s.status == -SIGKILL);\n    assertThrown!ProcessException(kill(pid));\n}\n\n@system unittest // wait() and kill() detached process\n{\n    import core.thread;\n    import std.exception : assertThrown;\n    TestScript prog = \"exit 0\";\n    auto pid = spawnProcess([prog.path], null, Config.detached);\n    /*\n    This sleep is needed because we can't wait() for detached process to end\n    and therefore TestScript destructor may run at the same time as /bin/sh tries to start the script.\n    This leads to the annoying message like \"/bin/sh: 0: Can't open /tmp/std.process temporary file\" to appear when running tests.\n    It does not happen in unittests with non-detached processes because we always wait() for them to finish.\n    */\n    Thread.sleep(1.seconds);\n    assert(!pid.owned);\n    version (Windows) assert(pid.osHandle == INVALID_HANDLE_VALUE);\n    assertThrown!ProcessException(wait(pid));\n    assertThrown!ProcessException(kill(pid));\n}\n\n\n/**\nCreates a unidirectional _pipe.\n\nData is written to one end of the _pipe and read from the other.\n---\nauto p = pipe();\np.writeEnd.writeln(\"Hello World\");\np.writeEnd.flush();\nassert(p.readEnd.readln().chomp() == \"Hello World\");\n---\nPipes can, for example, be used for interprocess communication\nby spawning a new process and passing one end of the _pipe to\nthe child, while the parent uses the other end.\n(See also $(LREF pipeProcess) and $(LREF pipeShell) for an easier\nway of doing this.)\n---\n// Use cURL to download the dlang.org front page, pipe its\n// output to grep to extract a list of links to ZIP files,\n// and write the list to the file \"D downloads.txt\":\nauto p = pipe();\nauto outFile = File(\"D downloads.txt\", \"w\");\nauto cpid = spawnProcess([\"curl\", \"http://dlang.org/download.html\"],\n                         std.stdio.stdin, p.writeEnd);\nscope(exit) wait(cpid);\nauto gpid = spawnProcess([\"grep\", \"-o\", `http://\\S*\\.zip`],\n                         p.readEnd, outFile);\nscope(exit) wait(gpid);\n---\n\nReturns:\nA $(LREF Pipe) object that corresponds to the created _pipe.\n\nThrows:\n$(REF StdioException, std,stdio) on failure.\n*/\nversion (Posix)\nPipe pipe() @trusted //TODO: @safe\n{\n    import core.sys.posix.stdio : fdopen;\n    int[2] fds;\n    if (core.sys.posix.unistd.pipe(fds) != 0)\n        throw new StdioException(\"Unable to create pipe\");\n    Pipe p;\n    auto readFP = fdopen(fds[0], \"r\");\n    if (readFP == null)\n        throw new StdioException(\"Cannot open read end of pipe\");\n    p._read = File(readFP, null);\n    auto writeFP = fdopen(fds[1], \"w\");\n    if (writeFP == null)\n        throw new StdioException(\"Cannot open write end of pipe\");\n    p._write = File(writeFP, null);\n    return p;\n}\nelse version (Windows)\nPipe pipe() @trusted //TODO: @safe\n{\n    // use CreatePipe to create an anonymous pipe\n    HANDLE readHandle;\n    HANDLE writeHandle;\n    if (!CreatePipe(&readHandle, &writeHandle, null, 0))\n    {\n        throw new StdioException(\n            \"Error creating pipe (\" ~ sysErrorString(GetLastError()) ~ ')',\n            0);\n    }\n\n    scope(failure)\n    {\n        CloseHandle(readHandle);\n        CloseHandle(writeHandle);\n    }\n\n    try\n    {\n        Pipe p;\n        p._read .windowsHandleOpen(readHandle , \"r\");\n        p._write.windowsHandleOpen(writeHandle, \"a\");\n        return p;\n    }\n    catch (Exception e)\n    {\n        throw new StdioException(\"Error attaching pipe (\" ~ e.msg ~ \")\",\n            0);\n    }\n}\n\n\n/// An interface to a pipe created by the $(LREF pipe) function.\nstruct Pipe\n{\n    /// The read end of the pipe.\n    @property File readEnd() @safe nothrow { return _read; }\n\n\n    /// The write end of the pipe.\n    @property File writeEnd() @safe nothrow { return _write; }\n\n\n    /**\n    Closes both ends of the pipe.\n\n    Normally it is not necessary to do this manually, as $(REF File, std,stdio)\n    objects are automatically closed when there are no more references\n    to them.\n\n    Note that if either end of the pipe has been passed to a child process,\n    it will only be closed in the parent process.  (What happens in the\n    child process is platform dependent.)\n\n    Throws:\n    $(REF ErrnoException, std,exception) if an error occurs.\n    */\n    void close() @safe\n    {\n        _read.close();\n        _write.close();\n    }\n\nprivate:\n    File _read, _write;\n}\n\n@system unittest\n{\n    import std.string;\n    auto p = pipe();\n    p.writeEnd.writeln(\"Hello World\");\n    p.writeEnd.flush();\n    assert(p.readEnd.readln().chomp() == \"Hello World\");\n    p.close();\n    assert(!p.readEnd.isOpen);\n    assert(!p.writeEnd.isOpen);\n}\n\n\n/**\nStarts a new process, creating pipes to redirect its standard\ninput, output and/or error streams.\n\n`pipeProcess` and `pipeShell` are convenient wrappers around\n$(LREF spawnProcess) and $(LREF spawnShell), respectively, and\nautomate the task of redirecting one or more of the child process'\nstandard streams through pipes.  Like the functions they wrap,\nthese functions return immediately, leaving the child process to\nexecute in parallel with the invoking process.  It is recommended\nto always call $(LREF wait) on the returned $(LREF ProcessPipes.pid),\nas detailed in the documentation for `wait`.\n\nThe `args`/`program`/`command`, `env` and `config`\nparameters are forwarded straight to the underlying spawn functions,\nand we refer to their documentation for details.\n\nParams:\nargs      = An array which contains the program name as the zeroth element\n            and any command-line arguments in the following elements.\n            (See $(LREF spawnProcess) for details.)\nprogram   = The program name, $(I without) command-line arguments.\n            (See $(LREF spawnProcess) for details.)\ncommand   = A shell command which is passed verbatim to the command\n            interpreter.  (See $(LREF spawnShell) for details.)\nredirect  = Flags that determine which streams are redirected, and\n            how.  See $(LREF Redirect) for an overview of available\n            flags.\nenv       = Additional environment variables for the child process.\n            (See $(LREF spawnProcess) for details.)\nconfig    = Flags that control process creation. See $(LREF Config)\n            for an overview of available flags, and note that the\n            `retainStd...` flags have no effect in this function.\nworkDir   = The working directory for the new process.\n            By default the child process inherits the parent's working\n            directory.\nshellPath = The path to the shell to use to run the specified program.\n            By default this is $(LREF nativeShell).\n\nReturns:\nA $(LREF ProcessPipes) object which contains $(REF File, std,stdio)\nhandles that communicate with the redirected streams of the child\nprocess, along with a $(LREF Pid) object that corresponds to the\nspawned process.\n\nThrows:\n$(LREF ProcessException) on failure to start the process.$(BR)\n$(REF StdioException, std,stdio) on failure to redirect any of the streams.$(BR)\n\nExample:\n---\n// my_application writes to stdout and might write to stderr\nauto pipes = pipeProcess(\"my_application\", Redirect.stdout | Redirect.stderr);\nscope(exit) wait(pipes.pid);\n\n// Store lines of output.\nstring[] output;\nforeach (line; pipes.stdout.byLine) output ~= line.idup;\n\n// Store lines of errors.\nstring[] errors;\nforeach (line; pipes.stderr.byLine) errors ~= line.idup;\n\n\n// sendmail expects to read from stdin\npipes = pipeProcess([\"/usr/bin/sendmail\", \"-t\"], Redirect.stdin);\npipes.stdin.writeln(\"To: you\");\npipes.stdin.writeln(\"From: me\");\npipes.stdin.writeln(\"Subject: dlang\");\npipes.stdin.writeln(\"\");\npipes.stdin.writeln(message);\n\n// a single period tells sendmail we are finished\npipes.stdin.writeln(\".\");\n\n// but at this point sendmail might not see it, we need to flush\npipes.stdin.flush();\n\n// sendmail happens to exit on \".\", but some you have to close the file:\npipes.stdin.close();\n\n// otherwise this wait will wait forever\nwait(pipes.pid);\n\n---\n*/\nProcessPipes pipeProcess(scope const(char[])[] args,\n                         Redirect redirect = Redirect.all,\n                         const string[string] env = null,\n                         Config config = Config.none,\n                         scope const(char)[] workDir = null)\n    @safe\n{\n    return pipeProcessImpl!spawnProcess(args, redirect, env, config, workDir);\n}\n\n/// ditto\nProcessPipes pipeProcess(scope const(char)[] program,\n                         Redirect redirect = Redirect.all,\n                         const string[string] env = null,\n                         Config config = Config.none,\n                         scope const(char)[] workDir = null)\n    @safe\n{\n    return pipeProcessImpl!spawnProcess(program, redirect, env, config, workDir);\n}\n\n/// ditto\nProcessPipes pipeShell(scope const(char)[] command,\n                       Redirect redirect = Redirect.all,\n                       const string[string] env = null,\n                       Config config = Config.none,\n                       scope const(char)[] workDir = null,\n                       string shellPath = nativeShell)\n    @safe\n{\n    return pipeProcessImpl!spawnShell(command,\n                                      redirect,\n                                      env,\n                                      config,\n                                      workDir,\n                                      shellPath);\n}\n\n// Implementation of the pipeProcess() family of functions.\nprivate ProcessPipes pipeProcessImpl(alias spawnFunc, Cmd, ExtraSpawnFuncArgs...)\n                                    (Cmd command,\n                                     Redirect redirectFlags,\n                                     const string[string] env = null,\n                                     Config config = Config.none,\n                                     scope const(char)[] workDir = null,\n                                     ExtraSpawnFuncArgs extraArgs = ExtraSpawnFuncArgs.init)\n    @trusted //TODO: @safe\n{\n    File childStdin, childStdout, childStderr;\n    ProcessPipes pipes;\n    pipes._redirectFlags = redirectFlags;\n\n    if (redirectFlags & Redirect.stdin)\n    {\n        auto p = pipe();\n        childStdin = p.readEnd;\n        pipes._stdin = p.writeEnd;\n    }\n    else\n    {\n        childStdin = std.stdio.stdin;\n    }\n\n    if (redirectFlags & Redirect.stdout)\n    {\n        if ((redirectFlags & Redirect.stdoutToStderr) != 0)\n            throw new StdioException(\"Cannot create pipe for stdout AND \"\n                                     ~\"redirect it to stderr\", 0);\n        auto p = pipe();\n        childStdout = p.writeEnd;\n        pipes._stdout = p.readEnd;\n    }\n    else\n    {\n        childStdout = std.stdio.stdout;\n    }\n\n    if (redirectFlags & Redirect.stderr)\n    {\n        if ((redirectFlags & Redirect.stderrToStdout) != 0)\n            throw new StdioException(\"Cannot create pipe for stderr AND \"\n                                     ~\"redirect it to stdout\", 0);\n        auto p = pipe();\n        childStderr = p.writeEnd;\n        pipes._stderr = p.readEnd;\n    }\n    else\n    {\n        childStderr = std.stdio.stderr;\n    }\n\n    if (redirectFlags & Redirect.stdoutToStderr)\n    {\n        if (redirectFlags & Redirect.stderrToStdout)\n        {\n            // We know that neither of the other options have been\n            // set, so we assign the std.stdio.std* streams directly.\n            childStdout = std.stdio.stderr;\n            childStderr = std.stdio.stdout;\n        }\n        else\n        {\n            childStdout = childStderr;\n        }\n    }\n    else if (redirectFlags & Redirect.stderrToStdout)\n    {\n        childStderr = childStdout;\n    }\n\n    config &= ~(Config.retainStdin | Config.retainStdout | Config.retainStderr);\n    pipes._pid = spawnFunc(command, childStdin, childStdout, childStderr,\n                           env, config, workDir, extraArgs);\n    return pipes;\n}\n\n\n/**\nFlags that can be passed to $(LREF pipeProcess) and $(LREF pipeShell)\nto specify which of the child process' standard streams are redirected.\nUse bitwise OR to combine flags.\n*/\nenum Redirect\n{\n    /// Redirect the standard input, output or error streams, respectively.\n    stdin = 1,\n    stdout = 2,                             /// ditto\n    stderr = 4,                             /// ditto\n\n    /**\n    Redirect _all three streams.  This is equivalent to\n    $(D Redirect.stdin | Redirect.stdout | Redirect.stderr).\n    */\n    all = stdin | stdout | stderr,\n\n    /**\n    Redirect the standard error stream into the standard output stream.\n    This can not be combined with `Redirect.stderr`.\n    */\n    stderrToStdout = 8,\n\n    /**\n    Redirect the standard output stream into the standard error stream.\n    This can not be combined with `Redirect.stdout`.\n    */\n    stdoutToStderr = 16,\n}\n\n@system unittest\n{\n    import std.string;\n    version (Windows) TestScript prog =\n       \"call :sub %~1 %~2 0\n        call :sub %~1 %~2 1\n        call :sub %~1 %~2 2\n        call :sub %~1 %~2 3\n        exit 3\n\n        :sub\n        set /p INPUT=\n        if -%INPUT%-==-stop- ( exit %~3 )\n        echo %INPUT% %~1\n        echo %INPUT% %~2 1>&2\";\n    else version (Posix) TestScript prog =\n       `for EXITCODE in 0 1 2 3; do\n            read INPUT\n            if test \"$INPUT\" = stop; then break; fi\n            echo \"$INPUT $1\"\n            echo \"$INPUT $2\" >&2\n        done\n        exit $EXITCODE`;\n    auto pp = pipeProcess([prog.path, \"bar\", \"baz\"]);\n    pp.stdin.writeln(\"foo\");\n    pp.stdin.flush();\n    assert(pp.stdout.readln().chomp() == \"foo bar\");\n    assert(pp.stderr.readln().chomp().stripRight() == \"foo baz\");\n    pp.stdin.writeln(\"1234567890\");\n    pp.stdin.flush();\n    assert(pp.stdout.readln().chomp() == \"1234567890 bar\");\n    assert(pp.stderr.readln().chomp().stripRight() == \"1234567890 baz\");\n    pp.stdin.writeln(\"stop\");\n    pp.stdin.flush();\n    assert(wait(pp.pid) == 2);\n\n    pp = pipeProcess([prog.path, \"12345\", \"67890\"],\n                     Redirect.stdin | Redirect.stdout | Redirect.stderrToStdout);\n    pp.stdin.writeln(\"xyz\");\n    pp.stdin.flush();\n    assert(pp.stdout.readln().chomp() == \"xyz 12345\");\n    assert(pp.stdout.readln().chomp().stripRight() == \"xyz 67890\");\n    pp.stdin.writeln(\"stop\");\n    pp.stdin.flush();\n    assert(wait(pp.pid) == 1);\n\n    pp = pipeShell(escapeShellCommand(prog.path, \"AAAAA\", \"BBB\"),\n                   Redirect.stdin | Redirect.stdoutToStderr | Redirect.stderr);\n    pp.stdin.writeln(\"ab\");\n    pp.stdin.flush();\n    assert(pp.stderr.readln().chomp() == \"ab AAAAA\");\n    assert(pp.stderr.readln().chomp().stripRight() == \"ab BBB\");\n    pp.stdin.writeln(\"stop\");\n    pp.stdin.flush();\n    assert(wait(pp.pid) == 1);\n}\n\n@system unittest\n{\n    import std.exception : assertThrown;\n    TestScript prog = \"exit 0\";\n    assertThrown!StdioException(pipeProcess(\n        prog.path,\n        Redirect.stdout | Redirect.stdoutToStderr));\n    assertThrown!StdioException(pipeProcess(\n        prog.path,\n        Redirect.stderr | Redirect.stderrToStdout));\n    auto p = pipeProcess(prog.path, Redirect.stdin);\n    assertThrown!Error(p.stdout);\n    assertThrown!Error(p.stderr);\n    wait(p.pid);\n    p = pipeProcess(prog.path, Redirect.stderr);\n    assertThrown!Error(p.stdin);\n    assertThrown!Error(p.stdout);\n    wait(p.pid);\n}\n\n/**\nObject which contains $(REF File, std,stdio) handles that allow communication\nwith a child process through its standard streams.\n*/\nstruct ProcessPipes\n{\n    /// The $(LREF Pid) of the child process.\n    @property Pid pid() @safe nothrow\n    {\n        return _pid;\n    }\n\n    /**\n    An $(REF File, std,stdio) that allows writing to the child process'\n    standard input stream.\n\n    Throws:\n    $(OBJECTREF Error) if the child process' standard input stream hasn't\n    been redirected.\n    */\n    @property File stdin() @safe nothrow\n    {\n        if ((_redirectFlags & Redirect.stdin) == 0)\n            throw new Error(\"Child process' standard input stream hasn't \"\n                            ~\"been redirected.\");\n        return _stdin;\n    }\n\n    /**\n    An $(REF File, std,stdio) that allows reading from the child process'\n    standard output stream.\n\n    Throws:\n    $(OBJECTREF Error) if the child process' standard output stream hasn't\n    been redirected.\n    */\n    @property File stdout() @safe nothrow\n    {\n        if ((_redirectFlags & Redirect.stdout) == 0)\n            throw new Error(\"Child process' standard output stream hasn't \"\n                            ~\"been redirected.\");\n        return _stdout;\n    }\n\n    /**\n    An $(REF File, std,stdio) that allows reading from the child process'\n    standard error stream.\n\n    Throws:\n    $(OBJECTREF Error) if the child process' standard error stream hasn't\n    been redirected.\n    */\n    @property File stderr() @safe nothrow\n    {\n        if ((_redirectFlags & Redirect.stderr) == 0)\n            throw new Error(\"Child process' standard error stream hasn't \"\n                            ~\"been redirected.\");\n        return _stderr;\n    }\n\nprivate:\n    Redirect _redirectFlags;\n    Pid _pid;\n    File _stdin, _stdout, _stderr;\n}\n\n\n\n/**\nExecutes the given program or shell command and returns its exit\ncode and output.\n\n`execute` and `executeShell` start a new process using\n$(LREF spawnProcess) and $(LREF spawnShell), respectively, and wait\nfor the process to complete before returning.  The functions capture\nwhat the child process prints to both its standard output and\nstandard error streams, and return this together with its exit code.\n---\nauto dmd = execute([\"dmd\", \"myapp.d\"]);\nif (dmd.status != 0) writeln(\"Compilation failed:\\n\", dmd.output);\n\nauto ls = executeShell(\"ls -l\");\nif (ls.status != 0) writeln(\"Failed to retrieve file listing\");\nelse writeln(ls.output);\n---\n\nThe `args`/`program`/`command`, `env` and `config`\nparameters are forwarded straight to the underlying spawn functions,\nand we refer to their documentation for details.\n\nParams:\nargs      = An array which contains the program name as the zeroth element\n            and any command-line arguments in the following elements.\n            (See $(LREF spawnProcess) for details.)\nprogram   = The program name, $(I without) command-line arguments.\n            (See $(LREF spawnProcess) for details.)\ncommand   = A shell command which is passed verbatim to the command\n            interpreter.  (See $(LREF spawnShell) for details.)\nenv       = Additional environment variables for the child process.\n            (See $(LREF spawnProcess) for details.)\nconfig    = Flags that control process creation. See $(LREF Config)\n            for an overview of available flags, and note that the\n            `retainStd...` flags have no effect in this function.\nmaxOutput = The maximum number of bytes of output that should be\n            captured.\nworkDir   = The working directory for the new process.\n            By default the child process inherits the parent's working\n            directory.\nshellPath = The path to the shell to use to run the specified program.\n            By default this is $(LREF nativeShell).\n\n\nReturns:\nAn $(D std.typecons.Tuple!(int, \"status\", string, \"output\")).\n\nPOSIX_specific:\nIf the process is terminated by a signal, the `status` field of\nthe return value will contain a negative number whose absolute\nvalue is the signal number.  (See $(LREF wait) for details.)\n\nThrows:\n$(LREF ProcessException) on failure to start the process.$(BR)\n$(REF StdioException, std,stdio) on failure to capture output.\n*/\nauto execute(scope const(char[])[] args,\n             const string[string] env = null,\n             Config config = Config.none,\n             size_t maxOutput = size_t.max,\n             scope const(char)[] workDir = null)\n    @trusted //TODO: @safe\n{\n    return executeImpl!pipeProcess(args, env, config, maxOutput, workDir);\n}\n\n/// ditto\nauto execute(scope const(char)[] program,\n             const string[string] env = null,\n             Config config = Config.none,\n             size_t maxOutput = size_t.max,\n             scope const(char)[] workDir = null)\n    @trusted //TODO: @safe\n{\n    return executeImpl!pipeProcess(program, env, config, maxOutput, workDir);\n}\n\n/// ditto\nauto executeShell(scope const(char)[] command,\n                  const string[string] env = null,\n                  Config config = Config.none,\n                  size_t maxOutput = size_t.max,\n                  scope const(char)[] workDir = null,\n                  string shellPath = nativeShell)\n    @trusted //TODO: @safe\n{\n    return executeImpl!pipeShell(command,\n                                 env,\n                                 config,\n                                 maxOutput,\n                                 workDir,\n                                 shellPath);\n}\n\n// Does the actual work for execute() and executeShell().\nprivate auto executeImpl(alias pipeFunc, Cmd, ExtraPipeFuncArgs...)(\n    Cmd commandLine,\n    const string[string] env = null,\n    Config config = Config.none,\n    size_t maxOutput = size_t.max,\n    scope const(char)[] workDir = null,\n    ExtraPipeFuncArgs extraArgs = ExtraPipeFuncArgs.init)\n{\n    import std.algorithm.comparison : min;\n    import std.array : appender;\n    import std.typecons : Tuple;\n\n    auto redirect = (config & Config.stderrPassThrough)\n        ? Redirect.stdout\n        : Redirect.stdout | Redirect.stderrToStdout;\n\n    auto p = pipeFunc(commandLine, redirect,\n                      env, config, workDir, extraArgs);\n\n    auto a = appender!string;\n    enum size_t defaultChunkSize = 4096;\n    immutable chunkSize = min(maxOutput, defaultChunkSize);\n\n    // Store up to maxOutput bytes in a.\n    foreach (ubyte[] chunk; p.stdout.byChunk(chunkSize))\n    {\n        immutable size_t remain = maxOutput - a.data.length;\n\n        if (chunk.length < remain) a.put(chunk);\n        else\n        {\n            a.put(chunk[0 .. remain]);\n            break;\n        }\n    }\n    // Exhaust the stream, if necessary.\n    foreach (ubyte[] chunk; p.stdout.byChunk(defaultChunkSize)) { }\n\n    return Tuple!(int, \"status\", string, \"output\")(wait(p.pid), a.data);\n}\n\n@system unittest\n{\n    import std.string;\n    // To avoid printing the newline characters, we use the echo|set trick on\n    // Windows, and printf on POSIX (neither echo -n nor echo \\c are portable).\n    version (Windows) TestScript prog =\n       \"echo|set /p=%~1\n        echo|set /p=%~2 1>&2\n        exit 123\";\n    else version (Android) TestScript prog =\n       `echo -n $1\n        echo -n $2 >&2\n        exit 123`;\n    else version (Posix) TestScript prog =\n       `printf '%s' $1\n        printf '%s' $2 >&2\n        exit 123`;\n    auto r = execute([prog.path, \"foo\", \"bar\"]);\n    assert(r.status == 123);\n    assert(r.output.stripRight() == \"foobar\");\n    auto s = execute([prog.path, \"Hello\", \"World\"]);\n    assert(s.status == 123);\n    assert(s.output.stripRight() == \"HelloWorld\");\n}\n\n@safe unittest\n{\n    import std.string;\n    auto r1 = executeShell(\"echo foo\");\n    assert(r1.status == 0);\n    assert(r1.output.chomp() == \"foo\");\n    auto r2 = executeShell(\"echo bar 1>&2\");\n    assert(r2.status == 0);\n    assert(r2.output.chomp().stripRight() == \"bar\");\n    auto r3 = executeShell(\"exit 123\");\n    assert(r3.status == 123);\n    assert(r3.output.empty);\n    auto r4 = executeShell(\"echo stderr test, please ignore 1>&2\",\n        null, Config.stderrPassThrough);\n    assert(r4.status == 0);\n    assert(r4.output.empty);\n}\n\n@safe unittest\n{\n    import std.typecons : Tuple;\n    void foo() //Just test the compilation\n    {\n        auto ret1 = execute([\"dummy\", \"arg\"]);\n        auto ret2 = executeShell(\"dummy arg\");\n        static assert(is(typeof(ret1) == typeof(ret2)));\n\n        Tuple!(int, string) ret3 = execute([\"dummy\", \"arg\"]);\n    }\n}\n\n/// An exception that signals a problem with starting or waiting for a process.\nclass ProcessException : Exception\n{\n    import std.exception : basicExceptionCtors;\n    mixin basicExceptionCtors;\n\n    // Creates a new ProcessException based on errno.\n    static ProcessException newFromErrno(string customMsg = null,\n                                         string file = __FILE__,\n                                         size_t line = __LINE__)\n    {\n        import core.stdc.errno : errno;\n        return newFromErrno(errno, customMsg, file, line);\n    }\n\n    // ditto, but error number is provided by caller\n    static ProcessException newFromErrno(int error,\n                                         string customMsg = null,\n                                         string file = __FILE__,\n                                         size_t line = __LINE__)\n    {\n        import std.exception : errnoString;\n        auto errnoMsg = errnoString(error);\n        auto msg = customMsg.empty ? errnoMsg\n                                   : customMsg ~ \" (\" ~ errnoMsg ~ ')';\n        return new ProcessException(msg, file, line);\n    }\n\n    // Creates a new ProcessException based on GetLastError() (Windows only).\n    version (Windows)\n    static ProcessException newFromLastError(string customMsg = null,\n                                             string file = __FILE__,\n                                             size_t line = __LINE__)\n    {\n        auto lastMsg = sysErrorString(GetLastError());\n        auto msg = customMsg.empty ? lastMsg\n                                   : customMsg ~ \" (\" ~ lastMsg ~ ')';\n        return new ProcessException(msg, file, line);\n    }\n}\n\n\n/**\nDetermines the path to the current user's preferred command interpreter.\n\nOn Windows, this function returns the contents of the COMSPEC environment\nvariable, if it exists.  Otherwise, it returns the result of $(LREF nativeShell).\n\nOn POSIX, `userShell` returns the contents of the SHELL environment\nvariable, if it exists and is non-empty.  Otherwise, it returns the result of\n$(LREF nativeShell).\n*/\n@property string userShell() @safe\n{\n    version (Windows)      return environment.get(\"COMSPEC\", nativeShell);\n    else version (Posix)   return environment.get(\"SHELL\", nativeShell);\n}\n\n/**\nThe platform-specific native shell path.\n\nThis function returns `\"cmd.exe\"` on Windows, `\"/bin/sh\"` on POSIX, and\n`\"/system/bin/sh\"` on Android.\n*/\n@property string nativeShell() @safe @nogc pure nothrow\n{\n    version (Windows)      return \"cmd.exe\";\n    else version (Android) return \"/system/bin/sh\";\n    else version (Posix)   return \"/bin/sh\";\n}\n\n// A command-line switch that indicates to the shell that it should\n// interpret the following argument as a command to be executed.\nversion (Posix)   private immutable string shellSwitch = \"-c\";\nversion (Windows) private immutable string shellSwitch = \"/C\";\n\n\n/**\n * Returns the process ID of the current process,\n * which is guaranteed to be unique on the system.\n *\n * Example:\n * ---\n * writefln(\"Current process ID: %d\", thisProcessID);\n * ---\n */\n@property int thisProcessID() @trusted nothrow //TODO: @safe\n{\n    version (Windows)    return GetCurrentProcessId();\n    else version (Posix) return core.sys.posix.unistd.getpid();\n}\n\n\n/**\n * Returns the process ID of the current thread,\n * which is guaranteed to be unique within the current process.\n *\n * Returns:\n * A $(REF ThreadID, core,thread) value for the calling thread.\n *\n * Example:\n * ---\n * writefln(\"Current thread ID: %s\", thisThreadID);\n * ---\n */\n@property ThreadID thisThreadID() @trusted nothrow //TODO: @safe\n{\n    version (Windows)\n        return GetCurrentThreadId();\n    else\n    version (Posix)\n    {\n        import core.sys.posix.pthread : pthread_self;\n        return pthread_self();\n    }\n}\n\n\n@system unittest\n{\n    int pidA, pidB;\n    ThreadID tidA, tidB;\n    pidA = thisProcessID;\n    tidA = thisThreadID;\n\n    import core.thread;\n    auto t = new Thread({\n        pidB = thisProcessID;\n        tidB = thisThreadID;\n    });\n    t.start();\n    t.join();\n\n    assert(pidA == pidB);\n    assert(tidA != tidB);\n}\n\n\n// Unittest support code:  TestScript takes a string that contains a\n// shell script for the current platform, and writes it to a temporary\n// file. On Windows the file name gets a .cmd extension, while on\n// POSIX its executable permission bit is set.  The file is\n// automatically deleted when the object goes out of scope.\nversion (unittest)\nprivate struct TestScript\n{\n    this(string code) @system\n    {\n        // @system due to chmod\n        import std.ascii : newline;\n        import std.file : write;\n        version (Windows)\n        {\n            auto ext = \".cmd\";\n            auto firstLine = \"@echo off\";\n        }\n        else version (Posix)\n        {\n            auto ext = \"\";\n            auto firstLine = \"#!\" ~ nativeShell;\n        }\n        path = uniqueTempPath()~ext;\n        write(path, firstLine ~ newline ~ code ~ newline);\n        version (Posix)\n        {\n            import core.sys.posix.sys.stat : chmod;\n            chmod(path.tempCString(), octal!777);\n        }\n    }\n\n    ~this()\n    {\n        import std.file : remove, exists;\n        if (!path.empty && exists(path))\n        {\n            try { remove(path); }\n            catch (Exception e)\n            {\n                debug std.stdio.stderr.writeln(e.msg);\n            }\n        }\n    }\n\n    string path;\n}\n\nversion (unittest)\nprivate string uniqueTempPath() @safe\n{\n    import std.file : tempDir;\n    import std.path : buildPath;\n    import std.uuid : randomUUID;\n    // Path should contain spaces to test escaping whitespace\n    return buildPath(tempDir(), \"std.process temporary file \" ~\n        randomUUID().toString());\n}\n\n\n// =============================================================================\n// Functions for shell command quoting/escaping.\n// =============================================================================\n\n\n/*\n    Command line arguments exist in three forms:\n    1) string or char* array, as received by main.\n       Also used internally on POSIX systems.\n    2) Command line string, as used in Windows'\n       CreateProcess and CommandLineToArgvW functions.\n       A specific quoting and escaping algorithm is used\n       to distinguish individual arguments.\n    3) Shell command string, as written at a shell prompt\n       or passed to cmd /C - this one may contain shell\n       control characters, e.g. > or | for redirection /\n       piping - thus, yet another layer of escaping is\n       used to distinguish them from program arguments.\n\n    Except for escapeWindowsArgument, the intermediary\n    format (2) is hidden away from the user in this module.\n*/\n\n/**\nEscapes an argv-style argument array to be used with $(LREF spawnShell),\n$(LREF pipeShell) or $(LREF executeShell).\n---\nstring url = \"http://dlang.org/\";\nexecuteShell(escapeShellCommand(\"wget\", url, \"-O\", \"dlang-index.html\"));\n---\n\nConcatenate multiple `escapeShellCommand` and\n$(LREF escapeShellFileName) results to use shell redirection or\npiping operators.\n---\nexecuteShell(\n    escapeShellCommand(\"curl\", \"http://dlang.org/download.html\") ~\n    \"|\" ~\n    escapeShellCommand(\"grep\", \"-o\", `http://\\S*\\.zip`) ~\n    \">\" ~\n    escapeShellFileName(\"D download links.txt\"));\n---\n\nThrows:\n$(OBJECTREF Exception) if any part of the command line contains unescapable\ncharacters (NUL on all platforms, as well as CR and LF on Windows).\n*/\nstring escapeShellCommand(scope const(char[])[] args...) @safe pure\n{\n    if (args.empty)\n        return null;\n    version (Windows)\n    {\n        // Do not ^-escape the first argument (the program path),\n        // as the shell parses it differently from parameters.\n        // ^-escaping a program path that contains spaces will fail.\n        string result = escapeShellFileName(args[0]);\n        if (args.length > 1)\n        {\n            result ~= \" \" ~ escapeShellCommandString(\n                escapeShellArguments(args[1..$]));\n        }\n        return result;\n    }\n    version (Posix)\n    {\n        return escapeShellCommandString(escapeShellArguments(args));\n    }\n}\n\n@safe unittest\n{\n    // This is a simple unit test without any special requirements,\n    // in addition to the unittest_burnin one below which requires\n    // special preparation.\n\n    struct TestVector { string[] args; string windows, posix; }\n    TestVector[] tests =\n    [\n        {\n            args    : [\"foo bar\"],\n            windows : `\"foo bar\"`,\n            posix   : `'foo bar'`\n        },\n        {\n            args    : [\"foo bar\", \"hello\"],\n            windows : `\"foo bar\" hello`,\n            posix   : `'foo bar' 'hello'`\n        },\n        {\n            args    : [\"foo bar\", \"hello world\"],\n            windows : `\"foo bar\" ^\"hello world^\"`,\n            posix   : `'foo bar' 'hello world'`\n        },\n        {\n            args    : [\"foo bar\", \"hello\", \"world\"],\n            windows : `\"foo bar\" hello world`,\n            posix   : `'foo bar' 'hello' 'world'`\n        },\n        {\n            args    : [\"foo bar\", `'\"^\\`],\n            windows : `\"foo bar\" ^\"'\\^\"^^\\\\^\"`,\n            posix   : `'foo bar' ''\\''\"^\\'`\n        },\n    ];\n\n    foreach (test; tests)\n        version (Windows)\n            assert(escapeShellCommand(test.args) == test.windows);\n        else\n            assert(escapeShellCommand(test.args) == test.posix  );\n}\n\nprivate string escapeShellCommandString(string command) @safe pure\n{\n    version (Windows)\n        return escapeWindowsShellCommand(command);\n    else\n        return command;\n}\n\nprivate string escapeWindowsShellCommand(scope const(char)[] command) @safe pure\n{\n    import std.array : appender;\n    auto result = appender!string();\n    result.reserve(command.length);\n\n    foreach (c; command)\n        switch (c)\n        {\n            case '\\0':\n                throw new Exception(\"Cannot put NUL in command line\");\n            case '\\r':\n            case '\\n':\n                throw new Exception(\"CR/LF are not escapable\");\n            case '\\x01': .. case '\\x09':\n            case '\\x0B': .. case '\\x0C':\n            case '\\x0E': .. case '\\x1F':\n            case '\"':\n            case '^':\n            case '&':\n            case '<':\n            case '>':\n            case '|':\n                result.put('^');\n                goto default;\n            default:\n                result.put(c);\n        }\n    return result.data;\n}\n\nprivate string escapeShellArguments(scope const(char[])[] args...)\n    @trusted pure nothrow\n{\n    import std.exception : assumeUnique;\n    char[] buf;\n\n    @safe nothrow\n    char[] allocator(size_t size)\n    {\n        if (buf.length == 0)\n            return buf = new char[size];\n        else\n        {\n            auto p = buf.length;\n            buf.length = buf.length + 1 + size;\n            buf[p++] = ' ';\n            return buf[p .. p+size];\n        }\n    }\n\n    foreach (arg; args)\n        escapeShellArgument!allocator(arg);\n    return assumeUnique(buf);\n}\n\nprivate auto escapeShellArgument(alias allocator)(scope const(char)[] arg) @safe nothrow\n{\n    // The unittest for this function requires special\n    // preparation - see below.\n\n    version (Windows)\n        return escapeWindowsArgumentImpl!allocator(arg);\n    else\n        return escapePosixArgumentImpl!allocator(arg);\n}\n\n/**\nQuotes a command-line argument in a manner conforming to the behavior of\n$(LINK2 http://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx,\nCommandLineToArgvW).\n*/\nstring escapeWindowsArgument(scope const(char)[] arg) @trusted pure nothrow\n{\n    // Rationale for leaving this function as public:\n    // this algorithm of escaping paths is also used in other software,\n    // e.g. DMD's response files.\n    import std.exception : assumeUnique;\n    auto buf = escapeWindowsArgumentImpl!charAllocator(arg);\n    return assumeUnique(buf);\n}\n\n\nprivate char[] charAllocator(size_t size) @safe pure nothrow\n{\n    return new char[size];\n}\n\n\nprivate char[] escapeWindowsArgumentImpl(alias allocator)(scope const(char)[] arg)\n    @safe nothrow\nif (is(typeof(allocator(size_t.init)[0] = char.init)))\n{\n    // References:\n    // * http://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx\n    // * http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx\n\n    // Check if the string needs to be escaped,\n    // and calculate the total string size.\n\n    // Trailing backslashes must be escaped\n    bool escaping = true;\n    bool needEscape = false;\n    // Result size = input size + 2 for surrounding quotes + 1 for the\n    // backslash for each escaped character.\n    size_t size = 1 + arg.length + 1;\n\n    foreach_reverse (char c; arg)\n    {\n        if (c == '\"')\n        {\n            needEscape = true;\n            escaping = true;\n            size++;\n        }\n        else\n        if (c == '\\\\')\n        {\n            if (escaping)\n                size++;\n        }\n        else\n        {\n            if (c == ' ' || c == '\\t')\n                needEscape = true;\n            escaping = false;\n        }\n    }\n\n    import std.ascii : isDigit;\n    // Empty arguments need to be specified as \"\"\n    if (!arg.length)\n        needEscape = true;\n    else\n    // Arguments ending with digits need to be escaped,\n    // to disambiguate with 1>file redirection syntax\n    if (isDigit(arg[$-1]))\n        needEscape = true;\n\n    if (!needEscape)\n        return allocator(arg.length)[] = arg;\n\n    // Construct result string.\n\n    auto buf = allocator(size);\n    size_t p = size;\n    buf[--p] = '\"';\n    escaping = true;\n    foreach_reverse (char c; arg)\n    {\n        if (c == '\"')\n            escaping = true;\n        else\n        if (c != '\\\\')\n            escaping = false;\n\n        buf[--p] = c;\n        if (escaping)\n            buf[--p] = '\\\\';\n    }\n    buf[--p] = '\"';\n    assert(p == 0);\n\n    return buf;\n}\n\nversion (Windows) version (unittest)\n{\nprivate:\n    import core.stdc.stddef;\n    import core.stdc.wchar_ : wcslen;\n    import core.sys.windows.shellapi : CommandLineToArgvW;\n    import core.sys.windows.windows;\n    import std.array;\n\n    string[] parseCommandLine(string line)\n    {\n        import std.algorithm.iteration : map;\n        import std.array : array;\n        LPWSTR lpCommandLine = (to!(wchar[])(line) ~ \"\\0\"w).ptr;\n        int numArgs;\n        LPWSTR* args = CommandLineToArgvW(lpCommandLine, &numArgs);\n        scope(exit) LocalFree(args);\n        return args[0 .. numArgs]\n            .map!(arg => to!string(arg[0 .. wcslen(arg)]))\n            .array();\n    }\n\n    @system unittest\n    {\n        string[] testStrings = [\n            `Hello`,\n            `Hello, world`,\n            `Hello, \"world\"`,\n            `C:\\`,\n            `C:\\dmd`,\n            `C:\\Program Files\\`,\n        ];\n\n        enum CHARS = `_x\\\" *&^` ~ \"\\t\"; // _ is placeholder for nothing\n        foreach (c1; CHARS)\n        foreach (c2; CHARS)\n        foreach (c3; CHARS)\n        foreach (c4; CHARS)\n            testStrings ~= [c1, c2, c3, c4].replace(\"_\", \"\");\n\n        foreach (s; testStrings)\n        {\n            auto q = escapeWindowsArgument(s);\n            auto args = parseCommandLine(\"Dummy.exe \" ~ q);\n            assert(args.length == 2, s ~ \" => \" ~ q ~ \" #\" ~ text(args.length-1));\n            assert(args[1] == s, s ~ \" => \" ~ q ~ \" => \" ~ args[1]);\n        }\n    }\n}\n\nprivate string escapePosixArgument(scope const(char)[] arg) @trusted pure nothrow\n{\n    import std.exception : assumeUnique;\n    auto buf = escapePosixArgumentImpl!charAllocator(arg);\n    return assumeUnique(buf);\n}\n\nprivate char[] escapePosixArgumentImpl(alias allocator)(scope const(char)[] arg)\n    @safe nothrow\nif (is(typeof(allocator(size_t.init)[0] = char.init)))\n{\n    // '\\'' means: close quoted part of argument, append an escaped\n    // single quote, and reopen quotes\n\n    // Below code is equivalent to:\n    // return `'` ~ std.array.replace(arg, `'`, `'\\''`) ~ `'`;\n\n    size_t size = 1 + arg.length + 1;\n    foreach (char c; arg)\n        if (c == '\\'')\n            size += 3;\n\n    auto buf = allocator(size);\n    size_t p = 0;\n    buf[p++] = '\\'';\n    foreach (char c; arg)\n        if (c == '\\'')\n        {\n            buf[p .. p+4] = `'\\''`;\n            p += 4;\n        }\n        else\n            buf[p++] = c;\n    buf[p++] = '\\'';\n    assert(p == size);\n\n    return buf;\n}\n\n/**\nEscapes a filename to be used for shell redirection with $(LREF spawnShell),\n$(LREF pipeShell) or $(LREF executeShell).\n*/\nstring escapeShellFileName(scope const(char)[] fileName) @trusted pure nothrow\n{\n    // The unittest for this function requires special\n    // preparation - see below.\n\n    version (Windows)\n    {\n        // If a file starts with &, it can cause cmd.exe to misinterpret\n        // the file name as the stream redirection syntax:\n        //     command > \"&foo.txt\"\n        // gets interpreted as\n        //     command >&foo.txt\n        // Prepend .\\ to disambiguate.\n\n        if (fileName.length && fileName[0] == '&')\n            return cast(string)(`\".\\` ~ fileName ~ '\"');\n\n        return cast(string)('\"' ~ fileName ~ '\"');\n    }\n    else\n        return escapePosixArgument(fileName);\n}\n\n// Loop generating strings with random characters\n//version = unittest_burnin;\n\nversion (unittest_burnin)\n@system unittest\n{\n    // There are no readily-available commands on all platforms suitable\n    // for properly testing command escaping. The behavior of CMD's \"echo\"\n    // built-in differs from the POSIX program, and Windows ports of POSIX\n    // environments (Cygwin, msys, gnuwin32) may interfere with their own\n    // \"echo\" ports.\n\n    // To run this unit test, create std_process_unittest_helper.d with the\n    // following content and compile it:\n    // import std.stdio, std.array; void main(string[] args) { write(args.join(\"\\0\")); }\n    // Then, test this module with:\n    // rdmd --main -unittest -version=unittest_burnin process.d\n\n    auto helper = absolutePath(\"std_process_unittest_helper\");\n    assert(executeShell(helper ~ \" hello\").output.split(\"\\0\")[1..$] == [\"hello\"], \"Helper malfunction\");\n\n    void test(string[] s, string fn)\n    {\n        string e;\n        string[] g;\n\n        e = escapeShellCommand(helper ~ s);\n        {\n            scope(failure) writefln(\"executeShell() failed.\\nExpected:\\t%s\\nEncoded:\\t%s\", s, [e]);\n            auto result = executeShell(e);\n            assert(result.status == 0, \"std_process_unittest_helper failed\");\n            g = result.output.split(\"\\0\")[1..$];\n        }\n        assert(s == g, format(\"executeShell() test failed.\\nExpected:\\t%s\\nGot:\\t\\t%s\\nEncoded:\\t%s\", s, g, [e]));\n\n        e = escapeShellCommand(helper ~ s) ~ \">\" ~ escapeShellFileName(fn);\n        {\n            scope(failure) writefln(\n                \"executeShell() with redirect failed.\\nExpected:\\t%s\\nFilename:\\t%s\\nEncoded:\\t%s\", s, [fn], [e]);\n            auto result = executeShell(e);\n            assert(result.status == 0, \"std_process_unittest_helper failed\");\n            assert(!result.output.length, \"No output expected, got:\\n\" ~ result.output);\n            g = readText(fn).split(\"\\0\")[1..$];\n        }\n        remove(fn);\n        assert(s == g,\n            format(\"executeShell() with redirect test failed.\\nExpected:\\t%s\\nGot:\\t\\t%s\\nEncoded:\\t%s\", s, g, [e]));\n    }\n\n    while (true)\n    {\n        string[] args;\n        foreach (n; 0 .. uniform(1, 4))\n        {\n            string arg;\n            foreach (l; 0 .. uniform(0, 10))\n            {\n                dchar c;\n                while (true)\n                {\n                    version (Windows)\n                    {\n                        // As long as DMD's system() uses CreateProcessA,\n                        // we can't reliably pass Unicode\n                        c = uniform(0, 128);\n                    }\n                    else\n                        c = uniform!ubyte();\n\n                    if (c == 0)\n                        continue; // argv-strings are zero-terminated\n                    version (Windows)\n                        if (c == '\\r' || c == '\\n')\n                            continue; // newlines are unescapable on Windows\n                    break;\n                }\n                arg ~= c;\n            }\n            args ~= arg;\n        }\n\n        // generate filename\n        string fn;\n        foreach (l; 0 .. uniform(1, 10))\n        {\n            dchar c;\n            while (true)\n            {\n                version (Windows)\n                    c = uniform(0, 128); // as above\n                else\n                    c = uniform!ubyte();\n\n                if (c == 0 || c == '/')\n                    continue; // NUL and / are the only characters\n                              // forbidden in POSIX filenames\n                version (Windows)\n                    if (c < '\\x20' || c == '<' || c == '>' || c == ':' ||\n                        c == '\"' || c == '\\\\' || c == '|' || c == '?' || c == '*')\n                        continue; // http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx\n                break;\n            }\n\n            fn ~= c;\n        }\n        fn = fn[0..$/2] ~ \"_testfile_\" ~ fn[$/2..$];\n\n        test(args, fn);\n    }\n}\n\n\n// =============================================================================\n// Environment variable manipulation.\n// =============================================================================\n\n\n/**\nManipulates _environment variables using an associative-array-like\ninterface.\n\nThis class contains only static methods, and cannot be instantiated.\nSee below for examples of use.\n*/\nabstract final class environment\n{\nstatic:\n    /**\n    Retrieves the value of the environment variable with the given `name`.\n    ---\n    auto path = environment[\"PATH\"];\n    ---\n\n    Throws:\n    $(OBJECTREF Exception) if the environment variable does not exist,\n    or $(REF UTFException, std,utf) if the variable contains invalid UTF-16\n    characters (Windows only).\n\n    See_also:\n    $(LREF environment.get), which doesn't throw on failure.\n    */\n    string opIndex(scope const(char)[] name) @safe\n    {\n        import std.exception : enforce;\n        string value;\n        enforce(getImpl(name, value), \"Environment variable not found: \"~name);\n        return value;\n    }\n\n    /**\n    Retrieves the value of the environment variable with the given `name`,\n    or a default value if the variable doesn't exist.\n\n    Unlike $(LREF environment.opIndex), this function never throws on Posix.\n    ---\n    auto sh = environment.get(\"SHELL\", \"/bin/sh\");\n    ---\n    This function is also useful in checking for the existence of an\n    environment variable.\n    ---\n    auto myVar = environment.get(\"MYVAR\");\n    if (myVar is null)\n    {\n        // Environment variable doesn't exist.\n        // Note that we have to use 'is' for the comparison, since\n        // myVar == null is also true if the variable exists but is\n        // empty.\n    }\n    ---\n    Params:\n        name = name of the environment variable to retrieve\n        defaultValue = default value to return if the environment variable doesn't exist.\n\n    Returns:\n        the value of the environment variable if found, otherwise\n        `null` if the environment doesn't exist.\n\n    Throws:\n    $(REF UTFException, std,utf) if the variable contains invalid UTF-16\n    characters (Windows only).\n    */\n    string get(scope const(char)[] name, string defaultValue = null) @safe\n    {\n        string value;\n        auto found = getImpl(name, value);\n        return found ? value : defaultValue;\n    }\n\n    /**\n    Assigns the given `value` to the environment variable with the given\n    `name`.\n    If `value` is null the variable is removed from environment.\n\n    If the variable does not exist, it will be created. If it already exists,\n    it will be overwritten.\n    ---\n    environment[\"foo\"] = \"bar\";\n    ---\n\n    Throws:\n    $(OBJECTREF Exception) if the environment variable could not be added\n        (e.g. if the name is invalid).\n\n    Note:\n    On some platforms, modifying environment variables may not be allowed in\n    multi-threaded programs. See e.g.\n    $(LINK2 https://www.gnu.org/software/libc/manual/html_node/Environment-Access.html#Environment-Access, glibc).\n    */\n    inout(char)[] opIndexAssign(inout char[] value, scope const(char)[] name) @trusted\n    {\n        version (Posix)\n        {\n            import std.exception : enforce, errnoEnforce;\n            if (value is null)\n            {\n                remove(name);\n                return value;\n            }\n            if (core.sys.posix.stdlib.setenv(name.tempCString(), value.tempCString(), 1) != -1)\n            {\n                return value;\n            }\n            // The default errno error message is very uninformative\n            // in the most common case, so we handle it manually.\n            enforce(errno != EINVAL,\n                \"Invalid environment variable name: '\"~name~\"'\");\n            errnoEnforce(false,\n                \"Failed to add environment variable\");\n            assert(0);\n        }\n        else version (Windows)\n        {\n            import std.exception : enforce;\n            enforce(\n                SetEnvironmentVariableW(name.tempCStringW(), value.tempCStringW()),\n                sysErrorString(GetLastError())\n            );\n            return value;\n        }\n        else static assert(0);\n    }\n\n    /**\n    Removes the environment variable with the given `name`.\n\n    If the variable isn't in the environment, this function returns\n    successfully without doing anything.\n\n    Note:\n    On some platforms, modifying environment variables may not be allowed in\n    multi-threaded programs. See e.g.\n    $(LINK2 https://www.gnu.org/software/libc/manual/html_node/Environment-Access.html#Environment-Access, glibc).\n    */\n    void remove(scope const(char)[] name) @trusted nothrow @nogc // TODO: @safe\n    {\n        version (Windows)    SetEnvironmentVariableW(name.tempCStringW(), null);\n        else version (Posix) core.sys.posix.stdlib.unsetenv(name.tempCString());\n        else static assert(0);\n    }\n\n    /**\n    Identify whether a variable is defined in the environment.\n\n    Because it doesn't return the value, this function is cheaper than `get`.\n    However, if you do need the value as well, you should just check the\n    return of `get` for `null` instead of using this function first.\n\n    Example:\n    -------------\n    // good usage\n    if (\"MY_ENV_FLAG\" in environment)\n        doSomething();\n\n    // bad usage\n    if (\"MY_ENV_VAR\" in environment)\n        doSomething(environment[\"MY_ENV_VAR\"]);\n\n    // do this instead\n    if (auto var = environment.get(\"MY_ENV_VAR\"))\n        doSomething(var);\n    -------------\n    */\n    bool opBinaryRight(string op : \"in\")(scope const(char)[] name) @trusted\n    {\n        version (Posix)\n            return core.sys.posix.stdlib.getenv(name.tempCString()) !is null;\n        else version (Windows)\n        {\n            SetLastError(NO_ERROR);\n            if (GetEnvironmentVariableW(name.tempCStringW, null, 0) > 0)\n                return true;\n            immutable err = GetLastError();\n            if (err == ERROR_ENVVAR_NOT_FOUND)\n                return false;\n            // some other windows error. Might actually be NO_ERROR, because\n            // GetEnvironmentVariable doesn't specify whether it sets on all\n            // failures\n            throw new WindowsException(err);\n        }\n        else static assert(0);\n    }\n\n    /**\n    Copies all environment variables into an associative array.\n\n    Windows_specific:\n    While Windows environment variable names are case insensitive, D's\n    built-in associative arrays are not.  This function will store all\n    variable names in uppercase (e.g. `PATH`).\n\n    Throws:\n    $(OBJECTREF Exception) if the environment variables could not\n        be retrieved (Windows only).\n    */\n    string[string] toAA() @trusted\n    {\n        import std.conv : to;\n        string[string] aa;\n        version (Posix)\n        {\n            auto environ = getEnvironPtr;\n            for (int i=0; environ[i] != null; ++i)\n            {\n                import std.string : indexOf;\n\n                immutable varDef = to!string(environ[i]);\n                immutable eq = indexOf(varDef, '=');\n                assert(eq >= 0);\n\n                immutable name = varDef[0 .. eq];\n                immutable value = varDef[eq+1 .. $];\n\n                // In POSIX, environment variables may be defined more\n                // than once.  This is a security issue, which we avoid\n                // by checking whether the key already exists in the array.\n                // For more info:\n                // http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/environment-variables.html\n                if (name !in aa)  aa[name] = value;\n            }\n        }\n        else version (Windows)\n        {\n            import std.exception : enforce;\n            import std.uni : toUpper;\n            auto envBlock = GetEnvironmentStringsW();\n            enforce(envBlock, \"Failed to retrieve environment variables.\");\n            scope(exit) FreeEnvironmentStringsW(envBlock);\n\n            for (int i=0; envBlock[i] != '\\0'; ++i)\n            {\n                auto start = i;\n                while (envBlock[i] != '=') ++i;\n                immutable name = toUTF8(toUpper(envBlock[start .. i]));\n\n                start = i+1;\n                while (envBlock[i] != '\\0') ++i;\n\n                // Ignore variables with empty names. These are used internally\n                // by Windows to keep track of each drive's individual current\n                // directory.\n                if (!name.length)\n                    continue;\n\n                // Just like in POSIX systems, environment variables may be\n                // defined more than once in an environment block on Windows,\n                // and it is just as much of a security issue there.  Moreso,\n                // in fact, due to the case insensensitivity of variable names,\n                // which is not handled correctly by all programs.\n                auto val = toUTF8(envBlock[start .. i]);\n                if (name !in aa) aa[name] = val is null ? \"\" : val;\n            }\n        }\n        else static assert(0);\n        return aa;\n    }\n\nprivate:\n    // Retrieves the environment variable, returns false on failure.\n    bool getImpl(scope const(char)[] name, out string value) @trusted\n    {\n        version (Windows)\n        {\n            // first we ask windows how long the environment variable is,\n            // then we try to read it in to a buffer of that length. Lots\n            // of error conditions because the windows API is nasty.\n\n            import std.conv : to;\n            const namezTmp = name.tempCStringW();\n            WCHAR[] buf;\n\n            // clear error because GetEnvironmentVariable only says it sets it\n            // if the environment variable is missing, not on other errors.\n            SetLastError(NO_ERROR);\n            // len includes terminating null\n            immutable len = GetEnvironmentVariableW(namezTmp, null, 0);\n            if (len == 0)\n            {\n                immutable err = GetLastError();\n                if (err == ERROR_ENVVAR_NOT_FOUND)\n                    return false;\n                // some other windows error. Might actually be NO_ERROR, because\n                // GetEnvironmentVariable doesn't specify whether it sets on all\n                // failures\n                throw new WindowsException(err);\n            }\n            if (len == 1)\n            {\n                value = \"\";\n                return true;\n            }\n            buf.length = len;\n\n            while (true)\n            {\n                // lenRead is either the number of bytes read w/o null - if buf was long enough - or\n                // the number of bytes necessary *including* null if buf wasn't long enough\n                immutable lenRead = GetEnvironmentVariableW(namezTmp, buf.ptr, to!DWORD(buf.length));\n                if (lenRead == 0)\n                {\n                    immutable err = GetLastError();\n                    if (err == NO_ERROR) // sucessfully read a 0-length variable\n                    {\n                        value = \"\";\n                        return true;\n                    }\n                    if (err == ERROR_ENVVAR_NOT_FOUND) // variable didn't exist\n                        return false;\n                    // some other windows error\n                    throw new WindowsException(err);\n                }\n                assert(lenRead != buf.length, \"impossible according to msft docs\");\n                if (lenRead < buf.length) // the buffer was long enough\n                {\n                    value = toUTF8(buf[0 .. lenRead]);\n                    return true;\n                }\n                // resize and go around again, because the environment variable grew\n                buf.length = lenRead;\n            }\n        }\n        else version (Posix)\n        {\n            const vz = core.sys.posix.stdlib.getenv(name.tempCString());\n            if (vz == null) return false;\n            auto v = vz[0 .. strlen(vz)];\n\n            // Cache the last call's result.\n            static string lastResult;\n            if (v.empty)\n            {\n                // Return non-null array for blank result to distinguish from\n                // not-present result.\n                lastResult = \"\";\n            }\n            else if (v != lastResult)\n            {\n                lastResult = v.idup;\n            }\n            value = lastResult;\n            return true;\n        }\n        else static assert(0);\n    }\n}\n\n@safe unittest\n{\n    import std.exception : assertThrown;\n    // New variable\n    environment[\"std_process\"] = \"foo\";\n    assert(environment[\"std_process\"] == \"foo\");\n    assert(\"std_process\" in environment);\n\n    // Set variable again (also tests length 1 case)\n    environment[\"std_process\"] = \"b\";\n    assert(environment[\"std_process\"] == \"b\");\n    assert(\"std_process\" in environment);\n\n    // Remove variable\n    environment.remove(\"std_process\");\n    assert(\"std_process\" !in environment);\n\n    // Remove again, should succeed\n    environment.remove(\"std_process\");\n    assert(\"std_process\" !in environment);\n\n    // Throw on not found.\n    assertThrown(environment[\"std_process\"]);\n\n    // get() without default value\n    assert(environment.get(\"std_process\") is null);\n\n    // get() with default value\n    assert(environment.get(\"std_process\", \"baz\") == \"baz\");\n\n    // get() on an empty (but present) value\n    environment[\"std_process\"] = \"\";\n    auto res = environment.get(\"std_process\");\n    assert(res !is null);\n    assert(res == \"\");\n    assert(\"std_process\" in environment);\n\n    // Important to do the following round-trip after the previous test\n    // because it tests toAA with an empty var\n\n    // Convert to associative array\n    auto aa = environment.toAA();\n    assert(aa.length > 0);\n    foreach (n, v; aa)\n    {\n        // Wine has some bugs related to environment variables:\n        //  - Wine allows the existence of an env. variable with the name\n        //    \"\\0\", but GetEnvironmentVariable refuses to retrieve it.\n        //    As of 2.067 we filter these out anyway (see comment in toAA).\n\n        assert(v == environment[n]);\n    }\n\n    // ... and back again.\n    foreach (n, v; aa)\n        environment[n] = v;\n\n    // Complete the roundtrip\n    auto aa2 = environment.toAA();\n    import std.conv : text;\n    assert(aa == aa2, text(aa, \" != \", aa2));\n    assert(\"std_process\" in environment);\n\n    // Setting null must have the same effect as remove\n    environment[\"std_process\"] = null;\n    assert(\"std_process\" !in environment);\n}\n\n\n\n\n// =============================================================================\n// Everything below this line was part of the old std.process, and most of\n// it will be deprecated and removed.\n// =============================================================================\n\n\n/*\nCopyright: Copyright The D Language Foundation 2007 - 2009.\nLicense:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   $(HTTP digitalmars.com, Walter Bright),\n           $(HTTP erdani.org, Andrei Alexandrescu),\n           $(HTTP thecybershadow.net, Vladimir Panteleev)\nSource:    $(PHOBOSSRC std/_process.d)\n*/\n/*\n         Copyright The D Language Foundation 2007 - 2009.\nDistributed under the Boost Software License, Version 1.0.\n   (See accompanying file LICENSE_1_0.txt or copy at\n         http://www.boost.org/LICENSE_1_0.txt)\n*/\n\n\nimport core.stdc.errno;\nimport core.stdc.stdlib;\nimport core.stdc.string;\nimport core.thread;\n\nversion (Windows)\n{\n    import std.file, std.format, std.random;\n}\nversion (Posix)\n{\n    import core.sys.posix.stdlib;\n}\nversion (unittest)\n{\n    import std.conv, std.file, std.random;\n}\n\n\nprivate void toAStringz(in string[] a, const(char)**az)\n{\n    import std.string : toStringz;\n    foreach (string s; a)\n    {\n        *az++ = toStringz(s);\n    }\n    *az = null;\n}\n\n\n/* ========================================================== */\n\n//version (Windows)\n//{\n//    int spawnvp(int mode, string pathname, string[] argv)\n//    {\n//      char** argv_ = cast(char**) core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));\n//      scope(exit) core.stdc.stdlib.free(argv_);\n//\n//      toAStringz(argv, argv_);\n//\n//      return spawnvp(mode, pathname.tempCString(), argv_);\n//    }\n//}\n\n// Incorporating idea (for spawnvp() on Posix) from Dave Fladebo\n\nenum { _P_WAIT, _P_NOWAIT, _P_OVERLAY }\nversion (Windows) extern(C) int spawnvp(int, scope const(char) *, scope const(char*)*);\nalias P_WAIT = _P_WAIT;\nalias P_NOWAIT = _P_NOWAIT;\n\n/* ========================================================== */\n\nversion (StdDdoc)\n{\n    /**\n    Replaces the current process by executing a command, `pathname`, with\n    the arguments in `argv`.\n\n    $(BLUE This function is Posix-Only.)\n\n    Typically, the first element of `argv` is\n    the command being executed, i.e. $(D argv[0] == pathname). The 'p'\n    versions of `exec` search the PATH environment variable for $(D\n    pathname). The 'e' versions additionally take the new process'\n    environment variables as an array of strings of the form key=value.\n\n    Does not return on success (the current process will have been\n    replaced). Returns -1 on failure with no indication of the\n    underlying error.\n\n    Windows_specific:\n    These functions are only supported on POSIX platforms, as the Windows\n    operating systems do not provide the ability to overwrite the current\n    process image with another. In single-threaded programs it is possible\n    to approximate the effect of `execv*` by using $(LREF spawnProcess)\n    and terminating the current process once the child process has returned.\n    For example:\n    ---\n    auto commandLine = [ \"program\", \"arg1\", \"arg2\" ];\n    version (Posix)\n    {\n        execv(commandLine[0], commandLine);\n        throw new Exception(\"Failed to execute program\");\n    }\n    else version (Windows)\n    {\n        import core.stdc.stdlib : _exit;\n        _exit(wait(spawnProcess(commandLine)));\n    }\n    ---\n    This is, however, NOT equivalent to POSIX' `execv*`.  For one thing, the\n    executed program is started as a separate process, with all this entails.\n    Secondly, in a multithreaded program, other threads will continue to do\n    work while the current thread is waiting for the child process to complete.\n\n    A better option may sometimes be to terminate the current program immediately\n    after spawning the child process.  This is the behaviour exhibited by the\n    $(LINK2 http://msdn.microsoft.com/en-us/library/431x4c1w.aspx,`__exec`)\n    functions in Microsoft's C runtime library, and it is how D's now-deprecated\n    Windows `execv*` functions work. Example:\n    ---\n    auto commandLine = [ \"program\", \"arg1\", \"arg2\" ];\n    version (Posix)\n    {\n        execv(commandLine[0], commandLine);\n        throw new Exception(\"Failed to execute program\");\n    }\n    else version (Windows)\n    {\n        spawnProcess(commandLine);\n        import core.stdc.stdlib : _exit;\n        _exit(0);\n    }\n    ---\n    */\n    int execv(in string pathname, in string[] argv);\n    ///ditto\n    int execve(in string pathname, in string[] argv, in string[] envp);\n    /// ditto\n    int execvp(in string pathname, in string[] argv);\n    /// ditto\n    int execvpe(in string pathname, in string[] argv, in string[] envp);\n}\nelse version (Posix)\n{\n    int execv(in string pathname, in string[] argv)\n    {\n        return execv_(pathname, argv);\n    }\n    int execve(in string pathname, in string[] argv, in string[] envp)\n    {\n        return execve_(pathname, argv, envp);\n    }\n    int execvp(in string pathname, in string[] argv)\n    {\n        return execvp_(pathname, argv);\n    }\n    int execvpe(in string pathname, in string[] argv, in string[] envp)\n    {\n        return execvpe_(pathname, argv, envp);\n    }\n}\n\n// Move these C declarations to druntime if we decide to keep the D wrappers\nextern(C)\n{\n    int execv(scope const(char) *, scope const(char *)*);\n    int execve(scope const(char)*, scope const(char*)*, scope const(char*)*);\n    int execvp(scope const(char)*, scope const(char*)*);\n    version (Windows) int execvpe(scope const(char)*, scope const(char*)*, scope const(char*)*);\n}\n\nprivate int execv_(in string pathname, in string[] argv)\n{\n    auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));\n    scope(exit) core.stdc.stdlib.free(argv_);\n\n    toAStringz(argv, argv_);\n\n    return execv(pathname.tempCString(), argv_);\n}\n\nprivate int execve_(in string pathname, in string[] argv, in string[] envp)\n{\n    auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));\n    scope(exit) core.stdc.stdlib.free(argv_);\n    auto envp_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + envp.length));\n    scope(exit) core.stdc.stdlib.free(envp_);\n\n    toAStringz(argv, argv_);\n    toAStringz(envp, envp_);\n\n    return execve(pathname.tempCString(), argv_, envp_);\n}\n\nprivate int execvp_(in string pathname, in string[] argv)\n{\n    auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));\n    scope(exit) core.stdc.stdlib.free(argv_);\n\n    toAStringz(argv, argv_);\n\n    return execvp(pathname.tempCString(), argv_);\n}\n\nprivate int execvpe_(in string pathname, in string[] argv, in string[] envp)\n{\nversion (Posix)\n{\n    import std.array : split;\n    import std.conv : to;\n    // Is pathname rooted?\n    if (pathname[0] == '/')\n    {\n        // Yes, so just call execve()\n        return execve(pathname, argv, envp);\n    }\n    else\n    {\n        // No, so must traverse PATHs, looking for first match\n        string[]    envPaths    =   split(\n            to!string(core.stdc.stdlib.getenv(\"PATH\")), \":\");\n        int         iRet        =   0;\n\n        // Note: if any call to execve() succeeds, this process will cease\n        // execution, so there's no need to check the execve() result through\n        // the loop.\n\n        foreach (string pathDir; envPaths)\n        {\n            string  composite   =  cast(string) (pathDir ~ \"/\" ~ pathname);\n\n            iRet = execve(composite, argv, envp);\n        }\n        if (0 != iRet)\n        {\n            iRet = execve(pathname, argv, envp);\n        }\n\n        return iRet;\n    }\n}\nelse version (Windows)\n{\n    auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));\n    scope(exit) core.stdc.stdlib.free(argv_);\n    auto envp_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + envp.length));\n    scope(exit) core.stdc.stdlib.free(envp_);\n\n    toAStringz(argv, argv_);\n    toAStringz(envp, envp_);\n\n    return execvpe(pathname.tempCString(), argv_, envp_);\n}\nelse\n{\n    static assert(0);\n} // version\n}\n\nversion (StdDdoc)\n{\n    /****************************************\n     * Start up the browser and set it to viewing the page at url.\n     */\n    void browse(scope const(char)[] url);\n}\nelse\nversion (Windows)\n{\n    import core.sys.windows.windows;\n\n    pragma(lib,\"shell32.lib\");\n\n    void browse(scope const(char)[] url)\n    {\n        ShellExecuteW(null, \"open\", url.tempCStringW(), null, null, SW_SHOWNORMAL);\n    }\n}\nelse version (OSX)\n{\n    import core.stdc.stdio;\n    import core.stdc.string;\n    import core.sys.posix.unistd;\n\n    void browse(scope const(char)[] url) nothrow @nogc\n    {\n        const(char)*[5] args;\n\n        auto curl = url.tempCString();\n        const(char)* browser = core.stdc.stdlib.getenv(\"BROWSER\");\n        if (browser)\n        {   browser = strdup(browser);\n            args[0] = browser;\n            args[1] = curl;\n            args[2] = null;\n        }\n        else\n        {\n            args[0] = \"open\".ptr;\n            args[1] = curl;\n            args[2] = null;\n        }\n\n        auto childpid = core.sys.posix.unistd.fork();\n        if (childpid == 0)\n        {\n            core.sys.posix.unistd.execvp(args[0], cast(char**) args.ptr);\n            perror(args[0]);                // failed to execute\n            return;\n        }\n        if (browser)\n            free(cast(void*) browser);\n    }\n}\nelse version (Posix)\n{\n    import core.stdc.stdio;\n    import core.stdc.string;\n    import core.sys.posix.unistd;\n\n    void browse(scope const(char)[] url) nothrow @nogc\n    {\n        const(char)*[3] args;\n\n        const(char)* browser = core.stdc.stdlib.getenv(\"BROWSER\");\n        if (browser)\n        {   browser = strdup(browser);\n            args[0] = browser;\n        }\n        else\n            //args[0] = \"x-www-browser\".ptr;  // doesn't work on some systems\n            args[0] = \"xdg-open\".ptr;\n\n        args[1] = url.tempCString();\n        args[2] = null;\n\n        auto childpid = core.sys.posix.unistd.fork();\n        if (childpid == 0)\n        {\n            core.sys.posix.unistd.execvp(args[0], cast(char**) args.ptr);\n            perror(args[0]);                // failed to execute\n            return;\n        }\n        if (browser)\n            free(cast(void*) browser);\n    }\n}\nelse\n    static assert(0, \"os not supported\");\n"
  },
  {
    "path": "libphobos/src/std/random.d",
    "content": "// Written in the D programming language.\n\n/**\nFacilities for random number generation.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Uniform sampling) $(TD\n    $(LREF uniform)\n    $(LREF uniform01)\n    $(LREF uniformDistribution)\n))\n$(TR $(TD Element sampling) $(TD\n    $(LREF choice)\n    $(LREF dice)\n))\n$(TR $(TD Range sampling) $(TD\n    $(LREF randomCover)\n    $(LREF randomSample)\n))\n$(TR $(TD Default Random Engines) $(TD\n    $(LREF rndGen)\n    $(LREF Random)\n    $(LREF unpredictableSeed)\n))\n$(TR $(TD Linear Congruential Engines) $(TD\n    $(LREF MinstdRand)\n    $(LREF MinstdRand0)\n    $(LREF LinearCongruentialEngine)\n))\n$(TR $(TD Mersenne Twister Engines) $(TD\n    $(LREF Mt19937)\n    $(LREF Mt19937_64)\n    $(LREF MersenneTwisterEngine)\n))\n$(TR $(TD Xorshift Engines) $(TD\n    $(LREF Xorshift)\n    $(LREF XorshiftEngine)\n    $(LREF Xorshift32)\n    $(LREF Xorshift64)\n    $(LREF Xorshift96)\n    $(LREF Xorshift128)\n    $(LREF Xorshift160)\n    $(LREF Xorshift192)\n))\n$(TR $(TD Shuffle) $(TD\n    $(LREF partialShuffle)\n    $(LREF randomShuffle)\n))\n$(TR $(TD Traits) $(TD\n    $(LREF isSeedable)\n    $(LREF isUniformRNG)\n))\n)\n\n$(RED Disclaimer:) The random number generators and API provided in this\nmodule are not designed to be cryptographically secure, and are therefore\nunsuitable for cryptographic or security-related purposes such as generating\nauthentication tokens or network sequence numbers. For such needs, please use a\nreputable cryptographic library instead.\n\nThe new-style generator objects hold their own state so they are\nimmune of threading issues. The generators feature a number of\nwell-known and well-documented methods of generating random\nnumbers. An overall fast and reliable means to generate random numbers\nis the $(D_PARAM Mt19937) generator, which derives its name from\n\"$(LINK2 https://en.wikipedia.org/wiki/Mersenne_Twister, Mersenne Twister)\nwith a period of 2 to the power of\n19937\". In memory-constrained situations,\n$(LINK2 https://en.wikipedia.org/wiki/Linear_congruential_generator,\nlinear congruential generators) such as `MinstdRand0` and `MinstdRand` might be\nuseful. The standard library provides an alias $(D_PARAM Random) for\nwhichever generator it considers the most fit for the target\nenvironment.\n\nIn addition to random number generators, this module features\ndistributions, which skew a generator's output statistical\ndistribution in various ways. So far the uniform distribution for\nintegers and real numbers have been implemented.\n\nSource:    $(PHOBOSSRC std/random.d)\n\nMacros:\n\nCopyright: Copyright Andrei Alexandrescu 2008 - 2009, Joseph Rushton Wakeling 2012.\nLicense:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   $(HTTP erdani.org, Andrei Alexandrescu)\n           Masahiro Nakagawa (Xorshift random generator)\n           $(HTTP braingam.es, Joseph Rushton Wakeling) (Algorithm D for random sampling)\n           Ilya Yaroshenko (Mersenne Twister implementation, adapted from $(HTTPS github.com/libmir/mir-random, mir-random))\nCredits:   The entire random number library architecture is derived from the\n           excellent $(HTTP open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf, C++0X)\n           random number facility proposed by Jens Maurer and contributed to by\n           researchers at the Fermi laboratory (excluding Xorshift).\n*/\n/*\n         Copyright Andrei Alexandrescu 2008 - 2009.\nDistributed under the Boost Software License, Version 1.0.\n   (See accompanying file LICENSE_1_0.txt or copy at\n         http://www.boost.org/LICENSE_1_0.txt)\n*/\nmodule std.random;\n\n\nimport std.range.primitives;\nimport std.traits;\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : among, equal;\n    import std.range : iota;\n\n    // seed a random generator with a constant\n    auto rnd = Random(42);\n\n    // Generate a uniformly-distributed integer in the range [0, 14]\n    // If no random generator is passed, the global `rndGen` would be used\n    auto i = uniform(0, 15, rnd);\n    assert(i >= 0 && i < 15);\n\n    // Generate a uniformly-distributed real in the range [0, 100)\n    auto r = uniform(0.0L, 100.0L, rnd);\n    assert(r >= 0 && r < 100);\n\n    // Sample from a custom type\n    enum Fruit { apple, mango, pear }\n    auto f = rnd.uniform!Fruit;\n    with(Fruit)\n    assert(f.among(apple, mango, pear));\n\n    // Generate a 32-bit random number\n    auto u = uniform!uint(rnd);\n    static assert(is(typeof(u) == uint));\n\n    // Generate a random number in the range in the range [0, 1)\n    auto u2 = uniform01(rnd);\n    assert(u2 >= 0 && u2 < 1);\n\n    // Select an element randomly\n    auto el = 10.iota.choice(rnd);\n    assert(0 <= el && el < 10);\n\n    // Throw a dice with custom proportions\n    // 0: 20%, 1: 10%, 2: 60%\n    auto val = rnd.dice(0.2, 0.1, 0.6);\n    assert(0 <= val && val <= 2);\n\n    auto rnd2 = MinstdRand0(42);\n\n    // Select a random subsample from a range\n    assert(10.iota.randomSample(3, rnd2).equal([7, 8, 9]));\n\n    // Cover all elements in an array in random order\n    version (X86_64) // Issue 15147\n    assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));\n\n    // Shuffle an array\n    version (X86_64) // Issue 15147\n    assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1]));\n}\n\nversion (unittest)\n{\n    static import std.meta;\n    package alias PseudoRngTypes = std.meta.AliasSeq!(MinstdRand0, MinstdRand, Mt19937, Xorshift32, Xorshift64,\n                                                      Xorshift96, Xorshift128, Xorshift160, Xorshift192);\n}\n\n// Segments of the code in this file Copyright (c) 1997 by Rick Booth\n// From \"Inner Loops\" by Rick Booth, Addison-Wesley\n\n// Work derived from:\n\n/*\n   A C-program for MT19937, with initialization improved 2002/1/26.\n   Coded by Takuji Nishimura and Makoto Matsumoto.\n\n   Before using, initialize the state by using init_genrand(seed)\n   or init_by_array(init_key, key_length).\n\n   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,\n   All rights reserved.\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n     1. Redistributions of source code must retain the above copyright\n        notice, this list of conditions and the following disclaimer.\n\n     2. Redistributions in binary form must reproduce the above copyright\n        notice, this list of conditions and the following disclaimer in the\n        documentation and/or other materials provided with the distribution.\n\n     3. The names of its contributors may not be used to endorse or promote\n        products derived from this software without specific prior written\n        permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n   Any feedback is very welcome.\n   http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html\n   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)\n*/\n\n/**\n * Test if Rng is a random-number generator. The overload\n * taking a ElementType also makes sure that the Rng generates\n * values of that type.\n *\n * A random-number generator has at least the following features:\n * $(UL\n *   $(LI it's an InputRange)\n *   $(LI it has a 'bool isUniformRandom' field readable in CTFE)\n * )\n */\ntemplate isUniformRNG(Rng, ElementType)\n{\n    enum bool isUniformRNG = isInputRange!Rng &&\n        is(typeof(Rng.front) == ElementType) &&\n        is(typeof(\n        {\n            static assert(Rng.isUniformRandom); //tag\n        }));\n}\n\n/**\n * ditto\n */\ntemplate isUniformRNG(Rng)\n{\n    enum bool isUniformRNG = isInputRange!Rng &&\n        is(typeof(\n        {\n            static assert(Rng.isUniformRandom); //tag\n        }));\n}\n\n///\n@safe unittest\n{\n    struct NoRng\n    {\n        @property uint front() {return 0;}\n        @property bool empty() {return false;}\n        void popFront() {}\n    }\n    static assert(!isUniformRNG!(NoRng));\n\n    struct validRng\n    {\n        @property uint front() {return 0;}\n        @property bool empty() {return false;}\n        void popFront() {}\n\n        enum isUniformRandom = true;\n    }\n    static assert(isUniformRNG!(validRng, uint));\n    static assert(isUniformRNG!(validRng));\n}\n\n/**\n * Test if Rng is seedable. The overload\n * taking a SeedType also makes sure that the Rng can be seeded with SeedType.\n *\n * A seedable random-number generator has the following additional features:\n * $(UL\n *   $(LI it has a 'seed(ElementType)' function)\n * )\n */\ntemplate isSeedable(Rng, SeedType)\n{\n    enum bool isSeedable = isUniformRNG!(Rng) &&\n        is(typeof(\n        {\n            Rng r = void;              // can define a Rng object\n            SeedType s = void;\n            r.seed(s); // can seed a Rng\n        }));\n}\n\n///ditto\ntemplate isSeedable(Rng)\n{\n    enum bool isSeedable = isUniformRNG!Rng &&\n        is(typeof(\n        {\n            Rng r = void;                     // can define a Rng object\n            alias SeedType = typeof(r.front);\n            SeedType s = void;\n            r.seed(s); // can seed a Rng\n        }));\n}\n\n///\n@safe unittest\n{\n    struct validRng\n    {\n        @property uint front() {return 0;}\n        @property bool empty() {return false;}\n        void popFront() {}\n\n        enum isUniformRandom = true;\n    }\n    static assert(!isSeedable!(validRng, uint));\n    static assert(!isSeedable!(validRng));\n\n    struct seedRng\n    {\n        @property uint front() {return 0;}\n        @property bool empty() {return false;}\n        void popFront() {}\n        void seed(uint val){}\n        enum isUniformRandom = true;\n    }\n    static assert(isSeedable!(seedRng, uint));\n    static assert(!isSeedable!(seedRng, ulong));\n    static assert(isSeedable!(seedRng));\n}\n\n@safe @nogc pure nothrow unittest\n{\n    struct NoRng\n    {\n        @property uint front() {return 0;}\n        @property bool empty() {return false;}\n        void popFront() {}\n    }\n    static assert(!isUniformRNG!(NoRng, uint));\n    static assert(!isUniformRNG!(NoRng));\n    static assert(!isSeedable!(NoRng, uint));\n    static assert(!isSeedable!(NoRng));\n\n    struct NoRng2\n    {\n        @property uint front() {return 0;}\n        @property bool empty() {return false;}\n        void popFront() {}\n\n        enum isUniformRandom = false;\n    }\n    static assert(!isUniformRNG!(NoRng2, uint));\n    static assert(!isUniformRNG!(NoRng2));\n    static assert(!isSeedable!(NoRng2, uint));\n    static assert(!isSeedable!(NoRng2));\n\n    struct NoRng3\n    {\n        @property bool empty() {return false;}\n        void popFront() {}\n\n        enum isUniformRandom = true;\n    }\n    static assert(!isUniformRNG!(NoRng3, uint));\n    static assert(!isUniformRNG!(NoRng3));\n    static assert(!isSeedable!(NoRng3, uint));\n    static assert(!isSeedable!(NoRng3));\n\n    struct validRng\n    {\n        @property uint front() {return 0;}\n        @property bool empty() {return false;}\n        void popFront() {}\n\n        enum isUniformRandom = true;\n    }\n    static assert(isUniformRNG!(validRng, uint));\n    static assert(isUniformRNG!(validRng));\n    static assert(!isSeedable!(validRng, uint));\n    static assert(!isSeedable!(validRng));\n\n    struct seedRng\n    {\n        @property uint front() {return 0;}\n        @property bool empty() {return false;}\n        void popFront() {}\n        void seed(uint val){}\n        enum isUniformRandom = true;\n    }\n    static assert(isUniformRNG!(seedRng, uint));\n    static assert(isUniformRNG!(seedRng));\n    static assert(isSeedable!(seedRng, uint));\n    static assert(!isSeedable!(seedRng, ulong));\n    static assert(isSeedable!(seedRng));\n}\n\n/**\nLinear Congruential generator.\n */\nstruct LinearCongruentialEngine(UIntType, UIntType a, UIntType c, UIntType m)\nif (isUnsigned!UIntType)\n{\n    ///Mark this as a Rng\n    enum bool isUniformRandom = true;\n    /// Does this generator have a fixed range? ($(D_PARAM true)).\n    enum bool hasFixedRange = true;\n    /// Lowest generated value (`1` if $(D c == 0), `0` otherwise).\n    enum UIntType min = ( c == 0 ? 1 : 0 );\n    /// Highest generated value ($(D modulus - 1)).\n    enum UIntType max = m - 1;\n/**\nThe parameters of this distribution. The random number is $(D_PARAM x\n= (x * multipler + increment) % modulus).\n */\n    enum UIntType multiplier = a;\n    ///ditto\n    enum UIntType increment = c;\n    ///ditto\n    enum UIntType modulus = m;\n\n    static assert(isIntegral!(UIntType));\n    static assert(m == 0 || a < m);\n    static assert(m == 0 || c < m);\n    static assert(m == 0 ||\n            (cast(ulong) a * (m-1) + c) % m == (c < a ? c - a + m : c - a));\n\n    // Check for maximum range\n    private static ulong gcd(ulong a, ulong b) @safe pure nothrow @nogc\n    {\n        while (b)\n        {\n            auto t = b;\n            b = a % b;\n            a = t;\n        }\n        return a;\n    }\n\n    private static ulong primeFactorsOnly(ulong n) @safe pure nothrow @nogc\n    {\n        ulong result = 1;\n        ulong iter = 2;\n        for (; n >= iter * iter; iter += 2 - (iter == 2))\n        {\n            if (n % iter) continue;\n            result *= iter;\n            do\n            {\n                n /= iter;\n            } while (n % iter == 0);\n        }\n        return result * n;\n    }\n\n    @safe pure nothrow unittest\n    {\n        static assert(primeFactorsOnly(100) == 10);\n        //writeln(primeFactorsOnly(11));\n        static assert(primeFactorsOnly(11) == 11);\n        static assert(primeFactorsOnly(7 * 7 * 7 * 11 * 15 * 11) == 7 * 11 * 15);\n        static assert(primeFactorsOnly(129 * 2) == 129 * 2);\n        // enum x = primeFactorsOnly(7 * 7 * 7 * 11 * 15);\n        // static assert(x == 7 * 11 * 15);\n    }\n\n    private static bool properLinearCongruentialParameters(ulong m,\n            ulong a, ulong c) @safe pure nothrow @nogc\n    {\n        if (m == 0)\n        {\n            static if (is(UIntType == uint))\n            {\n                // Assume m is uint.max + 1\n                m = (1uL << 32);\n            }\n            else\n            {\n                return false;\n            }\n        }\n        // Bounds checking\n        if (a == 0 || a >= m || c >= m) return false;\n        // c and m are relatively prime\n        if (c > 0 && gcd(c, m) != 1) return false;\n        // a - 1 is divisible by all prime factors of m\n        if ((a - 1) % primeFactorsOnly(m)) return false;\n        // if a - 1 is multiple of 4, then m is a  multiple of 4 too.\n        if ((a - 1) % 4 == 0 && m % 4) return false;\n        // Passed all tests\n        return true;\n    }\n\n    // check here\n    static assert(c == 0 || properLinearCongruentialParameters(m, a, c),\n            \"Incorrect instantiation of LinearCongruentialEngine\");\n\n/**\nConstructs a $(D_PARAM LinearCongruentialEngine) generator seeded with\n`x0`.\n */\n    this(UIntType x0) @safe pure nothrow @nogc\n    {\n        seed(x0);\n    }\n\n/**\n   (Re)seeds the generator.\n*/\n    void seed(UIntType x0 = 1) @safe pure nothrow @nogc\n    {\n        _x = modulus ? (x0 % modulus) : x0;\n        static if (c == 0)\n        {\n            //Necessary to prevent generator from outputting an endless series of zeroes.\n            if (_x == 0)\n                _x = max;\n        }\n        popFront();\n    }\n\n/**\n   Advances the random sequence.\n*/\n    void popFront() @safe pure nothrow @nogc\n    {\n        static if (m)\n        {\n            static if (is(UIntType == uint) && m == uint.max)\n            {\n                immutable ulong\n                    x = (cast(ulong) a * _x + c),\n                    v = x >> 32,\n                    w = x & uint.max;\n                immutable y = cast(uint)(v + w);\n                _x = (y < v || y == uint.max) ? (y + 1) : y;\n            }\n            else static if (is(UIntType == uint) && m == int.max)\n            {\n                immutable ulong\n                    x = (cast(ulong) a * _x + c),\n                    v = x >> 31,\n                    w = x & int.max;\n                immutable uint y = cast(uint)(v + w);\n                _x = (y >= int.max) ? (y - int.max) : y;\n            }\n            else\n            {\n                _x = cast(UIntType) ((cast(ulong) a * _x + c) % m);\n            }\n        }\n        else\n        {\n            _x = a * _x + c;\n        }\n    }\n\n/**\n   Returns the current number in the random sequence.\n*/\n    @property UIntType front() const @safe pure nothrow @nogc\n    {\n        return _x;\n    }\n\n///\n    @property typeof(this) save() @safe pure nothrow @nogc\n    {\n        return this;\n    }\n\n/**\nAlways `false` (random generators are infinite ranges).\n */\n    enum bool empty = false;\n\n/**\n   Compares against $(D_PARAM rhs) for equality.\n */\n    bool opEquals(ref const LinearCongruentialEngine rhs) const @safe pure nothrow @nogc\n    {\n        return _x == rhs._x;\n    }\n\n    private UIntType _x = m ? (a + c) % m : (a + c);\n}\n\n/// Declare your own linear congruential engine\n@safe unittest\n{\n    alias CPP11LCG = LinearCongruentialEngine!(uint, 48271, 0, 2_147_483_647);\n\n    // seed with a constant\n    auto rnd = CPP11LCG(42);\n    auto n = rnd.front; // same for each run\n    assert(n == 2027382);\n}\n\n/// Declare your own linear congruential engine\n@safe unittest\n{\n    // glibc's LCG\n    alias GLibcLCG = LinearCongruentialEngine!(uint, 1103515245, 12345, 2_147_483_648);\n\n    // Seed with an unpredictable value\n    auto rnd = GLibcLCG(unpredictableSeed);\n    auto n = rnd.front; // different across runs\n}\n\n/**\nDefine $(D_PARAM LinearCongruentialEngine) generators with well-chosen\nparameters. `MinstdRand0` implements Park and Miller's \"minimal\nstandard\" $(HTTP\nwikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator,\ngenerator) that uses 16807 for the multiplier. `MinstdRand`\nimplements a variant that has slightly better spectral behavior by\nusing the multiplier 48271. Both generators are rather simplistic.\n */\nalias MinstdRand0 = LinearCongruentialEngine!(uint, 16_807, 0, 2_147_483_647);\n/// ditto\nalias MinstdRand = LinearCongruentialEngine!(uint, 48_271, 0, 2_147_483_647);\n\n///\n@safe @nogc unittest\n{\n    // seed with a constant\n    auto rnd0 = MinstdRand0(1);\n    auto n = rnd0.front;\n     // same for each run\n    assert(n == 16807);\n\n    // Seed with an unpredictable value\n    rnd0.seed(unpredictableSeed);\n    n = rnd0.front; // different across runs\n}\n\n@safe @nogc unittest\n{\n    import std.range;\n    static assert(isForwardRange!MinstdRand);\n    static assert(isUniformRNG!MinstdRand);\n    static assert(isUniformRNG!MinstdRand0);\n    static assert(isUniformRNG!(MinstdRand, uint));\n    static assert(isUniformRNG!(MinstdRand0, uint));\n    static assert(isSeedable!MinstdRand);\n    static assert(isSeedable!MinstdRand0);\n    static assert(isSeedable!(MinstdRand, uint));\n    static assert(isSeedable!(MinstdRand0, uint));\n\n    // The correct numbers are taken from The Database of Integer Sequences\n    // http://www.research.att.com/~njas/sequences/eisBTfry00128.txt\n    enum ulong[20] checking0 = [\n        16807UL,282475249,1622650073,984943658,1144108930,470211272,\n        101027544,1457850878,1458777923,2007237709,823564440,1115438165,\n        1784484492,74243042,114807987,1137522503,1441282327,16531729,\n        823378840,143542612 ];\n    //auto rnd0 = MinstdRand0(1);\n    MinstdRand0 rnd0;\n\n    foreach (e; checking0)\n    {\n        assert(rnd0.front == e);\n        rnd0.popFront();\n    }\n    // Test the 10000th invocation\n    // Correct value taken from:\n    // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf\n    rnd0.seed();\n    popFrontN(rnd0, 9999);\n    assert(rnd0.front == 1043618065);\n\n    // Test MinstdRand\n    enum ulong[6] checking = [48271UL,182605794,1291394886,1914720637,2078669041,\n                     407355683];\n    //auto rnd = MinstdRand(1);\n    MinstdRand rnd;\n    foreach (e; checking)\n    {\n        assert(rnd.front == e);\n        rnd.popFront();\n    }\n\n    // Test the 10000th invocation\n    // Correct value taken from:\n    // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf\n    rnd.seed();\n    popFrontN(rnd, 9999);\n    assert(rnd.front == 399268537);\n\n    // Check .save works\n    static foreach (Type; std.meta.AliasSeq!(MinstdRand0, MinstdRand))\n    {{\n        auto rnd1 = Type(123_456_789);\n        rnd1.popFront();\n        auto rnd2 = rnd1.save;\n        assert(rnd1 == rnd2);\n        // Enable next test when RNGs are reference types\n        version (none) { assert(rnd1 !is rnd2); }\n        for (auto i = 0; i < 100; i++, rnd1.popFront, rnd2.popFront)\n            assert(rnd1.front() == rnd2.front());\n    }}\n}\n\n@safe @nogc unittest\n{\n    auto rnd0 = MinstdRand0(MinstdRand0.modulus);\n    auto n = rnd0.front;\n    rnd0.popFront();\n    assert(n != rnd0.front);\n}\n\n/**\nThe $(LINK2 https://en.wikipedia.org/wiki/Mersenne_Twister, Mersenne Twister) generator.\n */\nstruct MersenneTwisterEngine(UIntType, size_t w, size_t n, size_t m, size_t r,\n                             UIntType a, size_t u, UIntType d, size_t s,\n                             UIntType b, size_t t,\n                             UIntType c, size_t l, UIntType f)\nif (isUnsigned!UIntType)\n{\n    static assert(0 < w && w <= UIntType.sizeof * 8);\n    static assert(1 <= m && m <= n);\n    static assert(0 <= r && 0 <= u && 0 <= s && 0 <= t && 0 <= l);\n    static assert(r <= w && u <= w && s <= w && t <= w && l <= w);\n    static assert(0 <= a && 0 <= b && 0 <= c);\n    static assert(n <= sizediff_t.max);\n\n    ///Mark this as a Rng\n    enum bool isUniformRandom = true;\n\n/**\nParameters for the generator.\n*/\n    enum size_t   wordSize   = w;\n    enum size_t   stateSize  = n; /// ditto\n    enum size_t   shiftSize  = m; /// ditto\n    enum size_t   maskBits   = r; /// ditto\n    enum UIntType xorMask    = a; /// ditto\n    enum size_t   temperingU = u; /// ditto\n    enum UIntType temperingD = d; /// ditto\n    enum size_t   temperingS = s; /// ditto\n    enum UIntType temperingB = b; /// ditto\n    enum size_t   temperingT = t; /// ditto\n    enum UIntType temperingC = c; /// ditto\n    enum size_t   temperingL = l; /// ditto\n    enum UIntType initializationMultiplier = f; /// ditto\n\n    /// Smallest generated value (0).\n    enum UIntType min = 0;\n    /// Largest generated value.\n    enum UIntType max = UIntType.max >> (UIntType.sizeof * 8u - w);\n    // note, `max` also serves as a bitmask for the lowest `w` bits\n    static assert(a <= max && b <= max && c <= max && f <= max);\n\n    /// The default seed value.\n    enum UIntType defaultSeed = 5489u;\n\n    // Bitmasks used in the 'twist' part of the algorithm\n    private enum UIntType lowerMask = (cast(UIntType) 1u << r) - 1,\n                          upperMask = (~lowerMask) & this.max;\n\n    /*\n       Collection of all state variables\n       used by the generator\n    */\n    private struct State\n    {\n        /*\n           State array of the generator.  This\n           is iterated through backwards (from\n           last element to first), providing a\n           few extra compiler optimizations by\n           comparison to the forward iteration\n           used in most implementations.\n        */\n        UIntType[n] data;\n\n        /*\n           Cached copy of most recently updated\n           element of `data` state array, ready\n           to be tempered to generate next\n           `front` value\n        */\n        UIntType z;\n\n        /*\n           Most recently generated random variate\n        */\n        UIntType front;\n\n        /*\n           Index of the entry in the `data`\n           state array that will be twisted\n           in the next `popFront()` call\n        */\n        size_t index;\n    }\n\n    /*\n       State variables used by the generator;\n       initialized to values equivalent to\n       explicitly seeding the generator with\n       `defaultSeed`\n    */\n    private State state = defaultState();\n    /* NOTE: the above is a workaround to ensure\n       backwards compatibility with the original\n       implementation, which permitted implicit\n       construction.  With `@disable this();`\n       it would not be necessary. */\n\n/**\n   Constructs a MersenneTwisterEngine object.\n*/\n    this(UIntType value) @safe pure nothrow @nogc\n    {\n        seed(value);\n    }\n\n    /**\n       Generates the default initial state for a Mersenne\n       Twister; equivalent to the internal state obtained\n       by calling `seed(defaultSeed)`\n    */\n    private static State defaultState() @safe pure nothrow @nogc\n    {\n        if (!__ctfe) assert(false);\n        State mtState;\n        seedImpl(defaultSeed, mtState);\n        return mtState;\n    }\n\n/**\n   Seeds a MersenneTwisterEngine object.\n   Note:\n   This seed function gives 2^w starting points (the lowest w bits of\n   the value provided will be used). To allow the RNG to be started\n   in any one of its internal states use the seed overload taking an\n   InputRange.\n*/\n    void seed()(UIntType value = defaultSeed) @safe pure nothrow @nogc\n    {\n        this.seedImpl(value, this.state);\n    }\n\n    /**\n       Implementation of the seeding mechanism, which\n       can be used with an arbitrary `State` instance\n    */\n    private static void seedImpl(UIntType value, ref State mtState) @nogc\n    {\n        mtState.data[$ - 1] = value;\n        static if (this.max != UIntType.max)\n        {\n            mtState.data[$ - 1] &= this.max;\n        }\n\n        foreach_reverse (size_t i, ref e; mtState.data[0 .. $ - 1])\n        {\n            e = f * (mtState.data[i + 1] ^ (mtState.data[i + 1] >> (w - 2))) + cast(UIntType)(n - (i + 1));\n            static if (this.max != UIntType.max)\n            {\n                e &= this.max;\n            }\n        }\n\n        mtState.index = n - 1;\n\n        /* double popFront() to guarantee both `mtState.z`\n           and `mtState.front` are derived from the newly\n           set values in `mtState.data` */\n        MersenneTwisterEngine.popFrontImpl(mtState);\n        MersenneTwisterEngine.popFrontImpl(mtState);\n    }\n\n/**\n   Seeds a MersenneTwisterEngine object using an InputRange.\n\n   Throws:\n   `Exception` if the InputRange didn't provide enough elements to seed the generator.\n   The number of elements required is the 'n' template parameter of the MersenneTwisterEngine struct.\n */\n    void seed(T)(T range) if (isInputRange!T && is(Unqual!(ElementType!T) == UIntType))\n    {\n        this.seedImpl(range, this.state);\n    }\n\n    /**\n       Implementation of the range-based seeding mechanism,\n       which can be used with an arbitrary `State` instance\n    */\n    private static void seedImpl(T)(T range, ref State mtState)\n        if (isInputRange!T && is(Unqual!(ElementType!T) == UIntType))\n    {\n        size_t j;\n        for (j = 0; j < n && !range.empty; ++j, range.popFront())\n        {\n            sizediff_t idx = n - j - 1;\n            mtState.data[idx] = range.front;\n        }\n\n        mtState.index = n - 1;\n\n        if (range.empty && j < n)\n        {\n            import core.internal.string : UnsignedStringBuf, unsignedToTempString;\n\n            UnsignedStringBuf buf = void;\n            string s = \"MersenneTwisterEngine.seed: Input range didn't provide enough elements: Need \";\n            s ~= unsignedToTempString(n, buf, 10) ~ \" elements.\";\n            throw new Exception(s);\n        }\n\n        /* double popFront() to guarantee both `mtState.z`\n           and `mtState.front` are derived from the newly\n           set values in `mtState.data` */\n        MersenneTwisterEngine.popFrontImpl(mtState);\n        MersenneTwisterEngine.popFrontImpl(mtState);\n    }\n\n/**\n   Advances the generator.\n*/\n    void popFront() @safe pure nothrow @nogc\n    {\n        this.popFrontImpl(this.state);\n    }\n\n    /*\n       Internal implementation of `popFront()`, which\n       can be used with an arbitrary `State` instance\n    */\n    private static void popFrontImpl(ref State mtState) @nogc\n    {\n        /* This function blends two nominally independent\n           processes: (i) calculation of the next random\n           variate `mtState.front` from the cached previous\n           `data` entry `z`, and (ii) updating the value\n           of `data[index]` and `mtState.z` and advancing\n           the `index` value to the next in sequence.\n\n           By interweaving the steps involved in these\n           procedures, rather than performing each of\n           them separately in sequence, the variables\n           are kept 'hot' in CPU registers, allowing\n           for significantly faster performance. */\n        sizediff_t index = mtState.index;\n        sizediff_t next = index - 1;\n        if (next < 0)\n            next = n - 1;\n        auto z = mtState.z;\n        sizediff_t conj = index - m;\n        if (conj < 0)\n            conj = index - m + n;\n\n        static if (d == UIntType.max)\n        {\n            z ^= (z >> u);\n        }\n        else\n        {\n            z ^= (z >> u) & d;\n        }\n\n        auto q = mtState.data[index] & upperMask;\n        auto p = mtState.data[next] & lowerMask;\n        z ^= (z << s) & b;\n        auto y = q | p;\n        auto x = y >> 1;\n        z ^= (z << t) & c;\n        if (y & 1)\n            x ^= a;\n        auto e = mtState.data[conj] ^ x;\n        z ^= (z >> l);\n        mtState.z = mtState.data[index] = e;\n        mtState.index = next;\n\n        /* technically we should take the lowest `w`\n           bits here, but if the tempering bitmasks\n           `b` and `c` are set correctly, this should\n           be unnecessary */\n        mtState.front = z;\n    }\n\n/**\n   Returns the current random value.\n */\n    @property UIntType front() @safe const pure nothrow @nogc\n    {\n        return this.state.front;\n    }\n\n///\n    @property typeof(this) save() @safe pure nothrow @nogc\n    {\n        return this;\n    }\n\n/**\nAlways `false`.\n */\n    enum bool empty = false;\n}\n\n///\n@safe unittest\n{\n    // seed with a constant\n    Mt19937 gen;\n    auto n = gen.front; // same for each run\n    assert(n == 3499211612);\n\n    // Seed with an unpredictable value\n    gen.seed(unpredictableSeed);\n    n = gen.front; // different across runs\n}\n\n/**\nA `MersenneTwisterEngine` instantiated with the parameters of the\noriginal engine $(HTTP math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html,\nMT19937), generating uniformly-distributed 32-bit numbers with a\nperiod of 2 to the power of 19937. Recommended for random number\ngeneration unless memory is severely restricted, in which case a $(LREF\nLinearCongruentialEngine) would be the generator of choice.\n */\nalias Mt19937 = MersenneTwisterEngine!(uint, 32, 624, 397, 31,\n                                       0x9908b0df, 11, 0xffffffff, 7,\n                                       0x9d2c5680, 15,\n                                       0xefc60000, 18, 1_812_433_253);\n\n///\n@safe @nogc unittest\n{\n    // seed with a constant\n    Mt19937 gen;\n    auto n = gen.front; // same for each run\n    assert(n == 3499211612);\n\n    // Seed with an unpredictable value\n    gen.seed(unpredictableSeed);\n    n = gen.front; // different across runs\n}\n\n@safe nothrow unittest\n{\n    import std.algorithm;\n    import std.range;\n    static assert(isUniformRNG!Mt19937);\n    static assert(isUniformRNG!(Mt19937, uint));\n    static assert(isSeedable!Mt19937);\n    static assert(isSeedable!(Mt19937, uint));\n    static assert(isSeedable!(Mt19937, typeof(map!((a) => unpredictableSeed)(repeat(0)))));\n    Mt19937 gen;\n    assert(gen.front == 3499211612);\n    popFrontN(gen, 9999);\n    assert(gen.front == 4123659995);\n    try { gen.seed(iota(624u)); } catch (Exception) { assert(false); }\n    assert(gen.front == 3708921088u);\n    popFrontN(gen, 9999);\n    assert(gen.front == 165737292u);\n}\n\n/**\nA `MersenneTwisterEngine` instantiated with the parameters of the\noriginal engine $(HTTP en.wikipedia.org/wiki/Mersenne_Twister,\nMT19937-64), generating uniformly-distributed 64-bit numbers with a\nperiod of 2 to the power of 19937.\n*/\nalias Mt19937_64 = MersenneTwisterEngine!(ulong, 64, 312, 156, 31,\n                                          0xb5026f5aa96619e9, 29, 0x5555555555555555, 17,\n                                          0x71d67fffeda60000, 37,\n                                          0xfff7eee000000000, 43, 6_364_136_223_846_793_005);\n\n///\n@safe @nogc unittest\n{\n    // Seed with a constant\n    auto gen = Mt19937_64(12345);\n    auto n = gen.front; // same for each run\n    assert(n == 6597103971274460346);\n\n    // Seed with an unpredictable value\n    gen.seed(unpredictableSeed);\n    n = gen.front; // different across runs\n}\n\n@safe nothrow unittest\n{\n    import std.algorithm;\n    import std.range;\n    static assert(isUniformRNG!Mt19937_64);\n    static assert(isUniformRNG!(Mt19937_64, ulong));\n    static assert(isSeedable!Mt19937_64);\n    static assert(isSeedable!(Mt19937_64, ulong));\n    // Issue 15147: this test demonstrates viably that Mt19937_64\n    // is seedable with an infinite range of `ulong` values\n    // but it's a poor example of how to actually seed the\n    // generator, since it can't cover the full range of\n    // possible seed values.  Ideally we need a 64-bit\n    // unpredictable seed to complement the 32-bit one!\n    static assert(isSeedable!(Mt19937_64, typeof(map!((a) => (cast(ulong) unpredictableSeed))(repeat(0)))));\n    Mt19937_64 gen;\n    assert(gen.front == 14514284786278117030uL);\n    popFrontN(gen, 9999);\n    assert(gen.front == 9981545732273789042uL);\n    try { gen.seed(iota(312uL)); } catch (Exception) { assert(false); }\n    assert(gen.front == 14660652410669508483uL);\n    popFrontN(gen, 9999);\n    assert(gen.front == 15956361063660440239uL);\n}\n\n@safe unittest\n{\n    import std.algorithm;\n    import std.exception;\n    import std.range;\n\n    Mt19937 gen;\n\n    assertThrown(gen.seed(map!((a) => 123_456_789U)(repeat(0, 623))));\n\n    gen.seed(123_456_789U.repeat(624));\n    //infinite Range\n    gen.seed(123_456_789U.repeat);\n}\n\n@safe @nogc pure nothrow unittest\n{\n    uint a, b;\n    {\n        Mt19937 gen;\n        a = gen.front;\n    }\n    {\n        Mt19937 gen;\n        gen.popFront();\n        //popFrontN(gen, 1);  // skip 1 element\n        b = gen.front;\n    }\n    assert(a != b);\n}\n\n@safe @nogc unittest\n{\n    // Check .save works\n    static foreach (Type; std.meta.AliasSeq!(Mt19937, Mt19937_64))\n    {{\n        auto gen1 = Type(123_456_789);\n        gen1.popFront();\n        auto gen2 = gen1.save;\n        assert(gen1 == gen2);  // Danger, Will Robinson -- no opEquals for MT\n        // Enable next test when RNGs are reference types\n        version (none) { assert(gen1 !is gen2); }\n        for (auto i = 0; i < 100; i++, gen1.popFront, gen2.popFront)\n            assert(gen1.front() == gen2.front());\n    }}\n}\n\n@safe @nogc pure nothrow unittest //11690\n{\n    alias MT(UIntType, uint w) = MersenneTwisterEngine!(UIntType, w, 624, 397, 31,\n                                                        0x9908b0df, 11, 0xffffffff, 7,\n                                                        0x9d2c5680, 15,\n                                                        0xefc60000, 18, 1812433253);\n\n    static immutable ulong[] expectedFirstValue = [3499211612uL, 3499211612uL,\n                                  171143175841277uL, 1145028863177033374uL];\n\n    static immutable ulong[] expected10kValue = [4123659995uL, 4123659995uL,\n                                51991688252792uL, 3031481165133029945uL];\n\n    static foreach (i, R; std.meta.AliasSeq!(MT!(uint, 32), MT!(ulong, 32), MT!(ulong, 48), MT!(ulong, 64)))\n    {{\n        auto a = R();\n        a.seed(a.defaultSeed); // checks that some alternative paths in `seed` are utilized\n        assert(a.front == expectedFirstValue[i]);\n        a.popFrontN(9999);\n        assert(a.front == expected10kValue[i]);\n    }}\n}\n\n\n/**\n * Xorshift generator using 32bit algorithm.\n *\n * Implemented according to $(HTTP www.jstatsoft.org/v08/i14/paper, Xorshift RNGs).\n * Supporting bits are below, `bits` means second parameter of XorshiftEngine.\n *\n * $(BOOKTABLE ,\n *  $(TR $(TH bits) $(TH period))\n *  $(TR $(TD 32)   $(TD 2^32 - 1))\n *  $(TR $(TD 64)   $(TD 2^64 - 1))\n *  $(TR $(TD 96)   $(TD 2^96 - 1))\n *  $(TR $(TD 128)  $(TD 2^128 - 1))\n *  $(TR $(TD 160)  $(TD 2^160 - 1))\n *  $(TR $(TD 192)  $(TD 2^192 - 2^32))\n * )\n */\nstruct XorshiftEngine(UIntType, UIntType bits, UIntType a, UIntType b, UIntType c)\nif (isUnsigned!UIntType)\n{\n    static assert(bits == 32 || bits == 64 || bits == 96 || bits == 128 || bits == 160 || bits == 192,\n                  \"Xorshift supports only 32, 64, 96, 128, 160 and 192 bit versions. \"\n                  ~ to!string(bits) ~ \" is not supported.\");\n\n  public:\n    ///Mark this as a Rng\n    enum bool isUniformRandom = true;\n    /// Always `false` (random generators are infinite ranges).\n    enum empty = false;\n    /// Smallest generated value.\n    enum UIntType min = seeds_.length == 1 ? 1 : 0;\n    /// Largest generated value.\n    enum UIntType max = UIntType.max;\n\n\n  private:\n    enum size = bits / 32;\n\n    static if (bits == 32)\n        UIntType[size] seeds_ = [2_463_534_242];\n    else static if (bits == 64)\n        UIntType[size] seeds_ = [123_456_789, 362_436_069];\n    else static if (bits == 96)\n        UIntType[size] seeds_ = [123_456_789, 362_436_069, 521_288_629];\n    else static if (bits == 128)\n        UIntType[size] seeds_ = [123_456_789, 362_436_069, 521_288_629, 88_675_123];\n    else static if (bits == 160)\n        UIntType[size] seeds_ = [123_456_789, 362_436_069, 521_288_629, 88_675_123, 5_783_321];\n    else static if (bits == 192)\n    {\n        UIntType[size] seeds_ = [123_456_789, 362_436_069, 521_288_629, 88_675_123, 5_783_321, 6_615_241];\n        UIntType       value_;\n    }\n    else\n    {\n        static assert(false, \"Phobos Error: Xorshift has no instantiation rule for \"\n                             ~ to!string(bits) ~ \" bits.\");\n    }\n\n\n  public:\n    /**\n     * Constructs a `XorshiftEngine` generator seeded with $(D_PARAM x0).\n     */\n    this(UIntType x0) @safe pure nothrow @nogc\n    {\n        seed(x0);\n    }\n\n\n    /**\n     * (Re)seeds the generator.\n     */\n    void seed(UIntType x0) @safe pure nothrow @nogc\n    {\n        // Initialization routine from MersenneTwisterEngine.\n        foreach (i, e; seeds_)\n            seeds_[i] = x0 = cast(UIntType)(1_812_433_253U * (x0 ^ (x0 >> 30)) + i + 1);\n\n        // All seeds must not be 0.\n        sanitizeSeeds(seeds_);\n\n        popFront();\n    }\n\n\n    /**\n     * Returns the current number in the random sequence.\n     */\n    @property\n    UIntType front() const @safe pure nothrow @nogc\n    {\n        static if (bits == 192)\n            return value_;\n        else\n            return seeds_[size - 1];\n    }\n\n\n    /**\n     * Advances the random sequence.\n     */\n    void popFront() @safe pure nothrow @nogc\n    {\n        UIntType temp;\n\n        static if (bits == 32)\n        {\n            temp      = seeds_[0] ^ (seeds_[0] << a);\n            temp      = temp ^ (temp >> b);\n            seeds_[0] = temp ^ (temp << c);\n        }\n        else static if (bits == 64)\n        {\n            temp      = seeds_[0] ^ (seeds_[0] << a);\n            seeds_[0] = seeds_[1];\n            seeds_[1] = seeds_[1] ^ (seeds_[1] >> c) ^ temp ^ (temp >> b);\n        }\n        else static if (bits == 96)\n        {\n            temp      = seeds_[0] ^ (seeds_[0] << a);\n            seeds_[0] = seeds_[1];\n            seeds_[1] = seeds_[2];\n            seeds_[2] = seeds_[2] ^ (seeds_[2] >> c) ^ temp ^ (temp >> b);\n        }\n        else static if (bits == 128)\n        {\n            temp      = seeds_[0] ^ (seeds_[0] << a);\n            seeds_[0] = seeds_[1];\n            seeds_[1] = seeds_[2];\n            seeds_[2] = seeds_[3];\n            seeds_[3] = seeds_[3] ^ (seeds_[3] >> c) ^ temp ^ (temp >> b);\n        }\n        else static if (bits == 160)\n        {\n            temp      = seeds_[0] ^ (seeds_[0] << a);\n            seeds_[0] = seeds_[1];\n            seeds_[1] = seeds_[2];\n            seeds_[2] = seeds_[3];\n            seeds_[3] = seeds_[4];\n            seeds_[4] = seeds_[4] ^ (seeds_[4] >> c) ^ temp ^ (temp >> b);\n        }\n        else static if (bits == 192)\n        {\n            temp      = seeds_[0] ^ (seeds_[0] >> a);\n            seeds_[0] = seeds_[1];\n            seeds_[1] = seeds_[2];\n            seeds_[2] = seeds_[3];\n            seeds_[3] = seeds_[4];\n            seeds_[4] = seeds_[4] ^ (seeds_[4] << c) ^ temp ^ (temp << b);\n            value_    = seeds_[4] + (seeds_[5] += 362_437);\n        }\n        else\n        {\n            static assert(false, \"Phobos Error: Xorshift has no popFront() update for \"\n                                 ~ to!string(bits) ~ \" bits.\");\n        }\n    }\n\n\n    /**\n     * Captures a range state.\n     */\n    @property\n    typeof(this) save() @safe pure nothrow @nogc\n    {\n        return this;\n    }\n\n\n    /**\n     * Compares against $(D_PARAM rhs) for equality.\n     */\n    bool opEquals(ref const XorshiftEngine rhs) const @safe pure nothrow @nogc\n    {\n        return seeds_ == rhs.seeds_;\n    }\n\n\n  private:\n    static void sanitizeSeeds(ref UIntType[size] seeds) @safe pure nothrow @nogc\n    {\n        for (uint i; i < seeds.length; i++)\n        {\n            if (seeds[i] == 0)\n                seeds[i] = i + 1;\n        }\n    }\n\n\n    @safe pure nothrow unittest\n    {\n        static if (size  ==  4)  // Other bits too\n        {\n            UIntType[size] seeds = [1, 0, 0, 4];\n\n            sanitizeSeeds(seeds);\n\n            assert(seeds == [1, 2, 3, 4]);\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    alias Xorshift96  = XorshiftEngine!(uint, 96,  10, 5,  26);\n    auto rnd = Xorshift96(42);\n    auto num = rnd.front;  // same for each run\n    assert(num == 2704588748);\n}\n\n\n/**\n * Define `XorshiftEngine` generators with well-chosen parameters. See each bits examples of \"Xorshift RNGs\".\n * `Xorshift` is a Xorshift128's alias because 128bits implementation is mostly used.\n */\nalias Xorshift32  = XorshiftEngine!(uint, 32,  13, 17, 15) ;\nalias Xorshift64  = XorshiftEngine!(uint, 64,  10, 13, 10); /// ditto\nalias Xorshift96  = XorshiftEngine!(uint, 96,  10, 5,  26); /// ditto\nalias Xorshift128 = XorshiftEngine!(uint, 128, 11, 8,  19); /// ditto\nalias Xorshift160 = XorshiftEngine!(uint, 160, 2,  1,  4);  /// ditto\nalias Xorshift192 = XorshiftEngine!(uint, 192, 2,  1,  4);  /// ditto\nalias Xorshift    = Xorshift128;                            /// ditto\n\n///\n@safe @nogc unittest\n{\n    // Seed with a constant\n    auto rnd = Xorshift(1);\n    auto num = rnd.front;  // same for each run\n    assert(num == 1405313047);\n\n    // Seed with an unpredictable value\n    rnd.seed(unpredictableSeed);\n    num = rnd.front; // different across rnd\n}\n\n@safe @nogc unittest\n{\n    import std.range;\n    static assert(isForwardRange!Xorshift);\n    static assert(isUniformRNG!Xorshift);\n    static assert(isUniformRNG!(Xorshift, uint));\n    static assert(isSeedable!Xorshift);\n    static assert(isSeedable!(Xorshift, uint));\n\n    static assert(Xorshift32.min == 1);\n\n    // Result from reference implementation.\n    static ulong[][] checking = [\n        [2463534242UL, 901999875, 3371835698, 2675058524, 1053936272, 3811264849,\n        472493137, 3856898176, 2131710969, 2312157505],\n        [362436069UL, 2113136921, 19051112, 3010520417, 951284840, 1213972223,\n        3173832558, 2611145638, 2515869689, 2245824891],\n        [521288629UL, 1950277231, 185954712, 1582725458, 3580567609, 2303633688,\n        2394948066, 4108622809, 1116800180, 3357585673],\n        [88675123UL, 3701687786, 458299110, 2500872618, 3633119408, 516391518,\n        2377269574, 2599949379, 717229868, 137866584],\n        [5783321UL, 393427209, 1947109840, 565829276, 1006220149, 971147905,\n        1436324242, 2800460115, 1484058076, 3823330032],\n        [0UL, 246875399, 3690007200, 1264581005, 3906711041, 1866187943, 2481925219,\n        2464530826, 1604040631, 3653403911]\n    ];\n\n    alias XorshiftTypes = std.meta.AliasSeq!(Xorshift32, Xorshift64, Xorshift96, Xorshift128, Xorshift160, Xorshift192);\n\n    foreach (I, Type; XorshiftTypes)\n    {\n        Type rnd;\n\n        foreach (e; checking[I])\n        {\n            assert(rnd.front == e);\n            rnd.popFront();\n        }\n    }\n\n    // Check .save works\n    foreach (Type; XorshiftTypes)\n    {\n        auto rnd1 = Type(123_456_789);\n        rnd1.popFront();\n        auto rnd2 = rnd1.save;\n        assert(rnd1 == rnd2);\n        // Enable next test when RNGs are reference types\n        version (none) { assert(rnd1 !is rnd2); }\n        for (auto i = 0; i < 100; i++, rnd1.popFront, rnd2.popFront)\n            assert(rnd1.front() == rnd2.front());\n    }\n}\n\n\n/* A complete list of all pseudo-random number generators implemented in\n * std.random.  This can be used to confirm that a given function or\n * object is compatible with all the pseudo-random number generators\n * available.  It is enabled only in unittest mode.\n */\n@safe @nogc unittest\n{\n    foreach (Rng; PseudoRngTypes)\n    {\n        static assert(isUniformRNG!Rng);\n        auto rng = Rng(123_456_789);\n    }\n}\n\nversion (CRuntime_Bionic)\n    version = SecureARC4Random; // ChaCha20\nversion (OSX)\n    version = SecureARC4Random; // AES\nversion (OpenBSD)\n    version = SecureARC4Random; // ChaCha20\nversion (NetBSD)\n    version = SecureARC4Random; // ChaCha20\n\nversion (CRuntime_UClibc)\n    version = LegacyARC4Random; // ARC4\nversion (FreeBSD)\n    version = LegacyARC4Random; // ARC4\nversion (DragonFlyBSD)\n    version = LegacyARC4Random; // ARC4\nversion (BSD)\n    version = LegacyARC4Random; // Unknown implementation\n\n// For the current purpose of unpredictableSeed the difference between\n// a secure arc4random implementation and a legacy implementation is\n// unimportant. The source code documents this distinction in case in the\n// future Phobos is altered to require cryptographically secure sources\n// of randomness, and also so other people reading this source code (as\n// Phobos is often looked to as an example of good D programming practices)\n// do not mistakenly use insecure versions of arc4random in contexts where\n// cryptographically secure sources of randomness are needed.\n\n// Performance note: ChaCha20 is about 70% faster than ARC4, contrary to\n// what one might assume from it being more secure.\n\nversion (SecureARC4Random)\n    version = AnyARC4Random;\nversion (LegacyARC4Random)\n    version = AnyARC4Random;\n\nversion (AnyARC4Random)\n{\n    extern(C) private @nogc nothrow\n    {\n        uint arc4random() @safe;\n    }\n}\n\n/**\nA \"good\" seed for initializing random number engines. Initializing\nwith $(D_PARAM unpredictableSeed) makes engines generate different\nrandom number sequences every run.\n\nReturns:\nA single unsigned integer seed value, different on each successive call\nNote:\nIn general periodically 'reseeding' a PRNG does not improve its quality\nand in some cases may harm it. For an extreme example the Mersenne\nTwister has `2 ^^ 19937 - 1` distinct states but after `seed(uint)` is\ncalled it can only be in one of `2 ^^ 32` distinct states regardless of\nhow excellent the source of entropy is.\n*/\n@property uint unpredictableSeed() @trusted nothrow @nogc\n{\n    version (AnyARC4Random)\n    {\n        return arc4random();\n    }\n    else\n    {\n        import core.thread : Thread, getpid, MonoTime;\n        static bool seeded;\n        static MinstdRand0 rand;\n        if (!seeded)\n        {\n            uint threadID = cast(uint) cast(void*) Thread.getThis();\n            rand.seed((getpid() + threadID) ^ cast(uint) MonoTime.currTime.ticks);\n            seeded = true;\n        }\n        rand.popFront();\n        return cast(uint) (MonoTime.currTime.ticks ^ rand.front);\n    }\n}\n\n///\n@safe @nogc unittest\n{\n    auto rnd = Random(unpredictableSeed);\n    auto n = rnd.front;\n    static assert(is(typeof(n) == uint));\n}\n\n/**\nThe \"default\", \"favorite\", \"suggested\" random number generator type on\nthe current platform. It is an alias for one of the previously-defined\ngenerators. You may want to use it if (1) you need to generate some\nnice random numbers, and (2) you don't care for the minutiae of the\nmethod being used.\n */\n\nalias Random = Mt19937;\n\n@safe @nogc unittest\n{\n    static assert(isUniformRNG!Random);\n    static assert(isUniformRNG!(Random, uint));\n    static assert(isSeedable!Random);\n    static assert(isSeedable!(Random, uint));\n}\n\n/**\nGlobal random number generator used by various functions in this\nmodule whenever no generator is specified. It is allocated per-thread\nand initialized to an unpredictable value for each thread.\n\nReturns:\nA singleton instance of the default random number generator\n */\n@property ref Random rndGen() @safe @nogc\n{\n    import std.algorithm.iteration : map;\n    import std.range : repeat;\n\n    static Random result;\n    static bool initialized;\n    if (!initialized)\n    {\n        static if (isSeedable!(Random, ReturnType!unpredictableSeed))\n            result.seed(unpredictableSeed); // Avoid unnecessary copy.\n        else\n            result = Random(unpredictableSeed);\n        initialized = true;\n    }\n    return result;\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.iteration : sum;\n    import std.range : take;\n    auto rnd = rndGen;\n    assert(rnd.take(3).sum > 0);\n}\n\n/**\nGenerates a number between `a` and `b`. The `boundaries`\nparameter controls the shape of the interval (open vs. closed on\neither side). Valid values for `boundaries` are `\"[]\"`, $(D\n\"$(LPAREN)]\"), `\"[$(RPAREN)\"`, and `\"()\"`. The default interval\nis closed to the left and open to the right. The version that does not\ntake `urng` uses the default generator `rndGen`.\n\nParams:\n    a = lower bound of the _uniform distribution\n    b = upper bound of the _uniform distribution\n    urng = (optional) random number generator to use;\n           if not specified, defaults to `rndGen`\n\nReturns:\n    A single random variate drawn from the _uniform distribution\n    between `a` and `b`, whose type is the common type of\n    these parameters\n */\nauto uniform(string boundaries = \"[)\", T1, T2)\n(T1 a, T2 b)\nif (!is(CommonType!(T1, T2) == void))\n{\n    return uniform!(boundaries, T1, T2, Random)(a, b, rndGen);\n}\n\n///\n@safe unittest\n{\n    auto rnd = Random(unpredictableSeed);\n\n    // Generate an integer in [0, 1023]\n    auto a = uniform(0, 1024, rnd);\n    assert(0 <= a && a < 1024);\n\n    // Generate a float in [0, 1)\n    auto b = uniform(0.0f, 1.0f, rnd);\n    assert(0 <= b && b < 1);\n\n    // Generate a float in [0, 1]\n    b = uniform!\"[]\"(0.0f, 1.0f, rnd);\n    assert(0 <= b && b <= 1);\n\n    // Generate a float in (0, 1)\n    b = uniform!\"()\"(0.0f, 1.0f, rnd);\n    assert(0 < b && b < 1);\n}\n\n/// Create an array of random numbers using range functions and UFCS\n@safe unittest\n{\n    import std.array : array;\n    import std.range : generate, takeExactly;\n\n    int[] arr = generate!(() => uniform(0, 100)).takeExactly(10).array;\n    assert(arr.length == 10);\n    assert(arr[0] >= 0 && arr[0] < 100);\n}\n\n@safe unittest\n{\n    MinstdRand0 gen;\n    foreach (i; 0 .. 20)\n    {\n        auto x = uniform(0.0, 15.0, gen);\n        assert(0 <= x && x < 15);\n    }\n    foreach (i; 0 .. 20)\n    {\n        auto x = uniform!\"[]\"('a', 'z', gen);\n        assert('a' <= x && x <= 'z');\n    }\n\n    foreach (i; 0 .. 20)\n    {\n        auto x = uniform('a', 'z', gen);\n        assert('a' <= x && x < 'z');\n    }\n\n    foreach (i; 0 .. 20)\n    {\n        immutable ubyte a = 0;\n            immutable ubyte b = 15;\n        auto x = uniform(a, b, gen);\n            assert(a <= x && x < b);\n    }\n}\n\n// Implementation of uniform for floating-point types\n/// ditto\nauto uniform(string boundaries = \"[)\",\n        T1, T2, UniformRandomNumberGenerator)\n(T1 a, T2 b, ref UniformRandomNumberGenerator urng)\nif (isFloatingPoint!(CommonType!(T1, T2)) && isUniformRNG!UniformRandomNumberGenerator)\n{\n    import std.conv : text;\n    import std.exception : enforce;\n    alias NumberType = Unqual!(CommonType!(T1, T2));\n    static if (boundaries[0] == '(')\n    {\n        import std.math : nextafter;\n        NumberType _a = nextafter(cast(NumberType) a, NumberType.infinity);\n    }\n    else\n    {\n        NumberType _a = a;\n    }\n    static if (boundaries[1] == ')')\n    {\n        import std.math : nextafter;\n        NumberType _b = nextafter(cast(NumberType) b, -NumberType.infinity);\n    }\n    else\n    {\n        NumberType _b = b;\n    }\n    enforce(_a <= _b,\n            text(\"std.random.uniform(): invalid bounding interval \",\n                    boundaries[0], a, \", \", b, boundaries[1]));\n    NumberType result =\n        _a + (_b - _a) * cast(NumberType) (urng.front - urng.min)\n        / (urng.max - urng.min);\n    urng.popFront();\n    return result;\n}\n\n// Implementation of uniform for integral types\n/+ Description of algorithm and suggestion of correctness:\n\nThe modulus operator maps an integer to a small, finite space. For instance, `x\n% 3` will map whatever x is into the range [0 .. 3). 0 maps to 0, 1 maps to 1, 2\nmaps to 2, 3 maps to 0, and so on infinitely. As long as the integer is\nuniformly chosen from the infinite space of all non-negative integers then `x %\n3` will uniformly fall into that range.\n\n(Non-negative is important in this case because some definitions of modulus,\nnamely the one used in computers generally, map negative numbers differently to\n(-3 .. 0]. `uniform` does not use negative number modulus, thus we can safely\nignore that fact.)\n\nThe issue with computers is that integers have a finite space they must fit in,\nand our uniformly chosen random number is picked in that finite space. So, that\nmethod is not sufficient. You can look at it as the integer space being divided\ninto \"buckets\" and every bucket after the first bucket maps directly into that\nfirst bucket. `[0, 1, 2]`, `[3, 4, 5]`, ... When integers are finite, then the\nlast bucket has the chance to be \"incomplete\": `[uint.max - 3, uint.max - 2,\nuint.max - 1]`, `[uint.max]` ... (the last bucket only has 1!). The issue here\nis that _every_ bucket maps _completely_ to the first bucket except for that\nlast one. The last one doesn't have corresponding mappings to 1 or 2, in this\ncase, which makes it unfair.\n\nSo, the answer is to simply \"reroll\" if you're in that last bucket, since it's\nthe only unfair one. Eventually you'll roll into a fair bucket. Simply, instead\nof the meaning of the last bucket being \"maps to `[0]`\", it changes to \"maps to\n`[0, 1, 2]`\", which is precisely what we want.\n\nTo generalize, `upperDist` represents the size of our buckets (and, thus, the\nexclusive upper bound for our desired uniform number). `rnum` is a uniformly\nrandom number picked from the space of integers that a computer can hold (we'll\nsay `UpperType` represents that type).\n\nWe'll first try to do the mapping into the first bucket by doing `offset = rnum\n% upperDist`. We can figure out the position of the front of the bucket we're in\nby `bucketFront = rnum - offset`.\n\nIf we start at `UpperType.max` and walk backwards `upperDist - 1` spaces, then\nthe space we land on is the last acceptable position where a full bucket can\nfit:\n\n---\n   bucketFront     UpperType.max\n      v                 v\n[..., 0, 1, 2, ..., upperDist - 1]\n      ^~~ upperDist - 1 ~~^\n---\n\nIf the bucket starts any later, then it must have lost at least one number and\nat least that number won't be represented fairly.\n\n---\n                bucketFront     UpperType.max\n                     v                v\n[..., upperDist - 1, 0, 1, 2, ..., upperDist - 2]\n          ^~~~~~~~ upperDist - 1 ~~~~~~~^\n---\n\nHence, our condition to reroll is\n`bucketFront > (UpperType.max - (upperDist - 1))`\n+/\nauto uniform(string boundaries = \"[)\", T1, T2, RandomGen)\n(T1 a, T2 b, ref RandomGen rng)\nif ((isIntegral!(CommonType!(T1, T2)) || isSomeChar!(CommonType!(T1, T2))) &&\n     isUniformRNG!RandomGen)\n{\n    import std.conv : text, unsigned;\n    import std.exception : enforce;\n    alias ResultType = Unqual!(CommonType!(T1, T2));\n    static if (boundaries[0] == '(')\n    {\n        enforce(a < ResultType.max,\n                text(\"std.random.uniform(): invalid left bound \", a));\n        ResultType lower = cast(ResultType) (a + 1);\n    }\n    else\n    {\n        ResultType lower = a;\n    }\n\n    static if (boundaries[1] == ']')\n    {\n        enforce(lower <= b,\n                text(\"std.random.uniform(): invalid bounding interval \",\n                        boundaries[0], a, \", \", b, boundaries[1]));\n        /* Cannot use this next optimization with dchar, as dchar\n         * only partially uses its full bit range\n         */\n        static if (!is(ResultType == dchar))\n        {\n            if (b == ResultType.max && lower == ResultType.min)\n            {\n                // Special case - all bits are occupied\n                return std.random.uniform!ResultType(rng);\n            }\n        }\n        auto upperDist = unsigned(b - lower) + 1u;\n    }\n    else\n    {\n        enforce(lower < b,\n                text(\"std.random.uniform(): invalid bounding interval \",\n                        boundaries[0], a, \", \", b, boundaries[1]));\n        auto upperDist = unsigned(b - lower);\n    }\n\n    assert(upperDist != 0);\n\n    alias UpperType = typeof(upperDist);\n    static assert(UpperType.min == 0);\n\n    UpperType offset, rnum, bucketFront;\n    do\n    {\n        rnum = uniform!UpperType(rng);\n        offset = rnum % upperDist;\n        bucketFront = rnum - offset;\n    } // while we're in an unfair bucket...\n    while (bucketFront > (UpperType.max - (upperDist - 1)));\n\n    return cast(ResultType)(lower + offset);\n}\n\n@safe unittest\n{\n    import std.conv : to;\n    auto gen = Mt19937(123_456_789);\n    static assert(isForwardRange!(typeof(gen)));\n\n    auto a = uniform(0, 1024, gen);\n    assert(0 <= a && a <= 1024);\n    auto b = uniform(0.0f, 1.0f, gen);\n    assert(0 <= b && b < 1, to!string(b));\n    auto c = uniform(0.0, 1.0);\n    assert(0 <= c && c < 1);\n\n    static foreach (T; std.meta.AliasSeq!(char, wchar, dchar, byte, ubyte, short, ushort,\n                          int, uint, long, ulong, float, double, real))\n    {{\n        T lo = 0, hi = 100;\n\n        // Try tests with each of the possible bounds\n        {\n            T init = uniform(lo, hi);\n            size_t i = 50;\n            while (--i && uniform(lo, hi) == init) {}\n            assert(i > 0);\n        }\n        {\n            T init = uniform!\"[)\"(lo, hi);\n            size_t i = 50;\n            while (--i && uniform(lo, hi) == init) {}\n            assert(i > 0);\n        }\n        {\n            T init = uniform!\"(]\"(lo, hi);\n            size_t i = 50;\n            while (--i && uniform(lo, hi) == init) {}\n            assert(i > 0);\n        }\n        {\n            T init = uniform!\"()\"(lo, hi);\n            size_t i = 50;\n            while (--i && uniform(lo, hi) == init) {}\n            assert(i > 0);\n        }\n        {\n            T init = uniform!\"[]\"(lo, hi);\n            size_t i = 50;\n            while (--i && uniform(lo, hi) == init) {}\n            assert(i > 0);\n        }\n\n        /* Test case with closed boundaries covering whole range\n         * of integral type\n         */\n        static if (isIntegral!T || isSomeChar!T)\n        {\n            foreach (immutable _; 0 .. 100)\n            {\n                auto u = uniform!\"[]\"(T.min, T.max);\n                static assert(is(typeof(u) == T));\n                assert(T.min <= u, \"Lower bound violation for uniform!\\\"[]\\\" with \" ~ T.stringof);\n                assert(u <= T.max, \"Upper bound violation for uniform!\\\"[]\\\" with \" ~ T.stringof);\n            }\n        }\n    }}\n\n    auto reproRng = Xorshift(239842);\n\n    static foreach (T; std.meta.AliasSeq!(char, wchar, dchar, byte, ubyte, short,\n                          ushort, int, uint, long, ulong))\n    {{\n        T lo = T.min + 10, hi = T.max - 10;\n        T init = uniform(lo, hi, reproRng);\n        size_t i = 50;\n        while (--i && uniform(lo, hi, reproRng) == init) {}\n        assert(i > 0);\n    }}\n\n    {\n        bool sawLB = false, sawUB = false;\n        foreach (i; 0 .. 50)\n        {\n            auto x = uniform!\"[]\"('a', 'd', reproRng);\n            if (x == 'a') sawLB = true;\n            if (x == 'd') sawUB = true;\n            assert('a' <= x && x <= 'd');\n        }\n        assert(sawLB && sawUB);\n    }\n\n    {\n        bool sawLB = false, sawUB = false;\n        foreach (i; 0 .. 50)\n        {\n            auto x = uniform('a', 'd', reproRng);\n            if (x == 'a') sawLB = true;\n            if (x == 'c') sawUB = true;\n            assert('a' <= x && x < 'd');\n        }\n        assert(sawLB && sawUB);\n    }\n\n    {\n        bool sawLB = false, sawUB = false;\n        foreach (i; 0 .. 50)\n        {\n            immutable int lo = -2, hi = 2;\n            auto x = uniform!\"()\"(lo, hi, reproRng);\n            if (x == (lo+1)) sawLB = true;\n            if (x == (hi-1)) sawUB = true;\n            assert(lo < x && x < hi);\n        }\n        assert(sawLB && sawUB);\n    }\n\n    {\n        bool sawLB = false, sawUB = false;\n        foreach (i; 0 .. 50)\n        {\n            immutable ubyte lo = 0, hi = 5;\n            auto x = uniform(lo, hi, reproRng);\n            if (x == lo) sawLB = true;\n            if (x == (hi-1)) sawUB = true;\n            assert(lo <= x && x < hi);\n        }\n        assert(sawLB && sawUB);\n    }\n\n    {\n        foreach (i; 0 .. 30)\n        {\n            assert(i == uniform(i, i+1, reproRng));\n        }\n    }\n}\n\n/+\nGenerates an unsigned integer in the half-open range `[0, k)`.\nNon-public because we locally guarantee `k > 0`.\n\nParams:\n    k = unsigned exclusive upper bound; caller guarantees this is non-zero\n    rng = random number generator to use\n\nReturns:\n    Pseudo-random unsigned integer strictly less than `k`.\n+/\nprivate UInt _uniformIndex(UniformRNG, UInt = size_t)(const UInt k, ref UniformRNG rng)\nif (isUnsigned!UInt && isUniformRNG!UniformRNG)\n{\n    alias ResultType = UInt;\n    alias UpperType = Unsigned!(typeof(k - 0));\n    alias upperDist = k;\n\n    assert(upperDist != 0);\n\n    // For backwards compatibility use same algorithm as uniform(0, k, rng).\n    UpperType offset, rnum, bucketFront;\n    do\n    {\n        rnum = uniform!UpperType(rng);\n        offset = rnum % upperDist;\n        bucketFront = rnum - offset;\n    } // while we're in an unfair bucket...\n    while (bucketFront > (UpperType.max - (upperDist - 1)));\n\n    return cast(ResultType) offset;\n}\n\npure @safe unittest\n{\n    // For backwards compatibility check that _uniformIndex(k, rng)\n    // has the same result as uniform(0, k, rng).\n    auto rng1 = Xorshift(123_456_789);\n    auto rng2 = rng1.save();\n    const size_t k = (1U << 31) - 1;\n    assert(_uniformIndex(k, rng1) == uniform(0, k, rng2));\n}\n\n/**\nGenerates a uniformly-distributed number in the range $(D [T.min,\nT.max]) for any integral or character type `T`. If no random\nnumber generator is passed, uses the default `rndGen`.\n\nIf an `enum` is used as type, the random variate is drawn with\nequal probability from any of the possible values of the enum `E`.\n\nParams:\n    urng = (optional) random number generator to use;\n           if not specified, defaults to `rndGen`\n\nReturns:\n    Random variate drawn from the _uniform distribution across all\n    possible values of the integral, character or enum type `T`.\n */\nauto uniform(T, UniformRandomNumberGenerator)\n(ref UniformRandomNumberGenerator urng)\nif (!is(T == enum) && (isIntegral!T || isSomeChar!T) && isUniformRNG!UniformRandomNumberGenerator)\n{\n    /* dchar does not use its full bit range, so we must\n     * revert to the uniform with specified bounds\n     */\n    static if (is(T == dchar))\n    {\n        return uniform!\"[]\"(T.min, T.max);\n    }\n    else\n    {\n        auto r = urng.front;\n        urng.popFront();\n        static if (T.sizeof <= r.sizeof)\n        {\n            return cast(T) r;\n        }\n        else\n        {\n            static assert(T.sizeof == 8 && r.sizeof == 4);\n            T r1 = urng.front | (cast(T) r << 32);\n            urng.popFront();\n            return r1;\n        }\n    }\n}\n\n/// Ditto\nauto uniform(T)()\nif (!is(T == enum) && (isIntegral!T || isSomeChar!T))\n{\n    return uniform!T(rndGen);\n}\n\n///\n@safe unittest\n{\n    auto rnd = MinstdRand0(42);\n\n    assert(rnd.uniform!ubyte == 102);\n    assert(rnd.uniform!ulong == 4838462006927449017);\n\n    enum Fruit { apple, mango, pear }\n    version (X86_64) // Issue 15147\n    assert(rnd.uniform!Fruit == Fruit.mango);\n}\n\n@safe unittest\n{\n    static foreach (T; std.meta.AliasSeq!(char, wchar, dchar, byte, ubyte, short, ushort,\n                          int, uint, long, ulong))\n    {{\n        T init = uniform!T();\n        size_t i = 50;\n        while (--i && uniform!T() == init) {}\n        assert(i > 0);\n\n        foreach (immutable _; 0 .. 100)\n        {\n            auto u = uniform!T();\n            static assert(is(typeof(u) == T));\n            assert(T.min <= u, \"Lower bound violation for uniform!\" ~ T.stringof);\n            assert(u <= T.max, \"Upper bound violation for uniform!\" ~ T.stringof);\n        }\n    }}\n}\n\n/// ditto\nauto uniform(E, UniformRandomNumberGenerator)\n(ref UniformRandomNumberGenerator urng)\nif (is(E == enum) && isUniformRNG!UniformRandomNumberGenerator)\n{\n    static immutable E[EnumMembers!E.length] members = [EnumMembers!E];\n    return members[std.random.uniform(0, members.length, urng)];\n}\n\n/// Ditto\nauto uniform(E)()\nif (is(E == enum))\n{\n    return uniform!E(rndGen);\n}\n\n@safe unittest\n{\n    enum Fruit { Apple = 12, Mango = 29, Pear = 72 }\n    foreach (_; 0 .. 100)\n    {\n        foreach (f; [uniform!Fruit(), rndGen.uniform!Fruit()])\n        {\n            assert(f == Fruit.Apple || f == Fruit.Mango || f == Fruit.Pear);\n        }\n    }\n}\n\n/**\n * Generates a uniformly-distributed floating point number of type\n * `T` in the range [0, 1$(RPAREN).  If no random number generator is\n * specified, the default RNG `rndGen` will be used as the source\n * of randomness.\n *\n * `uniform01` offers a faster generation of random variates than\n * the equivalent $(D uniform!\"[$(RPAREN)\"(0.0, 1.0)) and so may be preferred\n * for some applications.\n *\n * Params:\n *     rng = (optional) random number generator to use;\n *           if not specified, defaults to `rndGen`\n *\n * Returns:\n *     Floating-point random variate of type `T` drawn from the _uniform\n *     distribution across the half-open interval [0, 1$(RPAREN).\n *\n */\nT uniform01(T = double)()\nif (isFloatingPoint!T)\n{\n    return uniform01!T(rndGen);\n}\n\n/// ditto\nT uniform01(T = double, UniformRNG)(ref UniformRNG rng)\nif (isFloatingPoint!T && isUniformRNG!UniformRNG)\nout (result)\n{\n    assert(0 <= result);\n    assert(result < 1);\n}\ndo\n{\n    alias R = typeof(rng.front);\n    static if (isIntegral!R)\n    {\n        enum T factor = 1 / (T(1) + rng.max - rng.min);\n    }\n    else static if (isFloatingPoint!R)\n    {\n        enum T factor = 1 / (rng.max - rng.min);\n    }\n    else\n    {\n        static assert(false);\n    }\n\n    while (true)\n    {\n        immutable T u = (rng.front - rng.min) * factor;\n        rng.popFront();\n\n        static if (isIntegral!R && T.mant_dig >= (8 * R.sizeof))\n        {\n            /* If RNG variates are integral and T has enough precision to hold\n             * R without loss, we're guaranteed by the definition of factor\n             * that precisely u < 1.\n             */\n            return u;\n        }\n        else\n        {\n            /* Otherwise we have to check whether u is beyond the assumed range\n             * because of the loss of precision, or for another reason, a\n             * floating-point RNG can return a variate that is exactly equal to\n             * its maximum.\n             */\n            if (u < 1)\n            {\n                return u;\n            }\n        }\n    }\n\n    // Shouldn't ever get here.\n    assert(false);\n}\n\n///\n@safe @nogc unittest\n{\n    import std.math : feqrel;\n\n    auto rnd = MinstdRand0(42);\n\n    assert(rnd.uniform01.feqrel(0.000328707) > 20);\n    assert(rnd.uniform01!float.feqrel(0.524587) > 20);\n}\n\n@safe @nogc unittest\n{\n    import std.meta;\n    static foreach (UniformRNG; PseudoRngTypes)\n    {{\n\n        static foreach (T; std.meta.AliasSeq!(float, double, real))\n        {{\n            UniformRNG rng = UniformRNG(123_456_789);\n\n            auto a = uniform01();\n            assert(is(typeof(a) == double));\n            assert(0 <= a && a < 1);\n\n            auto b = uniform01(rng);\n            assert(is(typeof(a) == double));\n            assert(0 <= b && b < 1);\n\n            auto c = uniform01!T();\n            assert(is(typeof(c) == T));\n            assert(0 <= c && c < 1);\n\n            auto d = uniform01!T(rng);\n            assert(is(typeof(d) == T));\n            assert(0 <= d && d < 1);\n\n            T init = uniform01!T(rng);\n            size_t i = 50;\n            while (--i && uniform01!T(rng) == init) {}\n            assert(i > 0);\n            assert(i < 50);\n        }}\n    }}\n}\n\n/**\nGenerates a uniform probability distribution of size `n`, i.e., an\narray of size `n` of positive numbers of type `F` that sum to\n`1`. If `useThis` is provided, it is used as storage.\n */\nF[] uniformDistribution(F = double)(size_t n, F[] useThis = null)\nif (isFloatingPoint!F)\n{\n    import std.numeric : normalize;\n    useThis.length = n;\n    foreach (ref e; useThis)\n    {\n        e = uniform(0.0, 1);\n    }\n    normalize(useThis);\n    return useThis;\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.iteration : reduce;\n    import std.math : approxEqual;\n\n    auto a = uniformDistribution(5);\n    assert(a.length == 5);\n    assert(approxEqual(reduce!\"a + b\"(a), 1));\n\n    a = uniformDistribution(10, a);\n    assert(a.length == 10);\n    assert(approxEqual(reduce!\"a + b\"(a), 1));\n}\n\n/**\nReturns a random, uniformly chosen, element `e` from the supplied\n$(D Range range). If no random number generator is passed, the default\n`rndGen` is used.\n\nParams:\n    range = a random access range that has the `length` property defined\n    urng = (optional) random number generator to use;\n           if not specified, defaults to `rndGen`\n\nReturns:\n    A single random element drawn from the `range`. If it can, it will\n    return a `ref` to the $(D range element), otherwise it will return\n    a copy.\n */\nauto ref choice(Range, RandomGen = Random)(auto ref Range range, ref RandomGen urng)\nif (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen)\n{\n    assert(range.length > 0,\n           __PRETTY_FUNCTION__ ~ \": invalid Range supplied. Range cannot be empty\");\n\n    return range[uniform(size_t(0), $, urng)];\n}\n\n/// ditto\nauto ref choice(Range)(auto ref Range range)\n{\n    return choice(range, rndGen);\n}\n\n///\n@safe unittest\n{\n    auto rnd = MinstdRand0(42);\n\n    auto elem  = [1, 2, 3, 4, 5].choice(rnd);\n    version (X86_64) // Issue 15147\n    assert(elem == 3);\n}\n\n@safe unittest\n{\n    import std.algorithm.searching : canFind;\n\n    class MyTestClass\n    {\n        int x;\n\n        this(int x)\n        {\n            this.x = x;\n        }\n    }\n\n    MyTestClass[] testClass;\n    foreach (i; 0 .. 5)\n    {\n        testClass ~= new MyTestClass(i);\n    }\n\n    auto elem = choice(testClass);\n\n    assert(canFind!((ref MyTestClass a, ref MyTestClass b) => a.x == b.x)(testClass, elem),\n           \"Choice did not return a valid element from the given Range\");\n}\n\n@system unittest\n{\n    import std.algorithm.iteration : map;\n    import std.algorithm.searching : canFind;\n\n    auto array = [1, 2, 3, 4, 5];\n    auto elemAddr = &choice(array);\n\n    assert(array.map!((ref e) => &e).canFind(elemAddr),\n           \"Choice did not return a ref to an element from the given Range\");\n    assert(array.canFind(*(cast(int *)(elemAddr))),\n           \"Choice did not return a valid element from the given Range\");\n}\n\n/**\nShuffles elements of `r` using `gen` as a shuffler. `r` must be\na random-access range with length.  If no RNG is specified, `rndGen`\nwill be used.\n\nParams:\n    r = random-access range whose elements are to be shuffled\n    gen = (optional) random number generator to use; if not\n          specified, defaults to `rndGen`\nReturns:\n    The shuffled random-access range.\n*/\n\nRange randomShuffle(Range, RandomGen)(Range r, ref RandomGen gen)\nif (isRandomAccessRange!Range && isUniformRNG!RandomGen)\n{\n    import std.algorithm.mutation : swapAt;\n    const n = r.length;\n    foreach (i; 0 .. n)\n    {\n        r.swapAt(i, i + _uniformIndex(n - i, gen));\n    }\n    return r;\n}\n\n/// ditto\nRange randomShuffle(Range)(Range r)\nif (isRandomAccessRange!Range)\n{\n    return randomShuffle(r, rndGen);\n}\n\n///\n@safe unittest\n{\n    auto rnd = MinstdRand0(42);\n\n    auto arr = [1, 2, 3, 4, 5].randomShuffle(rnd);\n    version (X86_64) // Issue 15147\n    assert(arr == [3, 5, 2, 4, 1]);\n}\n\n@safe unittest\n{\n    int[10] sa = void;\n    int[10] sb = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n    import std.algorithm.sorting : sort;\n    foreach (RandomGen; PseudoRngTypes)\n    {\n        sa[] = sb[];\n        auto a = sa[];\n        auto b = sb[];\n        auto gen = RandomGen(123_456_789);\n        randomShuffle(a, gen);\n        sort(a);\n        assert(a == b);\n        randomShuffle(a);\n        sort(a);\n        assert(a == b);\n    }\n    // For backwards compatibility verify randomShuffle(r, gen)\n    // is equivalent to partialShuffle(r, 0, r.length, gen).\n    auto gen1 = Xorshift(123_456_789);\n    auto gen2 = gen1.save();\n    sa[] = sb[];\n    // Issue 19156 - @nogc std.random.randomShuffle.\n    () @nogc nothrow pure { randomShuffle(sa[], gen1); }();\n    partialShuffle(sb[], sb.length, gen2);\n    assert(sa[] == sb[]);\n}\n\n@safe unittest // bugzilla 18501\n{\n    import std.algorithm.comparison : among;\n    auto r = randomShuffle([0,1]);\n    assert(r.among([0,1],[1,0]));\n}\n\n/**\nPartially shuffles the elements of `r` such that upon returning $(D r[0 .. n])\nis a random subset of `r` and is randomly ordered.  $(D r[n .. r.length])\nwill contain the elements not in $(D r[0 .. n]).  These will be in an undefined\norder, but will not be random in the sense that their order after\n`partialShuffle` returns will not be independent of their order before\n`partialShuffle` was called.\n\n`r` must be a random-access range with length.  `n` must be less than\nor equal to `r.length`.  If no RNG is specified, `rndGen` will be used.\n\nParams:\n    r = random-access range whose elements are to be shuffled\n    n = number of elements of `r` to shuffle (counting from the beginning);\n        must be less than `r.length`\n    gen = (optional) random number generator to use; if not\n          specified, defaults to `rndGen`\nReturns:\n    The shuffled random-access range.\n*/\nRange partialShuffle(Range, RandomGen)(Range r, in size_t n, ref RandomGen gen)\nif (isRandomAccessRange!Range && isUniformRNG!RandomGen)\n{\n    import std.algorithm.mutation : swapAt;\n    import std.exception : enforce;\n    enforce(n <= r.length, \"n must be <= r.length for partialShuffle.\");\n    foreach (i; 0 .. n)\n    {\n        r.swapAt(i, uniform(i, r.length, gen));\n    }\n    return r;\n}\n\n/// ditto\nRange partialShuffle(Range)(Range r, in size_t n)\nif (isRandomAccessRange!Range)\n{\n    return partialShuffle(r, n, rndGen);\n}\n\n///\n@safe unittest\n{\n    auto rnd = MinstdRand0(42);\n\n    auto arr = [1, 2, 3, 4, 5, 6];\n    arr = arr.dup.partialShuffle(1, rnd);\n\n    version (X86_64) // Issue 15147\n    assert(arr == [2, 1, 3, 4, 5, 6]); // 1<->2\n\n    arr = arr.dup.partialShuffle(2, rnd);\n    version (X86_64) // Issue 15147\n    assert(arr == [1, 4, 3, 2, 5, 6]); // 1<->2, 2<->4\n\n    arr = arr.dup.partialShuffle(3, rnd);\n    version (X86_64) // Issue 15147\n    assert(arr == [5, 4, 6, 2, 1, 3]); // 1<->5, 2<->4, 3<->6\n}\n\n@safe unittest\n{\n    import std.algorithm;\n    foreach (RandomGen; PseudoRngTypes)\n    {\n        auto a = [0, 1, 1, 2, 3];\n        auto b = a.dup;\n\n        // Pick a fixed seed so that the outcome of the statistical\n        // test below is deterministic.\n        auto gen = RandomGen(12345);\n\n        // NUM times, pick LEN elements from the array at random.\n        immutable int LEN = 2;\n        immutable int NUM = 750;\n        int[][] chk;\n        foreach (step; 0 .. NUM)\n        {\n            partialShuffle(a, LEN, gen);\n            chk ~= a[0 .. LEN].dup;\n        }\n\n        // Check that each possible a[0 .. LEN] was produced at least once.\n        // For a perfectly random RandomGen, the probability that each\n        // particular combination failed to appear would be at most\n        // 0.95 ^^ NUM which is approximately 1,962e-17.\n        // As long as hardware failure (e.g. bit flip) probability\n        // is higher, we are fine with this unittest.\n        sort(chk);\n        assert(equal(uniq(chk), [       [0,1], [0,2], [0,3],\n                                 [1,0], [1,1], [1,2], [1,3],\n                                 [2,0], [2,1],        [2,3],\n                                 [3,0], [3,1], [3,2],      ]));\n\n        // Check that all the elements are still there.\n        sort(a);\n        assert(equal(a, b));\n    }\n}\n\n/**\nRolls a dice with relative probabilities stored in $(D\nproportions). Returns the index in `proportions` that was chosen.\n\nParams:\n    rnd = (optional) random number generator to use; if not\n          specified, defaults to `rndGen`\n    proportions = forward range or list of individual values\n                  whose elements correspond to the probabilities\n                  with which to choose the corresponding index\n                  value\n\nReturns:\n    Random variate drawn from the index values\n    [0, ... `proportions.length` - 1], with the probability\n    of getting an individual index value `i` being proportional to\n    `proportions[i]`.\n*/\nsize_t dice(Rng, Num)(ref Rng rnd, Num[] proportions...)\nif (isNumeric!Num && isForwardRange!Rng)\n{\n    return diceImpl(rnd, proportions);\n}\n\n/// Ditto\nsize_t dice(R, Range)(ref R rnd, Range proportions)\nif (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)\n{\n    return diceImpl(rnd, proportions);\n}\n\n/// Ditto\nsize_t dice(Range)(Range proportions)\nif (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)\n{\n    return diceImpl(rndGen, proportions);\n}\n\n/// Ditto\nsize_t dice(Num)(Num[] proportions...)\nif (isNumeric!Num)\n{\n    return diceImpl(rndGen, proportions);\n}\n\n///\n@safe unittest\n{\n    auto x = dice(0.5, 0.5);   // x is 0 or 1 in equal proportions\n    auto y = dice(50, 50);     // y is 0 or 1 in equal proportions\n    auto z = dice(70, 20, 10); // z is 0 70% of the time, 1 20% of the time,\n                               // and 2 10% of the time\n}\n\n///\n@safe unittest\n{\n    auto rnd = MinstdRand0(42);\n    auto z = rnd.dice(70, 20, 10);\n    assert(z == 0);\n    z = rnd.dice(30, 20, 40, 10);\n    assert(z == 2);\n}\n\nprivate size_t diceImpl(Rng, Range)(ref Rng rng, scope Range proportions)\nif (isForwardRange!Range && isNumeric!(ElementType!Range) && isForwardRange!Rng)\nin\n{\n    import std.algorithm.searching : all;\n    assert(proportions.save.all!\"a >= 0\");\n}\ndo\n{\n    import std.algorithm.iteration : reduce;\n    import std.exception : enforce;\n    double sum = reduce!\"a + b\"(0.0, proportions.save);\n    enforce(sum > 0, \"Proportions in a dice cannot sum to zero\");\n    immutable point = uniform(0.0, sum, rng);\n    assert(point < sum);\n    auto mass = 0.0;\n\n    size_t i = 0;\n    foreach (e; proportions)\n    {\n        mass += e;\n        if (point < mass) return i;\n        i++;\n    }\n    // this point should not be reached\n    assert(false);\n}\n\n///\n@safe unittest\n{\n    auto rnd = Xorshift(123_456_789);\n    auto i = dice(rnd, 0.0, 100.0);\n    assert(i == 1);\n    i = dice(rnd, 100.0, 0.0);\n    assert(i == 0);\n\n    i = dice(100U, 0U);\n    assert(i == 0);\n}\n\n/+ @nogc bool array designed for RandomCover.\n- constructed with an invariable length\n- small length means 0 alloc and bit field (if up to 32(x86) or 64(x64) choices to cover)\n- bigger length means non-GC heap allocation(s) and dealloc. +/\nprivate struct RandomCoverChoices\n{\n    private void* buffer;\n    private immutable size_t _length;\n    private immutable bool hasPackedBits;\n\n    void opAssign(T)(T) @disable;\n\n    this(this) pure nothrow @nogc @trusted\n    {\n        import core.memory : pureMalloc;\n        import core.stdc.string : memcpy;\n        import core.exception : onOutOfMemoryError;\n\n        if (!hasPackedBits && buffer !is null)\n        {\n            void* nbuffer = pureMalloc(_length);\n            if (nbuffer is null)\n                onOutOfMemoryError();\n            buffer = memcpy(nbuffer, buffer, _length);\n        }\n    }\n\n    this(size_t numChoices) pure nothrow @nogc @trusted\n    {\n        import core.memory : pureCalloc;\n        import core.exception : onOutOfMemoryError;\n\n        _length = numChoices;\n        hasPackedBits = _length <= size_t.sizeof * 8;\n        if (!hasPackedBits)\n        {\n            buffer = pureCalloc(numChoices, 1);\n            if (buffer is null)\n                onOutOfMemoryError();\n        }\n    }\n\n    size_t length() const pure nothrow @nogc @safe @property {return _length;}\n\n    ~this() pure nothrow @nogc @trusted\n    {\n        import core.memory : pureFree;\n\n        if (!hasPackedBits && buffer !is null)\n            pureFree(buffer);\n    }\n\n    bool opIndex(size_t index) const pure nothrow @nogc @trusted\n    {\n        assert(index < _length);\n        if (!hasPackedBits)\n            return *((cast(bool*) buffer) + index);\n        else\n            return ((cast(size_t) buffer) >> index) & size_t(1);\n    }\n\n    void opIndexAssign(bool value, size_t index) pure nothrow @nogc @trusted\n    {\n        assert(index < _length);\n        if (!hasPackedBits)\n        {\n            *((cast(bool*) buffer) + index) = value;\n        }\n        else\n        {\n            if (value)\n                (*cast(size_t*) &buffer) |= size_t(1) << index;\n            else\n                (*cast(size_t*) &buffer) &= ~(size_t(1) << index);\n        }\n    }\n}\n\n@safe @nogc nothrow unittest\n{\n    static immutable lengths = [3, 32, 65, 256];\n    foreach (length; lengths)\n    {\n        RandomCoverChoices c = RandomCoverChoices(length);\n        assert(c.hasPackedBits == (length <= size_t.sizeof * 8));\n        c[0] = true;\n        c[2] = true;\n        assert(c[0]);\n        assert(!c[1]);\n        assert(c[2]);\n        c[0] = false;\n        c[1] = true;\n        c[2] = false;\n        assert(!c[0]);\n        assert(c[1]);\n        assert(!c[2]);\n    }\n}\n\n/**\nCovers a given range `r` in a random manner, i.e. goes through each\nelement of `r` once and only once, just in a random order. `r`\nmust be a random-access range with length.\n\nIf no random number generator is passed to `randomCover`, the\nthread-global RNG rndGen will be used internally.\n\nParams:\n    r = random-access range to cover\n    rng = (optional) random number generator to use;\n          if not specified, defaults to `rndGen`\n\nReturns:\n    Range whose elements consist of the elements of `r`,\n    in random order.  Will be a forward range if both `r` and\n    `rng` are forward ranges, an\n    $(REF_ALTTEXT input range, isInputRange, std,range,primitives) otherwise.\n*/\nstruct RandomCover(Range, UniformRNG = void)\nif (isRandomAccessRange!Range && (isUniformRNG!UniformRNG || is(UniformRNG == void)))\n{\n    private Range _input;\n    private RandomCoverChoices _chosen;\n    private size_t _current;\n    private size_t _alreadyChosen = 0;\n    private bool _isEmpty = false;\n\n    static if (is(UniformRNG == void))\n    {\n        this(Range input)\n        {\n            _input = input;\n            _chosen = RandomCoverChoices(_input.length);\n            if (_input.empty)\n            {\n                _isEmpty = true;\n            }\n            else\n            {\n                _current = _uniformIndex(_chosen.length, rndGen);\n            }\n        }\n    }\n    else\n    {\n        private UniformRNG _rng;\n\n        this(Range input, ref UniformRNG rng)\n        {\n            _input = input;\n            _rng = rng;\n            _chosen = RandomCoverChoices(_input.length);\n            if (_input.empty)\n            {\n                _isEmpty = true;\n            }\n            else\n            {\n                _current = _uniformIndex(_chosen.length, rng);\n            }\n        }\n\n        this(Range input, UniformRNG rng)\n        {\n            this(input, rng);\n        }\n    }\n\n    static if (hasLength!Range)\n    {\n        @property size_t length()\n        {\n            return _input.length - _alreadyChosen;\n        }\n    }\n\n    @property auto ref front()\n    {\n        assert(!_isEmpty);\n        return _input[_current];\n    }\n\n    void popFront()\n    {\n        assert(!_isEmpty);\n\n        size_t k = _input.length - _alreadyChosen - 1;\n        if (k == 0)\n        {\n            _isEmpty = true;\n            ++_alreadyChosen;\n            return;\n        }\n\n        size_t i;\n        foreach (e; _input)\n        {\n            if (_chosen[i] || i == _current) { ++i; continue; }\n            // Roll a dice with k faces\n            static if (is(UniformRNG == void))\n            {\n                auto chooseMe = _uniformIndex(k, rndGen) == 0;\n            }\n            else\n            {\n                auto chooseMe = _uniformIndex(k, _rng) == 0;\n            }\n            assert(k > 1 || chooseMe);\n            if (chooseMe)\n            {\n                _chosen[_current] = true;\n                _current = i;\n                ++_alreadyChosen;\n                return;\n            }\n            --k;\n            ++i;\n        }\n    }\n\n    static if (isForwardRange!UniformRNG)\n    {\n        @property typeof(this) save()\n        {\n            auto ret = this;\n            ret._input = _input.save;\n            ret._rng = _rng.save;\n            return ret;\n        }\n    }\n\n    @property bool empty() { return _isEmpty; }\n}\n\n/// Ditto\nauto randomCover(Range, UniformRNG)(Range r, auto ref UniformRNG rng)\nif (isRandomAccessRange!Range && isUniformRNG!UniformRNG)\n{\n    return RandomCover!(Range, UniformRNG)(r, rng);\n}\n\n/// Ditto\nauto randomCover(Range)(Range r)\nif (isRandomAccessRange!Range)\n{\n    return RandomCover!(Range, void)(r);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota;\n    auto rnd = MinstdRand0(42);\n\n    version (X86_64) // Issue 15147\n    assert(10.iota.randomCover(rnd).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));\n}\n\n@safe unittest // cover RandomCoverChoices postblit for heap storage\n{\n    import std.array : array;\n    import std.range : iota;\n    auto a = 1337.iota.randomCover().array;\n    assert(a.length == 1337);\n}\n\n@nogc nothrow pure @safe unittest\n{\n    // Issue 14001 - Optionally @nogc std.random.randomCover\n    auto rng = Xorshift(123_456_789);\n    int[5] sa = [1, 2, 3, 4, 5];\n    auto r = randomCover(sa[], rng);\n    assert(!r.empty);\n    const x = r.front;\n    r.popFront();\n    assert(!r.empty);\n    const y = r.front;\n    assert(x != y);\n}\n\n@safe unittest\n{\n    import std.algorithm;\n    import std.conv;\n    int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ];\n    int[] c;\n    static foreach (UniformRNG; std.meta.AliasSeq!(void, PseudoRngTypes))\n    {{\n        static if (is(UniformRNG == void))\n        {\n            auto rc = randomCover(a);\n            static assert(isInputRange!(typeof(rc)));\n            static assert(!isForwardRange!(typeof(rc)));\n        }\n        else\n        {\n            auto rng = UniformRNG(123_456_789);\n            auto rc = randomCover(a, rng);\n            static assert(isForwardRange!(typeof(rc)));\n            // check for constructor passed a value-type RNG\n            auto rc2 = RandomCover!(int[], UniformRNG)(a, UniformRNG(987_654_321));\n            static assert(isForwardRange!(typeof(rc2)));\n            auto rcEmpty = randomCover(c, rng);\n            assert(rcEmpty.length == 0);\n        }\n\n        int[] b = new int[9];\n        uint i;\n        foreach (e; rc)\n        {\n            //writeln(e);\n            b[i++] = e;\n        }\n        sort(b);\n        assert(a == b, text(b));\n    }}\n}\n\n@safe unittest\n{\n    // Bugzilla 12589\n    int[] r = [];\n    auto rc = randomCover(r);\n    assert(rc.length == 0);\n    assert(rc.empty);\n\n    // Bugzilla 16724\n    import std.range : iota;\n    auto range = iota(10);\n    auto randy = range.randomCover;\n\n    for (int i=1; i <= range.length; i++)\n    {\n        randy.popFront;\n        assert(randy.length == range.length - i);\n    }\n}\n\n// RandomSample\n/**\nSelects a random subsample out of `r`, containing exactly `n`\nelements. The order of elements is the same as in the original\nrange. The total length of `r` must be known. If `total` is\npassed in, the total number of sample is considered to be $(D\ntotal). Otherwise, `RandomSample` uses `r.length`.\n\nParams:\n    r = range to sample from\n    n = number of elements to include in the sample;\n        must be less than or equal to the total number\n        of elements in `r` and/or the parameter\n        `total` (if provided)\n    total = (semi-optional) number of elements of `r`\n            from which to select the sample (counting from\n            the beginning); must be less than or equal to\n            the total number of elements in `r` itself.\n            May be omitted if `r` has the `.length`\n            property and the sample is to be drawn from\n            all elements of `r`.\n    rng = (optional) random number generator to use;\n          if not specified, defaults to `rndGen`\n\nReturns:\n    Range whose elements consist of a randomly selected subset of\n    the elements of `r`, in the same order as these elements\n    appear in `r` itself.  Will be a forward range if both `r`\n    and `rng` are forward ranges, an input range otherwise.\n\n`RandomSample` implements Jeffrey Scott Vitter's Algorithm D\n(see Vitter $(HTTP dx.doi.org/10.1145/358105.893, 1984), $(HTTP\ndx.doi.org/10.1145/23002.23003, 1987)), which selects a sample\nof size `n` in O(n) steps and requiring O(n) random variates,\nregardless of the size of the data being sampled.  The exception\nto this is if traversing k elements on the input range is itself\nan O(k) operation (e.g. when sampling lines from an input file),\nin which case the sampling calculation will inevitably be of\nO(total).\n\nRandomSample will throw an exception if `total` is verifiably\nless than the total number of elements available in the input,\nor if $(D n > total).\n\nIf no random number generator is passed to `randomSample`, the\nthread-global RNG rndGen will be used internally.\n*/\nstruct RandomSample(Range, UniformRNG = void)\nif (isInputRange!Range && (isUniformRNG!UniformRNG || is(UniformRNG == void)))\n{\n    private size_t _available, _toSelect;\n    private enum ushort _alphaInverse = 13; // Vitter's recommended value.\n    private double _Vprime;\n    private Range _input;\n    private size_t _index;\n    private enum Skip { None, A, D }\n    private Skip _skip = Skip.None;\n\n    // If we're using the default thread-local random number generator then\n    // we shouldn't store a copy of it here.  UniformRNG == void is a sentinel\n    // for this.  If we're using a user-specified generator then we have no\n    // choice but to store a copy.\n    static if (is(UniformRNG == void))\n    {\n        static if (hasLength!Range)\n        {\n            this(Range input, size_t howMany)\n            {\n                _input = input;\n                initialize(howMany, input.length);\n            }\n        }\n\n        this(Range input, size_t howMany, size_t total)\n        {\n            _input = input;\n            initialize(howMany, total);\n        }\n    }\n    else\n    {\n        UniformRNG _rng;\n\n        static if (hasLength!Range)\n        {\n            this(Range input, size_t howMany, ref UniformRNG rng)\n            {\n                _rng = rng;\n                _input = input;\n                initialize(howMany, input.length);\n            }\n\n            this(Range input, size_t howMany, UniformRNG rng)\n            {\n                this(input, howMany, rng);\n            }\n        }\n\n        this(Range input, size_t howMany, size_t total, ref UniformRNG rng)\n        {\n            _rng = rng;\n            _input = input;\n            initialize(howMany, total);\n        }\n\n        this(Range input, size_t howMany, size_t total, UniformRNG rng)\n        {\n            this(input, howMany, total, rng);\n        }\n    }\n\n    private void initialize(size_t howMany, size_t total)\n    {\n        import std.conv : text;\n        import std.exception : enforce;\n        _available = total;\n        _toSelect = howMany;\n        enforce(_toSelect <= _available,\n                text(\"RandomSample: cannot sample \", _toSelect,\n                     \" items when only \", _available, \" are available\"));\n        static if (hasLength!Range)\n        {\n            enforce(_available <= _input.length,\n                    text(\"RandomSample: specified \", _available,\n                         \" items as available when input contains only \",\n                         _input.length));\n        }\n    }\n\n    private void initializeFront()\n    {\n        assert(_skip == Skip.None);\n        // We can save ourselves a random variate by checking right\n        // at the beginning if we should use Algorithm A.\n        if ((_alphaInverse * _toSelect) > _available)\n        {\n            _skip = Skip.A;\n        }\n        else\n        {\n            _skip = Skip.D;\n            _Vprime = newVprime(_toSelect);\n        }\n        prime();\n    }\n\n/**\n   Range primitives.\n*/\n    @property bool empty() const\n    {\n        return _toSelect == 0;\n    }\n\n/// Ditto\n    @property auto ref front()\n    {\n        assert(!empty);\n        // The first sample point must be determined here to avoid\n        // having it always correspond to the first element of the\n        // input.  The rest of the sample points are determined each\n        // time we call popFront().\n        if (_skip == Skip.None)\n        {\n            initializeFront();\n        }\n        return _input.front;\n    }\n\n/// Ditto\n    void popFront()\n    {\n        // First we need to check if the sample has\n        // been initialized in the first place.\n        if (_skip == Skip.None)\n        {\n            initializeFront();\n        }\n\n        _input.popFront();\n        --_available;\n        --_toSelect;\n        ++_index;\n        prime();\n    }\n\n/// Ditto\n    static if (isForwardRange!Range && isForwardRange!UniformRNG)\n    {\n        @property typeof(this) save()\n        {\n            auto ret = this;\n            ret._input = _input.save;\n            ret._rng = _rng.save;\n            return ret;\n        }\n    }\n\n/// Ditto\n    @property size_t length()\n    {\n        return _toSelect;\n    }\n\n/**\nReturns the index of the visited record.\n */\n    @property size_t index()\n    {\n        if (_skip == Skip.None)\n        {\n            initializeFront();\n        }\n        return _index;\n    }\n\n    private size_t skip()\n    {\n        assert(_skip != Skip.None);\n\n        // Step D1: if the number of points still to select is greater\n        // than a certain proportion of the remaining data points, i.e.\n        // if n >= alpha * N where alpha = 1/13, we carry out the\n        // sampling with Algorithm A.\n        if (_skip == Skip.A)\n        {\n            return skipA();\n        }\n        else if ((_alphaInverse * _toSelect) > _available)\n        {\n            // We shouldn't get here unless the current selected\n            // algorithm is D.\n            assert(_skip == Skip.D);\n            _skip = Skip.A;\n            return skipA();\n        }\n        else\n        {\n            assert(_skip == Skip.D);\n            return skipD();\n        }\n    }\n\n/*\nVitter's Algorithm A, used when the ratio of needed sample values\nto remaining data values is sufficiently large.\n*/\n    private size_t skipA()\n    {\n        size_t s;\n        double v, quot, top;\n\n        if (_toSelect == 1)\n        {\n            static if (is(UniformRNG == void))\n            {\n                s = uniform(0, _available);\n            }\n            else\n            {\n                s = uniform(0, _available, _rng);\n            }\n        }\n        else\n        {\n            v = 0;\n            top = _available - _toSelect;\n            quot = top / _available;\n\n            static if (is(UniformRNG == void))\n            {\n                v = uniform!\"()\"(0.0, 1.0);\n            }\n            else\n            {\n                v = uniform!\"()\"(0.0, 1.0, _rng);\n            }\n\n            while (quot > v)\n            {\n                ++s;\n                quot *= (top - s) / (_available - s);\n            }\n        }\n\n        return s;\n    }\n\n/*\nRandomly reset the value of _Vprime.\n*/\n    private double newVprime(size_t remaining)\n    {\n        static if (is(UniformRNG == void))\n        {\n            double r = uniform!\"()\"(0.0, 1.0);\n        }\n        else\n        {\n            double r = uniform!\"()\"(0.0, 1.0, _rng);\n        }\n\n        return r ^^ (1.0 / remaining);\n    }\n\n/*\nVitter's Algorithm D.  For an extensive description of the algorithm\nand its rationale, see:\n\n  * Vitter, J.S. (1984), \"Faster methods for random sampling\",\n    Commun. ACM 27(7): 703--718\n\n  * Vitter, J.S. (1987) \"An efficient algorithm for sequential random\n    sampling\", ACM Trans. Math. Softw. 13(1): 58-67.\n\nVariable names are chosen to match those in Vitter's paper.\n*/\n    private size_t skipD()\n    {\n        import std.math : isNaN, trunc;\n        // Confirm that the check in Step D1 is valid and we\n        // haven't been sent here by mistake\n        assert((_alphaInverse * _toSelect) <= _available);\n\n        // Now it's safe to use the standard Algorithm D mechanism.\n        if (_toSelect > 1)\n        {\n            size_t s;\n            size_t qu1 = 1 + _available - _toSelect;\n            double x, y1;\n\n            assert(!_Vprime.isNaN());\n\n            while (true)\n            {\n                // Step D2: set values of x and u.\n                while (1)\n                {\n                    x = _available * (1-_Vprime);\n                    s = cast(size_t) trunc(x);\n                    if (s < qu1)\n                        break;\n                    _Vprime = newVprime(_toSelect);\n                }\n\n                static if (is(UniformRNG == void))\n                {\n                    double u = uniform!\"()\"(0.0, 1.0);\n                }\n                else\n                {\n                    double u = uniform!\"()\"(0.0, 1.0, _rng);\n                }\n\n                y1 = (u * (cast(double) _available) / qu1) ^^ (1.0/(_toSelect - 1));\n\n                _Vprime = y1 * ((-x/_available)+1.0) * ( qu1/( (cast(double) qu1) - s ) );\n\n                // Step D3: if _Vprime <= 1.0 our work is done and we return S.\n                // Otherwise ...\n                if (_Vprime > 1.0)\n                {\n                    size_t top = _available - 1, limit;\n                    double y2 = 1.0, bottom;\n\n                    if (_toSelect > (s+1))\n                    {\n                        bottom = _available - _toSelect;\n                        limit = _available - s;\n                    }\n                    else\n                    {\n                        bottom = _available - (s+1);\n                        limit = qu1;\n                    }\n\n                    foreach (size_t t; limit .. _available)\n                    {\n                        y2 *= top/bottom;\n                        top--;\n                        bottom--;\n                    }\n\n                    // Step D4: decide whether or not to accept the current value of S.\n                    if (_available/(_available-x) < y1 * (y2 ^^ (1.0/(_toSelect-1))))\n                    {\n                        // If it's not acceptable, we generate a new value of _Vprime\n                        // and go back to the start of the for (;;) loop.\n                        _Vprime = newVprime(_toSelect);\n                    }\n                    else\n                    {\n                        // If it's acceptable we generate a new value of _Vprime\n                        // based on the remaining number of sample points needed,\n                        // and return S.\n                        _Vprime = newVprime(_toSelect-1);\n                        return s;\n                    }\n                }\n                else\n                {\n                    // Return if condition D3 satisfied.\n                    return s;\n                }\n            }\n        }\n        else\n        {\n            // If only one sample point remains to be taken ...\n            return cast(size_t) trunc(_available * _Vprime);\n        }\n    }\n\n    private void prime()\n    {\n        if (empty)\n        {\n            return;\n        }\n        assert(_available && _available >= _toSelect);\n        immutable size_t s = skip();\n        assert(s + _toSelect <= _available);\n        static if (hasLength!Range)\n        {\n            assert(s + _toSelect <= _input.length);\n        }\n        assert(!_input.empty);\n        _input.popFrontExactly(s);\n        _index += s;\n        _available -= s;\n        assert(_available > 0);\n    }\n}\n\n/// Ditto\nauto randomSample(Range)(Range r, size_t n, size_t total)\nif (isInputRange!Range)\n{\n    return RandomSample!(Range, void)(r, n, total);\n}\n\n/// Ditto\nauto randomSample(Range)(Range r, size_t n)\nif (isInputRange!Range && hasLength!Range)\n{\n    return RandomSample!(Range, void)(r, n, r.length);\n}\n\n/// Ditto\nauto randomSample(Range, UniformRNG)(Range r, size_t n, size_t total, auto ref UniformRNG rng)\nif (isInputRange!Range && isUniformRNG!UniformRNG)\n{\n    return RandomSample!(Range, UniformRNG)(r, n, total, rng);\n}\n\n/// Ditto\nauto randomSample(Range, UniformRNG)(Range r, size_t n, auto ref UniformRNG rng)\nif (isInputRange!Range && hasLength!Range && isUniformRNG!UniformRNG)\n{\n    return RandomSample!(Range, UniformRNG)(r, n, r.length, rng);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota;\n    auto rnd = MinstdRand0(42);\n    assert(10.iota.randomSample(3, rnd).equal([7, 8, 9]));\n}\n\n@system unittest\n{\n    // @system because it takes the address of a local\n    import std.conv : text;\n    import std.exception;\n    import std.range;\n    // For test purposes, an infinite input range\n    struct TestInputRange\n    {\n        private auto r = recurrence!\"a[n-1] + 1\"(0);\n        bool empty() @property const pure nothrow { return r.empty; }\n        auto front() @property pure nothrow { return r.front; }\n        void popFront() pure nothrow { r.popFront(); }\n    }\n    static assert(isInputRange!TestInputRange);\n    static assert(!isForwardRange!TestInputRange);\n\n    int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];\n\n    foreach (UniformRNG; PseudoRngTypes)\n    {\n        auto rng = UniformRNG(1234);\n        /* First test the most general case: randomSample of input range, with and\n         * without a specified random number generator.\n         */\n        static assert(isInputRange!(typeof(randomSample(TestInputRange(), 5, 10))));\n        static assert(isInputRange!(typeof(randomSample(TestInputRange(), 5, 10, rng))));\n        static assert(!isForwardRange!(typeof(randomSample(TestInputRange(), 5, 10))));\n        static assert(!isForwardRange!(typeof(randomSample(TestInputRange(), 5, 10, rng))));\n        // test case with range initialized by direct call to struct\n        {\n            auto sample =\n                RandomSample!(TestInputRange, UniformRNG)\n                             (TestInputRange(), 5, 10, UniformRNG(987_654_321));\n            static assert(isInputRange!(typeof(sample)));\n            static assert(!isForwardRange!(typeof(sample)));\n        }\n\n        /* Now test the case of an input range with length.  We ignore the cases\n         * already covered by the previous tests.\n         */\n        static assert(isInputRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5))));\n        static assert(isInputRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5, rng))));\n        static assert(!isForwardRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5))));\n        static assert(!isForwardRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5, rng))));\n        // test case with range initialized by direct call to struct\n        {\n            auto sample =\n                RandomSample!(typeof(TestInputRange().takeExactly(10)), UniformRNG)\n                             (TestInputRange().takeExactly(10), 5, 10, UniformRNG(654_321_987));\n            static assert(isInputRange!(typeof(sample)));\n            static assert(!isForwardRange!(typeof(sample)));\n        }\n\n        // Now test the case of providing a forward range as input.\n        static assert(!isForwardRange!(typeof(randomSample(a, 5))));\n        static if (isForwardRange!UniformRNG)\n        {\n            static assert(isForwardRange!(typeof(randomSample(a, 5, rng))));\n            // ... and test with range initialized directly\n            {\n                auto sample =\n                    RandomSample!(int[], UniformRNG)\n                                 (a, 5, UniformRNG(321_987_654));\n                static assert(isForwardRange!(typeof(sample)));\n            }\n        }\n        else\n        {\n            static assert(isInputRange!(typeof(randomSample(a, 5, rng))));\n            static assert(!isForwardRange!(typeof(randomSample(a, 5, rng))));\n            // ... and test with range initialized directly\n            {\n                auto sample =\n                    RandomSample!(int[], UniformRNG)\n                                 (a, 5, UniformRNG(789_123_456));\n                static assert(isInputRange!(typeof(sample)));\n                static assert(!isForwardRange!(typeof(sample)));\n            }\n        }\n\n        /* Check that randomSample will throw an error if we claim more\n         * items are available than there actually are, or if we try to\n         * sample more items than are available. */\n        assert(collectExceptionMsg(\n            randomSample(a, 5, 15)\n        ) == \"RandomSample: specified 15 items as available when input contains only 10\");\n        assert(collectExceptionMsg(\n            randomSample(a, 15)\n        ) == \"RandomSample: cannot sample 15 items when only 10 are available\");\n        assert(collectExceptionMsg(\n            randomSample(a, 9, 8)\n        ) == \"RandomSample: cannot sample 9 items when only 8 are available\");\n        assert(collectExceptionMsg(\n            randomSample(TestInputRange(), 12, 11)\n        ) == \"RandomSample: cannot sample 12 items when only 11 are available\");\n\n        /* Check that sampling algorithm never accidentally overruns the end of\n         * the input range.  If input is an InputRange without .length, this\n         * relies on the user specifying the total number of available items\n         * correctly.\n         */\n        {\n            uint i = 0;\n            foreach (e; randomSample(a, a.length))\n            {\n                assert(e == i);\n                ++i;\n            }\n            assert(i == a.length);\n\n            i = 0;\n            foreach (e; randomSample(TestInputRange(), 17, 17))\n            {\n                assert(e == i);\n                ++i;\n            }\n            assert(i == 17);\n        }\n\n\n        // Check length properties of random samples.\n        assert(randomSample(a, 5).length == 5);\n        assert(randomSample(a, 5, 10).length == 5);\n        assert(randomSample(a, 5, rng).length == 5);\n        assert(randomSample(a, 5, 10, rng).length == 5);\n        assert(randomSample(TestInputRange(), 5, 10).length == 5);\n        assert(randomSample(TestInputRange(), 5, 10, rng).length == 5);\n\n        // ... and emptiness!\n        assert(randomSample(a, 0).empty);\n        assert(randomSample(a, 0, 5).empty);\n        assert(randomSample(a, 0, rng).empty);\n        assert(randomSample(a, 0, 5, rng).empty);\n        assert(randomSample(TestInputRange(), 0, 10).empty);\n        assert(randomSample(TestInputRange(), 0, 10, rng).empty);\n\n        /* Test that the (lazy) evaluation of random samples works correctly.\n         *\n         * We cover 2 different cases: a sample where the ratio of sample points\n         * to total points is greater than the threshold for using Algorithm, and\n         * one where the ratio is small enough (< 1/13) for Algorithm D to be used.\n         *\n         * For each, we also cover the case with and without a specified RNG.\n         */\n        {\n            // Small sample/source ratio, no specified RNG.\n            uint i = 0;\n            foreach (e; randomSample(randomCover(a), 5))\n            {\n                ++i;\n            }\n            assert(i == 5);\n\n            // Small sample/source ratio, specified RNG.\n            i = 0;\n            foreach (e; randomSample(randomCover(a), 5, rng))\n            {\n                ++i;\n            }\n            assert(i == 5);\n\n            // Large sample/source ratio, no specified RNG.\n            i = 0;\n            foreach (e; randomSample(TestInputRange(), 123, 123_456))\n            {\n                ++i;\n            }\n            assert(i == 123);\n\n            // Large sample/source ratio, specified RNG.\n            i = 0;\n            foreach (e; randomSample(TestInputRange(), 123, 123_456, rng))\n            {\n                ++i;\n            }\n            assert(i == 123);\n\n            /* Sample/source ratio large enough to start with Algorithm D,\n             * small enough to switch to Algorithm A.\n             */\n            i = 0;\n            foreach (e; randomSample(TestInputRange(), 10, 131))\n            {\n                ++i;\n            }\n            assert(i == 10);\n        }\n\n        // Test that the .index property works correctly\n        {\n            auto sample1 = randomSample(TestInputRange(), 654, 654_321);\n            for (; !sample1.empty; sample1.popFront())\n            {\n                assert(sample1.front == sample1.index);\n            }\n\n            auto sample2 = randomSample(TestInputRange(), 654, 654_321, rng);\n            for (; !sample2.empty; sample2.popFront())\n            {\n                assert(sample2.front == sample2.index);\n            }\n\n            /* Check that it also works if .index is called before .front.\n             * See: http://d.puremagic.com/issues/show_bug.cgi?id=10322\n             */\n            auto sample3 = randomSample(TestInputRange(), 654, 654_321);\n            for (; !sample3.empty; sample3.popFront())\n            {\n                assert(sample3.index == sample3.front);\n            }\n\n            auto sample4 = randomSample(TestInputRange(), 654, 654_321, rng);\n            for (; !sample4.empty; sample4.popFront())\n            {\n                assert(sample4.index == sample4.front);\n            }\n        }\n\n        /* Test behaviour if .popFront() is called before sample is read.\n         * This is a rough-and-ready check that the statistical properties\n         * are in the ballpark -- not a proper validation of statistical\n         * quality!  This incidentally also checks for reference-type\n         * initialization bugs, as the foreach () loop will operate on a\n         * copy of the popFronted (and hence initialized) sample.\n         */\n        {\n            size_t count0, count1, count99;\n            foreach (_; 0 .. 100_000)\n            {\n                auto sample = randomSample(iota(100), 5, &rng);\n                sample.popFront();\n                foreach (s; sample)\n                {\n                    if (s == 0)\n                    {\n                        ++count0;\n                    }\n                    else if (s == 1)\n                    {\n                        ++count1;\n                    }\n                    else if (s == 99)\n                    {\n                        ++count99;\n                    }\n                }\n            }\n            /* Statistical assumptions here: this is a sequential sampling process\n             * so (i) 0 can only be the first sample point, so _can't_ be in the\n             * remainder of the sample after .popFront() is called. (ii) By similar\n             * token, 1 can only be in the remainder if it's the 2nd point of the\n             * whole sample, and hence if 0 was the first; probability of 0 being\n             * first and 1 second is 5/100 * 4/99 (thank you, Algorithm S:-) and\n             * so the mean count of 1 should be about 202.  Finally, 99 can only\n             * be the _last_ sample point to be picked, so its probability of\n             * inclusion should be independent of the .popFront() and it should\n             * occur with frequency 5/100, hence its count should be about 5000.\n             * Unfortunately we have to set quite a high tolerance because with\n             * sample size small enough for unittests to run in reasonable time,\n             * the variance can be quite high.\n             */\n            assert(count0 == 0);\n            assert(count1 < 300, text(\"1: \", count1, \" > 300.\"));\n            assert(4_700 < count99, text(\"99: \", count99, \" < 4700.\"));\n            assert(count99 < 5_300, text(\"99: \", count99, \" > 5300.\"));\n        }\n\n        /* Odd corner-cases: RandomSample has 2 constructors that are not called\n         * by the randomSample() helper functions, but that can be used if the\n         * constructor is called directly.  These cover the case of the user\n         * specifying input but not input length.\n         */\n        {\n            auto input1 = TestInputRange().takeExactly(456_789);\n            static assert(hasLength!(typeof(input1)));\n            auto sample1 = RandomSample!(typeof(input1), void)(input1, 789);\n            static assert(isInputRange!(typeof(sample1)));\n            static assert(!isForwardRange!(typeof(sample1)));\n            assert(sample1.length == 789);\n            assert(sample1._available == 456_789);\n            uint i = 0;\n            for (; !sample1.empty; sample1.popFront())\n            {\n                assert(sample1.front == sample1.index);\n                ++i;\n            }\n            assert(i == 789);\n\n            auto input2 = TestInputRange().takeExactly(456_789);\n            static assert(hasLength!(typeof(input2)));\n            auto sample2 = RandomSample!(typeof(input2), typeof(rng))(input2, 789, rng);\n            static assert(isInputRange!(typeof(sample2)));\n            static assert(!isForwardRange!(typeof(sample2)));\n            assert(sample2.length == 789);\n            assert(sample2._available == 456_789);\n            i = 0;\n            for (; !sample2.empty; sample2.popFront())\n            {\n                assert(sample2.front == sample2.index);\n                ++i;\n            }\n            assert(i == 789);\n        }\n\n        /* Test that the save property works where input is a forward range,\n         * and RandomSample is using a (forward range) random number generator\n         * that is not rndGen.\n         */\n        static if (isForwardRange!UniformRNG)\n        {\n            auto sample1 = randomSample(a, 5, rng);\n            auto sample2 = sample1.save;\n            assert(sample1.array() == sample2.array());\n        }\n\n        // Bugzilla 8314\n        {\n            auto sample(RandomGen)(uint seed) { return randomSample(a, 1, RandomGen(seed)).front; }\n\n            // Start from 1 because not all RNGs accept 0 as seed.\n            immutable fst = sample!UniformRNG(1);\n            uint n = 1;\n            while (sample!UniformRNG(++n) == fst && n < n.max) {}\n            assert(n < n.max);\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/range/interfaces.d",
    "content": "/**\nThis module is a submodule of $(MREF std, range).\n\nThe main $(MREF std, range) module provides template-based tools for working with\nranges, but sometimes an object-based interface for ranges is needed, such as\nwhen runtime polymorphism is required. For this purpose, this submodule\nprovides a number of object and `interface` definitions that can be used to\nwrap around range objects created by the $(MREF std, range) templates.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE ,\n    $(TR $(TD $(LREF InputRange))\n        $(TD Wrapper for input ranges.\n    ))\n    $(TR $(TD $(LREF InputAssignable))\n        $(TD Wrapper for input ranges with assignable elements.\n    ))\n    $(TR $(TD $(LREF ForwardRange))\n        $(TD Wrapper for forward ranges.\n    ))\n    $(TR $(TD $(LREF ForwardAssignable))\n        $(TD Wrapper for forward ranges with assignable elements.\n    ))\n    $(TR $(TD $(LREF BidirectionalRange))\n        $(TD Wrapper for bidirectional ranges.\n    ))\n    $(TR $(TD $(LREF BidirectionalAssignable))\n        $(TD Wrapper for bidirectional ranges with assignable elements.\n    ))\n    $(TR $(TD $(LREF RandomAccessFinite))\n        $(TD Wrapper for finite random-access ranges.\n    ))\n    $(TR $(TD $(LREF RandomAccessAssignable))\n        $(TD Wrapper for finite random-access ranges with assignable elements.\n    ))\n    $(TR $(TD $(LREF RandomAccessInfinite))\n        $(TD Wrapper for infinite random-access ranges.\n    ))\n    $(TR $(TD $(LREF OutputRange))\n        $(TD Wrapper for output ranges.\n    ))\n    $(TR $(TD $(LREF OutputRangeObject))\n        $(TD Class that implements the `OutputRange` interface and wraps the\n        `put` methods in virtual functions.\n    ))\n    $(TR $(TD $(LREF outputRangeObject))\n        $(TD Convenience function for creating an `OutputRangeObject` with a base\n        range of type R that accepts types E.\n    ))\n    $(TR $(TD $(LREF InputRangeObject))\n        $(TD Class that implements the `InputRange` interface and wraps the\n        input range methods in virtual functions.\n    ))\n    $(TR $(TD $(LREF inputRangeObject))\n        $(TD Convenience function for creating an `InputRangeObject`\n        of the proper type.\n    ))\n    $(TR $(TD $(LREF MostDerivedInputRange))\n        $(TD Returns the interface type that best matches the range.\n    ))\n)\n\n\nSource: $(PHOBOSSRC std/range/interfaces.d)\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu), David Simcha, and\n         $(HTTP jmdavisprog.com, Jonathan M Davis). Credit for some of the ideas\n         in building this module goes to\n         $(HTTP fantascienza.net/leonardo/so/, Leonardo Maffi).\n*/\nmodule std.range.interfaces;\n\nimport std.meta;\nimport std.range.primitives;\nimport std.traits;\n\n/**These interfaces are intended to provide virtual function-based wrappers\n * around input ranges with element type E.  This is useful where a well-defined\n * binary interface is required, such as when a DLL function or virtual function\n * needs to accept a generic range as a parameter. Note that\n * $(REF_ALTTEXT isInputRange, isInputRange, std, range, primitives)\n * and friends check for conformance to structural interfaces\n * not for implementation of these `interface` types.\n *\n * Limitations:\n *\n * These interfaces are not capable of forwarding `ref` access to elements.\n *\n * Infiniteness of the wrapped range is not propagated.\n *\n * Length is not propagated in the case of non-random access ranges.\n *\n * See_Also:\n * $(LREF inputRangeObject)\n */\ninterface InputRange(E) {\n    ///\n    @property E front();\n\n    ///\n    E moveFront();\n\n    ///\n    void popFront();\n\n    ///\n    @property bool empty();\n\n    /* Measurements of the benefits of using opApply instead of range primitives\n     * for foreach, using timings for iterating over an iota(100_000_000) range\n     * with an empty loop body, using the same hardware in each case:\n     *\n     * Bare Iota struct, range primitives:  278 milliseconds\n     * InputRangeObject, opApply:           436 milliseconds  (1.57x penalty)\n     * InputRangeObject, range primitives:  877 milliseconds  (3.15x penalty)\n     */\n\n    /**`foreach` iteration uses opApply, since one delegate call per loop\n     * iteration is faster than three virtual function calls.\n     */\n    int opApply(scope int delegate(E));\n\n    /// Ditto\n    int opApply(scope int delegate(size_t, E));\n\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.iteration : map;\n    import std.range : iota;\n\n    void useRange(InputRange!int range) {\n        // Function body.\n    }\n\n    // Create a range type.\n    auto squares = map!\"a * a\"(iota(10));\n\n    // Wrap it in an interface.\n    auto squaresWrapped = inputRangeObject(squares);\n\n    // Use it.\n    useRange(squaresWrapped);\n}\n\n/**Interface for a forward range of type `E`.*/\ninterface ForwardRange(E) : InputRange!E {\n    ///\n    @property ForwardRange!E save();\n}\n\n/**Interface for a bidirectional range of type `E`.*/\ninterface BidirectionalRange(E) : ForwardRange!(E) {\n    ///\n    @property BidirectionalRange!E save();\n\n    ///\n    @property E back();\n\n    ///\n    E moveBack();\n\n    ///\n    void popBack();\n}\n\n/**Interface for a finite random access range of type `E`.*/\ninterface RandomAccessFinite(E) : BidirectionalRange!(E) {\n    ///\n    @property RandomAccessFinite!E save();\n\n    ///\n    E opIndex(size_t);\n\n    ///\n    E moveAt(size_t);\n\n    ///\n    @property size_t length();\n\n    ///\n    alias opDollar = length;\n\n    // Can't support slicing until issues with requiring slicing for all\n    // finite random access ranges are fully resolved.\n    version (none)\n    {\n        ///\n        RandomAccessFinite!E opSlice(size_t, size_t);\n    }\n}\n\n/**Interface for an infinite random access range of type `E`.*/\ninterface RandomAccessInfinite(E) : ForwardRange!E {\n    ///\n    E moveAt(size_t);\n\n    ///\n    @property RandomAccessInfinite!E save();\n\n    ///\n    E opIndex(size_t);\n}\n\n/**Adds assignable elements to InputRange.*/\ninterface InputAssignable(E) : InputRange!E {\n    ///\n    @property void front(E newVal);\n\n    alias front = InputRange!E.front; // overload base interface method\n}\n\n@safe unittest\n{\n    static assert(isInputRange!(InputAssignable!int));\n}\n\n/**Adds assignable elements to ForwardRange.*/\ninterface ForwardAssignable(E) : InputAssignable!E, ForwardRange!E {\n    ///\n    @property ForwardAssignable!E save();\n}\n\n/**Adds assignable elements to BidirectionalRange.*/\ninterface BidirectionalAssignable(E) : ForwardAssignable!E, BidirectionalRange!E {\n    ///\n    @property BidirectionalAssignable!E save();\n\n    ///\n    @property void back(E newVal);\n}\n\n/**Adds assignable elements to RandomAccessFinite.*/\ninterface RandomFiniteAssignable(E) : RandomAccessFinite!E, BidirectionalAssignable!E {\n    ///\n    @property RandomFiniteAssignable!E save();\n\n    ///\n    void opIndexAssign(E val, size_t index);\n}\n\n/**Interface for an output range of type `E`.  Usage is similar to the\n * `InputRange` interface and descendants.*/\ninterface OutputRange(E) {\n    ///\n    void put(E);\n}\n\n@safe unittest\n{\n    // 6973\n    static assert(isOutputRange!(OutputRange!int, int));\n}\n\n\n// CTFE function that generates mixin code for one put() method for each\n// type E.\nprivate string putMethods(E...)()\n{\n    import std.conv : to;\n\n    string ret;\n\n    foreach (ti, Unused; E)\n    {\n        ret ~= \"void put(E[\" ~ to!string(ti) ~ \"] e) { .put(_range, e); }\";\n    }\n\n    return ret;\n}\n\n/**Implements the `OutputRange` interface for all types E and wraps the\n * `put` method for each type `E` in a virtual function.\n */\nclass OutputRangeObject(R, E...) : staticMap!(OutputRange, E) {\n    // @BUG 4689:  There should be constraints on this template class, but\n    // DMD won't let me put them in.\n    private R _range;\n\n    ///\n    this(R range) {\n        this._range = range;\n    }\n\n    mixin(putMethods!E());\n}\n\n\n/**Returns the interface type that best matches `R`.*/\ntemplate MostDerivedInputRange(R)\nif (isInputRange!(Unqual!R))\n{\n    private alias E = ElementType!R;\n\n    static if (isRandomAccessRange!R)\n    {\n        static if (isInfinite!R)\n        {\n            alias MostDerivedInputRange = RandomAccessInfinite!E;\n        }\n        else static if (hasAssignableElements!R)\n        {\n            alias MostDerivedInputRange = RandomFiniteAssignable!E;\n        }\n        else\n        {\n            alias MostDerivedInputRange = RandomAccessFinite!E;\n        }\n    }\n    else static if (isBidirectionalRange!R)\n    {\n        static if (hasAssignableElements!R)\n        {\n            alias MostDerivedInputRange = BidirectionalAssignable!E;\n        }\n        else\n        {\n            alias MostDerivedInputRange = BidirectionalRange!E;\n        }\n    }\n    else static if (isForwardRange!R)\n    {\n        static if (hasAssignableElements!R)\n        {\n            alias MostDerivedInputRange = ForwardAssignable!E;\n        }\n        else\n        {\n            alias MostDerivedInputRange = ForwardRange!E;\n        }\n    }\n    else\n    {\n        static if (hasAssignableElements!R)\n        {\n            alias MostDerivedInputRange = InputAssignable!E;\n        }\n        else\n        {\n            alias MostDerivedInputRange = InputRange!E;\n        }\n    }\n}\n\n/**Implements the most derived interface that `R` works with and wraps\n * all relevant range primitives in virtual functions.  If `R` is already\n * derived from the `InputRange` interface, aliases itself away.\n */\ntemplate InputRangeObject(R)\nif (isInputRange!(Unqual!R))\n{\n    static if (is(R : InputRange!(ElementType!R)))\n    {\n        alias InputRangeObject = R;\n    }\n    else static if (!is(Unqual!R == R))\n    {\n        alias InputRangeObject = InputRangeObject!(Unqual!R);\n    }\n    else\n    {\n\n        ///\n        class InputRangeObject : MostDerivedInputRange!(R) {\n            private R _range;\n            private alias E = ElementType!R;\n\n            this(R range) {\n                this._range = range;\n            }\n\n            @property E front() { return _range.front; }\n\n            E moveFront() {\n                return _range.moveFront();\n            }\n\n            void popFront() { _range.popFront(); }\n            @property bool empty() { return _range.empty; }\n\n            static if (isForwardRange!R)\n            {\n                @property typeof(this) save() {\n                    return new typeof(this)(_range.save);\n                }\n            }\n\n            static if (hasAssignableElements!R)\n            {\n                @property void front(E newVal) {\n                    _range.front = newVal;\n                }\n            }\n\n            static if (isBidirectionalRange!R)\n            {\n                @property E back() { return _range.back; }\n\n                E moveBack() {\n                    return _range.moveBack();\n                }\n\n                void popBack() { return _range.popBack(); }\n\n                static if (hasAssignableElements!R)\n                {\n                    @property void back(E newVal) {\n                        _range.back = newVal;\n                    }\n                }\n            }\n\n            static if (isRandomAccessRange!R)\n            {\n                E opIndex(size_t index) {\n                    return _range[index];\n                }\n\n                E moveAt(size_t index) {\n                    return _range.moveAt(index);\n                }\n\n                static if (hasAssignableElements!R)\n                {\n                    void opIndexAssign(E val, size_t index) {\n                        _range[index] = val;\n                    }\n                }\n\n                static if (!isInfinite!R)\n                {\n                    @property size_t length() {\n                        return _range.length;\n                    }\n\n                    alias opDollar = length;\n\n                    // Can't support slicing until all the issues with\n                    // requiring slicing support for finite random access\n                    // ranges are resolved.\n                    version (none)\n                    {\n                        typeof(this) opSlice(size_t lower, size_t upper) {\n                            return new typeof(this)(_range[lower .. upper]);\n                        }\n                    }\n                }\n            }\n\n            // Optimization:  One delegate call is faster than three virtual\n            // function calls.  Use opApply for foreach syntax.\n            int opApply(scope int delegate(E) dg) {\n                int res;\n\n                for (auto r = _range; !r.empty; r.popFront())\n                {\n                    res = dg(r.front);\n                    if (res) break;\n                }\n\n                return res;\n            }\n\n            int opApply(scope int delegate(size_t, E) dg) {\n                int res;\n\n                size_t i = 0;\n                for (auto r = _range; !r.empty; r.popFront())\n                {\n                    res = dg(i, r.front);\n                    if (res) break;\n                    i++;\n                }\n\n                return res;\n            }\n        }\n    }\n}\n\n/**Convenience function for creating an `InputRangeObject` of the proper type.\n * See $(LREF InputRange) for an example.\n */\nInputRangeObject!R inputRangeObject(R)(R range)\nif (isInputRange!R)\n{\n    static if (is(R : InputRange!(ElementType!R)))\n    {\n        return range;\n    }\n    else\n    {\n        return new InputRangeObject!R(range);\n    }\n}\n\n/**Convenience function for creating an `OutputRangeObject` with a base range\n * of type `R` that accepts types `E`.\n*/\ntemplate outputRangeObject(E...) {\n\n    ///\n    OutputRangeObject!(R, E) outputRangeObject(R)(R range) {\n        return new OutputRangeObject!(R, E)(range);\n    }\n}\n\n///\n@safe unittest\n{\n     import std.array;\n     auto app = appender!(uint[])();\n     auto appWrapped = outputRangeObject!(uint, uint[])(app);\n     static assert(is(typeof(appWrapped) : OutputRange!(uint[])));\n     static assert(is(typeof(appWrapped) : OutputRange!(uint)));\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.array;\n    import std.internal.test.dummyrange;\n\n    static void testEquality(R)(iInputRange r1, R r2) {\n        assert(equal(r1, r2));\n    }\n\n    auto arr = [1,2,3,4];\n    RandomFiniteAssignable!int arrWrapped = inputRangeObject(arr);\n    static assert(isRandomAccessRange!(typeof(arrWrapped)));\n    //    static assert(hasSlicing!(typeof(arrWrapped)));\n    static assert(hasLength!(typeof(arrWrapped)));\n    arrWrapped[0] = 0;\n    assert(arr[0] == 0);\n    assert(arr.moveFront() == 0);\n    assert(arr.moveBack() == 4);\n    assert(arr.moveAt(1) == 2);\n\n    foreach (elem; arrWrapped) {}\n    foreach (i, elem; arrWrapped) {}\n\n    assert(inputRangeObject(arrWrapped) is arrWrapped);\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        auto d = DummyType.init;\n        static assert(propagatesRangeType!(DummyType,\n                        typeof(inputRangeObject(d))));\n        static assert(propagatesRangeType!(DummyType,\n                        MostDerivedInputRange!DummyType));\n        InputRange!uint wrapped = inputRangeObject(d);\n        assert(equal(wrapped, d));\n    }\n\n    // Test output range stuff.\n    auto app = appender!(uint[])();\n    auto appWrapped = outputRangeObject!(uint, uint[])(app);\n    static assert(is(typeof(appWrapped) : OutputRange!(uint[])));\n    static assert(is(typeof(appWrapped) : OutputRange!(uint)));\n\n    appWrapped.put(1);\n    appWrapped.put([2, 3]);\n    assert(app.data.length == 3);\n    assert(equal(app.data, [1,2,3]));\n}\n"
  },
  {
    "path": "libphobos/src/std/range/package.d",
    "content": "// Written in the D programming language.\n\n/**\nThis module defines the notion of a range. Ranges generalize the concept of\narrays, lists, or anything that involves sequential access. This abstraction\nenables the same set of algorithms (see $(MREF std, algorithm)) to be used\nwith a vast variety of different concrete types. For example,\na linear search algorithm such as $(REF find, std, algorithm, searching)\nworks not just for arrays, but for linked-lists, input files,\nincoming network data, etc.\n\nGuides:\n\nThere are many articles available that can bolster understanding ranges:\n\n$(UL\n    $(LI Ali Çehreli's $(HTTP ddili.org/ders/d.en/ranges.html, tutorial on ranges)\n        for the basics of working with and creating range-based code.)\n    $(LI Jonathan M. Davis $(LINK2 http://dconf.org/2015/talks/davis.html, $(I Introduction to Ranges))\n        talk at DConf 2015 a vivid introduction from its core constructs to practical advice.)\n    $(LI The DLang Tour's $(LINK2 http://tour.dlang.org/tour/en/basics/ranges, chapter on ranges)\n        for an interactive introduction.)\n    $(LI H. S. Teoh's $(LINK2 http://wiki.dlang.org/Component_programming_with_ranges, tutorial on\n        component programming with ranges) for a real-world showcase of the influence\n        of range-based programming on complex algorithms.)\n    $(LI Andrei Alexandrescu's article\n        $(LINK2 http://www.informit.com/articles/printerfriendly.aspx?p=1407357$(AMP)rll=1,\n        $(I On Iteration)) for conceptual aspect of ranges and the motivation\n    )\n)\n\nSubmodules:\n\nThis module has two submodules:\n\nThe $(MREF std, range, primitives) submodule\nprovides basic range functionality. It defines several templates for testing\nwhether a given object is a range, what kind of range it is, and provides\nsome common range operations.\n\nThe $(MREF std, range, interfaces) submodule\nprovides object-based interfaces for working with ranges via runtime\npolymorphism.\n\nThe remainder of this module provides a rich set of range creation and\ncomposition templates that let you construct new ranges out of existing ranges:\n\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE ,\n    $(TR $(TD $(LREF chain))\n        $(TD Concatenates several ranges into a single range.\n    ))\n    $(TR $(TD $(LREF choose))\n        $(TD Chooses one of two ranges at runtime based on a boolean condition.\n    ))\n    $(TR $(TD $(LREF chooseAmong))\n        $(TD Chooses one of several ranges at runtime based on an index.\n    ))\n    $(TR $(TD $(LREF chunks))\n        $(TD Creates a range that returns fixed-size chunks of the original\n        range.\n    ))\n    $(TR $(TD $(LREF cycle))\n        $(TD Creates an infinite range that repeats the given forward range\n        indefinitely. Good for implementing circular buffers.\n    ))\n    $(TR $(TD $(LREF drop))\n        $(TD Creates the range that results from discarding the first $(I n)\n        elements from the given range.\n    ))\n    $(TR $(TD $(LREF dropBack))\n        $(TD Creates the range that results from discarding the last $(I n)\n        elements from the given range.\n    ))\n    $(TR $(TD $(LREF dropExactly))\n        $(TD Creates the range that results from discarding exactly $(I n)\n        of the first elements from the given range.\n    ))\n    $(TR $(TD $(LREF dropBackExactly))\n        $(TD Creates the range that results from discarding exactly $(I n)\n        of the last elements from the given range.\n    ))\n    $(TR $(TD $(LREF dropOne))\n        $(TD Creates the range that results from discarding\n        the first element from the given range.\n    ))\n    $(TR $(TD $(D $(LREF dropBackOne)))\n        $(TD Creates the range that results from discarding\n        the last element from the given range.\n    ))\n    $(TR $(TD $(LREF enumerate))\n        $(TD Iterates a range with an attached index variable.\n    ))\n    $(TR $(TD $(LREF evenChunks))\n        $(TD Creates a range that returns a number of chunks of\n        approximately equal length from the original range.\n    ))\n    $(TR $(TD $(LREF frontTransversal))\n        $(TD Creates a range that iterates over the first elements of the\n        given ranges.\n    ))\n    $(TR $(TD $(LREF generate))\n        $(TD Creates a range by successive calls to a given function. This\n        allows to create ranges as a single delegate.\n    ))\n    $(TR $(TD $(LREF indexed))\n        $(TD Creates a range that offers a view of a given range as though\n        its elements were reordered according to a given range of indices.\n    ))\n    $(TR $(TD $(LREF iota))\n        $(TD Creates a range consisting of numbers between a starting point\n        and ending point, spaced apart by a given interval.\n    ))\n    $(TR $(TD $(LREF lockstep))\n        $(TD Iterates $(I n) ranges in lockstep, for use in a `foreach`\n        loop. Similar to `zip`, except that `lockstep` is designed\n        especially for `foreach` loops.\n    ))\n    $(TR $(TD $(LREF nullSink))\n        $(TD An output range that discards the data it receives.\n    ))\n    $(TR $(TD $(LREF only))\n        $(TD Creates a range that iterates over the given arguments.\n    ))\n    $(TR $(TD $(LREF padLeft))\n        $(TD Pads a range to a specified length by adding a given element to\n        the front of the range. Is lazy if the range has a known length.\n    ))\n    $(TR $(TD $(LREF padRight))\n        $(TD Lazily pads a range to a specified length by adding a given element to\n        the back of the range.\n    ))\n    $(TR $(TD $(LREF radial))\n        $(TD Given a random-access range and a starting point, creates a\n        range that alternately returns the next left and next right element to\n        the starting point.\n    ))\n    $(TR $(TD $(LREF recurrence))\n        $(TD Creates a forward range whose values are defined by a\n        mathematical recurrence relation.\n    ))\n    $(TR $(TD $(LREF refRange))\n        $(TD Pass a range by reference. Both the original range and the RefRange\n        will always have the exact same elements.\n        Any operation done on one will affect the other.\n    ))\n    $(TR $(TD $(LREF repeat))\n        $(TD Creates a range that consists of a single element repeated $(I n)\n        times, or an infinite range repeating that element indefinitely.\n    ))\n    $(TR $(TD $(LREF retro))\n        $(TD Iterates a bidirectional range backwards.\n    ))\n    $(TR $(TD $(LREF roundRobin))\n        $(TD Given $(I n) ranges, creates a new range that return the $(I n)\n        first elements of each range, in turn, then the second element of each\n        range, and so on, in a round-robin fashion.\n    ))\n    $(TR $(TD $(LREF sequence))\n        $(TD Similar to `recurrence`, except that a random-access range is\n        created.\n    ))\n    $(TR $(TD $(D $(LREF slide)))\n        $(TD Creates a range that returns a fixed-size sliding window\n        over the original range. Unlike chunks,\n        it advances a configurable number of items at a time,\n        not one chunk at a time.\n    ))\n    $(TR $(TD $(LREF stride))\n        $(TD Iterates a range with stride $(I n).\n    ))\n    $(TR $(TD $(LREF tail))\n        $(TD Return a range advanced to within `n` elements of the end of\n        the given range.\n    ))\n    $(TR $(TD $(LREF take))\n        $(TD Creates a sub-range consisting of only up to the first $(I n)\n        elements of the given range.\n    ))\n    $(TR $(TD $(LREF takeExactly))\n        $(TD Like `take`, but assumes the given range actually has $(I n)\n        elements, and therefore also defines the `length` property.\n    ))\n    $(TR $(TD $(LREF takeNone))\n        $(TD Creates a random-access range consisting of zero elements of the\n        given range.\n    ))\n    $(TR $(TD $(LREF takeOne))\n        $(TD Creates a random-access range consisting of exactly the first\n        element of the given range.\n    ))\n    $(TR $(TD $(LREF tee))\n        $(TD Creates a range that wraps a given range, forwarding along\n        its elements while also calling a provided function with each element.\n    ))\n    $(TR $(TD $(LREF transposed))\n        $(TD Transposes a range of ranges.\n    ))\n    $(TR $(TD $(LREF transversal))\n        $(TD Creates a range that iterates over the $(I n)'th elements of the\n        given random-access ranges.\n    ))\n    $(TR $(TD $(LREF zip))\n        $(TD Given $(I n) ranges, creates a range that successively returns a\n        tuple of all the first elements, a tuple of all the second elements,\n        etc.\n    ))\n)\n\nSortedness:\n\nRanges whose elements are sorted afford better efficiency with certain\noperations. For this, the $(LREF assumeSorted) function can be used to\nconstruct a $(LREF SortedRange) from a pre-sorted range. The $(REF\nsort, std, algorithm, sorting) function also conveniently\nreturns a $(LREF SortedRange). $(LREF SortedRange) objects provide some additional\nrange operations that take advantage of the fact that the range is sorted.\n\nSource: $(PHOBOSSRC std/range/package.d)\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu), David Simcha,\n         $(HTTP jmdavisprog.com, Jonathan M Davis), and Jack Stouffer. Credit\n         for some of the ideas in building this module goes to\n         $(HTTP fantascienza.net/leonardo/so/, Leonardo Maffi).\n */\nmodule std.range;\n\npublic import std.array;\npublic import std.range.interfaces;\npublic import std.range.primitives;\npublic import std.typecons : Flag, Yes, No;\n\nimport std.meta; // allSatisfy, staticMap\nimport std.traits; // CommonType, isCallable, isFloatingPoint, isIntegral,\n    // isPointer, isSomeFunction, isStaticArray, Unqual\n\n\n/**\nIterates a bidirectional range backwards. The original range can be\naccessed by using the `source` property. Applying retro twice to\nthe same range yields the original range.\n\nParams:\n    r = the bidirectional range to iterate backwards\n\nReturns:\n    A bidirectional range with length if `r` also provides a length. Or,\n    if `r` is a random access range, then the return value will be random\n    access as well.\nSee_Also:\n    $(REF reverse, std,algorithm,mutation) for mutating the source range directly.\n */\nauto retro(Range)(Range r)\nif (isBidirectionalRange!(Unqual!Range))\n{\n    // Check for retro(retro(r)) and just return r in that case\n    static if (is(typeof(retro(r.source)) == Range))\n    {\n        return r.source;\n    }\n    else\n    {\n        static struct Result()\n        {\n            private alias R = Unqual!Range;\n\n            // User code can get and set source, too\n            R source;\n\n            static if (hasLength!R)\n            {\n                size_t retroIndex(size_t n)\n                {\n                    return source.length - n - 1;\n                }\n            }\n\n        public:\n            alias Source = R;\n\n            @property bool empty() { return source.empty; }\n            @property auto save()\n            {\n                return Result(source.save);\n            }\n            @property auto ref front() { return source.back; }\n            void popFront() { source.popBack(); }\n            @property auto ref back() { return source.front; }\n            void popBack() { source.popFront(); }\n\n            static if (is(typeof(source.moveBack())))\n            {\n                ElementType!R moveFront()\n                {\n                    return source.moveBack();\n                }\n            }\n\n            static if (is(typeof(source.moveFront())))\n            {\n                ElementType!R moveBack()\n                {\n                    return source.moveFront();\n                }\n            }\n\n            static if (hasAssignableElements!R)\n            {\n                @property void front(ElementType!R val)\n                {\n                    source.back = val;\n                }\n\n                @property void back(ElementType!R val)\n                {\n                    source.front = val;\n                }\n            }\n\n            static if (isRandomAccessRange!(R) && hasLength!(R))\n            {\n                auto ref opIndex(size_t n) { return source[retroIndex(n)]; }\n\n                static if (hasAssignableElements!R)\n                {\n                    void opIndexAssign(ElementType!R val, size_t n)\n                    {\n                        source[retroIndex(n)] = val;\n                    }\n                }\n\n                static if (is(typeof(source.moveAt(0))))\n                {\n                    ElementType!R moveAt(size_t index)\n                    {\n                        return source.moveAt(retroIndex(index));\n                    }\n                }\n\n                static if (hasSlicing!R)\n                    typeof(this) opSlice(size_t a, size_t b)\n                    {\n                        return typeof(this)(source[source.length - b .. source.length - a]);\n                    }\n            }\n\n            static if (hasLength!R)\n            {\n                @property auto length()\n                {\n                    return source.length;\n                }\n\n                alias opDollar = length;\n            }\n        }\n\n        return Result!()(r);\n    }\n}\n\n\n///\npure @safe nothrow @nogc unittest\n{\n    import std.algorithm.comparison : equal;\n    int[5] a = [ 1, 2, 3, 4, 5 ];\n    int[5] b = [ 5, 4, 3, 2, 1 ];\n    assert(equal(retro(a[]), b[]));\n    assert(retro(a[]).source is a[]);\n    assert(retro(retro(a[])) is a[]);\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    static assert(isBidirectionalRange!(typeof(retro(\"hello\"))));\n    int[] a;\n    static assert(is(typeof(a) == typeof(retro(retro(a)))));\n    assert(retro(retro(a)) is a);\n    static assert(isRandomAccessRange!(typeof(retro([1, 2, 3]))));\n    void test(int[] input, int[] witness)\n    {\n        auto r = retro(input);\n        assert(r.front == witness.front);\n        assert(r.back == witness.back);\n        assert(equal(r, witness));\n    }\n    test([ 1 ], [ 1 ]);\n    test([ 1, 2 ], [ 2, 1 ]);\n    test([ 1, 2, 3 ], [ 3, 2, 1 ]);\n    test([ 1, 2, 3, 4 ], [ 4, 3, 2, 1 ]);\n    test([ 1, 2, 3, 4, 5 ], [ 5, 4, 3, 2, 1 ]);\n    test([ 1, 2, 3, 4, 5, 6 ], [ 6, 5, 4, 3, 2, 1 ]);\n\n    immutable foo = [1,2,3].idup;\n    auto r = retro(foo);\n    assert(equal(r, [3, 2, 1]));\n}\n\npure @safe nothrow unittest\n{\n    import std.internal.test.dummyrange : AllDummyRanges, propagatesRangeType,\n        ReturnBy;\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        static if (!isBidirectionalRange!DummyType)\n        {\n            static assert(!__traits(compiles, Retro!DummyType));\n        }\n        else\n        {\n            DummyType dummyRange;\n            dummyRange.reinit();\n\n            auto myRetro = retro(dummyRange);\n            static assert(propagatesRangeType!(typeof(myRetro), DummyType));\n            assert(myRetro.front == 10);\n            assert(myRetro.back == 1);\n            assert(myRetro.moveFront() == 10);\n            assert(myRetro.moveBack() == 1);\n\n            static if (isRandomAccessRange!DummyType && hasLength!DummyType)\n            {\n                assert(myRetro[0] == myRetro.front);\n                assert(myRetro.moveAt(2) == 8);\n\n                static if (DummyType.r == ReturnBy.Reference)\n                {\n                    {\n                        myRetro[9]++;\n                        scope(exit) myRetro[9]--;\n                        assert(dummyRange[0] == 2);\n                        myRetro.front++;\n                        scope(exit) myRetro.front--;\n                        assert(myRetro.front == 11);\n                        myRetro.back++;\n                        scope(exit) myRetro.back--;\n                        assert(myRetro.back == 3);\n                    }\n\n                    {\n                        myRetro.front = 0xFF;\n                        scope(exit) myRetro.front = 10;\n                        assert(dummyRange.back == 0xFF);\n\n                        myRetro.back = 0xBB;\n                        scope(exit) myRetro.back = 1;\n                        assert(dummyRange.front == 0xBB);\n\n                        myRetro[1] = 11;\n                        scope(exit) myRetro[1] = 8;\n                        assert(dummyRange[8] == 11);\n                    }\n                }\n            }\n        }\n    }\n}\n\npure @safe nothrow @nogc unittest\n{\n    import std.algorithm.comparison : equal;\n    auto LL = iota(1L, 4L);\n    auto r = retro(LL);\n    long[3] excepted = [3, 2, 1];\n    assert(equal(r, excepted[]));\n}\n\n// Issue 12662\npure @safe nothrow @nogc unittest\n{\n    int[3] src = [1,2,3];\n    int[] data = src[];\n    foreach_reverse (x; data) {}\n    foreach (x; data.retro) {}\n}\n\n\n/**\nIterates range `r` with stride `n`. If the range is a\nrandom-access range, moves by indexing into the range; otherwise,\nmoves by successive calls to `popFront`. Applying stride twice to\nthe same range results in a stride with a step that is the\nproduct of the two applications. It is an error for `n` to be 0.\n\nParams:\n    r = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to stride over\n    n = the number of elements to skip over\n\nReturns:\n    At minimum, an input range. The resulting range will adopt the\n    range primitives of the underlying range as long as\n    $(REF hasLength, std,range,primitives) is `true`.\n */\nauto stride(Range)(Range r, size_t n)\nif (isInputRange!(Unqual!Range))\nin\n{\n    assert(n != 0, \"stride cannot have step zero.\");\n}\ndo\n{\n    import std.algorithm.comparison : min;\n\n    static if (is(typeof(stride(r.source, n)) == Range))\n    {\n        // stride(stride(r, n1), n2) is stride(r, n1 * n2)\n        return stride(r.source, r._n * n);\n    }\n    else\n    {\n        static struct Result\n        {\n            private alias R = Unqual!Range;\n            public R source;\n            private size_t _n;\n\n            // Chop off the slack elements at the end\n            static if (hasLength!R &&\n                    (isRandomAccessRange!R && hasSlicing!R\n                            || isBidirectionalRange!R))\n                private void eliminateSlackElements()\n                {\n                    auto slack = source.length % _n;\n\n                    if (slack)\n                    {\n                        slack--;\n                    }\n                    else if (!source.empty)\n                    {\n                        slack = min(_n, source.length) - 1;\n                    }\n                    else\n                    {\n                        slack = 0;\n                    }\n                    if (!slack) return;\n                    static if (isRandomAccessRange!R && hasLength!R && hasSlicing!R)\n                    {\n                        source = source[0 .. source.length - slack];\n                    }\n                    else static if (isBidirectionalRange!R)\n                    {\n                        foreach (i; 0 .. slack)\n                        {\n                            source.popBack();\n                        }\n                    }\n                }\n\n            static if (isForwardRange!R)\n            {\n                @property auto save()\n                {\n                    return Result(source.save, _n);\n                }\n            }\n\n            static if (isInfinite!R)\n            {\n                enum bool empty = false;\n            }\n            else\n            {\n                @property bool empty()\n                {\n                    return source.empty;\n                }\n            }\n\n            @property auto ref front()\n            {\n                return source.front;\n            }\n\n            static if (is(typeof(.moveFront(source))))\n            {\n                ElementType!R moveFront()\n                {\n                    return source.moveFront();\n                }\n            }\n\n            static if (hasAssignableElements!R)\n            {\n                @property void front(ElementType!R val)\n                {\n                    source.front = val;\n                }\n            }\n\n            void popFront()\n            {\n                source.popFrontN(_n);\n            }\n\n            static if (isBidirectionalRange!R && hasLength!R)\n            {\n                void popBack()\n                {\n                    popBackN(source, _n);\n                }\n\n                @property auto ref back()\n                {\n                    eliminateSlackElements();\n                    return source.back;\n                }\n\n                static if (is(typeof(.moveBack(source))))\n                {\n                    ElementType!R moveBack()\n                    {\n                        eliminateSlackElements();\n                        return source.moveBack();\n                    }\n                }\n\n                static if (hasAssignableElements!R)\n                {\n                    @property void back(ElementType!R val)\n                    {\n                        eliminateSlackElements();\n                        source.back = val;\n                    }\n                }\n            }\n\n            static if (isRandomAccessRange!R && hasLength!R)\n            {\n                auto ref opIndex(size_t n)\n                {\n                    return source[_n * n];\n                }\n\n                /**\n                   Forwards to $(D moveAt(source, n)).\n                */\n                static if (is(typeof(source.moveAt(0))))\n                {\n                    ElementType!R moveAt(size_t n)\n                    {\n                        return source.moveAt(_n * n);\n                    }\n                }\n\n                static if (hasAssignableElements!R)\n                {\n                    void opIndexAssign(ElementType!R val, size_t n)\n                    {\n                        source[_n * n] = val;\n                    }\n                }\n            }\n\n            static if (hasSlicing!R && hasLength!R)\n                typeof(this) opSlice(size_t lower, size_t upper)\n                {\n                    assert(upper >= lower && upper <= length);\n                    immutable translatedUpper = (upper == 0) ? 0 :\n                        (upper * _n - (_n - 1));\n                    immutable translatedLower = min(lower * _n, translatedUpper);\n\n                    assert(translatedLower <= translatedUpper);\n\n                    return typeof(this)(source[translatedLower .. translatedUpper], _n);\n                }\n\n            static if (hasLength!R)\n            {\n                @property auto length()\n                {\n                    return (source.length + _n - 1) / _n;\n                }\n\n                alias opDollar = length;\n            }\n        }\n        return Result(r, n);\n    }\n}\n\n///\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];\n    assert(equal(stride(a, 3), [ 1, 4, 7, 10 ][]));\n    assert(stride(stride(a, 2), 3) == stride(a, 6));\n}\n\npure @safe nothrow @nogc unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[4] testArr = [1,2,3,4];\n    static immutable result = [1, 3];\n    assert(equal(testArr[].stride(2), result));\n}\n\ndebug pure nothrow @system unittest\n{//check the contract\n    int[4] testArr = [1,2,3,4];\n    bool passed = false;\n    scope (success) assert(passed);\n    import core.exception : AssertError;\n    //std.exception.assertThrown won't do because it can't infer nothrow\n    // @@@BUG@@@ 12647\n    try\n    {\n        auto unused = testArr[].stride(0);\n    }\n    catch (AssertError unused)\n    {\n        passed = true;\n    }\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges, propagatesRangeType,\n        ReturnBy;\n\n    static assert(isRandomAccessRange!(typeof(stride([1, 2, 3], 2))));\n    void test(size_t n, int[] input, int[] witness)\n    {\n        assert(equal(stride(input, n), witness));\n    }\n    test(1, [], []);\n    int[] arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\n    assert(stride(stride(arr, 2), 3) is stride(arr, 6));\n    test(1, arr, arr);\n    test(2, arr, [1, 3, 5, 7, 9]);\n    test(3, arr, [1, 4, 7, 10]);\n    test(4, arr, [1, 5, 9]);\n\n    // Test slicing.\n    auto s1 = stride(arr, 1);\n    assert(equal(s1[1 .. 4], [2, 3, 4]));\n    assert(s1[1 .. 4].length == 3);\n    assert(equal(s1[1 .. 5], [2, 3, 4, 5]));\n    assert(s1[1 .. 5].length == 4);\n    assert(s1[0 .. 0].empty);\n    assert(s1[3 .. 3].empty);\n    // assert(s1[$ .. $].empty);\n    assert(s1[s1.opDollar .. s1.opDollar].empty);\n\n    auto s2 = stride(arr, 2);\n    assert(equal(s2[0 .. 2], [1,3]));\n    assert(s2[0 .. 2].length == 2);\n    assert(equal(s2[1 .. 5], [3, 5, 7, 9]));\n    assert(s2[1 .. 5].length == 4);\n    assert(s2[0 .. 0].empty);\n    assert(s2[3 .. 3].empty);\n    // assert(s2[$ .. $].empty);\n    assert(s2[s2.opDollar .. s2.opDollar].empty);\n\n    // Test fix for Bug 5035\n    auto m = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]; // 3 rows, 4 columns\n    auto col = stride(m, 4);\n    assert(equal(col, [1, 1, 1]));\n    assert(equal(retro(col), [1, 1, 1]));\n\n    immutable int[] immi = [ 1, 2, 3 ];\n    static assert(isRandomAccessRange!(typeof(stride(immi, 1))));\n\n    // Check for infiniteness propagation.\n    static assert(isInfinite!(typeof(stride(repeat(1), 3))));\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType dummyRange;\n        dummyRange.reinit();\n\n        auto myStride = stride(dummyRange, 4);\n\n        // Should fail if no length and bidirectional b/c there's no way\n        // to know how much slack we have.\n        static if (hasLength!DummyType || !isBidirectionalRange!DummyType)\n        {\n            static assert(propagatesRangeType!(typeof(myStride), DummyType));\n        }\n        assert(myStride.front == 1);\n        assert(myStride.moveFront() == 1);\n        assert(equal(myStride, [1, 5, 9]));\n\n        static if (hasLength!DummyType)\n        {\n            assert(myStride.length == 3);\n        }\n\n        static if (isBidirectionalRange!DummyType && hasLength!DummyType)\n        {\n            assert(myStride.back == 9);\n            assert(myStride.moveBack() == 9);\n        }\n\n        static if (isRandomAccessRange!DummyType && hasLength!DummyType)\n        {\n            assert(myStride[0] == 1);\n            assert(myStride[1] == 5);\n            assert(myStride.moveAt(1) == 5);\n            assert(myStride[2] == 9);\n\n            static assert(hasSlicing!(typeof(myStride)));\n        }\n\n        static if (DummyType.r == ReturnBy.Reference)\n        {\n            // Make sure reference is propagated.\n\n            {\n                myStride.front++;\n                scope(exit) myStride.front--;\n                assert(dummyRange.front == 2);\n            }\n            {\n                myStride.front = 4;\n                scope(exit) myStride.front = 1;\n                assert(dummyRange.front == 4);\n            }\n\n            static if (isBidirectionalRange!DummyType && hasLength!DummyType)\n            {\n                {\n                    myStride.back++;\n                    scope(exit) myStride.back--;\n                    assert(myStride.back == 10);\n                }\n                {\n                    myStride.back = 111;\n                    scope(exit) myStride.back = 9;\n                    assert(myStride.back == 111);\n                }\n\n                static if (isRandomAccessRange!DummyType)\n                {\n                    {\n                        myStride[1]++;\n                        scope(exit) myStride[1]--;\n                        assert(dummyRange[4] == 6);\n                    }\n                    {\n                        myStride[1] = 55;\n                        scope(exit) myStride[1] = 5;\n                        assert(dummyRange[4] == 55);\n                    }\n                }\n            }\n        }\n    }\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto LL = iota(1L, 10L);\n    auto s = stride(LL, 3);\n    assert(equal(s, [1L, 4L, 7L]));\n}\n\n/**\nSpans multiple ranges in sequence. The function `chain` takes any\nnumber of ranges and returns a $(D Chain!(R1, R2,...)) object. The\nranges may be different, but they must have the same element type. The\nresult is a range that offers the `front`, `popFront`, and $(D\nempty) primitives. If all input ranges offer random access and $(D\nlength), `Chain` offers them as well.\n\nIf only one range is offered to `Chain` or `chain`, the $(D\nChain) type exits the picture by aliasing itself directly to that\nrange's type.\n\nParams:\n    rs = the $(REF_ALTTEXT input ranges, isInputRange, std,range,primitives) to chain together\n\nReturns:\n    An input range at minimum. If all of the ranges in `rs` provide\n    a range primitive, the returned range will also provide that range\n    primitive.\n\nSee_Also: $(LREF only) to chain values to a range\n */\nauto chain(Ranges...)(Ranges rs)\nif (Ranges.length > 0 &&\n    allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)) &&\n    !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, Ranges))) == void))\n{\n    static if (Ranges.length == 1)\n    {\n        return rs[0];\n    }\n    else\n    {\n        static struct Result\n        {\n        private:\n            alias R = staticMap!(Unqual, Ranges);\n            alias RvalueElementType = CommonType!(staticMap!(.ElementType, R));\n            private template sameET(A)\n            {\n                enum sameET = is(.ElementType!A == RvalueElementType);\n            }\n\n            enum bool allSameType = allSatisfy!(sameET, R);\n\n            // This doesn't work yet\n            static if (allSameType)\n            {\n                alias ElementType = ref RvalueElementType;\n            }\n            else\n            {\n                alias ElementType = RvalueElementType;\n            }\n            static if (allSameType && allSatisfy!(hasLvalueElements, R))\n            {\n                static ref RvalueElementType fixRef(ref RvalueElementType val)\n                {\n                    return val;\n                }\n            }\n            else\n            {\n                static RvalueElementType fixRef(RvalueElementType val)\n                {\n                    return val;\n                }\n            }\n\n            // This is the entire state\n            R source;\n            // TODO: use a vtable (or more) instead of linear iteration\n\n        public:\n            this(R input)\n            {\n                foreach (i, v; input)\n                {\n                    source[i] = v;\n                }\n            }\n\n            import std.meta : anySatisfy;\n\n            static if (anySatisfy!(isInfinite, R))\n            {\n                // Propagate infiniteness.\n                enum bool empty = false;\n            }\n            else\n            {\n                @property bool empty()\n                {\n                    foreach (i, Unused; R)\n                    {\n                        if (!source[i].empty) return false;\n                    }\n                    return true;\n                }\n            }\n\n            static if (allSatisfy!(isForwardRange, R))\n                @property auto save()\n                {\n                    typeof(this) result = this;\n                    foreach (i, Unused; R)\n                    {\n                        result.source[i] = result.source[i].save;\n                    }\n                    return result;\n                }\n\n            void popFront()\n            {\n                foreach (i, Unused; R)\n                {\n                    if (source[i].empty) continue;\n                    source[i].popFront();\n                    return;\n                }\n            }\n\n            @property auto ref front()\n            {\n                foreach (i, Unused; R)\n                {\n                    if (source[i].empty) continue;\n                    return fixRef(source[i].front);\n                }\n                assert(false);\n            }\n\n            static if (allSameType && allSatisfy!(hasAssignableElements, R))\n            {\n                // @@@BUG@@@\n                //@property void front(T)(T v) if (is(T : RvalueElementType))\n\n                @property void front(RvalueElementType v)\n                {\n                    foreach (i, Unused; R)\n                    {\n                        if (source[i].empty) continue;\n                        source[i].front = v;\n                        return;\n                    }\n                    assert(false);\n                }\n            }\n\n            static if (allSatisfy!(hasMobileElements, R))\n            {\n                RvalueElementType moveFront()\n                {\n                    foreach (i, Unused; R)\n                    {\n                        if (source[i].empty) continue;\n                        return source[i].moveFront();\n                    }\n                    assert(false);\n                }\n            }\n\n            static if (allSatisfy!(isBidirectionalRange, R))\n            {\n                @property auto ref back()\n                {\n                    foreach_reverse (i, Unused; R)\n                    {\n                        if (source[i].empty) continue;\n                        return fixRef(source[i].back);\n                    }\n                    assert(false);\n                }\n\n                void popBack()\n                {\n                    foreach_reverse (i, Unused; R)\n                    {\n                        if (source[i].empty) continue;\n                        source[i].popBack();\n                        return;\n                    }\n                }\n\n                static if (allSatisfy!(hasMobileElements, R))\n                {\n                    RvalueElementType moveBack()\n                    {\n                        foreach_reverse (i, Unused; R)\n                        {\n                            if (source[i].empty) continue;\n                            return source[i].moveBack();\n                        }\n                        assert(false);\n                    }\n                }\n\n                static if (allSameType && allSatisfy!(hasAssignableElements, R))\n                {\n                    @property void back(RvalueElementType v)\n                    {\n                        foreach_reverse (i, Unused; R)\n                        {\n                            if (source[i].empty) continue;\n                            source[i].back = v;\n                            return;\n                        }\n                        assert(false);\n                    }\n                }\n            }\n\n            static if (allSatisfy!(hasLength, R))\n            {\n                @property size_t length()\n                {\n                    size_t result;\n                    foreach (i, Unused; R)\n                    {\n                        result += source[i].length;\n                    }\n                    return result;\n                }\n\n                alias opDollar = length;\n            }\n\n            static if (allSatisfy!(isRandomAccessRange, R))\n            {\n                auto ref opIndex(size_t index)\n                {\n                    foreach (i, Range; R)\n                    {\n                        static if (isInfinite!(Range))\n                        {\n                            return source[i][index];\n                        }\n                        else\n                        {\n                            immutable length = source[i].length;\n                            if (index < length) return fixRef(source[i][index]);\n                            index -= length;\n                        }\n                    }\n                    assert(false);\n                }\n\n                static if (allSatisfy!(hasMobileElements, R))\n                {\n                    RvalueElementType moveAt(size_t index)\n                    {\n                        foreach (i, Range; R)\n                        {\n                            static if (isInfinite!(Range))\n                            {\n                                return source[i].moveAt(index);\n                            }\n                            else\n                            {\n                                immutable length = source[i].length;\n                                if (index < length) return source[i].moveAt(index);\n                                index -= length;\n                            }\n                        }\n                        assert(false);\n                    }\n                }\n\n                static if (allSameType && allSatisfy!(hasAssignableElements, R))\n                    void opIndexAssign(ElementType v, size_t index)\n                    {\n                        foreach (i, Range; R)\n                        {\n                            static if (isInfinite!(Range))\n                            {\n                                source[i][index] = v;\n                            }\n                            else\n                            {\n                                immutable length = source[i].length;\n                                if (index < length)\n                                {\n                                    source[i][index] = v;\n                                    return;\n                                }\n                                index -= length;\n                            }\n                        }\n                        assert(false);\n                    }\n            }\n\n            static if (allSatisfy!(hasLength, R) && allSatisfy!(hasSlicing, R))\n                auto opSlice(size_t begin, size_t end)\n                {\n                    auto result = this;\n                    foreach (i, Unused; R)\n                    {\n                        immutable len = result.source[i].length;\n                        if (len < begin)\n                        {\n                            result.source[i] = result.source[i]\n                                [len .. len];\n                            begin -= len;\n                        }\n                        else\n                        {\n                            result.source[i] = result.source[i]\n                                [begin .. len];\n                            break;\n                        }\n                    }\n                    auto cut = length;\n                    cut = cut <= end ? 0 : cut - end;\n                    foreach_reverse (i, Unused; R)\n                    {\n                        immutable len = result.source[i].length;\n                        if (cut > len)\n                        {\n                            result.source[i] = result.source[i]\n                                [0 .. 0];\n                            cut -= len;\n                        }\n                        else\n                        {\n                            result.source[i] = result.source[i]\n                                [0 .. len - cut];\n                            break;\n                        }\n                    }\n                    return result;\n                }\n        }\n        return Result(rs);\n    }\n}\n\n///\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[] arr1 = [ 1, 2, 3, 4 ];\n    int[] arr2 = [ 5, 6 ];\n    int[] arr3 = [ 7 ];\n    auto s = chain(arr1, arr2, arr3);\n    assert(s.length == 7);\n    assert(s[5] == 6);\n    assert(equal(s, [1, 2, 3, 4, 5, 6, 7][]));\n}\n\n/**\n * Range primitives are carried over to the returned range if\n * all of the ranges provide them\n */\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.sorting : sort;\n\n    int[] arr1 = [5, 2, 8];\n    int[] arr2 = [3, 7, 9];\n    int[] arr3 = [1, 4, 6];\n\n    // in-place sorting across all of the arrays\n    auto s = arr1.chain(arr2, arr3).sort;\n\n    assert(s.equal([1, 2, 3, 4, 5, 6, 7, 8, 9]));\n    assert(arr1.equal([1, 2, 3]));\n    assert(arr2.equal([4, 5, 6]));\n    assert(arr3.equal([7, 8, 9]));\n}\n\n/**\nDue to safe type promotion in D, chaining together different\ncharacter ranges results in a `uint` range.\n\nUse $(REF_ALTTEXT byChar, byChar,std,utf), $(REF_ALTTEXT byWchar, byWchar,std,utf),\nand $(REF_ALTTEXT byDchar, byDchar,std,utf) on the ranges\nto get the type you need.\n */\npure @safe nothrow unittest\n{\n    import std.utf : byChar, byCodeUnit;\n\n    auto s1 = \"string one\";\n    auto s2 = \"string two\";\n    // s1 and s2 front is dchar because of auto-decoding\n    static assert(is(typeof(s1.front) == dchar) && is(typeof(s2.front) == dchar));\n\n    auto r1 = s1.chain(s2);\n    // chains of ranges of the same character type give that same type\n    static assert(is(typeof(r1.front) == dchar));\n\n    auto s3 = \"string three\".byCodeUnit;\n    static assert(is(typeof(s3.front) == immutable char));\n    auto r2 = s1.chain(s3);\n    // type is promoted\n    static assert(is(typeof(r2.front) == uint));\n\n    // use byChar on character ranges to correctly convert them to UTF-8\n    auto r3 = s1.byChar.chain(s3);\n    static assert(is(typeof(r3.front) == immutable char));\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges, dummyLength,\n                                          propagatesRangeType;\n\n    {\n        int[] arr1 = [ 1, 2, 3, 4 ];\n        int[] arr2 = [ 5, 6 ];\n        int[] arr3 = [ 7 ];\n        int[] witness = [ 1, 2, 3, 4, 5, 6, 7 ];\n        auto s1 = chain(arr1);\n        static assert(isRandomAccessRange!(typeof(s1)));\n        auto s2 = chain(arr1, arr2);\n        static assert(isBidirectionalRange!(typeof(s2)));\n        static assert(isRandomAccessRange!(typeof(s2)));\n        s2.front = 1;\n        auto s = chain(arr1, arr2, arr3);\n        assert(s[5] == 6);\n        assert(equal(s, witness));\n        assert(s[5] == 6);\n    }\n    {\n        int[] arr1 = [ 1, 2, 3, 4 ];\n        int[] witness = [ 1, 2, 3, 4 ];\n        assert(equal(chain(arr1), witness));\n    }\n    {\n        uint[] foo = [1,2,3,4,5];\n        uint[] bar = [1,2,3,4,5];\n        auto c = chain(foo, bar);\n        c[3] = 42;\n        assert(c[3] == 42);\n        assert(c.moveFront() == 1);\n        assert(c.moveBack() == 5);\n        assert(c.moveAt(4) == 5);\n        assert(c.moveAt(5) == 1);\n    }\n\n    // Make sure bug 3311 is fixed.  ChainImpl should compile even if not all\n    // elements are mutable.\n    assert(equal(chain(iota(0, 3), iota(0, 3)), [0, 1, 2, 0, 1, 2]));\n\n    // Test the case where infinite ranges are present.\n    auto inf = chain([0,1,2][], cycle([4,5,6][]), [7,8,9][]); // infinite range\n    assert(inf[0] == 0);\n    assert(inf[3] == 4);\n    assert(inf[6] == 4);\n    assert(inf[7] == 5);\n    static assert(isInfinite!(typeof(inf)));\n\n    immutable int[] immi = [ 1, 2, 3 ];\n    immutable float[] immf = [ 1, 2, 3 ];\n    static assert(is(typeof(chain(immi, immf))));\n\n    // Check that chain at least instantiates and compiles with every possible\n    // pair of DummyRange types, in either order.\n\n    foreach (DummyType1; AllDummyRanges)\n    {\n        DummyType1 dummy1;\n        foreach (DummyType2; AllDummyRanges)\n        {\n            DummyType2 dummy2;\n            auto myChain = chain(dummy1, dummy2);\n\n            static assert(\n                propagatesRangeType!(typeof(myChain), DummyType1, DummyType2)\n            );\n\n            assert(myChain.front == 1);\n            foreach (i; 0 .. dummyLength)\n            {\n                myChain.popFront();\n            }\n            assert(myChain.front == 1);\n\n            static if (isBidirectionalRange!DummyType1 &&\n                      isBidirectionalRange!DummyType2) {\n                assert(myChain.back == 10);\n            }\n\n            static if (isRandomAccessRange!DummyType1 &&\n                      isRandomAccessRange!DummyType2) {\n                assert(myChain[0] == 1);\n            }\n\n            static if (hasLvalueElements!DummyType1 && hasLvalueElements!DummyType2)\n            {\n                static assert(hasLvalueElements!(typeof(myChain)));\n            }\n            else\n            {\n                static assert(!hasLvalueElements!(typeof(myChain)));\n            }\n        }\n    }\n}\n\npure @safe nothrow @nogc unittest\n{\n    class Foo{}\n    immutable(Foo)[] a;\n    immutable(Foo)[] b;\n    assert(chain(a, b).empty);\n}\n\n/**\nChoose one of two ranges at runtime depending on a Boolean condition.\n\nThe ranges may be different, but they must have compatible element types (i.e.\n`CommonType` must exist for the two element types). The result is a range\nthat offers the weakest capabilities of the two (e.g. `ForwardRange` if $(D\nR1) is a random-access range and `R2` is a forward range).\n\nParams:\n    condition = which range to choose: `r1` if `true`, `r2` otherwise\n    r1 = the \"true\" range\n    r2 = the \"false\" range\n\nReturns:\n    A range type dependent on `R1` and `R2`.\n */\nauto choose(R1, R2)(bool condition, R1 r1, R2 r2)\nif (isInputRange!(Unqual!R1) && isInputRange!(Unqual!R2) &&\n    !is(CommonType!(ElementType!(Unqual!R1), ElementType!(Unqual!R2)) == void))\n{\n    return ChooseResult!(R1, R2)(condition, r1, r2);\n}\n\n///\n@safe nothrow pure @nogc unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter, map;\n\n    auto data1 = only(1, 2, 3, 4).filter!(a => a != 3);\n    auto data2 = only(5, 6, 7, 8).map!(a => a + 1);\n\n    // choose() is primarily useful when you need to select one of two ranges\n    // with different types at runtime.\n    static assert(!is(typeof(data1) == typeof(data2)));\n\n    auto chooseRange(bool pickFirst)\n    {\n        // The returned range is a common wrapper type that can be used for\n        // returning or storing either range without running into a type error.\n        return choose(pickFirst, data1, data2);\n\n        // Simply returning the chosen range without using choose() does not\n        // work, because map() and filter() return different types.\n        //return pickFirst ? data1 : data2; // does not compile\n    }\n\n    auto result = chooseRange(true);\n    assert(result.equal(only(1, 2, 4)));\n\n    result = chooseRange(false);\n    assert(result.equal(only(6, 7, 8, 9)));\n}\n\n\nprivate struct ChooseResult(R1, R2)\n{\n    import std.traits : hasElaborateCopyConstructor, hasElaborateDestructor;\n\n    private union\n    {\n        R1 r1;\n        R2 r2;\n    }\n    private bool r1Chosen;\n\n    private static auto ref actOnChosen(alias foo, ExtraArgs ...)(ref ChooseResult r,\n            auto ref ExtraArgs extraArgs)\n    {\n        if (r.r1Chosen)\n            return foo(r.r1, extraArgs);\n        else\n            return foo(r.r2, extraArgs);\n    }\n\n    this(bool r1Chosen, R1 r1, R2 r2)\n    {\n        import std.conv : emplace;\n\n        // This should be the only place r1Chosen is ever assigned\n        // independently\n        this.r1Chosen = r1Chosen;\n        if (r1Chosen)\n        {\n            this.r2 = R2.init;\n            emplace(&this.r1, r1);\n        }\n        else\n        {\n            this.r1 = R1.init;\n            emplace(&this.r2, r2);\n        }\n    }\n\n    // Carefully defined postblit to postblit the appropriate range\n    static if (hasElaborateCopyConstructor!R1\n        || hasElaborateCopyConstructor!R2)\n    this(this)\n    {\n        this.actOnChosen!((ref r) {\n                static if (hasElaborateCopyConstructor!(typeof(r))) r.__postblit();\n            });\n    }\n\n    static if (hasElaborateDestructor!R1 || hasElaborateDestructor!R2)\n    ~this()\n    {\n        actOnChosen!((ref r) => destroy(r))(this);\n    }\n\n    static if (isInfinite!R1 && isInfinite!R2)\n        // Propagate infiniteness.\n        enum bool empty = false;\n    else\n        @property bool empty()\n        {\n            return actOnChosen!(r => r.empty)(this);\n        }\n\n    @property auto ref front()\n    {\n        static auto ref getFront(R)(ref R r) { return r.front; }\n        return actOnChosen!getFront(this);\n    }\n\n    void popFront()\n    {\n        return actOnChosen!((ref r) { r.popFront; })(this);\n    }\n\n    static if (isForwardRange!R1 && isForwardRange!R2)\n        @property auto save()\n        {\n            auto result = this;\n            actOnChosen!((ref r) { r = r.save; })(result);\n            return result;\n        }\n\n    @property void front(T)(T v)\n    if (is(typeof({ r1.front = v; r2.front = v; })))\n    {\n        actOnChosen!((ref r, T v) { r.front = v; })(this, v);\n    }\n\n    static if (hasMobileElements!R1 && hasMobileElements!R2)\n        auto moveFront()\n        {\n            return actOnChosen!((ref r) => r.moveFront)(this);\n        }\n\n    static if (isBidirectionalRange!R1 && isBidirectionalRange!R2)\n    {\n        @property auto ref back()\n        {\n            static auto ref getBack(R)(ref R r) { return r.back; }\n            return actOnChosen!getBack(this);\n        }\n\n        void popBack()\n        {\n            actOnChosen!((ref r) { r.popBack; })(this);\n        }\n\n        static if (hasMobileElements!R1 && hasMobileElements!R2)\n            auto moveBack()\n            {\n                return actOnChosen!((ref r) => r.moveBack)(this);\n            }\n\n        @property void back(T)(T v)\n        if (is(typeof({ r1.back = v; r2.back = v; })))\n        {\n            actOnChosen!((ref r, T v) { r.back = v; })(this, v);\n        }\n    }\n\n    static if (hasLength!R1 && hasLength!R2)\n    {\n        @property size_t length()\n        {\n            return actOnChosen!(r => r.length)(this);\n        }\n        alias opDollar = length;\n    }\n\n    static if (isRandomAccessRange!R1 && isRandomAccessRange!R2)\n    {\n        auto ref opIndex(size_t index)\n        {\n            static auto ref get(R)(ref R r, size_t index) { return r[index]; }\n            return actOnChosen!get(this, index);\n        }\n\n        static if (hasMobileElements!R1 && hasMobileElements!R2)\n            auto moveAt(size_t index)\n            {\n                return actOnChosen!((ref r, size_t index) => r.moveAt(index))\n                    (this, index);\n            }\n\n        void opIndexAssign(T)(T v, size_t index)\n        if (is(typeof({ r1[1] = v; r2[1] = v; })))\n        {\n            return actOnChosen!((ref r, size_t index, T v) { r[index] = v; })\n                (this, index, v);\n        }\n    }\n\n    static if (hasSlicing!R1 && hasSlicing!R2)\n        auto opSlice(size_t begin, size_t end)\n        {\n            alias Slice1 = typeof(R1.init[0 .. 1]);\n            alias Slice2 = typeof(R2.init[0 .. 1]);\n            return actOnChosen!((r, size_t begin, size_t end) {\n                    static if (is(typeof(r) == Slice1))\n                        return choose(true, r[begin .. end], Slice2.init);\n                    else\n                        return choose(false, Slice1.init, r[begin .. end]);\n                })(this, begin, end);\n        }\n}\n\n/**\nChoose one of multiple ranges at runtime.\n\nThe ranges may be different, but they must have compatible element types. The\nresult is a range that offers the weakest capabilities of all `Ranges`.\n\nParams:\n    index = which range to choose, must be less than the number of ranges\n    rs = two or more ranges\n\nReturns:\n    The indexed range. If rs consists of only one range, the return type is an\n    alias of that range's type.\n */\nauto chooseAmong(Ranges...)(size_t index, Ranges rs)\nif (Ranges.length >= 2\n        && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges))\n        && !is(CommonType!(staticMap!(ElementType, Ranges)) == void))\n{\n    static if (Ranges.length == 2)\n        return choose(index == 0, rs[0], rs[1]);\n    else\n        return choose(index == 0, rs[0], chooseAmong(index - 1, rs[1 .. $]));\n}\n\n///\n@safe nothrow pure @nogc unittest\n{\n    auto test()\n    {\n        import std.algorithm.comparison : equal;\n\n        int[4] sarr1 = [1, 2, 3, 4];\n        int[2] sarr2 = [5, 6];\n        int[1] sarr3 = [7];\n        auto arr1 = sarr1[];\n        auto arr2 = sarr2[];\n        auto arr3 = sarr3[];\n\n        {\n            auto s = chooseAmong(0, arr1, arr2, arr3);\n            auto t = s.save;\n            assert(s.length == 4);\n            assert(s[2] == 3);\n            s.popFront();\n            assert(equal(t, only(1, 2, 3, 4)));\n        }\n        {\n            auto s = chooseAmong(1, arr1, arr2, arr3);\n            assert(s.length == 2);\n            s.front = 8;\n            assert(equal(s, only(8, 6)));\n        }\n        {\n            auto s = chooseAmong(1, arr1, arr2, arr3);\n            assert(s.length == 2);\n            s[1] = 9;\n            assert(equal(s, only(8, 9)));\n        }\n        {\n            auto s = chooseAmong(1, arr2, arr1, arr3)[1 .. 3];\n            assert(s.length == 2);\n            assert(equal(s, only(2, 3)));\n        }\n        {\n            auto s = chooseAmong(0, arr1, arr2, arr3);\n            assert(s.length == 4);\n            assert(s.back == 4);\n            s.popBack();\n            s.back = 5;\n            assert(equal(s, only(1, 2, 5)));\n            s.back = 3;\n            assert(equal(s, only(1, 2, 3)));\n        }\n        {\n            uint[5] foo = [1, 2, 3, 4, 5];\n            uint[5] bar = [6, 7, 8, 9, 10];\n            auto c = chooseAmong(1, foo[], bar[]);\n            assert(c[3] == 9);\n            c[3] = 42;\n            assert(c[3] == 42);\n            assert(c.moveFront() == 6);\n            assert(c.moveBack() == 10);\n            assert(c.moveAt(4) == 10);\n        }\n        {\n            import std.range : cycle;\n            auto s = chooseAmong(0, cycle(arr2), cycle(arr3));\n            assert(isInfinite!(typeof(s)));\n            assert(!s.empty);\n            assert(s[100] == 8);\n            assert(s[101] == 9);\n            assert(s[0 .. 3].equal(only(8, 9, 8)));\n        }\n        return 0;\n    }\n    // works at runtime\n    auto a = test();\n    // and at compile time\n    static b = test();\n}\n\n@safe nothrow pure @nogc unittest\n{\n    int[3] a = [1, 2, 3];\n    long[3] b = [4, 5, 6];\n    auto c = chooseAmong(0, a[], b[]);\n    c[0] = 42;\n    assert(c[0] == 42);\n}\n\n@safe nothrow pure @nogc unittest\n{\n    static struct RefAccessRange\n    {\n        int[] r;\n        ref front() @property { return r[0]; }\n        ref back() @property { return r[$ - 1]; }\n        void popFront() { r = r[1 .. $]; }\n        void popBack() { r = r[0 .. $ - 1]; }\n        auto empty() @property { return r.empty; }\n        ref opIndex(size_t i) { return r[i]; }\n        auto length() @property { return r.length; }\n        alias opDollar = length;\n        auto save() { return this; }\n    }\n    static assert(isRandomAccessRange!RefAccessRange);\n    static assert(isRandomAccessRange!RefAccessRange);\n    int[4] a = [4, 3, 2, 1];\n    int[2] b = [6, 5];\n    auto c = chooseAmong(0, RefAccessRange(a[]), RefAccessRange(b[]));\n\n    void refFunc(ref int a, int target) { assert(a == target); }\n\n    refFunc(c[2], 2);\n    refFunc(c.front, 4);\n    refFunc(c.back, 1);\n}\n\n\n/**\n$(D roundRobin(r1, r2, r3)) yields `r1.front`, then `r2.front`,\nthen `r3.front`, after which it pops off one element from each and\ncontinues again from `r1`. For example, if two ranges are involved,\nit alternately yields elements off the two ranges. `roundRobin`\nstops after it has consumed all ranges (skipping over the ones that\nfinish early).\n */\nauto roundRobin(Rs...)(Rs rs)\nif (Rs.length > 1 && allSatisfy!(isInputRange, staticMap!(Unqual, Rs)))\n{\n    struct Result\n    {\n        import std.conv : to;\n\n        public Rs source;\n        private size_t _current = size_t.max;\n\n        @property bool empty()\n        {\n            foreach (i, Unused; Rs)\n            {\n                if (!source[i].empty) return false;\n            }\n            return true;\n        }\n\n        @property auto ref front()\n        {\n            final switch (_current)\n            {\n                foreach (i, R; Rs)\n                {\n                    case i:\n                        assert(\n                            !source[i].empty,\n                            \"Attempting to fetch the front of an empty roundRobin\"\n                        );\n                        return source[i].front;\n                }\n            }\n            assert(0);\n        }\n\n        void popFront()\n        {\n            final switch (_current)\n            {\n                foreach (i, R; Rs)\n                {\n                    case i:\n                        source[i].popFront();\n                        break;\n                }\n            }\n\n            auto next = _current == (Rs.length - 1) ? 0 : (_current + 1);\n            final switch (next)\n            {\n                foreach (i, R; Rs)\n                {\n                    case i:\n                        if (!source[i].empty)\n                        {\n                            _current = i;\n                            return;\n                        }\n                        if (i == _current)\n                        {\n                            _current = _current.max;\n                            return;\n                        }\n                        goto case (i + 1) % Rs.length;\n                }\n            }\n        }\n\n        static if (allSatisfy!(isForwardRange, staticMap!(Unqual, Rs)))\n            @property auto save()\n            {\n                Result result = this;\n                foreach (i, Unused; Rs)\n                {\n                    result.source[i] = result.source[i].save;\n                }\n                return result;\n            }\n\n        static if (allSatisfy!(hasLength, Rs))\n        {\n            @property size_t length()\n            {\n                size_t result;\n                foreach (i, R; Rs)\n                {\n                    result += source[i].length;\n                }\n                return result;\n            }\n\n            alias opDollar = length;\n        }\n    }\n\n    return Result(rs, 0);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[] a = [ 1, 2, 3 ];\n    int[] b = [ 10, 20, 30, 40 ];\n    auto r = roundRobin(a, b);\n    assert(equal(r, [ 1, 10, 2, 20, 3, 30, 40 ]));\n}\n\n/**\n * roundRobin can be used to create \"interleave\" functionality which inserts\n * an element between each element in a range.\n */\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto interleave(R, E)(R range, E element)\n    if ((isInputRange!R && hasLength!R) || isForwardRange!R)\n    {\n        static if (hasLength!R)\n            immutable len = range.length;\n        else\n            immutable len = range.save.walkLength;\n\n        return roundRobin(\n            range,\n            element.repeat(len - 1)\n        );\n    }\n\n    assert(interleave([1, 2, 3], 0).equal([1, 0, 2, 0, 3]));\n}\n\n/**\nIterates a random-access range starting from a given point and\nprogressively extending left and right from that point. If no initial\npoint is given, iteration starts from the middle of the\nrange. Iteration spans the entire range.\n\nWhen `startingIndex` is 0 the range will be fully iterated in order\nand in reverse order when `r.length` is given.\n\nParams:\n    r = a random access range with length and slicing\n    startingIndex = the index to begin iteration from\n\nReturns:\n    A forward range with length\n */\nauto radial(Range, I)(Range r, I startingIndex)\nif (isRandomAccessRange!(Unqual!Range) && hasLength!(Unqual!Range) && hasSlicing!(Unqual!Range) && isIntegral!I)\n{\n    if (startingIndex != r.length) ++startingIndex;\n    return roundRobin(retro(r[0 .. startingIndex]), r[startingIndex .. r.length]);\n}\n\n/// Ditto\nauto radial(R)(R r)\nif (isRandomAccessRange!(Unqual!R) && hasLength!(Unqual!R) && hasSlicing!(Unqual!R))\n{\n    return .radial(r, (r.length - !r.empty) / 2);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    int[] a = [ 1, 2, 3, 4, 5 ];\n    assert(equal(radial(a), [ 3, 4, 2, 5, 1 ]));\n    a = [ 1, 2, 3, 4 ];\n    assert(equal(radial(a), [ 2, 3, 1, 4 ]));\n\n    // If the left end is reached first, the remaining elements on the right\n    // are concatenated in order:\n    a = [ 0, 1, 2, 3, 4, 5 ];\n    assert(equal(radial(a, 1), [ 1, 2, 0, 3, 4, 5 ]));\n\n    // If the right end is reached first, the remaining elements on the left\n    // are concatenated in reverse order:\n    assert(equal(radial(a, 4), [ 4, 5, 3, 2, 1, 0 ]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : text;\n    import std.exception : enforce;\n    import std.internal.test.dummyrange : DummyRange, Length, RangeType, ReturnBy;\n\n    void test(int[] input, int[] witness)\n    {\n        enforce(equal(radial(input), witness),\n                text(radial(input), \" vs. \", witness));\n    }\n    test([], []);\n    test([ 1 ], [ 1 ]);\n    test([ 1, 2 ], [ 1, 2 ]);\n    test([ 1, 2, 3 ], [ 2, 3, 1 ]);\n    test([ 1, 2, 3, 4 ], [ 2, 3, 1, 4 ]);\n    test([ 1, 2, 3, 4, 5 ], [ 3, 4, 2, 5, 1 ]);\n    test([ 1, 2, 3, 4, 5, 6 ], [ 3, 4, 2, 5, 1, 6 ]);\n\n    int[] a = [ 1, 2, 3, 4, 5 ];\n    assert(equal(radial(a, 1), [ 2, 3, 1, 4, 5 ]));\n    assert(equal(radial(a, 0), [ 1, 2, 3, 4, 5 ])); // only right subrange\n    assert(equal(radial(a, a.length), [ 5, 4, 3, 2, 1 ])); // only left subrange\n    static assert(isForwardRange!(typeof(radial(a, 1))));\n\n    auto r = radial([1,2,3,4,5]);\n    for (auto rr = r.save; !rr.empty; rr.popFront())\n    {\n        assert(rr.front == moveFront(rr));\n    }\n    r.front = 5;\n    assert(r.front == 5);\n\n    // Test instantiation without lvalue elements.\n    DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Random) dummy;\n    assert(equal(radial(dummy, 4), [5, 6, 4, 7, 3, 8, 2, 9, 1, 10]));\n\n    // immutable int[] immi = [ 1, 2 ];\n    // static assert(is(typeof(radial(immi))));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto LL = iota(1L, 6L);\n    auto r = radial(LL);\n    assert(equal(r, [3L, 4L, 2L, 5L, 1L]));\n}\n\n/**\nLazily takes only up to `n` elements of a range. This is\nparticularly useful when using with infinite ranges.\n\nUnlike $(LREF takeExactly), `take` does not require that there\nare `n` or more elements in `input`. As a consequence, length\ninformation is not applied to the result unless `input` also has\nlength information.\n\nParams:\n    input = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    to iterate over up to `n` times\n    n = the number of elements to take\n\nReturns:\n    At minimum, an input range. If the range offers random access\n    and `length`, `take` offers them as well.\n */\nTake!R take(R)(R input, size_t n)\nif (isInputRange!(Unqual!R))\n{\n    alias U = Unqual!R;\n    static if (is(R T == Take!T))\n    {\n        import std.algorithm.comparison : min;\n        return R(input.source, min(n, input._maxAvailable));\n    }\n    else static if (!isInfinite!U && hasSlicing!U)\n    {\n        import std.algorithm.comparison : min;\n        return input[0 .. min(n, input.length)];\n    }\n    else\n    {\n        return Take!R(input, n);\n    }\n}\n\n/// ditto\nstruct Take(Range)\nif (isInputRange!(Unqual!Range) &&\n    //take _cannot_ test hasSlicing on infinite ranges, because hasSlicing uses\n    //take for slicing infinite ranges.\n    !((!isInfinite!(Unqual!Range) && hasSlicing!(Unqual!Range)) || is(Range T == Take!T)))\n{\n    private alias R = Unqual!Range;\n\n    /// User accessible in read and write\n    public R source;\n\n    private size_t _maxAvailable;\n\n    alias Source = R;\n\n    /// Range primitives\n    @property bool empty()\n    {\n        return _maxAvailable == 0 || source.empty;\n    }\n\n    /// ditto\n    @property auto ref front()\n    {\n        assert(!empty,\n            \"Attempting to fetch the front of an empty \"\n            ~ Take.stringof);\n        return source.front;\n    }\n\n    /// ditto\n    void popFront()\n    {\n        assert(!empty,\n            \"Attempting to popFront() past the end of a \"\n            ~ Take.stringof);\n        source.popFront();\n        --_maxAvailable;\n    }\n\n    static if (isForwardRange!R)\n        /// ditto\n        @property Take save()\n        {\n            return Take(source.save, _maxAvailable);\n        }\n\n    static if (hasAssignableElements!R)\n        /// ditto\n        @property void front(ElementType!R v)\n        {\n            assert(!empty,\n                \"Attempting to assign to the front of an empty \"\n                ~ Take.stringof);\n            // This has to return auto instead of void because of Bug 4706.\n            source.front = v;\n        }\n\n    static if (hasMobileElements!R)\n    {\n        /// ditto\n        auto moveFront()\n        {\n            assert(!empty,\n                \"Attempting to move the front of an empty \"\n                ~ Take.stringof);\n            return source.moveFront();\n        }\n    }\n\n    static if (isInfinite!R)\n    {\n        /// ditto\n        @property size_t length() const\n        {\n            return _maxAvailable;\n        }\n\n        /// ditto\n        alias opDollar = length;\n\n        //Note: Due to Take/hasSlicing circular dependency,\n        //This needs to be a restrained template.\n        /// ditto\n        auto opSlice()(size_t i, size_t j)\n        if (hasSlicing!R)\n        {\n            assert(i <= j, \"Invalid slice bounds\");\n            assert(j <= length, \"Attempting to slice past the end of a \"\n                ~ Take.stringof);\n            return source[i .. j];\n        }\n    }\n    else static if (hasLength!R)\n    {\n        /// ditto\n        @property size_t length()\n        {\n            import std.algorithm.comparison : min;\n            return min(_maxAvailable, source.length);\n        }\n\n        alias opDollar = length;\n    }\n\n    static if (isRandomAccessRange!R)\n    {\n        /// ditto\n        void popBack()\n        {\n            assert(!empty,\n                \"Attempting to popBack() past the beginning of a \"\n                ~ Take.stringof);\n            --_maxAvailable;\n        }\n\n        /// ditto\n        @property auto ref back()\n        {\n            assert(!empty,\n                \"Attempting to fetch the back of an empty \"\n                ~ Take.stringof);\n            return source[this.length - 1];\n        }\n\n        /// ditto\n        auto ref opIndex(size_t index)\n        {\n            assert(index < length,\n                \"Attempting to index out of the bounds of a \"\n                ~ Take.stringof);\n            return source[index];\n        }\n\n        static if (hasAssignableElements!R)\n        {\n            /// ditto\n            @property void back(ElementType!R v)\n            {\n                // This has to return auto instead of void because of Bug 4706.\n                assert(!empty,\n                    \"Attempting to assign to the back of an empty \"\n                    ~ Take.stringof);\n                source[this.length - 1] = v;\n            }\n\n            /// ditto\n            void opIndexAssign(ElementType!R v, size_t index)\n            {\n                assert(index < length,\n                    \"Attempting to index out of the bounds of a \"\n                    ~ Take.stringof);\n                source[index] = v;\n            }\n        }\n\n        static if (hasMobileElements!R)\n        {\n            /// ditto\n            auto moveBack()\n            {\n                assert(!empty,\n                    \"Attempting to move the back of an empty \"\n                    ~ Take.stringof);\n                return source.moveAt(this.length - 1);\n            }\n\n            /// ditto\n            auto moveAt(size_t index)\n            {\n                assert(index < length,\n                    \"Attempting to index out of the bounds of a \"\n                    ~ Take.stringof);\n                return source.moveAt(index);\n            }\n        }\n    }\n\n    /**\n    Access to maximal length of the range.\n    Note: the actual length of the range depends on the underlying range.\n    If it has fewer elements, it will stop before maxLength is reached.\n    */\n    @property size_t maxLength() const\n    {\n        return _maxAvailable;\n    }\n}\n\n/// ditto\ntemplate Take(R)\nif (isInputRange!(Unqual!R) &&\n    ((!isInfinite!(Unqual!R) && hasSlicing!(Unqual!R)) || is(R T == Take!T)))\n{\n    alias Take = R;\n}\n\n///\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[] arr1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\n    auto s = take(arr1, 5);\n    assert(s.length == 5);\n    assert(s[4] == 5);\n    assert(equal(s, [ 1, 2, 3, 4, 5 ][]));\n}\n\n/**\n * If the range runs out before `n` elements, `take` simply returns the entire\n * range (unlike $(LREF takeExactly), which will cause an assertion failure if\n * the range ends prematurely):\n */\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[] arr2 = [ 1, 2, 3 ];\n    auto t = take(arr2, 5);\n    assert(t.length == 3);\n    assert(equal(t, [ 1, 2, 3 ]));\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges;\n\n    int[] arr1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\n    auto s = take(arr1, 5);\n    assert(s.length == 5);\n    assert(s[4] == 5);\n    assert(equal(s, [ 1, 2, 3, 4, 5 ][]));\n    assert(equal(retro(s), [ 5, 4, 3, 2, 1 ][]));\n\n    // Test fix for bug 4464.\n    static assert(is(typeof(s) == Take!(int[])));\n    static assert(is(typeof(s) == int[]));\n\n    // Test using narrow strings.\n    import std.exception : assumeWontThrow;\n\n    auto myStr = \"This is a string.\";\n    auto takeMyStr = take(myStr, 7);\n    assert(assumeWontThrow(equal(takeMyStr, \"This is\")));\n    // Test fix for bug 5052.\n    auto takeMyStrAgain = take(takeMyStr, 4);\n    assert(assumeWontThrow(equal(takeMyStrAgain, \"This\")));\n    static assert(is (typeof(takeMyStrAgain) == typeof(takeMyStr)));\n    takeMyStrAgain = take(takeMyStr, 10);\n    assert(assumeWontThrow(equal(takeMyStrAgain, \"This is\")));\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        DummyType dummy;\n        auto t = take(dummy, 5);\n        alias T = typeof(t);\n\n        static if (isRandomAccessRange!DummyType)\n        {\n            static assert(isRandomAccessRange!T);\n            assert(t[4] == 5);\n\n            assert(moveAt(t, 1) == t[1]);\n            assert(t.back == moveBack(t));\n        }\n        else static if (isForwardRange!DummyType)\n        {\n            static assert(isForwardRange!T);\n        }\n\n        for (auto tt = t; !tt.empty; tt.popFront())\n        {\n            assert(tt.front == moveFront(tt));\n        }\n\n        // Bidirectional ranges can't be propagated properly if they don't\n        // also have random access.\n\n        assert(equal(t, [1,2,3,4,5]));\n\n        //Test that take doesn't wrap the result of take.\n        assert(take(t, 4) == take(dummy, 4));\n    }\n\n    immutable myRepeat = repeat(1);\n    static assert(is(Take!(typeof(myRepeat))));\n}\n\npure @safe nothrow @nogc unittest\n{\n    //check for correct slicing of Take on an infinite range\n    import std.algorithm.comparison : equal;\n    foreach (start; 0 .. 4)\n        foreach (stop; start .. 4)\n            assert(iota(4).cycle.take(4)[start .. stop]\n                .equal(iota(start, stop)));\n}\n\npure @safe nothrow @nogc unittest\n{\n    // Check that one can declare variables of all Take types,\n    // and that they match the return type of the corresponding\n    // take().  (See issue 4464.)\n    int[] r1;\n    Take!(int[]) t1;\n    t1 = take(r1, 1);\n    assert(t1.empty);\n\n    string r2;\n    Take!string t2;\n    t2 = take(r2, 1);\n    assert(t2.empty);\n\n    Take!(Take!string) t3;\n    t3 = take(t2, 1);\n    assert(t3.empty);\n}\n\npure @safe nothrow @nogc unittest\n{\n    alias R1 = typeof(repeat(1));\n    alias R2 = typeof(cycle([1]));\n    alias TR1 = Take!R1;\n    alias TR2 = Take!R2;\n    static assert(isBidirectionalRange!TR1);\n    static assert(isBidirectionalRange!TR2);\n}\n\npure @safe nothrow @nogc unittest //12731\n{\n    auto a = repeat(1);\n    auto s = a[1 .. 5];\n    s = s[1 .. 3];\n    assert(s.length == 2);\n    assert(s[0] == 1);\n    assert(s[1] == 1);\n}\n\npure @safe nothrow @nogc unittest //13151\n{\n    import std.algorithm.comparison : equal;\n\n    auto r = take(repeat(1, 4), 3);\n    assert(r.take(2).equal(repeat(1, 2)));\n}\n\n\n/**\nSimilar to $(LREF take), but assumes that `range` has at least $(D\nn) elements. Consequently, the result of $(D takeExactly(range, n))\nalways defines the `length` property (and initializes it to `n`)\neven when `range` itself does not define `length`.\n\nThe result of `takeExactly` is identical to that of $(LREF take) in\ncases where the original range defines `length` or is infinite.\n\nUnlike $(LREF take), however, it is illegal to pass a range with less than\n`n` elements to `takeExactly`; this will cause an assertion failure.\n */\nauto takeExactly(R)(R range, size_t n)\nif (isInputRange!R)\n{\n    static if (is(typeof(takeExactly(range._input, n)) == R))\n    {\n        assert(n <= range._n,\n               \"Attempted to take more than the length of the range with takeExactly.\");\n        // takeExactly(takeExactly(r, n1), n2) has the same type as\n        // takeExactly(r, n1) and simply returns takeExactly(r, n2)\n        range._n = n;\n        return range;\n    }\n    //Also covers hasSlicing!R for finite ranges.\n    else static if (hasLength!R)\n    {\n        assert(n <= range.length,\n               \"Attempted to take more than the length of the range with takeExactly.\");\n        return take(range, n);\n    }\n    else static if (isInfinite!R)\n        return Take!R(range, n);\n    else\n    {\n        static struct Result\n        {\n            R _input;\n            private size_t _n;\n\n            @property bool empty() const { return !_n; }\n            @property auto ref front()\n            {\n                assert(_n > 0, \"front() on an empty \" ~ Result.stringof);\n                return _input.front;\n            }\n            void popFront() { _input.popFront(); --_n; }\n            @property size_t length() const { return _n; }\n            alias opDollar = length;\n\n            @property auto _takeExactly_Result_asTake()\n            {\n                return take(_input, _n);\n            }\n\n            alias _takeExactly_Result_asTake this;\n\n            static if (isForwardRange!R)\n                @property auto save()\n                {\n                    return Result(_input.save, _n);\n                }\n\n            static if (hasMobileElements!R)\n            {\n                auto moveFront()\n                {\n                    assert(!empty,\n                        \"Attempting to move the front of an empty \"\n                        ~ typeof(this).stringof);\n                    return _input.moveFront();\n                }\n            }\n\n            static if (hasAssignableElements!R)\n            {\n                @property auto ref front(ElementType!R v)\n                {\n                    assert(!empty,\n                        \"Attempting to assign to the front of an empty \"\n                        ~ typeof(this).stringof);\n                    return _input.front = v;\n                }\n            }\n        }\n\n        return Result(range, n);\n    }\n}\n\n///\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto a = [ 1, 2, 3, 4, 5 ];\n\n    auto b = takeExactly(a, 3);\n    assert(equal(b, [1, 2, 3]));\n    static assert(is(typeof(b.length) == size_t));\n    assert(b.length == 3);\n    assert(b.front == 1);\n    assert(b.back == 3);\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter;\n\n    auto a = [ 1, 2, 3, 4, 5 ];\n    auto b = takeExactly(a, 3);\n    assert(equal(b, [1, 2, 3]));\n    auto c = takeExactly(b, 2);\n    assert(equal(c, [1, 2]));\n\n\n\n    auto d = filter!\"a > 2\"(a);\n    auto e = takeExactly(d, 3);\n    assert(equal(e, [3, 4, 5]));\n    static assert(is(typeof(e.length) == size_t));\n    assert(e.length == 3);\n    assert(e.front == 3);\n\n    assert(equal(takeExactly(e, 3), [3, 4, 5]));\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges;\n\n    auto a = [ 1, 2, 3, 4, 5 ];\n    //Test that take and takeExactly are the same for ranges which define length\n    //but aren't sliceable.\n    struct L\n    {\n        @property auto front() { return _arr[0]; }\n        @property bool empty() { return _arr.empty; }\n        void popFront() { _arr.popFront(); }\n        @property size_t length() { return _arr.length; }\n        int[] _arr;\n    }\n    static assert(is(typeof(take(L(a), 3)) == typeof(takeExactly(L(a), 3))));\n    assert(take(L(a), 3) == takeExactly(L(a), 3));\n\n    //Test that take and takeExactly are the same for ranges which are sliceable.\n    static assert(is(typeof(take(a, 3)) == typeof(takeExactly(a, 3))));\n    assert(take(a, 3) == takeExactly(a, 3));\n\n    //Test that take and takeExactly are the same for infinite ranges.\n    auto inf = repeat(1);\n    static assert(is(typeof(take(inf, 5)) == Take!(typeof(inf))));\n    assert(take(inf, 5) == takeExactly(inf, 5));\n\n    //Test that take and takeExactly are _not_ the same for ranges which don't\n    //define length.\n    static assert(!is(typeof(take(filter!\"true\"(a), 3)) == typeof(takeExactly(filter!\"true\"(a), 3))));\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        {\n            DummyType dummy;\n            auto t = takeExactly(dummy, 5);\n\n            //Test that takeExactly doesn't wrap the result of takeExactly.\n            assert(takeExactly(t, 4) == takeExactly(dummy, 4));\n        }\n\n        static if (hasMobileElements!DummyType)\n        {\n            {\n                auto t = takeExactly(DummyType.init, 4);\n                assert(t.moveFront() == 1);\n                assert(equal(t, [1, 2, 3, 4]));\n            }\n        }\n\n        static if (hasAssignableElements!DummyType)\n        {\n            {\n                auto t = takeExactly(DummyType.init, 4);\n                t.front = 9;\n                assert(equal(t, [9, 2, 3, 4]));\n            }\n        }\n    }\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : DummyRange, Length, RangeType, ReturnBy;\n\n    alias DummyType = DummyRange!(ReturnBy.Value, Length.No, RangeType.Forward);\n    auto te = takeExactly(DummyType(), 5);\n    Take!DummyType t = te;\n    assert(equal(t, [1, 2, 3, 4, 5]));\n    assert(equal(t, te));\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=18092\n// can't combine take and takeExactly\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges;\n\n    static foreach (Range; AllDummyRanges)\n    {{\n        Range r;\n        assert(r.take(6).takeExactly(2).equal([1, 2]));\n        assert(r.takeExactly(6).takeExactly(2).equal([1, 2]));\n        assert(r.takeExactly(6).take(2).equal([1, 2]));\n    }}\n}\n\n/**\nReturns a range with at most one element; for example, $(D\ntakeOne([42, 43, 44])) returns a range consisting of the integer $(D\n42). Calling `popFront()` off that range renders it empty.\n\nIn effect `takeOne(r)` is somewhat equivalent to $(D take(r, 1)) but in\ncertain interfaces it is important to know statically that the range may only\nhave at most one element.\n\nThe type returned by `takeOne` is a random-access range with length\nregardless of `R`'s capabilities, as long as it is a forward range.\n(another feature that distinguishes `takeOne` from `take`). If\n(D R) is an input range but not a forward range, return type is an input\nrange with all random-access capabilities except save.\n */\nauto takeOne(R)(R source)\nif (isInputRange!R)\n{\n    static if (hasSlicing!R)\n    {\n        return source[0 .. !source.empty];\n    }\n    else\n    {\n        static struct Result\n        {\n            private R _source;\n            private bool _empty = true;\n            @property bool empty() const { return _empty; }\n            @property auto ref front()\n            {\n                assert(!empty, \"Attempting to fetch the front of an empty takeOne\");\n                return _source.front;\n            }\n            void popFront()\n            {\n                assert(!empty, \"Attempting to popFront an empty takeOne\");\n                _source.popFront();\n                _empty = true;\n            }\n            void popBack()\n            {\n                assert(!empty, \"Attempting to popBack an empty takeOne\");\n                _source.popFront();\n                _empty = true;\n            }\n            static if (isForwardRange!(Unqual!R))\n            {\n                @property auto save() { return Result(_source.save, empty); }\n            }\n            @property auto ref back()\n            {\n                assert(!empty, \"Attempting to fetch the back of an empty takeOne\");\n                return _source.front;\n            }\n            @property size_t length() const { return !empty; }\n            alias opDollar = length;\n            auto ref opIndex(size_t n)\n            {\n                assert(n < length, \"Attempting to index a takeOne out of bounds\");\n                return _source.front;\n            }\n            auto opSlice(size_t m, size_t n)\n            {\n                assert(m <= n && n < length, \"Attempting to index a takeOne out of bounds\");\n                return n > m ? this : Result(_source, false);\n            }\n            // Non-standard property\n            @property R source() { return _source; }\n        }\n\n        return Result(source, source.empty);\n    }\n}\n\n///\npure @safe nothrow unittest\n{\n    auto s = takeOne([42, 43, 44]);\n    static assert(isRandomAccessRange!(typeof(s)));\n    assert(s.length == 1);\n    assert(!s.empty);\n    assert(s.front == 42);\n    s.front = 43;\n    assert(s.front == 43);\n    assert(s.back == 43);\n    assert(s[0] == 43);\n    s.popFront();\n    assert(s.length == 0);\n    assert(s.empty);\n}\n\npure @safe nothrow @nogc unittest\n{\n    struct NonForwardRange\n    {\n        enum empty = false;\n        int front() { return 42; }\n        void popFront() {}\n    }\n\n    static assert(!isForwardRange!NonForwardRange);\n\n    auto s = takeOne(NonForwardRange());\n    assert(s.front == 42);\n}\n\n//guards against issue 16999\npure @safe unittest\n{\n    auto myIota = new class\n    {\n        int front = 0;\n        @safe void popFront(){front++;}\n        enum empty = false;\n    };\n    auto iotaPart = myIota.takeOne;\n    int sum;\n    foreach (var; chain(iotaPart, iotaPart, iotaPart))\n    {\n        sum += var;\n    }\n    assert(sum == 3);\n    assert(iotaPart.front == 3);\n}\n\n/++\n    Returns an empty range which is statically known to be empty and is\n    guaranteed to have `length` and be random access regardless of `R`'s\n    capabilities.\n  +/\nauto takeNone(R)()\nif (isInputRange!R)\n{\n    return typeof(takeOne(R.init)).init;\n}\n\n///\npure @safe nothrow @nogc unittest\n{\n    auto range = takeNone!(int[])();\n    assert(range.length == 0);\n    assert(range.empty);\n}\n\npure @safe nothrow @nogc unittest\n{\n    enum ctfe = takeNone!(int[])();\n    static assert(ctfe.length == 0);\n    static assert(ctfe.empty);\n}\n\n\n/++\n    Creates an empty range from the given range in $(BIGOH 1). If it can, it\n    will return the same range type. If not, it will return\n    $(D takeExactly(range, 0)).\n  +/\nauto takeNone(R)(R range)\nif (isInputRange!R)\n{\n    import std.traits : isDynamicArray;\n    //Makes it so that calls to takeNone which don't use UFCS still work with a\n    //member version if it's defined.\n    static if (is(typeof(R.takeNone)))\n        auto retval = range.takeNone();\n    //@@@BUG@@@ 8339\n    else static if (isDynamicArray!R)/+ ||\n                   (is(R == struct) && __traits(compiles, {auto r = R.init;}) && R.init.empty))+/\n    {\n        auto retval = R.init;\n    }\n    //An infinite range sliced at [0 .. 0] would likely still not be empty...\n    else static if (hasSlicing!R && !isInfinite!R)\n        auto retval = range[0 .. 0];\n    else\n        auto retval = takeExactly(range, 0);\n\n    //@@@BUG@@@ 7892 prevents this from being done in an out block.\n    assert(retval.empty);\n    return retval;\n}\n\n///\npure @safe nothrow unittest\n{\n    import std.algorithm.iteration : filter;\n    assert(takeNone([42, 27, 19]).empty);\n    assert(takeNone(\"dlang.org\").empty);\n    assert(takeNone(filter!\"true\"([42, 27, 19])).empty);\n}\n\n@safe unittest\n{\n    import std.algorithm.iteration : filter;\n    import std.meta : AliasSeq;\n\n    struct Dummy\n    {\n        mixin template genInput()\n        {\n        @safe:\n            @property bool empty() { return _arr.empty; }\n            @property auto front() { return _arr.front; }\n            void popFront() { _arr.popFront(); }\n            static assert(isInputRange!(typeof(this)));\n        }\n    }\n    alias genInput = Dummy.genInput;\n\n    static struct NormalStruct\n    {\n        //Disabled to make sure that the takeExactly version is used.\n        @disable this();\n        this(int[] arr) { _arr = arr; }\n        mixin genInput;\n        int[] _arr;\n    }\n\n    static struct SliceStruct\n    {\n        @disable this();\n        this(int[] arr) { _arr = arr; }\n        mixin genInput;\n        @property auto save() { return this; }\n        auto opSlice(size_t i, size_t j) { return typeof(this)(_arr[i .. j]); }\n        @property size_t length() { return _arr.length; }\n        int[] _arr;\n    }\n\n    static struct InitStruct\n    {\n        mixin genInput;\n        int[] _arr;\n    }\n\n    static struct TakeNoneStruct\n    {\n        this(int[] arr) { _arr = arr; }\n        @disable this();\n        mixin genInput;\n        auto takeNone() { return typeof(this)(null); }\n        int[] _arr;\n    }\n\n    static class NormalClass\n    {\n        this(int[] arr) {_arr = arr;}\n        mixin genInput;\n        int[] _arr;\n    }\n\n    static class SliceClass\n    {\n    @safe:\n        this(int[] arr) { _arr = arr; }\n        mixin genInput;\n        @property auto save() { return new typeof(this)(_arr); }\n        auto opSlice(size_t i, size_t j) { return new typeof(this)(_arr[i .. j]); }\n        @property size_t length() { return _arr.length; }\n        int[] _arr;\n    }\n\n    static class TakeNoneClass\n    {\n    @safe:\n        this(int[] arr) { _arr = arr; }\n        mixin genInput;\n        auto takeNone() { return new typeof(this)(null); }\n        int[] _arr;\n    }\n\n    import std.format : format;\n\n    static foreach (range; AliasSeq!([1, 2, 3, 4, 5],\n                             \"hello world\",\n                             \"hello world\"w,\n                             \"hello world\"d,\n                             SliceStruct([1, 2, 3]),\n                             //@@@BUG@@@ 8339 forces this to be takeExactly\n                             //`InitStruct([1, 2, 3]),\n                             TakeNoneStruct([1, 2, 3])))\n    {\n        static assert(takeNone(range).empty, typeof(range).stringof);\n        assert(takeNone(range).empty);\n        static assert(is(typeof(range) == typeof(takeNone(range))), typeof(range).stringof);\n    }\n\n    static foreach (range; AliasSeq!(NormalStruct([1, 2, 3]),\n                             InitStruct([1, 2, 3])))\n    {\n        static assert(takeNone(range).empty, typeof(range).stringof);\n        assert(takeNone(range).empty);\n        static assert(is(typeof(takeExactly(range, 0)) == typeof(takeNone(range))), typeof(range).stringof);\n    }\n\n    //Don't work in CTFE.\n    auto normal = new NormalClass([1, 2, 3]);\n    assert(takeNone(normal).empty);\n    static assert(is(typeof(takeExactly(normal, 0)) == typeof(takeNone(normal))), typeof(normal).stringof);\n\n    auto slice = new SliceClass([1, 2, 3]);\n    assert(takeNone(slice).empty);\n    static assert(is(SliceClass == typeof(takeNone(slice))), typeof(slice).stringof);\n\n    auto taken = new TakeNoneClass([1, 2, 3]);\n    assert(takeNone(taken).empty);\n    static assert(is(TakeNoneClass == typeof(takeNone(taken))), typeof(taken).stringof);\n\n    auto filtered = filter!\"true\"([1, 2, 3, 4, 5]);\n    assert(takeNone(filtered).empty);\n    //@@@BUG@@@ 8339 and 5941 force this to be takeExactly\n    //static assert(is(typeof(filtered) == typeof(takeNone(filtered))), typeof(filtered).stringof);\n}\n\n/++\n + Return a range advanced to within `_n` elements of the end of\n + `range`.\n +\n + Intended as the range equivalent of the Unix\n + $(HTTP en.wikipedia.org/wiki/Tail_%28Unix%29, _tail) utility. When the length\n + of `range` is less than or equal to `_n`, `range` is returned\n + as-is.\n +\n + Completes in $(BIGOH 1) steps for ranges that support slicing and have\n + length. Completes in $(BIGOH range.length) time for all other ranges.\n +\n + Params:\n +    range = range to get _tail of\n +    n = maximum number of elements to include in _tail\n +\n + Returns:\n +    Returns the _tail of `range` augmented with length information\n +/\nauto tail(Range)(Range range, size_t n)\nif (isInputRange!Range && !isInfinite!Range &&\n    (hasLength!Range || isForwardRange!Range))\n{\n    static if (hasLength!Range)\n    {\n        immutable length = range.length;\n        if (n >= length)\n            return range.takeExactly(length);\n        else\n            return range.drop(length - n).takeExactly(n);\n    }\n    else\n    {\n        Range scout = range.save;\n        foreach (immutable i; 0 .. n)\n        {\n            if (scout.empty)\n                return range.takeExactly(i);\n            scout.popFront();\n        }\n\n        auto tail = range.save;\n        while (!scout.empty)\n        {\n            assert(!tail.empty);\n            scout.popFront();\n            tail.popFront();\n        }\n\n        return tail.takeExactly(n);\n    }\n}\n\n///\npure @safe nothrow unittest\n{\n    // tail -c n\n    assert([1, 2, 3].tail(1) == [3]);\n    assert([1, 2, 3].tail(2) == [2, 3]);\n    assert([1, 2, 3].tail(3) == [1, 2, 3]);\n    assert([1, 2, 3].tail(4) == [1, 2, 3]);\n    assert([1, 2, 3].tail(0).length == 0);\n\n    // tail --lines=n\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : joiner;\n    import std.exception : assumeWontThrow;\n    import std.string : lineSplitter;\n    assert(\"one\\ntwo\\nthree\"\n        .lineSplitter\n        .tail(2)\n        .joiner(\"\\n\")\n        .equal(\"two\\nthree\")\n        .assumeWontThrow);\n}\n\n// @nogc prevented by @@@BUG@@@ 15408\npure nothrow @safe /+@nogc+/ unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges, DummyRange, Length,\n        RangeType, ReturnBy;\n\n    static immutable cheatsheet = [6, 7, 8, 9, 10];\n\n    foreach (R; AllDummyRanges)\n    {\n        static if (isInputRange!R && !isInfinite!R &&\n                   (hasLength!R || isForwardRange!R))\n        {\n            assert(R.init.tail(5).equal(cheatsheet));\n            static assert(R.init.tail(5).equal(cheatsheet));\n\n            assert(R.init.tail(0).length == 0);\n            assert(R.init.tail(10).equal(R.init));\n            assert(R.init.tail(11).equal(R.init));\n        }\n    }\n\n    // Infinite ranges are not supported\n    static assert(!__traits(compiles, repeat(0).tail(0)));\n\n    // Neither are non-forward ranges without length\n    static assert(!__traits(compiles, DummyRange!(ReturnBy.Value, Length.No,\n        RangeType.Input).init.tail(5)));\n}\n\npure @safe nothrow @nogc unittest\n{\n    static immutable input = [1, 2, 3];\n    static immutable expectedOutput = [2, 3];\n    assert(input.tail(2) == expectedOutput);\n}\n\n/++\n    Convenience function which calls\n    $(REF popFrontN, std, range, primitives)`(range, n)` and returns `range`.\n    `drop` makes it easier to pop elements from a range\n    and then pass it to another function within a single expression,\n    whereas `popFrontN` would require multiple statements.\n\n    `dropBack` provides the same functionality but instead calls\n    $(REF popBackN, std, range, primitives)`(range, n)`\n\n    Note: `drop` and `dropBack` will only pop $(I up to)\n    `n` elements but will stop if the range is empty first.\n    In other languages this is sometimes called `skip`.\n\n    Params:\n        range = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to drop from\n        n = the number of elements to drop\n\n    Returns:\n        `range` with up to `n` elements dropped\n\n    See_Also:\n        $(REF popFront, std, range, primitives), $(REF popBackN, std, range, primitives)\n  +/\nR drop(R)(R range, size_t n)\nif (isInputRange!R)\n{\n    range.popFrontN(n);\n    return range;\n}\n/// ditto\nR dropBack(R)(R range, size_t n)\nif (isBidirectionalRange!R)\n{\n    range.popBackN(n);\n    return range;\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert([0, 2, 1, 5, 0, 3].drop(3) == [5, 0, 3]);\n    assert(\"hello world\".drop(6) == \"world\");\n    assert(\"hello world\".drop(50).empty);\n    assert(\"hello world\".take(6).drop(3).equal(\"lo \"));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert([0, 2, 1, 5, 0, 3].dropBack(3) == [0, 2, 1]);\n    assert(\"hello world\".dropBack(6) == \"hello\");\n    assert(\"hello world\".dropBack(50).empty);\n    assert(\"hello world\".drop(4).dropBack(4).equal(\"o w\"));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container.dlist : DList;\n\n    //Remove all but the first two elements\n    auto a = DList!int(0, 1, 9, 9, 9, 9);\n    a.remove(a[].drop(2));\n    assert(a[].equal(a[].take(2)));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter;\n\n    assert(drop(\"\", 5).empty);\n    assert(equal(drop(filter!\"true\"([0, 2, 1, 5, 0, 3]), 3), [5, 0, 3]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.container.dlist : DList;\n\n    //insert before the last two elements\n    auto a = DList!int(0, 1, 2, 5, 6);\n    a.insertAfter(a[].dropBack(2), [3, 4]);\n    assert(a[].equal(iota(0, 7)));\n}\n\n/++\n    Similar to $(LREF drop) and `dropBack` but they call\n    $(D range.$(LREF popFrontExactly)(n)) and `range.popBackExactly(n)`\n    instead.\n\n    Note: Unlike `drop`, `dropExactly` will assume that the\n    range holds at least `n` elements. This makes `dropExactly`\n    faster than `drop`, but it also means that if `range` does\n    not contain at least `n` elements, it will attempt to call `popFront`\n    on an empty range, which is undefined behavior. So, only use\n    `popFrontExactly` when it is guaranteed that `range` holds at least\n    `n` elements.\n\n    Params:\n        range = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to drop from\n        n = the number of elements to drop\n\n    Returns:\n        `range` with `n` elements dropped\n\n    See_Also:\n        $(REF popFrontExcatly, std, range, primitives),\n        $(REF popBackExcatly, std, range, primitives)\n+/\nR dropExactly(R)(R range, size_t n)\nif (isInputRange!R)\n{\n    popFrontExactly(range, n);\n    return range;\n}\n/// ditto\nR dropBackExactly(R)(R range, size_t n)\nif (isBidirectionalRange!R)\n{\n    popBackExactly(range, n);\n    return range;\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filterBidirectional;\n\n    auto a = [1, 2, 3];\n    assert(a.dropExactly(2) == [3]);\n    assert(a.dropBackExactly(2) == [1]);\n\n    string s = \"日本語\";\n    assert(s.dropExactly(2) == \"語\");\n    assert(s.dropBackExactly(2) == \"日\");\n\n    auto bd = filterBidirectional!\"true\"([1, 2, 3]);\n    assert(bd.dropExactly(2).equal([3]));\n    assert(bd.dropBackExactly(2).equal([1]));\n}\n\n/++\n    Convenience function which calls\n    `range.popFront()` and returns `range`. `dropOne`\n    makes it easier to pop an element from a range\n    and then pass it to another function within a single expression,\n    whereas `popFront` would require multiple statements.\n\n    `dropBackOne` provides the same functionality but instead calls\n    `range.popBack()`.\n+/\nR dropOne(R)(R range)\nif (isInputRange!R)\n{\n    range.popFront();\n    return range;\n}\n/// ditto\nR dropBackOne(R)(R range)\nif (isBidirectionalRange!R)\n{\n    range.popBack();\n    return range;\n}\n\n///\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filterBidirectional;\n    import std.container.dlist : DList;\n\n    auto dl = DList!int(9, 1, 2, 3, 9);\n    assert(dl[].dropOne().dropBackOne().equal([1, 2, 3]));\n\n    auto a = [1, 2, 3];\n    assert(a.dropOne() == [2, 3]);\n    assert(a.dropBackOne() == [1, 2]);\n\n    string s = \"日本語\";\n    import std.exception : assumeWontThrow;\n    assert(assumeWontThrow(s.dropOne() == \"本語\"));\n    assert(assumeWontThrow(s.dropBackOne() == \"日本\"));\n\n    auto bd = filterBidirectional!\"true\"([1, 2, 3]);\n    assert(bd.dropOne().equal([2, 3]));\n    assert(bd.dropBackOne().equal([1, 2]));\n}\n\n/**\nCreate a range which repeats one value.\n\nParams:\n    value = the _value to repeat\n    n = the number of times to repeat `value`\n\nReturns:\n    If `n` is not defined, an infinite random access range\n    with slicing.\n\n    If `n` is defined, a random access range with slicing.\n*/\nstruct Repeat(T)\n{\nprivate:\n    //Store a non-qualified T when possible: This is to make Repeat assignable\n    static if ((is(T == class) || is(T == interface)) && (is(T == const) || is(T == immutable)))\n    {\n        import std.typecons : Rebindable;\n        alias UT = Rebindable!T;\n    }\n    else static if (is(T : Unqual!T) && is(Unqual!T : T))\n        alias UT = Unqual!T;\n    else\n        alias UT = T;\n    UT _value;\n\npublic:\n    /// Range primitives\n    @property inout(T) front() inout { return _value; }\n\n    /// ditto\n    @property inout(T) back() inout { return _value; }\n\n    /// ditto\n    enum bool empty = false;\n\n    /// ditto\n    void popFront() {}\n\n    /// ditto\n    void popBack() {}\n\n    /// ditto\n    @property auto save() inout { return this; }\n\n    /// ditto\n    inout(T) opIndex(size_t) inout { return _value; }\n\n    /// ditto\n    auto opSlice(size_t i, size_t j)\n    in\n    {\n        assert(\n            i <= j,\n            \"Attempting to slice a Repeat with a larger first argument than the second.\"\n        );\n    }\n    do\n    {\n        return this.takeExactly(j - i);\n    }\n    private static struct DollarToken {}\n\n    /// ditto\n    enum opDollar = DollarToken.init;\n\n    /// ditto\n    auto opSlice(size_t, DollarToken) inout { return this; }\n}\n\n/// Ditto\nRepeat!T repeat(T)(T value) { return Repeat!T(value); }\n\n///\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(5.repeat().take(4).equal([5, 5, 5, 5]));\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto  r = repeat(5);\n    alias R = typeof(r);\n    static assert(isBidirectionalRange!R);\n    static assert(isForwardRange!R);\n    static assert(isInfinite!R);\n    static assert(hasSlicing!R);\n\n    assert(r.back == 5);\n    assert(r.front == 5);\n    assert(r.take(4).equal([ 5, 5, 5, 5 ]));\n    assert(r[0 .. 4].equal([ 5, 5, 5, 5 ]));\n\n    R r2 = r[5 .. $];\n    assert(r2.back == 5);\n    assert(r2.front == 5);\n}\n\n/// ditto\nTake!(Repeat!T) repeat(T)(T value, size_t n)\n{\n    return take(repeat(value), n);\n}\n\n///\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(5.repeat(4).equal([5, 5, 5, 5]));\n}\n\npure @safe nothrow unittest //12007\n{\n    static class C{}\n    Repeat!(immutable int) ri;\n    ri = ri.save;\n    Repeat!(immutable C) rc;\n    rc = rc.save;\n\n    import std.algorithm.setops : cartesianProduct;\n    import std.algorithm.comparison : equal;\n    import std.typecons : tuple;\n    immutable int[] A = [1,2,3];\n    immutable int[] B = [4,5,6];\n\n    assert(equal(cartesianProduct(A,B),\n        [\n            tuple(1, 4), tuple(1, 5), tuple(1, 6),\n            tuple(2, 4), tuple(2, 5), tuple(2, 6),\n            tuple(3, 4), tuple(3, 5), tuple(3, 6),\n        ]));\n}\n\n/**\nGiven callable ($(REF isCallable, std,traits)) `fun`, create as a range\nwhose front is defined by successive calls to `fun()`.\nThis is especially useful to call function with global side effects (random\nfunctions), or to create ranges expressed as a single delegate, rather than\nan entire `front`/`popFront`/`empty` structure.\n`fun` maybe be passed either a template alias parameter (existing\nfunction, delegate, struct type defining `static opCall`) or\na run-time value argument (delegate, function object).\nThe result range models an InputRange\n($(REF isInputRange, std,range,primitives)).\nThe resulting range will call `fun()` on construction, and every call to\n`popFront`, and the cached value will be returned when `front` is called.\n\nReturns: an `inputRange` where each element represents another call to fun.\n*/\nauto generate(Fun)(Fun fun)\nif (isCallable!fun)\n{\n    auto gen = Generator!(Fun)(fun);\n    gen.popFront(); // prime the first element\n    return gen;\n}\n\n/// ditto\nauto generate(alias fun)()\nif (isCallable!fun)\n{\n    auto gen = Generator!(fun)();\n    gen.popFront(); // prime the first element\n    return gen;\n}\n\n///\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n\n    int i = 1;\n    auto powersOfTwo = generate!(() => i *= 2)().take(10);\n    assert(equal(powersOfTwo, iota(1, 11).map!\"2^^a\"()));\n}\n\n///\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    //Returns a run-time delegate\n    auto infiniteIota(T)(T low, T high)\n    {\n        T i = high;\n        return (){if (i == high) i = low; return i++;};\n    }\n    //adapted as a range.\n    assert(equal(generate(infiniteIota(1, 4)).take(10), [1, 2, 3, 1, 2, 3, 1, 2, 3, 1]));\n}\n\n///\n@safe unittest\n{\n    import std.format : format;\n    import std.random : uniform;\n\n    auto r = generate!(() => uniform(0, 6)).take(10);\n    format(\"%(%s %)\", r);\n}\n\nprivate struct Generator(Fun...)\n{\n    static assert(Fun.length == 1);\n    static assert(isInputRange!Generator);\n\nprivate:\n    static if (is(Fun[0]))\n        Fun[0] fun;\n    else\n        alias fun = Fun[0];\n\n    enum returnByRef_ = (functionAttributes!fun & FunctionAttribute.ref_) ? true : false;\n    static if (returnByRef_)\n        ReturnType!fun *elem_;\n    else\n        ReturnType!fun elem_;\npublic:\n    /// Range primitives\n    enum empty = false;\n\n    static if (returnByRef_)\n    {\n        /// ditto\n        ref front() @property\n        {\n            return *elem_;\n        }\n        /// ditto\n        void popFront()\n        {\n            elem_ = &fun();\n        }\n    }\n    else\n    {\n        /// ditto\n        auto front() @property\n        {\n            return elem_;\n        }\n        /// ditto\n        void popFront()\n        {\n            elem_ = fun();\n        }\n    }\n}\n\n@safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    struct StaticOpCall\n    {\n        static ubyte opCall() { return 5 ; }\n    }\n\n    assert(equal(generate!StaticOpCall().take(10), repeat(5).take(10)));\n}\n\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    struct OpCall\n    {\n        ubyte opCall() @safe pure { return 5 ; }\n    }\n\n    OpCall op;\n    assert(equal(generate(op).take(10), repeat(5).take(10)));\n}\n\n// verify ref mechanism works\n@system nothrow unittest\n{\n    int[10] arr;\n    int idx;\n\n    ref int fun() {\n        auto x = idx++;\n        idx %= arr.length;\n        return arr[x];\n    }\n    int y = 1;\n    foreach (ref x; generate!(fun).take(20))\n    {\n        x += y++;\n    }\n    import std.algorithm.comparison : equal;\n    assert(equal(arr[], iota(12, 32, 2)));\n}\n\n// assure front isn't the mechanism to make generate go to the next element.\n@safe unittest\n{\n    int i;\n    auto g = generate!(() => ++i);\n    auto f = g.front;\n    assert(f == g.front);\n    g = g.drop(5); // reassign because generate caches\n    assert(g.front == f + 5);\n}\n\n/**\nRepeats the given forward range ad infinitum. If the original range is\ninfinite (fact that would make `Cycle` the identity application),\n`Cycle` detects that and aliases itself to the range type\nitself. That works for non-forward ranges too.\nIf the original range has random access, `Cycle` offers\nrandom access and also offers a constructor taking an initial position\n`index`. `Cycle` works with static arrays in addition to ranges,\nmostly for performance reasons.\n\nNote: The input range must not be empty.\n\nTip: This is a great way to implement simple circular buffers.\n*/\nstruct Cycle(R)\nif (isForwardRange!R && !isInfinite!R)\n{\n    static if (isRandomAccessRange!R && hasLength!R)\n    {\n        private R _original;\n        private size_t _index;\n\n        /// Range primitives\n        this(R input, size_t index = 0)\n        {\n            _original = input;\n            _index = index % _original.length;\n        }\n\n        /// ditto\n        @property auto ref front()\n        {\n            return _original[_index];\n        }\n\n        static if (is(typeof((cast(const R)_original)[_index])))\n        {\n            /// ditto\n            @property auto ref front() const\n            {\n                return _original[_index];\n            }\n        }\n\n        static if (hasAssignableElements!R)\n        {\n            /// ditto\n            @property void front(ElementType!R val)\n            {\n                _original[_index] = val;\n            }\n        }\n\n        /// ditto\n        enum bool empty = false;\n\n        /// ditto\n        void popFront()\n        {\n            ++_index;\n            if (_index >= _original.length)\n                _index = 0;\n        }\n\n        /// ditto\n        auto ref opIndex(size_t n)\n        {\n            return _original[(n + _index) % _original.length];\n        }\n\n        static if (is(typeof((cast(const R)_original)[_index])) &&\n                   is(typeof((cast(const R)_original).length)))\n        {\n            /// ditto\n            auto ref opIndex(size_t n) const\n            {\n                return _original[(n + _index) % _original.length];\n            }\n        }\n\n        static if (hasAssignableElements!R)\n        {\n            /// ditto\n            void opIndexAssign(ElementType!R val, size_t n)\n            {\n                _original[(n + _index) % _original.length] = val;\n            }\n        }\n\n        /// ditto\n        @property Cycle save()\n        {\n            //No need to call _original.save, because Cycle never actually modifies _original\n            return Cycle(_original, _index);\n        }\n\n        private static struct DollarToken {}\n\n        /// ditto\n        enum opDollar = DollarToken.init;\n\n        static if (hasSlicing!R)\n        {\n            /// ditto\n            auto opSlice(size_t i, size_t j)\n            in\n            {\n                assert(i <= j);\n            }\n            do\n            {\n                return this[i .. $].takeExactly(j - i);\n            }\n\n            /// ditto\n            auto opSlice(size_t i, DollarToken)\n            {\n                return typeof(this)(_original, _index + i);\n            }\n        }\n    }\n    else\n    {\n        private R _original;\n        private R _current;\n\n        /// ditto\n        this(R input)\n        {\n            _original = input;\n            _current = input.save;\n        }\n\n        /// ditto\n        @property auto ref front()\n        {\n            return _current.front;\n        }\n\n        static if (is(typeof((cast(const R)_current).front)))\n        {\n            /// ditto\n            @property auto ref front() const\n            {\n                return _current.front;\n            }\n        }\n\n        static if (hasAssignableElements!R)\n        {\n            /// ditto\n            @property auto front(ElementType!R val)\n            {\n                return _current.front = val;\n            }\n        }\n\n        /// ditto\n        enum bool empty = false;\n\n        /// ditto\n        void popFront()\n        {\n            _current.popFront();\n            if (_current.empty)\n                _current = _original.save;\n        }\n\n        /// ditto\n        @property Cycle save()\n        {\n            //No need to call _original.save, because Cycle never actually modifies _original\n            Cycle ret = this;\n            ret._original = _original;\n            ret._current =  _current.save;\n            return ret;\n        }\n    }\n}\n\n/// ditto\ntemplate Cycle(R)\nif (isInfinite!R)\n{\n    alias Cycle = R;\n}\n\n/// ditto\nstruct Cycle(R)\nif (isStaticArray!R)\n{\n    private alias ElementType = typeof(R.init[0]);\n    private ElementType* _ptr;\n    private size_t _index;\n\nnothrow:\n\n    /// Range primitives\n    this(ref R input, size_t index = 0) @system\n    {\n        _ptr = input.ptr;\n        _index = index % R.length;\n    }\n\n    /// ditto\n    @property ref inout(ElementType) front() inout @safe\n    {\n        static ref auto trustedPtrIdx(typeof(_ptr) p, size_t idx) @trusted\n        {\n            return p[idx];\n        }\n        return trustedPtrIdx(_ptr, _index);\n    }\n\n    /// ditto\n    enum bool empty = false;\n\n    /// ditto\n    void popFront() @safe\n    {\n        ++_index;\n        if (_index >= R.length)\n            _index = 0;\n    }\n\n    /// ditto\n    ref inout(ElementType) opIndex(size_t n) inout @safe\n    {\n        static ref auto trustedPtrIdx(typeof(_ptr) p, size_t idx) @trusted\n        {\n            return p[idx % R.length];\n        }\n        return trustedPtrIdx(_ptr, n + _index);\n    }\n\n    /// ditto\n    @property inout(Cycle) save() inout @safe\n    {\n        return this;\n    }\n\n    private static struct DollarToken {}\n    /// ditto\n    enum opDollar = DollarToken.init;\n\n    /// ditto\n    auto opSlice(size_t i, size_t j) @safe\n    in\n    {\n        assert(\n            i <= j,\n            \"Attempting to slice a Repeat with a larger first argument than the second.\"\n        );\n    }\n    do\n    {\n        return this[i .. $].takeExactly(j - i);\n    }\n\n    /// ditto\n    inout(typeof(this)) opSlice(size_t i, DollarToken) inout @safe\n    {\n        static auto trustedCtor(typeof(_ptr) p, size_t idx) @trusted\n        {\n            return cast(inout) Cycle(*cast(R*)(p), idx);\n        }\n        return trustedCtor(_ptr, _index + i);\n    }\n}\n\n/// Ditto\nauto cycle(R)(R input)\nif (isInputRange!R)\n{\n    static assert(isForwardRange!R || isInfinite!R,\n        \"Cycle requires a forward range argument unless it's statically known\"\n         ~ \" to be infinite\");\n    assert(!input.empty, \"Attempting to pass an empty input to cycle\");\n    static if (isInfinite!R) return input;\n    else return Cycle!R(input);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : cycle, take;\n\n    // Here we create an infinitive cyclic sequence from [1, 2]\n    // (i.e. get here [1, 2, 1, 2, 1, 2 and so on]) then\n    // take 5 elements of this sequence (so we have [1, 2, 1, 2, 1])\n    // and compare them with the expected values for equality.\n    assert(cycle([1, 2]).take(5).equal([ 1, 2, 1, 2, 1 ]));\n}\n\n/// Ditto\nCycle!R cycle(R)(R input, size_t index = 0)\nif (isRandomAccessRange!R && !isInfinite!R)\n{\n    assert(!input.empty, \"Attempting to pass an empty input to cycle\");\n    return Cycle!R(input, index);\n}\n\n/// Ditto\nCycle!R cycle(R)(ref R input, size_t index = 0) @system\nif (isStaticArray!R)\n{\n    return Cycle!R(input, index);\n}\n\n@safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges;\n\n    static assert(isForwardRange!(Cycle!(uint[])));\n\n    // Make sure ref is getting propagated properly.\n    int[] nums = [1,2,3];\n    auto c2 = cycle(nums);\n    c2[3]++;\n    assert(nums[0] == 2);\n\n    immutable int[] immarr = [1, 2, 3];\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        static if (isForwardRange!DummyType)\n        {\n            DummyType dummy;\n            auto cy = cycle(dummy);\n            static assert(isForwardRange!(typeof(cy)));\n            auto t = take(cy, 20);\n            assert(equal(t, [1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10]));\n\n            const cRange = cy;\n            assert(cRange.front == 1);\n\n            static if (hasAssignableElements!DummyType)\n            {\n                {\n                    cy.front = 66;\n                    scope(exit) cy.front = 1;\n                    assert(dummy.front == 66);\n                }\n\n                static if (isRandomAccessRange!DummyType)\n                {\n                    {\n                        cy[10] = 66;\n                        scope(exit) cy[10] = 1;\n                        assert(dummy.front == 66);\n                    }\n\n                    assert(cRange[10] == 1);\n                }\n            }\n\n            static if (hasSlicing!DummyType)\n            {\n                auto slice = cy[5 .. 15];\n                assert(equal(slice, [6, 7, 8, 9, 10, 1, 2, 3, 4, 5]));\n                static assert(is(typeof(slice) == typeof(takeExactly(cy, 5))));\n\n                auto infSlice = cy[7 .. $];\n                assert(equal(take(infSlice, 5), [8, 9, 10, 1, 2]));\n                static assert(isInfinite!(typeof(infSlice)));\n            }\n        }\n    }\n}\n\n@system nothrow unittest // For static arrays.\n{\n    import std.algorithm.comparison : equal;\n\n    int[3] a = [ 1, 2, 3 ];\n    static assert(isStaticArray!(typeof(a)));\n    auto c = cycle(a);\n    assert(a.ptr == c._ptr);\n    assert(equal(take(cycle(a), 5), [ 1, 2, 3, 1, 2 ][]));\n    static assert(isForwardRange!(typeof(c)));\n\n    // Test qualifiers on slicing.\n    alias C = typeof(c);\n    static assert(is(typeof(c[1 .. $]) == C));\n    const cConst = c;\n    static assert(is(typeof(cConst[1 .. $]) == const(C)));\n}\n\n@safe nothrow unittest // For infinite ranges\n{\n    struct InfRange\n    {\n        void popFront() { }\n        @property int front() { return 0; }\n        enum empty = false;\n        auto save() { return this; }\n    }\n    struct NonForwardInfRange\n    {\n        void popFront() { }\n        @property int front() { return 0; }\n        enum empty = false;\n    }\n\n    InfRange i;\n    NonForwardInfRange j;\n    auto c = cycle(i);\n    assert(c == i);\n    //make sure it can alias out even non-forward infinite ranges\n    static assert(is(typeof(j.cycle) == typeof(j)));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[5] arr = [0, 1, 2, 3, 4];\n    auto cleD = cycle(arr[]); //Dynamic\n    assert(equal(cleD[5 .. 10], arr[]));\n\n    //n is a multiple of 5 worth about 3/4 of size_t.max\n    auto n = size_t.max/4 + size_t.max/2;\n    n -= n % 5;\n\n    //Test index overflow\n    foreach (_ ; 0 .. 10)\n    {\n        cleD = cleD[n .. $];\n        assert(equal(cleD[5 .. 10], arr[]));\n    }\n}\n\n@system @nogc nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[5] arr = [0, 1, 2, 3, 4];\n    auto cleS = cycle(arr);   //Static\n    assert(equal(cleS[5 .. 10], arr[]));\n\n    //n is a multiple of 5 worth about 3/4 of size_t.max\n    auto n = size_t.max/4 + size_t.max/2;\n    n -= n % 5;\n\n    //Test index overflow\n    foreach (_ ; 0 .. 10)\n    {\n        cleS = cleS[n .. $];\n        assert(equal(cleS[5 .. 10], arr[]));\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[1] arr = [0];\n    auto cleS = cycle(arr);\n    cleS = cleS[10 .. $];\n    assert(equal(cleS[5 .. 10], 0.repeat(5)));\n    assert(cleS.front == 0);\n}\n\n@system unittest //10845\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter;\n\n    auto a = inputRangeObject(iota(3).filter!\"true\");\n    assert(equal(cycle(a).take(10), [0, 1, 2, 0, 1, 2, 0, 1, 2, 0]));\n}\n\n@safe unittest // 12177\n{\n    static assert(__traits(compiles, recurrence!q{a[n - 1] ~ a[n - 2]}(\"1\", \"0\")));\n}\n\n// Issue 13390\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.exception : assertThrown;\n    assertThrown!AssertError(cycle([0, 1, 2][0 .. 0]));\n}\n\nprivate alias lengthType(R) = typeof(R.init.length.init);\n\n/**\n   Iterate several ranges in lockstep. The element type is a proxy tuple\n   that allows accessing the current element in the `n`th range by\n   using `e[n]`.\n\n   `zip` is similar to $(LREF lockstep), but `lockstep` doesn't\n   bundle its elements and uses the `opApply` protocol.\n   `lockstep` allows reference access to the elements in\n   `foreach` iterations.\n\n    Params:\n        sp = controls what `zip` will do if the ranges are different lengths\n        ranges = the ranges to zip together\n    Returns:\n        At minimum, an input range. `Zip` offers the lowest range facilities\n        of all components, e.g. it offers random access iff all ranges offer\n        random access, and also offers mutation and swapping if all ranges offer\n        it. Due to this, `Zip` is extremely powerful because it allows manipulating\n        several ranges in lockstep.\n    Throws:\n        An `Exception` if all of the ranges are not the same length and\n        `sp` is set to `StoppingPolicy.requireSameLength`.\n\n    Limitations: The `@nogc` and `nothrow` attributes cannot be inferred for\n    the `Zip` struct because $(LREF StoppingPolicy) can vary at runtime. This\n    limitation is not shared by the anonymous range returned by the `zip`\n    function when not given an explicit `StoppingPolicy` as an argument.\n*/\nstruct Zip(Ranges...)\nif (Ranges.length && allSatisfy!(isInputRange, Ranges))\n{\n    import std.format : format; //for generic mixins\n    import std.typecons : Tuple;\n\n    alias R = Ranges;\n    private R ranges;\n    alias ElementType = Tuple!(staticMap!(.ElementType, R));\n    private StoppingPolicy stoppingPolicy = StoppingPolicy.shortest;\n\n/**\n   Builds an object. Usually this is invoked indirectly by using the\n   $(LREF zip) function.\n */\n    this(R rs, StoppingPolicy s = StoppingPolicy.shortest)\n    {\n        ranges[] = rs[];\n        stoppingPolicy = s;\n    }\n\n/**\n   Returns `true` if the range is at end. The test depends on the\n   stopping policy.\n*/\n    static if (allSatisfy!(isInfinite, R))\n    {\n        // BUG:  Doesn't propagate infiniteness if only some ranges are infinite\n        //       and s == StoppingPolicy.longest.  This isn't fixable in the\n        //       current design since StoppingPolicy is known only at runtime.\n        enum bool empty = false;\n    }\n    else\n    {\n        ///\n        @property bool empty()\n        {\n            import std.exception : enforce;\n            import std.meta : anySatisfy;\n\n            final switch (stoppingPolicy)\n            {\n            case StoppingPolicy.shortest:\n                foreach (i, Unused; R)\n                {\n                    if (ranges[i].empty) return true;\n                }\n                return false;\n            case StoppingPolicy.longest:\n                static if (anySatisfy!(isInfinite, R))\n                {\n                    return false;\n                }\n                else\n                {\n                    foreach (i, Unused; R)\n                    {\n                        if (!ranges[i].empty) return false;\n                    }\n                    return true;\n                }\n            case StoppingPolicy.requireSameLength:\n                foreach (i, Unused; R[1 .. $])\n                {\n                    enforce(ranges[0].empty ==\n                            ranges[i + 1].empty,\n                            \"Inequal-length ranges passed to Zip\");\n                }\n                return ranges[0].empty;\n            }\n            assert(false);\n        }\n    }\n\n    static if (allSatisfy!(isForwardRange, R))\n    {\n        ///\n        @property Zip save()\n        {\n            //Zip(ranges[0].save, ranges[1].save, ..., stoppingPolicy)\n            return mixin (q{Zip(%(ranges[%s].save%|, %), stoppingPolicy)}.format(iota(0, R.length)));\n        }\n    }\n\n    private .ElementType!(R[i]) tryGetInit(size_t i)()\n    {\n        alias E = .ElementType!(R[i]);\n        static if (!is(typeof({static E i;})))\n            throw new Exception(\"Range with non-default constructable elements exhausted.\");\n        else\n            return E.init;\n    }\n\n/**\n   Returns the current iterated element.\n*/\n    @property ElementType front()\n    {\n        @property tryGetFront(size_t i)(){return ranges[i].empty ? tryGetInit!i() : ranges[i].front;}\n        //ElementType(tryGetFront!0, tryGetFront!1, ...)\n        return mixin(q{ElementType(%(tryGetFront!%s, %))}.format(iota(0, R.length)));\n    }\n\n/**\n   Sets the front of all iterated ranges.\n*/\n    static if (allSatisfy!(hasAssignableElements, R))\n    {\n        @property void front(ElementType v)\n        {\n            foreach (i, Unused; R)\n            {\n                if (!ranges[i].empty)\n                {\n                    ranges[i].front = v[i];\n                }\n            }\n        }\n    }\n\n/**\n   Moves out the front.\n*/\n    static if (allSatisfy!(hasMobileElements, R))\n    {\n        ElementType moveFront()\n        {\n            @property tryMoveFront(size_t i)(){return ranges[i].empty ? tryGetInit!i() : ranges[i].moveFront();}\n            //ElementType(tryMoveFront!0, tryMoveFront!1, ...)\n            return mixin(q{ElementType(%(tryMoveFront!%s, %))}.format(iota(0, R.length)));\n        }\n    }\n\n/**\n   Returns the rightmost element.\n*/\n    static if (allSatisfy!(isBidirectionalRange, R))\n    {\n        @property ElementType back()\n        {\n            //TODO: Fixme! BackElement != back of all ranges in case of jagged-ness\n\n            @property tryGetBack(size_t i)(){return ranges[i].empty ? tryGetInit!i() : ranges[i].back;}\n            //ElementType(tryGetBack!0, tryGetBack!1, ...)\n            return mixin(q{ElementType(%(tryGetBack!%s, %))}.format(iota(0, R.length)));\n        }\n\n/**\n   Moves out the back.\n*/\n        static if (allSatisfy!(hasMobileElements, R))\n        {\n            ElementType moveBack()\n            {\n                //TODO: Fixme! BackElement != back of all ranges in case of jagged-ness\n\n                @property tryMoveBack(size_t i)(){return ranges[i].empty ? tryGetInit!i() : ranges[i].moveBack();}\n                //ElementType(tryMoveBack!0, tryMoveBack!1, ...)\n                return mixin(q{ElementType(%(tryMoveBack!%s, %))}.format(iota(0, R.length)));\n            }\n        }\n\n/**\n   Returns the current iterated element.\n*/\n        static if (allSatisfy!(hasAssignableElements, R))\n        {\n            @property void back(ElementType v)\n            {\n                //TODO: Fixme! BackElement != back of all ranges in case of jagged-ness.\n                //Not sure the call is even legal for StoppingPolicy.longest\n\n                foreach (i, Unused; R)\n                {\n                    if (!ranges[i].empty)\n                    {\n                        ranges[i].back = v[i];\n                    }\n                }\n            }\n        }\n    }\n\n/**\n   Advances to the next element in all controlled ranges.\n*/\n    void popFront()\n    {\n        import std.exception : enforce;\n\n        final switch (stoppingPolicy)\n        {\n        case StoppingPolicy.shortest:\n            foreach (i, Unused; R)\n            {\n                assert(!ranges[i].empty);\n                ranges[i].popFront();\n            }\n            break;\n        case StoppingPolicy.longest:\n            foreach (i, Unused; R)\n            {\n                if (!ranges[i].empty) ranges[i].popFront();\n            }\n            break;\n        case StoppingPolicy.requireSameLength:\n            foreach (i, Unused; R)\n            {\n                enforce(!ranges[i].empty, \"Invalid Zip object\");\n                ranges[i].popFront();\n            }\n            break;\n        }\n    }\n\n/**\n   Calls `popBack` for all controlled ranges.\n*/\n    static if (allSatisfy!(isBidirectionalRange, R))\n    {\n        void popBack()\n        {\n            //TODO: Fixme! In case of jaggedness, this is wrong.\n            import std.exception : enforce;\n\n            final switch (stoppingPolicy)\n            {\n            case StoppingPolicy.shortest:\n                foreach (i, Unused; R)\n                {\n                    assert(!ranges[i].empty);\n                    ranges[i].popBack();\n                }\n                break;\n            case StoppingPolicy.longest:\n                foreach (i, Unused; R)\n                {\n                    if (!ranges[i].empty) ranges[i].popBack();\n                }\n                break;\n            case StoppingPolicy.requireSameLength:\n                foreach (i, Unused; R)\n                {\n                    enforce(!ranges[i].empty, \"Invalid Zip object\");\n                    ranges[i].popBack();\n                }\n                break;\n            }\n        }\n    }\n\n/**\n   Returns the length of this range. Defined only if all ranges define\n   `length`.\n*/\n    static if (allSatisfy!(hasLength, R))\n    {\n        @property auto length()\n        {\n            static if (Ranges.length == 1)\n                return ranges[0].length;\n            else\n            {\n                if (stoppingPolicy == StoppingPolicy.requireSameLength)\n                    return ranges[0].length;\n\n                //[min|max](ranges[0].length, ranges[1].length, ...)\n                import std.algorithm.comparison : min, max;\n                if (stoppingPolicy == StoppingPolicy.shortest)\n                    return mixin(q{min(%(ranges[%s].length%|, %))}.format(iota(0, R.length)));\n                else\n                    return mixin(q{max(%(ranges[%s].length%|, %))}.format(iota(0, R.length)));\n            }\n        }\n\n        alias opDollar = length;\n    }\n\n/**\n   Returns a slice of the range. Defined only if all range define\n   slicing.\n*/\n    static if (allSatisfy!(hasSlicing, R))\n    {\n        auto opSlice(size_t from, size_t to)\n        {\n            //Slicing an infinite range yields the type Take!R\n            //For finite ranges, the type Take!R aliases to R\n            alias ZipResult = Zip!(staticMap!(Take, R));\n\n            //ZipResult(ranges[0][from .. to], ranges[1][from .. to], ..., stoppingPolicy)\n            return mixin (q{ZipResult(%(ranges[%s][from .. to]%|, %), stoppingPolicy)}.format(iota(0, R.length)));\n        }\n    }\n\n/**\n   Returns the `n`th element in the composite range. Defined if all\n   ranges offer random access.\n*/\n    static if (allSatisfy!(isRandomAccessRange, R))\n    {\n        ElementType opIndex(size_t n)\n        {\n            //TODO: Fixme! This may create an out of bounds access\n            //for StoppingPolicy.longest\n\n            //ElementType(ranges[0][n], ranges[1][n], ...)\n            return mixin (q{ElementType(%(ranges[%s][n]%|, %))}.format(iota(0, R.length)));\n        }\n\n/**\n   Assigns to the `n`th element in the composite range. Defined if\n   all ranges offer random access.\n*/\n        static if (allSatisfy!(hasAssignableElements, R))\n        {\n            void opIndexAssign(ElementType v, size_t n)\n            {\n                //TODO: Fixme! Not sure the call is even legal for StoppingPolicy.longest\n                foreach (i, Range; R)\n                {\n                    ranges[i][n] = v[i];\n                }\n            }\n        }\n\n/**\n   Destructively reads the `n`th element in the composite\n   range. Defined if all ranges offer random access.\n*/\n        static if (allSatisfy!(hasMobileElements, R))\n        {\n            ElementType moveAt(size_t n)\n            {\n                //TODO: Fixme! This may create an out of bounds access\n                //for StoppingPolicy.longest\n\n                //ElementType(ranges[0].moveAt(n), ranges[1].moveAt(n), ..., )\n                return mixin (q{ElementType(%(ranges[%s].moveAt(n)%|, %))}.format(iota(0, R.length)));\n            }\n        }\n    }\n}\n\n/// Ditto\nauto zip(Ranges...)(Ranges ranges)\nif (Ranges.length && allSatisfy!(isInputRange, Ranges))\n{\n    static if (allSatisfy!(isInfinite, Ranges) || Ranges.length == 1)\n    {\n        return ZipShortest!(Ranges)(ranges);\n    }\n    else static if (allSatisfy!(isBidirectionalRange, Ranges))\n    {\n        static if (allSatisfy!(templateOr!(isInfinite, hasLength), Ranges)\n            && allSatisfy!(templateOr!(isInfinite, hasSlicing), Ranges)\n            && allSatisfy!(isBidirectionalRange, staticMap!(Take, Ranges)))\n        {\n            // If all the ranges are bidirectional, if possible slice them to\n            // the same length to simplify the implementation.\n            static assert(anySatisfy!(hasLength, Ranges));\n            static foreach (i, Range; Ranges)\n                static if (hasLength!Range)\n                {\n                    static if (!anySatisfy!(hasLength, Ranges[0 .. i]))\n                        size_t minLen = ranges[i].length;\n                    else\n                    {{\n                        const x = ranges[i].length;\n                        if (x < minLen) minLen = x;\n                    }}\n                }\n            import std.format : format;\n            static if (!anySatisfy!(isInfinite, Ranges))\n                return mixin(`ZipShortest!(Yes.allKnownSameLength, staticMap!(Take, Ranges))`~\n                    `(%(ranges[%s][0 .. minLen]%|, %))`.format(iota(0, Ranges.length)));\n            else\n                return mixin(`ZipShortest!(Yes.allKnownSameLength, staticMap!(Take, Ranges))`~\n                    `(%(take(ranges[%s], minLen)%|, %))`.format(iota(0, Ranges.length)));\n        }\n        else static if (allSatisfy!(isRandomAccessRange, Ranges))\n        {\n            // We can't slice but we can still use random access to ensure\n            // \"back\" is retrieving the same index for each range.\n            return ZipShortest!(Ranges)(ranges);\n        }\n        else\n        {\n            // If bidirectional range operations would not be supported by\n            // ZipShortest that might have actually been a bug since Zip\n            // supported `back` without verifying that each range had the\n            // same length, but for the sake of backwards compatibility\n            // use the old Zip to continue supporting them.\n            return Zip!Ranges(ranges);\n        }\n    }\n    else\n    {\n        return ZipShortest!(Ranges)(ranges);\n    }\n}\n\n///\n@nogc nothrow pure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n\n    // pairwise sum\n    auto arr = only(0, 1, 2);\n    auto part1 = zip(arr, arr.dropOne).map!\"a[0] + a[1]\";\n    assert(part1.equal(only(1, 3)));\n}\n\n///\nnothrow pure @safe unittest\n{\n    import std.conv : to;\n\n    int[] a = [ 1, 2, 3 ];\n    string[] b = [ \"a\", \"b\", \"c\" ];\n    string[] result;\n\n    foreach (tup; zip(a, b))\n    {\n        result ~= tup[0].to!string ~ tup[1];\n    }\n\n    assert(result == [ \"1a\", \"2b\", \"3c\" ]);\n\n    size_t idx = 0;\n    // unpacking tuple elements with foreach\n    foreach (e1, e2; zip(a, b))\n    {\n        assert(e1 == a[idx]);\n        assert(e2 == b[idx]);\n        ++idx;\n    }\n}\n\n/// `zip` is powerful - the following code sorts two arrays in parallel:\nnothrow pure @safe unittest\n{\n    import std.algorithm.sorting : sort;\n\n    int[] a = [ 1, 2, 3 ];\n    string[] b = [ \"a\", \"c\", \"b\" ];\n    zip(a, b).sort!((t1, t2) => t1[0] > t2[0]);\n\n    assert(a == [ 3, 2, 1 ]);\n    // b is sorted according to a's sorting\n    assert(b == [ \"b\", \"c\", \"a\" ]);\n}\n\n/// Ditto\nauto zip(Ranges...)(StoppingPolicy sp, Ranges ranges)\nif (Ranges.length && allSatisfy!(isInputRange, Ranges))\n{\n    return Zip!Ranges(ranges, sp);\n}\n\n/**\n   Dictates how iteration in a $(LREF zip) and $(LREF lockstep) should stop.\n   By default stop at the end of the shortest of all ranges.\n*/\nenum StoppingPolicy\n{\n    /// Stop when the shortest range is exhausted\n    shortest,\n    /// Stop when the longest range is exhausted\n    longest,\n    /// Require that all ranges are equal\n    requireSameLength,\n}\n\n///\npure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.exception : assertThrown;\n    import std.range.primitives;\n    import std.typecons : tuple;\n\n    auto a = [1, 2, 3];\n    auto b = [4, 5, 6, 7];\n\n    auto shortest = zip(StoppingPolicy.shortest, a, b);\n    assert(shortest.equal([\n        tuple(1, 4),\n        tuple(2, 5),\n        tuple(3, 6)\n    ]));\n\n    auto longest = zip(StoppingPolicy.longest, a, b);\n    assert(longest.equal([\n        tuple(1, 4),\n        tuple(2, 5),\n        tuple(3, 6),\n        tuple(0, 7)\n    ]));\n\n    auto same = zip(StoppingPolicy.requireSameLength, a, b);\n    same.popFrontN(3);\n    assertThrown!Exception(same.popFront);\n}\n\n/+\nNon-public. Like $(LREF Zip) with `StoppingPolicy.shortest`\nexcept it properly implements `back` and `popBack` in the\ncase of uneven ranges or disables those operations when\nit is not possible to guarantee they are correct.\n+/\npackage template ZipShortest(Ranges...)\nif (Ranges.length && __traits(compiles,\n    {\n        static assert(allSatisfy!(isInputRange, Ranges));\n    }))\n{\n    alias ZipShortest = .ZipShortest!(\n        Ranges.length == 1 || allSatisfy!(isInfinite, Ranges)\n            ? Yes.allKnownSameLength\n            : No.allKnownSameLength,\n        Ranges);\n}\n/+ non-public, ditto +/\npackage struct ZipShortest(Flag!\"allKnownSameLength\" allKnownSameLength, Ranges...)\nif (Ranges.length && allSatisfy!(isInputRange, Ranges))\n{\n    import std.format : format; //for generic mixins\n    import std.typecons : Tuple;\n\n    deprecated(\"Use of an undocumented alias R.\")\n    alias R = Ranges; // Unused here but defined in case library users rely on it.\n    private Ranges ranges;\n    alias ElementType = Tuple!(staticMap!(.ElementType, Ranges));\n\n    /+\n       Builds an object. Usually this is invoked indirectly by using the\n       $(LREF zip) function.\n    +/\n    this(Ranges rs)\n    {\n        ranges[] = rs[];\n    }\n\n    /+\n       Returns `true` if the range is at end.\n    +/\n    static if (allKnownSameLength ? anySatisfy!(isInfinite, Ranges)\n        : allSatisfy!(isInfinite, Ranges))\n    {\n        enum bool empty = false;\n    }\n    else\n    {\n        @property bool empty()\n        {\n            static if (allKnownSameLength)\n            {\n                return ranges[0].empty;\n            }\n            else\n            {\n                static foreach (i; 0 .. Ranges.length)\n                {\n                    if (ranges[i].empty)\n                        return true;\n                }\n                return false;\n            }\n        }\n    }\n\n    /+\n       Forward range primitive. Only present if each constituent range is a\n       forward range.\n    +/\n    static if (allSatisfy!(isForwardRange, Ranges))\n    @property typeof(this) save()\n    {\n        return mixin(`typeof(return)(%(ranges[%s].save%|, %))`.format(iota(0, Ranges.length)));\n    }\n\n    /+\n       Returns the current iterated element.\n    +/\n    @property ElementType front()\n    {\n        return mixin(`typeof(return)(%(ranges[%s].front%|, %))`.format(iota(0, Ranges.length)));\n    }\n\n    /+\n       Sets the front of all iterated ranges. Only present if each constituent\n       range has assignable elements.\n    +/\n    static if (allSatisfy!(hasAssignableElements, Ranges))\n    @property void front()(ElementType v)\n    {\n        static foreach (i; 0 .. Ranges.length)\n            ranges[i].front = v[i];\n    }\n\n    /+\n       Moves out the front. Present if each constituent range has mobile elements.\n    +/\n    static if (allSatisfy!(hasMobileElements, Ranges))\n    ElementType moveFront()()\n    {\n        return mixin(`typeof(return)(%(ranges[%s].moveFront()%|, %))`.format(iota(0, Ranges.length)));\n    }\n\n    private enum bool isBackWellDefined = allSatisfy!(isBidirectionalRange, Ranges)\n        && (allKnownSameLength\n            || allSatisfy!(isRandomAccessRange, Ranges)\n            // Could also add the case where there is one non-infinite bidirectional\n            // range that defines `length` and all others are infinite random access\n            // ranges. Adding this would require appropriate branches in\n            // back/moveBack/popBack.\n            );\n\n    /+\n       Returns the rightmost element. Present if all constituent ranges are\n       bidirectional and either there is a compile-time guarantee that all\n       ranges have the same length (in `allKnownSameLength`) or all ranges\n       provide random access to elements.\n    +/\n    static if (isBackWellDefined)\n    @property ElementType back()\n    {\n        static if (allKnownSameLength)\n        {\n            return mixin(`typeof(return)(%(ranges[%s].back()%|, %))`.format(iota(0, Ranges.length)));\n        }\n        else\n        {\n            const backIndex = length - 1;\n            return mixin(`typeof(return)(%(ranges[%s][backIndex]%|, %))`.format(iota(0, Ranges.length)));\n        }\n    }\n\n    /+\n       Moves out the back. Present if `back` is defined and\n       each constituent range has mobile elements.\n    +/\n    static if (isBackWellDefined && allSatisfy!(hasMobileElements, Ranges))\n    ElementType moveBack()()\n    {\n        static if (allKnownSameLength)\n        {\n            return mixin(`typeof(return)(%(ranges[%s].moveBack()%|, %))`.format(iota(0, Ranges.length)));\n        }\n        else\n        {\n            const backIndex = length - 1;\n            return mixin(`typeof(return)(%(ranges[%s].moveAt(backIndex)%|, %))`.format(iota(0, Ranges.length)));\n        }\n    }\n\n    /+\n       Sets the rightmost element. Only present if `back` is defined and\n       each constituent range has assignable elements.\n    +/\n    static if (isBackWellDefined && allSatisfy!(hasAssignableElements, Ranges))\n    @property void back()(ElementType v)\n    {\n        static if (allKnownSameLength)\n        {\n            static foreach (i; 0 .. Ranges.length)\n                ranges[i].back = v[i];\n        }\n        else\n        {\n            const backIndex = length - 1;\n            static foreach (i; 0 .. Ranges.length)\n                ranges[i][backIndex] = v[i];\n        }\n    }\n\n    /+\n       Calls `popFront` on each constituent range.\n    +/\n    void popFront()\n    {\n        static foreach (i; 0 .. Ranges.length)\n            ranges[i].popFront();\n    }\n\n    /+\n       Pops the rightmost element. Present if `back` is defined.\n    +/\n    static if (isBackWellDefined)\n    void popBack()\n    {\n        static if (allKnownSameLength)\n        {\n            static foreach (i; 0 .. Ranges.length)\n                ranges[i].popBack;\n        }\n        else\n        {\n            const len = length;\n            static foreach (i; 0 .. Ranges.length)\n                static if (!isInfinite!(Ranges[i]))\n                    if (ranges[i].length == len)\n                        ranges[i].popBack();\n        }\n    }\n\n    /+\n       Returns the length of this range. Defined if at least one\n       constituent range defines `length` and the other ranges all also\n       define `length` or are infinite, or if at least one constituent\n       range defines `length` and there is a compile-time guarantee that\n       all ranges have the same length (in `allKnownSameLength`).\n    +/\n    static if (allKnownSameLength\n        ? anySatisfy!(hasLength, Ranges)\n        : (anySatisfy!(hasLength, Ranges)\n            && allSatisfy!(templateOr!(isInfinite, hasLength), Ranges)))\n    {\n        @property size_t length()\n        {\n            static if (allKnownSameLength)\n            {\n                static foreach (i, Range; Ranges)\n                {\n                    static if (hasLength!Range && !anySatisfy!(hasLength, Ranges[0 .. i]))\n                        return ranges[i].length;\n                }\n            }\n            else\n            {\n                static foreach (i, Range; Ranges)\n                    static if (hasLength!Range)\n                    {\n                        static if (!anySatisfy!(hasLength, Ranges[0 .. i]))\n                            size_t minLen = ranges[i].length;\n                        else\n                        {{\n                            const x = ranges[i].length;\n                            if (x < minLen) minLen = x;\n                        }}\n                    }\n                return minLen;\n            }\n        }\n\n        alias opDollar = length;\n    }\n\n    /+\n       Returns a slice of the range. Defined if all constituent ranges\n       support slicing.\n    +/\n    static if (allSatisfy!(hasSlicing, Ranges))\n    {\n        // Note: we will know that all elements of the resultant range\n        // will have the same length but we cannot change `allKnownSameLength`\n        // because the `hasSlicing` predicate tests that the result returned\n        // by `opSlice` has the same type as the receiver.\n        auto opSlice()(size_t from, size_t to)\n        {\n            //(ranges[0][from .. to], ranges[1][from .. to], ...)\n            enum sliceArgs = `(%(ranges[%s][from .. to]%|, %))`.format(iota(0, Ranges.length));\n            static if (__traits(compiles, mixin(`typeof(this)`~sliceArgs)))\n                return mixin(`typeof(this)`~sliceArgs);\n            else\n                // The type is different anyway so we might as well\n                // explicitly set allKnownSameLength.\n                return mixin(`ZipShortest!(Yes.allKnownSameLength, staticMap!(Take, Ranges))`\n                    ~sliceArgs);\n        }\n    }\n\n    /+\n       Returns the `n`th element in the composite range. Defined if all\n       constituent ranges offer random access.\n    +/\n    static if (allSatisfy!(isRandomAccessRange, Ranges))\n    ElementType opIndex()(size_t n)\n    {\n        return mixin(`typeof(return)(%(ranges[%s][n]%|, %))`.format(iota(0, Ranges.length)));\n    }\n\n    /+\n       Sets the `n`th element in the composite range. Defined if all\n       constituent ranges offer random access and have assignable elements.\n    +/\n    static if (allSatisfy!(isRandomAccessRange, Ranges)\n        && allSatisfy!(hasAssignableElements, Ranges))\n    void opIndexAssign()(ElementType v, size_t n)\n    {\n        static foreach (i; 0 .. Ranges.length)\n            ranges[i][n] = v[i];\n    }\n\n    /+\n       Destructively reads the `n`th element in the composite\n       range. Defined if all constituent ranges offer random\n       access and have mobile elements.\n    +/\n    static if (allSatisfy!(isRandomAccessRange, Ranges)\n        && allSatisfy!(hasMobileElements, Ranges))\n    ElementType moveAt()(size_t n)\n    {\n        return mixin(`typeof(return)(%(ranges[%s].moveAt(n)%|, %))`.format(iota(0, Ranges.length)));\n    }\n}\n\npure @system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter, map;\n    import std.algorithm.mutation : swap;\n    import std.algorithm.sorting : sort;\n\n    import std.exception : assertThrown, assertNotThrown;\n    import std.typecons : tuple;\n\n    int[] a = [ 1, 2, 3 ];\n    float[] b = [ 1.0, 2.0, 3.0 ];\n    foreach (e; zip(a, b))\n    {\n        assert(e[0] == e[1]);\n    }\n\n    swap(a[0], a[1]);\n    {\n        auto z = zip(a, b);\n    }\n    //swap(z.front(), z.back());\n    sort!(\"a[0] < b[0]\")(zip(a, b));\n    assert(a == [1, 2, 3]);\n    assert(b == [2.0, 1.0, 3.0]);\n\n    auto z = zip(StoppingPolicy.requireSameLength, a, b);\n    assertNotThrown(z.popBack());\n    assertNotThrown(z.popBack());\n    assertNotThrown(z.popBack());\n    assert(z.empty);\n    assertThrown(z.popBack());\n\n    a = [ 1, 2, 3 ];\n    b = [ 1.0, 2.0, 3.0 ];\n    sort!(\"a[0] > b[0]\")(zip(StoppingPolicy.requireSameLength, a, b));\n    assert(a == [3, 2, 1]);\n    assert(b == [3.0, 2.0, 1.0]);\n\n    a = [];\n    b = [];\n    assert(zip(StoppingPolicy.requireSameLength, a, b).empty);\n\n    // Test infiniteness propagation.\n    static assert(isInfinite!(typeof(zip(repeat(1), repeat(1)))));\n\n    // Test stopping policies with both value and reference.\n    auto a1 = [1, 2];\n    auto a2 = [1, 2, 3];\n    auto stuff = tuple(tuple(a1, a2),\n            tuple(filter!\"a\"(a1), filter!\"a\"(a2)));\n\n    alias FOO = Zip!(immutable(int)[], immutable(float)[]);\n\n    foreach (t; stuff.expand)\n    {\n        auto arr1 = t[0];\n        auto arr2 = t[1];\n        auto zShortest = zip(arr1, arr2);\n        assert(equal(map!\"a[0]\"(zShortest), [1, 2]));\n        assert(equal(map!\"a[1]\"(zShortest), [1, 2]));\n\n        try {\n            auto zSame = zip(StoppingPolicy.requireSameLength, arr1, arr2);\n            foreach (elem; zSame) {}\n            assert(0);\n        } catch (Throwable) { /* It's supposed to throw.*/ }\n\n        auto zLongest = zip(StoppingPolicy.longest, arr1, arr2);\n        assert(!zLongest.ranges[0].empty);\n        assert(!zLongest.ranges[1].empty);\n\n        zLongest.popFront();\n        zLongest.popFront();\n        assert(!zLongest.empty);\n        assert(zLongest.ranges[0].empty);\n        assert(!zLongest.ranges[1].empty);\n\n        zLongest.popFront();\n        assert(zLongest.empty);\n    }\n\n    // BUG 8900\n    assert(zip([1, 2], repeat('a')).array == [tuple(1, 'a'), tuple(2, 'a')]);\n    assert(zip(repeat('a'), [1, 2]).array == [tuple('a', 1), tuple('a', 2)]);\n\n    // Issue 18524 - moveBack instead performs moveFront\n    {\n        auto r = zip([1,2,3]);\n        assert(r.moveBack()[0] == 3);\n        assert(r.moveFront()[0] == 1);\n    }\n\n    // Doesn't work yet.  Issues w/ emplace.\n    // static assert(is(Zip!(immutable int[], immutable float[])));\n\n\n    // These unittests pass, but make the compiler consume an absurd amount\n    // of RAM and time.  Therefore, they should only be run if explicitly\n    // uncommented when making changes to Zip.  Also, running them using\n    // make -fwin32.mak unittest makes the compiler completely run out of RAM.\n    // You need to test just this module.\n    /+\n     foreach (DummyType1; AllDummyRanges)\n     {\n         DummyType1 d1;\n         foreach (DummyType2; AllDummyRanges)\n         {\n             DummyType2 d2;\n             auto r = zip(d1, d2);\n             assert(equal(map!\"a[0]\"(r), [1,2,3,4,5,6,7,8,9,10]));\n             assert(equal(map!\"a[1]\"(r), [1,2,3,4,5,6,7,8,9,10]));\n\n             static if (isForwardRange!DummyType1 && isForwardRange!DummyType2)\n             {\n                 static assert(isForwardRange!(typeof(r)));\n             }\n\n             static if (isBidirectionalRange!DummyType1 &&\n                     isBidirectionalRange!DummyType2) {\n                 static assert(isBidirectionalRange!(typeof(r)));\n             }\n             static if (isRandomAccessRange!DummyType1 &&\n                     isRandomAccessRange!DummyType2) {\n                 static assert(isRandomAccessRange!(typeof(r)));\n             }\n         }\n     }\n    +/\n}\n\nnothrow pure @safe unittest\n{\n    import std.algorithm.sorting : sort;\n\n    auto a = [5,4,3,2,1];\n    auto b = [3,1,2,5,6];\n    auto z = zip(a, b);\n\n    sort!\"a[0] < b[0]\"(z);\n\n    assert(a == [1, 2, 3, 4, 5]);\n    assert(b == [6, 5, 2, 1, 3]);\n}\n\nnothrow pure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : tuple;\n\n    auto LL = iota(1L, 1000L);\n    auto z = zip(LL, [4]);\n\n    assert(equal(z, [tuple(1L,4)]));\n\n    auto LL2 = iota(0L, 500L);\n    auto z2 = zip([7], LL2);\n    assert(equal(z2, [tuple(7, 0L)]));\n}\n\n// Text for Issue 11196\n@safe pure unittest\n{\n    import std.exception : assertThrown;\n\n    static struct S { @disable this(); }\n    assert(zip((S[5]).init[]).length == 5);\n    assert(zip(StoppingPolicy.longest, cast(S[]) null, new int[1]).length == 1);\n    assertThrown(zip(StoppingPolicy.longest, cast(S[]) null, new int[1]).front);\n}\n\n@nogc nothrow @safe pure unittest //12007\n{\n    static struct R\n    {\n        enum empty = false;\n        void popFront(){}\n        int front(){return 1;} @property\n        R save(){return this;} @property\n        void opAssign(R) @disable;\n    }\n    R r;\n    auto z = zip(r, r);\n    assert(z.save == z);\n}\n\nnothrow pure @system unittest\n{\n    import std.typecons : tuple;\n\n    auto r1 = [0,1,2];\n    auto r2 = [1,2,3];\n    auto z1 = zip(refRange(&r1), refRange(&r2));\n    auto z2 = z1.save;\n    z1.popFront();\n    assert(z1.front == tuple(1,2));\n    assert(z2.front == tuple(0,1));\n}\n\n@nogc nothrow pure @safe unittest\n{\n    // Test zip's `back` and `length` with non-equal ranges.\n    static struct NonSliceableRandomAccess\n    {\n        private int[] a;\n        @property ref front()\n        {\n            return a.front;\n        }\n        @property ref back()\n        {\n            return a.back;\n        }\n        ref opIndex(size_t i)\n        {\n            return a[i];\n        }\n        void popFront()\n        {\n            a.popFront();\n        }\n        void popBack()\n        {\n            a.popBack();\n        }\n        auto moveFront()\n        {\n            return a.moveFront();\n        }\n        auto moveBack()\n        {\n            return a.moveBack();\n        }\n        auto moveAt(size_t i)\n        {\n            return a.moveAt(i);\n        }\n        bool empty() const\n        {\n            return a.empty;\n        }\n        size_t length() const\n        {\n            return a.length;\n        }\n        typeof(this) save()\n        {\n            return this;\n        }\n    }\n    static assert(isRandomAccessRange!NonSliceableRandomAccess);\n    static assert(!hasSlicing!NonSliceableRandomAccess);\n    static foreach (iteration; 0 .. 2)\n    {{\n        int[5] data = [101, 102, 103, 201, 202];\n        static if (iteration == 0)\n        {\n            auto r1 = NonSliceableRandomAccess(data[0 .. 3]);\n            auto r2 = NonSliceableRandomAccess(data[3 .. 5]);\n        }\n        else\n        {\n            auto r1 = data[0 .. 3];\n            auto r2 = data[3 .. 5];\n        }\n        auto z = zip(r1, r2);\n        static assert(isRandomAccessRange!(typeof(z)));\n        assert(z.length == 2);\n        assert(z.back[0] == 102 && z.back[1] == 202);\n        z.back = typeof(z.back)(-102, -202);// Assign to back.\n        assert(z.back[0] == -102 && z.back[1] == -202);\n        z.popBack();\n        assert(z.length == 1);\n        assert(z.back[0] == 101 && z.back[1] == 201);\n        z.front = typeof(z.front)(-101, -201);\n        assert(z.moveBack() == typeof(z.back)(-101, -201));\n        z.popBack();\n        assert(z.empty);\n    }}\n}\n\n@nogc nothrow pure @safe unittest\n{\n    // Test opSlice on infinite `zip`.\n    auto z = zip(repeat(1), repeat(2));\n    assert(hasSlicing!(typeof(z)));\n    auto slice = z[10 .. 20];\n    assert(slice.length == 10);\n    static assert(!is(typeof(z) == typeof(slice)));\n}\n\n/*\n    Generate lockstep's opApply function as a mixin string.\n    If withIndex is true prepend a size_t index to the delegate.\n*/\nprivate string lockstepMixin(Ranges...)(bool withIndex, bool reverse)\n{\n    import std.format : format;\n\n    string[] params;\n    string[] emptyChecks;\n    string[] dgArgs;\n    string[] popFronts;\n    string indexDef;\n    string indexInc;\n\n    if (withIndex)\n    {\n        params ~= \"size_t\";\n        dgArgs ~= \"index\";\n        if (reverse)\n        {\n            indexDef = q{\n                size_t index = ranges[0].length-1;\n                enforce(_stoppingPolicy == StoppingPolicy.requireSameLength,\n                        \"lockstep can only be used with foreach_reverse when stoppingPolicy == requireSameLength\");\n\n                foreach (range; ranges[1..$])\n                    enforce(range.length == ranges[0].length);\n                };\n            indexInc = \"--index;\";\n        }\n        else\n        {\n            indexDef = \"size_t index = 0;\";\n            indexInc = \"++index;\";\n        }\n    }\n\n    foreach (idx, Range; Ranges)\n    {\n        params ~= format(\"%sElementType!(Ranges[%s])\", hasLvalueElements!Range ? \"ref \" : \"\", idx);\n        emptyChecks ~= format(\"!ranges[%s].empty\", idx);\n        if (reverse)\n        {\n            dgArgs ~= format(\"ranges[%s].back\", idx);\n            popFronts ~= format(\"ranges[%s].popBack();\", idx);\n        }\n        else\n        {\n            dgArgs ~= format(\"ranges[%s].front\", idx);\n            popFronts ~= format(\"ranges[%s].popFront();\", idx);\n        }\n    }\n\n    string name = reverse ? \"opApplyReverse\" : \"opApply\";\n\n    return format(\n    q{\n        int %s(scope int delegate(%s) dg)\n        {\n            import std.exception : enforce;\n\n            auto ranges = _ranges;\n            int res;\n            %s\n\n            while (%s)\n            {\n                res = dg(%s);\n                if (res) break;\n                %s\n                %s\n            }\n\n            if (_stoppingPolicy == StoppingPolicy.requireSameLength)\n            {\n                foreach (range; ranges)\n                    enforce(range.empty);\n            }\n            return res;\n        }\n    }, name, params.join(\", \"), indexDef,\n       emptyChecks.join(\" && \"), dgArgs.join(\", \"),\n       popFronts.join(\"\\n                \"),\n       indexInc);\n}\n\n/**\n   Iterate multiple ranges in lockstep using a `foreach` loop. In contrast to\n   $(LREF zip) it allows reference access to its elements. If only a single\n   range is passed in, the `Lockstep` aliases itself away.  If the\n   ranges are of different lengths and `s` == `StoppingPolicy.shortest`\n   stop after the shortest range is empty.  If the ranges are of different\n   lengths and `s` == `StoppingPolicy.requireSameLength`, throw an\n   exception.  `s` may not be `StoppingPolicy.longest`, and passing this\n   will throw an exception.\n\n   Iterating over `Lockstep` in reverse and with an index is only possible\n   when `s` == `StoppingPolicy.requireSameLength`, in order to preserve\n   indexes. If an attempt is made at iterating in reverse when `s` ==\n   `StoppingPolicy.shortest`, an exception will be thrown.\n\n   By default `StoppingPolicy` is set to `StoppingPolicy.shortest`.\n\n   Limitations: The `pure`, `@safe`, `@nogc`, or `nothrow` attributes cannot be\n   inferred for `lockstep` iteration. $(LREF zip) can infer the first two due to\n   a different implementation.\n\n   See_Also: $(LREF zip)\n\n       `lockstep` is similar to $(LREF zip), but `zip` bundles its\n       elements and returns a range.\n       `lockstep` also supports reference access.\n       Use `zip` if you want to pass the result to a range function.\n*/\nstruct Lockstep(Ranges...)\nif (Ranges.length > 1 && allSatisfy!(isInputRange, Ranges))\n{\n    ///\n    this(R ranges, StoppingPolicy sp = StoppingPolicy.shortest)\n    {\n        import std.exception : enforce;\n\n        _ranges = ranges;\n        enforce(sp != StoppingPolicy.longest,\n                \"Can't use StoppingPolicy.Longest on Lockstep.\");\n        _stoppingPolicy = sp;\n    }\n\n    mixin(lockstepMixin!Ranges(false, false));\n    mixin(lockstepMixin!Ranges(true, false));\n    static if (allSatisfy!(isBidirectionalRange, Ranges))\n    {\n        mixin(lockstepMixin!Ranges(false, true));\n        static if (allSatisfy!(hasLength, Ranges))\n        {\n            mixin(lockstepMixin!Ranges(true, true));\n        }\n        else\n        {\n            mixin(lockstepReverseFailMixin!Ranges(true));\n        }\n    }\n    else\n    {\n        mixin(lockstepReverseFailMixin!Ranges(false));\n        mixin(lockstepReverseFailMixin!Ranges(true));\n    }\n\nprivate:\n    alias R = Ranges;\n    R _ranges;\n    StoppingPolicy _stoppingPolicy;\n}\n\n/// Ditto\nLockstep!(Ranges) lockstep(Ranges...)(Ranges ranges)\nif (allSatisfy!(isInputRange, Ranges))\n{\n    return Lockstep!(Ranges)(ranges);\n}\n/// Ditto\nLockstep!(Ranges) lockstep(Ranges...)(Ranges ranges, StoppingPolicy s)\nif (allSatisfy!(isInputRange, Ranges))\n{\n    static if (Ranges.length > 1)\n        return Lockstep!Ranges(ranges, s);\n    else\n        return ranges[0];\n}\n\n///\n@system unittest\n{\n   auto arr1 = [1,2,3,4,5,100];\n   auto arr2 = [6,7,8,9,10];\n\n   foreach (ref a, b; lockstep(arr1, arr2))\n   {\n       a += b;\n   }\n\n   assert(arr1 == [7,9,11,13,15,100]);\n\n   /// Lockstep also supports iterating with an index variable:\n   foreach (index, a, b; lockstep(arr1, arr2))\n   {\n       assert(arr1[index] == a);\n       assert(arr2[index] == b);\n   }\n}\n\n@system unittest // Bugzilla 15860: foreach_reverse on lockstep\n{\n    auto arr1 = [0, 1, 2, 3];\n    auto arr2 = [4, 5, 6, 7];\n\n    size_t n = arr1.length -1;\n    foreach_reverse (index, a, b; lockstep(arr1, arr2, StoppingPolicy.requireSameLength))\n    {\n        assert(n == index);\n        assert(index == a);\n        assert(arr1[index] == a);\n        assert(arr2[index] == b);\n        n--;\n    }\n\n    auto arr3 = [4, 5];\n    n = 1;\n    foreach_reverse (a, b; lockstep(arr1, arr3))\n    {\n        assert(a == arr1[$-n] && b == arr3[$-n]);\n        n++;\n    }\n}\n\n@system unittest\n{\n    import std.algorithm.iteration : filter;\n    import std.conv : to;\n\n    // The filters are to make these the lowest common forward denominator ranges,\n    // i.e. w/o ref return, random access, length, etc.\n    auto foo = filter!\"a\"([1,2,3,4,5]);\n    immutable bar = [6f,7f,8f,9f,10f].idup;\n    auto l = lockstep(foo, bar);\n\n    // Should work twice.  These are forward ranges with implicit save.\n    foreach (i; 0 .. 2)\n    {\n        uint[] res1;\n        float[] res2;\n\n        foreach (a, ref b; l)\n        {\n            res1 ~= a;\n            res2 ~= b;\n        }\n\n        assert(res1 == [1,2,3,4,5]);\n        assert(res2 == [6,7,8,9,10]);\n        assert(bar == [6f,7f,8f,9f,10f]);\n    }\n\n    // Doc example.\n    auto arr1 = [1,2,3,4,5];\n    auto arr2 = [6,7,8,9,10];\n\n    foreach (ref a, ref b; lockstep(arr1, arr2))\n    {\n        a += b;\n    }\n\n    assert(arr1 == [7,9,11,13,15]);\n\n    // Make sure StoppingPolicy.requireSameLength doesn't throw.\n    auto ls = lockstep(arr1, arr2, StoppingPolicy.requireSameLength);\n\n    int k = 1;\n    foreach (a, b; ls)\n    {\n        assert(a - b == k);\n        ++k;\n    }\n\n    // Make sure StoppingPolicy.requireSameLength throws.\n    arr2.popBack();\n    ls = lockstep(arr1, arr2, StoppingPolicy.requireSameLength);\n\n    try {\n        foreach (a, b; ls) {}\n        assert(0);\n    } catch (Exception) {}\n\n    // Just make sure 1-range case instantiates.  This hangs the compiler\n    // when no explicit stopping policy is specified due to Bug 4652.\n    auto stuff = lockstep([1,2,3,4,5], StoppingPolicy.shortest);\n    foreach (int i, a; stuff)\n    {\n        assert(stuff[i] == a);\n    }\n\n    // Test with indexing.\n    uint[] res1;\n    float[] res2;\n    size_t[] indices;\n    foreach (i, a, b; lockstep(foo, bar))\n    {\n        indices ~= i;\n        res1 ~= a;\n        res2 ~= b;\n    }\n\n    assert(indices == to!(size_t[])([0, 1, 2, 3, 4]));\n    assert(res1 == [1,2,3,4,5]);\n    assert(res2 == [6f,7f,8f,9f,10f]);\n\n    // Make sure we've worked around the relevant compiler bugs and this at least\n    // compiles w/ >2 ranges.\n    lockstep(foo, foo, foo);\n\n    // Make sure it works with const.\n    const(int[])[] foo2 = [[1, 2, 3]];\n    const(int[])[] bar2 = [[4, 5, 6]];\n    auto c = chain(foo2, bar2);\n\n    foreach (f, b; lockstep(c, c)) {}\n\n    // Regression 10468\n    foreach (x, y; lockstep(iota(0, 10), iota(0, 10))) { }\n}\n\n@system unittest\n{\n    struct RvalueRange\n    {\n        int[] impl;\n        @property bool empty() { return impl.empty; }\n        @property int front() { return impl[0]; } // N.B. non-ref\n        void popFront() { impl.popFront(); }\n    }\n    auto data1 = [ 1, 2, 3, 4 ];\n    auto data2 = [ 5, 6, 7, 8 ];\n    auto r1 = RvalueRange(data1);\n    auto r2 = data2;\n    foreach (a, ref b; lockstep(r1, r2))\n    {\n        a++;\n        b++;\n    }\n    assert(data1 == [ 1, 2, 3, 4 ]); // changes to a do not propagate to data\n    assert(data2 == [ 6, 7, 8, 9 ]); // but changes to b do.\n\n    // Since r1 is by-value only, the compiler should reject attempts to\n    // foreach over it with ref.\n    static assert(!__traits(compiles, {\n        foreach (ref a, ref b; lockstep(r1, r2)) { a++; }\n    }));\n}\n\nprivate string lockstepReverseFailMixin(Ranges...)(bool withIndex)\n{\n    import std.format : format;\n    string[] params;\n    string message;\n\n    if (withIndex)\n    {\n        message = \"Indexed reverse iteration with lockstep is only supported\"\n        ~\"if all ranges are bidirectional and have a length.\\n\";\n    }\n    else\n    {\n        message = \"Reverse iteration with lockstep is only supported if all ranges are bidirectional.\\n\";\n    }\n\n    if (withIndex)\n    {\n        params ~= \"size_t\";\n    }\n\n    foreach (idx, Range; Ranges)\n    {\n        params ~= format(\"%sElementType!(Ranges[%s])\", hasLvalueElements!Range ? \"ref \" : \"\", idx);\n    }\n\n    return format(\n    q{\n        int opApplyReverse()(scope int delegate(%s) dg)\n        {\n            static assert(false, \"%s\");\n        }\n    }, params.join(\", \"), message);\n}\n\n// For generic programming, make sure Lockstep!(Range) is well defined for a\n// single range.\ntemplate Lockstep(Range)\n{\n    alias Lockstep = Range;\n}\n\n/**\nCreates a mathematical sequence given the initial values and a\nrecurrence function that computes the next value from the existing\nvalues. The sequence comes in the form of an infinite forward\nrange. The type `Recurrence` itself is seldom used directly; most\noften, recurrences are obtained by calling the function $(D\nrecurrence).\n\nWhen calling `recurrence`, the function that computes the next\nvalue is specified as a template argument, and the initial values in\nthe recurrence are passed as regular arguments. For example, in a\nFibonacci sequence, there are two initial values (and therefore a\nstate size of 2) because computing the next Fibonacci value needs the\npast two values.\n\nThe signature of this function should be:\n----\nauto fun(R)(R state, size_t n)\n----\nwhere `n` will be the index of the current value, and `state` will be an\nopaque state vector that can be indexed with array-indexing notation\n`state[i]`, where valid values of `i` range from $(D (n - 1)) to\n$(D (n - State.length)).\n\nIf the function is passed in string form, the state has name `\"a\"`\nand the zero-based index in the recurrence has name `\"n\"`. The\ngiven string must return the desired value for `a[n]` given $(D a[n\n- 1]), $(D a[n - 2]), $(D a[n - 3]),..., $(D a[n - stateSize]). The\nstate size is dictated by the number of arguments passed to the call\nto `recurrence`. The `Recurrence` struct itself takes care of\nmanaging the recurrence's state and shifting it appropriately.\n */\nstruct Recurrence(alias fun, StateType, size_t stateSize)\n{\n    import std.functional : binaryFun;\n\n    StateType[stateSize] _state;\n    size_t _n;\n\n    this(StateType[stateSize] initial) { _state = initial; }\n\n    void popFront()\n    {\n        static auto trustedCycle(ref typeof(_state) s) @trusted\n        {\n            return cycle(s);\n        }\n        // The cast here is reasonable because fun may cause integer\n        // promotion, but needs to return a StateType to make its operation\n        // closed.  Therefore, we have no other choice.\n        _state[_n % stateSize] = cast(StateType) binaryFun!(fun, \"a\", \"n\")(\n            trustedCycle(_state), _n + stateSize);\n        ++_n;\n    }\n\n    @property StateType front()\n    {\n        return _state[_n % stateSize];\n    }\n\n    @property typeof(this) save()\n    {\n        return this;\n    }\n\n    enum bool empty = false;\n}\n\n///\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // The Fibonacci numbers, using function in string form:\n    // a[0] = 1, a[1] = 1, and compute a[n+1] = a[n-1] + a[n]\n    auto fib = recurrence!(\"a[n-1] + a[n-2]\")(1, 1);\n    assert(fib.take(10).equal([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]));\n\n    // The factorials, using function in lambda form:\n    auto fac = recurrence!((a,n) => a[n-1] * n)(1);\n    assert(take(fac, 10).equal([\n        1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880\n    ]));\n\n    // The triangular numbers, using function in explicit form:\n    static size_t genTriangular(R)(R state, size_t n)\n    {\n        return state[n-1] + n;\n    }\n    auto tri = recurrence!genTriangular(0);\n    assert(take(tri, 10).equal([0, 1, 3, 6, 10, 15, 21, 28, 36, 45]));\n}\n\n/// Ditto\nRecurrence!(fun, CommonType!(State), State.length)\nrecurrence(alias fun, State...)(State initial)\n{\n    CommonType!(State)[State.length] state;\n    foreach (i, Unused; State)\n    {\n        state[i] = initial[i];\n    }\n    return typeof(return)(state);\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto fib = recurrence!(\"a[n-1] + a[n-2]\")(1, 1);\n    static assert(isForwardRange!(typeof(fib)));\n\n    int[] witness = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ];\n    assert(equal(take(fib, 10), witness));\n    foreach (e; take(fib, 10)) {}\n    auto fact = recurrence!(\"n * a[n-1]\")(1);\n    assert( equal(take(fact, 10), [1, 1, 2, 2*3, 2*3*4, 2*3*4*5, 2*3*4*5*6,\n                            2*3*4*5*6*7, 2*3*4*5*6*7*8, 2*3*4*5*6*7*8*9][]) );\n    auto piapprox = recurrence!(\"a[n] + (n & 1 ? 4.0 : -4.0) / (2 * n + 3)\")(4.0);\n    foreach (e; take(piapprox, 20)) {}\n    // Thanks to yebblies for this test and the associated fix\n    auto r = recurrence!\"a[n-2]\"(1, 2);\n    witness = [1, 2, 1, 2, 1];\n    assert(equal(take(r, 5), witness));\n}\n\n/**\n   `Sequence` is similar to `Recurrence` except that iteration is\n   presented in the so-called $(HTTP en.wikipedia.org/wiki/Closed_form,\n   closed form). This means that the `n`th element in the series is\n   computable directly from the initial values and `n` itself. This\n   implies that the interface offered by `Sequence` is a random-access\n   range, as opposed to the regular `Recurrence`, which only offers\n   forward iteration.\n\n   The state of the sequence is stored as a `Tuple` so it can be\n   heterogeneous.\n*/\nstruct Sequence(alias fun, State)\n{\nprivate:\n    import std.functional : binaryFun;\n\n    alias compute = binaryFun!(fun, \"a\", \"n\");\n    alias ElementType = typeof(compute(State.init, cast(size_t) 1));\n    State _state;\n    size_t _n;\n\n    static struct DollarToken{}\n\npublic:\n    this(State initial, size_t n = 0)\n    {\n        _state = initial;\n        _n = n;\n    }\n\n    @property ElementType front()\n    {\n        return compute(_state, _n);\n    }\n\n    void popFront()\n    {\n        ++_n;\n    }\n\n    enum opDollar = DollarToken();\n\n    auto opSlice(size_t lower, size_t upper)\n    in\n    {\n        assert(\n            upper >= lower,\n            \"Attempting to slice a Sequence with a larger first argument than the second.\"\n        );\n    }\n    do\n    {\n        return typeof(this)(_state, _n + lower).take(upper - lower);\n    }\n\n    auto opSlice(size_t lower, DollarToken)\n    {\n        return typeof(this)(_state, _n + lower);\n    }\n\n    ElementType opIndex(size_t n)\n    {\n        return compute(_state, n + _n);\n    }\n\n    enum bool empty = false;\n\n    @property Sequence save() { return this; }\n}\n\n/// Ditto\nauto sequence(alias fun, State...)(State args)\n{\n    import std.typecons : Tuple, tuple;\n    alias Return = Sequence!(fun, Tuple!State);\n    return Return(tuple(args));\n}\n\n/// Odd numbers, using function in string form:\npure @safe nothrow @nogc unittest\n{\n    auto odds = sequence!(\"a[0] + n * a[1]\")(1, 2);\n    assert(odds.front == 1);\n    odds.popFront();\n    assert(odds.front == 3);\n    odds.popFront();\n    assert(odds.front == 5);\n}\n\n/// Triangular numbers, using function in lambda form:\npure @safe nothrow @nogc unittest\n{\n    auto tri = sequence!((a,n) => n*(n+1)/2)();\n\n    // Note random access\n    assert(tri[0] == 0);\n    assert(tri[3] == 6);\n    assert(tri[1] == 1);\n    assert(tri[4] == 10);\n    assert(tri[2] == 3);\n}\n\n/// Fibonacci numbers, using function in explicit form:\n@safe nothrow @nogc unittest\n{\n    import std.math : pow, round, sqrt;\n    static ulong computeFib(S)(S state, size_t n)\n    {\n        // Binet's formula\n        return cast(ulong)(round((pow(state[0], n+1) - pow(state[1], n+1)) /\n                                 state[2]));\n    }\n    auto fib = sequence!computeFib(\n        (1.0 + sqrt(5.0)) / 2.0,    // Golden Ratio\n        (1.0 - sqrt(5.0)) / 2.0,    // Conjugate of Golden Ratio\n        sqrt(5.0));\n\n    // Note random access with [] operator\n    assert(fib[1] == 1);\n    assert(fib[4] == 5);\n    assert(fib[3] == 3);\n    assert(fib[2] == 2);\n    assert(fib[9] == 55);\n}\n\npure @safe nothrow @nogc unittest\n{\n    import std.typecons : Tuple, tuple;\n    auto y = Sequence!(\"a[0] + n * a[1]\", Tuple!(int, int))(tuple(0, 4));\n    static assert(isForwardRange!(typeof(y)));\n\n    //@@BUG\n    //auto y = sequence!(\"a[0] + n * a[1]\")(0, 4);\n    //foreach (e; take(y, 15))\n    {}                                 //writeln(e);\n\n    auto odds = Sequence!(\"a[0] + n * a[1]\", Tuple!(int, int))(\n        tuple(1, 2));\n    for (int currentOdd = 1; currentOdd <= 21; currentOdd += 2)\n    {\n        assert(odds.front == odds[0]);\n        assert(odds[0] == currentOdd);\n        odds.popFront();\n    }\n}\n\npure @safe nothrow @nogc unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto odds = sequence!(\"a[0] + n * a[1]\")(1, 2);\n    static assert(hasSlicing!(typeof(odds)));\n\n    //Note: don't use drop or take as the target of an equal,\n    //since they'll both just forward to opSlice, making the tests irrelevant\n\n    // static slicing tests\n    assert(equal(odds[0 .. 5], only(1,  3,  5,  7,  9)));\n    assert(equal(odds[3 .. 7], only(7,  9, 11, 13)));\n\n    // relative slicing test, testing slicing is NOT agnostic of state\n    auto odds_less5 = odds.drop(5); //this should actually call odds[5 .. $]\n    assert(equal(odds_less5[0 ..  3], only(11, 13, 15)));\n    assert(equal(odds_less5[0 .. 10], odds[5 .. 15]));\n\n    //Infinite slicing tests\n    odds = odds[10 .. $];\n    assert(equal(odds.take(3), only(21, 23, 25)));\n}\n\n// Issue 5036\npure @safe nothrow unittest\n{\n    auto s = sequence!((a, n) => new int)(0);\n    assert(s.front != s.front);  // no caching\n}\n\n// iota\n/**\n   Creates a range of values that span the given starting and stopping\n   values.\n\n   Params:\n   begin = The starting value.\n   end = The value that serves as the stopping criterion. This value is not\n        included in the range.\n   step = The value to add to the current value at each iteration.\n\n   Returns:\n   A range that goes through the numbers `begin`, $(D begin + step),\n   $(D begin + 2 * step), `...`, up to and excluding `end`.\n\n   The two-argument overloads have $(D step = 1). If $(D begin < end && step <\n   0) or $(D begin > end && step > 0) or $(D begin == end), then an empty range\n   is returned. If $(D step == 0) then $(D begin == end) is an error.\n\n   For built-in types, the range returned is a random access range. For\n   user-defined types that support `++`, the range is an input\n   range.\n\n   An integral iota also supports `in` operator from the right. It takes\n   the stepping into account, the integral won't be considered\n   contained if it falls between two consecutive values of the range.\n   `contains` does the same as in, but from lefthand side.\n\n    Example:\n    ---\n    void main()\n    {\n        import std.stdio;\n\n        // The following groups all produce the same output of:\n        // 0 1 2 3 4\n\n        foreach (i; 0 .. 5)\n            writef(\"%s \", i);\n        writeln();\n\n        import std.range : iota;\n        foreach (i; iota(0, 5))\n            writef(\"%s \", i);\n        writeln();\n\n        writefln(\"%(%s %|%)\", iota(0, 5));\n\n        import std.algorithm.iteration : map;\n        import std.algorithm.mutation : copy;\n        import std.format;\n        iota(0, 5).map!(i => format(\"%s \", i)).copy(stdout.lockingTextWriter());\n        writeln();\n    }\n    ---\n*/\nauto iota(B, E, S)(B begin, E end, S step)\nif ((isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E)))\n        && isIntegral!S)\n{\n    import std.conv : unsigned;\n\n    alias Value = CommonType!(Unqual!B, Unqual!E);\n    alias StepType = Unqual!S;\n\n    assert(step != 0 || begin == end);\n\n    static struct Result\n    {\n        private Value current, last;\n        private StepType step; // by convention, 0 if range is empty\n\n        this(Value current, Value pastLast, StepType step)\n        {\n            if (current < pastLast && step > 0)\n            {\n                // Iterating upward\n                assert(unsigned((pastLast - current) / step) <= size_t.max);\n                // Cast below can't fail because current < pastLast\n                this.last = cast(Value) (pastLast - 1);\n                this.last -= unsigned(this.last - current) % step;\n            }\n            else if (current > pastLast && step < 0)\n            {\n                // Iterating downward\n                assert(unsigned((current - pastLast) / (0 - step)) <= size_t.max);\n                // Cast below can't fail because current > pastLast\n                this.last = cast(Value) (pastLast + 1);\n                this.last += unsigned(current - this.last) % (0 - step);\n            }\n            else\n            {\n                // Initialize an empty range\n                this.step = 0;\n                return;\n            }\n            this.step = step;\n            this.current = current;\n        }\n\n        @property bool empty() const { return step == 0; }\n        @property inout(Value) front() inout { assert(!empty); return current; }\n        void popFront()\n        {\n            assert(!empty);\n            if (current == last) step = 0;\n            else current += step;\n        }\n\n        @property inout(Value) back() inout\n        {\n            assert(!empty);\n            return last;\n        }\n        void popBack()\n        {\n            assert(!empty);\n            if (current == last) step = 0;\n            else last -= step;\n        }\n\n        @property auto save() { return this; }\n\n        inout(Value) opIndex(ulong n) inout\n        {\n            assert(n < this.length);\n\n            // Just cast to Value here because doing so gives overflow behavior\n            // consistent with calling popFront() n times.\n            return cast(inout Value) (current + step * n);\n        }\n        auto opBinaryRight(string op)(Value val) const\n        if (op == \"in\")\n        {\n            if (empty) return false;\n            //cast to avoid becoming unsigned\n            auto supposedIndex = cast(StepType)(val - current) / step;\n            return supposedIndex < length && supposedIndex * step + current == val;\n        }\n        auto contains(Value x){return x in this;}\n        inout(Result) opSlice() inout { return this; }\n        inout(Result) opSlice(ulong lower, ulong upper) inout\n        {\n            assert(upper >= lower && upper <= this.length);\n\n            return cast(inout Result) Result(\n                cast(Value)(current + lower * step),\n                cast(Value)(current + upper * step),\n                step);\n        }\n        @property size_t length() const\n        {\n            if (step > 0)\n                return 1 + cast(size_t) (unsigned(last - current) / step);\n            if (step < 0)\n                return 1 + cast(size_t) (unsigned(current - last) / (0 - step));\n            return 0;\n        }\n\n        alias opDollar = length;\n    }\n\n    return Result(begin, end, step);\n}\n\n/// Ditto\nauto iota(B, E)(B begin, E end)\nif (isFloatingPoint!(CommonType!(B, E)))\n{\n    return iota(begin, end, CommonType!(B, E)(1));\n}\n\n/// Ditto\nauto iota(B, E)(B begin, E end)\nif (isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E)))\n{\n    import std.conv : unsigned;\n\n    alias Value = CommonType!(Unqual!B, Unqual!E);\n\n    static struct Result\n    {\n        private Value current, pastLast;\n\n        this(Value current, Value pastLast)\n        {\n            if (current < pastLast)\n            {\n                assert(unsigned(pastLast - current) <= size_t.max);\n\n                this.current = current;\n                this.pastLast = pastLast;\n            }\n            else\n            {\n                // Initialize an empty range\n                this.current = this.pastLast = current;\n            }\n        }\n\n        @property bool empty() const { return current == pastLast; }\n        @property inout(Value) front() inout { assert(!empty); return current; }\n        void popFront() { assert(!empty); ++current; }\n\n        @property inout(Value) back() inout { assert(!empty); return cast(inout(Value))(pastLast - 1); }\n        void popBack() { assert(!empty); --pastLast; }\n\n        @property auto save() { return this; }\n\n        inout(Value) opIndex(size_t n) inout\n        {\n            assert(n < this.length);\n\n            // Just cast to Value here because doing so gives overflow behavior\n            // consistent with calling popFront() n times.\n            return cast(inout Value) (current + n);\n        }\n        auto opBinaryRight(string op)(Value val) const\n        if (op == \"in\")\n        {\n            return current <= val && val < pastLast;\n        }\n        auto contains(Value x){return x in this;}\n        inout(Result) opSlice() inout { return this; }\n        inout(Result) opSlice(ulong lower, ulong upper) inout\n        {\n            assert(upper >= lower && upper <= this.length);\n\n            return cast(inout Result) Result(cast(Value)(current + lower),\n                                            cast(Value)(pastLast - (length - upper)));\n        }\n        @property size_t length() const\n        {\n            return cast(size_t)(pastLast - current);\n        }\n\n        alias opDollar = length;\n    }\n\n    return Result(begin, end);\n}\n\n/// Ditto\nauto iota(E)(E end)\nif (is(typeof(iota(E(0), end))))\n{\n    E begin = E(0);\n    return iota(begin, end);\n}\n\n/// Ditto\n// Specialization for floating-point types\nauto iota(B, E, S)(B begin, E end, S step)\nif (isFloatingPoint!(CommonType!(B, E, S)))\nin\n{\n    assert(step != 0, \"iota: step must not be 0\");\n    assert((end - begin) / step >= 0, \"iota: incorrect startup parameters\");\n}\ndo\n{\n    alias Value = Unqual!(CommonType!(B, E, S));\n    static struct Result\n    {\n        private Value start, step;\n        private size_t index, count;\n\n        this(Value start, Value end, Value step)\n        {\n            import std.conv : to;\n\n            this.start = start;\n            this.step = step;\n            immutable fcount = (end - start) / step;\n            count = to!size_t(fcount);\n            auto pastEnd = start + count * step;\n            if (step > 0)\n            {\n                if (pastEnd < end) ++count;\n                assert(start + count * step >= end);\n            }\n            else\n            {\n                if (pastEnd > end) ++count;\n                assert(start + count * step <= end);\n            }\n        }\n\n        @property bool empty() const { return index == count; }\n        @property Value front() const { assert(!empty); return start + step * index; }\n        void popFront()\n        {\n            assert(!empty);\n            ++index;\n        }\n        @property Value back() const\n        {\n            assert(!empty);\n            return start + step * (count - 1);\n        }\n        void popBack()\n        {\n            assert(!empty);\n            --count;\n        }\n\n        @property auto save() { return this; }\n\n        Value opIndex(size_t n) const\n        {\n            assert(n < count);\n            return start + step * (n + index);\n        }\n        inout(Result) opSlice() inout\n        {\n            return this;\n        }\n        inout(Result) opSlice(size_t lower, size_t upper) inout\n        {\n            assert(upper >= lower && upper <= count);\n\n            Result ret = this;\n            ret.index += lower;\n            ret.count = upper - lower + ret.index;\n            return cast(inout Result) ret;\n        }\n        @property size_t length() const\n        {\n            return count - index;\n        }\n\n        alias opDollar = length;\n    }\n\n    return Result(begin, end, step);\n}\n\n///\npure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.math : approxEqual;\n\n    auto r = iota(0, 10, 1);\n    assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));\n    assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));\n    assert(3 in r);\n    assert(r.contains(3)); //Same as above\n    assert(!(10 in r));\n    assert(!(-8 in r));\n    r = iota(0, 11, 3);\n    assert(equal(r, [0, 3, 6, 9]));\n    assert(r[2] == 6);\n    assert(!(2 in r));\n    auto rf = iota(0.0, 0.5, 0.1);\n    assert(approxEqual(rf, [0.0, 0.1, 0.2, 0.3, 0.4]));\n}\n\npure nothrow @nogc @safe unittest\n{\n   //float overloads use std.conv.to so can't be @nogc or nothrow\n    alias ssize_t = Signed!size_t;\n    assert(iota(ssize_t.max, 0, -1).length == ssize_t.max);\n    assert(iota(ssize_t.max, ssize_t.min, -1).length == size_t.max);\n    assert(iota(ssize_t.max, ssize_t.min, -2).length == 1 + size_t.max / 2);\n    assert(iota(ssize_t.min, ssize_t.max, 2).length == 1 + size_t.max / 2);\n    assert(iota(ssize_t.max, ssize_t.min, -3).length == size_t.max / 3);\n}\n\ndebug @system unittest\n{//check the contracts\n    import core.exception : AssertError;\n    import std.exception : assertThrown;\n    assertThrown!AssertError(iota(1,2,0));\n    assertThrown!AssertError(iota(0f,1f,0f));\n    assertThrown!AssertError(iota(1f,0f,0.1f));\n    assertThrown!AssertError(iota(0f,1f,-0.1f));\n}\n\npure @system nothrow unittest\n{\n    int[] a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n    auto r1 = iota(a.ptr, a.ptr + a.length, 1);\n    assert(r1.front == a.ptr);\n    assert(r1.back == a.ptr + a.length - 1);\n    assert(&a[4] in r1);\n}\n\npure @safe nothrow @nogc unittest\n{\n    assert(iota(1UL, 0UL).length == 0);\n    assert(iota(1UL, 0UL, 1).length == 0);\n    assert(iota(0, 1, 1).length == 1);\n    assert(iota(1, 0, -1).length == 1);\n    assert(iota(0, 1, -1).length == 0);\n    assert(iota(ulong.max, 0).length == 0);\n}\n\npure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.searching : count;\n    import std.math : approxEqual, nextUp, nextDown;\n    import std.meta : AliasSeq;\n\n    static assert(is(ElementType!(typeof(iota(0f))) == float));\n\n    static assert(hasLength!(typeof(iota(0, 2))));\n    auto r = iota(0, 10, 1);\n    assert(r[$ - 1] == 9);\n    assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][]));\n\n    auto rSlice = r[2 .. 8];\n    assert(equal(rSlice, [2, 3, 4, 5, 6, 7]));\n\n    rSlice.popFront();\n    assert(rSlice[0] == rSlice.front);\n    assert(rSlice.front == 3);\n\n    rSlice.popBack();\n    assert(rSlice[rSlice.length - 1] == rSlice.back);\n    assert(rSlice.back == 6);\n\n    rSlice = r[0 .. 4];\n    assert(equal(rSlice, [0, 1, 2, 3]));\n    assert(3 in rSlice);\n    assert(!(4 in rSlice));\n\n    auto rr = iota(10);\n    assert(equal(rr, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][]));\n\n    r = iota(0, -10, -1);\n    assert(equal(r, [0, -1, -2, -3, -4, -5, -6, -7, -8, -9][]));\n    rSlice = r[3 .. 9];\n    assert(equal(rSlice, [-3, -4, -5, -6, -7, -8]));\n\n    r = iota(0, -6, -3);\n    assert(equal(r, [0, -3][]));\n    rSlice = r[1 .. 2];\n    assert(equal(rSlice, [-3]));\n\n    r = iota(0, -7, -3);\n    assert(equal(r, [0, -3, -6][]));\n    assert(0 in r);\n    assert(-6 in r);\n    rSlice = r[1 .. 3];\n    assert(equal(rSlice, [-3, -6]));\n    assert(!(0 in rSlice));\n    assert(!(-2 in rSlice));\n    assert(!(-5 in rSlice));\n    assert(!(3 in rSlice));\n    assert(!(-9 in rSlice));\n\n    r = iota(0, 11, 3);\n    assert(equal(r, [0, 3, 6, 9][]));\n    assert(r[2] == 6);\n    rSlice = r[1 .. 3];\n    assert(equal(rSlice, [3, 6]));\n\n    auto rf = iota(0.0, 0.5, 0.1);\n    assert(approxEqual(rf, [0.0, 0.1, 0.2, 0.3, 0.4][]));\n    assert(rf.length == 5);\n\n    rf.popFront();\n    assert(rf.length == 4);\n\n    auto rfSlice = rf[1 .. 4];\n    assert(rfSlice.length == 3);\n    assert(approxEqual(rfSlice, [0.2, 0.3, 0.4]));\n\n    rfSlice.popFront();\n    assert(approxEqual(rfSlice[0], 0.3));\n\n    rf.popFront();\n    assert(rf.length == 3);\n\n    rfSlice = rf[1 .. 3];\n    assert(rfSlice.length == 2);\n    assert(approxEqual(rfSlice, [0.3, 0.4]));\n    assert(approxEqual(rfSlice[0], 0.3));\n\n    // With something just above 0.5\n    rf = iota(0.0, nextUp(0.5), 0.1);\n    assert(approxEqual(rf, [0.0, 0.1, 0.2, 0.3, 0.4, 0.5][]));\n    rf.popBack();\n    assert(rf[rf.length - 1] == rf.back);\n    assert(approxEqual(rf.back, 0.4));\n    assert(rf.length == 5);\n\n    // going down\n    rf = iota(0.0, -0.5, -0.1);\n    assert(approxEqual(rf, [0.0, -0.1, -0.2, -0.3, -0.4][]));\n    rfSlice = rf[2 .. 5];\n    assert(approxEqual(rfSlice, [-0.2, -0.3, -0.4]));\n\n    rf = iota(0.0, nextDown(-0.5), -0.1);\n    assert(approxEqual(rf, [0.0, -0.1, -0.2, -0.3, -0.4, -0.5][]));\n\n    // iota of longs\n    auto rl = iota(5_000_000L);\n    assert(rl.length == 5_000_000L);\n    assert(0 in rl);\n    assert(4_000_000L in rl);\n    assert(!(-4_000_000L in rl));\n    assert(!(5_000_000L in rl));\n\n    // iota of longs with steps\n    auto iota_of_longs_with_steps = iota(50L, 101L, 10);\n    assert(iota_of_longs_with_steps.length == 6);\n    assert(equal(iota_of_longs_with_steps, [50L, 60L, 70L, 80L, 90L, 100L]));\n\n    // iota of unsigned zero length (issue 6222, actually trying to consume it\n    // is the only way to find something is wrong because the public\n    // properties are all correct)\n    auto iota_zero_unsigned = iota(0, 0u, 3);\n    assert(count(iota_zero_unsigned) == 0);\n\n    // unsigned reverse iota can be buggy if .length doesn't take them into\n    // account (issue 7982).\n    assert(iota(10u, 0u, -1).length == 10);\n    assert(iota(10u, 0u, -2).length == 5);\n    assert(iota(uint.max, uint.max-10, -1).length == 10);\n    assert(iota(uint.max, uint.max-10, -2).length == 5);\n    assert(iota(uint.max, 0u, -1).length == uint.max);\n\n    assert(20 in iota(20u, 10u, -2));\n    assert(16 in iota(20u, 10u, -2));\n    assert(!(15 in iota(20u, 10u, -2)));\n    assert(!(10 in iota(20u, 10u, -2)));\n    assert(!(uint.max in iota(20u, 10u, -1)));\n    assert(!(int.min in iota(20u, 10u, -1)));\n    assert(!(int.max in iota(20u, 10u, -1)));\n\n\n    // Issue 8920\n    static foreach (Type; AliasSeq!(byte, ubyte, short, ushort,\n        int, uint, long, ulong))\n    {{\n        Type val;\n        foreach (i; iota(cast(Type) 0, cast(Type) 10)) { val++; }\n        assert(val == 10);\n    }}\n}\n\npure @safe nothrow unittest\n{\n    import std.algorithm.mutation : copy;\n    auto idx = new size_t[100];\n    copy(iota(0, idx.length), idx);\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (range; AliasSeq!(iota(2, 27, 4),\n                             iota(3, 9),\n                             iota(2.7, 12.3, .1),\n                             iota(3.2, 9.7)))\n    {{\n        const cRange = range;\n        const e = cRange.empty;\n        const f = cRange.front;\n        const b = cRange.back;\n        const i = cRange[2];\n        const s1 = cRange[];\n        const s2 = cRange[0 .. 3];\n        const l = cRange.length;\n    }}\n}\n\n@system unittest\n{\n    //The ptr stuff can't be done at compile time, so we unfortunately end\n    //up with some code duplication here.\n    auto arr = [0, 5, 3, 5, 5, 7, 9, 2, 0, 42, 7, 6];\n\n    {\n        const cRange = iota(arr.ptr, arr.ptr + arr.length, 3);\n        const e = cRange.empty;\n        const f = cRange.front;\n        const b = cRange.back;\n        const i = cRange[2];\n        const s1 = cRange[];\n        const s2 = cRange[0 .. 3];\n        const l = cRange.length;\n    }\n\n    {\n        const cRange = iota(arr.ptr, arr.ptr + arr.length);\n        const e = cRange.empty;\n        const f = cRange.front;\n        const b = cRange.back;\n        const i = cRange[2];\n        const s1 = cRange[];\n        const s2 = cRange[0 .. 3];\n        const l = cRange.length;\n    }\n}\n\n@nogc nothrow pure @safe unittest\n{\n    {\n        ushort start = 0, end = 10, step = 2;\n        foreach (i; iota(start, end, step))\n            static assert(is(typeof(i) == ushort));\n    }\n    {\n        ubyte start = 0, end = 255, step = 128;\n        uint x;\n        foreach (i; iota(start, end, step))\n        {\n            static assert(is(typeof(i) == ubyte));\n            ++x;\n        }\n        assert(x == 2);\n    }\n}\n\n/* Generic overload that handles arbitrary types that support arithmetic\n * operations.\n *\n * User-defined types such as $(REF BigInt, std,bigint) are also supported, as long\n * as they can be incremented with `++` and compared with `<` or `==`.\n */\n/// ditto\nauto iota(B, E)(B begin, E end)\nif (!isIntegral!(CommonType!(B, E)) &&\n    !isFloatingPoint!(CommonType!(B, E)) &&\n    !isPointer!(CommonType!(B, E)) &&\n    is(typeof((ref B b) { ++b; })) &&\n    (is(typeof(B.init < E.init)) || is(typeof(B.init == E.init))) )\n{\n    static struct Result\n    {\n        B current;\n        E end;\n\n        @property bool empty()\n        {\n            static if (is(typeof(B.init < E.init)))\n                return !(current < end);\n            else static if (is(typeof(B.init != E.init)))\n                return current == end;\n            else\n                static assert(0);\n        }\n        @property auto front() { return current; }\n        void popFront()\n        {\n            assert(!empty);\n            ++current;\n        }\n    }\n    return Result(begin, end);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // Test iota() for a type that only supports ++ and != but does not have\n    // '<'-ordering.\n    struct Cyclic(int wrapAround)\n    {\n        int current;\n\n        this(int start) { current = start % wrapAround; }\n\n        bool opEquals(Cyclic c) const { return current == c.current; }\n        bool opEquals(int i) const { return current == i; }\n        void opUnary(string op)() if (op == \"++\")\n        {\n            current = (current + 1) % wrapAround;\n        }\n    }\n    alias Cycle5 = Cyclic!5;\n\n    // Easy case\n    auto i1 = iota(Cycle5(1), Cycle5(4));\n    assert(i1.equal([1, 2, 3]));\n\n    // Wraparound case\n    auto i2 = iota(Cycle5(3), Cycle5(2));\n    assert(i2.equal([3, 4, 0, 1 ]));\n}\n\n/**\n   Options for the $(LREF FrontTransversal) and $(LREF Transversal) ranges\n   (below).\n*/\nenum TransverseOptions\n{\n/**\n   When transversed, the elements of a range of ranges are assumed to\n   have different lengths (e.g. a jagged array).\n*/\n    assumeJagged,                      //default\n    /**\n       The transversal enforces that the elements of a range of ranges have\n       all the same length (e.g. an array of arrays, all having the same\n       length). Checking is done once upon construction of the transversal\n       range.\n    */\n        enforceNotJagged,\n    /**\n       The transversal assumes, without verifying, that the elements of a\n       range of ranges have all the same length. This option is useful if\n       checking was already done from the outside of the range.\n    */\n        assumeNotJagged,\n}\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.exception : assertThrown;\n\n    auto arr = [[1, 2], [3, 4, 5]];\n\n    auto r1 = arr.frontTransversal!(TransverseOptions.assumeJagged);\n    assert(r1.equal([1, 3]));\n\n    // throws on construction\n    assertThrown!Exception(arr.frontTransversal!(TransverseOptions.enforceNotJagged));\n\n    auto r2 = arr.frontTransversal!(TransverseOptions.assumeNotJagged);\n    assert(r2.equal([1, 3]));\n\n    // either assuming or checking for equal lengths makes\n    // the result a random access range\n    assert(r2[0] == 1);\n    static assert(!__traits(compiles, r1[0]));\n}\n\n/**\n   Given a range of ranges, iterate transversally through the first\n   elements of each of the enclosed ranges.\n*/\nstruct FrontTransversal(Ror,\n        TransverseOptions opt = TransverseOptions.assumeJagged)\n{\n    alias RangeOfRanges = Unqual!(Ror);\n    alias RangeType     = .ElementType!RangeOfRanges;\n    alias ElementType   = .ElementType!RangeType;\n\n    private void prime()\n    {\n        static if (opt == TransverseOptions.assumeJagged)\n        {\n            while (!_input.empty && _input.front.empty)\n            {\n                _input.popFront();\n            }\n            static if (isBidirectionalRange!RangeOfRanges)\n            {\n                while (!_input.empty && _input.back.empty)\n                {\n                    _input.popBack();\n                }\n            }\n        }\n    }\n\n/**\n   Construction from an input.\n*/\n    this(RangeOfRanges input)\n    {\n        _input = input;\n        prime();\n        static if (opt == TransverseOptions.enforceNotJagged)\n            // (isRandomAccessRange!RangeOfRanges\n            //     && hasLength!RangeType)\n        {\n            import std.exception : enforce;\n\n            if (empty) return;\n            immutable commonLength = _input.front.length;\n            foreach (e; _input)\n            {\n                enforce(e.length == commonLength);\n            }\n        }\n    }\n\n/**\n   Forward range primitives.\n*/\n    static if (isInfinite!RangeOfRanges)\n    {\n        enum bool empty = false;\n    }\n    else\n    {\n        @property bool empty()\n        {\n            static if (opt != TransverseOptions.assumeJagged)\n            {\n                if (!_input.empty)\n                    return _input.front.empty;\n            }\n\n            return _input.empty;\n        }\n    }\n\n    /// Ditto\n    @property auto ref front()\n    {\n        assert(!empty, \"Attempting to fetch the front of an empty FrontTransversal\");\n        return _input.front.front;\n    }\n\n    /// Ditto\n    static if (hasMobileElements!RangeType)\n    {\n        ElementType moveFront()\n        {\n            return _input.front.moveFront();\n        }\n    }\n\n    static if (hasAssignableElements!RangeType)\n    {\n        @property void front(ElementType val)\n        {\n            _input.front.front = val;\n        }\n    }\n\n    /// Ditto\n    void popFront()\n    {\n        assert(!empty, \"Attempting to popFront an empty FrontTransversal\");\n        _input.popFront();\n        prime();\n    }\n\n/**\n   Duplicates this `frontTransversal`. Note that only the encapsulating\n   range of range will be duplicated. Underlying ranges will not be\n   duplicated.\n*/\n    static if (isForwardRange!RangeOfRanges)\n    {\n        @property FrontTransversal save()\n        {\n            return FrontTransversal(_input.save);\n        }\n    }\n\n    static if (isBidirectionalRange!RangeOfRanges)\n    {\n/**\n   Bidirectional primitives. They are offered if $(D\n   isBidirectionalRange!RangeOfRanges).\n*/\n        @property auto ref back()\n        {\n            assert(!empty, \"Attempting to fetch the back of an empty FrontTransversal\");\n            return _input.back.front;\n        }\n        /// Ditto\n        void popBack()\n        {\n            assert(!empty, \"Attempting to popBack an empty FrontTransversal\");\n            _input.popBack();\n            prime();\n        }\n\n        /// Ditto\n        static if (hasMobileElements!RangeType)\n        {\n            ElementType moveBack()\n            {\n                return _input.back.moveFront();\n            }\n        }\n\n        static if (hasAssignableElements!RangeType)\n        {\n            @property void back(ElementType val)\n            {\n                _input.back.front = val;\n            }\n        }\n    }\n\n    static if (isRandomAccessRange!RangeOfRanges &&\n            (opt == TransverseOptions.assumeNotJagged ||\n                    opt == TransverseOptions.enforceNotJagged))\n    {\n/**\n   Random-access primitive. It is offered if $(D\n   isRandomAccessRange!RangeOfRanges && (opt ==\n   TransverseOptions.assumeNotJagged || opt ==\n   TransverseOptions.enforceNotJagged)).\n*/\n        auto ref opIndex(size_t n)\n        {\n            return _input[n].front;\n        }\n\n        /// Ditto\n        static if (hasMobileElements!RangeType)\n        {\n            ElementType moveAt(size_t n)\n            {\n                return _input[n].moveFront();\n            }\n        }\n        /// Ditto\n        static if (hasAssignableElements!RangeType)\n        {\n            void opIndexAssign(ElementType val, size_t n)\n            {\n                _input[n].front = val;\n            }\n        }\n        /// Ditto\n        static if (hasLength!RangeOfRanges)\n        {\n            @property size_t length()\n            {\n                return _input.length;\n            }\n\n            alias opDollar = length;\n        }\n\n/**\n   Slicing if offered if `RangeOfRanges` supports slicing and all the\n   conditions for supporting indexing are met.\n*/\n        static if (hasSlicing!RangeOfRanges)\n        {\n            typeof(this) opSlice(size_t lower, size_t upper)\n            {\n                return typeof(this)(_input[lower .. upper]);\n            }\n        }\n    }\n\n    auto opSlice() { return this; }\n\nprivate:\n    RangeOfRanges _input;\n}\n\n/// Ditto\nFrontTransversal!(RangeOfRanges, opt) frontTransversal(\n    TransverseOptions opt = TransverseOptions.assumeJagged,\n    RangeOfRanges)\n(RangeOfRanges rr)\n{\n    return typeof(return)(rr);\n}\n\n///\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    int[][] x = new int[][2];\n    x[0] = [1, 2];\n    x[1] = [3, 4];\n    auto ror = frontTransversal(x);\n    assert(equal(ror, [ 1, 3 ][]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges, DummyRange, ReturnBy;\n\n    static assert(is(FrontTransversal!(immutable int[][])));\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        auto dummies =\n            [DummyType.init, DummyType.init, DummyType.init, DummyType.init];\n\n        foreach (i, ref elem; dummies)\n        {\n            // Just violate the DummyRange abstraction to get what I want.\n            elem.arr = elem.arr[i..$ - (3 - i)];\n        }\n\n        auto ft = frontTransversal!(TransverseOptions.assumeNotJagged)(dummies);\n        static if (isForwardRange!DummyType)\n        {\n            static assert(isForwardRange!(typeof(ft)));\n        }\n\n        assert(equal(ft, [1, 2, 3, 4]));\n\n        // Test slicing.\n        assert(equal(ft[0 .. 2], [1, 2]));\n        assert(equal(ft[1 .. 3], [2, 3]));\n\n        assert(ft.front == ft.moveFront());\n        assert(ft.back == ft.moveBack());\n        assert(ft.moveAt(1) == ft[1]);\n\n\n        // Test infiniteness propagation.\n        static assert(isInfinite!(typeof(frontTransversal(repeat(\"foo\")))));\n\n        static if (DummyType.r == ReturnBy.Reference)\n        {\n            {\n                ft.front++;\n                scope(exit) ft.front--;\n                assert(dummies.front.front == 2);\n            }\n\n            {\n                ft.front = 5;\n                scope(exit) ft.front = 1;\n                assert(dummies[0].front == 5);\n            }\n\n            {\n                ft.back = 88;\n                scope(exit) ft.back = 4;\n                assert(dummies.back.front == 88);\n            }\n\n            {\n                ft[1] = 99;\n                scope(exit) ft[1] = 2;\n                assert(dummies[1].front == 99);\n            }\n        }\n    }\n}\n\n// Issue 16363\npure @safe nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[][] darr = [[0, 1], [4, 5]];\n    auto ft = frontTransversal!(TransverseOptions.assumeNotJagged)(darr);\n\n    assert(equal(ft, [0, 4]));\n    static assert(isRandomAccessRange!(typeof(ft)));\n}\n\n// Bugzilla 16442\npure @safe nothrow unittest\n{\n    int[][] arr = [[], []];\n\n    auto ft = frontTransversal!(TransverseOptions.assumeNotJagged)(arr);\n    assert(ft.empty);\n}\n\n// ditto\npure @safe unittest\n{\n    int[][] arr = [[], []];\n\n    auto ft = frontTransversal!(TransverseOptions.enforceNotJagged)(arr);\n    assert(ft.empty);\n}\n\n/**\n    Given a range of ranges, iterate transversally through the\n    `n`th element of each of the enclosed ranges. This function\n    is similar to `unzip` in other languages.\n\n    Params:\n        opt = Controls the assumptions the function makes about the lengths\n        of the ranges\n        rr = An input range of random access ranges\n    Returns:\n        At minimum, an input range. Range primitives such as bidirectionality\n        and random access are given if the element type of `rr` provides them.\n*/\nstruct Transversal(Ror,\n        TransverseOptions opt = TransverseOptions.assumeJagged)\n{\n    private alias RangeOfRanges = Unqual!Ror;\n    private alias InnerRange = ElementType!RangeOfRanges;\n    private alias E = ElementType!InnerRange;\n\n    private void prime()\n    {\n        static if (opt == TransverseOptions.assumeJagged)\n        {\n            while (!_input.empty && _input.front.length <= _n)\n            {\n                _input.popFront();\n            }\n            static if (isBidirectionalRange!RangeOfRanges)\n            {\n                while (!_input.empty && _input.back.length <= _n)\n                {\n                    _input.popBack();\n                }\n            }\n        }\n    }\n\n/**\n   Construction from an input and an index.\n*/\n    this(RangeOfRanges input, size_t n)\n    {\n        _input = input;\n        _n = n;\n        prime();\n        static if (opt == TransverseOptions.enforceNotJagged)\n        {\n            import std.exception : enforce;\n\n            if (empty) return;\n            immutable commonLength = _input.front.length;\n            foreach (e; _input)\n            {\n                enforce(e.length == commonLength);\n            }\n        }\n    }\n\n/**\n   Forward range primitives.\n*/\n    static if (isInfinite!(RangeOfRanges))\n    {\n        enum bool empty = false;\n    }\n    else\n    {\n        @property bool empty()\n        {\n            return _input.empty;\n        }\n    }\n\n    /// Ditto\n    @property auto ref front()\n    {\n        assert(!empty, \"Attempting to fetch the front of an empty Transversal\");\n        return _input.front[_n];\n    }\n\n    /// Ditto\n    static if (hasMobileElements!InnerRange)\n    {\n        E moveFront()\n        {\n            return _input.front.moveAt(_n);\n        }\n    }\n\n    /// Ditto\n    static if (hasAssignableElements!InnerRange)\n    {\n        @property void front(E val)\n        {\n            _input.front[_n] = val;\n        }\n    }\n\n\n    /// Ditto\n    void popFront()\n    {\n        assert(!empty, \"Attempting to popFront an empty Transversal\");\n        _input.popFront();\n        prime();\n    }\n\n    /// Ditto\n    static if (isForwardRange!RangeOfRanges)\n    {\n        @property typeof(this) save()\n        {\n            auto ret = this;\n            ret._input = _input.save;\n            return ret;\n        }\n    }\n\n    static if (isBidirectionalRange!RangeOfRanges)\n    {\n/**\n   Bidirectional primitives. They are offered if $(D\n   isBidirectionalRange!RangeOfRanges).\n*/\n        @property auto ref back()\n        {\n            assert(!empty, \"Attempting to fetch the back of an empty Transversal\");\n            return _input.back[_n];\n        }\n\n        /// Ditto\n        void popBack()\n        {\n            assert(!empty, \"Attempting to popBack an empty Transversal\");\n            _input.popBack();\n            prime();\n        }\n\n        /// Ditto\n        static if (hasMobileElements!InnerRange)\n        {\n            E moveBack()\n            {\n                return _input.back.moveAt(_n);\n            }\n        }\n\n        /// Ditto\n        static if (hasAssignableElements!InnerRange)\n        {\n            @property void back(E val)\n            {\n                _input.back[_n] = val;\n            }\n        }\n\n    }\n\n    static if (isRandomAccessRange!RangeOfRanges &&\n            (opt == TransverseOptions.assumeNotJagged ||\n                    opt == TransverseOptions.enforceNotJagged))\n    {\n/**\n   Random-access primitive. It is offered if $(D\n   isRandomAccessRange!RangeOfRanges && (opt ==\n   TransverseOptions.assumeNotJagged || opt ==\n   TransverseOptions.enforceNotJagged)).\n*/\n        auto ref opIndex(size_t n)\n        {\n            return _input[n][_n];\n        }\n\n        /// Ditto\n        static if (hasMobileElements!InnerRange)\n        {\n            E moveAt(size_t n)\n            {\n                return _input[n].moveAt(_n);\n            }\n        }\n\n        /// Ditto\n        static if (hasAssignableElements!InnerRange)\n        {\n            void opIndexAssign(E val, size_t n)\n            {\n                _input[n][_n] = val;\n            }\n        }\n\n        /// Ditto\n        static if (hasLength!RangeOfRanges)\n        {\n            @property size_t length()\n            {\n                return _input.length;\n            }\n\n            alias opDollar = length;\n        }\n\n/**\n   Slicing if offered if `RangeOfRanges` supports slicing and all the\n   conditions for supporting indexing are met.\n*/\n        static if (hasSlicing!RangeOfRanges)\n        {\n            typeof(this) opSlice(size_t lower, size_t upper)\n            {\n                return typeof(this)(_input[lower .. upper], _n);\n            }\n        }\n    }\n\n    auto opSlice() { return this; }\n\nprivate:\n    RangeOfRanges _input;\n    size_t _n;\n}\n\n/// Ditto\nTransversal!(RangeOfRanges, opt) transversal\n(TransverseOptions opt = TransverseOptions.assumeJagged, RangeOfRanges)\n(RangeOfRanges rr, size_t n)\n{\n    return typeof(return)(rr, n);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    int[][] x = new int[][2];\n    x[0] = [1, 2];\n    x[1] = [3, 4];\n    auto ror = transversal(x, 1);\n    assert(equal(ror, [ 2, 4 ]));\n}\n\n/// The following code does a full unzip\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    int[][] y = [[1, 2, 3], [4, 5, 6]];\n    auto z = y.front.walkLength.iota.map!(i => transversal(y, i));\n    assert(equal!equal(z, [[1, 4], [2, 5], [3, 6]]));\n}\n\n@safe unittest\n{\n    import std.internal.test.dummyrange : DummyRange, Length, RangeType, ReturnBy;\n\n    int[][] x = new int[][2];\n    x[0] = [ 1, 2 ];\n    x[1] = [3, 4];\n    auto ror = transversal!(TransverseOptions.assumeNotJagged)(x, 1);\n    auto witness = [ 2, 4 ];\n    uint i;\n    foreach (e; ror) assert(e == witness[i++]);\n    assert(i == 2);\n    assert(ror.length == 2);\n\n    static assert(is(Transversal!(immutable int[][])));\n\n    // Make sure ref, assign is being propagated.\n    {\n        ror.front++;\n        scope(exit) ror.front--;\n        assert(x[0][1] == 3);\n    }\n    {\n        ror.front = 5;\n        scope(exit) ror.front = 2;\n        assert(x[0][1] == 5);\n        assert(ror.moveFront() == 5);\n    }\n    {\n        ror.back = 999;\n        scope(exit) ror.back = 4;\n        assert(x[1][1] == 999);\n        assert(ror.moveBack() == 999);\n    }\n    {\n        ror[0] = 999;\n        scope(exit) ror[0] = 2;\n        assert(x[0][1] == 999);\n        assert(ror.moveAt(0) == 999);\n    }\n\n    // Test w/o ref return.\n    alias D = DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Random);\n    auto drs = [D.init, D.init];\n    foreach (num; 0 .. 10)\n    {\n        auto t = transversal!(TransverseOptions.enforceNotJagged)(drs, num);\n        assert(t[0] == t[1]);\n        assert(t[1] == num + 1);\n    }\n\n    static assert(isInfinite!(typeof(transversal(repeat([1,2,3]), 1))));\n\n    // Test slicing.\n    auto mat = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]];\n    auto mat1 = transversal!(TransverseOptions.assumeNotJagged)(mat, 1)[1 .. 3];\n    assert(mat1[0] == 6);\n    assert(mat1[1] == 10);\n}\n\nstruct Transposed(RangeOfRanges,\n    TransverseOptions opt = TransverseOptions.assumeJagged)\nif (isForwardRange!RangeOfRanges &&\n    isInputRange!(ElementType!RangeOfRanges) &&\n    hasAssignableElements!RangeOfRanges)\n{\n    this(RangeOfRanges input)\n    {\n        this._input = input;\n        static if (opt == TransverseOptions.enforceNotJagged)\n        {\n            import std.exception : enforce;\n\n            if (empty) return;\n            immutable commonLength = _input.front.length;\n            foreach (e; _input)\n            {\n                enforce(e.length == commonLength);\n            }\n        }\n    }\n\n    @property auto front()\n    {\n        import std.algorithm.iteration : filter, map;\n        return _input.save\n                     .filter!(a => !a.empty)\n                     .map!(a => a.front);\n    }\n\n    void popFront()\n    {\n        // Advance the position of each subrange.\n        auto r = _input.save;\n        while (!r.empty)\n        {\n            auto e = r.front;\n            if (!e.empty)\n            {\n                e.popFront();\n                r.front = e;\n            }\n\n            r.popFront();\n        }\n    }\n\n    static if (isRandomAccessRange!(ElementType!RangeOfRanges))\n    {\n        auto ref opIndex(size_t n)\n        {\n            return transversal!opt(_input, n);\n        }\n    }\n\n    @property bool empty()\n    {\n        if (_input.empty) return true;\n        foreach (e; _input.save)\n        {\n            if (!e.empty) return false;\n        }\n        return true;\n    }\n\n    deprecated(\"This function is incorrect and will be removed November 2018. See the docs for more details.\")\n    @property Transposed save()\n    {\n        return Transposed(_input.save);\n    }\n\n    auto opSlice() { return this; }\n\nprivate:\n    RangeOfRanges _input;\n}\n\n@safe unittest\n{\n    // Boundary case: transpose of empty range should be empty\n    int[][] ror = [];\n    assert(transposed(ror).empty);\n}\n\n// Issue 9507\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto r = [[1,2], [3], [4,5], [], [6]];\n    assert(r.transposed.equal!equal([\n        [1, 3, 4, 6],\n        [2, 5]\n    ]));\n}\n\n// Issue 17742\n@safe unittest\n{\n    import std.algorithm.iteration : map;\n    import std.algorithm.comparison : equal;\n    auto ror = 5.iota.map!(y => 5.iota.map!(x => x * y).array).array;\n    assert(ror[3][2] == 6);\n    auto result = transposed!(TransverseOptions.assumeNotJagged)(ror);\n    assert(result[2][3] == 6);\n\n    auto x = [[1,2,3],[4,5,6]];\n    auto y = transposed!(TransverseOptions.assumeNotJagged)(x);\n    assert(y.front.equal([1,4]));\n    assert(y[0].equal([1,4]));\n    assert(y[0][0] == 1);\n    assert(y[1].equal([2,5]));\n    assert(y[1][1] == 5);\n\n    auto yy = transposed!(TransverseOptions.enforceNotJagged)(x);\n    assert(yy.front.equal([1,4]));\n    assert(yy[0].equal([1,4]));\n    assert(yy[0][0] == 1);\n    assert(yy[1].equal([2,5]));\n    assert(yy[1][1] == 5);\n\n    auto z = x.transposed; // assumeJagged\n    assert(z.front.equal([1,4]));\n    assert(z[0].equal([1,4]));\n    assert(!is(typeof(z[0][0])));\n}\n\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    auto r = [[1,2], [3], [4,5], [], [6]];\n    assertThrown(r.transposed!(TransverseOptions.enforceNotJagged));\n}\n\n/**\nGiven a range of ranges, returns a range of ranges where the $(I i)'th subrange\ncontains the $(I i)'th elements of the original subranges.\n\n$(RED `Transposed` currently defines `save`, but does not work as a forward range.\nConsuming a copy made with `save` will consume all copies, even the original sub-ranges\nfed into `Transposed`.)\n\nParams:\n    opt = Controls the assumptions the function makes about the lengths of the ranges (i.e. jagged or not)\n    rr = Range of ranges\n */\nTransposed!(RangeOfRanges, opt) transposed\n(TransverseOptions opt = TransverseOptions.assumeJagged, RangeOfRanges)\n(RangeOfRanges rr)\nif (isForwardRange!RangeOfRanges &&\n    isInputRange!(ElementType!RangeOfRanges) &&\n    hasAssignableElements!RangeOfRanges)\n{\n    return Transposed!(RangeOfRanges, opt)(rr);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    int[][] ror = [\n        [1, 2, 3],\n        [4, 5, 6]\n    ];\n    auto xp = transposed(ror);\n    assert(equal!\"a.equal(b)\"(xp, [\n        [1, 4],\n        [2, 5],\n        [3, 6]\n    ]));\n}\n\n///\n@safe unittest\n{\n    int[][] x = new int[][2];\n    x[0] = [1, 2];\n    x[1] = [3, 4];\n    auto tr = transposed(x);\n    int[][] witness = [ [ 1, 3 ], [ 2, 4 ] ];\n    uint i;\n\n    foreach (e; tr)\n    {\n        assert(array(e) == witness[i++]);\n    }\n}\n\n// Issue 8764\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    ulong[1] t0 = [ 123 ];\n\n    assert(!hasAssignableElements!(typeof(t0[].chunks(1))));\n    assert(!is(typeof(transposed(t0[].chunks(1)))));\n    assert(is(typeof(transposed(t0[].chunks(1).array()))));\n\n    auto t1 = transposed(t0[].chunks(1).array());\n    assert(equal!\"a.equal(b)\"(t1, [[123]]));\n}\n\n/**\nThis struct takes two ranges, `source` and `indices`, and creates a view\nof `source` as if its elements were reordered according to `indices`.\n`indices` may include only a subset of the elements of `source` and\nmay also repeat elements.\n\n`Source` must be a random access range.  The returned range will be\nbidirectional or random-access if `Indices` is bidirectional or\nrandom-access, respectively.\n*/\nstruct Indexed(Source, Indices)\nif (isRandomAccessRange!Source && isInputRange!Indices &&\n    is(typeof(Source.init[ElementType!(Indices).init])))\n{\n    this(Source source, Indices indices)\n    {\n        this._source = source;\n        this._indices = indices;\n    }\n\n    /// Range primitives\n    @property auto ref front()\n    {\n        assert(!empty, \"Attempting to fetch the front of an empty Indexed\");\n        return _source[_indices.front];\n    }\n\n    /// Ditto\n    void popFront()\n    {\n        assert(!empty, \"Attempting to popFront an empty Indexed\");\n        _indices.popFront();\n    }\n\n    static if (isInfinite!Indices)\n    {\n        enum bool empty = false;\n    }\n    else\n    {\n        /// Ditto\n        @property bool empty()\n        {\n            return _indices.empty;\n        }\n    }\n\n    static if (isForwardRange!Indices)\n    {\n        /// Ditto\n        @property typeof(this) save()\n        {\n            // Don't need to save _source because it's never consumed.\n            return typeof(this)(_source, _indices.save);\n        }\n    }\n\n    /// Ditto\n    static if (hasAssignableElements!Source)\n    {\n        @property auto ref front(ElementType!Source newVal)\n        {\n            assert(!empty);\n            return _source[_indices.front] = newVal;\n        }\n    }\n\n\n    static if (hasMobileElements!Source)\n    {\n        /// Ditto\n        auto moveFront()\n        {\n            assert(!empty);\n            return _source.moveAt(_indices.front);\n        }\n    }\n\n    static if (isBidirectionalRange!Indices)\n    {\n        /// Ditto\n        @property auto ref back()\n        {\n            assert(!empty, \"Attempting to fetch the back of an empty Indexed\");\n            return _source[_indices.back];\n        }\n\n        /// Ditto\n        void popBack()\n        {\n           assert(!empty, \"Attempting to popBack an empty Indexed\");\n           _indices.popBack();\n        }\n\n        /// Ditto\n        static if (hasAssignableElements!Source)\n        {\n            @property auto ref back(ElementType!Source newVal)\n            {\n                assert(!empty);\n                return _source[_indices.back] = newVal;\n            }\n        }\n\n\n        static if (hasMobileElements!Source)\n        {\n            /// Ditto\n            auto moveBack()\n            {\n                assert(!empty);\n                return _source.moveAt(_indices.back);\n            }\n        }\n    }\n\n    static if (hasLength!Indices)\n    {\n        /// Ditto\n         @property size_t length()\n        {\n            return _indices.length;\n        }\n\n        alias opDollar = length;\n    }\n\n    static if (isRandomAccessRange!Indices)\n    {\n        /// Ditto\n        auto ref opIndex(size_t index)\n        {\n            return _source[_indices[index]];\n        }\n\n        static if (hasSlicing!Indices)\n        {\n            /// Ditto\n            typeof(this) opSlice(size_t a, size_t b)\n            {\n                return typeof(this)(_source, _indices[a .. b]);\n            }\n        }\n\n\n        static if (hasAssignableElements!Source)\n        {\n            /// Ditto\n            auto opIndexAssign(ElementType!Source newVal, size_t index)\n            {\n                return _source[_indices[index]] = newVal;\n            }\n        }\n\n\n        static if (hasMobileElements!Source)\n        {\n            /// Ditto\n            auto moveAt(size_t index)\n            {\n                return _source.moveAt(_indices[index]);\n            }\n        }\n    }\n\n    // All this stuff is useful if someone wants to index an Indexed\n    // without adding a layer of indirection.\n\n    /**\n    Returns the source range.\n    */\n    @property Source source()\n    {\n        return _source;\n    }\n\n    /**\n    Returns the indices range.\n    */\n     @property Indices indices()\n    {\n        return _indices;\n    }\n\n    static if (isRandomAccessRange!Indices)\n    {\n        /**\n        Returns the physical index into the source range corresponding to a\n        given logical index.  This is useful, for example, when indexing\n        an `Indexed` without adding another layer of indirection.\n        */\n        size_t physicalIndex(size_t logicalIndex)\n        {\n            return _indices[logicalIndex];\n        }\n\n        ///\n        @safe unittest\n        {\n            auto ind = indexed([1, 2, 3, 4, 5], [1, 3, 4]);\n            assert(ind.physicalIndex(0) == 1);\n        }\n    }\n\nprivate:\n    Source _source;\n    Indices _indices;\n\n}\n\n/// Ditto\nIndexed!(Source, Indices) indexed(Source, Indices)(Source source, Indices indices)\n{\n    return typeof(return)(source, indices);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto source = [1, 2, 3, 4, 5];\n    auto indices = [4, 3, 1, 2, 0, 4];\n    auto ind = indexed(source, indices);\n    assert(equal(ind, [5, 4, 2, 3, 1, 5]));\n    assert(equal(retro(ind), [5, 1, 3, 2, 4, 5]));\n}\n\n@safe unittest\n{\n    {\n        auto ind = indexed([1, 2, 3, 4, 5], [1, 3, 4]);\n        assert(ind.physicalIndex(0) == 1);\n    }\n\n    auto source = [1, 2, 3, 4, 5];\n    auto indices = [4, 3, 1, 2, 0, 4];\n    auto ind = indexed(source, indices);\n\n    // When elements of indices are duplicated and Source has lvalue elements,\n    // these are aliased in ind.\n    ind[0]++;\n    assert(ind[0] == 6);\n    assert(ind[5] == 6);\n}\n\n@safe unittest\n{\n    import std.internal.test.dummyrange : AllDummyRanges, propagatesLength,\n        propagatesRangeType, RangeType;\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        auto d = DummyType.init;\n        auto r = indexed([1, 2, 3, 4, 5], d);\n        static assert(propagatesRangeType!(DummyType, typeof(r)));\n        static assert(propagatesLength!(DummyType, typeof(r)));\n    }\n}\n\n/**\nThis range iterates over fixed-sized chunks of size `chunkSize` of a\n`source` range. `Source` must be an $(REF_ALTTEXT input range, isInputRange, std,range,primitives).\n`chunkSize` must be greater than zero.\n\nIf `!isInfinite!Source` and `source.walkLength` is not evenly\ndivisible by `chunkSize`, the back element of this range will contain\nfewer than `chunkSize` elements.\n\nIf `Source` is a forward range, the resulting range will be forward ranges as\nwell. Otherwise, the resulting chunks will be input ranges consuming the same\ninput: iterating over `front` will shrink the chunk such that subsequent\ninvocations of `front` will no longer return the full chunk, and calling\n`popFront` on the outer range will invalidate any lingering references to\nprevious values of `front`.\n\nParams:\n    source = Range from which the chunks will be selected\n    chunkSize = Chunk size\n\nSee_Also: $(LREF slide)\n\nReturns: Range of chunks.\n*/\nstruct Chunks(Source)\nif (isInputRange!Source)\n{\n    static if (isForwardRange!Source)\n    {\n        /// Standard constructor\n        this(Source source, size_t chunkSize)\n        {\n            assert(chunkSize != 0, \"Cannot create a Chunk with an empty chunkSize\");\n            _source = source;\n            _chunkSize = chunkSize;\n        }\n\n        /// Input range primitives. Always present.\n        @property auto front()\n        {\n            assert(!empty, \"Attempting to fetch the front of an empty Chunks\");\n            return _source.save.take(_chunkSize);\n        }\n\n        /// Ditto\n        void popFront()\n        {\n            assert(!empty, \"Attempting to popFront and empty Chunks\");\n            _source.popFrontN(_chunkSize);\n        }\n\n        static if (!isInfinite!Source)\n            /// Ditto\n            @property bool empty()\n            {\n                return _source.empty;\n            }\n        else\n            // undocumented\n            enum empty = false;\n\n        /// Forward range primitives. Only present if `Source` is a forward range.\n        @property typeof(this) save()\n        {\n            return typeof(this)(_source.save, _chunkSize);\n        }\n\n        static if (hasLength!Source)\n        {\n            /// Length. Only if `hasLength!Source` is `true`\n            @property size_t length()\n            {\n                // Note: _source.length + _chunkSize may actually overflow.\n                // We cast to ulong to mitigate the problem on x86 machines.\n                // For x64 machines, we just suppose we'll never overflow.\n                // The \"safe\" code would require either an extra branch, or a\n                //   modulo operation, which is too expensive for such a rare case\n                return cast(size_t)((cast(ulong)(_source.length) + _chunkSize - 1) / _chunkSize);\n            }\n            //Note: No point in defining opDollar here without slicing.\n            //opDollar is defined below in the hasSlicing!Source section\n        }\n\n        static if (hasSlicing!Source)\n        {\n            //Used for various purposes\n            private enum hasSliceToEnd = is(typeof(Source.init[_chunkSize .. $]) == Source);\n\n            /**\n            Indexing and slicing operations. Provided only if\n            `hasSlicing!Source` is `true`.\n             */\n            auto opIndex(size_t index)\n            {\n                immutable start = index * _chunkSize;\n                immutable end   = start + _chunkSize;\n\n                static if (isInfinite!Source)\n                    return _source[start .. end];\n                else\n                {\n                    import std.algorithm.comparison : min;\n                    immutable len = _source.length;\n                    assert(start < len, \"chunks index out of bounds\");\n                    return _source[start .. min(end, len)];\n                }\n            }\n\n            /// Ditto\n            static if (hasLength!Source)\n                typeof(this) opSlice(size_t lower, size_t upper)\n                {\n                    import std.algorithm.comparison : min;\n                    assert(lower <= upper && upper <= length, \"chunks slicing index out of bounds\");\n                    immutable len = _source.length;\n                    return chunks(_source[min(lower * _chunkSize, len) .. min(upper * _chunkSize, len)], _chunkSize);\n                }\n            else static if (hasSliceToEnd)\n                //For slicing an infinite chunk, we need to slice the source to the end.\n                typeof(takeExactly(this, 0)) opSlice(size_t lower, size_t upper)\n                {\n                    assert(lower <= upper, \"chunks slicing index out of bounds\");\n                    return chunks(_source[lower * _chunkSize .. $], _chunkSize).takeExactly(upper - lower);\n                }\n\n            static if (isInfinite!Source)\n            {\n                static if (hasSliceToEnd)\n                {\n                    private static struct DollarToken{}\n                    DollarToken opDollar()\n                    {\n                        return DollarToken();\n                    }\n                    //Slice to dollar\n                    typeof(this) opSlice(size_t lower, DollarToken)\n                    {\n                        return typeof(this)(_source[lower * _chunkSize .. $], _chunkSize);\n                    }\n                }\n            }\n            else\n            {\n                //Dollar token carries a static type, with no extra information.\n                //It can lazily transform into _source.length on algorithmic\n                //operations such as : chunks[$/2, $-1];\n                private static struct DollarToken\n                {\n                    Chunks!Source* mom;\n                    @property size_t momLength()\n                    {\n                        return mom.length;\n                    }\n                    alias momLength this;\n                }\n                DollarToken opDollar()\n                {\n                    return DollarToken(&this);\n                }\n\n                //Slice overloads optimized for using dollar. Without this, to slice to end, we would...\n                //1. Evaluate chunks.length\n                //2. Multiply by _chunksSize\n                //3. To finally just compare it (with min) to the original length of source (!)\n                //These overloads avoid that.\n                typeof(this) opSlice(DollarToken, DollarToken)\n                {\n                    static if (hasSliceToEnd)\n                        return chunks(_source[$ .. $], _chunkSize);\n                    else\n                    {\n                        immutable len = _source.length;\n                        return chunks(_source[len .. len], _chunkSize);\n                    }\n                }\n                typeof(this) opSlice(size_t lower, DollarToken)\n                {\n                    import std.algorithm.comparison : min;\n                    assert(lower <= length, \"chunks slicing index out of bounds\");\n                    static if (hasSliceToEnd)\n                        return chunks(_source[min(lower * _chunkSize, _source.length) .. $], _chunkSize);\n                    else\n                    {\n                        immutable len = _source.length;\n                        return chunks(_source[min(lower * _chunkSize, len) .. len], _chunkSize);\n                    }\n                }\n                typeof(this) opSlice(DollarToken, size_t upper)\n                {\n                    assert(upper == length, \"chunks slicing index out of bounds\");\n                    return this[$ .. $];\n                }\n            }\n        }\n\n        //Bidirectional range primitives\n        static if (hasSlicing!Source && hasLength!Source)\n        {\n            /**\n            Bidirectional range primitives. Provided only if both\n            `hasSlicing!Source` and `hasLength!Source` are `true`.\n             */\n            @property auto back()\n            {\n                assert(!empty, \"back called on empty chunks\");\n                immutable len = _source.length;\n                immutable start = (len - 1) / _chunkSize * _chunkSize;\n                return _source[start .. len];\n            }\n\n            /// Ditto\n            void popBack()\n            {\n                assert(!empty, \"popBack() called on empty chunks\");\n                immutable end = (_source.length - 1) / _chunkSize * _chunkSize;\n                _source = _source[0 .. end];\n            }\n        }\n\n    private:\n        Source _source;\n        size_t _chunkSize;\n    }\n    else // is input range only\n    {\n        import std.typecons : RefCounted;\n\n        static struct Chunk\n        {\n            private RefCounted!Impl impl;\n\n            @property bool empty() { return impl.curSizeLeft == 0 || impl.r.empty; }\n            @property auto front() { return impl.r.front; }\n            void popFront()\n            {\n                assert(impl.curSizeLeft > 0 && !impl.r.empty);\n                impl.curSizeLeft--;\n                impl.r.popFront();\n            }\n        }\n\n        static struct Impl\n        {\n            private Source r;\n            private size_t chunkSize;\n            private size_t curSizeLeft;\n        }\n\n        private RefCounted!Impl impl;\n\n        private this(Source r, size_t chunkSize)\n        {\n            impl = RefCounted!Impl(r, r.empty ? 0 : chunkSize, chunkSize);\n        }\n\n        @property bool empty() { return impl.chunkSize == 0; }\n        @property Chunk front() return { return Chunk(impl); }\n\n        void popFront()\n        {\n            impl.curSizeLeft -= impl.r.popFrontN(impl.curSizeLeft);\n            if (!impl.r.empty)\n                impl.curSizeLeft = impl.chunkSize;\n            else\n                impl.chunkSize = 0;\n        }\n\n        static assert(isInputRange!(typeof(this)));\n    }\n}\n\n/// Ditto\nChunks!Source chunks(Source)(Source source, size_t chunkSize)\nif (isInputRange!Source)\n{\n    return typeof(return)(source, chunkSize);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    auto chunks = chunks(source, 4);\n    assert(chunks[0] == [1, 2, 3, 4]);\n    assert(chunks[1] == [5, 6, 7, 8]);\n    assert(chunks[2] == [9, 10]);\n    assert(chunks.back == chunks[2]);\n    assert(chunks.front == chunks[0]);\n    assert(chunks.length == 3);\n    assert(equal(retro(array(chunks)), array(retro(chunks))));\n}\n\n/// Non-forward input ranges are supported, but with limited semantics.\n@system /*@safe*/ unittest // FIXME: can't be @safe because RefCounted isn't.\n{\n    import std.algorithm.comparison : equal;\n\n    int i;\n\n    // The generator doesn't save state, so it cannot be a forward range.\n    auto inputRange = generate!(() => ++i).take(10);\n\n    // We can still process it in chunks, but it will be single-pass only.\n    auto chunked = inputRange.chunks(2);\n\n    assert(chunked.front.equal([1, 2]));\n    assert(chunked.front.empty); // Iterating the chunk has consumed it\n    chunked.popFront;\n    assert(chunked.front.equal([3, 4]));\n}\n\n@system /*@safe*/ unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : ReferenceInputRange;\n\n    auto data = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\n    auto r = new ReferenceInputRange!int(data).chunks(3);\n    assert(r.equal!equal([\n        [ 1, 2, 3 ],\n        [ 4, 5, 6 ],\n        [ 7, 8, 9 ],\n        [ 10 ]\n    ]));\n\n    auto data2 = [ 1, 2, 3, 4, 5, 6 ];\n    auto r2 = new ReferenceInputRange!int(data2).chunks(3);\n    assert(r2.equal!equal([\n        [ 1, 2, 3 ],\n        [ 4, 5, 6 ]\n    ]));\n\n    auto data3 = [ 1, 2, 3, 4, 5 ];\n    auto r3 = new ReferenceInputRange!int(data3).chunks(2);\n    assert(r3.front.equal([1, 2]));\n    r3.popFront();\n    assert(!r3.empty);\n    r3.popFront();\n    assert(r3.front.equal([5]));\n}\n\n@safe unittest\n{\n    auto source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    auto chunks = chunks(source, 4);\n    auto chunks2 = chunks.save;\n    chunks.popFront();\n    assert(chunks[0] == [5, 6, 7, 8]);\n    assert(chunks[1] == [9, 10]);\n    chunks2.popBack();\n    assert(chunks2[1] == [5, 6, 7, 8]);\n    assert(chunks2.length == 2);\n\n    static assert(isRandomAccessRange!(typeof(chunks)));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    //Extra toying with slicing and indexing.\n    auto chunks1 = [0, 0, 1, 1, 2, 2, 3, 3, 4].chunks(2);\n    auto chunks2 = [0, 0, 1, 1, 2, 2, 3, 3, 4, 4].chunks(2);\n\n    assert(chunks1.length == 5);\n    assert(chunks2.length == 5);\n    assert(chunks1[4] == [4]);\n    assert(chunks2[4] == [4, 4]);\n    assert(chunks1.back == [4]);\n    assert(chunks2.back == [4, 4]);\n\n    assert(chunks1[0 .. 1].equal([[0, 0]]));\n    assert(chunks1[0 .. 2].equal([[0, 0], [1, 1]]));\n    assert(chunks1[4 .. 5].equal([[4]]));\n    assert(chunks2[4 .. 5].equal([[4, 4]]));\n\n    assert(chunks1[0 .. 0].equal((int[][]).init));\n    assert(chunks1[5 .. 5].equal((int[][]).init));\n    assert(chunks2[5 .. 5].equal((int[][]).init));\n\n    //Fun with opDollar\n    assert(chunks1[$ .. $].equal((int[][]).init)); //Quick\n    assert(chunks2[$ .. $].equal((int[][]).init)); //Quick\n    assert(chunks1[$ - 1 .. $].equal([[4]]));      //Semiquick\n    assert(chunks2[$ - 1 .. $].equal([[4, 4]]));   //Semiquick\n    assert(chunks1[$ .. 5].equal((int[][]).init)); //Semiquick\n    assert(chunks2[$ .. 5].equal((int[][]).init)); //Semiquick\n\n    assert(chunks1[$ / 2 .. $ - 1].equal([[2, 2], [3, 3]])); //Slow\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter;\n\n    //ForwardRange\n    auto r = filter!\"true\"([1, 2, 3, 4, 5]).chunks(2);\n    assert(equal!\"equal(a, b)\"(r, [[1, 2], [3, 4], [5]]));\n\n    //InfiniteRange w/o RA\n    auto fibsByPairs = recurrence!\"a[n-1] + a[n-2]\"(1, 1).chunks(2);\n    assert(equal!`equal(a, b)`(fibsByPairs.take(2),         [[ 1,  1], [ 2,  3]]));\n\n    //InfiniteRange w/ RA and slicing\n    auto odds = sequence!(\"a[0] + n * a[1]\")(1, 2);\n    auto oddsByPairs = odds.chunks(2);\n    assert(equal!`equal(a, b)`(oddsByPairs.take(2),         [[ 1,  3], [ 5,  7]]));\n\n    //Requires phobos#991 for Sequence to have slice to end\n    static assert(hasSlicing!(typeof(odds)));\n    assert(equal!`equal(a, b)`(oddsByPairs[3 .. 5],         [[13, 15], [17, 19]]));\n    assert(equal!`equal(a, b)`(oddsByPairs[3 .. $].take(2), [[13, 15], [17, 19]]));\n}\n\n\n\n/**\nThis range splits a `source` range into `chunkCount` chunks of\napproximately equal length. `Source` must be a forward range with\nknown length.\n\nUnlike $(LREF chunks), `evenChunks` takes a chunk count (not size).\nThe returned range will contain zero or more $(D source.length /\nchunkCount + 1) elements followed by $(D source.length / chunkCount)\nelements. If $(D source.length < chunkCount), some chunks will be empty.\n\n`chunkCount` must not be zero, unless `source` is also empty.\n*/\nstruct EvenChunks(Source)\nif (isForwardRange!Source && hasLength!Source)\n{\n    /// Standard constructor\n    this(Source source, size_t chunkCount)\n    {\n        assert(chunkCount != 0 || source.empty, \"Cannot create EvenChunks with a zero chunkCount\");\n        _source = source;\n        _chunkCount = chunkCount;\n    }\n\n    /// Forward range primitives. Always present.\n    @property auto front()\n    {\n        assert(!empty, \"Attempting to fetch the front of an empty evenChunks\");\n        return _source.save.take(_chunkPos(1));\n    }\n\n    /// Ditto\n    void popFront()\n    {\n        assert(!empty, \"Attempting to popFront an empty evenChunks\");\n        _source.popFrontN(_chunkPos(1));\n        _chunkCount--;\n    }\n\n    /// Ditto\n    @property bool empty()\n    {\n        return _source.empty;\n    }\n\n    /// Ditto\n    @property typeof(this) save()\n    {\n        return typeof(this)(_source.save, _chunkCount);\n    }\n\n    /// Length\n    @property size_t length() const\n    {\n        return _chunkCount;\n    }\n    //Note: No point in defining opDollar here without slicing.\n    //opDollar is defined below in the hasSlicing!Source section\n\n    static if (hasSlicing!Source)\n    {\n        /**\n        Indexing, slicing and bidirectional operations and range primitives.\n        Provided only if `hasSlicing!Source` is `true`.\n         */\n        auto opIndex(size_t index)\n        {\n            assert(index < _chunkCount, \"evenChunks index out of bounds\");\n            return _source[_chunkPos(index) .. _chunkPos(index+1)];\n        }\n\n        /// Ditto\n        typeof(this) opSlice(size_t lower, size_t upper)\n        {\n            assert(lower <= upper && upper <= length, \"evenChunks slicing index out of bounds\");\n            return evenChunks(_source[_chunkPos(lower) .. _chunkPos(upper)], upper - lower);\n        }\n\n        /// Ditto\n        @property auto back()\n        {\n            assert(!empty, \"back called on empty evenChunks\");\n            return _source[_chunkPos(_chunkCount - 1) .. _source.length];\n        }\n\n        /// Ditto\n        void popBack()\n        {\n            assert(!empty, \"popBack() called on empty evenChunks\");\n            _source = _source[0 .. _chunkPos(_chunkCount - 1)];\n            _chunkCount--;\n        }\n    }\n\nprivate:\n    Source _source;\n    size_t _chunkCount;\n\n    size_t _chunkPos(size_t i)\n    {\n        /*\n            _chunkCount = 5, _source.length = 13:\n\n               chunk0\n                 |   chunk3\n                 |     |\n                 v     v\n                +-+-+-+-+-+   ^\n                |0|3|.| | |   |\n                +-+-+-+-+-+   | div\n                |1|4|.| | |   |\n                +-+-+-+-+-+   v\n                |2|5|.|\n                +-+-+-+\n\n                <----->\n                  mod\n\n                <--------->\n                _chunkCount\n\n            One column is one chunk.\n            popFront and popBack pop the left-most\n            and right-most column, respectively.\n        */\n\n        auto div = _source.length / _chunkCount;\n        auto mod = _source.length % _chunkCount;\n        auto pos = i <= mod\n            ? i   * (div+1)\n            : mod * (div+1) + (i-mod) * div\n        ;\n        //auto len = i < mod\n        //    ? div+1\n        //    : div\n        //;\n        return pos;\n    }\n}\n\n/// Ditto\nEvenChunks!Source evenChunks(Source)(Source source, size_t chunkCount)\nif (isForwardRange!Source && hasLength!Source)\n{\n    return typeof(return)(source, chunkCount);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    auto chunks = evenChunks(source, 3);\n    assert(chunks[0] == [1, 2, 3, 4]);\n    assert(chunks[1] == [5, 6, 7]);\n    assert(chunks[2] == [8, 9, 10]);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    auto chunks = evenChunks(source, 3);\n    assert(chunks.back == chunks[2]);\n    assert(chunks.front == chunks[0]);\n    assert(chunks.length == 3);\n    assert(equal(retro(array(chunks)), array(retro(chunks))));\n\n    auto chunks2 = chunks.save;\n    chunks.popFront();\n    assert(chunks[0] == [5, 6, 7]);\n    assert(chunks[1] == [8, 9, 10]);\n    chunks2.popBack();\n    assert(chunks2[1] == [5, 6, 7]);\n    assert(chunks2.length == 2);\n\n    static assert(isRandomAccessRange!(typeof(chunks)));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[] source = [];\n    auto chunks = source.evenChunks(0);\n    assert(chunks.length == 0);\n    chunks = source.evenChunks(3);\n    assert(equal(chunks, [[], [], []]));\n    chunks = [1, 2, 3].evenChunks(5);\n    assert(equal(chunks, [[1], [2], [3], [], []]));\n}\n\n/**\nA fixed-sized sliding window iteration\nof size `windowSize` over a `source` range by a custom `stepSize`.\n\nThe `Source` range must be at least a $(REF_ALTTEXT ForwardRange, isForwardRange, std,range,primitives)\nand the `windowSize` must be greater than zero.\n\nFor `windowSize = 1` it splits the range into single element groups (aka `unflatten`)\nFor `windowSize = 2` it is similar to `zip(source, source.save.dropOne)`.\n\nParams:\n    f = Whether the last element has fewer elements than `windowSize`\n        it should be be ignored (`No.withPartial`) or added (`Yes.withPartial`)\n    source = Range from which the slide will be selected\n    windowSize = Sliding window size\n    stepSize = Steps between the windows (by default 1)\n\nReturns: Range of all sliding windows with propagated bi-directionality,\n         forwarding, random access, and slicing.\n\nNote: To avoid performance overhead, $(REF_ALTTEXT bi-directionality, isBidirectionalRange, std,range,primitives)\n      is only available when $(REF hasSlicing, std,range,primitives)\n      and $(REF hasLength, std,range,primitives) are true.\n\nSee_Also: $(LREF chunks)\n*/\nauto slide(Flag!\"withPartial\" f = Yes.withPartial,\n            Source)(Source source, size_t windowSize, size_t stepSize = 1)\nif (isForwardRange!Source)\n{\n    return Slides!(f, Source)(source, windowSize, stepSize);\n}\n\n/// Iterate over ranges with windows\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert([0, 1, 2, 3].slide(2).equal!equal(\n        [[0, 1], [1, 2], [2, 3]]\n    ));\n\n    assert(5.iota.slide(3).equal!equal(\n        [[0, 1, 2], [1, 2, 3], [2, 3, 4]]\n    ));\n}\n\n/// set a custom stepsize (default 1)\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(6.iota.slide(1, 2).equal!equal(\n        [[0], [2], [4]]\n    ));\n\n    assert(6.iota.slide(2, 4).equal!equal(\n        [[0, 1], [4, 5]]\n    ));\n\n    assert(iota(7).slide(2, 2).equal!equal(\n        [[0, 1], [2, 3], [4, 5], [6]]\n    ));\n\n    assert(iota(12).slide(2, 4).equal!equal(\n        [[0, 1], [4, 5], [8, 9]]\n    ));\n}\n\n/// Allow the last slide to have fewer elements than windowSize\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(3.iota.slide!(No.withPartial)(4).empty);\n    assert(3.iota.slide!(Yes.withPartial)(4).equal!equal(\n        [[0, 1, 2]]\n    ));\n}\n\n/// Count all the possible substrings of length 2\n@safe pure nothrow unittest\n{\n    import std.algorithm.iteration : each;\n\n    int[dstring] d;\n    \"AGAGA\"d.slide!(Yes.withPartial)(2).each!(a => d[a]++);\n    assert(d == [\"AG\"d: 2, \"GA\"d: 2]);\n}\n\n/// withPartial only has an effect if last element in the range doesn't have the full size\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(5.iota.slide!(Yes.withPartial)(3, 4).equal!equal([[0, 1, 2], [4]]));\n    assert(6.iota.slide!(Yes.withPartial)(3, 4).equal!equal([[0, 1, 2], [4, 5]]));\n    assert(7.iota.slide!(Yes.withPartial)(3, 4).equal!equal([[0, 1, 2], [4, 5, 6]]));\n\n    assert(5.iota.slide!(No.withPartial)(3, 4).equal!equal([[0, 1, 2]]));\n    assert(6.iota.slide!(No.withPartial)(3, 4).equal!equal([[0, 1, 2]]));\n    assert(7.iota.slide!(No.withPartial)(3, 4).equal!equal([[0, 1, 2], [4, 5, 6]]));\n}\n\nprivate struct Slides(Flag!\"withPartial\" withPartial = Yes.withPartial, Source)\nif (isForwardRange!Source)\n{\nprivate:\n    Source source;\n    size_t windowSize;\n    size_t stepSize;\n\n    static if (hasLength!Source)\n    {\n        enum needsEndTracker = false;\n    }\n    else\n    {\n        // If there's no information about the length, track needs to be kept manually\n        Source nextSource;\n        enum needsEndTracker = true;\n    }\n\n    bool _empty;\n\n    static if (hasSlicing!Source)\n        enum hasSliceToEnd = hasSlicing!Source && is(typeof(Source.init[0 .. $]) == Source);\n\n    static if (withPartial)\n        bool hasShownPartialBefore;\n\npublic:\n    /// Standard constructor\n    this(Source source, size_t windowSize, size_t stepSize)\n    {\n        assert(windowSize > 0, \"windowSize must be greater than zero\");\n        assert(stepSize > 0, \"stepSize must be greater than zero\");\n        this.source = source;\n        this.windowSize = windowSize;\n        this.stepSize = stepSize;\n\n        static if (needsEndTracker)\n        {\n            // `nextSource` is used to \"look one step into the future\" and check for the end\n            // this means `nextSource` is advanced by `stepSize` on every `popFront`\n            nextSource = source.save.drop(windowSize);\n        }\n\n        if (source.empty)\n        {\n            _empty = true;\n            return;\n        }\n\n        static if (withPartial)\n        {\n            static if (needsEndTracker)\n            {\n                if (nextSource.empty)\n                    hasShownPartialBefore = true;\n            }\n            else\n            {\n                if (source.length <= windowSize)\n                    hasShownPartialBefore = true;\n            }\n\n        }\n        else\n        {\n            // empty source range is needed, s.t. length, slicing etc. works properly\n            static if (needsEndTracker)\n            {\n                if (nextSource.empty)\n                     _empty = true;\n            }\n            else\n            {\n                if (source.length < windowSize)\n                     _empty = true;\n            }\n        }\n    }\n\n    /// Forward range primitives. Always present.\n    @property auto front()\n    {\n        assert(!empty, \"Attempting to access front on an empty slide.\");\n        static if (hasSlicing!Source && hasLength!Source)\n        {\n            static if (withPartial)\n            {\n                import std.algorithm.comparison : min;\n                return source[0 .. min(windowSize, source.length)];\n            }\n            else\n            {\n                assert(windowSize <= source.length, \"The last element is smaller than the current windowSize.\");\n                return source[0 .. windowSize];\n            }\n        }\n        else\n        {\n            static if (withPartial)\n                return source.save.take(windowSize);\n            else\n                return source.save.takeExactly(windowSize);\n        }\n    }\n\n    /// Ditto\n    void popFront()\n    {\n        assert(!empty, \"Attempting to call popFront() on an empty slide.\");\n        source.popFrontN(stepSize);\n\n        if (source.empty)\n        {\n            _empty = true;\n            return;\n        }\n\n        static if (withPartial)\n        {\n            if (hasShownPartialBefore)\n                _empty = true;\n        }\n\n        static if (needsEndTracker)\n        {\n            // Check the upcoming slide\n            auto poppedElements = nextSource.popFrontN(stepSize);\n            static if (withPartial)\n            {\n                if (poppedElements < stepSize || nextSource.empty)\n                    hasShownPartialBefore = true;\n            }\n            else\n            {\n                if (poppedElements < stepSize)\n                    _empty = true;\n            }\n        }\n        else\n        {\n            static if (withPartial)\n            {\n                if (source.length <= windowSize)\n                    hasShownPartialBefore = true;\n            }\n            else\n            {\n                if (source.length < windowSize)\n                    _empty = true;\n            }\n        }\n    }\n\n    static if (!isInfinite!Source)\n    {\n        /// Ditto\n        @property bool empty() const\n        {\n            return _empty;\n        }\n    }\n    else\n    {\n        // undocumented\n        enum empty = false;\n    }\n\n    /// Ditto\n    @property typeof(this) save()\n    {\n        return typeof(this)(source.save, windowSize, stepSize);\n    }\n\n    static if (hasLength!Source)\n    {\n        // gaps between the last element and the end of the range\n        private size_t gap()\n        {\n            /*\n            * Note:\n            * - In the following `end` is the exclusive end as used in opSlice\n            * - For the trivial case with `stepSize = 1`  `end` is at `len`:\n            *\n            *    iota(4).slide(2) = [[0, 1], [1, 2], [2, 3]]    (end = 4)\n            *    iota(4).slide(3) = [[0, 1, 2], [1, 2, 3]]      (end = 4)\n            *\n            * - For the non-trivial cases, we need to calculate the gap\n            *   between `len` and `end` - this is the number of missing elements\n            *   from the input range:\n            *\n            *    iota(7).slide(2, 3) = [[0, 1], [3, 4]] || <gap: 2> 6\n            *    iota(7).slide(2, 4) = [[0, 1], [4, 5]] || <gap: 1> 6\n            *    iota(7).slide(1, 5) = [[0], [5]]       || <gap: 1> 6\n            *\n            *   As it can be seen `gap` can be at most `stepSize - 1`\n            *   More generally the elements of the sliding window with\n            *   `w = windowSize` and `s = stepSize` are:\n            *\n            *     [0, w], [s, s + w], [2 * s, 2 * s + w], ... [n * s, n * s + w]\n            *\n            *  We can thus calculate the gap between the `end` and `len` as:\n            *\n            *     gap = len - (n * s + w) = len - w - (n * s)\n            *\n            *  As we aren't interested in exact value of `n`, but the best\n            *  minimal `gap` value, we can use modulo to \"cut\" `len - w` optimally:\n            *\n            *     gap = len - w - (s - s ... - s) = (len - w) % s\n            *\n            *  So for example:\n            *\n            *    iota(7).slide(2, 3) = [[0, 1], [3, 4]]\n            *      gap: (7 - 2) % 3 = 5 % 3 = 2\n            *      end: 7 - 2 = 5\n            *\n            *    iota(7).slide(4, 2) = [[0, 1, 2, 3], [2, 3, 4, 5]]\n            *      gap: (7 - 4) % 2 = 3 % 2 = 1\n            *      end: 7 - 1 = 6\n            */\n            return (source.length - windowSize)  % stepSize;\n        }\n\n        private size_t numberOfFullFrames()\n        {\n            /**\n            5.iota.slides(2, 1) => [0, 1], [1, 2], [2, 3], [3, 4]       (4)\n            7.iota.slides(2, 2) => [0, 1], [2, 3], [4, 5], [6]          (3)\n            7.iota.slides(2, 3) => [0, 1], [3, 4], [6]                  (2)\n            6.iota.slides(3, 2) => [0, 1, 2], [2, 3, 4], [4, 5]         (2)\n            7.iota.slides(3, 3) => [0, 1, 2], [3, 4, 5], [6]            (2)\n\n            As the last window is only added iff its complete,\n            we don't count the last window except if it's full due to integer rounding.\n            */\n            return 1 + (source.length - windowSize) / stepSize;\n        }\n\n        // Whether the last slide frame size is less than windowSize\n        private bool hasPartialElements()\n        {\n            static if (withPartial)\n                return gap != 0 && source.length > numberOfFullFrames * stepSize;\n            else\n                return 0;\n        }\n\n        /// Length. Only if `hasLength!Source` is `true`\n        @property size_t length()\n        {\n            if (source.length < windowSize)\n            {\n                static if (withPartial)\n                    return source.length > 0;\n                else\n                    return 0;\n            }\n            else\n            {\n                /***\n                  We bump the pointer by stepSize for every element.\n                  If withPartial, we don't count the last element if its size\n                  isn't windowSize\n\n                  At most:\n                      [p, p + stepSize, ..., p + stepSize * n]\n\n                5.iota.slides(2, 1) => [0, 1], [1, 2], [2, 3], [3, 4]       (4)\n                7.iota.slides(2, 2) => [0, 1], [2, 3], [4, 5], [6]          (4)\n                7.iota.slides(2, 3) => [0, 1], [3, 4], [6]                  (3)\n                7.iota.slides(3, 2) => [0, 1, 2], [2, 3, 4], [4, 5, 6]      (3)\n                7.iota.slides(3, 3) => [0, 1, 2], [3, 4, 5], [6]            (3)\n                */\n                return numberOfFullFrames + hasPartialElements;\n            }\n        }\n    }\n\n    static if (hasSlicing!Source)\n    {\n        /**\n        Indexing and slicing operations. Provided only if\n        `hasSlicing!Source` is `true`.\n         */\n        auto opIndex(size_t index)\n        {\n            immutable start = index * stepSize;\n\n            static if (isInfinite!Source)\n            {\n                immutable end = start + windowSize;\n            }\n            else\n            {\n                import std.algorithm.comparison : min;\n\n                immutable len = source.length;\n                assert(start < len, \"slide index out of bounds\");\n                immutable end = min(start + windowSize, len);\n            }\n\n            return source[start .. end];\n        }\n\n        static if (!isInfinite!Source)\n        {\n            /// ditto\n            typeof(this) opSlice(size_t lower, size_t upper)\n            {\n                import std.algorithm.comparison : min;\n\n                assert(upper <= length, \"slide slicing index out of bounds\");\n                assert(lower <= upper, \"slide slicing index out of bounds\");\n\n                lower *= stepSize;\n                upper *= stepSize;\n\n                immutable len = source.length;\n\n                static if (withPartial)\n                {\n                    import std.algorithm.comparison : max;\n\n                    if (lower == upper)\n                        return this[$ .. $];\n\n                    /*\n                    A) If `stepSize` >= `windowSize` => `rightPos = upper`\n\n                       [0, 1, 2, 3, 4, 5, 6].slide(2, 3) -> s = [[0, 1], [3, 4], [6]]\n                         rightPos for s[0 .. 2]: (upper=2) * (stepSize=3) = 6\n                         6.iota.slide(2, 3) = [[0, 1], [3, 4]]\n\n                    B) If `stepSize` < `windowSize` => add `windowSize - stepSize` to `upper`\n\n                       [0, 1, 2, 3].slide(2) = [[0, 1], [1, 2], [2, 3]]\n                         rightPos for s[0 .. 1]: = (upper=1) * (stepSize=1) = 1\n                         1.iota.slide(2) = [[0]]\n\n                         rightPos for s[0 .. 1]: = (upper=1) * (stepSize=1) + (windowSize-stepSize=1) = 2\n                         1.iota.slide(2) = [[0, 1]]\n\n                       More complex:\n\n                       20.iota.slide(7, 6)[0 .. 2]\n                         rightPos: (upper=2) * (stepSize=6) = 12.iota\n                         12.iota.slide(7, 6) = [[0, 1, 2, 3, 4, 5, 6], [6, 7, 8, 9, 10, 11]]\n\n                       Now we add up for the difference between `windowSize` and `stepSize`:\n\n                         rightPos: (upper=2) * (stepSize=6) + (windowSize-stepSize=1) = 13.iota\n                         13.iota.slide(7, 6) = [[0, 1, 2, 3, 4, 5, 6], [6, 7, 8, 9, 10, 11, 12]]\n                    */\n                    immutable rightPos = min(len, upper + max(0, windowSize - stepSize));\n                }\n                else\n                {\n                    /*\n                    After we have normalized `lower` and `upper` by `stepSize`,\n                    we only need to look at the case of `stepSize=1`.\n                    As `leftPos`, is equal to `lower`, we will only look `rightPos`.\n                    Notice that starting from `upper`,\n                    we only need to move for `windowSize - 1` to the right:\n\n                      - [0, 1, 2, 3].slide(2) -> s = [[0, 1], [1, 2], [2, 3]]\n                        rightPos for s[0 .. 3]: (upper=3) + (windowSize=2) - 1 = 4\n\n                      - [0, 1, 2, 3].slide(3) -> s = [[0, 1, 2], [1, 2, 3]]\n                        rightPos for s[0 .. 2]: (upper=2) + (windowSize=3) - 1 = 4\n\n                      - [0, 1, 2, 3, 4].slide(4) -> s = [[0, 1, 2, 3], [1, 2, 3, 4]]\n                        rightPos for s[0 .. 2]: (upper=2) + (windowSize=4) - 1 = 5\n                    */\n                    immutable rightPos = min(upper + windowSize - 1, len);\n                }\n\n                return typeof(this)(source[min(lower, len) .. rightPos], windowSize, stepSize);\n            }\n        }\n        else static if (hasSliceToEnd)\n        {\n            // For slicing an infinite chunk, we need to slice the source to the infinite end.\n            auto opSlice(size_t lower, size_t upper)\n            {\n                assert(lower <= upper, \"slide slicing index out of bounds\");\n                return typeof(this)(source[lower * stepSize .. $], windowSize, stepSize)\n                                    .takeExactly(upper - lower);\n            }\n        }\n\n        static if (isInfinite!Source)\n        {\n            static if (hasSliceToEnd)\n            {\n                private static struct DollarToken{}\n                DollarToken opDollar()\n                {\n                    return DollarToken();\n                }\n                //Slice to dollar\n                typeof(this) opSlice(size_t lower, DollarToken)\n                {\n                    return typeof(this)(source[lower * stepSize .. $], windowSize, stepSize);\n                }\n            }\n        }\n        else\n        {\n            // Dollar token carries a static type, with no extra information.\n            // It can lazily transform into source.length on algorithmic\n            // operations such as : slide[$/2, $-1];\n            private static struct DollarToken\n            {\n                private size_t _length;\n                alias _length this;\n            }\n\n            DollarToken opDollar()\n            {\n                return DollarToken(this.length);\n            }\n\n            // Optimized slice overloads optimized for using dollar.\n            typeof(this) opSlice(DollarToken, DollarToken)\n            {\n                static if (hasSliceToEnd)\n                {\n                    return typeof(this)(source[$ .. $], windowSize, stepSize);\n                }\n                else\n                {\n                    immutable len = source.length;\n                    return typeof(this)(source[len .. len], windowSize, stepSize);\n                }\n            }\n\n            // Optimized slice overloads optimized for using dollar.\n            typeof(this) opSlice(size_t lower, DollarToken)\n            {\n                import std.algorithm.comparison : min;\n                assert(lower <= length, \"slide slicing index out of bounds\");\n                lower *= stepSize;\n                static if (hasSliceToEnd)\n                {\n                    return typeof(this)(source[min(lower, source.length) .. $], windowSize, stepSize);\n                }\n                else\n                {\n                    immutable len = source.length;\n                    return typeof(this)(source[min(lower, len) .. len], windowSize, stepSize);\n                }\n            }\n\n            // Optimized slice overloads optimized for using dollar.\n            typeof(this) opSlice(DollarToken, size_t upper)\n            {\n                assert(upper == length, \"slide slicing index out of bounds\");\n                return this[$ .. $];\n            }\n        }\n\n        // Bidirectional range primitives\n        static if (!isInfinite!Source)\n        {\n            /**\n            Bidirectional range primitives. Provided only if both\n            `hasSlicing!Source` and `!isInfinite!Source` are `true`.\n             */\n            @property auto back()\n            {\n                import std.algorithm.comparison : max;\n\n                assert(!empty, \"Attempting to access front on an empty slide\");\n\n                immutable len = source.length;\n\n                static if (withPartial)\n                {\n                    if (source.length <= windowSize)\n                        return source[0 .. source.length];\n\n                    if (hasPartialElements)\n                        return source[numberOfFullFrames * stepSize .. len];\n                }\n\n                // check for underflow\n                immutable start = (len > windowSize + gap) ? len - windowSize - gap : 0;\n                return source[start .. len - gap];\n            }\n\n            /// Ditto\n            void popBack()\n            {\n                assert(!empty, \"Attempting to call popBack() on an empty slide\");\n\n                // Move by stepSize\n                immutable end = source.length > stepSize ? source.length - stepSize : 0;\n\n                static if (withPartial)\n                {\n                    if (hasShownPartialBefore || source.empty)\n                    {\n                        _empty = true;\n                        return;\n                    }\n\n                    // pop by stepSize, except for the partial frame at the end\n                    if (hasPartialElements)\n                        source = source[0 .. source.length - gap];\n                    else\n                        source = source[0 .. end];\n                }\n                else\n                {\n                    source = source[0 .. end];\n                }\n\n                if (source.length < windowSize)\n                    _empty = true;\n            }\n        }\n    }\n}\n\n// test @nogc\n@safe pure nothrow @nogc unittest\n{\n    import std.algorithm.comparison : equal;\n\n    static immutable res1 = [[0], [1], [2], [3]];\n    assert(4.iota.slide!(Yes.withPartial)(1).equal!equal(res1));\n\n    static immutable res2 = [[0, 1], [1, 2], [2, 3]];\n    assert(4.iota.slide!(Yes.withPartial)(2).equal!equal(res2));\n}\n\n// test different window sizes\n@safe pure nothrow unittest\n{\n    import std.array : array;\n    import std.algorithm.comparison : equal;\n\n    assert([0, 1, 2, 3].slide!(Yes.withPartial)(1).array == [[0], [1], [2], [3]]);\n    assert([0, 1, 2, 3].slide!(Yes.withPartial)(2).array == [[0, 1], [1, 2], [2, 3]]);\n    assert([0, 1, 2, 3].slide!(Yes.withPartial)(3).array == [[0, 1, 2], [1, 2, 3]]);\n    assert([0, 1, 2, 3].slide!(Yes.withPartial)(4).array == [[0, 1, 2, 3]]);\n    assert([0, 1, 2, 3].slide!(No.withPartial)(5).walkLength == 0);\n    assert([0, 1, 2, 3].slide!(Yes.withPartial)(5).array == [[0, 1, 2, 3]]);\n\n    assert(iota(2).slide!(Yes.withPartial)(2).front.equal([0, 1]));\n    assert(iota(3).slide!(Yes.withPartial)(2).equal!equal([[0, 1],[1, 2]]));\n    assert(iota(3).slide!(Yes.withPartial)(3).equal!equal([[0, 1, 2]]));\n    assert(iota(3).slide!(No.withPartial)(4).walkLength == 0);\n    assert(iota(3).slide!(Yes.withPartial)(4).equal!equal([[0, 1, 2]]));\n    assert(iota(1, 4).slide!(Yes.withPartial)(1).equal!equal([[1], [2], [3]]));\n    assert(iota(1, 4).slide!(Yes.withPartial)(3).equal!equal([[1, 2, 3]]));\n}\n\n// test combinations\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : tuple;\n\n    alias t = tuple;\n    auto list = [\n        t(t(1, 1), [[0], [1], [2], [3], [4], [5]]),\n        t(t(1, 2), [[0], [2], [4]]),\n        t(t(1, 3), [[0], [3]]),\n        t(t(1, 4), [[0], [4]]),\n        t(t(1, 5), [[0], [5]]),\n        t(t(2, 1), [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]]),\n        t(t(2, 2), [[0, 1], [2, 3], [4, 5]]),\n        t(t(2, 3), [[0, 1], [3, 4]]),\n        t(t(2, 4), [[0, 1], [4, 5]]),\n        t(t(3, 1), [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5]]),\n        t(t(3, 3), [[0, 1, 2], [3, 4, 5]]),\n        t(t(4, 1), [[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]),\n        t(t(4, 2), [[0, 1, 2, 3], [2, 3, 4, 5]]),\n        t(t(5, 1), [[0, 1, 2, 3, 4], [1, 2, 3, 4, 5]]),\n    ];\n\n    static foreach (Partial; [Yes.withPartial, No.withPartial])\n        foreach (e; list)\n            assert(6.iota.slide!Partial(e[0].expand).equal!equal(e[1]));\n\n    auto listSpecial = [\n        t(t(2, 5), [[0, 1], [5]]),\n        t(t(3, 2), [[0, 1, 2], [2, 3, 4], [4, 5]]),\n        t(t(3, 4), [[0, 1, 2], [4, 5]]),\n        t(t(4, 3), [[0, 1, 2, 3], [3, 4, 5]]),\n        t(t(5, 2), [[0, 1, 2, 3, 4], [2, 3, 4, 5]]),\n        t(t(5, 3), [[0, 1, 2, 3, 4], [3, 4, 5]]),\n    ];\n    foreach (e; listSpecial)\n    {\n        assert(6.iota.slide!(Yes.withPartial)(e[0].expand).equal!equal(e[1]));\n        assert(6.iota.slide!(No.withPartial)(e[0].expand).equal!equal(e[1].dropBackOne));\n    }\n}\n\n// test emptiness and copyability\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n\n    // check with empty input\n    int[] d;\n    assert(d.slide!(Yes.withPartial)(2).empty);\n    assert(d.slide!(Yes.withPartial)(2, 2).empty);\n\n    // is copyable?\n    auto e = iota(5).slide!(Yes.withPartial)(2);\n    e.popFront;\n    assert(e.save.equal!equal([[1, 2], [2, 3], [3, 4]]));\n    assert(e.save.equal!equal([[1, 2], [2, 3], [3, 4]]));\n    assert(e.map!\"a.array\".array == [[1, 2], [2, 3], [3, 4]]);\n}\n\n// test with strings\n@safe pure nothrow unittest\n{\n    import std.algorithm.iteration : each;\n\n    int[dstring] f;\n    \"AGAGA\"d.slide!(Yes.withPartial)(3).each!(a => f[a]++);\n    assert(f == [\"AGA\"d: 2, \"GAG\"d: 1]);\n\n    int[dstring] g;\n    \"ABCDEFG\"d.slide!(Yes.withPartial)(3, 3).each!(a => g[a]++);\n    assert(g == [\"ABC\"d:1, \"DEF\"d:1, \"G\": 1]);\n    g = null;\n    \"ABCDEFG\"d.slide!(No.withPartial)(3, 3).each!(a => g[a]++);\n    assert(g == [\"ABC\"d:1, \"DEF\"d:1]);\n}\n\n// test with utf8 strings\n@safe unittest\n{\n    import std.stdio;\n    import std.algorithm.comparison : equal;\n\n    assert(\"ä.ö.ü.\".slide!(Yes.withPartial)(3, 2).equal!equal([\"ä.ö\", \"ö.ü\", \"ü.\"]));\n    assert(\"ä.ö.ü.\".slide!(No.withPartial)(3, 2).equal!equal([\"ä.ö\", \"ö.ü\"]));\n\n    \"😄😅😆😇😈😄😅😆😇😈\".slide!(Yes.withPartial)(2, 4).equal!equal([\"😄😅\", \"😈😄\", \"😇😈\"]);\n    \"😄😅😆😇😈😄😅😆😇😈\".slide!(No.withPartial)(2, 4).equal!equal([\"😄😅\", \"😈😄\", \"😇😈\"]);\n    \"😄😅😆😇😈😄😅😆😇😈\".slide!(Yes.withPartial)(3, 3).equal!equal([\"😄😅😆\", \"😇😈😄\", \"😅😆😇\", \"😈\"]);\n    \"😄😅😆😇😈😄😅😆😇😈\".slide!(No.withPartial)(3, 3).equal!equal([\"😄😅😆\", \"😇😈😄\", \"😅😆😇\"]);\n}\n\n// test length\n@safe pure nothrow unittest\n{\n    // Slides with fewer elements are empty or 1 for Yes.withPartial\n    static foreach (expectedLength, Partial; [No.withPartial, Yes.withPartial])\n    {{\n        assert(3.iota.slide!(Partial)(4, 2).walkLength == expectedLength);\n        assert(3.iota.slide!(Partial)(4).walkLength == expectedLength);\n        assert(3.iota.slide!(Partial)(4, 3).walkLength == expectedLength);\n    }}\n\n    static immutable list = [\n    //  iota   slide    expected\n        [4,    2, 1,     3, 3],\n        [5,    3, 1,     3, 3],\n        [7,    2, 2,     4, 3],\n        [12,   2, 4,     3, 3],\n        [6,    1, 2,     3, 3],\n        [6,    2, 4,     2, 2],\n        [3,    2, 4,     1, 1],\n        [5,    2, 1,     4, 4],\n        [7,    2, 2,     4, 3],\n        [7,    2, 3,     3, 2],\n        [7,    3, 2,     3, 3],\n        [7,    3, 3,     3, 2],\n    ];\n    foreach (e; list)\n    {\n        assert(e[0].iota.slide!(Yes.withPartial)(e[1], e[2]).length == e[3]);\n        assert(e[0].iota.slide!(No.withPartial)(e[1], e[2]).length == e[4]);\n    }\n}\n\n// test index and slicing\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.array : array;\n\n    static foreach (Partial; [Yes.withPartial, No.withPartial])\n    {\n        foreach (s; [5, 7, 10, 15, 20])\n        foreach (windowSize; 1 .. 10)\n        foreach (stepSize; 1 .. 10)\n        {\n            auto r = s.iota.slide!Partial(windowSize, stepSize);\n            auto arr = r.array;\n            assert(r.length == arr.length);\n\n            // test indexing\n            foreach (i; 0 .. arr.length)\n                assert(r[i] == arr[i]);\n\n            // test slicing\n            foreach (i; 0 .. arr.length)\n            {\n                foreach (j; i .. arr.length)\n                    assert(r[i .. j].equal(arr[i .. j]));\n\n                assert(r[i .. $].equal(arr[i .. $]));\n            }\n\n            // test opDollar slicing\n            assert(r[$/2 .. $].equal(arr[$/2 .. $]));\n            assert(r[$ .. $].empty);\n            if (arr.empty)\n            {\n                assert(r[$ .. 0].empty);\n                assert(r[$/2 .. $].empty);\n\n            }\n        }\n    }\n}\n\n// test with infinite ranges\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    static foreach (Partial; [Yes.withPartial, No.withPartial])\n    {{\n        // InfiniteRange without RandomAccess\n        auto fibs = recurrence!\"a[n-1] + a[n-2]\"(1, 1);\n        assert(fibs.slide!Partial(2).take(2).equal!equal([[1,  1], [1,  2]]));\n        assert(fibs.slide!Partial(2, 3).take(2).equal!equal([[1,  1], [3,  5]]));\n\n        // InfiniteRange with RandomAccess and slicing\n        auto odds = sequence!(\"a[0] + n * a[1]\")(1, 2);\n        auto oddsByPairs = odds.slide!Partial(2);\n        assert(oddsByPairs.take(2).equal!equal([[ 1,  3], [ 3,  5]]));\n        assert(oddsByPairs[1].equal([3, 5]));\n        assert(oddsByPairs[4].equal([9, 11]));\n\n        static assert(hasSlicing!(typeof(odds)));\n        assert(oddsByPairs[3 .. 5].equal!equal([[7, 9], [9, 11]]));\n        assert(oddsByPairs[3 .. $].take(2).equal!equal([[7, 9], [9, 11]]));\n\n        auto oddsWithGaps = odds.slide!Partial(2, 4);\n        assert(oddsWithGaps.take(3).equal!equal([[1, 3], [9, 11], [17, 19]]));\n        assert(oddsWithGaps[2].equal([17, 19]));\n        assert(oddsWithGaps[1 .. 3].equal!equal([[9, 11], [17, 19]]));\n        assert(oddsWithGaps[1 .. $].take(2).equal!equal([[9, 11], [17, 19]]));\n    }}\n}\n\n// test reverse\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    static foreach (Partial; [Yes.withPartial, No.withPartial])\n    {{\n        foreach (windowSize; 1 .. 15)\n        foreach (stepSize; 1 .. 15)\n        {\n            auto r = 20.iota.slide!Partial(windowSize, stepSize);\n            auto rArr = r.array.retro;\n            auto rRetro = r.retro;\n\n            assert(rRetro.length == rArr.length);\n            assert(rRetro.equal(rArr));\n            assert(rRetro.array.retro.equal(r));\n        }\n    }}\n}\n\n// test with dummy ranges\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges;\n    import std.meta : Filter;\n\n    static foreach (Range; Filter!(isForwardRange, AllDummyRanges))\n    {{\n        Range r;\n\n        static foreach (Partial; [Yes.withPartial, No.withPartial])\n        {\n            assert(r.slide!Partial(1).equal!equal(\n                [[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]]\n            ));\n            assert(r.slide!Partial(2).equal!equal(\n                [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10]]\n            ));\n            assert(r.slide!Partial(3).equal!equal(\n                [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6],\n                [5, 6, 7], [6, 7, 8], [7, 8, 9], [8, 9, 10]]\n            ));\n            assert(r.slide!Partial(6).equal!equal(\n                [[1, 2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8],\n                [4, 5, 6, 7, 8, 9], [5, 6, 7, 8, 9, 10]]\n            ));\n        }\n\n        // special cases\n        assert(r.slide!(Yes.withPartial)(15).equal!equal(iota(1, 11).only));\n        assert(r.slide!(Yes.withPartial)(15).walkLength == 1);\n        assert(r.slide!(No.withPartial)(15).empty);\n        assert(r.slide!(No.withPartial)(15).walkLength == 0);\n    }}\n}\n\n// test with dummy ranges\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges;\n    import std.meta : Filter;\n    import std.typecons : tuple;\n\n    alias t = tuple;\n    static immutable list = [\n    // iota   slide    expected\n        t(6,  t(4, 2), [[1, 2, 3, 4], [3, 4, 5, 6]]),\n        t(6,  t(4, 6), [[1, 2, 3, 4]]),\n        t(6,  t(4, 1), [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]),\n        t(7,  t(4, 1), [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]]),\n        t(7,  t(4, 3), [[1, 2, 3, 4], [4, 5, 6, 7]]),\n        t(8,  t(4, 2), [[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8]]),\n        t(8,  t(4, 1), [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8]]),\n        t(8,  t(3, 4), [[1, 2, 3], [5, 6, 7]]),\n        t(10, t(3, 7), [[1, 2, 3], [8, 9, 10]]),\n    ];\n\n    static foreach (Range; Filter!(isForwardRange, AllDummyRanges))\n    static foreach (Partial; [Yes.withPartial, No.withPartial])\n    foreach (e; list)\n        assert(Range().take(e[0]).slide!Partial(e[1].expand).equal!equal(e[2]));\n\n    static immutable listSpecial = [\n    // iota   slide    expected\n        t(6,  t(4, 3), [[1, 2, 3, 4], [4, 5, 6]]),\n        t(7,  t(4, 5), [[1, 2, 3, 4], [6, 7]]),\n        t(7,  t(4, 4), [[1, 2, 3, 4], [5, 6, 7]]),\n        t(7,  t(4, 2), [[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7]]),\n        t(8,  t(4, 3), [[1, 2, 3, 4], [4, 5, 6, 7], [7, 8]]),\n        t(8,  t(3, 3), [[1, 2, 3], [4, 5, 6], [7, 8]]),\n        t(8,  t(3, 6), [[1, 2, 3], [7, 8]]),\n        t(10, t(7, 6), [[1, 2, 3, 4, 5, 6, 7], [7, 8, 9, 10]]),\n        t(10, t(3, 8), [[1, 2, 3], [9, 10]]),\n    ];\n    static foreach (Range; Filter!(isForwardRange, AllDummyRanges))\n    static foreach (Partial; [Yes.withPartial, No.withPartial])\n    foreach (e; listSpecial)\n    {\n        Range r;\n        assert(r.take(e[0]).slide!(Yes.withPartial)(e[1].expand).equal!equal(e[2]));\n        assert(r.take(e[0]).slide!(No.withPartial)(e[1].expand).equal!equal(e[2].dropBackOne));\n    }\n}\n\n// test reverse with dummy ranges\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges;\n    import std.meta : Filter, templateAnd;\n    import std.typecons : tuple;\n    alias t = tuple;\n\n    static immutable list = [\n    //   slide   expected\n        t(1, 1, [[10], [9], [8], [7], [6], [5], [4], [3], [2], [1]]),\n        t(2, 1, [[9, 10], [8, 9], [7, 8], [6, 7], [5, 6], [4, 5], [3, 4], [2, 3], [1, 2]]),\n        t(5, 1, [[6, 7, 8, 9, 10], [5, 6, 7, 8, 9], [4, 5, 6, 7, 8],\n                 [3, 4, 5, 6, 7], [2, 3, 4, 5, 6], [1, 2, 3, 4, 5]]),\n        t(2, 2, [[9, 10], [7, 8], [5, 6], [3, 4], [1, 2]]),\n        t(2, 4, [[9, 10], [5, 6], [1, 2]]),\n    ];\n\n    static foreach (Range; Filter!(templateAnd!(hasSlicing, hasLength, isBidirectionalRange), AllDummyRanges))\n    {{\n        Range r;\n        static foreach (Partial; [Yes.withPartial, No.withPartial])\n        {\n            foreach (e; list)\n                assert(r.slide!Partial(e[0], e[1]).retro.equal!equal(e[2]));\n\n            // front = back\n            foreach (windowSize; 1 .. 10)\n            foreach (stepSize; 1 .. 10)\n            {\n                auto slider = r.slide!Partial(windowSize, stepSize);\n                auto sliderRetro = slider.retro.array;\n                assert(slider.length == sliderRetro.length);\n                assert(sliderRetro.retro.equal!equal(slider));\n            }\n        }\n\n        // special cases\n        assert(r.slide!(No.withPartial)(15).retro.walkLength == 0);\n        assert(r.slide!(Yes.withPartial)(15).retro.equal!equal(iota(1, 11).only));\n    }}\n}\n\n// test different sliceable ranges\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges;\n    import std.meta : AliasSeq;\n\n    struct SliceableRange(Range, Flag!\"withOpDollar\" withOpDollar = No.withOpDollar,\n                                 Flag!\"withInfiniteness\" withInfiniteness = No.withInfiniteness)\n    {\n        Range arr = 10.iota.array; // similar to DummyRange\n        @property auto save() { return typeof(this)(arr); }\n        @property auto front() { return arr[0]; }\n        void popFront() { arr.popFront(); }\n        auto opSlice(size_t i, size_t j)\n        {\n            // subslices can't be infinite\n            return SliceableRange!(Range, withOpDollar, No.withInfiniteness)(arr[i .. j]);\n        }\n\n        static if (withInfiniteness)\n        {\n            enum empty = false;\n        }\n        else\n        {\n            @property bool empty() { return arr.empty; }\n            @property auto length() { return arr.length; }\n        }\n\n        static if (withOpDollar)\n        {\n            static if (withInfiniteness)\n            {\n                struct Dollar {}\n                Dollar opDollar() const { return Dollar.init; }\n\n                // Slice to dollar\n                typeof(this) opSlice(size_t lower, Dollar)\n                {\n                    return typeof(this)(arr[lower .. $]);\n                }\n\n            }\n            else\n            {\n                alias opDollar = length;\n            }\n        }\n    }\n\n    alias SliceableDummyRanges = Filter!(hasSlicing, AllDummyRanges);\n\n    static foreach (Partial; [Yes.withPartial, No.withPartial])\n    {{\n        static foreach (Range; SliceableDummyRanges)\n        {{\n            Range r;\n            r.reinit;\n            r.arr[] -= 1; // use a 0-based array (for clarity)\n\n            assert(r.slide!Partial(2)[0].equal([0, 1]));\n            assert(r.slide!Partial(2)[1].equal([1, 2]));\n\n            // saveable\n            auto s = r.slide!Partial(2);\n            assert(s[0 .. 2].equal!equal([[0, 1], [1, 2]]));\n            s.save.popFront;\n            assert(s[0 .. 2].equal!equal([[0, 1], [1, 2]]));\n\n            assert(r.slide!Partial(3)[1 .. 3].equal!equal([[1, 2, 3], [2, 3, 4]]));\n        }}\n\n        static foreach (Range; Filter!(templateNot!isInfinite, SliceableDummyRanges))\n        {{\n            Range r;\n            r.reinit;\n            r.arr[] -= 1; // use a 0-based array (for clarity)\n\n            assert(r.slide!(No.withPartial)(6).equal!equal(\n                [[0, 1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7],\n                [3, 4, 5, 6, 7, 8], [4, 5, 6, 7, 8, 9]]\n            ));\n            assert(r.slide!(No.withPartial)(16).empty);\n\n            assert(r.slide!Partial(4)[0 .. $].equal(r.slide!Partial(4)));\n            assert(r.slide!Partial(2)[$/2 .. $].equal!equal([[4, 5], [5, 6], [6, 7], [7, 8], [8, 9]]));\n            assert(r.slide!Partial(2)[$ .. $].empty);\n\n            assert(r.slide!Partial(3).retro.equal!equal(\n                [[7, 8, 9], [6, 7, 8], [5, 6, 7], [4, 5, 6], [3, 4, 5], [2, 3, 4], [1, 2, 3], [0, 1, 2]]\n            ));\n        }}\n\n        alias T = int[];\n\n        // separate checks for infinity\n        auto infIndex = SliceableRange!(T, No.withOpDollar, Yes.withInfiniteness)([0, 1, 2, 3]);\n        assert(infIndex.slide!Partial(2)[0].equal([0, 1]));\n        assert(infIndex.slide!Partial(2)[1].equal([1, 2]));\n\n        auto infDollar = SliceableRange!(T, Yes.withOpDollar, Yes.withInfiniteness)();\n        assert(infDollar.slide!Partial(2)[1 .. $].front.equal([1, 2]));\n        assert(infDollar.slide!Partial(4)[0 .. $].front.equal([0, 1, 2, 3]));\n        assert(infDollar.slide!Partial(4)[2 .. $].front.equal([2, 3, 4, 5]));\n    }}\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=19082\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    assert([1].map!(x => x).slide(2).equal!equal([[1]]));\n}\n\nprivate struct OnlyResult(T, size_t arity)\n{\n    private this(Values...)(auto ref Values values)\n    {\n        this.data = [values];\n        this.backIndex = arity;\n    }\n\n    bool empty() @property\n    {\n        return frontIndex >= backIndex;\n    }\n\n    T front() @property\n    {\n        assert(!empty, \"Attempting to fetch the front of an empty Only range\");\n        return data[frontIndex];\n    }\n\n    void popFront()\n    {\n        assert(!empty, \"Attempting to popFront an empty Only range\");\n        ++frontIndex;\n    }\n\n    T back() @property\n    {\n        assert(!empty, \"Attempting to fetch the back of an empty Only range\");\n        return data[backIndex - 1];\n    }\n\n    void popBack()\n    {\n        assert(!empty, \"Attempting to popBack an empty Only range\");\n        --backIndex;\n    }\n\n    OnlyResult save() @property\n    {\n        return this;\n    }\n\n    size_t length() const @property\n    {\n        return backIndex - frontIndex;\n    }\n\n    alias opDollar = length;\n\n    T opIndex(size_t idx)\n    {\n        // when i + idx points to elements popped\n        // with popBack\n        assert(idx < length, \"Attempting to fetch an out of bounds index from an Only range\");\n        return data[frontIndex + idx];\n    }\n\n    OnlyResult opSlice()\n    {\n        return this;\n    }\n\n    OnlyResult opSlice(size_t from, size_t to)\n    {\n        OnlyResult result = this;\n        result.frontIndex += from;\n        result.backIndex = this.frontIndex + to;\n        assert(\n            from <= to,\n            \"Attempting to slice an Only range with a larger first argument than the second.\"\n        );\n        assert(\n            to <= length,\n            \"Attempting to slice using an out of bounds index on an Only range\"\n        );\n        return result;\n    }\n\n    private size_t frontIndex = 0;\n    private size_t backIndex = 0;\n\n    // @@@BUG@@@ 10643\n    version (none)\n    {\n        import std.traits : hasElaborateAssign;\n        static if (hasElaborateAssign!T)\n            private T[arity] data;\n        else\n            private T[arity] data = void;\n    }\n    else\n        private T[arity] data;\n}\n\n// Specialize for single-element results\nprivate struct OnlyResult(T, size_t arity : 1)\n{\n    @property T front()\n    {\n        assert(!empty, \"Attempting to fetch the front of an empty Only range\");\n        return _value;\n    }\n    @property T back()\n    {\n        assert(!empty, \"Attempting to fetch the back of an empty Only range\");\n        return _value;\n    }\n    @property bool empty() const { return _empty; }\n    @property size_t length() const { return !_empty; }\n    @property auto save() { return this; }\n    void popFront()\n    {\n        assert(!_empty, \"Attempting to popFront an empty Only range\");\n        _empty = true;\n    }\n    void popBack()\n    {\n        assert(!_empty, \"Attempting to popBack an empty Only range\");\n        _empty = true;\n    }\n    alias opDollar = length;\n\n    private this()(auto ref T value)\n    {\n        this._value = value;\n        this._empty = false;\n    }\n\n    T opIndex(size_t i)\n    {\n        assert(!_empty && i == 0, \"Attempting to fetch an out of bounds index from an Only range\");\n        return _value;\n    }\n\n    OnlyResult opSlice()\n    {\n        return this;\n    }\n\n    OnlyResult opSlice(size_t from, size_t to)\n    {\n        assert(\n            from <= to,\n            \"Attempting to slice an Only range with a larger first argument than the second.\"\n        );\n        assert(\n            to <= length,\n            \"Attempting to slice using an out of bounds index on an Only range\"\n        );\n        OnlyResult copy = this;\n        copy._empty = _empty || from == to;\n        return copy;\n    }\n\n    private Unqual!T _value;\n    private bool _empty = true;\n}\n\n// Specialize for the empty range\nprivate struct OnlyResult(T, size_t arity : 0)\n{\n    private static struct EmptyElementType {}\n\n    bool empty() @property { return true; }\n    size_t length() const @property { return 0; }\n    alias opDollar = length;\n    EmptyElementType front() @property { assert(false); }\n    void popFront() { assert(false); }\n    EmptyElementType back() @property { assert(false); }\n    void popBack() { assert(false); }\n    OnlyResult save() @property { return this; }\n\n    EmptyElementType opIndex(size_t i)\n    {\n        assert(false);\n    }\n\n    OnlyResult opSlice() { return this; }\n\n    OnlyResult opSlice(size_t from, size_t to)\n    {\n        assert(from == 0 && to == 0);\n        return this;\n    }\n}\n\n/**\nAssemble `values` into a range that carries all its\nelements in-situ.\n\nUseful when a single value or multiple disconnected values\nmust be passed to an algorithm expecting a range, without\nhaving to perform dynamic memory allocation.\n\nAs copying the range means copying all elements, it can be\nsafely returned from functions. For the same reason, copying\nthe returned range may be expensive for a large number of arguments.\n\nParams:\n    values = the values to assemble together\n\nReturns:\n    A `RandomAccessRange` of the assembled values.\n\nSee_Also: $(LREF chain) to chain ranges\n */\nauto only(Values...)(auto ref Values values)\nif (!is(CommonType!Values == void) || Values.length == 0)\n{\n    return OnlyResult!(CommonType!Values, Values.length)(values);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter, joiner, map;\n    import std.algorithm.searching : findSplitBefore;\n    import std.uni : isUpper;\n\n    assert(equal(only('♡'), \"♡\"));\n    assert([1, 2, 3, 4].findSplitBefore(only(3))[0] == [1, 2]);\n\n    assert(only(\"one\", \"two\", \"three\").joiner(\" \").equal(\"one two three\"));\n\n    string title = \"The D Programming Language\";\n    assert(title\n        .filter!isUpper // take the upper case letters\n        .map!only       // make each letter its own range\n        .joiner(\".\")    // join the ranges together lazily\n        .equal(\"T.D.P.L\"));\n}\n\n@safe unittest\n{\n    // Verify that the same common type and same arity\n    // results in the same template instantiation\n    static assert(is(typeof(only(byte.init, int.init)) ==\n        typeof(only(int.init, byte.init))));\n\n    static assert(is(typeof(only((const(char)[]).init, string.init)) ==\n        typeof(only((const(char)[]).init, (const(char)[]).init))));\n}\n\n// Tests the zero-element result\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto emptyRange = only();\n\n    alias EmptyRange = typeof(emptyRange);\n    static assert(isInputRange!EmptyRange);\n    static assert(isForwardRange!EmptyRange);\n    static assert(isBidirectionalRange!EmptyRange);\n    static assert(isRandomAccessRange!EmptyRange);\n    static assert(hasLength!EmptyRange);\n    static assert(hasSlicing!EmptyRange);\n\n    assert(emptyRange.empty);\n    assert(emptyRange.length == 0);\n    assert(emptyRange.equal(emptyRange[]));\n    assert(emptyRange.equal(emptyRange.save));\n    assert(emptyRange[0 .. 0].equal(emptyRange));\n}\n\n// Tests the single-element result\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : tuple;\n    foreach (x; tuple(1, '1', 1.0, \"1\", [1]))\n    {\n        auto a = only(x);\n        typeof(x)[] e = [];\n        assert(a.front == x);\n        assert(a.back == x);\n        assert(!a.empty);\n        assert(a.length == 1);\n        assert(equal(a, a[]));\n        assert(equal(a, a[0 .. 1]));\n        assert(equal(a[0 .. 0], e));\n        assert(equal(a[1 .. 1], e));\n        assert(a[0] == x);\n\n        auto b = a.save;\n        assert(equal(a, b));\n        a.popFront();\n        assert(a.empty && a.length == 0 && a[].empty);\n        b.popBack();\n        assert(b.empty && b.length == 0 && b[].empty);\n\n        alias A = typeof(a);\n        static assert(isInputRange!A);\n        static assert(isForwardRange!A);\n        static assert(isBidirectionalRange!A);\n        static assert(isRandomAccessRange!A);\n        static assert(hasLength!A);\n        static assert(hasSlicing!A);\n    }\n\n    auto imm = only!(immutable int)(1);\n    immutable int[] imme = [];\n    assert(imm.front == 1);\n    assert(imm.back == 1);\n    assert(!imm.empty);\n    assert(imm.init.empty); // Issue 13441\n    assert(imm.length == 1);\n    assert(equal(imm, imm[]));\n    assert(equal(imm, imm[0 .. 1]));\n    assert(equal(imm[0 .. 0], imme));\n    assert(equal(imm[1 .. 1], imme));\n    assert(imm[0] == 1);\n}\n\n// Tests multiple-element results\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : joiner;\n    import std.meta : AliasSeq;\n    static assert(!__traits(compiles, only(1, \"1\")));\n\n    auto nums = only!(byte, uint, long)(1, 2, 3);\n    static assert(is(ElementType!(typeof(nums)) == long));\n    assert(nums.length == 3);\n\n    foreach (i; 0 .. 3)\n        assert(nums[i] == i + 1);\n\n    auto saved = nums.save;\n\n    foreach (i; 1 .. 4)\n    {\n        assert(nums.front == nums[0]);\n        assert(nums.front == i);\n        nums.popFront();\n        assert(nums.length == 3 - i);\n    }\n\n    assert(nums.empty);\n\n    assert(saved.equal(only(1, 2, 3)));\n    assert(saved.equal(saved[]));\n    assert(saved[0 .. 1].equal(only(1)));\n    assert(saved[0 .. 2].equal(only(1, 2)));\n    assert(saved[0 .. 3].equal(saved));\n    assert(saved[1 .. 3].equal(only(2, 3)));\n    assert(saved[2 .. 3].equal(only(3)));\n    assert(saved[0 .. 0].empty);\n    assert(saved[3 .. 3].empty);\n\n    alias data = AliasSeq!(\"one\", \"two\", \"three\", \"four\");\n    static joined =\n        [\"one two\", \"one two three\", \"one two three four\"];\n    string[] joinedRange = joined;\n\n    static foreach (argCount; 2 .. 5)\n    {{\n        auto values = only(data[0 .. argCount]);\n        alias Values = typeof(values);\n        static assert(is(ElementType!Values == string));\n        static assert(isInputRange!Values);\n        static assert(isForwardRange!Values);\n        static assert(isBidirectionalRange!Values);\n        static assert(isRandomAccessRange!Values);\n        static assert(hasSlicing!Values);\n        static assert(hasLength!Values);\n\n        assert(values.length == argCount);\n        assert(values[0 .. $].equal(values[0 .. values.length]));\n        assert(values.joiner(\" \").equal(joinedRange.front));\n        joinedRange.popFront();\n    }}\n\n    assert(saved.retro.equal(only(3, 2, 1)));\n    assert(saved.length == 3);\n\n    assert(saved.back == 3);\n    saved.popBack();\n    assert(saved.length == 2);\n    assert(saved.back == 2);\n\n    assert(saved.front == 1);\n    saved.popFront();\n    assert(saved.length == 1);\n    assert(saved.front == 2);\n\n    saved.popBack();\n    assert(saved.empty);\n\n    auto imm = only!(immutable int, immutable int)(42, 24);\n    alias Imm = typeof(imm);\n    static assert(is(ElementType!Imm == immutable(int)));\n    assert(!imm.empty);\n    assert(imm.init.empty); // Issue 13441\n    assert(imm.front == 42);\n    imm.popFront();\n    assert(imm.front == 24);\n    imm.popFront();\n    assert(imm.empty);\n\n    static struct Test { int* a; }\n    immutable(Test) test;\n    cast(void) only(test, test); // Works with mutable indirection\n}\n\n/**\nIterate over `range` with an attached index variable.\n\nEach element is a $(REF Tuple, std,typecons) containing the index\nand the element, in that order, where the index member is named `index`\nand the element member is named `value`.\n\nThe index starts at `start` and is incremented by one on every iteration.\n\nOverflow:\n    If `range` has length, then it is an error to pass a value for `start`\n    so that `start + range.length` is bigger than `Enumerator.max`, thus\n    it is ensured that overflow cannot happen.\n\n    If `range` does not have length, and `popFront` is called when\n    `front.index == Enumerator.max`, the index will overflow and\n    continue from `Enumerator.min`.\n\nParams:\n    range = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to attach indexes to\n    start = the number to start the index counter from\n\nReturns:\n    At minimum, an input range. All other range primitives are given in the\n    resulting range if `range` has them. The exceptions are the bidirectional\n    primitives, which are propagated only if `range` has length.\n\nExample:\nUseful for using `foreach` with an index loop variable:\n----\n    import std.stdio : stdin, stdout;\n    import std.range : enumerate;\n\n    foreach (lineNum, line; stdin.byLine().enumerate(1))\n        stdout.writefln(\"line #%s: %s\", lineNum, line);\n----\n*/\nauto enumerate(Enumerator = size_t, Range)(Range range, Enumerator start = 0)\nif (isIntegral!Enumerator && isInputRange!Range)\nin\n{\n    static if (hasLength!Range)\n    {\n        // TODO: core.checkedint supports mixed signedness yet?\n        import core.checkedint : adds, addu;\n        import std.conv : ConvException, to;\n        import std.traits : isSigned, Largest, Signed;\n\n        alias LengthType = typeof(range.length);\n        bool overflow;\n        static if (isSigned!Enumerator && isSigned!LengthType)\n            auto result = adds(start, range.length, overflow);\n        else static if (isSigned!Enumerator)\n        {\n            Largest!(Enumerator, Signed!LengthType) signedLength;\n            try signedLength = to!(typeof(signedLength))(range.length);\n            catch (ConvException)\n                overflow = true;\n            catch (Exception)\n                assert(false);\n\n            auto result = adds(start, signedLength, overflow);\n        }\n        else\n        {\n            static if (isSigned!LengthType)\n                assert(range.length >= 0);\n            auto result = addu(start, range.length, overflow);\n        }\n\n        assert(!overflow && result <= Enumerator.max);\n    }\n}\ndo\n{\n    // TODO: Relax isIntegral!Enumerator to allow user-defined integral types\n    static struct Result\n    {\n        import std.typecons : Tuple;\n\n        private:\n        alias ElemType = Tuple!(Enumerator, \"index\", ElementType!Range, \"value\");\n        Range range;\n        Enumerator index;\n\n        public:\n        ElemType front() @property\n        {\n            assert(!range.empty, \"Attempting to fetch the front of an empty enumerate\");\n            return typeof(return)(index, range.front);\n        }\n\n        static if (isInfinite!Range)\n            enum bool empty = false;\n        else\n        {\n            bool empty() @property\n            {\n                return range.empty;\n            }\n        }\n\n        void popFront()\n        {\n            assert(!range.empty, \"Attempting to popFront an empty enumerate\");\n            range.popFront();\n            ++index; // When !hasLength!Range, overflow is expected\n        }\n\n        static if (isForwardRange!Range)\n        {\n            Result save() @property\n            {\n                return typeof(return)(range.save, index);\n            }\n        }\n\n        static if (hasLength!Range)\n        {\n            size_t length() @property\n            {\n                return range.length;\n            }\n\n            alias opDollar = length;\n\n            static if (isBidirectionalRange!Range)\n            {\n                ElemType back() @property\n                {\n                    assert(!range.empty, \"Attempting to fetch the back of an empty enumerate\");\n                    return typeof(return)(cast(Enumerator)(index + range.length - 1), range.back);\n                }\n\n                void popBack()\n                {\n                    assert(!range.empty, \"Attempting to popBack an empty enumerate\");\n                    range.popBack();\n                }\n            }\n        }\n\n        static if (isRandomAccessRange!Range)\n        {\n             ElemType opIndex(size_t i)\n             {\n                return typeof(return)(cast(Enumerator)(index + i), range[i]);\n             }\n        }\n\n        static if (hasSlicing!Range)\n        {\n            static if (hasLength!Range)\n            {\n                Result opSlice(size_t i, size_t j)\n                {\n                    return typeof(return)(range[i .. j], cast(Enumerator)(index + i));\n                }\n            }\n            else\n            {\n                static struct DollarToken {}\n                enum opDollar = DollarToken.init;\n\n                Result opSlice(size_t i, DollarToken)\n                {\n                    return typeof(return)(range[i .. $], cast(Enumerator)(index + i));\n                }\n\n                auto opSlice(size_t i, size_t j)\n                {\n                    return this[i .. $].takeExactly(j - 1);\n                }\n            }\n        }\n    }\n\n    return Result(range, start);\n}\n\n/// Can start enumeration from a negative position:\npure @safe nothrow unittest\n{\n    import std.array : assocArray;\n    import std.range : enumerate;\n\n    bool[int] aa = true.repeat(3).enumerate(-1).assocArray();\n    assert(aa[-1]);\n    assert(aa[0]);\n    assert(aa[1]);\n}\n\npure @safe nothrow unittest\n{\n    import std.internal.test.dummyrange : AllDummyRanges;\n    import std.meta : AliasSeq;\n    import std.typecons : tuple;\n\n    static struct HasSlicing\n    {\n        typeof(this) front() @property { return typeof(this).init; }\n        bool empty() @property { return true; }\n        void popFront() {}\n\n        typeof(this) opSlice(size_t, size_t)\n        {\n            return typeof(this)();\n        }\n    }\n\n    static foreach (DummyType; AliasSeq!(AllDummyRanges, HasSlicing))\n    {{\n        alias R = typeof(enumerate(DummyType.init));\n        static assert(isInputRange!R);\n        static assert(isForwardRange!R == isForwardRange!DummyType);\n        static assert(isRandomAccessRange!R == isRandomAccessRange!DummyType);\n        static assert(!hasAssignableElements!R);\n\n        static if (hasLength!DummyType)\n        {\n            static assert(hasLength!R);\n            static assert(isBidirectionalRange!R ==\n                isBidirectionalRange!DummyType);\n        }\n\n        static assert(hasSlicing!R == hasSlicing!DummyType);\n    }}\n\n    static immutable values = [\"zero\", \"one\", \"two\", \"three\"];\n    auto enumerated = values[].enumerate();\n    assert(!enumerated.empty);\n    assert(enumerated.front == tuple(0, \"zero\"));\n    assert(enumerated.back == tuple(3, \"three\"));\n\n    typeof(enumerated) saved = enumerated.save;\n    saved.popFront();\n    assert(enumerated.front == tuple(0, \"zero\"));\n    assert(saved.front == tuple(1, \"one\"));\n    assert(saved.length == enumerated.length - 1);\n    saved.popBack();\n    assert(enumerated.back == tuple(3, \"three\"));\n    assert(saved.back == tuple(2, \"two\"));\n    saved.popFront();\n    assert(saved.front == tuple(2, \"two\"));\n    assert(saved.back == tuple(2, \"two\"));\n    saved.popFront();\n    assert(saved.empty);\n\n    size_t control = 0;\n    foreach (i, v; enumerated)\n    {\n        static assert(is(typeof(i) == size_t));\n        static assert(is(typeof(v) == typeof(values[0])));\n        assert(i == control);\n        assert(v == values[i]);\n        assert(tuple(i, v) == enumerated[i]);\n        ++control;\n    }\n\n    assert(enumerated[0 .. $].front == tuple(0, \"zero\"));\n    assert(enumerated[$ - 1 .. $].front == tuple(3, \"three\"));\n\n    foreach (i; 0 .. 10)\n    {\n        auto shifted = values[0 .. 2].enumerate(i);\n        assert(shifted.front == tuple(i, \"zero\"));\n        assert(shifted[0] == shifted.front);\n\n        auto next = tuple(i + 1, \"one\");\n        assert(shifted[1] == next);\n        shifted.popFront();\n        assert(shifted.front == next);\n        shifted.popFront();\n        assert(shifted.empty);\n    }\n\n    static foreach (T; AliasSeq!(ubyte, byte, uint, int))\n    {{\n        auto inf = 42.repeat().enumerate(T.max);\n        alias Inf = typeof(inf);\n        static assert(isInfinite!Inf);\n        static assert(hasSlicing!Inf);\n\n        // test overflow\n        assert(inf.front == tuple(T.max, 42));\n        inf.popFront();\n        assert(inf.front == tuple(T.min, 42));\n\n        // test slicing\n        inf = inf[42 .. $];\n        assert(inf.front == tuple(T.min + 42, 42));\n        auto window = inf[0 .. 2];\n        assert(window.length == 1);\n        assert(window.front == inf.front);\n        window.popFront();\n        assert(window.empty);\n    }}\n}\n\npure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.meta : AliasSeq;\n    static immutable int[] values = [0, 1, 2, 3, 4];\n    static foreach (T; AliasSeq!(ubyte, ushort, uint, ulong))\n    {{\n        auto enumerated = values.enumerate!T();\n        static assert(is(typeof(enumerated.front.index) == T));\n        assert(enumerated.equal(values[].zip(values)));\n\n        foreach (T i; 0 .. 5)\n        {\n            auto subset = values[cast(size_t) i .. $];\n            auto offsetEnumerated = subset.enumerate(i);\n            static assert(is(typeof(enumerated.front.index) == T));\n            assert(offsetEnumerated.equal(subset.zip(subset)));\n        }\n    }}\n}\n\nversion (none) // @@@BUG@@@ 10939\n{\n    // Re-enable (or remove) if 10939 is resolved.\n    /+pure+/ @safe unittest // Impure because of std.conv.to\n    {\n        import core.exception : RangeError;\n        import std.exception : assertNotThrown, assertThrown;\n        import std.meta : AliasSeq;\n\n        static immutable values = [42];\n\n        static struct SignedLengthRange\n        {\n            immutable(int)[] _values = values;\n\n            int front() @property { assert(false); }\n            bool empty() @property { assert(false); }\n            void popFront() { assert(false); }\n\n            int length() @property\n            {\n                return cast(int)_values.length;\n            }\n        }\n\n        SignedLengthRange svalues;\n        static foreach (Enumerator; AliasSeq!(ubyte, byte, ushort, short, uint, int, ulong, long))\n        {\n            assertThrown!RangeError(values[].enumerate!Enumerator(Enumerator.max));\n            assertNotThrown!RangeError(values[].enumerate!Enumerator(Enumerator.max - values.length));\n            assertThrown!RangeError(values[].enumerate!Enumerator(Enumerator.max - values.length + 1));\n\n            assertThrown!RangeError(svalues.enumerate!Enumerator(Enumerator.max));\n            assertNotThrown!RangeError(svalues.enumerate!Enumerator(Enumerator.max - values.length));\n            assertThrown!RangeError(svalues.enumerate!Enumerator(Enumerator.max - values.length + 1));\n        }\n\n        static foreach (Enumerator; AliasSeq!(byte, short, int))\n        {\n            assertThrown!RangeError(repeat(0, uint.max).enumerate!Enumerator());\n        }\n\n        assertNotThrown!RangeError(repeat(0, uint.max).enumerate!long());\n    }\n}\n\n/**\n  Returns true if `fn` accepts variables of type T1 and T2 in any order.\n  The following code should compile:\n  ---\n  T1 foo();\n  T2 bar();\n\n  fn(foo(), bar());\n  fn(bar(), foo());\n  ---\n*/\ntemplate isTwoWayCompatible(alias fn, T1, T2)\n{\n    enum isTwoWayCompatible = is(typeof( (){\n            T1 foo();\n            T2 bar();\n\n            cast(void) fn(foo(), bar());\n            cast(void) fn(bar(), foo());\n        }\n    ));\n}\n\n///\n@safe unittest\n{\n    void func1(int a, int b);\n    void func2(int a, float b);\n\n    static assert(isTwoWayCompatible!(func1, int, int));\n    static assert(isTwoWayCompatible!(func1, short, int));\n    static assert(!isTwoWayCompatible!(func2, int, float));\n}\n\n\n/**\n   Policy used with the searching primitives `lowerBound`, $(D\n   upperBound), and `equalRange` of $(LREF SortedRange) below.\n */\nenum SearchPolicy\n{\n    /**\n       Searches in a linear fashion.\n    */\n    linear,\n\n    /**\n       Searches with a step that is grows linearly (1, 2, 3,...)\n       leading to a quadratic search schedule (indexes tried are 0, 1,\n       3, 6, 10, 15, 21, 28,...) Once the search overshoots its target,\n       the remaining interval is searched using binary search. The\n       search is completed in $(BIGOH sqrt(n)) time. Use it when you\n       are reasonably confident that the value is around the beginning\n       of the range.\n    */\n    trot,\n\n    /**\n       Performs a $(LINK2 https://en.wikipedia.org/wiki/Exponential_search,\n       galloping search algorithm), i.e. searches\n       with a step that doubles every time, (1, 2, 4, 8, ...)  leading\n       to an exponential search schedule (indexes tried are 0, 1, 3,\n       7, 15, 31, 63,...) Once the search overshoots its target, the\n       remaining interval is searched using binary search. A value is\n       found in $(BIGOH log(n)) time.\n    */\n    gallop,\n\n    /**\n       Searches using a classic interval halving policy. The search\n       starts in the middle of the range, and each search step cuts\n       the range in half. This policy finds a value in $(BIGOH log(n))\n       time but is less cache friendly than `gallop` for large\n       ranges. The `binarySearch` policy is used as the last step\n       of `trot`, `gallop`, `trotBackwards`, and $(D\n       gallopBackwards) strategies.\n    */\n    binarySearch,\n\n    /**\n       Similar to `trot` but starts backwards. Use it when\n       confident that the value is around the end of the range.\n    */\n    trotBackwards,\n\n    /**\n       Similar to `gallop` but starts backwards. Use it when\n       confident that the value is around the end of the range.\n    */\n    gallopBackwards\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto a = assumeSorted([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);\n    auto p1 = a.upperBound!(SearchPolicy.binarySearch)(3);\n    assert(p1.equal([4, 5, 6, 7, 8, 9]));\n\n    auto p2 = a.lowerBound!(SearchPolicy.gallop)(4);\n    assert(p2.equal([0, 1, 2, 3]));\n}\n\n/**\nRepresents a sorted range. In addition to the regular range\nprimitives, supports additional operations that take advantage of the\nordering, such as merge and binary search. To obtain a $(D\nSortedRange) from an unsorted range `r`, use\n$(REF sort, std,algorithm,sorting) which sorts `r` in place and returns the\ncorresponding `SortedRange`. To construct a `SortedRange` from a range\n`r` that is known to be already sorted, use $(LREF assumeSorted) described\nbelow.\n*/\nstruct SortedRange(Range, alias pred = \"a < b\")\nif (isInputRange!Range)\n{\n    import std.functional : binaryFun;\n\n    private alias predFun = binaryFun!pred;\n    private bool geq(L, R)(L lhs, R rhs)\n    {\n        return !predFun(lhs, rhs);\n    }\n    private bool gt(L, R)(L lhs, R rhs)\n    {\n        return predFun(rhs, lhs);\n    }\n    private Range _input;\n\n    // Undocummented because a clearer way to invoke is by calling\n    // assumeSorted.\n    this(Range input)\n    out\n    {\n        // moved out of the body as a workaround for Issue 12661\n        dbgVerifySorted();\n    }\n    do\n    {\n        this._input = input;\n    }\n\n    // Assertion only.\n    private void dbgVerifySorted()\n    {\n        if (!__ctfe)\n        debug\n        {\n            static if (isRandomAccessRange!Range && hasLength!Range)\n            {\n                import core.bitop : bsr;\n                import std.algorithm.sorting : isSorted;\n\n                // Check the sortedness of the input\n                if (this._input.length < 2) return;\n\n                immutable size_t msb = bsr(this._input.length) + 1;\n                assert(msb > 0 && msb <= this._input.length);\n                immutable step = this._input.length / msb;\n                auto st = stride(this._input, step);\n\n                assert(isSorted!pred(st), \"Range is not sorted\");\n            }\n        }\n    }\n\n    /// Range primitives.\n    @property bool empty()             //const\n    {\n        return this._input.empty;\n    }\n\n    /// Ditto\n    static if (isForwardRange!Range)\n    @property auto save()\n    {\n        // Avoid the constructor\n        typeof(this) result = this;\n        result._input = _input.save;\n        return result;\n    }\n\n    /// Ditto\n    @property auto ref front()\n    {\n        return _input.front;\n    }\n\n    /// Ditto\n    void popFront()\n    {\n        _input.popFront();\n    }\n\n    /// Ditto\n    static if (isBidirectionalRange!Range)\n    {\n        @property auto ref back()\n        {\n            return _input.back;\n        }\n\n        /// Ditto\n        void popBack()\n        {\n            _input.popBack();\n        }\n    }\n\n    /// Ditto\n    static if (isRandomAccessRange!Range)\n        auto ref opIndex(size_t i)\n        {\n            return _input[i];\n        }\n\n    /// Ditto\n    static if (hasSlicing!Range)\n        auto opSlice(size_t a, size_t b)\n        {\n            assert(\n                a <= b,\n                \"Attempting to slice a SortedRange with a larger first argument than the second.\"\n            );\n            typeof(this) result = this;\n            result._input = _input[a .. b];// skip checking\n            return result;\n        }\n\n    /// Ditto\n    static if (hasLength!Range)\n    {\n        @property size_t length()          //const\n        {\n            return _input.length;\n        }\n        alias opDollar = length;\n    }\n\n/**\n   Releases the controlled range and returns it.\n*/\n    auto release()\n    {\n        import std.algorithm.mutation : move;\n        return move(_input);\n    }\n\n    // Assuming a predicate \"test\" that returns 0 for a left portion\n    // of the range and then 1 for the rest, returns the index at\n    // which the first 1 appears. Used internally by the search routines.\n    private size_t getTransitionIndex(SearchPolicy sp, alias test, V)(V v)\n    if (sp == SearchPolicy.binarySearch && isRandomAccessRange!Range && hasLength!Range)\n    {\n        size_t first = 0, count = _input.length;\n        while (count > 0)\n        {\n            immutable step = count / 2, it = first + step;\n            if (!test(_input[it], v))\n            {\n                first = it + 1;\n                count -= step + 1;\n            }\n            else\n            {\n                count = step;\n            }\n        }\n        return first;\n    }\n\n    // Specialization for trot and gallop\n    private size_t getTransitionIndex(SearchPolicy sp, alias test, V)(V v)\n    if ((sp == SearchPolicy.trot || sp == SearchPolicy.gallop)\n        && isRandomAccessRange!Range)\n    {\n        if (empty || test(front, v)) return 0;\n        immutable count = length;\n        if (count == 1) return 1;\n        size_t below = 0, above = 1, step = 2;\n        while (!test(_input[above], v))\n        {\n            // Still too small, update below and increase gait\n            below = above;\n            immutable next = above + step;\n            if (next >= count)\n            {\n                // Overshot - the next step took us beyond the end. So\n                // now adjust next and simply exit the loop to do the\n                // binary search thingie.\n                above = count;\n                break;\n            }\n            // Still in business, increase step and continue\n            above = next;\n            static if (sp == SearchPolicy.trot)\n                ++step;\n            else\n                step <<= 1;\n        }\n        return below + this[below .. above].getTransitionIndex!(\n            SearchPolicy.binarySearch, test, V)(v);\n    }\n\n    // Specialization for trotBackwards and gallopBackwards\n    private size_t getTransitionIndex(SearchPolicy sp, alias test, V)(V v)\n    if ((sp == SearchPolicy.trotBackwards || sp == SearchPolicy.gallopBackwards)\n        && isRandomAccessRange!Range)\n    {\n        immutable count = length;\n        if (empty || !test(back, v)) return count;\n        if (count == 1) return 0;\n        size_t below = count - 2, above = count - 1, step = 2;\n        while (test(_input[below], v))\n        {\n            // Still too large, update above and increase gait\n            above = below;\n            if (below < step)\n            {\n                // Overshot - the next step took us beyond the end. So\n                // now adjust next and simply fall through to do the\n                // binary search thingie.\n                below = 0;\n                break;\n            }\n            // Still in business, increase step and continue\n            below -= step;\n            static if (sp == SearchPolicy.trot)\n                ++step;\n            else\n                step <<= 1;\n        }\n        return below + this[below .. above].getTransitionIndex!(\n            SearchPolicy.binarySearch, test, V)(v);\n    }\n\n// lowerBound\n/**\n   This function uses a search with policy `sp` to find the\n   largest left subrange on which $(D pred(x, value)) is `true` for\n   all `x` (e.g., if `pred` is \"less than\", returns the portion of\n   the range with elements strictly smaller than `value`). The search\n   schedule and its complexity are documented in\n   $(LREF SearchPolicy).\n*/\n    auto lowerBound(SearchPolicy sp = SearchPolicy.binarySearch, V)(V value)\n    if (isTwoWayCompatible!(predFun, ElementType!Range, V)\n         && hasSlicing!Range)\n    {\n        return this[0 .. getTransitionIndex!(sp, geq)(value)];\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.algorithm.comparison : equal;\n        auto a = assumeSorted([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]);\n        auto p = a.lowerBound(4);\n        assert(equal(p, [ 0, 1, 2, 3 ]));\n    }\n\n// upperBound\n/**\nThis function searches with policy `sp` to find the largest right\nsubrange on which $(D pred(value, x)) is `true` for all `x`\n(e.g., if `pred` is \"less than\", returns the portion of the range\nwith elements strictly greater than `value`). The search schedule\nand its complexity are documented in $(LREF SearchPolicy).\n\nFor ranges that do not offer random access, `SearchPolicy.linear`\nis the only policy allowed (and it must be specified explicitly lest it exposes\nuser code to unexpected inefficiencies). For random-access searches, all\npolicies are allowed, and `SearchPolicy.binarySearch` is the default.\n*/\n    auto upperBound(SearchPolicy sp = SearchPolicy.binarySearch, V)(V value)\n    if (isTwoWayCompatible!(predFun, ElementType!Range, V))\n    {\n        static assert(hasSlicing!Range || sp == SearchPolicy.linear,\n            \"Specify SearchPolicy.linear explicitly for \"\n            ~ typeof(this).stringof);\n        static if (sp == SearchPolicy.linear)\n        {\n            for (; !_input.empty && !predFun(value, _input.front);\n                 _input.popFront())\n            {\n            }\n            return this;\n        }\n        else\n        {\n            return this[getTransitionIndex!(sp, gt)(value) .. length];\n        }\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.algorithm.comparison : equal;\n        auto a = assumeSorted([ 1, 2, 3, 3, 3, 4, 4, 5, 6 ]);\n        auto p = a.upperBound(3);\n        assert(equal(p, [4, 4, 5, 6]));\n    }\n\n\n// equalRange\n/**\n   Returns the subrange containing all elements `e` for which both $(D\n   pred(e, value)) and $(D pred(value, e)) evaluate to `false` (e.g.,\n   if `pred` is \"less than\", returns the portion of the range with\n   elements equal to `value`). Uses a classic binary search with\n   interval halving until it finds a value that satisfies the condition,\n   then uses `SearchPolicy.gallopBackwards` to find the left boundary\n   and `SearchPolicy.gallop` to find the right boundary. These\n   policies are justified by the fact that the two boundaries are likely\n   to be near the first found value (i.e., equal ranges are relatively\n   small). Completes the entire search in $(BIGOH log(n)) time.\n*/\n    auto equalRange(V)(V value)\n    if (isTwoWayCompatible!(predFun, ElementType!Range, V)\n        && isRandomAccessRange!Range)\n    {\n        size_t first = 0, count = _input.length;\n        while (count > 0)\n        {\n            immutable step = count / 2;\n            auto it = first + step;\n            if (predFun(_input[it], value))\n            {\n                // Less than value, bump left bound up\n                first = it + 1;\n                count -= step + 1;\n            }\n            else if (predFun(value, _input[it]))\n            {\n                // Greater than value, chop count\n                count = step;\n            }\n            else\n            {\n                // Equal to value, do binary searches in the\n                // leftover portions\n                // Gallop towards the left end as it's likely nearby\n                immutable left = first\n                    + this[first .. it]\n                    .lowerBound!(SearchPolicy.gallopBackwards)(value).length;\n                first += count;\n                // Gallop towards the right end as it's likely nearby\n                immutable right = first\n                    - this[it + 1 .. first]\n                    .upperBound!(SearchPolicy.gallop)(value).length;\n                return this[left .. right];\n            }\n        }\n        return this.init;\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.algorithm.comparison : equal;\n        auto a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];\n        auto r = a.assumeSorted.equalRange(3);\n        assert(equal(r, [ 3, 3, 3 ]));\n    }\n\n// trisect\n/**\nReturns a tuple `r` such that `r[0]` is the same as the result\nof `lowerBound(value)`, `r[1]` is the same as the result of $(D\nequalRange(value)), and `r[2]` is the same as the result of $(D\nupperBound(value)). The call is faster than computing all three\nseparately. Uses a search schedule similar to $(D\nequalRange). Completes the entire search in $(BIGOH log(n)) time.\n*/\n    auto trisect(V)(V value)\n    if (isTwoWayCompatible!(predFun, ElementType!Range, V)\n        && isRandomAccessRange!Range && hasLength!Range)\n    {\n        import std.typecons : tuple;\n        size_t first = 0, count = _input.length;\n        while (count > 0)\n        {\n            immutable step = count / 2;\n            auto it = first + step;\n            if (predFun(_input[it], value))\n            {\n                // Less than value, bump left bound up\n                first = it + 1;\n                count -= step + 1;\n            }\n            else if (predFun(value, _input[it]))\n            {\n                // Greater than value, chop count\n                count = step;\n            }\n            else\n            {\n                // Equal to value, do binary searches in the\n                // leftover portions\n                // Gallop towards the left end as it's likely nearby\n                immutable left = first\n                    + this[first .. it]\n                    .lowerBound!(SearchPolicy.gallopBackwards)(value).length;\n                first += count;\n                // Gallop towards the right end as it's likely nearby\n                immutable right = first\n                    - this[it + 1 .. first]\n                    .upperBound!(SearchPolicy.gallop)(value).length;\n                return tuple(this[0 .. left], this[left .. right],\n                        this[right .. length]);\n            }\n        }\n        // No equal element was found\n        return tuple(this[0 .. first], this.init, this[first .. length]);\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.algorithm.comparison : equal;\n        auto a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];\n        auto r = assumeSorted(a).trisect(3);\n        assert(equal(r[0], [ 1, 2 ]));\n        assert(equal(r[1], [ 3, 3, 3 ]));\n        assert(equal(r[2], [ 4, 4, 5, 6 ]));\n    }\n\n// contains\n/**\nReturns `true` if and only if `value` can be found in $(D\nrange), which is assumed to be sorted. Performs $(BIGOH log(r.length))\nevaluations of `pred`.\n */\n\n    bool contains(V)(V value)\n    if (isRandomAccessRange!Range)\n    {\n        if (empty) return false;\n        immutable i = getTransitionIndex!(SearchPolicy.binarySearch, geq)(value);\n        if (i >= length) return false;\n        return !predFun(value, _input[i]);\n    }\n\n/**\nLike `contains`, but the value is specified before the range.\n*/\n    auto opBinaryRight(string op, V)(V value)\n    if (op == \"in\" && isRandomAccessRange!Range)\n    {\n        return contains(value);\n    }\n\n// groupBy\n/**\nReturns a range of subranges of elements that are equivalent according to the\nsorting relation.\n */\n    auto groupBy()()\n    {\n        import std.algorithm.iteration : chunkBy;\n        return _input.chunkBy!((a, b) => !predFun(a, b) && !predFun(b, a));\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.sorting : sort;\n    auto a = [ 1, 2, 3, 42, 52, 64 ];\n    auto r = assumeSorted(a);\n    assert(r.contains(3));\n    assert(!(32 in r));\n    auto r1 = sort!\"a > b\"(a);\n    assert(3 in r1);\n    assert(!r1.contains(32));\n    assert(r1.release() == [ 64, 52, 42, 3, 2, 1 ]);\n}\n\n/**\n`SortedRange` could accept ranges weaker than random-access, but it\nis unable to provide interesting functionality for them. Therefore,\n`SortedRange` is currently restricted to random-access ranges.\n\nNo copy of the original range is ever made. If the underlying range is\nchanged concurrently with its corresponding `SortedRange` in ways\nthat break its sorted-ness, `SortedRange` will work erratically.\n*/\n@safe unittest\n{\n    import std.algorithm.mutation : swap;\n    auto a = [ 1, 2, 3, 42, 52, 64 ];\n    auto r = assumeSorted(a);\n    assert(r.contains(42));\n    swap(a[3], a[5]);         // illegal to break sortedness of original range\n    assert(!r.contains(42));  // passes although it shouldn't\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    auto a = [ 10, 20, 30, 30, 30, 40, 40, 50, 60 ];\n    auto r = assumeSorted(a).trisect(30);\n    assert(equal(r[0], [ 10, 20 ]));\n    assert(equal(r[1], [ 30, 30, 30 ]));\n    assert(equal(r[2], [ 40, 40, 50, 60 ]));\n\n    r = assumeSorted(a).trisect(35);\n    assert(equal(r[0], [ 10, 20, 30, 30, 30 ]));\n    assert(r[1].empty);\n    assert(equal(r[2], [ 40, 40, 50, 60 ]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto a = [ \"A\", \"AG\", \"B\", \"E\", \"F\" ];\n    auto r = assumeSorted!\"cmp(a,b) < 0\"(a).trisect(\"B\"w);\n    assert(equal(r[0], [ \"A\", \"AG\" ]));\n    assert(equal(r[1], [ \"B\" ]));\n    assert(equal(r[2], [ \"E\", \"F\" ]));\n    r = assumeSorted!\"cmp(a,b) < 0\"(a).trisect(\"A\"d);\n    assert(r[0].empty);\n    assert(equal(r[1], [ \"A\" ]));\n    assert(equal(r[2], [ \"AG\", \"B\", \"E\", \"F\" ]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    static void test(SearchPolicy pol)()\n    {\n        auto a = [ 1, 2, 3, 42, 52, 64 ];\n        auto r = assumeSorted(a);\n        assert(equal(r.lowerBound(42), [1, 2, 3]));\n\n        assert(equal(r.lowerBound!(pol)(42), [1, 2, 3]));\n        assert(equal(r.lowerBound!(pol)(41), [1, 2, 3]));\n        assert(equal(r.lowerBound!(pol)(43), [1, 2, 3, 42]));\n        assert(equal(r.lowerBound!(pol)(51), [1, 2, 3, 42]));\n        assert(equal(r.lowerBound!(pol)(3), [1, 2]));\n        assert(equal(r.lowerBound!(pol)(55), [1, 2, 3, 42, 52]));\n        assert(equal(r.lowerBound!(pol)(420), a));\n        assert(equal(r.lowerBound!(pol)(0), a[0 .. 0]));\n\n        assert(equal(r.upperBound!(pol)(42), [52, 64]));\n        assert(equal(r.upperBound!(pol)(41), [42, 52, 64]));\n        assert(equal(r.upperBound!(pol)(43), [52, 64]));\n        assert(equal(r.upperBound!(pol)(51), [52, 64]));\n        assert(equal(r.upperBound!(pol)(53), [64]));\n        assert(equal(r.upperBound!(pol)(55), [64]));\n        assert(equal(r.upperBound!(pol)(420), a[0 .. 0]));\n        assert(equal(r.upperBound!(pol)(0), a));\n    }\n\n    test!(SearchPolicy.trot)();\n    test!(SearchPolicy.gallop)();\n    test!(SearchPolicy.trotBackwards)();\n    test!(SearchPolicy.gallopBackwards)();\n    test!(SearchPolicy.binarySearch)();\n}\n\n@safe unittest\n{\n    // Check for small arrays\n    int[] a;\n    auto r = assumeSorted(a);\n    a = [ 1 ];\n    r = assumeSorted(a);\n    a = [ 1, 2 ];\n    r = assumeSorted(a);\n    a = [ 1, 2, 3 ];\n    r = assumeSorted(a);\n}\n\n@safe unittest\n{\n    import std.algorithm.mutation : swap;\n    auto a = [ 1, 2, 3, 42, 52, 64 ];\n    auto r = assumeSorted(a);\n    assert(r.contains(42));\n    swap(a[3], a[5]);                  // illegal to break sortedness of original range\n    assert(!r.contains(42));            // passes although it shouldn't\n}\n\n@safe unittest\n{\n    immutable(int)[] arr = [ 1, 2, 3 ];\n    auto s = assumeSorted(arr);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    int[] arr = [100, 101, 102, 200, 201, 300];\n    auto s = assumeSorted!((a, b) => a / 100 < b / 100)(arr);\n    assert(s.groupBy.equal!equal([[100, 101, 102], [200, 201], [300]]));\n}\n\n// Test on an input range\n@system unittest\n{\n    import std.conv : text;\n    import std.file : exists, remove, tempDir;\n    import std.path : buildPath;\n    import std.stdio : File;\n    import std.uuid : randomUUID;\n    auto name = buildPath(tempDir(), \"test.std.range.line-\" ~ text(__LINE__) ~\n                          \".\" ~ randomUUID().toString());\n    auto f = File(name, \"w\");\n    scope(exit) if (exists(name)) remove(name);\n    // write a sorted range of lines to the file\n    f.write(\"abc\\ndef\\nghi\\njkl\");\n    f.close();\n    f.open(name, \"r\");\n    auto r = assumeSorted(f.byLine());\n    auto r1 = r.upperBound!(SearchPolicy.linear)(\"def\");\n    assert(r1.front == \"ghi\", r1.front);\n    f.close();\n}\n\n/**\nAssumes `r` is sorted by predicate `pred` and returns the\ncorresponding $(D SortedRange!(pred, R)) having `r` as support. To\nkeep the checking costs low, the cost is $(BIGOH 1) in release mode\n(no checks for sorted-ness are performed). In debug mode, a few random\nelements of `r` are checked for sorted-ness. The size of the sample\nis proportional $(BIGOH log(r.length)). That way, checking has no\neffect on the complexity of subsequent operations specific to sorted\nranges (such as binary search). The probability of an arbitrary\nunsorted range failing the test is very high (however, an\nalmost-sorted range is likely to pass it). To check for sorted-ness at\ncost $(BIGOH n), use $(REF isSorted, std,algorithm,sorting).\n */\nauto assumeSorted(alias pred = \"a < b\", R)(R r)\nif (isInputRange!(Unqual!R))\n{\n    // Avoid senseless `SortedRange!(SortedRange!(...), pred)` nesting.\n    static if (is(R == SortedRange!(RRange, RPred), RRange, alias RPred))\n    {\n        static if (isInputRange!R && __traits(isSame, pred, RPred))\n            // If the predicate is the same and we don't need to cast away\n            // constness for the result to be an input range.\n            return r;\n        else\n            return SortedRange!(Unqual!(typeof(r._input)), pred)(r._input);\n    }\n    else\n    {\n        return SortedRange!(Unqual!R, pred)(r);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    int[] a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n    auto p = assumeSorted(a);\n\n    assert(equal(p.lowerBound(4), [0, 1, 2, 3]));\n    assert(equal(p.lowerBound(5), [0, 1, 2, 3, 4]));\n    assert(equal(p.lowerBound(6), [0, 1, 2, 3, 4, 5]));\n    assert(equal(p.lowerBound(6.9), [0, 1, 2, 3, 4, 5, 6]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    static assert(isRandomAccessRange!(SortedRange!(int[])));\n    int[] a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];\n    auto p = assumeSorted(a).upperBound(3);\n    assert(equal(p, [4, 4, 5, 6 ]));\n    p = assumeSorted(a).upperBound(4.2);\n    assert(equal(p, [ 5, 6 ]));\n\n    // Issue 18933 - don't create senselessly nested SortedRange types.\n    assert(is(typeof(assumeSorted(a)) == typeof(assumeSorted(assumeSorted(a)))));\n    assert(is(typeof(assumeSorted(a)) == typeof(assumeSorted(assumeSorted!\"a > b\"(a)))));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : text;\n\n    int[] a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];\n    auto p = assumeSorted(a).equalRange(3);\n    assert(equal(p, [ 3, 3, 3 ]), text(p));\n    p = assumeSorted(a).equalRange(4);\n    assert(equal(p, [ 4, 4 ]), text(p));\n    p = assumeSorted(a).equalRange(2);\n    assert(equal(p, [ 2 ]));\n    p = assumeSorted(a).equalRange(0);\n    assert(p.empty);\n    p = assumeSorted(a).equalRange(7);\n    assert(p.empty);\n    p = assumeSorted(a).equalRange(3.0);\n    assert(equal(p, [ 3, 3, 3]));\n}\n\n@safe unittest\n{\n    int[] a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];\n    if (a.length)\n    {\n        auto b = a[a.length / 2];\n        //auto r = sort(a);\n        //assert(r.contains(b));\n    }\n}\n\n@safe unittest\n{\n    auto a = [ 5, 7, 34, 345, 677 ];\n    auto r = assumeSorted(a);\n    a = null;\n    r = assumeSorted(a);\n    a = [ 1 ];\n    r = assumeSorted(a);\n}\n\n@system unittest\n{\n    bool ok = true;\n    try\n    {\n        auto r2 = assumeSorted([ 677, 345, 34, 7, 5 ]);\n        debug ok = false;\n    }\n    catch (Throwable)\n    {\n    }\n    assert(ok);\n}\n\n// issue 15003\n@nogc @safe unittest\n{\n    static immutable a = [1, 2, 3, 4];\n    auto r = a.assumeSorted;\n}\n\n/++\n    Wrapper which effectively makes it possible to pass a range by reference.\n    Both the original range and the RefRange will always have the exact same\n    elements. Any operation done on one will affect the other. So, for instance,\n    if it's passed to a function which would implicitly copy the original range\n    if it were passed to it, the original range is $(I not) copied but is\n    consumed as if it were a reference type.\n\n    Note:\n        `save` works as normal and operates on a new range, so if\n        `save` is ever called on the `RefRange`, then no operations on the\n        saved range will affect the original.\n\n    Params:\n        range = the range to construct the `RefRange` from\n\n    Returns:\n        A `RefRange`. If the given range is a class type\n        (and thus is already a reference type), then the original\n        range is returned rather than a `RefRange`.\n  +/\nstruct RefRange(R)\nif (isInputRange!R)\n{\npublic:\n\n    /++ +/\n    this(R* range) @safe pure nothrow\n    {\n        _range = range;\n    }\n\n\n    /++\n        This does not assign the pointer of `rhs` to this `RefRange`.\n        Rather it assigns the range pointed to by `rhs` to the range pointed\n        to by this `RefRange`. This is because $(I any) operation on a\n        `RefRange` is the same is if it occurred to the original range. The\n        one exception is when a `RefRange` is assigned `null` either\n        directly or because `rhs` is `null`. In that case, `RefRange`\n        no longer refers to the original range but is `null`.\n      +/\n    auto opAssign(RefRange rhs)\n    {\n        if (_range && rhs._range)\n            *_range = *rhs._range;\n        else\n            _range = rhs._range;\n\n        return this;\n    }\n\n    /++ +/\n    void opAssign(typeof(null) rhs)\n    {\n        _range = null;\n    }\n\n\n    /++\n        A pointer to the wrapped range.\n      +/\n    @property inout(R*) ptr() @safe inout pure nothrow\n    {\n        return _range;\n    }\n\n\n    version (StdDdoc)\n    {\n        /++ +/\n        @property auto front() {assert(0);}\n        /++ Ditto +/\n        @property auto front() const {assert(0);}\n        /++ Ditto +/\n        @property auto front(ElementType!R value) {assert(0);}\n    }\n    else\n    {\n        @property auto front()\n        {\n            return (*_range).front;\n        }\n\n        static if (is(typeof((*(cast(const R*)_range)).front))) @property auto front() const\n        {\n            return (*_range).front;\n        }\n\n        static if (is(typeof((*_range).front = (*_range).front))) @property auto front(ElementType!R value)\n        {\n            return (*_range).front = value;\n        }\n    }\n\n\n    version (StdDdoc)\n    {\n        @property bool empty(); ///\n        @property bool empty() const; ///Ditto\n    }\n    else static if (isInfinite!R)\n        enum empty = false;\n    else\n    {\n        @property bool empty()\n        {\n            return (*_range).empty;\n        }\n\n        static if (is(typeof((*cast(const R*)_range).empty))) @property bool empty() const\n        {\n            return (*_range).empty;\n        }\n    }\n\n\n    /++ +/\n    void popFront()\n    {\n        return (*_range).popFront();\n    }\n\n\n    version (StdDdoc)\n    {\n        /++\n            Only defined if `isForwardRange!R` is `true`.\n          +/\n        @property auto save() {assert(0);}\n        /++ Ditto +/\n        @property auto save() const {assert(0);}\n        /++ Ditto +/\n        auto opSlice() {assert(0);}\n        /++ Ditto +/\n        auto opSlice() const {assert(0);}\n    }\n    else static if (isForwardRange!R)\n    {\n        import std.traits : isSafe;\n        private alias S = typeof((*_range).save);\n\n        static if (is(typeof((*cast(const R*)_range).save)))\n            private alias CS = typeof((*cast(const R*)_range).save);\n\n        static if (isSafe!((R* r) => (*r).save))\n        {\n            @property RefRange!S save() @trusted\n            {\n                mixin(_genSave());\n            }\n\n            static if (is(typeof((*cast(const R*)_range).save))) @property RefRange!CS save() @trusted const\n            {\n                mixin(_genSave());\n            }\n        }\n        else\n        {\n            @property RefRange!S save()\n            {\n                mixin(_genSave());\n            }\n\n            static if (is(typeof((*cast(const R*)_range).save))) @property RefRange!CS save() const\n            {\n                mixin(_genSave());\n            }\n        }\n\n        auto opSlice()()\n        {\n            return save;\n        }\n\n        auto opSlice()() const\n        {\n            return save;\n        }\n\n        private static string _genSave() @safe pure nothrow\n        {\n            return `import std.conv : emplace;` ~\n                   `alias S = typeof((*_range).save);` ~\n                   `static assert(isForwardRange!S, S.stringof ~ \" is not a forward range.\");` ~\n                   `auto mem = new void[S.sizeof];` ~\n                   `emplace!S(mem, cast(S)(*_range).save);` ~\n                   `return RefRange!S(cast(S*) mem.ptr);`;\n        }\n\n        static assert(isForwardRange!RefRange);\n    }\n\n\n    version (StdDdoc)\n    {\n        /++\n            Only defined if `isBidirectionalRange!R` is `true`.\n          +/\n        @property auto back() {assert(0);}\n        /++ Ditto +/\n        @property auto back() const {assert(0);}\n        /++ Ditto +/\n        @property auto back(ElementType!R value) {assert(0);}\n    }\n    else static if (isBidirectionalRange!R)\n    {\n        @property auto back()\n        {\n            return (*_range).back;\n        }\n\n        static if (is(typeof((*(cast(const R*)_range)).back))) @property auto back() const\n        {\n            return (*_range).back;\n        }\n\n        static if (is(typeof((*_range).back = (*_range).back))) @property auto back(ElementType!R value)\n        {\n            return (*_range).back = value;\n        }\n    }\n\n\n    /++ Ditto +/\n    static if (isBidirectionalRange!R) void popBack()\n    {\n        return (*_range).popBack();\n    }\n\n\n    version (StdDdoc)\n    {\n        /++\n            Only defined if `isRandomAccesRange!R` is `true`.\n          +/\n        auto ref opIndex(IndexType)(IndexType index) {assert(0);}\n\n        /++ Ditto +/\n        auto ref opIndex(IndexType)(IndexType index) const {assert(0);}\n    }\n    else static if (isRandomAccessRange!R)\n    {\n        auto ref opIndex(IndexType)(IndexType index)\n            if (is(typeof((*_range)[index])))\n        {\n            return (*_range)[index];\n        }\n\n        auto ref opIndex(IndexType)(IndexType index) const\n            if (is(typeof((*cast(const R*)_range)[index])))\n        {\n            return (*_range)[index];\n        }\n    }\n\n\n    /++\n        Only defined if `hasMobileElements!R` and `isForwardRange!R` are\n        `true`.\n      +/\n    static if (hasMobileElements!R && isForwardRange!R) auto moveFront()\n    {\n        return (*_range).moveFront();\n    }\n\n\n    /++\n        Only defined if `hasMobileElements!R` and `isBidirectionalRange!R`\n        are `true`.\n      +/\n    static if (hasMobileElements!R && isBidirectionalRange!R) auto moveBack()\n    {\n        return (*_range).moveBack();\n    }\n\n\n    /++\n        Only defined if `hasMobileElements!R` and `isRandomAccessRange!R`\n        are `true`.\n      +/\n    static if (hasMobileElements!R && isRandomAccessRange!R) auto moveAt(size_t index)\n    {\n        return (*_range).moveAt(index);\n    }\n\n\n    version (StdDdoc)\n    {\n        /++\n            Only defined if `hasLength!R` is `true`.\n          +/\n        @property auto length() {assert(0);}\n\n        /++ Ditto +/\n        @property auto length() const {assert(0);}\n\n        /++ Ditto +/\n        alias opDollar = length;\n    }\n    else static if (hasLength!R)\n    {\n        @property auto length()\n        {\n            return (*_range).length;\n        }\n\n        static if (is(typeof((*cast(const R*)_range).length))) @property auto length() const\n        {\n            return (*_range).length;\n        }\n\n        alias opDollar = length;\n    }\n\n\n    version (StdDdoc)\n    {\n        /++\n            Only defined if `hasSlicing!R` is `true`.\n          +/\n        auto opSlice(IndexType1, IndexType2)\n                    (IndexType1 begin, IndexType2 end) {assert(0);}\n\n        /++ Ditto +/\n        auto opSlice(IndexType1, IndexType2)\n                    (IndexType1 begin, IndexType2 end) const {assert(0);}\n    }\n    else static if (hasSlicing!R)\n    {\n        private alias T = typeof((*_range)[1 .. 2]);\n        static if (is(typeof((*cast(const R*)_range)[1 .. 2])))\n        {\n            private alias CT = typeof((*cast(const R*)_range)[1 .. 2]);\n        }\n\n        RefRange!T opSlice(IndexType1, IndexType2)\n                    (IndexType1 begin, IndexType2 end)\n            if (is(typeof((*_range)[begin .. end])))\n        {\n            mixin(_genOpSlice());\n        }\n\n        RefRange!CT opSlice(IndexType1, IndexType2)\n                    (IndexType1 begin, IndexType2 end) const\n            if (is(typeof((*cast(const R*)_range)[begin .. end])))\n        {\n            mixin(_genOpSlice());\n        }\n\n        private static string _genOpSlice() @safe pure nothrow\n        {\n            return `import std.conv : emplace;` ~\n                   `alias S = typeof((*_range)[begin .. end]);` ~\n                   `static assert(hasSlicing!S, S.stringof ~ \" is not sliceable.\");` ~\n                   `auto mem = new void[S.sizeof];` ~\n                   `emplace!S(mem, cast(S)(*_range)[begin .. end]);` ~\n                   `return RefRange!S(cast(S*) mem.ptr);`;\n        }\n    }\n\n\nprivate:\n\n    R* _range;\n}\n\n/// Basic Example\n@system unittest\n{\n    import std.algorithm.searching : find;\n    ubyte[] buffer = [1, 9, 45, 12, 22];\n    auto found1 = find(buffer, 45);\n    assert(found1 == [45, 12, 22]);\n    assert(buffer == [1, 9, 45, 12, 22]);\n\n    auto wrapped1 = refRange(&buffer);\n    auto found2 = find(wrapped1, 45);\n    assert(*found2.ptr == [45, 12, 22]);\n    assert(buffer == [45, 12, 22]);\n\n    auto found3 = find(wrapped1.save, 22);\n    assert(*found3.ptr == [22]);\n    assert(buffer == [45, 12, 22]);\n\n    string str = \"hello world\";\n    auto wrappedStr = refRange(&str);\n    assert(str.front == 'h');\n    str.popFrontN(5);\n    assert(str == \" world\");\n    assert(wrappedStr.front == ' ');\n    assert(*wrappedStr.ptr == \" world\");\n}\n\n/// opAssign Example.\n@system unittest\n{\n    ubyte[] buffer1 = [1, 2, 3, 4, 5];\n    ubyte[] buffer2 = [6, 7, 8, 9, 10];\n    auto wrapped1 = refRange(&buffer1);\n    auto wrapped2 = refRange(&buffer2);\n    assert(wrapped1.ptr is &buffer1);\n    assert(wrapped2.ptr is &buffer2);\n    assert(wrapped1.ptr !is wrapped2.ptr);\n    assert(buffer1 != buffer2);\n\n    wrapped1 = wrapped2;\n\n    //Everything points to the same stuff as before.\n    assert(wrapped1.ptr is &buffer1);\n    assert(wrapped2.ptr is &buffer2);\n    assert(wrapped1.ptr !is wrapped2.ptr);\n\n    //But buffer1 has changed due to the assignment.\n    assert(buffer1 == [6, 7, 8, 9, 10]);\n    assert(buffer2 == [6, 7, 8, 9, 10]);\n\n    buffer2 = [11, 12, 13, 14, 15];\n\n    //Everything points to the same stuff as before.\n    assert(wrapped1.ptr is &buffer1);\n    assert(wrapped2.ptr is &buffer2);\n    assert(wrapped1.ptr !is wrapped2.ptr);\n\n    //But buffer2 has changed due to the assignment.\n    assert(buffer1 == [6, 7, 8, 9, 10]);\n    assert(buffer2 == [11, 12, 13, 14, 15]);\n\n    wrapped2 = null;\n\n    //The pointer changed for wrapped2 but not wrapped1.\n    assert(wrapped1.ptr is &buffer1);\n    assert(wrapped2.ptr is null);\n    assert(wrapped1.ptr !is wrapped2.ptr);\n\n    //buffer2 is not affected by the assignment.\n    assert(buffer1 == [6, 7, 8, 9, 10]);\n    assert(buffer2 == [11, 12, 13, 14, 15]);\n}\n\n@system unittest\n{\n    import std.algorithm.iteration : filter;\n    {\n        ubyte[] buffer = [1, 2, 3, 4, 5];\n        auto wrapper = refRange(&buffer);\n        auto p = wrapper.ptr;\n        auto f = wrapper.front;\n        wrapper.front = f;\n        auto e = wrapper.empty;\n        wrapper.popFront();\n        auto s = wrapper.save;\n        auto b = wrapper.back;\n        wrapper.back = b;\n        wrapper.popBack();\n        auto i = wrapper[0];\n        wrapper.moveFront();\n        wrapper.moveBack();\n        wrapper.moveAt(0);\n        auto l = wrapper.length;\n        auto sl = wrapper[0 .. 1];\n        assert(wrapper[0 .. $].length == buffer[0 .. $].length);\n    }\n\n    {\n        ubyte[] buffer = [1, 2, 3, 4, 5];\n        const wrapper = refRange(&buffer);\n        const p = wrapper.ptr;\n        const f = wrapper.front;\n        const e = wrapper.empty;\n        const s = wrapper.save;\n        const b = wrapper.back;\n        const i = wrapper[0];\n        const l = wrapper.length;\n        const sl = wrapper[0 .. 1];\n    }\n\n    {\n        ubyte[] buffer = [1, 2, 3, 4, 5];\n        auto filtered = filter!\"true\"(buffer);\n        auto wrapper = refRange(&filtered);\n        auto p = wrapper.ptr;\n        auto f = wrapper.front;\n        wrapper.front = f;\n        auto e = wrapper.empty;\n        wrapper.popFront();\n        auto s = wrapper.save;\n        wrapper.moveFront();\n    }\n\n    {\n        ubyte[] buffer = [1, 2, 3, 4, 5];\n        auto filtered = filter!\"true\"(buffer);\n        const wrapper = refRange(&filtered);\n        const p = wrapper.ptr;\n\n        //Cannot currently be const. filter needs to be updated to handle const.\n        /+\n        const f = wrapper.front;\n        const e = wrapper.empty;\n        const s = wrapper.save;\n        +/\n    }\n\n    {\n        string str = \"hello world\";\n        auto wrapper = refRange(&str);\n        auto p = wrapper.ptr;\n        auto f = wrapper.front;\n        auto e = wrapper.empty;\n        wrapper.popFront();\n        auto s = wrapper.save;\n        auto b = wrapper.back;\n        wrapper.popBack();\n    }\n\n    {\n        // Issue 16534 - opDollar should be defined if the\n        // wrapped range defines length.\n        auto range = 10.iota.takeExactly(5);\n        auto wrapper = refRange(&range);\n        assert(wrapper.length == 5);\n        assert(wrapper[0 .. $ - 1].length == 4);\n    }\n}\n\n//Test assignment.\n@system unittest\n{\n    ubyte[] buffer1 = [1, 2, 3, 4, 5];\n    ubyte[] buffer2 = [6, 7, 8, 9, 10];\n    RefRange!(ubyte[]) wrapper1;\n    RefRange!(ubyte[]) wrapper2 = refRange(&buffer2);\n    assert(wrapper1.ptr is null);\n    assert(wrapper2.ptr is &buffer2);\n\n    wrapper1 = refRange(&buffer1);\n    assert(wrapper1.ptr is &buffer1);\n\n    wrapper1 = wrapper2;\n    assert(wrapper1.ptr is &buffer1);\n    assert(buffer1 == buffer2);\n\n    wrapper1 = RefRange!(ubyte[]).init;\n    assert(wrapper1.ptr is null);\n    assert(wrapper2.ptr is &buffer2);\n    assert(buffer1 == buffer2);\n    assert(buffer1 == [6, 7, 8, 9, 10]);\n\n    wrapper2 = null;\n    assert(wrapper2.ptr is null);\n    assert(buffer2 == [6, 7, 8, 9, 10]);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.mutation : bringToFront;\n    import std.algorithm.searching : commonPrefix, find, until;\n    import std.algorithm.sorting : sort;\n\n    //Test that ranges are properly consumed.\n    {\n        int[] arr = [1, 42, 2, 41, 3, 40, 4, 42, 9];\n        auto wrapper = refRange(&arr);\n\n        assert(*find(wrapper, 41).ptr == [41, 3, 40, 4, 42, 9]);\n        assert(arr == [41, 3, 40, 4, 42, 9]);\n\n        assert(*drop(wrapper, 2).ptr == [40, 4, 42, 9]);\n        assert(arr == [40, 4, 42, 9]);\n\n        assert(equal(until(wrapper, 42), [40, 4]));\n        assert(arr == [42, 9]);\n\n        assert(find(wrapper, 12).empty);\n        assert(arr.empty);\n    }\n\n    {\n        string str = \"Hello, world-like object.\";\n        auto wrapper = refRange(&str);\n\n        assert(*find(wrapper, \"l\").ptr == \"llo, world-like object.\");\n        assert(str == \"llo, world-like object.\");\n\n        assert(equal(take(wrapper, 5), \"llo, \"));\n        assert(str == \"world-like object.\");\n    }\n\n    //Test that operating on saved ranges does not consume the original.\n    {\n        int[] arr = [1, 42, 2, 41, 3, 40, 4, 42, 9];\n        auto wrapper = refRange(&arr);\n        auto saved = wrapper.save;\n        saved.popFrontN(3);\n        assert(*saved.ptr == [41, 3, 40, 4, 42, 9]);\n        assert(arr == [1, 42, 2, 41, 3, 40, 4, 42, 9]);\n    }\n\n    {\n        string str = \"Hello, world-like object.\";\n        auto wrapper = refRange(&str);\n        auto saved = wrapper.save;\n        saved.popFrontN(13);\n        assert(*saved.ptr == \"like object.\");\n        assert(str == \"Hello, world-like object.\");\n    }\n\n    //Test that functions which use save work properly.\n    {\n        int[] arr = [1, 42];\n        auto wrapper = refRange(&arr);\n        assert(equal(commonPrefix(wrapper, [1, 27]), [1]));\n    }\n\n    {\n        int[] arr = [4, 5, 6, 7, 1, 2, 3];\n        auto wrapper = refRange(&arr);\n        assert(bringToFront(wrapper[0 .. 4], wrapper[4 .. arr.length]) == 3);\n        assert(arr == [1, 2, 3, 4, 5, 6, 7]);\n    }\n\n    //Test bidirectional functions.\n    {\n        int[] arr = [1, 42, 2, 41, 3, 40, 4, 42, 9];\n        auto wrapper = refRange(&arr);\n\n        assert(wrapper.back == 9);\n        assert(arr == [1, 42, 2, 41, 3, 40, 4, 42, 9]);\n\n        wrapper.popBack();\n        assert(arr == [1, 42, 2, 41, 3, 40, 4, 42]);\n    }\n\n    {\n        string str = \"Hello, world-like object.\";\n        auto wrapper = refRange(&str);\n\n        assert(wrapper.back == '.');\n        assert(str == \"Hello, world-like object.\");\n\n        wrapper.popBack();\n        assert(str == \"Hello, world-like object\");\n    }\n\n    //Test random access functions.\n    {\n        int[] arr = [1, 42, 2, 41, 3, 40, 4, 42, 9];\n        auto wrapper = refRange(&arr);\n\n        assert(wrapper[2] == 2);\n        assert(arr == [1, 42, 2, 41, 3, 40, 4, 42, 9]);\n\n        assert(*wrapper[3 .. 6].ptr != null, [41, 3, 40]);\n        assert(arr == [1, 42, 2, 41, 3, 40, 4, 42, 9]);\n    }\n\n    //Test move functions.\n    {\n        int[] arr = [1, 42, 2, 41, 3, 40, 4, 42, 9];\n        auto wrapper = refRange(&arr);\n\n        auto t1 = wrapper.moveFront();\n        auto t2 = wrapper.moveBack();\n        wrapper.front = t2;\n        wrapper.back = t1;\n        assert(arr == [9, 42, 2, 41, 3, 40, 4, 42, 1]);\n\n        sort(wrapper.save);\n        assert(arr == [1, 2, 3, 4, 9, 40, 41, 42, 42]);\n    }\n}\n\n@system unittest\n{\n    struct S\n    {\n        @property int front() @safe const pure nothrow { return 0; }\n        enum bool empty = false;\n        void popFront() @safe pure nothrow { }\n        @property auto save() @safe pure nothrow { return this; }\n    }\n\n    S s;\n    auto wrapper = refRange(&s);\n    static assert(isInfinite!(typeof(wrapper)));\n}\n\n@system unittest\n{\n    class C\n    {\n        @property int front() @safe const pure nothrow { return 0; }\n        @property bool empty() @safe const pure nothrow { return false; }\n        void popFront() @safe pure nothrow { }\n        @property auto save() @safe pure nothrow { return this; }\n    }\n    static assert(isForwardRange!C);\n\n    auto c = new C;\n    auto cWrapper = refRange(&c);\n    static assert(is(typeof(cWrapper) == C));\n    assert(cWrapper is c);\n}\n\n@system unittest // issue 14373\n{\n    static struct R\n    {\n        @property int front() {return 0;}\n        void popFront() {empty = true;}\n        bool empty = false;\n    }\n    R r;\n    refRange(&r).popFront();\n    assert(r.empty);\n}\n\n@system unittest // issue 14575\n{\n    struct R\n    {\n        Object front;\n        alias back = front;\n        bool empty = false;\n        void popFront() {empty = true;}\n        alias popBack = popFront;\n        @property R save() {return this;}\n    }\n    static assert(isBidirectionalRange!R);\n    R r;\n    auto rr = refRange(&r);\n\n    struct R2\n    {\n        @property Object front() {return null;}\n        @property const(Object) front() const {return null;}\n        alias back = front;\n        bool empty = false;\n        void popFront() {empty = true;}\n        alias popBack = popFront;\n        @property R2 save() {return this;}\n    }\n    static assert(isBidirectionalRange!R2);\n    R2 r2;\n    auto rr2 = refRange(&r2);\n}\n\n/// ditto\nauto refRange(R)(R* range)\nif (isInputRange!R)\n{\n    static if (!is(R == class))\n        return RefRange!R(range);\n    else\n        return *range;\n}\n\n/*****************************************************************************/\n\n@safe unittest    // bug 9060\n{\n    import std.algorithm.iteration : map, joiner, group;\n    import std.algorithm.searching : until;\n    // fix for std.algorithm\n    auto r = map!(x => 0)([1]);\n    chain(r, r);\n    zip(r, r);\n    roundRobin(r, r);\n\n    struct NRAR {\n        typeof(r) input;\n        @property empty() { return input.empty; }\n        @property front() { return input.front; }\n        void popFront()   { input.popFront(); }\n        @property save()  { return NRAR(input.save); }\n    }\n    auto n1 = NRAR(r);\n    cycle(n1);  // non random access range version\n\n    assumeSorted(r);\n\n    // fix for std.range\n    joiner([r], [9]);\n\n    struct NRAR2 {\n        NRAR input;\n        @property empty() { return true; }\n        @property front() { return input; }\n        void popFront() { }\n        @property save()  { return NRAR2(input.save); }\n    }\n    auto n2 = NRAR2(n1);\n    joiner(n2);\n\n    group(r);\n\n    until(r, 7);\n    static void foo(R)(R r) { until!(x => x > 7)(r); }\n    foo(r);\n}\n\nprivate struct Bitwise(R)\nif (isInputRange!R && isIntegral!(ElementType!R))\n{\nprivate:\n    alias ElemType = ElementType!R;\n    alias UnsignedElemType = Unsigned!ElemType;\n\n    R parent;\n    enum bitsNum = ElemType.sizeof * 8;\n    size_t maskPos = 1;\n\n    static if (isBidirectionalRange!R)\n    {\n        size_t backMaskPos = bitsNum;\n    }\n\npublic:\n    this()(auto ref R range)\n    {\n        parent = range;\n    }\n\n    static if (isInfinite!R)\n    {\n        enum empty = false;\n    }\n    else\n    {\n        /**\n         * Check if the range is empty\n         *\n         * Returns: a boolean true or false\n         */\n        bool empty()\n        {\n            static if (hasLength!R)\n            {\n                return length == 0;\n            }\n            else static if (isBidirectionalRange!R)\n            {\n                if (parent.empty)\n                {\n                    return true;\n                }\n                else\n                {\n                    /*\n                       If we have consumed the last element of the range both from\n                       the front and the back, then the masks positions will overlap\n                     */\n                    return parent.save.dropOne.empty && (maskPos > backMaskPos);\n                }\n            }\n            else\n            {\n                /*\n                   If we consumed the last element of the range, but not all the\n                   bits in the last element\n                 */\n                return parent.empty;\n            }\n        }\n    }\n\n    bool front()\n    {\n        assert(!empty);\n        return (parent.front & mask(maskPos)) != 0;\n    }\n\n    void popFront()\n    {\n        assert(!empty);\n        ++maskPos;\n        if (maskPos > bitsNum)\n        {\n            parent.popFront;\n            maskPos = 1;\n        }\n    }\n\n    static if (hasLength!R)\n    {\n        size_t length()\n        {\n            auto len = parent.length * bitsNum - (maskPos - 1);\n            static if (isBidirectionalRange!R)\n            {\n                len -= bitsNum - backMaskPos;\n            }\n            return len;\n        }\n\n        alias opDollar = length;\n    }\n\n    static if (isForwardRange!R)\n    {\n        typeof(this) save()\n        {\n            auto result = this;\n            result.parent = parent.save;\n            return result;\n        }\n    }\n\n    static if (isBidirectionalRange!R)\n    {\n        bool back()\n        {\n            assert(!empty);\n            return (parent.back & mask(backMaskPos)) != 0;\n        }\n\n        void popBack()\n        {\n            assert(!empty);\n            --backMaskPos;\n            if (backMaskPos == 0)\n            {\n                parent.popBack;\n                backMaskPos = bitsNum;\n            }\n        }\n    }\n\n    static if (isRandomAccessRange!R)\n    {\n        /**\n          Return the `n`th bit within the range\n         */\n        bool opIndex(size_t n)\n        in\n        {\n            /*\n               If it does not have the length property, it means that R is\n               an infinite range\n             */\n            static if (hasLength!R)\n            {\n                assert(n < length, \"Index out of bounds\");\n            }\n        }\n        do\n        {\n            immutable size_t remainingBits = bitsNum - maskPos + 1;\n            // If n >= maskPos, then the bit sign will be 1, otherwise 0\n            immutable sizediff_t sign = (remainingBits - n - 1) >> (sizediff_t.sizeof * 8 - 1);\n            /*\n               By truncating n with remainingBits bits we have skipped the\n               remaining bits in parent[0], so we need to add 1 to elemIndex.\n\n               Because bitsNum is a power of 2, n / bitsNum == n >> bitsNum.bsf\n             */\n            import core.bitop : bsf;\n            immutable size_t elemIndex = sign * (((n - remainingBits) >> bitsNum.bsf) + 1);\n\n            /*\n               Since the indexing is from LSB to MSB, we need to index at the\n               remainder of (n - remainingBits).\n\n               Because bitsNum is a power of 2, n % bitsNum == n & (bitsNum - 1)\n             */\n            immutable size_t elemMaskPos = (sign ^ 1) * (maskPos + n)\n                             + sign * (1 + ((n - remainingBits) & (bitsNum - 1)));\n\n            return (parent[elemIndex] & mask(elemMaskPos)) != 0;\n        }\n\n        static if (hasAssignableElements!R)\n        {\n            /**\n              Assigns `flag` to the `n`th bit within the range\n             */\n            void opIndexAssign(bool flag, size_t n)\n                in\n                {\n                    static if (hasLength!R)\n                    {\n                        assert(n < length, \"Index out of bounds\");\n                    }\n                }\n            do\n            {\n                import core.bitop : bsf;\n\n                immutable size_t remainingBits = bitsNum - maskPos + 1;\n                immutable sizediff_t sign = (remainingBits - n - 1) >> (sizediff_t.sizeof * 8 - 1);\n                immutable size_t elemIndex = sign * (((n - remainingBits) >> bitsNum.bsf) + 1);\n                immutable size_t elemMaskPos = (sign ^ 1) * (maskPos + n)\n                    + sign * (1 + ((n - remainingBits) & (bitsNum - 1)));\n\n                auto elem = parent[elemIndex];\n                auto elemMask = mask(elemMaskPos);\n                parent[elemIndex] = cast(UnsignedElemType)(flag * (elem | elemMask)\n                        + (flag ^ 1) * (elem & ~elemMask));\n            }\n        }\n\n        Bitwise!R opSlice()\n        {\n            return this.save;\n        }\n\n        Bitwise!R opSlice(size_t start, size_t end)\n        in\n        {\n            assert(start < end, \"Invalid bounds: end <= start\");\n        }\n        do\n        {\n            import core.bitop : bsf;\n\n            size_t remainingBits = bitsNum - maskPos + 1;\n            sizediff_t sign = (remainingBits - start - 1) >> (sizediff_t.sizeof * 8 - 1);\n            immutable size_t startElemIndex = sign * (((start - remainingBits) >> bitsNum.bsf) + 1);\n            immutable size_t startElemMaskPos = (sign ^ 1) * (maskPos + start)\n                                              + sign * (1 + ((start - remainingBits) & (bitsNum - 1)));\n\n            immutable size_t sliceLen = end - start - 1;\n            remainingBits = bitsNum - startElemMaskPos + 1;\n            sign = (remainingBits - sliceLen - 1) >> (sizediff_t.sizeof * 8 - 1);\n            immutable size_t endElemIndex = startElemIndex\n                                          + sign * (((sliceLen - remainingBits) >> bitsNum.bsf) + 1);\n            immutable size_t endElemMaskPos = (sign ^ 1) * (startElemMaskPos + sliceLen)\n                                            + sign * (1 + ((sliceLen - remainingBits) & (bitsNum - 1)));\n\n            typeof(return) result;\n            // Get the slice to be returned from the parent\n            result.parent = (parent[startElemIndex .. endElemIndex + 1]).save;\n            result.maskPos = startElemMaskPos;\n            static if (isBidirectionalRange!R)\n            {\n                result.backMaskPos = endElemMaskPos;\n            }\n            return result;\n        }\n    }\n\nprivate:\n    auto mask(size_t maskPos)\n    {\n        return (1UL << (maskPos - 1UL));\n    }\n}\n\n/**\nBitwise adapter over an integral type range. Consumes the range elements bit by\nbit, from the least significant bit to the most significant bit.\n\nParams:\n    R = an integral $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to iterate over\n    range = range to consume bit by by\n\nReturns:\n    A `Bitwise` input range with propagated forward, bidirectional\n    and random access capabilities\n*/\nauto bitwise(R)(auto ref R range)\nif (isInputRange!R && isIntegral!(ElementType!R))\n{\n    return Bitwise!R(range);\n}\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.format : format;\n\n    // 00000011 00001001\n    ubyte[] arr = [3, 9];\n    auto r = arr.bitwise;\n\n    // iterate through it as with any other range\n    assert(format(\"%(%d%)\", r) == \"1100000010010000\");\n    assert(format(\"%(%d%)\", r.retro).equal(\"1100000010010000\".retro));\n\n    auto r2 = r[5 .. $];\n    // set a bit\n    r[2] = 1;\n    assert(arr[0] == 7);\n    assert(r[5] == r2[0]);\n}\n\n/// You can use bitwise to implement an uniform bool generator\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.random : rndGen;\n\n    auto rb = rndGen.bitwise;\n    static assert(isInfinite!(typeof(rb)));\n\n    auto rb2 = rndGen.bitwise;\n    // Don't forget that structs are passed by value\n    assert(rb.take(10).equal(rb2.take(10)));\n}\n\n// Test nogc inference\n@safe @nogc unittest\n{\n    static ubyte[] arr = [3, 9];\n    auto bw = arr.bitwise;\n    auto bw2 = bw[];\n    auto bw3 = bw[8 .. $];\n    bw3[2] = true;\n\n    assert(arr[1] == 13);\n    assert(bw[$ - 6]);\n    assert(bw[$ - 6] == bw2[$ - 6]);\n    assert(bw[$ - 6] == bw3[$ - 6]);\n}\n\n// Test all range types over all integral types\n@safe pure nothrow unittest\n{\n    import std.internal.test.dummyrange;\n\n    alias IntegralTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint,\n            long, ulong);\n    foreach (IntegralType; IntegralTypes)\n    {\n        foreach (T; AllDummyRangesType!(IntegralType[]))\n        {\n            T a;\n            auto bw = Bitwise!T(a);\n\n            static if (isForwardRange!T)\n            {\n                auto bwFwdSave = bw.save;\n            }\n\n            static if (isBidirectionalRange!T)\n            {\n                auto bwBack = bw.save;\n                auto bwBackSave = bw.save;\n            }\n\n            static if (hasLength!T)\n            {\n                auto bwLength = bw.length;\n                assert(bw.length == (IntegralType.sizeof * 8 * a.length));\n                static if (isForwardRange!T)\n                {\n                    assert(bw.length == bwFwdSave.length);\n                }\n            }\n\n            // Make sure front and back are not the mechanisms that modify the range\n            long numCalls = 42;\n            bool initialFrontValue;\n\n            if (!bw.empty)\n            {\n                initialFrontValue = bw.front;\n            }\n\n            while (!bw.empty && (--numCalls))\n            {\n                bw.front;\n                assert(bw.front == initialFrontValue);\n            }\n\n            /*\n               Check that empty works properly and that popFront does not get called\n               more times than it should\n             */\n            numCalls = 0;\n            while (!bw.empty)\n            {\n                ++numCalls;\n\n                static if (hasLength!T)\n                {\n                    assert(bw.length == bwLength);\n                    --bwLength;\n                }\n\n                static if (isForwardRange!T)\n                {\n                    assert(bw.front == bwFwdSave.front);\n                    bwFwdSave.popFront();\n                }\n\n                static if (isBidirectionalRange!T)\n                {\n                    assert(bwBack.front == bwBackSave.front);\n                    bwBack.popBack();\n                    bwBackSave.popBack();\n                }\n                bw.popFront();\n            }\n\n            auto rangeLen = numCalls / (IntegralType.sizeof * 8);\n            assert(numCalls == (IntegralType.sizeof * 8 * rangeLen));\n            assert(bw.empty);\n            static if (isForwardRange!T)\n            {\n                assert(bwFwdSave.empty);\n            }\n\n            static if (isBidirectionalRange!T)\n            {\n                assert(bwBack.empty);\n            }\n        }\n    }\n}\n\n// Test opIndex and opSlice\n@system unittest\n{\n    alias IntegralTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint,\n            long, ulong);\n    foreach (IntegralType; IntegralTypes)\n    {\n        size_t bitsNum = IntegralType.sizeof * 8;\n\n        auto first = cast(IntegralType)(1);\n\n        // 2 ^ (bitsNum - 1)\n        auto second = cast(IntegralType)(cast(IntegralType)(1) << (bitsNum - 2));\n\n        IntegralType[] a = [first, second];\n        auto bw = Bitwise!(IntegralType[])(a);\n\n        // Check against lsb of a[0]\n        assert(bw[0] == true);\n        // Check against msb - 1 of a[1]\n        assert(bw[2 * bitsNum - 2] == true);\n\n        bw.popFront();\n        assert(bw[2 * bitsNum - 3] == true);\n\n        import std.exception : assertThrown;\n\n        // Check out of bounds error\n        assertThrown!Error(bw[2 * bitsNum - 1]);\n\n        bw[2] = true;\n        assert(bw[2] == true);\n        bw.popFront();\n        assert(bw[1] == true);\n\n        auto bw2 = bw[0 .. $ - 5];\n        auto bw3 = bw2[];\n        assert(bw2.length == (bw.length - 5));\n        assert(bw2.length == bw3.length);\n        bw2.popFront();\n        assert(bw2.length != bw3.length);\n    }\n}\n\n/*********************************\n * An OutputRange that discards the data it receives.\n */\nstruct NullSink\n{\n    void put(E)(scope const E) pure @safe @nogc nothrow {}\n}\n\n/// ditto\nauto ref nullSink()\n{\n    static NullSink sink;\n    return sink;\n}\n\n///\n@safe nothrow unittest\n{\n    import std.algorithm.iteration : map;\n    import std.algorithm.mutation : copy;\n    [4, 5, 6].map!(x => x * 2).copy(nullSink); // data is discarded\n}\n\n///\n@safe unittest\n{\n    import std.csv : csvNextToken;\n\n    string line = \"a,b,c\";\n\n    // ignore the first column\n    line.csvNextToken(nullSink, ',', '\"');\n    line.popFront;\n\n    // look at the second column\n    Appender!string app;\n    line.csvNextToken(app, ',', '\"');\n    assert(app.data == \"b\");\n}\n\n@safe unittest\n{\n    auto r = 10.iota\n                .tee(nullSink)\n                .dropOne;\n\n    assert(r.front == 1);\n}\n\n/++\n\n  Implements a \"tee\" style pipe, wrapping an input range so that elements of the\n  range can be passed to a provided function or $(LREF OutputRange) as they are\n  iterated over. This is useful for printing out intermediate values in a long\n  chain of range code, performing some operation with side-effects on each call\n  to `front` or `popFront`, or diverting the elements of a range into an\n  auxiliary $(LREF OutputRange).\n\n  It is important to note that as the resultant range is evaluated lazily,\n  in the case of the version of `tee` that takes a function, the function\n  will not actually be executed until the range is \"walked\" using functions\n  that evaluate ranges, such as $(REF array, std,array) or\n  $(REF fold, std,algorithm,iteration).\n\n  Params:\n  pipeOnPop = If `Yes.pipeOnPop`, simply iterating the range without ever\n  calling `front` is enough to have `tee` mirror elements to `outputRange` (or,\n  respectively, `fun`). If `No.pipeOnPop`, only elements for which `front` does\n  get called will be also sent to `outputRange`/`fun`.\n  inputRange = The input range being passed through.\n  outputRange = This range will receive elements of `inputRange` progressively\n  as iteration proceeds.\n  fun = This function will be called with elements of `inputRange`\n  progressively as iteration proceeds.\n\n  Returns:\n  An input range that offers the elements of `inputRange`. Regardless of\n  whether `inputRange` is a more powerful range (forward, bidirectional etc),\n  the result is always an input range. Reading this causes `inputRange` to be\n  iterated and returns its elements in turn. In addition, the same elements\n  will be passed to `outputRange` or `fun` as well.\n\n  See_Also: $(REF each, std,algorithm,iteration)\n+/\nauto tee(Flag!\"pipeOnPop\" pipeOnPop = Yes.pipeOnPop, R1, R2)(R1 inputRange, R2 outputRange)\nif (isInputRange!R1 && isOutputRange!(R2, ElementType!R1))\n{\n    static struct Result\n    {\n        private R1 _input;\n        private R2 _output;\n        static if (!pipeOnPop)\n        {\n            private bool _frontAccessed;\n        }\n\n        static if (hasLength!R1)\n        {\n            @property auto length()\n            {\n                return _input.length;\n            }\n        }\n\n        static if (isInfinite!R1)\n        {\n            enum bool empty = false;\n        }\n        else\n        {\n            @property bool empty() { return _input.empty; }\n        }\n\n        void popFront()\n        {\n            assert(!_input.empty, \"Attempting to popFront an empty tee\");\n            static if (pipeOnPop)\n            {\n                put(_output, _input.front);\n            }\n            else\n            {\n                _frontAccessed = false;\n            }\n            _input.popFront();\n        }\n\n        @property auto ref front()\n        {\n            assert(!_input.empty, \"Attempting to fetch the front of an empty tee\");\n            static if (!pipeOnPop)\n            {\n                if (!_frontAccessed)\n                {\n                    _frontAccessed = true;\n                    put(_output, _input.front);\n                }\n            }\n            return _input.front;\n        }\n    }\n\n    return Result(inputRange, outputRange);\n}\n\n/// Ditto\nauto tee(alias fun, Flag!\"pipeOnPop\" pipeOnPop = Yes.pipeOnPop, R1)(R1 inputRange)\nif (is(typeof(fun) == void) || isSomeFunction!fun)\n{\n    import std.traits : isDelegate, isFunctionPointer;\n    /*\n        Distinguish between function literals and template lambdas\n        when using either as an $(LREF OutputRange). Since a template\n        has no type, typeof(template) will always return void.\n        If it's a template lambda, it's first necessary to instantiate\n        it with `ElementType!R1`.\n    */\n    static if (is(typeof(fun) == void))\n        alias _fun = fun!(ElementType!R1);\n    else\n        alias _fun = fun;\n\n    static if (isFunctionPointer!_fun || isDelegate!_fun)\n    {\n        return tee!pipeOnPop(inputRange, _fun);\n    }\n    else\n    {\n        return tee!pipeOnPop(inputRange, &_fun);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter, map;\n\n    // Sum values while copying\n    int[] values = [1, 4, 9, 16, 25];\n    int sum = 0;\n    auto newValues = values.tee!(a => sum += a).array;\n    assert(equal(newValues, values));\n    assert(sum == 1 + 4 + 9 + 16 + 25);\n\n    // Count values that pass the first filter\n    int count = 0;\n    auto newValues4 = values.filter!(a => a < 10)\n                            .tee!(a => count++)\n                            .map!(a => a + 1)\n                            .filter!(a => a < 10);\n\n    //Fine, equal also evaluates any lazy ranges passed to it.\n    //count is not 3 until equal evaluates newValues4\n    assert(equal(newValues4, [2, 5]));\n    assert(count == 3);\n}\n\n//\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter, map;\n\n    int[] values = [1, 4, 9, 16, 25];\n\n    int count = 0;\n    auto newValues = values.filter!(a => a < 10)\n        .tee!(a => count++, No.pipeOnPop)\n        .map!(a => a + 1)\n        .filter!(a => a < 10);\n\n    auto val = newValues.front;\n    assert(count == 1);\n    //front is only evaluated once per element\n    val = newValues.front;\n    assert(count == 1);\n\n    //popFront() called, fun will be called\n    //again on the next access to front\n    newValues.popFront();\n    newValues.front;\n    assert(count == 2);\n\n    int[] preMap = new int[](3), postMap = [];\n    auto mappedValues = values.filter!(a => a < 10)\n        //Note the two different ways of using tee\n        .tee(preMap)\n        .map!(a => a + 1)\n        .tee!(a => postMap ~= a)\n        .filter!(a => a < 10);\n    assert(equal(mappedValues, [2, 5]));\n    assert(equal(preMap, [1, 4, 9]));\n    assert(equal(postMap, [2, 5, 10]));\n}\n\n//\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter, map;\n\n    char[] txt = \"Line one, Line 2\".dup;\n\n    bool isVowel(dchar c)\n    {\n        import std.string : indexOf;\n        return \"AaEeIiOoUu\".indexOf(c) != -1;\n    }\n\n    int vowelCount = 0;\n    int shiftedCount = 0;\n    auto removeVowels = txt.tee!(c => isVowel(c) ? vowelCount++ : 0)\n                                .filter!(c => !isVowel(c))\n                                .map!(c => (c == ' ') ? c : c + 1)\n                                .tee!(c => isVowel(c) ? shiftedCount++ : 0);\n    assert(equal(removeVowels, \"Mo o- Mo 3\"));\n    assert(vowelCount == 6);\n    assert(shiftedCount == 3);\n}\n\n@safe unittest\n{\n    // Manually stride to test different pipe behavior.\n    void testRange(Range)(Range r)\n    {\n        const int strideLen = 3;\n        int i = 0;\n        ElementType!Range elem1;\n        ElementType!Range elem2;\n        while (!r.empty)\n        {\n            if (i % strideLen == 0)\n            {\n                //Make sure front is only\n                //evaluated once per item\n                elem1 = r.front;\n                elem2 = r.front;\n                assert(elem1 == elem2);\n            }\n            r.popFront();\n            i++;\n        }\n    }\n\n    string txt = \"abcdefghijklmnopqrstuvwxyz\";\n\n    int popCount = 0;\n    auto pipeOnPop = txt.tee!(a => popCount++);\n    testRange(pipeOnPop);\n    assert(popCount == 26);\n\n    int frontCount = 0;\n    auto pipeOnFront = txt.tee!(a => frontCount++, No.pipeOnPop);\n    testRange(pipeOnFront);\n    assert(frontCount == 9);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.meta : AliasSeq;\n\n    //Test diverting elements to an OutputRange\n    string txt = \"abcdefghijklmnopqrstuvwxyz\";\n\n    dchar[] asink1 = [];\n    auto fsink = (dchar c) { asink1 ~= c; };\n    auto result1 = txt.tee(fsink).array;\n    assert(equal(txt, result1) && (equal(result1, asink1)));\n\n    dchar[] _asink1 = [];\n    auto _result1 = txt.tee!((dchar c) { _asink1 ~= c; })().array;\n    assert(equal(txt, _result1) && (equal(_result1, _asink1)));\n\n    dchar[] asink2 = new dchar[](txt.length);\n    void fsink2(dchar c) { static int i = 0; asink2[i] = c; i++; }\n    auto result2 = txt.tee(&fsink2).array;\n    assert(equal(txt, result2) && equal(result2, asink2));\n\n    dchar[] asink3 = new dchar[](txt.length);\n    auto result3 = txt.tee(asink3).array;\n    assert(equal(txt, result3) && equal(result3, asink3));\n\n    static foreach (CharType; AliasSeq!(char, wchar, dchar))\n    {{\n        auto appSink = appender!(CharType[])();\n        auto appResult = txt.tee(appSink).array;\n        assert(equal(txt, appResult) && equal(appResult, appSink.data));\n    }}\n\n    static foreach (StringType; AliasSeq!(string, wstring, dstring))\n    {{\n        auto appSink = appender!StringType();\n        auto appResult = txt.tee(appSink).array;\n        assert(equal(txt, appResult) && equal(appResult, appSink.data));\n    }}\n}\n\n@safe unittest\n{\n    // Issue 13483\n    static void func1(T)(T x) {}\n    void func2(int x) {}\n\n    auto r = [1, 2, 3, 4].tee!func1.tee!func2;\n}\n\n/**\nExtends the length of the input range `r` by padding out the start of the\nrange with the element `e`. The element `e` must be of a common type with\nthe element type of the range `r` as defined by $(REF CommonType, std, traits).\nIf `n` is less than the length of of `r`, then `r` is returned unmodified.\n\nIf `r` is a string with Unicode characters in it, `padLeft` follows D's rules\nabout length for strings, which is not the number of characters, or\ngraphemes, but instead the number of encoding units. If you want to treat each\ngrapheme as only one encoding unit long, then call\n$(REF byGrapheme, std, uni) before calling this function.\n\nIf `r` has a length, then this is $(BIGOH 1). Otherwise, it's $(BIGOH r.length).\n\nParams:\n    r = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) with a length, or a forward range\n    e = element to pad the range with\n    n = the length to pad to\n\nReturns:\n    A range containing the elements of the original range with the extra padding\n\nSee Also:\n    $(REF leftJustifier, std, string)\n*/\nauto padLeft(R, E)(R r, E e, size_t n)\nif (\n    ((isInputRange!R && hasLength!R) || isForwardRange!R) &&\n    !is(CommonType!(ElementType!R, E) == void)\n)\n{\n    static if (hasLength!R)\n        auto dataLength = r.length;\n    else\n        auto dataLength = r.save.walkLength(n);\n\n    return e.repeat(n > dataLength ? n - dataLength : 0).chain(r);\n}\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert([1, 2, 3, 4].padLeft(0, 6).equal([0, 0, 1, 2, 3, 4]));\n    assert([1, 2, 3, 4].padLeft(0, 3).equal([1, 2, 3, 4]));\n\n    assert(\"abc\".padLeft('_', 6).equal(\"___abc\"));\n}\n\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : DummyRange, Length, RangeType, ReturnBy;\n    import std.meta : AliasSeq;\n\n    alias DummyRanges = AliasSeq!(\n        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Input),\n        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Forward),\n        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Bidirectional),\n        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random),\n        DummyRange!(ReturnBy.Reference, Length.No, RangeType.Forward),\n        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Input),\n        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Forward),\n        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Bidirectional),\n        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Random),\n        DummyRange!(ReturnBy.Value, Length.No, RangeType.Forward)\n    );\n\n    foreach (Range; DummyRanges)\n    {\n        Range r;\n        assert(r\n            .padLeft(0, 12)\n            .equal([0, 0, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U])\n        );\n    }\n}\n\n// Test nogc inference\n@safe @nogc pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    static immutable r1 = [1, 2, 3, 4];\n    static immutable r2 = [0, 0, 1, 2, 3, 4];\n    assert(r1.padLeft(0, 6).equal(r2));\n}\n\n/**\nExtend the length of the input range `r` by padding out the end of the range\nwith the element `e`. The element `e` must be of a common type with the\nelement type of the range `r` as defined by $(REF CommonType, std, traits).\nIf `n` is less than the length of of `r`, then the contents of `r` are\nreturned.\n\nThe range primitives that the resulting range provides depends whether or not `r`\nprovides them. Except the functions `back` and `popBack`, which also require\nthe range to have a length as well as `back` and `popBack`\n\nParams:\n    r = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) with a length\n    e = element to pad the range with\n    n = the length to pad to\n\nReturns:\n    A range containing the elements of the original range with the extra padding\n\nSee Also:\n    $(REF rightJustifier, std, string)\n*/\nauto padRight(R, E)(R r, E e, size_t n)\nif (\n    isInputRange!R &&\n    !isInfinite!R &&\n    !is(CommonType!(ElementType!R, E) == void))\n{\n    static struct Result\n    {\n        private:\n        R data;\n        E element;\n        size_t counter;\n        static if (isBidirectionalRange!R && hasLength!R) size_t backPosition;\n        size_t maxSize;\n\n        public:\n        bool empty() @property\n        {\n            return data.empty && counter >= maxSize;\n        }\n\n        auto front() @property\n        {\n            assert(!empty, \"Attempting to fetch the front of an empty padRight\");\n            return data.empty ? element : data.front;\n        }\n\n        void popFront()\n        {\n            assert(!empty, \"Attempting to popFront an empty padRight\");\n            ++counter;\n\n            if (!data.empty)\n            {\n                data.popFront;\n            }\n        }\n\n        static if (hasLength!R)\n        {\n            size_t length() @property\n            {\n                import std.algorithm.comparison : max;\n                return max(data.length, maxSize);\n            }\n        }\n\n        static if (isForwardRange!R)\n        {\n            auto save() @property\n            {\n                typeof(this) result = this;\n                data = data.save;\n                return result;\n            }\n        }\n\n        static if (isBidirectionalRange!R && hasLength!R)\n        {\n            auto back() @property\n            {\n                assert(!empty, \"Attempting to fetch the back of an empty padRight\");\n                return backPosition > data.length ? element : data.back;\n            }\n\n            void popBack()\n            {\n                assert(!empty, \"Attempting to popBack an empty padRight\");\n                if (backPosition > data.length)\n                {\n                    --backPosition;\n                    --maxSize;\n                }\n                else\n                {\n                    data.popBack;\n                }\n            }\n        }\n\n        static if (isRandomAccessRange!R && hasLength!R)\n        {\n            E opIndex(size_t index)\n            {\n                assert(index <= this.length, \"Index out of bounds\");\n                return (index > data.length && index <= maxSize) ? element :\n                    data[index];\n            }\n        }\n\n        static if (hasSlicing!R && hasLength!R)\n        {\n            auto opSlice(size_t a, size_t b)\n            {\n                assert(\n                    a <= b,\n                    \"Attempting to slice a padRight with a larger first argument than the second.\"\n                );\n                assert(\n                    b <= length,\n                    \"Attempting to slice using an out of bounds index on a padRight\"\n                );\n                return Result((b <= data.length) ? data[a .. b] : data[a .. data.length],\n                    element, b - a);\n            }\n\n            alias opDollar = length;\n        }\n\n        this(R r, E e, size_t max)\n        {\n            data = r;\n            element = e;\n            maxSize = max;\n            static if (isBidirectionalRange!R && hasLength!R)\n                backPosition = max;\n        }\n\n        @disable this();\n    }\n\n    return Result(r, e, n);\n}\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert([1, 2, 3, 4].padRight(0, 6).equal([1, 2, 3, 4, 0, 0]));\n    assert([1, 2, 3, 4].padRight(0, 4).equal([1, 2, 3, 4]));\n\n    assert(\"abc\".padRight('_', 6).equal(\"abc___\"));\n}\n\npure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : AllDummyRanges, ReferenceInputRange;\n    import std.meta : AliasSeq;\n\n    auto string_input_range = new ReferenceInputRange!dchar(['a', 'b', 'c']);\n    dchar padding = '_';\n    assert(string_input_range.padRight(padding, 6).equal(\"abc___\"));\n\n    foreach (RangeType; AllDummyRanges)\n    {\n        RangeType r1;\n        assert(r1\n            .padRight(0, 12)\n            .equal([1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 0, 0])\n        );\n\n        // test if Result properly uses random access ranges\n        static if (isRandomAccessRange!RangeType)\n        {\n            RangeType r3;\n            assert(r3.padRight(0, 12)[0] == 1);\n            assert(r3.padRight(0, 12)[2] == 3);\n            assert(r3.padRight(0, 12)[11] == 0);\n        }\n\n        // test if Result properly uses slicing and opDollar\n        static if (hasSlicing!RangeType)\n        {\n            RangeType r4;\n            assert(r4\n                .padRight(0, 12)[0 .. 3]\n                .equal([1, 2, 3])\n            );\n            assert(r4\n                .padRight(0, 12)[2 .. $]\n                .equal([3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 0, 0])\n            );\n            assert(r4\n                .padRight(0, 12)[0 .. $]\n                .equal([1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 0, 0])\n            );\n        }\n    }\n}\n\n// Test nogc inference\n@safe @nogc pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    static immutable r1 = [1, 2, 3, 4];\n    static immutable r2 = [1, 2, 3, 4, 0, 0];\n    assert(r1.padRight(0, 6).equal(r2));\n}\n"
  },
  {
    "path": "libphobos/src/std/range/primitives.d",
    "content": "/**\nThis module is a submodule of $(MREF std, range).\n\nIt provides basic range functionality by defining several templates for testing\nwhether a given object is a range, and what kind of range it is:\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE ,\n    $(TR $(TD $(LREF isInputRange))\n        $(TD Tests if something is an $(I input range), defined to be\n        something from which one can sequentially read data using the\n        primitives `front`, `popFront`, and `empty`.\n    ))\n    $(TR $(TD $(LREF isOutputRange))\n        $(TD Tests if something is an $(I output range), defined to be\n        something to which one can sequentially write data using the\n        $(LREF put) primitive.\n    ))\n    $(TR $(TD $(LREF isForwardRange))\n        $(TD Tests if something is a $(I forward range), defined to be an\n        input range with the additional capability that one can save one's\n        current position with the `save` primitive, thus allowing one to\n        iterate over the same range multiple times.\n    ))\n    $(TR $(TD $(LREF isBidirectionalRange))\n        $(TD Tests if something is a $(I bidirectional range), that is, a\n        forward range that allows reverse traversal using the primitives $(D\n        back) and `popBack`.\n    ))\n    $(TR $(TD $(LREF isRandomAccessRange))\n        $(TD Tests if something is a $(I random access range), which is a\n        bidirectional range that also supports the array subscripting\n        operation via the primitive `opIndex`.\n    ))\n)\n\nIt also provides number of templates that test for various range capabilities:\n\n$(BOOKTABLE ,\n    $(TR $(TD $(LREF hasMobileElements))\n        $(TD Tests if a given range's elements can be moved around using the\n        primitives `moveFront`, `moveBack`, or `moveAt`.\n    ))\n    $(TR $(TD $(LREF ElementType))\n        $(TD Returns the element type of a given range.\n    ))\n    $(TR $(TD $(LREF ElementEncodingType))\n        $(TD Returns the encoding element type of a given range.\n    ))\n    $(TR $(TD $(LREF hasSwappableElements))\n        $(TD Tests if a range is a forward range with swappable elements.\n    ))\n    $(TR $(TD $(LREF hasAssignableElements))\n        $(TD Tests if a range is a forward range with mutable elements.\n    ))\n    $(TR $(TD $(LREF hasLvalueElements))\n        $(TD Tests if a range is a forward range with elements that can be\n        passed by reference and have their address taken.\n    ))\n    $(TR $(TD $(LREF hasLength))\n        $(TD Tests if a given range has the `length` attribute.\n    ))\n    $(TR $(TD $(LREF isInfinite))\n        $(TD Tests if a given range is an $(I infinite range).\n    ))\n    $(TR $(TD $(LREF hasSlicing))\n        $(TD Tests if a given range supports the array slicing operation $(D\n        R[x .. y]).\n    ))\n)\n\nFinally, it includes some convenience functions for manipulating ranges:\n\n$(BOOKTABLE ,\n    $(TR $(TD $(LREF popFrontN))\n        $(TD Advances a given range by up to $(I n) elements.\n    ))\n    $(TR $(TD $(LREF popBackN))\n        $(TD Advances a given bidirectional range from the right by up to\n        $(I n) elements.\n    ))\n    $(TR $(TD $(LREF popFrontExactly))\n        $(TD Advances a given range by up exactly $(I n) elements.\n    ))\n    $(TR $(TD $(LREF popBackExactly))\n        $(TD Advances a given bidirectional range from the right by exactly\n        $(I n) elements.\n    ))\n    $(TR $(TD $(LREF moveFront))\n        $(TD Removes the front element of a range.\n    ))\n    $(TR $(TD $(LREF moveBack))\n        $(TD Removes the back element of a bidirectional range.\n    ))\n    $(TR $(TD $(LREF moveAt))\n        $(TD Removes the $(I i)'th element of a random-access range.\n    ))\n    $(TR $(TD $(LREF walkLength))\n        $(TD Computes the length of any range in O(n) time.\n    ))\n    $(TR $(TD $(LREF put))\n        $(TD Outputs element `e` to a range.\n    ))\n)\n\nSource: $(PHOBOSSRC std/range/primitives.d)\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP erdani.com, Andrei Alexandrescu), David Simcha, and\n         $(HTTP jmdavisprog.com, Jonathan M Davis). Credit for some of the ideas\n         in building this module goes to\n         $(HTTP fantascienza.net/leonardo/so/, Leonardo Maffi).\n*/\nmodule std.range.primitives;\n\nimport std.traits;\n\n/**\nReturns `true` if `R` is an input range. An input range must\ndefine the primitives `empty`, `popFront`, and `front`. The\nfollowing code should compile for any input range.\n\n----\nR r;              // can define a range object\nif (r.empty) {}   // can test for empty\nr.popFront();     // can invoke popFront()\nauto h = r.front; // can get the front of the range of non-void type\n----\n\nThe following are rules of input ranges are assumed to hold true in all\nPhobos code. These rules are not checkable at compile-time, so not conforming\nto these rules when writing ranges or range based code will result in\nundefined behavior.\n\n$(UL\n    $(LI `r.empty` returns `false` if and only if there is more data\n    available in the range.)\n    $(LI `r.empty` evaluated multiple times, without calling\n    `r.popFront`, or otherwise mutating the range object or the\n    underlying data, yields the same result for every evaluation.)\n    $(LI `r.front` returns the current element in the range.\n    It may return by value or by reference.)\n    $(LI `r.front` can be legally evaluated if and only if evaluating\n    `r.empty` has, or would have, equaled `false`.)\n    $(LI `r.front` evaluated multiple times, without calling\n    `r.popFront`, or otherwise mutating the range object or the\n    underlying data, yields the same result for every evaluation.)\n    $(LI `r.popFront` advances to the next element in the range.)\n    $(LI `r.popFront` can be called if and only if evaluating `r.empty`\n    has, or would have, equaled `false`.)\n)\n\nAlso, note that Phobos code assumes that the primitives `r.front` and\n`r.empty` are $(BIGOH 1) time complexity wise or \"cheap\" in terms of\nrunning time. $(BIGOH) statements in the documentation of range functions\nare made with this assumption.\n\nSee_Also:\n    The header of $(MREF std,range) for tutorials on ranges.\n\nParams:\n    R = type to be tested\n\nReturns:\n    `true` if R is an input range, `false` if not\n */\nenum bool isInputRange(R) =\n    is(typeof(R.init) == R)\n    && is(ReturnType!((R r) => r.empty) == bool)\n    && is(typeof((return ref R r) => r.front))\n    && !is(ReturnType!((R r) => r.front) == void)\n    && is(typeof((R r) => r.popFront));\n\n///\n@safe unittest\n{\n    struct A {}\n    struct B\n    {\n        void popFront();\n        @property bool empty();\n        @property int front();\n    }\n    static assert(!isInputRange!A);\n    static assert( isInputRange!B);\n    static assert( isInputRange!(int[]));\n    static assert( isInputRange!(char[]));\n    static assert(!isInputRange!(char[4]));\n    static assert( isInputRange!(inout(int)[]));\n\n    static struct NotDefaultConstructible\n    {\n        @disable this();\n        void popFront();\n        @property bool empty();\n        @property int front();\n    }\n    static assert( isInputRange!NotDefaultConstructible);\n\n    static struct NotDefaultConstructibleOrCopyable\n    {\n        @disable this();\n        @disable this(this);\n        void popFront();\n        @property bool empty();\n        @property int front();\n    }\n    static assert(isInputRange!NotDefaultConstructibleOrCopyable);\n\n    static struct Frontless\n    {\n        void popFront();\n        @property bool empty();\n    }\n    static assert(!isInputRange!Frontless);\n\n    static struct VoidFront\n    {\n        void popFront();\n        @property bool empty();\n        void front();\n    }\n    static assert(!isInputRange!VoidFront);\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    static struct R\n    {\n        static struct Front\n        {\n            R* impl;\n            @property int value() { return impl._front; }\n            alias value this;\n        }\n\n        int _front;\n\n        @property bool empty() { return _front >= 3; }\n        @property auto front() { return Front(&this); }\n        void popFront() { _front++; }\n    }\n    R r;\n\n    static assert(isInputRange!R);\n    assert(r.equal([ 0, 1, 2 ]));\n}\n\n/+\nputs the whole raw element `e` into `r`. doPut will not attempt to\niterate, slice or transcode `e` in any way shape or form. It will $(B only)\ncall the correct primitive (`r.put(e)`,  $(D r.front = e) or\n`r(e)` once.\n\nThis can be important when `e` needs to be placed in `r` unchanged.\nFurthermore, it can be useful when working with `InputRange`s, as doPut\nguarantees that no more than a single element will be placed.\n+/\nprivate void doPut(R, E)(ref R r, auto ref E e)\n{\n    static if (is(PointerTarget!R == struct))\n        enum usingPut = hasMember!(PointerTarget!R, \"put\");\n    else\n        enum usingPut = hasMember!(R, \"put\");\n\n    static if (usingPut)\n    {\n        static assert(is(typeof(r.put(e))),\n            \"Cannot put a \" ~ E.stringof ~ \" into a \" ~ R.stringof ~ \".\");\n        r.put(e);\n    }\n    else static if (isNarrowString!R && is(const(E) == const(typeof(r[0]))))\n    {\n        // one character, we can put it\n        r[0] = e;\n        r = r[1 .. $];\n    }\n    else static if (isNarrowString!R && isNarrowString!E && is(typeof(r[] = e)))\n    {\n        // slice assign. Note that this is a duplicate from put, but because\n        // putChar uses doPut exclusively, we have to copy it here.\n        immutable len = e.length;\n        r[0 .. len] = e;\n        r = r[len .. $];\n    }\n    else static if (isInputRange!R)\n    {\n        static assert(is(typeof(r.front = e)),\n            \"Cannot put a \" ~ E.stringof ~ \" into a \" ~ R.stringof ~ \".\");\n        r.front = e;\n        r.popFront();\n    }\n    else static if (is(typeof(r(e))))\n    {\n        r(e);\n    }\n    else\n    {\n        static assert(false,\n            \"Cannot put a \" ~ E.stringof ~ \" into a \" ~ R.stringof ~ \".\");\n    }\n}\n\n@safe unittest\n{\n    static assert(!isNativeOutputRange!(int,     int));\n    static assert( isNativeOutputRange!(int[],   int));\n    static assert(!isNativeOutputRange!(int[][], int));\n\n    static assert(!isNativeOutputRange!(int,     int[]));\n    static assert(!isNativeOutputRange!(int[],   int[]));\n    static assert( isNativeOutputRange!(int[][], int[]));\n\n    static assert(!isNativeOutputRange!(int,     int[][]));\n    static assert(!isNativeOutputRange!(int[],   int[][]));\n    static assert(!isNativeOutputRange!(int[][], int[][]));\n\n    static assert(!isNativeOutputRange!(int[4],   int));\n    static assert( isNativeOutputRange!(int[4][], int)); //Scary!\n    static assert( isNativeOutputRange!(int[4][], int[4]));\n\n    static assert( isNativeOutputRange!( char[],   char));\n    static assert(!isNativeOutputRange!( char[],  dchar));\n    static assert( isNativeOutputRange!(dchar[],   char));\n    static assert( isNativeOutputRange!(dchar[],  dchar));\n\n}\n\n/++\nOutputs `e` to `r`. The exact effect is dependent upon the two\ntypes. Several cases are accepted, as described below. The code snippets\nare attempted in order, and the first to compile \"wins\" and gets\nevaluated.\n\nIn this table \"doPut\" is a method that places `e` into `r`, using the\ncorrect primitive: `r.put(e)` if `R` defines `put`, $(D r.front = e)\nif `r` is an input range (followed by `r.popFront()`), or `r(e)`\notherwise.\n\n$(BOOKTABLE ,\n    $(TR\n        $(TH Code Snippet)\n        $(TH Scenario)\n    )\n    $(TR\n        $(TD `r.doPut(e);`)\n        $(TD `R` specifically accepts an `E`.)\n    )\n    $(TR\n        $(TD $(D r.doPut([ e ]);))\n        $(TD `R` specifically accepts an `E[]`.)\n    )\n    $(TR\n        $(TD `r.putChar(e);`)\n        $(TD `R` accepts some form of string or character. put will\n            transcode the character `e` accordingly.)\n    )\n    $(TR\n        $(TD $(D for (; !e.empty; e.popFront()) put(r, e.front);))\n        $(TD Copying range `E` into `R`.)\n    )\n)\n\nTip: `put` should $(I not) be used \"UFCS-style\", e.g. `r.put(e)`.\nDoing this may call `R.put` directly, by-passing any transformation\nfeature provided by `Range.put`. $(D put(r, e)) is prefered.\n +/\nvoid put(R, E)(ref R r, E e)\n{\n    //First level: simply straight up put.\n    static if (is(typeof(doPut(r, e))))\n    {\n        doPut(r, e);\n    }\n    //Optional optimization block for straight up array to array copy.\n    else static if (isDynamicArray!R && !isNarrowString!R && isDynamicArray!E && is(typeof(r[] = e[])))\n    {\n        immutable len = e.length;\n        r[0 .. len] = e[];\n        r = r[len .. $];\n    }\n    //Accepts E[] ?\n    else static if (is(typeof(doPut(r, [e]))) && !isDynamicArray!R)\n    {\n        if (__ctfe)\n        {\n            E[1] arr = [e];\n            doPut(r, arr[]);\n        }\n        else\n            doPut(r, (ref e) @trusted { return (&e)[0 .. 1]; }(e));\n    }\n    //special case for char to string.\n    else static if (isSomeChar!E && is(typeof(putChar(r, e))))\n    {\n        putChar(r, e);\n    }\n    //Extract each element from the range\n    //We can use \"put\" here, so we can recursively test a RoR of E.\n    else static if (isInputRange!E && is(typeof(put(r, e.front))))\n    {\n        //Special optimization: If E is a narrow string, and r accepts characters no-wider than the string's\n        //Then simply feed the characters 1 by 1.\n        static if (isNarrowString!E && (\n            (is(E : const  char[]) && is(typeof(doPut(r,  char.max))) && !is(typeof(doPut(r, dchar.max))) &&\n                !is(typeof(doPut(r, wchar.max)))) ||\n            (is(E : const wchar[]) && is(typeof(doPut(r, wchar.max))) && !is(typeof(doPut(r, dchar.max)))) ) )\n        {\n            foreach (c; e)\n                doPut(r, c);\n        }\n        else\n        {\n            for (; !e.empty; e.popFront())\n                put(r, e.front);\n        }\n    }\n    else\n    {\n        static assert(false, \"Cannot put a \" ~ E.stringof ~ \" into a \" ~ R.stringof ~ \".\");\n    }\n}\n\n/**\n * When an output range's `put` method only accepts elements of type\n * `T`, use the global `put` to handle outputting a `T[]` to the range\n * or vice-versa.\n */\n@safe pure unittest\n{\n    import std.traits : isSomeChar;\n\n    static struct A\n    {\n        string data;\n\n        void put(C)(C c) if (isSomeChar!C)\n        {\n            data ~= c;\n        }\n    }\n    static assert(isOutputRange!(A, char));\n\n    auto a = A();\n    put(a, \"Hello\");\n    assert(a.data == \"Hello\");\n}\n\n/**\n * `put` treats dynamic arrays as array slices, and will call `popFront`\n * on the slice after an element has been copied.\n *\n * Be sure to save the position of the array before calling `put`.\n */\n@safe pure nothrow unittest\n{\n    int[] a = [1, 2, 3], b = [10, 20];\n    auto c = a;\n    put(a, b);\n    assert(c == [10, 20, 3]);\n    // at this point, a was advanced twice, so it only contains\n    // its last element while c represents the whole array\n    assert(a == [3]);\n}\n\n/**\n * It's also possible to `put` any width strings or characters into narrow\n * strings -- put does the conversion for you.\n *\n * Note that putting the same width character as the target buffer type is\n * `nothrow`, but transcoding can throw a $(REF UTFException, std, utf).\n */\n@safe pure unittest\n{\n    // the elements must be mutable, so using string or const(char)[]\n    // won't compile\n    char[] s1 = new char[13];\n    auto r1 = s1;\n    put(r1, \"Hello, World!\"w);\n    assert(s1 == \"Hello, World!\");\n}\n\n@safe pure nothrow unittest\n{\n    // same thing, just using same character width.\n    char[] s1 = new char[13];\n    auto r1 = s1;\n    put(r1, \"Hello, World!\");\n    assert(s1 == \"Hello, World!\");\n}\n\n\n@safe pure nothrow @nogc unittest\n{\n    static struct R() { void put(in char[]) {} }\n    R!() r;\n    put(r, 'a');\n}\n\n//Helper function to handle chars as quickly and as elegantly as possible\n//Assumes r.put(e)/r(e) has already been tested\nprivate void putChar(R, E)(ref R r, E e)\nif (isSomeChar!E)\n{\n    ////@@@9186@@@: Can't use (E[]).init\n    ref const( char)[] cstringInit();\n    ref const(wchar)[] wstringInit();\n    ref const(dchar)[] dstringInit();\n\n    enum csCond = is(typeof(doPut(r, cstringInit())));\n    enum wsCond = is(typeof(doPut(r, wstringInit())));\n    enum dsCond = is(typeof(doPut(r, dstringInit())));\n\n    //Use \"max\" to avoid static type demotion\n    enum ccCond = is(typeof(doPut(r,  char.max)));\n    enum wcCond = is(typeof(doPut(r, wchar.max)));\n    //enum dcCond = is(typeof(doPut(r, dchar.max)));\n\n    //Fast transform a narrow char into a wider string\n    static if ((wsCond && E.sizeof < wchar.sizeof) || (dsCond && E.sizeof < dchar.sizeof))\n    {\n        enum w = wsCond && E.sizeof < wchar.sizeof;\n        Select!(w, wchar, dchar) c = e;\n        typeof(c)[1] arr = [c];\n        doPut(r, arr[]);\n    }\n    //Encode a wide char into a narrower string\n    else static if (wsCond || csCond)\n    {\n        import std.utf : encode;\n        /+static+/ Select!(wsCond, wchar[2], char[4]) buf; //static prevents purity.\n        doPut(r, buf[0 .. encode(buf, e)]);\n    }\n    //Slowly encode a wide char into a series of narrower chars\n    else static if (wcCond || ccCond)\n    {\n        import std.encoding : encode;\n        alias C = Select!(wcCond, wchar, char);\n        encode!(C, R)(e, r);\n    }\n    else\n    {\n        static assert(false, \"Cannot put a \" ~ E.stringof ~ \" into a \" ~ R.stringof ~ \".\");\n    }\n}\n\npure @safe unittest\n{\n    auto f = delegate (const(char)[]) {};\n    putChar(f, cast(dchar)'a');\n}\n\n\n@safe pure unittest\n{\n    static struct R() { void put(in char[]) {} }\n    R!() r;\n    putChar(r, 'a');\n}\n\n@safe unittest\n{\n    struct A {}\n    static assert(!isInputRange!(A));\n    struct B\n    {\n        void put(int) {}\n    }\n    B b;\n    put(b, 5);\n}\n\n@safe unittest\n{\n    int[] a = new int[10];\n    int b;\n    static assert(isInputRange!(typeof(a)));\n    put(a, b);\n}\n\n@safe unittest\n{\n    void myprint(in char[] s) { }\n    auto r = &myprint;\n    put(r, 'a');\n}\n\n@safe unittest\n{\n    int[] a = new int[10];\n    static assert(!__traits(compiles, put(a, 1.0L)));\n    put(a, 1);\n    assert(a.length == 9);\n    /*\n     * a[0] = 65;       // OK\n     * a[0] = 'A';      // OK\n     * a[0] = \"ABC\"[0]; // OK\n     * put(a, \"ABC\");   // OK\n     */\n    put(a, \"ABC\");\n    assert(a.length == 6);\n}\n\n@safe unittest\n{\n    char[] a = new char[10];\n    static assert(!__traits(compiles, put(a, 1.0L)));\n    static assert(!__traits(compiles, put(a, 1)));\n    //char[] is now an output range for char, wchar, dchar, and ranges of such.\n    static assert(__traits(compiles, putChar(a, 'a')));\n    static assert(__traits(compiles, put(a, wchar('a'))));\n    static assert(__traits(compiles, put(a, dchar('a'))));\n    static assert(__traits(compiles, put(a, \"ABC\")));\n    static assert(__traits(compiles, put(a, \"ABC\"w)));\n    static assert(__traits(compiles, put(a, \"ABC\"d)));\n}\n\n@safe unittest\n{\n    // attempt putting into narrow strings by transcoding\n    char[] a = new char[10];\n    auto b = a;\n    put(a, \"ABC\"w);\n    assert(b[0 .. 3] == \"ABC\");\n    assert(a.length == 7);\n\n    a = b; // reset\n    put(a, 'λ');\n    assert(b[0 .. 2] == \"λ\");\n    assert(a.length == 8);\n\n    a = b; // reset\n    put(a, \"ABC\"d);\n    assert(b[0 .. 3] == \"ABC\");\n    assert(a.length == 7);\n\n    a = b; // reset\n    put(a, '𐐷');\n    assert(b[0 .. 4] == \"𐐷\");\n    assert(a.length == 6);\n\n    wchar[] aw = new wchar[10];\n    auto bw = aw;\n    put(aw, \"ABC\");\n    assert(bw[0 .. 3] == \"ABC\"w);\n    assert(aw.length == 7);\n\n    aw = bw; // reset\n    put(aw, 'λ');\n    assert(bw[0 .. 1] == \"λ\"w);\n    assert(aw.length == 9);\n\n    aw = bw; // reset\n    put(aw, \"ABC\"d);\n    assert(bw[0 .. 3] == \"ABC\"w);\n    assert(aw.length == 7);\n\n    aw = bw; // reset\n    put(aw, '𐐷');\n    assert(bw[0 .. 2] == \"𐐷\"w);\n    assert(aw.length == 8);\n\n    aw = bw; // reset\n    put(aw, \"𐐷\"); // try transcoding from char[]\n    assert(bw[0 .. 2] == \"𐐷\"w);\n    assert(aw.length == 8);\n}\n\n@safe unittest\n{\n    int[][] a = new int[][10];\n    int[]   b = new int[10];\n    int     c;\n    put(b, c);\n    assert(b.length == 9);\n    put(a, b);\n    assert(a.length == 9);\n    static assert(!__traits(compiles, put(a, c)));\n}\n\n@safe unittest\n{\n    int[][] a = new int[][](3);\n    int[]   b = [1];\n    auto aa = a;\n    put(aa, b);\n    assert(aa == [[], []]);\n    assert(a  == [[1], [], []]);\n    int[][3] c = [2];\n    aa = a;\n    put(aa, c[]);\n    assert(aa.empty);\n    assert(a == [[2], [2], [2]]);\n}\n\n@safe unittest\n{\n    // Test fix for bug 7476.\n    struct LockingTextWriter\n    {\n        void put(dchar c){}\n    }\n    struct RetroResult\n    {\n        bool end = false;\n        @property bool empty() const { return end; }\n        @property dchar front(){ return 'a'; }\n        void popFront(){ end = true; }\n    }\n    LockingTextWriter w;\n    RetroResult re;\n    put(w, re);\n}\n\n@system unittest\n{\n    import std.conv : to;\n    import std.meta : AliasSeq;\n    import std.typecons : tuple;\n\n    static struct PutC(C)\n    {\n        string result;\n        void put(const(C) c) { result ~= to!string((&c)[0 .. 1]); }\n    }\n    static struct PutS(C)\n    {\n        string result;\n        void put(const(C)[] s) { result ~= to!string(s); }\n    }\n    static struct PutSS(C)\n    {\n        string result;\n        void put(const(C)[][] ss)\n        {\n            foreach (s; ss)\n                result ~= to!string(s);\n        }\n    }\n\n    PutS!char p;\n    putChar(p, cast(dchar)'a');\n\n    //Source Char\n    static foreach (SC; AliasSeq!(char, wchar, dchar))\n    {{\n        SC ch = 'I';\n        dchar dh = '♥';\n        immutable(SC)[] s = \"日本語！\";\n        immutable(SC)[][] ss = [\"日本語\", \"が\", \"好き\", \"ですか\", \"？\"];\n\n        //Target Char\n        static foreach (TC; AliasSeq!(char, wchar, dchar))\n        {\n            //Testing PutC and PutS\n            static foreach (Type; AliasSeq!(PutC!TC, PutS!TC))\n            {{\n                Type type;\n                auto sink = new Type();\n\n                //Testing put and sink\n                foreach (value ; tuple(type, sink))\n                {\n                    put(value, ch);\n                    assert(value.result == \"I\");\n                    put(value, dh);\n                    assert(value.result == \"I♥\");\n                    put(value, s);\n                    assert(value.result == \"I♥日本語！\");\n                    put(value, ss);\n                    assert(value.result == \"I♥日本語！日本語が好きですか？\");\n                }\n            }}\n        }\n    }}\n}\n\n@safe unittest\n{\n    static struct CharRange\n    {\n        char c;\n        enum empty = false;\n        void popFront(){}\n        ref char front() return @property\n        {\n            return c;\n        }\n    }\n    CharRange c;\n    put(c, cast(dchar)'H');\n    put(c, \"hello\"d);\n}\n\n@system unittest\n{\n    // issue 9823\n    const(char)[] r;\n    void delegate(const(char)[]) dg = (s) { r = s; };\n    put(dg, [\"ABC\"]);\n    assert(r == \"ABC\");\n}\n\n@safe unittest\n{\n    // issue 10571\n    import std.format;\n    string buf;\n    formattedWrite((in char[] s) { buf ~= s; }, \"%s\", \"hello\");\n    assert(buf == \"hello\");\n}\n\n@safe unittest\n{\n    import std.format;\n    import std.meta : AliasSeq;\n    struct PutC(C)\n    {\n        void put(C){}\n    }\n    struct PutS(C)\n    {\n        void put(const(C)[]){}\n    }\n    struct CallC(C)\n    {\n        void opCall(C){}\n    }\n    struct CallS(C)\n    {\n        void opCall(const(C)[]){}\n    }\n    struct FrontC(C)\n    {\n        enum empty = false;\n        auto front()@property{return C.init;}\n        void front(C)@property{}\n        void popFront(){}\n    }\n    struct FrontS(C)\n    {\n        enum empty = false;\n        auto front()@property{return C[].init;}\n        void front(const(C)[])@property{}\n        void popFront(){}\n    }\n    void foo()\n    {\n        static foreach (C; AliasSeq!(char, wchar, dchar))\n        {{\n            formattedWrite((C c){},        \"\", 1, 'a', cast(wchar)'a', cast(dchar)'a', \"a\"c, \"a\"w, \"a\"d);\n            formattedWrite((const(C)[]){}, \"\", 1, 'a', cast(wchar)'a', cast(dchar)'a', \"a\"c, \"a\"w, \"a\"d);\n            formattedWrite(PutC!C(),       \"\", 1, 'a', cast(wchar)'a', cast(dchar)'a', \"a\"c, \"a\"w, \"a\"d);\n            formattedWrite(PutS!C(),       \"\", 1, 'a', cast(wchar)'a', cast(dchar)'a', \"a\"c, \"a\"w, \"a\"d);\n            CallC!C callC;\n            CallS!C callS;\n            formattedWrite(callC,          \"\", 1, 'a', cast(wchar)'a', cast(dchar)'a', \"a\"c, \"a\"w, \"a\"d);\n            formattedWrite(callS,          \"\", 1, 'a', cast(wchar)'a', cast(dchar)'a', \"a\"c, \"a\"w, \"a\"d);\n            formattedWrite(FrontC!C(),     \"\", 1, 'a', cast(wchar)'a', cast(dchar)'a', \"a\"c, \"a\"w, \"a\"d);\n            formattedWrite(FrontS!C(),     \"\", 1, 'a', cast(wchar)'a', cast(dchar)'a', \"a\"c, \"a\"w, \"a\"d);\n        }}\n        formattedWrite((dchar[]).init,     \"\", 1, 'a', cast(wchar)'a', cast(dchar)'a', \"a\"c, \"a\"w, \"a\"d);\n    }\n}\n\n/+\nReturns `true` if `R` is a native output range for elements of type\n`E`. An output range is defined functionally as a range that\nsupports the operation $(D doPut(r, e)) as defined above. if $(D doPut(r, e))\nis valid, then `put(r,e)` will have the same behavior.\n\nThe two guarantees isNativeOutputRange gives over the larger `isOutputRange`\nare:\n1: `e` is $(B exactly) what will be placed (not `[e]`, for example).\n2: if `E` is a non $(empty) `InputRange`, then placing `e` is\nguaranteed to not overflow the range.\n +/\npackage(std) enum bool isNativeOutputRange(R, E) =\n    is(typeof(doPut(lvalueOf!R, lvalueOf!E)));\n\n@safe unittest\n{\n    int[] r = new int[](4);\n    static assert(isInputRange!(int[]));\n    static assert( isNativeOutputRange!(int[], int));\n    static assert(!isNativeOutputRange!(int[], int[]));\n    static assert( isOutputRange!(int[], int[]));\n\n    if (!r.empty)\n        put(r, 1); //guaranteed to succeed\n    if (!r.empty)\n        put(r, [1, 2]); //May actually error out.\n}\n\n/++\nReturns `true` if `R` is an output range for elements of type\n`E`. An output range is defined functionally as a range that\nsupports the operation $(D put(r, e)) as defined above.\n\nSee_Also:\n    The header of $(MREF std,range) for tutorials on ranges.\n +/\nenum bool isOutputRange(R, E) =\n    is(typeof(put(lvalueOf!R, lvalueOf!E)));\n\n///\n@safe unittest\n{\n    void myprint(in char[] s) { }\n    static assert(isOutputRange!(typeof(&myprint), char));\n\n    static assert( isOutputRange!(char[], char));\n    static assert( isOutputRange!(dchar[], wchar));\n    static assert( isOutputRange!(dchar[], dchar));\n}\n\n@safe unittest\n{\n    import std.array;\n    import std.stdio : writeln;\n\n    auto app = appender!string();\n    string s;\n    static assert( isOutputRange!(Appender!string, string));\n    static assert( isOutputRange!(Appender!string*, string));\n    static assert(!isOutputRange!(Appender!string, int));\n    static assert( isOutputRange!(wchar[], wchar));\n    static assert( isOutputRange!(dchar[], char));\n    static assert( isOutputRange!(dchar[], string));\n    static assert( isOutputRange!(dchar[], wstring));\n    static assert( isOutputRange!(dchar[], dstring));\n\n    static assert(!isOutputRange!(const(int)[], int));\n    static assert(!isOutputRange!(inout(int)[], int));\n}\n\n\n/**\nReturns `true` if `R` is a forward range. A forward range is an\ninput range `r` that can save \"checkpoints\" by saving `r.save`\nto another value of type `R`. Notable examples of input ranges that\nare $(I not) forward ranges are file/socket ranges; copying such a\nrange will not save the position in the stream, and they most likely\nreuse an internal buffer as the entire stream does not sit in\nmemory. Subsequently, advancing either the original or the copy will\nadvance the stream, so the copies are not independent.\n\nThe following code should compile for any forward range.\n\n----\nstatic assert(isInputRange!R);\nR r1;\nauto s1 = r1.save;\nstatic assert(is(typeof(s1) == R));\n----\n\nSaving a range is not duplicating it; in the example above, `r1`\nand `r2` still refer to the same underlying data. They just\nnavigate that data independently.\n\nThe semantics of a forward range (not checkable during compilation)\nare the same as for an input range, with the additional requirement\nthat backtracking must be possible by saving a copy of the range\nobject with `save` and using it later.\n\nSee_Also:\n    The header of $(MREF std,range) for tutorials on ranges.\n */\nenum bool isForwardRange(R) = isInputRange!R\n    && is(ReturnType!((R r) => r.save) == R);\n\n///\n@safe unittest\n{\n    static assert(!isForwardRange!(int));\n    static assert( isForwardRange!(int[]));\n    static assert( isForwardRange!(inout(int)[]));\n}\n\n@safe unittest\n{\n    // BUG 14544\n    struct R14544\n    {\n        int front() { return 0;}\n        void popFront() {}\n        bool empty() { return false; }\n        R14544 save() {return this;}\n    }\n\n    static assert( isForwardRange!R14544 );\n}\n\n/**\nReturns `true` if `R` is a bidirectional range. A bidirectional\nrange is a forward range that also offers the primitives `back` and\n`popBack`. The following code should compile for any bidirectional\nrange.\n\nThe semantics of a bidirectional range (not checkable during\ncompilation) are assumed to be the following (`r` is an object of\ntype `R`):\n\n$(UL $(LI `r.back` returns (possibly a reference to) the last\nelement in the range. Calling `r.back` is allowed only if calling\n`r.empty` has, or would have, returned `false`.))\n\nSee_Also:\n    The header of $(MREF std,range) for tutorials on ranges.\n */\nenum bool isBidirectionalRange(R) = isForwardRange!R\n    && is(typeof((R r) => r.popBack))\n    && is(ReturnType!((R r) => r.back) == ElementType!R);\n\n///\n@safe unittest\n{\n    alias R = int[];\n    R r = [0,1];\n    static assert(isForwardRange!R);           // is forward range\n    r.popBack();                               // can invoke popBack\n    auto t = r.back;                           // can get the back of the range\n    auto w = r.front;\n    static assert(is(typeof(t) == typeof(w))); // same type for front and back\n}\n\n@safe unittest\n{\n    struct A {}\n    struct B\n    {\n        void popFront();\n        @property bool empty();\n        @property int front();\n    }\n    struct C\n    {\n        @property bool empty();\n        @property C save();\n        void popFront();\n        @property int front();\n        void popBack();\n        @property int back();\n    }\n    static assert(!isBidirectionalRange!(A));\n    static assert(!isBidirectionalRange!(B));\n    static assert( isBidirectionalRange!(C));\n    static assert( isBidirectionalRange!(int[]));\n    static assert( isBidirectionalRange!(char[]));\n    static assert( isBidirectionalRange!(inout(int)[]));\n}\n\n/**\nReturns `true` if `R` is a random-access range. A random-access\nrange is a bidirectional range that also offers the primitive $(D\nopIndex), OR an infinite forward range that offers `opIndex`. In\neither case, the range must either offer `length` or be\ninfinite. The following code should compile for any random-access\nrange.\n\nThe semantics of a random-access range (not checkable during\ncompilation) are assumed to be the following (`r` is an object of\ntype `R`): $(UL $(LI `r.opIndex(n)` returns a reference to the\n`n`th element in the range.))\n\nAlthough `char[]` and `wchar[]` (as well as their qualified\nversions including `string` and `wstring`) are arrays, $(D\nisRandomAccessRange) yields `false` for them because they use\nvariable-length encodings (UTF-8 and UTF-16 respectively). These types\nare bidirectional ranges only.\n\nSee_Also:\n    The header of $(MREF std,range) for tutorials on ranges.\n */\nenum bool isRandomAccessRange(R) =\n    is(typeof(lvalueOf!R[1]) == ElementType!R)\n    && !isNarrowString!R\n    && isForwardRange!R\n    && (isBidirectionalRange!R || isInfinite!R)\n    && (hasLength!R || isInfinite!R)\n    && (isInfinite!R || !is(typeof(lvalueOf!R[$ - 1]))\n        || is(typeof(lvalueOf!R[$ - 1]) == ElementType!R));\n\n///\n@safe unittest\n{\n    import std.traits : isNarrowString;\n\n    alias R = int[];\n\n    // range is finite and bidirectional or infinite and forward.\n    static assert(isBidirectionalRange!R ||\n                  isForwardRange!R && isInfinite!R);\n\n    R r = [0,1];\n    auto e = r[1]; // can index\n    auto f = r.front;\n    static assert(is(typeof(e) == typeof(f))); // same type for indexed and front\n    static assert(!isNarrowString!R); // narrow strings cannot be indexed as ranges\n    static assert(hasLength!R || isInfinite!R); // must have length or be infinite\n\n    // $ must work as it does with arrays if opIndex works with $\n    static if (is(typeof(r[$])))\n    {\n        static assert(is(typeof(f) == typeof(r[$])));\n\n        // $ - 1 doesn't make sense with infinite ranges but needs to work\n        // with finite ones.\n        static if (!isInfinite!R)\n            static assert(is(typeof(f) == typeof(r[$ - 1])));\n    }\n}\n\n@safe unittest\n{\n    struct A {}\n    struct B\n    {\n        void popFront();\n        @property bool empty();\n        @property int front();\n    }\n    struct C\n    {\n        void popFront();\n        @property bool empty();\n        @property int front();\n        void popBack();\n        @property int back();\n    }\n    struct D\n    {\n        @property bool empty();\n        @property D save();\n        @property int front();\n        void popFront();\n        @property int back();\n        void popBack();\n        ref int opIndex(uint);\n        @property size_t length();\n        alias opDollar = length;\n        //int opSlice(uint, uint);\n    }\n    struct E\n    {\n        bool empty();\n        E save();\n        int front();\n        void popFront();\n        int back();\n        void popBack();\n        ref int opIndex(uint);\n        size_t length();\n        alias opDollar = length;\n        //int opSlice(uint, uint);\n    }\n    static assert(!isRandomAccessRange!(A));\n    static assert(!isRandomAccessRange!(B));\n    static assert(!isRandomAccessRange!(C));\n    static assert( isRandomAccessRange!(D));\n    static assert( isRandomAccessRange!(E));\n    static assert( isRandomAccessRange!(int[]));\n    static assert( isRandomAccessRange!(inout(int)[]));\n}\n\n@safe unittest\n{\n    // Test fix for bug 6935.\n    struct R\n    {\n        @disable this();\n\n        @property bool empty() const { return false; }\n        @property int front() const { return 0; }\n        void popFront() {}\n\n        @property R save() { return this; }\n\n        @property int back() const { return 0; }\n        void popBack(){}\n\n        int opIndex(size_t n) const { return 0; }\n        @property size_t length() const { return 0; }\n        alias opDollar = length;\n\n        void put(int e){  }\n    }\n    static assert(isInputRange!R);\n    static assert(isForwardRange!R);\n    static assert(isBidirectionalRange!R);\n    static assert(isRandomAccessRange!R);\n    static assert(isOutputRange!(R, int));\n}\n\n/**\nReturns `true` iff `R` is an input range that supports the\n`moveFront` primitive, as well as `moveBack` and `moveAt` if it's a\nbidirectional or random access range. These may be explicitly implemented, or\nmay work via the default behavior of the module level functions `moveFront`\nand friends. The following code should compile for any range\nwith mobile elements.\n\n----\nalias E = ElementType!R;\nR r;\nstatic assert(isInputRange!R);\nstatic assert(is(typeof(moveFront(r)) == E));\nstatic if (isBidirectionalRange!R)\n    static assert(is(typeof(moveBack(r)) == E));\nstatic if (isRandomAccessRange!R)\n    static assert(is(typeof(moveAt(r, 0)) == E));\n----\n */\nenum bool hasMobileElements(R) =\n    isInputRange!R\n    && is(typeof(moveFront(lvalueOf!R)) == ElementType!R)\n    && (!isBidirectionalRange!R\n        || is(typeof(moveBack(lvalueOf!R)) == ElementType!R))\n    && (!isRandomAccessRange!R\n        || is(typeof(moveAt(lvalueOf!R, 0)) == ElementType!R));\n\n///\n@safe unittest\n{\n    import std.algorithm.iteration : map;\n    import std.range : iota, repeat;\n\n    static struct HasPostblit\n    {\n        this(this) {}\n    }\n\n    auto nonMobile = map!\"a\"(repeat(HasPostblit.init));\n    static assert(!hasMobileElements!(typeof(nonMobile)));\n    static assert( hasMobileElements!(int[]));\n    static assert( hasMobileElements!(inout(int)[]));\n    static assert( hasMobileElements!(typeof(iota(1000))));\n\n    static assert( hasMobileElements!( string));\n    static assert( hasMobileElements!(dstring));\n    static assert( hasMobileElements!( char[]));\n    static assert( hasMobileElements!(dchar[]));\n}\n\n/**\nThe element type of `R`. `R` does not have to be a range. The\nelement type is determined as the type yielded by `r.front` for an\nobject `r` of type `R`. For example, `ElementType!(T[])` is\n`T` if `T[]` isn't a narrow string; if it is, the element type is\n`dchar`. If `R` doesn't have `front`, `ElementType!R` is\n`void`.\n */\ntemplate ElementType(R)\n{\n    static if (is(typeof(R.init.front.init) T))\n        alias ElementType = T;\n    else\n        alias ElementType = void;\n}\n\n///\n@safe unittest\n{\n    import std.range : iota;\n\n    // Standard arrays: returns the type of the elements of the array\n    static assert(is(ElementType!(int[]) == int));\n\n    // Accessing .front retrieves the decoded dchar\n    static assert(is(ElementType!(char[])  == dchar)); // rvalue\n    static assert(is(ElementType!(dchar[]) == dchar)); // lvalue\n\n    // Ditto\n    static assert(is(ElementType!(string) == dchar));\n    static assert(is(ElementType!(dstring) == immutable(dchar)));\n\n    // For ranges it gets the type of .front.\n    auto range = iota(0, 10);\n    static assert(is(ElementType!(typeof(range)) == int));\n}\n\n@safe unittest\n{\n    static assert(is(ElementType!(byte[]) == byte));\n    static assert(is(ElementType!(wchar[]) == dchar)); // rvalue\n    static assert(is(ElementType!(wstring) == dchar));\n}\n\n@safe unittest\n{\n    enum XYZ : string { a = \"foo\" }\n    auto x = XYZ.a.front;\n    immutable char[3] a = \"abc\";\n    int[] i;\n    void[] buf;\n    static assert(is(ElementType!(XYZ) == dchar));\n    static assert(is(ElementType!(typeof(a)) == dchar));\n    static assert(is(ElementType!(typeof(i)) == int));\n    static assert(is(ElementType!(typeof(buf)) == void));\n    static assert(is(ElementType!(inout(int)[]) == inout(int)));\n    static assert(is(ElementType!(inout(int[])) == inout(int)));\n}\n\n@safe unittest\n{\n    static assert(is(ElementType!(int[5]) == int));\n    static assert(is(ElementType!(int[0]) == int));\n    static assert(is(ElementType!(char[5]) == dchar));\n    static assert(is(ElementType!(char[0]) == dchar));\n}\n\n@safe unittest //11336\n{\n    static struct S\n    {\n        this(this) @disable;\n    }\n    static assert(is(ElementType!(S[]) == S));\n}\n\n@safe unittest // 11401\n{\n    // ElementType should also work for non-@propety 'front'\n    struct E { ushort id; }\n    struct R\n    {\n        E front() { return E.init; }\n    }\n    static assert(is(ElementType!R == E));\n}\n\n/**\nThe encoding element type of `R`. For narrow strings (`char[]`,\n`wchar[]` and their qualified variants including `string` and\n`wstring`), `ElementEncodingType` is the character type of the\nstring. For all other types, `ElementEncodingType` is the same as\n`ElementType`.\n */\ntemplate ElementEncodingType(R)\n{\n    static if (is(StringTypeOf!R) && is(R : E[], E))\n        alias ElementEncodingType = E;\n    else\n        alias ElementEncodingType = ElementType!R;\n}\n\n///\n@safe unittest\n{\n    import std.range : iota;\n    // internally the range stores the encoded type\n    static assert(is(ElementEncodingType!(char[])  == char));\n\n    static assert(is(ElementEncodingType!(wstring) == immutable(wchar)));\n\n    static assert(is(ElementEncodingType!(byte[]) == byte));\n\n    auto range = iota(0, 10);\n    static assert(is(ElementEncodingType!(typeof(range)) == int));\n}\n\n@safe unittest\n{\n    static assert(is(ElementEncodingType!(wchar[]) == wchar));\n    static assert(is(ElementEncodingType!(dchar[]) == dchar));\n    static assert(is(ElementEncodingType!(string)  == immutable(char)));\n    static assert(is(ElementEncodingType!(dstring) == immutable(dchar)));\n    static assert(is(ElementEncodingType!(int[])  == int));\n}\n\n@safe unittest\n{\n    enum XYZ : string { a = \"foo\" }\n    auto x = XYZ.a.front;\n    immutable char[3] a = \"abc\";\n    int[] i;\n    void[] buf;\n    static assert(is(ElementType!(XYZ) : dchar));\n    static assert(is(ElementEncodingType!(char[]) == char));\n    static assert(is(ElementEncodingType!(string) == immutable char));\n    static assert(is(ElementType!(typeof(a)) : dchar));\n    static assert(is(ElementType!(typeof(i)) == int));\n    static assert(is(ElementEncodingType!(typeof(i)) == int));\n    static assert(is(ElementType!(typeof(buf)) : void));\n\n    static assert(is(ElementEncodingType!(inout char[]) : inout(char)));\n}\n\n@safe unittest\n{\n    static assert(is(ElementEncodingType!(int[5]) == int));\n    static assert(is(ElementEncodingType!(int[0]) == int));\n    static assert(is(ElementEncodingType!(char[5]) == char));\n    static assert(is(ElementEncodingType!(char[0]) == char));\n}\n\n/**\nReturns `true` if `R` is an input range and has swappable\nelements. The following code should compile for any range\nwith swappable elements.\n\n----\nR r;\nstatic assert(isInputRange!R);\nswap(r.front, r.front);\nstatic if (isBidirectionalRange!R) swap(r.back, r.front);\nstatic if (isRandomAccessRange!R) swap(r[0], r.front);\n----\n */\ntemplate hasSwappableElements(R)\n{\n    import std.algorithm.mutation : swap;\n    enum bool hasSwappableElements = isInputRange!R\n        && is(typeof((ref R r) => swap(r.front, r.front)))\n        && (!isBidirectionalRange!R\n            || is(typeof((ref R r) => swap(r.back, r.front))))\n        && (!isRandomAccessRange!R\n            || is(typeof((ref R r) => swap(r[0], r.front))));\n}\n\n///\n@safe unittest\n{\n    static assert(!hasSwappableElements!(const int[]));\n    static assert(!hasSwappableElements!(const(int)[]));\n    static assert(!hasSwappableElements!(inout(int)[]));\n    static assert( hasSwappableElements!(int[]));\n\n    static assert(!hasSwappableElements!( string));\n    static assert(!hasSwappableElements!(dstring));\n    static assert(!hasSwappableElements!( char[]));\n    static assert( hasSwappableElements!(dchar[]));\n}\n\n/**\nReturns `true` if `R` is an input range and has mutable\nelements. The following code should compile for any range\nwith assignable elements.\n\n----\nR r;\nstatic assert(isInputRange!R);\nr.front = r.front;\nstatic if (isBidirectionalRange!R) r.back = r.front;\nstatic if (isRandomAccessRange!R) r[0] = r.front;\n----\n */\nenum bool hasAssignableElements(R) = isInputRange!R\n    && is(typeof(lvalueOf!R.front = lvalueOf!R.front))\n    && (!isBidirectionalRange!R\n        || is(typeof(lvalueOf!R.back = lvalueOf!R.back)))\n    && (!isRandomAccessRange!R\n        || is(typeof(lvalueOf!R[0] = lvalueOf!R.front)));\n\n///\n@safe unittest\n{\n    static assert(!hasAssignableElements!(const int[]));\n    static assert(!hasAssignableElements!(const(int)[]));\n    static assert( hasAssignableElements!(int[]));\n    static assert(!hasAssignableElements!(inout(int)[]));\n\n    static assert(!hasAssignableElements!( string));\n    static assert(!hasAssignableElements!(dstring));\n    static assert(!hasAssignableElements!( char[]));\n    static assert( hasAssignableElements!(dchar[]));\n}\n\n/**\nTests whether the range `R` has lvalue elements. These are defined as\nelements that can be passed by reference and have their address taken.\nThe following code should compile for any range with lvalue elements.\n----\nvoid passByRef(ref ElementType!R stuff);\n...\nstatic assert(isInputRange!R);\npassByRef(r.front);\nstatic if (isBidirectionalRange!R) passByRef(r.back);\nstatic if (isRandomAccessRange!R) passByRef(r[0]);\n----\n*/\nenum bool hasLvalueElements(R) = isInputRange!R\n    && is(typeof(((ref x) => x)(lvalueOf!R.front)))\n    && (!isBidirectionalRange!R\n        || is(typeof(((ref x) => x)(lvalueOf!R.back))))\n    && (!isRandomAccessRange!R\n        || is(typeof(((ref x) => x)(lvalueOf!R[0]))));\n\n///\n@safe unittest\n{\n    import std.range : iota, chain;\n\n    static assert( hasLvalueElements!(int[]));\n    static assert( hasLvalueElements!(const(int)[]));\n    static assert( hasLvalueElements!(inout(int)[]));\n    static assert( hasLvalueElements!(immutable(int)[]));\n    static assert(!hasLvalueElements!(typeof(iota(3))));\n\n    static assert(!hasLvalueElements!( string));\n    static assert( hasLvalueElements!(dstring));\n    static assert(!hasLvalueElements!( char[]));\n    static assert( hasLvalueElements!(dchar[]));\n\n    auto c = chain([1, 2, 3], [4, 5, 6]);\n    static assert( hasLvalueElements!(typeof(c)));\n}\n\n@safe unittest\n{\n    // bugfix 6336\n    struct S { immutable int value; }\n    static assert( isInputRange!(S[]));\n    static assert( hasLvalueElements!(S[]));\n}\n\n/**\nYields `true` if `R` has a `length` member that returns a value of `size_t`\ntype. `R` does not have to be a range. If `R` is a range, algorithms in the\nstandard library are only guaranteed to support `length` with type `size_t`.\n\nNote that `length` is an optional primitive as no range must implement it. Some\nranges do not store their length explicitly, some cannot compute it without\nactually exhausting the range (e.g. socket streams), and some other ranges may\nbe infinite.\n\nAlthough narrow string types (`char[]`, `wchar[]`, and their qualified\nderivatives) do define a `length` property, `hasLength` yields `false` for them.\nThis is because a narrow string's length does not reflect the number of\ncharacters, but instead the number of encoding units, and as such is not useful\nwith range-oriented algorithms. To use strings as random-access ranges with\nlength, use $(REF representation, std, string) or $(REF byCodeUnit, std, utf).\n*/\ntemplate hasLength(R)\n{\n    static if (is(typeof(((R* r) => r.length)(null)) Length))\n        enum bool hasLength = is(Length == size_t) && !isNarrowString!R;\n    else\n        enum bool hasLength = false;\n}\n\n///\n@safe unittest\n{\n    static assert(!hasLength!(char[]));\n    static assert( hasLength!(int[]));\n    static assert( hasLength!(inout(int)[]));\n\n    struct A { size_t length() { return 0; } }\n    struct B { @property size_t length() { return 0; } }\n    static assert( hasLength!(A));\n    static assert( hasLength!(B));\n}\n\n// test combinations which are invalid on some platforms\n@safe unittest\n{\n    struct A { ulong length; }\n    struct B { @property uint length() { return 0; } }\n\n    version (X86)\n    {\n        static assert(!hasLength!(A));\n        static assert(hasLength!(B));\n    }\n    else version (X86_64)\n    {\n        static assert(hasLength!(A));\n        static assert(!hasLength!(B));\n    }\n}\n\n// test combinations which are invalid on all platforms\n@safe unittest\n{\n    struct A { long length; }\n    struct B { int length; }\n    struct C { ubyte length; }\n    struct D { char length; }\n    static assert(!hasLength!(A));\n    static assert(!hasLength!(B));\n    static assert(!hasLength!(C));\n    static assert(!hasLength!(D));\n}\n\n/**\nReturns `true` if `R` is an infinite input range. An\ninfinite input range is an input range that has a statically-defined\nenumerated member called `empty` that is always `false`,\nfor example:\n\n----\nstruct MyInfiniteRange\n{\n    enum bool empty = false;\n    ...\n}\n----\n */\n\ntemplate isInfinite(R)\n{\n    static if (isInputRange!R && __traits(compiles, { enum e = R.empty; }))\n        enum bool isInfinite = !R.empty;\n    else\n        enum bool isInfinite = false;\n}\n\n///\n@safe unittest\n{\n    import std.range : Repeat;\n    static assert(!isInfinite!(int[]));\n    static assert( isInfinite!(Repeat!(int)));\n}\n\n/**\nReturns `true` if `R` offers a slicing operator with integral boundaries\nthat returns a forward range type.\n\nFor finite ranges, the result of `opSlice` must be of the same type as the\noriginal range type. If the range defines `opDollar`, then it must support\nsubtraction.\n\nFor infinite ranges, when $(I not) using `opDollar`, the result of\n`opSlice` must be the result of $(LREF take) or $(LREF takeExactly) on the\noriginal range (they both return the same type for infinite ranges). However,\nwhen using `opDollar`, the result of `opSlice` must be that of the\noriginal range type.\n\nThe following expression must be true for `hasSlicing` to be `true`:\n\n----\n    isForwardRange!R\n    && !isNarrowString!R\n    && is(ReturnType!((R r) => r[1 .. 1].length) == size_t)\n    && (is(typeof(lvalueOf!R[1 .. 1]) == R) || isInfinite!R)\n    && (!is(typeof(lvalueOf!R[0 .. $])) || is(typeof(lvalueOf!R[0 .. $]) == R))\n    && (!is(typeof(lvalueOf!R[0 .. $])) || isInfinite!R\n        || is(typeof(lvalueOf!R[0 .. $ - 1]) == R))\n    && is(typeof((ref R r)\n    {\n        static assert(isForwardRange!(typeof(r[1 .. 2])));\n    }));\n----\n */\nenum bool hasSlicing(R) = isForwardRange!R\n    && !isNarrowString!R\n    && is(ReturnType!((R r) => r[1 .. 1].length) == size_t)\n    && (is(typeof(lvalueOf!R[1 .. 1]) == R) || isInfinite!R)\n    && (!is(typeof(lvalueOf!R[0 .. $])) || is(typeof(lvalueOf!R[0 .. $]) == R))\n    && (!is(typeof(lvalueOf!R[0 .. $])) || isInfinite!R\n        || is(typeof(lvalueOf!R[0 .. $ - 1]) == R))\n    && is(typeof((ref R r)\n    {\n        static assert(isForwardRange!(typeof(r[1 .. 2])));\n    }));\n\n///\n@safe unittest\n{\n    import std.range : takeExactly;\n    static assert( hasSlicing!(int[]));\n    static assert( hasSlicing!(const(int)[]));\n    static assert(!hasSlicing!(const int[]));\n    static assert( hasSlicing!(inout(int)[]));\n    static assert(!hasSlicing!(inout int []));\n    static assert( hasSlicing!(immutable(int)[]));\n    static assert(!hasSlicing!(immutable int[]));\n    static assert(!hasSlicing!string);\n    static assert( hasSlicing!dstring);\n\n    enum rangeFuncs = \"@property int front();\" ~\n                      \"void popFront();\" ~\n                      \"@property bool empty();\" ~\n                      \"@property auto save() { return this; }\" ~\n                      \"@property size_t length();\";\n\n    struct A { mixin(rangeFuncs); int opSlice(size_t, size_t); }\n    struct B { mixin(rangeFuncs); B opSlice(size_t, size_t); }\n    struct C { mixin(rangeFuncs); @disable this(); C opSlice(size_t, size_t); }\n    struct D { mixin(rangeFuncs); int[] opSlice(size_t, size_t); }\n    static assert(!hasSlicing!(A));\n    static assert( hasSlicing!(B));\n    static assert( hasSlicing!(C));\n    static assert(!hasSlicing!(D));\n\n    struct InfOnes\n    {\n        enum empty = false;\n        void popFront() {}\n        @property int front() { return 1; }\n        @property InfOnes save() { return this; }\n        auto opSlice(size_t i, size_t j) { return takeExactly(this, j - i); }\n        auto opSlice(size_t i, Dollar d) { return this; }\n\n        struct Dollar {}\n        Dollar opDollar() const { return Dollar.init; }\n    }\n\n    static assert(hasSlicing!InfOnes);\n}\n\n/**\nThis is a best-effort implementation of `length` for any kind of\nrange.\n\nIf `hasLength!Range`, simply returns `range.length` without\nchecking `upTo` (when specified).\n\nOtherwise, walks the range through its length and returns the number\nof elements seen. Performes $(BIGOH n) evaluations of `range.empty`\nand `range.popFront()`, where `n` is the effective length of $(D\nrange).\n\nThe `upTo` parameter is useful to \"cut the losses\" in case\nthe interest is in seeing whether the range has at least some number\nof elements. If the parameter `upTo` is specified, stops if $(D\nupTo) steps have been taken and returns `upTo`.\n\nInfinite ranges are compatible, provided the parameter `upTo` is\nspecified, in which case the implementation simply returns upTo.\n */\nauto walkLength(Range)(Range range)\nif (isInputRange!Range && !isInfinite!Range)\n{\n    static if (hasLength!Range)\n        return range.length;\n    else\n    {\n        size_t result;\n        for ( ; !range.empty ; range.popFront() )\n            ++result;\n        return result;\n    }\n}\n/// ditto\nauto walkLength(Range)(Range range, const size_t upTo)\nif (isInputRange!Range)\n{\n    static if (hasLength!Range)\n        return range.length;\n    else static if (isInfinite!Range)\n        return upTo;\n    else\n    {\n        size_t result;\n        for ( ; result < upTo && !range.empty ; range.popFront() )\n            ++result;\n        return result;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.range : iota;\n\n    assert(10.iota.walkLength == 10);\n    // iota has a length function, and therefore the\n    // doesn't have to be walked, and the upTo\n    // parameter is ignored\n    assert(10.iota.walkLength(5) == 10);\n}\n\n@safe unittest\n{\n    import std.algorithm.iteration : filter;\n    import std.range : recurrence, take;\n\n    //hasLength Range\n    int[] a = [ 1, 2, 3 ];\n    assert(walkLength(a) == 3);\n    assert(walkLength(a, 0) == 3);\n    assert(walkLength(a, 2) == 3);\n    assert(walkLength(a, 4) == 3);\n\n    //Forward Range\n    auto b = filter!\"true\"([1, 2, 3, 4]);\n    assert(b.walkLength() == 4);\n    assert(b.walkLength(0) == 0);\n    assert(b.walkLength(2) == 2);\n    assert(b.walkLength(4) == 4);\n    assert(b.walkLength(6) == 4);\n\n    //Infinite Range\n    auto fibs = recurrence!\"a[n-1] + a[n-2]\"(1, 1);\n    assert(!__traits(compiles, fibs.walkLength()));\n    assert(fibs.take(10).walkLength() == 10);\n    assert(fibs.walkLength(55) == 55);\n}\n\n/**\n    `popFrontN` eagerly advances `r` itself (not a copy) up to `n` times\n    (by calling `r.popFront`). `popFrontN` takes `r` by `ref`,\n    so it mutates the original range. Completes in $(BIGOH 1) steps for ranges\n    that support slicing and have length.\n    Completes in $(BIGOH n) time for all other ranges.\n\n    `popBackN` behaves the same as `popFrontN` but instead removes\n    elements from the back of the (bidirectional) range instead of the front.\n\n    Returns:\n    How much `r` was actually advanced, which may be less than `n` if\n    `r` did not have at least `n` elements.\n\n    See_Also: $(REF drop, std, range), $(REF dropBack, std, range)\n*/\nsize_t popFrontN(Range)(ref Range r, size_t n)\nif (isInputRange!Range)\n{\n    static if (hasLength!Range)\n    {\n        n = cast(size_t) (n < r.length ? n : r.length);\n    }\n\n    static if (hasSlicing!Range && is(typeof(r = r[n .. $])))\n    {\n        r = r[n .. $];\n    }\n    else static if (hasSlicing!Range && hasLength!Range) //TODO: Remove once hasSlicing forces opDollar.\n    {\n        r = r[n .. r.length];\n    }\n    else\n    {\n        static if (hasLength!Range)\n        {\n            foreach (i; 0 .. n)\n                r.popFront();\n        }\n        else\n        {\n            foreach (i; 0 .. n)\n            {\n                if (r.empty) return i;\n                r.popFront();\n            }\n        }\n    }\n    return n;\n}\n\n/// ditto\nsize_t popBackN(Range)(ref Range r, size_t n)\nif (isBidirectionalRange!Range)\n{\n    static if (hasLength!Range)\n    {\n        n = cast(size_t) (n < r.length ? n : r.length);\n    }\n\n    static if (hasSlicing!Range && is(typeof(r = r[0 .. $ - n])))\n    {\n        r = r[0 .. $ - n];\n    }\n    else static if (hasSlicing!Range && hasLength!Range) //TODO: Remove once hasSlicing forces opDollar.\n    {\n        r = r[0 .. r.length - n];\n    }\n    else\n    {\n        static if (hasLength!Range)\n        {\n            foreach (i; 0 .. n)\n                r.popBack();\n        }\n        else\n        {\n            foreach (i; 0 .. n)\n            {\n                if (r.empty) return i;\n                r.popBack();\n            }\n        }\n    }\n    return n;\n}\n\n///\n@safe unittest\n{\n    int[] a = [ 1, 2, 3, 4, 5 ];\n    a.popFrontN(2);\n    assert(a == [ 3, 4, 5 ]);\n    a.popFrontN(7);\n    assert(a == [ ]);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota;\n    auto LL = iota(1L, 7L);\n    auto r = popFrontN(LL, 2);\n    assert(equal(LL, [3L, 4L, 5L, 6L]));\n    assert(r == 2);\n}\n\n///\n@safe unittest\n{\n    int[] a = [ 1, 2, 3, 4, 5 ];\n    a.popBackN(2);\n    assert(a == [ 1, 2, 3 ]);\n    a.popBackN(7);\n    assert(a == [ ]);\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : iota;\n    auto LL = iota(1L, 7L);\n    auto r = popBackN(LL, 2);\n    assert(equal(LL, [1L, 2L, 3L, 4L]));\n    assert(r == 2);\n}\n\n/**\n    Eagerly advances `r` itself (not a copy) exactly `n` times (by\n    calling `r.popFront`). `popFrontExactly` takes `r` by `ref`,\n    so it mutates the original range. Completes in $(BIGOH 1) steps for ranges\n    that support slicing, and have either length or are infinite.\n    Completes in $(BIGOH n) time for all other ranges.\n\n    Note: Unlike $(LREF popFrontN), `popFrontExactly` will assume that the\n    range holds at least `n` elements. This makes `popFrontExactly`\n    faster than `popFrontN`, but it also means that if `range` does\n    not contain at least `n` elements, it will attempt to call `popFront`\n    on an empty range, which is undefined behavior. So, only use\n    `popFrontExactly` when it is guaranteed that `range` holds at least\n    `n` elements.\n\n    `popBackExactly` will behave the same but instead removes elements from\n    the back of the (bidirectional) range instead of the front.\n\n    See_Also: $(REF dropExactly, std, range), $(REF dropBackExactly, std, range)\n*/\nvoid popFrontExactly(Range)(ref Range r, size_t n)\nif (isInputRange!Range)\n{\n    static if (hasLength!Range)\n        assert(n <= r.length, \"range is smaller than amount of items to pop\");\n\n    static if (hasSlicing!Range && is(typeof(r = r[n .. $])))\n        r = r[n .. $];\n    else static if (hasSlicing!Range && hasLength!Range) //TODO: Remove once hasSlicing forces opDollar.\n        r = r[n .. r.length];\n    else\n        foreach (i; 0 .. n)\n            r.popFront();\n}\n\n/// ditto\nvoid popBackExactly(Range)(ref Range r, size_t n)\nif (isBidirectionalRange!Range)\n{\n    static if (hasLength!Range)\n        assert(n <= r.length, \"range is smaller than amount of items to pop\");\n\n    static if (hasSlicing!Range && is(typeof(r = r[0 .. $ - n])))\n        r = r[0 .. $ - n];\n    else static if (hasSlicing!Range && hasLength!Range) //TODO: Remove once hasSlicing forces opDollar.\n        r = r[0 .. r.length - n];\n    else\n        foreach (i; 0 .. n)\n            r.popBack();\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filterBidirectional;\n\n    auto a = [1, 2, 3];\n    a.popFrontExactly(1);\n    assert(a == [2, 3]);\n    a.popBackExactly(1);\n    assert(a == [2]);\n\n    string s = \"日本語\";\n    s.popFrontExactly(1);\n    assert(s == \"本語\");\n    s.popBackExactly(1);\n    assert(s == \"本\");\n\n    auto bd = filterBidirectional!\"true\"([1, 2, 3]);\n    bd.popFrontExactly(1);\n    assert(bd.equal([2, 3]));\n    bd.popBackExactly(1);\n    assert(bd.equal([2]));\n}\n\n/**\n   Moves the front of `r` out and returns it. Leaves `r.front` in a\n   destroyable state that does not allocate any resources (usually equal\n   to its `.init` value).\n*/\nElementType!R moveFront(R)(R r)\n{\n    static if (is(typeof(&r.moveFront)))\n    {\n        return r.moveFront();\n    }\n    else static if (!hasElaborateCopyConstructor!(ElementType!R))\n    {\n        return r.front;\n    }\n    else static if (is(typeof(&(r.front())) == ElementType!R*))\n    {\n        import std.algorithm.mutation : move;\n        return move(r.front);\n    }\n    else\n    {\n        static assert(0,\n                \"Cannot move front of a range with a postblit and an rvalue front.\");\n    }\n}\n\n///\n@safe unittest\n{\n    auto a = [ 1, 2, 3 ];\n    assert(moveFront(a) == 1);\n    assert(a.length == 3);\n\n    // define a perfunctory input range\n    struct InputRange\n    {\n        enum bool empty = false;\n        enum int front = 7;\n        void popFront() {}\n        int moveFront() { return 43; }\n    }\n    InputRange r;\n    // calls r.moveFront\n    assert(moveFront(r) == 43);\n}\n\n@safe unittest\n{\n    struct R\n    {\n        @property ref int front() { static int x = 42; return x; }\n        this(this){}\n    }\n    R r;\n    assert(moveFront(r) == 42);\n}\n\n/**\n   Moves the back of `r` out and returns it. Leaves `r.back` in a\n   destroyable state that does not allocate any resources (usually equal\n   to its `.init` value).\n*/\nElementType!R moveBack(R)(R r)\n{\n    static if (is(typeof(&r.moveBack)))\n    {\n        return r.moveBack();\n    }\n    else static if (!hasElaborateCopyConstructor!(ElementType!R))\n    {\n        return r.back;\n    }\n    else static if (is(typeof(&(r.back())) == ElementType!R*))\n    {\n        import std.algorithm.mutation : move;\n        return move(r.back);\n    }\n    else\n    {\n        static assert(0,\n                \"Cannot move back of a range with a postblit and an rvalue back.\");\n    }\n}\n\n///\n@safe unittest\n{\n    struct TestRange\n    {\n        int payload = 5;\n        @property bool empty() { return false; }\n        @property TestRange save() { return this; }\n        @property ref int front() return { return payload; }\n        @property ref int back() return { return payload; }\n        void popFront() { }\n        void popBack() { }\n    }\n    static assert(isBidirectionalRange!TestRange);\n    TestRange r;\n    auto x = moveBack(r);\n    assert(x == 5);\n}\n\n/**\n   Moves element at index `i` of `r` out and returns it. Leaves $(D\n   r[i]) in a destroyable state that does not allocate any resources\n   (usually equal to its `.init` value).\n*/\nElementType!R moveAt(R)(R r, size_t i)\n{\n    static if (is(typeof(&r.moveAt)))\n    {\n        return r.moveAt(i);\n    }\n    else static if (!hasElaborateCopyConstructor!(ElementType!(R)))\n    {\n        return r[i];\n    }\n    else static if (is(typeof(&r[i]) == ElementType!R*))\n    {\n        import std.algorithm.mutation : move;\n        return move(r[i]);\n    }\n    else\n    {\n        static assert(0,\n                \"Cannot move element of a range with a postblit and rvalue elements.\");\n    }\n}\n\n///\n@safe unittest\n{\n    auto a = [1,2,3,4];\n    foreach (idx, it; a)\n    {\n        assert(it == moveAt(a, idx));\n    }\n}\n\n@safe unittest\n{\n    import std.internal.test.dummyrange;\n\n    foreach (DummyType; AllDummyRanges)\n    {\n        auto d = DummyType.init;\n        assert(moveFront(d) == 1);\n\n        static if (isBidirectionalRange!DummyType)\n        {\n            assert(moveBack(d) == 10);\n        }\n\n        static if (isRandomAccessRange!DummyType)\n        {\n            assert(moveAt(d, 2) == 3);\n        }\n    }\n}\n\n/**\nImplements the range interface primitive `empty` for types that\nobey $(LREF hasLength) property and for narrow strings. Due to the\nfact that nonmember functions can be called with the first argument\nusing the dot notation, `a.empty` is equivalent to `empty(a)`.\n */\n@property bool empty(T)(auto ref scope const(T) a)\nif (is(typeof(a.length) : size_t) || isNarrowString!T)\n{\n    return !a.length;\n}\n\n///\n@safe pure nothrow unittest\n{\n    auto a = [ 1, 2, 3 ];\n    assert(!a.empty);\n    assert(a[3 .. $].empty);\n\n    int[string] b;\n    assert(b.empty);\n    b[\"zero\"] = 0;\n    assert(!b.empty);\n}\n\n/**\nImplements the range interface primitive `save` for built-in\narrays. Due to the fact that nonmember functions can be called with\nthe first argument using the dot notation, `array.save` is\nequivalent to `save(array)`. The function does not duplicate the\ncontent of the array, it simply returns its argument.\n */\n@property T[] save(T)(T[] a) @safe pure nothrow @nogc\n{\n    return a;\n}\n\n///\n@safe pure nothrow unittest\n{\n    auto a = [ 1, 2, 3 ];\n    auto b = a.save;\n    assert(b is a);\n}\n\n/**\nImplements the range interface primitive `popFront` for built-in\narrays. Due to the fact that nonmember functions can be called with\nthe first argument using the dot notation, `array.popFront` is\nequivalent to `popFront(array)`. For $(GLOSSARY narrow strings),\n`popFront` automatically advances to the next $(GLOSSARY code\npoint).\n*/\nvoid popFront(T)(ref T[] a) @safe pure nothrow @nogc\nif (!isNarrowString!(T[]) && !is(T[] == void[]))\n{\n    assert(a.length, \"Attempting to popFront() past the end of an array of \" ~ T.stringof);\n    a = a[1 .. $];\n}\n\n///\n@safe pure nothrow unittest\n{\n    auto a = [ 1, 2, 3 ];\n    a.popFront();\n    assert(a == [ 2, 3 ]);\n}\n\n@safe unittest\n{\n    static assert(!is(typeof({          int[4] a; popFront(a); })));\n    static assert(!is(typeof({ immutable int[] a; popFront(a); })));\n    static assert(!is(typeof({          void[] a; popFront(a); })));\n}\n\n/// ditto\nvoid popFront(C)(ref C[] str) @trusted pure nothrow\nif (isNarrowString!(C[]))\n{\n    import std.algorithm.comparison : min;\n\n    assert(str.length, \"Attempting to popFront() past the end of an array of \" ~ C.stringof);\n\n    static if (is(Unqual!C == char))\n    {\n        static immutable ubyte[] charWidthTab = [\n            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n            4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1\n        ];\n\n        immutable c = str[0];\n        if (c < 192)\n        {\n            str = str.ptr[1 .. str.length];\n        }\n        else\n        {\n            str = str.ptr[min(str.length, charWidthTab.ptr[c - 192]) .. str.length];\n        }\n\n    }\n    else static if (is(Unqual!C == wchar))\n    {\n        immutable u = str[0];\n        immutable seqLen = 1 + (u >= 0xD800 && u <= 0xDBFF);\n        str = str.ptr[min(seqLen, str.length) .. str.length];\n    }\n    else static assert(0, \"Bad template constraint.\");\n}\n\n@safe pure unittest\n{\n    import std.meta : AliasSeq;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        S s = \"\\xC2\\xA9hello\";\n        s.popFront();\n        assert(s == \"hello\");\n\n        S str = \"hello\\U00010143\\u0100\\U00010143\";\n        foreach (dchar c; ['h', 'e', 'l', 'l', 'o', '\\U00010143', '\\u0100', '\\U00010143'])\n        {\n            assert(str.front == c);\n            str.popFront();\n        }\n        assert(str.empty);\n\n        static assert(!is(typeof({          immutable S a; popFront(a); })));\n        static assert(!is(typeof({ typeof(S.init[0])[4] a; popFront(a); })));\n    }}\n\n    C[] _eatString(C)(C[] str)\n    {\n        while (!str.empty)\n            str.popFront();\n\n        return str;\n    }\n    enum checkCTFE = _eatString(\"ウェブサイト@La_Verité.com\");\n    static assert(checkCTFE.empty);\n    enum checkCTFEW = _eatString(\"ウェブサイト@La_Verité.com\"w);\n    static assert(checkCTFEW.empty);\n}\n\n@safe unittest // issue 16090\n{\n    string s = \"\\u00E4\";\n    assert(s.length == 2);\n    s = s[0 .. 1];\n    assert(s.length == 1);\n    s.popFront;\n    assert(s.empty);\n}\n\n@safe unittest\n{\n    wstring s = \"\\U00010000\";\n    assert(s.length == 2);\n    s = s[0 .. 1];\n    assert(s.length == 1);\n    s.popFront;\n    assert(s.empty);\n}\n\n/**\nImplements the range interface primitive `popBack` for built-in\narrays. Due to the fact that nonmember functions can be called with\nthe first argument using the dot notation, `array.popBack` is\nequivalent to `popBack(array)`. For $(GLOSSARY narrow strings), $(D\npopFront) automatically eliminates the last $(GLOSSARY code point).\n*/\nvoid popBack(T)(ref T[] a) @safe pure nothrow @nogc\nif (!isNarrowString!(T[]) && !is(T[] == void[]))\n{\n    assert(a.length);\n    a = a[0 .. $ - 1];\n}\n\n///\n@safe pure nothrow unittest\n{\n    auto a = [ 1, 2, 3 ];\n    a.popBack();\n    assert(a == [ 1, 2 ]);\n}\n\n@safe unittest\n{\n    static assert(!is(typeof({ immutable int[] a; popBack(a); })));\n    static assert(!is(typeof({          int[4] a; popBack(a); })));\n    static assert(!is(typeof({          void[] a; popBack(a); })));\n}\n\n/// ditto\nvoid popBack(T)(ref T[] a) @safe pure\nif (isNarrowString!(T[]))\n{\n    import std.utf : strideBack;\n    assert(a.length, \"Attempting to popBack() past the front of an array of \" ~ T.stringof);\n    a = a[0 .. $ - strideBack(a, $)];\n}\n\n@safe pure unittest\n{\n    import std.meta : AliasSeq;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        S s = \"hello\\xE2\\x89\\xA0\";\n        s.popBack();\n        assert(s == \"hello\");\n        S s3 = \"\\xE2\\x89\\xA0\";\n        auto c = s3.back;\n        assert(c == cast(dchar)'\\u2260');\n        s3.popBack();\n        assert(s3 == \"\");\n\n        S str = \"\\U00010143\\u0100\\U00010143hello\";\n        foreach (dchar ch; ['o', 'l', 'l', 'e', 'h', '\\U00010143', '\\u0100', '\\U00010143'])\n        {\n            assert(str.back == ch);\n            str.popBack();\n        }\n        assert(str.empty);\n\n        static assert(!is(typeof({          immutable S a; popBack(a); })));\n        static assert(!is(typeof({ typeof(S.init[0])[4] a; popBack(a); })));\n    }}\n}\n\n/**\nImplements the range interface primitive `front` for built-in\narrays. Due to the fact that nonmember functions can be called with\nthe first argument using the dot notation, `array.front` is\nequivalent to `front(array)`. For $(GLOSSARY narrow strings), $(D\nfront) automatically returns the first $(GLOSSARY code point) as _a $(D\ndchar).\n*/\n@property ref T front(T)(T[] a) @safe pure nothrow @nogc\nif (!isNarrowString!(T[]) && !is(T[] == void[]))\n{\n    assert(a.length, \"Attempting to fetch the front of an empty array of \" ~ T.stringof);\n    return a[0];\n}\n\n///\n@safe pure nothrow unittest\n{\n    int[] a = [ 1, 2, 3 ];\n    assert(a.front == 1);\n}\n\n@safe pure nothrow unittest\n{\n    auto a = [ 1, 2 ];\n    a.front = 4;\n    assert(a.front == 4);\n    assert(a == [ 4, 2 ]);\n\n    immutable b = [ 1, 2 ];\n    assert(b.front == 1);\n\n    int[2] c = [ 1, 2 ];\n    assert(c.front == 1);\n}\n\n/// ditto\n@property dchar front(T)(T[] a) @safe pure\nif (isNarrowString!(T[]))\n{\n    import std.utf : decode;\n    assert(a.length, \"Attempting to fetch the front of an empty array of \" ~ T.stringof);\n    size_t i = 0;\n    return decode(a, i);\n}\n\n/**\nImplements the range interface primitive `back` for built-in\narrays. Due to the fact that nonmember functions can be called with\nthe first argument using the dot notation, `array.back` is\nequivalent to `back(array)`. For $(GLOSSARY narrow strings), $(D\nback) automatically returns the last $(GLOSSARY code point) as _a $(D\ndchar).\n*/\n@property ref T back(T)(T[] a) @safe pure nothrow @nogc\nif (!isNarrowString!(T[]) && !is(T[] == void[]))\n{\n    assert(a.length, \"Attempting to fetch the back of an empty array of \" ~ T.stringof);\n    return a[$ - 1];\n}\n\n///\n@safe pure nothrow unittest\n{\n    int[] a = [ 1, 2, 3 ];\n    assert(a.back == 3);\n    a.back += 4;\n    assert(a.back == 7);\n}\n\n@safe pure nothrow unittest\n{\n    immutable b = [ 1, 2, 3 ];\n    assert(b.back == 3);\n\n    int[3] c = [ 1, 2, 3 ];\n    assert(c.back == 3);\n}\n\n/// ditto\n// Specialization for strings\n@property dchar back(T)(T[] a) @safe pure\nif (isNarrowString!(T[]))\n{\n    import std.utf : decode, strideBack;\n    assert(a.length, \"Attempting to fetch the back of an empty array of \" ~ T.stringof);\n    size_t i = a.length - strideBack(a, a.length);\n    return decode(a, i);\n}\n"
  },
  {
    "path": "libphobos/src/std/regex/internal/backtracking.d",
    "content": "/*\n    Implementation of backtracking std.regex engine.\n    Contains both compile-time and run-time versions.\n*/\nmodule std.regex.internal.backtracking;\n\npackage(std.regex):\n\nimport core.stdc.stdlib, std.range.primitives, std.traits, std.typecons;\nimport std.regex.internal.ir;\n\n/+\n    BacktrackingMatcher implements backtracking scheme of matching\n    regular expressions.\n+/\n@trusted class BacktrackingMatcher(Char, Stream = Input!Char) : Matcher!Char\nif (is(Char : dchar))\n{\n    alias DataIndex = Stream.DataIndex;\n    struct State\n    {//top bit in pc is set if saved along with matches\n        DataIndex index;\n        uint pc, counter, infiniteNesting;\n    }\n    static assert(State.sizeof % size_t.sizeof == 0);\n    enum stateSize = State.sizeof / size_t.sizeof;\n    enum initialStack = 1 << 11; // items in a block of segmented stack\n    alias String = const(Char)[];\n    alias RegEx = Regex!Char;\n    alias MatchFn = bool function (BacktrackingMatcher);\n    const RegEx re;         // regex program\n    MatchFn nativeFn; // native code for that program\n    // Stream state\n    Stream s;\n    DataIndex index;\n    dchar front;\n    bool exhausted;\n    // Backtracking machine state\n    uint pc, counter;\n    DataIndex lastState = 0;    // Top of state stack\n    uint infiniteNesting;\n    size_t[] memory;\n    Trace[]  merge;\n    static struct Trace\n    {\n        ulong mask;\n        size_t offset;\n\n        bool mark(size_t idx)\n        {\n            immutable d = idx - offset;\n            if (d < 64) // including overflow\n            {\n                immutable p = mask & (1UL << d);\n                mask |= 1UL << d;\n                return p != 0;\n            }\n            else\n            {\n                offset = idx;\n                mask = 1;\n                return false;\n            }\n        }\n    }\n    //local slice of matches, global for backref\n    Group!DataIndex[] matches, backrefed;\n    size_t _refCount;\nfinal:\n\n    override @property ref size_t refCount() { return _refCount; }\n    override @property ref const(RegEx) pattern(){ return re; }\n\n    static if (__traits(hasMember,Stream, \"search\"))\n    {\n        enum kicked = true;\n    }\n    else\n        enum kicked = false;\n\n    static size_t initialMemory(const ref RegEx re)\n    {\n        return stackSize(re)*size_t.sizeof + re.hotspotTableSize*Trace.sizeof;\n    }\n\n    static size_t stackSize(const ref RegEx re)\n    {\n        size_t itemSize = stateSize\n            + re.ngroup * (Group!DataIndex).sizeof / size_t.sizeof;\n        return initialStack * itemSize + 2;\n    }\n\n    @property bool atStart(){ return index == 0; }\n\n    @property bool atEnd(){ return index == s.lastIndex && s.atEnd; }\n\n    void next()\n    {\n        if (!s.nextChar(front, index))\n            index = s.lastIndex;\n    }\n\n    void search()\n    {\n        static if (kicked)\n        {\n            if (!s.search(re.kickstart, front, index))\n            {\n                index = s.lastIndex;\n            }\n        }\n        else\n            next();\n    }\n\n    //\n    void newStack()\n    {\n        auto chunk = mallocArray!(size_t)(stackSize(re));\n        chunk[0] = cast(size_t)(memory.ptr);\n        chunk[1] = lastState;\n        memory = chunk[2..$];\n        lastState = 0;\n    }\n\n    bool prevStack()\n    {\n        // pointer to previous block\n        size_t* prev = cast(size_t*) memory.ptr[-2];\n        if (!prev)\n        {\n            // The last segment is freed in RegexMatch\n            return false;\n        }\n        else\n        {\n            import core.stdc.stdlib : free;\n            // memory used in previous block\n            size_t size = memory.ptr[-1];\n            free(memory.ptr-2);\n            memory = prev[0 .. size];\n            lastState = size;\n            return true;\n        }\n    }\n\n    void initExternalMemory(void[] memBlock)\n    {\n        merge = arrayInChunk!(Trace)(re.hotspotTableSize, memBlock);\n        merge[] = Trace.init;\n        memory = cast(size_t[]) memBlock;\n        memory[0] = 0; // hidden pointer\n        memory[1] = 0; // used size\n        memory = memory[2..$];\n    }\n\n    void initialize(ref const RegEx program, Stream stream, void[] memBlock)\n    {\n        s = stream;\n        exhausted = false;\n        initExternalMemory(memBlock);\n        backrefed = null;\n    }\n\n    override void dupTo(Matcher!Char m, void[] memBlock)\n    {\n        auto backtracking = cast(BacktrackingMatcher) m;\n        backtracking.s = s;\n        backtracking.front = front;\n        backtracking.index = index;\n        backtracking.exhausted = exhausted;\n        backtracking.initExternalMemory(memBlock);\n    }\n\n    override Matcher!Char rearm(in Char[] data)\n    {\n        merge[] = Trace.init;\n        exhausted = false;\n        s = Stream(data);\n        next();\n        return this;\n    }\n\n    this(ref const RegEx program, Stream stream, void[] memBlock, dchar ch, DataIndex idx)\n    {\n        _refCount = 1;\n        re = program;\n        nativeFn = null;\n        initialize(program, stream, memBlock);\n        front = ch;\n        index = idx;\n    }\n\n    this(ref const RegEx program, MatchFn func, Stream stream, void[] memBlock)\n    {\n        _refCount = 1;\n        re = program;\n        initialize(program, stream, memBlock);\n        nativeFn = func;\n        next();\n    }\n\n    this(ref const RegEx program, Stream stream, void[] memBlock)\n    {\n        _refCount = 1;\n        re = program;\n        nativeFn = null;\n        initialize(program, stream, memBlock);\n        next();\n    }\n\n    auto fwdMatcher(ref const RegEx re, void[] memBlock)\n    {\n        alias BackMatcher = BacktrackingMatcher!(Char, Stream);\n        auto fwdMatcher = new BackMatcher(re, s, memBlock, front, index);\n        return fwdMatcher;\n    }\n\n    auto bwdMatcher(ref const RegEx re, void[] memBlock)\n    {\n        alias BackMatcher = BacktrackingMatcher!(Char, typeof(s.loopBack(index)));\n        auto fwdMatcher =\n            new BackMatcher(re, s.loopBack(index), memBlock);\n        return fwdMatcher;\n    }\n\n    //\n    int matchFinalize()\n    {\n        immutable start = index;\n        immutable val = matchImpl();\n        if (val)\n        {//stream is updated here\n            matches[0].begin = start;\n            matches[0].end = index;\n            if (!(re.flags & RegexOption.global) || atEnd)\n                exhausted = true;\n            if (start == index)//empty match advances input\n                next();\n            return val;\n        }\n        else\n            return 0;\n    }\n\n    //lookup next match, fill matches with indices into input\n    override int match(Group!DataIndex[] matches)\n    {\n        debug(std_regex_matcher)\n        {\n            writeln(\"------------------------------------------\");\n        }\n        if (exhausted) //all matches collected\n            return false;\n        this.matches = matches;\n        if (re.flags & RegexInfo.oneShot)\n        {\n            exhausted = true;\n            const DataIndex start = index;\n            immutable m = matchImpl();\n            if (m)\n            {\n                matches[0].begin = start;\n                matches[0].end = index;\n            }\n            return m;\n        }\n        static if (kicked)\n        {\n            if (!re.kickstart.empty)\n            {\n                for (;;)\n                {\n                    immutable val = matchFinalize();\n                    if (val)\n                        return val;\n                    else\n                    {\n                        if (atEnd)\n                            break;\n                        search();\n                        if (atEnd)\n                        {\n                            exhausted = true;\n                            return matchFinalize();\n                        }\n                    }\n                }\n                exhausted = true;\n                return 0; //early return\n            }\n        }\n        //no search available - skip a char at a time\n        for (;;)\n        {\n            immutable val = matchFinalize();\n            if (val)\n                return val;\n            else\n            {\n                if (atEnd)\n                    break;\n                next();\n                if (atEnd)\n                {\n                    exhausted = true;\n                    return matchFinalize();\n                }\n            }\n        }\n        exhausted = true;\n        return 0;\n    }\n\n    /+\n        match subexpression against input,\n        results are stored in matches\n    +/\n    int matchImpl()\n    {\n        if (nativeFn)\n        {\n            debug(std_regex_ctr) writeln(\"using C-T matcher\");\n            return nativeFn(this);\n        }\n        else\n        {\n            pc = 0;\n            counter = 0;\n            lastState = 0;\n            infiniteNesting = 0;\n            matches[] = Group!DataIndex.init;\n            auto start = s._index;\n            debug(std_regex_matcher)\n                writeln(\"Try match starting at \", s[index .. s.lastIndex]);\n            for (;;)\n            {\n                debug(std_regex_matcher)\n                    writefln(\"PC: %s\\tCNT: %s\\t%s \\tfront: %s src: %s\",\n                        pc, counter, disassemble(re.ir, pc, re.dict),\n                        front, s._index);\n                switch (re.ir[pc].code)\n                {\n                case IR.OrChar://assumes IRL!(OrChar) == 1\n                    if (atEnd)\n                        goto L_backtrack;\n                    uint len = re.ir[pc].sequence;\n                    uint end = pc + len;\n                    if (re.ir[pc].data != front && re.ir[pc+1].data != front)\n                    {\n                        for (pc = pc+2; pc < end; pc++)\n                            if (re.ir[pc].data == front)\n                                break;\n                        if (pc == end)\n                            goto L_backtrack;\n                    }\n                    pc = end;\n                    next();\n                    break;\n                case IR.Char:\n                    if (atEnd || front != re.ir[pc].data)\n                        goto L_backtrack;\n                    pc += IRL!(IR.Char);\n                    next();\n                break;\n                case IR.Any:\n                    if (atEnd)\n                        goto L_backtrack;\n                    pc += IRL!(IR.Any);\n                    next();\n                    break;\n                case IR.CodepointSet:\n                    if (atEnd || !re.charsets[re.ir[pc].data].scanFor(front))\n                        goto L_backtrack;\n                    next();\n                    pc += IRL!(IR.CodepointSet);\n                    break;\n                case IR.Trie:\n                    if (atEnd || !re.matchers[re.ir[pc].data][front])\n                        goto L_backtrack;\n                    next();\n                    pc += IRL!(IR.Trie);\n                    break;\n                case IR.Wordboundary:\n                    dchar back;\n                    DataIndex bi;\n                    //at start & end of input\n                    if (atStart && wordMatcher[front])\n                    {\n                        pc += IRL!(IR.Wordboundary);\n                        break;\n                    }\n                    else if (atEnd && s.loopBack(index).nextChar(back, bi)\n                            && wordMatcher[back])\n                    {\n                        pc += IRL!(IR.Wordboundary);\n                        break;\n                    }\n                    else if (s.loopBack(index).nextChar(back, bi))\n                    {\n                        immutable af = wordMatcher[front];\n                        immutable ab = wordMatcher[back];\n                        if (af ^ ab)\n                        {\n                            pc += IRL!(IR.Wordboundary);\n                            break;\n                        }\n                    }\n                    goto L_backtrack;\n                case IR.Notwordboundary:\n                    dchar back;\n                    DataIndex bi;\n                    //at start & end of input\n                    if (atStart && wordMatcher[front])\n                        goto L_backtrack;\n                    else if (atEnd && s.loopBack(index).nextChar(back, bi)\n                            && wordMatcher[back])\n                        goto L_backtrack;\n                    else if (s.loopBack(index).nextChar(back, bi))\n                    {\n                        immutable af = wordMatcher[front];\n                        immutable ab = wordMatcher[back];\n                        if (af ^ ab)\n                            goto L_backtrack;\n                    }\n                    pc += IRL!(IR.Wordboundary);\n                    break;\n                case IR.Bof:\n                    if (atStart)\n                        pc += IRL!(IR.Bol);\n                    else\n                        goto L_backtrack;\n                    break;\n                case IR.Bol:\n                    dchar back;\n                    DataIndex bi;\n                    if (atStart)\n                        pc += IRL!(IR.Bol);\n                    else if (s.loopBack(index).nextChar(back,bi)\n                        && endOfLine(back, front == '\\n'))\n                    {\n                        pc += IRL!(IR.Bol);\n                    }\n                    else\n                        goto L_backtrack;\n                    break;\n                case IR.Eof:\n                    if (atEnd)\n                        pc += IRL!(IR.Eol);\n                    else\n                        goto L_backtrack;\n                    break;\n                case IR.Eol:\n                    dchar back;\n                    DataIndex bi;\n                    debug(std_regex_matcher) writefln(\"EOL (front 0x%x) %s\", front, s[index .. s.lastIndex]);\n                    //no matching inside \\r\\n\n                    if (atEnd || (endOfLine(front, s.loopBack(index).nextChar(back,bi)\n                            && back == '\\r')))\n                    {\n                        pc += IRL!(IR.Eol);\n                    }\n                    else\n                        goto L_backtrack;\n                    break;\n                case IR.InfiniteStart, IR.InfiniteQStart:\n                    pc += re.ir[pc].data + IRL!(IR.InfiniteStart);\n                    //now pc is at end IR.Infinite(Q)End\n                    uint len = re.ir[pc].data;\n                    if (re.ir[pc].code == IR.InfiniteEnd)\n                    {\n                        pushState(pc+IRL!(IR.InfiniteEnd), counter);\n                        pc -= len;\n                    }\n                    else\n                    {\n                        pushState(pc - len, counter);\n                        pc += IRL!(IR.InfiniteEnd);\n                    }\n                    break;\n                case IR.InfiniteBloomStart:\n                    pc += re.ir[pc].data + IRL!(IR.InfiniteBloomStart);\n                    //now pc is at end IR.InfiniteBloomEnd\n                    immutable len = re.ir[pc].data;\n                    immutable filterIdx = re.ir[pc+2].raw;\n                    if (re.filters[filterIdx][front])\n                        pushState(pc+IRL!(IR.InfiniteBloomEnd), counter);\n                    pc -= len;\n                    break;\n                case IR.RepeatStart, IR.RepeatQStart:\n                    pc += re.ir[pc].data + IRL!(IR.RepeatStart);\n                    break;\n                case IR.RepeatEnd:\n                case IR.RepeatQEnd:\n                    if (merge[re.ir[pc + 1].raw+counter].mark(index))\n                    {\n                        // merged!\n                        goto L_backtrack;\n                    }\n                    //len, step, min, max\n                    immutable len = re.ir[pc].data;\n                    immutable step =  re.ir[pc+2].raw;\n                    immutable min = re.ir[pc+3].raw;\n                    immutable max = re.ir[pc+4].raw;\n                    if (counter < min)\n                    {\n                        counter += step;\n                        pc -= len;\n                    }\n                    else if (counter < max)\n                    {\n                        if (re.ir[pc].code == IR.RepeatEnd)\n                        {\n                            pushState(pc + IRL!(IR.RepeatEnd), counter%step);\n                            counter += step;\n                            pc -= len;\n                        }\n                        else\n                        {\n                            pushState(pc - len, counter + step);\n                            counter = counter%step;\n                            pc += IRL!(IR.RepeatEnd);\n                        }\n                    }\n                    else\n                    {\n                        counter = counter%step;\n                        pc += IRL!(IR.RepeatEnd);\n                    }\n                    break;\n                case IR.InfiniteEnd:\n                case IR.InfiniteQEnd:\n                    debug(std_regex_matcher) writeln(\"Infinited nesting:\", infiniteNesting);\n                    if (merge[re.ir[pc + 1].raw+counter].mark(index))\n                    {\n                        // merged!\n                        goto L_backtrack;\n                    }\n                    immutable len = re.ir[pc].data;\n                    if (re.ir[pc].code == IR.InfiniteEnd)\n                    {\n                        pushState(pc + IRL!(IR.InfiniteEnd), counter);\n                        pc -= len;\n                    }\n                    else\n                    {\n                        pushState(pc-len, counter);\n                        pc += IRL!(IR.InfiniteEnd);\n                    }\n                    break;\n                case IR.InfiniteBloomEnd:\n                    debug(std_regex_matcher) writeln(\"Infinited nesting:\", infiniteNesting);\n                    if (merge[re.ir[pc + 1].raw+counter].mark(index))\n                    {\n                        // merged!\n                        goto L_backtrack;\n                    }\n                    immutable len = re.ir[pc].data;\n                    immutable filterIdx = re.ir[pc+2].raw;\n                    if (re.filters[filterIdx][front])\n                    {\n                        infiniteNesting--;\n                        pushState(pc + IRL!(IR.InfiniteBloomEnd), counter);\n                        infiniteNesting++;\n                    }\n                    pc -= len;\n                    break;\n                case IR.OrEnd:\n                    if (merge[re.ir[pc + 1].raw+counter].mark(index))\n                    {\n                        // merged!\n                        goto L_backtrack;\n                    }\n                    pc += IRL!(IR.OrEnd);\n                    break;\n                case IR.OrStart:\n                    pc += IRL!(IR.OrStart);\n                    goto case;\n                case IR.Option:\n                    immutable len = re.ir[pc].data;\n                    if (re.ir[pc+len].code == IR.GotoEndOr)//not a last one\n                    {\n                        pushState(pc + len + IRL!(IR.Option), counter); //remember 2nd branch\n                    }\n                    pc += IRL!(IR.Option);\n                    break;\n                case IR.GotoEndOr:\n                    pc = pc + re.ir[pc].data + IRL!(IR.GotoEndOr);\n                    break;\n                case IR.GroupStart:\n                    immutable n = re.ir[pc].data;\n                    matches[n].begin = index;\n                    debug(std_regex_matcher)  writefln(\"IR group #%u starts at %u\", n, index);\n                    pc += IRL!(IR.GroupStart);\n                    break;\n                case IR.GroupEnd:\n                    immutable n = re.ir[pc].data;\n                    matches[n].end = index;\n                    debug(std_regex_matcher) writefln(\"IR group #%u ends at %u\", n, index);\n                    pc += IRL!(IR.GroupEnd);\n                    break;\n                case IR.LookaheadStart:\n                case IR.NeglookaheadStart:\n                    immutable len = re.ir[pc].data;\n                    auto save = index;\n                    immutable ms = re.ir[pc+1].raw, me = re.ir[pc+2].raw;\n                    auto mem = malloc(initialMemory(re))[0 .. initialMemory(re)];\n                    scope(exit) free(mem.ptr);\n                    auto slicedRe = re.withCode(re.ir[\n                        pc+IRL!(IR.LookaheadStart) .. pc+IRL!(IR.LookaheadStart)+len+IRL!(IR.LookaheadEnd)\n                    ]);\n                    static if (Stream.isLoopback)\n                    {\n                        auto matcher = bwdMatcher(slicedRe, mem);\n                    }\n                    else\n                    {\n                        auto matcher = fwdMatcher(slicedRe, mem);\n                    }\n                    matcher.matches = matches[ms .. me];\n                    matcher.backrefed = backrefed.empty ? matches : backrefed;\n                    immutable match = (matcher.matchImpl() != 0) ^ (re.ir[pc].code == IR.NeglookaheadStart);\n                    s.reset(save);\n                    next();\n                    if (!match)\n                        goto L_backtrack;\n                    else\n                    {\n                        pc += IRL!(IR.LookaheadStart)+len+IRL!(IR.LookaheadEnd);\n                    }\n                    break;\n                case IR.LookbehindStart:\n                case IR.NeglookbehindStart:\n                    immutable len = re.ir[pc].data;\n                    immutable ms = re.ir[pc+1].raw, me = re.ir[pc+2].raw;\n                    auto mem = malloc(initialMemory(re))[0 .. initialMemory(re)];\n                    scope(exit) free(mem.ptr);\n                    auto slicedRe = re.withCode(re.ir[\n                        pc + IRL!(IR.LookbehindStart) .. pc + IRL!(IR.LookbehindStart) + len + IRL!(IR.LookbehindEnd)\n                    ]);\n                    static if (Stream.isLoopback)\n                    {\n                        alias Matcher = BacktrackingMatcher!(Char, Stream);\n                        auto matcher = new Matcher(slicedRe, s, mem, front, index);\n                    }\n                    else\n                    {\n                        alias Matcher = BacktrackingMatcher!(Char, typeof(s.loopBack(index)));\n                        auto matcher = new Matcher(slicedRe, s.loopBack(index), mem);\n                    }\n                    matcher.matches = matches[ms .. me];\n                    matcher.backrefed  = backrefed.empty ? matches : backrefed;\n                    immutable match = (matcher.matchImpl() != 0) ^ (re.ir[pc].code == IR.NeglookbehindStart);\n                    if (!match)\n                        goto L_backtrack;\n                    else\n                    {\n                        pc += IRL!(IR.LookbehindStart)+len+IRL!(IR.LookbehindEnd);\n                    }\n                    break;\n                case IR.Backref:\n                    immutable n = re.ir[pc].data;\n                    auto referenced = re.ir[pc].localRef\n                            ? s[matches[n].begin .. matches[n].end]\n                            : s[backrefed[n].begin .. backrefed[n].end];\n                    while (!atEnd && !referenced.empty && front == referenced.front)\n                    {\n                        next();\n                        referenced.popFront();\n                    }\n                    if (referenced.empty)\n                        pc++;\n                    else\n                        goto L_backtrack;\n                    break;\n                    case IR.Nop:\n                    pc += IRL!(IR.Nop);\n                    break;\n                case IR.LookaheadEnd:\n                case IR.NeglookaheadEnd:\n                case IR.LookbehindEnd:\n                case IR.NeglookbehindEnd:\n                case IR.End:\n                    // cleanup stale stack blocks if any\n                    while (prevStack()) {}\n                    return re.ir[pc].data;\n                default:\n                    debug printBytecode(re.ir[0..$]);\n                    assert(0);\n                L_backtrack:\n                    if (!popState())\n                    {\n                        s.reset(start);\n                        return 0;\n                    }\n                }\n            }\n        }\n        assert(0);\n    }\n\n    @property size_t stackAvail()\n    {\n        return memory.length - lastState;\n    }\n\n    void stackPush(T)(T val)\n        if (!isDynamicArray!T)\n    {\n        *cast(T*)&memory[lastState] = val;\n        enum delta = (T.sizeof+size_t.sizeof/2)/size_t.sizeof;\n        lastState += delta;\n        debug(std_regex_matcher) writeln(\"push element SP= \", lastState);\n    }\n\n    void stackPush(T)(T[] val)\n    {\n        static assert(T.sizeof % size_t.sizeof == 0);\n        (cast(T*)&memory[lastState])[0 .. val.length]\n            = val[0..$];\n        lastState += val.length*(T.sizeof/size_t.sizeof);\n        debug(std_regex_matcher) writeln(\"push array SP= \", lastState);\n    }\n\n    void stackPop(T)(ref T val)\n        if (!isDynamicArray!T)\n    {\n        enum delta = (T.sizeof+size_t.sizeof/2)/size_t.sizeof;\n        lastState -= delta;\n        val = *cast(T*)&memory[lastState];\n        debug(std_regex_matcher) writeln(\"pop element SP= \", lastState);\n    }\n\n    void stackPop(T)(T[] val)\n    {\n        stackPop(val);  // call ref version\n    }\n    void stackPop(T)(ref T[] val)\n    {\n        lastState -= val.length*(T.sizeof/size_t.sizeof);\n        val[0..$] = (cast(T*)&memory[lastState])[0 .. val.length];\n        debug(std_regex_matcher) writeln(\"pop array SP= \", lastState);\n    }\n    //helper function, saves engine state\n    void pushState(uint pc, uint counter)\n    {\n        if (stateSize + 2 * matches.length > stackAvail)\n        {\n            newStack();\n        }\n        *cast(State*)&memory[lastState] =\n            State(index, pc, counter, infiniteNesting);\n        lastState += stateSize;\n        memory[lastState .. lastState + 2 * matches.length] = (cast(size_t[]) matches)[];\n        lastState += 2*matches.length;\n        debug(std_regex_matcher)\n            writefln(\"Saved(pc=%s) front: %s src: %s\",\n                pc, front, s[index .. s.lastIndex]);\n    }\n\n    //helper function, restores engine state\n    bool popState()\n    {\n        if (!lastState && !prevStack())\n            return false;\n        lastState -= 2*matches.length;\n        auto pm = cast(size_t[]) matches;\n        pm[] = memory[lastState .. lastState + 2 * matches.length];\n        lastState -= stateSize;\n        State* state = cast(State*)&memory[lastState];\n        index = state.index;\n        pc = state.pc;\n        counter = state.counter;\n        infiniteNesting = state.infiniteNesting;\n        debug(std_regex_matcher)\n        {\n            writefln(\"Restored matches\", front, s[index .. s.lastIndex]);\n            foreach (i, m; matches)\n                writefln(\"Sub(%d) : %s..%s\", i, m.begin, m.end);\n        }\n        s.reset(index);\n        next();\n        debug(std_regex_matcher)\n            writefln(\"Backtracked (pc=%s) front: %s src: %s\",\n                pc, front, s[index .. s.lastIndex]);\n        return true;\n    }\n}\n\n//very shitty string formatter, $$ replaced with next argument converted to string\n@trusted string ctSub( U...)(string format, U args)\n{\n    import std.conv : to;\n    bool seenDollar;\n    foreach (i, ch; format)\n    {\n        if (ch == '$')\n        {\n            if (seenDollar)\n            {\n                static if (args.length > 0)\n                {\n                    return  format[0 .. i - 1] ~ to!string(args[0])\n                        ~ ctSub(format[i + 1 .. $], args[1 .. $]);\n                }\n                else\n                    assert(0);\n            }\n            else\n                seenDollar = true;\n        }\n        else\n            seenDollar = false;\n\n    }\n    return format;\n}\n\nstruct CtContext\n{\n    import std.conv : to, text;\n    //dirty flags\n    bool counter;\n    //to mark the portion of matches to save\n    int match, total_matches;\n    int reserved;\n    const(CodepointInterval)[][] charsets;\n\n\n    //state of codegenerator\n    static struct CtState\n    {\n        string code;\n        int addr;\n    }\n\n    this(Char)(ref const Regex!Char re)\n    {\n        match = 1;\n        reserved = 1; //first match is skipped\n        total_matches = re.ngroup;\n        foreach (ref set; re.charsets)\n        {\n            charsets ~= set.intervals;\n        }\n    }\n\n    CtContext lookaround(uint s, uint e)\n    {\n        CtContext ct;\n        ct.total_matches = e - s;\n        ct.match = 1;\n        return ct;\n    }\n\n    //restore state having current context\n    string restoreCode()\n    {\n        string text;\n        //stack is checked in L_backtrack\n        text ~= counter\n            ? \"\n                    stackPop(counter);\"\n            : \"\n                    counter = 0;\";\n        if (match < total_matches)\n        {\n            text ~= ctSub(\"\n                    stackPop(matches[$$..$$]);\", reserved, match);\n            text ~= ctSub(\"\n                    matches[$$..$] = typeof(matches[0]).init;\", match);\n        }\n        else\n            text ~= ctSub(\"\n                    stackPop(matches[$$..$]);\", reserved);\n        return text;\n    }\n\n    //save state having current context\n    string saveCode(uint pc, string count_expr=\"counter\")\n    {\n        string text = ctSub(\"\n                    if (stackAvail < $$*(Group!(DataIndex)).sizeof/size_t.sizeof + $$)\n                    {\n                        newStack();\n                    }\", match - reserved, cast(int) counter + 2);\n        if (match < total_matches)\n            text ~= ctSub(\"\n                    stackPush(matches[$$..$$]);\", reserved, match);\n        else\n            text ~= ctSub(\"\n                    stackPush(matches[$$..$]);\", reserved);\n        text ~= counter ? ctSub(\"\n                    stackPush($$);\", count_expr) : \"\";\n        text ~= ctSub(\"\n                    stackPush(index); stackPush($$); \\n\", pc);\n        return text;\n    }\n\n    //\n    CtState ctGenBlock(const(Bytecode)[] ir, int addr)\n    {\n        CtState result;\n        result.addr = addr;\n        while (!ir.empty)\n        {\n            auto n = ctGenGroup(ir, result.addr);\n            result.code ~= n.code;\n            result.addr = n.addr;\n        }\n        return result;\n    }\n\n    //\n    CtState ctGenGroup(ref const(Bytecode)[] ir, int addr)\n    {\n        import std.algorithm.comparison : max;\n        auto bailOut = \"goto L_backtrack;\";\n        auto nextInstr = ctSub(\"goto case $$;\", addr+1);\n        CtState r;\n        assert(!ir.empty);\n        switch (ir[0].code)\n        {\n        case IR.InfiniteStart,  IR.InfiniteBloomStart,IR.InfiniteQStart, IR.RepeatStart, IR.RepeatQStart:\n            immutable infLoop =\n                ir[0].code == IR.InfiniteStart || ir[0].code == IR.InfiniteQStart ||\n                ir[0].code == IR.InfiniteBloomStart;\n\n            counter = counter ||\n                ir[0].code == IR.RepeatStart || ir[0].code == IR.RepeatQStart;\n            immutable len = ir[0].data;\n            auto nir = ir[ir[0].length .. ir[0].length+len];\n            r = ctGenBlock(nir, addr+1);\n            //start/end codegen\n            //r.addr is at last test+ jump of loop, addr+1 is body of loop\n            nir = ir[ir[0].length + len .. $];\n            r.code = ctGenFixupCode(ir[0 .. ir[0].length], addr, r.addr) ~ r.code;\n            r.code ~= ctGenFixupCode(nir, r.addr, addr+1);\n            r.addr += 2;   //account end instruction + restore state\n            ir = nir;\n            break;\n        case IR.OrStart:\n            immutable len = ir[0].data;\n            auto nir = ir[ir[0].length .. ir[0].length+len];\n            r = ctGenAlternation(nir, addr);\n            ir = ir[ir[0].length + len .. $];\n            assert(ir[0].code == IR.OrEnd);\n            ir = ir[ir[0].length..$];\n            break;\n        case IR.LookaheadStart:\n        case IR.NeglookaheadStart:\n        case IR.LookbehindStart:\n        case IR.NeglookbehindStart:\n            immutable len = ir[0].data;\n            immutable behind = ir[0].code == IR.LookbehindStart || ir[0].code == IR.NeglookbehindStart;\n            immutable negative = ir[0].code == IR.NeglookaheadStart || ir[0].code == IR.NeglookbehindStart;\n            string fwdType = \"typeof(fwdMatcher(re, []))\";\n            string bwdType = \"typeof(bwdMatcher(re, []))\";\n            string fwdCreate = \"fwdMatcher(re, mem)\";\n            string bwdCreate = \"bwdMatcher(re, mem)\";\n            immutable start = IRL!(IR.LookbehindStart);\n            immutable end = IRL!(IR.LookbehindStart)+len+IRL!(IR.LookaheadEnd);\n            CtContext context = lookaround(ir[1].raw, ir[2].raw); //split off new context\n            auto slice = ir[start .. end];\n            r.code ~= ctSub(`\n            case $$: //fake lookaround \"atom\"\n                    static if (typeof(matcher.s).isLoopback)\n                        alias Lookaround = $$;\n                    else\n                        alias Lookaround = $$;\n                    static bool matcher_$$(Lookaround matcher) @trusted\n                    {\n                        //(neg)lookaround piece start\n                        $$\n                        //(neg)lookaround piece ends\n                    }\n                    auto save = index;\n                    auto mem = malloc(initialMemory(re))[0 .. initialMemory(re)];\n                    scope(exit) free(mem.ptr);\n                    static if (typeof(matcher.s).isLoopback)\n                        auto lookaround = $$;\n                    else\n                        auto lookaround = $$;\n                    lookaround.matches = matches[$$..$$];\n                    lookaround.backrefed = backrefed.empty ? matches : backrefed;\n                    lookaround.nativeFn = &matcher_$$; //hookup closure's binary code\n                    int match = $$;\n                    s.reset(save);\n                    next();\n                    if (match)\n                        $$\n                    else\n                        $$`, addr,\n                        behind ? fwdType : bwdType, behind ? bwdType : fwdType,\n                        addr, context.ctGenRegEx(slice),\n                        behind ? fwdCreate : bwdCreate, behind ? bwdCreate : fwdCreate,\n                        ir[1].raw, ir[2].raw, //start - end of matches slice\n                        addr,\n                        negative ? \"!lookaround.matchImpl()\" : \"lookaround.matchImpl()\",\n                        nextInstr, bailOut);\n            ir = ir[end .. $];\n            r.addr = addr + 1;\n            break;\n        case IR.LookaheadEnd: case IR.NeglookaheadEnd:\n        case IR.LookbehindEnd: case IR.NeglookbehindEnd:\n            ir = ir[IRL!(IR.LookaheadEnd) .. $];\n            r.addr = addr;\n            break;\n        default:\n            assert(ir[0].isAtom,  text(ir[0].mnemonic));\n            r = ctGenAtom(ir, addr);\n        }\n        return r;\n    }\n\n    //generate source for bytecode contained  in OrStart ... OrEnd\n    CtState ctGenAlternation(const(Bytecode)[] ir, int addr)\n    {\n        CtState[] pieces;\n        CtState r;\n        enum optL = IRL!(IR.Option);\n        for (;;)\n        {\n            assert(ir[0].code == IR.Option);\n            auto len = ir[0].data;\n            if (optL+len < ir.length  && ir[optL+len].code == IR.Option)//not a last option\n            {\n                auto nir = ir[optL .. optL+len-IRL!(IR.GotoEndOr)];\n                r = ctGenBlock(nir, addr+2);//space for Option + restore state\n                //r.addr+1 to account GotoEndOr  at end of branch\n                r.code = ctGenFixupCode(ir[0 .. ir[0].length], addr, r.addr+1) ~ r.code;\n                addr = r.addr+1;//leave space for GotoEndOr\n                pieces ~= r;\n                ir = ir[optL + len .. $];\n            }\n            else\n            {\n                pieces ~= ctGenBlock(ir[optL..$], addr);\n                addr = pieces[$-1].addr;\n                break;\n            }\n        }\n        r = pieces[0];\n        for (uint i = 1; i < pieces.length; i++)\n        {\n            r.code ~= ctSub(`\n                case $$:\n                    goto case $$; `, pieces[i-1].addr, addr);\n            r.code ~= pieces[i].code;\n        }\n        r.addr = addr;\n        return r;\n    }\n\n    // generate fixup code for instruction in ir,\n    // fixup means it has an alternative way for control flow\n    string ctGenFixupCode(const(Bytecode)[] ir, int addr, int fixup)\n    {\n        return ctGenFixupCode(ir, addr, fixup); // call ref Bytecode[] version\n    }\n    string ctGenFixupCode(ref const(Bytecode)[] ir, int addr, int fixup)\n    {\n        string r;\n        string testCode;\n        r = ctSub(`\n                case $$: debug(std_regex_matcher) writeln(\"#$$\");`,\n                    addr, addr);\n        switch (ir[0].code)\n        {\n        case IR.InfiniteStart, IR.InfiniteQStart, IR.InfiniteBloomStart:\n            r ~= ctSub( `\n                    goto case $$;`, fixup);\n            ir = ir[ir[0].length..$];\n            break;\n        case IR.InfiniteEnd:\n            testCode = ctQuickTest(ir[IRL!(IR.InfiniteEnd) .. $],addr + 1);\n            r ~= ctSub( `\n                    if (merge[$$+counter].mark(index))\n                    {\n                        // merged!\n                        goto L_backtrack;\n                    }\n\n                    $$\n                    {\n                        $$\n                    }\n                    goto case $$;\n                case $$: //restore state and go out of loop\n                    $$\n                    goto case;`, ir[1].raw, testCode, saveCode(addr+1), fixup,\n                    addr+1, restoreCode());\n            ir = ir[ir[0].length..$];\n            break;\n        case IR.InfiniteBloomEnd:\n            //TODO: check bloom filter and skip on failure\n            testCode = ctQuickTest(ir[IRL!(IR.InfiniteBloomEnd) .. $],addr + 1);\n            r ~= ctSub( `\n                    if (merge[$$+counter].mark(index))\n                    {\n                        // merged!\n                        goto L_backtrack;\n                    }\n\n                    $$\n                    {\n                        $$\n                    }\n                    goto case $$;\n                case $$: //restore state and go out of loop\n                    $$\n                    goto case;`, ir[1].raw, testCode, saveCode(addr+1), fixup,\n                    addr+1, restoreCode());\n            ir = ir[ir[0].length..$];\n            break;\n        case IR.InfiniteQEnd:\n            testCode = ctQuickTest(ir[IRL!(IR.InfiniteEnd) .. $],addr + 1);\n            auto altCode = testCode.length ? ctSub(\"else goto case $$;\", fixup) : \"\";\n            r ~= ctSub( `\n                    if (merge[$$+counter].mark(index))\n                    {\n                        // merged!\n                        goto L_backtrack;\n                    }\n\n                    $$\n                    {\n                        $$\n                        goto case $$;\n                    }\n                    $$\n                case $$://restore state and go inside loop\n                    $$\n                    goto case $$;`, ir[1].raw,\n                    testCode, saveCode(addr+1), addr+2, altCode,\n                    addr+1, restoreCode(), fixup);\n            ir = ir[ir[0].length..$];\n            break;\n        case IR.RepeatStart, IR.RepeatQStart:\n            r ~= ctSub( `\n                    goto case $$;`, fixup);\n            ir = ir[ir[0].length..$];\n            break;\n         case IR.RepeatEnd, IR.RepeatQEnd:\n            //len, step, min, max\n            immutable len = ir[0].data;\n            immutable step = ir[2].raw;\n            immutable min = ir[3].raw;\n            immutable max = ir[4].raw;\n            r ~= ctSub(`\n                    if (merge[$$+counter].mark(index))\n                    {\n                        // merged!\n                        goto L_backtrack;\n                    }\n                    if (counter < $$)\n                    {\n                        debug(std_regex_matcher) writeln(\"RepeatEnd min case pc=\", $$);\n                        counter += $$;\n                        goto case $$;\n                    }`,  ir[1].raw, min, addr, step, fixup);\n            if (ir[0].code == IR.RepeatEnd)\n            {\n                string counter_expr = ctSub(\"counter % $$\", step);\n                r ~= ctSub(`\n                    else if (counter < $$)\n                    {\n                            $$\n                            counter += $$;\n                            goto case $$;\n                    }`, max, saveCode(addr+1, counter_expr), step, fixup);\n            }\n            else\n            {\n                string counter_expr = ctSub(\"counter % $$\", step);\n                r ~= ctSub(`\n                    else if (counter < $$)\n                    {\n                        $$\n                        counter = counter % $$;\n                        goto case $$;\n                    }`, max, saveCode(addr+1,counter_expr), step, addr+2);\n            }\n            r ~= ctSub(`\n                    else\n                    {\n                        counter = counter % $$;\n                        goto case $$;\n                    }\n                case $$: //restore state\n                    $$\n                    goto case $$;`, step, addr+2, addr+1, restoreCode(),\n                    ir[0].code == IR.RepeatEnd ? addr+2 : fixup );\n            ir = ir[ir[0].length..$];\n            break;\n        case IR.Option:\n            r ~= ctSub( `\n                {\n                    $$\n                }\n                goto case $$;\n            case $$://restore thunk to go to the next group\n                $$\n                goto case $$;`, saveCode(addr+1), addr+2,\n                    addr+1, restoreCode(), fixup);\n                ir = ir[ir[0].length..$];\n            break;\n        default:\n            assert(0, text(ir[0].mnemonic));\n        }\n        return r;\n    }\n\n\n    string ctQuickTest(const(Bytecode)[] ir, int id)\n    {\n        uint pc = 0;\n        while (pc < ir.length && ir[pc].isAtom)\n        {\n            if (ir[pc].code == IR.GroupStart || ir[pc].code == IR.GroupEnd)\n            {\n                pc++;\n            }\n            else if (ir[pc].code == IR.Backref)\n                break;\n            else\n            {\n                auto code = ctAtomCode(ir[pc..$], -1);\n                return ctSub(`\n                    int test_$$()\n                    {\n                        $$ //$$\n                    }\n                    if (test_$$() >= 0)`, id, code.ptr ? code : \"return 0;\",\n                        ir[pc].mnemonic, id);\n            }\n        }\n        return \"\";\n    }\n\n    //process & generate source for simple bytecodes at front of ir using address addr\n    CtState ctGenAtom(ref const(Bytecode)[] ir, int addr)\n    {\n        CtState result;\n        result.code = ctAtomCode(ir, addr);\n        ir.popFrontN(ir[0].code == IR.OrChar ? ir[0].sequence : ir[0].length);\n        result.addr = addr + 1;\n        return result;\n    }\n\n    //D code for atom at ir using address addr, addr < 0 means quickTest\n    string ctAtomCode(const(Bytecode)[] ir, int addr)\n    {\n        string code;\n        string bailOut, nextInstr;\n        if (addr < 0)\n        {\n            bailOut = \"return -1;\";\n            nextInstr = \"return 0;\";\n        }\n        else\n        {\n            bailOut = \"goto L_backtrack;\";\n            nextInstr = ctSub(\"goto case $$;\", addr+1);\n            code ~=  ctSub( `\n                 case $$: debug(std_regex_matcher) writeln(\"#$$\");\n                    `, addr, addr);\n        }\n        switch (ir[0].code)\n        {\n        case IR.OrChar://assumes IRL!(OrChar) == 1\n            code ~=  ctSub(`\n                    if (atEnd)\n                        $$`, bailOut);\n            immutable len = ir[0].sequence;\n            for (uint i = 0; i < len; i++)\n            {\n                code ~= ctSub( `\n                    if (front == $$)\n                    {\n                        $$\n                        $$\n                    }`,   ir[i].data, addr >= 0 ? \"next();\" :\"\", nextInstr);\n            }\n            code ~= ctSub( `\n                $$`, bailOut);\n            break;\n        case IR.Char:\n            code ~= ctSub( `\n                    if (atEnd || front != $$)\n                        $$\n                    $$\n                    $$`, ir[0].data, bailOut, addr >= 0 ? \"next();\" :\"\", nextInstr);\n            break;\n        case IR.Any:\n            code ~= ctSub( `\n                    if (atEnd || (!(re.flags & RegexOption.singleline)\n                                && (front == '\\r' || front == '\\n')))\n                        $$\n                    $$\n                    $$`, bailOut, addr >= 0 ? \"next();\" :\"\",nextInstr);\n            break;\n        case IR.CodepointSet:\n            if (charsets.length)\n            {\n                string name = `func_`~to!string(addr+1);\n                string funcCode = CodepointSet.toSourceCode(charsets[ir[0].data], name);\n                code ~= ctSub( `\n                    static $$\n                    if (atEnd || !$$(front))\n                        $$\n                    $$\n                $$`, funcCode, name, bailOut, addr >= 0 ? \"next();\" :\"\", nextInstr);\n            }\n            else\n                code ~= ctSub( `\n                    if (atEnd || !re.charsets[$$].scanFor(front))\n                        $$\n                    $$\n                $$`, ir[0].data, bailOut, addr >= 0 ? \"next();\" :\"\", nextInstr);\n            break;\n        case IR.Trie:\n            if (charsets.length && charsets[ir[0].data].length  <= 8)\n                goto case IR.CodepointSet;\n            code ~= ctSub( `\n                    if (atEnd || !re.matchers[$$][front])\n                        $$\n                    $$\n                $$`, ir[0].data, bailOut, addr >= 0 ? \"next();\" :\"\", nextInstr);\n            break;\n        case IR.Wordboundary:\n            code ~= ctSub( `\n                    dchar back;\n                    DataIndex bi;\n                    if (atStart && wordMatcher[front])\n                    {\n                        $$\n                    }\n                    else if (atEnd && s.loopBack(index).nextChar(back, bi)\n                            && wordMatcher[back])\n                    {\n                        $$\n                    }\n                    else if (s.loopBack(index).nextChar(back, bi))\n                    {\n                        bool af = wordMatcher[front];\n                        bool ab = wordMatcher[back];\n                        if (af ^ ab)\n                        {\n                            $$\n                        }\n                    }\n                    $$`, nextInstr, nextInstr, nextInstr, bailOut);\n            break;\n        case IR.Notwordboundary:\n            code ~= ctSub( `\n                    dchar back;\n                    DataIndex bi;\n                    //at start & end of input\n                    if (atStart && wordMatcher[front])\n                        $$\n                    else if (atEnd && s.loopBack(index).nextChar(back, bi)\n                            && wordMatcher[back])\n                        $$\n                    else if (s.loopBack(index).nextChar(back, bi))\n                    {\n                        bool af = wordMatcher[front];\n                        bool ab = wordMatcher[back];\n                        if (af ^ ab)\n                            $$\n                    }\n                    $$`, bailOut, bailOut, bailOut, nextInstr);\n\n            break;\n        case IR.Bol:\n            code ~= ctSub(`\n                    dchar back;\n                    DataIndex bi;\n                    if (atStart || (s.loopBack(index).nextChar(back,bi)\n                        && endOfLine(back, front == '\\n')))\n                    {\n                        debug(std_regex_matcher) writeln(\"BOL matched\");\n                        $$\n                    }\n                    else\n                        $$`, nextInstr, bailOut);\n\n            break;\n        case IR.Bof:\n            code ~= ctSub(`\n                    if (atStart)\n                    {\n                        debug(std_regex_matcher) writeln(\"BOF matched\");\n                        $$\n                    }\n                    else\n                        $$`, nextInstr, bailOut);\n            break;\n        case IR.Eol:\n            code ~= ctSub(`\n                    dchar back;\n                    DataIndex bi;\n                    debug(std_regex_matcher) writefln(\"EOL (front 0x%x) %s\", front, s[index .. s.lastIndex]);\n                    //no matching inside \\r\\n\n                    if (atEnd || (endOfLine(front, s.loopBack(index).nextChar(back,bi)\n                             && back == '\\r')))\n                    {\n                        debug(std_regex_matcher) writeln(\"EOL matched\");\n                        $$\n                    }\n                    else\n                        $$`, nextInstr, bailOut);\n            break;\n        case IR.Eof:\n            code ~= ctSub(`\n                    if (atEnd)\n                    {\n                        debug(std_regex_matcher) writeln(\"BOF matched\");\n                        $$\n                    }\n                    else\n                        $$`, nextInstr, bailOut);\n            break;\n        case IR.GroupStart:\n            code ~= ctSub(`\n                    matches[$$].begin = index;\n                    $$`, ir[0].data, nextInstr);\n            match = ir[0].data+1;\n            break;\n        case IR.GroupEnd:\n            code ~= ctSub(`\n                    matches[$$].end = index;\n                    $$`, ir[0].data, nextInstr);\n            break;\n        case IR.Backref:\n            string mStr = \"auto referenced = \";\n            mStr ~= ir[0].localRef\n                ? ctSub(\"s[matches[$$].begin .. matches[$$].end];\",\n                    ir[0].data, ir[0].data)\n                : ctSub(\"s[backrefed[$$].begin .. backrefed[$$].end];\",\n                    ir[0].data, ir[0].data);\n            code ~= ctSub( `\n                    $$\n                    while (!atEnd && !referenced.empty && front == referenced.front)\n                    {\n                        next();\n                        referenced.popFront();\n                    }\n                    if (referenced.empty)\n                        $$\n                    else\n                        $$`, mStr, nextInstr, bailOut);\n            break;\n        case IR.Nop:\n        case IR.End:\n            break;\n        default:\n            assert(0, text(ir[0].mnemonic, \" is not supported yet\"));\n        }\n        return code;\n    }\n\n    //generate D code for the whole regex\n    public string ctGenRegEx(const(Bytecode)[] ir)\n    {\n        auto bdy = ctGenBlock(ir, 0);\n        auto r = `\n            import core.stdc.stdlib;\n            with(matcher)\n            {\n            pc = 0;\n            counter = 0;\n            lastState = 0;\n            matches[] = Group!DataIndex.init;\n            auto start = s._index;`;\n        r ~= `\n            goto StartLoop;\n            debug(std_regex_matcher) writeln(\"Try CT matching  starting at \",s[index .. s.lastIndex]);\n        L_backtrack:\n            if (lastState || prevStack())\n            {\n                stackPop(pc);\n                stackPop(index);\n                s.reset(index);\n                next();\n            }\n            else\n            {\n                s.reset(start);\n                return false;\n            }\n        StartLoop:\n            switch (pc)\n            {\n        `;\n        r ~= bdy.code;\n        r ~= ctSub(`\n                case $$: break;`,bdy.addr);\n        r ~= `\n            default:\n                assert(0);\n            }\n            // cleanup stale stack blocks\n            while (prevStack()) {}\n            return true;\n            }\n        `;\n        return r;\n    }\n\n}\n\nstring ctGenRegExCode(Char)(const Regex!Char re)\n{\n    auto context = CtContext(re);\n    return context.ctGenRegEx(re.ir);\n}\n"
  },
  {
    "path": "libphobos/src/std/regex/internal/generator.d",
    "content": "/*\n    Generators - components that generate strings for a given regex pattern.\n\n    For the moment undocumented, and is subject to change.\n*/\nmodule std.regex.internal.generator;\n\n/*\n    Useful utility for self-testing, an infinite range of string samples\n    that _have_ to match given compiled regex.\n    Caveats: supports only a simple subset of bytecode.\n*/\n@trusted private struct SampleGenerator(Char)\n{\n    import std.array : appender, Appender;\n    import std.format : formattedWrite;\n    import std.random : Xorshift;\n    import std.regex.internal.ir : Regex, IR, IRL;\n    import std.utf : isValidDchar, byChar;\n    Regex!Char re;\n    Appender!(char[]) app;\n    uint limit, seed;\n    Xorshift gen;\n    //generator for pattern r, with soft maximum of threshold elements\n    //and a given random seed\n    this(ref Regex!Char r, uint threshold, uint randomSeed)\n    {\n        re = r;\n        limit = threshold;\n        seed = randomSeed;\n        app = appender!(Char[])();\n        compose();\n    }\n\n    uint rand(uint x)\n    {\n        uint r = gen.front % x;\n        gen.popFront();\n        return r;\n    }\n\n    void compose()\n    {\n        uint pc = 0, counter = 0, dataLenOld = uint.max;\n        for (;;)\n        {\n            switch (re.ir[pc].code)\n            {\n            case IR.Char:\n                    formattedWrite(app,\"%s\", cast(dchar) re.ir[pc].data);\n                    pc += IRL!(IR.Char);\n                    break;\n                case IR.OrChar:\n                    uint len = re.ir[pc].sequence;\n                    formattedWrite(app, \"%s\", cast(dchar) re.ir[pc + rand(len)].data);\n                    pc += len;\n                    break;\n                case IR.CodepointSet:\n                case IR.Trie:\n                    auto set = re.charsets[re.ir[pc].data];\n                    auto x = rand(cast(uint) set.byInterval.length);\n                    auto y = rand(set.byInterval[x].b - set.byInterval[x].a);\n                    formattedWrite(app, \"%s\", cast(dchar)(set.byInterval[x].a+y));\n                    pc += IRL!(IR.CodepointSet);\n                    break;\n                case IR.Any:\n                    uint x;\n                    do\n                    {\n                        x = rand(0x11_000);\n                    }while (x == '\\r' || x == '\\n' || !isValidDchar(x));\n                    formattedWrite(app, \"%s\", cast(dchar) x);\n                    pc += IRL!(IR.Any);\n                    break;\n                case IR.GotoEndOr:\n                    pc += IRL!(IR.GotoEndOr)+re.ir[pc].data;\n                    assert(re.ir[pc].code == IR.OrEnd);\n                    goto case;\n                case IR.OrEnd:\n                    pc += IRL!(IR.OrEnd);\n                    break;\n                case IR.OrStart:\n                    pc += IRL!(IR.OrStart);\n                    goto case;\n                case IR.Option:\n                    uint next = pc + re.ir[pc].data + IRL!(IR.Option);\n                    uint nOpt = 0;\n                    //queue next Option\n                    while (re.ir[next].code == IR.Option)\n                    {\n                        nOpt++;\n                        next += re.ir[next].data + IRL!(IR.Option);\n                    }\n                    nOpt++;\n                    nOpt = rand(nOpt);\n                    for (;nOpt; nOpt--)\n                    {\n                        pc += re.ir[pc].data + IRL!(IR.Option);\n                    }\n                    assert(re.ir[pc].code == IR.Option);\n                    pc += IRL!(IR.Option);\n                    break;\n                case IR.RepeatStart:case IR.RepeatQStart:\n                    pc += IRL!(IR.RepeatStart)+re.ir[pc].data;\n                    goto case IR.RepeatEnd;\n                case IR.RepeatEnd:\n                case IR.RepeatQEnd:\n                    uint len = re.ir[pc].data;\n                    uint step = re.ir[pc+2].raw;\n                    uint min = re.ir[pc+3].raw;\n                    if (counter < min)\n                    {\n                        counter += step;\n                        pc -= len;\n                        break;\n                    }\n                    uint max = re.ir[pc+4].raw;\n                    if (counter < max)\n                    {\n                        if (app.data.length < limit && rand(3) > 0)\n                        {\n                            pc -= len;\n                            counter += step;\n                        }\n                        else\n                        {\n                            counter = counter%step;\n                            pc += IRL!(IR.RepeatEnd);\n                        }\n                    }\n                    else\n                    {\n                        counter = counter%step;\n                        pc += IRL!(IR.RepeatEnd);\n                    }\n                    break;\n                case IR.InfiniteStart, IR.InfiniteBloomStart, IR.InfiniteQStart:\n                    pc += re.ir[pc].data + IRL!(IR.InfiniteStart);\n                    goto case IR.InfiniteEnd; //both Q and non-Q\n                case IR.InfiniteEnd, IR.InfiniteBloomEnd, IR.InfiniteQEnd:\n                    uint len = re.ir[pc].data;\n                    if (app.data.length == dataLenOld)\n                    {\n                        pc += IRL!(IR.InfiniteEnd);\n                        break;\n                    }\n                    dataLenOld = cast(uint) app.data.length;\n                    if (app.data.length < limit && rand(3) > 0)\n                        pc = pc - len;\n                    else\n                        pc = pc + re.ir[pc].length;\n                    break;\n                case IR.GroupStart, IR.GroupEnd:\n                    pc += IRL!(IR.GroupStart);\n                    break;\n                case IR.Bol, IR.Wordboundary, IR.Notwordboundary:\n                case IR.LookaheadStart, IR.NeglookaheadStart, IR.LookbehindStart, IR.NeglookbehindStart:\n                default:\n                    return;\n            }\n        }\n    }\n\n    @property Char[] front()\n    {\n        return app.data;\n    }\n\n    enum empty = false;\n\n    void popFront()\n    {\n        app.shrinkTo(0);\n        compose();\n    }\n}\n\n@system unittest\n{\n    import std.range, std.regex;\n    auto re = regex(`P[a-z]{3,}q`);\n    auto gen = SampleGenerator!char(re, 20, 3141592);\n    static assert(isInputRange!(typeof(gen)));\n    //@@@BUG@@@ somehow gen.take(1_000) doesn't work\n    foreach (v; take(gen, 1_000))\n        assert(v.match(re));\n}\n"
  },
  {
    "path": "libphobos/src/std/regex/internal/ir.d",
    "content": "/*\n    Implementation of std.regex IR, an intermediate representation\n    of a regular expression pattern.\n\n    This is a common ground between frontend regex component (parser)\n    and backend components - generators, matchers and other \"filters\".\n*/\nmodule std.regex.internal.ir;\n\npackage(std.regex):\n\nimport std.exception, std.meta, std.range.primitives, std.traits, std.uni;\n\ndebug(std_regex_parser) import std.stdio;\n// just a common trait, may be moved elsewhere\nalias BasicElementOf(Range) = Unqual!(ElementEncodingType!Range);\n\nenum privateUseStart = '\\U000F0000', privateUseEnd ='\\U000FFFFD';\n\n// heuristic value determines maximum CodepointSet length suitable for linear search\nenum maxCharsetUsed = 6;\n\n// another variable to tweak behavior of caching generated Tries for character classes\nenum maxCachedMatchers = 8;\n\nalias Trie = CodepointSetTrie!(13, 8);\nalias makeTrie = codepointSetTrie!(13, 8);\n\nCharMatcher[CodepointSet] matcherCache;\n\n//accessor with caching\n@trusted CharMatcher getMatcher(CodepointSet set)\n{// @@@BUG@@@ 6357 almost all properties of AA are not @safe\n    if (__ctfe || maxCachedMatchers == 0)\n        return CharMatcher(set);\n    else\n    {\n        auto p = set in matcherCache;\n        if (p)\n            return *p;\n        if (matcherCache.length == maxCachedMatchers)\n        {\n            // flush enmatchers in trieCache\n            matcherCache = null;\n        }\n        return (matcherCache[set] = CharMatcher(set));\n    }\n}\n\n@property ref wordMatcher()()\n{\n    static CharMatcher matcher = CharMatcher(wordCharacter);\n    return matcher;\n}\n\n// some special Unicode white space characters\nprivate enum NEL = '\\u0085', LS = '\\u2028', PS = '\\u2029';\n\n//Regular expression engine/parser options:\n// global - search  all nonoverlapping matches in input\n// casefold - case insensitive matching, do casefolding on match in unicode mode\n// freeform - ignore whitespace in pattern, to match space use [ ] or \\s\n// multiline - switch  ^, $ detect start and end of linesinstead of just start and end of input\nenum RegexOption: uint {\n    global = 0x1,\n    casefold = 0x2,\n    freeform = 0x4,\n    nonunicode = 0x8,\n    multiline = 0x10,\n    singleline = 0x20\n}\n//do not reorder this list\nalias RegexOptionNames = AliasSeq!('g', 'i', 'x', 'U', 'm', 's');\nstatic assert( RegexOption.max < 0x80);\n// flags that allow guide execution of engine\nenum RegexInfo : uint { oneShot = 0x80 }\n\n// IR bit pattern: 0b1_xxxxx_yy\n// where yy indicates class of instruction, xxxxx for actual operation code\n//     00: atom, a normal instruction\n//     01: open, opening of a group, has length of contained IR in the low bits\n//     10: close, closing of a group, has length of contained IR in the low bits\n//     11 unused\n//\n// Loops with Q (non-greedy, with ? mark) must have the same size / other properties as non Q version\n// Possible changes:\n//* merge group, option, infinite/repeat start (to never copy during parsing of (a|b){1,2})\n//* reorganize groups to make n args easier to find, or simplify the check for groups of similar ops\n//  (like lookaround), or make it easier to identify hotspots.\n\nenum IR:uint {\n    Char              = 0b1_00000_00, //a character\n    Any               = 0b1_00001_00, //any character\n    CodepointSet      = 0b1_00010_00, //a most generic CodepointSet [...]\n    Trie              = 0b1_00011_00, //CodepointSet implemented as Trie\n    //match with any of a consecutive OrChar's in this sequence\n    //(used for case insensitive match)\n    //OrChar holds in upper two bits of data total number of OrChars in this _sequence_\n    //the drawback of this representation is that it is difficult\n    // to detect a jump in the middle of it\n    OrChar             = 0b1_00100_00,\n    Nop                = 0b1_00101_00, //no operation (padding)\n    End                = 0b1_00110_00, //end of program\n    Bol                = 0b1_00111_00, //beginning of a line ^\n    Eol                = 0b1_01000_00, //end of a line $\n    Wordboundary       = 0b1_01001_00, //boundary of a word\n    Notwordboundary    = 0b1_01010_00, //not a word boundary\n    Backref            = 0b1_01011_00, //backreference to a group (that has to be pinned, i.e. locally unique) (group index)\n    GroupStart         = 0b1_01100_00, //start of a group (x) (groupIndex+groupPinning(1bit))\n    GroupEnd           = 0b1_01101_00, //end of a group (x) (groupIndex+groupPinning(1bit))\n    Option             = 0b1_01110_00, //start of an option within an alternation x | y (length)\n    GotoEndOr          = 0b1_01111_00, //end of an option (length of the rest)\n    Bof                = 0b1_10000_00, //begining of \"file\" (string) ^\n    Eof                = 0b1_10001_00, //end of \"file\" (string) $\n    //... any additional atoms here\n\n    OrStart            = 0b1_00000_01, //start of alternation group  (length)\n    OrEnd              = 0b1_00000_10, //end of the or group (length,mergeIndex)\n    //with this instruction order\n    //bit mask 0b1_00001_00 could be used to test/set greediness\n    InfiniteStart      = 0b1_00001_01, //start of an infinite repetition x* (length)\n    InfiniteEnd        = 0b1_00001_10, //end of infinite repetition x* (length,mergeIndex)\n    InfiniteQStart     = 0b1_00010_01, //start of a non eager infinite repetition x*? (length)\n    InfiniteQEnd       = 0b1_00010_10, //end of non eager infinite repetition x*? (length,mergeIndex)\n    InfiniteBloomStart = 0b1_00011_01, //start of an filtered infinite repetition x* (length)\n    InfiniteBloomEnd   = 0b1_00011_10, //end of filtered infinite repetition x* (length,mergeIndex)\n    RepeatStart        = 0b1_00100_01, //start of a {n,m} repetition (length)\n    RepeatEnd          = 0b1_00100_10, //end of x{n,m} repetition (length,step,minRep,maxRep)\n    RepeatQStart       = 0b1_00101_01, //start of a non eager x{n,m}? repetition (length)\n    RepeatQEnd         = 0b1_00101_10, //end of non eager x{n,m}? repetition (length,step,minRep,maxRep)\n\n    //\n    LookaheadStart     = 0b1_00110_01, //begin of the lookahead group (length)\n    LookaheadEnd       = 0b1_00110_10, //end of a lookahead group (length)\n    NeglookaheadStart  = 0b1_00111_01, //start of a negative lookahead (length)\n    NeglookaheadEnd    = 0b1_00111_10, //end of a negative lookahead (length)\n    LookbehindStart    = 0b1_01000_01, //start of a lookbehind (length)\n    LookbehindEnd      = 0b1_01000_10, //end of a lookbehind (length)\n    NeglookbehindStart = 0b1_01001_01, //start of a negative lookbehind (length)\n    NeglookbehindEnd   = 0b1_01001_10, //end of negative lookbehind (length)\n}\n\n//a shorthand for IR length - full length of specific opcode evaluated at compile time\ntemplate IRL(IR code)\n{\n    enum uint IRL =  lengthOfIR(code);\n}\nstatic assert(IRL!(IR.LookaheadStart) == 3);\n\n//how many parameters follow the IR, should be optimized fixing some IR bits\nint immediateParamsIR(IR i){\n    switch (i)\n    {\n    case IR.OrEnd,IR.InfiniteEnd,IR.InfiniteQEnd:\n        return 1;  // merge table index\n    case IR.InfiniteBloomEnd:\n        return 2;  // bloom filter index + merge table index\n    case IR.RepeatEnd, IR.RepeatQEnd:\n        return 4;\n    case IR.LookaheadStart, IR.NeglookaheadStart, IR.LookbehindStart, IR.NeglookbehindStart:\n        return 2;  // start-end of captures used\n    default:\n        return 0;\n    }\n}\n\n//full length of IR instruction inlcuding all parameters that might follow it\nint lengthOfIR(IR i)\n{\n    return 1 + immediateParamsIR(i);\n}\n\n//full length of the paired IR instruction inlcuding all parameters that might follow it\nint lengthOfPairedIR(IR i)\n{\n    return 1 + immediateParamsIR(pairedIR(i));\n}\n\n//if the operation has a merge point (this relies on the order of the ops)\nbool hasMerge(IR i)\n{\n    return (i&0b11)==0b10 && i <= IR.RepeatQEnd;\n}\n\n//is an IR that opens a \"group\"\nbool isStartIR(IR i)\n{\n    return (i&0b11)==0b01;\n}\n\n//is an IR that ends a \"group\"\nbool isEndIR(IR i)\n{\n    return (i&0b11)==0b10;\n}\n\n//is a standalone IR\nbool isAtomIR(IR i)\n{\n    return (i&0b11)==0b00;\n}\n\n//makes respective pair out of IR i, swapping start/end bits of instruction\nIR pairedIR(IR i)\n{\n    assert(isStartIR(i) || isEndIR(i));\n    return cast(IR) (i ^ 0b11);\n}\n\n//encoded IR instruction\nstruct Bytecode\n{\n    uint raw;\n    //natural constraints\n    enum maxSequence = 2+4;\n    enum maxData = 1 << 22;\n    enum maxRaw = 1 << 31;\n\n    this(IR code, uint data)\n    {\n        assert(data < (1 << 22) && code < 256);\n        raw = code << 24 | data;\n    }\n\n    this(IR code, uint data, uint seq)\n    {\n        assert(data < (1 << 22) && code < 256 );\n        assert(seq >= 2 && seq < maxSequence);\n        raw = code << 24 | (seq - 2)<<22 | data;\n    }\n\n    //store raw data\n    static Bytecode fromRaw(uint data)\n    {\n        Bytecode t;\n        t.raw = data;\n        return t;\n    }\n\n    //bit twiddling helpers\n    //0-arg template due to @@@BUG@@@ 10985\n    @property uint data()() const { return raw & 0x003f_ffff; }\n\n    @property void data()(uint val)\n    {\n        raw = (raw & ~0x003f_ffff) | (val & 0x003f_ffff);\n    }\n\n    //ditto\n    //0-arg template due to @@@BUG@@@ 10985\n    @property uint sequence()() const { return 2 + (raw >> 22 & 0x3); }\n\n    //ditto\n    //0-arg template due to @@@BUG@@@ 10985\n    @property IR code()() const { return cast(IR)(raw >> 24); }\n\n    //ditto\n    @property bool hotspot() const { return hasMerge(code); }\n\n    //test the class of this instruction\n    @property bool isAtom() const { return isAtomIR(code); }\n\n    //ditto\n    @property bool isStart() const { return isStartIR(code); }\n\n    //ditto\n    @property bool isEnd() const { return isEndIR(code); }\n\n    //number of arguments for this instruction\n    @property int args() const { return immediateParamsIR(code); }\n\n    //mark this GroupStart or GroupEnd as referenced in backreference\n    void setBackrefence()\n    {\n        assert(code == IR.GroupStart || code == IR.GroupEnd);\n        raw = raw | 1 << 23;\n    }\n\n    //is referenced\n    @property bool backreference() const\n    {\n        assert(code == IR.GroupStart || code == IR.GroupEnd);\n        return cast(bool)(raw & 1 << 23);\n    }\n\n    //mark as local reference (for backrefs in lookarounds)\n    void setLocalRef()\n    {\n        assert(code == IR.Backref);\n        raw = raw | 1 << 23;\n    }\n\n    //is a local ref\n    @property bool localRef() const\n    {\n        assert(code == IR.Backref);\n        return cast(bool)(raw & 1 << 23);\n    }\n\n    //human readable name of instruction\n    @trusted @property string mnemonic()() const\n    {//@@@BUG@@@ to is @system\n        import std.conv : to;\n        return to!string(code);\n    }\n\n    //full length of instruction\n    @property uint length() const\n    {\n        return lengthOfIR(code);\n    }\n\n    //full length of respective start/end of this instruction\n    @property uint pairedLength() const\n    {\n        return lengthOfPairedIR(code);\n    }\n\n    //returns bytecode of paired instruction (assuming this one is start or end)\n    @property Bytecode paired() const\n    {//depends on bit and struct layout order\n        assert(isStart || isEnd);\n        return Bytecode.fromRaw(raw ^ 0b11 << 24);\n    }\n\n    //gets an index into IR block of the respective pair\n    uint indexOfPair(uint pc) const\n    {\n        assert(isStart || isEnd);\n        return isStart ? pc + data + length  : pc - data - lengthOfPairedIR(code);\n    }\n}\n\nstatic assert(Bytecode.sizeof == 4);\n\n\n//index entry structure for name --> number of submatch\nstruct NamedGroup\n{\n    string name;\n    uint group;\n}\n\n//holds pair of start-end markers for a submatch\nstruct Group(DataIndex)\n{\n    DataIndex begin, end;\n    @trusted string toString()() const\n    {\n        import std.array : appender;\n        import std.format : formattedWrite;\n        auto a = appender!string();\n        formattedWrite(a, \"%s..%s\", begin, end);\n        return a.data;\n    }\n}\n\n//debugging tool, prints out instruction along with opcodes\n@trusted string disassemble(in Bytecode[] irb, uint pc, in NamedGroup[] dict=[])\n{\n    import std.array : appender;\n    import std.format : formattedWrite;\n    auto output = appender!string();\n    formattedWrite(output,\"%s\", irb[pc].mnemonic);\n    switch (irb[pc].code)\n    {\n    case IR.Char:\n        formattedWrite(output, \" %s (0x%x)\",cast(dchar) irb[pc].data, irb[pc].data);\n        break;\n    case IR.OrChar:\n        formattedWrite(output, \" %s (0x%x) seq=%d\", cast(dchar) irb[pc].data, irb[pc].data, irb[pc].sequence);\n        break;\n    case IR.RepeatStart, IR.InfiniteStart, IR.InfiniteBloomStart,\n    IR.Option, IR.GotoEndOr, IR.OrStart:\n        //forward-jump instructions\n        uint len = irb[pc].data;\n        formattedWrite(output, \" pc=>%u\", pc+len+IRL!(IR.RepeatStart));\n        break;\n    case IR.RepeatEnd, IR.RepeatQEnd: //backward-jump instructions\n        uint len = irb[pc].data;\n        formattedWrite(output, \" pc=>%u min=%u max=%u step=%u\",\n            pc - len, irb[pc + 3].raw, irb[pc + 4].raw, irb[pc + 2].raw);\n        break;\n    case IR.InfiniteEnd, IR.InfiniteQEnd, IR.InfiniteBloomEnd, IR.OrEnd: //ditto\n        uint len = irb[pc].data;\n        formattedWrite(output, \" pc=>%u\", pc-len);\n        break;\n    case  IR.LookaheadEnd, IR.NeglookaheadEnd: //ditto\n        uint len = irb[pc].data;\n        formattedWrite(output, \" pc=>%u\", pc-len);\n        break;\n    case IR.GroupStart, IR.GroupEnd:\n        uint n = irb[pc].data;\n        string name;\n        foreach (v;dict)\n            if (v.group == n)\n            {\n                name = \"'\"~v.name~\"'\";\n                break;\n            }\n        formattedWrite(output, \" %s #%u \" ~ (irb[pc].backreference ? \"referenced\" : \"\"),\n                name, n);\n        break;\n    case IR.LookaheadStart, IR.NeglookaheadStart, IR.LookbehindStart, IR.NeglookbehindStart:\n        uint len = irb[pc].data;\n        uint start = irb[pc+1].raw, end = irb[pc+2].raw;\n        formattedWrite(output, \" pc=>%u [%u..%u]\", pc + len + IRL!(IR.LookaheadStart), start, end);\n        break;\n    case IR.Backref: case IR.CodepointSet: case IR.Trie:\n        uint n = irb[pc].data;\n        formattedWrite(output, \" %u\",  n);\n        if (irb[pc].code == IR.Backref)\n            formattedWrite(output, \" %s\", irb[pc].localRef ? \"local\" : \"global\");\n        break;\n    default://all data-free instructions\n    }\n    if (irb[pc].hotspot)\n        formattedWrite(output, \" Hotspot %u\", irb[pc+1].raw);\n    return output.data;\n}\n\n//disassemble the whole chunk\n@trusted void printBytecode()(in Bytecode[] slice, in NamedGroup[] dict=[])\n{\n    import std.stdio : writeln;\n    for (uint pc=0; pc<slice.length; pc += slice[pc].length)\n        writeln(\"\\t\", disassemble(slice, pc, dict));\n}\n\n// Encapsulates memory management, explicit ref counting\n// and the exact type of engine created\n// there is a single instance per engine combination type x Char\n// In future may also maintain a (TLS?) cache of memory\ninterface MatcherFactory(Char)\n{\n@safe:\n    Matcher!Char create(const ref Regex!Char, in Char[] input) const;\n    Matcher!Char dup(Matcher!Char m, in Char[] input) const;\n    size_t incRef(Matcher!Char m) const;\n    size_t decRef(Matcher!Char m) const;\n}\n\n// Only memory management, no compile-time vs run-time specialities\nabstract class GenericFactory(alias EngineType, Char) : MatcherFactory!Char\n{\n    import core.stdc.stdlib : malloc, free;\n    import core.memory : GC;\n    // round up to next multiple of size_t for alignment purposes\n    enum classSize = (__traits(classInstanceSize, EngineType!Char) + size_t.sizeof - 1) & ~(size_t.sizeof - 1);\n\n    EngineType!Char construct(const ref Regex!Char re, in Char[] input, void[] memory) const;\n\n    override EngineType!Char create(const ref Regex!Char re, in Char[] input) const @trusted\n    {\n        immutable size = EngineType!Char.initialMemory(re) + classSize;\n        auto memory = enforce(malloc(size), \"malloc failed\")[0 .. size];\n        scope(failure) free(memory.ptr);\n        GC.addRange(memory.ptr, classSize);\n        auto engine = construct(re, input, memory);\n        assert(engine.refCount == 1);\n        assert(cast(void*) engine == memory.ptr);\n        return engine;\n    }\n\n    override EngineType!Char dup(Matcher!Char engine, in Char[] input) const @trusted\n    {\n        immutable size = EngineType!Char.initialMemory(engine.pattern) + classSize;\n        auto memory = enforce(malloc(size), \"malloc failed\")[0 .. size];\n        scope(failure) free(memory.ptr);\n        auto copy = construct(engine.pattern, input, memory);\n        GC.addRange(memory.ptr, classSize);\n        engine.dupTo(copy, memory[classSize .. size]);\n        assert(copy.refCount == 1);\n        return copy;\n    }\n\n    override size_t incRef(Matcher!Char m) const\n    {\n        return ++m.refCount;\n    }\n\n    override size_t decRef(Matcher!Char m) const  @trusted\n    {\n        assert(m.refCount != 0);\n        auto cnt = --m.refCount;\n        if (cnt == 0)\n        {\n            void* ptr = cast(void*) m;\n            GC.removeRange(ptr);\n            free(ptr);\n        }\n        return cnt;\n    }\n}\n\n// A factory for run-time engines\nclass RuntimeFactory(alias EngineType, Char) : GenericFactory!(EngineType, Char)\n{\n    override EngineType!Char construct(const ref Regex!Char re, in Char[] input, void[] memory) const\n    {\n        import std.conv : emplace;\n        return emplace!(EngineType!Char)(memory[0 .. classSize],\n            re, Input!Char(input), memory[classSize .. $]);\n    }\n}\n\n// A factory for compile-time engine\nclass CtfeFactory(alias EngineType, Char, alias func) : GenericFactory!(EngineType, Char)\n{\n    override EngineType!Char construct(const ref Regex!Char re, in Char[] input, void[] memory) const\n    {\n        import std.conv : emplace;\n        return emplace!(EngineType!Char)(memory[0 .. classSize],\n            re, &func, Input!Char(input), memory[classSize .. $]);\n    }\n}\n\n// A workaround for R-T enum re = regex(...)\ntemplate defaultFactory(Char)\n{\n    @property MatcherFactory!Char defaultFactory(const ref Regex!Char re) @safe\n    {\n        import std.regex.internal.backtracking : BacktrackingMatcher;\n        import std.regex.internal.thompson : ThompsonMatcher;\n        import std.algorithm.searching : canFind;\n        static MatcherFactory!Char backtrackingFactory;\n        static MatcherFactory!Char thompsonFactory;\n        if (re.backrefed.canFind!\"a != 0\")\n        {\n            if (backtrackingFactory is null)\n                backtrackingFactory = new RuntimeFactory!(BacktrackingMatcher, Char);\n            return backtrackingFactory;\n        }\n        else\n        {\n            if (thompsonFactory is null)\n                thompsonFactory = new RuntimeFactory!(ThompsonMatcher, Char);\n            return thompsonFactory;\n        }\n    }\n}\n\n// Defining it as an interface has the undesired side-effect:\n// casting any class to an interface silently adjusts pointer to point to a nested vtbl\nabstract class Matcher(Char)\n{\nabstract:\n    // Get a (next) match\n    int match(Group!size_t[] matches);\n    // This only maintains internal ref-count,\n    // deallocation happens inside MatcherFactory\n    @property ref size_t refCount() @safe;\n    // Copy internal state to another engine, using memory arena 'memory'\n    void dupTo(Matcher!Char m, void[] memory);\n    // The pattern loaded\n    @property ref const(Regex!Char) pattern() @safe;\n    // Re-arm the engine with new Input\n    Matcher rearm(in Char[] stream);\n}\n\n/++\n    `Regex` object holds regular expression pattern in compiled form.\n    Instances of this object are constructed via calls to `regex`.\n    This is an intended form for caching and storage of frequently\n    used regular expressions.\n+/\nstruct Regex(Char)\n{\n    //temporary workaround for identifier lookup\n    CodepointSet[] charsets; //\n    Bytecode[] ir;      //compiled bytecode of pattern\n\n\n    @safe @property bool empty() const nothrow {  return ir is null; }\n\n    @safe @property auto namedCaptures()\n    {\n        static struct NamedGroupRange\n        {\n        private:\n            const(NamedGroup)[] groups;\n            size_t start;\n            size_t end;\n        public:\n            this(const(NamedGroup)[] g, size_t s, size_t e)\n            {\n                assert(s <= e);\n                assert(e <= g.length);\n                groups = g;\n                start = s;\n                end = e;\n            }\n\n            @property string front() { return groups[start].name; }\n            @property string back() { return groups[end-1].name; }\n            @property bool empty() { return start >= end; }\n            @property size_t length() { return end - start; }\n            alias opDollar = length;\n            @property NamedGroupRange save()\n            {\n                return NamedGroupRange(groups, start, end);\n            }\n            void popFront() { assert(!empty); start++; }\n            void popBack() { assert(!empty); end--; }\n            string opIndex()(size_t i)\n            {\n                assert(start + i < end,\n                       \"Requested named group is out of range.\");\n                return groups[start+i].name;\n            }\n            NamedGroupRange opSlice(size_t low, size_t high) {\n                assert(low <= high);\n                assert(start + high <= end);\n                return NamedGroupRange(groups, start + low, start + high);\n            }\n            NamedGroupRange opSlice() { return this.save; }\n        }\n        return NamedGroupRange(dict, 0, dict.length);\n    }\n\npackage(std.regex):\n    import std.regex.internal.kickstart : Kickstart; //TODO: get rid of this dependency\n    const(NamedGroup)[] dict;              // maps name -> user group number\n    uint ngroup;                           // number of internal groups\n    uint maxCounterDepth;                  // max depth of nested {n,m} repetitions\n    uint hotspotTableSize;                 // number of entries in merge table\n    uint threadCount;                      // upper bound on number of Thompson VM threads\n    uint flags;                            // global regex flags\n    public const(CharMatcher)[]  matchers; // tables that represent character sets\n    public const(BitTable)[] filters;      // bloom filters for conditional loops\n    uint[] backrefed;                      // bit array of backreferenced submatches\n    Kickstart!Char kickstart;\n    MatcherFactory!Char factory;           // produces optimal matcher for this pattern\n    immutable(Char)[] pattern;             // copy of pattern to serve as cache key\n\n    const(Regex) withFactory(MatcherFactory!Char factory) pure const @trusted\n    {\n        auto r = cast() this;\n        r.factory = factory;\n        return r;\n    }\n\n    const(Regex) withFlags(uint newFlags) pure const @trusted\n    {\n        auto r = cast() this;\n        r.flags = newFlags;\n        return r;\n    }\n\n    const(Regex) withCode(const(Bytecode)[] code) pure const @trusted\n    {\n        auto r = cast() this;\n        r.ir = code.dup; // TODO: sidestep const instead?\n        return r;\n    }\n\n    const(Regex) withNGroup(uint nGroup) pure const @trusted\n    {\n        auto r = cast() this;\n        r.ngroup = nGroup;\n        return r;\n    }\n\n    //bit access helper\n    uint isBackref(uint n)\n    {\n        if (n/32 >= backrefed.length)\n            return 0;\n        return backrefed[n / 32] & (1 << (n & 31));\n    }\n\n    //check if searching is not needed\n    void checkIfOneShot()\n    {\n    L_CheckLoop:\n        for (uint i = 0; i < ir.length; i += ir[i].length)\n        {\n            switch (ir[i].code)\n            {\n                case IR.Bof:\n                    flags |= RegexInfo.oneShot;\n                    break L_CheckLoop;\n                case IR.GroupStart, IR.GroupEnd, IR.Bol, IR.Eol, IR.Eof,\n                IR.Wordboundary, IR.Notwordboundary:\n                    break;\n                default:\n                    break L_CheckLoop;\n            }\n        }\n    }\n\n    //print out disassembly a program's IR\n    @trusted debug(std_regex_parser) void print() const\n    {//@@@BUG@@@ write is system\n        for (uint i = 0; i < ir.length; i += ir[i].length)\n        {\n            writefln(\"%d\\t%s \", i, disassemble(ir, i, dict));\n        }\n        writeln(\"Total merge table size: \", hotspotTableSize);\n        writeln(\"Max counter nesting depth: \", maxCounterDepth);\n    }\n\n}\n\n// The stuff below this point is temporarrily part of IR module\n// but may need better place in the future (all internals)\npackage(std.regex):\n\n//Simple UTF-string abstraction compatible with stream interface\nstruct Input(Char)\nif (is(Char :dchar))\n{\n    import std.utf : decode;\n    alias DataIndex = size_t;\n    enum bool isLoopback = false;\n    alias String = const(Char)[];\n    String _origin;\n    size_t _index;\n\n    //constructs Input object out of plain string\n    this(String input, size_t idx = 0)\n    {\n        _origin = input;\n        _index = idx;\n    }\n\n    //codepoint at current stream position\n    pragma(inline, true) bool nextChar(ref dchar res, ref size_t pos)\n    {\n        pos = _index;\n        // DMD's inliner hates multiple return functions\n        // but can live with single statement if/else bodies\n        bool n = !(_index == _origin.length);\n        if (n)\n            res = decode(_origin, _index);\n        return n;\n    }\n    @property bool atEnd(){\n        return _index == _origin.length;\n    }\n    bool search(Kickstart)(ref const Kickstart kick, ref dchar res, ref size_t pos)\n    {\n        size_t idx = kick.search(_origin, _index);\n        _index = idx;\n        return nextChar(res, pos);\n    }\n\n    //index of at End position\n    @property size_t lastIndex(){   return _origin.length; }\n\n    //support for backtracker engine, might not be present\n    void reset(size_t index){   _index = index;  }\n\n    String opSlice(size_t start, size_t end){   return _origin[start .. end]; }\n\n    auto loopBack(size_t index){   return BackLooper!Input(this, index); }\n}\n\nstruct BackLooperImpl(Input)\n{\n    import std.utf : strideBack;\n    alias DataIndex = size_t;\n    alias String = Input.String;\n    enum bool isLoopback = true;\n    String _origin;\n    size_t _index;\n    this(Input input, size_t index)\n    {\n        _origin = input._origin;\n        _index = index;\n    }\n    this(String input)\n    {\n        _origin = input;\n        _index = input.length;\n    }\n    @trusted bool nextChar(ref dchar res,ref size_t pos)\n    {\n        pos = _index;\n        if (_index == 0)\n            return false;\n\n        res = _origin[0.._index].back;\n        _index -= strideBack(_origin, _index);\n\n        return true;\n    }\n    @property atEnd(){ return _index == 0 || _index == strideBack(_origin, _index); }\n    auto loopBack(size_t index){   return Input(_origin, index); }\n\n    //support for backtracker engine, might not be present\n    //void reset(size_t index){   _index = index ? index-std.utf.strideBack(_origin, index) : 0;  }\n    void reset(size_t index){   _index = index;  }\n\n    String opSlice(size_t start, size_t end){   return _origin[end .. start]; }\n    //index of at End position\n    @property size_t lastIndex(){   return 0; }\n}\n\ntemplate BackLooper(E)\n{\n    static if (is(E : BackLooperImpl!U, U))\n    {\n        alias BackLooper = U;\n    }\n    else\n    {\n        alias BackLooper = BackLooperImpl!E;\n    }\n}\n\n//both helpers below are internal, on its own are quite \"explosive\"\n//unsafe, no initialization of elements\n@system T[] mallocArray(T)(size_t len)\n{\n    import core.stdc.stdlib : malloc;\n    return (cast(T*) malloc(len * T.sizeof))[0 .. len];\n}\n\n//very unsafe, no initialization\n@system T[] arrayInChunk(T)(size_t len, ref void[] chunk)\n{\n    auto ret = (cast(T*) chunk.ptr)[0 .. len];\n    chunk = chunk[len * T.sizeof .. $];\n    return ret;\n}\n\n//\n@trusted uint lookupNamedGroup(String)(const(NamedGroup)[] dict, String name)\n{//equal is @system?\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    import std.conv : text;\n    import std.range : assumeSorted;\n\n    auto fnd = assumeSorted!\"cmp(a,b) < 0\"(map!\"a.name\"(dict)).lowerBound(name).length;\n    enforce(fnd < dict.length && equal(dict[fnd].name, name),\n        text(\"no submatch named \", name));\n    return dict[fnd].group;\n}\n\n//whether ch is one of unicode newline sequences\n//0-arg template due to @@@BUG@@@ 10985\nbool endOfLine()(dchar front, bool seenCr)\n{\n    return ((front == '\\n') ^ seenCr) || front == '\\r'\n    || front == NEL || front == LS || front == PS;\n}\n\n//\n//0-arg template due to @@@BUG@@@ 10985\nbool startOfLine()(dchar back, bool seenNl)\n{\n    return ((back == '\\r') ^ seenNl) || back == '\\n'\n    || back == NEL || back == LS || back == PS;\n}\n\n///Exception object thrown in case of errors during regex compilation.\npublic class RegexException : Exception\n{\n    mixin basicExceptionCtors;\n}\n\n// simple 128-entry bit-table used with a hash function\nstruct BitTable {\n    uint[4] filter;\n\n    this(CodepointSet set){\n        foreach (iv; set.byInterval)\n        {\n            foreach (v; iv.a .. iv.b)\n                add(v);\n        }\n    }\n\n    void add()(dchar ch){\n        immutable i = index(ch);\n        filter[i >> 5]  |=  1<<(i & 31);\n    }\n    // non-zero -> might be present, 0 -> absent\n    bool opIndex()(dchar ch) const{\n        immutable i = index(ch);\n        return (filter[i >> 5]>>(i & 31)) & 1;\n    }\n\n    static uint index()(dchar ch){\n        return ((ch >> 7) ^ ch) & 0x7F;\n    }\n}\n\nstruct CharMatcher {\n    BitTable ascii; // fast path for ASCII\n    Trie trie;      // slow path for Unicode\n\n    this(CodepointSet set)\n    {\n        auto asciiSet = set & unicode.ASCII;\n        ascii = BitTable(asciiSet);\n        trie = makeTrie(set);\n    }\n\n    bool opIndex()(dchar ch) const\n    {\n        if (ch < 0x80)\n            return ascii[ch];\n        else\n            return trie[ch];\n    }\n}\n\n// Internal non-resizeble array, switches between inline storage and CoW\n// POD-only\nstruct SmallFixedArray(T, uint SMALL=3)\nif (!hasElaborateDestructor!T)\n{\n    import core.stdc.stdlib : malloc, free;\n    static struct Payload\n    {\n        size_t refcount;\n        T[0] placeholder;\n        inout(T)* ptr() inout { return placeholder.ptr; }\n    }\n    static assert(Payload.sizeof == size_t.sizeof);\n    union\n    {\n        Payload* big;\n        T[SMALL] small;\n    }\n    size_t _sizeMask;\n    enum BIG_MASK = size_t(1)<<(8*size_t.sizeof-1);\n    enum SIZE_MASK = ~BIG_MASK;\n\n    @property bool isBig() const { return (_sizeMask & BIG_MASK) != 0; }\n    @property size_t length() const { return _sizeMask & SIZE_MASK; }\n\n    this(size_t size)\n    {\n        if (size <= SMALL)\n        {\n            small[] = T.init;\n            _sizeMask = size;\n        }\n        else\n        {\n            big = cast(Payload*) enforce(malloc(Payload.sizeof + T.sizeof*size), \"Failed to malloc storage\");\n            big.refcount = 1;\n            _sizeMask = size | BIG_MASK;\n        }\n    }\n\n    private @trusted @property inout(T)[] internalSlice() inout\n    {\n        return isBig ? big.ptr[0 .. length] : small[0 .. length];\n    }\n\n    this(this)\n    {\n        if (isBig)\n        {\n            big.refcount++;\n        }\n    }\n\n    bool opEquals(SmallFixedArray a)\n    {\n        return internalSlice[] == a.internalSlice[];\n    }\n\n    size_t toHash() const\n    {\n        return hashOf(internalSlice[]);\n    }\n\n    T opIndex(size_t idx) inout\n    {\n        return internalSlice[idx];\n    }\n\n    // accesses big to test self-referencing so not @safe\n    @trusted ref opAssign(SmallFixedArray arr)\n    {\n        if (isBig)\n        {\n            if (arr.isBig)\n            {\n                if (big is arr.big) return this; // self-assign\n                else\n                {\n                    abandonRef();\n                    _sizeMask = arr._sizeMask;\n                    big = arr.big;\n                    big.refcount++;\n                }\n            }\n            else\n            {\n                abandonRef();\n                _sizeMask = arr._sizeMask;\n                small = arr.small;\n            }\n        }\n        else\n        {\n            if (arr.isBig)\n            {\n                _sizeMask = arr._sizeMask;\n                big = arr.big;\n                big.refcount++;\n            }\n            else\n            {\n                _sizeMask = arr._sizeMask;\n                small = arr.small;\n            }\n        }\n        return this;\n    }\n\n    void mutate(scope void delegate(T[]) filler)\n    {\n        if (isBig && big.refcount != 1) // copy on write\n        {\n            auto oldSizeMask = _sizeMask;\n            auto newbig = cast(Payload*) enforce(malloc(Payload.sizeof + T.sizeof*length), \"Failed to malloc storage\");\n            newbig.refcount = 1;\n            abandonRef();\n            big = newbig;\n            _sizeMask = oldSizeMask;\n        }\n        filler(internalSlice);\n    }\n\n    ~this()\n    {\n        if (isBig)\n        {\n            abandonRef();\n        }\n    }\n\n    @trusted private void abandonRef()\n    {\n        assert(isBig);\n        if (--big.refcount == 0)\n        {\n            free(big);\n            _sizeMask = 0;\n            assert(!isBig);\n        }\n    }\n}\n\n@system unittest\n{\n    alias SA = SmallFixedArray!(int, 2);\n    SA create(int[] data)\n    {\n        SA a = SA(data.length);\n        a.mutate((slice) { slice[] = data[]; });\n        assert(a.internalSlice == data);\n        return a;\n    }\n\n    {\n        SA a;\n        a = SA(1);\n        assert(a.length == 1);\n        a = SA.init;\n        assert(a.length == 0);\n    }\n\n    {\n        SA a, b, c, d;\n        assert(a.length == 0);\n        assert(a.internalSlice == b.internalSlice);\n        a = create([1]);\n        assert(a.internalSlice == [1]);\n        b = create([2, 3]);\n        assert(b.internalSlice == [2, 3]);\n        c = create([3, 4, 5]);\n        d = create([5, 6, 7, 8]);\n        assert(c.isBig);\n        a = c;\n        assert(a.isBig);\n        assert(a.big is c.big);\n        assert(a.big.refcount == 2);\n        assert(a.internalSlice == [3, 4, 5]);\n        assert(c.internalSlice == [3, 4, 5]);\n        a = b;\n        assert(!a.isBig);\n        assert(a.internalSlice == [2, 3]);\n        assert(c.big.refcount == 1);\n        a = c;\n        assert(c.big.refcount == 2);\n\n        // mutate copies on write if ref-count is not 1\n        a.mutate((slice){ slice[] = 1; });\n        assert(a.internalSlice == [1, 1, 1]);\n        assert(c.internalSlice == [3, 4, 5]);\n        assert(a.isBig && c.isBig);\n        assert(a.big.refcount == 1);\n        assert(c.big.refcount == 1);\n\n        auto e = d;\n        assert(e.big.refcount == 2);\n        auto f = d;\n        f = a;\n        assert(f.isBig);\n        assert(f.internalSlice == [1, 1, 1]);\n        assert(f.big.refcount == 2); // a & f\n        assert(e.big.refcount == 2); // d & e\n        a = c;\n        assert(f.big.refcount == 1); // f\n        assert(e.big.refcount == 2); // d & e\n        a = a;\n        a = a;\n        a = a;\n        assert(a.big.refcount == 2); // a & c\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/regex/internal/kickstart.d",
    "content": "/*\n    Kickstart is a coarse-grained \"filter\" engine that finds likely matches\n    to be verified by full-blown matcher.\n*/\nmodule std.regex.internal.kickstart;\n\npackage(std.regex):\n\nimport std.range.primitives, std.utf;\nimport std.regex.internal.ir;\n\n//utility for shiftOr, returns a minimum number of bytes to test in a Char\nuint effectiveSize(Char)()\n{\n    static if (is(Char == char))\n        return 1;\n    else static if (is(Char == wchar))\n        return 2;\n    else static if (is(Char == dchar))\n        return 3;\n    else\n        static assert(0);\n}\n\n/*\n    Kickstart engine using ShiftOr algorithm,\n    a bit parallel technique for inexact string searching.\n*/\nstruct ShiftOr(Char)\n{\nprivate:\n    uint[] table;\n    uint fChar;\n    uint n_length;\n    enum charSize =  effectiveSize!Char();\n    //maximum number of chars in CodepointSet to process\n    enum uint charsetThreshold = 32_000;\n    static struct ShiftThread\n    {\n        uint[] tab;\n        uint mask;\n        uint idx;\n        uint pc, counter, hops;\n        this(uint newPc, uint newCounter, uint[] table)\n        {\n            pc = newPc;\n            counter = newCounter;\n            mask = 1;\n            idx = 0;\n            hops = 0;\n            tab = table;\n        }\n\n        void setMask(uint idx, uint mask)\n        {\n            tab[idx] |= mask;\n        }\n\n        void setInvMask(uint idx, uint mask)\n        {\n            tab[idx] &= ~mask;\n        }\n\n        void set(alias setBits = setInvMask)(dchar ch)\n        {\n            static if (charSize == 3)\n            {\n                uint val = ch, tmask = mask;\n                setBits(val&0xFF, tmask);\n                tmask <<= 1;\n                val >>= 8;\n                setBits(val&0xFF, tmask);\n                tmask <<= 1;\n                val >>= 8;\n                assert(val <= 0x10);\n                setBits(val, tmask);\n                tmask <<= 1;\n            }\n            else\n            {\n                Char[dchar.sizeof/Char.sizeof] buf;\n                uint tmask = mask;\n                size_t total = encode(buf, ch);\n                for (size_t i = 0; i < total; i++, tmask<<=1)\n                {\n                    static if (charSize == 1)\n                        setBits(buf[i], tmask);\n                    else static if (charSize == 2)\n                    {\n                        setBits(buf[i]&0xFF, tmask);\n                        tmask <<= 1;\n                        setBits(buf[i]>>8, tmask);\n                    }\n                }\n            }\n        }\n        void add(dchar ch){ return set!setInvMask(ch); }\n        void advance(uint s)\n        {\n            mask <<= s;\n            idx += s;\n        }\n        @property bool full(){    return !mask; }\n    }\n\n    static ShiftThread fork(ShiftThread t, uint newPc, uint newCounter)\n    {\n        ShiftThread nt = t;\n        nt.pc = newPc;\n        nt.counter = newCounter;\n        return nt;\n    }\n\n    @trusted static ShiftThread fetch(ref ShiftThread[] worklist)\n    {\n        auto t = worklist[$-1];\n        worklist.length -= 1;\n        if (!__ctfe)\n            cast(void) worklist.assumeSafeAppend();\n        return t;\n    }\n\n    static uint charLen(uint ch)\n    {\n        assert(ch <= 0x10FFFF);\n        return codeLength!Char(cast(dchar) ch)*charSize;\n    }\n\npublic:\n    @trusted this(ref Regex!Char re, uint[] memory)\n    {\n        static import std.algorithm.comparison;\n        import std.algorithm.searching : countUntil;\n        import std.conv : text;\n        import std.range : assumeSorted;\n        assert(memory.length == 256);\n        fChar = uint.max;\n        // FNV-1a flavored hash (uses 32bits at a time)\n        ulong hash(uint[] tab)\n        {\n            ulong h = 0xcbf29ce484222325;\n            foreach (v; tab)\n            {\n                h ^= v;\n                h *= 0x100000001b3;\n            }\n            return h;\n        }\n    L_FindChar:\n        for (size_t i = 0;;)\n        {\n            switch (re.ir[i].code)\n            {\n                case IR.Char:\n                    fChar = re.ir[i].data;\n                    static if (charSize != 3)\n                    {\n                        Char[dchar.sizeof/Char.sizeof] buf;\n                        encode(buf, fChar);\n                        fChar = buf[0];\n                    }\n                    fChar = fChar & 0xFF;\n                    break L_FindChar;\n                case IR.GroupStart, IR.GroupEnd:\n                    i += IRL!(IR.GroupStart);\n                    break;\n                case IR.Bof, IR.Bol, IR.Wordboundary, IR.Notwordboundary:\n                    i += IRL!(IR.Bol);\n                    break;\n                default:\n                    break L_FindChar;\n            }\n        }\n        table = memory;\n        table[] =  uint.max;\n        alias MergeTab = bool[ulong];\n        // use reasonably complex hash to identify equivalent tables\n        auto merge = new MergeTab[re.hotspotTableSize];\n        ShiftThread[] trs;\n        ShiftThread t = ShiftThread(0, 0, table);\n        //locate first fixed char if any\n        n_length = 32;\n        for (;;)\n        {\n        L_Eval_Thread:\n            for (;;)\n            {\n                switch (re.ir[t.pc].code)\n                {\n                case IR.Char:\n                    uint s = charLen(re.ir[t.pc].data);\n                    if (t.idx+s > n_length)\n                        goto L_StopThread;\n                    t.add(re.ir[t.pc].data);\n                    t.advance(s);\n                    t.pc += IRL!(IR.Char);\n                    break;\n                case IR.OrChar://assumes IRL!(OrChar) == 1\n                    uint len = re.ir[t.pc].sequence;\n                    uint end = t.pc + len;\n                    uint[Bytecode.maxSequence] s;\n                    uint numS;\n                    for (uint i = 0; i < len; i++)\n                    {\n                        auto x = charLen(re.ir[t.pc+i].data);\n                        if (countUntil(s[0 .. numS], x) < 0)\n                           s[numS++] = x;\n                    }\n                    for (uint i = t.pc; i < end; i++)\n                    {\n                        t.add(re.ir[i].data);\n                    }\n                    for (uint i = 0; i < numS; i++)\n                    {\n                        auto tx = fork(t, t.pc + len, t.counter);\n                        if (tx.idx + s[i] <= n_length)\n                        {\n                            tx.advance(s[i]);\n                            trs ~= tx;\n                        }\n                    }\n                    if (!trs.empty)\n                        t = fetch(trs);\n                    else\n                        goto L_StopThread;\n                    break;\n                case IR.CodepointSet:\n                case IR.Trie:\n                    auto set = re.charsets[re.ir[t.pc].data];\n                    uint[4] s;\n                    uint numS;\n                    static if (charSize == 3)\n                    {\n                        s[0] = charSize;\n                        numS = 1;\n                    }\n                    else\n                    {\n\n                        static if (charSize == 1)\n                            static immutable codeBounds = [0x0, 0x7F, 0x80, 0x7FF, 0x800, 0xFFFF, 0x10000, 0x10FFFF];\n                        else //== 2\n                            static immutable codeBounds = [0x0, 0xFFFF, 0x10000, 0x10FFFF];\n                        uint[] arr = new uint[set.byInterval.length * 2];\n                        size_t ofs = 0;\n                        foreach (ival; set.byInterval)\n                        {\n                            arr[ofs++] = ival.a;\n                            arr[ofs++] = ival.b;\n                        }\n                        auto srange = assumeSorted!\"a <= b\"(arr);\n                        for (uint i = 0; i < codeBounds.length/2; i++)\n                        {\n                            auto start = srange.lowerBound(codeBounds[2*i]).length;\n                            auto end = srange.lowerBound(codeBounds[2*i+1]).length;\n                            if (end > start || (end == start && (end & 1)))\n                               s[numS++] = (i+1)*charSize;\n                        }\n                    }\n                    if (numS == 0 || t.idx + s[numS-1] > n_length)\n                        goto L_StopThread;\n                    auto  chars = set.length;\n                    if (chars > charsetThreshold)\n                        goto L_StopThread;\n                    foreach (ch; set.byCodepoint)\n                    {\n                        //avoid surrogate pairs\n                        if (0xD800 <= ch && ch <= 0xDFFF)\n                            continue;\n                        t.add(ch);\n                    }\n                    for (uint i = 0; i < numS; i++)\n                    {\n                        auto tx =  fork(t, t.pc + IRL!(IR.CodepointSet), t.counter);\n                        tx.advance(s[i]);\n                        trs ~= tx;\n                    }\n                    if (!trs.empty)\n                        t = fetch(trs);\n                    else\n                        goto L_StopThread;\n                    break;\n                case IR.Any:\n                    goto L_StopThread;\n\n                case IR.GotoEndOr:\n                    t.pc += IRL!(IR.GotoEndOr)+re.ir[t.pc].data;\n                    assert(re.ir[t.pc].code == IR.OrEnd);\n                    goto case;\n                case IR.OrEnd:\n                    auto slot = re.ir[t.pc+1].raw+t.counter;\n                    auto val = hash(t.tab);\n                    if (val in merge[slot])\n                        goto L_StopThread; // merge equivalent\n                    merge[slot][val] = true;\n                    t.pc += IRL!(IR.OrEnd);\n                    break;\n                case IR.OrStart:\n                    t.pc += IRL!(IR.OrStart);\n                    goto case;\n                case IR.Option:\n                    uint next = t.pc + re.ir[t.pc].data + IRL!(IR.Option);\n                    //queue next Option\n                    if (re.ir[next].code == IR.Option)\n                    {\n                        trs ~= fork(t, next, t.counter);\n                    }\n                    t.pc += IRL!(IR.Option);\n                    break;\n                case IR.RepeatStart:case IR.RepeatQStart:\n                    t.pc += IRL!(IR.RepeatStart)+re.ir[t.pc].data;\n                    goto case IR.RepeatEnd;\n                case IR.RepeatEnd:\n                case IR.RepeatQEnd:\n                    auto slot = re.ir[t.pc+1].raw+t.counter;\n                    auto val = hash(t.tab);\n                    if (val in merge[slot])\n                        goto L_StopThread; // merge equivalent\n                    merge[slot][val] = true;\n                    uint len = re.ir[t.pc].data;\n                    uint step = re.ir[t.pc+2].raw;\n                    uint min = re.ir[t.pc+3].raw;\n                    if (t.counter < min)\n                    {\n                        t.counter += step;\n                        t.pc -= len;\n                        break;\n                    }\n                    uint max = re.ir[t.pc+4].raw;\n                    if (t.counter < max)\n                    {\n                        trs ~= fork(t, t.pc - len, t.counter + step);\n                        t.counter = t.counter%step;\n                        t.pc += IRL!(IR.RepeatEnd);\n                    }\n                    else\n                    {\n                        t.counter = t.counter%step;\n                        t.pc += IRL!(IR.RepeatEnd);\n                    }\n                    break;\n                case IR.InfiniteStart, IR.InfiniteQStart:\n                    t.pc += re.ir[t.pc].data + IRL!(IR.InfiniteStart);\n                    goto case IR.InfiniteEnd; //both Q and non-Q\n                case IR.InfiniteEnd:\n                case IR.InfiniteQEnd:\n                    auto slot = re.ir[t.pc+1].raw+t.counter;\n                    auto val = hash(t.tab);\n                    if (val in merge[slot])\n                        goto L_StopThread; // merge equivalent\n                    merge[slot][val] = true;\n                    uint len = re.ir[t.pc].data;\n                    uint pc1, pc2; //branches to take in priority order\n                    if (++t.hops == 32)\n                        goto L_StopThread;\n                    pc1 = t.pc + IRL!(IR.InfiniteEnd);\n                    pc2 = t.pc - len;\n                    trs ~= fork(t, pc2, t.counter);\n                    t.pc = pc1;\n                    break;\n                case IR.GroupStart, IR.GroupEnd:\n                    t.pc += IRL!(IR.GroupStart);\n                    break;\n                case IR.Bof, IR.Bol, IR.Wordboundary, IR.Notwordboundary:\n                    t.pc += IRL!(IR.Bol);\n                    break;\n                case IR.LookaheadStart, IR.NeglookaheadStart, IR.LookbehindStart, IR.NeglookbehindStart:\n                    t.pc += IRL!(IR.LookaheadStart) + IRL!(IR.LookaheadEnd) + re.ir[t.pc].data;\n                    break;\n                default:\n                L_StopThread:\n                    assert(re.ir[t.pc].code >= 0x80, text(re.ir[t.pc].code));\n                    debug (fred_search) writeln(\"ShiftOr stumbled on \",re.ir[t.pc].mnemonic);\n                    n_length = std.algorithm.comparison.min(t.idx, n_length);\n                    break L_Eval_Thread;\n                }\n            }\n            if (trs.empty)\n                break;\n            t = fetch(trs);\n        }\n        debug(std_regex_search)\n        {\n            writeln(\"Min length: \", n_length);\n        }\n    }\n\n    @property bool empty() const {  return n_length == 0; }\n\n    @property uint length() const{ return n_length/charSize; }\n\n    // lookup compatible bit pattern in haystack, return starting index\n    // has a useful trait: if supplied with valid UTF indexes,\n    // returns only valid UTF indexes\n    // (that given the haystack in question is valid UTF string)\n    @trusted size_t search(const(Char)[] haystack, size_t idx) const\n    {//@BUG: apparently assumes little endian machines\n        import core.stdc.string : memchr;\n        import std.conv : text;\n        assert(!empty);\n        auto p = cast(const(ubyte)*)(haystack.ptr+idx);\n        uint state = uint.max;\n        uint limit = 1u<<(n_length - 1u);\n        debug(std_regex_search) writefln(\"Limit: %32b\",limit);\n        if (fChar != uint.max)\n        {\n            const(ubyte)* end = cast(ubyte*)(haystack.ptr + haystack.length);\n            const orginalAlign = cast(size_t) p & (Char.sizeof-1);\n            while (p != end)\n            {\n                if (!~state)\n                {//speed up seeking first matching place\n                    for (;;)\n                    {\n                        assert(p <= end, text(p,\" vs \", end));\n                        p = cast(ubyte*) memchr(p, fChar, end - p);\n                        if (!p)\n                            return haystack.length;\n                        if ((cast(size_t) p & (Char.sizeof-1)) == orginalAlign)\n                            break;\n                        if (++p == end)\n                            return haystack.length;\n                    }\n                    state = ~1u;\n                    assert((cast(size_t) p & (Char.sizeof-1)) == orginalAlign);\n                    static if (charSize == 3)\n                    {\n                        state = (state << 1) | table[p[1]];\n                        state = (state << 1) | table[p[2]];\n                        p += 4;\n                    }\n                    else\n                        p++;\n                    //first char is tested, see if that's all\n                    if (!(state & limit))\n                        return (p-cast(ubyte*) haystack.ptr)/Char.sizeof\n                            -length;\n                }\n                else\n                {//have some bits/states for possible matches,\n                 //use the usual shift-or cycle\n                    static if (charSize == 3)\n                    {\n                        state = (state << 1) | table[p[0]];\n                        state = (state << 1) | table[p[1]];\n                        state = (state << 1) | table[p[2]];\n                        p += 4;\n                    }\n                    else\n                    {\n                        state = (state << 1) | table[p[0]];\n                        p++;\n                    }\n                    if (!(state & limit))\n                        return (p-cast(ubyte*) haystack.ptr)/Char.sizeof\n                            -length;\n                }\n                debug(std_regex_search) writefln(\"State: %32b\", state);\n            }\n        }\n        else\n        {\n            //normal path, partially unrolled for char/wchar\n            static if (charSize == 3)\n            {\n                const(ubyte)* end = cast(ubyte*)(haystack.ptr + haystack.length);\n                while (p != end)\n                {\n                    state = (state << 1) | table[p[0]];\n                    state = (state << 1) | table[p[1]];\n                    state = (state << 1) | table[p[2]];\n                    p += 4;\n                    if (!(state & limit))//division rounds down for dchar\n                        return (p-cast(ubyte*) haystack.ptr)/Char.sizeof\n                        -length;\n                }\n            }\n            else\n            {\n                auto len = cast(ubyte*)(haystack.ptr + haystack.length) - p;\n                size_t i  = 0;\n                if (len & 1)\n                {\n                    state = (state << 1) | table[p[i++]];\n                    if (!(state & limit))\n                        return idx+i/Char.sizeof-length;\n                }\n                while (i < len)\n                {\n                    state = (state << 1) | table[p[i++]];\n                    if (!(state & limit))\n                        return idx+i/Char.sizeof\n                            -length;\n                    state = (state << 1) | table[p[i++]];\n                    if (!(state & limit))\n                        return idx+i/Char.sizeof\n                            -length;\n                    debug(std_regex_search) writefln(\"State: %32b\", state);\n                }\n            }\n        }\n        return haystack.length;\n    }\n\n    @system debug static void dump(uint[] table)\n    {//@@@BUG@@@ writef(ln) is @system\n        import std.stdio : writefln;\n        for (size_t i = 0; i < table.length; i += 4)\n        {\n            writefln(\"%32b %32b %32b %32b\",table[i], table[i+1], table[i+2], table[i+3]);\n        }\n    }\n}\n\n@system unittest\n{\n    import std.conv, std.regex;\n    @trusted void test_fixed(alias Kick)()\n    {\n        static foreach (i, v; AliasSeq!(char, wchar, dchar))\n        {{\n            alias Char = v;\n            alias String = immutable(v)[];\n            auto r = regex(to!String(`abc$`));\n            auto kick = Kick!Char(r, new uint[256]);\n            assert(kick.length == 3, text(Kick.stringof,\" \",v.stringof, \" == \", kick.length));\n            auto r2 = regex(to!String(`(abc){2}a+`));\n            kick = Kick!Char(r2, new uint[256]);\n            assert(kick.length == 7, text(Kick.stringof,v.stringof,\" == \", kick.length));\n            auto r3 = regex(to!String(`\\b(a{2}b{3}){2,4}`));\n            kick = Kick!Char(r3, new uint[256]);\n            assert(kick.length == 10, text(Kick.stringof,v.stringof,\" == \", kick.length));\n            auto r4 = regex(to!String(`\\ba{2}c\\bxyz`));\n            kick = Kick!Char(r4, new uint[256]);\n            assert(kick.length == 6, text(Kick.stringof,v.stringof, \" == \", kick.length));\n            auto r5 = regex(to!String(`\\ba{2}c\\b`));\n            kick = Kick!Char(r5, new uint[256]);\n            size_t x = kick.search(\"aabaacaa\", 0);\n            assert(x == 3, text(Kick.stringof,v.stringof,\" == \", kick.length));\n            x = kick.search(\"aabaacaa\", x+1);\n            assert(x == 8, text(Kick.stringof,v.stringof,\" == \", kick.length));\n        }}\n    }\n    @trusted void test_flex(alias Kick)()\n    {\n        static foreach (i, v; AliasSeq!(char, wchar, dchar))\n        {{\n            alias Char = v;\n            alias String = immutable(v)[];\n            auto r = regex(to!String(`abc[a-z]`));\n            auto kick = Kick!Char(r, new uint[256]);\n            auto x = kick.search(to!String(\"abbabca\"), 0);\n            assert(x == 3, text(\"real x is \", x, \" \",v.stringof));\n\n            auto r2 = regex(to!String(`(ax|bd|cdy)`));\n            String s2 = to!String(\"abdcdyabax\");\n            kick = Kick!Char(r2, new uint[256]);\n            x = kick.search(s2, 0);\n            assert(x == 1, text(\"real x is \", x));\n            x = kick.search(s2, x+1);\n            assert(x == 3, text(\"real x is \", x));\n            x = kick.search(s2, x+1);\n            assert(x == 8, text(\"real x is \", x));\n            auto rdot = regex(to!String(`...`));\n            kick = Kick!Char(rdot, new uint[256]);\n            assert(kick.length == 0);\n            auto rN = regex(to!String(`a(b+|c+)x`));\n            kick = Kick!Char(rN, new uint[256]);\n            assert(kick.length == 3, to!string(kick.length));\n            assert(kick.search(\"ababx\",0) == 2);\n            assert(kick.search(\"abaacba\",0) == 3);//expected inexact\n\n        }}\n    }\n    test_fixed!(ShiftOr)();\n    test_flex!(ShiftOr)();\n}\n\nalias Kickstart = ShiftOr;\n"
  },
  {
    "path": "libphobos/src/std/regex/internal/parser.d",
    "content": "//Written in the D programming language\n/*\n    Regular expression pattern parser.\n*/\nmodule std.regex.internal.parser;\n\nimport std.regex.internal.ir;\nimport std.range.primitives, std.uni, std.meta,\n    std.traits, std.typecons, std.exception;\nstatic import std.ascii;\n\n// package relevant info from parser into a regex object\nauto makeRegex(S, CG)(Parser!(S, CG) p)\n{\n    import std.regex.internal.backtracking : BacktrackingMatcher;\n    import std.regex.internal.thompson : ThompsonMatcher;\n    import std.algorithm.searching : canFind;\n    alias Char = BasicElementOf!S;\n    Regex!Char re;\n    auto g = p.g;\n    with(re)\n    {\n        ir = g.ir;\n        dict = g.dict;\n        ngroup = g.ngroup;\n        maxCounterDepth = g.counterDepth;\n        flags = p.re_flags;\n        charsets = g.charsets;\n        matchers = g.matchers;\n        backrefed = g.backrefed;\n        re.pattern = p.origin.idup;\n        re.postprocess();\n        // check if we have backreferences, if so - use backtracking\n        if (__ctfe) factory = null; // allows us to use the awful enum re = regex(...);\n        else if (re.backrefed.canFind!\"a != 0\")\n            factory =  new RuntimeFactory!(BacktrackingMatcher, Char);\n        else\n            factory = new RuntimeFactory!(ThompsonMatcher, Char);\n        debug(std_regex_parser)\n        {\n            __ctfe || print();\n        }\n        //@@@BUG@@@ (not reduced)\n        //somehow just using validate _collides_ with std.utf.validate (!)\n        version (assert) re.validateRe();\n    }\n    return re;\n}\n\n// helper for unittest\nauto makeRegex(S)(S arg)\nif (isSomeString!S)\n{\n    return makeRegex(Parser!(S, CodeGen)(arg, \"\"));\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    auto re = makeRegex(`(?P<name>\\w+) = (?P<var>\\d+)`);\n    auto nc = re.namedCaptures;\n    static assert(isRandomAccessRange!(typeof(nc)));\n    assert(!nc.empty);\n    assert(nc.length == 2);\n    assert(nc.equal([\"name\", \"var\"]));\n    assert(nc[0] == \"name\");\n    assert(nc[1..$].equal([\"var\"]));\n\n    re = makeRegex(`(\\w+) (?P<named>\\w+) (\\w+)`);\n    nc = re.namedCaptures;\n    assert(nc.length == 1);\n    assert(nc[0] == \"named\");\n    assert(nc.front == \"named\");\n    assert(nc.back == \"named\");\n\n    re = makeRegex(`(\\w+) (\\w+)`);\n    nc = re.namedCaptures;\n    assert(nc.empty);\n\n    re = makeRegex(`(?P<year>\\d{4})/(?P<month>\\d{2})/(?P<day>\\d{2})/`);\n    nc = re.namedCaptures;\n    auto cp = nc.save;\n    assert(nc.equal(cp));\n    nc.popFront();\n    assert(nc.equal(cp[1..$]));\n    nc.popBack();\n    assert(nc.equal(cp[1 .. $ - 1]));\n}\n\n\n@trusted void reverseBytecode()(Bytecode[] code)\n{\n    Bytecode[] rev = new Bytecode[code.length];\n    uint revPc = cast(uint) rev.length;\n    Stack!(Tuple!(uint, uint, uint)) stack;\n    uint start = 0;\n    uint end = cast(uint) code.length;\n    for (;;)\n    {\n        for (uint pc = start; pc < end; )\n        {\n            immutable len = code[pc].length;\n            if (code[pc].code == IR.GotoEndOr)\n                break; //pick next alternation branch\n            if (code[pc].isAtom)\n            {\n                rev[revPc - len .. revPc] = code[pc .. pc + len];\n                revPc -= len;\n                pc += len;\n            }\n            else if (code[pc].isStart || code[pc].isEnd)\n            {\n                //skip over other embedded lookbehinds they are reversed\n                if (code[pc].code == IR.LookbehindStart\n                    || code[pc].code == IR.NeglookbehindStart)\n                {\n                    immutable blockLen = len + code[pc].data\n                         + code[pc].pairedLength;\n                    rev[revPc - blockLen .. revPc] = code[pc .. pc + blockLen];\n                    pc += blockLen;\n                    revPc -= blockLen;\n                    continue;\n                }\n                immutable second = code[pc].indexOfPair(pc);\n                immutable secLen = code[second].length;\n                rev[revPc - secLen .. revPc] = code[second .. second + secLen];\n                revPc -= secLen;\n                if (code[pc].code == IR.OrStart)\n                {\n                    //we pass len bytes forward, but secLen in reverse\n                    immutable revStart = revPc - (second + len - secLen - pc);\n                    uint r = revStart;\n                    uint i = pc + IRL!(IR.OrStart);\n                    while (code[i].code == IR.Option)\n                    {\n                        if (code[i - 1].code != IR.OrStart)\n                        {\n                            assert(code[i - 1].code == IR.GotoEndOr);\n                            rev[r - 1] = code[i - 1];\n                        }\n                        rev[r] = code[i];\n                        auto newStart = i + IRL!(IR.Option);\n                        auto newEnd = newStart + code[i].data;\n                        auto newRpc = r + code[i].data + IRL!(IR.Option);\n                        if (code[newEnd].code != IR.OrEnd)\n                        {\n                            newRpc--;\n                        }\n                        stack.push(tuple(newStart, newEnd, newRpc));\n                        r += code[i].data + IRL!(IR.Option);\n                        i += code[i].data + IRL!(IR.Option);\n                    }\n                    pc = i;\n                    revPc = revStart;\n                    assert(code[pc].code == IR.OrEnd);\n                }\n                else\n                    pc += len;\n            }\n        }\n        if (stack.empty)\n            break;\n        start = stack.top[0];\n        end = stack.top[1];\n        revPc = stack.top[2];\n        stack.pop();\n    }\n    code[] = rev[];\n}\n\nstruct CodeGen\n{\n    Bytecode[] ir;                 // resulting bytecode\n    Stack!(uint) fixupStack;       // stack of opened start instructions\n    NamedGroup[] dict;             // maps name -> user group number\n    Stack!(uint) groupStack;       // stack of current number of group\n    uint nesting = 0;              // group nesting level and repetitions step\n    uint lookaroundNest = 0;       // nesting of lookaround\n    uint counterDepth = 0;         // current depth of nested counted repetitions\n    CodepointSet[] charsets;       // sets for char classes\n    const(CharMatcher)[] matchers; // matchers for char classes\n    uint[] backrefed;              // bitarray for groups refered by backref\n    uint ngroup;                   // final number of groups (of all patterns)\n\n    void start(uint length)\n    {\n        if (!__ctfe)\n            ir.reserve((length*5+2)/4);\n        fixupStack.push(0);\n        groupStack.push(1);//0 - whole match\n    }\n\n    //mark referenced groups for latter processing\n    void markBackref(uint n)\n    {\n        if (n/32 >= backrefed.length)\n            backrefed.length = n/32 + 1;\n        backrefed[n / 32] |= 1 << (n & 31);\n    }\n\n    bool isOpenGroup(uint n)\n    {\n        import std.algorithm.searching : canFind;\n        // walk the fixup stack and see if there are groups labeled 'n'\n        // fixup '0' is reserved for alternations\n        return fixupStack.data[1..$].\n            canFind!(fix => ir[fix].code == IR.GroupStart && ir[fix].data == n)();\n    }\n\n    void put(Bytecode code)\n    {\n        enforce(ir.length < maxCompiledLength,\n            \"maximum compiled pattern length is exceeded\");\n        ir ~= code;\n    }\n\n    void putRaw(uint number)\n    {\n        enforce(ir.length < maxCompiledLength,\n            \"maximum compiled pattern length is exceeded\");\n        ir ~= Bytecode.fromRaw(number);\n    }\n\n    //try to generate optimal IR code for this CodepointSet\n    @trusted void charsetToIr(CodepointSet set)\n    {//@@@BUG@@@ writeln is @system\n        uint chars = cast(uint) set.length;\n        if (chars < Bytecode.maxSequence)\n        {\n            switch (chars)\n            {\n                case 1:\n                    put(Bytecode(IR.Char, set.byCodepoint.front));\n                    break;\n                case 0:\n                    throw new RegexException(\"empty CodepointSet not allowed\");\n                default:\n                    foreach (ch; set.byCodepoint)\n                        put(Bytecode(IR.OrChar, ch, chars));\n            }\n        }\n        else\n        {\n            import std.algorithm.searching : countUntil;\n            const ivals = set.byInterval;\n            immutable n = charsets.countUntil(set);\n            if (n >= 0)\n            {\n                if (ivals.length*2 > maxCharsetUsed)\n                    put(Bytecode(IR.Trie, cast(uint) n));\n                else\n                    put(Bytecode(IR.CodepointSet, cast(uint) n));\n                return;\n            }\n            if (ivals.length*2 > maxCharsetUsed)\n            {\n                auto t  = getMatcher(set);\n                put(Bytecode(IR.Trie, cast(uint) matchers.length));\n                matchers ~= t;\n                debug(std_regex_allocation) writeln(\"Trie generated\");\n            }\n            else\n            {\n                put(Bytecode(IR.CodepointSet, cast(uint) charsets.length));\n                matchers ~= CharMatcher.init;\n            }\n            charsets ~= set;\n            assert(charsets.length == matchers.length);\n        }\n    }\n\n    void genLogicGroup()\n    {\n        nesting++;\n        pushFixup(length);\n        put(Bytecode(IR.Nop, 0));\n    }\n\n    void genGroup()\n    {\n        nesting++;\n        pushFixup(length);\n        immutable nglob = groupStack.top++;\n        enforce(groupStack.top <= maxGroupNumber, \"limit on number of submatches is exceeded\");\n        put(Bytecode(IR.GroupStart, nglob));\n    }\n\n    void genNamedGroup(string name)\n    {\n        import std.array : insertInPlace;\n        import std.range : assumeSorted;\n        nesting++;\n        pushFixup(length);\n        immutable nglob = groupStack.top++;\n        enforce(groupStack.top <= maxGroupNumber, \"limit on submatches is exceeded\");\n        auto t = NamedGroup(name, nglob);\n        auto d = assumeSorted!\"a.name < b.name\"(dict);\n        immutable ind = d.lowerBound(t).length;\n        insertInPlace(dict, ind, t);\n        put(Bytecode(IR.GroupStart, nglob));\n    }\n\n        //generate code for start of lookaround: (?= (?! (?<= (?<!\n    void genLookaround(IR opcode)\n    {\n        nesting++;\n        pushFixup(length);\n        put(Bytecode(opcode, 0));\n        put(Bytecode.fromRaw(0));\n        put(Bytecode.fromRaw(0));\n        groupStack.push(0);\n        lookaroundNest++;\n        enforce(lookaroundNest <= maxLookaroundDepth,\n            \"maximum lookaround depth is exceeded\");\n    }\n\n    void endPattern(uint num)\n    {\n        import std.algorithm.comparison : max;\n        put(Bytecode(IR.End, num));\n        ngroup = max(ngroup, groupStack.top);\n        groupStack.top = 1; // reset group counter\n    }\n\n    //fixup lookaround with start at offset fix and append a proper *-End opcode\n    void fixLookaround(uint fix)\n    {\n        lookaroundNest--;\n        ir[fix] = Bytecode(ir[fix].code,\n            cast(uint) ir.length - fix - IRL!(IR.LookaheadStart));\n        auto g = groupStack.pop();\n        assert(!groupStack.empty);\n        ir[fix+1] = Bytecode.fromRaw(groupStack.top);\n        //groups are cumulative across lookarounds\n        ir[fix+2] = Bytecode.fromRaw(groupStack.top+g);\n        groupStack.top += g;\n        if (ir[fix].code == IR.LookbehindStart || ir[fix].code == IR.NeglookbehindStart)\n        {\n            reverseBytecode(ir[fix + IRL!(IR.LookbehindStart) .. $]);\n        }\n        put(ir[fix].paired);\n    }\n\n    // repetition of {1,1}\n    void fixRepetition(uint offset)\n    {\n        import std.algorithm.mutation : copy;\n        immutable replace = ir[offset].code == IR.Nop;\n        if (replace)\n        {\n            copy(ir[offset + 1 .. $], ir[offset .. $ - 1]);\n            ir.length -= 1;\n        }\n    }\n\n    // repetition of {x,y}\n    void fixRepetition(uint offset, uint min, uint max, bool greedy)\n    {\n        static import std.algorithm.comparison;\n        import std.algorithm.mutation : copy;\n        import std.array : insertInPlace;\n        immutable replace = ir[offset].code == IR.Nop;\n        immutable len = cast(uint) ir.length - offset - replace;\n        if (max != infinite)\n        {\n            if (min != 1 || max != 1)\n            {\n                Bytecode op = Bytecode(greedy ? IR.RepeatStart : IR.RepeatQStart, len);\n                if (replace)\n                    ir[offset] = op;\n                else\n                    insertInPlace(ir, offset, op);\n                put(Bytecode(greedy ? IR.RepeatEnd : IR.RepeatQEnd, len));\n                put(Bytecode.init); //hotspot\n                putRaw(1);\n                putRaw(min);\n                putRaw(max);\n                counterDepth = std.algorithm.comparison.max(counterDepth, nesting+1);\n            }\n        }\n        else if (min) //&& max is infinite\n        {\n            if (min != 1)\n            {\n                Bytecode op = Bytecode(greedy ? IR.RepeatStart : IR.RepeatQStart, len);\n                if (replace)\n                    ir[offset] = op;\n                else\n                    insertInPlace(ir, offset, op);\n                offset += 1;//so it still points to the repeated block\n                put(Bytecode(greedy ? IR.RepeatEnd : IR.RepeatQEnd, len));\n                put(Bytecode.init); //hotspot\n                putRaw(1);\n                putRaw(min);\n                putRaw(min);\n                counterDepth = std.algorithm.comparison.max(counterDepth, nesting+1);\n            }\n            else if (replace)\n            {\n                copy(ir[offset+1 .. $], ir[offset .. $-1]);\n                ir.length -= 1;\n            }\n            put(Bytecode(greedy ? IR.InfiniteStart : IR.InfiniteQStart, len));\n            enforce(ir.length + len < maxCompiledLength,  \"maximum compiled pattern length is exceeded\");\n            ir ~= ir[offset .. offset+len];\n            //IR.InfinteX is always a hotspot\n            put(Bytecode(greedy ? IR.InfiniteEnd : IR.InfiniteQEnd, len));\n            put(Bytecode.init); //merge index\n        }\n        else//vanila {0,inf}\n        {\n            Bytecode op = Bytecode(greedy ? IR.InfiniteStart : IR.InfiniteQStart, len);\n            if (replace)\n                ir[offset] = op;\n            else\n                insertInPlace(ir, offset, op);\n            //IR.InfinteX is always a hotspot\n            put(Bytecode(greedy ? IR.InfiniteEnd : IR.InfiniteQEnd, len));\n            put(Bytecode.init); //merge index\n        }\n    }\n\n    void fixAlternation()\n    {\n        import std.array : insertInPlace;\n        uint fix = fixupStack.top;\n        if (ir.length > fix && ir[fix].code == IR.Option)\n        {\n            ir[fix] = Bytecode(ir[fix].code, cast(uint) ir.length - fix);\n            put(Bytecode(IR.GotoEndOr, 0));\n            fixupStack.top = cast(uint) ir.length; //replace latest fixup for Option\n            put(Bytecode(IR.Option, 0));\n            return;\n        }\n        uint len, orStart;\n        //start a new option\n        if (fixupStack.length == 1)\n        {//only root entry, effectively no fixup\n            len = cast(uint) ir.length + IRL!(IR.GotoEndOr);\n            orStart = 0;\n        }\n        else\n        {//IR.lookahead, etc. fixups that have length > 1, thus check ir[x].length\n            len = cast(uint) ir.length - fix - (ir[fix].length - 1);\n            orStart = fix + ir[fix].length;\n        }\n        insertInPlace(ir, orStart, Bytecode(IR.OrStart, 0), Bytecode(IR.Option, len));\n        assert(ir[orStart].code == IR.OrStart);\n        put(Bytecode(IR.GotoEndOr, 0));\n        fixupStack.push(orStart); //fixup for StartOR\n        fixupStack.push(cast(uint) ir.length); //for second Option\n        put(Bytecode(IR.Option, 0));\n    }\n\n    // finalizes IR.Option, fix points to the first option of sequence\n    void finishAlternation(uint fix)\n    {\n        enforce(ir[fix].code == IR.Option, \"no matching ')'\");\n        ir[fix] = Bytecode(ir[fix].code, cast(uint) ir.length - fix - IRL!(IR.OrStart));\n        fix = fixupStack.pop();\n        enforce(ir[fix].code == IR.OrStart, \"no matching ')'\");\n        ir[fix] = Bytecode(IR.OrStart, cast(uint) ir.length - fix - IRL!(IR.OrStart));\n        put(Bytecode(IR.OrEnd, cast(uint) ir.length - fix - IRL!(IR.OrStart)));\n        uint pc = fix + IRL!(IR.OrStart);\n        while (ir[pc].code == IR.Option)\n        {\n            pc = pc + ir[pc].data;\n            if (ir[pc].code != IR.GotoEndOr)\n                break;\n            ir[pc] = Bytecode(IR.GotoEndOr, cast(uint)(ir.length - pc - IRL!(IR.OrEnd)));\n            pc += IRL!(IR.GotoEndOr);\n        }\n        put(Bytecode.fromRaw(0));\n    }\n\n    // returns: (flag - repetition possible?, fixup of the start of this \"group\")\n    Tuple!(bool, uint) onClose()\n    {\n        nesting--;\n        uint fix = popFixup();\n        switch (ir[fix].code)\n        {\n        case IR.GroupStart:\n            put(Bytecode(IR.GroupEnd, ir[fix].data));\n            return tuple(true, fix);\n        case IR.LookaheadStart, IR.NeglookaheadStart, IR.LookbehindStart, IR.NeglookbehindStart:\n            assert(lookaroundNest);\n            fixLookaround(fix);\n            return tuple(false, 0u);\n        case IR.Option: //| xxx )\n            //two fixups: last option + full OR\n            finishAlternation(fix);\n            fix = topFixup;\n            switch (ir[fix].code)\n            {\n            case IR.GroupStart:\n                popFixup();\n                put(Bytecode(IR.GroupEnd, ir[fix].data));\n                return tuple(true, fix);\n            case IR.LookaheadStart, IR.NeglookaheadStart, IR.LookbehindStart, IR.NeglookbehindStart:\n                assert(lookaroundNest);\n                fix = popFixup();\n                fixLookaround(fix);\n                return tuple(false, 0u);\n            default://(?:xxx)\n                popFixup();\n                return tuple(true, fix);\n            }\n        default://(?:xxx)\n            return tuple(true, fix);\n        }\n    }\n\n    uint popFixup(){ return fixupStack.pop(); }\n\n    void pushFixup(uint val){ return fixupStack.push(val); }\n\n    @property uint topFixup(){ return fixupStack.top; }\n\n    @property size_t fixupLength(){ return fixupStack.data.length; }\n\n    @property uint length(){ return cast(uint) ir.length; }\n}\n\n// safety limits\nenum maxGroupNumber = 2^^19;\nenum maxLookaroundDepth = 16;\n// *Bytecode.sizeof, i.e. 1Mb of bytecode alone\nenum maxCompiledLength = 2^^18;\n// amounts to up to 4 Mb of auxilary table for matching\nenum maxCumulativeRepetitionLength = 2^^20;\n// marker to indicate infinite repetition\nenum infinite = ~0u;\n\nstruct Parser(R, Generator)\nif (isForwardRange!R && is(ElementType!R : dchar))\n{\n    dchar front;\n    bool empty;\n    R pat, origin;       //keep full pattern for pretty printing error messages\n    uint re_flags = 0;   //global flags e.g. multiline + internal ones\n    Generator g;\n\n    @trusted this(S)(R pattern, S flags)\n        if (isSomeString!S)\n    {\n        pat = origin = pattern;\n        //reserve slightly more then avg as sampled from unittests\n        parseFlags(flags);\n        front = ' ';//a safe default for freeform parsing\n        popFront();\n        g.start(cast(uint) pat.length);\n        try\n        {\n            parseRegex();\n        }\n        catch (Exception e)\n        {\n            error(e.msg);//also adds pattern location\n        }\n        g.endPattern(1);\n    }\n\n    void _popFront()\n    {\n        if (pat.empty)\n        {\n            empty =  true;\n        }\n        else\n        {\n            front = pat.front;\n            pat.popFront();\n        }\n    }\n\n    void skipSpace()\n    {\n        while (!empty && isWhite(front)) _popFront();\n    }\n\n    void popFront()\n    {\n        _popFront();\n        if (re_flags & RegexOption.freeform) skipSpace();\n    }\n\n    auto save(){ return this; }\n\n    //parsing number with basic overflow check\n    uint parseDecimal()\n    {\n        uint r = 0;\n        while (std.ascii.isDigit(front))\n        {\n            if (r >= (uint.max/10))\n                error(\"Overflow in decimal number\");\n            r = 10*r + cast(uint)(front-'0');\n            popFront();\n            if (empty) break;\n        }\n        return r;\n    }\n\n    //\n    @trusted void parseFlags(S)(S flags)\n    {//@@@BUG@@@ text is @system\n        import std.conv : text;\n        foreach (ch; flags)//flags are ASCII anyway\n        {\n        L_FlagSwitch:\n            switch (ch)\n            {\n\n                foreach (i, op; __traits(allMembers, RegexOption))\n                {\n                    case RegexOptionNames[i]:\n                            if (re_flags & mixin(\"RegexOption.\"~op))\n                                throw new RegexException(text(\"redundant flag specified: \",ch));\n                            re_flags |= mixin(\"RegexOption.\"~op);\n                            break L_FlagSwitch;\n                }\n                default:\n                    throw new RegexException(text(\"unknown regex flag '\",ch,\"'\"));\n            }\n        }\n    }\n\n    //parse and store IR for regex pattern\n    @trusted void parseRegex()\n    {\n        uint fix;//fixup pointer\n\n        while (!empty)\n        {\n            debug(std_regex_parser)\n                __ctfe || writeln(\"*LR*\\nSource: \", pat, \"\\nStack: \",fixupStack.data);\n            switch (front)\n            {\n            case '(':\n                popFront();\n                if (front == '?')\n                {\n                    popFront();\n                    switch (front)\n                    {\n                    case '#':\n                        for (;;)\n                        {\n                            popFront();\n                            enforce(!empty, \"Unexpected end of pattern\");\n                            if (front == ')')\n                            {\n                                popFront();\n                                break;\n                            }\n                        }\n                        break;\n                    case ':':\n                        g.genLogicGroup();\n                        popFront();\n                        break;\n                    case '=':\n                        g.genLookaround(IR.LookaheadStart);\n                        popFront();\n                        break;\n                    case '!':\n                        g.genLookaround(IR.NeglookaheadStart);\n                        popFront();\n                        break;\n                    case 'P':\n                        popFront();\n                        enforce(front == '<', \"Expected '<' in named group\");\n                        string name;\n                        popFront();\n                        if (empty || !(isAlpha(front) || front == '_'))\n                            error(\"Expected alpha starting a named group\");\n                        name ~= front;\n                        popFront();\n                        while (!empty && (isAlpha(front) ||\n                            front == '_' || std.ascii.isDigit(front)))\n                        {\n                            name ~= front;\n                            popFront();\n                        }\n                        enforce(front == '>', \"Expected '>' closing named group\");\n                        popFront();\n                        g.genNamedGroup(name);\n                        break;\n                    case '<':\n                        popFront();\n                        if (front == '=')\n                            g.genLookaround(IR.LookbehindStart);\n                        else if (front == '!')\n                            g.genLookaround(IR.NeglookbehindStart);\n                        else\n                            error(\"'!' or '=' expected after '<'\");\n                        popFront();\n                        break;\n                    default:\n                        uint enableFlags, disableFlags;\n                        bool enable = true;\n                        do\n                        {\n                            switch (front)\n                            {\n                            case 's':\n                                if (enable)\n                                    enableFlags |= RegexOption.singleline;\n                                else\n                                    disableFlags |= RegexOption.singleline;\n                                break;\n                            case 'x':\n                                if (enable)\n                                    enableFlags |= RegexOption.freeform;\n                                else\n                                    disableFlags |= RegexOption.freeform;\n                                break;\n                            case 'i':\n                                if (enable)\n                                    enableFlags |= RegexOption.casefold;\n                                else\n                                    disableFlags |= RegexOption.casefold;\n                                break;\n                            case 'm':\n                                if (enable)\n                                    enableFlags |= RegexOption.multiline;\n                                else\n                                    disableFlags |= RegexOption.multiline;\n                                break;\n                            case '-':\n                                if (!enable)\n                                    error(\" unexpected second '-' in flags\");\n                                enable = false;\n                                break;\n                            default:\n                                error(\" 's', 'x', 'i', 'm' or '-' expected after '(?' \");\n                            }\n                            popFront();\n                        }while (front != ')');\n                        popFront();\n                        re_flags |= enableFlags;\n                        re_flags &= ~disableFlags;\n                    }\n                }\n                else\n                {\n                    g.genGroup();\n                }\n                break;\n            case ')':\n                enforce(g.nesting, \"Unmatched ')'\");\n                popFront();\n                auto pair = g.onClose();\n                if (pair[0])\n                    parseQuantifier(pair[1]);\n                break;\n            case '|':\n                popFront();\n                g.fixAlternation();\n                break;\n            default://no groups or whatever\n                immutable start = g.length;\n                parseAtom();\n                parseQuantifier(start);\n            }\n        }\n\n        if (g.fixupLength != 1)\n        {\n            fix = g.popFixup();\n            g.finishAlternation(fix);\n            enforce(g.fixupLength == 1, \"no matching ')'\");\n        }\n    }\n\n\n    //parse and store IR for atom-quantifier pair\n    @trusted void parseQuantifier(uint offset)\n    {//copy is @system\n        if (empty)\n            return g.fixRepetition(offset);\n        uint min, max;\n        switch (front)\n        {\n        case '*':\n            min = 0;\n            max = infinite;\n            break;\n        case '?':\n            min = 0;\n            max = 1;\n            break;\n        case '+':\n            min = 1;\n            max = infinite;\n            break;\n        case '{':\n            popFront();\n            enforce(!empty, \"Unexpected end of regex pattern\");\n            enforce(std.ascii.isDigit(front), \"First number required in repetition\");\n            min = parseDecimal();\n            if (front == '}')\n                max = min;\n            else if (front == ',')\n            {\n                popFront();\n                if (std.ascii.isDigit(front))\n                    max = parseDecimal();\n                else if (front == '}')\n                    max = infinite;\n                else\n                    error(\"Unexpected symbol in regex pattern\");\n                skipSpace();\n                enforce(front == '}', \"Unmatched '{' in regex pattern\");\n            }\n            else\n                error(\"Unexpected symbol in regex pattern\");\n            enforce(min <= max, \"Illegal {n,m} quantifier\");\n            break;\n        default:\n            g.fixRepetition(offset);\n            return;\n        }\n        bool greedy = true;\n        //check only if we managed to get new symbol\n        popFront();\n        if (!empty && front == '?')\n        {\n            greedy = false;\n            popFront();\n        }\n        g.fixRepetition(offset, min, max, greedy);\n    }\n\n    //parse and store IR for atom\n    void parseAtom()\n    {\n        if (empty)\n            return;\n        switch (front)\n        {\n        case '*', '?', '+', '|', '{', '}':\n            error(\"'*', '+', '?', '{', '}' not allowed in atom\");\n            break;\n        case '.':\n            if (re_flags & RegexOption.singleline)\n                g.put(Bytecode(IR.Any, 0));\n            else\n            {\n                CodepointSet set;\n                g.charsetToIr(set.add('\\n','\\n'+1).add('\\r', '\\r'+1).inverted);\n            }\n            popFront();\n            break;\n        case '[':\n            parseCharset();\n            break;\n        case '\\\\':\n            _popFront();\n            enforce(!empty, \"Unfinished escape sequence\");\n            parseEscape();\n            break;\n        case '^':\n            if (re_flags & RegexOption.multiline)\n                g.put(Bytecode(IR.Bol, 0));\n            else\n                g.put(Bytecode(IR.Bof, 0));\n            popFront();\n            break;\n        case '$':\n            if (re_flags & RegexOption.multiline)\n                g.put(Bytecode(IR.Eol, 0));\n            else\n                g.put(Bytecode(IR.Eof, 0));\n            popFront();\n            break;\n        default:\n            if (re_flags & RegexOption.casefold)\n            {\n                auto range = simpleCaseFoldings(front);\n                assert(range.length <= 5);\n                if (range.length == 1)\n                    g.put(Bytecode(IR.Char, range.front));\n                else\n                    foreach (v; range)\n                        g.put(Bytecode(IR.OrChar, v, cast(uint) range.length));\n            }\n            else\n                g.put(Bytecode(IR.Char, front));\n            popFront();\n        }\n    }\n\n    //parse and store IR for CodepointSet\n    void parseCharset()\n    {\n        const save = re_flags;\n        re_flags &= ~RegexOption.freeform; // stop ignoring whitespace if we did\n        bool casefold = cast(bool)(re_flags & RegexOption.casefold);\n        g.charsetToIr(unicode.parseSet(this, casefold));\n        re_flags = save;\n        // Last next() in parseCharset is executed w/o freeform flag\n        if (re_flags & RegexOption.freeform) skipSpace();\n    }\n\n    //parse and generate IR for escape stand alone escape sequence\n    @trusted void parseEscape()\n    {//accesses array of appender\n        import std.algorithm.iteration : sum;\n        switch (front)\n        {\n        case 'f':   popFront(); g.put(Bytecode(IR.Char, '\\f')); break;\n        case 'n':   popFront(); g.put(Bytecode(IR.Char, '\\n')); break;\n        case 'r':   popFront(); g.put(Bytecode(IR.Char, '\\r')); break;\n        case 't':   popFront(); g.put(Bytecode(IR.Char, '\\t')); break;\n        case 'v':   popFront(); g.put(Bytecode(IR.Char, '\\v')); break;\n\n        case 'd':\n            popFront();\n            g.charsetToIr(unicode.Nd);\n            break;\n        case 'D':\n            popFront();\n            g.charsetToIr(unicode.Nd.inverted);\n            break;\n        case 'b':   popFront(); g.put(Bytecode(IR.Wordboundary, 0)); break;\n        case 'B':   popFront(); g.put(Bytecode(IR.Notwordboundary, 0)); break;\n        case 's':\n            popFront();\n            g.charsetToIr(unicode.White_Space);\n            break;\n        case 'S':\n            popFront();\n            g.charsetToIr(unicode.White_Space.inverted);\n            break;\n        case 'w':\n            popFront();\n            g.charsetToIr(wordCharacter);\n            break;\n        case 'W':\n            popFront();\n            g.charsetToIr(wordCharacter.inverted);\n            break;\n        case 'p': case 'P':\n            bool casefold = cast(bool)(re_flags & RegexOption.casefold);\n            auto set = unicode.parsePropertySpec(this, front == 'P', casefold);\n            g.charsetToIr(set);\n            break;\n        case 'x':\n            immutable code = parseUniHex(pat, 2);\n            popFront();\n            g.put(Bytecode(IR.Char,code));\n            break;\n        case 'u': case 'U':\n            immutable code = parseUniHex(pat, front == 'u' ? 4 : 8);\n            popFront();\n            g.put(Bytecode(IR.Char, code));\n            break;\n        case 'c': //control codes\n            Bytecode code = Bytecode(IR.Char, unicode.parseControlCode(this));\n            popFront();\n            g.put(code);\n            break;\n        case '0':\n            popFront();\n            g.put(Bytecode(IR.Char, 0));//NUL character\n            break;\n        case '1': .. case '9':\n            uint nref = cast(uint) front - '0';\n            immutable maxBackref = sum(g.groupStack.data);\n            enforce(nref < maxBackref, \"Backref to unseen group\");\n            //perl's disambiguation rule i.e.\n            //get next digit only if there is such group number\n            popFront();\n            while (nref < maxBackref && !empty && std.ascii.isDigit(front))\n            {\n                nref = nref * 10 + front - '0';\n                popFront();\n            }\n            if (nref >= maxBackref)\n                nref /= 10;\n            enforce(!g.isOpenGroup(nref), \"Backref to open group\");\n            uint localLimit = maxBackref - g.groupStack.top;\n            if (nref >= localLimit)\n            {\n                g.put(Bytecode(IR.Backref, nref-localLimit));\n                g.ir[$-1].setLocalRef();\n            }\n            else\n                g.put(Bytecode(IR.Backref, nref));\n            g.markBackref(nref);\n            break;\n        default:\n            if (front == '\\\\' && !pat.empty)\n            {\n                if (pat.front >= privateUseStart && pat.front <= privateUseEnd)\n                    enforce(false, \"invalid escape sequence\");\n            }\n            if (front >= privateUseStart && front <= privateUseEnd)\n            {\n                g.endPattern(front - privateUseStart + 1);\n                break;\n            }\n            auto op = Bytecode(IR.Char, front);\n            popFront();\n            g.put(op);\n        }\n    }\n\n    //\n    @trusted void error(string msg)\n    {\n        import std.array : appender;\n        import std.format : formattedWrite;\n        auto app = appender!string();\n        formattedWrite(app, \"%s\\nPattern with error: `%s` <--HERE-- `%s`\",\n                       msg, origin[0..$-pat.length], pat);\n        throw new RegexException(app.data);\n    }\n\n    alias Char = BasicElementOf!R;\n\n    @property program()\n    {\n        return makeRegex(this);\n    }\n}\n\n/+\n    Postproces the IR, then optimize.\n+/\n@trusted void postprocess(Char)(ref Regex!Char zis)\n{//@@@BUG@@@ write is @system\n    with(zis)\n    {\n        struct FixedStack(T)\n        {\n            T[] arr;\n            uint _top;\n            //this(T[] storage){   arr = storage; _top = -1; }\n            @property ref T top(){  assert(!empty); return arr[_top]; }\n            void push(T x){  arr[++_top] = x; }\n            T pop() { assert(!empty);   return arr[_top--]; }\n            @property bool empty(){   return _top == -1; }\n        }\n        auto counterRange = FixedStack!uint(new uint[maxCounterDepth+1], -1);\n        counterRange.push(1);\n        ulong cumRange = 0;\n        for (uint i = 0; i < ir.length; i += ir[i].length)\n        {\n            if (ir[i].hotspot)\n            {\n                assert(i + 1 < ir.length,\n                    \"unexpected end of IR while looking for hotspot\");\n                ir[i+1] = Bytecode.fromRaw(hotspotTableSize);\n                hotspotTableSize += counterRange.top;\n            }\n            switch (ir[i].code)\n            {\n            case IR.RepeatStart, IR.RepeatQStart:\n                uint repEnd = cast(uint)(i + ir[i].data + IRL!(IR.RepeatStart));\n                assert(ir[repEnd].code == ir[i].paired.code);\n                immutable max = ir[repEnd + 4].raw;\n                ir[repEnd+2].raw = counterRange.top;\n                ir[repEnd+3].raw *= counterRange.top;\n                ir[repEnd+4].raw *= counterRange.top;\n                ulong cntRange = cast(ulong)(max)*counterRange.top;\n                cumRange += cntRange;\n                enforce(cumRange < maxCumulativeRepetitionLength,\n                    \"repetition length limit is exceeded\");\n                counterRange.push(cast(uint) cntRange + counterRange.top);\n                threadCount += counterRange.top;\n                break;\n            case IR.RepeatEnd, IR.RepeatQEnd:\n                threadCount += counterRange.top;\n                counterRange.pop();\n                break;\n            case IR.GroupStart:\n                if (isBackref(ir[i].data))\n                    ir[i].setBackrefence();\n                threadCount += counterRange.top;\n                break;\n            case IR.GroupEnd:\n                if (isBackref(ir[i].data))\n                    ir[i].setBackrefence();\n                threadCount += counterRange.top;\n                break;\n            default:\n                threadCount += counterRange.top;\n            }\n        }\n        checkIfOneShot();\n        if (!(flags & RegexInfo.oneShot))\n            kickstart = Kickstart!Char(zis, new uint[](256));\n        debug(std_regex_allocation) writefln(\"IR processed, max threads: %d\", threadCount);\n        optimize(zis);\n    }\n}\n\nvoid fixupBytecode()(Bytecode[] ir)\n{\n    Stack!uint fixups;\n\n    with(IR) for (uint i=0; i<ir.length; i+= ir[i].length)\n    {\n        if (ir[i].isStart || ir[i].code == Option)\n            fixups.push(i);\n        else if (ir[i].code == OrEnd)\n        {\n            // Alternatives need more care\n            auto j = fixups.pop(); // last Option\n            ir[j].data = i -  j - ir[j].length;\n            j = fixups.pop(); // OrStart\n            ir[j].data = i - j - ir[j].length;\n            ir[i].data = ir[j].data;\n\n            // fixup all GotoEndOrs\n            j = j + IRL!(OrStart);\n            assert(ir[j].code == Option);\n            for (;;)\n            {\n                auto next = j + ir[j].data + IRL!(Option);\n                if (ir[next].code == IR.OrEnd)\n                    break;\n                ir[next - IRL!(GotoEndOr)].data = i - next;\n                j = next;\n            }\n        }\n        else if (ir[i].code == GotoEndOr)\n        {\n            auto j = fixups.pop(); // Option\n            ir[j].data = i - j + IRL!(GotoEndOr)- IRL!(Option); // to the next option\n        }\n        else if (ir[i].isEnd)\n        {\n            auto j = fixups.pop();\n            ir[i].data = i - j - ir[j].length;\n            ir[j].data = ir[i].data;\n        }\n    }\n    assert(fixups.empty);\n}\n\nvoid optimize(Char)(ref Regex!Char zis)\n{\n    import std.array : insertInPlace;\n    CodepointSet nextSet(uint idx)\n    {\n        CodepointSet set;\n        with(zis) with(IR)\n    Outer:\n        for (uint i = idx; i < ir.length; i += ir[i].length)\n        {\n            switch (ir[i].code)\n            {\n                case Char:\n                    set.add(ir[i].data, ir[i].data+1);\n                    goto default;\n                //TODO: OrChar\n                case Trie, CodepointSet:\n                    set = zis.charsets[ir[i].data];\n                    goto default;\n                case GroupStart,GroupEnd:\n                    break;\n                default:\n                    break Outer;\n            }\n        }\n        return set;\n    }\n\n    with(zis) with(IR) for (uint i = 0; i < ir.length; i += ir[i].length)\n    {\n        if (ir[i].code == InfiniteEnd)\n        {\n            auto set = nextSet(i+IRL!(InfiniteEnd));\n            if (!set.empty && set.length < 10_000)\n            {\n                ir[i] = Bytecode(InfiniteBloomEnd, ir[i].data);\n                ir[i - ir[i].data - IRL!(InfiniteStart)] =\n                    Bytecode(InfiniteBloomStart, ir[i].data);\n                ir.insertInPlace(i+IRL!(InfiniteEnd),\n                    Bytecode.fromRaw(cast(uint) zis.filters.length));\n                zis.filters ~= BitTable(set);\n                fixupBytecode(ir);\n            }\n        }\n    }\n}\n\n//IR code validator - proper nesting, illegal instructions, etc.\n@trusted void validateRe(Char)(ref Regex!Char zis)\n{//@@@BUG@@@ text is @system\n    import std.conv : text;\n    with(zis)\n    {\n        for (uint pc = 0; pc < ir.length; pc += ir[pc].length)\n        {\n            if (ir[pc].isStart || ir[pc].isEnd)\n            {\n                immutable dest = ir[pc].indexOfPair(pc);\n                assert(dest < ir.length, text(\"Wrong length in opcode at pc=\",\n                    pc, \" \", dest, \" vs \", ir.length));\n                assert(ir[dest].paired ==  ir[pc],\n                    text(\"Wrong pairing of opcodes at pc=\", pc, \"and pc=\", dest));\n            }\n            else if (ir[pc].isAtom)\n            {\n\n            }\n            else\n               assert(0, text(\"Unknown type of instruction at pc=\", pc));\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/regex/internal/tests.d",
    "content": "/*\n    Regualar expressions package test suite.\n*/\nmodule std.regex.internal.tests;\n\npackage(std.regex):\n\nimport std.conv, std.exception, std.meta, std.range,\n    std.typecons, std.regex;\n\nimport std.uni : Escapables; // characters that need escaping\n\ndebug(std_regex_test) import std.stdio;\n\n@safe unittest\n{//sanity checks\n    regex(\"(a|b)*\");\n    regex(`(?:([0-9A-F]+)\\.\\.([0-9A-F]+)|([0-9A-F]+))\\s*;\\s*(.*)\\s*#`);\n    regex(\"abc|edf|ighrg\");\n    auto r1 = regex(\"abc\");\n    auto r2 = regex(\"(gylba)\");\n    assert(match(\"abcdef\", r1).hit == \"abc\");\n    assert(!match(\"wida\",r2));\n    assert(bmatch(\"abcdef\", r1).hit == \"abc\");\n    assert(!bmatch(\"wida\", r2));\n    assert(match(\"abc\", \"abc\".dup));\n    assert(bmatch(\"abc\", \"abc\".dup));\n    Regex!char rc;\n    assert(rc.empty);\n    rc = regex(\"test\");\n    assert(!rc.empty);\n}\n\n/* The test vectors in this file are altered from Henry Spencer's regexp\n   test code. His copyright notice is:\n\n        Copyright (c) 1986 by University of Toronto.\n        Written by Henry Spencer.  Not derived from licensed software.\n\n        Permission is granted to anyone to use this software for any\n        purpose on any computer system, and to redistribute it freely,\n        subject to the following restrictions:\n\n        1. The author is not responsible for the consequences of use of\n                this software, no matter how awful, even if they arise\n                from defects in it.\n\n        2. The origin of this software must not be misrepresented, either\n                by explicit claim or by omission.\n\n        3. Altered versions must be plainly marked as such, and must not\n                be misrepresented as being the original software.\n\n\n */\n\n@safe unittest\n{\n    struct TestVectors\n    {\n        string pattern;\n        string input;\n        string result;\n        string format;\n        string replace;\n        string flags;\n    }\n\n    static immutable TestVectors[] tv = [\n        TestVectors(  \"a\\\\b\",       \"a\",  \"y\",    \"$&\",    \"a\" ),\n        TestVectors(  \"(a)b\\\\1\",   \"abaab\",\"y\",    \"$&\",    \"aba\" ),\n        TestVectors(  \"()b\\\\1\",     \"aaab\", \"y\",    \"$&\",    \"b\" ),\n        TestVectors(  \"abc\",       \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"abc\",       \"xbc\",  \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"abc\",       \"axc\",  \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"abc\",       \"abx\",  \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"abc\",       \"xabcy\",\"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"abc\",       \"ababc\",\"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"ab*c\",      \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"ab*bc\",     \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"ab*bc\",     \"abbc\", \"y\",    \"$&\",    \"abbc\" ),\n        TestVectors(  \"ab*bc\",     \"abbbbc\",\"y\",   \"$&\",    \"abbbbc\" ),\n        TestVectors(  \"ab+bc\",     \"abbc\", \"y\",    \"$&\",    \"abbc\" ),\n        TestVectors(  \"ab+bc\",     \"abc\",  \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"ab+bc\",     \"abq\",  \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"ab+bc\",     \"abbbbc\",\"y\",   \"$&\",    \"abbbbc\" ),\n        TestVectors(  \"ab?bc\",     \"abbc\", \"y\",    \"$&\",    \"abbc\" ),\n        TestVectors(  \"ab?bc\",     \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"ab?bc\",     \"abbbbc\",\"n\",   \"-\",    \"-\" ),\n        TestVectors(  \"ab?c\",      \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"^abc$\",     \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"^abc$\",     \"abcc\", \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"^abc\",      \"abcc\", \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"^abc$\",     \"aabc\", \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"abc$\",      \"aabc\", \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"^\",         \"abc\",  \"y\",    \"$&\",    \"\" ),\n        TestVectors(  \"$\",         \"abc\",  \"y\",    \"$&\",    \"\" ),\n        TestVectors(  \"a.c\",       \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"a.c\",       \"axc\",  \"y\",    \"$&\",    \"axc\" ),\n        TestVectors(  \"a.*c\",      \"axyzc\",\"y\",    \"$&\",    \"axyzc\" ),\n        TestVectors(  \"a.*c\",      \"axyzd\",\"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"a[bc]d\",    \"abc\",  \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"a[bc]d\",    \"abd\",  \"y\",    \"$&\",    \"abd\" ),\n        TestVectors(  \"a[b-d]e\",   \"abd\",  \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"a[b-d]e\",   \"ace\",  \"y\",    \"$&\",    \"ace\" ),\n        TestVectors(  \"a[b-d]\",    \"aac\",  \"y\",    \"$&\",    \"ac\" ),\n        TestVectors(  \"a[-b]\",     \"a-\",   \"y\",    \"$&\",    \"a-\" ),\n        TestVectors(  \"a[b-]\",     \"a-\",   \"y\",    \"$&\",    \"a-\" ),\n        TestVectors(  \"a[b-a]\",    \"-\",    \"c\",    \"-\",    \"-\" ),\n        TestVectors(  \"a[]b\",      \"-\",    \"c\",    \"-\",    \"-\" ),\n        TestVectors(  \"a[\",        \"-\",    \"c\",    \"-\",    \"-\" ),\n        TestVectors(  \"a]\",        \"a]\",   \"y\",    \"$&\",    \"a]\" ),\n        TestVectors(  \"a[\\\\]]b\",     \"a]b\",  \"y\",  \"$&\",    \"a]b\" ),\n        TestVectors(  \"a[^bc]d\",   \"aed\",  \"y\",    \"$&\",    \"aed\" ),\n        TestVectors(  \"a[^bc]d\",   \"abd\",  \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"a[^-b]c\",   \"adc\",  \"y\",    \"$&\",    \"adc\" ),\n        TestVectors(  \"a[^-b]c\",   \"a-c\",  \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"a[^\\\\]b]c\",   \"adc\",  \"y\",  \"$&\",    \"adc\" ),\n        TestVectors(  \"ab|cd\",     \"abc\",  \"y\",    \"$&\",    \"ab\" ),\n        TestVectors(  \"ab|cd\",     \"abcd\", \"y\",    \"$&\",    \"ab\" ),\n        TestVectors(  \"()ef\",      \"def\",  \"y\",    \"$&-$1\",        \"ef-\" ),\n        TestVectors(  \"()*\",       \"-\",    \"y\",    \"-\",    \"-\" ),\n        TestVectors(  \"*a\",        \"-\",    \"c\",    \"-\",    \"-\" ),\n        TestVectors(  \"^*\",        \"-\",    \"y\",    \"-\",    \"-\" ),\n        TestVectors(  \"$*\",        \"-\",    \"y\",    \"-\",    \"-\" ),\n        TestVectors(  \"(*)b\",      \"-\",    \"c\",    \"-\",    \"-\" ),\n        TestVectors(  \"$b\",        \"b\",    \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"a\\\\\",       \"-\",    \"c\",    \"-\",    \"-\" ),\n        TestVectors(  \"a\\\\(b\",     \"a(b\",  \"y\",    \"$&-$1\",        \"a(b-\" ),\n        TestVectors(  \"a\\\\(*b\",    \"ab\",   \"y\",    \"$&\",    \"ab\" ),\n        TestVectors(  \"a\\\\(*b\",    \"a((b\", \"y\",    \"$&\",    \"a((b\" ),\n        TestVectors(  \"a\\\\\\\\b\",    \"a\\\\b\", \"y\",    \"$&\",    \"a\\\\b\" ),\n        TestVectors(  \"abc)\",      \"-\",    \"c\",    \"-\",    \"-\" ),\n        TestVectors(  \"(abc\",      \"-\",    \"c\",    \"-\",    \"-\" ),\n        TestVectors(  \"((a))\",     \"abc\",  \"y\",    \"$&-$1-$2\",    \"a-a-a\" ),\n        TestVectors(  \"(a)b(c)\",   \"abc\",  \"y\",    \"$&-$1-$2\",    \"abc-a-c\" ),\n        TestVectors(  \"a+b+c\",     \"aabbabc\",\"y\",  \"$&\",    \"abc\" ),\n        TestVectors(  \"a**\",       \"-\",    \"c\",    \"-\",    \"-\" ),\n        TestVectors(  \"a*?a\",      \"aa\",   \"y\",    \"$&\",    \"a\" ),\n        TestVectors(  \"(a*)*\",     \"aaa\",  \"y\",    \"-\",    \"-\" ),\n        TestVectors(  \"(a*)+\",     \"aaa\",  \"y\",    \"-\",    \"-\" ),\n        TestVectors(  \"(a|)*\",     \"-\",    \"y\",    \"-\",    \"-\" ),\n        TestVectors(  \"(a*|b)*\",   \"aabb\", \"y\",    \"-\",    \"-\" ),\n        TestVectors(  \"(a|b)*\",    \"ab\",   \"y\",    \"$&-$1\",        \"ab-b\" ),\n        TestVectors(  \"(a+|b)*\",   \"ab\",   \"y\",    \"$&-$1\",        \"ab-b\" ),\n        TestVectors(  \"(a+|b)+\",   \"ab\",   \"y\",    \"$&-$1\",        \"ab-b\" ),\n        TestVectors(  \"(a+|b)?\",   \"ab\",   \"y\",    \"$&-$1\",        \"a-a\" ),\n        TestVectors(  \"[^ab]*\",    \"cde\",  \"y\",    \"$&\",    \"cde\" ),\n        TestVectors(  \"(^)*\",      \"-\",    \"y\",    \"-\",    \"-\" ),\n        TestVectors(  \"(ab|)*\",    \"-\",    \"y\",    \"-\",    \"-\" ),\n        TestVectors(  \")(\",        \"-\",    \"c\",    \"-\",    \"-\" ),\n        TestVectors(  \"\",  \"abc\",  \"y\",    \"$&\",    \"\" ),\n        TestVectors(  \"abc\",       \"\",     \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"a*\",        \"\",     \"y\",    \"$&\",    \"\" ),\n        TestVectors(  \"([abc])*d\", \"abbbcd\",       \"y\",    \"$&-$1\",        \"abbbcd-c\" ),\n        TestVectors(  \"([abc])*bcd\", \"abcd\",       \"y\",    \"$&-$1\",        \"abcd-a\" ),\n        TestVectors(  \"a|b|c|d|e\", \"e\",    \"y\",    \"$&\",    \"e\" ),\n        TestVectors(  \"(a|b|c|d|e)f\", \"ef\",        \"y\",    \"$&-$1\",        \"ef-e\" ),\n        TestVectors(  \"((a*|b))*\", \"aabb\", \"y\",    \"-\",    \"-\" ),\n        TestVectors(  \"abcd*efg\",  \"abcdefg\",      \"y\",    \"$&\",    \"abcdefg\" ),\n        TestVectors(  \"ab*\",       \"xabyabbbz\",    \"y\",    \"$&\",    \"ab\" ),\n        TestVectors(  \"ab*\",       \"xayabbbz\",     \"y\",    \"$&\",    \"a\" ),\n        TestVectors(  \"(ab|cd)e\",  \"abcde\",        \"y\",    \"$&-$1\",        \"cde-cd\" ),\n        TestVectors(  \"[abhgefdc]ij\",      \"hij\",  \"y\",    \"$&\",    \"hij\" ),\n        TestVectors(  \"^(ab|cd)e\", \"abcde\",        \"n\",    \"x$1y\",        \"xy\" ),\n        TestVectors(  \"(abc|)ef\",  \"abcdef\",       \"y\",    \"$&-$1\",        \"ef-\" ),\n        TestVectors(  \"(a|b)c*d\",  \"abcd\",         \"y\",    \"$&-$1\",        \"bcd-b\" ),\n        TestVectors(  \"(ab|ab*)bc\",        \"abc\",  \"y\",    \"$&-$1\",        \"abc-a\" ),\n        TestVectors(  \"a([bc]*)c*\",        \"abc\",  \"y\",    \"$&-$1\",        \"abc-bc\" ),\n        TestVectors(  \"a([bc]*)(c*d)\",     \"abcd\", \"y\",    \"$&-$1-$2\",    \"abcd-bc-d\" ),\n        TestVectors(  \"a([bc]+)(c*d)\",     \"abcd\", \"y\",    \"$&-$1-$2\",    \"abcd-bc-d\" ),\n        TestVectors(  \"a([bc]*)(c+d)\",     \"abcd\", \"y\",    \"$&-$1-$2\",    \"abcd-b-cd\" ),\n        TestVectors(  \"a[bcd]*dcdcde\",     \"adcdcde\",      \"y\",    \"$&\",    \"adcdcde\" ),\n        TestVectors(  \"a[bcd]+dcdcde\",     \"adcdcde\",      \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"(ab|a)b*c\", \"abc\",           \"y\",    \"$&-$1\",        \"abc-ab\" ),\n        TestVectors(  \"((a)(b)c)(d)\",      \"abcd\",  \"y\",    \"$1-$2-$3-$4\",      \"abc-a-b-d\" ),\n        TestVectors(  \"[a-zA-Z_][a-zA-Z0-9_]*\",    \"alpha\",        \"y\",    \"$&\",    \"alpha\" ),\n        TestVectors(  \"^a(bc+|b[eh])g|.h$\",        \"abh\",  \"y\",    \"$&-$1\",        \"bh-\" ),\n        TestVectors(  \"(bc+d$|ef*g.|h?i(j|k))\",    \"effgz\",        \"y\",    \"$&-$1-$2\",    \"effgz-effgz-\" ),\n        TestVectors(  \"(bc+d$|ef*g.|h?i(j|k))\",    \"ij\",   \"y\",    \"$&-$1-$2\",    \"ij-ij-j\" ),\n        TestVectors(  \"(bc+d$|ef*g.|h?i(j|k))\",    \"effg\", \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"(bc+d$|ef*g.|h?i(j|k))\",    \"bcdd\", \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"(bc+d$|ef*g.|h?i(j|k))\",    \"reffgz\",       \"y\",    \"$&-$1-$2\",    \"effgz-effgz-\" ),\n        TestVectors(  \"(((((((((a)))))))))\",       \"a\",    \"y\",    \"$&\",    \"a\" ),\n        TestVectors(  \"multiple words of text\",    \"uh-uh\",        \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"multiple words\",    \"multiple words, yeah\", \"y\",    \"$&\",    \"multiple words\" ),\n        TestVectors(  \"(.*)c(.*)\", \"abcde\",                \"y\",    \"$&-$1-$2\",    \"abcde-ab-de\" ),\n        TestVectors(  \"\\\\((.*), (.*)\\\\)\",  \"(a, b)\",       \"y\",    \"($2, $1)\",   \"(b, a)\" ),\n        TestVectors(  \"abcd\",      \"abcd\",                   \"y\",    \"$&-&-$$$&\",  \"abcd-&-$abcd\" ),\n        TestVectors(  \"a(bc)d\",    \"abcd\",                 \"y\",    \"$1-$$1-$$$1\",    \"bc-$1-$bc\" ),\n        TestVectors(  \"[k]\",                       \"ab\",   \"n\",    \"-\",    \"-\" ),\n        TestVectors(  \"[ -~]*\",                    \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"[ -~ -~]*\",                 \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"[ -~ -~ -~]*\",              \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"[ -~ -~ -~ -~]*\",           \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"[ -~ -~ -~ -~ -~]*\",        \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"[ -~ -~ -~ -~ -~ -~]*\",     \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"[ -~ -~ -~ -~ -~ -~ -~]*\",  \"abc\",  \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"a{2}\",      \"candy\",                \"n\",    \"\",     \"\" ),\n        TestVectors(  \"a{2}\",      \"caandy\",               \"y\",    \"$&\",    \"aa\" ),\n        TestVectors(  \"a{2}\",      \"caaandy\",              \"y\",    \"$&\",    \"aa\" ),\n        TestVectors(  \"a{2,}\",     \"candy\",                \"n\",    \"\",     \"\" ),\n        TestVectors(  \"a{2,}\",     \"caandy\",               \"y\",    \"$&\",    \"aa\" ),\n        TestVectors(  \"a{2,}\",     \"caaaaaandy\",           \"y\",    \"$&\",    \"aaaaaa\" ),\n        TestVectors(  \"a{1,3}\",    \"cndy\",                 \"n\",    \"\",     \"\" ),\n        TestVectors(  \"a{1,3}\",    \"candy\",                \"y\",    \"$&\",    \"a\" ),\n        TestVectors(  \"a{1,3}\",    \"caandy\",               \"y\",    \"$&\",    \"aa\" ),\n        TestVectors(  \"a{1,3}\",    \"caaaaaandy\",           \"y\",    \"$&\",    \"aaa\" ),\n        TestVectors(  \"e?le?\",     \"angel\",                \"y\",    \"$&\",    \"el\" ),\n        TestVectors(  \"e?le?\",     \"angle\",                \"y\",    \"$&\",    \"le\" ),\n        TestVectors(  \"\\\\bn\\\\w\",   \"noonday\",              \"y\",    \"$&\",    \"no\" ),\n        TestVectors(  \"\\\\wy\\\\b\",   \"possibly yesterday\",   \"y\",    \"$&\",    \"ly\" ),\n        TestVectors(  \"\\\\w\\\\Bn\",   \"noonday\",              \"y\",    \"$&\",    \"on\" ),\n        TestVectors(  \"y\\\\B\\\\w\",   \"possibly yesterday\",   \"y\",    \"$&\",    \"ye\" ),\n        TestVectors(  \"\\\\cJ\",      \"abc\\ndef\",             \"y\",    \"$&\",    \"\\n\" ),\n        TestVectors(  \"\\\\d\",       \"B2 is\",                \"y\",    \"$&\",    \"2\" ),\n        TestVectors(  \"\\\\D\",       \"B2 is\",                \"y\",    \"$&\",    \"B\" ),\n        TestVectors(  \"\\\\s\\\\w*\",   \"foo bar\",              \"y\",    \"$&\",    \" bar\" ),\n        TestVectors(  \"\\\\S\\\\w*\",   \"foo bar\",              \"y\",    \"$&\",    \"foo\" ),\n        TestVectors(  \"abc\",       \"ababc\",                \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"apple(,)\\\\sorange\\\\1\",      \"apple, orange, cherry, peach\", \"y\", \"$&\", \"apple, orange,\" ),\n        TestVectors(  \"(\\\\w+)\\\\s(\\\\w+)\",           \"John Smith\", \"y\", \"$2, $1\", \"Smith, John\" ),\n        TestVectors(  \"\\\\n\\\\f\\\\r\\\\t\\\\v\",           \"abc\\n\\f\\r\\t\\vdef\", \"y\", \"$&\", \"\\n\\f\\r\\t\\v\" ),\n        TestVectors(  \".*c\",       \"abcde\",                        \"y\",    \"$&\",    \"abc\" ),\n        TestVectors(  \"^\\\\w+((;|=)\\\\w+)+$\", \"some=host=tld\",    \"y\", \"$&-$1-$2\", \"some=host=tld-=tld-=\" ),\n        TestVectors(  \"^\\\\w+((\\\\.|-)\\\\w+)+$\", \"some.host.tld\",    \"y\", \"$&-$1-$2\", \"some.host.tld-.tld-.\" ),\n        TestVectors(  \"q(a|b)*q\",  \"xxqababqyy\",                \"y\",    \"$&-$1\",        \"qababq-b\" ),\n        TestVectors(  \"^(a)(b){0,1}(c*)\",   \"abcc\", \"y\", \"$1 $2 $3\", \"a b cc\" ),\n        TestVectors(  \"^(a)((b){0,1})(c*)\", \"abcc\", \"y\", \"$1 $2 $3\", \"a b b\" ),\n        TestVectors(  \"^(a)(b)?(c*)\",       \"abcc\", \"y\", \"$1 $2 $3\", \"a b cc\" ),\n        TestVectors(  \"^(a)((b)?)(c*)\",     \"abcc\", \"y\", \"$1 $2 $3\", \"a b b\" ),\n        TestVectors(  \"^(a)(b){0,1}(c*)\",   \"acc\",  \"y\", \"$1 $2 $3\", \"a  cc\" ),\n        TestVectors(  \"^(a)((b){0,1})(c*)\", \"acc\",  \"y\", \"$1 $2 $3\", \"a  \" ),\n        TestVectors(  \"^(a)(b)?(c*)\",       \"acc\",  \"y\", \"$1 $2 $3\", \"a  cc\" ),\n        TestVectors(  \"^(a)((b)?)(c*)\",     \"acc\",  \"y\", \"$1 $2 $3\", \"a  \" ),\n        TestVectors(  \"(?:ab){3}\",       \"_abababc\",\"y\", \"$&-$1\",    \"ababab-\" ),\n        TestVectors(  \"(?:a(?:x)?)+\",    \"aaxaxx\",  \"y\", \"$&-$1-$2\", \"aaxax--\" ),\n        TestVectors(  `\\W\\w\\W`,         \"aa b!ca\",  \"y\", \"$&\",       \" b!\"),\n//more repetitions:\n        TestVectors(  \"(?:a{2,4}b{1,3}){1,2}\",  \"aaabaaaabbb\", \"y\", \"$&\", \"aaabaaaabbb\" ),\n        TestVectors(  \"(?:a{2,4}b{1,3}){1,2}?\", \"aaabaaaabbb\", \"y\", \"$&\", \"aaab\" ),\n//groups:\n        TestVectors(  \"(abc)|(edf)|(xyz)\",     \"xyz\",             \"y\",   \"$1-$2-$3\",\"--xyz\"),\n        TestVectors(  \"(?P<q>\\\\d+)/(?P<d>\\\\d+)\",     \"2/3\",       \"y\",     \"${d}/${q}\",    \"3/2\"),\n//set operations:\n        TestVectors(  \"[a-z--d-f]\",                  \" dfa\",      \"y\",   \"$&\",     \"a\"),\n        TestVectors(  \"[abc[pq--acq]]{2}\",           \"bqpaca\",    \"y\",   \"$&\",     \"pa\"),\n        TestVectors(  \"[a-z9&&abc0-9]{3}\",           \"z90a0abc\",  \"y\",   \"$&\",     \"abc\"),\n        TestVectors(  \"[0-9a-f~~0-5a-z]{2}\",         \"g0a58x\",    \"y\",   \"$&\",     \"8x\"),\n        TestVectors(  \"[abc[pq]xyz[rs]]{4}\",         \"cqxr\",      \"y\",   \"$&\",     \"cqxr\"),\n        TestVectors(  \"[abcdf--[ab&&[bcd]][acd]]\",   \"abcdefgh\",  \"y\",   \"$&\",     \"f\"),\n        TestVectors(  \"[a-c||d-f]+\",    \"abcdef\", \"y\", \"$&\", \"abcdef\"),\n        TestVectors(  \"[a-f--a-c]+\",    \"abcdef\", \"y\", \"$&\", \"def\"),\n        TestVectors(  \"[a-c&&b-f]+\",    \"abcdef\", \"y\", \"$&\", \"bc\"),\n        TestVectors(  \"[a-c~~b-f]+\",    \"abcdef\", \"y\", \"$&\", \"a\"),\n//unicode blocks & properties:\n        TestVectors(  `\\P{Inlatin1suppl ement}`, \"\\u00c2!\", \"y\", \"$&\", \"!\"),\n        TestVectors(  `\\p{InLatin-1 Supplement}\\p{in-mathematical-operators}\\P{Inlatin1suppl ement}`,\n            \"\\u00c2\\u2200\\u00c3\\u2203.\", \"y\", \"$&\", \"\\u00c3\\u2203.\"),\n        TestVectors(  `[-+*/\\p{in-mathematical-operators}]{2}`,    \"a+\\u2212\",    \"y\",    \"$&\",    \"+\\u2212\"),\n        TestVectors(  `\\p{Ll}+`,                      \"XabcD\",    \"y\",  \"$&\",      \"abc\"),\n        TestVectors(  `\\p{Lu}+`,                      \"абвГДЕ\",   \"y\",  \"$&\",      \"ГДЕ\"),\n        TestVectors(  `^\\p{Currency Symbol}\\p{Sc}`,   \"$₤\",       \"y\",  \"$&\",      \"$₤\"),\n        TestVectors(  `\\p{Common}\\p{Thai}`,           \"!ฆ\",       \"y\",  \"$&\",      \"!ฆ\"),\n        TestVectors(  `[\\d\\s]*\\D`,  \"12 \\t3\\U00001680\\u0F20_2\",   \"y\",  \"$&\", \"12 \\t3\\U00001680\\u0F20_\"),\n        TestVectors(  `[c-wф]фф`, \"ффф\", \"y\", \"$&\", \"ффф\"),\n//case insensitive:\n        TestVectors(   `^abcdEf$`,           \"AbCdEF\",              \"y\",   \"$&\", \"AbCdEF\",      \"i\"),\n        TestVectors(   `Русский язык`, \"рУсскИй ЯзЫк\", \"y\", \"$&\", \"рУсскИй ЯзЫк\", \"i\"),\n        TestVectors(   `ⒶⒷⓒ` ,        \"ⓐⓑⒸ\",                   \"y\",   \"$&\", \"ⓐⓑⒸ\",      \"i\"),\n        TestVectors(   \"\\U00010400{2}\",  \"\\U00010428\\U00010400 \",   \"y\",   \"$&\", \"\\U00010428\\U00010400\", \"i\"),\n        TestVectors(   `[adzУ-Я]{4}`,    \"DzюЯ\",                   \"y\",   \"$&\", \"DzюЯ\", \"i\"),\n        TestVectors(   `\\p{L}\\p{Lu}{10}`, \"абвгдеЖЗИКЛ\", \"y\",   \"$&\", \"абвгдеЖЗИКЛ\", \"i\"),\n        TestVectors(   `(?:Dåb){3}`,  \"DåbDÅBdÅb\",                  \"y\",   \"$&\", \"DåbDÅBdÅb\", \"i\"),\n//escapes:\n        TestVectors(    `\\u0041\\u005a\\U00000065\\u0001`,         \"AZe\\u0001\",       \"y\",   \"$&\", \"AZe\\u0001\"),\n        TestVectors(    `\\u`,               \"\",   \"c\",   \"-\",  \"-\"),\n        TestVectors(    `\\U`,               \"\",   \"c\",   \"-\",  \"-\"),\n        TestVectors(    `\\u003`,            \"\",   \"c\",   \"-\",  \"-\"),\n        TestVectors(    `[\\x00-\\x7f]{4}`,        \"\\x00\\x09ab\",   \"y\", \"$&\", \"\\x00\\x09ab\"),\n        TestVectors(    `[\\cJ\\cK\\cA-\\cD]{3}\\cQ`, \"\\x01\\x0B\\x0A\\x11\", \"y\", \"$&\", \"\\x01\\x0B\\x0A\\x11\"),\n        TestVectors(    `\\r\\n\\v\\t\\f\\\\`,     \"\\r\\n\\v\\t\\f\\\\\",   \"y\",   \"$&\", \"\\r\\n\\v\\t\\f\\\\\"),\n        TestVectors(    `[\\u0003\\u0001]{2}`,  \"\\u0001\\u0003\",         \"y\",   \"$&\", \"\\u0001\\u0003\"),\n        TestVectors(    `^[\\u0020-\\u0080\\u0001\\n-\\r]{8}`,  \"abc\\u0001\\v\\f\\r\\n\",  \"y\",   \"$&\", \"abc\\u0001\\v\\f\\r\\n\"),\n        TestVectors(    `\\w+\\S\\w+`, \"ab7!44c\",  \"y\", \"$&\", \"ab7!44c\"),\n        TestVectors(    `\\b\\w+\\b`,  \" abde4 \",  \"y\", \"$&\", \"abde4\"),\n        TestVectors(    `\\b\\w+\\b`,  \" abde4\",   \"y\", \"$&\", \"abde4\"),\n        TestVectors(    `\\b\\w+\\b`,  \"abde4 \",   \"y\", \"$&\", \"abde4\"),\n        TestVectors(    `\\pL\\pS`,   \"a\\u02DA\",  \"y\", \"$&\", \"a\\u02DA\"),\n        TestVectors(    `\\pX`,      \"\",         \"c\", \"-\",  \"-\"),\n// ^, $, \\b, \\B, multiline :\n        TestVectors(    `\\r.*?$`,    \"abc\\r\\nxy\", \"y\", \"$&\", \"\\r\\nxy\", \"sm\"),\n        TestVectors(    `^a$^b$`,    \"a\\r\\nb\\n\",  \"n\", \"$&\", \"-\", \"m\"),\n        TestVectors(    `^a$\\r\\n^b$`,\"a\\r\\nb\\n\",  \"y\", \"$&\", \"a\\r\\nb\", \"m\"),\n        TestVectors(    `^$`,        \"\\r\\n\",      \"y\", \"$&\", \"\", \"m\"),\n        TestVectors(    `^a$\\nx$`,   \"a\\nx\\u2028\",\"y\", \"$&\", \"a\\nx\", \"m\"),\n        TestVectors(    `^a$\\nx$`,   \"a\\nx\\u2029\",\"y\", \"$&\", \"a\\nx\", \"m\"),\n        TestVectors(    `^a$\\nx$`,   \"a\\nx\\u0085\",\"y\", \"$&\", \"a\\nx\",\"m\"),\n        TestVectors(    `^x$`,       \"\\u2028x\",   \"y\", \"$&\", \"x\", \"m\"),\n        TestVectors(    `^x$`,       \"\\u2029x\",   \"y\", \"$&\", \"x\", \"m\"),\n        TestVectors(    `^x$`,       \"\\u0085x\",   \"y\", \"$&\", \"x\", \"m\"),\n        TestVectors(    `\\b^.`,      \"ab\",        \"y\", \"$&\", \"a\"),\n        TestVectors(    `\\B^.`,      \"ab\",        \"n\", \"-\",  \"-\"),\n        TestVectors(    `^ab\\Bc\\B`,  \"\\r\\nabcd\",  \"y\", \"$&\", \"abc\", \"m\"),\n        TestVectors(    `^.*$`,      \"12345678\",  \"y\", \"$&\", \"12345678\"),\n\n// luckily obtained regression on incremental matching in backtracker\n        TestVectors(  `^(?:(?:([0-9A-F]+)\\.\\.([0-9A-F]+)|([0-9A-F]+))\\s*;\\s*([^ ]*)\\s*#|# (?:\\w|_)+=((?:\\w|_)+))`,\n            \"0020  ; White_Space # \", \"y\", \"$1-$2-$3\", \"--0020\"),\n//lookahead\n        TestVectors(    \"(foo.)(?=(bar))\",     \"foobar foodbar\", \"y\", \"$&-$1-$2\", \"food-food-bar\" ),\n        TestVectors(    `\\b(\\d+)[a-z](?=\\1)`,  \"123a123\",        \"y\", \"$&-$1\", \"123a-123\" ),\n        TestVectors(    `\\$(?!\\d{3})\\w+`,      \"$123 $abc\",      \"y\", \"$&\", \"$abc\"),\n        TestVectors(    `(abc)(?=(ed(f))\\3)`,    \"abcedff\",      \"y\", \"-\", \"-\"),\n        TestVectors(    `\\b[A-Za-z0-9.]+(?=(@(?!gmail)))`, \"a@gmail,x@com\",  \"y\", \"$&-$1\", \"x-@\"),\n        TestVectors(    `x()(abc)(?=(d)(e)(f)\\2)`,   \"xabcdefabc\", \"y\", \"$&\", \"xabc\"),\n        TestVectors(    `x()(abc)(?=(d)(e)(f)()\\3\\4\\5)`,   \"xabcdefdef\", \"y\", \"$&\", \"xabc\"),\n//lookback\n        TestVectors(    `(?<=(ab))\\d`,    \"12ba3ab4\",    \"y\",   \"$&-$1\", \"4-ab\",  \"i\"),\n        TestVectors(    `\\w(?<!\\d)\\w`,   \"123ab24\",  \"y\",   \"$&\", \"ab\"),\n        TestVectors(    `(?<=Dåb)x\\w`,  \"DåbDÅBxdÅb\",  \"y\",   \"$&\", \"xd\", \"i\"),\n        TestVectors(    `(?<=(ab*c))x`,   \"abbbbcxac\",  \"y\",   \"$&-$1\", \"x-abbbbc\"),\n        TestVectors(    `(?<=(ab*?c))x`,   \"abbbbcxac\",  \"y\",   \"$&-$1\", \"x-abbbbc\"),\n        TestVectors(    `(?<=(a.*?c))x`,   \"ababbcxac\",  \"y\",   \"$&-$1\", \"x-abbc\"),\n        TestVectors(    `(?<=(a{2,4}b{1,3}))x`,   \"yyaaaabx\",  \"y\",   \"$&-$1\", \"x-aaaab\"),\n        TestVectors(    `(?<=((?:a{2,4}b{1,3}){1,2}))x`,   \"aabbbaaaabx\",  \"y\",   \"$&-$1\", \"x-aabbbaaaab\"),\n        TestVectors(    `(?<=((?:a{2,4}b{1,3}){1,2}?))x`,   \"aabbbaaaabx\",  \"y\",   \"$&-$1\", \"x-aaaab\"),\n        TestVectors(    `(?<=(abc|def|aef))x`,    \"abcx\", \"y\",        \"$&-$1\",  \"x-abc\"),\n        TestVectors(    `(?<=(abc|def|aef))x`,    \"aefx\", \"y\",        \"$&-$1\",  \"x-aef\"),\n        TestVectors(    `(?<=(abc|dabc))(x)`,    \"dabcx\", \"y\",        \"$&-$1-$2\",  \"x-abc-x\"),\n        TestVectors(    `(?<=(|abc))x`,        \"dabcx\", \"y\",        \"$&-$1\",  \"x-\"),\n        TestVectors(    `(?<=((ab|da)*))x`,    \"abdaabx\", \"y\",        \"$&-$2-$1\",  \"x-ab-abdaab\"),\n        TestVectors(    `a(?<=(ba(?<=(aba)(?<=aaba))))`, \"aabaa\", \"y\", \"$&-$1-$2\", \"a-ba-aba\"),\n        TestVectors(    `.(?<!b).`,   \"bax\",  \"y\", \"$&\", \"ax\"),\n        TestVectors(    `(?<=b(?<!ab)).`,   \"abbx\",  \"y\",  \"$&\", \"x\"),\n        TestVectors(    `(?<=\\.|[!?]+)X`,   \"Hey?!X\", \"y\", \"$&\", \"X\"),\n        TestVectors(    `(?<=\\.|[!?]+)a{3}`,   \".Nope.aaaX\", \"y\", \"$&\", \"aaa\"),\n//mixed lookaround\n        TestVectors(   `a(?<=a(?=b))b`,    \"ab\", \"y\",      \"$&\", \"ab\"),\n        TestVectors(   `a(?<=a(?!b))c`,    \"ac\", \"y\",      \"$&\", \"ac\"),\n        TestVectors(   `a(?i)bc`,         \"aBc\", \"y\",      \"$&\", \"aBc\"),\n        TestVectors(   `a(?i)bc`,         \"Abc\", \"n\",      \"$&\", \"-\"),\n        TestVectors(   `(?i)a(?-i)bc`, \"aBcAbc\", \"y\",      \"$&\", \"Abc\"),\n        TestVectors(   `(?s).(?-s).`, \"\\n\\n\\na\", \"y\",      \"$&\", \"\\na\"),\n        TestVectors(   `(?m)^a(?-m)$`,  \"\\na\",   \"y\",      \"$&\", \"a\")\n        ];\n    string produceExpected(M,String)(auto ref M m, String fmt)\n    {\n        auto app = appender!(String)();\n        replaceFmt(fmt, m.captures, app, true);\n        return app.data;\n    }\n    void run_tests(alias matchFn)()\n    {\n        int i;\n        static foreach (Char; AliasSeq!( char, wchar, dchar))\n        {{\n            alias String = immutable(Char)[];\n            String produceExpected(M,Range)(auto ref M m, Range fmt)\n            {\n                auto app = appender!(String)();\n                replaceFmt(fmt, m.captures, app, true);\n                return app.data;\n            }\n            Regex!(Char) r;\n            foreach (a, tvd; tv)\n            {\n                uint c = tvd.result[0];\n                debug(std_regex_test) writeln(\" Test #\", a, \" pattern: \", tvd.pattern, \" with Char = \", Char.stringof);\n                try\n                {\n                    i = 1;\n                    r = regex(to!(String)(tvd.pattern), tvd.flags);\n                }\n                catch (RegexException e)\n                {\n                    i = 0;\n                    debug(std_regex_test) writeln(e.msg);\n                }\n\n                assert((c == 'c') ? !i : i, \"failed to compile pattern \"~tvd.pattern);\n\n                if (c != 'c')\n                {\n                    auto m = matchFn(to!(String)(tvd.input), r);\n                    i = !m.empty;\n                    assert(\n                        (c == 'y') ? i : !i,\n                        text(matchFn.stringof ~\": failed to match pattern #\", a ,\": \", tvd.pattern)\n                    );\n                    if (c == 'y')\n                    {\n                        auto result = produceExpected(m, to!(String)(tvd.format));\n                        assert(result == to!String(tvd.replace),\n                            text(matchFn.stringof ~\": mismatch pattern #\", a, \": \", tvd.pattern,\" expected: \",\n                                    tvd.replace, \" vs \", result));\n                    }\n                }\n            }\n        }}\n        debug(std_regex_test) writeln(\"!!! FReD bulk test done \"~matchFn.stringof~\" !!!\");\n    }\n\n\n    void ct_tests()\n    {\n        import std.algorithm.comparison : equal;\n        version (std_regex_ct1)\n        {\n            pragma(msg, \"Testing 1st part of ctRegex\");\n            enum Tests = iota(0, 155);\n        }\n        else version (std_regex_ct2)\n        {\n            pragma(msg, \"Testing 2nd part of ctRegex\");\n            enum Tests = iota(155, 174);\n        }\n        //FIXME: #174-178 contains CTFE parser bug\n        else version (std_regex_ct3)\n        {\n            pragma(msg, \"Testing 3rd part of ctRegex\");\n            enum Tests = iota(178, 220);\n        }\n        else version (std_regex_ct4)\n        {\n            pragma(msg, \"Testing 4th part of ctRegex\");\n            enum Tests = iota(220, tv.length);\n        }\n        else\n            enum Tests = chain(iota(0, 30), iota(235, tv.length-5));\n        static foreach (v; Tests)\n        {{\n            enum tvd = tv[v];\n            static if (tvd.result == \"c\")\n            {\n                static assert(!__traits(compiles, (){\n                    enum r = regex(tvd.pattern, tvd.flags);\n                }), \"errornously compiles regex pattern: \" ~ tvd.pattern);\n            }\n            else\n            {\n                //BUG: tv[v] is fine but tvd is not known at compile time?!\n                auto r = ctRegex!(tv[v].pattern, tv[v].flags);\n                auto nr = regex(tvd.pattern, tvd.flags);\n                assert(equal(r.ir, nr.ir),\n                    text(\"!C-T regex! failed to compile pattern #\", v ,\": \", tvd.pattern));\n                auto m = match(tvd.input, r);\n                auto c = tvd.result[0];\n                bool ok = (c == 'y') ^ m.empty;\n                assert(ok, text(\"ctRegex: failed to match pattern #\",\n                    v ,\": \", tvd.pattern));\n                if (c == 'y')\n                {\n                    auto result = produceExpected(m, tvd.format);\n                    assert(result == tvd.replace, text(\"ctRegex mismatch pattern #\", v,\n                        \": \", tvd.pattern,\" expected: \", tvd.replace, \" vs \", result));\n                }\n            }\n        }}\n        debug(std_regex_test) writeln(\"!!! FReD C-T test done !!!\");\n    }\n\n    ct_tests();\n    run_tests!bmatch(); //backtracker\n    run_tests!match(); //thompson VM\n}\n\n"
  },
  {
    "path": "libphobos/src/std/regex/internal/tests2.d",
    "content": "// Split-up due to DMD's enormous memory consumption\n\nmodule std.regex.internal.tests2;\n\npackage(std.regex):\n\nimport std.conv, std.exception, std.meta, std.range,\n    std.typecons, std.regex;\n\nimport std.uni : Escapables; // characters that need escaping\n\n@safe unittest\n{\n    auto cr = ctRegex!(\"abc\");\n    assert(bmatch(\"abc\",cr).hit == \"abc\");\n    auto cr2 = ctRegex!(\"ab*c\");\n    assert(bmatch(\"abbbbc\",cr2).hit == \"abbbbc\");\n}\n@safe unittest\n{\n    auto cr3 = ctRegex!(\"^abc$\");\n    assert(bmatch(\"abc\",cr3).hit == \"abc\");\n    auto cr4 = ctRegex!(`\\b(a\\B[a-z]b)\\b`);\n    assert(array(match(\"azb\",cr4).captures) == [\"azb\", \"azb\"]);\n}\n\n@safe unittest\n{\n    auto cr5 = ctRegex!(\"(?:a{2,4}b{1,3}){1,2}\");\n    assert(bmatch(\"aaabaaaabbb\", cr5).hit == \"aaabaaaabbb\");\n    auto cr6 = ctRegex!(\"(?:a{2,4}b{1,3}){1,2}?\"w);\n    assert(bmatch(\"aaabaaaabbb\"w,  cr6).hit == \"aaab\"w);\n}\n\n@safe unittest\n{\n    auto cr7 = ctRegex!(`\\r.*?$`,\"sm\");\n    assert(bmatch(\"abc\\r\\nxy\",  cr7).hit == \"\\r\\nxy\");\n    auto greed =  ctRegex!(\"<packet.*?/packet>\");\n    assert(bmatch(\"<packet>text</packet><packet>text</packet>\", greed).hit\n            == \"<packet>text</packet>\");\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto cr8 = ctRegex!(\"^(a)(b)?(c*)\");\n    auto m8 = bmatch(\"abcc\",cr8);\n    assert(m8);\n    assert(m8.captures[1] == \"a\");\n    assert(m8.captures[2] == \"b\");\n    assert(m8.captures[3] == \"cc\");\n    auto cr9 = ctRegex!(\"q(a|b)*q\");\n    auto m9 = match(\"xxqababqyy\",cr9);\n    assert(m9);\n    assert(equal(bmatch(\"xxqababqyy\",cr9).captures, [\"qababq\", \"b\"]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto rtr = regex(\"a|b|c\");\n    static ctr = regex(\"a|b|c\");\n    assert(equal(rtr.ir,ctr.ir));\n    //CTFE parser BUG is triggered by group\n    //in the middle of alternation (at least not first and not last)\n    static testCT = regex(`abc|(edf)|xyz`);\n    auto testRT = regex(`abc|(edf)|xyz`);\n    assert(equal(testCT.ir,testRT.ir));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    enum cx = ctRegex!\"(A|B|C)\";\n    auto mx = match(\"B\",cx);\n    assert(mx);\n    assert(equal(mx.captures, [ \"B\", \"B\"]));\n    enum cx2 = ctRegex!\"(A|B)*\";\n    assert(match(\"BAAA\",cx2));\n\n    enum cx3 = ctRegex!(\"a{3,4}\",\"i\");\n    auto mx3 = match(\"AaA\",cx3);\n    assert(mx3);\n    assert(mx3.captures[0] == \"AaA\");\n    enum cx4 = ctRegex!(`^a{3,4}?[a-zA-Z0-9~]{1,2}`,\"i\");\n    auto mx4 = match(\"aaaabc\", cx4);\n    assert(mx4);\n    assert(mx4.captures[0] == \"aaaab\");\n    auto cr8 = ctRegex!(\"(a)(b)?(c*)\");\n    auto m8 = bmatch(\"abcc\",cr8);\n    assert(m8);\n    assert(m8.captures[1] == \"a\");\n    assert(m8.captures[2] == \"b\");\n    assert(m8.captures[3] == \"cc\");\n    auto cr9 = ctRegex!(\".*$\", \"gm\");\n    auto m9 = match(\"First\\rSecond\", cr9);\n    assert(m9);\n    assert(equal(map!\"a.hit\"(m9), [\"First\", \"\", \"Second\"]));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n//global matching\n    void test_body(alias matchFn)()\n    {\n        string s = \"a quick brown fox jumps over a lazy dog\";\n        auto r1 = regex(\"\\\\b[a-z]+\\\\b\",\"g\");\n        string[] test;\n        foreach (m; matchFn(s, r1))\n            test ~= m.hit;\n        assert(equal(test, [ \"a\", \"quick\", \"brown\", \"fox\", \"jumps\", \"over\", \"a\", \"lazy\", \"dog\"]));\n        auto free_reg = regex(`\n\n            abc\n            \\s+\n            \"\n            (\n                    [^\"]+\n                |   \\\\ \"\n            )+\n            \"\n            z\n        `, \"x\");\n        auto m = match(`abc  \"quoted string with \\\" inside\"z`,free_reg);\n        assert(m);\n        string mails = \" hey@you.com no@spam.net \";\n        auto rm = regex(`@(?<=\\S+@)\\S+`,\"g\");\n        assert(equal(map!\"a[0]\"(matchFn(mails, rm)), [\"@you.com\", \"@spam.net\"]));\n        auto m2 = matchFn(\"First line\\nSecond line\",regex(\".*$\",\"gm\"));\n        assert(equal(map!\"a[0]\"(m2), [\"First line\", \"\", \"Second line\"]));\n        auto m2a = matchFn(\"First line\\nSecond line\",regex(\".+$\",\"gm\"));\n        assert(equal(map!\"a[0]\"(m2a), [\"First line\", \"Second line\"]));\n        auto m2b = matchFn(\"First line\\nSecond line\",regex(\".+?$\",\"gm\"));\n        assert(equal(map!\"a[0]\"(m2b), [\"First line\", \"Second line\"]));\n        debug(std_regex_test) writeln(\"!!! FReD FLAGS test done \"~matchFn.stringof~\" !!!\");\n    }\n    test_body!bmatch();\n    test_body!match();\n}\n\n//tests for accumulated std.regex issues and other regressions\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    void test_body(alias matchFn)()\n    {\n        //issue 5857\n        //matching goes out of control if ... in (...){x} has .*/.+\n        auto c = matchFn(\"axxxzayyyyyzd\",regex(\"(a.*z){2}d\")).captures;\n        assert(c[0] == \"axxxzayyyyyzd\");\n        assert(c[1] == \"ayyyyyz\");\n        auto c2 = matchFn(\"axxxayyyyyd\",regex(\"(a.*){2}d\")).captures;\n        assert(c2[0] == \"axxxayyyyyd\");\n        assert(c2[1] == \"ayyyyy\");\n        //issue 2108\n        //greedy vs non-greedy\n        auto nogreed = regex(\"<packet.*?/packet>\");\n        assert(matchFn(\"<packet>text</packet><packet>text</packet>\", nogreed).hit\n               == \"<packet>text</packet>\");\n        auto greed =  regex(\"<packet.*/packet>\");\n        assert(matchFn(\"<packet>text</packet><packet>text</packet>\", greed).hit\n               == \"<packet>text</packet><packet>text</packet>\");\n        //issue 4574\n        //empty successful match still advances the input\n        string[] pres, posts, hits;\n        foreach (m; matchFn(\"abcabc\", regex(\"\",\"g\")))\n        {\n            pres ~= m.pre;\n            posts ~= m.post;\n            assert(m.hit.empty);\n\n        }\n        auto heads = [\n            \"abcabc\",\n            \"abcab\",\n            \"abca\",\n            \"abc\",\n            \"ab\",\n            \"a\",\n            \"\"\n        ];\n        auto tails = [\n            \"abcabc\",\n             \"bcabc\",\n              \"cabc\",\n               \"abc\",\n                \"bc\",\n                 \"c\",\n                  \"\"\n        ];\n        assert(pres == array(retro(heads)));\n        assert(posts == tails);\n        //issue 6076\n        //regression on .*\n        auto re = regex(\"c.*|d\");\n        auto m = matchFn(\"mm\", re);\n        assert(!m);\n        debug(std_regex_test) writeln(\"!!! FReD REGRESSION test done \"~matchFn.stringof~\" !!!\");\n        auto rprealloc = regex(`((.){5}.{1,10}){5}`);\n        auto arr = array(repeat('0',100));\n        auto m2 = matchFn(arr, rprealloc);\n        assert(m2);\n        assert(collectException(\n                regex(r\"^(import|file|binary|config)\\s+([^\\(]+)\\(?([^\\)]*)\\)?\\s*$\")\n                ) is null);\n        foreach (ch; [Escapables])\n        {\n            assert(match(to!string(ch),regex(`[\\`~ch~`]`)));\n            assert(!match(to!string(ch),regex(`[^\\`~ch~`]`)));\n            assert(match(to!string(ch),regex(`[\\`~ch~`-\\`~ch~`]`)));\n        }\n        //bugzilla 7718\n        string strcmd = \"./myApp.rb -os OSX -path \\\"/GIT/Ruby Apps/sec\\\" -conf 'notimer'\";\n        auto reStrCmd = regex (`(\".*\")|('.*')`, \"g\");\n        assert(equal(map!\"a[0]\"(matchFn(strcmd, reStrCmd)),\n                     [`\"/GIT/Ruby Apps/sec\"`, `'notimer'`]));\n    }\n    test_body!bmatch();\n    test_body!match();\n}\n\n// tests for replace\n@safe unittest\n{\n    void test(alias matchFn)()\n    {\n        import std.uni : toUpper;\n\n        static foreach (i, v; AliasSeq!(string, wstring, dstring))\n        {{\n            auto baz(Cap)(Cap m)\n            if (is(Cap == Captures!(Cap.String)))\n            {\n                return toUpper(m.hit);\n            }\n            alias String = v;\n            assert(std.regex.replace!(matchFn)(to!String(\"ark rapacity\"), regex(to!String(\"r\")), to!String(\"c\"))\n                   == to!String(\"ack rapacity\"));\n            assert(std.regex.replace!(matchFn)(to!String(\"ark rapacity\"), regex(to!String(\"r\"), \"g\"), to!String(\"c\"))\n                   == to!String(\"ack capacity\"));\n            assert(std.regex.replace!(matchFn)(to!String(\"noon\"), regex(to!String(\"^n\")), to!String(\"[$&]\"))\n                   == to!String(\"[n]oon\"));\n            assert(std.regex.replace!(matchFn)(\n                to!String(\"test1 test2\"), regex(to!String(`\\w+`),\"g\"), to!String(\"$`:$'\")\n            ) == to!String(\": test2 test1 :\"));\n            auto s = std.regex.replace!(baz!(Captures!(String)))(to!String(\"Strap a rocket engine on a chicken.\"),\n                    regex(to!String(\"[ar]\"), \"g\"));\n            assert(s == \"StRAp A Rocket engine on A chicken.\");\n        }}\n        debug(std_regex_test) writeln(\"!!! Replace test done \"~matchFn.stringof~\"  !!!\");\n    }\n    test!(bmatch)();\n    test!(match)();\n}\n\n// tests for splitter\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto s1 = \", abc, de,     fg, hi, \";\n    auto sp1 = splitter(s1, regex(\", *\"));\n    auto w1 = [\"\", \"abc\", \"de\", \"fg\", \"hi\", \"\"];\n    assert(equal(sp1, w1));\n\n    auto s2 = \", abc, de,  fg, hi\";\n    auto sp2 = splitter(s2, regex(\", *\"));\n    auto w2 = [\"\", \"abc\", \"de\", \"fg\", \"hi\"];\n\n    uint cnt;\n    foreach (e; sp2)\n    {\n        assert(w2[cnt++] == e);\n    }\n    assert(equal(sp2, w2));\n}\n\n@safe unittest\n{\n    char[] s1 = \", abc, de,  fg, hi, \".dup;\n    auto sp2 = splitter(s1, regex(\", *\"));\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto s1 = \", abc, de,  fg, hi, \";\n    auto w1 = [\"\", \"abc\", \"de\", \"fg\", \"hi\", \"\"];\n    assert(equal(split(s1, regex(\", *\")), w1[]));\n}\n\n@safe unittest\n{ // bugzilla 7141\n    string pattern = `[a\\--b]`;\n    assert(match(\"-\", pattern));\n    assert(match(\"b\", pattern));\n    string pattern2 = `[&-z]`;\n    assert(match(\"b\", pattern2));\n}\n@safe unittest\n{//bugzilla 7111\n    assert(match(\"\", regex(\"^\")));\n}\n@safe unittest\n{//bugzilla 7300\n    assert(!match(\"a\"d, \"aa\"d));\n}\n\n// bugzilla 7551\n@safe unittest\n{\n    auto r = regex(\"[]abc]*\");\n    assert(\"]ab\".matchFirst(r).hit == \"]ab\");\n    assertThrown(regex(\"[]\"));\n    auto r2 = regex(\"[]abc--ab]*\");\n    assert(\"]ac\".matchFirst(r2).hit == \"]\");\n}\n\n@safe unittest\n{//bugzilla 7674\n    assert(\"1234\".replace(regex(\"^\"), \"$$\") == \"$1234\");\n    assert(\"hello?\".replace(regex(r\"\\?\", \"g\"), r\"\\?\") == r\"hello\\?\");\n    assert(\"hello?\".replace(regex(r\"\\?\", \"g\"), r\"\\\\?\") != r\"hello\\?\");\n}\n@safe unittest\n{// bugzilla 7679\n    import std.algorithm.comparison : equal;\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        enum re = ctRegex!(to!S(r\"\\.\"));\n        auto str = to!S(\"a.b\");\n        assert(equal(std.regex.splitter(str, re), [to!S(\"a\"), to!S(\"b\")]));\n        assert(split(str, re) == [to!S(\"a\"), to!S(\"b\")]);\n    }}\n}\n@safe unittest\n{//bugzilla 8203\n    string data = \"\n    NAME   = XPAW01_STA:STATION\n    NAME   = XPAW01_STA\n    \";\n    auto uniFileOld = data;\n    auto r = regex(\n       r\"^NAME   = (?P<comp>[a-zA-Z0-9_]+):*(?P<blk>[a-zA-Z0-9_]*)\",\"gm\");\n    auto uniCapturesNew = match(uniFileOld, r);\n    for (int i = 0; i < 20; i++)\n        foreach (matchNew; uniCapturesNew) {}\n    //a second issue with same symptoms\n    auto r2 = regex(`([а-яА-Я\\-_]+\\s*)+(?<=[\\s\\.,\\^])`);\n    match(\"аллея Театральная\", r2);\n}\n@safe unittest\n{// bugzilla 8637 purity of enforce\n    auto m = match(\"hello world\", regex(\"world\"));\n    enforce(m);\n}\n\n// bugzilla 8725\n@safe unittest\n{\n  static italic = regex( r\"\\*\n                (?!\\s+)\n                (.*?)\n                (?!\\s+)\n                \\*\", \"gx\" );\n  string input = \"this * is* interesting, *very* interesting\";\n  assert(replace(input, italic, \"<i>$1</i>\") ==\n      \"this * is* interesting, <i>very</i> interesting\");\n}\n\n// bugzilla 8349\n@safe unittest\n{\n    enum peakRegexStr = r\"\\>(wgEncode.*Tfbs.*\\.(?:narrow)|(?:broad)Peak.gz)</a>\";\n    enum peakRegex = ctRegex!(peakRegexStr);\n    //note that the regex pattern itself is probably bogus\n    assert(match(r\"\\>wgEncode-blah-Tfbs.narrow</a>\", peakRegex));\n}\n\n// bugzilla 9211\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto rx_1 =  regex(r\"^(\\w)*(\\d)\");\n    auto m = match(\"1234\", rx_1);\n    assert(equal(m.front, [\"1234\", \"3\", \"4\"]));\n    auto rx_2 = regex(r\"^([0-9])*(\\d)\");\n    auto m2 = match(\"1234\", rx_2);\n    assert(equal(m2.front, [\"1234\", \"3\", \"4\"]));\n}\n\n// bugzilla 9280\n@safe unittest\n{\n    string tomatch = \"a!b@c\";\n    static r = regex(r\"^(?P<nick>.*?)!(?P<ident>.*?)@(?P<host>.*?)$\");\n    auto nm = match(tomatch, r);\n    assert(nm);\n    auto c = nm.captures;\n    assert(c[1] == \"a\");\n    assert(c[\"nick\"] == \"a\");\n}\n\n\n// bugzilla 9579\n@safe unittest\n{\n    char[] input = ['a', 'b', 'c'];\n    string format = \"($1)\";\n    // used to give a compile error:\n    auto re = regex(`(a)`, \"g\");\n    auto r = replace(input, re, format);\n    assert(r == \"(a)bc\");\n}\n\n// bugzilla 9634\n@safe unittest\n{\n    auto re = ctRegex!\"(?:a+)\";\n    assert(match(\"aaaa\", re).hit == \"aaaa\");\n}\n\n//bugzilla 10798\n@safe unittest\n{\n    auto cr = ctRegex!(\"[abcd--c]*\");\n    auto m  = \"abc\".match(cr);\n    assert(m);\n    assert(m.hit == \"ab\");\n}\n\n// bugzilla 10913\n@system unittest\n{\n    @system static string foo(const(char)[] s)\n    {\n        return s.dup;\n    }\n    @safe static string bar(const(char)[] s)\n    {\n        return s.dup;\n    }\n    () @system {\n        replace!((a) => foo(a.hit))(\"blah\", regex(`a`));\n    }();\n    () @safe {\n        replace!((a) => bar(a.hit))(\"blah\", regex(`a`));\n    }();\n}\n\n// bugzilla 11262\n@safe unittest\n{\n    enum reg = ctRegex!(r\",\", \"g\");\n    auto str = \"This,List\";\n    str = str.replace(reg, \"-\");\n    assert(str == \"This-List\");\n}\n\n// bugzilla 11775\n@safe unittest\n{\n    assert(collectException(regex(\"a{1,0}\")));\n}\n\n// bugzilla 11839\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    assert(regex(`(?P<var1>\\w+)`).namedCaptures.equal([\"var1\"]));\n    assert(collectException(regex(`(?P<1>\\w+)`)));\n    assert(regex(`(?P<v1>\\w+)`).namedCaptures.equal([\"v1\"]));\n    assert(regex(`(?P<__>\\w+)`).namedCaptures.equal([\"__\"]));\n    assert(regex(`(?P<я>\\w+)`).namedCaptures.equal([\"я\"]));\n}\n\n// bugzilla 12076\n@safe unittest\n{\n    auto RE = ctRegex!(r\"(?<!x[a-z]+)\\s([a-z]+)\");\n    string s = \"one two\";\n    auto m = match(s, RE);\n}\n\n// bugzilla 12105\n@safe unittest\n{\n    auto r = ctRegex!`.*?(?!a)`;\n    assert(\"aaab\".matchFirst(r).hit == \"aaa\");\n    auto r2 = ctRegex!`.*(?!a)`;\n    assert(\"aaab\".matchFirst(r2).hit == \"aaab\");\n}\n\n//bugzilla 11784\n@safe unittest\n{\n    assert(\"abcdefghijklmnopqrstuvwxyz\"\n        .matchFirst(\"[a-z&&[^aeiuo]]\").hit == \"b\");\n}\n\n//bugzilla 12366\n@safe unittest\n{\n     auto re = ctRegex!(`^((?=(xx+?)\\2+$)((?=\\2+$)(?=(x+)(\\4+$))\\5){2})*x?$`);\n     assert(\"xxxxxxxx\".match(re).empty);\n     assert(!\"xxxx\".match(re).empty);\n}\n\n// bugzilla 12582\n@safe unittest\n{\n    auto r = regex(`(?P<a>abc)`);\n    assert(collectException(\"abc\".matchFirst(r)[\"b\"]));\n}\n\n// bugzilla 12691\n@safe unittest\n{\n    assert(bmatch(\"e@\", \"^([a-z]|)*$\").empty);\n    assert(bmatch(\"e@\", ctRegex!`^([a-z]|)*$`).empty);\n}\n\n//bugzilla  12713\n@safe unittest\n{\n    assertThrown(regex(\"[[a-z]([a-z]|(([[a-z])))\"));\n}\n\n//bugzilla 12747\n@safe unittest\n{\n    assertThrown(regex(`^x(\\1)`));\n    assertThrown(regex(`^(x(\\1))`));\n    assertThrown(regex(`^((x)(?=\\1))`));\n}\n\n// bugzilla 13532\nversion (none) // TODO: revist once we have proper benchmark framework\n@safe unittest\n{\n    import std.datetime.stopwatch : StopWatch, AutoStart;\n    import std.math : abs;\n    import std.conv : to;\n    enum re1 = ctRegex!`[0-9][0-9]`;\n    immutable static re2 = ctRegex!`[0-9][0-9]`;\n    immutable iterations = 1_000_000;\n    size_t result1 = 0, result2 = 0;\n    auto sw = StopWatch(AutoStart.yes);\n    foreach (_; 0 .. iterations)\n    {\n        result1 += matchFirst(\"12345678\", re1).length;\n    }\n    const staticTime = sw.peek();\n    sw.reset();\n    foreach (_; 0 .. iterations)\n    {\n        result2 += matchFirst(\"12345678\", re2).length;\n    }\n    const enumTime = sw.peek();\n    assert(result1 == result2);\n    auto ratio = 1.0 * enumTime.total!\"usecs\" / staticTime.total!\"usecs\";\n    // enum is faster or the diff is less < 30%\n    assert(ratio < 1.0 || abs(ratio - 1.0) < 0.75,\n        \"enum regex to static regex ratio \"~to!string(ratio));\n}\n\n// bugzilla 14504\n@safe unittest\n{\n    auto p = ctRegex!(\"a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?\" ~\n            \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");\n}\n\n// bugzilla 14529\n@safe unittest\n{\n    auto ctPat2 = regex(r\"^[CDF]$\", \"i\");\n    foreach (v; [\"C\", \"c\", \"D\", \"d\", \"F\", \"f\"])\n        assert(matchAll(v, ctPat2).front.hit == v);\n}\n\n// bugzilla 14615\n@safe unittest\n{\n    import std.array : appender;\n    import std.regex : replaceFirst, replaceFirstInto, regex;\n    import std.stdio : writeln;\n\n    auto example = \"Hello, world!\";\n    auto pattern = regex(\"^Hello, (bug)\");  // won't find this one\n    auto result = replaceFirst(example, pattern, \"$1 Sponge Bob\");\n    assert(result == \"Hello, world!\");  // Ok.\n\n    auto sink = appender!string;\n    replaceFirstInto(sink, example, pattern, \"$1 Sponge Bob\");\n    assert(sink.data == \"Hello, world!\");\n    replaceAllInto(sink, example, pattern, \"$1 Sponge Bob\");\n    assert(sink.data == \"Hello, world!Hello, world!\");\n}\n\n// bugzilla 15573\n@safe unittest\n{\n    auto rx = regex(\"[c d]\", \"x\");\n    assert(\"a b\".matchFirst(rx));\n}\n\n// bugzilla 15864\n@safe unittest\n{\n    regex(`(<a (?:(?:\\w+=\\\"[^\"]*\\\")?\\s*)*href=\"\\.\\.?)\"`);\n}\n\n@safe unittest\n{\n    auto r = regex(\"(?# comment)abc(?# comment2)\");\n    assert(\"abc\".matchFirst(r));\n    assertThrown(regex(\"(?#...\"));\n}\n\n// bugzilla 17075\n@safe unittest\n{\n    enum titlePattern = `<title>(.+)</title>`;\n    static titleRegex = ctRegex!titlePattern;\n    string input = \"<title>\" ~ \"<\".repeat(100_000).join;\n    assert(input.matchFirst(titleRegex).empty);\n}\n\n// bugzilla 17212\n@safe unittest\n{\n    auto r = regex(\" [a] \", \"x\");\n    assert(\"a\".matchFirst(r));\n}\n\n// bugzilla 17157\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    auto ctr = ctRegex!\"(a)|(b)|(c)|(d)\";\n    auto r = regex(\"(a)|(b)|(c)|(d)\", \"g\");\n    auto s = \"--a--b--c--d--\";\n    auto outcomes = [\n        [\"a\", \"a\", \"\", \"\", \"\"],\n        [\"b\", \"\", \"b\", \"\", \"\"],\n        [\"c\", \"\", \"\", \"c\", \"\"],\n        [\"d\", \"\", \"\", \"\", \"d\"]\n    ];\n    assert(equal!equal(s.matchAll(ctr), outcomes));\n    assert(equal!equal(s.bmatch(r), outcomes));\n}\n\n// bugzilla 17667\n@safe unittest\n{\n    import std.algorithm.searching : canFind;\n    void willThrow(T, size_t line = __LINE__)(T arg, string msg)\n    {\n        auto e = collectException(regex(arg));\n        assert(e.msg.canFind(msg), to!string(line) ~ \": \" ~ e.msg);\n    }\n    willThrow([r\".\", r\"[\\(\\{[\\]\\}\\)]\"], \"no matching ']' found while parsing character class\");\n    willThrow([r\"[\\\", r\"123\"], \"no matching ']' found while parsing character class\");\n    willThrow([r\"[a-\", r\"123\"], \"no matching ']' found while parsing character class\");\n    willThrow([r\"[a-\\\", r\"123\"], \"no matching ']' found while parsing character class\");\n    willThrow([r\"\\\", r\"123\"], \"invalid escape sequence\");\n}\n\n// bugzilla 17668\n@safe unittest\n{\n    import std.algorithm.searching;\n    auto e = collectException!RegexException(regex(q\"<[^]>\"));\n    assert(e.msg.canFind(\"no operand for '^'\"), e.msg);\n}\n\n// bugzilla 17673\n@safe unittest\n{\n    string str = `<\">`;\n    string[] regexps = [\"abc\", \"\\\"|x\"];\n    auto regexp = regex(regexps);\n    auto c = matchFirst(str, regexp);\n    assert(c);\n    assert(c.whichPattern == 2);\n}\n\n// bugzilla 18692\n@safe unittest\n{\n    auto rx = regex(\"()()()\");\n    auto ma = \"\".matchFirst(rx);\n    auto ma2 = ma;\n    ma = ma2;\n    assert(ma[1] == \"\");\n}"
  },
  {
    "path": "libphobos/src/std/regex/internal/thompson.d",
    "content": "//Written in the D programming language\n/*\n    Implementation of Thompson NFA std.regex engine.\n    Key point is evaluation of all possible threads (state) at each step\n    in a breadth-first manner, thereby geting some nice properties:\n        - looking at each character only once\n        - merging of equivalent threads, that gives matching process linear time complexity\n*/\nmodule std.regex.internal.thompson;\n\npackage(std.regex):\n\nimport std.range.primitives;\nimport std.regex.internal.ir;\n\n//State of VM thread\nstruct Thread(DataIndex)\n{\n    Thread* next;    //intrusive linked list\n    uint pc;\n    uint counter;    //loop counter\n    uint uopCounter; //counts micro operations inside one macro instruction (e.g. BackRef)\n    Group!DataIndex[1] matches;\n}\n\n//head-tail singly-linked list\nstruct ThreadList(DataIndex)\n{\n    Thread!DataIndex* tip = null, toe = null;\n    //add new thread to the start of list\n    void insertFront(Thread!DataIndex* t)\n    {\n        if (tip)\n        {\n            t.next = tip;\n            tip = t;\n        }\n        else\n        {\n            t.next = null;\n            tip = toe = t;\n        }\n    }\n    //add new thread to the end of list\n    void insertBack(Thread!DataIndex* t)\n    {\n        if (toe)\n        {\n            toe.next = t;\n            toe = t;\n        }\n        else\n            tip = toe = t;\n        toe.next = null;\n    }\n    //move head element out of list\n    Thread!DataIndex* fetch()\n    {\n        auto t = tip;\n        if (tip == toe)\n            tip = toe = null;\n        else\n            tip = tip.next;\n        return t;\n    }\n    //non-destructive iteration of ThreadList\n    struct ThreadRange\n    {\n        const(Thread!DataIndex)* ct;\n        this(ThreadList tlist){ ct = tlist.tip; }\n        @property bool empty(){ return ct is null; }\n        @property const(Thread!DataIndex)* front(){ return ct; }\n        void popFront()\n        {\n            assert(ct);\n            ct = ct.next;\n        }\n    }\n    @property bool empty()\n    {\n        return tip == null;\n    }\n    ThreadRange opSlice()\n    {\n        return ThreadRange(this);\n    }\n}\n\ntemplate ThompsonOps(E, S, bool withInput:true)\n{\n@trusted:\n    static bool op(IR code:IR.End)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            finish(t, matches, re.ir[t.pc].data);\n            //fix endpoint of the whole match\n            matches[0].end = index;\n            recycle(t);\n            //cut off low priority threads\n            recycle(clist);\n            recycle(worklist);\n            debug(std_regex_matcher) writeln(\"Finished thread \", matches);\n            return false; // no more state to eval\n        }\n    }\n\n    static bool op(IR code:IR.Wordboundary)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            dchar back;\n            DataIndex bi;\n            //at start & end of input\n            if (atStart && wordMatcher[front])\n            {\n                t.pc += IRL!(IR.Wordboundary);\n                return true;\n            }\n            else if (atEnd && s.loopBack(index).nextChar(back, bi)\n                    && wordMatcher[back])\n            {\n                t.pc += IRL!(IR.Wordboundary);\n                return true;\n            }\n            else if (s.loopBack(index).nextChar(back, bi))\n            {\n                bool af = wordMatcher[front];\n                bool ab = wordMatcher[back];\n                if (af ^ ab)\n                {\n                    t.pc += IRL!(IR.Wordboundary);\n                    return true;\n                }\n            }\n            return popState(e);\n        }\n    }\n\n    static bool op(IR code:IR.Notwordboundary)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            dchar back;\n            DataIndex bi;\n            //at start & end of input\n            if (atStart && wordMatcher[front])\n            {\n                return popState(e);\n            }\n            else if (atEnd && s.loopBack(index).nextChar(back, bi)\n                    && wordMatcher[back])\n            {\n                return popState(e);\n            }\n            else if (s.loopBack(index).nextChar(back, bi))\n            {\n                bool af = wordMatcher[front];\n                bool ab = wordMatcher[back]  != 0;\n                if (af ^ ab)\n                {\n                    return popState(e);\n                }\n            }\n            t.pc += IRL!(IR.Notwordboundary);\n        }\n        return true;\n    }\n\n    static bool op(IR code:IR.Bof)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            if (atStart)\n            {\n                t.pc += IRL!(IR.Bof);\n                return true;\n            }\n            else\n            {\n                return popState(e);\n            }\n        }\n    }\n\n    static bool op(IR code:IR.Bol)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            dchar back;\n            DataIndex bi;\n            if (atStart\n                ||(s.loopBack(index).nextChar(back,bi)\n                && startOfLine(back, front == '\\n')))\n            {\n                t.pc += IRL!(IR.Bol);\n                return true;\n            }\n            else\n            {\n                return popState(e);\n            }\n        }\n    }\n\n    static bool op(IR code:IR.Eof)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            if (atEnd)\n            {\n                t.pc += IRL!(IR.Eol);\n                return true;\n            }\n            else\n            {\n                return popState(e);\n            }\n        }\n    }\n\n    static bool op(IR code:IR.Eol)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            dchar back;\n            DataIndex bi;\n            //no matching inside \\r\\n\n            if (atEnd || (endOfLine(front, s.loopBack(index).nextChar(back, bi)\n                    && back == '\\r')))\n            {\n                t.pc += IRL!(IR.Eol);\n                return true;\n            }\n            else\n            {\n                return popState(e);\n            }\n\n        }\n    }\n\n    static bool op(IR code:IR.InfiniteStart)(E e, S* state)\n    {\n        with(e) with(state)\n            t.pc += re.ir[t.pc].data + IRL!(IR.InfiniteStart);\n        return op!(IR.InfiniteEnd)(e,state);\n    }\n\n    static bool op(IR code:IR.InfiniteBloomStart)(E e, S* state)\n    {\n        with(e) with(state)\n            t.pc += re.ir[t.pc].data + IRL!(IR.InfiniteBloomStart);\n        return op!(IR.InfiniteBloomEnd)(e,state);\n    }\n\n    static bool op(IR code:IR.InfiniteQStart)(E e, S* state)\n    {\n        with(e) with(state)\n            t.pc += re.ir[t.pc].data + IRL!(IR.InfiniteQStart);\n        return op!(IR.InfiniteQEnd)(e,state);\n    }\n\n    static bool op(IR code:IR.RepeatStart)(E e, S* state)\n    {\n        with(e) with(state)\n            t.pc += re.ir[t.pc].data + IRL!(IR.RepeatStart);\n        return op!(IR.RepeatEnd)(e,state);\n    }\n\n    static bool op(IR code:IR.RepeatQStart)(E e, S* state)\n    {\n        with(e) with(state)\n            t.pc += re.ir[t.pc].data + IRL!(IR.RepeatQStart);\n        return op!(IR.RepeatQEnd)(e,state);\n    }\n\n    static bool op(IR code)(E e, S* state)\n        if (code == IR.RepeatEnd || code == IR.RepeatQEnd)\n    {\n        with(e) with(state)\n        {\n            //len, step, min, max\n                uint len = re.ir[t.pc].data;\n                uint step =  re.ir[t.pc+2].raw;\n                uint min = re.ir[t.pc+3].raw;\n                if (t.counter < min)\n                {\n                    t.counter += step;\n                    t.pc -= len;\n                    return true;\n                }\n                if (merge[re.ir[t.pc + 1].raw+t.counter] < genCounter)\n                {\n                    debug(std_regex_matcher) writefln(\"A thread(pc=%s) passed there : %s ; GenCounter=%s mergetab=%s\",\n                                    t.pc, index, genCounter, merge[re.ir[t.pc + 1].raw+t.counter] );\n                    merge[re.ir[t.pc + 1].raw+t.counter] = genCounter;\n                }\n                else\n                {\n                    debug(std_regex_matcher)\n                        writefln(\"A thread(pc=%s) got merged there : %s ; GenCounter=%s mergetab=%s\",\n                            t.pc, index, genCounter, merge[re.ir[t.pc + 1].raw+t.counter] );\n                    return popState(e);\n                }\n                uint max = re.ir[t.pc+4].raw;\n                if (t.counter < max)\n                {\n                    if (re.ir[t.pc].code == IR.RepeatEnd)\n                    {\n                        //queue out-of-loop thread\n                        worklist.insertFront(fork(t, t.pc + IRL!(IR.RepeatEnd),  t.counter % step));\n                        t.counter += step;\n                        t.pc -= len;\n                    }\n                    else\n                    {\n                        //queue into-loop thread\n                        worklist.insertFront(fork(t, t.pc - len,  t.counter + step));\n                        t.counter %= step;\n                        t.pc += IRL!(IR.RepeatEnd);\n                    }\n                }\n                else\n                {\n                    t.counter %= step;\n                    t.pc += IRL!(IR.RepeatEnd);\n                }\n                return true;\n        }\n    }\n\n    static bool op(IR code)(E e, S* state)\n        if (code == IR.InfiniteEnd || code == IR.InfiniteQEnd)\n    {\n        with(e) with(state)\n        {\n            if (merge[re.ir[t.pc + 1].raw+t.counter] < genCounter)\n            {\n                debug(std_regex_matcher) writefln(\"A thread(pc=%s) passed there : %s ; GenCounter=%s mergetab=%s\",\n                                t.pc, index, genCounter, merge[re.ir[t.pc + 1].raw+t.counter] );\n                merge[re.ir[t.pc + 1].raw+t.counter] = genCounter;\n            }\n            else\n            {\n                debug(std_regex_matcher) writefln(\"A thread(pc=%s) got merged there : %s ; GenCounter=%s mergetab=%s\",\n                                t.pc, index, genCounter, merge[re.ir[t.pc + 1].raw+t.counter] );\n                return popState(e);\n            }\n            uint len = re.ir[t.pc].data;\n            uint pc1, pc2; //branches to take in priority order\n            if (re.ir[t.pc].code == IR.InfiniteEnd)\n            {\n                pc1 = t.pc - len;\n                pc2 = t.pc + IRL!(IR.InfiniteEnd);\n            }\n            else\n            {\n                pc1 = t.pc + IRL!(IR.InfiniteEnd);\n                pc2 = t.pc - len;\n            }\n            worklist.insertFront(fork(t, pc2, t.counter));\n            t.pc = pc1;\n            return true;\n        }\n    }\n\n    static bool op(IR code)(E e, S* state)\n        if (code == IR.InfiniteBloomEnd)\n    {\n        with(e) with(state)\n        {\n            if (merge[re.ir[t.pc + 1].raw+t.counter] < genCounter)\n            {\n                debug(std_regex_matcher) writefln(\"A thread(pc=%s) passed there : %s ; GenCounter=%s mergetab=%s\",\n                                t.pc, index, genCounter, merge[re.ir[t.pc + 1].raw+t.counter] );\n                merge[re.ir[t.pc + 1].raw+t.counter] = genCounter;\n            }\n            else\n            {\n                debug(std_regex_matcher) writefln(\"A thread(pc=%s) got merged there : %s ; GenCounter=%s mergetab=%s\",\n                                t.pc, index, genCounter, merge[re.ir[t.pc + 1].raw+t.counter] );\n                return popState(e);\n            }\n            uint len = re.ir[t.pc].data;\n            uint pc1, pc2; //branches to take in priority order\n            pc1 = t.pc - len;\n            pc2 = t.pc + IRL!(IR.InfiniteBloomEnd);\n            uint filterIndex = re.ir[t.pc + 2].raw;\n            if (re.filters[filterIndex][front])\n                worklist.insertFront(fork(t, pc2, t.counter));\n            t.pc = pc1;\n            return true;\n        }\n    }\n\n    static bool op(IR code:IR.OrEnd)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            if (merge[re.ir[t.pc + 1].raw+t.counter] < genCounter)\n            {\n                debug(std_regex_matcher) writefln(\"A thread(pc=%s) passed there : %s ; GenCounter=%s mergetab=%s\",\n                                t.pc, s[index .. s.lastIndex], genCounter, merge[re.ir[t.pc + 1].raw + t.counter] );\n                merge[re.ir[t.pc + 1].raw+t.counter] = genCounter;\n                t.pc += IRL!(IR.OrEnd);\n            }\n            else\n            {\n                debug(std_regex_matcher) writefln(\"A thread(pc=%s) got merged there : %s ; GenCounter=%s mergetab=%s\",\n                                t.pc, s[index .. s.lastIndex], genCounter, merge[re.ir[t.pc + 1].raw + t.counter] );\n                return popState(e);\n            }\n            return true;\n        }\n    }\n\n    static bool op(IR code:IR.OrStart)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            t.pc += IRL!(IR.OrStart);\n            return op!(IR.Option)(e,state);\n        }\n    }\n\n    static bool op(IR code:IR.Option)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            uint next = t.pc + re.ir[t.pc].data + IRL!(IR.Option);\n            //queue next Option\n            if (re.ir[next].code == IR.Option)\n            {\n                worklist.insertFront(fork(t, next, t.counter));\n            }\n            t.pc += IRL!(IR.Option);\n            return true;\n        }\n    }\n\n    static bool op(IR code:IR.GotoEndOr)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            t.pc = t.pc + re.ir[t.pc].data + IRL!(IR.GotoEndOr);\n            return op!(IR.OrEnd)(e, state);\n        }\n    }\n\n    static bool op(IR code:IR.GroupStart)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            uint n = re.ir[t.pc].data;\n            t.matches.ptr[n].begin = index;\n            t.pc += IRL!(IR.GroupStart);\n            return true;\n        }\n    }\n    static bool op(IR code:IR.GroupEnd)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            uint n = re.ir[t.pc].data;\n            t.matches.ptr[n].end = index;\n            t.pc += IRL!(IR.GroupEnd);\n            return true;\n        }\n    }\n\n    static bool op(IR code:IR.Backref)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            uint n = re.ir[t.pc].data;\n            Group!DataIndex* source = re.ir[t.pc].localRef ? t.matches.ptr : backrefed.ptr;\n            assert(source);\n            if (source[n].begin == source[n].end)//zero-width Backref!\n            {\n                t.pc += IRL!(IR.Backref);\n                return true;\n            }\n            else\n            {\n                size_t idx = source[n].begin + t.uopCounter;\n                size_t end = source[n].end;\n                if (s[idx .. end].front == front)\n                {\n                    import std.utf : stride;\n\n                    t.uopCounter += stride(s[idx .. end], 0);\n                    if (t.uopCounter + source[n].begin == source[n].end)\n                    {//last codepoint\n                        t.pc += IRL!(IR.Backref);\n                        t.uopCounter = 0;\n                    }\n                    nlist.insertBack(t);\n                }\n                else\n                    recycle(t);\n                t = worklist.fetch();\n                return t != null;\n            }\n        }\n    }\n\n\n    static bool op(IR code)(E e, S* state)\n        if (code == IR.LookbehindStart || code == IR.NeglookbehindStart)\n    {\n        with(e) with(state)\n        {\n            uint len = re.ir[t.pc].data;\n            uint ms = re.ir[t.pc + 1].raw, me = re.ir[t.pc + 2].raw;\n            uint end = t.pc + len + IRL!(IR.LookbehindEnd) + IRL!(IR.LookbehindStart);\n            bool positive = re.ir[t.pc].code == IR.LookbehindStart;\n            static if (Stream.isLoopback)\n                auto matcher = fwdMatcher(t.pc, end, me - ms, subCounters.get(t.pc, 0));\n            else\n                auto matcher = bwdMatcher(t.pc, end, me - ms, subCounters.get(t.pc, 0));\n            matcher.backrefed = backrefed.empty ? t.matches : backrefed;\n            //backMatch\n            auto mRes = matcher.matchOneShot(t.matches.ptr[ms .. me], IRL!(IR.LookbehindStart));\n            freelist = matcher.freelist;\n            subCounters[t.pc] = matcher.genCounter;\n            if ((mRes != 0 ) ^ positive)\n            {\n                return popState(e);\n            }\n            t.pc = end;\n            return true;\n        }\n    }\n\n    static bool op(IR code)(E e, S* state)\n        if (code == IR.LookaheadStart || code == IR.NeglookaheadStart)\n    {\n        with(e) with(state)\n        {\n            auto save = index;\n            uint len = re.ir[t.pc].data;\n            uint ms = re.ir[t.pc+1].raw, me = re.ir[t.pc+2].raw;\n            uint end = t.pc+len+IRL!(IR.LookaheadEnd)+IRL!(IR.LookaheadStart);\n            bool positive = re.ir[t.pc].code == IR.LookaheadStart;\n            static if (Stream.isLoopback)\n                auto matcher = bwdMatcher(t.pc, end, me - ms, subCounters.get(t.pc, 0));\n            else\n                auto matcher = fwdMatcher(t.pc, end, me - ms, subCounters.get(t.pc, 0));\n            matcher.backrefed = backrefed.empty ? t.matches : backrefed;\n            auto mRes = matcher.matchOneShot(t.matches.ptr[ms .. me], IRL!(IR.LookaheadStart));\n            freelist = matcher.freelist;\n            subCounters[t.pc] = matcher.genCounter;\n            s.reset(index);\n            next();\n            if ((mRes != 0) ^ positive)\n            {\n                return popState(e);\n            }\n            t.pc = end;\n            return true;\n        }\n    }\n\n    static bool op(IR code)(E e, S* state)\n        if (code == IR.LookaheadEnd || code == IR.NeglookaheadEnd ||\n            code == IR.LookbehindEnd || code == IR.NeglookbehindEnd)\n    {\n        with(e) with(state)\n        {\n                finish(t, matches.ptr[0 .. re.ngroup], re.ir[t.pc].data);\n                recycle(t);\n                //cut off low priority threads\n                recycle(clist);\n                recycle(worklist);\n                return false; // no more state\n        }\n    }\n\n    static bool op(IR code:IR.Nop)(E e, S* state)\n    {\n        with(state) t.pc += IRL!(IR.Nop);\n        return true;\n    }\n\n    static bool op(IR code:IR.OrChar)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            uint len = re.ir[t.pc].sequence;\n            uint end = t.pc + len;\n            static assert(IRL!(IR.OrChar) == 1);\n            for (; t.pc < end; t.pc++)\n                if (re.ir[t.pc].data == front)\n                    break;\n            if (t.pc != end)\n            {\n                t.pc = end;\n                nlist.insertBack(t);\n            }\n            else\n                recycle(t);\n            t = worklist.fetch();\n            return t != null;\n        }\n    }\n\n    static bool op(IR code:IR.Char)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            if (front == re.ir[t.pc].data)\n            {\n                t.pc += IRL!(IR.Char);\n                nlist.insertBack(t);\n            }\n            else\n                recycle(t);\n            t = worklist.fetch();\n            return t != null;\n        }\n    }\n\n    static bool op(IR code:IR.Any)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            t.pc += IRL!(IR.Any);\n            nlist.insertBack(t);\n            t = worklist.fetch();\n            return t != null;\n        }\n    }\n\n    static bool op(IR code:IR.CodepointSet)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            if (re.charsets[re.ir[t.pc].data].scanFor(front))\n            {\n                t.pc += IRL!(IR.CodepointSet);\n                nlist.insertBack(t);\n            }\n            else\n            {\n                recycle(t);\n            }\n            t = worklist.fetch();\n            return t != null;\n        }\n    }\n\n    static bool op(IR code:IR.Trie)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            if (re.matchers[re.ir[t.pc].data][front])\n            {\n                t.pc += IRL!(IR.Trie);\n                nlist.insertBack(t);\n            }\n            else\n            {\n                recycle(t);\n            }\n            t = worklist.fetch();\n            return t != null;\n        }\n    }\n\n}\n\ntemplate ThompsonOps(E,S, bool withInput:false)\n{\n@trusted:\n    // can't match these without input\n    static bool op(IR code)(E e, S* state)\n        if (code == IR.Char || code == IR.OrChar || code == IR.CodepointSet\n        || code == IR.Trie || code == IR.Char || code == IR.Any)\n    {\n        return state.popState(e);\n    }\n\n    // special case of zero-width backref\n    static bool op(IR code:IR.Backref)(E e, S* state)\n    {\n        with(e) with(state)\n        {\n            uint n = re.ir[t.pc].data;\n            Group!DataIndex* source = re.ir[t.pc].localRef ? t.matches.ptr : backrefed.ptr;\n            assert(source);\n            if (source[n].begin == source[n].end)//zero-width Backref!\n            {\n                t.pc += IRL!(IR.Backref);\n                return true;\n            }\n            else\n                return popState(e);\n        }\n    }\n\n    // forward all control flow to normal versions\n    static bool op(IR code)(E e, S* state)\n        if (code != IR.Char && code != IR.OrChar && code != IR.CodepointSet\n        && code != IR.Trie && code != IR.Char && code != IR.Any && code != IR.Backref)\n    {\n        return ThompsonOps!(E,S,true).op!code(e,state);\n    }\n}\n\n/+\n   Thomspon matcher does all matching in lockstep,\n   never looking at the same char twice\n+/\n@trusted class ThompsonMatcher(Char, StreamType = Input!Char): Matcher!Char\nif (is(Char : dchar))\n{\n    alias DataIndex = Stream.DataIndex;\n    alias Stream = StreamType;\n    alias OpFunc = bool function(ThompsonMatcher, State*);\n    alias BackMatcher = ThompsonMatcher!(Char, BackLooper!(Stream));\n    alias OpBackFunc = bool function(BackMatcher, BackMatcher.State*);\n    Thread!DataIndex* freelist;\n    ThreadList!DataIndex clist, nlist;\n    DataIndex[] merge;\n    Group!DataIndex[] backrefed;\n    const Regex!Char re;           //regex program\n    Stream s;\n    dchar front;\n    DataIndex index;\n    DataIndex genCounter;    //merge trace counter, goes up on every dchar\n    size_t[size_t] subCounters; //a table of gen counter per sub-engine: PC -> counter\n    OpFunc[] opCacheTrue;   // pointers to Op!(IR.xyz) for each bytecode\n    OpFunc[] opCacheFalse;  // ditto\n    OpBackFunc[] opCacheBackTrue;   // ditto\n    OpBackFunc[] opCacheBackFalse;  // ditto\n    size_t threadSize;\n    size_t _refCount;\n    int matched;\n    bool exhausted;\n\nfinal:\n    static struct State\n    {\n        Thread!DataIndex* t;\n        ThreadList!DataIndex worklist;\n        Group!DataIndex[] matches;\n\n        bool popState(E)(E e)\n        {\n            with(e)\n            {\n                recycle(t);\n                t = worklist.fetch();\n                return t != null;\n            }\n        }\n\n    }\n\n    static if (__traits(hasMember,Stream, \"search\"))\n    {\n        enum kicked = true;\n    }\n    else\n        enum kicked = false;\n\n    static size_t getThreadSize(const ref Regex!Char re)\n    {\n        return re.ngroup\n            ? (Thread!DataIndex).sizeof + (re.ngroup-1)*(Group!DataIndex).sizeof\n            : (Thread!DataIndex).sizeof - (Group!DataIndex).sizeof;\n    }\n\n    static size_t initialMemory(const ref Regex!Char re)\n    {\n        return getThreadSize(re)*re.threadCount + re.hotspotTableSize*size_t.sizeof\n            +4*OpFunc.sizeof*re.ir.length;\n    }\n\n    //true if it's start of input\n    @property bool atStart(){   return index == 0; }\n\n    //true if it's end of input\n    @property bool atEnd(){  return index == s.lastIndex && s.atEnd; }\n\n    override @property ref size_t refCount() @safe { return _refCount; }\n\n    override @property ref const(Regex!Char) pattern() @safe { return re; }\n\n    bool next()\n    {\n        if (!s.nextChar(front, index))\n        {\n            index =  s.lastIndex;\n            return false;\n        }\n        return true;\n    }\n\n    static if (kicked)\n    {\n        bool search()\n        {\n\n            if (!s.search(re.kickstart, front, index))\n            {\n                index = s.lastIndex;\n                return false;\n            }\n            return true;\n        }\n    }\n\n    void initExternalMemory(void[] memory)\n    {\n        threadSize = getThreadSize(re);\n        prepareFreeList(re.threadCount, memory);\n        if (re.hotspotTableSize)\n        {\n            merge = arrayInChunk!(DataIndex)(re.hotspotTableSize, memory);\n            merge[] = 0;\n        }\n        opCacheTrue = arrayInChunk!(OpFunc)(re.ir.length, memory);\n        opCacheFalse = arrayInChunk!(OpFunc)(re.ir.length, memory);\n        opCacheBackTrue = arrayInChunk!(OpBackFunc)(re.ir.length, memory);\n        opCacheBackFalse = arrayInChunk!(OpBackFunc)(re.ir.length, memory);\n\n        for (uint pc = 0; pc<re.ir.length; pc += re.ir[pc].length)\n        {\n        L_dispatch:\n            switch (re.ir[pc].code)\n            {\n                foreach (e; __traits(allMembers, IR))\n                {\n            mixin(`case IR.`~e~`:\n                    opCacheTrue[pc] = &Ops!(true).op!(IR.`~e~`);\n                    opCacheBackTrue[pc] = &BackOps!(true).op!(IR.`~e~`);\n                    opCacheFalse[pc] = &Ops!(false).op!(IR.`~e~`);\n                    opCacheBackFalse[pc] = &BackOps!(false).op!(IR.`~e~`);\n                break L_dispatch;\n                `);\n                }\n            default:\n                assert(0, \"Unrecognized instruction \"~re.ir[pc].mnemonic);\n            }\n        }\n    }\n\n    override Matcher!Char rearm(in Char[] data)\n    {\n        exhausted = false;\n        matched = 0;\n        s = Stream(data);\n        return this;\n    }\n\n    this()(ref const Regex!Char program, Stream stream, void[] memory)\n    {\n         // We are emplace'd to malloced memory w/o blitting T.init over it\\\n         // make sure we initialize all fields explicitly\n        _refCount = 1;\n        subCounters = null;\n        backrefed = null;\n        exhausted = false;\n        matched = 0;\n        re = program;\n        s = stream;\n        initExternalMemory(memory);\n        genCounter = 0;\n    }\n\n    this(ThompsonMatcher matcher, size_t lo, size_t hi, uint nGroup, Stream stream)\n    {\n        _refCount = 1;\n        subCounters = matcher.subCounters;\n        s = stream;\n        auto code = matcher.re.ir[lo .. hi];\n        re = matcher.re.withCode(code).withNGroup(nGroup);\n        threadSize = matcher.threadSize;\n        merge = matcher.merge;\n        freelist = matcher.freelist;\n        opCacheTrue = matcher.opCacheTrue[lo .. hi];\n        opCacheBackTrue = matcher.opCacheBackTrue[lo .. hi];\n        opCacheFalse = matcher.opCacheFalse[lo .. hi];\n        opCacheBackFalse = matcher.opCacheBackFalse[lo .. hi];\n        front = matcher.front;\n        index = matcher.index;\n    }\n\n    this(BackMatcher matcher, size_t lo, size_t hi, uint nGroup, Stream stream)\n    {\n        _refCount = 1;\n        subCounters = matcher.subCounters;\n        s = stream;\n        auto code = matcher.re.ir[lo .. hi];\n        re = matcher.re.withCode(code).withNGroup(nGroup);\n        threadSize = matcher.threadSize;\n        merge = matcher.merge;\n        freelist = matcher.freelist;\n        opCacheTrue = matcher.opCacheBackTrue[lo .. hi];\n        opCacheBackTrue = matcher.opCacheTrue[lo .. hi];\n        opCacheFalse = matcher.opCacheBackFalse[lo .. hi];\n        opCacheBackFalse = matcher.opCacheFalse[lo .. hi];\n        front = matcher.front;\n        index = matcher.index;\n    }\n\n    auto fwdMatcher()(size_t lo, size_t hi, uint nGroup, size_t counter)\n    {\n        auto m = new ThompsonMatcher!(Char, Stream)(this, lo, hi, nGroup, s);\n        m.genCounter = counter;\n        return m;\n    }\n\n    auto bwdMatcher()(size_t lo, size_t hi, uint nGroup, size_t counter)\n    {\n        alias BackLooper = typeof(s.loopBack(index));\n        auto m = new ThompsonMatcher!(Char, BackLooper)(this, lo, hi, nGroup, s.loopBack(index));\n        m.genCounter = counter;\n        m.next();\n        return m;\n    }\n\n    override void dupTo(Matcher!Char engine, void[] memory)\n    {\n        auto thompson = cast(ThompsonMatcher) engine;\n        thompson.s = s;\n        thompson.subCounters = null;\n        thompson.front = front;\n        thompson.index = index;\n        thompson.matched = matched;\n        thompson.exhausted = exhausted;\n        thompson.initExternalMemory(memory);\n    }\n\n    override int match(Group!DataIndex[] matches)\n    {\n        debug(std_regex_matcher)\n            writeln(\"------------------------------------------\");\n        if (exhausted)\n        {\n            return false;\n        }\n        if (re.flags & RegexInfo.oneShot)\n        {\n            next();\n            exhausted = true;\n            return matchOneShot(matches);\n        }\n        static if (kicked)\n            if (!re.kickstart.empty)\n                return matchImpl!(true)(matches);\n        return matchImpl!(false)(matches);\n    }\n\n    //match the input and fill matches\n    int matchImpl(bool withSearch)(Group!DataIndex[] matches)\n    {\n        if (!matched && clist.empty)\n        {\n           static if (withSearch)\n                search();\n           else\n                next();\n        }\n        else//char in question is  fetched in prev call to match\n        {\n            matched = 0;\n        }\n        State state;\n        state.matches = matches;\n\n        if (!atEnd)//if no char\n            for (;;)\n            {\n                genCounter++;\n                debug(std_regex_matcher)\n                {\n                    writefln(\"Threaded matching threads at  %s\", s[index .. s.lastIndex]);\n                    foreach (t; clist[])\n                    {\n                        assert(t);\n                        writef(\"pc=%s \",t.pc);\n                        write(t.matches);\n                        writeln();\n                    }\n                }\n                for (state.t = clist.fetch(); state.t; state.t = clist.fetch())\n                {\n                    eval!true(&state);\n                }\n                //if we already have match no need to push the engine\n                if (!matched)\n                {\n                    state.t = createStart(index);\n                    eval!true(&state);//new thread staring at this position\n                }\n                else if (nlist.empty)\n                {\n                    debug(std_regex_matcher) writeln(\"Stopped  matching before consuming full input\");\n                    break;//not a partial match for sure\n                }\n                clist = nlist;\n                nlist = (ThreadList!DataIndex).init;\n                if (clist.tip is null)\n                {\n                    static if (withSearch)\n                    {\n                        if (!search())\n                            break;\n                    }\n                    else\n                    {\n                        if (!next())\n                            break;\n                    }\n                }\n                else if (!next())\n                {\n                    if (!atEnd) return false;\n                    exhausted = true;\n                    break;\n                }\n            }\n\n        genCounter++; //increment also on each end\n        debug(std_regex_matcher) writefln(\"Threaded matching threads at end\");\n        //try out all zero-width posibilities\n        for (state.t = clist.fetch(); state.t; state.t = clist.fetch())\n        {\n            eval!false(&state);\n        }\n        if (!matched)\n        {\n            state.t = createStart(index);\n            eval!false(&state);//new thread starting at end of input\n        }\n        if (matched)\n        {//in case NFA found match along the way\n         //and last possible longer alternative ultimately failed\n            s.reset(matches[0].end);//reset to last successful match\n            next();//and reload front character\n            //--- here the exact state of stream was restored ---\n            exhausted = atEnd || !(re.flags & RegexOption.global);\n            //+ empty match advances the input\n            if (!exhausted && matches[0].begin == matches[0].end)\n                next();\n        }\n        return matched;\n    }\n\n    /+\n        handle succesful threads\n    +/\n    void finish(const(Thread!DataIndex)* t, Group!DataIndex[] matches, int code)\n    {\n        matches.ptr[0 .. re.ngroup] = t.matches.ptr[0 .. re.ngroup];\n        debug(std_regex_matcher)\n        {\n            writef(\"FOUND pc=%s prog_len=%s\",\n                    t.pc, re.ir.length);\n            if (!matches.empty)\n                writefln(\": %s..%s\", matches[0].begin, matches[0].end);\n            foreach (v; matches)\n                writefln(\"%d .. %d\", v.begin, v.end);\n        }\n        matched = code;\n    }\n\n    alias Ops(bool withInput) =  ThompsonOps!(ThompsonMatcher, State, withInput);\n    alias BackOps(bool withInput) =  ThompsonOps!(BackMatcher, BackMatcher.State, withInput);\n\n    /+\n        match thread against codepoint, cutting trough all 0-width instructions\n        and taking care of control flow, then add it to nlist\n    +/\n    void eval(bool withInput)(State* state)\n    {\n        debug(std_regex_matcher) writeln(\"---- Evaluating thread\");\n        static if (withInput)\n            while (opCacheTrue.ptr[state.t.pc](this, state)){}\n        else\n            while (opCacheFalse.ptr[state.t.pc](this, state)){}\n    }\n    enum uint RestartPc = uint.max;\n    //match the input, evaluating IR without searching\n    int matchOneShot(Group!DataIndex[] matches, uint startPc = 0)\n    {\n        debug(std_regex_matcher)\n        {\n            writefln(\"---------------single shot match ----------------- \");\n        }\n        alias evalFn = eval;\n        assert(clist == (ThreadList!DataIndex).init || startPc == RestartPc); // incorrect after a partial match\n        assert(nlist == (ThreadList!DataIndex).init || startPc == RestartPc);\n        State state;\n        state.matches = matches;\n        if (!atEnd)//if no char\n        {\n            debug(std_regex_matcher)\n            {\n                writefln(\"-- Threaded matching threads at  %s\",  s[index .. s.lastIndex]);\n            }\n            if (startPc != RestartPc)\n            {\n                state.t = createStart(index, startPc);\n                genCounter++;\n                evalFn!true(&state);\n            }\n            for (;;)\n            {\n                debug(std_regex_matcher) writeln(\"\\n-- Started iteration of main cycle\");\n                genCounter++;\n                debug(std_regex_matcher)\n                {\n                    foreach (t; clist[])\n                    {\n                        assert(t);\n                    }\n                }\n                for (state.t = clist.fetch(); state.t; state.t = clist.fetch())\n                {\n                    evalFn!true(&state);\n                }\n                if (nlist.empty)\n                {\n                    debug(std_regex_matcher) writeln(\"Stopped  matching before consuming full input\");\n                    break;//not a partial match for sure\n                }\n                clist = nlist;\n                nlist = (ThreadList!DataIndex).init;\n                if (!next())\n                    break;\n                debug(std_regex_matcher) writeln(\"-- Ended iteration of main cycle\\n\");\n            }\n        }\n        genCounter++; //increment also on each end\n        debug(std_regex_matcher) writefln(\"-- Matching threads at end\");\n        //try out all zero-width posibilities\n        for (state.t = clist.fetch(); state.t; state.t = clist.fetch())\n        {\n            evalFn!false(&state);\n        }\n        if (!matched)\n        {\n            state.t = createStart(index, startPc);\n            evalFn!false(&state);\n        }\n        return matched;\n    }\n\n    //get a dirty recycled Thread\n    Thread!DataIndex* allocate()\n    {\n        assert(freelist, \"not enough preallocated memory\");\n        Thread!DataIndex* t = freelist;\n        freelist = freelist.next;\n        return t;\n    }\n\n    //link memory into a free list of Threads\n    void prepareFreeList(size_t size, ref void[] memory)\n    {\n        void[] mem = memory[0 .. threadSize*size];\n        memory = memory[threadSize * size .. $];\n        freelist = cast(Thread!DataIndex*)&mem[0];\n        size_t i;\n        for (i = threadSize; i < threadSize*size; i += threadSize)\n            (cast(Thread!DataIndex*)&mem[i-threadSize]).next = cast(Thread!DataIndex*)&mem[i];\n        (cast(Thread!DataIndex*)&mem[i-threadSize]).next = null;\n    }\n\n    //dispose a thread\n    void recycle(Thread!DataIndex* t)\n    {\n        t.next = freelist;\n        freelist = t;\n    }\n\n    //dispose list of threads\n    void recycle(ref ThreadList!DataIndex list)\n    {\n        if (list.tip)\n        {\n            // just put this head-tail list in front of freelist\n            list.toe.next = freelist;\n            freelist = list.tip;\n            list = list.init;\n        }\n    }\n\n    //creates a copy of master thread with given pc\n    Thread!DataIndex* fork(Thread!DataIndex* master, uint pc, uint counter)\n    {\n        auto t = allocate();\n        t.matches.ptr[0 .. re.ngroup] = master.matches.ptr[0 .. re.ngroup];\n        t.pc = pc;\n        t.counter = counter;\n        t.uopCounter = 0;\n        return t;\n    }\n\n    //creates a start thread\n    Thread!DataIndex* createStart(DataIndex index, uint pc = 0)\n    {\n        auto t = allocate();\n        t.matches.ptr[0 .. re.ngroup] = (Group!DataIndex).init;\n        t.matches[0].begin = index;\n        t.pc = pc;\n        t.counter = 0;\n        t.uopCounter = 0;\n        return t;\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/regex/package.d",
    "content": "/++\n  $(LINK2 https://en.wikipedia.org/wiki/Regular_expression, Regular expressions)\n  are a commonly used method of pattern matching\n  on strings, with $(I regex) being a catchy word for a pattern in this domain\n  specific language. Typical problems usually solved by regular expressions\n  include validation of user input and the ubiquitous find $(AMP) replace\n  in text processing utilities.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Matching) $(TD\n        $(LREF bmatch)\n        $(LREF match)\n        $(LREF matchAll)\n        $(LREF matchFirst)\n))\n$(TR $(TD Building) $(TD\n        $(LREF ctRegex)\n        $(LREF escaper)\n        $(LREF regex)\n))\n$(TR $(TD Replace) $(TD\n        $(LREF replace)\n        $(LREF replaceAll)\n        $(LREF replaceAllInto)\n        $(LREF replaceFirst)\n        $(LREF replaceFirstInto)\n))\n$(TR $(TD Split) $(TD\n        $(LREF split)\n        $(LREF splitter)\n))\n$(TR $(TD Objects) $(TD\n        $(LREF Captures)\n        $(LREF Regex)\n        $(LREF RegexException)\n        $(LREF RegexMatch)\n        $(LREF Splitter)\n        $(LREF StaticRegex)\n))\n)\n\n  $(SECTION Synopsis)\n  ---\n  import std.regex;\n  import std.stdio;\n  void main()\n  {\n      // Print out all possible dd/mm/yy(yy) dates found in user input.\n      auto r = regex(r\"\\b[0-9][0-9]?/[0-9][0-9]?/[0-9][0-9](?:[0-9][0-9])?\\b\");\n      foreach (line; stdin.byLine)\n      {\n        // matchAll() returns a range that can be iterated\n        // to get all subsequent matches.\n        foreach (c; matchAll(line, r))\n            writeln(c.hit);\n      }\n  }\n  ...\n\n  // Create a static regex at compile-time, which contains fast native code.\n  auto ctr = ctRegex!(`^.*/([^/]+)/?$`);\n\n  // It works just like a normal regex:\n  auto c2 = matchFirst(\"foo/bar\", ctr);   // First match found here, if any\n  assert(!c2.empty);   // Be sure to check if there is a match before examining contents!\n  assert(c2[1] == \"bar\");   // Captures is a range of submatches: 0 = full match.\n\n  ...\n  // multi-pattern regex\n  auto multi = regex([`\\d+,\\d+`,`(a-z]+):(\\d+)`]);\n  auto m = \"abc:43 12,34\".matchAll(multi);\n  assert(m.front.whichPattern == 2);\n  assert(m.front[1] == \"abc\");\n  assert(m.front[2] == \"43\");\n  m.popFront();\n  assert(m.front.whichPattern == 1);\n  assert(m.front[1] == \"12\");\n  ...\n\n  // The result of the `matchAll/matchFirst` is directly testable with if/assert/while.\n  // e.g. test if a string consists of letters:\n  assert(matchFirst(\"Letter\", `^\\p{L}+$`));\n  ---\n\n  $(SECTION Syntax and general information)\n  The general usage guideline is to keep regex complexity on the side of simplicity,\n  as its capabilities reside in purely character-level manipulation.\n  As such it's ill-suited for tasks involving higher level invariants\n  like matching an integer number $(U bounded) in an [a,b] interval.\n  Checks of this sort of are better addressed by additional post-processing.\n\n  The basic syntax shouldn't surprise experienced users of regular expressions.\n  For an introduction to `std.regex` see a\n  $(HTTP dlang.org/regular-expression.html, short tour) of the module API\n  and its abilities.\n\n  There are other web resources on regular expressions to help newcomers,\n  and a good $(HTTP www.regular-expressions.info, reference with tutorial)\n  can easily be found.\n\n  This library uses a remarkably common ECMAScript syntax flavor\n  with the following extensions:\n  $(UL\n    $(LI Named subexpressions, with Python syntax. )\n    $(LI Unicode properties such as Scripts, Blocks and common binary properties e.g Alphabetic, White_Space, Hex_Digit etc.)\n    $(LI Arbitrary length and complexity lookbehind, including lookahead in lookbehind and vise-versa.)\n  )\n\n  $(REG_START Pattern syntax )\n  $(I std.regex operates on codepoint level,\n    'character' in this table denotes a single Unicode codepoint.)\n  $(REG_TABLE\n    $(REG_TITLE Pattern element, Semantics )\n    $(REG_TITLE Atoms, Match single characters )\n    $(REG_ROW any character except [{|*+?()^$, Matches the character itself. )\n    $(REG_ROW ., In single line mode matches any character.\n      Otherwise it matches any character except '\\n' and '\\r'. )\n    $(REG_ROW [class], Matches a single character\n      that belongs to this character class. )\n    $(REG_ROW [^class], Matches a single character that\n      does $(U not) belong to this character class.)\n    $(REG_ROW \\cC, Matches the control character corresponding to letter C)\n    $(REG_ROW \\xXX, Matches a character with hexadecimal value of XX. )\n    $(REG_ROW \\uXXXX, Matches a character  with hexadecimal value of XXXX. )\n    $(REG_ROW \\U00YYYYYY, Matches a character with hexadecimal value of YYYYYY. )\n    $(REG_ROW \\f, Matches a formfeed character. )\n    $(REG_ROW \\n, Matches a linefeed character. )\n    $(REG_ROW \\r, Matches a carriage return character. )\n    $(REG_ROW \\t, Matches a tab character. )\n    $(REG_ROW \\v, Matches a vertical tab character. )\n    $(REG_ROW \\d, Matches any Unicode digit. )\n    $(REG_ROW \\D, Matches any character except Unicode digits. )\n    $(REG_ROW \\w, Matches any word character (note: this includes numbers).)\n    $(REG_ROW \\W, Matches any non-word character.)\n    $(REG_ROW \\s, Matches whitespace, same as \\p{White_Space}.)\n    $(REG_ROW \\S, Matches any character except those recognized as $(I \\s ). )\n    $(REG_ROW \\\\, Matches \\ character. )\n    $(REG_ROW \\c where c is one of [|*+?(), Matches the character c itself. )\n    $(REG_ROW \\p{PropertyName}, Matches a character that belongs\n        to the Unicode PropertyName set.\n      Single letter abbreviations can be used without surrounding {,}. )\n    $(REG_ROW  \\P{PropertyName}, Matches a character that does not belong\n        to the Unicode PropertyName set.\n      Single letter abbreviations can be used without surrounding {,}. )\n    $(REG_ROW \\p{InBasicLatin}, Matches any character that is part of\n          the BasicLatin Unicode $(U block).)\n    $(REG_ROW \\P{InBasicLatin}, Matches any character except ones in\n          the BasicLatin Unicode $(U block).)\n    $(REG_ROW \\p{Cyrillic}, Matches any character that is part of\n        Cyrillic $(U script).)\n    $(REG_ROW \\P{Cyrillic}, Matches any character except ones in\n        Cyrillic $(U script).)\n    $(REG_TITLE Quantifiers, Specify repetition of other elements)\n    $(REG_ROW *, Matches previous character/subexpression 0 or more times.\n      Greedy version - tries as many times as possible.)\n    $(REG_ROW *?, Matches previous character/subexpression 0 or more times.\n      Lazy version  - stops as early as possible.)\n    $(REG_ROW +, Matches previous character/subexpression 1 or more times.\n      Greedy version - tries as many times as possible.)\n    $(REG_ROW +?, Matches previous character/subexpression 1 or more times.\n      Lazy version  - stops as early as possible.)\n    $(REG_ROW {n}, Matches previous character/subexpression exactly n times. )\n    $(REG_ROW {n$(COMMA)}, Matches previous character/subexpression n times or more.\n      Greedy version - tries as many times as possible. )\n    $(REG_ROW {n$(COMMA)}?, Matches previous character/subexpression n times or more.\n      Lazy version - stops as early as possible.)\n    $(REG_ROW {n$(COMMA)m}, Matches previous character/subexpression n to m times.\n      Greedy version - tries as many times as possible, but no more than m times. )\n    $(REG_ROW {n$(COMMA)m}?, Matches previous character/subexpression n to m times.\n      Lazy version - stops as early as possible, but no less then n times.)\n    $(REG_TITLE Other, Subexpressions $(AMP) alternations )\n    $(REG_ROW (regex),  Matches subexpression regex,\n      saving matched portion of text for later retrieval. )\n    $(REG_ROW (?#comment), An inline comment that is ignored while matching.)\n    $(REG_ROW (?:regex), Matches subexpression regex,\n      $(U not) saving matched portion of text. Useful to speed up matching. )\n    $(REG_ROW A|B, Matches subexpression A, or failing that, matches B. )\n    $(REG_ROW (?P$(LT)name$(GT)regex), Matches named subexpression\n        regex labeling it with name 'name'.\n        When referring to a matched portion of text,\n        names work like aliases in addition to direct numbers.\n     )\n    $(REG_TITLE Assertions, Match position rather than character )\n    $(REG_ROW ^, Matches at the begining of input or line (in multiline mode).)\n    $(REG_ROW $, Matches at the end of input or line (in multiline mode). )\n    $(REG_ROW \\b, Matches at word boundary. )\n    $(REG_ROW \\B, Matches when $(U not) at word boundary. )\n    $(REG_ROW (?=regex), Zero-width lookahead assertion.\n        Matches at a point where the subexpression\n        regex could be matched starting from the current position.\n      )\n    $(REG_ROW (?!regex), Zero-width negative lookahead assertion.\n        Matches at a point where the subexpression\n        regex could $(U not) be matched starting from the current position.\n      )\n    $(REG_ROW (?<=regex), Zero-width lookbehind assertion. Matches at a point\n        where the subexpression regex could be matched ending\n        at the current position (matching goes backwards).\n      )\n    $(REG_ROW  (?<!regex), Zero-width negative lookbehind assertion.\n      Matches at a point where the subexpression regex could $(U not)\n      be matched ending at the current position (matching goes backwards).\n     )\n  )\n\n  $(REG_START Character classes )\n  $(REG_TABLE\n    $(REG_TITLE Pattern element, Semantics )\n    $(REG_ROW Any atom, Has the same meaning as outside of a character class.)\n    $(REG_ROW a-z, Includes characters a, b, c, ..., z. )\n    $(REG_ROW [a||b]$(COMMA) [a--b]$(COMMA) [a~~b]$(COMMA) [a$(AMP)$(AMP)b],\n     Where a, b are arbitrary classes, means union, set difference,\n     symmetric set difference, and intersection respectively.\n     $(I Any sequence of character class elements implicitly forms a union.) )\n  )\n\n  $(REG_START Regex flags )\n  $(REG_TABLE\n    $(REG_TITLE Flag, Semantics )\n    $(REG_ROW g, Global regex, repeat over the whole input. )\n    $(REG_ROW i, Case insensitive matching. )\n    $(REG_ROW m, Multi-line mode, match ^, $ on start and end line separators\n       as well as start and end of input.)\n    $(REG_ROW s, Single-line mode, makes . match '\\n' and '\\r' as well. )\n    $(REG_ROW x, Free-form syntax, ignores whitespace in pattern,\n      useful for formatting complex regular expressions. )\n  )\n\n  $(SECTION Unicode support)\n\n  This library provides full Level 1 support* according to\n    $(HTTP unicode.org/reports/tr18/, UTS 18). Specifically:\n  $(UL\n    $(LI 1.1 Hex notation via any of \\uxxxx, \\U00YYYYYY, \\xZZ.)\n    $(LI 1.2 Unicode properties.)\n    $(LI 1.3 Character classes with set operations.)\n    $(LI 1.4 Word boundaries use the full set of \"word\" characters.)\n    $(LI 1.5 Using simple casefolding to match case\n        insensitively across the full range of codepoints.)\n    $(LI 1.6 Respecting line breaks as any of\n        \\u000A | \\u000B | \\u000C | \\u000D | \\u0085 | \\u2028 | \\u2029 | \\u000D\\u000A.)\n    $(LI 1.7 Operating on codepoint level.)\n  )\n  *With exception of point 1.1.1, as of yet, normalization of input\n    is expected to be enforced by user.\n\n    $(SECTION Replace format string)\n\n    A set of functions in this module that do the substitution rely\n    on a simple format to guide the process. In particular the table below\n    applies to the `format` argument of\n    $(LREF replaceFirst) and $(LREF replaceAll).\n\n    The format string can reference parts of match using the following notation.\n    $(REG_TABLE\n        $(REG_TITLE Format specifier, Replaced by )\n        $(REG_ROW $(DOLLAR)$(AMP), the whole match. )\n        $(REG_ROW $(DOLLAR)$(BACKTICK), part of input $(I preceding) the match. )\n        $(REG_ROW $', part of input $(I following) the match. )\n        $(REG_ROW $$, '$' character. )\n        $(REG_ROW \\c $(COMMA) where c is any character, the character c itself. )\n        $(REG_ROW \\\\, '\\' character. )\n        $(REG_ROW $(DOLLAR)1 .. $(DOLLAR)99, submatch number 1 to 99 respectively. )\n    )\n\n  $(SECTION Slicing and zero memory allocations orientation)\n\n  All matches returned by pattern matching functionality in this library\n    are slices of the original input. The notable exception is the `replace`\n    family of functions  that generate a new string from the input.\n\n    In cases where producing the replacement is the ultimate goal\n    $(LREF replaceFirstInto) and $(LREF replaceAllInto) could come in handy\n    as functions that  avoid allocations even for replacement.\n\n    Copyright: Copyright Dmitry Olshansky, 2011-\n\n  License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\n  Authors: Dmitry Olshansky,\n\n    API and utility constructs are modeled after the original `std.regex`\n  by Walter Bright and Andrei Alexandrescu.\n\n  Source: $(PHOBOSSRC std/regex/package.d)\n\nMacros:\n    REG_ROW = $(TR $(TD $(I $1 )) $(TD $+) )\n    REG_TITLE = $(TR $(TD $(B $1)) $(TD $(B $2)) )\n    REG_TABLE = <table border=\"1\" cellspacing=\"0\" cellpadding=\"5\" > $0 </table>\n    REG_START = <h3><div align=\"center\"> $0 </div></h3>\n    SECTION = <h3><a id=\"$1\" href=\"#$1\" class=\"anchor\">$0</a></h3>\n    S_LINK = <a href=\"#$1\">$+</a>\n +/\nmodule std.regex;\n\nimport std.range.primitives, std.traits;\nimport std.regex.internal.ir;\nimport std.typecons; // : Flag, Yes, No;\n\n/++\n    `Regex` object holds regular expression pattern in compiled form.\n\n    Instances of this object are constructed via calls to `regex`.\n    This is an intended form for caching and storage of frequently\n    used regular expressions.\n\n    Example:\n\n    Test if this object doesn't contain any compiled pattern.\n    ---\n    Regex!char r;\n    assert(r.empty);\n    r = regex(\"\"); // Note: \"\" is a valid regex pattern.\n    assert(!r.empty);\n    ---\n\n    Getting a range of all the named captures in the regex.\n    ----\n    import std.range;\n    import std.algorithm;\n\n    auto re = regex(`(?P<name>\\w+) = (?P<var>\\d+)`);\n    auto nc = re.namedCaptures;\n    static assert(isRandomAccessRange!(typeof(nc)));\n    assert(!nc.empty);\n    assert(nc.length == 2);\n    assert(nc.equal([\"name\", \"var\"]));\n    assert(nc[0] == \"name\");\n    assert(nc[1..$].equal([\"var\"]));\n    ----\n+/\npublic alias Regex(Char) = std.regex.internal.ir.Regex!(Char);\n\n/++\n    A `StaticRegex` is `Regex` object that contains D code specially\n    generated at compile-time to speed up matching.\n\n    No longer used, kept as alias to Regex for backwards compatibility.\n+/\npublic alias StaticRegex = Regex;\n\n/++\n    Compile regular expression pattern for the later execution.\n    Returns: `Regex` object that works on inputs having\n    the same character width as `pattern`.\n\n    Params:\n    pattern = A single regular expression to match.\n    patterns = An array of regular expression strings.\n        The resulting `Regex` object will match any expression;\n        use $(LREF whichPattern) to know which.\n    flags = The _attributes (g, i, m, s and x accepted)\n\n    Throws: `RegexException` if there were any errors during compilation.\n+/\n@trusted public auto regex(S)(S[] patterns, const(char)[] flags=\"\")\nif (isSomeString!(S))\n{\n    import std.array : appender;\n    import std.functional : memoize;\n    enum cacheSize = 8; //TODO: invent nice interface to control regex caching\n    S pat;\n    if (patterns.length > 1)\n    {\n        auto app = appender!S();\n        foreach (i, p; patterns)\n        {\n            if (i != 0)\n                app.put(\"|\");\n            app.put(\"(?:\");\n            app.put(patterns[i]);\n            // terminator for the pattern\n            // to detect if the pattern unexpectedly ends\n            app.put(\"\\\\\");\n            app.put(cast(dchar)(privateUseStart+i));\n            app.put(\")\");\n            // another one to return correct whichPattern\n            // for all of potential alternatives in the patterns[i]\n            app.put(\"\\\\\");\n            app.put(cast(dchar)(privateUseStart+i));\n        }\n        pat = app.data;\n    }\n    else\n        pat = patterns[0];\n\n    if (__ctfe)\n        return regexImpl(pat, flags);\n    return memoize!(regexImpl!S, cacheSize)(pat, flags);\n}\n\n///ditto\n@trusted public auto regex(S)(S pattern, const(char)[] flags=\"\")\nif (isSomeString!(S))\n{\n    return regex([pattern], flags);\n}\n\n///\n@system unittest\n{\n    // multi-pattern regex example\n    auto multi = regex([`([a-z]+):(\\d+)`, `(\\d+),\\d+`]); // multi regex\n    auto m = \"abc:43 12,34\".matchAll(multi);\n    assert(m.front.whichPattern == 1);\n    assert(m.front[1] == \"abc\");\n    assert(m.front[2] == \"43\");\n    m.popFront();\n    assert(m.front.whichPattern == 2);\n    assert(m.front[1] == \"12\");\n}\n\npublic auto regexImpl(S)(S pattern, const(char)[] flags=\"\")\nif (isSomeString!(S))\n{\n    import std.regex.internal.parser : Parser, CodeGen;\n    auto parser = Parser!(Unqual!(typeof(pattern)), CodeGen)(pattern, flags);\n    auto r = parser.program;\n    return r;\n}\n\n\ntemplate ctRegexImpl(alias pattern, string flags=[])\n{\n    import std.regex.internal.backtracking, std.regex.internal.parser;\n    static immutable r = cast(immutable) regex(pattern, flags);\n    alias Char = BasicElementOf!(typeof(pattern));\n    enum source = ctGenRegExCode(r);\n    @trusted bool func(BacktrackingMatcher!Char matcher)\n    {\n        debug(std_regex_ctr) pragma(msg, source);\n        cast(void) matcher;\n        mixin(source);\n    }\n    static immutable staticRe =\n        cast(immutable) r.withFactory(new CtfeFactory!(BacktrackingMatcher, Char, func));\n    struct Wrapper\n    {\n        // allow code that expects mutable Regex to still work\n        // we stay \"logically const\"\n        @property @trusted ref getRe() const { return *cast(Regex!Char*)&staticRe; }\n        alias getRe this;\n    }\n    enum wrapper = Wrapper();\n}\n\n@safe unittest\n{\n    // test compat for logical const workaround\n    static void test(StaticRegex!char)\n    {\n    }\n    enum re = ctRegex!``;\n    test(re);\n}\n\n/++\n    Compile regular expression using CTFE\n    and generate optimized native machine code for matching it.\n\n    Returns: StaticRegex object for faster matching.\n\n    Params:\n    pattern = Regular expression\n    flags = The _attributes (g, i, m, s and x accepted)\n+/\npublic enum ctRegex(alias pattern, alias flags=[]) = ctRegexImpl!(pattern, flags).wrapper;\n\nenum isRegexFor(RegEx, R) = is(Unqual!RegEx == Regex!(BasicElementOf!R)) || is(RegEx : const(Regex!(BasicElementOf!R)))\n     || is(Unqual!RegEx == StaticRegex!(BasicElementOf!R));\n\n\n/++\n    `Captures` object contains submatches captured during a call\n    to `match` or iteration over `RegexMatch` range.\n\n    First element of range is the whole match.\n+/\n@trusted public struct Captures(R)\nif (isSomeString!R)\n{//@trusted because of union inside\n    alias DataIndex = size_t;\n    alias String = R;\n    alias Store = SmallFixedArray!(Group!DataIndex, 3);\nprivate:\n    import std.conv : text;\n    Store matches;\n    const(NamedGroup)[] _names;\n    R _input;\n    int _nMatch;\n    uint _f, _b;\n\n    this(R input, uint n, const(NamedGroup)[] named)\n    {\n        _input = input;\n        _names = named;\n        matches = Store(n);\n        _b = n;\n        _f = 0;\n    }\n\n    this(ref RegexMatch!R rmatch)\n    {\n        _input = rmatch._input;\n        _names = rmatch._engine.pattern.dict;\n        immutable n = rmatch._engine.pattern.ngroup;\n        matches = Store(n);\n        _b = n;\n        _f = 0;\n    }\n\npublic:\n    ///Slice of input prior to the match.\n    @property R pre()\n    {\n        return _nMatch == 0 ? _input[] : _input[0 .. matches[0].begin];\n    }\n\n    ///Slice of input immediately after the match.\n    @property R post()\n    {\n        return _nMatch == 0 ? _input[] : _input[matches[0].end .. $];\n    }\n\n    ///Slice of matched portion of input.\n    @property R hit()\n    {\n        assert(_nMatch, \"attempted to get hit of an empty match\");\n        return _input[matches[0].begin .. matches[0].end];\n    }\n\n    ///Range interface.\n    @property R front()\n    {\n        assert(_nMatch, \"attempted to get front of an empty match\");\n        return _input[matches[_f].begin .. matches[_f].end];\n    }\n\n    ///ditto\n    @property R back()\n    {\n        assert(_nMatch, \"attempted to get back of an empty match\");\n        return _input[matches[_b - 1].begin .. matches[_b - 1].end];\n    }\n\n    ///ditto\n    void popFront()\n    {\n        assert(!empty);\n        ++_f;\n    }\n\n    ///ditto\n    void popBack()\n    {\n        assert(!empty);\n        --_b;\n    }\n\n    ///ditto\n    @property bool empty() const { return _nMatch == 0 || _f >= _b; }\n\n    ///ditto\n    inout(R) opIndex()(size_t i) inout\n    {\n        assert(_f + i < _b,text(\"requested submatch number \", i,\" is out of range\"));\n        assert(matches[_f + i].begin <= matches[_f + i].end,\n            text(\"wrong match: \", matches[_f + i].begin, \"..\", matches[_f + i].end));\n        return _input[matches[_f + i].begin .. matches[_f + i].end];\n    }\n\n    /++\n        Explicit cast to bool.\n        Useful as a shorthand for !(x.empty) in if and assert statements.\n\n        ---\n        import std.regex;\n\n        assert(!matchFirst(\"nothing\", \"something\"));\n        ---\n    +/\n\n    @safe bool opCast(T:bool)() const nothrow { return _nMatch != 0; }\n\n    /++\n        Number of pattern matched counting, where 1 - the first pattern.\n        Returns 0 on no match.\n    +/\n\n    @safe @property int whichPattern() const nothrow { return _nMatch; }\n\n    ///\n    @system unittest\n    {\n        import std.regex;\n        assert(matchFirst(\"abc\", \"[0-9]+\", \"[a-z]+\").whichPattern == 2);\n    }\n\n    /++\n        Lookup named submatch.\n\n        ---\n        import std.regex;\n        import std.range;\n\n        auto c = matchFirst(\"a = 42;\", regex(`(?P<var>\\w+)\\s*=\\s*(?P<value>\\d+);`));\n        assert(c[\"var\"] == \"a\");\n        assert(c[\"value\"] == \"42\");\n        popFrontN(c, 2);\n        //named groups are unaffected by range primitives\n        assert(c[\"var\"] ==\"a\");\n        assert(c.front == \"42\");\n        ----\n    +/\n    R opIndex(String)(String i) /*const*/ //@@@BUG@@@\n        if (isSomeString!String)\n    {\n        size_t index = lookupNamedGroup(_names, i);\n        return _input[matches[index].begin .. matches[index].end];\n    }\n\n    ///Number of matches in this object.\n    @property size_t length() const { return _nMatch == 0 ? 0 : _b - _f;  }\n\n    ///A hook for compatibility with original std.regex.\n    @property ref captures(){ return this; }\n}\n\n///\n@system unittest\n{\n    import std.range.primitives : popFrontN;\n\n    auto c = matchFirst(\"@abc#\", regex(`(\\w)(\\w)(\\w)`));\n    assert(c.pre == \"@\"); // Part of input preceding match\n    assert(c.post == \"#\"); // Immediately after match\n    assert(c.hit == c[0] && c.hit == \"abc\"); // The whole match\n    assert(c[2] == \"b\");\n    assert(c.front == \"abc\");\n    c.popFront();\n    assert(c.front == \"a\");\n    assert(c.back == \"c\");\n    c.popBack();\n    assert(c.back == \"b\");\n    popFrontN(c, 2);\n    assert(c.empty);\n\n    assert(!matchFirst(\"nothing\", \"something\"));\n}\n\n@system unittest\n{\n    Captures!string c;\n    string s = \"abc\";\n    assert(cast(bool)(c = matchFirst(s, regex(\"d\")))\n        || cast(bool)(c = matchFirst(s, regex(\"a\"))));\n}\n\n/++\n    A regex engine state, as returned by `match` family of functions.\n\n    Effectively it's a forward range of Captures!R, produced\n    by lazily searching for matches in a given input.\n+/\n@trusted public struct RegexMatch(R)\nif (isSomeString!R)\n{\nprivate:\n    alias Char = BasicElementOf!R;\n    Matcher!Char _engine;\n    Rebindable!(const MatcherFactory!Char) _factory;\n    R _input;\n    Captures!R _captures;\n\n    this(RegEx)(R input, RegEx prog)\n    {\n        import std.exception : enforce;\n        _input = input;\n        if (prog.factory is null) _factory = defaultFactory!Char(prog);\n        else _factory = prog.factory;\n        _engine = _factory.create(prog, input);\n        assert(_engine.refCount == 1);\n        _captures = Captures!R(this);\n        _captures.matches.mutate((slice) { _captures._nMatch = _engine.match(slice); });\n    }\n\npublic:\n    this(this)\n    {\n        if (_engine) _factory.incRef(_engine);\n    }\n\n    ~this()\n    {\n        if (_engine) _factory.decRef(_engine);\n    }\n\n    ///Shorthands for front.pre, front.post, front.hit.\n    @property R pre()\n    {\n        return _captures.pre;\n    }\n\n    ///ditto\n    @property R post()\n    {\n        return _captures.post;\n    }\n\n    ///ditto\n    @property R hit()\n    {\n        return _captures.hit;\n    }\n\n    /++\n        Functionality for processing subsequent matches of global regexes via range interface:\n        ---\n        import std.regex;\n        auto m = matchAll(\"Hello, world!\", regex(`\\w+`));\n        assert(m.front.hit == \"Hello\");\n        m.popFront();\n        assert(m.front.hit == \"world\");\n        m.popFront();\n        assert(m.empty);\n        ---\n    +/\n    @property inout(Captures!R) front() inout\n    {\n        return _captures;\n    }\n\n    ///ditto\n    void popFront()\n    {\n        import std.exception : enforce;\n        // CoW - if refCount is not 1, we are aliased by somebody else\n        if (_engine.refCount != 1)\n        {\n            // we create a new engine & abandon this reference\n            auto old = _engine;\n            _engine = _factory.dup(old, _input);\n            _factory.decRef(old);\n        }\n        _captures.matches.mutate((slice) { _captures._nMatch = _engine.match(slice); });\n    }\n\n    ///ditto\n    auto save(){ return this; }\n\n    ///Test if this match object is empty.\n    @property bool empty() const { return _captures._nMatch == 0; }\n\n    ///Same as !(x.empty), provided for its convenience  in conditional statements.\n    T opCast(T:bool)(){ return !empty; }\n\n    /// Same as .front, provided for compatibility with original std.regex.\n    @property inout(Captures!R) captures() inout { return _captures; }\n}\n\nprivate @trusted auto matchOnce(RegEx, R)(R input, const auto ref RegEx prog)\n{\n    alias Char = BasicElementOf!R;\n    static struct Key\n    {\n        immutable(Char)[] pattern;\n        uint flags;\n    }\n    static Key cacheKey = Key(\"\", -1);\n    static Matcher!Char cache;\n    auto factory = prog.factory is null ? defaultFactory!Char(prog) : prog.factory;\n    auto key = Key(prog.pattern, prog.flags);\n    Matcher!Char engine;\n    if (cacheKey == key)\n    {\n        engine = cache;\n        engine.rearm(input);\n    }\n    else\n    {\n        engine = factory.create(prog, input);\n        if (cache) factory.decRef(cache); // destroy cached engine *after* building a new one\n        cache = engine;\n        cacheKey = key;\n    }\n    auto captures = Captures!R(input, prog.ngroup, prog.dict);\n    captures.matches.mutate((slice){ captures._nMatch = engine.match(slice); });\n    return captures;\n}\n\nprivate auto matchMany(RegEx, R)(R input, auto ref RegEx re) @safe\n{\n    return RegexMatch!R(input, re.withFlags(re.flags | RegexOption.global));\n}\n\n@system unittest\n{\n    //sanity checks for new API\n    auto re = regex(\"abc\");\n    assert(!\"abc\".matchOnce(re).empty);\n    assert(\"abc\".matchOnce(re)[0] == \"abc\");\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=18135\n@system unittest\n{\n    static struct MapResult { RegexMatch!string m; }\n    MapResult m;\n    m = MapResult();\n    assert(m == m);\n}\n\nprivate enum isReplaceFunctor(alias fun, R) =\n    __traits(compiles, (Captures!R c) { fun(c); });\n\n// the lowest level - just stuff replacements into the sink\nprivate @trusted void replaceCapturesInto(alias output, Sink, R, T)\n        (ref Sink sink, R input, T captures)\nif (isOutputRange!(Sink, dchar) && isSomeString!R)\n{\n    if (captures.empty)\n    {\n        sink.put(input);\n        return;\n    }\n    sink.put(captures.pre);\n    // a hack to get around bogus errors, should be simply output(captures, sink)\n    // \"is a nested function and cannot be accessed from\"\n    static if (isReplaceFunctor!(output, R))\n        sink.put(output(captures)); //\"mutator\" type of function\n    else\n        output(captures, sink); //\"output\" type of function\n    sink.put(captures.post);\n}\n\n// ditto for a range of captures\nprivate void replaceMatchesInto(alias output, Sink, R, T)\n        (ref Sink sink, R input, T matches)\nif (isOutputRange!(Sink, dchar) && isSomeString!R)\n{\n    size_t offset = 0;\n    foreach (cap; matches)\n    {\n        sink.put(cap.pre[offset .. $]);\n        // same hack, see replaceCapturesInto\n        static if (isReplaceFunctor!(output, R))\n            sink.put(output(cap)); //\"mutator\" type of function\n        else\n            output(cap, sink); //\"output\" type of function\n        offset = cap.pre.length + cap.hit.length;\n    }\n    sink.put(input[offset .. $]);\n}\n\n//  a general skeleton of replaceFirst\nprivate R replaceFirstWith(alias output, R, RegEx)(R input, RegEx re)\nif (isSomeString!R && isRegexFor!(RegEx, R))\n{\n    import std.array : appender;\n    auto data = matchFirst(input, re);\n    if (data.empty)\n        return input;\n    auto app = appender!(R)();\n    replaceCapturesInto!output(app, input, data);\n    return app.data;\n}\n\n// ditto for replaceAll\n// the method parameter allows old API to ride on the back of the new one\nprivate R replaceAllWith(alias output,\n        alias method=matchAll, R, RegEx)(R input, RegEx re)\nif (isSomeString!R && isRegexFor!(RegEx, R))\n{\n    import std.array : appender;\n    auto matches = method(input, re); //inout(C)[] fails\n    if (matches.empty)\n        return input;\n    auto app = appender!(R)();\n    replaceMatchesInto!output(app, input, matches);\n    return app.data;\n}\n\n\n/++\n    Start matching `input` to regex pattern `re`,\n    using Thompson NFA matching scheme.\n\n    The use of this function is $(RED discouraged) - use either of\n    $(LREF matchAll) or $(LREF matchFirst).\n\n    Delegating  the kind of operation\n    to \"g\" flag is soon to be phased out along with the\n    ability to choose the exact matching scheme. The choice of\n    matching scheme to use depends highly on the pattern kind and\n    can done automatically on case by case basis.\n\n    Returns: a `RegexMatch` object holding engine state after first match.\n+/\n\npublic auto match(R, RegEx)(R input, RegEx re)\nif (isSomeString!R && isRegexFor!(RegEx,R))\n{\n    return RegexMatch!(Unqual!(typeof(input)))(input, re);\n}\n\n///ditto\npublic auto match(R, String)(R input, String re)\nif (isSomeString!R && isSomeString!String)\n{\n    return RegexMatch!(Unqual!(typeof(input)))(input, regex(re));\n}\n\n/++\n    Find the first (leftmost) slice of the `input` that\n    matches the pattern `re`. This function picks the most suitable\n    regular expression engine depending on the pattern properties.\n\n    `re` parameter can be one of three types:\n    $(UL\n      $(LI Plain string(s), in which case it's compiled to bytecode before matching. )\n      $(LI Regex!char (wchar/dchar) that contains a pattern in the form of\n        compiled  bytecode. )\n      $(LI StaticRegex!char (wchar/dchar) that contains a pattern in the form of\n        compiled native machine code. )\n    )\n\n    Returns:\n    $(LREF Captures) containing the extent of a match together with all submatches\n    if there was a match, otherwise an empty $(LREF Captures) object.\n+/\npublic auto matchFirst(R, RegEx)(R input, RegEx re)\nif (isSomeString!R && isRegexFor!(RegEx, R))\n{\n    return matchOnce(input, re);\n}\n\n///ditto\npublic auto matchFirst(R, String)(R input, String re)\nif (isSomeString!R && isSomeString!String)\n{\n    return matchOnce(input, regex(re));\n}\n\n///ditto\npublic auto matchFirst(R, String)(R input, String[] re...)\nif (isSomeString!R && isSomeString!String)\n{\n    return matchOnce(input, regex(re));\n}\n\n/++\n    Initiate a search for all non-overlapping matches to the pattern `re`\n    in the given `input`. The result is a lazy range of matches generated\n    as they are encountered in the input going left to right.\n\n    This function picks the most suitable regular expression engine\n    depending on the pattern properties.\n\n    `re` parameter can be one of three types:\n    $(UL\n      $(LI Plain string(s), in which case it's compiled to bytecode before matching. )\n      $(LI Regex!char (wchar/dchar) that contains a pattern in the form of\n        compiled  bytecode. )\n      $(LI StaticRegex!char (wchar/dchar) that contains a pattern in the form of\n        compiled native machine code. )\n    )\n\n    Returns:\n    $(LREF RegexMatch) object that represents matcher state\n    after the first match was found or an empty one if not present.\n+/\npublic auto matchAll(R, RegEx)(R input, RegEx re)\nif (isSomeString!R && isRegexFor!(RegEx, R))\n{\n    return matchMany(input, re);\n}\n\n///ditto\npublic auto matchAll(R, String)(R input, String re)\nif (isSomeString!R && isSomeString!String)\n{\n    return matchMany(input, regex(re));\n}\n\n///ditto\npublic auto matchAll(R, String)(R input, String[] re...)\nif (isSomeString!R && isSomeString!String)\n{\n    return matchMany(input, regex(re));\n}\n\n// another set of tests just to cover the new API\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    import std.conv : to;\n\n    static foreach (String; AliasSeq!(string, wstring, const(dchar)[]))\n    {{\n        auto str1 = \"blah-bleh\".to!String();\n        auto pat1 = \"bl[ae]h\".to!String();\n        auto mf = matchFirst(str1, pat1);\n        assert(mf.equal([\"blah\".to!String()]));\n        auto mAll = matchAll(str1, pat1);\n        assert(mAll.equal!((a,b) => a.equal(b))\n            ([[\"blah\".to!String()], [\"bleh\".to!String()]]));\n\n        auto str2 = \"1/03/12 - 3/03/12\".to!String();\n        auto pat2 = regex([r\"(\\d+)/(\\d+)/(\\d+)\".to!String(), \"abc\".to!String]);\n        auto mf2 = matchFirst(str2, pat2);\n        assert(mf2.equal([\"1/03/12\", \"1\", \"03\", \"12\"].map!(to!String)()));\n        auto mAll2 = matchAll(str2, pat2);\n        assert(mAll2.front.equal(mf2));\n        mAll2.popFront();\n        assert(mAll2.front.equal([\"3/03/12\", \"3\", \"03\", \"12\"].map!(to!String)()));\n        mf2.popFrontN(3);\n        assert(mf2.equal([\"12\".to!String()]));\n\n        auto ctPat = ctRegex!(`(?P<Quot>\\d+)/(?P<Denom>\\d+)`.to!String());\n        auto str = \"2 + 34/56 - 6/1\".to!String();\n        auto cmf = matchFirst(str, ctPat);\n        assert(cmf.equal([\"34/56\", \"34\", \"56\"].map!(to!String)()));\n        assert(cmf[\"Quot\"] == \"34\".to!String());\n        assert(cmf[\"Denom\"] == \"56\".to!String());\n\n        auto cmAll = matchAll(str, ctPat);\n        assert(cmAll.front.equal(cmf));\n        cmAll.popFront();\n        assert(cmAll.front.equal([\"6/1\", \"6\", \"1\"].map!(to!String)()));\n    }}\n}\n\n/++\n    Start matching of `input` to regex pattern `re`,\n    using traditional $(LINK2 https://en.wikipedia.org/wiki/Backtracking,\n    backtracking) matching scheme.\n\n    The use of this function is $(RED discouraged) - use either of\n    $(LREF matchAll) or $(LREF matchFirst).\n\n    Delegating  the kind of operation\n    to \"g\" flag is soon to be phased out along with the\n    ability to choose the exact matching scheme. The choice of\n    matching scheme to use depends highly on the pattern kind and\n    can done automatically on case by case basis.\n\n    Returns: a `RegexMatch` object holding engine\n    state after first match.\n\n+/\npublic auto bmatch(R, RegEx)(R input, RegEx re)\nif (isSomeString!R && isRegexFor!(RegEx, R))\n{\n    return RegexMatch!(Unqual!(typeof(input)))(input, re);\n}\n\n///ditto\npublic auto bmatch(R, String)(R input, String re)\nif (isSomeString!R && isSomeString!String)\n{\n    return RegexMatch!(Unqual!(typeof(input)))(input, regex(re));\n}\n\n// produces replacement string from format using captures for substitution\npackage void replaceFmt(R, Capt, OutR)\n    (R format, Capt captures, OutR sink, bool ignoreBadSubs = false)\nif (isOutputRange!(OutR, ElementEncodingType!R[]) &&\n    isOutputRange!(OutR, ElementEncodingType!(Capt.String)[]))\n{\n    import std.algorithm.searching : find;\n    import std.ascii : isDigit, isAlpha;\n    import std.conv : text, parse;\n    import std.exception : enforce;\n    enum State { Normal, Dollar }\n    auto state = State.Normal;\n    size_t offset;\nL_Replace_Loop:\n    while (!format.empty)\n        final switch (state)\n        {\n        case State.Normal:\n            for (offset = 0; offset < format.length; offset++)//no decoding\n            {\n                if (format[offset] == '$')\n                {\n                    state = State.Dollar;\n                    sink.put(format[0 .. offset]);\n                    format = format[offset+1 .. $];//ditto\n                    continue L_Replace_Loop;\n                }\n            }\n            sink.put(format[0 .. offset]);\n            format = format[offset .. $];\n            break;\n        case State.Dollar:\n            if (isDigit(format[0]))\n            {\n                uint digit = parse!uint(format);\n                enforce(ignoreBadSubs || digit < captures.length, text(\"invalid submatch number \", digit));\n                if (digit < captures.length)\n                    sink.put(captures[digit]);\n            }\n            else if (format[0] == '{')\n            {\n                auto x = find!(a => !isAlpha(a))(format[1..$]);\n                enforce(!x.empty && x[0] == '}', \"no matching '}' in replacement format\");\n                auto name = format[1 .. $ - x.length];\n                format = x[1..$];\n                enforce(!name.empty, \"invalid name in ${...} replacement format\");\n                sink.put(captures[name]);\n            }\n            else if (format[0] == '&')\n            {\n                sink.put(captures[0]);\n                format = format[1 .. $];\n            }\n            else if (format[0] == '`')\n            {\n                sink.put(captures.pre);\n                format = format[1 .. $];\n            }\n            else if (format[0] == '\\'')\n            {\n                sink.put(captures.post);\n                format = format[1 .. $];\n            }\n            else if (format[0] == '$')\n            {\n                sink.put(format[0 .. 1]);\n                format = format[1 .. $];\n            }\n            state = State.Normal;\n            break;\n        }\n    enforce(state == State.Normal, \"invalid format string in regex replace\");\n}\n\n/++\n    Construct a new string from `input` by replacing the first match with\n    a string generated from it according to the `format` specifier.\n\n    To replace all matches use $(LREF replaceAll).\n\n    Params:\n    input = string to search\n    re = compiled regular expression to use\n    format = _format string to generate replacements from,\n    see $(S_LINK Replace _format string, the _format string).\n\n    Returns:\n    A string of the same type with the first match (if any) replaced.\n    If no match is found returns the input string itself.\n+/\npublic R replaceFirst(R, C, RegEx)(R input, RegEx re, const(C)[] format)\nif (isSomeString!R && is(C : dchar) && isRegexFor!(RegEx, R))\n{\n    return replaceFirstWith!((m, sink) => replaceFmt(format, m, sink))(input, re);\n}\n\n///\n@system unittest\n{\n    assert(replaceFirst(\"noon\", regex(\"n\"), \"[$&]\") == \"[n]oon\");\n}\n\n/++\n    This is a general replacement tool that construct a new string by replacing\n    matches of pattern `re` in the `input`. Unlike the other overload\n    there is no format string instead captures are passed to\n    to a user-defined functor `fun` that returns a new string\n    to use as replacement.\n\n    This version replaces the first match in `input`,\n    see $(LREF replaceAll) to replace the all of the matches.\n\n    Returns:\n    A new string of the same type as `input` with all matches\n    replaced by return values of `fun`. If no matches found\n    returns the `input` itself.\n+/\npublic R replaceFirst(alias fun, R, RegEx)(R input, RegEx re)\nif (isSomeString!R && isRegexFor!(RegEx, R))\n{\n    return replaceFirstWith!((m, sink) => sink.put(fun(m)))(input, re);\n}\n\n///\n@system unittest\n{\n    import std.conv : to;\n    string list = \"#21 out of 46\";\n    string newList = replaceFirst!(cap => to!string(to!int(cap.hit)+1))\n        (list, regex(`[0-9]+`));\n    assert(newList == \"#22 out of 46\");\n}\n\n/++\n    A variation on $(LREF replaceFirst) that instead of allocating a new string\n    on each call outputs the result piece-wise to the `sink`. In particular\n    this enables efficient construction of a final output incrementally.\n\n    Like in $(LREF replaceFirst) family of functions there is an overload\n    for the substitution guided by the `format` string\n    and the one with the user defined callback.\n+/\npublic @trusted void replaceFirstInto(Sink, R, C, RegEx)\n        (ref Sink sink, R input, RegEx re, const(C)[] format)\nif (isOutputRange!(Sink, dchar) && isSomeString!R\n    && is(C : dchar) && isRegexFor!(RegEx, R))\n    {\n    replaceCapturesInto!((m, sink) => replaceFmt(format, m, sink))\n        (sink, input, matchFirst(input, re));\n    }\n\n///ditto\npublic @trusted void replaceFirstInto(alias fun, Sink, R, RegEx)\n    (Sink sink, R input, RegEx re)\nif (isOutputRange!(Sink, dchar) && isSomeString!R && isRegexFor!(RegEx, R))\n{\n    replaceCapturesInto!fun(sink, input, matchFirst(input, re));\n}\n\n///\n@system unittest\n{\n    import std.array;\n    string m1 = \"first message\\n\";\n    string m2 = \"second message\\n\";\n    auto result = appender!string();\n    replaceFirstInto(result, m1, regex(`([a-z]+) message`), \"$1\");\n    //equivalent of the above with user-defined callback\n    replaceFirstInto!(cap=>cap[1])(result, m2, regex(`([a-z]+) message`));\n    assert(result.data == \"first\\nsecond\\n\");\n}\n\n//examples for replaceFirst\n@system unittest\n{\n    import std.conv;\n    string list = \"#21 out of 46\";\n    string newList = replaceFirst!(cap => to!string(to!int(cap.hit)+1))\n        (list, regex(`[0-9]+`));\n    assert(newList == \"#22 out of 46\");\n    import std.array;\n    string m1 = \"first message\\n\";\n    string m2 = \"second message\\n\";\n    auto result = appender!string();\n    replaceFirstInto(result, m1, regex(`([a-z]+) message`), \"$1\");\n    //equivalent of the above with user-defined callback\n    replaceFirstInto!(cap=>cap[1])(result, m2, regex(`([a-z]+) message`));\n    assert(result.data == \"first\\nsecond\\n\");\n}\n\n/++\n    Construct a new string from `input` by replacing all of the\n    fragments that match a pattern `re` with a string generated\n    from the match according to the `format` specifier.\n\n    To replace only the first match use $(LREF replaceFirst).\n\n    Params:\n    input = string to search\n    re = compiled regular expression to use\n    format = _format string to generate replacements from,\n    see $(S_LINK Replace _format string, the _format string).\n\n    Returns:\n    A string of the same type as `input` with the all\n    of the matches (if any) replaced.\n    If no match is found returns the input string itself.\n+/\npublic @trusted R replaceAll(R, C, RegEx)(R input, RegEx re, const(C)[] format)\nif (isSomeString!R && is(C : dchar) && isRegexFor!(RegEx, R))\n{\n    return replaceAllWith!((m, sink) => replaceFmt(format, m, sink))(input, re);\n}\n\n///\n@system unittest\n{\n    // insert comma as thousands delimiter\n    auto re = regex(r\"(?<=\\d)(?=(\\d\\d\\d)+\\b)\",\"g\");\n    assert(replaceAll(\"12000 + 42100 = 54100\", re, \",\") == \"12,000 + 42,100 = 54,100\");\n}\n\n/++\n    This is a general replacement tool that construct a new string by replacing\n    matches of pattern `re` in the `input`. Unlike the other overload\n    there is no format string instead captures are passed to\n    to a user-defined functor `fun` that returns a new string\n    to use as replacement.\n\n    This version replaces all of the matches found in `input`,\n    see $(LREF replaceFirst) to replace the first match only.\n\n    Returns:\n    A new string of the same type as `input` with all matches\n    replaced by return values of `fun`. If no matches found\n    returns the `input` itself.\n\n    Params:\n    input = string to search\n    re = compiled regular expression\n    fun = delegate to use\n+/\npublic @trusted R replaceAll(alias fun, R, RegEx)(R input, RegEx re)\nif (isSomeString!R && isRegexFor!(RegEx, R))\n{\n    return replaceAllWith!((m, sink) => sink.put(fun(m)))(input, re);\n}\n\n///\n@system unittest\n{\n    string baz(Captures!(string) m)\n    {\n        import std.string : toUpper;\n        return toUpper(m.hit);\n    }\n    // Capitalize the letters 'a' and 'r':\n    auto s = replaceAll!(baz)(\"Strap a rocket engine on a chicken.\",\n            regex(\"[ar]\"));\n    assert(s == \"StRAp A Rocket engine on A chicken.\");\n}\n\n/++\n    A variation on $(LREF replaceAll) that instead of allocating a new string\n    on each call outputs the result piece-wise to the `sink`. In particular\n    this enables efficient construction of a final output incrementally.\n\n    As with $(LREF replaceAll) there are 2 overloads - one with a format string,\n    the other one with a user defined functor.\n+/\npublic @trusted void replaceAllInto(Sink, R, C, RegEx)\n        (Sink sink, R input, RegEx re, const(C)[] format)\nif (isOutputRange!(Sink, dchar) && isSomeString!R\n    && is(C : dchar) && isRegexFor!(RegEx, R))\n    {\n    replaceMatchesInto!((m, sink) => replaceFmt(format, m, sink))\n        (sink, input, matchAll(input, re));\n    }\n\n///ditto\npublic @trusted void replaceAllInto(alias fun, Sink, R, RegEx)\n        (Sink sink, R input, RegEx re)\nif (isOutputRange!(Sink, dchar) && isSomeString!R && isRegexFor!(RegEx, R))\n{\n    replaceMatchesInto!fun(sink, input, matchAll(input, re));\n}\n\n///\n@system unittest\n{\n    // insert comma as thousands delimiter in fifty randomly produced big numbers\n    import std.array, std.conv, std.random, std.range;\n    static re = regex(`(?<=\\d)(?=(\\d\\d\\d)+\\b)`, \"g\");\n    auto sink = appender!(char [])();\n    enum ulong min = 10UL ^^ 10, max = 10UL ^^ 19;\n    foreach (i; 0 .. 50)\n    {\n        sink.clear();\n        replaceAllInto(sink, text(uniform(min, max)), re, \",\");\n        foreach (pos; iota(sink.data.length - 4, 0, -4))\n            assert(sink.data[pos] == ',');\n    }\n}\n\n// exercise all of the replace APIs\n@system unittest\n{\n    import std.array : appender;\n    import std.conv;\n    // try and check first/all simple substitution\n    static foreach (S; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[]))\n    {{\n        S s1 = \"curt trial\".to!S();\n        S s2 = \"round dome\".to!S();\n        S t1F = \"court trial\".to!S();\n        S t2F = \"hound dome\".to!S();\n        S t1A = \"court trial\".to!S();\n        S t2A = \"hound home\".to!S();\n        auto re1 = regex(\"curt\".to!S());\n        auto re2 = regex(\"[dr]o\".to!S());\n\n        assert(replaceFirst(s1, re1, \"court\") == t1F);\n        assert(replaceFirst(s2, re2, \"ho\") == t2F);\n        assert(replaceAll(s1, re1, \"court\") == t1A);\n        assert(replaceAll(s2, re2, \"ho\") == t2A);\n\n        auto rep1 = replaceFirst!(cap => cap[0][0]~\"o\".to!S()~cap[0][1..$])(s1, re1);\n        assert(rep1 == t1F);\n        assert(replaceFirst!(cap => \"ho\".to!S())(s2, re2) == t2F);\n        auto rep1A = replaceAll!(cap => cap[0][0]~\"o\".to!S()~cap[0][1..$])(s1, re1);\n        assert(rep1A == t1A);\n        assert(replaceAll!(cap => \"ho\".to!S())(s2, re2) == t2A);\n\n        auto sink = appender!S();\n        replaceFirstInto(sink, s1, re1, \"court\");\n        assert(sink.data == t1F);\n        replaceFirstInto(sink, s2, re2, \"ho\");\n        assert(sink.data == t1F~t2F);\n        replaceAllInto(sink, s1, re1, \"court\");\n        assert(sink.data == t1F~t2F~t1A);\n        replaceAllInto(sink, s2, re2, \"ho\");\n        assert(sink.data == t1F~t2F~t1A~t2A);\n    }}\n}\n\n/++\n    Old API for replacement, operation depends on flags of pattern `re`.\n    With \"g\" flag it performs the equivalent of $(LREF replaceAll) otherwise it\n    works the same as $(LREF replaceFirst).\n\n    The use of this function is $(RED discouraged), please use $(LREF replaceAll)\n    or $(LREF replaceFirst) explicitly.\n+/\npublic R replace(alias scheme = match, R, C, RegEx)(R input, RegEx re, const(C)[] format)\nif (isSomeString!R && isRegexFor!(RegEx, R))\n{\n    return replaceAllWith!((m, sink) => replaceFmt(format, m, sink), match)(input, re);\n}\n\n///ditto\npublic R replace(alias fun, R, RegEx)(R input, RegEx re)\nif (isSomeString!R && isRegexFor!(RegEx, R))\n{\n    return replaceAllWith!(fun, match)(input, re);\n}\n\n/**\nSplits a string `r` using a regular expression `pat` as a separator.\n\nParams:\n    keepSeparators = flag to specify if the matches should be in the resulting range\n    r = the string to split\n    pat = the pattern to split on\nReturns:\n    A lazy range of strings\n*/\npublic struct Splitter(Flag!\"keepSeparators\" keepSeparators = No.keepSeparators, Range, alias RegEx = Regex)\nif (isSomeString!Range && isRegexFor!(RegEx, Range))\n{\nprivate:\n    Range _input;\n    size_t _offset;\n    alias Rx = typeof(match(Range.init,RegEx.init));\n    Rx _match;\n\n    static if (keepSeparators) bool onMatch = false;\n\n    @trusted this(Range input, RegEx separator)\n    {//@@@BUG@@@ generated opAssign of RegexMatch is not @trusted\n        _input = input;\n        const re = separator.withFlags(separator.flags | RegexOption.global);\n        if (_input.empty)\n        {\n            //there is nothing to match at all, make _offset > 0\n            _offset = 1;\n        }\n        else\n        {\n            _match = Rx(_input, re);\n\n            static if (keepSeparators)\n                if (_match.pre.empty)\n                    popFront();\n        }\n    }\n\npublic:\n    auto ref opSlice()\n    {\n        return this.save;\n    }\n\n    ///Forward range primitives.\n    @property Range front()\n    {\n        import std.algorithm.comparison : min;\n\n        assert(!empty && _offset <= _match.pre.length\n                && _match.pre.length <= _input.length);\n\n        static if (keepSeparators)\n        {\n            if (!onMatch)\n                return _input[_offset .. min($, _match.pre.length)];\n            else\n                return _match.hit();\n        }\n        else\n        {\n            return _input[_offset .. min($, _match.pre.length)];\n        }\n    }\n\n    ///ditto\n    @property bool empty()\n    {\n        static if (keepSeparators)\n            return _offset >= _input.length;\n        else\n            return _offset > _input.length;\n    }\n\n    ///ditto\n    void popFront()\n    {\n        assert(!empty);\n        if (_match.empty)\n        {\n            //No more separators, work is done here\n            _offset = _input.length + 1;\n        }\n        else\n        {\n            static if (keepSeparators)\n            {\n                if (!onMatch)\n                {\n                    //skip past the separator\n                    _offset = _match.pre.length;\n                }\n                else\n                {\n                    _offset += _match.hit.length;\n                    _match.popFront();\n                }\n\n                onMatch = !onMatch;\n            }\n            else\n            {\n                //skip past the separator\n                _offset = _match.pre.length + _match.hit.length;\n                _match.popFront();\n            }\n        }\n    }\n\n    ///ditto\n    @property auto save()\n    {\n        return this;\n    }\n}\n\n/// ditto\npublic Splitter!(keepSeparators, Range, RegEx) splitter(\n    Flag!\"keepSeparators\" keepSeparators = No.keepSeparators, Range, RegEx)(Range r, RegEx pat)\nif (\n    is(BasicElementOf!Range : dchar) && isRegexFor!(RegEx, Range))\n{\n    return Splitter!(keepSeparators, Range, RegEx)(r, pat);\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    auto s1 = \", abc, de,  fg, hi, \";\n    assert(equal(splitter(s1, regex(\", *\")),\n        [\"\", \"abc\", \"de\", \"fg\", \"hi\", \"\"]));\n}\n\n/// Split on a pattern, but keep the matches in the resulting range\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : Yes;\n\n    auto pattern = regex(`([\\.,])`);\n\n    assert(\"2003.04.05\"\n        .splitter!(Yes.keepSeparators)(pattern)\n        .equal([\"2003\", \".\", \"04\", \".\", \"05\"]));\n\n    assert(\",1,2,3\"\n        .splitter!(Yes.keepSeparators)(pattern)\n        .equal([\",\", \"1\", \",\", \"2\", \",\", \"3\"]));\n}\n\n///An eager version of `splitter` that creates an array with splitted slices of `input`.\npublic @trusted String[] split(String, RegEx)(String input, RegEx rx)\nif (isSomeString!String  && isRegexFor!(RegEx, String))\n{\n    import std.array : appender;\n    auto a = appender!(String[])();\n    foreach (e; splitter(input, rx))\n        a.put(e);\n    return a.data;\n}\n\n///Exception object thrown in case of errors during regex compilation.\npublic alias RegexException = std.regex.internal.ir.RegexException;\n\n/++\n  A range that lazily produces a string output escaped\n  to be used inside of a regular expression.\n+/\nauto escaper(Range)(Range r)\n{\n    import std.algorithm.searching : find;\n    static immutable escapables = [Escapables];\n    static struct Escaper // template to deduce attributes\n    {\n        Range r;\n        bool escaped;\n\n        @property ElementType!Range front(){\n          if (escaped)\n              return '\\\\';\n          else\n              return r.front;\n        }\n\n        @property bool empty(){ return r.empty; }\n\n        void popFront(){\n          if (escaped) escaped = false;\n          else\n          {\n              r.popFront();\n              if (!r.empty && !escapables.find(r.front).empty)\n                  escaped = true;\n          }\n        }\n\n        @property auto save(){ return Escaper(r.save, escaped); }\n    }\n\n    bool escaped = !r.empty && !escapables.find(r.front).empty;\n    return Escaper(r, escaped);\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison;\n    import std.regex;\n    string s = `This is {unfriendly} to *regex*`;\n    assert(s.escaper.equal(`This is \\{unfriendly\\} to \\*regex\\*`));\n}\n\n@system unittest\n{\n    import std.algorithm.comparison;\n    import std.conv;\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n      auto s = \"^\".to!S;\n      assert(s.escaper.equal(`\\^`));\n      auto s2 = \"\";\n      assert(s2.escaper.equal(\"\"));\n    }}\n}\n"
  },
  {
    "path": "libphobos/src/std/signals.d",
    "content": "// Written in the D programming language.\n\n/**\n * Signals and Slots are an implementation of the Observer Pattern.\n * Essentially, when a Signal is emitted, a list of connected Observers\n * (called slots) are called.\n *\n * There have been several D implementations of Signals and Slots.\n * This version makes use of several new features in D, which make\n * using it simpler and less error prone. In particular, it is no\n * longer necessary to instrument the slots.\n *\n * References:\n *      $(LUCKY A Deeper Look at Signals and Slots)$(BR)\n *      $(LINK2 http://en.wikipedia.org/wiki/Observer_pattern, Observer pattern)$(BR)\n *      $(LINK2 http://en.wikipedia.org/wiki/Signals_and_slots, Wikipedia)$(BR)\n *      $(LINK2 http://boost.org/doc/html/$(SIGNALS).html, Boost Signals)$(BR)\n *      $(LINK2 http://qt-project.org/doc/qt-5/signalsandslots.html, Qt)$(BR)\n *\n *      There has been a great deal of discussion in the D newsgroups\n *      over this, and several implementations:\n *\n *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/announce/signal_slots_library_4825.html, signal slots library)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/Signals_and_Slots_in_D_42387.html, Signals and Slots in D)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/Dynamic_binding_--_Qt_s_Signals_and_Slots_vs_Objective-C_42260.html, Dynamic binding -- Qt's Signals and Slots vs Objective-C)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/Dissecting_the_SS_42377.html, Dissecting the SS)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/dwt/about_harmonia_454.html, about harmonia)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/announce/1502.html, Another event handling module)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/41825.html, Suggestion: signal/slot mechanism)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/13251.html, Signals and slots?)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/10714.html, Signals and slots ready for evaluation)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/1393.html, Signals &amp; Slots for Walter)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/28456.html, Signal/Slot mechanism?)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/19470.html, Modern Features?)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/16592.html, Delegates vs interfaces)$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/16583.html, The importance of component programming (properties$(COMMA) signals and slots$(COMMA) etc))$(BR)\n *      $(LINK2 http://www.digitalmars.com/d/archives/16368.html, signals and slots)$(BR)\n *\n * Bugs:\n *      Slots can only be delegates formed from class objects or\n *      interfaces to class objects. If a delegate to something else\n *      is passed to connect(), such as a struct member function,\n *      a nested function or a COM interface, undefined behavior\n *      will result.\n *\n *      Not safe for multiple threads operating on the same signals\n *      or slots.\n * Macros:\n *      SIGNALS=signals\n *\n * Copyright: Copyright The D Language Foundation 2000 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright)\n * Source:    $(PHOBOSSRC std/signals.d)\n *\n * $(SCRIPT inhibitQuickIndex = 1;)\n */\n/*          Copyright The D Language Foundation 2000 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.signals;\n\nimport core.exception : onOutOfMemoryError;\nimport core.stdc.stdlib : calloc, realloc, free;\nimport std.stdio;\n\n// Special function for internal use only.\n// Use of this is where the slot had better be a delegate\n// to an object or an interface that is part of an object.\nextern (C) Object _d_toObject(void* p);\n\n// Used in place of Object.notifyRegister and Object.notifyUnRegister.\nalias DisposeEvt = void delegate(Object);\nextern (C) void  rt_attachDisposeEvent( Object obj, DisposeEvt evt );\nextern (C) void  rt_detachDisposeEvent( Object obj, DisposeEvt evt );\n//debug=signal;\n\n/************************\n * Mixin to create a signal within a class object.\n *\n * Different signals can be added to a class by naming the mixins.\n */\n\nmixin template Signal(T1...)\n{\n    static import core.exception;\n    static import core.stdc.stdlib;\n    /***\n     * A slot is implemented as a delegate.\n     * The slot_t is the type of the delegate.\n     * The delegate must be to an instance of a class or an interface\n     * to a class instance.\n     * Delegates to struct instances or nested functions must not be\n     * used as slots.\n     */\n    alias slot_t = void delegate(T1);\n\n    /***\n     * Call each of the connected slots, passing the argument(s) i to them.\n     * Nested call will be ignored.\n     */\n    final void emit( T1 i )\n    {\n        if (status >= ST.inemitting || !slots.length)\n            return; // should not nest\n\n        status = ST.inemitting;\n        scope (exit)\n            status = ST.idle;\n\n        foreach (slot; slots[0 .. slots_idx])\n        {   if (slot)\n                slot(i);\n        }\n\n        assert(status >= ST.inemitting);\n        if (status == ST.inemitting_disconnected)\n        {\n            for (size_t j = 0; j < slots_idx;)\n            {\n                if (slots[j] is null)\n                {\n                    slots_idx--;\n                    slots[j] = slots[slots_idx];\n                }\n                else\n                    j++;\n            }\n        }\n    }\n\n    /***\n     * Add a slot to the list of slots to be called when emit() is called.\n     */\n    final void connect(slot_t slot)\n    {\n        /* Do this:\n         *    slots ~= slot;\n         * but use malloc() and friends instead\n         */\n        auto len = slots.length;\n        if (slots_idx == len)\n        {\n            if (slots.length == 0)\n            {\n                len = 4;\n                auto p = core.stdc.stdlib.calloc(slot_t.sizeof, len);\n                if (!p)\n                    core.exception.onOutOfMemoryError();\n                slots = (cast(slot_t*) p)[0 .. len];\n            }\n            else\n            {\n                import core.checkedint : addu, mulu;\n                bool overflow;\n                len = addu(mulu(len, 2, overflow), 4, overflow); // len = len * 2 + 4\n                const nbytes = mulu(len, slot_t.sizeof, overflow);\n                if (overflow) assert(0);\n\n                auto p = core.stdc.stdlib.realloc(slots.ptr, nbytes);\n                if (!p)\n                    core.exception.onOutOfMemoryError();\n                slots = (cast(slot_t*) p)[0 .. len];\n                slots[slots_idx + 1 .. $] = null;\n            }\n        }\n        slots[slots_idx++] = slot;\n\n     L1:\n        Object o = _d_toObject(slot.ptr);\n        rt_attachDisposeEvent(o, &unhook);\n    }\n\n    /***\n     * Remove a slot from the list of slots to be called when emit() is called.\n     */\n    final void disconnect(slot_t slot)\n    {\n        debug (signal) writefln(\"Signal.disconnect(slot)\");\n        size_t disconnectedSlots = 0;\n        size_t instancePreviousSlots = 0;\n        if (status >= ST.inemitting)\n        {\n            foreach (i, sloti; slots[0 .. slots_idx])\n            {\n                if (sloti.ptr == slot.ptr &&\n                    ++instancePreviousSlots &&\n                    sloti == slot)\n                {\n                    disconnectedSlots++;\n                    slots[i] = null;\n                    status = ST.inemitting_disconnected;\n                }\n            }\n        }\n        else\n        {\n            for (size_t i = 0; i < slots_idx; )\n            {\n                if (slots[i].ptr == slot.ptr &&\n                    ++instancePreviousSlots &&\n                    slots[i] == slot)\n                {\n                    slots_idx--;\n                    disconnectedSlots++;\n                    slots[i] = slots[slots_idx];\n                    slots[slots_idx] = null;        // not strictly necessary\n                }\n                else\n                    i++;\n            }\n        }\n\n         // detach object from dispose event if all its slots have been removed\n        if (instancePreviousSlots == disconnectedSlots)\n        {\n            Object o = _d_toObject(slot.ptr);\n            rt_detachDisposeEvent(o, &unhook);\n        }\n     }\n\n    /***\n     * Disconnect all the slots.\n     */\n    final void disconnectAll()\n    {\n        debug (signal) writefln(\"Signal.disconnectAll\");\n        __dtor();\n        slots_idx = 0;\n        status = ST.idle;\n    }\n\n    /* **\n     * Special function called when o is destroyed.\n     * It causes any slots dependent on o to be removed from the list\n     * of slots to be called by emit().\n     */\n    final void unhook(Object o)\n    in { assert( status == ST.idle ); }\n    do\n    {\n        debug (signal) writefln(\"Signal.unhook(o = %s)\", cast(void*) o);\n        for (size_t i = 0; i < slots_idx; )\n        {\n            if (_d_toObject(slots[i].ptr) is o)\n            {   slots_idx--;\n                slots[i] = slots[slots_idx];\n                slots[slots_idx] = null;        // not strictly necessary\n            }\n            else\n                i++;\n        }\n    }\n\n    /* **\n     * There can be multiple destructors inserted by mixins.\n     */\n    ~this()\n    {\n        /* **\n         * When this object is destroyed, need to let every slot\n         * know that this object is destroyed so they are not left\n         * with dangling references to it.\n         */\n        if (slots.length)\n        {\n            foreach (slot; slots[0 .. slots_idx])\n            {\n                if (slot)\n                {   Object o = _d_toObject(slot.ptr);\n                    rt_detachDisposeEvent(o, &unhook);\n                }\n            }\n            core.stdc.stdlib.free(slots.ptr);\n            slots = null;\n        }\n    }\n\n  private:\n    slot_t[] slots;             // the slots to call from emit()\n    size_t slots_idx;           // used length of slots[]\n\n    enum ST { idle, inemitting, inemitting_disconnected }\n    ST status;\n}\n\n///\n@system unittest\n{\n    import std.signals;\n\n    int observedMessageCounter = 0;\n\n    class Observer\n    {   // our slot\n        void watch(string msg, int value)\n        {\n            switch (observedMessageCounter++)\n            {\n                case 0:\n                    assert(msg == \"setting new value\");\n                    assert(value == 4);\n                    break;\n                case 1:\n                    assert(msg == \"setting new value\");\n                    assert(value == 6);\n                    break;\n                default:\n                    assert(0, \"Unknown observation\");\n            }\n        }\n    }\n\n    class Observer2\n    {   // our slot\n        void watch(string msg, int value)\n        {\n        }\n    }\n\n    class Foo\n    {\n        int value() { return _value; }\n\n        int value(int v)\n        {\n            if (v != _value)\n            {   _value = v;\n                // call all the connected slots with the two parameters\n                emit(\"setting new value\", v);\n            }\n            return v;\n        }\n\n        // Mix in all the code we need to make Foo into a signal\n        mixin Signal!(string, int);\n\n      private :\n        int _value;\n    }\n\n    Foo a = new Foo;\n    Observer o = new Observer;\n    auto o2 = new Observer2;\n    auto o3 = new Observer2;\n    auto o4 = new Observer2;\n    auto o5 = new Observer2;\n\n    a.value = 3;                // should not call o.watch()\n    a.connect(&o.watch);        // o.watch is the slot\n    a.connect(&o2.watch);\n    a.connect(&o3.watch);\n    a.connect(&o4.watch);\n    a.connect(&o5.watch);\n    a.value = 4;                // should call o.watch()\n    a.disconnect(&o.watch);     // o.watch is no longer a slot\n    a.disconnect(&o3.watch);\n    a.disconnect(&o5.watch);\n    a.disconnect(&o4.watch);\n    a.disconnect(&o2.watch);\n    a.value = 5;                // so should not call o.watch()\n    a.connect(&o2.watch);\n    a.connect(&o.watch);        // connect again\n    a.value = 6;                // should call o.watch()\n    destroy(o);                 // destroying o should automatically disconnect it\n    a.value = 7;                // should not call o.watch()\n\n    assert(observedMessageCounter == 2);\n}\n\n// A function whose sole purpose is to get this module linked in\n// so the unittest will run.\nvoid linkin() { }\n\n@system unittest\n{\n    class Observer\n    {\n        void watch(string msg, int i)\n        {\n            //writefln(\"Observed msg '%s' and value %s\", msg, i);\n            captured_value = i;\n            captured_msg   = msg;\n        }\n\n        int    captured_value;\n        string captured_msg;\n    }\n\n    class Foo\n    {\n        @property int value() { return _value; }\n\n        @property int value(int v)\n        {\n            if (v != _value)\n            {   _value = v;\n                emit(\"setting new value\", v);\n            }\n            return v;\n        }\n\n        mixin Signal!(string, int);\n\n      private:\n        int _value;\n    }\n\n    Foo a = new Foo;\n    Observer o = new Observer;\n\n    // check initial condition\n    assert(o.captured_value == 0);\n    assert(o.captured_msg == \"\");\n\n    // set a value while no observation is in place\n    a.value = 3;\n    assert(o.captured_value == 0);\n    assert(o.captured_msg == \"\");\n\n    // connect the watcher and trigger it\n    a.connect(&o.watch);\n    a.value = 4;\n    assert(o.captured_value == 4);\n    assert(o.captured_msg == \"setting new value\");\n\n    // disconnect the watcher and make sure it doesn't trigger\n    a.disconnect(&o.watch);\n    a.value = 5;\n    assert(o.captured_value == 4);\n    assert(o.captured_msg == \"setting new value\");\n\n    // reconnect the watcher and make sure it triggers\n    a.connect(&o.watch);\n    a.value = 6;\n    assert(o.captured_value == 6);\n    assert(o.captured_msg == \"setting new value\");\n\n    // destroy the underlying object and make sure it doesn't cause\n    // a crash or other problems\n    destroy(o);\n    a.value = 7;\n}\n\n@system unittest\n{\n    class Observer\n    {\n        int    i;\n        long   l;\n        string str;\n\n        void watchInt(string str, int i)\n        {\n            this.str = str;\n            this.i = i;\n        }\n\n        void watchLong(string str, long l)\n        {\n            this.str = str;\n            this.l = l;\n        }\n    }\n\n    class Bar\n    {\n        @property void value1(int v)  { s1.emit(\"str1\", v); }\n        @property void value2(int v)  { s2.emit(\"str2\", v); }\n        @property void value3(long v) { s3.emit(\"str3\", v); }\n\n        mixin Signal!(string, int)  s1;\n        mixin Signal!(string, int)  s2;\n        mixin Signal!(string, long) s3;\n    }\n\n    void test(T)(T a) {\n        auto o1 = new Observer;\n        auto o2 = new Observer;\n        auto o3 = new Observer;\n\n        // connect the watcher and trigger it\n        a.s1.connect(&o1.watchInt);\n        a.s2.connect(&o2.watchInt);\n        a.s3.connect(&o3.watchLong);\n\n        assert(!o1.i && !o1.l && o1.str == null);\n        assert(!o2.i && !o2.l && o2.str == null);\n        assert(!o3.i && !o3.l && o3.str == null);\n\n        a.value1 = 11;\n        assert(o1.i == 11 && !o1.l && o1.str == \"str1\");\n        assert(!o2.i && !o2.l && o2.str == null);\n        assert(!o3.i && !o3.l && o3.str == null);\n        o1.i = -11; o1.str = \"x1\";\n\n        a.value2 = 12;\n        assert(o1.i == -11 && !o1.l && o1.str == \"x1\");\n        assert(o2.i == 12 && !o2.l && o2.str == \"str2\");\n        assert(!o3.i && !o3.l && o3.str == null);\n        o2.i = -12; o2.str = \"x2\";\n\n        a.value3 = 13;\n        assert(o1.i == -11 && !o1.l && o1.str == \"x1\");\n        assert(o2.i == -12 && !o1.l && o2.str == \"x2\");\n        assert(!o3.i && o3.l == 13 && o3.str == \"str3\");\n        o3.l = -13; o3.str = \"x3\";\n\n        // disconnect the watchers and make sure it doesn't trigger\n        a.s1.disconnect(&o1.watchInt);\n        a.s2.disconnect(&o2.watchInt);\n        a.s3.disconnect(&o3.watchLong);\n\n        a.value1 = 21;\n        a.value2 = 22;\n        a.value3 = 23;\n        assert(o1.i == -11 && !o1.l && o1.str == \"x1\");\n        assert(o2.i == -12 && !o1.l && o2.str == \"x2\");\n        assert(!o3.i && o3.l == -13 && o3.str == \"x3\");\n\n        // reconnect the watcher and make sure it triggers\n        a.s1.connect(&o1.watchInt);\n        a.s2.connect(&o2.watchInt);\n        a.s3.connect(&o3.watchLong);\n\n        a.value1 = 31;\n        a.value2 = 32;\n        a.value3 = 33;\n        assert(o1.i == 31 && !o1.l && o1.str == \"str1\");\n        assert(o2.i == 32 && !o1.l && o2.str == \"str2\");\n        assert(!o3.i && o3.l == 33 && o3.str == \"str3\");\n\n        // destroy observers\n        destroy(o1);\n        destroy(o2);\n        destroy(o3);\n        a.value1 = 41;\n        a.value2 = 42;\n        a.value3 = 43;\n    }\n\n    test(new Bar);\n\n    class BarDerived: Bar\n    {\n        @property void value4(int v)  { s4.emit(\"str4\", v); }\n        @property void value5(int v)  { s5.emit(\"str5\", v); }\n        @property void value6(long v) { s6.emit(\"str6\", v); }\n\n        mixin Signal!(string, int)  s4;\n        mixin Signal!(string, int)  s5;\n        mixin Signal!(string, long) s6;\n    }\n\n    auto a = new BarDerived;\n\n    test!Bar(a);\n    test!BarDerived(a);\n\n    auto o4 = new Observer;\n    auto o5 = new Observer;\n    auto o6 = new Observer;\n\n    // connect the watcher and trigger it\n    a.s4.connect(&o4.watchInt);\n    a.s5.connect(&o5.watchInt);\n    a.s6.connect(&o6.watchLong);\n\n    assert(!o4.i && !o4.l && o4.str == null);\n    assert(!o5.i && !o5.l && o5.str == null);\n    assert(!o6.i && !o6.l && o6.str == null);\n\n    a.value4 = 44;\n    assert(o4.i == 44 && !o4.l && o4.str == \"str4\");\n    assert(!o5.i && !o5.l && o5.str == null);\n    assert(!o6.i && !o6.l && o6.str == null);\n    o4.i = -44; o4.str = \"x4\";\n\n    a.value5 = 45;\n    assert(o4.i == -44 && !o4.l && o4.str == \"x4\");\n    assert(o5.i == 45 && !o5.l && o5.str == \"str5\");\n    assert(!o6.i && !o6.l && o6.str == null);\n    o5.i = -45; o5.str = \"x5\";\n\n    a.value6 = 46;\n    assert(o4.i == -44 && !o4.l && o4.str == \"x4\");\n    assert(o5.i == -45 && !o4.l && o5.str == \"x5\");\n    assert(!o6.i && o6.l == 46 && o6.str == \"str6\");\n    o6.l = -46; o6.str = \"x6\";\n\n    // disconnect the watchers and make sure it doesn't trigger\n    a.s4.disconnect(&o4.watchInt);\n    a.s5.disconnect(&o5.watchInt);\n    a.s6.disconnect(&o6.watchLong);\n\n    a.value4 = 54;\n    a.value5 = 55;\n    a.value6 = 56;\n    assert(o4.i == -44 && !o4.l && o4.str == \"x4\");\n    assert(o5.i == -45 && !o4.l && o5.str == \"x5\");\n    assert(!o6.i && o6.l == -46 && o6.str == \"x6\");\n\n    // reconnect the watcher and make sure it triggers\n    a.s4.connect(&o4.watchInt);\n    a.s5.connect(&o5.watchInt);\n    a.s6.connect(&o6.watchLong);\n\n    a.value4 = 64;\n    a.value5 = 65;\n    a.value6 = 66;\n    assert(o4.i == 64 && !o4.l && o4.str == \"str4\");\n    assert(o5.i == 65 && !o4.l && o5.str == \"str5\");\n    assert(!o6.i && o6.l == 66 && o6.str == \"str6\");\n\n    // destroy observers\n    destroy(o4);\n    destroy(o5);\n    destroy(o6);\n    a.value4 = 44;\n    a.value5 = 45;\n    a.value6 = 46;\n}\n\n// Triggers bug from issue 15341\n@system unittest\n{\n    class Observer\n    {\n       void watch() { }\n       void watch2() { }\n    }\n\n    class Bar\n    {\n       mixin Signal!();\n    }\n\n   auto a = new Bar;\n   auto o = new Observer;\n\n   //Connect both observer methods for the same instance\n   a.connect(&o.watch);\n   a.connect(&o.watch2); // not connecting watch2() or disconnecting it manually fixes the issue\n\n   //Disconnect a single method of the two\n   a.disconnect(&o.watch); // NOT disconnecting watch() fixes the issue\n\n   destroy(o); // destroying o should automatically call unhook and disconnect the slot for watch2\n   a.emit(); // should not raise segfault since &o.watch2 is no longer connected\n}\n\nversion (none) // Disabled because of dmd @@@BUG5028@@@\n@system unittest\n{\n    class A\n    {\n        mixin Signal!(string, int) s1;\n    }\n\n    class B : A\n    {\n        mixin Signal!(string, int) s2;\n    }\n}\n\n// Triggers bug from issue 16249\n@system unittest\n{\n    class myLINE\n    {\n        mixin Signal!( myLINE, int );\n\n        void value( int v )\n        {\n            if ( v >= 0 ) emit( this, v );\n            else          emit( new myLINE, v );\n        }\n    }\n\n    class Dot\n    {\n        int value;\n\n        myLINE line_;\n        void line( myLINE line_x )\n        {\n            if ( line_ is line_x ) return;\n\n            if ( line_ !is null )\n            {\n                line_.disconnect( &watch );\n            }\n            line_ = line_x;\n            line_.connect( &watch );\n        }\n\n        void watch( myLINE line_x, int value_x )\n        {\n            line = line_x;\n            value = value_x;\n        }\n    }\n\n    auto dot1 = new Dot;\n    auto dot2 = new Dot;\n    auto line = new myLINE;\n    dot1.line = line;\n    dot2.line = line;\n\n    line.value = 11;\n    assert( dot1.value == 11 );\n    assert( dot2.value == 11 );\n\n    line.value = -22;\n    assert( dot1.value == -22 );\n    assert( dot2.value == -22 );\n}\n\n@system unittest\n{\n    import std.signals;\n\n    class Observer\n    {   // our slot\n        void watch(string msg, int value)\n        {\n            if (value != 0)\n            {\n                assert(msg == \"setting new value\");\n                assert(value == 1);\n            }\n        }\n    }\n\n    class Foo\n    {\n        int value() { return _value; }\n\n        int value(int v)\n        {\n            if (v != _value)\n            {\n                _value = v;\n                // call all the connected slots with the parameters\n                emit(\"setting new value\", v);\n            }\n            return v;\n        }\n\n        // Mix in all the code we need to make Foo into a signal\n        mixin Signal!(string, int);\n\n      private :\n        int _value;\n    }\n\n    Foo a = new Foo;\n    Observer o = new Observer;\n    auto o2 = new Observer;\n\n    a.value = 3;                // should not call o.watch()\n    a.connect(&o.watch);        // o.watch is the slot\n    a.connect(&o2.watch);\n    a.value = 1;                // should call o.watch()\n    a.disconnectAll();\n    a.value = 5;                // so should not call o.watch()\n    a.connect(&o.watch);        // connect again\n    a.connect(&o2.watch);\n    a.value = 1;                // should call o.watch()\n    destroy(o);                 // destroying o should automatically disconnect it\n    destroy(o2);\n    a.value = 7;                // should not call o.watch()\n}\n"
  },
  {
    "path": "libphobos/src/std/socket.d",
    "content": "// Written in the D programming language\n\n/*\n        Copyright (C) 2004-2011 Christopher E. Miller\n\n        Boost Software License - Version 1.0 - August 17th, 2003\n\n        Permission is hereby granted, free of charge, to any person or organization\n        obtaining a copy of the software and accompanying documentation covered by\n        this license (the \"Software\") to use, reproduce, display, distribute,\n        execute, and transmit the Software, and to prepare derivative works of the\n        Software, and to permit third-parties to whom the Software is furnished to\n        do so, all subject to the following:\n\n        The copyright notices in the Software and this entire statement, including\n        the above license grant, this restriction and the following disclaimer,\n        must be included in all copies of the Software, in whole or in part, and\n        all derivative works of the Software, unless such copies or derivative\n        works are solely in the form of machine-executable object code generated by\n        a source language processor.\n\n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\n        SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\n        FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\n        ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n        DEALINGS IN THE SOFTWARE.\n\n        socket.d 1.4\n        Jan 2011\n\n        Thanks to Benjamin Herr for his assistance.\n */\n\n/**\n * Socket primitives.\n * Example: See $(SAMPLESRC listener.d) and $(SAMPLESRC htmlget.d)\n * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors: Christopher E. Miller, $(HTTP klickverbot.at, David Nadlinger),\n *      $(HTTP thecybershadow.net, Vladimir Panteleev)\n * Source:  $(PHOBOSSRC std/socket.d)\n */\n\nmodule std.socket;\n\nimport core.stdc.stdint, core.stdc.stdlib, core.stdc.string, std.conv, std.string;\n\nimport core.stdc.config;\nimport core.time : dur, Duration;\nimport std.exception;\n\nimport std.internal.cstring;\n\n\n@safe:\n\nversion (Windows)\n{\n    pragma (lib, \"ws2_32.lib\");\n    pragma (lib, \"wsock32.lib\");\n\n    import core.sys.windows.windows, std.windows.syserror;\n    public import core.sys.windows.winsock2;\n    private alias _ctimeval = core.sys.windows.winsock2.timeval;\n    private alias _clinger = core.sys.windows.winsock2.linger;\n\n    enum socket_t : SOCKET { INVALID_SOCKET }\n    private const int _SOCKET_ERROR = SOCKET_ERROR;\n\n\n    private int _lasterr() nothrow @nogc\n    {\n        return WSAGetLastError();\n    }\n}\nelse version (Posix)\n{\n    version (linux)\n    {\n        enum : int\n        {\n            TCP_KEEPIDLE  = 4,\n            TCP_KEEPINTVL = 5\n        }\n    }\n\n    public import core.sys.posix.netinet.in_;\n    import core.sys.posix.arpa.inet;\n    import core.sys.posix.fcntl;\n    import core.sys.posix.netdb;\n    import core.sys.posix.netinet.tcp;\n    import core.sys.posix.sys.select;\n    import core.sys.posix.sys.socket;\n    import core.sys.posix.sys.time;\n    import core.sys.posix.sys.un : sockaddr_un;\n    import core.sys.posix.unistd;\n    private alias _ctimeval = core.sys.posix.sys.time.timeval;\n    private alias _clinger = core.sys.posix.sys.socket.linger;\n\n    import core.stdc.errno;\n\n    enum socket_t : int32_t { init = -1 }\n    private const int _SOCKET_ERROR = -1;\n\n    private enum : int\n    {\n        SD_RECEIVE = SHUT_RD,\n        SD_SEND    = SHUT_WR,\n        SD_BOTH    = SHUT_RDWR\n    }\n\n    private int _lasterr() nothrow @nogc\n    {\n        return errno;\n    }\n}\nelse\n{\n    static assert(0);     // No socket support yet.\n}\n\nversion (unittest)\n{\n    // Print a message on exception instead of failing the unittest.\n    private void softUnittest(void delegate() @safe test, int line = __LINE__) @trusted\n    {\n        import std.stdio : writefln;\n        try\n            test();\n        catch (Throwable e)\n        {\n            writefln(\" --- std.socket(%d) test fails depending on environment ---\", line);\n            writefln(\" (%s)\", e);\n        }\n    }\n}\n\n/// Base exception thrown by `std.socket`.\nclass SocketException: Exception\n{\n    mixin basicExceptionCtors;\n}\n\nversion (CRuntime_Glibc) version = GNU_STRERROR;\nversion (CRuntime_UClibc) version = GNU_STRERROR;\n\n/*\n * Needs to be public so that SocketOSException can be thrown outside of\n * std.socket (since it uses it as a default argument), but it probably doesn't\n * need to actually show up in the docs, since there's not really any public\n * need for it outside of being a default argument.\n */\nstring formatSocketError(int err) @trusted\n{\n    version (Posix)\n    {\n        char[80] buf;\n        const(char)* cs;\n        version (GNU_STRERROR)\n        {\n            cs = strerror_r(err, buf.ptr, buf.length);\n        }\n        else\n        {\n            auto errs = strerror_r(err, buf.ptr, buf.length);\n            if (errs == 0)\n                cs = buf.ptr;\n            else\n                return \"Socket error \" ~ to!string(err);\n        }\n\n        auto len = strlen(cs);\n\n        if (cs[len - 1] == '\\n')\n            len--;\n        if (cs[len - 1] == '\\r')\n            len--;\n        return cs[0 .. len].idup;\n    }\n    else\n    version (Windows)\n    {\n        return sysErrorString(err);\n    }\n    else\n        return \"Socket error \" ~ to!string(err);\n}\n\n/// Retrieve the error message for the most recently encountered network error.\n@property string lastSocketError()\n{\n    return formatSocketError(_lasterr());\n}\n\n/**\n * Socket exceptions representing network errors reported by the operating\n * system.\n */\nclass SocketOSException: SocketException\n{\n    int errorCode;     /// Platform-specific error code.\n\n    ///\n    this(string msg,\n         string file = __FILE__,\n         size_t line = __LINE__,\n         Throwable next = null,\n         int err = _lasterr(),\n         string function(int) @trusted errorFormatter = &formatSocketError)\n    {\n        errorCode = err;\n\n        if (msg.length)\n            super(msg ~ \": \" ~ errorFormatter(err), file, line, next);\n        else\n            super(errorFormatter(err), file, line, next);\n    }\n\n    ///\n    this(string msg,\n         Throwable next,\n         string file = __FILE__,\n         size_t line = __LINE__,\n         int err = _lasterr(),\n         string function(int) @trusted errorFormatter = &formatSocketError)\n    {\n        this(msg, file, line, next, err, errorFormatter);\n    }\n\n    ///\n    this(string msg,\n         int err,\n         string function(int) @trusted errorFormatter = &formatSocketError,\n         string file = __FILE__,\n         size_t line = __LINE__,\n         Throwable next = null)\n    {\n        this(msg, file, line, next, err, errorFormatter);\n    }\n}\n\n/// Socket exceptions representing invalid parameters specified by user code.\nclass SocketParameterException: SocketException\n{\n    mixin basicExceptionCtors;\n}\n\n/**\n * Socket exceptions representing attempts to use network capabilities not\n * available on the current system.\n */\nclass SocketFeatureException: SocketException\n{\n    mixin basicExceptionCtors;\n}\n\n\n/**\n * Returns:\n * `true` if the last socket operation failed because the socket\n * was in non-blocking mode and the operation would have blocked.\n */\nbool wouldHaveBlocked() nothrow @nogc\n{\n    version (Windows)\n        return _lasterr() == WSAEWOULDBLOCK;\n    else version (Posix)\n        return _lasterr() == EAGAIN;\n    else\n        static assert(0);\n}\n\n\nprivate immutable\n{\n    typeof(&getnameinfo) getnameinfoPointer;\n    typeof(&getaddrinfo) getaddrinfoPointer;\n    typeof(&freeaddrinfo) freeaddrinfoPointer;\n}\n\nshared static this() @system\n{\n    version (Windows)\n    {\n        WSADATA wd;\n\n        // Winsock will still load if an older version is present.\n        // The version is just a request.\n        int val;\n        val = WSAStartup(0x2020, &wd);\n        if (val)         // Request Winsock 2.2 for IPv6.\n            throw new SocketOSException(\"Unable to initialize socket library\", val);\n\n        // These functions may not be present on older Windows versions.\n        // See the comment in InternetAddress.toHostNameString() for details.\n        auto ws2Lib = GetModuleHandleA(\"ws2_32.dll\");\n        if (ws2Lib)\n        {\n            getnameinfoPointer = cast(typeof(getnameinfoPointer))\n                                 GetProcAddress(ws2Lib, \"getnameinfo\");\n            getaddrinfoPointer = cast(typeof(getaddrinfoPointer))\n                                 GetProcAddress(ws2Lib, \"getaddrinfo\");\n            freeaddrinfoPointer = cast(typeof(freeaddrinfoPointer))\n                                 GetProcAddress(ws2Lib, \"freeaddrinfo\");\n        }\n    }\n    else version (Posix)\n    {\n        getnameinfoPointer = &getnameinfo;\n        getaddrinfoPointer = &getaddrinfo;\n        freeaddrinfoPointer = &freeaddrinfo;\n    }\n}\n\n\nshared static ~this() @system nothrow @nogc\n{\n    version (Windows)\n    {\n        WSACleanup();\n    }\n}\n\n/**\n * The communication domain used to resolve an address.\n */\nenum AddressFamily: int\n{\n    UNSPEC =     AF_UNSPEC,     /// Unspecified address family\n    UNIX =       AF_UNIX,       /// Local communication\n    INET =       AF_INET,       /// Internet Protocol version 4\n    IPX =        AF_IPX,        /// Novell IPX\n    APPLETALK =  AF_APPLETALK,  /// AppleTalk\n    INET6 =      AF_INET6,      /// Internet Protocol version 6\n}\n\n\n/**\n * Communication semantics\n */\nenum SocketType: int\n{\n    STREAM =     SOCK_STREAM,           /// Sequenced, reliable, two-way communication-based byte streams\n    DGRAM =      SOCK_DGRAM,            /// Connectionless, unreliable datagrams with a fixed maximum length; data may be lost or arrive out of order\n    RAW =        SOCK_RAW,              /// Raw protocol access\n    RDM =        SOCK_RDM,              /// Reliably-delivered message datagrams\n    SEQPACKET =  SOCK_SEQPACKET,        /// Sequenced, reliable, two-way connection-based datagrams with a fixed maximum length\n}\n\n\n/**\n * Protocol\n */\nenum ProtocolType: int\n{\n    IP =    IPPROTO_IP,         /// Internet Protocol version 4\n    ICMP =  IPPROTO_ICMP,       /// Internet Control Message Protocol\n    IGMP =  IPPROTO_IGMP,       /// Internet Group Management Protocol\n    GGP =   IPPROTO_GGP,        /// Gateway to Gateway Protocol\n    TCP =   IPPROTO_TCP,        /// Transmission Control Protocol\n    PUP =   IPPROTO_PUP,        /// PARC Universal Packet Protocol\n    UDP =   IPPROTO_UDP,        /// User Datagram Protocol\n    IDP =   IPPROTO_IDP,        /// Xerox NS protocol\n    RAW =   IPPROTO_RAW,        /// Raw IP packets\n    IPV6 =  IPPROTO_IPV6,       /// Internet Protocol version 6\n}\n\n\n/**\n * `Protocol` is a class for retrieving protocol information.\n *\n * Example:\n * ---\n * auto proto = new Protocol;\n * writeln(\"About protocol TCP:\");\n * if (proto.getProtocolByType(ProtocolType.TCP))\n * {\n *     writefln(\"  Name: %s\", proto.name);\n *     foreach (string s; proto.aliases)\n *          writefln(\"  Alias: %s\", s);\n * }\n * else\n *     writeln(\"  No information found\");\n * ---\n */\nclass Protocol\n{\n    /// These members are populated when one of the following functions are called successfully:\n    ProtocolType type;\n    string name;                /// ditto\n    string[] aliases;           /// ditto\n\n\n    void populate(protoent* proto) @system pure nothrow\n    {\n        type = cast(ProtocolType) proto.p_proto;\n        name = to!string(proto.p_name);\n\n        int i;\n        for (i = 0;; i++)\n        {\n            if (!proto.p_aliases[i])\n                break;\n        }\n\n        if (i)\n        {\n            aliases = new string[i];\n            for (i = 0; i != aliases.length; i++)\n            {\n                aliases[i] =\n                    to!string(proto.p_aliases[i]);\n            }\n        }\n        else\n        {\n            aliases = null;\n        }\n    }\n\n    /** Returns: false on failure */\n    bool getProtocolByName(scope const(char)[] name) @trusted nothrow\n    {\n        protoent* proto;\n        proto = getprotobyname(name.tempCString());\n        if (!proto)\n            return false;\n        populate(proto);\n        return true;\n    }\n\n\n    /** Returns: false on failure */\n    // Same as getprotobynumber().\n    bool getProtocolByType(ProtocolType type) @trusted nothrow\n    {\n        protoent* proto;\n        proto = getprotobynumber(type);\n        if (!proto)\n            return false;\n        populate(proto);\n        return true;\n    }\n}\n\n\n// Skip this test on Android because getprotobyname/number are\n// unimplemented in bionic.\nversion (CRuntime_Bionic) {} else\n@safe unittest\n{\n    // import std.stdio : writefln;\n    softUnittest({\n        Protocol proto = new Protocol;\n        assert(proto.getProtocolByType(ProtocolType.TCP));\n        //writeln(\"About protocol TCP:\");\n        //writefln(\"\\tName: %s\", proto.name);\n        // foreach (string s; proto.aliases)\n        // {\n        //      writefln(\"\\tAlias: %s\", s);\n        // }\n        assert(proto.name == \"tcp\");\n        assert(proto.aliases.length == 1 && proto.aliases[0] == \"TCP\");\n    });\n}\n\n\n/**\n * `Service` is a class for retrieving service information.\n *\n * Example:\n * ---\n * auto serv = new Service;\n * writeln(\"About service epmap:\");\n * if (serv.getServiceByName(\"epmap\", \"tcp\"))\n * {\n *     writefln(\"  Service: %s\", serv.name);\n *     writefln(\"  Port: %d\", serv.port);\n *     writefln(\"  Protocol: %s\", serv.protocolName);\n *     foreach (string s; serv.aliases)\n *          writefln(\"  Alias: %s\", s);\n * }\n * else\n *     writefln(\"  No service for epmap.\");\n * ---\n */\nclass Service\n{\n    /// These members are populated when one of the following functions are called successfully:\n    string name;\n    string[] aliases;           /// ditto\n    ushort port;                /// ditto\n    string protocolName;        /// ditto\n\n\n    void populate(servent* serv) @system pure nothrow\n    {\n        name = to!string(serv.s_name);\n        port = ntohs(cast(ushort) serv.s_port);\n        protocolName = to!string(serv.s_proto);\n\n        int i;\n        for (i = 0;; i++)\n        {\n            if (!serv.s_aliases[i])\n                break;\n        }\n\n        if (i)\n        {\n            aliases = new string[i];\n            for (i = 0; i != aliases.length; i++)\n            {\n                aliases[i] =\n                    to!string(serv.s_aliases[i]);\n            }\n        }\n        else\n        {\n            aliases = null;\n        }\n    }\n\n    /**\n     * If a protocol name is omitted, any protocol will be matched.\n     * Returns: false on failure.\n     */\n    bool getServiceByName(scope const(char)[] name, scope const(char)[] protocolName = null) @trusted nothrow\n    {\n        servent* serv;\n        serv = getservbyname(name.tempCString(), protocolName.tempCString());\n        if (!serv)\n            return false;\n        populate(serv);\n        return true;\n    }\n\n\n    /// ditto\n    bool getServiceByPort(ushort port, scope const(char)[] protocolName = null) @trusted nothrow\n    {\n        servent* serv;\n        serv = getservbyport(port, protocolName.tempCString());\n        if (!serv)\n            return false;\n        populate(serv);\n        return true;\n    }\n}\n\n\n@safe unittest\n{\n    import std.stdio : writefln;\n    softUnittest({\n        Service serv = new Service;\n        if (serv.getServiceByName(\"epmap\", \"tcp\"))\n        {\n            // writefln(\"About service epmap:\");\n            // writefln(\"\\tService: %s\", serv.name);\n            // writefln(\"\\tPort: %d\", serv.port);\n            // writefln(\"\\tProtocol: %s\", serv.protocolName);\n            // foreach (string s; serv.aliases)\n            // {\n            //      writefln(\"\\tAlias: %s\", s);\n            // }\n            // For reasons unknown this is loc-srv on Wine and epmap on Windows\n            assert(serv.name == \"loc-srv\" || serv.name == \"epmap\", serv.name);\n            assert(serv.port == 135);\n            assert(serv.protocolName == \"tcp\");\n        }\n        else\n        {\n            writefln(\"No service for epmap.\");\n        }\n    });\n}\n\n\nprivate mixin template socketOSExceptionCtors()\n{\n    ///\n    this(string msg, string file = __FILE__, size_t line = __LINE__,\n         Throwable next = null, int err = _lasterr())\n    {\n        super(msg, file, line, next, err);\n    }\n\n    ///\n    this(string msg, Throwable next, string file = __FILE__,\n         size_t line = __LINE__, int err = _lasterr())\n    {\n        super(msg, next, file, line, err);\n    }\n\n    ///\n    this(string msg, int err, string file = __FILE__, size_t line = __LINE__,\n         Throwable next = null)\n    {\n        super(msg, next, file, line, err);\n    }\n}\n\n\n/**\n * Class for exceptions thrown from an `InternetHost`.\n */\nclass HostException: SocketOSException\n{\n    mixin socketOSExceptionCtors;\n}\n\n/**\n * `InternetHost` is a class for resolving IPv4 addresses.\n *\n * Consider using `getAddress`, `parseAddress` and `Address` methods\n * instead of using this class directly.\n */\nclass InternetHost\n{\n    /// These members are populated when one of the following functions are called successfully:\n    string name;\n    string[] aliases;           /// ditto\n    uint[] addrList;            /// ditto\n\n\n    void validHostent(in hostent* he)\n    {\n        if (he.h_addrtype != cast(int) AddressFamily.INET || he.h_length != 4)\n            throw new HostException(\"Address family mismatch\");\n    }\n\n\n    void populate(hostent* he) @system pure nothrow\n    {\n        int i;\n        char* p;\n\n        name = to!string(he.h_name);\n\n        for (i = 0;; i++)\n        {\n            p = he.h_aliases[i];\n            if (!p)\n                break;\n        }\n\n        if (i)\n        {\n            aliases = new string[i];\n            for (i = 0; i != aliases.length; i++)\n            {\n                aliases[i] =\n                    to!string(he.h_aliases[i]);\n            }\n        }\n        else\n        {\n            aliases = null;\n        }\n\n        for (i = 0;; i++)\n        {\n            p = he.h_addr_list[i];\n            if (!p)\n                break;\n        }\n\n        if (i)\n        {\n            addrList = new uint[i];\n            for (i = 0; i != addrList.length; i++)\n            {\n                addrList[i] = ntohl(*(cast(uint*) he.h_addr_list[i]));\n            }\n        }\n        else\n        {\n            addrList = null;\n        }\n    }\n\n    private bool getHostNoSync(string opMixin, T)(T param) @system\n    {\n        mixin(opMixin);\n        if (!he)\n            return false;\n        validHostent(he);\n        populate(he);\n        return true;\n    }\n\n    version (Windows)\n        alias getHost = getHostNoSync;\n    else\n    {\n        // posix systems use global state for return value, so we\n        // must synchronize across all threads\n        private bool getHost(string opMixin, T)(T param) @system\n        {\n            synchronized(this.classinfo)\n                return getHostNoSync!(opMixin, T)(param);\n        }\n    }\n\n    /**\n     * Resolve host name.\n     * Returns: false if unable to resolve.\n     */\n    bool getHostByName(scope const(char)[] name) @trusted\n    {\n        static if (is(typeof(gethostbyname_r)))\n        {\n            return getHostNoSync!q{\n                hostent he_v;\n                hostent* he;\n                ubyte[256] buffer_v = void;\n                auto buffer = buffer_v[];\n                auto param_zTmp = param.tempCString();\n                while (true)\n                {\n                    he = &he_v;\n                    int errno;\n                    if (gethostbyname_r(param_zTmp, he, buffer.ptr, buffer.length, &he, &errno) == ERANGE)\n                        buffer.length = buffer.length * 2;\n                    else\n                        break;\n                }\n            }(name);\n        }\n        else\n        {\n            return getHost!q{\n                auto he = gethostbyname(param.tempCString());\n            }(name);\n        }\n    }\n\n    /**\n     * Resolve IPv4 address number.\n     *\n     * Params:\n     *   addr = The IPv4 address to resolve, in host byte order.\n     * Returns:\n     *   false if unable to resolve.\n     */\n    bool getHostByAddr(uint addr) @trusted\n    {\n        return getHost!q{\n            auto x = htonl(param);\n            auto he = gethostbyaddr(&x, 4, cast(int) AddressFamily.INET);\n        }(addr);\n    }\n\n    /**\n     * Same as previous, but addr is an IPv4 address string in the\n     * dotted-decimal form $(I a.b.c.d).\n     * Returns: false if unable to resolve.\n     */\n    bool getHostByAddr(scope const(char)[] addr) @trusted\n    {\n        return getHost!q{\n            auto x = inet_addr(param.tempCString());\n            enforce(x != INADDR_NONE,\n                new SocketParameterException(\"Invalid IPv4 address\"));\n            auto he = gethostbyaddr(&x, 4, cast(int) AddressFamily.INET);\n        }(addr);\n    }\n}\n\n///\n@safe unittest\n{\n    InternetHost ih = new InternetHost;\n\n    ih.getHostByAddr(0x7F_00_00_01);\n    assert(ih.addrList[0] == 0x7F_00_00_01);\n    ih.getHostByAddr(\"127.0.0.1\");\n    assert(ih.addrList[0] == 0x7F_00_00_01);\n\n    if (!ih.getHostByName(\"www.digitalmars.com\"))\n        return;             // don't fail if not connected to internet\n\n    assert(ih.addrList.length);\n    InternetAddress ia = new InternetAddress(ih.addrList[0], InternetAddress.PORT_ANY);\n    assert(ih.name == \"www.digitalmars.com\" || ih.name == \"digitalmars.com\",\n            ih.name);\n\n    assert(ih.getHostByAddr(ih.addrList[0]));\n    string getHostNameFromInt = ih.name.dup;\n\n    assert(ih.getHostByAddr(ia.toAddrString()));\n    string getHostNameFromStr = ih.name.dup;\n\n    assert(getHostNameFromInt == getHostNameFromStr);\n}\n\n\n/// Holds information about a socket _address retrieved by `getAddressInfo`.\nstruct AddressInfo\n{\n    AddressFamily family;   /// Address _family\n    SocketType type;        /// Socket _type\n    ProtocolType protocol;  /// Protocol\n    Address address;        /// Socket _address\n    string canonicalName;   /// Canonical name, when `AddressInfoFlags.CANONNAME` is used.\n}\n\n/**\n * A subset of flags supported on all platforms with getaddrinfo.\n * Specifies option flags for `getAddressInfo`.\n */\nenum AddressInfoFlags: int\n{\n    /// The resulting addresses will be used in a call to `Socket.bind`.\n    PASSIVE = AI_PASSIVE,\n\n    /// The canonical name is returned in `canonicalName` member in the first `AddressInfo`.\n    CANONNAME = AI_CANONNAME,\n\n    /**\n     * The `node` parameter passed to `getAddressInfo` must be a numeric string.\n     * This will suppress any potentially lengthy network host address lookups.\n     */\n    NUMERICHOST = AI_NUMERICHOST,\n}\n\n\n/**\n * On POSIX, getaddrinfo uses its own error codes, and thus has its own\n * formatting function.\n */\nprivate string formatGaiError(int err) @trusted\n{\n    version (Windows)\n    {\n        return sysErrorString(err);\n    }\n    else\n    {\n        synchronized\n            return to!string(gai_strerror(err));\n    }\n}\n\n/**\n * Provides _protocol-independent translation from host names to socket\n * addresses. If advanced functionality is not required, consider using\n * `getAddress` for compatibility with older systems.\n *\n * Returns: Array with one `AddressInfo` per socket address.\n *\n * Throws: `SocketOSException` on failure, or `SocketFeatureException`\n * if this functionality is not available on the current system.\n *\n * Params:\n *  node     = string containing host name or numeric address\n *  options  = optional additional parameters, identified by type:\n *             $(UL $(LI `string` - service name or port number)\n *                  $(LI `AddressInfoFlags` - option flags)\n *                  $(LI `AddressFamily` - address family to filter by)\n *                  $(LI `SocketType` - socket type to filter by)\n *                  $(LI `ProtocolType` - protocol to filter by))\n *\n * Example:\n * ---\n * // Roundtrip DNS resolution\n * auto results = getAddressInfo(\"www.digitalmars.com\");\n * assert(results[0].address.toHostNameString() ==\n *     \"digitalmars.com\");\n *\n * // Canonical name\n * results = getAddressInfo(\"www.digitalmars.com\",\n *     AddressInfoFlags.CANONNAME);\n * assert(results[0].canonicalName == \"digitalmars.com\");\n *\n * // IPv6 resolution\n * results = getAddressInfo(\"ipv6.google.com\");\n * assert(results[0].family == AddressFamily.INET6);\n *\n * // Multihomed resolution\n * results = getAddressInfo(\"google.com\");\n * assert(results.length > 1);\n *\n * // Parsing IPv4\n * results = getAddressInfo(\"127.0.0.1\",\n *     AddressInfoFlags.NUMERICHOST);\n * assert(results.length && results[0].family ==\n *     AddressFamily.INET);\n *\n * // Parsing IPv6\n * results = getAddressInfo(\"::1\",\n *     AddressInfoFlags.NUMERICHOST);\n * assert(results.length && results[0].family ==\n *     AddressFamily.INET6);\n * ---\n */\nAddressInfo[] getAddressInfo(T...)(scope const(char)[] node, scope T options)\n{\n    const(char)[] service = null;\n    addrinfo hints;\n    hints.ai_family = AF_UNSPEC;\n\n    foreach (i, option; options)\n    {\n        static if (is(typeof(option) : const(char)[]))\n            service = options[i];\n        else\n        static if (is(typeof(option) == AddressInfoFlags))\n            hints.ai_flags |= option;\n        else\n        static if (is(typeof(option) == AddressFamily))\n            hints.ai_family = option;\n        else\n        static if (is(typeof(option) == SocketType))\n            hints.ai_socktype = option;\n        else\n        static if (is(typeof(option) == ProtocolType))\n            hints.ai_protocol = option;\n        else\n            static assert(0, \"Unknown getAddressInfo option type: \" ~ typeof(option).stringof);\n    }\n\n    return () @trusted { return getAddressInfoImpl(node, service, &hints); }();\n}\n\n@system unittest\n{\n    struct Oops\n    {\n        const(char[]) breakSafety()\n        {\n            *cast(int*) 0xcafebabe = 0xdeadbeef;\n            return null;\n        }\n        alias breakSafety this;\n    }\n    assert(!__traits(compiles, () {\n        getAddressInfo(\"\", Oops.init);\n    }), \"getAddressInfo breaks @safe\");\n}\n\nprivate AddressInfo[] getAddressInfoImpl(scope const(char)[] node, scope const(char)[] service, addrinfo* hints) @system\n{\n        import std.array : appender;\n\n    if (getaddrinfoPointer && freeaddrinfoPointer)\n    {\n        addrinfo* ai_res;\n\n        int ret = getaddrinfoPointer(\n            node.tempCString(),\n            service.tempCString(),\n            hints, &ai_res);\n        enforce(ret == 0, new SocketOSException(\"getaddrinfo error\", ret, &formatGaiError));\n        scope(exit) freeaddrinfoPointer(ai_res);\n\n        auto result = appender!(AddressInfo[])();\n\n        // Use const to force UnknownAddressReference to copy the sockaddr.\n        for (const(addrinfo)* ai = ai_res; ai; ai = ai.ai_next)\n            result ~= AddressInfo(\n                cast(AddressFamily) ai.ai_family,\n                cast(SocketType   ) ai.ai_socktype,\n                cast(ProtocolType ) ai.ai_protocol,\n                new UnknownAddressReference(ai.ai_addr, cast(socklen_t) ai.ai_addrlen),\n                ai.ai_canonname ? to!string(ai.ai_canonname) : null);\n\n        assert(result.data.length > 0);\n        return result.data;\n    }\n\n    throw new SocketFeatureException(\"Address info lookup is not available \" ~\n        \"on this system.\");\n}\n\n\n@safe unittest\n{\n    softUnittest({\n        if (getaddrinfoPointer)\n        {\n            // Roundtrip DNS resolution\n            auto results = getAddressInfo(\"www.digitalmars.com\");\n            assert(results[0].address.toHostNameString() == \"digitalmars.com\");\n\n            // Canonical name\n            results = getAddressInfo(\"www.digitalmars.com\",\n                AddressInfoFlags.CANONNAME);\n            assert(results[0].canonicalName == \"digitalmars.com\");\n\n            // IPv6 resolution\n            //results = getAddressInfo(\"ipv6.google.com\");\n            //assert(results[0].family == AddressFamily.INET6);\n\n            // Multihomed resolution\n            //results = getAddressInfo(\"google.com\");\n            //assert(results.length > 1);\n\n            // Parsing IPv4\n            results = getAddressInfo(\"127.0.0.1\", AddressInfoFlags.NUMERICHOST);\n            assert(results.length && results[0].family == AddressFamily.INET);\n\n            // Parsing IPv6\n            results = getAddressInfo(\"::1\", AddressInfoFlags.NUMERICHOST);\n            assert(results.length && results[0].family == AddressFamily.INET6);\n        }\n    });\n\n    if (getaddrinfoPointer)\n    {\n        auto results = getAddressInfo(null, \"1234\", AddressInfoFlags.PASSIVE,\n                                      SocketType.STREAM, ProtocolType.TCP, AddressFamily.INET);\n        assert(results.length == 1 && results[0].address.toString() == \"0.0.0.0:1234\");\n    }\n}\n\n\nprivate ushort serviceToPort(scope const(char)[] service)\n{\n    if (service == \"\")\n        return InternetAddress.PORT_ANY;\n    else\n    if (isNumeric(service))\n        return to!ushort(service);\n    else\n    {\n        auto s = new Service();\n        s.getServiceByName(service);\n        return s.port;\n    }\n}\n\n/**\n * Provides _protocol-independent translation from host names to socket\n * addresses. Uses `getAddressInfo` if the current system supports it,\n * and `InternetHost` otherwise.\n *\n * Returns: Array with one `Address` instance per socket address.\n *\n * Throws: `SocketOSException` on failure.\n *\n * Example:\n * ---\n * writeln(\"Resolving www.digitalmars.com:\");\n * try\n * {\n *     auto addresses = getAddress(\"www.digitalmars.com\");\n *     foreach (address; addresses)\n *         writefln(\"  IP: %s\", address.toAddrString());\n * }\n * catch (SocketException e)\n *     writefln(\"  Lookup failed: %s\", e.msg);\n * ---\n */\nAddress[] getAddress(scope const(char)[] hostname, scope const(char)[] service = null)\n{\n    if (getaddrinfoPointer && freeaddrinfoPointer)\n    {\n        // use getAddressInfo\n        auto infos = getAddressInfo(hostname, service);\n        Address[] results;\n        results.length = infos.length;\n        foreach (i, ref result; results)\n            result = infos[i].address;\n        return results;\n    }\n    else\n        return getAddress(hostname, serviceToPort(service));\n}\n\n/// ditto\nAddress[] getAddress(scope const(char)[] hostname, ushort port)\n{\n    if (getaddrinfoPointer && freeaddrinfoPointer)\n        return getAddress(hostname, to!string(port));\n    else\n    {\n        // use getHostByName\n        auto ih = new InternetHost;\n        if (!ih.getHostByName(hostname))\n            throw new AddressException(\n                        text(\"Unable to resolve host '\", hostname, \"'\"));\n\n        Address[] results;\n        foreach (uint addr; ih.addrList)\n            results ~= new InternetAddress(addr, port);\n        return results;\n    }\n}\n\n\n@safe unittest\n{\n    softUnittest({\n        auto addresses = getAddress(\"63.105.9.61\");\n        assert(addresses.length && addresses[0].toAddrString() == \"63.105.9.61\");\n\n        if (getaddrinfoPointer)\n        {\n            // test via gethostbyname\n            auto getaddrinfoPointerBackup = getaddrinfoPointer;\n            cast() getaddrinfoPointer = null;\n            scope(exit) cast() getaddrinfoPointer = getaddrinfoPointerBackup;\n\n            addresses = getAddress(\"63.105.9.61\");\n            assert(addresses.length && addresses[0].toAddrString() == \"63.105.9.61\");\n        }\n    });\n}\n\n\n/**\n * Provides _protocol-independent parsing of network addresses. Does not\n * attempt name resolution. Uses `getAddressInfo` with\n * `AddressInfoFlags.NUMERICHOST` if the current system supports it, and\n * `InternetAddress` otherwise.\n *\n * Returns: An `Address` instance representing specified address.\n *\n * Throws: `SocketException` on failure.\n *\n * Example:\n * ---\n * writeln(\"Enter IP address:\");\n * string ip = readln().chomp();\n * try\n * {\n *     Address address = parseAddress(ip);\n *     writefln(\"Looking up reverse of %s:\",\n *         address.toAddrString());\n *     try\n *     {\n *         string reverse = address.toHostNameString();\n *         if (reverse)\n *             writefln(\"  Reverse name: %s\", reverse);\n *         else\n *             writeln(\"  Reverse hostname not found.\");\n *     }\n *     catch (SocketException e)\n *         writefln(\"  Lookup error: %s\", e.msg);\n * }\n * catch (SocketException e)\n * {\n *     writefln(\"  %s is not a valid IP address: %s\",\n *         ip, e.msg);\n * }\n * ---\n */\nAddress parseAddress(scope const(char)[] hostaddr, scope const(char)[] service = null)\n{\n    if (getaddrinfoPointer && freeaddrinfoPointer)\n        return getAddressInfo(hostaddr, service, AddressInfoFlags.NUMERICHOST)[0].address;\n    else\n        return parseAddress(hostaddr, serviceToPort(service));\n}\n\n/// ditto\nAddress parseAddress(scope const(char)[] hostaddr, ushort port)\n{\n    if (getaddrinfoPointer && freeaddrinfoPointer)\n        return parseAddress(hostaddr, to!string(port));\n    else\n    {\n        auto in4_addr = InternetAddress.parse(hostaddr);\n        enforce(in4_addr != InternetAddress.ADDR_NONE,\n            new SocketParameterException(\"Invalid IP address\"));\n        return new InternetAddress(in4_addr, port);\n    }\n}\n\n\n@safe unittest\n{\n    softUnittest({\n        auto address = parseAddress(\"63.105.9.61\");\n        assert(address.toAddrString() == \"63.105.9.61\");\n\n        if (getaddrinfoPointer)\n        {\n            // test via inet_addr\n            auto getaddrinfoPointerBackup = getaddrinfoPointer;\n            cast() getaddrinfoPointer = null;\n            scope(exit) cast() getaddrinfoPointer = getaddrinfoPointerBackup;\n\n            address = parseAddress(\"63.105.9.61\");\n            assert(address.toAddrString() == \"63.105.9.61\");\n        }\n\n        assert(collectException!SocketException(parseAddress(\"Invalid IP address\")));\n    });\n}\n\n\n/**\n * Class for exceptions thrown from an `Address`.\n */\nclass AddressException: SocketOSException\n{\n    mixin socketOSExceptionCtors;\n}\n\n\n/**\n * `Address` is an abstract class for representing a socket addresses.\n *\n * Example:\n * ---\n * writeln(\"About www.google.com port 80:\");\n * try\n * {\n *     Address[] addresses = getAddress(\"www.google.com\", 80);\n *     writefln(\"  %d addresses found.\", addresses.length);\n *     foreach (int i, Address a; addresses)\n *     {\n *         writefln(\"  Address %d:\", i+1);\n *         writefln(\"    IP address: %s\", a.toAddrString());\n *         writefln(\"    Hostname: %s\", a.toHostNameString());\n *         writefln(\"    Port: %s\", a.toPortString());\n *         writefln(\"    Service name: %s\",\n *             a.toServiceNameString());\n *     }\n * }\n * catch (SocketException e)\n *     writefln(\"  Lookup error: %s\", e.msg);\n * ---\n */\nabstract class Address\n{\n    /// Returns pointer to underlying `sockaddr` structure.\n    abstract @property sockaddr* name() pure nothrow @nogc;\n    abstract @property const(sockaddr)* name() const pure nothrow @nogc; /// ditto\n\n    /// Returns actual size of underlying `sockaddr` structure.\n    abstract @property socklen_t nameLen() const pure nothrow @nogc;\n\n    // Socket.remoteAddress, Socket.localAddress, and Socket.receiveFrom\n    // use setNameLen to set the actual size of the address as returned by\n    // getsockname, getpeername, and recvfrom, respectively.\n    // The following implementation is sufficient for fixed-length addresses,\n    // and ensures that the length is not changed.\n    // Must be overridden for variable-length addresses.\n    protected void setNameLen(socklen_t len)\n    {\n        if (len != this.nameLen)\n            throw new AddressException(\n                format(\"%s expects address of length %d, not %d\", typeid(this),\n                    this.nameLen, len), 0);\n    }\n\n    /// Family of this address.\n    @property AddressFamily addressFamily() const pure nothrow @nogc\n    {\n        return cast(AddressFamily) name.sa_family;\n    }\n\n    // Common code for toAddrString and toHostNameString\n    private string toHostString(bool numeric) @trusted const\n    {\n        // getnameinfo() is the recommended way to perform a reverse (name)\n        // lookup on both Posix and Windows. However, it is only available\n        // on Windows XP and above, and not included with the WinSock import\n        // libraries shipped with DMD. Thus, we check for getnameinfo at\n        // runtime in the shared module constructor, and use it if it's\n        // available in the base class method. Classes for specific network\n        // families (e.g. InternetHost) override this method and use a\n        // deprecated, albeit commonly-available method when getnameinfo()\n        // is not available.\n        // http://technet.microsoft.com/en-us/library/aa450403.aspx\n        if (getnameinfoPointer)\n        {\n            auto buf = new char[NI_MAXHOST];\n            auto ret = getnameinfoPointer(\n                        name, nameLen,\n                        buf.ptr, cast(uint) buf.length,\n                        null, 0,\n                        numeric ? NI_NUMERICHOST : NI_NAMEREQD);\n\n            if (!numeric)\n            {\n                if (ret == EAI_NONAME)\n                    return null;\n                version (Windows)\n                    if (ret == WSANO_DATA)\n                        return null;\n            }\n\n            enforce(ret == 0, new AddressException(\"Could not get \" ~\n                        (numeric ? \"host address\" : \"host name\")));\n            return assumeUnique(buf[0 .. strlen(buf.ptr)]);\n        }\n\n        throw new SocketFeatureException((numeric ? \"Host address\" : \"Host name\") ~\n            \" lookup for this address family is not available on this system.\");\n    }\n\n    // Common code for toPortString and toServiceNameString\n    private string toServiceString(bool numeric) @trusted const\n    {\n        // See toHostNameString() for details about getnameinfo().\n        if (getnameinfoPointer)\n        {\n            auto buf = new char[NI_MAXSERV];\n            enforce(getnameinfoPointer(\n                        name, nameLen,\n                        null, 0,\n                        buf.ptr, cast(uint) buf.length,\n                        numeric ? NI_NUMERICSERV : NI_NAMEREQD\n                    ) == 0, new AddressException(\"Could not get \" ~\n                        (numeric ? \"port number\" : \"service name\")));\n            return assumeUnique(buf[0 .. strlen(buf.ptr)]);\n        }\n\n        throw new SocketFeatureException((numeric ? \"Port number\" : \"Service name\") ~\n            \" lookup for this address family is not available on this system.\");\n    }\n\n    /**\n     * Attempts to retrieve the host address as a human-readable string.\n     *\n     * Throws: `AddressException` on failure, or `SocketFeatureException`\n     * if address retrieval for this address family is not available on the\n     * current system.\n     */\n    string toAddrString() const\n    {\n        return toHostString(true);\n    }\n\n    /**\n     * Attempts to retrieve the host name as a fully qualified domain name.\n     *\n     * Returns: The FQDN corresponding to this `Address`, or `null` if\n     * the host name did not resolve.\n     *\n     * Throws: `AddressException` on error, or `SocketFeatureException`\n     * if host name lookup for this address family is not available on the\n     * current system.\n     */\n    string toHostNameString() const\n    {\n        return toHostString(false);\n    }\n\n    /**\n     * Attempts to retrieve the numeric port number as a string.\n     *\n     * Throws: `AddressException` on failure, or `SocketFeatureException`\n     * if port number retrieval for this address family is not available on the\n     * current system.\n     */\n    string toPortString() const\n    {\n        return toServiceString(true);\n    }\n\n    /**\n     * Attempts to retrieve the service name as a string.\n     *\n     * Throws: `AddressException` on failure, or `SocketFeatureException`\n     * if service name lookup for this address family is not available on the\n     * current system.\n     */\n    string toServiceNameString() const\n    {\n        return toServiceString(false);\n    }\n\n    /// Human readable string representing this address.\n    override string toString() const\n    {\n        try\n        {\n            string host = toAddrString();\n            string port = toPortString();\n            if (host.indexOf(':') >= 0)\n                return \"[\" ~ host ~ \"]:\" ~ port;\n            else\n                return host ~ \":\" ~ port;\n        }\n        catch (SocketException)\n            return \"Unknown\";\n    }\n}\n\n/**\n * `UnknownAddress` encapsulates an unknown socket address.\n */\nclass UnknownAddress: Address\n{\nprotected:\n    sockaddr sa;\n\n\npublic:\n    override @property sockaddr* name()\n    {\n        return &sa;\n    }\n\n    override @property const(sockaddr)* name() const\n    {\n        return &sa;\n    }\n\n\n    override @property socklen_t nameLen() const\n    {\n        return cast(socklen_t) sa.sizeof;\n    }\n\n}\n\n\n/**\n * `UnknownAddressReference` encapsulates a reference to an arbitrary\n * socket address.\n */\nclass UnknownAddressReference: Address\n{\nprotected:\n    sockaddr* sa;\n    socklen_t len;\n\npublic:\n    /// Constructs an `Address` with a reference to the specified `sockaddr`.\n    this(sockaddr* sa, socklen_t len) pure nothrow @nogc\n    {\n        this.sa  = sa;\n        this.len = len;\n    }\n\n    /// Constructs an `Address` with a copy of the specified `sockaddr`.\n    this(const(sockaddr)* sa, socklen_t len) @system pure nothrow\n    {\n        this.sa = cast(sockaddr*) (cast(ubyte*) sa)[0 .. len].dup.ptr;\n        this.len = len;\n    }\n\n    override @property sockaddr* name()\n    {\n        return sa;\n    }\n\n    override @property const(sockaddr)* name() const\n    {\n        return sa;\n    }\n\n\n    override @property socklen_t nameLen() const\n    {\n        return cast(socklen_t) len;\n    }\n}\n\n\n/**\n * `InternetAddress` encapsulates an IPv4 (Internet Protocol version 4)\n * socket address.\n *\n * Consider using `getAddress`, `parseAddress` and `Address` methods\n * instead of using this class directly.\n */\nclass InternetAddress: Address\n{\nprotected:\n    sockaddr_in sin;\n\n\n    this() pure nothrow @nogc\n    {\n    }\n\n\npublic:\n    override @property sockaddr* name()\n    {\n        return cast(sockaddr*)&sin;\n    }\n\n    override @property const(sockaddr)* name() const\n    {\n        return cast(const(sockaddr)*)&sin;\n    }\n\n\n    override @property socklen_t nameLen() const\n    {\n        return cast(socklen_t) sin.sizeof;\n    }\n\n\n    enum uint ADDR_ANY = INADDR_ANY;         /// Any IPv4 host address.\n    enum uint ADDR_NONE = INADDR_NONE;       /// An invalid IPv4 host address.\n    enum ushort PORT_ANY = 0;                /// Any IPv4 port number.\n\n    /// Returns the IPv4 _port number (in host byte order).\n    @property ushort port() const pure nothrow @nogc\n    {\n        return ntohs(sin.sin_port);\n    }\n\n    /// Returns the IPv4 address number (in host byte order).\n    @property uint addr() const pure nothrow @nogc\n    {\n        return ntohl(sin.sin_addr.s_addr);\n    }\n\n    /**\n     * Construct a new `InternetAddress`.\n     * Params:\n     *   addr = an IPv4 address string in the dotted-decimal form a.b.c.d,\n     *          or a host name which will be resolved using an `InternetHost`\n     *          object.\n     *   port = port number, may be `PORT_ANY`.\n     */\n    this(scope const(char)[] addr, ushort port)\n    {\n        uint uiaddr = parse(addr);\n        if (ADDR_NONE == uiaddr)\n        {\n            InternetHost ih = new InternetHost;\n            if (!ih.getHostByName(addr))\n                //throw new AddressException(\"Invalid internet address\");\n                throw new AddressException(\n                          text(\"Unable to resolve host '\", addr, \"'\"));\n            uiaddr = ih.addrList[0];\n        }\n        sin.sin_family = AddressFamily.INET;\n        sin.sin_addr.s_addr = htonl(uiaddr);\n        sin.sin_port = htons(port);\n    }\n\n    /**\n     * Construct a new `InternetAddress`.\n     * Params:\n     *   addr = (optional) an IPv4 address in host byte order, may be `ADDR_ANY`.\n     *   port = port number, may be `PORT_ANY`.\n     */\n    this(uint addr, ushort port) pure nothrow @nogc\n    {\n        sin.sin_family = AddressFamily.INET;\n        sin.sin_addr.s_addr = htonl(addr);\n        sin.sin_port = htons(port);\n    }\n\n    /// ditto\n    this(ushort port) pure nothrow @nogc\n    {\n        sin.sin_family = AddressFamily.INET;\n        sin.sin_addr.s_addr = ADDR_ANY;\n        sin.sin_port = htons(port);\n    }\n\n    /**\n     * Construct a new `InternetAddress`.\n     * Params:\n     *   addr = A sockaddr_in as obtained from lower-level API calls such as getifaddrs.\n     */\n    this(sockaddr_in addr) pure nothrow @nogc\n    {\n        assert(addr.sin_family == AddressFamily.INET);\n        sin = addr;\n    }\n\n    /// Human readable string representing the IPv4 address in dotted-decimal form.\n    override string toAddrString() @trusted const\n    {\n        return to!string(inet_ntoa(sin.sin_addr));\n    }\n\n    /// Human readable string representing the IPv4 port.\n    override string toPortString() const\n    {\n        return std.conv.to!string(port);\n    }\n\n    /**\n     * Attempts to retrieve the host name as a fully qualified domain name.\n     *\n     * Returns: The FQDN corresponding to this `InternetAddress`, or\n     * `null` if the host name did not resolve.\n     *\n     * Throws: `AddressException` on error.\n     */\n    override string toHostNameString() const\n    {\n        // getnameinfo() is the recommended way to perform a reverse (name)\n        // lookup on both Posix and Windows. However, it is only available\n        // on Windows XP and above, and not included with the WinSock import\n        // libraries shipped with DMD. Thus, we check for getnameinfo at\n        // runtime in the shared module constructor, and fall back to the\n        // deprecated getHostByAddr() if it could not be found. See also:\n        // http://technet.microsoft.com/en-us/library/aa450403.aspx\n\n        if (getnameinfoPointer)\n            return super.toHostNameString();\n        else\n        {\n            auto host = new InternetHost();\n            if (!host.getHostByAddr(ntohl(sin.sin_addr.s_addr)))\n                return null;\n            return host.name;\n        }\n    }\n\n    /**\n     * Compares with another InternetAddress of same type for equality\n     * Returns: true if the InternetAddresses share the same address and\n     * port number.\n     */\n    override bool opEquals(Object o) const\n    {\n        auto other = cast(InternetAddress) o;\n        return other && this.sin.sin_addr.s_addr == other.sin.sin_addr.s_addr &&\n            this.sin.sin_port == other.sin.sin_port;\n    }\n\n    ///\n    @system unittest\n    {\n        auto addr1 = new InternetAddress(\"127.0.0.1\", 80);\n        auto addr2 = new InternetAddress(\"127.0.0.2\", 80);\n\n        assert(addr1 == addr1);\n        assert(addr1 != addr2);\n    }\n\n    /**\n     * Parse an IPv4 address string in the dotted-decimal form $(I a.b.c.d)\n     * and return the number.\n     * Returns: If the string is not a legitimate IPv4 address,\n     * `ADDR_NONE` is returned.\n     */\n    static uint parse(scope const(char)[] addr) @trusted nothrow\n    {\n        return ntohl(inet_addr(addr.tempCString()));\n    }\n\n    /**\n     * Convert an IPv4 address number in host byte order to a human readable\n     * string representing the IPv4 address in dotted-decimal form.\n     */\n    static string addrToString(uint addr) @trusted nothrow\n    {\n        in_addr sin_addr;\n        sin_addr.s_addr = htonl(addr);\n        return to!string(inet_ntoa(sin_addr));\n    }\n}\n\n\n@safe unittest\n{\n    softUnittest({\n        const InternetAddress ia = new InternetAddress(\"63.105.9.61\", 80);\n        assert(ia.toString() == \"63.105.9.61:80\");\n    });\n\n    softUnittest({\n        // test construction from a sockaddr_in\n        sockaddr_in sin;\n\n        sin.sin_addr.s_addr = htonl(0x7F_00_00_01);  // 127.0.0.1\n        sin.sin_family = AddressFamily.INET;\n        sin.sin_port = htons(80);\n\n        const InternetAddress ia = new InternetAddress(sin);\n        assert(ia.toString() == \"127.0.0.1:80\");\n    });\n\n    softUnittest({\n        // test reverse lookup\n        auto ih = new InternetHost;\n        if (ih.getHostByName(\"digitalmars.com\"))\n        {\n            const ia = new InternetAddress(ih.addrList[0], 80);\n            assert(ia.toHostNameString() == \"digitalmars.com\");\n\n            if (getnameinfoPointer)\n            {\n                // test reverse lookup, via gethostbyaddr\n                auto getnameinfoPointerBackup = getnameinfoPointer;\n                cast() getnameinfoPointer = null;\n                scope(exit) cast() getnameinfoPointer = getnameinfoPointerBackup;\n\n                assert(ia.toHostNameString() == \"digitalmars.com\");\n            }\n        }\n    });\n\n    version (SlowTests)\n    softUnittest({\n        // test failing reverse lookup\n        const InternetAddress ia = new InternetAddress(\"127.114.111.120\", 80);\n        assert(ia.toHostNameString() is null);\n\n        if (getnameinfoPointer)\n        {\n            // test failing reverse lookup, via gethostbyaddr\n            auto getnameinfoPointerBackup = getnameinfoPointer;\n            getnameinfoPointer = null;\n            scope(exit) getnameinfoPointer = getnameinfoPointerBackup;\n\n            assert(ia.toHostNameString() is null);\n        }\n    });\n}\n\n\n/**\n * `Internet6Address` encapsulates an IPv6 (Internet Protocol version 6)\n * socket address.\n *\n * Consider using `getAddress`, `parseAddress` and `Address` methods\n * instead of using this class directly.\n */\nclass Internet6Address: Address\n{\nprotected:\n    sockaddr_in6 sin6;\n\n\n    this() pure nothrow @nogc\n    {\n    }\n\n\npublic:\n    override @property sockaddr* name()\n    {\n        return cast(sockaddr*)&sin6;\n    }\n\n    override @property const(sockaddr)* name() const\n    {\n        return cast(const(sockaddr)*)&sin6;\n    }\n\n\n    override @property socklen_t nameLen() const\n    {\n        return cast(socklen_t) sin6.sizeof;\n    }\n\n\n    /// Any IPv6 host address.\n    static @property ref const(ubyte)[16] ADDR_ANY() pure nothrow @nogc\n    {\n        const(ubyte)[16]* addr;\n        static if (is(typeof(IN6ADDR_ANY)))\n        {\n            addr = &IN6ADDR_ANY.s6_addr;\n            return *addr;\n        }\n        else static if (is(typeof(in6addr_any)))\n        {\n            addr = &in6addr_any.s6_addr;\n            return *addr;\n        }\n        else\n            static assert(0);\n    }\n\n    /// Any IPv6 port number.\n    enum ushort PORT_ANY = 0;\n\n    /// Returns the IPv6 port number.\n    @property ushort port() const pure nothrow @nogc\n    {\n        return ntohs(sin6.sin6_port);\n    }\n\n    /// Returns the IPv6 address.\n    @property ubyte[16] addr() const pure nothrow @nogc\n    {\n        return sin6.sin6_addr.s6_addr;\n    }\n\n    /**\n     * Construct a new `Internet6Address`.\n     * Params:\n     *   addr    = an IPv6 host address string in the form described in RFC 2373,\n     *             or a host name which will be resolved using `getAddressInfo`.\n     *   service = (optional) service name.\n     */\n    this(scope const(char)[] addr, scope const(char)[] service = null) @trusted\n    {\n        auto results = getAddressInfo(addr, service, AddressFamily.INET6);\n        assert(results.length && results[0].family == AddressFamily.INET6);\n        sin6 = *cast(sockaddr_in6*) results[0].address.name;\n    }\n\n    /**\n     * Construct a new `Internet6Address`.\n     * Params:\n     *   addr = an IPv6 host address string in the form described in RFC 2373,\n     *          or a host name which will be resolved using `getAddressInfo`.\n     *   port = port number, may be `PORT_ANY`.\n     */\n    this(scope const(char)[] addr, ushort port)\n    {\n        if (port == PORT_ANY)\n            this(addr);\n        else\n            this(addr, to!string(port));\n    }\n\n    /**\n     * Construct a new `Internet6Address`.\n     * Params:\n     *   addr = (optional) an IPv6 host address in host byte order, or\n     *          `ADDR_ANY`.\n     *   port = port number, may be `PORT_ANY`.\n     */\n    this(ubyte[16] addr, ushort port) pure nothrow @nogc\n    {\n        sin6.sin6_family = AddressFamily.INET6;\n        sin6.sin6_addr.s6_addr = addr;\n        sin6.sin6_port = htons(port);\n    }\n\n    /// ditto\n    this(ushort port) pure nothrow @nogc\n    {\n        sin6.sin6_family = AddressFamily.INET6;\n        sin6.sin6_addr.s6_addr = ADDR_ANY;\n        sin6.sin6_port = htons(port);\n    }\n\n     /**\n     * Construct a new `Internet6Address`.\n     * Params:\n     *   addr = A sockaddr_in6 as obtained from lower-level API calls such as getifaddrs.\n     */\n    this(sockaddr_in6 addr) pure nothrow @nogc\n    {\n        assert(addr.sin6_family == AddressFamily.INET6);\n        sin6 = addr;\n    }\n\n   /**\n     * Parse an IPv6 host address string as described in RFC 2373, and return the\n     * address.\n     * Throws: `SocketException` on error.\n     */\n    static ubyte[16] parse(scope const(char)[] addr) @trusted\n    {\n        // Although we could use inet_pton here, it's only available on Windows\n        // versions starting with Vista, so use getAddressInfo with NUMERICHOST\n        // instead.\n        auto results = getAddressInfo(addr, AddressInfoFlags.NUMERICHOST);\n        if (results.length && results[0].family == AddressFamily.INET6)\n            return (cast(sockaddr_in6*) results[0].address.name).sin6_addr.s6_addr;\n        throw new AddressException(\"Not an IPv6 address\", 0);\n    }\n}\n\n\n@safe unittest\n{\n    softUnittest({\n        const Internet6Address ia = new Internet6Address(\"::1\", 80);\n        assert(ia.toString() == \"[::1]:80\");\n    });\n\n    softUnittest({\n        // test construction from a sockaddr_in6\n        sockaddr_in6 sin;\n\n        sin.sin6_addr.s6_addr = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];  // [::1]\n        sin.sin6_family = AddressFamily.INET6;\n        sin.sin6_port = htons(80);\n\n        const Internet6Address ia = new Internet6Address(sin);\n        assert(ia.toString() == \"[::1]:80\");\n    });\n}\n\n\nversion (StdDdoc)\n{\n    static if (!is(sockaddr_un))\n    {\n        // This exists only to allow the constructor taking\n        // a sockaddr_un to be compilable for documentation\n        // on platforms that don't supply a sockaddr_un.\n        struct sockaddr_un\n        {\n        }\n    }\n\n    /**\n     * `UnixAddress` encapsulates an address for a Unix domain socket\n     * (`AF_UNIX`), i.e. a socket bound to a path name in the file system.\n     * Available only on supported systems.\n     *\n     * Linux also supports an abstract address namespace, in which addresses\n     * are independent of the file system. A socket address is abstract\n     * iff `path` starts with a _null byte (`'\\0'`). Null bytes in other\n     * positions of an abstract address are allowed and have no special\n     * meaning.\n     *\n     * Example:\n     * ---\n     * auto addr = new UnixAddress(\"/var/run/dbus/system_bus_socket\");\n     * auto abstractAddr = new UnixAddress(\"\\0/tmp/dbus-OtHLWmCLPR\");\n     * ---\n     *\n     * See_Also: $(HTTP http://man7.org/linux/man-pages/man7/unix.7.html, UNIX(7))\n     */\n    class UnixAddress: Address\n    {\n        private this() pure nothrow @nogc {}\n\n        /// Construct a new `UnixAddress` from the specified path.\n        this(scope const(char)[] path) { }\n\n        /**\n         * Construct a new `UnixAddress`.\n         * Params:\n         *   addr = A sockaddr_un as obtained from lower-level API calls.\n         */\n        this(sockaddr_un addr) pure nothrow @nogc { }\n\n        /// Get the underlying _path.\n        @property string path() const { return null; }\n\n        /// ditto\n        override string toString() const { return null; }\n\n        override @property sockaddr* name() { return null; }\n        override @property const(sockaddr)* name() const { return null; }\n        override @property socklen_t nameLen() const { return 0; }\n    }\n}\nelse\nstatic if (is(sockaddr_un))\n{\n    class UnixAddress: Address\n    {\n    protected:\n        socklen_t _nameLen;\n\n        struct\n        {\n        align (1):\n            sockaddr_un sun;\n            char unused = '\\0'; // placeholder for a terminating '\\0'\n        }\n\n        this() pure nothrow @nogc\n        {\n            sun.sun_family = AddressFamily.UNIX;\n            sun.sun_path = '?';\n            _nameLen = sun.sizeof;\n        }\n\n        override void setNameLen(socklen_t len) @trusted\n        {\n            if (len > sun.sizeof)\n                throw new SocketParameterException(\"Not enough socket address storage\");\n            _nameLen = len;\n        }\n\n    public:\n        override @property sockaddr* name()\n        {\n            return cast(sockaddr*)&sun;\n        }\n\n        override @property const(sockaddr)* name() const\n        {\n            return cast(const(sockaddr)*)&sun;\n        }\n\n        override @property socklen_t nameLen() @trusted const\n        {\n            return _nameLen;\n        }\n\n        this(scope const(char)[] path) @trusted pure\n        {\n            enforce(path.length <= sun.sun_path.sizeof, new SocketParameterException(\"Path too long\"));\n            sun.sun_family = AddressFamily.UNIX;\n            sun.sun_path.ptr[0 .. path.length] = (cast(byte[]) path)[];\n            _nameLen = cast(socklen_t)\n                {\n                    auto len = sockaddr_un.init.sun_path.offsetof + path.length;\n                    // Pathname socket address must be terminated with '\\0'\n                    // which must be included in the address length.\n                    if (sun.sun_path.ptr[0])\n                    {\n                        sun.sun_path.ptr[path.length] = 0;\n                        ++len;\n                    }\n                    return len;\n                }();\n        }\n\n        this(sockaddr_un addr) pure nothrow @nogc\n        {\n            assert(addr.sun_family == AddressFamily.UNIX);\n            sun = addr;\n        }\n\n        @property string path() @trusted const pure\n        {\n            auto len = _nameLen - sockaddr_un.init.sun_path.offsetof;\n            // For pathname socket address we need to strip off the terminating '\\0'\n            if (sun.sun_path.ptr[0])\n                --len;\n            return (cast(const(char)*) sun.sun_path.ptr)[0 .. len].idup;\n        }\n\n        override string toString() const pure\n        {\n            return path;\n        }\n    }\n\n    @safe unittest\n    {\n        import core.stdc.stdio : remove;\n        import std.file : deleteme;\n\n        immutable ubyte[] data = [1, 2, 3, 4];\n        Socket[2] pair;\n\n        auto names = [ deleteme ~ \"-unix-socket\" ];\n        version (linux)\n            names ~= \"\\0\" ~ deleteme ~ \"-abstract\\0unix\\0socket\";\n        foreach (name; names)\n        {\n            auto address = new UnixAddress(name);\n\n            auto listener = new Socket(AddressFamily.UNIX, SocketType.STREAM);\n            scope(exit) listener.close();\n            listener.bind(address);\n            scope(exit) () @trusted { if (name[0]) remove(name.tempCString()); } ();\n            assert(listener.localAddress.toString == name);\n\n            listener.listen(1);\n\n            pair[0] = new Socket(AddressFamily.UNIX, SocketType.STREAM);\n            scope(exit) listener.close();\n\n            pair[0].connect(address);\n            scope(exit) pair[0].close();\n\n            pair[1] = listener.accept();\n            scope(exit) pair[1].close();\n\n            pair[0].send(data);\n\n            auto buf = new ubyte[data.length];\n            pair[1].receive(buf);\n            assert(buf == data);\n        }\n    }\n}\n\n\n/**\n * Class for exceptions thrown by `Socket.accept`.\n */\nclass SocketAcceptException: SocketOSException\n{\n    mixin socketOSExceptionCtors;\n}\n\n/// How a socket is shutdown:\nenum SocketShutdown: int\n{\n    RECEIVE =  SD_RECEIVE,      /// socket receives are disallowed\n    SEND =     SD_SEND,         /// socket sends are disallowed\n    BOTH =     SD_BOTH,         /// both RECEIVE and SEND\n}\n\n\n/// Flags may be OR'ed together:\nenum SocketFlags: int\n{\n    NONE =       0,                 /// no flags specified\n\n    OOB =        MSG_OOB,           /// out-of-band stream data\n    PEEK =       MSG_PEEK,          /// peek at incoming data without removing it from the queue, only for receiving\n    DONTROUTE =  MSG_DONTROUTE,     /// data should not be subject to routing; this flag may be ignored. Only for sending\n}\n\n\nprivate mixin template FieldProxy(string target, string field)\n{\n    mixin(`\n        @property typeof(`~target~`) `~field~`() const pure nothrow @nogc\n        {\n            return `~target~`;\n        }\n\n        /// ditto\n        @property typeof(`~target~`) `~field~`(typeof(`~target~`) value) pure nothrow @nogc\n        {\n            return `~target~` = value;\n        }\n    `);\n}\n\n\n/// Duration timeout value.\nstruct TimeVal\n{\n    _ctimeval ctimeval;\n    alias tv_sec_t = typeof(ctimeval.tv_sec);\n    alias tv_usec_t = typeof(ctimeval.tv_usec);\n\n    version (StdDdoc) // no DDoc for string mixins, can't forward individual fields\n    {\n        tv_sec_t seconds;           /// Number of _seconds.\n        tv_usec_t microseconds;     /// Number of additional _microseconds.\n    }\n    else\n    {\n        // D interface\n        mixin FieldProxy!(`ctimeval.tv_sec`, `seconds`);\n        mixin FieldProxy!(`ctimeval.tv_usec`, `microseconds`);\n    }\n}\n\n\n/**\n * A collection of sockets for use with `Socket.select`.\n *\n * `SocketSet` wraps the platform `fd_set` type. However, unlike\n * `fd_set`, `SocketSet` is not statically limited to `FD_SETSIZE`\n * or any other limit, and grows as needed.\n */\nclass SocketSet\n{\nprivate:\n    version (Windows)\n    {\n        // On Windows, fd_set is an array of socket handles,\n        // following a word containing the fd_set instance size.\n        // We use one dynamic array for everything, and use its first\n        // element(s) for the count.\n\n        alias fd_set_count_type = typeof(fd_set.init.fd_count);\n        alias fd_set_type = typeof(fd_set.init.fd_array[0]);\n        static assert(fd_set_type.sizeof == socket_t.sizeof);\n\n        // Number of fd_set_type elements at the start of our array that are\n        // used for the socket count and alignment\n\n        enum FD_SET_OFFSET = fd_set.fd_array.offsetof / fd_set_type.sizeof;\n        static assert(FD_SET_OFFSET);\n        static assert(fd_set.fd_count.offsetof % fd_set_type.sizeof == 0);\n\n        fd_set_type[] set;\n\n        void resize(size_t size) pure nothrow\n        {\n            set.length = FD_SET_OFFSET + size;\n        }\n\n        ref inout(fd_set_count_type) count() @trusted @property inout pure nothrow @nogc\n        {\n            assert(set.length);\n            return *cast(inout(fd_set_count_type)*)set.ptr;\n        }\n\n        size_t capacity() @property const pure nothrow @nogc\n        {\n            return set.length - FD_SET_OFFSET;\n        }\n\n        inout(socket_t)[] fds() @trusted inout @property pure nothrow @nogc\n        {\n            return cast(inout(socket_t)[])set[FD_SET_OFFSET .. FD_SET_OFFSET+count];\n        }\n    }\n    else\n    version (Posix)\n    {\n        // On Posix, fd_set is a bit array. We assume that the fd_set\n        // type (declared in core.sys.posix.sys.select) is a structure\n        // containing a single field, a static array.\n\n        static assert(fd_set.tupleof.length == 1);\n\n        // This is the type used in the fd_set array.\n        // Using the type of the correct size is important for big-endian\n        // architectures.\n\n        alias fd_set_type = typeof(fd_set.init.tupleof[0][0]);\n\n        // Number of file descriptors represented by one fd_set_type\n\n        enum FD_NFDBITS = 8 * fd_set_type.sizeof;\n\n        static fd_set_type mask(uint n) pure nothrow @nogc\n        {\n            return (cast(fd_set_type) 1) << (n % FD_NFDBITS);\n        }\n\n        // Array size to fit that many sockets\n\n        static size_t lengthFor(size_t size) pure nothrow @nogc\n        {\n            return (size + (FD_NFDBITS-1)) / FD_NFDBITS;\n        }\n\n        fd_set_type[] set;\n\n        void resize(size_t size) pure nothrow\n        {\n            set.length = lengthFor(size);\n        }\n\n        // Make sure we can fit that many sockets\n\n        void setMinCapacity(size_t size) pure nothrow\n        {\n            auto length = lengthFor(size);\n            if (set.length < length)\n                set.length = length;\n        }\n\n        size_t capacity() @property const pure nothrow @nogc\n        {\n            return set.length * FD_NFDBITS;\n        }\n\n        int maxfd;\n    }\n    else\n        static assert(false, \"Unknown platform\");\n\npublic:\n\n    /**\n     * Create a SocketSet with a specific initial capacity (defaults to\n     * `FD_SETSIZE`, the system's default capacity).\n     */\n    this(size_t size = FD_SETSIZE) pure nothrow\n    {\n        resize(size);\n        reset();\n    }\n\n    /// Reset the `SocketSet` so that there are 0 `Socket`s in the collection.\n    void reset() pure nothrow @nogc\n    {\n        version (Windows)\n            count = 0;\n        else\n        {\n            set[] = 0;\n            maxfd = -1;\n        }\n    }\n\n\n    void add(socket_t s) @trusted pure nothrow\n    {\n        version (Windows)\n        {\n            if (count == capacity)\n            {\n                set.length *= 2;\n                set.length = set.capacity;\n            }\n            ++count;\n            fds[$-1] = s;\n        }\n        else\n        {\n            auto index = s / FD_NFDBITS;\n            auto length = set.length;\n            if (index >= length)\n            {\n                while (index >= length)\n                    length *= 2;\n                set.length = length;\n                set.length = set.capacity;\n            }\n            set[index] |= mask(s);\n            if (maxfd < s)\n                maxfd = s;\n        }\n    }\n\n    /**\n     * Add a `Socket` to the collection.\n     * The socket must not already be in the collection.\n     */\n    void add(Socket s) pure nothrow\n    {\n        add(s.sock);\n    }\n\n    void remove(socket_t s) pure nothrow\n    {\n        version (Windows)\n        {\n            import std.algorithm.searching : countUntil;\n            auto fds = fds;\n            auto p = fds.countUntil(s);\n            if (p >= 0)\n                fds[p] = fds[--count];\n        }\n        else\n        {\n            auto index = s / FD_NFDBITS;\n            if (index >= set.length)\n                return;\n            set[index] &= ~mask(s);\n            // note: adjusting maxfd would require scanning the set, not worth it\n        }\n    }\n\n\n    /**\n     * Remove this `Socket` from the collection.\n     * Does nothing if the socket is not in the collection already.\n     */\n    void remove(Socket s) pure nothrow\n    {\n        remove(s.sock);\n    }\n\n    int isSet(socket_t s) const pure nothrow @nogc\n    {\n        version (Windows)\n        {\n            import std.algorithm.searching : canFind;\n            return fds.canFind(s) ? 1 : 0;\n        }\n        else\n        {\n            if (s > maxfd)\n                return 0;\n            auto index = s / FD_NFDBITS;\n            return (set[index] & mask(s)) ? 1 : 0;\n        }\n    }\n\n\n    /// Return nonzero if this `Socket` is in the collection.\n    int isSet(Socket s) const pure nothrow @nogc\n    {\n        return isSet(s.sock);\n    }\n\n\n    /**\n     * Returns:\n     * The current capacity of this `SocketSet`. The exact\n     * meaning of the return value varies from platform to platform.\n     *\n     * Note:\n     * Since D 2.065, this value does not indicate a\n     * restriction, and `SocketSet` will grow its capacity as\n     * needed automatically.\n     */\n    @property uint max() const pure nothrow @nogc\n    {\n        return cast(uint) capacity;\n    }\n\n\n    fd_set* toFd_set() @trusted pure nothrow @nogc\n    {\n        return cast(fd_set*) set.ptr;\n    }\n\n\n    int selectn() const pure nothrow @nogc\n    {\n        version (Windows)\n        {\n            return count;\n        }\n        else version (Posix)\n        {\n            return maxfd + 1;\n        }\n    }\n}\n\n@safe unittest\n{\n    auto fds = cast(socket_t[])\n        [cast(socket_t) 1, 2, 0, 1024, 17, 42, 1234, 77, 77+32, 77+64];\n    auto set = new SocketSet();\n    foreach (fd; fds) assert(!set.isSet(fd));\n    foreach (fd; fds) set.add(fd);\n    foreach (fd; fds) assert(set.isSet(fd));\n\n    // Make sure SocketSet reimplements fd_set correctly\n    auto fdset = set.toFd_set();\n    foreach (fd; fds[0]..cast(socket_t)(fds[$-1]+1))\n        assert(cast(bool) set.isSet(fd) == cast(bool)(() @trusted => FD_ISSET(fd, fdset))());\n\n    foreach (fd; fds)\n    {\n        assert(set.isSet(fd));\n        set.remove(fd);\n        assert(!set.isSet(fd));\n    }\n}\n\n@safe unittest\n{\n    softUnittest({\n        enum PAIRS = 768;\n        version (Posix)\n        () @trusted\n        {\n            enum LIMIT = 2048;\n            static assert(LIMIT > PAIRS*2);\n            import core.sys.posix.sys.resource;\n            rlimit fileLimit;\n            getrlimit(RLIMIT_NOFILE, &fileLimit);\n            assert(fileLimit.rlim_max > LIMIT, \"Open file hard limit too low\");\n            fileLimit.rlim_cur = LIMIT;\n            setrlimit(RLIMIT_NOFILE, &fileLimit);\n        } ();\n\n        Socket[2][PAIRS] pairs;\n        foreach (ref pair; pairs)\n            pair = socketPair();\n        scope(exit)\n        {\n            foreach (pair; pairs)\n            {\n                pair[0].close();\n                pair[1].close();\n            }\n        }\n\n        import std.random;\n        auto rng = Xorshift(42);\n        pairs[].randomShuffle(rng);\n\n        auto readSet = new SocketSet();\n        auto writeSet = new SocketSet();\n        auto errorSet = new SocketSet();\n\n        foreach (testPair; pairs)\n        {\n            void fillSets()\n            {\n                readSet.reset();\n                writeSet.reset();\n                errorSet.reset();\n                foreach (ref pair; pairs)\n                    foreach (s; pair[])\n                    {\n                        readSet.add(s);\n                        writeSet.add(s);\n                        errorSet.add(s);\n                    }\n            }\n\n            fillSets();\n            auto n = Socket.select(readSet, writeSet, errorSet);\n            assert(n == PAIRS*2); // All in writeSet\n            assert(writeSet.isSet(testPair[0]));\n            assert(writeSet.isSet(testPair[1]));\n            assert(!readSet.isSet(testPair[0]));\n            assert(!readSet.isSet(testPair[1]));\n            assert(!errorSet.isSet(testPair[0]));\n            assert(!errorSet.isSet(testPair[1]));\n\n            ubyte[1] b;\n            // Socket.send can't be marked with `scope`\n            // -> @safe DIP1000 code can't use it - see https://github.com/dlang/phobos/pull/6204\n            () @trusted {\n                testPair[0].send(b[]);\n            }();\n            fillSets();\n            n = Socket.select(readSet, null, null);\n            assert(n == 1); // testPair[1]\n            assert(readSet.isSet(testPair[1]));\n            assert(!readSet.isSet(testPair[0]));\n            // Socket.receive can't be marked with `scope`\n            // -> @safe DIP1000 code can't use it - see https://github.com/dlang/phobos/pull/6204\n            () @trusted {\n                testPair[1].receive(b[]);\n            }();\n        }\n    });\n}\n\n@safe unittest // Issue 14012, 14013\n{\n    auto set = new SocketSet(1);\n    assert(set.max >= 0);\n\n    enum LIMIT = 4096;\n    foreach (n; 0 .. LIMIT)\n        set.add(cast(socket_t) n);\n    assert(set.max >= LIMIT);\n}\n\n/// The level at which a socket option is defined:\nenum SocketOptionLevel: int\n{\n    SOCKET =  SOL_SOCKET,               /// Socket level\n    IP =      ProtocolType.IP,          /// Internet Protocol version 4 level\n    ICMP =    ProtocolType.ICMP,        /// Internet Control Message Protocol level\n    IGMP =    ProtocolType.IGMP,        /// Internet Group Management Protocol level\n    GGP =     ProtocolType.GGP,         /// Gateway to Gateway Protocol level\n    TCP =     ProtocolType.TCP,         /// Transmission Control Protocol level\n    PUP =     ProtocolType.PUP,         /// PARC Universal Packet Protocol level\n    UDP =     ProtocolType.UDP,         /// User Datagram Protocol level\n    IDP =     ProtocolType.IDP,         /// Xerox NS protocol level\n    RAW =     ProtocolType.RAW,         /// Raw IP packet level\n    IPV6 =    ProtocolType.IPV6,        /// Internet Protocol version 6 level\n}\n\n/// _Linger information for use with SocketOption.LINGER.\nstruct Linger\n{\n    _clinger clinger;\n\n    version (StdDdoc) // no DDoc for string mixins, can't forward individual fields\n    {\n        private alias l_onoff_t = typeof(_clinger.init.l_onoff );\n        private alias l_linger_t = typeof(_clinger.init.l_linger);\n        l_onoff_t  on;   /// Nonzero for _on.\n        l_linger_t time; /// Linger _time.\n    }\n    else\n    {\n        // D interface\n        mixin FieldProxy!(`clinger.l_onoff`, `on`);\n        mixin FieldProxy!(`clinger.l_linger`, `time`);\n    }\n}\n\n/// Specifies a socket option:\nenum SocketOption: int\n{\n    DEBUG =                SO_DEBUG,            /// Record debugging information\n    BROADCAST =            SO_BROADCAST,        /// Allow transmission of broadcast messages\n    REUSEADDR =            SO_REUSEADDR,        /// Allow local reuse of address\n    LINGER =               SO_LINGER,           /// Linger on close if unsent data is present\n    OOBINLINE =            SO_OOBINLINE,        /// Receive out-of-band data in band\n    SNDBUF =               SO_SNDBUF,           /// Send buffer size\n    RCVBUF =               SO_RCVBUF,           /// Receive buffer size\n    DONTROUTE =            SO_DONTROUTE,        /// Do not route\n    SNDTIMEO =             SO_SNDTIMEO,         /// Send timeout\n    RCVTIMEO =             SO_RCVTIMEO,         /// Receive timeout\n    ERROR =                SO_ERROR,            /// Retrieve and clear error status\n    KEEPALIVE =            SO_KEEPALIVE,        /// Enable keep-alive packets\n    ACCEPTCONN =           SO_ACCEPTCONN,       /// Listen\n    RCVLOWAT =             SO_RCVLOWAT,         /// Minimum number of input bytes to process\n    SNDLOWAT =             SO_SNDLOWAT,         /// Minimum number of output bytes to process\n    TYPE =                 SO_TYPE,             /// Socket type\n\n    // SocketOptionLevel.TCP:\n    TCP_NODELAY =          .TCP_NODELAY,        /// Disable the Nagle algorithm for send coalescing\n\n    // SocketOptionLevel.IPV6:\n    IPV6_UNICAST_HOPS =    .IPV6_UNICAST_HOPS,          /// IP unicast hop limit\n    IPV6_MULTICAST_IF =    .IPV6_MULTICAST_IF,          /// IP multicast interface\n    IPV6_MULTICAST_LOOP =  .IPV6_MULTICAST_LOOP,        /// IP multicast loopback\n    IPV6_MULTICAST_HOPS =  .IPV6_MULTICAST_HOPS,        /// IP multicast hops\n    IPV6_JOIN_GROUP =      .IPV6_JOIN_GROUP,            /// Add an IP group membership\n    IPV6_LEAVE_GROUP =     .IPV6_LEAVE_GROUP,           /// Drop an IP group membership\n    IPV6_V6ONLY =          .IPV6_V6ONLY,                /// Treat wildcard bind as AF_INET6-only\n}\n\n\n/**\n * `Socket` is a class that creates a network communication endpoint using\n * the Berkeley sockets interface.\n */\nclass Socket\n{\nprivate:\n    socket_t sock;\n    AddressFamily _family;\n\n    version (Windows)\n        bool _blocking = false;         /// Property to get or set whether the socket is blocking or nonblocking.\n\n    // The WinSock timeouts seem to be effectively skewed by a constant\n    // offset of about half a second (value in milliseconds). This has\n    // been confirmed on updated (as of Jun 2011) Windows XP, Windows 7\n    // and Windows Server 2008 R2 boxes. The unittest below tests this\n    // behavior.\n    enum WINSOCK_TIMEOUT_SKEW = 500;\n\n    @safe unittest\n    {\n        version (SlowTests)\n        softUnittest({\n            import std.datetime.stopwatch;\n            import std.typecons;\n\n            enum msecs = 1000;\n            auto pair = socketPair();\n            auto sock = pair[0];\n            sock.setOption(SocketOptionLevel.SOCKET,\n                SocketOption.RCVTIMEO, dur!\"msecs\"(msecs));\n\n            auto sw = StopWatch(Yes.autoStart);\n            ubyte[1] buf;\n            sock.receive(buf);\n            sw.stop();\n\n            Duration readBack = void;\n            sock.getOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, readBack);\n\n            assert(readBack.total!\"msecs\" == msecs);\n            assert(sw.peek().total!\"msecs\" > msecs - 100 && sw.peek().total!\"msecs\" < msecs + 100);\n        });\n    }\n\n    void setSock(socket_t handle)\n    {\n        assert(handle != socket_t.init);\n        sock = handle;\n\n        // Set the option to disable SIGPIPE on send() if the platform\n        // has it (e.g. on OS X).\n        static if (is(typeof(SO_NOSIGPIPE)))\n        {\n            setOption(SocketOptionLevel.SOCKET, cast(SocketOption) SO_NOSIGPIPE, true);\n        }\n    }\n\n\n    // For use with accepting().\n    protected this() pure nothrow @nogc\n    {\n    }\n\n\npublic:\n\n    /**\n     * Create a blocking socket. If a single protocol type exists to support\n     * this socket type within the address family, the `ProtocolType` may be\n     * omitted.\n     */\n    this(AddressFamily af, SocketType type, ProtocolType protocol) @trusted\n    {\n        _family = af;\n        auto handle = cast(socket_t) socket(af, type, protocol);\n        if (handle == socket_t.init)\n            throw new SocketOSException(\"Unable to create socket\");\n        setSock(handle);\n    }\n\n    /// ditto\n    this(AddressFamily af, SocketType type)\n    {\n        /* A single protocol exists to support this socket type within the\n         * protocol family, so the ProtocolType is assumed.\n         */\n        this(af, type, cast(ProtocolType) 0);         // Pseudo protocol number.\n    }\n\n\n    /// ditto\n    this(AddressFamily af, SocketType type, scope const(char)[] protocolName) @trusted\n    {\n        protoent* proto;\n        proto = getprotobyname(protocolName.tempCString());\n        if (!proto)\n            throw new SocketOSException(\"Unable to find the protocol\");\n        this(af, type, cast(ProtocolType) proto.p_proto);\n    }\n\n\n    /**\n     * Create a blocking socket using the parameters from the specified\n     * `AddressInfo` structure.\n     */\n    this(in AddressInfo info)\n    {\n        this(info.family, info.type, info.protocol);\n    }\n\n    /// Use an existing socket handle.\n    this(socket_t sock, AddressFamily af) pure nothrow @nogc\n    {\n        assert(sock != socket_t.init);\n        this.sock = sock;\n        this._family = af;\n    }\n\n\n    ~this() nothrow @nogc\n    {\n        close();\n    }\n\n\n    /// Get underlying socket handle.\n    @property socket_t handle() const pure nothrow @nogc\n    {\n        return sock;\n    }\n\n    /**\n     * Get/set socket's blocking flag.\n     *\n     * When a socket is blocking, calls to receive(), accept(), and send()\n     * will block and wait for data/action.\n     * A non-blocking socket will immediately return instead of blocking.\n     */\n    @property bool blocking() @trusted const nothrow @nogc\n    {\n        version (Windows)\n        {\n            return _blocking;\n        }\n        else version (Posix)\n        {\n            return !(fcntl(handle, F_GETFL, 0) & O_NONBLOCK);\n        }\n    }\n\n    /// ditto\n    @property void blocking(bool byes) @trusted\n    {\n        version (Windows)\n        {\n            uint num = !byes;\n            if (_SOCKET_ERROR == ioctlsocket(sock, FIONBIO, &num))\n                goto err;\n            _blocking = byes;\n        }\n        else version (Posix)\n        {\n            int x = fcntl(sock, F_GETFL, 0);\n            if (-1 == x)\n                goto err;\n            if (byes)\n                x &= ~O_NONBLOCK;\n            else\n                x |= O_NONBLOCK;\n            if (-1 == fcntl(sock, F_SETFL, x))\n                goto err;\n        }\n        return;         // Success.\n\n err:\n        throw new SocketOSException(\"Unable to set socket blocking\");\n    }\n\n\n    /// Get the socket's address family.\n    @property AddressFamily addressFamily()\n    {\n        return _family;\n    }\n\n    /// Property that indicates if this is a valid, alive socket.\n    @property bool isAlive() @trusted const\n    {\n        int type;\n        socklen_t typesize = cast(socklen_t) type.sizeof;\n        return !getsockopt(sock, SOL_SOCKET, SO_TYPE, cast(char*)&type, &typesize);\n    }\n\n    /// Associate a local address with this socket.\n    void bind(Address addr) @trusted\n    {\n        if (_SOCKET_ERROR == .bind(sock, addr.name, addr.nameLen))\n            throw new SocketOSException(\"Unable to bind socket\");\n    }\n\n    /**\n     * Establish a connection. If the socket is blocking, connect waits for\n     * the connection to be made. If the socket is nonblocking, connect\n     * returns immediately and the connection attempt is still in progress.\n     */\n    void connect(Address to) @trusted\n    {\n        if (_SOCKET_ERROR == .connect(sock, to.name, to.nameLen))\n        {\n            int err;\n            err = _lasterr();\n\n            if (!blocking)\n            {\n                version (Windows)\n                {\n                    if (WSAEWOULDBLOCK == err)\n                        return;\n                }\n                else version (Posix)\n                {\n                    if (EINPROGRESS == err)\n                        return;\n                }\n                else\n                {\n                    static assert(0);\n                }\n            }\n            throw new SocketOSException(\"Unable to connect socket\", err);\n        }\n    }\n\n    /**\n     * Listen for an incoming connection. `bind` must be called before you\n     * can `listen`. The `backlog` is a request of how many pending\n     * incoming connections are queued until `accept`ed.\n     */\n    void listen(int backlog) @trusted\n    {\n        if (_SOCKET_ERROR == .listen(sock, backlog))\n            throw new SocketOSException(\"Unable to listen on socket\");\n    }\n\n    /**\n     * Called by `accept` when a new `Socket` must be created for a new\n     * connection. To use a derived class, override this method and return an\n     * instance of your class. The returned `Socket`'s handle must not be\n     * set; `Socket` has a protected constructor `this()` to use in this\n     * situation.\n     *\n     * Override to use a derived class.\n     * The returned socket's handle must not be set.\n     */\n    protected Socket accepting() pure nothrow\n    {\n        return new Socket;\n    }\n\n    /**\n     * Accept an incoming connection. If the socket is blocking, `accept`\n     * waits for a connection request. Throws `SocketAcceptException` if\n     * unable to _accept. See `accepting` for use with derived classes.\n     */\n    Socket accept() @trusted\n    {\n        auto newsock = cast(socket_t).accept(sock, null, null);\n        if (socket_t.init == newsock)\n            throw new SocketAcceptException(\"Unable to accept socket connection\");\n\n        Socket newSocket;\n        try\n        {\n            newSocket = accepting();\n            assert(newSocket.sock == socket_t.init);\n\n            newSocket.setSock(newsock);\n            version (Windows)\n                newSocket._blocking = _blocking;                 //inherits blocking mode\n            newSocket._family = _family;             //same family\n        }\n        catch (Throwable o)\n        {\n            _close(newsock);\n            throw o;\n        }\n\n        return newSocket;\n    }\n\n    /// Disables sends and/or receives.\n    void shutdown(SocketShutdown how) @trusted nothrow @nogc\n    {\n        .shutdown(sock, cast(int) how);\n    }\n\n\n    private static void _close(socket_t sock) @system nothrow @nogc\n    {\n        version (Windows)\n        {\n            .closesocket(sock);\n        }\n        else version (Posix)\n        {\n            .close(sock);\n        }\n    }\n\n\n    /**\n     * Immediately drop any connections and release socket resources.\n     * The `Socket` object is no longer usable after `close`.\n     * Calling `shutdown` before `close` is recommended\n     * for connection-oriented sockets.\n     */\n    void close() @trusted nothrow @nogc\n    {\n        _close(sock);\n        sock = socket_t.init;\n    }\n\n\n    /**\n     * Returns: the local machine's host name\n     */\n    static @property string hostName() @trusted     // getter\n    {\n        char[256] result;         // Host names are limited to 255 chars.\n        if (_SOCKET_ERROR == .gethostname(result.ptr, result.length))\n            throw new SocketOSException(\"Unable to obtain host name\");\n        return to!string(result.ptr);\n    }\n\n    /// Remote endpoint `Address`.\n    @property Address remoteAddress() @trusted\n    {\n        Address addr = createAddress();\n        socklen_t nameLen = addr.nameLen;\n        if (_SOCKET_ERROR == .getpeername(sock, addr.name, &nameLen))\n            throw new SocketOSException(\"Unable to obtain remote socket address\");\n        addr.setNameLen(nameLen);\n        assert(addr.addressFamily == _family);\n        return addr;\n    }\n\n    /// Local endpoint `Address`.\n    @property Address localAddress() @trusted\n    {\n        Address addr = createAddress();\n        socklen_t nameLen = addr.nameLen;\n        if (_SOCKET_ERROR == .getsockname(sock, addr.name, &nameLen))\n            throw new SocketOSException(\"Unable to obtain local socket address\");\n        addr.setNameLen(nameLen);\n        assert(addr.addressFamily == _family);\n        return addr;\n    }\n\n    /**\n     * Send or receive error code. See `wouldHaveBlocked`,\n     * `lastSocketError` and `Socket.getErrorText` for obtaining more\n     * information about the error.\n     */\n    enum int ERROR = _SOCKET_ERROR;\n\n    private static int capToInt(size_t size) nothrow @nogc\n    {\n        // Windows uses int instead of size_t for length arguments.\n        // Luckily, the send/recv functions make no guarantee that\n        // all the data is sent, so we use that to send at most\n        // int.max bytes.\n        return size > size_t(int.max) ? int.max : cast(int) size;\n    }\n\n    /**\n     * Send data on the connection. If the socket is blocking and there is no\n     * buffer space left, `send` waits.\n     * Returns: The number of bytes actually sent, or `Socket.ERROR` on\n     * failure.\n     */\n    ptrdiff_t send(const(void)[] buf, SocketFlags flags) @trusted\n    {\n        static if (is(typeof(MSG_NOSIGNAL)))\n        {\n            flags = cast(SocketFlags)(flags | MSG_NOSIGNAL);\n        }\n        version (Windows)\n            auto sent = .send(sock, buf.ptr, capToInt(buf.length), cast(int) flags);\n        else\n            auto sent = .send(sock, buf.ptr, buf.length, cast(int) flags);\n        return sent;\n    }\n\n    /// ditto\n    ptrdiff_t send(const(void)[] buf)\n    {\n        return send(buf, SocketFlags.NONE);\n    }\n\n    /**\n     * Send data to a specific destination Address. If the destination address is\n     * not specified, a connection must have been made and that address is used.\n     * If the socket is blocking and there is no buffer space left, `sendTo` waits.\n     * Returns: The number of bytes actually sent, or `Socket.ERROR` on\n     * failure.\n     */\n    ptrdiff_t sendTo(const(void)[] buf, SocketFlags flags, Address to) @trusted\n    {\n        static if (is(typeof(MSG_NOSIGNAL)))\n        {\n            flags = cast(SocketFlags)(flags | MSG_NOSIGNAL);\n        }\n        version (Windows)\n            return .sendto(\n                       sock, buf.ptr, capToInt(buf.length),\n                       cast(int) flags, to.name, to.nameLen\n                       );\n        else\n            return .sendto(sock, buf.ptr, buf.length, cast(int) flags, to.name, to.nameLen);\n    }\n\n    /// ditto\n    ptrdiff_t sendTo(const(void)[] buf, Address to)\n    {\n        return sendTo(buf, SocketFlags.NONE, to);\n    }\n\n\n    //assumes you connect()ed\n    /// ditto\n    ptrdiff_t sendTo(const(void)[] buf, SocketFlags flags) @trusted\n    {\n        static if (is(typeof(MSG_NOSIGNAL)))\n        {\n            flags = cast(SocketFlags)(flags | MSG_NOSIGNAL);\n        }\n        version (Windows)\n            return .sendto(sock, buf.ptr, capToInt(buf.length), cast(int) flags, null, 0);\n        else\n            return .sendto(sock, buf.ptr, buf.length, cast(int) flags, null, 0);\n    }\n\n\n    //assumes you connect()ed\n    /// ditto\n    ptrdiff_t sendTo(const(void)[] buf)\n    {\n        return sendTo(buf, SocketFlags.NONE);\n    }\n\n\n    /**\n     * Receive data on the connection. If the socket is blocking, `receive`\n     * waits until there is data to be received.\n     * Returns: The number of bytes actually received, `0` if the remote side\n     * has closed the connection, or `Socket.ERROR` on failure.\n     */\n    ptrdiff_t receive(void[] buf, SocketFlags flags) @trusted\n    {\n        version (Windows)         // Does not use size_t\n        {\n            return buf.length\n                   ? .recv(sock, buf.ptr, capToInt(buf.length), cast(int) flags)\n                   : 0;\n        }\n        else\n        {\n            return buf.length\n                   ? .recv(sock, buf.ptr, buf.length, cast(int) flags)\n                   : 0;\n        }\n    }\n\n    /// ditto\n    ptrdiff_t receive(void[] buf)\n    {\n        return receive(buf, SocketFlags.NONE);\n    }\n\n    /**\n     * Receive data and get the remote endpoint `Address`.\n     * If the socket is blocking, `receiveFrom` waits until there is data to\n     * be received.\n     * Returns: The number of bytes actually received, `0` if the remote side\n     * has closed the connection, or `Socket.ERROR` on failure.\n     */\n    ptrdiff_t receiveFrom(void[] buf, SocketFlags flags, ref Address from) @trusted\n    {\n        if (!buf.length)         //return 0 and don't think the connection closed\n            return 0;\n        if (from is null || from.addressFamily != _family)\n            from = createAddress();\n        socklen_t nameLen = from.nameLen;\n        version (Windows)\n        {\n            auto read = .recvfrom(sock, buf.ptr, capToInt(buf.length), cast(int) flags, from.name, &nameLen);\n            from.setNameLen(nameLen);\n            assert(from.addressFamily == _family);\n            // if (!read) //connection closed\n            return read;\n        }\n        else\n        {\n            auto read = .recvfrom(sock, buf.ptr, buf.length, cast(int) flags, from.name, &nameLen);\n            from.setNameLen(nameLen);\n            assert(from.addressFamily == _family);\n            // if (!read) //connection closed\n            return read;\n        }\n    }\n\n\n    /// ditto\n    ptrdiff_t receiveFrom(void[] buf, ref Address from)\n    {\n        return receiveFrom(buf, SocketFlags.NONE, from);\n    }\n\n\n    //assumes you connect()ed\n    /// ditto\n    ptrdiff_t receiveFrom(void[] buf, SocketFlags flags) @trusted\n    {\n        if (!buf.length)         //return 0 and don't think the connection closed\n            return 0;\n        version (Windows)\n        {\n            auto read = .recvfrom(sock, buf.ptr, capToInt(buf.length), cast(int) flags, null, null);\n            // if (!read) //connection closed\n            return read;\n        }\n        else\n        {\n            auto read = .recvfrom(sock, buf.ptr, buf.length, cast(int) flags, null, null);\n            // if (!read) //connection closed\n            return read;\n        }\n    }\n\n\n    //assumes you connect()ed\n    /// ditto\n    ptrdiff_t receiveFrom(void[] buf)\n    {\n        return receiveFrom(buf, SocketFlags.NONE);\n    }\n\n\n    /**\n     * Get a socket option.\n     * Returns: The number of bytes written to `result`.\n     * The length, in bytes, of the actual result - very different from getsockopt()\n     */\n    int getOption(SocketOptionLevel level, SocketOption option, void[] result) @trusted\n    {\n        socklen_t len = cast(socklen_t) result.length;\n        if (_SOCKET_ERROR == .getsockopt(sock, cast(int) level, cast(int) option, result.ptr, &len))\n            throw new SocketOSException(\"Unable to get socket option\");\n        return len;\n    }\n\n\n    /// Common case of getting integer and boolean options.\n    int getOption(SocketOptionLevel level, SocketOption option, out int32_t result) @trusted\n    {\n        return getOption(level, option, (&result)[0 .. 1]);\n    }\n\n\n    /// Get the linger option.\n    int getOption(SocketOptionLevel level, SocketOption option, out Linger result) @trusted\n    {\n        //return getOption(cast(SocketOptionLevel) SocketOptionLevel.SOCKET, SocketOption.LINGER, (&result)[0 .. 1]);\n        return getOption(level, option, (&result.clinger)[0 .. 1]);\n    }\n\n    /// Get a timeout (duration) option.\n    void getOption(SocketOptionLevel level, SocketOption option, out Duration result) @trusted\n    {\n        enforce(option == SocketOption.SNDTIMEO || option == SocketOption.RCVTIMEO,\n                new SocketParameterException(\"Not a valid timeout option: \" ~ to!string(option)));\n        // WinSock returns the timeout values as a milliseconds DWORD,\n        // while Linux and BSD return a timeval struct.\n        version (Windows)\n        {\n            int msecs;\n            getOption(level, option, (&msecs)[0 .. 1]);\n            if (option == SocketOption.RCVTIMEO)\n                msecs += WINSOCK_TIMEOUT_SKEW;\n            result = dur!\"msecs\"(msecs);\n        }\n        else version (Posix)\n        {\n            TimeVal tv;\n            getOption(level, option, (&tv.ctimeval)[0 .. 1]);\n            result = dur!\"seconds\"(tv.seconds) + dur!\"usecs\"(tv.microseconds);\n        }\n        else static assert(false);\n    }\n\n    /// Set a socket option.\n    void setOption(SocketOptionLevel level, SocketOption option, void[] value) @trusted\n    {\n        if (_SOCKET_ERROR == .setsockopt(sock, cast(int) level,\n                                        cast(int) option, value.ptr, cast(uint) value.length))\n            throw new SocketOSException(\"Unable to set socket option\");\n    }\n\n\n    /// Common case for setting integer and boolean options.\n    void setOption(SocketOptionLevel level, SocketOption option, int32_t value) @trusted\n    {\n        setOption(level, option, (&value)[0 .. 1]);\n    }\n\n\n    /// Set the linger option.\n    void setOption(SocketOptionLevel level, SocketOption option, Linger value) @trusted\n    {\n        //setOption(cast(SocketOptionLevel) SocketOptionLevel.SOCKET, SocketOption.LINGER, (&value)[0 .. 1]);\n        setOption(level, option, (&value.clinger)[0 .. 1]);\n    }\n\n    /**\n     * Sets a timeout (duration) option, i.e. `SocketOption.SNDTIMEO` or\n     * `RCVTIMEO`. Zero indicates no timeout.\n     *\n     * In a typical application, you might also want to consider using\n     * a non-blocking socket instead of setting a timeout on a blocking one.\n     *\n     * Note: While the receive timeout setting is generally quite accurate\n     * on *nix systems even for smaller durations, there are two issues to\n     * be aware of on Windows: First, although undocumented, the effective\n     * timeout duration seems to be the one set on the socket plus half\n     * a second. `setOption()` tries to compensate for that, but still,\n     * timeouts under 500ms are not possible on Windows. Second, be aware\n     * that the actual amount of time spent until a blocking call returns\n     * randomly varies on the order of 10ms.\n     *\n     * Params:\n     *   level  = The level at which a socket option is defined.\n     *   option = Either `SocketOption.SNDTIMEO` or `SocketOption.RCVTIMEO`.\n     *   value  = The timeout duration to set. Must not be negative.\n     *\n     * Throws: `SocketException` if setting the options fails.\n     *\n     * Example:\n     * ---\n     * import std.datetime;\n     * import std.typecons;\n     * auto pair = socketPair();\n     * scope(exit) foreach (s; pair) s.close();\n     *\n     * // Set a receive timeout, and then wait at one end of\n     * // the socket pair, knowing that no data will arrive.\n     * pair[0].setOption(SocketOptionLevel.SOCKET,\n     *     SocketOption.RCVTIMEO, dur!\"seconds\"(1));\n     *\n     * auto sw = StopWatch(Yes.autoStart);\n     * ubyte[1] buffer;\n     * pair[0].receive(buffer);\n     * writefln(\"Waited %s ms until the socket timed out.\",\n     *     sw.peek.msecs);\n     * ---\n     */\n    void setOption(SocketOptionLevel level, SocketOption option, Duration value) @trusted\n    {\n        enforce(option == SocketOption.SNDTIMEO || option == SocketOption.RCVTIMEO,\n                new SocketParameterException(\"Not a valid timeout option: \" ~ to!string(option)));\n\n        enforce(value >= dur!\"hnsecs\"(0), new SocketParameterException(\n                    \"Timeout duration must not be negative.\"));\n\n        version (Windows)\n        {\n            import std.algorithm.comparison : max;\n\n            auto msecs = to!int(value.total!\"msecs\");\n            if (msecs != 0 && option == SocketOption.RCVTIMEO)\n                msecs = max(1, msecs - WINSOCK_TIMEOUT_SKEW);\n            setOption(level, option, msecs);\n        }\n        else version (Posix)\n        {\n            _ctimeval tv;\n            value.split!(\"seconds\", \"usecs\")(tv.tv_sec, tv.tv_usec);\n            setOption(level, option, (&tv)[0 .. 1]);\n        }\n        else static assert(false);\n    }\n\n    /**\n     * Get a text description of this socket's error status, and clear the\n     * socket's error status.\n     */\n    string getErrorText()\n    {\n        int32_t error;\n        getOption(SocketOptionLevel.SOCKET, SocketOption.ERROR, error);\n        return formatSocketError(error);\n    }\n\n    /**\n     * Enables TCP keep-alive with the specified parameters.\n     *\n     * Params:\n     *   time     = Number of seconds with no activity until the first\n     *              keep-alive packet is sent.\n     *   interval = Number of seconds between when successive keep-alive\n     *              packets are sent if no acknowledgement is received.\n     *\n     * Throws: `SocketOSException` if setting the options fails, or\n     * `SocketFeatureException` if setting keep-alive parameters is\n     * unsupported on the current platform.\n     */\n    void setKeepAlive(int time, int interval) @trusted\n    {\n        version (Windows)\n        {\n            tcp_keepalive options;\n            options.onoff = 1;\n            options.keepalivetime = time * 1000;\n            options.keepaliveinterval = interval * 1000;\n            uint cbBytesReturned;\n            enforce(WSAIoctl(sock, SIO_KEEPALIVE_VALS,\n                             &options, options.sizeof,\n                             null, 0,\n                             &cbBytesReturned, null, null) == 0,\n                    new SocketOSException(\"Error setting keep-alive\"));\n        }\n        else\n        static if (is(typeof(TCP_KEEPIDLE)) && is(typeof(TCP_KEEPINTVL)))\n        {\n            setOption(SocketOptionLevel.TCP, cast(SocketOption) TCP_KEEPIDLE, time);\n            setOption(SocketOptionLevel.TCP, cast(SocketOption) TCP_KEEPINTVL, interval);\n            setOption(SocketOptionLevel.SOCKET, SocketOption.KEEPALIVE, true);\n        }\n        else\n            throw new SocketFeatureException(\"Setting keep-alive options \" ~\n                \"is not supported on this platform\");\n    }\n\n    /**\n     * Wait for a socket to change status. A wait timeout of $(REF Duration, core, time) or\n     * `TimeVal`, may be specified; if a timeout is not specified or the\n     * `TimeVal` is `null`, the maximum timeout is used. The `TimeVal`\n     * timeout has an unspecified value when `select` returns.\n     * Returns: The number of sockets with status changes, `0` on timeout,\n     * or `-1` on interruption. If the return value is greater than `0`,\n     * the `SocketSets` are updated to only contain the sockets having status\n     * changes. For a connecting socket, a write status change means the\n     * connection is established and it's able to send. For a listening socket,\n     * a read status change means there is an incoming connection request and\n     * it's able to accept.\n     *\n     * `SocketSet`'s updated to include only those sockets which an event occured.\n     * For a `connect()`ing socket, writeability means connected.\n     * For a `listen()`ing socket, readability means listening\n     * `Winsock`; possibly internally limited to 64 sockets per set.\n     *\n     * Returns:\n     * the number of events, 0 on timeout, or -1 on interruption\n     */\n    static int select(SocketSet checkRead, SocketSet checkWrite, SocketSet checkError, Duration timeout) @trusted\n    {\n        auto vals = timeout.split!(\"seconds\", \"usecs\")();\n        TimeVal tv;\n        tv.seconds      = cast(tv.tv_sec_t ) vals.seconds;\n        tv.microseconds = cast(tv.tv_usec_t) vals.usecs;\n        return select(checkRead, checkWrite, checkError, &tv);\n    }\n\n    /// ditto\n    //maximum timeout\n    static int select(SocketSet checkRead, SocketSet checkWrite, SocketSet checkError)\n    {\n        return select(checkRead, checkWrite, checkError, null);\n    }\n\n    /// Ditto\n    static int select(SocketSet checkRead, SocketSet checkWrite, SocketSet checkError, TimeVal* timeout) @trusted\n    in\n    {\n        //make sure none of the SocketSet's are the same object\n        if (checkRead)\n        {\n            assert(checkRead !is checkWrite);\n            assert(checkRead !is checkError);\n        }\n        if (checkWrite)\n        {\n            assert(checkWrite !is checkError);\n        }\n    }\n    do\n    {\n        fd_set* fr, fw, fe;\n        int n = 0;\n\n        version (Windows)\n        {\n            // Windows has a problem with empty fd_set`s that aren't null.\n            fr = checkRead  && checkRead.count  ? checkRead.toFd_set()  : null;\n            fw = checkWrite && checkWrite.count ? checkWrite.toFd_set() : null;\n            fe = checkError && checkError.count ? checkError.toFd_set() : null;\n        }\n        else\n        {\n            if (checkRead)\n            {\n                fr = checkRead.toFd_set();\n                n = checkRead.selectn();\n            }\n            else\n            {\n                fr = null;\n            }\n\n            if (checkWrite)\n            {\n                fw = checkWrite.toFd_set();\n                int _n;\n                _n = checkWrite.selectn();\n                if (_n > n)\n                    n = _n;\n            }\n            else\n            {\n                fw = null;\n            }\n\n            if (checkError)\n            {\n                fe = checkError.toFd_set();\n                int _n;\n                _n = checkError.selectn();\n                if (_n > n)\n                    n = _n;\n            }\n            else\n            {\n                fe = null;\n            }\n\n            // Make sure the sets' capacity matches, to avoid select reading\n            // out of bounds just because one set was bigger than another\n            if (checkRead ) checkRead .setMinCapacity(n);\n            if (checkWrite) checkWrite.setMinCapacity(n);\n            if (checkError) checkError.setMinCapacity(n);\n        }\n\n        int result = .select(n, fr, fw, fe, &timeout.ctimeval);\n\n        version (Windows)\n        {\n            if (_SOCKET_ERROR == result && WSAGetLastError() == WSAEINTR)\n                return -1;\n        }\n        else version (Posix)\n        {\n            if (_SOCKET_ERROR == result && errno == EINTR)\n                return -1;\n        }\n        else\n        {\n            static assert(0);\n        }\n\n        if (_SOCKET_ERROR == result)\n            throw new SocketOSException(\"Socket select error\");\n\n        return result;\n    }\n\n\n    /**\n     * Can be overridden to support other addresses.\n     * Returns: a new `Address` object for the current address family.\n     */\n    protected Address createAddress() pure nothrow\n    {\n        Address result;\n        switch (_family)\n        {\n        static if (is(sockaddr_un))\n        {\n            case AddressFamily.UNIX:\n                result = new UnixAddress;\n                break;\n        }\n\n        case AddressFamily.INET:\n            result = new InternetAddress;\n            break;\n\n        case AddressFamily.INET6:\n            result = new Internet6Address;\n            break;\n\n        default:\n            result = new UnknownAddress;\n        }\n        return result;\n    }\n\n}\n\n\n/// `TcpSocket` is a shortcut class for a TCP Socket.\nclass TcpSocket: Socket\n{\n    /// Constructs a blocking TCP Socket.\n    this(AddressFamily family)\n    {\n        super(family, SocketType.STREAM, ProtocolType.TCP);\n    }\n\n    /// Constructs a blocking IPv4 TCP Socket.\n    this()\n    {\n        this(AddressFamily.INET);\n    }\n\n\n    //shortcut\n    /// Constructs a blocking TCP Socket and connects to an `Address`.\n    this(Address connectTo)\n    {\n        this(connectTo.addressFamily);\n        connect(connectTo);\n    }\n}\n\n\n/// `UdpSocket` is a shortcut class for a UDP Socket.\nclass UdpSocket: Socket\n{\n    /// Constructs a blocking UDP Socket.\n    this(AddressFamily family)\n    {\n        super(family, SocketType.DGRAM, ProtocolType.UDP);\n    }\n\n\n    /// Constructs a blocking IPv4 UDP Socket.\n    this()\n    {\n        this(AddressFamily.INET);\n    }\n}\n\n// Issue 16514\n@safe unittest\n{\n    class TestSocket : Socket\n    {\n        override\n        {\n            const pure nothrow @nogc @property @safe socket_t handle() { assert(0); }\n            const nothrow @nogc @property @trusted bool blocking() { assert(0); }\n            @property @trusted void blocking(bool byes) { assert(0); }\n            @property @safe AddressFamily addressFamily() { assert(0); }\n            const @property @trusted bool isAlive() { assert(0); }\n            @trusted void bind(Address addr) { assert(0); }\n            @trusted void connect(Address to) { assert(0); }\n            @trusted void listen(int backlog) { assert(0); }\n            protected pure nothrow @safe Socket accepting() { assert(0); }\n            @trusted Socket accept() { assert(0); }\n            nothrow @nogc @trusted void shutdown(SocketShutdown how) { assert(0); }\n            nothrow @nogc @trusted void close() { assert(0); }\n            @property @trusted Address remoteAddress() { assert(0); }\n            @property @trusted Address localAddress() { assert(0); }\n            @trusted ptrdiff_t send(const(void)[] buf, SocketFlags flags) { assert(0); }\n            @safe ptrdiff_t send(const(void)[] buf) { assert(0); }\n            @trusted ptrdiff_t sendTo(const(void)[] buf, SocketFlags flags, Address to) { assert(0); }\n            @safe ptrdiff_t sendTo(const(void)[] buf, Address to) { assert(0); }\n            @trusted ptrdiff_t sendTo(const(void)[] buf, SocketFlags flags) { assert(0); }\n            @safe ptrdiff_t sendTo(const(void)[] buf) { assert(0); }\n            @trusted ptrdiff_t receive(void[] buf, SocketFlags flags) { assert(0); }\n            @safe ptrdiff_t receive(void[] buf) { assert(0); }\n            @trusted ptrdiff_t receiveFrom(void[] buf, SocketFlags flags, ref Address from) { assert(0); }\n            @safe ptrdiff_t receiveFrom(void[] buf, ref Address from) { assert(0); }\n            @trusted ptrdiff_t receiveFrom(void[] buf, SocketFlags flags) { assert(0); }\n            @safe ptrdiff_t receiveFrom(void[] buf) { assert(0); }\n            @trusted int getOption(SocketOptionLevel level, SocketOption option, void[] result) { assert(0); }\n            @trusted int getOption(SocketOptionLevel level, SocketOption option, out int32_t result) { assert(0); }\n            @trusted int getOption(SocketOptionLevel level, SocketOption option, out Linger result) { assert(0); }\n            @trusted void getOption(SocketOptionLevel level, SocketOption option, out Duration result) { assert(0); }\n            @trusted void setOption(SocketOptionLevel level, SocketOption option, void[] value) { assert(0); }\n            @trusted void setOption(SocketOptionLevel level, SocketOption option, int32_t value) { assert(0); }\n            @trusted void setOption(SocketOptionLevel level, SocketOption option, Linger value) { assert(0); }\n            @trusted void setOption(SocketOptionLevel level, SocketOption option, Duration value) { assert(0); }\n            @safe string getErrorText() { assert(0); }\n            @trusted void setKeepAlive(int time, int interval) { assert(0); }\n            protected pure nothrow @safe Address createAddress() { assert(0); }\n        }\n    }\n}\n\n/**\n * Creates a pair of connected sockets.\n *\n * The two sockets are indistinguishable.\n *\n * Throws: `SocketException` if creation of the sockets fails.\n */\nSocket[2] socketPair() @trusted\n{\n    version (Posix)\n    {\n        int[2] socks;\n        if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1)\n            throw new SocketOSException(\"Unable to create socket pair\");\n\n        Socket toSocket(size_t id)\n        {\n            auto s = new Socket;\n            s.setSock(cast(socket_t) socks[id]);\n            s._family = AddressFamily.UNIX;\n            return s;\n        }\n\n        return [toSocket(0), toSocket(1)];\n    }\n    else version (Windows)\n    {\n        // We do not have socketpair() on Windows, just manually create a\n        // pair of sockets connected over some localhost port.\n        Socket[2] result;\n\n        auto listener = new TcpSocket();\n        listener.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true);\n        listener.bind(new InternetAddress(INADDR_LOOPBACK, InternetAddress.PORT_ANY));\n        auto addr = listener.localAddress;\n        listener.listen(1);\n\n        result[0] = new TcpSocket(addr);\n        result[1] = listener.accept();\n\n        listener.close();\n        return result;\n    }\n    else\n        static assert(false);\n}\n\n///\n@safe unittest\n{\n    immutable ubyte[] data = [1, 2, 3, 4];\n    auto pair = socketPair();\n    scope(exit) foreach (s; pair) s.close();\n\n    pair[0].send(data);\n\n    auto buf = new ubyte[data.length];\n    pair[1].receive(buf);\n    assert(buf == data);\n}\n"
  },
  {
    "path": "libphobos/src/std/stdint.d",
    "content": "// Written in the D programming language.\n\n/**\n *\n    D constrains integral types to specific sizes. But efficiency\n    of different sizes varies from machine to machine,\n    pointer sizes vary, and the maximum integer size varies.\n    <b>stdint</b> offers a portable way of trading off size\n    vs efficiency, in a manner compatible with the <tt>stdint.h</tt>\n    definitions in C.\n\n    In the table below, the $(B exact alias)es are types of exactly the\n    specified number of bits.\n    The $(B at least alias)es are at least the specified number of bits\n    large, and can be larger.\n    The $(B fast alias)es are the fastest integral type supported by the\n    processor that is at least as wide as the specified number of bits.\n\n    The aliases are:\n\n    $(ATABLE $(TR\n    $(TH Exact Alias)\n    $(TH Description)\n    $(TH At Least Alias)\n    $(TH Description)\n    $(TH Fast Alias)\n    $(TH Description)\n    )$(TR\n    $(TD int8_t)\n    $(TD exactly 8 bits signed)\n    $(TD int_least8_t)\n    $(TD at least 8 bits signed)\n    $(TD int_fast8_t)\n    $(TD fast 8 bits signed)\n    )$(TR\n    $(TD uint8_t)\n    $(TD exactly 8 bits unsigned)\n    $(TD uint_least8_t)\n    $(TD at least 8 bits unsigned)\n    $(TD uint_fast8_t)\n    $(TD fast 8 bits unsigned)\n\n    )$(TR\n    $(TD int16_t)\n    $(TD exactly 16 bits signed)\n    $(TD int_least16_t)\n    $(TD at least 16 bits signed)\n    $(TD int_fast16_t)\n    $(TD fast 16 bits signed)\n    )$(TR\n    $(TD uint16_t)\n    $(TD exactly 16 bits unsigned)\n    $(TD uint_least16_t)\n    $(TD at least 16 bits unsigned)\n    $(TD uint_fast16_t)\n    $(TD fast 16 bits unsigned)\n\n    )$(TR\n    $(TD int32_t)\n    $(TD exactly 32 bits signed)\n    $(TD int_least32_t)\n    $(TD at least 32 bits signed)\n    $(TD int_fast32_t)\n    $(TD fast 32 bits signed)\n    )$(TR\n    $(TD uint32_t)\n    $(TD exactly 32 bits unsigned)\n    $(TD uint_least32_t)\n    $(TD at least 32 bits unsigned)\n    $(TD uint_fast32_t)\n    $(TD fast 32 bits unsigned)\n\n    )$(TR\n    $(TD int64_t)\n    $(TD exactly 64 bits signed)\n    $(TD int_least64_t)\n    $(TD at least 64 bits signed)\n    $(TD int_fast64_t)\n    $(TD fast 64 bits signed)\n    )$(TR\n    $(TD uint64_t)\n    $(TD exactly 64 bits unsigned)\n    $(TD uint_least64_t)\n    $(TD at least 64 bits unsigned)\n    $(TD uint_fast64_t)\n    $(TD fast 64 bits unsigned)\n    ))\n\n    The ptr aliases are integral types guaranteed to be large enough\n    to hold a pointer without losing bits:\n\n    $(ATABLE $(TR\n    $(TH Alias)\n    $(TH Description)\n    )$(TR\n    $(TD intptr_t)\n    $(TD signed integral type large enough to hold a pointer)\n    )$(TR\n    $(TD uintptr_t)\n    $(TD unsigned integral type large enough to hold a pointer)\n    ))\n\n    The max aliases are the largest integral types:\n\n    $(ATABLE $(TR\n    $(TH Alias)\n    $(TH Description)\n    )$(TR\n    $(TD intmax_t)\n    $(TD the largest signed integral type)\n    )$(TR\n    $(TD uintmax_t)\n    $(TD the largest unsigned integral type)\n    ))\n\n * Macros:\n *  ATABLE=<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">$0</table>\n *\n * Copyright: Copyright The D Language Foundation 2000 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright)\n * Source:    $(PHOBOSSRC std/stdint.d)\n */\n/*          Copyright The D Language Foundation 2000 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.stdint;\n\npublic import core.stdc.stdint;\n"
  },
  {
    "path": "libphobos/src/std/stdio.d",
    "content": "// Written in the D programming language.\n\n/**\nStandard I/O functions that extend $(B core.stdc.stdio).  $(B core.stdc.stdio)\nis $(D_PARAM public)ally imported when importing $(B std.stdio).\n\nSource: $(PHOBOSSRC std/stdio.d)\nCopyright: Copyright The D Language Foundation 2007-.\nLicense:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   $(HTTP digitalmars.com, Walter Bright),\n           $(HTTP erdani.org, Andrei Alexandrescu),\n           Alex Rønne Petersen\n */\nmodule std.stdio;\n\nimport core.stdc.stddef; // wchar_t\npublic import core.stdc.stdio;\nimport std.algorithm.mutation; // copy\nimport std.meta; // allSatisfy\nimport std.range.primitives; // ElementEncodingType, empty, front,\n    // isBidirectionalRange, isInputRange, put\nimport std.traits; // isSomeChar, isSomeString, Unqual, isPointer\nimport std.typecons; // Flag\n\n/++\nIf flag `KeepTerminator` is set to `KeepTerminator.yes`, then the delimiter\nis included in the strings returned.\n+/\nalias KeepTerminator = Flag!\"keepTerminator\";\n\nversion (CRuntime_Microsoft)\n{\n    version = MICROSOFT_STDIO;\n}\nelse version (CRuntime_DigitalMars)\n{\n    // Specific to the way Digital Mars C does stdio\n    version = DIGITAL_MARS_STDIO;\n}\n\nversion (CRuntime_Glibc)\n{\n    // Specific to the way Gnu C does stdio\n    version = GCC_IO;\n    version = HAS_GETDELIM;\n}\nelse version (CRuntime_Bionic)\n{\n    version = GENERIC_IO;\n    version = HAS_GETDELIM;\n}\nelse version (CRuntime_Musl)\n{\n    version = GENERIC_IO;\n    version = HAS_GETDELIM;\n}\nelse version (CRuntime_UClibc)\n{\n    // uClibc supports GCC IO\n    version = GCC_IO;\n    version = HAS_GETDELIM;\n}\n\nversion (OSX)\n{\n    version = GENERIC_IO;\n    version = HAS_GETDELIM;\n}\nelse version (FreeBSD)\n{\n    version = GENERIC_IO;\n    version = HAS_GETDELIM;\n}\nelse version (NetBSD)\n{\n    version = GENERIC_IO;\n    version = HAS_GETDELIM;\n}\nelse version (DragonFlyBSD)\n{\n    version = GENERIC_IO;\n    version = HAS_GETDELIM;\n}\nelse version (Solaris)\n{\n    version = GENERIC_IO;\n    version = NO_GETDELIM;\n}\n\n// Character type used for operating system filesystem APIs\nversion (Windows)\n{\n    private alias FSChar = wchar;\n}\nelse version (Posix)\n{\n    private alias FSChar = char;\n}\nelse\n    static assert(0);\n\nversion (Windows)\n{\n    // core.stdc.stdio.fopen expects file names to be\n    // encoded in CP_ACP on Windows instead of UTF-8.\n    /+ Waiting for druntime pull 299\n    +/\n    extern (C) nothrow @nogc FILE* _wfopen(in wchar* filename, in wchar* mode);\n    extern (C) nothrow @nogc FILE* _wfreopen(in wchar* filename, in wchar* mode, FILE* fp);\n\n    import core.sys.windows.windows : HANDLE;\n}\n\nversion (DIGITAL_MARS_STDIO)\n{\n    extern (C)\n    {\n        /* **\n         * Digital Mars under-the-hood C I/O functions.\n         * Use _iobuf* for the unshared version of FILE*,\n         * usable when the FILE is locked.\n         */\n      nothrow:\n      @nogc:\n        int _fputc_nlock(int, _iobuf*);\n        int _fputwc_nlock(int, _iobuf*);\n        int _fgetc_nlock(_iobuf*);\n        int _fgetwc_nlock(_iobuf*);\n        int __fp_lock(FILE*);\n        void __fp_unlock(FILE*);\n\n        int setmode(int, int);\n    }\n    alias FPUTC = _fputc_nlock;\n    alias FPUTWC = _fputwc_nlock;\n    alias FGETC = _fgetc_nlock;\n    alias FGETWC = _fgetwc_nlock;\n\n    alias FLOCK = __fp_lock;\n    alias FUNLOCK = __fp_unlock;\n\n    alias _setmode = setmode;\n    int _fileno(FILE* f) { return f._file; }\n    alias fileno = _fileno;\n}\nelse version (MICROSOFT_STDIO)\n{\n    extern (C)\n    {\n        /* **\n         * Microsoft under-the-hood C I/O functions\n         */\n      nothrow:\n      @nogc:\n        int _fputc_nolock(int, _iobuf*);\n        int _fputwc_nolock(int, _iobuf*);\n        int _fgetc_nolock(_iobuf*);\n        int _fgetwc_nolock(_iobuf*);\n        void _lock_file(FILE*);\n        void _unlock_file(FILE*);\n        int _setmode(int, int);\n        int _fileno(FILE*);\n        FILE* _fdopen(int, const (char)*);\n        int _fseeki64(FILE*, long, int);\n        long _ftelli64(FILE*);\n    }\n    alias FPUTC = _fputc_nolock;\n    alias FPUTWC = _fputwc_nolock;\n    alias FGETC = _fgetc_nolock;\n    alias FGETWC = _fgetwc_nolock;\n\n    alias FLOCK = _lock_file;\n    alias FUNLOCK = _unlock_file;\n\n    alias setmode = _setmode;\n    alias fileno = _fileno;\n}\nelse version (GCC_IO)\n{\n    /* **\n     * Gnu under-the-hood C I/O functions; see\n     * http://gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html\n     */\n    extern (C)\n    {\n      nothrow:\n      @nogc:\n        int fputc_unlocked(int, _iobuf*);\n        int fputwc_unlocked(wchar_t, _iobuf*);\n        int fgetc_unlocked(_iobuf*);\n        int fgetwc_unlocked(_iobuf*);\n        void flockfile(FILE*);\n        void funlockfile(FILE*);\n\n        private size_t fwrite_unlocked(const(void)* ptr,\n                size_t size, size_t n, _iobuf *stream);\n    }\n\n    alias FPUTC = fputc_unlocked;\n    alias FPUTWC = fputwc_unlocked;\n    alias FGETC = fgetc_unlocked;\n    alias FGETWC = fgetwc_unlocked;\n\n    alias FLOCK = flockfile;\n    alias FUNLOCK = funlockfile;\n}\nelse version (GENERIC_IO)\n{\n    nothrow:\n    @nogc:\n\n    extern (C)\n    {\n        void flockfile(FILE*);\n        void funlockfile(FILE*);\n    }\n\n    int fputc_unlocked(int c, _iobuf* fp) { return fputc(c, cast(shared) fp); }\n    int fputwc_unlocked(wchar_t c, _iobuf* fp)\n    {\n        import core.stdc.wchar_ : fputwc;\n        return fputwc(c, cast(shared) fp);\n    }\n    int fgetc_unlocked(_iobuf* fp) { return fgetc(cast(shared) fp); }\n    int fgetwc_unlocked(_iobuf* fp)\n    {\n        import core.stdc.wchar_ : fgetwc;\n        return fgetwc(cast(shared) fp);\n    }\n\n    alias FPUTC = fputc_unlocked;\n    alias FPUTWC = fputwc_unlocked;\n    alias FGETC = fgetc_unlocked;\n    alias FGETWC = fgetwc_unlocked;\n\n    alias FLOCK = flockfile;\n    alias FUNLOCK = funlockfile;\n}\nelse\n{\n    static assert(0, \"unsupported C I/O system\");\n}\n\nversion (HAS_GETDELIM) extern(C) nothrow @nogc\n{\n    ptrdiff_t getdelim(char**, size_t*, int, FILE*);\n    // getline() always comes together with getdelim()\n    ptrdiff_t getline(char**, size_t*, FILE*);\n}\n\n//------------------------------------------------------------------------------\nprivate struct ByRecordImpl(Fields...)\n{\nprivate:\n    import std.typecons : Tuple;\n\n    File file;\n    char[] line;\n    Tuple!(Fields) current;\n    string format;\n\npublic:\n    this(File f, string format)\n    {\n        assert(f.isOpen);\n        file = f;\n        this.format = format;\n        popFront(); // prime the range\n    }\n\n    /// Range primitive implementations.\n    @property bool empty()\n    {\n        return !file.isOpen;\n    }\n\n    /// Ditto\n    @property ref Tuple!(Fields) front()\n    {\n        return current;\n    }\n\n    /// Ditto\n    void popFront()\n    {\n        import std.conv : text;\n        import std.exception : enforce;\n        import std.format : formattedRead;\n        import std.string : chomp;\n\n        enforce(file.isOpen, \"ByRecord: File must be open\");\n        file.readln(line);\n        if (!line.length)\n        {\n            file.detach();\n        }\n        else\n        {\n            line = chomp(line);\n            formattedRead(line, format, &current);\n            enforce(line.empty, text(\"Leftover characters in record: `\",\n                            line, \"'\"));\n        }\n    }\n}\n\n// @@@DEPRECATED_2019-01@@@\ndeprecated(\"Use .byRecord\")\nstruct ByRecord(Fields...)\n{\n    ByRecordImpl!Fields payload;\n    alias payload this;\n}\n\ntemplate byRecord(Fields...)\n{\n    auto byRecord(File f, string format)\n    {\n        return typeof(return)(f, format);\n    }\n}\n\n/**\nEncapsulates a `FILE*`. Generally D does not attempt to provide\nthin wrappers over equivalent functions in the C standard library, but\nmanipulating `FILE*` values directly is unsafe and error-prone in\nmany ways. The `File` type ensures safe manipulation, automatic\nfile closing, and a lot of convenience.\n\nThe underlying `FILE*` handle is maintained in a reference-counted\nmanner, such that as soon as the last `File` variable bound to a\ngiven `FILE*` goes out of scope, the underlying `FILE*` is\nautomatically closed.\n\nExample:\n----\n// test.d\nvoid main(string[] args)\n{\n    auto f = File(\"test.txt\", \"w\"); // open for writing\n    f.write(\"Hello\");\n    if (args.length > 1)\n    {\n        auto g = f; // now g and f write to the same file\n                    // internal reference count is 2\n        g.write(\", \", args[1]);\n        // g exits scope, reference count decreases to 1\n    }\n    f.writeln(\"!\");\n    // f exits scope, reference count falls to zero,\n    // underlying `FILE*` is closed.\n}\n----\n$(CONSOLE\n% rdmd test.d Jimmy\n% cat test.txt\nHello, Jimmy!\n% __\n)\n */\nstruct File\n{\n    import core.atomic : atomicOp, atomicStore, atomicLoad;\n    import std.range.primitives : ElementEncodingType;\n    import std.traits : isScalarType, isArray;\n    enum Orientation { unknown, narrow, wide }\n\n    private struct Impl\n    {\n        FILE * handle = null; // Is null iff this Impl is closed by another File\n        shared uint refs = uint.max / 2;\n        bool isPopened; // true iff the stream has been created by popen()\n        Orientation orientation;\n    }\n    private Impl* _p;\n    private string _name;\n\n    package this(FILE* handle, string name, uint refs = 1, bool isPopened = false) @trusted\n    {\n        import core.stdc.stdlib : malloc;\n        import std.exception : enforce;\n\n        assert(!_p);\n        _p = cast(Impl*) enforce(malloc(Impl.sizeof), \"Out of memory\");\n        initImpl(handle, name, refs, isPopened);\n    }\n\n    private void initImpl(FILE* handle, string name, uint refs = 1, bool isPopened = false)\n    {\n        assert(_p);\n        _p.handle = handle;\n        atomicStore(_p.refs, refs);\n        _p.isPopened = isPopened;\n        _p.orientation = Orientation.unknown;\n        _name = name;\n    }\n\n/**\nConstructor taking the name of the file to open and the open mode.\n\nCopying one `File` object to another results in the two `File`\nobjects referring to the same underlying file.\n\nThe destructor automatically closes the file as soon as no `File`\nobject refers to it anymore.\n\nParams:\n    name = range or string representing the file _name\n    stdioOpenmode = range or string represting the open mode\n        (with the same semantics as in the C standard library\n        $(HTTP cplusplus.com/reference/clibrary/cstdio/fopen.html, fopen)\n        function)\n\nThrows: `ErrnoException` if the file could not be opened.\n */\n    this(string name, scope const(char)[] stdioOpenmode = \"rb\") @safe\n    {\n        import std.conv : text;\n        import std.exception : errnoEnforce;\n\n        this(errnoEnforce(_fopen(name, stdioOpenmode),\n                        text(\"Cannot open file `\", name, \"' in mode `\",\n                                stdioOpenmode, \"'\")),\n                name);\n\n        // MSVCRT workaround (issue 14422)\n        version (MICROSOFT_STDIO)\n        {\n            setAppendWin(stdioOpenmode);\n        }\n    }\n\n    /// ditto\n    this(R1, R2)(R1 name)\n        if (isInputRange!R1 && isSomeChar!(ElementEncodingType!R1))\n    {\n        import std.conv : to;\n        this(name.to!string, \"rb\");\n    }\n\n    /// ditto\n    this(R1, R2)(R1 name, R2 mode)\n        if (isInputRange!R1 && isSomeChar!(ElementEncodingType!R1) &&\n            isInputRange!R2 && isSomeChar!(ElementEncodingType!R2))\n    {\n        import std.conv : to;\n        this(name.to!string, mode.to!string);\n    }\n\n    @safe unittest\n    {\n        static import std.file;\n        import std.utf : byChar;\n        auto deleteme = testFilename();\n        auto f = File(deleteme.byChar, \"w\".byChar);\n        f.close();\n        std.file.remove(deleteme);\n    }\n\n    ~this() @safe\n    {\n        detach();\n    }\n\n    this(this) @safe nothrow\n    {\n        if (!_p) return;\n        assert(atomicLoad(_p.refs));\n        atomicOp!\"+=\"(_p.refs, 1);\n    }\n\n/**\nAssigns a file to another. The target of the assignment gets detached\nfrom whatever file it was attached to, and attaches itself to the new\nfile.\n */\n    void opAssign(File rhs) @safe\n    {\n        import std.algorithm.mutation : swap;\n\n        swap(this, rhs);\n    }\n\n/**\nDetaches from the current file (throwing on failure), and then attempts to\n_open file `name` with mode `stdioOpenmode`. The mode has the\nsame semantics as in the C standard library $(HTTP\ncplusplus.com/reference/clibrary/cstdio/fopen.html, fopen) function.\n\nThrows: `ErrnoException` in case of error.\n */\n    void open(string name, scope const(char)[] stdioOpenmode = \"rb\") @trusted\n    {\n        resetFile(name, stdioOpenmode, false);\n    }\n\n    private void resetFile(string name, scope const(char)[] stdioOpenmode, bool isPopened) @trusted\n    {\n        import core.stdc.stdlib : malloc;\n        import std.exception : enforce;\n        import std.conv : text;\n        import std.exception : errnoEnforce;\n\n        if (_p !is null)\n        {\n            detach();\n        }\n\n        _p = cast(Impl*) enforce(malloc(Impl.sizeof), \"Out of memory\");\n        FILE* handle;\n        version (Posix)\n        {\n            if (isPopened)\n            {\n                errnoEnforce(handle = _popen(name, stdioOpenmode),\n                             \"Cannot run command `\"~name~\"'\");\n            }\n            else\n            {\n                errnoEnforce(handle = _fopen(name, stdioOpenmode),\n                             text(\"Cannot open file `\", name, \"' in mode `\",\n                                  stdioOpenmode, \"'\"));\n            }\n        }\n        else\n        {\n            assert(isPopened == false);\n            errnoEnforce(handle = _fopen(name, stdioOpenmode),\n                         text(\"Cannot open file `\", name, \"' in mode `\",\n                              stdioOpenmode, \"'\"));\n        }\n        initImpl(handle, name, 1, isPopened);\n        version (MICROSOFT_STDIO)\n        {\n            setAppendWin(stdioOpenmode);\n        }\n    }\n\n    private void closeHandles() @trusted\n    {\n        assert(_p);\n        import std.exception : errnoEnforce;\n\n        version (Posix)\n        {\n            import core.sys.posix.stdio : pclose;\n            import std.format : format;\n\n            if (_p.isPopened)\n            {\n                auto res = pclose(_p.handle);\n                errnoEnforce(res != -1,\n                        \"Could not close pipe `\"~_name~\"'\");\n                _p.handle = null;\n                return;\n            }\n        }\n        if (_p.handle)\n        {\n            errnoEnforce(.fclose(_p.handle) == 0,\n                    \"Could not close file `\"~_name~\"'\");\n            _p.handle = null;\n        }\n    }\n\n    version (MICROSOFT_STDIO)\n    {\n        private void setAppendWin(scope const(char)[] stdioOpenmode) @safe\n        {\n            bool append, update;\n            foreach (c; stdioOpenmode)\n                if (c == 'a')\n                    append = true;\n                else\n                if (c == '+')\n                    update = true;\n            if (append && !update)\n                seek(size);\n        }\n    }\n\n/**\nReuses the `File` object to either open a different file, or change\nthe file mode. If `name` is `null`, the mode of the currently open\nfile is changed; otherwise, a new file is opened, reusing the C\n`FILE*`. The function has the same semantics as in the C standard\nlibrary $(HTTP cplusplus.com/reference/cstdio/freopen/, freopen)\nfunction.\n\nNote: Calling `reopen` with a `null` `name` is not implemented\nin all C runtimes.\n\nThrows: `ErrnoException` in case of error.\n */\n    void reopen(string name, scope const(char)[] stdioOpenmode = \"rb\") @trusted\n    {\n        import std.conv : text;\n        import std.exception : enforce, errnoEnforce;\n        import std.internal.cstring : tempCString;\n\n        enforce(isOpen, \"Attempting to reopen() an unopened file\");\n\n        auto namez = (name == null ? _name : name).tempCString!FSChar();\n        auto modez = stdioOpenmode.tempCString!FSChar();\n\n        FILE* fd = _p.handle;\n        version (Windows)\n            fd =  _wfreopen(namez, modez, fd);\n        else\n            fd = freopen(namez, modez, fd);\n\n        errnoEnforce(fd, name\n            ? text(\"Cannot reopen file `\", name, \"' in mode `\", stdioOpenmode, \"'\")\n            : text(\"Cannot reopen file in mode `\", stdioOpenmode, \"'\"));\n\n        if (name !is null)\n            _name = name;\n    }\n\n    @system unittest // Test changing filename\n    {\n        import std.exception : assertThrown, assertNotThrown;\n        static import std.file;\n\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"foo\");\n        scope(exit) std.file.remove(deleteme);\n        auto f = File(deleteme);\n        assert(f.readln() == \"foo\");\n\n        auto deleteme2 = testFilename();\n        std.file.write(deleteme2, \"bar\");\n        scope(exit) std.file.remove(deleteme2);\n        f.reopen(deleteme2);\n        assert(f.name == deleteme2);\n        assert(f.readln() == \"bar\");\n        f.close();\n    }\n\n    version (CRuntime_DigitalMars) {} else // Not implemented\n    version (CRuntime_Microsoft) {} else // Not implemented\n    @system unittest // Test changing mode\n    {\n        import std.exception : assertThrown, assertNotThrown;\n        static import std.file;\n\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"foo\");\n        scope(exit) std.file.remove(deleteme);\n        auto f = File(deleteme, \"r+\");\n        assert(f.readln() == \"foo\");\n        f.reopen(null, \"w\");\n        f.write(\"bar\");\n        f.seek(0);\n        f.reopen(null, \"a\");\n        f.write(\"baz\");\n        assert(f.name == deleteme);\n        f.close();\n        assert(std.file.readText(deleteme) == \"barbaz\");\n    }\n\n/**\nDetaches from the current file (throwing on failure), and then runs a command\nby calling the C standard library function $(HTTP\nopengroup.org/onlinepubs/007908799/xsh/_popen.html, _popen).\n\nThrows: `ErrnoException` in case of error.\n */\n    version (Posix) void popen(string command, scope const(char)[] stdioOpenmode = \"r\") @safe\n    {\n        resetFile(command, stdioOpenmode ,true);\n    }\n\n/**\nFirst calls `detach` (throwing on failure), and then attempts to\nassociate the given file descriptor with the `File`. The mode must\nbe compatible with the mode of the file descriptor.\n\nThrows: `ErrnoException` in case of error.\n */\n    void fdopen(int fd, scope const(char)[] stdioOpenmode = \"rb\") @safe\n    {\n        fdopen(fd, stdioOpenmode, null);\n    }\n\n    package void fdopen(int fd, scope const(char)[] stdioOpenmode, string name) @trusted\n    {\n        import std.exception : errnoEnforce;\n        import std.internal.cstring : tempCString;\n\n        auto modez = stdioOpenmode.tempCString();\n        detach();\n\n        version (DIGITAL_MARS_STDIO)\n        {\n            // This is a re-implementation of DMC's fdopen, but without the\n            // mucking with the file descriptor.  POSIX standard requires the\n            // new fdopen'd file to retain the given file descriptor's\n            // position.\n            auto fp = fopen(\"NUL\", modez);\n            errnoEnforce(fp, \"Cannot open placeholder NUL stream\");\n            FLOCK(fp);\n            auto iob = cast(_iobuf*) fp;\n            .close(iob._file);\n            iob._file = fd;\n            iob._flag &= ~_IOTRAN;\n            FUNLOCK(fp);\n        }\n        else\n        {\n            version (Windows) // MSVCRT\n                auto fp = _fdopen(fd, modez);\n            else version (Posix)\n            {\n                import core.sys.posix.stdio : fdopen;\n                auto fp = fdopen(fd, modez);\n            }\n            errnoEnforce(fp);\n        }\n        this = File(fp, name);\n    }\n\n    // Declare a dummy HANDLE to allow generating documentation\n    // for Windows-only methods.\n    version (StdDdoc) { version (Windows) {} else alias HANDLE = int; }\n\n/**\nFirst calls `detach` (throwing on failure), and then attempts to\nassociate the given Windows `HANDLE` with the `File`. The mode must\nbe compatible with the access attributes of the handle. Windows only.\n\nThrows: `ErrnoException` in case of error.\n*/\n    version (StdDdoc)\n    void windowsHandleOpen(HANDLE handle, scope const(char)[] stdioOpenmode);\n\n    version (Windows)\n    void windowsHandleOpen(HANDLE handle, scope const(char)[] stdioOpenmode)\n    {\n        import core.stdc.stdint : intptr_t;\n        import std.exception : errnoEnforce;\n        import std.format : format;\n\n        // Create file descriptors from the handles\n        version (DIGITAL_MARS_STDIO)\n            auto fd = _handleToFD(handle, FHND_DEVICE);\n        else // MSVCRT\n        {\n            int mode;\n            modeLoop:\n            foreach (c; stdioOpenmode)\n                switch (c)\n                {\n                    case 'r': mode |= _O_RDONLY; break;\n                    case '+': mode &=~_O_RDONLY; break;\n                    case 'a': mode |= _O_APPEND; break;\n                    case 'b': mode |= _O_BINARY; break;\n                    case 't': mode |= _O_TEXT;   break;\n                    case ',': break modeLoop;\n                    default: break;\n                }\n\n            auto fd = _open_osfhandle(cast(intptr_t) handle, mode);\n        }\n\n        errnoEnforce(fd >= 0, \"Cannot open Windows HANDLE\");\n        fdopen(fd, stdioOpenmode, \"HANDLE(%s)\".format(handle));\n    }\n\n\n/** Returns `true` if the file is opened. */\n    @property bool isOpen() const @safe pure nothrow\n    {\n        return _p !is null && _p.handle;\n    }\n\n/**\nReturns `true` if the file is at end (see $(HTTP\ncplusplus.com/reference/clibrary/cstdio/feof.html, feof)).\n\nThrows: `Exception` if the file is not opened.\n */\n    @property bool eof() const @trusted pure\n    {\n        import std.exception : enforce;\n\n        enforce(_p && _p.handle, \"Calling eof() against an unopened file.\");\n        return .feof(cast(FILE*) _p.handle) != 0;\n    }\n\n/** Returns the name of the last opened file, if any.\nIf a `File` was created with $(LREF tmpfile) and $(LREF wrapFile)\nit has no name.*/\n    @property string name() const @safe pure nothrow\n    {\n        return _name;\n    }\n\n/**\nIf the file is not opened, returns `true`. Otherwise, returns\n$(HTTP cplusplus.com/reference/clibrary/cstdio/ferror.html, ferror) for\nthe file handle.\n */\n    @property bool error() const @trusted pure nothrow\n    {\n        return !isOpen || .ferror(cast(FILE*) _p.handle);\n    }\n\n    @safe unittest\n    {\n        // Issue 12349\n        static import std.file;\n        auto deleteme = testFilename();\n        auto f = File(deleteme, \"w\");\n        scope(exit) std.file.remove(deleteme);\n\n        f.close();\n        assert(f.error);\n    }\n\n/**\nDetaches from the underlying file. If the sole owner, calls `close`.\n\nThrows: `ErrnoException` on failure if closing the file.\n  */\n    void detach() @trusted\n    {\n        import core.stdc.stdlib : free;\n\n        if (!_p) return;\n        scope(exit) _p = null;\n\n        if (atomicOp!\"-=\"(_p.refs, 1) == 0)\n        {\n            scope(exit) free(_p);\n            closeHandles();\n        }\n    }\n\n    @safe unittest\n    {\n        static import std.file;\n\n        auto deleteme = testFilename();\n        scope(exit) std.file.remove(deleteme);\n        auto f = File(deleteme, \"w\");\n        {\n            auto f2 = f;\n            f2.detach();\n        }\n        assert(f._p.refs == 1);\n        f.close();\n    }\n\n/**\nIf the file was unopened, succeeds vacuously. Otherwise closes the\nfile (by calling $(HTTP\ncplusplus.com/reference/clibrary/cstdio/fclose.html, fclose)),\nthrowing on error. Even if an exception is thrown, afterwards the $(D\nFile) object is empty. This is different from `detach` in that it\nalways closes the file; consequently, all other `File` objects\nreferring to the same handle will see a closed file henceforth.\n\nThrows: `ErrnoException` on error.\n */\n    void close() @trusted\n    {\n        import core.stdc.stdlib : free;\n        import std.exception : errnoEnforce;\n\n        if (!_p) return; // succeed vacuously\n        scope(exit)\n        {\n            if (atomicOp!\"-=\"(_p.refs, 1) == 0)\n                free(_p);\n            _p = null; // start a new life\n        }\n        if (!_p.handle) return; // Impl is closed by another File\n\n        scope(exit) _p.handle = null; // nullify the handle anyway\n        closeHandles();\n    }\n\n/**\nIf the file is not opened, succeeds vacuously. Otherwise, returns\n$(HTTP cplusplus.com/reference/clibrary/cstdio/_clearerr.html,\n_clearerr) for the file handle.\n */\n    void clearerr() @safe pure nothrow\n    {\n        _p is null || _p.handle is null ||\n        .clearerr(_p.handle);\n    }\n\n/**\nFlushes the C `FILE` buffers.\n\nCalls $(HTTP cplusplus.com/reference/clibrary/cstdio/_fflush.html, _fflush)\nfor the file handle.\n\nThrows: `Exception` if the file is not opened or if the call to `fflush` fails.\n */\n    void flush() @trusted\n    {\n        import std.exception : enforce, errnoEnforce;\n\n        enforce(isOpen, \"Attempting to flush() in an unopened file\");\n        errnoEnforce(.fflush(_p.handle) == 0);\n    }\n\n    @safe unittest\n    {\n        // Issue 12349\n        import std.exception : assertThrown;\n        static import std.file;\n\n        auto deleteme = testFilename();\n        auto f = File(deleteme, \"w\");\n        scope(exit) std.file.remove(deleteme);\n\n        f.close();\n        assertThrown(f.flush());\n    }\n\n/**\nForces any data buffered by the OS to be written to disk.\nCall $(LREF flush) before calling this function to flush the C `FILE` buffers first.\n\nThis function calls\n$(HTTP msdn.microsoft.com/en-us/library/windows/desktop/aa364439%28v=vs.85%29.aspx,\n`FlushFileBuffers`) on Windows and\n$(HTTP pubs.opengroup.org/onlinepubs/7908799/xsh/fsync.html,\n`fsync`) on POSIX for the file handle.\n\nThrows: `Exception` if the file is not opened or if the OS call fails.\n */\n    void sync() @trusted\n    {\n        import std.exception : enforce;\n\n        enforce(isOpen, \"Attempting to sync() an unopened file\");\n\n        version (Windows)\n        {\n            import core.sys.windows.windows : FlushFileBuffers;\n            wenforce(FlushFileBuffers(windowsHandle), \"FlushFileBuffers failed\");\n        }\n        else\n        {\n            import core.sys.posix.unistd : fsync;\n            import std.exception : errnoEnforce;\n            errnoEnforce(fsync(fileno) == 0, \"fsync failed\");\n        }\n    }\n\n/**\nCalls $(HTTP cplusplus.com/reference/clibrary/cstdio/fread.html, fread) for the\nfile handle. The number of items to read and the size of\neach item is inferred from the size and type of the input array, respectively.\n\nReturns: The slice of `buffer` containing the data that was actually read.\nThis will be shorter than `buffer` if EOF was reached before the buffer\ncould be filled.\n\nThrows: `Exception` if `buffer` is empty.\n        `ErrnoException` if the file is not opened or the call to `fread` fails.\n\n`rawRead` always reads in binary mode on Windows.\n */\n    T[] rawRead(T)(T[] buffer)\n    {\n        import std.exception : errnoEnforce;\n\n        if (!buffer.length)\n            throw new Exception(\"rawRead must take a non-empty buffer\");\n        version (Windows)\n        {\n            immutable fd = ._fileno(_p.handle);\n            immutable mode = ._setmode(fd, _O_BINARY);\n            scope(exit) ._setmode(fd, mode);\n            version (DIGITAL_MARS_STDIO)\n            {\n                import core.atomic : atomicOp;\n\n                // @@@BUG@@@ 4243\n                immutable info = __fhnd_info[fd];\n                atomicOp!\"&=\"(__fhnd_info[fd], ~FHND_TEXT);\n                scope(exit) __fhnd_info[fd] = info;\n            }\n        }\n        immutable freadResult = trustedFread(_p.handle, buffer);\n        assert(freadResult <= buffer.length); // fread return guarantee\n        if (freadResult != buffer.length) // error or eof\n        {\n            errnoEnforce(!error);\n            return buffer[0 .. freadResult];\n        }\n        return buffer;\n    }\n\n    ///\n    @system unittest\n    {\n        static import std.file;\n\n        auto testFile = std.file.deleteme();\n        std.file.write(testFile, \"\\r\\n\\n\\r\\n\");\n        scope(exit) std.file.remove(testFile);\n\n        auto f = File(testFile, \"r\");\n        auto buf = f.rawRead(new char[5]);\n        f.close();\n        assert(buf == \"\\r\\n\\n\\r\\n\");\n    }\n\n/**\nCalls $(HTTP cplusplus.com/reference/clibrary/cstdio/fwrite.html, fwrite) for the file\nhandle. The number of items to write and the size of each\nitem is inferred from the size and type of the input array, respectively. An\nerror is thrown if the buffer could not be written in its entirety.\n\n`rawWrite` always writes in binary mode on Windows.\n\nThrows: `ErrnoException` if the file is not opened or if the call to `fwrite` fails.\n */\n    void rawWrite(T)(in T[] buffer)\n    {\n        import std.conv : text;\n        import std.exception : errnoEnforce;\n\n        version (Windows)\n        {\n            flush(); // before changing translation mode\n            immutable fd = ._fileno(_p.handle);\n            immutable mode = ._setmode(fd, _O_BINARY);\n            scope(exit) ._setmode(fd, mode);\n            version (DIGITAL_MARS_STDIO)\n            {\n                import core.atomic : atomicOp;\n\n                // @@@BUG@@@ 4243\n                immutable info = __fhnd_info[fd];\n                atomicOp!\"&=\"(__fhnd_info[fd], ~FHND_TEXT);\n                scope(exit) __fhnd_info[fd] = info;\n            }\n            scope(exit) flush(); // before restoring translation mode\n        }\n        auto result = trustedFwrite(_p.handle, buffer);\n        if (result == result.max) result = 0;\n        errnoEnforce(result == buffer.length,\n                text(\"Wrote \", result, \" instead of \", buffer.length,\n                        \" objects of type \", T.stringof, \" to file `\",\n                        _name, \"'\"));\n    }\n\n    ///\n    @system unittest\n    {\n        static import std.file;\n\n        auto testFile = std.file.deleteme();\n        auto f = File(testFile, \"w\");\n        scope(exit) std.file.remove(testFile);\n\n        f.rawWrite(\"\\r\\n\\n\\r\\n\");\n        f.close();\n        assert(std.file.read(testFile) == \"\\r\\n\\n\\r\\n\");\n    }\n\n/**\nCalls $(HTTP cplusplus.com/reference/clibrary/cstdio/fseek.html, fseek)\nfor the file handle.\n\nThrows: `Exception` if the file is not opened.\n        `ErrnoException` if the call to `fseek` fails.\n */\n    void seek(long offset, int origin = SEEK_SET) @trusted\n    {\n        import std.conv : to, text;\n        import std.exception : enforce, errnoEnforce;\n\n        enforce(isOpen, \"Attempting to seek() in an unopened file\");\n        version (Windows)\n        {\n            version (CRuntime_Microsoft)\n            {\n                alias fseekFun = _fseeki64;\n                alias off_t = long;\n            }\n            else\n            {\n                alias fseekFun = fseek;\n                alias off_t = int;\n            }\n        }\n        else version (Posix)\n        {\n            import core.sys.posix.stdio : fseeko, off_t;\n            alias fseekFun = fseeko;\n        }\n        errnoEnforce(fseekFun(_p.handle, to!off_t(offset), origin) == 0,\n                \"Could not seek in file `\"~_name~\"'\");\n    }\n\n    @system unittest\n    {\n        import std.conv : text;\n        static import std.file;\n\n        auto deleteme = testFilename();\n        auto f = File(deleteme, \"w+\");\n        scope(exit) { f.close(); std.file.remove(deleteme); }\n        f.rawWrite(\"abcdefghijklmnopqrstuvwxyz\");\n        f.seek(7);\n        assert(f.readln() == \"hijklmnopqrstuvwxyz\");\n\n        version (CRuntime_DigitalMars)\n            auto bigOffset = int.max - 100;\n        else\n        version (CRuntime_Bionic)\n            auto bigOffset = int.max - 100;\n        else\n            auto bigOffset = cast(ulong) int.max + 100;\n        f.seek(bigOffset);\n        assert(f.tell == bigOffset, text(f.tell));\n        // Uncomment the tests below only if you want to wait for\n        // a long time\n        // f.rawWrite(\"abcdefghijklmnopqrstuvwxyz\");\n        // f.seek(-3, SEEK_END);\n        // assert(f.readln() == \"xyz\");\n    }\n\n/**\nCalls $(HTTP cplusplus.com/reference/clibrary/cstdio/ftell.html, ftell) for the\nmanaged file handle.\n\nThrows: `Exception` if the file is not opened.\n        `ErrnoException` if the call to `ftell` fails.\n */\n    @property ulong tell() const @trusted\n    {\n        import std.exception : enforce, errnoEnforce;\n\n        enforce(isOpen, \"Attempting to tell() in an unopened file\");\n        version (Windows)\n        {\n            version (CRuntime_Microsoft)\n                immutable result = _ftelli64(cast(FILE*) _p.handle);\n            else\n                immutable result = ftell(cast(FILE*) _p.handle);\n        }\n        else version (Posix)\n        {\n            import core.sys.posix.stdio : ftello;\n            immutable result = ftello(cast(FILE*) _p.handle);\n        }\n        errnoEnforce(result != -1,\n                \"Query ftell() failed for file `\"~_name~\"'\");\n        return result;\n    }\n\n    ///\n    @system unittest\n    {\n        import std.conv : text;\n        static import std.file;\n\n        auto testFile = std.file.deleteme();\n        std.file.write(testFile, \"abcdefghijklmnopqrstuvwqxyz\");\n        scope(exit) { std.file.remove(testFile); }\n\n        auto f = File(testFile);\n        auto a = new ubyte[4];\n        f.rawRead(a);\n        assert(f.tell == 4, text(f.tell));\n    }\n\n/**\nCalls $(HTTP cplusplus.com/reference/clibrary/cstdio/_rewind.html, _rewind)\nfor the file handle.\n\nThrows: `Exception` if the file is not opened.\n */\n    void rewind() @safe\n    {\n        import std.exception : enforce;\n\n        enforce(isOpen, \"Attempting to rewind() an unopened file\");\n        .rewind(_p.handle);\n    }\n\n/**\nCalls $(HTTP cplusplus.com/reference/clibrary/cstdio/_setvbuf.html, _setvbuf) for\nthe file handle.\n\nThrows: `Exception` if the file is not opened.\n        `ErrnoException` if the call to `setvbuf` fails.\n */\n    void setvbuf(size_t size, int mode = _IOFBF) @trusted\n    {\n        import std.exception : enforce, errnoEnforce;\n\n        enforce(isOpen, \"Attempting to call setvbuf() on an unopened file\");\n        errnoEnforce(.setvbuf(_p.handle, null, mode, size) == 0,\n                \"Could not set buffering for file `\"~_name~\"'\");\n    }\n\n/**\nCalls $(HTTP cplusplus.com/reference/clibrary/cstdio/_setvbuf.html,\n_setvbuf) for the file handle.\n\nThrows: `Exception` if the file is not opened.\n        `ErrnoException` if the call to `setvbuf` fails.\n*/\n    void setvbuf(void[] buf, int mode = _IOFBF) @trusted\n    {\n        import std.exception : enforce, errnoEnforce;\n\n        enforce(isOpen, \"Attempting to call setvbuf() on an unopened file\");\n        errnoEnforce(.setvbuf(_p.handle,\n                        cast(char*) buf.ptr, mode, buf.length) == 0,\n                \"Could not set buffering for file `\"~_name~\"'\");\n    }\n\n\n    version (Windows)\n    {\n        import core.sys.windows.windows : ULARGE_INTEGER, OVERLAPPED, BOOL;\n\n        private BOOL lockImpl(alias F, Flags...)(ulong start, ulong length,\n            Flags flags)\n        {\n            if (!start && !length)\n                length = ulong.max;\n            ULARGE_INTEGER liStart = void, liLength = void;\n            liStart.QuadPart = start;\n            liLength.QuadPart = length;\n            OVERLAPPED overlapped;\n            overlapped.Offset = liStart.LowPart;\n            overlapped.OffsetHigh = liStart.HighPart;\n            overlapped.hEvent = null;\n            return F(windowsHandle, flags, 0, liLength.LowPart,\n                liLength.HighPart, &overlapped);\n        }\n\n        private static T wenforce(T)(T cond, string str)\n        {\n            import core.sys.windows.windows : GetLastError;\n            import std.windows.syserror : sysErrorString;\n\n            if (cond) return cond;\n            throw new Exception(str ~ \": \" ~ sysErrorString(GetLastError()));\n        }\n    }\n    version (Posix)\n    {\n        private int lockImpl(int operation, short l_type,\n            ulong start, ulong length)\n        {\n            import core.sys.posix.fcntl : fcntl, flock, off_t;\n            import core.sys.posix.unistd : getpid;\n            import std.conv : to;\n\n            flock fl = void;\n            fl.l_type   = l_type;\n            fl.l_whence = SEEK_SET;\n            fl.l_start  = to!off_t(start);\n            fl.l_len    = to!off_t(length);\n            fl.l_pid    = getpid();\n            return fcntl(fileno, operation, &fl);\n        }\n    }\n\n/**\nLocks the specified file segment. If the file segment is already locked\nby another process, waits until the existing lock is released.\nIf both `start` and `length` are zero, the entire file is locked.\n\nLocks created using `lock` and `tryLock` have the following properties:\n$(UL\n $(LI All locks are automatically released when the process terminates.)\n $(LI Locks are not inherited by child processes.)\n $(LI Closing a file will release all locks associated with the file. On POSIX,\n      even locks acquired via a different `File` will be released as well.)\n $(LI Not all NFS implementations correctly implement file locking.)\n)\n */\n    void lock(LockType lockType = LockType.readWrite,\n        ulong start = 0, ulong length = 0)\n    {\n        import std.exception : enforce;\n\n        enforce(isOpen, \"Attempting to call lock() on an unopened file\");\n        version (Posix)\n        {\n            import core.sys.posix.fcntl : F_RDLCK, F_SETLKW, F_WRLCK;\n            import std.exception : errnoEnforce;\n            immutable short type = lockType == LockType.readWrite\n                ? F_WRLCK : F_RDLCK;\n            errnoEnforce(lockImpl(F_SETLKW, type, start, length) != -1,\n                    \"Could not set lock for file `\"~_name~\"'\");\n        }\n        else\n        version (Windows)\n        {\n            import core.sys.windows.windows : LockFileEx, LOCKFILE_EXCLUSIVE_LOCK;\n            immutable type = lockType == LockType.readWrite ?\n                LOCKFILE_EXCLUSIVE_LOCK : 0;\n            wenforce(lockImpl!LockFileEx(start, length, type),\n                    \"Could not set lock for file `\"~_name~\"'\");\n        }\n        else\n            static assert(false);\n    }\n\n/**\nAttempts to lock the specified file segment.\nIf both `start` and `length` are zero, the entire file is locked.\nReturns: `true` if the lock was successful, and `false` if the\nspecified file segment was already locked.\n */\n    bool tryLock(LockType lockType = LockType.readWrite,\n        ulong start = 0, ulong length = 0)\n    {\n        import std.exception : enforce;\n\n        enforce(isOpen, \"Attempting to call tryLock() on an unopened file\");\n        version (Posix)\n        {\n            import core.stdc.errno : EACCES, EAGAIN, errno;\n            import core.sys.posix.fcntl : F_RDLCK, F_SETLK, F_WRLCK;\n            import std.exception : errnoEnforce;\n            immutable short type = lockType == LockType.readWrite\n                ? F_WRLCK : F_RDLCK;\n            immutable res = lockImpl(F_SETLK, type, start, length);\n            if (res == -1 && (errno == EACCES || errno == EAGAIN))\n                return false;\n            errnoEnforce(res != -1, \"Could not set lock for file `\"~_name~\"'\");\n            return true;\n        }\n        else\n        version (Windows)\n        {\n            import core.sys.windows.windows : GetLastError, LockFileEx, LOCKFILE_EXCLUSIVE_LOCK,\n                ERROR_IO_PENDING, ERROR_LOCK_VIOLATION, LOCKFILE_FAIL_IMMEDIATELY;\n            immutable type = lockType == LockType.readWrite\n                ? LOCKFILE_EXCLUSIVE_LOCK : 0;\n            immutable res = lockImpl!LockFileEx(start, length,\n                type | LOCKFILE_FAIL_IMMEDIATELY);\n            if (!res && (GetLastError() == ERROR_IO_PENDING\n                || GetLastError() == ERROR_LOCK_VIOLATION))\n                return false;\n            wenforce(res, \"Could not set lock for file `\"~_name~\"'\");\n            return true;\n        }\n        else\n            static assert(false);\n    }\n\n/**\nRemoves the lock over the specified file segment.\n */\n    void unlock(ulong start = 0, ulong length = 0)\n    {\n        import std.exception : enforce;\n\n        enforce(isOpen, \"Attempting to call unlock() on an unopened file\");\n        version (Posix)\n        {\n            import core.sys.posix.fcntl : F_SETLK, F_UNLCK;\n            import std.exception : errnoEnforce;\n            errnoEnforce(lockImpl(F_SETLK, F_UNLCK, start, length) != -1,\n                    \"Could not remove lock for file `\"~_name~\"'\");\n        }\n        else\n        version (Windows)\n        {\n            import core.sys.windows.windows : UnlockFileEx;\n            wenforce(lockImpl!UnlockFileEx(start, length),\n                \"Could not remove lock for file `\"~_name~\"'\");\n        }\n        else\n            static assert(false);\n    }\n\n    version (Windows)\n    @system unittest\n    {\n        static import std.file;\n        auto deleteme = testFilename();\n        scope(exit) std.file.remove(deleteme);\n        auto f = File(deleteme, \"wb\");\n        assert(f.tryLock());\n        auto g = File(deleteme, \"wb\");\n        assert(!g.tryLock());\n        assert(!g.tryLock(LockType.read));\n        f.unlock();\n        f.lock(LockType.read);\n        assert(!g.tryLock());\n        assert(g.tryLock(LockType.read));\n        f.unlock();\n        g.unlock();\n    }\n\n    version (Posix)\n    @system unittest\n    {\n        static import std.file;\n        auto deleteme = testFilename();\n        scope(exit) std.file.remove(deleteme);\n\n        // Since locks are per-process, we cannot test lock failures within\n        // the same process. fork() is used to create a second process.\n        static void runForked(void delegate() code)\n        {\n            import core.stdc.stdlib : exit;\n            import core.sys.posix.sys.wait : wait;\n            import core.sys.posix.unistd : fork;\n            int child, status;\n            if ((child = fork()) == 0)\n            {\n                code();\n                exit(0);\n            }\n            else\n            {\n                assert(wait(&status) != -1);\n                assert(status == 0, \"Fork crashed\");\n            }\n        }\n\n        auto f = File(deleteme, \"w+b\");\n\n        runForked\n        ({\n            auto g = File(deleteme, \"a+b\");\n            assert(g.tryLock());\n            g.unlock();\n            assert(g.tryLock(LockType.read));\n        });\n\n        assert(f.tryLock());\n        runForked\n        ({\n            auto g = File(deleteme, \"a+b\");\n            assert(!g.tryLock());\n            assert(!g.tryLock(LockType.read));\n        });\n        f.unlock();\n\n        f.lock(LockType.read);\n        runForked\n        ({\n            auto g = File(deleteme, \"a+b\");\n            assert(!g.tryLock());\n            assert(g.tryLock(LockType.read));\n            g.unlock();\n        });\n        f.unlock();\n    }\n\n\n/**\nWrites its arguments in text format to the file.\n\nThrows: `Exception` if the file is not opened.\n        `ErrnoException` on an error writing to the file.\n*/\n    void write(S...)(S args)\n    {\n        import std.traits : isBoolean, isIntegral, isAggregateType;\n        auto w = lockingTextWriter();\n        foreach (arg; args)\n        {\n            alias A = typeof(arg);\n            static if (isAggregateType!A || is(A == enum))\n            {\n                import std.format : formattedWrite;\n\n                formattedWrite(w, \"%s\", arg);\n            }\n            else static if (isSomeString!A)\n            {\n                put(w, arg);\n            }\n            else static if (isIntegral!A)\n            {\n                import std.conv : toTextRange;\n\n                toTextRange(arg, w);\n            }\n            else static if (isBoolean!A)\n            {\n                put(w, arg ? \"true\" : \"false\");\n            }\n            else static if (isSomeChar!A)\n            {\n                put(w, arg);\n            }\n            else\n            {\n                import std.format : formattedWrite;\n\n                // Most general case\n                formattedWrite(w, \"%s\", arg);\n            }\n        }\n    }\n\n/**\nWrites its arguments in text format to the file, followed by a newline.\n\nThrows: `Exception` if the file is not opened.\n        `ErrnoException` on an error writing to the file.\n*/\n    void writeln(S...)(S args)\n    {\n        write(args, '\\n');\n    }\n\n/**\nWrites its arguments in text format to the file, according to the\nformat string fmt.\n\nParams:\nfmt = The $(REF_ALTTEXT format string, formattedWrite, std, _format).\nWhen passed as a compile-time argument, the string will be statically checked\nagainst the argument types passed.\nargs = Items to write.\n\nThrows: `Exception` if the file is not opened.\n        `ErrnoException` on an error writing to the file.\n*/\n    void writef(alias fmt, A...)(A args)\n    if (isSomeString!(typeof(fmt)))\n    {\n        import std.format : checkFormatException;\n\n        alias e = checkFormatException!(fmt, A);\n        static assert(!e, e.msg);\n        return this.writef(fmt, args);\n    }\n\n    /// ditto\n    void writef(Char, A...)(in Char[] fmt, A args)\n    {\n        import std.format : formattedWrite;\n\n        formattedWrite(lockingTextWriter(), fmt, args);\n    }\n\n    /// Equivalent to `file.writef(fmt, args, '\\n')`.\n    void writefln(alias fmt, A...)(A args)\n    if (isSomeString!(typeof(fmt)))\n    {\n        import std.format : checkFormatException;\n\n        alias e = checkFormatException!(fmt, A);\n        static assert(!e, e.msg);\n        return this.writefln(fmt, args);\n    }\n\n    /// ditto\n    void writefln(Char, A...)(in Char[] fmt, A args)\n    {\n        import std.format : formattedWrite;\n\n        auto w = lockingTextWriter();\n        formattedWrite(w, fmt, args);\n        w.put('\\n');\n    }\n\n/**\nRead line from the file handle and return it as a specified type.\n\nThis version manages its own read buffer, which means one memory allocation per call. If you are not\nretaining a reference to the read data, consider the `File.readln(buf)` version, which may offer\nbetter performance as it can reuse its read buffer.\n\nParams:\n    S = Template parameter; the type of the allocated buffer, and the type returned. Defaults to `string`.\n    terminator = Line terminator (by default, `'\\n'`).\n\nNote:\n    String terminators are not supported due to ambiguity with readln(buf) below.\n\nReturns:\n    The line that was read, including the line terminator character.\n\nThrows:\n    `StdioException` on I/O error, or `UnicodeException` on Unicode conversion error.\n\nExample:\n---\n// Reads `stdin` and writes it to `stdout`.\nimport std.stdio;\n\nvoid main()\n{\n    string line;\n    while ((line = stdin.readln()) !is null)\n        write(line);\n}\n---\n*/\n    S readln(S = string)(dchar terminator = '\\n')\n    if (isSomeString!S)\n    {\n        Unqual!(ElementEncodingType!S)[] buf;\n        readln(buf, terminator);\n        return cast(S) buf;\n    }\n\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n        static import std.file;\n        import std.meta : AliasSeq;\n\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"hello\\nworld\\n\");\n        scope(exit) std.file.remove(deleteme);\n        static foreach (String; AliasSeq!(string, char[], wstring, wchar[], dstring, dchar[]))\n        {{\n            auto witness = [ \"hello\\n\", \"world\\n\" ];\n            auto f = File(deleteme);\n            uint i = 0;\n            String buf;\n            while ((buf = f.readln!String()).length)\n            {\n                assert(i < witness.length);\n                assert(equal(buf, witness[i++]));\n            }\n            assert(i == witness.length);\n        }}\n    }\n\n    @system unittest\n    {\n        static import std.file;\n        import std.typecons : Tuple;\n\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"cześć \\U0002000D\");\n        scope(exit) std.file.remove(deleteme);\n        uint[] lengths = [12,8,7];\n        static foreach (uint i, C; Tuple!(char, wchar, dchar).Types)\n        {{\n            immutable(C)[] witness = \"cześć \\U0002000D\";\n            auto buf = File(deleteme).readln!(immutable(C)[])();\n            assert(buf.length == lengths[i]);\n            assert(buf == witness);\n        }}\n    }\n\n/**\nRead line from the file handle and write it to `buf[]`, including\nterminating character.\n\nThis can be faster than $(D line = File.readln()) because you can reuse\nthe buffer for each call. Note that reusing the buffer means that you\nmust copy the previous contents if you wish to retain them.\n\nParams:\nbuf = Buffer used to store the resulting line data. buf is\nresized as necessary.\nterminator = Line terminator (by default, `'\\n'`). Use\n$(REF newline, std,ascii) for portability (unless the file was opened in\ntext mode).\n\nReturns:\n0 for end of file, otherwise number of characters read\n\nThrows: `StdioException` on I/O error, or `UnicodeException` on Unicode\nconversion error.\n\nExample:\n---\n// Read lines from `stdin` into a string\n// Ignore lines starting with '#'\n// Write the string to `stdout`\n\nvoid main()\n{\n    string output;\n    char[] buf;\n\n    while (stdin.readln(buf))\n    {\n        if (buf[0] == '#')\n            continue;\n\n        output ~= buf;\n    }\n\n    write(output);\n}\n---\n\nThis method can be more efficient than the one in the previous example\nbecause `stdin.readln(buf)` reuses (if possible) memory allocated\nfor `buf`, whereas $(D line = stdin.readln()) makes a new memory allocation\nfor every line.\n\nFor even better performance you can help `readln` by passing in a\nlarge buffer to avoid memory reallocations. This can be done by reusing the\nlargest buffer returned by `readln`:\n\nExample:\n---\n// Read lines from `stdin` and count words\n\nvoid main()\n{\n    char[] buf;\n    size_t words = 0;\n\n    while (!stdin.eof)\n    {\n        char[] line = buf;\n        stdin.readln(line);\n        if (line.length > buf.length)\n            buf = line;\n\n        words += line.split.length;\n    }\n\n    writeln(words);\n}\n---\nThis is actually what $(LREF byLine) does internally, so its usage\nis recommended if you want to process a complete file.\n*/\n    size_t readln(C)(ref C[] buf, dchar terminator = '\\n')\n    if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum))\n    {\n        import std.exception : enforce;\n\n        static if (is(C == char))\n        {\n            enforce(_p && _p.handle, \"Attempt to read from an unopened file.\");\n            if (_p.orientation == Orientation.unknown)\n            {\n                import core.stdc.wchar_ : fwide;\n                auto w = fwide(_p.handle, 0);\n                if (w < 0) _p.orientation = Orientation.narrow;\n                else if (w > 0) _p.orientation = Orientation.wide;\n            }\n            return readlnImpl(_p.handle, buf, terminator, _p.orientation);\n        }\n        else\n        {\n            // TODO: optimize this\n            string s = readln(terminator);\n            buf.length = 0;\n            if (!s.length) return 0;\n            foreach (C c; s)\n            {\n                buf ~= c;\n            }\n            return buf.length;\n        }\n    }\n\n    @system unittest\n    {\n        // @system due to readln\n        static import std.file;\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"123\\n456789\");\n        scope(exit) std.file.remove(deleteme);\n\n        auto file = File(deleteme);\n        char[] buffer = new char[10];\n        char[] line = buffer;\n        file.readln(line);\n        auto beyond = line.length;\n        buffer[beyond] = 'a';\n        file.readln(line); // should not write buffer beyond line\n        assert(buffer[beyond] == 'a');\n    }\n\n    @system unittest // bugzilla 15293\n    {\n        // @system due to readln\n        static import std.file;\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"a\\n\\naa\");\n        scope(exit) std.file.remove(deleteme);\n\n        auto file = File(deleteme);\n        char[] buffer;\n        char[] line;\n\n        file.readln(buffer, '\\n');\n\n        line = buffer;\n        file.readln(line, '\\n');\n\n        line = buffer;\n        file.readln(line, '\\n');\n\n        assert(line[0 .. 1].capacity == 0);\n    }\n\n/** ditto */\n    size_t readln(C, R)(ref C[] buf, R terminator)\n    if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) &&\n        isBidirectionalRange!R && is(typeof(terminator.front == dchar.init)))\n    {\n        import std.algorithm.mutation : swap;\n        import std.algorithm.searching : endsWith;\n        import std.range.primitives : back;\n\n        auto last = terminator.back;\n        C[] buf2;\n        swap(buf, buf2);\n        for (;;)\n        {\n            if (!readln(buf2, last) || endsWith(buf2, terminator))\n            {\n                if (buf.empty)\n                {\n                    buf = buf2;\n                }\n                else\n                {\n                    buf ~= buf2;\n                }\n                break;\n            }\n            buf ~= buf2;\n        }\n        return buf.length;\n    }\n\n    @system unittest\n    {\n        static import std.file;\n        import std.typecons : Tuple;\n\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"hello\\n\\rworld\\nhow\\n\\rare ya\");\n        scope(exit) std.file.remove(deleteme);\n        foreach (C; Tuple!(char, wchar, dchar).Types)\n        {\n            immutable(C)[][] witness = [ \"hello\\n\\r\", \"world\\nhow\\n\\r\", \"are ya\" ];\n            auto f = File(deleteme);\n            uint i = 0;\n            C[] buf;\n            while (f.readln(buf, \"\\n\\r\"))\n            {\n                assert(i < witness.length);\n                assert(buf == witness[i++]);\n            }\n            assert(buf.length == 0);\n        }\n    }\n\n    /**\n     * Reads formatted _data from the file using $(REF formattedRead, std,_format).\n     * Params:\n     * format = The $(REF_ALTTEXT format string, formattedWrite, std _format).\n     * When passed as a compile-time argument, the string will be statically checked\n     * against the argument types passed.\n     * data = Items to be read.\n     * Example:\n----\n// test.d\nvoid main()\n{\n    import std.stdio;\n    auto f = File(\"input\");\n    foreach (_; 0 .. 3)\n    {\n        int a;\n        f.readf!\" %d\"(a);\n        writeln(++a);\n    }\n}\n----\n$(CONSOLE\n% echo \"1 2 3\" > input\n% rdmd test.d\n2\n3\n4\n)\n     */\n    uint readf(alias format, Data...)(auto ref Data data)\n    if (isSomeString!(typeof(format)))\n    {\n        import std.format : checkFormatException;\n\n        alias e = checkFormatException!(format, Data);\n        static assert(!e, e.msg);\n        return this.readf(format, data);\n    }\n\n    /// ditto\n    uint readf(Data...)(scope const(char)[] format, auto ref Data data)\n    {\n        import std.format : formattedRead;\n\n        assert(isOpen);\n        auto input = LockingTextReader(this);\n        return formattedRead(input, format, data);\n    }\n\n    ///\n    @system unittest\n    {\n        static import std.file;\n\n        auto deleteme = std.file.deleteme();\n        std.file.write(deleteme, \"hello\\nworld\\ntrue\\nfalse\\n\");\n        scope(exit) std.file.remove(deleteme);\n        string s;\n        auto f = File(deleteme);\n        f.readf!\"%s\\n\"(s);\n        assert(s == \"hello\", \"[\"~s~\"]\");\n        f.readf(\"%s\\n\", s);\n        assert(s == \"world\", \"[\"~s~\"]\");\n\n        bool b1, b2;\n        f.readf(\"%s\\n%s\\n\", b1, b2);\n        assert(b1 == true && b2 == false);\n    }\n\n    // backwards compatibility with pointers\n    @system unittest\n    {\n        // @system due to readf\n        static import std.file;\n\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"hello\\nworld\\ntrue\\nfalse\\n\");\n        scope(exit) std.file.remove(deleteme);\n        string s;\n        auto f = File(deleteme);\n        f.readf(\"%s\\n\", &s);\n        assert(s == \"hello\", \"[\"~s~\"]\");\n        f.readf(\"%s\\n\", &s);\n        assert(s == \"world\", \"[\"~s~\"]\");\n\n        // Issue 11698\n        bool b1, b2;\n        f.readf(\"%s\\n%s\\n\", &b1, &b2);\n        assert(b1 == true && b2 == false);\n    }\n\n    // backwards compatibility (mixed)\n    @system unittest\n    {\n        // @system due to readf\n        static import std.file;\n\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"hello\\nworld\\ntrue\\nfalse\\n\");\n        scope(exit) std.file.remove(deleteme);\n        string s1, s2;\n        auto f = File(deleteme);\n        f.readf(\"%s\\n%s\\n\", s1, &s2);\n        assert(s1 == \"hello\");\n        assert(s2 == \"world\");\n\n        // Issue 11698\n        bool b1, b2;\n        f.readf(\"%s\\n%s\\n\", &b1, b2);\n        assert(b1 == true && b2 == false);\n    }\n\n    // Issue 12260 - Nice error of std.stdio.readf with newlines\n    @system unittest\n    {\n        static import std.file;\n\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"1\\n2\");\n        scope(exit) std.file.remove(deleteme);\n        int input;\n        auto f = File(deleteme);\n        f.readf(\"%s\", &input);\n\n        import std.conv : ConvException;\n        import std.exception : collectException;\n        assert(collectException!ConvException(f.readf(\"%s\", &input)).msg ==\n            \"Unexpected '\\\\n' when converting from type LockingTextReader to type int\");\n    }\n\n/**\n Returns a temporary file by calling\n $(HTTP cplusplus.com/reference/clibrary/cstdio/_tmpfile.html, _tmpfile).\n Note that the created file has no $(LREF name).*/\n    static File tmpfile() @safe\n    {\n        import std.exception : errnoEnforce;\n\n        return File(errnoEnforce(.tmpfile(),\n                \"Could not create temporary file with tmpfile()\"),\n            null);\n    }\n\n/**\nUnsafe function that wraps an existing `FILE*`. The resulting $(D\nFile) never takes the initiative in closing the file.\nNote that the created file has no $(LREF name)*/\n    /*private*/ static File wrapFile(FILE* f) @safe\n    {\n        import std.exception : enforce;\n\n        return File(enforce(f, \"Could not wrap null FILE*\"),\n            null, /*uint.max / 2*/ 9999);\n    }\n\n/**\nReturns the `FILE*` corresponding to this object.\n */\n    FILE* getFP() @safe pure\n    {\n        import std.exception : enforce;\n\n        enforce(_p && _p.handle,\n                \"Attempting to call getFP() on an unopened file\");\n        return _p.handle;\n    }\n\n    @system unittest\n    {\n        static import core.stdc.stdio;\n        assert(stdout.getFP() == core.stdc.stdio.stdout);\n    }\n\n/**\nReturns the file number corresponding to this object.\n */\n    @property int fileno() const @trusted\n    {\n        import std.exception : enforce;\n\n        enforce(isOpen, \"Attempting to call fileno() on an unopened file\");\n        return .fileno(cast(FILE*) _p.handle);\n    }\n\n/**\nReturns the underlying operating system `HANDLE` (Windows only).\n*/\n    version (StdDdoc)\n    @property HANDLE windowsHandle();\n\n    version (Windows)\n    @property HANDLE windowsHandle()\n    {\n        version (DIGITAL_MARS_STDIO)\n            return _fdToHandle(fileno);\n        else\n            return cast(HANDLE)_get_osfhandle(fileno);\n    }\n\n\n// Note: This was documented until 2013/08\n/*\nRange that reads one line at a time.  Returned by $(LREF byLine).\n\nAllows to directly use range operations on lines of a file.\n*/\n    private struct ByLineImpl(Char, Terminator)\n    {\n    private:\n        import std.typecons : RefCounted, RefCountedAutoInitialize;\n\n        /* Ref-counting stops the source range's Impl\n         * from getting out of sync after the range is copied, e.g.\n         * when accessing range.front, then using std.range.take,\n         * then accessing range.front again. */\n        alias PImpl = RefCounted!(Impl, RefCountedAutoInitialize.no);\n        PImpl impl;\n\n        static if (isScalarType!Terminator)\n            enum defTerm = '\\n';\n        else\n            enum defTerm = cast(Terminator)\"\\n\";\n\n    public:\n        this(File f, KeepTerminator kt = No.keepTerminator,\n                Terminator terminator = defTerm)\n        {\n            impl = PImpl(f, kt, terminator);\n        }\n\n        @property bool empty()\n        {\n            return impl.refCountedPayload.empty;\n        }\n\n        @property Char[] front()\n        {\n            return impl.refCountedPayload.front;\n        }\n\n        void popFront()\n        {\n            impl.refCountedPayload.popFront();\n        }\n\n    private:\n        struct Impl\n        {\n        private:\n            File file;\n            Char[] line;\n            Char[] buffer;\n            Terminator terminator;\n            KeepTerminator keepTerminator;\n\n        public:\n            this(File f, KeepTerminator kt, Terminator terminator)\n            {\n                file = f;\n                this.terminator = terminator;\n                keepTerminator = kt;\n                popFront();\n            }\n\n            // Range primitive implementations.\n            @property bool empty()\n            {\n                return line is null;\n            }\n\n            @property Char[] front()\n            {\n                return line;\n            }\n\n            void popFront()\n            {\n                import std.algorithm.searching : endsWith;\n                assert(file.isOpen);\n                line = buffer;\n                file.readln(line, terminator);\n                if (line.length > buffer.length)\n                {\n                    buffer = line;\n                }\n                if (line.empty)\n                {\n                    file.detach();\n                    line = null;\n                }\n                else if (keepTerminator == No.keepTerminator\n                        && endsWith(line, terminator))\n                {\n                    static if (isScalarType!Terminator)\n                        enum tlen = 1;\n                    else static if (isArray!Terminator)\n                    {\n                        static assert(\n                            is(Unqual!(ElementEncodingType!Terminator) == Char));\n                        const tlen = terminator.length;\n                    }\n                    else\n                        static assert(false);\n                    line = line[0 .. line.length - tlen];\n                }\n            }\n        }\n    }\n\n    // @@@DEPRECATED_2019-01@@@\n    deprecated(\"Use .byLine\")\n    struct ByLine(Char, Terminator)\n    {\n        ByLineImpl!(Char, Terminator) payload;\n        alias payload this;\n    }\n\n/**\nReturns an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\nset up to read from the file handle one line at a time.\n\nThe element type for the range will be `Char[]`. Range primitives\nmay throw `StdioException` on I/O error.\n\nNote:\nEach `front` will not persist after $(D\npopFront) is called, so the caller must copy its contents (e.g. by\ncalling `to!string`) when retention is needed. If the caller needs\nto retain a copy of every line, use the $(LREF byLineCopy) function\ninstead.\n\nParams:\nChar = Character type for each line, defaulting to `char`.\nkeepTerminator = Use `Yes.keepTerminator` to include the\nterminator at the end of each line.\nterminator = Line separator (`'\\n'` by default). Use\n$(REF newline, std,ascii) for portability (unless the file was opened in\ntext mode).\n\nExample:\n----\nimport std.algorithm, std.stdio, std.string;\n// Count words in a file using ranges.\nvoid main()\n{\n    auto file = File(\"file.txt\"); // Open for reading\n    const wordCount = file.byLine()            // Read lines\n                          .map!split           // Split into words\n                          .map!(a => a.length) // Count words per line\n                          .sum();              // Total word count\n    writeln(wordCount);\n}\n----\n\nExample:\n----\nimport std.range, std.stdio;\n// Read lines using foreach.\nvoid main()\n{\n    auto file = File(\"file.txt\"); // Open for reading\n    auto range = file.byLine();\n    // Print first three lines\n    foreach (line; range.take(3))\n        writeln(line);\n    // Print remaining lines beginning with '#'\n    foreach (line; range)\n    {\n        if (!line.empty && line[0] == '#')\n            writeln(line);\n    }\n}\n----\nNotice that neither example accesses the line data returned by\n`front` after the corresponding `popFront` call is made (because\nthe contents may well have changed).\n*/\n    auto byLine(Terminator = char, Char = char)\n            (KeepTerminator keepTerminator = No.keepTerminator,\n            Terminator terminator = '\\n')\n    if (isScalarType!Terminator)\n    {\n        return ByLineImpl!(Char, Terminator)(this, keepTerminator, terminator);\n    }\n\n/// ditto\n    auto byLine(Terminator, Char = char)\n            (KeepTerminator keepTerminator, Terminator terminator)\n    if (is(Unqual!(ElementEncodingType!Terminator) == Char))\n    {\n        return ByLineImpl!(Char, Terminator)(this, keepTerminator, terminator);\n    }\n\n    @system unittest\n    {\n        static import std.file;\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"hi\");\n        scope(success) std.file.remove(deleteme);\n\n        import std.meta : AliasSeq;\n        static foreach (T; AliasSeq!(char, wchar, dchar))\n        {{\n            auto blc = File(deleteme).byLine!(T, T);\n            assert(blc.front == \"hi\");\n            // check front is cached\n            assert(blc.front is blc.front);\n        }}\n    }\n\n    private struct ByLineCopy(Char, Terminator)\n    {\n    private:\n        import std.typecons : RefCounted, RefCountedAutoInitialize;\n\n        /* Ref-counting stops the source range's ByLineCopyImpl\n         * from getting out of sync after the range is copied, e.g.\n         * when accessing range.front, then using std.range.take,\n         * then accessing range.front again. */\n        alias Impl = RefCounted!(ByLineCopyImpl!(Char, Terminator),\n            RefCountedAutoInitialize.no);\n        Impl impl;\n\n    public:\n        this(File f, KeepTerminator kt, Terminator terminator)\n        {\n            impl = Impl(f, kt, terminator);\n        }\n\n        @property bool empty()\n        {\n            return impl.refCountedPayload.empty;\n        }\n\n        @property Char[] front()\n        {\n            return impl.refCountedPayload.front;\n        }\n\n        void popFront()\n        {\n            impl.refCountedPayload.popFront();\n        }\n    }\n\n    private struct ByLineCopyImpl(Char, Terminator)\n    {\n        ByLineImpl!(Unqual!Char, Terminator).Impl impl;\n        bool gotFront;\n        Char[] line;\n\n    public:\n        this(File f, KeepTerminator kt, Terminator terminator)\n        {\n            impl = ByLineImpl!(Unqual!Char, Terminator).Impl(f, kt, terminator);\n        }\n\n        @property bool empty()\n        {\n            return impl.empty;\n        }\n\n        @property front()\n        {\n            if (!gotFront)\n            {\n                line = impl.front.dup;\n                gotFront = true;\n            }\n            return line;\n        }\n\n        void popFront()\n        {\n            impl.popFront();\n            gotFront = false;\n        }\n    }\n\n/**\nReturns an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\nset up to read from the file handle one line\nat a time. Each line will be newly allocated. `front` will cache\nits value to allow repeated calls without unnecessary allocations.\n\nNote: Due to caching byLineCopy can be more memory-efficient than\n`File.byLine.map!idup`.\n\nThe element type for the range will be `Char[]`. Range\nprimitives may throw `StdioException` on I/O error.\n\nParams:\nChar = Character type for each line, defaulting to $(D immutable char).\nkeepTerminator = Use `Yes.keepTerminator` to include the\nterminator at the end of each line.\nterminator = Line separator (`'\\n'` by default). Use\n$(REF newline, std,ascii) for portability (unless the file was opened in\ntext mode).\n\nExample:\n----\nimport std.algorithm, std.array, std.stdio;\n// Print sorted lines of a file.\nvoid main()\n{\n    auto sortedLines = File(\"file.txt\")   // Open for reading\n                       .byLineCopy()      // Read persistent lines\n                       .array()           // into an array\n                       .sort();           // then sort them\n    foreach (line; sortedLines)\n        writeln(line);\n}\n----\nSee_Also:\n$(REF readText, std,file)\n*/\n    auto byLineCopy(Terminator = char, Char = immutable char)\n            (KeepTerminator keepTerminator = No.keepTerminator,\n            Terminator terminator = '\\n')\n    if (isScalarType!Terminator)\n    {\n        return ByLineCopy!(Char, Terminator)(this, keepTerminator, terminator);\n    }\n\n/// ditto\n    auto byLineCopy(Terminator, Char = immutable char)\n            (KeepTerminator keepTerminator, Terminator terminator)\n    if (is(Unqual!(ElementEncodingType!Terminator) == Unqual!Char))\n    {\n        return ByLineCopy!(Char, Terminator)(this, keepTerminator, terminator);\n    }\n\n    @safe unittest\n    {\n        static assert(is(typeof(File(\"\").byLine.front) == char[]));\n        static assert(is(typeof(File(\"\").byLineCopy.front) == string));\n        static assert(\n            is(typeof(File(\"\").byLineCopy!(char, char).front) == char[]));\n    }\n\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n        static import std.file;\n\n        scope(failure) printf(\"Failed test at line %d\\n\", __LINE__);\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"\");\n        scope(success) std.file.remove(deleteme);\n\n        // Test empty file\n        auto f = File(deleteme);\n        foreach (line; f.byLine())\n        {\n            assert(false);\n        }\n        f.detach();\n        assert(!f.isOpen);\n\n        void test(Terminator)(string txt, in string[] witness,\n                KeepTerminator kt, Terminator term, bool popFirstLine = false)\n        {\n            import std.algorithm.sorting : sort;\n            import std.array : array;\n            import std.conv : text;\n            import std.range.primitives : walkLength;\n\n            uint i;\n            std.file.write(deleteme, txt);\n            auto f = File(deleteme);\n            scope(exit)\n            {\n                f.close();\n                assert(!f.isOpen);\n            }\n            auto lines = f.byLine(kt, term);\n            if (popFirstLine)\n            {\n                lines.popFront();\n                i = 1;\n            }\n            assert(lines.empty || lines.front is lines.front);\n            foreach (line; lines)\n            {\n                assert(line == witness[i++]);\n            }\n            assert(i == witness.length, text(i, \" != \", witness.length));\n\n            // Issue 11830\n            auto walkedLength = File(deleteme).byLine(kt, term).walkLength;\n            assert(walkedLength == witness.length, text(walkedLength, \" != \", witness.length));\n\n            // test persistent lines\n            assert(File(deleteme).byLineCopy(kt, term).array.sort() == witness.dup.sort());\n        }\n\n        KeepTerminator kt = No.keepTerminator;\n        test(\"\", null, kt, '\\n');\n        test(\"\\n\", [ \"\" ], kt, '\\n');\n        test(\"asd\\ndef\\nasdf\", [ \"asd\", \"def\", \"asdf\" ], kt, '\\n');\n        test(\"asd\\ndef\\nasdf\", [ \"asd\", \"def\", \"asdf\" ], kt, '\\n', true);\n        test(\"asd\\ndef\\nasdf\\n\", [ \"asd\", \"def\", \"asdf\" ], kt, '\\n');\n        test(\"foo\", [ \"foo\" ], kt, '\\n', true);\n        test(\"bob\\r\\nmarge\\r\\nsteve\\r\\n\", [\"bob\", \"marge\", \"steve\"],\n            kt, \"\\r\\n\");\n        test(\"sue\\r\", [\"sue\"], kt, '\\r');\n\n        kt = Yes.keepTerminator;\n        test(\"\", null, kt, '\\n');\n        test(\"\\n\", [ \"\\n\" ], kt, '\\n');\n        test(\"asd\\ndef\\nasdf\", [ \"asd\\n\", \"def\\n\", \"asdf\" ], kt, '\\n');\n        test(\"asd\\ndef\\nasdf\\n\", [ \"asd\\n\", \"def\\n\", \"asdf\\n\" ], kt, '\\n');\n        test(\"asd\\ndef\\nasdf\\n\", [ \"asd\\n\", \"def\\n\", \"asdf\\n\" ], kt, '\\n', true);\n        test(\"foo\", [ \"foo\" ], kt, '\\n');\n        test(\"bob\\r\\nmarge\\r\\nsteve\\r\\n\", [\"bob\\r\\n\", \"marge\\r\\n\", \"steve\\r\\n\"],\n            kt, \"\\r\\n\");\n        test(\"sue\\r\", [\"sue\\r\"], kt, '\\r');\n    }\n\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.range : drop, take;\n\n        version (Win64)\n        {\n            static import std.file;\n\n            /* the C function tmpfile doesn't seem to work, even when called from C */\n            auto deleteme = testFilename();\n            auto file = File(deleteme, \"w+\");\n            scope(success) std.file.remove(deleteme);\n        }\n        else version (CRuntime_Bionic)\n        {\n            static import std.file;\n\n            /* the C function tmpfile doesn't work when called from a shared\n               library apk:\n               https://code.google.com/p/android/issues/detail?id=66815 */\n            auto deleteme = testFilename();\n            auto file = File(deleteme, \"w+\");\n            scope(success) std.file.remove(deleteme);\n        }\n        else\n            auto file = File.tmpfile();\n        file.write(\"1\\n2\\n3\\n\");\n\n        // bug 9599\n        file.rewind();\n        File.ByLineImpl!(char, char) fbl = file.byLine();\n        auto fbl2 = fbl;\n        assert(fbl.front == \"1\");\n        assert(fbl.front is fbl2.front);\n        assert(fbl.take(1).equal([\"1\"]));\n        assert(fbl.equal([\"2\", \"3\"]));\n        assert(fbl.empty);\n        assert(file.isOpen); // we still have a valid reference\n\n        file.rewind();\n        fbl = file.byLine();\n        assert(!fbl.drop(2).empty);\n        assert(fbl.equal([\"3\"]));\n        assert(fbl.empty);\n        assert(file.isOpen);\n\n        file.detach();\n        assert(!file.isOpen);\n    }\n\n    @system unittest\n    {\n        static import std.file;\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"hi\");\n        scope(success) std.file.remove(deleteme);\n\n        auto blc = File(deleteme).byLineCopy;\n        assert(!blc.empty);\n        // check front is cached\n        assert(blc.front is blc.front);\n    }\n\n    /**\n    Creates an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    set up to parse one line at a time from the file into a tuple.\n\n    Range primitives may throw `StdioException` on I/O error.\n\n    Params:\n        format = tuple record $(REF_ALTTEXT _format, formattedRead, std, _format)\n\n    Returns:\n        The input range set up to parse one line at a time into a record tuple.\n\n    See_Also:\n\n        It is similar to $(LREF byLine) and uses\n        $(REF_ALTTEXT _format, formattedRead, std, _format) under the hood.\n    */\n    template byRecord(Fields...)\n    {\n        auto byRecord(string format)\n        {\n            return ByRecordImpl!(Fields)(this, format);\n        }\n    }\n\n    ///\n    @system unittest\n    {\n         static import std.file;\n         import std.typecons : tuple;\n\n         // prepare test file\n         auto testFile = std.file.deleteme();\n         scope(failure) printf(\"Failed test at line %d\\n\", __LINE__);\n         std.file.write(testFile, \"1 2\\n4 1\\n5 100\");\n         scope(exit) std.file.remove(testFile);\n\n         File f = File(testFile);\n         scope(exit) f.close();\n\n         auto expected = [tuple(1, 2), tuple(4, 1), tuple(5, 100)];\n         uint i;\n         foreach (e; f.byRecord!(int, int)(\"%s %s\"))\n         {\n             assert(e == expected[i++]);\n         }\n    }\n\n    // Note: This was documented until 2013/08\n    /*\n     * Range that reads a chunk at a time.\n     */\n    private struct ByChunkImpl\n    {\n    private:\n        File    file_;\n        ubyte[] chunk_;\n\n        void prime()\n        {\n            chunk_ = file_.rawRead(chunk_);\n            if (chunk_.length == 0)\n                file_.detach();\n        }\n\n    public:\n        this(File file, size_t size)\n        {\n            this(file, new ubyte[](size));\n        }\n\n        this(File file, ubyte[] buffer)\n        {\n            import std.exception : enforce;\n            enforce(buffer.length, \"size must be larger than 0\");\n            file_ = file;\n            chunk_ = buffer;\n            prime();\n        }\n\n        // `ByChunk`'s input range primitive operations.\n        @property nothrow\n        bool empty() const\n        {\n            return !file_.isOpen;\n        }\n\n        /// Ditto\n        @property nothrow\n        ubyte[] front()\n        {\n            version (assert)\n            {\n                import core.exception : RangeError;\n                if (empty)\n                    throw new RangeError();\n            }\n            return chunk_;\n        }\n\n        /// Ditto\n        void popFront()\n        {\n            version (assert)\n            {\n                import core.exception : RangeError;\n                if (empty)\n                    throw new RangeError();\n            }\n            prime();\n        }\n    }\n\n    // @@@DEPRECATED_2019-01@@@\n    deprecated(\"Use .byChunk\")\n    struct ByChunk\n    {\n        ByChunkImpl payload;\n        alias payload this;\n    }\n\n/**\nReturns an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\nset up to read from the file handle a chunk at a time.\n\nThe element type for the range will be `ubyte[]`. Range primitives\nmay throw `StdioException` on I/O error.\n\nExample:\n---------\nvoid main()\n{\n    // Read standard input 4KB at a time\n    foreach (ubyte[] buffer; stdin.byChunk(4096))\n    {\n        ... use buffer ...\n    }\n}\n---------\n\nThe parameter may be a number (as shown in the example above) dictating the\nsize of each chunk. Alternatively, `byChunk` accepts a\nuser-provided buffer that it uses directly.\n\nExample:\n---------\nvoid main()\n{\n    // Read standard input 4KB at a time\n    foreach (ubyte[] buffer; stdin.byChunk(new ubyte[4096]))\n    {\n        ... use buffer ...\n    }\n}\n---------\n\nIn either case, the content of the buffer is reused across calls. That means\n`front` will not persist after `popFront` is called, so if retention is\nneeded, the caller must copy its contents (e.g. by calling `buffer.dup`).\n\nIn the  example above, `buffer.length` is 4096 for all iterations, except\nfor the last one, in which case `buffer.length` may be less than 4096 (but\nalways greater than zero).\n\nWith the mentioned limitations, `byChunk` works with any algorithm\ncompatible with input ranges.\n\nExample:\n---\n// Efficient file copy, 1MB at a time.\nimport std.algorithm, std.stdio;\nvoid main()\n{\n    stdin.byChunk(1024 * 1024).copy(stdout.lockingTextWriter());\n}\n---\n\n$(REF joiner, std,algorithm,iteration) can be used to join chunks together into\na single range lazily.\nExample:\n---\nimport std.algorithm, std.stdio;\nvoid main()\n{\n    //Range of ranges\n    static assert(is(typeof(stdin.byChunk(4096).front) == ubyte[]));\n    //Range of elements\n    static assert(is(typeof(stdin.byChunk(4096).joiner.front) == ubyte));\n}\n---\n\nReturns: A call to `byChunk` returns a range initialized with the `File`\nobject and the appropriate buffer.\n\nThrows: If the user-provided size is zero or the user-provided buffer\nis empty, throws an `Exception`. In case of an I/O error throws\n`StdioException`.\n */\n    auto byChunk(size_t chunkSize)\n    {\n        return ByChunkImpl(this, chunkSize);\n    }\n/// Ditto\n    auto byChunk(ubyte[] buffer)\n    {\n        return ByChunkImpl(this, buffer);\n    }\n\n    @system unittest\n    {\n        static import std.file;\n\n        scope(failure) printf(\"Failed test at line %d\\n\", __LINE__);\n\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"asd\\ndef\\nasdf\");\n\n        auto witness = [\"asd\\n\", \"def\\n\", \"asdf\" ];\n        auto f = File(deleteme);\n        scope(exit)\n        {\n            f.close();\n            assert(!f.isOpen);\n            std.file.remove(deleteme);\n        }\n\n        uint i;\n        foreach (chunk; f.byChunk(4))\n            assert(chunk == cast(ubyte[]) witness[i++]);\n\n        assert(i == witness.length);\n    }\n\n    @system unittest\n    {\n        static import std.file;\n\n        scope(failure) printf(\"Failed test at line %d\\n\", __LINE__);\n\n        auto deleteme = testFilename();\n        std.file.write(deleteme, \"asd\\ndef\\nasdf\");\n\n        auto witness = [\"asd\\n\", \"def\\n\", \"asdf\" ];\n        auto f = File(deleteme);\n        scope(exit)\n        {\n            f.close();\n            assert(!f.isOpen);\n            std.file.remove(deleteme);\n        }\n\n        uint i;\n        foreach (chunk; f.byChunk(new ubyte[4]))\n            assert(chunk == cast(ubyte[]) witness[i++]);\n\n        assert(i == witness.length);\n    }\n\n    // Note: This was documented until 2013/08\n/*\n`Range` that locks the file and allows fast writing to it.\n */\n    struct LockingTextWriter\n    {\n    private:\n        import std.range.primitives : ElementType, isInfinite, isInputRange;\n        // Access the FILE* handle through the 'file_' member\n        // to keep the object alive through refcounting\n        File file_;\n\n        // the unshared version of FILE* handle, extracted from the File object\n        @property _iobuf* handle_() @trusted { return cast(_iobuf*) file_._p.handle; }\n\n        // the file's orientation (byte- or wide-oriented)\n        int orientation_;\n\n        // A buffer for when we need to transcode.\n        wchar highSurrogate = '\\0'; // '\\0' indicates empty\n        void highSurrogateShouldBeEmpty() @safe\n        {\n            import std.utf : UTFException;\n            if (highSurrogate != '\\0')\n                throw new UTFException(\"unpaired surrogate UTF-16 value\");\n        }\n    public:\n\n        this(ref File f) @trusted\n        {\n            import core.stdc.wchar_ : fwide;\n            import std.exception : enforce;\n\n            enforce(f._p && f._p.handle, \"Attempting to write to closed File\");\n            file_ = f;\n            FILE* fps = f._p.handle;\n            orientation_ = fwide(fps, 0);\n            FLOCK(fps);\n        }\n\n        ~this() @trusted\n        {\n            if (auto p = file_._p)\n            {\n                if (p.handle) FUNLOCK(p.handle);\n            }\n            file_ = File.init;\n                /* Destroy file_ before possibly throwing. Else it wouldn't be\n                destroyed, and its reference count would be wrong. */\n            highSurrogateShouldBeEmpty();\n        }\n\n        this(this) @trusted\n        {\n            if (auto p = file_._p)\n            {\n                if (p.handle) FLOCK(p.handle);\n            }\n        }\n\n        /// Range primitive implementations.\n        void put(A)(scope A writeme)\n            if ((isSomeChar!(Unqual!(ElementType!A)) ||\n                  is(ElementType!A : const(ubyte))) &&\n                isInputRange!A &&\n                !isInfinite!A)\n        {\n            import std.exception : errnoEnforce;\n\n            alias C = ElementEncodingType!A;\n            static assert(!is(C == void));\n            static if (isSomeString!A && C.sizeof == 1 || is(A : const(ubyte)[]))\n            {\n                if (orientation_ <= 0)\n                {\n                    //file.write(writeme); causes infinite recursion!!!\n                    //file.rawWrite(writeme);\n                    auto result = trustedFwrite(file_._p.handle, writeme);\n                    if (result != writeme.length) errnoEnforce(0);\n                    return;\n                }\n            }\n\n            // put each element in turn.\n            foreach (c; writeme)\n            {\n                put(c);\n            }\n        }\n\n        /// ditto\n        void put(C)(scope C c) @safe if (isSomeChar!C || is(C : const(ubyte)))\n        {\n            import std.traits : Parameters;\n            static auto trustedFPUTC(int ch, _iobuf* h) @trusted\n            {\n                return FPUTC(ch, h);\n            }\n            static auto trustedFPUTWC(Parameters!FPUTWC[0] ch, _iobuf* h) @trusted\n            {\n                return FPUTWC(ch, h);\n            }\n\n            static if (c.sizeof == 1)\n            {\n                // simple char\n                highSurrogateShouldBeEmpty();\n                if (orientation_ <= 0) trustedFPUTC(c, handle_);\n                else trustedFPUTWC(c, handle_);\n            }\n            else static if (c.sizeof == 2)\n            {\n                import std.utf : encode;\n\n                if (orientation_ <= 0)\n                {\n                    if (c <= 0x7F)\n                    {\n                        highSurrogateShouldBeEmpty();\n                        trustedFPUTC(c, handle_);\n                    }\n                    else if (0xD800 <= c && c <= 0xDBFF) // high surrogate\n                    {\n                        highSurrogateShouldBeEmpty();\n                        highSurrogate = c;\n                    }\n                    else // standalone or low surrogate\n                    {\n                        dchar d = c;\n                        if (highSurrogate != '\\0')\n                        {\n                            immutable wchar[2] rbuf = [highSurrogate, c];\n                            d = rbuf[].front;\n                            highSurrogate = 0;\n                        }\n                        char[4] wbuf;\n                        immutable size = encode(wbuf, d);\n                        foreach (i; 0 .. size)\n                            trustedFPUTC(wbuf[i], handle_);\n                    }\n                }\n                else\n                {\n                    trustedFPUTWC(c, handle_);\n                }\n            }\n            else // 32-bit characters\n            {\n                import std.utf : encode;\n\n                highSurrogateShouldBeEmpty();\n                if (orientation_ <= 0)\n                {\n                    if (c <= 0x7F)\n                    {\n                        trustedFPUTC(c, handle_);\n                    }\n                    else\n                    {\n                        char[4] buf = void;\n                        immutable len = encode(buf, c);\n                        foreach (i ; 0 .. len)\n                            trustedFPUTC(buf[i], handle_);\n                    }\n                }\n                else\n                {\n                    version (Windows)\n                    {\n                        import std.utf : isValidDchar;\n\n                        assert(isValidDchar(c));\n                        if (c <= 0xFFFF)\n                        {\n                            trustedFPUTWC(c, handle_);\n                        }\n                        else\n                        {\n                            trustedFPUTWC(cast(wchar)\n                                    ((((c - 0x10000) >> 10) & 0x3FF)\n                                            + 0xD800), handle_);\n                            trustedFPUTWC(cast(wchar)\n                                    (((c - 0x10000) & 0x3FF) + 0xDC00),\n                                    handle_);\n                        }\n                    }\n                    else version (Posix)\n                    {\n                        trustedFPUTWC(c, handle_);\n                    }\n                    else\n                    {\n                        static assert(0);\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Output range which locks the file when created, and unlocks the file when it goes\n     * out of scope.\n     *\n     * Returns: An $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n     * which accepts string types, `ubyte[]`, individual character types, and\n     * individual `ubyte`s.\n     *\n     * Note: Writing either arrays of `char`s or `ubyte`s is faster than\n     * writing each character individually from a range. For large amounts of data,\n     * writing the contents in chunks using an intermediary array can result\n     * in a speed increase.\n     *\n     * Throws: $(REF UTFException, std, utf) if the data given is a `char` range\n     * and it contains malformed UTF data.\n     *\n     * See_Also: $(LREF byChunk) for an example.\n     */\n    auto lockingTextWriter() @safe\n    {\n        return LockingTextWriter(this);\n    }\n\n    // An output range which optionally locks the file and puts it into\n    // binary mode (similar to rawWrite). Because it needs to restore\n    // the file mode on destruction, it is RefCounted on Windows.\n    struct BinaryWriterImpl(bool locking)\n    {\n        import std.traits : hasIndirections;\n    private:\n        // Access the FILE* handle through the 'file_' member\n        // to keep the object alive through refcounting\n        File file_;\n        string name;\n\n        version (Windows)\n        {\n            int fd, oldMode;\n            version (DIGITAL_MARS_STDIO)\n                ubyte oldInfo;\n        }\n\n    package:\n        this(ref File f)\n        {\n            import std.exception : enforce;\n            file_ = f;\n            enforce(f._p && f._p.handle);\n            name = f._name;\n            FILE* fps = f._p.handle;\n            static if (locking)\n                FLOCK(fps);\n\n            version (Windows)\n            {\n                .fflush(fps); // before changing translation mode\n                fd = ._fileno(fps);\n                oldMode = ._setmode(fd, _O_BINARY);\n                version (DIGITAL_MARS_STDIO)\n                {\n                    import core.atomic : atomicOp;\n\n                    // @@@BUG@@@ 4243\n                    oldInfo = __fhnd_info[fd];\n                    atomicOp!\"&=\"(__fhnd_info[fd], ~FHND_TEXT);\n                }\n            }\n        }\n\n    public:\n        ~this()\n        {\n            if (!file_._p || !file_._p.handle)\n                return;\n\n            FILE* fps = file_._p.handle;\n\n            version (Windows)\n            {\n                .fflush(fps); // before restoring translation mode\n                version (DIGITAL_MARS_STDIO)\n                {\n                    // @@@BUG@@@ 4243\n                    __fhnd_info[fd] = oldInfo;\n                }\n                ._setmode(fd, oldMode);\n            }\n\n            FUNLOCK(fps);\n        }\n\n        void rawWrite(T)(in T[] buffer)\n        {\n            import std.conv : text;\n            import std.exception : errnoEnforce;\n\n            auto result = trustedFwrite(file_._p.handle, buffer);\n            if (result == result.max) result = 0;\n            errnoEnforce(result == buffer.length,\n                    text(\"Wrote \", result, \" instead of \", buffer.length,\n                            \" objects of type \", T.stringof, \" to file `\",\n                            name, \"'\"));\n        }\n\n        version (Windows)\n        {\n            @disable this(this);\n        }\n        else\n        {\n            this(this)\n            {\n                if (auto p = file_._p)\n                {\n                    if (p.handle) FLOCK(p.handle);\n                }\n            }\n        }\n\n        void put(T)(auto ref scope const T value)\n        if (!hasIndirections!T &&\n            !isInputRange!T)\n        {\n            rawWrite((&value)[0 .. 1]);\n        }\n\n        void put(T)(scope const(T)[] array)\n        if (!hasIndirections!T &&\n            !isInputRange!T)\n        {\n            rawWrite(array);\n        }\n    }\n\n/** Returns an output range that locks the file and allows fast writing to it.\n\nExample:\nProduce a grayscale image of the $(LINK2 https://en.wikipedia.org/wiki/Mandelbrot_set, Mandelbrot set)\nin binary $(LINK2 https://en.wikipedia.org/wiki/Netpbm_format, Netpbm format) to standard output.\n---\nimport std.algorithm, std.range, std.stdio;\n\nvoid main()\n{\n    enum size = 500;\n    writef(\"P5\\n%d %d %d\\n\", size, size, ubyte.max);\n\n    iota(-1, 3, 2.0/size).map!(y =>\n        iota(-1.5, 0.5, 2.0/size).map!(x =>\n            cast(ubyte)(1+\n                recurrence!((a, n) => x + y*1i + a[n-1]^^2)(0+0i)\n                .take(ubyte.max)\n                .countUntil!(z => z.re^^2 + z.im^^2 > 4))\n        )\n    )\n    .copy(stdout.lockingBinaryWriter);\n}\n---\n*/\n    auto lockingBinaryWriter()\n    {\n        alias LockingBinaryWriterImpl = BinaryWriterImpl!true;\n\n        version (Windows)\n        {\n            import std.typecons : RefCounted;\n            alias LockingBinaryWriter = RefCounted!LockingBinaryWriterImpl;\n        }\n        else\n            alias LockingBinaryWriter = LockingBinaryWriterImpl;\n\n        return LockingBinaryWriter(this);\n    }\n\n    @system unittest\n    {\n        import std.algorithm.mutation : reverse;\n        import std.exception : collectException;\n        static import std.file;\n        import std.range : only, retro;\n        import std.string : format;\n\n        auto deleteme = testFilename();\n        scope(exit) collectException(std.file.remove(deleteme));\n\n        {\n            auto writer = File(deleteme, \"wb\").lockingBinaryWriter();\n            auto input = File(deleteme, \"rb\");\n\n            ubyte[1] byteIn = [42];\n            writer.rawWrite(byteIn);\n            destroy(writer);\n\n            ubyte[1] byteOut = input.rawRead(new ubyte[1]);\n            assert(byteIn[0] == byteOut[0]);\n        }\n\n        auto output = File(deleteme, \"wb\");\n        auto writer = output.lockingBinaryWriter();\n        auto input = File(deleteme, \"rb\");\n\n        T[] readExact(T)(T[] buf)\n        {\n            auto result = input.rawRead(buf);\n            assert(result.length == buf.length,\n                \"Read %d out of %d bytes\"\n                .format(result.length, buf.length));\n            return result;\n        }\n\n        // test raw values\n        ubyte byteIn = 42;\n        byteIn.only.copy(writer); output.flush();\n        ubyte byteOut = readExact(new ubyte[1])[0];\n        assert(byteIn == byteOut);\n\n        // test arrays\n        ubyte[] bytesIn = [1, 2, 3, 4, 5];\n        bytesIn.copy(writer); output.flush();\n        ubyte[] bytesOut = readExact(new ubyte[bytesIn.length]);\n        scope(failure) .writeln(bytesOut);\n        assert(bytesIn == bytesOut);\n\n        // test ranges of values\n        bytesIn.retro.copy(writer); output.flush();\n        bytesOut = readExact(bytesOut);\n        bytesOut.reverse();\n        assert(bytesIn == bytesOut);\n\n        // test string\n        \"foobar\".copy(writer); output.flush();\n        char[] charsOut = readExact(new char[6]);\n        assert(charsOut == \"foobar\");\n\n        // test ranges of arrays\n        only(\"foo\", \"bar\").copy(writer); output.flush();\n        charsOut = readExact(charsOut);\n        assert(charsOut == \"foobar\");\n\n        // test that we are writing arrays as is,\n        // without UTF-8 transcoding\n        \"foo\"d.copy(writer); output.flush();\n        dchar[] dcharsOut = readExact(new dchar[3]);\n        assert(dcharsOut == \"foo\");\n    }\n\n/// Get the size of the file, ulong.max if file is not searchable, but still throws if an actual error occurs.\n    @property ulong size() @safe\n    {\n        import std.exception : collectException;\n\n        ulong pos = void;\n        if (collectException(pos = tell)) return ulong.max;\n        scope(exit) seek(pos);\n        seek(0, SEEK_END);\n        return tell;\n    }\n}\n\n@system unittest\n{\n    @system struct SystemToString\n    {\n        string toString()\n        {\n            return \"system\";\n        }\n    }\n\n    @trusted struct TrustedToString\n    {\n        string toString()\n        {\n            return \"trusted\";\n        }\n    }\n\n    @safe struct SafeToString\n    {\n        string toString()\n        {\n            return \"safe\";\n        }\n    }\n\n    @system void systemTests()\n    {\n        //system code can write to files/stdout with anything!\n        if (false)\n        {\n            auto f = File();\n\n            f.write(\"just a string\");\n            f.write(\"string with arg: \", 47);\n            f.write(SystemToString());\n            f.write(TrustedToString());\n            f.write(SafeToString());\n\n            write(\"just a string\");\n            write(\"string with arg: \", 47);\n            write(SystemToString());\n            write(TrustedToString());\n            write(SafeToString());\n\n            f.writeln(\"just a string\");\n            f.writeln(\"string with arg: \", 47);\n            f.writeln(SystemToString());\n            f.writeln(TrustedToString());\n            f.writeln(SafeToString());\n\n            writeln(\"just a string\");\n            writeln(\"string with arg: \", 47);\n            writeln(SystemToString());\n            writeln(TrustedToString());\n            writeln(SafeToString());\n\n            f.writef(\"string with arg: %s\", 47);\n            f.writef(\"%s\", SystemToString());\n            f.writef(\"%s\", TrustedToString());\n            f.writef(\"%s\", SafeToString());\n\n            writef(\"string with arg: %s\", 47);\n            writef(\"%s\", SystemToString());\n            writef(\"%s\", TrustedToString());\n            writef(\"%s\", SafeToString());\n\n            f.writefln(\"string with arg: %s\", 47);\n            f.writefln(\"%s\", SystemToString());\n            f.writefln(\"%s\", TrustedToString());\n            f.writefln(\"%s\", SafeToString());\n\n            writefln(\"string with arg: %s\", 47);\n            writefln(\"%s\", SystemToString());\n            writefln(\"%s\", TrustedToString());\n            writefln(\"%s\", SafeToString());\n        }\n    }\n\n    @safe void safeTests()\n    {\n        auto f = File();\n\n        //safe code can write to files only with @safe and @trusted code...\n        if (false)\n        {\n            f.write(\"just a string\");\n            f.write(\"string with arg: \", 47);\n            f.write(TrustedToString());\n            f.write(SafeToString());\n\n            write(\"just a string\");\n            write(\"string with arg: \", 47);\n            write(TrustedToString());\n            write(SafeToString());\n\n            f.writeln(\"just a string\");\n            f.writeln(\"string with arg: \", 47);\n            f.writeln(TrustedToString());\n            f.writeln(SafeToString());\n\n            writeln(\"just a string\");\n            writeln(\"string with arg: \", 47);\n            writeln(TrustedToString());\n            writeln(SafeToString());\n\n            f.writef(\"string with arg: %s\", 47);\n            f.writef(\"%s\", TrustedToString());\n            f.writef(\"%s\", SafeToString());\n\n            writef(\"string with arg: %s\", 47);\n            writef(\"%s\", TrustedToString());\n            writef(\"%s\", SafeToString());\n\n            f.writefln(\"string with arg: %s\", 47);\n            f.writefln(\"%s\", TrustedToString());\n            f.writefln(\"%s\", SafeToString());\n\n            writefln(\"string with arg: %s\", 47);\n            writefln(\"%s\", TrustedToString());\n            writefln(\"%s\", SafeToString());\n        }\n\n        static assert(!__traits(compiles, f.write(SystemToString().toString())));\n        static assert(!__traits(compiles, f.writeln(SystemToString())));\n        static assert(!__traits(compiles, f.writef(\"%s\", SystemToString())));\n        static assert(!__traits(compiles, f.writefln(\"%s\", SystemToString())));\n\n        static assert(!__traits(compiles, write(SystemToString().toString())));\n        static assert(!__traits(compiles, writeln(SystemToString())));\n        static assert(!__traits(compiles, writef(\"%s\", SystemToString())));\n        static assert(!__traits(compiles, writefln(\"%s\", SystemToString())));\n    }\n\n    systemTests();\n    safeTests();\n}\n\n@safe unittest\n{\n    import std.exception : collectException;\n    static import std.file;\n\n    auto deleteme = testFilename();\n    scope(exit) collectException(std.file.remove(deleteme));\n    std.file.write(deleteme, \"1 2 3\");\n    auto f = File(deleteme);\n    assert(f.size == 5);\n    assert(f.tell == 0);\n}\n\n@system unittest\n{\n    // @system due to readln\n    static import std.file;\n    import std.range : chain, only, repeat;\n    import std.range.primitives : isOutputRange;\n\n    auto deleteme = testFilename();\n    scope(exit) std.file.remove(deleteme);\n\n    {\n        auto writer = File(deleteme, \"w\").lockingTextWriter();\n        static assert(isOutputRange!(typeof(writer), dchar));\n        writer.put(\"日本語\");\n        writer.put(\"日本語\"w);\n        writer.put(\"日本語\"d);\n        writer.put('日');\n        writer.put(chain(only('本'), only('語')));\n        writer.put(repeat('#', 12)); // BUG 11945\n        writer.put(cast(immutable(ubyte)[])\"日本語\"); // Bug 17229\n    }\n    assert(File(deleteme).readln() == \"日本語日本語日本語日本語############日本語\");\n}\n\n@safe unittest // wchar -> char\n{\n    static import std.file;\n    import std.exception : assertThrown;\n    import std.utf : UTFException;\n\n    auto deleteme = testFilename();\n    scope(exit) std.file.remove(deleteme);\n\n    {\n        auto writer = File(deleteme, \"w\").lockingTextWriter();\n        writer.put(\"\\U0001F608\"w);\n    }\n    assert(std.file.readText!string(deleteme) == \"\\U0001F608\");\n\n    // Test invalid input: unpaired high surrogate\n    {\n        immutable wchar surr = \"\\U0001F608\"w[0];\n        auto f = File(deleteme, \"w\");\n        assertThrown!UTFException(() {\n            auto writer = f.lockingTextWriter();\n            writer.put('x');\n            writer.put(surr);\n            assertThrown!UTFException(writer.put(char('y')));\n            assertThrown!UTFException(writer.put(wchar('y')));\n            assertThrown!UTFException(writer.put(dchar('y')));\n            assertThrown!UTFException(writer.put(surr));\n            // First `surr` is still unpaired at this point. `writer` gets\n            // destroyed now, and the destructor throws a UTFException for\n            // the unpaired surrogate.\n        } ());\n    }\n    assert(std.file.readText!string(deleteme) == \"x\");\n\n    // Test invalid input: unpaired low surrogate\n    {\n        immutable wchar surr = \"\\U0001F608\"w[1];\n        auto writer = File(deleteme, \"w\").lockingTextWriter();\n        assertThrown!UTFException(writer.put(surr));\n        writer.put('y');\n        assertThrown!UTFException(writer.put(surr));\n    }\n    assert(std.file.readText!string(deleteme) == \"y\");\n}\n\n@safe unittest\n{\n    import std.exception : collectException;\n    auto e = collectException({ File f; f.writeln(\"Hello!\"); }());\n    assert(e && e.msg == \"Attempting to write to closed File\");\n}\n\nversion (StdStressTest)\n{\n    // issue 15768\n    @system unittest\n    {\n        import std.parallelism : parallel;\n        import std.range : iota;\n\n        auto deleteme = testFilename();\n        stderr = File(deleteme, \"w\");\n\n        foreach (t; 1_000_000.iota.parallel)\n        {\n            stderr.write(\"aaa\");\n        }\n    }\n}\n\n/// Used to specify the lock type for `File.lock` and `File.tryLock`.\nenum LockType\n{\n    /**\n     * Specifies a _read (shared) lock. A _read lock denies all processes\n     * write access to the specified region of the file, including the\n     * process that first locks the region. All processes can _read the\n     * locked region. Multiple simultaneous _read locks are allowed, as\n     * long as there are no exclusive locks.\n     */\n    read,\n\n    /**\n     * Specifies a read/write (exclusive) lock. A read/write lock denies all\n     * other processes both read and write access to the locked file region.\n     * If a segment has an exclusive lock, it may not have any shared locks\n     * or other exclusive locks.\n     */\n    readWrite\n}\n\nstruct LockingTextReader\n{\n    private File _f;\n    private char _front;\n    private bool _hasChar;\n\n    this(File f)\n    {\n        import std.exception : enforce;\n        enforce(f.isOpen, \"LockingTextReader: File must be open\");\n        _f = f;\n        FLOCK(_f._p.handle);\n    }\n\n    this(this)\n    {\n        FLOCK(_f._p.handle);\n    }\n\n    ~this()\n    {\n        if (_hasChar)\n            ungetc(_front, cast(FILE*)_f._p.handle);\n\n        // File locking has its own reference count\n        if (_f.isOpen) FUNLOCK(_f._p.handle);\n    }\n\n    void opAssign(LockingTextReader r)\n    {\n        import std.algorithm.mutation : swap;\n        swap(this, r);\n    }\n\n    @property bool empty()\n    {\n        if (!_hasChar)\n        {\n            if (!_f.isOpen || _f.eof)\n                return true;\n            immutable int c = FGETC(cast(_iobuf*) _f._p.handle);\n            if (c == EOF)\n            {\n                .destroy(_f);\n                return true;\n            }\n            _front = cast(char) c;\n            _hasChar = true;\n        }\n        return false;\n    }\n\n    @property char front()\n    {\n        if (!_hasChar)\n        {\n            version (assert)\n            {\n                import core.exception : RangeError;\n                if (empty)\n                    throw new RangeError();\n            }\n            else\n            {\n                empty;\n            }\n        }\n        return _front;\n    }\n\n    void popFront()\n    {\n        if (!_hasChar)\n            empty;\n        _hasChar = false;\n    }\n}\n\n@system unittest\n{\n    // @system due to readf\n    static import std.file;\n    import std.range.primitives : isInputRange;\n\n    static assert(isInputRange!LockingTextReader);\n    auto deleteme = testFilename();\n    std.file.write(deleteme, \"1 2 3\");\n    scope(exit) std.file.remove(deleteme);\n    int x;\n    auto f = File(deleteme);\n    f.readf(\"%s \", &x);\n    assert(x == 1);\n    f.readf(\"%d \", &x);\n    assert(x == 2);\n    f.readf(\"%d \", &x);\n    assert(x == 3);\n}\n\n@system unittest // bugzilla 13686\n{\n    import std.algorithm.comparison : equal;\n    static import std.file;\n    import std.utf : byDchar;\n\n    auto deleteme = testFilename();\n    std.file.write(deleteme, \"Тест\");\n    scope(exit) std.file.remove(deleteme);\n\n    string s;\n    File(deleteme).readf(\"%s\", &s);\n    assert(s == \"Тест\");\n\n    auto ltr = LockingTextReader(File(deleteme)).byDchar;\n    assert(equal(ltr, \"Тест\".byDchar));\n}\n\n@system unittest // bugzilla 12320\n{\n    static import std.file;\n    auto deleteme = testFilename();\n    std.file.write(deleteme, \"ab\");\n    scope(exit) std.file.remove(deleteme);\n    auto ltr = LockingTextReader(File(deleteme));\n    assert(ltr.front == 'a');\n    ltr.popFront();\n    assert(ltr.front == 'b');\n    ltr.popFront();\n    assert(ltr.empty);\n}\n\n@system unittest // bugzilla 14861\n{\n    // @system due to readf\n    static import std.file;\n    auto deleteme = testFilename();\n    File fw = File(deleteme, \"w\");\n    for (int i; i != 5000; i++)\n        fw.writeln(i, \";\", \"Иванов;Пётр;Петрович\");\n    fw.close();\n    scope(exit) std.file.remove(deleteme);\n    // Test read\n    File fr = File(deleteme, \"r\");\n    scope (exit) fr.close();\n    int nom; string fam, nam, ot;\n    // Error format read\n    while (!fr.eof)\n        fr.readf(\"%s;%s;%s;%s\\n\", &nom, &fam, &nam, &ot);\n}\n\n/**\n * Indicates whether `T` is a file handle, i.e. the type\n * is implicitly convertable to $(LREF File) or a pointer to a\n * $(REF FILE, core,stdc,stdio).\n *\n * Returns:\n *      `true` if `T` is a file handle, `false` otherwise.\n */\ntemplate isFileHandle(T)\n{\n    enum isFileHandle = is(T : FILE*) ||\n        is(T : File);\n}\n\n///\n@safe unittest\n{\n    static assert(isFileHandle!(FILE*));\n    static assert(isFileHandle!(File));\n}\n\n/**\n * Property used by writeln/etc. so it can infer @safe since stdout is __gshared\n */\nprivate @property File trustedStdout() @trusted\n{\n    return stdout;\n}\n\n/***********************************\nWrites its arguments in text format to standard output (without a trailing newline).\n\nParams:\n    args = the items to write to `stdout`\n\nThrows: In case of an I/O error, throws an `StdioException`.\n\nExample:\n    Reads `stdin` and writes it to `stdout` with an argument\n    counter.\n---\nimport std.stdio;\n\nvoid main()\n{\n    string line;\n\n    for (size_t count = 0; (line = readln) !is null; count++)\n    {\n         write(\"Input \", count, \": \", line, \"\\n\");\n    }\n}\n---\n */\nvoid write(T...)(T args)\nif (!is(T[0] : File))\n{\n    trustedStdout.write(args);\n}\n\n@system unittest\n{\n    static import std.file;\n\n    scope(failure) printf(\"Failed test at line %d\\n\", __LINE__);\n    void[] buf;\n    if (false) write(buf);\n    // test write\n    auto deleteme = testFilename();\n    auto f = File(deleteme, \"w\");\n    f.write(\"Hello, \",  \"world number \", 42, \"!\");\n    f.close();\n    scope(exit) { std.file.remove(deleteme); }\n    assert(cast(char[]) std.file.read(deleteme) == \"Hello, world number 42!\");\n}\n\n/***********************************\n * Equivalent to `write(args, '\\n')`.  Calling `writeln` without\n * arguments is valid and just prints a newline to the standard\n * output.\n *\n * Params:\n *      args = the items to write to `stdout`\n *\n * Throws:\n *      In case of an I/O error, throws an $(LREF StdioException).\n * Example:\n *        Reads `stdin` and writes it to `stdout` with a argument\n *        counter.\n---\nimport std.stdio;\n\nvoid main()\n{\n    string line;\n\n    for (size_t count = 0; (line = readln) !is null; count++)\n    {\n         writeln(\"Input \", count, \": \", line);\n    }\n}\n---\n */\nvoid writeln(T...)(T args)\n{\n    import std.traits : isAggregateType;\n    static if (T.length == 0)\n    {\n        import std.exception : enforce;\n\n        enforce(fputc('\\n', .trustedStdout._p.handle) != EOF, \"fputc failed\");\n    }\n    else static if (T.length == 1 &&\n                    is(typeof(args[0]) : const(char)[]) &&\n                    !is(typeof(args[0]) == enum) &&\n                    !is(Unqual!(typeof(args[0])) == typeof(null)) &&\n                    !isAggregateType!(typeof(args[0])))\n    {\n        import std.traits : isStaticArray;\n\n        // Specialization for strings - a very frequent case\n        auto w = .trustedStdout.lockingTextWriter();\n\n        static if (isStaticArray!(typeof(args[0])))\n        {\n            w.put(args[0][]);\n        }\n        else\n        {\n            w.put(args[0]);\n        }\n        w.put('\\n');\n    }\n    else\n    {\n        // Most general instance\n        trustedStdout.write(args, '\\n');\n    }\n}\n\n@safe unittest\n{\n    // Just make sure the call compiles\n    if (false) writeln();\n\n    if (false) writeln(\"wyda\");\n\n    // bug 8040\n    if (false) writeln(null);\n    if (false) writeln(\">\", null, \"<\");\n\n    // Bugzilla 14041\n    if (false)\n    {\n        char[8] a;\n        writeln(a);\n    }\n}\n\n@system unittest\n{\n    static import std.file;\n\n    scope(failure) printf(\"Failed test at line %d\\n\", __LINE__);\n\n    // test writeln\n    auto deleteme = testFilename();\n    auto f = File(deleteme, \"w\");\n    scope(exit) { std.file.remove(deleteme); }\n    f.writeln(\"Hello, \",  \"world number \", 42, \"!\");\n    f.close();\n    version (Windows)\n        assert(cast(char[]) std.file.read(deleteme) ==\n                \"Hello, world number 42!\\r\\n\");\n    else\n        assert(cast(char[]) std.file.read(deleteme) ==\n                \"Hello, world number 42!\\n\");\n\n    // test writeln on stdout\n    auto saveStdout = stdout;\n    scope(exit) stdout = saveStdout;\n    stdout.open(deleteme, \"w\");\n    writeln(\"Hello, \",  \"world number \", 42, \"!\");\n    stdout.close();\n    version (Windows)\n        assert(cast(char[]) std.file.read(deleteme) ==\n                \"Hello, world number 42!\\r\\n\");\n    else\n        assert(cast(char[]) std.file.read(deleteme) ==\n                \"Hello, world number 42!\\n\");\n\n    stdout.open(deleteme, \"w\");\n    writeln(\"Hello!\"c);\n    writeln(\"Hello!\"w);    // bug 8386\n    writeln(\"Hello!\"d);    // bug 8386\n    writeln(\"embedded\\0null\"c); // bug 8730\n    stdout.close();\n    version (Windows)\n        assert(cast(char[]) std.file.read(deleteme) ==\n            \"Hello!\\r\\nHello!\\r\\nHello!\\r\\nembedded\\0null\\r\\n\");\n    else\n        assert(cast(char[]) std.file.read(deleteme) ==\n            \"Hello!\\nHello!\\nHello!\\nembedded\\0null\\n\");\n}\n\n@system unittest\n{\n    static import std.file;\n\n    auto deleteme = testFilename();\n    auto f = File(deleteme, \"w\");\n    scope(exit) { std.file.remove(deleteme); }\n\n    enum EI : int    { A, B }\n    enum ED : double { A = 0, B } // NOTE: explicit initialization to 0 required during Enum init deprecation cycle\n    enum EC : char   { A = 0, B } // NOTE: explicit initialization to 0 required during Enum init deprecation cycle\n    enum ES : string { A = \"aaa\", B = \"bbb\" }\n\n    f.writeln(EI.A);  // false, but A on 2.058\n    f.writeln(EI.B);  // true, but B on 2.058\n\n    f.writeln(ED.A);  // A\n    f.writeln(ED.B);  // B\n\n    f.writeln(EC.A);  // A\n    f.writeln(EC.B);  // B\n\n    f.writeln(ES.A);  // A\n    f.writeln(ES.B);  // B\n\n    f.close();\n    version (Windows)\n        assert(cast(char[]) std.file.read(deleteme) ==\n                \"A\\r\\nB\\r\\nA\\r\\nB\\r\\nA\\r\\nB\\r\\nA\\r\\nB\\r\\n\");\n    else\n        assert(cast(char[]) std.file.read(deleteme) ==\n                \"A\\nB\\nA\\nB\\nA\\nB\\nA\\nB\\n\");\n}\n\n@system unittest\n{\n    static auto useInit(T)(T ltw)\n    {\n        T val;\n        val = ltw;\n        val = T.init;\n        return val;\n    }\n    useInit(stdout.lockingTextWriter());\n}\n\n\n/***********************************\nWrites formatted data to standard output (without a trailing newline).\n\nParams:\nfmt = The $(REF_ALTTEXT format string, formattedWrite, std, _format).\nWhen passed as a compile-time argument, the string will be statically checked\nagainst the argument types passed.\nargs = Items to write.\n\nNote: In older versions of Phobos, it used to be possible to write:\n\n------\nwritef(stderr, \"%s\", \"message\");\n------\n\nto print a message to `stderr`. This syntax is no longer supported, and has\nbeen superceded by:\n\n------\nstderr.writef(\"%s\", \"message\");\n------\n\n*/\nvoid writef(alias fmt, A...)(A args)\nif (isSomeString!(typeof(fmt)))\n{\n    import std.format : checkFormatException;\n\n    alias e = checkFormatException!(fmt, A);\n    static assert(!e, e.msg);\n    return .writef(fmt, args);\n}\n\n/// ditto\nvoid writef(Char, A...)(in Char[] fmt, A args)\n{\n    trustedStdout.writef(fmt, args);\n}\n\n@system unittest\n{\n    static import std.file;\n\n    scope(failure) printf(\"Failed test at line %d\\n\", __LINE__);\n\n    // test writef\n    auto deleteme = testFilename();\n    auto f = File(deleteme, \"w\");\n    scope(exit) { std.file.remove(deleteme); }\n    f.writef!\"Hello, %s world number %s!\"(\"nice\", 42);\n    f.close();\n    assert(cast(char[]) std.file.read(deleteme) ==  \"Hello, nice world number 42!\");\n    // test write on stdout\n    auto saveStdout = stdout;\n    scope(exit) stdout = saveStdout;\n    stdout.open(deleteme, \"w\");\n    writef!\"Hello, %s world number %s!\"(\"nice\", 42);\n    stdout.close();\n    assert(cast(char[]) std.file.read(deleteme) == \"Hello, nice world number 42!\");\n}\n\n/***********************************\n * Equivalent to $(D writef(fmt, args, '\\n')).\n */\nvoid writefln(alias fmt, A...)(A args)\nif (isSomeString!(typeof(fmt)))\n{\n    import std.format : checkFormatException;\n\n    alias e = checkFormatException!(fmt, A);\n    static assert(!e, e.msg);\n    return .writefln(fmt, args);\n}\n\n/// ditto\nvoid writefln(Char, A...)(in Char[] fmt, A args)\n{\n    trustedStdout.writefln(fmt, args);\n}\n\n@system unittest\n{\n    static import std.file;\n\n    scope(failure) printf(\"Failed test at line %d\\n\", __LINE__);\n\n    // test File.writefln\n    auto deleteme = testFilename();\n    auto f = File(deleteme, \"w\");\n    scope(exit) { std.file.remove(deleteme); }\n    f.writefln!\"Hello, %s world number %s!\"(\"nice\", 42);\n    f.close();\n    version (Windows)\n        assert(cast(char[]) std.file.read(deleteme) ==\n                \"Hello, nice world number 42!\\r\\n\");\n    else\n        assert(cast(char[]) std.file.read(deleteme) ==\n                \"Hello, nice world number 42!\\n\",\n                cast(char[]) std.file.read(deleteme));\n\n    // test writefln\n    auto saveStdout = stdout;\n    scope(exit) stdout = saveStdout;\n    stdout.open(deleteme, \"w\");\n    writefln!\"Hello, %s world number %s!\"(\"nice\", 42);\n    stdout.close();\n    version (Windows)\n        assert(cast(char[]) std.file.read(deleteme) ==\n                \"Hello, nice world number 42!\\r\\n\");\n    else\n        assert(cast(char[]) std.file.read(deleteme) ==\n                \"Hello, nice world number 42!\\n\");\n}\n\n/**\n * Reads formatted data from `stdin` using $(REF formattedRead, std,_format).\n * Params:\n * format = The $(REF_ALTTEXT format string, formattedWrite, std, _format).\n * When passed as a compile-time argument, the string will be statically checked\n * against the argument types passed.\n * args = Items to be read.\n * Example:\n----\n// test.d\nvoid main()\n{\n    import std.stdio;\n    foreach (_; 0 .. 3)\n    {\n        int a;\n        readf!\" %d\"(a);\n        writeln(++a);\n    }\n}\n----\n$(CONSOLE\n% echo \"1 2 3\" | rdmd test.d\n2\n3\n4\n)\n */\nuint readf(alias format, A...)(auto ref A args)\nif (isSomeString!(typeof(format)))\n{\n    import std.format : checkFormatException;\n\n    alias e = checkFormatException!(format, A);\n    static assert(!e, e.msg);\n    return .readf(format, args);\n}\n\n/// ditto\nuint readf(A...)(scope const(char)[] format, auto ref A args)\n{\n    return stdin.readf(format, args);\n}\n\n@system unittest\n{\n    float f;\n    if (false) readf(\"%s\", &f);\n\n    char a;\n    wchar b;\n    dchar c;\n    if (false) readf(\"%s %s %s\", a, b, c);\n    // backwards compatibility with pointers\n    if (false) readf(\"%s %s %s\", a, &b, c);\n    if (false) readf(\"%s %s %s\", &a, &b, &c);\n}\n\n/**********************************\n * Read line from `stdin`.\n *\n * This version manages its own read buffer, which means one memory allocation per call. If you are not\n * retaining a reference to the read data, consider the `readln(buf)` version, which may offer\n * better performance as it can reuse its read buffer.\n *\n * Returns:\n *        The line that was read, including the line terminator character.\n * Params:\n *        S = Template parameter; the type of the allocated buffer, and the type returned. Defaults to `string`.\n *        terminator = Line terminator (by default, `'\\n'`).\n * Note:\n *        String terminators are not supported due to ambiguity with readln(buf) below.\n * Throws:\n *        `StdioException` on I/O error, or `UnicodeException` on Unicode conversion error.\n * Example:\n *        Reads `stdin` and writes it to `stdout`.\n---\nimport std.stdio;\n\nvoid main()\n{\n    string line;\n    while ((line = readln()) !is null)\n        write(line);\n}\n---\n*/\nS readln(S = string)(dchar terminator = '\\n')\nif (isSomeString!S)\n{\n    return stdin.readln!S(terminator);\n}\n\n/**********************************\n * Read line from `stdin` and write it to buf[], including terminating character.\n *\n * This can be faster than $(D line = readln()) because you can reuse\n * the buffer for each call. Note that reusing the buffer means that you\n * must copy the previous contents if you wish to retain them.\n *\n * Returns:\n *        `size_t` 0 for end of file, otherwise number of characters read\n * Params:\n *        buf = Buffer used to store the resulting line data. buf is resized as necessary.\n *        terminator = Line terminator (by default, `'\\n'`). Use $(REF newline, std,ascii)\n *        for portability (unless the file was opened in text mode).\n * Throws:\n *        `StdioException` on I/O error, or `UnicodeException` on Unicode conversion error.\n * Example:\n *        Reads `stdin` and writes it to `stdout`.\n---\nimport std.stdio;\n\nvoid main()\n{\n    char[] buf;\n    while (readln(buf))\n        write(buf);\n}\n---\n*/\nsize_t readln(C)(ref C[] buf, dchar terminator = '\\n')\nif (isSomeChar!C && is(Unqual!C == C) && !is(C == enum))\n{\n    return stdin.readln(buf, terminator);\n}\n\n/** ditto */\nsize_t readln(C, R)(ref C[] buf, R terminator)\nif (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) &&\n    isBidirectionalRange!R && is(typeof(terminator.front == dchar.init)))\n{\n    return stdin.readln(buf, terminator);\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n\n    //we can't actually test readln, so at the very least,\n    //we test compilability\n    void foo()\n    {\n        readln();\n        readln('\\t');\n        static foreach (String; AliasSeq!(string, char[], wstring, wchar[], dstring, dchar[]))\n        {\n            readln!String();\n            readln!String('\\t');\n        }\n        static foreach (String; AliasSeq!(char[], wchar[], dchar[]))\n        {{\n            String buf;\n            readln(buf);\n            readln(buf, '\\t');\n            readln(buf, \"<br />\");\n        }}\n    }\n}\n\n/*\n * Convenience function that forwards to `core.sys.posix.stdio.fopen`\n * (to `_wfopen` on Windows)\n * with appropriately-constructed C-style strings.\n */\nprivate FILE* _fopen(R1, R2)(R1 name, R2 mode = \"r\")\nif ((isInputRange!R1 && isSomeChar!(ElementEncodingType!R1) || isSomeString!R1) &&\n    (isInputRange!R2 && isSomeChar!(ElementEncodingType!R2) || isSomeString!R2))\n{\n    import std.internal.cstring : tempCString;\n\n    auto namez = name.tempCString!FSChar();\n    auto modez = mode.tempCString!FSChar();\n\n    static _fopenImpl(const(FSChar)* namez, const(FSChar)* modez) @trusted nothrow @nogc\n    {\n        version (Windows)\n        {\n            return _wfopen(namez, modez);\n        }\n        else version (Posix)\n        {\n            /*\n             * The new opengroup large file support API is transparently\n             * included in the normal C bindings. http://opengroup.org/platform/lfs.html#1.0\n             * if _FILE_OFFSET_BITS in druntime is 64, off_t is 64 bit and\n             * the normal functions work fine. If not, then large file support\n             * probably isn't available. Do not use the old transitional API\n             * (the native extern(C) fopen64, http://www.unix.org/version2/whatsnew/lfs20mar.html#3.0)\n             */\n            import core.sys.posix.stdio : fopen;\n            return fopen(namez, modez);\n        }\n        else\n        {\n            return fopen(namez, modez);\n        }\n    }\n    return _fopenImpl(namez, modez);\n}\n\nversion (Posix)\n{\n    /***********************************\n     * Convenience function that forwards to `core.sys.posix.stdio.popen`\n     * with appropriately-constructed C-style strings.\n     */\n    FILE* _popen(R1, R2)(R1 name, R2 mode = \"r\") @trusted nothrow @nogc\n    if ((isInputRange!R1 && isSomeChar!(ElementEncodingType!R1) || isSomeString!R1) &&\n        (isInputRange!R2 && isSomeChar!(ElementEncodingType!R2) || isSomeString!R2))\n    {\n        import std.internal.cstring : tempCString;\n\n        auto namez = name.tempCString!FSChar();\n        auto modez = mode.tempCString!FSChar();\n\n        static popenImpl(const(FSChar)* namez, const(FSChar)* modez) @trusted nothrow @nogc\n        {\n            import core.sys.posix.stdio : popen;\n            return popen(namez, modez);\n        }\n        return popenImpl(namez, modez);\n    }\n}\n\n/*\n * Convenience function that forwards to `core.stdc.stdio.fwrite`\n */\nprivate auto trustedFwrite(T)(FILE* f, const T[] obj) @trusted\n{\n    return fwrite(obj.ptr, T.sizeof, obj.length, f);\n}\n\n/*\n * Convenience function that forwards to `core.stdc.stdio.fread`\n */\nprivate auto trustedFread(T)(FILE* f, T[] obj) @trusted\n{\n    return fread(obj.ptr, T.sizeof, obj.length, f);\n}\n\n/**\n * Iterates through the lines of a file by using `foreach`.\n *\n * Example:\n *\n---------\nvoid main()\n{\n  foreach (string line; lines(stdin))\n  {\n    ... use line ...\n  }\n}\n---------\nThe line terminator (`'\\n'` by default) is part of the string read (it\ncould be missing in the last line of the file). Several types are\nsupported for `line`, and the behavior of `lines`\nchanges accordingly:\n\n$(OL $(LI If `line` has type `string`, $(D\nwstring), or `dstring`, a new string of the respective type\nis allocated every read.) $(LI If `line` has type $(D\nchar[]), `wchar[]`, `dchar[]`, the line's content\nwill be reused (overwritten) across reads.) $(LI If `line`\nhas type `immutable(ubyte)[]`, the behavior is similar to\ncase (1), except that no UTF checking is attempted upon input.) $(LI\nIf `line` has type `ubyte[]`, the behavior is\nsimilar to case (2), except that no UTF checking is attempted upon\ninput.))\n\nIn all cases, a two-symbols versions is also accepted, in which case\nthe first symbol (of integral type, e.g. `ulong` or $(D\nuint)) tracks the zero-based number of the current line.\n\nExample:\n----\n  foreach (ulong i, string line; lines(stdin))\n  {\n    ... use line ...\n  }\n----\n\n In case of an I/O error, an `StdioException` is thrown.\n\nSee_Also:\n$(LREF byLine)\n */\n\nstruct lines\n{\n    private File f;\n    private dchar terminator = '\\n';\n\n    /**\n    Constructor.\n    Params:\n    f = File to read lines from.\n    terminator = Line separator (`'\\n'` by default).\n    */\n    this(File f, dchar terminator = '\\n')\n    {\n        this.f = f;\n        this.terminator = terminator;\n    }\n\n    int opApply(D)(scope D dg)\n    {\n        import std.traits : Parameters;\n        alias Parms = Parameters!(dg);\n        static if (isSomeString!(Parms[$ - 1]))\n        {\n            int result = 0;\n            static if (is(Parms[$ - 1] : const(char)[]))\n                alias C = char;\n            else static if (is(Parms[$ - 1] : const(wchar)[]))\n                alias C = wchar;\n            else static if (is(Parms[$ - 1] : const(dchar)[]))\n                alias C = dchar;\n            C[] line;\n            static if (Parms.length == 2)\n                Parms[0] i = 0;\n            for (;;)\n            {\n                import std.conv : to;\n\n                if (!f.readln(line, terminator)) break;\n                auto copy = to!(Parms[$ - 1])(line);\n                static if (Parms.length == 2)\n                {\n                    result = dg(i, copy);\n                    ++i;\n                }\n                else\n                {\n                    result = dg(copy);\n                }\n                if (result != 0) break;\n            }\n            return result;\n        }\n        else\n        {\n            // raw read\n            return opApplyRaw(dg);\n        }\n    }\n    // no UTF checking\n    int opApplyRaw(D)(scope D dg)\n    {\n        import std.conv : to;\n        import std.exception : assumeUnique;\n        import std.traits : Parameters;\n\n        alias Parms = Parameters!(dg);\n        enum duplicate = is(Parms[$ - 1] : immutable(ubyte)[]);\n        int result = 1;\n        int c = void;\n        FLOCK(f._p.handle);\n        scope(exit) FUNLOCK(f._p.handle);\n        ubyte[] buffer;\n        static if (Parms.length == 2)\n            Parms[0] line = 0;\n        while ((c = FGETC(cast(_iobuf*) f._p.handle)) != -1)\n        {\n            buffer ~= to!(ubyte)(c);\n            if (c == terminator)\n            {\n                static if (duplicate)\n                    auto arg = assumeUnique(buffer);\n                else\n                    alias arg = buffer;\n                // unlock the file while calling the delegate\n                FUNLOCK(f._p.handle);\n                scope(exit) FLOCK(f._p.handle);\n                static if (Parms.length == 1)\n                {\n                    result = dg(arg);\n                }\n                else\n                {\n                    result = dg(line, arg);\n                    ++line;\n                }\n                if (result) break;\n                static if (!duplicate)\n                    buffer.length = 0;\n            }\n        }\n        // can only reach when FGETC returned -1\n        if (!f.eof) throw new StdioException(\"Error in reading file\"); // error occured\n        return result;\n    }\n}\n\n@system unittest\n{\n    static import std.file;\n    import std.meta : AliasSeq;\n\n    scope(failure) printf(\"Failed test at line %d\\n\", __LINE__);\n\n    auto deleteme = testFilename();\n    scope(exit) { std.file.remove(deleteme); }\n\n    alias TestedWith =\n          AliasSeq!(string, wstring, dstring,\n                    char[], wchar[], dchar[]);\n    foreach (T; TestedWith)\n    {\n        // test looping with an empty file\n        std.file.write(deleteme, \"\");\n        auto f = File(deleteme, \"r\");\n        foreach (T line; lines(f))\n        {\n            assert(false);\n        }\n        f.close();\n\n        // test looping with a file with three lines\n        std.file.write(deleteme, \"Line one\\nline two\\nline three\\n\");\n        f.open(deleteme, \"r\");\n        uint i = 0;\n        foreach (T line; lines(f))\n        {\n            if (i == 0) assert(line == \"Line one\\n\");\n            else if (i == 1) assert(line == \"line two\\n\");\n            else if (i == 2) assert(line == \"line three\\n\");\n            else assert(false);\n            ++i;\n        }\n        f.close();\n\n        // test looping with a file with three lines, last without a newline\n        std.file.write(deleteme, \"Line one\\nline two\\nline three\");\n        f.open(deleteme, \"r\");\n        i = 0;\n        foreach (T line; lines(f))\n        {\n            if (i == 0) assert(line == \"Line one\\n\");\n            else if (i == 1) assert(line == \"line two\\n\");\n            else if (i == 2) assert(line == \"line three\");\n            else assert(false);\n            ++i;\n        }\n        f.close();\n    }\n\n    // test with ubyte[] inputs\n    alias TestedWith2 = AliasSeq!(immutable(ubyte)[], ubyte[]);\n    foreach (T; TestedWith2)\n    {\n        // test looping with an empty file\n        std.file.write(deleteme, \"\");\n        auto f = File(deleteme, \"r\");\n        foreach (T line; lines(f))\n        {\n            assert(false);\n        }\n        f.close();\n\n        // test looping with a file with three lines\n        std.file.write(deleteme, \"Line one\\nline two\\nline three\\n\");\n        f.open(deleteme, \"r\");\n        uint i = 0;\n        foreach (T line; lines(f))\n        {\n            if (i == 0) assert(cast(char[]) line == \"Line one\\n\");\n            else if (i == 1) assert(cast(char[]) line == \"line two\\n\",\n                T.stringof ~ \" \" ~ cast(char[]) line);\n            else if (i == 2) assert(cast(char[]) line == \"line three\\n\");\n            else assert(false);\n            ++i;\n        }\n        f.close();\n\n        // test looping with a file with three lines, last without a newline\n        std.file.write(deleteme, \"Line one\\nline two\\nline three\");\n        f.open(deleteme, \"r\");\n        i = 0;\n        foreach (T line; lines(f))\n        {\n            if (i == 0) assert(cast(char[]) line == \"Line one\\n\");\n            else if (i == 1) assert(cast(char[]) line == \"line two\\n\");\n            else if (i == 2) assert(cast(char[]) line == \"line three\");\n            else assert(false);\n            ++i;\n        }\n        f.close();\n\n    }\n\n    static foreach (T; AliasSeq!(ubyte[]))\n    {\n        // test looping with a file with three lines, last without a newline\n        // using a counter too this time\n        std.file.write(deleteme, \"Line one\\nline two\\nline three\");\n        auto f = File(deleteme, \"r\");\n        uint i = 0;\n        foreach (ulong j, T line; lines(f))\n        {\n            if (i == 0) assert(cast(char[]) line == \"Line one\\n\");\n            else if (i == 1) assert(cast(char[]) line == \"line two\\n\");\n            else if (i == 2) assert(cast(char[]) line == \"line three\");\n            else assert(false);\n            ++i;\n        }\n        f.close();\n    }\n}\n\n/**\nIterates through a file a chunk at a time by using `foreach`.\n\nExample:\n\n---------\nvoid main()\n{\n    foreach (ubyte[] buffer; chunks(stdin, 4096))\n    {\n        ... use buffer ...\n    }\n}\n---------\n\nThe content of `buffer` is reused across calls. In the\n example above, `buffer.length` is 4096 for all iterations,\n except for the last one, in which case `buffer.length` may\n be less than 4096 (but always greater than zero).\n\n In case of an I/O error, an `StdioException` is thrown.\n*/\nauto chunks(File f, size_t size)\n{\n    return ChunksImpl(f, size);\n}\nprivate struct ChunksImpl\n{\n    private File f;\n    private size_t size;\n    // private string fileName; // Currently, no use\n\n    this(File f, size_t size)\n    in\n    {\n        assert(size, \"size must be larger than 0\");\n    }\n    do\n    {\n        this.f = f;\n        this.size = size;\n    }\n\n    int opApply(D)(scope D dg)\n    {\n        import core.stdc.stdlib : alloca;\n        enum maxStackSize = 1024 * 16;\n        ubyte[] buffer = void;\n        if (size < maxStackSize)\n            buffer = (cast(ubyte*) alloca(size))[0 .. size];\n        else\n            buffer = new ubyte[size];\n        size_t r = void;\n        int result = 1;\n        uint tally = 0;\n        while ((r = trustedFread(f._p.handle, buffer)) > 0)\n        {\n            assert(r <= size);\n            if (r != size)\n            {\n                // error occured\n                if (!f.eof) throw new StdioException(null);\n                buffer.length = r;\n            }\n            static if (is(typeof(dg(tally, buffer))))\n            {\n                if ((result = dg(tally, buffer)) != 0) break;\n            }\n            else\n            {\n                if ((result = dg(buffer)) != 0) break;\n            }\n            ++tally;\n        }\n        return result;\n    }\n}\n\n@system unittest\n{\n    static import std.file;\n\n    scope(failure) printf(\"Failed test at line %d\\n\", __LINE__);\n\n    auto deleteme = testFilename();\n    scope(exit) { std.file.remove(deleteme); }\n\n    // test looping with an empty file\n    std.file.write(deleteme, \"\");\n    auto f = File(deleteme, \"r\");\n    foreach (ubyte[] line; chunks(f, 4))\n    {\n        assert(false);\n    }\n    f.close();\n\n    // test looping with a file with three lines\n    std.file.write(deleteme, \"Line one\\nline two\\nline three\\n\");\n    f = File(deleteme, \"r\");\n    uint i = 0;\n    foreach (ubyte[] line; chunks(f, 3))\n    {\n        if (i == 0) assert(cast(char[]) line == \"Lin\");\n        else if (i == 1) assert(cast(char[]) line == \"e o\");\n        else if (i == 2) assert(cast(char[]) line == \"ne\\n\");\n        else break;\n        ++i;\n    }\n    f.close();\n}\n\n\n/**\nWrites an array or range to a file.\nShorthand for $(D data.copy(File(fileName, \"wb\").lockingBinaryWriter)).\nSimilar to $(REF write, std,file), strings are written as-is,\nrather than encoded according to the `File`'s $(HTTP\nen.cppreference.com/w/c/io#Narrow_and_wide_orientation,\norientation).\n*/\nvoid toFile(T)(T data, string fileName)\nif (is(typeof(copy(data, stdout.lockingBinaryWriter))))\n{\n    copy(data, File(fileName, \"wb\").lockingBinaryWriter);\n}\n\n@system unittest\n{\n    static import std.file;\n\n    auto deleteme = testFilename();\n    scope(exit) { std.file.remove(deleteme); }\n\n    \"Test\".toFile(deleteme);\n    assert(std.file.readText(deleteme) == \"Test\");\n}\n\n/*********************\n * Thrown if I/O errors happen.\n */\nclass StdioException : Exception\n{\n    static import core.stdc.errno;\n    /// Operating system error code.\n    uint errno;\n\n/**\nInitialize with a message and an error code.\n*/\n    this(string message, uint e = core.stdc.errno.errno) @trusted\n    {\n        import std.exception : errnoString;\n        errno = e;\n        auto sysmsg = errnoString(errno);\n        // If e is 0, we don't use the system error message.  (The message\n        // is \"Success\", which is rather pointless for an exception.)\n        super(e == 0 ? message\n                     : (message ? message ~ \" (\" ~ sysmsg ~ \")\" : sysmsg));\n    }\n\n/** Convenience functions that throw an `StdioException`. */\n    static void opCall(string msg)\n    {\n        throw new StdioException(msg);\n    }\n\n/// ditto\n    static void opCall()\n    {\n        throw new StdioException(null, core.stdc.errno.errno);\n    }\n}\n\nenum StdFileHandle: string\n{\n    stdin  = \"core.stdc.stdio.stdin\",\n    stdout = \"core.stdc.stdio.stdout\",\n    stderr = \"core.stdc.stdio.stderr\",\n}\n\n// Undocumented but public because the std* handles are aliasing it.\n@property ref File makeGlobal(StdFileHandle _iob)()\n{\n    __gshared File.Impl impl;\n    __gshared File result;\n\n    // Use an inline spinlock to make sure the initializer is only run once.\n    // We assume there will be at most uint.max / 2 threads trying to initialize\n    // `handle` at once and steal the high bit to indicate that the globals have\n    // been initialized.\n    static shared uint spinlock;\n    import core.atomic : atomicLoad, atomicOp, MemoryOrder;\n    if (atomicLoad!(MemoryOrder.acq)(spinlock) <= uint.max / 2)\n    {\n        for (;;)\n        {\n            if (atomicLoad!(MemoryOrder.acq)(spinlock) > uint.max / 2)\n                break;\n            if (atomicOp!\"+=\"(spinlock, 1) == 1)\n            {\n                with (StdFileHandle)\n                    assert(_iob == stdin || _iob == stdout || _iob == stderr);\n                impl.handle = mixin(_iob);\n                result._p = &impl;\n                atomicOp!\"+=\"(spinlock, uint.max / 2);\n                break;\n            }\n            atomicOp!\"-=\"(spinlock, 1);\n        }\n    }\n    return result;\n}\n\n/** The standard input stream.\n\n    Returns:\n        stdin as a $(LREF File).\n\n    Note:\n        The returned $(LREF File) wraps $(REF stdin,core,stdio), and\n        is therefore thread global. Reassigning `stdin` to a different\n        `File` must be done in a single-threaded or locked context in\n        order to avoid race conditions.\n\n        All reading from `stdin` automatically locks the file globally,\n        and will cause all other threads calling `read` to wait until\n        the lock is released.\n*/\nalias stdin = makeGlobal!(StdFileHandle.stdin);\n\n///\n@safe unittest\n{\n    // Read stdin, sort lines, write to stdout\n    import std.algorithm.mutation : copy;\n    import std.algorithm.sorting : sort;\n    import std.array : array;\n    import std.typecons : Yes;\n\n    void main()\n    {\n        stdin                       // read from stdin\n        .byLineCopy(Yes.keepTerminator) // copying each line\n        .array()                    // convert to array of lines\n        .sort()                     // sort the lines\n        .copy(                      // copy output of .sort to an OutputRange\n            stdout.lockingTextWriter()); // the OutputRange\n    }\n}\n\n/**\n    The standard output stream.\n\n    Returns:\n        stdout as a $(LREF File).\n\n    Note:\n        The returned $(LREF File) wraps $(REF stdout,core,stdio), and\n        is therefore thread global. Reassigning `stdout` to a different\n        `File` must be done in a single-threaded or locked context in\n        order to avoid race conditions.\n\n        All writing to `stdout` automatically locks the file globally,\n        and will cause all other threads calling `write` to wait until\n        the lock is released.\n*/\nalias stdout = makeGlobal!(StdFileHandle.stdout);\n\n///\n@safe unittest\n{\n    void main()\n    {\n        stdout.writeln(\"Write a message to stdout.\");\n    }\n}\n\n///\n@safe unittest\n{\n    void main()\n    {\n        import std.algorithm.iteration : filter, map, sum;\n        import std.format : format;\n        import std.range : iota, tee;\n\n        int len;\n        const r = 6.iota\n                  .filter!(a => a % 2) // 1 3 5\n                  .map!(a => a * 2) // 2 6 10\n                  .tee!(_ => stdout.writefln(\"len: %d\", len++))\n                  .sum;\n\n        assert(r == 18);\n    }\n}\n\n///\n@safe unittest\n{\n    void main()\n    {\n        import std.algorithm.mutation : copy;\n        import std.algorithm.iteration : map;\n        import std.format : format;\n        import std.range : iota;\n\n        10.iota\n        .map!(e => \"N: %d\".format(e))\n        .copy(stdout.lockingTextWriter()); // the OutputRange\n    }\n}\n\n/**\n    The standard error stream.\n\n    Returns:\n        stderr as a $(LREF File).\n\n    Note:\n        The returned $(LREF File) wraps $(REF stderr,core,stdio), and\n        is therefore thread global. Reassigning `stderr` to a different\n        `File` must be done in a single-threaded or locked context in\n        order to avoid race conditions.\n\n        All writing to `stderr` automatically locks the file globally,\n        and will cause all other threads calling `write` to wait until\n        the lock is released.\n*/\nalias stderr = makeGlobal!(StdFileHandle.stderr);\n\n///\n@safe unittest\n{\n    void main()\n    {\n        stderr.writeln(\"Write a message to stderr.\");\n    }\n}\n\n@system unittest\n{\n    static import std.file;\n    import std.typecons : tuple;\n\n    scope(failure) printf(\"Failed test at line %d\\n\", __LINE__);\n    auto deleteme = testFilename();\n\n    std.file.write(deleteme, \"1 2\\n4 1\\n5 100\");\n    scope(exit) std.file.remove(deleteme);\n    {\n        File f = File(deleteme);\n        scope(exit) f.close();\n        auto t = [ tuple(1, 2), tuple(4, 1), tuple(5, 100) ];\n        uint i;\n        foreach (e; f.byRecord!(int, int)(\"%s %s\"))\n        {\n            //writeln(e);\n            assert(e == t[i++]);\n        }\n        assert(i == 3);\n    }\n}\n\n@safe unittest\n{\n    // Retain backwards compatibility\n    // https://issues.dlang.org/show_bug.cgi?id=17472\n    static assert(is(typeof(stdin) == File));\n    static assert(is(typeof(stdout) == File));\n    static assert(is(typeof(stderr) == File));\n}\n\n// roll our own appender, but with \"safe\" arrays\nprivate struct ReadlnAppender\n{\n    char[] buf;\n    size_t pos;\n    bool safeAppend = false;\n\n    void initialize(char[] b)\n    {\n        buf = b;\n        pos = 0;\n    }\n    @property char[] data() @trusted\n    {\n        if (safeAppend)\n            assumeSafeAppend(buf.ptr[0 .. pos]);\n        return buf.ptr[0 .. pos];\n    }\n\n    bool reserveWithoutAllocating(size_t n)\n    {\n        if (buf.length >= pos + n) // buf is already large enough\n            return true;\n\n        immutable curCap = buf.capacity;\n        if (curCap >= pos + n)\n        {\n            buf.length = curCap;\n            /* Any extra capacity we end up not using can safely be claimed\n            by someone else. */\n            safeAppend = true;\n            return true;\n        }\n\n        return false;\n    }\n    void reserve(size_t n) @trusted\n    {\n        import core.stdc.string : memcpy;\n        if (!reserveWithoutAllocating(n))\n        {\n            size_t ncap = buf.length * 2 + 128 + n;\n            char[] nbuf = new char[ncap];\n            memcpy(nbuf.ptr, buf.ptr, pos);\n            buf = nbuf;\n            // Allocated a new buffer. No one else knows about it.\n            safeAppend = true;\n        }\n    }\n    void putchar(char c) @trusted\n    {\n        reserve(1);\n        buf.ptr[pos++] = c;\n    }\n    void putdchar(dchar dc) @trusted\n    {\n        import std.utf : encode, UseReplacementDchar;\n\n        char[4] ubuf;\n        immutable size = encode!(UseReplacementDchar.yes)(ubuf, dc);\n        reserve(size);\n        foreach (c; ubuf)\n            buf.ptr[pos++] = c;\n    }\n    void putonly(char[] b) @trusted\n    {\n        import core.stdc.string : memcpy;\n        assert(pos == 0);   // assume this is the only put call\n        if (reserveWithoutAllocating(b.length))\n            memcpy(buf.ptr + pos, b.ptr, b.length);\n        else\n            buf = b.dup;\n        pos = b.length;\n    }\n}\n\n// Private implementation of readln\nversion (DIGITAL_MARS_STDIO)\nprivate size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation /*ignored*/)\n{\n    FLOCK(fps);\n    scope(exit) FUNLOCK(fps);\n\n    /* Since fps is now locked, we can create an \"unshared\" version\n     * of fp.\n     */\n    auto fp = cast(_iobuf*) fps;\n\n    ReadlnAppender app;\n    app.initialize(buf);\n\n    if (__fhnd_info[fp._file] & FHND_WCHAR)\n    {   /* Stream is in wide characters.\n         * Read them and convert to chars.\n         */\n        static assert(wchar_t.sizeof == 2);\n        for (int c = void; (c = FGETWC(fp)) != -1; )\n        {\n            if ((c & ~0x7F) == 0)\n            {\n                app.putchar(cast(char) c);\n                if (c == terminator)\n                    break;\n            }\n            else\n            {\n                if (c >= 0xD800 && c <= 0xDBFF)\n                {\n                    int c2 = void;\n                    if ((c2 = FGETWC(fp)) != -1 ||\n                            c2 < 0xDC00 && c2 > 0xDFFF)\n                    {\n                        StdioException(\"unpaired UTF-16 surrogate\");\n                    }\n                    c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);\n                }\n                app.putdchar(cast(dchar) c);\n            }\n        }\n        if (ferror(fps))\n            StdioException();\n    }\n\n    else if (fp._flag & _IONBF)\n    {\n        /* Use this for unbuffered I/O, when running\n         * across buffer boundaries, or for any but the common\n         * cases.\n         */\n      L1:\n        int c;\n        while ((c = FGETC(fp)) != -1)\n        {\n            app.putchar(cast(char) c);\n            if (c == terminator)\n            {\n                buf = app.data;\n                return buf.length;\n            }\n\n        }\n\n        if (ferror(fps))\n            StdioException();\n    }\n    else\n    {\n        int u = fp._cnt;\n        char* p = fp._ptr;\n        int i;\n        if (fp._flag & _IOTRAN)\n        {   /* Translated mode ignores \\r and treats ^Z as end-of-file\n             */\n            char c;\n            while (1)\n            {\n                if (i == u)         // if end of buffer\n                    goto L1;        // give up\n                c = p[i];\n                i++;\n                if (c != '\\r')\n                {\n                    if (c == terminator)\n                        break;\n                    if (c != 0x1A)\n                        continue;\n                    goto L1;\n                }\n                else\n                {   if (i != u && p[i] == terminator)\n                        break;\n                    goto L1;\n                }\n            }\n            app.putonly(p[0 .. i]);\n            app.buf[i - 1] = cast(char) terminator;\n            if (terminator == '\\n' && c == '\\r')\n                i++;\n        }\n        else\n        {\n            while (1)\n            {\n                if (i == u)         // if end of buffer\n                    goto L1;        // give up\n                auto c = p[i];\n                i++;\n                if (c == terminator)\n                    break;\n            }\n            app.putonly(p[0 .. i]);\n        }\n        fp._cnt -= i;\n        fp._ptr += i;\n    }\n\n    buf = app.data;\n    return buf.length;\n}\n\nversion (MICROSOFT_STDIO)\nprivate size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation /*ignored*/)\n{\n    FLOCK(fps);\n    scope(exit) FUNLOCK(fps);\n\n    /* Since fps is now locked, we can create an \"unshared\" version\n     * of fp.\n     */\n    auto fp = cast(_iobuf*) fps;\n\n    ReadlnAppender app;\n    app.initialize(buf);\n\n    int c;\n    while ((c = FGETC(fp)) != -1)\n    {\n        app.putchar(cast(char) c);\n        if (c == terminator)\n        {\n            buf = app.data;\n            return buf.length;\n        }\n\n    }\n\n    if (ferror(fps))\n        StdioException();\n    buf = app.data;\n    return buf.length;\n}\n\nversion (HAS_GETDELIM)\nprivate size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)\n{\n    import core.stdc.stdlib : free;\n    import core.stdc.wchar_ : fwide;\n\n    if (orientation == File.Orientation.wide)\n    {\n        /* Stream is in wide characters.\n         * Read them and convert to chars.\n         */\n        FLOCK(fps);\n        scope(exit) FUNLOCK(fps);\n        auto fp = cast(_iobuf*) fps;\n        version (Windows)\n        {\n            buf.length = 0;\n            for (int c = void; (c = FGETWC(fp)) != -1; )\n            {\n                if ((c & ~0x7F) == 0)\n                {   buf ~= c;\n                    if (c == terminator)\n                        break;\n                }\n                else\n                {\n                    if (c >= 0xD800 && c <= 0xDBFF)\n                    {\n                        int c2 = void;\n                        if ((c2 = FGETWC(fp)) != -1 ||\n                                c2 < 0xDC00 && c2 > 0xDFFF)\n                        {\n                            StdioException(\"unpaired UTF-16 surrogate\");\n                        }\n                        c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);\n                    }\n                    import std.utf : encode;\n                    encode(buf, c);\n                }\n            }\n            if (ferror(fp))\n                StdioException();\n            return buf.length;\n        }\n        else version (Posix)\n        {\n            buf.length = 0;\n            for (int c; (c = FGETWC(fp)) != -1; )\n            {\n                import std.utf : encode;\n\n                if ((c & ~0x7F) == 0)\n                    buf ~= cast(char) c;\n                else\n                    encode(buf, cast(dchar) c);\n                if (c == terminator)\n                    break;\n            }\n            if (ferror(fps))\n                StdioException();\n            return buf.length;\n        }\n        else\n        {\n            static assert(0);\n        }\n    }\n\n    static char *lineptr = null;\n    static size_t n = 0;\n    scope(exit)\n    {\n        if (n > 128 * 1024)\n        {\n            // Bound memory used by readln\n            free(lineptr);\n            lineptr = null;\n            n = 0;\n        }\n    }\n\n    auto s = getdelim(&lineptr, &n, terminator, fps);\n    if (s < 0)\n    {\n        if (ferror(fps))\n            StdioException();\n        buf.length = 0;                // end of file\n        return 0;\n    }\n\n    if (s <= buf.length)\n    {\n        buf = buf[0 .. s];\n        buf[] = lineptr[0 .. s];\n    }\n    else\n    {\n        buf = lineptr[0 .. s].dup;\n    }\n    return s;\n}\n\nversion (NO_GETDELIM)\nprivate size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation)\n{\n    import core.stdc.wchar_ : fwide;\n\n    FLOCK(fps);\n    scope(exit) FUNLOCK(fps);\n    auto fp = cast(_iobuf*) fps;\n    if (orientation == File.Orientation.wide)\n    {\n        /* Stream is in wide characters.\n         * Read them and convert to chars.\n         */\n        version (Windows)\n        {\n            buf.length = 0;\n            for (int c; (c = FGETWC(fp)) != -1; )\n            {\n                if ((c & ~0x7F) == 0)\n                {   buf ~= c;\n                    if (c == terminator)\n                        break;\n                }\n                else\n                {\n                    if (c >= 0xD800 && c <= 0xDBFF)\n                    {\n                        int c2 = void;\n                        if ((c2 = FGETWC(fp)) != -1 ||\n                                c2 < 0xDC00 && c2 > 0xDFFF)\n                        {\n                            StdioException(\"unpaired UTF-16 surrogate\");\n                        }\n                        c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);\n                    }\n                    import std.utf : encode;\n                    encode(buf, c);\n                }\n            }\n            if (ferror(fp))\n                StdioException();\n            return buf.length;\n        }\n        else version (Posix)\n        {\n            import std.utf : encode;\n            buf.length = 0;\n            for (int c; (c = FGETWC(fp)) != -1; )\n            {\n                if ((c & ~0x7F) == 0)\n                    buf ~= cast(char) c;\n                else\n                    encode(buf, cast(dchar) c);\n                if (c == terminator)\n                    break;\n            }\n            if (ferror(fps))\n                StdioException();\n            return buf.length;\n        }\n        else\n        {\n            static assert(0);\n        }\n    }\n\n    // Narrow stream\n    // First, fill the existing buffer\n    for (size_t bufPos = 0; bufPos < buf.length; )\n    {\n        immutable c = FGETC(fp);\n        if (c == -1)\n        {\n            buf.length = bufPos;\n            goto endGame;\n        }\n        buf[bufPos++] = cast(char) c;\n        if (c == terminator)\n        {\n            // No need to test for errors in file\n            buf.length = bufPos;\n            return bufPos;\n        }\n    }\n    // Then, append to it\n    for (int c; (c = FGETC(fp)) != -1; )\n    {\n        buf ~= cast(char) c;\n        if (c == terminator)\n        {\n            // No need to test for errors in file\n            return buf.length;\n        }\n    }\n\n  endGame:\n    if (ferror(fps))\n        StdioException();\n    return buf.length;\n}\n\n@system unittest\n{\n    static import std.file;\n    auto deleteme = testFilename();\n    scope(exit) std.file.remove(deleteme);\n\n    std.file.write(deleteme, \"abcd\\n0123456789abcde\\n1234\\n\");\n    File f = File(deleteme, \"rb\");\n\n    char[] ln = new char[2];\n    f.readln(ln);\n\n    assert(ln == \"abcd\\n\");\n    char[] t = ln[0 .. 2];\n    t ~= 't';\n    assert(t == \"abt\");\n    assert(ln == \"abcd\\n\");  // bug 13856: ln stomped to \"abtd\"\n\n    // it can also stomp the array length\n    ln = new char[4];\n    f.readln(ln);\n    assert(ln == \"0123456789abcde\\n\");\n\n    char[100] buf;\n    ln = buf[];\n    f.readln(ln);\n    assert(ln == \"1234\\n\");\n    assert(ln.ptr == buf.ptr); // avoid allocation, buffer is good enough\n}\n\n/** Experimental network access via the File interface\n\n        Opens a TCP connection to the given host and port, then returns\n        a File struct with read and write access through the same interface\n        as any other file (meaning writef and the byLine ranges work!).\n\n        Authors:\n                Adam D. Ruppe\n\n        Bugs:\n                Only works on Linux\n*/\nversion (linux)\n{\n    File openNetwork(string host, ushort port)\n    {\n        import core.stdc.string : memcpy;\n        import core.sys.posix.arpa.inet : htons;\n        import core.sys.posix.netdb : gethostbyname;\n        import core.sys.posix.netinet.in_ : sockaddr_in;\n        static import core.sys.posix.unistd;\n        static import sock = core.sys.posix.sys.socket;\n        import std.conv : to;\n        import std.exception : enforce;\n        import std.internal.cstring : tempCString;\n\n        auto h = enforce( gethostbyname(host.tempCString()),\n            new StdioException(\"gethostbyname\"));\n\n        int s = sock.socket(sock.AF_INET, sock.SOCK_STREAM, 0);\n        enforce(s != -1, new StdioException(\"socket\"));\n\n        scope(failure)\n        {\n            // want to make sure it doesn't dangle if something throws. Upon\n            // normal exit, the File struct's reference counting takes care of\n            // closing, so we don't need to worry about success\n            core.sys.posix.unistd.close(s);\n        }\n\n        sockaddr_in addr;\n\n        addr.sin_family = sock.AF_INET;\n        addr.sin_port = htons(port);\n        memcpy(&addr.sin_addr.s_addr, h.h_addr, h.h_length);\n\n        enforce(sock.connect(s, cast(sock.sockaddr*) &addr, addr.sizeof) != -1,\n            new StdioException(\"Connect failed\"));\n\n        File f;\n        f.fdopen(s, \"w+\", host ~ \":\" ~ to!string(port));\n        return f;\n    }\n}\n\nversion (unittest) private string testFilename(string file = __FILE__, size_t line = __LINE__) @safe\n{\n    import std.conv : text;\n    import std.file : deleteme;\n    import std.path : baseName;\n\n    // filename intentionally contains non-ASCII (Russian) characters for test Issue 7648\n    return text(deleteme, \"-детка.\", baseName(file), \".\", line);\n}\n"
  },
  {
    "path": "libphobos/src/std/string.d",
    "content": "// Written in the D programming language.\n\n/**\nString handling functions.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n\n$(DIVC quickindex,\n$(BOOKTABLE ,\n$(TR $(TH Category) $(TH Functions) )\n$(TR $(TDNW Searching)\n    $(TD\n         $(MYREF column)\n         $(MYREF indexOf)\n         $(MYREF indexOfAny)\n         $(MYREF indexOfNeither)\n         $(MYREF lastIndexOf)\n         $(MYREF lastIndexOfAny)\n         $(MYREF lastIndexOfNeither)\n    )\n)\n$(TR $(TDNW Comparison)\n    $(TD\n         $(MYREF isNumeric)\n    )\n)\n$(TR $(TDNW Mutation)\n    $(TD\n         $(MYREF capitalize)\n    )\n)\n$(TR $(TDNW Pruning and Filling)\n    $(TD\n         $(MYREF center)\n         $(MYREF chomp)\n         $(MYREF chompPrefix)\n         $(MYREF chop)\n         $(MYREF detabber)\n         $(MYREF detab)\n         $(MYREF entab)\n         $(MYREF entabber)\n         $(MYREF leftJustify)\n         $(MYREF outdent)\n         $(MYREF rightJustify)\n         $(MYREF strip)\n         $(MYREF stripLeft)\n         $(MYREF stripRight)\n         $(MYREF wrap)\n    )\n)\n$(TR $(TDNW Substitution)\n    $(TD\n         $(MYREF abbrev)\n         $(MYREF soundex)\n         $(MYREF soundexer)\n         $(MYREF succ)\n         $(MYREF tr)\n         $(MYREF translate)\n    )\n)\n$(TR $(TDNW Miscellaneous)\n    $(TD\n         $(MYREF assumeUTF)\n         $(MYREF fromStringz)\n         $(MYREF lineSplitter)\n         $(MYREF representation)\n         $(MYREF splitLines)\n         $(MYREF toStringz)\n    )\n)))\n\nObjects of types `string`, `wstring`, and `dstring` are value types\nand cannot be mutated element-by-element. For using mutation during building\nstrings, use `char[]`, `wchar[]`, or `dchar[]`. The `xxxstring`\ntypes are preferable because they don't exhibit undesired aliasing, thus\nmaking code more robust.\n\nThe following functions are publicly imported:\n\n$(BOOKTABLE ,\n$(TR $(TH Module) $(TH Functions) )\n$(LEADINGROW Publicly imported functions)\n    $(TR $(TD std.algorithm)\n        $(TD\n         $(REF_SHORT cmp, std,algorithm,comparison)\n         $(REF_SHORT count, std,algorithm,searching)\n         $(REF_SHORT endsWith, std,algorithm,searching)\n         $(REF_SHORT startsWith, std,algorithm,searching)\n    ))\n    $(TR $(TD std.array)\n        $(TD\n         $(REF_SHORT join, std,array)\n         $(REF_SHORT replace, std,array)\n         $(REF_SHORT replaceInPlace, std,array)\n         $(REF_SHORT split, std,array)\n         $(REF_SHORT empty, std,array)\n    ))\n    $(TR $(TD std.format)\n        $(TD\n         $(REF_SHORT format, std,format)\n         $(REF_SHORT sformat, std,format)\n    ))\n    $(TR $(TD std.uni)\n        $(TD\n         $(REF_SHORT icmp, std,uni)\n         $(REF_SHORT toLower, std,uni)\n         $(REF_SHORT toLowerInPlace, std,uni)\n         $(REF_SHORT toUpper, std,uni)\n         $(REF_SHORT toUpperInPlace, std,uni)\n    ))\n)\n\nThere is a rich set of functions for string handling defined in other modules.\nFunctions related to Unicode and ASCII are found in $(MREF std, uni)\nand $(MREF std, ascii), respectively. Other functions that have a\nwider generality than just strings can be found in $(MREF std, algorithm)\nand $(MREF std, range).\n\nSee_Also:\n    $(LIST\n    $(MREF std, algorithm) and\n    $(MREF std, range)\n    for generic range algorithms\n    ,\n    $(MREF std, ascii)\n    for functions that work with ASCII strings\n    ,\n    $(MREF std, uni)\n    for functions that work with unicode strings\n    )\n\nCopyright: Copyright The D Language Foundation 2007-.\n\nLicense: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\nAuthors: $(HTTP digitalmars.com, Walter Bright),\n         $(HTTP erdani.org, Andrei Alexandrescu),\n         $(HTTP jmdavisprog.com, Jonathan M Davis),\n         and David L. 'SpottedTiger' Davis\n\nSource:    $(PHOBOSSRC std/string.d)\n\n*/\nmodule std.string;\n\nversion (unittest)\n{\nprivate:\n    struct TestAliasedString\n    {\n        string get() @safe @nogc pure nothrow { return _s; }\n        alias get this;\n        @disable this(this);\n        string _s;\n    }\n\n    bool testAliasedString(alias func, Args...)(string s, Args args)\n    {\n        import std.algorithm.comparison : equal;\n        auto a = func(TestAliasedString(s), args);\n        auto b = func(s, args);\n        static if (is(typeof(equal(a, b))))\n        {\n            // For ranges, compare contents instead of object identity.\n            return equal(a, b);\n        }\n        else\n        {\n            return a == b;\n        }\n    }\n}\n\npublic import std.format : format, sformat;\nimport std.typecons : Flag, Yes, No;\npublic import std.uni : icmp, toLower, toLowerInPlace, toUpper, toUpperInPlace;\n\nimport std.meta; // AliasSeq, staticIndexOf\nimport std.range.primitives; // back, ElementEncodingType, ElementType, front,\n    // hasLength, hasSlicing, isBidirectionalRange, isForwardRange, isInfinite,\n    // isInputRange, isOutputRange, isRandomAccessRange, popBack, popFront, put,\n    // save;\nimport std.traits; // isConvertibleToString, isNarrowString, isSomeChar,\n    // isSomeString, StringTypeOf, Unqual\n\n//public imports for backward compatibility\npublic import std.algorithm.comparison : cmp;\npublic import std.algorithm.searching : startsWith, endsWith, count;\npublic import std.array : join, replace, replaceInPlace, split, empty;\n\n/* ************* Exceptions *************** */\n\n/++\n    Exception thrown on errors in std.string functions.\n  +/\nclass StringException : Exception\n{\n    import std.exception : basicExceptionCtors;\n\n    ///\n    mixin basicExceptionCtors;\n}\n\n///\n@safe pure unittest\n{\n    import std.exception : assertThrown;\n    auto bad = \"      a\\n\\tb\\n   c\";\n    assertThrown!StringException(bad.outdent);\n}\n\n/++\n    Params:\n        cString = A null-terminated c-style string.\n\n    Returns: A D-style array of `char`, `wchar` or `dchar` referencing the same\n    string. The returned array will retain the same type qualifiers as the input.\n\n    $(RED Important Note:) The returned array is a slice of the original buffer.\n    The original data is not changed and not copied.\n+/\nChar[] fromStringz(Char)(Char* cString) @nogc @system pure nothrow\nif (isSomeChar!Char)\n{\n    import core.stdc.stddef : wchar_t;\n\n    static if (is(Unqual!Char == char))\n        import core.stdc.string : cstrlen = strlen;\n    else static if (is(Unqual!Char == wchar_t))\n        import core.stdc.wchar_ : cstrlen = wcslen;\n    else\n        static size_t cstrlen(const Char* s)\n        {\n            const(Char)* p = s;\n            while (*p)\n                ++p;\n            return p - s;\n        }\n\n    return cString ? cString[0 .. cstrlen(cString)] : null;\n}\n\n///\n@system pure unittest\n{\n    assert(fromStringz(\"foo\\0\"c.ptr) == \"foo\"c);\n    assert(fromStringz(\"foo\\0\"w.ptr) == \"foo\"w);\n    assert(fromStringz(\"foo\\0\"d.ptr) == \"foo\"d);\n\n    assert(fromStringz(\"福\\0\"c.ptr) == \"福\"c);\n    assert(fromStringz(\"福\\0\"w.ptr) == \"福\"w);\n    assert(fromStringz(\"福\\0\"d.ptr) == \"福\"d);\n}\n\n@system pure unittest\n{\n    char* a = null;\n    assert(fromStringz(a) == null);\n    wchar* b = null;\n    assert(fromStringz(b) == null);\n    dchar* c = null;\n    assert(fromStringz(c) == null);\n\n    const char* d = \"foo\\0\";\n    assert(fromStringz(d) == \"foo\");\n\n    immutable char* e = \"foo\\0\";\n    assert(fromStringz(e) == \"foo\");\n\n    const wchar* f = \"foo\\0\";\n    assert(fromStringz(f) == \"foo\");\n\n    immutable wchar* g = \"foo\\0\";\n    assert(fromStringz(g) == \"foo\");\n\n    const dchar* h = \"foo\\0\";\n    assert(fromStringz(h) == \"foo\");\n\n    immutable dchar* i = \"foo\\0\";\n    assert(fromStringz(i) == \"foo\");\n\n    immutable wchar z = 0x0000;\n    // Test some surrogate pairs\n    // high surrogates are in the range 0xD800 .. 0xDC00\n    // low surrogates are in the range  0xDC00 .. 0xE000\n    // since UTF16 doesn't specify endianness we test both.\n    foreach (wchar[] t; [[0xD800, 0xDC00], [0xD800, 0xE000], [0xDC00, 0xDC00],\n            [0xDC00, 0xE000], [0xDA00, 0xDE00]])\n    {\n        immutable hi = t[0], lo = t[1];\n        assert(fromStringz([hi, lo, z].ptr) == [hi, lo]);\n        assert(fromStringz([lo, hi, z].ptr) == [lo, hi]);\n    }\n}\n\n/++\n    Params:\n        s = A D-style string.\n\n    Returns: A C-style null-terminated string equivalent to `s`. `s`\n    must not contain embedded `'\\0'`'s as any C function will treat the\n    first `'\\0'` that it sees as the end of the string. If `s.empty` is\n    `true`, then a string containing only `'\\0'` is returned.\n\n    $(RED Important Note:) When passing a `char*` to a C function, and the C\n    function keeps it around for any reason, make sure that you keep a\n    reference to it in your D code. Otherwise, it may become invalid during a\n    garbage collection cycle and cause a nasty bug when the C code tries to use\n    it.\n  +/\nimmutable(char)* toStringz(scope const(char)[] s) @trusted pure nothrow\nout (result)\n{\n    import core.stdc.string : strlen, memcmp;\n    if (result)\n    {\n        auto slen = s.length;\n        while (slen > 0 && s[slen-1] == 0) --slen;\n        assert(strlen(result) == slen);\n        assert(result[0 .. slen] == s[0 .. slen]);\n    }\n}\ndo\n{\n    import std.exception : assumeUnique;\n    /+ Unfortunately, this isn't reliable.\n     We could make this work if string literals are put\n     in read-only memory and we test if s[] is pointing into\n     that.\n\n     /* Peek past end of s[], if it's 0, no conversion necessary.\n     * Note that the compiler will put a 0 past the end of static\n     * strings, and the storage allocator will put a 0 past the end\n     * of newly allocated char[]'s.\n     */\n     char* p = &s[0] + s.length;\n     if (*p == 0)\n     return s;\n     +/\n\n    // Need to make a copy\n    auto copy = new char[s.length + 1];\n    copy[0 .. s.length] = s[];\n    copy[s.length] = 0;\n\n    return &assumeUnique(copy)[0];\n}\n\n/++ Ditto +/\nimmutable(char)* toStringz(return scope string s) @trusted pure nothrow\n{\n    if (s.empty) return \"\".ptr;\n    /* Peek past end of s[], if it's 0, no conversion necessary.\n     * Note that the compiler will put a 0 past the end of static\n     * strings, and the storage allocator will put a 0 past the end\n     * of newly allocated char[]'s.\n     */\n    immutable p = s.ptr + s.length;\n    // Is p dereferenceable? A simple test: if the p points to an\n    // address multiple of 4, then conservatively assume the pointer\n    // might be pointing to a new block of memory, which might be\n    // unreadable. Otherwise, it's definitely pointing to valid\n    // memory.\n    if ((cast(size_t) p & 3) && *p == 0)\n        return &s[0];\n    return toStringz(cast(const char[]) s);\n}\n\n///\npure nothrow @system unittest\n{\n    import core.stdc.string : strlen;\n    import std.conv : to;\n\n    auto p = toStringz(\"foo\");\n    assert(strlen(p) == 3);\n    const(char)[] foo = \"abbzxyzzy\";\n    p = toStringz(foo[3 .. 5]);\n    assert(strlen(p) == 2);\n\n    string test = \"\";\n    p = toStringz(test);\n    assert(*p == 0);\n\n    test = \"\\0\";\n    p = toStringz(test);\n    assert(*p == 0);\n\n    test = \"foo\\0\";\n    p = toStringz(test);\n    assert(p[0] == 'f' && p[1] == 'o' && p[2] == 'o' && p[3] == 0);\n\n    const string test2 = \"\";\n    p = toStringz(test2);\n    assert(*p == 0);\n}\n\n\n/**\n   Flag indicating whether a search is case-sensitive.\n*/\nalias CaseSensitive = Flag!\"caseSensitive\";\n\n/++\n    Searches for character in range.\n\n    Params:\n        s = string or InputRange of characters to search in correct UTF format\n        c = character to search for\n        startIdx = starting index to a well-formed code point\n        cs = `Yes.caseSensitive` or `No.caseSensitive`\n\n    Returns:\n        the index of the first occurrence of `c` in `s` with\n        respect to the start index `startIdx`. If `c`\n        is not found, then `-1` is returned.\n        If `c` is found the value of the returned index is at least\n        `startIdx`.\n        If the parameters are not valid UTF, the result will still\n        be in the range [-1 .. s.length], but will not be reliable otherwise.\n\n    Throws:\n        If the sequence starting at `startIdx` does not represent a well\n        formed codepoint, then a $(REF UTFException, std,utf) may be thrown.\n\n    See_Also: $(REF countUntil, std,algorithm,searching)\n  +/\nptrdiff_t indexOf(Range)(Range s, dchar c, CaseSensitive cs = Yes.caseSensitive)\nif (isInputRange!Range && isSomeChar!(ElementType!Range) && !isSomeString!Range)\n{\n    return _indexOf(s, c, cs);\n}\n\n/// Ditto\nptrdiff_t indexOf(C)(C[] s, dchar c, CaseSensitive cs = Yes.caseSensitive)\nif (isSomeChar!C)\n{\n    return _indexOf(s, c, cs);\n}\n\n/// Ditto\nptrdiff_t indexOf(Range)(Range s, dchar c, size_t startIdx, CaseSensitive cs = Yes.caseSensitive)\nif (isInputRange!Range && isSomeChar!(ElementType!Range) && !isSomeString!Range)\n{\n    return _indexOf(s, c, startIdx, cs);\n}\n\n/// Ditto\nptrdiff_t indexOf(C)(C[] s, dchar c, size_t startIdx, CaseSensitive cs = Yes.caseSensitive)\nif (isSomeChar!C)\n{\n    return _indexOf(s, c, startIdx, cs);\n}\n\n///\n@safe pure unittest\n{\n    import std.typecons : No;\n\n    string s = \"Hello World\";\n    assert(indexOf(s, 'W') == 6);\n    assert(indexOf(s, 'Z') == -1);\n    assert(indexOf(s, 'w', No.caseSensitive) == 6);\n}\n\n///\n@safe pure unittest\n{\n    import std.typecons : No;\n\n    string s = \"Hello World\";\n    assert(indexOf(s, 'W', 4) == 6);\n    assert(indexOf(s, 'Z', 100) == -1);\n    assert(indexOf(s, 'w', 3, No.caseSensitive) == 6);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!indexOf(\"std/string.d\", '/'));\n\n    enum S : string { a = \"std/string.d\" }\n    assert(S.a.indexOf('/') == 3);\n\n    char[S.a.length] sa = S.a[];\n    assert(sa.indexOf('/') == 3);\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n    import std.traits : EnumMembers;\n    import std.utf : byChar, byWchar, byDchar;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        assert(indexOf(cast(S) null, cast(dchar)'a') == -1);\n        assert(indexOf(to!S(\"def\"), cast(dchar)'a') == -1);\n        assert(indexOf(to!S(\"abba\"), cast(dchar)'a') == 0);\n        assert(indexOf(to!S(\"def\"), cast(dchar)'f') == 2);\n\n        assert(indexOf(to!S(\"def\"), cast(dchar)'a', No.caseSensitive) == -1);\n        assert(indexOf(to!S(\"def\"), cast(dchar)'a', No.caseSensitive) == -1);\n        assert(indexOf(to!S(\"Abba\"), cast(dchar)'a', No.caseSensitive) == 0);\n        assert(indexOf(to!S(\"def\"), cast(dchar)'F', No.caseSensitive) == 2);\n        assert(indexOf(to!S(\"ödef\"), 'ö', No.caseSensitive) == 0);\n\n        S sPlts = \"Mars: the fourth Rock (Planet) from the Sun.\";\n        assert(indexOf(\"def\", cast(char)'f', No.caseSensitive) == 2);\n        assert(indexOf(sPlts, cast(char)'P', No.caseSensitive) == 23);\n        assert(indexOf(sPlts, cast(char)'R', No.caseSensitive) == 2);\n    }}\n\n    foreach (cs; EnumMembers!CaseSensitive)\n    {\n        assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\", '\\u0100', cs) == 9);\n        assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\"w, '\\u0100', cs) == 7);\n        assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\"d, '\\u0100', cs) == 6);\n\n        assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\".byChar, '\\u0100', cs) == 9);\n        assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\".byWchar, '\\u0100', cs) == 7);\n        assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\".byDchar, '\\u0100', cs) == 6);\n\n        assert(indexOf(\"hello\\U000007FF\\u0100\\U00010143\".byChar, 'l',      cs) == 2);\n        assert(indexOf(\"hello\\U000007FF\\u0100\\U00010143\".byChar, '\\u0100', cs) == 7);\n        assert(indexOf(\"hello\\U0000EFFF\\u0100\\U00010143\".byChar, '\\u0100', cs) == 8);\n\n        assert(indexOf(\"hello\\U00010100\".byWchar, '\\U00010100', cs) == 5);\n        assert(indexOf(\"hello\\U00010100\".byWchar, '\\U00010101', cs) == -1);\n    }\n\n    char[10] fixedSizeArray = \"0123456789\";\n    assert(indexOf(fixedSizeArray, '2') == 2);\n    });\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!indexOf(\"std/string.d\", '/', 0));\n    assert(testAliasedString!indexOf(\"std/string.d\", '/', 1));\n    assert(testAliasedString!indexOf(\"std/string.d\", '/', 4));\n\n    enum S : string { a = \"std/string.d\" }\n    assert(S.a.indexOf('/', 0) == 3);\n    assert(S.a.indexOf('/', 1) == 3);\n    assert(S.a.indexOf('/', 4) == -1);\n\n    char[S.a.length] sa = S.a[];\n    assert(sa.indexOf('/', 0) == 3);\n    assert(sa.indexOf('/', 1) == 3);\n    assert(sa.indexOf('/', 4) == -1);\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.traits : EnumMembers;\n    import std.utf : byCodeUnit, byChar, byWchar;\n\n    assert(\"hello\".byCodeUnit.indexOf(cast(dchar)'l', 1) == 2);\n    assert(\"hello\".byWchar.indexOf(cast(dchar)'l', 1) == 2);\n    assert(\"hello\".byWchar.indexOf(cast(dchar)'l', 6) == -1);\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        assert(indexOf(cast(S) null, cast(dchar)'a', 1) == -1);\n        assert(indexOf(to!S(\"def\"), cast(dchar)'a', 1) == -1);\n        assert(indexOf(to!S(\"abba\"), cast(dchar)'a', 1) == 3);\n        assert(indexOf(to!S(\"def\"), cast(dchar)'f', 1) == 2);\n\n        assert((to!S(\"def\")).indexOf(cast(dchar)'a', 1,\n                No.caseSensitive) == -1);\n        assert(indexOf(to!S(\"def\"), cast(dchar)'a', 1,\n                No.caseSensitive) == -1);\n        assert(indexOf(to!S(\"def\"), cast(dchar)'a', 12,\n                No.caseSensitive) == -1);\n        assert(indexOf(to!S(\"AbbA\"), cast(dchar)'a', 2,\n                No.caseSensitive) == 3);\n        assert(indexOf(to!S(\"def\"), cast(dchar)'F', 2, No.caseSensitive) == 2);\n\n        S sPlts = \"Mars: the fourth Rock (Planet) from the Sun.\";\n        assert(indexOf(\"def\", cast(char)'f', cast(uint) 2,\n            No.caseSensitive) == 2);\n        assert(indexOf(sPlts, cast(char)'P', 12, No.caseSensitive) == 23);\n        assert(indexOf(sPlts, cast(char)'R', cast(ulong) 1,\n            No.caseSensitive) == 2);\n    }}\n\n    foreach (cs; EnumMembers!CaseSensitive)\n    {\n        assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\", '\\u0100', 2, cs)\n            == 9);\n        assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\"w, '\\u0100', 3, cs)\n            == 7);\n        assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\"d, '\\u0100', 6, cs)\n            == 6);\n    }\n}\n\nprivate ptrdiff_t _indexOf(Range)(Range s, dchar c, CaseSensitive cs = Yes.caseSensitive)\nif (isInputRange!Range && isSomeChar!(ElementType!Range))\n{\n    static import std.ascii;\n    static import std.uni;\n    import std.utf : byDchar, byCodeUnit, UTFException, codeLength;\n    alias Char = Unqual!(ElementEncodingType!Range);\n\n    if (cs == Yes.caseSensitive)\n    {\n        static if (Char.sizeof == 1 && isSomeString!Range)\n        {\n            if (std.ascii.isASCII(c) && !__ctfe)\n            {                                               // Plain old ASCII\n                static ptrdiff_t trustedmemchr(Range s, char c) @trusted\n                {\n                    import core.stdc.string : memchr;\n                    const p = cast(const(Char)*)memchr(s.ptr, c, s.length);\n                    return p ? p - s.ptr : -1;\n                }\n\n                return trustedmemchr(s, cast(char) c);\n            }\n        }\n\n        static if (Char.sizeof == 1)\n        {\n            if (c <= 0x7F)\n            {\n                ptrdiff_t i;\n                foreach (const c2; s)\n                {\n                    if (c == c2)\n                        return i;\n                    ++i;\n                }\n            }\n            else\n            {\n                ptrdiff_t i;\n                foreach (const c2; s.byDchar())\n                {\n                    if (c == c2)\n                        return i;\n                    i += codeLength!Char(c2);\n                }\n            }\n        }\n        else static if (Char.sizeof == 2)\n        {\n            if (c <= 0xFFFF)\n            {\n                ptrdiff_t i;\n                foreach (const c2; s)\n                {\n                    if (c == c2)\n                        return i;\n                    ++i;\n                }\n            }\n            else if (c <= 0x10FFFF)\n            {\n                // Encode UTF-16 surrogate pair\n                const wchar c1 = cast(wchar)((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);\n                const wchar c2 = cast(wchar)(((c - 0x10000) & 0x3FF) + 0xDC00);\n                ptrdiff_t i;\n                for (auto r = s.byCodeUnit(); !r.empty; r.popFront())\n                {\n                    if (c1 == r.front)\n                    {\n                        r.popFront();\n                        if (r.empty)    // invalid UTF - missing second of pair\n                            break;\n                        if (c2 == r.front)\n                            return i;\n                        ++i;\n                    }\n                    ++i;\n                }\n            }\n        }\n        else static if (Char.sizeof == 4)\n        {\n            ptrdiff_t i;\n            foreach (const c2; s)\n            {\n                if (c == c2)\n                    return i;\n                ++i;\n            }\n        }\n        else\n            static assert(0);\n        return -1;\n    }\n    else\n    {\n        if (std.ascii.isASCII(c))\n        {                                                   // Plain old ASCII\n            immutable c1 = cast(char) std.ascii.toLower(c);\n\n            ptrdiff_t i;\n            foreach (const c2; s.byCodeUnit())\n            {\n                if (c1 == std.ascii.toLower(c2))\n                    return i;\n                ++i;\n            }\n        }\n        else\n        {                                                   // c is a universal character\n            immutable c1 = std.uni.toLower(c);\n\n            ptrdiff_t i;\n            foreach (const c2; s.byDchar())\n            {\n                if (c1 == std.uni.toLower(c2))\n                    return i;\n                i += codeLength!Char(c2);\n            }\n        }\n    }\n    return -1;\n}\n\nprivate ptrdiff_t _indexOf(Range)(Range s, dchar c, size_t startIdx, CaseSensitive cs = Yes.caseSensitive)\nif (isInputRange!Range && isSomeChar!(ElementType!Range))\n{\n    static if (isSomeString!(typeof(s)) ||\n                (hasSlicing!(typeof(s)) && hasLength!(typeof(s))))\n    {\n        if (startIdx < s.length)\n        {\n            ptrdiff_t foundIdx = indexOf(s[startIdx .. $], c, cs);\n            if (foundIdx != -1)\n            {\n                return foundIdx + cast(ptrdiff_t) startIdx;\n            }\n        }\n    }\n    else\n    {\n        foreach (i; 0 .. startIdx)\n        {\n            if (s.empty)\n                return -1;\n            s.popFront();\n        }\n        ptrdiff_t foundIdx = indexOf(s, c, cs);\n        if (foundIdx != -1)\n        {\n            return foundIdx + cast(ptrdiff_t) startIdx;\n        }\n    }\n    return -1;\n}\n\n/++\n    Searches for substring in `s`.\n\n    Params:\n        s = string or ForwardRange of characters to search in correct UTF format\n        sub = substring to search for\n        startIdx = the index into s to start searching from\n        cs = `Yes.caseSensitive` or `No.caseSensitive`\n\n    Returns:\n        the index of the first occurrence of `sub` in `s` with\n        respect to the start index `startIdx`. If `sub` is not found,\n        then `-1` is returned.\n        If the arguments are not valid UTF, the result will still\n        be in the range [-1 .. s.length], but will not be reliable otherwise.\n        If `sub` is found the value of the returned index is at least\n        `startIdx`.\n\n    Throws:\n        If the sequence starting at `startIdx` does not represent a well\n        formed codepoint, then a $(REF UTFException, std,utf) may be thrown.\n\n    Bugs:\n        Does not work with case insensitive strings where the mapping of\n        tolower and toupper is not 1:1.\n  +/\nptrdiff_t indexOf(Range, Char)(Range s, const(Char)[] sub,\n        in CaseSensitive cs = Yes.caseSensitive)\nif (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) &&\n    isSomeChar!Char)\n{\n    alias Char1 = Unqual!(ElementEncodingType!Range);\n\n    static if (isSomeString!Range)\n    {\n        import std.algorithm.searching : find;\n\n        const(Char1)[] balance;\n        if (cs == Yes.caseSensitive)\n        {\n            balance = find(s, sub);\n        }\n        else\n        {\n            balance = find!\n                ((a, b) => toLower(a) == toLower(b))\n                (s, sub);\n        }\n        return () @trusted { return balance.empty ? -1 : balance.ptr - s.ptr; } ();\n    }\n    else\n    {\n        if (s.empty)\n            return -1;\n        if (sub.empty)\n            return 0;                   // degenerate case\n\n        import std.utf : byDchar, codeLength;\n        auto subr = sub.byDchar;        // decode sub[] by dchar's\n        dchar sub0 = subr.front;        // cache first character of sub[]\n        subr.popFront();\n\n        // Special case for single character search\n        if (subr.empty)\n            return indexOf(s, sub0, cs);\n\n        if (cs == No.caseSensitive)\n            sub0 = toLower(sub0);\n\n        /* Classic double nested loop search algorithm\n         */\n        ptrdiff_t index = 0;            // count code unit index into s\n        for (auto sbydchar = s.byDchar(); !sbydchar.empty; sbydchar.popFront())\n        {\n            dchar c2 = sbydchar.front;\n            if (cs == No.caseSensitive)\n                c2 = toLower(c2);\n            if (c2 == sub0)\n            {\n                auto s2 = sbydchar.save;        // why s must be a forward range\n                foreach (c; subr.save)\n                {\n                    s2.popFront();\n                    if (s2.empty)\n                        return -1;\n                    if (cs == Yes.caseSensitive ? c != s2.front\n                                                : toLower(c) != toLower(s2.front)\n                       )\n                        goto Lnext;\n                }\n                return index;\n            }\n          Lnext:\n            index += codeLength!Char1(c2);\n        }\n        return -1;\n    }\n}\n\n/// Ditto\nptrdiff_t indexOf(Char1, Char2)(const(Char1)[] s, const(Char2)[] sub,\n        in size_t startIdx, in CaseSensitive cs = Yes.caseSensitive)\n@safe\nif (isSomeChar!Char1 && isSomeChar!Char2)\n{\n    if (startIdx < s.length)\n    {\n        ptrdiff_t foundIdx = indexOf(s[startIdx .. $], sub, cs);\n        if (foundIdx != -1)\n        {\n            return foundIdx + cast(ptrdiff_t) startIdx;\n        }\n    }\n    return -1;\n}\n\n///\n@safe pure unittest\n{\n    import std.typecons : No;\n\n    string s = \"Hello World\";\n    assert(indexOf(s, \"Wo\", 4) == 6);\n    assert(indexOf(s, \"Zo\", 100) == -1);\n    assert(indexOf(s, \"wo\", 3, No.caseSensitive) == 6);\n}\n\n///\n@safe pure unittest\n{\n    import std.typecons : No;\n\n    string s = \"Hello World\";\n    assert(indexOf(s, \"Wo\") == 6);\n    assert(indexOf(s, \"Zo\") == -1);\n    assert(indexOf(s, \"wO\", No.caseSensitive) == 6);\n}\n\nptrdiff_t indexOf(Range, Char)(auto ref Range s, const(Char)[] sub,\n        in CaseSensitive cs = Yes.caseSensitive)\nif (!(isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) &&\n    isSomeChar!Char) &&\n    is(StringTypeOf!Range))\n{\n    return indexOf!(StringTypeOf!Range)(s, sub, cs);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!indexOf(\"std/string.d\", \"string\"));\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n    import std.traits : EnumMembers;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {{\n            assert(indexOf(cast(S) null, to!T(\"a\")) == -1);\n            assert(indexOf(to!S(\"def\"), to!T(\"a\")) == -1);\n            assert(indexOf(to!S(\"abba\"), to!T(\"a\")) == 0);\n            assert(indexOf(to!S(\"def\"), to!T(\"f\")) == 2);\n            assert(indexOf(to!S(\"dfefffg\"), to!T(\"fff\")) == 3);\n            assert(indexOf(to!S(\"dfeffgfff\"), to!T(\"fff\")) == 6);\n\n            assert(indexOf(to!S(\"dfeffgfff\"), to!T(\"a\"), No.caseSensitive) == -1);\n            assert(indexOf(to!S(\"def\"), to!T(\"a\"), No.caseSensitive) == -1);\n            assert(indexOf(to!S(\"abba\"), to!T(\"a\"), No.caseSensitive) == 0);\n            assert(indexOf(to!S(\"def\"), to!T(\"f\"), No.caseSensitive) == 2);\n            assert(indexOf(to!S(\"dfefffg\"), to!T(\"fff\"), No.caseSensitive) == 3);\n            assert(indexOf(to!S(\"dfeffgfff\"), to!T(\"fff\"), No.caseSensitive) == 6);\n\n            S sPlts = \"Mars: the fourth Rock (Planet) from the Sun.\";\n            S sMars = \"Who\\'s \\'My Favorite Maritian?\\'\";\n\n            assert(indexOf(sMars, to!T(\"MY fAVe\"), No.caseSensitive) == -1);\n            assert(indexOf(sMars, to!T(\"mY fAVOriTe\"), No.caseSensitive) == 7);\n            assert(indexOf(sPlts, to!T(\"mArS:\"), No.caseSensitive) == 0);\n            assert(indexOf(sPlts, to!T(\"rOcK\"), No.caseSensitive) == 17);\n            assert(indexOf(sPlts, to!T(\"Un.\"), No.caseSensitive) == 41);\n            assert(indexOf(sPlts, to!T(sPlts), No.caseSensitive) == 0);\n\n            assert(indexOf(\"\\u0100\", to!T(\"\\u0100\"), No.caseSensitive) == 0);\n\n            // Thanks to Carlos Santander B. and zwang\n            assert(indexOf(\"sus mejores cortesanos. Se embarcaron en el puerto de Dubai y\",\n                           to!T(\"page-break-before\"), No.caseSensitive) == -1);\n        }}\n\n        foreach (cs; EnumMembers!CaseSensitive)\n        {\n            assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\", to!S(\"\\u0100\"), cs) == 9);\n            assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\"w, to!S(\"\\u0100\"), cs) == 7);\n            assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\"d, to!S(\"\\u0100\"), cs) == 6);\n        }\n    }\n    });\n}\n\n@safe pure @nogc nothrow\nunittest\n{\n    import std.traits : EnumMembers;\n    import std.utf : byWchar;\n\n    foreach (cs; EnumMembers!CaseSensitive)\n    {\n        assert(indexOf(\"\".byWchar, \"\", cs) == -1);\n        assert(indexOf(\"hello\".byWchar, \"\", cs) == 0);\n        assert(indexOf(\"hello\".byWchar, \"l\", cs) == 2);\n        assert(indexOf(\"heLLo\".byWchar, \"LL\", cs) == 2);\n        assert(indexOf(\"hello\".byWchar, \"lox\", cs) == -1);\n        assert(indexOf(\"hello\".byWchar, \"betty\", cs) == -1);\n        assert(indexOf(\"hello\\U00010143\\u0100*\\U00010143\".byWchar, \"\\u0100*\", cs) == 7);\n    }\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.traits : EnumMembers;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {{\n            assert(indexOf(cast(S) null, to!T(\"a\"), 1337) == -1);\n            assert(indexOf(to!S(\"def\"), to!T(\"a\"), 0) == -1);\n            assert(indexOf(to!S(\"abba\"), to!T(\"a\"), 2) == 3);\n            assert(indexOf(to!S(\"def\"), to!T(\"f\"), 1) == 2);\n            assert(indexOf(to!S(\"dfefffg\"), to!T(\"fff\"), 1) == 3);\n            assert(indexOf(to!S(\"dfeffgfff\"), to!T(\"fff\"), 5) == 6);\n\n            assert(indexOf(to!S(\"dfeffgfff\"), to!T(\"a\"), 1, No.caseSensitive) == -1);\n            assert(indexOf(to!S(\"def\"), to!T(\"a\"), 2, No.caseSensitive) == -1);\n            assert(indexOf(to!S(\"abba\"), to!T(\"a\"), 3, No.caseSensitive) == 3);\n            assert(indexOf(to!S(\"def\"), to!T(\"f\"), 1, No.caseSensitive) == 2);\n            assert(indexOf(to!S(\"dfefffg\"), to!T(\"fff\"), 2, No.caseSensitive) == 3);\n            assert(indexOf(to!S(\"dfeffgfff\"), to!T(\"fff\"), 4, No.caseSensitive) == 6);\n            assert(indexOf(to!S(\"dfeffgffföä\"), to!T(\"öä\"), 9, No.caseSensitive) == 9,\n                to!string(indexOf(to!S(\"dfeffgffföä\"), to!T(\"öä\"), 9, No.caseSensitive))\n                ~ \" \" ~ S.stringof ~ \" \" ~ T.stringof);\n\n            S sPlts = \"Mars: the fourth Rock (Planet) from the Sun.\";\n            S sMars = \"Who\\'s \\'My Favorite Maritian?\\'\";\n\n            assert(indexOf(sMars, to!T(\"MY fAVe\"), 10,\n                No.caseSensitive) == -1);\n            assert(indexOf(sMars, to!T(\"mY fAVOriTe\"), 4, No.caseSensitive) == 7);\n            assert(indexOf(sPlts, to!T(\"mArS:\"), 0, No.caseSensitive) == 0);\n            assert(indexOf(sPlts, to!T(\"rOcK\"), 12, No.caseSensitive) == 17);\n            assert(indexOf(sPlts, to!T(\"Un.\"), 32, No.caseSensitive) == 41);\n            assert(indexOf(sPlts, to!T(sPlts), 0, No.caseSensitive) == 0);\n\n            assert(indexOf(\"\\u0100\", to!T(\"\\u0100\"), 0, No.caseSensitive) == 0);\n\n            // Thanks to Carlos Santander B. and zwang\n            assert(indexOf(\"sus mejores cortesanos. Se embarcaron en el puerto de Dubai y\",\n                           to!T(\"page-break-before\"), 10, No.caseSensitive) == -1);\n\n            // In order for indexOf with and without index to be consistent\n            assert(indexOf(to!S(\"\"), to!T(\"\")) == indexOf(to!S(\"\"), to!T(\"\"), 0));\n        }}\n\n        foreach (cs; EnumMembers!CaseSensitive)\n        {\n            assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\", to!S(\"\\u0100\"),\n                3, cs) == 9);\n            assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\"w, to!S(\"\\u0100\"),\n                3, cs) == 7);\n            assert(indexOf(\"hello\\U00010143\\u0100\\U00010143\"d, to!S(\"\\u0100\"),\n                3, cs) == 6);\n        }\n    }\n}\n\n/++\n    Params:\n        s = string to search\n        c = character to search for\n        startIdx = the index into s to start searching from\n        cs = `Yes.caseSensitive` or `No.caseSensitive`\n\n    Returns:\n        The index of the last occurrence of `c` in `s`. If `c` is not\n        found, then `-1` is returned. The `startIdx` slices `s` in\n        the following way $(D s[0 .. startIdx]). `startIdx` represents a\n        codeunit index in `s`.\n\n    Throws:\n        If the sequence ending at `startIdx` does not represent a well\n        formed codepoint, then a $(REF UTFException, std,utf) may be thrown.\n\n    `cs` indicates whether the comparisons are case sensitive.\n  +/\nptrdiff_t lastIndexOf(Char)(const(Char)[] s, in dchar c,\n        in CaseSensitive cs = Yes.caseSensitive) @safe pure\nif (isSomeChar!Char)\n{\n    static import std.ascii, std.uni;\n    import std.utf : canSearchInCodeUnits;\n    if (cs == Yes.caseSensitive)\n    {\n        if (canSearchInCodeUnits!Char(c))\n        {\n            foreach_reverse (i, it; s)\n            {\n                if (it == c)\n                {\n                    return i;\n                }\n            }\n        }\n        else\n        {\n            foreach_reverse (i, dchar it; s)\n            {\n                if (it == c)\n                {\n                    return i;\n                }\n            }\n        }\n    }\n    else\n    {\n        if (std.ascii.isASCII(c))\n        {\n            immutable c1 = std.ascii.toLower(c);\n\n            foreach_reverse (i, it; s)\n            {\n                immutable c2 = std.ascii.toLower(it);\n                if (c1 == c2)\n                {\n                    return i;\n                }\n            }\n        }\n        else\n        {\n            immutable c1 = std.uni.toLower(c);\n\n            foreach_reverse (i, dchar it; s)\n            {\n                immutable c2 = std.uni.toLower(it);\n                if (c1 == c2)\n                {\n                    return i;\n                }\n            }\n        }\n    }\n\n    return -1;\n}\n\n/// Ditto\nptrdiff_t lastIndexOf(Char)(const(Char)[] s, in dchar c, in size_t startIdx,\n        in CaseSensitive cs = Yes.caseSensitive) @safe pure\nif (isSomeChar!Char)\n{\n    if (startIdx <= s.length)\n    {\n        return lastIndexOf(s[0u .. startIdx], c, cs);\n    }\n\n    return -1;\n}\n\n///\n@safe pure unittest\n{\n    import std.typecons : No;\n\n    string s = \"Hello World\";\n    assert(lastIndexOf(s, 'l') == 9);\n    assert(lastIndexOf(s, 'Z') == -1);\n    assert(lastIndexOf(s, 'L', No.caseSensitive) == 9);\n}\n\n///\n@safe pure unittest\n{\n    import std.typecons : No;\n\n    string s = \"Hello World\";\n    assert(lastIndexOf(s, 'l', 4) == 3);\n    assert(lastIndexOf(s, 'Z', 1337) == -1);\n    assert(lastIndexOf(s, 'L', 7, No.caseSensitive) == 3);\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n    import std.traits : EnumMembers;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        assert(lastIndexOf(cast(S) null, 'a') == -1);\n        assert(lastIndexOf(to!S(\"def\"), 'a') == -1);\n        assert(lastIndexOf(to!S(\"abba\"), 'a') == 3);\n        assert(lastIndexOf(to!S(\"def\"), 'f') == 2);\n        assert(lastIndexOf(to!S(\"ödef\"), 'ö') == 0);\n\n        assert(lastIndexOf(cast(S) null, 'a', No.caseSensitive) == -1);\n        assert(lastIndexOf(to!S(\"def\"), 'a', No.caseSensitive) == -1);\n        assert(lastIndexOf(to!S(\"AbbA\"), 'a', No.caseSensitive) == 3);\n        assert(lastIndexOf(to!S(\"def\"), 'F', No.caseSensitive) == 2);\n        assert(lastIndexOf(to!S(\"ödef\"), 'ö', No.caseSensitive) == 0);\n        assert(lastIndexOf(to!S(\"i\\u0100def\"), to!dchar(\"\\u0100\"),\n            No.caseSensitive) == 1);\n\n        S sPlts = \"Mars: the fourth Rock (Planet) from the Sun.\";\n\n        assert(lastIndexOf(to!S(\"def\"), 'f', No.caseSensitive) == 2);\n        assert(lastIndexOf(sPlts, 'M', No.caseSensitive) == 34);\n        assert(lastIndexOf(sPlts, 'S', No.caseSensitive) == 40);\n    }}\n\n    foreach (cs; EnumMembers!CaseSensitive)\n    {\n        assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\", '\\u0100', cs) == 4);\n        assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\"w, '\\u0100', cs) == 2);\n        assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\"d, '\\u0100', cs) == 1);\n    }\n    });\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.traits : EnumMembers;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        assert(lastIndexOf(cast(S) null, 'a') == -1);\n        assert(lastIndexOf(to!S(\"def\"), 'a') == -1);\n        assert(lastIndexOf(to!S(\"abba\"), 'a', 3) == 0);\n        assert(lastIndexOf(to!S(\"deff\"), 'f', 3) == 2);\n\n        assert(lastIndexOf(cast(S) null, 'a', No.caseSensitive) == -1);\n        assert(lastIndexOf(to!S(\"def\"), 'a', No.caseSensitive) == -1);\n        assert(lastIndexOf(to!S(\"AbbAa\"), 'a', to!ushort(4), No.caseSensitive) == 3,\n                to!string(lastIndexOf(to!S(\"AbbAa\"), 'a', 4, No.caseSensitive)));\n        assert(lastIndexOf(to!S(\"def\"), 'F', 3, No.caseSensitive) == 2);\n\n        S sPlts = \"Mars: the fourth Rock (Planet) from the Sun.\";\n\n        assert(lastIndexOf(to!S(\"def\"), 'f', 4, No.caseSensitive) == -1);\n        assert(lastIndexOf(sPlts, 'M', sPlts.length -2, No.caseSensitive) == 34);\n        assert(lastIndexOf(sPlts, 'S', sPlts.length -2, No.caseSensitive) == 40);\n    }}\n\n    foreach (cs; EnumMembers!CaseSensitive)\n    {\n        assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\", '\\u0100', cs) == 4);\n        assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\"w, '\\u0100', cs) == 2);\n        assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\"d, '\\u0100', cs) == 1);\n    }\n}\n\n/++\n    Params:\n        s = string to search\n        sub = substring to search for\n        startIdx = the index into s to start searching from\n        cs = `Yes.caseSensitive` or `No.caseSensitive`\n\n    Returns:\n        the index of the last occurrence of `sub` in `s`. If `sub` is\n        not found, then `-1` is returned. The `startIdx` slices `s`\n        in the following way $(D s[0 .. startIdx]). `startIdx` represents a\n        codeunit index in `s`.\n\n    Throws:\n        If the sequence ending at `startIdx` does not represent a well\n        formed codepoint, then a $(REF UTFException, std,utf) may be thrown.\n\n    `cs` indicates whether the comparisons are case sensitive.\n  +/\nptrdiff_t lastIndexOf(Char1, Char2)(const(Char1)[] s, const(Char2)[] sub,\n        in CaseSensitive cs = Yes.caseSensitive) @safe pure\nif (isSomeChar!Char1 && isSomeChar!Char2)\n{\n    import std.algorithm.searching : endsWith;\n    import std.conv : to;\n    import std.range.primitives : walkLength;\n    static import std.uni;\n    import std.utf : strideBack;\n    if (sub.empty)\n        return -1;\n\n    if (walkLength(sub) == 1)\n        return lastIndexOf(s, sub.front, cs);\n\n    if (cs == Yes.caseSensitive)\n    {\n        static if (is(Unqual!Char1 == Unqual!Char2))\n        {\n            import core.stdc.string : memcmp;\n\n            immutable c = sub[0];\n\n            for (ptrdiff_t i = s.length - sub.length; i >= 0; --i)\n            {\n                if (s[i] == c)\n                {\n                    if (__ctfe)\n                    {\n                        foreach (j; 1 .. sub.length)\n                        {\n                            if (s[i + j] != sub[j])\n                                continue;\n                        }\n                        return i;\n                    }\n                    else\n                    {\n                        auto trustedMemcmp(in void* s1, in void* s2, size_t n) @trusted\n                        {\n                            return memcmp(s1, s2, n);\n                        }\n                        if (trustedMemcmp(&s[i + 1], &sub[1],\n                                (sub.length - 1) * Char1.sizeof) == 0)\n                            return i;\n                    }\n                }\n            }\n        }\n        else\n        {\n            for (size_t i = s.length; !s.empty;)\n            {\n                if (s.endsWith(sub))\n                    return cast(ptrdiff_t) i - to!(const(Char1)[])(sub).length;\n\n                i -= strideBack(s, i);\n                s = s[0 .. i];\n            }\n        }\n    }\n    else\n    {\n        for (size_t i = s.length; !s.empty;)\n        {\n            if (endsWith!((a, b) => std.uni.toLower(a) == std.uni.toLower(b))\n                         (s, sub))\n            {\n                return cast(ptrdiff_t) i - to!(const(Char1)[])(sub).length;\n            }\n\n            i -= strideBack(s, i);\n            s = s[0 .. i];\n        }\n    }\n\n    return -1;\n}\n\n/// Ditto\nptrdiff_t lastIndexOf(Char1, Char2)(const(Char1)[] s, const(Char2)[] sub,\n        in size_t startIdx, in CaseSensitive cs = Yes.caseSensitive) @safe pure\nif (isSomeChar!Char1 && isSomeChar!Char2)\n{\n    if (startIdx <= s.length)\n    {\n        return lastIndexOf(s[0u .. startIdx], sub, cs);\n    }\n\n    return -1;\n}\n\n///\n@safe pure unittest\n{\n    import std.typecons : No;\n\n    string s = \"Hello World\";\n    assert(lastIndexOf(s, \"ll\") == 2);\n    assert(lastIndexOf(s, \"Zo\") == -1);\n    assert(lastIndexOf(s, \"lL\", No.caseSensitive) == 2);\n}\n\n///\n@safe pure unittest\n{\n    import std.typecons : No;\n\n    string s = \"Hello World\";\n    assert(lastIndexOf(s, \"ll\", 4) == 2);\n    assert(lastIndexOf(s, \"Zo\", 128) == -1);\n    assert(lastIndexOf(s, \"lL\", 3, No.caseSensitive) == -1);\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        auto r = to!S(\"\").lastIndexOf(\"hello\");\n        assert(r == -1, to!string(r));\n\n        r = to!S(\"hello\").lastIndexOf(\"\");\n        assert(r == -1, to!string(r));\n\n        r = to!S(\"\").lastIndexOf(\"\");\n        assert(r == -1, to!string(r));\n    }}\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n    import std.traits : EnumMembers;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {{\n            enum typeStr = S.stringof ~ \" \" ~ T.stringof;\n\n            assert(lastIndexOf(cast(S) null, to!T(\"a\")) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"c\")) == 6, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"cd\")) == 6, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"ef\")) == 8, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefCdef\"), to!T(\"c\")) == 2, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefCdef\"), to!T(\"cd\")) == 2, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"x\")) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"xy\")) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"\")) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"öabcdefcdef\"), to!T(\"ö\")) == 0, typeStr);\n\n            assert(lastIndexOf(cast(S) null, to!T(\"a\"), No.caseSensitive) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefCdef\"), to!T(\"c\"), No.caseSensitive) == 6, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefCdef\"), to!T(\"cD\"), No.caseSensitive) == 6, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"x\"), No.caseSensitive) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"xy\"), No.caseSensitive) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"\"), No.caseSensitive) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"öabcdefcdef\"), to!T(\"ö\"), No.caseSensitive) == 0, typeStr);\n\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"c\"), No.caseSensitive) == 6, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"cd\"), No.caseSensitive) == 6, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"def\"), No.caseSensitive) == 7, typeStr);\n\n            assert(lastIndexOf(to!S(\"ödfeffgfff\"), to!T(\"ö\"), Yes.caseSensitive) == 0);\n\n            S sPlts = \"Mars: the fourth Rock (Planet) from the Sun.\";\n            S sMars = \"Who\\'s \\'My Favorite Maritian?\\'\";\n\n            assert(lastIndexOf(sMars, to!T(\"RiTE maR\"), No.caseSensitive) == 14, typeStr);\n            assert(lastIndexOf(sPlts, to!T(\"FOuRTh\"), No.caseSensitive) == 10, typeStr);\n            assert(lastIndexOf(sMars, to!T(\"whO\\'s \\'MY\"), No.caseSensitive) == 0, typeStr);\n            assert(lastIndexOf(sMars, to!T(sMars), No.caseSensitive) == 0, typeStr);\n        }}\n\n        foreach (cs; EnumMembers!CaseSensitive)\n        {\n            enum csString = to!string(cs);\n\n            assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\", to!S(\"\\u0100\"), cs) == 4, csString);\n            assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\"w, to!S(\"\\u0100\"), cs) == 2, csString);\n            assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\"d, to!S(\"\\u0100\"), cs) == 1, csString);\n        }\n    }\n    });\n}\n\n@safe pure unittest // issue13529\n{\n    import std.conv : to;\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {{\n            enum typeStr = S.stringof ~ \" \" ~ T.stringof;\n            auto idx = lastIndexOf(to!T(\"Hällö Wörldö ö\"),to!S(\"ö ö\"));\n            assert(idx != -1, to!string(idx) ~ \" \" ~ typeStr);\n\n            idx = lastIndexOf(to!T(\"Hällö Wörldö ö\"),to!S(\"ö öd\"));\n            assert(idx == -1, to!string(idx) ~ \" \" ~ typeStr);\n        }}\n    }\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.traits : EnumMembers;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {{\n            enum typeStr = S.stringof ~ \" \" ~ T.stringof;\n\n            assert(lastIndexOf(cast(S) null, to!T(\"a\")) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"c\"), 5) == 2, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"cd\"), 3) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"ef\"), 6) == 4, typeStr ~\n                format(\" %u\", lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"ef\"), 6)));\n            assert(lastIndexOf(to!S(\"abcdefCdef\"), to!T(\"c\"), 5) == 2, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefCdef\"), to!T(\"cd\"), 3) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdefx\"), to!T(\"x\"), 1) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdefxy\"), to!T(\"xy\"), 6) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"\"), 8) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"öafö\"), to!T(\"ö\"), 3) == 0, typeStr ~\n                    to!string(lastIndexOf(to!S(\"öafö\"), to!T(\"ö\"), 3))); //BUG 10472\n\n            assert(lastIndexOf(cast(S) null, to!T(\"a\"), 1, No.caseSensitive) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefCdef\"), to!T(\"c\"), 5, No.caseSensitive) == 2, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefCdef\"), to!T(\"cD\"), 4, No.caseSensitive) == 2, typeStr ~\n                \" \" ~ to!string(lastIndexOf(to!S(\"abcdefCdef\"), to!T(\"cD\"), 3, No.caseSensitive)));\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"x\"),3 , No.caseSensitive) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdefXY\"), to!T(\"xy\"), 4, No.caseSensitive) == -1, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"\"), 7, No.caseSensitive) == -1, typeStr);\n\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"c\"), 4, No.caseSensitive) == 2, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"cd\"), 4, No.caseSensitive) == 2, typeStr);\n            assert(lastIndexOf(to!S(\"abcdefcdef\"), to!T(\"def\"), 6, No.caseSensitive) == 3, typeStr);\n            assert(lastIndexOf(to!S(\"\"), to!T(\"\"), 0) == lastIndexOf(to!S(\"\"), to!T(\"\")), typeStr);\n        }}\n\n        foreach (cs; EnumMembers!CaseSensitive)\n        {\n            enum csString = to!string(cs);\n\n            assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\", to!S(\"\\u0100\"), 6, cs) == 4, csString);\n            assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\"w, to!S(\"\\u0100\"), 6, cs) == 2, csString);\n            assert(lastIndexOf(\"\\U00010143\\u0100\\U00010143hello\"d, to!S(\"\\u0100\"), 3, cs) == 1, csString);\n        }\n    }\n}\n\nprivate ptrdiff_t indexOfAnyNeitherImpl(bool forward, bool any, Char, Char2)(\n        const(Char)[] haystack, const(Char2)[] needles,\n        in CaseSensitive cs = Yes.caseSensitive) @safe pure\nif (isSomeChar!Char && isSomeChar!Char2)\n{\n    import std.algorithm.searching : canFind, findAmong;\n    if (cs == Yes.caseSensitive)\n    {\n        static if (forward)\n        {\n            static if (any)\n            {\n                size_t n = haystack.findAmong(needles).length;\n                return n ? haystack.length - n : -1;\n            }\n            else\n            {\n                foreach (idx, dchar hay; haystack)\n                {\n                    if (!canFind(needles, hay))\n                    {\n                        return idx;\n                    }\n                }\n            }\n        }\n        else\n        {\n            static if (any)\n            {\n                import std.range : retro;\n                import std.utf : strideBack;\n                size_t n = haystack.retro.findAmong(needles).source.length;\n                if (n)\n                {\n                    return n - haystack.strideBack(n);\n                }\n            }\n            else\n            {\n                foreach_reverse (idx, dchar hay; haystack)\n                {\n                    if (!canFind(needles, hay))\n                    {\n                        return idx;\n                    }\n                }\n            }\n        }\n    }\n    else\n    {\n        import std.range.primitives : walkLength;\n        if (needles.length <= 16 && needles.walkLength(17))\n        {\n            size_t si = 0;\n            dchar[16] scratch = void;\n            foreach ( dchar c; needles)\n            {\n                scratch[si++] = toLower(c);\n            }\n\n            static if (forward)\n            {\n                foreach (i, dchar c; haystack)\n                {\n                    if (canFind(scratch[0 .. si], toLower(c)) == any)\n                    {\n                        return i;\n                    }\n                }\n            }\n            else\n            {\n                foreach_reverse (i, dchar c; haystack)\n                {\n                    if (canFind(scratch[0 .. si], toLower(c)) == any)\n                    {\n                        return i;\n                    }\n                }\n            }\n        }\n        else\n        {\n            static bool f(dchar a, dchar b)\n            {\n                return toLower(a) == b;\n            }\n\n            static if (forward)\n            {\n                foreach (i, dchar c; haystack)\n                {\n                    if (canFind!f(needles, toLower(c)) == any)\n                    {\n                        return i;\n                    }\n                }\n            }\n            else\n            {\n                foreach_reverse (i, dchar c; haystack)\n                {\n                    if (canFind!f(needles, toLower(c)) == any)\n                    {\n                        return i;\n                    }\n                }\n            }\n        }\n    }\n\n    return -1;\n}\n\n/**\n    Returns the index of the first occurrence of any of the elements in $(D\n    needles) in `haystack`. If no element of `needles` is found,\n    then `-1` is returned. The `startIdx` slices `haystack` in the\n    following way $(D haystack[startIdx .. $]). `startIdx` represents a\n    codeunit index in `haystack`. If the sequence ending at `startIdx`\n    does not represent a well formed codepoint, then a $(REF UTFException, std,utf)\n    may be thrown.\n\n    Params:\n        haystack = String to search for needles in.\n        needles = Strings to search for in haystack.\n        startIdx = slices haystack like this $(D haystack[startIdx .. $]). If\n            the startIdx is greater equal the length of haystack the functions\n            returns `-1`.\n        cs = Indicates whether the comparisons are case sensitive.\n*/\nptrdiff_t indexOfAny(Char,Char2)(const(Char)[] haystack, const(Char2)[] needles,\n        in CaseSensitive cs = Yes.caseSensitive) @safe pure\nif (isSomeChar!Char && isSomeChar!Char2)\n{\n    return indexOfAnyNeitherImpl!(true, true)(haystack, needles, cs);\n}\n\n/// Ditto\nptrdiff_t indexOfAny(Char,Char2)(const(Char)[] haystack, const(Char2)[] needles,\n        in size_t startIdx, in CaseSensitive cs = Yes.caseSensitive) @safe pure\nif (isSomeChar!Char && isSomeChar!Char2)\n{\n    if (startIdx < haystack.length)\n    {\n        ptrdiff_t foundIdx = indexOfAny(haystack[startIdx .. $], needles, cs);\n        if (foundIdx != -1)\n        {\n            return foundIdx + cast(ptrdiff_t) startIdx;\n        }\n    }\n\n    return -1;\n}\n\n///\n@safe pure unittest\n{\n    import std.conv : to;\n\n    ptrdiff_t i = \"helloWorld\".indexOfAny(\"Wr\");\n    assert(i == 5);\n    i = \"öällo world\".indexOfAny(\"lo \");\n    assert(i == 4, to!string(i));\n}\n\n///\n@safe pure unittest\n{\n    import std.conv : to;\n\n    ptrdiff_t i = \"helloWorld\".indexOfAny(\"Wr\", 4);\n    assert(i == 5);\n\n    i = \"Foo öällo world\".indexOfAny(\"lh\", 3);\n    assert(i == 8, to!string(i));\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        auto r = to!S(\"\").indexOfAny(\"hello\");\n        assert(r == -1, to!string(r));\n\n        r = to!S(\"hello\").indexOfAny(\"\");\n        assert(r == -1, to!string(r));\n\n        r = to!S(\"\").indexOfAny(\"\");\n        assert(r == -1, to!string(r));\n    }}\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {\n            assert(indexOfAny(cast(S) null, to!T(\"a\")) == -1);\n            assert(indexOfAny(to!S(\"def\"), to!T(\"rsa\")) == -1);\n            assert(indexOfAny(to!S(\"abba\"), to!T(\"a\")) == 0);\n            assert(indexOfAny(to!S(\"def\"), to!T(\"f\")) == 2);\n            assert(indexOfAny(to!S(\"dfefffg\"), to!T(\"fgh\")) == 1);\n            assert(indexOfAny(to!S(\"dfeffgfff\"), to!T(\"feg\")) == 1);\n\n            assert(indexOfAny(to!S(\"zfeffgfff\"), to!T(\"ACDC\"),\n                No.caseSensitive) == -1);\n            assert(indexOfAny(to!S(\"def\"), to!T(\"MI6\"),\n                No.caseSensitive) == -1);\n            assert(indexOfAny(to!S(\"abba\"), to!T(\"DEA\"),\n                No.caseSensitive) == 0);\n            assert(indexOfAny(to!S(\"def\"), to!T(\"FBI\"), No.caseSensitive) == 2);\n            assert(indexOfAny(to!S(\"dfefffg\"), to!T(\"NSA\"), No.caseSensitive)\n                == -1);\n            assert(indexOfAny(to!S(\"dfeffgfff\"), to!T(\"BND\"),\n                No.caseSensitive) == 0);\n            assert(indexOfAny(to!S(\"dfeffgfff\"), to!T(\"BNDabCHIJKQEPÖÖSYXÄ??ß\"),\n                No.caseSensitive) == 0);\n\n            assert(indexOfAny(\"\\u0100\", to!T(\"\\u0100\"), No.caseSensitive) == 0);\n        }\n    }\n    }\n    );\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.traits : EnumMembers;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {\n            assert(indexOfAny(cast(S) null, to!T(\"a\"), 1337) == -1);\n            assert(indexOfAny(to!S(\"def\"), to!T(\"AaF\"), 0) == -1);\n            assert(indexOfAny(to!S(\"abba\"), to!T(\"NSa\"), 2) == 3);\n            assert(indexOfAny(to!S(\"def\"), to!T(\"fbi\"), 1) == 2);\n            assert(indexOfAny(to!S(\"dfefffg\"), to!T(\"foo\"), 2) == 3);\n            assert(indexOfAny(to!S(\"dfeffgfff\"), to!T(\"fsb\"), 5) == 6);\n\n            assert(indexOfAny(to!S(\"dfeffgfff\"), to!T(\"NDS\"), 1,\n                No.caseSensitive) == -1);\n            assert(indexOfAny(to!S(\"def\"), to!T(\"DRS\"), 2,\n                No.caseSensitive) == -1);\n            assert(indexOfAny(to!S(\"abba\"), to!T(\"SI\"), 3,\n                No.caseSensitive) == -1);\n            assert(indexOfAny(to!S(\"deO\"), to!T(\"ASIO\"), 1,\n                No.caseSensitive) == 2);\n            assert(indexOfAny(to!S(\"dfefffg\"), to!T(\"fbh\"), 2,\n                No.caseSensitive) == 3);\n            assert(indexOfAny(to!S(\"dfeffgfff\"), to!T(\"fEe\"), 4,\n                No.caseSensitive) == 4);\n            assert(indexOfAny(to!S(\"dfeffgffföä\"), to!T(\"föä\"), 9,\n                No.caseSensitive) == 9);\n\n            assert(indexOfAny(\"\\u0100\", to!T(\"\\u0100\"), 0,\n                No.caseSensitive) == 0);\n        }\n\n        foreach (cs; EnumMembers!CaseSensitive)\n        {\n            assert(indexOfAny(\"hello\\U00010143\\u0100\\U00010143\",\n                to!S(\"e\\u0100\"), 3, cs) == 9);\n            assert(indexOfAny(\"hello\\U00010143\\u0100\\U00010143\"w,\n                to!S(\"h\\u0100\"), 3, cs) == 7);\n            assert(indexOfAny(\"hello\\U00010143\\u0100\\U00010143\"d,\n                to!S(\"l\\u0100\"), 5, cs) == 6);\n        }\n    }\n}\n\n/**\n    Returns the index of the last occurrence of any of the elements in $(D\n    needles) in `haystack`. If no element of `needles` is found,\n    then `-1` is returned. The `stopIdx` slices `haystack` in the\n    following way $(D s[0 .. stopIdx]). `stopIdx` represents a codeunit\n    index in `haystack`. If the sequence ending at `startIdx` does not\n    represent a well formed codepoint, then a $(REF UTFException, std,utf) may be\n    thrown.\n\n    Params:\n        haystack = String to search for needles in.\n        needles = Strings to search for in haystack.\n        stopIdx = slices haystack like this $(D haystack[0 .. stopIdx]). If\n            the stopIdx is greater equal the length of haystack the functions\n            returns `-1`.\n        cs = Indicates whether the comparisons are case sensitive.\n*/\nptrdiff_t lastIndexOfAny(Char,Char2)(const(Char)[] haystack,\n        const(Char2)[] needles, in CaseSensitive cs = Yes.caseSensitive)\n        @safe pure\nif (isSomeChar!Char && isSomeChar!Char2)\n{\n    return indexOfAnyNeitherImpl!(false, true)(haystack, needles, cs);\n}\n\n/// Ditto\nptrdiff_t lastIndexOfAny(Char,Char2)(const(Char)[] haystack,\n        const(Char2)[] needles, in size_t stopIdx,\n        in CaseSensitive cs = Yes.caseSensitive) @safe pure\nif (isSomeChar!Char && isSomeChar!Char2)\n{\n    if (stopIdx <= haystack.length)\n    {\n        return lastIndexOfAny(haystack[0u .. stopIdx], needles, cs);\n    }\n\n    return -1;\n}\n\n///\n@safe pure unittest\n{\n    ptrdiff_t i = \"helloWorld\".lastIndexOfAny(\"Wlo\");\n    assert(i == 8);\n\n    i = \"Foo öäöllo world\".lastIndexOfAny(\"öF\");\n    assert(i == 8);\n}\n\n///\n@safe pure unittest\n{\n    import std.conv : to;\n\n    ptrdiff_t i = \"helloWorld\".lastIndexOfAny(\"Wlo\", 4);\n    assert(i == 3);\n\n    i = \"Foo öäöllo world\".lastIndexOfAny(\"öF\", 3);\n    assert(i == 0);\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        auto r = to!S(\"\").lastIndexOfAny(\"hello\");\n        assert(r == -1, to!string(r));\n\n        r = to!S(\"hello\").lastIndexOfAny(\"\");\n        assert(r == -1, to!string(r));\n\n        r = to!S(\"\").lastIndexOfAny(\"\");\n        assert(r == -1, to!string(r));\n    }}\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {{\n            assert(lastIndexOfAny(cast(S) null, to!T(\"a\")) == -1);\n            assert(lastIndexOfAny(to!S(\"def\"), to!T(\"rsa\")) == -1);\n            assert(lastIndexOfAny(to!S(\"abba\"), to!T(\"a\")) == 3);\n            assert(lastIndexOfAny(to!S(\"def\"), to!T(\"f\")) == 2);\n            assert(lastIndexOfAny(to!S(\"dfefffg\"), to!T(\"fgh\")) == 6);\n\n            ptrdiff_t oeIdx = 9;\n               if (is(S == wstring) || is(S == dstring))\n            {\n                oeIdx = 8;\n            }\n\n            auto foundOeIdx = lastIndexOfAny(to!S(\"dfeffgföf\"), to!T(\"feg\"));\n            assert(foundOeIdx == oeIdx, to!string(foundOeIdx));\n\n            assert(lastIndexOfAny(to!S(\"zfeffgfff\"), to!T(\"ACDC\"),\n                No.caseSensitive) == -1);\n            assert(lastIndexOfAny(to!S(\"def\"), to!T(\"MI6\"),\n                No.caseSensitive) == -1);\n            assert(lastIndexOfAny(to!S(\"abba\"), to!T(\"DEA\"),\n                No.caseSensitive) == 3);\n            assert(lastIndexOfAny(to!S(\"def\"), to!T(\"FBI\"),\n                No.caseSensitive) == 2);\n            assert(lastIndexOfAny(to!S(\"dfefffg\"), to!T(\"NSA\"),\n                No.caseSensitive) == -1);\n\n            oeIdx = 2;\n               if (is(S == wstring) || is(S == dstring))\n            {\n                oeIdx = 1;\n            }\n            assert(lastIndexOfAny(to!S(\"ödfeffgfff\"), to!T(\"BND\"),\n                No.caseSensitive) == oeIdx);\n\n            assert(lastIndexOfAny(\"\\u0100\", to!T(\"\\u0100\"),\n                No.caseSensitive) == 0);\n        }}\n    }\n    }\n    );\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {{\n            enum typeStr = S.stringof ~ \" \" ~ T.stringof;\n\n            assert(lastIndexOfAny(cast(S) null, to!T(\"a\"), 1337) == -1,\n                typeStr);\n            assert(lastIndexOfAny(to!S(\"abcdefcdef\"), to!T(\"c\"), 7) == 6,\n                typeStr);\n            assert(lastIndexOfAny(to!S(\"abcdefcdef\"), to!T(\"cd\"), 5) == 3,\n                typeStr);\n            assert(lastIndexOfAny(to!S(\"abcdefcdef\"), to!T(\"ef\"), 6) == 5,\n                typeStr);\n            assert(lastIndexOfAny(to!S(\"abcdefCdef\"), to!T(\"c\"), 8) == 2,\n                typeStr);\n            assert(lastIndexOfAny(to!S(\"abcdefcdef\"), to!T(\"x\"), 7) == -1,\n                typeStr);\n            assert(lastIndexOfAny(to!S(\"abcdefcdef\"), to!T(\"xy\"), 4) == -1,\n                typeStr);\n            assert(lastIndexOfAny(to!S(\"öabcdefcdef\"), to!T(\"ö\"), 2) == 0,\n                typeStr);\n\n            assert(lastIndexOfAny(cast(S) null, to!T(\"a\"), 1337,\n                No.caseSensitive) == -1, typeStr);\n            assert(lastIndexOfAny(to!S(\"abcdefcdef\"), to!T(\"C\"), 7,\n                No.caseSensitive) == 6, typeStr);\n            assert(lastIndexOfAny(to!S(\"ABCDEFCDEF\"), to!T(\"cd\"), 5,\n                No.caseSensitive) == 3, typeStr);\n            assert(lastIndexOfAny(to!S(\"abcdefcdef\"), to!T(\"EF\"), 6,\n                No.caseSensitive) == 5, typeStr);\n            assert(lastIndexOfAny(to!S(\"ABCDEFcDEF\"), to!T(\"C\"), 8,\n                No.caseSensitive) == 6, typeStr);\n            assert(lastIndexOfAny(to!S(\"ABCDEFCDEF\"), to!T(\"x\"), 7,\n                No.caseSensitive) == -1, typeStr);\n            assert(lastIndexOfAny(to!S(\"abCdefcdef\"), to!T(\"XY\"), 4,\n                No.caseSensitive) == -1, typeStr);\n            assert(lastIndexOfAny(to!S(\"ÖABCDEFCDEF\"), to!T(\"ö\"), 2,\n                No.caseSensitive) == 0, typeStr);\n        }}\n    }\n    }\n    );\n}\n\n/**\n    Returns the index of the first occurrence of any character not an elements\n    in `needles` in `haystack`. If all element of `haystack` are\n    element of `needles` `-1` is returned.\n\n    Params:\n        haystack = String to search for needles in.\n        needles = Strings to search for in haystack.\n        startIdx = slices haystack like this $(D haystack[startIdx .. $]). If\n            the startIdx is greater equal the length of haystack the functions\n            returns `-1`.\n        cs = Indicates whether the comparisons are case sensitive.\n*/\nptrdiff_t indexOfNeither(Char,Char2)(const(Char)[] haystack,\n        const(Char2)[] needles, in CaseSensitive cs = Yes.caseSensitive)\n        @safe pure\nif (isSomeChar!Char && isSomeChar!Char2)\n{\n    return indexOfAnyNeitherImpl!(true, false)(haystack, needles, cs);\n}\n\n/// Ditto\nptrdiff_t indexOfNeither(Char,Char2)(const(Char)[] haystack,\n        const(Char2)[] needles, in size_t startIdx,\n        in CaseSensitive cs = Yes.caseSensitive)\n        @safe pure\nif (isSomeChar!Char && isSomeChar!Char2)\n{\n    if (startIdx < haystack.length)\n    {\n        ptrdiff_t foundIdx = indexOfAnyNeitherImpl!(true, false)(\n            haystack[startIdx .. $], needles, cs);\n        if (foundIdx != -1)\n        {\n            return foundIdx + cast(ptrdiff_t) startIdx;\n        }\n    }\n    return -1;\n}\n\n///\n@safe pure unittest\n{\n    assert(indexOfNeither(\"abba\", \"a\", 2) == 2);\n    assert(indexOfNeither(\"def\", \"de\", 1) == 2);\n    assert(indexOfNeither(\"dfefffg\", \"dfe\", 4) == 6);\n}\n\n///\n@safe pure unittest\n{\n    assert(indexOfNeither(\"def\", \"a\") == 0);\n    assert(indexOfNeither(\"def\", \"de\") == 2);\n    assert(indexOfNeither(\"dfefffg\", \"dfe\") == 6);\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        auto r = to!S(\"\").indexOfNeither(\"hello\");\n        assert(r == -1, to!string(r));\n\n        r = to!S(\"hello\").indexOfNeither(\"\");\n        assert(r == 0, to!string(r));\n\n        r = to!S(\"\").indexOfNeither(\"\");\n        assert(r == -1, to!string(r));\n    }}\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {\n            assert(indexOfNeither(cast(S) null, to!T(\"a\")) == -1);\n            assert(indexOfNeither(\"abba\", \"a\") == 1);\n\n            assert(indexOfNeither(to!S(\"dfeffgfff\"), to!T(\"a\"),\n                No.caseSensitive) == 0);\n            assert(indexOfNeither(to!S(\"def\"), to!T(\"D\"),\n                No.caseSensitive) == 1);\n            assert(indexOfNeither(to!S(\"ABca\"), to!T(\"a\"),\n                No.caseSensitive) == 1);\n            assert(indexOfNeither(to!S(\"def\"), to!T(\"f\"),\n                No.caseSensitive) == 0);\n            assert(indexOfNeither(to!S(\"DfEfffg\"), to!T(\"dFe\"),\n                No.caseSensitive) == 6);\n            if (is(S == string))\n            {\n                assert(indexOfNeither(to!S(\"äDfEfffg\"), to!T(\"ädFe\"),\n                    No.caseSensitive) == 8,\n                    to!string(indexOfNeither(to!S(\"äDfEfffg\"), to!T(\"ädFe\"),\n                    No.caseSensitive)));\n            }\n            else\n            {\n                assert(indexOfNeither(to!S(\"äDfEfffg\"), to!T(\"ädFe\"),\n                    No.caseSensitive) == 7,\n                    to!string(indexOfNeither(to!S(\"äDfEfffg\"), to!T(\"ädFe\"),\n                    No.caseSensitive)));\n            }\n        }\n    }\n    }\n    );\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {\n            assert(indexOfNeither(cast(S) null, to!T(\"a\"), 1) == -1);\n            assert(indexOfNeither(to!S(\"def\"), to!T(\"a\"), 1) == 1,\n                to!string(indexOfNeither(to!S(\"def\"), to!T(\"a\"), 1)));\n\n            assert(indexOfNeither(to!S(\"dfeffgfff\"), to!T(\"a\"), 4,\n                No.caseSensitive) == 4);\n            assert(indexOfNeither(to!S(\"def\"), to!T(\"D\"), 2,\n                No.caseSensitive) == 2);\n            assert(indexOfNeither(to!S(\"ABca\"), to!T(\"a\"), 3,\n                No.caseSensitive) == -1);\n            assert(indexOfNeither(to!S(\"def\"), to!T(\"tzf\"), 2,\n                No.caseSensitive) == -1);\n            assert(indexOfNeither(to!S(\"DfEfffg\"), to!T(\"dFe\"), 5,\n                No.caseSensitive) == 6);\n            if (is(S == string))\n            {\n                assert(indexOfNeither(to!S(\"öDfEfffg\"), to!T(\"äDi\"), 2,\n                    No.caseSensitive) == 3, to!string(indexOfNeither(\n                    to!S(\"öDfEfffg\"), to!T(\"äDi\"), 2, No.caseSensitive)));\n            }\n            else\n            {\n                assert(indexOfNeither(to!S(\"öDfEfffg\"), to!T(\"äDi\"), 2,\n                    No.caseSensitive) == 2, to!string(indexOfNeither(\n                    to!S(\"öDfEfffg\"), to!T(\"äDi\"), 2, No.caseSensitive)));\n            }\n        }\n    }\n    }\n    );\n}\n\n/**\n    Returns the last index of the first occurence of any character that is not\n    an elements in `needles` in `haystack`. If all element of\n    `haystack` are element of `needles` `-1` is returned.\n\n    Params:\n        haystack = String to search for needles in.\n        needles = Strings to search for in haystack.\n        stopIdx = slices haystack like this $(D haystack[0 .. stopIdx]) If\n        the stopIdx is greater equal the length of haystack the functions\n        returns `-1`.\n        cs = Indicates whether the comparisons are case sensitive.\n*/\nptrdiff_t lastIndexOfNeither(Char,Char2)(const(Char)[] haystack,\n        const(Char2)[] needles, in CaseSensitive cs = Yes.caseSensitive)\n        @safe pure\nif (isSomeChar!Char && isSomeChar!Char2)\n{\n    return indexOfAnyNeitherImpl!(false, false)(haystack, needles, cs);\n}\n\n/// Ditto\nptrdiff_t lastIndexOfNeither(Char,Char2)(const(Char)[] haystack,\n        const(Char2)[] needles, in size_t stopIdx,\n        in CaseSensitive cs = Yes.caseSensitive)\n        @safe pure\nif (isSomeChar!Char && isSomeChar!Char2)\n{\n    if (stopIdx < haystack.length)\n    {\n        return indexOfAnyNeitherImpl!(false, false)(haystack[0 .. stopIdx],\n            needles, cs);\n    }\n    return -1;\n}\n\n///\n@safe pure unittest\n{\n    assert(lastIndexOfNeither(\"abba\", \"a\") == 2);\n    assert(lastIndexOfNeither(\"def\", \"f\") == 1);\n}\n\n///\n@safe pure unittest\n{\n    assert(lastIndexOfNeither(\"def\", \"rsa\", 3) == -1);\n    assert(lastIndexOfNeither(\"abba\", \"a\", 2) == 1);\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        auto r = to!S(\"\").lastIndexOfNeither(\"hello\");\n        assert(r == -1, to!string(r));\n\n        r = to!S(\"hello\").lastIndexOfNeither(\"\");\n        assert(r == 4, to!string(r));\n\n        r = to!S(\"\").lastIndexOfNeither(\"\");\n        assert(r == -1, to!string(r));\n    }}\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {{\n            assert(lastIndexOfNeither(cast(S) null, to!T(\"a\")) == -1);\n            assert(lastIndexOfNeither(to!S(\"def\"), to!T(\"rsa\")) == 2);\n            assert(lastIndexOfNeither(to!S(\"dfefffg\"), to!T(\"fgh\")) == 2);\n\n            ptrdiff_t oeIdx = 8;\n               if (is(S == string))\n            {\n                oeIdx = 9;\n            }\n\n            auto foundOeIdx = lastIndexOfNeither(to!S(\"ödfefegff\"), to!T(\"zeg\"));\n            assert(foundOeIdx == oeIdx, to!string(foundOeIdx));\n\n            assert(lastIndexOfNeither(to!S(\"zfeffgfsb\"), to!T(\"FSB\"),\n                No.caseSensitive) == 5);\n            assert(lastIndexOfNeither(to!S(\"def\"), to!T(\"MI6\"),\n                No.caseSensitive) == 2, to!string(lastIndexOfNeither(to!S(\"def\"),\n                to!T(\"MI6\"), No.caseSensitive)));\n            assert(lastIndexOfNeither(to!S(\"abbadeafsb\"), to!T(\"fSb\"),\n                No.caseSensitive) == 6, to!string(lastIndexOfNeither(\n                to!S(\"abbadeafsb\"), to!T(\"fSb\"), No.caseSensitive)));\n            assert(lastIndexOfNeither(to!S(\"defbi\"), to!T(\"FBI\"),\n                No.caseSensitive) == 1);\n            assert(lastIndexOfNeither(to!S(\"dfefffg\"), to!T(\"NSA\"),\n                No.caseSensitive) == 6);\n            assert(lastIndexOfNeither(to!S(\"dfeffgfffö\"), to!T(\"BNDabCHIJKQEPÖÖSYXÄ??ß\"),\n                No.caseSensitive) == 8, to!string(lastIndexOfNeither(to!S(\"dfeffgfffö\"),\n                to!T(\"BNDabCHIJKQEPÖÖSYXÄ??ß\"), No.caseSensitive)));\n        }}\n    }\n    }\n    );\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(string, wstring, dstring))\n        {{\n            assert(lastIndexOfNeither(cast(S) null, to!T(\"a\"), 1337) == -1);\n            assert(lastIndexOfNeither(to!S(\"def\"), to!T(\"f\")) == 1);\n            assert(lastIndexOfNeither(to!S(\"dfefffg\"), to!T(\"fgh\")) == 2);\n\n            ptrdiff_t oeIdx = 4;\n               if (is(S == string))\n            {\n                oeIdx = 5;\n            }\n\n            auto foundOeIdx = lastIndexOfNeither(to!S(\"ödfefegff\"), to!T(\"zeg\"),\n                7);\n            assert(foundOeIdx == oeIdx, to!string(foundOeIdx));\n\n            assert(lastIndexOfNeither(to!S(\"zfeffgfsb\"), to!T(\"FSB\"), 6,\n                No.caseSensitive) == 5);\n            assert(lastIndexOfNeither(to!S(\"def\"), to!T(\"MI6\"), 2,\n                No.caseSensitive) == 1, to!string(lastIndexOfNeither(to!S(\"def\"),\n                to!T(\"MI6\"), 2, No.caseSensitive)));\n            assert(lastIndexOfNeither(to!S(\"abbadeafsb\"), to!T(\"fSb\"), 6,\n                No.caseSensitive) == 5, to!string(lastIndexOfNeither(\n                to!S(\"abbadeafsb\"), to!T(\"fSb\"), 6, No.caseSensitive)));\n            assert(lastIndexOfNeither(to!S(\"defbi\"), to!T(\"FBI\"), 3,\n                No.caseSensitive) == 1);\n            assert(lastIndexOfNeither(to!S(\"dfefffg\"), to!T(\"NSA\"), 2,\n                No.caseSensitive) == 1, to!string(lastIndexOfNeither(\n                    to!S(\"dfefffg\"), to!T(\"NSA\"), 2, No.caseSensitive)));\n        }}\n    }\n    }\n    );\n}\n\n/**\n * Returns the _representation of a string, which has the same type\n * as the string except the character type is replaced by `ubyte`,\n * `ushort`, or `uint` depending on the character width.\n *\n * Params:\n *     s = The string to return the _representation of.\n *\n * Returns:\n *     The _representation of the passed string.\n */\nauto representation(Char)(Char[] s) @safe pure nothrow @nogc\nif (isSomeChar!Char)\n{\n    import std.traits : ModifyTypePreservingTQ;\n    alias ToRepType(T) = AliasSeq!(ubyte, ushort, uint)[T.sizeof / 2];\n    return cast(ModifyTypePreservingTQ!(ToRepType, Char)[])s;\n}\n\n///\n@safe pure unittest\n{\n    string s = \"hello\";\n    static assert(is(typeof(representation(s)) == immutable(ubyte)[]));\n    assert(representation(s) is cast(immutable(ubyte)[]) s);\n    assert(representation(s) == [0x68, 0x65, 0x6c, 0x6c, 0x6f]);\n}\n\n@system pure unittest\n{\n    import std.exception : assertCTFEable;\n    import std.traits : Fields;\n    import std.typecons : Tuple;\n\n    assertCTFEable!(\n    {\n    void test(Char, T)(Char[] str)\n    {\n        static assert(is(typeof(representation(str)) == T[]));\n        assert(representation(str) is cast(T[]) str);\n    }\n\n    static foreach (Type; AliasSeq!(Tuple!(char , ubyte ),\n                             Tuple!(wchar, ushort),\n                             Tuple!(dchar, uint  )))\n    {{\n        alias Char = Fields!Type[0];\n        alias Int  = Fields!Type[1];\n        enum immutable(Char)[] hello = \"hello\";\n\n        test!(   immutable Char,    immutable Int)(hello);\n        test!(       const Char,        const Int)(hello);\n        test!(             Char,              Int)(hello.dup);\n        test!(      shared Char,       shared Int)(cast(shared) hello.dup);\n        test!(const shared Char, const shared Int)(hello);\n    }}\n    });\n}\n\n\n/**\n * Capitalize the first character of `s` and convert the rest of `s` to\n * lowercase.\n *\n * Params:\n *     input = The string to _capitalize.\n *\n * Returns:\n *     The capitalized string.\n *\n * See_Also:\n *      $(REF asCapitalized, std,uni) for a lazy range version that doesn't allocate memory\n */\nS capitalize(S)(S input) @trusted pure\nif (isSomeString!S)\n{\n    import std.array : array;\n    import std.uni : asCapitalized;\n    import std.utf : byUTF;\n\n    return input.asCapitalized.byUTF!(ElementEncodingType!(S)).array;\n}\n\n///\npure @safe unittest\n{\n    assert(capitalize(\"hello\") == \"Hello\");\n    assert(capitalize(\"World\") == \"World\");\n}\n\nauto capitalize(S)(auto ref S s)\nif (!isSomeString!S && is(StringTypeOf!S))\n{\n    return capitalize!(StringTypeOf!S)(s);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!capitalize(\"hello\"));\n}\n\n@safe pure unittest\n{\n    import std.algorithm.comparison : cmp;\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[]))\n    {{\n        S s1 = to!S(\"FoL\");\n        S s2;\n\n        s2 = capitalize(s1);\n        assert(cmp(s2, \"Fol\") == 0);\n        assert(s2 !is s1);\n\n        s2 = capitalize(s1[0 .. 2]);\n        assert(cmp(s2, \"Fo\") == 0);\n\n        s1 = to!S(\"fOl\");\n        s2 = capitalize(s1);\n        assert(cmp(s2, \"Fol\") == 0);\n        assert(s2 !is s1);\n        s1 = to!S(\"\\u0131 \\u0130\");\n        s2 = capitalize(s1);\n        assert(cmp(s2, \"\\u0049 i\\u0307\") == 0);\n        assert(s2 !is s1);\n\n        s1 = to!S(\"\\u017F \\u0049\");\n        s2 = capitalize(s1);\n        assert(cmp(s2, \"\\u0053 \\u0069\") == 0);\n        assert(s2 !is s1);\n    }}\n    });\n}\n\n/++\n    Split `s` into an array of lines according to the unicode standard using\n    `'\\r'`, `'\\n'`, `\"\\r\\n\"`, $(REF lineSep, std,uni),\n    $(REF paraSep, std,uni), `U+0085` (NEL), `'\\v'`  and `'\\f'`\n    as delimiters. If `keepTerm` is set to `KeepTerminator.yes`, then the\n    delimiter is included in the strings returned.\n\n    Does not throw on invalid UTF; such is simply passed unchanged\n    to the output.\n\n    Allocates memory; use $(LREF lineSplitter) for an alternative that\n    does not.\n\n    Adheres to $(HTTP www.unicode.org/versions/Unicode7.0.0/ch05.pdf, Unicode 7.0).\n\n  Params:\n    s = a string of `chars`, `wchars`, or `dchars`, or any custom\n        type that casts to a `string` type\n    keepTerm = whether delimiter is included or not in the results\n  Returns:\n    array of strings, each element is a line that is a slice of `s`\n  See_Also:\n    $(LREF lineSplitter)\n    $(REF splitter, std,algorithm)\n    $(REF splitter, std,regex)\n +/\nalias KeepTerminator = Flag!\"keepTerminator\";\n\n/// ditto\nC[][] splitLines(C)(C[] s, KeepTerminator keepTerm = No.keepTerminator) @safe pure\nif (isSomeChar!C)\n{\n    import std.array : appender;\n    import std.uni : lineSep, paraSep;\n\n    size_t iStart = 0;\n    auto retval = appender!(C[][])();\n\n    for (size_t i; i < s.length; ++i)\n    {\n        switch (s[i])\n        {\n            case '\\v', '\\f', '\\n':\n                retval.put(s[iStart .. i + (keepTerm == Yes.keepTerminator)]);\n                iStart = i + 1;\n                break;\n\n            case '\\r':\n                if (i + 1 < s.length && s[i + 1] == '\\n')\n                {\n                    retval.put(s[iStart .. i + (keepTerm == Yes.keepTerminator) * 2]);\n                    iStart = i + 2;\n                    ++i;\n                }\n                else\n                {\n                    goto case '\\n';\n                }\n                break;\n\n            static if (s[i].sizeof == 1)\n            {\n                /* Manually decode:\n                 *  lineSep is E2 80 A8\n                 *  paraSep is E2 80 A9\n                 */\n                case 0xE2:\n                    if (i + 2 < s.length &&\n                        s[i + 1] == 0x80 &&\n                        (s[i + 2] == 0xA8 || s[i + 2] == 0xA9)\n                       )\n                    {\n                        retval.put(s[iStart .. i + (keepTerm == Yes.keepTerminator) * 3]);\n                        iStart = i + 3;\n                        i += 2;\n                    }\n                    else\n                        goto default;\n                    break;\n                /* Manually decode:\n                 *  NEL is C2 85\n                 */\n                case 0xC2:\n                    if (i + 1 < s.length && s[i + 1] == 0x85)\n                    {\n                        retval.put(s[iStart .. i + (keepTerm == Yes.keepTerminator) * 2]);\n                        iStart = i + 2;\n                        i += 1;\n                    }\n                    else\n                        goto default;\n                    break;\n            }\n            else\n            {\n                case lineSep:\n                case paraSep:\n                case '\\u0085':\n                    goto case '\\n';\n            }\n\n            default:\n                break;\n        }\n    }\n\n    if (iStart != s.length)\n        retval.put(s[iStart .. $]);\n\n    return retval.data;\n}\n\n///\n@safe pure nothrow unittest\n{\n    string s = \"Hello\\nmy\\rname\\nis\";\n    assert(splitLines(s) == [\"Hello\", \"my\", \"name\", \"is\"]);\n}\n\n@safe pure nothrow unittest\n{\n    string s = \"a\\xC2\\x86b\";\n    assert(splitLines(s) == [s]);\n}\n\n@safe pure nothrow unittest\n{\n    assert(testAliasedString!splitLines(\"hello\\nworld\"));\n\n    enum S : string { a = \"hello\\nworld\" }\n    assert(S.a.splitLines() == [\"hello\", \"world\"]);\n\n    char[S.a.length] sa = S.a[];\n    assert(sa.splitLines() == [\"hello\", \"world\"]);\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n    {{\n        auto s = to!S(\n            \"\\rpeter\\n\\rpaul\\r\\njerry\\u2028ice\\u2029cream\\n\\nsunday\\n\" ~\n            \"mon\\u2030day\\nschadenfreude\\vkindergarten\\f\\vcookies\\u0085\"\n        );\n        auto lines = splitLines(s);\n        assert(lines.length == 14);\n        assert(lines[0] == \"\");\n        assert(lines[1] == \"peter\");\n        assert(lines[2] == \"\");\n        assert(lines[3] == \"paul\");\n        assert(lines[4] == \"jerry\");\n        assert(lines[5] == \"ice\");\n        assert(lines[6] == \"cream\");\n        assert(lines[7] == \"\");\n        assert(lines[8] == \"sunday\");\n        assert(lines[9] == \"mon\\u2030day\");\n        assert(lines[10] == \"schadenfreude\");\n        assert(lines[11] == \"kindergarten\");\n        assert(lines[12] == \"\");\n        assert(lines[13] == \"cookies\");\n\n\n        ubyte[] u = ['a', 0xFF, 0x12, 'b'];     // invalid UTF\n        auto ulines = splitLines(cast(char[]) u);\n        assert(cast(ubyte[])(ulines[0]) == u);\n\n        lines = splitLines(s, Yes.keepTerminator);\n        assert(lines.length == 14);\n        assert(lines[0] == \"\\r\");\n        assert(lines[1] == \"peter\\n\");\n        assert(lines[2] == \"\\r\");\n        assert(lines[3] == \"paul\\r\\n\");\n        assert(lines[4] == \"jerry\\u2028\");\n        assert(lines[5] == \"ice\\u2029\");\n        assert(lines[6] == \"cream\\n\");\n        assert(lines[7] == \"\\n\");\n        assert(lines[8] == \"sunday\\n\");\n        assert(lines[9] == \"mon\\u2030day\\n\");\n        assert(lines[10] == \"schadenfreude\\v\");\n        assert(lines[11] == \"kindergarten\\f\");\n        assert(lines[12] == \"\\v\");\n        assert(lines[13] == \"cookies\\u0085\");\n\n        s.popBack(); // Lop-off trailing \\n\n        lines = splitLines(s);\n        assert(lines.length == 14);\n        assert(lines[9] == \"mon\\u2030day\");\n\n        lines = splitLines(s, Yes.keepTerminator);\n        assert(lines.length == 14);\n        assert(lines[13] == \"cookies\");\n    }}\n    });\n}\n\nprivate struct LineSplitter(KeepTerminator keepTerm = No.keepTerminator, Range)\n{\n    import std.conv : unsigned;\n    import std.uni : lineSep, paraSep;\nprivate:\n    Range _input;\n\n    alias IndexType = typeof(unsigned(_input.length));\n    enum IndexType _unComputed = IndexType.max;\n    IndexType iStart = _unComputed;\n    IndexType iEnd = 0;\n    IndexType iNext = 0;\n\npublic:\n    this(Range input)\n    {\n        _input = input;\n    }\n\n    static if (isInfinite!Range)\n    {\n        enum bool empty = false;\n    }\n    else\n    {\n        @property bool empty()\n        {\n            return iStart == _unComputed && iNext == _input.length;\n        }\n    }\n\n    @property typeof(_input) front()\n    {\n        if (iStart == _unComputed)\n        {\n            iStart = iNext;\n        Loop:\n            for (IndexType i = iNext; ; ++i)\n            {\n                if (i == _input.length)\n                {\n                    iEnd = i;\n                    iNext = i;\n                    break Loop;\n                }\n                switch (_input[i])\n                {\n                case '\\v', '\\f', '\\n':\n                    iEnd = i + (keepTerm == Yes.keepTerminator);\n                    iNext = i + 1;\n                    break Loop;\n\n                case '\\r':\n                    if (i + 1 < _input.length && _input[i + 1] == '\\n')\n                    {\n                        iEnd = i + (keepTerm == Yes.keepTerminator) * 2;\n                        iNext = i + 2;\n                        break Loop;\n                    }\n                    else\n                    {\n                        goto case '\\n';\n                    }\n\n                    static if (_input[i].sizeof == 1)\n                    {\n                        /* Manually decode:\n                         *  lineSep is E2 80 A8\n                         *  paraSep is E2 80 A9\n                         */\n                    case 0xE2:\n                        if (i + 2 < _input.length &&\n                            _input[i + 1] == 0x80 &&\n                            (_input[i + 2] == 0xA8 || _input[i + 2] == 0xA9)\n                        )\n                        {\n                            iEnd = i + (keepTerm == Yes.keepTerminator) * 3;\n                            iNext = i + 3;\n                            break Loop;\n                        }\n                        else\n                            goto default;\n                        /* Manually decode:\n                         *  NEL is C2 85\n                         */\n                    case 0xC2:\n                        if (i + 1 < _input.length && _input[i + 1] == 0x85)\n                        {\n                            iEnd = i + (keepTerm == Yes.keepTerminator) * 2;\n                            iNext = i + 2;\n                            break Loop;\n                        }\n                        else\n                            goto default;\n                    }\n                    else\n                    {\n                    case '\\u0085':\n                    case lineSep:\n                    case paraSep:\n                        goto case '\\n';\n                    }\n\n                default:\n                    break;\n                }\n            }\n        }\n        return _input[iStart .. iEnd];\n    }\n\n    void popFront()\n    {\n        if (iStart == _unComputed)\n        {\n            assert(!empty);\n            front;\n        }\n        iStart = _unComputed;\n    }\n\n    static if (isForwardRange!Range)\n    {\n        @property typeof(this) save()\n        {\n            auto ret = this;\n            ret._input = _input.save;\n            return ret;\n        }\n    }\n}\n\n/***********************************\n *  Split an array or slicable range of characters into a range of lines\n    using `'\\r'`, `'\\n'`, `'\\v'`, `'\\f'`, `\"\\r\\n\"`,\n    $(REF lineSep, std,uni), $(REF paraSep, std,uni) and `'\\u0085'` (NEL)\n    as delimiters. If `keepTerm` is set to `Yes.keepTerminator`, then the\n    delimiter is included in the slices returned.\n\n    Does not throw on invalid UTF; such is simply passed unchanged\n    to the output.\n\n    Adheres to $(HTTP www.unicode.org/versions/Unicode7.0.0/ch05.pdf, Unicode 7.0).\n\n    Does not allocate memory.\n\n  Params:\n    r = array of `chars`, `wchars`, or `dchars` or a slicable range\n    keepTerm = whether delimiter is included or not in the results\n  Returns:\n    range of slices of the input range `r`\n\n  See_Also:\n    $(LREF splitLines)\n    $(REF splitter, std,algorithm)\n    $(REF splitter, std,regex)\n */\nauto lineSplitter(KeepTerminator keepTerm = No.keepTerminator, Range)(Range r)\nif (hasSlicing!Range && hasLength!Range && isSomeChar!(ElementType!Range) && !isSomeString!Range)\n{\n    return LineSplitter!(keepTerm, Range)(r);\n}\n\n/// Ditto\nauto lineSplitter(KeepTerminator keepTerm = No.keepTerminator, C)(C[] r)\nif (isSomeChar!C)\n{\n    return LineSplitter!(keepTerm, C[])(r);\n}\n\n///\n@safe pure unittest\n{\n    import std.array : array;\n\n    string s = \"Hello\\nmy\\rname\\nis\";\n\n    /* notice the call to 'array' to turn the lazy range created by\n    lineSplitter comparable to the string[] created by splitLines.\n    */\n    assert(lineSplitter(s).array == splitLines(s));\n}\n\n@safe pure unittest\n{\n    import std.array : array;\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n    {{\n        auto s = to!S(\n            \"\\rpeter\\n\\rpaul\\r\\njerry\\u2028ice\\u2029cream\\n\\n\" ~\n            \"sunday\\nmon\\u2030day\\nschadenfreude\\vkindergarten\\f\\vcookies\\u0085\"\n        );\n\n        auto lines = lineSplitter(s).array;\n        assert(lines.length == 14);\n        assert(lines[0] == \"\");\n        assert(lines[1] == \"peter\");\n        assert(lines[2] == \"\");\n        assert(lines[3] == \"paul\");\n        assert(lines[4] == \"jerry\");\n        assert(lines[5] == \"ice\");\n        assert(lines[6] == \"cream\");\n        assert(lines[7] == \"\");\n        assert(lines[8] == \"sunday\");\n        assert(lines[9] == \"mon\\u2030day\");\n        assert(lines[10] == \"schadenfreude\");\n        assert(lines[11] == \"kindergarten\");\n        assert(lines[12] == \"\");\n        assert(lines[13] == \"cookies\");\n\n\n        ubyte[] u = ['a', 0xFF, 0x12, 'b'];     // invalid UTF\n        auto ulines = lineSplitter(cast(char[]) u).array;\n        assert(cast(ubyte[])(ulines[0]) == u);\n\n        lines = lineSplitter!(Yes.keepTerminator)(s).array;\n        assert(lines.length == 14);\n        assert(lines[0] == \"\\r\");\n        assert(lines[1] == \"peter\\n\");\n        assert(lines[2] == \"\\r\");\n        assert(lines[3] == \"paul\\r\\n\");\n        assert(lines[4] == \"jerry\\u2028\");\n        assert(lines[5] == \"ice\\u2029\");\n        assert(lines[6] == \"cream\\n\");\n        assert(lines[7] == \"\\n\");\n        assert(lines[8] == \"sunday\\n\");\n        assert(lines[9] == \"mon\\u2030day\\n\");\n        assert(lines[10] == \"schadenfreude\\v\");\n        assert(lines[11] == \"kindergarten\\f\");\n        assert(lines[12] == \"\\v\");\n        assert(lines[13] == \"cookies\\u0085\");\n\n        s.popBack(); // Lop-off trailing \\n\n        lines = lineSplitter(s).array;\n        assert(lines.length == 14);\n        assert(lines[9] == \"mon\\u2030day\");\n\n        lines = lineSplitter!(Yes.keepTerminator)(s).array;\n        assert(lines.length == 14);\n        assert(lines[13] == \"cookies\");\n    }}\n    });\n}\n\n///\n@nogc @safe pure unittest\n{\n    auto s = \"\\rpeter\\n\\rpaul\\r\\njerry\\u2028ice\\u2029cream\\n\\nsunday\\nmon\\u2030day\\n\";\n    auto lines = s.lineSplitter();\n    static immutable witness = [\"\", \"peter\", \"\", \"paul\", \"jerry\", \"ice\", \"cream\", \"\", \"sunday\", \"mon\\u2030day\"];\n    uint i;\n    foreach (line; lines)\n    {\n        assert(line == witness[i++]);\n    }\n    assert(i == witness.length);\n}\n\n@nogc @safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : only;\n\n    auto s = \"std/string.d\";\n    auto as = TestAliasedString(s);\n    assert(equal(s.lineSplitter(), as.lineSplitter()));\n\n    enum S : string { a = \"hello\\nworld\" }\n    assert(equal(S.a.lineSplitter(), only(\"hello\", \"world\")));\n\n    char[S.a.length] sa = S.a[];\n    assert(equal(sa.lineSplitter(), only(\"hello\", \"world\")));\n}\n\n@safe pure unittest\n{\n    auto s = \"line1\\nline2\";\n    auto spl0 = s.lineSplitter!(Yes.keepTerminator);\n    auto spl1 = spl0.save;\n    spl0.popFront;\n    assert(spl1.front ~ spl0.front == s);\n    string r = \"a\\xC2\\x86b\";\n    assert(r.lineSplitter.front == r);\n}\n\n/++\n    Strips leading whitespace (as defined by $(REF isWhite, std,uni)) or\n    as specified in the second argument.\n\n    Params:\n        input = string or $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n        of characters\n        chars = string of characters to be stripped\n\n    Returns: `input` stripped of leading whitespace or characters\n    specified in the second argument.\n\n    Postconditions: `input` and the returned value\n    will share the same tail (see $(REF sameTail, std,array)).\n\n    See_Also:\n        Generic stripping on ranges: $(REF _stripLeft, std, algorithm, mutation)\n  +/\nauto stripLeft(Range)(Range input)\nif (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) &&\n    !isInfinite!Range && !isConvertibleToString!Range)\n{\n    static import std.ascii;\n    static import std.uni;\n\n    static if (is(Unqual!(ElementEncodingType!Range) == dchar)\n        || is(Unqual!(ElementEncodingType!Range) == wchar))\n    {\n        // Decoding is never needed for dchar. It happens not to be needed\n        // here for wchar because no whitepace is outside the basic\n        // multilingual plane meaning every whitespace character is encoded\n        // with a single wchar and due to the design of UTF-16 those wchars\n        // will not occur as part of the encoding of multi-wchar codepoints.\n        static if (isDynamicArray!Range)\n        {\n            foreach (i; 0 .. input.length)\n            {\n                if (!std.uni.isWhite(input[i]))\n                    return input[i .. $];\n            }\n            return input[$ .. $];\n        }\n        else\n        {\n            while (!input.empty)\n            {\n                if (!std.uni.isWhite(input.front))\n                    break;\n                input.popFront();\n            }\n            return input;\n        }\n    }\n    else\n    {\n        static if (isDynamicArray!Range)\n        {\n            // ASCII optimization for dynamic arrays.\n            size_t i = 0;\n            for (const size_t end = input.length; i < end; ++i)\n            {\n                auto c = input[i];\n                if (c >= 0x80) goto NonAsciiPath;\n                if (!std.ascii.isWhite(c)) break;\n            }\n            input = input[i .. $];\n            return input;\n\n        NonAsciiPath:\n            input = input[i .. $];\n            // Fall through to standard case.\n        }\n\n        static if (ElementType!Range.sizeof > ElementEncodingType!Range.sizeof)\n        {\n            // Type performs its own decoding.\n            while (!input.empty)\n            {\n                if (!std.uni.isWhite(input.front))\n                    break;\n                input.popFront();\n            }\n            return input;\n        }\n        else\n        {\n            // Type doesn't perform its own decoding.\n            import std.utf : decodeFront, UseReplacementDchar;\n            while (!input.empty)\n            {\n                auto c = input.front;\n                if (std.ascii.isASCII(c))\n                {\n                    if (!std.ascii.isWhite(c))\n                        break;\n                    input.popFront();\n                }\n                else\n                {\n                    auto save = input.save;\n                    auto dc = decodeFront!(UseReplacementDchar.yes)(input);\n                    if (!std.uni.isWhite(dc))\n                        return save;\n                }\n            }\n            return input;\n        }\n    }\n}\n\n///\n@safe pure unittest\n{\n    import std.uni : lineSep, paraSep;\n    assert(stripLeft(\"     hello world     \") ==\n           \"hello world     \");\n    assert(stripLeft(\"\\n\\t\\v\\rhello world\\n\\t\\v\\r\") ==\n           \"hello world\\n\\t\\v\\r\");\n    assert(stripLeft(\" \\u2028hello world\") ==\n           \"hello world\");\n    assert(stripLeft(\"hello world\") ==\n           \"hello world\");\n    assert(stripLeft([lineSep] ~ \"hello world\" ~ lineSep) ==\n           \"hello world\" ~ [lineSep]);\n    assert(stripLeft([paraSep] ~ \"hello world\" ~ paraSep) ==\n           \"hello world\" ~ [paraSep]);\n\n    import std.array : array;\n    import std.utf : byChar;\n    assert(stripLeft(\"     hello world     \"w.byChar).array ==\n           \"hello world     \");\n    assert(stripLeft(\"     \\u2022hello world     \".byChar).array ==\n           \"\\u2022hello world     \");\n}\n\nauto stripLeft(Range)(auto ref Range str)\nif (isConvertibleToString!Range)\n{\n    return stripLeft!(StringTypeOf!Range)(str);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!stripLeft(\"  hello\"));\n}\n\n/// Ditto\nauto stripLeft(Range, Char)(Range input, const(Char)[] chars)\nif (((isForwardRange!Range && isSomeChar!(ElementEncodingType!Range)) ||\n     isConvertibleToString!Range) && isSomeChar!Char)\n{\n    static if (isConvertibleToString!Range)\n        return stripLeft!(StringTypeOf!Range)(input, chars);\n    else\n    {\n        for (; !input.empty; input.popFront)\n        {\n            if (chars.indexOf(input.front) == -1)\n                break;\n        }\n        return input;\n    }\n}\n\n///\n@safe pure unittest\n{\n    assert(stripLeft(\"     hello world     \", \" \") ==\n           \"hello world     \");\n    assert(stripLeft(\"xxxxxhello world     \", \"x\") ==\n           \"hello world     \");\n    assert(stripLeft(\"xxxyy    hello world     \", \"xy \") ==\n           \"hello world     \");\n}\n\n///\n@safe pure unittest\n{\n    import std.array : array;\n    import std.utf : byChar, byWchar, byDchar;\n\n    assert(stripLeft(\"  xxxyy hello world     \"w.byChar, \"xy \").array ==\n           \"hello world     \");\n\n    assert(stripLeft(\"\\u2028\\u2020hello world\\u2028\"w.byWchar,\n                     \"\\u2028\").array == \"\\u2020hello world\\u2028\");\n    assert(stripLeft(\"\\U00010001hello world\"w.byWchar, \" \").array ==\n           \"\\U00010001hello world\"w);\n    assert(stripLeft(\"\\U00010001 xyhello world\"d.byDchar,\n                     \"\\U00010001 xy\").array == \"hello world\"d);\n\n    assert(stripLeft(\"\\u2020hello\"w, \"\\u2020\"w) == \"hello\"w);\n    assert(stripLeft(\"\\U00010001hello\"d, \"\\U00010001\"d) == \"hello\"d);\n    assert(stripLeft(\" hello \", \"\") == \" hello \");\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!stripLeft(\" xyz  hello\", \"xyz \"));\n}\n\n/++\n    Strips trailing whitespace (as defined by $(REF isWhite, std,uni)) or\n    as specified in the second argument.\n\n    Params:\n        str = string or random access range of characters\n        chars = string of characters to be stripped\n\n    Returns:\n        slice of `str` stripped of trailing whitespace or characters\n        specified in the second argument.\n\n    See_Also:\n        Generic stripping on ranges: $(REF _stripRight, std, algorithm, mutation)\n  +/\nauto stripRight(Range)(Range str)\nif (isSomeString!Range ||\n    isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range &&\n    !isConvertibleToString!Range &&\n    isSomeChar!(ElementEncodingType!Range))\n{\n    import std.uni : isWhite;\n    alias C = Unqual!(ElementEncodingType!(typeof(str)));\n\n    static if (isSomeString!(typeof(str)))\n    {\n        import std.utf : codeLength;\n\n        foreach_reverse (i, dchar c; str)\n        {\n            if (!isWhite(c))\n                return str[0 .. i + codeLength!C(c)];\n        }\n\n        return str[0 .. 0];\n    }\n    else\n    {\n        size_t i = str.length;\n        while (i--)\n        {\n            static if (C.sizeof == 4)\n            {\n                if (isWhite(str[i]))\n                    continue;\n                break;\n            }\n            else static if (C.sizeof == 2)\n            {\n                auto c2 = str[i];\n                if (c2 < 0xD800 || c2 >= 0xE000)\n                {\n                    if (isWhite(c2))\n                        continue;\n                }\n                else if (c2 >= 0xDC00)\n                {\n                    if (i)\n                    {\n                        immutable c1 = str[i - 1];\n                        if (c1 >= 0xD800 && c1 < 0xDC00)\n                        {\n                            immutable dchar c = ((c1 - 0xD7C0) << 10) + (c2 - 0xDC00);\n                            if (isWhite(c))\n                            {\n                                --i;\n                                continue;\n                            }\n                        }\n                    }\n                }\n                break;\n            }\n            else static if (C.sizeof == 1)\n            {\n                import std.utf : byDchar;\n\n                char cx = str[i];\n                if (cx <= 0x7F)\n                {\n                    if (isWhite(cx))\n                        continue;\n                    break;\n                }\n                else\n                {\n                    size_t stride = 0;\n\n                    while (1)\n                    {\n                        ++stride;\n                        if (!i || (cx & 0xC0) == 0xC0 || stride == 4)\n                            break;\n                        cx = str[i - 1];\n                        if (!(cx & 0x80))\n                            break;\n                        --i;\n                    }\n\n                    if (!str[i .. i + stride].byDchar.front.isWhite)\n                        return str[0 .. i + stride];\n                }\n            }\n            else\n                static assert(0);\n        }\n\n        return str[0 .. i + 1];\n    }\n}\n\n///\n@safe pure\nunittest\n{\n    import std.uni : lineSep, paraSep;\n    assert(stripRight(\"     hello world     \") ==\n           \"     hello world\");\n    assert(stripRight(\"\\n\\t\\v\\rhello world\\n\\t\\v\\r\") ==\n           \"\\n\\t\\v\\rhello world\");\n    assert(stripRight(\"hello world\") ==\n           \"hello world\");\n    assert(stripRight([lineSep] ~ \"hello world\" ~ lineSep) ==\n           [lineSep] ~ \"hello world\");\n    assert(stripRight([paraSep] ~ \"hello world\" ~ paraSep) ==\n           [paraSep] ~ \"hello world\");\n}\n\nauto stripRight(Range)(auto ref Range str)\nif (isConvertibleToString!Range)\n{\n    return stripRight!(StringTypeOf!Range)(str);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!stripRight(\"hello   \"));\n}\n\n@safe pure unittest\n{\n    import std.array : array;\n    import std.uni : lineSep, paraSep;\n    import std.utf : byChar, byDchar, byUTF, byWchar, invalidUTFstrings;\n    assert(stripRight(\"     hello world     \".byChar).array == \"     hello world\");\n    assert(stripRight(\"\\n\\t\\v\\rhello world\\n\\t\\v\\r\"w.byWchar).array == \"\\n\\t\\v\\rhello world\"w);\n    assert(stripRight(\"hello world\"d.byDchar).array == \"hello world\"d);\n    assert(stripRight(\"\\u2028hello world\\u2020\\u2028\".byChar).array == \"\\u2028hello world\\u2020\");\n    assert(stripRight(\"hello world\\U00010001\"w.byWchar).array == \"hello world\\U00010001\"w);\n\n    static foreach (C; AliasSeq!(char, wchar, dchar))\n    {\n        foreach (s; invalidUTFstrings!C())\n        {\n            cast(void) stripRight(s.byUTF!C).array;\n        }\n    }\n\n    cast(void) stripRight(\"a\\x80\".byUTF!char).array;\n    wstring ws = ['a', cast(wchar) 0xDC00];\n    cast(void) stripRight(ws.byUTF!wchar).array;\n}\n\n/// Ditto\nauto stripRight(Range, Char)(Range str, const(Char)[] chars)\nif (((isBidirectionalRange!Range && isSomeChar!(ElementEncodingType!Range)) ||\n     isConvertibleToString!Range) && isSomeChar!Char)\n{\n    static if (isConvertibleToString!Range)\n        return stripRight!(StringTypeOf!Range)(str, chars);\n    else\n    {\n        for (; !str.empty; str.popBack)\n        {\n            if (chars.indexOf(str.back) == -1)\n                break;\n        }\n        return str;\n    }\n}\n\n///\n@safe pure\nunittest\n{\n    assert(stripRight(\"     hello world     \", \"x\") ==\n           \"     hello world     \");\n    assert(stripRight(\"     hello world     \", \" \") ==\n           \"     hello world\");\n    assert(stripRight(\"     hello worldxy     \", \"xy \") ==\n           \"     hello world\");\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!stripRight(\"hello xyz  \", \"xyz \"));\n}\n\n@safe pure unittest\n{\n    import std.array : array;\n    import std.utf : byChar, byDchar, byUTF, byWchar;\n\n    assert(stripRight(\"     hello world  xyz   \".byChar,\n                      \"xyz \").array == \"     hello world\");\n    assert(stripRight(\"\\u2028hello world\\u2020\\u2028\"w.byWchar,\n                      \"\\u2028\").array == \"\\u2028hello world\\u2020\");\n    assert(stripRight(\"hello world\\U00010001\"w.byWchar,\n                      \" \").array == \"hello world\\U00010001\"w);\n    assert(stripRight(\"hello world\\U00010001 xy\"d.byDchar,\n                      \"\\U00010001 xy\").array == \"hello world\"d);\n    assert(stripRight(\"hello\\u2020\"w, \"\\u2020\"w) == \"hello\"w);\n    assert(stripRight(\"hello\\U00010001\"d, \"\\U00010001\"d) == \"hello\"d);\n    assert(stripRight(\" hello \", \"\") == \" hello \");\n}\n\n\n/++\n    Strips both leading and trailing whitespace (as defined by\n    $(REF isWhite, std,uni)) or as specified in the second argument.\n\n    Params:\n        str = string or random access range of characters\n        chars = string of characters to be stripped\n        leftChars = string of leading characters to be stripped\n        rightChars = string of trailing characters to be stripped\n\n    Returns:\n        slice of `str` stripped of leading and trailing whitespace\n        or characters as specified in the second argument.\n\n    See_Also:\n        Generic stripping on ranges: $(REF _strip, std, algorithm, mutation)\n  +/\nauto strip(Range)(Range str)\nif (isSomeString!Range ||\n    isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range &&\n    !isConvertibleToString!Range &&\n    isSomeChar!(ElementEncodingType!Range))\n{\n    return stripRight(stripLeft(str));\n}\n\n///\n@safe pure unittest\n{\n    import std.uni : lineSep, paraSep;\n    assert(strip(\"     hello world     \") ==\n           \"hello world\");\n    assert(strip(\"\\n\\t\\v\\rhello world\\n\\t\\v\\r\") ==\n           \"hello world\");\n    assert(strip(\"hello world\") ==\n           \"hello world\");\n    assert(strip([lineSep] ~ \"hello world\" ~ [lineSep]) ==\n           \"hello world\");\n    assert(strip([paraSep] ~ \"hello world\" ~ [paraSep]) ==\n           \"hello world\");\n}\n\nauto strip(Range)(auto ref Range str)\nif (isConvertibleToString!Range)\n{\n    return strip!(StringTypeOf!Range)(str);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!strip(\"     hello world     \"));\n}\n\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!( char[], const  char[],  string,\n                          wchar[], const wchar[], wstring,\n                          dchar[], const dchar[], dstring))\n    {\n        assert(equal(stripLeft(to!S(\"  foo\\t \")), \"foo\\t \"));\n        assert(equal(stripLeft(to!S(\"\\u2008  foo\\t \\u2007\")), \"foo\\t \\u2007\"));\n        assert(equal(stripLeft(to!S(\"\\u0085 μ \\u0085 \\u00BB \\r\")), \"μ \\u0085 \\u00BB \\r\"));\n        assert(equal(stripLeft(to!S(\"1\")), \"1\"));\n        assert(equal(stripLeft(to!S(\"\\U0010FFFE\")), \"\\U0010FFFE\"));\n        assert(equal(stripLeft(to!S(\"\")), \"\"));\n\n        assert(equal(stripRight(to!S(\"  foo\\t \")), \"  foo\"));\n        assert(equal(stripRight(to!S(\"\\u2008  foo\\t \\u2007\")), \"\\u2008  foo\"));\n        assert(equal(stripRight(to!S(\"\\u0085 μ \\u0085 \\u00BB \\r\")), \"\\u0085 μ \\u0085 \\u00BB\"));\n        assert(equal(stripRight(to!S(\"1\")), \"1\"));\n        assert(equal(stripRight(to!S(\"\\U0010FFFE\")), \"\\U0010FFFE\"));\n        assert(equal(stripRight(to!S(\"\")), \"\"));\n\n        assert(equal(strip(to!S(\"  foo\\t \")), \"foo\"));\n        assert(equal(strip(to!S(\"\\u2008  foo\\t \\u2007\")), \"foo\"));\n        assert(equal(strip(to!S(\"\\u0085 μ \\u0085 \\u00BB \\r\")), \"μ \\u0085 \\u00BB\"));\n        assert(equal(strip(to!S(\"\\U0010FFFE\")), \"\\U0010FFFE\"));\n        assert(equal(strip(to!S(\"\")), \"\"));\n    }\n    });\n}\n\n@safe pure unittest\n{\n    import std.array : sameHead, sameTail;\n    import std.exception : assertCTFEable;\n    assertCTFEable!(\n    {\n    wstring s = \" \";\n    assert(s.sameTail(s.stripLeft()));\n    assert(s.sameHead(s.stripRight()));\n    });\n}\n\n/// Ditto\nauto strip(Range, Char)(Range str, const(Char)[] chars)\nif (((isBidirectionalRange!Range && isSomeChar!(ElementEncodingType!Range)) ||\n     isConvertibleToString!Range) && isSomeChar!Char)\n{\n    static if (isConvertibleToString!Range)\n        return strip!(StringTypeOf!Range)(str, chars);\n    else\n        return stripRight(stripLeft(str, chars), chars);\n}\n\n///\n@safe pure unittest\n{\n    assert(strip(\"     hello world     \", \"x\") ==\n           \"     hello world     \");\n    assert(strip(\"     hello world     \", \" \") ==\n           \"hello world\");\n    assert(strip(\"   xyxyhello worldxyxy     \", \"xy \") ==\n           \"hello world\");\n    assert(strip(\"\\u2020hello\\u2020\"w, \"\\u2020\"w) == \"hello\"w);\n    assert(strip(\"\\U00010001hello\\U00010001\"d, \"\\U00010001\"d) == \"hello\"d);\n    assert(strip(\" hello \", \"\") == \" hello \");\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!strip(\"  xyz   hello world  xyz   \", \"xyz \"));\n}\n\n/// Ditto\nauto strip(Range, Char)(Range str, const(Char)[] leftChars, const(Char)[] rightChars)\nif (((isBidirectionalRange!Range && isSomeChar!(ElementEncodingType!Range)) ||\n     isConvertibleToString!Range) && isSomeChar!Char)\n{\n    static if (isConvertibleToString!Range)\n        return strip!(StringTypeOf!Range)(str, leftChars, rightChars);\n    else\n        return stripRight(stripLeft(str, leftChars), rightChars);\n}\n\n///\n@safe pure unittest\n{\n    assert(strip(\"xxhelloyy\", \"x\", \"y\") == \"hello\");\n    assert(strip(\"   xyxyhello worldxyxyzz    \", \"xy \", \"xyz \") ==\n           \"hello world\");\n    assert(strip(\"\\u2020hello\\u2028\"w, \"\\u2020\"w, \"\\u2028\"w) == \"hello\"w);\n    assert(strip(\"\\U00010001hello\\U00010002\"d, \"\\U00010001\"d, \"\\U00010002\"d) ==\n           \"hello\"d);\n    assert(strip(\" hello \", \"\", \"\") == \" hello \");\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!strip(\"  xy   hello world  pq   \", \"xy \", \"pq \"));\n}\n\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!( char[], const  char[],  string,\n                          wchar[], const wchar[], wstring,\n                          dchar[], const dchar[], dstring))\n    {\n        assert(equal(stripLeft(to!S(\"  \\tfoo\\t \"), \"\\t \"), \"foo\\t \"));\n        assert(equal(stripLeft(to!S(\"\\u2008  foo\\t \\u2007\"), \"\\u2008 \"),\n                     \"foo\\t \\u2007\"));\n        assert(equal(stripLeft(to!S(\"\\u0085 μ \\u0085 \\u00BB \\r\"), \"\\u0085 \"),\n                     \"μ \\u0085 \\u00BB \\r\"));\n        assert(equal(stripLeft(to!S(\"1\"), \" \"), \"1\"));\n        assert(equal(stripLeft(to!S(\"\\U0010FFFE\"), \" \"), \"\\U0010FFFE\"));\n        assert(equal(stripLeft(to!S(\"\"), \" \"), \"\"));\n\n        assert(equal(stripRight(to!S(\"  foo\\t \"), \"\\t \"), \"  foo\"));\n        assert(equal(stripRight(to!S(\"\\u2008  foo\\t \\u2007\"), \"\\u2007\\t \"),\n                     \"\\u2008  foo\"));\n        assert(equal(stripRight(to!S(\"\\u0085 μ \\u0085 \\u00BB \\r\"), \"\\r \"),\n                     \"\\u0085 μ \\u0085 \\u00BB\"));\n        assert(equal(stripRight(to!S(\"1\"), \" \"), \"1\"));\n        assert(equal(stripRight(to!S(\"\\U0010FFFE\"), \" \"), \"\\U0010FFFE\"));\n        assert(equal(stripRight(to!S(\"\"), \" \"), \"\"));\n\n        assert(equal(strip(to!S(\"  foo\\t \"), \"\\t \"), \"foo\"));\n        assert(equal(strip(to!S(\"\\u2008  foo\\t \\u2007\"), \"\\u2008\\u2007\\t \"),\n                     \"foo\"));\n        assert(equal(strip(to!S(\"\\u0085 μ \\u0085 \\u00BB \\r\"), \"\\u0085\\r \"),\n                     \"μ \\u0085 \\u00BB\"));\n        assert(equal(strip(to!S(\"\\U0010FFFE\"), \" \"), \"\\U0010FFFE\"));\n        assert(equal(strip(to!S(\"\"), \" \"), \"\"));\n\n        assert(equal(strip(to!S(\"  \\nfoo\\t \"), \"\\n \", \"\\t \"), \"foo\"));\n        assert(equal(strip(to!S(\"\\u2008\\n  foo\\t \\u2007\"),\n                           \"\\u2008\\n \", \"\\u2007\\t \"), \"foo\"));\n        assert(equal(strip(to!S(\"\\u0085 μ \\u0085 \\u00BB μ \\u00BB\\r\"),\n                           \"\\u0085 \", \"\\u00BB\\r \"), \"μ \\u0085 \\u00BB μ\"));\n        assert(equal(strip(to!S(\"\\U0010FFFE\"), \" \", \" \"), \"\\U0010FFFE\"));\n        assert(equal(strip(to!S(\"\"), \" \", \" \"), \"\"));\n    }\n    });\n}\n\n@safe pure unittest\n{\n    import std.array : sameHead, sameTail;\n    import std.exception : assertCTFEable;\n    assertCTFEable!(\n    {\n    wstring s = \" xyz \";\n    assert(s.sameTail(s.stripLeft(\" \")));\n    assert(s.sameHead(s.stripRight(\" \")));\n    });\n}\n\n\n/++\n    If `str` ends with `delimiter`, then `str` is returned without\n    `delimiter` on its end. If it `str` does $(I not) end with\n    `delimiter`, then it is returned unchanged.\n\n    If no `delimiter` is given, then one trailing  `'\\r'`, `'\\n'`,\n    `\"\\r\\n\"`, `'\\f'`, `'\\v'`, $(REF lineSep, std,uni), $(REF paraSep, std,uni), or $(REF nelSep, std,uni)\n    is removed from the end of `str`. If `str` does not end with any of those characters,\n    then it is returned unchanged.\n\n    Params:\n        str = string or indexable range of characters\n        delimiter = string of characters to be sliced off end of str[]\n\n    Returns:\n        slice of str\n  +/\nRange chomp(Range)(Range str)\nif ((isRandomAccessRange!Range && isSomeChar!(ElementEncodingType!Range) ||\n    isNarrowString!Range) &&\n    !isConvertibleToString!Range)\n{\n    import std.uni : lineSep, paraSep, nelSep;\n    if (str.empty)\n        return str;\n\n    alias C = ElementEncodingType!Range;\n\n    switch (str[$ - 1])\n    {\n        case '\\n':\n        {\n            if (str.length > 1 && str[$ - 2] == '\\r')\n                return str[0 .. $ - 2];\n            goto case;\n        }\n        case '\\r', '\\v', '\\f':\n            return str[0 .. $ - 1];\n\n        // Pop off the last character if lineSep, paraSep, or nelSep\n        static if (is(C : const char))\n        {\n            /* Manually decode:\n             *  lineSep is E2 80 A8\n             *  paraSep is E2 80 A9\n             */\n            case 0xA8: // Last byte of lineSep\n            case 0xA9: // Last byte of paraSep\n                if (str.length > 2 && str[$ - 2] == 0x80 && str[$ - 3] == 0xE2)\n                    return str [0 .. $ - 3];\n                goto default;\n\n            /* Manually decode:\n             *  NEL is C2 85\n             */\n            case 0x85:\n                if (str.length > 1 && str[$ - 2] == 0xC2)\n                    return str [0 .. $ - 2];\n                goto default;\n        }\n        else\n        {\n            case lineSep:\n            case paraSep:\n            case nelSep:\n                return str[0 .. $ - 1];\n        }\n        default:\n            return str;\n    }\n}\n\n/// Ditto\nRange chomp(Range, C2)(Range str, const(C2)[] delimiter)\nif ((isBidirectionalRange!Range && isSomeChar!(ElementEncodingType!Range) ||\n    isNarrowString!Range) &&\n    !isConvertibleToString!Range &&\n    isSomeChar!C2)\n{\n    if (delimiter.empty)\n        return chomp(str);\n\n    alias C1 = ElementEncodingType!Range;\n\n    static if (is(Unqual!C1 == Unqual!C2) && (isSomeString!Range || (hasSlicing!Range && C2.sizeof == 4)))\n    {\n        import std.algorithm.searching : endsWith;\n        if (str.endsWith(delimiter))\n            return str[0 .. $ - delimiter.length];\n        return str;\n    }\n    else\n    {\n        auto orig = str.save;\n\n        static if (isSomeString!Range)\n            alias C = dchar;    // because strings auto-decode\n        else\n            alias C = C1;       // and ranges do not\n\n        foreach_reverse (C c; delimiter)\n        {\n            if (str.empty || str.back != c)\n                return orig;\n\n            str.popBack();\n        }\n\n        return str;\n    }\n}\n\n///\n@safe pure\nunittest\n{\n    import std.uni : lineSep, paraSep, nelSep;\n    import std.utf : decode;\n    assert(chomp(\" hello world  \\n\\r\") == \" hello world  \\n\");\n    assert(chomp(\" hello world  \\r\\n\") == \" hello world  \");\n    assert(chomp(\" hello world  \\f\") == \" hello world  \");\n    assert(chomp(\" hello world  \\v\") == \" hello world  \");\n    assert(chomp(\" hello world  \\n\\n\") == \" hello world  \\n\");\n    assert(chomp(\" hello world  \\n\\n \") == \" hello world  \\n\\n \");\n    assert(chomp(\" hello world  \\n\\n\" ~ [lineSep]) == \" hello world  \\n\\n\");\n    assert(chomp(\" hello world  \\n\\n\" ~ [paraSep]) == \" hello world  \\n\\n\");\n    assert(chomp(\" hello world  \\n\\n\" ~ [ nelSep]) == \" hello world  \\n\\n\");\n    assert(chomp(\" hello world\") == \" hello world\");\n    assert(chomp(\"\") == \"\");\n\n    assert(chomp(\" hello world\", \"orld\") == \" hello w\");\n    assert(chomp(\" hello world\", \" he\") == \" hello world\");\n    assert(chomp(\"\", \"hello\") == \"\");\n\n    // Don't decode pointlessly\n    assert(chomp(\"hello\\xFE\", \"\\r\") == \"hello\\xFE\");\n}\n\nStringTypeOf!Range chomp(Range)(auto ref Range str)\nif (isConvertibleToString!Range)\n{\n    return chomp!(StringTypeOf!Range)(str);\n}\n\nStringTypeOf!Range chomp(Range, C2)(auto ref Range str, const(C2)[] delimiter)\nif (isConvertibleToString!Range)\n{\n    return chomp!(StringTypeOf!Range, C2)(str, delimiter);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!chomp(\" hello world  \\n\\r\"));\n    assert(testAliasedString!chomp(\" hello world\", \"orld\"));\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n    {\n        // @@@ BUG IN COMPILER, MUST INSERT CAST\n        assert(chomp(cast(S) null) is null);\n        assert(chomp(to!S(\"hello\")) == \"hello\");\n        assert(chomp(to!S(\"hello\\n\")) == \"hello\");\n        assert(chomp(to!S(\"hello\\r\")) == \"hello\");\n        assert(chomp(to!S(\"hello\\r\\n\")) == \"hello\");\n        assert(chomp(to!S(\"hello\\n\\r\")) == \"hello\\n\");\n        assert(chomp(to!S(\"hello\\n\\n\")) == \"hello\\n\");\n        assert(chomp(to!S(\"hello\\r\\r\")) == \"hello\\r\");\n        assert(chomp(to!S(\"hello\\nxxx\\n\")) == \"hello\\nxxx\");\n        assert(chomp(to!S(\"hello\\u2028\")) == \"hello\");\n        assert(chomp(to!S(\"hello\\u2029\")) == \"hello\");\n        assert(chomp(to!S(\"hello\\u0085\")) == \"hello\");\n        assert(chomp(to!S(\"hello\\u2028\\u2028\")) == \"hello\\u2028\");\n        assert(chomp(to!S(\"hello\\u2029\\u2029\")) == \"hello\\u2029\");\n        assert(chomp(to!S(\"hello\\u2029\\u2129\")) == \"hello\\u2029\\u2129\");\n        assert(chomp(to!S(\"hello\\u2029\\u0185\")) == \"hello\\u2029\\u0185\");\n\n        static foreach (T; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n        {\n            // @@@ BUG IN COMPILER, MUST INSERT CAST\n            assert(chomp(cast(S) null, cast(T) null) is null);\n            assert(chomp(to!S(\"hello\\n\"), cast(T) null) == \"hello\");\n            assert(chomp(to!S(\"hello\"), to!T(\"o\")) == \"hell\");\n            assert(chomp(to!S(\"hello\"), to!T(\"p\")) == \"hello\");\n            // @@@ BUG IN COMPILER, MUST INSERT CAST\n            assert(chomp(to!S(\"hello\"), cast(T) null) == \"hello\");\n            assert(chomp(to!S(\"hello\"), to!T(\"llo\")) == \"he\");\n            assert(chomp(to!S(\"\\uFF28ello\"), to!T(\"llo\")) == \"\\uFF28e\");\n            assert(chomp(to!S(\"\\uFF28el\\uFF4co\"), to!T(\"l\\uFF4co\")) == \"\\uFF28e\");\n        }\n    }\n    });\n\n    // Ranges\n    import std.array : array;\n    import std.utf : byChar, byWchar, byDchar;\n    assert(chomp(\"hello world\\r\\n\" .byChar ).array == \"hello world\");\n    assert(chomp(\"hello world\\r\\n\"w.byWchar).array == \"hello world\"w);\n    assert(chomp(\"hello world\\r\\n\"d.byDchar).array == \"hello world\"d);\n\n    assert(chomp(\"hello world\"d.byDchar, \"ld\").array == \"hello wor\"d);\n\n    assert(chomp(\"hello\\u2020\" .byChar , \"\\u2020\").array == \"hello\");\n    assert(chomp(\"hello\\u2020\"d.byDchar, \"\\u2020\"d).array == \"hello\"d);\n}\n\n\n/++\n    If `str` starts with `delimiter`, then the part of `str` following\n    `delimiter` is returned. If `str` does $(I not) start with\n\n    `delimiter`, then it is returned unchanged.\n\n    Params:\n        str = string or $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n        of characters\n        delimiter = string of characters to be sliced off front of str[]\n\n    Returns:\n        slice of str\n +/\nRange chompPrefix(Range, C2)(Range str, const(C2)[] delimiter)\nif ((isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) ||\n    isNarrowString!Range) &&\n    !isConvertibleToString!Range &&\n    isSomeChar!C2)\n{\n    alias C1 = ElementEncodingType!Range;\n\n    static if (is(Unqual!C1 == Unqual!C2) && (isSomeString!Range || (hasSlicing!Range && C2.sizeof == 4)))\n    {\n        import std.algorithm.searching : startsWith;\n        if (str.startsWith(delimiter))\n            return str[delimiter.length .. $];\n        return str;\n    }\n    else\n    {\n        auto orig = str.save;\n\n        static if (isSomeString!Range)\n            alias C = dchar;    // because strings auto-decode\n        else\n            alias C = C1;       // and ranges do not\n\n        foreach (C c; delimiter)\n        {\n            if (str.empty || str.front != c)\n                return orig;\n\n            str.popFront();\n        }\n\n        return str;\n    }\n}\n\n///\n@safe pure unittest\n{\n    assert(chompPrefix(\"hello world\", \"he\") == \"llo world\");\n    assert(chompPrefix(\"hello world\", \"hello w\") == \"orld\");\n    assert(chompPrefix(\"hello world\", \" world\") == \"hello world\");\n    assert(chompPrefix(\"\", \"hello\") == \"\");\n}\n\nStringTypeOf!Range chompPrefix(Range, C2)(auto ref Range str, const(C2)[] delimiter)\nif (isConvertibleToString!Range)\n{\n    return chompPrefix!(StringTypeOf!Range, C2)(str, delimiter);\n}\n\n@safe pure\nunittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n    {\n        static foreach (T; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n        {\n            assert(equal(chompPrefix(to!S(\"abcdefgh\"), to!T(\"abcde\")), \"fgh\"));\n            assert(equal(chompPrefix(to!S(\"abcde\"), to!T(\"abcdefgh\")), \"abcde\"));\n            assert(equal(chompPrefix(to!S(\"\\uFF28el\\uFF4co\"), to!T(\"\\uFF28el\\uFF4co\")), \"\"));\n            assert(equal(chompPrefix(to!S(\"\\uFF28el\\uFF4co\"), to!T(\"\\uFF28el\")), \"\\uFF4co\"));\n            assert(equal(chompPrefix(to!S(\"\\uFF28el\"), to!T(\"\\uFF28el\\uFF4co\")), \"\\uFF28el\"));\n        }\n    }\n    });\n\n    // Ranges\n    import std.array : array;\n    import std.utf : byChar, byWchar, byDchar;\n    assert(chompPrefix(\"hello world\" .byChar , \"hello\"d).array == \" world\");\n    assert(chompPrefix(\"hello world\"w.byWchar, \"hello\" ).array == \" world\"w);\n    assert(chompPrefix(\"hello world\"d.byDchar, \"hello\"w).array == \" world\"d);\n    assert(chompPrefix(\"hello world\"c.byDchar, \"hello\"w).array == \" world\"d);\n\n    assert(chompPrefix(\"hello world\"d.byDchar, \"lx\").array == \"hello world\"d);\n    assert(chompPrefix(\"hello world\"d.byDchar, \"hello world xx\").array == \"hello world\"d);\n\n    assert(chompPrefix(\"\\u2020world\" .byChar , \"\\u2020\").array == \"world\");\n    assert(chompPrefix(\"\\u2020world\"d.byDchar, \"\\u2020\"d).array == \"world\"d);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!chompPrefix(\"hello world\", \"hello\"));\n}\n\n/++\n    Returns `str` without its last character, if there is one. If `str`\n    ends with `\"\\r\\n\"`, then both are removed. If `str` is empty, then\n    it is returned unchanged.\n\n    Params:\n        str = string (must be valid UTF)\n    Returns:\n        slice of str\n +/\n\nRange chop(Range)(Range str)\nif ((isBidirectionalRange!Range && isSomeChar!(ElementEncodingType!Range) ||\n    isNarrowString!Range) &&\n    !isConvertibleToString!Range)\n{\n    if (str.empty)\n        return str;\n\n    static if (isSomeString!Range)\n    {\n        if (str.length >= 2 && str[$ - 1] == '\\n' && str[$ - 2] == '\\r')\n            return str[0 .. $ - 2];\n        str.popBack();\n        return str;\n    }\n    else\n    {\n        alias C = Unqual!(ElementEncodingType!Range);\n        C c = str.back;\n        str.popBack();\n        if (c == '\\n')\n        {\n            if (!str.empty && str.back == '\\r')\n                str.popBack();\n            return str;\n        }\n        // Pop back a dchar, not just a code unit\n        static if (C.sizeof == 1)\n        {\n            int cnt = 1;\n            while ((c & 0xC0) == 0x80)\n            {\n                if (str.empty)\n                    break;\n                c = str.back;\n                str.popBack();\n                if (++cnt > 4)\n                    break;\n            }\n        }\n        else static if (C.sizeof == 2)\n        {\n            if (c >= 0xD800 && c <= 0xDBFF)\n            {\n                if (!str.empty)\n                    str.popBack();\n            }\n        }\n        else static if (C.sizeof == 4)\n        {\n        }\n        else\n            static assert(0);\n        return str;\n    }\n}\n\n///\n@safe pure unittest\n{\n    assert(chop(\"hello world\") == \"hello worl\");\n    assert(chop(\"hello world\\n\") == \"hello world\");\n    assert(chop(\"hello world\\r\") == \"hello world\");\n    assert(chop(\"hello world\\n\\r\") == \"hello world\\n\");\n    assert(chop(\"hello world\\r\\n\") == \"hello world\");\n    assert(chop(\"Walter Bright\") == \"Walter Brigh\");\n    assert(chop(\"\") == \"\");\n}\n\nStringTypeOf!Range chop(Range)(auto ref Range str)\nif (isConvertibleToString!Range)\n{\n    return chop!(StringTypeOf!Range)(str);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!chop(\"hello world\"));\n}\n\n@safe pure unittest\n{\n    import std.array : array;\n    import std.utf : byChar, byWchar, byDchar, byCodeUnit, invalidUTFstrings;\n\n    assert(chop(\"hello world\".byChar).array == \"hello worl\");\n    assert(chop(\"hello world\\n\"w.byWchar).array == \"hello world\"w);\n    assert(chop(\"hello world\\r\"d.byDchar).array == \"hello world\"d);\n    assert(chop(\"hello world\\n\\r\".byChar).array == \"hello world\\n\");\n    assert(chop(\"hello world\\r\\n\"w.byWchar).array == \"hello world\"w);\n    assert(chop(\"Walter Bright\"d.byDchar).array == \"Walter Brigh\"d);\n    assert(chop(\"\".byChar).array == \"\");\n\n    assert(chop(`ミツバチと科学者` .byCodeUnit).array == \"ミツバチと科学\");\n    assert(chop(`ミツバチと科学者`w.byCodeUnit).array == \"ミツバチと科学\"w);\n    assert(chop(`ミツバチと科学者`d.byCodeUnit).array == \"ミツバチと科学\"d);\n\n    auto ca = invalidUTFstrings!char();\n    foreach (s; ca)\n    {\n        foreach (c; chop(s.byCodeUnit))\n        {\n        }\n    }\n\n    auto wa = invalidUTFstrings!wchar();\n    foreach (s; wa)\n    {\n        foreach (c; chop(s.byCodeUnit))\n        {\n        }\n    }\n}\n\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n    {\n        assert(chop(cast(S) null) is null);\n        assert(equal(chop(to!S(\"hello\")), \"hell\"));\n        assert(equal(chop(to!S(\"hello\\r\\n\")), \"hello\"));\n        assert(equal(chop(to!S(\"hello\\n\\r\")), \"hello\\n\"));\n        assert(equal(chop(to!S(\"Verité\")), \"Verit\"));\n        assert(equal(chop(to!S(`さいごの果実`)), \"さいごの果\"));\n        assert(equal(chop(to!S(`ミツバチと科学者`)), \"ミツバチと科学\"));\n    }\n    });\n}\n\n\n/++\n    Left justify `s` in a field `width` characters wide. `fillChar`\n    is the character that will be used to fill up the space in the field that\n    `s` doesn't fill.\n\n    Params:\n        s = string\n        width = minimum field width\n        fillChar = used to pad end up to `width` characters\n\n    Returns:\n        GC allocated string\n\n    See_Also:\n        $(LREF leftJustifier), which does not allocate\n  +/\nS leftJustify(S)(S s, size_t width, dchar fillChar = ' ')\nif (isSomeString!S)\n{\n    import std.array : array;\n    return leftJustifier(s, width, fillChar).array;\n}\n\n///\n@safe pure unittest\n{\n    assert(leftJustify(\"hello\", 7, 'X') == \"helloXX\");\n    assert(leftJustify(\"hello\", 2, 'X') == \"hello\");\n    assert(leftJustify(\"hello\", 9, 'X') == \"helloXXXX\");\n}\n\n/++\n    Left justify `s` in a field `width` characters wide. `fillChar`\n    is the character that will be used to fill up the space in the field that\n    `s` doesn't fill.\n\n    Params:\n        r = string or range of characters\n        width = minimum field width\n        fillChar = used to pad end up to `width` characters\n\n    Returns:\n        a lazy range of the left justified result\n\n    See_Also:\n        $(LREF rightJustifier)\n  +/\n\nauto leftJustifier(Range)(Range r, size_t width, dchar fillChar = ' ')\nif (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) &&\n    !isConvertibleToString!Range)\n{\n    alias C = Unqual!(ElementEncodingType!Range);\n\n    static if (C.sizeof == 1)\n    {\n        import std.utf : byDchar, byChar;\n        return leftJustifier(r.byDchar, width, fillChar).byChar;\n    }\n    else static if (C.sizeof == 2)\n    {\n        import std.utf : byDchar, byWchar;\n        return leftJustifier(r.byDchar, width, fillChar).byWchar;\n    }\n    else static if (C.sizeof == 4)\n    {\n        static struct Result\n        {\n          private:\n            Range _input;\n            size_t _width;\n            dchar _fillChar;\n            size_t len;\n\n          public:\n\n            @property bool empty()\n            {\n                return len >= _width && _input.empty;\n            }\n\n            @property C front()\n            {\n                return _input.empty ? _fillChar : _input.front;\n            }\n\n            void popFront()\n            {\n                ++len;\n                if (!_input.empty)\n                    _input.popFront();\n            }\n\n            static if (isForwardRange!Range)\n            {\n                @property typeof(this) save() return scope\n                {\n                    auto ret = this;\n                    ret._input = _input.save;\n                    return ret;\n                }\n            }\n        }\n\n        return Result(r, width, fillChar);\n    }\n    else\n        static assert(0);\n}\n\n///\n@safe pure @nogc nothrow\nunittest\n{\n    import std.algorithm.comparison : equal;\n    import std.utf : byChar;\n    assert(leftJustifier(\"hello\", 2).equal(\"hello\".byChar));\n    assert(leftJustifier(\"hello\", 7).equal(\"hello  \".byChar));\n    assert(leftJustifier(\"hello\", 7, 'x').equal(\"helloxx\".byChar));\n}\n\nauto leftJustifier(Range)(auto ref Range r, size_t width, dchar fillChar = ' ')\nif (isConvertibleToString!Range)\n{\n    return leftJustifier!(StringTypeOf!Range)(r, width, fillChar);\n}\n\n@safe pure unittest\n{\n    auto r = \"hello\".leftJustifier(8);\n    r.popFront();\n    auto save = r.save;\n    r.popFront();\n    assert(r.front == 'l');\n    assert(save.front == 'e');\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!leftJustifier(\"hello\", 2));\n}\n\n/++\n    Right justify `s` in a field `width` characters wide. `fillChar`\n    is the character that will be used to fill up the space in the field that\n    `s` doesn't fill.\n\n    Params:\n        s = string\n        width = minimum field width\n        fillChar = used to pad end up to `width` characters\n\n    Returns:\n        GC allocated string\n\n    See_Also:\n        $(LREF rightJustifier), which does not allocate\n  +/\nS rightJustify(S)(S s, size_t width, dchar fillChar = ' ')\nif (isSomeString!S)\n{\n    import std.array : array;\n    return rightJustifier(s, width, fillChar).array;\n}\n\n///\n@safe pure unittest\n{\n    assert(rightJustify(\"hello\", 7, 'X') == \"XXhello\");\n    assert(rightJustify(\"hello\", 2, 'X') == \"hello\");\n    assert(rightJustify(\"hello\", 9, 'X') == \"XXXXhello\");\n}\n\n/++\n    Right justify `s` in a field `width` characters wide. `fillChar`\n    is the character that will be used to fill up the space in the field that\n    `s` doesn't fill.\n\n    Params:\n        r = string or $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n        of characters\n        width = minimum field width\n        fillChar = used to pad end up to `width` characters\n\n    Returns:\n        a lazy range of the right justified result\n\n    See_Also:\n        $(LREF leftJustifier)\n  +/\n\nauto rightJustifier(Range)(Range r, size_t width, dchar fillChar = ' ')\nif (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) &&\n    !isConvertibleToString!Range)\n{\n    alias C = Unqual!(ElementEncodingType!Range);\n\n    static if (C.sizeof == 1)\n    {\n        import std.utf : byDchar, byChar;\n        return rightJustifier(r.byDchar, width, fillChar).byChar;\n    }\n    else static if (C.sizeof == 2)\n    {\n        import std.utf : byDchar, byWchar;\n        return rightJustifier(r.byDchar, width, fillChar).byWchar;\n    }\n    else static if (C.sizeof == 4)\n    {\n        static struct Result\n        {\n          private:\n            Range _input;\n            size_t _width;\n            alias nfill = _width;       // number of fill characters to prepend\n            dchar _fillChar;\n            bool inited;\n\n            // Lazy initialization so constructor is trivial and cannot fail\n            void initialize()\n            {\n                // Replace _width with nfill\n                // (use alias instead of union because CTFE cannot deal with unions)\n                assert(_width);\n                static if (hasLength!Range)\n                {\n                    immutable len = _input.length;\n                    nfill = (_width > len) ? _width - len : 0;\n                }\n                else\n                {\n                    // Lookahead to see now many fill characters are needed\n                    import std.range : take;\n                    import std.range.primitives : walkLength;\n                    nfill = _width - walkLength(_input.save.take(_width), _width);\n                }\n                inited = true;\n            }\n\n          public:\n            this(Range input, size_t width, dchar fillChar) pure nothrow\n            {\n                _input = input;\n                _fillChar = fillChar;\n                _width = width;\n            }\n\n            @property bool empty()\n            {\n                return !nfill && _input.empty;\n            }\n\n            @property C front()\n            {\n                if (!nfill)\n                    return _input.front;   // fast path\n                if (!inited)\n                    initialize();\n                return nfill ? _fillChar : _input.front;\n            }\n\n            void popFront()\n            {\n                if (!nfill)\n                    _input.popFront();  // fast path\n                else\n                {\n                    if (!inited)\n                        initialize();\n                    if (nfill)\n                        --nfill;\n                    else\n                        _input.popFront();\n                }\n            }\n\n            @property typeof(this) save()\n            {\n                auto ret = this;\n                ret._input = _input.save;\n                return ret;\n            }\n        }\n\n        return Result(r, width, fillChar);\n    }\n    else\n        static assert(0);\n}\n\n///\n@safe pure @nogc nothrow\nunittest\n{\n    import std.algorithm.comparison : equal;\n    import std.utf : byChar;\n    assert(rightJustifier(\"hello\", 2).equal(\"hello\".byChar));\n    assert(rightJustifier(\"hello\", 7).equal(\"  hello\".byChar));\n    assert(rightJustifier(\"hello\", 7, 'x').equal(\"xxhello\".byChar));\n}\n\nauto rightJustifier(Range)(auto ref Range r, size_t width, dchar fillChar = ' ')\nif (isConvertibleToString!Range)\n{\n    return rightJustifier!(StringTypeOf!Range)(r, width, fillChar);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!rightJustifier(\"hello\", 2));\n}\n\n@safe pure unittest\n{\n    auto r = \"hello\"d.rightJustifier(6);\n    r.popFront();\n    auto save = r.save;\n    r.popFront();\n    assert(r.front == 'e');\n    assert(save.front == 'h');\n\n    auto t = \"hello\".rightJustifier(7);\n    t.popFront();\n    assert(t.front == ' ');\n    t.popFront();\n    assert(t.front == 'h');\n\n    auto u = \"hello\"d.rightJustifier(5);\n    u.popFront();\n    u.popFront();\n    u.popFront();\n}\n\n/++\n    Center `s` in a field `width` characters wide. `fillChar`\n    is the character that will be used to fill up the space in the field that\n    `s` doesn't fill.\n\n    Params:\n        s = The string to center\n        width = Width of the field to center `s` in\n        fillChar = The character to use for filling excess space in the field\n\n    Returns:\n        The resulting _center-justified string. The returned string is\n        GC-allocated. To avoid GC allocation, use $(LREF centerJustifier)\n        instead.\n  +/\nS center(S)(S s, size_t width, dchar fillChar = ' ')\nif (isSomeString!S)\n{\n    import std.array : array;\n    return centerJustifier(s, width, fillChar).array;\n}\n\n///\n@safe pure unittest\n{\n    assert(center(\"hello\", 7, 'X') == \"XhelloX\");\n    assert(center(\"hello\", 2, 'X') == \"hello\");\n    assert(center(\"hello\", 9, 'X') == \"XXhelloXX\");\n}\n\n@safe pure\nunittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n    {{\n        S s = to!S(\"hello\");\n\n        assert(leftJustify(s, 2) == \"hello\");\n        assert(rightJustify(s, 2) == \"hello\");\n        assert(center(s, 2) == \"hello\");\n\n        assert(leftJustify(s, 7) == \"hello  \");\n        assert(rightJustify(s, 7) == \"  hello\");\n        assert(center(s, 7) == \" hello \");\n\n        assert(leftJustify(s, 8) == \"hello   \");\n        assert(rightJustify(s, 8) == \"   hello\");\n        assert(center(s, 8) == \" hello  \");\n\n        assert(leftJustify(s, 8, '\\u0100') == \"hello\\u0100\\u0100\\u0100\");\n        assert(rightJustify(s, 8, '\\u0100') == \"\\u0100\\u0100\\u0100hello\");\n        assert(center(s, 8, '\\u0100') == \"\\u0100hello\\u0100\\u0100\");\n\n        assert(leftJustify(s, 8, 'ö') == \"helloööö\");\n        assert(rightJustify(s, 8, 'ö') == \"öööhello\");\n        assert(center(s, 8, 'ö') == \"öhelloöö\");\n    }}\n    });\n}\n\n/++\n    Center justify `r` in a field `width` characters wide. `fillChar`\n    is the character that will be used to fill up the space in the field that\n    `r` doesn't fill.\n\n    Params:\n        r = string or $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n        of characters\n        width = minimum field width\n        fillChar = used to pad end up to `width` characters\n\n    Returns:\n        a lazy range of the center justified result\n\n    See_Also:\n        $(LREF leftJustifier)\n        $(LREF rightJustifier)\n  +/\n\nauto centerJustifier(Range)(Range r, size_t width, dchar fillChar = ' ')\nif (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) &&\n    !isConvertibleToString!Range)\n{\n    alias C = Unqual!(ElementEncodingType!Range);\n\n    static if (C.sizeof == 1)\n    {\n        import std.utf : byDchar, byChar;\n        return centerJustifier(r.byDchar, width, fillChar).byChar;\n    }\n    else static if (C.sizeof == 2)\n    {\n        import std.utf : byDchar, byWchar;\n        return centerJustifier(r.byDchar, width, fillChar).byWchar;\n    }\n    else static if (C.sizeof == 4)\n    {\n        import std.range : chain, repeat;\n        import std.range.primitives : walkLength;\n\n        auto len = walkLength(r.save, width);\n        if (len > width)\n            len = width;\n        const nleft = (width - len) / 2;\n        const nright = width - len - nleft;\n        return chain(repeat(fillChar, nleft), r, repeat(fillChar, nright));\n    }\n    else\n        static assert(0);\n}\n\n///\n@safe pure @nogc nothrow\nunittest\n{\n    import std.algorithm.comparison : equal;\n    import std.utf : byChar;\n    assert(centerJustifier(\"hello\", 2).equal(\"hello\".byChar));\n    assert(centerJustifier(\"hello\", 8).equal(\" hello  \".byChar));\n    assert(centerJustifier(\"hello\", 7, 'x').equal(\"xhellox\".byChar));\n}\n\nauto centerJustifier(Range)(auto ref Range r, size_t width, dchar fillChar = ' ')\nif (isConvertibleToString!Range)\n{\n    return centerJustifier!(StringTypeOf!Range)(r, width, fillChar);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!centerJustifier(\"hello\", 8));\n}\n\n@safe unittest\n{\n    static auto byFwdRange(dstring s)\n    {\n        static struct FRange\n        {\n            @safe:\n            dstring str;\n            this(dstring s) { str = s; }\n            @property bool empty() { return str.length == 0; }\n            @property dchar front() { return str[0]; }\n            void popFront() { str = str[1 .. $]; }\n            @property FRange save() { return this; }\n        }\n        return FRange(s);\n    }\n\n    auto r = centerJustifier(byFwdRange(\"hello\"d), 6);\n    r.popFront();\n    auto save = r.save;\n    r.popFront();\n    assert(r.front == 'l');\n    assert(save.front == 'e');\n\n    auto t = \"hello\".centerJustifier(7);\n    t.popFront();\n    assert(t.front == 'h');\n    t.popFront();\n    assert(t.front == 'e');\n\n    auto u = byFwdRange(\"hello\"d).centerJustifier(6);\n    u.popFront();\n    u.popFront();\n    u.popFront();\n    u.popFront();\n    u.popFront();\n    u.popFront();\n}\n\n\n/++\n    Replace each tab character in `s` with the number of spaces necessary\n    to align the following character at the next tab stop.\n\n    Params:\n        s = string\n        tabSize = distance between tab stops\n\n    Returns:\n        GC allocated string with tabs replaced with spaces\n  +/\nauto detab(Range)(auto ref Range s, size_t tabSize = 8) pure\nif ((isForwardRange!Range && isSomeChar!(ElementEncodingType!Range))\n    || __traits(compiles, StringTypeOf!Range))\n{\n    import std.array : array;\n    return detabber(s, tabSize).array;\n}\n\n///\n@safe pure unittest\n{\n    assert(detab(\" \\n\\tx\", 9) == \" \\n         x\");\n}\n\n@safe pure unittest\n{\n    static struct TestStruct\n    {\n        string s;\n        alias s this;\n    }\n\n    static struct TestStruct2\n    {\n        string s;\n        alias s this;\n        @disable this(this);\n    }\n\n    string s = \" \\n\\tx\";\n    string cmp = \" \\n         x\";\n    auto t = TestStruct(s);\n    assert(detab(t, 9) == cmp);\n    assert(detab(TestStruct(s), 9) == cmp);\n    assert(detab(TestStruct(s), 9) == detab(TestStruct(s), 9));\n    assert(detab(TestStruct2(s), 9) == detab(TestStruct2(s), 9));\n    assert(detab(TestStruct2(s), 9) == cmp);\n}\n\n/++\n    Replace each tab character in `r` with the number of spaces\n    necessary to align the following character at the next tab stop.\n\n    Params:\n        r = string or $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n        tabSize = distance between tab stops\n\n    Returns:\n        lazy forward range with tabs replaced with spaces\n  +/\nauto detabber(Range)(Range r, size_t tabSize = 8)\nif (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) &&\n    !isConvertibleToString!Range)\n{\n    import std.uni : lineSep, paraSep, nelSep;\n    import std.utf : codeUnitLimit, decodeFront;\n\n    assert(tabSize > 0);\n\n    alias C = Unqual!(ElementEncodingType!(Range));\n\n    static struct Result\n    {\n    private:\n        Range _input;\n        size_t _tabSize;\n        size_t nspaces;\n        int column;\n        size_t index;\n\n    public:\n\n        this(Range input, size_t tabSize)\n        {\n            _input = input;\n            _tabSize = tabSize;\n        }\n\n        static if (isInfinite!(Range))\n        {\n            enum bool empty = false;\n        }\n        else\n        {\n            @property bool empty()\n            {\n                return _input.empty && nspaces == 0;\n            }\n        }\n\n        @property C front()\n        {\n            if (nspaces)\n                return ' ';\n            static if (isSomeString!(Range))\n                C c = _input[0];\n            else\n                C c = _input.front;\n            if (index)\n                return c;\n            dchar dc;\n            if (c < codeUnitLimit!(immutable(C)[]))\n            {\n                dc = c;\n                index = 1;\n            }\n            else\n            {\n                auto r = _input.save;\n                dc = decodeFront(r, index);     // lookahead to decode\n            }\n            switch (dc)\n            {\n                case '\\r':\n                case '\\n':\n                case paraSep:\n                case lineSep:\n                case nelSep:\n                    column = 0;\n                    break;\n\n                case '\\t':\n                    nspaces = _tabSize - (column % _tabSize);\n                    column += nspaces;\n                    c = ' ';\n                    break;\n\n                default:\n                    ++column;\n                    break;\n            }\n            return c;\n        }\n\n        void popFront()\n        {\n            if (!index)\n                front;\n            if (nspaces)\n                --nspaces;\n            if (!nspaces)\n            {\n                static if (isSomeString!(Range))\n                   _input = _input[1 .. $];\n                else\n                    _input.popFront();\n                --index;\n            }\n        }\n\n        @property typeof(this) save()\n        {\n            auto ret = this;\n            ret._input = _input.save;\n            return ret;\n        }\n    }\n\n    return Result(r, tabSize);\n}\n\n///\n@safe pure unittest\n{\n    import std.array : array;\n\n    assert(detabber(\" \\n\\tx\", 9).array == \" \\n         x\");\n}\n\nauto detabber(Range)(auto ref Range r, size_t tabSize = 8)\nif (isConvertibleToString!Range)\n{\n    return detabber!(StringTypeOf!Range)(r, tabSize);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!detabber(  \"  ab\\t asdf \", 8));\n}\n\n@safe pure unittest\n{\n    import std.algorithm.comparison : cmp;\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n    {{\n        S s = to!S(\"This \\tis\\t a fofof\\tof list\");\n        assert(cmp(detab(s), \"This    is       a fofof        of list\") == 0);\n\n        assert(detab(cast(S) null) is null);\n        assert(detab(\"\").empty);\n        assert(detab(\"a\") == \"a\");\n        assert(detab(\"\\t\") == \"        \");\n        assert(detab(\"\\t\", 3) == \"   \");\n        assert(detab(\"\\t\", 9) == \"         \");\n        assert(detab(  \"  ab\\t asdf \") == \"  ab     asdf \");\n        assert(detab(  \"  \\U00010000b\\tasdf \") == \"  \\U00010000b    asdf \");\n        assert(detab(\"\\r\\t\", 9) == \"\\r         \");\n        assert(detab(\"\\n\\t\", 9) == \"\\n         \");\n        assert(detab(\"\\u0085\\t\", 9) == \"\\u0085         \");\n        assert(detab(\"\\u2028\\t\", 9) == \"\\u2028         \");\n        assert(detab(\" \\u2029\\t\", 9) == \" \\u2029         \");\n    }}\n    });\n}\n\n///\n@safe pure unittest\n{\n    import std.array : array;\n    import std.utf : byChar, byWchar;\n\n    assert(detabber(\" \\u2029\\t\".byChar, 9).array == \" \\u2029         \");\n    auto r = \"hel\\tx\".byWchar.detabber();\n    assert(r.front == 'h');\n    auto s = r.save;\n    r.popFront();\n    r.popFront();\n    assert(r.front == 'l');\n    assert(s.front == 'h');\n}\n\n/++\n    Replaces spaces in `s` with the optimal number of tabs.\n    All spaces and tabs at the end of a line are removed.\n\n    Params:\n        s       = String to convert.\n        tabSize = Tab columns are `tabSize` spaces apart.\n\n    Returns:\n        GC allocated string with spaces replaced with tabs;\n        use $(LREF entabber) to not allocate.\n\n    See_Also:\n        $(LREF entabber)\n +/\nauto entab(Range)(Range s, size_t tabSize = 8)\nif (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range))\n{\n    import std.array : array;\n    return entabber(s, tabSize).array;\n}\n\n///\n@safe pure unittest\n{\n    assert(entab(\"        x \\n\") == \"\\tx\\n\");\n}\n\nauto entab(Range)(auto ref Range s, size_t tabSize = 8)\nif (!(isForwardRange!Range && isSomeChar!(ElementEncodingType!Range)) &&\n    is(StringTypeOf!Range))\n{\n    return entab!(StringTypeOf!Range)(s, tabSize);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!entab(\"        x \\n\"));\n}\n\n/++\n    Replaces spaces in range `r` with the optimal number of tabs.\n    All spaces and tabs at the end of a line are removed.\n\n    Params:\n        r = string or $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)\n        tabSize = distance between tab stops\n\n    Returns:\n        lazy forward range with spaces replaced with tabs\n\n    See_Also:\n        $(LREF entab)\n  +/\nauto entabber(Range)(Range r, size_t tabSize = 8)\nif (isForwardRange!Range && !isConvertibleToString!Range)\n{\n    import std.uni : lineSep, paraSep, nelSep;\n    import std.utf : codeUnitLimit, decodeFront;\n\n    assert(tabSize > 0);\n    alias C = Unqual!(ElementEncodingType!Range);\n\n    static struct Result\n    {\n    private:\n        Range _input;\n        size_t _tabSize;\n        size_t nspaces;\n        size_t ntabs;\n        int column;\n        size_t index;\n\n        @property C getFront()\n        {\n            static if (isSomeString!Range)\n                return _input[0];       // avoid autodecode\n            else\n                return _input.front;\n        }\n\n    public:\n\n        this(Range input, size_t tabSize)\n        {\n            _input = input;\n            _tabSize = tabSize;\n        }\n\n        @property bool empty()\n        {\n            if (ntabs || nspaces)\n                return false;\n\n            /* Since trailing spaces are removed,\n             * look ahead for anything that is not a trailing space\n             */\n            static if (isSomeString!Range)\n            {\n                foreach (c; _input)\n                {\n                    if (c != ' ' && c != '\\t')\n                        return false;\n                }\n                return true;\n            }\n            else\n            {\n                if (_input.empty)\n                    return true;\n                immutable c = _input.front;\n                if (c != ' ' && c != '\\t')\n                    return false;\n                auto t = _input.save;\n                t.popFront();\n                foreach (c2; t)\n                {\n                    if (c2 != ' ' && c2 != '\\t')\n                        return false;\n                }\n                return true;\n            }\n        }\n\n        @property C front()\n        {\n            //writefln(\"   front(): ntabs = %s nspaces = %s index = %s front = '%s'\", ntabs, nspaces, index, getFront);\n            if (ntabs)\n                return '\\t';\n            if (nspaces)\n                return ' ';\n            C c = getFront;\n            if (index)\n                return c;\n            dchar dc;\n            if (c < codeUnitLimit!(immutable(C)[]))\n            {\n                index = 1;\n                dc = c;\n                if (c == ' ' || c == '\\t')\n                {\n                    // Consume input until a non-blank is encountered\n                    immutable startcol = column;\n                    C cx;\n                    static if (isSomeString!Range)\n                    {\n                        while (1)\n                        {\n                            assert(_input.length);\n                            cx = _input[0];\n                            if (cx == ' ')\n                                ++column;\n                            else if (cx == '\\t')\n                                column += _tabSize - (column % _tabSize);\n                            else\n                                break;\n                            _input = _input[1 .. $];\n                        }\n                    }\n                    else\n                    {\n                        while (1)\n                        {\n                            assert(!_input.empty);\n                            cx = _input.front;\n                            if (cx == ' ')\n                                ++column;\n                            else if (cx == '\\t')\n                                column += _tabSize - (column % _tabSize);\n                            else\n                                break;\n                            _input.popFront();\n                        }\n                    }\n                    // Compute ntabs+nspaces to get from startcol to column\n                    immutable n = column - startcol;\n                    if (n == 1)\n                    {\n                        nspaces = 1;\n                    }\n                    else\n                    {\n                        ntabs = column / _tabSize - startcol / _tabSize;\n                        if (ntabs == 0)\n                            nspaces = column - startcol;\n                        else\n                            nspaces = column % _tabSize;\n                    }\n                    //writefln(\"\\tstartcol = %s, column = %s, _tabSize = %s\", startcol, column, _tabSize);\n                    //writefln(\"\\tntabs = %s, nspaces = %s\", ntabs, nspaces);\n                    if (cx < codeUnitLimit!(immutable(C)[]))\n                    {\n                        dc = cx;\n                        index = 1;\n                    }\n                    else\n                    {\n                        auto r = _input.save;\n                        dc = decodeFront(r, index);     // lookahead to decode\n                    }\n                    switch (dc)\n                    {\n                        case '\\r':\n                        case '\\n':\n                        case paraSep:\n                        case lineSep:\n                        case nelSep:\n                            column = 0;\n                            // Spaces followed by newline are ignored\n                            ntabs = 0;\n                            nspaces = 0;\n                            return cx;\n\n                        default:\n                            ++column;\n                            break;\n                    }\n                    return ntabs ? '\\t' : ' ';\n                }\n            }\n            else\n            {\n                auto r = _input.save;\n                dc = decodeFront(r, index);     // lookahead to decode\n            }\n            //writefln(\"dc = x%x\", dc);\n            switch (dc)\n            {\n                case '\\r':\n                case '\\n':\n                case paraSep:\n                case lineSep:\n                case nelSep:\n                    column = 0;\n                    break;\n\n                default:\n                    ++column;\n                    break;\n            }\n            return c;\n        }\n\n        void popFront()\n        {\n            //writefln(\"popFront(): ntabs = %s nspaces = %s index = %s front = '%s'\", ntabs, nspaces, index, getFront);\n            if (!index)\n                front;\n            if (ntabs)\n                --ntabs;\n            else if (nspaces)\n                --nspaces;\n            else if (!ntabs && !nspaces)\n            {\n                static if (isSomeString!Range)\n                   _input = _input[1 .. $];\n                else\n                    _input.popFront();\n                --index;\n            }\n        }\n\n        @property typeof(this) save()\n        {\n            auto ret = this;\n            ret._input = _input.save;\n            return ret;\n        }\n    }\n\n    return Result(r, tabSize);\n}\n\n///\n@safe pure unittest\n{\n    import std.array : array;\n    assert(entabber(\"        x \\n\").array == \"\\tx\\n\");\n}\n\nauto entabber(Range)(auto ref Range r, size_t tabSize = 8)\nif (isConvertibleToString!Range)\n{\n    return entabber!(StringTypeOf!Range)(r, tabSize);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!entabber(\"  ab    asdf \", 8));\n}\n\n@safe pure\nunittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    assert(entab(cast(string) null) is null);\n    assert(entab(\"\").empty);\n    assert(entab(\"a\") == \"a\");\n    assert(entab(\"        \") == \"\");\n    assert(entab(\"        x\") == \"\\tx\");\n    assert(entab(\"  ab    asdf \") == \"  ab\\tasdf\");\n    assert(entab(\"  ab     asdf \") == \"  ab\\t asdf\");\n    assert(entab(\"  ab \\t   asdf \") == \"  ab\\t   asdf\");\n    assert(entab(\"1234567 \\ta\") == \"1234567\\t\\ta\");\n    assert(entab(\"1234567  \\ta\") == \"1234567\\t\\ta\");\n    assert(entab(\"1234567   \\ta\") == \"1234567\\t\\ta\");\n    assert(entab(\"1234567    \\ta\") == \"1234567\\t\\ta\");\n    assert(entab(\"1234567     \\ta\") == \"1234567\\t\\ta\");\n    assert(entab(\"1234567      \\ta\") == \"1234567\\t\\ta\");\n    assert(entab(\"1234567       \\ta\") == \"1234567\\t\\ta\");\n    assert(entab(\"1234567        \\ta\") == \"1234567\\t\\ta\");\n    assert(entab(\"1234567         \\ta\") == \"1234567\\t\\t\\ta\");\n\n    assert(entab(\"a               \") == \"a\");\n    assert(entab(\"a\\v\") == \"a\\v\");\n    assert(entab(\"a\\f\") == \"a\\f\");\n    assert(entab(\"a\\n\") == \"a\\n\");\n    assert(entab(\"a\\n\\r\") == \"a\\n\\r\");\n    assert(entab(\"a\\r\\n\") == \"a\\r\\n\");\n    assert(entab(\"a\\u2028\") == \"a\\u2028\");\n    assert(entab(\"a\\u2029\") == \"a\\u2029\");\n    assert(entab(\"a\\u0085\") == \"a\\u0085\");\n    assert(entab(\"a  \") == \"a\");\n    assert(entab(\"a\\t\") == \"a\");\n    assert(entab(\"\\uFF28\\uFF45\\uFF4C\\uFF4C567      \\t\\uFF4F \\t\") ==\n                 \"\\uFF28\\uFF45\\uFF4C\\uFF4C567\\t\\t\\uFF4F\");\n    assert(entab(\" \\naa\") == \"\\naa\");\n    assert(entab(\" \\r aa\") == \"\\r aa\");\n    assert(entab(\" \\u2028 aa\") == \"\\u2028 aa\");\n    assert(entab(\" \\u2029 aa\") == \"\\u2029 aa\");\n    assert(entab(\" \\u0085 aa\") == \"\\u0085 aa\");\n    });\n}\n\n@safe pure\nunittest\n{\n    import std.array : array;\n    import std.utf : byChar;\n    assert(entabber(\" \\u0085 aa\".byChar).array == \"\\u0085 aa\");\n    assert(entabber(\" \\u2028\\t aa \\t\".byChar).array == \"\\u2028\\t aa\");\n\n    auto r = entabber(\"1234\", 4);\n    r.popFront();\n    auto rsave = r.save;\n    r.popFront();\n    assert(r.front == '3');\n    assert(rsave.front == '2');\n}\n\n\n/++\n    Replaces the characters in `str` which are keys in `transTable` with\n    their corresponding values in `transTable`. `transTable` is an AA\n    where its keys are `dchar` and its values are either `dchar` or some\n    type of string. Also, if `toRemove` is given, the characters in it are\n    removed from `str` prior to translation. `str` itself is unaltered.\n    A copy with the changes is returned.\n\n    See_Also:\n        $(LREF tr),\n        $(REF replace, std,array),\n        $(REF substitute, std,algorithm,iteration)\n\n    Params:\n        str        = The original string.\n        transTable = The AA indicating which characters to replace and what to\n                     replace them with.\n        toRemove   = The characters to remove from the string.\n  +/\nC1[] translate(C1, C2 = immutable char)(C1[] str,\n                                        in dchar[dchar] transTable,\n                                        const(C2)[] toRemove = null) @safe pure\nif (isSomeChar!C1 && isSomeChar!C2)\n{\n    import std.array : appender;\n    auto buffer = appender!(C1[])();\n    translateImpl(str, transTable, toRemove, buffer);\n    return buffer.data;\n}\n\n///\n@safe pure unittest\n{\n    dchar[dchar] transTable1 = ['e' : '5', 'o' : '7', '5': 'q'];\n    assert(translate(\"hello world\", transTable1) == \"h5ll7 w7rld\");\n\n    assert(translate(\"hello world\", transTable1, \"low\") == \"h5 rd\");\n\n    string[dchar] transTable2 = ['e' : \"5\", 'o' : \"orange\"];\n    assert(translate(\"hello world\", transTable2) == \"h5llorange worangerld\");\n}\n\n@safe pure unittest // issue 13018\n{\n    immutable dchar[dchar] transTable1 = ['e' : '5', 'o' : '7', '5': 'q'];\n    assert(translate(\"hello world\", transTable1) == \"h5ll7 w7rld\");\n\n    assert(translate(\"hello world\", transTable1, \"low\") == \"h5 rd\");\n\n    immutable string[dchar] transTable2 = ['e' : \"5\", 'o' : \"orange\"];\n    assert(translate(\"hello world\", transTable2) == \"h5llorange worangerld\");\n}\n\n@system pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!( char[], const( char)[], immutable( char)[],\n                          wchar[], const(wchar)[], immutable(wchar)[],\n                          dchar[], const(dchar)[], immutable(dchar)[]))\n    {{\n        assert(translate(to!S(\"hello world\"), cast(dchar[dchar])['h' : 'q', 'l' : '5']) ==\n               to!S(\"qe55o wor5d\"));\n        assert(translate(to!S(\"hello world\"), cast(dchar[dchar])['o' : 'l', 'l' : '\\U00010143']) ==\n               to!S(\"he\\U00010143\\U00010143l wlr\\U00010143d\"));\n        assert(translate(to!S(\"hello \\U00010143 world\"), cast(dchar[dchar])['h' : 'q', 'l': '5']) ==\n               to!S(\"qe55o \\U00010143 wor5d\"));\n        assert(translate(to!S(\"hello \\U00010143 world\"), cast(dchar[dchar])['o' : '0', '\\U00010143' : 'o']) ==\n               to!S(\"hell0 o w0rld\"));\n        assert(translate(to!S(\"hello world\"), cast(dchar[dchar]) null) == to!S(\"hello world\"));\n\n        static foreach (T; AliasSeq!( char[], const( char)[], immutable( char)[],\n                              wchar[], const(wchar)[], immutable(wchar)[],\n                              dchar[], const(dchar)[], immutable(dchar)[]))\n        {\n            static foreach (R; AliasSeq!(dchar[dchar], const dchar[dchar],\n                        immutable dchar[dchar]))\n            {{\n                R tt = ['h' : 'q', 'l' : '5'];\n                assert(translate(to!S(\"hello world\"), tt, to!T(\"r\"))\n                    == to!S(\"qe55o wo5d\"));\n                assert(translate(to!S(\"hello world\"), tt, to!T(\"helo\"))\n                    == to!S(\" wrd\"));\n                assert(translate(to!S(\"hello world\"), tt, to!T(\"q5\"))\n                    == to!S(\"qe55o wor5d\"));\n            }}\n        }\n\n        auto s = to!S(\"hello world\");\n        dchar[dchar] transTable = ['h' : 'q', 'l' : '5'];\n        static assert(is(typeof(s) == typeof(translate(s, transTable))));\n        assert(translate(s, transTable) == \"qe55o wor5d\");\n    }}\n    });\n}\n\n/++ Ditto +/\nC1[] translate(C1, S, C2 = immutable char)(C1[] str,\n                                           in S[dchar] transTable,\n                                           const(C2)[] toRemove = null) @safe pure\nif (isSomeChar!C1 && isSomeString!S && isSomeChar!C2)\n{\n    import std.array : appender;\n    auto buffer = appender!(C1[])();\n    translateImpl(str, transTable, toRemove, buffer);\n    return buffer.data;\n}\n\n@system pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (S; AliasSeq!( char[], const( char)[], immutable( char)[],\n                          wchar[], const(wchar)[], immutable(wchar)[],\n                          dchar[], const(dchar)[], immutable(dchar)[]))\n    {{\n        assert(translate(to!S(\"hello world\"), ['h' : \"yellow\", 'l' : \"42\"]) ==\n               to!S(\"yellowe4242o wor42d\"));\n        assert(translate(to!S(\"hello world\"), ['o' : \"owl\", 'l' : \"\\U00010143\\U00010143\"]) ==\n               to!S(\"he\\U00010143\\U00010143\\U00010143\\U00010143owl wowlr\\U00010143\\U00010143d\"));\n        assert(translate(to!S(\"hello \\U00010143 world\"), ['h' : \"yellow\", 'l' : \"42\"]) ==\n               to!S(\"yellowe4242o \\U00010143 wor42d\"));\n        assert(translate(to!S(\"hello \\U00010143 world\"), ['o' : \"owl\", 'l' : \"\\U00010143\\U00010143\"]) ==\n               to!S(\"he\\U00010143\\U00010143\\U00010143\\U00010143owl \\U00010143 wowlr\\U00010143\\U00010143d\"));\n        assert(translate(to!S(\"hello \\U00010143 world\"), ['h' : \"\"]) ==\n               to!S(\"ello \\U00010143 world\"));\n        assert(translate(to!S(\"hello \\U00010143 world\"), ['\\U00010143' : \"\"]) ==\n               to!S(\"hello  world\"));\n        assert(translate(to!S(\"hello world\"), cast(string[dchar]) null) == to!S(\"hello world\"));\n\n        static foreach (T; AliasSeq!( char[], const( char)[], immutable( char)[],\n                              wchar[], const(wchar)[], immutable(wchar)[],\n                              dchar[], const(dchar)[], immutable(dchar)[]))\n        {\n\n            static foreach (R; AliasSeq!(string[dchar], const string[dchar],\n                        immutable string[dchar]))\n            {{\n                R tt = ['h' : \"yellow\", 'l' : \"42\"];\n                assert(translate(to!S(\"hello world\"), tt, to!T(\"r\")) ==\n                       to!S(\"yellowe4242o wo42d\"));\n                assert(translate(to!S(\"hello world\"), tt, to!T(\"helo\")) ==\n                       to!S(\" wrd\"));\n                assert(translate(to!S(\"hello world\"), tt, to!T(\"y42\")) ==\n                       to!S(\"yellowe4242o wor42d\"));\n                assert(translate(to!S(\"hello world\"), tt, to!T(\"hello world\")) ==\n                       to!S(\"\"));\n                assert(translate(to!S(\"hello world\"), tt, to!T(\"42\")) ==\n                       to!S(\"yellowe4242o wor42d\"));\n            }}\n        }\n\n        auto s = to!S(\"hello world\");\n        string[dchar] transTable = ['h' : \"silly\", 'l' : \"putty\"];\n        static assert(is(typeof(s) == typeof(translate(s, transTable))));\n        assert(translate(s, transTable) == \"sillyeputtyputtyo worputtyd\");\n    }}\n    });\n}\n\n/++\n    This is an overload of `translate` which takes an existing buffer to write the contents to.\n\n    Params:\n        str        = The original string.\n        transTable = The AA indicating which characters to replace and what to\n                     replace them with.\n        toRemove   = The characters to remove from the string.\n        buffer     = An output range to write the contents to.\n  +/\nvoid translate(C1, C2 = immutable char, Buffer)(C1[] str,\n                                        in dchar[dchar] transTable,\n                                        const(C2)[] toRemove,\n                                        Buffer buffer)\nif (isSomeChar!C1 && isSomeChar!C2 && isOutputRange!(Buffer, C1))\n{\n    translateImpl(str, transTable, toRemove, buffer);\n}\n\n///\n@safe pure unittest\n{\n    import std.array : appender;\n    dchar[dchar] transTable1 = ['e' : '5', 'o' : '7', '5': 'q'];\n    auto buffer = appender!(dchar[])();\n    translate(\"hello world\", transTable1, null, buffer);\n    assert(buffer.data == \"h5ll7 w7rld\");\n\n    buffer.clear();\n    translate(\"hello world\", transTable1, \"low\", buffer);\n    assert(buffer.data == \"h5 rd\");\n\n    buffer.clear();\n    string[dchar] transTable2 = ['e' : \"5\", 'o' : \"orange\"];\n    translate(\"hello world\", transTable2, null, buffer);\n    assert(buffer.data == \"h5llorange worangerld\");\n}\n\n@safe pure unittest // issue 13018\n{\n    import std.array : appender;\n    immutable dchar[dchar] transTable1 = ['e' : '5', 'o' : '7', '5': 'q'];\n    auto buffer = appender!(dchar[])();\n    translate(\"hello world\", transTable1, null, buffer);\n    assert(buffer.data == \"h5ll7 w7rld\");\n\n    buffer.clear();\n    translate(\"hello world\", transTable1, \"low\", buffer);\n    assert(buffer.data == \"h5 rd\");\n\n    buffer.clear();\n    immutable string[dchar] transTable2 = ['e' : \"5\", 'o' : \"orange\"];\n    translate(\"hello world\", transTable2, null, buffer);\n    assert(buffer.data == \"h5llorange worangerld\");\n}\n\n/++ Ditto +/\nvoid translate(C1, S, C2 = immutable char, Buffer)(C1[] str,\n                                                   in S[dchar] transTable,\n                                                   const(C2)[] toRemove,\n                                                   Buffer buffer)\nif (isSomeChar!C1 && isSomeString!S && isSomeChar!C2 && isOutputRange!(Buffer, S))\n{\n    translateImpl(str, transTable, toRemove, buffer);\n}\n\nprivate void translateImpl(C1, T, C2, Buffer)(C1[] str,\n                                      T transTable,\n                                      const(C2)[] toRemove,\n                                      Buffer buffer)\n{\n    bool[dchar] removeTable;\n\n    foreach (dchar c; toRemove)\n        removeTable[c] = true;\n\n    foreach (dchar c; str)\n    {\n        if (c in removeTable)\n            continue;\n\n        auto newC = c in transTable;\n\n        if (newC)\n            put(buffer, *newC);\n        else\n            put(buffer, c);\n    }\n}\n\n/++\n    This is an $(I $(RED ASCII-only)) overload of $(LREF _translate). It\n    will $(I not) work with Unicode. It exists as an optimization for the\n    cases where Unicode processing is not necessary.\n\n    Unlike the other overloads of $(LREF _translate), this one does not take\n    an AA. Rather, it takes a `string` generated by $(LREF makeTransTable).\n\n    The array generated by `makeTransTable` is `256` elements long such that\n    the index is equal to the ASCII character being replaced and the value is\n    equal to the character that it's being replaced with. Note that translate\n    does not decode any of the characters, so you can actually pass it Extended\n    ASCII characters if you want to (ASCII only actually uses `128`\n    characters), but be warned that Extended ASCII characters are not valid\n    Unicode and therefore will result in a `UTFException` being thrown from\n    most other Phobos functions.\n\n    Also, because no decoding occurs, it is possible to use this overload to\n    translate ASCII characters within a proper UTF-8 string without altering the\n    other, non-ASCII characters. It's replacing any code unit greater than\n    `127` with another code unit or replacing any code unit with another code\n    unit greater than `127` which will cause UTF validation issues.\n\n    See_Also:\n        $(LREF tr),\n        $(REF replace, std,array),\n        $(REF substitute, std,algorithm,iteration)\n\n    Params:\n        str        = The original string.\n        transTable = The string indicating which characters to replace and what\n                     to replace them with. It is generated by $(LREF makeTransTable).\n        toRemove   = The characters to remove from the string.\n  +/\nC[] translate(C = immutable char)(scope const(char)[] str, scope const(char)[] transTable,\n              scope const(char)[] toRemove = null) @trusted pure nothrow\nif (is(Unqual!C == char))\nin\n{\n    assert(transTable.length == 256);\n}\ndo\n{\n    bool[256] remTable = false;\n\n    foreach (char c; toRemove)\n        remTable[c] = true;\n\n    size_t count = 0;\n    foreach (char c; str)\n    {\n        if (!remTable[c])\n            ++count;\n    }\n\n    auto buffer = new char[count];\n\n    size_t i = 0;\n    foreach (char c; str)\n    {\n        if (!remTable[c])\n            buffer[i++] = transTable[c];\n    }\n\n    return cast(C[])(buffer);\n}\n\n///\n@safe pure nothrow unittest\n{\n    auto transTable1 = makeTrans(\"eo5\", \"57q\");\n    assert(translate(\"hello world\", transTable1) == \"h5ll7 w7rld\");\n\n    assert(translate(\"hello world\", transTable1, \"low\") == \"h5 rd\");\n}\n\n/**\n * Do same thing as $(LREF makeTransTable) but allocate the translation table\n * on the GC heap.\n *\n * Use $(LREF makeTransTable) instead.\n */\nstring makeTrans(scope const(char)[] from, scope const(char)[] to) @trusted pure nothrow\n{\n    return makeTransTable(from, to)[].idup;\n}\n\n///\n@safe pure nothrow unittest\n{\n    auto transTable1 = makeTrans(\"eo5\", \"57q\");\n    assert(translate(\"hello world\", transTable1) == \"h5ll7 w7rld\");\n\n    assert(translate(\"hello world\", transTable1, \"low\") == \"h5 rd\");\n}\n\n/*******\n * Construct 256 character translation table, where characters in from[] are replaced\n * by corresponding characters in to[].\n *\n * Params:\n *      from = array of chars, less than or equal to 256 in length\n *      to = corresponding array of chars to translate to\n * Returns:\n *      translation array\n */\nchar[256] makeTransTable(scope const(char)[] from, scope const(char)[] to) @safe pure nothrow @nogc\nin\n{\n    import std.ascii : isASCII;\n    assert(from.length == to.length);\n    assert(from.length <= 256);\n    foreach (char c; from)\n        assert(isASCII(c));\n    foreach (char c; to)\n        assert(isASCII(c));\n}\ndo\n{\n    char[256] result = void;\n\n    foreach (i; 0 .. result.length)\n        result[i] = cast(char) i;\n    foreach (i, c; from)\n        result[c] = to[i];\n    return result;\n}\n\n///\n@safe pure unittest\n{\n    assert(translate(\"hello world\", makeTransTable(\"hl\", \"q5\")) == \"qe55o wor5d\");\n    assert(translate(\"hello world\", makeTransTable(\"12345\", \"67890\")) == \"hello world\");\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    static foreach (C; AliasSeq!(char, const char, immutable char))\n    {{\n        assert(translate!C(\"hello world\", makeTransTable(\"hl\", \"q5\")) == to!(C[])(\"qe55o wor5d\"));\n\n        auto s = to!(C[])(\"hello world\");\n        auto transTable = makeTransTable(\"hl\", \"q5\");\n        static assert(is(typeof(s) == typeof(translate!C(s, transTable))));\n        assert(translate(s, transTable) == \"qe55o wor5d\");\n    }}\n\n    static foreach (S; AliasSeq!(char[], const(char)[], immutable(char)[]))\n    {\n        assert(translate(to!S(\"hello world\"), makeTransTable(\"hl\", \"q5\")) == to!S(\"qe55o wor5d\"));\n        assert(translate(to!S(\"hello \\U00010143 world\"), makeTransTable(\"hl\", \"q5\")) ==\n               to!S(\"qe55o \\U00010143 wor5d\"));\n        assert(translate(to!S(\"hello world\"), makeTransTable(\"ol\", \"1o\")) == to!S(\"heoo1 w1rod\"));\n        assert(translate(to!S(\"hello world\"), makeTransTable(\"\", \"\")) == to!S(\"hello world\"));\n        assert(translate(to!S(\"hello world\"), makeTransTable(\"12345\", \"67890\")) == to!S(\"hello world\"));\n        assert(translate(to!S(\"hello \\U00010143 world\"), makeTransTable(\"12345\", \"67890\")) ==\n               to!S(\"hello \\U00010143 world\"));\n\n        static foreach (T; AliasSeq!(char[], const(char)[], immutable(char)[]))\n        {\n            assert(translate(to!S(\"hello world\"), makeTransTable(\"hl\", \"q5\"), to!T(\"r\")) ==\n                   to!S(\"qe55o wo5d\"));\n            assert(translate(to!S(\"hello \\U00010143 world\"), makeTransTable(\"hl\", \"q5\"), to!T(\"r\")) ==\n                   to!S(\"qe55o \\U00010143 wo5d\"));\n            assert(translate(to!S(\"hello world\"), makeTransTable(\"hl\", \"q5\"), to!T(\"helo\")) ==\n                   to!S(\" wrd\"));\n            assert(translate(to!S(\"hello world\"), makeTransTable(\"hl\", \"q5\"), to!T(\"q5\")) ==\n                   to!S(\"qe55o wor5d\"));\n        }\n    }\n    });\n}\n\n/++\n    This is an $(I $(RED ASCII-only)) overload of `translate` which takes an existing buffer to write the contents to.\n\n    Params:\n        str        = The original string.\n        transTable = The string indicating which characters to replace and what\n                     to replace them with. It is generated by $(LREF makeTransTable).\n        toRemove   = The characters to remove from the string.\n        buffer     = An output range to write the contents to.\n  +/\nvoid translate(C = immutable char, Buffer)(scope const(char)[] str, scope const(char)[] transTable,\n        scope const(char)[] toRemove, Buffer buffer) @trusted pure\nif (is(Unqual!C == char) && isOutputRange!(Buffer, char))\nin\n{\n    assert(transTable.length == 256);\n}\ndo\n{\n    bool[256] remTable = false;\n\n    foreach (char c; toRemove)\n        remTable[c] = true;\n\n    foreach (char c; str)\n    {\n        if (!remTable[c])\n            put(buffer, transTable[c]);\n    }\n}\n\n///\n@safe pure unittest\n{\n    import std.array : appender;\n    auto buffer = appender!(char[])();\n    auto transTable1 = makeTransTable(\"eo5\", \"57q\");\n    translate(\"hello world\", transTable1, null, buffer);\n    assert(buffer.data == \"h5ll7 w7rld\");\n\n    buffer.clear();\n    translate(\"hello world\", transTable1, \"low\", buffer);\n    assert(buffer.data == \"h5 rd\");\n}\n\n//@@@DEPRECATED_2.086@@@\ndeprecated(\"This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.\")\nbool inPattern(S)(dchar c, in S pattern) @safe pure @nogc\nif (isSomeString!S)\n{\n    bool result = false;\n    int range = 0;\n    dchar lastc;\n\n    foreach (size_t i, dchar p; pattern)\n    {\n        if (p == '^' && i == 0)\n        {\n            result = true;\n            if (i + 1 == pattern.length)\n                return (c == p);    // or should this be an error?\n        }\n        else if (range)\n        {\n            range = 0;\n            if (lastc <= c && c <= p || c == p)\n                return !result;\n        }\n        else if (p == '-' && i > result && i + 1 < pattern.length)\n        {\n            range = 1;\n            continue;\n        }\n        else if (c == p)\n            return !result;\n        lastc = p;\n    }\n    return result;\n}\n\n\ndeprecated\n@safe pure @nogc unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    assert(inPattern('x', \"x\") == 1);\n    assert(inPattern('x', \"y\") == 0);\n    assert(inPattern('x', string.init) == 0);\n    assert(inPattern('x', \"^y\") == 1);\n    assert(inPattern('x', \"yxxy\") == 1);\n    assert(inPattern('x', \"^yxxy\") == 0);\n    assert(inPattern('x', \"^abcd\") == 1);\n    assert(inPattern('^', \"^^\") == 0);\n    assert(inPattern('^', \"^\") == 1);\n    assert(inPattern('^', \"a^\") == 1);\n    assert(inPattern('x', \"a-z\") == 1);\n    assert(inPattern('x', \"A-Z\") == 0);\n    assert(inPattern('x', \"^a-z\") == 0);\n    assert(inPattern('x', \"^A-Z\") == 1);\n    assert(inPattern('-', \"a-\") == 1);\n    assert(inPattern('-', \"^A-\") == 0);\n    assert(inPattern('a', \"z-a\") == 1);\n    assert(inPattern('z', \"z-a\") == 1);\n    assert(inPattern('x', \"z-a\") == 0);\n    });\n}\n\n//@@@DEPRECATED_2.086@@@\ndeprecated(\"This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.\")\nbool inPattern(S)(dchar c, S[] patterns) @safe pure @nogc\nif (isSomeString!S)\n{\n    foreach (string pattern; patterns)\n    {\n        if (!inPattern(c, pattern))\n        {\n            return false;\n        }\n    }\n    return true;\n}\n\n//@@@DEPRECATED_2.086@@@\ndeprecated(\"This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.\")\nsize_t countchars(S, S1)(S s, in S1 pattern) @safe pure @nogc\nif (isSomeString!S && isSomeString!S1)\n{\n    size_t count;\n    foreach (dchar c; s)\n    {\n        count += inPattern(c, pattern);\n    }\n    return count;\n}\n\ndeprecated\n@safe pure @nogc unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    assert(countchars(\"abc\", \"a-c\") == 3);\n    assert(countchars(\"hello world\", \"or\") == 3);\n    });\n}\n\n//@@@DEPRECATED_2.086@@@\ndeprecated(\"This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.\")\nS removechars(S)(S s, in S pattern) @safe pure\nif (isSomeString!S)\n{\n    import std.utf : encode;\n\n    Unqual!(typeof(s[0]))[] r;\n    bool changed = false;\n\n    foreach (size_t i, dchar c; s)\n    {\n        if (inPattern(c, pattern))\n        {\n            if (!changed)\n            {\n                changed = true;\n                r = s[0 .. i].dup;\n            }\n            continue;\n        }\n        if (changed)\n        {\n            encode(r, c);\n        }\n    }\n    if (changed)\n        return r;\n    else\n        return s;\n}\n\ndeprecated\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    assert(removechars(\"abc\", \"a-c\").length == 0);\n    assert(removechars(\"hello world\", \"or\") == \"hell wld\");\n    assert(removechars(\"hello world\", \"d\") == \"hello worl\");\n    assert(removechars(\"hah\", \"h\") == \"a\");\n    });\n}\n\ndeprecated\n@safe pure unittest\n{\n    assert(removechars(\"abc\", \"x\") == \"abc\");\n}\n\n//@@@DEPRECATED_2.086@@@\ndeprecated(\"This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.\")\nS squeeze(S)(S s, in S pattern = null)\n{\n    import std.utf : encode, stride;\n\n    Unqual!(typeof(s[0]))[] r;\n    dchar lastc;\n    size_t lasti;\n    int run;\n    bool changed;\n\n    foreach (size_t i, dchar c; s)\n    {\n        if (run && lastc == c)\n        {\n            changed = true;\n        }\n        else if (pattern is null || inPattern(c, pattern))\n        {\n            run = 1;\n            if (changed)\n            {\n                if (r is null)\n                    r = s[0 .. lasti].dup;\n                encode(r, c);\n            }\n            else\n                lasti = i + stride(s, i);\n            lastc = c;\n        }\n        else\n        {\n            run = 0;\n            if (changed)\n            {\n                if (r is null)\n                    r = s[0 .. lasti].dup;\n                encode(r, c);\n            }\n        }\n    }\n    return changed ? ((r is null) ? s[0 .. lasti] : cast(S) r) : s;\n}\n\ndeprecated\n@system pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    string s;\n\n    assert(squeeze(\"hello\") == \"helo\");\n\n    s = \"abcd\";\n    assert(squeeze(s) is s);\n    s = \"xyzz\";\n    assert(squeeze(s).ptr == s.ptr); // should just be a slice\n\n    assert(squeeze(\"hello goodbyee\", \"oe\") == \"hello godbye\");\n    });\n}\n\n//@@@DEPRECATED_2.086@@@\ndeprecated(\"This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.\")\nS1 munch(S1, S2)(ref S1 s, S2 pattern) @safe pure @nogc\n{\n    size_t j = s.length;\n    foreach (i, dchar c; s)\n    {\n        if (!inPattern(c, pattern))\n        {\n            j = i;\n            break;\n        }\n    }\n    scope(exit) s = s[j .. $];\n    return s[0 .. j];\n}\n\n///\ndeprecated\n@safe pure @nogc unittest\n{\n    string s = \"123abc\";\n    string t = munch(s, \"0123456789\");\n    assert(t == \"123\" && s == \"abc\");\n    t = munch(s, \"0123456789\");\n    assert(t == \"\" && s == \"abc\");\n}\n\ndeprecated\n@safe pure @nogc unittest\n{\n    string s = \"123€abc\";\n    string t = munch(s, \"0123456789\");\n    assert(t == \"123\" && s == \"€abc\");\n    t = munch(s, \"0123456789\");\n    assert(t == \"\" && s == \"€abc\");\n    t = munch(s, \"£$€¥\");\n    assert(t == \"€\" && s == \"abc\");\n}\n\n\n/**********************************************\n * Return string that is the 'successor' to s[].\n * If the rightmost character is a-zA-Z0-9, it is incremented within\n * its case or digits. If it generates a carry, the process is\n * repeated with the one to its immediate left.\n */\n\nS succ(S)(S s) @safe pure\nif (isSomeString!S)\n{\n    import std.ascii : isAlphaNum;\n\n    if (s.length && isAlphaNum(s[$ - 1]))\n    {\n        auto r = s.dup;\n        size_t i = r.length - 1;\n\n        while (1)\n        {\n            dchar c = s[i];\n            dchar carry;\n\n            switch (c)\n            {\n            case '9':\n                c = '0';\n                carry = '1';\n                goto Lcarry;\n            case 'z':\n            case 'Z':\n                c -= 'Z' - 'A';\n                carry = c;\n            Lcarry:\n                r[i] = cast(char) c;\n                if (i == 0)\n                {\n                    auto t = new typeof(r[0])[r.length + 1];\n                    t[0] = cast(char) carry;\n                    t[1 .. $] = r[];\n                    return t;\n                }\n                i--;\n                break;\n\n            default:\n                if (isAlphaNum(c))\n                    r[i]++;\n                return r;\n            }\n        }\n    }\n    return s;\n}\n\n///\n@safe pure unittest\n{\n    assert(succ(\"1\") == \"2\");\n    assert(succ(\"9\") == \"10\");\n    assert(succ(\"999\") == \"1000\");\n    assert(succ(\"zz99\") == \"aaa00\");\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    assert(succ(string.init) is null);\n    assert(succ(\"!@#$%\") == \"!@#$%\");\n    assert(succ(\"1\") == \"2\");\n    assert(succ(\"9\") == \"10\");\n    assert(succ(\"999\") == \"1000\");\n    assert(succ(\"zz99\") == \"aaa00\");\n    });\n}\n\n\n/++\n    Replaces the characters in `str` which are in `from` with the\n    the corresponding characters in `to` and returns the resulting string.\n\n    `tr` is based on\n    $(HTTP pubs.opengroup.org/onlinepubs/9699919799/utilities/_tr.html, Posix's tr),\n    though it doesn't do everything that the Posix utility does.\n\n    Params:\n        str       = The original string.\n        from      = The characters to replace.\n        to        = The characters to replace with.\n        modifiers = String containing modifiers.\n\n    Modifiers:\n        $(BOOKTABLE,\n        $(TR $(TD Modifier) $(TD Description))\n        $(TR $(TD `'c'`) $(TD Complement the list of characters in `from`))\n        $(TR $(TD `'d'`) $(TD Removes matching characters with no corresponding\n                              replacement in `to`))\n        $(TR $(TD `'s'`) $(TD Removes adjacent duplicates in the replaced\n                              characters))\n        )\n\n    If the modifier `'d'` is present, then the number of characters in\n    `to` may be only `0` or `1`.\n\n    If the modifier `'d'` is $(I not) present, and `to` is empty, then\n    `to` is taken to be the same as `from`.\n\n    If the modifier `'d'` is $(I not) present, and `to` is shorter than\n    `from`, then `to` is extended by replicating the last character in\n    `to`.\n\n    Both `from` and `to` may contain ranges using the `'-'` character\n    (e.g. `\"a-d\"` is synonymous with `\"abcd\"`.) Neither accept a leading\n    `'^'` as meaning the complement of the string (use the `'c'` modifier\n    for that).\n\n    See_Also:\n        $(LREF translate),\n        $(REF replace, std,array),\n        $(REF substitute, std,algorithm,iteration)\n  +/\nC1[] tr(C1, C2, C3, C4 = immutable char)\n       (C1[] str, const(C2)[] from, const(C3)[] to, const(C4)[] modifiers = null)\n{\n    import std.array : appender;\n    import std.conv : conv_to = to;\n    import std.utf : decode;\n\n    bool mod_c;\n    bool mod_d;\n    bool mod_s;\n\n    foreach (char c; modifiers)\n    {\n        switch (c)\n        {\n        case 'c':   mod_c = 1; break;   // complement\n        case 'd':   mod_d = 1; break;   // delete unreplaced chars\n        case 's':   mod_s = 1; break;   // squeeze duplicated replaced chars\n        default:    assert(0);\n        }\n    }\n\n    if (to.empty && !mod_d)\n        to = conv_to!(typeof(to))(from);\n\n    auto result = appender!(C1[])();\n    bool modified;\n    dchar lastc;\n\n    foreach (dchar c; str)\n    {\n        dchar lastf;\n        dchar lastt;\n        dchar newc;\n        int n = 0;\n\n        for (size_t i = 0; i < from.length; )\n        {\n            immutable f = decode(from, i);\n            if (f == '-' && lastf != dchar.init && i < from.length)\n            {\n                immutable nextf = decode(from, i);\n                if (lastf <= c && c <= nextf)\n                {\n                    n += c - lastf - 1;\n                    if (mod_c)\n                        goto Lnotfound;\n                    goto Lfound;\n                }\n                n += nextf - lastf;\n                lastf = lastf.init;\n                continue;\n            }\n\n            if (c == f)\n            {   if (mod_c)\n                    goto Lnotfound;\n                goto Lfound;\n            }\n            lastf = f;\n            n++;\n        }\n        if (!mod_c)\n            goto Lnotfound;\n        n = 0;          // consider it 'found' at position 0\n\n      Lfound:\n\n        // Find the nth character in to[]\n        dchar nextt;\n        for (size_t i = 0; i < to.length; )\n        {\n            immutable t = decode(to, i);\n            if (t == '-' && lastt != dchar.init && i < to.length)\n            {\n                nextt = decode(to, i);\n                n -= nextt - lastt;\n                if (n < 0)\n                {\n                    newc = nextt + n + 1;\n                    goto Lnewc;\n                }\n                lastt = dchar.init;\n                continue;\n            }\n            if (n == 0)\n            {   newc = t;\n                goto Lnewc;\n            }\n            lastt = t;\n            nextt = t;\n            n--;\n        }\n        if (mod_d)\n            continue;\n        newc = nextt;\n\n      Lnewc:\n        if (mod_s && modified && newc == lastc)\n            continue;\n        result.put(newc);\n        assert(newc != dchar.init);\n        modified = true;\n        lastc = newc;\n        continue;\n\n      Lnotfound:\n        result.put(c);\n        lastc = c;\n        modified = false;\n    }\n\n    return result.data;\n}\n\n///\n@safe pure unittest\n{\n    assert(tr(\"abcdef\", \"cd\", \"CD\") == \"abCDef\");\n    assert(tr(\"1st March, 2018\", \"March\", \"MAR\", \"s\") == \"1st MAR, 2018\");\n    assert(tr(\"abcdef\", \"ef\", \"\", \"d\") == \"abcd\");\n    assert(tr(\"14-Jul-87\", \"a-zA-Z\", \" \", \"cs\") == \" Jul \");\n}\n\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    // Complete list of test types; too slow to test'em all\n    // alias TestTypes = AliasSeq!(\n    //          char[], const( char)[], immutable( char)[],\n    //         wchar[], const(wchar)[], immutable(wchar)[],\n    //         dchar[], const(dchar)[], immutable(dchar)[]);\n\n    // Reduced list of test types\n    alias TestTypes = AliasSeq!(char[], const(wchar)[], immutable(dchar)[]);\n\n    assertCTFEable!(\n    {\n    foreach (S; TestTypes)\n    {\n        foreach (T; TestTypes)\n        {\n            foreach (U; TestTypes)\n            {\n                assert(equal(tr(to!S(\"abcdef\"), to!T(\"cd\"), to!U(\"CD\")), \"abCDef\"));\n                assert(equal(tr(to!S(\"abcdef\"), to!T(\"b-d\"), to!U(\"B-D\")), \"aBCDef\"));\n                assert(equal(tr(to!S(\"abcdefgh\"), to!T(\"b-dh\"), to!U(\"B-Dx\")), \"aBCDefgx\"));\n                assert(equal(tr(to!S(\"abcdefgh\"), to!T(\"b-dh\"), to!U(\"B-CDx\")), \"aBCDefgx\"));\n                assert(equal(tr(to!S(\"abcdefgh\"), to!T(\"b-dh\"), to!U(\"B-BCDx\")), \"aBCDefgx\"));\n                assert(equal(tr(to!S(\"abcdef\"), to!T(\"ef\"), to!U(\"*\"), to!S(\"c\")), \"****ef\"));\n                assert(equal(tr(to!S(\"abcdef\"), to!T(\"ef\"), to!U(\"\"), to!T(\"d\")), \"abcd\"));\n                assert(equal(tr(to!S(\"hello goodbye\"), to!T(\"lo\"), to!U(\"\"), to!U(\"s\")), \"helo godbye\"));\n                assert(equal(tr(to!S(\"hello goodbye\"), to!T(\"lo\"), to!U(\"x\"), \"s\"), \"hex gxdbye\"));\n                assert(equal(tr(to!S(\"14-Jul-87\"), to!T(\"a-zA-Z\"), to!U(\" \"), \"cs\"), \" Jul \"));\n                assert(equal(tr(to!S(\"Abc\"), to!T(\"AAA\"), to!U(\"XYZ\")), \"Xbc\"));\n            }\n        }\n\n        auto s = to!S(\"hello world\");\n        static assert(is(typeof(s) == typeof(tr(s, \"he\", \"if\"))));\n        assert(tr(s, \"he\", \"if\") == \"ifllo world\");\n    }\n    });\n}\n\n@system pure unittest\n{\n    import core.exception : AssertError;\n    import std.exception : assertThrown;\n    assertThrown!AssertError(tr(\"abcdef\", \"cd\", \"CD\", \"X\"));\n}\n\n/**\n * Takes a string `s` and determines if it represents a number. This function\n * also takes an optional parameter, `bAllowSep`, which will accept the\n * separator characters `','` and `'__'` within the string. But these\n * characters should be stripped from the string before using any\n * of the conversion functions like `to!int()`, `to!float()`, and etc\n * else an error will occur.\n *\n * Also please note, that no spaces are allowed within the string\n * anywhere whether it's a leading, trailing, or embedded space(s),\n * thus they too must be stripped from the string before using this\n * function, or any of the conversion functions.\n *\n * Params:\n *     s = the string or random access range to check\n *     bAllowSep = accept separator characters or not\n *\n * Returns:\n *     `bool`\n */\nbool isNumeric(S)(S s, bool bAllowSep = false)\nif (isSomeString!S ||\n    (isRandomAccessRange!S &&\n    hasSlicing!S &&\n    isSomeChar!(ElementType!S) &&\n    !isInfinite!S))\n{\n    import std.algorithm.comparison : among;\n    import std.ascii : isASCII;\n\n    // ASCII only case insensitive comparison with two ranges\n    static bool asciiCmp(S1)(S1 a, string b)\n    {\n        import std.algorithm.comparison : equal;\n        import std.algorithm.iteration : map;\n        import std.ascii : toLower;\n        import std.utf : byChar;\n        return a.map!toLower.equal(b.byChar.map!toLower);\n    }\n\n    // auto-decoding special case, we're only comparing characters\n    // in the ASCII range so there's no reason to decode\n    static if (isSomeString!S)\n    {\n        import std.utf : byCodeUnit;\n        auto codeUnits = s.byCodeUnit;\n    }\n    else\n    {\n        alias codeUnits = s;\n    }\n\n    if (codeUnits.empty)\n        return false;\n\n    // Check for NaN (Not a Number) and for Infinity\n    if (codeUnits.among!((a, b) => asciiCmp(a.save, b))\n            (\"nan\", \"nani\", \"nan+nani\", \"inf\", \"-inf\"))\n        return true;\n\n    immutable frontResult = codeUnits.front;\n    if (frontResult == '-' || frontResult == '+')\n        codeUnits.popFront;\n\n    immutable iLen = codeUnits.length;\n    bool bDecimalPoint, bExponent, bComplex, sawDigits;\n\n    for (size_t i = 0; i < iLen; i++)\n    {\n        immutable c = codeUnits[i];\n\n        if (!c.isASCII)\n            return false;\n\n        // Digits are good, skip to the next character\n        if (c >= '0' && c <= '9')\n        {\n            sawDigits = true;\n            continue;\n        }\n\n        // Check for the complex type, and if found\n        // reset the flags for checking the 2nd number.\n        if (c == '+')\n        {\n            if (!i)\n                return false;\n            bDecimalPoint = false;\n            bExponent = false;\n            bComplex = true;\n            sawDigits = false;\n            continue;\n        }\n\n        // Allow only one exponent per number\n        if (c == 'e' || c == 'E')\n        {\n            // A 2nd exponent found, return not a number\n            if (bExponent || i + 1 >= iLen)\n                return false;\n            // Look forward for the sign, and if\n            // missing then this is not a number.\n            if (codeUnits[i + 1] != '-' && codeUnits[i + 1] != '+')\n                return false;\n            bExponent = true;\n            i++;\n            continue;\n        }\n        // Allow only one decimal point per number to be used\n        if (c == '.')\n        {\n            // A 2nd decimal point found, return not a number\n            if (bDecimalPoint)\n                return false;\n            bDecimalPoint = true;\n            continue;\n        }\n        // Check for ending literal characters: \"f,u,l,i,ul,fi,li\",\n        // and whether they're being used with the correct datatype.\n        if (i == iLen - 2)\n        {\n            if (!sawDigits)\n                return false;\n            // Integer Whole Number\n            if (asciiCmp(codeUnits[i .. iLen], \"ul\") &&\n                    (!bDecimalPoint && !bExponent && !bComplex))\n                return true;\n            // Floating-Point Number\n            if (codeUnits[i .. iLen].among!((a, b) => asciiCmp(a, b))(\"fi\", \"li\") &&\n                    (bDecimalPoint || bExponent || bComplex))\n                return true;\n            if (asciiCmp(codeUnits[i .. iLen], \"ul\") &&\n                    (bDecimalPoint || bExponent || bComplex))\n                return false;\n            // Could be a Integer or a Float, thus\n            // all these suffixes are valid for both\n            return codeUnits[i .. iLen].among!((a, b) => asciiCmp(a, b))\n                (\"ul\", \"fi\", \"li\") != 0;\n        }\n        if (i == iLen - 1)\n        {\n            if (!sawDigits)\n                return false;\n            // Integer Whole Number\n            if (c.among!('u', 'l', 'U', 'L')() &&\n                   (!bDecimalPoint && !bExponent && !bComplex))\n                return true;\n            // Check to see if the last character in the string\n            // is the required 'i' character\n            if (bComplex)\n                return c.among!('i', 'I')() != 0;\n            // Floating-Point Number\n            return c.among!('l', 'L', 'f', 'F', 'i', 'I')() != 0;\n        }\n        // Check if separators are allowed to be in the numeric string\n        if (!bAllowSep || !c.among!('_', ',')())\n            return false;\n    }\n\n    return sawDigits;\n}\n\n/**\n * Integer Whole Number: (byte, ubyte, short, ushort, int, uint, long, and ulong)\n * ['+'|'-']digit(s)[U|L|UL]\n */\n@safe @nogc pure nothrow unittest\n{\n    assert(isNumeric(\"123\"));\n    assert(isNumeric(\"123UL\"));\n    assert(isNumeric(\"123L\"));\n    assert(isNumeric(\"+123U\"));\n    assert(isNumeric(\"-123L\"));\n}\n\n/**\n * Floating-Point Number: (float, double, real, ifloat, idouble, and ireal)\n * ['+'|'-']digit(s)[.][digit(s)][[e-|e+]digit(s)][i|f|L|Li|fi]]\n *      or [nan|nani|inf|-inf]\n */\n@safe @nogc pure nothrow unittest\n{\n    assert(isNumeric(\"+123\"));\n    assert(isNumeric(\"-123.01\"));\n    assert(isNumeric(\"123.3e-10f\"));\n    assert(isNumeric(\"123.3e-10fi\"));\n    assert(isNumeric(\"123.3e-10L\"));\n\n    assert(isNumeric(\"nan\"));\n    assert(isNumeric(\"nani\"));\n    assert(isNumeric(\"-inf\"));\n}\n\n/**\n * Floating-Point Number: (cfloat, cdouble, and creal)\n * ['+'|'-']digit(s)[.][digit(s)][[e-|e+]digit(s)][+]\n *         [digit(s)[.][digit(s)][[e-|e+]digit(s)][i|f|L|Li|fi]]\n *      or [nan|nani|nan+nani|inf|-inf]\n */\n@safe @nogc pure nothrow unittest\n{\n    assert(isNumeric(\"-123e-1+456.9e-10Li\"));\n    assert(isNumeric(\"+123e+10+456i\"));\n    assert(isNumeric(\"123+456\"));\n}\n\n@safe @nogc pure nothrow unittest\n{\n    assert(!isNumeric(\"F\"));\n    assert(!isNumeric(\"L\"));\n    assert(!isNumeric(\"U\"));\n    assert(!isNumeric(\"i\"));\n    assert(!isNumeric(\"fi\"));\n    assert(!isNumeric(\"ul\"));\n    assert(!isNumeric(\"li\"));\n    assert(!isNumeric(\".\"));\n    assert(!isNumeric(\"-\"));\n    assert(!isNumeric(\"+\"));\n    assert(!isNumeric(\"e-\"));\n    assert(!isNumeric(\"e+\"));\n    assert(!isNumeric(\".f\"));\n    assert(!isNumeric(\"e+f\"));\n    assert(!isNumeric(\"++1\"));\n    assert(!isNumeric(\"\"));\n    assert(!isNumeric(\"1E+1E+1\"));\n    assert(!isNumeric(\"1E1\"));\n    assert(!isNumeric(\"\\x81\"));\n}\n\n// Test string types\n@safe unittest\n{\n    import std.conv : to;\n\n    static foreach (T; AliasSeq!(string, char[], wstring, wchar[], dstring, dchar[]))\n    {\n        assert(\"123\".to!T.isNumeric());\n        assert(\"123UL\".to!T.isNumeric());\n        assert(\"123fi\".to!T.isNumeric());\n        assert(\"123li\".to!T.isNumeric());\n        assert(!\"--123L\".to!T.isNumeric());\n    }\n}\n\n// test ranges\n@system pure unittest\n{\n    import std.range : refRange;\n    import std.utf : byCodeUnit;\n\n    assert(\"123\".byCodeUnit.isNumeric());\n    assert(\"123UL\".byCodeUnit.isNumeric());\n    assert(\"123fi\".byCodeUnit.isNumeric());\n    assert(\"123li\".byCodeUnit.isNumeric());\n    assert(!\"--123L\".byCodeUnit.isNumeric());\n\n    dstring z = \"0\";\n    assert(isNumeric(refRange(&z)));\n\n    dstring nani = \"nani\";\n    assert(isNumeric(refRange(&nani)));\n}\n\n/// isNumeric works with CTFE\n@safe pure unittest\n{\n    enum a = isNumeric(\"123.00E-5+1234.45E-12Li\");\n    enum b = isNumeric(\"12345xxxx890\");\n\n    static assert( a);\n    static assert(!b);\n}\n\n@system unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    // Test the isNumeric(in string) function\n    assert(isNumeric(\"1\") == true );\n    assert(isNumeric(\"1.0\") == true );\n    assert(isNumeric(\"1e-1\") == true );\n    assert(isNumeric(\"12345xxxx890\") == false );\n    assert(isNumeric(\"567L\") == true );\n    assert(isNumeric(\"23UL\") == true );\n    assert(isNumeric(\"-123..56f\") == false );\n    assert(isNumeric(\"12.3.5.6\") == false );\n    assert(isNumeric(\" 12.356\") == false );\n    assert(isNumeric(\"123 5.6\") == false );\n    assert(isNumeric(\"1233E-1+1.0e-1i\") == true );\n\n    assert(isNumeric(\"123.00E-5+1234.45E-12Li\") == true);\n    assert(isNumeric(\"123.00e-5+1234.45E-12iL\") == false);\n    assert(isNumeric(\"123.00e-5+1234.45e-12uL\") == false);\n    assert(isNumeric(\"123.00E-5+1234.45e-12lu\") == false);\n\n    assert(isNumeric(\"123fi\") == true);\n    assert(isNumeric(\"123li\") == true);\n    assert(isNumeric(\"--123L\") == false);\n    assert(isNumeric(\"+123.5UL\") == false);\n    assert(isNumeric(\"123f\") == true);\n    assert(isNumeric(\"123.u\") == false);\n\n  // @@@BUG@@ to!string(float) is not CTFEable.\n  // Related: formatValue(T) if (is(FloatingPointTypeOf!T))\n  if (!__ctfe)\n  {\n    assert(isNumeric(to!string(real.nan)) == true);\n    assert(isNumeric(to!string(-real.infinity)) == true);\n  }\n\n    string s = \"$250.99-\";\n    assert(isNumeric(s[1 .. s.length - 2]) == true);\n    assert(isNumeric(s) == false);\n    assert(isNumeric(s[0 .. s.length - 1]) == false);\n    });\n\n    assert(!isNumeric(\"-\"));\n    assert(!isNumeric(\"+\"));\n}\n\nversion (TestComplex)\ndeprecated\n@safe unittest\n{\n    import std.conv : to;\n    assert(isNumeric(to!string(123e+2+1234.78Li)) == true);\n}\n\n/*****************************\n * Soundex algorithm.\n *\n * The Soundex algorithm converts a word into 4 characters\n * based on how the word sounds phonetically. The idea is that\n * two spellings that sound alike will have the same Soundex\n * value, which means that Soundex can be used for fuzzy matching\n * of names.\n *\n * Params:\n *  str = String or InputRange to convert to Soundex representation.\n *\n * Returns:\n *  The four character array with the Soundex result in it.\n *  The array has zero's in it if there is no Soundex representation for the string.\n *\n * See_Also:\n *  $(LINK2 http://en.wikipedia.org/wiki/Soundex, Wikipedia),\n *  $(LUCKY The Soundex Indexing System)\n *  $(LREF soundex)\n *\n * Note:\n *  Only works well with English names.\n */\nchar[4] soundexer(Range)(Range str)\nif (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) &&\n    !isConvertibleToString!Range)\n{\n    alias C = Unqual!(ElementEncodingType!Range);\n\n    static immutable dex =\n        // ABCDEFGHIJKLMNOPQRSTUVWXYZ\n          \"01230120022455012623010202\";\n\n    char[4] result = void;\n    size_t b = 0;\n    C lastc;\n    foreach (C c; str)\n    {\n        if (c >= 'a' && c <= 'z')\n            c -= 'a' - 'A';\n        else if (c >= 'A' && c <= 'Z')\n        {\n        }\n        else\n        {\n            lastc = lastc.init;\n            continue;\n        }\n        if (b == 0)\n        {\n            result[0] = cast(char) c;\n            b++;\n            lastc = dex[c - 'A'];\n        }\n        else\n        {\n            if (c == 'H' || c == 'W')\n                continue;\n            if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U')\n                lastc = lastc.init;\n            c = dex[c - 'A'];\n            if (c != '0' && c != lastc)\n            {\n                result[b] = cast(char) c;\n                b++;\n                lastc = c;\n            }\n            if (b == 4)\n                goto Lret;\n        }\n    }\n    if (b == 0)\n        result[] = 0;\n    else\n        result[b .. 4] = '0';\n  Lret:\n    return result;\n}\n\n/// ditto\nchar[4] soundexer(Range)(auto ref Range str)\nif (isConvertibleToString!Range)\n{\n    return soundexer!(StringTypeOf!Range)(str);\n}\n\n///\n@safe unittest\n{\n    assert(soundexer(\"Gauss\") == \"G200\");\n    assert(soundexer(\"Ghosh\") == \"G200\");\n\n    assert(soundexer(\"Robert\") == \"R163\");\n    assert(soundexer(\"Rupert\") == \"R163\");\n\n    assert(soundexer(\"0123^&^^**&^\") == ['\\0', '\\0', '\\0', '\\0']);\n}\n\n/*****************************\n * Like $(LREF soundexer), but with different parameters\n * and return value.\n *\n * Params:\n *  str = String to convert to Soundex representation.\n *  buffer = Optional 4 char array to put the resulting Soundex\n *      characters into. If null, the return value\n *      buffer will be allocated on the heap.\n * Returns:\n *  The four character array with the Soundex result in it.\n *  Returns null if there is no Soundex representation for the string.\n * See_Also:\n *  $(LREF soundexer)\n */\nchar[] soundex(scope const(char)[] str, char[] buffer = null)\n    @safe pure nothrow\nin\n{\n    assert(buffer is null || buffer.length >= 4);\n}\nout (result)\n{\n    if (result !is null)\n    {\n        assert(result.length == 4);\n        assert(result[0] >= 'A' && result[0] <= 'Z');\n        foreach (char c; result[1 .. 4])\n            assert(c >= '0' && c <= '6');\n    }\n}\ndo\n{\n    char[4] result = soundexer(str);\n    if (result[0] == 0)\n        return null;\n    if (buffer is null)\n        buffer = new char[4];\n    buffer[] = result[];\n    return buffer;\n}\n\n///\n@safe unittest\n{\n    assert(soundex(\"Gauss\") == \"G200\");\n    assert(soundex(\"Ghosh\") == \"G200\");\n\n    assert(soundex(\"Robert\") == \"R163\");\n    assert(soundex(\"Rupert\") == \"R163\");\n\n    assert(soundex(\"0123^&^^**&^\") == null);\n}\n\n@safe pure nothrow unittest\n{\n    import std.exception : assertCTFEable;\n    assertCTFEable!(\n    {\n    char[4] buffer;\n\n    assert(soundex(null) == null);\n    assert(soundex(\"\") == null);\n    assert(soundex(\"0123^&^^**&^\") == null);\n    assert(soundex(\"Euler\") == \"E460\");\n    assert(soundex(\" Ellery \") == \"E460\");\n    assert(soundex(\"Gauss\") == \"G200\");\n    assert(soundex(\"Ghosh\") == \"G200\");\n    assert(soundex(\"Hilbert\") == \"H416\");\n    assert(soundex(\"Heilbronn\") == \"H416\");\n    assert(soundex(\"Knuth\") == \"K530\");\n    assert(soundex(\"Kant\", buffer) == \"K530\");\n    assert(soundex(\"Lloyd\") == \"L300\");\n    assert(soundex(\"Ladd\") == \"L300\");\n    assert(soundex(\"Lukasiewicz\", buffer) == \"L222\");\n    assert(soundex(\"Lissajous\") == \"L222\");\n    assert(soundex(\"Robert\") == \"R163\");\n    assert(soundex(\"Rupert\") == \"R163\");\n    assert(soundex(\"Rubin\") == \"R150\");\n    assert(soundex(\"Washington\") == \"W252\");\n    assert(soundex(\"Lee\") == \"L000\");\n    assert(soundex(\"Gutierrez\") == \"G362\");\n    assert(soundex(\"Pfister\") == \"P236\");\n    assert(soundex(\"Jackson\") == \"J250\");\n    assert(soundex(\"Tymczak\") == \"T522\");\n    assert(soundex(\"Ashcraft\") == \"A261\");\n\n    assert(soundex(\"Woo\") == \"W000\");\n    assert(soundex(\"Pilgrim\") == \"P426\");\n    assert(soundex(\"Flingjingwaller\") == \"F452\");\n    assert(soundex(\"PEARSE\") == \"P620\");\n    assert(soundex(\"PIERCE\") == \"P620\");\n    assert(soundex(\"Price\") == \"P620\");\n    assert(soundex(\"CATHY\") == \"C300\");\n    assert(soundex(\"KATHY\") == \"K300\");\n    assert(soundex(\"Jones\") == \"J520\");\n    assert(soundex(\"johnsons\") == \"J525\");\n    assert(soundex(\"Hardin\") == \"H635\");\n    assert(soundex(\"Martinez\") == \"M635\");\n\n    import std.utf : byChar, byDchar, byWchar;\n    assert(soundexer(\"Martinez\".byChar ) == \"M635\");\n    assert(soundexer(\"Martinez\".byWchar) == \"M635\");\n    assert(soundexer(\"Martinez\".byDchar) == \"M635\");\n    });\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!soundexer(\"Martinez\"));\n}\n\n\n/***************************************************\n * Construct an associative array consisting of all\n * abbreviations that uniquely map to the strings in values.\n *\n * This is useful in cases where the user is expected to type\n * in one of a known set of strings, and the program will helpfully\n * auto-complete the string once sufficient characters have been\n * entered that uniquely identify it.\n */\nstring[string] abbrev(string[] values) @safe pure\n{\n    import std.algorithm.sorting : sort;\n\n    string[string] result;\n\n    // Make a copy when sorting so we follow COW principles.\n    values = values.dup;\n    sort(values);\n\n    size_t values_length = values.length;\n    size_t lasti = values_length;\n    size_t nexti;\n\n    string nv;\n    string lv;\n\n    for (size_t i = 0; i < values_length; i = nexti)\n    {\n        string value = values[i];\n\n        // Skip dups\n        for (nexti = i + 1; nexti < values_length; nexti++)\n        {\n            nv = values[nexti];\n            if (value != values[nexti])\n                break;\n        }\n\n        import std.utf : stride;\n\n        for (size_t j = 0; j < value.length; j += stride(value, j))\n        {\n            string v = value[0 .. j];\n\n            if ((nexti == values_length || j > nv.length || v != nv[0 .. j]) &&\n                (lasti == values_length || j > lv.length || v != lv[0 .. j]))\n            {\n                result[v] = value;\n            }\n        }\n        result[value] = value;\n        lasti = i;\n        lv = value;\n    }\n\n    return result;\n}\n\n///\n@safe unittest\n{\n    import std.string;\n\n    static string[] list = [ \"food\", \"foxy\" ];\n    auto abbrevs = abbrev(list);\n    assert(abbrevs == [\"fox\": \"foxy\", \"food\": \"food\",\n                       \"foxy\": \"foxy\", \"foo\": \"food\"]);\n}\n\n\n@system pure unittest\n{\n    import std.algorithm.sorting : sort;\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    string[] values;\n    values ~= \"hello\";\n    values ~= \"hello\";\n    values ~= \"he\";\n\n    string[string] r;\n\n    r = abbrev(values);\n    auto keys = r.keys.dup;\n    sort(keys);\n\n    assert(keys.length == 4);\n    assert(keys[0] == \"he\");\n    assert(keys[1] == \"hel\");\n    assert(keys[2] == \"hell\");\n    assert(keys[3] == \"hello\");\n\n    assert(r[keys[0]] == \"he\");\n    assert(r[keys[1]] == \"hello\");\n    assert(r[keys[2]] == \"hello\");\n    assert(r[keys[3]] == \"hello\");\n    });\n}\n\n\n/******************************************\n * Compute _column number at the end of the printed form of the string,\n * assuming the string starts in the leftmost _column, which is numbered\n * starting from 0.\n *\n * Tab characters are expanded into enough spaces to bring the _column number\n * to the next multiple of tabsize.\n * If there are multiple lines in the string, the _column number of the last\n * line is returned.\n *\n * Params:\n *    str = string or InputRange to be analyzed\n *    tabsize = number of columns a tab character represents\n *\n * Returns:\n *    column number\n */\n\nsize_t column(Range)(Range str, in size_t tabsize = 8)\nif ((isInputRange!Range && isSomeChar!(Unqual!(ElementEncodingType!Range)) ||\n    isNarrowString!Range) &&\n    !isConvertibleToString!Range)\n{\n    static if (is(Unqual!(ElementEncodingType!Range) == char))\n    {\n        // decoding needed for chars\n        import std.utf : byDchar;\n\n        return str.byDchar.column(tabsize);\n    }\n    else\n    {\n        // decoding not needed for wchars and dchars\n        import std.uni : lineSep, paraSep, nelSep;\n\n        size_t column;\n\n        foreach (const c; str)\n        {\n            switch (c)\n            {\n                case '\\t':\n                    column = (column + tabsize) / tabsize * tabsize;\n                    break;\n\n                case '\\r':\n                case '\\n':\n                case paraSep:\n                case lineSep:\n                case nelSep:\n                    column = 0;\n                    break;\n\n                default:\n                    column++;\n                    break;\n            }\n        }\n        return column;\n    }\n}\n\n///\n@safe pure unittest\n{\n    import std.utf : byChar, byWchar, byDchar;\n\n    assert(column(\"1234 \") == 5);\n    assert(column(\"1234 \"w) == 5);\n    assert(column(\"1234 \"d) == 5);\n\n    assert(column(\"1234 \".byChar()) == 5);\n    assert(column(\"1234 \"w.byWchar()) == 5);\n    assert(column(\"1234 \"d.byDchar()) == 5);\n\n    // Tab stops are set at 8 spaces by default; tab characters insert enough\n    // spaces to bring the column position to the next multiple of 8.\n    assert(column(\"\\t\") == 8);\n    assert(column(\"1\\t\") == 8);\n    assert(column(\"\\t1\") == 9);\n    assert(column(\"123\\t\") == 8);\n\n    // Other tab widths are possible by specifying it explicitly:\n    assert(column(\"\\t\", 4) == 4);\n    assert(column(\"1\\t\", 4) == 4);\n    assert(column(\"\\t1\", 4) == 5);\n    assert(column(\"123\\t\", 4) == 4);\n\n    // New lines reset the column number.\n    assert(column(\"abc\\n\") == 0);\n    assert(column(\"abc\\n1\") == 1);\n    assert(column(\"abcdefg\\r1234\") == 4);\n    assert(column(\"abc\\u20281\") == 1);\n    assert(column(\"abc\\u20291\") == 1);\n    assert(column(\"abc\\u00851\") == 1);\n    assert(column(\"abc\\u00861\") == 5);\n}\n\nsize_t column(Range)(auto ref Range str, in size_t tabsize = 8)\nif (isConvertibleToString!Range)\n{\n    return column!(StringTypeOf!Range)(str, tabsize);\n}\n\n@safe pure unittest\n{\n    assert(testAliasedString!column(\"abc\\u00861\"));\n}\n\n@safe @nogc unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    assert(column(string.init) == 0);\n    assert(column(\"\") == 0);\n    assert(column(\"\\t\") == 8);\n    assert(column(\"abc\\t\") == 8);\n    assert(column(\"12345678\\t\") == 16);\n    });\n}\n\n/******************************************\n * Wrap text into a paragraph.\n *\n * The input text string s is formed into a paragraph\n * by breaking it up into a sequence of lines, delineated\n * by \\n, such that the number of columns is not exceeded\n * on each line.\n * The last line is terminated with a \\n.\n * Params:\n *  s = text string to be wrapped\n *  columns = maximum number of _columns in the paragraph\n *  firstindent = string used to _indent first line of the paragraph\n *  indent = string to use to _indent following lines of the paragraph\n *  tabsize = column spacing of tabs in firstindent[] and indent[]\n * Returns:\n *  resulting paragraph as an allocated string\n */\n\nS wrap(S)(S s, in size_t columns = 80, S firstindent = null,\nS indent = null, in size_t tabsize = 8)\nif (isSomeString!S)\n{\n    import std.uni : isWhite;\n    typeof(s.dup) result;\n    bool inword;\n    bool first = true;\n    size_t wordstart;\n\n    const indentcol = column(indent, tabsize);\n\n    result.length = firstindent.length + s.length;\n    result.length = firstindent.length;\n    result[] = firstindent[];\n    auto col = column(firstindent, tabsize);\n    foreach (size_t i, dchar c; s)\n    {\n        if (isWhite(c))\n        {\n            if (inword)\n            {\n                if (first)\n                {\n                }\n                else if (col + 1 + (i - wordstart) > columns)\n                {\n                    result ~= '\\n';\n                    result ~= indent;\n                    col = indentcol;\n                }\n                else\n                {\n                    result ~= ' ';\n                    col += 1;\n                }\n                result ~= s[wordstart .. i];\n                col += i - wordstart;\n                inword = false;\n                first = false;\n            }\n        }\n        else\n        {\n            if (!inword)\n            {\n                wordstart = i;\n                inword = true;\n            }\n        }\n    }\n\n    if (inword)\n    {\n        if (col + 1 + (s.length - wordstart) >= columns)\n        {\n            result ~= '\\n';\n            result ~= indent;\n        }\n        else if (result.length != firstindent.length)\n            result ~= ' ';\n        result ~= s[wordstart .. s.length];\n    }\n    result ~= '\\n';\n\n    return result;\n}\n\n///\n@safe pure unittest\n{\n    assert(wrap(\"a short string\", 7) == \"a short\\nstring\\n\");\n\n    // wrap will not break inside of a word, but at the next space\n    assert(wrap(\"a short string\", 4) == \"a\\nshort\\nstring\\n\");\n\n    assert(wrap(\"a short string\", 7, \"\\t\") == \"\\ta\\nshort\\nstring\\n\");\n    assert(wrap(\"a short string\", 7, \"\\t\", \"    \") == \"\\ta\\n    short\\n    string\\n\");\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    assertCTFEable!(\n    {\n    assert(wrap(string.init) == \"\\n\");\n    assert(wrap(\" a b   df \") == \"a b df\\n\");\n    assert(wrap(\" a b   df \", 3) == \"a b\\ndf\\n\");\n    assert(wrap(\" a bc   df \", 3) == \"a\\nbc\\ndf\\n\");\n    assert(wrap(\" abcd   df \", 3) == \"abcd\\ndf\\n\");\n    assert(wrap(\"x\") == \"x\\n\");\n    assert(wrap(\"u u\") == \"u u\\n\");\n    assert(wrap(\"abcd\", 3) == \"\\nabcd\\n\");\n    assert(wrap(\"a de\", 10, \"\\t\", \"   \", 8) == \"\\ta\\n   de\\n\");\n    });\n}\n\n/******************************************\n * Removes one level of indentation from a multi-line string.\n *\n * This uniformly outdents the text as much as possible.\n * Whitespace-only lines are always converted to blank lines.\n *\n * Does not allocate memory if it does not throw.\n *\n * Params:\n *     str = multi-line string\n *\n * Returns:\n *      outdented string\n *\n * Throws:\n *     StringException if indentation is done with different sequences\n *     of whitespace characters.\n */\nS outdent(S)(S str) @safe pure\nif (isSomeString!S)\n{\n    return str.splitLines(Yes.keepTerminator).outdent().join();\n}\n\n///\n@safe pure unittest\n{\n    enum pretty = q{\n       import std.stdio;\n       void main() {\n           writeln(\"Hello\");\n       }\n    }.outdent();\n\n    enum ugly = q{\nimport std.stdio;\nvoid main() {\n    writeln(\"Hello\");\n}\n};\n\n    assert(pretty == ugly);\n}\n\n\n/******************************************\n * Removes one level of indentation from an array of single-line strings.\n *\n * This uniformly outdents the text as much as possible.\n * Whitespace-only lines are always converted to blank lines.\n *\n * Params:\n *     lines = array of single-line strings\n *\n * Returns:\n *      lines[] is rewritten in place with outdented lines\n *\n * Throws:\n *     StringException if indentation is done with different sequences\n *     of whitespace characters.\n */\nS[] outdent(S)(S[] lines) @safe pure\nif (isSomeString!S)\n{\n    import std.algorithm.searching : startsWith;\n\n    if (lines.empty)\n    {\n        return null;\n    }\n\n    static S leadingWhiteOf(S str)\n    {\n        return str[ 0 .. $ - stripLeft(str).length ];\n    }\n\n    S shortestIndent;\n    foreach (ref line; lines)\n    {\n        const stripped = line.stripLeft();\n\n        if (stripped.empty)\n        {\n            line = line[line.chomp().length .. $];\n        }\n        else\n        {\n            const indent = leadingWhiteOf(line);\n\n            // Comparing number of code units instead of code points is OK here\n            // because this function throws upon inconsistent indentation.\n            if (shortestIndent is null || indent.length < shortestIndent.length)\n            {\n                if (indent.empty)\n                    return lines;\n                shortestIndent = indent;\n            }\n        }\n    }\n\n    foreach (ref line; lines)\n    {\n        const stripped = line.stripLeft();\n\n        if (stripped.empty)\n        {\n            // Do nothing\n        }\n        else if (line.startsWith(shortestIndent))\n        {\n            line = line[shortestIndent.length .. $];\n        }\n        else\n        {\n            throw new StringException(\"outdent: Inconsistent indentation\");\n        }\n    }\n\n    return lines;\n}\n\n///\n@safe pure unittest\n{\n    auto str1 = [\n        \"    void main()\\n\",\n        \"    {\\n\",\n        \"        test();\\n\",\n        \"    }\\n\"\n    ];\n    auto str1Expected = [\n        \"void main()\\n\",\n        \"{\\n\",\n        \"    test();\\n\",\n        \"}\\n\"\n    ];\n    assert(str1.outdent == str1Expected);\n\n    auto str2 = [\n        \"void main()\\n\",\n        \"    {\\n\",\n        \"            test();\\n\",\n        \"    }\\n\"\n    ];\n    assert(str2.outdent == str2);\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n\n    template outdent_testStr(S)\n    {\n        enum S outdent_testStr =\n\"\n \\t\\tX\n \\t\\U00010143X\n \\t\\t\n\n \\t\\t\\tX\n\\t \";\n    }\n\n    template outdent_expected(S)\n    {\n        enum S outdent_expected =\n\"\n\\tX\n\\U00010143X\n\n\n\\t\\tX\n\";\n    }\n\n    assertCTFEable!(\n    {\n\n    static foreach (S; AliasSeq!(string, wstring, dstring))\n    {{\n        enum S blank = \"\";\n        assert(blank.outdent() == blank);\n        static assert(blank.outdent() == blank);\n\n        enum S testStr1  = \" \\n \\t\\n \";\n        enum S expected1 = \"\\n\\n\";\n        assert(testStr1.outdent() == expected1);\n        static assert(testStr1.outdent() == expected1);\n\n        assert(testStr1[0..$-1].outdent() == expected1);\n        static assert(testStr1[0..$-1].outdent() == expected1);\n\n        enum S testStr2  = \"a\\n \\t\\nb\";\n        assert(testStr2.outdent() == testStr2);\n        static assert(testStr2.outdent() == testStr2);\n\n        enum S testStr3 =\n\"\n \\t\\tX\n \\t\\U00010143X\n \\t\\t\n\n \\t\\t\\tX\n\\t \";\n\n        enum S expected3 =\n\"\n\\tX\n\\U00010143X\n\n\n\\t\\tX\n\";\n        assert(testStr3.outdent() == expected3);\n        static assert(testStr3.outdent() == expected3);\n\n        enum testStr4 = \"  X\\r  X\\n  X\\r\\n  X\\u2028  X\\u2029  X\";\n        enum expected4 = \"X\\rX\\nX\\r\\nX\\u2028X\\u2029X\";\n        assert(testStr4.outdent() == expected4);\n        static assert(testStr4.outdent() == expected4);\n\n        enum testStr5  = testStr4[0..$-1];\n        enum expected5 = expected4[0..$-1];\n        assert(testStr5.outdent() == expected5);\n        static assert(testStr5.outdent() == expected5);\n\n        enum testStr6 = \"  \\r  \\n  \\r\\n  \\u2028  \\u2029\";\n        enum expected6 = \"\\r\\n\\r\\n\\u2028\\u2029\";\n        assert(testStr6.outdent() == expected6);\n        static assert(testStr6.outdent() == expected6);\n\n        enum testStr7 = \" a \\n b \";\n        enum expected7 = \"a \\nb \";\n        assert(testStr7.outdent() == expected7);\n        static assert(testStr7.outdent() == expected7);\n    }}\n    });\n}\n\n@safe pure unittest\n{\n    import std.exception : assertThrown;\n    auto bad = \"      a\\n\\tb\\n   c\";\n    assertThrown!StringException(bad.outdent);\n}\n\n/** Assume the given array of integers `arr` is a well-formed UTF string and\nreturn it typed as a UTF string.\n\n`ubyte` becomes `char`, `ushort` becomes `wchar` and `uint`\nbecomes `dchar`. Type qualifiers are preserved.\n\nWhen compiled with debug mode, this function performs an extra check to make\nsure the return value is a valid Unicode string.\n\nParams:\n    arr = array of bytes, ubytes, shorts, ushorts, ints, or uints\n\nReturns:\n    arr retyped as an array of chars, wchars, or dchars\n\nSee_Also: $(LREF representation)\n*/\nauto assumeUTF(T)(T[] arr) pure\nif (staticIndexOf!(Unqual!T, ubyte, ushort, uint) != -1)\n{\n    import std.traits : ModifyTypePreservingTQ;\n    import std.utf : validate;\n    alias ToUTFType(U) = AliasSeq!(char, wchar, dchar)[U.sizeof / 2];\n    auto asUTF = cast(ModifyTypePreservingTQ!(ToUTFType, T)[])arr;\n    debug validate(asUTF);\n    return asUTF;\n}\n\n///\n@safe pure unittest\n{\n    string a = \"Hölo World\";\n    immutable(ubyte)[] b = a.representation;\n    string c = b.assumeUTF;\n\n    assert(a == c);\n}\n\npure @system unittest\n{\n    import std.algorithm.comparison : equal;\n    static foreach (T; AliasSeq!(char[], wchar[], dchar[]))\n    {{\n        immutable T jti = \"Hello World\";\n        T jt = jti.dup;\n\n        static if (is(T == char[]))\n        {\n            auto gt = cast(ubyte[]) jt;\n            auto gtc = cast(const(ubyte)[])jt;\n            auto gti = cast(immutable(ubyte)[])jt;\n        }\n        else static if (is(T == wchar[]))\n        {\n            auto gt = cast(ushort[]) jt;\n            auto gtc = cast(const(ushort)[])jt;\n            auto gti = cast(immutable(ushort)[])jt;\n        }\n        else static if (is(T == dchar[]))\n        {\n            auto gt = cast(uint[]) jt;\n            auto gtc = cast(const(uint)[])jt;\n            auto gti = cast(immutable(uint)[])jt;\n        }\n\n        auto ht = assumeUTF(gt);\n        auto htc = assumeUTF(gtc);\n        auto hti = assumeUTF(gti);\n        assert(equal(jt, ht));\n        assert(equal(jt, htc));\n        assert(equal(jt, hti));\n    }}\n}\n"
  },
  {
    "path": "libphobos/src/std/system.d",
    "content": "// Written in the D programming language.\n\n/**\n * Information about the target operating system, environment, and CPU.\n *\n *  Copyright: Copyright The D Language Foundation 2000 - 2011\n *  License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n *  Authors:   $(HTTP digitalmars.com, Walter Bright) and\n               $(HTTP jmdavisprog.com, Jonathan M Davis)\n *  Source:    $(PHOBOSSRC std/system.d)\n */\nmodule std.system;\n\nimmutable\n{\n    /++\n        Operating system.\n\n        Note:\n            This is for cases where you need a value representing the OS at\n            runtime. If you're doing something which should compile differently\n            on different OSes, then please use `version (Windows)`,\n            `version (linux)`, etc.\n\n        See_Also:\n            $(DDSUBLINK spec/version,PredefinedVersions, Predefined Versions)\n      +/\n    enum OS\n    {\n        win32 = 1, /// Microsoft 32 bit Windows systems\n        win64,     /// Microsoft 64 bit Windows systems\n        linux,     /// All Linux Systems, except for Android\n        osx,       /// Mac OS X\n        freeBSD,   /// FreeBSD\n        netBSD,    /// NetBSD\n        dragonFlyBSD, /// DragonFlyBSD\n        solaris,   /// Solaris\n        android,   /// Android\n        otherPosix /// Other Posix Systems\n    }\n\n    /// The OS that the program was compiled for.\n    version (Win32)        OS os = OS.win32;\n    else version (Win64)   OS os = OS.win64;\n    else version (Android) OS os = OS.android;\n    else version (linux)   OS os = OS.linux;\n    else version (OSX)     OS os = OS.osx;\n    else version (FreeBSD) OS os = OS.freeBSD;\n    else version (NetBSD)  OS os = OS.netBSD;\n    else version (DragonFlyBSD) OS os = OS.dragonFlyBSD;\n    else version (Posix)   OS os = OS.otherPosix;\n    else static assert(0, \"Unknown OS.\");\n\n    /++\n        Byte order endianness.\n\n        Note:\n            This is intended for cases where you need to deal with endianness at\n            runtime. If you're doing something which should compile differently\n            depending on whether you're compiling on a big endian or little\n            endian machine, then please use `version (BigEndian)` and\n            `version (LittleEndian)`.\n\n        See_Also:\n            $(DDSUBLINK spec/version,PredefinedVersions, Predefined Versions)\n      +/\n    enum Endian\n    {\n        bigEndian,   /// Big endian byte order\n        littleEndian /// Little endian byte order\n    }\n\n    /// The endianness that the program was compiled for.\n    version (LittleEndian) Endian endian = Endian.littleEndian;\n    else                  Endian endian = Endian.bigEndian;\n}\n\n"
  },
  {
    "path": "libphobos/src/std/traits.d",
    "content": "// Written in the D programming language.\n\n/**\n * Templates which extract information about types and symbols at compile time.\n *\n * $(SCRIPT inhibitQuickIndex = 1;)\n *\n * $(DIVC quickindex,\n * $(BOOKTABLE ,\n * $(TR $(TH Category) $(TH Templates))\n * $(TR $(TD Symbol Name traits) $(TD\n *           $(LREF fullyQualifiedName)\n *           $(LREF moduleName)\n *           $(LREF packageName)\n * ))\n * $(TR $(TD Function traits) $(TD\n *           $(LREF isFunction)\n *           $(LREF arity)\n *           $(LREF functionAttributes)\n *           $(LREF hasFunctionAttributes)\n *           $(LREF functionLinkage)\n *           $(LREF FunctionTypeOf)\n *           $(LREF isSafe)\n *           $(LREF isUnsafe)\n *           $(LREF isFinal)\n *           $(LREF ParameterDefaults)\n *           $(LREF ParameterIdentifierTuple)\n *           $(LREF ParameterStorageClassTuple)\n *           $(LREF Parameters)\n *           $(LREF ReturnType)\n *           $(LREF SetFunctionAttributes)\n *           $(LREF variadicFunctionStyle)\n * ))\n * $(TR $(TD Aggregate Type traits) $(TD\n *           $(LREF BaseClassesTuple)\n *           $(LREF BaseTypeTuple)\n *           $(LREF classInstanceAlignment)\n *           $(LREF EnumMembers)\n *           $(LREF FieldNameTuple)\n *           $(LREF Fields)\n *           $(LREF hasAliasing)\n *           $(LREF hasElaborateAssign)\n *           $(LREF hasElaborateCopyConstructor)\n *           $(LREF hasElaborateDestructor)\n *           $(LREF hasIndirections)\n *           $(LREF hasMember)\n *           $(LREF hasStaticMember)\n *           $(LREF hasNested)\n *           $(LREF hasUnsharedAliasing)\n *           $(LREF InterfacesTuple)\n *           $(LREF isInnerClass)\n *           $(LREF isNested)\n *           $(LREF MemberFunctionsTuple)\n *           $(LREF RepresentationTypeTuple)\n *           $(LREF TemplateArgsOf)\n *           $(LREF TemplateOf)\n *           $(LREF TransitiveBaseTypeTuple)\n * ))\n * $(TR $(TD Type Conversion) $(TD\n *           $(LREF CommonType)\n *           $(LREF ImplicitConversionTargets)\n *           $(LREF CopyTypeQualifiers)\n *           $(LREF CopyConstness)\n *           $(LREF isAssignable)\n *           $(LREF isCovariantWith)\n *           $(LREF isImplicitlyConvertible)\n * ))\n * $(TR $(TD SomethingTypeOf) $(TD\n *           $(LREF rvalueOf)\n *           $(LREF lvalueOf)\n *           $(LREF InoutOf)\n *           $(LREF ConstOf)\n *           $(LREF SharedOf)\n *           $(LREF SharedInoutOf)\n *           $(LREF SharedConstOf)\n *           $(LREF ImmutableOf)\n *           $(LREF QualifierOf)\n * ))\n * $(TR $(TD Categories of types) $(TD\n *           $(LREF allSameType)\n *           $(LREF ifTestable)\n *           $(LREF isType)\n *           $(LREF isAggregateType)\n *           $(LREF isArray)\n *           $(LREF isAssociativeArray)\n *           $(LREF isAutodecodableString)\n *           $(LREF isBasicType)\n *           $(LREF isBoolean)\n *           $(LREF isBuiltinType)\n *           $(LREF isCopyable)\n *           $(LREF isDynamicArray)\n *           $(LREF isEqualityComparable)\n *           $(LREF isFloatingPoint)\n *           $(LREF isIntegral)\n *           $(LREF isNarrowString)\n *           $(LREF isConvertibleToString)\n *           $(LREF isNumeric)\n *           $(LREF isOrderingComparable)\n *           $(LREF isPointer)\n *           $(LREF isScalarType)\n *           $(LREF isSigned)\n *           $(LREF isSIMDVector)\n *           $(LREF isSomeChar)\n *           $(LREF isSomeString)\n *           $(LREF isStaticArray)\n *           $(LREF isUnsigned)\n * ))\n * $(TR $(TD Type behaviours) $(TD\n *           $(LREF isAbstractClass)\n *           $(LREF isAbstractFunction)\n *           $(LREF isCallable)\n *           $(LREF isDelegate)\n *           $(LREF isExpressions)\n *           $(LREF isFinalClass)\n *           $(LREF isFinalFunction)\n *           $(LREF isFunctionPointer)\n *           $(LREF isInstanceOf)\n *           $(LREF isIterable)\n *           $(LREF isMutable)\n *           $(LREF isSomeFunction)\n *           $(LREF isTypeTuple)\n * ))\n * $(TR $(TD General Types) $(TD\n *           $(LREF ForeachType)\n *           $(LREF KeyType)\n *           $(LREF Largest)\n *           $(LREF mostNegative)\n *           $(LREF OriginalType)\n *           $(LREF PointerTarget)\n *           $(LREF Signed)\n *           $(LREF Unqual)\n *           $(LREF Unsigned)\n *           $(LREF ValueType)\n *           $(LREF Promoted)\n * ))\n * $(TR $(TD Misc) $(TD\n *           $(LREF mangledName)\n *           $(LREF Select)\n *           $(LREF select)\n * ))\n * $(TR $(TD User-Defined Attributes) $(TD\n *           $(LREF hasUDA)\n *           $(LREF getUDAs)\n *           $(LREF getSymbolsByUDA)\n * ))\n * )\n * )\n *\n * Copyright: Copyright The D Language Foundation 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright),\n *            Tomasz Stachowiak (`isExpressions`),\n *            $(HTTP erdani.org, Andrei Alexandrescu),\n *            Shin Fujishiro,\n *            $(HTTP octarineparrot.com, Robert Clipsham),\n *            $(HTTP klickverbot.at, David Nadlinger),\n *            Kenji Hara,\n *            Shoichi Kato\n * Source:    $(PHOBOSSRC std/traits.d)\n */\n/*          Copyright The D Language Foundation 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.traits;\n\nimport std.meta : AliasSeq, allSatisfy;\nimport std.functional : unaryFun;\n\n// Legacy inheritance from std.typetuple\n// See also: https://github.com/dlang/phobos/pull/5484#discussion_r122602797\nimport std.meta : staticMapMeta = staticMap;\n// TODO: find a way to trigger deprecation warnings\n//deprecated(\"staticMap is part of std.meta: Please import std.meta\")\nalias staticMap = staticMapMeta;\n\n///////////////////////////////////////////////////////////////////////////////\n// Functions\n///////////////////////////////////////////////////////////////////////////////\n\n// Petit demangler\n// (this or similar thing will eventually go to std.demangle if necessary\n//  ctfe stuffs are available)\nprivate\n{\n    struct Demangle(T)\n    {\n        T       value;  // extracted information\n        string  rest;\n    }\n\n    /* Demangles mstr as the storage class part of Argument. */\n    Demangle!uint demangleParameterStorageClass(string mstr)\n    {\n        uint pstc = 0; // parameter storage class\n\n        // Argument --> Argument2 | M Argument2\n        if (mstr.length > 0 && mstr[0] == 'M')\n        {\n            pstc |= ParameterStorageClass.scope_;\n            mstr  = mstr[1 .. $];\n        }\n\n        // Argument2 --> Type | J Type | K Type | L Type\n        ParameterStorageClass stc2;\n\n        switch (mstr.length ? mstr[0] : char.init)\n        {\n            case 'J': stc2 = ParameterStorageClass.out_;  break;\n            case 'K': stc2 = ParameterStorageClass.ref_;  break;\n            case 'L': stc2 = ParameterStorageClass.lazy_; break;\n            case 'N': if (mstr.length >= 2 && mstr[1] == 'k')\n                        stc2 = ParameterStorageClass.return_;\n                      break;\n            default : break;\n        }\n        if (stc2 != ParameterStorageClass.init)\n        {\n            pstc |= stc2;\n            mstr  = mstr[1 .. $];\n            if (stc2 & ParameterStorageClass.return_)\n                mstr  = mstr[1 .. $];\n        }\n\n        return Demangle!uint(pstc, mstr);\n    }\n\n    /* Demangles mstr as FuncAttrs. */\n    Demangle!uint demangleFunctionAttributes(string mstr)\n    {\n        immutable LOOKUP_ATTRIBUTE =\n        [\n            'a': FunctionAttribute.pure_,\n            'b': FunctionAttribute.nothrow_,\n            'c': FunctionAttribute.ref_,\n            'd': FunctionAttribute.property,\n            'e': FunctionAttribute.trusted,\n            'f': FunctionAttribute.safe,\n            'i': FunctionAttribute.nogc,\n            'j': FunctionAttribute.return_,\n            'l': FunctionAttribute.scope_\n        ];\n        uint atts = 0;\n\n        // FuncAttrs --> FuncAttr | FuncAttr FuncAttrs\n        // FuncAttr  --> empty | Na | Nb | Nc | Nd | Ne | Nf | Ni | Nj\n        // except 'Ng' == inout, because it is a qualifier of function type\n        while (mstr.length >= 2 && mstr[0] == 'N' && mstr[1] != 'g' && mstr[1] != 'k')\n        {\n            if (FunctionAttribute att = LOOKUP_ATTRIBUTE[ mstr[1] ])\n            {\n                atts |= att;\n                mstr  = mstr[2 .. $];\n            }\n            else assert(0);\n        }\n        return Demangle!uint(atts, mstr);\n    }\n\n    static if (is(ucent))\n    {\n        alias CentTypeList         = AliasSeq!(cent, ucent);\n        alias SignedCentTypeList   = AliasSeq!(cent);\n        alias UnsignedCentTypeList = AliasSeq!(ucent);\n    }\n    else\n    {\n        alias CentTypeList         = AliasSeq!();\n        alias SignedCentTypeList   = AliasSeq!();\n        alias UnsignedCentTypeList = AliasSeq!();\n    }\n\n    alias IntegralTypeList      = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList);\n    alias SignedIntTypeList     = AliasSeq!(byte, short, int, long, SignedCentTypeList);\n    alias UnsignedIntTypeList   = AliasSeq!(ubyte, ushort, uint, ulong, UnsignedCentTypeList);\n    alias FloatingPointTypeList = AliasSeq!(float, double, real);\n    alias ImaginaryTypeList     = AliasSeq!(ifloat, idouble, ireal);\n    alias ComplexTypeList       = AliasSeq!(cfloat, cdouble, creal);\n    alias NumericTypeList       = AliasSeq!(IntegralTypeList, FloatingPointTypeList);\n    alias CharTypeList          = AliasSeq!(char, wchar, dchar);\n}\n\npackage\n{\n    // Add the mutable qualifier to the given type T.\n    template MutableOf(T)     { alias MutableOf     =              T  ; }\n}\n\n/**\n * Params:\n *     T = The type to qualify\n * Returns:\n *     `T` with the `inout` qualifier added.\n */\ntemplate InoutOf(T)\n{\n    alias InoutOf = inout(T);\n}\n\n///\n@safe unittest\n{\n    static assert(is(InoutOf!(int) == inout int));\n    static assert(is(InoutOf!(inout int) == inout int));\n    static assert(is(InoutOf!(const int) == inout const int));\n    static assert(is(InoutOf!(shared int) == inout shared int));\n}\n\n/**\n * Params:\n *     T = The type to qualify\n * Returns:\n *     `T` with the `const` qualifier added.\n */\ntemplate ConstOf(T)\n{\n    alias ConstOf = const(T);\n}\n\n///\n@safe unittest\n{\n    static assert(is(ConstOf!(int) == const int));\n    static assert(is(ConstOf!(const int) == const int));\n    static assert(is(ConstOf!(inout int) == const inout int));\n    static assert(is(ConstOf!(shared int) == const shared int));\n}\n\n/**\n * Params:\n *     T = The type to qualify\n * Returns:\n *     `T` with the `shared` qualifier added.\n */\ntemplate SharedOf(T)\n{\n    alias SharedOf = shared(T);\n}\n\n///\n@safe unittest\n{\n    static assert(is(SharedOf!(int) == shared int));\n    static assert(is(SharedOf!(shared int) == shared int));\n    static assert(is(SharedOf!(inout int) == shared inout int));\n    static assert(is(SharedOf!(immutable int) == shared immutable int));\n}\n\n/**\n * Params:\n *     T = The type to qualify\n * Returns:\n *     `T` with the `inout` and `shared` qualifiers added.\n */\ntemplate SharedInoutOf(T)\n{\n    alias SharedInoutOf = shared(inout(T));\n}\n\n///\n@safe unittest\n{\n    static assert(is(SharedInoutOf!(int) == shared inout int));\n    static assert(is(SharedInoutOf!(int) == inout shared int));\n\n    static assert(is(SharedInoutOf!(const int) == shared inout const int));\n    static assert(is(SharedInoutOf!(immutable int) == shared inout immutable int));\n}\n\n/**\n * Params:\n *     T = The type to qualify\n * Returns:\n *     `T` with the `const` and `shared` qualifiers added.\n */\ntemplate SharedConstOf(T)\n{\n    alias SharedConstOf = shared(const(T));\n}\n\n///\n@safe unittest\n{\n    static assert(is(SharedConstOf!(int) == shared const int));\n    static assert(is(SharedConstOf!(int) == const shared int));\n\n    static assert(is(SharedConstOf!(inout int) == shared inout const int));\n    // immutable variables are implicitly shared and const\n    static assert(is(SharedConstOf!(immutable int) == immutable int));\n}\n\n/**\n * Params:\n *     T = The type to qualify\n * Returns:\n *     `T` with the `immutable` qualifier added.\n */\ntemplate ImmutableOf(T)\n{\n    alias ImmutableOf = immutable(T);\n}\n\n///\n@safe unittest\n{\n    static assert(is(ImmutableOf!(int) == immutable int));\n    static assert(is(ImmutableOf!(const int) == immutable int));\n    static assert(is(ImmutableOf!(inout int) == immutable int));\n    static assert(is(ImmutableOf!(shared int) == immutable int));\n}\n\n@safe unittest\n{\n    static assert(is(    MutableOf!int ==              int));\n    static assert(is(      InoutOf!int ==        inout int));\n    static assert(is(      ConstOf!int ==        const int));\n    static assert(is(     SharedOf!int == shared       int));\n    static assert(is(SharedInoutOf!int == shared inout int));\n    static assert(is(SharedConstOf!int == shared const int));\n    static assert(is(  ImmutableOf!int ==    immutable int));\n}\n\n/**\n * Gives a template that can be used to apply the same\n * attributes that are on the given type `T`. E.g. passing\n * `inout shared int` will return `SharedInoutOf`.\n *\n * Params:\n *     T = the type to check qualifiers from\n * Returns:\n *     The qualifier template from the given type `T`\n */\ntemplate QualifierOf(T)\n{\n    static if (is(T == shared(const U), U))\n        alias QualifierOf = SharedConstOf;\n    else static if (is(T == const U, U))\n        alias QualifierOf = ConstOf;\n    else static if (is(T == shared(inout U), U))\n        alias QualifierOf = SharedInoutOf;\n    else static if (is(T == inout U, U))\n        alias QualifierOf = InoutOf;\n    else static if (is(T == immutable U, U))\n        alias QualifierOf = ImmutableOf;\n    else static if (is(T == shared U, U))\n        alias QualifierOf = SharedOf;\n    else\n        alias QualifierOf = MutableOf;\n}\n\n///\n@safe unittest\n{\n    static assert(__traits(isSame, QualifierOf!(immutable int), ImmutableOf));\n    static assert(__traits(isSame, QualifierOf!(shared int), SharedOf));\n    static assert(__traits(isSame, QualifierOf!(shared inout int), SharedInoutOf));\n}\n\n@safe unittest\n{\n    alias Qual1 = QualifierOf!(             int);   static assert(is(Qual1!long ==              long));\n    alias Qual2 = QualifierOf!(       inout int);   static assert(is(Qual2!long ==        inout long));\n    alias Qual3 = QualifierOf!(       const int);   static assert(is(Qual3!long ==        const long));\n    alias Qual4 = QualifierOf!(shared       int);   static assert(is(Qual4!long == shared       long));\n    alias Qual5 = QualifierOf!(shared inout int);   static assert(is(Qual5!long == shared inout long));\n    alias Qual6 = QualifierOf!(shared const int);   static assert(is(Qual6!long == shared const long));\n    alias Qual7 = QualifierOf!(   immutable int);   static assert(is(Qual7!long ==    immutable long));\n}\n\nversion (unittest)\n{\n    alias TypeQualifierList = AliasSeq!(MutableOf, ConstOf, SharedOf, SharedConstOf, ImmutableOf);\n\n    struct SubTypeOf(T)\n    {\n        T val;\n        alias val this;\n    }\n}\n\nprivate alias parentOf(alias sym) = Identity!(__traits(parent, sym));\nprivate alias parentOf(alias sym : T!Args, alias T, Args...) = Identity!(__traits(parent, T));\n\n/**\n * Get the full package name for the given symbol.\n */\ntemplate packageName(alias T)\n{\n    import std.algorithm.searching : startsWith;\n\n    enum bool isNotFunc = !isSomeFunction!(T);\n\n    static if (__traits(compiles, parentOf!T))\n        enum parent = packageName!(parentOf!T);\n    else\n        enum string parent = null;\n\n    static if (isNotFunc && T.stringof.startsWith(\"package \"))\n        enum packageName = (parent.length ? parent ~ '.' : \"\") ~ T.stringof[8 .. $];\n    else static if (parent)\n        enum packageName = parent;\n    else\n        static assert(false, T.stringof ~ \" has no parent\");\n}\n\n///\n@safe unittest\n{\n    static assert(packageName!packageName == \"std\");\n}\n\n@safe unittest\n{\n    import std.array;\n\n    static assert(packageName!std == \"std\");\n    static assert(packageName!(std.traits) == \"std\");     // this module\n    static assert(packageName!packageName == \"std\");      // symbol in this module\n    static assert(packageName!(std.array) == \"std\");  // other module from same package\n\n    import core.sync.barrier;  // local import\n    static assert(packageName!core == \"core\");\n    static assert(packageName!(core.sync) == \"core.sync\");\n    static assert(packageName!Barrier == \"core.sync\");\n\n    struct X12287(T) { T i; }\n    static assert(packageName!(X12287!int.i) == \"std\");\n}\n\nversion (none) @safe unittest //Please uncomment me when changing packageName to test global imports\n{\n    import core.sync.barrier;  // global import\n    static assert(packageName!core == \"core\");\n    static assert(packageName!(core.sync) == \"core.sync\");\n    static assert(packageName!Barrier == \"core.sync\");\n}\n\n///\n@safe unittest\n{\n    static assert(packageName!moduleName == \"std\");\n}\n\n@safe unittest // issue 13741\n{\n    import std.ascii : isWhite;\n    static assert(packageName!(isWhite) == \"std\");\n\n    struct Foo{void opCall(int){}}\n    static assert(packageName!(Foo.opCall) == \"std\");\n\n    @property void function(int) vf;\n    static assert(packageName!(vf) == \"std\");\n}\n\n/**\n * Get the module name (including package) for the given symbol.\n */\ntemplate moduleName(alias T)\n{\n    import std.algorithm.searching : startsWith;\n\n    enum bool isNotFunc = !isSomeFunction!(T);\n\n    static if (isNotFunc)\n        static assert(!T.stringof.startsWith(\"package \"),\n            \"cannot get the module name for a package\");\n\n    static if (isNotFunc && T.stringof.startsWith(\"module \"))\n    {\n        static if (__traits(compiles, packageName!T))\n            enum packagePrefix = packageName!T ~ '.';\n        else\n            enum packagePrefix = \"\";\n\n        enum moduleName = packagePrefix ~ T.stringof[7..$];\n    }\n    else\n        alias moduleName = moduleName!(parentOf!T); // If you use enum, it will cause compiler ICE\n}\n\n///\n@safe unittest\n{\n    static assert(moduleName!moduleName == \"std.traits\");\n}\n\n@safe unittest\n{\n    import std.array;\n\n    static assert(!__traits(compiles, moduleName!std));\n    static assert(moduleName!(std.traits) == \"std.traits\");            // this module\n    static assert(moduleName!moduleName == \"std.traits\");              // symbol in this module\n    static assert(moduleName!(std.array) == \"std.array\");      // other module\n    static assert(moduleName!(std.array.array) == \"std.array\");  // symbol in other module\n\n    import core.sync.barrier;  // local import\n    static assert(!__traits(compiles, moduleName!(core.sync)));\n    static assert(moduleName!(core.sync.barrier) == \"core.sync.barrier\");\n    static assert(moduleName!Barrier == \"core.sync.barrier\");\n\n    struct X12287(T) { T i; }\n    static assert(moduleName!(X12287!int.i) == \"std.traits\");\n}\n\n@safe unittest // issue 13741\n{\n    import std.ascii : isWhite;\n    static assert(moduleName!(isWhite) == \"std.ascii\");\n\n    struct Foo{void opCall(int){}}\n    static assert(moduleName!(Foo.opCall) == \"std.traits\");\n\n    @property void function(int) vf;\n    static assert(moduleName!(vf) == \"std.traits\");\n}\n\nversion (none) @safe unittest //Please uncomment me when changing moduleName to test global imports\n{\n    import core.sync.barrier;  // global import\n    static assert(!__traits(compiles, moduleName!(core.sync)));\n    static assert(moduleName!(core.sync.barrier) == \"core.sync.barrier\");\n    static assert(moduleName!Barrier == \"core.sync.barrier\");\n}\n\n/***\n * Get the fully qualified name of a type or a symbol. Can act as an intelligent type/symbol to string  converter.\n\nExample:\n-----------------\nmodule myModule;\nstruct MyStruct {}\nstatic assert(fullyQualifiedName!(const MyStruct[]) == \"const(myModule.MyStruct[])\");\n-----------------\n*/\ntemplate fullyQualifiedName(T...)\nif (T.length == 1)\n{\n\n    static if (is(T))\n        enum fullyQualifiedName = fqnType!(T[0], false, false, false, false);\n    else\n        enum fullyQualifiedName = fqnSym!(T[0]);\n}\n\n///\n@safe unittest\n{\n    static assert(fullyQualifiedName!fullyQualifiedName == \"std.traits.fullyQualifiedName\");\n}\n\nversion (unittest)\n{\n    // Used for both fqnType and fqnSym unittests\n    private struct QualifiedNameTests\n    {\n        struct Inner\n        {\n            bool value;\n        }\n\n        ref const(Inner[string]) func( ref Inner var1, lazy scope string var2 );\n        ref const(Inner[string]) retfunc( return ref Inner var1 );\n        Inner inoutFunc(inout Inner) inout;\n        shared(const(Inner[string])[]) data;\n        const Inner delegate(double, string) @safe nothrow deleg;\n        inout(int) delegate(inout int) inout inoutDeleg;\n        Inner function(out double, string) funcPtr;\n        extern(C) Inner function(double, string) cFuncPtr;\n\n        extern(C) void cVarArg(int, ...);\n        void dVarArg(...);\n        void dVarArg2(int, ...);\n        void typesafeVarArg(int[] ...);\n\n        Inner[] array;\n        Inner[16] sarray;\n        Inner[Inner] aarray;\n        const(Inner[const(Inner)]) qualAarray;\n\n        shared(immutable(Inner) delegate(ref double, scope string) const shared @trusted nothrow) attrDeleg;\n\n        struct Data(T) { int x; }\n        void tfunc(T...)(T args) {}\n\n        template Inst(alias A) { int x; }\n\n        class Test12309(T, int x, string s) {}\n    }\n\n    private enum QualifiedEnum\n    {\n        a = 42\n    }\n}\n\nprivate template fqnSym(alias T : X!A, alias X, A...)\n{\n    template fqnTuple(T...)\n    {\n        static if (T.length == 0)\n            enum fqnTuple = \"\";\n        else static if (T.length == 1)\n        {\n            static if (isExpressionTuple!T)\n                enum fqnTuple = T[0].stringof;\n            else\n                enum fqnTuple = fullyQualifiedName!(T[0]);\n        }\n        else\n            enum fqnTuple = fqnTuple!(T[0]) ~ \", \" ~ fqnTuple!(T[1 .. $]);\n    }\n\n    enum fqnSym =\n        fqnSym!(__traits(parent, X)) ~\n        '.' ~ __traits(identifier, X) ~ \"!(\" ~ fqnTuple!A ~ \")\";\n}\n\nprivate template fqnSym(alias T)\n{\n    static if (__traits(compiles, __traits(parent, T)) && !__traits(isSame, T, __traits(parent, T)))\n        enum parentPrefix = fqnSym!(__traits(parent, T)) ~ \".\";\n    else\n        enum parentPrefix = null;\n\n    static string adjustIdent(string s)\n    {\n        import std.algorithm.searching : findSplit, skipOver;\n\n        if (s.skipOver(\"package \") || s.skipOver(\"module \"))\n            return s;\n        return s.findSplit(\"(\")[0];\n    }\n    enum fqnSym = parentPrefix ~ adjustIdent(__traits(identifier, T));\n}\n\n@safe unittest\n{\n    alias fqn = fullyQualifiedName;\n\n    // Make sure those 2 are the same\n    static assert(fqnSym!fqn == fqn!fqn);\n\n    static assert(fqn!fqn == \"std.traits.fullyQualifiedName\");\n\n    alias qnTests = QualifiedNameTests;\n    enum prefix = \"std.traits.QualifiedNameTests.\";\n    static assert(fqn!(qnTests.Inner)           == prefix ~ \"Inner\");\n    static assert(fqn!(qnTests.func)            == prefix ~ \"func\");\n    static assert(fqn!(qnTests.Data!int)        == prefix ~ \"Data!(int)\");\n    static assert(fqn!(qnTests.Data!int.x)      == prefix ~ \"Data!(int).x\");\n    static assert(fqn!(qnTests.tfunc!(int[]))   == prefix ~ \"tfunc!(int[])\");\n    static assert(fqn!(qnTests.Inst!(Object))   == prefix ~ \"Inst!(object.Object)\");\n    static assert(fqn!(qnTests.Inst!(Object).x) == prefix ~ \"Inst!(object.Object).x\");\n\n    static assert(fqn!(qnTests.Test12309!(int, 10, \"str\"))\n                                                == prefix ~ \"Test12309!(int, 10, \\\"str\\\")\");\n\n    import core.sync.barrier;\n    static assert(fqn!Barrier == \"core.sync.barrier.Barrier\");\n}\n\n@safe unittest\n{\n    struct TemplatedStruct()\n    {\n        enum foo = 0;\n    }\n    alias TemplatedStructAlias = TemplatedStruct;\n    assert(\"TemplatedStruct.foo\" == fullyQualifiedName!(TemplatedStructAlias!().foo));\n}\n\nprivate template fqnType(T,\n    bool alreadyConst, bool alreadyImmutable, bool alreadyShared, bool alreadyInout)\n{\n    import std.format : format;\n\n    // Convenience tags\n    enum {\n        _const = 0,\n        _immutable = 1,\n        _shared = 2,\n        _inout = 3\n    }\n\n    alias qualifiers   = AliasSeq!(is(T == const), is(T == immutable), is(T == shared), is(T == inout));\n    alias noQualifiers = AliasSeq!(false, false, false, false);\n\n    string storageClassesString(uint psc)() @property\n    {\n        alias PSC = ParameterStorageClass;\n\n        return format(\"%s%s%s%s%s\",\n            psc & PSC.scope_ ? \"scope \" : \"\",\n            psc & PSC.return_ ? \"return \" : \"\",\n            psc & PSC.out_ ? \"out \" : \"\",\n            psc & PSC.ref_ ? \"ref \" : \"\",\n            psc & PSC.lazy_ ? \"lazy \" : \"\"\n        );\n    }\n\n    string parametersTypeString(T)() @property\n    {\n        alias parameters   = Parameters!(T);\n        alias parameterStC = ParameterStorageClassTuple!(T);\n\n        enum variadic = variadicFunctionStyle!T;\n        static if (variadic == Variadic.no)\n            enum variadicStr = \"\";\n        else static if (variadic == Variadic.c)\n            enum variadicStr = \", ...\";\n        else static if (variadic == Variadic.d)\n            enum variadicStr = parameters.length ? \", ...\" : \"...\";\n        else static if (variadic == Variadic.typesafe)\n            enum variadicStr = \" ...\";\n        else\n            static assert(0, \"New variadic style has been added, please update fullyQualifiedName implementation\");\n\n        static if (parameters.length)\n        {\n            import std.algorithm.iteration : map;\n            import std.array : join;\n            import std.meta : staticMap;\n            import std.range : zip;\n\n            string result = join(\n                map!(a => format(\"%s%s\", a[0], a[1]))(\n                    zip([staticMap!(storageClassesString, parameterStC)],\n                        [staticMap!(fullyQualifiedName, parameters)])\n                ),\n                \", \"\n            );\n\n            return result ~= variadicStr;\n        }\n        else\n            return variadicStr;\n    }\n\n    string linkageString(T)() @property\n    {\n        enum linkage = functionLinkage!T;\n\n        if (linkage != \"D\")\n            return format(\"extern(%s) \", linkage);\n        else\n            return \"\";\n    }\n\n    string functionAttributeString(T)() @property\n    {\n        alias FA = FunctionAttribute;\n        enum attrs = functionAttributes!T;\n\n        static if (attrs == FA.none)\n            return \"\";\n        else\n            return format(\"%s%s%s%s%s%s%s%s\",\n                 attrs & FA.pure_ ? \" pure\" : \"\",\n                 attrs & FA.nothrow_ ? \" nothrow\" : \"\",\n                 attrs & FA.ref_ ? \" ref\" : \"\",\n                 attrs & FA.property ? \" @property\" : \"\",\n                 attrs & FA.trusted ? \" @trusted\" : \"\",\n                 attrs & FA.safe ? \" @safe\" : \"\",\n                 attrs & FA.nogc ? \" @nogc\" : \"\",\n                 attrs & FA.return_ ? \" return\" : \"\"\n            );\n    }\n\n    string addQualifiers(string typeString,\n        bool addConst, bool addImmutable, bool addShared, bool addInout)\n    {\n        auto result = typeString;\n        if (addShared)\n        {\n            result = format(\"shared(%s)\", result);\n        }\n        if (addConst || addImmutable || addInout)\n        {\n            result = format(\"%s(%s)\",\n                addConst ? \"const\" :\n                    addImmutable ? \"immutable\" : \"inout\",\n                result\n            );\n        }\n        return result;\n    }\n\n    // Convenience template to avoid copy-paste\n    template chain(string current)\n    {\n        enum chain = addQualifiers(current,\n            qualifiers[_const]     && !alreadyConst,\n            qualifiers[_immutable] && !alreadyImmutable,\n            qualifiers[_shared]    && !alreadyShared,\n            qualifiers[_inout]     && !alreadyInout);\n    }\n\n    static if (is(T == string))\n    {\n        enum fqnType = \"string\";\n    }\n    else static if (is(T == wstring))\n    {\n        enum fqnType = \"wstring\";\n    }\n    else static if (is(T == dstring))\n    {\n        enum fqnType = \"dstring\";\n    }\n    else static if (isBasicType!T && !is(T == enum))\n    {\n        enum fqnType = chain!((Unqual!T).stringof);\n    }\n    else static if (isAggregateType!T || is(T == enum))\n    {\n        enum fqnType = chain!(fqnSym!T);\n    }\n    else static if (isStaticArray!T)\n    {\n        enum fqnType = chain!(\n            format(\"%s[%s]\", fqnType!(typeof(T.init[0]), qualifiers), T.length)\n        );\n    }\n    else static if (isArray!T)\n    {\n        enum fqnType = chain!(\n            format(\"%s[]\", fqnType!(typeof(T.init[0]), qualifiers))\n        );\n    }\n    else static if (isAssociativeArray!T)\n    {\n        enum fqnType = chain!(\n            format(\"%s[%s]\", fqnType!(ValueType!T, qualifiers), fqnType!(KeyType!T, noQualifiers))\n        );\n    }\n    else static if (isSomeFunction!T)\n    {\n        static if (is(T F == delegate))\n        {\n            enum qualifierString = format(\"%s%s\",\n                is(F == shared) ? \" shared\" : \"\",\n                is(F == inout) ? \" inout\" :\n                is(F == immutable) ? \" immutable\" :\n                is(F == const) ? \" const\" : \"\"\n            );\n            enum formatStr = \"%s%s delegate(%s)%s%s\";\n            enum fqnType = chain!(\n                format(formatStr, linkageString!T, fqnType!(ReturnType!T, noQualifiers),\n                    parametersTypeString!(T), functionAttributeString!T, qualifierString)\n            );\n        }\n        else\n        {\n            static if (isFunctionPointer!T)\n                enum formatStr = \"%s%s function(%s)%s\";\n            else\n                enum formatStr = \"%s%s(%s)%s\";\n\n            enum fqnType = chain!(\n                format(formatStr, linkageString!T, fqnType!(ReturnType!T, noQualifiers),\n                    parametersTypeString!(T), functionAttributeString!T)\n            );\n        }\n    }\n    else static if (isPointer!T)\n    {\n        enum fqnType = chain!(\n            format(\"%s*\", fqnType!(PointerTarget!T, qualifiers))\n        );\n    }\n    else static if (is(T : __vector(V[N]), V, size_t N))\n    {\n        enum fqnType = chain!(\n            format(\"__vector(%s[%s])\", fqnType!(V, qualifiers), N)\n        );\n    }\n    else\n        // In case something is forgotten\n        static assert(0, \"Unrecognized type \" ~ T.stringof ~ \", can't convert to fully qualified string\");\n}\n\n@safe unittest\n{\n    import std.format : format;\n    alias fqn = fullyQualifiedName;\n\n    // Verify those 2 are the same for simple case\n    alias Ambiguous = const(QualifiedNameTests.Inner);\n    static assert(fqn!Ambiguous == fqnType!(Ambiguous, false, false, false, false));\n\n    // Main tests\n    enum inner_name = \"std.traits.QualifiedNameTests.Inner\";\n    with (QualifiedNameTests)\n    {\n        // Special cases\n        static assert(fqn!(string) == \"string\");\n        static assert(fqn!(wstring) == \"wstring\");\n        static assert(fqn!(dstring) == \"dstring\");\n        static assert(fqn!(void) == \"void\");\n        static assert(fqn!(const(void)) == \"const(void)\");\n        static assert(fqn!(shared(void)) == \"shared(void)\");\n        static assert(fqn!(shared const(void)) == \"const(shared(void))\");\n        static assert(fqn!(shared inout(void)) == \"inout(shared(void))\");\n        static assert(fqn!(shared inout const(void)) == \"const(shared(void))\");\n        static assert(fqn!(inout(void)) == \"inout(void)\");\n        static assert(fqn!(inout const(void)) == \"const(void)\");\n        static assert(fqn!(immutable(void)) == \"immutable(void)\");\n\n        // Basic qualified name\n        static assert(fqn!(Inner) == inner_name);\n        static assert(fqn!(QualifiedEnum) == \"std.traits.QualifiedEnum\"); // type\n        static assert(fqn!(QualifiedEnum.a) == \"std.traits.QualifiedEnum.a\"); // symbol\n\n        // Array types\n        static assert(fqn!(typeof(array)) == format(\"%s[]\", inner_name));\n        static assert(fqn!(typeof(sarray)) == format(\"%s[16]\", inner_name));\n        static assert(fqn!(typeof(aarray)) == format(\"%s[%s]\", inner_name, inner_name));\n\n        // qualified key for AA\n        static assert(fqn!(typeof(qualAarray)) == format(\"const(%s[const(%s)])\", inner_name, inner_name));\n\n        // Qualified composed data types\n        static assert(fqn!(typeof(data)) == format(\"shared(const(%s[string])[])\", inner_name));\n\n        // Function types + function attributes\n        static assert(fqn!(typeof(func)) == format(\"const(%s[string])(ref %s, scope lazy string) ref\",\n                    inner_name, inner_name));\n        static assert(fqn!(typeof(retfunc)) == format(\"const(%s[string])(return %s) ref\", inner_name, inner_name));\n        static assert(fqn!(typeof(inoutFunc)) == format(\"inout(%s(inout(%s)))\", inner_name, inner_name));\n        static assert(fqn!(typeof(deleg)) == format(\"const(%s delegate(double, string) nothrow @safe)\", inner_name));\n        static assert(fqn!(typeof(inoutDeleg)) == \"inout(int) delegate(inout(int)) inout\");\n        static assert(fqn!(typeof(funcPtr)) == format(\"%s function(out double, string)\", inner_name));\n        static assert(fqn!(typeof(cFuncPtr)) == format(\"extern(C) %s function(double, string)\", inner_name));\n\n        // Delegate type with qualified function type\n        static assert(fqn!(typeof(attrDeleg)) == format(\"shared(immutable(%s) \"~\n            \"delegate(ref double, scope string) nothrow @trusted shared const)\", inner_name));\n\n        // Variable argument function types\n        static assert(fqn!(typeof(cVarArg)) == \"extern(C) void(int, ...)\");\n        static assert(fqn!(typeof(dVarArg)) == \"void(...)\");\n        static assert(fqn!(typeof(dVarArg2)) == \"void(int, ...)\");\n        static assert(fqn!(typeof(typesafeVarArg)) == \"void(int[] ...)\");\n\n        // SIMD vector\n        static if (is(__vector(float[4])))\n        {\n            static assert(fqn!(__vector(float[4])) == \"__vector(float[4])\");\n        }\n    }\n}\n\n/***\n * Get the type of the return value from a function,\n * a pointer to function, a delegate, a struct\n * with an opCall, a pointer to a struct with an opCall,\n * or a class with an `opCall`. Please note that $(D_KEYWORD ref)\n * is not part of a type, but the attribute of the function\n * (see template $(LREF functionAttributes)).\n */\ntemplate ReturnType(func...)\nif (func.length == 1 && isCallable!func)\n{\n    static if (is(FunctionTypeOf!func R == return))\n        alias ReturnType = R;\n    else\n        static assert(0, \"argument has no return type\");\n}\n\n///\n@safe unittest\n{\n    int foo();\n    ReturnType!foo x;   // x is declared as int\n}\n\n@safe unittest\n{\n    struct G\n    {\n        int opCall (int i) { return 1;}\n    }\n\n    alias ShouldBeInt = ReturnType!G;\n    static assert(is(ShouldBeInt == int));\n\n    G g;\n    static assert(is(ReturnType!g == int));\n\n    G* p;\n    alias pg = ReturnType!p;\n    static assert(is(pg == int));\n\n    class C\n    {\n        int opCall (int i) { return 1;}\n    }\n\n    static assert(is(ReturnType!C == int));\n\n    C c;\n    static assert(is(ReturnType!c == int));\n\n    class Test\n    {\n        int prop() @property { return 0; }\n    }\n    alias R_Test_prop = ReturnType!(Test.prop);\n    static assert(is(R_Test_prop == int));\n\n    alias R_dglit = ReturnType!((int a) { return a; });\n    static assert(is(R_dglit == int));\n}\n\n/***\nGet, as a tuple, the types of the parameters to a function, a pointer\nto function, a delegate, a struct with an `opCall`, a pointer to a\nstruct with an `opCall`, or a class with an `opCall`.\n*/\ntemplate Parameters(func...)\nif (func.length == 1 && isCallable!func)\n{\n    static if (is(FunctionTypeOf!func P == function))\n        alias Parameters = P;\n    else\n        static assert(0, \"argument has no parameters\");\n}\n\n///\n@safe unittest\n{\n    int foo(int, long);\n    void bar(Parameters!foo);      // declares void bar(int, long);\n    void abc(Parameters!foo[1]);   // declares void abc(long);\n}\n\n/**\n * Alternate name for $(LREF Parameters), kept for legacy compatibility.\n */\nalias ParameterTypeTuple = Parameters;\n\n@safe unittest\n{\n    int foo(int i, bool b) { return 0; }\n    static assert(is(ParameterTypeTuple!foo == AliasSeq!(int, bool)));\n    static assert(is(ParameterTypeTuple!(typeof(&foo)) == AliasSeq!(int, bool)));\n\n    struct S { real opCall(real r, int i) { return 0.0; } }\n    S s;\n    static assert(is(ParameterTypeTuple!S == AliasSeq!(real, int)));\n    static assert(is(ParameterTypeTuple!(S*) == AliasSeq!(real, int)));\n    static assert(is(ParameterTypeTuple!s == AliasSeq!(real, int)));\n\n    class Test\n    {\n        int prop() @property { return 0; }\n    }\n    alias P_Test_prop = ParameterTypeTuple!(Test.prop);\n    static assert(P_Test_prop.length == 0);\n\n    alias P_dglit = ParameterTypeTuple!((int a){});\n    static assert(P_dglit.length == 1);\n    static assert(is(P_dglit[0] == int));\n}\n\n/**\nReturns the number of arguments of function `func`.\narity is undefined for variadic functions.\n*/\ntemplate arity(func...)\nif (func.length == 1 && isCallable!func &&\n    variadicFunctionStyle!func == Variadic.no)\n{\n    enum size_t arity = Parameters!func.length;\n}\n\n///\n@safe unittest\n{\n    void foo(){}\n    static assert(arity!foo == 0);\n    void bar(uint){}\n    static assert(arity!bar == 1);\n    void variadicFoo(uint...){}\n    static assert(!__traits(compiles, arity!variadicFoo));\n}\n\n@safe unittest // issue 11389\n{\n    alias TheType = size_t function( string[] );\n    static assert(arity!TheType == 1);\n}\n\n/**\nGet tuple, one per function parameter, of the storage classes of the parameters.\nParams:\n    func = function symbol or type of function, delegate, or pointer to function\nReturns:\n    A tuple of ParameterStorageClass bits\n */\nenum ParameterStorageClass : uint\n{\n    /**\n     * These flags can be bitwise OR-ed together to represent complex storage\n     * class.\n     */\n    none    = 0,\n    scope_  = 1,    /// ditto\n    out_    = 2,    /// ditto\n    ref_    = 4,    /// ditto\n    lazy_   = 8,    /// ditto\n    return_ = 0x10, /// ditto\n}\n\n/// ditto\ntemplate ParameterStorageClassTuple(func...)\nif (func.length == 1 && isCallable!func)\n{\n    alias Func = FunctionTypeOf!func;\n\n    static if (is(Func PT == __parameters))\n    {\n        template StorageClass(size_t i)\n        {\n            static if (i < PT.length)\n            {\n                alias StorageClass = AliasSeq!(\n                        extractParameterStorageClassFlags!(__traits(getParameterStorageClasses, Func, i)),\n                        StorageClass!(i + 1));\n            }\n            else\n                alias StorageClass = AliasSeq!();\n        }\n        alias ParameterStorageClassTuple = StorageClass!0;\n    }\n    else\n    {\n        static assert(0, func[0].stringof ~ \" is not a function\");\n        alias ParameterStorageClassTuple = AliasSeq!();\n    }\n}\n\n///\n@safe unittest\n{\n    alias STC = ParameterStorageClass; // shorten the enum name\n\n    void func(ref int ctx, out real result, real param)\n    {\n    }\n    alias pstc = ParameterStorageClassTuple!func;\n    static assert(pstc.length == 3); // three parameters\n    static assert(pstc[0] == STC.ref_);\n    static assert(pstc[1] == STC.out_);\n    static assert(pstc[2] == STC.none);\n}\n\n/**\nConvert the result of `__traits(getParameterStorageClasses)`\nto $(LREF ParameterStorageClass) `enum`s.\n\nParams:\n    Attribs = The return value of `__traits(getParameterStorageClasses)`\nReturns:\n    The bitwise OR of the equivalent $(LREF ParameterStorageClass) `enum`s.\n */\ntemplate extractParameterStorageClassFlags(Attribs...)\n{\n    enum ParameterStorageClass extractParameterStorageClassFlags = ()\n    {\n        auto result = ParameterStorageClass.none;\n        static if (Attribs.length > 0)\n        {\n            static foreach (attrib; Attribs)\n            {\n                final switch (attrib) with (ParameterStorageClass)\n                {\n                    case \"scope\":  result |= scope_;  break;\n                    case \"out\":    result |= out_;    break;\n                    case \"ref\":    result |= ref_;    break;\n                    case \"lazy\":   result |= lazy_;   break;\n                    case \"return\": result |= return_; break;\n                }\n            }\n            /* Mimic behavor of original version of ParameterStorageClassTuple()\n             * to avoid breaking existing code.\n             */\n            if (result == (ParameterStorageClass.ref_ | ParameterStorageClass.return_))\n                result = ParameterStorageClass.return_;\n        }\n        return result;\n    }();\n}\n\n///\n@safe unittest\n{\n    static void func(ref int ctx, out real result);\n\n    enum param1 = extractParameterStorageClassFlags!(\n        __traits(getParameterStorageClasses, func, 0)\n    );\n    static assert(param1 == ParameterStorageClass.ref_);\n\n    enum param2 = extractParameterStorageClassFlags!(\n        __traits(getParameterStorageClasses, func, 1)\n    );\n    static assert(param2 == ParameterStorageClass.out_);\n\n    enum param3 = extractParameterStorageClassFlags!(\n        __traits(getParameterStorageClasses, func, 0),\n        __traits(getParameterStorageClasses, func, 1)\n    );\n    static assert(param3 == (ParameterStorageClass.ref_ | ParameterStorageClass.out_));\n}\n\n@safe unittest\n{\n    alias STC = ParameterStorageClass;\n\n    void noparam() {}\n    static assert(ParameterStorageClassTuple!noparam.length == 0);\n\n    ref int test(scope int*, ref int, out int, lazy int, int, return ref int i) { return i; }\n    alias test_pstc = ParameterStorageClassTuple!test;\n    static assert(test_pstc.length == 6);\n    static assert(test_pstc[0] == STC.scope_);\n    static assert(test_pstc[1] == STC.ref_);\n    static assert(test_pstc[2] == STC.out_);\n    static assert(test_pstc[3] == STC.lazy_);\n    static assert(test_pstc[4] == STC.none);\n    static assert(test_pstc[5] == STC.return_);\n\n    interface Test\n    {\n        void test_const(int) const;\n        void test_sharedconst(int) shared const;\n    }\n    Test testi;\n\n    alias test_const_pstc = ParameterStorageClassTuple!(Test.test_const);\n    static assert(test_const_pstc.length == 1);\n    static assert(test_const_pstc[0] == STC.none);\n\n    alias test_sharedconst_pstc = ParameterStorageClassTuple!(testi.test_sharedconst);\n    static assert(test_sharedconst_pstc.length == 1);\n    static assert(test_sharedconst_pstc[0] == STC.none);\n\n    alias dglit_pstc = ParameterStorageClassTuple!((ref int a) {});\n    static assert(dglit_pstc.length == 1);\n    static assert(dglit_pstc[0] == STC.ref_);\n\n    // Bugzilla 9317\n    static inout(int) func(inout int param) { return param; }\n    static assert(ParameterStorageClassTuple!(typeof(func))[0] == STC.none);\n}\n\n@safe unittest\n{\n    // Bugzilla 14253\n    static struct Foo {\n        ref Foo opAssign(ref Foo rhs) return { return this; }\n    }\n\n    alias tup = ParameterStorageClassTuple!(__traits(getOverloads, Foo, \"opAssign\")[0]);\n}\n\n\n/**\nGet, as a tuple, the identifiers of the parameters to a function symbol.\n */\ntemplate ParameterIdentifierTuple(func...)\nif (func.length == 1 && isCallable!func)\n{\n    static if (is(FunctionTypeOf!func PT == __parameters))\n    {\n        template Get(size_t i)\n        {\n            static if (!isFunctionPointer!func && !isDelegate!func\n                       // Unnamed parameters yield CT error.\n                       && is(typeof(__traits(identifier, PT[i .. i+1]))))\n            {\n                enum Get = __traits(identifier, PT[i .. i+1]);\n            }\n            else\n            {\n                enum Get = \"\";\n            }\n        }\n    }\n    else\n    {\n        static assert(0, func[0].stringof ~ \"is not a function\");\n\n        // Define dummy entities to avoid pointless errors\n        template Get(size_t i) { enum Get = \"\"; }\n        alias PT = AliasSeq!();\n    }\n\n    template Impl(size_t i = 0)\n    {\n        static if (i == PT.length)\n            alias Impl = AliasSeq!();\n        else\n            alias Impl = AliasSeq!(Get!i, Impl!(i+1));\n    }\n\n    alias ParameterIdentifierTuple = Impl!();\n}\n\n///\n@safe unittest\n{\n    int foo(int num, string name, int);\n    static assert([ParameterIdentifierTuple!foo] == [\"num\", \"name\", \"\"]);\n}\n\n@safe unittest\n{\n    alias PIT = ParameterIdentifierTuple;\n\n    void bar(int num, string name, int[] array){}\n    static assert([PIT!bar] == [\"num\", \"name\", \"array\"]);\n\n    // might be changed in the future?\n    void function(int num, string name) fp;\n    static assert([PIT!fp] == [\"\", \"\"]);\n\n    // might be changed in the future?\n    void delegate(int num, string name, int[long] aa) dg;\n    static assert([PIT!dg] == [\"\", \"\", \"\"]);\n\n    interface Test\n    {\n        @property string getter();\n        @property void setter(int a);\n        Test method(int a, long b, string c);\n    }\n    static assert([PIT!(Test.getter)] == []);\n    static assert([PIT!(Test.setter)] == [\"a\"]);\n    static assert([PIT!(Test.method)] == [\"a\", \"b\", \"c\"]);\n\n/+\n    // depends on internal\n    void baw(int, string, int[]){}\n    static assert([PIT!baw] == [\"_param_0\", \"_param_1\", \"_param_2\"]);\n\n    // depends on internal\n    void baz(AliasSeq!(int, string, int[]) args){}\n    static assert([PIT!baz] == [\"_param_0\", \"_param_1\", \"_param_2\"]);\n+/\n}\n\n\n/**\nGet, as a tuple, the default value of the parameters to a function symbol.\nIf a parameter doesn't have the default value, `void` is returned instead.\n */\ntemplate ParameterDefaults(func...)\nif (func.length == 1 && isCallable!func)\n{\n    alias param_names = ParameterIdentifierTuple!func;\n    static if (is(FunctionTypeOf!(func[0]) PT == __parameters))\n    {\n        template Get(size_t i)\n        {\n            // `PT[i .. i+1]` declares a parameter with an arbitrary name.\n            // To avoid a name clash, generate local names that are distinct\n            // from the parameter name, and mix them in.\n            enum name = param_names[i];\n            enum args = \"args\" ~ (name == \"args\" ? \"_\" : \"\");\n            enum val = \"val\" ~ (name == \"val\" ? \"_\" : \"\");\n            enum ptr = \"ptr\" ~ (name == \"ptr\" ? \"_\" : \"\");\n            mixin(\"\n                // workaround scope escape check, see\n                // https://issues.dlang.org/show_bug.cgi?id=16582\n                // should use return scope once available\n                enum get = (PT[i .. i+1] \" ~ args ~ \") @trusted\n                {\n                    // If the parameter is lazy, we force it to be evaluated\n                    // like this.\n                    auto \" ~ val ~ \" = \" ~ args ~ \"[0];\n                    auto \" ~ ptr ~ \" = &\" ~ val ~ \";\n                        // workaround Bugzilla 16582\n                    return *\" ~ ptr ~ \";\n                };\n            \");\n            static if (is(typeof(get())))\n                enum Get = get();\n            else\n                alias Get = void;\n                // If default arg doesn't exist, returns void instead.\n        }\n    }\n    else\n    {\n        static assert(0, func[0].stringof ~ \"is not a function\");\n\n        // Define dummy entities to avoid pointless errors\n        template Get(size_t i) { enum Get = \"\"; }\n        alias PT = AliasSeq!();\n    }\n\n    template Impl(size_t i = 0)\n    {\n        static if (i == PT.length)\n            alias Impl = AliasSeq!();\n        else\n            alias Impl = AliasSeq!(Get!i, Impl!(i+1));\n    }\n\n    alias ParameterDefaults = Impl!();\n}\n\n///\n@safe unittest\n{\n    int foo(int num, string name = \"hello\", int[] = [1,2,3], lazy int x = 0);\n    static assert(is(ParameterDefaults!foo[0] == void));\n    static assert(   ParameterDefaults!foo[1] == \"hello\");\n    static assert(   ParameterDefaults!foo[2] == [1,2,3]);\n    static assert(   ParameterDefaults!foo[3] == 0);\n}\n\n@safe unittest // issue 17192\n{\n    static void func(int i, int PT, int __pd_value, int __pd_val, int __args,\n        int name, int args, int val, int ptr, int args_, int val_, int ptr_)\n    {\n    }\n    alias Voids = ParameterDefaults!func;\n    static assert(Voids.length == 12);\n    static foreach (V; Voids) static assert(is(V == void));\n}\n\n/**\n * Alternate name for $(LREF ParameterDefaults), kept for legacy compatibility.\n */\nalias ParameterDefaultValueTuple = ParameterDefaults;\n\n@safe unittest\n{\n    alias PDVT = ParameterDefaultValueTuple;\n\n    void bar(int n = 1, string s = \"hello\"){}\n    static assert(PDVT!bar.length == 2);\n    static assert(PDVT!bar[0] == 1);\n    static assert(PDVT!bar[1] == \"hello\");\n    static assert(is(typeof(PDVT!bar) == typeof(AliasSeq!(1, \"hello\"))));\n\n    void baz(int x, int n = 1, string s = \"hello\"){}\n    static assert(PDVT!baz.length == 3);\n    static assert(is(PDVT!baz[0] == void));\n    static assert(   PDVT!baz[1] == 1);\n    static assert(   PDVT!baz[2] == \"hello\");\n    static assert(is(typeof(PDVT!baz) == typeof(AliasSeq!(void, 1, \"hello\"))));\n\n    // bug 10800 - property functions return empty string\n    @property void foo(int x = 3) { }\n    static assert(PDVT!foo.length == 1);\n    static assert(PDVT!foo[0] == 3);\n    static assert(is(typeof(PDVT!foo) == typeof(AliasSeq!(3))));\n\n    struct Colour\n    {\n        ubyte a,r,g,b;\n\n        static immutable Colour white = Colour(255,255,255,255);\n    }\n    void bug8106(Colour c = Colour.white) {}\n    //pragma(msg, PDVT!bug8106);\n    static assert(PDVT!bug8106[0] == Colour.white);\n    void bug16582(scope int* val = null) {}\n    static assert(PDVT!bug16582[0] is null);\n}\n\n\n/**\nReturns the FunctionAttribute mask for function `func`.\n\nSee_Also:\n    $(LREF hasFunctionAttributes)\n */\nenum FunctionAttribute : uint\n{\n    /**\n     * These flags can be bitwise OR-ed together to represent a complex attribute.\n     */\n    none       = 0,\n    pure_      = 1 << 0,  /// ditto\n    nothrow_   = 1 << 1,  /// ditto\n    ref_       = 1 << 2,  /// ditto\n    property   = 1 << 3,  /// ditto\n    trusted    = 1 << 4,  /// ditto\n    safe       = 1 << 5,  /// ditto\n    nogc       = 1 << 6,  /// ditto\n    system     = 1 << 7,  /// ditto\n    const_     = 1 << 8,  /// ditto\n    immutable_ = 1 << 9,  /// ditto\n    inout_     = 1 << 10, /// ditto\n    shared_    = 1 << 11, /// ditto\n    return_    = 1 << 12, /// ditto\n    scope_     = 1 << 13, /// ditto\n}\n\n/// ditto\ntemplate functionAttributes(func...)\nif (func.length == 1 && isCallable!func)\n{\n    // @bug: workaround for opCall\n    alias FuncSym = Select!(is(typeof(__traits(getFunctionAttributes, func))),\n                            func, Unqual!(FunctionTypeOf!func));\n\n    enum FunctionAttribute functionAttributes =\n        extractAttribFlags!(__traits(getFunctionAttributes, FuncSym))();\n}\n\n///\n@safe unittest\n{\n    alias FA = FunctionAttribute; // shorten the enum name\n\n    real func(real x) pure nothrow @safe\n    {\n        return x;\n    }\n    static assert(functionAttributes!func & FA.pure_);\n    static assert(functionAttributes!func & FA.safe);\n    static assert(!(functionAttributes!func & FA.trusted)); // not @trusted\n}\n\n@system unittest\n{\n    alias FA = FunctionAttribute;\n\n    struct S\n    {\n        int noF() { return 0; }\n        int constF() const { return 0; }\n        int immutableF() immutable { return 0; }\n        int inoutF() inout { return 0; }\n        int sharedF() shared { return 0; }\n\n        int x;\n        ref int refF() return { return x; }\n        int propertyF() @property { return 0; }\n        int nothrowF() nothrow { return 0; }\n        int nogcF() @nogc { return 0; }\n\n        int systemF() @system { return 0; }\n        int trustedF() @trusted { return 0; }\n        int safeF() @safe { return 0; }\n\n        int pureF() pure { return 0; }\n    }\n\n    static assert(functionAttributes!(S.noF) == FA.system);\n    static assert(functionAttributes!(typeof(S.noF)) == FA.system);\n\n    static assert(functionAttributes!(S.constF) == (FA.const_ | FA.system));\n    static assert(functionAttributes!(typeof(S.constF)) == (FA.const_ | FA.system));\n\n    static assert(functionAttributes!(S.immutableF) == (FA.immutable_ | FA.system));\n    static assert(functionAttributes!(typeof(S.immutableF)) == (FA.immutable_ | FA.system));\n\n    static assert(functionAttributes!(S.inoutF) == (FA.inout_ | FA.system));\n    static assert(functionAttributes!(typeof(S.inoutF)) == (FA.inout_ | FA.system));\n\n    static assert(functionAttributes!(S.sharedF) == (FA.shared_ | FA.system));\n    static assert(functionAttributes!(typeof(S.sharedF)) == (FA.shared_ | FA.system));\n\n    static assert(functionAttributes!(S.refF) == (FA.ref_ | FA.system | FA.return_));\n    static assert(functionAttributes!(typeof(S.refF)) == (FA.ref_ | FA.system | FA.return_));\n\n    static assert(functionAttributes!(S.propertyF) == (FA.property | FA.system));\n    static assert(functionAttributes!(typeof(&S.propertyF)) == (FA.property | FA.system));\n\n    static assert(functionAttributes!(S.nothrowF) == (FA.nothrow_ | FA.system));\n    static assert(functionAttributes!(typeof(S.nothrowF)) == (FA.nothrow_ | FA.system));\n\n    static assert(functionAttributes!(S.nogcF) == (FA.nogc | FA.system));\n    static assert(functionAttributes!(typeof(S.nogcF)) == (FA.nogc | FA.system));\n\n    static assert(functionAttributes!(S.systemF) == FA.system);\n    static assert(functionAttributes!(typeof(S.systemF)) == FA.system);\n\n    static assert(functionAttributes!(S.trustedF) == FA.trusted);\n    static assert(functionAttributes!(typeof(S.trustedF)) == FA.trusted);\n\n    static assert(functionAttributes!(S.safeF) == FA.safe);\n    static assert(functionAttributes!(typeof(S.safeF)) == FA.safe);\n\n    static assert(functionAttributes!(S.pureF) == (FA.pure_ | FA.system));\n    static assert(functionAttributes!(typeof(S.pureF)) == (FA.pure_ | FA.system));\n\n    int pure_nothrow() nothrow pure;\n    void safe_nothrow() @safe nothrow;\n    static ref int static_ref_property() @property;\n    ref int ref_property() @property;\n\n    static assert(functionAttributes!(pure_nothrow) == (FA.pure_ | FA.nothrow_ | FA.system));\n    static assert(functionAttributes!(typeof(pure_nothrow)) == (FA.pure_ | FA.nothrow_ | FA.system));\n\n    static assert(functionAttributes!(safe_nothrow) == (FA.safe | FA.nothrow_));\n    static assert(functionAttributes!(typeof(safe_nothrow)) == (FA.safe | FA.nothrow_));\n\n    static assert(functionAttributes!(static_ref_property) == (FA.property | FA.ref_ | FA.system));\n    static assert(functionAttributes!(typeof(&static_ref_property)) == (FA.property | FA.ref_ | FA.system));\n\n    static assert(functionAttributes!(ref_property) == (FA.property | FA.ref_ | FA.system));\n    static assert(functionAttributes!(typeof(&ref_property)) == (FA.property | FA.ref_ | FA.system));\n\n    struct S2\n    {\n        int pure_const() const pure { return 0; }\n        int pure_sharedconst() const shared pure { return 0; }\n    }\n\n    static assert(functionAttributes!(S2.pure_const) == (FA.const_ | FA.pure_ | FA.system));\n    static assert(functionAttributes!(typeof(S2.pure_const)) == (FA.const_ | FA.pure_ | FA.system));\n\n    static assert(functionAttributes!(S2.pure_sharedconst) == (FA.const_ | FA.shared_ | FA.pure_ | FA.system));\n    static assert(functionAttributes!(typeof(S2.pure_sharedconst)) == (FA.const_ | FA.shared_ | FA.pure_ | FA.system));\n\n    static assert(functionAttributes!((int a) { }) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.safe));\n    static assert(functionAttributes!(typeof((int a) { })) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.safe));\n\n    auto safeDel = delegate() @safe { };\n    static assert(functionAttributes!(safeDel) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.safe));\n    static assert(functionAttributes!(typeof(safeDel)) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.safe));\n\n    auto trustedDel = delegate() @trusted { };\n    static assert(functionAttributes!(trustedDel) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.trusted));\n    static assert(functionAttributes!(typeof(trustedDel)) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.trusted));\n\n    auto systemDel = delegate() @system { };\n    static assert(functionAttributes!(systemDel) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.system));\n    static assert(functionAttributes!(typeof(systemDel)) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.system));\n}\n\nprivate FunctionAttribute extractAttribFlags(Attribs...)()\n{\n    auto res = FunctionAttribute.none;\n\n    static foreach (attrib; Attribs)\n    {\n        switch (attrib) with (FunctionAttribute)\n        {\n            case \"pure\":      res |= pure_; break;\n            case \"nothrow\":   res |= nothrow_; break;\n            case \"ref\":       res |= ref_; break;\n            case \"@property\": res |= property; break;\n            case \"@trusted\":  res |= trusted; break;\n            case \"@safe\":     res |= safe; break;\n            case \"@nogc\":     res |= nogc; break;\n            case \"@system\":   res |= system; break;\n            case \"const\":     res |= const_; break;\n            case \"immutable\": res |= immutable_; break;\n            case \"inout\":     res |= inout_; break;\n            case \"shared\":    res |= shared_; break;\n            case \"return\":    res |= return_; break;\n            case \"scope\":     res |= scope_; break;\n            default: assert(0, attrib);\n        }\n    }\n\n    return res;\n}\n\n/**\nChecks whether a function has the given attributes attached.\n\nParams:\n    args = Function to check, followed by a\n    variadic number of function attributes as strings\n\nReturns:\n    `true`, if the function has the list of attributes attached and `false` otherwise.\n\nSee_Also:\n    $(LREF functionAttributes)\n*/\ntemplate hasFunctionAttributes(args...)\nif (args.length > 0 && isCallable!(args[0])\n     && allSatisfy!(isSomeString, typeof(args[1 .. $])))\n{\n    enum bool hasFunctionAttributes = {\n        import std.algorithm.searching : canFind;\n        import std.range : only;\n        enum funcAttribs = only(__traits(getFunctionAttributes, args[0]));\n        static foreach (attribute; args[1 .. $])\n        {\n            if (!funcAttribs.canFind(attribute))\n                return false;\n        }\n        return true;\n    }();\n}\n\n///\n@safe unittest\n{\n    real func(real x) pure nothrow @safe;\n    static assert(hasFunctionAttributes!(func, \"@safe\", \"pure\"));\n    static assert(!hasFunctionAttributes!(func, \"@trusted\"));\n\n    // for templates attributes are automatically inferred\n    bool myFunc(T)(T b)\n    {\n        return !b;\n    }\n    static assert(hasFunctionAttributes!(myFunc!bool, \"@safe\", \"pure\", \"@nogc\", \"nothrow\"));\n    static assert(!hasFunctionAttributes!(myFunc!bool, \"shared\"));\n}\n\n@system unittest\n{\n    struct S\n    {\n        int noF();\n        int constF() const;\n        int immutableF() immutable;\n        int inoutF() inout;\n        int sharedF() shared;\n\n        ref int refF() return;\n        int propertyF() @property;\n        int nothrowF() nothrow;\n        int nogcF() @nogc;\n\n        int systemF() @system;\n        int trustedF() @trusted;\n        int safeF() @safe;\n\n        int pureF() pure;\n    }\n\n    // true if no args passed\n    static assert(hasFunctionAttributes!(S.noF));\n\n    static assert(hasFunctionAttributes!(S.noF, \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(S.noF), \"@system\"));\n    static assert(!hasFunctionAttributes!(S.noF, \"@system\", \"pure\"));\n\n    static assert(hasFunctionAttributes!(S.constF, \"const\", \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(S.constF), \"const\", \"@system\"));\n    static assert(!hasFunctionAttributes!(S.constF, \"const\", \"@system\", \"@nogc\"));\n\n    static assert(hasFunctionAttributes!(S.immutableF, \"immutable\", \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(S.immutableF), \"immutable\", \"@system\"));\n    static assert(!hasFunctionAttributes!(S.immutableF, \"immutable\", \"@system\", \"pure\"));\n\n    static assert(hasFunctionAttributes!(S.inoutF, \"inout\", \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(S.inoutF), \"inout\", \"@system\"));\n    static assert(!hasFunctionAttributes!(S.inoutF, \"inout\", \"@system\", \"pure\"));\n\n    static assert(hasFunctionAttributes!(S.sharedF, \"shared\", \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(S.sharedF), \"shared\", \"@system\"));\n    static assert(!hasFunctionAttributes!(S.sharedF, \"shared\", \"@system\", \"@trusted\"));\n\n    static assert(hasFunctionAttributes!(S.refF, \"ref\", \"@system\", \"return\"));\n    static assert(hasFunctionAttributes!(typeof(S.refF), \"ref\", \"@system\", \"return\"));\n    static assert(!hasFunctionAttributes!(S.refF, \"ref\", \"@system\", \"return\", \"pure\"));\n\n    static assert(hasFunctionAttributes!(S.propertyF, \"@property\", \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(&S.propertyF), \"@property\", \"@system\"));\n    static assert(!hasFunctionAttributes!(S.propertyF, \"@property\", \"@system\", \"ref\"));\n\n    static assert(hasFunctionAttributes!(S.nothrowF, \"nothrow\", \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(S.nothrowF), \"nothrow\", \"@system\"));\n    static assert(!hasFunctionAttributes!(S.nothrowF, \"nothrow\", \"@system\", \"@trusted\"));\n\n    static assert(hasFunctionAttributes!(S.nogcF, \"@nogc\", \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(S.nogcF), \"@nogc\", \"@system\"));\n    static assert(!hasFunctionAttributes!(S.nogcF, \"@nogc\", \"@system\", \"ref\"));\n\n    static assert(hasFunctionAttributes!(S.systemF, \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(S.systemF), \"@system\"));\n    static assert(!hasFunctionAttributes!(S.systemF, \"@system\", \"ref\"));\n\n    static assert(hasFunctionAttributes!(S.trustedF, \"@trusted\"));\n    static assert(hasFunctionAttributes!(typeof(S.trustedF), \"@trusted\"));\n    static assert(!hasFunctionAttributes!(S.trustedF, \"@trusted\", \"@safe\"));\n\n    static assert(hasFunctionAttributes!(S.safeF, \"@safe\"));\n    static assert(hasFunctionAttributes!(typeof(S.safeF), \"@safe\"));\n    static assert(!hasFunctionAttributes!(S.safeF, \"@safe\", \"nothrow\"));\n\n    static assert(hasFunctionAttributes!(S.pureF, \"pure\", \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(S.pureF), \"pure\", \"@system\"));\n    static assert(!hasFunctionAttributes!(S.pureF, \"pure\", \"@system\", \"ref\"));\n\n    int pure_nothrow() nothrow pure { return 0; }\n    void safe_nothrow() @safe nothrow { }\n    static ref int static_ref_property() @property { return *(new int); }\n    ref int ref_property() @property { return *(new int); }\n\n    static assert(hasFunctionAttributes!(pure_nothrow, \"pure\", \"nothrow\", \"@safe\"));\n    static assert(hasFunctionAttributes!(typeof(pure_nothrow), \"pure\", \"nothrow\", \"@safe\"));\n    static assert(!hasFunctionAttributes!(pure_nothrow, \"pure\", \"nothrow\", \"@safe\", \"@trusted\"));\n\n    static assert(hasFunctionAttributes!(safe_nothrow, \"@safe\", \"nothrow\"));\n    static assert(hasFunctionAttributes!(typeof(safe_nothrow), \"@safe\", \"nothrow\"));\n    static assert(hasFunctionAttributes!(safe_nothrow, \"@safe\", \"nothrow\", \"pure\"));\n    static assert(!hasFunctionAttributes!(safe_nothrow, \"@safe\", \"nothrow\", \"pure\", \"@trusted\"));\n\n    static assert(hasFunctionAttributes!(static_ref_property, \"@property\", \"ref\", \"@safe\"));\n    static assert(hasFunctionAttributes!(typeof(&static_ref_property), \"@property\", \"ref\", \"@safe\"));\n    static assert(hasFunctionAttributes!(static_ref_property, \"@property\", \"ref\", \"@safe\", \"nothrow\"));\n    static assert(!hasFunctionAttributes!(static_ref_property, \"@property\", \"ref\", \"@safe\", \"nothrow\", \"@nogc\"));\n\n    static assert(hasFunctionAttributes!(ref_property, \"@property\", \"ref\", \"@safe\"));\n    static assert(hasFunctionAttributes!(typeof(&ref_property), \"@property\", \"ref\", \"@safe\"));\n    static assert(!hasFunctionAttributes!(ref_property, \"@property\", \"ref\", \"@safe\", \"@nogc\"));\n\n    struct S2\n    {\n        int pure_const() const pure { return 0; }\n        int pure_sharedconst() const shared pure { return 0; }\n    }\n\n    static assert(hasFunctionAttributes!(S2.pure_const, \"const\", \"pure\", \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(S2.pure_const), \"const\", \"pure\", \"@system\"));\n    static assert(!hasFunctionAttributes!(S2.pure_const, \"const\", \"pure\", \"@system\", \"ref\"));\n\n    static assert(hasFunctionAttributes!(S2.pure_sharedconst, \"const\", \"shared\", \"pure\", \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(S2.pure_sharedconst), \"const\", \"shared\", \"pure\", \"@system\"));\n    static assert(!hasFunctionAttributes!(S2.pure_sharedconst, \"const\", \"shared\", \"pure\", \"@system\", \"@nogc\"));\n\n    static assert(hasFunctionAttributes!((int a) { }, \"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n    static assert(hasFunctionAttributes!(typeof((int a) { }), \"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n    static assert(!hasFunctionAttributes!((int a) { }, \"pure\", \"nothrow\", \"@nogc\", \"@safe\", \"ref\"));\n\n    auto safeDel = delegate() @safe { };\n    static assert(hasFunctionAttributes!(safeDel, \"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n    static assert(hasFunctionAttributes!(typeof(safeDel), \"pure\", \"nothrow\", \"@nogc\", \"@safe\"));\n    static assert(!hasFunctionAttributes!(safeDel, \"pure\", \"nothrow\", \"@nogc\", \"@safe\", \"@system\"));\n\n    auto trustedDel = delegate() @trusted { };\n    static assert(hasFunctionAttributes!(trustedDel, \"pure\", \"nothrow\", \"@nogc\", \"@trusted\"));\n    static assert(hasFunctionAttributes!(typeof(trustedDel), \"pure\", \"nothrow\", \"@nogc\", \"@trusted\"));\n    static assert(!hasFunctionAttributes!(trustedDel, \"pure\", \"nothrow\", \"@nogc\", \"@trusted\", \"ref\"));\n\n    auto systemDel = delegate() @system { };\n    static assert(hasFunctionAttributes!(systemDel, \"pure\", \"nothrow\", \"@nogc\", \"@system\"));\n    static assert(hasFunctionAttributes!(typeof(systemDel), \"pure\", \"nothrow\", \"@nogc\", \"@system\"));\n    static assert(!hasFunctionAttributes!(systemDel, \"pure\", \"nothrow\", \"@nogc\", \"@system\", \"@property\"));\n\n\n    // call functions to make CodeCov happy\n    {\n        assert(pure_nothrow == 0);\n        safe_nothrow;\n        assert(static_ref_property == 0);\n        assert(ref_property == 0);\n        assert(S2().pure_const == 0);\n        assert((shared S2()).pure_sharedconst == 0);\n        cast(void) safeDel;\n        cast(void) trustedDel;\n        cast(void) systemDel;\n    }\n}\n\n/**\n`true` if `func` is `@safe` or `@trusted`.\n */\ntemplate isSafe(alias func)\nif (isCallable!func)\n{\n    enum isSafe = (functionAttributes!func & FunctionAttribute.safe) != 0 ||\n                  (functionAttributes!func & FunctionAttribute.trusted) != 0;\n}\n\n///\n@safe unittest\n{\n    @safe    int add(int a, int b) {return a+b;}\n    @trusted int sub(int a, int b) {return a-b;}\n    @system  int mul(int a, int b) {return a*b;}\n\n    static assert( isSafe!add);\n    static assert( isSafe!sub);\n    static assert(!isSafe!mul);\n}\n\n\n@safe unittest\n{\n    //Member functions\n    interface Set\n    {\n        int systemF() @system;\n        int trustedF() @trusted;\n        int safeF() @safe;\n    }\n    static assert( isSafe!(Set.safeF));\n    static assert( isSafe!(Set.trustedF));\n    static assert(!isSafe!(Set.systemF));\n\n    //Functions\n    @safe static void safeFunc() {}\n    @trusted static void trustedFunc() {}\n    @system static void systemFunc() {}\n\n    static assert( isSafe!safeFunc);\n    static assert( isSafe!trustedFunc);\n    static assert(!isSafe!systemFunc);\n\n    //Delegates\n    auto safeDel = delegate() @safe {};\n    auto trustedDel = delegate() @trusted {};\n    auto systemDel = delegate() @system {};\n\n    static assert( isSafe!safeDel);\n    static assert( isSafe!trustedDel);\n    static assert(!isSafe!systemDel);\n\n    //Lambdas\n    static assert( isSafe!({safeDel();}));\n    static assert( isSafe!({trustedDel();}));\n    static assert(!isSafe!({systemDel();}));\n\n    //Static opCall\n    struct SafeStatic { @safe static SafeStatic opCall() { return SafeStatic.init; } }\n    struct TrustedStatic { @trusted static TrustedStatic opCall() { return TrustedStatic.init; } }\n    struct SystemStatic { @system static SystemStatic opCall() { return SystemStatic.init; } }\n\n    static assert( isSafe!(SafeStatic()));\n    static assert( isSafe!(TrustedStatic()));\n    static assert(!isSafe!(SystemStatic()));\n\n    //Non-static opCall\n    struct Safe { @safe Safe opCall() { return Safe.init; } }\n    struct Trusted { @trusted Trusted opCall() { return Trusted.init; } }\n    struct System { @system System opCall() { return System.init; } }\n\n    static assert( isSafe!(Safe.init()));\n    static assert( isSafe!(Trusted.init()));\n    static assert(!isSafe!(System.init()));\n}\n\n\n/**\n`true` if `func` is `@system`.\n*/\ntemplate isUnsafe(alias func)\n{\n    enum isUnsafe = !isSafe!func;\n}\n\n///\n@safe unittest\n{\n    @safe    int add(int a, int b) {return a+b;}\n    @trusted int sub(int a, int b) {return a-b;}\n    @system  int mul(int a, int b) {return a*b;}\n\n    static assert(!isUnsafe!add);\n    static assert(!isUnsafe!sub);\n    static assert( isUnsafe!mul);\n}\n\n@safe unittest\n{\n    //Member functions\n    interface Set\n    {\n        int systemF() @system;\n        int trustedF() @trusted;\n        int safeF() @safe;\n    }\n    static assert(!isUnsafe!(Set.safeF));\n    static assert(!isUnsafe!(Set.trustedF));\n    static assert( isUnsafe!(Set.systemF));\n\n    //Functions\n    @safe static void safeFunc() {}\n    @trusted static void trustedFunc() {}\n    @system static void systemFunc() {}\n\n    static assert(!isUnsafe!safeFunc);\n    static assert(!isUnsafe!trustedFunc);\n    static assert( isUnsafe!systemFunc);\n\n    //Delegates\n    auto safeDel = delegate() @safe {};\n    auto trustedDel = delegate() @trusted {};\n    auto systemDel = delegate() @system {};\n\n    static assert(!isUnsafe!safeDel);\n    static assert(!isUnsafe!trustedDel);\n    static assert( isUnsafe!systemDel);\n\n    //Lambdas\n    static assert(!isUnsafe!({safeDel();}));\n    static assert(!isUnsafe!({trustedDel();}));\n    static assert( isUnsafe!({systemDel();}));\n\n    //Static opCall\n    struct SafeStatic { @safe static SafeStatic opCall() { return SafeStatic.init; } }\n    struct TrustedStatic { @trusted static TrustedStatic opCall() { return TrustedStatic.init; } }\n    struct SystemStatic { @system static SystemStatic opCall() { return SystemStatic.init; } }\n\n    static assert(!isUnsafe!(SafeStatic()));\n    static assert(!isUnsafe!(TrustedStatic()));\n    static assert( isUnsafe!(SystemStatic()));\n\n    //Non-static opCall\n    struct Safe { @safe Safe opCall() { return Safe.init; } }\n    struct Trusted { @trusted Trusted opCall() { return Trusted.init; } }\n    struct System { @system System opCall() { return System.init; } }\n\n    static assert(!isUnsafe!(Safe.init()));\n    static assert(!isUnsafe!(Trusted.init()));\n    static assert( isUnsafe!(System.init()));\n}\n\n\n/**\nDetermine the linkage attribute of the function.\nParams:\n    func = the function symbol, or the type of a function, delegate, or pointer to function\nReturns:\n    one of the strings \"D\", \"C\", \"Windows\", \"Pascal\", or \"Objective-C\"\n*/\ntemplate functionLinkage(func...)\nif (func.length == 1 && isCallable!func)\n{\n    enum string functionLinkage = __traits(getLinkage, FunctionTypeOf!func);\n}\n\n///\n@safe unittest\n{\n    extern(D) void Dfunc() {}\n    extern(C) void Cfunc() {}\n    static assert(functionLinkage!Dfunc == \"D\");\n    static assert(functionLinkage!Cfunc == \"C\");\n\n    string a = functionLinkage!Dfunc;\n    assert(a == \"D\");\n\n    auto fp = &Cfunc;\n    string b = functionLinkage!fp;\n    assert(b == \"C\");\n}\n\n@safe unittest\n{\n    interface Test\n    {\n        void const_func() const;\n        void sharedconst_func() shared const;\n    }\n    static assert(functionLinkage!(Test.const_func) == \"D\");\n    static assert(functionLinkage!(Test.sharedconst_func) == \"D\");\n\n    static assert(functionLinkage!((int a){}) == \"D\");\n}\n\n\n/**\nDetermines what kind of variadic parameters function has.\nParams:\n    func = function symbol or type of function, delegate, or pointer to function\nReturns:\n    enum Variadic\n */\nenum Variadic\n{\n    /// Function is not variadic.\n    no,\n    /// Function is a _C-style variadic function, which uses\n    /// `core.stdc.stdarg`\n    c,\n    /// Function is a _D-style variadic function, which uses\n    /// `__argptr` and `__arguments`.\n    d,\n    /// Function is a typesafe variadic function.\n    typesafe,\n}\n\n/// ditto\ntemplate variadicFunctionStyle(func...)\nif (func.length == 1 && isCallable!func)\n{\n    enum string varargs = __traits(getFunctionVariadicStyle, FunctionTypeOf!func);\n    enum Variadic variadicFunctionStyle =\n        (varargs == \"stdarg\") ? Variadic.c :\n        (varargs == \"argptr\") ? Variadic.d :\n        (varargs == \"typesafe\") ? Variadic.typesafe :\n        (varargs == \"none\") ? Variadic.no : Variadic.no;\n}\n\n///\n@safe unittest\n{\n    void func() {}\n    static assert(variadicFunctionStyle!func == Variadic.no);\n\n    extern(C) int printf(in char*, ...);\n    static assert(variadicFunctionStyle!printf == Variadic.c);\n}\n\n@safe unittest\n{\n    import core.vararg;\n\n    extern(D) void novar() {}\n    extern(C) void cstyle(int, ...) {}\n    extern(D) void dstyle(...) {}\n    extern(D) void typesafe(int[]...) {}\n\n    static assert(variadicFunctionStyle!novar == Variadic.no);\n    static assert(variadicFunctionStyle!cstyle == Variadic.c);\n    static assert(variadicFunctionStyle!dstyle == Variadic.d);\n    static assert(variadicFunctionStyle!typesafe == Variadic.typesafe);\n\n    static assert(variadicFunctionStyle!((int[] a...) {}) == Variadic.typesafe);\n}\n\n\n/**\nGet the function type from a callable object `func`.\n\nUsing builtin `typeof` on a property function yields the types of the\nproperty value, not of the property function itself.  Still,\n`FunctionTypeOf` is able to obtain function types of properties.\n\nNote:\nDo not confuse function types with function pointer types; function types are\nusually used for compile-time reflection purposes.\n */\ntemplate FunctionTypeOf(func...)\nif (func.length == 1 && isCallable!func)\n{\n    static if (is(typeof(& func[0]) Fsym : Fsym*) && is(Fsym == function) || is(typeof(& func[0]) Fsym == delegate))\n    {\n        alias FunctionTypeOf = Fsym; // HIT: (nested) function symbol\n    }\n    else static if (is(typeof(& func[0].opCall) Fobj == delegate))\n    {\n        alias FunctionTypeOf = Fobj; // HIT: callable object\n    }\n    else static if (is(typeof(& func[0].opCall) Ftyp : Ftyp*) && is(Ftyp == function))\n    {\n        alias FunctionTypeOf = Ftyp; // HIT: callable type\n    }\n    else static if (is(func[0] T) || is(typeof(func[0]) T))\n    {\n        static if (is(T == function))\n            alias FunctionTypeOf = T;    // HIT: function\n        else static if (is(T Fptr : Fptr*) && is(Fptr == function))\n            alias FunctionTypeOf = Fptr; // HIT: function pointer\n        else static if (is(T Fdlg == delegate))\n            alias FunctionTypeOf = Fdlg; // HIT: delegate\n        else\n            static assert(0);\n    }\n    else\n        static assert(0);\n}\n\n///\n@safe unittest\n{\n    class C\n    {\n        int value() @property { return 0; }\n    }\n    static assert(is( typeof(C.value) == int ));\n    static assert(is( FunctionTypeOf!(C.value) == function ));\n}\n\n@system unittest\n{\n    int test(int a);\n    int propGet() @property;\n    int propSet(int a) @property;\n    int function(int) test_fp;\n    int delegate(int) test_dg;\n    static assert(is( typeof(test) == FunctionTypeOf!(typeof(test)) ));\n    static assert(is( typeof(test) == FunctionTypeOf!test ));\n    static assert(is( typeof(test) == FunctionTypeOf!test_fp ));\n    static assert(is( typeof(test) == FunctionTypeOf!test_dg ));\n    alias int GetterType() @property;\n    alias int SetterType(int) @property;\n    static assert(is( FunctionTypeOf!propGet == GetterType ));\n    static assert(is( FunctionTypeOf!propSet == SetterType ));\n\n    interface Prop { int prop() @property; }\n    Prop prop;\n    static assert(is( FunctionTypeOf!(Prop.prop) == GetterType ));\n    static assert(is( FunctionTypeOf!(prop.prop) == GetterType ));\n\n    class Callable { int opCall(int) { return 0; } }\n    auto call = new Callable;\n    static assert(is( FunctionTypeOf!call == typeof(test) ));\n\n    struct StaticCallable { static int opCall(int) { return 0; } }\n    StaticCallable stcall_val;\n    StaticCallable* stcall_ptr;\n    static assert(is( FunctionTypeOf!stcall_val == typeof(test) ));\n    static assert(is( FunctionTypeOf!stcall_ptr == typeof(test) ));\n\n    interface Overloads\n    {\n        void test(string);\n        real test(real);\n        int  test(int);\n        int  test() @property;\n    }\n    alias ov = AliasSeq!(__traits(getVirtualFunctions, Overloads, \"test\"));\n    alias F_ov0 = FunctionTypeOf!(ov[0]);\n    alias F_ov1 = FunctionTypeOf!(ov[1]);\n    alias F_ov2 = FunctionTypeOf!(ov[2]);\n    alias F_ov3 = FunctionTypeOf!(ov[3]);\n    static assert(is(F_ov0* == void function(string)));\n    static assert(is(F_ov1* == real function(real)));\n    static assert(is(F_ov2* == int function(int)));\n    static assert(is(F_ov3* == int function() @property));\n\n    alias F_dglit = FunctionTypeOf!((int a){ return a; });\n    static assert(is(F_dglit* : int function(int)));\n}\n\n/**\n * Constructs a new function or delegate type with the same basic signature\n * as the given one, but different attributes (including linkage).\n *\n * This is especially useful for adding/removing attributes to/from types in\n * generic code, where the actual type name cannot be spelt out.\n *\n * Params:\n *    T = The base type.\n *    linkage = The desired linkage of the result type.\n *    attrs = The desired $(LREF FunctionAttribute)s of the result type.\n */\ntemplate SetFunctionAttributes(T, string linkage, uint attrs)\nif (isFunctionPointer!T || isDelegate!T)\n{\n    mixin({\n        import std.algorithm.searching : canFind;\n\n        static assert(!(attrs & FunctionAttribute.trusted) ||\n            !(attrs & FunctionAttribute.safe),\n            \"Cannot have a function/delegate that is both trusted and safe.\");\n\n        static immutable linkages = [\"D\", \"C\", \"Windows\", \"Pascal\", \"C++\", \"System\"];\n        static assert(canFind(linkages, linkage), \"Invalid linkage '\" ~\n            linkage ~ \"', must be one of \" ~ linkages.stringof ~ \".\");\n\n        string result = \"alias \";\n\n        static if (linkage != \"D\")\n            result ~= \"extern(\" ~ linkage ~ \") \";\n\n        static if (attrs & FunctionAttribute.ref_)\n            result ~= \"ref \";\n\n        result ~= \"ReturnType!T\";\n\n        static if (isDelegate!T)\n            result ~= \" delegate\";\n        else\n            result ~= \" function\";\n\n        result ~= \"(\";\n\n        static if (Parameters!T.length > 0)\n            result ~= \"Parameters!T\";\n\n        enum varStyle = variadicFunctionStyle!T;\n        static if (varStyle == Variadic.c)\n            result ~= \", ...\";\n        else static if (varStyle == Variadic.d)\n            result ~= \"...\";\n        else static if (varStyle == Variadic.typesafe)\n            result ~= \"...\";\n\n        result ~= \")\";\n\n        static if (attrs & FunctionAttribute.pure_)\n            result ~= \" pure\";\n        static if (attrs & FunctionAttribute.nothrow_)\n            result ~= \" nothrow\";\n        static if (attrs & FunctionAttribute.property)\n            result ~= \" @property\";\n        static if (attrs & FunctionAttribute.trusted)\n            result ~= \" @trusted\";\n        static if (attrs & FunctionAttribute.safe)\n            result ~= \" @safe\";\n        static if (attrs & FunctionAttribute.nogc)\n            result ~= \" @nogc\";\n        static if (attrs & FunctionAttribute.system)\n            result ~= \" @system\";\n        static if (attrs & FunctionAttribute.const_)\n            result ~= \" const\";\n        static if (attrs & FunctionAttribute.immutable_)\n            result ~= \" immutable\";\n        static if (attrs & FunctionAttribute.inout_)\n            result ~= \" inout\";\n        static if (attrs & FunctionAttribute.shared_)\n            result ~= \" shared\";\n        static if (attrs & FunctionAttribute.return_)\n            result ~= \" return\";\n\n        result ~= \" SetFunctionAttributes;\";\n        return result;\n    }());\n}\n\n/// Ditto\ntemplate SetFunctionAttributes(T, string linkage, uint attrs)\nif (is(T == function))\n{\n    // To avoid a lot of syntactic headaches, we just use the above version to\n    // operate on the corresponding function pointer type and then remove the\n    // indirection again.\n    alias SetFunctionAttributes = FunctionTypeOf!(SetFunctionAttributes!(T*, linkage, attrs));\n}\n\n///\n@safe unittest\n{\n    alias ExternC(T) = SetFunctionAttributes!(T, \"C\", functionAttributes!T);\n\n    auto assumePure(T)(T t)\n    if (isFunctionPointer!T || isDelegate!T)\n    {\n        enum attrs = functionAttributes!T | FunctionAttribute.pure_;\n        return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;\n    }\n}\n\nversion (unittest)\n{\nprivate:\n    // Some function types to test.\n    int sc(scope int, ref int, out int, lazy int, int);\n    extern(System) int novar();\n    extern(C) int cstyle(int, ...);\n    extern(D) int dstyle(...);\n    extern(D) int typesafe(int[]...);\n}\n@safe unittest\n{\n    import std.algorithm.iteration : reduce;\n\n    alias FA = FunctionAttribute;\n    static foreach (BaseT; AliasSeq!(typeof(&sc), typeof(&novar), typeof(&cstyle),\n        typeof(&dstyle), typeof(&typesafe)))\n    {\n        static foreach (T; AliasSeq!(BaseT, FunctionTypeOf!BaseT))\n        {{\n            enum linkage = functionLinkage!T;\n            enum attrs = functionAttributes!T;\n\n            static assert(is(SetFunctionAttributes!(T, linkage, attrs) == T),\n                \"Identity check failed for: \" ~ T.stringof);\n\n            // Check that all linkage types work (D-style variadics require D linkage).\n            static if (variadicFunctionStyle!T != Variadic.d)\n            {\n                static foreach (newLinkage; AliasSeq!(\"D\", \"C\", \"Windows\", \"Pascal\", \"C++\"))\n                {{\n                    alias New = SetFunctionAttributes!(T, newLinkage, attrs);\n                    static assert(functionLinkage!New == newLinkage,\n                        \"Linkage test failed for: \" ~ T.stringof ~ \", \" ~ newLinkage ~\n                        \" (got \" ~ New.stringof ~ \")\");\n                }}\n            }\n\n            // Add @safe.\n            alias T1 = SetFunctionAttributes!(T, functionLinkage!T, FA.safe);\n            static assert(functionAttributes!T1 == FA.safe);\n\n            // Add all known attributes, excluding conflicting ones.\n            enum allAttrs = reduce!\"a | b\"([EnumMembers!FA])\n                & ~FA.safe & ~FA.property & ~FA.const_ & ~FA.immutable_ & ~FA.inout_\n                & ~FA.shared_ & ~FA.system & ~FA.return_ & ~FA.scope_;\n\n            alias T2 = SetFunctionAttributes!(T1, functionLinkage!T, allAttrs);\n            static assert(functionAttributes!T2 == allAttrs);\n\n            // Strip all attributes again.\n            alias T3 = SetFunctionAttributes!(T2, functionLinkage!T, FA.none);\n            static assert(is(T3 == T));\n        }}\n    }\n}\n\n\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n// Aggregate Types\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n/**\nDetermines whether `T` is a class nested inside another class\nand that `T.outer` is the implicit reference to the outer class\n(i.e. `outer` has not been used as a field or method name)\n\nParams:\n    T = type to test\n\nReturns:\n`true` if `T` is a class nested inside another, with the conditions described above;\n`false` otherwise\n*/\ntemplate isInnerClass(T)\nif (is(T == class))\n{\n    import std.meta : staticIndexOf;\n\n    static if (is(typeof(T.outer)))\n        enum isInnerClass = __traits(isSame, typeof(T.outer), __traits(parent, T))\n                         && (staticIndexOf!(__traits(allMembers, T), \"outer\") == -1);\n    else\n        enum isInnerClass = false;\n}\n\n///\n@safe unittest\n{\n    class C\n    {\n        int outer;\n    }\n    static assert(!isInnerClass!C);\n\n    class Outer1\n    {\n        class Inner1 { }\n        class Inner2\n        {\n            int outer;\n        }\n    }\n    static assert(isInnerClass!(Outer1.Inner1));\n    static assert(!isInnerClass!(Outer1.Inner2));\n\n    static class Outer2\n    {\n        static class Inner\n        {\n            int outer;\n        }\n    }\n    static assert(!isInnerClass!(Outer2.Inner));\n}\n\n/**\nDetermines whether `T` has its own context pointer.\n`T` must be either `class`, `struct`, or `union`.\n*/\ntemplate isNested(T)\nif (is(T == class) || is(T == struct) || is(T == union))\n{\n    enum isNested = __traits(isNested, T);\n}\n\n///\n@safe unittest\n{\n    static struct S { }\n    static assert(!isNested!S);\n\n    int i;\n    struct NestedStruct { void f() { ++i; } }\n    static assert(isNested!NestedStruct);\n}\n\n/**\nDetermines whether `T` or any of its representation types\nhave a context pointer.\n*/\ntemplate hasNested(T)\n{\n    import std.meta : anySatisfy, Filter;\n\n    static if (isStaticArray!T && T.length)\n        enum hasNested = hasNested!(typeof(T.init[0]));\n    else static if (is(T == class) || is(T == struct) || is(T == union))\n    {\n        // prevent infinite recursion for class with member of same type\n        enum notSame(U) = !is(Unqual!T == Unqual!U);\n        enum hasNested = isNested!T ||\n            anySatisfy!(.hasNested, Filter!(notSame, Fields!T));\n    }\n    else\n        enum hasNested = false;\n}\n\n///\n@safe unittest\n{\n    static struct S { }\n\n    int i;\n    struct NS { void f() { ++i; } }\n\n    static assert(!hasNested!(S[2]));\n    static assert(hasNested!(NS[2]));\n}\n\n@safe unittest\n{\n    static assert(!__traits(compiles, isNested!int));\n    static assert(!hasNested!int);\n\n    static struct StaticStruct { }\n    static assert(!isNested!StaticStruct);\n    static assert(!hasNested!StaticStruct);\n\n    int i;\n    struct NestedStruct { void f() { ++i; } }\n    static assert( isNested!NestedStruct);\n    static assert( hasNested!NestedStruct);\n    static assert( isNested!(immutable NestedStruct));\n    static assert( hasNested!(immutable NestedStruct));\n\n    static assert(!__traits(compiles, isNested!(NestedStruct[1])));\n    static assert( hasNested!(NestedStruct[1]));\n    static assert(!hasNested!(NestedStruct[0]));\n\n    struct S1 { NestedStruct nested; }\n    static assert(!isNested!S1);\n    static assert( hasNested!S1);\n\n    static struct S2 { NestedStruct nested; }\n    static assert(!isNested!S2);\n    static assert( hasNested!S2);\n\n    static struct S3 { NestedStruct[0] nested; }\n    static assert(!isNested!S3);\n    static assert(!hasNested!S3);\n\n    static union U { NestedStruct nested; }\n    static assert(!isNested!U);\n    static assert( hasNested!U);\n\n    static class StaticClass { }\n    static assert(!isNested!StaticClass);\n    static assert(!hasNested!StaticClass);\n\n    class NestedClass { void f() { ++i; } }\n    static assert( isNested!NestedClass);\n    static assert( hasNested!NestedClass);\n    static assert( isNested!(immutable NestedClass));\n    static assert( hasNested!(immutable NestedClass));\n\n    static assert(!__traits(compiles, isNested!(NestedClass[1])));\n    static assert( hasNested!(NestedClass[1]));\n    static assert(!hasNested!(NestedClass[0]));\n\n    static class A\n    {\n        A a;\n    }\n    static assert(!hasNested!A);\n}\n\n\n/***\n * Get as a tuple the types of the fields of a struct, class, or union.\n * This consists of the fields that take up memory space,\n * excluding the hidden fields like the virtual function\n * table pointer or a context pointer for nested types.\n * If `T` isn't a struct, class, or union returns a tuple\n * with one element `T`.\n */\ntemplate Fields(T)\n{\n    static if (is(T == struct) || is(T == union))\n        alias Fields = typeof(T.tupleof[0 .. $ - isNested!T]);\n    else static if (is(T == class))\n        alias Fields = typeof(T.tupleof);\n    else\n        alias Fields = AliasSeq!T;\n}\n\n///\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    struct S { int x; float y; }\n    static assert(is(Fields!S == AliasSeq!(int, float)));\n}\n\n/**\n * Alternate name for $(LREF Fields), kept for legacy compatibility.\n */\nalias FieldTypeTuple = Fields;\n\n@safe unittest\n{\n    static assert(is(FieldTypeTuple!int == AliasSeq!int));\n\n    static struct StaticStruct1 { }\n    static assert(is(FieldTypeTuple!StaticStruct1 == AliasSeq!()));\n\n    static struct StaticStruct2 { int a, b; }\n    static assert(is(FieldTypeTuple!StaticStruct2 == AliasSeq!(int, int)));\n\n    int i;\n\n    struct NestedStruct1 { void f() { ++i; } }\n    static assert(is(FieldTypeTuple!NestedStruct1 == AliasSeq!()));\n\n    struct NestedStruct2 { int a; void f() { ++i; } }\n    static assert(is(FieldTypeTuple!NestedStruct2 == AliasSeq!int));\n\n    class NestedClass { int a; void f() { ++i; } }\n    static assert(is(FieldTypeTuple!NestedClass == AliasSeq!int));\n}\n\n\n//Required for FieldNameTuple\nprivate enum NameOf(alias T) = T.stringof;\n\n/**\n * Get as an expression tuple the names of the fields of a struct, class, or\n * union. This consists of the fields that take up memory space, excluding the\n * hidden fields like the virtual function table pointer or a context pointer\n * for nested types.\n * Inherited fields (for classes) are not included.\n * If `T` isn't a struct, class, or union, an\n * expression tuple with an empty string is returned.\n */\ntemplate FieldNameTuple(T)\n{\n    import std.meta : staticMap;\n    static if (is(T == struct) || is(T == union))\n        alias FieldNameTuple = staticMap!(NameOf, T.tupleof[0 .. $ - isNested!T]);\n    else static if (is(T == class))\n        alias FieldNameTuple = staticMap!(NameOf, T.tupleof);\n    else\n        alias FieldNameTuple = AliasSeq!\"\";\n}\n\n///\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    struct S { int x; float y; }\n    static assert(FieldNameTuple!S == AliasSeq!(\"x\", \"y\"));\n    static assert(FieldNameTuple!int == AliasSeq!\"\");\n}\n\n@safe unittest\n{\n    static assert(FieldNameTuple!int == AliasSeq!\"\");\n\n    static struct StaticStruct1 { }\n    static assert(is(FieldNameTuple!StaticStruct1 == AliasSeq!()));\n\n    static struct StaticStruct2 { int a, b; }\n    static assert(FieldNameTuple!StaticStruct2 == AliasSeq!(\"a\", \"b\"));\n\n    static class StaticClass1 { }\n    static assert(is(FieldNameTuple!StaticClass1 == AliasSeq!()));\n\n    static class StaticClass2 : StaticClass1 { int a, b; }\n    static assert(FieldNameTuple!StaticClass2 == AliasSeq!(\"a\", \"b\"));\n\n    static class StaticClass3 : StaticClass2 { int c; }\n    static assert(FieldNameTuple!StaticClass3 == AliasSeq!(\"c\"));\n\n    int i;\n\n    struct NestedStruct1 { void f() { ++i; } }\n    static assert(is(FieldNameTuple!NestedStruct1 == AliasSeq!()));\n\n    struct NestedStruct2 { int a; void f() { ++i; } }\n    static assert(FieldNameTuple!NestedStruct2 == AliasSeq!\"a\");\n\n    class NestedClass { int a; void f() { ++i; } }\n    static assert(FieldNameTuple!NestedClass == AliasSeq!\"a\");\n}\n\n\n/***\nGet the primitive types of the fields of a struct or class, in\ntopological order.\n*/\ntemplate RepresentationTypeTuple(T)\n{\n    template Impl(T...)\n    {\n        static if (T.length == 0)\n        {\n            alias Impl = AliasSeq!();\n        }\n        else\n        {\n            import std.typecons : Rebindable;\n\n            static if (is(T[0] R: Rebindable!R))\n            {\n                alias Impl = Impl!(Impl!R, T[1 .. $]);\n            }\n            else  static if (is(T[0] == struct) || is(T[0] == union))\n            {\n                // @@@BUG@@@ this should work\n                //alias .RepresentationTypes!(T[0].tupleof)\n                //    RepresentationTypes;\n                alias Impl = Impl!(FieldTypeTuple!(T[0]), T[1 .. $]);\n            }\n            else\n            {\n                alias Impl = AliasSeq!(T[0], Impl!(T[1 .. $]));\n            }\n        }\n    }\n\n    static if (is(T == struct) || is(T == union) || is(T == class))\n    {\n        alias RepresentationTypeTuple = Impl!(FieldTypeTuple!T);\n    }\n    else\n    {\n        alias RepresentationTypeTuple = Impl!T;\n    }\n}\n\n///\n@safe unittest\n{\n    struct S1 { int a; float b; }\n    struct S2 { char[] a; union { S1 b; S1 * c; } }\n    alias R = RepresentationTypeTuple!S2;\n    assert(R.length == 4\n        && is(R[0] == char[]) && is(R[1] == int)\n        && is(R[2] == float) && is(R[3] == S1*));\n}\n\n@safe unittest\n{\n    alias S1 = RepresentationTypeTuple!int;\n    static assert(is(S1 == AliasSeq!int));\n\n    struct S2 { int a; }\n    struct S3 { int a; char b; }\n    struct S4 { S1 a; int b; S3 c; }\n    static assert(is(RepresentationTypeTuple!S2 == AliasSeq!int));\n    static assert(is(RepresentationTypeTuple!S3 == AliasSeq!(int, char)));\n    static assert(is(RepresentationTypeTuple!S4 == AliasSeq!(int, int, int, char)));\n\n    struct S11 { int a; float b; }\n    struct S21 { char[] a; union { S11 b; S11 * c; } }\n    alias R = RepresentationTypeTuple!S21;\n    assert(R.length == 4\n           && is(R[0] == char[]) && is(R[1] == int)\n           && is(R[2] == float) && is(R[3] == S11*));\n\n    class C { int a; float b; }\n    alias R1 = RepresentationTypeTuple!C;\n    static assert(R1.length == 2 && is(R1[0] == int) && is(R1[1] == float));\n\n    /* Issue 6642 */\n    import std.typecons : Rebindable;\n\n    struct S5 { int a; Rebindable!(immutable Object) b; }\n    alias R2 = RepresentationTypeTuple!S5;\n    static assert(R2.length == 2 && is(R2[0] == int) && is(R2[1] == immutable(Object)));\n}\n\n/*\nStatically evaluates to `true` if and only if `T`'s\nrepresentation contains at least one field of pointer or array type.\nMembers of class types are not considered raw pointers. Pointers to\nimmutable objects are not considered raw aliasing.\n*/\nprivate template hasRawAliasing(T...)\n{\n    template Impl(T...)\n    {\n        static if (T.length == 0)\n        {\n            enum Impl = false;\n        }\n        else\n        {\n            static if (is(T[0] foo : U*, U) && !isFunctionPointer!(T[0]))\n                enum has = !is(U == immutable);\n            else static if (is(T[0] foo : U[N], U, size_t N))\n                enum has = hasRawAliasing!U;\n            else static if (is(T[0] foo : U[], U) && !isStaticArray!(T[0]))\n                enum has = !is(U == immutable);\n            else static if (isAssociativeArray!(T[0]))\n                enum has = !is(T[0] == immutable);\n            else\n                enum has = false;\n\n            enum Impl = has || Impl!(T[1 .. $]);\n        }\n    }\n\n    enum hasRawAliasing = Impl!(RepresentationTypeTuple!T);\n}\n\n//\n@safe unittest\n{\n    // simple types\n    static assert(!hasRawAliasing!int);\n    static assert( hasRawAliasing!(char*));\n    // references aren't raw pointers\n    static assert(!hasRawAliasing!Object);\n    // built-in arrays do contain raw pointers\n    static assert( hasRawAliasing!(int[]));\n    // aggregate of simple types\n    struct S1 { int a; double b; }\n    static assert(!hasRawAliasing!S1);\n    // indirect aggregation\n    struct S2 { S1 a; double b; }\n    static assert(!hasRawAliasing!S2);\n}\n\n// Issue 19228\n@safe unittest\n{\n    static struct C\n    {\n        int*[1] a;\n    }\n    static assert(hasRawAliasing!C);\n}\n\n@safe unittest\n{\n    // struct with a pointer member\n    struct S3 { int a; double * b; }\n    static assert( hasRawAliasing!S3);\n    // struct with an indirect pointer member\n    struct S4 { S3 a; double b; }\n    static assert( hasRawAliasing!S4);\n    struct S5 { int a; Object z; int c; }\n    static assert( hasRawAliasing!S3);\n    static assert( hasRawAliasing!S4);\n    static assert(!hasRawAliasing!S5);\n\n    union S6 { int a; int b; }\n    union S7 { int a; int * b; }\n    static assert(!hasRawAliasing!S6);\n    static assert( hasRawAliasing!S7);\n\n    static assert(!hasRawAliasing!(void delegate()));\n    static assert(!hasRawAliasing!(void delegate() const));\n    static assert(!hasRawAliasing!(void delegate() immutable));\n    static assert(!hasRawAliasing!(void delegate() shared));\n    static assert(!hasRawAliasing!(void delegate() shared const));\n    static assert(!hasRawAliasing!(const(void delegate())));\n    static assert(!hasRawAliasing!(immutable(void delegate())));\n\n    struct S8 { void delegate() a; int b; Object c; }\n    class S12 { typeof(S8.tupleof) a; }\n    class S13 { typeof(S8.tupleof) a; int* b; }\n    static assert(!hasRawAliasing!S8);\n    static assert(!hasRawAliasing!S12);\n    static assert( hasRawAliasing!S13);\n\n    enum S9 { a }\n    static assert(!hasRawAliasing!S9);\n\n    // indirect members\n    struct S10 { S7 a; int b; }\n    struct S11 { S6 a; int b; }\n    static assert( hasRawAliasing!S10);\n    static assert(!hasRawAliasing!S11);\n\n    static assert( hasRawAliasing!(int[string]));\n    static assert(!hasRawAliasing!(immutable(int[string])));\n}\n\n/*\nStatically evaluates to `true` if and only if `T`'s\nrepresentation contains at least one non-shared field of pointer or\narray type.  Members of class types are not considered raw pointers.\nPointers to immutable objects are not considered raw aliasing.\n*/\nprivate template hasRawUnsharedAliasing(T...)\n{\n    template Impl(T...)\n    {\n        static if (T.length == 0)\n        {\n            enum Impl = false;\n        }\n        else\n        {\n            static if (is(T[0] foo : U*, U) && !isFunctionPointer!(T[0]))\n                enum has = !is(U == immutable) && !is(U == shared);\n            else static if (is(T[0] foo : U[], U) && !isStaticArray!(T[0]))\n                enum has = !is(U == immutable) && !is(U == shared);\n            else static if (isAssociativeArray!(T[0]))\n                enum has = !is(T[0] == immutable) && !is(T[0] == shared);\n            else\n                enum has = false;\n\n            enum Impl = has || Impl!(T[1 .. $]);\n        }\n    }\n\n    enum hasRawUnsharedAliasing = Impl!(RepresentationTypeTuple!T);\n}\n\n//\n@safe unittest\n{\n    // simple types\n    static assert(!hasRawUnsharedAliasing!int);\n    static assert( hasRawUnsharedAliasing!(char*));\n    static assert(!hasRawUnsharedAliasing!(shared char*));\n    // references aren't raw pointers\n    static assert(!hasRawUnsharedAliasing!Object);\n    // built-in arrays do contain raw pointers\n    static assert( hasRawUnsharedAliasing!(int[]));\n    static assert(!hasRawUnsharedAliasing!(shared int[]));\n    // aggregate of simple types\n    struct S1 { int a; double b; }\n    static assert(!hasRawUnsharedAliasing!S1);\n    // indirect aggregation\n    struct S2 { S1 a; double b; }\n    static assert(!hasRawUnsharedAliasing!S2);\n    // struct with a pointer member\n    struct S3 { int a; double * b; }\n    static assert( hasRawUnsharedAliasing!S3);\n    struct S4 { int a; shared double * b; }\n    static assert(!hasRawUnsharedAliasing!S4);\n}\n\n@safe unittest\n{\n    // struct with a pointer member\n    struct S3 { int a; double * b; }\n    static assert( hasRawUnsharedAliasing!S3);\n    struct S4 { int a; shared double * b; }\n    static assert(!hasRawUnsharedAliasing!S4);\n    // struct with an indirect pointer member\n    struct S5 { S3 a; double b; }\n    static assert( hasRawUnsharedAliasing!S5);\n    struct S6 { S4 a; double b; }\n    static assert(!hasRawUnsharedAliasing!S6);\n    struct S7 { int a; Object z;      int c; }\n    static assert( hasRawUnsharedAliasing!S5);\n    static assert(!hasRawUnsharedAliasing!S6);\n    static assert(!hasRawUnsharedAliasing!S7);\n\n    union S8  { int a; int b; }\n    union S9  { int a; int* b; }\n    union S10 { int a; shared int* b; }\n    static assert(!hasRawUnsharedAliasing!S8);\n    static assert( hasRawUnsharedAliasing!S9);\n    static assert(!hasRawUnsharedAliasing!S10);\n\n    static assert(!hasRawUnsharedAliasing!(void delegate()));\n    static assert(!hasRawUnsharedAliasing!(void delegate() const));\n    static assert(!hasRawUnsharedAliasing!(void delegate() immutable));\n    static assert(!hasRawUnsharedAliasing!(void delegate() shared));\n    static assert(!hasRawUnsharedAliasing!(void delegate() shared const));\n    static assert(!hasRawUnsharedAliasing!(const(void delegate())));\n    static assert(!hasRawUnsharedAliasing!(const(void delegate() const)));\n    static assert(!hasRawUnsharedAliasing!(const(void delegate() immutable)));\n    static assert(!hasRawUnsharedAliasing!(const(void delegate() shared)));\n    static assert(!hasRawUnsharedAliasing!(const(void delegate() shared const)));\n    static assert(!hasRawUnsharedAliasing!(immutable(void delegate())));\n    static assert(!hasRawUnsharedAliasing!(immutable(void delegate() const)));\n    static assert(!hasRawUnsharedAliasing!(immutable(void delegate() immutable)));\n    static assert(!hasRawUnsharedAliasing!(immutable(void delegate() shared)));\n    static assert(!hasRawUnsharedAliasing!(immutable(void delegate() shared const)));\n    static assert(!hasRawUnsharedAliasing!(shared(void delegate())));\n    static assert(!hasRawUnsharedAliasing!(shared(void delegate() const)));\n    static assert(!hasRawUnsharedAliasing!(shared(void delegate() immutable)));\n    static assert(!hasRawUnsharedAliasing!(shared(void delegate() shared)));\n    static assert(!hasRawUnsharedAliasing!(shared(void delegate() shared const)));\n    static assert(!hasRawUnsharedAliasing!(shared(const(void delegate()))));\n    static assert(!hasRawUnsharedAliasing!(shared(const(void delegate() const))));\n    static assert(!hasRawUnsharedAliasing!(shared(const(void delegate() immutable))));\n    static assert(!hasRawUnsharedAliasing!(shared(const(void delegate() shared))));\n    static assert(!hasRawUnsharedAliasing!(shared(const(void delegate() shared const))));\n    static assert(!hasRawUnsharedAliasing!(void function()));\n\n    enum S13 { a }\n    static assert(!hasRawUnsharedAliasing!S13);\n\n    // indirect members\n    struct S14 { S9  a; int b; }\n    struct S15 { S10 a; int b; }\n    struct S16 { S6  a; int b; }\n    static assert( hasRawUnsharedAliasing!S14);\n    static assert(!hasRawUnsharedAliasing!S15);\n    static assert(!hasRawUnsharedAliasing!S16);\n\n    static assert( hasRawUnsharedAliasing!(int[string]));\n    static assert(!hasRawUnsharedAliasing!(shared(int[string])));\n    static assert(!hasRawUnsharedAliasing!(immutable(int[string])));\n\n    struct S17\n    {\n        void delegate() shared a;\n        void delegate() immutable b;\n        void delegate() shared const c;\n        shared(void delegate()) d;\n        shared(void delegate() shared) e;\n        shared(void delegate() immutable) f;\n        shared(void delegate() shared const) g;\n        immutable(void delegate()) h;\n        immutable(void delegate() shared) i;\n        immutable(void delegate() immutable) j;\n        immutable(void delegate() shared const) k;\n        shared(const(void delegate())) l;\n        shared(const(void delegate() shared)) m;\n        shared(const(void delegate() immutable)) n;\n        shared(const(void delegate() shared const)) o;\n    }\n    struct S18 { typeof(S17.tupleof) a; void delegate() p; }\n    struct S19 { typeof(S17.tupleof) a; Object p; }\n    struct S20 { typeof(S17.tupleof) a; int* p; }\n    class S21 { typeof(S17.tupleof) a; }\n    class S22 { typeof(S17.tupleof) a; void delegate() p; }\n    class S23 { typeof(S17.tupleof) a; Object p; }\n    class S24 { typeof(S17.tupleof) a; int* p; }\n    static assert(!hasRawUnsharedAliasing!S17);\n    static assert(!hasRawUnsharedAliasing!(immutable(S17)));\n    static assert(!hasRawUnsharedAliasing!(shared(S17)));\n    static assert(!hasRawUnsharedAliasing!S18);\n    static assert(!hasRawUnsharedAliasing!(immutable(S18)));\n    static assert(!hasRawUnsharedAliasing!(shared(S18)));\n    static assert(!hasRawUnsharedAliasing!S19);\n    static assert(!hasRawUnsharedAliasing!(immutable(S19)));\n    static assert(!hasRawUnsharedAliasing!(shared(S19)));\n    static assert( hasRawUnsharedAliasing!S20);\n    static assert(!hasRawUnsharedAliasing!(immutable(S20)));\n    static assert(!hasRawUnsharedAliasing!(shared(S20)));\n    static assert(!hasRawUnsharedAliasing!S21);\n    static assert(!hasRawUnsharedAliasing!(immutable(S21)));\n    static assert(!hasRawUnsharedAliasing!(shared(S21)));\n    static assert(!hasRawUnsharedAliasing!S22);\n    static assert(!hasRawUnsharedAliasing!(immutable(S22)));\n    static assert(!hasRawUnsharedAliasing!(shared(S22)));\n    static assert(!hasRawUnsharedAliasing!S23);\n    static assert(!hasRawUnsharedAliasing!(immutable(S23)));\n    static assert(!hasRawUnsharedAliasing!(shared(S23)));\n    static assert( hasRawUnsharedAliasing!S24);\n    static assert(!hasRawUnsharedAliasing!(immutable(S24)));\n    static assert(!hasRawUnsharedAliasing!(shared(S24)));\n    struct S25 {}\n    class S26 {}\n    interface S27 {}\n    union S28 {}\n    static assert(!hasRawUnsharedAliasing!S25);\n    static assert(!hasRawUnsharedAliasing!S26);\n    static assert(!hasRawUnsharedAliasing!S27);\n    static assert(!hasRawUnsharedAliasing!S28);\n}\n\n/*\nStatically evaluates to `true` if and only if `T`'s\nrepresentation includes at least one non-immutable object reference.\n*/\n\nprivate template hasObjects(T...)\n{\n    static if (T.length == 0)\n    {\n        enum hasObjects = false;\n    }\n    else static if (is(T[0] == struct))\n    {\n        enum hasObjects = hasObjects!(\n            RepresentationTypeTuple!(T[0]), T[1 .. $]);\n    }\n    else\n    {\n        enum hasObjects = ((is(T[0] == class) || is(T[0] == interface))\n            && !is(T[0] == immutable)) || hasObjects!(T[1 .. $]);\n    }\n}\n\n/*\nStatically evaluates to `true` if and only if `T`'s\nrepresentation includes at least one non-immutable non-shared object\nreference.\n*/\nprivate template hasUnsharedObjects(T...)\n{\n    static if (T.length == 0)\n    {\n        enum hasUnsharedObjects = false;\n    }\n    else static if (is(T[0] == struct))\n    {\n        enum hasUnsharedObjects = hasUnsharedObjects!(\n            RepresentationTypeTuple!(T[0]), T[1 .. $]);\n    }\n    else\n    {\n        enum hasUnsharedObjects = ((is(T[0] == class) || is(T[0] == interface)) &&\n                                !is(T[0] == immutable) && !is(T[0] == shared)) ||\n            hasUnsharedObjects!(T[1 .. $]);\n    }\n}\n\n/**\nReturns `true` if and only if `T`'s representation includes at\nleast one of the following: $(OL $(LI a raw pointer `U*` and `U`\nis not immutable;) $(LI an array `U[]` and `U` is not\nimmutable;) $(LI a reference to a class or interface type `C` and `C` is\nnot immutable.) $(LI an associative array that is not immutable.)\n$(LI a delegate.))\n*/\ntemplate hasAliasing(T...)\n{\n    import std.meta : anySatisfy;\n    import std.typecons : Rebindable;\n\n    static if (T.length && is(T[0] : Rebindable!R, R))\n    {\n        enum hasAliasing = hasAliasing!(R, T[1 .. $]);\n    }\n    else\n    {\n        template isAliasingDelegate(T)\n        {\n            enum isAliasingDelegate = isDelegate!T\n                                  && !is(T == immutable)\n                                  && !is(FunctionTypeOf!T == immutable);\n        }\n        enum hasAliasing = hasRawAliasing!T || hasObjects!T ||\n            anySatisfy!(isAliasingDelegate, T, RepresentationTypeTuple!T);\n    }\n}\n\n///\n@safe unittest\n{\n    struct S1 { int a; Object b; }\n    struct S2 { string a; }\n    struct S3 { int a; immutable Object b; }\n    struct S4 { float[3] vals; }\n    static assert( hasAliasing!S1);\n    static assert(!hasAliasing!S2);\n    static assert(!hasAliasing!S3);\n    static assert(!hasAliasing!S4);\n}\n\n@safe unittest\n{\n    static assert( hasAliasing!(uint[uint]));\n    static assert(!hasAliasing!(immutable(uint[uint])));\n    static assert( hasAliasing!(void delegate()));\n    static assert( hasAliasing!(void delegate() const));\n    static assert(!hasAliasing!(void delegate() immutable));\n    static assert( hasAliasing!(void delegate() shared));\n    static assert( hasAliasing!(void delegate() shared const));\n    static assert( hasAliasing!(const(void delegate())));\n    static assert( hasAliasing!(const(void delegate() const)));\n    static assert(!hasAliasing!(const(void delegate() immutable)));\n    static assert( hasAliasing!(const(void delegate() shared)));\n    static assert( hasAliasing!(const(void delegate() shared const)));\n    static assert(!hasAliasing!(immutable(void delegate())));\n    static assert(!hasAliasing!(immutable(void delegate() const)));\n    static assert(!hasAliasing!(immutable(void delegate() immutable)));\n    static assert(!hasAliasing!(immutable(void delegate() shared)));\n    static assert(!hasAliasing!(immutable(void delegate() shared const)));\n    static assert( hasAliasing!(shared(const(void delegate()))));\n    static assert( hasAliasing!(shared(const(void delegate() const))));\n    static assert(!hasAliasing!(shared(const(void delegate() immutable))));\n    static assert( hasAliasing!(shared(const(void delegate() shared))));\n    static assert( hasAliasing!(shared(const(void delegate() shared const))));\n    static assert(!hasAliasing!(void function()));\n\n    interface I;\n    static assert( hasAliasing!I);\n\n    import std.typecons : Rebindable;\n    static assert( hasAliasing!(Rebindable!(const Object)));\n    static assert(!hasAliasing!(Rebindable!(immutable Object)));\n    static assert( hasAliasing!(Rebindable!(shared Object)));\n    static assert( hasAliasing!(Rebindable!Object));\n\n    struct S5\n    {\n        void delegate() immutable b;\n        shared(void delegate() immutable) f;\n        immutable(void delegate() immutable) j;\n        shared(const(void delegate() immutable)) n;\n    }\n    struct S6 { typeof(S5.tupleof) a; void delegate() p; }\n    static assert(!hasAliasing!S5);\n    static assert( hasAliasing!S6);\n\n    struct S7 { void delegate() a; int b; Object c; }\n    class S8 { int a; int b; }\n    class S9 { typeof(S8.tupleof) a; }\n    class S10 { typeof(S8.tupleof) a; int* b; }\n    static assert( hasAliasing!S7);\n    static assert( hasAliasing!S8);\n    static assert( hasAliasing!S9);\n    static assert( hasAliasing!S10);\n    struct S11 {}\n    class S12 {}\n    interface S13 {}\n    union S14 {}\n    static assert(!hasAliasing!S11);\n    static assert( hasAliasing!S12);\n    static assert( hasAliasing!S13);\n    static assert(!hasAliasing!S14);\n}\n/**\nReturns `true` if and only if `T`'s representation includes at\nleast one of the following: $(OL $(LI a raw pointer `U*`;) $(LI an\narray `U[]`;) $(LI a reference to a class type `C`.)\n$(LI an associative array.) $(LI a delegate.))\n */\ntemplate hasIndirections(T)\n{\n    import std.meta : anySatisfy;\n    static if (is(T == struct) || is(T == union))\n        enum hasIndirections = anySatisfy!(.hasIndirections, FieldTypeTuple!T);\n    else static if (isStaticArray!T && is(T : E[N], E, size_t N))\n        enum hasIndirections = is(E == void) ? true : hasIndirections!E;\n    else static if (isFunctionPointer!T)\n        enum hasIndirections = false;\n    else\n        enum hasIndirections = isPointer!T || isDelegate!T || isDynamicArray!T ||\n            isAssociativeArray!T || is (T == class) || is(T == interface);\n}\n\n///\n@safe unittest\n{\n    static assert( hasIndirections!(int[string]));\n    static assert( hasIndirections!(void delegate()));\n    static assert( hasIndirections!(void delegate() immutable));\n    static assert( hasIndirections!(immutable(void delegate())));\n    static assert( hasIndirections!(immutable(void delegate() immutable)));\n\n    static assert(!hasIndirections!(void function()));\n    static assert( hasIndirections!(void*[1]));\n    static assert(!hasIndirections!(byte[1]));\n}\n\n@safe unittest\n{\n    // void static array hides actual type of bits, so \"may have indirections\".\n    static assert( hasIndirections!(void[1]));\n    interface I {}\n    struct S1 {}\n    struct S2 { int a; }\n    struct S3 { int a; int b; }\n    struct S4 { int a; int* b; }\n    struct S5 { int a; Object b; }\n    struct S6 { int a; string b; }\n    struct S7 { int a; immutable Object b; }\n    struct S8 { int a; immutable I b; }\n    struct S9 { int a; void delegate() b; }\n    struct S10 { int a; immutable(void delegate()) b; }\n    struct S11 { int a; void delegate() immutable b; }\n    struct S12 { int a; immutable(void delegate() immutable) b; }\n    class S13 {}\n    class S14 { int a; }\n    class S15 { int a; int b; }\n    class S16 { int a; Object b; }\n    class S17 { string a; }\n    class S18 { int a; immutable Object b; }\n    class S19 { int a; immutable(void delegate() immutable) b; }\n    union S20 {}\n    union S21 { int a; }\n    union S22 { int a; int b; }\n    union S23 { int a; Object b; }\n    union S24 { string a; }\n    union S25 { int a; immutable Object b; }\n    union S26 { int a; immutable(void delegate() immutable) b; }\n    static assert( hasIndirections!I);\n    static assert(!hasIndirections!S1);\n    static assert(!hasIndirections!S2);\n    static assert(!hasIndirections!S3);\n    static assert( hasIndirections!S4);\n    static assert( hasIndirections!S5);\n    static assert( hasIndirections!S6);\n    static assert( hasIndirections!S7);\n    static assert( hasIndirections!S8);\n    static assert( hasIndirections!S9);\n    static assert( hasIndirections!S10);\n    static assert( hasIndirections!S12);\n    static assert( hasIndirections!S13);\n    static assert( hasIndirections!S14);\n    static assert( hasIndirections!S15);\n    static assert( hasIndirections!S16);\n    static assert( hasIndirections!S17);\n    static assert( hasIndirections!S18);\n    static assert( hasIndirections!S19);\n    static assert(!hasIndirections!S20);\n    static assert(!hasIndirections!S21);\n    static assert(!hasIndirections!S22);\n    static assert( hasIndirections!S23);\n    static assert( hasIndirections!S24);\n    static assert( hasIndirections!S25);\n    static assert( hasIndirections!S26);\n}\n\n@safe unittest //12000\n{\n    static struct S(T)\n    {\n        static assert(hasIndirections!T);\n    }\n\n    static class A(T)\n    {\n        S!A a;\n    }\n\n    A!int dummy;\n}\n\n/**\nReturns `true` if and only if `T`'s representation includes at\nleast one of the following: $(OL $(LI a raw pointer `U*` and `U`\nis not immutable or shared;) $(LI an array `U[]` and `U` is not\nimmutable or shared;) $(LI a reference to a class type `C` and\n`C` is not immutable or shared.) $(LI an associative array that is not\nimmutable or shared.) $(LI a delegate that is not shared.))\n*/\n\ntemplate hasUnsharedAliasing(T...)\n{\n    import std.meta : anySatisfy;\n    import std.typecons : Rebindable;\n\n    static if (!T.length)\n    {\n        enum hasUnsharedAliasing = false;\n    }\n    else static if (is(T[0] R: Rebindable!R))\n    {\n        enum hasUnsharedAliasing = hasUnsharedAliasing!R;\n    }\n    else\n    {\n        template unsharedDelegate(T)\n        {\n            enum bool unsharedDelegate = isDelegate!T\n                                     && !is(T == shared)\n                                     && !is(T == shared)\n                                     && !is(T == immutable)\n                                     && !is(FunctionTypeOf!T == shared)\n                                     && !is(FunctionTypeOf!T == immutable);\n        }\n\n        enum hasUnsharedAliasing =\n            hasRawUnsharedAliasing!(T[0]) ||\n            anySatisfy!(unsharedDelegate, RepresentationTypeTuple!(T[0])) ||\n            hasUnsharedObjects!(T[0]) ||\n            hasUnsharedAliasing!(T[1..$]);\n    }\n}\n\n///\n@safe unittest\n{\n    struct S1 { int a; Object b; }\n    struct S2 { string a; }\n    struct S3 { int a; immutable Object b; }\n    static assert( hasUnsharedAliasing!S1);\n    static assert(!hasUnsharedAliasing!S2);\n    static assert(!hasUnsharedAliasing!S3);\n\n    struct S4 { int a; shared Object b; }\n    struct S5 { char[] a; }\n    struct S6 { shared char[] b; }\n    struct S7 { float[3] vals; }\n    static assert(!hasUnsharedAliasing!S4);\n    static assert( hasUnsharedAliasing!S5);\n    static assert(!hasUnsharedAliasing!S6);\n    static assert(!hasUnsharedAliasing!S7);\n}\n\n@safe unittest\n{\n    /* Issue 6642 */\n    import std.typecons : Rebindable;\n    struct S8 { int a; Rebindable!(immutable Object) b; }\n    static assert(!hasUnsharedAliasing!S8);\n\n    static assert( hasUnsharedAliasing!(uint[uint]));\n\n    static assert( hasUnsharedAliasing!(void delegate()));\n    static assert( hasUnsharedAliasing!(void delegate() const));\n    static assert(!hasUnsharedAliasing!(void delegate() immutable));\n    static assert(!hasUnsharedAliasing!(void delegate() shared));\n    static assert(!hasUnsharedAliasing!(void delegate() shared const));\n}\n\n@safe unittest\n{\n    import std.typecons : Rebindable;\n    static assert( hasUnsharedAliasing!(const(void delegate())));\n    static assert( hasUnsharedAliasing!(const(void delegate() const)));\n    static assert(!hasUnsharedAliasing!(const(void delegate() immutable)));\n    static assert(!hasUnsharedAliasing!(const(void delegate() shared)));\n    static assert(!hasUnsharedAliasing!(const(void delegate() shared const)));\n    static assert(!hasUnsharedAliasing!(immutable(void delegate())));\n    static assert(!hasUnsharedAliasing!(immutable(void delegate() const)));\n    static assert(!hasUnsharedAliasing!(immutable(void delegate() immutable)));\n    static assert(!hasUnsharedAliasing!(immutable(void delegate() shared)));\n    static assert(!hasUnsharedAliasing!(immutable(void delegate() shared const)));\n    static assert(!hasUnsharedAliasing!(shared(void delegate())));\n    static assert(!hasUnsharedAliasing!(shared(void delegate() const)));\n    static assert(!hasUnsharedAliasing!(shared(void delegate() immutable)));\n    static assert(!hasUnsharedAliasing!(shared(void delegate() shared)));\n    static assert(!hasUnsharedAliasing!(shared(void delegate() shared const)));\n    static assert(!hasUnsharedAliasing!(shared(const(void delegate()))));\n    static assert(!hasUnsharedAliasing!(shared(const(void delegate() const))));\n    static assert(!hasUnsharedAliasing!(shared(const(void delegate() immutable))));\n    static assert(!hasUnsharedAliasing!(shared(const(void delegate() shared))));\n    static assert(!hasUnsharedAliasing!(shared(const(void delegate() shared const))));\n    static assert(!hasUnsharedAliasing!(void function()));\n\n    interface I {}\n    static assert(hasUnsharedAliasing!I);\n\n    static assert( hasUnsharedAliasing!(Rebindable!(const Object)));\n    static assert(!hasUnsharedAliasing!(Rebindable!(immutable Object)));\n    static assert(!hasUnsharedAliasing!(Rebindable!(shared Object)));\n    static assert( hasUnsharedAliasing!(Rebindable!Object));\n\n    /* Issue 6979 */\n    static assert(!hasUnsharedAliasing!(int, shared(int)*));\n    static assert( hasUnsharedAliasing!(int, int*));\n    static assert( hasUnsharedAliasing!(int, const(int)[]));\n    static assert( hasUnsharedAliasing!(int, shared(int)*, Rebindable!Object));\n    static assert(!hasUnsharedAliasing!(shared(int)*, Rebindable!(shared Object)));\n    static assert(!hasUnsharedAliasing!());\n\n    struct S9\n    {\n        void delegate() shared a;\n        void delegate() immutable b;\n        void delegate() shared const c;\n        shared(void delegate()) d;\n        shared(void delegate() shared) e;\n        shared(void delegate() immutable) f;\n        shared(void delegate() shared const) g;\n        immutable(void delegate()) h;\n        immutable(void delegate() shared) i;\n        immutable(void delegate() immutable) j;\n        immutable(void delegate() shared const) k;\n        shared(const(void delegate())) l;\n        shared(const(void delegate() shared)) m;\n        shared(const(void delegate() immutable)) n;\n        shared(const(void delegate() shared const)) o;\n    }\n    struct S10 { typeof(S9.tupleof) a; void delegate() p; }\n    struct S11 { typeof(S9.tupleof) a; Object p; }\n    struct S12 { typeof(S9.tupleof) a; int* p; }\n    class S13 { typeof(S9.tupleof) a; }\n    class S14 { typeof(S9.tupleof) a; void delegate() p; }\n    class S15 { typeof(S9.tupleof) a; Object p; }\n    class S16 { typeof(S9.tupleof) a; int* p; }\n    static assert(!hasUnsharedAliasing!S9);\n    static assert(!hasUnsharedAliasing!(immutable(S9)));\n    static assert(!hasUnsharedAliasing!(shared(S9)));\n    static assert( hasUnsharedAliasing!S10);\n    static assert(!hasUnsharedAliasing!(immutable(S10)));\n    static assert(!hasUnsharedAliasing!(shared(S10)));\n    static assert( hasUnsharedAliasing!S11);\n    static assert(!hasUnsharedAliasing!(immutable(S11)));\n    static assert(!hasUnsharedAliasing!(shared(S11)));\n    static assert( hasUnsharedAliasing!S12);\n    static assert(!hasUnsharedAliasing!(immutable(S12)));\n    static assert(!hasUnsharedAliasing!(shared(S12)));\n    static assert( hasUnsharedAliasing!S13);\n    static assert(!hasUnsharedAliasing!(immutable(S13)));\n    static assert(!hasUnsharedAliasing!(shared(S13)));\n    static assert( hasUnsharedAliasing!S14);\n    static assert(!hasUnsharedAliasing!(immutable(S14)));\n    static assert(!hasUnsharedAliasing!(shared(S14)));\n    static assert( hasUnsharedAliasing!S15);\n    static assert(!hasUnsharedAliasing!(immutable(S15)));\n    static assert(!hasUnsharedAliasing!(shared(S15)));\n    static assert( hasUnsharedAliasing!S16);\n    static assert(!hasUnsharedAliasing!(immutable(S16)));\n    static assert(!hasUnsharedAliasing!(shared(S16)));\n    struct S17 {}\n    class S18 {}\n    interface S19 {}\n    union S20 {}\n    static assert(!hasUnsharedAliasing!S17);\n    static assert( hasUnsharedAliasing!S18);\n    static assert( hasUnsharedAliasing!S19);\n    static assert(!hasUnsharedAliasing!S20);\n}\n\n/**\n True if `S` or any type embedded directly in the representation of `S`\n defines an elaborate copy constructor. Elaborate copy constructors are\n introduced by defining `this(this)` for a `struct`.\n\n Classes and unions never have elaborate copy constructors.\n */\ntemplate hasElaborateCopyConstructor(S)\n{\n    import std.meta : anySatisfy;\n    static if (isStaticArray!S && S.length)\n    {\n        enum bool hasElaborateCopyConstructor = hasElaborateCopyConstructor!(typeof(S.init[0]));\n    }\n    else static if (is(S == struct))\n    {\n        enum hasElaborateCopyConstructor = hasMember!(S, \"__xpostblit\");\n    }\n    else\n    {\n        enum bool hasElaborateCopyConstructor = false;\n    }\n}\n\n///\n@safe unittest\n{\n    static assert(!hasElaborateCopyConstructor!int);\n\n    static struct S1 { }\n    static struct S2 { this(this) {} }\n    static struct S3 { S2 field; }\n    static struct S4 { S3[1] field; }\n    static struct S5 { S3[] field; }\n    static struct S6 { S3[0] field; }\n    static struct S7 { @disable this(); S3 field; }\n    static assert(!hasElaborateCopyConstructor!S1);\n    static assert( hasElaborateCopyConstructor!S2);\n    static assert( hasElaborateCopyConstructor!(immutable S2));\n    static assert( hasElaborateCopyConstructor!S3);\n    static assert( hasElaborateCopyConstructor!(S3[1]));\n    static assert(!hasElaborateCopyConstructor!(S3[0]));\n    static assert( hasElaborateCopyConstructor!S4);\n    static assert(!hasElaborateCopyConstructor!S5);\n    static assert(!hasElaborateCopyConstructor!S6);\n    static assert( hasElaborateCopyConstructor!S7);\n}\n\n/**\n   True if `S` or any type directly embedded in the representation of `S`\n   defines an elaborate assignment. Elaborate assignments are introduced by\n   defining `opAssign(typeof(this))` or $(D opAssign(ref typeof(this)))\n   for a `struct` or when there is a compiler-generated `opAssign`.\n\n   A type `S` gets compiler-generated `opAssign` in case it has\n   an elaborate copy constructor or elaborate destructor.\n\n   Classes and unions never have elaborate assignments.\n\n   Note: Structs with (possibly nested) postblit operator(s) will have a\n   hidden yet elaborate compiler generated assignment operator (unless\n   explicitly disabled).\n */\ntemplate hasElaborateAssign(S)\n{\n    import std.meta : anySatisfy;\n    static if (isStaticArray!S && S.length)\n    {\n        enum bool hasElaborateAssign = hasElaborateAssign!(typeof(S.init[0]));\n    }\n    else static if (is(S == struct))\n    {\n        enum hasElaborateAssign = is(typeof(S.init.opAssign(rvalueOf!S))) ||\n                                  is(typeof(S.init.opAssign(lvalueOf!S))) ||\n            anySatisfy!(.hasElaborateAssign, FieldTypeTuple!S);\n    }\n    else\n    {\n        enum bool hasElaborateAssign = false;\n    }\n}\n\n///\n@safe unittest\n{\n    static assert(!hasElaborateAssign!int);\n\n    static struct S  { void opAssign(S) {} }\n    static assert( hasElaborateAssign!S);\n    static assert(!hasElaborateAssign!(const(S)));\n\n    static struct S1 { void opAssign(ref S1) {} }\n    static struct S2 { void opAssign(int) {} }\n    static struct S3 { S s; }\n    static assert( hasElaborateAssign!S1);\n    static assert(!hasElaborateAssign!S2);\n    static assert( hasElaborateAssign!S3);\n    static assert( hasElaborateAssign!(S3[1]));\n    static assert(!hasElaborateAssign!(S3[0]));\n}\n\n@safe unittest\n{\n    static struct S  { void opAssign(S) {} }\n    static struct S4\n    {\n        void opAssign(U)(U u) {}\n        @disable void opAssign(U)(ref U u);\n    }\n    static assert( hasElaborateAssign!S4);\n\n    static struct S41\n    {\n        void opAssign(U)(ref U u) {}\n        @disable void opAssign(U)(U u);\n    }\n    static assert( hasElaborateAssign!S41);\n\n    static struct S5 { @disable this(); this(int n){ s = S(); } S s; }\n    static assert( hasElaborateAssign!S5);\n\n    static struct S6 { this(this) {} }\n    static struct S7 { this(this) {} @disable void opAssign(S7); }\n    static struct S8 { this(this) {} @disable void opAssign(S8); void opAssign(int) {} }\n    static struct S9 { this(this) {}                             void opAssign(int) {} }\n    static struct S10 { ~this() { } }\n    static assert( hasElaborateAssign!S6);\n    static assert(!hasElaborateAssign!S7);\n    static assert(!hasElaborateAssign!S8);\n    static assert( hasElaborateAssign!S9);\n    static assert( hasElaborateAssign!S10);\n    static struct SS6 { S6 s; }\n    static struct SS7 { S7 s; }\n    static struct SS8 { S8 s; }\n    static struct SS9 { S9 s; }\n    static assert( hasElaborateAssign!SS6);\n    static assert(!hasElaborateAssign!SS7);\n    static assert(!hasElaborateAssign!SS8);\n    static assert( hasElaborateAssign!SS9);\n}\n\n/**\n   True if `S` or any type directly embedded in the representation\n   of `S` defines an elaborate destructor. Elaborate destructors\n   are introduced by defining `~this()` for a $(D\n   struct).\n\n   Classes and unions never have elaborate destructors, even\n   though classes may define `~this()`.\n */\ntemplate hasElaborateDestructor(S)\n{\n    import std.meta : anySatisfy;\n    static if (isStaticArray!S && S.length)\n    {\n        enum bool hasElaborateDestructor = hasElaborateDestructor!(typeof(S.init[0]));\n    }\n    else static if (is(S == struct))\n    {\n        enum hasElaborateDestructor = hasMember!(S, \"__dtor\")\n            || anySatisfy!(.hasElaborateDestructor, FieldTypeTuple!S);\n    }\n    else\n    {\n        enum bool hasElaborateDestructor = false;\n    }\n}\n\n///\n@safe unittest\n{\n    static assert(!hasElaborateDestructor!int);\n\n    static struct S1 { }\n    static struct S2 { ~this() {} }\n    static struct S3 { S2 field; }\n    static struct S4 { S3[1] field; }\n    static struct S5 { S3[] field; }\n    static struct S6 { S3[0] field; }\n    static struct S7 { @disable this(); S3 field; }\n    static assert(!hasElaborateDestructor!S1);\n    static assert( hasElaborateDestructor!S2);\n    static assert( hasElaborateDestructor!(immutable S2));\n    static assert( hasElaborateDestructor!S3);\n    static assert( hasElaborateDestructor!(S3[1]));\n    static assert(!hasElaborateDestructor!(S3[0]));\n    static assert( hasElaborateDestructor!S4);\n    static assert(!hasElaborateDestructor!S5);\n    static assert(!hasElaborateDestructor!S6);\n    static assert( hasElaborateDestructor!S7);\n}\n\npackage alias Identity(alias A) = A;\n\n/**\n   Yields `true` if and only if `T` is an aggregate that defines\n   a symbol called `name`.\n */\nenum hasMember(T, string name) = __traits(hasMember, T, name);\n\n///\n@safe unittest\n{\n    static assert(!hasMember!(int, \"blah\"));\n    struct S1 { int blah; }\n    struct S2 { int blah(){ return 0; } }\n    class C1 { int blah; }\n    class C2 { int blah(){ return 0; } }\n    static assert(hasMember!(S1, \"blah\"));\n    static assert(hasMember!(S2, \"blah\"));\n    static assert(hasMember!(C1, \"blah\"));\n    static assert(hasMember!(C2, \"blah\"));\n}\n\n@safe unittest\n{\n    // 8321\n    struct S {\n        int x;\n        void f(){}\n        void t()(){}\n        template T(){}\n    }\n    struct R1(T) {\n        T t;\n        alias t this;\n    }\n    struct R2(T) {\n        T t;\n        @property ref inout(T) payload() inout { return t; }\n        alias t this;\n    }\n    static assert(hasMember!(S, \"x\"));\n    static assert(hasMember!(S, \"f\"));\n    static assert(hasMember!(S, \"t\"));\n    static assert(hasMember!(S, \"T\"));\n    static assert(hasMember!(R1!S, \"x\"));\n    static assert(hasMember!(R1!S, \"f\"));\n    static assert(hasMember!(R1!S, \"t\"));\n    static assert(hasMember!(R1!S, \"T\"));\n    static assert(hasMember!(R2!S, \"x\"));\n    static assert(hasMember!(R2!S, \"f\"));\n    static assert(hasMember!(R2!S, \"t\"));\n    static assert(hasMember!(R2!S, \"T\"));\n}\n\n@safe unittest\n{\n    static struct S\n    {\n        void opDispatch(string n, A)(A dummy) {}\n    }\n    static assert(hasMember!(S, \"foo\"));\n}\n\n/**\n * Whether the symbol represented by the string, member, exists and is a static member of T.\n *\n * Params:\n *     T = Type containing symbol `member`.\n *     member = Name of symbol to test that resides in `T`.\n *\n * Returns:\n *     `true` iff `member` exists and is static.\n */\ntemplate hasStaticMember(T, string member)\n{\n    static if (__traits(hasMember, T, member))\n    {\n        static if (isPointer!T)\n            alias U = PointerTarget!T;\n        else\n            alias U = T;\n\n        import std.meta : Alias;\n        alias sym = Alias!(__traits(getMember, U, member));\n\n        static if (__traits(getOverloads, U, member).length == 0)\n            enum bool hasStaticMember = __traits(compiles, &sym);\n        else\n            enum bool hasStaticMember = __traits(isStaticFunction, sym);\n    }\n    else\n    {\n        enum bool hasStaticMember = false;\n    }\n}\n\n///\n@safe unittest\n{\n    static struct S\n    {\n        static void sf() {}\n        void f() {}\n\n        static int si;\n        int i;\n    }\n\n    static assert( hasStaticMember!(S, \"sf\"));\n    static assert(!hasStaticMember!(S, \"f\"));\n\n    static assert( hasStaticMember!(S, \"si\"));\n    static assert(!hasStaticMember!(S, \"i\"));\n\n    static assert(!hasStaticMember!(S, \"hello\"));\n}\n\n@safe unittest\n{\n    static struct S\n    {\n        enum X = 10;\n        enum Y\n        {\n            i = 10\n        }\n        struct S {}\n        class C {}\n\n        static int sx = 0;\n        __gshared int gx = 0;\n\n        Y y;\n        static Y sy;\n\n        static void f();\n        static void f2() pure nothrow @nogc @safe;\n\n        shared void g();\n\n        static void function() fp;\n        __gshared void function() gfp;\n        void function() fpm;\n\n        void delegate() dm;\n        static void delegate() sd;\n\n        void m();\n        void m2() const pure nothrow @nogc @safe;\n\n        inout(int) iom() inout;\n        static inout(int) iosf(inout int x);\n\n        @property int p();\n        static @property int sp();\n    }\n\n    static class C\n    {\n        enum X = 10;\n        enum Y\n        {\n            i = 10\n        }\n        struct S {}\n        class C {}\n\n        static int sx = 0;\n        __gshared int gx = 0;\n\n        Y y;\n        static Y sy;\n\n        static void f();\n        static void f2() pure nothrow @nogc @safe;\n\n        shared void g() { }\n\n        static void function() fp;\n        __gshared void function() gfp;\n        void function() fpm;\n\n        void delegate() dm;\n        static void delegate() sd;\n\n        void m() {}\n        final void m2() const pure nothrow @nogc @safe;\n\n        inout(int) iom() inout { return 10; }\n        static inout(int) iosf(inout int x);\n\n        @property int p() { return 10; }\n        static @property int sp();\n    }\n\n    static assert(!hasStaticMember!(S, \"na\"));\n    static assert(!hasStaticMember!(S, \"X\"));\n    static assert(!hasStaticMember!(S, \"Y\"));\n    static assert(!hasStaticMember!(S, \"Y.i\"));\n    static assert(!hasStaticMember!(S, \"S\"));\n    static assert(!hasStaticMember!(S, \"C\"));\n    static assert( hasStaticMember!(S, \"sx\"));\n    static assert( hasStaticMember!(S, \"gx\"));\n    static assert(!hasStaticMember!(S, \"y\"));\n    static assert( hasStaticMember!(S, \"sy\"));\n    static assert( hasStaticMember!(S, \"f\"));\n    static assert( hasStaticMember!(S, \"f2\"));\n    static assert(!hasStaticMember!(S, \"dm\"));\n    static assert( hasStaticMember!(S, \"sd\"));\n    static assert(!hasStaticMember!(S, \"g\"));\n    static assert( hasStaticMember!(S, \"fp\"));\n    static assert( hasStaticMember!(S, \"gfp\"));\n    static assert(!hasStaticMember!(S, \"fpm\"));\n    static assert(!hasStaticMember!(S, \"m\"));\n    static assert(!hasStaticMember!(S, \"m2\"));\n    static assert(!hasStaticMember!(S, \"iom\"));\n    static assert( hasStaticMember!(S, \"iosf\"));\n    static assert(!hasStaticMember!(S, \"p\"));\n    static assert( hasStaticMember!(S, \"sp\"));\n\n    static assert(!hasStaticMember!(C, \"na\"));\n    static assert(!hasStaticMember!(C, \"X\"));\n    static assert(!hasStaticMember!(C, \"Y\"));\n    static assert(!hasStaticMember!(C, \"Y.i\"));\n    static assert(!hasStaticMember!(C, \"S\"));\n    static assert(!hasStaticMember!(C, \"C\"));\n    static assert( hasStaticMember!(C, \"sx\"));\n    static assert( hasStaticMember!(C, \"gx\"));\n    static assert(!hasStaticMember!(C, \"y\"));\n    static assert( hasStaticMember!(C, \"sy\"));\n    static assert( hasStaticMember!(C, \"f\"));\n    static assert( hasStaticMember!(C, \"f2\"));\n    static assert(!hasStaticMember!(C, \"dm\"));\n    static assert( hasStaticMember!(C, \"sd\"));\n    static assert(!hasStaticMember!(C, \"g\"));\n    static assert( hasStaticMember!(C, \"fp\"));\n    static assert( hasStaticMember!(C, \"gfp\"));\n    static assert(!hasStaticMember!(C, \"fpm\"));\n    static assert(!hasStaticMember!(C, \"m\"));\n    static assert(!hasStaticMember!(C, \"m2\"));\n    static assert(!hasStaticMember!(C, \"iom\"));\n    static assert( hasStaticMember!(C, \"iosf\"));\n    static assert(!hasStaticMember!(C, \"p\"));\n    static assert( hasStaticMember!(C, \"sp\"));\n\n    alias P = S*;\n    static assert(!hasStaticMember!(P, \"na\"));\n    static assert(!hasStaticMember!(P, \"X\"));\n    static assert(!hasStaticMember!(P, \"Y\"));\n    static assert(!hasStaticMember!(P, \"Y.i\"));\n    static assert(!hasStaticMember!(P, \"S\"));\n    static assert(!hasStaticMember!(P, \"C\"));\n    static assert( hasStaticMember!(P, \"sx\"));\n    static assert( hasStaticMember!(P, \"gx\"));\n    static assert(!hasStaticMember!(P, \"y\"));\n    static assert( hasStaticMember!(P, \"sy\"));\n    static assert( hasStaticMember!(P, \"f\"));\n    static assert( hasStaticMember!(P, \"f2\"));\n    static assert(!hasStaticMember!(P, \"dm\"));\n    static assert( hasStaticMember!(P, \"sd\"));\n    static assert(!hasStaticMember!(P, \"g\"));\n    static assert( hasStaticMember!(P, \"fp\"));\n    static assert( hasStaticMember!(P, \"gfp\"));\n    static assert(!hasStaticMember!(P, \"fpm\"));\n    static assert(!hasStaticMember!(P, \"m\"));\n    static assert(!hasStaticMember!(P, \"m2\"));\n    static assert(!hasStaticMember!(P, \"iom\"));\n    static assert( hasStaticMember!(P, \"iosf\"));\n    static assert(!hasStaticMember!(P, \"p\"));\n    static assert( hasStaticMember!(P, \"sp\"));\n}\n\n/**\nRetrieves the members of an enumerated type `enum E`.\n\nParams:\n    E = An enumerated type. `E` may have duplicated values.\n\nReturns:\n    Static tuple composed of the members of the enumerated type `E`.\n    The members are arranged in the same order as declared in `E`.\n\nNote:\n    An enum can have multiple members which have the same value. If you want\n    to use EnumMembers to e.g. generate switch cases at compile-time,\n    you should use the $(REF NoDuplicates, std,meta) template to avoid\n    generating duplicate switch cases.\n\nNote:\n    Returned values are strictly typed with `E`. Thus, the following code\n    does not work without the explicit cast:\n--------------------\nenum E : int { a, b, c }\nint[] abc = cast(int[]) [ EnumMembers!E ];\n--------------------\n    Cast is not necessary if the type of the variable is inferred. See the\n    example below.\n */\ntemplate EnumMembers(E)\nif (is(E == enum))\n{\n    import std.meta : AliasSeq;\n    // Supply the specified identifier to an constant value.\n    template WithIdentifier(string ident)\n    {\n        static if (ident == \"Symbolize\")\n        {\n            template Symbolize(alias value)\n            {\n                enum Symbolize = value;\n            }\n        }\n        else\n        {\n            mixin(\"template Symbolize(alias \"~ ident ~\")\"\n                 ~\"{\"\n                     ~\"alias Symbolize = \"~ ident ~\";\"\n                 ~\"}\");\n        }\n    }\n\n    template EnumSpecificMembers(names...)\n    {\n        static if (names.length == 1)\n        {\n            alias EnumSpecificMembers = AliasSeq!(WithIdentifier!(names[0])\n                        .Symbolize!(__traits(getMember, E, names[0])));\n        }\n        else static if (names.length > 0)\n        {\n            alias EnumSpecificMembers =\n                AliasSeq!(\n                    WithIdentifier!(names[0])\n                        .Symbolize!(__traits(getMember, E, names[0])),\n                    EnumSpecificMembers!(names[1 .. $/2]),\n                    EnumSpecificMembers!(names[$/2..$])\n                );\n        }\n        else\n        {\n            alias EnumSpecificMembers = AliasSeq!();\n        }\n    }\n\n    alias EnumMembers = EnumSpecificMembers!(__traits(allMembers, E));\n}\n\n/// Create an array of enumerated values\n@safe unittest\n{\n    enum Sqrts : real\n    {\n        one = 1,\n        two = 1.41421,\n        three = 1.73205\n    }\n    auto sqrts = [EnumMembers!Sqrts];\n    assert(sqrts == [Sqrts.one, Sqrts.two, Sqrts.three]);\n}\n\n/**\nA generic function `rank(v)` in the following example uses this\ntemplate for finding a member `e` in an enumerated type `E`.\n */\n@safe unittest\n{\n    // Returns i if e is the i-th enumerator of E.\n    static size_t rank(E)(E e)\n    if (is(E == enum))\n    {\n        static foreach (i, member; EnumMembers!E)\n        {\n            if (e == member)\n                return i;\n        }\n        assert(0, \"Not an enum member\");\n    }\n\n    enum Mode\n    {\n        read = 1,\n        write = 2,\n        map = 4\n    }\n    assert(rank(Mode.read) == 0);\n    assert(rank(Mode.write) == 1);\n    assert(rank(Mode.map) == 2);\n}\n\n@safe unittest\n{\n    enum A { a }\n    static assert([ EnumMembers!A ] == [ A.a ]);\n    enum B { a, b, c, d, e }\n    static assert([ EnumMembers!B ] == [ B.a, B.b, B.c, B.d, B.e ]);\n}\n\n@safe unittest    // typed enums\n{\n    enum A : string { a = \"alpha\", b = \"beta\" }\n    static assert([ EnumMembers!A ] == [ A.a, A.b ]);\n\n    static struct S\n    {\n        int value;\n        int opCmp(S rhs) const nothrow { return value - rhs.value; }\n    }\n    enum B : S { a = S(1), b = S(2), c = S(3) }\n    static assert([ EnumMembers!B ] == [ B.a, B.b, B.c ]);\n}\n\n@safe unittest    // duplicated values\n{\n    enum A\n    {\n        a = 0, b = 0,\n        c = 1, d = 1, e\n    }\n    static assert([ EnumMembers!A ] == [ A.a, A.b, A.c, A.d, A.e ]);\n}\n\n@safe unittest // Bugzilla 14561: huge enums\n{\n    string genEnum()\n    {\n        string result = \"enum TLAs {\";\n        foreach (c0; '0'..'2'+1)\n            foreach (c1; '0'..'9'+1)\n                foreach (c2; '0'..'9'+1)\n                    foreach (c3; '0'..'9'+1)\n        {\n            result ~= '_';\n            result ~= c0;\n            result ~= c1;\n            result ~= c2;\n            result ~= c3;\n            result ~= ',';\n        }\n        result ~= '}';\n        return result;\n    }\n    mixin(genEnum);\n    static assert(EnumMembers!TLAs[0] == TLAs._0000);\n    static assert(EnumMembers!TLAs[$-1] == TLAs._2999);\n}\n\n@safe unittest\n{\n    enum E { member, a = 0, b = 0 }\n    static assert(__traits(identifier, EnumMembers!E[0]) == \"member\");\n    static assert(__traits(identifier, EnumMembers!E[1]) == \"a\");\n    static assert(__traits(identifier, EnumMembers!E[2]) == \"b\");\n}\n\n\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n// Classes and Interfaces\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n/***\n * Get a $(D_PARAM AliasSeq) of the base class and base interfaces of\n * this class or interface. $(D_PARAM BaseTypeTuple!Object) returns\n * the empty type tuple.\n */\ntemplate BaseTypeTuple(A)\n{\n    static if (is(A P == super))\n        alias BaseTypeTuple = P;\n    else\n        static assert(0, \"argument is not a class or interface\");\n}\n\n///\n@safe unittest\n{\n    import std.meta : AliasSeq;\n\n    interface I1 { }\n    interface I2 { }\n    interface I12 : I1, I2 { }\n    static assert(is(BaseTypeTuple!I12 == AliasSeq!(I1, I2)));\n\n    interface I3 : I1 { }\n    interface I123 : I1, I2, I3 { }\n    static assert(is(BaseTypeTuple!I123 == AliasSeq!(I1, I2, I3)));\n}\n\n@safe unittest\n{\n    interface I1 { }\n    interface I2 { }\n    class A { }\n    class C : A, I1, I2 { }\n\n    alias TL = BaseTypeTuple!C;\n    assert(TL.length == 3);\n    assert(is (TL[0] == A));\n    assert(is (TL[1] == I1));\n    assert(is (TL[2] == I2));\n\n    assert(BaseTypeTuple!Object.length == 0);\n}\n\n/**\n * Get a $(D_PARAM AliasSeq) of $(I all) base classes of this class,\n * in decreasing order. Interfaces are not included. $(D_PARAM\n * BaseClassesTuple!Object) yields the empty type tuple.\n */\ntemplate BaseClassesTuple(T)\nif (is(T == class))\n{\n    static if (is(T == Object))\n    {\n        alias BaseClassesTuple = AliasSeq!();\n    }\n    else static if (is(BaseTypeTuple!T[0] == Object))\n    {\n        alias BaseClassesTuple = AliasSeq!Object;\n    }\n    else static if (!is(BaseTypeTuple!T[0] == Object) && !is(BaseTypeTuple!T[0] == class))\n    {\n        alias BaseClassesTuple = AliasSeq!();\n    }\n    else\n    {\n        alias BaseClassesTuple =\n            AliasSeq!(BaseTypeTuple!T[0],\n                       BaseClassesTuple!(BaseTypeTuple!T[0]));\n    }\n}\n\n///\n@safe unittest\n{\n    import std.meta : AliasSeq;\n\n    class C1 { }\n    class C2 : C1 { }\n    class C3 : C2 { }\n    static assert(!BaseClassesTuple!Object.length);\n    static assert(is(BaseClassesTuple!C1 == AliasSeq!(Object)));\n    static assert(is(BaseClassesTuple!C2 == AliasSeq!(C1, Object)));\n    static assert(is(BaseClassesTuple!C3 == AliasSeq!(C2, C1, Object)));\n}\n\n@safe unittest // issue 17276\n{\n    extern (C++) static interface Ext\n    {\n        void someext();\n    }\n\n    extern (C++) static class E : Ext\n    {\n        void someext() {}\n    }\n\n    alias BaseClassesWithNoObject = BaseClassesTuple!E;\n}\n\n@safe unittest\n{\n    struct S { }\n    static assert(!__traits(compiles, BaseClassesTuple!S));\n    interface I { }\n    static assert(!__traits(compiles, BaseClassesTuple!I));\n    class C4 : I { }\n    class C5 : C4, I { }\n    static assert(is(BaseClassesTuple!C5 == AliasSeq!(C4, Object)));\n}\n\n/**\nParams:\n    T = The `class` or `interface` to search.\n\nReturns:\n    $(REF AliasSeq,std,meta) of all interfaces directly or\n    indirectly inherited by this class or interface. Interfaces\n    do not repeat if multiply implemented.\n\n    `InterfacesTuple!Object` yields an empty `AliasSeq`.\n */\ntemplate InterfacesTuple(T)\n{\n    import std.meta : NoDuplicates;\n    template Flatten(H, T...)\n    {\n        static if (T.length)\n        {\n            alias Flatten = AliasSeq!(Flatten!H, Flatten!T);\n        }\n        else\n        {\n            static if (is(H == interface))\n                alias Flatten = AliasSeq!(H, InterfacesTuple!H);\n            else\n                alias Flatten = InterfacesTuple!H;\n        }\n    }\n\n    static if (is(T S == super) && S.length)\n        alias InterfacesTuple = NoDuplicates!(Flatten!S);\n    else\n        alias InterfacesTuple = AliasSeq!();\n}\n\n///\n@safe unittest\n{\n    interface I1 {}\n    interface I2 {}\n    class A : I1, I2 {}\n    class B : A, I1 {}\n    class C : B {}\n\n    alias TL = InterfacesTuple!C;\n    static assert(is(TL[0] == I1) && is(TL[1] == I2));\n}\n\n@safe unittest\n{\n    interface Iaa {}\n    interface Iab {}\n    interface Iba {}\n    interface Ibb {}\n    interface Ia : Iaa, Iab {}\n    interface Ib : Iba, Ibb {}\n    interface I : Ia, Ib {}\n    interface J {}\n    class B2 : J {}\n    class C2 : B2, Ia, Ib {}\n    static assert(is(InterfacesTuple!I ==\n                    AliasSeq!(Ia, Iaa, Iab, Ib, Iba, Ibb)));\n    static assert(is(InterfacesTuple!C2 ==\n                    AliasSeq!(J, Ia, Iaa, Iab, Ib, Iba, Ibb)));\n\n}\n\n/**\n * Get a $(D_PARAM AliasSeq) of $(I all) base classes of $(D_PARAM\n * T), in decreasing order, followed by $(D_PARAM T)'s\n * interfaces. $(D_PARAM TransitiveBaseTypeTuple!Object) yields the\n * empty type tuple.\n */\ntemplate TransitiveBaseTypeTuple(T)\n{\n    static if (is(T == Object))\n        alias TransitiveBaseTypeTuple = AliasSeq!();\n    else\n        alias TransitiveBaseTypeTuple =\n            AliasSeq!(BaseClassesTuple!T, InterfacesTuple!T);\n}\n\n///\n@safe unittest\n{\n    interface J1 {}\n    interface J2 {}\n    class B1 {}\n    class B2 : B1, J1, J2 {}\n    class B3 : B2, J1 {}\n    alias TL = TransitiveBaseTypeTuple!B3;\n    assert(TL.length == 5);\n    assert(is (TL[0] == B2));\n    assert(is (TL[1] == B1));\n    assert(is (TL[2] == Object));\n    assert(is (TL[3] == J1));\n    assert(is (TL[4] == J2));\n\n    assert(TransitiveBaseTypeTuple!Object.length == 0);\n}\n\n\n/**\nReturns a tuple of non-static functions with the name `name` declared in the\nclass or interface `C`.  Covariant duplicates are shrunk into the most\nderived one.\n */\ntemplate MemberFunctionsTuple(C, string name)\nif (is(C == class) || is(C == interface))\n{\n    static if (__traits(hasMember, C, name))\n    {\n        /*\n         * First, collect all overloads in the class hierarchy.\n         */\n        template CollectOverloads(Node)\n        {\n            static if (__traits(hasMember, Node, name) && __traits(compiles, __traits(getMember, Node, name)))\n            {\n                // Get all overloads in sight (not hidden).\n                alias inSight = AliasSeq!(__traits(getVirtualFunctions, Node, name));\n\n                // And collect all overloads in ancestor classes to reveal hidden\n                // methods.  The result may contain duplicates.\n                template walkThru(Parents...)\n                {\n                    static if (Parents.length > 0)\n                        alias walkThru = AliasSeq!(\n                                    CollectOverloads!(Parents[0]),\n                                    walkThru!(Parents[1 .. $])\n                                );\n                    else\n                        alias walkThru = AliasSeq!();\n                }\n\n                static if (is(Node Parents == super))\n                    alias CollectOverloads = AliasSeq!(inSight, walkThru!Parents);\n                else\n                    alias CollectOverloads = AliasSeq!inSight;\n            }\n            else\n                alias CollectOverloads = AliasSeq!(); // no overloads in this hierarchy\n        }\n\n        // duplicates in this tuple will be removed by shrink()\n        alias overloads = CollectOverloads!C;\n\n        // shrinkOne!args[0]    = the most derived one in the covariant siblings of target\n        // shrinkOne!args[1..$] = non-covariant others\n        template shrinkOne(/+ alias target, rest... +/ args...)\n        {\n            import std.meta : AliasSeq;\n            alias target = args[0 .. 1]; // prevent property functions from being evaluated\n            alias rest = args[1 .. $];\n\n            static if (rest.length > 0)\n            {\n                alias Target = FunctionTypeOf!target;\n                alias Rest0 = FunctionTypeOf!(rest[0]);\n\n                static if (isCovariantWith!(Target, Rest0) && isCovariantWith!(Rest0, Target))\n                {\n                    // One of these overrides the other. Choose the one from the most derived parent.\n                    static if (is(AliasSeq!(__traits(parent, target))[0] : AliasSeq!(__traits(parent, rest[0]))[0]))\n                        alias shrinkOne = shrinkOne!(target, rest[1 .. $]);\n                    else\n                        alias shrinkOne = shrinkOne!(rest[0], rest[1 .. $]);\n                }\n                else static if (isCovariantWith!(Target, Rest0))\n                    // target overrides rest[0] -- erase rest[0].\n                    alias shrinkOne = shrinkOne!(target, rest[1 .. $]);\n                else static if (isCovariantWith!(Rest0, Target))\n                    // rest[0] overrides target -- erase target.\n                    alias shrinkOne = shrinkOne!(rest[0], rest[1 .. $]);\n                else\n                    // target and rest[0] are distinct.\n                    alias shrinkOne = AliasSeq!(\n                                shrinkOne!(target, rest[1 .. $]),\n                                rest[0] // keep\n                            );\n            }\n            else\n                alias shrinkOne = AliasSeq!target; // done\n        }\n\n        /*\n         * Now shrink covariant overloads into one.\n         */\n        template shrink(overloads...)\n        {\n            static if (overloads.length > 0)\n            {\n                alias temp = shrinkOne!overloads;\n                alias shrink = AliasSeq!(temp[0], shrink!(temp[1 .. $]));\n            }\n            else\n                alias shrink = AliasSeq!(); // done\n        }\n\n        // done.\n        alias MemberFunctionsTuple = shrink!overloads;\n    }\n    else\n        alias MemberFunctionsTuple = AliasSeq!();\n}\n\n///\n@safe unittest\n{\n    interface I { I foo(); }\n    class B\n    {\n        real foo(real v) { return v; }\n    }\n    class C : B, I\n    {\n        override C foo() { return this; } // covariant overriding of I.foo()\n    }\n    alias foos = MemberFunctionsTuple!(C, \"foo\");\n    static assert(foos.length == 2);\n    static assert(__traits(isSame, foos[0], C.foo));\n    static assert(__traits(isSame, foos[1], B.foo));\n}\n\n@safe unittest // Issue 15920\n{\n    import std.meta : AliasSeq;\n    class A\n    {\n        void f(){}\n        void f(int){}\n    }\n    class B : A\n    {\n        override void f(){}\n        override void f(int){}\n    }\n    alias fs = MemberFunctionsTuple!(B, \"f\");\n    alias bfs = AliasSeq!(__traits(getOverloads, B, \"f\"));\n    assert(__traits(isSame, fs[0], bfs[0]) || __traits(isSame, fs[0], bfs[1]));\n    assert(__traits(isSame, fs[1], bfs[0]) || __traits(isSame, fs[1], bfs[1]));\n}\n\n@safe unittest\n{\n    interface I     { I test(); }\n    interface J : I { J test(); }\n    interface K     { K test(int); }\n    class B : I, K\n    {\n        K test(int) { return this; }\n        B test() { return this; }\n        static void test(string) { }\n    }\n    class C : B, J\n    {\n        override C test() { return this; }\n    }\n    alias test =MemberFunctionsTuple!(C, \"test\");\n    static assert(test.length == 2);\n    static assert(is(FunctionTypeOf!(test[0]) == FunctionTypeOf!(C.test)));\n    static assert(is(FunctionTypeOf!(test[1]) == FunctionTypeOf!(K.test)));\n    alias noexist = MemberFunctionsTuple!(C, \"noexist\");\n    static assert(noexist.length == 0);\n\n    interface L { int prop() @property; }\n    alias prop = MemberFunctionsTuple!(L, \"prop\");\n    static assert(prop.length == 1);\n\n    interface Test_I\n    {\n        void foo();\n        void foo(int);\n        void foo(int, int);\n    }\n    interface Test : Test_I {}\n    alias Test_foo = MemberFunctionsTuple!(Test, \"foo\");\n    static assert(Test_foo.length == 3);\n    static assert(is(typeof(&Test_foo[0]) == void function()));\n    static assert(is(typeof(&Test_foo[2]) == void function(int)));\n    static assert(is(typeof(&Test_foo[1]) == void function(int, int)));\n}\n\n\n/**\nReturns an alias to the template that `T` is an instance of.\nIt will return `void` if a symbol without a template is given.\n */\ntemplate TemplateOf(alias T : Base!Args, alias Base, Args...)\n{\n    alias TemplateOf = Base;\n}\n\n/// ditto\ntemplate TemplateOf(T : Base!Args, alias Base, Args...)\n{\n    alias TemplateOf = Base;\n}\n\n/// ditto\ntemplate TemplateOf(T)\n{\n    alias TemplateOf = void;\n}\n\n///\n@safe unittest\n{\n    struct Foo(T, U) {}\n    static assert(__traits(isSame, TemplateOf!(Foo!(int, real)), Foo));\n}\n\n@safe unittest\n{\n    template Foo1(A) {}\n    template Foo2(A, B) {}\n    template Foo3(alias A) {}\n    template Foo4(string A) {}\n    struct Foo5(A) {}\n    struct Foo6(A, B) {}\n    struct Foo7(alias A) {}\n    template Foo8(A) { template Foo9(B) {} }\n    template Foo10() {}\n\n    static assert(__traits(isSame, TemplateOf!(Foo1!(int)), Foo1));\n    static assert(__traits(isSame, TemplateOf!(Foo2!(int, int)), Foo2));\n    static assert(__traits(isSame, TemplateOf!(Foo3!(123)), Foo3));\n    static assert(__traits(isSame, TemplateOf!(Foo4!(\"123\")), Foo4));\n    static assert(__traits(isSame, TemplateOf!(Foo5!(int)), Foo5));\n    static assert(__traits(isSame, TemplateOf!(Foo6!(int, int)), Foo6));\n    static assert(__traits(isSame, TemplateOf!(Foo7!(123)), Foo7));\n    static assert(__traits(isSame, TemplateOf!(Foo8!(int).Foo9!(real)), Foo8!(int).Foo9));\n    static assert(__traits(isSame, TemplateOf!(Foo10!()), Foo10));\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=18214\n@safe unittest\n{\n    static assert(is(TemplateOf!(int[]) == void));\n    static assert(is(TemplateOf!bool == void));\n}\n\n/**\nReturns a `AliasSeq` of the template arguments used to instantiate `T`.\n */\ntemplate TemplateArgsOf(alias T : Base!Args, alias Base, Args...)\n{\n    alias TemplateArgsOf = Args;\n}\n\n/// ditto\ntemplate TemplateArgsOf(T : Base!Args, alias Base, Args...)\n{\n    alias TemplateArgsOf = Args;\n}\n\n///\n@safe unittest\n{\n    import std.meta : AliasSeq;\n\n    struct Foo(T, U) {}\n    static assert(is(TemplateArgsOf!(Foo!(int, real)) == AliasSeq!(int, real)));\n}\n\n@safe unittest\n{\n    template Foo1(A) {}\n    template Foo2(A, B) {}\n    template Foo3(alias A) {}\n    template Foo4(string A) {}\n    struct Foo5(A) {}\n    struct Foo6(A, B) {}\n    struct Foo7(alias A) {}\n    template Foo8(A) { template Foo9(B) {} }\n    template Foo10() {}\n\n    enum x = 123;\n    enum y = \"123\";\n    static assert(is(TemplateArgsOf!(Foo1!(int)) == AliasSeq!(int)));\n    static assert(is(TemplateArgsOf!(Foo2!(int, int)) == AliasSeq!(int, int)));\n    static assert(__traits(isSame, TemplateArgsOf!(Foo3!(x)), AliasSeq!(x)));\n    static assert(TemplateArgsOf!(Foo4!(y)) == AliasSeq!(y));\n    static assert(is(TemplateArgsOf!(Foo5!(int)) == AliasSeq!(int)));\n    static assert(is(TemplateArgsOf!(Foo6!(int, int)) == AliasSeq!(int, int)));\n    static assert(__traits(isSame, TemplateArgsOf!(Foo7!(x)), AliasSeq!(x)));\n    static assert(is(TemplateArgsOf!(Foo8!(int).Foo9!(real)) == AliasSeq!(real)));\n    static assert(is(TemplateArgsOf!(Foo10!()) == AliasSeq!()));\n}\n\n\nprivate template maxAlignment(U...)\nif (isTypeTuple!U)\n{\n    import std.meta : staticMap;\n    static if (U.length == 0)\n        static assert(0);\n    else static if (U.length == 1)\n        enum maxAlignment = U[0].alignof;\n    else\n    {\n        import std.algorithm.comparison : max;\n        enum maxAlignment = max(staticMap!(.maxAlignment, U));\n    }\n}\n\n\n/**\nReturns class instance alignment.\n */\ntemplate classInstanceAlignment(T)\nif (is(T == class))\n{\n    alias classInstanceAlignment = maxAlignment!(void*, typeof(T.tupleof));\n}\n\n///\n@safe unittest\n{\n    class A { byte b; }\n    class B { long l; }\n\n    // As class instance always has a hidden pointer\n    static assert(classInstanceAlignment!A == (void*).alignof);\n    static assert(classInstanceAlignment!B == long.alignof);\n}\n\n\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n// Type Conversion\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n/**\nGet the type that all types can be implicitly converted to. Useful\ne.g. in figuring out an array type from a bunch of initializing\nvalues. Returns $(D_PARAM void) if passed an empty list, or if the\ntypes have no common type.\n */\ntemplate CommonType(T...)\n{\n    static if (!T.length)\n    {\n        alias CommonType = void;\n    }\n    else static if (T.length == 1)\n    {\n        static if (is(typeof(T[0])))\n        {\n            alias CommonType = typeof(T[0]);\n        }\n        else\n        {\n            alias CommonType = T[0];\n        }\n    }\n    else static if (is(typeof(true ? T[0].init : T[1].init) U))\n    {\n        alias CommonType = CommonType!(U, T[2 .. $]);\n    }\n    else\n        alias CommonType = void;\n}\n\n///\n@safe unittest\n{\n    alias X = CommonType!(int, long, short);\n    assert(is(X == long));\n    alias Y = CommonType!(int, char[], short);\n    assert(is(Y == void));\n}\n\n///\n@safe unittest\n{\n    static assert(is(CommonType!(3) == int));\n    static assert(is(CommonType!(double, 4, float) == double));\n    static assert(is(CommonType!(string, char[]) == const(char)[]));\n    static assert(is(CommonType!(3, 3U) == uint));\n    static assert(is(CommonType!(double, int) == double));\n}\n\n\n/**\nParams:\n    T = The type to check\n\nReturns:\n    An $(REF AliasSeq,std,meta) with all possible target types of an implicit\n    conversion `T`.\n\n    If `T` is a class derived from `Object`, the the result of\n    $(LREF TransitiveBaseTypeTuple) is returned.\n\n    If the type is not a built-in value type or a class derived from\n    `Object`, the an empty $(REF AliasSeq,std,meta) is returned.\n\nNote:\n    The possible targets are computed more conservatively than the\n    language allows, eliminating all dangerous conversions. For example,\n    `ImplicitConversionTargets!double` does not include `float`.\n\nSee_Also:\n    $(LREF isImplicitlyConvertible)\n */\ntemplate ImplicitConversionTargets(T)\n{\n    static if (is(T == bool))\n        alias ImplicitConversionTargets =\n            AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList,\n                       float, double, real, char, wchar, dchar);\n    else static if (is(T == byte))\n        alias ImplicitConversionTargets =\n            AliasSeq!(short, ushort, int, uint, long, ulong, CentTypeList,\n                       float, double, real, char, wchar, dchar);\n    else static if (is(T == ubyte))\n        alias ImplicitConversionTargets =\n            AliasSeq!(short, ushort, int, uint, long, ulong, CentTypeList,\n                       float, double, real, char, wchar, dchar);\n    else static if (is(T == short))\n        alias ImplicitConversionTargets =\n            AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real);\n    else static if (is(T == ushort))\n        alias ImplicitConversionTargets =\n            AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real);\n    else static if (is(T == int))\n        alias ImplicitConversionTargets =\n            AliasSeq!(long, ulong, CentTypeList, float, double, real);\n    else static if (is(T == uint))\n        alias ImplicitConversionTargets =\n            AliasSeq!(long, ulong, CentTypeList, float, double, real);\n    else static if (is(T == long))\n        alias ImplicitConversionTargets = AliasSeq!(float, double, real);\n    else static if (is(T == ulong))\n        alias ImplicitConversionTargets = AliasSeq!(float, double, real);\n    else static if (is(cent) && is(T == cent))\n        alias ImplicitConversionTargets = AliasSeq!(float, double, real);\n    else static if (is(ucent) && is(T == ucent))\n        alias ImplicitConversionTargets = AliasSeq!(float, double, real);\n    else static if (is(T == float))\n        alias ImplicitConversionTargets = AliasSeq!(double, real);\n    else static if (is(T == double))\n        alias ImplicitConversionTargets = AliasSeq!real;\n    else static if (is(T == char))\n        alias ImplicitConversionTargets =\n            AliasSeq!(wchar, dchar, byte, ubyte, short, ushort,\n                       int, uint, long, ulong, CentTypeList, float, double, real);\n    else static if (is(T == wchar))\n        alias ImplicitConversionTargets =\n            AliasSeq!(dchar, short, ushort, int, uint, long, ulong, CentTypeList,\n                       float, double, real);\n    else static if (is(T == dchar))\n        alias ImplicitConversionTargets =\n            AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real);\n    else static if (is(T : typeof(null)))\n        alias ImplicitConversionTargets = AliasSeq!(typeof(null));\n    else static if (is(T : Object))\n        alias ImplicitConversionTargets = TransitiveBaseTypeTuple!(T);\n    else static if (isDynamicArray!T && !is(typeof(T.init[0]) == const))\n    {\n       static if (is(typeof(T.init[0]) == shared))\n           alias ImplicitConversionTargets =\n           AliasSeq!(const(shared(Unqual!(typeof(T.init[0]))))[]);\n       else\n           alias ImplicitConversionTargets =\n           AliasSeq!(const(Unqual!(typeof(T.init[0])))[]);\n    }\n    else static if (is(T : void*))\n        alias ImplicitConversionTargets = AliasSeq!(void*);\n    else\n        alias ImplicitConversionTargets = AliasSeq!();\n}\n\n///\n@safe unittest\n{\n    import std.meta : AliasSeq;\n\n    static assert(is(ImplicitConversionTargets!(ulong) == AliasSeq!(float, double, real)));\n    static assert(is(ImplicitConversionTargets!(int) == AliasSeq!(long, ulong, float, double, real)));\n    static assert(is(ImplicitConversionTargets!(float) == AliasSeq!(double, real)));\n    static assert(is(ImplicitConversionTargets!(double) == AliasSeq!(real)));\n\n    static assert(is(ImplicitConversionTargets!(char) == AliasSeq!(\n        wchar, dchar, byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real\n    )));\n    static assert(is(ImplicitConversionTargets!(wchar) == AliasSeq!(\n        dchar, short, ushort, int, uint, long, ulong, float, double, real\n    )));\n    static assert(is(ImplicitConversionTargets!(dchar) == AliasSeq!(\n        int, uint, long, ulong, float, double, real\n    )));\n\n    static assert(is(ImplicitConversionTargets!(string) == AliasSeq!(const(char)[])));\n    static assert(is(ImplicitConversionTargets!(void*) == AliasSeq!(void*)));\n\n    interface A {}\n    interface B {}\n    class C : A, B {}\n\n    static assert(is(ImplicitConversionTargets!(C) == AliasSeq!(Object, A, B)));\n}\n\n@safe unittest\n{\n    static assert(is(ImplicitConversionTargets!(double)[0] == real));\n    static assert(is(ImplicitConversionTargets!(string)[0] == const(char)[]));\n}\n\n/**\nIs `From` implicitly convertible to `To`?\n */\ntemplate isImplicitlyConvertible(From, To)\n{\n    enum bool isImplicitlyConvertible = is(typeof({\n        void fun(ref From v)\n        {\n            void gun(To) {}\n            gun(v);\n        }\n    }));\n}\n\n///\n@safe unittest\n{\n    static assert( isImplicitlyConvertible!(immutable(char), char));\n    static assert( isImplicitlyConvertible!(const(char), char));\n    static assert( isImplicitlyConvertible!(char, wchar));\n    static assert(!isImplicitlyConvertible!(wchar, char));\n\n    static assert(!isImplicitlyConvertible!(const(ushort), ubyte));\n    static assert(!isImplicitlyConvertible!(const(uint), ubyte));\n    static assert(!isImplicitlyConvertible!(const(ulong), ubyte));\n\n    static assert(!isImplicitlyConvertible!(const(char)[], string));\n    static assert( isImplicitlyConvertible!(string, const(char)[]));\n}\n\n/**\nReturns `true` iff a value of type `Rhs` can be assigned to a variable of\ntype `Lhs`.\n\n`isAssignable` returns whether both an lvalue and rvalue can be assigned.\n\nIf you omit `Rhs`, `isAssignable` will check identity assignable of `Lhs`.\n*/\nenum isAssignable(Lhs, Rhs = Lhs) = isRvalueAssignable!(Lhs, Rhs) && isLvalueAssignable!(Lhs, Rhs);\n\n///\n@safe unittest\n{\n    static assert( isAssignable!(long, int));\n    static assert(!isAssignable!(int, long));\n    static assert( isAssignable!(const(char)[], string));\n    static assert(!isAssignable!(string, char[]));\n\n    // int is assignable to int\n    static assert( isAssignable!int);\n\n    // immutable int is not assignable to immutable int\n    static assert(!isAssignable!(immutable int));\n}\n\n// ditto\nprivate enum isRvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, lvalueOf!Lhs = rvalueOf!Rhs);\n\n// ditto\nprivate enum isLvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, lvalueOf!Lhs = lvalueOf!Rhs);\n\n@safe unittest\n{\n    static assert(!isAssignable!(immutable int, int));\n    static assert( isAssignable!(int, immutable int));\n\n    static assert(!isAssignable!(inout int, int));\n    static assert( isAssignable!(int, inout int));\n    static assert(!isAssignable!(inout int));\n\n    static assert( isAssignable!(shared int, int));\n    static assert( isAssignable!(int, shared int));\n    static assert( isAssignable!(shared int));\n\n    static assert( isAssignable!(void[1], void[1]));\n\n    struct S { @disable this(); this(int n){} }\n    static assert( isAssignable!(S, S));\n\n    struct S2 { this(int n){} }\n    static assert( isAssignable!(S2, S2));\n    static assert(!isAssignable!(S2, int));\n\n    struct S3 { @disable void opAssign(); }\n    static assert( isAssignable!(S3, S3));\n\n    struct S3X { @disable void opAssign(S3X); }\n    static assert(!isAssignable!(S3X, S3X));\n\n    struct S4 { void opAssign(int); }\n    static assert( isAssignable!(S4, S4));\n    static assert( isAssignable!(S4, int));\n    static assert( isAssignable!(S4, immutable int));\n\n    struct S5 { @disable this(); @disable this(this); }\n    struct S6 { void opAssign(in ref S5); }\n    static assert(!isAssignable!(S6, S5));\n    static assert(!isRvalueAssignable!(S6, S5));\n    static assert( isLvalueAssignable!(S6, S5));\n    static assert( isLvalueAssignable!(S6, immutable S5));\n}\n\n\n// Equivalent with TypeStruct::isAssignable in compiler code.\npackage template isBlitAssignable(T)\n{\n    static if (is(OriginalType!T U) && !is(T == U))\n    {\n        enum isBlitAssignable = isBlitAssignable!U;\n    }\n    else static if (isStaticArray!T && is(T == E[n], E, size_t n))\n    // Workaround for issue 11499 : isStaticArray!T should not be necessary.\n    {\n        enum isBlitAssignable = isBlitAssignable!E;\n    }\n    else static if (is(T == struct) || is(T == union))\n    {\n        enum isBlitAssignable = isMutable!T &&\n        {\n            size_t offset = 0;\n            bool assignable = true;\n            foreach (i, F; FieldTypeTuple!T)\n            {\n                static if (i == 0)\n                {\n                }\n                else\n                {\n                    if (T.tupleof[i].offsetof == offset)\n                    {\n                        if (assignable)\n                            continue;\n                    }\n                    else\n                    {\n                        if (!assignable)\n                            return false;\n                    }\n                }\n                assignable = isBlitAssignable!(typeof(T.tupleof[i]));\n                offset = T.tupleof[i].offsetof;\n            }\n            return assignable;\n        }();\n    }\n    else\n        enum isBlitAssignable = isMutable!T;\n}\n\n@safe unittest\n{\n    static assert( isBlitAssignable!int);\n    static assert(!isBlitAssignable!(const int));\n\n    class C{ const int i; }\n    static assert( isBlitAssignable!C);\n\n    struct S1{ int i; }\n    struct S2{ const int i; }\n    static assert( isBlitAssignable!S1);\n    static assert(!isBlitAssignable!S2);\n\n    struct S3X { union {       int x;       int y; } }\n    struct S3Y { union {       int x; const int y; } }\n    struct S3Z { union { const int x; const int y; } }\n    static assert( isBlitAssignable!(S3X));\n    static assert( isBlitAssignable!(S3Y));\n    static assert(!isBlitAssignable!(S3Z));\n    static assert(!isBlitAssignable!(const S3X));\n    static assert(!isBlitAssignable!(inout S3Y));\n    static assert(!isBlitAssignable!(immutable S3Z));\n    static assert( isBlitAssignable!(S3X[3]));\n    static assert( isBlitAssignable!(S3Y[3]));\n    static assert(!isBlitAssignable!(S3Z[3]));\n    enum ES3X : S3X { a = S3X() }\n    enum ES3Y : S3Y { a = S3Y() }\n    enum ES3Z : S3Z { a = S3Z() }\n    static assert( isBlitAssignable!(ES3X));\n    static assert( isBlitAssignable!(ES3Y));\n    static assert(!isBlitAssignable!(ES3Z));\n    static assert(!isBlitAssignable!(const ES3X));\n    static assert(!isBlitAssignable!(inout ES3Y));\n    static assert(!isBlitAssignable!(immutable ES3Z));\n    static assert( isBlitAssignable!(ES3X[3]));\n    static assert( isBlitAssignable!(ES3Y[3]));\n    static assert(!isBlitAssignable!(ES3Z[3]));\n\n    union U1X {       int x;       int y; }\n    union U1Y {       int x; const int y; }\n    union U1Z { const int x; const int y; }\n    static assert( isBlitAssignable!(U1X));\n    static assert( isBlitAssignable!(U1Y));\n    static assert(!isBlitAssignable!(U1Z));\n    static assert(!isBlitAssignable!(const U1X));\n    static assert(!isBlitAssignable!(inout U1Y));\n    static assert(!isBlitAssignable!(immutable U1Z));\n    static assert( isBlitAssignable!(U1X[3]));\n    static assert( isBlitAssignable!(U1Y[3]));\n    static assert(!isBlitAssignable!(U1Z[3]));\n    enum EU1X : U1X { a = U1X() }\n    enum EU1Y : U1Y { a = U1Y() }\n    enum EU1Z : U1Z { a = U1Z() }\n    static assert( isBlitAssignable!(EU1X));\n    static assert( isBlitAssignable!(EU1Y));\n    static assert(!isBlitAssignable!(EU1Z));\n    static assert(!isBlitAssignable!(const EU1X));\n    static assert(!isBlitAssignable!(inout EU1Y));\n    static assert(!isBlitAssignable!(immutable EU1Z));\n    static assert( isBlitAssignable!(EU1X[3]));\n    static assert( isBlitAssignable!(EU1Y[3]));\n    static assert(!isBlitAssignable!(EU1Z[3]));\n\n    struct SA\n    {\n        @property int[3] foo() { return [1,2,3]; }\n        alias foo this;\n        const int x;    // SA is not blit assignable\n    }\n    static assert(!isStaticArray!SA);\n    static assert(!isBlitAssignable!(SA[3]));\n}\n\n\n/*\nWorks like `isImplicitlyConvertible`, except this cares only about storage\nclasses of the arguments.\n */\nprivate template isStorageClassImplicitlyConvertible(From, To)\n{\n    alias Pointify(T) = void*;\n\n    enum isStorageClassImplicitlyConvertible = isImplicitlyConvertible!(\n            ModifyTypePreservingTQ!(Pointify, From),\n            ModifyTypePreservingTQ!(Pointify,   To) );\n}\n\n@safe unittest\n{\n    static assert( isStorageClassImplicitlyConvertible!(          int, const int));\n    static assert( isStorageClassImplicitlyConvertible!(immutable int, const int));\n\n    static assert(!isStorageClassImplicitlyConvertible!(const int,           int));\n    static assert(!isStorageClassImplicitlyConvertible!(const int, immutable int));\n    static assert(!isStorageClassImplicitlyConvertible!(int, shared int));\n    static assert(!isStorageClassImplicitlyConvertible!(shared int, int));\n}\n\n\n/**\nDetermines whether the function type `F` is covariant with `G`, i.e.,\nfunctions of the type `F` can override ones of the type `G`.\n */\ntemplate isCovariantWith(F, G)\nif (is(F == function) && is(G == function) ||\n    is(F == delegate) && is(G == delegate) ||\n    isFunctionPointer!F && isFunctionPointer!G)\n{\n    static if (is(F : G))\n        enum isCovariantWith = true;\n    else\n    {\n        alias Upr = F;\n        alias Lwr = G;\n\n        /*\n         * Check for calling convention: require exact match.\n         */\n        template checkLinkage()\n        {\n            enum ok = functionLinkage!Upr == functionLinkage!Lwr;\n        }\n        /*\n         * Check for variadic parameter: require exact match.\n         */\n        template checkVariadicity()\n        {\n            enum ok = variadicFunctionStyle!Upr == variadicFunctionStyle!Lwr;\n        }\n        /*\n         * Check for function storage class:\n         *  - overrider can have narrower storage class than base\n         */\n        template checkSTC()\n        {\n            // Note the order of arguments.  The convertion order Lwr -> Upr is\n            // correct since Upr should be semantically 'narrower' than Lwr.\n            enum ok = isStorageClassImplicitlyConvertible!(Lwr, Upr);\n        }\n        /*\n         * Check for function attributes:\n         *  - require exact match for ref and @property\n         *  - overrider can add pure and nothrow, but can't remove them\n         *  - @safe and @trusted are covariant with each other, unremovable\n         */\n        template checkAttributes()\n        {\n            alias FA = FunctionAttribute;\n            enum uprAtts = functionAttributes!Upr;\n            enum lwrAtts = functionAttributes!Lwr;\n            //\n            enum wantExact = FA.ref_ | FA.property;\n            enum safety = FA.safe | FA.trusted;\n            enum ok =\n                (  (uprAtts & wantExact)   == (lwrAtts & wantExact)) &&\n                (  (uprAtts & FA.pure_   ) >= (lwrAtts & FA.pure_   )) &&\n                (  (uprAtts & FA.nothrow_) >= (lwrAtts & FA.nothrow_)) &&\n                (!!(uprAtts & safety    )  >= !!(lwrAtts & safety    )) ;\n        }\n        /*\n         * Check for return type: usual implicit convertion.\n         */\n        template checkReturnType()\n        {\n            enum ok = is(ReturnType!Upr : ReturnType!Lwr);\n        }\n        /*\n         * Check for parameters:\n         *  - require exact match for types (cf. bugzilla 3075)\n         *  - require exact match for in, out, ref and lazy\n         *  - overrider can add scope, but can't remove\n         */\n        template checkParameters()\n        {\n            alias STC = ParameterStorageClass;\n            alias UprParams = Parameters!Upr;\n            alias LwrParams = Parameters!Lwr;\n            alias UprPSTCs  = ParameterStorageClassTuple!Upr;\n            alias LwrPSTCs  = ParameterStorageClassTuple!Lwr;\n            //\n            template checkNext(size_t i)\n            {\n                static if (i < UprParams.length)\n                {\n                    enum uprStc = UprPSTCs[i];\n                    enum lwrStc = LwrPSTCs[i];\n                    //\n                    enum wantExact = STC.out_ | STC.ref_ | STC.lazy_ | STC.return_;\n                    enum ok =\n                        ((uprStc & wantExact )  == (lwrStc & wantExact )) &&\n                        ((uprStc & STC.scope_)  >= (lwrStc & STC.scope_)) &&\n                        checkNext!(i + 1).ok;\n                }\n                else\n                    enum ok = true; // done\n            }\n            static if (UprParams.length == LwrParams.length)\n                enum ok = is(UprParams == LwrParams) && checkNext!(0).ok;\n            else\n                enum ok = false;\n        }\n\n        /* run all the checks */\n        enum isCovariantWith =\n            checkLinkage    !().ok &&\n            checkVariadicity!().ok &&\n            checkSTC        !().ok &&\n            checkAttributes !().ok &&\n            checkReturnType !().ok &&\n            checkParameters !().ok ;\n    }\n}\n\n///\n@safe unittest\n{\n    interface I { I clone(); }\n    interface J { J clone(); }\n    class C : I\n    {\n        override C clone()   // covariant overriding of I.clone()\n        {\n            return new C;\n        }\n    }\n\n    // C.clone() can override I.clone(), indeed.\n    static assert(isCovariantWith!(typeof(C.clone), typeof(I.clone)));\n\n    // C.clone() can't override J.clone(); the return type C is not implicitly\n    // convertible to J.\n    static assert(!isCovariantWith!(typeof(C.clone), typeof(J.clone)));\n}\n\n@safe unittest\n{\n    enum bool isCovariantWith(alias f, alias g) = .isCovariantWith!(typeof(f), typeof(g));\n\n    // covariant return type\n    interface I     {}\n    interface J : I {}\n    interface BaseA            {          const(I) test(int); }\n    interface DerivA_1 : BaseA { override const(J) test(int); }\n    interface DerivA_2 : BaseA { override       J  test(int); }\n    static assert( isCovariantWith!(DerivA_1.test, BaseA.test));\n    static assert( isCovariantWith!(DerivA_2.test, BaseA.test));\n    static assert(!isCovariantWith!(BaseA.test, DerivA_1.test));\n    static assert(!isCovariantWith!(BaseA.test, DerivA_2.test));\n    static assert( isCovariantWith!(BaseA.test, BaseA.test));\n    static assert( isCovariantWith!(DerivA_1.test, DerivA_1.test));\n    static assert( isCovariantWith!(DerivA_2.test, DerivA_2.test));\n\n     // function, function pointer and delegate\n     J function() derived_function;\n     I function() base_function;\n     J delegate() derived_delegate;\n     I delegate() base_delegate;\n     static assert(.isCovariantWith!(typeof(derived_function), typeof(base_function)));\n     static assert(.isCovariantWith!(typeof(*derived_function), typeof(*base_function)));\n     static assert(.isCovariantWith!(typeof(derived_delegate), typeof(base_delegate)));\n\n    // scope parameter\n    interface BaseB            {          void test(      int*,       int*); }\n    interface DerivB_1 : BaseB { override void test(scope int*,       int*); }\n    interface DerivB_2 : BaseB { override void test(      int*, scope int*); }\n    interface DerivB_3 : BaseB { override void test(scope int*, scope int*); }\n    static assert( isCovariantWith!(DerivB_1.test, BaseB.test));\n    static assert( isCovariantWith!(DerivB_2.test, BaseB.test));\n    static assert( isCovariantWith!(DerivB_3.test, BaseB.test));\n    static assert(!isCovariantWith!(BaseB.test, DerivB_1.test));\n    static assert(!isCovariantWith!(BaseB.test, DerivB_2.test));\n    static assert(!isCovariantWith!(BaseB.test, DerivB_3.test));\n\n    // function storage class\n    interface BaseC            {          void test()      ; }\n    interface DerivC_1 : BaseC { override void test() const; }\n    static assert( isCovariantWith!(DerivC_1.test, BaseC.test));\n    static assert(!isCovariantWith!(BaseC.test, DerivC_1.test));\n\n    // increasing safety\n    interface BaseE            {          void test()         ; }\n    interface DerivE_1 : BaseE { override void test() @safe   ; }\n    interface DerivE_2 : BaseE { override void test() @trusted; }\n    static assert( isCovariantWith!(DerivE_1.test, BaseE.test));\n    static assert( isCovariantWith!(DerivE_2.test, BaseE.test));\n    static assert(!isCovariantWith!(BaseE.test, DerivE_1.test));\n    static assert(!isCovariantWith!(BaseE.test, DerivE_2.test));\n\n    // @safe and @trusted\n    interface BaseF\n    {\n        void test1() @safe;\n        void test2() @trusted;\n    }\n    interface DerivF : BaseF\n    {\n        override void test1() @trusted;\n        override void test2() @safe;\n    }\n    static assert( isCovariantWith!(DerivF.test1, BaseF.test1));\n    static assert( isCovariantWith!(DerivF.test2, BaseF.test2));\n}\n\n\n// Needed for rvalueOf/lvalueOf because \"inout on return means\n// inout must be on a parameter as well\"\nprivate struct __InoutWorkaroundStruct{}\n\n/**\nCreates an lvalue or rvalue of type `T` for `typeof(...)` and\n`__traits(compiles, ...)` purposes. No actual value is returned.\n\nParams:\n    T = The type to transform\n\nNote: Trying to use returned value will result in a\n\"Symbol Undefined\" error at link time.\n*/\n@property T rvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);\n\n/// ditto\n@property ref T lvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);\n\n// Note: can't put these unittests together as function overloads\n// aren't allowed inside functions.\n///\n@system unittest\n{\n    static int f(int);\n    static assert(is(typeof(f(rvalueOf!int)) == int));\n}\n\n///\n@system unittest\n{\n    static bool f(ref int);\n    static assert(is(typeof(f(lvalueOf!int)) == bool));\n}\n\n@system unittest\n{\n    void needLvalue(T)(ref T);\n    static struct S { }\n    int i;\n    struct Nested { void f() { ++i; } }\n    static foreach (T; AliasSeq!(int, immutable int, inout int, string, S, Nested, Object))\n    {\n        static assert(!__traits(compiles, needLvalue(rvalueOf!T)));\n        static assert( __traits(compiles, needLvalue(lvalueOf!T)));\n        static assert(is(typeof(rvalueOf!T) == T));\n        static assert(is(typeof(lvalueOf!T) == T));\n    }\n\n    static assert(!__traits(compiles, rvalueOf!int = 1));\n    static assert( __traits(compiles, lvalueOf!byte = 127));\n    static assert(!__traits(compiles, lvalueOf!byte = 128));\n}\n\n\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n// SomethingTypeOf\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\nprivate template AliasThisTypeOf(T)\nif (isAggregateType!T)\n{\n    alias members = AliasSeq!(__traits(getAliasThis, T));\n\n    static if (members.length == 1)\n    {\n        alias AliasThisTypeOf = typeof(__traits(getMember, T.init, members[0]));\n    }\n    else\n        static assert(0, T.stringof~\" does not have alias this type\");\n}\n\n/*\n */\ntemplate BooleanTypeOf(T)\n{\n    static if (is(AliasThisTypeOf!T AT) && !is(AT[] == AT))\n        alias X = BooleanTypeOf!AT;\n    else\n        alias X = OriginalType!T;\n\n    static if (is(Unqual!X == bool))\n    {\n        alias BooleanTypeOf = X;\n    }\n    else\n        static assert(0, T.stringof~\" is not boolean type\");\n}\n\n@safe unittest\n{\n    // unexpected failure, maybe dmd type-merging bug\n    static foreach (T; AliasSeq!bool)\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( is(Q!T == BooleanTypeOf!(            Q!T  )));\n            static assert( is(Q!T == BooleanTypeOf!( SubTypeOf!(Q!T) )));\n        }\n\n    static foreach (T; AliasSeq!(void, NumericTypeList, /*ImaginaryTypeList, ComplexTypeList,*/ CharTypeList))\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert(!is(BooleanTypeOf!(            Q!T  )), Q!T.stringof);\n            static assert(!is(BooleanTypeOf!( SubTypeOf!(Q!T) )));\n        }\n}\n\n@safe unittest\n{\n    struct B\n    {\n        bool val;\n        alias val this;\n    }\n    struct S\n    {\n        B b;\n        alias b this;\n    }\n    static assert(is(BooleanTypeOf!B == bool));\n    static assert(is(BooleanTypeOf!S == bool));\n}\n\n/*\n */\ntemplate IntegralTypeOf(T)\n{\n    import std.meta : staticIndexOf;\n    static if (is(AliasThisTypeOf!T AT) && !is(AT[] == AT))\n        alias X = IntegralTypeOf!AT;\n    else\n        alias X = OriginalType!T;\n\n    static if (staticIndexOf!(Unqual!X, IntegralTypeList) >= 0)\n    {\n        alias IntegralTypeOf = X;\n    }\n    else\n        static assert(0, T.stringof~\" is not an integral type\");\n}\n\n@safe unittest\n{\n    static foreach (T; IntegralTypeList)\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( is(Q!T == IntegralTypeOf!(            Q!T  )));\n            static assert( is(Q!T == IntegralTypeOf!( SubTypeOf!(Q!T) )));\n        }\n\n    static foreach (T; AliasSeq!(void, bool, FloatingPointTypeList,\n                /*ImaginaryTypeList, ComplexTypeList,*/ CharTypeList))\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert(!is(IntegralTypeOf!(            Q!T  )));\n            static assert(!is(IntegralTypeOf!( SubTypeOf!(Q!T) )));\n        }\n}\n\n/*\n */\ntemplate FloatingPointTypeOf(T)\n{\n    import std.meta : staticIndexOf;\n    static if (is(AliasThisTypeOf!T AT) && !is(AT[] == AT))\n        alias X = FloatingPointTypeOf!AT;\n    else\n        alias X = OriginalType!T;\n\n    static if (staticIndexOf!(Unqual!X, FloatingPointTypeList) >= 0)\n    {\n        alias FloatingPointTypeOf = X;\n    }\n    else\n        static assert(0, T.stringof~\" is not a floating point type\");\n}\n\n@safe unittest\n{\n    static foreach (T; FloatingPointTypeList)\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( is(Q!T == FloatingPointTypeOf!(            Q!T  )));\n            static assert( is(Q!T == FloatingPointTypeOf!( SubTypeOf!(Q!T) )));\n        }\n\n    static foreach (T; AliasSeq!(void, bool, IntegralTypeList, /*ImaginaryTypeList, ComplexTypeList,*/ CharTypeList))\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert(!is(FloatingPointTypeOf!(            Q!T  )));\n            static assert(!is(FloatingPointTypeOf!( SubTypeOf!(Q!T) )));\n        }\n}\n\n/*\n */\ntemplate NumericTypeOf(T)\n{\n    static if (is(IntegralTypeOf!T X) || is(FloatingPointTypeOf!T X))\n    {\n        alias NumericTypeOf = X;\n    }\n    else\n        static assert(0, T.stringof~\" is not a numeric type\");\n}\n\n@safe unittest\n{\n    static foreach (T; NumericTypeList)\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( is(Q!T == NumericTypeOf!(            Q!T  )));\n            static assert( is(Q!T == NumericTypeOf!( SubTypeOf!(Q!T) )));\n        }\n\n    static foreach (T; AliasSeq!(void, bool, CharTypeList, /*ImaginaryTypeList, ComplexTypeList*/))\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert(!is(NumericTypeOf!(            Q!T  )));\n            static assert(!is(NumericTypeOf!( SubTypeOf!(Q!T) )));\n        }\n}\n\n/*\n */\ntemplate UnsignedTypeOf(T)\n{\n    import std.meta : staticIndexOf;\n    static if (is(IntegralTypeOf!T X) &&\n               staticIndexOf!(Unqual!X, UnsignedIntTypeList) >= 0)\n        alias UnsignedTypeOf = X;\n    else\n        static assert(0, T.stringof~\" is not an unsigned type.\");\n}\n\n/*\n */\ntemplate SignedTypeOf(T)\n{\n    import std.meta : staticIndexOf;\n    static if (is(IntegralTypeOf!T X) &&\n               staticIndexOf!(Unqual!X, SignedIntTypeList) >= 0)\n        alias SignedTypeOf = X;\n    else static if (is(FloatingPointTypeOf!T X))\n        alias SignedTypeOf = X;\n    else\n        static assert(0, T.stringof~\" is not an signed type.\");\n}\n\n/*\n */\ntemplate CharTypeOf(T)\n{\n    import std.meta : staticIndexOf;\n    static if (is(AliasThisTypeOf!T AT) && !is(AT[] == AT))\n        alias X = CharTypeOf!AT;\n    else\n        alias X = OriginalType!T;\n\n    static if (staticIndexOf!(Unqual!X, CharTypeList) >= 0)\n    {\n        alias CharTypeOf = X;\n    }\n    else\n        static assert(0, T.stringof~\" is not a character type\");\n}\n\n@safe unittest\n{\n    static foreach (T; CharTypeList)\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( is(CharTypeOf!(            Q!T  )));\n            static assert( is(CharTypeOf!( SubTypeOf!(Q!T) )));\n        }\n\n    static foreach (T; AliasSeq!(void, bool, NumericTypeList, /*ImaginaryTypeList, ComplexTypeList*/))\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert(!is(CharTypeOf!(            Q!T  )));\n            static assert(!is(CharTypeOf!( SubTypeOf!(Q!T) )));\n        }\n\n    static foreach (T; AliasSeq!(string, wstring, dstring, char[4]))\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert(!is(CharTypeOf!(            Q!T  )));\n            static assert(!is(CharTypeOf!( SubTypeOf!(Q!T) )));\n        }\n}\n\n/*\n */\ntemplate StaticArrayTypeOf(T)\n{\n    static if (is(AliasThisTypeOf!T AT) && !is(AT[] == AT))\n        alias X = StaticArrayTypeOf!AT;\n    else\n        alias X = OriginalType!T;\n\n    static if (is(X : E[n], E, size_t n))\n        alias StaticArrayTypeOf = X;\n    else\n        static assert(0, T.stringof~\" is not a static array type\");\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(bool, NumericTypeList, /*ImaginaryTypeList, ComplexTypeList*/))\n        static foreach (Q; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))\n        {\n            static assert(is( Q!(   T[1] ) == StaticArrayTypeOf!( Q!(              T[1]  ) ) ));\n\n            static foreach (P; TypeQualifierList)\n            { // SubTypeOf cannot have inout type\n                static assert(is( Q!(P!(T[1])) == StaticArrayTypeOf!( Q!(SubTypeOf!(P!(T[1]))) ) ));\n            }\n        }\n\n    static foreach (T; AliasSeq!void)\n        static foreach (Q; AliasSeq!TypeQualifierList)\n        {\n            static assert(is( StaticArrayTypeOf!( Q!(void[1]) ) == Q!(void[1]) ));\n        }\n}\n\n/*\n */\ntemplate DynamicArrayTypeOf(T)\n{\n    static if (is(AliasThisTypeOf!T AT) && !is(AT[] == AT))\n        alias X = DynamicArrayTypeOf!AT;\n    else\n        alias X = OriginalType!T;\n\n    static if (is(Unqual!X : E[], E) && !is(typeof({ enum n = X.length; })))\n    {\n        alias DynamicArrayTypeOf = X;\n    }\n    else\n        static assert(0, T.stringof~\" is not a dynamic array\");\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(/*void, */bool, NumericTypeList, /*ImaginaryTypeList, ComplexTypeList*/))\n        static foreach (Q; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))\n        {\n            static assert(is( Q!T[]  == DynamicArrayTypeOf!( Q!T[] ) ));\n            static assert(is( Q!(T[])  == DynamicArrayTypeOf!( Q!(T[]) ) ));\n\n            static foreach (P; AliasSeq!(MutableOf, ConstOf, ImmutableOf))\n            {\n                static assert(is( Q!(P!T[]) == DynamicArrayTypeOf!( Q!(SubTypeOf!(P!T[])) ) ));\n                static assert(is( Q!(P!(T[])) == DynamicArrayTypeOf!( Q!(SubTypeOf!(P!(T[]))) ) ));\n            }\n        }\n\n    static assert(!is(DynamicArrayTypeOf!(int[3])));\n    static assert(!is(DynamicArrayTypeOf!(void[3])));\n    static assert(!is(DynamicArrayTypeOf!(typeof(null))));\n}\n\n/*\n */\ntemplate ArrayTypeOf(T)\n{\n    static if (is(StaticArrayTypeOf!T X) || is(DynamicArrayTypeOf!T X))\n    {\n        alias ArrayTypeOf = X;\n    }\n    else\n        static assert(0, T.stringof~\" is not an array type\");\n}\n\n/*\nAlways returns the Dynamic Array version.\n */\ntemplate StringTypeOf(T)\n{\n    static if (is(T == typeof(null)))\n    {\n        // It is impossible to determine exact string type from typeof(null) -\n        // it means that StringTypeOf!(typeof(null)) is undefined.\n        // Then this behavior is convenient for template constraint.\n        static assert(0, T.stringof~\" is not a string type\");\n    }\n    else static if (is(T : const char[]) || is(T : const wchar[]) || is(T : const dchar[]))\n    {\n        static if (is(T : U[], U))\n            alias StringTypeOf = U[];\n        else\n            static assert(0);\n    }\n    else\n        static assert(0, T.stringof~\" is not a string type\");\n}\n\n@safe unittest\n{\n    static foreach (T; CharTypeList)\n        static foreach (Q; AliasSeq!(MutableOf, ConstOf, ImmutableOf, InoutOf))\n        {\n            static assert(is(Q!T[] == StringTypeOf!( Q!T[] )));\n\n            static if (!__traits(isSame, Q, InoutOf))\n            {{\n                static assert(is(Q!T[] == StringTypeOf!( SubTypeOf!(Q!T[]) )));\n\n                alias Str = Q!T[];\n                class C(S) { S val;  alias val this; }\n                static assert(is(StringTypeOf!(C!Str) == Str));\n            }}\n        }\n\n    static foreach (T; CharTypeList)\n        static foreach (Q; AliasSeq!(SharedOf, SharedConstOf, SharedInoutOf))\n        {\n            static assert(!is(StringTypeOf!( Q!T[] )));\n        }\n}\n\n@safe unittest\n{\n    static assert(is(StringTypeOf!(char[4]) == char[]));\n}\n\n/*\n */\ntemplate AssocArrayTypeOf(T)\n{\n    static if (is(AliasThisTypeOf!T AT) && !is(AT[] == AT))\n        alias X = AssocArrayTypeOf!AT;\n    else\n        alias X = OriginalType!T;\n\n    static if (is(Unqual!X : V[K], K, V))\n    {\n        alias AssocArrayTypeOf = X;\n    }\n    else\n        static assert(0, T.stringof~\" is not an associative array type\");\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(int/*bool, CharTypeList, NumericTypeList, ImaginaryTypeList, ComplexTypeList*/))\n        static foreach (P; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))\n            static foreach (Q; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))\n                static foreach (R; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))\n                {\n                    static assert(is( P!(Q!T[R!T]) == AssocArrayTypeOf!(            P!(Q!T[R!T])  ) ));\n                }\n\n    static foreach (T; AliasSeq!(int/*bool, CharTypeList, NumericTypeList, ImaginaryTypeList, ComplexTypeList*/))\n        static foreach (O; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))\n            static foreach (P; AliasSeq!TypeQualifierList)\n                static foreach (Q; AliasSeq!TypeQualifierList)\n                    static foreach (R; AliasSeq!TypeQualifierList)\n                    {\n                        static assert(is( O!(P!(Q!T[R!T])) == AssocArrayTypeOf!( O!(SubTypeOf!(P!(Q!T[R!T]))) ) ));\n                    }\n}\n\n/*\n */\ntemplate BuiltinTypeOf(T)\n{\n         static if (is(T : void))               alias BuiltinTypeOf = void;\n    else static if (is(BooleanTypeOf!T X))      alias BuiltinTypeOf = X;\n    else static if (is(IntegralTypeOf!T X))     alias BuiltinTypeOf = X;\n    else static if (is(FloatingPointTypeOf!T X))alias BuiltinTypeOf = X;\n    else static if (is(T : const(ireal)))       alias BuiltinTypeOf = ireal;  //TODO\n    else static if (is(T : const(creal)))       alias BuiltinTypeOf = creal;  //TODO\n    else static if (is(CharTypeOf!T X))         alias BuiltinTypeOf = X;\n    else static if (is(ArrayTypeOf!T X))        alias BuiltinTypeOf = X;\n    else static if (is(AssocArrayTypeOf!T X))   alias BuiltinTypeOf = X;\n    else                                        static assert(0);\n}\n\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n// isSomething\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n/**\n * Detect whether `T` is a built-in boolean type.\n */\nenum bool isBoolean(T) = is(BooleanTypeOf!T) && !isAggregateType!T;\n\n///\n@safe unittest\n{\n    static assert( isBoolean!bool);\n    enum EB : bool { a = true }\n    static assert( isBoolean!EB);\n    static assert(!isBoolean!(SubTypeOf!bool));\n}\n\n@safe unittest\n{\n    static struct S(T)\n    {\n        T t;\n        alias t this;\n    }\n    static assert(!isIntegral!(S!bool));\n}\n\n/**\n * Detect whether `T` is a built-in integral type. Types `bool`,\n * `char`, `wchar`, and `dchar` are not considered integral.\n */\nenum bool isIntegral(T) = is(IntegralTypeOf!T) && !isAggregateType!T;\n\n///\n@safe unittest\n{\n    static assert(\n        isIntegral!byte &&\n        isIntegral!short &&\n        isIntegral!int &&\n        isIntegral!long &&\n        isIntegral!(const(long)) &&\n        isIntegral!(immutable(long))\n    );\n\n    static assert(\n        !isIntegral!bool &&\n        !isIntegral!char &&\n        !isIntegral!double\n    );\n\n    // types which act as integral values do not pass\n    struct S\n    {\n        int val;\n        alias val this;\n    }\n\n    static assert(!isIntegral!S);\n}\n\n@safe unittest\n{\n    static foreach (T; IntegralTypeList)\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( isIntegral!(Q!T));\n            static assert(!isIntegral!(SubTypeOf!(Q!T)));\n        }\n    }\n\n    static assert(!isIntegral!float);\n\n    enum EU : uint { a = 0, b = 1, c = 2 }  // base type is unsigned\n    enum EI : int { a = -1, b = 0, c = 1 }  // base type is signed (bug 7909)\n    static assert(isIntegral!EU &&  isUnsigned!EU && !isSigned!EU);\n    static assert(isIntegral!EI && !isUnsigned!EI &&  isSigned!EI);\n}\n\n/**\n * Detect whether `T` is a built-in floating point type.\n */\nenum bool isFloatingPoint(T) = __traits(isFloating, T) && !(is(Unqual!T == cfloat) ||\n                                                            is(Unqual!T == cdouble) ||\n                                                            is(Unqual!T == creal) ||\n                                                            is(Unqual!T == ifloat) ||\n                                                            is(Unqual!T == idouble) ||\n                                                            is(Unqual!T == ireal));\n\n///\n@safe unittest\n{\n    static assert(\n        isFloatingPoint!float &&\n        isFloatingPoint!double &&\n        isFloatingPoint!real &&\n        isFloatingPoint!(const(real)) &&\n        isFloatingPoint!(immutable(real))\n    );\n\n    static assert(!isFloatingPoint!int);\n\n    // complex and imaginary numbers do not pass\n    static assert(\n        !isFloatingPoint!cfloat &&\n        !isFloatingPoint!ifloat\n    );\n\n    // types which act as floating point values do not pass\n    struct S\n    {\n        float val;\n        alias val this;\n    }\n\n    static assert(!isFloatingPoint!S);\n}\n\n@safe unittest\n{\n    enum EF : real { a = 1.414, b = 1.732, c = 2.236 }\n\n    static foreach (T; AliasSeq!(FloatingPointTypeList, EF))\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( isFloatingPoint!(Q!T));\n            static assert(!isFloatingPoint!(SubTypeOf!(Q!T)));\n        }\n    }\n    static foreach (T; IntegralTypeList)\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert(!isFloatingPoint!(Q!T));\n        }\n    }\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17195\n@safe unittest\n{\n    static assert(!isFloatingPoint!cfloat);\n    static assert(!isFloatingPoint!cdouble);\n    static assert(!isFloatingPoint!creal);\n\n    static assert(!isFloatingPoint!ifloat);\n    static assert(!isFloatingPoint!idouble);\n    static assert(!isFloatingPoint!ireal);\n}\n\n/**\n * Detect whether `T` is a built-in numeric type (integral or floating\n * point).\n */\nenum bool isNumeric(T) = __traits(isArithmetic, T) && !(is(Unqual!T == bool) ||\n                                                        is(Unqual!T == char) ||\n                                                        is(Unqual!T == wchar) ||\n                                                        is(Unqual!T == dchar));\n\n///\n@safe unittest\n{\n    static assert(\n        isNumeric!byte &&\n        isNumeric!short &&\n        isNumeric!int &&\n        isNumeric!long &&\n        isNumeric!float &&\n        isNumeric!double &&\n        isNumeric!real &&\n        isNumeric!(const(real)) &&\n        isNumeric!(immutable(real))\n    );\n\n    static assert(\n        !isNumeric!void &&\n        !isNumeric!bool &&\n        !isNumeric!char &&\n        !isNumeric!wchar &&\n        !isNumeric!dchar\n    );\n\n    // types which act as numeric values do not pass\n    struct S\n    {\n        int val;\n        alias val this;\n    }\n\n    static assert(!isIntegral!S);\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(NumericTypeList))\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( isNumeric!(Q!T));\n            static assert(!isNumeric!(SubTypeOf!(Q!T)));\n        }\n    }\n\n    static struct S(T)\n    {\n        T t;\n        alias t this;\n    }\n    static assert(!isNumeric!(S!int));\n}\n\n/**\n * Detect whether `T` is a scalar type (a built-in numeric, character or\n * boolean type).\n */\nenum bool isScalarType(T) = is(T : real) && !isAggregateType!T;\n\n///\n@safe unittest\n{\n    static assert(!isScalarType!void);\n    static assert( isScalarType!(immutable(byte)));\n    static assert( isScalarType!(immutable(ushort)));\n    static assert( isScalarType!(immutable(int)));\n    static assert( isScalarType!(ulong));\n    static assert( isScalarType!(shared(float)));\n    static assert( isScalarType!(shared(const bool)));\n    static assert( isScalarType!(const(char)));\n    static assert( isScalarType!(wchar));\n    static assert( isScalarType!(const(dchar)));\n    static assert( isScalarType!(const(double)));\n    static assert( isScalarType!(const(real)));\n}\n\n@safe unittest\n{\n    static struct S(T)\n    {\n        T t;\n        alias t this;\n    }\n    static assert(!isScalarType!(S!int));\n}\n\n/**\n * Detect whether `T` is a basic type (scalar type or void).\n */\nenum bool isBasicType(T) = isScalarType!T || is(Unqual!T == void);\n\n///\n@safe unittest\n{\n    static assert(isBasicType!void);\n    static assert(isBasicType!(const(void)));\n    static assert(isBasicType!(shared(void)));\n    static assert(isBasicType!(immutable(void)));\n    static assert(isBasicType!(shared const(void)));\n    static assert(isBasicType!(shared inout(void)));\n    static assert(isBasicType!(shared inout const(void)));\n    static assert(isBasicType!(inout(void)));\n    static assert(isBasicType!(inout const(void)));\n    static assert(isBasicType!(immutable(int)));\n    static assert(isBasicType!(shared(float)));\n    static assert(isBasicType!(shared(const bool)));\n    static assert(isBasicType!(const(dchar)));\n}\n\n/**\n * Detect whether `T` is a built-in unsigned numeric type.\n */\nenum bool isUnsigned(T) = __traits(isUnsigned, T) && !(is(Unqual!T == char) ||\n                                                       is(Unqual!T == wchar) ||\n                                                       is(Unqual!T == dchar) ||\n                                                       is(Unqual!T == bool));\n\n///\n@safe unittest\n{\n    static assert(\n        isUnsigned!uint &&\n        isUnsigned!ulong\n    );\n\n    static assert(\n        !isUnsigned!char &&\n        !isUnsigned!int &&\n        !isUnsigned!long &&\n        !isUnsigned!char &&\n        !isUnsigned!wchar &&\n        !isUnsigned!dchar\n    );\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(UnsignedIntTypeList))\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( isUnsigned!(Q!T));\n            static assert(!isUnsigned!(SubTypeOf!(Q!T)));\n        }\n    }\n\n    static struct S(T)\n    {\n        T t;\n        alias t this;\n    }\n    static assert(!isUnsigned!(S!uint));\n}\n\n/**\n * Detect whether `T` is a built-in signed numeric type.\n */\nenum bool isSigned(T) = __traits(isArithmetic, T) && !__traits(isUnsigned, T);\n\n///\n@safe unittest\n{\n    static assert(\n        isSigned!int &&\n        isSigned!long\n    );\n\n    static assert(\n        !isSigned!uint &&\n        !isSigned!ulong\n    );\n}\n\n@safe unittest\n{\n    enum E { e1 = 0 }\n    static assert(isSigned!E);\n\n    enum Eubyte : ubyte { e1 = 0 }\n    static assert(!isSigned!Eubyte);\n\n    static foreach (T; AliasSeq!(SignedIntTypeList))\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( isSigned!(Q!T));\n            static assert(!isSigned!(SubTypeOf!(Q!T)));\n        }\n    }\n\n    static struct S(T)\n    {\n        T t;\n        alias t this;\n    }\n    static assert(!isSigned!(S!uint));\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=17196\n@safe unittest\n{\n    static assert(isUnsigned!bool == false);\n    static assert(isSigned!bool == false);\n}\n\n/**\n * Detect whether `T` is one of the built-in character types.\n *\n * The built-in char types are any of `char`, `wchar` or `dchar`, with\n * or without qualifiers.\n */\nenum bool isSomeChar(T) = is(CharTypeOf!T) && !isAggregateType!T;\n\n///\n@safe unittest\n{\n    //Char types\n    static assert( isSomeChar!char);\n    static assert( isSomeChar!wchar);\n    static assert( isSomeChar!dchar);\n    static assert( isSomeChar!(typeof('c')));\n    static assert( isSomeChar!(immutable char));\n    static assert( isSomeChar!(const dchar));\n\n    //Non char types\n    static assert(!isSomeChar!int);\n    static assert(!isSomeChar!byte);\n    static assert(!isSomeChar!string);\n    static assert(!isSomeChar!wstring);\n    static assert(!isSomeChar!dstring);\n    static assert(!isSomeChar!(char[4]));\n}\n\n@safe unittest\n{\n    enum EC : char { a = 'x', b = 'y' }\n\n    static foreach (T; AliasSeq!(CharTypeList, EC))\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( isSomeChar!(            Q!T  ));\n            static assert(!isSomeChar!( SubTypeOf!(Q!T) ));\n        }\n    }\n\n    // alias-this types are not allowed\n    static struct S(T)\n    {\n        T t;\n        alias t this;\n    }\n    static assert(!isSomeChar!(S!char));\n}\n\n/**\nDetect whether `T` is one of the built-in string types.\n\nThe built-in string types are `Char[]`, where `Char` is any of `char`,\n`wchar` or `dchar`, with or without qualifiers.\n\nStatic arrays of characters (like `char[80]`) are not considered\nbuilt-in string types.\n */\nenum bool isSomeString(T) = is(StringTypeOf!T) && !isAggregateType!T && !isStaticArray!T && !is(T == enum);\n\n///\n@safe unittest\n{\n    //String types\n    static assert( isSomeString!string);\n    static assert( isSomeString!(wchar[]));\n    static assert( isSomeString!(dchar[]));\n    static assert( isSomeString!(typeof(\"aaa\")));\n    static assert( isSomeString!(const(char)[]));\n\n    //Non string types\n    static assert(!isSomeString!int);\n    static assert(!isSomeString!(int[]));\n    static assert(!isSomeString!(byte[]));\n    static assert(!isSomeString!(typeof(null)));\n    static assert(!isSomeString!(char[4]));\n\n    enum ES : string { a = \"aaa\", b = \"bbb\" }\n    static assert(!isSomeString!ES);\n\n    static struct Stringish\n    {\n        string str;\n        alias str this;\n    }\n    static assert(!isSomeString!Stringish);\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(char[], dchar[], string, wstring, dstring))\n    {\n        static assert( isSomeString!(           T ));\n        static assert(!isSomeString!(SubTypeOf!(T)));\n    }\n}\n\n/**\n * Detect whether type `T` is a narrow string.\n *\n * All arrays that use char, wchar, and their qualified versions are narrow\n * strings. (Those include string and wstring).\n */\nenum bool isNarrowString(T) = isSomeString!T && !is(T : const dchar[]);\n\n///\n@safe unittest\n{\n    static assert(isNarrowString!string);\n    static assert(isNarrowString!wstring);\n    static assert(isNarrowString!(char[]));\n    static assert(isNarrowString!(wchar[]));\n\n    static assert(!isNarrowString!dstring);\n    static assert(!isNarrowString!(dchar[]));\n\n    static assert(!isNarrowString!(typeof(null)));\n    static assert(!isNarrowString!(char[4]));\n\n    enum ES : string { a = \"aaa\", b = \"bbb\" }\n    static assert(!isNarrowString!ES);\n\n    static struct Stringish\n    {\n        string str;\n        alias str this;\n    }\n    static assert(!isNarrowString!Stringish);\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(char[], string, wstring))\n    {\n        static foreach (Q; AliasSeq!(MutableOf, ConstOf, ImmutableOf)/*TypeQualifierList*/)\n        {\n            static assert( isNarrowString!(            Q!T  ));\n            static assert(!isNarrowString!( SubTypeOf!(Q!T) ));\n        }\n    }\n\n    static foreach (T; AliasSeq!(int, int[], byte[], dchar[], dstring, char[4]))\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert(!isNarrowString!(            Q!T  ));\n            static assert(!isNarrowString!( SubTypeOf!(Q!T) ));\n        }\n    }\n}\n\n/**\n * Detects whether `T` is a comparable type. Basic types and structs and\n * classes that implement opCmp are ordering comparable.\n */\nenum bool isOrderingComparable(T) = ifTestable!(T, unaryFun!\"a < a\");\n\n///\n@safe unittest\n{\n    static assert(isOrderingComparable!int);\n    static assert(isOrderingComparable!string);\n    static assert(!isOrderingComparable!creal);\n\n    static struct Foo {}\n    static assert(!isOrderingComparable!Foo);\n\n    static struct Bar\n    {\n        int a;\n        auto opCmp(Bar b1) const { return a - b1.a; }\n    }\n\n    Bar b1 = Bar(5);\n    Bar b2 = Bar(7);\n    assert(isOrderingComparable!Bar && b2 > b1);\n}\n\n/// ditto\nenum bool isEqualityComparable(T) = ifTestable!(T, unaryFun!\"a == a\");\n\n@safe unittest\n{\n    static assert(isEqualityComparable!int);\n    static assert(isEqualityComparable!string);\n    static assert(!isEqualityComparable!void);\n\n    struct Foo {}\n    static assert(isEqualityComparable!Foo);\n\n    struct Bar\n    {\n        int a;\n        auto opEquals(Bar b1) const { return a == b1.a; }\n    }\n\n    Bar b1 = Bar(5);\n    Bar b2 = Bar(5);\n    Bar b3 = Bar(7);\n    static assert(isEqualityComparable!Bar);\n    assert(b1 == b2);\n    assert(b1 != b3);\n}\n\nversion (TestComplex)\ndeprecated\n@safe unittest\n{\n    static assert(isEqualityComparable!creal);\n}\n\n/**\n  $(RED Warning: This trait will be deprecated as soon as it is no longer used\n                 in Phobos. For a function parameter to safely accept a type\n                 that implicitly converts to string as a string, the conversion\n                 needs to happen at the callsite; otherwise, the conversion is\n                 done inside the function, and in many cases, that means that\n                 local memory is sliced (e.g. if a static array is passed to\n                 the function, then it's copied, and the resulting dynamic\n                 array will be a slice of a local variable). So, if the\n                 resulting string escapes the function, the string refers to\n                 invalid memory, and accessing it would mean accessing invalid\n                 memory. As such, the only safe way for a function to accept\n                 types that implicitly convert to string is for the implicit\n                 conversion to be done at the callsite, and that can only occur\n                 if the parameter is explicitly typed as an array, whereas\n                 using isConvertibleToString in a template constraint would\n                 result in the conversion being done inside the function. As\n                 such, isConvertibleToString is inherently unsafe and is going\n                 to be deprecated.)\n\n   Detect whether `T` is a struct, static array, or enum that is implicitly\n   convertible to a string.\n */\ntemplate isConvertibleToString(T)\n{\n    enum isConvertibleToString =\n        (isAggregateType!T || isStaticArray!T || is(T == enum))\n        && is(StringTypeOf!T);\n}\n\n///\n@safe unittest\n{\n    static struct AliasedString\n    {\n        string s;\n        alias s this;\n    }\n\n    enum StringEnum { a = \"foo\" }\n\n    assert(!isConvertibleToString!string);\n    assert(isConvertibleToString!AliasedString);\n    assert(isConvertibleToString!StringEnum);\n    assert(isConvertibleToString!(char[25]));\n    assert(!isConvertibleToString!(char[]));\n}\n\n@safe unittest // Bugzilla 16573\n{\n    enum I : int { foo = 1 }\n    enum S : string { foo = \"foo\" }\n    assert(!isConvertibleToString!I);\n    assert(isConvertibleToString!S);\n}\n\npackage template convertToString(T)\n{\n    static if (isConvertibleToString!T)\n        alias convertToString = StringTypeOf!T;\n    else\n        alias convertToString = T;\n}\n\n/**\n * Detect whether type `T` is a string that will be autodecoded.\n *\n * All arrays that use char, wchar, and their qualified versions are narrow\n * strings. (Those include string and wstring).\n * Aggregates that implicitly cast to narrow strings are included.\n *\n * Params:\n *      T = type to be tested\n *\n * Returns:\n *      true if T represents a string that is subject to autodecoding\n *\n * See Also:\n *      $(LREF isNarrowString)\n */\nenum bool isAutodecodableString(T) = (is(T : const char[]) || is(T : const wchar[])) && !isStaticArray!T;\n\n///\n@safe unittest\n{\n    static struct Stringish\n    {\n        string s;\n        alias s this;\n    }\n    assert(isAutodecodableString!wstring);\n    assert(isAutodecodableString!Stringish);\n    assert(!isAutodecodableString!dstring);\n}\n\n/**\n * Detect whether type `T` is a static array.\n */\nenum bool isStaticArray(T) = __traits(isStaticArray, T);\n\n///\n@safe unittest\n{\n    static assert( isStaticArray!(int[3]));\n    static assert( isStaticArray!(const(int)[5]));\n    static assert( isStaticArray!(const(int)[][5]));\n\n    static assert(!isStaticArray!(const(int)[]));\n    static assert(!isStaticArray!(immutable(int)[]));\n    static assert(!isStaticArray!(const(int)[4][]));\n    static assert(!isStaticArray!(int[]));\n    static assert(!isStaticArray!(int[char]));\n    static assert(!isStaticArray!(int[1][]));\n    static assert(!isStaticArray!(int[int]));\n    static assert(!isStaticArray!int);\n}\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(int[51], int[][2],\n                           char[][int][11], immutable char[13u],\n                           const(real)[1], const(real)[1][1], void[0]))\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( isStaticArray!(            Q!T  ));\n            static assert(!isStaticArray!( SubTypeOf!(Q!T) ));\n        }\n    }\n\n    //enum ESA : int[1] { a = [1], b = [2] }\n    //static assert( isStaticArray!ESA);\n}\n\n/**\n * Detect whether type `T` is a dynamic array.\n */\nenum bool isDynamicArray(T) = is(DynamicArrayTypeOf!T) && !isAggregateType!T;\n\n///\n@safe unittest\n{\n    static assert( isDynamicArray!(int[]));\n    static assert( isDynamicArray!(string));\n    static assert( isDynamicArray!(long[3][]));\n\n    static assert(!isDynamicArray!(int[5]));\n    static assert(!isDynamicArray!(typeof(null)));\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(int[], char[], string, long[3][], double[string][]))\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( isDynamicArray!(            Q!T  ));\n            static assert(!isDynamicArray!( SubTypeOf!(Q!T) ));\n        }\n    }\n}\n\n/**\n * Detect whether type `T` is an array (static or dynamic; for associative\n *  arrays see $(LREF isAssociativeArray)).\n */\nenum bool isArray(T) = isStaticArray!T || isDynamicArray!T;\n\n///\n@safe unittest\n{\n    static assert( isArray!(int[]));\n    static assert( isArray!(int[5]));\n    static assert( isArray!(string));\n\n    static assert(!isArray!uint);\n    static assert(!isArray!(uint[uint]));\n    static assert(!isArray!(typeof(null)));\n}\n\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    static foreach (T; AliasSeq!(int[], int[5], void[]))\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( isArray!(Q!T));\n            static assert(!isArray!(SubTypeOf!(Q!T)));\n        }\n    }\n}\n\n/**\n * Detect whether `T` is an associative array type\n */\nenum bool isAssociativeArray(T) = __traits(isAssociativeArray, T);\n\n@safe unittest\n{\n    struct Foo\n    {\n        @property uint[] keys()   { return null; }\n        @property uint[] values() { return null; }\n    }\n\n    static foreach (T; AliasSeq!(int[int], int[string], immutable(char[5])[int]))\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( isAssociativeArray!(Q!T));\n            static assert(!isAssociativeArray!(SubTypeOf!(Q!T)));\n        }\n    }\n\n    static assert(!isAssociativeArray!Foo);\n    static assert(!isAssociativeArray!int);\n    static assert(!isAssociativeArray!(int[]));\n    static assert(!isAssociativeArray!(typeof(null)));\n\n    //enum EAA : int[int] { a = [1:1], b = [2:2] }\n    //static assert( isAssociativeArray!EAA);\n}\n\n/**\n * Detect whether type `T` is a builtin type.\n */\nenum bool isBuiltinType(T) = is(BuiltinTypeOf!T) && !isAggregateType!T;\n\n///\n@safe unittest\n{\n    class C;\n    union U;\n    struct S;\n    interface I;\n\n    static assert( isBuiltinType!void);\n    static assert( isBuiltinType!string);\n    static assert( isBuiltinType!(int[]));\n    static assert( isBuiltinType!(C[string]));\n    static assert(!isBuiltinType!C);\n    static assert(!isBuiltinType!U);\n    static assert(!isBuiltinType!S);\n    static assert(!isBuiltinType!I);\n    static assert(!isBuiltinType!(void delegate(int)));\n}\n\n/**\n * Detect whether type `T` is a SIMD vector type.\n */\nenum bool isSIMDVector(T) = is(T : __vector(V[N]), V, size_t N);\n\n@safe unittest\n{\n    static if (is(__vector(float[4])))\n    {\n        alias SimdVec = __vector(float[4]);\n        static assert(isSIMDVector!(__vector(float[4])));\n        static assert(isSIMDVector!SimdVec);\n    }\n    static assert(!isSIMDVector!uint);\n    static assert(!isSIMDVector!(float[4]));\n}\n\n/**\n * Detect whether type `T` is a pointer.\n */\nenum bool isPointer(T) = is(T == U*, U) && !isAggregateType!T;\n\n@safe unittest\n{\n    static foreach (T; AliasSeq!(int*, void*, char[]*))\n    {\n        static foreach (Q; TypeQualifierList)\n        {\n            static assert( isPointer!(Q!T));\n            static assert(!isPointer!(SubTypeOf!(Q!T)));\n        }\n    }\n\n    static assert(!isPointer!uint);\n    static assert(!isPointer!(uint[uint]));\n    static assert(!isPointer!(char[]));\n    static assert(!isPointer!(typeof(null)));\n}\n\n/**\nReturns the target type of a pointer.\n*/\nalias PointerTarget(T : T*) = T;\n\n///\n@safe unittest\n{\n    static assert(is(PointerTarget!(int*) == int));\n    static assert(is(PointerTarget!(void*) == void));\n}\n\n/**\n * Detect whether type `T` is an aggregate type.\n */\nenum bool isAggregateType(T) = is(T == struct) || is(T == union) ||\n                               is(T == class) || is(T == interface);\n\n///\n@safe unittest\n{\n    class C;\n    union U;\n    struct S;\n    interface I;\n\n    static assert( isAggregateType!C);\n    static assert( isAggregateType!U);\n    static assert( isAggregateType!S);\n    static assert( isAggregateType!I);\n    static assert(!isAggregateType!void);\n    static assert(!isAggregateType!string);\n    static assert(!isAggregateType!(int[]));\n    static assert(!isAggregateType!(C[string]));\n    static assert(!isAggregateType!(void delegate(int)));\n}\n\n/**\n * Returns `true` if T can be iterated over using a `foreach` loop with\n * a single loop variable of automatically inferred type, regardless of how\n * the `foreach` loop is implemented.  This includes ranges, structs/classes\n * that define `opApply` with a single loop variable, and builtin dynamic,\n * static and associative arrays.\n */\nenum bool isIterable(T) = is(typeof({ foreach (elem; T.init) {} }));\n\n///\n@safe unittest\n{\n    struct OpApply\n    {\n        int opApply(scope int delegate(ref uint) dg) { assert(0); }\n    }\n\n    struct Range\n    {\n        @property uint front() { assert(0); }\n        void popFront() { assert(0); }\n        enum bool empty = false;\n    }\n\n    static assert( isIterable!(uint[]));\n    static assert( isIterable!OpApply);\n    static assert( isIterable!(uint[string]));\n    static assert( isIterable!Range);\n\n    static assert(!isIterable!uint);\n}\n\n/**\n * Returns true if T is not const or immutable.  Note that isMutable is true for\n * string, or immutable(char)[], because the 'head' is mutable.\n */\nenum bool isMutable(T) = !is(T == const) && !is(T == immutable) && !is(T == inout);\n\n///\n@safe unittest\n{\n    static assert( isMutable!int);\n    static assert( isMutable!string);\n    static assert( isMutable!(shared int));\n    static assert( isMutable!(shared const(int)[]));\n\n    static assert(!isMutable!(const int));\n    static assert(!isMutable!(inout int));\n    static assert(!isMutable!(shared(const int)));\n    static assert(!isMutable!(shared(inout int)));\n    static assert(!isMutable!(immutable string));\n}\n\n/**\n * Returns true if T is an instance of the template S.\n */\nenum bool isInstanceOf(alias S, T) = is(T == S!Args, Args...);\n/// ditto\ntemplate isInstanceOf(alias S, alias T)\n{\n    enum impl(alias T : S!Args, Args...) = true;\n    enum impl(alias T) = false;\n    enum isInstanceOf = impl!T;\n}\n\n///\n@safe unittest\n{\n    static struct Foo(T...) { }\n    static struct Bar(T...) { }\n    static struct Doo(T) { }\n    static struct ABC(int x) { }\n    static void fun(T)() { }\n    template templ(T) { }\n\n    static assert(isInstanceOf!(Foo, Foo!int));\n    static assert(!isInstanceOf!(Foo, Bar!int));\n    static assert(!isInstanceOf!(Foo, int));\n    static assert(isInstanceOf!(Doo, Doo!int));\n    static assert(isInstanceOf!(ABC, ABC!1));\n    static assert(!isInstanceOf!(Foo, Foo));\n    static assert(isInstanceOf!(fun, fun!int));\n    static assert(isInstanceOf!(templ, templ!int));\n}\n\n/**\n * To use `isInstanceOf` to check the identity of a template while inside of said\n * template, use $(LREF TemplateOf).\n */\n@safe unittest\n{\n    static struct A(T = void)\n    {\n        // doesn't work as expected, only accepts A when T = void\n        void func(B)(B b) if (isInstanceOf!(A, B)) {}\n\n        // correct behavior\n        void method(B)(B b) if (isInstanceOf!(TemplateOf!(A), B)) {}\n    }\n\n    A!(void) a1;\n    A!(void) a2;\n    A!(int) a3;\n\n    static assert(!__traits(compiles, a1.func(a3)));\n    static assert( __traits(compiles, a1.method(a2)));\n    static assert( __traits(compiles, a1.method(a3)));\n}\n\n@safe unittest\n{\n    static void fun1(T)() { }\n    static void fun2(T)() { }\n    template templ1(T) { }\n    template templ2(T) { }\n\n    static assert(!isInstanceOf!(fun1, fun2!int));\n    static assert(!isInstanceOf!(templ1, templ2!int));\n}\n\n/**\n * Check whether the tuple T is an expression tuple.\n * An expression tuple only contains expressions.\n *\n * See_Also: $(LREF isTypeTuple).\n */\ntemplate isExpressions(T...)\n{\n    static foreach (Ti; T)\n    {\n        static if (!is(typeof(isExpressions) == bool) && // not yet defined\n                   (is(Ti) || !__traits(compiles, { auto ex = Ti; })))\n        {\n            enum isExpressions = false;\n        }\n    }\n    static if (!is(typeof(isExpressions) == bool)) // if not yet defined\n    {\n        enum isExpressions = true;\n    }\n}\n\n///\n@safe unittest\n{\n    static assert(isExpressions!(1, 2.0, \"a\"));\n    static assert(!isExpressions!(int, double, string));\n    static assert(!isExpressions!(int, 2.0, \"a\"));\n}\n\n/**\n * Alternate name for $(LREF isExpressions), kept for legacy compatibility.\n */\n\nalias isExpressionTuple = isExpressions;\n\n@safe unittest\n{\n    void foo();\n    static int bar() { return 42; }\n    immutable aa = [ 1: -1 ];\n    alias myint = int;\n\n    static assert( isExpressionTuple!(42));\n    static assert( isExpressionTuple!aa);\n    static assert( isExpressionTuple!(\"cattywampus\", 2.7, aa));\n    static assert( isExpressionTuple!(bar()));\n\n    static assert(!isExpressionTuple!isExpressionTuple);\n    static assert(!isExpressionTuple!foo);\n    static assert(!isExpressionTuple!( (a) { } ));\n    static assert(!isExpressionTuple!int);\n    static assert(!isExpressionTuple!myint);\n}\n\n\n/**\n * Check whether the tuple `T` is a type tuple.\n * A type tuple only contains types.\n *\n * See_Also: $(LREF isExpressions).\n */\ntemplate isTypeTuple(T...)\n{\n    static if (T.length >= 2)\n        enum bool isTypeTuple = isTypeTuple!(T[0 .. $/2]) && isTypeTuple!(T[$/2 .. $]);\n    else static if (T.length == 1)\n        enum bool isTypeTuple = is(T[0]);\n    else\n        enum bool isTypeTuple = true; // default\n}\n\n///\n@safe unittest\n{\n    static assert(isTypeTuple!(int, float, string));\n    static assert(!isTypeTuple!(1, 2.0, \"a\"));\n    static assert(!isTypeTuple!(1, double, string));\n}\n\n@safe unittest\n{\n    class C {}\n    void func(int) {}\n    auto c = new C;\n    enum CONST = 42;\n\n    static assert( isTypeTuple!int);\n    static assert( isTypeTuple!string);\n    static assert( isTypeTuple!C);\n    static assert( isTypeTuple!(typeof(func)));\n    static assert( isTypeTuple!(int, char, double));\n\n    static assert(!isTypeTuple!c);\n    static assert(!isTypeTuple!isTypeTuple);\n    static assert(!isTypeTuple!CONST);\n}\n\n\n/**\nDetect whether symbol or type `T` is a function pointer.\n */\ntemplate isFunctionPointer(T...)\nif (T.length == 1)\n{\n    static if (is(T[0] U) || is(typeof(T[0]) U))\n    {\n        static if (is(U F : F*) && is(F == function))\n            enum bool isFunctionPointer = true;\n        else\n            enum bool isFunctionPointer = false;\n    }\n    else\n        enum bool isFunctionPointer = false;\n}\n\n///\n@safe unittest\n{\n    static void foo() {}\n    void bar() {}\n\n    auto fpfoo = &foo;\n    static assert( isFunctionPointer!fpfoo);\n    static assert( isFunctionPointer!(void function()));\n\n    auto dgbar = &bar;\n    static assert(!isFunctionPointer!dgbar);\n    static assert(!isFunctionPointer!(void delegate()));\n    static assert(!isFunctionPointer!foo);\n    static assert(!isFunctionPointer!bar);\n\n    static assert( isFunctionPointer!((int a) {}));\n}\n\n/**\nDetect whether symbol or type `T` is a delegate.\n*/\ntemplate isDelegate(T...)\nif (T.length == 1)\n{\n    static if (is(typeof(& T[0]) U : U*) && is(typeof(& T[0]) U == delegate))\n    {\n        // T is a (nested) function symbol.\n        enum bool isDelegate = true;\n    }\n    else static if (is(T[0] W) || is(typeof(T[0]) W))\n    {\n        // T is an expression or a type.  Take the type of it and examine.\n        enum bool isDelegate = is(W == delegate);\n    }\n    else\n        enum bool isDelegate = false;\n}\n\n///\n@safe unittest\n{\n    static void sfunc() { }\n    int x;\n    void func() { x++; }\n\n    int delegate() dg;\n    assert(isDelegate!dg);\n    assert(isDelegate!(int delegate()));\n    assert(isDelegate!(typeof(&func)));\n\n    int function() fp;\n    assert(!isDelegate!fp);\n    assert(!isDelegate!(int function()));\n    assert(!isDelegate!(typeof(&sfunc)));\n}\n\n/**\nDetect whether symbol or type `T` is a function, a function pointer or a delegate.\n\nParams:\n    T = The type to check\nReturns:\n    A `bool`\n */\ntemplate isSomeFunction(T...)\nif (T.length == 1)\n{\n    static if (is(typeof(& T[0]) U : U*) && is(U == function) || is(typeof(& T[0]) U == delegate))\n    {\n        // T is a (nested) function symbol.\n        enum bool isSomeFunction = true;\n    }\n    else static if (is(T[0] W) || is(typeof(T[0]) W))\n    {\n        // T is an expression or a type.  Take the type of it and examine.\n        static if (is(W F : F*) && is(F == function))\n            enum bool isSomeFunction = true; // function pointer\n        else\n            enum bool isSomeFunction = is(W == function) || is(W == delegate);\n    }\n    else\n        enum bool isSomeFunction = false;\n}\n\n///\n@safe unittest\n{\n    static real func(ref int) { return 0; }\n    static void prop() @property { }\n    class C\n    {\n        real method(ref int) { return 0; }\n        real prop() @property { return 0; }\n    }\n    auto c = new C;\n    auto fp = &func;\n    auto dg = &c.method;\n    real val;\n\n    static assert( isSomeFunction!func);\n    static assert( isSomeFunction!prop);\n    static assert( isSomeFunction!(C.method));\n    static assert( isSomeFunction!(C.prop));\n    static assert( isSomeFunction!(c.prop));\n    static assert( isSomeFunction!(c.prop));\n    static assert( isSomeFunction!fp);\n    static assert( isSomeFunction!dg);\n\n    static assert(!isSomeFunction!int);\n    static assert(!isSomeFunction!val);\n}\n\n@safe unittest\n{\n    void nestedFunc() { }\n    void nestedProp() @property { }\n    static assert(isSomeFunction!nestedFunc);\n    static assert(isSomeFunction!nestedProp);\n    static assert(isSomeFunction!(real function(ref int)));\n    static assert(isSomeFunction!(real delegate(ref int)));\n    static assert(isSomeFunction!((int a) { return a; }));\n    static assert(!isSomeFunction!isSomeFunction);\n}\n\n/**\nDetect whether `T` is a callable object, which can be called with the\nfunction call operator `$(LPAREN)...$(RPAREN)`.\n */\ntemplate isCallable(T...)\nif (T.length == 1)\n{\n    static if (is(typeof(& T[0].opCall) == delegate))\n        // T is a object which has a member function opCall().\n        enum bool isCallable = true;\n    else static if (is(typeof(& T[0].opCall) V : V*) && is(V == function))\n        // T is a type which has a static member function opCall().\n        enum bool isCallable = true;\n    else\n        enum bool isCallable = isSomeFunction!T;\n}\n\n///\n@safe unittest\n{\n    interface I { real value() @property; }\n    struct S { static int opCall(int) { return 0; } }\n    class C { int opCall(int) { return 0; } }\n    auto c = new C;\n\n    static assert( isCallable!c);\n    static assert( isCallable!S);\n    static assert( isCallable!(c.opCall));\n    static assert( isCallable!(I.value));\n    static assert( isCallable!((int a) { return a; }));\n\n    static assert(!isCallable!I);\n}\n\n\n/**\nDetect whether `T` is an abstract function.\n\nParams:\n    T = The type to check\nReturns:\n    A `bool`\n */\ntemplate isAbstractFunction(T...)\nif (T.length == 1)\n{\n    enum bool isAbstractFunction = __traits(isAbstractFunction, T[0]);\n}\n\n///\n@safe unittest\n{\n    struct S { void foo() { } }\n    class C { void foo() { } }\n    class AC { abstract void foo(); }\n    static assert(!isAbstractFunction!(int));\n    static assert(!isAbstractFunction!(S.foo));\n    static assert(!isAbstractFunction!(C.foo));\n    static assert( isAbstractFunction!(AC.foo));\n}\n\n/**\n * Detect whether `T` is a final function.\n */\ntemplate isFinalFunction(T...)\nif (T.length == 1)\n{\n    enum bool isFinalFunction = __traits(isFinalFunction, T[0]);\n}\n\n///\n@safe unittest\n{\n    struct S { void bar() { } }\n    final class FC { void foo(); }\n    class C\n    {\n        void bar() { }\n        final void foo();\n    }\n    static assert(!isFinalFunction!(int));\n    static assert(!isFinalFunction!(S.bar));\n    static assert( isFinalFunction!(FC.foo));\n    static assert(!isFinalFunction!(C.bar));\n    static assert( isFinalFunction!(C.foo));\n}\n\n/**\nDetermines if `f` is a function that requires a context pointer.\n\nParams:\n    f = The type to check\nReturns\n    A `bool`\n*/\ntemplate isNestedFunction(alias f)\n{\n    enum isNestedFunction = __traits(isNested, f) && isSomeFunction!(f);\n}\n\n///\n@safe unittest\n{\n    static void f() {}\n    static void fun()\n    {\n        int i;\n        int f() { return i; }\n\n        static assert(isNestedFunction!(f));\n    }\n\n    static assert(!isNestedFunction!f);\n}\n\n// issue 18669\n@safe unittest\n{\n    static class Outer\n    {\n        class Inner\n        {\n        }\n    }\n    int i;\n    struct SS\n    {\n        int bar() { return i; }\n    }\n    static assert(!isNestedFunction!(Outer.Inner));\n    static assert(!isNestedFunction!(SS));\n}\n\n/**\n * Detect whether `T` is an abstract class.\n */\ntemplate isAbstractClass(T...)\nif (T.length == 1)\n{\n    enum bool isAbstractClass = __traits(isAbstractClass, T[0]);\n}\n\n///\n@safe unittest\n{\n    struct S { }\n    class C { }\n    abstract class AC { }\n    static assert(!isAbstractClass!S);\n    static assert(!isAbstractClass!C);\n    static assert( isAbstractClass!AC);\n    C c;\n    static assert(!isAbstractClass!c);\n    AC ac;\n    static assert( isAbstractClass!ac);\n}\n\n/**\n * Detect whether `T` is a final class.\n */\ntemplate isFinalClass(T...)\nif (T.length == 1)\n{\n    enum bool isFinalClass = __traits(isFinalClass, T[0]);\n}\n\n///\n@safe unittest\n{\n    class C { }\n    abstract class AC { }\n    final class FC1 : C { }\n    final class FC2 { }\n    static assert(!isFinalClass!C);\n    static assert(!isFinalClass!AC);\n    static assert( isFinalClass!FC1);\n    static assert( isFinalClass!FC2);\n    C c;\n    static assert(!isFinalClass!c);\n    FC1 fc1;\n    static assert( isFinalClass!fc1);\n}\n\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n// General Types\n//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n/**\nRemoves all qualifiers, if any, from type `T`.\n */\ntemplate Unqual(T)\n{\n    version (none) // Error: recursive alias declaration @@@BUG1308@@@\n    {\n             static if (is(T U ==     const U)) alias Unqual = Unqual!U;\n        else static if (is(T U == immutable U)) alias Unqual = Unqual!U;\n        else static if (is(T U ==     inout U)) alias Unqual = Unqual!U;\n        else static if (is(T U ==    shared U)) alias Unqual = Unqual!U;\n        else                                    alias Unqual =        T;\n    }\n    else // workaround\n    {\n             static if (is(T U ==          immutable U)) alias Unqual = U;\n        else static if (is(T U == shared inout const U)) alias Unqual = U;\n        else static if (is(T U == shared inout       U)) alias Unqual = U;\n        else static if (is(T U == shared       const U)) alias Unqual = U;\n        else static if (is(T U == shared             U)) alias Unqual = U;\n        else static if (is(T U ==        inout const U)) alias Unqual = U;\n        else static if (is(T U ==        inout       U)) alias Unqual = U;\n        else static if (is(T U ==              const U)) alias Unqual = U;\n        else                                             alias Unqual = T;\n    }\n}\n\n///\n@safe unittest\n{\n    static assert(is(Unqual!int == int));\n    static assert(is(Unqual!(const int) == int));\n    static assert(is(Unqual!(immutable int) == int));\n    static assert(is(Unqual!(shared int) == int));\n    static assert(is(Unqual!(shared(const int)) == int));\n}\n\n@safe unittest\n{\n    static assert(is(Unqual!(                   int) == int));\n    static assert(is(Unqual!(             const int) == int));\n    static assert(is(Unqual!(       inout       int) == int));\n    static assert(is(Unqual!(       inout const int) == int));\n    static assert(is(Unqual!(shared             int) == int));\n    static assert(is(Unqual!(shared       const int) == int));\n    static assert(is(Unqual!(shared inout       int) == int));\n    static assert(is(Unqual!(shared inout const int) == int));\n    static assert(is(Unqual!(         immutable int) == int));\n\n    alias ImmIntArr = immutable(int[]);\n    static assert(is(Unqual!ImmIntArr == immutable(int)[]));\n}\n\n// [For internal use]\npackage template ModifyTypePreservingTQ(alias Modifier, T)\n{\n         static if (is(T U ==          immutable U)) alias ModifyTypePreservingTQ =          immutable Modifier!U;\n    else static if (is(T U == shared inout const U)) alias ModifyTypePreservingTQ = shared inout const Modifier!U;\n    else static if (is(T U == shared inout       U)) alias ModifyTypePreservingTQ = shared inout       Modifier!U;\n    else static if (is(T U == shared       const U)) alias ModifyTypePreservingTQ = shared       const Modifier!U;\n    else static if (is(T U == shared             U)) alias ModifyTypePreservingTQ = shared             Modifier!U;\n    else static if (is(T U ==        inout const U)) alias ModifyTypePreservingTQ =        inout const Modifier!U;\n    else static if (is(T U ==        inout       U)) alias ModifyTypePreservingTQ =              inout Modifier!U;\n    else static if (is(T U ==              const U)) alias ModifyTypePreservingTQ =              const Modifier!U;\n    else                                             alias ModifyTypePreservingTQ =                    Modifier!T;\n}\n\n@safe unittest\n{\n    alias Intify(T) = int;\n    static assert(is(ModifyTypePreservingTQ!(Intify,                    real) ==                    int));\n    static assert(is(ModifyTypePreservingTQ!(Intify,              const real) ==              const int));\n    static assert(is(ModifyTypePreservingTQ!(Intify,        inout       real) ==        inout       int));\n    static assert(is(ModifyTypePreservingTQ!(Intify,        inout const real) ==        inout const int));\n    static assert(is(ModifyTypePreservingTQ!(Intify, shared             real) == shared             int));\n    static assert(is(ModifyTypePreservingTQ!(Intify, shared       const real) == shared       const int));\n    static assert(is(ModifyTypePreservingTQ!(Intify, shared inout       real) == shared inout       int));\n    static assert(is(ModifyTypePreservingTQ!(Intify, shared inout const real) == shared inout const int));\n    static assert(is(ModifyTypePreservingTQ!(Intify,          immutable real) ==          immutable int));\n}\n\n/**\n * Copies type qualifiers from `FromType` to `ToType`.\n *\n * Supported type qualifiers:\n * $(UL\n *     $(LI `const`)\n *     $(LI `inout`)\n *     $(LI `immutable`)\n *     $(LI `shared`)\n * )\n */\ntemplate CopyTypeQualifiers(FromType, ToType)\n{\n    alias T(U) = ToType;\n    alias CopyTypeQualifiers = ModifyTypePreservingTQ!(T, FromType);\n}\n\n///\n@safe unittest\n{\n    static assert(is(CopyTypeQualifiers!(inout const real, int) == inout const int));\n}\n\n@safe unittest\n{\n    static assert(is(CopyTypeQualifiers!(                   real, int) ==                    int));\n    static assert(is(CopyTypeQualifiers!(             const real, int) ==              const int));\n    static assert(is(CopyTypeQualifiers!(       inout       real, int) ==        inout       int));\n    static assert(is(CopyTypeQualifiers!(       inout const real, int) ==        inout const int));\n    static assert(is(CopyTypeQualifiers!(shared             real, int) == shared             int));\n    static assert(is(CopyTypeQualifiers!(shared       const real, int) == shared       const int));\n    static assert(is(CopyTypeQualifiers!(shared inout       real, int) == shared inout       int));\n    static assert(is(CopyTypeQualifiers!(shared inout const real, int) == shared inout const int));\n    static assert(is(CopyTypeQualifiers!(         immutable real, int) ==          immutable int));\n}\n\n/**\nReturns the type of `Target` with the \"constness\" of `Source`. A type's $(B constness)\nrefers to whether it is `const`, `immutable`, or `inout`. If `source` has no constness, the\nreturned type will be the same as `Target`.\n*/\ntemplate CopyConstness(FromType, ToType)\n{\n    alias Unshared(T) = T;\n    alias Unshared(T: shared U, U) = U;\n\n    alias CopyConstness = Unshared!(CopyTypeQualifiers!(FromType, ToType));\n}\n\n///\n@safe unittest\n{\n    const(int) i;\n    CopyConstness!(typeof(i), float) f;\n    assert( is(typeof(f) == const float));\n\n    CopyConstness!(char, uint) u;\n    assert( is(typeof(u) == uint));\n\n    //The 'shared' qualifier will not be copied\n    assert(!is(CopyConstness!(shared bool, int) == shared int));\n\n    //But the constness will be\n    assert( is(CopyConstness!(shared const real, double) == const double));\n\n    //Careful, const(int)[] is a mutable array of const(int)\n    alias MutT = CopyConstness!(const(int)[], int);\n    assert(!is(MutT == const(int)));\n\n    //Okay, const(int[]) applies to array and contained ints\n    alias CstT = CopyConstness!(const(int[]), int);\n    assert( is(CstT == const(int)));\n}\n\n@safe unittest\n{\n    struct Test\n    {\n        void method1() {}\n        void method2() const {}\n        void method3() immutable {}\n    }\n\n    assert(is(CopyConstness!(typeof(Test.method1), real) == real));\n\n    assert(is(CopyConstness!(typeof(Test.method2), byte) == const(byte)));\n\n    assert(is(CopyConstness!(typeof(Test.method3), string) == immutable(string)));\n}\n\n@safe unittest\n{\n    assert(is(CopyConstness!(inout(int)[], int[]) == int[]));\n    assert(is(CopyConstness!(inout(int[]), int[]) == inout(int[])));\n}\n\n@safe unittest\n{\n    static assert(is(CopyConstness!(                   int, real) ==             real));\n    static assert(is(CopyConstness!(const              int, real) ==       const real));\n    static assert(is(CopyConstness!(inout              int, real) ==       inout real));\n    static assert(is(CopyConstness!(inout const        int, real) == inout const real));\n    static assert(is(CopyConstness!(shared             int, real) ==             real));\n    static assert(is(CopyConstness!(shared const       int, real) ==       const real));\n    static assert(is(CopyConstness!(shared inout       int, real) == inout       real));\n    static assert(is(CopyConstness!(shared inout const int, real) == inout const real));\n    static assert(is(CopyConstness!(immutable          int, real) ==   immutable real));\n}\n\n/**\nReturns the inferred type of the loop variable when a variable of type T\nis iterated over using a `foreach` loop with a single loop variable and\nautomatically inferred return type.  Note that this may not be the same as\n`std.range.ElementType!Range` in the case of narrow strings, or if T\nhas both opApply and a range interface.\n*/\ntemplate ForeachType(T)\n{\n    alias ForeachType = ReturnType!(typeof(\n    (inout int x = 0)\n    {\n        foreach (elem; T.init)\n        {\n            return elem;\n        }\n        assert(0);\n    }));\n}\n\n///\n@safe unittest\n{\n    static assert(is(ForeachType!(uint[]) == uint));\n    static assert(is(ForeachType!string == immutable(char)));\n    static assert(is(ForeachType!(string[string]) == string));\n    static assert(is(ForeachType!(inout(int)[]) == inout(int)));\n}\n\n\n/**\n * Strips off all `enum`s from type `T`.\n */\ntemplate OriginalType(T)\n{\n    template Impl(T)\n    {\n        static if (is(T U == enum)) alias Impl = OriginalType!U;\n        else                        alias Impl =              T;\n    }\n\n    alias OriginalType = ModifyTypePreservingTQ!(Impl, T);\n}\n\n///\n@safe unittest\n{\n    enum E : real { a = 0 } // NOTE: explicit initialization to 0 required during Enum init deprecation cycle\n    enum F : E    { a = E.a }\n    alias G = const(F);\n    static assert(is(OriginalType!E == real));\n    static assert(is(OriginalType!F == real));\n    static assert(is(OriginalType!G == const real));\n}\n\n/**\n * Get the Key type of an Associative Array.\n */\nalias KeyType(V : V[K], K) = K;\n\n///\n@safe unittest\n{\n    alias Hash = int[string];\n    static assert(is(KeyType!Hash == string));\n    static assert(is(ValueType!Hash == int));\n    KeyType!Hash str = \"a\"; // str is declared as string\n    ValueType!Hash num = 1; // num is declared as int\n}\n\n/**\n * Get the Value type of an Associative Array.\n */\nalias ValueType(V : V[K], K) = V;\n\n///\n@safe unittest\n{\n    alias Hash = int[string];\n    static assert(is(KeyType!Hash == string));\n    static assert(is(ValueType!Hash == int));\n    KeyType!Hash str = \"a\"; // str is declared as string\n    ValueType!Hash num = 1; // num is declared as int\n}\n\n/**\nParams:\n    T = A built in integral or vector type.\n\nReturns:\n    The corresponding unsigned numeric type for `T` with the\n    same type qualifiers.\n\n    If `T` is not a integral or vector, a compile-time error is given.\n */\ntemplate Unsigned(T)\n{\n    template Impl(T)\n    {\n        static if (is(T : __vector(V[N]), V, size_t N))\n            alias Impl = __vector(Impl!V[N]);\n        else static if (isUnsigned!T)\n            alias Impl = T;\n        else static if (isSigned!T && !isFloatingPoint!T)\n        {\n            static if (is(T == byte )) alias Impl = ubyte;\n            static if (is(T == short)) alias Impl = ushort;\n            static if (is(T == int  )) alias Impl = uint;\n            static if (is(T == long )) alias Impl = ulong;\n            static if (is(ucent) && is(T == cent )) alias Impl = ucent;\n        }\n        else\n            static assert(false, \"Type \" ~ T.stringof ~\n                                 \" does not have an Unsigned counterpart\");\n    }\n\n    alias Unsigned = ModifyTypePreservingTQ!(Impl, OriginalType!T);\n}\n\n///\n@safe unittest\n{\n    static assert(is(Unsigned!(int) == uint));\n    static assert(is(Unsigned!(long) == ulong));\n    static assert(is(Unsigned!(const short) == const ushort));\n    static assert(is(Unsigned!(immutable byte) == immutable ubyte));\n    static assert(is(Unsigned!(inout int) == inout uint));\n}\n\n\n/// Unsigned types are forwarded\n@safe unittest\n{\n    static assert(is(Unsigned!(uint) == uint));\n    static assert(is(Unsigned!(const uint) == const uint));\n\n    static assert(is(Unsigned!(ubyte) == ubyte));\n    static assert(is(Unsigned!(immutable uint) == immutable uint));\n}\n\n@safe unittest\n{\n    alias U1 = Unsigned!int;\n    alias U2 = Unsigned!(const(int));\n    alias U3 = Unsigned!(immutable(int));\n    static assert(is(U1 == uint));\n    static assert(is(U2 == const(uint)));\n    static assert(is(U3 == immutable(uint)));\n    static if (is(__vector(int[4])) && is(__vector(uint[4])))\n    {\n        alias UV1 = Unsigned!(__vector(int[4]));\n        alias UV2 = Unsigned!(const(__vector(int[4])));\n        static assert(is(UV1 == __vector(uint[4])));\n        static assert(is(UV2 == const(__vector(uint[4]))));\n    }\n    //struct S {}\n    //alias U2 = Unsigned!S;\n    //alias U3 = Unsigned!double;\n    static if (is(ucent))\n    {\n        alias U4 = Unsigned!cent;\n        alias U5 = Unsigned!(const(cent));\n        alias U6 = Unsigned!(immutable(cent));\n        static assert(is(U4 == ucent));\n        static assert(is(U5 == const(ucent)));\n        static assert(is(U6 == immutable(ucent)));\n    }\n}\n\n/**\nReturns the largest type, i.e. T such that T.sizeof is the largest.  If more\nthan one type is of the same size, the leftmost argument of these in will be\nreturned.\n*/\ntemplate Largest(T...)\nif (T.length >= 1)\n{\n    static if (T.length == 1)\n    {\n        alias Largest = T[0];\n    }\n    else static if (T.length == 2)\n    {\n        static if (T[0].sizeof >= T[1].sizeof)\n        {\n            alias Largest = T[0];\n        }\n        else\n        {\n            alias Largest = T[1];\n        }\n    }\n    else\n    {\n        alias Largest = Largest!(Largest!(T[0 .. $/2]), Largest!(T[$/2 .. $]));\n    }\n}\n\n///\n@safe unittest\n{\n    static assert(is(Largest!(uint, ubyte, ushort, real) == real));\n    static assert(is(Largest!(ulong, double) == ulong));\n    static assert(is(Largest!(double, ulong) == double));\n    static assert(is(Largest!(uint, byte, double, short) == double));\n    static if (is(ucent))\n        static assert(is(Largest!(uint, ubyte, ucent, ushort) == ucent));\n}\n\n/**\nReturns the corresponding signed type for T. T must be a numeric integral type,\notherwise a compile-time error occurs.\n */\ntemplate Signed(T)\n{\n    template Impl(T)\n    {\n        static if (is(T : __vector(V[N]), V, size_t N))\n            alias Impl = __vector(Impl!V[N]);\n        else static if (isSigned!T)\n            alias Impl = T;\n        else static if (isUnsigned!T)\n        {\n            static if (is(T == ubyte )) alias Impl = byte;\n            static if (is(T == ushort)) alias Impl = short;\n            static if (is(T == uint  )) alias Impl = int;\n            static if (is(T == ulong )) alias Impl = long;\n            static if (is(ucent) && is(T == ucent )) alias Impl = cent;\n        }\n        else\n            static assert(false, \"Type \" ~ T.stringof ~\n                                 \" does not have an Signed counterpart\");\n    }\n\n    alias Signed = ModifyTypePreservingTQ!(Impl, OriginalType!T);\n}\n\n///\n@safe unittest\n{\n    alias S1 = Signed!uint;\n    static assert(is(S1 == int));\n    alias S2 = Signed!(const(uint));\n    static assert(is(S2 == const(int)));\n    alias S3 = Signed!(immutable(uint));\n    static assert(is(S3 == immutable(int)));\n    static if (is(ucent))\n    {\n        alias S4 = Signed!ucent;\n        static assert(is(S4 == cent));\n    }\n}\n\n@safe unittest\n{\n    static assert(is(Signed!float == float));\n    static if (is(__vector(int[4])) && is(__vector(uint[4])))\n    {\n        alias SV1 = Signed!(__vector(uint[4]));\n        alias SV2 = Signed!(const(__vector(uint[4])));\n        static assert(is(SV1 == __vector(int[4])));\n        static assert(is(SV2 == const(__vector(int[4]))));\n    }\n}\n\n\n/**\nReturns the most negative value of the numeric type T.\n*/\ntemplate mostNegative(T)\nif (isNumeric!T || isSomeChar!T || isBoolean!T)\n{\n    static if (is(typeof(T.min_normal)))\n        enum mostNegative = -T.max;\n    else static if (T.min == 0)\n        enum byte mostNegative = 0;\n    else\n        enum mostNegative = T.min;\n}\n\n///\n@safe unittest\n{\n    static assert(mostNegative!float == -float.max);\n    static assert(mostNegative!double == -double.max);\n    static assert(mostNegative!real == -real.max);\n    static assert(mostNegative!bool == false);\n}\n\n///\n@safe unittest\n{\n    import std.meta : AliasSeq;\n\n    static foreach (T; AliasSeq!(bool, byte, short, int, long))\n        static assert(mostNegative!T == T.min);\n\n    static foreach (T; AliasSeq!(ubyte, ushort, uint, ulong, char, wchar, dchar))\n        static assert(mostNegative!T == 0);\n}\n\n/**\nGet the type that a scalar type `T` will $(LINK2 $(ROOT_DIR)spec/type.html#integer-promotions, promote)\nto in multi-term arithmetic expressions.\n*/\ntemplate Promoted(T)\nif (isScalarType!T)\n{\n    alias Promoted = CopyTypeQualifiers!(T, typeof(T.init + T.init));\n}\n\n///\n@safe unittest\n{\n    ubyte a = 3, b = 5;\n    static assert(is(typeof(a * b) == Promoted!ubyte));\n    static assert(is(Promoted!ubyte == int));\n\n    static assert(is(Promoted!(shared(bool)) == shared(int)));\n    static assert(is(Promoted!(const(int)) == const(int)));\n    static assert(is(Promoted!double == double));\n}\n\n@safe unittest\n{\n    // promote to int:\n    static foreach (T; AliasSeq!(bool, byte, ubyte, short, ushort, char, wchar))\n    {\n        static assert(is(Promoted!T == int));\n        static assert(is(Promoted!(shared(const T)) == shared(const int)));\n    }\n\n    // already promoted:\n    static foreach (T; AliasSeq!(int, uint, long, ulong, float, double, real))\n    {\n        static assert(is(Promoted!T == T));\n        static assert(is(Promoted!(immutable(T)) == immutable(T)));\n    }\n}\n\n//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n// Misc.\n//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n/**\nReturns the mangled name of symbol or type `sth`.\n\n`mangledName` is the same as builtin `.mangleof` property, but\nmight be more convenient in generic code, e.g. as a template argument\nwhen invoking staticMap.\n */\ntemplate mangledName(sth...)\nif (sth.length == 1)\n{\n    enum string mangledName = sth[0].mangleof;\n}\n\n///\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    alias TL = staticMap!(mangledName, int, const int, immutable int);\n    static assert(TL == AliasSeq!(\"i\", \"xi\", \"yi\"));\n}\n\nversion (unittest) private void freeFunc(string);\n\n@safe unittest\n{\n    class C { int value() @property { return 0; } }\n    static assert(mangledName!int == int.mangleof);\n    static assert(mangledName!C == C.mangleof);\n    static assert(mangledName!(C.value) == C.value.mangleof);\n    static assert(mangledName!(C.value)[$ - 12 .. $] == \"5valueMFNdZi\");\n    static assert(mangledName!mangledName == \"3std6traits11mangledName\");\n    static assert(mangledName!freeFunc == \"_D3std6traits8freeFuncFAyaZv\");\n    int x;\n  static if (is(typeof({ return x; }) : int delegate() pure))   // issue 9148\n    static assert(mangledName!((int a) { return a+x; }) == \"DFNaNbNiNfiZi\");  // pure nothrow @safe @nogc\n  else\n    static assert(mangledName!((int a) { return a+x; }) == \"DFNbNiNfiZi\");  // nothrow @safe @nnogc\n}\n\n@system unittest\n{\n    // @system due to demangle\n    // Test for bug 5718\n    import std.demangle : demangle;\n    int foo;\n    auto foo_demangled = demangle(mangledName!foo);\n    assert(foo_demangled[0 .. 4] == \"int \" && foo_demangled[$-3 .. $] == \"foo\",\n        foo_demangled);\n\n    void bar();\n    auto bar_demangled = demangle(mangledName!bar);\n    assert(bar_demangled[0 .. 5] == \"void \" && bar_demangled[$-5 .. $] == \"bar()\");\n}\n\n\n\n// XXX Select & select should go to another module. (functional or algorithm?)\n\n/**\nAliases itself to `T[0]` if the boolean `condition` is `true`\nand to `T[1]` otherwise.\n */\ntemplate Select(bool condition, T...)\nif (T.length == 2)\n{\n    import std.meta : Alias;\n    alias Select = Alias!(T[!condition]);\n}\n\n///\n@safe unittest\n{\n    // can select types\n    static assert(is(Select!(true, int, long) == int));\n    static assert(is(Select!(false, int, long) == long));\n    static struct Foo {}\n    static assert(is(Select!(false, const(int), const(Foo)) == const(Foo)));\n\n    // can select symbols\n    int a = 1;\n    int b = 2;\n    alias selA = Select!(true, a, b);\n    alias selB = Select!(false, a, b);\n    assert(selA == 1);\n    assert(selB == 2);\n\n    // can select (compile-time) expressions\n    enum val = Select!(false, -4, 9 - 6);\n    static assert(val == 3);\n}\n\n/**\nSelect one of two functions to run via template parameter.\n\nParams:\n    cond = A `bool` which determines which function is run\n    a = The first function\n    b = The second function\n\nReturns:\n    `a` without evaluating `b` if `cond` is `true`.\n    Otherwise, returns `b` without evaluating `a`.\n */\nA select(bool cond : true, A, B)(A a, lazy B b) { return a; }\n/// Ditto\nB select(bool cond : false, A, B)(lazy A a, B b) { return b; }\n\n///\n@safe unittest\n{\n    real run() { return 0; }\n    int fail() { assert(0); }\n    auto a = select!true(run(), fail());\n    auto b = select!false(fail(), run());\n    static assert(is(typeof(a) == real));\n    static assert(is(typeof(b) == real));\n}\n\n/++\n    Determine if a symbol has a given\n    $(DDSUBLINK spec/attribute, uda, user-defined attribute).\n\n    See_Also:\n        $(LREF getUDAs)\n  +/\ntemplate hasUDA(alias symbol, alias attribute)\n{\n    enum hasUDA = getUDAs!(symbol, attribute).length != 0;\n}\n\n///\n@safe unittest\n{\n    enum E;\n    struct S {}\n\n    @(\"alpha\") int a;\n    static assert(hasUDA!(a, \"alpha\"));\n    static assert(!hasUDA!(a, S));\n    static assert(!hasUDA!(a, E));\n\n    @(E) int b;\n    static assert(!hasUDA!(b, \"alpha\"));\n    static assert(!hasUDA!(b, S));\n    static assert(hasUDA!(b, E));\n\n    @E int c;\n    static assert(!hasUDA!(c, \"alpha\"));\n    static assert(!hasUDA!(c, S));\n    static assert(hasUDA!(c, E));\n\n    @(S, E) int d;\n    static assert(!hasUDA!(d, \"alpha\"));\n    static assert(hasUDA!(d, S));\n    static assert(hasUDA!(d, E));\n\n    @S int e;\n    static assert(!hasUDA!(e, \"alpha\"));\n    static assert(hasUDA!(e, S));\n    static assert(!hasUDA!(e, S()));\n    static assert(!hasUDA!(e, E));\n\n    @S() int f;\n    static assert(!hasUDA!(f, \"alpha\"));\n    static assert(hasUDA!(f, S));\n    static assert(hasUDA!(f, S()));\n    static assert(!hasUDA!(f, E));\n\n    @(S, E, \"alpha\") int g;\n    static assert(hasUDA!(g, \"alpha\"));\n    static assert(hasUDA!(g, S));\n    static assert(hasUDA!(g, E));\n\n    @(100) int h;\n    static assert(hasUDA!(h, 100));\n\n    struct Named { string name; }\n\n    @Named(\"abc\") int i;\n    static assert(hasUDA!(i, Named));\n    static assert(hasUDA!(i, Named(\"abc\")));\n    static assert(!hasUDA!(i, Named(\"def\")));\n\n    struct AttrT(T)\n    {\n        string name;\n        T value;\n    }\n\n    @AttrT!int(\"answer\", 42) int j;\n    static assert(hasUDA!(j, AttrT));\n    static assert(hasUDA!(j, AttrT!int));\n    static assert(!hasUDA!(j, AttrT!string));\n\n    @AttrT!string(\"hello\", \"world\") int k;\n    static assert(hasUDA!(k, AttrT));\n    static assert(!hasUDA!(k, AttrT!int));\n    static assert(hasUDA!(k, AttrT!string));\n\n    struct FuncAttr(alias f) { alias func = f; }\n    static int fourtyTwo() { return 42; }\n    static size_t getLen(string s) { return s.length; }\n\n    @FuncAttr!getLen int l;\n    static assert(hasUDA!(l, FuncAttr));\n    static assert(!hasUDA!(l, FuncAttr!fourtyTwo));\n    static assert(hasUDA!(l, FuncAttr!getLen));\n    static assert(!hasUDA!(l, FuncAttr!fourtyTwo()));\n    static assert(!hasUDA!(l, FuncAttr!getLen()));\n\n    @FuncAttr!getLen() int m;\n    static assert(hasUDA!(m, FuncAttr));\n    static assert(!hasUDA!(m, FuncAttr!fourtyTwo));\n    static assert(hasUDA!(m, FuncAttr!getLen));\n    static assert(!hasUDA!(m, FuncAttr!fourtyTwo()));\n    static assert(hasUDA!(m, FuncAttr!getLen()));\n}\n\n/++\n    Gets the matching $(DDSUBLINK spec/attribute, uda, user-defined attributes)\n    from the given symbol.\n\n    If the UDA is a type, then any UDAs of the same type on the symbol will\n    match. If the UDA is a template for a type, then any UDA which is an\n    instantiation of that template will match. And if the UDA is a value,\n    then any UDAs on the symbol which are equal to that value will match.\n\n    See_Also:\n        $(LREF hasUDA)\n  +/\ntemplate getUDAs(alias symbol, alias attribute)\n{\n    import std.meta : Filter;\n\n    alias getUDAs = Filter!(isDesiredUDA!attribute, __traits(getAttributes, symbol));\n}\n\n///\n@safe unittest\n{\n    struct Attr\n    {\n        string name;\n        int value;\n    }\n\n    @Attr(\"Answer\", 42) int a;\n    static assert(getUDAs!(a, Attr).length == 1);\n    static assert(getUDAs!(a, Attr)[0].name == \"Answer\");\n    static assert(getUDAs!(a, Attr)[0].value == 42);\n\n    @(Attr(\"Answer\", 42), \"string\", 9999) int b;\n    static assert(getUDAs!(b, Attr).length == 1);\n    static assert(getUDAs!(b, Attr)[0].name == \"Answer\");\n    static assert(getUDAs!(b, Attr)[0].value == 42);\n\n    @Attr(\"Answer\", 42) @Attr(\"Pi\", 3) int c;\n    static assert(getUDAs!(c, Attr).length == 2);\n    static assert(getUDAs!(c, Attr)[0].name == \"Answer\");\n    static assert(getUDAs!(c, Attr)[0].value == 42);\n    static assert(getUDAs!(c, Attr)[1].name == \"Pi\");\n    static assert(getUDAs!(c, Attr)[1].value == 3);\n\n    static assert(getUDAs!(c, Attr(\"Answer\", 42)).length == 1);\n    static assert(getUDAs!(c, Attr(\"Answer\", 42))[0].name == \"Answer\");\n    static assert(getUDAs!(c, Attr(\"Answer\", 42))[0].value == 42);\n\n    static assert(getUDAs!(c, Attr(\"Answer\", 99)).length == 0);\n\n    struct AttrT(T)\n    {\n        string name;\n        T value;\n    }\n\n    @AttrT!uint(\"Answer\", 42) @AttrT!int(\"Pi\", 3) @AttrT int d;\n    static assert(getUDAs!(d, AttrT).length == 2);\n    static assert(getUDAs!(d, AttrT)[0].name == \"Answer\");\n    static assert(getUDAs!(d, AttrT)[0].value == 42);\n    static assert(getUDAs!(d, AttrT)[1].name == \"Pi\");\n    static assert(getUDAs!(d, AttrT)[1].value == 3);\n\n    static assert(getUDAs!(d, AttrT!uint).length == 1);\n    static assert(getUDAs!(d, AttrT!uint)[0].name == \"Answer\");\n    static assert(getUDAs!(d, AttrT!uint)[0].value == 42);\n\n    static assert(getUDAs!(d, AttrT!int).length == 1);\n    static assert(getUDAs!(d, AttrT!int)[0].name == \"Pi\");\n    static assert(getUDAs!(d, AttrT!int)[0].value == 3);\n\n    struct SimpleAttr {}\n\n    @SimpleAttr int e;\n    static assert(getUDAs!(e, SimpleAttr).length == 1);\n    static assert(is(getUDAs!(e, SimpleAttr)[0] == SimpleAttr));\n\n    @SimpleAttr() int f;\n    static assert(getUDAs!(f, SimpleAttr).length == 1);\n    static assert(is(typeof(getUDAs!(f, SimpleAttr)[0]) == SimpleAttr));\n\n    struct FuncAttr(alias f) { alias func = f; }\n    static int add42(int v) { return v + 42; }\n    static string concat(string l, string r) { return l ~ r; }\n\n    @FuncAttr!add42 int g;\n    static assert(getUDAs!(g, FuncAttr).length == 1);\n    static assert(getUDAs!(g, FuncAttr)[0].func(5) == 47);\n\n    static assert(getUDAs!(g, FuncAttr!add42).length == 1);\n    static assert(getUDAs!(g, FuncAttr!add42)[0].func(5) == 47);\n\n    static assert(getUDAs!(g, FuncAttr!add42()).length == 0);\n\n    static assert(getUDAs!(g, FuncAttr!concat).length == 0);\n    static assert(getUDAs!(g, FuncAttr!concat()).length == 0);\n\n    @FuncAttr!add42() int h;\n    static assert(getUDAs!(h, FuncAttr).length == 1);\n    static assert(getUDAs!(h, FuncAttr)[0].func(5) == 47);\n\n    static assert(getUDAs!(h, FuncAttr!add42).length == 1);\n    static assert(getUDAs!(h, FuncAttr!add42)[0].func(5) == 47);\n\n    static assert(getUDAs!(h, FuncAttr!add42()).length == 1);\n    static assert(getUDAs!(h, FuncAttr!add42())[0].func(5) == 47);\n\n    static assert(getUDAs!(h, FuncAttr!concat).length == 0);\n    static assert(getUDAs!(h, FuncAttr!concat()).length == 0);\n\n    @(\"alpha\") @(42) int i;\n    static assert(getUDAs!(i, \"alpha\").length == 1);\n    static assert(getUDAs!(i, \"alpha\")[0] == \"alpha\");\n\n    static assert(getUDAs!(i, 42).length == 1);\n    static assert(getUDAs!(i, 42)[0] == 42);\n\n    static assert(getUDAs!(i, 'c').length == 0);\n}\n\nprivate template isDesiredUDA(alias attribute)\n{\n    template isDesiredUDA(alias toCheck)\n    {\n        static if (is(typeof(attribute)) && !__traits(isTemplate, attribute))\n        {\n            static if (__traits(compiles, toCheck == attribute))\n                enum isDesiredUDA = toCheck == attribute;\n            else\n                enum isDesiredUDA = false;\n        }\n        else static if (is(typeof(toCheck)))\n        {\n            static if (__traits(isTemplate, attribute))\n                enum isDesiredUDA =  isInstanceOf!(attribute, typeof(toCheck));\n            else\n                enum isDesiredUDA = is(typeof(toCheck) == attribute);\n        }\n        else static if (__traits(isTemplate, attribute))\n            enum isDesiredUDA = isInstanceOf!(attribute, toCheck);\n        else\n            enum isDesiredUDA = is(toCheck == attribute);\n    }\n}\n\n/**\nParams:\n    symbol = The aggregate type to search\n    attribute = The user-defined attribute to search for\n\nReturns:\n    All symbols within `symbol` that have the given UDA `attribute`.\n\nNote:\n    This is not recursive; it will not search for symbols within symbols such as\n    nested structs or unions.\n */\ntemplate getSymbolsByUDA(alias symbol, alias attribute)\n{\n    alias membersWithUDA = getSymbolsByUDAImpl!(symbol, attribute, __traits(allMembers, symbol));\n\n    // if the symbol itself has the UDA, tack it on to the front of the list\n    static if (hasUDA!(symbol, attribute))\n        alias getSymbolsByUDA = AliasSeq!(symbol, membersWithUDA);\n    else\n        alias getSymbolsByUDA = membersWithUDA;\n}\n\n///\n@safe unittest\n{\n    enum Attr;\n    struct A\n    {\n        @Attr int a;\n        int b;\n    }\n\n    static assert(getSymbolsByUDA!(A, Attr).length == 1);\n    static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[0], Attr));\n}\n\n///\n@safe unittest\n{\n    enum Attr;\n\n    static struct A\n    {\n        @Attr int a;\n        int b;\n        @Attr void doStuff() {}\n        void doOtherStuff() {}\n        static struct Inner\n        {\n            // Not found by getSymbolsByUDA\n            @Attr int c;\n        }\n    }\n\n    // Finds both variables and functions with the attribute, but\n    // doesn't include the variables and functions without it.\n    static assert(getSymbolsByUDA!(A, Attr).length == 2);\n    // Can access attributes on the symbols returned by getSymbolsByUDA.\n    static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[0], Attr));\n    static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[1], Attr));\n}\n\n/// Finds multiple attributes\n@safe unittest\n{\n    static struct UDA { string name; }\n\n    static struct B\n    {\n        @UDA(\"X\")\n        int x;\n        @UDA(\"Y\")\n        int y;\n        @(100)\n        int z;\n    }\n\n    // Finds both UDA attributes.\n    static assert(getSymbolsByUDA!(B, UDA).length == 2);\n    // Finds one `100` attribute.\n    static assert(getSymbolsByUDA!(B, 100).length == 1);\n    // Can get the value of the UDA from the return value\n    static assert(getUDAs!(getSymbolsByUDA!(B, UDA)[0], UDA)[0].name == \"X\");\n}\n\n/// Checks for UDAs on the aggregate symbol itself\n@safe unittest\n{\n    static struct UDA { string name; }\n\n    @UDA(\"A\")\n    static struct C\n    {\n        @UDA(\"B\")\n        int d;\n    }\n\n    static assert(getSymbolsByUDA!(C, UDA).length == 2);\n    static assert(getSymbolsByUDA!(C, UDA)[0].stringof == \"C\");\n    static assert(getSymbolsByUDA!(C, UDA)[1].stringof == \"d\");\n}\n\n/// Finds nothing if there is no member with specific UDA\n@safe unittest\n{\n    static struct UDA { string name; }\n\n    static struct D\n    {\n        int x;\n    }\n\n    static assert(getSymbolsByUDA!(D, UDA).length == 0);\n}\n\n// Issue 18314\n@safe unittest\n{\n    enum attr1;\n    enum attr2;\n\n    struct A\n    {\n        @attr1\n        int n;\n        // Removed due to Issue 16206\n        //@attr1\n        //void foo()(string){}\n        @attr1\n        void foo();\n        @attr2\n        void foo(int a);\n    }\n\n    static assert(getSymbolsByUDA!(A, attr1).length == 2);\n    static assert(getSymbolsByUDA!(A, attr2).length == 1);\n}\n\n// #15335: getSymbolsByUDA fails if type has private members\n@safe unittest\n{\n    // HasPrivateMembers has, well, private members, one of which has a UDA.\n    import std.internal.test.uda : Attr, HasPrivateMembers;\n    // Trying access to private member from another file therefore we do not have access\n    // for this otherwise we get deprecation warning - not visible from module\n    static assert(getSymbolsByUDA!(HasPrivateMembers, Attr).length == 1);\n    static assert(hasUDA!(getSymbolsByUDA!(HasPrivateMembers, Attr)[0], Attr));\n}\n\n// #16387: getSymbolsByUDA works with structs but fails with classes\n@safe unittest\n{\n    enum Attr;\n    class A\n    {\n        @Attr uint a;\n    }\n\n    alias res = getSymbolsByUDA!(A, Attr);\n    static assert(res.length == 1);\n    static assert(res[0].stringof == \"a\");\n}\n\n// #18884: getSymbolsByUDA fails on AliasSeq members\n@safe unittest\n{\n    struct X\n    {\n        alias A = AliasSeq!(ulong, uint);\n    }\n\n    static assert(is(getSymbolsByUDA!(X, X) == AliasSeq!()));\n}\n\n// #18624: getSymbolsByUDA produces wrong result if one of the symbols having the UDA is a function\n@safe unittest\n{\n    enum Attr;\n    struct A\n    {\n        @Attr void a();\n        @Attr void a(int n);\n              void b();\n        @Attr void c();\n    }\n\n    static assert(getSymbolsByUDA!(A, Attr).stringof == \"tuple(a, a, c)\");\n}\n\nprivate template getSymbolsByUDAImpl(alias symbol, alias attribute, names...)\n{\n    import std.meta : Alias, AliasSeq, Filter;\n    static if (names.length == 0)\n    {\n        alias getSymbolsByUDAImpl = AliasSeq!();\n    }\n    else\n    {\n        alias tail = getSymbolsByUDAImpl!(symbol, attribute, names[1 .. $]);\n\n        // Filtering inaccessible members.\n        static if (!__traits(compiles, __traits(getMember, symbol, names[0])))\n        {\n            alias getSymbolsByUDAImpl = tail;\n        }\n        else\n        {\n            alias member = AliasSeq!(__traits(getMember, symbol, names[0]));\n\n            // Filtering not compiled members such as alias of basic types.\n            static if (!__traits(compiles, hasUDA!(member, attribute)))\n            {\n                alias getSymbolsByUDAImpl = tail;\n            }\n            // Get overloads for functions, in case different overloads have different sets of UDAs.\n            else static if (isFunction!member)\n            {\n                enum hasSpecificUDA(alias member) = hasUDA!(member, attribute);\n                alias overloadsWithUDA = Filter!(hasSpecificUDA, __traits(getOverloads, symbol, names[0]));\n                alias getSymbolsByUDAImpl = AliasSeq!(overloadsWithUDA, tail);\n            }\n            else static if (hasUDA!(member, attribute))\n            {\n                alias getSymbolsByUDAImpl = AliasSeq!(member, tail);\n            }\n            else\n            {\n                alias getSymbolsByUDAImpl = tail;\n            }\n        }\n    }\n}\n\n/**\n   Returns: `true` iff all types `T` are the same.\n*/\ntemplate allSameType(T...)\n{\n    static foreach (idx, Ti; T)\n    {\n        static if (idx + 1 < T.length &&\n                   !is(typeof(allSameType) == bool) &&\n                   !is(T[idx] == T[idx + 1]))\n        {\n            enum bool allSameType = false;\n        }\n    }\n    static if (!is(typeof(allSameType) == bool))\n    {\n        enum bool allSameType = true;\n    }\n}\n\n///\n@safe unittest\n{\n    static assert(allSameType!(int, int));\n    static assert(allSameType!(int, int, int));\n    static assert(allSameType!(float, float, float));\n    static assert(!allSameType!(int, double));\n    static assert(!allSameType!(int, float, double));\n    static assert(!allSameType!(int, float, double, real));\n    static assert(!allSameType!(short, int, float, double, real));\n}\n\n/**\n   Returns: `true` iff the type `T` can be tested in an $(D\n   if)-expression, that is if $(D if (pred(T.init)) {}) is compilable.\n*/\nenum ifTestable(T, alias pred = a => a) = __traits(compiles, { if (pred(T.init)) {} });\n\n@safe unittest\n{\n    import std.meta : AliasSeq, allSatisfy;\n    static assert(allSatisfy!(ifTestable, AliasSeq!(bool, int, float, double, string)));\n    struct BoolWrapper { bool value; }\n    static assert(!ifTestable!(bool, a => BoolWrapper(a)));\n}\n\n/**\n * Detect whether `X` is a type. Analogous to `is(X)`. This is useful when used\n * in conjunction with other templates, e.g. `allSatisfy!(isType, X)`.\n *\n * Returns:\n *      `true` if `X` is a type, `false` otherwise\n */\ntemplate isType(X...)\nif (X.length == 1)\n{\n    enum isType = is(X[0]);\n}\n\n///\n@safe unittest\n{\n    struct S {\n        template Test() {}\n    }\n    class C {}\n    interface I {}\n    union U {}\n    static assert(isType!int);\n    static assert(isType!string);\n    static assert(isType!(int[int]));\n    static assert(isType!S);\n    static assert(isType!C);\n    static assert(isType!I);\n    static assert(isType!U);\n\n    int n;\n    void func(){}\n    static assert(!isType!n);\n    static assert(!isType!func);\n    static assert(!isType!(S.Test));\n    static assert(!isType!(S.Test!()));\n}\n\n/**\n * Detect whether symbol or type `X` is a function. This is different that finding\n * if a symbol is callable or satisfying `is(X == function)`, it finds\n * specifically if the symbol represents a normal function declaration, i.e.\n * not a delegate or a function pointer.\n *\n * Returns:\n *     `true` if `X` is a function, `false` otherwise\n *\n * See_Also:\n *     Use $(LREF isFunctionPointer) or $(LREF isDelegate) for detecting those types\n *     respectively.\n */\ntemplate isFunction(X...)\nif (X.length == 1)\n{\n    static if (is(typeof(&X[0]) U : U*) && is(U == function) ||\n               is(typeof(&X[0]) U == delegate))\n    {\n        // x is a (nested) function symbol.\n        enum isFunction = true;\n    }\n    else static if (is(X[0] T))\n    {\n        // x is a type.  Take the type of it and examine.\n        enum isFunction = is(T == function);\n    }\n    else\n        enum isFunction = false;\n}\n\n///\n@safe unittest\n{\n    static void func(){}\n    static assert(isFunction!func);\n\n    struct S\n    {\n        void func(){}\n    }\n    static assert(isFunction!(S.func));\n}\n\n/**\n * Detect whether `X` is a final method or class.\n *\n * Returns:\n *     `true` if `X` is final, `false` otherwise\n */\ntemplate isFinal(X...)\nif (X.length == 1)\n{\n    static if (is(X[0] == class))\n        enum isFinal = __traits(isFinalClass, X[0]);\n    else static if (isFunction!X)\n        enum isFinal = __traits(isFinalFunction, X[0]);\n    else\n        enum isFinal = false;\n}\n\n///\n@safe unittest\n{\n    class C\n    {\n        void nf() {}\n        static void sf() {}\n        final void ff() {}\n    }\n    final class FC { }\n\n    static assert(!isFinal!(C));\n    static assert( isFinal!(FC));\n\n    static assert(!isFinal!(C.nf));\n    static assert(!isFinal!(C.sf));\n    static assert( isFinal!(C.ff));\n}\n\n/++\n + Determines whether the type `S` can be copied.\n + If a type cannot be copied, then code such as `MyStruct x; auto y = x;` will fail to compile.\n + Copying for structs can be disabled by using `@disable this(this)`.\n +\n + Params:\n +  S = The type to check.\n +\n + Returns:\n +  `true` if `S` can be copied. `false` otherwise.\n + ++/\nenum isCopyable(S) = is(typeof(\n    { S foo = S.init; S copy = foo; }\n));\n\n///\n@safe unittest\n{\n    struct S1 {}                        // Fine. Can be copied\n    struct S2 {         this(this) {}}  // Fine. Can be copied\n    struct S3 {@disable this(this) {}}  // Not fine. Copying is disabled.\n    struct S4 {S3 s;}                   // Not fine. A field has copying disabled.\n\n    class C1 {}\n\n    static assert( isCopyable!S1);\n    static assert( isCopyable!S2);\n    static assert(!isCopyable!S3);\n    static assert(!isCopyable!S4);\n\n    static assert(isCopyable!C1);\n    static assert(isCopyable!int);\n    static assert(isCopyable!(int[]));\n}\n"
  },
  {
    "path": "libphobos/src/std/typecons.d",
    "content": "// Written in the D programming language.\n\n/**\nThis module implements a variety of type constructors, i.e., templates\nthat allow construction of new, useful general-purpose types.\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Tuple) $(TD\n    $(LREF isTuple)\n    $(LREF Tuple)\n    $(LREF tuple)\n    $(LREF reverse)\n))\n$(TR $(TD Flags) $(TD\n    $(LREF BitFlags)\n    $(LREF isBitFlagEnum)\n    $(LREF Flag)\n    $(LREF No)\n    $(LREF Yes)\n))\n$(TR $(TD Memory allocation) $(TD\n    $(LREF RefCounted)\n    $(LREF refCounted)\n    $(LREF RefCountedAutoInitialize)\n    $(LREF scoped)\n    $(LREF Unique)\n))\n$(TR $(TD Code generation) $(TD\n    $(LREF AutoImplement)\n    $(LREF BlackHole)\n    $(LREF generateAssertTrap)\n    $(LREF generateEmptyFunction)\n    $(LREF WhiteHole)\n))\n$(TR $(TD Nullable) $(TD\n    $(LREF Nullable)\n    $(LREF nullable)\n    $(LREF NullableRef)\n    $(LREF nullableRef)\n))\n$(TR $(TD Proxies) $(TD\n    $(LREF Proxy)\n    $(LREF rebindable)\n    $(LREF Rebindable)\n    $(LREF ReplaceType)\n    $(LREF unwrap)\n    $(LREF wrap)\n))\n$(TR $(TD Types) $(TD\n    $(LREF alignForSize)\n    $(LREF Ternary)\n    $(LREF Typedef)\n    $(LREF TypedefType)\n    $(LREF UnqualRef)\n))\n)\n\nCopyright: Copyright the respective authors, 2008-\nLicense:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).\nSource:    $(PHOBOSSRC std/typecons.d)\nAuthors:   $(HTTP erdani.org, Andrei Alexandrescu),\n           $(HTTP bartoszmilewski.wordpress.com, Bartosz Milewski),\n           Don Clugston,\n           Shin Fujishiro,\n           Kenji Hara\n */\nmodule std.typecons;\n\nimport std.format : singleSpec, FormatSpec, formatValue;\nimport std.meta; // : AliasSeq, allSatisfy;\nimport std.range.primitives : isOutputRange;\nimport std.traits;\n\n///\n@safe unittest\n{\n    // value tuples\n    alias Coord = Tuple!(int, \"x\", int, \"y\", int, \"z\");\n    Coord c;\n    c[1] = 1;       // access by index\n    c.z = 1;        // access by given name\n    assert(c == Coord(0, 1, 1));\n\n    // names can be omitted\n    alias DicEntry = Tuple!(string, string);\n\n    // tuples can also be constructed on instantiation\n    assert(tuple(2, 3, 4)[1] == 3);\n    // construction on instantiation works with names too\n    assert(tuple!(\"x\", \"y\", \"z\")(2, 3, 4).y == 3);\n\n    // Rebindable references to const and immutable objects\n    {\n        class Widget { void foo() const @safe {} }\n        const w1 = new Widget, w2 = new Widget;\n        w1.foo();\n        // w1 = w2 would not work; can't rebind const object\n        auto r = Rebindable!(const Widget)(w1);\n        // invoke method as if r were a Widget object\n        r.foo();\n        // rebind r to refer to another object\n        r = w2;\n    }\n}\n\n/**\nEncapsulates unique ownership of a resource.\n\nWhen a `Unique!T` goes out of scope it will call `destroy`\non the resource `T` that it manages, unless it is transferred.\nOne important consequence of `destroy` is that it will call the\ndestructor of the resource `T`.  GC-managed references are not\nguaranteed to be valid during a destructor call, but other members of\n`T`, such as file handles or pointers to `malloc` memory, will\nstill be valid during the destructor call.  This allows the resource\n`T` to deallocate or clean up any non-GC resources.\n\nIf it is desirable to persist a `Unique!T` outside of its original\nscope, then it can be transferred.  The transfer can be explicit, by\ncalling `release`, or implicit, when returning Unique from a\nfunction. The resource `T` can be a polymorphic class object or\ninstance of an interface, in which case Unique behaves polymorphically\ntoo.\n\nIf `T` is a value type, then `Unique!T` will be implemented\nas a reference to a `T`.\n*/\nstruct Unique(T)\n{\n/** Represents a reference to `T`. Resolves to `T*` if `T` is a value type. */\nstatic if (is(T == class) || is(T == interface))\n    alias RefT = T;\nelse\n    alias RefT = T*;\n\npublic:\n    // Deferred in case we get some language support for checking uniqueness.\n    version (None)\n    /**\n    Allows safe construction of `Unique`. It creates the resource and\n    guarantees unique ownership of it (unless `T` publishes aliases of\n    `this`).\n    Note: Nested structs/classes cannot be created.\n    Params:\n    args = Arguments to pass to `T`'s constructor.\n    ---\n    static class C {}\n    auto u = Unique!(C).create();\n    ---\n    */\n    static Unique!T create(A...)(auto ref A args)\n    if (__traits(compiles, new T(args)))\n    {\n        Unique!T u;\n        u._p = new T(args);\n        return u;\n    }\n\n    /**\n    Constructor that takes an rvalue.\n    It will ensure uniqueness, as long as the rvalue\n    isn't just a view on an lvalue (e.g., a cast).\n    Typical usage:\n    ----\n    Unique!Foo f = new Foo;\n    ----\n    */\n    this(RefT p)\n    {\n        _p = p;\n    }\n    /**\n    Constructor that takes an lvalue. It nulls its source.\n    The nulling will ensure uniqueness as long as there\n    are no previous aliases to the source.\n    */\n    this(ref RefT p)\n    {\n        _p = p;\n        p = null;\n        assert(p is null);\n    }\n    /**\n    Constructor that takes a `Unique` of a type that is convertible to our type.\n\n    Typically used to transfer a `Unique` rvalue of derived type to\n    a `Unique` of base type.\n    Example:\n    ---\n    class C : Object {}\n\n    Unique!C uc = new C;\n    Unique!Object uo = uc.release;\n    ---\n    */\n    this(U)(Unique!U u)\n    if (is(u.RefT:RefT))\n    {\n        _p = u._p;\n        u._p = null;\n    }\n\n    /// Transfer ownership from a `Unique` of a type that is convertible to our type.\n    void opAssign(U)(Unique!U u)\n    if (is(u.RefT:RefT))\n    {\n        // first delete any resource we own\n        destroy(this);\n        _p = u._p;\n        u._p = null;\n    }\n\n    ~this()\n    {\n        if (_p !is null)\n        {\n            destroy(_p);\n            _p = null;\n        }\n    }\n\n    /** Returns whether the resource exists. */\n    @property bool isEmpty() const\n    {\n        return _p is null;\n    }\n    /** Transfer ownership to a `Unique` rvalue. Nullifies the current contents.\n    Same as calling std.algorithm.move on it.\n    */\n    Unique release()\n    {\n        import std.algorithm.mutation : move;\n        return this.move;\n    }\n\n    /** Forwards member access to contents. */\n    mixin Proxy!_p;\n\n    /**\n    Postblit operator is undefined to prevent the cloning of `Unique` objects.\n    */\n    @disable this(this);\n\nprivate:\n    RefT _p;\n}\n\n///\n@safe unittest\n{\n    static struct S\n    {\n        int i;\n        this(int i){this.i = i;}\n    }\n    Unique!S produce()\n    {\n        // Construct a unique instance of S on the heap\n        Unique!S ut = new S(5);\n        // Implicit transfer of ownership\n        return ut;\n    }\n    // Borrow a unique resource by ref\n    void increment(ref Unique!S ur)\n    {\n        ur.i++;\n    }\n    void consume(Unique!S u2)\n    {\n        assert(u2.i == 6);\n        // Resource automatically deleted here\n    }\n    Unique!S u1;\n    assert(u1.isEmpty);\n    u1 = produce();\n    increment(u1);\n    assert(u1.i == 6);\n    //consume(u1); // Error: u1 is not copyable\n    // Transfer ownership of the resource\n    consume(u1.release);\n    assert(u1.isEmpty);\n}\n\n@system unittest\n{\n    // test conversion to base ref\n    int deleted = 0;\n    class C\n    {\n        ~this(){deleted++;}\n    }\n    // constructor conversion\n    Unique!Object u = Unique!C(new C);\n    static assert(!__traits(compiles, {u = new C;}));\n    assert(!u.isEmpty);\n    destroy(u);\n    assert(deleted == 1);\n\n    Unique!C uc = new C;\n    static assert(!__traits(compiles, {Unique!Object uo = uc;}));\n    Unique!Object uo = new C;\n    // opAssign conversion, deleting uo resource first\n    uo = uc.release;\n    assert(uc.isEmpty);\n    assert(!uo.isEmpty);\n    assert(deleted == 2);\n}\n\n@system unittest\n{\n    class Bar\n    {\n        ~this() { debug(Unique) writeln(\"    Bar destructor\"); }\n        int val() const { return 4; }\n    }\n    alias UBar = Unique!(Bar);\n    UBar g(UBar u)\n    {\n        debug(Unique) writeln(\"inside g\");\n        return u.release;\n    }\n    auto ub = UBar(new Bar);\n    assert(!ub.isEmpty);\n    assert(ub.val == 4);\n    static assert(!__traits(compiles, {auto ub3 = g(ub);}));\n    auto ub2 = g(ub.release);\n    assert(ub.isEmpty);\n    assert(!ub2.isEmpty);\n}\n\n@system unittest\n{\n    interface Bar\n    {\n        int val() const;\n    }\n    class BarImpl : Bar\n    {\n        static int count;\n        this()\n        {\n            count++;\n        }\n        ~this()\n        {\n            count--;\n        }\n        int val() const { return 4; }\n    }\n    alias UBar = Unique!Bar;\n    UBar g(UBar u)\n    {\n        debug(Unique) writeln(\"inside g\");\n        return u.release;\n    }\n    void consume(UBar u)\n    {\n        assert(u.val() == 4);\n        // Resource automatically deleted here\n    }\n    auto ub = UBar(new BarImpl);\n    assert(BarImpl.count == 1);\n    assert(!ub.isEmpty);\n    assert(ub.val == 4);\n    static assert(!__traits(compiles, {auto ub3 = g(ub);}));\n    auto ub2 = g(ub.release);\n    assert(ub.isEmpty);\n    assert(!ub2.isEmpty);\n    consume(ub2.release);\n    assert(BarImpl.count == 0);\n}\n\n@safe unittest\n{\n    struct Foo\n    {\n        ~this() { }\n        int val() const { return 3; }\n        @disable this(this);\n    }\n    alias UFoo = Unique!(Foo);\n\n    UFoo f(UFoo u)\n    {\n        return u.release;\n    }\n\n    auto uf = UFoo(new Foo);\n    assert(!uf.isEmpty);\n    assert(uf.val == 3);\n    static assert(!__traits(compiles, {auto uf3 = f(uf);}));\n    auto uf2 = f(uf.release);\n    assert(uf.isEmpty);\n    assert(!uf2.isEmpty);\n}\n\n// ensure Unique behaves correctly through const access paths\n@system unittest\n{\n    struct Bar {int val;}\n    struct Foo\n    {\n        Unique!Bar bar = new Bar;\n    }\n\n    Foo foo;\n    foo.bar.val = 6;\n    const Foo* ptr = &foo;\n    static assert(is(typeof(ptr) == const(Foo*)));\n    static assert(is(typeof(ptr.bar) == const(Unique!Bar)));\n    static assert(is(typeof(ptr.bar.val) == const(int)));\n    assert(ptr.bar.val == 6);\n    foo.bar.val = 7;\n    assert(ptr.bar.val == 7);\n}\n\n// Used in Tuple.toString\nprivate template sharedToString(alias field)\nif (is(typeof(field) == shared))\n{\n    static immutable sharedToString = typeof(field).stringof;\n}\n\nprivate template sharedToString(alias field)\nif (!is(typeof(field) == shared))\n{\n    alias sharedToString = field;\n}\n\nprivate enum bool distinctFieldNames(names...) = __traits(compiles,\n{\n    static foreach (__name; names)\n        static if (is(typeof(__name) : string))\n            mixin(\"enum int \" ~ __name ~ \" = 0;\");\n});\n\n@safe unittest\n{\n    static assert(!distinctFieldNames!(string, \"abc\", string, \"abc\"));\n    static assert(distinctFieldNames!(string, \"abc\", int, \"abd\"));\n    static assert(!distinctFieldNames!(int, \"abc\", string, \"abd\", int, \"abc\"));\n    // Issue 19240\n    static assert(!distinctFieldNames!(int, \"int\"));\n}\n\n/**\n_Tuple of values, for example $(D Tuple!(int, string)) is a record that\nstores an `int` and a `string`. `Tuple` can be used to bundle\nvalues together, notably when returning multiple values from a\nfunction. If `obj` is a `Tuple`, the individual members are\naccessible with the syntax `obj[0]` for the first field, `obj[1]`\nfor the second, and so on.\n\nSee_Also: $(LREF tuple).\n\nParams:\n    Specs = A list of types (and optionally, member names) that the `Tuple` contains.\n*/\ntemplate Tuple(Specs...)\nif (distinctFieldNames!(Specs))\n{\n    import std.meta : staticMap;\n\n    // Parse (type,name) pairs (FieldSpecs) out of the specified\n    // arguments. Some fields would have name, others not.\n    template parseSpecs(Specs...)\n    {\n        static if (Specs.length == 0)\n        {\n            alias parseSpecs = AliasSeq!();\n        }\n        else static if (is(Specs[0]))\n        {\n            static if (is(typeof(Specs[1]) : string))\n            {\n                alias parseSpecs =\n                    AliasSeq!(FieldSpec!(Specs[0 .. 2]),\n                              parseSpecs!(Specs[2 .. $]));\n            }\n            else\n            {\n                alias parseSpecs =\n                    AliasSeq!(FieldSpec!(Specs[0]),\n                              parseSpecs!(Specs[1 .. $]));\n            }\n        }\n        else\n        {\n            static assert(0, \"Attempted to instantiate Tuple with an \"\n                            ~\"invalid argument: \"~ Specs[0].stringof);\n        }\n    }\n\n    template FieldSpec(T, string s = \"\")\n    {\n        alias Type = T;\n        alias name = s;\n    }\n\n    alias fieldSpecs = parseSpecs!Specs;\n\n    // Used with staticMap.\n    alias extractType(alias spec) = spec.Type;\n    alias extractName(alias spec) = spec.name;\n\n    // Generates named fields as follows:\n    //    alias name_0 = Identity!(field[0]);\n    //    alias name_1 = Identity!(field[1]);\n    //      :\n    // NOTE: field[k] is an expression (which yields a symbol of a\n    //       variable) and can't be aliased directly.\n    string injectNamedFields()\n    {\n        string decl = \"\";\n        static foreach (i, val; fieldSpecs)\n        {{\n            immutable si = i.stringof;\n            decl ~= \"alias _\" ~ si ~ \" = Identity!(field[\" ~ si ~ \"]);\";\n            if (val.name.length != 0)\n            {\n                decl ~= \"alias \" ~ val.name ~ \" = _\" ~ si ~ \";\";\n            }\n        }}\n        return decl;\n    }\n\n    // Returns Specs for a subtuple this[from .. to] preserving field\n    // names if any.\n    alias sliceSpecs(size_t from, size_t to) =\n        staticMap!(expandSpec, fieldSpecs[from .. to]);\n\n    template expandSpec(alias spec)\n    {\n        static if (spec.name.length == 0)\n        {\n            alias expandSpec = AliasSeq!(spec.Type);\n        }\n        else\n        {\n            alias expandSpec = AliasSeq!(spec.Type, spec.name);\n        }\n    }\n\n    enum areCompatibleTuples(Tup1, Tup2, string op) = isTuple!Tup2 && is(typeof(\n    (ref Tup1 tup1, ref Tup2 tup2)\n    {\n        static assert(tup1.field.length == tup2.field.length);\n        static foreach (i; 0 .. Tup1.Types.length)\n        {{\n            auto lhs = typeof(tup1.field[i]).init;\n            auto rhs = typeof(tup2.field[i]).init;\n            static if (op == \"=\")\n                lhs = rhs;\n            else\n                auto result = mixin(\"lhs \"~op~\" rhs\");\n        }}\n    }));\n\n    enum areBuildCompatibleTuples(Tup1, Tup2) = isTuple!Tup2 && is(typeof(\n    {\n        static assert(Tup1.Types.length == Tup2.Types.length);\n        static foreach (i; 0 .. Tup1.Types.length)\n            static assert(isBuildable!(Tup1.Types[i], Tup2.Types[i]));\n    }));\n\n    /+ Returns `true` iff a `T` can be initialized from a `U`. +/\n    enum isBuildable(T, U) =  is(typeof(\n    {\n        U u = U.init;\n        T t = u;\n    }));\n    /+ Helper for partial instantiation +/\n    template isBuildableFrom(U)\n    {\n        enum isBuildableFrom(T) = isBuildable!(T, U);\n    }\n\n    struct Tuple\n    {\n        /**\n         * The types of the `Tuple`'s components.\n         */\n        alias Types = staticMap!(extractType, fieldSpecs);\n\n        private alias _Fields = Specs;\n\n        ///\n        static if (Specs.length == 0) @safe unittest\n        {\n            alias Fields = Tuple!(int, \"id\", string, float);\n            static assert(is(Fields.Types == AliasSeq!(int, string, float)));\n        }\n\n        /**\n         * The names of the `Tuple`'s components. Unnamed fields have empty names.\n         */\n        alias fieldNames = staticMap!(extractName, fieldSpecs);\n\n        ///\n        static if (Specs.length == 0) @safe unittest\n        {\n            alias Fields = Tuple!(int, \"id\", string, float);\n            static assert(Fields.fieldNames == AliasSeq!(\"id\", \"\", \"\"));\n        }\n\n        /**\n         * Use `t.expand` for a `Tuple` `t` to expand it into its\n         * components. The result of `expand` acts as if the `Tuple`'s components\n         * were listed as a list of values. (Ordinarily, a `Tuple` acts as a\n         * single value.)\n         */\n        Types expand;\n        mixin(injectNamedFields());\n\n        ///\n        static if (Specs.length == 0) @safe unittest\n        {\n            auto t1 = tuple(1, \" hello \", 'a');\n            assert(t1.toString() == `Tuple!(int, string, char)(1, \" hello \", 'a')`);\n\n            void takeSeveralTypes(int n, string s, bool b)\n            {\n                assert(n == 4 && s == \"test\" && b == false);\n            }\n\n            auto t2 = tuple(4, \"test\", false);\n            //t.expand acting as a list of values\n            takeSeveralTypes(t2.expand);\n        }\n\n        static if (is(Specs))\n        {\n            // This is mostly to make t[n] work.\n            alias expand this;\n        }\n        else\n        {\n            @property\n            ref inout(Tuple!Types) _Tuple_super() inout @trusted\n            {\n                static foreach (i; 0 .. Types.length)   // Rely on the field layout\n                {\n                    static assert(typeof(return).init.tupleof[i].offsetof ==\n                                                       expand[i].offsetof);\n                }\n                return *cast(typeof(return)*) &(field[0]);\n            }\n            // This is mostly to make t[n] work.\n            alias _Tuple_super this;\n        }\n\n        // backwards compatibility\n        alias field = expand;\n\n        /**\n         * Constructor taking one value for each field.\n         *\n         * Params:\n         *     values = A list of values that are either the same\n         *              types as those given by the `Types` field\n         *              of this `Tuple`, or can implicitly convert\n         *              to those types. They must be in the same\n         *              order as they appear in `Types`.\n         */\n        static if (Types.length > 0)\n        {\n            this(Types values)\n            {\n                field[] = values[];\n            }\n        }\n\n        ///\n        static if (Specs.length == 0) @safe unittest\n        {\n            alias ISD = Tuple!(int, string, double);\n            auto tup = ISD(1, \"test\", 3.2);\n            assert(tup.toString() == `Tuple!(int, string, double)(1, \"test\", 3.2)`);\n        }\n\n        /**\n         * Constructor taking a compatible array.\n         *\n         * Params:\n         *     values = A compatible static array to build the `Tuple` from.\n         *              Array slices are not supported.\n         */\n        this(U, size_t n)(U[n] values)\n        if (n == Types.length && allSatisfy!(isBuildableFrom!U, Types))\n        {\n            static foreach (i; 0 .. Types.length)\n            {\n                field[i] = values[i];\n            }\n        }\n\n        ///\n        static if (Specs.length == 0) @safe unittest\n        {\n            int[2] ints;\n            Tuple!(int, int) t = ints;\n        }\n\n        /**\n         * Constructor taking a compatible `Tuple`. Two `Tuple`s are compatible\n         * $(B iff) they are both of the same length, and, for each type `T` on the\n         * left-hand side, the corresponding type `U` on the right-hand side can\n         * implicitly convert to `T`.\n         *\n         * Params:\n         *     another = A compatible `Tuple` to build from. Its type must be\n         *               compatible with the target `Tuple`'s type.\n         */\n        this(U)(U another)\n        if (areBuildCompatibleTuples!(typeof(this), U))\n        {\n            field[] = another.field[];\n        }\n\n        ///\n        static if (Specs.length == 0) @safe unittest\n        {\n            alias IntVec = Tuple!(int, int, int);\n            alias DubVec = Tuple!(double, double, double);\n\n            IntVec iv = tuple(1, 1, 1);\n\n            //Ok, int can implicitly convert to double\n            DubVec dv = iv;\n            //Error: double cannot implicitly convert to int\n            //IntVec iv2 = dv;\n        }\n\n        /**\n         * Comparison for equality. Two `Tuple`s are considered equal\n         * $(B iff) they fulfill the following criteria:\n         *\n         * $(UL\n         *   $(LI Each `Tuple` is the same length.)\n         *   $(LI For each type `T` on the left-hand side and each type\n         *        `U` on the right-hand side, values of type `T` can be\n         *        compared with values of type `U`.)\n         *   $(LI For each value `v1` on the left-hand side and each value\n         *        `v2` on the right-hand side, the expression `v1 == v2` is\n         *        true.))\n         *\n         * Params:\n         *     rhs = The `Tuple` to compare against. It must meeting the criteria\n         *           for comparison between `Tuple`s.\n         *\n         * Returns:\n         *     true if both `Tuple`s are equal, otherwise false.\n         */\n        bool opEquals(R)(R rhs)\n        if (areCompatibleTuples!(typeof(this), R, \"==\"))\n        {\n            return field[] == rhs.field[];\n        }\n\n        /// ditto\n        bool opEquals(R)(R rhs) const\n        if (areCompatibleTuples!(typeof(this), R, \"==\"))\n        {\n            return field[] == rhs.field[];\n        }\n\n        /// ditto\n        bool opEquals(R...)(auto ref R rhs)\n        if (R.length > 1 && areCompatibleTuples!(typeof(this), Tuple!R, \"==\"))\n        {\n            static foreach (i; 0 .. Types.length)\n                if (field[i] != rhs[i])\n                    return false;\n\n            return true;\n        }\n\n        ///\n        static if (Specs.length == 0) @safe unittest\n        {\n            Tuple!(int, string) t1 = tuple(1, \"test\");\n            Tuple!(double, string) t2 =  tuple(1.0, \"test\");\n            //Ok, int can be compared with double and\n            //both have a value of 1\n            assert(t1 == t2);\n        }\n\n        /**\n         * Comparison for ordering.\n         *\n         * Params:\n         *     rhs = The `Tuple` to compare against. It must meet the criteria\n         *           for comparison between `Tuple`s.\n         *\n         * Returns:\n         * For any values `v1` on the right-hand side and `v2` on the\n         * left-hand side:\n         *\n         * $(UL\n         *   $(LI A negative integer if the expression `v1 < v2` is true.)\n         *   $(LI A positive integer if the expression `v1 > v2` is true.)\n         *   $(LI 0 if the expression `v1 == v2` is true.))\n         */\n        int opCmp(R)(R rhs)\n        if (areCompatibleTuples!(typeof(this), R, \"<\"))\n        {\n            static foreach (i; 0 .. Types.length)\n            {\n                if (field[i] != rhs.field[i])\n                {\n                    return field[i] < rhs.field[i] ? -1 : 1;\n                }\n            }\n            return 0;\n        }\n\n        /// ditto\n        int opCmp(R)(R rhs) const\n        if (areCompatibleTuples!(typeof(this), R, \"<\"))\n        {\n            static foreach (i; 0 .. Types.length)\n            {\n                if (field[i] != rhs.field[i])\n                {\n                    return field[i] < rhs.field[i] ? -1 : 1;\n                }\n            }\n            return 0;\n        }\n\n        /**\n            The first `v1` for which `v1 > v2` is true determines\n            the result. This could lead to unexpected behaviour.\n         */\n        static if (Specs.length == 0) @safe unittest\n        {\n            auto tup1 = tuple(1, 1, 1);\n            auto tup2 = tuple(1, 100, 100);\n            assert(tup1 < tup2);\n\n            //Only the first result matters for comparison\n            tup1[0] = 2;\n            assert(tup1 > tup2);\n        }\n\n        /**\n         Concatenate Tuples.\n         Tuple concatenation is only allowed if all named fields are distinct (no named field of this tuple occurs in `t`\n         and no named field of `t` occurs in this tuple).\n\n         Params:\n             t = The `Tuple` to concatenate with\n\n         Returns: A concatenation of this tuple and `t`\n         */\n        auto opBinary(string op, T)(auto ref T t)\n        if (op == \"~\")\n        {\n            static if (isTuple!T)\n            {\n                static assert(distinctFieldNames!(_Fields, T._Fields),\n                    \"Cannot concatenate tuples with duplicate fields: \" ~ fieldNames.stringof ~\n                    \" - \" ~ T.fieldNames.stringof);\n                return Tuple!(_Fields, T._Fields)(expand, t.expand);\n            }\n            else\n            {\n                return Tuple!(_Fields, T)(expand, t);\n            }\n        }\n\n        /// ditto\n        auto opBinaryRight(string op, T)(auto ref T t)\n        if (op == \"~\")\n        {\n            static if (isTuple!T)\n            {\n                static assert(distinctFieldNames!(_Fields, T._Fields),\n                    \"Cannot concatenate tuples with duplicate fields: \" ~ T.stringof ~\n                    \" - \" ~ fieldNames.fieldNames.stringof);\n                return Tuple!(T._Fields, _Fields)(t.expand, expand);\n            }\n            else\n            {\n                return Tuple!(T, _Fields)(t, expand);\n            }\n        }\n\n        /**\n         * Assignment from another `Tuple`.\n         *\n         * Params:\n         *     rhs = The source `Tuple` to assign from. Each element of the\n         *           source `Tuple` must be implicitly assignable to each\n         *           respective element of the target `Tuple`.\n         */\n        ref Tuple opAssign(R)(auto ref R rhs)\n        if (areCompatibleTuples!(typeof(this), R, \"=\"))\n        {\n            import std.algorithm.mutation : swap;\n\n            static if (is(R : Tuple!Types) && !__traits(isRef, rhs))\n            {\n                if (__ctfe)\n                {\n                    // Cannot use swap at compile time\n                    field[] = rhs.field[];\n                }\n                else\n                {\n                    // Use swap-and-destroy to optimize rvalue assignment\n                    swap!(Tuple!Types)(this, rhs);\n                }\n            }\n            else\n            {\n                // Do not swap; opAssign should be called on the fields.\n                field[] = rhs.field[];\n            }\n            return this;\n        }\n\n        /**\n         * Renames the elements of a $(LREF Tuple).\n         *\n         * `rename` uses the passed `names` and returns a new\n         * $(LREF Tuple) using these names, with the content\n         * unchanged.\n         * If fewer names are passed than there are members\n         * of the $(LREF Tuple) then those trailing members are unchanged.\n         * An empty string will remove the name for that member.\n         * It is an compile-time error to pass more names than\n         * there are members of the $(LREF Tuple).\n         */\n        ref rename(names...)() return\n        if (names.length == 0 || allSatisfy!(isSomeString, typeof(names)))\n        {\n            import std.algorithm.comparison : equal;\n            // to circumvent bug 16418\n            static if (names.length == 0 || equal([names], [fieldNames]))\n                return this;\n            else\n            {\n                enum nT = Types.length;\n                enum nN = names.length;\n                static assert(nN <= nT, \"Cannot have more names than tuple members\");\n                alias allNames = AliasSeq!(names, fieldNames[nN .. $]);\n\n                template GetItem(size_t idx)\n                {\n                    import std.array : empty;\n                    static if (idx < nT)\n                        alias GetItem = Alias!(Types[idx]);\n                    else static if (allNames[idx - nT].empty)\n                        alias GetItem = AliasSeq!();\n                    else\n                        alias GetItem = Alias!(allNames[idx - nT]);\n                }\n\n                import std.range : roundRobin, iota;\n                alias NewTupleT = Tuple!(staticMap!(GetItem, aliasSeqOf!(\n                        roundRobin(iota(nT), iota(nT, 2*nT)))));\n                return *(() @trusted => cast(NewTupleT*)&this)();\n            }\n        }\n\n        ///\n        static if (Specs.length == 0) @safe unittest\n        {\n            auto t0 = tuple(4, \"hello\");\n\n            auto t0Named = t0.rename!(\"val\", \"tag\");\n            assert(t0Named.val == 4);\n            assert(t0Named.tag == \"hello\");\n\n            Tuple!(float, \"dat\", size_t[2], \"pos\") t1;\n            t1.pos = [2, 1];\n            auto t1Named = t1.rename!\"height\";\n            t1Named.height = 3.4f;\n            assert(t1Named.height == 3.4f);\n            assert(t1Named.pos == [2, 1]);\n            t1Named.rename!\"altitude\".altitude = 5;\n            assert(t1Named.height == 5);\n\n            Tuple!(int, \"a\", int, int, \"c\") t2;\n            t2 = tuple(3,4,5);\n            auto t2Named = t2.rename!(\"\", \"b\");\n            // \"a\" no longer has a name\n            static assert(!hasMember!(typeof(t2Named), \"a\"));\n            assert(t2Named[0] == 3);\n            assert(t2Named.b == 4);\n            assert(t2Named.c == 5);\n\n            // not allowed to specify more names than the tuple has members\n            static assert(!__traits(compiles, t2.rename!(\"a\",\"b\",\"c\",\"d\")));\n\n            // use it in a range pipeline\n            import std.range : iota, zip;\n            import std.algorithm.iteration : map, sum;\n            auto res = zip(iota(1, 4), iota(10, 13))\n                .map!(t => t.rename!(\"a\", \"b\"))\n                .map!(t => t.a * t.b)\n                .sum;\n            assert(res == 68);\n        }\n\n        /**\n         * Overload of $(LREF _rename) that takes an associative array\n         * `translate` as a template parameter, where the keys are\n         * either the names or indices of the members to be changed\n         * and the new names are the corresponding values.\n         * Every key in `translate` must be the name of a member of the\n         * $(LREF tuple).\n         * The same rules for empty strings apply as for the variadic\n         * template overload of $(LREF _rename).\n        */\n        ref rename(alias translate)()\n        if (is(typeof(translate) : V[K], V, K) && isSomeString!V &&\n                (isSomeString!K || is(K : size_t)))\n        {\n            import std.range : ElementType;\n            static if (isSomeString!(ElementType!(typeof(translate.keys))))\n            {\n                {\n                    import std.conv : to;\n                    import std.algorithm.iteration : filter;\n                    import std.algorithm.searching : canFind;\n                    enum notFound = translate.keys\n                        .filter!(k => fieldNames.canFind(k) == -1);\n                    static assert(notFound.empty, \"Cannot find members \"\n                        ~ notFound.to!string ~ \" in type \"\n                        ~ typeof(this).stringof);\n                }\n                return this.rename!(aliasSeqOf!(\n                    {\n                        import std.array : empty;\n                        auto names = [fieldNames];\n                        foreach (ref n; names)\n                            if (!n.empty)\n                                if (auto p = n in translate)\n                                    n = *p;\n                        return names;\n                    }()));\n            }\n            else\n            {\n                {\n                    import std.algorithm.iteration : filter;\n                    import std.conv : to;\n                    enum invalid = translate.keys.\n                        filter!(k => k < 0 || k >= this.length);\n                    static assert(invalid.empty, \"Indices \" ~ invalid.to!string\n                        ~ \" are out of bounds for tuple with length \"\n                        ~ this.length.to!string);\n                }\n                return this.rename!(aliasSeqOf!(\n                    {\n                        auto names = [fieldNames];\n                        foreach (k, v; translate)\n                            names[k] = v;\n                        return names;\n                    }()));\n            }\n        }\n\n        ///\n        static if (Specs.length == 0) @safe unittest\n        {\n            //replacing names by their current name\n\n            Tuple!(float, \"dat\", size_t[2], \"pos\") t1;\n            t1.pos = [2, 1];\n            auto t1Named = t1.rename!([\"dat\": \"height\"]);\n            t1Named.height = 3.4;\n            assert(t1Named.pos == [2, 1]);\n            t1Named.rename!([\"height\": \"altitude\"]).altitude = 5;\n            assert(t1Named.height == 5);\n\n            Tuple!(int, \"a\", int, \"b\") t2;\n            t2 = tuple(3, 4);\n            auto t2Named = t2.rename!([\"a\": \"b\", \"b\": \"c\"]);\n            assert(t2Named.b == 3);\n            assert(t2Named.c == 4);\n        }\n\n        ///\n        static if (Specs.length == 0) @safe unittest\n        {\n            //replace names by their position\n\n            Tuple!(float, \"dat\", size_t[2], \"pos\") t1;\n            t1.pos = [2, 1];\n            auto t1Named = t1.rename!([0: \"height\"]);\n            t1Named.height = 3.4;\n            assert(t1Named.pos == [2, 1]);\n            t1Named.rename!([0: \"altitude\"]).altitude = 5;\n            assert(t1Named.height == 5);\n\n            Tuple!(int, \"a\", int, \"b\", int, \"c\") t2;\n            t2 = tuple(3, 4, 5);\n            auto t2Named = t2.rename!([0: \"c\", 2: \"a\"]);\n            assert(t2Named.a == 5);\n            assert(t2Named.b == 4);\n            assert(t2Named.c == 3);\n        }\n\n        static if (Specs.length == 0) @safe unittest\n        {\n            //check that empty translations work fine\n            enum string[string] a0 = null;\n            enum string[int] a1 = null;\n            Tuple!(float, \"a\", float, \"b\") t0;\n\n            auto t1 = t0.rename!a0;\n\n            t1.a = 3;\n            t1.b = 4;\n            auto t2 = t0.rename!a1;\n            t2.a = 3;\n            t2.b = 4;\n            auto t3 = t0.rename;\n            t3.a = 3;\n            t3.b = 4;\n        }\n\n        /**\n         * Takes a slice by-reference of this `Tuple`.\n         *\n         * Params:\n         *     from = A `size_t` designating the starting position of the slice.\n         *     to = A `size_t` designating the ending position (exclusive) of the slice.\n         *\n         * Returns:\n         *     A new `Tuple` that is a slice from `[from, to$(RPAREN)` of the original.\n         *     It has the same types and values as the range `[from, to$(RPAREN)` in\n         *     the original.\n         */\n        @property\n        ref inout(Tuple!(sliceSpecs!(from, to))) slice(size_t from, size_t to)() inout @trusted\n        if (from <= to && to <= Types.length)\n        {\n            static assert(\n                (typeof(this).alignof % typeof(return).alignof == 0) &&\n                (expand[from].offsetof % typeof(return).alignof == 0),\n                \"Slicing by reference is impossible because of an alignment mistmatch. (See Phobos issue #15645.)\");\n\n            return *cast(typeof(return)*) &(field[from]);\n        }\n\n        ///\n        static if (Specs.length == 0) @safe unittest\n        {\n            Tuple!(int, string, float, double) a;\n            a[1] = \"abc\";\n            a[2] = 4.5;\n            auto s = a.slice!(1, 3);\n            static assert(is(typeof(s) == Tuple!(string, float)));\n            assert(s[0] == \"abc\" && s[1] == 4.5);\n\n            // Phobos issue #15645\n            Tuple!(int, short, bool, double) b;\n            static assert(!__traits(compiles, b.slice!(2, 4)));\n        }\n\n        /**\n            Creates a hash of this `Tuple`.\n\n            Returns:\n                A `size_t` representing the hash of this `Tuple`.\n         */\n        size_t toHash() const nothrow @safe\n        {\n            size_t h = 0;\n            static foreach (i, T; Types)\n            {{\n                const k = typeid(T).getHash((() @trusted => cast(const void*) &field[i])());\n                static if (i == 0)\n                    h = k;\n                else\n                    // As in boost::hash_combine\n                    // https://www.boost.org/doc/libs/1_55_0/doc/html/hash/reference.html#boost.hash_combine\n                    h ^= k + 0x9e3779b9 + (h << 6) + (h >>> 2);\n            }}\n            return h;\n        }\n\n        /**\n         * Converts to string.\n         *\n         * Returns:\n         *     The string representation of this `Tuple`.\n         */\n        string toString()() const\n        {\n            import std.array : appender;\n            auto app = appender!string();\n            this.toString((const(char)[] chunk) => app ~= chunk);\n            return app.data;\n        }\n\n        import std.format : FormatSpec;\n\n        /**\n         * Formats `Tuple` with either `%s`, `%(inner%)` or `%(inner%|sep%)`.\n         *\n         * $(TABLE2 Formats supported by Tuple,\n         * $(THEAD Format, Description)\n         * $(TROW $(P `%s`), $(P Format like `Tuple!(types)(elements formatted with %s each)`.))\n         * $(TROW $(P `%(inner%)`), $(P The format `inner` is applied the expanded `Tuple`$(COMMA) so\n         *      it may contain as many formats as the `Tuple` has fields.))\n         * $(TROW $(P `%(inner%|sep%)`), $(P The format `inner` is one format$(COMMA) that is applied\n         *      on all fields of the `Tuple`. The inner format must be compatible to all\n         *      of them.)))\n         *\n         * Params:\n         *     sink = A `char` accepting delegate\n         *     fmt = A $(REF FormatSpec, std,format)\n         */\n        void toString(DG)(scope DG sink) const\n        {\n            auto f = FormatSpec!char();\n            toString(sink, f);\n        }\n\n        /// ditto\n        void toString(DG, Char)(scope DG sink, const ref FormatSpec!Char fmt) const\n        {\n            import std.format : formatElement, formattedWrite, FormatException;\n            if (fmt.nested)\n            {\n                if (fmt.sep)\n                {\n                    foreach (i, Type; Types)\n                    {\n                        static if (i > 0)\n                        {\n                            sink(fmt.sep);\n                        }\n                        // TODO: Change this once formattedWrite() works for shared objects.\n                        static if (is(Type == class) && is(Type == shared))\n                        {\n                            sink(Type.stringof);\n                        }\n                        else\n                        {\n                            formattedWrite(sink, fmt.nested, this.field[i]);\n                        }\n                    }\n                }\n                else\n                {\n                    formattedWrite(sink, fmt.nested, staticMap!(sharedToString, this.expand));\n                }\n            }\n            else if (fmt.spec == 's')\n            {\n                enum header = Unqual!(typeof(this)).stringof ~ \"(\",\n                     footer = \")\",\n                     separator = \", \";\n                sink(header);\n                foreach (i, Type; Types)\n                {\n                    static if (i > 0)\n                    {\n                        sink(separator);\n                    }\n                    // TODO: Change this once formatElement() works for shared objects.\n                    static if (is(Type == class) && is(Type == shared))\n                    {\n                        sink(Type.stringof);\n                    }\n                    else\n                    {\n                        FormatSpec!Char f;\n                        formatElement(sink, field[i], f);\n                    }\n                }\n                sink(footer);\n            }\n            else\n            {\n                throw new FormatException(\n                    \"Expected '%s' or '%(...%)' or '%(...%|...%)' format specifier for type '\" ~\n                        Unqual!(typeof(this)).stringof ~ \"', not '%\" ~ fmt.spec ~ \"'.\");\n            }\n        }\n\n        ///\n        static if (Types.length == 0)\n        @safe unittest\n        {\n            import std.format : format;\n\n            Tuple!(int, double)[3] tupList = [ tuple(1, 1.0), tuple(2, 4.0), tuple(3, 9.0) ];\n\n            // Default format\n            assert(format(\"%s\", tuple(\"a\", 1)) == `Tuple!(string, int)(\"a\", 1)`);\n\n            // One Format for each individual component\n            assert(format(\"%(%#x v %.4f w %#x%)\", tuple(1, 1.0, 10))         == `0x1 v 1.0000 w 0xa`);\n            assert(format(  \"%#x v %.4f w %#x\"  , tuple(1, 1.0, 10).expand)  == `0x1 v 1.0000 w 0xa`);\n\n            // One Format for all components\n            assert(format(\"%(>%s<%| & %)\", tuple(\"abc\", 1, 2.3, [4, 5])) == `>abc< & >1< & >2.3< & >[4, 5]<`);\n\n            // Array of Tuples\n            assert(format(\"%(%(f(%d) = %.1f%);  %)\", tupList) == `f(1) = 1.0;  f(2) = 4.0;  f(3) = 9.0`);\n        }\n\n        ///\n        static if (Types.length == 0)\n        @safe unittest\n        {\n            import std.exception : assertThrown;\n            import std.format : format, FormatException;\n\n            // Error: %( %) missing.\n            assertThrown!FormatException(\n                format(\"%d, %f\", tuple(1, 2.0)) == `1, 2.0`\n            );\n\n            // Error: %( %| %) missing.\n            assertThrown!FormatException(\n                format(\"%d\", tuple(1, 2)) == `1, 2`\n            );\n\n            // Error: %d inadequate for double\n            assertThrown!FormatException(\n                format(\"%(%d%|, %)\", tuple(1, 2.0)) == `1, 2.0`\n            );\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    Tuple!(int, int) point;\n    // assign coordinates\n    point[0] = 5;\n    point[1] = 6;\n    // read coordinates\n    auto x = point[0];\n    auto y = point[1];\n}\n\n/**\n    `Tuple` members can be named. It is legal to mix named and unnamed\n    members. The method above is still applicable to all fields.\n */\n@safe unittest\n{\n    alias Entry = Tuple!(int, \"index\", string, \"value\");\n    Entry e;\n    e.index = 4;\n    e.value = \"Hello\";\n    assert(e[1] == \"Hello\");\n    assert(e[0] == 4);\n}\n\n/**\n    A `Tuple` with named fields is a distinct type from a `Tuple` with unnamed\n    fields, i.e. each naming imparts a separate type for the `Tuple`. Two\n    `Tuple`s differing in naming only are still distinct, even though they\n    might have the same structure.\n */\n@safe unittest\n{\n    Tuple!(int, \"x\", int, \"y\") point1;\n    Tuple!(int, int) point2;\n    assert(!is(typeof(point1) == typeof(point2)));\n}\n\n/// Use tuples as ranges\n@safe unittest\n{\n    import std.algorithm.iteration : sum;\n    import std.range : only;\n    auto t = tuple(1, 2);\n    assert(t.expand.only.sum == 3);\n}\n\n@safe unittest\n{\n    // Bugzilla 4582\n    static assert(!__traits(compiles, Tuple!(string, \"id\", int, \"id\")));\n    static assert(!__traits(compiles, Tuple!(string, \"str\", int, \"i\", string, \"str\", float)));\n}\n\n/// Concatenate tuples\n@safe unittest\n{\n    import std.meta : AliasSeq;\n    auto t = tuple(1, \"2\") ~ tuple(ushort(42), true);\n    static assert(is(t.Types == AliasSeq!(int, string, ushort, bool)));\n    assert(t[1] == \"2\");\n    assert(t[2] == 42);\n    assert(t[3] == true);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=14637\n// tuple concat\n@safe unittest\n{\n    auto t = tuple!\"foo\"(1.0) ~ tuple!\"bar\"(\"3\");\n    static assert(is(t.Types == AliasSeq!(double, string)));\n    static assert(t.fieldNames == tuple(\"foo\", \"bar\"));\n    assert(t.foo == 1.0);\n    assert(t.bar == \"3\");\n}\n\n// tuple concat\n@safe unittest\n{\n    auto t = tuple!\"foo\"(1.0) ~ \"3\";\n    static assert(is(t.Types == AliasSeq!(double, string)));\n    assert(t.foo == 1.0);\n    assert(t[1]== \"3\");\n}\n\n// tuple concat\n@safe unittest\n{\n    auto t = \"2\" ~ tuple!\"foo\"(1.0);\n    static assert(is(t.Types == AliasSeq!(string, double)));\n    assert(t.foo == 1.0);\n    assert(t[0]== \"2\");\n}\n\n// tuple concat\n@safe unittest\n{\n    auto t = \"2\" ~ tuple!\"foo\"(1.0) ~ tuple(42, 3.0f) ~ real(1) ~ \"a\";\n    static assert(is(t.Types == AliasSeq!(string, double, int, float, real, string)));\n    assert(t.foo == 1.0);\n    assert(t[0] == \"2\");\n    assert(t[1] == 1.0);\n    assert(t[2] == 42);\n    assert(t[3] == 3.0f);\n    assert(t[4] == 1.0);\n    assert(t[5] == \"a\");\n}\n\n// ensure that concatenation of tuples with non-distinct fields is forbidden\n@safe unittest\n{\n    static assert(!__traits(compiles,\n        tuple!(\"a\")(0) ~ tuple!(\"a\")(\"1\")));\n    static assert(!__traits(compiles,\n        tuple!(\"a\", \"b\")(0, 1) ~ tuple!(\"b\", \"a\")(\"3\", 1)));\n    static assert(!__traits(compiles,\n        tuple!(\"a\")(0) ~ tuple!(\"b\", \"a\")(\"3\", 1)));\n    static assert(!__traits(compiles,\n        tuple!(\"a1\", \"a\")(1.0, 0) ~ tuple!(\"a2\", \"a\")(\"3\", 0)));\n}\n\n// Ensure that Tuple comparison with non-const opEquals works\n@safe unittest\n{\n    static struct Bad\n    {\n        int a;\n\n        bool opEquals(Bad b)\n        {\n            return a == b.a;\n        }\n    }\n\n    auto t = Tuple!(int, Bad, string)(1, Bad(1), \"asdf\");\n\n    //Error: mutable method Bad.opEquals is not callable using a const object\n    assert(t == AliasSeq!(1, Bad(1), \"asdf\"));\n}\n\n/**\n    Creates a copy of a $(LREF Tuple) with its fields in _reverse order.\n\n    Params:\n        t = The `Tuple` to copy.\n\n    Returns:\n        A new `Tuple`.\n */\nauto reverse(T)(T t)\nif (isTuple!T)\n{\n    import std.meta : Reverse;\n    // @@@BUG@@@ Cannot be an internal function due to forward reference issues.\n\n    // @@@BUG@@@ 9929 Need 'this' when calling template with expanded tuple\n    // return tuple(Reverse!(t.expand));\n\n    ReverseTupleType!T result;\n    auto tup = t.expand;\n    result.expand = Reverse!tup;\n    return result;\n}\n\n///\n@safe unittest\n{\n    auto tup = tuple(1, \"2\");\n    assert(tup.reverse == tuple(\"2\", 1));\n}\n\n/* Get a Tuple type with the reverse specification of Tuple T. */\nprivate template ReverseTupleType(T)\nif (isTuple!T)\n{\n    static if (is(T : Tuple!A, A...))\n        alias ReverseTupleType = Tuple!(ReverseTupleSpecs!A);\n}\n\n/* Reverse the Specs of a Tuple. */\nprivate template ReverseTupleSpecs(T...)\n{\n    static if (T.length > 1)\n    {\n        static if (is(typeof(T[$-1]) : string))\n        {\n            alias ReverseTupleSpecs = AliasSeq!(T[$-2], T[$-1], ReverseTupleSpecs!(T[0 .. $-2]));\n        }\n        else\n        {\n            alias ReverseTupleSpecs = AliasSeq!(T[$-1], ReverseTupleSpecs!(T[0 .. $-1]));\n        }\n    }\n    else\n    {\n        alias ReverseTupleSpecs = T;\n    }\n}\n\n// ensure that internal Tuple unittests are compiled\n@safe unittest\n{\n    Tuple!() t;\n}\n\n@safe unittest\n{\n    import std.conv;\n    {\n        Tuple!(int, \"a\", int, \"b\") nosh;\n        static assert(nosh.length == 2);\n        nosh.a = 5;\n        nosh.b = 6;\n        assert(nosh.a == 5);\n        assert(nosh.b == 6);\n    }\n    {\n        Tuple!(short, double) b;\n        static assert(b.length == 2);\n        b[1] = 5;\n        auto a = Tuple!(int, real)(b);\n        assert(a[0] == 0 && a[1] == 5);\n        a = Tuple!(int, real)(1, 2);\n        assert(a[0] == 1 && a[1] == 2);\n        auto c = Tuple!(int, \"a\", double, \"b\")(a);\n        assert(c[0] == 1 && c[1] == 2);\n    }\n    {\n        Tuple!(int, real) nosh;\n        nosh[0] = 5;\n        nosh[1] = 0;\n        assert(nosh[0] == 5 && nosh[1] == 0);\n        assert(nosh.to!string == \"Tuple!(int, real)(5, 0)\", nosh.to!string);\n        Tuple!(int, int) yessh;\n        nosh = yessh;\n    }\n    {\n        class A {}\n        Tuple!(int, shared A) nosh;\n        nosh[0] = 5;\n        assert(nosh[0] == 5 && nosh[1] is null);\n        assert(nosh.to!string == \"Tuple!(int, shared(A))(5, shared(A))\");\n    }\n    {\n        Tuple!(int, string) t;\n        t[0] = 10;\n        t[1] = \"str\";\n        assert(t[0] == 10 && t[1] == \"str\");\n        assert(t.to!string == `Tuple!(int, string)(10, \"str\")`, t.to!string);\n    }\n    {\n        Tuple!(int, \"a\", double, \"b\") x;\n        static assert(x.a.offsetof == x[0].offsetof);\n        static assert(x.b.offsetof == x[1].offsetof);\n        x.b = 4.5;\n        x.a = 5;\n        assert(x[0] == 5 && x[1] == 4.5);\n        assert(x.a == 5 && x.b == 4.5);\n    }\n    // indexing\n    {\n        Tuple!(int, real) t;\n        static assert(is(typeof(t[0]) == int));\n        static assert(is(typeof(t[1]) == real));\n        int* p0 = &t[0];\n        real* p1 = &t[1];\n        t[0] = 10;\n        t[1] = -200.0L;\n        assert(*p0 == t[0]);\n        assert(*p1 == t[1]);\n    }\n    // slicing\n    {\n        Tuple!(int, \"x\", real, \"y\", double, \"z\", string) t;\n        t[0] = 10;\n        t[1] = 11;\n        t[2] = 12;\n        t[3] = \"abc\";\n        auto a = t.slice!(0, 3);\n        assert(a.length == 3);\n        assert(a.x == t.x);\n        assert(a.y == t.y);\n        assert(a.z == t.z);\n        auto b = t.slice!(2, 4);\n        assert(b.length == 2);\n        assert(b.z == t.z);\n        assert(b[1] == t[3]);\n    }\n    // nesting\n    {\n        Tuple!(Tuple!(int, real), Tuple!(string, \"s\")) t;\n        static assert(is(typeof(t[0]) == Tuple!(int, real)));\n        static assert(is(typeof(t[1]) == Tuple!(string, \"s\")));\n        static assert(is(typeof(t[0][0]) == int));\n        static assert(is(typeof(t[0][1]) == real));\n        static assert(is(typeof(t[1].s) == string));\n        t[0] = tuple(10, 20.0L);\n        t[1].s = \"abc\";\n        assert(t[0][0] == 10);\n        assert(t[0][1] == 20.0L);\n        assert(t[1].s == \"abc\");\n    }\n    // non-POD\n    {\n        static struct S\n        {\n            int count;\n            this(this) { ++count; }\n            ~this() { --count; }\n            void opAssign(S rhs) { count = rhs.count; }\n        }\n        Tuple!(S, S) ss;\n        Tuple!(S, S) ssCopy = ss;\n        assert(ssCopy[0].count == 1);\n        assert(ssCopy[1].count == 1);\n        ssCopy[1] = ssCopy[0];\n        assert(ssCopy[1].count == 2);\n    }\n    // bug 2800\n    {\n        static struct R\n        {\n            Tuple!(int, int) _front;\n            @property ref Tuple!(int, int) front() return { return _front;  }\n            @property bool empty() { return _front[0] >= 10; }\n            void popFront() { ++_front[0]; }\n        }\n        foreach (a; R())\n        {\n            static assert(is(typeof(a) == Tuple!(int, int)));\n            assert(0 <= a[0] && a[0] < 10);\n            assert(a[1] == 0);\n        }\n    }\n    // Construction with compatible elements\n    {\n        auto t1 = Tuple!(int, double)(1, 1);\n\n        // 8702\n        auto t8702a = tuple(tuple(1));\n        auto t8702b = Tuple!(Tuple!(int))(Tuple!(int)(1));\n    }\n    // Construction with compatible tuple\n    {\n        Tuple!(int, int) x;\n        x[0] = 10;\n        x[1] = 20;\n        Tuple!(int, \"a\", double, \"b\") y = x;\n        assert(y.a == 10);\n        assert(y.b == 20);\n        // incompatible\n        static assert(!__traits(compiles, Tuple!(int, int)(y)));\n    }\n    // 6275\n    {\n        const int x = 1;\n        auto t1 = tuple(x);\n        alias T = Tuple!(const(int));\n        auto t2 = T(1);\n    }\n    // 9431\n    {\n        alias T = Tuple!(int[1][]);\n        auto t = T([[10]]);\n    }\n    // 7666\n    {\n        auto tup = tuple(1, \"2\");\n        assert(tup.reverse == tuple(\"2\", 1));\n    }\n    {\n        Tuple!(int, \"x\", string, \"y\") tup = tuple(1, \"2\");\n        auto rev = tup.reverse;\n        assert(rev == tuple(\"2\", 1));\n        assert(rev.x == 1 && rev.y == \"2\");\n    }\n    {\n        Tuple!(wchar, dchar, int, \"x\", string, \"y\", char, byte, float) tup;\n        tup = tuple('a', 'b', 3, \"4\", 'c', cast(byte) 0x0D, 0.00);\n        auto rev = tup.reverse;\n        assert(rev == tuple(0.00, cast(byte) 0x0D, 'c', \"4\", 3, 'b', 'a'));\n        assert(rev.x == 3 && rev.y == \"4\");\n    }\n}\n@safe unittest\n{\n    // opEquals\n    {\n        struct Equ1 { bool opEquals(Equ1) { return true; } }\n        auto  tm1 = tuple(Equ1.init);\n        const tc1 = tuple(Equ1.init);\n        static assert( is(typeof(tm1 == tm1)));\n        static assert(!is(typeof(tm1 == tc1)));\n        static assert(!is(typeof(tc1 == tm1)));\n        static assert(!is(typeof(tc1 == tc1)));\n\n        struct Equ2 { bool opEquals(const Equ2) const { return true; } }\n        auto  tm2 = tuple(Equ2.init);\n        const tc2 = tuple(Equ2.init);\n        static assert( is(typeof(tm2 == tm2)));\n        static assert( is(typeof(tm2 == tc2)));\n        static assert( is(typeof(tc2 == tm2)));\n        static assert( is(typeof(tc2 == tc2)));\n\n        struct Equ3 { bool opEquals(T)(T) { return true; } }\n        auto  tm3 = tuple(Equ3.init);           // bugzilla 8686\n        const tc3 = tuple(Equ3.init);\n        static assert( is(typeof(tm3 == tm3)));\n        static assert( is(typeof(tm3 == tc3)));\n        static assert(!is(typeof(tc3 == tm3)));\n        static assert(!is(typeof(tc3 == tc3)));\n\n        struct Equ4 { bool opEquals(T)(T) const { return true; } }\n        auto  tm4 = tuple(Equ4.init);\n        const tc4 = tuple(Equ4.init);\n        static assert( is(typeof(tm4 == tm4)));\n        static assert( is(typeof(tm4 == tc4)));\n        static assert( is(typeof(tc4 == tm4)));\n        static assert( is(typeof(tc4 == tc4)));\n    }\n    // opCmp\n    {\n        struct Cmp1 { int opCmp(Cmp1) { return 0; } }\n        auto  tm1 = tuple(Cmp1.init);\n        const tc1 = tuple(Cmp1.init);\n        static assert( is(typeof(tm1 < tm1)));\n        static assert(!is(typeof(tm1 < tc1)));\n        static assert(!is(typeof(tc1 < tm1)));\n        static assert(!is(typeof(tc1 < tc1)));\n\n        struct Cmp2 { int opCmp(const Cmp2) const { return 0; } }\n        auto  tm2 = tuple(Cmp2.init);\n        const tc2 = tuple(Cmp2.init);\n        static assert( is(typeof(tm2 < tm2)));\n        static assert( is(typeof(tm2 < tc2)));\n        static assert( is(typeof(tc2 < tm2)));\n        static assert( is(typeof(tc2 < tc2)));\n\n        struct Cmp3 { int opCmp(T)(T) { return 0; } }\n        auto  tm3 = tuple(Cmp3.init);\n        const tc3 = tuple(Cmp3.init);\n        static assert( is(typeof(tm3 < tm3)));\n        static assert( is(typeof(tm3 < tc3)));\n        static assert(!is(typeof(tc3 < tm3)));\n        static assert(!is(typeof(tc3 < tc3)));\n\n        struct Cmp4 { int opCmp(T)(T) const { return 0; } }\n        auto  tm4 = tuple(Cmp4.init);\n        const tc4 = tuple(Cmp4.init);\n        static assert( is(typeof(tm4 < tm4)));\n        static assert( is(typeof(tm4 < tc4)));\n        static assert( is(typeof(tc4 < tm4)));\n        static assert( is(typeof(tc4 < tc4)));\n    }\n    // Bugzilla 14890\n    static void test14890(inout int[] dummy)\n    {\n        alias V = Tuple!(int, int);\n\n                    V mv;\n              const V cv;\n          immutable V iv;\n              inout V wv;   // OK <- NG\n        inout const V wcv;  // OK <- NG\n\n        static foreach (v1; AliasSeq!(mv, cv, iv, wv, wcv))\n        static foreach (v2; AliasSeq!(mv, cv, iv, wv, wcv))\n        {\n            assert(!(v1 < v2));\n        }\n    }\n    {\n        int[2] ints = [ 1, 2 ];\n        Tuple!(int, int) t = ints;\n        assert(t[0] == 1 && t[1] == 2);\n        Tuple!(long, uint) t2 = ints;\n        assert(t2[0] == 1 && t2[1] == 2);\n    }\n}\n@safe unittest\n{\n    auto t1 = Tuple!(int, \"x\", string, \"y\")(1, \"a\");\n    assert(t1.x == 1);\n    assert(t1.y == \"a\");\n    void foo(Tuple!(int, string) t2) {}\n    foo(t1);\n\n    Tuple!(int, int)[] arr;\n    arr ~= tuple(10, 20); // OK\n    arr ~= Tuple!(int, \"x\", int, \"y\")(10, 20); // NG -> OK\n\n    static assert(is(typeof(Tuple!(int, \"x\", string, \"y\").tupleof) ==\n                     typeof(Tuple!(int,      string     ).tupleof)));\n}\n@safe unittest\n{\n    // Bugzilla 10686\n    immutable Tuple!(int) t1;\n    auto r1 = t1[0]; // OK\n    immutable Tuple!(int, \"x\") t2;\n    auto r2 = t2[0]; // error\n}\n@safe unittest\n{\n    import std.exception : assertCTFEable;\n\n    // Bugzilla 10218\n    assertCTFEable!(\n    {\n        auto t = tuple(1);\n        t = tuple(2);   // assignment\n    });\n}\n@safe unittest\n{\n    class Foo{}\n    Tuple!(immutable(Foo)[]) a;\n}\n\n@safe unittest\n{\n    //Test non-assignable\n    static struct S\n    {\n        int* p;\n    }\n    alias IS = immutable S;\n    static assert(!isAssignable!IS);\n\n    auto s = IS.init;\n\n    alias TIS = Tuple!IS;\n    TIS a = tuple(s);\n    TIS b = a;\n\n    alias TISIS = Tuple!(IS, IS);\n    TISIS d = tuple(s, s);\n    IS[2] ss;\n    TISIS e = TISIS(ss);\n}\n\n// Bugzilla #9819\n@safe unittest\n{\n    alias T = Tuple!(int, \"x\", double, \"foo\");\n    static assert(T.fieldNames[0] == \"x\");\n    static assert(T.fieldNames[1] == \"foo\");\n\n    alias Fields = Tuple!(int, \"id\", string, float);\n    static assert(Fields.fieldNames == AliasSeq!(\"id\", \"\", \"\"));\n}\n\n// Bugzilla 13837\n@safe unittest\n{\n    // New behaviour, named arguments.\n    static assert(is(\n        typeof(tuple!(\"x\")(1)) == Tuple!(int, \"x\")));\n    static assert(is(\n        typeof(tuple!(\"x\")(1.0)) == Tuple!(double, \"x\")));\n    static assert(is(\n        typeof(tuple!(\"x\")(\"foo\")) == Tuple!(string, \"x\")));\n    static assert(is(\n        typeof(tuple!(\"x\", \"y\")(1, 2.0)) == Tuple!(int, \"x\", double, \"y\")));\n\n    auto a = tuple!(\"a\", \"b\", \"c\")(\"1\", 2, 3.0f);\n    static assert(is(typeof(a.a) == string));\n    static assert(is(typeof(a.b) == int));\n    static assert(is(typeof(a.c) == float));\n\n    // Old behaviour, but with explicit type parameters.\n    static assert(is(\n        typeof(tuple!(int, double)(1, 2.0)) == Tuple!(int, double)));\n    static assert(is(\n        typeof(tuple!(const int)(1)) == Tuple!(const int)));\n    static assert(is(\n        typeof(tuple()) == Tuple!()));\n\n    // Nonsensical behaviour\n    static assert(!__traits(compiles, tuple!(1)(2)));\n    static assert(!__traits(compiles, tuple!(\"x\")(1, 2)));\n    static assert(!__traits(compiles, tuple!(\"x\", \"y\")(1)));\n    static assert(!__traits(compiles, tuple!(\"x\")()));\n    static assert(!__traits(compiles, tuple!(\"x\", int)(2)));\n}\n\n@safe unittest\n{\n    class C {}\n    Tuple!(Rebindable!(const C)) a;\n    Tuple!(const C) b;\n    a = b;\n}\n\n@nogc @safe unittest\n{\n    alias T = Tuple!(string, \"s\");\n    T x;\n    x = T.init;\n}\n\n@safe unittest\n{\n    import std.format : format, FormatException;\n    import std.exception : assertThrown;\n\n    //enum tupStr = tuple(1, 1.0).toString; // toString is *impure*.\n    //static assert(tupStr == `Tuple!(int, double)(1, 1)`);\n}\n\n// Issue 17803, parte uno\n@safe unittest\n{\n    auto a = tuple(3, \"foo\");\n    assert(__traits(compiles, { a = (a = a); }));\n}\n// Ditto\n@safe unittest\n{\n    Tuple!(int[]) a, b, c;\n    a = tuple([0, 1, 2]);\n    c = b = a;\n    assert(a[0].length == b[0].length && b[0].length == c[0].length);\n    assert(a[0].ptr == b[0].ptr && b[0].ptr == c[0].ptr);\n}\n\n/**\n    Constructs a $(LREF Tuple) object instantiated and initialized according to\n    the given arguments.\n\n    Params:\n        Names = An optional list of strings naming each successive field of the `Tuple`\n                or a list of types that the elements are being casted to.\n                For a list of names,\n                each name matches up with the corresponding field given by `Args`.\n                A name does not have to be provided for every field, but as\n                the names must proceed in order, it is not possible to skip\n                one field and name the next after it.\n                For a list of types,\n                there must be exactly as many types as parameters.\n*/\ntemplate tuple(Names...)\n{\n    /**\n    Params:\n        args = Values to initialize the `Tuple` with. The `Tuple`'s type will\n               be inferred from the types of the values given.\n\n    Returns:\n        A new `Tuple` with its type inferred from the arguments given.\n     */\n    auto tuple(Args...)(Args args)\n    {\n        static if (Names.length == 0)\n        {\n            // No specified names, just infer types from Args...\n            return Tuple!Args(args);\n        }\n        else static if (!is(typeof(Names[0]) : string))\n        {\n            // Names[0] isn't a string, must be explicit types.\n            return Tuple!Names(args);\n        }\n        else\n        {\n            // Names[0] is a string, so must be specifying names.\n            static assert(Names.length == Args.length,\n                \"Insufficient number of names given.\");\n\n            // Interleave(a, b).and(c, d) == (a, c, b, d)\n            // This is to get the interleaving of types and names for Tuple\n            // e.g. Tuple!(int, \"x\", string, \"y\")\n            template Interleave(A...)\n            {\n                template and(B...) if (B.length == 1)\n                {\n                    alias and = AliasSeq!(A[0], B[0]);\n                }\n\n                template and(B...) if (B.length != 1)\n                {\n                    alias and = AliasSeq!(A[0], B[0],\n                        Interleave!(A[1..$]).and!(B[1..$]));\n                }\n            }\n            return Tuple!(Interleave!(Args).and!(Names))(args);\n        }\n    }\n}\n\n///\n@safe unittest\n{\n    auto value = tuple(5, 6.7, \"hello\");\n    assert(value[0] == 5);\n    assert(value[1] == 6.7);\n    assert(value[2] == \"hello\");\n\n    // Field names can be provided.\n    auto entry = tuple!(\"index\", \"value\")(4, \"Hello\");\n    assert(entry.index == 4);\n    assert(entry.value == \"Hello\");\n}\n\n/**\n    Returns `true` if and only if `T` is an instance of `std.typecons.Tuple`.\n\n    Params:\n        T = The type to check.\n\n    Returns:\n        true if `T` is a `Tuple` type, false otherwise.\n */\nenum isTuple(T) = __traits(compiles,\n                           {\n                               void f(Specs...)(Tuple!Specs tup) {}\n                               f(T.init);\n                           } );\n\n///\n@safe unittest\n{\n    static assert(isTuple!(Tuple!()));\n    static assert(isTuple!(Tuple!(int)));\n    static assert(isTuple!(Tuple!(int, real, string)));\n    static assert(isTuple!(Tuple!(int, \"x\", real, \"y\")));\n    static assert(isTuple!(Tuple!(int, Tuple!(real), string)));\n}\n\n@safe unittest\n{\n    static assert(isTuple!(const Tuple!(int)));\n    static assert(isTuple!(immutable Tuple!(int)));\n\n    static assert(!isTuple!(int));\n    static assert(!isTuple!(const int));\n\n    struct S {}\n    static assert(!isTuple!(S));\n}\n\n// used by both Rebindable and UnqualRef\nprivate mixin template RebindableCommon(T, U, alias This)\nif (is(T == class) || is(T == interface) || isAssociativeArray!T)\n{\n    private union\n    {\n        T original;\n        U stripped;\n    }\n\n    void opAssign(T another) @trusted pure nothrow @nogc\n    {\n        stripped = cast(U) another;\n    }\n\n    void opAssign(typeof(this) another) @trusted pure nothrow @nogc\n    {\n        stripped = another.stripped;\n    }\n\n    static if (is(T == const U) && is(T == const shared U))\n    {\n        // safely assign immutable to const / const shared\n        void opAssign(This!(immutable U) another) @trusted pure nothrow @nogc\n        {\n            stripped = another.stripped;\n        }\n    }\n\n    this(T initializer) @trusted pure nothrow @nogc\n    {\n        opAssign(initializer);\n    }\n\n    @property inout(T) get() @trusted pure nothrow @nogc inout\n    {\n        return original;\n    }\n\n    bool opEquals()(auto ref const(typeof(this)) rhs) const\n    {\n        // Must forward explicitly because 'stripped' is part of a union.\n        // The necessary 'toHash' is forwarded to the class via alias this.\n        return stripped == rhs.stripped;\n    }\n\n    bool opEquals(const(U) rhs) const\n    {\n        return stripped == rhs;\n    }\n\n    alias get this;\n}\n\n/**\n`Rebindable!(T)` is a simple, efficient wrapper that behaves just\nlike an object of type `T`, except that you can reassign it to\nrefer to another object. For completeness, `Rebindable!(T)` aliases\nitself away to `T` if `T` is a non-const object type.\n\nYou may want to use `Rebindable` when you want to have mutable\nstorage referring to `const` objects, for example an array of\nreferences that must be sorted in place. `Rebindable` does not\nbreak the soundness of D's type system and does not incur any of the\nrisks usually associated with `cast`.\n\nParams:\n    T = An object, interface, array slice type, or associative array type.\n */\ntemplate Rebindable(T)\nif (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T)\n{\n    static if (is(T == const U, U) || is(T == immutable U, U))\n    {\n        static if (isDynamicArray!T)\n        {\n            import std.range.primitives : ElementEncodingType;\n            alias Rebindable = const(ElementEncodingType!T)[];\n        }\n        else\n        {\n            struct Rebindable\n            {\n                mixin RebindableCommon!(T, U, Rebindable);\n            }\n        }\n    }\n    else\n    {\n        alias Rebindable = T;\n    }\n}\n\n///Regular `const` object references cannot be reassigned.\n@safe unittest\n{\n    class Widget { int x; int y() @safe const { return x; } }\n    const a = new Widget;\n    // Fine\n    a.y();\n    // error! can't modify const a\n    // a.x = 5;\n    // error! can't modify const a\n    // a = new Widget;\n}\n\n/**\n    However, `Rebindable!(Widget)` does allow reassignment,\n    while otherwise behaving exactly like a $(D const Widget).\n */\n@safe unittest\n{\n    class Widget { int x; int y() const @safe { return x; } }\n    auto a = Rebindable!(const Widget)(new Widget);\n    // Fine\n    a.y();\n    // error! can't modify const a\n    // a.x = 5;\n    // Fine\n    a = new Widget;\n}\n\n@safe unittest // issue 16054\n{\n    Rebindable!(immutable Object) r;\n    static assert(__traits(compiles, r.get()));\n    static assert(!__traits(compiles, &r.get()));\n}\n\n@safe unittest\n{\n    class CustomToHash\n    {\n        override size_t toHash() const nothrow @trusted { return 42; }\n    }\n    Rebindable!(immutable(CustomToHash)) a = new immutable CustomToHash();\n    assert(a.toHash() == 42, \"Rebindable!A should offer toHash()\"\n        ~ \" by forwarding to A.toHash().\");\n}\n\n@system unittest // issue 18615: Rebindable!A should use A.opEquals\n{\n    class CustomOpEq\n    {\n        int x;\n        override bool opEquals(Object rhsObj)\n        {\n            if (auto rhs = cast(const(CustomOpEq)) rhsObj)\n                return this.x == rhs.x;\n            else\n                return false;\n        }\n    }\n    CustomOpEq a = new CustomOpEq();\n    CustomOpEq b = new CustomOpEq();\n    assert(a !is b);\n    assert(a == b, \"a.x == b.x should be true (0 == 0).\");\n\n    Rebindable!(const(CustomOpEq)) ra = a;\n    Rebindable!(const(CustomOpEq)) rb = b;\n    assert(ra !is rb);\n    assert(ra == rb, \"Rebindable should use CustomOpEq's opEquals, not 'is'.\");\n    assert(ra == b, \"Rebindable!(someQualifier(A)) should be comparable\"\n        ~ \" against const(A) via A.opEquals.\");\n    assert(a == rb, \"Rebindable!(someQualifier(A)) should be comparable\"\n        ~ \" against const(A) via A.opEquals.\");\n\n    b.x = 1;\n    assert(a != b);\n    assert(ra != b, \"Rebindable!(someQualifier(A)) should be comparable\"\n        ~ \" against const(A) via A.opEquals.\");\n    assert(a != rb, \"Rebindable!(someQualifier(A)) should be comparable\"\n        ~ \" against const(A) via A.opEquals.\");\n\n    Rebindable!(const(Object)) o1 = new Object();\n    Rebindable!(const(Object)) o2 = new Object();\n    assert(o1 !is o2);\n    assert(o1 == o1, \"When the class doesn't provide its own opEquals,\"\n        ~ \" Rebindable treats 'a == b' as 'a is b' like Object.opEquals.\");\n    assert(o1 != o2, \"When the class doesn't provide its own opEquals,\"\n        ~ \" Rebindable treats 'a == b' as 'a is b' like Object.opEquals.\");\n    assert(o1 != new Object(), \"Rebindable!(const(Object)) should be\"\n        ~ \" comparable against Object itself and use Object.opEquals.\");\n}\n/**\nConvenience function for creating a `Rebindable` using automatic type\ninference.\n\nParams:\n    obj = A reference to an object, interface, associative array, or an array slice\n          to initialize the `Rebindable` with.\n\nReturns:\n    A newly constructed `Rebindable` initialized with the given reference.\n*/\nRebindable!T rebindable(T)(T obj)\nif (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T)\n{\n    typeof(return) ret;\n    ret = obj;\n    return ret;\n}\n\n///\n@system unittest\n{\n    class C\n    {\n        int payload;\n        this(int p) { payload = p; }\n    }\n    const c = new C(1);\n\n    auto c2 = c.rebindable;\n    assert(c2.payload == 1);\n    // passing Rebindable to rebindable\n    c2 = c2.rebindable;\n\n    c2 = new C(2);\n    assert(c2.payload == 2);\n\n    const c3 = c2.get;\n    assert(c3.payload == 2);\n}\n\n/**\nThis function simply returns the `Rebindable` object passed in.  It's useful\nin generic programming cases when a given object may be either a regular\n`class` or a `Rebindable`.\n\nParams:\n    obj = An instance of Rebindable!T.\n\nReturns:\n    `obj` without any modification.\n*/\nRebindable!T rebindable(T)(Rebindable!T obj)\n{\n    return obj;\n}\n\n// TODO: remove me once the rebindable overloads have been joined\n///\n@system unittest\n{\n    class C\n    {\n        int payload;\n        this(int p) { payload = p; }\n    }\n    const c = new C(1);\n\n    auto c2 = c.rebindable;\n    assert(c2.payload == 1);\n    // passing Rebindable to rebindable\n    c2 = c2.rebindable;\n    assert(c2.payload == 1);\n}\n\n@system unittest\n{\n    interface CI { int foo() const; }\n    class C : CI {\n      int foo() const { return 42; }\n      @property int bar() const { return 23; }\n    }\n    Rebindable!(C) obj0;\n    static assert(is(typeof(obj0) == C));\n\n    Rebindable!(const(C)) obj1;\n    static assert(is(typeof(obj1.get) == const(C)), typeof(obj1.get).stringof);\n    static assert(is(typeof(obj1.stripped) == C));\n    obj1 = new C;\n    assert(obj1.get !is null);\n    obj1 = new const(C);\n    assert(obj1.get !is null);\n\n    Rebindable!(immutable(C)) obj2;\n    static assert(is(typeof(obj2.get) == immutable(C)));\n    static assert(is(typeof(obj2.stripped) == C));\n    obj2 = new immutable(C);\n    assert(obj1.get !is null);\n\n    // test opDot\n    assert(obj2.foo() == 42);\n    assert(obj2.bar == 23);\n\n    interface I { final int foo() const { return 42; } }\n    Rebindable!(I) obj3;\n    static assert(is(typeof(obj3) == I));\n\n    Rebindable!(const I) obj4;\n    static assert(is(typeof(obj4.get) == const I));\n    static assert(is(typeof(obj4.stripped) == I));\n    static assert(is(typeof(obj4.foo()) == int));\n    obj4 = new class I {};\n\n    Rebindable!(immutable C) obj5i;\n    Rebindable!(const C) obj5c;\n    obj5c = obj5c;\n    obj5c = obj5i;\n    obj5i = obj5i;\n    static assert(!__traits(compiles, obj5i = obj5c));\n\n    // Test the convenience functions.\n    auto obj5convenience = rebindable(obj5i);\n    assert(obj5convenience is obj5i);\n\n    auto obj6 = rebindable(new immutable(C));\n    static assert(is(typeof(obj6) == Rebindable!(immutable C)));\n    assert(obj6.foo() == 42);\n\n    auto obj7 = rebindable(new C);\n    CI interface1 = obj7;\n    auto interfaceRebind1 = rebindable(interface1);\n    assert(interfaceRebind1.foo() == 42);\n\n    const interface2 = interface1;\n    auto interfaceRebind2 = rebindable(interface2);\n    assert(interfaceRebind2.foo() == 42);\n\n    auto arr = [1,2,3,4,5];\n    const arrConst = arr;\n    assert(rebindable(arr) == arr);\n    assert(rebindable(arrConst) == arr);\n\n    // Issue 7654\n    immutable(char[]) s7654;\n    Rebindable!(typeof(s7654)) r7654 = s7654;\n\n    static foreach (T; AliasSeq!(char, wchar, char, int))\n    {\n        static assert(is(Rebindable!(immutable(T[])) == immutable(T)[]));\n        static assert(is(Rebindable!(const(T[])) == const(T)[]));\n        static assert(is(Rebindable!(T[]) == T[]));\n    }\n\n    // Issue 12046\n    static assert(!__traits(compiles, Rebindable!(int[1])));\n    static assert(!__traits(compiles, Rebindable!(const int[1])));\n\n    // Pull request 3341\n    Rebindable!(immutable int[int]) pr3341 = [123:345];\n    assert(pr3341[123] == 345);\n    immutable int[int] pr3341_aa = [321:543];\n    pr3341 = pr3341_aa;\n    assert(pr3341[321] == 543);\n    assert(rebindable(pr3341_aa)[321] == 543);\n}\n\n/**\n    Similar to `Rebindable!(T)` but strips all qualifiers from the reference as\n    opposed to just constness / immutability. Primary intended use case is with\n    shared (having thread-local reference to shared class data)\n\n    Params:\n        T = A class or interface type.\n */\ntemplate UnqualRef(T)\nif (is(T == class) || is(T == interface))\n{\n    static if (is(T == const U, U)\n        || is(T == immutable U, U)\n        || is(T == shared U, U)\n        || is(T == const shared U, U))\n    {\n        struct UnqualRef\n        {\n            mixin RebindableCommon!(T, U, UnqualRef);\n        }\n    }\n    else\n    {\n        alias UnqualRef = T;\n    }\n}\n\n///\n@system unittest\n{\n    class Data {}\n\n    static shared(Data) a;\n    static UnqualRef!(shared Data) b;\n\n    import core.thread;\n\n    auto thread = new core.thread.Thread({\n        a = new shared Data();\n        b = new shared Data();\n    });\n\n    thread.start();\n    thread.join();\n\n    assert(a !is null);\n    assert(b is null);\n}\n\n@safe unittest\n{\n    class C { }\n    alias T = UnqualRef!(const shared C);\n    static assert(is(typeof(T.stripped) == C));\n}\n\n\n\n/**\n  Order the provided members to minimize size while preserving alignment.\n  Alignment is not always optimal for 80-bit reals, nor for structs declared\n  as align(1).\n\n  Params:\n      E = A list of the types to be aligned, representing fields\n          of an aggregate such as a `struct` or `class`.\n\n      names = The names of the fields that are to be aligned.\n\n  Returns:\n      A string to be mixed in to an aggregate, such as a `struct` or `class`.\n*/\nstring alignForSize(E...)(const char[][] names...)\n{\n    // Sort all of the members by .alignof.\n    // BUG: Alignment is not always optimal for align(1) structs\n    // or 80-bit reals or 64-bit primitives on x86.\n    // TRICK: Use the fact that .alignof is always a power of 2,\n    // and maximum 16 on extant systems. Thus, we can perform\n    // a very limited radix sort.\n    // Contains the members with .alignof = 64,32,16,8,4,2,1\n\n    assert(E.length == names.length,\n        \"alignForSize: There should be as many member names as the types\");\n\n    string[7] declaration = [\"\", \"\", \"\", \"\", \"\", \"\", \"\"];\n\n    foreach (i, T; E)\n    {\n        auto a = T.alignof;\n        auto k = a >= 64? 0 : a >= 32? 1 : a >= 16? 2 : a >= 8? 3 : a >= 4? 4 : a >= 2? 5 : 6;\n        declaration[k] ~= T.stringof ~ \" \" ~ names[i] ~ \";\\n\";\n    }\n\n    auto s = \"\";\n    foreach (decl; declaration)\n        s ~= decl;\n    return s;\n}\n\n///\n@safe unittest\n{\n    struct Banner {\n        mixin(alignForSize!(byte[6], double)([\"name\", \"height\"]));\n    }\n}\n\n@safe unittest\n{\n    enum x = alignForSize!(int[], char[3], short, double[5])(\"x\", \"y\",\"z\", \"w\");\n    struct Foo { int x; }\n    enum y = alignForSize!(ubyte, Foo, double)(\"x\", \"y\", \"z\");\n\n    enum passNormalX = x == \"double[5] w;\\nint[] x;\\nshort z;\\nchar[3] y;\\n\";\n    enum passNormalY = y == \"double z;\\nFoo y;\\nubyte x;\\n\";\n\n    enum passAbnormalX = x == \"int[] x;\\ndouble[5] w;\\nshort z;\\nchar[3] y;\\n\";\n    enum passAbnormalY = y == \"Foo y;\\ndouble z;\\nubyte x;\\n\";\n    // ^ blame http://d.puremagic.com/issues/show_bug.cgi?id=231\n\n    static assert(passNormalX || passAbnormalX && double.alignof <= (int[]).alignof);\n    static assert(passNormalY || passAbnormalY && double.alignof <= int.alignof);\n}\n\n// Issue 12914\n@safe unittest\n{\n    immutable string[] fieldNames = [\"x\", \"y\"];\n    struct S\n    {\n        mixin(alignForSize!(byte, int)(fieldNames));\n    }\n}\n\n/**\nDefines a value paired with a distinctive \"null\" state that denotes\nthe absence of a value. If default constructed, a $(D\nNullable!T) object starts in the null state. Assigning it renders it\nnon-null. Calling `nullify` can nullify it again.\n\nPractically `Nullable!T` stores a `T` and a `bool`.\n */\nstruct Nullable(T)\n{\n    private union DontCallDestructorT\n    {\n        T payload;\n    }\n\n    private DontCallDestructorT _value = DontCallDestructorT.init;\n\n    private bool _isNull = true;\n\n/**\nConstructor initializing `this` with `value`.\n\nParams:\n    value = The value to initialize this `Nullable` with.\n */\n    this(inout T value) inout\n    {\n        _value.payload = value;\n        _isNull = false;\n    }\n\n    static if (is(T == struct) && hasElaborateDestructor!T)\n    {\n        ~this()\n        {\n            if (!_isNull)\n            {\n                destroy(_value.payload);\n            }\n        }\n    }\n\n    /**\n      If they are both null, then they are equal. If one is null and the other\n      is not, then they are not equal. If they are both non-null, then they are\n      equal if their values are equal.\n      */\n    bool opEquals()(auto ref const(typeof(this)) rhs) const\n    {\n        if (_isNull)\n            return rhs._isNull;\n        if (rhs._isNull)\n            return false;\n        return _value.payload == rhs._value.payload;\n    }\n\n    /// Ditto\n    bool opEquals(U)(auto ref const(U) rhs) const\n    if (is(typeof(this.get == rhs)))\n    {\n        return _isNull ? false : rhs == _value.payload;\n    }\n\n    ///\n    @safe unittest\n    {\n        Nullable!int empty;\n        Nullable!int a = 42;\n        Nullable!int b = 42;\n        Nullable!int c = 27;\n\n        assert(empty == empty);\n        assert(empty == Nullable!int.init);\n        assert(empty != a);\n        assert(empty != b);\n        assert(empty != c);\n\n        assert(a == b);\n        assert(a != c);\n\n        assert(empty != 42);\n        assert(a == 42);\n        assert(c != 42);\n    }\n\n    @safe unittest\n    {\n        // Test constness\n        immutable Nullable!int a = 42;\n        Nullable!int b = 42;\n        immutable Nullable!int c = 29;\n        Nullable!int d = 29;\n        immutable e = 42;\n        int f = 29;\n        assert(a == a);\n        assert(a == b);\n        assert(a != c);\n        assert(a != d);\n        assert(a == e);\n        assert(a != f);\n\n        // Test rvalue\n        assert(a == const Nullable!int(42));\n        assert(a != Nullable!int(29));\n    }\n\n    // Issue 17482\n    @system unittest\n    {\n        import std.variant : Variant;\n        Nullable!Variant a = Variant(12);\n        assert(a == 12);\n        Nullable!Variant e;\n        assert(e != 12);\n    }\n\n    size_t toHash() const @safe nothrow\n    {\n        return _isNull ? 0 : typeid(T).getHash(&_value.payload);\n    }\n\n    /**\n     * Gives the string `\"Nullable.null\"` if `isNull` is `true`. Otherwise, the\n     * result is equivalent to calling $(REF formattedWrite, std,format) on the\n     * underlying value.\n     *\n     * Params:\n     *     writer = A `char` accepting\n     *     $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)\n     *     fmt = A $(REF FormatSpec, std,format) which is used to represent\n     *     the value if this Nullable is not null\n     * Returns:\n     *     A `string` if `writer` and `fmt` are not set; `void` otherwise.\n     */\n    string toString()\n    {\n        import std.array : appender;\n        auto app = appender!string();\n        auto spec = singleSpec(\"%s\");\n        toString(app, spec);\n        return app.data;\n    }\n\n    /// ditto\n    void toString(W)(ref W writer, const ref FormatSpec!char fmt)\n    if (isOutputRange!(W, char))\n    {\n        import std.range.primitives : put;\n        if (isNull)\n            put(writer, \"Nullable.null\");\n        else\n            formatValue(writer, _value.payload, fmt);\n    }\n\n    //@@@DEPRECATED_2.086@@@\n    deprecated(\"To be removed after 2.086. Please use the output range overload instead.\")\n    void toString()(scope void delegate(const(char)[]) sink, const ref FormatSpec!char fmt)\n    {\n        if (isNull)\n        {\n            sink.formatValue(\"Nullable.null\", fmt);\n        }\n        else\n        {\n            sink.formatValue(_value.payload, fmt);\n        }\n    }\n\n    // Issue 14940\n    //@@@DEPRECATED_2.086@@@\n    deprecated(\"To be removed after 2.086. Please use the output range overload instead.\")\n    void toString()(scope void delegate(const(char)[]) @safe sink, const ref FormatSpec!char fmt)\n    {\n        if (isNull)\n        {\n            sink.formatValue(\"Nullable.null\", fmt);\n        }\n        else\n        {\n            sink.formatValue(_value.payload, fmt);\n        }\n    }\n\n/**\nCheck if `this` is in the null state.\n\nReturns:\n    true $(B iff) `this` is in the null state, otherwise false.\n */\n    @property bool isNull() const @safe pure nothrow\n    {\n        return _isNull;\n    }\n\n///\n@safe unittest\n{\n    Nullable!int ni;\n    assert(ni.isNull);\n\n    ni = 0;\n    assert(!ni.isNull);\n}\n\n// Issue 14940\n@safe unittest\n{\n    import std.array : appender;\n    import std.format : formattedWrite;\n\n    auto app = appender!string();\n    Nullable!int a = 1;\n    formattedWrite(app, \"%s\", a);\n    assert(app.data == \"1\");\n}\n\n/**\nForces `this` to the null state.\n */\n    void nullify()()\n    {\n        static if (is(T == class) || is(T == interface))\n            _value.payload = null;\n        else\n            .destroy(_value.payload);\n        _isNull = true;\n    }\n\n///\n@safe unittest\n{\n    Nullable!int ni = 0;\n    assert(!ni.isNull);\n\n    ni.nullify();\n    assert(ni.isNull);\n}\n\n/**\nAssigns `value` to the internally-held state. If the assignment\nsucceeds, `this` becomes non-null.\n\nParams:\n    value = A value of type `T` to assign to this `Nullable`.\n */\n    void opAssign()(T value)\n    {\n        import std.algorithm.mutation : moveEmplace, move;\n\n        // the lifetime of the value in copy shall be managed by\n        // this Nullable, so we must avoid calling its destructor.\n        auto copy = DontCallDestructorT(value);\n\n        if (_isNull)\n        {\n            // trusted since payload is known to be T.init here.\n            () @trusted { moveEmplace(copy.payload, _value.payload); }();\n        }\n        else\n        {\n            move(copy.payload, _value.payload);\n        }\n        _isNull = false;\n    }\n\n/**\n    If this `Nullable` wraps a type that already has a null value\n    (such as a pointer), then assigning the null value to this\n    `Nullable` is no different than assigning any other value of\n    type `T`, and the resulting code will look very strange. It\n    is strongly recommended that this be avoided by instead using\n    the version of `Nullable` that takes an additional `nullValue`\n    template argument.\n */\n@safe unittest\n{\n    //Passes\n    Nullable!(int*) npi;\n    assert(npi.isNull);\n\n    //Passes?!\n    npi = null;\n    assert(!npi.isNull);\n}\n\n/**\nGets the value if not null. If `this` is in the null state, and the optional\nparameter `fallback` was provided, it will be returned. Without `fallback`,\ncalling `get` with a null state is invalid.\nThis function is also called for the implicit conversion to `T`.\n\nParams:\n    fallback = the value to return in case the `Nullable` is null.\n\nReturns:\n    The value held internally by this `Nullable`.\n */\n    @property ref inout(T) get() inout @safe pure nothrow\n    {\n        enum message = \"Called `get' on null Nullable!\" ~ T.stringof ~ \".\";\n        assert(!isNull, message);\n        return _value.payload;\n    }\n\n    /// ditto\n    @property get(U)(inout(U) fallback) inout @safe pure nothrow\n    {\n        return isNull ? fallback : _value.payload;\n    }\n\n///\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.exception : assertThrown, assertNotThrown;\n\n    Nullable!int ni;\n    int i = 42;\n    //`get` is implicitly called. Will throw\n    //an AssertError in non-release mode\n    assertThrown!AssertError(i = ni);\n    assert(i == 42);\n\n    ni = 5;\n    assertNotThrown!AssertError(i = ni);\n    assert(i == 5);\n}\n\n///\n@safe pure nothrow unittest\n{\n    int i = 42;\n    Nullable!int ni2;\n    int x = ni2.get(i);\n    assert(x == i);\n\n    ni2 = 7;\n    x = ni2.get(i);\n    assert(x == 7);\n}\n\n/**\nImplicitly converts to `T`.\n`this` must not be in the null state.\n */\n    alias get this;\n}\n\n/// ditto\nauto nullable(T)(T t)\n{\n    return Nullable!T(t);\n}\n\n///\n@safe unittest\n{\n    struct CustomerRecord\n    {\n        string name;\n        string address;\n        int customerNum;\n    }\n\n    Nullable!CustomerRecord getByName(string name)\n    {\n        //A bunch of hairy stuff\n\n        return Nullable!CustomerRecord.init;\n    }\n\n    auto queryResult = getByName(\"Doe, John\");\n    if (!queryResult.isNull)\n    {\n        //Process Mr. Doe's customer record\n        auto address = queryResult.address;\n        auto customerNum = queryResult.customerNum;\n\n        //Do some things with this customer's info\n    }\n    else\n    {\n        //Add the customer to the database\n    }\n}\n\n///\n@system unittest\n{\n    import std.exception : assertThrown;\n\n    auto a = 42.nullable;\n    assert(!a.isNull);\n    assert(a.get == 42);\n\n    a.nullify();\n    assert(a.isNull);\n    assertThrown!Throwable(a.get);\n}\n\n@system unittest\n{\n    import std.exception : assertThrown;\n\n    Nullable!int a;\n    assert(a.isNull);\n    assertThrown!Throwable(a.get);\n    a = 5;\n    assert(!a.isNull);\n    assert(a == 5);\n    assert(a != 3);\n    assert(a.get != 3);\n    a.nullify();\n    assert(a.isNull);\n    a = 3;\n    assert(a == 3);\n    a *= 6;\n    assert(a == 18);\n    a = a;\n    assert(a == 18);\n    a.nullify();\n    assertThrown!Throwable(a += 2);\n}\n@safe unittest\n{\n    auto k = Nullable!int(74);\n    assert(k == 74);\n    k.nullify();\n    assert(k.isNull);\n}\n@safe unittest\n{\n    static int f(scope const Nullable!int x) {\n        return x.isNull ? 42 : x.get;\n    }\n    Nullable!int a;\n    assert(f(a) == 42);\n    a = 8;\n    assert(f(a) == 8);\n    a.nullify();\n    assert(f(a) == 42);\n}\n@system unittest\n{\n    import std.exception : assertThrown;\n\n    static struct S { int x; }\n    Nullable!S s;\n    assert(s.isNull);\n    s = S(6);\n    assert(s == S(6));\n    assert(s != S(0));\n    assert(s.get != S(0));\n    s.x = 9190;\n    assert(s.x == 9190);\n    s.nullify();\n    assertThrown!Throwable(s.x = 9441);\n}\n@safe unittest\n{\n    // Ensure Nullable can be used in pure/nothrow/@safe environment.\n    function() @safe pure nothrow\n    {\n        Nullable!int n;\n        assert(n.isNull);\n        n = 4;\n        assert(!n.isNull);\n        assert(n == 4);\n        n.nullify();\n        assert(n.isNull);\n    }();\n}\n@system unittest\n{\n    // Ensure Nullable can be used when the value is not pure/nothrow/@safe\n    static struct S\n    {\n        int x;\n        this(this) @system {}\n    }\n\n    Nullable!S s;\n    assert(s.isNull);\n    s = S(5);\n    assert(!s.isNull);\n    assert(s.x == 5);\n    s.nullify();\n    assert(s.isNull);\n}\n@safe unittest\n{\n    // Bugzilla 9404\n    alias N = Nullable!int;\n\n    void foo(N a)\n    {\n        N b;\n        b = a; // `N b = a;` works fine\n    }\n    N n;\n    foo(n);\n}\n@safe unittest\n{\n    //Check nullable immutable is constructable\n    {\n        auto a1 = Nullable!(immutable int)();\n        auto a2 = Nullable!(immutable int)(1);\n        auto i = a2.get;\n    }\n    //Check immutable nullable is constructable\n    {\n        auto a1 = immutable (Nullable!int)();\n        auto a2 = immutable (Nullable!int)(1);\n        auto i = a2.get;\n    }\n}\n@safe unittest\n{\n    alias NInt   = Nullable!int;\n\n    //Construct tests\n    {\n        //from other Nullable null\n        NInt a1;\n        NInt b1 = a1;\n        assert(b1.isNull);\n\n        //from other Nullable non-null\n        NInt a2 = NInt(1);\n        NInt b2 = a2;\n        assert(b2 == 1);\n\n        //Construct from similar nullable\n        auto a3 = immutable(NInt)();\n        NInt b3 = a3;\n        assert(b3.isNull);\n    }\n\n    //Assign tests\n    {\n        //from other Nullable null\n        NInt a1;\n        NInt b1;\n        b1 = a1;\n        assert(b1.isNull);\n\n        //from other Nullable non-null\n        NInt a2 = NInt(1);\n        NInt b2;\n        b2 = a2;\n        assert(b2 == 1);\n\n        //Construct from similar nullable\n        auto a3 = immutable(NInt)();\n        NInt b3 = a3;\n        b3 = a3;\n        assert(b3.isNull);\n    }\n}\n@safe unittest\n{\n    //Check nullable is nicelly embedable in a struct\n    static struct S1\n    {\n        Nullable!int ni;\n    }\n    static struct S2 //inspired from 9404\n    {\n        Nullable!int ni;\n        this(S2 other)\n        {\n            ni = other.ni;\n        }\n        void opAssign(S2 other)\n        {\n            ni = other.ni;\n        }\n    }\n    static foreach (S; AliasSeq!(S1, S2))\n    {{\n        S a;\n        S b = a;\n        S c;\n        c = a;\n    }}\n}\n@system unittest\n{\n    // Bugzilla 10268\n    import std.json;\n    JSONValue value = null;\n    auto na = Nullable!JSONValue(value);\n\n    struct S1 { int val; }\n    struct S2 { int* val; }\n    struct S3 { immutable int* val; }\n\n    {\n        auto sm = S1(1);\n        immutable si = immutable S1(1);\n        auto x1 =           Nullable!S1(sm);\n        auto x2 = immutable Nullable!S1(sm);\n        auto x3 =           Nullable!S1(si);\n        auto x4 = immutable Nullable!S1(si);\n        assert(x1.val == 1);\n        assert(x2.val == 1);\n        assert(x3.val == 1);\n        assert(x4.val == 1);\n    }\n\n    auto nm = 10;\n    immutable ni = 10;\n\n    {\n        auto sm = S2(&nm);\n        immutable si = immutable S2(&ni);\n        auto x1 =           Nullable!S2(sm);\n        static assert(!__traits(compiles, { auto x2 = immutable Nullable!S2(sm); }));\n        static assert(!__traits(compiles, { auto x3 =           Nullable!S2(si); }));\n        auto x4 = immutable Nullable!S2(si);\n        assert(*x1.val == 10);\n        assert(*x4.val == 10);\n    }\n\n    {\n        auto sm = S3(&ni);\n        immutable si = immutable S3(&ni);\n        auto x1 =           Nullable!S3(sm);\n        auto x2 = immutable Nullable!S3(sm);\n        auto x3 =           Nullable!S3(si);\n        auto x4 = immutable Nullable!S3(si);\n        assert(*x1.val == 10);\n        assert(*x2.val == 10);\n        assert(*x3.val == 10);\n        assert(*x4.val == 10);\n    }\n}\n@safe unittest\n{\n    // Bugzila 10357\n    import std.datetime;\n    Nullable!SysTime time = SysTime(0);\n}\n@system unittest\n{\n    import std.conv : to;\n    import std.array;\n\n    // Bugzilla 10915\n    Appender!string buffer;\n\n    Nullable!int ni;\n    assert(ni.to!string() == \"Nullable.null\");\n\n    struct Test { string s; }\n    alias NullableTest = Nullable!Test;\n\n    NullableTest nt = Test(\"test\");\n    // test output range version\n    assert(nt.to!string() == `Test(\"test\")`);\n    // test appender version\n    assert(nt.toString() == `Test(\"test\")`);\n\n    NullableTest ntn = Test(\"null\");\n    assert(ntn.to!string() == `Test(\"null\")`);\n\n    class TestToString\n    {\n        double d;\n\n        this (double d)\n        {\n            this.d = d;\n        }\n\n        override string toString()\n        {\n            return d.to!string();\n        }\n    }\n    Nullable!TestToString ntts = new TestToString(2.5);\n    assert(ntts.to!string() == \"2.5\");\n}\n\n// Bugzilla 14477\n@safe unittest\n{\n    static struct DisabledDefaultConstructor\n    {\n        @disable this();\n        this(int i) { }\n    }\n    Nullable!DisabledDefaultConstructor var;\n    var = DisabledDefaultConstructor(5);\n    var.nullify;\n}\n\n// Issue 17440\n@system unittest\n{\n    static interface I { }\n\n    static class C : I\n    {\n        int canary;\n        ~this()\n        {\n            canary = 0x5050DEAD;\n        }\n    }\n    auto c = new C;\n    c.canary = 0xA71FE;\n    auto nc = nullable(c);\n    nc.nullify;\n    assert(c.canary == 0xA71FE);\n\n    I i = c;\n    auto ni = nullable(i);\n    ni.nullify;\n    assert(c.canary == 0xA71FE);\n}\n\n// Regression test for issue 18539\n@safe unittest\n{\n    import std.math : approxEqual;\n\n    auto foo = nullable(2.0);\n    auto bar = nullable(2.0);\n\n    assert(foo.approxEqual(bar));\n}\n// bugzilla issue 19037\n@safe unittest\n{\n    import std.datetime : SysTime;\n\n    struct Test\n    {\n        bool b;\n\n        nothrow invariant { assert(b == true); }\n\n        SysTime _st;\n\n        static bool destroyed;\n\n        @disable this();\n        this(bool b) { this.b = b; }\n        ~this() @safe { destroyed = true; }\n\n        // mustn't call opAssign on Test.init in Nullable!Test, because the invariant\n        // will be called before opAssign on the Test.init that is in Nullable\n        // and Test.init violates its invariant.\n        void opAssign(Test rhs) @safe { assert(false); }\n    }\n\n    {\n        Nullable!Test nt;\n\n        nt = Test(true);\n\n        // destroy value\n        Test.destroyed = false;\n\n        nt.nullify;\n\n        assert(Test.destroyed);\n\n        Test.destroyed = false;\n    }\n    // don't run destructor on T.init in Nullable on scope exit!\n    assert(!Test.destroyed);\n}\n// check that the contained type's destructor is called on assignment\n@system unittest\n{\n    struct S\n    {\n        // can't be static, since we need a specific value's pointer\n        bool* destroyedRef;\n\n        ~this()\n        {\n            if (this.destroyedRef)\n            {\n                *this.destroyedRef = true;\n            }\n        }\n    }\n\n    Nullable!S ns;\n\n    bool destroyed;\n\n    ns = S(&destroyed);\n\n    // reset from rvalue destruction in Nullable's opAssign\n    destroyed = false;\n\n    // overwrite Nullable\n    ns = S(null);\n\n    // the original S should be destroyed.\n    assert(destroyed == true);\n}\n// check that the contained type's destructor is still called when required\n@system unittest\n{\n    bool destructorCalled = false;\n\n    struct S\n    {\n        bool* destroyed;\n        ~this() { *this.destroyed = true; }\n    }\n\n    {\n        Nullable!S ns;\n    }\n    assert(!destructorCalled);\n    {\n        Nullable!S ns = Nullable!S(S(&destructorCalled));\n\n        destructorCalled = false; // reset after S was destroyed in the NS constructor\n    }\n    assert(destructorCalled);\n}\n\n// check that toHash on Nullable is forwarded to the contained type\n@system unittest\n{\n    struct S\n    {\n        size_t toHash() const @safe pure nothrow { return 5; }\n    }\n\n    Nullable!S s1 = S();\n    Nullable!S s2 = Nullable!S();\n\n    assert(typeid(Nullable!S).getHash(&s1) == 5);\n    assert(typeid(Nullable!S).getHash(&s2) == 0);\n}\n\n/**\nJust like `Nullable!T`, except that the null state is defined as a\nparticular value. For example, $(D Nullable!(uint, uint.max)) is an\n`uint` that sets aside the value `uint.max` to denote a null\nstate. $(D Nullable!(T, nullValue)) is more storage-efficient than $(D\nNullable!T) because it does not need to store an extra `bool`.\n\nParams:\n    T = The wrapped type for which Nullable provides a null value.\n\n    nullValue = The null value which denotes the null state of this\n                `Nullable`. Must be of type `T`.\n */\nstruct Nullable(T, T nullValue)\n{\n    private T _value = nullValue;\n\n/**\nConstructor initializing `this` with `value`.\n\nParams:\n    value = The value to initialize this `Nullable` with.\n */\n    this(T value)\n    {\n        _value = value;\n    }\n\n    template toString()\n    {\n        import std.format : FormatSpec, formatValue;\n        // Needs to be a template because of DMD @@BUG@@ 13737.\n        void toString()(scope void delegate(const(char)[]) sink, const ref FormatSpec!char fmt)\n        {\n            if (isNull)\n            {\n                sink.formatValue(\"Nullable.null\", fmt);\n            }\n            else\n            {\n                sink.formatValue(_value, fmt);\n            }\n        }\n    }\n\n/**\nCheck if `this` is in the null state.\n\nReturns:\n    true $(B iff) `this` is in the null state, otherwise false.\n */\n    @property bool isNull() const\n    {\n        //Need to use 'is' if T is a nullable type and\n        //nullValue is null, or it's a compiler error\n        static if (is(CommonType!(T, typeof(null)) == T) && nullValue is null)\n        {\n            return _value is nullValue;\n        }\n        //Need to use 'is' if T is a float type\n        //because NaN != NaN\n        else static if (isFloatingPoint!T)\n        {\n            return _value is nullValue;\n        }\n        else\n        {\n            return _value == nullValue;\n        }\n    }\n\n///\n@safe unittest\n{\n    Nullable!(int, -1) ni;\n    //Initialized to \"null\" state\n    assert(ni.isNull);\n\n    ni = 0;\n    assert(!ni.isNull);\n}\n\n// https://issues.dlang.org/show_bug.cgi?id=11135\n// disable test until https://issues.dlang.org/show_bug.cgi?id=15316 gets fixed\nversion (none) @system unittest\n{\n    static foreach (T; AliasSeq!(float, double, real))\n    {{\n        Nullable!(T, T.init) nf;\n        //Initialized to \"null\" state\n        assert(nf.isNull);\n        assert(nf is typeof(nf).init);\n\n        nf = 0;\n        assert(!nf.isNull);\n\n        nf.nullify();\n        assert(nf.isNull);\n    }}\n}\n\n/**\nForces `this` to the null state.\n */\n    void nullify()()\n    {\n        _value = nullValue;\n    }\n\n///\n@safe unittest\n{\n    Nullable!(int, -1) ni = 0;\n    assert(!ni.isNull);\n\n    ni = -1;\n    assert(ni.isNull);\n}\n\n/**\nAssigns `value` to the internally-held state. If the assignment\nsucceeds, `this` becomes non-null. No null checks are made. Note\nthat the assignment may leave `this` in the null state.\n\nParams:\n    value = A value of type `T` to assign to this `Nullable`.\n            If it is `nullvalue`, then the internal state of\n            this `Nullable` will be set to null.\n */\n    void opAssign()(T value)\n    {\n        import std.algorithm.mutation : swap;\n\n        swap(value, _value);\n    }\n\n/**\n    If this `Nullable` wraps a type that already has a null value\n    (such as a pointer), and that null value is not given for\n    `nullValue`, then assigning the null value to this `Nullable`\n    is no different than assigning any other value of type `T`,\n    and the resulting code will look very strange. It is strongly\n    recommended that this be avoided by using `T`'s \"built in\"\n    null value for `nullValue`.\n */\n@system unittest\n{\n    //Passes\n    enum nullVal = cast(int*) 0xCAFEBABE;\n    Nullable!(int*, nullVal) npi;\n    assert(npi.isNull);\n\n    //Passes?!\n    npi = null;\n    assert(!npi.isNull);\n}\n\n/**\nGets the value. `this` must not be in the null state.\nThis function is also called for the implicit conversion to `T`.\n\nPreconditions: `isNull` must be `false`.\nReturns:\n    The value held internally by this `Nullable`.\n */\n    @property ref inout(T) get() inout\n    {\n        //@@@6169@@@: We avoid any call that might evaluate nullValue's %s,\n        //Because it might messup get's purity and safety inference.\n        enum message = \"Called `get' on null Nullable!(\" ~ T.stringof ~ \",nullValue).\";\n        assert(!isNull, message);\n        return _value;\n    }\n\n///\n@system unittest\n{\n    import std.exception : assertThrown, assertNotThrown;\n\n    Nullable!(int, -1) ni;\n    //`get` is implicitly called. Will throw\n    //an error in non-release mode\n    assertThrown!Throwable(ni == 0);\n\n    ni = 0;\n    assertNotThrown!Throwable(ni == 0);\n}\n\n/**\nImplicitly converts to `T`.\n`this` must not be in the null state.\n */\n    alias get this;\n}\n\n/// ditto\nauto nullable(alias nullValue, T)(T t)\nif (is (typeof(nullValue) == T))\n{\n    return Nullable!(T, nullValue)(t);\n}\n\n///\n@safe unittest\n{\n    Nullable!(size_t, size_t.max) indexOf(string[] haystack, string needle)\n    {\n        //Find the needle, returning -1 if not found\n\n        return Nullable!(size_t, size_t.max).init;\n    }\n\n    void sendLunchInvite(string name)\n    {\n    }\n\n    //It's safer than C...\n    auto coworkers = [\"Jane\", \"Jim\", \"Marry\", \"Fred\"];\n    auto pos = indexOf(coworkers, \"Bob\");\n    if (!pos.isNull)\n    {\n        //Send Bob an invitation to lunch\n        sendLunchInvite(coworkers[pos]);\n    }\n    else\n    {\n        //Bob not found; report the error\n    }\n\n    //And there's no overhead\n    static assert(Nullable!(size_t, size_t.max).sizeof == size_t.sizeof);\n}\n\n///\n@system unittest\n{\n    import std.exception : assertThrown;\n\n    Nullable!(int, int.min) a;\n    assert(a.isNull);\n    assertThrown!Throwable(a.get);\n    a = 5;\n    assert(!a.isNull);\n    assert(a == 5);\n    static assert(a.sizeof == int.sizeof);\n}\n\n///\n@safe unittest\n{\n    auto a = nullable!(int.min)(8);\n    assert(a == 8);\n    a.nullify();\n    assert(a.isNull);\n}\n\n@safe unittest\n{\n    static int f(scope const Nullable!(int, int.min) x) {\n        return x.isNull ? 42 : x.get;\n    }\n    Nullable!(int, int.min) a;\n    assert(f(a) == 42);\n    a = 8;\n    assert(f(a) == 8);\n    a.nullify();\n    assert(f(a) == 42);\n}\n@safe unittest\n{\n    // Ensure Nullable can be used in pure/nothrow/@safe environment.\n    function() @safe pure nothrow\n    {\n        Nullable!(int, int.min) n;\n        assert(n.isNull);\n        n = 4;\n        assert(!n.isNull);\n        assert(n == 4);\n        n.nullify();\n        assert(n.isNull);\n    }();\n}\n@system unittest\n{\n    // Ensure Nullable can be used when the value is not pure/nothrow/@system\n    static struct S\n    {\n        int x;\n        bool opEquals(const S s) const @system { return s.x == x; }\n    }\n\n    Nullable!(S, S(711)) s;\n    assert(s.isNull);\n    s = S(5);\n    assert(!s.isNull);\n    assert(s.x == 5);\n    s.nullify();\n    assert(s.isNull);\n}\n@safe unittest\n{\n    //Check nullable is nicelly embedable in a struct\n    static struct S1\n    {\n        Nullable!(int, 0) ni;\n    }\n    static struct S2 //inspired from 9404\n    {\n        Nullable!(int, 0) ni;\n        this(S2 other)\n        {\n            ni = other.ni;\n        }\n        void opAssign(S2 other)\n        {\n            ni = other.ni;\n        }\n    }\n    static foreach (S; AliasSeq!(S1, S2))\n    {{\n        S a;\n        S b = a;\n        S c;\n        c = a;\n    }}\n}\n@system unittest\n{\n    import std.conv : to;\n\n    // Bugzilla 10915\n    Nullable!(int, 1) ni = 1;\n    assert(ni.to!string() == \"Nullable.null\");\n\n    struct Test { string s; }\n    alias NullableTest = Nullable!(Test, Test(\"null\"));\n\n    NullableTest nt = Test(\"test\");\n    assert(nt.to!string() == `Test(\"test\")`);\n\n    NullableTest ntn = Test(\"null\");\n    assert(ntn.to!string() == \"Nullable.null\");\n\n    class TestToString\n    {\n        double d;\n\n        this(double d)\n        {\n            this.d = d;\n        }\n\n        override string toString()\n        {\n            return d.to!string();\n        }\n    }\n    alias NullableTestToString = Nullable!(TestToString, null);\n\n    NullableTestToString ntts = new TestToString(2.5);\n    assert(ntts.to!string() == \"2.5\");\n}\n\n// apply\n/**\nUnpacks the content of a `Nullable`, performs an operation and packs it again. Does nothing if isNull.\n\nWhen called on a `Nullable`, `apply` will unpack the value contained in the `Nullable`,\npass it to the function you provide and wrap the result in another `Nullable` (if necessary).\nIf the `Nullable` is null, `apply` will return null itself.\n\nParams:\n    t = a `Nullable`\n    fun = a function operating on the content of the nullable\n\nReturns:\n    `fun(t.get).nullable` if `!t.isNull`, else `Nullable.init`.\n\nSee also:\n    $(HTTPS en.wikipedia.org/wiki/Monad_(functional_programming)#The_Maybe_monad, The `Maybe` monad)\n */\ntemplate apply(alias fun)\n{\n    import std.functional : unaryFun;\n\n    auto apply(T)(auto ref T t)\n    if (isInstanceOf!(Nullable, T) && is(typeof(unaryFun!fun(T.init.get))))\n    {\n        alias FunType = typeof(unaryFun!fun(T.init.get));\n\n        enum MustWrapReturn = !isInstanceOf!(Nullable, FunType);\n\n        static if (MustWrapReturn)\n        {\n            alias ReturnType = Nullable!FunType;\n        }\n        else\n        {\n            alias ReturnType = FunType;\n        }\n\n        if (!t.isNull)\n        {\n            static if (MustWrapReturn)\n            {\n                return fun(t.get).nullable;\n            }\n            else\n            {\n                return fun(t.get);\n            }\n        }\n        else\n        {\n            return ReturnType.init;\n        }\n    }\n}\n\n///\nnothrow pure @nogc @safe unittest\n{\n    alias toFloat = i => cast(float) i;\n\n    Nullable!int sample;\n\n    // apply(null) results in a null `Nullable` of the function's return type.\n    Nullable!float f = sample.apply!toFloat;\n    assert(sample.isNull && f.isNull);\n\n    sample = 3;\n\n    // apply(non-null) calls the function and wraps the result in a `Nullable`.\n    f = sample.apply!toFloat;\n    assert(!sample.isNull && !f.isNull);\n    assert(f.get == 3.0f);\n}\n\n///\nnothrow pure @nogc @safe unittest\n{\n    alias greaterThree = i => (i > 3) ? i.nullable : Nullable!(typeof(i)).init;\n\n    Nullable!int sample;\n\n    // when the function already returns a `Nullable`, that `Nullable` is not wrapped.\n    auto result = sample.apply!greaterThree;\n    assert(sample.isNull && result.isNull);\n\n    // The function may decide to return a null `Nullable`.\n    sample = 3;\n    result = sample.apply!greaterThree;\n    assert(!sample.isNull && result.isNull);\n\n    // Or it may return a value already wrapped in a `Nullable`.\n    sample = 4;\n    result = sample.apply!greaterThree;\n    assert(!sample.isNull && !result.isNull);\n    assert(result.get == 4);\n}\n\n/**\nJust like `Nullable!T`, except that the object refers to a value\nsitting elsewhere in memory. This makes assignments overwrite the\ninitially assigned value. Internally `NullableRef!T` only stores a\npointer to `T` (i.e., $(D Nullable!T.sizeof == (T*).sizeof)).\n */\nstruct NullableRef(T)\n{\n    private T* _value;\n\n/**\nConstructor binding `this` to `value`.\n\nParams:\n    value = The value to bind to.\n */\n    this(T* value) @safe pure nothrow\n    {\n        _value = value;\n    }\n\n    template toString()\n    {\n        import std.format : FormatSpec, formatValue;\n        // Needs to be a template because of DMD @@BUG@@ 13737.\n        void toString()(scope void delegate(const(char)[]) sink, const ref FormatSpec!char fmt)\n        {\n            if (isNull)\n            {\n                sink.formatValue(\"Nullable.null\", fmt);\n            }\n            else\n            {\n                sink.formatValue(*_value, fmt);\n            }\n        }\n    }\n\n/**\nBinds the internal state to `value`.\n\nParams:\n    value = A pointer to a value of type `T` to bind this `NullableRef` to.\n */\n    void bind(T* value) @safe pure nothrow\n    {\n        _value = value;\n    }\n\n    ///\n    @safe unittest\n    {\n        NullableRef!int nr = new int(42);\n        assert(nr == 42);\n\n        int* n = new int(1);\n        nr.bind(n);\n        assert(nr == 1);\n    }\n\n/**\nReturns `true` if and only if `this` is in the null state.\n\nReturns:\n    true if `this` is in the null state, otherwise false.\n */\n    @property bool isNull() const @safe pure nothrow\n    {\n        return _value is null;\n    }\n\n    ///\n    @safe unittest\n    {\n        NullableRef!int nr;\n        assert(nr.isNull);\n\n        int* n = new int(42);\n        nr.bind(n);\n        assert(!nr.isNull && nr == 42);\n    }\n\n/**\nForces `this` to the null state.\n */\n    void nullify() @safe pure nothrow\n    {\n        _value = null;\n    }\n\n    ///\n    @safe unittest\n    {\n        NullableRef!int nr = new int(42);\n        assert(!nr.isNull);\n\n        nr.nullify();\n        assert(nr.isNull);\n    }\n\n/**\nAssigns `value` to the internally-held state.\n\nParams:\n    value = A value of type `T` to assign to this `NullableRef`.\n            If the internal state of this `NullableRef` has not\n            been initialized, an error will be thrown in\n            non-release mode.\n */\n    void opAssign()(T value)\n        if (isAssignable!T) //@@@9416@@@\n    {\n        enum message = \"Called `opAssign' on null NullableRef!\" ~ T.stringof ~ \".\";\n        assert(!isNull, message);\n        *_value = value;\n    }\n\n    ///\n    @system unittest\n    {\n        import std.exception : assertThrown, assertNotThrown;\n\n        NullableRef!int nr;\n        assert(nr.isNull);\n        assertThrown!Throwable(nr = 42);\n\n        nr.bind(new int(0));\n        assert(!nr.isNull);\n        assertNotThrown!Throwable(nr = 42);\n        assert(nr == 42);\n    }\n\n/**\nGets the value. `this` must not be in the null state.\nThis function is also called for the implicit conversion to `T`.\n */\n    @property ref inout(T) get() inout @safe pure nothrow\n    {\n        enum message = \"Called `get' on null NullableRef!\" ~ T.stringof ~ \".\";\n        assert(!isNull, message);\n        return *_value;\n    }\n\n    ///\n    @system unittest\n    {\n        import std.exception : assertThrown, assertNotThrown;\n\n        NullableRef!int nr;\n        //`get` is implicitly called. Will throw\n        //an error in non-release mode\n        assertThrown!Throwable(nr == 0);\n\n        nr.bind(new int(0));\n        assertNotThrown!Throwable(nr == 0);\n    }\n\n/**\nImplicitly converts to `T`.\n`this` must not be in the null state.\n */\n    alias get this;\n}\n\n/// ditto\nauto nullableRef(T)(T* t)\n{\n    return NullableRef!T(t);\n}\n\n///\n@system unittest\n{\n    import std.exception : assertThrown;\n\n    int x = 5, y = 7;\n    auto a = nullableRef(&x);\n    assert(!a.isNull);\n    assert(a == 5);\n    assert(x == 5);\n    a = 42;\n    assert(x == 42);\n    assert(!a.isNull);\n    assert(a == 42);\n    a.nullify();\n    assert(x == 42);\n    assert(a.isNull);\n    assertThrown!Throwable(a.get);\n    assertThrown!Throwable(a = 71);\n    a.bind(&y);\n    assert(a == 7);\n    y = 135;\n    assert(a == 135);\n}\n@system unittest\n{\n    static int f(scope const NullableRef!int x) {\n        return x.isNull ? 42 : x.get;\n    }\n    int x = 5;\n    auto a = nullableRef(&x);\n    assert(f(a) == 5);\n    a.nullify();\n    assert(f(a) == 42);\n}\n@safe unittest\n{\n    // Ensure NullableRef can be used in pure/nothrow/@safe environment.\n    function() @safe pure nothrow\n    {\n        auto storage = new int;\n        *storage = 19902;\n        NullableRef!int n;\n        assert(n.isNull);\n        n.bind(storage);\n        assert(!n.isNull);\n        assert(n == 19902);\n        n = 2294;\n        assert(n == 2294);\n        assert(*storage == 2294);\n        n.nullify();\n        assert(n.isNull);\n    }();\n}\n@system unittest\n{\n    // Ensure NullableRef can be used when the value is not pure/nothrow/@safe\n    static struct S\n    {\n        int x;\n        this(this) @system {}\n        bool opEquals(const S s) const @system { return s.x == x; }\n    }\n\n    auto storage = S(5);\n\n    NullableRef!S s;\n    assert(s.isNull);\n    s.bind(&storage);\n    assert(!s.isNull);\n    assert(s.x == 5);\n    s.nullify();\n    assert(s.isNull);\n}\n@safe unittest\n{\n    //Check nullable is nicelly embedable in a struct\n    static struct S1\n    {\n        NullableRef!int ni;\n    }\n    static struct S2 //inspired from 9404\n    {\n        NullableRef!int ni;\n        this(S2 other)\n        {\n            ni = other.ni;\n        }\n        void opAssign(S2 other)\n        {\n            ni = other.ni;\n        }\n    }\n    static foreach (S; AliasSeq!(S1, S2))\n    {{\n        S a;\n        S b = a;\n        S c;\n        c = a;\n    }}\n}\n@system unittest\n{\n    import std.conv : to;\n\n    // Bugzilla 10915\n    NullableRef!int nri;\n    assert(nri.to!string() == \"Nullable.null\");\n\n    struct Test\n    {\n        string s;\n    }\n    NullableRef!Test nt = new Test(\"test\");\n    assert(nt.to!string() == `Test(\"test\")`);\n\n    class TestToString\n    {\n        double d;\n\n        this(double d)\n        {\n            this.d = d;\n        }\n\n        override string toString()\n        {\n            return d.to!string();\n        }\n    }\n    TestToString tts = new TestToString(2.5);\n    NullableRef!TestToString ntts = &tts;\n    assert(ntts.to!string() == \"2.5\");\n}\n\n\n/**\n`BlackHole!Base` is a subclass of `Base` which automatically implements\nall abstract member functions in `Base` as do-nothing functions.  Each\nauto-implemented function just returns the default value of the return type\nwithout doing anything.\n\nThe name came from\n$(HTTP search.cpan.org/~sburke/Class-_BlackHole-0.04/lib/Class/_BlackHole.pm, Class::_BlackHole)\nPerl module by Sean M. Burke.\n\nParams:\n    Base = A non-final class for `BlackHole` to inherit from.\n\nSee_Also:\n  $(LREF AutoImplement), $(LREF generateEmptyFunction)\n */\nalias BlackHole(Base) = AutoImplement!(Base, generateEmptyFunction, isAbstractFunction);\n\n///\n@system unittest\n{\n    import std.math : isNaN;\n\n    static abstract class C\n    {\n        int m_value;\n        this(int v) { m_value = v; }\n        int value() @property { return m_value; }\n\n        abstract real realValue() @property;\n        abstract void doSomething();\n    }\n\n    auto c = new BlackHole!C(42);\n    assert(c.value == 42);\n\n    // Returns real.init which is NaN\n    assert(c.realValue.isNaN);\n    // Abstract functions are implemented as do-nothing\n    c.doSomething();\n}\n\n@system unittest\n{\n    import std.math : isNaN;\n\n    // return default\n    {\n        interface I_1 { real test(); }\n        auto o = new BlackHole!I_1;\n        assert(o.test().isNaN()); // NaN\n    }\n    // doc example\n    {\n        static class C\n        {\n            int m_value;\n            this(int v) { m_value = v; }\n            int value() @property { return m_value; }\n\n            abstract real realValue() @property;\n            abstract void doSomething();\n        }\n\n        auto c = new BlackHole!C(42);\n        assert(c.value == 42);\n\n        assert(c.realValue.isNaN); // NaN\n        c.doSomething();\n    }\n\n    // Bugzilla 12058\n    interface Foo\n    {\n        inout(Object) foo() inout;\n    }\n    BlackHole!Foo o;\n}\n\n\n/**\n`WhiteHole!Base` is a subclass of `Base` which automatically implements\nall abstract member functions as functions that always fail. These functions\nsimply throw an `Error` and never return. `Whitehole` is useful for\ntrapping the use of class member functions that haven't been implemented.\n\nThe name came from\n$(HTTP search.cpan.org/~mschwern/Class-_WhiteHole-0.04/lib/Class/_WhiteHole.pm, Class::_WhiteHole)\nPerl module by Michael G Schwern.\n\nParams:\n    Base = A non-final class for `WhiteHole` to inherit from.\n\nSee_Also:\n  $(LREF AutoImplement), $(LREF generateAssertTrap)\n */\nalias WhiteHole(Base) = AutoImplement!(Base, generateAssertTrap, isAbstractFunction);\n\n///\n@system unittest\n{\n    import std.exception : assertThrown;\n\n    static class C\n    {\n        abstract void notYetImplemented();\n    }\n\n    auto c = new WhiteHole!C;\n    assertThrown!NotImplementedError(c.notYetImplemented()); // throws an Error\n}\n\n// / ditto\nclass NotImplementedError : Error\n{\n    this(string method)\n    {\n        super(method ~ \" is not implemented\");\n    }\n}\n\n@system unittest\n{\n    import std.exception : assertThrown;\n    // nothrow\n    {\n        interface I_1\n        {\n            void foo();\n            void bar() nothrow;\n        }\n        auto o = new WhiteHole!I_1;\n        assertThrown!NotImplementedError(o.foo());\n        assertThrown!NotImplementedError(o.bar());\n    }\n    // doc example\n    {\n        static class C\n        {\n            abstract void notYetImplemented();\n        }\n\n        auto c = new WhiteHole!C;\n        try\n        {\n            c.notYetImplemented();\n            assert(0);\n        }\n        catch (Error e) {}\n    }\n}\n\n\n/**\n`AutoImplement` automatically implements (by default) all abstract member\nfunctions in the class or interface `Base` in specified way.\n\nThe second version of `AutoImplement` automatically implements\n`Interface`, while deriving from `BaseClass`.\n\nParams:\n  how  = template which specifies _how functions will be implemented/overridden.\n\n         Two arguments are passed to `how`: the type `Base` and an alias\n         to an implemented function.  Then `how` must return an implemented\n         function body as a string.\n\n         The generated function body can use these keywords:\n         $(UL\n            $(LI `a0`, `a1`, &hellip;: arguments passed to the function;)\n            $(LI `args`: a tuple of the arguments;)\n            $(LI `self`: an alias to the function itself;)\n            $(LI `parent`: an alias to the overridden function (if any).)\n         )\n\n        You may want to use templated property functions (instead of Implicit\n        Template Properties) to generate complex functions:\n--------------------\n// Prints log messages for each call to overridden functions.\nstring generateLogger(C, alias fun)() @property\n{\n    import std.traits;\n    enum qname = C.stringof ~ \".\" ~ __traits(identifier, fun);\n    string stmt;\n\n    stmt ~= q{ struct Importer { import std.stdio; } };\n    stmt ~= `Importer.writeln(\"Log: ` ~ qname ~ `(\", args, \")\");`;\n    static if (!__traits(isAbstractFunction, fun))\n    {\n        static if (is(ReturnType!fun == void))\n            stmt ~= q{ parent(args); };\n        else\n            stmt ~= q{\n                auto r = parent(args);\n                Importer.writeln(\"--> \", r);\n                return r;\n            };\n    }\n    return stmt;\n}\n--------------------\n\n  what = template which determines _what functions should be\n         implemented/overridden.\n\n         An argument is passed to `what`: an alias to a non-final member\n         function in `Base`.  Then `what` must return a boolean value.\n         Return `true` to indicate that the passed function should be\n         implemented/overridden.\n\n--------------------\n// Sees if fun returns something.\nenum bool hasValue(alias fun) = !is(ReturnType!(fun) == void);\n--------------------\n\n\nNote:\n\nGenerated code is inserted in the scope of `std.typecons` module.  Thus,\nany useful functions outside `std.typecons` cannot be used in the generated\ncode.  To workaround this problem, you may `import` necessary things in a\nlocal struct, as done in the `generateLogger()` template in the above\nexample.\n\n\nBUGS:\n\n$(UL\n $(LI Variadic arguments to constructors are not forwarded to super.)\n $(LI Deep interface inheritance causes compile error with messages like\n      \"Error: function std.typecons._AutoImplement!(Foo)._AutoImplement.bar\n      does not override any function\".  [$(BUGZILLA 2525), $(BUGZILLA 3525)] )\n $(LI The `parent` keyword is actually a delegate to the super class'\n      corresponding member function.  [$(BUGZILLA 2540)] )\n $(LI Using alias template parameter in `how` and/or `what` may cause\n     strange compile error.  Use template tuple parameter instead to workaround\n     this problem.  [$(BUGZILLA 4217)] )\n)\n */\nclass AutoImplement(Base, alias how, alias what = isAbstractFunction) : Base\nif (!is(how == class))\n{\n    private alias autoImplement_helper_ =\n        AutoImplement_Helper!(\"autoImplement_helper_\", \"Base\", Base, typeof(this), how, what);\n    mixin(autoImplement_helper_.code);\n}\n\n/// ditto\nclass AutoImplement(\n    Interface, BaseClass, alias how,\n    alias what = isAbstractFunction) : BaseClass, Interface\nif (is(Interface == interface) && is(BaseClass == class))\n{\n    private alias autoImplement_helper_ = AutoImplement_Helper!(\n            \"autoImplement_helper_\", \"Interface\", Interface, typeof(this), how, what);\n    mixin(autoImplement_helper_.code);\n}\n\n///\n@system unittest\n{\n    interface PackageSupplier\n    {\n        int foo();\n        int bar();\n    }\n\n    static abstract class AbstractFallbackPackageSupplier : PackageSupplier\n    {\n        protected PackageSupplier default_, fallback;\n\n        this(PackageSupplier default_, PackageSupplier fallback)\n        {\n            this.default_ = default_;\n            this.fallback = fallback;\n        }\n\n        abstract int foo();\n        abstract int bar();\n    }\n\n    template fallback(T, alias func)\n    {\n        import std.format : format;\n        // for all implemented methods:\n        // - try default first\n        // - only on a failure run & return fallback\n        enum fallback = q{\n            scope (failure) return fallback.%1$s(args);\n            return default_.%1$s(args);\n        }.format(__traits(identifier, func));\n    }\n\n    // combines two classes and use the second one as fallback\n    alias FallbackPackageSupplier = AutoImplement!(AbstractFallbackPackageSupplier, fallback);\n\n    class FailingPackageSupplier : PackageSupplier\n    {\n        int foo(){ throw new Exception(\"failure\"); }\n        int bar(){ return 2;}\n    }\n\n    class BackupPackageSupplier : PackageSupplier\n    {\n        int foo(){ return -1; }\n        int bar(){ return -1;}\n    }\n\n    auto registry = new FallbackPackageSupplier(new FailingPackageSupplier(), new BackupPackageSupplier());\n\n    assert(registry.foo() == -1);\n    assert(registry.bar() == 2);\n}\n\n/*\n * Code-generating stuffs are encupsulated in this helper template so that\n * namespace pollution, which can cause name confliction with Base's public\n * members, should be minimized.\n */\nprivate template AutoImplement_Helper(string myName, string baseName,\n        Base, Self, alias generateMethodBody, alias cherrypickMethod)\n{\nprivate static:\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n    // Internal stuffs\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n    // Returns function overload sets in the class C, filtered with pred.\n    template enumerateOverloads(C, alias pred)\n    {\n        template Impl(names...)\n        {\n            import std.meta : Filter;\n            static if (names.length > 0)\n            {\n                alias methods = Filter!(pred, MemberFunctionsTuple!(C, names[0]));\n                alias next = Impl!(names[1 .. $]);\n\n                static if (methods.length > 0)\n                    alias Impl = AliasSeq!(OverloadSet!(names[0], methods), next);\n                else\n                    alias Impl = next;\n            }\n            else\n                alias Impl = AliasSeq!();\n        }\n\n        alias enumerateOverloads = Impl!(__traits(allMembers, C));\n    }\n\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n    // Target functions\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n    // Add a non-final check to the cherrypickMethod.\n    enum bool canonicalPicker(fun.../+[BUG 4217]+/) =\n        !__traits(isFinalFunction, fun[0]) && cherrypickMethod!(fun);\n\n    /*\n     * A tuple of overload sets, each item of which consists of functions to be\n     * implemented by the generated code.\n     */\n    alias targetOverloadSets = enumerateOverloads!(Base, canonicalPicker);\n\n    /*\n     * Super class of this AutoImplement instance\n     */\n    alias Super = BaseTypeTuple!(Self)[0];\n    static assert(is(Super == class));\n    static assert(is(Base == interface) || is(Super == Base));\n\n    /*\n     * A tuple of the super class' constructors.  Used for forwarding\n     * constructor calls.\n     */\n    static if (__traits(hasMember, Super, \"__ctor\"))\n        alias ctorOverloadSet = OverloadSet!(\"__ctor\", __traits(getOverloads, Super, \"__ctor\"));\n    else\n        alias ctorOverloadSet = OverloadSet!(\"__ctor\"); // empty\n\n\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n    // Type information\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n    /*\n     * The generated code will be mixed into AutoImplement, which will be\n     * instantiated in this module's scope.  Thus, any user-defined types are\n     * out of scope and cannot be used directly (i.e. by their names).\n     *\n     * We will use FuncInfo instances for accessing return types and parameter\n     * types of the implemented functions.  The instances will be populated to\n     * the AutoImplement's scope in a certain way; see the populate() below.\n     */\n\n    // Returns the preferred identifier for the FuncInfo instance for the i-th\n    // overloaded function with the name.\n    template INTERNAL_FUNCINFO_ID(string name, size_t i)\n    {\n        import std.format : format;\n\n        enum string INTERNAL_FUNCINFO_ID = format(\"F_%s_%s\", name, i);\n    }\n\n    /*\n     * Insert FuncInfo instances about all the target functions here.  This\n     * enables the generated code to access type information via, for example,\n     * \"autoImplement_helper_.F_foo_1\".\n     */\n    template populate(overloads...)\n    {\n        static if (overloads.length > 0)\n        {\n            mixin populate!(overloads[0].name, overloads[0].contents);\n            mixin populate!(overloads[1 .. $]);\n        }\n    }\n    template populate(string name, methods...)\n    {\n        static if (methods.length > 0)\n        {\n            mixin populate!(name, methods[0 .. $ - 1]);\n            //\n            alias target = methods[$ - 1];\n            enum ith = methods.length - 1;\n            mixin(\"alias \" ~ INTERNAL_FUNCINFO_ID!(name, ith) ~ \" = FuncInfo!target;\");\n        }\n    }\n\n    public mixin populate!(targetOverloadSets);\n    public mixin populate!(  ctorOverloadSet );\n\n\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n    // Code-generating policies\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n    /* Common policy configurations for generating constructors and methods. */\n    template CommonGeneratingPolicy()\n    {\n        // base class identifier which generated code should use\n        enum string BASE_CLASS_ID = baseName;\n\n        // FuncInfo instance identifier which generated code should use\n        template FUNCINFO_ID(string name, size_t i)\n        {\n            enum string FUNCINFO_ID =\n                myName ~ \".\" ~ INTERNAL_FUNCINFO_ID!(name, i);\n        }\n    }\n\n    /* Policy configurations for generating constructors. */\n    template ConstructorGeneratingPolicy()\n    {\n        mixin CommonGeneratingPolicy;\n\n        /* Generates constructor body.  Just forward to the base class' one. */\n        string generateFunctionBody(ctor.../+[BUG 4217]+/)() @property\n        {\n            enum varstyle = variadicFunctionStyle!(typeof(&ctor[0]));\n\n            static if (varstyle & (Variadic.c | Variadic.d))\n            {\n                // the argptr-forwarding problem\n                //pragma(msg, \"Warning: AutoImplement!(\", Base, \") \",\n                //        \"ignored variadic arguments to the constructor \",\n                //        FunctionTypeOf!(typeof(&ctor[0])) );\n            }\n            return \"super(args);\";\n        }\n    }\n\n    /* Policy configurations for genearting target methods. */\n    template MethodGeneratingPolicy()\n    {\n        mixin CommonGeneratingPolicy;\n\n        /* Geneartes method body. */\n        string generateFunctionBody(func.../+[BUG 4217]+/)() @property\n        {\n            return generateMethodBody!(Base, func); // given\n        }\n    }\n\n\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n    // Generated code\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n    alias ConstructorGenerator = MemberFunctionGenerator!(ConstructorGeneratingPolicy!());\n    alias MethodGenerator      = MemberFunctionGenerator!(MethodGeneratingPolicy!());\n\n    public enum string code =\n        ConstructorGenerator.generateCode!(  ctorOverloadSet ) ~ \"\\n\" ~\n             MethodGenerator.generateCode!(targetOverloadSets);\n\n    debug (SHOW_GENERATED_CODE)\n    {\n        pragma(msg, \"-------------------- < \", Base, \" >\");\n        pragma(msg, code);\n        pragma(msg, \"--------------------\");\n    }\n}\n\n//debug = SHOW_GENERATED_CODE;\n@system unittest\n{\n    import core.vararg;\n    // no function to implement\n    {\n        interface I_1 {}\n        auto o = new BlackHole!I_1;\n    }\n    // parameters\n    {\n        interface I_3 { void test(int, in int, out int, ref int, lazy int); }\n        auto o = new BlackHole!I_3;\n    }\n    // use of user-defined type\n    {\n        struct S {}\n        interface I_4 { S test(); }\n        auto o = new BlackHole!I_4;\n    }\n    // overloads\n    {\n        interface I_5\n        {\n            void test(string);\n            real test(real);\n            int  test();\n        }\n        auto o = new BlackHole!I_5;\n    }\n    // constructor forwarding\n    {\n        static class C_6\n        {\n            this(int n) { assert(n == 42); }\n            this(string s) { assert(s == \"Deeee\"); }\n            this(...) {}\n        }\n        auto o1 = new BlackHole!C_6(42);\n        auto o2 = new BlackHole!C_6(\"Deeee\");\n        auto o3 = new BlackHole!C_6(1, 2, 3, 4);\n    }\n    // attributes\n    {\n        interface I_7\n        {\n            ref int test_ref();\n            int test_pure() pure;\n            int test_nothrow() nothrow;\n            int test_property() @property;\n            int test_safe() @safe;\n            int test_trusted() @trusted;\n            int test_system() @system;\n            int test_pure_nothrow() pure nothrow;\n        }\n        auto o = new BlackHole!I_7;\n    }\n    // storage classes\n    {\n        interface I_8\n        {\n            void test_const() const;\n            void test_immutable() immutable;\n            void test_shared() shared;\n            void test_shared_const() shared const;\n        }\n        auto o = new BlackHole!I_8;\n    }\n    // use baseclass\n    {\n        static class C_9\n        {\n            private string foo_;\n\n            this(string s) {\n                foo_ = s;\n            }\n\n            protected string boilerplate() @property\n            {\n                return \"Boilerplate stuff.\";\n            }\n\n            public string foo() @property\n            {\n                return foo_;\n            }\n        }\n\n        interface I_10\n        {\n            string testMethod(size_t);\n        }\n\n        static string generateTestMethod(C, alias fun)() @property\n        {\n            return \"return this.boilerplate[0 .. a0];\";\n        }\n\n        auto o = new AutoImplement!(I_10, C_9, generateTestMethod)(\"Testing\");\n        assert(o.testMethod(11) == \"Boilerplate\");\n        assert(o.foo == \"Testing\");\n    }\n    /+ // deep inheritance\n    {\n    // XXX [BUG 2525,3525]\n    // NOTE: [r494] func.c(504-571) FuncDeclaration::semantic()\n        interface I { void foo(); }\n        interface J : I {}\n        interface K : J {}\n        static abstract class C_9 : K {}\n        auto o = new BlackHole!C_9;\n    }+/\n}\n\n// Issue 17177 - AutoImplement fails on function overload sets with \"cannot infer type from overloaded function symbol\"\n@system unittest\n{\n    static class Issue17177\n    {\n        private string n_;\n\n        public {\n            Issue17177 overloaded(string n)\n            {\n                this.n_ = n;\n\n                return this;\n            }\n\n            string overloaded()\n            {\n                return this.n_;\n            }\n        }\n    }\n\n    static string how(C, alias fun)()\n    {\n        static if (!is(ReturnType!fun == void))\n        {\n            return q{\n                return parent(args);\n            };\n        }\n        else\n        {\n            return q{\n                parent(args);\n            };\n        }\n    }\n\n    alias Implementation = AutoImplement!(Issue17177, how, templateNot!isFinalFunction);\n}\n\nversion (unittest)\n{\n    // Issue 10647\n    // Add prefix \"issue10647_\" as a workaround for issue 1238\n    private string issue10647_generateDoNothing(C, alias fun)() @property\n    {\n        string stmt;\n\n        static if (is(ReturnType!fun == void))\n            stmt ~= \"\";\n        else\n        {\n            string returnType = ReturnType!fun.stringof;\n            stmt ~= \"return \"~returnType~\".init;\";\n        }\n        return stmt;\n    }\n\n    private template issue10647_isAlwaysTrue(alias fun)\n    {\n        enum issue10647_isAlwaysTrue = true;\n    }\n\n    // Do nothing template\n    private template issue10647_DoNothing(Base)\n    {\n        alias issue10647_DoNothing = AutoImplement!(Base, issue10647_generateDoNothing, issue10647_isAlwaysTrue);\n    }\n\n    // A class to be overridden\n    private class issue10647_Foo{\n        void bar(int a) { }\n    }\n}\n@system unittest\n{\n    auto foo = new issue10647_DoNothing!issue10647_Foo();\n    foo.bar(13);\n}\n\n/*\nUsed by MemberFunctionGenerator.\n */\npackage template OverloadSet(string nam, T...)\n{\n    enum string name = nam;\n    alias contents = T;\n}\n\n/*\nUsed by MemberFunctionGenerator.\n */\npackage template FuncInfo(alias func, /+[BUG 4217 ?]+/ T = typeof(&func))\n{\n    alias RT = ReturnType!T;\n    alias PT = Parameters!T;\n}\npackage template FuncInfo(Func)\n{\n    alias RT = ReturnType!Func;\n    alias PT = Parameters!Func;\n}\n\n/*\nGeneral-purpose member function generator.\n--------------------\ntemplate GeneratingPolicy()\n{\n    // [optional] the name of the class where functions are derived\n    enum string BASE_CLASS_ID;\n\n    // [optional] define this if you have only function types\n    enum bool WITHOUT_SYMBOL;\n\n    // [optional] Returns preferred identifier for i-th parameter.\n    template PARAMETER_VARIABLE_ID(size_t i);\n\n    // Returns the identifier of the FuncInfo instance for the i-th overload\n    // of the specified name.  The identifier must be accessible in the scope\n    // where generated code is mixed.\n    template FUNCINFO_ID(string name, size_t i);\n\n    // Returns implemented function body as a string.  When WITHOUT_SYMBOL is\n    // defined, the latter is used.\n    template generateFunctionBody(alias func);\n    template generateFunctionBody(string name, FuncType);\n}\n--------------------\n */\npackage template MemberFunctionGenerator(alias Policy)\n{\nprivate static:\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n    // Internal stuffs\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n    import std.format;\n\n    enum CONSTRUCTOR_NAME = \"__ctor\";\n\n    // true if functions are derived from a base class\n    enum WITH_BASE_CLASS = __traits(hasMember, Policy, \"BASE_CLASS_ID\");\n\n    // true if functions are specified as types, not symbols\n    enum WITHOUT_SYMBOL = __traits(hasMember, Policy, \"WITHOUT_SYMBOL\");\n\n    // preferred identifier for i-th parameter variable\n    static if (__traits(hasMember, Policy, \"PARAMETER_VARIABLE_ID\"))\n    {\n        alias PARAMETER_VARIABLE_ID = Policy.PARAMETER_VARIABLE_ID;\n    }\n    else\n    {\n        enum string PARAMETER_VARIABLE_ID(size_t i) = format(\"a%s\", i);\n            // default: a0, a1, ...\n    }\n\n    // Returns a tuple consisting of 0,1,2,...,n-1.  For static foreach.\n    template CountUp(size_t n)\n    {\n        static if (n > 0)\n            alias CountUp = AliasSeq!(CountUp!(n - 1), n - 1);\n        else\n            alias CountUp = AliasSeq!();\n    }\n\n\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n    // Code generator\n    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://\n\n    /*\n     * Runs through all the target overload sets and generates D code which\n     * implements all the functions in the overload sets.\n     */\n    public string generateCode(overloads...)() @property\n    {\n        string code = \"\";\n\n        // run through all the overload sets\n        foreach (i_; CountUp!(0 + overloads.length)) // workaround\n        {\n            enum i = 0 + i_; // workaround\n            alias oset = overloads[i];\n\n            code ~= generateCodeForOverloadSet!(oset);\n\n            static if (WITH_BASE_CLASS && oset.name != CONSTRUCTOR_NAME)\n            {\n                // The generated function declarations may hide existing ones\n                // in the base class (cf. HiddenFuncError), so we put an alias\n                // declaration here to reveal possible hidden functions.\n                code ~= format(\"alias %s = %s.%s;\\n\",\n                            oset.name,\n                            Policy.BASE_CLASS_ID, // [BUG 2540] super.\n                            oset.name);\n            }\n        }\n        return code;\n    }\n\n    // handle each overload set\n    private string generateCodeForOverloadSet(alias oset)() @property\n    {\n        string code = \"\";\n\n        foreach (i_; CountUp!(0 + oset.contents.length)) // workaround\n        {\n            enum i = 0 + i_; // workaround\n            code ~= generateFunction!(\n                    Policy.FUNCINFO_ID!(oset.name, i), oset.name,\n                    oset.contents[i]) ~ \"\\n\";\n        }\n        return code;\n    }\n\n    /*\n     * Returns D code which implements the function func.  This function\n     * actually generates only the declarator part; the function body part is\n     * generated by the functionGenerator() policy.\n     */\n    public string generateFunction(\n            string myFuncInfo, string name, func... )() @property\n    {\n        import std.format : format;\n\n        enum isCtor = (name == CONSTRUCTOR_NAME);\n\n        string code; // the result\n\n        auto paramsRes = generateParameters!(myFuncInfo, func)();\n        code ~= paramsRes.imports;\n\n        /*** Function Declarator ***/\n        {\n            alias Func = FunctionTypeOf!(func);\n            alias FA = FunctionAttribute;\n            enum atts     = functionAttributes!(func);\n            enum realName = isCtor ? \"this\" : name;\n\n            // FIXME?? Make it so that these aren't CTFE funcs any more, since\n            // Format is deprecated, and format works at compile time?\n            /* Made them CTFE funcs just for the sake of Format!(...) */\n\n            // return type with optional \"ref\"\n            static string make_returnType()\n            {\n                string rtype = \"\";\n\n                if (!isCtor)\n                {\n                    if (atts & FA.ref_) rtype ~= \"ref \";\n                    rtype ~= myFuncInfo ~ \".RT\";\n                }\n                return rtype;\n            }\n            enum returnType = make_returnType();\n\n            // function attributes attached after declaration\n            static string make_postAtts()\n            {\n                string poatts = \"\";\n                if (atts & FA.pure_   ) poatts ~= \" pure\";\n                if (atts & FA.nothrow_) poatts ~= \" nothrow\";\n                if (atts & FA.property) poatts ~= \" @property\";\n                if (atts & FA.safe    ) poatts ~= \" @safe\";\n                if (atts & FA.trusted ) poatts ~= \" @trusted\";\n                return poatts;\n            }\n            enum postAtts = make_postAtts();\n\n            // function storage class\n            static string make_storageClass()\n            {\n                string postc = \"\";\n                if (is(Func ==    shared)) postc ~= \" shared\";\n                if (is(Func ==     const)) postc ~= \" const\";\n                if (is(Func ==     inout)) postc ~= \" inout\";\n                if (is(Func == immutable)) postc ~= \" immutable\";\n                return postc;\n            }\n            enum storageClass = make_storageClass();\n\n            //\n            if (__traits(isVirtualMethod, func))\n                code ~= \"override \";\n            code ~= format(\"extern(%s) %s %s(%s) %s %s\\n\",\n                    functionLinkage!(func),\n                    returnType,\n                    realName,\n                    paramsRes.params,\n                    postAtts, storageClass );\n        }\n\n        /*** Function Body ***/\n        code ~= \"{\\n\";\n        {\n            enum nparams = Parameters!(func).length;\n\n            /* Declare keywords: args, self and parent. */\n            string preamble;\n\n            preamble ~= \"alias args = AliasSeq!(\" ~ enumerateParameters!(nparams) ~ \");\\n\";\n            if (!isCtor)\n            {\n                preamble ~= \"alias self = \" ~ name ~ \";\\n\";\n                if (WITH_BASE_CLASS && !__traits(isAbstractFunction, func))\n                    preamble ~= \"alias parent = AliasSeq!(__traits(getMember, super, \\\"\" ~ name ~ \"\\\"))[0];\";\n            }\n\n            // Function body\n            static if (WITHOUT_SYMBOL)\n                enum fbody = Policy.generateFunctionBody!(name, func);\n            else\n                enum fbody = Policy.generateFunctionBody!(func);\n\n            code ~= preamble;\n            code ~= fbody;\n        }\n        code ~= \"}\";\n\n        return code;\n    }\n\n    /*\n     * Returns D code which declares function parameters,\n     * and optionally any imports (e.g. core.vararg)\n     * \"ref int a0, real a1, ...\"\n     */\n    static struct GenParams { string imports, params; }\n    private GenParams generateParameters(string myFuncInfo, func...)()\n    {\n        alias STC = ParameterStorageClass;\n        alias stcs = ParameterStorageClassTuple!(func);\n        enum nparams = stcs.length;\n\n        string imports = \"\"; // any imports required\n        string params = \"\"; // parameters\n\n        foreach (i, stc; stcs)\n        {\n            if (i > 0) params ~= \", \";\n\n            // Parameter storage classes.\n            if (stc & STC.scope_) params ~= \"scope \";\n            if (stc & STC.out_  ) params ~= \"out \";\n            if (stc & STC.ref_  ) params ~= \"ref \";\n            if (stc & STC.lazy_ ) params ~= \"lazy \";\n\n            // Take parameter type from the FuncInfo.\n            params ~= format(\"%s.PT[%s]\", myFuncInfo, i);\n\n            // Declare a parameter variable.\n            params ~= \" \" ~ PARAMETER_VARIABLE_ID!(i);\n        }\n\n        // Add some ellipsis part if needed.\n        auto style = variadicFunctionStyle!(func);\n        final switch (style)\n        {\n            case Variadic.no:\n                break;\n\n            case Variadic.c, Variadic.d:\n                imports ~= \"import core.vararg;\\n\";\n                // (...) or (a, b, ...)\n                params ~= (nparams == 0) ? \"...\" : \", ...\";\n                break;\n\n            case Variadic.typesafe:\n                params ~= \" ...\";\n                break;\n        }\n\n        return typeof(return)(imports, params);\n    }\n\n    // Returns D code which enumerates n parameter variables using comma as the\n    // separator.  \"a0, a1, a2, a3\"\n    private string enumerateParameters(size_t n)() @property\n    {\n        string params = \"\";\n\n        foreach (i_; CountUp!(n))\n        {\n            enum i = 0 + i_; // workaround\n            if (i > 0) params ~= \", \";\n            params ~= PARAMETER_VARIABLE_ID!(i);\n        }\n        return params;\n    }\n}\n\n\n/**\nPredefined how-policies for `AutoImplement`.  These templates are also used by\n`BlackHole` and `WhiteHole`, respectively.\n */\ntemplate generateEmptyFunction(C, func.../+[BUG 4217]+/)\n{\n    static if (is(ReturnType!(func) == void))\n        enum string generateEmptyFunction = q{\n        };\n    else static if (functionAttributes!(func) & FunctionAttribute.ref_)\n        enum string generateEmptyFunction = q{\n            static typeof(return) dummy;\n            return dummy;\n        };\n    else\n        enum string generateEmptyFunction = q{\n            return typeof(return).init;\n        };\n}\n\n///\n@system unittest\n{\n    alias BlackHole(Base) = AutoImplement!(Base, generateEmptyFunction);\n\n    interface I\n    {\n        int foo();\n        string bar();\n    }\n\n    auto i = new BlackHole!I();\n    // generateEmptyFunction returns the default value of the return type without doing anything\n    assert(i.foo == 0);\n    assert(i.bar is null);\n}\n\n/// ditto\ntemplate generateAssertTrap(C, func...)\n{\n    enum string generateAssertTrap =\n        `throw new NotImplementedError(\"` ~ C.stringof ~ \".\"\n                ~ __traits(identifier, func) ~ `\");`;\n}\n\n///\n@system unittest\n{\n    import std.exception : assertThrown;\n\n    alias WhiteHole(Base) = AutoImplement!(Base, generateAssertTrap);\n\n    interface I\n    {\n        int foo();\n        string bar();\n    }\n\n    auto i = new WhiteHole!I();\n    // generateAssertTrap throws an exception for every unimplemented function of the interface\n    assertThrown!NotImplementedError(i.foo);\n    assertThrown!NotImplementedError(i.bar);\n}\n\nprivate\n{\n    pragma(mangle, \"_d_toObject\")\n    extern(C) pure nothrow Object typecons_d_toObject(void* p);\n}\n\n/*\n * Avoids opCast operator overloading.\n */\nprivate template dynamicCast(T)\nif (is(T == class) || is(T == interface))\n{\n    @trusted\n    T dynamicCast(S)(inout S source)\n    if (is(S == class) || is(S == interface))\n    {\n        static if (is(Unqual!S : Unqual!T))\n        {\n            import std.traits : QualifierOf;\n            alias Qual = QualifierOf!S; // SharedOf or MutableOf\n            alias TmpT = Qual!(Unqual!T);\n            inout(TmpT) tmp = source;   // bypass opCast by implicit conversion\n            return *cast(T*)(&tmp);     // + variable pointer cast + dereference\n        }\n        else\n        {\n            return cast(T) typecons_d_toObject(*cast(void**)(&source));\n        }\n    }\n}\n\n@system unittest\n{\n    class C { @disable void opCast(T)(); }\n    auto c = new C;\n    static assert(!__traits(compiles, cast(Object) c));\n    auto o = dynamicCast!Object(c);\n    assert(c is o);\n\n    interface I { @disable void opCast(T)(); Object instance(); }\n    interface J { @disable void opCast(T)(); Object instance(); }\n    class D : I, J { Object instance() { return this; } }\n    I i = new D();\n    static assert(!__traits(compiles, cast(J) i));\n    J j = dynamicCast!J(i);\n    assert(i.instance() is j.instance());\n}\n\n/**\nSupports structural based typesafe conversion.\n\nIf `Source` has structural conformance with the `interface` `Targets`,\nwrap creates an internal wrapper class which inherits `Targets` and\nwraps the `src` object, then returns it.\n\n`unwrap` can be used to extract objects which have been wrapped by `wrap`.\n*/\ntemplate wrap(Targets...)\nif (Targets.length >= 1 && allSatisfy!(isMutable, Targets))\n{\n    import std.meta : staticMap;\n\n    // strict upcast\n    auto wrap(Source)(inout Source src) @trusted pure nothrow\n    if (Targets.length == 1 && is(Source : Targets[0]))\n    {\n        alias T = Select!(is(Source == shared), shared Targets[0], Targets[0]);\n        return dynamicCast!(inout T)(src);\n    }\n    // structural upcast\n    template wrap(Source)\n    if (!allSatisfy!(Bind!(isImplicitlyConvertible, Source), Targets))\n    {\n        auto wrap(inout Source src)\n        {\n            static assert(hasRequireMethods!(),\n                          \"Source \"~Source.stringof~\n                          \" does not have structural conformance to \"~\n                          Targets.stringof);\n\n            alias T = Select!(is(Source == shared), shared Impl, Impl);\n            return new inout T(src);\n        }\n\n        template FuncInfo(string s, F)\n        {\n            enum name = s;\n            alias type = F;\n        }\n\n        // issue 12064: Remove NVI members\n        template OnlyVirtual(members...)\n        {\n            enum notFinal(alias T) = !__traits(isFinalFunction, T);\n            alias OnlyVirtual = Filter!(notFinal, members);\n        }\n\n        // Concat all Targets function members into one tuple\n        template Concat(size_t i = 0)\n        {\n            static if (i >= Targets.length)\n                alias Concat = AliasSeq!();\n            else\n            {\n                alias Concat = AliasSeq!(OnlyVirtual!(GetOverloadedMethods!(Targets[i]), Concat!(i + 1)));\n            }\n        }\n\n        // Remove duplicated functions based on the identifier name and function type covariance\n        template Uniq(members...)\n        {\n            static if (members.length == 0)\n                alias Uniq = AliasSeq!();\n            else\n            {\n                alias func = members[0];\n                enum  name = __traits(identifier, func);\n                alias type = FunctionTypeOf!func;\n                template check(size_t i, mem...)\n                {\n                    static if (i >= mem.length)\n                        enum ptrdiff_t check = -1;\n                    else\n                    {\n                        enum ptrdiff_t check =\n                            __traits(identifier, func) == __traits(identifier, mem[i]) &&\n                            !is(DerivedFunctionType!(type, FunctionTypeOf!(mem[i])) == void)\n                          ? i : check!(i + 1, mem);\n                    }\n                }\n                enum ptrdiff_t x = 1 + check!(0, members[1 .. $]);\n                static if (x >= 1)\n                {\n                    alias typex = DerivedFunctionType!(type, FunctionTypeOf!(members[x]));\n                    alias remain = Uniq!(members[1 .. x], members[x + 1 .. $]);\n\n                    static if (remain.length >= 1 && remain[0].name == name &&\n                               !is(DerivedFunctionType!(typex, remain[0].type) == void))\n                    {\n                        alias F = DerivedFunctionType!(typex, remain[0].type);\n                        alias Uniq = AliasSeq!(FuncInfo!(name, F), remain[1 .. $]);\n                    }\n                    else\n                        alias Uniq = AliasSeq!(FuncInfo!(name, typex), remain);\n                }\n                else\n                {\n                    alias Uniq = AliasSeq!(FuncInfo!(name, type), Uniq!(members[1 .. $]));\n                }\n            }\n        }\n        alias TargetMembers = Uniq!(Concat!());             // list of FuncInfo\n        alias SourceMembers = GetOverloadedMethods!Source;  // list of function symbols\n\n        // Check whether all of SourceMembers satisfy covariance target in TargetMembers\n        template hasRequireMethods(size_t i = 0)\n        {\n            static if (i >= TargetMembers.length)\n                enum hasRequireMethods = true;\n            else\n            {\n                enum hasRequireMethods =\n                    findCovariantFunction!(TargetMembers[i], Source, SourceMembers) != -1 &&\n                    hasRequireMethods!(i + 1);\n            }\n        }\n\n        // Internal wrapper class\n        final class Impl : Structural, Targets\n        {\n        private:\n            Source _wrap_source;\n\n            this(       inout Source s)        inout @safe pure nothrow { _wrap_source = s; }\n            this(shared inout Source s) shared inout @safe pure nothrow { _wrap_source = s; }\n\n            // BUG: making private should work with NVI.\n            protected final inout(Object) _wrap_getSource() inout @trusted\n            {\n                return dynamicCast!(inout Object)(_wrap_source);\n            }\n\n            import std.conv : to;\n            import std.functional : forward;\n            template generateFun(size_t i)\n            {\n                enum name = TargetMembers[i].name;\n                enum fa = functionAttributes!(TargetMembers[i].type);\n                static @property stc()\n                {\n                    string r;\n                    if (fa & FunctionAttribute.property)    r ~= \"@property \";\n                    if (fa & FunctionAttribute.ref_)        r ~= \"ref \";\n                    if (fa & FunctionAttribute.pure_)       r ~= \"pure \";\n                    if (fa & FunctionAttribute.nothrow_)    r ~= \"nothrow \";\n                    if (fa & FunctionAttribute.trusted)     r ~= \"@trusted \";\n                    if (fa & FunctionAttribute.safe)        r ~= \"@safe \";\n                    return r;\n                }\n                static @property mod()\n                {\n                    alias type = AliasSeq!(TargetMembers[i].type)[0];\n                    string r;\n                    static if (is(type == immutable))       r ~= \" immutable\";\n                    else\n                    {\n                        static if (is(type == shared))      r ~= \" shared\";\n                        static if (is(type == const))       r ~= \" const\";\n                        else static if (is(type == inout))  r ~= \" inout\";\n                        //else  --> mutable\n                    }\n                    return r;\n                }\n                enum n = to!string(i);\n                static if (fa & FunctionAttribute.property)\n                {\n                    static if (Parameters!(TargetMembers[i].type).length == 0)\n                        enum fbody = \"_wrap_source.\"~name;\n                    else\n                        enum fbody = \"_wrap_source.\"~name~\" = forward!args\";\n                }\n                else\n                {\n                        enum fbody = \"_wrap_source.\"~name~\"(forward!args)\";\n                }\n                enum generateFun =\n                    \"override \"~stc~\"ReturnType!(TargetMembers[\"~n~\"].type) \"\n                    ~ name~\"(Parameters!(TargetMembers[\"~n~\"].type) args) \"~mod~\n                    \"{ return \"~fbody~\"; }\";\n            }\n\n        public:\n            mixin mixinAll!(\n                staticMap!(generateFun, staticIota!(0, TargetMembers.length)));\n        }\n    }\n}\n/// ditto\ntemplate wrap(Targets...)\nif (Targets.length >= 1 && !allSatisfy!(isMutable, Targets))\n{\n    import std.meta : staticMap;\n\n    alias wrap = .wrap!(staticMap!(Unqual, Targets));\n}\n\n/// ditto\ntemplate unwrap(Target)\nif (isMutable!Target)\n{\n    // strict downcast\n    auto unwrap(Source)(inout Source src) @trusted pure nothrow\n    if (is(Target : Source))\n    {\n        alias T = Select!(is(Source == shared), shared Target, Target);\n        return dynamicCast!(inout T)(src);\n    }\n    // structural downcast\n    auto unwrap(Source)(inout Source src) @trusted pure nothrow\n    if (!is(Target : Source))\n    {\n        alias T = Select!(is(Source == shared), shared Target, Target);\n        Object o = dynamicCast!(Object)(src);   // remove qualifier\n        do\n        {\n            if (auto a = dynamicCast!(Structural)(o))\n            {\n                if (auto d = dynamicCast!(inout T)(o = a._wrap_getSource()))\n                    return d;\n            }\n            else if (auto d = dynamicCast!(inout T)(o))\n                return d;\n            else\n                break;\n        } while (o);\n        return null;\n    }\n}\n\n/// ditto\ntemplate unwrap(Target)\nif (!isMutable!Target)\n{\n    alias unwrap = .unwrap!(Unqual!Target);\n}\n\n///\n@system unittest\n{\n    interface Quack\n    {\n        int quack();\n        @property int height();\n    }\n    interface Flyer\n    {\n        @property int height();\n    }\n    class Duck : Quack\n    {\n        int quack() { return 1; }\n        @property int height() { return 10; }\n    }\n    class Human\n    {\n        int quack() { return 2; }\n        @property int height() { return 20; }\n    }\n\n    Duck d1 = new Duck();\n    Human h1 = new Human();\n\n    interface Refleshable\n    {\n        int reflesh();\n    }\n\n    // does not have structural conformance\n    static assert(!__traits(compiles, d1.wrap!Refleshable));\n    static assert(!__traits(compiles, h1.wrap!Refleshable));\n\n    // strict upcast\n    Quack qd = d1.wrap!Quack;\n    assert(qd is d1);\n    assert(qd.quack() == 1);    // calls Duck.quack\n    // strict downcast\n    Duck d2 = qd.unwrap!Duck;\n    assert(d2 is d1);\n\n    // structural upcast\n    Quack qh = h1.wrap!Quack;\n    assert(qh.quack() == 2);    // calls Human.quack\n    // structural downcast\n    Human h2 = qh.unwrap!Human;\n    assert(h2 is h1);\n\n    // structural upcast (two steps)\n    Quack qx = h1.wrap!Quack;   // Human -> Quack\n    Flyer fx = qx.wrap!Flyer;   // Quack -> Flyer\n    assert(fx.height == 20);    // calls Human.height\n    // structural downcast (two steps)\n    Quack qy = fx.unwrap!Quack; // Flyer -> Quack\n    Human hy = qy.unwrap!Human; // Quack -> Human\n    assert(hy is h1);\n    // structural downcast (one step)\n    Human hz = fx.unwrap!Human; // Flyer -> Human\n    assert(hz is h1);\n}\n\n///\n@system unittest\n{\n    import std.traits : FunctionAttribute, functionAttributes;\n    interface A { int run(); }\n    interface B { int stop(); @property int status(); }\n    class X\n    {\n        int run() { return 1; }\n        int stop() { return 2; }\n        @property int status() { return 3; }\n    }\n\n    auto x = new X();\n    auto ab = x.wrap!(A, B);\n    A a = ab;\n    B b = ab;\n    assert(a.run() == 1);\n    assert(b.stop() == 2);\n    assert(b.status == 3);\n    static assert(functionAttributes!(typeof(ab).status) & FunctionAttribute.property);\n}\n\n// Internal class to support dynamic cross-casting\nprivate interface Structural\n{\n    inout(Object) _wrap_getSource() inout @safe pure nothrow;\n}\n\n@system unittest\n{\n    class A\n    {\n        int draw()              { return 1; }\n        int draw(int v)         { return v; }\n\n        int draw() const        { return 2; }\n        int draw() shared       { return 3; }\n        int draw() shared const { return 4; }\n        int draw() immutable    { return 5; }\n    }\n    interface Drawable\n    {\n        int draw();\n        int draw() const;\n        int draw() shared;\n        int draw() shared const;\n        int draw() immutable;\n    }\n    interface Drawable2\n    {\n        int draw(int v);\n    }\n\n    auto ma = new A();\n    auto sa = new shared A();\n    auto ia = new immutable A();\n    {\n                     Drawable  md = ma.wrap!Drawable;\n               const Drawable  cd = ma.wrap!Drawable;\n              shared Drawable  sd = sa.wrap!Drawable;\n        shared const Drawable scd = sa.wrap!Drawable;\n           immutable Drawable  id = ia.wrap!Drawable;\n        assert( md.draw() == 1);\n        assert( cd.draw() == 2);\n        assert( sd.draw() == 3);\n        assert(scd.draw() == 4);\n        assert( id.draw() == 5);\n    }\n    {\n        Drawable2 d = ma.wrap!Drawable2;\n        static assert(!__traits(compiles, d.draw()));\n        assert(d.draw(10) == 10);\n    }\n}\n@system unittest\n{\n    // Bugzilla 10377\n    import std.range, std.algorithm;\n\n    interface MyInputRange(T)\n    {\n        @property T front();\n        void popFront();\n        @property bool empty();\n    }\n\n    //auto o = iota(0,10,1).inputRangeObject();\n    //pragma(msg, __traits(allMembers, typeof(o)));\n    auto r = iota(0,10,1).inputRangeObject().wrap!(MyInputRange!int)();\n    assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));\n}\n@system unittest\n{\n    // Bugzilla 10536\n    interface Interface\n    {\n        int foo();\n    }\n    class Pluggable\n    {\n        int foo() { return 1; }\n        @disable void opCast(T, this X)();  // !\n    }\n\n    Interface i = new Pluggable().wrap!Interface;\n    assert(i.foo() == 1);\n}\n@system unittest\n{\n    // Enhancement 10538\n    interface Interface\n    {\n        int foo();\n        int bar(int);\n    }\n    class Pluggable\n    {\n        int opDispatch(string name, A...)(A args) { return 100; }\n    }\n\n    Interface i = wrap!Interface(new Pluggable());\n    assert(i.foo() == 100);\n    assert(i.bar(10) == 100);\n}\n\n@system unittest // issue 12064\n{\n    interface I\n    {\n        int foo();\n        final int nvi1(){return foo();}\n    }\n\n    interface J\n    {\n        int bar();\n        final int nvi2(){return bar();}\n    }\n\n    class Baz\n    {\n        int foo() { return 42;}\n        int bar() { return 12064;}\n    }\n\n    auto baz = new Baz();\n    auto foobar = baz.wrap!(I, J)();\n    assert(foobar.nvi1 == 42);\n    assert(foobar.nvi2 == 12064);\n}\n\n// Make a tuple of non-static function symbols\npackage template GetOverloadedMethods(T)\n{\n    import std.meta : Filter;\n\n    alias allMembers = AliasSeq!(__traits(allMembers, T));\n    template follows(size_t i = 0)\n    {\n        static if (i >= allMembers.length)\n        {\n            alias follows = AliasSeq!();\n        }\n        else static if (!__traits(compiles, mixin(\"T.\"~allMembers[i])))\n        {\n            alias follows = follows!(i + 1);\n        }\n        else\n        {\n            enum name = allMembers[i];\n\n            template isMethod(alias f)\n            {\n                static if (is(typeof(&f) F == F*) && is(F == function))\n                    enum isMethod = !__traits(isStaticFunction, f);\n                else\n                    enum isMethod = false;\n            }\n            alias follows = AliasSeq!(\n                std.meta.Filter!(isMethod, __traits(getOverloads, T, name)),\n                follows!(i + 1));\n        }\n    }\n    alias GetOverloadedMethods = follows!();\n}\n// find a function from Fs that has same identifier and covariant type with f\nprivate template findCovariantFunction(alias finfo, Source, Fs...)\n{\n    template check(size_t i = 0)\n    {\n        static if (i >= Fs.length)\n            enum ptrdiff_t check = -1;\n        else\n        {\n            enum ptrdiff_t check =\n                (finfo.name == __traits(identifier, Fs[i])) &&\n                isCovariantWith!(FunctionTypeOf!(Fs[i]), finfo.type)\n              ? i : check!(i + 1);\n        }\n    }\n    enum x = check!();\n    static if (x == -1 && is(typeof(Source.opDispatch)))\n    {\n        alias Params = Parameters!(finfo.type);\n        enum ptrdiff_t findCovariantFunction =\n            is(typeof((             Source).init.opDispatch!(finfo.name)(Params.init))) ||\n            is(typeof((       const Source).init.opDispatch!(finfo.name)(Params.init))) ||\n            is(typeof((   immutable Source).init.opDispatch!(finfo.name)(Params.init))) ||\n            is(typeof((      shared Source).init.opDispatch!(finfo.name)(Params.init))) ||\n            is(typeof((shared const Source).init.opDispatch!(finfo.name)(Params.init)))\n          ? ptrdiff_t.max : -1;\n    }\n    else\n        enum ptrdiff_t findCovariantFunction = x;\n}\n\nprivate enum TypeModifier\n{\n    mutable     = 0,    // type is mutable\n    const_      = 1,    // type is const\n    immutable_  = 2,    // type is immutable\n    shared_     = 4,    // type is shared\n    inout_      = 8,    // type is wild\n}\nprivate template TypeMod(T)\n{\n    static if (is(T == immutable))\n    {\n        enum mod1 = TypeModifier.immutable_;\n        enum mod2 = 0;\n    }\n    else\n    {\n        enum mod1 = is(T == shared) ? TypeModifier.shared_ : 0;\n        static if (is(T == const))\n            enum mod2 = TypeModifier.const_;\n        else static if (is(T == inout))\n            enum mod2 = TypeModifier.inout_;\n        else\n            enum mod2 = TypeModifier.mutable;\n    }\n    enum TypeMod = cast(TypeModifier)(mod1 | mod2);\n}\n\nversion (unittest)\n{\n    private template UnittestFuncInfo(alias f)\n    {\n        enum name = __traits(identifier, f);\n        alias type = FunctionTypeOf!f;\n    }\n}\n@system unittest\n{\n    class A\n    {\n        int draw() { return 1; }\n        @property int value() { return 2; }\n        final int run() { return 3; }\n    }\n    alias methods = GetOverloadedMethods!A;\n\n    alias int F1();\n    alias @property int F2();\n    alias string F3();\n    alias nothrow @trusted uint F4();\n    alias int F5(Object);\n    alias bool F6(Object);\n    static assert(methods.length == 3 + 4);\n    static assert(__traits(identifier, methods[0]) == \"draw\"     && is(typeof(&methods[0]) == F1*));\n    static assert(__traits(identifier, methods[1]) == \"value\"    && is(typeof(&methods[1]) == F2*));\n    static assert(__traits(identifier, methods[2]) == \"run\"      && is(typeof(&methods[2]) == F1*));\n\n    int draw();\n    @property int value();\n    void opEquals();\n    int nomatch();\n    static assert(findCovariantFunction!(UnittestFuncInfo!draw,     A, methods) == 0);\n    static assert(findCovariantFunction!(UnittestFuncInfo!value,    A, methods) == 1);\n    static assert(findCovariantFunction!(UnittestFuncInfo!opEquals, A, methods) == -1);\n    static assert(findCovariantFunction!(UnittestFuncInfo!nomatch,  A, methods) == -1);\n\n    // considering opDispatch\n    class B\n    {\n        void opDispatch(string name, A...)(A) {}\n    }\n    alias methodsB = GetOverloadedMethods!B;\n    static assert(findCovariantFunction!(UnittestFuncInfo!draw,     B, methodsB) == ptrdiff_t.max);\n    static assert(findCovariantFunction!(UnittestFuncInfo!value,    B, methodsB) == ptrdiff_t.max);\n    static assert(findCovariantFunction!(UnittestFuncInfo!opEquals, B, methodsB) == ptrdiff_t.max);\n    static assert(findCovariantFunction!(UnittestFuncInfo!nomatch,  B, methodsB) == ptrdiff_t.max);\n}\n\npackage template DerivedFunctionType(T...)\n{\n    static if (!T.length)\n    {\n        alias DerivedFunctionType = void;\n    }\n    else static if (T.length == 1)\n    {\n        static if (is(T[0] == function))\n        {\n            alias DerivedFunctionType = T[0];\n        }\n        else\n        {\n            alias DerivedFunctionType = void;\n        }\n    }\n    else static if (is(T[0] P0 == function) && is(T[1] P1 == function))\n    {\n        alias FA = FunctionAttribute;\n\n        alias F0 = T[0], R0 = ReturnType!F0, PSTC0 = ParameterStorageClassTuple!F0;\n        alias F1 = T[1], R1 = ReturnType!F1, PSTC1 = ParameterStorageClassTuple!F1;\n        enum FA0 = functionAttributes!F0;\n        enum FA1 = functionAttributes!F1;\n\n        template CheckParams(size_t i = 0)\n        {\n            static if (i >= P0.length)\n                enum CheckParams = true;\n            else\n            {\n                enum CheckParams = (is(P0[i] == P1[i]) && PSTC0[i] == PSTC1[i]) &&\n                                   CheckParams!(i + 1);\n            }\n        }\n        static if (R0.sizeof == R1.sizeof && !is(CommonType!(R0, R1) == void) &&\n                   P0.length == P1.length && CheckParams!() && TypeMod!F0 == TypeMod!F1 &&\n                   variadicFunctionStyle!F0 == variadicFunctionStyle!F1 &&\n                   functionLinkage!F0 == functionLinkage!F1 &&\n                   ((FA0 ^ FA1) & (FA.ref_ | FA.property)) == 0)\n        {\n            alias R = Select!(is(R0 : R1), R0, R1);\n            alias FX = FunctionTypeOf!(R function(P0));\n            // @system is default\n            alias FY = SetFunctionAttributes!(FX, functionLinkage!F0, (FA0 | FA1) & ~FA.system);\n            alias DerivedFunctionType = DerivedFunctionType!(FY, T[2 .. $]);\n        }\n        else\n            alias DerivedFunctionType = void;\n    }\n    else\n        alias DerivedFunctionType = void;\n}\n@safe unittest\n{\n    // attribute covariance\n    alias int F1();\n    static assert(is(DerivedFunctionType!(F1, F1) == F1));\n    alias int F2() pure nothrow;\n    static assert(is(DerivedFunctionType!(F1, F2) == F2));\n    alias int F3() @safe;\n    alias int F23() @safe pure nothrow;\n    static assert(is(DerivedFunctionType!(F2, F3) == F23));\n\n    // return type covariance\n    alias long F4();\n    static assert(is(DerivedFunctionType!(F1, F4) == void));\n    class C {}\n    class D : C {}\n    alias C F5();\n    alias D F6();\n    static assert(is(DerivedFunctionType!(F5, F6) == F6));\n    alias typeof(null) F7();\n    alias int[] F8();\n    alias int* F9();\n    static assert(is(DerivedFunctionType!(F5, F7) == F7));\n    static assert(is(DerivedFunctionType!(F7, F8) == void));\n    static assert(is(DerivedFunctionType!(F7, F9) == F7));\n\n    // variadic type equality\n    alias int F10(int);\n    alias int F11(int...);\n    alias int F12(int, ...);\n    static assert(is(DerivedFunctionType!(F10, F11) == void));\n    static assert(is(DerivedFunctionType!(F10, F12) == void));\n    static assert(is(DerivedFunctionType!(F11, F12) == void));\n\n    // linkage equality\n    alias extern(C) int F13(int);\n    alias extern(D) int F14(int);\n    alias extern(Windows) int F15(int);\n    static assert(is(DerivedFunctionType!(F13, F14) == void));\n    static assert(is(DerivedFunctionType!(F13, F15) == void));\n    static assert(is(DerivedFunctionType!(F14, F15) == void));\n\n    // ref & @property equality\n    alias int F16(int);\n    alias ref int F17(int);\n    alias @property int F18(int);\n    static assert(is(DerivedFunctionType!(F16, F17) == void));\n    static assert(is(DerivedFunctionType!(F16, F18) == void));\n    static assert(is(DerivedFunctionType!(F17, F18) == void));\n}\n\npackage template staticIota(int beg, int end)\n{\n    static if (beg + 1 >= end)\n    {\n        static if (beg >= end)\n        {\n            alias staticIota = AliasSeq!();\n        }\n        else\n        {\n            alias staticIota = AliasSeq!(+beg);\n        }\n    }\n    else\n    {\n        enum mid = beg + (end - beg) / 2;\n        alias staticIota = AliasSeq!(staticIota!(beg, mid), staticIota!(mid, end));\n    }\n}\n\npackage template mixinAll(mixins...)\n{\n    static if (mixins.length == 1)\n    {\n        static if (is(typeof(mixins[0]) == string))\n        {\n            mixin(mixins[0]);\n        }\n        else\n        {\n            alias it = mixins[0];\n            mixin it;\n        }\n    }\n    else static if (mixins.length >= 2)\n    {\n        mixin mixinAll!(mixins[ 0 .. $/2]);\n        mixin mixinAll!(mixins[$/2 .. $ ]);\n    }\n}\n\npackage template Bind(alias Template, args1...)\n{\n    alias Bind(args2...) = Template!(args1, args2);\n}\n\n\n/**\nOptions regarding auto-initialization of a `RefCounted` object (see\nthe definition of `RefCounted` below).\n */\nenum RefCountedAutoInitialize\n{\n    /// Do not auto-initialize the object\n    no,\n    /// Auto-initialize the object\n    yes,\n}\n\n///\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.exception : assertThrown;\n\n    struct Foo\n    {\n        int a = 42;\n    }\n\n    RefCounted!(Foo, RefCountedAutoInitialize.yes) rcAuto;\n    RefCounted!(Foo, RefCountedAutoInitialize.no) rcNoAuto;\n\n    assert(rcAuto.refCountedPayload.a == 42);\n\n    assertThrown!AssertError(rcNoAuto.refCountedPayload);\n    rcNoAuto.refCountedStore.ensureInitialized;\n    assert(rcNoAuto.refCountedPayload.a == 42);\n}\n\n/**\nDefines a reference-counted object containing a `T` value as\npayload.\n\nAn instance of `RefCounted` is a reference to a structure,\nwhich is referred to as the $(I store), or $(I storage implementation\nstruct) in this documentation.  The store contains a reference count\nand the `T` payload.  `RefCounted` uses `malloc` to allocate\nthe store.  As instances of `RefCounted` are copied or go out of\nscope, they will automatically increment or decrement the reference\ncount.  When the reference count goes down to zero, `RefCounted`\nwill call `destroy` against the payload and call `free` to\ndeallocate the store.  If the `T` payload contains any references\nto GC-allocated memory, then `RefCounted` will add it to the GC memory\nthat is scanned for pointers, and remove it from GC scanning before\n`free` is called on the store.\n\nOne important consequence of `destroy` is that it will call the\ndestructor of the `T` payload.  GC-managed references are not\nguaranteed to be valid during a destructor call, but other members of\n`T`, such as file handles or pointers to `malloc` memory, will\nstill be valid during the destructor call.  This allows the `T` to\ndeallocate or clean up any non-GC resources immediately after the\nreference count has reached zero.\n\n`RefCounted` is unsafe and should be used with care. No references\nto the payload should be escaped outside the `RefCounted` object.\n\nThe `autoInit` option makes the object ensure the store is\nautomatically initialized. Leaving $(D autoInit ==\nRefCountedAutoInitialize.yes) (the default option) is convenient but\nhas the cost of a test whenever the payload is accessed. If $(D\nautoInit == RefCountedAutoInitialize.no), user code must call either\n`refCountedStore.isInitialized` or `refCountedStore.ensureInitialized`\nbefore attempting to access the payload. Not doing so results in null\npointer dereference.\n */\nstruct RefCounted(T, RefCountedAutoInitialize autoInit =\n        RefCountedAutoInitialize.yes)\nif (!is(T == class) && !(is(T == interface)))\n{\n    extern(C) private pure nothrow @nogc static // TODO remove pure when https://issues.dlang.org/show_bug.cgi?id=15862 has been fixed\n    {\n        pragma(mangle, \"free\") void pureFree( void *ptr );\n        pragma(mangle, \"gc_addRange\") void pureGcAddRange( in void* p, size_t sz, const TypeInfo ti = null );\n        pragma(mangle, \"gc_removeRange\") void pureGcRemoveRange( in void* p );\n    }\n\n    /// `RefCounted` storage implementation.\n    struct RefCountedStore\n    {\n        import core.memory : pureMalloc;\n        private struct Impl\n        {\n            T _payload;\n            size_t _count;\n        }\n\n        private Impl* _store;\n\n        private void initialize(A...)(auto ref A args)\n        {\n            import core.exception : onOutOfMemoryError;\n            import std.conv : emplace;\n\n            _store = cast(Impl*) pureMalloc(Impl.sizeof);\n            if (_store is null)\n                onOutOfMemoryError();\n            static if (hasIndirections!T)\n                pureGcAddRange(&_store._payload, T.sizeof);\n            emplace(&_store._payload, args);\n            _store._count = 1;\n        }\n\n        private void move(ref T source)\n        {\n            import core.exception : onOutOfMemoryError;\n            import core.stdc.string : memcpy, memset;\n\n            _store = cast(Impl*) pureMalloc(Impl.sizeof);\n            if (_store is null)\n                onOutOfMemoryError();\n            static if (hasIndirections!T)\n                pureGcAddRange(&_store._payload, T.sizeof);\n\n            // Can't use std.algorithm.move(source, _store._payload)\n            // here because it requires the target to be initialized.\n            // Might be worth to add this as `moveEmplace`\n\n            // Can avoid destructing result.\n            static if (hasElaborateAssign!T || !isAssignable!T)\n                memcpy(&_store._payload, &source, T.sizeof);\n            else\n                _store._payload = source;\n\n            // If the source defines a destructor or a postblit hook, we must obliterate the\n            // object in order to avoid double freeing and undue aliasing\n            static if (hasElaborateDestructor!T || hasElaborateCopyConstructor!T)\n            {\n                // If T is nested struct, keep original context pointer\n                static if (__traits(isNested, T))\n                    enum sz = T.sizeof - (void*).sizeof;\n                else\n                    enum sz = T.sizeof;\n\n                static if (__traits(isZeroInit, T))\n                    memset(&source, 0, sz);\n                else\n                {\n                    auto init = typeid(T).initializer();\n                    memcpy(&source, init.ptr, sz);\n                }\n            }\n\n            _store._count = 1;\n        }\n\n        /**\n           Returns `true` if and only if the underlying store has been\n           allocated and initialized.\n        */\n        @property nothrow @safe pure @nogc\n        bool isInitialized() const\n        {\n            return _store !is null;\n        }\n\n        /**\n           Returns underlying reference count if it is allocated and initialized\n           (a positive integer), and `0` otherwise.\n        */\n        @property nothrow @safe pure @nogc\n        size_t refCount() const\n        {\n            return isInitialized ? _store._count : 0;\n        }\n\n        /**\n           Makes sure the payload was properly initialized. Such a\n           call is typically inserted before using the payload.\n        */\n        void ensureInitialized()\n        {\n            if (!isInitialized) initialize();\n        }\n\n    }\n    RefCountedStore _refCounted;\n\n    /// Returns storage implementation struct.\n    @property nothrow @safe\n    ref inout(RefCountedStore) refCountedStore() inout\n    {\n        return _refCounted;\n    }\n\n/**\nConstructor that initializes the payload.\n\nPostcondition: `refCountedStore.isInitialized`\n */\n    this(A...)(auto ref A args) if (A.length > 0)\n    {\n        _refCounted.initialize(args);\n    }\n\n    /// Ditto\n    this(T val)\n    {\n        _refCounted.move(val);\n    }\n\n/**\nConstructor that tracks the reference count appropriately. If $(D\n!refCountedStore.isInitialized), does nothing.\n */\n    this(this) @safe pure nothrow @nogc\n    {\n        if (!_refCounted.isInitialized) return;\n        ++_refCounted._store._count;\n    }\n\n/**\nDestructor that tracks the reference count appropriately. If $(D\n!refCountedStore.isInitialized), does nothing. When the reference count goes\ndown to zero, calls `destroy` agaist the payload and calls `free`\nto deallocate the corresponding resource.\n */\n    ~this()\n    {\n        if (!_refCounted.isInitialized) return;\n        assert(_refCounted._store._count > 0);\n        if (--_refCounted._store._count)\n            return;\n        // Done, deallocate\n        .destroy(_refCounted._store._payload);\n        static if (hasIndirections!T)\n        {\n            pureGcRemoveRange(&_refCounted._store._payload);\n        }\n\n        pureFree(_refCounted._store);\n        _refCounted._store = null;\n    }\n\n/**\nAssignment operators\n */\n    void opAssign(typeof(this) rhs)\n    {\n        import std.algorithm.mutation : swap;\n\n        swap(_refCounted._store, rhs._refCounted._store);\n    }\n\n/// Ditto\n    void opAssign(T rhs)\n    {\n        import std.algorithm.mutation : move;\n\n        static if (autoInit == RefCountedAutoInitialize.yes)\n        {\n            _refCounted.ensureInitialized();\n        }\n        else\n        {\n            assert(_refCounted.isInitialized);\n        }\n        move(rhs, _refCounted._store._payload);\n    }\n\n    //version to have a single properly ddoc'ed function (w/ correct sig)\n    version (StdDdoc)\n    {\n        /**\n        Returns a reference to the payload. If (autoInit ==\n        RefCountedAutoInitialize.yes), calls $(D\n        refCountedStore.ensureInitialized). Otherwise, just issues $(D\n        assert(refCountedStore.isInitialized)). Used with $(D alias\n        refCountedPayload this;), so callers can just use the `RefCounted`\n        object as a `T`.\n\n        $(BLUE The first overload exists only if $(D autoInit == RefCountedAutoInitialize.yes).)\n        So if $(D autoInit == RefCountedAutoInitialize.no)\n        or called for a constant or immutable object, then\n        `refCountedPayload` will also be qualified as safe and nothrow\n        (but will still assert if not initialized).\n         */\n        @property @trusted\n        ref T refCountedPayload() return;\n\n        /// ditto\n        @property nothrow @safe pure @nogc\n        ref inout(T) refCountedPayload() inout return;\n    }\n    else\n    {\n        static if (autoInit == RefCountedAutoInitialize.yes)\n        {\n            //Can't use inout here because of potential mutation\n            @property\n            ref T refCountedPayload() return\n            {\n                _refCounted.ensureInitialized();\n                return _refCounted._store._payload;\n            }\n        }\n\n        @property nothrow @safe pure @nogc\n        ref inout(T) refCountedPayload() inout return\n        {\n            assert(_refCounted.isInitialized, \"Attempted to access an uninitialized payload.\");\n            return _refCounted._store._payload;\n        }\n    }\n\n/**\nReturns a reference to the payload. If (autoInit ==\nRefCountedAutoInitialize.yes), calls $(D\nrefCountedStore.ensureInitialized). Otherwise, just issues $(D\nassert(refCountedStore.isInitialized)).\n */\n    alias refCountedPayload this;\n}\n\n///\npure @system nothrow @nogc unittest\n{\n    // A pair of an `int` and a `size_t` - the latter being the\n    // reference count - will be dynamically allocated\n    auto rc1 = RefCounted!int(5);\n    assert(rc1 == 5);\n    // No more allocation, add just one extra reference count\n    auto rc2 = rc1;\n    // Reference semantics\n    rc2 = 42;\n    assert(rc1 == 42);\n    // the pair will be freed when rc1 and rc2 go out of scope\n}\n\npure @system unittest\n{\n    RefCounted!int* p;\n    {\n        auto rc1 = RefCounted!int(5);\n        p = &rc1;\n        assert(rc1 == 5);\n        assert(rc1._refCounted._store._count == 1);\n        auto rc2 = rc1;\n        assert(rc1._refCounted._store._count == 2);\n        // Reference semantics\n        rc2 = 42;\n        assert(rc1 == 42);\n        rc2 = rc2;\n        assert(rc2._refCounted._store._count == 2);\n        rc1 = rc2;\n        assert(rc1._refCounted._store._count == 2);\n    }\n    assert(p._refCounted._store == null);\n\n    // RefCounted as a member\n    struct A\n    {\n        RefCounted!int x;\n        this(int y)\n        {\n            x._refCounted.initialize(y);\n        }\n        A copy()\n        {\n            auto another = this;\n            return another;\n        }\n    }\n    auto a = A(4);\n    auto b = a.copy();\n    assert(a.x._refCounted._store._count == 2, \"BUG 4356 still unfixed\");\n}\n\npure @system nothrow @nogc unittest\n{\n    import std.algorithm.mutation : swap;\n\n    RefCounted!int p1, p2;\n    swap(p1, p2);\n}\n\n// 6606\n@safe pure nothrow @nogc unittest\n{\n    union U {\n       size_t i;\n       void* p;\n    }\n\n    struct S {\n       U u;\n    }\n\n    alias SRC = RefCounted!S;\n}\n\n// 6436\n@system pure unittest\n{\n    struct S { this(ref int val) { assert(val == 3); ++val; } }\n\n    int val = 3;\n    auto s = RefCounted!S(val);\n    assert(val == 4);\n}\n\n// gc_addRange coverage\n@system pure unittest\n{\n    struct S { int* p; }\n\n    auto s = RefCounted!S(null);\n}\n\n@system pure nothrow @nogc unittest\n{\n    RefCounted!int a;\n    a = 5; //This should not assert\n    assert(a == 5);\n\n    RefCounted!int b;\n    b = a; //This should not assert either\n    assert(b == 5);\n\n    RefCounted!(int*) c;\n}\n\n/**\n * Initializes a `RefCounted` with `val`. The template parameter\n * `T` of `RefCounted` is inferred from `val`.\n * This function can be used to move non-copyable values to the heap.\n * It also disables the `autoInit` option of `RefCounted`.\n *\n * Params:\n *   val = The value to be reference counted\n * Returns:\n *   An initialized `RefCounted` containing `val`.\n * See_Also:\n *   $(HTTP en.cppreference.com/w/cpp/memory/shared_ptr/make_shared, C++'s make_shared)\n */\nRefCounted!(T, RefCountedAutoInitialize.no) refCounted(T)(T val)\n{\n    typeof(return) res;\n    res._refCounted.move(val);\n    return res;\n}\n\n///\n@system unittest\n{\n    static struct File\n    {\n        string name;\n        @disable this(this); // not copyable\n        ~this() { name = null; }\n    }\n\n    auto file = File(\"name\");\n    assert(file.name == \"name\");\n    // file cannot be copied and has unique ownership\n    static assert(!__traits(compiles, {auto file2 = file;}));\n\n    // make the file refcounted to share ownership\n    import std.algorithm.mutation : move;\n    auto rcFile = refCounted(move(file));\n    assert(rcFile.name == \"name\");\n    assert(file.name == null);\n    auto rcFile2 = rcFile;\n    assert(rcFile.refCountedStore.refCount == 2);\n    // file gets properly closed when last reference is dropped\n}\n\n/**\n    Creates a proxy for the value `a` that will forward all operations\n    while disabling implicit conversions. The aliased item `a` must be\n    an $(B lvalue). This is useful for creating a new type from the\n    \"base\" type (though this is $(B not) a subtype-supertype\n    relationship; the new type is not related to the old type in any way,\n    by design).\n\n    The new type supports all operations that the underlying type does,\n    including all operators such as `+`, `--`, `<`, `[]`, etc.\n\n    Params:\n        a = The value to act as a proxy for all operations. It must\n            be an lvalue.\n */\nmixin template Proxy(alias a)\n{\n    private alias ValueType = typeof({ return a; }());\n\n    /* Determine if 'T.a' can referenced via a const(T).\n     * Use T* as the parameter because 'scope' inference needs a fully\n     * analyzed T, which doesn't work when accessibleFrom() is used in a\n     * 'static if' in the definition of Proxy or T.\n     */\n    private enum bool accessibleFrom(T) =\n        is(typeof((T* self){ cast(void) mixin(\"(*self).\"~__traits(identifier, a)); }));\n\n    static if (is(typeof(this) == class))\n    {\n        override bool opEquals(Object o)\n        {\n            if (auto b = cast(typeof(this))o)\n            {\n                return a == mixin(\"b.\"~__traits(identifier, a));\n            }\n            return false;\n        }\n\n        bool opEquals(T)(T b)\n            if (is(ValueType : T) || is(typeof(a.opEquals(b))) || is(typeof(b.opEquals(a))))\n        {\n            static if (is(typeof(a.opEquals(b))))\n                return a.opEquals(b);\n            else static if (is(typeof(b.opEquals(a))))\n                return b.opEquals(a);\n            else\n                return a == b;\n        }\n\n        override int opCmp(Object o)\n        {\n            if (auto b = cast(typeof(this))o)\n            {\n                return a < mixin(\"b.\"~__traits(identifier, a)) ? -1\n                     : a > mixin(\"b.\"~__traits(identifier, a)) ? +1 : 0;\n            }\n            static if (is(ValueType == class))\n                return a.opCmp(o);\n            else\n                throw new Exception(\"Attempt to compare a \"~typeid(this).toString~\" and a \"~typeid(o).toString);\n        }\n\n        int opCmp(T)(auto ref const T b)\n            if (is(ValueType : T) || is(typeof(a.opCmp(b))) || is(typeof(b.opCmp(a))))\n        {\n            static if (is(typeof(a.opCmp(b))))\n                return a.opCmp(b);\n            else static if (is(typeof(b.opCmp(a))))\n                return -b.opCmp(b);\n            else\n                return a < b ? -1 : a > b ? +1 : 0;\n        }\n\n        static if (accessibleFrom!(const typeof(this)))\n        {\n            override hash_t toHash() const nothrow @trusted\n            {\n                static if (is(typeof(&a) == ValueType*))\n                    alias v = a;\n                else\n                    auto v = a;     // if a is (property) function\n                return typeid(ValueType).getHash(cast(const void*)&v);\n            }\n        }\n    }\n    else\n    {\n        auto ref opEquals(this X, B)(auto ref B b)\n        {\n            static if (is(immutable B == immutable typeof(this)))\n            {\n                return a == mixin(\"b.\"~__traits(identifier, a));\n            }\n            else\n                return a == b;\n        }\n\n        auto ref opCmp(this X, B)(auto ref B b)\n          if (!is(typeof(a.opCmp(b))) || !is(typeof(b.opCmp(a))))\n        {\n            static if (is(typeof(a.opCmp(b))))\n                return a.opCmp(b);\n            else static if (is(typeof(b.opCmp(a))))\n                return -b.opCmp(a);\n            else static if (isFloatingPoint!ValueType || isFloatingPoint!B)\n                return a < b ? -1 : a > b ? +1 : a == b ? 0 : float.nan;\n            else\n                return a < b ? -1 : (a > b);\n        }\n\n        static if (accessibleFrom!(const typeof(this)))\n        {\n            hash_t toHash() const nothrow @trusted\n            {\n                static if (is(typeof(&a) == ValueType*))\n                    alias v = a;\n                else\n                    auto v = a;     // if a is (property) function\n                return typeid(ValueType).getHash(cast(const void*)&v);\n            }\n        }\n    }\n\n    auto ref opCall(this X, Args...)(auto ref Args args) { return a(args); }\n\n    auto ref opCast(T, this X)() { return cast(T) a; }\n\n    auto ref opIndex(this X, D...)(auto ref D i)               { return a[i]; }\n    auto ref opSlice(this X      )()                           { return a[]; }\n    auto ref opSlice(this X, B, E)(auto ref B b, auto ref E e) { return a[b .. e]; }\n\n    auto ref opUnary     (string op, this X      )()                           { return mixin(op~\"a\"); }\n    auto ref opIndexUnary(string op, this X, D...)(auto ref D i)               { return mixin(op~\"a[i]\"); }\n    auto ref opSliceUnary(string op, this X      )()                           { return mixin(op~\"a[]\"); }\n    auto ref opSliceUnary(string op, this X, B, E)(auto ref B b, auto ref E e) { return mixin(op~\"a[b .. e]\"); }\n\n    auto ref opBinary(string op, this X, B)(auto ref B b)\n    if (op == \"in\" && is(typeof(a in b)) || op != \"in\")\n    {\n        return mixin(\"a \"~op~\" b\");\n    }\n    auto ref opBinaryRight(string op, this X, B)(auto ref B b) { return mixin(\"b \"~op~\" a\"); }\n\n    static if (!is(typeof(this) == class))\n    {\n        import std.traits;\n        static if (isAssignable!ValueType)\n        {\n            auto ref opAssign(this X)(auto ref typeof(this) v)\n            {\n                a = mixin(\"v.\"~__traits(identifier, a));\n                return this;\n            }\n        }\n        else\n        {\n            @disable void opAssign(this X)(auto ref typeof(this) v);\n        }\n    }\n\n    auto ref opAssign     (this X, V      )(auto ref V v) if (!is(V == typeof(this))) { return a       = v; }\n    auto ref opIndexAssign(this X, V, D...)(auto ref V v, auto ref D i)               { return a[i]    = v; }\n    auto ref opSliceAssign(this X, V      )(auto ref V v)                             { return a[]     = v; }\n    auto ref opSliceAssign(this X, V, B, E)(auto ref V v, auto ref B b, auto ref E e) { return a[b .. e] = v; }\n\n    auto ref opOpAssign     (string op, this X, V      )(auto ref V v)\n    {\n        return mixin(\"a \"      ~op~\"= v\");\n    }\n    auto ref opIndexOpAssign(string op, this X, V, D...)(auto ref V v, auto ref D i)\n    {\n        return mixin(\"a[i] \"   ~op~\"= v\");\n    }\n    auto ref opSliceOpAssign(string op, this X, V      )(auto ref V v)\n    {\n        return mixin(\"a[] \"    ~op~\"= v\");\n    }\n    auto ref opSliceOpAssign(string op, this X, V, B, E)(auto ref V v, auto ref B b, auto ref E e)\n    {\n        return mixin(\"a[b .. e] \"~op~\"= v\");\n    }\n\n    template opDispatch(string name)\n    {\n        static if (is(typeof(__traits(getMember, a, name)) == function))\n        {\n            // non template function\n            auto ref opDispatch(this X, Args...)(auto ref Args args) { return mixin(\"a.\"~name~\"(args)\"); }\n        }\n        else static if (is(typeof({ enum x = mixin(\"a.\"~name); })))\n        {\n            // built-in type field, manifest constant, and static non-mutable field\n            enum opDispatch = mixin(\"a.\"~name);\n        }\n        else static if (is(typeof(mixin(\"a.\"~name))) || __traits(getOverloads, a, name).length != 0)\n        {\n            // field or property function\n            @property auto ref opDispatch(this X)()                { return mixin(\"a.\"~name);        }\n            @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin(\"a.\"~name~\" = v\"); }\n        }\n        else\n        {\n            // member template\n            template opDispatch(T...)\n            {\n                enum targs = T.length ? \"!T\" : \"\";\n                auto ref opDispatch(this X, Args...)(auto ref Args args){ return mixin(\"a.\"~name~targs~\"(args)\"); }\n            }\n        }\n    }\n\n    import std.traits : isArray;\n\n    static if (isArray!ValueType)\n    {\n        auto opDollar() const { return a.length; }\n    }\n    else static if (is(typeof(a.opDollar!0)))\n    {\n        auto ref opDollar(size_t pos)() { return a.opDollar!pos(); }\n    }\n    else static if (is(typeof(a.opDollar) == function))\n    {\n        auto ref opDollar() { return a.opDollar(); }\n    }\n    else static if (is(typeof(a.opDollar)))\n    {\n        alias opDollar = a.opDollar;\n    }\n}\n\n///\n@safe unittest\n{\n    struct MyInt\n    {\n        private int value;\n        mixin Proxy!value;\n\n        this(int n){ value = n; }\n    }\n\n    MyInt n = 10;\n\n    // Enable operations that original type has.\n    ++n;\n    assert(n == 11);\n    assert(n * 2 == 22);\n\n    void func(int n) { }\n\n    // Disable implicit conversions to original type.\n    //int x = n;\n    //func(n);\n}\n\n///The proxied value must be an $(B lvalue).\n@safe unittest\n{\n    struct NewIntType\n    {\n        //Won't work; the literal '1'\n        //is an rvalue, not an lvalue\n        //mixin Proxy!1;\n\n        //Okay, n is an lvalue\n        int n;\n        mixin Proxy!n;\n\n        this(int n) { this.n = n; }\n    }\n\n    NewIntType nit = 0;\n    nit++;\n    assert(nit == 1);\n\n\n    struct NewObjectType\n    {\n        Object obj;\n        //Ok, obj is an lvalue\n        mixin Proxy!obj;\n\n        this (Object o) { obj = o; }\n    }\n\n    NewObjectType not = new Object();\n    assert(__traits(compiles, not.toHash()));\n}\n\n/**\n    There is one exception to the fact that the new type is not related to the\n    old type. $(DDSUBLINK spec/function,pseudo-member, Pseudo-member)\n    functions are usable with the new type; they will be forwarded on to the\n    proxied value.\n */\n@safe unittest\n{\n    import std.math;\n\n    float f = 1.0;\n    assert(!f.isInfinity);\n\n    struct NewFloat\n    {\n        float _;\n        mixin Proxy!_;\n\n        this(float f) { _ = f; }\n    }\n\n    NewFloat nf = 1.0f;\n    assert(!nf.isInfinity);\n}\n\n@safe unittest\n{\n    static struct MyInt\n    {\n        private int value;\n        mixin Proxy!value;\n        this(int n) inout { value = n; }\n\n        enum str = \"str\";\n        static immutable arr = [1,2,3];\n    }\n\n    static foreach (T; AliasSeq!(MyInt, const MyInt, immutable MyInt))\n    {{\n        T m = 10;\n        static assert(!__traits(compiles, { int x = m; }));\n        static assert(!__traits(compiles, { void func(int n){} func(m); }));\n        assert(m == 10);\n        assert(m != 20);\n        assert(m < 20);\n        assert(+m == 10);\n        assert(-m == -10);\n        assert(cast(double) m == 10.0);\n        assert(m + 10 == 20);\n        assert(m - 5 == 5);\n        assert(m * 20 == 200);\n        assert(m / 2 == 5);\n        assert(10 + m == 20);\n        assert(15 - m == 5);\n        assert(20 * m == 200);\n        assert(50 / m == 5);\n        static if (is(T == MyInt))  // mutable\n        {\n            assert(++m == 11);\n            assert(m++ == 11); assert(m == 12);\n            assert(--m == 11);\n            assert(m-- == 11); assert(m == 10);\n            m = m;\n            m = 20; assert(m == 20);\n        }\n        static assert(T.max == int.max);\n        static assert(T.min == int.min);\n        static assert(T.init == int.init);\n        static assert(T.str == \"str\");\n        static assert(T.arr == [1,2,3]);\n    }}\n}\n@system unittest\n{\n    static struct MyArray\n    {\n        private int[] value;\n        mixin Proxy!value;\n        this(int[] arr) { value = arr; }\n        this(immutable int[] arr) immutable { value = arr; }\n    }\n\n    static foreach (T; AliasSeq!(MyArray, const MyArray, immutable MyArray))\n    {{\n      static if (is(T == immutable) && !is(typeof({ T a = [1,2,3,4]; })))\n        T a = [1,2,3,4].idup;   // workaround until qualified ctor is properly supported\n      else\n        T a = [1,2,3,4];\n        assert(a == [1,2,3,4]);\n        assert(a != [5,6,7,8]);\n        assert(+a[0]    == 1);\n        version (LittleEndian)\n            assert(cast(ulong[]) a == [0x0000_0002_0000_0001, 0x0000_0004_0000_0003]);\n        else\n            assert(cast(ulong[]) a == [0x0000_0001_0000_0002, 0x0000_0003_0000_0004]);\n        assert(a ~ [10,11] == [1,2,3,4,10,11]);\n        assert(a[0]    == 1);\n        assert(a[]     == [1,2,3,4]);\n        assert(a[2 .. 4] == [3,4]);\n        static if (is(T == MyArray))    // mutable\n        {\n            a = a;\n            a = [5,6,7,8];  assert(a == [5,6,7,8]);\n            a[0]     = 0;   assert(a == [0,6,7,8]);\n            a[]      = 1;   assert(a == [1,1,1,1]);\n            a[0 .. 3]  = 2;   assert(a == [2,2,2,1]);\n            a[0]    += 2;   assert(a == [4,2,2,1]);\n            a[]     *= 2;   assert(a == [8,4,4,2]);\n            a[0 .. 2] /= 2;   assert(a == [4,2,4,2]);\n        }\n    }}\n}\n@system unittest\n{\n    class Foo\n    {\n        int field;\n\n        @property int val1() const { return field; }\n        @property void val1(int n) { field = n; }\n\n        @property ref int val2() { return field; }\n\n        int func(int x, int y) const { return x; }\n        void func1(ref int a) { a = 9; }\n\n        T ifti1(T)(T t) { return t; }\n        void ifti2(Args...)(Args args) { }\n        void ifti3(T, Args...)(Args args) { }\n\n        T opCast(T)(){ return T.init; }\n\n        T tempfunc(T)() { return T.init; }\n    }\n    class Hoge\n    {\n        Foo foo;\n        mixin Proxy!foo;\n        this(Foo f) { foo = f; }\n    }\n\n    auto h = new Hoge(new Foo());\n    int n;\n\n    static assert(!__traits(compiles, { Foo f = h; }));\n\n    // field\n    h.field = 1;            // lhs of assign\n    n = h.field;            // rhs of assign\n    assert(h.field == 1);   // lhs of BinExp\n    assert(1 == h.field);   // rhs of BinExp\n    assert(n == 1);\n\n    // getter/setter property function\n    h.val1 = 4;\n    n = h.val1;\n    assert(h.val1 == 4);\n    assert(4 == h.val1);\n    assert(n == 4);\n\n    // ref getter property function\n    h.val2 = 8;\n    n = h.val2;\n    assert(h.val2 == 8);\n    assert(8 == h.val2);\n    assert(n == 8);\n\n    // member function\n    assert(h.func(2,4) == 2);\n    h.func1(n);\n    assert(n == 9);\n\n    // IFTI\n    assert(h.ifti1(4) == 4);\n    h.ifti2(4);\n    h.ifti3!int(4, 3);\n\n    // bug5896 test\n    assert(h.opCast!int() == 0);\n    assert(cast(int) h == 0);\n    const ih = new const Hoge(new Foo());\n    static assert(!__traits(compiles, ih.opCast!int()));\n    static assert(!__traits(compiles, cast(int) ih));\n\n    // template member function\n    assert(h.tempfunc!int() == 0);\n}\n\n@system unittest // about Proxy inside a class\n{\n    class MyClass\n    {\n        int payload;\n        mixin Proxy!payload;\n        this(int i){ payload = i; }\n        string opCall(string msg){ return msg; }\n        int pow(int i){ return payload ^^ i; }\n    }\n\n    class MyClass2\n    {\n        MyClass payload;\n        mixin Proxy!payload;\n        this(int i){ payload = new MyClass(i); }\n    }\n\n    class MyClass3\n    {\n        int payload;\n        mixin Proxy!payload;\n        this(int i){ payload = i; }\n    }\n\n    // opEquals\n    Object a = new MyClass(5);\n    Object b = new MyClass(5);\n    Object c = new MyClass2(5);\n    Object d = new MyClass3(5);\n    assert(a == b);\n    assert((cast(MyClass) a) == 5);\n    assert(5 == (cast(MyClass) b));\n    assert(5 == cast(MyClass2) c);\n    assert(a != d);\n\n    assert(c != a);\n    // oops! above line is unexpected, isn't it?\n    // the reason is below.\n    // MyClass2.opEquals knows MyClass but,\n    // MyClass.opEquals doesn't know MyClass2.\n    // so, c.opEquals(a) is true, but a.opEquals(c) is false.\n    // furthermore, opEquals(T) couldn't be invoked.\n    assert((cast(MyClass2) c) != (cast(MyClass) a));\n\n    // opCmp\n    Object e = new MyClass2(7);\n    assert(a < cast(MyClass2) e); // OK. and\n    assert(e > a); // OK, but...\n    // assert(a < e); // RUNTIME ERROR!\n    // assert((cast(MyClass) a) < e); // RUNTIME ERROR!\n    assert(3 < cast(MyClass) a);\n    assert((cast(MyClass2) e) < 11);\n\n    // opCall\n    assert((cast(MyClass2) e)(\"hello\") == \"hello\");\n\n    // opCast\n    assert((cast(MyClass)(cast(MyClass2) c)) == a);\n    assert((cast(int)(cast(MyClass2) c)) == 5);\n\n    // opIndex\n    class MyClass4\n    {\n        string payload;\n        mixin Proxy!payload;\n        this(string s){ payload = s; }\n    }\n    class MyClass5\n    {\n        MyClass4 payload;\n        mixin Proxy!payload;\n        this(string s){ payload = new MyClass4(s); }\n    }\n    auto f = new MyClass4(\"hello\");\n    assert(f[1] == 'e');\n    auto g = new MyClass5(\"hello\");\n    assert(f[1] == 'e');\n\n    // opSlice\n    assert(f[2 .. 4] == \"ll\");\n\n    // opUnary\n    assert(-(cast(MyClass2) c) == -5);\n\n    // opBinary\n    assert((cast(MyClass) a) + (cast(MyClass2) c) == 10);\n    assert(5 + cast(MyClass) a == 10);\n\n    // opAssign\n    (cast(MyClass2) c) = 11;\n    assert((cast(MyClass2) c) == 11);\n    (cast(MyClass2) c) = new MyClass(13);\n    assert((cast(MyClass2) c) == 13);\n\n    // opOpAssign\n    assert((cast(MyClass2) c) += 4);\n    assert((cast(MyClass2) c) == 17);\n\n    // opDispatch\n    assert((cast(MyClass2) c).pow(2) == 289);\n\n    // opDollar\n    assert(f[2..$-1] == \"ll\");\n\n    // toHash\n    int[Object] hash;\n    hash[a] = 19;\n    hash[c] = 21;\n    assert(hash[b] == 19);\n    assert(hash[c] == 21);\n}\n\n@safe unittest\n{\n    struct MyInt\n    {\n        int payload;\n\n        mixin Proxy!payload;\n    }\n\n    MyInt v;\n    v = v;\n\n    struct Foo\n    {\n        @disable void opAssign(typeof(this));\n    }\n    struct MyFoo\n    {\n        Foo payload;\n\n        mixin Proxy!payload;\n    }\n    MyFoo f;\n    static assert(!__traits(compiles, f = f));\n\n    struct MyFoo2\n    {\n        Foo payload;\n\n        mixin Proxy!payload;\n\n        // override default Proxy behavior\n        void opAssign(typeof(this) rhs){}\n    }\n    MyFoo2 f2;\n    f2 = f2;\n}\n@safe unittest\n{\n    // bug8613\n    static struct Name\n    {\n        mixin Proxy!val;\n        private string val;\n        this(string s) { val = s; }\n    }\n\n    bool[Name] names;\n    names[Name(\"a\")] = true;\n    bool* b = Name(\"a\") in names;\n}\n\n// excludes struct S; it's 'mixin Proxy!foo' doesn't compile with -dip1000\nversion (DIP1000) {} else\n@system unittest\n{\n    // bug14213, using function for the payload\n    static struct S\n    {\n        int foo() { return 12; }\n        mixin Proxy!foo;\n    }\n    S s;\n    assert(s + 1 == 13);\n    assert(s * 2 == 24);\n}\n\n@system unittest\n{\n    static class C\n    {\n        int foo() { return 12; }\n        mixin Proxy!foo;\n    }\n    C c = new C();\n}\n\n// Check all floating point comparisons for both Proxy and Typedef,\n// also against int and a Typedef!int, to be as regression-proof\n// as possible. bug 15561\n@safe unittest\n{\n    static struct MyFloatImpl\n    {\n        float value;\n        mixin Proxy!value;\n    }\n    static void allFail(T0, T1)(T0 a, T1 b)\n    {\n        assert(!(a == b));\n        assert(!(a<b));\n        assert(!(a <= b));\n        assert(!(a>b));\n        assert(!(a >= b));\n    }\n    static foreach (T1; AliasSeq!(MyFloatImpl, Typedef!float, Typedef!double,\n        float, real, Typedef!int, int))\n    {\n        static foreach (T2; AliasSeq!(MyFloatImpl, Typedef!float))\n        {{\n            T1 a;\n            T2 b;\n\n            static if (isFloatingPoint!T1 || isFloatingPoint!(TypedefType!T1))\n                allFail(a, b);\n            a = 3;\n            allFail(a, b);\n\n            b = 4;\n            assert(a != b);\n            assert(a<b);\n            assert(a <= b);\n            assert(!(a>b));\n            assert(!(a >= b));\n\n            a = 4;\n            assert(a == b);\n            assert(!(a<b));\n            assert(a <= b);\n            assert(!(a>b));\n            assert(a >= b);\n        }}\n    }\n}\n\n/**\n$(B Typedef) allows the creation of a unique type which is\nbased on an existing type. Unlike the `alias` feature,\n$(B Typedef) ensures the two types are not considered as equals.\n\nParams:\n\n    init = Optional initial value for the new type.\n    cookie = Optional, used to create multiple unique types which are\n             based on the same origin type `T`\n\nNote: If a library routine cannot handle the Typedef type,\nyou can use the `TypedefType` template to extract the\ntype which the Typedef wraps.\n */\nstruct Typedef(T, T init = T.init, string cookie=null)\n{\n    private T Typedef_payload = init;\n\n    // issue 18415 : prevent default construction if original type does too.\n    static if ((is(T == struct) || is(T == union)) && !is(typeof({T t;})))\n    {\n        @disable this();\n    }\n\n    this(T init)\n    {\n        Typedef_payload = init;\n    }\n\n    this(Typedef tdef)\n    {\n        this(tdef.Typedef_payload);\n    }\n\n    // We need to add special overload for cast(Typedef!X) exp,\n    // thus we can't simply inherit Proxy!Typedef_payload\n    T2 opCast(T2 : Typedef!(T, Unused), this X, T, Unused...)()\n    {\n        return T2(cast(T) Typedef_payload);\n    }\n\n    auto ref opCast(T2, this X)()\n    {\n        return cast(T2) Typedef_payload;\n    }\n\n    mixin Proxy!Typedef_payload;\n\n    pure nothrow @nogc @safe @property\n    {\n        alias TD = typeof(this);\n        static if (isIntegral!T)\n        {\n            static TD min() {return TD(T.min);}\n            static TD max() {return TD(T.max);}\n        }\n        else static if (isFloatingPoint!T)\n        {\n            static TD infinity() {return TD(T.infinity);}\n            static TD nan() {return TD(T.nan);}\n            static TD dig() {return TD(T.dig);}\n            static TD epsilon() {return TD(T.epsilon);}\n            static TD mant_dig() {return TD(T.mant_dig);}\n            static TD max_10_exp() {return TD(T.max_10_exp);}\n            static TD max_exp()  {return TD(T.max_exp);}\n            static TD min_10_exp() {return TD(T.min_10_exp);}\n            static TD min_exp() {return TD(T.min_exp);}\n            static TD max() {return TD(T.max);}\n            static TD min_normal() {return TD(T.min_normal);}\n            TD re() {return TD(Typedef_payload.re);}\n            TD im() {return TD(Typedef_payload.im);}\n        }\n    }\n\n    /**\n     * Convert wrapped value to a human readable string\n     */\n    string toString(this T)()\n    {\n        import std.array : appender;\n        auto app = appender!string();\n        auto spec = singleSpec(\"%s\");\n        toString(app, spec);\n        return app.data;\n    }\n\n    /// ditto\n    void toString(this T, W)(ref W writer, const ref FormatSpec!char fmt)\n    if (isOutputRange!(W, char))\n    {\n        formatValue(writer, Typedef_payload, fmt);\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.conv : to;\n\n        int i = 123;\n        auto td = Typedef!int(i);\n        assert(i.to!string == td.to!string);\n    }\n}\n\n///\n@safe unittest\n{\n    alias MyInt = Typedef!int;\n    MyInt foo = 10;\n    foo++;\n    assert(foo == 11);\n}\n\n/// custom initialization values\n@safe unittest\n{\n    alias MyIntInit = Typedef!(int, 42);\n    static assert(is(TypedefType!MyIntInit == int));\n    static assert(MyIntInit() == 42);\n}\n\n/// Typedef creates a new type\n@safe unittest\n{\n    alias MyInt = Typedef!int;\n    static void takeInt(int) {}\n    static void takeMyInt(MyInt) {}\n\n    int i;\n    takeInt(i);    // ok\n    static assert(!__traits(compiles, takeMyInt(i)));\n\n    MyInt myInt;\n    static assert(!__traits(compiles, takeInt(myInt)));\n    takeMyInt(myInt);  // ok\n}\n\n/// Use the optional `cookie` argument to create different types of the same base type\n@safe unittest\n{\n    alias TypeInt1 = Typedef!int;\n    alias TypeInt2 = Typedef!int;\n\n    // The two Typedefs are the same type.\n    static assert(is(TypeInt1 == TypeInt2));\n\n    alias MoneyEuros = Typedef!(float, float.init, \"euros\");\n    alias MoneyDollars = Typedef!(float, float.init, \"dollars\");\n\n    // The two Typedefs are _not_ the same type.\n    static assert(!is(MoneyEuros == MoneyDollars));\n}\n\n/**\nGet the underlying type which a `Typedef` wraps.\nIf `T` is not a `Typedef` it will alias itself to `T`.\n*/\ntemplate TypedefType(T)\n{\n    static if (is(T : Typedef!Arg, Arg))\n        alias TypedefType = Arg;\n    else\n        alias TypedefType = T;\n}\n\n///\n@safe unittest\n{\n    import std.conv : to;\n\n    alias MyInt = Typedef!int;\n    static assert(is(TypedefType!MyInt == int));\n\n    /// Instantiating with a non-Typedef will return that type\n    static assert(is(TypedefType!int == int));\n\n    string num = \"5\";\n\n    // extract the needed type\n    MyInt myInt = MyInt( num.to!(TypedefType!MyInt) );\n    assert(myInt == 5);\n\n    // cast to the underlying type to get the value that's being wrapped\n    int x = cast(TypedefType!MyInt) myInt;\n\n    alias MyIntInit = Typedef!(int, 42);\n    static assert(is(TypedefType!MyIntInit == int));\n    static assert(MyIntInit() == 42);\n}\n\n@safe unittest\n{\n    Typedef!int x = 10;\n    static assert(!__traits(compiles, { int y = x; }));\n    static assert(!__traits(compiles, { long z = x; }));\n\n    Typedef!int y = 10;\n    assert(x == y);\n\n    static assert(Typedef!int.init == int.init);\n\n    Typedef!(float, 1.0) z; // specifies the init\n    assert(z == 1.0);\n\n    static assert(typeof(z).init == 1.0);\n\n    alias Dollar = Typedef!(int, 0, \"dollar\");\n    alias Yen    = Typedef!(int, 0, \"yen\");\n    static assert(!is(Dollar == Yen));\n\n    Typedef!(int[3]) sa;\n    static assert(sa.length == 3);\n    static assert(typeof(sa).length == 3);\n\n    Typedef!(int[3]) dollar1;\n    assert(dollar1[0..$] is dollar1[0 .. 3]);\n\n    Typedef!(int[]) dollar2;\n    dollar2.length = 3;\n    assert(dollar2[0..$] is dollar2[0 .. 3]);\n\n    static struct Dollar1\n    {\n        static struct DollarToken {}\n        enum opDollar = DollarToken.init;\n        auto opSlice(size_t, DollarToken) { return 1; }\n        auto opSlice(size_t, size_t) { return 2; }\n    }\n\n    Typedef!Dollar1 drange1;\n    assert(drange1[0..$] == 1);\n    assert(drange1[0 .. 1] == 2);\n\n    static struct Dollar2\n    {\n        size_t opDollar(size_t pos)() { return pos == 0 ? 1 : 100; }\n        size_t opIndex(size_t i, size_t j) { return i + j; }\n    }\n\n    Typedef!Dollar2 drange2;\n    assert(drange2[$, $] == 101);\n\n    static struct Dollar3\n    {\n        size_t opDollar() { return 123; }\n        size_t opIndex(size_t i) { return i; }\n    }\n\n    Typedef!Dollar3 drange3;\n    assert(drange3[$] == 123);\n}\n\n@safe @nogc pure nothrow unittest // Bugzilla 18415\n{\n    struct NoDefCtorS{@disable this();}\n    union NoDefCtorU{@disable this();}\n    static assert(!is(typeof({Typedef!NoDefCtorS s;})));\n    static assert(!is(typeof({Typedef!NoDefCtorU u;})));\n}\n\n@safe @nogc pure nothrow unittest // Bugzilla 11703\n{\n    alias I = Typedef!int;\n    static assert(is(typeof(I.min) == I));\n    static assert(is(typeof(I.max) == I));\n\n    alias F = Typedef!double;\n    static assert(is(typeof(F.infinity) == F));\n    static assert(is(typeof(F.epsilon) == F));\n\n    F f;\n    assert(!is(typeof(F.re).stringof == double));\n    assert(!is(typeof(F.im).stringof == double));\n}\n\n@safe unittest\n{\n    // bug8655\n    import std.typecons;\n    import std.bitmanip;\n    static import core.stdc.config;\n\n    alias c_ulong = Typedef!(core.stdc.config.c_ulong);\n\n    static struct Foo\n    {\n        mixin(bitfields!(\n            c_ulong, \"NameOffset\", 31,\n            c_ulong, \"NameIsString\", 1\n        ));\n    }\n}\n\n@safe unittest // Issue 12596\n{\n    import std.typecons;\n    alias TD = Typedef!int;\n    TD x = TD(1);\n    TD y = TD(x);\n    assert(x == y);\n}\n\n@safe unittest // about toHash\n{\n    import std.typecons;\n    {\n        alias TD = Typedef!int;\n        int[TD] td;\n        td[TD(1)] = 1;\n        assert(td[TD(1)] == 1);\n    }\n\n    {\n        alias TD = Typedef!(int[]);\n        int[TD] td;\n        td[TD([1,2,3,4])] = 2;\n        assert(td[TD([1,2,3,4])] == 2);\n    }\n\n    {\n        alias TD = Typedef!(int[][]);\n        int[TD] td;\n        td[TD([[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]])] = 3;\n        assert(td[TD([[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]])] == 3);\n    }\n\n    {\n        struct MyStruct{ int x; }\n        alias TD = Typedef!MyStruct;\n        int[TD] td;\n        td[TD(MyStruct(10))] = 4;\n        assert(TD(MyStruct(20)) !in td);\n        assert(td[TD(MyStruct(10))] == 4);\n    }\n\n    {\n        static struct MyStruct2\n        {\n            int x;\n            size_t toHash() const nothrow @safe { return x; }\n            bool opEquals(ref const MyStruct2 r) const { return r.x == x; }\n        }\n\n        alias TD = Typedef!MyStruct2;\n        int[TD] td;\n        td[TD(MyStruct2(50))] = 5;\n        assert(td[TD(MyStruct2(50))] == 5);\n    }\n\n    {\n        class MyClass{}\n        alias TD = Typedef!MyClass;\n        int[TD] td;\n        auto c = new MyClass;\n        td[TD(c)] = 6;\n        assert(TD(new MyClass) !in td);\n        assert(td[TD(c)] == 6);\n    }\n}\n\n@system unittest\n{\n    alias String = Typedef!(char[]);\n    alias CString = Typedef!(const(char)[]);\n    CString cs = \"fubar\";\n    String s = cast(String) cs;\n    assert(cs == s);\n    char[] s2 = cast(char[]) cs;\n    const(char)[] cs2 = cast(const(char)[])s;\n    assert(s2 == cs2);\n}\n\n@system unittest // toString\n{\n    import std.meta : AliasSeq;\n    import std.conv : to;\n\n    struct TestS {}\n    class TestC {}\n\n    static foreach (T; AliasSeq!(int, bool, float, double, real,\n                                 char, dchar, wchar,\n                                 TestS, TestC,\n                                 int*, int[], int[2], int[int]))\n    {{\n        T t;\n\n        Typedef!T td;\n        Typedef!(const T) ctd;\n        Typedef!(immutable T) itd;\n\n        assert(t.to!string() == td.to!string());\n\n        static if (!(is(T == TestS) || is(T == TestC)))\n        {\n            assert(t.to!string() == ctd.to!string());\n            assert(t.to!string() == itd.to!string());\n        }\n    }}\n}\n\n/**\nAllocates a `class` object right inside the current scope,\ntherefore avoiding the overhead of `new`. This facility is unsafe;\nit is the responsibility of the user to not escape a reference to the\nobject outside the scope.\n\nThe class destructor will be called when the result of `scoped()` is\nitself destroyed.\n\nScoped class instances can be embedded in a parent `class` or `struct`,\njust like a child struct instance. Scoped member variables must have\ntype `typeof(scoped!Class(args))`, and be initialized with a call to\nscoped. See below for an example.\n\nNote:\nIt's illegal to move a class instance even if you are sure there\nare no pointers to it. As such, it is illegal to move a scoped object.\n */\ntemplate scoped(T)\nif (is(T == class))\n{\n    // _d_newclass now use default GC alignment (looks like (void*).sizeof * 2 for\n    // small objects). We will just use the maximum of filed alignments.\n    alias alignment = classInstanceAlignment!T;\n    alias aligned = _alignUp!alignment;\n\n    static struct Scoped\n    {\n        // Addition of `alignment` is required as `Scoped_store` can be misaligned in memory.\n        private void[aligned(__traits(classInstanceSize, T) + size_t.sizeof) + alignment] Scoped_store = void;\n\n        @property inout(T) Scoped_payload() inout\n        {\n            void* alignedStore = cast(void*) aligned(cast(size_t) Scoped_store.ptr);\n            // As `Scoped` can be unaligned moved in memory class instance should be moved accordingly.\n            immutable size_t d = alignedStore - Scoped_store.ptr;\n            size_t* currD = cast(size_t*) &Scoped_store[$ - size_t.sizeof];\n            if (d != *currD)\n            {\n                import core.stdc.string : memmove;\n                memmove(alignedStore, Scoped_store.ptr + *currD, __traits(classInstanceSize, T));\n                *currD = d;\n            }\n            return cast(inout(T)) alignedStore;\n        }\n        alias Scoped_payload this;\n\n        @disable this();\n        @disable this(this);\n\n        ~this()\n        {\n            // `destroy` will also write .init but we have no functions in druntime\n            // for deterministic finalization and memory releasing for now.\n            .destroy(Scoped_payload);\n        }\n    }\n\n    /** Returns the _scoped object.\n    Params: args = Arguments to pass to `T`'s constructor.\n    */\n    @system auto scoped(Args...)(auto ref Args args)\n    {\n        import std.conv : emplace;\n\n        Scoped result = void;\n        void* alignedStore = cast(void*) aligned(cast(size_t) result.Scoped_store.ptr);\n        immutable size_t d = alignedStore - result.Scoped_store.ptr;\n        *cast(size_t*) &result.Scoped_store[$ - size_t.sizeof] = d;\n        emplace!(Unqual!T)(result.Scoped_store[d .. $ - size_t.sizeof], args);\n        return result;\n    }\n}\n\n///\n@system unittest\n{\n    class A\n    {\n        int x;\n        this()     {x = 0;}\n        this(int i){x = i;}\n        ~this()    {}\n    }\n\n    // Standard usage, constructing A on the stack\n    auto a1 = scoped!A();\n    a1.x = 42;\n\n    // Result of `scoped` call implicitly converts to a class reference\n    A aRef = a1;\n    assert(aRef.x == 42);\n\n    // Scoped destruction\n    {\n        auto a2 = scoped!A(1);\n        assert(a2.x == 1);\n        aRef = a2;\n        // a2 is destroyed here, calling A's destructor\n    }\n    // aRef is now an invalid reference\n\n    // Here the temporary scoped A is immediately destroyed.\n    // This means the reference is then invalid.\n    version (Bug)\n    {\n        // Wrong, should use `auto`\n        A invalid = scoped!A();\n    }\n\n    // Restrictions\n    version (Bug)\n    {\n        import std.algorithm.mutation : move;\n        auto invalid = a1.move; // illegal, scoped objects can't be moved\n    }\n    static assert(!is(typeof({\n        auto e1 = a1; // illegal, scoped objects can't be copied\n        assert([a1][0].x == 42); // ditto\n    })));\n    static assert(!is(typeof({\n        alias ScopedObject = typeof(a1);\n        auto e2 = ScopedObject();  // illegal, must be built via scoped!A\n        auto e3 = ScopedObject(1); // ditto\n    })));\n\n    // Use with alias\n    alias makeScopedA = scoped!A;\n    auto a3 = makeScopedA();\n    auto a4 = makeScopedA(1);\n\n    // Use as member variable\n    struct B\n    {\n        typeof(scoped!A()) a; // note the trailing parentheses\n\n        this(int i)\n        {\n            // construct member\n            a = scoped!A(i);\n        }\n    }\n\n    // Stack-allocate\n    auto b1 = B(5);\n    aRef = b1.a;\n    assert(aRef.x == 5);\n    destroy(b1); // calls A's destructor for b1.a\n    // aRef is now an invalid reference\n\n    // Heap-allocate\n    auto b2 = new B(6);\n    assert(b2.a.x == 6);\n    destroy(*b2); // calls A's destructor for b2.a\n}\n\nprivate size_t _alignUp(size_t alignment)(size_t n)\nif (alignment > 0 && !((alignment - 1) & alignment))\n{\n    enum badEnd = alignment - 1; // 0b11, 0b111, ...\n    return (n + badEnd) & ~badEnd;\n}\n\n@system unittest // Issue 6580 testcase\n{\n    enum alignment = (void*).alignof;\n\n    static class C0 { }\n    static class C1 { byte b; }\n    static class C2 { byte[2] b; }\n    static class C3 { byte[3] b; }\n    static class C7 { byte[7] b; }\n    static assert(scoped!C0().sizeof % alignment == 0);\n    static assert(scoped!C1().sizeof % alignment == 0);\n    static assert(scoped!C2().sizeof % alignment == 0);\n    static assert(scoped!C3().sizeof % alignment == 0);\n    static assert(scoped!C7().sizeof % alignment == 0);\n\n    enum longAlignment = long.alignof;\n    static class C1long\n    {\n        long long_; byte byte_ = 4;\n        this() { }\n        this(long _long, ref int i) { long_ = _long; ++i; }\n    }\n    static class C2long { byte[2] byte_ = [5, 6]; long long_ = 7; }\n    static assert(scoped!C1long().sizeof % longAlignment == 0);\n    static assert(scoped!C2long().sizeof % longAlignment == 0);\n\n    void alignmentTest()\n    {\n        int var = 5;\n        auto c1long = scoped!C1long(3, var);\n        assert(var == 6);\n        auto c2long = scoped!C2long();\n        assert(cast(uint)&c1long.long_ % longAlignment == 0);\n        assert(cast(uint)&c2long.long_ % longAlignment == 0);\n        assert(c1long.long_ == 3 && c1long.byte_ == 4);\n        assert(c2long.byte_ == [5, 6] && c2long.long_ == 7);\n    }\n\n    alignmentTest();\n\n    version (DigitalMars)\n    {\n        void test(size_t size)\n        {\n            import core.stdc.stdlib;\n            alloca(size);\n            alignmentTest();\n        }\n        foreach (i; 0 .. 10)\n            test(i);\n    }\n    else\n    {\n        void test(size_t size)()\n        {\n            byte[size] arr;\n            alignmentTest();\n        }\n        static foreach (i; 0 .. 11)\n            test!i();\n    }\n}\n\n@system unittest // Original Issue 6580 testcase\n{\n    class C { int i; byte b; }\n\n    auto sa = [scoped!C(), scoped!C()];\n    assert(cast(uint)&sa[0].i % int.alignof == 0);\n    assert(cast(uint)&sa[1].i % int.alignof == 0); // fails\n}\n\n@system unittest\n{\n    class A { int x = 1; }\n    auto a1 = scoped!A();\n    assert(a1.x == 1);\n    auto a2 = scoped!A();\n    a1.x = 42;\n    a2.x = 53;\n    assert(a1.x == 42);\n}\n\n@system unittest\n{\n    class A { int x = 1; this() { x = 2; } }\n    auto a1 = scoped!A();\n    assert(a1.x == 2);\n    auto a2 = scoped!A();\n    a1.x = 42;\n    a2.x = 53;\n    assert(a1.x == 42);\n}\n\n@system unittest\n{\n    class A { int x = 1; this(int y) { x = y; } ~this() {} }\n    auto a1 = scoped!A(5);\n    assert(a1.x == 5);\n    auto a2 = scoped!A(42);\n    a1.x = 42;\n    a2.x = 53;\n    assert(a1.x == 42);\n}\n\n@system unittest\n{\n    class A { static bool dead; ~this() { dead = true; } }\n    class B : A { static bool dead; ~this() { dead = true; } }\n    {\n        auto b = scoped!B();\n    }\n    assert(B.dead, \"asdasd\");\n    assert(A.dead, \"asdasd\");\n}\n\n@system unittest // Issue 8039 testcase\n{\n    static int dels;\n    static struct S { ~this(){ ++dels; } }\n\n    static class A { S s; }\n    dels = 0; { scoped!A(); }\n    assert(dels == 1);\n\n    static class B { S[2] s; }\n    dels = 0; { scoped!B(); }\n    assert(dels == 2);\n\n    static struct S2 { S[3] s; }\n    static class C { S2[2] s; }\n    dels = 0; { scoped!C(); }\n    assert(dels == 6);\n\n    static class D: A { S2[2] s; }\n    dels = 0; { scoped!D(); }\n    assert(dels == 1+6);\n}\n\n@system unittest\n{\n    // bug4500\n    class A\n    {\n        this() { a = this; }\n        this(int i) { a = this; }\n        A a;\n        bool check() { return this is a; }\n    }\n\n    auto a1 = scoped!A();\n    assert(a1.check());\n\n    auto a2 = scoped!A(1);\n    assert(a2.check());\n\n    a1.a = a1;\n    assert(a1.check());\n}\n\n@system unittest\n{\n    static class A\n    {\n        static int sdtor;\n\n        this() { ++sdtor; assert(sdtor == 1); }\n        ~this() { assert(sdtor == 1); --sdtor; }\n    }\n\n    interface Bob {}\n\n    static class ABob : A, Bob\n    {\n        this() { ++sdtor; assert(sdtor == 2); }\n        ~this() { assert(sdtor == 2); --sdtor; }\n    }\n\n    A.sdtor = 0;\n    scope(exit) assert(A.sdtor == 0);\n    auto abob = scoped!ABob();\n}\n\n@safe unittest\n{\n    static class A { this(int) {} }\n    static assert(!__traits(compiles, scoped!A()));\n}\n\n@system unittest\n{\n    static class A { @property inout(int) foo() inout { return 1; } }\n\n    auto a1 = scoped!A();\n    assert(a1.foo == 1);\n    static assert(is(typeof(a1.foo) == int));\n\n    auto a2 = scoped!(const(A))();\n    assert(a2.foo == 1);\n    static assert(is(typeof(a2.foo) == const(int)));\n\n    auto a3 = scoped!(immutable(A))();\n    assert(a3.foo == 1);\n    static assert(is(typeof(a3.foo) == immutable(int)));\n\n    const c1 = scoped!A();\n    assert(c1.foo == 1);\n    static assert(is(typeof(c1.foo) == const(int)));\n\n    const c2 = scoped!(const(A))();\n    assert(c2.foo == 1);\n    static assert(is(typeof(c2.foo) == const(int)));\n\n    const c3 = scoped!(immutable(A))();\n    assert(c3.foo == 1);\n    static assert(is(typeof(c3.foo) == immutable(int)));\n}\n\n@system unittest\n{\n    class C { this(ref int val) { assert(val == 3); ++val; } }\n\n    int val = 3;\n    auto s = scoped!C(val);\n    assert(val == 4);\n}\n\n@system unittest\n{\n    class C\n    {\n        this(){}\n        this(int){}\n        this(int, int){}\n    }\n    alias makeScopedC = scoped!C;\n\n    auto a = makeScopedC();\n    auto b = makeScopedC(1);\n    auto c = makeScopedC(1, 1);\n\n    static assert(is(typeof(a) == typeof(b)));\n    static assert(is(typeof(b) == typeof(c)));\n}\n\n/**\nDefines a simple, self-documenting yes/no flag. This makes it easy for\nAPIs to define functions accepting flags without resorting to $(D\nbool), which is opaque in calls, and without needing to define an\nenumerated type separately. Using `Flag!\"Name\"` instead of $(D\nbool) makes the flag's meaning visible in calls. Each yes/no flag has\nits own type, which makes confusions and mix-ups impossible.\n\nExample:\n\nCode calling `getLine` (usually far away from its definition) can't be\nunderstood without looking at the documentation, even by users familiar with\nthe API:\n----\nstring getLine(bool keepTerminator)\n{\n    ...\n    if (keepTerminator) ...\n    ...\n}\n...\nauto line = getLine(false);\n----\n\nAssuming the reverse meaning (i.e. \"ignoreTerminator\") and inserting the wrong\ncode compiles and runs with erroneous results.\n\nAfter replacing the boolean parameter with an instantiation of `Flag`, code\ncalling `getLine` can be easily read and understood even by people not\nfluent with the API:\n\n----\nstring getLine(Flag!\"keepTerminator\" keepTerminator)\n{\n    ...\n    if (keepTerminator) ...\n    ...\n}\n...\nauto line = getLine(Yes.keepTerminator);\n----\n\nThe structs `Yes` and `No` are provided as shorthand for\n`Flag!\"Name\".yes` and `Flag!\"Name\".no` and are preferred for brevity and\nreadability. These convenience structs mean it is usually unnecessary and\ncounterproductive to create an alias of a `Flag` as a way of avoiding typing\nout the full type while specifying the affirmative or negative options.\n\nPassing categorical data by means of unstructured `bool`\nparameters is classified under \"simple-data coupling\" by Steve\nMcConnell in the $(LUCKY Code Complete) book, along with three other\nkinds of coupling. The author argues citing several studies that\ncoupling has a negative effect on code quality. `Flag` offers a\nsimple structuring method for passing yes/no flags to APIs.\n */\ntemplate Flag(string name) {\n    ///\n    enum Flag : bool\n    {\n        /**\n         When creating a value of type `Flag!\"Name\"`, use $(D\n         Flag!\"Name\".no) for the negative option. When using a value\n         of type `Flag!\"Name\"`, compare it against $(D\n         Flag!\"Name\".no) or just `false` or `0`.  */\n        no = false,\n\n        /** When creating a value of type `Flag!\"Name\"`, use $(D\n         Flag!\"Name\".yes) for the affirmative option. When using a\n         value of type `Flag!\"Name\"`, compare it against $(D\n         Flag!\"Name\".yes).\n        */\n        yes = true\n    }\n}\n\n///\n@safe unittest\n{\n    Flag!\"abc\" flag;\n\n    assert(flag == Flag!\"abc\".no);\n    assert(flag == No.abc);\n    assert(!flag);\n    if (flag) assert(0);\n}\n\n///\n@safe unittest\n{\n    auto flag = Yes.abc;\n\n    assert(flag);\n    assert(flag == Yes.abc);\n    if (!flag) assert(0);\n    if (flag) {} else assert(0);\n}\n\n/**\nConvenience names that allow using e.g. `Yes.encryption` instead of\n`Flag!\"encryption\".yes` and `No.encryption` instead of $(D\nFlag!\"encryption\".no).\n*/\nstruct Yes\n{\n    template opDispatch(string name)\n    {\n        enum opDispatch = Flag!name.yes;\n    }\n}\n//template yes(string name) { enum Flag!name yes = Flag!name.yes; }\n\n/// Ditto\nstruct No\n{\n    template opDispatch(string name)\n    {\n        enum opDispatch = Flag!name.no;\n    }\n}\n\n///\n@safe unittest\n{\n    Flag!\"abc\" flag;\n\n    assert(flag == Flag!\"abc\".no);\n    assert(flag == No.abc);\n    assert(!flag);\n    if (flag) assert(0);\n}\n\n///\n@safe unittest\n{\n    auto flag = Yes.abc;\n\n    assert(flag);\n    assert(flag == Yes.abc);\n    if (!flag) assert(0);\n    if (flag) {} else assert(0);\n}\n\n/**\nDetect whether an enum is of integral type and has only \"flag\" values\n(i.e. values with a bit count of exactly 1).\nAdditionally, a zero value is allowed for compatibility with enums including\na \"None\" value.\n*/\ntemplate isBitFlagEnum(E)\n{\n    static if (is(E Base == enum) && isIntegral!Base)\n    {\n        enum isBitFlagEnum = (E.min >= 0) &&\n        {\n            static foreach (immutable flag; EnumMembers!E)\n            {{\n                Base value = flag;\n                value &= value - 1;\n                if (value != 0) return false;\n            }}\n            return true;\n        }();\n    }\n    else\n    {\n        enum isBitFlagEnum = false;\n    }\n}\n\n///\n@safe pure nothrow unittest\n{\n    enum A\n    {\n        None,\n        A = 1 << 0,\n        B = 1 << 1,\n        C = 1 << 2,\n        D = 1 << 3,\n    }\n\n    static assert(isBitFlagEnum!A);\n}\n\n/// Test an enum with default (consecutive) values\n@safe pure nothrow unittest\n{\n    enum B\n    {\n        A,\n        B,\n        C,\n        D // D == 3\n    }\n\n    static assert(!isBitFlagEnum!B);\n}\n\n/// Test an enum with non-integral values\n@safe pure nothrow unittest\n{\n    enum C: double\n    {\n        A = 1 << 0,\n        B = 1 << 1\n    }\n\n    static assert(!isBitFlagEnum!C);\n}\n\n/**\nA typesafe structure for storing combinations of enum values.\n\nThis template defines a simple struct to represent bitwise OR combinations of\nenum values. It can be used if all the enum values are integral constants with\na bit count of at most 1, or if the `unsafe` parameter is explicitly set to\nYes.\nThis is much safer than using the enum itself to store\nthe OR combination, which can produce surprising effects like this:\n----\nenum E\n{\n    A = 1 << 0,\n    B = 1 << 1\n}\nE e = E.A | E.B;\n// will throw SwitchError\nfinal switch (e)\n{\n    case E.A:\n        return;\n    case E.B:\n        return;\n}\n----\n*/\nstruct BitFlags(E, Flag!\"unsafe\" unsafe = No.unsafe)\nif (unsafe || isBitFlagEnum!(E))\n{\n@safe @nogc pure nothrow:\nprivate:\n    enum isBaseEnumType(T) = is(E == T);\n    alias Base = OriginalType!E;\n    Base mValue;\n    static struct Negation\n    {\n    @safe @nogc pure nothrow:\n    private:\n        Base mValue;\n\n        // Prevent non-copy construction outside the module.\n        @disable this();\n        this(Base value)\n        {\n            mValue = value;\n        }\n    }\n\npublic:\n    this(E flag)\n    {\n        this = flag;\n    }\n\n    this(T...)(T flags)\n        if (allSatisfy!(isBaseEnumType, T))\n    {\n        this = flags;\n    }\n\n    bool opCast(B: bool)() const\n    {\n        return mValue != 0;\n    }\n\n    Base opCast(B)() const\n        if (isImplicitlyConvertible!(Base, B))\n    {\n        return mValue;\n    }\n\n    Negation opUnary(string op)() const\n        if (op == \"~\")\n    {\n        return Negation(~mValue);\n    }\n\n    auto ref opAssign(T...)(T flags)\n        if (allSatisfy!(isBaseEnumType, T))\n    {\n        mValue = 0;\n        foreach (E flag; flags)\n        {\n            mValue |= flag;\n        }\n        return this;\n    }\n\n    auto ref opAssign(E flag)\n    {\n        mValue = flag;\n        return this;\n    }\n\n    auto ref opOpAssign(string op: \"|\")(BitFlags flags)\n    {\n        mValue |= flags.mValue;\n        return this;\n    }\n\n    auto ref opOpAssign(string op: \"&\")(BitFlags  flags)\n    {\n        mValue &= flags.mValue;\n        return this;\n    }\n\n    auto ref opOpAssign(string op: \"|\")(E flag)\n    {\n        mValue |= flag;\n        return this;\n    }\n\n    auto ref opOpAssign(string op: \"&\")(E flag)\n    {\n        mValue &= flag;\n        return this;\n    }\n\n    auto ref opOpAssign(string op: \"&\")(Negation negatedFlags)\n    {\n        mValue &= negatedFlags.mValue;\n        return this;\n    }\n\n    auto opBinary(string op)(BitFlags flags) const\n        if (op == \"|\" || op == \"&\")\n    {\n        BitFlags result = this;\n        result.opOpAssign!op(flags);\n        return result;\n    }\n\n    auto opBinary(string op)(E flag) const\n        if (op == \"|\" || op == \"&\")\n    {\n        BitFlags result = this;\n        result.opOpAssign!op(flag);\n        return result;\n    }\n\n    auto opBinary(string op: \"&\")(Negation negatedFlags) const\n    {\n        BitFlags result = this;\n        result.opOpAssign!op(negatedFlags);\n        return result;\n    }\n\n    auto opBinaryRight(string op)(E flag) const\n        if (op == \"|\" || op == \"&\")\n    {\n        return opBinary!op(flag);\n    }\n\n    bool opDispatch(string name)() const\n    if (__traits(hasMember, E, name))\n    {\n        enum e = __traits(getMember, E, name);\n        return (mValue & e) == e;\n    }\n\n    void opDispatch(string name)(bool set)\n    if (__traits(hasMember, E, name))\n    {\n        enum e = __traits(getMember, E, name);\n        if (set)\n            mValue |= e;\n        else\n            mValue &= ~e;\n    }\n}\n\n/// Set values with the | operator and test with &\n@safe @nogc pure nothrow unittest\n{\n    enum Enum\n    {\n        A = 1 << 0,\n    }\n\n    // A default constructed BitFlags has no value set\n    immutable BitFlags!Enum flags_empty;\n    assert(!flags_empty.A);\n\n    // Value can be set with the | operator\n    immutable flags_A = flags_empty | Enum.A;\n\n    // and tested using property access\n    assert(flags_A.A);\n\n    // or the & operator\n    assert(flags_A & Enum.A);\n    // which commutes.\n    assert(Enum.A & flags_A);\n}\n\n/// A default constructed BitFlags has no value set\n@safe @nogc pure nothrow unittest\n{\n    enum Enum\n    {\n        None,\n        A = 1 << 0,\n        B = 1 << 1,\n        C = 1 << 2\n    }\n\n    immutable BitFlags!Enum flags_empty;\n    assert(!(flags_empty & (Enum.A | Enum.B | Enum.C)));\n    assert(!(flags_empty & Enum.A) && !(flags_empty & Enum.B) && !(flags_empty & Enum.C));\n}\n\n// BitFlags can be variadically initialized\n@safe @nogc pure nothrow unittest\n{\n    import std.traits : EnumMembers;\n\n    enum Enum\n    {\n        A = 1 << 0,\n        B = 1 << 1,\n        C = 1 << 2\n    }\n\n    // Values can also be set using property access\n    BitFlags!Enum flags;\n    flags.A = true;\n    assert(flags & Enum.A);\n    flags.A = false;\n    assert(!(flags & Enum.A));\n\n    // BitFlags can be variadically initialized\n    immutable BitFlags!Enum flags_AB = BitFlags!Enum(Enum.A, Enum.B);\n    assert(flags_AB.A && flags_AB.B && !flags_AB.C);\n\n    // You can use the EnumMembers template to set all flags\n    immutable BitFlags!Enum flags_all = EnumMembers!Enum;\n    assert(flags_all.A && flags_all.B && flags_all.C);\n}\n\n/// Binary operations: subtracting and intersecting flags\n@safe @nogc pure nothrow unittest\n{\n    enum Enum\n    {\n        A = 1 << 0,\n        B = 1 << 1,\n        C = 1 << 2,\n    }\n    immutable BitFlags!Enum flags_AB = BitFlags!Enum(Enum.A, Enum.B);\n    immutable BitFlags!Enum flags_BC = BitFlags!Enum(Enum.B, Enum.C);\n\n    // Use the ~ operator for subtracting flags\n    immutable BitFlags!Enum flags_B = flags_AB & ~BitFlags!Enum(Enum.A);\n    assert(!flags_B.A && flags_B.B && !flags_B.C);\n\n    // use & between BitFlags for intersection\n    assert(flags_B == (flags_BC & flags_AB));\n}\n\n/// All the binary operators work in their assignment version\n@safe @nogc pure nothrow unittest\n{\n    enum Enum\n    {\n        A = 1 << 0,\n        B = 1 << 1,\n    }\n\n    BitFlags!Enum flags_empty, temp, flags_AB;\n    flags_AB = Enum.A | Enum.B;\n\n    temp |= flags_AB;\n    assert(temp == (flags_empty | flags_AB));\n\n    temp = flags_empty;\n    temp |= Enum.B;\n    assert(temp == (flags_empty | Enum.B));\n\n    temp = flags_empty;\n    temp &= flags_AB;\n    assert(temp == (flags_empty & flags_AB));\n\n    temp = flags_empty;\n    temp &= Enum.A;\n    assert(temp == (flags_empty & Enum.A));\n}\n\n/// Conversion to bool and int\n@safe @nogc pure nothrow unittest\n{\n    enum Enum\n    {\n        A = 1 << 0,\n        B = 1 << 1,\n    }\n\n    BitFlags!Enum flags;\n\n    // BitFlags with no value set evaluate to false\n    assert(!flags);\n\n    // BitFlags with at least one value set evaluate to true\n    flags |= Enum.A;\n    assert(flags);\n\n    // This can be useful to check intersection between BitFlags\n    BitFlags!Enum flags_AB = Enum.A | Enum.B;\n    assert(flags & flags_AB);\n    assert(flags & Enum.A);\n\n    // You can of course get you raw value out of flags\n    auto value = cast(int) flags;\n    assert(value == Enum.A);\n}\n\n/// You need to specify the `unsafe` parameter for enums with custom values\n@safe @nogc pure nothrow unittest\n{\n    enum UnsafeEnum\n    {\n        A = 1,\n        B = 2,\n        C = 4,\n        BC = B|C\n    }\n    static assert(!__traits(compiles, { BitFlags!UnsafeEnum flags; }));\n    BitFlags!(UnsafeEnum, Yes.unsafe) flags;\n\n    // property access tests for exact match of unsafe enums\n    flags.B = true;\n    assert(!flags.BC); // only B\n    flags.C = true;\n    assert(flags.BC); // both B and C\n    flags.B = false;\n    assert(!flags.BC); // only C\n\n    // property access sets all bits of unsafe enum group\n    flags = flags.init;\n    flags.BC = true;\n    assert(!flags.A && flags.B && flags.C);\n    flags.A = true;\n    flags.BC = false;\n    assert(flags.A && !flags.B && !flags.C);\n}\n\n// ReplaceType\n/**\nReplaces all occurrences of `From` into `To`, in one or more types `T`. For\nexample, $(D ReplaceType!(int, uint, Tuple!(int, float)[string])) yields\n$(D Tuple!(uint, float)[string]). The types in which replacement is performed\nmay be arbitrarily complex, including qualifiers, built-in type constructors\n(pointers, arrays, associative arrays, functions, and delegates), and template\ninstantiations; replacement proceeds transitively through the type definition.\nHowever, member types in `struct`s or `class`es are not replaced because there\nare no ways to express the types resulting after replacement.\n\nThis is an advanced type manipulation necessary e.g. for replacing the\nplaceholder type `This` in $(REF Algebraic, std,variant).\n\nReturns: `ReplaceType` aliases itself to the type(s) that result after\nreplacement.\n*/\ntemplate ReplaceType(From, To, T...)\n{\n    static if (T.length == 1)\n    {\n        static if (is(T[0] == From))\n            alias ReplaceType = To;\n        else static if (is(T[0] == const(U), U))\n            alias ReplaceType = const(ReplaceType!(From, To, U));\n        else static if (is(T[0] == immutable(U), U))\n            alias ReplaceType = immutable(ReplaceType!(From, To, U));\n        else static if (is(T[0] == shared(U), U))\n            alias ReplaceType = shared(ReplaceType!(From, To, U));\n        else static if (is(T[0] == U*, U))\n        {\n            static if (is(U == function))\n                alias ReplaceType = replaceTypeInFunctionType!(From, To, T[0]);\n            else\n                alias ReplaceType = ReplaceType!(From, To, U)*;\n        }\n        else static if (is(T[0] == delegate))\n        {\n            alias ReplaceType = replaceTypeInFunctionType!(From, To, T[0]);\n        }\n        else static if (is(T[0] == function))\n        {\n            static assert(0, \"Function types not supported,\" ~\n                \" use a function pointer type instead of \" ~ T[0].stringof);\n        }\n        else static if (is(T[0] : U!V, alias U, V...))\n        {\n            template replaceTemplateArgs(T...)\n            {\n                static if (is(typeof(T[0])))    // template argument is value or symbol\n                    enum replaceTemplateArgs = T[0];\n                else\n                    alias replaceTemplateArgs = ReplaceType!(From, To, T[0]);\n            }\n            alias ReplaceType = U!(staticMap!(replaceTemplateArgs, V));\n        }\n        else static if (is(T[0] == struct))\n            // don't match with alias this struct below (Issue 15168)\n            alias ReplaceType = T[0];\n        else static if (is(T[0] == U[], U))\n            alias ReplaceType = ReplaceType!(From, To, U)[];\n        else static if (is(T[0] == U[n], U, size_t n))\n            alias ReplaceType = ReplaceType!(From, To, U)[n];\n        else static if (is(T[0] == U[V], U, V))\n            alias ReplaceType =\n                ReplaceType!(From, To, U)[ReplaceType!(From, To, V)];\n        else\n            alias ReplaceType = T[0];\n    }\n    else static if (T.length > 1)\n    {\n        alias ReplaceType = AliasSeq!(ReplaceType!(From, To, T[0]),\n            ReplaceType!(From, To, T[1 .. $]));\n    }\n    else\n    {\n        alias ReplaceType = AliasSeq!();\n    }\n}\n\n///\n@safe unittest\n{\n    static assert(\n        is(ReplaceType!(int, string, int[]) == string[]) &&\n        is(ReplaceType!(int, string, int[int]) == string[string]) &&\n        is(ReplaceType!(int, string, const(int)[]) == const(string)[]) &&\n        is(ReplaceType!(int, string, Tuple!(int[], float))\n            == Tuple!(string[], float))\n    );\n}\n\nprivate template replaceTypeInFunctionType(From, To, fun)\n{\n    alias RX = ReplaceType!(From, To, ReturnType!fun);\n    alias PX = AliasSeq!(ReplaceType!(From, To, Parameters!fun));\n    // Wrapping with AliasSeq is neccesary because ReplaceType doesn't return\n    // tuple if Parameters!fun.length == 1\n\n    string gen()\n    {\n        enum  linkage = functionLinkage!fun;\n        alias attributes = functionAttributes!fun;\n        enum  variadicStyle = variadicFunctionStyle!fun;\n        alias storageClasses = ParameterStorageClassTuple!fun;\n\n        string result;\n\n        result ~= \"extern(\" ~ linkage ~ \") \";\n        static if (attributes & FunctionAttribute.ref_)\n        {\n            result ~= \"ref \";\n        }\n\n        result ~= \"RX\";\n        static if (is(fun == delegate))\n            result ~= \" delegate\";\n        else\n            result ~= \" function\";\n\n        result ~= \"(\";\n        static foreach (i; 0 .. PX.length)\n        {\n            if (i)\n                result ~= \", \";\n            if (storageClasses[i] & ParameterStorageClass.scope_)\n                result ~= \"scope \";\n            if (storageClasses[i] & ParameterStorageClass.out_)\n                result ~= \"out \";\n            if (storageClasses[i] & ParameterStorageClass.ref_)\n                result ~= \"ref \";\n            if (storageClasses[i] & ParameterStorageClass.lazy_)\n                result ~= \"lazy \";\n            if (storageClasses[i] & ParameterStorageClass.return_)\n                result ~= \"return \";\n\n            result ~= \"PX[\" ~ i.stringof ~ \"]\";\n        }\n        static if (variadicStyle == Variadic.typesafe)\n            result ~= \" ...\";\n        else static if (variadicStyle != Variadic.no)\n            result ~= \", ...\";\n        result ~= \")\";\n\n        static if (attributes & FunctionAttribute.pure_)\n            result ~= \" pure\";\n        static if (attributes & FunctionAttribute.nothrow_)\n            result ~= \" nothrow\";\n        static if (attributes & FunctionAttribute.property)\n            result ~= \" @property\";\n        static if (attributes & FunctionAttribute.trusted)\n            result ~= \" @trusted\";\n        static if (attributes & FunctionAttribute.safe)\n            result ~= \" @safe\";\n        static if (attributes & FunctionAttribute.nogc)\n            result ~= \" @nogc\";\n        static if (attributes & FunctionAttribute.system)\n            result ~= \" @system\";\n        static if (attributes & FunctionAttribute.const_)\n            result ~= \" const\";\n        static if (attributes & FunctionAttribute.immutable_)\n            result ~= \" immutable\";\n        static if (attributes & FunctionAttribute.inout_)\n            result ~= \" inout\";\n        static if (attributes & FunctionAttribute.shared_)\n            result ~= \" shared\";\n        static if (attributes & FunctionAttribute.return_)\n            result ~= \" return\";\n\n        return result;\n    }\n    //pragma(msg, \"gen ==> \", gen());\n\n    mixin(\"alias replaceTypeInFunctionType = \" ~ gen() ~ \";\");\n}\n\n@safe unittest\n{\n    template Test(Ts...)\n    {\n        static if (Ts.length)\n        {\n            //pragma(msg, \"Testing: ReplaceType!(\"~Ts[0].stringof~\", \"\n            //    ~Ts[1].stringof~\", \"~Ts[2].stringof~\")\");\n            static assert(is(ReplaceType!(Ts[0], Ts[1], Ts[2]) == Ts[3]),\n                \"ReplaceType!(\"~Ts[0].stringof~\", \"~Ts[1].stringof~\", \"\n                    ~Ts[2].stringof~\") == \"\n                    ~ReplaceType!(Ts[0], Ts[1], Ts[2]).stringof);\n            alias Test = Test!(Ts[4 .. $]);\n        }\n        else alias Test = void;\n    }\n\n    //import core.stdc.stdio;\n    alias RefFun1 = ref int function(float, long);\n    alias RefFun2 = ref float function(float, long);\n    extern(C) int printf(const char*, ...) nothrow @nogc @system;\n    extern(C) float floatPrintf(const char*, ...) nothrow @nogc @system;\n    int func(float);\n\n    int x;\n    struct S1 { void foo() { x = 1; } }\n    struct S2 { void bar() { x = 2; } }\n\n    alias Pass = Test!(\n        int, float, typeof(&func), float delegate(float),\n        int, float, typeof(&printf), typeof(&floatPrintf),\n        int, float, int function(out long, ...),\n            float function(out long, ...),\n        int, float, int function(ref float, long),\n            float function(ref float, long),\n        int, float, int function(ref int, long),\n            float function(ref float, long),\n        int, float, int function(out int, long),\n            float function(out float, long),\n        int, float, int function(lazy int, long),\n            float function(lazy float, long),\n        int, float, int function(out long, ref const int),\n            float function(out long, ref const float),\n        int, int, int, int,\n        int, float, int, float,\n        int, float, const int, const float,\n        int, float, immutable int, immutable float,\n        int, float, shared int, shared float,\n        int, float, int*, float*,\n        int, float, const(int)*, const(float)*,\n        int, float, const(int*), const(float*),\n        const(int)*, float, const(int*), const(float),\n        int*, float, const(int)*, const(int)*,\n        int, float, int[], float[],\n        int, float, int[42], float[42],\n        int, float, const(int)[42], const(float)[42],\n        int, float, const(int[42]), const(float[42]),\n        int, float, int[int], float[float],\n        int, float, int[double], float[double],\n        int, float, double[int], double[float],\n        int, float, int function(float, long), float function(float, long),\n        int, float, int function(float), float function(float),\n        int, float, int function(float, int), float function(float, float),\n        int, float, int delegate(float, long), float delegate(float, long),\n        int, float, int delegate(float), float delegate(float),\n        int, float, int delegate(float, int), float delegate(float, float),\n        int, float, Unique!int, Unique!float,\n        int, float, Tuple!(float, int), Tuple!(float, float),\n        int, float, RefFun1, RefFun2,\n        S1, S2,\n            S1[1][][S1]* function(),\n            S2[1][][S2]* function(),\n        int, string,\n               int[3] function(   int[] arr,    int[2] ...) pure @trusted,\n            string[3] function(string[] arr, string[2] ...) pure @trusted,\n    );\n\n    // Bugzilla 15168\n    static struct T1 { string s; alias s this; }\n    static struct T2 { char[10] s; alias s this; }\n    static struct T3 { string[string] s; alias s this; }\n    alias Pass2 = Test!(\n        ubyte, ubyte, T1, T1,\n        ubyte, ubyte, T2, T2,\n        ubyte, ubyte, T3, T3,\n    );\n}\n\n@safe unittest // Bugzilla 17116\n{\n    alias ConstDg = void delegate(float) const;\n    alias B = void delegate(int) const;\n    alias A = ReplaceType!(float, int, ConstDg);\n    static assert(is(B == A));\n}\n\n/**\nTernary type with three truth values:\n\n$(UL\n    $(LI `Ternary.yes` for `true`)\n    $(LI `Ternary.no` for `false`)\n    $(LI `Ternary.unknown` as an unknown state)\n)\n\nAlso known as trinary, trivalent, or trilean.\n\nSee_Also:\n    $(HTTP en.wikipedia.org/wiki/Three-valued_logic,\n        Three Valued Logic on Wikipedia)\n*/\nstruct Ternary\n{\n    @safe @nogc nothrow pure:\n\n    private ubyte value = 6;\n    private static Ternary make(ubyte b)\n    {\n        Ternary r = void;\n        r.value = b;\n        return r;\n    }\n\n    /**\n        The possible states of the `Ternary`\n    */\n    enum no = make(0);\n    /// ditto\n    enum yes = make(2);\n    /// ditto\n    enum unknown = make(6);\n\n    /**\n     Construct and assign from a `bool`, receiving `no` for `false` and `yes`\n     for `true`.\n    */\n    this(bool b) { value = b << 1; }\n\n    /// ditto\n    void opAssign(bool b) { value = b << 1; }\n\n    /**\n    Construct a ternary value from another ternary value\n    */\n    this(const Ternary b) { value = b.value; }\n\n    /**\n    $(TABLE Truth table for logical operations,\n      $(TR $(TH `a`) $(TH `b`) $(TH `$(TILDE)a`) $(TH `a | b`) $(TH `a & b`) $(TH `a ^ b`))\n      $(TR $(TD `no`) $(TD `no`) $(TD `yes`) $(TD `no`) $(TD `no`) $(TD `no`))\n      $(TR $(TD `no`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `no`) $(TD `yes`))\n      $(TR $(TD `no`) $(TD `unknown`) $(TD) $(TD `unknown`) $(TD `no`) $(TD `unknown`))\n      $(TR $(TD `yes`) $(TD `no`) $(TD `no`) $(TD `yes`) $(TD `no`) $(TD `yes`))\n      $(TR $(TD `yes`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `yes`) $(TD `no`))\n      $(TR $(TD `yes`) $(TD `unknown`) $(TD) $(TD `yes`) $(TD `unknown`) $(TD `unknown`))\n      $(TR $(TD `unknown`) $(TD `no`) $(TD `unknown`) $(TD `unknown`) $(TD `no`) $(TD `unknown`))\n      $(TR $(TD `unknown`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `unknown`) $(TD `unknown`))\n      $(TR $(TD `unknown`) $(TD `unknown`) $(TD) $(TD `unknown`) $(TD `unknown`) $(TD `unknown`))\n    )\n    */\n    Ternary opUnary(string s)() if (s == \"~\")\n    {\n        return make((386 >> value) & 6);\n    }\n\n    /// ditto\n    Ternary opBinary(string s)(Ternary rhs) if (s == \"|\")\n    {\n        return make((25_512 >> (value + rhs.value)) & 6);\n    }\n\n    /// ditto\n    Ternary opBinary(string s)(Ternary rhs) if (s == \"&\")\n    {\n        return make((26_144 >> (value + rhs.value)) & 6);\n    }\n\n    /// ditto\n    Ternary opBinary(string s)(Ternary rhs) if (s == \"^\")\n    {\n        return make((26_504 >> (value + rhs.value)) & 6);\n    }\n\n    /// ditto\n    Ternary opBinary(string s)(bool rhs)\n    if (s == \"|\" || s == \"&\" || s == \"^\")\n    {\n        return this.opBinary!s(Ternary(rhs));\n    }\n}\n\n///\n@safe @nogc nothrow pure\nunittest\n{\n    Ternary a;\n    assert(a == Ternary.unknown);\n\n    assert(~Ternary.yes == Ternary.no);\n    assert(~Ternary.no == Ternary.yes);\n    assert(~Ternary.unknown == Ternary.unknown);\n}\n\n@safe @nogc nothrow pure\nunittest\n{\n    alias f = Ternary.no, t = Ternary.yes, u = Ternary.unknown;\n    Ternary[27] truthTableAnd =\n    [\n        t, t, t,\n        t, u, u,\n        t, f, f,\n        u, t, u,\n        u, u, u,\n        u, f, f,\n        f, t, f,\n        f, u, f,\n        f, f, f,\n    ];\n\n    Ternary[27] truthTableOr =\n    [\n        t, t, t,\n        t, u, t,\n        t, f, t,\n        u, t, t,\n        u, u, u,\n        u, f, u,\n        f, t, t,\n        f, u, u,\n        f, f, f,\n    ];\n\n    Ternary[27] truthTableXor =\n    [\n        t, t, f,\n        t, u, u,\n        t, f, t,\n        u, t, u,\n        u, u, u,\n        u, f, u,\n        f, t, t,\n        f, u, u,\n        f, f, f,\n    ];\n\n    for (auto i = 0; i != truthTableAnd.length; i += 3)\n    {\n        assert((truthTableAnd[i] & truthTableAnd[i + 1])\n            == truthTableAnd[i + 2]);\n        assert((truthTableOr[i] | truthTableOr[i + 1])\n            == truthTableOr[i + 2]);\n        assert((truthTableXor[i] ^ truthTableXor[i + 1])\n            == truthTableXor[i + 2]);\n    }\n\n    Ternary a;\n    assert(a == Ternary.unknown);\n    static assert(!is(typeof({ if (a) {} })));\n    assert(!is(typeof({ auto b = Ternary(3); })));\n    a = true;\n    assert(a == Ternary.yes);\n    a = false;\n    assert(a == Ternary.no);\n    a = Ternary.unknown;\n    assert(a == Ternary.unknown);\n    Ternary b;\n    b = a;\n    assert(b == a);\n    assert(~Ternary.yes == Ternary.no);\n    assert(~Ternary.no == Ternary.yes);\n    assert(~Ternary.unknown == Ternary.unknown);\n}\n\n@safe @nogc nothrow pure\nunittest\n{\n    Ternary a = Ternary(true);\n    assert(a == Ternary.yes);\n    assert((a & false) == Ternary.no);\n    assert((a | false) == Ternary.yes);\n    assert((a ^ true) == Ternary.no);\n    assert((a ^ false) == Ternary.yes);\n}\n"
  },
  {
    "path": "libphobos/src/std/typetuple.d",
    "content": "/**\n * This module was renamed to disambiguate the term tuple, use\n * $(MREF std, meta) instead.\n *\n * Copyright: Copyright The D Language Foundation 2005 - 2015.\n * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:\n * Source:    $(PHOBOSSRC std/typetuple.d)\n *\n * $(SCRIPT inhibitQuickIndex = 1;)\n */\nmodule std.typetuple;\n\npublic import std.meta;\n\n/**\n * Alternate name for $(REF AliasSeq, std,meta) for legacy compatibility.\n */\nalias TypeTuple = AliasSeq;\n\n///\n@safe unittest\n{\n    import std.typetuple;\n    alias TL = TypeTuple!(int, double);\n\n    int foo(TL td)  // same as int foo(int, double);\n    {\n        return td[0] + cast(int) td[1];\n    }\n}\n\n///\n@safe unittest\n{\n    alias TL = TypeTuple!(int, double);\n\n    alias Types = TypeTuple!(TL, char);\n    static assert(is(Types == TypeTuple!(int, double, char)));\n}\n"
  },
  {
    "path": "libphobos/src/std/uni.d",
    "content": "// Written in the D programming language.\n\n/++\n    $(P The `std.uni` module provides an implementation\n    of fundamental Unicode algorithms and data structures.\n    This doesn't include UTF encoding and decoding primitives,\n    see $(REF decode, std,_utf) and $(REF encode, std,_utf) in $(MREF std, utf)\n    for this functionality. )\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Decode) $(TD\n    $(LREF byCodePoint)\n    $(LREF byGrapheme)\n    $(LREF decodeGrapheme)\n    $(LREF graphemeStride)\n))\n$(TR $(TD Comparison) $(TD\n    $(LREF icmp)\n    $(LREF sicmp)\n))\n$(TR $(TD Classification) $(TD\n    $(LREF isAlpha)\n    $(LREF isAlphaNum)\n    $(LREF isCodepointSet)\n    $(LREF isControl)\n    $(LREF isFormat)\n    $(LREF isGraphical)\n    $(LREF isIntegralPair)\n    $(LREF isMark)\n    $(LREF isNonCharacter)\n    $(LREF isNumber)\n    $(LREF isPrivateUse)\n    $(LREF isPunctuation)\n    $(LREF isSpace)\n    $(LREF isSurrogate)\n    $(LREF isSurrogateHi)\n    $(LREF isSurrogateLo)\n    $(LREF isSymbol)\n    $(LREF isWhite)\n))\n$(TR $(TD Normalization) $(TD\n    $(LREF NFC)\n    $(LREF NFD)\n    $(LREF NFKD)\n    $(LREF NormalizationForm)\n    $(LREF normalize)\n))\n$(TR $(TD Decompose) $(TD\n    $(LREF decompose)\n    $(LREF decomposeHangul)\n    $(LREF UnicodeDecomposition)\n))\n$(TR $(TD Compose) $(TD\n    $(LREF compose)\n    $(LREF composeJamo)\n))\n$(TR $(TD Sets) $(TD\n    $(LREF CodepointInterval)\n    $(LREF CodepointSet)\n    $(LREF InversionList)\n    $(LREF unicode)\n))\n$(TR $(TD Trie) $(TD\n    $(LREF codepointSetTrie)\n    $(LREF CodepointSetTrie)\n    $(LREF codepointTrie)\n    $(LREF CodepointTrie)\n    $(LREF toTrie)\n    $(LREF toDelegate)\n))\n$(TR $(TD Casing) $(TD\n    $(LREF asCapitalized)\n    $(LREF asLowerCase)\n    $(LREF asUpperCase)\n    $(LREF isLower)\n    $(LREF isUpper)\n    $(LREF toLower)\n    $(LREF toLowerInPlace)\n    $(LREF toUpper)\n    $(LREF toUpperInPlace)\n))\n$(TR $(TD Utf8Matcher) $(TD\n    $(LREF isUtfMatcher)\n    $(LREF MatcherConcept)\n    $(LREF utfMatcher)\n))\n$(TR $(TD Separators) $(TD\n    $(LREF lineSep)\n    $(LREF nelSep)\n    $(LREF paraSep)\n))\n$(TR $(TD Building blocks) $(TD\n    $(LREF allowedIn)\n    $(LREF combiningClass)\n    $(LREF Grapheme)\n))\n)\n\n    $(P All primitives listed operate on Unicode characters and\n        sets of characters. For functions which operate on ASCII characters\n        and ignore Unicode $(CHARACTERS), see $(MREF std, ascii).\n        For definitions of Unicode $(CHARACTER), $(CODEPOINT) and other terms\n        used throughout this module see the $(S_LINK Terminology, terminology) section\n        below.\n    )\n    $(P The focus of this module is the core needs of developing Unicode-aware\n        applications. To that effect it provides the following optimized primitives:\n    )\n    $(UL\n        $(LI Character classification by category and common properties:\n            $(LREF isAlpha), $(LREF isWhite) and others.\n        )\n        $(LI\n            Case-insensitive string comparison ($(LREF sicmp), $(LREF icmp)).\n        )\n        $(LI\n            Converting text to any of the four normalization forms via $(LREF normalize).\n        )\n        $(LI\n            Decoding ($(LREF decodeGrapheme))  and iteration ($(LREF byGrapheme), $(LREF graphemeStride))\n            by user-perceived characters, that is by $(LREF Grapheme) clusters.\n        )\n        $(LI\n            Decomposing and composing of individual character(s) according to canonical\n            or compatibility rules, see $(LREF compose) and $(LREF decompose),\n            including the specific version for Hangul syllables $(LREF composeJamo)\n            and $(LREF decomposeHangul).\n        )\n    )\n    $(P It's recognized that an application may need further enhancements\n        and extensions, such as less commonly known algorithms,\n        or tailoring existing ones for region specific needs. To help users\n        with building any extra functionality beyond the core primitives,\n        the module provides:\n    )\n    $(UL\n        $(LI\n            $(LREF CodepointSet), a type for easy manipulation of sets of characters.\n            Besides the typical set algebra it provides an unusual feature:\n            a D source code generator for detection of $(CODEPOINTS) in this set.\n            This is a boon for meta-programming parser frameworks,\n            and is used internally to power classification in small\n            sets like $(LREF isWhite).\n        )\n        $(LI\n            A way to construct optimal packed multi-stage tables also known as a\n            special case of $(LINK2 https://en.wikipedia.org/wiki/Trie, Trie).\n            The functions $(LREF codepointTrie), $(LREF codepointSetTrie)\n            construct custom tries that map dchar to value.\n            The end result is a fast and predictable $(BIGOH 1) lookup that powers\n            functions like $(LREF isAlpha) and $(LREF combiningClass),\n            but for user-defined data sets.\n        )\n        $(LI\n            A useful technique for Unicode-aware parsers that perform\n            character classification of encoded $(CODEPOINTS)\n            is to avoid unnecassary decoding at all costs.\n            $(LREF utfMatcher) provides an improvement over the usual workflow\n            of decode-classify-process, combining the decoding and classification\n            steps. By extracting necessary bits directly from encoded\n            $(S_LINK Code unit, code units) matchers achieve\n            significant performance improvements. See $(LREF MatcherConcept) for\n            the common interface of UTF matchers.\n        )\n        $(LI\n            Generally useful building blocks for customized normalization:\n            $(LREF combiningClass) for querying combining class\n            and $(LREF allowedIn) for testing the Quick_Check\n            property of a given normalization form.\n        )\n        $(LI\n            Access to a large selection of commonly used sets of $(CODEPOINTS).\n            $(S_LINK Unicode properties, Supported sets) include Script,\n            Block and General Category. The exact contents of a set can be\n            observed in the CLDR utility, on the\n            $(HTTP www.unicode.org/cldr/utility/properties.jsp, property index) page\n            of the Unicode website.\n            See $(LREF unicode) for easy and (optionally) compile-time checked set\n            queries.\n        )\n    )\n    $(SECTION Synopsis)\n    ---\n    import std.uni;\n    void main()\n    {\n        // initialize code point sets using script/block or property name\n        // now 'set' contains code points from both scripts.\n        auto set = unicode(\"Cyrillic\") | unicode(\"Armenian\");\n        // same thing but simpler and checked at compile-time\n        auto ascii = unicode.ASCII;\n        auto currency = unicode.Currency_Symbol;\n\n        // easy set ops\n        auto a = set & ascii;\n        assert(a.empty); // as it has no intersection with ascii\n        a = set | ascii;\n        auto b = currency - a; // subtract all ASCII, Cyrillic and Armenian\n\n        // some properties of code point sets\n        assert(b.length > 45); // 46 items in Unicode 6.1, even more in 6.2\n        // testing presence of a code point in a set\n        // is just fine, it is O(logN)\n        assert(!b['$']);\n        assert(!b['\\u058F']); // Armenian dram sign\n        assert(b['¥']);\n\n        // building fast lookup tables, these guarantee O(1) complexity\n        // 1-level Trie lookup table essentially a huge bit-set ~262Kb\n        auto oneTrie = toTrie!1(b);\n        // 2-level far more compact but typically slightly slower\n        auto twoTrie = toTrie!2(b);\n        // 3-level even smaller, and a bit slower yet\n        auto threeTrie = toTrie!3(b);\n        assert(oneTrie['£']);\n        assert(twoTrie['£']);\n        assert(threeTrie['£']);\n\n        // build the trie with the most sensible trie level\n        // and bind it as a functor\n        auto cyrillicOrArmenian = toDelegate(set);\n        auto balance = find!(cyrillicOrArmenian)(\"Hello ընկեր!\");\n        assert(balance == \"ընկեր!\");\n        // compatible with bool delegate(dchar)\n        bool delegate(dchar) bindIt = cyrillicOrArmenian;\n\n        // Normalization\n        string s = \"Plain ascii (and not only), is always normalized!\";\n        assert(s is normalize(s));// is the same string\n\n        string nonS = \"A\\u0308ffin\"; // A ligature\n        auto nS = normalize(nonS); // to NFC, the W3C endorsed standard\n        assert(nS == \"Äffin\");\n        assert(nS != nonS);\n        string composed = \"Äffin\";\n\n        assert(normalize!NFD(composed) == \"A\\u0308ffin\");\n        // to NFKD, compatibility decomposition useful for fuzzy matching/searching\n        assert(normalize!NFKD(\"2¹⁰\") == \"210\");\n    }\n    ---\n    $(SECTION Terminology)\n    $(P The following is a list of important Unicode notions\n    and definitions. Any conventions used specifically in this\n    module alone are marked as such. The descriptions are based on the formal\n    definition as found in $(HTTP www.unicode.org/versions/Unicode6.2.0/ch03.pdf,\n    chapter three of The Unicode Standard Core Specification.)\n    )\n    $(P $(DEF Abstract character) A unit of information used for the organization,\n        control, or representation of textual data.\n        Note that:\n        $(UL\n            $(LI When representing data, the nature of that data\n                is generally symbolic as opposed to some other\n                kind of data (for example, visual).\n            )\n             $(LI An abstract character has no concrete form\n                and should not be confused with a $(S_LINK Glyph, glyph).\n            )\n            $(LI An abstract character does not necessarily\n                correspond to what a user thinks of as a “character”\n                and should not be confused with a $(LREF Grapheme).\n            )\n            $(LI The abstract characters encoded (see Encoded character)\n                are known as Unicode abstract characters.\n            )\n            $(LI Abstract characters not directly\n                encoded by the Unicode Standard can often be\n                represented by the use of combining character sequences.\n            )\n        )\n    )\n    $(P $(DEF Canonical decomposition)\n        The decomposition of a character or character sequence\n        that results from recursively applying the canonical\n        mappings found in the Unicode Character Database\n        and these described in Conjoining Jamo Behavior\n        (section 12 of\n        $(HTTP www.unicode.org/uni2book/ch03.pdf, Unicode Conformance)).\n    )\n    $(P $(DEF Canonical composition)\n        The precise definition of the Canonical composition\n        is the algorithm as specified in $(HTTP www.unicode.org/uni2book/ch03.pdf,\n        Unicode Conformance) section 11.\n        Informally it's the process that does the reverse of the canonical\n        decomposition with the addition of certain rules\n        that e.g. prevent legacy characters from appearing in the composed result.\n    )\n    $(P $(DEF Canonical equivalent)\n        Two character sequences are said to be canonical equivalents if\n        their full canonical decompositions are identical.\n    )\n    $(P $(DEF Character) Typically differs by context.\n        For the purpose of this documentation the term $(I character)\n        implies $(I encoded character), that is, a code point having\n        an assigned abstract character (a symbolic meaning).\n    )\n    $(P $(DEF Code point) Any value in the Unicode codespace;\n        that is, the range of integers from 0 to 10FFFF (hex).\n        Not all code points are assigned to encoded characters.\n    )\n    $(P $(DEF Code unit) The minimal bit combination that can represent\n        a unit of encoded text for processing or interchange.\n        Depending on the encoding this could be:\n        8-bit code units in the UTF-8 (`char`),\n        16-bit code units in the UTF-16 (`wchar`),\n        and 32-bit code units in the UTF-32 (`dchar`).\n        $(I Note that in UTF-32, a code unit is a code point\n        and is represented by the D `dchar` type.)\n    )\n    $(P $(DEF Combining character) A character with the General Category\n        of Combining Mark(M).\n        $(UL\n            $(LI All characters with non-zero canonical combining class\n            are combining characters, but the reverse is not the case:\n            there are combining characters with a zero combining class.\n            )\n            $(LI These characters are not normally used in isolation\n            unless they are being described. They include such characters\n            as accents, diacritics, Hebrew points, Arabic vowel signs,\n            and Indic matras.\n            )\n        )\n    )\n    $(P $(DEF Combining class)\n        A numerical value used by the Unicode Canonical Ordering Algorithm\n        to determine which sequences of combining marks are to be\n        considered canonically equivalent and  which are not.\n    )\n    $(P $(DEF Compatibility decomposition)\n        The decomposition of a character or character sequence that results\n        from recursively applying both the compatibility mappings and\n        the canonical mappings found in the Unicode Character Database, and those\n        described in Conjoining Jamo Behavior no characters\n        can be further decomposed.\n    )\n    $(P $(DEF Compatibility equivalent)\n        Two character sequences are said to be compatibility\n        equivalents if their full compatibility decompositions are identical.\n    )\n    $(P $(DEF Encoded character) An association (or mapping)\n        between an abstract character and a code point.\n    )\n    $(P $(DEF Glyph) The actual, concrete image of a glyph representation\n        having been rasterized or otherwise imaged onto some display surface.\n    )\n    $(P $(DEF Grapheme base) A character with the property\n        Grapheme_Base, or any standard Korean syllable block.\n    )\n    $(P $(DEF Grapheme cluster) Defined as the text between\n        grapheme boundaries  as specified by Unicode Standard Annex #29,\n        $(HTTP www.unicode.org/reports/tr29/, Unicode text segmentation).\n        Important general properties of a grapheme:\n        $(UL\n            $(LI The grapheme cluster represents a horizontally segmentable\n            unit of text, consisting of some grapheme base (which may\n            consist of a Korean syllable) together with any number of\n            nonspacing marks applied to it.\n            )\n            $(LI  A grapheme cluster typically starts with a grapheme base\n            and then extends across any subsequent sequence of nonspacing marks.\n            A grapheme cluster is most directly relevant to text rendering and\n            processes such as cursor placement and text selection in editing,\n            but may also be relevant to comparison and searching.\n            )\n            $(LI For many processes, a grapheme cluster behaves as if it was a\n            single character with the same properties as its grapheme base.\n            Effectively, nonspacing marks apply $(I graphically) to the base,\n            but do not change its properties.\n            )\n        )\n        $(P This module defines a number of primitives that work with graphemes:\n        $(LREF Grapheme), $(LREF decodeGrapheme) and $(LREF graphemeStride).\n        All of them are using $(I extended grapheme) boundaries\n        as defined in the aforementioned standard annex.\n        )\n    )\n    $(P $(DEF Nonspacing mark) A combining character with the\n        General Category of Nonspacing Mark (Mn) or Enclosing Mark (Me).\n    )\n    $(P $(DEF Spacing mark) A combining character that is not a nonspacing mark.\n    )\n    $(SECTION Normalization)\n    $(P The concepts of $(S_LINK Canonical equivalent, canonical equivalent)\n        or $(S_LINK Compatibility equivalent, compatibility equivalent)\n        characters in the Unicode Standard make it necessary to have a full, formal\n        definition of equivalence for Unicode strings.\n        String equivalence is determined by a process called normalization,\n        whereby strings are converted into forms which are compared\n        directly for identity. This is the primary goal of the normalization process,\n        see the function $(LREF normalize) to convert into any of\n        the four defined forms.\n    )\n    $(P A very important attribute of the Unicode Normalization Forms\n        is that they must remain stable between versions of the Unicode Standard.\n        A Unicode string normalized to a particular Unicode Normalization Form\n        in one version of the standard is guaranteed to remain in that Normalization\n        Form for implementations of future versions of the standard.\n    )\n    $(P The Unicode Standard specifies four normalization forms.\n        Informally, two of these forms are defined by maximal decomposition\n        of equivalent sequences, and two of these forms are defined\n        by maximal $(I composition) of equivalent sequences.\n            $(UL\n            $(LI Normalization Form D (NFD): The $(S_LINK Canonical decomposition,\n                canonical decomposition) of a character sequence.)\n            $(LI Normalization Form KD (NFKD): The $(S_LINK Compatibility decomposition,\n                compatibility decomposition) of a character sequence.)\n            $(LI Normalization Form C (NFC): The canonical composition of the\n                $(S_LINK Canonical decomposition, canonical decomposition)\n                of a coded character sequence.)\n            $(LI Normalization Form KC (NFKC): The canonical composition\n            of the $(S_LINK Compatibility decomposition,\n                compatibility decomposition) of a character sequence)\n            )\n    )\n    $(P The choice of the normalization form depends on the particular use case.\n        NFC is the best form for general text, since it's more compatible with\n        strings converted from legacy encodings. NFKC is the preferred form for\n        identifiers, especially where there are security concerns. NFD and NFKD\n        are the most useful for internal processing.\n    )\n    $(SECTION Construction of lookup tables)\n    $(P The Unicode standard describes a set of algorithms that\n        depend on having the ability to quickly look up various properties\n        of a code point. Given the the codespace of about 1 million $(CODEPOINTS),\n        it is not a trivial task to provide a space-efficient solution for\n        the multitude of properties.\n    )\n    $(P Common approaches such as hash-tables or binary search over\n        sorted code point intervals (as in $(LREF InversionList)) are insufficient.\n        Hash-tables have enormous memory footprint and binary search\n        over intervals is not fast enough for some heavy-duty algorithms.\n    )\n    $(P The recommended solution (see Unicode Implementation Guidelines)\n        is using multi-stage tables that are an implementation of the\n        $(HTTP en.wikipedia.org/wiki/Trie, Trie) data structure with integer\n        keys and a fixed number of stages. For the remainder of the section\n        this will be called a fixed trie. The following describes a particular\n        implementation that is aimed for the speed of access at the expense\n        of ideal size savings.\n    )\n    $(P Taking a 2-level Trie as an example the principle of operation is as follows.\n        Split the number of bits in a key (code point, 21 bits) into 2 components\n        (e.g. 15 and 8).  The first is the number of bits in the index of the trie\n         and the other is number of bits in each page of the trie.\n        The layout of the trie is then an array of size 2^^bits-of-index followed\n        an array of memory chunks of size 2^^bits-of-page/bits-per-element.\n    )\n    $(P The number of pages is variable (but not less then 1)\n        unlike the number of entries in the index. The slots of the index\n        all have to contain a number of a page that is present. The lookup is then\n        just a couple of operations - slice the upper bits,\n        lookup an index for these, take a page at this index and use\n        the lower bits as an offset within this page.\n\n        Assuming that pages are laid out consequently\n        in one array at `pages`, the pseudo-code is:\n    )\n    ---\n    auto elemsPerPage = (2 ^^ bits_per_page) / Value.sizeOfInBits;\n    pages[index[n >> bits_per_page]][n & (elemsPerPage - 1)];\n    ---\n    $(P Where if `elemsPerPage` is a power of 2 the whole process is\n        a handful of simple instructions and 2 array reads. Subsequent levels\n        of the trie are introduced by recursing on this notion - the index array\n        is treated as values. The number of bits in index is then again\n        split into 2 parts, with pages over 'current-index' and the new 'upper-index'.\n    )\n\n    $(P For completeness a level 1 trie is simply an array.\n        The current implementation takes advantage of bit-packing values\n        when the range is known to be limited in advance (such as `bool`).\n        See also $(LREF BitPacked) for enforcing it manually.\n        The major size advantage however comes from the fact\n        that multiple $(B identical pages on every level are merged) by construction.\n    )\n    $(P The process of constructing a trie is more involved and is hidden from\n        the user in a form of the convenience functions $(LREF codepointTrie),\n        $(LREF codepointSetTrie) and the even more convenient $(LREF toTrie).\n        In general a set or built-in AA with `dchar` type\n        can be turned into a trie. The trie object in this module\n        is read-only (immutable); it's effectively frozen after construction.\n    )\n    $(SECTION Unicode properties)\n    $(P This is a full list of Unicode properties accessible through $(LREF unicode)\n        with specific helpers per category nested within. Consult the\n        $(HTTP www.unicode.org/cldr/utility/properties.jsp, CLDR utility)\n        when in doubt about the contents of a particular set.\n    )\n    $(P General category sets listed below are only accessible with the\n        $(LREF unicode) shorthand accessor.)\n        $(BOOKTABLE $(B General category ),\n             $(TR $(TH Abb.) $(TH Long form)\n                $(TH Abb.) $(TH Long form)$(TH Abb.) $(TH Long form))\n            $(TR $(TD L) $(TD Letter)\n                $(TD Cn) $(TD Unassigned)  $(TD Po) $(TD Other_Punctuation))\n            $(TR $(TD Ll) $(TD Lowercase_Letter)\n                $(TD Co) $(TD Private_Use) $(TD Ps) $(TD Open_Punctuation))\n            $(TR $(TD Lm) $(TD Modifier_Letter)\n                $(TD Cs) $(TD Surrogate)   $(TD S) $(TD Symbol))\n            $(TR $(TD Lo) $(TD Other_Letter)\n                $(TD N) $(TD Number)  $(TD Sc) $(TD Currency_Symbol))\n            $(TR $(TD Lt) $(TD Titlecase_Letter)\n              $(TD Nd) $(TD Decimal_Number)  $(TD Sk) $(TD Modifier_Symbol))\n            $(TR $(TD Lu) $(TD Uppercase_Letter)\n              $(TD Nl) $(TD Letter_Number)   $(TD Sm) $(TD Math_Symbol))\n            $(TR $(TD M) $(TD Mark)\n              $(TD No) $(TD Other_Number)    $(TD So) $(TD Other_Symbol))\n            $(TR $(TD Mc) $(TD Spacing_Mark)\n              $(TD P) $(TD Punctuation) $(TD Z) $(TD Separator))\n            $(TR $(TD Me) $(TD Enclosing_Mark)\n              $(TD Pc) $(TD Connector_Punctuation)   $(TD Zl) $(TD Line_Separator))\n            $(TR $(TD Mn) $(TD Nonspacing_Mark)\n              $(TD Pd) $(TD Dash_Punctuation)    $(TD Zp) $(TD Paragraph_Separator))\n            $(TR $(TD C) $(TD Other)\n              $(TD Pe) $(TD Close_Punctuation) $(TD Zs) $(TD Space_Separator))\n            $(TR $(TD Cc) $(TD Control) $(TD Pf)\n              $(TD Final_Punctuation)   $(TD -) $(TD Any))\n            $(TR $(TD Cf) $(TD Format)\n              $(TD Pi) $(TD Initial_Punctuation) $(TD -) $(TD ASCII))\n    )\n    $(P Sets for other commonly useful properties that are\n        accessible with $(LREF unicode):)\n        $(BOOKTABLE $(B Common binary properties),\n            $(TR $(TH Name) $(TH Name) $(TH Name))\n            $(TR $(TD Alphabetic)  $(TD Ideographic) $(TD Other_Uppercase))\n            $(TR $(TD ASCII_Hex_Digit) $(TD IDS_Binary_Operator) $(TD Pattern_Syntax))\n            $(TR $(TD Bidi_Control)    $(TD ID_Start)    $(TD Pattern_White_Space))\n            $(TR $(TD Cased)   $(TD IDS_Trinary_Operator)    $(TD Quotation_Mark))\n            $(TR $(TD Case_Ignorable)  $(TD Join_Control)    $(TD Radical))\n            $(TR $(TD Dash)    $(TD Logical_Order_Exception) $(TD Soft_Dotted))\n            $(TR $(TD Default_Ignorable_Code_Point)    $(TD Lowercase)   $(TD STerm))\n            $(TR $(TD Deprecated)  $(TD Math)    $(TD Terminal_Punctuation))\n            $(TR $(TD Diacritic)   $(TD Noncharacter_Code_Point) $(TD Unified_Ideograph))\n            $(TR $(TD Extender)    $(TD Other_Alphabetic)    $(TD Uppercase))\n            $(TR $(TD Grapheme_Base)   $(TD Other_Default_Ignorable_Code_Point)  $(TD Variation_Selector))\n            $(TR $(TD Grapheme_Extend) $(TD Other_Grapheme_Extend)   $(TD White_Space))\n            $(TR $(TD Grapheme_Link)   $(TD Other_ID_Continue)   $(TD XID_Continue))\n            $(TR $(TD Hex_Digit)   $(TD Other_ID_Start)  $(TD XID_Start))\n            $(TR $(TD Hyphen)  $(TD Other_Lowercase) )\n            $(TR $(TD ID_Continue) $(TD Other_Math)  )\n    )\n    $(P Below is the table with block names accepted by $(LREF unicode.block).\n        Note that the shorthand version $(LREF unicode) requires \"In\"\n        to be prepended to the names of blocks so as to disambiguate\n        scripts and blocks.\n    )\n    $(BOOKTABLE $(B Blocks),\n        $(TR $(TD Aegean Numbers)    $(TD Ethiopic Extended) $(TD Mongolian))\n        $(TR $(TD Alchemical Symbols)    $(TD Ethiopic Extended-A)   $(TD Musical Symbols))\n        $(TR $(TD Alphabetic Presentation Forms) $(TD Ethiopic Supplement)   $(TD Myanmar))\n        $(TR $(TD Ancient Greek Musical Notation)    $(TD General Punctuation)   $(TD Myanmar Extended-A))\n        $(TR $(TD Ancient Greek Numbers) $(TD Geometric Shapes)  $(TD New Tai Lue))\n        $(TR $(TD Ancient Symbols)   $(TD Georgian)  $(TD NKo))\n        $(TR $(TD Arabic)    $(TD Georgian Supplement)   $(TD Number Forms))\n        $(TR $(TD Arabic Extended-A) $(TD Glagolitic)    $(TD Ogham))\n        $(TR $(TD Arabic Mathematical Alphabetic Symbols)    $(TD Gothic)    $(TD Ol Chiki))\n        $(TR $(TD Arabic Presentation Forms-A)   $(TD Greek and Coptic)  $(TD Old Italic))\n        $(TR $(TD Arabic Presentation Forms-B)   $(TD Greek Extended)    $(TD Old Persian))\n        $(TR $(TD Arabic Supplement) $(TD Gujarati)  $(TD Old South Arabian))\n        $(TR $(TD Armenian)  $(TD Gurmukhi)  $(TD Old Turkic))\n        $(TR $(TD Arrows)    $(TD Halfwidth and Fullwidth Forms) $(TD Optical Character Recognition))\n        $(TR $(TD Avestan)   $(TD Hangul Compatibility Jamo) $(TD Oriya))\n        $(TR $(TD Balinese)  $(TD Hangul Jamo)   $(TD Osmanya))\n        $(TR $(TD Bamum) $(TD Hangul Jamo Extended-A)    $(TD Phags-pa))\n        $(TR $(TD Bamum Supplement)  $(TD Hangul Jamo Extended-B)    $(TD Phaistos Disc))\n        $(TR $(TD Basic Latin)   $(TD Hangul Syllables)  $(TD Phoenician))\n        $(TR $(TD Batak) $(TD Hanunoo)   $(TD Phonetic Extensions))\n        $(TR $(TD Bengali)   $(TD Hebrew)    $(TD Phonetic Extensions Supplement))\n        $(TR $(TD Block Elements)    $(TD High Private Use Surrogates)   $(TD Playing Cards))\n        $(TR $(TD Bopomofo)  $(TD High Surrogates)   $(TD Private Use Area))\n        $(TR $(TD Bopomofo Extended) $(TD Hiragana)  $(TD Rejang))\n        $(TR $(TD Box Drawing)   $(TD Ideographic Description Characters)    $(TD Rumi Numeral Symbols))\n        $(TR $(TD Brahmi)    $(TD Imperial Aramaic)  $(TD Runic))\n        $(TR $(TD Braille Patterns)  $(TD Inscriptional Pahlavi) $(TD Samaritan))\n        $(TR $(TD Buginese)  $(TD Inscriptional Parthian)    $(TD Saurashtra))\n        $(TR $(TD Buhid) $(TD IPA Extensions)    $(TD Sharada))\n        $(TR $(TD Byzantine Musical Symbols) $(TD Javanese)  $(TD Shavian))\n        $(TR $(TD Carian)    $(TD Kaithi)    $(TD Sinhala))\n        $(TR $(TD Chakma)    $(TD Kana Supplement)   $(TD Small Form Variants))\n        $(TR $(TD Cham)  $(TD Kanbun)    $(TD Sora Sompeng))\n        $(TR $(TD Cherokee)  $(TD Kangxi Radicals)   $(TD Spacing Modifier Letters))\n        $(TR $(TD CJK Compatibility) $(TD Kannada)   $(TD Specials))\n        $(TR $(TD CJK Compatibility Forms)   $(TD Katakana)  $(TD Sundanese))\n        $(TR $(TD CJK Compatibility Ideographs)  $(TD Katakana Phonetic Extensions)  $(TD Sundanese Supplement))\n        $(TR $(TD CJK Compatibility Ideographs Supplement)   $(TD Kayah Li)  $(TD Superscripts and Subscripts))\n        $(TR $(TD CJK Radicals Supplement)   $(TD Kharoshthi)    $(TD Supplemental Arrows-A))\n        $(TR $(TD CJK Strokes)   $(TD Khmer) $(TD Supplemental Arrows-B))\n        $(TR $(TD CJK Symbols and Punctuation)   $(TD Khmer Symbols) $(TD Supplemental Mathematical Operators))\n        $(TR $(TD CJK Unified Ideographs)    $(TD Lao)   $(TD Supplemental Punctuation))\n        $(TR $(TD CJK Unified Ideographs Extension A)    $(TD Latin-1 Supplement)    $(TD Supplementary Private Use Area-A))\n        $(TR $(TD CJK Unified Ideographs Extension B)    $(TD Latin Extended-A)  $(TD Supplementary Private Use Area-B))\n        $(TR $(TD CJK Unified Ideographs Extension C)    $(TD Latin Extended Additional) $(TD Syloti Nagri))\n        $(TR $(TD CJK Unified Ideographs Extension D)    $(TD Latin Extended-B)  $(TD Syriac))\n        $(TR $(TD Combining Diacritical Marks)   $(TD Latin Extended-C)  $(TD Tagalog))\n        $(TR $(TD Combining Diacritical Marks for Symbols)   $(TD Latin Extended-D)  $(TD Tagbanwa))\n        $(TR $(TD Combining Diacritical Marks Supplement)    $(TD Lepcha)    $(TD Tags))\n        $(TR $(TD Combining Half Marks)  $(TD Letterlike Symbols)    $(TD Tai Le))\n        $(TR $(TD Common Indic Number Forms) $(TD Limbu) $(TD Tai Tham))\n        $(TR $(TD Control Pictures)  $(TD Linear B Ideograms)    $(TD Tai Viet))\n        $(TR $(TD Coptic)    $(TD Linear B Syllabary)    $(TD Tai Xuan Jing Symbols))\n        $(TR $(TD Counting Rod Numerals) $(TD Lisu)  $(TD Takri))\n        $(TR $(TD Cuneiform) $(TD Low Surrogates)    $(TD Tamil))\n        $(TR $(TD Cuneiform Numbers and Punctuation) $(TD Lycian)    $(TD Telugu))\n        $(TR $(TD Currency Symbols)  $(TD Lydian)    $(TD Thaana))\n        $(TR $(TD Cypriot Syllabary) $(TD Mahjong Tiles) $(TD Thai))\n        $(TR $(TD Cyrillic)  $(TD Malayalam) $(TD Tibetan))\n        $(TR $(TD Cyrillic Extended-A)   $(TD Mandaic)   $(TD Tifinagh))\n        $(TR $(TD Cyrillic Extended-B)   $(TD Mathematical Alphanumeric Symbols) $(TD Transport And Map Symbols))\n        $(TR $(TD Cyrillic Supplement)   $(TD Mathematical Operators)    $(TD Ugaritic))\n        $(TR $(TD Deseret)   $(TD Meetei Mayek)  $(TD Unified Canadian Aboriginal Syllabics))\n        $(TR $(TD Devanagari)    $(TD Meetei Mayek Extensions)   $(TD Unified Canadian Aboriginal Syllabics Extended))\n        $(TR $(TD Devanagari Extended)   $(TD Meroitic Cursive)  $(TD Vai))\n        $(TR $(TD Dingbats)  $(TD Meroitic Hieroglyphs)  $(TD Variation Selectors))\n        $(TR $(TD Domino Tiles)  $(TD Miao)  $(TD Variation Selectors Supplement))\n        $(TR $(TD Egyptian Hieroglyphs)  $(TD Miscellaneous Mathematical Symbols-A)  $(TD Vedic Extensions))\n        $(TR $(TD Emoticons) $(TD Miscellaneous Mathematical Symbols-B)  $(TD Vertical Forms))\n        $(TR $(TD Enclosed Alphanumerics)    $(TD Miscellaneous Symbols) $(TD Yijing Hexagram Symbols))\n        $(TR $(TD Enclosed Alphanumeric Supplement)  $(TD Miscellaneous Symbols and Arrows)  $(TD Yi Radicals))\n        $(TR $(TD Enclosed CJK Letters and Months)   $(TD Miscellaneous Symbols And Pictographs) $(TD Yi Syllables))\n        $(TR $(TD Enclosed Ideographic Supplement)   $(TD Miscellaneous Technical)   )\n        $(TR $(TD Ethiopic)  $(TD Modifier Tone Letters) )\n    )\n    $(P Below is the table with script names accepted by $(LREF unicode.script)\n        and by the shorthand version $(LREF unicode):)\n        $(BOOKTABLE $(B Scripts),\n            $(TR $(TD Arabic)  $(TD Hanunoo) $(TD Old_Italic))\n            $(TR $(TD Armenian)    $(TD Hebrew)  $(TD Old_Persian))\n            $(TR $(TD Avestan) $(TD Hiragana)    $(TD Old_South_Arabian))\n            $(TR $(TD Balinese)    $(TD Imperial_Aramaic)    $(TD Old_Turkic))\n            $(TR $(TD Bamum)   $(TD Inherited)   $(TD Oriya))\n            $(TR $(TD Batak)   $(TD Inscriptional_Pahlavi)   $(TD Osmanya))\n            $(TR $(TD Bengali) $(TD Inscriptional_Parthian)  $(TD Phags_Pa))\n            $(TR $(TD Bopomofo)    $(TD Javanese)    $(TD Phoenician))\n            $(TR $(TD Brahmi)  $(TD Kaithi)  $(TD Rejang))\n            $(TR $(TD Braille) $(TD Kannada) $(TD Runic))\n            $(TR $(TD Buginese)    $(TD Katakana)    $(TD Samaritan))\n            $(TR $(TD Buhid)   $(TD Kayah_Li)    $(TD Saurashtra))\n            $(TR $(TD Canadian_Aboriginal) $(TD Kharoshthi)  $(TD Sharada))\n            $(TR $(TD Carian)  $(TD Khmer)   $(TD Shavian))\n            $(TR $(TD Chakma)  $(TD Lao) $(TD Sinhala))\n            $(TR $(TD Cham)    $(TD Latin)   $(TD Sora_Sompeng))\n            $(TR $(TD Cherokee)    $(TD Lepcha)  $(TD Sundanese))\n            $(TR $(TD Common)  $(TD Limbu)   $(TD Syloti_Nagri))\n            $(TR $(TD Coptic)  $(TD Linear_B)    $(TD Syriac))\n            $(TR $(TD Cuneiform)   $(TD Lisu)    $(TD Tagalog))\n            $(TR $(TD Cypriot) $(TD Lycian)  $(TD Tagbanwa))\n            $(TR $(TD Cyrillic)    $(TD Lydian)  $(TD Tai_Le))\n            $(TR $(TD Deseret) $(TD Malayalam)   $(TD Tai_Tham))\n            $(TR $(TD Devanagari)  $(TD Mandaic) $(TD Tai_Viet))\n            $(TR $(TD Egyptian_Hieroglyphs)    $(TD Meetei_Mayek)    $(TD Takri))\n            $(TR $(TD Ethiopic)    $(TD Meroitic_Cursive)    $(TD Tamil))\n            $(TR $(TD Georgian)    $(TD Meroitic_Hieroglyphs)    $(TD Telugu))\n            $(TR $(TD Glagolitic)  $(TD Miao)    $(TD Thaana))\n            $(TR $(TD Gothic)  $(TD Mongolian)   $(TD Thai))\n            $(TR $(TD Greek)   $(TD Myanmar) $(TD Tibetan))\n            $(TR $(TD Gujarati)    $(TD New_Tai_Lue) $(TD Tifinagh))\n            $(TR $(TD Gurmukhi)    $(TD Nko) $(TD Ugaritic))\n            $(TR $(TD Han) $(TD Ogham)   $(TD Vai))\n            $(TR $(TD Hangul)  $(TD Ol_Chiki)    $(TD Yi))\n    )\n    $(P Below is the table of names accepted by $(LREF unicode.hangulSyllableType).)\n        $(BOOKTABLE $(B Hangul syllable type),\n            $(TR $(TH Abb.) $(TH Long form))\n            $(TR $(TD L)   $(TD Leading_Jamo))\n            $(TR $(TD LV)  $(TD LV_Syllable))\n            $(TR $(TD LVT) $(TD LVT_Syllable) )\n            $(TR $(TD T)   $(TD Trailing_Jamo))\n            $(TR $(TD V)   $(TD Vowel_Jamo))\n    )\n    References:\n        $(HTTP www.digitalmars.com/d/ascii-table.html, ASCII Table),\n        $(HTTP en.wikipedia.org/wiki/Unicode, Wikipedia),\n        $(HTTP www.unicode.org, The Unicode Consortium),\n        $(HTTP www.unicode.org/reports/tr15/, Unicode normalization forms),\n        $(HTTP www.unicode.org/reports/tr29/, Unicode text segmentation)\n        $(HTTP www.unicode.org/uni2book/ch05.pdf,\n            Unicode Implementation Guidelines)\n        $(HTTP www.unicode.org/uni2book/ch03.pdf,\n            Unicode Conformance)\n    Trademarks:\n        Unicode(tm) is a trademark of Unicode, Inc.\n\n    Copyright: Copyright 2013 -\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   Dmitry Olshansky\n    Source:    $(PHOBOSSRC std/uni.d)\n    Standards: $(HTTP www.unicode.org/versions/Unicode6.2.0/, Unicode v6.2)\n\nMacros:\n\nSECTION = <h3><a id=\"$1\">$0</a></h3>\nDEF = <div><a id=\"$1\"><i>$0</i></a></div>\nS_LINK = <a href=\"#$1\">$+</a>\nCODEPOINT = $(S_LINK Code point, code point)\nCODEPOINTS = $(S_LINK Code point, code points)\nCHARACTER = $(S_LINK Character, character)\nCHARACTERS = $(S_LINK Character, characters)\nCLUSTER = $(S_LINK Grapheme cluster, grapheme cluster)\n+/\nmodule std.uni;\n\nimport std.meta; // AliasSeq\nimport std.range.primitives; // back, ElementEncodingType, ElementType, empty,\n    // front, isForwardRange, isInputRange, isRandomAccessRange, popFront, put,\n    // save\nimport std.traits; // isConvertibleToString, isIntegral, isSomeChar,\n    // isSomeString, Unqual\n// debug = std_uni;\n\ndebug(std_uni) import std.stdio; // writefln, writeln\n\nprivate:\n\nversion (unittest)\n{\nprivate:\n    struct TestAliasedString\n    {\n        string get() @safe @nogc pure nothrow { return _s; }\n        alias get this;\n        @disable this(this);\n        string _s;\n    }\n\n    bool testAliasedString(alias func, Args...)(string s, Args args)\n    {\n        import std.algorithm.comparison : equal;\n        auto a = func(TestAliasedString(s), args);\n        auto b = func(s, args);\n        static if (is(typeof(equal(a, b))))\n        {\n            // For ranges, compare contents instead of object identity.\n            return equal(a, b);\n        }\n        else\n        {\n            return a == b;\n        }\n    }\n}\n\nvoid copyBackwards(T,U)(T[] src, U[] dest)\n{\n    assert(src.length == dest.length);\n    for (size_t i=src.length; i-- > 0; )\n        dest[i] = src[i];\n}\n\nvoid copyForward(T,U)(T[] src, U[] dest)\n{\n    assert(src.length == dest.length);\n    for (size_t i=0; i<src.length; i++)\n        dest[i] = src[i];\n}\n\n// TODO: update to reflect all major CPUs supporting unaligned reads\nversion (X86)\n    enum hasUnalignedReads = true;\nelse version (X86_64)\n    enum hasUnalignedReads = true;\nelse\n    enum hasUnalignedReads = false; // better be safe then sorry\n\npublic enum dchar lineSep = '\\u2028'; /// Constant $(CODEPOINT) (0x2028) - line separator.\npublic enum dchar paraSep = '\\u2029'; /// Constant $(CODEPOINT) (0x2029) - paragraph separator.\npublic enum dchar nelSep  = '\\u0085'; /// Constant $(CODEPOINT) (0x0085) - next line.\n\n// test the intro example\n@safe unittest\n{\n    import std.algorithm.searching : find;\n    // initialize code point sets using script/block or property name\n    // set contains code points from both scripts.\n    auto set = unicode(\"Cyrillic\") | unicode(\"Armenian\");\n    // or simpler and statically-checked look\n    auto ascii = unicode.ASCII;\n    auto currency = unicode.Currency_Symbol;\n\n    // easy set ops\n    auto a = set & ascii;\n    assert(a.empty); // as it has no intersection with ascii\n    a = set | ascii;\n    auto b = currency - a; // subtract all ASCII, Cyrillic and Armenian\n\n    // some properties of code point sets\n    assert(b.length > 45); // 46 items in Unicode 6.1, even more in 6.2\n    // testing presence of a code point in a set\n    // is just fine, it is O(logN)\n    assert(!b['$']);\n    assert(!b['\\u058F']); // Armenian dram sign\n    assert(b['¥']);\n\n    // building fast lookup tables, these guarantee O(1) complexity\n    // 1-level Trie lookup table essentially a huge bit-set ~262Kb\n    auto oneTrie = toTrie!1(b);\n    // 2-level far more compact but typically slightly slower\n    auto twoTrie = toTrie!2(b);\n    // 3-level even smaller, and a bit slower yet\n    auto threeTrie = toTrie!3(b);\n    assert(oneTrie['£']);\n    assert(twoTrie['£']);\n    assert(threeTrie['£']);\n\n    // build the trie with the most sensible trie level\n    // and bind it as a functor\n    auto cyrillicOrArmenian = toDelegate(set);\n    auto balance = find!(cyrillicOrArmenian)(\"Hello ընկեր!\");\n    assert(balance == \"ընկեր!\");\n    // compatible with bool delegate(dchar)\n    bool delegate(dchar) bindIt = cyrillicOrArmenian;\n\n    // Normalization\n    string s = \"Plain ascii (and not only), is always normalized!\";\n    assert(s is normalize(s));// is the same string\n\n    string nonS = \"A\\u0308ffin\"; // A ligature\n    auto nS = normalize(nonS); // to NFC, the W3C endorsed standard\n    assert(nS == \"Äffin\");\n    assert(nS != nonS);\n    string composed = \"Äffin\";\n\n    assert(normalize!NFD(composed) == \"A\\u0308ffin\");\n    // to NFKD, compatibility decomposition useful for fuzzy matching/searching\n    assert(normalize!NFKD(\"2¹⁰\") == \"210\");\n}\n\nenum lastDchar = 0x10FFFF;\n\nauto force(T, F)(F from)\nif (isIntegral!T && !is(T == F))\n{\n    assert(from <= T.max && from >= T.min);\n    return cast(T) from;\n}\n\nauto force(T, F)(F from)\nif (isBitPacked!T && !is(T == F))\n{\n    assert(from <= 2^^bitSizeOf!T-1);\n    return T(cast(TypeOfBitPacked!T) from);\n}\n\nauto force(T, F)(F from)\nif (is(T == F))\n{\n    return from;\n}\n\n// repeat X times the bit-pattern in val assuming it's length is 'bits'\nsize_t replicateBits(size_t times, size_t bits)(size_t val) @safe pure nothrow @nogc\n{\n    static if (times == 1)\n        return val;\n    else static if (bits == 1)\n    {\n        static if (times == size_t.sizeof*8)\n            return val ? size_t.max : 0;\n        else\n            return val ? (1 << times)-1 : 0;\n    }\n    else static if (times % 2)\n        return (replicateBits!(times-1, bits)(val)<<bits) | val;\n    else\n        return replicateBits!(times/2, bits*2)((val << bits) | val);\n}\n\n@safe pure nothrow @nogc unittest // for replicate\n{\n    import std.algorithm.iteration : sum, map;\n    import std.range : iota;\n    size_t m = 0b111;\n    size_t m2 = 0b01;\n    static foreach (i; AliasSeq!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))\n    {\n        assert(replicateBits!(i, 3)(m)+1 == (1<<(3*i)));\n        assert(replicateBits!(i, 2)(m2) == iota(0, i).map!\"2^^(2*a)\"().sum());\n    }\n}\n\n// multiple arrays squashed into one memory block\nstruct MultiArray(Types...)\n{\n    import std.range.primitives : isOutputRange;\n    this(size_t[] sizes...) @safe pure nothrow\n    {\n        assert(dim == sizes.length);\n        size_t full_size;\n        foreach (i, v; Types)\n        {\n            full_size += spaceFor!(bitSizeOf!v)(sizes[i]);\n            sz[i] = sizes[i];\n            static if (i >= 1)\n                offsets[i] = offsets[i-1] +\n                    spaceFor!(bitSizeOf!(Types[i-1]))(sizes[i-1]);\n        }\n\n        storage = new size_t[full_size];\n    }\n\n    this(const(size_t)[] raw_offsets,\n        const(size_t)[] raw_sizes, const(size_t)[] data)const @safe pure nothrow @nogc\n    {\n        offsets[] = raw_offsets[];\n        sz[] = raw_sizes[];\n        storage = data;\n    }\n\n    @property auto slice(size_t n)()inout pure nothrow @nogc\n    {\n        auto ptr = raw_ptr!n;\n        return packedArrayView!(Types[n])(ptr, sz[n]);\n    }\n\n    @property auto ptr(size_t n)()inout pure nothrow @nogc\n    {\n        auto ptr = raw_ptr!n;\n        return inout(PackedPtr!(Types[n]))(ptr);\n    }\n\n    template length(size_t n)\n    {\n        @property size_t length()const @safe pure nothrow @nogc{ return sz[n]; }\n\n        @property void length(size_t new_size)\n        {\n            if (new_size > sz[n])\n            {// extend\n                size_t delta = (new_size - sz[n]);\n                sz[n] += delta;\n                delta = spaceFor!(bitSizeOf!(Types[n]))(delta);\n                storage.length +=  delta;// extend space at end\n                // raw_slice!x must follow resize as it could be moved!\n                // next stmts move all data past this array, last-one-goes-first\n                static if (n != dim-1)\n                {\n                    auto start = raw_ptr!(n+1);\n                    // len includes delta\n                    size_t len = (storage.ptr+storage.length-start);\n\n                    copyBackwards(start[0 .. len-delta], start[delta .. len]);\n\n                    start[0 .. delta] = 0;\n                    // offsets are used for raw_slice, ptr etc.\n                    foreach (i; n+1 .. dim)\n                        offsets[i] += delta;\n                }\n            }\n            else if (new_size < sz[n])\n            {// shrink\n                size_t delta = (sz[n] - new_size);\n                sz[n] -= delta;\n                delta = spaceFor!(bitSizeOf!(Types[n]))(delta);\n                // move all data past this array, forward direction\n                static if (n != dim-1)\n                {\n                    auto start = raw_ptr!(n+1);\n                    size_t len = (storage.ptr+storage.length-start);\n                    copyForward(start[0 .. len-delta], start[delta .. len]);\n\n                    // adjust offsets last, they affect raw_slice\n                    foreach (i; n+1 .. dim)\n                        offsets[i] -= delta;\n                }\n                storage.length -= delta;\n            }\n            // else - NOP\n        }\n    }\n\n    @property size_t bytes(size_t n=size_t.max)() const @safe\n    {\n        static if (n == size_t.max)\n            return storage.length*size_t.sizeof;\n        else static if (n != Types.length-1)\n            return (raw_ptr!(n+1)-raw_ptr!n)*size_t.sizeof;\n        else\n            return (storage.ptr+storage.length - raw_ptr!n)*size_t.sizeof;\n    }\n\n    void store(OutRange)(scope OutRange sink) const\n        if (isOutputRange!(OutRange, char))\n    {\n        import std.format : formattedWrite;\n        formattedWrite(sink, \"[%( 0x%x, %)]\", offsets[]);\n        formattedWrite(sink, \", [%( 0x%x, %)]\", sz[]);\n        formattedWrite(sink, \", [%( 0x%x, %)]\", storage);\n    }\n\nprivate:\n    import std.meta : staticMap;\n    @property auto raw_ptr(size_t n)()inout pure nothrow @nogc\n    {\n        static if (n == 0)\n            return storage.ptr;\n        else\n        {\n            return storage.ptr+offsets[n];\n        }\n    }\n    enum dim = Types.length;\n    size_t[dim] offsets;// offset for level x\n    size_t[dim] sz;// size of level x\n    alias bitWidth = staticMap!(bitSizeOf, Types);\n    size_t[] storage;\n}\n\n@system unittest\n{\n    import std.conv : text;\n    enum dg = (){\n        // sizes are:\n        // lvl0: 3, lvl1 : 2, lvl2: 1\n        auto m = MultiArray!(int, ubyte, int)(3,2,1);\n\n        static void check(size_t k, T)(ref T m, int n)\n        {\n            foreach (i; 0 .. n)\n                assert(m.slice!(k)[i] == i+1, text(\"level:\",i,\" : \",m.slice!(k)[0 .. n]));\n        }\n\n        static void checkB(size_t k, T)(ref T m, int n)\n        {\n            foreach (i; 0 .. n)\n                assert(m.slice!(k)[i] == n-i, text(\"level:\",i,\" : \",m.slice!(k)[0 .. n]));\n        }\n\n        static void fill(size_t k, T)(ref T m, int n)\n        {\n            foreach (i; 0 .. n)\n                m.slice!(k)[i] = force!ubyte(i+1);\n        }\n\n        static void fillB(size_t k, T)(ref T m, int n)\n        {\n            foreach (i; 0 .. n)\n                m.slice!(k)[i] = force!ubyte(n-i);\n        }\n\n        m.length!1 = 100;\n        fill!1(m, 100);\n        check!1(m, 100);\n\n        m.length!0 = 220;\n        fill!0(m, 220);\n        check!1(m, 100);\n        check!0(m, 220);\n\n        m.length!2 = 17;\n        fillB!2(m, 17);\n        checkB!2(m, 17);\n        check!0(m, 220);\n        check!1(m, 100);\n\n        m.length!2 = 33;\n        checkB!2(m, 17);\n        fillB!2(m, 33);\n        checkB!2(m, 33);\n        check!0(m, 220);\n        check!1(m, 100);\n\n        m.length!1 = 195;\n        fillB!1(m, 195);\n        checkB!1(m, 195);\n        checkB!2(m, 33);\n        check!0(m, 220);\n\n        auto marr = MultiArray!(BitPacked!(uint, 4), BitPacked!(uint, 6))(20, 10);\n        marr.length!0 = 15;\n        marr.length!1 = 30;\n        fill!1(marr, 30);\n        fill!0(marr, 15);\n        check!1(marr, 30);\n        check!0(marr, 15);\n        return 0;\n    };\n    enum ct = dg();\n    auto rt = dg();\n}\n\n@system unittest\n{// more bitpacking tests\n    import std.conv : text;\n\n    alias Bitty =\n      MultiArray!(BitPacked!(size_t, 3)\n                , BitPacked!(size_t, 4)\n                , BitPacked!(size_t, 3)\n                , BitPacked!(size_t, 6)\n                , bool);\n    alias fn1 = sliceBits!(13, 16);\n    alias fn2 = sliceBits!( 9, 13);\n    alias fn3 = sliceBits!( 6,  9);\n    alias fn4 = sliceBits!( 0,  6);\n    static void check(size_t lvl, MA)(ref MA arr){\n        for (size_t i = 0; i< arr.length!lvl; i++)\n            assert(arr.slice!(lvl)[i] == i, text(\"Mismatch on lvl \", lvl, \" idx \", i, \" value: \", arr.slice!(lvl)[i]));\n    }\n\n    static void fillIdx(size_t lvl, MA)(ref MA arr){\n        for (size_t i = 0; i< arr.length!lvl; i++)\n            arr.slice!(lvl)[i] = i;\n    }\n    Bitty m1;\n\n    m1.length!4 = 10;\n    m1.length!3 = 2^^6;\n    m1.length!2 = 2^^3;\n    m1.length!1 = 2^^4;\n    m1.length!0 = 2^^3;\n\n    m1.length!4 = 2^^16;\n\n    for (size_t i = 0; i< m1.length!4; i++)\n        m1.slice!(4)[i] = i % 2;\n\n    fillIdx!1(m1);\n    check!1(m1);\n    fillIdx!2(m1);\n    check!2(m1);\n    fillIdx!3(m1);\n    check!3(m1);\n    fillIdx!0(m1);\n    check!0(m1);\n    check!3(m1);\n    check!2(m1);\n    check!1(m1);\n    for (size_t i=0; i < 2^^16; i++)\n    {\n        m1.slice!(4)[i] = i % 2;\n        m1.slice!(0)[fn1(i)] = fn1(i);\n        m1.slice!(1)[fn2(i)] = fn2(i);\n        m1.slice!(2)[fn3(i)] = fn3(i);\n        m1.slice!(3)[fn4(i)] = fn4(i);\n    }\n    for (size_t i=0; i < 2^^16; i++)\n    {\n        assert(m1.slice!(4)[i] == i % 2);\n        assert(m1.slice!(0)[fn1(i)] == fn1(i));\n        assert(m1.slice!(1)[fn2(i)] == fn2(i));\n        assert(m1.slice!(2)[fn3(i)] == fn3(i));\n        assert(m1.slice!(3)[fn4(i)] == fn4(i));\n    }\n}\n\nsize_t spaceFor(size_t _bits)(size_t new_len) @safe pure nothrow @nogc\n{\n    import std.math : nextPow2;\n    enum bits = _bits == 1 ? 1 : nextPow2(_bits - 1);// see PackedArrayView\n    static if (bits > 8*size_t.sizeof)\n    {\n        static assert(bits % (size_t.sizeof*8) == 0);\n        return new_len * bits/(8*size_t.sizeof);\n    }\n    else\n    {\n        enum factor = size_t.sizeof*8/bits;\n        return (new_len+factor-1)/factor; // rounded up\n    }\n}\n\ntemplate isBitPackableType(T)\n{\n    enum isBitPackableType = isBitPacked!T\n        || isIntegral!T || is(T == bool) || isSomeChar!T;\n}\n\n//============================================================================\ntemplate PackedArrayView(T)\nif ((is(T dummy == BitPacked!(U, sz), U, size_t sz)\n    && isBitPackableType!U) || isBitPackableType!T)\n{\n    import std.math : nextPow2;\n    private enum bits = bitSizeOf!T;\n    alias PackedArrayView = PackedArrayViewImpl!(T, bits > 1 ? nextPow2(bits - 1) : 1);\n}\n\n//unsafe and fast access to a chunk of RAM as if it contains packed values\ntemplate PackedPtr(T)\nif ((is(T dummy == BitPacked!(U, sz), U, size_t sz)\n    && isBitPackableType!U) || isBitPackableType!T)\n{\n    import std.math : nextPow2;\n    private enum bits = bitSizeOf!T;\n    alias PackedPtr = PackedPtrImpl!(T, bits > 1 ? nextPow2(bits - 1) : 1);\n}\n\nstruct PackedPtrImpl(T, size_t bits)\n{\npure nothrow:\n    static assert(isPow2OrZero(bits));\n\n    this(inout(size_t)* ptr)inout @safe @nogc\n    {\n        origin = ptr;\n    }\n\n    private T simpleIndex(size_t n) inout\n    {\n        immutable q = n / factor;\n        immutable r = n % factor;\n        return cast(T)((origin[q] >> bits*r) & mask);\n    }\n\n    private void simpleWrite(TypeOfBitPacked!T val, size_t n)\n    in\n    {\n        static if (isIntegral!T)\n            assert(val <= mask);\n    }\n    do\n    {\n        immutable q = n / factor;\n        immutable r = n % factor;\n        immutable tgt_shift = bits*r;\n        immutable word = origin[q];\n        origin[q] = (word & ~(mask << tgt_shift))\n            | (cast(size_t) val << tgt_shift);\n    }\n\n    static if (factor == bytesPerWord// can safely pack by byte\n         || factor == 1 // a whole word at a time\n         || ((factor == bytesPerWord/2 || factor == bytesPerWord/4)\n                && hasUnalignedReads)) // this needs unaligned reads\n    {\n        static if (factor == bytesPerWord)\n            alias U = ubyte;\n        else static if (factor == bytesPerWord/2)\n            alias U = ushort;\n        else static if (factor == bytesPerWord/4)\n            alias U = uint;\n        else static if (size_t.sizeof == 8 && factor == bytesPerWord/8)\n            alias U = ulong;\n\n        T opIndex(size_t idx) inout\n        {\n            return __ctfe ? simpleIndex(idx) :\n                cast(inout(T))(cast(U*) origin)[idx];\n        }\n\n        static if (isBitPacked!T) // lack of user-defined implicit conversion\n        {\n            void opIndexAssign(T val, size_t idx)\n            {\n                return opIndexAssign(cast(TypeOfBitPacked!T) val, idx);\n            }\n        }\n\n        void opIndexAssign(TypeOfBitPacked!T val, size_t idx)\n        {\n            if (__ctfe)\n                simpleWrite(val, idx);\n            else\n                (cast(U*) origin)[idx] = cast(U) val;\n        }\n    }\n    else\n    {\n        T opIndex(size_t n) inout\n        {\n            return simpleIndex(n);\n        }\n\n        static if (isBitPacked!T) // lack of user-defined implicit conversion\n        {\n            void opIndexAssign(T val, size_t idx)\n            {\n                return opIndexAssign(cast(TypeOfBitPacked!T) val, idx);\n            }\n        }\n\n        void opIndexAssign(TypeOfBitPacked!T val, size_t n)\n        {\n            return simpleWrite(val, n);\n        }\n    }\n\nprivate:\n    // factor - number of elements in one machine word\n    enum factor = size_t.sizeof*8/bits, mask = 2^^bits-1;\n    enum bytesPerWord =  size_t.sizeof;\n    size_t* origin;\n}\n\n// data is packed only by power of two sized packs per word,\n// thus avoiding mul/div overhead at the cost of ultimate packing\n// this construct doesn't own memory, only provides access, see MultiArray for usage\nstruct PackedArrayViewImpl(T, size_t bits)\n{\npure nothrow:\n\n    this(inout(size_t)* origin, size_t offset, size_t items) inout @safe\n    {\n        ptr = inout(PackedPtr!(T))(origin);\n        ofs = offset;\n        limit = items;\n    }\n\n    bool zeros(size_t s, size_t e)\n    in\n    {\n        assert(s <= e);\n    }\n    do\n    {\n        s += ofs;\n        e += ofs;\n        immutable pad_s = roundUp(s);\n        if ( s >= e)\n        {\n            foreach (i; s .. e)\n                if (ptr[i])\n                    return false;\n            return true;\n        }\n        immutable pad_e = roundDown(e);\n        size_t i;\n        for (i=s; i<pad_s; i++)\n            if (ptr[i])\n                return false;\n        // all in between is x*factor elements\n        for (size_t j=i/factor; i<pad_e; i+=factor, j++)\n            if (ptr.origin[j])\n                return false;\n        for (; i<e; i++)\n            if (ptr[i])\n                return false;\n        return true;\n    }\n\n    T opIndex(size_t idx) inout\n    in\n    {\n        assert(idx < limit);\n    }\n    do\n    {\n        return ptr[ofs + idx];\n    }\n\n    static if (isBitPacked!T) // lack of user-defined implicit conversion\n    {\n        void opIndexAssign(T val, size_t idx)\n        {\n            return opIndexAssign(cast(TypeOfBitPacked!T) val, idx);\n        }\n    }\n\n    void opIndexAssign(TypeOfBitPacked!T val, size_t idx)\n    in\n    {\n        assert(idx < limit);\n    }\n    do\n    {\n        ptr[ofs + idx] = val;\n    }\n\n    static if (isBitPacked!T) // lack of user-defined implicit conversions\n    {\n        void opSliceAssign(T val, size_t start, size_t end)\n        {\n            opSliceAssign(cast(TypeOfBitPacked!T) val, start, end);\n        }\n    }\n\n    void opSliceAssign(TypeOfBitPacked!T val, size_t start, size_t end)\n    in\n    {\n        assert(start <= end);\n        assert(end <= limit);\n    }\n    do\n    {\n        // account for ofsetted view\n        start += ofs;\n        end += ofs;\n        // rounded to factor granularity\n        immutable pad_start = roundUp(start);// rounded up\n        if (pad_start >= end) //rounded up >= then end of slice\n        {\n            //nothing to gain, use per element assignment\n            foreach (i; start .. end)\n                ptr[i] = val;\n            return;\n        }\n        immutable pad_end = roundDown(end); // rounded down\n        size_t i;\n        for (i=start; i<pad_start; i++)\n            ptr[i] = val;\n        // all in between is x*factor elements\n        if (pad_start != pad_end)\n        {\n            immutable repval = replicateBits!(factor, bits)(val);\n            for (size_t j=i/factor; i<pad_end; i+=factor, j++)\n                ptr.origin[j] = repval;// so speed it up by factor\n        }\n        for (; i<end; i++)\n            ptr[i] = val;\n    }\n\n    auto opSlice(size_t from, size_t to)inout\n    in\n    {\n        assert(from <= to);\n        assert(ofs + to <= limit);\n    }\n    do\n    {\n        return typeof(this)(ptr.origin, ofs + from, to - from);\n    }\n\n    auto opSlice(){ return opSlice(0, length); }\n\n    bool opEquals(T)(auto ref T arr) const\n    {\n        if (limit != arr.limit)\n           return false;\n        size_t s1 = ofs, s2 = arr.ofs;\n        size_t e1 = s1 + limit, e2 = s2 + limit;\n        if (s1 % factor == 0 && s2 % factor == 0 && length % factor == 0)\n        {\n            return ptr.origin[s1/factor .. e1/factor]\n                == arr.ptr.origin[s2/factor .. e2/factor];\n        }\n        for (size_t i=0;i<limit; i++)\n            if (this[i] != arr[i])\n                return false;\n        return true;\n    }\n\n    @property size_t length()const{ return limit; }\n\nprivate:\n    auto roundUp()(size_t val){ return (val+factor-1)/factor*factor; }\n    auto roundDown()(size_t val){ return val/factor*factor; }\n    // factor - number of elements in one machine word\n    enum factor = size_t.sizeof*8/bits;\n    PackedPtr!(T) ptr;\n    size_t ofs, limit;\n}\n\n\nprivate struct SliceOverIndexed(T)\n{\n    enum assignableIndex = is(typeof((){ T.init[0] = Item.init; }));\n    enum assignableSlice = is(typeof((){ T.init[0 .. 0] = Item.init; }));\n    auto opIndex(size_t idx)const\n    in\n    {\n        assert(idx < to - from);\n    }\n    do\n    {\n        return (*arr)[from+idx];\n    }\n\n    static if (assignableIndex)\n    void opIndexAssign(Item val, size_t idx)\n    in\n    {\n        assert(idx < to - from);\n    }\n    do\n    {\n       (*arr)[from+idx] = val;\n    }\n\n    auto opSlice(size_t a, size_t b)\n    {\n        return typeof(this)(from+a, from+b, arr);\n    }\n\n    // static if (assignableSlice)\n    void opSliceAssign(T)(T val, size_t start, size_t end)\n    {\n        (*arr)[start+from .. end+from] = val;\n    }\n\n    auto opSlice()\n    {\n        return typeof(this)(from, to, arr);\n    }\n\n    @property size_t length()const { return to-from;}\n\n    auto opDollar()const { return length; }\n\n    @property bool empty()const { return from == to; }\n\n    @property auto front()const { return (*arr)[from]; }\n\n    static if (assignableIndex)\n    @property void front(Item val) { (*arr)[from] = val; }\n\n    @property auto back()const { return (*arr)[to-1]; }\n\n    static if (assignableIndex)\n    @property void back(Item val) { (*arr)[to-1] = val; }\n\n    @property auto save() inout { return this; }\n\n    void popFront() {   from++; }\n\n    void popBack() {    to--; }\n\n    bool opEquals(T)(auto ref T arr) const\n    {\n        if (arr.length != length)\n            return false;\n        for (size_t i=0; i <length; i++)\n            if (this[i] != arr[i])\n                return false;\n        return true;\n    }\nprivate:\n    alias Item = typeof(T.init[0]);\n    size_t from, to;\n    T* arr;\n}\n\nstatic assert(isRandomAccessRange!(SliceOverIndexed!(int[])));\n\nSliceOverIndexed!(const(T)) sliceOverIndexed(T)(size_t a, size_t b, const(T)* x)\nif (is(Unqual!T == T))\n{\n    return SliceOverIndexed!(const(T))(a, b, x);\n}\n\n// BUG? inout is out of reach\n//...SliceOverIndexed.arr only parameters or stack based variables can be inout\nSliceOverIndexed!T sliceOverIndexed(T)(size_t a, size_t b, T* x)\nif (is(Unqual!T == T))\n{\n    return SliceOverIndexed!T(a, b, x);\n}\n\n@system unittest\n{\n    int[] idxArray = [2, 3, 5, 8, 13];\n    auto sliced = sliceOverIndexed(0, idxArray.length, &idxArray);\n\n    assert(!sliced.empty);\n    assert(sliced.front == 2);\n    sliced.front = 1;\n    assert(sliced.front == 1);\n    assert(sliced.back == 13);\n    sliced.popFront();\n    assert(sliced.front == 3);\n    assert(sliced.back == 13);\n    sliced.back = 11;\n    assert(sliced.back == 11);\n    sliced.popBack();\n\n    assert(sliced.front == 3);\n    assert(sliced[$-1] == 8);\n    sliced = sliced[];\n    assert(sliced[0] == 3);\n    assert(sliced.back == 8);\n    sliced = sliced[1..$];\n    assert(sliced.front == 5);\n    sliced = sliced[0..$-1];\n    assert(sliced[$-1] == 5);\n\n    int[] other = [2, 5];\n    assert(sliced[] == sliceOverIndexed(1, 2, &other));\n    sliceOverIndexed(0, 2, &idxArray)[0 .. 2] = -1;\n    assert(idxArray[0 .. 2] == [-1, -1]);\n    uint[] nullArr = null;\n    auto nullSlice = sliceOverIndexed(0, 0, &idxArray);\n    assert(nullSlice.empty);\n}\n\nprivate inout(PackedArrayView!T) packedArrayView(T)(inout(size_t)* ptr, size_t items)\n{\n    return inout(PackedArrayView!T)(ptr, 0, items);\n}\n\n\n//============================================================================\n// Partially unrolled binary search using Shar's method\n//============================================================================\n\nstring genUnrolledSwitchSearch(size_t size) @safe pure nothrow\n{\n    import core.bitop : bsr;\n    import std.array : replace;\n    import std.conv : to;\n    assert(isPow2OrZero(size));\n    string code = `\n    import core.bitop : bsr;\n    auto power = bsr(m)+1;\n    switch (power){`;\n    size_t i = bsr(size);\n    foreach_reverse (val; 0 .. bsr(size))\n    {\n        auto v = 2^^val;\n        code ~= `\n        case pow:\n            if (pred(range[idx+m], needle))\n                idx +=  m;\n            goto case;\n        `.replace(\"m\", to!string(v))\n        .replace(\"pow\", to!string(i));\n        i--;\n    }\n    code ~= `\n        case 0:\n            if (pred(range[idx], needle))\n                idx += 1;\n            goto default;\n        `;\n    code ~= `\n        default:\n    }`;\n    return code;\n}\n\nbool isPow2OrZero(size_t sz) @safe pure nothrow @nogc\n{\n    // See also: std.math.isPowerOf2()\n    return (sz & (sz-1)) == 0;\n}\n\nsize_t uniformLowerBound(alias pred, Range, T)(Range range, T needle)\nif (is(T : ElementType!Range))\n{\n    assert(isPow2OrZero(range.length));\n    size_t idx = 0, m = range.length/2;\n    while (m != 0)\n    {\n        if (pred(range[idx+m], needle))\n            idx += m;\n        m /= 2;\n    }\n    if (pred(range[idx], needle))\n        idx += 1;\n    return idx;\n}\n\nsize_t switchUniformLowerBound(alias pred, Range, T)(Range range, T needle)\nif (is(T : ElementType!Range))\n{\n    assert(isPow2OrZero(range.length));\n    size_t idx = 0, m = range.length/2;\n    enum max = 1 << 10;\n    while (m >= max)\n    {\n        if (pred(range[idx+m], needle))\n            idx += m;\n        m /= 2;\n    }\n    mixin(genUnrolledSwitchSearch(max));\n    return idx;\n}\n\ntemplate sharMethod(alias uniLowerBound)\n{\n    size_t sharMethod(alias _pred=\"a<b\", Range, T)(Range range, T needle)\n        if (is(T : ElementType!Range))\n    {\n        import std.functional : binaryFun;\n        import std.math : nextPow2, truncPow2;\n        alias pred = binaryFun!_pred;\n        if (range.length == 0)\n            return 0;\n        if (isPow2OrZero(range.length))\n            return uniLowerBound!pred(range, needle);\n        size_t n = truncPow2(range.length);\n        if (pred(range[n-1], needle))\n        {// search in another 2^^k area that fully covers the tail of range\n            size_t k = nextPow2(range.length - n + 1);\n            return range.length - k + uniLowerBound!pred(range[$-k..$], needle);\n        }\n        else\n            return uniLowerBound!pred(range[0 .. n], needle);\n    }\n}\n\nalias sharLowerBound = sharMethod!uniformLowerBound;\nalias sharSwitchLowerBound = sharMethod!switchUniformLowerBound;\n\n@safe unittest\n{\n    import std.array : array;\n    import std.range : assumeSorted, iota;\n\n    auto stdLowerBound(T)(T[] range, T needle)\n    {\n        return assumeSorted(range).lowerBound(needle).length;\n    }\n    immutable MAX = 5*1173;\n    auto arr = array(iota(5, MAX, 5));\n    assert(arr.length == MAX/5-1);\n    foreach (i; 0 .. MAX+5)\n    {\n        auto st = stdLowerBound(arr, i);\n        assert(st == sharLowerBound(arr, i));\n        assert(st == sharSwitchLowerBound(arr, i));\n    }\n    arr = [];\n    auto st = stdLowerBound(arr, 33);\n    assert(st == sharLowerBound(arr, 33));\n    assert(st == sharSwitchLowerBound(arr, 33));\n}\n//============================================================================\n\n@safe\n{\n// hope to see simillar stuff in public interface... once Allocators are out\n//@@@BUG moveFront and friends? dunno, for now it's POD-only\n\n@trusted size_t genericReplace(Policy=void, T, Range)\n    (ref T dest, size_t from, size_t to, Range stuff)\n{\n    import std.algorithm.mutation : copy;\n    size_t delta = to - from;\n    size_t stuff_end = from+stuff.length;\n    if (stuff.length > delta)\n    {// replace increases length\n        delta = stuff.length - delta;// now, new is > old  by delta\n        static if (is(Policy == void))\n            dest.length = dest.length+delta;//@@@BUG lame @property\n        else\n            dest = Policy.realloc(dest, dest.length+delta);\n        copyBackwards(dest[to .. dest.length-delta],\n            dest[to+delta .. dest.length]);\n        copyForward(stuff, dest[from .. stuff_end]);\n    }\n    else if (stuff.length == delta)\n    {\n        copy(stuff, dest[from .. to]);\n    }\n    else\n    {// replace decreases length by delta\n        delta = delta - stuff.length;\n        copy(stuff, dest[from .. stuff_end]);\n        copyForward(dest[to .. dest.length],\n            dest[stuff_end .. dest.length-delta]);\n        static if (is(Policy == void))\n            dest.length = dest.length - delta;//@@@BUG lame @property\n        else\n            dest = Policy.realloc(dest, dest.length-delta);\n    }\n    return stuff_end;\n}\n\n\n// Simple storage manipulation policy\n@safe private struct GcPolicy\n{\n    import std.traits : isDynamicArray;\n\n    static T[] dup(T)(const T[] arr)\n    {\n        return arr.dup;\n    }\n\n    static T[] alloc(T)(size_t size)\n    {\n        return new T[size];\n    }\n\n    static T[] realloc(T)(T[] arr, size_t sz)\n    {\n        arr.length = sz;\n        return arr;\n    }\n\n    static void replaceImpl(T, Range)(ref T[] dest, size_t from, size_t to, Range stuff)\n    {\n        replaceInPlace(dest, from, to, stuff);\n    }\n\n    static void append(T, V)(ref T[] arr, V value)\n        if (!isInputRange!V)\n    {\n        arr ~= force!T(value);\n    }\n\n    static void append(T, V)(ref T[] arr, V value)\n        if (isInputRange!V)\n    {\n        insertInPlace(arr, arr.length, value);\n    }\n\n    static void destroy(T)(ref T arr) pure // pure required for -dip25, inferred for -dip1000\n        if (isDynamicArray!T && is(Unqual!T == T))\n    {\n        debug\n        {\n            arr[] = cast(typeof(T.init[0]))(0xdead_beef);\n        }\n        arr = null;\n    }\n\n    static void destroy(T)(ref T arr) pure // pure required for -dip25, inferred for -dip1000\n        if (isDynamicArray!T && !is(Unqual!T == T))\n    {\n        arr = null;\n    }\n}\n\n// ditto\n@safe struct ReallocPolicy\n{\n    import std.range.primitives : hasLength;\n\n    static T[] dup(T)(const T[] arr)\n    {\n        auto result = alloc!T(arr.length);\n        result[] = arr[];\n        return result;\n    }\n\n    static T[] alloc(T)(size_t size) @trusted\n    {\n        import core.memory : pureMalloc;\n        import std.exception : enforce;\n\n        import core.checkedint : mulu;\n        bool overflow;\n        size_t nbytes = mulu(size, T.sizeof, overflow);\n        if (overflow) assert(0);\n\n        auto ptr = cast(T*) enforce(pureMalloc(nbytes), \"out of memory on C heap\");\n        return ptr[0 .. size];\n    }\n\n    static T[] realloc(T)(scope T[] arr, size_t size) @trusted\n    {\n        import core.memory : pureRealloc;\n        import std.exception : enforce;\n        if (!size)\n        {\n            destroy(arr);\n            return null;\n        }\n\n        import core.checkedint : mulu;\n        bool overflow;\n        size_t nbytes = mulu(size, T.sizeof, overflow);\n        if (overflow) assert(0);\n\n        auto ptr = cast(T*) enforce(pureRealloc(arr.ptr, nbytes), \"out of memory on C heap\");\n        return ptr[0 .. size];\n    }\n\n    static void replaceImpl(T, Range)(ref T[] dest, size_t from, size_t to, Range stuff)\n    {\n        genericReplace!(ReallocPolicy)(dest, from, to, stuff);\n    }\n\n    static void append(T, V)(ref T[] arr, V value)\n        if (!isInputRange!V)\n    {\n        if (arr.length == size_t.max) assert(0);\n        arr = realloc(arr, arr.length+1);\n        arr[$-1] = force!T(value);\n    }\n\n    pure @safe unittest\n    {\n        int[] arr;\n        ReallocPolicy.append(arr, 3);\n\n        import std.algorithm.comparison : equal;\n        assert(equal(arr, [3]));\n    }\n\n    static void append(T, V)(ref T[] arr, V value)\n        if (isInputRange!V && hasLength!V)\n    {\n        import core.checkedint : addu;\n        bool overflow;\n        size_t nelems = addu(arr.length, value.length, overflow);\n        if (overflow) assert(0);\n\n        arr = realloc(arr, nelems);\n\n        import std.algorithm.mutation : copy;\n        copy(value, arr[$-value.length..$]);\n    }\n\n    pure @safe unittest\n    {\n        int[] arr;\n        ReallocPolicy.append(arr, [1,2,3]);\n\n        import std.algorithm.comparison : equal;\n        assert(equal(arr, [1,2,3]));\n    }\n\n    static void destroy(T)(scope ref T[] arr) @trusted\n    {\n        import core.memory : pureFree;\n        if (arr.ptr)\n            pureFree(arr.ptr);\n        arr = null;\n    }\n}\n\n//build hack\nalias _RealArray = CowArray!ReallocPolicy;\n\npure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n\n    with(ReallocPolicy)\n    {\n        bool test(T, U, V)(T orig, size_t from, size_t to, U toReplace, V result,\n                   string file = __FILE__, size_t line = __LINE__)\n        {\n            {\n                replaceImpl(orig, from, to, toReplace);\n                scope(exit) destroy(orig);\n                if (!equal(orig, result))\n                    return false;\n            }\n            return true;\n        }\n        static T[] arr(T)(T[] args... )\n        {\n            return dup(args);\n        }\n\n        assert(test(arr([1, 2, 3, 4]), 0, 0, [5, 6, 7], [5, 6, 7, 1, 2, 3, 4]));\n        assert(test(arr([1, 2, 3, 4]), 0, 2, cast(int[])[], [3, 4]));\n        assert(test(arr([1, 2, 3, 4]), 0, 4, [5, 6, 7], [5, 6, 7]));\n        assert(test(arr([1, 2, 3, 4]), 0, 2, [5, 6, 7], [5, 6, 7, 3, 4]));\n        assert(test(arr([1, 2, 3, 4]), 2, 3, [5, 6, 7], [1, 2, 5, 6, 7, 4]));\n    }\n}\n\n/**\n    Tests if T is some kind a set of code points. Intended for template constraints.\n*/\npublic template isCodepointSet(T)\n{\n    static if (is(T dummy == InversionList!(Args), Args...))\n        enum isCodepointSet = true;\n    else\n        enum isCodepointSet = false;\n}\n\n/**\n    Tests if `T` is a pair of integers that implicitly convert to `V`.\n    The following code must compile for any pair `T`:\n    ---\n    (T x){ V a = x[0]; V b = x[1];}\n    ---\n    The following must not compile:\n     ---\n    (T x){ V c = x[2];}\n    ---\n*/\npublic template isIntegralPair(T, V=uint)\n{\n    enum isIntegralPair = is(typeof((T x){ V a = x[0]; V b = x[1];}))\n        && !is(typeof((T x){ V c = x[2]; }));\n}\n\n\n/**\n    The recommended default type for set of $(CODEPOINTS).\n    For details, see the current implementation: $(LREF InversionList).\n*/\npublic alias CodepointSet = InversionList!GcPolicy;\n\n\n//@@@BUG: std.typecons tuples depend on std.format to produce fields mixin\n// which relies on std.uni.isGraphical and this chain blows up with Forward reference error\n// hence below doesn't seem to work\n// public alias CodepointInterval = Tuple!(uint, \"a\", uint, \"b\");\n\n/**\n    The recommended type of $(REF Tuple, std,_typecons)\n    to represent [a, b$(RPAREN) intervals of $(CODEPOINTS). As used in $(LREF InversionList).\n    Any interval type should pass $(LREF isIntegralPair) trait.\n*/\npublic struct CodepointInterval\n{\npure:\n    uint[2] _tuple;\n    alias _tuple this;\n\n@safe pure nothrow @nogc:\n\n    this(uint low, uint high)\n    {\n        _tuple[0] = low;\n        _tuple[1] = high;\n    }\n    bool opEquals(T)(T val) const\n    {\n        return this[0] == val[0] && this[1] == val[1];\n    }\n    @property ref inout(uint) a() inout { return _tuple[0]; }\n    @property ref inout(uint) b() inout { return _tuple[1]; }\n}\n\n/**\n    $(P\n    `InversionList` is a set of $(CODEPOINTS)\n    represented as an array of open-right [a, b$(RPAREN)\n    intervals (see $(LREF CodepointInterval) above).\n    The name comes from the way the representation reads left to right.\n    For instance a set of all values [10, 50$(RPAREN), [80, 90$(RPAREN),\n    plus a singular value 60 looks like this:\n    )\n    ---\n    10, 50, 60, 61, 80, 90\n    ---\n    $(P\n    The way to read this is: start with negative meaning that all numbers\n    smaller then the next one are not present in this set (and positive\n    - the contrary). Then switch positive/negative after each\n    number passed from left to right.\n    )\n    $(P This way negative spans until 10, then positive until 50,\n    then negative until 60, then positive until 61, and so on.\n    As seen this provides a space-efficient storage of highly redundant data\n    that comes in long runs. A description which Unicode $(CHARACTER)\n    properties fit nicely. The technique itself could be seen as a variation\n    on $(LINK2 https://en.wikipedia.org/wiki/Run-length_encoding, RLE encoding).\n    )\n\n    $(P Sets are value types (just like `int` is) thus they\n        are never aliased.\n    )\n        Example:\n        ---\n        auto a = CodepointSet('a', 'z'+1);\n        auto b = CodepointSet('A', 'Z'+1);\n        auto c = a;\n        a = a | b;\n        assert(a == CodepointSet('A', 'Z'+1, 'a', 'z'+1));\n        assert(a != c);\n        ---\n    $(P See also $(LREF unicode) for simpler construction of sets\n        from predefined ones.\n    )\n\n    $(P Memory usage is 8 bytes per each contiguous interval in a set.\n    The value semantics are achieved by using the\n    $(HTTP en.wikipedia.org/wiki/Copy-on-write, COW) technique\n    and thus it's $(RED not) safe to cast this type to $(D_KEYWORD shared).\n    )\n\n    Note:\n    $(P It's not recommended to rely on the template parameters\n    or the exact type of a current $(CODEPOINT) set in `std.uni`.\n    The type and parameters may change when the standard\n    allocators design is finalized.\n    Use $(LREF isCodepointSet) with templates or just stick with the default\n    alias $(LREF CodepointSet) throughout the whole code base.\n    )\n*/\npublic struct InversionList(SP=GcPolicy)\n{\n    import std.range : assumeSorted;\n\n    /**\n        Construct from another code point set of any type.\n    */\n    this(Set)(Set set) pure\n        if (isCodepointSet!Set)\n    {\n        uint[] arr;\n        foreach (v; set.byInterval)\n        {\n            arr ~= v.a;\n            arr ~= v.b;\n        }\n        data = CowArray!(SP).reuse(arr);\n    }\n\n    /**\n        Construct a set from a forward range of code point intervals.\n    */\n    this(Range)(Range intervals) pure\n        if (isForwardRange!Range && isIntegralPair!(ElementType!Range))\n    {\n        uint[] arr;\n        foreach (v; intervals)\n        {\n            SP.append(arr, v.a);\n            SP.append(arr, v.b);\n        }\n        data = CowArray!(SP).reuse(arr);\n        sanitize(); //enforce invariant: sort intervals etc.\n    }\n\n    //helper function that avoids sanity check to be CTFE-friendly\n    private static fromIntervals(Range)(Range intervals) pure\n    {\n        import std.algorithm.iteration : map;\n        import std.range : roundRobin;\n        auto flattened = roundRobin(intervals.save.map!\"a[0]\"(),\n            intervals.save.map!\"a[1]\"());\n        InversionList set;\n        set.data = CowArray!(SP)(flattened);\n        return set;\n    }\n    //ditto untill sort is CTFE-able\n    private static fromIntervals()(uint[] intervals...) pure\n    in\n    {\n        import std.conv : text;\n        assert(intervals.length % 2 == 0, \"Odd number of interval bounds [a, b)!\");\n        for (uint i = 0; i < intervals.length; i += 2)\n        {\n            auto a = intervals[i], b = intervals[i+1];\n            assert(a < b, text(\"illegal interval [a, b): \", a, \" > \", b));\n        }\n    }\n    do\n    {\n        InversionList set;\n        set.data = CowArray!(SP)(intervals);\n        return set;\n    }\n\n    /**\n        Construct a set from plain values of code point intervals.\n    */\n    this()(uint[] intervals...)\n    in\n    {\n        import std.conv : text;\n        assert(intervals.length % 2 == 0, \"Odd number of interval bounds [a, b)!\");\n        for (uint i = 0; i < intervals.length; i += 2)\n        {\n            auto a = intervals[i], b = intervals[i+1];\n            assert(a < b, text(\"illegal interval [a, b): \", a, \" > \", b));\n        }\n    }\n    do\n    {\n        data = CowArray!(SP)(intervals);\n        sanitize(); //enforce invariant: sort intervals etc.\n    }\n\n    ///\n    pure @safe unittest\n    {\n        import std.algorithm.comparison : equal;\n\n        auto set = CodepointSet('a', 'z'+1, 'а', 'я'+1);\n        foreach (v; 'a'..'z'+1)\n            assert(set[v]);\n        // Cyrillic lowercase interval\n        foreach (v; 'а'..'я'+1)\n            assert(set[v]);\n        //specific order is not required, intervals may interesect\n        auto set2 = CodepointSet('а', 'я'+1, 'a', 'd', 'b', 'z'+1);\n        //the same end result\n        assert(set2.byInterval.equal(set.byInterval));\n        // test constructor this(Range)(Range intervals)\n        auto chessPiecesWhite = CodepointInterval(9812, 9818);\n        auto chessPiecesBlack = CodepointInterval(9818, 9824);\n        auto set3 = CodepointSet([chessPiecesWhite, chessPiecesBlack]);\n        foreach (v; '♔'..'♟'+1)\n            assert(set3[v]);\n    }\n\n    /**\n        Get range that spans all of the $(CODEPOINT) intervals in this $(LREF InversionList).\n    */\n    @property auto byInterval() scope\n    {\n        // TODO: change this to data[] once the -dip1000 errors have been fixed\n        // see e.g. https://github.com/dlang/phobos/pull/6638\n        import std.array : array;\n        return Intervals!(typeof(data.array))(data.array);\n    }\n\n    @safe unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.typecons : tuple;\n\n        auto set = CodepointSet('A', 'D'+1, 'a', 'd'+1);\n\n        assert(set.byInterval.equal([tuple('A','E'), tuple('a','e')]));\n    }\n\n    package @property const(CodepointInterval)[] intervals() const\n    {\n        import std.array : array;\n        return Intervals!(typeof(data[]))(data[]).array;\n    }\n\n    /**\n        Tests the presence of code point `val` in this set.\n    */\n    bool opIndex(uint val) const\n    {\n        // the <= ensures that searching in  interval of [a, b) for 'a' you get .length == 1\n        // return assumeSorted!((a,b) => a <= b)(data[]).lowerBound(val).length & 1;\n        return sharSwitchLowerBound!\"a <= b\"(data[], val) & 1;\n    }\n\n    ///\n    pure @safe unittest\n    {\n        auto gothic = unicode.Gothic;\n        // Gothic letter ahsa\n        assert(gothic['\\U00010330']);\n        // no ascii in Gothic obviously\n        assert(!gothic['$']);\n    }\n\n\n    // Linear scan for `ch`. Useful only for small sets.\n    // TODO:\n    // used internally in std.regex\n    // should be properly exposed in a public API ?\n    package auto scanFor()(dchar ch) const\n    {\n        immutable len = data.length;\n        for (size_t i = 0; i < len; i++)\n            if (ch < data[i])\n                return i & 1;\n        return 0;\n    }\n\n    /// Number of $(CODEPOINTS) in this set\n    @property size_t length()\n    {\n        size_t sum = 0;\n        foreach (iv; byInterval)\n        {\n            sum += iv.b - iv.a;\n        }\n        return sum;\n    }\n\n// bootstrap full set operations from 4 primitives (suitable as a template mixin):\n// addInterval, skipUpTo, dropUpTo & byInterval iteration\n//============================================================================\npublic:\n    /**\n        $(P Sets support natural syntax for set algebra, namely: )\n        $(BOOKTABLE ,\n            $(TR $(TH Operator) $(TH Math notation) $(TH Description) )\n            $(TR $(TD &) $(TD a ∩ b) $(TD intersection) )\n            $(TR $(TD |) $(TD a ∪ b) $(TD union) )\n            $(TR $(TD -) $(TD a ∖ b) $(TD subtraction) )\n            $(TR $(TD ~) $(TD a ~ b) $(TD symmetric set difference i.e. (a ∪ b) \\ (a ∩ b)) )\n        )\n    */\n    This opBinary(string op, U)(U rhs)\n        if (isCodepointSet!U || is(U:dchar))\n    {\n        static if (op == \"&\" || op == \"|\" || op == \"~\")\n        {// symmetric ops thus can swap arguments to reuse r-value\n            static if (is(U:dchar))\n            {\n                auto tmp = this;\n                mixin(\"tmp \"~op~\"= rhs; \");\n                return tmp;\n            }\n            else\n            {\n                static if (is(Unqual!U == U))\n                {\n                    // try hard to reuse r-value\n                    mixin(\"rhs \"~op~\"= this;\");\n                    return rhs;\n                }\n                else\n                {\n                    auto tmp = this;\n                    mixin(\"tmp \"~op~\"= rhs;\");\n                    return tmp;\n                }\n            }\n        }\n        else static if (op == \"-\") // anti-symmetric\n        {\n            auto tmp = this;\n            tmp -= rhs;\n            return tmp;\n        }\n        else\n            static assert(0, \"no operator \"~op~\" defined for Set\");\n    }\n\n    ///\n    pure @safe unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.range : iota;\n\n        auto lower = unicode.LowerCase;\n        auto upper = unicode.UpperCase;\n        auto ascii = unicode.ASCII;\n\n        assert((lower & upper).empty); // no intersection\n        auto lowerASCII = lower & ascii;\n        assert(lowerASCII.byCodepoint.equal(iota('a', 'z'+1)));\n        // throw away all of the lowercase ASCII\n        assert((ascii - lower).length == 128 - 26);\n\n        auto onlyOneOf = lower ~ ascii;\n        assert(!onlyOneOf['Δ']); // not ASCII and not lowercase\n        assert(onlyOneOf['$']); // ASCII and not lowercase\n        assert(!onlyOneOf['a']); // ASCII and lowercase\n        assert(onlyOneOf['я']); // not ASCII but lowercase\n\n        // throw away all cased letters from ASCII\n        auto noLetters = ascii - (lower | upper);\n        assert(noLetters.length == 128 - 26*2);\n    }\n\n    /// The 'op=' versions of the above overloaded operators.\n    ref This opOpAssign(string op, U)(U rhs)\n        if (isCodepointSet!U || is(U:dchar))\n    {\n        static if (op == \"|\")    // union\n        {\n            static if (is(U:dchar))\n            {\n                this.addInterval(rhs, rhs+1);\n                return this;\n            }\n            else\n                return this.add(rhs);\n        }\n        else static if (op == \"&\")   // intersection\n                return this.intersect(rhs);// overloaded\n        else static if (op == \"-\")   // set difference\n                return this.sub(rhs);// overloaded\n        else static if (op == \"~\")   // symmetric set difference\n        {\n            auto copy = this & rhs;\n            this |= rhs;\n            this -= copy;\n            return this;\n        }\n        else\n            static assert(0, \"no operator \"~op~\" defined for Set\");\n    }\n\n    /**\n        Tests the presence of codepoint `ch` in this set,\n        the same as $(LREF opIndex).\n    */\n    bool opBinaryRight(string op: \"in\", U)(U ch) const\n        if (is(U : dchar))\n    {\n        return this[ch];\n    }\n\n    ///\n    pure @safe unittest\n    {\n        assert('я' in unicode.Cyrillic);\n        assert(!('z' in unicode.Cyrillic));\n    }\n\n\n\n    /**\n     * Obtains a set that is the inversion of this set.\n     *\n     * See_Also: $(LREF inverted)\n     */\n    auto opUnary(string op: \"!\")()\n    {\n        return this.inverted;\n    }\n\n    /**\n        A range that spans each $(CODEPOINT) in this set.\n    */\n    @property auto byCodepoint()\n    {\n        static struct CodepointRange\n        {\n            this(This set)\n            {\n                r = set.byInterval;\n                if (!r.empty)\n                    cur = r.front.a;\n            }\n\n            @property dchar front() const\n            {\n                return cast(dchar) cur;\n            }\n\n            @property bool empty() const\n            {\n                return r.empty;\n            }\n\n            void popFront()\n            {\n                cur++;\n                while (cur >= r.front.b)\n                {\n                    r.popFront();\n                    if (r.empty)\n                        break;\n                    cur = r.front.a;\n                }\n            }\n        private:\n            uint cur;\n            typeof(This.init.byInterval) r;\n        }\n\n        return CodepointRange(this);\n    }\n\n    ///\n    pure @safe unittest\n    {\n        import std.algorithm.comparison : equal;\n        import std.range : iota;\n\n        auto set = unicode.ASCII;\n        set.byCodepoint.equal(iota(0, 0x80));\n    }\n\n    /**\n        $(P Obtain textual representation of this set in from of\n        open-right intervals and feed it to `sink`.\n        )\n        $(P Used by various standard formatting facilities such as\n         $(REF formattedWrite, std,format), $(REF write, std,stdio),\n         $(REF writef, std,stdio), $(REF to, std,conv) and others.\n        )\n        Example:\n        ---\n        import std.conv;\n        assert(unicode.ASCII.to!string == \"[0..128$(RPAREN)\");\n        ---\n    */\n\n    private import std.format : FormatSpec;\n\n    /***************************************\n     * Obtain a textual representation of this InversionList\n     * in form of open-right intervals.\n     *\n     * The formatting flag is applied individually to each value, for example:\n     * $(LI $(B %s) and $(B %d) format the intervals as a [low .. high$(RPAREN) range of integrals)\n     * $(LI $(B %x) formats the intervals as a [low .. high$(RPAREN) range of lowercase hex characters)\n     * $(LI $(B %X) formats the intervals as a [low .. high$(RPAREN) range of uppercase hex characters)\n     */\n    void toString(Writer)(scope Writer sink, const ref FormatSpec!char fmt) /* const */\n    {\n        import std.format : formatValue;\n        auto range = byInterval;\n        if (range.empty)\n            return;\n\n        while (1)\n        {\n            auto i = range.front;\n            range.popFront();\n\n            put(sink, \"[\");\n            formatValue(sink, i.a, fmt);\n            put(sink, \"..\");\n            formatValue(sink, i.b, fmt);\n            put(sink, \")\");\n            if (range.empty) return;\n            put(sink, \" \");\n        }\n    }\n\n    ///\n    pure @safe unittest\n    {\n        import std.conv : to;\n        import std.format : format;\n        import std.uni : unicode;\n\n        assert(unicode.Cyrillic.to!string ==\n            \"[1024..1157) [1159..1320) [7467..7468) [7544..7545) [11744..11776) [42560..42648) [42655..42656)\");\n\n        // The specs '%s' and '%d' are equivalent to the to!string call above.\n        assert(format(\"%d\", unicode.Cyrillic) == unicode.Cyrillic.to!string);\n\n        assert(format(\"%#x\", unicode.Cyrillic) ==\n            \"[0x400..0x485) [0x487..0x528) [0x1d2b..0x1d2c) [0x1d78..0x1d79) [0x2de0..0x2e00) \"\n            ~\"[0xa640..0xa698) [0xa69f..0xa6a0)\");\n\n        assert(format(\"%#X\", unicode.Cyrillic) ==\n            \"[0X400..0X485) [0X487..0X528) [0X1D2B..0X1D2C) [0X1D78..0X1D79) [0X2DE0..0X2E00) \"\n            ~\"[0XA640..0XA698) [0XA69F..0XA6A0)\");\n    }\n\n    pure @safe unittest\n    {\n        import std.exception : assertThrown;\n        import std.format : format, FormatException;\n        assertThrown!FormatException(format(\"%a\", unicode.ASCII));\n    }\n\n\n    /**\n        Add an interval [a, b$(RPAREN) to this set.\n    */\n    ref add()(uint a, uint b)\n    {\n        addInterval(a, b);\n        return this;\n    }\n\n    ///\n    pure @safe unittest\n    {\n        CodepointSet someSet;\n        someSet.add('0', '5').add('A','Z'+1);\n        someSet.add('5', '9'+1);\n        assert(someSet['0']);\n        assert(someSet['5']);\n        assert(someSet['9']);\n        assert(someSet['Z']);\n    }\n\nprivate:\n\n  package(std)  // used from: std.regex.internal.parser\n    ref intersect(U)(U rhs)\n        if (isCodepointSet!U)\n    {\n        Marker mark;\n        foreach ( i; rhs.byInterval)\n        {\n            mark = this.dropUpTo(i.a, mark);\n            mark = this.skipUpTo(i.b, mark);\n        }\n        this.dropUpTo(uint.max, mark);\n        return this;\n    }\n\n    ref intersect()(dchar ch)\n    {\n        foreach (i; byInterval)\n            if (i.a <= ch && ch < i.b)\n                return this = This.init.add(ch, ch+1);\n        this = This.init;\n        return this;\n    }\n\n    pure @safe unittest\n    {\n        assert(unicode.Cyrillic.intersect('-').byInterval.empty);\n    }\n\n    ref sub()(dchar ch)\n    {\n        return subChar(ch);\n    }\n\n    // same as the above except that skip & drop parts are swapped\n  package(std)  // used from: std.regex.internal.parser\n    ref sub(U)(U rhs)\n        if (isCodepointSet!U)\n    {\n        Marker mark;\n        foreach (i; rhs.byInterval)\n        {\n            mark = this.skipUpTo(i.a, mark);\n            mark = this.dropUpTo(i.b, mark);\n        }\n        return this;\n    }\n\n  package(std)  // used from: std.regex.internal.parse\n    ref add(U)(U rhs)\n        if (isCodepointSet!U)\n    {\n        Marker start;\n        foreach (i; rhs.byInterval)\n        {\n            start = addInterval(i.a, i.b, start);\n        }\n        return this;\n    }\n\n// end of mixin-able part\n//============================================================================\npublic:\n    /**\n        Obtains a set that is the inversion of this set.\n\n        See the '!' $(LREF opUnary) for the same but using operators.\n    */\n    @property auto inverted()\n    {\n        InversionList inversion = this;\n        if (inversion.data.length == 0)\n        {\n            inversion.addInterval(0, lastDchar+1);\n            return inversion;\n        }\n        if (inversion.data[0] != 0)\n            genericReplace(inversion.data, 0, 0, [0]);\n        else\n            genericReplace(inversion.data, 0, 1, cast(uint[]) null);\n        if (data[data.length-1] != lastDchar+1)\n            genericReplace(inversion.data,\n                inversion.data.length, inversion.data.length, [lastDchar+1]);\n        else\n            genericReplace(inversion.data,\n                inversion.data.length-1, inversion.data.length, cast(uint[]) null);\n\n        return inversion;\n    }\n\n    ///\n    pure @safe unittest\n    {\n        auto set = unicode.ASCII;\n        // union with the inverse gets all of the code points in the Unicode\n        assert((set | set.inverted).length == 0x110000);\n        // no intersection with the inverse\n        assert((set & set.inverted).empty);\n    }\n\n    package static string toSourceCode(const(CodepointInterval)[] range, string funcName)\n    {\n        import std.algorithm.searching : countUntil;\n        import std.format : format;\n        enum maxBinary = 3;\n        static string linearScope(R)(R ivals, string indent)\n        {\n            string result = indent~\"{\\n\";\n            string deeper = indent~\"    \";\n            foreach (ival; ivals)\n            {\n                immutable span = ival[1] - ival[0];\n                assert(span != 0);\n                if (span == 1)\n                {\n                    result ~= format(\"%sif (ch == %s) return true;\\n\", deeper, ival[0]);\n                }\n                else if (span == 2)\n                {\n                    result ~= format(\"%sif (ch == %s || ch == %s) return true;\\n\",\n                        deeper, ival[0], ival[0]+1);\n                }\n                else\n                {\n                    if (ival[0] != 0) // dchar is unsigned and  < 0 is useless\n                        result ~= format(\"%sif (ch < %s) return false;\\n\", deeper, ival[0]);\n                    result ~= format(\"%sif (ch < %s) return true;\\n\", deeper, ival[1]);\n                }\n            }\n            result ~= format(\"%sreturn false;\\n%s}\\n\", deeper, indent); // including empty range of intervals\n            return result;\n        }\n\n        static string binaryScope(R)(R ivals, string indent) @safe\n        {\n            // time to do unrolled comparisons?\n            if (ivals.length < maxBinary)\n                return linearScope(ivals, indent);\n            else\n                return bisect(ivals, ivals.length/2, indent);\n        }\n\n        // not used yet if/elsebinary search is far better with DMD  as of 2.061\n        // and GDC is doing fine job either way\n        static string switchScope(R)(R ivals, string indent)\n        {\n            string result = indent~\"switch (ch){\\n\";\n            string deeper = indent~\"    \";\n            foreach (ival; ivals)\n            {\n                if (ival[0]+1 == ival[1])\n                {\n                    result ~= format(\"%scase %s: return true;\\n\",\n                        deeper, ival[0]);\n                }\n                else\n                {\n                    result ~= format(\"%scase %s: .. case %s: return true;\\n\",\n                         deeper, ival[0], ival[1]-1);\n                }\n            }\n            result ~= deeper~\"default: return false;\\n\"~indent~\"}\\n\";\n            return result;\n        }\n\n        static string bisect(R)(R range, size_t idx, string indent)\n        {\n            string deeper = indent ~ \"    \";\n            // bisect on one [a, b) interval at idx\n            string result = indent~\"{\\n\";\n            // less branch, < a\n            result ~= format(\"%sif (ch < %s)\\n%s\",\n                deeper, range[idx][0], binaryScope(range[0 .. idx], deeper));\n            // middle point,  >= a && < b\n            result ~= format(\"%selse if (ch < %s) return true;\\n\",\n                deeper, range[idx][1]);\n            // greater or equal branch,  >= b\n            result ~= format(\"%selse\\n%s\",\n                deeper, binaryScope(range[idx+1..$], deeper));\n            return result~indent~\"}\\n\";\n        }\n\n        string code = format(\"bool %s(dchar ch) @safe pure nothrow @nogc\\n\",\n            funcName.empty ? \"function\" : funcName);\n        // special case first bisection to be on ASCII vs beyond\n        auto tillAscii = countUntil!\"a[0] > 0x80\"(range);\n        if (tillAscii <= 0) // everything is ASCII or nothing is ascii (-1 & 0)\n            code ~= binaryScope(range, \"\");\n        else\n            code ~= bisect(range, tillAscii, \"\");\n        return code;\n    }\n\n    /**\n        Generates string with D source code of unary function with name of\n        `funcName` taking a single `dchar` argument. If `funcName` is empty\n        the code is adjusted to be a lambda function.\n\n        The function generated tests if the $(CODEPOINT) passed\n        belongs to this set or not. The result is to be used with string mixin.\n        The intended usage area is aggressive optimization via meta programming\n        in parser generators and the like.\n\n        Note: Use with care for relatively small or regular sets. It\n        could end up being slower then just using multi-staged tables.\n\n        Example:\n        ---\n        import std.stdio;\n\n        // construct set directly from [a, b$RPAREN intervals\n        auto set = CodepointSet(10, 12, 45, 65, 100, 200);\n        writeln(set);\n        writeln(set.toSourceCode(\"func\"));\n        ---\n\n        The above outputs something along the lines of:\n        ---\n        bool func(dchar ch)  @safe pure nothrow @nogc\n        {\n            if (ch < 45)\n            {\n                if (ch == 10 || ch == 11) return true;\n                return false;\n            }\n            else if (ch < 65) return true;\n            else\n            {\n                if (ch < 100) return false;\n                if (ch < 200) return true;\n                return false;\n            }\n        }\n        ---\n    */\n    string toSourceCode(string funcName=\"\")\n    {\n        import std.array : array;\n        auto range = byInterval.array();\n        return toSourceCode(range, funcName);\n    }\n\n    /**\n        True if this set doesn't contain any $(CODEPOINTS).\n    */\n    @property bool empty() const\n    {\n        return data.length == 0;\n    }\n\n    ///\n    pure @safe unittest\n    {\n        CodepointSet emptySet;\n        assert(emptySet.length == 0);\n        assert(emptySet.empty);\n    }\n\nprivate:\n    alias This = typeof(this);\n    alias Marker = size_t;\n\n    // a random-access range of integral pairs\n    static struct Intervals(Range)\n    {\n        this(Range sp) scope\n        {\n            slice = sp;\n            start = 0;\n            end = sp.length;\n        }\n\n        this(Range sp, size_t s, size_t e) scope\n        {\n            slice = sp;\n            start = s;\n            end = e;\n        }\n\n        @property auto front()const\n        {\n            immutable a = slice[start];\n            immutable b = slice[start+1];\n            return CodepointInterval(a, b);\n        }\n\n        //may break sorted property - but we need std.sort to access it\n        //hence package protection attribute\n        static if (hasAssignableElements!Range)\n        package @property void front(CodepointInterval val)\n        {\n            slice[start] = val.a;\n            slice[start+1] = val.b;\n        }\n\n        @property auto back()const\n        {\n            immutable a = slice[end-2];\n            immutable b = slice[end-1];\n            return CodepointInterval(a, b);\n        }\n\n        //ditto about package\n        static if (hasAssignableElements!Range)\n        package @property void back(CodepointInterval val)\n        {\n            slice[end-2] = val.a;\n            slice[end-1] = val.b;\n        }\n\n        void popFront()\n        {\n            start += 2;\n        }\n\n        void popBack()\n        {\n            end -= 2;\n        }\n\n        auto opIndex(size_t idx) const\n        {\n            immutable a = slice[start+idx*2];\n            immutable b = slice[start+idx*2+1];\n            return CodepointInterval(a, b);\n        }\n\n        //ditto about package\n        static if (hasAssignableElements!Range)\n        package void opIndexAssign(CodepointInterval val, size_t idx)\n        {\n            slice[start+idx*2] = val.a;\n            slice[start+idx*2+1] = val.b;\n        }\n\n        auto opSlice(size_t s, size_t e)\n        {\n            return Intervals(slice, s*2+start, e*2+start);\n        }\n\n        @property size_t length()const {  return slice.length/2; }\n\n        @property bool empty()const { return start == end; }\n\n        @property auto save(){ return this; }\n    private:\n        size_t start, end;\n        Range slice;\n    }\n\n    // called after construction from intervals\n    // to make sure invariants hold\n    void sanitize()\n    {\n        import std.algorithm.comparison : max;\n        import std.algorithm.mutation : SwapStrategy;\n        import std.algorithm.sorting : sort;\n        if (data.length == 0)\n            return;\n        alias Ival = CodepointInterval;\n        //intervals wrapper for a _range_ over packed array\n        auto ivals = Intervals!(typeof(data[]))(data[]);\n        //@@@BUG@@@ can't use \"a.a < b.a\" see issue 12265\n        sort!((a,b) => a.a < b.a, SwapStrategy.stable)(ivals);\n        // what follows is a variation on stable remove\n        // differences:\n        // - predicate is binary, and is tested against\n        //   the last kept element (at 'i').\n        // - predicate mutates lhs (merges rhs into lhs)\n        size_t len = ivals.length;\n        size_t i = 0;\n        size_t j = 1;\n        while (j < len)\n        {\n            if (ivals[i].b >= ivals[j].a)\n            {\n                ivals[i] = Ival(ivals[i].a, max(ivals[i].b, ivals[j].b));\n                j++;\n            }\n            else //unmergable\n            {\n                // check if there is a hole after merges\n                // (in the best case we do 0 writes to ivals)\n                if (j != i+1)\n                    ivals[i+1] = ivals[j]; //copy over\n                i++;\n                j++;\n            }\n        }\n        len = i + 1;\n        for (size_t k=0; k + 1 < len; k++)\n        {\n            assert(ivals[k].a < ivals[k].b);\n            assert(ivals[k].b < ivals[k+1].a);\n        }\n        data.length = len * 2;\n    }\n\n    // special case for normal InversionList\n    ref subChar(dchar ch)\n    {\n        auto mark = skipUpTo(ch);\n        if (mark != data.length\n            && data[mark] == ch && data[mark-1] == ch)\n        {\n            // it has split, meaning that ch happens to be in one of intervals\n            data[mark] = data[mark]+1;\n        }\n        return this;\n    }\n\n    //\n    Marker addInterval(int a, int b, Marker hint=Marker.init)\n    in\n    {\n        assert(a <= b);\n    }\n    do\n    {\n        import std.range : assumeSorted, SearchPolicy;\n        auto range = assumeSorted(data[]);\n        size_t pos;\n        size_t a_idx = hint + range[hint..$].lowerBound!(SearchPolicy.gallop)(a).length;\n        if (a_idx == range.length)\n        {\n            //  [---+++----++++----++++++]\n            //  [                         a  b]\n            data.append(a, b);\n            return data.length-1;\n        }\n        size_t b_idx = range[a_idx .. range.length].lowerBound!(SearchPolicy.gallop)(b).length+a_idx;\n        uint[3] buf = void;\n        uint to_insert;\n        debug(std_uni)\n        {\n            writefln(\"a_idx=%d; b_idx=%d;\", a_idx, b_idx);\n        }\n        if (b_idx == range.length)\n        {\n            //  [-------++++++++----++++++-]\n            //  [      s     a                 b]\n            if (a_idx & 1)// a in positive\n            {\n                buf[0] = b;\n                to_insert = 1;\n            }\n            else// a in negative\n            {\n                buf[0] = a;\n                buf[1] = b;\n                to_insert = 2;\n            }\n            pos = genericReplace(data, a_idx, b_idx, buf[0 .. to_insert]);\n            return pos - 1;\n        }\n\n        uint top = data[b_idx];\n\n        debug(std_uni)\n        {\n            writefln(\"a_idx=%d; b_idx=%d;\", a_idx, b_idx);\n            writefln(\"a=%s; b=%s; top=%s;\", a, b, top);\n        }\n        if (a_idx & 1)\n        {// a in positive\n            if (b_idx & 1)// b in positive\n            {\n                //  [-------++++++++----++++++-]\n                //  [       s    a        b    ]\n                buf[0] = top;\n                to_insert = 1;\n            }\n            else // b in negative\n            {\n                //  [-------++++++++----++++++-]\n                //  [       s    a   b         ]\n                if (top == b)\n                {\n                    assert(b_idx+1 < data.length);\n                    buf[0] = data[b_idx+1];\n                    pos = genericReplace(data, a_idx, b_idx+2, buf[0 .. 1]);\n                    return pos - 1;\n                }\n                buf[0] = b;\n                buf[1] = top;\n                to_insert = 2;\n            }\n        }\n        else\n        { // a in negative\n            if (b_idx & 1) // b in positive\n            {\n                //  [----------+++++----++++++-]\n                //  [     a     b              ]\n                buf[0] = a;\n                buf[1] = top;\n                to_insert = 2;\n            }\n            else// b in negative\n            {\n                //  [----------+++++----++++++-]\n                //  [  a       s      b        ]\n                if (top == b)\n                {\n                    assert(b_idx+1 < data.length);\n                    buf[0] = a;\n                    buf[1] = data[b_idx+1];\n                    pos = genericReplace(data, a_idx, b_idx+2, buf[0 .. 2]);\n                    return pos - 1;\n                }\n                buf[0] = a;\n                buf[1] = b;\n                buf[2] = top;\n                to_insert = 3;\n            }\n        }\n        pos = genericReplace(data, a_idx, b_idx+1, buf[0 .. to_insert]);\n        debug(std_uni)\n        {\n            writefln(\"marker idx: %d; length=%d\", pos, data[pos], data.length);\n            writeln(\"inserting \", buf[0 .. to_insert]);\n        }\n        return pos - 1;\n    }\n\n    //\n    Marker dropUpTo(uint a, Marker pos=Marker.init)\n    in\n    {\n        assert(pos % 2 == 0); // at start of interval\n    }\n    do\n    {\n        auto range = assumeSorted!\"a <= b\"(data[pos .. data.length]);\n        if (range.empty)\n            return pos;\n        size_t idx = pos;\n        idx += range.lowerBound(a).length;\n\n        debug(std_uni)\n        {\n            writeln(\"dropUpTo full length=\", data.length);\n            writeln(pos,\"~~~\", idx);\n        }\n        if (idx == data.length)\n            return genericReplace(data, pos, idx, cast(uint[])[]);\n        if (idx & 1)\n        {   // a in positive\n            //[--+++----++++++----+++++++------...]\n            //      |<---si       s  a  t\n            genericReplace(data, pos, idx, [a]);\n        }\n        else\n        {   // a in negative\n            //[--+++----++++++----+++++++-------+++...]\n            //      |<---si              s  a  t\n            genericReplace(data, pos, idx, cast(uint[])[]);\n        }\n        return pos;\n    }\n\n    //\n    Marker skipUpTo(uint a, Marker pos=Marker.init)\n    out(result)\n    {\n        assert(result % 2 == 0);// always start of interval\n        //(may be  0-width after-split)\n    }\n    do\n    {\n        assert(data.length % 2 == 0);\n        auto range = assumeSorted!\"a <= b\"(data[pos .. data.length]);\n        size_t idx = pos+range.lowerBound(a).length;\n\n        if (idx >= data.length) // could have Marker point to recently removed stuff\n            return data.length;\n\n        if (idx & 1)// inside of interval, check for split\n        {\n\n            immutable top = data[idx];\n            if (top == a)// no need to split, it's end\n                return idx+1;\n            immutable start = data[idx-1];\n            if (a == start)\n                return idx-1;\n            // split it up\n            genericReplace(data, idx, idx+1, [a, a, top]);\n            return idx+1;        // avoid odd index\n        }\n        return idx;\n    }\n\n    CowArray!SP data;\n}\n\npure @system unittest\n{\n    import std.conv : to;\n    assert(unicode.ASCII.to!string() == \"[0..128)\");\n}\n\n// pedantic version for ctfe, and aligned-access only architectures\n@system private uint safeRead24(scope const ubyte* ptr, size_t idx) pure nothrow @nogc\n{\n    idx *= 3;\n    version (LittleEndian)\n        return ptr[idx] + (cast(uint) ptr[idx+1]<<8)\n             + (cast(uint) ptr[idx+2]<<16);\n    else\n        return (cast(uint) ptr[idx]<<16) + (cast(uint) ptr[idx+1]<<8)\n             + ptr[idx+2];\n}\n\n// ditto\n@system private void safeWrite24(scope ubyte* ptr, uint val, size_t idx) pure nothrow @nogc\n{\n    idx *= 3;\n    version (LittleEndian)\n    {\n        ptr[idx] = val & 0xFF;\n        ptr[idx+1] = (val >> 8) & 0xFF;\n        ptr[idx+2] = (val >> 16) & 0xFF;\n    }\n    else\n    {\n        ptr[idx] = (val >> 16) & 0xFF;\n        ptr[idx+1] = (val >> 8) & 0xFF;\n        ptr[idx+2] = val & 0xFF;\n    }\n}\n\n// unaligned x86-like read/write functions\n@system private uint unalignedRead24(scope const ubyte* ptr, size_t idx) pure nothrow @nogc\n{\n    uint* src = cast(uint*)(ptr+3*idx);\n    version (LittleEndian)\n        return *src & 0xFF_FFFF;\n    else\n        return *src >> 8;\n}\n\n// ditto\n@system private void unalignedWrite24(scope ubyte* ptr, uint val, size_t idx) pure nothrow @nogc\n{\n    uint* dest = cast(uint*)(cast(ubyte*) ptr + 3*idx);\n    version (LittleEndian)\n        *dest = val | (*dest & 0xFF00_0000);\n    else\n        *dest = (val << 8) | (*dest & 0xFF);\n}\n\n@system private uint read24(scope const ubyte* ptr, size_t idx) pure nothrow @nogc\n{\n    static if (hasUnalignedReads)\n        return __ctfe ? safeRead24(ptr, idx) : unalignedRead24(ptr, idx);\n    else\n        return safeRead24(ptr, idx);\n}\n\n@system private void write24(scope ubyte* ptr, uint val, size_t idx) pure nothrow @nogc\n{\n    static if (hasUnalignedReads)\n        return __ctfe ? safeWrite24(ptr, val, idx) : unalignedWrite24(ptr, val, idx);\n    else\n        return safeWrite24(ptr, val, idx);\n}\n\nstruct CowArray(SP=GcPolicy)\n{\n    import std.range.primitives : hasLength;\n\n  @safe:\n    static auto reuse(uint[] arr)\n    {\n        CowArray cow;\n        cow.data = arr;\n        SP.append(cow.data, 1);\n        assert(cow.refCount == 1);\n        assert(cow.length == arr.length);\n        return cow;\n    }\n\n    this(Range)(Range range)\n        if (isInputRange!Range && hasLength!Range)\n    {\n        import std.algorithm.mutation : copy;\n        length = range.length;\n        copy(range, data[0..$-1]);\n    }\n\n    this(Range)(Range range)\n        if (isForwardRange!Range && !hasLength!Range)\n    {\n        import std.algorithm.mutation : copy;\n        import std.range.primitives : walkLength;\n        immutable len = walkLength(range.save);\n        length = len;\n        copy(range, data[0..$-1]);\n    }\n\n    this(this)\n    {\n        if (!empty)\n        {\n            refCount = refCount + 1;\n        }\n    }\n\n    ~this()\n    {\n        if (!empty)\n        {\n            immutable cnt = refCount;\n            if (cnt == 1)\n                SP.destroy(data);\n            else\n                refCount = cnt - 1;\n        }\n    }\n\n    // no ref-count for empty U24 array\n    @property bool empty() const { return data.length == 0; }\n\n    // report one less then actual size\n    @property size_t length() const\n    {\n        return data.length ? data.length - 1 : 0;\n    }\n\n    //+ an extra slot for ref-count\n    @property void length(size_t len)\n    {\n        import std.algorithm.comparison : min;\n        import std.algorithm.mutation : copy;\n        if (len == 0)\n        {\n            if (!empty)\n                freeThisReference();\n            return;\n        }\n        immutable total = len + 1; // including ref-count\n        if (empty)\n        {\n            data = SP.alloc!uint(total);\n            refCount = 1;\n            return;\n        }\n        immutable cur_cnt = refCount;\n        if (cur_cnt != 1) // have more references to this memory\n        {\n            refCount = cur_cnt - 1;\n            auto new_data = SP.alloc!uint(total);\n            // take shrinking into account\n            auto to_copy = min(total, data.length) - 1;\n            copy(data[0 .. to_copy], new_data[0 .. to_copy]);\n            data = new_data; // before setting refCount!\n            refCount = 1;\n        }\n        else // 'this' is the only reference\n        {\n            // use the realloc (hopefully in-place operation)\n            data = SP.realloc(data, total);\n            refCount = 1; // setup a ref-count in the new end of the array\n        }\n    }\n\n    alias opDollar = length;\n\n    uint opIndex()(size_t idx)const\n    {\n        return data[idx];\n    }\n\n    void opIndexAssign(uint val, size_t idx)\n    {\n        auto cnt = refCount;\n        if (cnt != 1)\n            dupThisReference(cnt);\n        data[idx] = val;\n    }\n\n    //\n    auto opSlice(size_t from, size_t to)\n    {\n        if (!empty)\n        {\n            auto cnt = refCount;\n            if (cnt != 1)\n                dupThisReference(cnt);\n        }\n        return data[from .. to];\n\n    }\n\n    //\n    auto opSlice(size_t from, size_t to) const\n    {\n        return data[from .. to];\n    }\n\n    // length slices before the ref count\n    auto opSlice()\n    {\n        return opSlice(0, length);\n    }\n\n    // ditto\n    auto opSlice() const\n    {\n        return opSlice(0, length);\n    }\n\n    void append(Range)(Range range)\n        if (isInputRange!Range && hasLength!Range && is(ElementType!Range : uint))\n    {\n        size_t nl = length + range.length;\n        length = nl;\n        copy(range, this[nl-range.length .. nl]);\n    }\n\n    void append()(uint[] val...)\n    {\n        length = length + val.length;\n        data[$-val.length-1 .. $-1] = val[];\n    }\n\n    bool opEquals()(auto const ref CowArray rhs)const\n    {\n        if (empty ^ rhs.empty)\n            return false; // one is empty and the other isn't\n        return empty || data[0..$-1] == rhs.data[0..$-1];\n    }\n\nprivate:\n    // ref-count is right after the data\n    @property uint refCount() const\n    {\n        return data[$-1];\n    }\n\n    @property void refCount(uint cnt)\n    {\n        data[$-1] = cnt;\n    }\n\n    void freeThisReference()\n    {\n        immutable count = refCount;\n        if (count != 1) // have more references to this memory\n        {\n            // dec shared ref-count\n            refCount = count - 1;\n            data = [];\n        }\n        else\n            SP.destroy(data);\n        assert(!data.ptr);\n    }\n\n    void dupThisReference(uint count)\n    in\n    {\n        assert(!empty && count != 1 && count == refCount);\n    }\n    do\n    {\n        import std.algorithm.mutation : copy;\n        // dec shared ref-count\n        refCount = count - 1;\n        // copy to the new chunk of RAM\n        auto new_data = SP.alloc!uint(data.length);\n        // bit-blit old stuff except the counter\n        copy(data[0..$-1], new_data[0..$-1]);\n        data = new_data; // before setting refCount!\n        refCount = 1; // so that this updates the right one\n    }\n\n    uint[] data;\n}\n\npure @safe unittest// Uint24 tests\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.mutation : copy;\n    import std.conv : text;\n    import std.range : iota, chain;\n    import std.range.primitives : isBidirectionalRange, isOutputRange;\n    void funcRef(T)(ref T u24)\n    {\n        u24.length = 2;\n        u24[1] = 1024;\n        T u24_c = u24;\n        assert(u24[1] == 1024);\n        u24.length = 0;\n        assert(u24.empty);\n        u24.append([1, 2]);\n        assert(equal(u24[], [1, 2]));\n        u24.append(111);\n        assert(equal(u24[], [1, 2, 111]));\n        assert(!u24_c.empty && u24_c[1] == 1024);\n        u24.length = 3;\n        copy(iota(0, 3), u24[]);\n        assert(equal(u24[], iota(0, 3)));\n        assert(u24_c[1] == 1024);\n    }\n\n    void func2(T)(T u24)\n    {\n        T u24_2 = u24;\n        T u24_3;\n        u24_3 = u24_2;\n        assert(u24_2 == u24_3);\n        assert(equal(u24[], u24_2[]));\n        assert(equal(u24_2[], u24_3[]));\n        funcRef(u24_3);\n\n        assert(equal(u24_3[], iota(0, 3)));\n        assert(!equal(u24_2[], u24_3[]));\n        assert(equal(u24_2[], u24[]));\n        u24_2 = u24_3;\n        assert(equal(u24_2[], iota(0, 3)));\n        // to test that passed arg is intact outside\n        // plus try out opEquals\n        u24 = u24_3;\n        u24 = T.init;\n        u24_3 = T.init;\n        assert(u24.empty);\n        assert(u24 == u24_3);\n        assert(u24 != u24_2);\n    }\n\n    static foreach (Policy; AliasSeq!(GcPolicy, ReallocPolicy))\n    {{\n        alias Range = typeof(CowArray!Policy.init[]);\n        alias U24A = CowArray!Policy;\n        static assert(isForwardRange!Range);\n        static assert(isBidirectionalRange!Range);\n        static assert(isOutputRange!(Range, uint));\n        static assert(isRandomAccessRange!(Range));\n\n        auto arr = U24A([42u, 36, 100]);\n        assert(arr[0] == 42);\n        assert(arr[1] == 36);\n        arr[0] = 72;\n        arr[1] = 0xFE_FEFE;\n        assert(arr[0] == 72);\n        assert(arr[1] == 0xFE_FEFE);\n        assert(arr[2] == 100);\n        U24A arr2 = arr;\n        assert(arr2[0] == 72);\n        arr2[0] = 11;\n        // test COW-ness\n        assert(arr[0] == 72);\n        assert(arr2[0] == 11);\n        // set this to about 100M to stress-test COW memory management\n        foreach (v; 0 .. 10_000)\n            func2(arr);\n        assert(equal(arr[], [72, 0xFE_FEFE, 100]));\n\n        auto r2 = U24A(iota(0, 100));\n        assert(equal(r2[], iota(0, 100)), text(r2[]));\n        copy(iota(10, 170, 2), r2[10 .. 90]);\n        assert(equal(r2[], chain(iota(0, 10), iota(10, 170, 2), iota(90, 100)))\n               , text(r2[]));\n    }}\n}\n\nversion (unittest)\n{\n    private alias AllSets = AliasSeq!(InversionList!GcPolicy, InversionList!ReallocPolicy);\n}\n\npure @safe unittest// core set primitives test\n{\n    import std.conv : text;\n    foreach (CodeList; AllSets)\n    {\n        CodeList a;\n        //\"plug a hole\" test\n        a.add(10, 20).add(25, 30).add(15, 27);\n        assert(a == CodeList(10, 30), text(a));\n\n        auto x = CodeList.init;\n        x.add(10, 20).add(30, 40).add(50, 60);\n\n        a = x;\n        a.add(20, 49);//[10, 49) [50, 60)\n        assert(a == CodeList(10, 49, 50 ,60));\n\n        a = x;\n        a.add(20, 50);\n        assert(a == CodeList(10, 60), text(a));\n\n        // simple unions, mostly edge effects\n        x = CodeList.init;\n        x.add(10, 20).add(40, 60);\n\n        a = x;\n        a.add(10, 25); //[10, 25) [40, 60)\n        assert(a == CodeList(10, 25, 40, 60));\n\n        a = x;\n        a.add(5, 15); //[5, 20) [40, 60)\n        assert(a == CodeList(5, 20, 40, 60));\n\n        a = x;\n        a.add(0, 10); // [0, 20) [40, 60)\n        assert(a == CodeList(0, 20, 40, 60));\n\n        a = x;\n        a.add(0, 5); // prepand\n        assert(a == CodeList(0, 5, 10, 20, 40, 60), text(a));\n\n        a = x;\n        a.add(5, 20);\n        assert(a == CodeList(5, 20, 40, 60));\n\n        a = x;\n        a.add(3, 37);\n        assert(a == CodeList(3, 37, 40, 60));\n\n        a = x;\n        a.add(37, 65);\n        assert(a == CodeList(10, 20, 37, 65));\n\n        // some tests on helpers for set intersection\n        x = CodeList.init.add(10, 20).add(40, 60).add(100, 120);\n        a = x;\n\n        auto m = a.skipUpTo(60);\n        a.dropUpTo(110, m);\n        assert(a == CodeList(10, 20, 40, 60, 110, 120), text(a.data[]));\n\n        a = x;\n        a.dropUpTo(100);\n        assert(a == CodeList(100, 120), text(a.data[]));\n\n        a = x;\n        m = a.skipUpTo(50);\n        a.dropUpTo(140, m);\n        assert(a == CodeList(10, 20, 40, 50), text(a.data[]));\n        a = x;\n        a.dropUpTo(60);\n        assert(a == CodeList(100, 120), text(a.data[]));\n    }\n}\n\n\n//test constructor to work with any order of intervals\npure @safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : text, to;\n    import std.range : chain, iota;\n    import std.typecons : tuple;\n    //ensure constructor handles bad ordering and overlap\n    auto c1 = CodepointSet('а', 'я'+1, 'А','Я'+1);\n    foreach (ch; chain(iota('а', 'я'+1), iota('А','Я'+1)))\n        assert(ch in c1, to!string(ch));\n\n    //contiguos\n    assert(CodepointSet(1000, 1006, 1006, 1009)\n        .byInterval.equal([tuple(1000, 1009)]));\n    //contains\n    assert(CodepointSet(900, 1200, 1000, 1100)\n        .byInterval.equal([tuple(900, 1200)]));\n    //intersect left\n    assert(CodepointSet(900, 1100, 1000, 1200)\n        .byInterval.equal([tuple(900, 1200)]));\n    //intersect right\n    assert(CodepointSet(1000, 1200, 900, 1100)\n        .byInterval.equal([tuple(900, 1200)]));\n\n    //ditto with extra items at end\n    assert(CodepointSet(1000, 1200, 900, 1100, 800, 850)\n        .byInterval.equal([tuple(800, 850), tuple(900, 1200)]));\n    assert(CodepointSet(900, 1100, 1000, 1200, 800, 850)\n        .byInterval.equal([tuple(800, 850), tuple(900, 1200)]));\n\n    //\"plug a hole\" test\n    auto c2 = CodepointSet(20, 40,\n        60, 80, 100, 140, 150, 200,\n        40, 60, 80, 100, 140, 150\n    );\n    assert(c2.byInterval.equal([tuple(20, 200)]));\n\n    auto c3 = CodepointSet(\n        20, 40, 60, 80, 100, 140, 150, 200,\n        0, 10, 15, 100, 10, 20, 200, 220);\n    assert(c3.byInterval.equal([tuple(0, 140), tuple(150, 220)]));\n}\n\n\npure @safe unittest\n{   // full set operations\n    import std.conv : text;\n    foreach (CodeList; AllSets)\n    {\n        CodeList a, b, c, d;\n\n        //\"plug a hole\"\n        a.add(20, 40).add(60, 80).add(100, 140).add(150, 200);\n        b.add(40, 60).add(80, 100).add(140, 150);\n        c = a | b;\n        d = b | a;\n        assert(c == CodeList(20, 200), text(CodeList.stringof,\" \", c));\n        assert(c == d, text(c,\" vs \", d));\n\n        b = CodeList.init.add(25, 45).add(65, 85).add(95,110).add(150, 210);\n        c = a | b; //[20,45) [60, 85) [95, 140) [150, 210)\n        d = b | a;\n        assert(c == CodeList(20, 45, 60, 85, 95, 140, 150, 210), text(c));\n        assert(c == d, text(c,\" vs \", d));\n\n        b = CodeList.init.add(10, 20).add(30,100).add(145,200);\n        c = a | b;//[10, 140) [145, 200)\n        d = b | a;\n        assert(c == CodeList(10, 140, 145, 200));\n        assert(c == d, text(c,\" vs \", d));\n\n        b = CodeList.init.add(0, 10).add(15, 100).add(10, 20).add(200, 220);\n        c = a | b;//[0, 140) [150, 220)\n        d = b | a;\n        assert(c == CodeList(0, 140, 150, 220));\n        assert(c == d, text(c,\" vs \", d));\n\n\n        a = CodeList.init.add(20, 40).add(60, 80);\n        b = CodeList.init.add(25, 35).add(65, 75);\n        c = a & b;\n        d = b & a;\n        assert(c == CodeList(25, 35, 65, 75), text(c));\n        assert(c == d, text(c,\" vs \", d));\n\n        a = CodeList.init.add(20, 40).add(60, 80).add(100, 140).add(150, 200);\n        b = CodeList.init.add(25, 35).add(65, 75).add(110, 130).add(160, 180);\n        c = a & b;\n        d = b & a;\n        assert(c == CodeList(25, 35, 65, 75, 110, 130, 160, 180), text(c));\n        assert(c == d, text(c,\" vs \", d));\n\n        a = CodeList.init.add(20, 40).add(60, 80).add(100, 140).add(150, 200);\n        b = CodeList.init.add(10, 30).add(60, 120).add(135, 160);\n        c = a & b;//[20, 30)[60, 80) [100, 120) [135, 140) [150, 160)\n        d = b & a;\n\n        assert(c == CodeList(20, 30, 60, 80, 100, 120, 135, 140, 150, 160),text(c));\n        assert(c == d, text(c, \" vs \",d));\n        assert((c & a) == c);\n        assert((d & b) == d);\n        assert((c & d) == d);\n\n        b = CodeList.init.add(40, 60).add(80, 100).add(140, 200);\n        c = a & b;\n        d = b & a;\n        assert(c == CodeList(150, 200), text(c));\n        assert(c == d, text(c, \" vs \",d));\n        assert((c & a) == c);\n        assert((d & b) == d);\n        assert((c & d) == d);\n\n        assert((a & a) == a);\n        assert((b & b) == b);\n\n        a = CodeList.init.add(20, 40).add(60, 80).add(100, 140).add(150, 200);\n        b = CodeList.init.add(30, 60).add(75, 120).add(190, 300);\n        c = a - b;// [30, 40) [60, 75) [120, 140) [150, 190)\n        d = b - a;// [40, 60) [80, 100) [200, 300)\n        assert(c == CodeList(20, 30, 60, 75, 120, 140, 150, 190), text(c));\n        assert(d == CodeList(40, 60, 80, 100, 200, 300), text(d));\n        assert(c - d == c, text(c-d, \" vs \", c));\n        assert(d - c == d, text(d-c, \" vs \", d));\n        assert(c - c == CodeList.init);\n        assert(d - d == CodeList.init);\n\n        a = CodeList.init.add(20, 40).add( 60, 80).add(100, 140).add(150,            200);\n        b = CodeList.init.add(10,  50).add(60,                           160).add(190, 300);\n        c = a - b;// [160, 190)\n        d = b - a;// [10, 20) [40, 50) [80, 100) [140, 150) [200, 300)\n        assert(c == CodeList(160, 190), text(c));\n        assert(d == CodeList(10, 20, 40, 50, 80, 100, 140, 150, 200, 300), text(d));\n        assert(c - d == c, text(c-d, \" vs \", c));\n        assert(d - c == d, text(d-c, \" vs \", d));\n        assert(c - c == CodeList.init);\n        assert(d - d == CodeList.init);\n\n        a = CodeList.init.add(20,    40).add(60, 80).add(100,      140).add(150,  200);\n        b = CodeList.init.add(10, 30).add(45,         100).add(130,             190);\n        c = a ~ b; // [10, 20) [30, 40) [45, 60) [80, 130) [140, 150) [190, 200)\n        d = b ~ a;\n        assert(c == CodeList(10, 20, 30, 40, 45, 60, 80, 130, 140, 150, 190, 200),\n               text(c));\n        assert(c == d, text(c, \" vs \", d));\n    }\n}\n\n}\n\npure @safe unittest// vs single dchar\n{\n    import std.conv : text;\n    CodepointSet a = CodepointSet(10, 100, 120, 200);\n    assert(a - 'A' == CodepointSet(10, 65, 66, 100, 120, 200), text(a - 'A'));\n    assert((a & 'B') == CodepointSet(66, 67));\n}\n\npure @safe unittest// iteration & opIndex\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : text;\n    import std.typecons : tuple, Tuple;\n\n    static foreach (CodeList; AliasSeq!(InversionList!(ReallocPolicy)))\n    {{\n        auto arr = \"ABCDEFGHIJKLMabcdefghijklm\"d;\n        auto a = CodeList('A','N','a', 'n');\n        assert(equal(a.byInterval,\n                [tuple(cast(uint)'A', cast(uint)'N'), tuple(cast(uint)'a', cast(uint)'n')]\n            ), text(a.byInterval));\n\n        // same @@@BUG as in issue 8949 ?\n        version (bug8949)\n        {\n            import std.range : retro;\n            assert(equal(retro(a.byInterval),\n                [tuple(cast(uint)'a', cast(uint)'n'), tuple(cast(uint)'A', cast(uint)'N')]\n            ), text(retro(a.byInterval)));\n        }\n        auto achr = a.byCodepoint;\n        assert(equal(achr, arr), text(a.byCodepoint));\n        foreach (ch; a.byCodepoint)\n            assert(a[ch]);\n        auto x = CodeList(100, 500, 600, 900, 1200, 1500);\n        assert(equal(x.byInterval, [ tuple(100, 500), tuple(600, 900), tuple(1200, 1500)]), text(x.byInterval));\n        foreach (ch; x.byCodepoint)\n            assert(x[ch]);\n        static if (is(CodeList == CodepointSet))\n        {\n            auto y = CodeList(x.byInterval);\n            assert(equal(x.byInterval, y.byInterval));\n        }\n        assert(equal(CodepointSet.init.byInterval, cast(Tuple!(uint, uint)[])[]));\n        assert(equal(CodepointSet.init.byCodepoint, cast(dchar[])[]));\n    }}\n}\n\n//============================================================================\n// Generic Trie template and various ways to build it\n//============================================================================\n\n// debug helper to get a shortened array dump\nauto arrayRepr(T)(T x)\n{\n    import std.conv : text;\n    if (x.length > 32)\n    {\n        return text(x[0 .. 16],\"~...~\", x[x.length-16 .. x.length]);\n    }\n    else\n        return text(x);\n}\n\n/**\n    Maps `Key` to a suitable integer index within the range of `size_t`.\n    The mapping is constructed by applying predicates from `Prefix` left to right\n    and concatenating the resulting bits.\n\n    The first (leftmost) predicate defines the most significant bits of\n    the resulting index.\n */\ntemplate mapTrieIndex(Prefix...)\n{\n    size_t mapTrieIndex(Key)(Key key)\n        if (isValidPrefixForTrie!(Key, Prefix))\n    {\n        alias p = Prefix;\n        size_t idx;\n        foreach (i, v; p[0..$-1])\n        {\n            idx |= p[i](key);\n            idx <<= p[i+1].bitSize;\n        }\n        idx |= p[$-1](key);\n        return idx;\n    }\n}\n\n/*\n    `TrieBuilder` is a type used for incremental construction\n    of $(LREF Trie)s.\n\n    See $(LREF buildTrie) for generic helpers built on top of it.\n*/\n@trusted private struct TrieBuilder(Value, Key, Args...)\nif (isBitPackableType!Value && isValidArgsForTrie!(Key, Args))\n{\n    import std.exception : enforce;\n\nprivate:\n    // last index is not stored in table, it is used as an offset to values in a block.\n    static if (is(Value == bool))// always pack bool\n        alias V = BitPacked!(Value, 1);\n    else\n        alias V = Value;\n    static auto deduceMaxIndex(Preds...)()\n    {\n        size_t idx = 1;\n        foreach (v; Preds)\n            idx *= 2^^v.bitSize;\n        return idx;\n    }\n\n    static if (is(typeof(Args[0]) : Key)) // Args start with upper bound on Key\n    {\n        alias Prefix = Args[1..$];\n        enum lastPageSize = 2^^Prefix[$-1].bitSize;\n        enum translatedMaxIndex = mapTrieIndex!(Prefix)(Args[0]);\n        enum roughedMaxIndex =\n            (translatedMaxIndex + lastPageSize-1)/lastPageSize*lastPageSize;\n        // check warp around - if wrapped, use the default deduction rule\n        enum maxIndex = roughedMaxIndex < translatedMaxIndex ?\n            deduceMaxIndex!(Prefix)() : roughedMaxIndex;\n    }\n    else\n    {\n        alias Prefix = Args;\n        enum maxIndex = deduceMaxIndex!(Prefix)();\n    }\n\n    alias getIndex = mapTrieIndex!(Prefix);\n\n    enum lastLevel = Prefix.length-1;\n    struct ConstructState\n    {\n        size_t idx_zeros, idx_ones;\n    }\n    // iteration over levels of Trie, each indexes its own level and thus a shortened domain\n    size_t[Prefix.length] indices;\n    // default filler value to use\n    Value defValue;\n    // this is a full-width index of next item\n    size_t curIndex;\n    // all-zeros page index, all-ones page index (+ indicator if there is such a page)\n    ConstructState[Prefix.length] state;\n    // the table being constructed\n    MultiArray!(idxTypes!(Key, fullBitSize!(Prefix), Prefix[0..$]), V) table;\n\n    @disable this();\n\n    //shortcut for index variable at level 'level'\n    @property ref idx(size_t level)(){ return indices[level]; }\n\n    // this function assumes no holes in the input so\n    // indices are going one by one\n    void addValue(size_t level, T)(T val, size_t numVals)\n    {\n        alias j = idx!level;\n        enum pageSize = 1 << Prefix[level].bitSize;\n        if (numVals == 0)\n            return;\n        auto ptr = table.slice!(level);\n        if (numVals == 1)\n        {\n            static if (level == Prefix.length-1)\n                ptr[j] = val;\n            else\n            {// can incur narrowing conversion\n                assert(j < ptr.length);\n                ptr[j] = force!(typeof(ptr[j]))(val);\n            }\n            j++;\n            if (j % pageSize == 0)\n                spillToNextPage!level(ptr);\n            return;\n        }\n        // longer row of values\n        // get to the next page boundary\n        immutable nextPB = (j + pageSize) & ~(pageSize-1);\n        immutable n =  nextPB - j;// can fill right in this page\n        if (numVals < n) //fits in current page\n        {\n            ptr[j .. j+numVals]  = val;\n            j += numVals;\n            return;\n        }\n        static if (level != 0)//on the first level it always fits\n        {\n            numVals -= n;\n            //write till the end of current page\n            ptr[j .. j+n]  = val;\n            j += n;\n            //spill to the next page\n            spillToNextPage!level(ptr);\n            // page at once loop\n            if (state[level].idx_zeros != size_t.max && val == T.init)\n            {\n                alias NextIdx = typeof(table.slice!(level-1)[0]);\n                addValue!(level-1)(force!NextIdx(state[level].idx_zeros),\n                    numVals/pageSize);\n                ptr = table.slice!level; //table structure might have changed\n                numVals %= pageSize;\n            }\n            else\n            {\n                while (numVals >= pageSize)\n                {\n                    numVals -= pageSize;\n                    ptr[j .. j+pageSize]  = val;\n                    j += pageSize;\n                    spillToNextPage!level(ptr);\n                }\n            }\n            if (numVals)\n            {\n                // the leftovers, an incomplete page\n                ptr[j .. j+numVals]  = val;\n                j += numVals;\n            }\n        }\n    }\n\n    void spillToNextPage(size_t level, Slice)(ref Slice ptr)\n    {\n        // last level (i.e. topmost) has 1 \"page\"\n        // thus it need not to add a new page on upper level\n        static if (level != 0)\n            spillToNextPageImpl!(level)(ptr);\n    }\n\n    // this can re-use the current page if duplicate or allocate a new one\n    // it also makes sure that previous levels point to the correct page in this level\n    void spillToNextPageImpl(size_t level, Slice)(ref Slice ptr)\n    {\n        alias NextIdx = typeof(table.slice!(level-1)[0]);\n        NextIdx next_lvl_index;\n        enum pageSize = 1 << Prefix[level].bitSize;\n        assert(idx!level % pageSize == 0);\n        immutable last = idx!level-pageSize;\n        const slice = ptr[idx!level - pageSize .. idx!level];\n        size_t j;\n        for (j=0; j<last; j+=pageSize)\n        {\n            if (ptr[j .. j+pageSize] == slice)\n            {\n                // get index to it, reuse ptr space for the next block\n                next_lvl_index = force!NextIdx(j/pageSize);\n                version (none)\n                {\n                import std.stdio : writefln, writeln;\n                writefln(\"LEVEL(%s) page mapped idx: %s: 0..%s  ---> [%s..%s]\"\n                        ,level\n                        ,indices[level-1], pageSize, j, j+pageSize);\n                writeln(\"LEVEL(\", level\n                        , \") mapped page is: \", slice, \": \", arrayRepr(ptr[j .. j+pageSize]));\n                writeln(\"LEVEL(\", level\n                        , \") src page is :\", ptr, \": \", arrayRepr(slice[0 .. pageSize]));\n                }\n                idx!level -= pageSize; // reuse this page, it is duplicate\n                break;\n            }\n        }\n        if (j == last)\n        {\n    L_allocate_page:\n            next_lvl_index = force!NextIdx(idx!level/pageSize - 1);\n            if (state[level].idx_zeros == size_t.max && ptr.zeros(j, j+pageSize))\n            {\n                state[level].idx_zeros = next_lvl_index;\n            }\n            // allocate next page\n            version (none)\n            {\n            import std.stdio : writefln;\n            writefln(\"LEVEL(%s) page allocated: %s\"\n                     , level, arrayRepr(slice[0 .. pageSize]));\n            writefln(\"LEVEL(%s) index: %s ; page at this index %s\"\n                     , level\n                     , next_lvl_index\n                     , arrayRepr(\n                         table.slice!(level)\n                          [pageSize*next_lvl_index..(next_lvl_index+1)*pageSize]\n                        ));\n            }\n            table.length!level = table.length!level + pageSize;\n        }\n    L_know_index:\n        // for the previous level, values are indices to the pages in the current level\n        addValue!(level-1)(next_lvl_index, 1);\n        ptr = table.slice!level; //re-load the slice after moves\n    }\n\n    // idx - full-width index to fill with v (full-width index != key)\n    // fills everything in the range of [curIndex, idx) with filler\n    void putAt(size_t idx, Value v)\n    {\n        assert(idx >= curIndex);\n        immutable numFillers = idx - curIndex;\n        addValue!lastLevel(defValue, numFillers);\n        addValue!lastLevel(v, 1);\n        curIndex = idx + 1;\n    }\n\n    // ditto, but sets the range of [idxA, idxB) to v\n    void putRangeAt(size_t idxA, size_t idxB, Value v)\n    {\n        assert(idxA >= curIndex);\n        assert(idxB >= idxA);\n        size_t numFillers = idxA - curIndex;\n        addValue!lastLevel(defValue, numFillers);\n        addValue!lastLevel(v, idxB - idxA);\n        curIndex = idxB; // open-right\n    }\n\n    enum errMsg = \"non-monotonic prefix function(s), an unsorted range or \"~\n        \"duplicate key->value mapping\";\n\npublic:\n    /**\n        Construct a builder, where `filler` is a value\n        to indicate empty slots (or \"not found\" condition).\n    */\n    this(Value filler)\n    {\n        curIndex = 0;\n        defValue = filler;\n        // zeros-page index, ones-page index\n        foreach (ref v; state)\n            v = ConstructState(size_t.max, size_t.max);\n        table = typeof(table)(indices);\n        // one page per level is a bootstrap minimum\n        foreach (i, Pred; Prefix)\n            table.length!i = (1 << Pred.bitSize);\n    }\n\n    /**\n        Put a value `v` into interval as\n        mapped by keys from `a` to `b`.\n        All slots prior to `a` are filled with\n        the default filler.\n    */\n    void putRange(Key a, Key b, Value v)\n    {\n        auto idxA = getIndex(a), idxB = getIndex(b);\n        // indexes of key should always grow\n        enforce(idxB >= idxA && idxA >= curIndex, errMsg);\n        putRangeAt(idxA, idxB, v);\n    }\n\n    /**\n        Put a value `v` into slot mapped by `key`.\n        All slots prior to `key` are filled with the\n        default filler.\n    */\n    void putValue(Key key, Value v)\n    {\n        auto idx = getIndex(key);\n        enforce(idx >= curIndex, errMsg);\n        putAt(idx, v);\n    }\n\n    /// Finishes construction of Trie, yielding an immutable Trie instance.\n    auto build()\n    {\n        static if (maxIndex != 0) // doesn't cover full range of size_t\n        {\n            assert(curIndex <= maxIndex);\n            addValue!lastLevel(defValue, maxIndex - curIndex);\n        }\n        else\n        {\n            if (curIndex != 0 // couldn't wrap around\n                || (Prefix.length != 1 && indices[lastLevel] == 0)) // can be just empty\n            {\n                addValue!lastLevel(defValue, size_t.max - curIndex);\n                addValue!lastLevel(defValue, 1);\n            }\n            // else curIndex already completed the full range of size_t by wrapping around\n        }\n        return Trie!(V, Key, maxIndex, Prefix)(table);\n    }\n}\n\n/**\n    $(P A generic Trie data-structure for a fixed number of stages.\n    The design goal is optimal speed with smallest footprint size.\n    )\n    $(P It's intentionally read-only and doesn't provide constructors.\n     To construct one use a special builder,\n     see $(LREF TrieBuilder) and $(LREF buildTrie).\n    )\n\n*/\n@trusted private struct Trie(Value, Key, Args...)\nif (isValidPrefixForTrie!(Key, Args)\n    || (isValidPrefixForTrie!(Key, Args[1..$])\n    && is(typeof(Args[0]) : size_t)))\n{\n    import std.range.primitives : isOutputRange;\n    static if (is(typeof(Args[0]) : size_t))\n    {\n        private enum maxIndex = Args[0];\n        private enum hasBoundsCheck = true;\n        private alias Prefix = Args[1..$];\n    }\n    else\n    {\n        private enum hasBoundsCheck = false;\n        private alias Prefix = Args;\n    }\n\n    private this()(typeof(_table) table)\n    {\n        _table = table;\n    }\n\n    // only for constant Tries constructed from precompiled tables\n    private this()(const(size_t)[] offsets, const(size_t)[] sizes,\n        const(size_t)[] data) const\n    {\n        _table = typeof(_table)(offsets, sizes, data);\n    }\n\n    /**\n        $(P Lookup the `key` in this `Trie`. )\n\n        $(P The lookup always succeeds if key fits the domain\n        provided during construction. The whole domain defined\n        is covered so instead of not found condition\n        the sentinel (filler) value could be used. )\n\n        $(P See $(LREF buildTrie), $(LREF TrieBuilder) for how to\n        define a domain of `Trie` keys and the sentinel value. )\n\n        Note:\n        Domain range-checking is only enabled in debug builds\n        and results in assertion failure.\n    */\n    TypeOfBitPacked!Value opIndex()(Key key) const\n    {\n        static if (hasBoundsCheck)\n            assert(mapTrieIndex!Prefix(key) < maxIndex);\n        size_t idx;\n        alias p = Prefix;\n        idx = cast(size_t) p[0](key);\n        foreach (i, v; p[0..$-1])\n            idx = cast(size_t)((_table.ptr!i[idx]<<p[i+1].bitSize) + p[i+1](key));\n        return _table.ptr!(p.length-1)[idx];\n    }\n\n    ///\n    @property size_t bytes(size_t n=size_t.max)() const\n    {\n        return _table.bytes!n;\n    }\n\n    ///\n    @property size_t pages(size_t n)() const\n    {\n        return (bytes!n+2^^(Prefix[n].bitSize-1))\n                /2^^Prefix[n].bitSize;\n    }\n\n    ///\n    void store(OutRange)(scope OutRange sink) const\n        if (isOutputRange!(OutRange, char))\n    {\n        _table.store(sink);\n    }\n\nprivate:\n    MultiArray!(idxTypes!(Key, fullBitSize!(Prefix), Prefix[0..$]), Value) _table;\n}\n\n// create a tuple of 'sliceBits' that slice the 'top' of bits into pieces of sizes 'sizes'\n// left-to-right, the most significant bits first\ntemplate GetBitSlicing(size_t top, sizes...)\n{\n    static if (sizes.length > 0)\n        alias GetBitSlicing =\n            AliasSeq!(sliceBits!(top - sizes[0], top),\n                      GetBitSlicing!(top - sizes[0], sizes[1..$]));\n    else\n        alias GetBitSlicing = AliasSeq!();\n}\n\ntemplate callableWith(T)\n{\n    template callableWith(alias Pred)\n    {\n        static if (!is(typeof(Pred(T.init))))\n            enum callableWith = false;\n        else\n        {\n            alias Result = typeof(Pred(T.init));\n            enum callableWith = isBitPackableType!(TypeOfBitPacked!(Result));\n        }\n    }\n}\n\n/*\n    Check if `Prefix` is a valid set of predicates\n    for `Trie` template having `Key` as the type of keys.\n    This requires all predicates to be callable, take\n    single argument of type `Key` and return unsigned value.\n*/\ntemplate isValidPrefixForTrie(Key, Prefix...)\n{\n    import std.meta : allSatisfy;\n    enum isValidPrefixForTrie = allSatisfy!(callableWith!Key, Prefix); // TODO: tighten the screws\n}\n\n/*\n    Check if `Args` is a set of maximum key value followed by valid predicates\n    for `Trie` template having `Key` as the type of keys.\n*/\ntemplate isValidArgsForTrie(Key, Args...)\n{\n    static if (Args.length > 1)\n    {\n        enum isValidArgsForTrie = isValidPrefixForTrie!(Key, Args)\n            || (isValidPrefixForTrie!(Key, Args[1..$]) && is(typeof(Args[0]) : Key));\n    }\n    else\n        enum isValidArgsForTrie = isValidPrefixForTrie!Args;\n}\n\n@property size_t sumOfIntegerTuple(ints...)()\n{\n    size_t count=0;\n    foreach (v; ints)\n        count += v;\n    return count;\n}\n\n/**\n    A shorthand for creating a custom multi-level fixed Trie\n    from a `CodepointSet`. `sizes` are numbers of bits per level,\n    with the most significant bits used first.\n\n    Note: The sum of `sizes` must be equal 21.\n\n    See_Also: $(LREF toTrie), which is even simpler.\n\n    Example:\n    ---\n    {\n        import std.stdio;\n        auto set = unicode(\"Number\");\n        auto trie = codepointSetTrie!(8, 5, 8)(set);\n        writeln(\"Input code points to test:\");\n        foreach (line; stdin.byLine)\n        {\n            int count=0;\n            foreach (dchar ch; line)\n                if (trie[ch])// is number\n                    count++;\n            writefln(\"Contains %d number code points.\", count);\n        }\n    }\n    ---\n*/\npublic template codepointSetTrie(sizes...)\nif (sumOfIntegerTuple!sizes == 21)\n{\n    auto codepointSetTrie(Set)(Set set)\n        if (isCodepointSet!Set)\n    {\n        auto builder = TrieBuilder!(bool, dchar, lastDchar+1, GetBitSlicing!(21, sizes))(false);\n        foreach (ival; set.byInterval)\n            builder.putRange(ival[0], ival[1], true);\n        return builder.build();\n    }\n}\n\n/// Type of Trie generated by codepointSetTrie function.\npublic template CodepointSetTrie(sizes...)\nif (sumOfIntegerTuple!sizes == 21)\n{\n    alias Prefix = GetBitSlicing!(21, sizes);\n    alias CodepointSetTrie = typeof(TrieBuilder!(bool, dchar, lastDchar+1, Prefix)(false).build());\n}\n\n/**\n    A slightly more general tool for building fixed `Trie`\n    for the Unicode data.\n\n    Specifically unlike `codepointSetTrie` it's allows creating mappings\n    of `dchar` to an arbitrary type `T`.\n\n    Note: Overload taking `CodepointSet`s will naturally convert\n    only to bool mapping `Trie`s.\n\n    CodepointTrie is the type of Trie as generated by codepointTrie function.\n*/\npublic template codepointTrie(T, sizes...)\nif (sumOfIntegerTuple!sizes == 21)\n{\n    alias Prefix = GetBitSlicing!(21, sizes);\n\n    static if (is(TypeOfBitPacked!T == bool))\n    {\n        auto codepointTrie(Set)(const scope Set set)\n            if (isCodepointSet!Set)\n        {\n            return codepointSetTrie(set);\n        }\n    }\n\n    ///\n    auto codepointTrie()(T[dchar] map, T defValue=T.init)\n    {\n        return buildTrie!(T, dchar, Prefix)(map, defValue);\n    }\n\n    // unsorted range of pairs\n    ///\n    auto codepointTrie(R)(R range, T defValue=T.init)\n        if (isInputRange!R\n            && is(typeof(ElementType!R.init[0]) : T)\n            && is(typeof(ElementType!R.init[1]) : dchar))\n    {\n        // build from unsorted array of pairs\n        // TODO: expose index sorting functions for Trie\n        return buildTrie!(T, dchar, Prefix)(range, defValue, true);\n    }\n}\n\n@system pure unittest\n{\n    import std.algorithm.comparison : max;\n    import std.algorithm.searching : count;\n\n    // pick characters from the Greek script\n    auto set = unicode.Greek;\n\n    // a user-defined property (or an expensive function)\n    // that we want to look up\n    static uint luckFactor(dchar ch)\n    {\n        // here we consider a character lucky\n        // if its code point has a lot of identical hex-digits\n        // e.g. arabic letter DDAL (\\u0688) has a \"luck factor\" of 2\n        ubyte[6] nibbles; // 6 4-bit chunks of code point\n        uint value = ch;\n        foreach (i; 0 .. 6)\n        {\n            nibbles[i] = value & 0xF;\n            value >>= 4;\n        }\n        uint luck;\n        foreach (n; nibbles)\n            luck = cast(uint) max(luck, count(nibbles[], n));\n        return luck;\n    }\n\n    // only unsigned built-ins are supported at the moment\n    alias LuckFactor = BitPacked!(uint, 3);\n\n    // create a temporary associative array (AA)\n    LuckFactor[dchar] map;\n    foreach (ch; set.byCodepoint)\n        map[ch] = LuckFactor(luckFactor(ch));\n\n    // bits per stage are chosen randomly, fell free to optimize\n    auto trie = codepointTrie!(LuckFactor, 8, 5, 8)(map);\n\n    // from now on the AA is not needed\n    foreach (ch; set.byCodepoint)\n        assert(trie[ch] == luckFactor(ch)); // verify\n    // CJK is not Greek, thus it has the default value\n    assert(trie['\\u4444'] == 0);\n    // and here is a couple of quite lucky Greek characters:\n    // Greek small letter epsilon with dasia\n    assert(trie['\\u1F11'] == 3);\n    // Ancient Greek metretes sign\n    assert(trie['\\U00010181'] == 3);\n\n}\n\n/// ditto\npublic template CodepointTrie(T, sizes...)\nif (sumOfIntegerTuple!sizes == 21)\n{\n    alias Prefix = GetBitSlicing!(21, sizes);\n    alias CodepointTrie = typeof(TrieBuilder!(T, dchar, lastDchar+1, Prefix)(T.init).build());\n}\n\npackage template cmpK0(alias Pred)\n{\n    import std.typecons : Tuple;\n    static bool cmpK0(Value, Key)\n        (Tuple!(Value, Key) a, Tuple!(Value, Key) b)\n    {\n        return Pred(a[1]) < Pred(b[1]);\n    }\n}\n\n/**\n    The most general utility for construction of `Trie`s\n    short of using `TrieBuilder` directly.\n\n    Provides a number of convenience overloads.\n    `Args` is tuple of maximum key value followed by\n    predicates to construct index from key.\n\n    Alternatively if the first argument is not a value convertible to `Key`\n    then the whole tuple of `Args` is treated as predicates\n    and the maximum Key is deduced from predicates.\n*/\nprivate template buildTrie(Value, Key, Args...)\nif (isValidArgsForTrie!(Key, Args))\n{\n    static if (is(typeof(Args[0]) : Key)) // prefix starts with upper bound on Key\n    {\n        alias Prefix = Args[1..$];\n    }\n    else\n        alias Prefix = Args;\n\n    alias getIndex = mapTrieIndex!(Prefix);\n\n    // for multi-sort\n    template GetComparators(size_t n)\n    {\n        static if (n > 0)\n            alias GetComparators =\n                AliasSeq!(GetComparators!(n-1), cmpK0!(Prefix[n-1]));\n        else\n            alias GetComparators = AliasSeq!();\n    }\n\n    /*\n        Build `Trie` from a range of a Key-Value pairs,\n        assuming it is sorted by Key as defined by the following lambda:\n        ------\n        (a, b) => mapTrieIndex!(Prefix)(a) < mapTrieIndex!(Prefix)(b)\n        ------\n        Exception is thrown if it's detected that the above order doesn't hold.\n\n        In other words $(LREF mapTrieIndex) should be a\n        monotonically increasing function that maps `Key` to an integer.\n\n        See_Also: $(REF sort, std,_algorithm),\n        $(REF SortedRange, std,range),\n        $(REF setUnion, std,_algorithm).\n    */\n    auto buildTrie(Range)(Range range, Value filler=Value.init)\n        if (isInputRange!Range && is(typeof(Range.init.front[0]) : Value)\n            && is(typeof(Range.init.front[1]) : Key))\n    {\n        auto builder = TrieBuilder!(Value, Key, Prefix)(filler);\n        foreach (v; range)\n            builder.putValue(v[1], v[0]);\n        return builder.build();\n    }\n\n    /*\n        If `Value` is bool (or BitPacked!(bool, x)) then it's possible\n        to build `Trie` from a range of open-right intervals of `Key`s.\n        The requirement  on the ordering of keys (and the behavior on the\n        violation of it) is the same as for Key-Value range overload.\n\n        Intervals denote ranges of !`filler` i.e. the opposite of filler.\n        If no filler provided keys inside of the intervals map to true,\n        and `filler` is false.\n    */\n    auto buildTrie(Range)(Range range, Value filler=Value.init)\n        if (is(TypeOfBitPacked!Value ==  bool)\n            && isInputRange!Range && is(typeof(Range.init.front[0]) : Key)\n            && is(typeof(Range.init.front[1]) : Key))\n    {\n        auto builder = TrieBuilder!(Value, Key, Prefix)(filler);\n        foreach (ival; range)\n            builder.putRange(ival[0], ival[1], !filler);\n        return builder.build();\n    }\n\n    auto buildTrie(Range)(Range range, Value filler, bool unsorted)\n        if (isInputRange!Range\n            && is(typeof(Range.init.front[0]) : Value)\n            && is(typeof(Range.init.front[1]) : Key))\n    {\n        import std.algorithm.sorting : multiSort;\n        alias Comps = GetComparators!(Prefix.length);\n        if (unsorted)\n            multiSort!(Comps)(range);\n        return buildTrie(range, filler);\n    }\n\n    /*\n        If `Value` is bool (or BitPacked!(bool, x)) then it's possible\n        to build `Trie` simply from an input range of `Key`s.\n        The requirement  on the ordering of keys (and the behavior on the\n        violation of it) is the same as for Key-Value range overload.\n\n        Keys found in range denote !`filler` i.e. the opposite of filler.\n        If no filler provided keys map to true, and `filler` is false.\n    */\n    auto buildTrie(Range)(Range range, Value filler=Value.init)\n        if (is(TypeOfBitPacked!Value ==  bool)\n            && isInputRange!Range && is(typeof(Range.init.front) : Key))\n    {\n        auto builder = TrieBuilder!(Value, Key, Prefix)(filler);\n        foreach (v; range)\n            builder.putValue(v, !filler);\n        return builder.build();\n    }\n\n    /*\n        If `Key` is unsigned integer `Trie` could be constructed from array\n        of values where array index serves as key.\n    */\n    auto buildTrie()(Value[] array, Value filler=Value.init)\n        if (isUnsigned!Key)\n    {\n        auto builder = TrieBuilder!(Value, Key, Prefix)(filler);\n        foreach (idx, v; array)\n            builder.putValue(idx, v);\n        return builder.build();\n    }\n\n    /*\n        Builds `Trie` from associative array.\n    */\n    auto buildTrie(Key, Value)(Value[Key] map, Value filler=Value.init)\n    {\n        import std.array : array;\n        import std.range : zip;\n        auto range = array(zip(map.values, map.keys));\n        return buildTrie(range, filler, true); // sort it\n    }\n}\n\n// helper in place of assumeSize to\n//reduce mangled name & help DMD inline Trie functors\nstruct clamp(size_t bits)\n{\n    static size_t opCall(T)(T arg){ return arg; }\n    enum bitSize = bits;\n}\n\nstruct clampIdx(size_t idx, size_t bits)\n{\n    static size_t opCall(T)(T arg){ return arg[idx]; }\n    enum bitSize = bits;\n}\n\n/**\n    Conceptual type that outlines the common properties of all UTF Matchers.\n\n    Note: For illustration purposes only, every method\n    call results in assertion failure.\n    Use $(LREF utfMatcher) to obtain a concrete matcher\n    for UTF-8 or UTF-16 encodings.\n*/\npublic struct MatcherConcept\n{\n    /**\n        $(P Perform a semantic equivalent 2 operations:\n        decoding a $(CODEPOINT) at front of `inp` and testing if\n        it belongs to the set of $(CODEPOINTS) of this matcher. )\n\n        $(P The effect on `inp` depends on the kind of function called:)\n\n        $(P Match. If the codepoint is found in the set then range `inp`\n        is advanced by its size in $(S_LINK Code unit, code units),\n        otherwise the range is not modifed.)\n\n        $(P Skip. The range is always advanced by the size\n        of the tested $(CODEPOINT) regardless of the result of test.)\n\n        $(P Test. The range is left unaffected regardless\n        of the result of test.)\n    */\n    public bool match(Range)(ref Range inp)\n        if (isRandomAccessRange!Range && is(ElementType!Range : char))\n    {\n       assert(false);\n    }\n\n    ///ditto\n    public bool skip(Range)(ref Range inp)\n        if (isRandomAccessRange!Range && is(ElementType!Range : char))\n    {\n        assert(false);\n    }\n\n    ///ditto\n    public bool test(Range)(ref Range inp)\n        if (isRandomAccessRange!Range && is(ElementType!Range : char))\n    {\n        assert(false);\n    }\n    ///\n    pure @safe unittest\n    {\n        string truth = \"2² = 4\";\n        auto m = utfMatcher!char(unicode.Number);\n        assert(m.match(truth)); // '2' is a number all right\n        assert(truth == \"² = 4\"); // skips on match\n        assert(m.match(truth)); // so is the superscript '2'\n        assert(!m.match(truth)); // space is not a number\n        assert(truth == \" = 4\"); // unaffected on no match\n        assert(!m.skip(truth)); // same test ...\n        assert(truth == \"= 4\"); // but skips a codepoint regardless\n        assert(!m.test(truth)); // '=' is not a number\n        assert(truth == \"= 4\"); // test never affects argument\n    }\n\n    /**\n        Advanced feature - provide direct access to a subset of matcher based a\n        set of known encoding lengths. Lengths are provided in\n        $(S_LINK Code unit, code units). The sub-matcher then may do less\n        operations per any `test`/`match`.\n\n        Use with care as the sub-matcher won't match\n        any $(CODEPOINTS) that have encoded length that doesn't belong\n        to the selected set of lengths. Also the sub-matcher object references\n        the parent matcher and must not be used past the liftetime\n        of the latter.\n\n        Another caveat of using sub-matcher is that skip is not available\n        preciesly because sub-matcher doesn't detect all lengths.\n    */\n    @property auto subMatcher(Lengths...)()\n    {\n        assert(0);\n        return this;\n    }\n\n    pure @safe unittest\n    {\n        auto m = utfMatcher!char(unicode.Number);\n        string square = \"2²\";\n        // about sub-matchers\n        assert(!m.subMatcher!(2,3,4).test(square)); // ASCII no covered\n        assert(m.subMatcher!1.match(square)); // ASCII-only, works\n        assert(!m.subMatcher!1.test(square)); // unicode '²'\n        assert(m.subMatcher!(2,3,4).match(square));  //\n        assert(square == \"\");\n        wstring wsquare = \"2²\";\n        auto m16 = utfMatcher!wchar(unicode.Number);\n        // may keep ref, but the orignal (m16) must be kept alive\n        auto bmp = m16.subMatcher!1;\n        assert(bmp.match(wsquare)); // Okay, in basic multilingual plan\n        assert(bmp.match(wsquare)); // And '²' too\n    }\n}\n\n/**\n    Test if `M` is an UTF Matcher for ranges of `Char`.\n*/\npublic enum isUtfMatcher(M, C) = __traits(compiles, (){\n    C[] s;\n    auto d = s.decoder;\n    M m;\n    assert(is(typeof(m.match(d)) == bool));\n    assert(is(typeof(m.test(d)) == bool));\n    static if (is(typeof(m.skip(d))))\n    {\n        assert(is(typeof(m.skip(d)) == bool));\n        assert(is(typeof(m.skip(s)) == bool));\n    }\n    assert(is(typeof(m.match(s)) == bool));\n    assert(is(typeof(m.test(s)) == bool));\n});\n\npure @safe unittest\n{\n    alias CharMatcher = typeof(utfMatcher!char(CodepointSet.init));\n    alias WcharMatcher = typeof(utfMatcher!wchar(CodepointSet.init));\n    static assert(isUtfMatcher!(CharMatcher, char));\n    static assert(isUtfMatcher!(CharMatcher, immutable(char)));\n    static assert(isUtfMatcher!(WcharMatcher, wchar));\n    static assert(isUtfMatcher!(WcharMatcher, immutable(wchar)));\n}\n\nenum Mode {\n    alwaysSkip,\n    neverSkip,\n    skipOnMatch\n}\n\nmixin template ForwardStrings()\n{\n    private bool fwdStr(string fn, C)(ref C[] str) const @trusted\n    {\n        import std.utf : byCodeUnit;\n        alias type = typeof(byCodeUnit(str));\n        return mixin(fn~\"(*cast(type*)&str)\");\n    }\n}\n\ntemplate Utf8Matcher()\n{\n    enum validSize(int sz) = sz >= 1 && sz <= 4;\n\n    void badEncoding() pure @safe\n    {\n        import std.utf : UTFException;\n        throw new UTFException(\"Invalid UTF-8 sequence\");\n    }\n\n    //for 1-stage ASCII\n    alias AsciiSpec = AliasSeq!(bool, char, clamp!7);\n    //for 2-stage lookup of 2 byte UTF-8 sequences\n    alias Utf8Spec2 = AliasSeq!(bool, char[2],\n        clampIdx!(0, 5), clampIdx!(1, 6));\n    //ditto for 3 byte\n    alias Utf8Spec3 = AliasSeq!(bool, char[3],\n        clampIdx!(0, 4),\n        clampIdx!(1, 6),\n        clampIdx!(2, 6)\n    );\n    //ditto for 4 byte\n    alias Utf8Spec4 = AliasSeq!(bool, char[4],\n        clampIdx!(0, 3), clampIdx!(1, 6),\n        clampIdx!(2, 6), clampIdx!(3, 6)\n    );\n    alias Tables = AliasSeq!(\n        typeof(TrieBuilder!(AsciiSpec)(false).build()),\n        typeof(TrieBuilder!(Utf8Spec2)(false).build()),\n        typeof(TrieBuilder!(Utf8Spec3)(false).build()),\n        typeof(TrieBuilder!(Utf8Spec4)(false).build())\n    );\n    alias Table(int size) = Tables[size-1];\n\n    enum leadMask(size_t size) = (cast(size_t) 1<<(7 - size))-1;\n    enum encMask(size_t size) = ((1 << size)-1)<<(8-size);\n\n    char truncate()(char ch) pure @safe\n    {\n        ch -= 0x80;\n        if (ch < 0x40)\n        {\n            return ch;\n        }\n        else\n        {\n            badEncoding();\n            return cast(char) 0;\n        }\n    }\n\n    static auto encode(size_t sz)(dchar ch)\n        if (sz > 1)\n    {\n        import std.utf : encodeUTF = encode;\n        char[4] buf;\n        encodeUTF(buf, ch);\n        char[sz] ret;\n        buf[0] &= leadMask!sz;\n        foreach (n; 1 .. sz)\n            buf[n] = buf[n] & 0x3f; //keep 6 lower bits\n        ret[] = buf[0 .. sz];\n        return ret;\n    }\n\n    auto build(Set)(Set set)\n    {\n        import std.algorithm.iteration : map;\n        auto ascii = set & unicode.ASCII;\n        auto utf8_2 = set & CodepointSet(0x80, 0x800);\n        auto utf8_3 = set & CodepointSet(0x800, 0x1_0000);\n        auto utf8_4 = set & CodepointSet(0x1_0000, lastDchar+1);\n        auto asciiT = ascii.byCodepoint.map!(x=>cast(char) x).buildTrie!(AsciiSpec);\n        auto utf8_2T = utf8_2.byCodepoint.map!(x=>encode!2(x)).buildTrie!(Utf8Spec2);\n        auto utf8_3T = utf8_3.byCodepoint.map!(x=>encode!3(x)).buildTrie!(Utf8Spec3);\n        auto utf8_4T = utf8_4.byCodepoint.map!(x=>encode!4(x)).buildTrie!(Utf8Spec4);\n        alias Ret = Impl!(1,2,3,4);\n        return Ret(asciiT, utf8_2T, utf8_3T, utf8_4T);\n    }\n\n    // Bootstrap UTF-8 static matcher interface\n    // from 3 primitives: tab!(size), lookup and Sizes\n    mixin template DefMatcher()\n    {\n        import std.format : format;\n        import std.meta : Erase, staticIndexOf;\n        enum hasASCII = staticIndexOf!(1, Sizes) >= 0;\n        alias UniSizes = Erase!(1, Sizes);\n\n        //generate dispatch code sequence for unicode parts\n        static auto genDispatch()\n        {\n            string code;\n            foreach (size; UniSizes)\n                code ~= format(q{\n                    if ((ch & ~leadMask!%d) == encMask!(%d))\n                        return lookup!(%d, mode)(inp);\n                    else\n                }, size, size, size);\n            static if (Sizes.length == 4) //covers all code unit cases\n                code ~= \"{ badEncoding(); return false; }\";\n            else\n                code ~= \"return false;\"; //may be just fine but not covered\n            return code;\n        }\n        enum dispatch = genDispatch();\n\n        public bool match(Range)(ref Range inp) const\n            if (isRandomAccessRange!Range && is(ElementType!Range : char))\n        {\n            enum mode = Mode.skipOnMatch;\n            assert(!inp.empty);\n            immutable ch = inp[0];\n            static if (hasASCII)\n            {\n                if (ch < 0x80)\n                {\n                    immutable r = tab!1[ch];\n                    if (r)\n                        inp.popFront();\n                    return r;\n                }\n                else\n                    mixin(dispatch);\n            }\n            else\n                mixin(dispatch);\n        }\n\n        static if (Sizes.length == 4) // can skip iff can detect all encodings\n        {\n            public bool skip(Range)(ref Range inp) const\n                if (isRandomAccessRange!Range && is(ElementType!Range : char))\n            {\n                enum mode = Mode.alwaysSkip;\n                assert(!inp.empty);\n                auto ch = inp[0];\n                static if (hasASCII)\n                {\n                    if (ch < 0x80)\n                    {\n                        inp.popFront();\n                        return tab!1[ch];\n                    }\n                    else\n                        mixin(dispatch);\n                }\n                else\n                    mixin(dispatch);\n            }\n        }\n\n        public bool test(Range)(ref Range inp) const\n            if (isRandomAccessRange!Range && is(ElementType!Range : char))\n        {\n            enum mode = Mode.neverSkip;\n            assert(!inp.empty);\n            auto ch = inp[0];\n            static if (hasASCII)\n            {\n                if (ch < 0x80)\n                    return tab!1[ch];\n                else\n                    mixin(dispatch);\n            }\n            else\n                mixin(dispatch);\n        }\n\n        bool match(C)(ref C[] str) const\n            if (isSomeChar!C)\n        {\n            return fwdStr!\"match\"(str);\n        }\n\n        bool skip(C)(ref C[] str) const\n            if (isSomeChar!C)\n        {\n            return fwdStr!\"skip\"(str);\n        }\n\n        bool test(C)(ref C[] str) const\n            if (isSomeChar!C)\n        {\n            return fwdStr!\"test\"(str);\n        }\n\n        mixin ForwardStrings;\n    }\n\n    struct Impl(Sizes...)\n    {\n        import std.meta : allSatisfy, staticMap;\n        static assert(allSatisfy!(validSize, Sizes),\n            \"Only lengths of 1, 2, 3 and 4 code unit are possible for UTF-8\");\n    private:\n        //pick tables for chosen sizes\n        alias OurTabs = staticMap!(Table, Sizes);\n        OurTabs tables;\n        mixin DefMatcher;\n        //static disptach helper UTF size ==> table\n        alias tab(int i) = tables[i - 1];\n\n        package @property CherryPick!(Impl, SizesToPick) subMatcher(SizesToPick...)()\n        {\n            return CherryPick!(Impl, SizesToPick)(&this);\n        }\n\n        bool lookup(int size, Mode mode, Range)(ref Range inp) const\n        {\n            if (inp.length < size)\n            {\n                badEncoding();\n                return false;\n            }\n            char[size] needle = void;\n            needle[0] = leadMask!size & inp[0];\n            static foreach (i; 1 .. size)\n            {\n                needle[i] = truncate(inp[i]);\n            }\n            //overlong encoding checks\n            static if (size == 2)\n            {\n                //0x80-0x7FF\n                //got 6 bits in needle[1], must use at least 8 bits\n                //must use at least 2 bits in needle[1]\n                if (needle[0] < 2) badEncoding();\n            }\n            else static if (size == 3)\n            {\n                //0x800-0xFFFF\n                //got 6 bits in needle[2], must use at least 12bits\n                //must use 6 bits in needle[1] or anything in needle[0]\n                if (needle[0] == 0 && needle[1] < 0x20) badEncoding();\n            }\n            else static if (size == 4)\n            {\n                //0x800-0xFFFF\n                //got 2x6=12 bits in needle[2 .. 3] must use at least 17bits\n                //must use 5 bits (or above) in needle[1] or anything in needle[0]\n                if (needle[0] == 0 && needle[1] < 0x10) badEncoding();\n            }\n            static if (mode == Mode.alwaysSkip)\n            {\n                inp.popFrontN(size);\n                return tab!size[needle];\n            }\n            else static if (mode == Mode.neverSkip)\n            {\n                return tab!size[needle];\n            }\n            else\n            {\n                static assert(mode == Mode.skipOnMatch);\n                if (tab!size[needle])\n                {\n                    inp.popFrontN(size);\n                    return true;\n                }\n                else\n                    return false;\n            }\n        }\n    }\n\n    struct CherryPick(I, Sizes...)\n    {\n        import std.meta : allSatisfy;\n        static assert(allSatisfy!(validSize, Sizes),\n            \"Only lengths of 1, 2, 3 and 4 code unit are possible for UTF-8\");\n    private:\n        I* m;\n        @property auto tab(int i)() const { return m.tables[i - 1]; }\n        bool lookup(int size, Mode mode, Range)(ref Range inp) const\n        {\n            return m.lookup!(size, mode)(inp);\n        }\n        mixin DefMatcher;\n    }\n}\n\ntemplate Utf16Matcher()\n{\n    enum validSize(int sz) = sz >= 1 && sz <= 2;\n\n    void badEncoding() pure @safe\n    {\n        import std.utf : UTFException;\n        throw new UTFException(\"Invalid UTF-16 sequence\");\n    }\n\n    // 1-stage ASCII\n    alias AsciiSpec = AliasSeq!(bool, wchar, clamp!7);\n    //2-stage BMP\n    alias BmpSpec = AliasSeq!(bool, wchar, sliceBits!(7, 16), sliceBits!(0, 7));\n    //4-stage - full Unicode\n    //assume that 0xD800 & 0xDC00 bits are cleared\n    //thus leaving 10 bit per wchar to worry about\n    alias UniSpec = AliasSeq!(bool, wchar[2],\n        assumeSize!(x=>x[0]>>4, 6), assumeSize!(x=>x[0]&0xf, 4),\n        assumeSize!(x=>x[1]>>6, 4), assumeSize!(x=>x[1]&0x3f, 6),\n    );\n    alias Ascii = typeof(TrieBuilder!(AsciiSpec)(false).build());\n    alias Bmp = typeof(TrieBuilder!(BmpSpec)(false).build());\n    alias Uni = typeof(TrieBuilder!(UniSpec)(false).build());\n\n    auto encode2(dchar ch)\n    {\n        ch -= 0x1_0000;\n        assert(ch <= 0xF_FFFF);\n        wchar[2] ret;\n        //do not put surrogate bits, they are sliced off\n        ret[0] = cast(wchar)(ch >> 10);\n        ret[1] = (ch & 0xFFF);\n        return ret;\n    }\n\n    auto build(Set)(Set set)\n    {\n        import std.algorithm.iteration : map;\n        auto ascii = set & unicode.ASCII;\n        auto bmp = (set & CodepointSet.fromIntervals(0x80, 0xFFFF+1))\n            - CodepointSet.fromIntervals(0xD800, 0xDFFF+1);\n        auto other = set - (bmp | ascii);\n        auto asciiT = ascii.byCodepoint.map!(x=>cast(char) x).buildTrie!(AsciiSpec);\n        auto bmpT = bmp.byCodepoint.map!(x=>cast(wchar) x).buildTrie!(BmpSpec);\n        auto otherT = other.byCodepoint.map!(x=>encode2(x)).buildTrie!(UniSpec);\n        alias Ret = Impl!(1,2);\n        return Ret(asciiT, bmpT, otherT);\n    }\n\n    //bootstrap full UTF-16 matcher interace from\n    //sizeFlags, lookupUni and ascii\n    mixin template DefMatcher()\n    {\n        public bool match(Range)(ref Range inp) const\n            if (isRandomAccessRange!Range && is(ElementType!Range : wchar))\n        {\n            enum mode = Mode.skipOnMatch;\n            assert(!inp.empty);\n            immutable ch = inp[0];\n            static if (sizeFlags & 1)\n            {\n                if (ch < 0x80)\n                {\n                  if (ascii[ch])\n                  {\n                      inp.popFront();\n                      return true;\n                  }\n                  else\n                      return false;\n                }\n                return lookupUni!mode(inp);\n            }\n            else\n                return lookupUni!mode(inp);\n        }\n\n        static if (Sizes.length == 2)\n        {\n            public bool skip(Range)(ref Range inp) const\n                if (isRandomAccessRange!Range && is(ElementType!Range : wchar))\n            {\n                enum mode = Mode.alwaysSkip;\n                assert(!inp.empty);\n                immutable ch = inp[0];\n                static if (sizeFlags & 1)\n                {\n                    if (ch < 0x80)\n                    {\n                        inp.popFront();\n                        return ascii[ch];\n                    }\n                    else\n                        return lookupUni!mode(inp);\n                }\n                else\n                    return lookupUni!mode(inp);\n            }\n        }\n\n        public bool test(Range)(ref Range inp) const\n            if (isRandomAccessRange!Range && is(ElementType!Range : wchar))\n        {\n            enum mode = Mode.neverSkip;\n            assert(!inp.empty);\n            auto ch = inp[0];\n            static if (sizeFlags & 1)\n                return ch < 0x80 ? ascii[ch] : lookupUni!mode(inp);\n            else\n                return lookupUni!mode(inp);\n        }\n\n        bool match(C)(ref C[] str) const\n            if (isSomeChar!C)\n        {\n            return fwdStr!\"match\"(str);\n        }\n\n        bool skip(C)(ref C[] str) const\n            if (isSomeChar!C)\n        {\n            return fwdStr!\"skip\"(str);\n        }\n\n        bool test(C)(ref C[] str) const\n            if (isSomeChar!C)\n        {\n            return fwdStr!\"test\"(str);\n        }\n\n        mixin ForwardStrings; //dispatch strings to range versions\n    }\n\n    struct Impl(Sizes...)\n        if (Sizes.length >= 1 && Sizes.length <= 2)\n    {\n    private:\n        import std.meta : allSatisfy;\n        static assert(allSatisfy!(validSize, Sizes),\n            \"Only lengths of 1 and 2 code units are possible in UTF-16\");\n        static if (Sizes.length > 1)\n            enum sizeFlags = Sizes[0] | Sizes[1];\n        else\n            enum sizeFlags = Sizes[0];\n\n        static if (sizeFlags & 1)\n        {\n            Ascii ascii;\n            Bmp bmp;\n        }\n        static if (sizeFlags & 2)\n        {\n            Uni uni;\n        }\n        mixin DefMatcher;\n\n        package @property CherryPick!(Impl, SizesToPick) subMatcher(SizesToPick...)()\n        {\n            return CherryPick!(Impl, SizesToPick)(&this);\n        }\n\n        bool lookupUni(Mode mode, Range)(ref Range inp) const\n        {\n            wchar x = cast(wchar)(inp[0] - 0xD800);\n            //not a high surrogate\n            if (x > 0x3FF)\n            {\n                //low surrogate\n                if (x <= 0x7FF) badEncoding();\n                static if (sizeFlags & 1)\n                {\n                    auto ch = inp[0];\n                    static if (mode == Mode.alwaysSkip)\n                        inp.popFront();\n                    static if (mode == Mode.skipOnMatch)\n                    {\n                        if (bmp[ch])\n                        {\n                            inp.popFront();\n                            return true;\n                        }\n                        else\n                            return false;\n                    }\n                    else\n                        return bmp[ch];\n                }\n                else //skip is not available for sub-matchers, so just false\n                    return false;\n            }\n            else\n            {\n                static if (sizeFlags & 2)\n                {\n                    if (inp.length < 2)\n                        badEncoding();\n                    wchar y = cast(wchar)(inp[1] - 0xDC00);\n                    //not a low surrogate\n                    if (y > 0x3FF)\n                        badEncoding();\n                    wchar[2] needle = [inp[0] & 0x3ff, inp[1] & 0x3ff];\n                    static if (mode == Mode.alwaysSkip)\n                        inp.popFrontN(2);\n                    static if (mode == Mode.skipOnMatch)\n                    {\n                        if (uni[needle])\n                        {\n                            inp.popFrontN(2);\n                            return true;\n                        }\n                        else\n                            return false;\n                    }\n                    else\n                        return uni[needle];\n                }\n                else //ditto\n                    return false;\n            }\n        }\n    }\n\n    struct CherryPick(I, Sizes...)\n        if (Sizes.length >= 1 && Sizes.length <= 2)\n    {\n    private:\n        import std.meta : allSatisfy;\n        I* m;\n        enum sizeFlags = I.sizeFlags;\n\n        static if (sizeFlags & 1)\n        {\n            @property auto ascii()() const { return m.ascii; }\n        }\n\n        bool lookupUni(Mode mode, Range)(ref Range inp) const\n        {\n            return m.lookupUni!mode(inp);\n        }\n        mixin DefMatcher;\n        static assert(allSatisfy!(validSize, Sizes),\n            \"Only lengths of 1 and 2 code units are possible in UTF-16\");\n    }\n}\n\nprivate auto utf8Matcher(Set)(Set set)\n{\n    return Utf8Matcher!().build(set);\n}\n\nprivate auto utf16Matcher(Set)(Set set)\n{\n    return Utf16Matcher!().build(set);\n}\n\n/**\n    Constructs a matcher object\n    to classify $(CODEPOINTS) from the `set` for encoding\n    that has `Char` as code unit.\n\n    See $(LREF MatcherConcept) for API outline.\n*/\npublic auto utfMatcher(Char, Set)(Set set)\nif (isCodepointSet!Set)\n{\n    static if (is(Char : char))\n        return utf8Matcher(set);\n    else static if (is(Char : wchar))\n        return utf16Matcher(set);\n    else static if (is(Char : dchar))\n        static assert(false, \"UTF-32 needs no decoding,\n            and thus not supported by utfMatcher\");\n    else\n        static assert(false, \"Only character types 'char' and 'wchar' are allowed\");\n}\n\n\n//a range of code units, packed with index to speed up forward iteration\npackage auto decoder(C)(C[] s, size_t offset=0)\nif (is(C : wchar) || is(C : char))\n{\n    static struct Decoder\n    {\n    pure nothrow:\n        C[] str;\n        size_t idx;\n        @property C front(){ return str[idx]; }\n        @property C back(){ return str[$-1]; }\n        void popFront(){ idx++; }\n        void popBack(){ str = str[0..$-1]; }\n        void popFrontN(size_t n){ idx += n; }\n        @property bool empty(){ return idx == str.length; }\n        @property auto save(){ return this; }\n        auto opIndex(size_t i){ return str[idx+i]; }\n        @property size_t length(){ return str.length - idx; }\n        alias opDollar = length;\n        auto opSlice(size_t a, size_t b){ return Decoder(str[0 .. idx+b], idx+a); }\n    }\n    static assert(isRandomAccessRange!Decoder);\n    static assert(is(ElementType!Decoder : C));\n    return Decoder(s, offset);\n}\n\npure @safe unittest\n{\n    string rs = \"hi! ﾈемног砀 текста\";\n    auto codec = rs.decoder;\n    auto utf8 =  utf8Matcher(unicode.Letter);\n    auto asc = utf8.subMatcher!(1);\n    auto uni = utf8.subMatcher!(2,3,4);\n    assert(asc.test(codec));\n    assert(!uni.match(codec));\n    assert(utf8.skip(codec));\n    assert(codec.idx == 1);\n\n    assert(!uni.match(codec));\n    assert(asc.test(codec));\n    assert(utf8.skip(codec));\n    assert(codec.idx == 2);\n    assert(!asc.match(codec));\n\n    assert(!utf8.test(codec));\n    assert(!utf8.skip(codec));\n\n    assert(!asc.test(codec));\n    assert(!utf8.test(codec));\n    assert(!utf8.skip(codec));\n    assert(utf8.test(codec));\n    foreach (i; 0 .. 7)\n    {\n        assert(!asc.test(codec));\n        assert(uni.test(codec));\n        assert(utf8.skip(codec));\n    }\n    assert(!utf8.test(codec));\n    assert(!utf8.skip(codec));\n    //the same with match where applicable\n    codec = rs.decoder;\n    assert(utf8.match(codec));\n    assert(codec.idx == 1);\n    assert(utf8.match(codec));\n    assert(codec.idx == 2);\n    assert(!utf8.match(codec));\n    assert(codec.idx == 2);\n    assert(!utf8.skip(codec));\n    assert(!utf8.skip(codec));\n\n    foreach (i; 0 .. 7)\n    {\n        assert(!asc.test(codec));\n        assert(utf8.test(codec));\n        assert(utf8.match(codec));\n    }\n    auto i = codec.idx;\n    assert(!utf8.match(codec));\n    assert(codec.idx == i);\n}\n\npure @safe unittest\n{\n    import std.range : stride;\n    static bool testAll(Matcher, Range)(scope ref Matcher m, ref Range r)\n    {\n        bool t = m.test(r);\n        auto save = r.idx;\n        assert(t == m.match(r));\n        assert(r.idx == save || t); //ether no change or was match\n        r.idx = save;\n        static if (is(typeof(m.skip(r))))\n        {\n            assert(t == m.skip(r));\n            assert(r.idx != save); //always changed\n            r.idx = save;\n        }\n        return t;\n    }\n    auto utf16 = utfMatcher!wchar(unicode.L);\n    auto bmp = utf16.subMatcher!1;\n    auto nonBmp = utf16.subMatcher!1;\n    auto utf8 = utfMatcher!char(unicode.L);\n    auto ascii = utf8.subMatcher!1;\n    auto uni2 = utf8.subMatcher!2;\n    auto uni3 = utf8.subMatcher!3;\n    auto uni24 = utf8.subMatcher!(2,4);\n    foreach (ch; unicode.L.byCodepoint.stride(3))\n    {\n        import std.utf : encode;\n        char[4] buf;\n        wchar[2] buf16;\n        auto len = encode(buf, ch);\n        auto len16 = encode(buf16, ch);\n        auto c8 = buf[0 .. len].decoder;\n        auto c16 = buf16[0 .. len16].decoder;\n        assert(testAll(utf16, c16));\n        assert(testAll(bmp, c16) || len16 != 1);\n        assert(testAll(nonBmp, c16) || len16 != 2);\n\n        assert(testAll(utf8, c8));\n\n        //submatchers return false on out of their domain\n        assert(testAll(ascii, c8) || len != 1);\n        assert(testAll(uni2, c8) || len != 2);\n        assert(testAll(uni3, c8) || len != 3);\n        assert(testAll(uni24, c8) || (len != 2 && len != 4));\n    }\n}\n\n// cover decode fail cases of Matcher\npure @system unittest\n{\n    import std.algorithm.iteration : map;\n    import std.exception : collectException;\n    import std.format : format;\n    auto utf16 = utfMatcher!wchar(unicode.L);\n    auto utf8 = utfMatcher!char(unicode.L);\n    //decode failure cases UTF-8\n    alias fails8 = AliasSeq!(\"\\xC1\", \"\\x80\\x00\",\"\\xC0\\x00\", \"\\xCF\\x79\",\n        \"\\xFF\\x00\\0x00\\0x00\\x00\", \"\\xC0\\0x80\\0x80\\x80\", \"\\x80\\0x00\\0x00\\x00\",\n        \"\\xCF\\x00\\0x00\\0x00\\x00\");\n    foreach (msg; fails8)\n    {\n        assert(collectException((){\n            auto s = msg;\n            size_t idx = 0;\n            utf8.test(s);\n        }()), format(\"%( %2x %)\", cast(ubyte[]) msg));\n    }\n    //decode failure cases UTF-16\n    alias fails16 = AliasSeq!([0xD811], [0xDC02]);\n    foreach (msg; fails16)\n    {\n        assert(collectException((){\n            auto s = msg.map!(x => cast(wchar) x);\n            utf16.test(s);\n        }()));\n    }\n}\n\n/++\n    Convenience function to construct optimal configurations for\n    packed Trie from any `set` of $(CODEPOINTS).\n\n    The parameter `level` indicates the number of trie levels to use,\n    allowed values are: 1, 2, 3 or 4. Levels represent different trade-offs\n    speed-size wise.\n\n    $(P Level 1 is fastest and the most memory hungry (a bit array). )\n    $(P Level 4 is the slowest and has the smallest footprint. )\n\n    See the $(S_LINK Synopsis, Synopsis) section for example.\n\n    Note:\n    Level 4 stays very practical (being faster and more predictable)\n    compared to using direct lookup on the `set` itself.\n\n\n+/\npublic auto toTrie(size_t level, Set)(Set set)\nif (isCodepointSet!Set)\n{\n    static if (level == 1)\n        return codepointSetTrie!(21)(set);\n    else static if (level == 2)\n        return codepointSetTrie!(10, 11)(set);\n    else static if (level == 3)\n        return codepointSetTrie!(8, 5, 8)(set);\n    else static if (level == 4)\n         return codepointSetTrie!(6, 4, 4, 7)(set);\n    else\n        static assert(false,\n            \"Sorry, toTrie doesn't support levels > 4, use codepointSetTrie directly\");\n}\n\n/**\n    $(P Builds a `Trie` with typically optimal speed-size trade-off\n    and wraps it into a delegate of the following type:\n    $(D bool delegate(dchar ch)). )\n\n    $(P Effectively this creates a 'tester' lambda suitable\n    for algorithms like std.algorithm.find that take unary predicates. )\n\n    See the $(S_LINK Synopsis, Synopsis) section for example.\n*/\npublic auto toDelegate(Set)(Set set)\nif (isCodepointSet!Set)\n{\n    // 3 is very small and is almost as fast as 2-level (due to CPU caches?)\n    auto t = toTrie!3(set);\n    return (dchar ch) => t[ch];\n}\n\n/**\n    $(P Opaque wrapper around unsigned built-in integers and\n    code unit (char/wchar/dchar) types.\n    Parameter `sz` indicates that the value is confined\n    to the range of [0, 2^^sz$(RPAREN). With this knowledge it can be\n    packed more tightly when stored in certain\n    data-structures like trie. )\n\n    Note:\n    $(P The $(D BitPacked!(T, sz)) is implicitly convertible to `T`\n    but not vise-versa. Users have to ensure the value fits in\n    the range required and use the `cast`\n    operator to perform the conversion.)\n*/\nstruct BitPacked(T, size_t sz)\nif (isIntegral!T || is(T:dchar))\n{\n    enum bitSize = sz;\n    T _value;\n    alias _value this;\n}\n\n/*\n    Depending on the form of the passed argument `bitSizeOf` returns\n    the amount of bits required to represent a given type\n    or a return type of a given functor.\n*/\ntemplate bitSizeOf(Args...)\nif (Args.length == 1)\n{\n    import std.traits : ReturnType;\n    alias T = Args[0];\n    static if (__traits(compiles, { size_t val = T.bitSize; })) //(is(typeof(T.bitSize) : size_t))\n    {\n        enum bitSizeOf = T.bitSize;\n    }\n    else static if (is(ReturnType!T dummy == BitPacked!(U, bits), U, size_t bits))\n    {\n        enum bitSizeOf = bitSizeOf!(ReturnType!T);\n    }\n    else\n    {\n        enum bitSizeOf = T.sizeof*8;\n    }\n}\n\n/**\n    Tests if `T` is some instantiation of $(LREF BitPacked)!(U, x)\n    and thus suitable for packing.\n*/\ntemplate isBitPacked(T)\n{\n    static if (is(T dummy == BitPacked!(U, bits), U, size_t bits))\n        enum isBitPacked = true;\n    else\n        enum isBitPacked = false;\n}\n\n/**\n    Gives the type `U` from $(LREF BitPacked)!(U, x)\n    or `T` itself for every other type.\n*/\ntemplate TypeOfBitPacked(T)\n{\n    static if (is(T dummy == BitPacked!(U, bits), U, size_t bits))\n        alias TypeOfBitPacked = U;\n    else\n        alias TypeOfBitPacked = T;\n}\n\n/*\n    Wrapper, used in definition of custom data structures from `Trie` template.\n    Applying it to a unary lambda function indicates that the returned value always\n    fits within `bits` of bits.\n*/\nstruct assumeSize(alias Fn, size_t bits)\n{\n    enum bitSize = bits;\n    static auto ref opCall(T)(auto ref T arg)\n    {\n        return Fn(arg);\n    }\n}\n\n/*\n    A helper for defining lambda function that yields a slice\n    of certain bits from an unsigned integral value.\n    The resulting lambda is wrapped in assumeSize and can be used directly\n    with `Trie` template.\n*/\nstruct sliceBits(size_t from, size_t to)\n{\n    //for now bypass assumeSize, DMD has trouble inlining it\n    enum bitSize = to-from;\n    static auto opCall(T)(T x)\n    out(result)\n    {\n        assert(result < (1 << to-from));\n    }\n    do\n    {\n        static assert(from < to);\n        static if (from == 0)\n            return x & ((1 << to)-1);\n        else\n        return (x >> from) & ((1<<(to-from))-1);\n    }\n}\n\n@safe pure nothrow @nogc uint low_8(uint x) { return x&0xFF; }\n@safe pure nothrow @nogc uint midlow_8(uint x){ return (x&0xFF00)>>8; }\nalias lo8 = assumeSize!(low_8, 8);\nalias mlo8 = assumeSize!(midlow_8, 8);\n\nstatic assert(bitSizeOf!lo8 == 8);\nstatic assert(bitSizeOf!(sliceBits!(4, 7)) == 3);\nstatic assert(bitSizeOf!(BitPacked!(uint, 2)) == 2);\n\ntemplate Sequence(size_t start, size_t end)\n{\n    static if (start < end)\n        alias Sequence = AliasSeq!(start, Sequence!(start+1, end));\n    else\n        alias Sequence = AliasSeq!();\n}\n\n//---- TRIE TESTS ----\n@system unittest\n{\n    import std.algorithm.iteration : map;\n    import std.algorithm.sorting : sort;\n    import std.array : array;\n    import std.conv : text, to;\n    import std.range : iota;\n    static trieStats(TRIE)(TRIE t)\n    {\n        version (std_uni_stats)\n        {\n            import std.stdio : writefln, writeln;\n            writeln(\"---TRIE FOOTPRINT STATS---\");\n            static foreach (i; 0 .. t.table.dim)\n            {\n                writefln(\"lvl%s = %s bytes;  %s pages\"\n                         , i, t.bytes!i, t.pages!i);\n            }\n            writefln(\"TOTAL: %s bytes\", t.bytes);\n            version (none)\n            {\n                writeln(\"INDEX (excluding value level):\");\n                static foreach (i; 0 .. t.table.dim-1)\n                    writeln(t.table.slice!(i)[0 .. t.table.length!i]);\n            }\n            writeln(\"---------------------------\");\n        }\n    }\n    //@@@BUG link failure, lambdas not found by linker somehow (in case of trie2)\n    // alias lo8   = assumeSize!(8, function (uint x) { return x&0xFF; });\n    // alias next8 = assumeSize!(7, function (uint x) { return (x&0x7F00)>>8; });\n    alias Set = CodepointSet;\n    auto set = Set('A','Z','a','z');\n    auto trie = buildTrie!(bool, uint, 256, lo8)(set.byInterval);// simple bool array\n    for (int a='a'; a<'z';a++)\n        assert(trie[a]);\n    for (int a='A'; a<'Z';a++)\n        assert(trie[a]);\n    for (int a=0; a<'A'; a++)\n        assert(!trie[a]);\n    for (int a ='Z'; a<'a'; a++)\n        assert(!trie[a]);\n    trieStats(trie);\n\n    auto redundant2 = Set(\n        1, 18, 256+2, 256+111, 512+1, 512+18, 768+2, 768+111);\n    auto trie2 = buildTrie!(bool, uint, 1024, mlo8, lo8)(redundant2.byInterval);\n    trieStats(trie2);\n    foreach (e; redundant2.byCodepoint)\n        assert(trie2[e], text(cast(uint) e, \" - \", trie2[e]));\n    foreach (i; 0 .. 1024)\n    {\n        assert(trie2[i] == (i in redundant2));\n    }\n\n\n    auto redundant3 = Set(\n          2,    4,    6,    8,    16,\n       2+16, 4+16, 16+6, 16+8, 16+16,\n       2+32, 4+32, 32+6, 32+8,\n      );\n\n    enum max3 = 256;\n    // sliceBits\n    auto trie3 = buildTrie!(bool, uint, max3,\n            sliceBits!(6,8), sliceBits!(4,6), sliceBits!(0,4)\n        )(redundant3.byInterval);\n    trieStats(trie3);\n    foreach (i; 0 .. max3)\n        assert(trie3[i] == (i in redundant3), text(cast(uint) i));\n\n    auto redundant4 = Set(\n            10, 64, 64+10, 128, 128+10, 256, 256+10, 512,\n            1000, 2000, 3000, 4000, 5000, 6000\n        );\n    enum max4 = 2^^16;\n    auto trie4 = buildTrie!(bool, size_t, max4,\n            sliceBits!(13, 16), sliceBits!(9, 13), sliceBits!(6, 9) , sliceBits!(0, 6)\n        )(redundant4.byInterval);\n    foreach (i; 0 .. max4)\n    {\n        if (i in redundant4)\n            assert(trie4[i], text(cast(uint) i));\n    }\n    trieStats(trie4);\n\n        alias mapToS = mapTrieIndex!(useItemAt!(0, char));\n        string[] redundantS = [\"tea\", \"start\", \"orange\"];\n        redundantS.sort!((a,b) => mapToS(a) < mapToS(b))();\n        auto strie = buildTrie!(bool, string, useItemAt!(0, char))(redundantS);\n        // using first char only\n        assert(redundantS == [\"orange\", \"start\", \"tea\"]);\n        assert(strie[\"test\"], text(strie[\"test\"]));\n        assert(!strie[\"aea\"]);\n        assert(strie[\"s\"]);\n\n    // a bit size test\n    auto a = array(map!(x => to!ubyte(x))(iota(0, 256)));\n    auto bt = buildTrie!(bool, ubyte, sliceBits!(7, 8), sliceBits!(5, 7), sliceBits!(0, 5))(a);\n    trieStats(bt);\n    foreach (i; 0 .. 256)\n        assert(bt[cast(ubyte) i]);\n}\n\ntemplate useItemAt(size_t idx, T)\nif (isIntegral!T || is(T: dchar))\n{\n    size_t impl(const scope T[] arr){ return arr[idx]; }\n    alias useItemAt = assumeSize!(impl, 8*T.sizeof);\n}\n\ntemplate useLastItem(T)\n{\n    size_t impl(const scope T[] arr){ return arr[$-1]; }\n    alias useLastItem = assumeSize!(impl, 8*T.sizeof);\n}\n\ntemplate fullBitSize(Prefix...)\n{\n    static if (Prefix.length > 0)\n        enum fullBitSize = bitSizeOf!(Prefix[0])+fullBitSize!(Prefix[1..$]);\n    else\n        enum fullBitSize = 0;\n}\n\ntemplate idxTypes(Key, size_t fullBits, Prefix...)\n{\n    static if (Prefix.length == 1)\n    {// the last level is value level, so no index once reduced to 1-level\n        alias idxTypes = AliasSeq!();\n    }\n    else\n    {\n        // Important note on bit packing\n        // Each level has to hold enough of bits to address the next one\n        // The bottom level is known to hold full bit width\n        // thus it's size in pages is full_bit_width - size_of_last_prefix\n        // Recourse on this notion\n        alias idxTypes =\n            AliasSeq!(\n                idxTypes!(Key, fullBits - bitSizeOf!(Prefix[$-1]), Prefix[0..$-1]),\n                BitPacked!(typeof(Prefix[$-2](Key.init)), fullBits - bitSizeOf!(Prefix[$-1]))\n            );\n    }\n}\n\n//============================================================================\n\n@safe pure int comparePropertyName(Char1, Char2)(const(Char1)[] a, const(Char2)[] b)\nif (is(Char1 : dchar) && is(Char2 : dchar))\n{\n    import std.algorithm.comparison : cmp;\n    import std.algorithm.iteration : map, filter;\n    import std.ascii : toLower;\n    static bool pred(dchar c) {return !c.isWhite && c != '-' && c != '_';}\n    return cmp(\n        a.map!toLower.filter!pred,\n        b.map!toLower.filter!pred);\n}\n\n@safe pure unittest\n{\n    assert(!comparePropertyName(\"foo-bar\", \"fooBar\"));\n}\n\nbool propertyNameLess(Char1, Char2)(const(Char1)[] a, const(Char2)[] b) @safe pure\nif (is(Char1 : dchar) && is(Char2 : dchar))\n{\n    return comparePropertyName(a, b) < 0;\n}\n\n//============================================================================\n// Utilities for compression of Unicode code point sets\n//============================================================================\n\n@safe void compressTo(uint val, ref ubyte[] arr) pure nothrow\n{\n    // not optimized as usually done 1 time (and not public interface)\n    if (val < 128)\n        arr ~= cast(ubyte) val;\n    else if (val < (1 << 13))\n    {\n        arr ~= (0b1_00 << 5) | cast(ubyte)(val >> 8);\n        arr ~= val & 0xFF;\n    }\n    else\n    {\n        assert(val < (1 << 21));\n        arr ~= (0b1_01 << 5) | cast(ubyte)(val >> 16);\n        arr ~= (val >> 8) & 0xFF;\n        arr ~= val  & 0xFF;\n    }\n}\n\n@safe uint decompressFrom(const(ubyte)[] arr, ref size_t idx) pure\n{\n    import std.exception : enforce;\n    immutable first = arr[idx++];\n    if (!(first & 0x80)) // no top bit -> [0 .. 127]\n        return first;\n    immutable extra = ((first >> 5) & 1) + 1; // [1, 2]\n    uint val = (first & 0x1F);\n    enforce(idx + extra <= arr.length, \"bad code point interval encoding\");\n    foreach (j; 0 .. extra)\n        val = (val << 8) | arr[idx+j];\n    idx += extra;\n    return val;\n}\n\n\npackage ubyte[] compressIntervals(Range)(Range intervals)\nif (isInputRange!Range && isIntegralPair!(ElementType!Range))\n{\n    ubyte[] storage;\n    uint base = 0;\n    // RLE encode\n    foreach (val; intervals)\n    {\n        compressTo(val[0]-base, storage);\n        base = val[0];\n        if (val[1] != lastDchar+1) // till the end of the domain so don't store it\n        {\n            compressTo(val[1]-base, storage);\n            base = val[1];\n        }\n    }\n    return storage;\n}\n\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.typecons : tuple;\n\n    auto run = [tuple(80, 127), tuple(128, (1 << 10)+128)];\n    ubyte[] enc = [cast(ubyte) 80, 47, 1, (0b1_00 << 5) | (1 << 2), 0];\n    assert(compressIntervals(run) == enc);\n    auto run2 = [tuple(0, (1 << 20)+512+1), tuple((1 << 20)+512+4, lastDchar+1)];\n    ubyte[] enc2 = [cast(ubyte) 0, (0b1_01 << 5) | (1 << 4), 2, 1, 3]; // odd length-ed\n    assert(compressIntervals(run2) == enc2);\n    size_t  idx = 0;\n    assert(decompressFrom(enc, idx) == 80);\n    assert(decompressFrom(enc, idx) == 47);\n    assert(decompressFrom(enc, idx) == 1);\n    assert(decompressFrom(enc, idx) == (1 << 10));\n    idx = 0;\n    assert(decompressFrom(enc2, idx) == 0);\n    assert(decompressFrom(enc2, idx) == (1 << 20)+512+1);\n    assert(equal(decompressIntervals(compressIntervals(run)), run));\n    assert(equal(decompressIntervals(compressIntervals(run2)), run2));\n}\n\n// Creates a range of `CodepointInterval` that lazily decodes compressed data.\n@safe package auto decompressIntervals(const(ubyte)[] data) pure\n{\n    return DecompressedIntervals(data);\n}\n\n@safe struct DecompressedIntervals\n{\npure:\n    const(ubyte)[] _stream;\n    size_t _idx;\n    CodepointInterval _front;\n\n    this(const(ubyte)[] stream)\n    {\n        _stream = stream;\n        popFront();\n    }\n\n    @property CodepointInterval front()\n    {\n        assert(!empty);\n        return _front;\n    }\n\n    void popFront()\n    {\n        if (_idx == _stream.length)\n        {\n            _idx = size_t.max;\n            return;\n        }\n        uint base = _front[1];\n        _front[0] = base + decompressFrom(_stream, _idx);\n        if (_idx == _stream.length)// odd length ---> till the end\n            _front[1] = lastDchar+1;\n        else\n        {\n            base = _front[0];\n            _front[1] = base + decompressFrom(_stream, _idx);\n        }\n    }\n\n    @property bool empty() const\n    {\n        return _idx == size_t.max;\n    }\n\n    @property DecompressedIntervals save() { return this; }\n}\n\nstatic assert(isInputRange!DecompressedIntervals);\nstatic assert(isForwardRange!DecompressedIntervals);\n//============================================================================\n\nversion (std_uni_bootstrap){}\nelse\n{\n\n// helper for looking up code point sets\nptrdiff_t findUnicodeSet(alias table, C)(const scope C[] name)\n{\n    import std.algorithm.iteration : map;\n    import std.range : assumeSorted;\n    auto range = assumeSorted!((a,b) => propertyNameLess(a,b))\n        (table.map!\"a.name\"());\n    size_t idx = range.lowerBound(name).length;\n    if (idx < range.length && comparePropertyName(range[idx], name) == 0)\n        return idx;\n    return -1;\n}\n\n// another one that loads it\nbool loadUnicodeSet(alias table, Set, C)(const scope C[] name, ref Set dest)\n{\n    auto idx = findUnicodeSet!table(name);\n    if (idx >= 0)\n    {\n        dest = Set(asSet(table[idx].compressed));\n        return true;\n    }\n    return false;\n}\n\nbool loadProperty(Set=CodepointSet, C)\n    (const scope C[] name, ref Set target) pure\n{\n    import std.internal.unicode_tables : uniProps; // generated file\n    alias ucmp = comparePropertyName;\n    // conjure cumulative properties by hand\n    if (ucmp(name, \"L\") == 0 || ucmp(name, \"Letter\") == 0)\n    {\n        target = asSet(uniProps.Lu);\n        target |= asSet(uniProps.Ll);\n        target |= asSet(uniProps.Lt);\n        target |= asSet(uniProps.Lo);\n        target |= asSet(uniProps.Lm);\n    }\n    else if (ucmp(name,\"LC\") == 0 || ucmp(name,\"Cased Letter\")==0)\n    {\n        target = asSet(uniProps.Ll);\n        target |= asSet(uniProps.Lu);\n        target |= asSet(uniProps.Lt);// Title case\n    }\n    else if (ucmp(name, \"M\") == 0 || ucmp(name, \"Mark\") == 0)\n    {\n        target = asSet(uniProps.Mn);\n        target |= asSet(uniProps.Mc);\n        target |= asSet(uniProps.Me);\n    }\n    else if (ucmp(name, \"N\") == 0 || ucmp(name, \"Number\") == 0)\n    {\n        target = asSet(uniProps.Nd);\n        target |= asSet(uniProps.Nl);\n        target |= asSet(uniProps.No);\n    }\n    else if (ucmp(name, \"P\") == 0 || ucmp(name, \"Punctuation\") == 0)\n    {\n        target = asSet(uniProps.Pc);\n        target |= asSet(uniProps.Pd);\n        target |= asSet(uniProps.Ps);\n        target |= asSet(uniProps.Pe);\n        target |= asSet(uniProps.Pi);\n        target |= asSet(uniProps.Pf);\n        target |= asSet(uniProps.Po);\n    }\n    else if (ucmp(name, \"S\") == 0 || ucmp(name, \"Symbol\") == 0)\n    {\n        target = asSet(uniProps.Sm);\n        target |= asSet(uniProps.Sc);\n        target |= asSet(uniProps.Sk);\n        target |= asSet(uniProps.So);\n    }\n    else if (ucmp(name, \"Z\") == 0 || ucmp(name, \"Separator\") == 0)\n    {\n        target = asSet(uniProps.Zs);\n        target |= asSet(uniProps.Zl);\n        target |= asSet(uniProps.Zp);\n    }\n    else if (ucmp(name, \"C\") == 0 || ucmp(name, \"Other\") == 0)\n    {\n        target = asSet(uniProps.Co);\n        target |= asSet(uniProps.Lo);\n        target |= asSet(uniProps.No);\n        target |= asSet(uniProps.So);\n        target |= asSet(uniProps.Po);\n    }\n    else if (ucmp(name, \"graphical\") == 0)\n    {\n        target = asSet(uniProps.Alphabetic);\n\n        target |= asSet(uniProps.Mn);\n        target |= asSet(uniProps.Mc);\n        target |= asSet(uniProps.Me);\n\n        target |= asSet(uniProps.Nd);\n        target |= asSet(uniProps.Nl);\n        target |= asSet(uniProps.No);\n\n        target |= asSet(uniProps.Pc);\n        target |= asSet(uniProps.Pd);\n        target |= asSet(uniProps.Ps);\n        target |= asSet(uniProps.Pe);\n        target |= asSet(uniProps.Pi);\n        target |= asSet(uniProps.Pf);\n        target |= asSet(uniProps.Po);\n\n        target |= asSet(uniProps.Zs);\n\n        target |= asSet(uniProps.Sm);\n        target |= asSet(uniProps.Sc);\n        target |= asSet(uniProps.Sk);\n        target |= asSet(uniProps.So);\n    }\n    else if (ucmp(name, \"any\") == 0)\n        target = Set.fromIntervals(0, 0x110000);\n    else if (ucmp(name, \"ascii\") == 0)\n        target = Set.fromIntervals(0, 0x80);\n    else\n        return loadUnicodeSet!(uniProps.tab)(name, target);\n    return true;\n}\n\n// CTFE-only helper for checking property names at compile-time\n@safe bool isPrettyPropertyName(C)(const scope C[] name)\n{\n    import std.algorithm.searching : find;\n    auto names = [\n        \"L\", \"Letter\",\n        \"LC\", \"Cased Letter\",\n        \"M\", \"Mark\",\n        \"N\", \"Number\",\n        \"P\", \"Punctuation\",\n        \"S\", \"Symbol\",\n        \"Z\", \"Separator\",\n        \"Graphical\",\n        \"any\",\n        \"ascii\"\n    ];\n    auto x = find!(x => comparePropertyName(x, name) == 0)(names);\n    return !x.empty;\n}\n\n// ditto, CTFE-only, not optimized\n@safe private static bool findSetName(alias table, C)(const scope C[] name)\n{\n    return findUnicodeSet!table(name) >= 0;\n}\n\ntemplate SetSearcher(alias table, string kind)\n{\n    /// Run-time checked search.\n    static auto opCall(C)(const scope C[] name)\n        if (is(C : dchar))\n    {\n        import std.conv : to;\n        CodepointSet set;\n        if (loadUnicodeSet!table(name, set))\n            return set;\n        throw new Exception(\"No unicode set for \"~kind~\" by name \"\n            ~name.to!string()~\" was found.\");\n    }\n    /// Compile-time checked search.\n    static @property auto opDispatch(string name)()\n    {\n        static if (findSetName!table(name))\n        {\n            CodepointSet set;\n            loadUnicodeSet!table(name, set);\n            return set;\n        }\n        else\n            static assert(false, \"No unicode set for \"~kind~\" by name \"\n                ~name~\" was found.\");\n    }\n}\n\n// Characters that need escaping in string posed as regular expressions\npackage alias Escapables = AliasSeq!('[', ']', '\\\\', '^', '$', '.', '|', '?', ',', '-',\n    ';', ':', '#', '&', '%', '/', '<', '>', '`',  '*', '+', '(', ')', '{', '}',  '~');\n\npackage CodepointSet memoizeExpr(string expr)()\n{\n    if (__ctfe)\n        return mixin(expr);\n    alias T = typeof(mixin(expr));\n    static T slot;\n    static bool initialized;\n    if (!initialized)\n    {\n        slot =  mixin(expr);\n        initialized = true;\n    }\n    return slot;\n}\n\n//property for \\w character class\npackage @property CodepointSet wordCharacter() @safe\n{\n    return memoizeExpr!(\"unicode.Alphabetic | unicode.Mn | unicode.Mc\n        | unicode.Me | unicode.Nd | unicode.Pc\")();\n}\n\n//basic stack, just in case it gets used anywhere else then Parser\npackage struct Stack(T)\n{\n@safe:\n    T[] data;\n    @property bool empty(){ return data.empty; }\n\n    @property size_t length(){ return data.length; }\n\n    void push(T val){ data ~= val;  }\n\n    @trusted T pop()\n    {\n        assert(!empty);\n        auto val = data[$ - 1];\n        data = data[0 .. $ - 1];\n        if (!__ctfe)\n            cast(void) data.assumeSafeAppend();\n        return val;\n    }\n\n    @property ref T top()\n    {\n        assert(!empty);\n        return data[$ - 1];\n    }\n}\n\n//test if a given string starts with hex number of maxDigit that's a valid codepoint\n//returns it's value and skips these maxDigit chars on success, throws on failure\npackage dchar parseUniHex(Range)(ref Range str, size_t maxDigit)\n{\n    import std.exception : enforce;\n    //std.conv.parse is both @system and bogus\n    uint val;\n    for (int k = 0; k < maxDigit; k++)\n    {\n        enforce(!str.empty, \"incomplete escape sequence\");\n        //accepts ascii only, so it's OK to index directly\n        immutable current = str.front;\n        if ('0' <= current && current <= '9')\n            val = val * 16 + current - '0';\n        else if ('a' <= current && current <= 'f')\n            val = val * 16 + current -'a' + 10;\n        else if ('A' <= current && current <= 'F')\n            val = val * 16 + current - 'A' + 10;\n        else\n            throw new Exception(\"invalid escape sequence\");\n        str.popFront();\n    }\n    enforce(val <= 0x10FFFF, \"invalid codepoint\");\n    return val;\n}\n\n@safe unittest\n{\n    import std.algorithm.searching : canFind;\n    import std.exception : collectException;\n    string[] non_hex = [ \"000j\", \"000z\", \"FffG\", \"0Z\"];\n    string[] hex = [ \"01\", \"ff\", \"00af\", \"10FFFF\" ];\n    int[] value = [ 1, 0xFF, 0xAF, 0x10FFFF ];\n    foreach (v; non_hex)\n        assert(collectException(parseUniHex(v, v.length)).msg\n          .canFind(\"invalid escape sequence\"));\n    foreach (i, v; hex)\n        assert(parseUniHex(v, v.length) == value[i]);\n    string over = \"0011FFFF\";\n    assert(collectException(parseUniHex(over, over.length)).msg\n      .canFind(\"invalid codepoint\"));\n}\n\nauto caseEnclose(CodepointSet set)\n{\n    auto cased = set & unicode.LC;\n    foreach (dchar ch; cased.byCodepoint)\n    {\n        foreach (c; simpleCaseFoldings(ch))\n            set |= c;\n    }\n    return set;\n}\n\n/+\n    fetch codepoint set corresponding to a name (InBlock or binary property)\n+/\nCodepointSet getUnicodeSet(const scope char[] name, bool negated,  bool casefold) @safe\n{\n    CodepointSet s = unicode(name);\n    //FIXME: caseEnclose for new uni as Set | CaseEnclose(SET && LC)\n    if (casefold)\n       s = caseEnclose(s);\n    if (negated)\n        s = s.inverted;\n    return s;\n}\n\nstruct UnicodeSetParser(Range)\n{\n    import std.exception : enforce;\n    import std.typecons : tuple, Tuple;\n    Range range;\n    bool casefold_;\n\n    @property bool empty(){ return range.empty; }\n    @property dchar front(){ return range.front; }\n    void popFront(){ range.popFront(); }\n\n    //CodepointSet operations relatively in order of priority\n    enum Operator:uint {\n        Open = 0, Negate,  Difference, SymDifference, Intersection, Union, None\n    }\n\n    //parse unit of CodepointSet spec, most notably escape sequences and char ranges\n    //also fetches next set operation\n    Tuple!(CodepointSet,Operator) parseCharTerm()\n    {\n        import std.range : drop;\n        enum privateUseStart = '\\U000F0000', privateUseEnd ='\\U000FFFFD';\n        enum State{ Start, Char, Escape, CharDash, CharDashEscape,\n            PotentialTwinSymbolOperator }\n        Operator op = Operator.None;\n        dchar last;\n        CodepointSet set;\n        State state = State.Start;\n\n        void addWithFlags(ref CodepointSet set, uint ch)\n        {\n            if (casefold_)\n            {\n                auto range = simpleCaseFoldings(ch);\n                foreach (v; range)\n                    set |= v;\n            }\n            else\n                set |= ch;\n        }\n\n        static Operator twinSymbolOperator(dchar symbol)\n        {\n            switch (symbol)\n            {\n            case '|':\n                return Operator.Union;\n            case '-':\n                return Operator.Difference;\n            case '~':\n                return Operator.SymDifference;\n            case '&':\n                return Operator.Intersection;\n            default:\n                assert(false);\n            }\n        }\n\n        L_CharTermLoop:\n        for (;;)\n        {\n            final switch (state)\n            {\n            case State.Start:\n                switch (front)\n                {\n                case '|':\n                case '-':\n                case '~':\n                case '&':\n                    state = State.PotentialTwinSymbolOperator;\n                    last = front;\n                    break;\n                case '[':\n                    op = Operator.Union;\n                    goto case;\n                case ']':\n                    break L_CharTermLoop;\n                case '\\\\':\n                    state = State.Escape;\n                    break;\n                default:\n                    state = State.Char;\n                    last = front;\n                }\n                break;\n            case State.Char:\n                // xxx last front xxx\n                switch (front)\n                {\n                case '|':\n                case '~':\n                case '&':\n                    // then last is treated as normal char and added as implicit union\n                    state = State.PotentialTwinSymbolOperator;\n                    addWithFlags(set, last);\n                    last = front;\n                    break;\n                case '-': // still need more info\n                    state = State.CharDash;\n                    break;\n                case '\\\\':\n                    set |= last;\n                    state = State.Escape;\n                    break;\n                case '[':\n                    op = Operator.Union;\n                    goto case;\n                case ']':\n                    addWithFlags(set, last);\n                    break L_CharTermLoop;\n                default:\n                    state = State.Char;\n                    addWithFlags(set, last);\n                    last = front;\n                }\n                break;\n            case State.PotentialTwinSymbolOperator:\n                // xxx last front xxxx\n                // where last = [|-&~]\n                if (front == last)\n                {\n                    op = twinSymbolOperator(last);\n                    popFront();//skip second twin char\n                    break L_CharTermLoop;\n                }\n                goto case State.Char;\n            case State.Escape:\n                // xxx \\ front xxx\n                switch (front)\n                {\n                case 'f':\n                    last = '\\f';\n                    state = State.Char;\n                    break;\n                case 'n':\n                    last = '\\n';\n                    state = State.Char;\n                    break;\n                case 'r':\n                    last = '\\r';\n                    state = State.Char;\n                    break;\n                case 't':\n                    last = '\\t';\n                    state = State.Char;\n                    break;\n                case 'v':\n                    last = '\\v';\n                    state = State.Char;\n                    break;\n                case 'c':\n                    last = unicode.parseControlCode(this);\n                    state = State.Char;\n                    break;\n                foreach (val; Escapables)\n                {\n                case val:\n                }\n                    last = front;\n                    state = State.Char;\n                    break;\n                case 'p':\n                    set.add(unicode.parsePropertySpec(this, false, casefold_));\n                    state = State.Start;\n                    continue L_CharTermLoop; //next char already fetched\n                case 'P':\n                    set.add(unicode.parsePropertySpec(this, true, casefold_));\n                    state = State.Start;\n                    continue L_CharTermLoop; //next char already fetched\n                case 'x':\n                    popFront();\n                    last = parseUniHex(this, 2);\n                    state = State.Char;\n                    continue L_CharTermLoop;\n                case 'u':\n                    popFront();\n                    last = parseUniHex(this, 4);\n                    state = State.Char;\n                    continue L_CharTermLoop;\n                case 'U':\n                    popFront();\n                    last = parseUniHex(this, 8);\n                    state = State.Char;\n                    continue L_CharTermLoop;\n                case 'd':\n                    set.add(unicode.Nd);\n                    state = State.Start;\n                    break;\n                case 'D':\n                    set.add(unicode.Nd.inverted);\n                    state = State.Start;\n                    break;\n                case 's':\n                    set.add(unicode.White_Space);\n                    state = State.Start;\n                    break;\n                case 'S':\n                    set.add(unicode.White_Space.inverted);\n                    state = State.Start;\n                    break;\n                case 'w':\n                    set.add(wordCharacter);\n                    state = State.Start;\n                    break;\n                case 'W':\n                    set.add(wordCharacter.inverted);\n                    state = State.Start;\n                    break;\n                default:\n                    if (front >= privateUseStart && front <= privateUseEnd)\n                        enforce(false, \"no matching ']' found while parsing character class\");\n                    enforce(false, \"invalid escape sequence\");\n                }\n                break;\n            case State.CharDash:\n                // xxx last - front xxx\n                switch (front)\n                {\n                case '[':\n                    op = Operator.Union;\n                    goto case;\n                case ']':\n                    //means dash is a single char not an interval specifier\n                    addWithFlags(set, last);\n                    addWithFlags(set, '-');\n                    break L_CharTermLoop;\n                 case '-'://set Difference again\n                    addWithFlags(set, last);\n                    op = Operator.Difference;\n                    popFront();//skip '-'\n                    break L_CharTermLoop;\n                case '\\\\':\n                    state = State.CharDashEscape;\n                    break;\n                default:\n                    enforce(last <= front, \"inverted range\");\n                    if (casefold_)\n                    {\n                        for (uint ch = last; ch <= front; ch++)\n                            addWithFlags(set, ch);\n                    }\n                    else\n                        set.add(last, front + 1);\n                    state = State.Start;\n                }\n                break;\n            case State.CharDashEscape:\n            //xxx last - \\ front xxx\n                uint end;\n                switch (front)\n                {\n                case 'f':\n                    end = '\\f';\n                    break;\n                case 'n':\n                    end = '\\n';\n                    break;\n                case 'r':\n                    end = '\\r';\n                    break;\n                case 't':\n                    end = '\\t';\n                    break;\n                case 'v':\n                    end = '\\v';\n                    break;\n                foreach (val; Escapables)\n                {\n                case val:\n                }\n                    end = front;\n                    break;\n                case 'c':\n                    end = unicode.parseControlCode(this);\n                    break;\n                case 'x':\n                    popFront();\n                    end = parseUniHex(this, 2);\n                    enforce(last <= end,\"inverted range\");\n                    set.add(last, end + 1);\n                    state = State.Start;\n                    continue L_CharTermLoop;\n                case 'u':\n                    popFront();\n                    end = parseUniHex(this, 4);\n                    enforce(last <= end,\"inverted range\");\n                    set.add(last, end + 1);\n                    state = State.Start;\n                    continue L_CharTermLoop;\n                case 'U':\n                    popFront();\n                    end = parseUniHex(this, 8);\n                    enforce(last <= end,\"inverted range\");\n                    set.add(last, end + 1);\n                    state = State.Start;\n                    continue L_CharTermLoop;\n                default:\n                    if (front >= privateUseStart && front <= privateUseEnd)\n                        enforce(false, \"no matching ']' found while parsing character class\");\n                    enforce(false, \"invalid escape sequence\");\n                }\n                // Lookahead to check if it's a \\T\n                // where T is sub-pattern terminator in multi-pattern scheme\n                auto lookahead = range.save.drop(1);\n                if (end == '\\\\' && !lookahead.empty)\n                {\n                    if (lookahead.front >= privateUseStart && lookahead.front <= privateUseEnd)\n                        enforce(false, \"no matching ']' found while parsing character class\");\n                }\n                enforce(last <= end,\"inverted range\");\n                set.add(last, end + 1);\n                state = State.Start;\n                break;\n            }\n            popFront();\n            enforce(!empty, \"unexpected end of CodepointSet\");\n        }\n        return tuple(set, op);\n    }\n\n    alias ValStack = Stack!(CodepointSet);\n    alias OpStack = Stack!(Operator);\n\n    CodepointSet parseSet()\n    {\n        ValStack vstack;\n        OpStack opstack;\n        import std.functional : unaryFun;\n        enforce(!empty, \"unexpected end of input\");\n        enforce(front == '[', \"expected '[' at the start of unicode set\");\n        //\n        static bool apply(Operator op, ref ValStack stack)\n        {\n            switch (op)\n            {\n            case Operator.Negate:\n                enforce(!stack.empty, \"no operand for '^'\");\n                stack.top = stack.top.inverted;\n                break;\n            case Operator.Union:\n                auto s = stack.pop();//2nd operand\n                enforce(!stack.empty, \"no operand for '||'\");\n                stack.top.add(s);\n                break;\n            case Operator.Difference:\n                auto s = stack.pop();//2nd operand\n                enforce(!stack.empty, \"no operand for '--'\");\n                stack.top.sub(s);\n                break;\n            case Operator.SymDifference:\n                auto s = stack.pop();//2nd operand\n                enforce(!stack.empty, \"no operand for '~~'\");\n                stack.top ~= s;\n                break;\n            case Operator.Intersection:\n                auto s = stack.pop();//2nd operand\n                enforce(!stack.empty, \"no operand for '&&'\");\n                stack.top.intersect(s);\n                break;\n            default:\n                return false;\n            }\n            return true;\n        }\n        static bool unrollWhile(alias cond)(ref ValStack vstack, ref OpStack opstack)\n        {\n            while (cond(opstack.top))\n            {\n                if (!apply(opstack.pop(),vstack))\n                    return false;//syntax error\n                if (opstack.empty)\n                    return false;\n            }\n            return true;\n        }\n\n        L_CharsetLoop:\n        do\n        {\n            switch (front)\n            {\n            case '[':\n                opstack.push(Operator.Open);\n                popFront();\n                enforce(!empty, \"unexpected end of character class\");\n                if (front == '^')\n                {\n                    opstack.push(Operator.Negate);\n                    popFront();\n                    enforce(!empty, \"unexpected end of character class\");\n                }\n                else if (front == ']') // []...] is special cased\n                {\n                    popFront();\n                    enforce(!empty, \"wrong character set\");\n                    auto pair = parseCharTerm();\n                    pair[0].add(']', ']'+1);\n                    if (pair[1] != Operator.None)\n                    {\n                        if (opstack.top == Operator.Union)\n                            unrollWhile!(unaryFun!\"a == a.Union\")(vstack, opstack);\n                        opstack.push(pair[1]);\n                    }\n                    vstack.push(pair[0]);\n                }\n                break;\n            case ']':\n                enforce(unrollWhile!(unaryFun!\"a != a.Open\")(vstack, opstack),\n                    \"character class syntax error\");\n                enforce(!opstack.empty, \"unmatched ']'\");\n                opstack.pop();\n                popFront();\n                if (opstack.empty)\n                    break L_CharsetLoop;\n                auto pair  = parseCharTerm();\n                if (!pair[0].empty)//not only operator e.g. -- or ~~\n                {\n                    vstack.top.add(pair[0]);//apply union\n                }\n                if (pair[1] != Operator.None)\n                {\n                    if (opstack.top == Operator.Union)\n                        unrollWhile!(unaryFun!\"a == a.Union\")(vstack, opstack);\n                    opstack.push(pair[1]);\n                }\n                break;\n            //\n            default://yet another pair of term(op)?\n                auto pair = parseCharTerm();\n                if (pair[1] != Operator.None)\n                {\n                    if (opstack.top == Operator.Union)\n                        unrollWhile!(unaryFun!\"a == a.Union\")(vstack, opstack);\n                    opstack.push(pair[1]);\n                }\n                vstack.push(pair[0]);\n            }\n\n        }while (!empty || !opstack.empty);\n        while (!opstack.empty)\n            apply(opstack.pop(),vstack);\n        assert(vstack.length == 1);\n        return vstack.top;\n    }\n}\n\n/**\n    A single entry point to lookup Unicode $(CODEPOINT) sets by name or alias of\n    a block, script or general category.\n\n    It uses well defined standard rules of property name lookup.\n    This includes fuzzy matching of names, so that\n    'White_Space', 'white-SpAce' and 'whitespace' are all considered equal\n    and yield the same set of white space $(CHARACTERS).\n*/\n@safe public struct unicode\n{\n    import std.exception : enforce;\n    /**\n        Performs the lookup of set of $(CODEPOINTS)\n        with compile-time correctness checking.\n        This short-cut version combines 3 searches:\n        across blocks, scripts, and common binary properties.\n\n        Note that since scripts and blocks overlap the\n        usual trick to disambiguate is used - to get a block use\n        `unicode.InBlockName`, to search a script\n        use `unicode.ScriptName`.\n\n        See_Also: $(LREF block), $(LREF script)\n        and (not included in this search) $(LREF hangulSyllableType).\n    */\n\n    static @property auto opDispatch(string name)() pure\n    {\n        static if (findAny(name))\n            return loadAny(name);\n        else\n            static assert(false, \"No unicode set by name \"~name~\" was found.\");\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.exception : collectException;\n        auto ascii = unicode.ASCII;\n        assert(ascii['A']);\n        assert(ascii['~']);\n        assert(!ascii['\\u00e0']);\n        // matching is case-insensitive\n        assert(ascii == unicode.ascII);\n        assert(!ascii['à']);\n        // underscores, '-' and whitespace in names are ignored too\n        auto latin = unicode.in_latin1_Supplement;\n        assert(latin['à']);\n        assert(!latin['$']);\n        // BTW Latin 1 Supplement is a block, hence \"In\" prefix\n        assert(latin == unicode(\"In Latin 1 Supplement\"));\n        // run-time look up throws if no such set is found\n        assert(collectException(unicode(\"InCyrilliac\")));\n    }\n\n    /**\n        The same lookup across blocks, scripts, or binary properties,\n        but performed at run-time.\n        This version is provided for cases where `name`\n        is not known beforehand; otherwise compile-time\n        checked $(LREF opDispatch) is typically a better choice.\n\n        See the $(S_LINK Unicode properties, table of properties) for available\n        sets.\n    */\n    static auto opCall(C)(const scope C[] name)\n        if (is(C : dchar))\n    {\n        return loadAny(name);\n    }\n\n    /**\n        Narrows down the search for sets of $(CODEPOINTS) to all Unicode blocks.\n\n        Note:\n        Here block names are unambiguous as no scripts are searched\n        and thus to search use simply `unicode.block.BlockName` notation.\n\n        See $(S_LINK Unicode properties, table of properties) for available sets.\n        See_Also: $(S_LINK Unicode properties, table of properties).\n    */\n    struct block\n    {\n        import std.internal.unicode_tables : blocks; // generated file\n        mixin SetSearcher!(blocks.tab, \"block\");\n    }\n\n    ///\n    @safe unittest\n    {\n        // use .block for explicitness\n        assert(unicode.block.Greek_and_Coptic == unicode.InGreek_and_Coptic);\n    }\n\n    /**\n        Narrows down the search for sets of $(CODEPOINTS) to all Unicode scripts.\n\n        See the $(S_LINK Unicode properties, table of properties) for available\n        sets.\n    */\n    struct script\n    {\n        import std.internal.unicode_tables : scripts; // generated file\n        mixin SetSearcher!(scripts.tab, \"script\");\n    }\n\n    ///\n    @safe unittest\n    {\n        auto arabicScript = unicode.script.arabic;\n        auto arabicBlock = unicode.block.arabic;\n        // there is an intersection between script and block\n        assert(arabicBlock['؁']);\n        assert(arabicScript['؁']);\n        // but they are different\n        assert(arabicBlock != arabicScript);\n        assert(arabicBlock == unicode.inArabic);\n        assert(arabicScript == unicode.arabic);\n    }\n\n    /**\n        Fetch a set of $(CODEPOINTS) that have the given hangul syllable type.\n\n        Other non-binary properties (once supported) follow the same\n        notation - `unicode.propertyName.propertyValue` for compile-time\n        checked access and `unicode.propertyName(propertyValue)`\n        for run-time checked one.\n\n        See the $(S_LINK Unicode properties, table of properties) for available\n        sets.\n    */\n    struct hangulSyllableType\n    {\n        import std.internal.unicode_tables : hangul; // generated file\n        mixin SetSearcher!(hangul.tab, \"hangul syllable type\");\n    }\n\n    ///\n    @safe unittest\n    {\n        // L here is syllable type not Letter as in unicode.L short-cut\n        auto leadingVowel = unicode.hangulSyllableType(\"L\");\n        // check that some leading vowels are present\n        foreach (vowel; '\\u1110'..'\\u115F')\n            assert(leadingVowel[vowel]);\n        assert(leadingVowel == unicode.hangulSyllableType.L);\n    }\n\n    //parse control code of form \\cXXX, c assumed to be the current symbol\n    static package dchar parseControlCode(Parser)(ref Parser p)\n    {\n        with(p)\n        {\n            popFront();\n            enforce(!empty, \"Unfinished escape sequence\");\n            enforce(('a' <= front && front <= 'z')\n                || ('A' <= front && front <= 'Z'),\n            \"Only letters are allowed after \\\\c\");\n            return front & 0x1f;\n        }\n    }\n\n    //parse and return a CodepointSet for \\p{...Property...} and \\P{...Property..},\n    //\\ - assumed to be processed, p - is current\n    static package CodepointSet parsePropertySpec(Range)(ref Range p,\n        bool negated, bool casefold)\n    {\n        static import std.ascii;\n        with(p)\n        {\n            enum MAX_PROPERTY = 128;\n            char[MAX_PROPERTY] result;\n            uint k = 0;\n            popFront();\n            enforce(!empty, \"eof parsing unicode property spec\");\n            if (front == '{')\n            {\n                popFront();\n                while (k < MAX_PROPERTY && !empty && front !='}'\n                    && front !=':')\n                {\n                    if (front != '-' && front != ' ' && front != '_')\n                        result[k++] = cast(char) std.ascii.toLower(front);\n                    popFront();\n                }\n                enforce(k != MAX_PROPERTY, \"invalid property name\");\n                enforce(front == '}', \"} expected \");\n            }\n            else\n            {//single char properties e.g.: \\pL, \\pN ...\n                enforce(front < 0x80, \"invalid property name\");\n                result[k++] = cast(char) front;\n            }\n            auto s = getUnicodeSet(result[0 .. k], negated, casefold);\n            enforce(!s.empty, \"unrecognized unicode property spec\");\n            popFront();\n            return s;\n        }\n    }\n\n    /**\n        Parse unicode codepoint set from given `range` using standard regex\n        syntax '[...]'. The range is advanced skiping over regex set definition.\n        `casefold` parameter determines if the set should be casefolded - that is\n        include both lower and upper case versions for any letters in the set.\n    */\n    static CodepointSet parseSet(Range)(ref Range range, bool casefold=false)\n    if (isInputRange!Range && is(ElementType!Range : dchar))\n    {\n        auto usParser = UnicodeSetParser!Range(range, casefold);\n        auto set = usParser.parseSet();\n        range = usParser.range;\n        return set;\n    }\n\n    ///\n    @safe unittest\n    {\n        import std.uni : unicode;\n        string pat = \"[a-zA-Z0-9]hello\";\n        auto set = unicode.parseSet(pat);\n        // check some of the codepoints\n        assert(set['a'] && set['A'] && set['9']);\n        assert(pat == \"hello\");\n    }\n\nprivate:\n    alias ucmp = comparePropertyName;\n\n    static bool findAny(string name)\n    {\n        import std.internal.unicode_tables : blocks, scripts, uniProps; // generated file\n        return isPrettyPropertyName(name)\n            || findSetName!(uniProps.tab)(name) || findSetName!(scripts.tab)(name)\n            || (ucmp(name[0 .. 2],\"In\") == 0 && findSetName!(blocks.tab)(name[2..$]));\n    }\n\n    static auto loadAny(Set=CodepointSet, C)(const scope C[] name) pure\n    {\n        import std.conv : to;\n        import std.internal.unicode_tables : blocks, scripts; // generated file\n        Set set;\n        immutable loaded = loadProperty(name, set) || loadUnicodeSet!(scripts.tab)(name, set)\n            || (name.length > 2 && ucmp(name[0 .. 2],\"In\") == 0\n                && loadUnicodeSet!(blocks.tab)(name[2..$], set));\n        if (loaded)\n            return set;\n        throw new Exception(\"No unicode set by name \"~name.to!string()~\" was found.\");\n    }\n\n    // FIXME: re-disable once the compiler is fixed\n    // Disabled to prevent the mistake of creating instances of this pseudo-struct.\n    //@disable ~this();\n}\n\n@safe unittest\n{\n    import std.internal.unicode_tables : blocks, uniProps; // generated file\n    assert(unicode(\"InHebrew\") == asSet(blocks.Hebrew));\n    assert(unicode(\"separator\") == (asSet(uniProps.Zs) | asSet(uniProps.Zl) | asSet(uniProps.Zp)));\n    assert(unicode(\"In-Kharoshthi\") == asSet(blocks.Kharoshthi));\n}\n\nenum EMPTY_CASE_TRIE = ushort.max;// from what gen_uni uses internally\n\n// control - '\\r'\nenum controlSwitch = `\n    case '\\u0000':..case '\\u0008':case '\\u000E':..case '\\u001F':case '\\u007F':..\n    case '\\u0084':case '\\u0086':..case '\\u009F': case '\\u0009':..case '\\u000C': case '\\u0085':\n`;\n// TODO: redo the most of hangul stuff algorithmically in case of Graphemes too\n// kill unrolled switches\n\nprivate static bool isRegionalIndicator(dchar ch) @safe pure @nogc nothrow\n{\n    return ch >= '\\U0001F1E6' && ch <= '\\U0001F1FF';\n}\n\ntemplate genericDecodeGrapheme(bool getValue)\n{\n    alias graphemeExtend = graphemeExtendTrie;\n    alias spacingMark = mcTrie;\n    static if (getValue)\n        alias Value = Grapheme;\n    else\n        alias Value = void;\n\n    Value genericDecodeGrapheme(Input)(ref Input range)\n    {\n        import std.internal.unicode_tables : isHangL, isHangT, isHangV; // generated file\n        enum GraphemeState {\n            Start,\n            CR,\n            RI,\n            L,\n            V,\n            LVT\n        }\n        static if (getValue)\n            Grapheme grapheme;\n        auto state = GraphemeState.Start;\n        enum eat = q{\n            static if (getValue)\n                grapheme ~= ch;\n            range.popFront();\n        };\n\n        dchar ch;\n        assert(!range.empty, \"Attempting to decode grapheme from an empty \" ~ Input.stringof);\n        while (!range.empty)\n        {\n            ch = range.front;\n            final switch (state) with(GraphemeState)\n            {\n            case Start:\n                mixin(eat);\n                if (ch == '\\r')\n                    state = CR;\n                else if (isRegionalIndicator(ch))\n                    state = RI;\n                else if (isHangL(ch))\n                    state = L;\n                else if (hangLV[ch] || isHangV(ch))\n                    state = V;\n                else if (hangLVT[ch])\n                    state = LVT;\n                else if (isHangT(ch))\n                    state = LVT;\n                else\n                {\n                    switch (ch)\n                    {\n                    mixin(controlSwitch);\n                        goto L_End;\n                    default:\n                        goto L_End_Extend;\n                    }\n                }\n            break;\n            case CR:\n                if (ch == '\\n')\n                    mixin(eat);\n                goto L_End_Extend;\n            case RI:\n                if (isRegionalIndicator(ch))\n                    mixin(eat);\n                else\n                    goto L_End_Extend;\n            break;\n            case L:\n                if (isHangL(ch))\n                    mixin(eat);\n                else if (isHangV(ch) || hangLV[ch])\n                {\n                    state = V;\n                    mixin(eat);\n                }\n                else if (hangLVT[ch])\n                {\n                    state = LVT;\n                    mixin(eat);\n                }\n                else\n                    goto L_End_Extend;\n            break;\n            case V:\n                if (isHangV(ch))\n                    mixin(eat);\n                else if (isHangT(ch))\n                {\n                    state = LVT;\n                    mixin(eat);\n                }\n                else\n                    goto L_End_Extend;\n            break;\n            case LVT:\n                if (isHangT(ch))\n                {\n                    mixin(eat);\n                }\n                else\n                    goto L_End_Extend;\n            break;\n            }\n        }\n    L_End_Extend:\n        while (!range.empty)\n        {\n            ch = range.front;\n            // extend & spacing marks\n            if (!graphemeExtend[ch] && !spacingMark[ch])\n                break;\n            mixin(eat);\n        }\n    L_End:\n        static if (getValue)\n            return grapheme;\n    }\n\n}\n\npublic: // Public API continues\n\n/++\n    Computes the length of grapheme cluster starting at `index`.\n    Both the resulting length and the `index` are measured\n    in $(S_LINK Code unit, code units).\n\n    Params:\n        C = type that is implicitly convertible to `dchars`\n        input = array of grapheme clusters\n        index = starting index into `input[]`\n\n    Returns:\n        length of grapheme cluster\n+/\nsize_t graphemeStride(C)(const scope C[] input, size_t index) @safe pure\nif (is(C : dchar))\n{\n    auto src = input[index..$];\n    auto n = src.length;\n    genericDecodeGrapheme!(false)(src);\n    return n - src.length;\n}\n\n///\n@safe unittest\n{\n    assert(graphemeStride(\"  \", 1) == 1);\n    // A + combing ring above\n    string city = \"A\\u030Arhus\";\n    size_t first = graphemeStride(city, 0);\n    assert(first == 3); //\\u030A has 2 UTF-8 code units\n    assert(city[0 .. first] == \"A\\u030A\");\n    assert(city[first..$] == \"rhus\");\n}\n\n@safe unittest\n{\n    // Ensure that graphemeStride is usable from CTFE.\n    enum c1 = graphemeStride(\"A\", 0);\n    static assert(c1 == 1);\n\n    enum c2 = graphemeStride(\"A\\u0301\", 0);\n    static assert(c2 == 3); // \\u0301 has 2 UTF-8 code units\n}\n\n/++\n    Reads one full grapheme cluster from an\n    $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of dchar `inp`.\n\n    For examples see the $(LREF Grapheme) below.\n\n    Note:\n    This function modifies `inp` and thus `inp`\n    must be an L-value.\n+/\nGrapheme decodeGrapheme(Input)(ref Input inp)\nif (isInputRange!Input && is(Unqual!(ElementType!Input) == dchar))\n{\n    return genericDecodeGrapheme!true(inp);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    Grapheme gr;\n    string s = \" \\u0020\\u0308 \";\n    gr = decodeGrapheme(s);\n    assert(gr.length == 1 && gr[0] == ' ');\n    gr = decodeGrapheme(s);\n    assert(gr.length == 2 && equal(gr[0 .. 2], \" \\u0308\"));\n    s = \"\\u0300\\u0308\\u1100\";\n    assert(equal(decodeGrapheme(s)[], \"\\u0300\\u0308\"));\n    assert(equal(decodeGrapheme(s)[], \"\\u1100\"));\n    s = \"\\u11A8\\u0308\\uAC01\";\n    assert(equal(decodeGrapheme(s)[], \"\\u11A8\\u0308\"));\n    assert(equal(decodeGrapheme(s)[], \"\\uAC01\"));\n}\n\n/++\n    $(P Iterate a string by $(LREF Grapheme).)\n\n    $(P Useful for doing string manipulation that needs to be aware\n    of graphemes.)\n\n    See_Also:\n        $(LREF byCodePoint)\n+/\nauto byGrapheme(Range)(Range range)\nif (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar))\n{\n    // TODO: Bidirectional access\n    static struct Result(R)\n    {\n        private R _range;\n        private Grapheme _front;\n\n        bool empty() @property\n        {\n            return _front.length == 0;\n        }\n\n        Grapheme front() @property\n        {\n            return _front;\n        }\n\n        void popFront()\n        {\n            _front = _range.empty ? Grapheme.init : _range.decodeGrapheme();\n        }\n\n        static if (isForwardRange!R)\n        {\n            Result save() @property\n            {\n                return Result(_range.save, _front);\n            }\n        }\n    }\n\n    auto result = Result!(Range)(range);\n    result.popFront();\n    return result;\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range.primitives : walkLength;\n    import std.range : take, drop;\n    auto text = \"noe\\u0308l\"; // noël using e + combining diaeresis\n    assert(text.walkLength == 5); // 5 code points\n\n    auto gText = text.byGrapheme;\n    assert(gText.walkLength == 4); // 4 graphemes\n\n    assert(gText.take(3).equal(\"noe\\u0308\".byGrapheme));\n    assert(gText.drop(3).equal(\"l\".byGrapheme));\n}\n\n// For testing non-forward-range input ranges\nversion (unittest)\nprivate static struct InputRangeString\n{\n    private string s;\n\n    bool empty() @property { return s.empty; }\n    dchar front() @property { return s.front; }\n    void popFront() { s.popFront(); }\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.array : array;\n    import std.range : retro;\n    import std.range.primitives : walkLength;\n    assert(\"\".byGrapheme.walkLength == 0);\n\n    auto reverse = \"le\\u0308on\";\n    assert(reverse.walkLength == 5);\n\n    auto gReverse = reverse.byGrapheme;\n    assert(gReverse.walkLength == 4);\n\n    static foreach (text; AliasSeq!(\"noe\\u0308l\"c, \"noe\\u0308l\"w, \"noe\\u0308l\"d))\n    {{\n        assert(text.walkLength == 5);\n        static assert(isForwardRange!(typeof(text)));\n\n        auto gText = text.byGrapheme;\n        static assert(isForwardRange!(typeof(gText)));\n        assert(gText.walkLength == 4);\n        assert(gText.array.retro.equal(gReverse));\n    }}\n\n    auto nonForwardRange = InputRangeString(\"noe\\u0308l\").byGrapheme;\n    static assert(!isForwardRange!(typeof(nonForwardRange)));\n    assert(nonForwardRange.walkLength == 4);\n}\n\n/++\n    $(P Lazily transform a range of $(LREF Grapheme)s to a range of code points.)\n\n    $(P Useful for converting the result to a string after doing operations\n    on graphemes.)\n\n    $(P If passed in a range of code points, returns a range with equivalent capabilities.)\n+/\nauto byCodePoint(Range)(Range range)\nif (isInputRange!Range && is(Unqual!(ElementType!Range) == Grapheme))\n{\n    // TODO: Propagate bidirectional access\n    static struct Result\n    {\n        private Range _range;\n        private size_t i = 0;\n\n        bool empty() @property\n        {\n            return _range.empty;\n        }\n\n        dchar front() @property\n        {\n            return _range.front[i];\n        }\n\n        void popFront()\n        {\n            ++i;\n\n            if (i >= _range.front.length)\n            {\n                _range.popFront();\n                i = 0;\n            }\n        }\n\n        static if (isForwardRange!Range)\n        {\n            Result save() @property\n            {\n                return Result(_range.save, i);\n            }\n        }\n    }\n\n    return Result(range);\n}\n\n/// Ditto\nauto byCodePoint(Range)(Range range)\nif (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar))\n{\n    static if (isNarrowString!Range)\n    {\n        static struct Result\n        {\n            private Range _range;\n            @property bool empty() { return _range.empty; }\n            @property dchar front(){ return _range.front; }\n            void popFront(){ _range.popFront; }\n            @property auto save() { return Result(_range.save); }\n            @property dchar back(){ return _range.back; }\n            void popBack(){ _range.popBack; }\n        }\n        static assert(isBidirectionalRange!(Result));\n        return Result(range);\n    }\n    else\n        return range;\n}\n\n///\n@safe unittest\n{\n    import std.array : array;\n    import std.conv : text;\n    import std.range : retro;\n\n    string s = \"noe\\u0308l\"; // noël\n\n    // reverse it and convert the result to a string\n    string reverse = s.byGrapheme\n        .array\n        .retro\n        .byCodePoint\n        .text;\n\n    assert(reverse == \"le\\u0308on\"); // lëon\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range.primitives : walkLength;\n    import std.range : retro;\n    assert(\"\".byGrapheme.byCodePoint.equal(\"\"));\n\n    string text = \"noe\\u0308l\";\n    static assert(!__traits(compiles, \"noe\\u0308l\".byCodePoint.length));\n\n    auto gText = InputRangeString(text).byGrapheme;\n    static assert(!isForwardRange!(typeof(gText)));\n\n    auto cpText = gText.byCodePoint;\n    static assert(!isForwardRange!(typeof(cpText)));\n\n    assert(cpText.walkLength == text.walkLength);\n\n    auto plainCp = text.byCodePoint;\n    static assert(isForwardRange!(typeof(plainCp)));\n    assert(equal(plainCp, text));\n    assert(equal(retro(plainCp.save), retro(text.save)));\n    // Check that we still have length for dstring\n    assert(\"абвгд\"d.byCodePoint.length == 5);\n}\n\n/++\n    $(P A structure designed to effectively pack $(CHARACTERS)\n    of a $(CLUSTER).\n    )\n\n    $(P `Grapheme` has value semantics so 2 copies of a `Grapheme`\n    always refer to distinct objects. In most actual scenarios a `Grapheme`\n    fits on the stack and avoids memory allocation overhead for all but quite\n    long clusters.\n    )\n\n    See_Also: $(LREF decodeGrapheme), $(LREF graphemeStride)\n+/\n@safe struct Grapheme\n{\n    import std.exception : enforce;\n    import std.traits : isDynamicArray;\n\npublic:\n    /// Ctor\n    this(C)(const scope C[] chars...)\n        if (is(C : dchar))\n    {\n        this ~= chars;\n    }\n\n    ///ditto\n    this(Input)(Input seq)\n        if (!isDynamicArray!Input\n            && isInputRange!Input && is(ElementType!Input : dchar))\n    {\n        this ~= seq;\n    }\n\n    /// Gets a $(CODEPOINT) at the given index in this cluster.\n    dchar opIndex(size_t index) const @nogc nothrow pure @trusted\n    {\n        assert(index < length);\n        return read24(isBig ? ptr_ : small_.ptr, index);\n    }\n\n    /++\n        Writes a $(CODEPOINT) `ch` at given index in this cluster.\n\n        Warning:\n        Use of this facility may invalidate grapheme cluster,\n        see also $(LREF Grapheme.valid).\n    +/\n    void opIndexAssign(dchar ch, size_t index) @nogc nothrow pure @trusted\n    {\n        assert(index < length);\n        write24(isBig ? ptr_ : small_.ptr, ch, index);\n    }\n\n    ///\n    @safe unittest\n    {\n        auto g = Grapheme(\"A\\u0302\");\n        assert(g[0] == 'A');\n        assert(g.valid);\n        g[1] = '~'; // ASCII tilda is not a combining mark\n        assert(g[1] == '~');\n        assert(!g.valid);\n    }\n\n    /++\n        Random-access range over Grapheme's $(CHARACTERS).\n\n        Warning: Invalidates when this Grapheme leaves the scope,\n        attempts to use it then would lead to memory corruption.\n    +/\n    SliceOverIndexed!Grapheme opSlice(size_t a, size_t b) @nogc nothrow pure return\n    {\n        return sliceOverIndexed(a, b, &this);\n    }\n\n    /// ditto\n    SliceOverIndexed!Grapheme opSlice() @nogc nothrow pure return\n    {\n        return sliceOverIndexed(0, length, &this);\n    }\n\n    /// Grapheme cluster length in $(CODEPOINTS).\n    @property size_t length() const @nogc nothrow pure\n    {\n        return isBig ? len_ : slen_ & 0x7F;\n    }\n\n    /++\n        Append $(CHARACTER) `ch` to this grapheme.\n        Warning:\n        Use of this facility may invalidate grapheme cluster,\n        see also `valid`.\n\n        See_Also: $(LREF Grapheme.valid)\n    +/\n    ref opOpAssign(string op)(dchar ch) @trusted\n    {\n        static if (op == \"~\")\n        {\n            import core.exception : onOutOfMemoryError;\n            import core.memory : pureRealloc;\n            if (!isBig)\n            {\n                if (slen_ == small_cap)\n                    convertToBig();// & fallthrough to \"big\" branch\n                else\n                {\n                    write24(small_.ptr, ch, smallLength);\n                    slen_++;\n                    return this;\n                }\n            }\n\n            assert(isBig);\n            if (len_ == cap_)\n            {\n                import core.checkedint : addu, mulu;\n                bool overflow;\n                cap_ = addu(cap_, grow, overflow);\n                auto nelems = mulu(3, addu(cap_, 1, overflow), overflow);\n                if (overflow) assert(0);\n                ptr_ = cast(ubyte*) pureRealloc(ptr_, nelems);\n                if (ptr_ is null) onOutOfMemoryError();\n            }\n            write24(ptr_, ch, len_++);\n            return this;\n        }\n        else\n            static assert(false, \"No operation \"~op~\" defined for Grapheme\");\n    }\n\n    ///\n    @system unittest\n    {\n        import std.algorithm.comparison : equal;\n        auto g = Grapheme(\"A\");\n        assert(g.valid);\n        g ~= '\\u0301';\n        assert(g[].equal(\"A\\u0301\"));\n        assert(g.valid);\n        g ~= \"B\";\n        // not a valid grapheme cluster anymore\n        assert(!g.valid);\n        // still could be useful though\n        assert(g[].equal(\"A\\u0301B\"));\n    }\n\n    /// Append all $(CHARACTERS) from the input range `inp` to this Grapheme.\n    ref opOpAssign(string op, Input)(scope Input inp)\n        if (isInputRange!Input && is(ElementType!Input : dchar))\n    {\n        static if (op == \"~\")\n        {\n            foreach (dchar ch; inp)\n                this ~= ch;\n            return this;\n        }\n        else\n            static assert(false, \"No operation \"~op~\" defined for Grapheme\");\n    }\n\n    /++\n        True if this object contains valid extended grapheme cluster.\n        Decoding primitives of this module always return a valid `Grapheme`.\n\n        Appending to and direct manipulation of grapheme's $(CHARACTERS) may\n        render it no longer valid. Certain applications may chose to use\n        Grapheme as a \"small string\" of any $(CODEPOINTS) and ignore this property\n        entirely.\n    +/\n    @property bool valid()() /*const*/\n    {\n        auto r = this[];\n        genericDecodeGrapheme!false(r);\n        return r.length == 0;\n    }\n\n    this(this) @nogc nothrow pure @trusted\n    {\n        import core.exception : onOutOfMemoryError;\n        import core.memory : pureMalloc;\n        if (isBig)\n        {// dup it\n            import core.checkedint : addu, mulu;\n            bool overflow;\n            auto raw_cap = mulu(3, addu(cap_, 1, overflow), overflow);\n            if (overflow) assert(0);\n\n            auto p = cast(ubyte*) pureMalloc(raw_cap);\n            if (p is null) onOutOfMemoryError();\n            p[0 .. raw_cap] = ptr_[0 .. raw_cap];\n            ptr_ = p;\n        }\n    }\n\n    ~this() @nogc nothrow pure @trusted\n    {\n        import core.memory : pureFree;\n        if (isBig)\n        {\n            pureFree(ptr_);\n        }\n    }\n\n\nprivate:\n    enum small_bytes = ((ubyte*).sizeof+3*size_t.sizeof-1);\n    // \"out of the blue\" grow rate, needs testing\n    // (though graphemes are typically small < 9)\n    enum grow = 20;\n    enum small_cap = small_bytes/3;\n    enum small_flag = 0x80, small_mask = 0x7F;\n    // 16 bytes in 32bits, should be enough for the majority of cases\n    union\n    {\n        struct\n        {\n            ubyte* ptr_;\n            size_t cap_;\n            size_t len_;\n            size_t padding_;\n        }\n        struct\n        {\n            ubyte[small_bytes] small_;\n            ubyte slen_;\n        }\n    }\n\n    void convertToBig() @nogc nothrow pure @trusted\n    {\n        import core.exception : onOutOfMemoryError;\n        import core.memory : pureMalloc;\n        static assert(grow.max / 3 - 1 >= grow);\n        enum nbytes = 3 * (grow + 1);\n        size_t k = smallLength;\n        ubyte* p = cast(ubyte*) pureMalloc(nbytes);\n        if (p is null) onOutOfMemoryError();\n        for (int i=0; i<k; i++)\n            write24(p, read24(small_.ptr, i), i);\n        // now we can overwrite small array data\n        ptr_ = p;\n        len_ = slen_;\n        assert(grow > len_);\n        cap_ = grow;\n        setBig();\n    }\n\n    void setBig() @nogc nothrow pure { slen_ |= small_flag; }\n\n    @property size_t smallLength() const @nogc nothrow pure\n    {\n        return slen_ & small_mask;\n    }\n    @property ubyte isBig() const @nogc nothrow pure\n    {\n        return slen_ & small_flag;\n    }\n}\n\nstatic assert(Grapheme.sizeof == size_t.sizeof*4);\n\n\n@system pure /*nothrow @nogc*/ unittest // TODO: string .front is GC and throw\n{\n    import std.algorithm.comparison : equal;\n    Grapheme[3] data = [Grapheme(\"Ю\"), Grapheme(\"У\"), Grapheme(\"З\")];\n    assert(byGrapheme(\"ЮУЗ\").equal(data[]));\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : filter;\n    import std.range : isRandomAccessRange;\n\n    string bold = \"ku\\u0308hn\";\n\n    // note that decodeGrapheme takes parameter by ref\n    auto first = decodeGrapheme(bold);\n\n    assert(first.length == 1);\n    assert(first[0] == 'k');\n\n    // the next grapheme is 2 characters long\n    auto wideOne = decodeGrapheme(bold);\n    // slicing a grapheme yields a random-access range of dchar\n    assert(wideOne[].equal(\"u\\u0308\"));\n    assert(wideOne.length == 2);\n    static assert(isRandomAccessRange!(typeof(wideOne[])));\n\n    // all of the usual range manipulation is possible\n    assert(wideOne[].filter!isMark().equal(\"\\u0308\"));\n\n    auto g = Grapheme(\"A\");\n    assert(g.valid);\n    g ~= '\\u0301';\n    assert(g[].equal(\"A\\u0301\"));\n    assert(g.valid);\n    g ~= \"B\";\n    // not a valid grapheme cluster anymore\n    assert(!g.valid);\n    // still could be useful though\n    assert(g[].equal(\"A\\u0301B\"));\n}\n\n@safe unittest\n{\n    auto g = Grapheme(\"A\\u0302\");\n    assert(g[0] == 'A');\n    assert(g.valid);\n    g[1] = '~'; // ASCII tilda is not a combining mark\n    assert(g[1] == '~');\n    assert(!g.valid);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.iteration : map;\n    import std.conv : text;\n    import std.range : iota;\n\n    // not valid clusters (but it just a test)\n    auto g  = Grapheme('a', 'b', 'c', 'd', 'e');\n    assert(g[0] == 'a');\n    assert(g[1] == 'b');\n    assert(g[2] == 'c');\n    assert(g[3] == 'd');\n    assert(g[4] == 'e');\n    g[3] = 'Й';\n    assert(g[2] == 'c');\n    assert(g[3] == 'Й', text(g[3], \" vs \", 'Й'));\n    assert(g[4] == 'e');\n    assert(!g.valid);\n\n    g ~= 'ц';\n    g ~= '~';\n    assert(g[0] == 'a');\n    assert(g[1] == 'b');\n    assert(g[2] == 'c');\n    assert(g[3] == 'Й');\n    assert(g[4] == 'e');\n    assert(g[5] == 'ц');\n    assert(g[6] == '~');\n    assert(!g.valid);\n\n    Grapheme copy = g;\n    copy[0] = 'X';\n    copy[1] = '-';\n    assert(g[0] == 'a' && copy[0] == 'X');\n    assert(g[1] == 'b' && copy[1] == '-');\n    assert(equal(g[2 .. g.length], copy[2 .. copy.length]));\n    copy = Grapheme(\"АБВГДЕЁЖЗИКЛМ\");\n    assert(equal(copy[0 .. 8], \"АБВГДЕЁЖ\"), text(copy[0 .. 8]));\n    copy ~= \"xyz\";\n    assert(equal(copy[13 .. 15], \"xy\"), text(copy[13 .. 15]));\n    assert(!copy.valid);\n\n    Grapheme h;\n    foreach (dchar v; iota(cast(int)'A', cast(int)'Z'+1).map!\"cast(dchar)a\"())\n        h ~= v;\n    assert(equal(h[], iota(cast(int)'A', cast(int)'Z'+1)));\n}\n\n/++\n    $(P Does basic case-insensitive comparison of `r1` and `r2`.\n    This function uses simpler comparison rule thus achieving better performance\n    than $(LREF icmp). However keep in mind the warning below.)\n\n    Params:\n        r1 = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of characters\n        r2 = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of characters\n\n    Returns:\n        An `int` that is 0 if the strings match,\n        &lt;0 if `r1` is lexicographically \"less\" than `r2`,\n        &gt;0 if `r1` is lexicographically \"greater\" than `r2`\n\n    Warning:\n    This function only handles 1:1 $(CODEPOINT) mapping\n    and thus is not sufficient for certain alphabets\n    like German, Greek and few others.\n\n    See_Also:\n        $(LREF icmp)\n        $(REF cmp, std,algorithm,comparison)\n+/\nint sicmp(S1, S2)(scope S1 r1, scope S2 r2)\nif (isInputRange!S1 && isSomeChar!(ElementEncodingType!S1)\n    && isInputRange!S2 && isSomeChar!(ElementEncodingType!S2))\n{\n    import std.internal.unicode_tables : sTable = simpleCaseTable; // generated file\n    import std.utf : decodeFront;\n    import std.typecons : Yes;\n    static import std.ascii;\n\n    static if ((isDynamicArray!S1 || isRandomAccessRange!S1)\n        && (isDynamicArray!S2 || isRandomAccessRange!S2)\n        && !(isInfinite!S1 && isInfinite!S2)\n        && __traits(compiles,\n            {\n                size_t s = size_t.sizeof / 2;\n                r1 = r1[s .. $];\n                r2 = r2[s .. $];\n            }))\n    {{\n        // ASCII optimization for dynamic arrays & similar.\n        size_t i = 0;\n        static if (isInfinite!S1)\n            immutable end = r2.length;\n        else static if (isInfinite!S2)\n            immutable end = r1.length;\n        else\n            immutable end = r1.length > r2.length ? r2.length : r1.length;\n        for (; i < end; ++i)\n        {\n            auto lhs = r1[i];\n            auto rhs = r2[i];\n            if ((lhs | rhs) >= 0x80) goto NonAsciiPath;\n            if (lhs == rhs) continue;\n            auto lowDiff = std.ascii.toLower(lhs) - std.ascii.toLower(rhs);\n            if (lowDiff) return lowDiff;\n        }\n        static if (isInfinite!S1)\n            return 1;\n        else static if (isInfinite!S2)\n            return -1;\n        else\n            return (r1.length > r2.length) - (r2.length > r1.length);\n\n    NonAsciiPath:\n        r1 = r1[i .. $];\n        r2 = r2[i .. $];\n        // Fall through to standard case.\n    }}\n\n    while (!r1.empty)\n    {\n        immutable lhs = decodeFront!(Yes.useReplacementDchar)(r1);\n        if (r2.empty)\n            return 1;\n        immutable rhs = decodeFront!(Yes.useReplacementDchar)(r2);\n        int diff = lhs - rhs;\n        if (!diff)\n            continue;\n        if ((lhs | rhs) < 0x80)\n        {\n            immutable d = std.ascii.toLower(lhs) - std.ascii.toLower(rhs);\n            if (!d) continue;\n            return d;\n        }\n        size_t idx = simpleCaseTrie[lhs];\n        size_t idx2 = simpleCaseTrie[rhs];\n        // simpleCaseTrie is packed index table\n        if (idx != EMPTY_CASE_TRIE)\n        {\n            if (idx2 != EMPTY_CASE_TRIE)\n            {// both cased chars\n                // adjust idx --> start of bucket\n                idx = idx - sTable[idx].n;\n                idx2 = idx2 - sTable[idx2].n;\n                if (idx == idx2)// one bucket, equivalent chars\n                    continue;\n                else//  not the same bucket\n                    diff = sTable[idx].ch - sTable[idx2].ch;\n            }\n            else\n                diff = sTable[idx - sTable[idx].n].ch - rhs;\n        }\n        else if (idx2 != EMPTY_CASE_TRIE)\n        {\n            diff = lhs - sTable[idx2 - sTable[idx2].n].ch;\n        }\n        // one of chars is not cased at all\n        return diff;\n    }\n    return int(r2.empty) - 1;\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    assert(sicmp(\"Август\", \"авгусТ\") == 0);\n    // Greek also works as long as there is no 1:M mapping in sight\n    assert(sicmp(\"ΌΎ\", \"όύ\") == 0);\n    // things like the following won't get matched as equal\n    // Greek small letter iota with dialytika and tonos\n    assert(sicmp(\"ΐ\", \"\\u03B9\\u0308\\u0301\") != 0);\n\n    // while icmp has no problem with that\n    assert(icmp(\"ΐ\", \"\\u03B9\\u0308\\u0301\") == 0);\n    assert(icmp(\"ΌΎ\", \"όύ\") == 0);\n}\n\n// overloads for the most common cases to reduce compile time\n@safe @nogc pure nothrow\n{\n    int sicmp(scope const(char)[] str1, scope const(char)[] str2)\n    { return sicmp!(const(char)[], const(char)[])(str1, str2); }\n\n    int sicmp(scope const(wchar)[] str1, scope const(wchar)[] str2)\n    { return sicmp!(const(wchar)[], const(wchar)[])(str1, str2); }\n\n    int sicmp(scope const(dchar)[] str1, scope const(dchar)[] str2)\n    { return sicmp!(const(dchar)[], const(dchar)[])(str1, str2); }\n}\n\nprivate int fullCasedCmp(Range)(dchar lhs, dchar rhs, ref Range rtail)\n{\n    import std.algorithm.searching : skipOver;\n    import std.internal.unicode_tables : fullCaseTable; // generated file\n    alias fTable = fullCaseTable;\n    size_t idx = fullCaseTrie[lhs];\n    // fullCaseTrie is packed index table\n    if (idx == EMPTY_CASE_TRIE)\n        return lhs;\n    immutable start = idx - fTable[idx].n;\n    immutable end = fTable[idx].size + start;\n    assert(fTable[start].entry_len == 1);\n    for (idx=start; idx<end; idx++)\n    {\n        auto entryLen = fTable[idx].entry_len;\n        if (entryLen == 1)\n        {\n            if (fTable[idx].seq[0] == rhs)\n            {\n                return 0;\n            }\n        }\n        else\n        {// OK it's a long chunk, like 'ss' for German\n            dstring seq = fTable[idx].seq[0 .. entryLen];\n            if (rhs == seq[0]\n                && rtail.skipOver(seq[1..$]))\n            {\n                // note that this path modifies rtail\n                // iff we managed to get there\n                return 0;\n            }\n        }\n    }\n    return fTable[start].seq[0]; // new remapped character for accurate diffs\n}\n\n/++\n    Does case insensitive comparison of `r1` and `r2`.\n    Follows the rules of full case-folding mapping.\n    This includes matching as equal german ß with \"ss\" and\n    other 1:M $(CODEPOINT) mappings unlike $(LREF sicmp).\n    The cost of `icmp` being pedantically correct is\n    slightly worse performance.\n\n    Params:\n        r1 = a forward range of characters\n        r2 = a forward range of characters\n\n    Returns:\n        An `int` that is 0 if the strings match,\n        &lt;0 if `str1` is lexicographically \"less\" than `str2`,\n        &gt;0 if `str1` is lexicographically \"greater\" than `str2`\n\n    See_Also:\n        $(LREF sicmp)\n        $(REF cmp, std,algorithm,comparison)\n+/\nint icmp(S1, S2)(S1 r1, S2 r2)\nif (isForwardRange!S1 && isSomeChar!(ElementEncodingType!S1)\n    && isForwardRange!S2 && isSomeChar!(ElementEncodingType!S2))\n{\n    import std.utf : byDchar;\n    static import std.ascii;\n\n    static if ((isDynamicArray!S1 || isRandomAccessRange!S1)\n        && (isDynamicArray!S2 || isRandomAccessRange!S2)\n        && !(isInfinite!S1 && isInfinite!S2)\n        && __traits(compiles,\n            {\n                size_t s = size_t.max / 2;\n                r1 = r1[s .. $];\n                r2 = r2[s .. $];\n            }))\n    {{\n        // ASCII optimization for dynamic arrays & similar.\n        size_t i = 0;\n        static if (isInfinite!S1)\n            immutable end = r2.length;\n        else static if (isInfinite!S2)\n            immutable end = r1.length;\n        else\n            immutable end = r1.length > r2.length ? r2.length : r1.length;\n        for (; i < end; ++i)\n        {\n            auto lhs = r1[i];\n            auto rhs = r2[i];\n            if ((lhs | rhs) >= 0x80) goto NonAsciiPath;\n            if (lhs == rhs) continue;\n            auto lowDiff = std.ascii.toLower(lhs) - std.ascii.toLower(rhs);\n            if (lowDiff) return lowDiff;\n        }\n        static if (isInfinite!S1)\n            return 1;\n        else static if (isInfinite!S2)\n            return -1;\n        else\n            return (r1.length > r2.length) - (r2.length > r1.length);\n\n    NonAsciiPath:\n        r1 = r1[i .. $];\n        r2 = r2[i .. $];\n        // Fall through to standard case.\n    }}\n\n    auto str1 = r1.byDchar;\n    auto str2 = r2.byDchar;\n\n    for (;;)\n    {\n        if (str1.empty)\n            return str2.empty ? 0 : -1;\n        immutable lhs = str1.front;\n        if (str2.empty)\n            return 1;\n        immutable rhs = str2.front;\n        str1.popFront();\n        str2.popFront();\n        if (!(lhs - rhs))\n            continue;\n        // first try to match lhs to <rhs,right-tail> sequence\n        immutable cmpLR = fullCasedCmp(lhs, rhs, str2);\n        if (!cmpLR)\n            continue;\n        // then rhs to <lhs,left-tail> sequence\n        immutable cmpRL = fullCasedCmp(rhs, lhs, str1);\n        if (!cmpRL)\n            continue;\n        // cmpXX contain remapped codepoints\n        // to obtain stable ordering of icmp\n        return cmpLR - cmpRL;\n    }\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    assert(icmp(\"Rußland\", \"Russland\") == 0);\n    assert(icmp(\"ᾩ -> \\u1F70\\u03B9\", \"\\u1F61\\u03B9 -> ᾲ\") == 0);\n}\n\n/**\n * By using $(REF byUTF, std,utf) and its aliases, GC allocations via auto-decoding\n * and thrown exceptions can be avoided, making `icmp` `@safe @nogc nothrow pure`.\n */\n@safe @nogc nothrow pure unittest\n{\n    import std.utf : byDchar;\n\n    assert(icmp(\"Rußland\".byDchar, \"Russland\".byDchar) == 0);\n    assert(icmp(\"ᾩ -> \\u1F70\\u03B9\".byDchar, \"\\u1F61\\u03B9 -> ᾲ\".byDchar) == 0);\n}\n\n// test different character types\n@safe unittest\n{\n    assert(icmp(\"Rußland\", \"Russland\") == 0);\n    assert(icmp(\"Rußland\"w, \"Russland\") == 0);\n    assert(icmp(\"Rußland\", \"Russland\"w) == 0);\n    assert(icmp(\"Rußland\"w, \"Russland\"w) == 0);\n    assert(icmp(\"Rußland\"d, \"Russland\"w) == 0);\n    assert(icmp(\"Rußland\"w, \"Russland\"d) == 0);\n}\n\n// overloads for the most common cases to reduce compile time\n@safe @nogc pure nothrow\n{\n    int icmp(const(char)[] str1, const(char)[] str2)\n    { return icmp!(const(char)[], const(char)[])(str1, str2); }\n    int icmp(const(wchar)[] str1, const(wchar)[] str2)\n    { return icmp!(const(wchar)[], const(wchar)[])(str1, str2); }\n    int icmp(const(dchar)[] str1, const(dchar)[] str2)\n    { return icmp!(const(dchar)[], const(dchar)[])(str1, str2); }\n}\n\n@safe unittest\n{\n    import std.algorithm.sorting : sort;\n    import std.conv : to;\n    import std.exception : assertCTFEable;\n    assertCTFEable!(\n    {\n    static foreach (cfunc; AliasSeq!(icmp, sicmp))\n    {{\n        static foreach (S1; AliasSeq!(string, wstring, dstring))\n        static foreach (S2; AliasSeq!(string, wstring, dstring))\n        {\n            assert(cfunc(\"\".to!S1(), \"\".to!S2()) == 0);\n            assert(cfunc(\"A\".to!S1(), \"\".to!S2()) > 0);\n            assert(cfunc(\"\".to!S1(), \"0\".to!S2()) < 0);\n            assert(cfunc(\"abc\".to!S1(), \"abc\".to!S2()) == 0);\n            assert(cfunc(\"abcd\".to!S1(), \"abc\".to!S2()) > 0);\n            assert(cfunc(\"abc\".to!S1(), \"abcd\".to!S2()) < 0);\n            assert(cfunc(\"Abc\".to!S1(), \"aBc\".to!S2()) == 0);\n            assert(cfunc(\"авГуст\".to!S1(), \"АВгУСТ\".to!S2()) == 0);\n            // Check example:\n            assert(cfunc(\"Август\".to!S1(), \"авгусТ\".to!S2()) == 0);\n            assert(cfunc(\"ΌΎ\".to!S1(), \"όύ\".to!S2()) == 0);\n        }\n        // check that the order is properly agnostic to the case\n        auto strs = [ \"Apple\", \"ORANGE\",  \"orAcle\", \"amp\", \"banana\"];\n        sort!((a,b) => cfunc(a,b) < 0)(strs);\n        assert(strs == [\"amp\", \"Apple\",  \"banana\", \"orAcle\", \"ORANGE\"]);\n    }}\n    assert(icmp(\"ßb\", \"ssa\") > 0);\n    // Check example:\n    assert(icmp(\"Russland\", \"Rußland\") == 0);\n    assert(icmp(\"ᾩ -> \\u1F70\\u03B9\", \"\\u1F61\\u03B9 -> ᾲ\") == 0);\n    assert(icmp(\"ΐ\"w, \"\\u03B9\\u0308\\u0301\") == 0);\n    assert(sicmp(\"ΐ\", \"\\u03B9\\u0308\\u0301\") != 0);\n    //bugzilla 11057\n    assert( icmp(\"K\", \"L\") < 0 );\n    });\n}\n\n// issue 17372\n@safe pure unittest\n{\n    import std.algorithm.iteration : joiner, map;\n    import std.algorithm.sorting : sort;\n    import std.array : array;\n    auto a = [[\"foo\", \"bar\"], [\"baz\"]].map!(line => line.joiner(\" \")).array.sort!((a, b) => icmp(a, b) < 0);\n}\n\n// This is package for the moment to be used as a support tool for std.regex\n// It needs a better API\n/*\n    Return a range of all $(CODEPOINTS) that casefold to\n    and from this `ch`.\n*/\npackage auto simpleCaseFoldings(dchar ch) @safe\n{\n    import std.internal.unicode_tables : simpleCaseTable; // generated file\n    alias sTable = simpleCaseTable;\n    static struct Range\n    {\n    @safe pure nothrow:\n        uint idx; //if == uint.max, then read c.\n        union\n        {\n            dchar c; // == 0 - empty range\n            uint len;\n        }\n        @property bool isSmall() const { return idx == uint.max; }\n\n        this(dchar ch)\n        {\n            idx = uint.max;\n            c = ch;\n        }\n\n        this(uint start, uint size)\n        {\n            idx = start;\n            len = size;\n        }\n\n        @property dchar front() const\n        {\n            assert(!empty);\n            if (isSmall)\n            {\n                return c;\n            }\n            auto ch = sTable[idx].ch;\n            return ch;\n        }\n\n        @property bool empty() const\n        {\n            if (isSmall)\n            {\n                return c == 0;\n            }\n            return len == 0;\n        }\n\n        @property size_t length() const\n        {\n            if (isSmall)\n            {\n                return c == 0 ? 0 : 1;\n            }\n            return len;\n        }\n\n        void popFront()\n        {\n            if (isSmall)\n                c = 0;\n            else\n            {\n                idx++;\n                len--;\n            }\n        }\n    }\n    immutable idx = simpleCaseTrie[ch];\n    if (idx == EMPTY_CASE_TRIE)\n        return Range(ch);\n    auto entry = sTable[idx];\n    immutable start = idx - entry.n;\n    return Range(start, entry.size);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.algorithm.searching : canFind;\n    import std.array : array;\n    import std.exception : assertCTFEable;\n    assertCTFEable!((){\n        auto r = simpleCaseFoldings('Э').array;\n        assert(r.length == 2);\n        assert(r.canFind('э') && r.canFind('Э'));\n        auto sr = simpleCaseFoldings('~');\n        assert(sr.equal(\"~\"));\n        //A with ring above - casefolds to the same bucket as Angstrom sign\n        sr = simpleCaseFoldings('Å');\n        assert(sr.length == 3);\n        assert(sr.canFind('å') && sr.canFind('Å') && sr.canFind('\\u212B'));\n    });\n}\n\n/++\n    $(P Returns the $(S_LINK Combining class, combining class) of `ch`.)\n+/\nubyte combiningClass(dchar ch) @safe pure nothrow @nogc\n{\n    return combiningClassTrie[ch];\n}\n\n///\n@safe unittest\n{\n    // shorten the code\n    alias CC = combiningClass;\n\n    // combining tilda\n    assert(CC('\\u0303') == 230);\n    // combining ring below\n    assert(CC('\\u0325') == 220);\n    // the simple consequence is that  \"tilda\" should be\n    // placed after a \"ring below\" in a sequence\n}\n\n@safe pure nothrow @nogc unittest\n{\n    foreach (ch; 0 .. 0x80)\n        assert(combiningClass(ch) == 0);\n    assert(combiningClass('\\u05BD') == 22);\n    assert(combiningClass('\\u0300') == 230);\n    assert(combiningClass('\\u0317') == 220);\n    assert(combiningClass('\\u1939') == 222);\n}\n\n/// Unicode character decomposition type.\nenum UnicodeDecomposition {\n    /// Canonical decomposition. The result is canonically equivalent sequence.\n    Canonical,\n    /**\n         Compatibility decomposition. The result is compatibility equivalent sequence.\n         Note: Compatibility decomposition is a $(B lossy) conversion,\n         typically suitable only for fuzzy matching and internal processing.\n    */\n    Compatibility\n}\n\n/**\n    Shorthand aliases for character decomposition type, passed as a\n    template parameter to $(LREF decompose).\n*/\nenum {\n    Canonical = UnicodeDecomposition.Canonical,\n    Compatibility = UnicodeDecomposition.Compatibility\n}\n\n/++\n    Try to canonically compose 2 $(CHARACTERS).\n    Returns the composed $(CHARACTER) if they do compose and dchar.init otherwise.\n\n    The assumption is that `first` comes before `second` in the original text,\n    usually meaning that the first is a starter.\n\n    Note: Hangul syllables are not covered by this function.\n    See `composeJamo` below.\n+/\npublic dchar compose(dchar first, dchar second) pure nothrow @safe\n{\n    import std.algorithm.iteration : map;\n    import std.internal.unicode_comp : compositionTable, composeCntShift, composeIdxMask;\n    import std.range : assumeSorted;\n    immutable packed = compositionJumpTrie[first];\n    if (packed == ushort.max)\n        return dchar.init;\n    // unpack offset and length\n    immutable idx = packed & composeIdxMask, cnt = packed >> composeCntShift;\n    // TODO: optimize this micro binary search (no more then 4-5 steps)\n    auto r = compositionTable[idx .. idx+cnt].map!\"a.rhs\"().assumeSorted();\n    immutable target = r.lowerBound(second).length;\n    if (target == cnt)\n        return dchar.init;\n    immutable entry = compositionTable[idx+target];\n    if (entry.rhs != second)\n        return dchar.init;\n    return entry.composed;\n}\n\n///\n@safe unittest\n{\n    assert(compose('A','\\u0308') == '\\u00C4');\n    assert(compose('A', 'B') == dchar.init);\n    assert(compose('C', '\\u0301') == '\\u0106');\n    // note that the starter is the first one\n    // thus the following doesn't compose\n    assert(compose('\\u0308', 'A') == dchar.init);\n}\n\n/++\n    Returns a full $(S_LINK Canonical decomposition, Canonical)\n    (by default) or $(S_LINK Compatibility decomposition, Compatibility)\n    decomposition of $(CHARACTER) `ch`.\n    If no decomposition is available returns a $(LREF Grapheme)\n    with the `ch` itself.\n\n    Note:\n    This function also decomposes hangul syllables\n    as prescribed by the standard.\n\n    See_Also: $(LREF decomposeHangul) for a restricted version\n    that takes into account only hangul syllables  but\n    no other decompositions.\n+/\npublic Grapheme decompose(UnicodeDecomposition decompType=Canonical)(dchar ch) @safe\n{\n    import std.algorithm.searching : until;\n    import std.internal.unicode_decomp : decompCompatTable, decompCanonTable;\n    static if (decompType == Canonical)\n    {\n        alias table = decompCanonTable;\n        alias mapping = canonMappingTrie;\n    }\n    else static if (decompType == Compatibility)\n    {\n        alias table = decompCompatTable;\n        alias mapping = compatMappingTrie;\n    }\n    immutable idx = mapping[ch];\n    if (!idx) // not found, check hangul arithmetic decomposition\n        return decomposeHangul(ch);\n    auto decomp = table[idx..$].until(0);\n    return Grapheme(decomp);\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(compose('A','\\u0308') == '\\u00C4');\n    assert(compose('A', 'B') == dchar.init);\n    assert(compose('C', '\\u0301') == '\\u0106');\n    // note that the starter is the first one\n    // thus the following doesn't compose\n    assert(compose('\\u0308', 'A') == dchar.init);\n\n    assert(decompose('Ĉ')[].equal(\"C\\u0302\"));\n    assert(decompose('D')[].equal(\"D\"));\n    assert(decompose('\\uD4DC')[].equal(\"\\u1111\\u1171\\u11B7\"));\n    assert(decompose!Compatibility('¹')[].equal(\"1\"));\n}\n\n//----------------------------------------------------------------------------\n// Hangul specific composition/decomposition\nenum jamoSBase = 0xAC00;\nenum jamoLBase = 0x1100;\nenum jamoVBase = 0x1161;\nenum jamoTBase = 0x11A7;\nenum jamoLCount = 19, jamoVCount = 21, jamoTCount = 28;\nenum jamoNCount = jamoVCount * jamoTCount;\nenum jamoSCount = jamoLCount * jamoNCount;\n\n// Tests if `ch` is a Hangul leading consonant jamo.\nbool isJamoL(dchar ch) pure nothrow @nogc @safe\n{\n    // first cmp rejects ~ 1M code points above leading jamo range\n    return ch < jamoLBase+jamoLCount && ch >= jamoLBase;\n}\n\n// Tests if `ch` is a Hangul vowel jamo.\nbool isJamoT(dchar ch) pure nothrow @nogc @safe\n{\n    // first cmp rejects ~ 1M code points above trailing jamo range\n    // Note: ch == jamoTBase doesn't indicate trailing jamo (TIndex must be > 0)\n    return ch < jamoTBase+jamoTCount && ch > jamoTBase;\n}\n\n// Tests if `ch` is a Hangul trailnig consonant jamo.\nbool isJamoV(dchar ch) pure nothrow @nogc @safe\n{\n    // first cmp rejects ~ 1M code points above vowel range\n    return  ch < jamoVBase+jamoVCount && ch >= jamoVBase;\n}\n\nint hangulSyllableIndex(dchar ch) pure nothrow @nogc @safe\n{\n    int idxS = cast(int) ch - jamoSBase;\n    return idxS >= 0 && idxS < jamoSCount ? idxS : -1;\n}\n\n// internal helper: compose hangul syllables leaving dchar.init in holes\nvoid hangulRecompose(dchar[] seq) pure nothrow @nogc @safe\n{\n    for (size_t idx = 0; idx + 1 < seq.length; )\n    {\n        if (isJamoL(seq[idx]) && isJamoV(seq[idx+1]))\n        {\n            immutable int indexL = seq[idx] - jamoLBase;\n            immutable int indexV = seq[idx+1] - jamoVBase;\n            immutable int indexLV = indexL * jamoNCount + indexV * jamoTCount;\n            if (idx + 2 < seq.length && isJamoT(seq[idx+2]))\n            {\n                seq[idx] = jamoSBase + indexLV + seq[idx+2] - jamoTBase;\n                seq[idx+1] = dchar.init;\n                seq[idx+2] = dchar.init;\n                idx += 3;\n            }\n            else\n            {\n                seq[idx] = jamoSBase + indexLV;\n                seq[idx+1] = dchar.init;\n                idx += 2;\n            }\n        }\n        else\n            idx++;\n    }\n}\n\n//----------------------------------------------------------------------------\npublic:\n\n/**\n    Decomposes a Hangul syllable. If `ch` is not a composed syllable\n    then this function returns $(LREF Grapheme) containing only `ch` as is.\n*/\nGrapheme decomposeHangul(dchar ch) @safe\n{\n    immutable idxS = cast(int) ch - jamoSBase;\n    if (idxS < 0 || idxS >= jamoSCount) return Grapheme(ch);\n    immutable idxL = idxS / jamoNCount;\n    immutable idxV = (idxS % jamoNCount) / jamoTCount;\n    immutable idxT = idxS % jamoTCount;\n\n    immutable partL = jamoLBase + idxL;\n    immutable partV = jamoVBase + idxV;\n    if (idxT > 0) // there is a trailling consonant (T); <L,V,T> decomposition\n        return Grapheme(partL, partV, jamoTBase + idxT);\n    else // <L, V> decomposition\n        return Grapheme(partL, partV);\n}\n\n///\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    assert(decomposeHangul('\\uD4DB')[].equal(\"\\u1111\\u1171\\u11B6\"));\n}\n\n/++\n    Try to compose hangul syllable out of a leading consonant (`lead`),\n    a `vowel` and optional `trailing` consonant jamos.\n\n    On success returns the composed LV or LVT hangul syllable.\n\n    If any of `lead` and `vowel` are not a valid hangul jamo\n    of the respective $(CHARACTER) class returns dchar.init.\n+/\ndchar composeJamo(dchar lead, dchar vowel, dchar trailing=dchar.init) pure nothrow @nogc @safe\n{\n    if (!isJamoL(lead))\n        return dchar.init;\n    immutable indexL = lead - jamoLBase;\n    if (!isJamoV(vowel))\n        return dchar.init;\n    immutable indexV = vowel - jamoVBase;\n    immutable indexLV = indexL * jamoNCount + indexV * jamoTCount;\n    immutable dchar syllable = jamoSBase + indexLV;\n    return isJamoT(trailing) ? syllable + (trailing - jamoTBase) : syllable;\n}\n\n///\n@safe unittest\n{\n    assert(composeJamo('\\u1111', '\\u1171', '\\u11B6') == '\\uD4DB');\n    // leaving out T-vowel, or passing any codepoint\n    // that is not trailing consonant composes an LV-syllable\n    assert(composeJamo('\\u1111', '\\u1171') == '\\uD4CC');\n    assert(composeJamo('\\u1111', '\\u1171', ' ') == '\\uD4CC');\n    assert(composeJamo('\\u1111', 'A') == dchar.init);\n    assert(composeJamo('A', '\\u1171') == dchar.init);\n}\n\n@system unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.conv : text;\n\n    static void testDecomp(UnicodeDecomposition T)(dchar ch, string r)\n    {\n        Grapheme g = decompose!T(ch);\n        assert(equal(g[], r), text(g[], \" vs \", r));\n    }\n    testDecomp!Canonical('\\u1FF4', \"\\u03C9\\u0301\\u0345\");\n    testDecomp!Canonical('\\uF907', \"\\u9F9C\");\n    testDecomp!Compatibility('\\u33FF', \"\\u0067\\u0061\\u006C\");\n    testDecomp!Compatibility('\\uA7F9', \"\\u0153\");\n\n    // check examples\n    assert(decomposeHangul('\\uD4DB')[].equal(\"\\u1111\\u1171\\u11B6\"));\n    assert(composeJamo('\\u1111', '\\u1171', '\\u11B6') == '\\uD4DB');\n    assert(composeJamo('\\u1111', '\\u1171') == '\\uD4CC'); // leave out T-vowel\n    assert(composeJamo('\\u1111', '\\u1171', ' ') == '\\uD4CC');\n    assert(composeJamo('\\u1111', 'A') == dchar.init);\n    assert(composeJamo('A', '\\u1171') == dchar.init);\n}\n\n/**\n    Enumeration type for normalization forms,\n    passed as template parameter for functions like $(LREF normalize).\n*/\nenum NormalizationForm {\n    NFC,\n    NFD,\n    NFKC,\n    NFKD\n}\n\n\nenum {\n    /**\n        Shorthand aliases from values indicating normalization forms.\n    */\n    NFC = NormalizationForm.NFC,\n    ///ditto\n    NFD = NormalizationForm.NFD,\n    ///ditto\n    NFKC = NormalizationForm.NFKC,\n    ///ditto\n    NFKD = NormalizationForm.NFKD\n}\n\n/++\n    Returns `input` string normalized to the chosen form.\n    Form C is used by default.\n\n    For more information on normalization forms see\n    the $(S_LINK Normalization, normalization section).\n\n    Note:\n    In cases where the string in question is already normalized,\n    it is returned unmodified and no memory allocation happens.\n+/\ninout(C)[] normalize(NormalizationForm norm=NFC, C)(inout(C)[] input)\n{\n    import std.algorithm.mutation : SwapStrategy;\n    import std.algorithm.sorting : sort;\n    import std.array : appender;\n    import std.range : zip;\n\n    auto anchors = splitNormalized!norm(input);\n    if (anchors[0] == input.length && anchors[1] == input.length)\n        return input;\n    dchar[] decomposed;\n    decomposed.reserve(31);\n    ubyte[] ccc;\n    ccc.reserve(31);\n    auto app = appender!(C[])();\n    do\n    {\n        app.put(input[0 .. anchors[0]]);\n        foreach (dchar ch; input[anchors[0]..anchors[1]])\n            static if (norm == NFD || norm == NFC)\n            {\n                foreach (dchar c; decompose!Canonical(ch)[])\n                    decomposed ~= c;\n            }\n            else // NFKD & NFKC\n            {\n                foreach (dchar c; decompose!Compatibility(ch)[])\n                    decomposed ~= c;\n            }\n        ccc.length = decomposed.length;\n        size_t firstNonStable = 0;\n        ubyte lastClazz = 0;\n\n        foreach (idx, dchar ch; decomposed)\n        {\n            immutable clazz = combiningClass(ch);\n            ccc[idx] = clazz;\n            if (clazz == 0 && lastClazz != 0)\n            {\n                // found a stable code point after unstable ones\n                sort!(\"a[0] < b[0]\", SwapStrategy.stable)\n                    (zip(ccc[firstNonStable .. idx], decomposed[firstNonStable .. idx]));\n                firstNonStable = decomposed.length;\n            }\n            else if (clazz != 0 && lastClazz == 0)\n            {\n                // found first unstable code point after stable ones\n                firstNonStable = idx;\n            }\n            lastClazz = clazz;\n        }\n        sort!(\"a[0] < b[0]\", SwapStrategy.stable)\n            (zip(ccc[firstNonStable..$], decomposed[firstNonStable..$]));\n        static if (norm == NFC || norm == NFKC)\n        {\n            import std.algorithm.searching : countUntil;\n            auto first = countUntil(ccc, 0);\n            if (first >= 0) // no starters?? no recomposition\n            {\n                for (;;)\n                {\n                    immutable second = recompose(first, decomposed, ccc);\n                    if (second == decomposed.length)\n                        break;\n                    first = second;\n                }\n                // 2nd pass for hangul syllables\n                hangulRecompose(decomposed);\n            }\n        }\n        static if (norm == NFD || norm == NFKD)\n            app.put(decomposed);\n        else\n        {\n            import std.algorithm.mutation : remove;\n            auto clean = remove!(\"a == dchar.init\", SwapStrategy.stable)(decomposed);\n            app.put(decomposed[0 .. clean.length]);\n        }\n        // reset variables\n        decomposed.length = 0;\n        () @trusted {\n            decomposed.assumeSafeAppend();\n            ccc.length = 0;\n            ccc.assumeSafeAppend();\n        } ();\n        input = input[anchors[1]..$];\n        // and move on\n        anchors = splitNormalized!norm(input);\n    }while (anchors[0] != input.length);\n    app.put(input[0 .. anchors[0]]);\n    return () @trusted inout { return cast(inout(C)[]) app.data; } ();\n}\n\n///\n@safe unittest\n{\n    // any encoding works\n    wstring greet = \"Hello world\";\n    assert(normalize(greet) is greet); // the same exact slice\n\n    // An example of a character with all 4 forms being different:\n    // Greek upsilon with acute and hook symbol (code point 0x03D3)\n    assert(normalize!NFC(\"ϓ\") == \"\\u03D3\");\n    assert(normalize!NFD(\"ϓ\") == \"\\u03D2\\u0301\");\n    assert(normalize!NFKC(\"ϓ\") == \"\\u038E\");\n    assert(normalize!NFKD(\"ϓ\") == \"\\u03A5\\u0301\");\n}\n\n@safe unittest\n{\n    import std.conv : text;\n\n    assert(normalize!NFD(\"abc\\uF904def\") == \"abc\\u6ED1def\", text(normalize!NFD(\"abc\\uF904def\")));\n    assert(normalize!NFKD(\"2¹⁰\") == \"210\", normalize!NFKD(\"2¹⁰\"));\n    assert(normalize!NFD(\"Äffin\") == \"A\\u0308ffin\");\n\n    // check example\n\n    // any encoding works\n    wstring greet = \"Hello world\";\n    assert(normalize(greet) is greet); // the same exact slice\n\n    // An example of a character with all 4 forms being different:\n    // Greek upsilon with acute and hook symbol (code point 0x03D3)\n    assert(normalize!NFC(\"ϓ\") == \"\\u03D3\");\n    assert(normalize!NFD(\"ϓ\") == \"\\u03D2\\u0301\");\n    assert(normalize!NFKC(\"ϓ\") == \"\\u038E\");\n    assert(normalize!NFKD(\"ϓ\") == \"\\u03A5\\u0301\");\n}\n\n// canonically recompose given slice of code points, works in-place and mutates data\nprivate size_t recompose(size_t start, dchar[] input, ubyte[] ccc) pure nothrow @safe\n{\n    assert(input.length == ccc.length);\n    int accumCC = -1;// so that it's out of 0 .. 255 range\n    // writefln(\"recomposing %( %04x %)\", input);\n    // first one is always a starter thus we start at i == 1\n    size_t i = start+1;\n    for (; ; )\n    {\n        if (i == input.length)\n            break;\n        immutable curCC = ccc[i];\n        // In any character sequence beginning with a starter S\n        // a character C is blocked from S if and only if there\n        // is some character B between S and C, and either B\n        // is a starter or it has the same or higher combining class as C.\n        //------------------------\n        // Applying to our case:\n        // S is input[0]\n        // accumCC is the maximum CCC of characters between C and S,\n        //     as ccc are sorted\n        // C is input[i]\n\n        if (curCC > accumCC)\n        {\n            immutable comp = compose(input[start], input[i]);\n            if (comp != dchar.init)\n            {\n                input[start] = comp;\n                input[i] = dchar.init;// put a sentinel\n                // current was merged so its CCC shouldn't affect\n                // composing with the next one\n            }\n            else\n            {\n                // if it was a starter then accumCC is now 0, end of loop\n                accumCC = curCC;\n                if (accumCC == 0)\n                    break;\n            }\n        }\n        else\n        {\n            // ditto here\n            accumCC = curCC;\n            if (accumCC == 0)\n                break;\n        }\n        i++;\n    }\n    return i;\n}\n\n// returns tuple of 2 indexes that delimit:\n// normalized text, piece that needs normalization and\n// the rest of input starting with stable code point\nprivate auto splitNormalized(NormalizationForm norm, C)(const(C)[] input)\n{\n    import std.typecons : tuple;\n    ubyte lastCC = 0;\n\n    foreach (idx, dchar ch; input)\n    {\n        static if (norm == NFC)\n            if (ch < 0x0300)\n            {\n                lastCC = 0;\n                continue;\n            }\n        immutable ubyte CC = combiningClass(ch);\n        if (lastCC > CC && CC != 0)\n        {\n            return seekStable!norm(idx, input);\n        }\n\n        if (notAllowedIn!norm(ch))\n        {\n           return seekStable!norm(idx, input);\n        }\n        lastCC = CC;\n    }\n    return tuple(input.length, input.length);\n}\n\nprivate auto seekStable(NormalizationForm norm, C)(size_t idx, const scope C[] input)\n{\n    import std.typecons : tuple;\n    import std.utf : codeLength;\n\n    auto br = input[0 .. idx];\n    size_t region_start = 0;// default\n    for (;;)\n    {\n        if (br.empty)// start is 0\n            break;\n        dchar ch = br.back;\n        if (combiningClass(ch) == 0 && allowedIn!norm(ch))\n        {\n            region_start = br.length - codeLength!C(ch);\n            break;\n        }\n        br.popFront();\n    }\n    ///@@@BUG@@@ can't use find: \" find is a nested function and can't be used...\"\n    size_t region_end=input.length;// end is $ by default\n    foreach (i, dchar ch; input[idx..$])\n    {\n        if (combiningClass(ch) == 0 && allowedIn!norm(ch))\n        {\n            region_end = i+idx;\n            break;\n        }\n    }\n    // writeln(\"Region to normalize: \", input[region_start .. region_end]);\n    return tuple(region_start, region_end);\n}\n\n/**\n    Tests if dchar `ch` is always allowed (Quick_Check=YES) in normalization\n    form `norm`.\n*/\npublic bool allowedIn(NormalizationForm norm)(dchar ch)\n{\n    return !notAllowedIn!norm(ch);\n}\n\n///\n@safe unittest\n{\n    // e.g. Cyrillic is always allowed, so is ASCII\n    assert(allowedIn!NFC('я'));\n    assert(allowedIn!NFD('я'));\n    assert(allowedIn!NFKC('я'));\n    assert(allowedIn!NFKD('я'));\n    assert(allowedIn!NFC('Z'));\n}\n\n// not user friendly name but more direct\nprivate bool notAllowedIn(NormalizationForm norm)(dchar ch)\n{\n    static if (norm == NFC)\n        alias qcTrie = nfcQCTrie;\n    else static if (norm == NFD)\n        alias qcTrie = nfdQCTrie;\n    else static if (norm == NFKC)\n        alias qcTrie = nfkcQCTrie;\n    else static if (norm == NFKD)\n        alias qcTrie = nfkdQCTrie;\n    else\n        static assert(\"Unknown normalization form \"~norm);\n    return qcTrie[ch];\n}\n\n@safe unittest\n{\n    assert(allowedIn!NFC('я'));\n    assert(allowedIn!NFD('я'));\n    assert(allowedIn!NFKC('я'));\n    assert(allowedIn!NFKD('я'));\n    assert(allowedIn!NFC('Z'));\n}\n\n}\n\nversion (std_uni_bootstrap)\n{\n    // old version used for bootstrapping of gen_uni.d that generates\n    // up to date optimal versions of all of isXXX functions\n    @safe pure nothrow @nogc public bool isWhite(dchar c)\n    {\n        import std.ascii : isWhite;\n        return isWhite(c) ||\n               c == lineSep || c == paraSep ||\n               c == '\\u0085' || c == '\\u00A0' || c == '\\u1680' || c == '\\u180E' ||\n               (c >= '\\u2000' && c <= '\\u200A') ||\n               c == '\\u202F' || c == '\\u205F' || c == '\\u3000';\n    }\n}\nelse\n{\n\n// trusted -> avoid bounds check\n@trusted pure nothrow @nogc private\n{\n    import std.internal.unicode_tables; // : toLowerTable, toTitleTable, toUpperTable; // generated file\n\n    // hide template instances behind functions (Bugzilla 13232)\n    ushort toLowerIndex(dchar c) { return toLowerIndexTrie[c]; }\n    ushort toLowerSimpleIndex(dchar c) { return toLowerSimpleIndexTrie[c]; }\n    dchar toLowerTab(size_t idx) { return toLowerTable[idx]; }\n\n    ushort toTitleIndex(dchar c) { return toTitleIndexTrie[c]; }\n    ushort toTitleSimpleIndex(dchar c) { return toTitleSimpleIndexTrie[c]; }\n    dchar toTitleTab(size_t idx) { return toTitleTable[idx]; }\n\n    ushort toUpperIndex(dchar c) { return toUpperIndexTrie[c]; }\n    ushort toUpperSimpleIndex(dchar c) { return toUpperSimpleIndexTrie[c]; }\n    dchar toUpperTab(size_t idx) { return toUpperTable[idx]; }\n}\n\npublic:\n\n/++\n    Whether or not `c` is a Unicode whitespace $(CHARACTER).\n    (general Unicode category: Part of C0(tab, vertical tab, form feed,\n    carriage return, and linefeed characters), Zs, Zl, Zp, and NEL(U+0085))\n+/\n@safe pure nothrow @nogc\npublic bool isWhite(dchar c)\n{\n    import std.internal.unicode_tables : isWhiteGen; // generated file\n    return isWhiteGen(c); // call pregenerated binary search\n}\n\n/++\n    Return whether `c` is a Unicode lowercase $(CHARACTER).\n+/\n@safe pure nothrow @nogc\nbool isLower(dchar c)\n{\n    import std.ascii : isLower, isASCII;\n    if (isASCII(c))\n        return isLower(c);\n    return lowerCaseTrie[c];\n}\n\n@safe unittest\n{\n    import std.ascii : isLower;\n    foreach (v; 0 .. 0x80)\n        assert(isLower(v) == .isLower(v));\n    assert(.isLower('я'));\n    assert(.isLower('й'));\n    assert(!.isLower('Ж'));\n    // Greek HETA\n    assert(!.isLower('\\u0370'));\n    assert(.isLower('\\u0371'));\n    assert(!.isLower('\\u039C')); // capital MU\n    assert(.isLower('\\u03B2')); // beta\n    // from extended Greek\n    assert(!.isLower('\\u1F18'));\n    assert(.isLower('\\u1F00'));\n    foreach (v; unicode.lowerCase.byCodepoint)\n        assert(.isLower(v) && !isUpper(v));\n}\n\n\n/++\n    Return whether `c` is a Unicode uppercase $(CHARACTER).\n+/\n@safe pure nothrow @nogc\nbool isUpper(dchar c)\n{\n    import std.ascii : isUpper, isASCII;\n    if (isASCII(c))\n        return isUpper(c);\n    return upperCaseTrie[c];\n}\n\n@safe unittest\n{\n    import std.ascii : isLower;\n    foreach (v; 0 .. 0x80)\n        assert(isLower(v) == .isLower(v));\n    assert(!isUpper('й'));\n    assert(isUpper('Ж'));\n    // Greek HETA\n    assert(isUpper('\\u0370'));\n    assert(!isUpper('\\u0371'));\n    assert(isUpper('\\u039C')); // capital MU\n    assert(!isUpper('\\u03B2')); // beta\n    // from extended Greek\n    assert(!isUpper('\\u1F00'));\n    assert(isUpper('\\u1F18'));\n    foreach (v; unicode.upperCase.byCodepoint)\n        assert(isUpper(v) && !.isLower(v));\n}\n\n\n//TODO: Hidden for now, needs better API.\n//Other transforms could use better API as well, but this one is a new primitive.\n@safe pure nothrow @nogc\nprivate dchar toTitlecase(dchar c)\n{\n    // optimize ASCII case\n    if (c < 0xAA)\n    {\n        if (c < 'a')\n            return c;\n        if (c <= 'z')\n            return c - 32;\n        return c;\n    }\n    size_t idx = toTitleSimpleIndex(c);\n    if (idx != ushort.max)\n    {\n        return toTitleTab(idx);\n    }\n    return c;\n}\n\nprivate alias UpperTriple = AliasSeq!(toUpperIndex, MAX_SIMPLE_UPPER, toUpperTab);\nprivate alias LowerTriple = AliasSeq!(toLowerIndex, MAX_SIMPLE_LOWER, toLowerTab);\n\n// generic toUpper/toLower on whole string, creates new or returns as is\nprivate ElementEncodingType!S[] toCase(alias indexFn, uint maxIdx, alias tableFn, alias asciiConvert, S)(S s)\nif (isSomeString!S || (isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S)))\n{\n    import std.array : appender, array;\n    import std.ascii : isASCII;\n    import std.utf : byDchar, codeLength;\n\n    alias C = ElementEncodingType!S;\n\n    auto r = s.byDchar;\n    for (size_t i; !r.empty; i += r.front.codeLength!C , r.popFront())\n    {\n        auto cOuter = r.front;\n        ushort idx = indexFn(cOuter);\n        if (idx == ushort.max)\n            continue;\n        auto result = appender!(C[])();\n        result.reserve(s.length);\n        result.put(s[0 .. i]);\n        foreach (dchar c; s[i .. $].byDchar)\n        {\n            if (c.isASCII)\n            {\n                result.put(asciiConvert(c));\n            }\n            else\n            {\n                idx = indexFn(c);\n                if (idx == ushort.max)\n                    result.put(c);\n                else if (idx < maxIdx)\n                {\n                    c = tableFn(idx);\n                    result.put(c);\n                }\n                else\n                {\n                    auto val = tableFn(idx);\n                    // unpack length + codepoint\n                    immutable uint len = val >> 24;\n                    result.put(cast(dchar)(val & 0xFF_FFFF));\n                    foreach (j; idx+1 .. idx+len)\n                        result.put(tableFn(j));\n                }\n            }\n        }\n        return result.data;\n    }\n\n    static if (isSomeString!S)\n        return s;\n    else\n        return s.array;\n}\n\n@safe unittest //12428\n{\n    import std.array : replicate;\n    auto s = \"abcdefghij\".replicate(300);\n    s = s[0 .. 10];\n\n    toUpper(s);\n\n    assert(s == \"abcdefghij\");\n}\n\n@safe unittest // 18993\n{\n    static assert(`몬스터/A`.toLower.length == `몬스터/a`.toLower.length);\n}\n\n\n// generic toUpper/toLower on whole range, returns range\nprivate auto toCaser(alias indexFn, uint maxIdx, alias tableFn, alias asciiConvert, Range)(Range str)\n    // Accept range of dchar's\nif (isInputRange!Range &&\n    isSomeChar!(ElementEncodingType!Range) &&\n    ElementEncodingType!Range.sizeof == dchar.sizeof)\n{\n    static struct ToCaserImpl\n    {\n        @property bool empty()\n        {\n            return !nLeft && r.empty;\n        }\n\n        @property auto front()\n        {\n            import std.ascii : isASCII;\n\n            if (!nLeft)\n            {\n                dchar c = r.front;\n                if (c.isASCII)\n                {\n                    buf[0] = asciiConvert(c);\n                    nLeft = 1;\n                }\n                else\n                {\n                    const idx = indexFn(c);\n                    if (idx == ushort.max)\n                    {\n                        buf[0] = c;\n                        nLeft = 1;\n                    }\n                    else if (idx < maxIdx)\n                    {\n                        buf[0] = tableFn(idx);\n                        nLeft = 1;\n                    }\n                    else\n                    {\n                        immutable val = tableFn(idx);\n                        // unpack length + codepoint\n                        nLeft = val >> 24;\n                        if (nLeft == 0)\n                            nLeft = 1;\n                        assert(nLeft <= buf.length);\n                        buf[nLeft - 1] = cast(dchar)(val & 0xFF_FFFF);\n                        foreach (j; 1 .. nLeft)\n                            buf[nLeft - j - 1] = tableFn(idx + j);\n                    }\n                }\n            }\n            return buf[nLeft - 1];\n        }\n\n        void popFront()\n        {\n            if (!nLeft)\n                front;\n            assert(nLeft);\n            --nLeft;\n            if (!nLeft)\n                r.popFront();\n        }\n\n        static if (isForwardRange!Range)\n        {\n            @property auto save()\n            {\n                auto ret = this;\n                ret.r = r.save;\n                return ret;\n            }\n        }\n\n      private:\n        Range r;\n        uint nLeft;\n        dchar[3] buf = void;\n    }\n\n    return ToCaserImpl(str);\n}\n\n/*********************\n * Convert an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n * or a string to upper or lower case.\n *\n * Does not allocate memory.\n * Characters in UTF-8 or UTF-16 format that cannot be decoded\n * are treated as $(REF replacementDchar, std,utf).\n *\n * Params:\n *      str = string or range of characters\n *\n * Returns:\n *      an input range of `dchar`s\n *\n * See_Also:\n *      $(LREF toUpper), $(LREF toLower)\n */\n\nauto asLowerCase(Range)(Range str)\nif (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) &&\n    !isConvertibleToString!Range)\n{\n    static if (ElementEncodingType!Range.sizeof < dchar.sizeof)\n    {\n        import std.utf : byDchar;\n\n        // Decode first\n        return asLowerCase(str.byDchar);\n    }\n    else\n    {\n        static import std.ascii;\n        return toCaser!(LowerTriple, std.ascii.toLower)(str);\n    }\n}\n\n/// ditto\nauto asUpperCase(Range)(Range str)\nif (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) &&\n    !isConvertibleToString!Range)\n{\n    static if (ElementEncodingType!Range.sizeof < dchar.sizeof)\n    {\n        import std.utf : byDchar;\n\n        // Decode first\n        return asUpperCase(str.byDchar);\n    }\n    else\n    {\n        static import std.ascii;\n        return toCaser!(UpperTriple, std.ascii.toUpper)(str);\n    }\n}\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(\"hEllo\".asUpperCase.equal(\"HELLO\"));\n}\n\n// explicitly undocumented\nauto asLowerCase(Range)(auto ref Range str)\nif (isConvertibleToString!Range)\n{\n    import std.traits : StringTypeOf;\n    return asLowerCase!(StringTypeOf!Range)(str);\n}\n\n// explicitly undocumented\nauto asUpperCase(Range)(auto ref Range str)\nif (isConvertibleToString!Range)\n{\n    import std.traits : StringTypeOf;\n    return asUpperCase!(StringTypeOf!Range)(str);\n}\n\n@safe unittest\n{\n    assert(testAliasedString!asLowerCase(\"hEllo\"));\n    assert(testAliasedString!asUpperCase(\"hEllo\"));\n}\n\n@safe unittest\n{\n    import std.array : array;\n\n    auto a = \"HELLo\".asLowerCase;\n    auto savea = a.save;\n    auto s = a.array;\n    assert(s == \"hello\");\n    s = savea.array;\n    assert(s == \"hello\");\n\n    string[] lower = [\"123\", \"abcфеж\", \"\\u0131\\u023f\\u03c9\", \"i\\u0307\\u1Fe2\"];\n    string[] upper = [\"123\", \"ABCФЕЖ\", \"I\\u2c7e\\u2126\", \"\\u0130\\u03A5\\u0308\\u0300\"];\n\n    foreach (i, slwr; lower)\n    {\n        import std.utf : byChar;\n\n        auto sx = slwr.asUpperCase.byChar.array;\n        assert(sx == toUpper(slwr));\n        auto sy = upper[i].asLowerCase.byChar.array;\n        assert(sy == toLower(upper[i]));\n    }\n\n    // Not necessary to call r.front\n    for (auto r = lower[3].asUpperCase; !r.empty; r.popFront())\n    {\n    }\n\n    import std.algorithm.comparison : equal;\n\n    \"HELLo\"w.asLowerCase.equal(\"hello\"d);\n    \"HELLo\"w.asUpperCase.equal(\"HELLO\"d);\n    \"HELLo\"d.asLowerCase.equal(\"hello\"d);\n    \"HELLo\"d.asUpperCase.equal(\"HELLO\"d);\n\n    import std.utf : byChar;\n    assert(toLower(\"\\u1Fe2\") == asLowerCase(\"\\u1Fe2\").byChar.array);\n}\n\n// generic capitalizer on whole range, returns range\nprivate auto toCapitalizer(alias indexFnUpper, uint maxIdxUpper, alias tableFnUpper,\n                           Range)(Range str)\n    // Accept range of dchar's\nif (isInputRange!Range &&\n    isSomeChar!(ElementEncodingType!Range) &&\n    ElementEncodingType!Range.sizeof == dchar.sizeof)\n{\n    static struct ToCapitalizerImpl\n    {\n        @property bool empty()\n        {\n            return lower ? lwr.empty : !nLeft && r.empty;\n        }\n\n        @property auto front()\n        {\n            if (lower)\n                return lwr.front;\n\n            if (!nLeft)\n            {\n                immutable dchar c = r.front;\n                const idx = indexFnUpper(c);\n                if (idx == ushort.max)\n                {\n                    buf[0] = c;\n                    nLeft = 1;\n                }\n                else if (idx < maxIdxUpper)\n                {\n                    buf[0] = tableFnUpper(idx);\n                    nLeft = 1;\n                }\n                else\n                {\n                    immutable val = tableFnUpper(idx);\n                    // unpack length + codepoint\n                    nLeft = val >> 24;\n                    if (nLeft == 0)\n                        nLeft = 1;\n                    assert(nLeft <= buf.length);\n                    buf[nLeft - 1] = cast(dchar)(val & 0xFF_FFFF);\n                    foreach (j; 1 .. nLeft)\n                        buf[nLeft - j - 1] = tableFnUpper(idx + j);\n                }\n            }\n            return buf[nLeft - 1];\n        }\n\n        void popFront()\n        {\n            if (lower)\n                lwr.popFront();\n            else\n            {\n                if (!nLeft)\n                    front;\n                assert(nLeft);\n                --nLeft;\n                if (!nLeft)\n                {\n                    r.popFront();\n                    lwr = r.asLowerCase();\n                    lower = true;\n                }\n            }\n        }\n\n        static if (isForwardRange!Range)\n        {\n            @property auto save()\n            {\n                auto ret = this;\n                ret.r = r.save;\n                ret.lwr = lwr.save;\n                return ret;\n            }\n        }\n\n      private:\n        Range r;\n        typeof(r.asLowerCase) lwr; // range representing the lower case rest of string\n        bool lower = false;     // false for first character, true for rest of string\n        dchar[3] buf = void;\n        uint nLeft = 0;\n    }\n\n    return ToCapitalizerImpl(str);\n}\n\n/*********************\n * Capitalize an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n * or string, meaning convert the first\n * character to upper case and subsequent characters to lower case.\n *\n * Does not allocate memory.\n * Characters in UTF-8 or UTF-16 format that cannot be decoded\n * are treated as $(REF replacementDchar, std,utf).\n *\n * Params:\n *      str = string or range of characters\n *\n * Returns:\n *      an InputRange of dchars\n *\n * See_Also:\n *      $(LREF toUpper), $(LREF toLower)\n *      $(LREF asUpperCase), $(LREF asLowerCase)\n */\n\nauto asCapitalized(Range)(Range str)\nif (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) &&\n    !isConvertibleToString!Range)\n{\n    static if (ElementEncodingType!Range.sizeof < dchar.sizeof)\n    {\n        import std.utf : byDchar;\n\n        // Decode first\n        return toCapitalizer!UpperTriple(str.byDchar);\n    }\n    else\n    {\n        return toCapitalizer!UpperTriple(str);\n    }\n}\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    assert(\"hEllo\".asCapitalized.equal(\"Hello\"));\n}\n\nauto asCapitalized(Range)(auto ref Range str)\nif (isConvertibleToString!Range)\n{\n    import std.traits : StringTypeOf;\n    return asCapitalized!(StringTypeOf!Range)(str);\n}\n\n@safe unittest\n{\n    assert(testAliasedString!asCapitalized(\"hEllo\"));\n}\n\n@safe pure nothrow @nogc unittest\n{\n    auto r = \"hEllo\".asCapitalized();\n    assert(r.front == 'H');\n}\n\n@safe unittest\n{\n    import std.array : array;\n\n    auto a = \"hELLo\".asCapitalized;\n    auto savea = a.save;\n    auto s = a.array;\n    assert(s == \"Hello\");\n    s = savea.array;\n    assert(s == \"Hello\");\n\n    string[2][] cases =\n    [\n        [\"\", \"\"],\n        [\"h\", \"H\"],\n        [\"H\", \"H\"],\n        [\"3\", \"3\"],\n        [\"123\", \"123\"],\n        [\"h123A\", \"H123a\"],\n        [\"феж\", \"Феж\"],\n        [\"\\u1Fe2\", \"\\u03a5\\u0308\\u0300\"],\n    ];\n\n    foreach (i; 0 .. cases.length)\n    {\n        import std.utf : byChar;\n\n        auto r = cases[i][0].asCapitalized.byChar.array;\n        auto result = cases[i][1];\n        assert(r == result);\n    }\n\n    // Don't call r.front\n    for (auto r = \"\\u1Fe2\".asCapitalized; !r.empty; r.popFront())\n    {\n    }\n\n    import std.algorithm.comparison : equal;\n\n    \"HELLo\"w.asCapitalized.equal(\"Hello\"d);\n    \"hElLO\"w.asCapitalized.equal(\"Hello\"d);\n    \"hello\"d.asCapitalized.equal(\"Hello\"d);\n    \"HELLO\"d.asCapitalized.equal(\"Hello\"d);\n\n    import std.utf : byChar;\n    assert(asCapitalized(\"\\u0130\").byChar.array == asUpperCase(\"\\u0130\").byChar.array);\n}\n\n// TODO: helper, I wish std.utf was more flexible (and stright)\nprivate size_t encodeTo(scope char[] buf, size_t idx, dchar c) @trusted pure nothrow @nogc\n{\n    if (c <= 0x7F)\n    {\n        buf[idx] = cast(char) c;\n        idx++;\n    }\n    else if (c <= 0x7FF)\n    {\n        buf[idx] = cast(char)(0xC0 | (c >> 6));\n        buf[idx+1] = cast(char)(0x80 | (c & 0x3F));\n        idx += 2;\n    }\n    else if (c <= 0xFFFF)\n    {\n        buf[idx] = cast(char)(0xE0 | (c >> 12));\n        buf[idx+1] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n        buf[idx+2] = cast(char)(0x80 | (c & 0x3F));\n        idx += 3;\n    }\n    else if (c <= 0x10FFFF)\n    {\n        buf[idx] = cast(char)(0xF0 | (c >> 18));\n        buf[idx+1] = cast(char)(0x80 | ((c >> 12) & 0x3F));\n        buf[idx+2] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n        buf[idx+3] = cast(char)(0x80 | (c & 0x3F));\n        idx += 4;\n    }\n    else\n        assert(0);\n    return idx;\n}\n\n@safe unittest\n{\n    char[] s = \"abcd\".dup;\n    size_t i = 0;\n    i = encodeTo(s, i, 'X');\n    assert(s == \"Xbcd\");\n\n    i = encodeTo(s, i, cast(dchar)'\\u00A9');\n    assert(s == \"X\\xC2\\xA9d\");\n}\n\n// TODO: helper, I wish std.utf was more flexible (and stright)\nprivate size_t encodeTo(scope wchar[] buf, size_t idx, dchar c) @trusted pure\n{\n    import std.utf : UTFException;\n    if (c <= 0xFFFF)\n    {\n        if (0xD800 <= c && c <= 0xDFFF)\n            throw (new UTFException(\"Encoding an isolated surrogate code point in UTF-16\")).setSequence(c);\n        buf[idx] = cast(wchar) c;\n        idx++;\n    }\n    else if (c <= 0x10FFFF)\n    {\n        buf[idx] = cast(wchar)((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);\n        buf[idx+1] = cast(wchar)(((c - 0x10000) & 0x3FF) + 0xDC00);\n        idx += 2;\n    }\n    else\n        assert(0);\n    return idx;\n}\n\nprivate size_t encodeTo(scope dchar[] buf, size_t idx, dchar c) @trusted pure nothrow @nogc\n{\n    buf[idx] = c;\n    idx++;\n    return idx;\n}\n\nprivate void toCaseInPlace(alias indexFn, uint maxIdx, alias tableFn, C)(ref C[] s) @trusted pure\nif (is(C == char) || is(C == wchar)  || is(C == dchar))\n{\n    import std.utf : decode, codeLength;\n    size_t curIdx = 0;\n    size_t destIdx = 0;\n    alias slowToCase = toCaseInPlaceAlloc!(indexFn, maxIdx, tableFn);\n    size_t lastUnchanged = 0;\n    // in-buffer move of bytes to a new start index\n    // the trick is that it may not need to copy at all\n    static size_t moveTo(C[] str, size_t dest, size_t from, size_t to)\n    {\n        // Interestingly we may just bump pointer for a while\n        // then have to copy if a re-cased char was smaller the original\n        // later we may regain pace with char that got bigger\n        // In the end it sometimes flip-flops between the 2 cases below\n        if (dest == from)\n            return to;\n        // got to copy\n        foreach (C c; str[from .. to])\n            str[dest++] = c;\n        return dest;\n    }\n    while (curIdx != s.length)\n    {\n        size_t startIdx = curIdx;\n        immutable ch = decode(s, curIdx);\n        // TODO: special case for ASCII\n        immutable caseIndex = indexFn(ch);\n        if (caseIndex == ushort.max) // unchanged, skip over\n        {\n            continue;\n        }\n        else if (caseIndex < maxIdx)  // 1:1 codepoint mapping\n        {\n            // previous cased chars had the same length as uncased ones\n            // thus can just adjust pointer\n            destIdx = moveTo(s, destIdx, lastUnchanged, startIdx);\n            lastUnchanged = curIdx;\n            immutable cased = tableFn(caseIndex);\n            immutable casedLen = codeLength!C(cased);\n            if (casedLen + destIdx > curIdx) // no place to fit cased char\n            {\n                // switch to slow codepath, where we allocate\n                return slowToCase(s, startIdx, destIdx);\n            }\n            else\n            {\n                destIdx = encodeTo(s, destIdx, cased);\n            }\n        }\n        else  // 1:m codepoint mapping, slow codepath\n        {\n            destIdx = moveTo(s, destIdx, lastUnchanged, startIdx);\n            lastUnchanged = curIdx;\n            return slowToCase(s, startIdx, destIdx);\n        }\n        assert(destIdx <= curIdx);\n    }\n    if (lastUnchanged != s.length)\n    {\n        destIdx = moveTo(s, destIdx, lastUnchanged, s.length);\n    }\n    s = s[0 .. destIdx];\n}\n\n// helper to precalculate size of case-converted string\nprivate template toCaseLength(alias indexFn, uint maxIdx, alias tableFn)\n{\n    size_t toCaseLength(C)(const scope C[] str)\n    {\n        import std.utf : decode, codeLength;\n        size_t codeLen = 0;\n        size_t lastNonTrivial = 0;\n        size_t curIdx = 0;\n        while (curIdx != str.length)\n        {\n            immutable startIdx = curIdx;\n            immutable ch = decode(str, curIdx);\n            immutable ushort caseIndex = indexFn(ch);\n            if (caseIndex == ushort.max)\n                continue;\n            else if (caseIndex < maxIdx)\n            {\n                codeLen += startIdx - lastNonTrivial;\n                lastNonTrivial = curIdx;\n                immutable cased = tableFn(caseIndex);\n                codeLen += codeLength!C(cased);\n            }\n            else\n            {\n                codeLen += startIdx - lastNonTrivial;\n                lastNonTrivial = curIdx;\n                immutable val = tableFn(caseIndex);\n                immutable len = val >> 24;\n                immutable dchar cased = val & 0xFF_FFFF;\n                codeLen += codeLength!C(cased);\n                foreach (j; caseIndex+1 .. caseIndex+len)\n                    codeLen += codeLength!C(tableFn(j));\n            }\n        }\n        if (lastNonTrivial != str.length)\n            codeLen += str.length - lastNonTrivial;\n        return codeLen;\n    }\n}\n\n@safe unittest\n{\n    alias toLowerLength = toCaseLength!(LowerTriple);\n    assert(toLowerLength(\"abcd\") == 4);\n    assert(toLowerLength(\"аБВгд456\") == 10+3);\n}\n\n// slower code path that preallocates and then copies\n// case-converted stuf to the new string\nprivate template toCaseInPlaceAlloc(alias indexFn, uint maxIdx, alias tableFn)\n{\n    void toCaseInPlaceAlloc(C)(ref C[] s, size_t curIdx,\n        size_t destIdx) @trusted pure\n        if (is(C == char) || is(C == wchar) || is(C == dchar))\n    {\n        import std.utf : decode;\n        alias caseLength = toCaseLength!(indexFn, maxIdx, tableFn);\n        auto trueLength = destIdx + caseLength(s[curIdx..$]);\n        C[] ns = new C[trueLength];\n        ns[0 .. destIdx] = s[0 .. destIdx];\n        size_t lastUnchanged = curIdx;\n        while (curIdx != s.length)\n        {\n            immutable startIdx = curIdx; // start of current codepoint\n            immutable ch = decode(s, curIdx);\n            immutable caseIndex = indexFn(ch);\n            if (caseIndex == ushort.max) // skip over\n            {\n                continue;\n            }\n            else if (caseIndex < maxIdx)  // 1:1 codepoint mapping\n            {\n                immutable cased = tableFn(caseIndex);\n                auto toCopy = startIdx - lastUnchanged;\n                ns[destIdx .. destIdx+toCopy] = s[lastUnchanged .. startIdx];\n                lastUnchanged = curIdx;\n                destIdx += toCopy;\n                destIdx = encodeTo(ns, destIdx, cased);\n            }\n            else  // 1:m codepoint mapping, slow codepath\n            {\n                auto toCopy = startIdx - lastUnchanged;\n                ns[destIdx .. destIdx+toCopy] = s[lastUnchanged .. startIdx];\n                lastUnchanged = curIdx;\n                destIdx += toCopy;\n                auto val = tableFn(caseIndex);\n                // unpack length + codepoint\n                immutable uint len = val >> 24;\n                destIdx = encodeTo(ns, destIdx, cast(dchar)(val & 0xFF_FFFF));\n                foreach (j; caseIndex+1 .. caseIndex+len)\n                    destIdx = encodeTo(ns, destIdx, tableFn(j));\n            }\n        }\n        if (lastUnchanged != s.length)\n        {\n            auto toCopy = s.length - lastUnchanged;\n            ns[destIdx .. destIdx+toCopy] = s[lastUnchanged..$];\n            destIdx += toCopy;\n        }\n        assert(ns.length == destIdx);\n        s = ns;\n    }\n}\n\n/++\n    Converts `s` to lowercase (by performing Unicode lowercase mapping) in place.\n    For a few characters string length may increase after the transformation,\n    in such a case the function reallocates exactly once.\n    If `s` does not have any uppercase characters, then `s` is unaltered.\n+/\nvoid toLowerInPlace(C)(ref C[] s) @trusted pure\nif (is(C == char) || is(C == wchar) || is(C == dchar))\n{\n    toCaseInPlace!(LowerTriple)(s);\n}\n// overloads for the most common cases to reduce compile time\n@safe pure /*TODO nothrow*/\n{\n    void toLowerInPlace(ref char[] s)\n    { toLowerInPlace!char(s); }\n    void toLowerInPlace(ref wchar[] s)\n    { toLowerInPlace!wchar(s); }\n    void toLowerInPlace(ref dchar[] s)\n    { toLowerInPlace!dchar(s); }\n}\n\n/++\n    Converts `s` to uppercase  (by performing Unicode uppercase mapping) in place.\n    For a few characters string length may increase after the transformation,\n    in such a case the function reallocates exactly once.\n    If `s` does not have any lowercase characters, then `s` is unaltered.\n+/\nvoid toUpperInPlace(C)(ref C[] s) @trusted pure\nif (is(C == char) || is(C == wchar) || is(C == dchar))\n{\n    toCaseInPlace!(UpperTriple)(s);\n}\n// overloads for the most common cases to reduce compile time/code size\n@safe pure /*TODO nothrow*/\n{\n    void toUpperInPlace(ref char[] s)\n    { toUpperInPlace!char(s); }\n    void toUpperInPlace(ref wchar[] s)\n    { toUpperInPlace!wchar(s); }\n    void toUpperInPlace(ref dchar[] s)\n    { toUpperInPlace!dchar(s); }\n}\n\n/++\n    If `c` is a Unicode uppercase $(CHARACTER), then its lowercase equivalent\n    is returned. Otherwise `c` is returned.\n\n    Warning: certain alphabets like German and Greek have no 1:1\n    upper-lower mapping. Use overload of toLower which takes full string instead.\n+/\n@safe pure nothrow @nogc\ndchar toLower(dchar c)\n{\n     // optimize ASCII case\n    if (c < 0xAA)\n    {\n        if (c < 'A')\n            return c;\n        if (c <= 'Z')\n            return c + 32;\n        return c;\n    }\n    size_t idx = toLowerSimpleIndex(c);\n    if (idx != ushort.max)\n    {\n        return toLowerTab(idx);\n    }\n    return c;\n}\n\n/++\n    Creates a new array which is identical to `s` except that all of its\n    characters are converted to lowercase (by preforming Unicode lowercase mapping).\n    If none of `s` characters were affected, then `s` itself is returned if `s` is a\n    `string`-like type.\n\n    Params:\n        s = A $(REF_ALTTEXT random access range, isRandomAccessRange, std,range,primitives)\n        of characters\n    Returns:\n        An array with the same element type as `s`.\n+/\nElementEncodingType!S[] toLower(S)(S s)\nif (isSomeString!S || (isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S)))\n{\n    static import std.ascii;\n\n    static if (isSomeString!S)\n        return () @trusted { return toCase!(LowerTriple, std.ascii.toLower)(s); } ();\n    else\n        return toCase!(LowerTriple, std.ascii.toLower)(s);\n}\n\n// overloads for the most common cases to reduce compile time\n@safe pure /*TODO nothrow*/\n{\n    string toLower(string s)\n    { return toLower!string(s); }\n    wstring toLower(wstring s)\n    { return toLower!wstring(s); }\n    dstring toLower(dstring s)\n    { return toLower!dstring(s); }\n\n    @safe unittest\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=16663\n\n        static struct String\n        {\n            string data;\n            alias data this;\n        }\n\n        void foo()\n        {\n            auto u = toLower(String(\"\"));\n        }\n    }\n}\n\n\n@safe unittest\n{\n    static import std.ascii;\n    import std.format : format;\n    foreach (ch; 0 .. 0x80)\n        assert(std.ascii.toLower(ch) == toLower(ch));\n    assert(toLower('Я') == 'я');\n    assert(toLower('Δ') == 'δ');\n    foreach (ch; unicode.upperCase.byCodepoint)\n    {\n        dchar low = ch.toLower();\n        assert(low == ch || isLower(low), format(\"%s -> %s\", ch, low));\n    }\n    assert(toLower(\"АЯ\") == \"ая\");\n\n    assert(\"\\u1E9E\".toLower == \"\\u00df\");\n    assert(\"\\u00df\".toUpper == \"SS\");\n}\n\n//bugzilla 9629\n@safe unittest\n{\n    wchar[] test = \"hello þ world\"w.dup;\n    auto piece = test[6 .. 7];\n    toUpperInPlace(piece);\n    assert(test == \"hello Þ world\");\n}\n\n\n@safe unittest\n{\n    import std.algorithm.comparison : cmp;\n    string s1 = \"FoL\";\n    string s2 = toLower(s1);\n    assert(cmp(s2, \"fol\") == 0, s2);\n    assert(s2 != s1);\n\n    char[] s3 = s1.dup;\n    toLowerInPlace(s3);\n    assert(s3 == s2);\n\n    s1 = \"A\\u0100B\\u0101d\";\n    s2 = toLower(s1);\n    s3 = s1.dup;\n    assert(cmp(s2, \"a\\u0101b\\u0101d\") == 0);\n    assert(s2 !is s1);\n    toLowerInPlace(s3);\n    assert(s3 == s2);\n\n    s1 = \"A\\u0460B\\u0461d\";\n    s2 = toLower(s1);\n    s3 = s1.dup;\n    assert(cmp(s2, \"a\\u0461b\\u0461d\") == 0);\n    assert(s2 !is s1);\n    toLowerInPlace(s3);\n    assert(s3 == s2);\n\n    s1 = \"\\u0130\";\n    s2 = toLower(s1);\n    s3 = s1.dup;\n    assert(s2 == \"i\\u0307\");\n    assert(s2 !is s1);\n    toLowerInPlace(s3);\n    assert(s3 == s2);\n\n    // Test on wchar and dchar strings.\n    assert(toLower(\"Some String\"w) == \"some string\"w);\n    assert(toLower(\"Some String\"d) == \"some string\"d);\n\n    // bugzilla 12455\n    dchar c = 'İ'; // '\\U0130' LATIN CAPITAL LETTER I WITH DOT ABOVE\n    assert(isUpper(c));\n    assert(toLower(c) == 'i');\n    // extend on 12455 reprot - check simple-case toUpper too\n    c = '\\u1f87';\n    assert(isLower(c));\n    assert(toUpper(c) == '\\u1F8F');\n}\n\n@safe pure unittest\n{\n    import std.algorithm.comparison : cmp, equal;\n    import std.utf : byCodeUnit;\n    auto r1 = \"FoL\".byCodeUnit;\n    assert(r1.toLower.cmp(\"fol\") == 0);\n    auto r2 = \"A\\u0460B\\u0461d\".byCodeUnit;\n    assert(r2.toLower.cmp(\"a\\u0461b\\u0461d\") == 0);\n}\n\n/++\n    If `c` is a Unicode lowercase $(CHARACTER), then its uppercase equivalent\n    is returned. Otherwise `c` is returned.\n\n    Warning:\n    Certain alphabets like German and Greek have no 1:1\n    upper-lower mapping. Use overload of toUpper which takes full string instead.\n\n    toUpper can be used as an argument to $(REF map, std,algorithm,iteration)\n    to produce an algorithm that can convert a range of characters to upper case\n    without allocating memory.\n    A string can then be produced by using $(REF copy, std,algorithm,mutation)\n    to send it to an $(REF appender, std,array).\n+/\n@safe pure nothrow @nogc\ndchar toUpper(dchar c)\n{\n    // optimize ASCII case\n    if (c < 0xAA)\n    {\n        if (c < 'a')\n            return c;\n        if (c <= 'z')\n            return c - 32;\n        return c;\n    }\n    size_t idx = toUpperSimpleIndex(c);\n    if (idx != ushort.max)\n    {\n        return toUpperTab(idx);\n    }\n    return c;\n}\n\n///\n@safe unittest\n{\n    import std.algorithm.iteration : map;\n    import std.algorithm.mutation : copy;\n    import std.array : appender;\n\n    auto abuf = appender!(char[])();\n    \"hello\".map!toUpper.copy(abuf);\n    assert(abuf.data == \"HELLO\");\n}\n\n@safe unittest\n{\n    static import std.ascii;\n    import std.format : format;\n    foreach (ch; 0 .. 0x80)\n        assert(std.ascii.toUpper(ch) == toUpper(ch));\n    assert(toUpper('я') == 'Я');\n    assert(toUpper('δ') == 'Δ');\n    auto title = unicode.Titlecase_Letter;\n    foreach (ch; unicode.lowerCase.byCodepoint)\n    {\n        dchar up = ch.toUpper();\n        assert(up == ch || isUpper(up) || title[up],\n            format(\"%x -> %x\", ch, up));\n    }\n}\n\n/++\n    Allocates a new array which is identical to `s` except that all of its\n    characters are converted to uppercase (by preforming Unicode uppercase mapping).\n    If none of `s` characters were affected, then `s` itself is returned if `s`\n    is a `string`-like type.\n\n    Params:\n        s = A $(REF_ALTTEXT random access range, isRandomAccessRange, std,range,primitives)\n        of characters\n    Returns:\n        An new array with the same element type as `s`.\n+/\nElementEncodingType!S[] toUpper(S)(S s)\nif (isSomeString!S || (isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S)))\n{\n    static import std.ascii;\n\n    static if (isSomeString!S)\n        return () @trusted { return toCase!(UpperTriple, std.ascii.toUpper)(s); } ();\n    else\n        return toCase!(UpperTriple, std.ascii.toUpper)(s);\n}\n\n// overloads for the most common cases to reduce compile time\n@safe pure /*TODO nothrow*/\n{\n    string toUpper(string s)\n    { return toUpper!string(s); }\n    wstring toUpper(wstring s)\n    { return toUpper!wstring(s); }\n    dstring toUpper(dstring s)\n    { return toUpper!dstring(s); }\n\n    @safe unittest\n    {\n        // https://issues.dlang.org/show_bug.cgi?id=16663\n\n        static struct String\n        {\n            string data;\n            alias data this;\n        }\n\n        void foo()\n        {\n            auto u = toUpper(String(\"\"));\n        }\n    }\n}\n\n@safe unittest\n{\n    import std.algorithm.comparison : cmp;\n\n    string s1 = \"FoL\";\n    string s2;\n    char[] s3;\n\n    s2 = toUpper(s1);\n    s3 = s1.dup; toUpperInPlace(s3);\n    assert(s3 == s2, s3);\n    assert(cmp(s2, \"FOL\") == 0);\n    assert(s2 !is s1);\n\n    s1 = \"a\\u0100B\\u0101d\";\n    s2 = toUpper(s1);\n    s3 = s1.dup; toUpperInPlace(s3);\n    assert(s3 == s2);\n    assert(cmp(s2, \"A\\u0100B\\u0100D\") == 0);\n    assert(s2 !is s1);\n\n    s1 = \"a\\u0460B\\u0461d\";\n    s2 = toUpper(s1);\n    s3 = s1.dup; toUpperInPlace(s3);\n    assert(s3 == s2);\n    assert(cmp(s2, \"A\\u0460B\\u0460D\") == 0);\n    assert(s2 !is s1);\n}\n\n@system unittest\n{\n    static void doTest(C)(const(C)[] s, const(C)[] trueUp, const(C)[] trueLow)\n    {\n        import std.format : format;\n        string diff = \"src: %( %x %)\\nres: %( %x %)\\ntru: %( %x %)\";\n        auto low = s.toLower() , up = s.toUpper();\n        auto lowInp = s.dup, upInp = s.dup;\n        lowInp.toLowerInPlace();\n        upInp.toUpperInPlace();\n        assert(low == trueLow, format(diff, low, trueLow));\n        assert(up == trueUp,  format(diff, up, trueUp));\n        assert(lowInp == trueLow,\n            format(diff, cast(ubyte[]) s, cast(ubyte[]) lowInp, cast(ubyte[]) trueLow));\n        assert(upInp == trueUp,\n            format(diff, cast(ubyte[]) s, cast(ubyte[]) upInp, cast(ubyte[]) trueUp));\n    }\n    static foreach (S; AliasSeq!(dstring, wstring, string))\n    {{\n\n        S easy = \"123\";\n        S good = \"abCФеж\";\n        S awful = \"\\u0131\\u023f\\u2126\";\n        S wicked = \"\\u0130\\u1FE2\";\n        auto options = [easy, good, awful, wicked];\n        S[] lower = [\"123\", \"abcфеж\", \"\\u0131\\u023f\\u03c9\", \"i\\u0307\\u1Fe2\"];\n        S[] upper = [\"123\", \"ABCФЕЖ\", \"I\\u2c7e\\u2126\", \"\\u0130\\u03A5\\u0308\\u0300\"];\n\n        foreach (val; [easy, good])\n        {\n            auto e = val.dup;\n            auto g = e;\n            e.toUpperInPlace();\n            assert(e is g);\n            e.toLowerInPlace();\n            assert(e is g);\n        }\n        foreach (i, v; options)\n        {\n            doTest(v, upper[i], lower[i]);\n        }\n\n        // a few combinatorial runs\n        foreach (i; 0 .. options.length)\n        foreach (j; i .. options.length)\n        foreach (k; j .. options.length)\n        {\n            auto sample = options[i] ~ options[j] ~ options[k];\n            auto sample2 = options[k] ~ options[j] ~ options[i];\n            doTest(sample, upper[i] ~ upper[j] ~ upper[k],\n                lower[i] ~ lower[j] ~ lower[k]);\n            doTest(sample2, upper[k] ~ upper[j] ~ upper[i],\n                lower[k] ~ lower[j] ~ lower[i]);\n        }\n    }}\n}\n\n// test random access ranges\n@safe pure unittest\n{\n    import std.algorithm.comparison : cmp;\n    import std.utf : byCodeUnit;\n    auto s1 = \"FoL\".byCodeUnit;\n    assert(s1.toUpper.cmp(\"FOL\") == 0);\n    auto s2 = \"a\\u0460B\\u0461d\".byCodeUnit;\n    assert(s2.toUpper.cmp(\"A\\u0460B\\u0460D\") == 0);\n}\n\n/++\n    Returns whether `c` is a Unicode alphabetic $(CHARACTER)\n    (general Unicode category: Alphabetic).\n+/\n@safe pure nothrow @nogc\nbool isAlpha(dchar c)\n{\n    // optimization\n    if (c < 0xAA)\n    {\n        size_t x = c - 'A';\n        if (x <= 'Z' - 'A')\n            return true;\n        else\n        {\n            x = c - 'a';\n            if (x <= 'z'-'a')\n                return true;\n        }\n        return false;\n    }\n\n    return alphaTrie[c];\n}\n\n@safe unittest\n{\n    auto alpha = unicode(\"Alphabetic\");\n    foreach (ch; alpha.byCodepoint)\n        assert(isAlpha(ch));\n    foreach (ch; 0 .. 0x4000)\n        assert((ch in alpha) == isAlpha(ch));\n}\n\n\n/++\n    Returns whether `c` is a Unicode mark\n    (general Unicode category: Mn, Me, Mc).\n+/\n@safe pure nothrow @nogc\nbool isMark(dchar c)\n{\n    return markTrie[c];\n}\n\n@safe unittest\n{\n    auto mark = unicode(\"Mark\");\n    foreach (ch; mark.byCodepoint)\n        assert(isMark(ch));\n    foreach (ch; 0 .. 0x4000)\n        assert((ch in mark) == isMark(ch));\n}\n\n/++\n    Returns whether `c` is a Unicode numerical $(CHARACTER)\n    (general Unicode category: Nd, Nl, No).\n+/\n@safe pure nothrow @nogc\nbool isNumber(dchar c)\n{\n    // optimization for ascii case\n    if (c <= 0x7F)\n    {\n        return c >= '0' && c <= '9';\n    }\n    else\n    {\n        return numberTrie[c];\n    }\n}\n\n@safe unittest\n{\n    auto n = unicode(\"N\");\n    foreach (ch; n.byCodepoint)\n        assert(isNumber(ch));\n    foreach (ch; 0 .. 0x4000)\n        assert((ch in n) == isNumber(ch));\n}\n\n/++\n    Returns whether `c` is a Unicode alphabetic $(CHARACTER) or number.\n    (general Unicode category: Alphabetic, Nd, Nl, No).\n\n    Params:\n        c = any Unicode character\n    Returns:\n        `true` if the character is in the Alphabetic, Nd, Nl, or No Unicode\n        categories\n+/\n@safe pure nothrow @nogc\nbool isAlphaNum(dchar c)\n{\n    static import std.ascii;\n\n    // optimization for ascii case\n    if (std.ascii.isASCII(c))\n    {\n        return std.ascii.isAlphaNum(c);\n    }\n    else\n    {\n        return isAlpha(c) || isNumber(c);\n    }\n}\n\n@safe unittest\n{\n    auto n = unicode(\"N\");\n    auto alpha = unicode(\"Alphabetic\");\n\n    foreach (ch; n.byCodepoint)\n        assert(isAlphaNum(ch));\n\n    foreach (ch; alpha.byCodepoint)\n        assert(isAlphaNum(ch));\n\n    foreach (ch; 0 .. 0x4000)\n    {\n        assert(((ch in n) || (ch in alpha)) == isAlphaNum(ch));\n    }\n}\n\n/++\n    Returns whether `c` is a Unicode punctuation $(CHARACTER)\n    (general Unicode category: Pd, Ps, Pe, Pc, Po, Pi, Pf).\n+/\n@safe pure nothrow @nogc\nbool isPunctuation(dchar c)\n{\n    static import std.ascii;\n\n    // optimization for ascii case\n    if (c <= 0x7F)\n    {\n        return std.ascii.isPunctuation(c);\n    }\n    else\n    {\n        return punctuationTrie[c];\n    }\n}\n\n@safe unittest\n{\n    assert(isPunctuation('\\u0021'));\n    assert(isPunctuation('\\u0028'));\n    assert(isPunctuation('\\u0029'));\n    assert(isPunctuation('\\u002D'));\n    assert(isPunctuation('\\u005F'));\n    assert(isPunctuation('\\u00AB'));\n    assert(isPunctuation('\\u00BB'));\n    foreach (ch; unicode(\"P\").byCodepoint)\n        assert(isPunctuation(ch));\n}\n\n/++\n    Returns whether `c` is a Unicode symbol $(CHARACTER)\n    (general Unicode category: Sm, Sc, Sk, So).\n+/\n@safe pure nothrow @nogc\nbool isSymbol(dchar c)\n{\n   return symbolTrie[c];\n}\n\n@safe unittest\n{\n    import std.format : format;\n    assert(isSymbol('\\u0024'));\n    assert(isSymbol('\\u002B'));\n    assert(isSymbol('\\u005E'));\n    assert(isSymbol('\\u00A6'));\n    foreach (ch; unicode(\"S\").byCodepoint)\n        assert(isSymbol(ch), format(\"%04x\", ch));\n}\n\n/++\n    Returns whether `c` is a Unicode space $(CHARACTER)\n    (general Unicode category: Zs)\n    Note: This doesn't include '\\n', '\\r', \\t' and other non-space $(CHARACTER).\n    For commonly used less strict semantics see $(LREF isWhite).\n+/\n@safe pure nothrow @nogc\nbool isSpace(dchar c)\n{\n    import std.internal.unicode_tables : isSpaceGen; // generated file\n    return isSpaceGen(c);\n}\n\n@safe unittest\n{\n    assert(isSpace('\\u0020'));\n    auto space = unicode.Zs;\n    foreach (ch; space.byCodepoint)\n        assert(isSpace(ch));\n    foreach (ch; 0 .. 0x1000)\n        assert(isSpace(ch) == space[ch]);\n}\n\n\n/++\n    Returns whether `c` is a Unicode graphical $(CHARACTER)\n    (general Unicode category: L, M, N, P, S, Zs).\n\n+/\n@safe pure nothrow @nogc\nbool isGraphical(dchar c)\n{\n    return graphicalTrie[c];\n}\n\n\n@safe unittest\n{\n    auto set = unicode(\"Graphical\");\n    import std.format : format;\n    foreach (ch; set.byCodepoint)\n        assert(isGraphical(ch), format(\"%4x\", ch));\n    foreach (ch; 0 .. 0x4000)\n        assert((ch in set) == isGraphical(ch));\n}\n\n\n/++\n    Returns whether `c` is a Unicode control $(CHARACTER)\n    (general Unicode category: Cc).\n+/\n@safe pure nothrow @nogc\nbool isControl(dchar c)\n{\n    import std.internal.unicode_tables : isControlGen; // generated file\n    return isControlGen(c);\n}\n\n@safe unittest\n{\n    assert(isControl('\\u0000'));\n    assert(isControl('\\u0081'));\n    assert(!isControl('\\u0100'));\n    auto cc = unicode.Cc;\n    foreach (ch; cc.byCodepoint)\n        assert(isControl(ch));\n    foreach (ch; 0 .. 0x1000)\n        assert(isControl(ch) == cc[ch]);\n}\n\n\n/++\n    Returns whether `c` is a Unicode formatting $(CHARACTER)\n    (general Unicode category: Cf).\n+/\n@safe pure nothrow @nogc\nbool isFormat(dchar c)\n{\n    import std.internal.unicode_tables : isFormatGen; // generated file\n    return isFormatGen(c);\n}\n\n\n@safe unittest\n{\n    assert(isFormat('\\u00AD'));\n    foreach (ch; unicode(\"Format\").byCodepoint)\n        assert(isFormat(ch));\n}\n\n// code points for private use, surrogates are not likely to change in near feature\n// if need be they can be generated from unicode data as well\n\n/++\n    Returns whether `c` is a Unicode Private Use $(CODEPOINT)\n    (general Unicode category: Co).\n+/\n@safe pure nothrow @nogc\nbool isPrivateUse(dchar c)\n{\n    return (0x00_E000 <= c && c <= 0x00_F8FF)\n        || (0x0F_0000 <= c && c <= 0x0F_FFFD)\n        || (0x10_0000 <= c && c <= 0x10_FFFD);\n}\n\n/++\n    Returns whether `c` is a Unicode surrogate $(CODEPOINT)\n    (general Unicode category: Cs).\n+/\n@safe pure nothrow @nogc\nbool isSurrogate(dchar c)\n{\n    return (0xD800 <= c && c <= 0xDFFF);\n}\n\n/++\n    Returns whether `c` is a Unicode high surrogate (lead surrogate).\n+/\n@safe pure nothrow @nogc\nbool isSurrogateHi(dchar c)\n{\n    return (0xD800 <= c && c <= 0xDBFF);\n}\n\n/++\n    Returns whether `c` is a Unicode low surrogate (trail surrogate).\n+/\n@safe pure nothrow @nogc\nbool isSurrogateLo(dchar c)\n{\n    return (0xDC00 <= c && c <= 0xDFFF);\n}\n\n/++\n    Returns whether `c` is a Unicode non-character i.e.\n    a $(CODEPOINT) with no assigned abstract character.\n    (general Unicode category: Cn)\n+/\n@safe pure nothrow @nogc\nbool isNonCharacter(dchar c)\n{\n    return nonCharacterTrie[c];\n}\n\n@safe unittest\n{\n    auto set = unicode(\"Cn\");\n    foreach (ch; set.byCodepoint)\n        assert(isNonCharacter(ch));\n}\n\nprivate:\n// load static data from pre-generated tables into usable datastructures\n\n\n@safe auto asSet(const (ubyte)[] compressed) pure\n{\n    return CodepointSet.fromIntervals(decompressIntervals(compressed));\n}\n\n@safe pure nothrow auto asTrie(T...)(const scope TrieEntry!T e)\n{\n    return const(CodepointTrie!T)(e.offsets, e.sizes, e.data);\n}\n\n@safe pure nothrow @nogc @property\n{\n    import std.internal.unicode_tables; // generated file\n\n    // It's important to use auto return here, so that the compiler\n    // only runs semantic on the return type if the function gets\n    // used. Also these are functions rather than templates to not\n    // increase the object size of the caller.\n    auto lowerCaseTrie() { static immutable res = asTrie(lowerCaseTrieEntries); return res; }\n    auto upperCaseTrie() { static immutable res = asTrie(upperCaseTrieEntries); return res; }\n    auto simpleCaseTrie() { static immutable res = asTrie(simpleCaseTrieEntries); return res; }\n    auto fullCaseTrie() { static immutable res = asTrie(fullCaseTrieEntries); return res; }\n    auto alphaTrie() { static immutable res = asTrie(alphaTrieEntries); return res; }\n    auto markTrie() { static immutable res = asTrie(markTrieEntries); return res; }\n    auto numberTrie() { static immutable res = asTrie(numberTrieEntries); return res; }\n    auto punctuationTrie() { static immutable res = asTrie(punctuationTrieEntries); return res; }\n    auto symbolTrie() { static immutable res = asTrie(symbolTrieEntries); return res; }\n    auto graphicalTrie() { static immutable res = asTrie(graphicalTrieEntries); return res; }\n    auto nonCharacterTrie() { static immutable res = asTrie(nonCharacterTrieEntries); return res; }\n\n    //normalization quick-check tables\n    auto nfcQCTrie()\n    {\n        import std.internal.unicode_norm : nfcQCTrieEntries;\n        static immutable res = asTrie(nfcQCTrieEntries);\n        return res;\n    }\n\n    auto nfdQCTrie()\n    {\n        import std.internal.unicode_norm : nfdQCTrieEntries;\n        static immutable res = asTrie(nfdQCTrieEntries);\n        return res;\n    }\n\n    auto nfkcQCTrie()\n    {\n        import std.internal.unicode_norm : nfkcQCTrieEntries;\n        static immutable res = asTrie(nfkcQCTrieEntries);\n        return res;\n    }\n\n    auto nfkdQCTrie()\n    {\n        import std.internal.unicode_norm : nfkdQCTrieEntries;\n        static immutable res = asTrie(nfkdQCTrieEntries);\n        return res;\n    }\n\n    //grapheme breaking algorithm tables\n    auto mcTrie()\n    {\n        import std.internal.unicode_grapheme : mcTrieEntries;\n        static immutable res = asTrie(mcTrieEntries);\n        return res;\n    }\n\n    auto graphemeExtendTrie()\n    {\n        import std.internal.unicode_grapheme : graphemeExtendTrieEntries;\n        static immutable res = asTrie(graphemeExtendTrieEntries);\n        return res;\n    }\n\n    auto hangLV()\n    {\n        import std.internal.unicode_grapheme : hangulLVTrieEntries;\n        static immutable res = asTrie(hangulLVTrieEntries);\n        return res;\n    }\n\n    auto hangLVT()\n    {\n        import std.internal.unicode_grapheme : hangulLVTTrieEntries;\n        static immutable res = asTrie(hangulLVTTrieEntries);\n        return res;\n    }\n\n    // tables below are used for composition/decomposition\n    auto combiningClassTrie()\n    {\n        import std.internal.unicode_comp : combiningClassTrieEntries;\n        static immutable res = asTrie(combiningClassTrieEntries);\n        return res;\n    }\n\n    auto compatMappingTrie()\n    {\n        import std.internal.unicode_decomp : compatMappingTrieEntries;\n        static immutable res = asTrie(compatMappingTrieEntries);\n        return res;\n    }\n\n    auto canonMappingTrie()\n    {\n        import std.internal.unicode_decomp : canonMappingTrieEntries;\n        static immutable res = asTrie(canonMappingTrieEntries);\n        return res;\n    }\n\n    auto compositionJumpTrie()\n    {\n        import std.internal.unicode_comp : compositionJumpTrieEntries;\n        static immutable res = asTrie(compositionJumpTrieEntries);\n        return res;\n    }\n\n    //case conversion tables\n    auto toUpperIndexTrie() { static immutable res = asTrie(toUpperIndexTrieEntries); return res; }\n    auto toLowerIndexTrie() { static immutable res = asTrie(toLowerIndexTrieEntries); return res; }\n    auto toTitleIndexTrie() { static immutable res = asTrie(toTitleIndexTrieEntries); return res; }\n    //simple case conversion tables\n    auto toUpperSimpleIndexTrie() { static immutable res = asTrie(toUpperSimpleIndexTrieEntries); return res; }\n    auto toLowerSimpleIndexTrie() { static immutable res = asTrie(toLowerSimpleIndexTrieEntries); return res; }\n    auto toTitleSimpleIndexTrie() { static immutable res = asTrie(toTitleSimpleIndexTrieEntries); return res; }\n\n}\n\n}// version (!std_uni_bootstrap)\n"
  },
  {
    "path": "libphobos/src/std/uri.d",
    "content": "// Written in the D programming language.\n\n/**\n * Encode and decode Uniform Resource Identifiers (URIs).\n * URIs are used in internet transfer protocols.\n * Valid URI characters consist of letters, digits,\n * and the characters $(B ;/?:@&amp;=+$,-_.!~*'())\n * Reserved URI characters are $(B ;/?:@&amp;=+$,)\n * Escape sequences consist of $(B %) followed by two hex digits.\n *\n * See_Also:\n *  $(LINK2 http://www.ietf.org/rfc/rfc3986.txt, RFC 3986)<br>\n *  $(LINK2 http://en.wikipedia.org/wiki/Uniform_resource_identifier, Wikipedia)\n * Copyright: Copyright The D Language Foundation 2000 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright)\n * Source:    $(PHOBOSSRC std/uri.d)\n */\n/*          Copyright The D Language Foundation 2000 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.uri;\n\n//debug=uri;        // uncomment to turn on debugging writefln's\ndebug(uri) import std.stdio;\nimport std.traits : isSomeChar;\n\n/** This Exception is thrown if something goes wrong when encoding or\ndecoding a URI.\n*/\nclass URIException : Exception\n{\n    import std.exception : basicExceptionCtors;\n    mixin basicExceptionCtors;\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    assertThrown!URIException(\"%ab\".decode);\n}\n\nprivate enum\n{\n    URI_Alpha = 1,\n    URI_Reserved = 2,\n    URI_Mark = 4,\n    URI_Digit = 8,\n    URI_Hash = 0x10,        // '#'\n}\n\nprivate immutable char[16] hex2ascii = \"0123456789ABCDEF\";\n\nprivate immutable ubyte[128] uri_flags =      // indexed by character\n    ({\n        ubyte[128] uflags;\n\n        // Compile time initialize\n        uflags['#'] |= URI_Hash;\n\n        foreach (c; 'A' .. 'Z' + 1)\n        {\n            uflags[c] |= URI_Alpha;\n            uflags[c + 0x20] |= URI_Alpha;   // lowercase letters\n        }\n        foreach (c; '0' .. '9' + 1) uflags[c] |= URI_Digit;\n        foreach (c; \";/?:@&=+$,\")   uflags[c] |= URI_Reserved;\n        foreach (c; \"-_.!~*'()\")    uflags[c] |= URI_Mark;\n        return uflags;\n    })();\n\nprivate string URI_Encode(dstring str, uint unescapedSet) @safe pure\n{\n    uint j;\n    uint k;\n    dchar V;\n    dchar C;\n\n    // result buffer\n    char[50] buffer = void;\n    char[] R;\n    uint Rlen;\n    uint Rsize; // alloc'd size\n\n    immutable len = str.length;\n\n    R = buffer[];\n    Rsize = buffer.length;\n    Rlen = 0;\n\n    for (k = 0; k != len; k++)\n    {\n        C = str[k];\n        // if (C in unescapedSet)\n        if (C < uri_flags.length && uri_flags[C] & unescapedSet)\n        {\n            if (Rlen == Rsize)\n            {\n                char[] R2;\n\n                Rsize *= 2;\n                R2 = new char[Rsize];\n                R2[0 .. Rlen] = R[0 .. Rlen];\n                R = R2;\n            }\n            R[Rlen] = cast(char) C;\n            Rlen++;\n        }\n        else\n        {\n            char[6] Octet;\n            uint L;\n\n            V = C;\n\n            // Transform V into octets\n            if (V <= 0x7F)\n            {\n                Octet[0] = cast(char) V;\n                L = 1;\n            }\n            else if (V <= 0x7FF)\n            {\n                Octet[0] = cast(char)(0xC0 | (V >> 6));\n                Octet[1] = cast(char)(0x80 | (V & 0x3F));\n                L = 2;\n            }\n            else if (V <= 0xFFFF)\n            {\n                Octet[0] = cast(char)(0xE0 | (V >> 12));\n                Octet[1] = cast(char)(0x80 | ((V >> 6) & 0x3F));\n                Octet[2] = cast(char)(0x80 | (V & 0x3F));\n                L = 3;\n            }\n            else if (V <= 0x1FFFFF)\n            {\n                Octet[0] = cast(char)(0xF0 | (V >> 18));\n                Octet[1] = cast(char)(0x80 | ((V >> 12) & 0x3F));\n                Octet[2] = cast(char)(0x80 | ((V >> 6) & 0x3F));\n                Octet[3] = cast(char)(0x80 | (V & 0x3F));\n                L = 4;\n            }\n            else\n            {\n                throw new URIException(\"Undefined UTF-32 code point\");\n            }\n\n            if (Rlen + L * 3 > Rsize)\n            {\n                char[] R2;\n\n                Rsize = 2 * (Rlen + L * 3);\n                R2 = new char[Rsize];\n                R2[0 .. Rlen] = R[0 .. Rlen];\n                R = R2;\n            }\n\n            for (j = 0; j < L; j++)\n            {\n                R[Rlen] = '%';\n                R[Rlen + 1] = hex2ascii[Octet[j] >> 4];\n                R[Rlen + 2] = hex2ascii[Octet[j] & 15];\n\n                Rlen += 3;\n            }\n        }\n    }\n\n    return R[0 .. Rlen].idup;\n}\n\nprivate uint ascii2hex(dchar c) @nogc @safe pure nothrow\n{\n    return (c <= '9') ? c - '0' :\n        (c <= 'F') ? c - 'A' + 10 :\n        c - 'a' + 10;\n}\n\nprivate dstring URI_Decode(Char)(scope const(Char)[] uri, uint reservedSet)\nif (isSomeChar!Char)\n{\n    import std.ascii : isHexDigit;\n\n    uint j;\n    uint k;\n    uint V;\n    dchar C;\n\n    uint Rlen;\n    immutable len = uri.length;\n    auto s = uri;\n\n    auto Rsize = len;\n    dchar[] R = new dchar[Rsize];\n    Rlen = 0;\n\n    for (k = 0; k != len; k++)\n    {\n        char B;\n        uint start;\n\n        C = s[k];\n        if (C != '%')\n        {\n            R[Rlen] = C;\n            Rlen++;\n            continue;\n        }\n        start = k;\n        if (k + 2 >= len)\n            throw new URIException(\"Unexpected end of URI\");\n        if (!isHexDigit(s[k + 1]) || !isHexDigit(s[k + 2]))\n            throw new URIException(\"Expected two hexadecimal digits after '%'\");\n        B = cast(char)((ascii2hex(s[k + 1]) << 4) + ascii2hex(s[k + 2]));\n        k += 2;\n        if ((B & 0x80) == 0)\n        {\n            C = B;\n        }\n        else\n        {\n            uint n;\n\n            for (n = 1; ; n++)\n            {\n                if (n > 4)\n                    throw new URIException(\"UTF-32 code point size too large\");\n                if (((B << n) & 0x80) == 0)\n                {\n                    if (n == 1)\n                        throw new URIException(\"UTF-32 code point size too small\");\n                    break;\n                }\n            }\n\n            // Pick off (7 - n) significant bits of B from first byte of octet\n            V = B & ((1 << (7 - n)) - 1);   // (!!!)\n\n            if (k + (3 * (n - 1)) >= len)\n                throw new URIException(\"UTF-32 unaligned String\");\n            for (j = 1; j != n; j++)\n            {\n                k++;\n                if (s[k] != '%')\n                    throw new URIException(\"Expected: '%'\");\n                if (!isHexDigit(s[k + 1]) || !isHexDigit(s[k + 2]))\n                    throw new URIException(\"Expected two hexadecimal digits after '%'\");\n                B = cast(char)((ascii2hex(s[k + 1]) << 4) + ascii2hex(s[k + 2]));\n                if ((B & 0xC0) != 0x80)\n                    throw new URIException(\"Incorrect UTF-32 multi-byte sequence\");\n                k += 2;\n                V = (V << 6) | (B & 0x3F);\n            }\n            if (V > 0x10FFFF)\n                throw new URIException(\"Unknown UTF-32 code point\");\n            C = V;\n        }\n        if (C < uri_flags.length && uri_flags[C] & reservedSet)\n        {\n            // R ~= s[start .. k + 1];\n            immutable width = (k + 1) - start;\n            for (int ii = 0; ii < width; ii++)\n                R[Rlen + ii] = s[start + ii];\n            Rlen += width;\n        }\n        else\n        {\n            R[Rlen] = C;\n            Rlen++;\n        }\n    }\n    assert(Rlen <= Rsize);  // enforce our preallocation size guarantee\n\n    // Copy array on stack to array in memory\n    return R[0 .. Rlen].idup;\n}\n\n/*************************************\n * Decodes the URI string encodedURI into a UTF-8 string and returns it.\n * Escape sequences that resolve to reserved URI characters are not replaced.\n * Escape sequences that resolve to the '#' character are not replaced.\n */\nstring decode(Char)(scope const(Char)[] encodedURI)\nif (isSomeChar!Char)\n{\n    import std.algorithm.iteration : each;\n    import std.utf : encode;\n    auto s = URI_Decode(encodedURI, URI_Reserved | URI_Hash);\n    char[] r;\n    s.each!(c => encode(r, c));\n    return r;\n}\n\n///\n@safe unittest\n{\n    assert(\"foo%20bar\".decode == \"foo bar\");\n    assert(\"%3C%3E.@.%E2%84%A2\".decode == \"<>.@.™\");\n    assert(\"foo&/\".decode == \"foo&/\");\n    assert(\"!@#$&*(\".decode == \"!@#$&*(\");\n}\n\n/*******************************\n * Decodes the URI string encodedURI into a UTF-8 string and returns it. All\n * escape sequences are decoded.\n */\nstring decodeComponent(Char)(scope const(Char)[] encodedURIComponent)\nif (isSomeChar!Char)\n{\n    import std.algorithm.iteration : each;\n    import std.utf : encode;\n    auto s = URI_Decode(encodedURIComponent, 0);\n    char[] r;\n    s.each!(c => encode(r, c));\n    return r;\n}\n\n///\n@safe unittest\n{\n    assert(\"foo%2F%26\".decodeComponent == \"foo/&\");\n    assert(\"dl%C3%A4ng%20r%C3%B6cks\".decodeComponent == \"dläng röcks\");\n    assert(\"!%40%23%24%25%5E%26*(\".decodeComponent == \"!@#$%^&*(\");\n}\n\n/*****************************\n * Encodes the UTF-8 string uri into a URI and returns that URI. Any character\n * not a valid URI character is escaped. The '#' character is not escaped.\n */\nstring encode(Char)(scope const(Char)[] uri)\nif (isSomeChar!Char)\n{\n    import std.utf : toUTF32;\n    auto s = toUTF32(uri);\n    return URI_Encode(s, URI_Reserved | URI_Hash | URI_Alpha | URI_Digit | URI_Mark);\n}\n\n///\n@safe unittest\n{\n    assert(\"foo bar\".encode == \"foo%20bar\");\n    assert(\"<>.@.™\".encode == \"%3C%3E.@.%E2%84%A2\");\n    assert(\"foo/#?a=1&b=2\".encode == \"foo/#?a=1&b=2\");\n    assert(\"dlang+rocks!\".encode == \"dlang+rocks!\");\n    assert(\"!@#$%^&*(\".encode == \"!@#$%25%5E&*(\");\n}\n\n/********************************\n * Encodes the UTF-8 string uriComponent into a URI and returns that URI.\n * Any character not a letter, digit, or one of -_.!~*'() is escaped.\n */\nstring encodeComponent(Char)(scope const(Char)[] uriComponent)\nif (isSomeChar!Char)\n{\n    import std.utf : toUTF32;\n    auto s = toUTF32(uriComponent);\n    return URI_Encode(s, URI_Alpha | URI_Digit | URI_Mark);\n}\n\n///\n@safe unittest\n{\n    assert(\"!@#$%^&*(\".encodeComponent == \"!%40%23%24%25%5E%26*(\");\n    assert(\"<>.@.™\".encodeComponent == \"%3C%3E.%40.%E2%84%A2\");\n    assert(\"foo/&\".encodeComponent == \"foo%2F%26\");\n    assert(\"dläng röcks\".encodeComponent == \"dl%C3%A4ng%20r%C3%B6cks\");\n    assert(\"dlang+rocks!\".encodeComponent == \"dlang%2Brocks!\");\n}\n\n/* Encode associative array using www-form-urlencoding\n *\n * Params:\n *      values = an associative array containing the values to be encoded.\n *\n * Returns:\n *      A string encoded using www-form-urlencoding.\n */\npackage string urlEncode(scope string[string] values) @safe pure\n{\n    if (values.length == 0)\n        return \"\";\n\n    import std.array : Appender;\n    import std.format : formattedWrite;\n\n    Appender!string enc;\n    enc.reserve(values.length * 128);\n\n    bool first = true;\n    foreach (k, v; values)\n    {\n        if (!first)\n            enc.put('&');\n        formattedWrite(enc, \"%s=%s\", encodeComponent(k), encodeComponent(v));\n        first = false;\n    }\n    return enc.data;\n}\n\n@safe pure unittest\n{\n    // @system because urlEncode -> encodeComponent -> URI_Encode\n    // URI_Encode uses alloca and pointer slicing\n    string[string] a;\n    assert(urlEncode(a) == \"\");\n    assert(urlEncode([\"name1\" : \"value1\"]) == \"name1=value1\");\n    auto enc = urlEncode([\"name1\" : \"value1\", \"name2\" : \"value2\"]);\n    assert(enc == \"name1=value1&name2=value2\" || enc == \"name2=value2&name1=value1\");\n}\n\n/***************************\n * Does string s[] start with a URL?\n * Returns:\n *  -1   it does not\n *  len  it does, and s[0 .. len] is the slice of s[] that is that URL\n */\n\nptrdiff_t uriLength(Char)(scope const(Char)[] s)\nif (isSomeChar!Char)\n{\n    /* Must start with one of:\n     *  http://\n     *  https://\n     *  www.\n     */\n    import std.ascii : isAlphaNum;\n    import std.uni : icmp;\n\n    ptrdiff_t i;\n\n    if (s.length <= 4)\n        return -1;\n\n    if (s.length > 7 && icmp(s[0 .. 7], \"http://\") == 0)\n    {\n        i = 7;\n    }\n    else\n    {\n        if (s.length > 8 && icmp(s[0 .. 8], \"https://\") == 0)\n            i = 8;\n        else\n            return -1;\n    }\n\n    ptrdiff_t lastdot;\n    for (; i < s.length; i++)\n    {\n        auto c = s[i];\n        if (isAlphaNum(c))\n            continue;\n        if (c == '-' || c == '_' || c == '?' ||\n                c == '=' || c == '%' || c == '&' ||\n                c == '/' || c == '+' || c == '#' ||\n                c == '~' || c == '$')\n            continue;\n        if (c == '.')\n        {\n            lastdot = i;\n            continue;\n        }\n        break;\n    }\n    if (!lastdot)\n        return -1;\n\n    return i;\n}\n\n///\n@safe pure unittest\n{\n    string s1 = \"http://www.digitalmars.com/~fred/fredsRX.html#foo end!\";\n    assert(uriLength(s1) == 49);\n    string s2 = \"no uri here\";\n    assert(uriLength(s2) == -1);\n    assert(uriLength(\"issue 14924\") < 0);\n}\n\n\n/***************************\n * Does string s[] start with an email address?\n * Returns:\n *  -1    it does not\n *  len   it does, and s[0 .. i] is the slice of s[] that is that email address\n * References:\n *  RFC2822\n */\nptrdiff_t emailLength(Char)(scope const(Char)[] s)\nif (isSomeChar!Char)\n{\n    import std.ascii : isAlpha, isAlphaNum;\n\n    ptrdiff_t i;\n\n    if (!isAlpha(s[0]))\n        return -1;\n\n    for (i = 1; 1; i++)\n    {\n        if (i == s.length)\n            return -1;\n        auto c = s[i];\n        if (isAlphaNum(c))\n            continue;\n        if (c == '-' || c == '_' || c == '.')\n            continue;\n        if (c != '@')\n            return -1;\n        i++;\n        break;\n    }\n\n    /* Now do the part past the '@'\n     */\n    ptrdiff_t lastdot;\n    for (; i < s.length; i++)\n    {\n        auto c = s[i];\n        if (isAlphaNum(c))\n            continue;\n        if (c == '-' || c == '_')\n            continue;\n        if (c == '.')\n        {\n            lastdot = i;\n            continue;\n        }\n        break;\n    }\n    if (!lastdot || (i - lastdot != 3 && i - lastdot != 4))\n        return -1;\n\n    return i;\n}\n\n///\n@safe pure unittest\n{\n    string s1 = \"my.e-mail@www.example-domain.com with garbage added\";\n    assert(emailLength(s1) == 32);\n    string s2 = \"no email address here\";\n    assert(emailLength(s2) == -1);\n    assert(emailLength(\"issue 14924\") < 0);\n}\n\n@safe pure unittest\n{\n    //@system because of encode -> URI_Encode\n    debug(uri) writeln(\"uri.encodeURI.unittest\");\n\n    string source = \"http://www.digitalmars.com/~fred/fred's RX.html#foo\";\n    string target = \"http://www.digitalmars.com/~fred/fred's%20RX.html#foo\";\n\n    auto result = encode(source);\n    debug(uri) writefln(\"result = '%s'\", result);\n    assert(result == target);\n    result = decode(target);\n    debug(uri) writefln(\"result = '%s'\", result);\n    assert(result == source);\n\n    result = encode(decode(\"%E3%81%82%E3%81%82\"));\n    assert(result == \"%E3%81%82%E3%81%82\");\n\n    result = encodeComponent(\"c++\");\n    assert(result == \"c%2B%2B\");\n\n    auto str = new char[10_000_000];\n    str[] = 'A';\n    result = encodeComponent(str);\n    foreach (char c; result)\n        assert(c == 'A');\n\n    result = decode(\"%41%42%43\");\n    debug(uri) writeln(result);\n\n    import std.meta : AliasSeq;\n    static foreach (StringType; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))\n    {{\n        import std.conv : to;\n        StringType decoded1 = source.to!StringType;\n        string encoded1 = encode(decoded1);\n        assert(decoded1 == source.to!StringType); // check that `decoded1` wasn't changed\n        assert(encoded1 == target);\n        assert(decoded1 == decode(encoded1).to!StringType);\n\n        StringType encoded2 = target.to!StringType;\n        string decoded2 = decode(encoded2);\n        assert(encoded2 == target.to!StringType); // check that `encoded2` wasn't changed\n        assert(decoded2 == source);\n        assert(encoded2 == encode(decoded2).to!StringType);\n    }}\n}\n"
  },
  {
    "path": "libphobos/src/std/utf.d",
    "content": "// Written in the D programming language.\n\n/++\n    Encode and decode UTF-8, UTF-16 and UTF-32 strings.\n\n    UTF character support is restricted to\n    $(D '\\u0000' &lt;= character &lt;= '\\U0010FFFF').\n\n$(SCRIPT inhibitQuickIndex = 1;)\n$(BOOKTABLE,\n$(TR $(TH Category) $(TH Functions))\n$(TR $(TD Decode) $(TD\n    $(LREF decode)\n    $(LREF decodeFront)\n))\n$(TR $(TD Lazy decode) $(TD\n    $(LREF byCodeUnit)\n    $(LREF byChar)\n    $(LREF byWchar)\n    $(LREF byDchar)\n    $(LREF byUTF)\n))\n$(TR $(TD Encode) $(TD\n    $(LREF encode)\n    $(LREF toUTF8)\n    $(LREF toUTF16)\n    $(LREF toUTF32)\n    $(LREF toUTFz)\n    $(LREF toUTF16z)\n))\n$(TR $(TD Length) $(TD\n    $(LREF codeLength)\n    $(LREF count)\n    $(LREF stride)\n    $(LREF strideBack)\n))\n$(TR $(TD Index) $(TD\n    $(LREF toUCSindex)\n    $(LREF toUTFindex)\n))\n$(TR $(TD Validation) $(TD\n    $(LREF isValidDchar)\n    $(LREF validate)\n))\n$(TR $(TD Miscellaneous) $(TD\n    $(LREF replacementDchar)\n    $(LREF UseReplacementDchar)\n    $(LREF UTFException)\n))\n)\n    See_Also:\n        $(LINK2 http://en.wikipedia.org/wiki/Unicode, Wikipedia)<br>\n        $(LINK http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8)<br>\n        $(LINK http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335)\n    Copyright: Copyright The D Language Foundation 2000 - 2012.\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n    Authors:   $(HTTP digitalmars.com, Walter Bright) and\n               $(HTTP jmdavisprog.com, Jonathan M Davis)\n    Source:    $(PHOBOSSRC std/utf.d)\n   +/\nmodule std.utf;\n\nimport std.exception;  // basicExceptionCtors\nimport std.meta;       // AliasSeq\nimport std.range.primitives;\nimport std.traits;     // isSomeChar, isSomeString\nimport std.typecons;   // Flag, Yes, No\n\n\n/++\n    Exception thrown on errors in std.utf functions.\n  +/\nclass UTFException : Exception\n{\n    import core.internal.string : unsignedToTempString, UnsignedStringBuf;\n\n    uint[4] sequence;\n    size_t  len;\n\n    @safe pure nothrow @nogc\n    UTFException setSequence(scope uint[] data...)\n    {\n        assert(data.length <= 4);\n\n        len = data.length < 4 ? data.length : 4;\n        sequence[0 .. len] = data[0 .. len];\n\n        return this;\n    }\n\n    // FIXME: Use std.exception.basicExceptionCtors here once bug #11500 is fixed\n\n    /**\n    Standard exception constructors.\n     */\n    this(string msg, string file = __FILE__, size_t line = __LINE__,\n         Throwable next = null) @nogc @safe pure nothrow\n    {\n        super(msg, file, line, next);\n    }\n    /// ditto\n    this(string msg, size_t index, string file = __FILE__,\n         size_t line = __LINE__, Throwable next = null) @safe pure nothrow\n    {\n        UnsignedStringBuf buf = void;\n        msg ~= \" (at index \" ~ unsignedToTempString(index, buf, 10) ~ \")\";\n        super(msg, file, line, next);\n    }\n\n    /**\n    Returns:\n        A `string` detailing the invalid UTF sequence.\n     */\n    override string toString() const\n    {\n        if (len == 0)\n        {\n            /* Exception.toString() is not marked as const, although\n             * it is const-compatible.\n             */\n            //return super.toString();\n            auto e = () @trusted { return cast(Exception) super; } ();\n            return e.toString();\n        }\n\n        string result = \"Invalid UTF sequence:\";\n\n        foreach (i; sequence[0 .. len])\n        {\n            UnsignedStringBuf buf = void;\n            result ~= ' ';\n            auto h = unsignedToTempString(i, buf, 16);\n            if (h.length == 1)\n                result ~= '0';\n            result ~= h;\n            result ~= 'x';\n        }\n\n        if (super.msg.length > 0)\n        {\n            result ~= \" - \";\n            result ~= super.msg;\n        }\n\n        return result;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n\n    char[4] buf;\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));\n}\n\n/*\n   Provide array of invalidly encoded UTF strings. Useful for testing.\n\n   Params:\n        Char = char, wchar, or dchar\n\n   Returns:\n        an array of invalidly encoded UTF strings\n */\n\npackage auto invalidUTFstrings(Char)() @safe pure @nogc nothrow\nif (isSomeChar!Char)\n{\n    static if (is(Char == char))\n    {\n        enum x = 0xDC00;         // invalid surrogate value\n        enum y = 0x110000;       // out of range\n\n        static immutable string[8] result =\n        [\n            \"\\x80\",             // not a start byte\n            \"\\xC0\",             // truncated\n            \"\\xC0\\xC0\",         // invalid continuation\n            \"\\xF0\\x82\\x82\\xAC\", // overlong\n            [\n              0xE0 | (x >> 12),\n              0x80 | ((x >> 6) & 0x3F),\n              0x80 | (x & 0x3F)\n            ],\n            [\n              cast(char)(0xF0 | (y >> 18)),\n              cast(char)(0x80 | ((y >> 12) & 0x3F)),\n              cast(char)(0x80 | ((y >> 6) & 0x3F)),\n              cast(char)(0x80 | (y & 0x3F))\n            ],\n            [\n              cast(char)(0xF8 | 3),     // 5 byte encoding\n              cast(char)(0x80 | 3),\n              cast(char)(0x80 | 3),\n              cast(char)(0x80 | 3),\n              cast(char)(0x80 | 3),\n            ],\n            [\n              cast(char)(0xFC | 3),     // 6 byte encoding\n              cast(char)(0x80 | 3),\n              cast(char)(0x80 | 3),\n              cast(char)(0x80 | 3),\n              cast(char)(0x80 | 3),\n              cast(char)(0x80 | 3),\n            ],\n        ];\n\n        return result[];\n    }\n    else static if (is(Char == wchar))\n    {\n        static immutable wstring[5] result =\n        [\n            [\n              cast(wchar) 0xDC00,\n            ],\n            [\n              cast(wchar) 0xDFFF,\n            ],\n            [\n              cast(wchar) 0xDBFF,\n              cast(wchar) 0xDBFF,\n            ],\n            [\n              cast(wchar) 0xDBFF,\n              cast(wchar) 0xE000,\n            ],\n            [\n              cast(wchar) 0xD800,\n            ],\n        ];\n\n        return result[];\n    }\n    else static if (is(Char == dchar))\n    {\n        static immutable dstring[3] result =\n        [\n            [ cast(dchar) 0x110000 ],\n            [ cast(dchar) 0x00D800 ],\n            [ cast(dchar) 0x00DFFF ],\n        ];\n\n        return result;\n    }\n    else\n        static assert(0);\n}\n\n/++\n    Check whether the given Unicode code point is valid.\n\n    Params:\n        c = code point to check\n\n    Returns:\n        `true` if and only if `c` is a valid Unicode code point\n\n    Note:\n    `'\\uFFFE'` and `'\\uFFFF'` are considered valid by `isValidDchar`,\n    as they are permitted for internal use by an application, but they are\n    not allowed for interchange by the Unicode standard.\n  +/\nbool isValidDchar(dchar c) pure nothrow @safe @nogc\n{\n    return c < 0xD800 || (c > 0xDFFF && c <= 0x10FFFF);\n}\n\n///\n@safe @nogc pure nothrow unittest\n{\n    assert( isValidDchar(cast(dchar) 0x41));\n    assert( isValidDchar(cast(dchar) 0x00));\n    assert(!isValidDchar(cast(dchar) 0xD800));\n    assert(!isValidDchar(cast(dchar) 0x11FFFF));\n}\n\npure nothrow @safe @nogc unittest\n{\n    import std.exception;\n\n    assertCTFEable!(\n    {\n    assert( isValidDchar(cast(dchar)'a') == true);\n    assert( isValidDchar(cast(dchar) 0x1FFFFF) == false);\n\n    assert(!isValidDchar(cast(dchar) 0x00D800));\n    assert(!isValidDchar(cast(dchar) 0x00DBFF));\n    assert(!isValidDchar(cast(dchar) 0x00DC00));\n    assert(!isValidDchar(cast(dchar) 0x00DFFF));\n    assert( isValidDchar(cast(dchar) 0x00FFFE));\n    assert( isValidDchar(cast(dchar) 0x00FFFF));\n    assert( isValidDchar(cast(dchar) 0x01FFFF));\n    assert( isValidDchar(cast(dchar) 0x10FFFF));\n    assert(!isValidDchar(cast(dchar) 0x110000));\n    });\n}\n\n\n/++\n    Calculate the length of the UTF sequence starting at `index`\n    in `str`.\n\n    Params:\n        str = $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n        of UTF code units. Must be random access if `index` is passed\n        index = starting index of UTF sequence (default: `0`)\n\n    Returns:\n        The number of code units in the UTF sequence. For UTF-8, this is a\n        value between 1 and 4 (as per $(HTTP tools.ietf.org/html/rfc3629#section-3, RFC 3629$(COMMA) section 3)).\n        For UTF-16, it is either 1 or 2. For UTF-32, it is always 1.\n\n    Throws:\n        May throw a `UTFException` if `str[index]` is not the start of a\n        valid UTF sequence.\n\n    Note:\n        `stride` will only analyze the first `str[index]` element. It\n        will not fully verify the validity of the UTF sequence, nor even verify\n        the presence of the sequence: it will not actually guarantee that\n        $(D index + stride(str, index) <= str.length).\n  +/\nuint stride(S)(auto ref S str, size_t index)\nif (is(S : const char[]) ||\n    (isRandomAccessRange!S && is(Unqual!(ElementType!S) == char)))\n{\n    static if (is(typeof(str.length) : ulong))\n        assert(index < str.length, \"Past the end of the UTF-8 sequence\");\n    immutable c = str[index];\n\n    if (c < 0x80)\n        return 1;\n    else\n        return strideImpl(c, index);\n}\n\n/// Ditto\nuint stride(S)(auto ref S str)\nif (is(S : const char[]) ||\n    (isInputRange!S && is(Unqual!(ElementType!S) == char)))\n{\n    static if (is(S : const char[]))\n        immutable c = str[0];\n    else\n        immutable c = str.front;\n\n    if (c < 0x80)\n        return 1;\n    else\n        return strideImpl(c, 0);\n}\n\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.conv : to;\n    import std.exception;\n    import std.string : format;\n    static void test(string s, dchar c, size_t i = 0, size_t line = __LINE__)\n    {\n        enforce(stride(s, i) == codeLength!char(c),\n                new AssertError(format(\"Unit test failure string: %s\", s), __FILE__, line));\n\n        enforce(stride(RandomCU!char(s), i) == codeLength!char(c),\n                new AssertError(format(\"Unit test failure range: %s\", s), __FILE__, line));\n\n        auto refRandom = new RefRandomCU!char(s);\n        immutable randLen = refRandom.length;\n        enforce(stride(refRandom, i) == codeLength!char(c),\n                new AssertError(format(\"Unit test failure rand ref range: %s\", s), __FILE__, line));\n        enforce(refRandom.length == randLen,\n                new AssertError(format(\"Unit test failure rand ref range length: %s\", s), __FILE__, line));\n\n        if (i == 0)\n        {\n            enforce(stride(s) == codeLength!char(c),\n                    new AssertError(format(\"Unit test failure string 0: %s\", s), __FILE__, line));\n\n            enforce(stride(InputCU!char(s)) == codeLength!char(c),\n                    new AssertError(format(\"Unit test failure range 0: %s\", s), __FILE__, line));\n\n            auto refBidir = new RefBidirCU!char(s);\n            immutable bidirLen = refBidir.length;\n            enforce(stride(refBidir) == codeLength!char(c),\n                    new AssertError(format(\"Unit test failure bidir ref range code length: %s\", s), __FILE__, line));\n            enforce(refBidir.length == bidirLen,\n                    new AssertError(format(\"Unit test failure bidir ref range length: %s\", s), __FILE__, line));\n        }\n    }\n\n    assertCTFEable!(\n    {\n    test(\"a\", 'a');\n    test(\" \", ' ');\n    test(\"\\u2029\", '\\u2029'); //paraSep\n    test(\"\\u0100\", '\\u0100');\n    test(\"\\u0430\", '\\u0430');\n    test(\"\\U00010143\", '\\U00010143');\n    test(\"abcdefcdef\", 'a');\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'h', 0);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'e', 1);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'l', 2);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'l', 3);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'o', 4);\n    test(\"hello\\U00010143\\u0100\\U00010143\", '\\U00010143', 5);\n    test(\"hello\\U00010143\\u0100\\U00010143\", '\\u0100', 9);\n    test(\"hello\\U00010143\\u0100\\U00010143\", '\\U00010143', 11);\n\n    foreach (S; AliasSeq!(char[], const char[], string))\n    {\n        enum str = to!S(\"hello world\");\n        static assert(isSafe!({ stride(str, 0); }));\n        static assert(isSafe!({ stride(str);    }));\n        static assert((functionAttributes!({ stride(str, 0); }) & FunctionAttribute.pure_) != 0);\n        static assert((functionAttributes!({ stride(str);    }) & FunctionAttribute.pure_) != 0);\n    }\n    });\n}\n\n@safe unittest // invalid start bytes\n{\n    import std.exception : assertThrown;\n    immutable char[] invalidStartBytes = [\n        0b1111_1000, // indicating a sequence length of 5\n        0b1111_1100, // 6\n        0b1111_1110, // 7\n        0b1111_1111, // 8\n        0b1000_0000, // continuation byte\n    ];\n    foreach (c; invalidStartBytes)\n        assertThrown!UTFException(stride([c]));\n}\n\n/// Ditto\nuint stride(S)(auto ref S str, size_t index)\nif (is(S : const wchar[]) ||\n    (isRandomAccessRange!S && is(Unqual!(ElementType!S) == wchar)))\n{\n    static if (is(typeof(str.length) : ulong))\n        assert(index < str.length, \"Past the end of the UTF-16 sequence\");\n    immutable uint u = str[index];\n    return 1 + (u >= 0xD800 && u <= 0xDBFF);\n}\n\n/// Ditto\nuint stride(S)(auto ref S str) @safe pure\nif (is(S : const wchar[]))\n{\n    return stride(str, 0);\n}\n\n/// Ditto\nuint stride(S)(auto ref S str)\nif (isInputRange!S && is(Unqual!(ElementType!S) == wchar))\n{\n    assert(!str.empty, \"UTF-16 sequence is empty\");\n    immutable uint u = str.front;\n    return 1 + (u >= 0xD800 && u <= 0xDBFF);\n}\n\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.conv : to;\n    import std.exception;\n    import std.string : format;\n    static void test(wstring s, dchar c, size_t i = 0, size_t line = __LINE__)\n    {\n        enforce(stride(s, i) == codeLength!wchar(c),\n                new AssertError(format(\"Unit test failure string: %s\", s), __FILE__, line));\n\n        enforce(stride(RandomCU!wchar(s), i) == codeLength!wchar(c),\n                new AssertError(format(\"Unit test failure range: %s\", s), __FILE__, line));\n\n        auto refRandom = new RefRandomCU!wchar(s);\n        immutable randLen = refRandom.length;\n        enforce(stride(refRandom, i) == codeLength!wchar(c),\n                new AssertError(format(\"Unit test failure rand ref range: %s\", s), __FILE__, line));\n        enforce(refRandom.length == randLen,\n                new AssertError(format(\"Unit test failure rand ref range length: %s\", s), __FILE__, line));\n\n        if (i == 0)\n        {\n            enforce(stride(s) == codeLength!wchar(c),\n                    new AssertError(format(\"Unit test failure string 0: %s\", s), __FILE__, line));\n\n            enforce(stride(InputCU!wchar(s)) == codeLength!wchar(c),\n                    new AssertError(format(\"Unit test failure range 0: %s\", s), __FILE__, line));\n\n            auto refBidir = new RefBidirCU!wchar(s);\n            immutable bidirLen = refBidir.length;\n            enforce(stride(refBidir) == codeLength!wchar(c),\n                    new AssertError(format(\"Unit test failure bidir ref range code length: %s\", s), __FILE__, line));\n            enforce(refBidir.length == bidirLen,\n                    new AssertError(format(\"Unit test failure bidir ref range length: %s\", s), __FILE__, line));\n        }\n    }\n\n    assertCTFEable!(\n    {\n    test(\"a\", 'a');\n    test(\" \", ' ');\n    test(\"\\u2029\", '\\u2029'); //paraSep\n    test(\"\\u0100\", '\\u0100');\n    test(\"\\u0430\", '\\u0430');\n    test(\"\\U00010143\", '\\U00010143');\n    test(\"abcdefcdef\", 'a');\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'h', 0);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'e', 1);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'l', 2);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'l', 3);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'o', 4);\n    test(\"hello\\U00010143\\u0100\\U00010143\", '\\U00010143', 5);\n    test(\"hello\\U00010143\\u0100\\U00010143\", '\\u0100', 7);\n    test(\"hello\\U00010143\\u0100\\U00010143\", '\\U00010143', 8);\n\n    foreach (S; AliasSeq!(wchar[], const wchar[], wstring))\n    {\n        enum str = to!S(\"hello world\");\n        static assert(isSafe!(() => stride(str, 0)));\n        static assert(isSafe!(() => stride(str)   ));\n        static assert((functionAttributes!(() => stride(str, 0)) & FunctionAttribute.pure_) != 0);\n        static assert((functionAttributes!(() => stride(str)   ) & FunctionAttribute.pure_) != 0);\n    }\n    });\n}\n\n/// Ditto\nuint stride(S)(auto ref S str, size_t index = 0)\nif (is(S : const dchar[]) ||\n    (isInputRange!S && is(Unqual!(ElementEncodingType!S) == dchar)))\n{\n    static if (is(typeof(str.length) : ulong))\n        assert(index < str.length, \"Past the end of the UTF-32 sequence\");\n    else\n        assert(!str.empty, \"UTF-32 sequence is empty.\");\n    return 1;\n}\n\n///\n@safe unittest\n{\n    assert(\"a\".stride == 1);\n    assert(\"λ\".stride == 2);\n    assert(\"aλ\".stride == 1);\n    assert(\"aλ\".stride(1) == 2);\n    assert(\"𐐷\".stride == 4);\n}\n\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.conv : to;\n    import std.exception;\n    import std.string : format;\n    static void test(dstring s, dchar c, size_t i = 0, size_t line = __LINE__)\n    {\n        enforce(stride(s, i) == codeLength!dchar(c),\n                new AssertError(format(\"Unit test failure string: %s\", s), __FILE__, line));\n\n        enforce(stride(RandomCU!dchar(s), i) == codeLength!dchar(c),\n                new AssertError(format(\"Unit test failure range: %s\", s), __FILE__, line));\n\n        auto refRandom = new RefRandomCU!dchar(s);\n        immutable randLen = refRandom.length;\n        enforce(stride(refRandom, i) == codeLength!dchar(c),\n                new AssertError(format(\"Unit test failure rand ref range: %s\", s), __FILE__, line));\n        enforce(refRandom.length == randLen,\n                new AssertError(format(\"Unit test failure rand ref range length: %s\", s), __FILE__, line));\n\n        if (i == 0)\n        {\n            enforce(stride(s) == codeLength!dchar(c),\n                    new AssertError(format(\"Unit test failure string 0: %s\", s), __FILE__, line));\n\n            enforce(stride(InputCU!dchar(s)) == codeLength!dchar(c),\n                    new AssertError(format(\"Unit test failure range 0: %s\", s), __FILE__, line));\n\n            auto refBidir = new RefBidirCU!dchar(s);\n            immutable bidirLen = refBidir.length;\n            enforce(stride(refBidir) == codeLength!dchar(c),\n                    new AssertError(format(\"Unit test failure bidir ref range code length: %s\", s), __FILE__, line));\n            enforce(refBidir.length == bidirLen,\n                    new AssertError(format(\"Unit test failure bidir ref range length: %s\", s), __FILE__, line));\n        }\n    }\n\n    assertCTFEable!(\n    {\n    test(\"a\", 'a');\n    test(\" \", ' ');\n    test(\"\\u2029\", '\\u2029'); //paraSep\n    test(\"\\u0100\", '\\u0100');\n    test(\"\\u0430\", '\\u0430');\n    test(\"\\U00010143\", '\\U00010143');\n    test(\"abcdefcdef\", 'a');\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'h', 0);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'e', 1);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'l', 2);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'l', 3);\n    test(\"hello\\U00010143\\u0100\\U00010143\", 'o', 4);\n    test(\"hello\\U00010143\\u0100\\U00010143\", '\\U00010143', 5);\n    test(\"hello\\U00010143\\u0100\\U00010143\", '\\u0100', 6);\n    test(\"hello\\U00010143\\u0100\\U00010143\", '\\U00010143', 7);\n\n    foreach (S; AliasSeq!(dchar[], const dchar[], dstring))\n    {\n        enum str = to!S(\"hello world\");\n        static assert(isSafe!(() => stride(str, 0)));\n        static assert(isSafe!(() => stride(str)   ));\n        static assert((functionAttributes!(() => stride(str, 0)) & FunctionAttribute.pure_) != 0);\n        static assert((functionAttributes!(() => stride(str)   ) & FunctionAttribute.pure_) != 0);\n    }\n    });\n}\n\nprivate uint strideImpl(char c, size_t index) @trusted pure\nin { assert(c & 0x80); }\ndo\n{\n    import core.bitop : bsr;\n    immutable msbs = 7 - bsr((~uint(c)) & 0xFF);\n    if (c == 0xFF || msbs < 2 || msbs > 4)\n        throw new UTFException(\"Invalid UTF-8 sequence\", index);\n    return msbs;\n}\n\n/++\n    Calculate the length of the UTF sequence ending one code unit before\n    `index` in `str`.\n\n    Params:\n        str = bidirectional range of UTF code units. Must be random access if\n        `index` is passed\n        index = index one past end of UTF sequence (default: `str.length`)\n\n    Returns:\n        The number of code units in the UTF sequence. For UTF-8, this is a\n        value between 1 and 4 (as per $(HTTP tools.ietf.org/html/rfc3629#section-3, RFC 3629$(COMMA) section 3)).\n        For UTF-16, it is either 1 or 2. For UTF-32, it is always 1.\n\n    Throws:\n        May throw a `UTFException` if `str[index]` is not one past the\n        end of a valid UTF sequence.\n\n    Note:\n        `strideBack` will only analyze the element at $(D str[index - 1])\n        element. It will not fully verify the validity of the UTF sequence, nor\n        even verify the presence of the sequence: it will not actually\n        guarantee that $(D strideBack(str, index) <= index).\n  +/\nuint strideBack(S)(auto ref S str, size_t index)\nif (is(S : const char[]) ||\n    (isRandomAccessRange!S && is(Unqual!(ElementType!S) == char)))\n{\n    static if (is(typeof(str.length) : ulong))\n        assert(index <= str.length, \"Past the end of the UTF-8 sequence\");\n    assert(index > 0, \"Not the end of the UTF-8 sequence\");\n\n    if ((str[index-1] & 0b1100_0000) != 0b1000_0000)\n        return 1;\n\n    if (index >= 4) //single verification for most common case\n    {\n        static foreach (i; 2 .. 5)\n        {\n            if ((str[index-i] & 0b1100_0000) != 0b1000_0000)\n                return i;\n        }\n    }\n    else\n    {\n        static foreach (i; 2 .. 4)\n        {\n            if (index >= i && (str[index-i] & 0b1100_0000) != 0b1000_0000)\n                return i;\n        }\n    }\n    throw new UTFException(\"Not the end of the UTF sequence\", index);\n}\n\n/// Ditto\nuint strideBack(S)(auto ref S str)\nif (is(S : const char[]) ||\n    (isRandomAccessRange!S && hasLength!S && is(Unqual!(ElementType!S) == char)))\n{\n    return strideBack(str, str.length);\n}\n\n/// Ditto\nuint strideBack(S)(auto ref S str)\nif (isBidirectionalRange!S && is(Unqual!(ElementType!S) == char) && !isRandomAccessRange!S)\n{\n    assert(!str.empty, \"Past the end of the UTF-8 sequence\");\n    auto temp = str.save;\n    foreach (i; AliasSeq!(1, 2, 3, 4))\n    {\n        if ((temp.back & 0b1100_0000) != 0b1000_0000)\n            return i;\n        temp.popBack();\n        if (temp.empty)\n            break;\n    }\n    throw new UTFException(\"The last code unit is not the end of the UTF-8 sequence\");\n}\n\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.conv : to;\n    import std.exception;\n    import std.string : format;\n    static void test(string s, dchar c, size_t i = size_t.max, size_t line = __LINE__)\n    {\n        enforce(strideBack(s, i == size_t.max ? s.length : i) == codeLength!char(c),\n                new AssertError(format(\"Unit test failure string: %s\", s), __FILE__, line));\n\n        enforce(strideBack(RandomCU!char(s), i == size_t.max ? s.length : i) == codeLength!char(c),\n                new AssertError(format(\"Unit test failure range: %s\", s), __FILE__, line));\n\n        auto refRandom = new RefRandomCU!char(s);\n        immutable randLen = refRandom.length;\n        enforce(strideBack(refRandom, i == size_t.max ? s.length : i) == codeLength!char(c),\n                new AssertError(format(\"Unit test failure rand ref range: %s\", s), __FILE__, line));\n        enforce(refRandom.length == randLen,\n                new AssertError(format(\"Unit test failure rand ref range length: %s\", s), __FILE__, line));\n\n        if (i == size_t.max)\n        {\n            enforce(strideBack(s) == codeLength!char(c),\n                    new AssertError(format(\"Unit test failure string code length: %s\", s), __FILE__, line));\n\n            enforce(strideBack(BidirCU!char(s)) == codeLength!char(c),\n                    new AssertError(format(\"Unit test failure range code length: %s\", s), __FILE__, line));\n\n            auto refBidir = new RefBidirCU!char(s);\n            immutable bidirLen = refBidir.length;\n            enforce(strideBack(refBidir) == codeLength!char(c),\n                    new AssertError(format(\"Unit test failure bidir ref range code length: %s\", s), __FILE__, line));\n            enforce(refBidir.length == bidirLen,\n                    new AssertError(format(\"Unit test failure bidir ref range length: %s\", s), __FILE__, line));\n        }\n    }\n\n    assertCTFEable!(\n    {\n    test(\"a\", 'a');\n    test(\" \", ' ');\n    test(\"\\u2029\", '\\u2029'); //paraSep\n    test(\"\\u0100\", '\\u0100');\n    test(\"\\u0430\", '\\u0430');\n    test(\"\\U00010143\", '\\U00010143');\n    test(\"abcdefcdef\", 'f');\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'o', 15);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'l', 14);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'l', 13);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'e', 12);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'h', 11);\n    test(\"\\U00010143\\u0100\\U00010143hello\", '\\U00010143', 10);\n    test(\"\\U00010143\\u0100\\U00010143hello\", '\\u0100', 6);\n    test(\"\\U00010143\\u0100\\U00010143hello\", '\\U00010143', 4);\n\n    foreach (S; AliasSeq!(char[], const char[], string))\n    {\n        enum str = to!S(\"hello world\");\n        static assert(isSafe!({ strideBack(str, 0); }));\n        static assert(isSafe!({ strideBack(str);    }));\n        static assert((functionAttributes!({ strideBack(str, 0); }) & FunctionAttribute.pure_) != 0);\n        static assert((functionAttributes!({ strideBack(str);    }) & FunctionAttribute.pure_) != 0);\n    }\n    });\n}\n\n//UTF-16 is self synchronizing: The length of strideBack can be found from\n//the value of a single wchar\n/// Ditto\nuint strideBack(S)(auto ref S str, size_t index)\nif (is(S : const wchar[]) ||\n    (isRandomAccessRange!S && is(Unqual!(ElementType!S) == wchar)))\n{\n    static if (is(typeof(str.length) : ulong))\n        assert(index <= str.length, \"Past the end of the UTF-16 sequence\");\n    assert(index > 0, \"Not the end of a UTF-16 sequence\");\n\n    immutable c2 = str[index-1];\n    return 1 + (0xDC00 <= c2 && c2 < 0xE000);\n}\n\n/// Ditto\nuint strideBack(S)(auto ref S str)\nif (is(S : const wchar[]) ||\n    (isBidirectionalRange!S && is(Unqual!(ElementType!S) == wchar)))\n{\n    assert(!str.empty, \"UTF-16 sequence is empty\");\n\n    static if (is(S : const(wchar)[]))\n        immutable c2 = str[$ - 1];\n    else\n        immutable c2 = str.back;\n\n    return 1 + (0xDC00 <= c2 && c2 <= 0xE000);\n}\n\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.conv : to;\n    import std.exception;\n    import std.string : format;\n    static void test(wstring s, dchar c, size_t i = size_t.max, size_t line = __LINE__)\n    {\n        enforce(strideBack(s, i == size_t.max ? s.length : i) == codeLength!wchar(c),\n                new AssertError(format(\"Unit test failure string: %s\", s), __FILE__, line));\n\n        enforce(strideBack(RandomCU!wchar(s), i == size_t.max ? s.length : i) == codeLength!wchar(c),\n                new AssertError(format(\"Unit test failure range: %s\", s), __FILE__, line));\n\n        auto refRandom = new RefRandomCU!wchar(s);\n        immutable randLen = refRandom.length;\n        enforce(strideBack(refRandom, i == size_t.max ? s.length : i) == codeLength!wchar(c),\n                new AssertError(format(\"Unit test failure rand ref range: %s\", s), __FILE__, line));\n        enforce(refRandom.length == randLen,\n                new AssertError(format(\"Unit test failure rand ref range length: %s\", s), __FILE__, line));\n\n        if (i == size_t.max)\n        {\n            enforce(strideBack(s) == codeLength!wchar(c),\n                    new AssertError(format(\"Unit test failure string code length: %s\", s), __FILE__, line));\n\n            enforce(strideBack(BidirCU!wchar(s)) == codeLength!wchar(c),\n                    new AssertError(format(\"Unit test failure range code length: %s\", s), __FILE__, line));\n\n            auto refBidir = new RefBidirCU!wchar(s);\n            immutable bidirLen = refBidir.length;\n            enforce(strideBack(refBidir) == codeLength!wchar(c),\n                    new AssertError(format(\"Unit test failure bidir ref range code length: %s\", s), __FILE__, line));\n            enforce(refBidir.length == bidirLen,\n                    new AssertError(format(\"Unit test failure bidir ref range length: %s\", s), __FILE__, line));\n        }\n    }\n\n    assertCTFEable!(\n    {\n    test(\"a\", 'a');\n    test(\" \", ' ');\n    test(\"\\u2029\", '\\u2029'); //paraSep\n    test(\"\\u0100\", '\\u0100');\n    test(\"\\u0430\", '\\u0430');\n    test(\"\\U00010143\", '\\U00010143');\n    test(\"abcdefcdef\", 'f');\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'o', 10);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'l', 9);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'l', 8);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'e', 7);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'h', 6);\n    test(\"\\U00010143\\u0100\\U00010143hello\", '\\U00010143', 5);\n    test(\"\\U00010143\\u0100\\U00010143hello\", '\\u0100', 3);\n    test(\"\\U00010143\\u0100\\U00010143hello\", '\\U00010143', 2);\n\n    foreach (S; AliasSeq!(wchar[], const wchar[], wstring))\n    {\n        enum str = to!S(\"hello world\");\n        static assert(isSafe!(() => strideBack(str, 0)));\n        static assert(isSafe!(() => strideBack(str)   ));\n        static assert((functionAttributes!(() => strideBack(str, 0)) & FunctionAttribute.pure_) != 0);\n        static assert((functionAttributes!(() => strideBack(str)   ) & FunctionAttribute.pure_) != 0);\n    }\n    });\n}\n\n/// Ditto\nuint strideBack(S)(auto ref S str, size_t index)\nif (isRandomAccessRange!S && is(Unqual!(ElementEncodingType!S) == dchar))\n{\n    static if (is(typeof(str.length) : ulong))\n        assert(index <= str.length, \"Past the end of the UTF-32 sequence\");\n    assert(index > 0, \"Not the end of the UTF-32 sequence\");\n    return 1;\n}\n\n/// Ditto\nuint strideBack(S)(auto ref S str)\nif (isBidirectionalRange!S && is(Unqual!(ElementEncodingType!S) == dchar))\n{\n    assert(!str.empty, \"Empty UTF-32 sequence\");\n    return 1;\n}\n\n///\n@safe unittest\n{\n    assert(\"a\".strideBack == 1);\n    assert(\"λ\".strideBack == 2);\n    assert(\"aλ\".strideBack == 2);\n    assert(\"aλ\".strideBack(1) == 1);\n    assert(\"𐐷\".strideBack == 4);\n}\n\n@system unittest\n{\n    import core.exception : AssertError;\n    import std.conv : to;\n    import std.exception;\n    import std.string : format;\n    static void test(dstring s, dchar c, size_t i = size_t.max, size_t line = __LINE__)\n    {\n        enforce(strideBack(s, i == size_t.max ? s.length : i) == codeLength!dchar(c),\n                new AssertError(format(\"Unit test failure string: %s\", s), __FILE__, line));\n\n        enforce(strideBack(RandomCU!dchar(s), i == size_t.max ? s.length : i) == codeLength!dchar(c),\n                new AssertError(format(\"Unit test failure range: %s\", s), __FILE__, line));\n\n        auto refRandom = new RefRandomCU!dchar(s);\n        immutable randLen = refRandom.length;\n        enforce(strideBack(refRandom, i == size_t.max ? s.length : i) == codeLength!dchar(c),\n                new AssertError(format(\"Unit test failure rand ref range: %s\", s), __FILE__, line));\n        enforce(refRandom.length == randLen,\n                new AssertError(format(\"Unit test failure rand ref range length: %s\", s), __FILE__, line));\n\n        if (i == size_t.max)\n        {\n            enforce(strideBack(s) == codeLength!dchar(c),\n                    new AssertError(format(\"Unit test failure string code length: %s\", s), __FILE__, line));\n\n            enforce(strideBack(BidirCU!dchar(s)) == codeLength!dchar(c),\n                    new AssertError(format(\"Unit test failure range code length: %s\", s), __FILE__, line));\n\n            auto refBidir = new RefBidirCU!dchar(s);\n            immutable bidirLen = refBidir.length;\n            enforce(strideBack(refBidir) == codeLength!dchar(c),\n                    new AssertError(format(\"Unit test failure bidir ref range code length: %s\", s), __FILE__, line));\n            enforce(refBidir.length == bidirLen,\n                    new AssertError(format(\"Unit test failure bidir ref range length: %s\", s), __FILE__, line));\n        }\n    }\n\n    assertCTFEable!(\n    {\n    test(\"a\", 'a');\n    test(\" \", ' ');\n    test(\"\\u2029\", '\\u2029'); //paraSep\n    test(\"\\u0100\", '\\u0100');\n    test(\"\\u0430\", '\\u0430');\n    test(\"\\U00010143\", '\\U00010143');\n    test(\"abcdefcdef\", 'f');\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'o', 8);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'l', 7);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'l', 6);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'e', 5);\n    test(\"\\U00010143\\u0100\\U00010143hello\", 'h', 4);\n    test(\"\\U00010143\\u0100\\U00010143hello\", '\\U00010143', 3);\n    test(\"\\U00010143\\u0100\\U00010143hello\", '\\u0100', 2);\n    test(\"\\U00010143\\u0100\\U00010143hello\", '\\U00010143', 1);\n\n    foreach (S; AliasSeq!(dchar[], const dchar[], dstring))\n    {\n        enum str = to!S(\"hello world\");\n        static assert(isSafe!(() => strideBack(str, 0)));\n        static assert(isSafe!(() => strideBack(str)   ));\n        static assert((functionAttributes!(() => strideBack(str, 0)) & FunctionAttribute.pure_) != 0);\n        static assert((functionAttributes!(() => strideBack(str)   ) & FunctionAttribute.pure_) != 0);\n    }\n    });\n}\n\n\n/++\n    Given `index` into `str` and assuming that `index` is at the start\n    of a UTF sequence, `toUCSindex` determines the number of UCS characters\n    up to `index`. So, `index` is the index of a code unit at the\n    beginning of a code point, and the return value is how many code points into\n    the string that that code point is.\n  +/\nsize_t toUCSindex(C)(const(C)[] str, size_t index) @safe pure\nif (isSomeChar!C)\n{\n    static if (is(Unqual!C == dchar))\n        return index;\n    else\n    {\n        size_t n = 0;\n        size_t j = 0;\n\n        for (; j < index; ++n)\n            j += stride(str, j);\n\n        if (j > index)\n        {\n            static if (is(Unqual!C == char))\n                throw new UTFException(\"Invalid UTF-8 sequence\", index);\n            else\n                throw new UTFException(\"Invalid UTF-16 sequence\", index);\n        }\n\n        return n;\n    }\n}\n\n///\n@safe unittest\n{\n    assert(toUCSindex(`hello world`, 7) == 7);\n    assert(toUCSindex(`hello world`w, 7) == 7);\n    assert(toUCSindex(`hello world`d, 7) == 7);\n\n    assert(toUCSindex(`Ma Chérie`, 7) == 6);\n    assert(toUCSindex(`Ma Chérie`w, 7) == 7);\n    assert(toUCSindex(`Ma Chérie`d, 7) == 7);\n\n    assert(toUCSindex(`さいごの果実 / ミツバチと科学者`, 9) == 3);\n    assert(toUCSindex(`さいごの果実 / ミツバチと科学者`w, 9) == 9);\n    assert(toUCSindex(`さいごの果実 / ミツバチと科学者`d, 9) == 9);\n}\n\n\n/++\n    Given a UCS index `n` into `str`, returns the UTF index.\n    So, `n` is how many code points into the string the code point is, and\n    the array index of the code unit is returned.\n  +/\nsize_t toUTFindex(C)(const(C)[] str, size_t n) @safe pure\nif (isSomeChar!C)\n{\n    static if (is(Unqual!C == dchar))\n    {\n        return n;\n    }\n    else\n    {\n        size_t i;\n        while (n--)\n        {\n            i += stride(str, i);\n        }\n        return i;\n    }\n}\n\n///\n@safe unittest\n{\n    assert(toUTFindex(`hello world`, 7) == 7);\n    assert(toUTFindex(`hello world`w, 7) == 7);\n    assert(toUTFindex(`hello world`d, 7) == 7);\n\n    assert(toUTFindex(`Ma Chérie`, 6) == 7);\n    assert(toUTFindex(`Ma Chérie`w, 7) == 7);\n    assert(toUTFindex(`Ma Chérie`d, 7) == 7);\n\n    assert(toUTFindex(`さいごの果実 / ミツバチと科学者`, 3) == 9);\n    assert(toUTFindex(`さいごの果実 / ミツバチと科学者`w, 9) == 9);\n    assert(toUTFindex(`さいごの果実 / ミツバチと科学者`d, 9) == 9);\n}\n\n\n/* =================== Decode ======================= */\n\n/// Whether or not to replace invalid UTF with $(LREF replacementDchar)\nalias UseReplacementDchar = Flag!\"useReplacementDchar\";\n\n/++\n    Decodes and returns the code point starting at `str[index]`. `index`\n    is advanced to one past the decoded code point. If the code point is not\n    well-formed, then a `UTFException` is thrown and `index` remains\n    unchanged.\n\n    decode will only work with strings and random access ranges of code units\n    with length and slicing, whereas $(LREF decodeFront) will work with any\n    input range of code units.\n\n    Params:\n        useReplacementDchar = if invalid UTF, return replacementDchar rather than throwing\n        str = input string or indexable Range\n        index = starting index into s[]; incremented by number of code units processed\n\n    Returns:\n        decoded character\n\n    Throws:\n        $(LREF UTFException) if `str[index]` is not the start of a valid UTF\n        sequence and useReplacementDchar is `No.useReplacementDchar`\n  +/\ndchar decode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(auto ref S str, ref size_t index)\nif (!isSomeString!S &&\n    isRandomAccessRange!S && hasSlicing!S && hasLength!S && isSomeChar!(ElementType!S))\nin\n{\n    assert(index < str.length, \"Attempted to decode past the end of a string\");\n}\nout (result)\n{\n    assert(isValidDchar(result));\n}\ndo\n{\n    if (str[index] < codeUnitLimit!S)\n        return str[index++];\n    else\n        return decodeImpl!(true, useReplacementDchar)(str, index);\n}\n\n/// ditto\ndchar decode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(\nauto ref S str, ref size_t index) @trusted pure\nif (isSomeString!S)\nin\n{\n    assert(index < str.length, \"Attempted to decode past the end of a string\");\n}\nout (result)\n{\n    assert(isValidDchar(result));\n}\ndo\n{\n    if (str[index] < codeUnitLimit!S)\n        return str[index++];\n    else\n        return decodeImpl!(true, useReplacementDchar)(str, index);\n}\n\n///\n@safe pure unittest\n{\n    size_t i;\n\n    assert(\"a\".decode(i) == 'a' && i == 1);\n    i = 0;\n    assert(\"å\".decode(i) == 'å' && i == 2);\n    i = 1;\n    assert(\"aå\".decode(i) == 'å' && i == 3);\n    i = 0;\n    assert(\"å\"w.decode(i) == 'å' && i == 1);\n\n    // ë as a multi-code point grapheme\n    i = 0;\n    assert(\"e\\u0308\".decode(i) == 'e' && i == 1);\n    // ë as a single code point grapheme\n    i = 0;\n    assert(\"ë\".decode(i) == 'ë' && i == 2);\n    i = 0;\n    assert(\"ë\"w.decode(i) == 'ë' && i == 1);\n}\n\n/++\n    `decodeFront` is a variant of $(LREF decode) which specifically decodes\n    the first code point. Unlike $(LREF decode), `decodeFront` accepts any\n    $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n    of code units (rather than just a string or random access\n    range). It also takes the range by `ref` and pops off the elements as it\n    decodes them. If `numCodeUnits` is passed in, it gets set to the number\n    of code units which were in the code point which was decoded.\n\n    Params:\n        useReplacementDchar = if invalid UTF, return replacementDchar rather than throwing\n        str = input string or indexable Range\n        numCodeUnits = set to number of code units processed\n\n    Returns:\n        decoded character\n\n    Throws:\n        $(LREF UTFException) if `str.front` is not the start of a valid UTF\n        sequence. If an exception is thrown, then there is no guarantee as to\n        the number of code units which were popped off, as it depends on the\n        type of range being used and how many code units had to be popped off\n        before the code point was determined to be invalid.\n  +/\ndchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(\nref S str, out size_t numCodeUnits)\nif (!isSomeString!S && isInputRange!S && isSomeChar!(ElementType!S))\nin\n{\n    assert(!str.empty);\n}\nout (result)\n{\n    assert(isValidDchar(result));\n}\ndo\n{\n    immutable fst = str.front;\n\n    if (fst < codeUnitLimit!S)\n    {\n        str.popFront();\n        numCodeUnits = 1;\n        return fst;\n    }\n    else\n    {\n        //@@@BUG@@@ 14447 forces canIndex to be done outside of decodeImpl, which\n        //is undesirable, since not all overloads of decodeImpl need it. So, it\n        //should be moved back into decodeImpl once bug# 8521 has been fixed.\n        enum canIndex = isRandomAccessRange!S && hasSlicing!S && hasLength!S;\n        immutable retval = decodeImpl!(canIndex, useReplacementDchar)(str, numCodeUnits);\n\n        // The other range types were already popped by decodeImpl.\n        static if (isRandomAccessRange!S && hasSlicing!S && hasLength!S)\n            str = str[numCodeUnits .. str.length];\n\n        return retval;\n    }\n}\n\n/// ditto\ndchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(\nref S str, out size_t numCodeUnits) @trusted pure\nif (isSomeString!S)\nin\n{\n    assert(!str.empty);\n}\nout (result)\n{\n    assert(isValidDchar(result));\n}\ndo\n{\n    if (str[0] < codeUnitLimit!S)\n    {\n        numCodeUnits = 1;\n        immutable retval = str[0];\n        str = str[1 .. $];\n        return retval;\n    }\n    else\n    {\n        immutable retval = decodeImpl!(true, useReplacementDchar)(str, numCodeUnits);\n        str = str[numCodeUnits .. $];\n        return retval;\n    }\n}\n\n/++ Ditto +/\ndchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str)\nif (isInputRange!S && isSomeChar!(ElementType!S))\n{\n    size_t numCodeUnits;\n    return decodeFront!useReplacementDchar(str, numCodeUnits);\n}\n\n///\n@safe pure unittest\n{\n    import std.range.primitives;\n    string str = \"Hello, World!\";\n\n    assert(str.decodeFront == 'H' && str == \"ello, World!\");\n    str = \"å\";\n    assert(str.decodeFront == 'å' && str.empty);\n    str = \"å\";\n    size_t i;\n    assert(str.decodeFront(i) == 'å' && i == 2 && str.empty);\n}\n\n/++\n    `decodeBack` is a variant of $(LREF decode) which specifically decodes\n    the last code point. Unlike $(LREF decode), `decodeBack` accepts any\n    bidirectional range of code units (rather than just a string or random access\n    range). It also takes the range by `ref` and pops off the elements as it\n    decodes them. If `numCodeUnits` is passed in, it gets set to the number\n    of code units which were in the code point which was decoded.\n\n    Params:\n        useReplacementDchar = if invalid UTF, return `replacementDchar` rather than throwing\n        str = input string or bidirectional Range\n        numCodeUnits = gives the number of code units processed\n\n    Returns:\n        A decoded UTF character.\n\n    Throws:\n        $(LREF UTFException) if `str.back` is not the end of a valid UTF\n        sequence. If an exception is thrown, the `str` itself remains unchanged,\n        but there is no guarantee as to the value of `numCodeUnits` (when passed).\n  +/\ndchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(\n    ref S str, out size_t numCodeUnits)\nif (isSomeString!S)\nin\n{\n    assert(!str.empty);\n}\nout (result)\n{\n    assert(isValidDchar(result));\n}\ndo\n{\n    if (str[$ - 1] < codeUnitLimit!S)\n    {\n        numCodeUnits = 1;\n        immutable retval = str[$ - 1];\n        str = str[0 .. $ - 1];\n        return retval;\n    }\n    else\n    {\n        numCodeUnits = strideBack(str);\n        immutable newLength = str.length - numCodeUnits;\n        size_t index = newLength;\n        immutable retval = decodeImpl!(true, useReplacementDchar)(str, index);\n        str = str[0 .. newLength];\n        return retval;\n    }\n}\n\n/++ Ditto +/\ndchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(\n    ref S str, out size_t numCodeUnits)\nif (!isSomeString!S && isSomeChar!(ElementType!S) && isBidirectionalRange!S\n    && ((isRandomAccessRange!S && hasLength!S) || !isRandomAccessRange!S))\nin\n{\n    assert(!str.empty);\n}\nout (result)\n{\n    assert(isValidDchar(result));\n}\ndo\n{\n    if (str.back < codeUnitLimit!S)\n    {\n        numCodeUnits = 1;\n        immutable retval = str.back;\n        str.popBack();\n        return retval;\n    }\n    else\n    {\n        numCodeUnits = strideBack(str);\n        static if (isRandomAccessRange!S)\n        {\n            size_t index = str.length - numCodeUnits;\n            immutable retval = decodeImpl!(true, useReplacementDchar)(str, index);\n            str.popBackExactly(numCodeUnits);\n            return retval;\n        }\n        else\n        {\n            alias Char = Unqual!(ElementType!S);\n            Char[4] codeUnits;\n            S tmp = str.save;\n            for (size_t i = numCodeUnits; i > 0; )\n            {\n                codeUnits[--i] = tmp.back;\n                tmp.popBack();\n            }\n            const Char[] codePoint = codeUnits[0 .. numCodeUnits];\n            size_t index = 0;\n            immutable retval = decodeImpl!(true, useReplacementDchar)(codePoint, index);\n            str = tmp;\n            return retval;\n        }\n    }\n}\n\n/++ Ditto +/\ndchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str)\nif (isSomeString!S\n    || (isRandomAccessRange!S && hasLength!S && isSomeChar!(ElementType!S))\n    || (!isRandomAccessRange!S && isBidirectionalRange!S && isSomeChar!(ElementType!S)))\nin\n{\n    assert(!str.empty);\n}\nout (result)\n{\n    assert(isValidDchar(result));\n}\ndo\n{\n    size_t numCodeUnits;\n    return decodeBack!useReplacementDchar(str, numCodeUnits);\n}\n\n///\n@system pure unittest\n{\n    import std.range.primitives;\n    string str = \"Hello, World!\";\n\n    assert(str.decodeBack == '!' && str == \"Hello, World\");\n    str = \"å\";\n    assert(str.decodeBack == 'å' && str.empty);\n    str = \"å\";\n    size_t i;\n    assert(str.decodeBack(i) == 'å' && i == 2 && str.empty);\n}\n\n// Gives the maximum value that a code unit for the given range type can hold.\npackage template codeUnitLimit(S)\nif (isSomeChar!(ElementEncodingType!S))\n{\n    static if (is(Unqual!(ElementEncodingType!S) == char))\n        enum char codeUnitLimit = 0x80;\n    else static if (is(Unqual!(ElementEncodingType!S) == wchar))\n        enum wchar codeUnitLimit = 0xD800;\n    else\n        enum dchar codeUnitLimit = 0xD800;\n}\n\n/*\n * For strings, this function does its own bounds checking to give a\n * more useful error message when attempting to decode past the end of a string.\n * Subsequently it uses a pointer instead of an array to avoid\n * redundant bounds checking.\n *\n * The three overloads of this operate on chars, wchars, and dchars.\n *\n * Params:\n *      canIndex = if S is indexable\n *      useReplacementDchar = if invalid UTF, return replacementDchar rather than throwing\n *      str = input string or Range\n *      index = starting index into s[]; incremented by number of code units processed\n *\n * Returns:\n *      decoded character\n */\nprivate dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(\n    auto ref S str, ref size_t index)\nif (\n    is(S : const char[]) || (isInputRange!S && is(Unqual!(ElementEncodingType!S) == char)))\n{\n    /* The following encodings are valid, except for the 5 and 6 byte\n     * combinations:\n     *  0xxxxxxx\n     *  110xxxxx 10xxxxxx\n     *  1110xxxx 10xxxxxx 10xxxxxx\n     *  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n     *  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n     *  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n     */\n\n    /* Dchar bitmask for different numbers of UTF-8 code units.\n     */\n    alias bitMask = AliasSeq!((1 << 7) - 1, (1 << 11) - 1, (1 << 16) - 1, (1 << 21) - 1);\n\n    static if (is(S : const char[]))\n        auto pstr = str.ptr + index;    // this is what makes decodeImpl() @system code\n    else static if (isRandomAccessRange!S && hasSlicing!S && hasLength!S)\n        auto pstr = str[index .. str.length];\n    else\n        alias pstr = str;\n\n    //@@@BUG@@@ 14447 forces this to be done outside of decodeImpl\n    //enum canIndex = is(S : const char[]) || (isRandomAccessRange!S && hasSlicing!S && hasLength!S);\n\n    static if (canIndex)\n    {\n        immutable length = str.length - index;\n        ubyte fst = pstr[0];\n    }\n    else\n    {\n        ubyte fst = pstr.front;\n        pstr.popFront();\n    }\n\n    static if (!useReplacementDchar)\n    {\n        static if (canIndex)\n        {\n            static UTFException exception(S)(S str, string msg)\n            {\n                uint[4] sequence = void;\n                size_t i;\n\n                do\n                {\n                    sequence[i] = str[i];\n                } while (++i < str.length && i < 4 && (str[i] & 0xC0) == 0x80);\n\n                return new UTFException(msg, i).setSequence(sequence[0 .. i]);\n            }\n        }\n\n        UTFException invalidUTF()\n        {\n            static if (canIndex)\n               return exception(pstr[0 .. length], \"Invalid UTF-8 sequence\");\n            else\n            {\n                //We can't include the invalid sequence with input strings without\n                //saving each of the code units along the way, and we can't do it with\n                //forward ranges without saving the entire range. Both would incur a\n                //cost for the decoding of every character just to provide a better\n                //error message for the (hopefully) rare case when an invalid UTF-8\n                //sequence is encountered, so we don't bother trying to include the\n                //invalid sequence here, unlike with strings and sliceable ranges.\n               return new UTFException(\"Invalid UTF-8 sequence\");\n            }\n        }\n\n        UTFException outOfBounds()\n        {\n            static if (canIndex)\n               return exception(pstr[0 .. length], \"Attempted to decode past the end of a string\");\n            else\n               return new UTFException(\"Attempted to decode past the end of a string\");\n        }\n    }\n\n    if ((fst & 0b1100_0000) != 0b1100_0000)\n    {\n        static if (useReplacementDchar)\n        {\n            ++index;            // always consume bad input to avoid infinite loops\n            return replacementDchar;\n        }\n        else\n            throw invalidUTF(); // starter must have at least 2 first bits set\n    }\n    ubyte tmp = void;\n    dchar d = fst; // upper control bits are masked out later\n    fst <<= 1;\n\n    foreach (i; AliasSeq!(1, 2, 3))\n    {\n\n        static if (canIndex)\n        {\n            if (i == length)\n            {\n                static if (useReplacementDchar)\n                {\n                    index += i;\n                    return replacementDchar;\n                }\n                else\n                    throw outOfBounds();\n            }\n        }\n        else\n        {\n            if (pstr.empty)\n            {\n                static if (useReplacementDchar)\n                {\n                    index += i;\n                    return replacementDchar;\n                }\n                else\n                    throw outOfBounds();\n            }\n        }\n\n        static if (canIndex)\n            tmp = pstr[i];\n        else\n        {\n            tmp = pstr.front;\n            pstr.popFront();\n        }\n\n        if ((tmp & 0xC0) != 0x80)\n        {\n            static if (useReplacementDchar)\n            {\n                index += i + 1;\n                return replacementDchar;\n            }\n            else\n                throw invalidUTF();\n        }\n\n        d = (d << 6) | (tmp & 0x3F);\n        fst <<= 1;\n\n        if (!(fst & 0x80)) // no more bytes\n        {\n            d &= bitMask[i]; // mask out control bits\n\n            // overlong, could have been encoded with i bytes\n            if ((d & ~bitMask[i - 1]) == 0)\n            {\n                static if (useReplacementDchar)\n                {\n                    index += i + 1;\n                    return replacementDchar;\n                }\n                else\n                    throw invalidUTF();\n            }\n\n            // check for surrogates only needed for 3 bytes\n            static if (i == 2)\n            {\n                if (!isValidDchar(d))\n                {\n                    static if (useReplacementDchar)\n                    {\n                        index += i + 1;\n                        return replacementDchar;\n                    }\n                    else\n                        throw invalidUTF();\n                }\n            }\n\n            index += i + 1;\n            static if (i == 3)\n            {\n                if (d > dchar.max)\n                {\n                    static if (useReplacementDchar)\n                        d = replacementDchar;\n                    else\n                        throw invalidUTF();\n                }\n            }\n            return d;\n        }\n    }\n\n    static if (useReplacementDchar)\n    {\n        index += 4;             // read 4 chars by now\n        return replacementDchar;\n    }\n    else\n        throw invalidUTF();\n}\n\n@safe pure @nogc nothrow\nunittest\n{\n    // Add tests for useReplacemendDchar == yes path\n\n    static struct R\n    {\n      @safe pure @nogc nothrow:\n        this(string s) { this.s = s; }\n        @property bool empty() { return idx == s.length; }\n        @property char front() { return s[idx]; }\n        void popFront() { ++idx; }\n        size_t idx;\n        string s;\n    }\n\n    foreach (s; invalidUTFstrings!char())\n    {\n        auto r = R(s);\n        size_t index;\n        dchar dc = decodeImpl!(false, Yes.useReplacementDchar)(r, index);\n        assert(dc == replacementDchar);\n        assert(1 <= index && index <= s.length);\n    }\n}\n\nprivate dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)\n(auto ref S str, ref size_t index)\nif (is(S : const wchar[]) || (isInputRange!S && is(Unqual!(ElementEncodingType!S) == wchar)))\n{\n    static if (is(S : const wchar[]))\n        auto pstr = str.ptr + index;\n    else static if (isRandomAccessRange!S && hasSlicing!S && hasLength!S)\n        auto pstr = str[index .. str.length];\n    else\n        alias pstr = str;\n\n    //@@@BUG@@@ 14447 forces this to be done outside of decodeImpl\n    //enum canIndex = is(S : const wchar[]) || (isRandomAccessRange!S && hasSlicing!S && hasLength!S);\n\n    static if (canIndex)\n    {\n        immutable length = str.length - index;\n        uint u = pstr[0];\n    }\n    else\n    {\n        uint u = pstr.front;\n        pstr.popFront();\n    }\n\n    static if (!useReplacementDchar)\n    {\n        UTFException exception(string msg)\n        {\n            static if (canIndex)\n                return new UTFException(msg).setSequence(pstr[0]);\n            else\n                return new UTFException(msg);\n        }\n    }\n\n    // The < case must be taken care of before decodeImpl is called.\n    assert(u >= 0xD800);\n\n    if (u <= 0xDBFF)\n    {\n        static if (canIndex)\n            immutable onlyOneCodeUnit = length == 1;\n        else\n            immutable onlyOneCodeUnit = pstr.empty;\n\n        if (onlyOneCodeUnit)\n        {\n            static if (useReplacementDchar)\n            {\n                ++index;\n                return replacementDchar;\n            }\n            else\n                throw exception(\"surrogate UTF-16 high value past end of string\");\n        }\n\n        static if (canIndex)\n            immutable uint u2 = pstr[1];\n        else\n        {\n            immutable uint u2 = pstr.front;\n            pstr.popFront();\n        }\n\n        if (u2 < 0xDC00 || u2 > 0xDFFF)\n        {\n            static if (useReplacementDchar)\n                u = replacementDchar;\n            else\n                throw exception(\"surrogate UTF-16 low value out of range\");\n        }\n        else\n            u = ((u - 0xD7C0) << 10) + (u2 - 0xDC00);\n        ++index;\n    }\n    else if (u >= 0xDC00 && u <= 0xDFFF)\n    {\n        static if (useReplacementDchar)\n            u = replacementDchar;\n        else\n            throw exception(\"unpaired surrogate UTF-16 value\");\n    }\n    ++index;\n\n    // Note: u+FFFE and u+FFFF are specifically permitted by the\n    // Unicode standard for application internal use (see isValidDchar)\n\n    return cast(dchar) u;\n}\n\n@safe pure @nogc nothrow\nunittest\n{\n    // Add tests for useReplacemendDchar == true path\n\n    static struct R\n    {\n      @safe pure @nogc nothrow:\n        this(wstring s) { this.s = s; }\n        @property bool empty() { return idx == s.length; }\n        @property wchar front() { return s[idx]; }\n        void popFront() { ++idx; }\n        size_t idx;\n        wstring s;\n    }\n\n    foreach (s; invalidUTFstrings!wchar())\n    {\n        auto r = R(s);\n        size_t index;\n        dchar dc = decodeImpl!(false, Yes.useReplacementDchar)(r, index);\n        assert(dc == replacementDchar);\n        assert(1 <= index && index <= s.length);\n    }\n}\n\nprivate dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(\n    auto ref S str, ref size_t index)\nif (is(S : const dchar[]) || (isInputRange!S && is(Unqual!(ElementEncodingType!S) == dchar)))\n{\n    static if (is(S : const dchar[]))\n        auto pstr = str.ptr;\n    else\n        alias pstr = str;\n\n    static if (is(S : const dchar[]) || isRandomAccessRange!S)\n    {\n        dchar dc = pstr[index];\n        if (!isValidDchar(dc))\n        {\n            static if (useReplacementDchar)\n                dc = replacementDchar;\n            else\n                throw new UTFException(\"Invalid UTF-32 value\").setSequence(dc);\n        }\n        ++index;\n        return dc;\n    }\n    else\n    {\n        dchar dc = pstr.front;\n        if (!isValidDchar(dc))\n        {\n            static if (useReplacementDchar)\n                dc = replacementDchar;\n            else\n                throw new UTFException(\"Invalid UTF-32 value\").setSequence(dc);\n        }\n        ++index;\n        pstr.popFront();\n        return dc;\n    }\n}\n\n@safe pure @nogc nothrow\nunittest\n{\n    // Add tests for useReplacemendDchar == true path\n\n    static struct R\n    {\n      @safe pure @nogc nothrow:\n        this(dstring s) { this.s = s; }\n        @property bool empty() { return idx == s.length; }\n        @property dchar front() { return s[idx]; }\n        void popFront() { ++idx; }\n        size_t idx;\n        dstring s;\n    }\n\n    foreach (s; invalidUTFstrings!dchar())\n    {\n        auto r = R(s);\n        size_t index;\n        dchar dc = decodeImpl!(false, Yes.useReplacementDchar)(r, index);\n        assert(dc == replacementDchar);\n        assert(1 <= index && index <= s.length);\n    }\n}\n\n\nversion (unittest) private void testDecode(R)(R range,\n                                             size_t index,\n                                             dchar expectedChar,\n                                             size_t expectedIndex,\n                                             size_t line = __LINE__)\n{\n    import core.exception : AssertError;\n    import std.string : format;\n\n    static if (hasLength!R)\n        immutable lenBefore = range.length;\n\n    static if (isRandomAccessRange!R)\n    {\n        {\n            immutable result = decode(range, index);\n            enforce(result == expectedChar,\n                    new AssertError(format(\"decode: Wrong character: %s\", result), __FILE__, line));\n            enforce(index == expectedIndex,\n                    new AssertError(format(\"decode: Wrong index: %s\", index), __FILE__, line));\n            static if (hasLength!R)\n            {\n                enforce(range.length == lenBefore,\n                        new AssertError(format(\"decode: length changed: %s\", range.length), __FILE__, line));\n            }\n        }\n    }\n}\n\nversion (unittest) private void testDecodeFront(R)(ref R range,\n                                                  dchar expectedChar,\n                                                  size_t expectedNumCodeUnits,\n                                                  size_t line = __LINE__)\n{\n    import core.exception : AssertError;\n    import std.string : format;\n\n    static if (hasLength!R)\n        immutable lenBefore = range.length;\n\n    size_t numCodeUnits;\n    immutable result = decodeFront(range, numCodeUnits);\n    enforce(result == expectedChar,\n            new AssertError(format(\"decodeFront: Wrong character: %s\", result), __FILE__, line));\n    enforce(numCodeUnits == expectedNumCodeUnits,\n            new AssertError(format(\"decodeFront: Wrong numCodeUnits: %s\", numCodeUnits), __FILE__, line));\n\n    static if (hasLength!R)\n    {\n        enforce(range.length == lenBefore - numCodeUnits,\n                new AssertError(format(\"decodeFront: wrong length: %s\", range.length), __FILE__, line));\n    }\n}\n\nversion (unittest) private void testDecodeBack(R)(ref R range,\n                                                 dchar expectedChar,\n                                                 size_t expectedNumCodeUnits,\n                                                 size_t line = __LINE__)\n{\n    // This condition is to allow unit testing all `decode` functions together\n    static if (!isBidirectionalRange!R)\n        return;\n    else\n    {\n        import core.exception : AssertError;\n        import std.string : format;\n\n        static if (hasLength!R)\n            immutable lenBefore = range.length;\n\n        size_t numCodeUnits;\n        immutable result = decodeBack(range, numCodeUnits);\n        enforce(result == expectedChar,\n                new AssertError(format(\"decodeBack: Wrong character: %s\", result), __FILE__, line));\n        enforce(numCodeUnits == expectedNumCodeUnits,\n                new AssertError(format(\"decodeBack: Wrong numCodeUnits: %s\", numCodeUnits), __FILE__, line));\n\n        static if (hasLength!R)\n        {\n            enforce(range.length == lenBefore - numCodeUnits,\n                    new AssertError(format(\"decodeBack: wrong length: %s\", range.length), __FILE__, line));\n        }\n    }\n}\n\nversion (unittest) private void testAllDecode(R)(R range,\n                                                dchar expectedChar,\n                                                size_t expectedIndex,\n                                                size_t line = __LINE__)\n{\n    testDecode(range, 0, expectedChar, expectedIndex, line);\n    static if (isBidirectionalRange!R)\n    {\n        auto rangeCopy = range.save;\n        testDecodeBack(rangeCopy, expectedChar, expectedIndex, line);\n    }\n    testDecodeFront(range, expectedChar, expectedIndex, line);\n}\n\nversion (unittest) private void testBadDecode(R)(R range, size_t index, size_t line = __LINE__)\n{\n    import core.exception : AssertError;\n    import std.string : format;\n\n    immutable initialIndex = index;\n\n    static if (hasLength!R)\n        immutable lenBefore = range.length;\n\n    static if (isRandomAccessRange!R)\n    {\n        assertThrown!UTFException(decode(range, index), null, __FILE__, line);\n        enforce(index == initialIndex,\n                new AssertError(format(\"decode: Wrong index: %s\", index), __FILE__, line));\n        static if (hasLength!R)\n        {\n            enforce(range.length == lenBefore,\n                    new AssertError(format(\"decode: length changed:\", range.length), __FILE__, line));\n        }\n    }\n\n    if (initialIndex == 0)\n        assertThrown!UTFException(decodeFront(range, index), null, __FILE__, line);\n}\n\nversion (unittest) private void testBadDecodeBack(R)(R range, size_t line = __LINE__)\n{\n    // This condition is to allow unit testing all `decode` functions together\n    static if (!isBidirectionalRange!R)\n        return;\n    else\n    {\n        import core.exception : AssertError;\n        import std.string : format;\n\n        static if (hasLength!R)\n            immutable lenBefore = range.length;\n\n        static if (isRandomAccessRange!R)\n        {\n            assertThrown!UTFException(decodeBack(range), null, __FILE__, line);\n            static if (hasLength!R)\n            {\n                enforce(range.length == lenBefore,\n                        new AssertError(format(\"decodeBack: length changed:\", range.length), __FILE__, line));\n            }\n        }\n    }\n}\n\n@system unittest\n{\n    import std.conv : to;\n    import std.exception;\n\n    assertCTFEable!(\n    {\n    foreach (S; AliasSeq!(to!string, InputCU!char, RandomCU!char,\n                          (string s) => new RefBidirCU!char(s),\n                          (string s) => new RefRandomCU!char(s)))\n    {\n        enum sHasLength = hasLength!(typeof(S(\"abcd\")));\n\n        {\n            auto range = S(\"abcd\");\n            testDecode(range, 0, 'a', 1);\n            testDecode(range, 1, 'b', 2);\n            testDecodeFront(range, 'a', 1);\n            testDecodeFront(range, 'b', 1);\n            assert(decodeFront(range) == 'c');\n            assert(decodeFront(range) == 'd');\n        }\n\n        {\n            auto range = S(\"ウェブサイト\");\n            testDecode(range, 0, 'ウ', 3);\n            testDecode(range, 3, 'ェ', 6);\n            testDecodeFront(range, 'ウ', 3);\n            testDecodeFront(range, 'ェ', 3);\n            assert(decodeFront(range) == 'ブ');\n            assert(decodeFront(range) == 'サ');\n        }\n\n        {\n            auto range = S(\"abcd\");\n            testDecodeBack(range, 'd', 1);\n            testDecodeBack(range, 'c', 1);\n            testDecodeBack(range, 'b', 1);\n            testDecodeBack(range, 'a', 1);\n        }\n\n        {\n            auto range = S(\"ウェブサイト\");\n            testDecodeBack(range, 'ト', 3);\n            testDecodeBack(range, 'イ', 3);\n            testDecodeBack(range, 'サ', 3);\n            testDecodeBack(range, 'ブ', 3);\n        }\n\n        testAllDecode(S(\"\\xC2\\xA9\"), '\\u00A9', 2);\n        testAllDecode(S(\"\\xE2\\x89\\xA0\"), '\\u2260', 3);\n\n        foreach (str; [\"\\xE2\\x89\", // too short\n                       \"\\xC0\\x8A\",\n                       \"\\xE0\\x80\\x8A\",\n                       \"\\xF0\\x80\\x80\\x8A\",\n                       \"\\xF8\\x80\\x80\\x80\\x8A\",\n                       \"\\xFC\\x80\\x80\\x80\\x80\\x8A\"])\n        {\n            testBadDecode(S(str), 0);\n            testBadDecode(S(str), 1);\n            testBadDecodeBack(S(str));\n        }\n\n        //Invalid UTF-8 sequence where the first code unit is valid.\n        testAllDecode(S(\"\\xEF\\xBF\\xBE\"), cast(dchar) 0xFFFE, 3);\n        testAllDecode(S(\"\\xEF\\xBF\\xBF\"), cast(dchar) 0xFFFF, 3);\n\n        //Invalid UTF-8 sequence where the first code unit isn't valid.\n        foreach (str; [\"\\xED\\xA0\\x80\",\n                       \"\\xED\\xAD\\xBF\",\n                       \"\\xED\\xAE\\x80\",\n                       \"\\xED\\xAF\\xBF\",\n                       \"\\xED\\xB0\\x80\",\n                       \"\\xED\\xBE\\x80\",\n                       \"\\xED\\xBF\\xBF\"])\n        {\n            testBadDecode(S(str), 0);\n            testBadDecodeBack(S(str));\n        }\n    }\n    });\n}\n\n@system unittest\n{\n    import std.conv : to;\n    import std.exception;\n    assertCTFEable!(\n    {\n    foreach (S; AliasSeq!(to!wstring, InputCU!wchar, RandomCU!wchar,\n                          (wstring s) => new RefBidirCU!wchar(s),\n                          (wstring s) => new RefRandomCU!wchar(s)))\n    {\n        testAllDecode(S([cast(wchar) 0x1111]), cast(dchar) 0x1111, 1);\n        testAllDecode(S([cast(wchar) 0xD800, cast(wchar) 0xDC00]), cast(dchar) 0x10000, 2);\n        testAllDecode(S([cast(wchar) 0xDBFF, cast(wchar) 0xDFFF]), cast(dchar) 0x10FFFF, 2);\n        testAllDecode(S([cast(wchar) 0xFFFE]), cast(dchar) 0xFFFE, 1);\n        testAllDecode(S([cast(wchar) 0xFFFF]), cast(dchar) 0xFFFF, 1);\n\n        testBadDecode(S([ cast(wchar) 0xD801 ]), 0);\n        testBadDecode(S([ cast(wchar) 0xD800, cast(wchar) 0x1200 ]), 0);\n\n        testBadDecodeBack(S([ cast(wchar) 0xD801 ]));\n        testBadDecodeBack(S([ cast(wchar) 0x0010, cast(wchar) 0xD800 ]));\n\n        {\n            auto range = S(\"ウェブサイト\");\n            testDecode(range, 0, 'ウ', 1);\n            testDecode(range, 1, 'ェ', 2);\n            testDecodeFront(range, 'ウ', 1);\n            testDecodeFront(range, 'ェ', 1);\n            assert(decodeFront(range) == 'ブ');\n            assert(decodeFront(range) == 'サ');\n        }\n\n        {\n            auto range = S(\"ウェブサイト\");\n            testDecodeBack(range, 'ト', 1);\n            testDecodeBack(range, 'イ', 1);\n            testDecodeBack(range, 'サ', 1);\n            testDecodeBack(range, 'ブ', 1);\n        }\n    }\n\n    foreach (S; AliasSeq!(to!wstring, RandomCU!wchar, (wstring s) => new RefRandomCU!wchar(s)))\n    {\n        auto str = S([cast(wchar) 0xD800, cast(wchar) 0xDC00,\n                      cast(wchar) 0x1400,\n                      cast(wchar) 0xDAA7, cast(wchar) 0xDDDE]);\n        testDecode(str, 0, cast(dchar) 0x10000, 2);\n        testDecode(str, 2, cast(dchar) 0x1400, 3);\n        testDecode(str, 3, cast(dchar) 0xB9DDE, 5);\n        testDecodeBack(str, cast(dchar) 0xB9DDE, 2);\n        testDecodeBack(str, cast(dchar) 0x1400, 1);\n        testDecodeBack(str, cast(dchar) 0x10000, 2);\n    }\n    });\n}\n\n@system unittest\n{\n    import std.conv : to;\n    import std.exception;\n    assertCTFEable!(\n    {\n    foreach (S; AliasSeq!(to!dstring, RandomCU!dchar, InputCU!dchar,\n                          (dstring s) => new RefBidirCU!dchar(s),\n                          (dstring s) => new RefRandomCU!dchar(s)))\n    {\n        testAllDecode(S([cast(dchar) 0x1111]), cast(dchar) 0x1111, 1);\n        testAllDecode(S([cast(dchar) 0x10000]), cast(dchar) 0x10000, 1);\n        testAllDecode(S([cast(dchar) 0x10FFFF]), cast(dchar) 0x10FFFF, 1);\n        testAllDecode(S([cast(dchar) 0xFFFE]), cast(dchar) 0xFFFE, 1);\n        testAllDecode(S([cast(dchar) 0xFFFF]), cast(dchar) 0xFFFF, 1);\n\n        testBadDecode(S([cast(dchar) 0xD800]), 0);\n        testBadDecode(S([cast(dchar) 0xDFFE]), 0);\n        testBadDecode(S([cast(dchar) 0x110000]), 0);\n\n        testBadDecodeBack(S([cast(dchar) 0xD800]));\n        testBadDecodeBack(S([cast(dchar) 0xDFFE]));\n        testBadDecodeBack(S([cast(dchar) 0x110000]));\n\n        {\n            auto range = S(\"ウェブサイト\");\n            testDecode(range, 0, 'ウ', 1);\n            testDecode(range, 1, 'ェ', 2);\n            testDecodeFront(range, 'ウ', 1);\n            testDecodeFront(range, 'ェ', 1);\n            assert(decodeFront(range) == 'ブ');\n            assert(decodeFront(range) == 'サ');\n        }\n\n        {\n            auto range = S(\"ウェブサイト\");\n            testDecodeBack(range, 'ト', 1);\n            testDecodeBack(range, 'イ', 1);\n            testDecodeBack(range, 'サ', 1);\n            testDecodeBack(range, 'ブ', 1);\n        }\n    }\n\n    foreach (S; AliasSeq!(to!dstring, RandomCU!dchar, (dstring s) => new RefRandomCU!dchar(s)))\n    {\n        auto str = S([cast(dchar) 0x10000, cast(dchar) 0x1400, cast(dchar) 0xB9DDE]);\n        testDecode(str, 0, 0x10000, 1);\n        testDecode(str, 1, 0x1400, 2);\n        testDecode(str, 2, 0xB9DDE, 3);\n        testDecodeBack(str, cast(dchar) 0xB9DDE, 1);\n        testDecodeBack(str, cast(dchar) 0x1400, 1);\n        testDecodeBack(str, cast(dchar) 0x10000, 1);\n    }\n    });\n}\n\n@safe unittest\n{\n    import std.exception;\n    assertCTFEable!(\n    {\n    foreach (S; AliasSeq!( char[], const( char)[],  string,\n                          wchar[], const(wchar)[], wstring,\n                          dchar[], const(dchar)[], dstring))\n    {\n        static assert(isSafe!({ S str; size_t i = 0; decode(str, i);      }));\n        static assert(isSafe!({ S str; size_t i = 0; decodeFront(str, i); }));\n        static assert(isSafe!({ S str; decodeFront(str); }));\n        static assert((functionAttributes!({ S str; size_t i = 0; decode(str, i); }) & FunctionAttribute.pure_) != 0);\n        static assert((functionAttributes!({\n            S str; size_t i = 0; decodeFront(str, i);\n        }) & FunctionAttribute.pure_) != 0);\n        static assert((functionAttributes!({ S str; decodeFront(str); }) & FunctionAttribute.pure_) != 0);\n        static assert((functionAttributes!({\n            S str; size_t i = 0; decodeBack(str, i);\n        }) & FunctionAttribute.pure_) != 0);\n        static assert((functionAttributes!({ S str; decodeBack(str); }) & FunctionAttribute.pure_) != 0);\n    }\n    });\n}\n\n@safe unittest\n{\n    import std.exception;\n    char[4] val;\n    val[0] = 0b1111_0111;\n    val[1] = 0b1011_1111;\n    val[2] = 0b1011_1111;\n    val[3] = 0b1011_1111;\n    size_t i = 0;\n    assertThrown!UTFException((){ dchar ch = decode(val[], i); }());\n}\n/* =================== Encode ======================= */\n\nprivate dchar _utfException(UseReplacementDchar useReplacementDchar)(string msg, dchar c)\n{\n    static if (useReplacementDchar)\n        return replacementDchar;\n    else\n        throw new UTFException(msg).setSequence(c);\n}\n\n/++\n    Encodes `c` into the static array, `buf`, and returns the actual\n    length of the encoded character (a number between `1` and `4` for\n    `char[4]` buffers and a number between `1` and `2` for\n    `wchar[2]` buffers).\n\n    Throws:\n        `UTFException` if `c` is not a valid UTF code point.\n  +/\nsize_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(\n    out char[4] buf, dchar c) @safe pure\n{\n    if (c <= 0x7F)\n    {\n        assert(isValidDchar(c));\n        buf[0] = cast(char) c;\n        return 1;\n    }\n    if (c <= 0x7FF)\n    {\n        assert(isValidDchar(c));\n        buf[0] = cast(char)(0xC0 | (c >> 6));\n        buf[1] = cast(char)(0x80 | (c & 0x3F));\n        return 2;\n    }\n    if (c <= 0xFFFF)\n    {\n        if (0xD800 <= c && c <= 0xDFFF)\n            c = _utfException!useReplacementDchar(\"Encoding a surrogate code point in UTF-8\", c);\n\n        assert(isValidDchar(c));\n    L3:\n        buf[0] = cast(char)(0xE0 | (c >> 12));\n        buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n        buf[2] = cast(char)(0x80 | (c & 0x3F));\n        return 3;\n    }\n    if (c <= 0x10FFFF)\n    {\n        assert(isValidDchar(c));\n        buf[0] = cast(char)(0xF0 | (c >> 18));\n        buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));\n        buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n        buf[3] = cast(char)(0x80 | (c & 0x3F));\n        return 4;\n    }\n\n    assert(!isValidDchar(c));\n    c = _utfException!useReplacementDchar(\"Encoding an invalid code point in UTF-8\", c);\n    goto L3;\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    import std.typecons : Yes;\n\n    char[4] buf;\n\n    assert(encode(buf, '\\u0000') == 1 && buf[0 .. 1] == \"\\u0000\");\n    assert(encode(buf, '\\u007F') == 1 && buf[0 .. 1] == \"\\u007F\");\n    assert(encode(buf, '\\u0080') == 2 && buf[0 .. 2] == \"\\u0080\");\n    assert(encode(buf, '\\uE000') == 3 && buf[0 .. 3] == \"\\uE000\");\n    assert(encode(buf, 0xFFFE) == 3 && buf[0 .. 3] == \"\\xEF\\xBF\\xBE\");\n    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));\n\n    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);\n    auto slice = buf[];\n    assert(slice.decodeFront == replacementDchar);\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    import std.typecons : Yes;\n\n    wchar[2] buf;\n\n    assert(encode(buf, '\\u0000') == 1 && buf[0 .. 1] == \"\\u0000\");\n    assert(encode(buf, '\\uD7FF') == 1 && buf[0 .. 1] == \"\\uD7FF\");\n    assert(encode(buf, '\\uE000') == 1 && buf[0 .. 1] == \"\\uE000\");\n    assert(encode(buf, '\\U00010000') == 2 && buf[0 .. 2] == \"\\U00010000\");\n    assert(encode(buf, '\\U0010FFFF') == 2 && buf[0 .. 2] == \"\\U0010FFFF\");\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));\n\n    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);\n    auto slice = buf[];\n    assert(slice.decodeFront == replacementDchar);\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    import std.typecons : Yes;\n\n    dchar[1] buf;\n\n    assert(encode(buf, '\\u0000') == 1 && buf[0] == '\\u0000');\n    assert(encode(buf, '\\uD7FF') == 1 && buf[0] == '\\uD7FF');\n    assert(encode(buf, '\\uE000') == 1 && buf[0] == '\\uE000');\n    assert(encode(buf, '\\U0010FFFF') == 1 && buf[0] == '\\U0010FFFF');\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));\n\n    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);\n    assert(buf[0] == replacementDchar);\n}\n\n@safe unittest\n{\n    import std.exception;\n    assertCTFEable!(\n    {\n    char[4] buf;\n\n    assert(encode(buf, '\\u0000') == 1 && buf[0 .. 1] == \"\\u0000\");\n    assert(encode(buf, '\\u007F') == 1 && buf[0 .. 1] == \"\\u007F\");\n    assert(encode(buf, '\\u0080') == 2 && buf[0 .. 2] == \"\\u0080\");\n    assert(encode(buf, '\\u07FF') == 2 && buf[0 .. 2] == \"\\u07FF\");\n    assert(encode(buf, '\\u0800') == 3 && buf[0 .. 3] == \"\\u0800\");\n    assert(encode(buf, '\\uD7FF') == 3 && buf[0 .. 3] == \"\\uD7FF\");\n    assert(encode(buf, '\\uE000') == 3 && buf[0 .. 3] == \"\\uE000\");\n    assert(encode(buf, 0xFFFE) == 3 && buf[0 .. 3] == \"\\xEF\\xBF\\xBE\");\n    assert(encode(buf, 0xFFFF) == 3 && buf[0 .. 3] == \"\\xEF\\xBF\\xBF\");\n    assert(encode(buf, '\\U00010000') == 4 && buf[0 .. 4] == \"\\U00010000\");\n    assert(encode(buf, '\\U0010FFFF') == 4 && buf[0 .. 4] == \"\\U0010FFFF\");\n\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));\n\n    assert(encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000) == buf.stride);\n    assert(buf.front == replacementDchar);\n    });\n}\n\n\n/// Ditto\nsize_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(\n    out wchar[2] buf, dchar c) @safe pure\n{\n    if (c <= 0xFFFF)\n    {\n        if (0xD800 <= c && c <= 0xDFFF)\n            c = _utfException!useReplacementDchar(\"Encoding an isolated surrogate code point in UTF-16\", c);\n\n        assert(isValidDchar(c));\n    L1:\n        buf[0] = cast(wchar) c;\n        return 1;\n    }\n    if (c <= 0x10FFFF)\n    {\n        assert(isValidDchar(c));\n        buf[0] = cast(wchar)((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);\n        buf[1] = cast(wchar)(((c - 0x10000) & 0x3FF) + 0xDC00);\n        return 2;\n    }\n\n    c = _utfException!useReplacementDchar(\"Encoding an invalid code point in UTF-16\", c);\n    goto L1;\n}\n\n@safe unittest\n{\n    import std.exception;\n    assertCTFEable!(\n    {\n    wchar[2] buf;\n\n    assert(encode(buf, '\\u0000') == 1 && buf[0 .. 1] == \"\\u0000\");\n    assert(encode(buf, '\\uD7FF') == 1 && buf[0 .. 1] == \"\\uD7FF\");\n    assert(encode(buf, '\\uE000') == 1 && buf[0 .. 1] == \"\\uE000\");\n    assert(encode(buf, 0xFFFE) == 1 && buf[0] == 0xFFFE);\n    assert(encode(buf, 0xFFFF) == 1 && buf[0] == 0xFFFF);\n    assert(encode(buf, '\\U00010000') == 2 && buf[0 .. 2] == \"\\U00010000\");\n    assert(encode(buf, '\\U0010FFFF') == 2 && buf[0 .. 2] == \"\\U0010FFFF\");\n\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));\n\n    assert(encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000) == buf.stride);\n    assert(buf.front == replacementDchar);\n    });\n}\n\n\n/// Ditto\nsize_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(\n    out dchar[1] buf, dchar c) @safe pure\n{\n    if ((0xD800 <= c && c <= 0xDFFF) || 0x10FFFF < c)\n        c = _utfException!useReplacementDchar(\"Encoding an invalid code point in UTF-32\", c);\n    else\n        assert(isValidDchar(c));\n    buf[0] = c;\n    return 1;\n}\n\n@safe unittest\n{\n    import std.exception;\n    assertCTFEable!(\n    {\n    dchar[1] buf;\n\n    encode(buf, '\\u0000'); assert(buf[0] == '\\u0000');\n    encode(buf, '\\uD7FF'); assert(buf[0] == '\\uD7FF');\n    encode(buf, '\\uE000'); assert(buf[0] == '\\uE000');\n    encode(buf, 0xFFFE ); assert(buf[0] == 0xFFFE);\n    encode(buf, 0xFFFF ); assert(buf[0] == 0xFFFF);\n    encode(buf, '\\U0010FFFF'); assert(buf[0] == '\\U0010FFFF');\n\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));\n\n    assert(encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000) == buf.stride);\n    assert(buf.front == replacementDchar);\n    });\n}\n\n\n/++\n    Encodes `c` in `str`'s encoding and appends it to `str`.\n\n    Throws:\n        `UTFException` if `c` is not a valid UTF code point.\n  +/\nvoid encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(\n    ref char[] str, dchar c) @safe pure\n{\n    char[] r = str;\n\n    if (c <= 0x7F)\n    {\n        assert(isValidDchar(c));\n        r ~= cast(char) c;\n    }\n    else\n    {\n        char[4] buf;\n        uint L;\n\n        if (c <= 0x7FF)\n        {\n            assert(isValidDchar(c));\n            buf[0] = cast(char)(0xC0 | (c >> 6));\n            buf[1] = cast(char)(0x80 | (c & 0x3F));\n            L = 2;\n        }\n        else if (c <= 0xFFFF)\n        {\n            if (0xD800 <= c && c <= 0xDFFF)\n                c = _utfException!useReplacementDchar(\"Encoding a surrogate code point in UTF-8\", c);\n\n            assert(isValidDchar(c));\n        L3:\n            buf[0] = cast(char)(0xE0 | (c >> 12));\n            buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n            buf[2] = cast(char)(0x80 | (c & 0x3F));\n            L = 3;\n        }\n        else if (c <= 0x10FFFF)\n        {\n            assert(isValidDchar(c));\n            buf[0] = cast(char)(0xF0 | (c >> 18));\n            buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));\n            buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));\n            buf[3] = cast(char)(0x80 | (c & 0x3F));\n            L = 4;\n        }\n        else\n        {\n            assert(!isValidDchar(c));\n            c = _utfException!useReplacementDchar(\"Encoding an invalid code point in UTF-8\", c);\n            goto L3;\n        }\n        r ~= buf[0 .. L];\n    }\n    str = r;\n}\n\n///\n@safe unittest\n{\n    char[] s = \"abcd\".dup;\n    dchar d1 = 'a';\n    dchar d2 = 'ø';\n\n    encode(s, d1);\n    assert(s.length == 5);\n    assert(s == \"abcda\");\n    encode(s, d2);\n    assert(s.length == 7);\n    assert(s == \"abcdaø\");\n}\n\n@safe unittest\n{\n    import std.exception;\n\n    assertCTFEable!(\n    {\n    char[] s = \"abcd\".dup;\n    encode(s, cast(dchar)'a');\n    assert(s.length == 5);\n    assert(s == \"abcda\");\n\n    encode(s, cast(dchar)'\\u00A9');\n    assert(s.length == 7);\n    assert(s == \"abcda\\xC2\\xA9\");\n    //assert(s == \"abcda\\u00A9\");   // BUG: fix compiler\n\n    encode(s, cast(dchar)'\\u2260');\n    assert(s.length == 10);\n    assert(s == \"abcda\\xC2\\xA9\\xE2\\x89\\xA0\");\n    });\n}\n\n@safe unittest\n{\n    import std.exception;\n    assertCTFEable!(\n    {\n    char[] buf;\n\n    encode(buf, '\\u0000'); assert(buf[0 .. $] == \"\\u0000\");\n    encode(buf, '\\u007F'); assert(buf[1 .. $] == \"\\u007F\");\n    encode(buf, '\\u0080'); assert(buf[2 .. $] == \"\\u0080\");\n    encode(buf, '\\u07FF'); assert(buf[4 .. $] == \"\\u07FF\");\n    encode(buf, '\\u0800'); assert(buf[6 .. $] == \"\\u0800\");\n    encode(buf, '\\uD7FF'); assert(buf[9 .. $] == \"\\uD7FF\");\n    encode(buf, '\\uE000'); assert(buf[12 .. $] == \"\\uE000\");\n    encode(buf, 0xFFFE); assert(buf[15 .. $] == \"\\xEF\\xBF\\xBE\");\n    encode(buf, 0xFFFF); assert(buf[18 .. $] == \"\\xEF\\xBF\\xBF\");\n    encode(buf, '\\U00010000'); assert(buf[21 .. $] == \"\\U00010000\");\n    encode(buf, '\\U0010FFFF'); assert(buf[25 .. $] == \"\\U0010FFFF\");\n\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));\n\n    assert(buf.back != replacementDchar);\n    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);\n    assert(buf.back == replacementDchar);\n    });\n}\n\n/// ditto\nvoid encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(\n    ref wchar[] str, dchar c) @safe pure\n{\n    wchar[] r = str;\n\n    if (c <= 0xFFFF)\n    {\n        if (0xD800 <= c && c <= 0xDFFF)\n            c = _utfException!useReplacementDchar(\"Encoding an isolated surrogate code point in UTF-16\", c);\n\n        assert(isValidDchar(c));\n    L1:\n        r ~= cast(wchar) c;\n    }\n    else if (c <= 0x10FFFF)\n    {\n        wchar[2] buf;\n\n        assert(isValidDchar(c));\n        buf[0] = cast(wchar)((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);\n        buf[1] = cast(wchar)(((c - 0x10000) & 0x3FF) + 0xDC00);\n        r ~= buf;\n    }\n    else\n    {\n        assert(!isValidDchar(c));\n        c = _utfException!useReplacementDchar(\"Encoding an invalid code point in UTF-16\", c);\n        goto L1;\n    }\n\n    str = r;\n}\n\n@safe unittest\n{\n    import std.exception;\n    assertCTFEable!(\n    {\n    wchar[] buf;\n\n    encode(buf, '\\u0000'); assert(buf[0] == '\\u0000');\n    encode(buf, '\\uD7FF'); assert(buf[1] == '\\uD7FF');\n    encode(buf, '\\uE000'); assert(buf[2] == '\\uE000');\n    encode(buf, 0xFFFE); assert(buf[3] == 0xFFFE);\n    encode(buf, 0xFFFF); assert(buf[4] == 0xFFFF);\n    encode(buf, '\\U00010000'); assert(buf[5 .. $] == \"\\U00010000\");\n    encode(buf, '\\U0010FFFF'); assert(buf[7 .. $] == \"\\U0010FFFF\");\n\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));\n\n    assert(buf.back != replacementDchar);\n    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);\n    assert(buf.back == replacementDchar);\n    });\n}\n\n/// ditto\nvoid encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(\n    ref dchar[] str, dchar c) @safe pure\n{\n    if ((0xD800 <= c && c <= 0xDFFF) || 0x10FFFF < c)\n        c = _utfException!useReplacementDchar(\"Encoding an invalid code point in UTF-32\", c);\n    else\n        assert(isValidDchar(c));\n    str ~= c;\n}\n\n@safe unittest\n{\n    import std.exception;\n    assertCTFEable!(\n    {\n    dchar[] buf;\n\n    encode(buf, '\\u0000'); assert(buf[0] == '\\u0000');\n    encode(buf, '\\uD7FF'); assert(buf[1] == '\\uD7FF');\n    encode(buf, '\\uE000'); assert(buf[2] == '\\uE000');\n    encode(buf, 0xFFFE ); assert(buf[3] == 0xFFFE);\n    encode(buf, 0xFFFF ); assert(buf[4] == 0xFFFF);\n    encode(buf, '\\U0010FFFF'); assert(buf[5] == '\\U0010FFFF');\n\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));\n    assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));\n\n    assert(buf.back != replacementDchar);\n    encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);\n    assert(buf.back == replacementDchar);\n    });\n}\n\n\n/++\n    Returns the number of code units that are required to encode the code point\n    `c` when `C` is the character type used to encode it.\n  +/\nubyte codeLength(C)(dchar c) @safe pure nothrow @nogc\nif (isSomeChar!C)\n{\n    static if (C.sizeof == 1)\n    {\n        if (c <= 0x7F) return 1;\n        if (c <= 0x7FF) return 2;\n        if (c <= 0xFFFF) return 3;\n        if (c <= 0x10FFFF) return 4;\n        assert(false);\n    }\n    else static if (C.sizeof == 2)\n    {\n        return c <= 0xFFFF ? 1 : 2;\n    }\n    else\n    {\n        static assert(C.sizeof == 4);\n        return 1;\n    }\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(codeLength!char('a') == 1);\n    assert(codeLength!wchar('a') == 1);\n    assert(codeLength!dchar('a') == 1);\n\n    assert(codeLength!char('\\U0010FFFF') == 4);\n    assert(codeLength!wchar('\\U0010FFFF') == 2);\n    assert(codeLength!dchar('\\U0010FFFF') == 1);\n}\n\n\n/++\n    Returns the number of code units that are required to encode `str`\n    in a string whose character type is `C`. This is particularly useful\n    when slicing one string with the length of another and the two string\n    types use different character types.\n\n    Params:\n        C = the character type to get the encoding length for\n        input = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n        to calculate the encoding length from\n    Returns:\n        The number of code units in `input` when encoded to `C`\n  +/\nsize_t codeLength(C, InputRange)(InputRange input)\nif (isInputRange!InputRange && !isInfinite!InputRange && is(ElementType!InputRange : dchar))\n{\n    alias EncType = Unqual!(ElementEncodingType!InputRange);\n    static if (isSomeString!InputRange && is(EncType == C) && is(typeof(input.length)))\n        return input.length;\n    else\n    {\n        size_t total = 0;\n\n        foreach (dchar c; input)\n            total += codeLength!C(c);\n\n        return total;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.conv : to;\n    assert(codeLength!char(\"hello world\") ==\n           to!string(\"hello world\").length);\n    assert(codeLength!wchar(\"hello world\") ==\n           to!wstring(\"hello world\").length);\n    assert(codeLength!dchar(\"hello world\") ==\n           to!dstring(\"hello world\").length);\n\n    assert(codeLength!char(`プログラミング`) ==\n           to!string(`プログラミング`).length);\n    assert(codeLength!wchar(`プログラミング`) ==\n           to!wstring(`プログラミング`).length);\n    assert(codeLength!dchar(`プログラミング`) ==\n           to!dstring(`プログラミング`).length);\n\n    string haystack = `Être sans la verité, ça, ce ne serait pas bien.`;\n    wstring needle = `Être sans la verité`;\n    assert(haystack[codeLength!char(needle) .. $] ==\n           `, ça, ce ne serait pas bien.`);\n}\n\n@safe unittest\n{\n    import std.algorithm.iteration : filter;\n    import std.conv : to;\n    import std.exception;\n\n    assertCTFEable!(\n    {\n    foreach (S; AliasSeq!( char[], const  char[],  string,\n                          wchar[], const wchar[], wstring,\n                          dchar[], const dchar[], dstring))\n    {\n        foreach (C; AliasSeq!(char, wchar, dchar))\n        {\n            assert(codeLength!C(to!S(\"Walter Bright\")) == to!(C[])(\"Walter Bright\").length);\n            assert(codeLength!C(to!S(`言語`)) == to!(C[])(`言語`).length);\n            assert(codeLength!C(to!S(`ウェブサイト@La_Verité.com`)) ==\n                   to!(C[])(`ウェブサイト@La_Verité.com`).length);\n            assert(codeLength!C(to!S(`ウェブサイト@La_Verité.com`).filter!(x => true)()) ==\n                   to!(C[])(`ウェブサイト@La_Verité.com`).length);\n        }\n    }\n    });\n}\n\n/+\nInternal helper function:\n\nReturns true if it is safe to search for the Codepoint `c` inside\ncode units, without decoding.\n\nThis is a runtime check that is used an optimization in various functions,\nparticularly, in `std.string`.\n  +/\npackage bool canSearchInCodeUnits(C)(dchar c)\nif (isSomeChar!C)\n{\n    static if (C.sizeof == 1)\n         return c <= 0x7F;\n    else static if (C.sizeof == 2)\n        return c <= 0xD7FF || (0xE000 <= c && c <= 0xFFFF);\n    else static if (C.sizeof == 4)\n        return true;\n    else\n        static assert(0);\n}\n@safe unittest\n{\n    assert( canSearchInCodeUnits! char('a'));\n    assert( canSearchInCodeUnits!wchar('a'));\n    assert( canSearchInCodeUnits!dchar('a'));\n    assert(!canSearchInCodeUnits! char('ö')); //Important test: ö <= 0xFF\n    assert(!canSearchInCodeUnits! char(cast(char)'ö')); //Important test: ö <= 0xFF\n    assert( canSearchInCodeUnits!wchar('ö'));\n    assert( canSearchInCodeUnits!dchar('ö'));\n    assert(!canSearchInCodeUnits! char('日'));\n    assert( canSearchInCodeUnits!wchar('日'));\n    assert( canSearchInCodeUnits!dchar('日'));\n    assert(!canSearchInCodeUnits!wchar(cast(wchar) 0xDA00));\n    assert( canSearchInCodeUnits!dchar(cast(dchar) 0xDA00));\n    assert(!canSearchInCodeUnits! char('\\U00010001'));\n    assert(!canSearchInCodeUnits!wchar('\\U00010001'));\n    assert( canSearchInCodeUnits!dchar('\\U00010001'));\n}\n\n/* =================== Validation ======================= */\n\n/++\n    Checks to see if `str` is well-formed unicode or not.\n\n    Throws:\n        `UTFException` if `str` is not well-formed.\n  +/\nvoid validate(S)(in S str) @safe pure\nif (isSomeString!S)\n{\n    immutable len = str.length;\n    for (size_t i = 0; i < len; )\n    {\n        decode(str, i);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.exception : assertThrown;\n    char[] a = [167, 133, 175];\n    assertThrown!UTFException(validate(a));\n}\n\n@safe unittest // bugzilla 12923\n{\n    import std.exception;\n    assertThrown((){\n        char[3]a=[167, 133, 175];\n        validate(a[]);\n    }());\n}\n\n/**\n * Encodes the elements of `s` to UTF-8 and returns a newly allocated\n * string of the elements.\n *\n * Params:\n *     s = the string to encode\n * Returns:\n *     A UTF-8 string\n * See_Also:\n *     For a lazy, non-allocating version of these functions, see $(LREF byUTF).\n */\nstring toUTF8(S)(S s)\nif (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S))\n{\n    return toUTFImpl!string(s);\n}\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // The ö is represented by two UTF-8 code units\n    assert(\"Hellø\"w.toUTF8.equal(['H', 'e', 'l', 'l', 0xC3, 0xB8]));\n\n    // 𐐷 is four code units in UTF-8\n    assert(\"𐐷\"d.toUTF8.equal([0xF0, 0x90, 0x90, 0xB7]));\n}\n\n@system pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : ReferenceInputRange;\n\n    auto r1 = new ReferenceInputRange!dchar(\"Hellø\");\n    auto r2 = new ReferenceInputRange!dchar(\"𐐷\");\n\n    assert(r1.toUTF8.equal(['H', 'e', 'l', 'l', 0xC3, 0xB8]));\n    assert(r2.toUTF8.equal([0xF0, 0x90, 0x90, 0xB7]));\n}\n\n/**\n * Encodes the elements of `s` to UTF-16 and returns a newly GC allocated\n * `wstring` of the elements.\n *\n * Params:\n *     s = the range to encode\n * Returns:\n *     A UTF-16 string\n * See_Also:\n *     For a lazy, non-allocating version of these functions, see $(LREF byUTF).\n */\nwstring toUTF16(S)(S s)\nif (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S))\n{\n    return toUTFImpl!wstring(s);\n}\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // these graphemes are two code units in UTF-16 and one in UTF-32\n    assert(\"𤭢\"d.length == 1);\n    assert(\"𐐷\"d.length == 1);\n\n    assert(\"𤭢\"d.toUTF16.equal([0xD852, 0xDF62]));\n    assert(\"𐐷\"d.toUTF16.equal([0xD801, 0xDC37]));\n}\n\n@system pure unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.internal.test.dummyrange : ReferenceInputRange;\n\n    auto r1 = new ReferenceInputRange!dchar(\"𤭢\");\n    auto r2 = new ReferenceInputRange!dchar(\"𐐷\");\n\n    assert(r1.toUTF16.equal([0xD852, 0xDF62]));\n    assert(r2.toUTF16.equal([0xD801, 0xDC37]));\n}\n\n\n/**\n * Encodes the elements of `s` to UTF-32 and returns a newly GC allocated\n * `dstring` of the elements.\n *\n * Params:\n *     s = the range to encode\n * Returns:\n *     A UTF-32 string\n * See_Also:\n *     For a lazy, non-allocating version of these functions, see $(LREF byUTF).\n */\ndstring toUTF32(S)(S s)\nif (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S))\n{\n    return toUTFImpl!dstring(s);\n}\n\n///\n@safe pure unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // these graphemes are two code units in UTF-16 and one in UTF-32\n    assert(\"𤭢\"w.length == 2);\n    assert(\"𐐷\"w.length == 2);\n\n    assert(\"𤭢\"w.toUTF32.equal([0x00024B62]));\n    assert(\"𐐷\"w.toUTF32.equal([0x00010437]));\n}\n\nprivate T toUTFImpl(T, S)(S s)\n{\n    static if (is(S : T))\n    {\n        return s.idup;\n    }\n    else\n    {\n        import std.array : appender;\n        auto app = appender!T();\n\n        static if (hasLength!S || isSomeString!S)\n            app.reserve(s.length);\n\n        foreach (c; s.byUTF!(Unqual!(ElementEncodingType!T)))\n            app.put(c);\n\n        return app.data;\n    }\n}\n\n/* =================== toUTFz ======================= */\n\n/++\n    Returns a C-style zero-terminated string equivalent to `str`. `str`\n    must not contain embedded `'\\0'`'s as any C function will treat the first\n    `'\\0'` that it sees as the end of the string. If `str.empty` is\n    `true`, then a string containing only `'\\0'` is returned.\n\n    `toUTFz` accepts any type of string and is templated on the type of\n    character pointer that you wish to convert to. It will avoid allocating a\n    new string if it can, but there's a decent chance that it will end up having\n    to allocate a new string - particularly when dealing with character types\n    other than `char`.\n\n    $(RED Warning 1:) If the result of `toUTFz` equals `str.ptr`, then if\n    anything alters the character one past the end of `str` (which is the\n    `'\\0'` character terminating the string), then the string won't be\n    zero-terminated anymore. The most likely scenarios for that are if you\n    append to `str` and no reallocation takes place or when `str` is a\n    slice of a larger array, and you alter the character in the larger array\n    which is one character past the end of `str`. Another case where it could\n    occur would be if you had a mutable character array immediately after\n    `str` in memory (for example, if they're member variables in a\n    user-defined type with one declared right after the other) and that\n    character array happened to start with `'\\0'`. Such scenarios will never\n    occur if you immediately use the zero-terminated string after calling\n    `toUTFz` and the C function using it doesn't keep a reference to it.\n    Also, they are unlikely to occur even if you save the zero-terminated string\n    (the cases above would be among the few examples of where it could happen).\n    However, if you save the zero-terminate string and want to be absolutely\n    certain that the string stays zero-terminated, then simply append a\n    `'\\0'` to the string and use its `ptr` property rather than calling\n    `toUTFz`.\n\n    $(RED Warning 2:) When passing a character pointer to a C function, and the\n    C function keeps it around for any reason, make sure that you keep a\n    reference to it in your D code. Otherwise, it may go away during a garbage\n    collection cycle and cause a nasty bug when the C code tries to use it.\n  +/\ntemplate toUTFz(P)\n{\n    P toUTFz(S)(S str) @safe pure\n    {\n        return toUTFzImpl!(P, S)(str);\n    }\n}\n\n///\n@safe pure unittest\n{\n    auto p1 = toUTFz!(char*)(\"hello world\");\n    auto p2 = toUTFz!(const(char)*)(\"hello world\");\n    auto p3 = toUTFz!(immutable(char)*)(\"hello world\");\n    auto p4 = toUTFz!(char*)(\"hello world\"d);\n    auto p5 = toUTFz!(const(wchar)*)(\"hello world\");\n    auto p6 = toUTFz!(immutable(dchar)*)(\"hello world\"w);\n}\n\nprivate P toUTFzImpl(P, S)(S str) @safe pure\nif (isSomeString!S && isPointer!P && isSomeChar!(typeof(*P.init)) &&\n    is(Unqual!(typeof(*P.init)) == Unqual!(ElementEncodingType!S)) &&\n    is(immutable(Unqual!(ElementEncodingType!S)) == ElementEncodingType!S))\n//immutable(C)[] -> C*, const(C)*, or immutable(C)*\n{\n    if (str.empty)\n    {\n        typeof(*P.init)[] retval = ['\\0'];\n\n        auto trustedPtr() @trusted { return retval.ptr; }\n        return trustedPtr();\n    }\n\n    alias C = Unqual!(ElementEncodingType!S);\n\n    //If the P is mutable, then we have to make a copy.\n    static if (is(Unqual!(typeof(*P.init)) == typeof(*P.init)))\n    {\n        return toUTFzImpl!(P, const(C)[])(cast(const(C)[])str);\n    }\n    else\n    {\n        if (!__ctfe)\n        {\n            auto trustedPtrAdd(S s) @trusted { return s.ptr + s.length; }\n            immutable p = trustedPtrAdd(str);\n\n            // Peek past end of str, if it's 0, no conversion necessary.\n            // Note that the compiler will put a 0 past the end of static\n            // strings, and the storage allocator will put a 0 past the end\n            // of newly allocated char[]'s.\n            // Is p dereferenceable? A simple test: if the p points to an\n            // address multiple of 4, then conservatively assume the pointer\n            // might be pointing to a new block of memory, which might be\n            // unreadable. Otherwise, it's definitely pointing to valid\n            // memory.\n            if ((cast(size_t) p & 3) && *p == '\\0')\n                return &str[0];\n        }\n\n        return toUTFzImpl!(P, const(C)[])(cast(const(C)[])str);\n    }\n}\n\nprivate P toUTFzImpl(P, S)(S str) @safe pure\nif (isSomeString!S && isPointer!P && isSomeChar!(typeof(*P.init)) &&\n    is(Unqual!(typeof(*P.init)) == Unqual!(ElementEncodingType!S)) &&\n    !is(immutable(Unqual!(ElementEncodingType!S)) == ElementEncodingType!S))\n//C[] or const(C)[] -> C*, const(C)*, or immutable(C)*\n{\n    alias InChar  = ElementEncodingType!S;\n    alias OutChar = typeof(*P.init);\n\n    //const(C)[] -> const(C)* or\n    //C[] -> C* or const(C)*\n    static if (( is(const(Unqual!InChar) == InChar) &&  is(const(Unqual!OutChar) == OutChar)) ||\n               (!is(const(Unqual!InChar) == InChar) && !is(immutable(Unqual!OutChar) == OutChar)))\n    {\n        if (!__ctfe)\n        {\n            auto trustedPtrAdd(S s) @trusted { return s.ptr + s.length; }\n            auto p = trustedPtrAdd(str);\n\n            if ((cast(size_t) p & 3) && *p == '\\0')\n                return &str[0];\n        }\n\n        str ~= '\\0';\n        return &str[0];\n    }\n    //const(C)[] -> C* or immutable(C)* or\n    //C[] -> immutable(C)*\n    else\n    {\n        import std.array : uninitializedArray;\n        auto copy = uninitializedArray!(Unqual!OutChar[])(str.length + 1);\n        copy[0 .. $ - 1] = str[];\n        copy[$ - 1] = '\\0';\n\n        auto trustedCast(typeof(copy) c) @trusted { return cast(P) c.ptr; }\n        return trustedCast(copy);\n    }\n}\n\nprivate P toUTFzImpl(P, S)(S str) @safe pure\nif (isSomeString!S && isPointer!P && isSomeChar!(typeof(*P.init)) &&\n    !is(Unqual!(typeof(*P.init)) == Unqual!(ElementEncodingType!S)))\n//C1[], const(C1)[], or immutable(C1)[] -> C2*, const(C2)*, or immutable(C2)*\n{\n    import std.array : appender;\n    auto retval = appender!(typeof(*P.init)[])();\n\n    foreach (dchar c; str)\n        retval.put(c);\n    retval.put('\\0');\n\n    return () @trusted { return cast(P) retval.data.ptr; } ();\n}\n\n@safe pure unittest\n{\n    import core.exception : AssertError;\n    import std.algorithm;\n    import std.conv : to;\n    import std.exception;\n    import std.string : format;\n\n    assertCTFEable!(\n    {\n    foreach (S; AliasSeq!(string, wstring, dstring))\n    {\n        alias C = Unqual!(ElementEncodingType!S);\n\n        auto s1 = to!S(\"hello\\U00010143\\u0100\\U00010143\");\n        auto temp = new C[](s1.length + 1);\n        temp[0 .. $ - 1] = s1[0 .. $];\n        temp[$ - 1] = '\\n';\n        --temp.length;\n        auto trustedAssumeUnique(T)(T t) @trusted { return assumeUnique(t); }\n        auto s2 = trustedAssumeUnique(temp);\n        assert(s1 == s2);\n\n        void trustedCStringAssert(P, S)(S s) @trusted\n        {\n            auto p = toUTFz!P(s);\n            assert(p[0 .. s.length] == s);\n            assert(p[s.length] == '\\0');\n        }\n\n        foreach (P; AliasSeq!(C*, const(C)*, immutable(C)*))\n        {\n            trustedCStringAssert!P(s1);\n            trustedCStringAssert!P(s2);\n        }\n    }\n    });\n\n    static void test(P, S)(S s, size_t line = __LINE__) @trusted\n    {\n        static size_t zeroLen(C)(const(C)* ptr) @trusted\n        {\n            size_t len = 0;\n            while (*ptr != '\\0') { ++ptr; ++len; }\n            return len;\n        }\n\n        auto p = toUTFz!P(s);\n        immutable len = zeroLen(p);\n        enforce(cmp(s, p[0 .. len]) == 0,\n                new AssertError(format(\"Unit test failed: %s %s\", P.stringof, S.stringof),\n                                __FILE__, line));\n    }\n\n    assertCTFEable!(\n    {\n    foreach (P; AliasSeq!(wchar*, const(wchar)*, immutable(wchar)*,\n                          dchar*, const(dchar)*, immutable(dchar)*))\n    {\n        test!P(\"hello\\U00010143\\u0100\\U00010143\");\n    }\n    foreach (P; AliasSeq!( char*, const( char)*, immutable( char)*,\n                          dchar*, const(dchar)*, immutable(dchar)*))\n    {\n        test!P(\"hello\\U00010143\\u0100\\U00010143\"w);\n    }\n    foreach (P; AliasSeq!( char*, const( char)*, immutable( char)*,\n                          wchar*, const(wchar)*, immutable(wchar)*))\n    {\n        test!P(\"hello\\U00010143\\u0100\\U00010143\"d);\n    }\n    foreach (S; AliasSeq!( char[], const( char)[],\n                          wchar[], const(wchar)[],\n                          dchar[], const(dchar)[]))\n    {\n        auto s = to!S(\"hello\\U00010143\\u0100\\U00010143\");\n\n        foreach (P; AliasSeq!( char*, const( char)*, immutable( char)*,\n                              wchar*, const(wchar)*, immutable(wchar)*,\n                              dchar*, const(dchar)*, immutable(dchar)*))\n        {\n            test!P(s);\n        }\n    }\n    });\n}\n\n\n/++\n    `toUTF16z` is a convenience function for `toUTFz!(const(wchar)*)`.\n\n    Encodes string `s` into UTF-16 and returns the encoded string.\n    `toUTF16z` is suitable for calling the 'W' functions in the Win32 API\n    that take an `LPWSTR` or `LPCWSTR` argument.\n  +/\nconst(wchar)* toUTF16z(C)(const(C)[] str) @safe pure\nif (isSomeChar!C)\n{\n    return toUTFz!(const(wchar)*)(str);\n}\n\n///\n@system unittest\n{\n    string str = \"Hello, World!\";\n    const(wchar)* p = str.toUTF16z;\n    assert(p[str.length] == '\\0');\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    //toUTFz is already thoroughly tested, so this will just verify that\n    //toUTF16z compiles properly for the various string types.\n    foreach (S; AliasSeq!(string, wstring, dstring))\n        assert(toUTF16z(to!S(\"hello world\")) !is null);\n}\n\n\n/* ================================ tests ================================== */\n\n@safe pure unittest\n{\n    import std.exception;\n\n    assertCTFEable!(\n    {\n    assert(toUTF16(\"hello\"c) == \"hello\");\n    assert(toUTF32(\"hello\"c) == \"hello\");\n    assert(toUTF8 (\"hello\"w) == \"hello\");\n    assert(toUTF32(\"hello\"w) == \"hello\");\n    assert(toUTF8 (\"hello\"d) == \"hello\");\n    assert(toUTF16(\"hello\"d) == \"hello\");\n\n    assert(toUTF16(\"hel\\u1234o\"c) == \"hel\\u1234o\");\n    assert(toUTF32(\"hel\\u1234o\"c) == \"hel\\u1234o\");\n    assert(toUTF8 (\"hel\\u1234o\"w) == \"hel\\u1234o\");\n    assert(toUTF32(\"hel\\u1234o\"w) == \"hel\\u1234o\");\n    assert(toUTF8 (\"hel\\u1234o\"d) == \"hel\\u1234o\");\n    assert(toUTF16(\"hel\\u1234o\"d) == \"hel\\u1234o\");\n\n    assert(toUTF16(\"he\\U0010AAAAllo\"c) == \"he\\U0010AAAAllo\");\n    assert(toUTF32(\"he\\U0010AAAAllo\"c) == \"he\\U0010AAAAllo\");\n    assert(toUTF8 (\"he\\U0010AAAAllo\"w) == \"he\\U0010AAAAllo\");\n    assert(toUTF32(\"he\\U0010AAAAllo\"w) == \"he\\U0010AAAAllo\");\n    assert(toUTF8 (\"he\\U0010AAAAllo\"d) == \"he\\U0010AAAAllo\");\n    assert(toUTF16(\"he\\U0010AAAAllo\"d) == \"he\\U0010AAAAllo\");\n    });\n}\n\n\n/++\n    Returns the total number of code points encoded in `str`.\n\n    Supercedes: This function supercedes $(LREF toUCSindex).\n\n    Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252\n\n    Throws:\n        `UTFException` if `str` is not well-formed.\n  +/\nsize_t count(C)(const(C)[] str) @trusted pure nothrow @nogc\nif (isSomeChar!C)\n{\n    return walkLength(str);\n}\n\n///\n@safe pure nothrow @nogc unittest\n{\n    assert(count(\"\") == 0);\n    assert(count(\"a\") == 1);\n    assert(count(\"abc\") == 3);\n    assert(count(\"\\u20AC100\") == 4);\n}\n\n@safe pure nothrow @nogc unittest\n{\n    import std.exception;\n    assertCTFEable!(\n    {\n    assert(count(\"\") == 0);\n    assert(count(\"a\") == 1);\n    assert(count(\"abc\") == 3);\n    assert(count(\"\\u20AC100\") == 4);\n    });\n}\n\n\n// Ranges of code units for testing.\nversion (unittest)\n{\nprivate:\n    struct InputCU(C)\n    {\n        import std.conv : to;\n        @property bool empty() { return _str.empty; }\n        @property C front() { return _str[0]; }\n        void popFront() { _str = _str[1 .. $]; }\n\n        this(inout(C)[] str)\n        {\n            _str = to!(C[])(str);\n        }\n\n        C[] _str;\n    }\n\n    struct BidirCU(C)\n    {\n        import std.conv : to;\n        @property bool empty() { return _str.empty; }\n        @property C front() { return _str[0]; }\n        void popFront() { _str = _str[1 .. $]; }\n        @property C back() { return _str[$ - 1]; }\n        void popBack() { _str = _str[0 .. $ - 1]; }\n        @property auto save() { return BidirCU(_str); }\n        @property size_t length() { return _str.length; }\n\n        this(inout(C)[] str)\n        {\n            _str = to!(C[])(str);\n        }\n\n        C[] _str;\n    }\n\n    struct RandomCU(C)\n    {\n        import std.conv : to;\n        @property bool empty() { return _str.empty; }\n        @property C front() { return _str[0]; }\n        void popFront() { _str = _str[1 .. $]; }\n        @property C back() { return _str[$ - 1]; }\n        void popBack() { _str = _str[0 .. $ - 1]; }\n        @property auto save() { return RandomCU(_str); }\n        @property size_t length() { return _str.length; }\n        C opIndex(size_t i) { return _str[i]; }\n        auto opSlice(size_t i, size_t j) { return RandomCU(_str[i .. j]); }\n\n        this(inout(C)[] str)\n        {\n            _str = to!(C[])(str);\n        }\n\n        C[] _str;\n    }\n\n    class RefBidirCU(C)\n    {\n        import std.conv : to;\n        @property bool empty() { return _str.empty; }\n        @property C front() { return _str[0]; }\n        void popFront() { _str = _str[1 .. $]; }\n        @property C back() { return _str[$ - 1]; }\n        void popBack() { _str = _str[0 .. $ - 1]; }\n        @property auto save() { return new RefBidirCU(_str); }\n        @property size_t length() { return _str.length; }\n\n        this(inout(C)[] str)\n        {\n            _str = to!(C[])(str);\n        }\n\n        C[] _str;\n    }\n\n    class RefRandomCU(C)\n    {\n        import std.conv : to;\n        @property bool empty() { return _str.empty; }\n        @property C front() { return _str[0]; }\n        void popFront() { _str = _str[1 .. $]; }\n        @property C back() { return _str[$ - 1]; }\n        void popBack() { _str = _str[0 .. $ - 1]; }\n        @property auto save() { return new RefRandomCU(_str); }\n        @property size_t length() { return _str.length; }\n        C opIndex(size_t i) { return _str[i]; }\n        auto opSlice(size_t i, size_t j) { return new RefRandomCU(_str[i .. j]); }\n\n        this(inout(C)[] str)\n        {\n            _str = to!(C[])(str);\n        }\n\n        C[] _str;\n    }\n}\n\n\n/**\n * Inserted in place of invalid UTF sequences.\n *\n * References:\n *      $(LINK http://en.wikipedia.org/wiki/Replacement_character#Replacement_character)\n */\nenum dchar replacementDchar = '\\uFFFD';\n\n/********************************************\n * Iterate a range of char, wchar, or dchars by code unit.\n *\n * The purpose is to bypass the special case decoding that\n * $(REF front, std,range,primitives) does to character arrays. As a result,\n * using ranges with `byCodeUnit` can be `nothrow` while\n * $(REF front, std,range,primitives) throws when it encounters invalid Unicode\n * sequences.\n *\n * A code unit is a building block of the UTF encodings. Generally, an\n * individual code unit does not represent what's perceived as a full\n * character (a.k.a. a grapheme cluster in Unicode terminology). Many characters\n * are encoded with multiple code units. For example, the UTF-8 code units for\n * `ø` are `0xC3 0xB8`. That means, an individual element of `byCodeUnit`\n * often does not form a character on its own. Attempting to treat it as\n * one while iterating over the resulting range will give nonsensical results.\n *\n * Params:\n *      r = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n *      of characters (including strings) or a type that implicitly converts to a string type.\n * Returns:\n *      If `r` is not an auto-decodable string (i.e. a narrow string or a\n *      user-defined type that implicits converts to a string type), then `r`\n *      is returned.\n *\n *      Otherwise, `r` is converted to its corresponding string type (if it's\n *      not already a string) and wrapped in a random-access range where the\n *      element encoding type of the string (its code unit) is the element type\n *      of the range, and that range returned. The range has slicing.\n *\n *      If `r` is quirky enough to be a struct or class which is an input range\n *      of characters on its own (i.e. it has the input range API as member\n *      functions), $(I and) it's implicitly convertible to a string type, then\n *      `r` is returned, and no implicit conversion takes place.\n *\n *      If `r` is wrapped in a new range, then that range has a `source`\n *      property for returning the string that's currently contained within that\n *      range.\n *\n * See_Also:\n *      Refer to the $(MREF std, uni) docs for a reference on Unicode\n *      terminology.\n *\n *      For a range that iterates by grapheme cluster (written character) see\n *      $(REF byGrapheme, std,uni).\n */\nauto byCodeUnit(R)(R r)\nif (isAutodecodableString!R ||\n    isInputRange!R && isSomeChar!(ElementEncodingType!R) ||\n    (is(R : const dchar[]) && !isStaticArray!R))\n{\n    static if (isNarrowString!R ||\n               // This would be cleaner if we had a way to check whether a type\n               // was a range without any implicit conversions.\n               (isAutodecodableString!R && !__traits(hasMember, R, \"empty\") &&\n                !__traits(hasMember, R, \"front\") && !__traits(hasMember, R, \"popFront\")))\n    {\n        static struct ByCodeUnitImpl\n        {\n        @safe pure nothrow @nogc:\n\n            @property bool empty() const     { return source.length == 0; }\n            @property auto ref front() inout { return source[0]; }\n            void popFront()                  { source = source[1 .. $]; }\n\n            @property auto save() { return ByCodeUnitImpl(source.save); }\n\n            @property auto ref back() inout { return source[$ - 1]; }\n            void popBack()                  { source = source[0 .. $-1]; }\n\n            auto ref opIndex(size_t index) inout     { return source[index]; }\n            auto opSlice(size_t lower, size_t upper) { return ByCodeUnitImpl(source[lower .. upper]); }\n\n            @property size_t length() const { return source.length; }\n            alias opDollar = length;\n\n            StringTypeOf!R source;\n        }\n\n        static assert(isRandomAccessRange!ByCodeUnitImpl);\n\n        return ByCodeUnitImpl(r);\n    }\n    else static if (is(R : const dchar[]) && !__traits(hasMember, R, \"empty\") &&\n                    !__traits(hasMember, R, \"front\") && !__traits(hasMember, R, \"popFront\"))\n    {\n        return cast(StringTypeOf!R) r;\n    }\n    else\n    {\n        // byCodeUnit for ranges and dchar[] is a no-op\n        return r;\n    }\n}\n\n///\n@safe unittest\n{\n    import std.range.primitives;\n\n    auto r = \"Hello, World!\".byCodeUnit();\n    static assert(hasLength!(typeof(r)));\n    static assert(hasSlicing!(typeof(r)));\n    static assert(isRandomAccessRange!(typeof(r)));\n    static assert(is(ElementType!(typeof(r)) == immutable char));\n\n    // contrast with the range capabilities of standard strings\n    auto s = \"Hello, World!\";\n    static assert(isBidirectionalRange!(typeof(r)));\n    static assert(is(ElementType!(typeof(s)) == dchar));\n\n    static assert(!isRandomAccessRange!(typeof(s)));\n    static assert(!hasSlicing!(typeof(s)));\n    static assert(!hasLength!(typeof(s)));\n}\n\n/// `byCodeUnit` does no Unicode decoding\n@safe unittest\n{\n    string noel1 = \"noe\\u0308l\"; // noël using e + combining diaeresis\n    assert(noel1.byCodeUnit[2] != 'ë');\n    assert(noel1.byCodeUnit[2] == 'e');\n\n    string noel2 = \"no\\u00EBl\"; // noël using a precomposed ë character\n    // Because string is UTF-8, the code unit at index 2 is just\n    // the first of a sequence that encodes 'ë'\n    assert(noel2.byCodeUnit[2] != 'ë');\n}\n\n/// `byCodeUnit` exposes a `source` property when wrapping narrow strings.\n@safe unittest\n{\n    import std.algorithm.comparison : equal;\n    import std.range : popFrontN;\n    {\n        auto range = byCodeUnit(\"hello world\");\n        range.popFrontN(3);\n        assert(equal(range.save, \"lo world\"));\n        string str = range.source;\n        assert(str == \"lo world\");\n    }\n    // source only exists if the range was wrapped\n    {\n        auto range = byCodeUnit(\"hello world\"d);\n        static assert(!__traits(compiles, range.source));\n    }\n}\n\n@safe pure nothrow @nogc unittest\n{\n    import std.range;\n    {\n        enum testStr = \"𐁄𐂌𐃯 hello ディラン\";\n        char[testStr.length] s;\n        int i;\n        foreach (c; testStr.byCodeUnit().byCodeUnit())\n        {\n            s[i++] = c;\n        }\n        assert(s == testStr);\n    }\n    {\n        enum testStr = \"𐁄𐂌𐃯 hello ディラン\"w;\n        wchar[testStr.length] s;\n        int i;\n        foreach (c; testStr.byCodeUnit().byCodeUnit())\n        {\n            s[i++] = c;\n        }\n        assert(s == testStr);\n    }\n    {\n        enum testStr = \"𐁄𐂌𐃯 hello ディラン\"d;\n        dchar[testStr.length] s;\n        int i;\n        foreach (c; testStr.byCodeUnit().byCodeUnit())\n        {\n            s[i++] = c;\n        }\n        assert(s == testStr);\n    }\n    {\n        auto bcu = \"hello\".byCodeUnit();\n        assert(bcu.length == 5);\n        assert(bcu[3] == 'l');\n        assert(bcu[2 .. 4][1] == 'l');\n    }\n    {\n        char[5] orig = \"hello\";\n        auto bcu = orig[].byCodeUnit();\n        bcu.front = 'H';\n        assert(bcu.front == 'H');\n        bcu[1] = 'E';\n        assert(bcu[1] == 'E');\n    }\n    {\n        auto bcu = \"hello\".byCodeUnit().byCodeUnit();\n        static assert(isForwardRange!(typeof(bcu)));\n        static assert(is(typeof(bcu) == struct));\n        auto s = bcu.save;\n        bcu.popFront();\n        assert(s.front == 'h');\n    }\n    {\n        auto bcu = \"hello\".byCodeUnit();\n        static assert(hasSlicing!(typeof(bcu)));\n        static assert(isBidirectionalRange!(typeof(bcu)));\n        static assert(is(typeof(bcu) == struct));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        auto ret = bcu.retro;\n        assert(ret.front == 'o');\n        ret.popFront();\n        assert(ret.front == 'l');\n    }\n    {\n        auto bcu = \"κόσμε\"w.byCodeUnit();\n        static assert(hasSlicing!(typeof(bcu)));\n        static assert(isBidirectionalRange!(typeof(bcu)));\n        static assert(is(typeof(bcu) == struct));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        auto ret = bcu.retro;\n        assert(ret.front == 'ε');\n        ret.popFront();\n        assert(ret.front == 'μ');\n    }\n    {\n        static struct Stringish\n        {\n            string s;\n            alias s this;\n        }\n\n        auto orig = Stringish(\"\\U0010fff8 𐁊 foo 𐂓\");\n        auto bcu = orig.byCodeUnit();\n        static assert(is(typeof(bcu) == struct));\n        static assert(!is(typeof(bcu) == Stringish));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        static assert(is(ElementType!(typeof(bcu)) == immutable char));\n        assert(bcu.front == cast(char) 244);\n    }\n    {\n        static struct WStringish\n        {\n            wstring s;\n            alias s this;\n        }\n\n        auto orig = WStringish(\"\\U0010fff8 𐁊 foo 𐂓\"w);\n        auto bcu = orig.byCodeUnit();\n        static assert(is(typeof(bcu) == struct));\n        static assert(!is(typeof(bcu) == WStringish));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        static assert(is(ElementType!(typeof(bcu)) == immutable wchar));\n        assert(bcu.front == cast(wchar) 56319);\n    }\n    {\n        static struct DStringish\n        {\n            dstring s;\n            alias s this;\n        }\n\n        auto orig = DStringish(\"\\U0010fff8 𐁊 foo 𐂓\"d);\n        auto bcu = orig.byCodeUnit();\n        static assert(is(typeof(bcu) == dstring));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        static assert(is(ElementType!(typeof(bcu)) == immutable dchar));\n        assert(bcu.front == cast(dchar) 1114104);\n    }\n    {\n        static struct FuncStringish\n        {\n            string str;\n            string s() pure nothrow @nogc { return str; }\n            alias s this;\n        }\n\n        auto orig = FuncStringish(\"\\U0010fff8 𐁊 foo 𐂓\");\n        auto bcu = orig.byCodeUnit();\n        static assert(is(typeof(bcu) == struct));\n        static assert(!is(typeof(bcu) == FuncStringish));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        static assert(is(ElementType!(typeof(bcu)) == immutable char));\n        assert(bcu.front == cast(char) 244);\n    }\n    {\n        static struct Range\n        {\n            string data;\n            bool empty() pure nothrow @nogc { return data.empty; }\n            char front() pure nothrow @nogc { return data[0]; }\n            void popFront() pure nothrow @nogc { data = data[1 .. $]; }\n        }\n\n        auto orig = Range(\"\\U0010fff8 𐁊 foo 𐂓\");\n        auto bcu = orig.byCodeUnit();\n        static assert(is(typeof(bcu) == Range));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        static assert(is(ElementType!(typeof(bcu)) == char));\n        assert(bcu.front == cast(char) 244);\n    }\n    {\n        static struct WRange\n        {\n            wstring data;\n            bool empty() pure nothrow @nogc { return data.empty; }\n            wchar front() pure nothrow @nogc { return data[0]; }\n            void popFront() pure nothrow @nogc { data = data[1 .. $]; }\n        }\n\n        auto orig = WRange(\"\\U0010fff8 𐁊 foo 𐂓\"w);\n        auto bcu = orig.byCodeUnit();\n        static assert(is(typeof(bcu) == WRange));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        static assert(is(ElementType!(typeof(bcu)) == wchar));\n        assert(bcu.front == 56319);\n    }\n    {\n        static struct DRange\n        {\n            dstring data;\n            bool empty() pure nothrow @nogc { return data.empty; }\n            dchar front() pure nothrow @nogc { return data[0]; }\n            void popFront() pure nothrow @nogc { data = data[1 .. $]; }\n        }\n\n        auto orig = DRange(\"\\U0010fff8 𐁊 foo 𐂓\"d);\n        auto bcu = orig.byCodeUnit();\n        static assert(is(typeof(bcu) == DRange));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        static assert(is(ElementType!(typeof(bcu)) == dchar));\n        assert(bcu.front == 1114104);\n    }\n    {\n        static struct RangeAndStringish\n        {\n            bool empty() pure nothrow @nogc { return data.empty; }\n            char front() pure nothrow @nogc { return data[0]; }\n            void popFront() pure nothrow @nogc { data = data[1 .. $]; }\n\n            string data;\n            string s;\n            alias s this;\n        }\n\n        auto orig = RangeAndStringish(\"test.d\", \"other\");\n        auto bcu = orig.byCodeUnit();\n        static assert(is(typeof(bcu) == RangeAndStringish));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        static assert(is(ElementType!(typeof(bcu)) == char));\n        assert(bcu.front == 't');\n    }\n    {\n        static struct WRangeAndStringish\n        {\n            bool empty() pure nothrow @nogc { return data.empty; }\n            wchar front() pure nothrow @nogc { return data[0]; }\n            void popFront() pure nothrow @nogc { data = data[1 .. $]; }\n\n            wstring data;\n            wstring s;\n            alias s this;\n        }\n\n        auto orig = WRangeAndStringish(\"test.d\"w, \"other\"w);\n        auto bcu = orig.byCodeUnit();\n        static assert(is(typeof(bcu) == WRangeAndStringish));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        static assert(is(ElementType!(typeof(bcu)) == wchar));\n        assert(bcu.front == 't');\n    }\n    {\n        static struct DRangeAndStringish\n        {\n            bool empty() pure nothrow @nogc { return data.empty; }\n            dchar front() pure nothrow @nogc { return data[0]; }\n            void popFront() pure nothrow @nogc { data = data[1 .. $]; }\n\n            dstring data;\n            dstring s;\n            alias s this;\n        }\n\n        auto orig = DRangeAndStringish(\"test.d\"d, \"other\"d);\n        auto bcu = orig.byCodeUnit();\n        static assert(is(typeof(bcu) == DRangeAndStringish));\n        static assert(is(typeof(bcu) == typeof(bcu.byCodeUnit())));\n        static assert(is(ElementType!(typeof(bcu)) == dchar));\n        assert(bcu.front == 't');\n    }\n    {\n        enum Enum : string { a = \"test.d\" }\n\n        auto orig = Enum.a;\n        auto bcu = orig.byCodeUnit();\n        static assert(!is(typeof(bcu) == Enum));\n        static assert(is(typeof(bcu) == struct));\n        static assert(is(ElementType!(typeof(bcu)) == immutable char));\n        assert(bcu.front == 't');\n    }\n    {\n        enum WEnum : wstring { a = \"test.d\"w }\n\n        auto orig = WEnum.a;\n        auto bcu = orig.byCodeUnit();\n        static assert(!is(typeof(bcu) == WEnum));\n        static assert(is(typeof(bcu) == struct));\n        static assert(is(ElementType!(typeof(bcu)) == immutable wchar));\n        assert(bcu.front == 't');\n    }\n    {\n        enum DEnum : dstring { a = \"test.d\"d }\n\n        auto orig = DEnum.a;\n        auto bcu = orig.byCodeUnit();\n        static assert(is(typeof(bcu) == dstring));\n        static assert(is(ElementType!(typeof(bcu)) == immutable dchar));\n        assert(bcu.front == 't');\n    }\n\n    static assert(!is(typeof(byCodeUnit(\"hello\")) == string));\n    static assert(!is(typeof(byCodeUnit(\"hello\"w)) == wstring));\n    static assert(is(typeof(byCodeUnit(\"hello\"d)) == dstring));\n\n    static assert(!__traits(compiles, byCodeUnit((char[5]).init)));\n    static assert(!__traits(compiles, byCodeUnit((wchar[5]).init)));\n    static assert(!__traits(compiles, byCodeUnit((dchar[5]).init)));\n\n    enum SEnum : char[5] { a = \"hello\" }\n    enum WSEnum : wchar[5] { a = \"hello\"w }\n    enum DSEnum : dchar[5] { a = \"hello\"d }\n\n    static assert(!__traits(compiles, byCodeUnit(SEnum.a)));\n    static assert(!__traits(compiles, byCodeUnit(WSEnum.a)));\n    static assert(!__traits(compiles, byCodeUnit(DSEnum.a)));\n}\n\n/****************************\n * Iterate an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n * of characters by char, wchar, or dchar.\n * These aliases simply forward to $(LREF byUTF) with the\n * corresponding C argument.\n *\n * Params:\n *      r = input range of characters, or array of characters\n */\nalias byChar = byUTF!char;\n\n/// Ditto\nalias byWchar = byUTF!wchar;\n\n/// Ditto\nalias byDchar = byUTF!dchar;\n\n@safe pure nothrow @nogc unittest\n{\n  {\n    char[5] s;\n    int i;\n    foreach (c; \"hello\".byChar.byChar())\n    {\n        //writefln(\"[%d] '%c'\", i, c);\n        s[i++] = c;\n    }\n    assert(s == \"hello\");\n  }\n  {\n    char[5+2+3+4+3+3] s;\n    int i;\n    dchar[10] a;\n    a[0 .. 8] = \"hello\\u07FF\\uD7FF\\U0010FFFF\"d;\n    a[8] = 0xD800;   // invalid\n    a[9] = cast(dchar) 0x110000; // invalid\n    foreach (c; a[].byChar())\n    {\n        //writefln(\"[%d] '%c'\", i, c);\n        s[i++] = c;\n    }\n    assert(s == \"hello\\u07FF\\uD7FF\\U0010FFFF\\uFFFD\\uFFFD\");\n  }\n  {\n    auto r = \"hello\"w.byChar();\n    r.popFront();\n    r.popFront();\n    assert(r.front == 'l');\n  }\n  {\n    auto r = \"hello\"d.byChar();\n    r.popFront();\n    r.popFront();\n    assert(r.front == 'l');\n  }\n  {\n    auto r = \"hello\"d.byChar();\n    assert(isForwardRange!(typeof(r)));\n    auto s = r.save;\n    r.popFront();\n    assert(s.front == 'h');\n  }\n}\n\n@safe pure nothrow @nogc unittest\n{\n  {\n    wchar[11] s;\n    int i;\n    dchar[10] a;\n    a[0 .. 8] = \"hello\\u07FF\\uD7FF\\U0010FFFF\"d;\n    a[8] = 0xD800;   // invalid\n    a[9] = cast(dchar) 0x110000; // invalid\n    foreach (c; a[].byWchar())\n    {\n        //writefln(\"[%d] '%c' x%x\", i, c, c);\n        s[i++] = c;\n    }\n    foreach (j, wchar c; \"hello\\u07FF\\uD7FF\\U0010FFFF\\uFFFD\\uFFFD\"w)\n    {\n        //writefln(\"[%d] '%c' x%x\", j, c, c);\n    }\n    assert(s == \"hello\\u07FF\\uD7FF\\U0010FFFF\\uFFFD\\uFFFD\"w);\n  }\n\n  {\n    auto r = \"hello\".byWchar();\n    r.popFront();\n    r.popFront();\n    assert(r.front == 'l');\n  }\n  {\n    auto r = \"hello\"d.byWchar();\n    r.popFront();\n    r.popFront();\n    assert(r.front == 'l');\n  }\n  {\n    auto r = \"hello\"d.byWchar();\n    assert(isForwardRange!(typeof(r)));\n    auto s = r.save;\n    r.popFront();\n    assert(s.front == 'h');\n  }\n}\n\n@safe pure nothrow @nogc unittest\n{\n  {\n    dchar[9] s;\n    int i;\n    string a = \"hello\\u07FF\\uD7FF\\U00010000\\U0010FFFF\"; // 1,2,3,4 byte sequences\n    foreach (c; a.byDchar())\n    {\n        s[i++] = c;\n    }\n    assert(s == \"hello\\u07FF\\uD7FF\\U00010000\\U0010FFFF\"d);\n  }\n  {\n    foreach (s; invalidUTFstrings!char())\n    {\n        auto r = s.byDchar();\n        assert(!r.empty);\n        assert(r.front == r.front);\n        dchar c = r.front;\n        assert(c == replacementDchar);\n    }\n  }\n  {\n    auto r = \"hello\".byDchar();\n    r.popFront();\n    r.popFront();\n    assert(r.front == 'l');\n  }\n\n  {\n    dchar[8] s;\n    int i;\n    wstring a = \"hello\\u07FF\\uD7FF\\U0010FFFF\"w;\n    foreach (c; a.byDchar())\n    {\n        //writefln(\"[%d] '%c' x%x\", i, c, c);\n        s[i++] = c;\n    }\n    assert(s == \"hello\\u07FF\\uD7FF\\U0010FFFF\"d);\n  }\n  {\n    foreach (s; invalidUTFstrings!wchar())\n    {\n        auto r = s.byDchar();\n        assert(!r.empty);\n        assert(r.front == r.front);\n        dchar c = r.front;\n        assert(c == replacementDchar);\n    }\n  }\n  {\n    wchar[2] ws;\n    ws[0] = 0xD800;\n    ws[1] = 0xDD00;             // correct surrogate pair\n    auto r = ws[].byDchar();\n    assert(!r.empty);\n    assert(r.front == r.front);\n    dchar c = r.front;\n    assert(c == '\\U00010100');\n  }\n  {\n    auto r = \"hello\"w.byDchar();\n    r.popFront();\n    r.popFront();\n    assert(r.front == 'l');\n  }\n\n  {\n    dchar[5] s;\n    int i;\n    dstring a = \"hello\"d;\n    foreach (c; a.byDchar.byDchar())\n    {\n        //writefln(\"[%d] '%c' x%x\", i, c, c);\n        s[i++] = c;\n    }\n    assert(s == \"hello\"d);\n  }\n  {\n    auto r = \"hello\".byDchar();\n    assert(isForwardRange!(typeof(r)));\n    auto s = r.save;\n    r.popFront();\n    assert(s.front == 'h');\n  }\n  {\n    auto r = \"hello\"w.byDchar();\n    assert(isForwardRange!(typeof(r)));\n    auto s = r.save;\n    r.popFront();\n    assert(s.front == 'h');\n  }\n}\n\n// test pure, @safe, nothrow, @nogc correctness of byChar/byWchar/byDchar,\n// which needs to support ranges with and without those attributes\n\npure @safe nothrow @nogc unittest\n{\n    dchar[5] s = \"hello\"d;\n    foreach (c; s[].byChar())  { }\n    foreach (c; s[].byWchar()) { }\n    foreach (c; s[].byDchar()) { }\n}\n\nversion (unittest)\nprivate int impureVariable;\n\n@system unittest\n{\n    static struct ImpureThrowingSystemRange(Char)\n    {\n        @property bool empty() const { return true; }\n        @property Char front() const { return Char.init; }\n        void popFront()\n        {\n            impureVariable++;\n            throw new Exception(\"only for testing nothrow\");\n        }\n    }\n\n    foreach (Char; AliasSeq!(char, wchar, dchar))\n    {\n        ImpureThrowingSystemRange!Char range;\n        foreach (c; range.byChar())  { }\n        foreach (c; range.byWchar()) { }\n        foreach (c; range.byDchar()) { }\n    }\n}\n\n/****************************\n * Iterate an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)\n * of characters by char type `C` by encoding the elements of the range.\n *\n * UTF sequences that cannot be converted to the specified encoding are\n * replaced by U+FFFD per \"5.22 Best Practice for U+FFFD Substitution\"\n * of the Unicode Standard 6.2. Hence byUTF is not symmetric.\n * This algorithm is lazy, and does not allocate memory.\n * `@nogc`, `pure`-ity, `nothrow`, and `@safe`-ty are inferred from the\n * `r` parameter.\n *\n * Params:\n *      C = `char`, `wchar`, or `dchar`\n *\n * Returns:\n *      A forward range if `R` is a range and not auto-decodable, as defined by\n *      $(REF isAutodecodableString, std, traits), and if the base range is\n *      also a forward range.\n *\n *      Or, if `R` is a range and it is auto-decodable and\n *      `is(ElementEncodingType!typeof(r) == C)`, then the range is passed\n *      to $(LREF byCodeUnit).\n *\n *      Otherwise, an input range of characters.\n */\ntemplate byUTF(C)\nif (isSomeChar!C)\n{\n    static if (!is(Unqual!C == C))\n        alias byUTF = byUTF!(Unqual!C);\n    else:\n\n    auto ref byUTF(R)(R r)\n        if (isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))\n    {\n        return byUTF(r.byCodeUnit());\n    }\n\n    auto ref byUTF(R)(R r)\n        if (!isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R))\n    {\n        alias RC = Unqual!(ElementEncodingType!R);\n\n        static if (is(RC == C))\n        {\n            return r.byCodeUnit();\n        }\n        else static if (is(C == dchar))\n        {\n            static struct Result\n            {\n                this(R val)\n                {\n                    r = val;\n                    popFront();\n                }\n\n                @property bool empty()\n                {\n                    return buff == uint.max;\n                }\n\n                @property auto front()\n                {\n                    assert(!empty, \"Attempting to access the front of an empty byUTF\");\n                    return cast(dchar) buff;\n                }\n\n                void popFront() scope\n                {\n                    assert(!empty, \"Attempting to popFront an empty byUTF\");\n                    if (r.empty)\n                    {\n                        buff = uint.max;\n                    }\n                    else\n                    {\n                        static if (is(RC == wchar))\n                            enum firstMulti = 0xD800; // First high surrogate.\n                        else\n                            enum firstMulti = 0x80; // First non-ASCII.\n                        if (r.front < firstMulti)\n                        {\n                            buff = r.front;\n                            r.popFront;\n                        }\n                        else\n                        {\n                            buff = () @trusted { return decodeFront!(Yes.useReplacementDchar)(r); }();\n                        }\n                    }\n                }\n\n                static if (isForwardRange!R)\n                {\n                    @property auto save() return scope\n                    {\n                        auto ret = this;\n                        ret.r = r.save;\n                        return ret;\n                    }\n                }\n\n                uint buff;\n                R r;\n            }\n\n            return Result(r);\n        }\n        else\n        {\n            static struct Result\n            {\n                @property bool empty()\n                {\n                    return pos == fill && r.empty;\n                }\n\n                @property auto front() scope // 'scope' required by call to decodeFront() below\n                {\n                    if (pos == fill)\n                    {\n                        pos = 0;\n                        auto c = r.front;\n\n                        static if (C.sizeof >= 2 && RC.sizeof >= 2)\n                            enum firstMulti = 0xD800; // First high surrogate.\n                        else\n                            enum firstMulti = 0x80; // First non-ASCII.\n                        if (c < firstMulti)\n                        {\n                            fill = 1;\n                            r.popFront;\n                            buf[pos] = cast(C) c;\n                        }\n                        else\n                        {\n                            static if (is(RC == dchar))\n                            {\n                                r.popFront;\n                                dchar dc = c;\n                            }\n                            else\n                                dchar dc = () @trusted { return decodeFront!(Yes.useReplacementDchar)(r); }();\n                            fill = cast(ushort) encode!(Yes.useReplacementDchar)(buf, dc);\n                        }\n                    }\n                    return buf[pos];\n                }\n\n                void popFront()\n                {\n                    if (pos == fill)\n                        front;\n                    ++pos;\n                }\n\n                static if (isForwardRange!R)\n                {\n                    @property auto save() return scope\n                    /* `return scope` cannot be inferred because compiler does not\n                     * track it backwards from assignment to local `ret`\n                     */\n                    {\n                        auto ret = this;\n                        ret.r = r.save;\n                        return ret;\n                    }\n                }\n\n            private:\n\n                R r;\n                C[4 / C.sizeof] buf = void;\n                ushort pos, fill;\n            }\n\n            return Result(r);\n        }\n    }\n}\n\n///\n@safe pure nothrow unittest\n{\n    import std.algorithm.comparison : equal;\n\n    // hellö as a range of `char`s, which are UTF-8\n    \"hell\\u00F6\".byUTF!char().equal(['h', 'e', 'l', 'l', 0xC3, 0xB6]);\n\n    // `wchar`s are able to hold the ö in a single element (UTF-16 code unit)\n    \"hell\\u00F6\".byUTF!wchar().equal(['h', 'e', 'l', 'l', 'ö']);\n\n    // 𐐷 is four code units in UTF-8, two in UTF-16, and one in UTF-32\n    \"𐐷\".byUTF!char().equal([0xF0, 0x90, 0x90, 0xB7]);\n    \"𐐷\".byUTF!wchar().equal([0xD801, 0xDC37]);\n    \"𐐷\".byUTF!dchar().equal([0x00010437]);\n}\n"
  },
  {
    "path": "libphobos/src/std/uuid.d",
    "content": "/**\n * A $(LINK2 http://en.wikipedia.org/wiki/Universally_unique_identifier, UUID), or\n * $(LINK2 http://en.wikipedia.org/wiki/Universally_unique_identifier, Universally unique identifier),\n * is intended to uniquely identify information in a distributed environment\n * without significant central coordination. It can be\n * used to tag objects with very short lifetimes, or to reliably identify very\n * persistent objects across a network.\n *\n$(SCRIPT inhibitQuickIndex = 1;)\n\n$(DIVC quickindex,\n$(BOOKTABLE ,\n$(TR $(TH Category) $(TH Functions)\n)\n$(TR $(TDNW Parsing UUIDs)\n     $(TD $(MYREF parseUUID)\n          $(MYREF UUID)\n          $(MYREF UUIDParsingException)\n          $(MYREF uuidRegex)\n          )\n     )\n$(TR $(TDNW Generating UUIDs)\n     $(TD $(MYREF sha1UUID)\n          $(MYREF randomUUID)\n          $(MYREF md5UUID)\n          )\n     )\n$(TR $(TDNW Using UUIDs)\n     $(TD $(MYREF2 UUID.uuidVersion, uuidVersion)\n          $(MYREF2 UUID.variant, variant)\n          $(MYREF2 UUID.toString, toString)\n          $(MYREF2 UUID.data, data)\n          $(MYREF2 UUID.swap, swap)\n          $(MYREF2 UUID.opEquals, opEquals)\n          $(MYREF2 UUID.opCmp, opCmp)\n          $(MYREF2 UUID.toHash, toHash)\n          )\n     )\n$(TR $(TDNW UUID namespaces)\n     $(TD $(MYREF dnsNamespace)\n          $(MYREF urlNamespace)\n          $(MYREF oidNamespace)\n          $(MYREF x500Namespace)\n          )\n     )\n)\n)\n\n * UUIDs have many applications. Some examples follow: Databases may use UUIDs to identify\n * rows or records in order to ensure that they are unique across different\n * databases, or for publication/subscription services. Network messages may be\n * identified with a UUID to ensure that different parts of a message are put back together\n * again. Distributed computing may use UUIDs to identify a remote procedure call.\n * Transactions and classes involved in serialization may be identified by UUIDs.\n * Microsoft's component object model (COM) uses UUIDs to distinguish different software\n * component interfaces. UUIDs are inserted into documents from Microsoft Office programs.\n * UUIDs identify audio or video streams in the Advanced Systems Format (ASF). UUIDs are\n * also a basis for OIDs (object identifiers), and URNs (uniform resource name).\n *\n * An attractive feature of UUIDs when compared to alternatives is their relative small size,\n * of 128 bits, or 16 bytes. Another is that the creation of UUIDs does not require\n * a centralized authority.\n *\n * When UUIDs are generated by one of the defined mechanisms, they are either guaranteed\n * to be unique, different from all other generated UUIDs (that is, it has never been\n * generated before and it will never be generated again), or it is extremely likely\n * to be unique (depending on the mechanism).\n *\n * For efficiency, UUID is implemented as a struct. UUIDs are therefore empty if not explicitly\n * initialized. An UUID is empty if $(MYREF3 UUID.empty, empty) is true. Empty UUIDs are equal to\n * `UUID.init`, which is a UUID with all 16 bytes set to 0.\n * Use UUID's constructors or the UUID generator functions to get an initialized UUID.\n *\n * This is a port of $(LINK2 http://www.boost.org/doc/libs/1_42_0/libs/uuid/uuid.html,\n * boost.uuid) from the Boost project with some minor additions and API\n * changes for a more D-like API.\n *\n * Standards:\n * $(LINK2 http://www.ietf.org/rfc/rfc4122.txt, RFC 4122)\n *\n * See_Also:\n * $(LINK http://en.wikipedia.org/wiki/Universally_unique_identifier)\n *\n * Copyright: Copyright Johannes Pfau 2011 - .\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   Johannes Pfau\n * Source:    $(PHOBOSSRC std/uuid.d)\n *\n * Macros:\n * MYREF2 = <a href=\"#$2\">$(TT $1)</a>&nbsp;\n * MYREF3 = <a href=\"#$2\">`$1`</a>\n */\n/*          Copyright Johannes Pfau 2011 - 2012.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.uuid;\n\n///\n@safe unittest\n{\n    import std.uuid;\n\n    UUID[] ids;\n    ids ~= randomUUID();\n    ids ~= md5UUID(\"test.name.123\");\n    ids ~= sha1UUID(\"test.name.123\");\n\n    foreach (entry; ids)\n    {\n        assert(entry.variant == UUID.Variant.rfc4122);\n    }\n    assert(ids[0].uuidVersion == UUID.Version.randomNumberBased);\n    assert(ids[1].toString() == \"22390768-cced-325f-8f0f-cfeaa19d0ccd\");\n    assert(ids[1].data == [34, 57, 7, 104, 204, 237, 50, 95, 143, 15, 207,\n        234, 161, 157, 12, 205]);\n    UUID id;\n    assert(id.empty);\n}\n\nimport std.range.primitives;\nimport std.traits;\n\n/**\n *\n */\npublic struct UUID\n{\n    import std.meta : AliasSeq, allSatisfy;\n\n    private:\n        alias skipSeq = AliasSeq!(8, 13, 18, 23);\n        alias byteSeq = AliasSeq!(0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34);\n\n        @safe pure nothrow @nogc Char toChar(Char)(size_t i) const\n        {\n            if (i <= 9)\n                return cast(Char)('0' + i);\n            else\n                return cast(Char)('a' + (i-10));\n        }\n\n        @safe pure nothrow unittest\n        {\n            assert(UUID(cast(ubyte[16])[138, 179, 6, 14, 44, 186, 79, 35, 183, 76, 181, 45,\n                179, 189, 251, 70]).toString() == \"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\");\n        }\n\n        // Reinterpret the UUID as an array of some other primitive.\n        @trusted ref T[16 / T.sizeof] asArrayOf(T)() return\n        if (isIntegral!T)\n        {\n            return *cast(typeof(return)*)&data;\n        }\n\n    public:\n        /**\n         * RFC 4122 defines different internal data layouts for UUIDs. These are\n         * the UUID formats supported by this module. It's\n         * possible to read, compare and use all these Variants, but\n         * UUIDs generated by this module will always be in rfc4122 format.\n         *\n         * Note: Do not confuse this with $(REF _Variant, std,_variant).\n         */\n        enum Variant\n        {\n            ncs, /// NCS backward compatibility\n            rfc4122, /// Defined in RFC 4122 document\n            microsoft, /// Microsoft Corporation backward compatibility\n            future ///Reserved for future use\n        }\n\n        /**\n         * RFC 4122 defines different UUID versions. The version shows\n         * how a UUID was generated, e.g. a version 4 UUID was generated\n         * from a random number, a version 3 UUID from an MD5 hash of a name.\n         *\n         * Note:\n         * All of these UUID versions can be read and processed by\n         * `std.uuid`, but only version 3, 4 and 5 UUIDs can be generated.\n         */\n        enum Version\n        {\n            ///Unknown version\n            unknown = -1,\n            ///Version 1\n            timeBased = 1,\n            ///Version 2\n            dceSecurity = 2,\n            ///Version 3 (Name based + MD5)\n            nameBasedMD5 = 3,\n            ///Version 4 (Random)\n            randomNumberBased = 4,\n            ///Version 5 (Name based + SHA-1)\n            nameBasedSHA1 = 5\n        }\n\n        union\n        {\n            /**\n             * It is sometimes useful to get or set the 16 bytes of a UUID\n             * directly.\n             *\n             * Note:\n             * UUID uses a 16-ubyte representation for the UUID data.\n             * RFC 4122 defines a UUID as a special structure in big-endian\n             * format. These 16-ubytes always equal the big-endian structure\n             * defined in RFC 4122.\n             *\n             * Example:\n             * -----------------------------------------------\n             * auto rawData = uuid.data; //get data\n             * rawData[0] = 1; //modify\n             * uuid.data = rawData; //set data\n             * uuid.data[1] = 2; //modify directly\n             * -----------------------------------------------\n             */\n            ubyte[16] data;\n            private ulong[2] ulongs;\n            static if (size_t.sizeof == 4)\n                private uint[4] uints;\n        }\n\n        /*\n         * We could use a union here to also provide access to the\n         * fields specified in RFC 4122, but as we never have to access\n         * those (only necessary for version 1 (and maybe 2) UUIDs),\n         * that is not needed right now.\n         */\n\n        @safe pure unittest\n        {\n            UUID tmp;\n            tmp.data = cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,12,\n                13,14,15];\n            assert(tmp.data == cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,\n                12,13,14,15]);\n            tmp.data[2] = 3;\n            assert(tmp.data == cast(ubyte[16])[0,1,3,3,4,5,6,7,8,9,10,11,\n                12,13,14,15]);\n\n            auto tmp2 = cast(immutable UUID) tmp;\n            assert(tmp2.data == cast(ubyte[16])[0,1,3,3,4,5,6,7,8,9,10,11,\n                12,13,14,15]);\n        }\n\n        /**\n         * Construct a UUID struct from the 16 byte representation\n         * of a UUID.\n         */\n        @safe pure nothrow @nogc this(ref in ubyte[16] uuidData)\n        {\n            data = uuidData;\n        }\n        /// ditto\n        @safe pure nothrow @nogc this(in ubyte[16] uuidData)\n        {\n            data = uuidData;\n        }\n\n        ///\n        @safe pure unittest\n        {\n            enum ubyte[16] data = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];\n            auto uuid = UUID(data);\n            enum ctfe = UUID(data);\n            assert(uuid.data == data);\n            assert(ctfe.data == data);\n        }\n\n        /**\n         * Construct a UUID struct from the 16 byte representation\n         * of a UUID. Variadic constructor to allow a simpler syntax, see examples.\n         * You need to pass exactly 16 ubytes.\n         */\n        @safe pure this(T...)(T uuidData)\n            if (uuidData.length == 16 && allSatisfy!(isIntegral, T))\n        {\n            import std.conv : to;\n\n            foreach (idx, it; uuidData)\n            {\n                this.data[idx] = to!ubyte(it);\n            }\n        }\n\n        ///\n        @safe unittest\n        {\n            auto tmp = UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);\n            assert(tmp.data == cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,\n                12,13,14,15]);\n        }\n\n        @safe unittest\n        {\n            UUID tmp = UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);\n            assert(tmp.data == cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,\n                12,13,14,15]);\n\n            enum UUID ctfeID = UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);\n            assert(ctfeID == tmp);\n\n            //Too few arguments\n            assert(!__traits(compiles, typeof(UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))));\n\n            //Too many arguments\n            assert(!__traits(compiles, typeof(UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1))));\n        }\n\n        /**\n         * <a name=\"UUID(string)\"></a>\n         * Parse a UUID from its canonical string form. An UUID in its\n         * canonical form looks like this: 8ab3060e-2cba-4f23-b74c-b52db3bdfb46\n         *\n         * Throws:\n         * $(LREF UUIDParsingException) if the input is invalid\n         *\n         * CTFE:\n         * This function is supported in CTFE code. Note that error messages\n         * caused by a malformed UUID parsed at compile time can be cryptic,\n         * but errors are detected and reported at\n         * compile time.\n         *\n         * Note:\n         * This is a strict parser. It only accepts the pattern above.\n         * It doesn't support any leading or trailing characters. It only\n         * accepts characters used for hex numbers and the string must have\n         * hyphens exactly like above.\n         *\n         * For a less strict parser, see $(LREF parseUUID)\n         */\n        this(T)(in T[] uuid) if (isSomeChar!(Unqual!T))\n        {\n            import std.conv : to, parse;\n            if (uuid.length < 36)\n            {\n                throw new UUIDParsingException(to!string(uuid), 0,\n                    UUIDParsingException.Reason.tooLittle, \"Insufficient Input\");\n            }\n            if (uuid.length > 36)\n            {\n                throw new UUIDParsingException(to!string(uuid), 35, UUIDParsingException.Reason.tooMuch,\n                    \"Input is too long, need exactly 36 characters\");\n            }\n            static immutable skipInd = [skipSeq];\n            foreach (pos; skipInd)\n                if (uuid[pos] != '-')\n                    throw new UUIDParsingException(to!string(uuid), pos,\n                        UUIDParsingException.Reason.invalidChar, \"Expected '-'\");\n\n            ubyte[16] data2; //ctfe bug\n            uint pos = void;\n\n            foreach (i, p; byteSeq)\n            {\n                enum uint s = 'a'-10-'0';\n                uint h = uuid[p];\n                uint l = uuid[p+1];\n                pos = p;\n                if (h < '0') goto Lerr;\n                if (l < '0') goto Lerr;\n                if (h > '9')\n                {\n                    h |= 0x20; //poorman's tolower\n                    if (h < 'a') goto Lerr;\n                    if (h > 'f') goto Lerr;\n                    h -= s;\n                }\n                if (l > '9')\n                {\n                    l |= 0x20; //poorman's tolower\n                    if (l < 'a') goto Lerr;\n                    if (l > 'f') goto Lerr;\n                    l -= s;\n                }\n                h -= '0';\n                l -= '0';\n\n                data2[i] = cast(ubyte)((h << 4) ^ l);\n            }\n            this.data = data2;\n            return;\n\n        Lerr: throw new UUIDParsingException(to!string(uuid), pos,\n                UUIDParsingException.Reason.invalidChar, \"Couldn't parse ubyte\");\n        }\n\n        ///\n        @safe pure unittest\n        {\n            auto id = UUID(\"8AB3060E-2cba-4f23-b74c-b52db3bdfb46\");\n            assert(id.data == [138, 179, 6, 14, 44, 186, 79, 35, 183, 76,\n               181, 45, 179, 189, 251, 70]);\n            assert(id.toString() == \"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\");\n\n            //Can also be used in CTFE, for example as UUID literals:\n            enum ctfeID = UUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\");\n            //here parsing is done at compile time, no runtime overhead!\n        }\n\n        @safe pure unittest\n        {\n            import std.conv : to;\n            import std.exception;\n            import std.meta : AliasSeq;\n\n            static foreach (S; AliasSeq!(char[], const(char)[], immutable(char)[],\n                                  wchar[], const(wchar)[], immutable(wchar)[],\n                                  dchar[], const(dchar)[], immutable(dchar)[],\n                                  immutable(char[]), immutable(wchar[]), immutable(dchar[])))\n            {{\n                //Test valid, working cases\n                assert(UUID(to!S(\"00000000-0000-0000-0000-000000000000\")).empty);\n\n                auto id = UUID(to!S(\"8AB3060E-2cba-4f23-b74c-b52db3bdfb46\"));\n                assert(id.data == [138, 179, 6, 14, 44, 186, 79, 35, 183, 76,\n                    181, 45, 179, 189, 251, 70]);\n                assert(id.toString() == \"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\");\n\n                enum UUID ctfe = UUID(to!S(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\"));\n                assert(ctfe == id);\n\n                assert(UUID(to!S(\"5668122d-9df0-49a4-ad0b-b9b0a57f886a\")).data\n                    == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);\n\n                //Test too short UUIDS\n                auto except = collectException!UUIDParsingException(\n                    UUID(to!S(\"5668122d-9df0-49a4-ad0b-b9b0a57f886\")));\n                assert(except && except.reason == UUIDParsingException.Reason.tooLittle);\n\n                //Test too long UUIDS\n                except = collectException!UUIDParsingException(\n                    UUID(to!S(\"5668122d-9df0-49a4-ad0b-b9b0a57f886aa\")));\n                assert(except && except.reason == UUIDParsingException.Reason.tooMuch);\n\n                //Test dashes\n                except = collectException!UUIDParsingException(\n                    UUID(to!S(\"8ab3060e2cba-4f23-b74c-b52db3bdfb-46\")));\n                assert(except && except.reason == UUIDParsingException.Reason.invalidChar);\n\n                //Test dashes 2\n                except = collectException!UUIDParsingException(\n                    UUID(to!S(\"8ab3-060e2cba-4f23-b74c-b52db3bdfb46\")));\n                assert(except && except.reason == UUIDParsingException.Reason.invalidChar);\n\n                //Test invalid characters\n                //make sure 36 characters in total or we'll get a 'tooMuch' reason\n                except = collectException!UUIDParsingException(\n                    UUID(to!S(\"{8ab3060e-2cba-4f23-b74c-b52db3bdf6}\")));\n                assert(except && except.reason == UUIDParsingException.Reason.invalidChar);\n\n                //Boost test\n                assert(UUID(to!S(\"01234567-89ab-cdef-0123-456789ABCDEF\"))\n                    == UUID(cast(ubyte[16])[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,0x01,\n                    0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]));\n            }\n        }}\n\n        /**\n         * Returns true if and only if the UUID is equal\n         * to {00000000-0000-0000-0000-000000000000}\n         */\n        @trusted pure nothrow @nogc @property bool empty() const\n        {\n            if (__ctfe)\n                return data == (ubyte[16]).init;\n\n            auto p = cast(const(size_t*))data.ptr;\n            static if (size_t.sizeof == 4)\n                return p[0] == 0 && p[1] == 0 && p[2] == 0 && p[3] == 0;\n            else static if (size_t.sizeof == 8)\n                return p[0] == 0 && p[1] == 0;\n            else\n                static assert(false, \"nonsense, it's not 32 or 64 bit\");\n        }\n\n        ///\n        @safe pure unittest\n        {\n            UUID id;\n            assert(id.empty);\n            id = UUID(\"00000000-0000-0000-0000-000000000001\");\n            assert(!id.empty);\n        }\n\n        @safe pure unittest\n        {\n            ubyte[16] getData(size_t i)\n            {\n                ubyte[16] data;\n                data[i] = 1;\n                return data;\n            }\n\n            for (size_t i = 0; i < 16; i++)\n            {\n                assert(!UUID(getData(i)).empty);\n            }\n\n            enum ctfeEmpty = UUID.init.empty;\n            assert(ctfeEmpty);\n\n            bool ctfeTest()\n            {\n                for (size_t i = 0; i < 16; i++)\n                {\n                    auto ctfeEmpty2 = UUID(getData(i)).empty;\n                    assert(!ctfeEmpty2);\n                }\n                return true;\n            }\n            enum res = ctfeTest();\n        }\n\n        /**\n         * RFC 4122 defines different internal data layouts for UUIDs.\n         * Returns the format used by this UUID.\n         *\n         * Note: Do not confuse this with $(REF _Variant, std,_variant).\n         * The type of this property is $(MYREF3 std.uuid.UUID.Variant, _Variant).\n         *\n         * See_Also:\n         * $(MYREF3 UUID.Variant, Variant)\n         */\n        @safe pure nothrow @nogc @property Variant variant() const\n        {\n            //variant is stored in octet 7\n            //which is index 8, since indexes count backwards\n            immutable octet7 = data[8]; //octet 7 is array index 8\n\n            if ((octet7 & 0x80) == 0x00) //0b0xxxxxxx\n                return Variant.ncs;\n            else if ((octet7 & 0xC0) == 0x80) //0b10xxxxxx\n                return Variant.rfc4122;\n            else if ((octet7 & 0xE0) == 0xC0) //0b110xxxxx\n                return Variant.microsoft;\n            else\n            {\n                //assert((octet7 & 0xE0) == 0xE0, \"Unknown UUID variant!\") //0b111xxxx\n                return Variant.future;\n            }\n        }\n\n        ///\n        @safe pure unittest\n        {\n            assert(UUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\").variant\n               == UUID.Variant.rfc4122);\n        }\n        @system pure unittest\n        {\n            // @system due to Variant\n            Variant[ubyte] tests = cast(Variant[ubyte])[0x00 : Variant.ncs,\n                                    0x10 : Variant.ncs,\n                                    0x20 : Variant.ncs,\n                                    0x30 : Variant.ncs,\n                                    0x40 : Variant.ncs,\n                                    0x50 : Variant.ncs,\n                                    0x60 : Variant.ncs,\n                                    0x70 : Variant.ncs,\n                                    0x80 : Variant.rfc4122,\n                                    0x90 : Variant.rfc4122,\n                                    0xa0 : Variant.rfc4122,\n                                    0xb0 : Variant.rfc4122,\n                                    0xc0 : Variant.microsoft,\n                                    0xd0 : Variant.microsoft,\n                                    0xe0 : Variant.future,\n                                    0xf0 : Variant.future];\n            foreach (key, value; tests)\n            {\n                UUID u;\n                u.data[8] = key;\n                assert(u.variant == value);\n            }\n        }\n\n        /**\n         * RFC 4122 defines different UUID versions. The version shows\n         * how a UUID was generated, e.g. a version 4 UUID was generated\n         * from a random number, a version 3 UUID from an MD5 hash of a name.\n         * Returns the version used by this UUID.\n         *\n         * See_Also:\n         * $(MYREF3 UUID.Version, Version)\n         */\n        @safe pure nothrow @nogc @property Version uuidVersion() const\n        {\n            //version is stored in octet 9\n            //which is index 6, since indexes count backwards\n            immutable octet9 = data[6];\n            if ((octet9 & 0xF0) == 0x10)\n                return Version.timeBased;\n            else if ((octet9 & 0xF0) == 0x20)\n                return Version.dceSecurity;\n            else if ((octet9 & 0xF0) == 0x30)\n                return Version.nameBasedMD5;\n            else if ((octet9 & 0xF0) == 0x40)\n                return Version.randomNumberBased;\n            else if ((octet9 & 0xF0) == 0x50)\n                return Version.nameBasedSHA1;\n            else\n                return Version.unknown;\n        }\n\n        ///\n        @safe unittest\n        {\n            assert(UUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\").uuidVersion\n                == UUID.Version.randomNumberBased);\n        }\n        @system unittest\n        {\n            // @system due to cast\n            Version[ubyte] tests = cast(Version[ubyte]) [\n                0x00 : UUID.Version.unknown,\n                0x10 : UUID.Version.timeBased,\n                0x20 : UUID.Version.dceSecurity,\n                0x30 : UUID.Version.nameBasedMD5,\n                0x40 : UUID.Version.randomNumberBased,\n                0x50 : UUID.Version.nameBasedSHA1,\n                0x60 : UUID.Version.unknown,\n                0x70 : UUID.Version.unknown,\n                0x80 : UUID.Version.unknown,\n                0x90 : UUID.Version.unknown,\n                0xa0 : UUID.Version.unknown,\n                0xb0 : UUID.Version.unknown,\n                0xc0 : UUID.Version.unknown,\n                0xd0 : UUID.Version.unknown,\n                0xe0 : UUID.Version.unknown,\n                0xf0 : UUID.Version.unknown];\n            foreach (key, value; tests)\n            {\n                UUID u;\n                u.data[6] = key;\n                assert(u.uuidVersion == value);\n            }\n        }\n\n        /**\n         * Swap the data of this UUID with the data of rhs.\n         */\n        @safe pure nothrow @nogc void swap(ref UUID rhs)\n        {\n            immutable bck = data;\n            data = rhs.data;\n            rhs.data = bck;\n        }\n\n        ///\n        @safe unittest\n        {\n            immutable ubyte[16] data = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];\n            UUID u1;\n            UUID u2 = UUID(data);\n            u1.swap(u2);\n\n            assert(u1 == UUID(data));\n            assert(u2 == UUID.init);\n        }\n\n        /**\n         * All of the standard numeric operators are defined for\n         * the UUID struct.\n         */\n        @safe pure nothrow @nogc bool opEquals(in UUID s) const\n        {\n            return ulongs[0] == s.ulongs[0] && ulongs[1] == s.ulongs[1];\n        }\n\n        ///\n        @safe pure unittest\n        {\n            //compare UUIDs\n            assert(UUID(\"00000000-0000-0000-0000-000000000000\") == UUID.init);\n\n            //UUIDs in associative arrays:\n            int[UUID] test = [UUID(\"8a94f585-d180-44f7-8929-6fca0189c7d0\") : 1,\n                UUID(\"7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a\") : 2,\n                UUID(\"9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1\") : 3];\n\n            assert(test[UUID(\"9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1\")] == 3);\n\n            //UUIDS can be sorted:\n            import std.algorithm;\n            UUID[] ids = [UUID(\"8a94f585-d180-44f7-8929-6fca0189c7d0\"),\n                          UUID(\"7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a\"),\n                          UUID(\"9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1\")];\n            sort(ids);\n        }\n\n        /**\n         * ditto\n         */\n        @safe pure nothrow @nogc bool opEquals(ref in UUID s) const\n        {\n            return ulongs[0] == s.ulongs[0] && ulongs[1] == s.ulongs[1];\n        }\n\n        /**\n         * ditto\n         */\n        @safe pure nothrow @nogc int opCmp(in UUID s) const\n        {\n            import std.algorithm.comparison : cmp;\n            return cmp(this.data[], s.data[]);\n        }\n\n        /**\n         * ditto\n         */\n        @safe pure nothrow @nogc int opCmp(ref in UUID s) const\n        {\n            import std.algorithm.comparison : cmp;\n            return cmp(this.data[], s.data[]);\n        }\n\n        /**\n         * ditto\n         */\n       @safe pure nothrow @nogc UUID opAssign(in UUID s)\n        {\n            ulongs[0] = s.ulongs[0];\n            ulongs[1] = s.ulongs[1];\n            return this;\n        }\n\n        /**\n         * ditto\n         */\n        @safe pure nothrow @nogc UUID opAssign(ref in UUID s)\n        {\n            ulongs[0] = s.ulongs[0];\n            ulongs[1] = s.ulongs[1];\n            return this;\n        }\n\n        /**\n         * ditto\n         */\n        //MurmurHash2\n        @safe pure nothrow @nogc size_t toHash() const\n        {\n            static if (size_t.sizeof == 4)\n            {\n                enum uint m = 0x5bd1e995;\n                enum uint n = 16;\n                enum uint r = 24;\n\n                uint h = n;\n\n                uint k = uints[0];\n                k *= m;\n                k ^= k >> r;\n                k *= m;\n\n                h ^= k;\n                h *= m;\n\n                k = uints[1];\n                k *= m;\n                k ^= k >> r;\n                k *= m;\n\n                h ^= k;\n                h *= m;\n\n                k = uints[2];\n                k *= m;\n                k ^= k >> r;\n                k *= m;\n\n                h ^= k;\n                h *= m;\n\n                k = uints[3];\n                k *= m;\n                k ^= k >> r;\n                k *= m;\n\n                h ^= k;\n                h *= m;\n            }\n            else\n            {\n                enum ulong m = 0xc6a4a7935bd1e995UL;\n                enum ulong n = m * 16;\n                enum uint r = 47;\n\n                ulong h = n;\n\n                ulong k = ulongs[0];\n                k *= m;\n                k ^= k >> r;\n                k *= m;\n\n                h ^= k;\n                h *= m;\n\n                k = ulongs[1];\n                k *= m;\n                k ^= k >> r;\n                k *= m;\n\n                h ^= k;\n                h *= m;\n            }\n            return h;\n        }\n        @safe unittest\n        {\n            assert(UUID(\"00000000-0000-0000-0000-000000000000\") == UUID.init);\n            int[UUID] test = [UUID(\"8a94f585-d180-44f7-8929-6fca0189c7d0\") : 1,\n                UUID(\"7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a\") : 2,\n                UUID(\"9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1\") : 3];\n\n            assert(test[UUID(\"9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1\")] == 3);\n\n            import std.algorithm;\n            UUID[] ids = [UUID(\"8a94f585-d180-44f7-8929-6fca0189c7d0\"),\n                          UUID(\"7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a\"),\n                          UUID(\"9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1\")];\n            sort(ids);\n            auto id2 = ids.dup;\n\n            ids = [UUID(\"7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a\"),\n                   UUID(\"8a94f585-d180-44f7-8929-6fca0189c7d0\"),\n                   UUID(\"9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1\")];\n            sort(ids);\n            assert(ids == id2);\n\n            //test comparsion\n            UUID u1;\n            UUID u2 = UUID(cast(ubyte[16])[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);\n            UUID u3 = UUID(cast(ubyte[16])[255,255,255,255,255,255,255,255,255,\n                255,255,255,255,255,255,255]);\n\n            assert(u1 == u1);\n\n            assert(u1 != u2);\n\n            assert(u1 < u2);\n            assert(u2 < u3);\n\n            assert(u1 <= u1);\n            assert(u1 <= u2);\n            assert(u2 <= u3);\n\n            assert(u2 >= u2);\n            assert(u3 >= u2);\n\n            assert(u3 >= u3);\n            assert(u2 >= u1);\n            assert(u3 >= u1);\n\n            // test hash\n            assert(u1.toHash() != u2.toHash());\n            assert(u2.toHash() != u3.toHash());\n            assert(u3.toHash() != u1.toHash());\n        }\n\n\n        /**\n         * Write the UUID into `sink` as an ASCII string in the canonical form,\n         * which is 36 characters in the form \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n         * Params:\n         *      sink = OutputRange or writeable array at least 36 entries long\n         */\n        void toString(Writer)(scope Writer sink) const\n        {\n            char[36] result = void;\n            foreach (pos; skipSeq)\n                result[pos] = '-';\n            foreach (i, pos; byteSeq)\n            {\n                const uint entry = this.data[i];\n                const uint hi = entry >> 4;\n                result[pos  ] = toChar!char(hi);\n                const uint lo = (entry) & 0x0F;\n                result[pos+1] = toChar!char(lo);\n            }\n            static if (!__traits(compiles, put(sink, result[])) || isSomeString!Writer)\n            {\n                foreach (i, c; result)\n                    sink[i] = cast(typeof(sink[i]))c;\n            }\n            else\n            {\n                put(sink, result[]);\n            }\n        }\n\n        /**\n         * Return the UUID as a string in the canonical form.\n         */\n        @trusted pure nothrow string toString() const\n        {\n            import std.exception : assumeUnique;\n            auto result = new char[36];\n            toString(result);\n            return result.assumeUnique;\n        }\n\n        ///\n        @safe pure unittest\n        {\n            immutable str = \"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\";\n            auto id = UUID(str);\n            assert(id.toString() == str);\n        }\n\n        @safe pure nothrow @nogc unittest\n        {\n            import std.meta : AliasSeq;\n            static foreach (Char; AliasSeq!(char, wchar, dchar))\n            {{\n                alias String = immutable(Char)[];\n                //CTFE\n                enum String s = \"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\";\n                enum id = UUID(s);\n                static if (is(Char == char))\n                {\n                    enum p = id.toString();\n                    static assert(s == p);\n                }\n                //nogc\n                Char[36] str;\n                id.toString(str[]);\n                assert(str == s);\n            }}\n        }\n\n        @system pure nothrow @nogc unittest\n        {\n            // @system due to cast\n            import std.encoding : Char = AsciiChar;\n            enum  utfstr = \"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\";\n            alias String = immutable(Char)[];\n            enum String s = cast(String) utfstr;\n            enum id = UUID(utfstr);\n            //nogc\n            Char[36] str;\n            id.toString(str[]);\n            assert(str == s);\n        }\n\n        @safe unittest\n        {\n            auto u1 = UUID(cast(ubyte[16])[138, 179, 6, 14, 44, 186, 79,\n                35, 183, 76, 181, 45, 179, 189, 251, 70]);\n            assert(u1.toString() == \"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\");\n            u1 = UUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\");\n            assert(u1.toString() == \"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\");\n\n            char[] buf;\n            void sink(scope const(char)[] data)\n            {\n                buf ~= data;\n            }\n            u1.toString(&sink);\n            assert(buf == \"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\");\n        }\n}\n\n///\n@safe unittest\n{\n    UUID id;\n    assert(id.empty);\n\n    id = randomUUID;\n    assert(!id.empty);\n\n    id = UUID(cast(ubyte[16]) [138, 179, 6, 14, 44, 186, 79,\n        35, 183, 76, 181, 45, 179, 189, 251, 70]);\n    assert(id.toString() == \"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\");\n}\n\n/**\n * This function generates a name based (Version 3) UUID from a namespace UUID and a name.\n * If no namespace UUID was passed, the empty UUID `UUID.init` is used.\n *\n * Note:\n * The default namespaces ($(LREF dnsNamespace), ...) defined by\n * this module should be used when appropriate.\n *\n * RFC 4122 recommends to use Version 5 UUIDs (SHA-1) instead of Version 3\n * UUIDs (MD5) for new applications.\n *\n * CTFE:\n * CTFE is not supported.\n *\n * Note:\n * RFC 4122 isn't very clear on how UUIDs should be generated from names.\n * It is possible that different implementations return different UUIDs\n * for the same input, so be warned. The implementation for UTF-8 strings\n * and byte arrays used by `std.uuid` is compatible with Boost's implementation.\n * `std.uuid` guarantees that the same input to this function will generate\n * the same output at any time, on any system (this especially means endianness\n * doesn't matter).\n *\n * Note:\n * This function does not provide overloads for wstring and dstring, as\n * there's no clear answer on how that should be implemented. It could be\n * argued, that string, wstring and dstring input should have the same output,\n * but that wouldn't be compatible with Boost, which generates different output\n * for strings and wstrings. It's always possible to pass wstrings and dstrings\n * by using the ubyte[] function overload (but be aware of endianness issues!).\n */\n@safe pure nothrow @nogc UUID md5UUID(const(char[]) name, const UUID namespace = UUID.init)\n{\n    return md5UUID(cast(const(ubyte[]))name, namespace);\n}\n\n/// ditto\n@safe pure nothrow @nogc UUID md5UUID(const(ubyte[]) data, const UUID namespace = UUID.init)\n{\n    import std.digest.md : MD5;\n\n    MD5 hash;\n    hash.start();\n\n    /*\n     * NOTE: RFC 4122 says namespace should be converted to big-endian.\n     * We always keep the UUID data in big-endian representation, so\n     * that's fine\n     */\n    hash.put(namespace.data[]);\n    hash.put(data[]);\n\n    UUID u;\n    u.data = hash.finish();\n\n    //set variant\n    //must be 0b10xxxxxx\n    u.data[8] &= 0b10111111;\n    u.data[8] |= 0b10000000;\n\n    //set version\n    //must be 0b0011xxxx\n    u.data[6] &= 0b00111111;\n    u.data[6] |= 0b00110000;\n\n    return u;\n}\n\n///\n@safe unittest\n{\n    //Use default UUID.init namespace\n    auto simpleID = md5UUID(\"test.uuid.any.string\");\n\n    //use a name-based id as namespace\n    auto namespace = md5UUID(\"my.app\");\n    auto id = md5UUID(\"some-description\", namespace);\n}\n\n@safe pure unittest\n{\n    auto simpleID = md5UUID(\"test.uuid.any.string\");\n    assert(simpleID.data == cast(ubyte[16])[126, 206, 86, 72, 29, 233, 62, 213, 178, 139, 198, 136,\n        188, 135, 153, 123]);\n    auto namespace = md5UUID(\"my.app\");\n    auto id = md5UUID(\"some-description\", namespace);\n    assert(id.data == cast(ubyte[16])[166, 138, 167, 79, 48, 219, 55, 166, 170, 103, 39, 73, 216,\n        150, 144, 164]);\n\n    auto constTest = md5UUID(cast(const(char)[])\"test\");\n    constTest = md5UUID(cast(const(char[]))\"test\");\n\n    char[] mutable = \"test\".dup;\n    id = md5UUID(mutable, namespace);\n\n    const(ubyte)[] data = cast(ubyte[])[0,1,2,244,165,222];\n    id = md5UUID(data);\n    assert(id.data == cast(ubyte[16])[16, 50, 29, 247, 243, 185, 61, 178, 157, 100, 253, 236, 73,\n        76, 51, 47]);\n\n    assert(id.variant == UUID.Variant.rfc4122);\n    assert(id.uuidVersion == UUID.Version.nameBasedMD5);\n\n    auto correct = UUID(\"3d813cbb-47fb-32ba-91df-831e1593ac29\");\n\n    auto u = md5UUID(\"www.widgets.com\", dnsNamespace);\n    //enum ctfeId = md5UUID(\"www.widgets.com\", dnsNamespace);\n    //assert(ctfeId == u);\n    assert(u == correct);\n    assert(u.variant == UUID.Variant.rfc4122);\n    assert(u.uuidVersion == UUID.Version.nameBasedMD5);\n}\n\n /**\n * This function generates a name based (Version 5) UUID from a namespace\n * UUID and a name.\n * If no namespace UUID was passed, the empty UUID `UUID.init` is used.\n *\n * Note:\n * The default namespaces ($(LREF dnsNamespace), ...) defined by\n * this module should be used when appropriate.\n *\n * CTFE:\n * CTFE is not supported.\n *\n * Note:\n * RFC 4122 isn't very clear on how UUIDs should be generated from names.\n * It is possible that different implementations return different UUIDs\n * for the same input, so be warned. The implementation for UTF-8 strings\n * and byte arrays used by `std.uuid` is compatible with Boost's implementation.\n * `std.uuid` guarantees that the same input to this function will generate\n * the same output at any time, on any system (this especially means endianness\n * doesn't matter).\n *\n * Note:\n * This function does not provide overloads for wstring and dstring, as\n * there's no clear answer on how that should be implemented. It could be\n * argued, that string, wstring and dstring input should have the same output,\n * but that wouldn't be compatible with Boost, which generates different output\n * for strings and wstrings. It's always possible to pass wstrings and dstrings\n * by using the ubyte[] function overload (but be aware of endianness issues!).\n */\n@safe pure nothrow @nogc UUID sha1UUID(scope const(char)[] name, scope const UUID namespace = UUID.init)\n{\n    return sha1UUID(cast(const(ubyte[]))name, namespace);\n}\n\n/// ditto\n@safe pure nothrow @nogc UUID sha1UUID(scope const(ubyte)[] data, scope const UUID namespace = UUID.init)\n{\n    import std.digest.sha : SHA1;\n\n    SHA1 sha;\n    sha.start();\n\n    /*\n     * NOTE: RFC 4122 says namespace should be converted to big-endian.\n     * We always keep the UUID data in big-endian representation, so\n     * that's fine\n     */\n    sha.put(namespace.data[]);\n    sha.put(data[]);\n\n    auto hash = sha.finish();\n    auto u = UUID();\n    u.data[] = hash[0 .. 16];\n\n    //set variant\n    //must be 0b10xxxxxx\n    u.data[8] &= 0b10111111;\n    u.data[8] |= 0b10000000;\n\n    //set version\n    //must be 0b0101xxxx\n    u.data[6] &= 0b01011111;\n    u.data[6] |= 0b01010000;\n\n    return u;\n}\n\n///\n@safe unittest\n{\n    //Use default UUID.init namespace\n    auto simpleID = sha1UUID(\"test.uuid.any.string\");\n\n    //use a name-based id as namespace\n    auto namespace = sha1UUID(\"my.app\");\n    auto id = sha1UUID(\"some-description\", namespace);\n}\n\n@safe pure unittest\n{\n    auto simpleID = sha1UUID(\"test.uuid.any.string\");\n    assert(simpleID.data == cast(ubyte[16])[16, 209, 239, 61, 99, 12, 94, 70, 159, 79, 255, 250,\n        131, 79, 14, 147]);\n    auto namespace = sha1UUID(\"my.app\");\n    auto id = sha1UUID(\"some-description\", namespace);\n    assert(id.data == cast(ubyte[16])[225, 94, 195, 219, 126, 75, 83, 71, 157, 52, 247, 43, 238, 248,\n        148, 46]);\n\n    auto constTest = sha1UUID(cast(const(char)[])\"test\");\n    constTest = sha1UUID(cast(const(char[]))\"test\");\n\n    char[] mutable = \"test\".dup;\n    id = sha1UUID(mutable, namespace);\n\n    const(ubyte)[] data = cast(ubyte[])[0,1,2,244,165,222];\n    id = sha1UUID(data);\n    assert(id.data == cast(ubyte[16])[60, 65, 92, 240, 96, 46, 95, 238, 149, 100, 12, 64, 199, 194,\n        243, 12]);\n\n    auto correct = UUID(\"21f7f8de-8051-5b89-8680-0195ef798b6a\");\n\n    auto u = sha1UUID(\"www.widgets.com\", dnsNamespace);\n    assert(u == correct);\n    assert(u.variant == UUID.Variant.rfc4122);\n    assert(u.uuidVersion == UUID.Version.nameBasedSHA1);\n}\n\n/**\n * This function generates a random number based UUID from a random\n * number generator.\n *\n * This function is not supported at compile time.\n *\n * Params:\n *      randomGen = uniform RNG\n * See_Also: $(REF isUniformRNG, std,random)\n */\n@safe UUID randomUUID()\n{\n    import std.random : rndGen;\n    // A PRNG with fewer than `n` bytes of state cannot produce\n    // every distinct `n` byte sequence.\n    static if (typeof(rndGen).sizeof >= UUID.sizeof)\n    {\n        return randomUUID(rndGen);\n    }\n    else\n    {\n        import std.random : unpredictableSeed, Xorshift192;\n        static assert(Xorshift192.sizeof >= UUID.sizeof);\n        static Xorshift192 rng;\n        static bool initialized;\n        if (!initialized)\n        {\n            rng.seed(unpredictableSeed);\n            initialized = true;\n        }\n        return randomUUID(rng);\n    }\n}\n\n/// ditto\nUUID randomUUID(RNG)(ref RNG randomGen)\nif (isInputRange!RNG && isIntegral!(ElementType!RNG))\n{\n    import std.random : isUniformRNG;\n    static assert(isUniformRNG!RNG, \"randomGen must be a uniform RNG\");\n\n    alias E = ElementEncodingType!RNG;\n    enum size_t elemSize = E.sizeof;\n    static assert(elemSize <= 16);\n    static assert(16 % elemSize == 0);\n\n    UUID u;\n    foreach (ref E e ; u.asArrayOf!E())\n    {\n        e = randomGen.front;\n        randomGen.popFront();\n    }\n\n    //set variant\n    //must be 0b10xxxxxx\n    u.data[8] &= 0b10111111;\n    u.data[8] |= 0b10000000;\n\n    //set version\n    //must be 0b0100xxxx\n    u.data[6] &= 0b01001111;\n    u.data[6] |= 0b01000000;\n\n    return u;\n}\n\n///\n@safe unittest\n{\n    import std.random : Xorshift192, unpredictableSeed;\n\n    //simple call\n    auto uuid = randomUUID();\n\n    //provide a custom RNG. Must be seeded manually.\n    Xorshift192 gen;\n\n    gen.seed(unpredictableSeed);\n    auto uuid3 = randomUUID(gen);\n}\n\n@safe unittest\n{\n    import std.random : Xorshift192, unpredictableSeed;\n    //simple call\n    auto uuid = randomUUID();\n\n    //provide a custom RNG. Must be seeded manually.\n    Xorshift192 gen;\n    gen.seed(unpredictableSeed);\n    auto uuid3 = randomUUID(gen);\n\n    auto u1 = randomUUID();\n    auto u2 = randomUUID();\n    assert(u1 != u2);\n    assert(u1.variant == UUID.Variant.rfc4122);\n    assert(u1.uuidVersion == UUID.Version.randomNumberBased);\n}\n\n/**\n * This is a less strict parser compared to the parser used in the\n * UUID constructor. It enforces the following rules:\n *\n * $(UL\n *   $(LI hex numbers are always two hexdigits([0-9a-fA-F]))\n *   $(LI there must be exactly 16 such pairs in the input, not less, not more)\n *   $(LI there can be exactly one dash between two hex-pairs, but not more)\n *   $(LI there can be multiple characters enclosing the 16 hex pairs,\n *     as long as these characters do not contain [0-9a-fA-F])\n * )\n *\n * Note:\n * Like most parsers, it consumes its argument. This means:\n * -------------------------\n * string s = \"8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46\";\n * parseUUID(s);\n * assert(s == \"\");\n * -------------------------\n *\n * Throws:\n * $(LREF UUIDParsingException) if the input is invalid\n *\n * CTFE:\n * This function is supported in CTFE code. Note that error messages\n * caused by a malformed UUID parsed at compile time can be cryptic,\n * but errors are detected and reported at compile time.\n */\nUUID parseUUID(T)(T uuidString)\nif (isSomeString!T)\n{\n    return parseUUID(uuidString);\n}\n\n///ditto\nUUID parseUUID(Range)(ref Range uuidRange)\nif (isInputRange!Range\n    && is(Unqual!(ElementType!Range) == dchar))\n{\n    import std.ascii : isHexDigit;\n    import std.conv : ConvException, parse;\n\n    static if (isForwardRange!Range)\n        auto errorCopy = uuidRange.save;\n\n    void parserError()(size_t pos, UUIDParsingException.Reason reason, string message, Throwable next = null,\n        string file = __FILE__, size_t line = __LINE__)\n    {\n        static if (isForwardRange!Range)\n        {\n            import std.conv : to;\n            static if (isInfinite!Range)\n            {\n                throw new UUIDParsingException(to!string(take(errorCopy, pos)), pos, reason, message,\n                    next, file, line);\n            }\n            else\n            {\n                throw new UUIDParsingException(to!string(errorCopy), pos, reason, message, next, file,\n                    line);\n            }\n        }\n        else\n        {\n            throw new UUIDParsingException(\"\", pos, reason, message, next, file, line);\n        }\n    }\n\n    static if (hasLength!Range)\n    {\n        import std.conv : to;\n        if (uuidRange.length < 32)\n        {\n            throw new UUIDParsingException(to!string(uuidRange), 0, UUIDParsingException.Reason.tooLittle,\n                \"Insufficient Input\");\n        }\n    }\n\n    UUID result;\n    size_t consumed;\n    size_t element = 0;\n\n    //skip garbage\n    size_t skip()()\n    {\n        size_t skipped;\n        while (!uuidRange.empty && !isHexDigit(uuidRange.front))\n        {\n            skipped++;\n            uuidRange.popFront();\n        }\n        return skipped;\n    }\n\n    consumed += skip();\n\n    if (uuidRange.empty)\n        parserError(consumed, UUIDParsingException.Reason.tooLittle, \"Insufficient Input\");\n\n    bool dashAllowed = false;\n\n    parseLoop: while (!uuidRange.empty)\n    {\n        immutable character = uuidRange.front;\n\n        if (character == '-')\n        {\n            if (!dashAllowed)\n                parserError(consumed, UUIDParsingException.Reason.invalidChar, \"Unexpected '-'\");\n            else\n                dashAllowed = false;\n\n            consumed++;\n        }\n        else if (!isHexDigit(character))\n        {\n            parserError(consumed, UUIDParsingException.Reason.invalidChar,\n                \"Unexpected character (wanted a hexDigit)\");\n        }\n        else\n        {\n            try\n            {\n                consumed += 2;\n                static if (isSomeString!Range)\n                {\n                    if (uuidRange.length < 2)\n                    {\n                        parserError(consumed, UUIDParsingException.Reason.tooLittle,\n                            \"Insufficient Input\");\n                    }\n                    auto part = uuidRange[0 .. 2];\n                    result.data[element++] = parse!ubyte(part, 16);\n                    uuidRange.popFront();\n                }\n                else\n                {\n                    dchar[2] copyBuf;\n                    copyBuf[0] = character;\n                    uuidRange.popFront();\n                    if (uuidRange.empty)\n                    {\n                        parserError(consumed, UUIDParsingException.Reason.tooLittle,\n                            \"Insufficient Input\");\n                    }\n                    copyBuf[1] = uuidRange.front;\n                    auto part = copyBuf[];\n                    result.data[element++] = parse!ubyte(part, 16);\n                }\n\n                if (element == 16)\n                {\n                    uuidRange.popFront();\n                    break parseLoop;\n                }\n\n                dashAllowed = true;\n            }\n            catch (ConvException e)\n            {\n                parserError(consumed, UUIDParsingException.Reason.invalidChar,\n                    \"Couldn't parse ubyte\", e);\n            }\n        }\n        uuidRange.popFront();\n    }\n    assert(element <= 16);\n\n    if (element < 16)\n        parserError(consumed, UUIDParsingException.Reason.tooLittle, \"Insufficient Input\");\n\n    consumed += skip();\n    if (!uuidRange.empty)\n        parserError(consumed, UUIDParsingException.Reason.invalidChar, \"Unexpected character\");\n\n    return result;\n}\n\n///\n@safe unittest\n{\n    auto id = parseUUID(\"8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46\");\n    //no dashes\n    id = parseUUID(\"8ab3060e2cba4f23b74cb52db3bdfb46\");\n    //dashes at different positions\n    id = parseUUID(\"8a-b3-06-0e2cba4f23b74c-b52db3bdfb-46\");\n    //leading / trailing characters\n    id = parseUUID(\"{8ab3060e-2cba-4f23-b74c-b52db3bdfb46}\");\n    //unicode\n    id = parseUUID(\"ü8ab3060e2cba4f23b74cb52db3bdfb46ü\");\n    //multiple trailing/leading characters\n    id = parseUUID(\"///8ab3060e2cba4f23b74cb52db3bdfb46||\");\n\n    //Can also be used in CTFE, for example as UUID literals:\n    enum ctfeID = parseUUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\");\n    //here parsing is done at compile time, no runtime overhead!\n}\n\n@safe pure unittest\n{\n    import std.conv : to;\n    import std.exception;\n    import std.meta;\n\n    struct TestRange(bool forward)\n    {\n        dstring input;\n\n        @property dchar front()\n        {\n            return input.front;\n        }\n\n        void popFront()\n        {\n            input.popFront();\n        }\n\n        @property bool empty()\n        {\n            return input.empty;\n        }\n\n        static if (forward)\n        {\n            @property TestRange!true save()\n            {\n                return this;\n            }\n        }\n    }\n    alias TestInputRange = TestRange!false;\n    alias TestForwardRange = TestRange!true;\n\n    assert(isInputRange!TestInputRange);\n    assert(is(ElementType!TestInputRange == dchar));\n    assert(isInputRange!TestForwardRange);\n    assert(isForwardRange!TestForwardRange);\n    assert(is(ElementType!TestForwardRange == dchar));\n\n    //Helper function for unittests - Need to pass ranges by ref\n    UUID parseHelper(T)(string input)\n    {\n        static if (is(T == TestInputRange) || is(T == TestForwardRange))\n        {\n            T range = T(to!dstring(input));\n            return parseUUID(range);\n        }\n        else\n            return parseUUID(to!T(input));\n    }\n\n    static foreach (S; AliasSeq!(char[], const(char)[], immutable(char)[],\n                          wchar[], const(wchar)[], immutable(wchar)[],\n                          dchar[], const(dchar)[], immutable(dchar)[],\n                          immutable(char[]), immutable(wchar[]), immutable(dchar[]),\n                          TestForwardRange, TestInputRange))\n    {{\n        //Verify examples.\n        auto id = parseHelper!S(\"8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46\");\n        //no dashes\n        id = parseHelper!S(\"8ab3060e2cba4f23b74cb52db3bdfb46\");\n        //dashes at different positions\n        id = parseHelper!S(\"8a-b3-06-0e2cba4f23b74c-b52db3bdfb-46\");\n        //leading / trailing characters\n        id = parseHelper!S(\"{8ab3060e-2cba-4f23-b74c-b52db3bdfb46}\");\n        //unicode\n        id = parseHelper!S(\"ü8ab3060e2cba4f23b74cb52db3bdfb46ü\");\n        //multiple trailing/leading characters\n        id = parseHelper!S(\"///8ab3060e2cba4f23b74cb52db3bdfb46||\");\n        enum ctfeId = parseHelper!S(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\");\n        assert(parseHelper!S(\"8AB3060E-2cba-4f23-b74c-b52db3bdfb46\") == ctfeId);\n\n        //Test valid, working cases\n        assert(parseHelper!S(\"00000000-0000-0000-0000-000000000000\").empty);\n        assert(parseHelper!S(\"8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46\").data\n            == [138, 179, 6, 14, 44, 186, 79, 35, 183, 76, 181, 45, 179, 189, 251, 70]);\n\n        assert(parseHelper!S(\"5668122d-9df0-49a4-ad0b-b9b0a57f886a\").data\n            == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);\n\n        //wstring / dstring\n        assert(parseHelper!S(\"5668122d-9df0-49a4-ad0b-b9b0a57f886a\").data\n            == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);\n        assert(parseHelper!S(\"5668122d-9df0-49a4-ad0b-b9b0a57f886a\").data\n            == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);\n\n        //Test too short UUIDS\n        auto except = collectException!UUIDParsingException(\n            parseHelper!S(\"5668122d-9df0-49a4-ad0b-b9b0a57f886\"));\n        assert(except && except.reason == UUIDParsingException.Reason.tooLittle);\n\n        //Test too long UUIDS\n        except = collectException!UUIDParsingException(\n            parseHelper!S(\"5668122d-9df0-49a4-ad0b-b9b0a57f886aa\"));\n        assert(except && except.reason == UUIDParsingException.Reason.invalidChar);\n\n        //Test too long UUIDS 2\n        except = collectException!UUIDParsingException(\n            parseHelper!S(\"5668122d-9df0-49a4-ad0b-b9b0a57f886a-aa\"));\n        assert(except && except.reason == UUIDParsingException.Reason.invalidChar);\n\n        //Test dashes\n        assert(parseHelper!S(\"8ab3060e2cba-4f23-b74c-b52db3bdfb46\")\n            == parseUUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\"));\n        assert(parseHelper!S(\"8ab3-060e2cba-4f23-b74c-b52db3bdfb46\")\n            == parseUUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\"));\n        assert(parseHelper!S(\"8ab3060e2cba4f23b74cb52db3bdfb46\")\n            == parseUUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\"));\n\n        except = collectException!UUIDParsingException(\n            parseHelper!S(\"8-ab3060e2cba-4f23-b74c-b52db3bdfb46\"));\n        assert(except && except.reason == UUIDParsingException.Reason.invalidChar);\n\n        //Test leading/trailing characters\n        assert(parseHelper!S(\"{8ab3060e-2cba-4f23-b74c-b52db3bdfb46}\")\n            == parseUUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\"));\n        assert(parseHelper!S(\"{8ab3060e2cba4f23b74cb52db3bdfb46}\")\n            == parseUUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\"));\n\n        //Boost test\n        auto u_increasing = UUID(cast(ubyte[16])[0x01, 0x23, 0x45, 0x67, 0x89, 0xab,\n            0xcd, 0xef,0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);\n        assert(parseHelper!S(\"0123456789abcdef0123456789ABCDEF\") == UUID(cast(ubyte[16])[0x01,\n            0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]));\n\n        //unicode\n        assert(parseHelper!S(\"ü8ab3060e2cba4f23b74cb52db3bdfb46ü\")\n            == parseUUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\"));\n\n        //multiple trailing/leading characters\n        assert(parseHelper!S(\"///8ab3060e2cba4f23b74cb52db3bdfb46||\")\n            == parseUUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\"));\n    }}\n}\n\n/**\n * Default namespace from RFC 4122\n *\n * Name string is a fully-qualified domain name\n */\nenum dnsNamespace = UUID(\"6ba7b810-9dad-11d1-80b4-00c04fd430c8\");\n\n/**\n * Default namespace from RFC 4122\n *\n * Name string is a URL\n */\nenum urlNamespace = UUID(\"6ba7b811-9dad-11d1-80b4-00c04fd430c8\");\n\n/**\n * Default namespace from RFC 4122\n *\n * Name string is an ISO OID\n */\nenum oidNamespace = UUID(\"6ba7b812-9dad-11d1-80b4-00c04fd430c8\");\n\n/**\n * Default namespace from RFC 4122\n *\n * Name string is an X.500 DN (in DER or a text output format)\n */\nenum x500Namespace = UUID(\"6ba7b814-9dad-11d1-80b4-00c04fd430c8\");\n\n/**\n * Regex string to extract UUIDs from text.\n */\nenum uuidRegex = \"[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}\"~\n    \"-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\";\n\n///\n@safe unittest\n{\n    import std.algorithm;\n    import std.regex;\n\n    string test = \"Lorem ipsum dolor sit amet, consetetur \"~\n    \"6ba7b814-9dad-11d1-80b4-00c04fd430c8 sadipscing \\n\"~\n    \"elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore \\r\\n\"~\n    \"magna aliquyam erat, sed diam voluptua. \"~\n    \"8ab3060e-2cba-4f23-b74c-b52db3bdfb46 At vero eos et accusam et \"~\n    \"justo duo dolores et ea rebum.\";\n\n    auto r = regex(uuidRegex, \"g\");\n    UUID[] found;\n    foreach (c; match(test, r))\n    {\n        found ~= UUID(c.hit);\n    }\n    assert(found == [\n        UUID(\"6ba7b814-9dad-11d1-80b4-00c04fd430c8\"),\n        UUID(\"8ab3060e-2cba-4f23-b74c-b52db3bdfb46\"),\n    ]);\n}\n\n/**\n * This exception is thrown if an error occurs when parsing a UUID\n * from a string.\n */\npublic class UUIDParsingException : Exception\n{\n    /**\n     * The reason why parsing the UUID string failed (if known)\n     */\n    enum Reason\n    {\n        unknown, ///\n        tooLittle, ///The passed in input was correct, but more input was expected.\n        tooMuch, ///The input data is too long (There's no guarantee the first part of the data is valid)\n        invalidChar, ///Encountered an invalid character\n\n    }\n    ///ditto\n    Reason reason;\n    ///The original input string which should have been parsed.\n    string input;\n    ///The position in the input string where the error occurred.\n    size_t position;\n\n    private this(string input, size_t pos, Reason why = Reason.unknown, string msg = \"\",\n        Throwable next = null, string file = __FILE__, size_t line = __LINE__) pure @trusted\n    {\n        import std.array : replace;\n        import std.format : format;\n        this.input = input;\n        this.position = pos;\n        this.reason = why;\n        string message = format(\"An error occured in the UUID parser: %s\\n\" ~\n          \" * Input:\\t'%s'\\n * Position:\\t%s\", msg, replace(replace(input,\n          \"\\r\", \"\\\\r\"), \"\\n\", \"\\\\n\"), pos);\n        super(message, file, line, next);\n    }\n}\n\n///\n@safe unittest\n{\n    import std.exception : collectException;\n\n    const inputUUID = \"this-is-an-invalid-uuid\";\n    auto ex = collectException!UUIDParsingException(UUID(inputUUID));\n    assert(ex !is null); // check that exception was thrown\n    assert(ex.input == inputUUID);\n    assert(ex.position == 0);\n    assert(ex.reason == UUIDParsingException.Reason.tooLittle);\n}\n\n@safe unittest\n{\n    auto ex = new UUIDParsingException(\"foo\", 10, UUIDParsingException.Reason.tooMuch);\n    assert(ex.input == \"foo\");\n    assert(ex.position == 10);\n    assert(ex.reason == UUIDParsingException.Reason.tooMuch);\n}\n"
  },
  {
    "path": "libphobos/src/std/variant.d",
    "content": "// Written in the D programming language.\n\n/**\nThis module implements a\n$(HTTP erdani.org/publications/cuj-04-2002.html,discriminated union)\ntype (a.k.a.\n$(HTTP en.wikipedia.org/wiki/Tagged_union,tagged union),\n$(HTTP en.wikipedia.org/wiki/Algebraic_data_type,algebraic type)).\nSuch types are useful\nfor type-uniform binary interfaces, interfacing with scripting\nlanguages, and comfortable exploratory programming.\n\nA $(LREF Variant) object can hold a value of any type, with very few\nrestrictions (such as `shared` types and noncopyable types). Setting the value\nis as immediate as assigning to the `Variant` object. To read back the value of\nthe appropriate type `T`, use the $(LREF get) method. To query whether a\n`Variant` currently holds a value of type `T`, use $(LREF peek). To fetch the\nexact type currently held, call $(LREF type), which returns the `TypeInfo` of\nthe current value.\n\nIn addition to $(LREF Variant), this module also defines the $(LREF Algebraic)\ntype constructor. Unlike `Variant`, `Algebraic` only allows a finite set of\ntypes, which are specified in the instantiation (e.g. $(D Algebraic!(int,\nstring)) may only hold an `int` or a `string`).\n\nCredits: Reviewed by Brad Roberts. Daniel Keep provided a detailed code review\nprompting the following improvements: (1) better support for arrays; (2) support\nfor associative arrays; (3) friendlier behavior towards the garbage collector.\nCopyright: Copyright Andrei Alexandrescu 2007 - 2015.\nLicense:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   $(HTTP erdani.org, Andrei Alexandrescu)\nSource:    $(PHOBOSSRC std/variant.d)\n*/\nmodule std.variant;\n\nimport std.meta, std.traits, std.typecons;\n\n///\n@system unittest\n{\n    Variant a; // Must assign before use, otherwise exception ensues\n    // Initialize with an integer; make the type int\n    Variant b = 42;\n    assert(b.type == typeid(int));\n    // Peek at the value\n    assert(b.peek!(int) !is null && *b.peek!(int) == 42);\n    // Automatically convert per language rules\n    auto x = b.get!(real);\n\n    // Assign any other type, including other variants\n    a = b;\n    a = 3.14;\n    assert(a.type == typeid(double));\n    // Implicit conversions work just as with built-in types\n    assert(a < b);\n    // Check for convertibility\n    assert(!a.convertsTo!(int)); // double not convertible to int\n    // Strings and all other arrays are supported\n    a = \"now I'm a string\";\n    assert(a == \"now I'm a string\");\n\n    // can also assign arrays\n    a = new int[42];\n    assert(a.length == 42);\n    a[5] = 7;\n    assert(a[5] == 7);\n\n    // Can also assign class values\n    class Foo {}\n    auto foo = new Foo;\n    a = foo;\n    assert(*a.peek!(Foo) == foo); // and full type information is preserved\n}\n\n/++\n    Gives the `sizeof` the largest type given.\n  +/\ntemplate maxSize(T...)\n{\n    static if (T.length == 1)\n    {\n        enum size_t maxSize = T[0].sizeof;\n    }\n    else\n    {\n        import std.algorithm.comparison : max;\n        enum size_t maxSize = max(T[0].sizeof, maxSize!(T[1 .. $]));\n    }\n}\n\n///\n@safe unittest\n{\n    static assert(maxSize!(int, long) == 8);\n    static assert(maxSize!(bool, byte) == 1);\n\n    struct Cat { int a, b, c; }\n    static assert(maxSize!(bool, Cat) == 12);\n}\n\nstruct This;\n\nprivate alias This2Variant(V, T...) = AliasSeq!(ReplaceType!(This, V, T));\n\n/**\n * Back-end type seldom used directly by user\n * code. Two commonly-used types using `VariantN` are:\n *\n * $(OL $(LI $(LREF Algebraic): A closed discriminated union with a\n * limited type universe (e.g., $(D Algebraic!(int, double,\n * string)) only accepts these three types and rejects anything\n * else).) $(LI $(LREF Variant): An open discriminated union allowing an\n * unbounded set of types. If any of the types in the `Variant`\n * are larger than the largest built-in type, they will automatically\n * be boxed. This means that even large types will only be the size\n * of a pointer within the `Variant`, but this also implies some\n * overhead. `Variant` can accommodate all primitive types and\n * all user-defined types.))\n *\n * Both `Algebraic` and `Variant` share $(D\n * VariantN)'s interface. (See their respective documentations below.)\n *\n * `VariantN` is a discriminated union type parameterized\n * with the largest size of the types stored (`maxDataSize`)\n * and with the list of allowed types (`AllowedTypes`). If\n * the list is empty, then any type up of size up to $(D\n * maxDataSize) (rounded up for alignment) can be stored in a\n * `VariantN` object without being boxed (types larger\n * than this will be boxed).\n *\n */\nstruct VariantN(size_t maxDataSize, AllowedTypesParam...)\n{\n    /**\n    The list of allowed types. If empty, any type is allowed.\n    */\n    alias AllowedTypes = This2Variant!(VariantN, AllowedTypesParam);\n\nprivate:\n    // Compute the largest practical size from maxDataSize\n    struct SizeChecker\n    {\n        int function() fptr;\n        ubyte[maxDataSize] data;\n    }\n    enum size = SizeChecker.sizeof - (int function()).sizeof;\n\n    /** Tells whether a type `T` is statically _allowed for\n     * storage inside a `VariantN` object by looking\n     * `T` up in `AllowedTypes`.\n     */\n    public template allowed(T)\n    {\n        enum bool allowed\n            = is(T == VariantN)\n            ||\n            //T.sizeof <= size &&\n            (AllowedTypes.length == 0 || staticIndexOf!(T, AllowedTypes) >= 0);\n    }\n\n    // Each internal operation is encoded with an identifier. See\n    // the \"handler\" function below.\n    enum OpID { getTypeInfo, get, compare, equals, testConversion, toString,\n            index, indexAssign, catAssign, copyOut, length,\n            apply, postblit, destruct }\n\n    // state\n    ptrdiff_t function(OpID selector, ubyte[size]* store, void* data) fptr\n        = &handler!(void);\n    union\n    {\n        ubyte[size] store;\n        // conservatively mark the region as pointers\n        static if (size >= (void*).sizeof)\n            void*[size / (void*).sizeof] p;\n    }\n\n    // internals\n    // Handler for an uninitialized value\n    static ptrdiff_t handler(A : void)(OpID selector, ubyte[size]*, void* parm)\n    {\n        switch (selector)\n        {\n        case OpID.getTypeInfo:\n            *cast(TypeInfo *) parm = typeid(A);\n            break;\n        case OpID.copyOut:\n            auto target = cast(VariantN *) parm;\n            target.fptr = &handler!(A);\n            // no need to copy the data (it's garbage)\n            break;\n        case OpID.compare:\n        case OpID.equals:\n            auto rhs = cast(const VariantN *) parm;\n            return rhs.peek!(A)\n                ? 0 // all uninitialized are equal\n                : ptrdiff_t.min; // uninitialized variant is not comparable otherwise\n        case OpID.toString:\n            string * target = cast(string*) parm;\n            *target = \"<Uninitialized VariantN>\";\n            break;\n        case OpID.postblit:\n        case OpID.destruct:\n            break;\n        case OpID.get:\n        case OpID.testConversion:\n        case OpID.index:\n        case OpID.indexAssign:\n        case OpID.catAssign:\n        case OpID.length:\n            throw new VariantException(\n                \"Attempt to use an uninitialized VariantN\");\n        default: assert(false, \"Invalid OpID\");\n        }\n        return 0;\n    }\n\n    // Handler for all of a type's operations\n    static ptrdiff_t handler(A)(OpID selector, ubyte[size]* pStore, void* parm)\n    {\n        import std.conv : to;\n        static A* getPtr(void* untyped)\n        {\n            if (untyped)\n            {\n                static if (A.sizeof <= size)\n                    return cast(A*) untyped;\n                else\n                    return *cast(A**) untyped;\n            }\n            return null;\n        }\n\n        static ptrdiff_t compare(A* rhsPA, A* zis, OpID selector)\n        {\n            static if (is(typeof(*rhsPA == *zis)))\n            {\n                if (*rhsPA == *zis)\n                {\n                    return 0;\n                }\n                static if (is(typeof(*zis < *rhsPA)))\n                {\n                    // Many types (such as any using the default Object opCmp)\n                    // will throw on an invalid opCmp, so do it only\n                    // if the caller requests it.\n                    if (selector == OpID.compare)\n                        return *zis < *rhsPA ? -1 : 1;\n                    else\n                        return ptrdiff_t.min;\n                }\n                else\n                {\n                    // Not equal, and type does not support ordering\n                    // comparisons.\n                    return ptrdiff_t.min;\n                }\n            }\n            else\n            {\n                // Type does not support comparisons at all.\n                return ptrdiff_t.min;\n            }\n        }\n\n        auto zis = getPtr(pStore);\n        // Input: TypeInfo object\n        // Output: target points to a copy of *me, if me was not null\n        // Returns: true iff the A can be converted to the type represented\n        // by the incoming TypeInfo\n        static bool tryPutting(A* src, TypeInfo targetType, void* target)\n        {\n            alias UA = Unqual!A;\n            alias MutaTypes = AliasSeq!(UA, ImplicitConversionTargets!UA);\n            alias ConstTypes = staticMap!(ConstOf, MutaTypes);\n            alias SharedTypes = staticMap!(SharedOf, MutaTypes);\n            alias SharedConstTypes = staticMap!(SharedConstOf, MutaTypes);\n            alias ImmuTypes  = staticMap!(ImmutableOf, MutaTypes);\n\n            static if (is(A == immutable))\n                alias AllTypes = AliasSeq!(ImmuTypes, ConstTypes, SharedConstTypes);\n            else static if (is(A == shared))\n            {\n                static if (is(A == const))\n                    alias AllTypes = SharedConstTypes;\n                else\n                    alias AllTypes = AliasSeq!(SharedTypes, SharedConstTypes);\n            }\n            else\n            {\n                static if (is(A == const))\n                    alias AllTypes = ConstTypes;\n                else\n                    alias AllTypes = AliasSeq!(MutaTypes, ConstTypes);\n            }\n\n            foreach (T ; AllTypes)\n            {\n                if (targetType != typeid(T))\n                    continue;\n\n                // SPECIAL NOTE: variant only will ever create a new value with\n                // tryPutting (effectively), and T is ALWAYS the same type of\n                // A, but with different modifiers (and a limited set of\n                // implicit targets). So this checks to see if we can construct\n                // a T from A, knowing that prerequisite. This handles issues\n                // where the type contains some constant data aside from the\n                // modifiers on the type itself.\n                static if (is(typeof(delegate T() {return *src;})) ||\n                           is(T ==        const(U), U) ||\n                           is(T ==       shared(U), U) ||\n                           is(T == shared const(U), U) ||\n                           is(T ==    immutable(U), U))\n                {\n                    import std.conv : emplaceRef;\n\n                    auto zat = cast(T*) target;\n                    if (src)\n                    {\n                        static if (T.sizeof > 0)\n                            assert(target, \"target must be non-null\");\n\n                        emplaceRef(*cast(Unqual!T*) zat, *cast(UA*) src);\n                    }\n                }\n                else\n                {\n                    // type T is not constructible from A\n                    if (src)\n                        assert(false, A.stringof);\n                }\n                return true;\n            }\n            return false;\n        }\n\n        switch (selector)\n        {\n        case OpID.getTypeInfo:\n            *cast(TypeInfo *) parm = typeid(A);\n            break;\n        case OpID.copyOut:\n            auto target = cast(VariantN *) parm;\n            assert(target);\n\n            static if (target.size < A.sizeof)\n            {\n                if (target.type.tsize < A.sizeof)\n                {\n                    static if (is(A == U[n], U, size_t n))\n                    {\n                        A* p = cast(A*)(new U[n]).ptr;\n                    }\n                    else\n                    {\n                        A* p = new A;\n                    }\n                    *cast(A**)&target.store = p;\n                }\n            }\n            tryPutting(zis, typeid(A), cast(void*) getPtr(&target.store))\n                || assert(false);\n            target.fptr = &handler!(A);\n            break;\n        case OpID.get:\n            auto t = * cast(Tuple!(TypeInfo, void*)*) parm;\n            return !tryPutting(zis, t[0], t[1]);\n        case OpID.testConversion:\n            return !tryPutting(null, *cast(TypeInfo*) parm, null);\n        case OpID.compare:\n        case OpID.equals:\n            auto rhsP = cast(VariantN *) parm;\n            auto rhsType = rhsP.type;\n            // Are we the same?\n            if (rhsType == typeid(A))\n            {\n                // cool! Same type!\n                auto rhsPA = getPtr(&rhsP.store);\n                return compare(rhsPA, zis, selector);\n            }\n            else if (rhsType == typeid(void))\n            {\n                // No support for ordering comparisons with\n                // uninitialized vars\n                return ptrdiff_t.min;\n            }\n            VariantN temp;\n            // Do I convert to rhs?\n            if (tryPutting(zis, rhsType, &temp.store))\n            {\n                // cool, I do; temp's store contains my data in rhs's type!\n                // also fix up its fptr\n                temp.fptr = rhsP.fptr;\n                // now lhsWithRhsType is a full-blown VariantN of rhs's type\n                if (selector == OpID.compare)\n                    return temp.opCmp(*rhsP);\n                else\n                    return temp.opEquals(*rhsP) ? 0 : 1;\n            }\n            // Does rhs convert to zis?\n            auto t = tuple(typeid(A), &temp.store);\n            if (rhsP.fptr(OpID.get, &rhsP.store, &t) == 0)\n            {\n                // cool! Now temp has rhs in my type!\n                auto rhsPA = getPtr(&temp.store);\n                return compare(rhsPA, zis, selector);\n            }\n            return ptrdiff_t.min; // dunno\n        case OpID.toString:\n            auto target = cast(string*) parm;\n            static if (is(typeof(to!(string)(*zis))))\n            {\n                *target = to!(string)(*zis);\n                break;\n            }\n            // TODO: The following test evaluates to true for shared objects.\n            //       Use __traits for now until this is sorted out.\n            // else static if (is(typeof((*zis).toString)))\n            else static if (__traits(compiles, {(*zis).toString();}))\n            {\n                *target = (*zis).toString();\n                break;\n            }\n            else\n            {\n                throw new VariantException(typeid(A), typeid(string));\n            }\n\n        case OpID.index:\n            auto result = cast(Variant*) parm;\n            static if (isArray!(A) && !is(Unqual!(typeof(A.init[0])) == void))\n            {\n                // array type; input and output are the same VariantN\n                size_t index = result.convertsTo!(int)\n                    ? result.get!(int) : result.get!(size_t);\n                *result = (*zis)[index];\n                break;\n            }\n            else static if (isAssociativeArray!(A))\n            {\n                *result = (*zis)[result.get!(typeof(A.init.keys[0]))];\n                break;\n            }\n            else\n            {\n                throw new VariantException(typeid(A), result[0].type);\n            }\n\n        case OpID.indexAssign:\n            // array type; result comes first, index comes second\n            auto args = cast(Variant*) parm;\n            static if (isArray!(A) && is(typeof((*zis)[0] = (*zis)[0])))\n            {\n                size_t index = args[1].convertsTo!(int)\n                    ? args[1].get!(int) : args[1].get!(size_t);\n                (*zis)[index] = args[0].get!(typeof((*zis)[0]));\n                break;\n            }\n            else static if (isAssociativeArray!(A))\n            {\n                (*zis)[args[1].get!(typeof(A.init.keys[0]))]\n                    = args[0].get!(typeof(A.init.values[0]));\n                break;\n            }\n            else\n            {\n                throw new VariantException(typeid(A), args[0].type);\n            }\n\n        case OpID.catAssign:\n            static if (!is(Unqual!(typeof((*zis)[0])) == void) && is(typeof((*zis)[0])) && is(typeof((*zis) ~= *zis)))\n            {\n                // array type; parm is the element to append\n                auto arg = cast(Variant*) parm;\n                alias E = typeof((*zis)[0]);\n                if (arg[0].convertsTo!(E))\n                {\n                    // append one element to the array\n                    (*zis) ~= [ arg[0].get!(E) ];\n                }\n                else\n                {\n                    // append a whole array to the array\n                    (*zis) ~= arg[0].get!(A);\n                }\n                break;\n            }\n            else\n            {\n                throw new VariantException(typeid(A), typeid(void[]));\n            }\n\n        case OpID.length:\n            static if (isArray!(A) || isAssociativeArray!(A))\n            {\n                return zis.length;\n            }\n            else\n            {\n                throw new VariantException(typeid(A), typeid(void[]));\n            }\n\n        case OpID.apply:\n            static if (!isFunctionPointer!A && !isDelegate!A)\n            {\n                import std.conv : text;\n                import std.exception : enforce;\n                enforce(0, text(\"Cannot apply `()' to a value of type `\",\n                                A.stringof, \"'.\"));\n            }\n            else\n            {\n                import std.conv : text;\n                import std.exception : enforce;\n                alias ParamTypes = Parameters!A;\n                auto p = cast(Variant*) parm;\n                auto argCount = p.get!size_t;\n                // To assign the tuple we need to use the unqualified version,\n                // otherwise we run into issues such as with const values.\n                // We still get the actual type from the Variant though\n                // to ensure that we retain const correctness.\n                Tuple!(staticMap!(Unqual, ParamTypes)) t;\n                enforce(t.length == argCount,\n                        text(\"Argument count mismatch: \",\n                             A.stringof, \" expects \", t.length,\n                             \" argument(s), not \", argCount, \".\"));\n                auto variantArgs = p[1 .. argCount + 1];\n                foreach (i, T; ParamTypes)\n                {\n                    t[i] = cast() variantArgs[i].get!T;\n                }\n\n                auto args = cast(Tuple!(ParamTypes))t;\n                static if (is(ReturnType!A == void))\n                {\n                    (*zis)(args.expand);\n                    *p = Variant.init; // void returns uninitialized Variant.\n                }\n                else\n                {\n                    *p = (*zis)(args.expand);\n                }\n            }\n            break;\n\n        case OpID.postblit:\n            static if (hasElaborateCopyConstructor!A)\n            {\n                zis.__xpostblit();\n            }\n            break;\n\n        case OpID.destruct:\n            static if (hasElaborateDestructor!A)\n            {\n                zis.__xdtor();\n            }\n            break;\n\n        default: assert(false);\n        }\n        return 0;\n    }\n\npublic:\n    /** Constructs a `VariantN` value given an argument of a\n     * generic type. Statically rejects disallowed types.\n     */\n\n    this(T)(T value)\n    {\n        static assert(allowed!(T), \"Cannot store a \" ~ T.stringof\n            ~ \" in a \" ~ VariantN.stringof);\n        opAssign(value);\n    }\n\n    /// Allows assignment from a subset algebraic type\n    this(T : VariantN!(tsize, Types), size_t tsize, Types...)(T value)\n        if (!is(T : VariantN) && Types.length > 0 && allSatisfy!(allowed, Types))\n    {\n        opAssign(value);\n    }\n\n    static if (!AllowedTypes.length || anySatisfy!(hasElaborateCopyConstructor, AllowedTypes))\n    {\n        this(this)\n        {\n            fptr(OpID.postblit, &store, null);\n        }\n    }\n\n    static if (!AllowedTypes.length || anySatisfy!(hasElaborateDestructor, AllowedTypes))\n    {\n        ~this()\n        {\n            // Infer the safety of the provided types\n            static if (AllowedTypes.length)\n            {\n                if (0)\n                {\n                    AllowedTypes var;\n                }\n            }\n            (() @trusted => fptr(OpID.destruct, &store, null))();\n        }\n    }\n\n    /** Assigns a `VariantN` from a generic\n     * argument. Statically rejects disallowed types. */\n\n    VariantN opAssign(T)(T rhs)\n    {\n        //writeln(typeid(rhs));\n        static assert(allowed!(T), \"Cannot store a \" ~ T.stringof\n            ~ \" in a \" ~ VariantN.stringof ~ \". Valid types are \"\n                ~ AllowedTypes.stringof);\n\n        static if (is(T : VariantN))\n        {\n            rhs.fptr(OpID.copyOut, &rhs.store, &this);\n        }\n        else static if (is(T : const(VariantN)))\n        {\n            static assert(false,\n                    \"Assigning Variant objects from const Variant\"~\n                    \" objects is currently not supported.\");\n        }\n        else\n        {\n            static if (!AllowedTypes.length || anySatisfy!(hasElaborateDestructor, AllowedTypes))\n            {\n                // Assignment should destruct previous value\n                fptr(OpID.destruct, &store, null);\n            }\n\n            static if (T.sizeof <= size)\n            {\n                import core.stdc.string : memcpy;\n                // rhs has already been copied onto the stack, so even if T is\n                // shared, it's not really shared. Therefore, we can safely\n                // remove the shared qualifier when copying, as we are only\n                // copying from the unshared stack.\n                //\n                // In addition, the storage location is not accessible outside\n                // the Variant, so even if shared data is stored there, it's\n                // not really shared, as it's copied out as well.\n                memcpy(&store, cast(const(void*)) &rhs, rhs.sizeof);\n                static if (hasElaborateCopyConstructor!T)\n                {\n                    // Safer than using typeid's postblit function because it\n                    // type-checks the postblit function against the qualifiers\n                    // of the type.\n                    (cast(T*)&store).__xpostblit();\n                }\n            }\n            else\n            {\n                import core.stdc.string : memcpy;\n                static if (__traits(compiles, {new T(T.init);}))\n                {\n                    auto p = new T(rhs);\n                }\n                else static if (is(T == U[n], U, size_t n))\n                {\n                    auto p = cast(T*)(new U[n]).ptr;\n                    *p = rhs;\n                }\n                else\n                {\n                    auto p = new T;\n                    *p = rhs;\n                }\n                memcpy(&store, &p, p.sizeof);\n            }\n            fptr = &handler!(T);\n        }\n        return this;\n    }\n\n    // Allow assignment from another variant which is a subset of this one\n    VariantN opAssign(T : VariantN!(tsize, Types), size_t tsize, Types...)(T rhs)\n        if (!is(T : VariantN) && Types.length > 0 && allSatisfy!(allowed, Types))\n    {\n        // discover which type rhs is actually storing\n        foreach (V; T.AllowedTypes)\n            if (rhs.type == typeid(V))\n                return this = rhs.get!V;\n        assert(0, T.AllowedTypes.stringof);\n    }\n\n\n    Variant opCall(P...)(auto ref P params)\n    {\n        Variant[P.length + 1] pack;\n        pack[0] = P.length;\n        foreach (i, _; params)\n        {\n            pack[i + 1] = params[i];\n        }\n        fptr(OpID.apply, &store, &pack);\n        return pack[0];\n    }\n\n    /** Returns true if and only if the `VariantN` object\n     * holds a valid value (has been initialized with, or assigned\n     * from, a valid value).\n     */\n    @property bool hasValue() const pure nothrow\n    {\n        // @@@BUG@@@ in compiler, the cast shouldn't be needed\n        return cast(typeof(&handler!(void))) fptr != &handler!(void);\n    }\n\n    ///\n    version (unittest)\n    @system unittest\n    {\n        Variant a;\n        assert(!a.hasValue);\n        Variant b;\n        a = b;\n        assert(!a.hasValue); // still no value\n        a = 5;\n        assert(a.hasValue);\n    }\n\n    /**\n     * If the `VariantN` object holds a value of the\n     * $(I exact) type `T`, returns a pointer to that\n     * value. Otherwise, returns `null`. In cases\n     * where `T` is statically disallowed, $(D\n     * peek) will not compile.\n     */\n    @property inout(T)* peek(T)() inout\n    {\n        static if (!is(T == void))\n            static assert(allowed!(T), \"Cannot store a \" ~ T.stringof\n                    ~ \" in a \" ~ VariantN.stringof);\n        if (type != typeid(T))\n            return null;\n        static if (T.sizeof <= size)\n            return cast(inout T*)&store;\n        else\n            return *cast(inout T**)&store;\n    }\n\n    ///\n    version (unittest)\n    @system unittest\n    {\n        Variant a = 5;\n        auto b = a.peek!(int);\n        assert(b !is null);\n        *b = 6;\n        assert(a == 6);\n    }\n\n    /**\n     * Returns the `typeid` of the currently held value.\n     */\n\n    @property TypeInfo type() const nothrow @trusted\n    {\n        scope(failure) assert(0);\n\n        TypeInfo result;\n        fptr(OpID.getTypeInfo, null, &result);\n        return result;\n    }\n\n    /**\n     * Returns `true` if and only if the `VariantN`\n     * object holds an object implicitly convertible to type `T`.\n     * Implicit convertibility is defined as per\n     * $(REF_ALTTEXT ImplicitConversionTargets, ImplicitConversionTargets, std,traits).\n     */\n\n    @property bool convertsTo(T)() const\n    {\n        TypeInfo info = typeid(T);\n        return fptr(OpID.testConversion, null, &info) == 0;\n    }\n\n    /**\n    Returns the value stored in the `VariantN` object, either by specifying the\n    needed type or the index in the list of allowed types. The latter overload\n    only applies to bounded variants (e.g. $(LREF Algebraic)).\n\n    Params:\n    T = The requested type. The currently stored value must implicitly convert\n    to the requested type, in fact `DecayStaticToDynamicArray!T`. If an\n    implicit conversion is not possible, throws a `VariantException`.\n    index = The index of the type among `AllowedTypesParam`, zero-based.\n     */\n    @property inout(T) get(T)() inout\n    {\n        inout(T) result = void;\n        static if (is(T == shared))\n            alias R = shared Unqual!T;\n        else\n            alias R = Unqual!T;\n        auto buf = tuple(typeid(T), cast(R*)&result);\n\n        if (fptr(OpID.get, cast(ubyte[size]*) &store, &buf))\n        {\n            throw new VariantException(type, typeid(T));\n        }\n        return result;\n    }\n\n    /// Ditto\n    @property auto get(uint index)() inout\n    if (index < AllowedTypes.length)\n    {\n        foreach (i, T; AllowedTypes)\n        {\n            static if (index == i) return get!T;\n        }\n        assert(0);\n    }\n\n    /**\n     * Returns the value stored in the `VariantN` object,\n     * explicitly converted (coerced) to the requested type $(D\n     * T). If `T` is a string type, the value is formatted as\n     * a string. If the `VariantN` object is a string, a\n     * parse of the string to type `T` is attempted. If a\n     * conversion is not possible, throws a $(D\n     * VariantException).\n     */\n\n    @property T coerce(T)()\n    {\n        import std.conv : to, text;\n        static if (isNumeric!T || isBoolean!T)\n        {\n            if (convertsTo!real)\n            {\n                // maybe optimize this fella; handle ints separately\n                return to!T(get!real);\n            }\n            else if (convertsTo!(const(char)[]))\n            {\n                return to!T(get!(const(char)[]));\n            }\n            // I'm not sure why this doesn't convert to const(char),\n            // but apparently it doesn't (probably a deeper bug).\n            //\n            // Until that is fixed, this quick addition keeps a common\n            // function working. \"10\".coerce!int ought to work.\n            else if (convertsTo!(immutable(char)[]))\n            {\n                return to!T(get!(immutable(char)[]));\n            }\n            else\n            {\n                import std.exception : enforce;\n                enforce(false, text(\"Type \", type, \" does not convert to \",\n                                typeid(T)));\n                assert(0);\n            }\n        }\n        else static if (is(T : Object))\n        {\n            return to!(T)(get!(Object));\n        }\n        else static if (isSomeString!(T))\n        {\n            return to!(T)(toString());\n        }\n        else\n        {\n            // Fix for bug 1649\n            static assert(false, \"unsupported type for coercion\");\n        }\n    }\n\n    /**\n     * Formats the stored value as a string.\n     */\n\n    string toString()\n    {\n        string result;\n        fptr(OpID.toString, &store, &result) == 0 || assert(false);\n        return result;\n    }\n\n    /**\n     * Comparison for equality used by the \"==\" and \"!=\"  operators.\n     */\n\n    // returns 1 if the two are equal\n    bool opEquals(T)(auto ref T rhs) const\n    if (allowed!T || is(Unqual!T == VariantN))\n    {\n        static if (is(Unqual!T == VariantN))\n            alias temp = rhs;\n        else\n            auto temp = VariantN(rhs);\n        return !fptr(OpID.equals, cast(ubyte[size]*) &store,\n                     cast(void*) &temp);\n    }\n\n    // workaround for bug 10567 fix\n    int opCmp(ref const VariantN rhs) const\n    {\n        return (cast() this).opCmp!(VariantN)(cast() rhs);\n    }\n\n    /**\n     * Ordering comparison used by the \"<\", \"<=\", \">\", and \">=\"\n     * operators. In case comparison is not sensible between the held\n     * value and `rhs`, an exception is thrown.\n     */\n\n    int opCmp(T)(T rhs)\n    if (allowed!T)  // includes T == VariantN\n    {\n        static if (is(T == VariantN))\n            alias temp = rhs;\n        else\n            auto temp = VariantN(rhs);\n        auto result = fptr(OpID.compare, &store, &temp);\n        if (result == ptrdiff_t.min)\n        {\n            throw new VariantException(type, temp.type);\n        }\n\n        assert(result >= -1 && result <= 1);  // Should be true for opCmp.\n        return cast(int) result;\n    }\n\n    /**\n     * Computes the hash of the held value.\n     */\n\n    size_t toHash() const nothrow @safe\n    {\n        return type.getHash(&store);\n    }\n\n    private VariantN opArithmetic(T, string op)(T other)\n    {\n        static if (isInstanceOf!(.VariantN, T))\n        {\n            string tryUseType(string tp)\n            {\n                import std.format : format;\n                return q{\n                    static if (allowed!%1$s && T.allowed!%1$s)\n                        if (convertsTo!%1$s && other.convertsTo!%1$s)\n                            return VariantN(get!%1$s %2$s other.get!%1$s);\n                }.format(tp, op);\n            }\n\n            mixin(tryUseType(\"uint\"));\n            mixin(tryUseType(\"int\"));\n            mixin(tryUseType(\"ulong\"));\n            mixin(tryUseType(\"long\"));\n            mixin(tryUseType(\"float\"));\n            mixin(tryUseType(\"double\"));\n            mixin(tryUseType(\"real\"));\n        }\n        else\n        {\n            static if (allowed!T)\n                if (auto pv = peek!T) return VariantN(mixin(\"*pv \" ~ op ~ \" other\"));\n            static if (allowed!uint && is(typeof(T.max) : uint) && isUnsigned!T)\n                if (convertsTo!uint) return VariantN(mixin(\"get!(uint) \" ~ op ~ \" other\"));\n            static if (allowed!int && is(typeof(T.max) : int) && !isUnsigned!T)\n                if (convertsTo!int) return VariantN(mixin(\"get!(int) \" ~ op ~ \" other\"));\n            static if (allowed!ulong && is(typeof(T.max) : ulong) && isUnsigned!T)\n                if (convertsTo!ulong) return VariantN(mixin(\"get!(ulong) \" ~ op ~ \" other\"));\n            static if (allowed!long && is(typeof(T.max) : long) && !isUnsigned!T)\n                if (convertsTo!long) return VariantN(mixin(\"get!(long) \" ~ op ~ \" other\"));\n            static if (allowed!float && is(T : float))\n                if (convertsTo!float) return VariantN(mixin(\"get!(float) \" ~ op ~ \" other\"));\n            static if (allowed!double && is(T : double))\n                if (convertsTo!double) return VariantN(mixin(\"get!(double) \" ~ op ~ \" other\"));\n            static if (allowed!real && is (T : real))\n                if (convertsTo!real) return VariantN(mixin(\"get!(real) \" ~ op ~ \" other\"));\n        }\n\n        throw new VariantException(\"No possible match found for VariantN \"~op~\" \"~T.stringof);\n    }\n\n    private VariantN opLogic(T, string op)(T other)\n    {\n        VariantN result;\n        static if (is(T == VariantN))\n        {\n            if (convertsTo!(uint) && other.convertsTo!(uint))\n                result = mixin(\"get!(uint) \" ~ op ~ \" other.get!(uint)\");\n            else if (convertsTo!(int) && other.convertsTo!(int))\n                result = mixin(\"get!(int) \" ~ op ~ \" other.get!(int)\");\n            else if (convertsTo!(ulong) && other.convertsTo!(ulong))\n                result = mixin(\"get!(ulong) \" ~ op ~ \" other.get!(ulong)\");\n            else\n                result = mixin(\"get!(long) \" ~ op ~ \" other.get!(long)\");\n        }\n        else\n        {\n            if (is(typeof(T.max) : uint) && T.min == 0 && convertsTo!(uint))\n                result = mixin(\"get!(uint) \" ~ op ~ \" other\");\n            else if (is(typeof(T.max) : int) && T.min < 0 && convertsTo!(int))\n                result = mixin(\"get!(int) \" ~ op ~ \" other\");\n            else if (is(typeof(T.max) : ulong) && T.min == 0\n                     && convertsTo!(ulong))\n                result = mixin(\"get!(ulong) \" ~ op ~ \" other\");\n            else\n                result = mixin(\"get!(long) \" ~ op ~ \" other\");\n        }\n        return result;\n    }\n\n    /**\n     * Arithmetic between `VariantN` objects and numeric\n     * values. All arithmetic operations return a `VariantN`\n     * object typed depending on the types of both values\n     * involved. The conversion rules mimic D's built-in rules for\n     * arithmetic conversions.\n     */\n    VariantN opBinary(string op, T)(T rhs)\n    if ((op == \"+\" || op == \"-\" || op == \"*\" || op == \"/\" || op == \"^^\" || op == \"%\") &&\n        is(typeof(opArithmetic!(T, op)(rhs))))\n    { return opArithmetic!(T, op)(rhs); }\n    ///ditto\n    VariantN opBinary(string op, T)(T rhs)\n    if ((op == \"&\" || op == \"|\" || op == \"^\" || op == \">>\" || op == \"<<\" || op == \">>>\") &&\n        is(typeof(opLogic!(T, op)(rhs))))\n    { return opLogic!(T, op)(rhs); }\n    ///ditto\n    VariantN opBinaryRight(string op, T)(T lhs)\n    if ((op == \"+\" || op == \"*\") &&\n        is(typeof(opArithmetic!(T, op)(lhs))))\n    { return opArithmetic!(T, op)(lhs); }\n    ///ditto\n    VariantN opBinaryRight(string op, T)(T lhs)\n    if ((op == \"&\" || op == \"|\" || op == \"^\") &&\n        is(typeof(opLogic!(T, op)(lhs))))\n    { return opLogic!(T, op)(lhs); }\n    ///ditto\n    VariantN opCat(T)(T rhs)\n    {\n        auto temp = this;\n        temp ~= rhs;\n        return temp;\n    }\n    // ///ditto\n    // VariantN opCat_r(T)(T rhs)\n    // {\n    //     VariantN temp = rhs;\n    //     temp ~= this;\n    //     return temp;\n    // }\n\n    ///ditto\n    VariantN opOpAssign(string op, T)(T rhs)\n    {\n        static if (op != \"~\")\n        {\n            mixin(\"return this = this\" ~ op ~ \"rhs;\");\n        }\n        else\n        {\n            auto toAppend = Variant(rhs);\n            fptr(OpID.catAssign, &store, &toAppend) == 0 || assert(false);\n            return this;\n        }\n    }\n\n    /**\n     * Array and associative array operations. If a $(D\n     * VariantN) contains an (associative) array, it can be indexed\n     * into. Otherwise, an exception is thrown.\n     */\n    inout(Variant) opIndex(K)(K i) inout\n    {\n        auto result = Variant(i);\n        fptr(OpID.index, cast(ubyte[size]*) &store, &result) == 0 || assert(false);\n        return result;\n    }\n\n    ///\n    version (unittest)\n    @system unittest\n    {\n        Variant a = new int[10];\n        a[5] = 42;\n        assert(a[5] == 42);\n        a[5] += 8;\n        assert(a[5] == 50);\n\n        int[int] hash = [ 42:24 ];\n        a = hash;\n        assert(a[42] == 24);\n        a[42] /= 2;\n        assert(a[42] == 12);\n    }\n\n    /// ditto\n    Variant opIndexAssign(T, N)(T value, N i)\n    {\n        static if (AllowedTypes.length && !isInstanceOf!(.VariantN, T))\n        {\n            enum canAssign(U) = __traits(compiles, (U u){ u[i] = value; });\n            static assert(anySatisfy!(canAssign, AllowedTypes),\n                \"Cannot assign \" ~ T.stringof ~ \" to \" ~ VariantN.stringof ~\n                \" indexed with \" ~ N.stringof);\n        }\n        Variant[2] args = [ Variant(value), Variant(i) ];\n        fptr(OpID.indexAssign, &store, &args) == 0 || assert(false);\n        return args[0];\n    }\n\n    /// ditto\n    Variant opIndexOpAssign(string op, T, N)(T value, N i)\n    {\n        return opIndexAssign(mixin(`opIndex(i)` ~ op ~ `value`), i);\n    }\n\n    /** If the `VariantN` contains an (associative) array,\n     * returns the _length of that array. Otherwise, throws an\n     * exception.\n     */\n    @property size_t length()\n    {\n        return cast(size_t) fptr(OpID.length, &store, null);\n    }\n\n    /**\n       If the `VariantN` contains an array, applies `dg` to each\n       element of the array in turn. Otherwise, throws an exception.\n     */\n    int opApply(Delegate)(scope Delegate dg) if (is(Delegate == delegate))\n    {\n        alias A = Parameters!(Delegate)[0];\n        if (type == typeid(A[]))\n        {\n            auto arr = get!(A[]);\n            foreach (ref e; arr)\n            {\n                if (dg(e)) return 1;\n            }\n        }\n        else static if (is(A == VariantN))\n        {\n            foreach (i; 0 .. length)\n            {\n                // @@@TODO@@@: find a better way to not confuse\n                // clients who think they change values stored in the\n                // Variant when in fact they are only changing tmp.\n                auto tmp = this[i];\n                debug scope(exit) assert(tmp == this[i]);\n                if (dg(tmp)) return 1;\n            }\n        }\n        else\n        {\n            import std.conv : text;\n            import std.exception : enforce;\n            enforce(false, text(\"Variant type \", type,\n                            \" not iterable with values of type \",\n                            A.stringof));\n        }\n        return 0;\n    }\n}\n\n///\n@system unittest\n{\n    alias Var = VariantN!(maxSize!(int, double, string));\n\n    Var a; // Must assign before use, otherwise exception ensues\n    // Initialize with an integer; make the type int\n    Var b = 42;\n    assert(b.type == typeid(int));\n    // Peek at the value\n    assert(b.peek!(int) !is null && *b.peek!(int) == 42);\n    // Automatically convert per language rules\n    auto x = b.get!(real);\n\n    // Assign any other type, including other variants\n    a = b;\n    a = 3.14;\n    assert(a.type == typeid(double));\n    // Implicit conversions work just as with built-in types\n    assert(a < b);\n    // Check for convertibility\n    assert(!a.convertsTo!(int)); // double not convertible to int\n    // Strings and all other arrays are supported\n    a = \"now I'm a string\";\n    assert(a == \"now I'm a string\");\n}\n\n/// can also assign arrays\n@system unittest\n{\n    alias Var = VariantN!(maxSize!(int[]));\n\n    Var a = new int[42];\n    assert(a.length == 42);\n    a[5] = 7;\n    assert(a[5] == 7);\n}\n\n/// Can also assign class values\n@system unittest\n{\n    alias Var = VariantN!(maxSize!(int*)); // classes are pointers\n    Var a;\n\n    class Foo {}\n    auto foo = new Foo;\n    a = foo;\n    assert(*a.peek!(Foo) == foo); // and full type information is preserved\n}\n\n@system unittest\n{\n    import std.conv : to;\n    Variant v;\n    int foo() { return 42; }\n    v = &foo;\n    assert(v() == 42);\n\n    static int bar(string s) { return to!int(s); }\n    v = &bar;\n    assert(v(\"43\") == 43);\n}\n\n@system unittest\n{\n    int[int] hash = [ 42:24 ];\n    Variant v = hash;\n    assert(v[42] == 24);\n    v[42] = 5;\n    assert(v[42] == 5);\n}\n\n// opIndex with static arrays, issue 12771\n@system unittest\n{\n    int[4] elements = [0, 1, 2, 3];\n    Variant v = elements;\n    assert(v == elements);\n    assert(v[2] == 2);\n    assert(v[3] == 3);\n    v[2] = 6;\n    assert(v[2] == 6);\n    assert(v != elements);\n}\n\n@system unittest\n{\n    import std.exception : assertThrown;\n    Algebraic!(int[]) v = [2, 2];\n\n    assert(v == [2, 2]);\n    v[0] = 1;\n    assert(v[0] == 1);\n    assert(v != [2, 2]);\n\n    // opIndexAssign from Variant\n    v[1] = v[0];\n    assert(v[1] == 1);\n\n    static assert(!__traits(compiles, (v[1] = null)));\n    assertThrown!VariantException(v[1] = Variant(null));\n}\n\n//Issue# 10879\n@system unittest\n{\n    int[10] arr = [1,2,3,4,5,6,7,8,9,10];\n    Variant v1 = arr;\n    Variant v2;\n    v2 = arr;\n    assert(v1 == arr);\n    assert(v2 == arr);\n    foreach (i, e; arr)\n    {\n        assert(v1[i] == e);\n        assert(v2[i] == e);\n    }\n    static struct LargeStruct\n    {\n        int[100] data;\n    }\n    LargeStruct ls;\n    ls.data[] = 4;\n    v1 = ls;\n    Variant v3 = ls;\n    assert(v1 == ls);\n    assert(v3 == ls);\n}\n\n//Issue# 8195\n@system unittest\n{\n    struct S\n    {\n        int a;\n        long b;\n        string c;\n        real d = 0.0;\n        bool e;\n    }\n\n    static assert(S.sizeof >= Variant.sizeof);\n    alias Types = AliasSeq!(string, int, S);\n    alias MyVariant = VariantN!(maxSize!Types, Types);\n\n    auto v = MyVariant(S.init);\n    assert(v == S.init);\n}\n\n// Issue #10961\n@system unittest\n{\n    // Primarily test that we can assign a void[] to a Variant.\n    void[] elements = cast(void[])[1, 2, 3];\n    Variant v = elements;\n    void[] returned = v.get!(void[]);\n    assert(returned == elements);\n}\n\n// Issue #13352\n@system unittest\n{\n    alias TP = Algebraic!(long);\n    auto a = TP(1L);\n    auto b = TP(2L);\n    assert(!TP.allowed!ulong);\n    assert(a + b == 3L);\n    assert(a + 2 == 3L);\n    assert(1 + b == 3L);\n\n    alias TP2 = Algebraic!(long, string);\n    auto c = TP2(3L);\n    assert(a + c == 4L);\n}\n\n// Issue #13354\n@system unittest\n{\n    alias A = Algebraic!(string[]);\n    A a = [\"a\", \"b\"];\n    assert(a[0] == \"a\");\n    assert(a[1] == \"b\");\n    a[1] = \"c\";\n    assert(a[1] == \"c\");\n\n    alias AA = Algebraic!(int[string]);\n    AA aa = [\"a\": 1, \"b\": 2];\n    assert(aa[\"a\"] == 1);\n    assert(aa[\"b\"] == 2);\n    aa[\"b\"] = 3;\n    assert(aa[\"b\"] == 3);\n}\n\n// Issue #14198\n@system unittest\n{\n    Variant a = true;\n    assert(a.type == typeid(bool));\n}\n\n// Issue #14233\n@system unittest\n{\n    alias Atom = Algebraic!(string, This[]);\n\n    Atom[] values = [];\n    auto a = Atom(values);\n}\n\npure nothrow @nogc\n@system unittest\n{\n    Algebraic!(int, double) a;\n    a = 100;\n    a = 1.0;\n}\n\n// Issue 14457\n@system unittest\n{\n    alias A = Algebraic!(int, float, double);\n    alias B = Algebraic!(int, float);\n\n    A a = 1;\n    B b = 6f;\n    a = b;\n\n    assert(a.type == typeid(float));\n    assert(a.get!float == 6f);\n}\n\n// Issue 14585\n@system unittest\n{\n    static struct S\n    {\n        int x = 42;\n        ~this() {assert(x == 42);}\n    }\n    Variant(S()).get!S;\n}\n\n// Issue 14586\n@system unittest\n{\n    const Variant v = new immutable Object;\n    v.get!(immutable Object);\n}\n\n@system unittest\n{\n    static struct S\n    {\n        T opCast(T)() {assert(false);}\n    }\n    Variant v = S();\n    v.get!S;\n}\n\n// issue 13262\n@system unittest\n{\n    static void fun(T)(Variant v){\n        T x;\n        v = x;\n        auto r = v.get!(T);\n    }\n    Variant v;\n    fun!(shared(int))(v);\n    fun!(shared(int)[])(v);\n\n    static struct S1\n    {\n        int c;\n        string a;\n    }\n\n    static struct S2\n    {\n        string a;\n        shared int[] b;\n    }\n\n    static struct S3\n    {\n        string a;\n        shared int[] b;\n        int c;\n    }\n\n    fun!(S1)(v);\n    fun!(shared(S1))(v);\n    fun!(S2)(v);\n    fun!(shared(S2))(v);\n    fun!(S3)(v);\n    fun!(shared(S3))(v);\n\n    // ensure structs that are shared, but don't have shared postblits\n    // can't be used.\n    static struct S4\n    {\n        int x;\n        this(this) {x = 0;}\n    }\n\n    fun!(S4)(v);\n    static assert(!is(typeof(fun!(shared(S4))(v))));\n}\n\n@safe unittest\n{\n    Algebraic!(int) x;\n\n    static struct SafeS\n    {\n        @safe ~this() {}\n    }\n\n    Algebraic!(SafeS) y;\n}\n\n/**\n_Algebraic data type restricted to a closed set of possible\ntypes. It's an alias for $(LREF VariantN) with an\nappropriately-constructed maximum size. `Algebraic` is\nuseful when it is desirable to restrict what a discriminated type\ncould hold to the end of defining simpler and more efficient\nmanipulation.\n\n*/\ntemplate Algebraic(T...)\n{\n    alias Algebraic = VariantN!(maxSize!T, T);\n}\n\n///\n@system unittest\n{\n    auto v = Algebraic!(int, double, string)(5);\n    assert(v.peek!(int));\n    v = 3.14;\n    assert(v.peek!(double));\n    // auto x = v.peek!(long); // won't compile, type long not allowed\n    // v = '1'; // won't compile, type char not allowed\n}\n\n/**\n$(H4 Self-Referential Types)\n\nA useful and popular use of algebraic data structures is for defining $(LUCKY\nself-referential data structures), i.e. structures that embed references to\nvalues of their own type within.\n\nThis is achieved with `Algebraic` by using `This` as a placeholder whenever a\nreference to the type being defined is needed. The `Algebraic` instantiation\nwill perform $(LINK2 https://en.wikipedia.org/wiki/Name_resolution_(programming_languages)#Alpha_renaming_to_make_name_resolution_trivial,\nalpha renaming) on its constituent types, replacing `This`\nwith the self-referenced type. The structure of the type involving `This` may\nbe arbitrarily complex.\n*/\n@system unittest\n{\n    import std.typecons : Tuple, tuple;\n\n    // A tree is either a leaf or a branch of two other trees\n    alias Tree(Leaf) = Algebraic!(Leaf, Tuple!(This*, This*));\n    Tree!int tree = tuple(new Tree!int(42), new Tree!int(43));\n    Tree!int* right = tree.get!1[1];\n    assert(*right == 43);\n\n    // An object is a double, a string, or a hash of objects\n    alias Obj = Algebraic!(double, string, This[string]);\n    Obj obj = \"hello\";\n    assert(obj.get!1 == \"hello\");\n    obj = 42.0;\n    assert(obj.get!0 == 42);\n    obj = [\"customer\": Obj(\"John\"), \"paid\": Obj(23.95)];\n    assert(obj.get!2[\"customer\"] == \"John\");\n}\n\nprivate struct FakeComplexReal\n{\n    real re, im;\n}\n\n/**\nAlias for $(LREF VariantN) instantiated with the largest size of `creal`,\n`char[]`, and `void delegate()`. This ensures that `Variant` is large enough\nto hold all of D's predefined types unboxed, including all numeric types,\npointers, delegates, and class references.  You may want to use\n`VariantN` directly with a different maximum size either for\nstoring larger types unboxed, or for saving memory.\n */\nalias Variant = VariantN!(maxSize!(FakeComplexReal, char[], void delegate()));\n\n///\n@system unittest\n{\n    Variant a; // Must assign before use, otherwise exception ensues\n    // Initialize with an integer; make the type int\n    Variant b = 42;\n    assert(b.type == typeid(int));\n    // Peek at the value\n    assert(b.peek!(int) !is null && *b.peek!(int) == 42);\n    // Automatically convert per language rules\n    auto x = b.get!(real);\n\n    // Assign any other type, including other variants\n    a = b;\n    a = 3.14;\n    assert(a.type == typeid(double));\n    // Implicit conversions work just as with built-in types\n    assert(a < b);\n    // Check for convertibility\n    assert(!a.convertsTo!(int)); // double not convertible to int\n    // Strings and all other arrays are supported\n    a = \"now I'm a string\";\n    assert(a == \"now I'm a string\");\n}\n\n/// can also assign arrays\n@system unittest\n{\n    Variant a = new int[42];\n    assert(a.length == 42);\n    a[5] = 7;\n    assert(a[5] == 7);\n}\n\n/// Can also assign class values\n@system unittest\n{\n    Variant a;\n\n    class Foo {}\n    auto foo = new Foo;\n    a = foo;\n    assert(*a.peek!(Foo) == foo); // and full type information is preserved\n}\n\n/**\n * Returns an array of variants constructed from `args`.\n *\n * This is by design. During construction the `Variant` needs\n * static type information about the type being held, so as to store a\n * pointer to function for fast retrieval.\n */\nVariant[] variantArray(T...)(T args)\n{\n    Variant[] result;\n    foreach (arg; args)\n    {\n        result ~= Variant(arg);\n    }\n    return result;\n}\n\n///\n@system unittest\n{\n    auto a = variantArray(1, 3.14, \"Hi!\");\n    assert(a[1] == 3.14);\n    auto b = Variant(a); // variant array as variant\n    assert(b[1] == 3.14);\n}\n\n/**\n * Thrown in three cases:\n *\n * $(OL $(LI An uninitialized `Variant` is used in any way except\n * assignment and `hasValue`;) $(LI A `get` or\n * `coerce` is attempted with an incompatible target type;)\n * $(LI A comparison between `Variant` objects of\n * incompatible types is attempted.))\n *\n */\n\n// @@@ BUG IN COMPILER. THE 'STATIC' BELOW SHOULD NOT COMPILE\nstatic class VariantException : Exception\n{\n    /// The source type in the conversion or comparison\n    TypeInfo source;\n    /// The target type in the conversion or comparison\n    TypeInfo target;\n    this(string s)\n    {\n        super(s);\n    }\n    this(TypeInfo source, TypeInfo target)\n    {\n        super(\"Variant: attempting to use incompatible types \"\n                            ~ source.toString()\n                            ~ \" and \" ~ target.toString());\n        this.source = source;\n        this.target = target;\n    }\n}\n\n///\n@system unittest\n{\n    import std.exception : assertThrown;\n\n    Variant v;\n\n    // uninitialized use\n    assertThrown!VariantException(v + 1);\n    assertThrown!VariantException(v.length);\n\n    // .get with an incompatible target type\n    assertThrown!VariantException(Variant(\"a\").get!int);\n\n    // comparison between incompatible types\n    assertThrown!VariantException(Variant(3) < Variant(\"a\"));\n}\n\n@system unittest\n{\n    alias W1 = This2Variant!(char, int, This[int]);\n    alias W2 = AliasSeq!(int, char[int]);\n    static assert(is(W1 == W2));\n\n    alias var_t = Algebraic!(void, string);\n    var_t foo = \"quux\";\n}\n\n@system unittest\n{\n     alias A = Algebraic!(real, This[], This[int], This[This]);\n     A v1, v2, v3;\n     v2 = 5.0L;\n     v3 = 42.0L;\n     //v1 = [ v2 ][];\n      auto v = v1.peek!(A[]);\n     //writeln(v[0]);\n     v1 = [ 9 : v3 ];\n     //writeln(v1);\n     v1 = [ v3 : v3 ];\n     //writeln(v1);\n}\n\n@system unittest\n{\n    import std.conv : ConvException;\n    import std.exception : assertThrown, collectException;\n    // try it with an oddly small size\n    VariantN!(1) test;\n    assert(test.size > 1);\n\n    // variantArray tests\n    auto heterogeneous = variantArray(1, 4.5, \"hi\");\n    assert(heterogeneous.length == 3);\n    auto variantArrayAsVariant = Variant(heterogeneous);\n    assert(variantArrayAsVariant[0] == 1);\n    assert(variantArrayAsVariant.length == 3);\n\n    // array tests\n    auto arr = Variant([1.2].dup);\n    auto e = arr[0];\n    assert(e == 1.2);\n    arr[0] = 2.0;\n    assert(arr[0] == 2);\n    arr ~= 4.5;\n    assert(arr[1] == 4.5);\n\n    // general tests\n    Variant a;\n    auto b = Variant(5);\n    assert(!b.peek!(real) && b.peek!(int));\n    // assign\n    a = *b.peek!(int);\n    // comparison\n    assert(a == b, a.type.toString() ~ \" \" ~ b.type.toString());\n    auto c = Variant(\"this is a string\");\n    assert(a != c);\n    // comparison via implicit conversions\n    a = 42; b = 42.0; assert(a == b);\n\n    // try failing conversions\n    bool failed = false;\n    try\n    {\n        auto d = c.get!(int);\n    }\n    catch (Exception e)\n    {\n        //writeln(stderr, e.toString);\n        failed = true;\n    }\n    assert(failed); // :o)\n\n    // toString tests\n    a = Variant(42); assert(a.toString() == \"42\");\n    a = Variant(42.22); assert(a.toString() == \"42.22\");\n\n    // coerce tests\n    a = Variant(42.22); assert(a.coerce!(int) == 42);\n    a = cast(short) 5; assert(a.coerce!(double) == 5);\n    a = Variant(\"10\"); assert(a.coerce!int == 10);\n\n    a = Variant(1);\n    assert(a.coerce!bool);\n    a = Variant(0);\n    assert(!a.coerce!bool);\n\n    a = Variant(1.0);\n    assert(a.coerce!bool);\n    a = Variant(0.0);\n    assert(!a.coerce!bool);\n    a = Variant(float.init);\n    assertThrown!ConvException(a.coerce!bool);\n\n    a = Variant(\"true\");\n    assert(a.coerce!bool);\n    a = Variant(\"false\");\n    assert(!a.coerce!bool);\n    a = Variant(\"\");\n    assertThrown!ConvException(a.coerce!bool);\n\n    // Object tests\n    class B1 {}\n    class B2 : B1 {}\n    a = new B2;\n    assert(a.coerce!(B1) !is null);\n    a = new B1;\n    assert(collectException(a.coerce!(B2) is null));\n    a = cast(Object) new B2; // lose static type info; should still work\n    assert(a.coerce!(B2) !is null);\n\n//     struct Big { int a[45]; }\n//     a = Big.init;\n\n    // hash\n    assert(a.toHash() != 0);\n}\n\n// tests adapted from\n// http://www.dsource.org/projects/tango/browser/trunk/tango/core/Variant.d?rev=2601\n@system unittest\n{\n    Variant v;\n\n    assert(!v.hasValue);\n    v = 42;\n    assert( v.peek!(int) );\n    assert( v.convertsTo!(long) );\n    assert( v.get!(int) == 42 );\n    assert( v.get!(long) == 42L );\n    assert( v.get!(ulong) == 42uL );\n\n    v = \"Hello, World!\";\n    assert( v.peek!(string) );\n\n    assert( v.get!(string) == \"Hello, World!\" );\n    assert(!is(char[] : wchar[]));\n    assert( !v.convertsTo!(wchar[]) );\n    assert( v.get!(string) == \"Hello, World!\" );\n\n    // Literal arrays are dynamically-typed\n    v = cast(int[4]) [1,2,3,4];\n    assert( v.peek!(int[4]) );\n    assert( v.get!(int[4]) == [1,2,3,4] );\n\n    {\n         v = [1,2,3,4,5];\n         assert( v.peek!(int[]) );\n         assert( v.get!(int[]) == [1,2,3,4,5] );\n    }\n\n    v = 3.1413;\n    assert( v.peek!(double) );\n    assert( v.convertsTo!(real) );\n    //@@@ BUG IN COMPILER: DOUBLE SHOULD NOT IMPLICITLY CONVERT TO FLOAT\n    assert( !v.convertsTo!(float) );\n    assert( *v.peek!(double) == 3.1413 );\n\n    auto u = Variant(v);\n    assert( u.peek!(double) );\n    assert( *u.peek!(double) == 3.1413 );\n\n    // operators\n    v = 38;\n    assert( v + 4 == 42 );\n    assert( 4 + v == 42 );\n    assert( v - 4 == 34 );\n    assert( Variant(4) - v == -34 );\n    assert( v * 2 == 76 );\n    assert( 2 * v == 76 );\n    assert( v / 2 == 19 );\n    assert( Variant(2) / v == 0 );\n    assert( v % 2 == 0 );\n    assert( Variant(2) % v == 2 );\n    assert( (v & 6) == 6 );\n    assert( (6 & v) == 6 );\n    assert( (v | 9) == 47 );\n    assert( (9 | v) == 47 );\n    assert( (v ^ 5) == 35 );\n    assert( (5 ^ v) == 35 );\n    assert( v << 1 == 76 );\n    assert( Variant(1) << Variant(2) == 4 );\n    assert( v >> 1 == 19 );\n    assert( Variant(4) >> Variant(2) == 1 );\n    assert( Variant(\"abc\") ~ \"def\" == \"abcdef\" );\n    assert( Variant(\"abc\") ~ Variant(\"def\") == \"abcdef\" );\n\n    v = 38;\n    v += 4;\n    assert( v == 42 );\n    v = 38; v -= 4; assert( v == 34 );\n    v = 38; v *= 2; assert( v == 76 );\n    v = 38; v /= 2; assert( v == 19 );\n    v = 38; v %= 2; assert( v == 0 );\n    v = 38; v &= 6; assert( v == 6 );\n    v = 38; v |= 9; assert( v == 47 );\n    v = 38; v ^= 5; assert( v == 35 );\n    v = 38; v <<= 1; assert( v == 76 );\n    v = 38; v >>= 1; assert( v == 19 );\n    v = 38; v += 1;  assert( v < 40 );\n\n    v = \"abc\";\n    v ~= \"def\";\n    assert( v == \"abcdef\", *v.peek!(char[]) );\n    assert( Variant(0) < Variant(42) );\n    assert( Variant(42) > Variant(0) );\n    assert( Variant(42) > Variant(0.1) );\n    assert( Variant(42.1) > Variant(1) );\n    assert( Variant(21) == Variant(21) );\n    assert( Variant(0) != Variant(42) );\n    assert( Variant(\"bar\") == Variant(\"bar\") );\n    assert( Variant(\"foo\") != Variant(\"bar\") );\n\n    {\n        auto v1 = Variant(42);\n        auto v2 = Variant(\"foo\");\n\n        int[Variant] hash;\n        hash[v1] = 0;\n        hash[v2] = 1;\n\n        assert( hash[v1] == 0 );\n        assert( hash[v2] == 1 );\n    }\n\n    {\n        int[char[]] hash;\n        hash[\"a\"] = 1;\n        hash[\"b\"] = 2;\n        hash[\"c\"] = 3;\n        Variant vhash = hash;\n\n        assert( vhash.get!(int[char[]])[\"a\"] == 1 );\n        assert( vhash.get!(int[char[]])[\"b\"] == 2 );\n        assert( vhash.get!(int[char[]])[\"c\"] == 3 );\n    }\n}\n\nversion (TestComplex)\ndeprecated\n@system unittest\n{\n    auto v3 = Variant(1+2.0i);\n    hash[v3] = 2;\n    assert( hash[v3] == 2 );\n}\n\n@system unittest\n{\n    // check comparisons incompatible with AllowedTypes\n    Algebraic!int v = 2;\n\n    assert(v == 2);\n    assert(v < 3);\n    static assert(!__traits(compiles, {v == long.max;}));\n    static assert(!__traits(compiles, {v == null;}));\n    static assert(!__traits(compiles, {v < long.max;}));\n    static assert(!__traits(compiles, {v > null;}));\n}\n\n@system unittest\n{\n    // bug 1558\n    Variant va=1;\n    Variant vb=-2;\n    assert((va+vb).get!(int) == -1);\n    assert((va-vb).get!(int) == 3);\n}\n\n@system unittest\n{\n    Variant a;\n    a=5;\n    Variant b;\n    b=a;\n    Variant[] c;\n    c = variantArray(1, 2, 3.0, \"hello\", 4);\n    assert(c[3] == \"hello\");\n}\n\n@system unittest\n{\n    Variant v = 5;\n    assert(!__traits(compiles, v.coerce!(bool delegate())));\n}\n\n\n@system unittest\n{\n    struct Huge {\n        real a, b, c, d, e, f, g;\n    }\n\n    Huge huge;\n    huge.e = 42;\n    Variant v;\n    v = huge;  // Compile time error.\n    assert(v.get!(Huge).e == 42);\n}\n\n@system unittest\n{\n    const x = Variant(42);\n    auto y1 = x.get!(const int);\n    // @@@BUG@@@\n    //auto y2 = x.get!(immutable int)();\n}\n\n// test iteration\n@system unittest\n{\n    auto v = Variant([ 1, 2, 3, 4 ][]);\n    auto j = 0;\n    foreach (int i; v)\n    {\n        assert(i == ++j);\n    }\n    assert(j == 4);\n}\n\n// test convertibility\n@system unittest\n{\n    auto v = Variant(\"abc\".dup);\n    assert(v.convertsTo!(char[]));\n}\n\n// http://d.puremagic.com/issues/show_bug.cgi?id=5424\n@system unittest\n{\n    interface A {\n        void func1();\n    }\n    static class AC: A {\n        void func1() {\n        }\n    }\n\n    A a = new AC();\n    a.func1();\n    Variant b = Variant(a);\n}\n\n@system unittest\n{\n    // bug 7070\n    Variant v;\n    v = null;\n}\n\n// Class and interface opEquals, issue 12157\n@system unittest\n{\n    class Foo { }\n\n    class DerivedFoo : Foo { }\n\n    Foo f1 = new Foo();\n    Foo f2 = new DerivedFoo();\n\n    Variant v1 = f1, v2 = f2;\n    assert(v1 == f1);\n    assert(v1 != new Foo());\n    assert(v1 != f2);\n    assert(v2 != v1);\n    assert(v2 == f2);\n}\n\n// Const parameters with opCall, issue 11361.\n@system unittest\n{\n    static string t1(string c) {\n        return c ~ \"a\";\n    }\n\n    static const(char)[] t2(const(char)[] p) {\n        return p ~ \"b\";\n    }\n\n    static char[] t3(int p) {\n        import std.conv : text;\n        return p.text.dup;\n    }\n\n    Variant v1 = &t1;\n    Variant v2 = &t2;\n    Variant v3 = &t3;\n\n    assert(v1(\"abc\") == \"abca\");\n    assert(v1(\"abc\").type == typeid(string));\n    assert(v2(\"abc\") == \"abcb\");\n\n    assert(v2(cast(char[])(\"abc\".dup)) == \"abcb\");\n    assert(v2(\"abc\").type == typeid(const(char)[]));\n\n    assert(v3(4) == ['4']);\n    assert(v3(4).type == typeid(char[]));\n}\n\n// issue 12071\n@system unittest\n{\n    static struct Structure { int data; }\n    alias VariantTest = Algebraic!(Structure delegate() pure nothrow @nogc @safe);\n\n    bool called = false;\n    Structure example() pure nothrow @nogc @safe\n    {\n        called = true;\n        return Structure.init;\n    }\n    auto m = VariantTest(&example);\n    m();\n    assert(called);\n}\n\n// Ordering comparisons of incompatible types, e.g. issue 7990.\n@system unittest\n{\n    import std.exception : assertThrown;\n    assertThrown!VariantException(Variant(3) < \"a\");\n    assertThrown!VariantException(\"a\" < Variant(3));\n    assertThrown!VariantException(Variant(3) < Variant(\"a\"));\n\n    assertThrown!VariantException(Variant.init < Variant(3));\n    assertThrown!VariantException(Variant(3) < Variant.init);\n}\n\n// Handling of unordered types, e.g. issue 9043.\n@system unittest\n{\n    import std.exception : assertThrown;\n    static struct A { int a; }\n\n    assert(Variant(A(3)) != A(4));\n\n    assertThrown!VariantException(Variant(A(3)) < A(4));\n    assertThrown!VariantException(A(3) < Variant(A(4)));\n    assertThrown!VariantException(Variant(A(3)) < Variant(A(4)));\n}\n\n// Handling of empty types and arrays, e.g. issue 10958\n@system unittest\n{\n    class EmptyClass { }\n    struct EmptyStruct { }\n    alias EmptyArray = void[0];\n    alias Alg = Algebraic!(EmptyClass, EmptyStruct, EmptyArray);\n\n    Variant testEmpty(T)()\n    {\n        T inst;\n        Variant v = inst;\n        assert(v.get!T == inst);\n        assert(v.peek!T !is null);\n        assert(*v.peek!T == inst);\n        Alg alg = inst;\n        assert(alg.get!T == inst);\n        return v;\n    }\n\n    testEmpty!EmptyClass();\n    testEmpty!EmptyStruct();\n    testEmpty!EmptyArray();\n\n    // EmptyClass/EmptyStruct sizeof is 1, so we have this to test just size 0.\n    EmptyArray arr = EmptyArray.init;\n    Algebraic!(EmptyArray) a = arr;\n    assert(a.length == 0);\n    assert(a.get!EmptyArray == arr);\n}\n\n// Handling of void function pointers / delegates, e.g. issue 11360\n@system unittest\n{\n    static void t1() { }\n    Variant v = &t1;\n    assert(v() == Variant.init);\n\n    static int t2() { return 3; }\n    Variant v2 = &t2;\n    assert(v2() == 3);\n}\n\n// Using peek for large structs, issue 8580\n@system unittest\n{\n    struct TestStruct(bool pad)\n    {\n        int val1;\n        static if (pad)\n            ubyte[Variant.size] padding;\n        int val2;\n    }\n\n    void testPeekWith(T)()\n    {\n        T inst;\n        inst.val1 = 3;\n        inst.val2 = 4;\n        Variant v = inst;\n        T* original = v.peek!T;\n        assert(original.val1 == 3);\n        assert(original.val2 == 4);\n        original.val1 = 6;\n        original.val2 = 8;\n        T modified = v.get!T;\n        assert(modified.val1 == 6);\n        assert(modified.val2 == 8);\n    }\n\n    testPeekWith!(TestStruct!false)();\n    testPeekWith!(TestStruct!true)();\n}\n\n/**\n * Applies a delegate or function to the given $(LREF Algebraic) depending on the held type,\n * ensuring that all types are handled by the visiting functions.\n *\n * The delegate or function having the currently held value as parameter is called\n * with `variant`'s current value. Visiting handlers are passed\n * in the template parameter list.\n * It is statically ensured that all held types of\n * `variant` are handled across all handlers.\n * `visit` allows delegates and static functions to be passed\n * as parameters.\n *\n * If a function with an untyped parameter is specified, this function is called\n * when the variant contains a type that does not match any other function.\n * This can be used to apply the same function across multiple possible types.\n * Exactly one generic function is allowed.\n *\n * If a function without parameters is specified, this function is called\n * when `variant` doesn't hold a value. Exactly one parameter-less function\n * is allowed.\n *\n * Duplicate overloads matching the same type in one of the visitors are disallowed.\n *\n * Returns: The return type of visit is deduced from the visiting functions and must be\n * the same across all overloads.\n * Throws: $(LREF VariantException) if `variant` doesn't hold a value and no\n * parameter-less fallback function is specified.\n */\ntemplate visit(Handlers...)\nif (Handlers.length > 0)\n{\n    ///\n    auto visit(VariantType)(VariantType variant)\n        if (isAlgebraic!VariantType)\n    {\n        return visitImpl!(true, VariantType, Handlers)(variant);\n    }\n}\n\n///\n@system unittest\n{\n    Algebraic!(int, string) variant;\n\n    variant = 10;\n    assert(variant.visit!((string s) => cast(int) s.length,\n                          (int i)    => i)()\n                          == 10);\n    variant = \"string\";\n    assert(variant.visit!((int i) => i,\n                          (string s) => cast(int) s.length)()\n                          == 6);\n\n    // Error function usage\n    Algebraic!(int, string) emptyVar;\n    auto rslt = emptyVar.visit!((string s) => cast(int) s.length,\n                          (int i)    => i,\n                          () => -1)();\n    assert(rslt == -1);\n\n    // Generic function usage\n    Algebraic!(int, float, real) number = 2;\n    assert(number.visit!(x => x += 1) == 3);\n\n    // Generic function for int/float with separate behavior for string\n    Algebraic!(int, float, string) something = 2;\n    assert(something.visit!((string s) => s.length, x => x) == 2); // generic\n    something = \"asdf\";\n    assert(something.visit!((string s) => s.length, x => x) == 4); // string\n\n    // Generic handler and empty handler\n    Algebraic!(int, float, real) empty2;\n    assert(empty2.visit!(x => x + 1, () => -1) == -1);\n}\n\n@system unittest\n{\n    Algebraic!(size_t, string) variant;\n\n    // not all handled check\n    static assert(!__traits(compiles, variant.visit!((size_t i){ })() ));\n\n    variant = cast(size_t) 10;\n    auto which = 0;\n    variant.visit!( (string s) => which = 1,\n                    (size_t i) => which = 0\n                    )();\n\n    // integer overload was called\n    assert(which == 0);\n\n    // mustn't compile as generic Variant not supported\n    Variant v;\n    static assert(!__traits(compiles, v.visit!((string s) => which = 1,\n                                               (size_t i) => which = 0\n                                                )()\n                                                ));\n\n    static size_t func(string s) {\n        return s.length;\n    }\n\n    variant = \"test\";\n    assert( 4 == variant.visit!(func,\n                                (size_t i) => i\n                                )());\n\n    Algebraic!(int, float, string) variant2 = 5.0f;\n    // Shouldn' t compile as float not handled by visitor.\n    static assert(!__traits(compiles, variant2.visit!(\n                        (int _) {},\n                        (string _) {})()));\n\n    Algebraic!(size_t, string, float) variant3;\n    variant3 = 10.0f;\n    auto floatVisited = false;\n\n    assert(variant3.visit!(\n                 (float f) { floatVisited = true; return cast(size_t) f; },\n                 func,\n                 (size_t i) { return i; }\n                 )() == 10);\n    assert(floatVisited == true);\n\n    Algebraic!(float, string) variant4;\n\n    assert(variant4.visit!(func, (float f) => cast(size_t) f, () => size_t.max)() == size_t.max);\n\n    // double error func check\n    static assert(!__traits(compiles,\n                            visit!(() => size_t.max, func, (float f) => cast(size_t) f, () => size_t.max)(variant4))\n                 );\n}\n\n// disallow providing multiple generic handlers to visit\n// disallow a generic handler that does not apply to all types\n@system unittest\n{\n    Algebraic!(int, float) number = 2;\n    // ok, x + 1 valid for int and float\n    static assert( __traits(compiles, number.visit!(x => x + 1)));\n    // bad, two generic handlers\n    static assert(!__traits(compiles, number.visit!(x => x + 1, x => x + 2)));\n    // bad, x ~ \"a\" does not apply to int or float\n    static assert(!__traits(compiles, number.visit!(x => x ~ \"a\")));\n    // bad, x ~ \"a\" does not apply to int or float\n    static assert(!__traits(compiles, number.visit!(x => x + 1, x => x ~ \"a\")));\n\n    Algebraic!(int, string) maybenumber = 2;\n    // ok, x ~ \"a\" valid for string, x + 1 valid for int, only 1 generic\n    static assert( __traits(compiles, number.visit!((string x) => x ~ \"a\", x => x + 1)));\n    // bad, x ~ \"a\" valid for string but not int\n    static assert(!__traits(compiles, number.visit!(x => x ~ \"a\")));\n    // bad, two generics, each only applies in one case\n    static assert(!__traits(compiles, number.visit!(x => x + 1, x => x ~ \"a\")));\n}\n\n/**\n * Behaves as $(LREF visit) but doesn't enforce that all types are handled\n * by the visiting functions.\n *\n * If a parameter-less function is specified it is called when\n * either `variant` doesn't hold a value or holds a type\n * which isn't handled by the visiting functions.\n *\n * Returns: The return type of tryVisit is deduced from the visiting functions and must be\n * the same across all overloads.\n * Throws: $(LREF VariantException) if `variant` doesn't hold a value or\n * `variant` holds a value which isn't handled by the visiting functions,\n * when no parameter-less fallback function is specified.\n */\ntemplate tryVisit(Handlers...)\nif (Handlers.length > 0)\n{\n    ///\n    auto tryVisit(VariantType)(VariantType variant)\n        if (isAlgebraic!VariantType)\n    {\n        return visitImpl!(false, VariantType, Handlers)(variant);\n    }\n}\n\n///\n@system unittest\n{\n    Algebraic!(int, string) variant;\n\n    variant = 10;\n    auto which = -1;\n    variant.tryVisit!((int i) { which = 0; })();\n    assert(which == 0);\n\n    // Error function usage\n    variant = \"test\";\n    variant.tryVisit!((int i) { which = 0; },\n                      ()      { which = -100; })();\n    assert(which == -100);\n}\n\n@system unittest\n{\n    import std.exception : assertThrown;\n    Algebraic!(int, string) variant;\n\n    variant = 10;\n    auto which = -1;\n    variant.tryVisit!((int i){ which = 0; })();\n\n    assert(which == 0);\n\n    variant = \"test\";\n\n    assertThrown!VariantException(variant.tryVisit!((int i) { which = 0; })());\n\n    void errorfunc()\n    {\n        which = -1;\n    }\n\n    variant.tryVisit!((int i) { which = 0; }, errorfunc)();\n\n    assert(which == -1);\n}\n\nprivate template isAlgebraic(Type)\n{\n    static if (is(Type _ == VariantN!T, T...))\n        enum isAlgebraic = T.length >= 2; // T[0] == maxDataSize, T[1..$] == AllowedTypesParam\n    else\n        enum isAlgebraic = false;\n}\n\n@system unittest\n{\n    static assert(!isAlgebraic!(Variant));\n    static assert( isAlgebraic!(Algebraic!(string)));\n    static assert( isAlgebraic!(Algebraic!(int, int[])));\n}\n\nprivate auto visitImpl(bool Strict, VariantType, Handler...)(VariantType variant)\nif (isAlgebraic!VariantType && Handler.length > 0)\n{\n    alias AllowedTypes = VariantType.AllowedTypes;\n\n\n    /**\n     * Returns: Struct where `indices`  is an array which\n     * contains at the n-th position the index in Handler which takes the\n     * n-th type of AllowedTypes. If an Handler doesn't match an\n     * AllowedType, -1 is set. If a function in the delegates doesn't\n     * have parameters, the field `exceptionFuncIdx` is set;\n     * otherwise it's -1.\n     */\n    auto visitGetOverloadMap()\n    {\n        struct Result {\n            int[AllowedTypes.length] indices;\n            int exceptionFuncIdx = -1;\n            int generalFuncIdx = -1;\n        }\n\n        Result result;\n\n        foreach (tidx, T; AllowedTypes)\n        {\n            bool added = false;\n            foreach (dgidx, dg; Handler)\n            {\n                // Handle normal function objects\n                static if (isSomeFunction!dg)\n                {\n                    alias Params = Parameters!dg;\n                    static if (Params.length == 0)\n                    {\n                        // Just check exception functions in the first\n                        // inner iteration (over delegates)\n                        if (tidx > 0)\n                            continue;\n                        else\n                        {\n                            if (result.exceptionFuncIdx != -1)\n                                assert(false, \"duplicate parameter-less (error-)function specified\");\n                            result.exceptionFuncIdx = dgidx;\n                        }\n                    }\n                    else static if (is(Params[0] == T) || is(Unqual!(Params[0]) == T))\n                    {\n                        if (added)\n                            assert(false, \"duplicate overload specified for type '\" ~ T.stringof ~ \"'\");\n\n                        added = true;\n                        result.indices[tidx] = dgidx;\n                    }\n                }\n                else static if (isSomeFunction!(dg!T))\n                {\n                    assert(result.generalFuncIdx == -1 ||\n                           result.generalFuncIdx == dgidx,\n                           \"Only one generic visitor function is allowed\");\n                    result.generalFuncIdx = dgidx;\n                }\n                // Handle composite visitors with opCall overloads\n                else\n                {\n                    static assert(false, dg.stringof ~ \" is not a function or delegate\");\n                }\n            }\n\n            if (!added)\n                result.indices[tidx] = -1;\n        }\n\n        return result;\n    }\n\n    enum HandlerOverloadMap = visitGetOverloadMap();\n\n    if (!variant.hasValue)\n    {\n        // Call the exception function. The HandlerOverloadMap\n        // will have its exceptionFuncIdx field set to value != -1 if an\n        // exception function has been specified; otherwise we just through an exception.\n        static if (HandlerOverloadMap.exceptionFuncIdx != -1)\n            return Handler[ HandlerOverloadMap.exceptionFuncIdx ]();\n        else\n            throw new VariantException(\"variant must hold a value before being visited.\");\n    }\n\n    foreach (idx, T; AllowedTypes)\n    {\n        if (auto ptr = variant.peek!T)\n        {\n            enum dgIdx = HandlerOverloadMap.indices[idx];\n\n            static if (dgIdx == -1)\n            {\n                static if (HandlerOverloadMap.generalFuncIdx >= 0)\n                    return Handler[HandlerOverloadMap.generalFuncIdx](*ptr);\n                else static if (Strict)\n                    static assert(false, \"overload for type '\" ~ T.stringof ~ \"' hasn't been specified\");\n                else static if (HandlerOverloadMap.exceptionFuncIdx != -1)\n                    return Handler[HandlerOverloadMap.exceptionFuncIdx]();\n                else\n                    throw new VariantException(\n                        \"variant holds value of type '\"\n                        ~ T.stringof ~\n                        \"' but no visitor has been provided\"\n                    );\n            }\n            else\n            {\n                return Handler[ dgIdx ](*ptr);\n            }\n        }\n    }\n\n    assert(false);\n}\n\n@system unittest\n{\n    // validate that visit can be called with a const type\n    struct Foo { int depth; }\n    struct Bar { int depth; }\n    alias FooBar = Algebraic!(Foo, Bar);\n\n    int depth(in FooBar fb) {\n        return fb.visit!((Foo foo) => foo.depth,\n                         (Bar bar) => bar.depth);\n    }\n\n    FooBar fb = Foo(3);\n    assert(depth(fb) == 3);\n}\n\n@system unittest\n{\n    // https://issues.dlang.org/show_bug.cgi?id=16383\n    class Foo {this() immutable {}}\n    alias V = Algebraic!(immutable Foo);\n\n    auto x = V(new immutable Foo).visit!(\n        (immutable(Foo) _) => 3\n    );\n    assert(x == 3);\n}\n\n@system unittest\n{\n    // http://d.puremagic.com/issues/show_bug.cgi?id=5310\n    const Variant a;\n    assert(a == a);\n    Variant b;\n    assert(a == b);\n    assert(b == a);\n}\n\n@system unittest\n{\n    const Variant a = [2];\n    assert(a[0] == 2);\n}\n\n@system unittest\n{\n    // http://d.puremagic.com/issues/show_bug.cgi?id=10017\n    static struct S\n    {\n        ubyte[Variant.size + 1] s;\n    }\n\n    Variant v1, v2;\n    v1 = S(); // the payload is allocated on the heap\n    v2 = v1;  // AssertError: target must be non-null\n    assert(v1 == v2);\n}\n@system unittest\n{\n    import std.exception : assertThrown;\n    // http://d.puremagic.com/issues/show_bug.cgi?id=7069\n    Variant v;\n\n    int i = 10;\n    v = i;\n    static foreach (qual; AliasSeq!(MutableOf, ConstOf))\n    {\n        assert(v.get!(qual!int) == 10);\n        assert(v.get!(qual!float) == 10.0f);\n    }\n    static foreach (qual; AliasSeq!(ImmutableOf, SharedOf, SharedConstOf))\n    {\n        assertThrown!VariantException(v.get!(qual!int));\n    }\n\n    const(int) ci = 20;\n    v = ci;\n    static foreach (qual; AliasSeq!(ConstOf))\n    {\n        assert(v.get!(qual!int) == 20);\n        assert(v.get!(qual!float) == 20.0f);\n    }\n    static foreach (qual; AliasSeq!(MutableOf, ImmutableOf, SharedOf, SharedConstOf))\n    {\n        assertThrown!VariantException(v.get!(qual!int));\n        assertThrown!VariantException(v.get!(qual!float));\n    }\n\n    immutable(int) ii = ci;\n    v = ii;\n    static foreach (qual; AliasSeq!(ImmutableOf, ConstOf, SharedConstOf))\n    {\n        assert(v.get!(qual!int) == 20);\n        assert(v.get!(qual!float) == 20.0f);\n    }\n    static foreach (qual; AliasSeq!(MutableOf, SharedOf))\n    {\n        assertThrown!VariantException(v.get!(qual!int));\n        assertThrown!VariantException(v.get!(qual!float));\n    }\n\n    int[] ai = [1,2,3];\n    v = ai;\n    static foreach (qual; AliasSeq!(MutableOf, ConstOf))\n    {\n        assert(v.get!(qual!(int[])) == [1,2,3]);\n        assert(v.get!(qual!(int)[]) == [1,2,3]);\n    }\n    static foreach (qual; AliasSeq!(ImmutableOf, SharedOf, SharedConstOf))\n    {\n        assertThrown!VariantException(v.get!(qual!(int[])));\n        assertThrown!VariantException(v.get!(qual!(int)[]));\n    }\n\n    const(int[]) cai = [4,5,6];\n    v = cai;\n    static foreach (qual; AliasSeq!(ConstOf))\n    {\n        assert(v.get!(qual!(int[])) == [4,5,6]);\n        assert(v.get!(qual!(int)[]) == [4,5,6]);\n    }\n    static foreach (qual; AliasSeq!(MutableOf, ImmutableOf, SharedOf, SharedConstOf))\n    {\n        assertThrown!VariantException(v.get!(qual!(int[])));\n        assertThrown!VariantException(v.get!(qual!(int)[]));\n    }\n\n    immutable(int[]) iai = [7,8,9];\n    v = iai;\n    //assert(v.get!(immutable(int[])) == [7,8,9]);   // Bug ??? runtime error\n    assert(v.get!(immutable(int)[]) == [7,8,9]);\n    assert(v.get!(const(int[])) == [7,8,9]);\n    assert(v.get!(const(int)[]) == [7,8,9]);\n    //assert(v.get!(shared(const(int[]))) == cast(shared const)[7,8,9]);    // Bug ??? runtime error\n    //assert(v.get!(shared(const(int))[]) == cast(shared const)[7,8,9]);    // Bug ??? runtime error\n    static foreach (qual; AliasSeq!(MutableOf))\n    {\n        assertThrown!VariantException(v.get!(qual!(int[])));\n        assertThrown!VariantException(v.get!(qual!(int)[]));\n    }\n\n    class A {}\n    class B : A {}\n    B b = new B();\n    v = b;\n    static foreach (qual; AliasSeq!(MutableOf, ConstOf))\n    {\n        assert(v.get!(qual!B) is b);\n        assert(v.get!(qual!A) is b);\n        assert(v.get!(qual!Object) is b);\n    }\n    static foreach (qual; AliasSeq!(ImmutableOf, SharedOf, SharedConstOf))\n    {\n        assertThrown!VariantException(v.get!(qual!B));\n        assertThrown!VariantException(v.get!(qual!A));\n        assertThrown!VariantException(v.get!(qual!Object));\n    }\n\n    const(B) cb = new B();\n    v = cb;\n    static foreach (qual; AliasSeq!(ConstOf))\n    {\n        assert(v.get!(qual!B) is cb);\n        assert(v.get!(qual!A) is cb);\n        assert(v.get!(qual!Object) is cb);\n    }\n    static foreach (qual; AliasSeq!(MutableOf, ImmutableOf, SharedOf, SharedConstOf))\n    {\n        assertThrown!VariantException(v.get!(qual!B));\n        assertThrown!VariantException(v.get!(qual!A));\n        assertThrown!VariantException(v.get!(qual!Object));\n    }\n\n    immutable(B) ib = new immutable(B)();\n    v = ib;\n    static foreach (qual; AliasSeq!(ImmutableOf, ConstOf, SharedConstOf))\n    {\n        assert(v.get!(qual!B) is ib);\n        assert(v.get!(qual!A) is ib);\n        assert(v.get!(qual!Object) is ib);\n    }\n    static foreach (qual; AliasSeq!(MutableOf, SharedOf))\n    {\n        assertThrown!VariantException(v.get!(qual!B));\n        assertThrown!VariantException(v.get!(qual!A));\n        assertThrown!VariantException(v.get!(qual!Object));\n    }\n\n    shared(B) sb = new shared B();\n    v = sb;\n    static foreach (qual; AliasSeq!(SharedOf, SharedConstOf))\n    {\n        assert(v.get!(qual!B) is sb);\n        assert(v.get!(qual!A) is sb);\n        assert(v.get!(qual!Object) is sb);\n    }\n    static foreach (qual; AliasSeq!(MutableOf, ImmutableOf, ConstOf))\n    {\n        assertThrown!VariantException(v.get!(qual!B));\n        assertThrown!VariantException(v.get!(qual!A));\n        assertThrown!VariantException(v.get!(qual!Object));\n    }\n\n    shared(const(B)) scb = new shared const B();\n    v = scb;\n    static foreach (qual; AliasSeq!(SharedConstOf))\n    {\n        assert(v.get!(qual!B) is scb);\n        assert(v.get!(qual!A) is scb);\n        assert(v.get!(qual!Object) is scb);\n    }\n    static foreach (qual; AliasSeq!(MutableOf, ConstOf, ImmutableOf, SharedOf))\n    {\n        assertThrown!VariantException(v.get!(qual!B));\n        assertThrown!VariantException(v.get!(qual!A));\n        assertThrown!VariantException(v.get!(qual!Object));\n    }\n}\n\n@system unittest\n{\n    static struct DummyScope\n    {\n        // https://d.puremagic.com/issues/show_bug.cgi?id=12540\n        alias Alias12540 = Algebraic!Class12540;\n\n        static class Class12540\n        {\n            Alias12540 entity;\n        }\n    }\n}\n\n@system unittest\n{\n    // https://issues.dlang.org/show_bug.cgi?id=10194\n    // Also test for elaborate copying\n    static struct S\n    {\n        @disable this();\n        this(int dummy)\n        {\n            ++cnt;\n        }\n\n        this(this)\n        {\n            ++cnt;\n        }\n\n        @disable S opAssign();\n\n        ~this()\n        {\n            --cnt;\n            assert(cnt >= 0);\n        }\n        static int cnt = 0;\n    }\n\n    {\n        Variant v;\n        {\n            v = S(0);\n            assert(S.cnt == 1);\n        }\n        assert(S.cnt == 1);\n\n        // assigning a new value should destroy the existing one\n        v = 0;\n        assert(S.cnt == 0);\n\n        // destroying the variant should destroy it's current value\n        v = S(0);\n        assert(S.cnt == 1);\n    }\n    assert(S.cnt == 0);\n}\n\n@system unittest\n{\n    // Bugzilla 13300\n    static struct S\n    {\n        this(this) {}\n        ~this() {}\n    }\n\n    static assert( hasElaborateCopyConstructor!(Variant));\n    static assert(!hasElaborateCopyConstructor!(Algebraic!bool));\n    static assert( hasElaborateCopyConstructor!(Algebraic!S));\n    static assert( hasElaborateCopyConstructor!(Algebraic!(bool, S)));\n\n    static assert( hasElaborateDestructor!(Variant));\n    static assert(!hasElaborateDestructor!(Algebraic!bool));\n    static assert( hasElaborateDestructor!(Algebraic!S));\n    static assert( hasElaborateDestructor!(Algebraic!(bool, S)));\n\n    import std.array;\n    alias Value = Algebraic!bool;\n\n    static struct T\n    {\n        Value value;\n        @disable this();\n    }\n    auto a = appender!(T[]);\n}\n\n@system unittest\n{\n    // Bugzilla 13871\n    alias A = Algebraic!(int, typeof(null));\n    static struct B { A value; }\n    alias C = std.variant.Algebraic!B;\n\n    C var;\n    var = C(B());\n}\n\n@system unittest\n{\n    import std.exception : assertThrown, assertNotThrown;\n    // Make sure Variant can handle types with opDispatch but no length field.\n    struct SWithNoLength\n    {\n        void opDispatch(string s)() { }\n    }\n\n    struct SWithLength\n    {\n        @property int opDispatch(string s)()\n        {\n            // Assume that s == \"length\"\n            return 5; // Any value is OK for test.\n        }\n    }\n\n    SWithNoLength sWithNoLength;\n    Variant v = sWithNoLength;\n    assertThrown!VariantException(v.length);\n\n    SWithLength sWithLength;\n    v = sWithLength;\n    assertNotThrown!VariantException(v.get!SWithLength.length);\n    assertThrown!VariantException(v.length);\n}\n\n@system unittest\n{\n    // Bugzilla 13534\n    static assert(!__traits(compiles, () @safe {\n        auto foo() @system { return 3; }\n        auto v = Variant(&foo);\n        v(); // foo is called in safe code!?\n    }));\n}\n\n@system unittest\n{\n    // Bugzilla 15039\n    import std.typecons;\n    import std.variant;\n\n    alias IntTypedef = Typedef!int;\n    alias Obj = Algebraic!(int, IntTypedef, This[]);\n\n    Obj obj = 1;\n\n    obj.visit!(\n        (int x) {},\n        (IntTypedef x) {},\n        (Obj[] x) {},\n    );\n}\n\n@system unittest\n{\n    // Bugzilla 15791\n    int n = 3;\n    struct NS1 { int foo() { return n + 10; } }\n    struct NS2 { int foo() { return n * 10; } }\n\n    Variant v;\n    v = NS1();\n    assert(v.get!NS1.foo() == 13);\n    v = NS2();\n    assert(v.get!NS2.foo() == 30);\n}\n\n@system unittest\n{\n    // Bugzilla 15827\n    static struct Foo15827 { Variant v; this(Foo15827 v) {} }\n    Variant v = Foo15827.init;\n}\n\n@system unittest\n{\n    // Bugzilla 18934\n    static struct S\n    {\n        const int x;\n    }\n\n    auto s = S(42);\n    Variant v = s;\n    auto s2 = v.get!S;\n    assert(s2.x == 42);\n    Variant v2 = v; // support copying from one variant to the other\n    v2 = S(2);\n    v = v2;\n    assert(v.get!S.x == 2);\n}\n\n@system unittest\n{\n    // Bugzilla 19200\n    static struct S\n    {\n        static int opBinaryRight(string op : \"|\", T)(T rhs)\n        {\n            return 3;\n        }\n    }\n\n    S s;\n    Variant v;\n    auto b = v | s;\n    assert(b == 3);\n}\n"
  },
  {
    "path": "libphobos/src/std/windows/charset.d",
    "content": "// Written in the D programming language.\n\n/**\n * Support UTF-8 on Windows 95, 98 and ME systems.\n *\n * Copyright: Copyright The D Language Foundation\" 2005 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright)\n */\n/*          Copyright The D Language Foundation\" 2005 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.windows.charset;\n\nversion (StdDdoc)\n{\n    /******************************************\n     * Converts the UTF-8 string s into a null-terminated string in a Windows\n     * 8-bit character set.\n     *\n     * Params:\n     * s = UTF-8 string to convert.\n     * codePage = is the number of the target codepage, or\n     *   0 - ANSI,\n     *   1 - OEM,\n     *   2 - Mac\n     *\n     * Authors:\n     *      yaneurao, Walter Bright, Stewart Gordon\n     */\n    const(char)* toMBSz(scope const(char)[] s, uint codePage = 0);\n\n    /**********************************************\n     * Converts the null-terminated string s from a Windows 8-bit character set\n     * into a UTF-8 char array.\n     *\n     * Params:\n     * s = UTF-8 string to convert.\n     * codePage = is the number of the source codepage, or\n     *   0 - ANSI,\n     *   1 - OEM,\n     *   2 - Mac\n     * Authors: Stewart Gordon, Walter Bright\n     */\n    string fromMBSz(immutable(char)* s, int codePage = 0);\n}\nelse:\n\nversion (Windows):\n\nimport core.sys.windows.windows;\nimport std.conv;\nimport std.string;\nimport std.windows.syserror;\n\nimport std.internal.cstring;\n\nconst(char)* toMBSz(scope const(char)[] s, uint codePage = 0)\n{\n    // Only need to do this if any chars have the high bit set\n    foreach (char c; s)\n    {\n        if (c >= 0x80)\n        {\n            char[] result;\n            int readLen;\n            auto wsTmp = s.tempCStringW();\n            result.length = WideCharToMultiByte(codePage, 0, wsTmp, -1, null, 0,\n                    null, null);\n\n            if (result.length)\n            {\n                readLen = WideCharToMultiByte(codePage, 0, wsTmp, -1, result.ptr,\n                        to!int(result.length), null, null);\n            }\n\n            if (!readLen || readLen != result.length)\n            {\n                throw new Exception(\"Couldn't convert string: \" ~\n                        sysErrorString(GetLastError()));\n            }\n\n            return result.ptr;\n        }\n    }\n    return std.string.toStringz(s);\n}\n\nstring fromMBSz(return scope immutable(char)* s, int codePage = 0)\n{\n    const(char)* c;\n\n    for (c = s; *c != 0; c++)\n    {\n        if (*c >= 0x80)\n        {\n            wchar[] result;\n            int readLen;\n\n            result.length = MultiByteToWideChar(codePage, 0, s, -1, null, 0);\n\n            if (result.length)\n            {\n                readLen = MultiByteToWideChar(codePage, 0, s, -1, result.ptr,\n                        to!int(result.length));\n            }\n\n            if (!readLen || readLen != result.length)\n            {\n                throw new Exception(\"Couldn't convert string: \" ~\n                    sysErrorString(GetLastError()));\n            }\n\n            return result[0 .. result.length-1].to!string; // omit trailing null\n        }\n    }\n    return s[0 .. c-s];         // string is ASCII, no conversion necessary\n}\n\n\n"
  },
  {
    "path": "libphobos/src/std/windows/registry.d",
    "content": "/**\n    This library provides Win32 Registry facilities.\n\n    Copyright: Copyright 2003-2004 by Matthew Wilson and Synesis Software\n               Written by Matthew Wilson\n\n    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n\n    Author:    Matthew Wilson, Kenji Hara\n\n    History:\n        Created      15th March 2003,\n        Updated      25th April 2004,\n\n    Source:    $(PHOBOSSRC std/windows/registry.d)\n*/\n/* /////////////////////////////////////////////////////////////////////////////\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, in both source and binary form, subject to the following\n * restrictions:\n *\n * -  The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would be\n *    appreciated but is not required.\n * -  Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n * -  This notice may not be removed or altered from any source\n *    distribution.\n *\n * ////////////////////////////////////////////////////////////////////////// */\nmodule std.windows.registry;\nversion (Windows):\n\nimport core.sys.windows.windows;\nimport std.array;\nimport std.conv;\nimport std.exception;\nimport std.internal.cstring;\nimport std.internal.windows.advapi32;\nimport std.system : Endian, endian;\nimport std.windows.syserror;\n\n//debug = winreg;\ndebug(winreg) import std.stdio;\n\nprivate\n{\n    import core.sys.windows.winbase : lstrlenW;\n\n    void enforceSucc(LONG res, lazy string message, string fn = __FILE__, size_t ln = __LINE__)\n    {\n        if (res != ERROR_SUCCESS)\n            throw new RegistryException(message, res, fn, ln);\n    }\n}\n\n/* ************* Exceptions *************** */\n\n// Do not use. Left for compatibility.\nclass Win32Exception : WindowsException\n{\n    @safe\n    this(string message, string fn = __FILE__, size_t ln = __LINE__, Throwable next = null)\n    {\n        super(0, message, fn, ln);\n    }\n\n    @safe\n    this(string message, int errnum, string fn = __FILE__, size_t ln = __LINE__, Throwable next = null)\n    {\n        super(errnum, message, fn, ln);\n    }\n\n    @property int error() { return super.code; }\n}\n\nversion (unittest) import std.string : startsWith, endsWith;\n\n@safe unittest\n{\n    // Test that we can throw and catch one by its own type\n    string message = \"Test W1\";\n\n    auto e = collectException!Win32Exception(\n        enforce(false, new Win32Exception(message)));\n    assert(e.msg.startsWith(message));\n}\n\n@system unittest\n{\n    // ditto\n    string message = \"Test W2\";\n    int    code    = 5;\n\n    auto e = collectException!Win32Exception(\n        enforce(false, new Win32Exception(message, code)));\n    assert(e.error == code);\n    assert(e.msg.startsWith(message));\n}\n\n/**\n    Exception class thrown by the std.windows.registry classes.\n */\nclass RegistryException\n    : Win32Exception\n{\npublic:\n    /**\n        Creates an instance of the exception.\n\n        Params:\n            message = The message associated with the exception.\n     */\n    @safe\n    this(string message, string fn = __FILE__, size_t ln = __LINE__, Throwable next = null)\n    {\n        super(message, fn, ln, next);\n    }\n\n    /**\n        Creates an instance of the exception, with the given.\n\n        Params:\n            message = The message associated with the exception.\n            error = The Win32 error number associated with the exception.\n     */\n    @safe\n    this(string message, int error, string fn = __FILE__, size_t ln = __LINE__, Throwable next = null)\n    {\n        super(message, error, fn, ln, next);\n    }\n}\n\n@system unittest\n{\n    // (i) Test that we can throw and catch one by its own type\n    string message = \"Test 1\";\n    int    code    = 3;\n\n    auto e = collectException!RegistryException(\n        enforce(false, new RegistryException(message, code)));\n    assert(e.error == code);\n    assert(e.msg.startsWith(message));\n}\n\n@safe unittest\n{\n    // ditto\n    string message = \"Test 2\";\n\n    auto e = collectException!RegistryException(\n        enforce(false, new RegistryException(message)));\n    assert(e.msg.startsWith(message));\n}\n\n/* ************* public enumerations *************** */\n\n/**\n    Enumeration of the recognised registry access modes.\n */\nenum REGSAM\n{\n    KEY_QUERY_VALUE         = 0x0001,   /// Permission to query subkey data\n    KEY_SET_VALUE           = 0x0002,   /// Permission to set subkey data\n    KEY_CREATE_SUB_KEY      = 0x0004,   /// Permission to create subkeys\n    KEY_ENUMERATE_SUB_KEYS  = 0x0008,   /// Permission to enumerate subkeys\n    KEY_NOTIFY              = 0x0010,   /// Permission for change notification\n    KEY_CREATE_LINK         = 0x0020,   /// Permission to create a symbolic link\n    KEY_WOW64_32KEY         = 0x0200,   /// Enables a 64- or 32-bit application to open a 32-bit key\n    KEY_WOW64_64KEY         = 0x0100,   /// Enables a 64- or 32-bit application to open a 64-bit key\n    KEY_WOW64_RES           = 0x0300,   ///\n    KEY_READ                = (STANDARD_RIGHTS_READ\n                               | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY)\n                              & ~(SYNCHRONIZE),\n                                        /// Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE,\n                                        /// KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY access rights\n    KEY_WRITE               = (STANDARD_RIGHTS_WRITE\n                               | KEY_SET_VALUE | KEY_CREATE_SUB_KEY)\n                              & ~(SYNCHRONIZE),\n                                        /// Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE,\n                                        /// and KEY_CREATE_SUB_KEY access rights\n    KEY_EXECUTE             = KEY_READ & ~(SYNCHRONIZE),\n                                        /// Permission for read access\n    KEY_ALL_ACCESS          = (STANDARD_RIGHTS_ALL\n                               | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY\n                               | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_CREATE_LINK)\n                              & ~(SYNCHRONIZE),\n                                        /// Combines the KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS,\n                                        /// KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK, and\n                                        /// KEY_SET_VALUE access rights, plus all the standard\n                                        /// access rights except SYNCHRONIZE\n}\n\n/**\n    Enumeration of the recognised registry value types.\n */\nenum REG_VALUE_TYPE : DWORD\n{\n    REG_UNKNOWN                     =  -1,  ///\n    REG_NONE                        =   0,  /// The null value type. (In practise this is treated as a zero-length binary array by the Win32 registry)\n    REG_SZ                          =   1,  /// A zero-terminated string\n    REG_EXPAND_SZ                   =   2,  /// A zero-terminated string containing expandable environment variable references\n    REG_BINARY                      =   3,  /// A binary blob\n    REG_DWORD                       =   4,  /// A 32-bit unsigned integer\n    REG_DWORD_LITTLE_ENDIAN         =   4,  /// A 32-bit unsigned integer, stored in little-endian byte order\n    REG_DWORD_BIG_ENDIAN            =   5,  /// A 32-bit unsigned integer, stored in big-endian byte order\n    REG_LINK                        =   6,  /// A registry link\n    REG_MULTI_SZ                    =   7,  /// A set of zero-terminated strings\n    REG_RESOURCE_LIST               =   8,  /// A hardware resource list\n    REG_FULL_RESOURCE_DESCRIPTOR    =   9,  /// A hardware resource descriptor\n    REG_RESOURCE_REQUIREMENTS_LIST  =  10,  /// A hardware resource requirements list\n    REG_QWORD                       =  11,  /// A 64-bit unsigned integer\n    REG_QWORD_LITTLE_ENDIAN         =  11,  /// A 64-bit unsigned integer, stored in little-endian byte order\n}\n\n\n/* ************* private *************** */\n\nimport core.sys.windows.winnt :\n    DELETE                  ,\n    READ_CONTROL            ,\n    WRITE_DAC               ,\n    WRITE_OWNER             ,\n    SYNCHRONIZE             ,\n\n    STANDARD_RIGHTS_REQUIRED,\n\n    STANDARD_RIGHTS_READ    ,\n    STANDARD_RIGHTS_WRITE   ,\n    STANDARD_RIGHTS_EXECUTE ,\n\n    STANDARD_RIGHTS_ALL     ,\n\n    SPECIFIC_RIGHTS_ALL     ;\n\nimport core.sys.windows.winreg :\n    REG_CREATED_NEW_KEY     ,\n    REG_OPENED_EXISTING_KEY ;\n\n// Returns samDesired but without WoW64 flags if not in WoW64 mode\n// for compatibility with Windows 2000\nprivate REGSAM compatibleRegsam(in REGSAM samDesired)\n{\n    return isWow64 ? samDesired : cast(REGSAM)(samDesired & ~REGSAM.KEY_WOW64_RES);\n}\n\n///Returns true, if we are in WoW64 mode and have WoW64 flags\nprivate bool haveWoW64Job(in REGSAM samDesired)\n{\n    return isWow64 && (samDesired & REGSAM.KEY_WOW64_RES);\n}\n\nprivate REG_VALUE_TYPE _RVT_from_Endian(Endian endian)\n{\n    final switch (endian)\n    {\n        case Endian.bigEndian:\n            return REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN;\n\n        case Endian.littleEndian:\n            return REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN;\n    }\n}\n\nprivate LONG regCloseKey(in HKEY hkey)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    /* No need to attempt to close any of the standard hive keys.\n     * Although it's documented that calling RegCloseKey() on any of\n     * these hive keys is ignored, we'd rather not trust the Win32\n     * API.\n     */\n    if (cast(uint) hkey & 0x80000000)\n    {\n        switch (cast(uint) hkey)\n        {\n            case HKEY_CLASSES_ROOT:\n            case HKEY_CURRENT_USER:\n            case HKEY_LOCAL_MACHINE:\n            case HKEY_USERS:\n            case HKEY_PERFORMANCE_DATA:\n            case HKEY_PERFORMANCE_TEXT:\n            case HKEY_PERFORMANCE_NLSTEXT:\n            case HKEY_CURRENT_CONFIG:\n            case HKEY_DYN_DATA:\n                return ERROR_SUCCESS;\n            default:\n                /* Do nothing */\n                break;\n        }\n    }\n\n    return RegCloseKey(hkey);\n}\n\nprivate void regFlushKey(in HKEY hkey)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    immutable res = RegFlushKey(hkey);\n    enforceSucc(res, \"Key cannot be flushed\");\n}\n\nprivate HKEY regCreateKey(in HKEY hkey, in string subKey, in DWORD dwOptions, in REGSAM samDesired,\n                          in LPSECURITY_ATTRIBUTES lpsa, out DWORD disposition)\nin\n{\n    assert(hkey !is null);\n    assert(subKey !is null);\n}\ndo\n{\n    HKEY hkeyResult;\n    enforceSucc(RegCreateKeyExW(\n                        hkey, subKey.tempCStringW(), 0, null, dwOptions,\n                        compatibleRegsam(samDesired), cast(LPSECURITY_ATTRIBUTES) lpsa,\n                        &hkeyResult, &disposition),\n        \"Failed to create requested key: \\\"\" ~ subKey ~ \"\\\"\");\n\n    return hkeyResult;\n}\n\nprivate void regDeleteKey(in HKEY hkey, in string subKey, in REGSAM samDesired)\nin\n{\n    assert(hkey !is null);\n    assert(subKey !is null);\n}\ndo\n{\n    LONG res;\n    if (haveWoW64Job(samDesired))\n    {\n        loadAdvapi32();\n        res = pRegDeleteKeyExW(hkey, subKey.tempCStringW(), samDesired, 0);\n    }\n    else\n    {\n        res = RegDeleteKeyW(hkey, subKey.tempCStringW());\n    }\n    enforceSucc(res, \"Key cannot be deleted: \\\"\" ~ subKey ~ \"\\\"\");\n}\n\nprivate void regDeleteValue(in HKEY hkey, in string valueName)\nin\n{\n    assert(hkey !is null);\n    assert(valueName !is null);\n}\ndo\n{\n    enforceSucc(RegDeleteValueW(hkey, valueName.tempCStringW()),\n        \"Value cannot be deleted: \\\"\" ~ valueName ~ \"\\\"\");\n}\n\nprivate HKEY regDup(HKEY hkey)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    /* Can't duplicate standard keys, but don't need to, so can just return */\n    if (cast(uint) hkey & 0x80000000)\n    {\n        switch (cast(uint) hkey)\n        {\n            case HKEY_CLASSES_ROOT:\n            case HKEY_CURRENT_USER:\n            case HKEY_LOCAL_MACHINE:\n            case HKEY_USERS:\n            case HKEY_PERFORMANCE_DATA:\n            case HKEY_PERFORMANCE_TEXT:\n            case HKEY_PERFORMANCE_NLSTEXT:\n            case HKEY_CURRENT_CONFIG:\n            case HKEY_DYN_DATA:\n                return hkey;\n            default:\n                /* Do nothing */\n                break;\n        }\n    }\n\n    HKEY hkeyDup;\n    immutable res = RegOpenKeyW(hkey, null, &hkeyDup);\n\n    debug(winreg)\n    {\n        if (res != ERROR_SUCCESS)\n        {\n            writefln(\"regDup() failed: 0x%08x 0x%08x %d\", hkey, hkeyDup, res);\n        }\n\n        assert(res == ERROR_SUCCESS);\n    }\n\n    return (res == ERROR_SUCCESS) ? hkeyDup : null;\n}\n\nprivate LONG regEnumKeyName(in HKEY hkey, in DWORD index, ref wchar[] name, out DWORD cchName)\nin\n{\n    assert(hkey !is null);\n    assert(name !is null);\n    assert(name.length > 0);\n}\nout(res)\n{\n    assert(res != ERROR_MORE_DATA);\n}\ndo\n{\n    // The Registry API lies about the lengths of a very few sub-key lengths\n    // so we have to test to see if it whinges about more data, and provide\n    // more if it does.\n    for (;;)\n    {\n        cchName = to!DWORD(name.length);\n        immutable res = RegEnumKeyExW(hkey, index, name.ptr, &cchName, null, null, null, null);\n        if (res != ERROR_MORE_DATA)\n            return res;\n\n        // Now need to increase the size of the buffer and try again\n        name.length *= 2;\n    }\n\n    assert(0);\n}\n\n\nprivate LONG regEnumValueName(in HKEY hkey, in DWORD dwIndex, ref wchar[] name, out DWORD cchName)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    for (;;)\n    {\n        cchName = to!DWORD(name.length);\n        immutable res = RegEnumValueW(hkey, dwIndex, name.ptr, &cchName, null, null, null, null);\n        if (res != ERROR_MORE_DATA)\n            return res;\n\n        name.length *= 2;\n    }\n\n    assert(0);\n}\n\nprivate LONG regGetNumSubKeys(in HKEY hkey, out DWORD cSubKeys, out DWORD cchSubKeyMaxLen)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    return RegQueryInfoKeyW(hkey, null, null, null, &cSubKeys,\n                            &cchSubKeyMaxLen, null, null, null, null, null, null);\n}\n\nprivate LONG regGetNumValues(in HKEY hkey, out DWORD cValues, out DWORD cchValueMaxLen)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    return RegQueryInfoKeyW(hkey, null, null, null, null, null, null,\n                            &cValues, &cchValueMaxLen, null, null, null);\n}\n\nprivate REG_VALUE_TYPE regGetValueType(in HKEY hkey, in string name)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    REG_VALUE_TYPE type;\n    enforceSucc(RegQueryValueExW(hkey, name.tempCStringW(), null, cast(LPDWORD) &type, null, null),\n        \"Value cannot be opened: \\\"\" ~ name ~ \"\\\"\");\n\n    return type;\n}\n\nprivate HKEY regOpenKey(in HKEY hkey, in string subKey, in REGSAM samDesired)\nin\n{\n    assert(hkey !is null);\n    assert(subKey !is null);\n}\ndo\n{\n    HKEY hkeyResult;\n    enforceSucc(RegOpenKeyExW(hkey, subKey.tempCStringW(), 0, compatibleRegsam(samDesired), &hkeyResult),\n        \"Failed to open requested key: \\\"\" ~ subKey ~ \"\\\"\");\n\n    return hkeyResult;\n}\n\nprivate void regQueryValue(in HKEY hkey, string name, out string value, REG_VALUE_TYPE reqType)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    import core.bitop : bswap;\n\n    REG_VALUE_TYPE type;\n\n    // See bugzilla 961 on this\n    union U\n    {\n        uint    dw;\n        ulong   qw;\n    }\n    U u;\n    void* data = &u.qw;\n    DWORD cbData = u.qw.sizeof;\n\n    auto keynameTmp = name.tempCStringW();\n    LONG res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data, &cbData);\n    if (res == ERROR_MORE_DATA)\n    {\n        data = (new ubyte[cbData]).ptr;\n        res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data, &cbData);\n    }\n\n    enforceSucc(res,\n        \"Cannot read the requested value\");\n    enforce(type == reqType,\n            new RegistryException(\"Value type has been changed since the value was acquired\"));\n\n    switch (type)\n    {\n        case REG_VALUE_TYPE.REG_SZ:\n        case REG_VALUE_TYPE.REG_EXPAND_SZ:\n            auto wstr = (cast(immutable(wchar)*)data)[0 .. cbData / wchar.sizeof];\n            assert(wstr.length > 0 && wstr[$-1] == '\\0');\n            if (wstr.length && wstr[$-1] == '\\0')\n                wstr.length = wstr.length - 1;\n            assert(wstr.length == 0 || wstr[$-1] != '\\0');\n            value = wstr.to!string;\n            break;\n\n        case REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN:\n            version (LittleEndian)\n                value = to!string(u.dw);\n            else\n                value = to!string(bswap(u.dw));\n            break;\n\n        case REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN:\n            version (LittleEndian)\n                value = to!string(bswap(u.dw));\n            else\n                value = to!string(u.dw);\n            break;\n\n        case REG_VALUE_TYPE.REG_QWORD_LITTLE_ENDIAN:\n            value = to!string(u.qw);\n            break;\n\n        case REG_VALUE_TYPE.REG_BINARY:\n        case REG_VALUE_TYPE.REG_MULTI_SZ:\n        default:\n            throw new RegistryException(\"Cannot read the given value as a string\");\n    }\n}\n\nprivate void regQueryValue(in HKEY hkey, in string name, out string[] value, REG_VALUE_TYPE reqType)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    REG_VALUE_TYPE type;\n\n    auto keynameTmp = name.tempCStringW();\n    wchar[] data = new wchar[256];\n    DWORD cbData = to!DWORD(data.length * wchar.sizeof);\n    LONG res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data.ptr, &cbData);\n    if (res == ERROR_MORE_DATA)\n    {\n        data.length = cbData / wchar.sizeof;\n        res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data.ptr, &cbData);\n    }\n    else if (res == ERROR_SUCCESS)\n    {\n        data.length = cbData / wchar.sizeof;\n    }\n    enforceSucc(res, \"Cannot read the requested value\");\n    enforce(type == REG_VALUE_TYPE.REG_MULTI_SZ,\n            new RegistryException(\"Cannot read the given value as a string\"));\n    enforce(type == reqType,\n            new RegistryException(\"Value type has been changed since the value was acquired\"));\n\n    // Remove last two (or one) null terminator\n    assert(data.length > 0 && data[$-1] == '\\0');\n    data.length = data.length - 1;\n    if (data.length > 0 && data[$-1] == '\\0')\n        data.length = data.length - 1;\n\n    auto list = std.array.split(data[], \"\\0\");\n    value.length = list.length;\n    foreach (i, ref v; value)\n    {\n        v = list[i].to!string;\n    }\n}\n\nprivate void regQueryValue(in HKEY hkey, in string name, out uint value, REG_VALUE_TYPE reqType)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    import core.bitop : bswap;\n\n    REG_VALUE_TYPE type;\n\n    DWORD cbData = value.sizeof;\n    enforceSucc(RegQueryValueExW(hkey, name.tempCStringW(), null, cast(LPDWORD) &type, &value, &cbData),\n        \"Cannot read the requested value\");\n    enforce(type == reqType,\n            new RegistryException(\"Value type has been changed since the value was acquired\"));\n\n    switch (type)\n    {\n        case REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN:\n            version (LittleEndian)\n                static assert(REG_VALUE_TYPE.REG_DWORD == REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN);\n            else\n                value = bswap(value);\n            break;\n\n        case REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN:\n            version (LittleEndian)\n                value = bswap(value);\n            else\n                static assert(REG_VALUE_TYPE.REG_DWORD == REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN);\n            break;\n\n        default:\n            throw new RegistryException(\"Cannot read the given value as a 32-bit integer\");\n    }\n}\n\nprivate void regQueryValue(in HKEY hkey, in string name, out ulong value, REG_VALUE_TYPE reqType)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    REG_VALUE_TYPE type;\n\n    DWORD cbData = value.sizeof;\n    enforceSucc(RegQueryValueExW(hkey, name.tempCStringW(), null, cast(LPDWORD) &type, &value, &cbData),\n        \"Cannot read the requested value\");\n    enforce(type == reqType,\n            new RegistryException(\"Value type has been changed since the value was acquired\"));\n\n    switch (type)\n    {\n        case REG_VALUE_TYPE.REG_QWORD_LITTLE_ENDIAN:\n            break;\n\n        default:\n            throw new RegistryException(\"Cannot read the given value as a 64-bit integer\");\n    }\n}\n\nprivate void regQueryValue(in HKEY hkey, in string name, out byte[] value, REG_VALUE_TYPE reqType)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    REG_VALUE_TYPE type;\n\n    byte[] data = new byte[100];\n    DWORD cbData = to!DWORD(data.length);\n    LONG res;\n    auto keynameTmp = name.tempCStringW();\n    res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data.ptr, &cbData);\n    if (res == ERROR_MORE_DATA)\n    {\n        data.length = cbData;\n        res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data.ptr, &cbData);\n    }\n    enforceSucc(res, \"Cannot read the requested value\");\n    enforce(type == reqType,\n            new RegistryException(\"Value type has been changed since the value was acquired\"));\n\n    switch (type)\n    {\n        case REG_VALUE_TYPE.REG_BINARY:\n            data.length = cbData;\n            value = data;\n            break;\n\n        default:\n            throw new RegistryException(\"Cannot read the given value as a string\");\n    }\n}\n\nprivate void regSetValue(in HKEY hkey, in string subKey, in REG_VALUE_TYPE type, in LPCVOID lpData, in DWORD cbData)\nin\n{\n    assert(hkey !is null);\n}\ndo\n{\n    enforceSucc(RegSetValueExW(hkey, subKey.tempCStringW(), 0, type, cast(BYTE*) lpData, cbData),\n        \"Value cannot be set: \\\"\" ~ subKey ~ \"\\\"\");\n}\n\nprivate void regProcessNthKey(Key key, scope void delegate(scope LONG delegate(DWORD, out string)) dg)\n{\n    DWORD cSubKeys;\n    DWORD cchSubKeyMaxLen;\n\n    immutable res = regGetNumSubKeys(key.m_hkey, cSubKeys, cchSubKeyMaxLen);\n    assert(res == ERROR_SUCCESS);\n\n    wchar[] sName = new wchar[cchSubKeyMaxLen + 1];\n\n    // Capture `key` in the lambda to keep the object alive (and so its HKEY handle open).\n    dg((DWORD index, out string name)\n    {\n        DWORD cchName;\n        immutable res = regEnumKeyName(key.m_hkey, index, sName, cchName);\n        if (res == ERROR_SUCCESS)\n        {\n            name = sName[0 .. cchName].to!string;\n        }\n        return res;\n    });\n}\n\nprivate void regProcessNthValue(Key key, scope void delegate(scope LONG delegate(DWORD, out string)) dg)\n{\n    DWORD cValues;\n    DWORD cchValueMaxLen;\n\n    immutable res = regGetNumValues(key.m_hkey, cValues, cchValueMaxLen);\n    assert(res == ERROR_SUCCESS);\n\n    wchar[] sName = new wchar[cchValueMaxLen + 1];\n\n    // Capture `key` in the lambda to keep the object alive (and so its HKEY handle open).\n    dg((DWORD index, out string name)\n    {\n        DWORD cchName;\n        immutable res = regEnumValueName(key.m_hkey, index, sName, cchName);\n        if (res == ERROR_SUCCESS)\n        {\n            name = sName[0 .. cchName].to!string;\n        }\n        return res;\n    });\n}\n\n/* ************* public classes *************** */\n\n/**\n    This class represents a registry key.\n */\nclass Key\n{\n    @safe pure nothrow\n    invariant()\n    {\n        assert(m_hkey !is null);\n    }\n\nprivate:\n    @safe pure nothrow\n    this(HKEY hkey, string name, bool created)\n    in\n    {\n        assert(hkey !is null);\n    }\n    do\n    {\n        m_hkey = hkey;\n        m_name = name;\n    }\n\n    ~this()\n    {\n        regCloseKey(m_hkey);\n\n        // Even though this is horried waste-of-cycles programming\n        // we're doing it here so that the\n        m_hkey = null;\n    }\n\npublic:\n    /// The name of the key\n    @property string name() @safe pure nothrow const\n    {\n        return m_name;\n    }\n\n    /**\n        The number of sub keys.\n     */\n    @property size_t keyCount() const\n    {\n        uint cSubKeys;\n        uint cchSubKeyMaxLen;\n        enforceSucc(regGetNumSubKeys(m_hkey, cSubKeys, cchSubKeyMaxLen),\n            \"Number of sub-keys cannot be determined\");\n\n        return cSubKeys;\n    }\n\n    /**\n        An enumerable sequence of all the sub-keys of this key.\n     */\n    @property KeySequence keys() @safe pure\n    {\n        return new KeySequence(this);\n    }\n\n    /**\n        An enumerable sequence of the names of all the sub-keys of this key.\n     */\n    @property KeyNameSequence keyNames() @safe pure\n    {\n        return new KeyNameSequence(this);\n    }\n\n    /**\n        The number of values.\n     */\n    @property size_t valueCount() const\n    {\n        uint cValues;\n        uint cchValueMaxLen;\n        enforceSucc(regGetNumValues(m_hkey, cValues, cchValueMaxLen),\n            \"Number of values cannot be determined\");\n\n        return cValues;\n    }\n\n    /**\n        An enumerable sequence of all the values of this key.\n     */\n    @property ValueSequence values() @safe pure\n    {\n        return new ValueSequence(this);\n    }\n\n    /**\n        An enumerable sequence of the names of all the values of this key.\n     */\n    @property ValueNameSequence valueNames() @safe pure\n    {\n        return new ValueNameSequence(this);\n    }\n\npublic:\n    /**\n        Returns the named sub-key of this key.\n\n        Params:\n            name = The name of the subkey to create. May not be `null`.\n        Returns:\n            The created key.\n        Throws:\n            `RegistryException` is thrown if the key cannot be created.\n     */\n    Key createKey(string name, REGSAM access = REGSAM.KEY_ALL_ACCESS)\n    {\n        enforce(!name.empty, new RegistryException(\"Key name is invalid\"));\n\n        DWORD disposition;\n        HKEY hkey = regCreateKey(m_hkey, name, 0, access, null, disposition);\n        assert(hkey !is null);\n\n        // Potential resource leak here!!\n        //\n        // If the allocation of the memory for Key fails, the HKEY could be\n        // lost. Hence, we catch such a failure by the finally, and release\n        // the HKEY there. If the creation of\n        try\n        {\n            Key key = new Key(hkey, name, disposition == REG_CREATED_NEW_KEY);\n            hkey = null;\n            return key;\n        }\n        finally\n        {\n            if (hkey !is null)\n            {\n                regCloseKey(hkey);\n            }\n        }\n    }\n\n    /**\n        Returns the named sub-key of this key.\n\n        Params:\n            name = The name of the subkey to aquire. If name is the empty\n                   string, then the called key is duplicated.\n            access = The desired access; one of the `REGSAM` enumeration.\n        Returns:\n            The aquired key.\n        Throws:\n            This function never returns `null`. If a key corresponding to\n            the requested name is not found, `RegistryException` is thrown.\n     */\n    Key getKey(string name, REGSAM access = REGSAM.KEY_READ)\n    {\n        if (name.empty)\n            return new Key(regDup(m_hkey), m_name, false);\n\n        HKEY hkey = regOpenKey(m_hkey, name, access);\n        assert(hkey !is null);\n\n        // Potential resource leak here!!\n        //\n        // If the allocation of the memory for Key fails, the HKEY could be\n        // lost. Hence, we catch such a failure by the finally, and release\n        // the HKEY there. If the creation of\n        try\n        {\n            Key key = new Key(hkey, name, false);\n            hkey = null;\n            return key;\n        }\n        finally\n        {\n            if (hkey != null)\n            {\n                regCloseKey(hkey);\n            }\n        }\n    }\n\n    /**\n        Deletes the named key.\n\n        Params:\n            name = The name of the key to delete. May not be `null`.\n     */\n    void deleteKey(string name, REGSAM access = cast(REGSAM) 0)\n    {\n        enforce(!name.empty, new RegistryException(\"Key name is invalid\"));\n\n        regDeleteKey(m_hkey, name, access);\n    }\n\n    /**\n        Returns the named value.\n        If `name` is the empty string, then the default value is returned.\n\n        Returns:\n            This function never returns `null`. If a value corresponding\n            to the requested name is not found, `RegistryException` is thrown.\n     */\n    Value getValue(string name)\n    {\n        return new Value(this, name, regGetValueType(m_hkey, name));\n    }\n\n    /**\n        Sets the named value with the given 32-bit unsigned integer value.\n\n        Params:\n            name = The name of the value to set. If it is the empty string,\n                   sets the default value.\n            value = The 32-bit unsigned value to set.\n        Throws:\n            If a value corresponding to the requested name is not found,\n            `RegistryException` is thrown.\n     */\n    void setValue(string name, uint value)\n    {\n        setValue(name, value, endian);\n    }\n\n    /**\n        Sets the named value with the given 32-bit unsigned integer value,\n        according to the desired byte-ordering.\n\n        Params:\n            name = The name of the value to set. If it is the empty string,\n                   sets the default value.\n            value = The 32-bit unsigned value to set.\n            endian = Can be `Endian.BigEndian` or `Endian.LittleEndian`.\n        Throws:\n            If a value corresponding to the requested name is not found,\n            `RegistryException` is thrown.\n     */\n    void setValue(string name, uint value, Endian endian)\n    {\n        REG_VALUE_TYPE  type = _RVT_from_Endian(endian);\n\n        assert(type == REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN ||\n               type == REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN);\n\n        regSetValue(m_hkey, name, type, &value, value.sizeof);\n    }\n\n    /**\n        Sets the named value with the given 64-bit unsigned integer value.\n\n        Params:\n            name = The name of the value to set. If it is the empty string,\n                   sets the default value.\n            value = The 64-bit unsigned value to set.\n        Throws:\n            If a value corresponding to the requested name is not found,\n            `RegistryException` is thrown.\n     */\n    void setValue(string name, ulong value)\n    {\n        regSetValue(m_hkey, name, REG_VALUE_TYPE.REG_QWORD, &value, value.sizeof);\n    }\n\n    /**\n        Sets the named value with the given string value.\n\n        Params:\n            name = The name of the value to set. If it is the empty string,\n                   sets the default value.\n            value = The string value to set.\n        Throws:\n            If a value corresponding to the requested name is not found,\n            `RegistryException` is thrown.\n     */\n    void setValue(string name, string value)\n    {\n        setValue(name, value, false);\n    }\n\n    /**\n        Sets the named value with the given string value.\n\n        Params:\n            name = The name of the value to set. If it is the empty string,\n                   sets the default value.\n            value = The string value to set.\n            asEXPAND_SZ = If `true`, the value will be stored as an\n                          expandable environment string, otherwise as a normal string.\n        Throws:\n            If a value corresponding to the requested name is not found,\n            `RegistryException` is thrown.\n     */\n    void setValue(string name, string value, bool asEXPAND_SZ)\n    {\n        auto pszTmp = value.tempCStringW();\n        const(void)* data = pszTmp;\n        DWORD len = to!DWORD(lstrlenW(pszTmp) * wchar.sizeof);\n\n        regSetValue(m_hkey, name,\n                    asEXPAND_SZ ? REG_VALUE_TYPE.REG_EXPAND_SZ\n                                : REG_VALUE_TYPE.REG_SZ,\n                    data, len);\n    }\n\n    /**\n        Sets the named value with the given multiple-strings value.\n\n        Params:\n            name = The name of the value to set. If it is the empty string,\n                   sets the default value.\n            value = The multiple-strings value to set.\n        Throws:\n            If a value corresponding to the requested name is not found,\n            `RegistryException` is thrown.\n     */\n    void setValue(string name, string[] value)\n    {\n        wstring[] data = new wstring[value.length+1];\n        foreach (i, ref s; data[0..$-1])\n        {\n            s = value[i].to!wstring;\n        }\n        data[$-1] = \"\\0\";\n        auto ws = std.array.join(data, \"\\0\"w);\n\n        regSetValue(m_hkey, name, REG_VALUE_TYPE.REG_MULTI_SZ, ws.ptr, to!uint(ws.length * wchar.sizeof));\n    }\n\n    /**\n        Sets the named value with the given binary value.\n\n        Params:\n            name = The name of the value to set. If it is the empty string,\n                   sets the default value.\n            value = The binary value to set.\n        Throws:\n            If a value corresponding to the requested name is not found,\n            `RegistryException` is thrown.\n     */\n    void setValue(string name, byte[] value)\n    {\n        regSetValue(m_hkey, name, REG_VALUE_TYPE.REG_BINARY, value.ptr, to!DWORD(value.length));\n    }\n\n    /**\n        Deletes the named value.\n\n        Params:\n            name = The name of the value to delete. May not be `null`.\n        Throws:\n            If a value of the requested name is not found,\n            `RegistryException` is thrown.\n     */\n    void deleteValue(string name)\n    {\n        regDeleteValue(m_hkey, name);\n    }\n\n    /**\n        Flushes any changes to the key to disk.\n     */\n    void flush()\n    {\n        regFlushKey(m_hkey);\n    }\n\nprivate:\n    HKEY   m_hkey;\n    string m_name;\n}\n\n/**\n    This class represents a value of a registry key.\n */\nclass Value\n{\n    @safe pure nothrow\n    invariant()\n    {\n        assert(m_key !is null);\n    }\n\nprivate:\n    @safe pure nothrow\n    this(Key key, string name, REG_VALUE_TYPE type)\n    in\n    {\n        assert(null !is key);\n    }\n    do\n    {\n        m_key = key;\n        m_type = type;\n        m_name = name;\n    }\n\npublic:\n    /**\n        The name of the value.\n        If the value represents a default value of a key, which has no name,\n        the returned string will be of zero length.\n     */\n    @property string name() @safe pure nothrow const\n    {\n        return m_name;\n    }\n\n    /**\n        The type of value.\n     */\n    @property REG_VALUE_TYPE type() @safe pure nothrow const\n    {\n        return m_type;\n    }\n\n    /**\n        Obtains the current value of the value as a string.\n        If the value's type is REG_EXPAND_SZ the returned value is <b>not</b>\n        expanded; `value_EXPAND_SZ` should be called\n\n        Returns:\n            The contents of the value.\n        Throws:\n            `RegistryException` if the type of the value is not REG_SZ,\n            REG_EXPAND_SZ, REG_DWORD, or REG_QWORD.\n     */\n    @property string value_SZ() const\n    {\n        string value;\n\n        regQueryValue(m_key.m_hkey, m_name, value, m_type);\n\n        return value;\n    }\n\n    /**\n        Obtains the current value as a string, within which any environment\n        variables have undergone expansion.\n        This function works with the same value-types as `value_SZ`.\n\n        Returns:\n            The contents of the value.\n     */\n    @property string value_EXPAND_SZ() const\n    {\n        string  value   =   value_SZ;\n\n        // ExpandEnvironemntStrings():\n        //      http://msdn2.microsoft.com/en-us/library/ms724265.aspx\n        const srcTmp        =   value.tempCStringW();\n        DWORD   cchRequired =   ExpandEnvironmentStringsW(srcTmp, null, 0);\n        wchar[]  newValue   =   new wchar[cchRequired];\n\n        immutable DWORD count = enforce!Win32Exception(\n            ExpandEnvironmentStringsW(srcTmp, newValue.ptr, to!DWORD(newValue.length)),\n            \"Failed to expand environment variables\");\n\n        return newValue[0 .. count-1].to!string; // remove trailing 0\n    }\n\n    /**\n        Obtains the current value as an array of strings.\n\n        Returns:\n            The contents of the value.\n        Throws:\n            `RegistryException` if the type of the value is not REG_MULTI_SZ.\n     */\n    @property string[] value_MULTI_SZ() const\n    {\n        string[] value;\n\n        regQueryValue(m_key.m_hkey, m_name, value, m_type);\n\n        return value;\n    }\n\n    /**\n        Obtains the current value as a 32-bit unsigned integer, ordered\n        correctly according to the current architecture.\n\n        Returns:\n            The contents of the value.\n        Throws:\n            `RegistryException` is thrown for all types other than\n            REG_DWORD, REG_DWORD_LITTLE_ENDIAN and REG_DWORD_BIG_ENDIAN.\n     */\n    @property uint value_DWORD() const\n    {\n        uint value;\n\n        regQueryValue(m_key.m_hkey, m_name, value, m_type);\n\n        return value;\n    }\n\n    /**\n        Obtains the value as a 64-bit unsigned integer, ordered correctly\n        according to the current architecture.\n\n        Returns:\n            The contents of the value.\n        Throws:\n            `RegistryException` if the type of the value is not REG_QWORD.\n     */\n    @property ulong value_QWORD() const\n    {\n        ulong value;\n\n        regQueryValue(m_key.m_hkey, m_name, value, m_type);\n\n        return value;\n    }\n\n    /**\n        Obtains the value as a binary blob.\n\n        Returns:\n            The contents of the value.\n        Throws:\n            `RegistryException` if the type of the value is not REG_BINARY.\n     */\n    @property byte[] value_BINARY() const\n    {\n        byte[] value;\n\n        regQueryValue(m_key.m_hkey, m_name, value, m_type);\n\n        return value;\n    }\n\nprivate:\n    Key             m_key;\n    REG_VALUE_TYPE  m_type;\n    string          m_name;\n}\n\n/**\n    Represents the local system registry.\n */\nfinal class Registry\n{\nprivate:\n    @disable this() { }\n\npublic:\n    /// Returns the root key for the HKEY_CLASSES_ROOT hive\n    static @property Key classesRoot()     { return new Key(HKEY_CLASSES_ROOT,     \"HKEY_CLASSES_ROOT\",     false); }\n    /// Returns the root key for the HKEY_CURRENT_USER hive\n    static @property Key currentUser()     { return new Key(HKEY_CURRENT_USER,     \"HKEY_CURRENT_USER\",     false); }\n    /// Returns the root key for the HKEY_LOCAL_MACHINE hive\n    static @property Key localMachine()    { return new Key(HKEY_LOCAL_MACHINE,    \"HKEY_LOCAL_MACHINE\",    false); }\n    /// Returns the root key for the HKEY_USERS hive\n    static @property Key users()           { return new Key(HKEY_USERS,            \"HKEY_USERS\",            false); }\n    /// Returns the root key for the HKEY_PERFORMANCE_DATA hive\n    static @property Key performanceData() { return new Key(HKEY_PERFORMANCE_DATA, \"HKEY_PERFORMANCE_DATA\", false); }\n    /// Returns the root key for the HKEY_CURRENT_CONFIG hive\n    static @property Key currentConfig()   { return new Key(HKEY_CURRENT_CONFIG,   \"HKEY_CURRENT_CONFIG\",   false); }\n    /// Returns the root key for the HKEY_DYN_DATA hive\n    static @property Key dynData()         { return new Key(HKEY_DYN_DATA,         \"HKEY_DYN_DATA\",         false); }\n}\n\n/**\n    An enumerable sequence representing the names of the sub-keys of a registry Key.\n\nExample:\n----\nKey key = ...\nforeach (string subkeyName; key.keyNames)\n{\n    // using subkeyName\n}\n----\n */\nclass KeyNameSequence\n{\n    @safe pure nothrow\n    invariant()\n    {\n        assert(m_key !is null);\n    }\n\nprivate:\n    @safe pure nothrow\n    this(Key key)\n    {\n        m_key = key;\n    }\n\npublic:\n    /**\n        The number of keys.\n     */\n    @property size_t count() const\n    {\n        return m_key.keyCount;\n    }\n\n    /**\n        The name of the key at the given index.\n\n        Params:\n            index = The 0-based index of the key to retrieve.\n        Returns:\n            The name of the key corresponding to the given index.\n        Throws:\n            RegistryException if no corresponding key is retrieved.\n     */\n    string getKeyName(size_t index)\n    {\n        string name;\n        regProcessNthKey(m_key, (scope LONG delegate(DWORD, out string) getName)\n        {\n            enforceSucc(getName(to!DWORD(index), name), \"Invalid key\");\n        });\n        return name;\n    }\n\n    /**\n        The name of the key at the given index.\n\n        Params:\n            index = The 0-based index of the key to retrieve.\n        Returns:\n            The name of the key corresponding to the given index.\n        Throws:\n            `RegistryException` if no corresponding key is retrieved.\n     */\n    string opIndex(size_t index)\n    {\n        return getKeyName(index);\n    }\n\npublic:\n    ///\n    int opApply(scope int delegate(ref string name) dg)\n    {\n        int result;\n        regProcessNthKey(m_key, (scope LONG delegate(DWORD, out string) getName)\n        {\n            for (DWORD index = 0; !result; ++index)\n            {\n                string name;\n                immutable res = getName(index, name);\n                if (res == ERROR_NO_MORE_ITEMS) // Enumeration complete\n                    break;\n                enforceSucc(res, \"Key name enumeration incomplete\");\n\n                result = dg(name);\n            }\n        });\n        return result;\n    }\n\nprivate:\n    Key m_key;\n}\n\n\n/**\n    An enumerable sequence representing the sub-keys of a registry Key.\n\nExample:\n----\nKey key = ...\nforeach (Key subkey; key.keys)\n{\n    // using subkey\n}\n----\n */\nclass KeySequence\n{\n    @safe pure nothrow\n    invariant()\n    {\n        assert(m_key !is null);\n    }\n\nprivate:\n    @safe pure nothrow\n    this(Key key)\n    {\n        m_key = key;\n    }\n\npublic:\n    /**\n        The number of keys.\n     */\n    @property size_t count() const\n    {\n        return m_key.keyCount;\n    }\n\n    /**\n        The key at the given index.\n\n        Params:\n            index = The 0-based index of the key to retrieve.\n        Returns:\n            The key corresponding to the given index.\n        Throws:\n            `RegistryException` if no corresponding key is retrieved.\n     */\n    Key getKey(size_t index)\n    {\n        string name;\n        regProcessNthKey(m_key, (scope LONG delegate(DWORD, out string) getName)\n        {\n            enforceSucc(getName(to!DWORD(index), name), \"Invalid key\");\n        });\n        return m_key.getKey(name);\n    }\n\n    /**\n        The key at the given index.\n\n        Params:\n            index = The 0-based index of the key to retrieve.\n        Returns:\n            The key corresponding to the given index.\n        Throws:\n            `RegistryException` if no corresponding key is retrieved.\n     */\n    Key opIndex(size_t index)\n    {\n        return getKey(index);\n    }\n\npublic:\n    ///\n    int opApply(scope int delegate(ref Key key) dg)\n    {\n        int result = 0;\n        regProcessNthKey(m_key, (scope LONG delegate(DWORD, out string) getName)\n        {\n            for (DWORD index = 0; !result; ++index)\n            {\n                string name;\n                immutable res = getName(index, name);\n                if (res == ERROR_NO_MORE_ITEMS) // Enumeration complete\n                    break;\n                enforceSucc(res, \"Key enumeration incomplete\");\n\n                try\n                {\n                    Key key = m_key.getKey(name);\n                    result = dg(key);\n                }\n                catch (RegistryException e)\n                {\n                    // Skip inaccessible keys; they are\n                    // accessible via the KeyNameSequence\n                    if (e.error == ERROR_ACCESS_DENIED)\n                        continue;\n\n                    throw e;\n                }\n            }\n        });\n        return result;\n    }\n\nprivate:\n    Key m_key;\n}\n\n/**\n    An enumerable sequence representing the names of the values of a registry Key.\n\nExample:\n----\nKey key = ...\nforeach (string valueName; key.valueNames)\n{\n    // using valueName\n}\n----\n */\nclass ValueNameSequence\n{\n    @safe pure nothrow\n    invariant()\n    {\n        assert(m_key !is null);\n    }\n\nprivate:\n    @safe pure nothrow\n    this(Key key)\n    {\n        m_key = key;\n    }\n\npublic:\n    /**\n        The number of values.\n     */\n    @property size_t count() const\n    {\n        return m_key.valueCount;\n    }\n\n    /**\n        The name of the value at the given index.\n\n        Params:\n            index = The 0-based index of the value to retrieve.\n        Returns:\n            The name of the value corresponding to the given index.\n        Throws:\n            `RegistryException` if no corresponding value is retrieved.\n     */\n    string getValueName(size_t index)\n    {\n        string name;\n        regProcessNthValue(m_key, (scope LONG delegate(DWORD, out string) getName)\n        {\n            enforceSucc(getName(to!DWORD(index), name), \"Invalid value\");\n        });\n        return name;\n    }\n\n    /**\n        The name of the value at the given index.\n\n        Params:\n            index = The 0-based index of the value to retrieve.\n        Returns:\n            The name of the value corresponding to the given index.\n        Throws:\n            `RegistryException` if no corresponding value is retrieved.\n     */\n    string opIndex(size_t index)\n    {\n        return getValueName(index);\n    }\n\npublic:\n    ///\n    int opApply(scope int delegate(ref string name) dg)\n    {\n        int result = 0;\n        regProcessNthValue(m_key, (scope LONG delegate(DWORD, out string) getName)\n        {\n            for (DWORD index = 0; !result; ++index)\n            {\n                string name;\n                immutable res = getName(index, name);\n                if (res == ERROR_NO_MORE_ITEMS) // Enumeration complete\n                    break;\n                enforceSucc(res, \"Value name enumeration incomplete\");\n\n                result = dg(name);\n            }\n        });\n        return result;\n    }\n\nprivate:\n    Key m_key;\n}\n\n/**\n    An enumerable sequence representing the values of a registry Key.\n\nExample:\n----\nKey key = ...\nforeach (Value value; key.values)\n{\n    // using value\n}\n----\n */\nclass ValueSequence\n{\n    @safe pure nothrow\n    invariant()\n    {\n        assert(m_key !is null);\n    }\n\nprivate:\n    @safe pure nothrow\n    this(Key key)\n    {\n        m_key = key;\n    }\n\npublic:\n    /// The number of values\n    @property size_t count() const\n    {\n        return m_key.valueCount;\n    }\n\n    /**\n        The value at the given `index`.\n\n        Params:\n            index = The 0-based index of the value to retrieve\n        Returns:\n            The value corresponding to the given index.\n        Throws:\n            `RegistryException` if no corresponding value is retrieved\n     */\n    Value getValue(size_t index)\n    {\n        string name;\n        regProcessNthValue(m_key, (scope LONG delegate(DWORD, out string) getName)\n        {\n            enforceSucc(getName(to!DWORD(index), name), \"Invalid value\");\n        });\n        return m_key.getValue(name);\n    }\n\n    /**\n        The value at the given `index`.\n\n        Params:\n            index = The 0-based index of the value to retrieve.\n        Returns:\n            The value corresponding to the given index.\n        Throws:\n            `RegistryException` if no corresponding value is retrieved.\n     */\n    Value opIndex(size_t index)\n    {\n        return getValue(index);\n    }\n\npublic:\n    ///\n    int opApply(scope int delegate(ref Value value) dg)\n    {\n        int result = 0;\n        regProcessNthValue(m_key, (scope LONG delegate(DWORD, out string) getName)\n        {\n            for (DWORD index = 0; !result; ++index)\n            {\n                string name;\n                immutable res = getName(index, name);\n                if (res == ERROR_NO_MORE_ITEMS) // Enumeration complete\n                    break;\n                enforceSucc(res, \"Value enumeration incomplete\");\n\n                Value value = m_key.getValue(name);\n                result = dg(value);\n            }\n        });\n        return result;\n    }\n\nprivate:\n    Key m_key;\n}\n\n\n@system unittest\n{\n    debug(winreg) scope(success) writeln(\"unittest @\", __FILE__, \":\", __LINE__, \" succeeded.\");\n    debug(winreg) writefln(\"std.windows.registry.unittest read\");\n\n/+\n    // Mask for test speed up\n\n    Key HKCR  = Registry.classesRoot;\n    Key CLSID = HKCR.getKey(\"CLSID\");\n\n    foreach (Key key; CLSID.keys)\n    {\n        foreach (Value val; key.values)\n        {\n        }\n    }\n+/\n    Key HKCU = Registry.currentUser;\n    assert(HKCU);\n\n    // Enumerate all subkeys of key Software\n    Key softwareKey = HKCU.getKey(\"Software\");\n    assert(softwareKey);\n    foreach (Key key; softwareKey.keys)\n    {\n        //writefln(\"Key %s\", key.name);\n        foreach (Value val; key.values)\n        {\n        }\n    }\n}\n\n@system unittest\n{\n    debug(winreg) scope(success) writeln(\"unittest @\", __FILE__, \":\", __LINE__, \" succeeded.\");\n    debug(winreg) writefln(\"std.windows.registry.unittest write\");\n\n    // Warning: This unit test writes to the registry.\n    // The test can fail if you don't have sufficient rights\n\n    Key HKCU = Registry.currentUser;\n    assert(HKCU);\n\n    // Create a new key\n    string unittestKeyName = \"Temporary key for a D UnitTest which can be deleted afterwards\";\n    Key unittestKey = HKCU.createKey(unittestKeyName);\n    assert(unittestKey);\n    Key cityKey = unittestKey.createKey(\n        \"CityCollection using foreign names with umlauts and accents: \"\n        ~\"\\u00f6\\u00e4\\u00fc\\u00d6\\u00c4\\u00dc\\u00e0\\u00e1\\u00e2\\u00df\"\n    );\n    cityKey.setValue(\"K\\u00f6ln\", \"Germany\"); // Cologne\n    cityKey.setValue(\"\\u041c\\u0438\\u043d\\u0441\\u043a\", \"Belarus\"); // Minsk\n    cityKey.setValue(\"\\u5317\\u4eac\", \"China\"); // Bejing\n    bool foundCologne, foundMinsk, foundBeijing;\n    foreach (Value v; cityKey.values)\n    {\n        auto vname = v.name;\n        auto vvalue_SZ = v.value_SZ;\n        if (v.name == \"K\\u00f6ln\")\n        {\n            foundCologne = true;\n            assert(v.value_SZ == \"Germany\");\n        }\n        if (v.name == \"\\u041c\\u0438\\u043d\\u0441\\u043a\")\n        {\n            foundMinsk = true;\n            assert(v.value_SZ == \"Belarus\");\n        }\n        if (v.name == \"\\u5317\\u4eac\")\n        {\n            foundBeijing = true;\n            assert(v.value_SZ == \"China\");\n        }\n    }\n    assert(foundCologne);\n    assert(foundMinsk);\n    assert(foundBeijing);\n\n    Key stateKey = unittestKey.createKey(\"StateCollection\");\n    stateKey.setValue(\"Germany\", [\"D\\u00fcsseldorf\", \"K\\u00f6ln\", \"Hamburg\"]);\n    Value v = stateKey.getValue(\"Germany\");\n    string[] actual = v.value_MULTI_SZ;\n    assert(actual.length == 3);\n    assert(actual[0] == \"D\\u00fcsseldorf\");\n    assert(actual[1] == \"K\\u00f6ln\");\n    assert(actual[2] == \"Hamburg\");\n\n    Key numberKey = unittestKey.createKey(\"Number\");\n    numberKey.setValue(\"One\", 1);\n    Value one = numberKey.getValue(\"One\");\n    assert(one.value_SZ == \"1\");\n    assert(one.value_DWORD == 1);\n\n    unittestKey.deleteKey(numberKey.name);\n    unittestKey.deleteKey(stateKey.name);\n    unittestKey.deleteKey(cityKey.name);\n    HKCU.deleteKey(unittestKeyName);\n\n    auto e = collectException!RegistryException(HKCU.getKey(\"cDhmxsX9K23a8Uf869uB\"));\n    assert(e.msg.endsWith(\" (error 2)\"));\n}\n\n@system unittest\n{\n    Key HKCU = Registry.currentUser;\n    assert(HKCU);\n\n    Key key = HKCU.getKey(\"Control Panel\");\n    assert(key);\n    assert(key.keyCount >= 2);\n\n    // Make sure `key` isn't garbage-collected while iterating over it.\n    // Trigger a collection in the first iteration and check whether we\n    // make it successfully to the second iteration.\n    int i = 0;\n    foreach (name; key.keyNames)\n    {\n        if (i++ > 0)\n            break;\n\n        import core.memory;\n        GC.collect();\n    }\n    assert(i == 2);\n}\n"
  },
  {
    "path": "libphobos/src/std/windows/syserror.d",
    "content": "// Written in the D programming language.\n\n/**\n * Convert Win32 error code to string.\n *\n * Copyright: Copyright The D Language Foundation\" 2006 - 2013.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright)\n * Credits:   Based on code written by Regan Heath\n */\n/*          Copyright The D Language Foundation\" 2006 - 2013.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.windows.syserror;\nimport std.traits : isSomeString;\n\nversion (StdDdoc)\n{\n    private\n    {\n        alias DWORD = uint;\n        enum LANG_NEUTRAL = 0, SUBLANG_DEFAULT = 1;\n    }\n\n    /** Query the text for a Windows error code, as returned by\n        $(LINK2 http://msdn.microsoft.com/en-us/library/windows/desktop/ms679360.aspx,\n        `GetLastError`), as a D string.\n     */\n    string sysErrorString(\n        DWORD errCode,\n        // MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) is the user's default language\n        int langId = LANG_NEUTRAL,\n        int subLangId = SUBLANG_DEFAULT) @trusted;\n\n    /*********************\n       Thrown if errors that set\n       $(LINK2 http://msdn.microsoft.com/en-us/library/windows/desktop/ms679360.aspx,\n       `GetLastError`) occur.\n     */\n    class WindowsException : Exception\n    {\n        private alias DWORD = int;\n        final @property DWORD code(); /// `GetLastError`'s return value.\n        this(DWORD code, string str=null, string file = null, size_t line = 0) @trusted;\n    }\n\n    /++\n        If `!!value` is true, `value` is returned. Otherwise,\n        $(D new WindowsException(GetLastError(), msg)) is thrown.\n        `WindowsException` assumes that the last operation set\n        `GetLastError()` appropriately.\n\n        Example:\n        --------------------\n        wenforce(DeleteFileA(\"junk.tmp\"), \"DeleteFile failed\");\n        --------------------\n     +/\n    T wenforce(T, S)(T value, lazy S msg = null,\n        string file = __FILE__, size_t line = __LINE__) @safe\n    if (isSomeString!S);\n}\nelse:\n\nversion (Windows):\n\nimport core.sys.windows.windows;\nimport std.array : appender;\nimport std.conv : to;\nimport std.format : formattedWrite;\nimport std.windows.charset;\n\nstring sysErrorString(\n    DWORD errCode,\n    // MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) is the user's default language\n    int langId = LANG_NEUTRAL,\n    int subLangId = SUBLANG_DEFAULT) @trusted\n{\n    auto buf = appender!string();\n\n    if (!putSysError(errCode, buf, MAKELANGID(langId, subLangId)))\n    {\n        throw new Exception(\n            \"failed getting error string for WinAPI error code: \" ~\n            sysErrorString(GetLastError()));\n    }\n\n    return buf.data;\n}\n\nbool putSysError(Writer)(DWORD code, Writer w, /*WORD*/int langId = 0)\n{\n    wchar *lpMsgBuf = null;\n    auto res = FormatMessageW(\n        FORMAT_MESSAGE_ALLOCATE_BUFFER |\n        FORMAT_MESSAGE_FROM_SYSTEM |\n        FORMAT_MESSAGE_IGNORE_INSERTS,\n        null,\n        code,\n        langId,\n        cast(LPWSTR)&lpMsgBuf,\n        0,\n        null);\n    scope(exit) if (lpMsgBuf) LocalFree(lpMsgBuf);\n\n    if (lpMsgBuf)\n    {\n        import std.string : strip;\n        w.put(lpMsgBuf[0 .. res].strip());\n        return true;\n    }\n    else\n        return false;\n}\n\n\nclass WindowsException : Exception\n{\n    import core.sys.windows.windows : DWORD;\n\n    final @property DWORD code() { return _code; } /// `GetLastError`'s return value.\n    private DWORD _code;\n\n    this(DWORD code, string str=null, string file = null, size_t line = 0) @trusted\n    {\n        _code = code;\n\n        auto buf = appender!string();\n\n        if (str != null)\n        {\n            buf.put(str);\n            if (code)\n                buf.put(\": \");\n        }\n\n        if (code)\n        {\n            auto success = putSysError(code, buf);\n            formattedWrite(buf, success ? \" (error %d)\" : \"Error %d\", code);\n        }\n\n        super(buf.data, file, line);\n    }\n}\n\n\nT wenforce(T, S)(T value, lazy S msg = null,\nstring file = __FILE__, size_t line = __LINE__)\nif (isSomeString!S)\n{\n    if (!value)\n        throw new WindowsException(GetLastError(), to!string(msg), file, line);\n    return value;\n}\n\nT wenforce(T)(T condition, const(char)[] name, const(wchar)* namez, string file = __FILE__, size_t line = __LINE__)\n{\n    if (condition)\n        return condition;\n    string names;\n    if (!name)\n    {\n        static string trustedToString(const(wchar)* stringz) @trusted\n        {\n            import core.stdc.wchar_ : wcslen;\n            import std.conv : to;\n            auto len = wcslen(stringz);\n            return to!string(stringz[0 .. len]);\n        }\n\n        names = trustedToString(namez);\n    }\n    else\n        names = to!string(name);\n    throw new WindowsException(GetLastError(), names, file, line);\n}\n\nversion (Windows)\n@system unittest\n{\n    import std.algorithm.searching : startsWith, endsWith;\n    import std.exception;\n    import std.string;\n\n    auto e = collectException!WindowsException(\n        DeleteFileA(\"unexisting.txt\").wenforce(\"DeleteFile\")\n    );\n    assert(e.code == ERROR_FILE_NOT_FOUND);\n    assert(e.msg.startsWith(\"DeleteFile: \"));\n    // can't test the entire message, as it depends on Windows locale\n    assert(e.msg.endsWith(\" (error 2)\"));\n\n    // Test code zero\n    e = new WindowsException(0);\n    assert(e.msg == \"\");\n\n    e = new WindowsException(0, \"Test\");\n    assert(e.msg == \"Test\");\n}\n"
  },
  {
    "path": "libphobos/src/std/xml.d",
    "content": "// Written in the D programming language.\n\n/**\n$(RED Warning: This module is considered out-dated and not up to Phobos'\n      current standards. It will remain until we have a suitable replacement,\n      but be aware that it will not remain long term.)\n\nClasses and functions for creating and parsing XML\n\nThe basic architecture of this module is that there are standalone functions,\nclasses for constructing an XML document from scratch (Tag, Element and\nDocument), and also classes for parsing a pre-existing XML file (ElementParser\nand DocumentParser). The parsing classes <i>may</i> be used to build a\nDocument, but that is not their primary purpose. The handling capabilities of\nDocumentParser and ElementParser are sufficiently customizable that you can\nmake them do pretty much whatever you want.\n\nExample: This example creates a DOM (Document Object Model) tree\n    from an XML file.\n------------------------------------------------------------------------------\nimport std.xml;\nimport std.stdio;\nimport std.string;\nimport std.file;\n\n// books.xml is used in various samples throughout the Microsoft XML Core\n// Services (MSXML) SDK.\n//\n// See http://msdn2.microsoft.com/en-us/library/ms762271(VS.85).aspx\n\nvoid main()\n{\n    string s = cast(string) std.file.read(\"books.xml\");\n\n    // Check for well-formedness\n    check(s);\n\n    // Make a DOM tree\n    auto doc = new Document(s);\n\n    // Plain-print it\n    writeln(doc);\n}\n------------------------------------------------------------------------------\n\nExample: This example does much the same thing, except that the file is\n    deconstructed and reconstructed by hand. This is more work, but the\n    techniques involved offer vastly more power.\n------------------------------------------------------------------------------\nimport std.xml;\nimport std.stdio;\nimport std.string;\n\nstruct Book\n{\n    string id;\n    string author;\n    string title;\n    string genre;\n    string price;\n    string pubDate;\n    string description;\n}\n\nvoid main()\n{\n    string s = cast(string) std.file.read(\"books.xml\");\n\n    // Check for well-formedness\n    check(s);\n\n    // Take it apart\n    Book[] books;\n\n    auto xml = new DocumentParser(s);\n    xml.onStartTag[\"book\"] = (ElementParser xml)\n    {\n        Book book;\n        book.id = xml.tag.attr[\"id\"];\n\n        xml.onEndTag[\"author\"]       = (in Element e) { book.author      = e.text(); };\n        xml.onEndTag[\"title\"]        = (in Element e) { book.title       = e.text(); };\n        xml.onEndTag[\"genre\"]        = (in Element e) { book.genre       = e.text(); };\n        xml.onEndTag[\"price\"]        = (in Element e) { book.price       = e.text(); };\n        xml.onEndTag[\"publish-date\"] = (in Element e) { book.pubDate     = e.text(); };\n        xml.onEndTag[\"description\"]  = (in Element e) { book.description = e.text(); };\n\n        xml.parse();\n\n        books ~= book;\n    };\n    xml.parse();\n\n    // Put it back together again;\n    auto doc = new Document(new Tag(\"catalog\"));\n    foreach (book;books)\n    {\n        auto element = new Element(\"book\");\n        element.tag.attr[\"id\"] = book.id;\n\n        element ~= new Element(\"author\",      book.author);\n        element ~= new Element(\"title\",       book.title);\n        element ~= new Element(\"genre\",       book.genre);\n        element ~= new Element(\"price\",       book.price);\n        element ~= new Element(\"publish-date\",book.pubDate);\n        element ~= new Element(\"description\", book.description);\n\n        doc ~= element;\n    }\n\n    // Pretty-print it\n    writefln(join(doc.pretty(3),\"\\n\"));\n}\n-------------------------------------------------------------------------------\nCopyright: Copyright Janice Caron 2008 - 2009.\nLicense:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\nAuthors:   Janice Caron\nSource:    $(PHOBOSSRC std/xml.d)\n*/\n/*\n         Copyright Janice Caron 2008 - 2009.\nDistributed under the Boost Software License, Version 1.0.\n   (See accompanying file LICENSE_1_0.txt or copy at\n         http://www.boost.org/LICENSE_1_0.txt)\n*/\nmodule std.xml;\n\nenum cdata = \"<![CDATA[\";\n\n/**\n * Returns true if the character is a character according to the XML standard\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Params:\n *    c = the character to be tested\n */\nbool isChar(dchar c) @safe @nogc pure nothrow // rule 2\n{\n    if (c <= 0xD7FF)\n    {\n        if (c >= 0x20)\n            return true;\n        switch (c)\n        {\n        case 0xA:\n        case 0x9:\n        case 0xD:\n            return true;\n        default:\n            return false;\n        }\n    }\n    else if (0xE000 <= c && c <= 0x10FFFF)\n    {\n        if ((c & 0x1FFFFE) != 0xFFFE) // U+FFFE and U+FFFF\n            return true;\n    }\n    return false;\n}\n\n@safe @nogc nothrow pure unittest\n{\n    assert(!isChar(cast(dchar) 0x8));\n    assert( isChar(cast(dchar) 0x9));\n    assert( isChar(cast(dchar) 0xA));\n    assert(!isChar(cast(dchar) 0xB));\n    assert(!isChar(cast(dchar) 0xC));\n    assert( isChar(cast(dchar) 0xD));\n    assert(!isChar(cast(dchar) 0xE));\n    assert(!isChar(cast(dchar) 0x1F));\n    assert( isChar(cast(dchar) 0x20));\n    assert( isChar('J'));\n    assert( isChar(cast(dchar) 0xD7FF));\n    assert(!isChar(cast(dchar) 0xD800));\n    assert(!isChar(cast(dchar) 0xDFFF));\n    assert( isChar(cast(dchar) 0xE000));\n    assert( isChar(cast(dchar) 0xFFFD));\n    assert(!isChar(cast(dchar) 0xFFFE));\n    assert(!isChar(cast(dchar) 0xFFFF));\n    assert( isChar(cast(dchar) 0x10000));\n    assert( isChar(cast(dchar) 0x10FFFF));\n    assert(!isChar(cast(dchar) 0x110000));\n\n    debug (stdxml_TestHardcodedChecks)\n    {\n        foreach (c; 0 .. dchar.max + 1)\n            assert(isChar(c) == lookup(CharTable, c));\n    }\n}\n\n/**\n * Returns true if the character is whitespace according to the XML standard\n *\n * Only the following characters are considered whitespace in XML - space, tab,\n * carriage return and linefeed\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Params:\n *    c = the character to be tested\n */\nbool isSpace(dchar c) @safe @nogc pure nothrow\n{\n    return c == '\\u0020' || c == '\\u0009' || c == '\\u000A' || c == '\\u000D';\n}\n\n/**\n * Returns true if the character is a digit according to the XML standard\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Params:\n *    c = the character to be tested\n */\nbool isDigit(dchar c) @safe @nogc pure nothrow\n{\n    if (c <= 0x0039 && c >= 0x0030)\n        return true;\n    else\n        return lookup(DigitTable,c);\n}\n\n@safe @nogc nothrow pure unittest\n{\n    debug (stdxml_TestHardcodedChecks)\n    {\n        foreach (c; 0 .. dchar.max + 1)\n            assert(isDigit(c) == lookup(DigitTable, c));\n    }\n}\n\n/**\n * Returns true if the character is a letter according to the XML standard\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Params:\n *    c = the character to be tested\n */\nbool isLetter(dchar c) @safe @nogc nothrow pure // rule 84\n{\n    return isIdeographic(c) || isBaseChar(c);\n}\n\n/**\n * Returns true if the character is an ideographic character according to the\n * XML standard\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Params:\n *    c = the character to be tested\n */\nbool isIdeographic(dchar c) @safe @nogc nothrow pure\n{\n    if (c == 0x3007)\n        return true;\n    if (c <= 0x3029 && c >= 0x3021 )\n        return true;\n    if (c <= 0x9FA5 && c >= 0x4E00)\n        return true;\n    return false;\n}\n\n@safe @nogc nothrow pure unittest\n{\n    assert(isIdeographic('\\u4E00'));\n    assert(isIdeographic('\\u9FA5'));\n    assert(isIdeographic('\\u3007'));\n    assert(isIdeographic('\\u3021'));\n    assert(isIdeographic('\\u3029'));\n\n    debug (stdxml_TestHardcodedChecks)\n    {\n        foreach (c; 0 .. dchar.max + 1)\n            assert(isIdeographic(c) == lookup(IdeographicTable, c));\n    }\n}\n\n/**\n * Returns true if the character is a base character according to the XML\n * standard\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Params:\n *    c = the character to be tested\n */\nbool isBaseChar(dchar c) @safe @nogc nothrow pure\n{\n    return lookup(BaseCharTable,c);\n}\n\n/**\n * Returns true if the character is a combining character according to the\n * XML standard\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Params:\n *    c = the character to be tested\n */\nbool isCombiningChar(dchar c) @safe @nogc nothrow pure\n{\n    return lookup(CombiningCharTable,c);\n}\n\n/**\n * Returns true if the character is an extender according to the XML standard\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Params:\n *    c = the character to be tested\n */\nbool isExtender(dchar c) @safe @nogc nothrow pure\n{\n    return lookup(ExtenderTable,c);\n}\n\n/**\n * Encodes a string by replacing all characters which need to be escaped with\n * appropriate predefined XML entities.\n *\n * encode() escapes certain characters (ampersand, quote, apostrophe, less-than\n * and greater-than), and similarly, decode() unescapes them. These functions\n * are provided for convenience only. You do not need to use them when using\n * the std.xml classes, because then all the encoding and decoding will be done\n * for you automatically.\n *\n * If the string is not modified, the original will be returned.\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Params:\n *      s = The string to be encoded\n *\n * Returns: The encoded string\n *\n * Example:\n * --------------\n * writefln(encode(\"a > b\")); // writes \"a &gt; b\"\n * --------------\n */\nS encode(S)(S s)\n{\n    import std.array : appender;\n\n    string r;\n    size_t lastI;\n    auto result = appender!S();\n\n    foreach (i, c; s)\n    {\n        switch (c)\n        {\n        case '&':  r = \"&amp;\"; break;\n        case '\"':  r = \"&quot;\"; break;\n        case '\\'': r = \"&apos;\"; break;\n        case '<':  r = \"&lt;\"; break;\n        case '>':  r = \"&gt;\"; break;\n        default: continue;\n        }\n        // Replace with r\n        result.put(s[lastI .. i]);\n        result.put(r);\n        lastI = i + 1;\n    }\n\n    if (!result.data.ptr) return s;\n    result.put(s[lastI .. $]);\n    return result.data;\n}\n\n@safe pure unittest\n{\n    auto s = \"hello\";\n    assert(encode(s) is s);\n    assert(encode(\"a > b\") == \"a &gt; b\", encode(\"a > b\"));\n    assert(encode(\"a < b\") == \"a &lt; b\");\n    assert(encode(\"don't\") == \"don&apos;t\");\n    assert(encode(\"\\\"hi\\\"\") == \"&quot;hi&quot;\", encode(\"\\\"hi\\\"\"));\n    assert(encode(\"cat & dog\") == \"cat &amp; dog\");\n}\n\n/**\n * Mode to use for decoding.\n *\n * $(DDOC_ENUM_MEMBERS NONE) Do not decode\n * $(DDOC_ENUM_MEMBERS LOOSE) Decode, but ignore errors\n * $(DDOC_ENUM_MEMBERS STRICT) Decode, and throw exception on error\n */\nenum DecodeMode\n{\n    NONE, LOOSE, STRICT\n}\n\n/**\n * Decodes a string by unescaping all predefined XML entities.\n *\n * encode() escapes certain characters (ampersand, quote, apostrophe, less-than\n * and greater-than), and similarly, decode() unescapes them. These functions\n * are provided for convenience only. You do not need to use them when using\n * the std.xml classes, because then all the encoding and decoding will be done\n * for you automatically.\n *\n * This function decodes the entities &amp;amp;, &amp;quot;, &amp;apos;,\n * &amp;lt; and &amp;gt,\n * as well as decimal and hexadecimal entities such as &amp;#x20AC;\n *\n * If the string does not contain an ampersand, the original will be returned.\n *\n * Note that the \"mode\" parameter can be one of DecodeMode.NONE (do not\n * decode), DecodeMode.LOOSE (decode, but ignore errors), or DecodeMode.STRICT\n * (decode, and throw a DecodeException in the event of an error).\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Params:\n *      s = The string to be decoded\n *      mode = (optional) Mode to use for decoding. (Defaults to LOOSE).\n *\n * Throws: DecodeException if mode == DecodeMode.STRICT and decode fails\n *\n * Returns: The decoded string\n *\n * Example:\n * --------------\n * writefln(decode(\"a &gt; b\")); // writes \"a > b\"\n * --------------\n */\nstring decode(string s, DecodeMode mode=DecodeMode.LOOSE) @safe pure\n{\n    import std.algorithm.searching : startsWith;\n\n    if (mode == DecodeMode.NONE) return s;\n\n    string buffer;\n    foreach (ref i; 0 .. s.length)\n    {\n        char c = s[i];\n        if (c != '&')\n        {\n            if (buffer.length != 0) buffer ~= c;\n        }\n        else\n        {\n            if (buffer.length == 0)\n            {\n                buffer = s[0 .. i].dup;\n            }\n            if (startsWith(s[i..$],\"&#\"))\n            {\n                try\n                {\n                    dchar d;\n                    string t = s[i..$];\n                    checkCharRef(t, d);\n                    char[4] temp;\n                    import std.utf : encode;\n                    buffer ~= temp[0 .. encode(temp, d)];\n                    i = s.length - t.length - 1;\n                }\n                catch (Err e)\n                {\n                    if (mode == DecodeMode.STRICT)\n                        throw new DecodeException(\"Unescaped &\");\n                    buffer ~= '&';\n                }\n            }\n            else if (startsWith(s[i..$],\"&amp;\" )) { buffer ~= '&';  i += 4; }\n            else if (startsWith(s[i..$],\"&quot;\")) { buffer ~= '\"';  i += 5; }\n            else if (startsWith(s[i..$],\"&apos;\")) { buffer ~= '\\''; i += 5; }\n            else if (startsWith(s[i..$],\"&lt;\"  )) { buffer ~= '<';  i += 3; }\n            else if (startsWith(s[i..$],\"&gt;\"  )) { buffer ~= '>';  i += 3; }\n            else\n            {\n                if (mode == DecodeMode.STRICT)\n                    throw new DecodeException(\"Unescaped &\");\n                buffer ~= '&';\n            }\n        }\n    }\n    return (buffer.length == 0) ? s : buffer;\n}\n\n@safe pure unittest\n{\n    void assertNot(string s) pure\n    {\n        bool b = false;\n        try { decode(s,DecodeMode.STRICT); }\n        catch (DecodeException e) { b = true; }\n        assert(b,s);\n    }\n\n    // Assert that things that should work, do\n    auto s = \"hello\";\n    assert(decode(s,                DecodeMode.STRICT) is s);\n    assert(decode(\"a &gt; b\",       DecodeMode.STRICT) == \"a > b\");\n    assert(decode(\"a &lt; b\",       DecodeMode.STRICT) == \"a < b\");\n    assert(decode(\"don&apos;t\",     DecodeMode.STRICT) == \"don't\");\n    assert(decode(\"&quot;hi&quot;\", DecodeMode.STRICT) == \"\\\"hi\\\"\");\n    assert(decode(\"cat &amp; dog\",  DecodeMode.STRICT) == \"cat & dog\");\n    assert(decode(\"&#42;\",          DecodeMode.STRICT) == \"*\");\n    assert(decode(\"&#x2A;\",         DecodeMode.STRICT) == \"*\");\n    assert(decode(\"cat & dog\",      DecodeMode.LOOSE) == \"cat & dog\");\n    assert(decode(\"a &gt b\",        DecodeMode.LOOSE) == \"a &gt b\");\n    assert(decode(\"&#;\",            DecodeMode.LOOSE) == \"&#;\");\n    assert(decode(\"&#x;\",           DecodeMode.LOOSE) == \"&#x;\");\n    assert(decode(\"&#2G;\",          DecodeMode.LOOSE) == \"&#2G;\");\n    assert(decode(\"&#x2G;\",         DecodeMode.LOOSE) == \"&#x2G;\");\n\n    // Assert that things that shouldn't work, don't\n    assertNot(\"cat & dog\");\n    assertNot(\"a &gt b\");\n    assertNot(\"&#;\");\n    assertNot(\"&#x;\");\n    assertNot(\"&#2G;\");\n    assertNot(\"&#x2G;\");\n}\n\n/**\n * Class representing an XML document.\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n */\nclass Document : Element\n{\n    /**\n     * Contains all text which occurs before the root element.\n     * Defaults to &lt;?xml version=\"1.0\"?&gt;\n     */\n    string prolog = \"<?xml version=\\\"1.0\\\"?>\";\n    /**\n     * Contains all text which occurs after the root element.\n     * Defaults to the empty string\n     */\n    string epilog;\n\n    /**\n     * Constructs a Document by parsing XML text.\n     *\n     * This function creates a complete DOM (Document Object Model) tree.\n     *\n     * The input to this function MUST be valid XML.\n     * This is enforced by DocumentParser's in contract.\n     *\n     * Params:\n     *      s = the complete XML text.\n     */\n    this(string s)\n    in\n    {\n        assert(s.length != 0);\n    }\n    do\n    {\n        auto xml = new DocumentParser(s);\n        string tagString = xml.tag.tagString;\n\n        this(xml.tag);\n        prolog = s[0 .. tagString.ptr - s.ptr];\n        parse(xml);\n        epilog = *xml.s;\n    }\n\n    /**\n     * Constructs a Document from a Tag.\n     *\n     * Params:\n     *      tag = the start tag of the document.\n     */\n    this(const(Tag) tag)\n    {\n        super(tag);\n    }\n\n    const\n    {\n        /**\n         * Compares two Documents for equality\n         *\n         * Example:\n         * --------------\n         * Document d1,d2;\n         * if (d1 == d2) { }\n         * --------------\n         */\n        override bool opEquals(scope const Object o) const\n        {\n            const doc = toType!(const Document)(o);\n            return prolog == doc.prolog\n                && (cast(const) this).Element.opEquals(cast(const) doc)\n                && epilog == doc.epilog;\n        }\n\n        /**\n         * Compares two Documents\n         *\n         * You should rarely need to call this function. It exists so that\n         * Documents can be used as associative array keys.\n         *\n         * Example:\n         * --------------\n         * Document d1,d2;\n         * if (d1 < d2) { }\n         * --------------\n         */\n        override int opCmp(scope const Object o) scope const\n        {\n            const doc = toType!(const Document)(o);\n            if (prolog != doc.prolog)\n                return prolog < doc.prolog ? -1 : 1;\n            if (int cmp = this.Element.opCmp(doc))\n                return cmp;\n            if (epilog != doc.epilog)\n                return epilog < doc.epilog ? -1 : 1;\n            return 0;\n        }\n\n        /**\n         * Returns the hash of a Document\n         *\n         * You should rarely need to call this function. It exists so that\n         * Documents can be used as associative array keys.\n         */\n        override size_t toHash() scope const @trusted\n        {\n            return hash(prolog, hash(epilog, (cast() this).Element.toHash()));\n        }\n\n        /**\n         * Returns the string representation of a Document. (That is, the\n         * complete XML of a document).\n         */\n        override string toString() scope const @safe\n        {\n            return prolog ~ super.toString() ~ epilog;\n        }\n    }\n}\n\n@system unittest\n{\n    // https://issues.dlang.org/show_bug.cgi?id=14966\n    auto xml = `<?xml version=\"1.0\" encoding=\"UTF-8\"?><foo></foo>`;\n\n    auto a = new Document(xml);\n    auto b = new Document(xml);\n    assert(a == b);\n    assert(!(a < b));\n    int[Document] aa;\n    aa[a] = 1;\n    assert(aa[b] == 1);\n\n    b ~= new Element(\"b\");\n    assert(a < b);\n    assert(b > a);\n}\n\n/**\n * Class representing an XML element.\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n */\nclass Element : Item\n{\n    Tag tag; /// The start tag of the element\n    Item[] items; /// The element's items\n    Text[] texts; /// The element's text items\n    CData[] cdatas; /// The element's CData items\n    Comment[] comments; /// The element's comments\n    ProcessingInstruction[] pis; /// The element's processing instructions\n    Element[] elements; /// The element's child elements\n\n    /**\n     * Constructs an Element given a name and a string to be used as a Text\n     * interior.\n     *\n     * Params:\n     *      name = the name of the element.\n     *      interior = (optional) the string interior.\n     *\n     * Example:\n     * -------------------------------------------------------\n     * auto element = new Element(\"title\",\"Serenity\")\n     *     // constructs the element <title>Serenity</title>\n     * -------------------------------------------------------\n     */\n    this(string name, string interior=null) @safe pure\n    {\n        this(new Tag(name));\n        if (interior.length != 0) opCatAssign(new Text(interior));\n    }\n\n    /**\n     * Constructs an Element from a Tag.\n     *\n     * Params:\n     *      tag_ = the start or empty tag of the element.\n     */\n    this(const(Tag) tag_) @safe pure\n    {\n        this.tag = new Tag(tag_.name);\n        tag.type = TagType.EMPTY;\n        foreach (k,v;tag_.attr) tag.attr[k] = v;\n        tag.tagString = tag_.tagString;\n    }\n\n    /**\n     * Append a text item to the interior of this element\n     *\n     * Params:\n     *      item = the item you wish to append.\n     *\n     * Example:\n     * --------------\n     * Element element;\n     * element ~= new Text(\"hello\");\n     * --------------\n     */\n    void opCatAssign(Text item) @safe pure\n    {\n        texts ~= item;\n        appendItem(item);\n    }\n\n    /**\n     * Append a CData item to the interior of this element\n     *\n     * Params:\n     *      item = the item you wish to append.\n     *\n     * Example:\n     * --------------\n     * Element element;\n     * element ~= new CData(\"hello\");\n     * --------------\n     */\n    void opCatAssign(CData item) @safe pure\n    {\n        cdatas ~= item;\n        appendItem(item);\n    }\n\n    /**\n     * Append a comment to the interior of this element\n     *\n     * Params:\n     *      item = the item you wish to append.\n     *\n     * Example:\n     * --------------\n     * Element element;\n     * element ~= new Comment(\"hello\");\n     * --------------\n     */\n    void opCatAssign(Comment item) @safe pure\n    {\n        comments ~= item;\n        appendItem(item);\n    }\n\n    /**\n     * Append a processing instruction to the interior of this element\n     *\n     * Params:\n     *      item = the item you wish to append.\n     *\n     * Example:\n     * --------------\n     * Element element;\n     * element ~= new ProcessingInstruction(\"hello\");\n     * --------------\n     */\n    void opCatAssign(ProcessingInstruction item) @safe pure\n    {\n        pis ~= item;\n        appendItem(item);\n    }\n\n    /**\n     * Append a complete element to the interior of this element\n     *\n     * Params:\n     *      item = the item you wish to append.\n     *\n     * Example:\n     * --------------\n     * Element element;\n     * Element other = new Element(\"br\");\n     * element ~= other;\n     *    // appends element representing <br />\n     * --------------\n     */\n    void opCatAssign(Element item) @safe pure\n    {\n        elements ~= item;\n        appendItem(item);\n    }\n\n    private void appendItem(Item item) @safe pure\n    {\n        items ~= item;\n        if (tag.type == TagType.EMPTY && !item.isEmptyXML)\n            tag.type = TagType.START;\n    }\n\n    private void parse(ElementParser xml)\n    {\n        xml.onText = (string s) { opCatAssign(new Text(s)); };\n        xml.onCData = (string s) { opCatAssign(new CData(s)); };\n        xml.onComment = (string s) { opCatAssign(new Comment(s)); };\n        xml.onPI = (string s) { opCatAssign(new ProcessingInstruction(s)); };\n\n        xml.onStartTag[null] = (ElementParser xml)\n        {\n            auto e = new Element(xml.tag);\n            e.parse(xml);\n            opCatAssign(e);\n        };\n\n        xml.parse();\n    }\n\n    /**\n     * Compares two Elements for equality\n     *\n     * Example:\n     * --------------\n     * Element e1,e2;\n     * if (e1 == e2) { }\n     * --------------\n     */\n    override bool opEquals(scope const Object o) const\n    {\n        const element = toType!(const Element)(o);\n        immutable len = items.length;\n        if (len != element.items.length) return false;\n        foreach (i; 0 .. len)\n        {\n            if (!items[i].opEquals(element.items[i])) return false;\n        }\n        return true;\n    }\n\n    /**\n     * Compares two Elements\n     *\n     * You should rarely need to call this function. It exists so that Elements\n     * can be used as associative array keys.\n     *\n     * Example:\n     * --------------\n     * Element e1,e2;\n     * if (e1 < e2) { }\n     * --------------\n     */\n    override int opCmp(scope const Object o) @safe const\n    {\n        const element = toType!(const Element)(o);\n        for (uint i=0; ; ++i)\n        {\n            if (i == items.length && i == element.items.length) return 0;\n            if (i == items.length) return -1;\n            if (i == element.items.length) return 1;\n            if (!items[i].opEquals(element.items[i]))\n                return items[i].opCmp(element.items[i]);\n        }\n    }\n\n    /**\n     * Returns the hash of an Element\n     *\n     * You should rarely need to call this function. It exists so that Elements\n     * can be used as associative array keys.\n     */\n    override size_t toHash() scope const @safe\n    {\n        size_t hash = tag.toHash();\n        foreach (item;items) hash += item.toHash();\n        return hash;\n    }\n\n    const\n    {\n        /**\n         * Returns the decoded interior of an element.\n         *\n         * The element is assumed to contain text <i>only</i>. So, for\n         * example, given XML such as \"&lt;title&gt;Good &amp;amp;\n         * Bad&lt;/title&gt;\", will return \"Good &amp; Bad\".\n         *\n         * Params:\n         *      mode = (optional) Mode to use for decoding. (Defaults to LOOSE).\n         *\n         * Throws: DecodeException if decode fails\n         */\n        string text(DecodeMode mode=DecodeMode.LOOSE)\n        {\n            string buffer;\n            foreach (item;items)\n            {\n                Text t = cast(Text) item;\n                if (t is null) throw new DecodeException(item.toString());\n                buffer ~= decode(t.toString(),mode);\n            }\n            return buffer;\n        }\n\n        /**\n         * Returns an indented string representation of this item\n         *\n         * Params:\n         *      indent = (optional) number of spaces by which to indent this\n         *          element. Defaults to 2.\n         */\n        override string[] pretty(uint indent=2) scope\n        {\n            import std.algorithm.searching : count;\n            import std.string : rightJustify;\n\n            if (isEmptyXML) return [ tag.toEmptyString() ];\n\n            if (items.length == 1)\n            {\n                auto t = cast(const(Text))(items[0]);\n                if (t !is null)\n                {\n                    return [tag.toStartString() ~ t.toString() ~ tag.toEndString()];\n                }\n            }\n\n            string[] a = [ tag.toStartString() ];\n            foreach (item;items)\n            {\n                string[] b = item.pretty(indent);\n                foreach (s;b)\n                {\n                    a ~= rightJustify(s,count(s) + indent);\n                }\n            }\n            a ~= tag.toEndString();\n            return a;\n        }\n\n        /**\n         * Returns the string representation of an Element\n         *\n         * Example:\n         * --------------\n         * auto element = new Element(\"br\");\n         * writefln(element.toString()); // writes \"<br />\"\n         * --------------\n         */\n        override string toString() scope @safe\n        {\n            if (isEmptyXML) return tag.toEmptyString();\n\n            string buffer = tag.toStartString();\n            foreach (item;items) { buffer ~= item.toString(); }\n            buffer ~= tag.toEndString();\n            return buffer;\n        }\n\n        override @property @safe pure @nogc nothrow bool isEmptyXML() const scope { return items.length == 0; }\n    }\n}\n\n/**\n * Tag types.\n *\n * $(DDOC_ENUM_MEMBERS START) Used for start tags\n * $(DDOC_ENUM_MEMBERS END) Used for end tags\n * $(DDOC_ENUM_MEMBERS EMPTY) Used for empty tags\n *\n */\nenum TagType { START, END, EMPTY }\n\n/**\n * Class representing an XML tag.\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * The class invariant guarantees\n * <ul>\n * <li> that $(B type) is a valid enum TagType value</li>\n * <li> that $(B name) consists of valid characters</li>\n * <li> that each attribute name consists of valid characters</li>\n * </ul>\n */\nclass Tag\n{\n    TagType type = TagType.START;   /// Type of tag\n    string name;                    /// Tag name\n    string[string] attr;            /// Associative array of attributes\n    private string tagString;\n\n    invariant()\n    {\n        string s;\n        string t;\n\n        assert(type == TagType.START\n            || type == TagType.END\n            || type == TagType.EMPTY);\n\n        s = name;\n        try { checkName(s,t); }\n        catch (Err e) { assert(false,\"Invalid tag name:\" ~ e.toString()); }\n\n        foreach (k,v;attr)\n        {\n            s = k;\n            try { checkName(s,t); }\n            catch (Err e)\n                { assert(false,\"Invalid atrribute name:\" ~ e.toString()); }\n        }\n    }\n\n    /**\n     * Constructs an instance of Tag with a specified name and type\n     *\n     * The constructor does not initialize the attributes. To initialize the\n     * attributes, you access the $(B attr) member variable.\n     *\n     * Params:\n     *      name = the Tag's name\n     *      type = (optional) the Tag's type. If omitted, defaults to\n     *          TagType.START.\n     *\n     * Example:\n     * --------------\n     * auto tag = new Tag(\"img\",Tag.EMPTY);\n     * tag.attr[\"src\"] = \"http://example.com/example.jpg\";\n     * --------------\n     */\n    this(string name, TagType type=TagType.START) @safe pure\n    {\n        this.name = name;\n        this.type = type;\n    }\n\n    /* Private constructor (so don't ddoc this!)\n     *\n     * Constructs a Tag by parsing the string representation, e.g. \"<html>\".\n     *\n     * The string is passed by reference, and is advanced over all characters\n     * consumed.\n     *\n     * The second parameter is a dummy parameter only, required solely to\n     * distinguish this constructor from the public one.\n     */\n    private this(ref string s, bool dummy) @safe pure\n    {\n        import std.algorithm.searching : countUntil;\n        import std.ascii : isWhite;\n        import std.utf : byCodeUnit;\n\n        tagString = s;\n        try\n        {\n            reqc(s,'<');\n            if (optc(s,'/')) type = TagType.END;\n            ptrdiff_t i = s.byCodeUnit.countUntil(\">\", \"/>\", \" \", \"\\t\", \"\\v\", \"\\r\", \"\\n\", \"\\f\");\n            name = s[0 .. i];\n            s = s[i .. $];\n\n            i = s.byCodeUnit.countUntil!(a => !isWhite(a));\n            s = s[i .. $];\n\n            while (s.length > 0 && s[0] != '>' && s[0] != '/')\n            {\n                i = s.byCodeUnit.countUntil(\"=\", \" \", \"\\t\", \"\\v\", \"\\r\", \"\\n\", \"\\f\");\n                string key = s[0 .. i];\n                s = s[i .. $];\n\n                i = s.byCodeUnit.countUntil!(a => !isWhite(a));\n                s = s[i .. $];\n                reqc(s,'=');\n                i = s.byCodeUnit.countUntil!(a => !isWhite(a));\n                s = s[i .. $];\n\n                immutable char quote = requireOneOf(s,\"'\\\"\");\n                i = s.byCodeUnit.countUntil(quote);\n                string val = decode(s[0 .. i], DecodeMode.LOOSE);\n                s = s[i .. $];\n                reqc(s,quote);\n\n                i = s.byCodeUnit.countUntil!(a => !isWhite(a));\n                s = s[i .. $];\n                attr[key] = val;\n            }\n            if (optc(s,'/'))\n            {\n                if (type == TagType.END) throw new TagException(\"\");\n                type = TagType.EMPTY;\n            }\n            reqc(s,'>');\n            tagString.length = tagString.length - s.length;\n        }\n        catch (XMLException e)\n        {\n            tagString.length = tagString.length - s.length;\n            throw new TagException(tagString);\n        }\n    }\n\n    const\n    {\n        /**\n         * Compares two Tags for equality\n         *\n         * You should rarely need to call this function. It exists so that Tags\n         * can be used as associative array keys.\n         *\n         * Example:\n         * --------------\n         * Tag tag1,tag2\n         * if (tag1 == tag2) { }\n         * --------------\n         */\n        override bool opEquals(scope Object o)\n        {\n            const tag = toType!(const Tag)(o);\n            return\n                (name != tag.name) ? false : (\n                (attr != tag.attr) ? false : (\n                (type != tag.type) ? false : (\n            true )));\n        }\n\n        /**\n         * Compares two Tags\n         *\n         * Example:\n         * --------------\n         * Tag tag1,tag2\n         * if (tag1 < tag2) { }\n         * --------------\n         */\n        override int opCmp(Object o)\n        {\n            const tag = toType!(const Tag)(o);\n            // Note that attr is an AA, so the comparison is nonsensical (bug 10381)\n            return\n                ((name != tag.name) ? ( name < tag.name ? -1 : 1 ) :\n                ((attr != tag.attr) ? ( cast(void *) attr < cast(void*) tag.attr ? -1 : 1 ) :\n                ((type != tag.type) ? ( type < tag.type ? -1 : 1 ) :\n            0 )));\n        }\n\n        /**\n         * Returns the hash of a Tag\n         *\n         * You should rarely need to call this function. It exists so that Tags\n         * can be used as associative array keys.\n         */\n        override size_t toHash()\n        {\n            return typeid(name).getHash(&name);\n        }\n\n        /**\n         * Returns the string representation of a Tag\n         *\n         * Example:\n         * --------------\n         * auto tag = new Tag(\"book\",TagType.START);\n         * writefln(tag.toString()); // writes \"<book>\"\n         * --------------\n         */\n        override string toString() @safe\n        {\n            if (isEmpty) return toEmptyString();\n            return (isEnd) ? toEndString() : toStartString();\n        }\n\n        private\n        {\n            string toNonEndString() @safe\n            {\n                import std.format : format;\n\n                string s = \"<\" ~ name;\n                foreach (key,val;attr)\n                    s ~= format(\" %s=\\\"%s\\\"\",key,encode(val));\n                return s;\n            }\n\n            string toStartString() @safe { return toNonEndString() ~ \">\"; }\n\n            string toEndString() @safe { return \"</\" ~ name ~ \">\"; }\n\n            string toEmptyString() @safe { return toNonEndString() ~ \" />\"; }\n        }\n\n        /**\n         * Returns true if the Tag is a start tag\n         *\n         * Example:\n         * --------------\n         * if (tag.isStart) { }\n         * --------------\n         */\n        @property bool isStart() @safe @nogc pure nothrow { return type == TagType.START; }\n\n        /**\n         * Returns true if the Tag is an end tag\n         *\n         * Example:\n         * --------------\n         * if (tag.isEnd) { }\n         * --------------\n         */\n        @property bool isEnd() @safe @nogc pure nothrow { return type == TagType.END;   }\n\n        /**\n         * Returns true if the Tag is an empty tag\n         *\n         * Example:\n         * --------------\n         * if (tag.isEmpty) { }\n         * --------------\n         */\n        @property bool isEmpty() @safe @nogc pure nothrow { return type == TagType.EMPTY; }\n    }\n}\n\n/**\n * Class representing a comment\n */\nclass Comment : Item\n{\n    private string content;\n\n    /**\n     * Construct a comment\n     *\n     * Params:\n     *      content = the body of the comment\n     *\n     * Throws: CommentException if the comment body is illegal (contains \"--\"\n     * or exactly equals \"-\")\n     *\n     * Example:\n     * --------------\n     * auto item = new Comment(\"This is a comment\");\n     *    // constructs <!--This is a comment-->\n     * --------------\n     */\n    this(string content) @safe pure\n    {\n        import std.string : indexOf;\n\n        if (content == \"-\" || content.indexOf(\"--\") != -1)\n            throw new CommentException(content);\n        this.content = content;\n    }\n\n    /**\n     * Compares two comments for equality\n     *\n     * Example:\n     * --------------\n     * Comment item1,item2;\n     * if (item1 == item2) { }\n     * --------------\n     */\n    override bool opEquals(scope const Object o) const\n    {\n        const item = toType!(const Item)(o);\n        const t = cast(const Comment) item;\n        return t !is null && content == t.content;\n    }\n\n    /**\n     * Compares two comments\n     *\n     * You should rarely need to call this function. It exists so that Comments\n     * can be used as associative array keys.\n     *\n     * Example:\n     * --------------\n     * Comment item1,item2;\n     * if (item1 < item2) { }\n     * --------------\n     */\n    override int opCmp(scope const Object o) scope const\n    {\n        const item = toType!(const Item)(o);\n        const t = cast(const Comment) item;\n        return t !is null && (content != t.content\n            ? (content < t.content ? -1 : 1 ) : 0 );\n    }\n\n    /**\n     * Returns the hash of a Comment\n     *\n     * You should rarely need to call this function. It exists so that Comments\n     * can be used as associative array keys.\n     */\n    override size_t toHash() scope const nothrow { return hash(content); }\n\n    /**\n     * Returns a string representation of this comment\n     */\n    override string toString() scope const @safe pure nothrow { return \"<!--\" ~ content ~ \"-->\"; }\n\n    override @property @safe @nogc pure nothrow scope bool isEmptyXML() const { return false; } /// Returns false always\n}\n\n@safe unittest // issue 16241\n{\n    import std.exception : assertThrown;\n    auto c = new Comment(\"==\");\n    assert(c.content == \"==\");\n    assertThrown!CommentException(new Comment(\"--\"));\n}\n\n/**\n * Class representing a Character Data section\n */\nclass CData : Item\n{\n    private string content;\n\n    /**\n     * Construct a character data section\n     *\n     * Params:\n     *      content = the body of the character data segment\n     *\n     * Throws: CDataException if the segment body is illegal (contains \"]]>\")\n     *\n     * Example:\n     * --------------\n     * auto item = new CData(\"<b>hello</b>\");\n     *    // constructs <![CDATA[<b>hello</b>]]>\n     * --------------\n     */\n    this(string content) @safe pure\n    {\n        import std.string : indexOf;\n        if (content.indexOf(\"]]>\") != -1) throw new CDataException(content);\n        this.content = content;\n    }\n\n    /**\n     * Compares two CDatas for equality\n     *\n     * Example:\n     * --------------\n     * CData item1,item2;\n     * if (item1 == item2) { }\n     * --------------\n     */\n    override bool opEquals(scope const Object o) const\n    {\n        const item = toType!(const Item)(o);\n        const t = cast(const CData) item;\n        return t !is null && content == t.content;\n    }\n\n    /**\n     * Compares two CDatas\n     *\n     * You should rarely need to call this function. It exists so that CDatas\n     * can be used as associative array keys.\n     *\n     * Example:\n     * --------------\n     * CData item1,item2;\n     * if (item1 < item2) { }\n     * --------------\n     */\n    override int opCmp(scope const Object o) scope const\n    {\n        const item = toType!(const Item)(o);\n        const t = cast(const CData) item;\n        return t !is null && (content != t.content\n            ? (content < t.content ? -1 : 1 ) : 0 );\n    }\n\n    /**\n     * Returns the hash of a CData\n     *\n     * You should rarely need to call this function. It exists so that CDatas\n     * can be used as associative array keys.\n     */\n    override size_t toHash() scope const nothrow { return hash(content); }\n\n    /**\n     * Returns a string representation of this CData section\n     */\n    override string toString() scope const @safe pure nothrow { return cdata ~ content ~ \"]]>\"; }\n\n    override @property @safe @nogc pure nothrow scope bool isEmptyXML() const { return false; } /// Returns false always\n}\n\n/**\n * Class representing a text (aka Parsed Character Data) section\n */\nclass Text : Item\n{\n    private string content;\n\n    /**\n     * Construct a text (aka PCData) section\n     *\n     * Params:\n     *      content = the text. This function encodes the text before\n     *      insertion, so it is safe to insert any text\n     *\n     * Example:\n     * --------------\n     * auto Text = new CData(\"a < b\");\n     *    // constructs a &lt; b\n     * --------------\n     */\n    this(string content) @safe pure\n    {\n        this.content = encode(content);\n    }\n\n    /**\n     * Compares two text sections for equality\n     *\n     * Example:\n     * --------------\n     * Text item1,item2;\n     * if (item1 == item2) { }\n     * --------------\n     */\n    override bool opEquals(scope const Object o) const\n    {\n        const item = toType!(const Item)(o);\n        const t = cast(const Text) item;\n        return t !is null && content == t.content;\n    }\n\n    /**\n     * Compares two text sections\n     *\n     * You should rarely need to call this function. It exists so that Texts\n     * can be used as associative array keys.\n     *\n     * Example:\n     * --------------\n     * Text item1,item2;\n     * if (item1 < item2) { }\n     * --------------\n     */\n    override int opCmp(scope const Object o) scope const\n    {\n        const item = toType!(const Item)(o);\n        const t = cast(const Text) item;\n        return t !is null\n            && (content != t.content ? (content < t.content ? -1 : 1 ) : 0 );\n    }\n\n    /**\n     * Returns the hash of a text section\n     *\n     * You should rarely need to call this function. It exists so that Texts\n     * can be used as associative array keys.\n     */\n    override size_t toHash() scope const nothrow { return hash(content); }\n\n    /**\n     * Returns a string representation of this Text section\n     */\n    override string toString() scope const @safe @nogc pure nothrow { return content; }\n\n    /**\n     * Returns true if the content is the empty string\n     */\n    override @property @safe @nogc pure nothrow scope bool isEmptyXML() const { return content.length == 0; }\n}\n\n/**\n * Class representing an XML Instruction section\n */\nclass XMLInstruction : Item\n{\n    private string content;\n\n    /**\n     * Construct an XML Instruction section\n     *\n     * Params:\n     *      content = the body of the instruction segment\n     *\n     * Throws: XIException if the segment body is illegal (contains \">\")\n     *\n     * Example:\n     * --------------\n     * auto item = new XMLInstruction(\"ATTLIST\");\n     *    // constructs <!ATTLIST>\n     * --------------\n     */\n    this(string content) @safe pure\n    {\n        import std.string : indexOf;\n        if (content.indexOf(\">\") != -1) throw new XIException(content);\n        this.content = content;\n    }\n\n    /**\n     * Compares two XML instructions for equality\n     *\n     * Example:\n     * --------------\n     * XMLInstruction item1,item2;\n     * if (item1 == item2) { }\n     * --------------\n     */\n    override bool opEquals(scope const Object o) const\n    {\n        const item = toType!(const Item)(o);\n        const t = cast(const XMLInstruction) item;\n        return t !is null && content == t.content;\n    }\n\n    /**\n     * Compares two XML instructions\n     *\n     * You should rarely need to call this function. It exists so that\n     * XmlInstructions can be used as associative array keys.\n     *\n     * Example:\n     * --------------\n     * XMLInstruction item1,item2;\n     * if (item1 < item2) { }\n     * --------------\n     */\n    override int opCmp(scope const Object o) scope const\n    {\n        const item = toType!(const Item)(o);\n        const t = cast(const XMLInstruction) item;\n        return t !is null\n            && (content != t.content ? (content < t.content ? -1 : 1 ) : 0 );\n    }\n\n    /**\n     * Returns the hash of an XMLInstruction\n     *\n     * You should rarely need to call this function. It exists so that\n     * XmlInstructions can be used as associative array keys.\n     */\n    override size_t toHash() scope const nothrow { return hash(content); }\n\n    /**\n     * Returns a string representation of this XmlInstruction\n     */\n    override string toString() scope const @safe pure nothrow { return \"<!\" ~ content ~ \">\"; }\n\n    override @property @safe @nogc pure nothrow scope bool isEmptyXML() const { return false; } /// Returns false always\n}\n\n/**\n * Class representing a Processing Instruction section\n */\nclass ProcessingInstruction : Item\n{\n    private string content;\n\n    /**\n     * Construct a Processing Instruction section\n     *\n     * Params:\n     *      content = the body of the instruction segment\n     *\n     * Throws: PIException if the segment body is illegal (contains \"?>\")\n     *\n     * Example:\n     * --------------\n     * auto item = new ProcessingInstruction(\"php\");\n     *    // constructs <?php?>\n     * --------------\n     */\n    this(string content) @safe pure\n    {\n        import std.string : indexOf;\n        if (content.indexOf(\"?>\") != -1) throw new PIException(content);\n        this.content = content;\n    }\n\n    /**\n     * Compares two processing instructions for equality\n     *\n     * Example:\n     * --------------\n     * ProcessingInstruction item1,item2;\n     * if (item1 == item2) { }\n     * --------------\n     */\n    override bool opEquals(scope const Object o) const\n    {\n        const item = toType!(const Item)(o);\n        const t = cast(const ProcessingInstruction) item;\n        return t !is null && content == t.content;\n    }\n\n    /**\n     * Compares two processing instructions\n     *\n     * You should rarely need to call this function. It exists so that\n     * ProcessingInstructions can be used as associative array keys.\n     *\n     * Example:\n     * --------------\n     * ProcessingInstruction item1,item2;\n     * if (item1 < item2) { }\n     * --------------\n     */\n    override int opCmp(scope const Object o) scope const\n    {\n        const item = toType!(const Item)(o);\n        const t = cast(const ProcessingInstruction) item;\n        return t !is null\n            && (content != t.content ? (content < t.content ? -1 : 1 ) : 0 );\n    }\n\n    /**\n     * Returns the hash of a ProcessingInstruction\n     *\n     * You should rarely need to call this function. It exists so that\n     * ProcessingInstructions can be used as associative array keys.\n     */\n    override size_t toHash() scope const nothrow { return hash(content); }\n\n    /**\n     * Returns a string representation of this ProcessingInstruction\n     */\n    override string toString() scope const @safe pure nothrow { return \"<?\" ~ content ~ \"?>\"; }\n\n    override @property @safe @nogc pure nothrow bool isEmptyXML() scope const { return false; } /// Returns false always\n}\n\n/**\n * Abstract base class for XML items\n */\nabstract class Item\n{\n    /// Compares with another Item of same type for equality\n    abstract override bool opEquals(scope const Object o) @safe const;\n\n    /// Compares with another Item of same type\n    abstract override int opCmp(scope const Object o) @safe const;\n\n    /// Returns the hash of this item\n    abstract override size_t toHash() @safe scope const;\n\n    /// Returns a string representation of this item\n    abstract override string toString() @safe scope const;\n\n    /**\n     * Returns an indented string representation of this item\n     *\n     * Params:\n     *      indent = number of spaces by which to indent child elements\n     */\n    string[] pretty(uint indent) @safe scope const\n    {\n        import std.string : strip;\n        string s = strip(toString());\n        return s.length == 0 ? [] : [ s ];\n    }\n\n    /// Returns true if the item represents empty XML text\n    abstract @property @safe @nogc pure nothrow bool isEmptyXML() scope const;\n}\n\n/**\n * Class for parsing an XML Document.\n *\n * This is a subclass of ElementParser. Most of the useful functions are\n * documented there.\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Bugs:\n *      Currently only supports UTF documents.\n *\n *      If there is an encoding attribute in the prolog, it is ignored.\n *\n */\nclass DocumentParser : ElementParser\n{\n    string xmlText;\n\n    /**\n     * Constructs a DocumentParser.\n     *\n     * The input to this function MUST be valid XML.\n     * This is enforced by the function's in contract.\n     *\n     * Params:\n     *      xmlText_ = the entire XML document as text\n     *\n     */\n    this(string xmlText_)\n    in\n    {\n        assert(xmlText_.length != 0);\n        try\n        {\n            // Confirm that the input is valid XML\n            check(xmlText_);\n        }\n        catch (CheckException e)\n        {\n            // And if it's not, tell the user why not\n            assert(false, \"\\n\" ~ e.toString());\n        }\n    }\n    do\n    {\n        xmlText = xmlText_;\n        s = &xmlText;\n        super();    // Initialize everything\n        parse();    // Parse through the root tag (but not beyond)\n    }\n}\n\n@system unittest\n{\n    auto doc = new Document(\"<root><child><grandchild/></child></root>\");\n    assert(doc.elements.length == 1);\n    assert(doc.elements[0].tag.name == \"child\");\n    assert(doc.items == doc.elements);\n}\n\n/**\n * Class for parsing an XML element.\n *\n * Standards: $(LINK2 http://www.w3.org/TR/1998/REC-xml-19980210, XML 1.0)\n *\n * Note that you cannot construct instances of this class directly. You can\n * construct a DocumentParser (which is a subclass of ElementParser), but\n * otherwise, Instances of ElementParser will be created for you by the\n * library, and passed your way via onStartTag handlers.\n *\n */\nclass ElementParser\n{\n    alias Handler = void delegate(string);\n    alias ElementHandler = void delegate(in Element element);\n    alias ParserHandler = void delegate(ElementParser parser);\n\n    private\n    {\n        Tag tag_;\n        string elementStart;\n        string* s;\n\n        Handler commentHandler = null;\n        Handler cdataHandler = null;\n        Handler xiHandler = null;\n        Handler piHandler = null;\n        Handler rawTextHandler = null;\n        Handler textHandler = null;\n\n        // Private constructor for start tags\n        this(ElementParser parent) @safe @nogc pure nothrow\n        {\n            s = parent.s;\n            this();\n            tag_ = parent.tag_;\n        }\n\n        // Private constructor for empty tags\n        this(Tag tag, string* t) @safe @nogc pure nothrow\n        {\n            s = t;\n            this();\n            tag_ = tag;\n        }\n    }\n\n    /**\n     * The Tag at the start of the element being parsed. You can read this to\n     * determine the tag's name and attributes.\n     */\n    @property @safe @nogc pure nothrow const(Tag) tag() const { return tag_; }\n\n    /**\n     * Register a handler which will be called whenever a start tag is\n     * encountered which matches the specified name. You can also pass null as\n     * the name, in which case the handler will be called for any unmatched\n     * start tag.\n     *\n     * Example:\n     * --------------\n     * // Call this function whenever a <podcast> start tag is encountered\n     * onStartTag[\"podcast\"] = (ElementParser xml)\n     * {\n     *     // Your code here\n     *     //\n     *     // This is a a closure, so code here may reference\n     *     // variables which are outside of this scope\n     * };\n     *\n     * // call myEpisodeStartHandler (defined elsewhere) whenever an <episode>\n     * // start tag is encountered\n     * onStartTag[\"episode\"] = &myEpisodeStartHandler;\n     *\n     * // call delegate dg for all other start tags\n     * onStartTag[null] = dg;\n     * --------------\n     *\n     * This library will supply your function with a new instance of\n     * ElementHandler, which may be used to parse inside the element whose\n     * start tag was just found, or to identify the tag attributes of the\n     * element, etc.\n     *\n     * Note that your function will be called for both start tags and empty\n     * tags. That is, we make no distinction between &lt;br&gt;&lt;/br&gt;\n     * and &lt;br/&gt;.\n     */\n    ParserHandler[string] onStartTag;\n\n    /**\n     * Register a handler which will be called whenever an end tag is\n     * encountered which matches the specified name. You can also pass null as\n     * the name, in which case the handler will be called for any unmatched\n     * end tag.\n     *\n     * Example:\n     * --------------\n     * // Call this function whenever a </podcast> end tag is encountered\n     * onEndTag[\"podcast\"] = (in Element e)\n     * {\n     *     // Your code here\n     *     //\n     *     // This is a a closure, so code here may reference\n     *     // variables which are outside of this scope\n     * };\n     *\n     * // call myEpisodeEndHandler (defined elsewhere) whenever an </episode>\n     * // end tag is encountered\n     * onEndTag[\"episode\"] = &myEpisodeEndHandler;\n     *\n     * // call delegate dg for all other end tags\n     * onEndTag[null] = dg;\n     * --------------\n     *\n     * Note that your function will be called for both start tags and empty\n     * tags. That is, we make no distinction between &lt;br&gt;&lt;/br&gt;\n     * and &lt;br/&gt;.\n     */\n    ElementHandler[string] onEndTag;\n\n    protected this() @safe @nogc pure nothrow\n    {\n        elementStart = *s;\n    }\n\n    /**\n     * Register a handler which will be called whenever text is encountered.\n     *\n     * Example:\n     * --------------\n     * // Call this function whenever text is encountered\n     * onText = (string s)\n     * {\n     *     // Your code here\n     *\n     *     // The passed parameter s will have been decoded by the time you see\n     *     // it, and so may contain any character.\n     *     //\n     *     // This is a a closure, so code here may reference\n     *     // variables which are outside of this scope\n     * };\n     * --------------\n     */\n    @property @safe @nogc pure nothrow void onText(Handler handler) { textHandler = handler; }\n\n    /**\n     * Register an alternative handler which will be called whenever text\n     * is encountered. This differs from onText in that onText will decode\n     * the text, whereas onTextRaw will not. This allows you to make design\n     * choices, since onText will be more accurate, but slower, while\n     * onTextRaw will be faster, but less accurate. Of course, you can\n     * still call decode() within your handler, if you want, but you'd\n     * probably want to use onTextRaw only in circumstances where you\n     * know that decoding is unnecessary.\n     *\n     * Example:\n     * --------------\n     * // Call this function whenever text is encountered\n     * onText = (string s)\n     * {\n     *     // Your code here\n     *\n     *     // The passed parameter s will NOT have been decoded.\n     *     //\n     *     // This is a a closure, so code here may reference\n     *     // variables which are outside of this scope\n     * };\n     * --------------\n     */\n    @safe @nogc pure nothrow void onTextRaw(Handler handler) { rawTextHandler = handler; }\n\n    /**\n     * Register a handler which will be called whenever a character data\n     * segment is encountered.\n     *\n     * Example:\n     * --------------\n     * // Call this function whenever a CData section is encountered\n     * onCData = (string s)\n     * {\n     *     // Your code here\n     *\n     *     // The passed parameter s does not include the opening <![CDATA[\n     *     // nor closing ]]>\n     *     //\n     *     // This is a a closure, so code here may reference\n     *     // variables which are outside of this scope\n     * };\n     * --------------\n     */\n    @property @safe @nogc pure nothrow void onCData(Handler handler) { cdataHandler = handler; }\n\n    /**\n     * Register a handler which will be called whenever a comment is\n     * encountered.\n     *\n     * Example:\n     * --------------\n     * // Call this function whenever a comment is encountered\n     * onComment = (string s)\n     * {\n     *     // Your code here\n     *\n     *     // The passed parameter s does not include the opening <!-- nor\n     *     // closing -->\n     *     //\n     *     // This is a a closure, so code here may reference\n     *     // variables which are outside of this scope\n     * };\n     * --------------\n     */\n    @property @safe @nogc pure nothrow void onComment(Handler handler) { commentHandler = handler; }\n\n    /**\n     * Register a handler which will be called whenever a processing\n     * instruction is encountered.\n     *\n     * Example:\n     * --------------\n     * // Call this function whenever a processing instruction is encountered\n     * onPI = (string s)\n     * {\n     *     // Your code here\n     *\n     *     // The passed parameter s does not include the opening <? nor\n     *     // closing ?>\n     *     //\n     *     // This is a a closure, so code here may reference\n     *     // variables which are outside of this scope\n     * };\n     * --------------\n     */\n    @property @safe @nogc pure nothrow void onPI(Handler handler) { piHandler = handler; }\n\n    /**\n     * Register a handler which will be called whenever an XML instruction is\n     * encountered.\n     *\n     * Example:\n     * --------------\n     * // Call this function whenever an XML instruction is encountered\n     * // (Note: XML instructions may only occur preceding the root tag of a\n     * // document).\n     * onPI = (string s)\n     * {\n     *     // Your code here\n     *\n     *     // The passed parameter s does not include the opening <! nor\n     *     // closing >\n     *     //\n     *     // This is a a closure, so code here may reference\n     *     // variables which are outside of this scope\n     * };\n     * --------------\n     */\n    @property @safe @nogc pure nothrow void onXI(Handler handler) { xiHandler = handler; }\n\n    /**\n     * Parse an XML element.\n     *\n     * Parsing will continue until the end of the current element. Any items\n     * encountered for which a handler has been registered will invoke that\n     * handler.\n     *\n     * Throws: various kinds of XMLException\n     */\n    void parse()\n    {\n        import std.algorithm.searching : startsWith;\n        import std.string : indexOf;\n\n        string t;\n        const Tag root = tag_;\n        Tag[string] startTags;\n        if (tag_ !is null) startTags[tag_.name] = tag_;\n\n        while (s.length != 0)\n        {\n            if (startsWith(*s,\"<!--\"))\n            {\n                chop(*s,4);\n                t = chop(*s,indexOf(*s,\"-->\"));\n                if (commentHandler.funcptr !is null) commentHandler(t);\n                chop(*s,3);\n            }\n            else if (startsWith(*s,\"<![CDATA[\"))\n            {\n                chop(*s,9);\n                t = chop(*s,indexOf(*s,\"]]>\"));\n                if (cdataHandler.funcptr !is null) cdataHandler(t);\n                chop(*s,3);\n            }\n            else if (startsWith(*s,\"<!\"))\n            {\n                chop(*s,2);\n                t = chop(*s,indexOf(*s,\">\"));\n                if (xiHandler.funcptr !is null) xiHandler(t);\n                chop(*s,1);\n            }\n            else if (startsWith(*s,\"<?\"))\n            {\n                chop(*s,2);\n                t = chop(*s,indexOf(*s,\"?>\"));\n                if (piHandler.funcptr !is null) piHandler(t);\n                chop(*s,2);\n            }\n            else if (startsWith(*s,\"<\"))\n            {\n                tag_ = new Tag(*s,true);\n                if (root is null)\n                    return; // Return to constructor of derived class\n\n                if (tag_.isStart)\n                {\n                    startTags[tag_.name] = tag_;\n\n                    auto parser = new ElementParser(this);\n\n                    auto handler = tag_.name in onStartTag;\n                    if (handler !is null) (*handler)(parser);\n                    else\n                    {\n                        handler = null in onStartTag;\n                        if (handler !is null) (*handler)(parser);\n                    }\n                }\n                else if (tag_.isEnd)\n                {\n                    const startTag = startTags[tag_.name];\n                    string text;\n\n                    if (startTag.tagString.length == 0)\n                        assert(0);\n\n                    immutable(char)* p = startTag.tagString.ptr\n                        + startTag.tagString.length;\n                    immutable(char)* q = &tag_.tagString[0];\n                    text = decode(p[0..(q-p)], DecodeMode.LOOSE);\n\n                    auto element = new Element(startTag);\n                    if (text.length != 0) element ~= new Text(text);\n\n                    auto handler = tag_.name in onEndTag;\n                    if (handler !is null) (*handler)(element);\n                    else\n                    {\n                        handler = null in onEndTag;\n                        if (handler !is null) (*handler)(element);\n                    }\n\n                    if (tag_.name == root.name) return;\n                }\n                else if (tag_.isEmpty)\n                {\n                    Tag startTag = new Tag(tag_.name);\n\n                    // FIX by hed010gy, for bug 2979\n                    // http://d.puremagic.com/issues/show_bug.cgi?id=2979\n                    if (tag_.attr.length > 0)\n                          foreach (tn,tv; tag_.attr) startTag.attr[tn]=tv;\n                    // END FIX\n\n                    // Handle the pretend start tag\n                    string s2;\n                    auto parser = new ElementParser(startTag,&s2);\n                    auto handler1 = startTag.name in onStartTag;\n                    if (handler1 !is null) (*handler1)(parser);\n                    else\n                    {\n                        handler1 = null in onStartTag;\n                        if (handler1 !is null) (*handler1)(parser);\n                    }\n\n                    // Handle the pretend end tag\n                    auto element = new Element(startTag);\n                    auto handler2 = tag_.name in onEndTag;\n                    if (handler2 !is null) (*handler2)(element);\n                    else\n                    {\n                        handler2 = null in onEndTag;\n                        if (handler2 !is null) (*handler2)(element);\n                    }\n                }\n            }\n            else\n            {\n                t = chop(*s,indexOf(*s,\"<\"));\n                if (rawTextHandler.funcptr !is null)\n                    rawTextHandler(t);\n                else if (textHandler.funcptr !is null)\n                    textHandler(decode(t,DecodeMode.LOOSE));\n            }\n        }\n    }\n\n    /**\n     * Returns that part of the element which has already been parsed\n     */\n    override string toString() const @nogc @safe pure nothrow\n    {\n        assert(elementStart.length >= s.length);\n        return elementStart[0 .. elementStart.length - s.length];\n    }\n\n}\n\nprivate\n{\n    template Check(string msg)\n    {\n        string old = s;\n\n        void fail() @safe pure\n        {\n            s = old;\n            throw new Err(s,msg);\n        }\n\n        void fail(Err e) @safe pure\n        {\n            s = old;\n            throw new Err(s,msg,e);\n        }\n\n        void fail(string msg2) @safe pure\n        {\n            fail(new Err(s,msg2));\n        }\n    }\n\n    void checkMisc(ref string s) @safe pure // rule 27\n    {\n        import std.algorithm.searching : startsWith;\n\n        mixin Check!(\"Misc\");\n\n        try\n        {\n                 if (s.startsWith(\"<!--\")) { checkComment(s); }\n            else if (s.startsWith(\"<?\"))   { checkPI(s); }\n            else                           { checkSpace(s); }\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkDocument(ref string s) @safe pure // rule 1\n    {\n        mixin Check!(\"Document\");\n        try\n        {\n            checkProlog(s);\n            checkElement(s);\n            star!(checkMisc)(s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkChars(ref string s) @safe pure // rule 2\n    {\n        // TO DO - Fix std.utf stride and decode functions, then use those\n        // instead\n        import std.format : format;\n\n        mixin Check!(\"Chars\");\n\n        dchar c;\n        int n = -1;\n        foreach (int i,dchar d; s)\n        {\n            if (!isChar(d))\n            {\n                c = d;\n                n = i;\n                break;\n            }\n        }\n        if (n != -1)\n        {\n            s = s[n..$];\n            fail(format(\"invalid character: U+%04X\",c));\n        }\n    }\n\n    void checkSpace(ref string s) @safe pure // rule 3\n    {\n        import std.algorithm.searching : countUntil;\n        import std.ascii : isWhite;\n        import std.utf : byCodeUnit;\n\n        mixin Check!(\"Whitespace\");\n        ptrdiff_t i = s.byCodeUnit.countUntil!(a => !isWhite(a));\n        if (i == -1 && s.length > 0 && isWhite(s[0]))\n            s = s[$ .. $];\n        else if (i > -1)\n            s = s[i .. $];\n        if (s is old) fail();\n    }\n\n    void checkName(ref string s, out string name) @safe pure // rule 5\n    {\n        mixin Check!(\"Name\");\n\n        if (s.length == 0) fail();\n        int n;\n        foreach (int i,dchar c;s)\n        {\n            if (c == '_' || c == ':' || isLetter(c)) continue;\n            if (i == 0) fail();\n            if (c == '-' || c == '.' || isDigit(c)\n                || isCombiningChar(c) || isExtender(c)) continue;\n            n = i;\n            break;\n        }\n        name = s[0 .. n];\n        s = s[n..$];\n    }\n\n    void checkAttValue(ref string s) @safe pure // rule 10\n    {\n        import std.algorithm.searching : countUntil;\n        import std.utf : byCodeUnit;\n\n        mixin Check!(\"AttValue\");\n\n        if (s.length == 0) fail();\n        char c = s[0];\n        if (c != '\\u0022' && c != '\\u0027')\n            fail(\"attribute value requires quotes\");\n        s = s[1..$];\n        for (;;)\n        {\n            s = s[s.byCodeUnit.countUntil(c) .. $];\n            if (s.length == 0) fail(\"unterminated attribute value\");\n            if (s[0] == '<') fail(\"< found in attribute value\");\n            if (s[0] == c) break;\n            try { checkReference(s); } catch (Err e) { fail(e); }\n        }\n        s = s[1..$];\n    }\n\n    void checkCharData(ref string s) @safe pure // rule 14\n    {\n        import std.algorithm.searching : startsWith;\n\n        mixin Check!(\"CharData\");\n\n        while (s.length != 0)\n        {\n            if (s.startsWith(\"&\")) break;\n            if (s.startsWith(\"<\")) break;\n            if (s.startsWith(\"]]>\")) fail(\"]]> found within char data\");\n            s = s[1..$];\n        }\n    }\n\n    void checkComment(ref string s) @safe pure // rule 15\n    {\n        import std.string : indexOf;\n\n        mixin Check!(\"Comment\");\n\n        try { checkLiteral(\"<!--\",s); } catch (Err e) { fail(e); }\n        ptrdiff_t n = s.indexOf(\"--\");\n        if (n == -1) fail(\"unterminated comment\");\n        s = s[n..$];\n        try { checkLiteral(\"-->\",s); } catch (Err e) { fail(e); }\n    }\n\n    void checkPI(ref string s) @safe pure // rule 16\n    {\n        mixin Check!(\"PI\");\n\n        try\n        {\n            checkLiteral(\"<?\",s);\n            checkEnd(\"?>\",s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkCDSect(ref string s) @safe pure // rule 18\n    {\n        mixin Check!(\"CDSect\");\n\n        try\n        {\n            checkLiteral(cdata,s);\n            checkEnd(\"]]>\",s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkProlog(ref string s) @safe pure // rule 22\n    {\n        mixin Check!(\"Prolog\");\n\n        try\n        {\n            /* The XML declaration is optional\n             * http://www.w3.org/TR/2008/REC-xml-20081126/#NT-prolog\n             */\n            opt!(checkXMLDecl)(s);\n\n            star!(checkMisc)(s);\n            opt!(seq!(checkDocTypeDecl,star!(checkMisc)))(s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkXMLDecl(ref string s) @safe pure // rule 23\n    {\n        mixin Check!(\"XMLDecl\");\n\n        try\n        {\n            checkLiteral(\"<?xml\",s);\n            checkVersionInfo(s);\n            opt!(checkEncodingDecl)(s);\n            opt!(checkSDDecl)(s);\n            opt!(checkSpace)(s);\n            checkLiteral(\"?>\",s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkVersionInfo(ref string s) @safe pure // rule 24\n    {\n        mixin Check!(\"VersionInfo\");\n\n        try\n        {\n            checkSpace(s);\n            checkLiteral(\"version\",s);\n            checkEq(s);\n            quoted!(checkVersionNum)(s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkEq(ref string s) @safe pure // rule 25\n    {\n        mixin Check!(\"Eq\");\n\n        try\n        {\n            opt!(checkSpace)(s);\n            checkLiteral(\"=\",s);\n            opt!(checkSpace)(s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkVersionNum(ref string s) @safe pure // rule 26\n    {\n        import std.algorithm.searching : countUntil;\n        import std.utf : byCodeUnit;\n\n        mixin Check!(\"VersionNum\");\n\n        s = s[s.byCodeUnit.countUntil('\\\"') .. $];\n        if (s is old) fail();\n    }\n\n    void checkDocTypeDecl(ref string s) @safe pure // rule 28\n    {\n        mixin Check!(\"DocTypeDecl\");\n\n        try\n        {\n            checkLiteral(\"<!DOCTYPE\",s);\n            //\n            // TO DO -- ensure DOCTYPE is well formed\n            // (But not yet. That's one of our \"future directions\")\n            //\n            checkEnd(\">\",s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkSDDecl(ref string s) @safe pure // rule 32\n    {\n        import std.algorithm.searching : startsWith;\n\n        mixin Check!(\"SDDecl\");\n\n        try\n        {\n            checkSpace(s);\n            checkLiteral(\"standalone\",s);\n            checkEq(s);\n        }\n        catch (Err e) { fail(e); }\n\n        int n = 0;\n             if (s.startsWith(\"'yes'\") || s.startsWith(\"\\\"yes\\\"\")) n = 5;\n        else if (s.startsWith(\"'no'\" ) || s.startsWith(\"\\\"no\\\"\" )) n = 4;\n        else fail(\"standalone attribute value must be 'yes', \\\"yes\\\",\"~\n            \" 'no' or \\\"no\\\"\");\n        s = s[n..$];\n    }\n\n    void checkElement(ref string s) @safe pure // rule 39\n    {\n        mixin Check!(\"Element\");\n\n        string sname,ename,t;\n        try { checkTag(s,t,sname); } catch (Err e) { fail(e); }\n\n        if (t == \"STag\")\n        {\n            try\n            {\n                checkContent(s);\n                t = s;\n                checkETag(s,ename);\n            }\n            catch (Err e) { fail(e); }\n\n            if (sname != ename)\n            {\n                s = t;\n                fail(\"end tag name \\\"\" ~ ename\n                    ~ \"\\\" differs from start tag name \\\"\"~sname~\"\\\"\");\n            }\n        }\n    }\n\n    // rules 40 and 44\n    void checkTag(ref string s, out string type, out string name) @safe pure\n    {\n        mixin Check!(\"Tag\");\n\n        try\n        {\n            type = \"STag\";\n            checkLiteral(\"<\",s);\n            checkName(s,name);\n            star!(seq!(checkSpace,checkAttribute))(s);\n            opt!(checkSpace)(s);\n            if (s.length != 0 && s[0] == '/')\n            {\n                s = s[1..$];\n                type = \"ETag\";\n            }\n            checkLiteral(\">\",s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkAttribute(ref string s) @safe pure // rule 41\n    {\n        mixin Check!(\"Attribute\");\n\n        try\n        {\n            string name;\n            checkName(s,name);\n            checkEq(s);\n            checkAttValue(s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkETag(ref string s, out string name) @safe pure // rule 42\n    {\n        mixin Check!(\"ETag\");\n\n        try\n        {\n            checkLiteral(\"</\",s);\n            checkName(s,name);\n            opt!(checkSpace)(s);\n            checkLiteral(\">\",s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkContent(ref string s) @safe pure // rule 43\n    {\n        import std.algorithm.searching : startsWith;\n\n        mixin Check!(\"Content\");\n\n        try\n        {\n            while (s.length != 0)\n            {\n                old = s;\n                     if (s.startsWith(\"&\"))        { checkReference(s); }\n                else if (s.startsWith(\"<!--\"))     { checkComment(s); }\n                else if (s.startsWith(\"<?\"))       { checkPI(s); }\n                else if (s.startsWith(cdata)) { checkCDSect(s); }\n                else if (s.startsWith(\"</\"))       { break; }\n                else if (s.startsWith(\"<\"))        { checkElement(s); }\n                else                               { checkCharData(s); }\n            }\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkCharRef(ref string s, out dchar c) @safe pure // rule 66\n    {\n        import std.format : format;\n\n        mixin Check!(\"CharRef\");\n\n        c = 0;\n        try { checkLiteral(\"&#\",s); } catch (Err e) { fail(e); }\n        int radix = 10;\n        if (s.length != 0 && s[0] == 'x')\n        {\n            s = s[1..$];\n            radix = 16;\n        }\n        if (s.length == 0) fail(\"unterminated character reference\");\n        if (s[0] == ';')\n            fail(\"character reference must have at least one digit\");\n        while (s.length != 0)\n        {\n            immutable char d = s[0];\n            int n = 0;\n            switch (d)\n            {\n                case 'F','f': ++n;      goto case;\n                case 'E','e': ++n;      goto case;\n                case 'D','d': ++n;      goto case;\n                case 'C','c': ++n;      goto case;\n                case 'B','b': ++n;      goto case;\n                case 'A','a': ++n;      goto case;\n                case '9':     ++n;      goto case;\n                case '8':     ++n;      goto case;\n                case '7':     ++n;      goto case;\n                case '6':     ++n;      goto case;\n                case '5':     ++n;      goto case;\n                case '4':     ++n;      goto case;\n                case '3':     ++n;      goto case;\n                case '2':     ++n;      goto case;\n                case '1':     ++n;      goto case;\n                case '0':     break;\n                default: n = 100; break;\n            }\n            if (n >= radix) break;\n            c *= radix;\n            c += n;\n            s = s[1..$];\n        }\n        if (!isChar(c)) fail(format(\"U+%04X is not a legal character\",c));\n        if (s.length == 0 || s[0] != ';') fail(\"expected ;\");\n        else s = s[1..$];\n    }\n\n    void checkReference(ref string s) @safe pure // rule 67\n    {\n        import std.algorithm.searching : startsWith;\n\n        mixin Check!(\"Reference\");\n\n        try\n        {\n            dchar c;\n            if (s.startsWith(\"&#\")) checkCharRef(s,c);\n            else checkEntityRef(s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkEntityRef(ref string s) @safe pure // rule 68\n    {\n        mixin Check!(\"EntityRef\");\n\n        try\n        {\n            string name;\n            checkLiteral(\"&\",s);\n            checkName(s,name);\n            checkLiteral(\";\",s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    void checkEncName(ref string s) @safe pure // rule 81\n    {\n        import std.algorithm.searching : countUntil;\n        import std.ascii : isAlpha;\n        import std.utf : byCodeUnit;\n\n        mixin Check!(\"EncName\");\n\n        s = s[s.byCodeUnit.countUntil!(a => !isAlpha(a)) .. $];\n        if (s is old) fail();\n        s = s[s.byCodeUnit.countUntil('\\\"', '\\'') .. $];\n    }\n\n    void checkEncodingDecl(ref string s) @safe pure // rule 80\n    {\n        mixin Check!(\"EncodingDecl\");\n\n        try\n        {\n            checkSpace(s);\n            checkLiteral(\"encoding\",s);\n            checkEq(s);\n            quoted!(checkEncName)(s);\n        }\n        catch (Err e) { fail(e); }\n    }\n\n    // Helper functions\n\n    void checkLiteral(string literal,ref string s) @safe pure\n    {\n        import std.string : startsWith;\n\n        mixin Check!(\"Literal\");\n\n        if (!s.startsWith(literal)) fail(\"Expected literal \\\"\"~literal~\"\\\"\");\n        s = s[literal.length..$];\n    }\n\n    void checkEnd(string end,ref string s) @safe pure\n    {\n        import std.string : indexOf;\n        // Deliberately no mixin Check here.\n\n        auto n = s.indexOf(end);\n        if (n == -1) throw new Err(s,\"Unable to find terminating \\\"\"~end~\"\\\"\");\n        s = s[n..$];\n        checkLiteral(end,s);\n    }\n\n    // Metafunctions -- none of these use mixin Check\n\n    void opt(alias f)(ref string s)\n    {\n        try { f(s); } catch (Err e) {}\n    }\n\n    void plus(alias f)(ref string s)\n    {\n        f(s);\n        star!(f)(s);\n    }\n\n    void star(alias f)(ref string s)\n    {\n        while (s.length != 0)\n        {\n            try { f(s); }\n            catch (Err e) { return; }\n        }\n    }\n\n    void quoted(alias f)(ref string s)\n    {\n        import std.string : startsWith;\n\n        if (s.startsWith(\"'\"))\n        {\n            checkLiteral(\"'\",s);\n            f(s);\n            checkLiteral(\"'\",s);\n        }\n        else\n        {\n            checkLiteral(\"\\\"\",s);\n            f(s);\n            checkLiteral(\"\\\"\",s);\n        }\n    }\n\n    void seq(alias f,alias g)(ref string s)\n    {\n        f(s);\n        g(s);\n    }\n}\n\n/**\n * Check an entire XML document for well-formedness\n *\n * Params:\n *      s = the document to be checked, passed as a string\n *\n * Throws: CheckException if the document is not well formed\n *\n * CheckException's toString() method will yield the complete hierarchy of\n * parse failure (the XML equivalent of a stack trace), giving the line and\n * column number of every failure at every level.\n */\nvoid check(string s) @safe pure\n{\n    try\n    {\n        checkChars(s);\n        checkDocument(s);\n        if (s.length != 0) throw new Err(s,\"Junk found after document\");\n    }\n    catch (Err e)\n    {\n        e.complete(s);\n        throw e;\n    }\n}\n\n@system pure unittest\n{\n    import std.string : indexOf;\n\n    try\n    {\n        check(q\"[<?xml version=\"1.0\"?>\n        <catalog>\n           <book id=\"bk101\">\n              <author>Gambardella, Matthew</author>\n              <title>XML Developer's Guide</title>\n              <genre>Computer</genre>\n              <price>44.95</price>\n              <publish_date>2000-10-01</publish_date>\n              <description>An in-depth look at creating applications\n              with XML.</description>\n           </book>\n           <book id=\"bk102\">\n              <author>Ralls, Kim</author>\n              <title>Midnight Rain</title>\n              <genre>Fantasy</genres>\n              <price>5.95</price>\n              <publish_date>2000-12-16</publish_date>\n              <description>A former architect battles corporate zombies,\n              an evil sorceress, and her own childhood to become queen\n              of the world.</description>\n           </book>\n           <book id=\"bk103\">\n              <author>Corets, Eva</author>\n              <title>Maeve Ascendant</title>\n              <genre>Fantasy</genre>\n              <price>5.95</price>\n              <publish_date>2000-11-17</publish_date>\n              <description>After the collapse of a nanotechnology\n              society in England, the young survivors lay the\n              foundation for a new society.</description>\n           </book>\n        </catalog>\n        ]\");\n        assert(false);\n    }\n    catch (CheckException e)\n    {\n        auto n = e.toString().indexOf(\"end tag name \\\"genres\\\" differs\"~\n                                      \" from start tag name \\\"genre\\\"\");\n        assert(n != -1);\n    }\n}\n\n@system unittest\n{\n    string s = q\"EOS\n<?xml version=\"1.0\"?>\n<set>\n    <one>A</one>\n    <!-- comment -->\n    <two>B</two>\n</set>\nEOS\";\n    try\n    {\n        check(s);\n    }\n    catch (CheckException e)\n    {\n        assert(0, e.toString());\n    }\n}\n\n@system unittest\n{\n    string test_xml = `<?xml version=\"1.0\" encoding='UTF-8'?><r><stream:stream\n                        xmlns:stream=\"http://etherx.'jabber'.org/streams\"\n                        xmlns=\"jabber:'client'\" from='jid.pl' id=\"587a5767\"\n                        xml:lang=\"en\" version=\"1.0\" attr='a\"b\"c'>\n                        </stream:stream></r>`;\n\n    DocumentParser parser = new DocumentParser(test_xml);\n    bool tested = false;\n    parser.onStartTag[\"stream:stream\"] = (ElementParser p) {\n        assert(p.tag.attr[\"xmlns\"] == \"jabber:'client'\");\n        assert(p.tag.attr[\"from\"] == \"jid.pl\");\n        assert(p.tag.attr[\"attr\"] == \"a\\\"b\\\"c\");\n        tested = true;\n    };\n    parser.parse();\n    assert(tested);\n}\n\n@system unittest\n{\n    string s = q\"EOS\n<?xml version=\"1.0\" encoding=\"utf-8\"?> <Tests>\n    <Test thing=\"What &amp; Up\">What &amp; Up Second</Test>\n</Tests>\nEOS\";\n    auto xml = new DocumentParser(s);\n\n    xml.onStartTag[\"Test\"] = (ElementParser xml) {\n        assert(xml.tag.attr[\"thing\"] == \"What & Up\");\n    };\n\n    xml.onEndTag[\"Test\"] = (in Element e) {\n        assert(e.text() == \"What & Up Second\");\n    };\n    xml.parse();\n}\n\n@system unittest\n{\n    string s = `<tag attr=\"&quot;value&gt;\" />`;\n    auto doc = new Document(s);\n    assert(doc.toString() == s);\n}\n\n/** The base class for exceptions thrown by this module */\nclass XMLException : Exception { this(string msg) @safe pure { super(msg); } }\n\n// Other exceptions\n\n/// Thrown during Comment constructor\nclass CommentException : XMLException\n{ private this(string msg) @safe pure { super(msg); } }\n\n/// Thrown during CData constructor\nclass CDataException : XMLException\n{ private this(string msg) @safe pure { super(msg); } }\n\n/// Thrown during XMLInstruction constructor\nclass XIException : XMLException\n{ private this(string msg) @safe pure { super(msg); } }\n\n/// Thrown during ProcessingInstruction constructor\nclass PIException : XMLException\n{ private this(string msg) @safe pure { super(msg); } }\n\n/// Thrown during Text constructor\nclass TextException : XMLException\n{ private this(string msg) @safe pure { super(msg); } }\n\n/// Thrown during decode()\nclass DecodeException : XMLException\n{ private this(string msg) @safe pure { super(msg); } }\n\n/// Thrown if comparing with wrong type\nclass InvalidTypeException : XMLException\n{ private this(string msg) @safe pure { super(msg); } }\n\n/// Thrown when parsing for Tags\nclass TagException : XMLException\n{ private this(string msg) @safe pure { super(msg); } }\n\n/**\n * Thrown during check()\n */\nclass CheckException : XMLException\n{\n    CheckException err; /// Parent in hierarchy\n    private string tail;\n    /**\n     * Name of production rule which failed to parse,\n     * or specific error message\n     */\n    string msg;\n    size_t line = 0; /// Line number at which parse failure occurred\n    size_t column = 0; /// Column number at which parse failure occurred\n\n    private this(string tail,string msg,Err err=null) @safe pure\n    {\n        super(null);\n        this.tail = tail;\n        this.msg = msg;\n        this.err = err;\n    }\n\n    private void complete(string entire) @safe pure\n    {\n        import std.string : count, lastIndexOf;\n        import std.utf : toUTF32;\n\n        string head = entire[0..$-tail.length];\n        ptrdiff_t n = head.lastIndexOf('\\n') + 1;\n        line = head.count(\"\\n\") + 1;\n        dstring t = toUTF32(head[n..$]);\n        column = t.length + 1;\n        if (err !is null) err.complete(entire);\n    }\n\n    override string toString() const @safe pure\n    {\n        import std.format : format;\n\n        string s;\n        if (line != 0) s = format(\"Line %d, column %d: \",line,column);\n        s ~= msg;\n        s ~= '\\n';\n        if (err !is null) s = err.toString() ~ s;\n        return s;\n    }\n}\n\nprivate alias Err = CheckException;\n\n// Private helper functions\n\nprivate\n{\n    inout(T) toType(T)(inout Object o)\n    {\n        T t = cast(T)(o);\n        if (t is null)\n        {\n            throw new InvalidTypeException(\"Attempt to compare a \"\n                ~ T.stringof ~ \" with an instance of another type\");\n        }\n        return t;\n    }\n\n    string chop(ref string s, size_t n) @safe pure nothrow\n    {\n        if (n == -1) n = s.length;\n        string t = s[0 .. n];\n        s = s[n..$];\n        return t;\n    }\n\n    bool optc(ref string s, char c) @safe pure nothrow\n    {\n        immutable bool b = s.length != 0 && s[0] == c;\n        if (b) s = s[1..$];\n        return b;\n    }\n\n    void reqc(ref string s, char c) @safe pure\n    {\n        if (s.length == 0 || s[0] != c) throw new TagException(\"\");\n        s = s[1..$];\n    }\n\n    char requireOneOf(ref string s, string chars) @safe pure\n    {\n        import std.string : indexOf;\n\n        if (s.length == 0 || indexOf(chars,s[0]) == -1)\n            throw new TagException(\"\");\n        immutable char ch = s[0];\n        s = s[1..$];\n        return ch;\n    }\n\n    size_t hash(string s,size_t h=0) @trusted nothrow\n    {\n        return typeid(s).getHash(&s) + h;\n    }\n\n    // Definitions from the XML specification\n    immutable CharTable=[0x9,0x9,0xA,0xA,0xD,0xD,0x20,0xD7FF,0xE000,0xFFFD,\n        0x10000,0x10FFFF];\n    immutable BaseCharTable=[0x0041,0x005A,0x0061,0x007A,0x00C0,0x00D6,0x00D8,\n        0x00F6,0x00F8,0x00FF,0x0100,0x0131,0x0134,0x013E,0x0141,0x0148,0x014A,\n        0x017E,0x0180,0x01C3,0x01CD,0x01F0,0x01F4,0x01F5,0x01FA,0x0217,0x0250,\n        0x02A8,0x02BB,0x02C1,0x0386,0x0386,0x0388,0x038A,0x038C,0x038C,0x038E,\n        0x03A1,0x03A3,0x03CE,0x03D0,0x03D6,0x03DA,0x03DA,0x03DC,0x03DC,0x03DE,\n        0x03DE,0x03E0,0x03E0,0x03E2,0x03F3,0x0401,0x040C,0x040E,0x044F,0x0451,\n        0x045C,0x045E,0x0481,0x0490,0x04C4,0x04C7,0x04C8,0x04CB,0x04CC,0x04D0,\n        0x04EB,0x04EE,0x04F5,0x04F8,0x04F9,0x0531,0x0556,0x0559,0x0559,0x0561,\n        0x0586,0x05D0,0x05EA,0x05F0,0x05F2,0x0621,0x063A,0x0641,0x064A,0x0671,\n        0x06B7,0x06BA,0x06BE,0x06C0,0x06CE,0x06D0,0x06D3,0x06D5,0x06D5,0x06E5,\n        0x06E6,0x0905,0x0939,0x093D,0x093D,0x0958,0x0961,0x0985,0x098C,0x098F,\n        0x0990,0x0993,0x09A8,0x09AA,0x09B0,0x09B2,0x09B2,0x09B6,0x09B9,0x09DC,\n        0x09DD,0x09DF,0x09E1,0x09F0,0x09F1,0x0A05,0x0A0A,0x0A0F,0x0A10,0x0A13,\n        0x0A28,0x0A2A,0x0A30,0x0A32,0x0A33,0x0A35,0x0A36,0x0A38,0x0A39,0x0A59,\n        0x0A5C,0x0A5E,0x0A5E,0x0A72,0x0A74,0x0A85,0x0A8B,0x0A8D,0x0A8D,0x0A8F,\n        0x0A91,0x0A93,0x0AA8,0x0AAA,0x0AB0,0x0AB2,0x0AB3,0x0AB5,0x0AB9,0x0ABD,\n        0x0ABD,0x0AE0,0x0AE0,0x0B05,0x0B0C,0x0B0F,0x0B10,0x0B13,0x0B28,0x0B2A,\n        0x0B30,0x0B32,0x0B33,0x0B36,0x0B39,0x0B3D,0x0B3D,0x0B5C,0x0B5D,0x0B5F,\n        0x0B61,0x0B85,0x0B8A,0x0B8E,0x0B90,0x0B92,0x0B95,0x0B99,0x0B9A,0x0B9C,\n        0x0B9C,0x0B9E,0x0B9F,0x0BA3,0x0BA4,0x0BA8,0x0BAA,0x0BAE,0x0BB5,0x0BB7,\n        0x0BB9,0x0C05,0x0C0C,0x0C0E,0x0C10,0x0C12,0x0C28,0x0C2A,0x0C33,0x0C35,\n        0x0C39,0x0C60,0x0C61,0x0C85,0x0C8C,0x0C8E,0x0C90,0x0C92,0x0CA8,0x0CAA,\n        0x0CB3,0x0CB5,0x0CB9,0x0CDE,0x0CDE,0x0CE0,0x0CE1,0x0D05,0x0D0C,0x0D0E,\n        0x0D10,0x0D12,0x0D28,0x0D2A,0x0D39,0x0D60,0x0D61,0x0E01,0x0E2E,0x0E30,\n        0x0E30,0x0E32,0x0E33,0x0E40,0x0E45,0x0E81,0x0E82,0x0E84,0x0E84,0x0E87,\n        0x0E88,0x0E8A,0x0E8A,0x0E8D,0x0E8D,0x0E94,0x0E97,0x0E99,0x0E9F,0x0EA1,\n        0x0EA3,0x0EA5,0x0EA5,0x0EA7,0x0EA7,0x0EAA,0x0EAB,0x0EAD,0x0EAE,0x0EB0,\n        0x0EB0,0x0EB2,0x0EB3,0x0EBD,0x0EBD,0x0EC0,0x0EC4,0x0F40,0x0F47,0x0F49,\n        0x0F69,0x10A0,0x10C5,0x10D0,0x10F6,0x1100,0x1100,0x1102,0x1103,0x1105,\n        0x1107,0x1109,0x1109,0x110B,0x110C,0x110E,0x1112,0x113C,0x113C,0x113E,\n        0x113E,0x1140,0x1140,0x114C,0x114C,0x114E,0x114E,0x1150,0x1150,0x1154,\n        0x1155,0x1159,0x1159,0x115F,0x1161,0x1163,0x1163,0x1165,0x1165,0x1167,\n        0x1167,0x1169,0x1169,0x116D,0x116E,0x1172,0x1173,0x1175,0x1175,0x119E,\n        0x119E,0x11A8,0x11A8,0x11AB,0x11AB,0x11AE,0x11AF,0x11B7,0x11B8,0x11BA,\n        0x11BA,0x11BC,0x11C2,0x11EB,0x11EB,0x11F0,0x11F0,0x11F9,0x11F9,0x1E00,\n        0x1E9B,0x1EA0,0x1EF9,0x1F00,0x1F15,0x1F18,0x1F1D,0x1F20,0x1F45,0x1F48,\n        0x1F4D,0x1F50,0x1F57,0x1F59,0x1F59,0x1F5B,0x1F5B,0x1F5D,0x1F5D,0x1F5F,\n        0x1F7D,0x1F80,0x1FB4,0x1FB6,0x1FBC,0x1FBE,0x1FBE,0x1FC2,0x1FC4,0x1FC6,\n        0x1FCC,0x1FD0,0x1FD3,0x1FD6,0x1FDB,0x1FE0,0x1FEC,0x1FF2,0x1FF4,0x1FF6,\n        0x1FFC,0x2126,0x2126,0x212A,0x212B,0x212E,0x212E,0x2180,0x2182,0x3041,\n        0x3094,0x30A1,0x30FA,0x3105,0x312C,0xAC00,0xD7A3];\n    immutable IdeographicTable=[0x3007,0x3007,0x3021,0x3029,0x4E00,0x9FA5];\n    immutable CombiningCharTable=[0x0300,0x0345,0x0360,0x0361,0x0483,0x0486,\n        0x0591,0x05A1,0x05A3,0x05B9,0x05BB,0x05BD,0x05BF,0x05BF,0x05C1,0x05C2,\n        0x05C4,0x05C4,0x064B,0x0652,0x0670,0x0670,0x06D6,0x06DC,0x06DD,0x06DF,\n        0x06E0,0x06E4,0x06E7,0x06E8,0x06EA,0x06ED,0x0901,0x0903,0x093C,0x093C,\n        0x093E,0x094C,0x094D,0x094D,0x0951,0x0954,0x0962,0x0963,0x0981,0x0983,\n        0x09BC,0x09BC,0x09BE,0x09BE,0x09BF,0x09BF,0x09C0,0x09C4,0x09C7,0x09C8,\n        0x09CB,0x09CD,0x09D7,0x09D7,0x09E2,0x09E3,0x0A02,0x0A02,0x0A3C,0x0A3C,\n        0x0A3E,0x0A3E,0x0A3F,0x0A3F,0x0A40,0x0A42,0x0A47,0x0A48,0x0A4B,0x0A4D,\n        0x0A70,0x0A71,0x0A81,0x0A83,0x0ABC,0x0ABC,0x0ABE,0x0AC5,0x0AC7,0x0AC9,\n        0x0ACB,0x0ACD,0x0B01,0x0B03,0x0B3C,0x0B3C,0x0B3E,0x0B43,0x0B47,0x0B48,\n        0x0B4B,0x0B4D,0x0B56,0x0B57,0x0B82,0x0B83,0x0BBE,0x0BC2,0x0BC6,0x0BC8,\n        0x0BCA,0x0BCD,0x0BD7,0x0BD7,0x0C01,0x0C03,0x0C3E,0x0C44,0x0C46,0x0C48,\n        0x0C4A,0x0C4D,0x0C55,0x0C56,0x0C82,0x0C83,0x0CBE,0x0CC4,0x0CC6,0x0CC8,\n        0x0CCA,0x0CCD,0x0CD5,0x0CD6,0x0D02,0x0D03,0x0D3E,0x0D43,0x0D46,0x0D48,\n        0x0D4A,0x0D4D,0x0D57,0x0D57,0x0E31,0x0E31,0x0E34,0x0E3A,0x0E47,0x0E4E,\n        0x0EB1,0x0EB1,0x0EB4,0x0EB9,0x0EBB,0x0EBC,0x0EC8,0x0ECD,0x0F18,0x0F19,\n        0x0F35,0x0F35,0x0F37,0x0F37,0x0F39,0x0F39,0x0F3E,0x0F3E,0x0F3F,0x0F3F,\n        0x0F71,0x0F84,0x0F86,0x0F8B,0x0F90,0x0F95,0x0F97,0x0F97,0x0F99,0x0FAD,\n        0x0FB1,0x0FB7,0x0FB9,0x0FB9,0x20D0,0x20DC,0x20E1,0x20E1,0x302A,0x302F,\n        0x3099,0x3099,0x309A,0x309A];\n    immutable DigitTable=[0x0030,0x0039,0x0660,0x0669,0x06F0,0x06F9,0x0966,\n        0x096F,0x09E6,0x09EF,0x0A66,0x0A6F,0x0AE6,0x0AEF,0x0B66,0x0B6F,0x0BE7,\n        0x0BEF,0x0C66,0x0C6F,0x0CE6,0x0CEF,0x0D66,0x0D6F,0x0E50,0x0E59,0x0ED0,\n        0x0ED9,0x0F20,0x0F29];\n    immutable ExtenderTable=[0x00B7,0x00B7,0x02D0,0x02D0,0x02D1,0x02D1,0x0387,\n        0x0387,0x0640,0x0640,0x0E46,0x0E46,0x0EC6,0x0EC6,0x3005,0x3005,0x3031,\n        0x3035,0x309D,0x309E,0x30FC,0x30FE];\n\n    bool lookup(const(int)[] table, int c) @safe @nogc nothrow pure\n    {\n        while (table.length != 0)\n        {\n            auto m = (table.length >> 1) & ~1;\n            if (c < table[m])\n            {\n                table = table[0 .. m];\n            }\n            else if (c > table[m+1])\n            {\n                table = table[m+2..$];\n            }\n            else return true;\n        }\n        return false;\n    }\n\n    string startOf(string s) @safe nothrow pure\n    {\n        string r;\n        foreach (char c;s)\n        {\n            r ~= (c < 0x20 || c > 0x7F) ? '.' : c;\n            if (r.length >= 40) { r ~= \"___\"; break; }\n        }\n        return r;\n    }\n\n    void exit(string s=null)\n    {\n        throw new XMLException(s);\n    }\n}\n"
  },
  {
    "path": "libphobos/src/std/zip.d",
    "content": "// Written in the D programming language.\n\n/**\n * Read/write data in the $(LINK2 http://www.info-zip.org, zip archive) format.\n * Makes use of the etc.c.zlib compression library.\n *\n * Bugs:\n *      $(UL\n *      $(LI Multi-disk zips not supported.)\n *      $(LI Only Zip version 20 formats are supported.)\n *      $(LI Only supports compression modes 0 (no compression) and 8 (deflate).)\n *      $(LI Does not support encryption.)\n *      $(LI $(BUGZILLA 592))\n *      $(LI $(BUGZILLA 2137))\n *      )\n *\n * Example:\n * ---\n// Read existing zip file.\nimport std.digest.crc, std.file, std.stdio, std.zip;\n\nvoid main(string[] args)\n{\n    // read a zip file into memory\n    auto zip = new ZipArchive(read(args[1]));\n    writeln(\"Archive: \", args[1]);\n    writefln(\"%-10s  %-8s  Name\", \"Length\", \"CRC-32\");\n    // iterate over all zip members\n    foreach (name, am; zip.directory)\n    {\n        // print some data about each member\n        writefln(\"%10s  %08x  %s\", am.expandedSize, am.crc32, name);\n        assert(am.expandedData.length == 0);\n        // decompress the archive member\n        zip.expand(am);\n        assert(am.expandedData.length == am.expandedSize);\n    }\n}\n\n// Create and write new zip file.\nimport std.file : write;\nimport std.string : representation;\n\nvoid main()\n{\n    char[] data = \"Test data.\\n\".dup;\n    // Create an ArchiveMember for the test file.\n    ArchiveMember am = new ArchiveMember();\n    am.name = \"test.txt\";\n    am.expandedData(data.representation);\n    // Create an archive and add the member.\n    ZipArchive zip = new ZipArchive();\n    zip.addMember(am);\n    // Build the archive\n    void[] compressed_data = zip.build();\n    // Write to a file\n    write(\"test.zip\", compressed_data);\n}\n * ---\n *\n * Copyright: Copyright The D Language Foundation 2000 - 2009.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright)\n * Source:    $(PHOBOSSRC std/zip.d)\n */\n\n/*          Copyright The D Language Foundation 2000 - 2009.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.zip;\n\n//debug=print;\n\n/** Thrown on error.\n */\nclass ZipException : Exception\n{\n    import std.exception : basicExceptionCtors;\n    ///\n    mixin basicExceptionCtors;\n}\n\n/**\n * Compression method used by ArchiveMember\n */\nenum CompressionMethod : ushort\n{\n    none = 0,   /// No compression, just archiving\n    deflate = 8 /// Deflate algorithm. Use zlib library to compress\n}\n\n/**\n * A member of the ZipArchive.\n */\nfinal class ArchiveMember\n{\n    import std.conv : to, octal;\n    import std.datetime.systime : DosFileTime, SysTime, SysTimeToDosFileTime;\n\n    /**\n     * Read/Write: Usually the file name of the archive member; it is used to\n     * index the archive directory for the member. Each member must have a unique\n     * name[]. Do not change without removing member from the directory first.\n     */\n    string name;\n\n    ubyte[] extra;              /// Read/Write: extra data for this member.\n    string comment;             /// Read/Write: comment associated with this member.\n\n    private ubyte[] _compressedData;\n    private ubyte[] _expandedData;\n    private uint offset;\n    private uint _crc32;\n    private uint _compressedSize;\n    private uint _expandedSize;\n    private CompressionMethod _compressionMethod;\n    private ushort _madeVersion = 20;\n    private ushort _extractVersion = 20;\n    private ushort _diskNumber;\n    private uint _externalAttributes;\n    private DosFileTime _time;\n    // by default, no explicit order goes after explicit order\n    private uint _index = uint.max;\n\n    ushort flags;                  /// Read/Write: normally set to 0\n    ushort internalAttributes;     /// Read/Write\n\n    /// Read Only\n    @property @safe pure nothrow @nogc ushort extractVersion() const { return _extractVersion; }\n    /// Read Only: cyclic redundancy check (CRC) value\n    @property @safe pure nothrow @nogc uint crc32() const { return _crc32; }\n\n    /// Read Only: size of data of member in compressed form.\n    @property @safe pure nothrow @nogc uint compressedSize() const { return _compressedSize; }\n\n    /// Read Only: size of data of member in expanded form.\n    @property @safe pure nothrow @nogc uint expandedSize() const { return _expandedSize; }\n    /// Read Only: should be 0.\n    @property @safe pure nothrow @nogc ushort diskNumber() const { return _diskNumber; }\n\n    /// Read Only: data of member in compressed form.\n    @property @safe pure nothrow @nogc ubyte[] compressedData() { return _compressedData; }\n\n    /// Read data of member in uncompressed form.\n    @property @safe pure nothrow @nogc ubyte[] expandedData() { return _expandedData; }\n\n    /// Write data of member in uncompressed form.\n    @property @safe void expandedData(ubyte[] ed)\n    {\n        _expandedData = ed;\n        _expandedSize  = to!uint(_expandedData.length);\n\n        // Clean old compressed data, if any\n        _compressedData.length = 0;\n        _compressedSize = 0;\n    }\n\n    /**\n     * Set the OS specific file attributes, as obtained by\n     * $(REF getAttributes, std,file) or $(REF DirEntry.attributes, std,file), for this archive member.\n     */\n    @property @safe void fileAttributes(uint attr)\n    {\n        version (Posix)\n        {\n            _externalAttributes = (attr & 0xFFFF) << 16;\n            _madeVersion &= 0x00FF;\n            _madeVersion |= 0x0300; // attributes are in UNIX format\n        }\n        else version (Windows)\n        {\n            _externalAttributes = attr;\n            _madeVersion &= 0x00FF; // attributes are in MS-DOS and OS/2 format\n        }\n        else\n        {\n            static assert(0, \"Unimplemented platform\");\n        }\n    }\n\n    version (Posix) @safe unittest\n    {\n        auto am = new ArchiveMember();\n        am.fileAttributes = octal!100644;\n        assert(am._externalAttributes == octal!100644 << 16);\n        assert((am._madeVersion & 0xFF00) == 0x0300);\n    }\n\n    /**\n     * Get the OS specific file attributes for the archive member.\n     *\n     * Returns: The file attributes or 0 if the file attributes were\n     * encoded for an incompatible OS (Windows vs. Posix).\n     *\n     */\n    @property @nogc nothrow uint fileAttributes() const\n    {\n        version (Posix)\n        {\n            if ((_madeVersion & 0xFF00) == 0x0300)\n                return _externalAttributes >> 16;\n            return 0;\n        }\n        else version (Windows)\n        {\n            if ((_madeVersion & 0xFF00) == 0x0000)\n                return _externalAttributes;\n            return 0;\n        }\n        else\n        {\n            static assert(0, \"Unimplemented platform\");\n        }\n    }\n\n    /// Set the last modification time for this member.\n    @property void time(SysTime time)\n    {\n        _time = SysTimeToDosFileTime(time);\n    }\n\n    /// ditto\n    @property void time(DosFileTime time) @safe pure nothrow @nogc\n    {\n        _time = time;\n    }\n\n    /// Get the last modification time for this member.\n    @property DosFileTime time() const @safe pure nothrow @nogc\n    {\n        return _time;\n    }\n\n    /**\n     * Read compression method used for this member\n     * See_Also:\n     *     CompressionMethod\n     **/\n    @property @safe @nogc pure nothrow CompressionMethod compressionMethod() const { return _compressionMethod; }\n\n    /**\n     * Write compression method used for this member\n     * See_Also:\n     *     CompressionMethod\n     **/\n    @property @safe pure void compressionMethod(CompressionMethod cm)\n    {\n        if (cm == _compressionMethod) return;\n\n        if (_compressedSize > 0)\n            throw new ZipException(\"Can't change compression method for a compressed element\");\n\n        _compressionMethod = cm;\n    }\n\n    /**\n      * The index of this archive member within the archive.\n      */\n    @property uint index() const @safe pure nothrow @nogc { return _index; }\n    @property uint index(uint value) @safe pure nothrow @nogc { return _index = value; }\n\n    debug(print)\n    {\n    void print()\n    {\n        printf(\"name = '%.*s'\\n\", name.length, name.ptr);\n        printf(\"\\tcomment = '%.*s'\\n\", comment.length, comment.ptr);\n        printf(\"\\tmadeVersion = x%04x\\n\", _madeVersion);\n        printf(\"\\textractVersion = x%04x\\n\", extractVersion);\n        printf(\"\\tflags = x%04x\\n\", flags);\n        printf(\"\\tcompressionMethod = %d\\n\", compressionMethod);\n        printf(\"\\ttime = %d\\n\", time);\n        printf(\"\\tcrc32 = x%08x\\n\", crc32);\n        printf(\"\\texpandedSize = %d\\n\", expandedSize);\n        printf(\"\\tcompressedSize = %d\\n\", compressedSize);\n        printf(\"\\tinternalAttributes = x%04x\\n\", internalAttributes);\n        printf(\"\\texternalAttributes = x%08x\\n\", externalAttributes);\n        printf(\"\\tindex = x%08x\\n\", index);\n    }\n    }\n}\n\n/**\n * Object representing the entire archive.\n * ZipArchives are collections of ArchiveMembers.\n */\nfinal class ZipArchive\n{\n    import std.algorithm.comparison : max;\n    import std.bitmanip : littleEndianToNative, nativeToLittleEndian;\n    import std.conv : to;\n    import std.datetime.systime : DosFileTime;\n\n    string comment;     /// Read/Write: the archive comment. Must be less than 65536 bytes in length.\n\n    private ubyte[] _data;\n    private uint endrecOffset;\n\n    private uint _diskNumber;\n    private uint _diskStartDir;\n    private uint _numEntries;\n    private uint _totalEntries;\n    private bool _isZip64;\n    static const ushort zip64ExtractVersion = 45;\n    static const int digiSignLength = 6;\n    static const int eocd64LocLength = 20;\n    static const int eocd64Length = 56;\n\n    /// Read Only: array representing the entire contents of the archive.\n    @property @safe @nogc pure nothrow ubyte[] data() { return _data; }\n\n    /// Read Only: 0 since multi-disk zip archives are not supported.\n    @property @safe @nogc pure nothrow uint diskNumber() const { return _diskNumber; }\n\n    /// Read Only: 0 since multi-disk zip archives are not supported\n    @property @safe @nogc pure nothrow uint diskStartDir() const { return _diskStartDir; }\n\n    /// Read Only: number of ArchiveMembers in the directory.\n    @property @safe @nogc pure nothrow uint numEntries() const { return _numEntries; }\n    @property @safe @nogc pure nothrow uint totalEntries() const { return _totalEntries; }    /// ditto\n\n    /// True when the archive is in Zip64 format.\n    @property @safe @nogc pure nothrow bool isZip64() const { return _isZip64; }\n\n    /// Set this to true to force building a Zip64 archive.\n    @property @safe @nogc pure nothrow void isZip64(bool value) { _isZip64 = value; }\n    /**\n     * Read Only: array indexed by the name of each member of the archive.\n     *  All the members of the archive can be accessed with a foreach loop:\n     * Example:\n     * --------------------\n     * ZipArchive archive = new ZipArchive(data);\n     * foreach (ArchiveMember am; archive.directory)\n     * {\n     *     writefln(\"member name is '%s'\", am.name);\n     * }\n     * --------------------\n     */\n    @property @safe @nogc pure nothrow ArchiveMember[string] directory() { return _directory; }\n\n    private ArchiveMember[string] _directory;\n\n    debug (print)\n    {\n    @safe void print()\n    {\n        printf(\"\\tdiskNumber = %u\\n\", diskNumber);\n        printf(\"\\tdiskStartDir = %u\\n\", diskStartDir);\n        printf(\"\\tnumEntries = %u\\n\", numEntries);\n        printf(\"\\ttotalEntries = %u\\n\", totalEntries);\n        printf(\"\\tcomment = '%.*s'\\n\", comment.length, comment.ptr);\n    }\n    }\n\n    /* ============ Creating a new archive =================== */\n\n    /** Constructor to use when creating a new archive.\n     */\n    this() @safe @nogc pure nothrow\n    {\n    }\n\n    /** Add de to the archive. The file is compressed on the fly.\n     */\n    @safe void addMember(ArchiveMember de)\n    {\n        _directory[de.name] = de;\n        if (!de._compressedData.length)\n        {\n            switch (de.compressionMethod)\n            {\n                case CompressionMethod.none:\n                    de._compressedData = de._expandedData;\n                    break;\n\n                case CompressionMethod.deflate:\n                    import std.zlib : compress;\n                    () @trusted\n                    {\n                        de._compressedData = cast(ubyte[]) compress(cast(void[]) de._expandedData);\n                    }();\n                        de._compressedData = de._compressedData[2 .. de._compressedData.length - 4];\n                    break;\n\n                default:\n                    throw new ZipException(\"unsupported compression method\");\n            }\n\n            de._compressedSize = to!uint(de._compressedData.length);\n            import std.zlib : crc32;\n            () @trusted { de._crc32 = crc32(0, cast(void[]) de._expandedData); }();\n        }\n        assert(de._compressedData.length == de._compressedSize, \"Archive member compressed failed.\");\n    }\n\n    /** Delete de from the archive.\n     */\n    @safe void deleteMember(ArchiveMember de)\n    {\n        _directory.remove(de.name);\n    }\n\n    /**\n     * Construct an archive out of the current members of the archive.\n     *\n     * Fills in the properties data[], diskNumber, diskStartDir, numEntries,\n     * totalEntries, and directory[].\n     * For each ArchiveMember, fills in properties crc32, compressedSize,\n     * compressedData[].\n     *\n     * Returns: array representing the entire archive.\n     */\n    void[] build() @safe pure\n    {\n        import std.array : array, uninitializedArray;\n        import std.algorithm.sorting : sort;\n        import std.string : representation;\n\n        uint i;\n        uint directoryOffset;\n\n        if (comment.length > 0xFFFF)\n            throw new ZipException(\"archive comment longer than 65535\");\n\n        // Compress each member; compute size\n        uint archiveSize = 0;\n        uint directorySize = 0;\n        auto directory = _directory.byValue.array.sort!((x, y) => x.index < y.index).release;\n        foreach (ArchiveMember de; directory)\n        {\n            if (to!ulong(archiveSize) + 30 + de.name.length + de.extra.length + de.compressedSize\n                    + directorySize + 46 + de.name.length + de.extra.length + de.comment.length\n                    + 22 + comment.length + eocd64LocLength + eocd64Length > uint.max)\n                throw new ZipException(\"zip files bigger than 4 GB are unsupported\");\n\n            archiveSize += 30 + de.name.length +\n                                de.extra.length +\n                                de.compressedSize;\n            directorySize += 46 + de.name.length +\n                                de.extra.length +\n                                de.comment.length;\n        }\n\n        if (!isZip64 && _directory.length > ushort.max)\n            _isZip64 = true;\n        uint dataSize = archiveSize + directorySize + 22 + cast(uint) comment.length;\n        if (isZip64)\n            dataSize += eocd64LocLength + eocd64Length;\n\n        _data = uninitializedArray!(ubyte[])(dataSize);\n\n        // Populate the data[]\n\n        // Store each archive member\n        i = 0;\n        foreach (ArchiveMember de; directory)\n        {\n            de.offset = i;\n            _data[i .. i + 4] = \"PK\\x03\\x04\".representation;\n            putUshort(i + 4,  de.extractVersion);\n            putUshort(i + 6,  de.flags);\n            putUshort(i + 8,  de._compressionMethod);\n            putUint  (i + 10, cast(uint) de.time);\n            putUint  (i + 14, de.crc32);\n            putUint  (i + 18, de.compressedSize);\n            putUint  (i + 22, to!uint(de.expandedSize));\n            putUshort(i + 26, cast(ushort) de.name.length);\n            putUshort(i + 28, cast(ushort) de.extra.length);\n            i += 30;\n\n            _data[i .. i + de.name.length] = (de.name.representation)[];\n            i += de.name.length;\n            _data[i .. i + de.extra.length] = (cast(ubyte[]) de.extra)[];\n            i += de.extra.length;\n            _data[i .. i + de.compressedSize] = de.compressedData[];\n            i += de.compressedSize;\n        }\n\n        // Write directory\n        directoryOffset = i;\n        _numEntries = 0;\n        foreach (ArchiveMember de; directory)\n        {\n            _data[i .. i + 4] = \"PK\\x01\\x02\".representation;\n            putUshort(i + 4,  de._madeVersion);\n            putUshort(i + 6,  de.extractVersion);\n            putUshort(i + 8,  de.flags);\n            putUshort(i + 10, de._compressionMethod);\n            putUint  (i + 12, cast(uint) de.time);\n            putUint  (i + 16, de.crc32);\n            putUint  (i + 20, de.compressedSize);\n            putUint  (i + 24, de.expandedSize);\n            putUshort(i + 28, cast(ushort) de.name.length);\n            putUshort(i + 30, cast(ushort) de.extra.length);\n            putUshort(i + 32, cast(ushort) de.comment.length);\n            putUshort(i + 34, de.diskNumber);\n            putUshort(i + 36, de.internalAttributes);\n            putUint  (i + 38, de._externalAttributes);\n            putUint  (i + 42, de.offset);\n            i += 46;\n\n            _data[i .. i + de.name.length] = (de.name.representation)[];\n            i += de.name.length;\n            _data[i .. i + de.extra.length] = (cast(ubyte[]) de.extra)[];\n            i += de.extra.length;\n            _data[i .. i + de.comment.length] = (de.comment.representation)[];\n            i += de.comment.length;\n            _numEntries++;\n        }\n        _totalEntries = numEntries;\n\n        if (isZip64)\n        {\n            // Write zip64 end of central directory record\n            uint eocd64Offset = i;\n            _data[i .. i + 4] = \"PK\\x06\\x06\".representation;\n            putUlong (i + 4,  eocd64Length - 12);\n            putUshort(i + 12, zip64ExtractVersion);\n            putUshort(i + 14, zip64ExtractVersion);\n            putUint  (i + 16, diskNumber);\n            putUint  (i + 20, diskStartDir);\n            putUlong (i + 24, numEntries);\n            putUlong (i + 32, totalEntries);\n            putUlong (i + 40, directorySize);\n            putUlong (i + 48, directoryOffset);\n            i += eocd64Length;\n\n            // Write zip64 end of central directory record locator\n            _data[i .. i + 4] = \"PK\\x06\\x07\".representation;\n            putUint  (i + 4,  diskNumber);\n            putUlong (i + 8,  eocd64Offset);\n            putUint  (i + 16, 1);\n            i += eocd64LocLength;\n        }\n\n        // Write end record\n        endrecOffset = i;\n        _data[i .. i + 4] = \"PK\\x05\\x06\".representation;\n        putUshort(i + 4,  cast(ushort) diskNumber);\n        putUshort(i + 6,  cast(ushort) diskStartDir);\n        putUshort(i + 8,  (numEntries > ushort.max ? ushort.max : cast(ushort) numEntries));\n        putUshort(i + 10, (totalEntries > ushort.max ? ushort.max : cast(ushort) totalEntries));\n        putUint  (i + 12, directorySize);\n        putUint  (i + 16, directoryOffset);\n        putUshort(i + 20, cast(ushort) comment.length);\n        i += 22;\n\n        // Write archive comment\n        assert(i + comment.length == data.length, \"Writing the archive comment failed.\");\n        _data[i .. data.length] = (comment.representation)[];\n\n        return cast(void[]) data;\n    }\n\n    /* ============ Reading an existing archive =================== */\n\n    /**\n     * Constructor to use when reading an existing archive.\n     *\n     * Fills in the properties data[], diskNumber, diskStartDir, numEntries,\n     * totalEntries, comment[], and directory[].\n     * For each ArchiveMember, fills in\n     * properties madeVersion, extractVersion, flags, compressionMethod, time,\n     * crc32, compressedSize, expandedSize, compressedData[], diskNumber,\n     * internalAttributes, externalAttributes, name[], extra[], comment[].\n     * Use expand() to get the expanded data for each ArchiveMember.\n     *\n     * Params:\n     *  buffer = the entire contents of the archive.\n     */\n\n    this(void[] buffer)\n    {   uint iend;\n        uint i;\n        int endcommentlength;\n        uint directorySize;\n        uint directoryOffset;\n\n        this._data = cast(ubyte[]) buffer;\n\n        if (data.length > uint.max - 2)\n            throw new ZipException(\"zip files bigger than 4 GB are unsupported\");\n\n        // Find 'end record index' by searching backwards for signature\n        iend = (data.length > 66_000 ? to!uint(data.length - 66_000) : 0);\n        for (i = to!uint(data.length) - 22; 1; i--)\n        {\n            if (i < iend || i >= data.length)\n                throw new ZipException(\"no end record\");\n\n            if (_data[i .. i + 4] == cast(ubyte[])\"PK\\x05\\x06\")\n            {\n                endcommentlength = getUshort(i + 20);\n                if (i + 22 + endcommentlength > data.length\n                        || i + 22 + endcommentlength < i)\n                    continue;\n                comment = cast(string)(_data[i + 22 .. i + 22 + endcommentlength]);\n                endrecOffset = i;\n\n                uint k = i - eocd64LocLength;\n                if (k < i && _data[k .. k + 4] == cast(ubyte[])\"PK\\x06\\x07\")\n                {\n                    _isZip64 = true;\n                    i = k;\n                }\n\n                break;\n            }\n        }\n\n        if (isZip64)\n        {\n            // Read Zip64 record data\n            ulong eocdOffset = getUlong(i + 8);\n            if (eocdOffset + eocd64Length > _data.length)\n                throw new ZipException(\"corrupted directory\");\n\n            i = to!uint(eocdOffset);\n            if (_data[i .. i + 4] != cast(ubyte[])\"PK\\x06\\x06\")\n                throw new ZipException(\"invalid Zip EOCD64 signature\");\n\n            ulong eocd64Size = getUlong(i + 4);\n            if (eocd64Size + i - 12 > data.length)\n                throw new ZipException(\"invalid Zip EOCD64 size\");\n\n            _diskNumber = getUint(i + 16);\n            _diskStartDir = getUint(i + 20);\n\n            ulong numEntriesUlong = getUlong(i + 24);\n            ulong totalEntriesUlong = getUlong(i + 32);\n            ulong directorySizeUlong = getUlong(i + 40);\n            ulong directoryOffsetUlong = getUlong(i + 48);\n\n            if (numEntriesUlong > uint.max)\n                throw new ZipException(\"supposedly more than 4294967296 files in archive\");\n\n            if (numEntriesUlong != totalEntriesUlong)\n                throw new ZipException(\"multiple disk zips not supported\");\n\n            if (directorySizeUlong > i || directoryOffsetUlong > i\n                    || directorySizeUlong + directoryOffsetUlong > i)\n                throw new ZipException(\"corrupted directory\");\n\n            _numEntries = to!uint(numEntriesUlong);\n            _totalEntries = to!uint(totalEntriesUlong);\n            directorySize = to!uint(directorySizeUlong);\n            directoryOffset = to!uint(directoryOffsetUlong);\n        }\n        else\n        {\n        // Read end record data\n        _diskNumber = getUshort(i + 4);\n        _diskStartDir = getUshort(i + 6);\n\n        _numEntries = getUshort(i + 8);\n        _totalEntries = getUshort(i + 10);\n\n        if (numEntries != totalEntries)\n            throw new ZipException(\"multiple disk zips not supported\");\n\n        directorySize = getUint(i + 12);\n        directoryOffset = getUint(i + 16);\n\n        if (directoryOffset + directorySize > i)\n            throw new ZipException(\"corrupted directory\");\n        }\n\n        i = directoryOffset;\n        for (int n = 0; n < numEntries; n++)\n        {\n            /* The format of an entry is:\n             *  'PK' 1, 2\n             *  directory info\n             *  path\n             *  extra data\n             *  comment\n             */\n\n            uint namelen;\n            uint extralen;\n            uint commentlen;\n\n            if (_data[i .. i + 4] != cast(ubyte[])\"PK\\x01\\x02\")\n                throw new ZipException(\"invalid directory entry 1\");\n            ArchiveMember de = new ArchiveMember();\n            de._index = n;\n            de._madeVersion = getUshort(i + 4);\n            de._extractVersion = getUshort(i + 6);\n            de.flags = getUshort(i + 8);\n            de._compressionMethod = cast(CompressionMethod) getUshort(i + 10);\n            de.time = cast(DosFileTime) getUint(i + 12);\n            de._crc32 = getUint(i + 16);\n            de._compressedSize = getUint(i + 20);\n            de._expandedSize = getUint(i + 24);\n            namelen = getUshort(i + 28);\n            extralen = getUshort(i + 30);\n            commentlen = getUshort(i + 32);\n            de._diskNumber = getUshort(i + 34);\n            de.internalAttributes = getUshort(i + 36);\n            de._externalAttributes = getUint(i + 38);\n            de.offset = getUint(i + 42);\n            i += 46;\n\n            if (i + namelen + extralen + commentlen > directoryOffset + directorySize)\n                throw new ZipException(\"invalid directory entry 2\");\n\n            de.name = cast(string)(_data[i .. i + namelen]);\n            i += namelen;\n            de.extra = _data[i .. i + extralen];\n            i += extralen;\n            de.comment = cast(string)(_data[i .. i + commentlen]);\n            i += commentlen;\n\n            immutable uint dataOffset = de.offset + 30 + namelen + extralen;\n            if (dataOffset + de.compressedSize > endrecOffset)\n                throw new ZipException(\"Invalid directory entry offset or size.\");\n            de._compressedData = _data[dataOffset .. dataOffset + de.compressedSize];\n\n            _directory[de.name] = de;\n\n        }\n        if (i != directoryOffset + directorySize)\n            throw new ZipException(\"invalid directory entry 3\");\n    }\n\n    /*****\n     * Decompress the contents of archive member de and return the expanded\n     * data.\n     *\n     * Fills in properties extractVersion, flags, compressionMethod, time,\n     * crc32, compressedSize, expandedSize, expandedData[], name[], extra[].\n     */\n    ubyte[] expand(ArchiveMember de)\n    {\n        import std.string : representation;\n\n        uint namelen;\n        uint extralen;\n\n        if (_data[de.offset .. de.offset + 4] != \"PK\\x03\\x04\".representation)\n            throw new ZipException(\"invalid directory entry 4\");\n\n        // These values should match what is in the main zip archive directory\n        de._extractVersion = getUshort(de.offset + 4);\n        de.flags = getUshort(de.offset + 6);\n        de._compressionMethod = cast(CompressionMethod) getUshort(de.offset + 8);\n        de.time = cast(DosFileTime) getUint(de.offset + 10);\n        de._crc32 = getUint(de.offset + 14);\n        de._compressedSize = max(getUint(de.offset + 18), de.compressedSize);\n        de._expandedSize = max(getUint(de.offset + 22), de.expandedSize);\n        namelen = getUshort(de.offset + 26);\n        extralen = getUshort(de.offset + 28);\n\n        debug(print)\n        {\n            printf(\"\\t\\texpandedSize = %d\\n\", de.expandedSize);\n            printf(\"\\t\\tcompressedSize = %d\\n\", de.compressedSize);\n            printf(\"\\t\\tnamelen = %d\\n\", namelen);\n            printf(\"\\t\\textralen = %d\\n\", extralen);\n        }\n\n        if (de.flags & 1)\n            throw new ZipException(\"encryption not supported\");\n\n        uint i;\n        i = de.offset + 30 + namelen + extralen;\n        if (i + de.compressedSize > endrecOffset)\n            throw new ZipException(\"invalid directory entry 5\");\n\n        de._compressedData = _data[i .. i + de.compressedSize];\n        debug(print) arrayPrint(de.compressedData);\n\n        switch (de.compressionMethod)\n        {\n            case CompressionMethod.none:\n                de._expandedData = de.compressedData;\n                return de.expandedData;\n\n            case CompressionMethod.deflate:\n                // -15 is a magic value used to decompress zip files.\n                // It has the effect of not requiring the 2 byte header\n                // and 4 byte trailer.\n                import std.zlib : uncompress;\n                de._expandedData = cast(ubyte[]) uncompress(cast(void[]) de.compressedData, de.expandedSize, -15);\n                return de.expandedData;\n\n            default:\n                throw new ZipException(\"unsupported compression method\");\n        }\n    }\n\n    /* ============ Utility =================== */\n\n    @safe @nogc pure nothrow ushort getUshort(uint i)\n    {\n        ubyte[2] result = data[i .. i + 2];\n        return littleEndianToNative!ushort(result);\n    }\n\n    @safe @nogc pure nothrow uint getUint(uint i)\n    {\n        ubyte[4] result = data[i .. i + 4];\n        return littleEndianToNative!uint(result);\n    }\n\n    @safe @nogc pure nothrow ulong getUlong(uint i)\n    {\n        ubyte[8] result = data[i .. i + 8];\n        return littleEndianToNative!ulong(result);\n    }\n\n    @safe @nogc pure nothrow void putUshort(uint i, ushort us)\n    {\n        data[i .. i + 2] = nativeToLittleEndian(us);\n    }\n\n    @safe @nogc pure nothrow void putUint(uint i, uint ui)\n    {\n        data[i .. i + 4] = nativeToLittleEndian(ui);\n    }\n\n    @safe @nogc pure nothrow void putUlong(uint i, ulong ul)\n    {\n        data[i .. i + 8] = nativeToLittleEndian(ul);\n    }\n}\n\ndebug(print)\n{\n    @safe void arrayPrint(ubyte[] array)\n    {\n        printf(\"array %p,%d\\n\", cast(void*) array, array.length);\n        for (int i = 0; i < array.length; i++)\n        {\n            printf(\"%02x \", array[i]);\n            if (((i + 1) & 15) == 0)\n                printf(\"\\n\");\n        }\n        printf(\"\\n\");\n    }\n}\n\n@system unittest\n{\n    // @system due to (at least) ZipArchive.build\n    auto zip1 = new ZipArchive();\n    auto zip2 = new ZipArchive();\n    auto am1 = new ArchiveMember();\n    am1.name = \"foo\";\n    am1.expandedData = new ubyte[](1024);\n    zip1.addMember(am1);\n    auto data1 = zip1.build();\n    zip2.addMember(zip1.directory[\"foo\"]);\n    zip2.build();\n    auto am2 = zip2.directory[\"foo\"];\n    zip2.expand(am2);\n    assert(am1.expandedData == am2.expandedData);\n    auto zip3 = new ZipArchive(data1);\n    zip3.build();\n    assert(zip3.directory[\"foo\"].compressedSize == am1.compressedSize);\n\n    // Test if packing and unpacking produces the original data\n    import std.conv, std.stdio;\n    import std.random : uniform, MinstdRand0;\n    MinstdRand0 gen;\n    const uint itemCount = 20, minSize = 10, maxSize = 500;\n    foreach (variant; 0 .. 2)\n    {\n        bool useZip64 = !!variant;\n        zip1 = new ZipArchive();\n        zip1.isZip64 = useZip64;\n        ArchiveMember[itemCount] ams;\n        foreach (i; 0 .. itemCount)\n        {\n            ams[i] = new ArchiveMember();\n            ams[i].name = to!string(i);\n            ams[i].expandedData = new ubyte[](uniform(minSize, maxSize));\n            foreach (ref ubyte c; ams[i].expandedData)\n                c = cast(ubyte)(uniform(0, 256));\n            ams[i].compressionMethod = CompressionMethod.deflate;\n            zip1.addMember(ams[i]);\n        }\n        auto zippedData = zip1.build();\n        zip2 = new ZipArchive(zippedData);\n        assert(zip2.isZip64 == useZip64);\n        foreach (am; ams)\n        {\n            am2 = zip2.directory[am.name];\n            zip2.expand(am2);\n            assert(am.crc32 == am2.crc32);\n            assert(am.expandedData == am2.expandedData);\n        }\n    }\n}\n\n@system unittest\n{\n    import std.conv : to;\n    import std.random : Mt19937, randomShuffle;\n    // Test if packing and unpacking preserves order.\n    auto rand = Mt19937(15966);\n    string[] names;\n    int value = 0;\n    // Generate a series of unique numbers as filenames.\n    foreach (i; 0 .. 20)\n    {\n        value += 1 + rand.front & 0xFFFF;\n        rand.popFront;\n        names ~= value.to!string;\n    }\n    // Insert them in a random order.\n    names.randomShuffle(rand);\n    auto zip1 = new ZipArchive();\n    foreach (i, name; names)\n    {\n        auto member = new ArchiveMember();\n        member.name = name;\n        member.expandedData = cast(ubyte[]) name;\n        member.index = cast(int) i;\n        zip1.addMember(member);\n    }\n    auto data = zip1.build();\n\n    // Ensure that they appear in the same order.\n    auto zip2 = new ZipArchive(data);\n    foreach (i, name; names)\n    {\n        const member = zip2.directory[name];\n        assert(member.index == i, \"member \" ~ name ~ \" had index \" ~\n                member.index.to!string ~ \" but we expected index \" ~ i.to!string ~\n                \". The input array was \" ~ names.to!string);\n    }\n}\n\n@system unittest\n{\n    import std.zlib;\n\n    ubyte[] src = cast(ubyte[])\n\"the quick brown fox jumps over the lazy dog\\r\nthe quick brown fox jumps over the lazy dog\\r\n\";\n    auto dst = cast(ubyte[]) compress(cast(void[]) src);\n    auto after = cast(ubyte[]) uncompress(cast(void[]) dst);\n    assert(src == after);\n}\n\n@system unittest\n{\n    // @system due to ZipArchive.build\n    import std.datetime;\n    ubyte[] buf = [1, 2, 3, 4, 5, 0, 7, 8, 9];\n\n    auto ar = new ZipArchive;\n    auto am = new ArchiveMember;  // 10\n    am.name = \"buf\";\n    am.expandedData = buf;\n    am.compressionMethod = CompressionMethod.deflate;\n    am.time = SysTimeToDosFileTime(Clock.currTime());\n    ar.addMember(am);            // 15\n\n    auto zip1 = ar.build();\n    auto arAfter = new ZipArchive(zip1);\n    assert(arAfter.directory.length == 1);\n    auto amAfter = arAfter.directory[\"buf\"];\n    arAfter.expand(amAfter);\n    assert(amAfter.name == am.name);\n    assert(amAfter.expandedData == am.expandedData);\n    assert(amAfter.time == am.time);\n}\n\n// Non-Android Posix-only, because we can't rely on the unzip command being\n// available on Android or Windows\nversion (Android) {} else\nversion (Posix) @system unittest\n{\n    import std.datetime, std.file, std.format, std.path, std.process, std.stdio;\n\n    auto zr = new ZipArchive();\n    auto am = new ArchiveMember();\n    am.compressionMethod = CompressionMethod.deflate;\n    am.name = \"foo.bar\";\n    am.time = SysTimeToDosFileTime(Clock.currTime());\n    am.expandedData = cast(ubyte[])\"We all live in a yellow submarine, a yellow submarine\";\n    zr.addMember(am);\n    auto data2 = zr.build();\n\n    mkdirRecurse(deleteme);\n    scope(exit) rmdirRecurse(deleteme);\n    string zipFile = buildPath(deleteme, \"foo.zip\");\n    std.file.write(zipFile, cast(byte[]) data2);\n\n    auto result = executeShell(format(\"unzip -l %s\", zipFile));\n    scope(failure) writeln(result.output);\n    assert(result.status == 0);\n}\n"
  },
  {
    "path": "libphobos/src/std/zlib.d",
    "content": "// Written in the D programming language.\n\n/**\n * Compress/decompress data using the $(HTTP www.zlib.net, zlib library).\n *\n * Examples:\n *\n * If you have a small buffer you can use $(LREF compress) and\n * $(LREF uncompress) directly.\n *\n * -------\n * import std.zlib;\n *\n * auto src =\n * \"the quick brown fox jumps over the lazy dog\\r\n *  the quick brown fox jumps over the lazy dog\\r\";\n *\n * ubyte[] dst;\n * ubyte[] result;\n *\n * dst = compress(src);\n * result = cast(ubyte[]) uncompress(dst);\n * assert(result == src);\n * -------\n *\n * When the data to be compressed doesn't fit in one buffer, use\n * $(LREF Compress) and $(LREF UnCompress).\n *\n * -------\n * import std.zlib;\n * import std.stdio;\n * import std.conv : to;\n * import std.algorithm.iteration : map;\n *\n * UnCompress decmp = new UnCompress;\n * foreach (chunk; stdin.byChunk(4096).map!(x => decmp.uncompress(x)))\n * {\n *     chunk.to!string.write;\n * }\n\n * -------\n *\n * References:\n *  $(HTTP en.wikipedia.org/wiki/Zlib, Wikipedia)\n *\n * Copyright: Copyright The D Language Foundation 2000 - 2011.\n * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).\n * Authors:   $(HTTP digitalmars.com, Walter Bright)\n * Source:    $(PHOBOSSRC std/zlib.d)\n */\n/*          Copyright The D Language Foundation 2000 - 2011.\n * Distributed under the Boost Software License, Version 1.0.\n *    (See accompanying file LICENSE_1_0.txt or copy at\n *          http://www.boost.org/LICENSE_1_0.txt)\n */\nmodule std.zlib;\n\n//debug=zlib;       // uncomment to turn on debugging printf's\n\nimport etc.c.zlib;\n\n// Values for 'mode'\n\nenum\n{\n    Z_NO_FLUSH      = 0,\n    Z_SYNC_FLUSH    = 2,\n    Z_FULL_FLUSH    = 3,\n    Z_FINISH        = 4,\n}\n\n/*************************************\n * Errors throw a ZlibException.\n */\n\nclass ZlibException : Exception\n{\n    private static string getmsg(int errnum) nothrow @nogc pure @safe\n    {\n        string msg;\n        switch (errnum)\n        {\n            case Z_STREAM_END:      msg = \"stream end\"; break;\n            case Z_NEED_DICT:       msg = \"need dict\"; break;\n            case Z_ERRNO:           msg = \"errno\"; break;\n            case Z_STREAM_ERROR:    msg = \"stream error\"; break;\n            case Z_DATA_ERROR:      msg = \"data error\"; break;\n            case Z_MEM_ERROR:       msg = \"mem error\"; break;\n            case Z_BUF_ERROR:       msg = \"buf error\"; break;\n            case Z_VERSION_ERROR:   msg = \"version error\"; break;\n            default:                msg = \"unknown error\";  break;\n        }\n        return msg;\n    }\n\n    this(int errnum)\n    {\n        super(getmsg(errnum));\n    }\n}\n\n/**\n * $(P Compute the Adler-32 checksum of a buffer's worth of data.)\n *\n * Params:\n *     adler = the starting checksum for the computation. Use 1\n *             for a new checksum. Use the output of this function\n *             for a cumulative checksum.\n *     buf = buffer containing input data\n *\n * Returns:\n *     A `uint` checksum for the provided input data and starting checksum\n *\n * See_Also:\n *     $(LINK http://en.wikipedia.org/wiki/Adler-32)\n */\n\nuint adler32(uint adler, const(void)[] buf)\n{\n    import std.range : chunks;\n    foreach (chunk; (cast(ubyte[]) buf).chunks(0xFFFF0000))\n    {\n        adler = etc.c.zlib.adler32(adler, chunk.ptr, cast(uint) chunk.length);\n    }\n    return adler;\n}\n\n///\n@system unittest\n{\n    static ubyte[] data = [1,2,3,4,5,6,7,8,9,10];\n\n    uint adler = adler32(0u, data);\n    assert(adler == 0xdc0037);\n}\n\n@system unittest\n{\n    static string data = \"test\";\n\n    uint adler = adler32(1, data);\n    assert(adler == 0x045d01c1);\n}\n\n/**\n * $(P Compute the CRC32 checksum of a buffer's worth of data.)\n *\n * Params:\n *     crc = the starting checksum for the computation. Use 0\n *             for a new checksum. Use the output of this function\n *             for a cumulative checksum.\n *     buf = buffer containing input data\n *\n * Returns:\n *     A `uint` checksum for the provided input data and starting checksum\n *\n * See_Also:\n *     $(LINK http://en.wikipedia.org/wiki/Cyclic_redundancy_check)\n */\n\nuint crc32(uint crc, const(void)[] buf)\n{\n    import std.range : chunks;\n    foreach (chunk; (cast(ubyte[]) buf).chunks(0xFFFF0000))\n    {\n        crc = etc.c.zlib.crc32(crc, chunk.ptr, cast(uint) chunk.length);\n    }\n    return crc;\n}\n\n@system unittest\n{\n    static ubyte[] data = [1,2,3,4,5,6,7,8,9,10];\n\n    uint crc;\n\n    debug(zlib) printf(\"D.zlib.crc32.unittest\\n\");\n    crc = crc32(0u, cast(void[]) data);\n    debug(zlib) printf(\"crc = %x\\n\", crc);\n    assert(crc == 0x2520577b);\n}\n\n/**\n * $(P Compress data)\n *\n * Params:\n *     srcbuf = buffer containing the data to compress\n *     level = compression level. Legal values are -1 .. 9, with -1 indicating\n *             the default level (6), 0 indicating no compression, 1 being the\n *             least compression and 9 being the most.\n *\n * Returns:\n *     the compressed data\n */\n\nubyte[] compress(const(void)[] srcbuf, int level)\nin\n{\n    assert(-1 <= level && level <= 9, \"Compression level needs to be within [-1, 9].\");\n}\ndo\n{\n    import core.memory : GC;\n    import std.array : uninitializedArray;\n    auto destlen = srcbuf.length + ((srcbuf.length + 1023) / 1024) + 12;\n    auto destbuf = uninitializedArray!(ubyte[])(destlen);\n    auto err = etc.c.zlib.compress2(destbuf.ptr, &destlen, cast(ubyte *) srcbuf.ptr, srcbuf.length, level);\n    if (err)\n    {\n        GC.free(destbuf.ptr);\n        throw new ZlibException(err);\n    }\n\n    destbuf.length = destlen;\n    return destbuf;\n}\n\n/*********************************************\n * ditto\n */\n\nubyte[] compress(const(void)[] srcbuf)\n{\n    return compress(srcbuf, Z_DEFAULT_COMPRESSION);\n}\n\n/*********************************************\n * Decompresses the data in srcbuf[].\n * Params:\n *  srcbuf  = buffer containing the compressed data.\n *  destlen = size of the uncompressed data.\n *            It need not be accurate, but the decompression will be faster\n *            if the exact size is supplied.\n *  winbits = the base two logarithm of the maximum window size.\n * Returns: the decompressed data.\n */\n\nvoid[] uncompress(const(void)[] srcbuf, size_t destlen = 0u, int winbits = 15)\n{\n    import std.conv : to;\n    int err;\n    ubyte[] destbuf;\n\n    if (!destlen)\n        destlen = srcbuf.length * 2 + 1;\n\n    etc.c.zlib.z_stream zs;\n    zs.next_in = cast(typeof(zs.next_in)) srcbuf.ptr;\n    zs.avail_in = to!uint(srcbuf.length);\n    err = etc.c.zlib.inflateInit2(&zs, winbits);\n    if (err)\n    {\n        throw new ZlibException(err);\n    }\n\n    size_t olddestlen = 0u;\n\n    loop:\n    while (true)\n    {\n        destbuf.length = destlen;\n        zs.next_out = cast(typeof(zs.next_out)) &destbuf[olddestlen];\n        zs.avail_out = to!uint(destlen - olddestlen);\n        olddestlen = destlen;\n\n        err = etc.c.zlib.inflate(&zs, Z_NO_FLUSH);\n        switch (err)\n        {\n            case Z_OK:\n                destlen = destbuf.length * 2;\n                continue loop;\n\n            case Z_STREAM_END:\n                destbuf.length = zs.total_out;\n                err = etc.c.zlib.inflateEnd(&zs);\n                if (err != Z_OK)\n                    throw new ZlibException(err);\n                return destbuf;\n\n            default:\n                etc.c.zlib.inflateEnd(&zs);\n                throw new ZlibException(err);\n        }\n    }\n    assert(0, \"Unreachable code\");\n}\n\n@system unittest\n{\n    auto src =\n\"the quick brown fox jumps over the lazy dog\\r\nthe quick brown fox jumps over the lazy dog\\r\n\";\n    ubyte[] dst;\n    ubyte[] result;\n\n    //arrayPrint(src);\n    dst = compress(src);\n    //arrayPrint(dst);\n    result = cast(ubyte[]) uncompress(dst);\n    //arrayPrint(result);\n    assert(result == src);\n}\n\n@system unittest\n{\n    ubyte[] src = new ubyte[1000000];\n    ubyte[] dst;\n    ubyte[] result;\n\n    src[] = 0x80;\n    dst = compress(src);\n    assert(dst.length*2 + 1 < src.length);\n    result = cast(ubyte[]) uncompress(dst);\n    assert(result == src);\n}\n\n/+\nvoid arrayPrint(ubyte[] array)\n{\n    //printf(\"array %p,%d\\n\", cast(void*) array, array.length);\n    for (size_t i = 0; i < array.length; i++)\n    {\n        printf(\"%02x \", array[i]);\n        if (((i + 1) & 15) == 0)\n            printf(\"\\n\");\n    }\n    printf(\"\\n\\n\");\n}\n+/\n\n/// the header format the compressed stream is wrapped in\nenum HeaderFormat {\n    deflate, /// a standard zlib header\n    gzip, /// a gzip file format header\n    determineFromData /// used when decompressing. Try to automatically detect the stream format by looking at the data\n}\n\n/*********************************************\n * Used when the data to be compressed is not all in one buffer.\n */\n\nclass Compress\n{\n    import std.conv : to;\n\n  private:\n    z_stream zs;\n    int level = Z_DEFAULT_COMPRESSION;\n    int inited;\n    immutable bool gzip;\n\n    void error(int err)\n    {\n        if (inited)\n        {   deflateEnd(&zs);\n            inited = 0;\n        }\n        throw new ZlibException(err);\n    }\n\n  public:\n\n    /**\n     * Constructor.\n     *\n     * Params:\n     *    level = compression level. Legal values are 1 .. 9, with 1 being the least\n     *            compression and 9 being the most. The default value is 6.\n     *    header = sets the compression type to one of the options available\n     *             in $(LREF HeaderFormat). Defaults to HeaderFormat.deflate.\n     *\n     * See_Also:\n     *    $(LREF compress), $(LREF HeaderFormat)\n     */\n    this(int level, HeaderFormat header = HeaderFormat.deflate)\n    in\n    {\n        assert(1 <= level && level <= 9, \"Legal compression level are in [1, 9].\");\n    }\n    do\n    {\n        this.level = level;\n        this.gzip = header == HeaderFormat.gzip;\n    }\n\n    /// ditto\n    this(HeaderFormat header = HeaderFormat.deflate)\n    {\n        this.gzip = header == HeaderFormat.gzip;\n    }\n\n    ~this()\n    {   int err;\n\n        if (inited)\n        {\n            inited = 0;\n            deflateEnd(&zs);\n        }\n    }\n\n    /**\n     * Compress the data in buf and return the compressed data.\n     * Params:\n     *    buf = data to compress\n     *\n     * Returns:\n     *    the compressed data. The buffers returned from successive calls to this should be concatenated together.\n     *\n     */\n    const(void)[] compress(const(void)[] buf)\n    {\n        import core.memory : GC;\n        import std.array : uninitializedArray;\n        int err;\n        ubyte[] destbuf;\n\n        if (buf.length == 0)\n            return null;\n\n        if (!inited)\n        {\n            err = deflateInit2(&zs, level, Z_DEFLATED, 15 + (gzip ? 16 : 0), 8, Z_DEFAULT_STRATEGY);\n            if (err)\n                error(err);\n            inited = 1;\n        }\n\n        destbuf = uninitializedArray!(ubyte[])(zs.avail_in + buf.length);\n        zs.next_out = destbuf.ptr;\n        zs.avail_out = to!uint(destbuf.length);\n\n        if (zs.avail_in)\n            buf = zs.next_in[0 .. zs.avail_in] ~ cast(ubyte[]) buf;\n\n        zs.next_in = cast(typeof(zs.next_in)) buf.ptr;\n        zs.avail_in = to!uint(buf.length);\n\n        err = deflate(&zs, Z_NO_FLUSH);\n        if (err != Z_STREAM_END && err != Z_OK)\n        {\n            GC.free(destbuf.ptr);\n            error(err);\n        }\n        destbuf.length = destbuf.length - zs.avail_out;\n        return destbuf;\n    }\n\n    /***\n     * Compress and return any remaining data.\n     * The returned data should be appended to that returned by compress().\n     * Params:\n     *  mode = one of the following:\n     *          $(DL\n                    $(DT Z_SYNC_FLUSH )\n                    $(DD Syncs up flushing to the next byte boundary.\n                        Used when more data is to be compressed later on.)\n                    $(DT Z_FULL_FLUSH )\n                    $(DD Syncs up flushing to the next byte boundary.\n                        Used when more data is to be compressed later on,\n                        and the decompressor needs to be restartable at this\n                        point.)\n                    $(DT Z_FINISH)\n                    $(DD (default) Used when finished compressing the data. )\n                )\n     */\n    void[] flush(int mode = Z_FINISH)\n    in\n    {\n        assert(mode == Z_FINISH || mode == Z_SYNC_FLUSH || mode == Z_FULL_FLUSH,\n                \"Mode must be either Z_FINISH, Z_SYNC_FLUSH or Z_FULL_FLUSH.\");\n    }\n    do\n    {\n        import core.memory : GC;\n        ubyte[] destbuf;\n        ubyte[512] tmpbuf = void;\n        int err;\n\n        if (!inited)\n            return null;\n\n        /* may be  zs.avail_out+<some constant>\n         * zs.avail_out is set nonzero by deflate in previous compress()\n         */\n        //tmpbuf = new void[zs.avail_out];\n        zs.next_out = tmpbuf.ptr;\n        zs.avail_out = tmpbuf.length;\n\n        while ( (err = deflate(&zs, mode)) != Z_STREAM_END)\n        {\n            if (err == Z_OK)\n            {\n                if (zs.avail_out != 0 && mode != Z_FINISH)\n                    break;\n                else if (zs.avail_out == 0)\n                {\n                    destbuf ~= tmpbuf;\n                    zs.next_out = tmpbuf.ptr;\n                    zs.avail_out = tmpbuf.length;\n                    continue;\n                }\n                err = Z_BUF_ERROR;\n            }\n            GC.free(destbuf.ptr);\n            error(err);\n        }\n        destbuf ~= tmpbuf[0 .. (tmpbuf.length - zs.avail_out)];\n\n        if (mode == Z_FINISH)\n        {\n            err = deflateEnd(&zs);\n            inited = 0;\n            if (err)\n                error(err);\n        }\n        return destbuf;\n    }\n}\n\n/******\n * Used when the data to be decompressed is not all in one buffer.\n */\n\nclass UnCompress\n{\n    import std.conv : to;\n\n  private:\n    z_stream zs;\n    int inited;\n    int done;\n    bool inputEnded;\n    size_t destbufsize;\n\n    HeaderFormat format;\n\n    void error(int err)\n    {\n        if (inited)\n        {   inflateEnd(&zs);\n            inited = 0;\n        }\n        throw new ZlibException(err);\n    }\n\n  public:\n\n    /**\n     * Construct. destbufsize is the same as for D.zlib.uncompress().\n     */\n    this(uint destbufsize)\n    {\n        this.destbufsize = destbufsize;\n    }\n\n    /** ditto */\n    this(HeaderFormat format = HeaderFormat.determineFromData)\n    {\n        this.format = format;\n    }\n\n    ~this()\n    {   int err;\n\n        if (inited)\n        {\n            inited = 0;\n            inflateEnd(&zs);\n        }\n        done = 1;\n    }\n\n    /**\n     * Decompress the data in buf and return the decompressed data.\n     * The buffers returned from successive calls to this should be concatenated\n     * together.\n     */\n    const(void)[] uncompress(const(void)[] buf)\n    in\n    {\n        assert(!done, \"Buffer has been flushed.\");\n    }\n    do\n    {\n        if (inputEnded || !buf.length)\n            return null;\n\n        import core.memory : GC;\n        import std.array : uninitializedArray;\n        int err;\n\n        if (!inited)\n        {\n        int windowBits = 15;\n        if (format == HeaderFormat.gzip)\n            windowBits += 16;\n            else if (format == HeaderFormat.determineFromData)\n            windowBits += 32;\n\n            err = inflateInit2(&zs, windowBits);\n            if (err)\n                error(err);\n            inited = 1;\n        }\n\n        if (!destbufsize)\n            destbufsize = to!uint(buf.length) * 2;\n        auto destbuf = uninitializedArray!(ubyte[])(destbufsize);\n        size_t destFill;\n\n        zs.next_in = cast(ubyte*) buf.ptr;\n        zs.avail_in = to!uint(buf.length);\n\n        while (true)\n        {\n            auto oldAvailIn = zs.avail_in;\n\n            zs.next_out = destbuf[destFill .. $].ptr;\n            zs.avail_out = to!uint(destbuf.length - destFill);\n\n            err = inflate(&zs, Z_NO_FLUSH);\n            if (err == Z_STREAM_END)\n            {\n                inputEnded = true;\n                break;\n            }\n            else if (err != Z_OK)\n            {\n                GC.free(destbuf.ptr);\n                error(err);\n            }\n            else if (!zs.avail_in)\n                break;\n\n            /*\n                According to the zlib manual inflate() stops when either there's\n                no more data to uncompress or the output buffer is full\n                So at this point, the output buffer is too full\n            */\n\n            destFill = destbuf.length;\n\n            if (destbuf.capacity)\n            {\n                if (destbuf.length < destbuf.capacity)\n                    destbuf.length = destbuf.capacity;\n                else\n                {\n                    auto newLength = GC.extend(destbuf.ptr, destbufsize, destbufsize);\n\n                    if (newLength && destbuf.length < destbuf.capacity)\n                        destbuf.length = destbuf.capacity;\n                    else\n                        destbuf.length += destbufsize;\n                }\n            }\n            else\n                destbuf.length += destbufsize;\n        }\n\n        destbuf.length = destbuf.length - zs.avail_out;\n        return destbuf;\n    }\n\n    // Test for issues 3191 and 9505\n    @system unittest\n    {\n        import std.algorithm.comparison;\n        import std.array;\n        import std.file;\n        import std.zlib;\n\n        // Data that can be easily compressed\n        ubyte[1024] originalData;\n\n        // This should yield a compression ratio of at least 1/2\n        auto compressedData = compress(originalData, 9);\n        assert(compressedData.length < originalData.length / 2,\n                \"The compression ratio is too low to accurately test this situation\");\n\n        auto chunkSize = compressedData.length / 4;\n        assert(chunkSize < compressedData.length,\n                \"The length of the compressed data is too small to accurately test this situation\");\n\n        auto decompressor = new UnCompress();\n        ubyte[originalData.length] uncompressedData;\n        ubyte[] reusedBuf;\n        int progress;\n\n        reusedBuf.length = chunkSize;\n\n        for (int i = 0; i < compressedData.length; i += chunkSize)\n        {\n            auto len = min(chunkSize, compressedData.length - i);\n            // simulate reading from a stream in small chunks\n            reusedBuf[0 .. len] = compressedData[i .. i + len];\n\n            // decompress using same input buffer\n            auto chunk = decompressor.uncompress(reusedBuf);\n            assert(progress + chunk.length <= originalData.length,\n                    \"The uncompressed result is bigger than the original data\");\n\n            uncompressedData[progress .. progress + chunk.length] = cast(const ubyte[]) chunk[];\n            progress += chunk.length;\n        }\n\n        auto chunk = decompressor.flush();\n        assert(progress + chunk.length <= originalData.length,\n                \"The uncompressed result is bigger than the original data\");\n\n        uncompressedData[progress .. progress + chunk.length] = cast(const ubyte[]) chunk[];\n        progress += chunk.length;\n\n        assert(progress == originalData.length,\n                \"The uncompressed and the original data sizes differ\");\n        assert(originalData[] == uncompressedData[],\n                \"The uncompressed and the original data differ\");\n    }\n\n    @system unittest\n    {\n        ubyte[1024] invalidData;\n        auto decompressor = new UnCompress();\n\n        try\n        {\n            auto uncompressedData = decompressor.uncompress(invalidData);\n        }\n        catch (ZlibException e)\n        {\n            assert(e.msg == \"data error\");\n            return;\n        }\n\n        assert(false, \"Corrupted data didn't result in an error\");\n    }\n\n    @system unittest\n    {\n        ubyte[2014] originalData = void;\n        auto compressedData = compress(originalData, 9);\n\n        auto decompressor = new UnCompress();\n        auto uncompressedData = decompressor.uncompress(compressedData ~ cast(ubyte[]) \"whatever\");\n\n        assert(originalData.length == uncompressedData.length,\n                \"The uncompressed and the original data sizes differ\");\n        assert(originalData[] == uncompressedData[],\n                \"The uncompressed and the original data differ\");\n        assert(!decompressor.uncompress(\"whatever\").length,\n                \"Compression continued after the end\");\n    }\n\n    /**\n     * Decompress and return any remaining data.\n     * The returned data should be appended to that returned by uncompress().\n     * The UnCompress object cannot be used further.\n     */\n    void[] flush()\n    in\n    {\n        assert(!done, \"Buffer has been flushed before.\");\n    }\n    out\n    {\n        assert(done, \"Flushing failed.\");\n    }\n    do\n    {\n        done = 1;\n        return null;\n    }\n\n    /// Returns true if all input data has been decompressed and no further data\n    /// can be decompressed (inflate() returned Z_STREAM_END)\n    @property bool empty() const\n    {\n        return inputEnded;\n    }\n\n    ///\n    @system unittest\n    {\n        // some random data\n        ubyte[1024] originalData = void;\n\n        // append garbage data (or don't, this works in both cases)\n        auto compressedData = cast(ubyte[]) compress(originalData) ~ cast(ubyte[]) \"whatever\";\n\n        auto decompressor = new UnCompress();\n        auto uncompressedData = decompressor.uncompress(compressedData);\n\n        assert(uncompressedData[] == originalData[],\n                \"The uncompressed and the original data differ\");\n        assert(decompressor.empty, \"The UnCompressor reports not being done\");\n    }\n}\n\n/* ========================== unittest ========================= */\n\nimport std.random;\nimport std.stdio;\n\n@system unittest // by Dave\n{\n    debug(zlib) writeln(\"std.zlib.unittest\");\n\n    bool CompressThenUncompress (void[] src)\n    {\n        ubyte[] dst = std.zlib.compress(src);\n        double ratio = (dst.length / cast(double) src.length);\n        debug(zlib) writef(\"src.length: %1$d, dst: %2$d, Ratio = %3$f\", src.length, dst.length, ratio);\n        ubyte[] uncompressedBuf;\n        uncompressedBuf = cast(ubyte[]) std.zlib.uncompress(dst);\n        assert(src.length == uncompressedBuf.length);\n        assert(src == uncompressedBuf);\n\n        return true;\n    }\n\n\n    // smallish buffers\n    for (int idx = 0; idx < 25; idx++)\n    {\n        char[] buf = new char[uniform(0, 100)];\n\n        // Alternate between more & less compressible\n        foreach (ref char c; buf)\n            c = cast(char) (' ' + (uniform(0, idx % 2 ? 91 : 2)));\n\n        if (CompressThenUncompress(buf))\n        {\n            debug(zlib) writeln(\"; Success.\");\n        }\n        else\n        {\n            return;\n        }\n    }\n\n    // larger buffers\n    for (int idx = 0; idx < 25; idx++)\n    {\n        char[] buf = new char[uniform(0, 1000/*0000*/)];\n\n        // Alternate between more & less compressible\n        foreach (ref char c; buf)\n            c = cast(char) (' ' + (uniform(0, idx % 2 ? 91 : 10)));\n\n        if (CompressThenUncompress(buf))\n        {\n            debug(zlib) writefln(\"; Success.\");\n        }\n        else\n        {\n            return;\n        }\n    }\n\n    debug(zlib) writefln(\"PASSED std.zlib.unittest\");\n}\n\n\n@system unittest // by Artem Rebrov\n{\n    Compress cmp = new Compress;\n    UnCompress decmp = new UnCompress;\n\n    const(void)[] input;\n    input = \"tesatdffadf\";\n\n    const(void)[] buf = cmp.compress(input);\n    buf ~= cmp.flush();\n    const(void)[] output = decmp.uncompress(buf);\n\n    //writefln(\"input = '%s'\", cast(char[]) input);\n    //writefln(\"output = '%s'\", cast(char[]) output);\n    assert( output[] == input[] );\n}\n\n@system unittest\n{\n    static assert(__traits(compiles, etc.c.zlib.gzclose(null)));        // bugzilla 15457\n}\n"
  },
  {
    "path": "libphobos/testsuite/Makefile.am",
    "content": "## Makefile for the testsuite subdirectory of the D Standard library.\n## Copyright (C) 2016-2018 Free Software Foundation, Inc.\n##\n## GCC is free software; you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation; either version 3, or (at your option)\n## any later version.\n##\n## GCC is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License\n## along with GCC; see the file COPYING3.  If not see\n## <http://www.gnu.org/licenses/>.\n\n# Process this file with automake to produce Makefile.in.\n\nAUTOMAKE_OPTIONS = foreign dejagnu\n\n# Setup the testing framework, if you have one\nEXPECT = $(shell if test -f $(top_builddir)/../expect/expect; then \\\n\t   echo $(top_builddir)/../expect/expect; else echo expect; fi)\n\n_RUNTEST = $(shell if test -f $(top_srcdir)/../dejagnu/runtest; then \\\n\t     echo $(top_srcdir)/../dejagnu/runtest; else echo runtest; fi)\nRUNTEST = \"$(_RUNTEST) $(AM_RUNTESTFLAGS)\"\n\nAM_MAKEFLAGS = \"EXEEXT=$(EXEEXT)\"\n\nCLEANFILES = *.log *.sum\n"
  },
  {
    "path": "libphobos/testsuite/Makefile.in",
    "content": "# Makefile.in generated by automake 1.11.6 from Makefile.am.\n# @configure_input@\n\n# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,\n# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software\n# Foundation, Inc.\n# This Makefile.in is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY, to the extent permitted by law; without\n# even the implied warranty of MERCHANTABILITY or FITNESS FOR A\n# PARTICULAR PURPOSE.\n\n@SET_MAKE@\n\n# Process this file with automake to produce Makefile.in.\nVPATH = @srcdir@\nam__make_dryrun = \\\n  { \\\n    am__dry=no; \\\n    case $$MAKEFLAGS in \\\n      *\\\\[\\ \\\t]*) \\\n        echo 'am--echo: ; @echo \"AM\"  OK' | $(MAKE) -f - 2>/dev/null \\\n          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \\\n      *) \\\n        for am__flg in $$MAKEFLAGS; do \\\n          case $$am__flg in \\\n            *=*|--*) ;; \\\n            *n*) am__dry=yes; break;; \\\n          esac; \\\n        done;; \\\n    esac; \\\n    test $$am__dry = yes; \\\n  }\npkgdatadir = $(datadir)/@PACKAGE@\npkgincludedir = $(includedir)/@PACKAGE@\npkglibdir = $(libdir)/@PACKAGE@\npkglibexecdir = $(libexecdir)/@PACKAGE@\nam__cd = CDPATH=\"$${ZSH_VERSION+.}$(PATH_SEPARATOR)\" && cd\ninstall_sh_DATA = $(install_sh) -c -m 644\ninstall_sh_PROGRAM = $(install_sh) -c\ninstall_sh_SCRIPT = $(install_sh) -c\nINSTALL_HEADER = $(INSTALL_DATA)\ntransform = $(program_transform_name)\nNORMAL_INSTALL = :\nPRE_INSTALL = :\nPOST_INSTALL = :\nNORMAL_UNINSTALL = :\nPRE_UNINSTALL = :\nPOST_UNINSTALL = :\nbuild_triplet = @build@\nhost_triplet = @host@\ntarget_triplet = @target@\nsubdir = testsuite\nDIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \\\n\t$(srcdir)/testsuite_flags.in\nACLOCAL_M4 = $(top_srcdir)/aclocal.m4\nam__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \\\n\t$(top_srcdir)/../config/lead-dot.m4 \\\n\t$(top_srcdir)/../config/multi.m4 \\\n\t$(top_srcdir)/../config/override.m4 \\\n\t$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \\\n\t$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \\\n\t$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \\\n\t$(top_srcdir)/m4/gcc_support.m4 $(top_srcdir)/m4/autoconf.m4 \\\n\t$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/gdc.m4 \\\n\t$(top_srcdir)/m4/druntime.m4 $(top_srcdir)/m4/druntime/cpu.m4 \\\n\t$(top_srcdir)/m4/druntime/os.m4 \\\n\t$(top_srcdir)/m4/druntime/libraries.m4 \\\n\t$(top_srcdir)/configure.ac\nam__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \\\n\t$(ACLOCAL_M4)\nmkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs\nCONFIG_HEADER = $(top_builddir)/config.h\nCONFIG_CLEAN_FILES = testsuite_flags\nCONFIG_CLEAN_VPATH_FILES =\ndepcomp =\nam__depfiles_maybe =\nSOURCES =\nam__can_run_installinfo = \\\n  case $$AM_UPDATE_INFO_DIR in \\\n    n|no|NO) false;; \\\n    *) (install-info --version) >/dev/null 2>&1;; \\\n  esac\nDEJATOOL = $(PACKAGE)\nRUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir\nACLOCAL = @ACLOCAL@\nAMTAR = @AMTAR@\nAR = @AR@\nAUTOCONF = @AUTOCONF@\nAUTOHEADER = @AUTOHEADER@\nAUTOMAKE = @AUTOMAKE@\nAWK = @AWK@\nBACKTRACE_SUPPORTED = @BACKTRACE_SUPPORTED@\nBACKTRACE_SUPPORTS_THREADS = @BACKTRACE_SUPPORTS_THREADS@\nBACKTRACE_USES_MALLOC = @BACKTRACE_USES_MALLOC@\nCC = @CC@\nCCAS = @CCAS@\nCCASFLAGS = @CCASFLAGS@\nCC_FOR_BUILD = @CC_FOR_BUILD@\nCFLAGS = @CFLAGS@\nCFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@\nCPP = @CPP@\nCPPFLAGS = @CPPFLAGS@\nCYGPATH_W = @CYGPATH_W@\nDCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@\nDCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@\nDCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@\nDCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@\nDCFG_MINFO_BRACKETING = @DCFG_MINFO_BRACKETING@\nDCFG_THREAD_MODEL = @DCFG_THREAD_MODEL@\nDEFS = @DEFS@\nDRUNTIME_SOVERSION = @DRUNTIME_SOVERSION@\nDSYMUTIL = @DSYMUTIL@\nDUMPBIN = @DUMPBIN@\nECHO_C = @ECHO_C@\nECHO_N = @ECHO_N@\nECHO_T = @ECHO_T@\nEGREP = @EGREP@\nEXEEXT = @EXEEXT@\nFGREP = @FGREP@\nGDC = @GDC@\nGDCFLAGS = @GDCFLAGS@\nGDCFLAGSX = @GDCFLAGSX@\nGREP = @GREP@\nINSTALL = @INSTALL@\nINSTALL_DATA = @INSTALL_DATA@\nINSTALL_PROGRAM = @INSTALL_PROGRAM@\nINSTALL_SCRIPT = @INSTALL_SCRIPT@\nINSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@\nLD = @LD@\nLDFLAGS = @LDFLAGS@\nLIBATOMIC = @LIBATOMIC@\nLIBBACKTRACE = @LIBBACKTRACE@\nLIBOBJS = @LIBOBJS@\nLIBS = @LIBS@\nLIBTOOL = @LIBTOOL@\nLIPO = @LIPO@\nLN_S = @LN_S@\nLTLIBOBJS = @LTLIBOBJS@\nMAINT = @MAINT@\nMAKEINFO = @MAKEINFO@\nMKDIR_P = @MKDIR_P@\nNM = @NM@\nNMEDIT = @NMEDIT@\nOBJDUMP = @OBJDUMP@\nOBJEXT = @OBJEXT@\nOTOOL = @OTOOL@\nOTOOL64 = @OTOOL64@\nPACKAGE = @PACKAGE@\nPACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@\nPACKAGE_NAME = @PACKAGE_NAME@\nPACKAGE_STRING = @PACKAGE_STRING@\nPACKAGE_TARNAME = @PACKAGE_TARNAME@\nPACKAGE_URL = @PACKAGE_URL@\nPACKAGE_VERSION = @PACKAGE_VERSION@\nPATH_SEPARATOR = @PATH_SEPARATOR@\nPHOBOS_SOVERSION = @PHOBOS_SOVERSION@\nRANLIB = @RANLIB@\nSED = @SED@\nSET_MAKE = @SET_MAKE@\nSHELL = @SHELL@\nSPEC_PHOBOS_DEPS = @SPEC_PHOBOS_DEPS@\nSTRIP = @STRIP@\nVERSION = @VERSION@\nabs_builddir = @abs_builddir@\nabs_srcdir = @abs_srcdir@\nabs_top_builddir = @abs_top_builddir@\nabs_top_srcdir = @abs_top_srcdir@\nac_ct_CC = @ac_ct_CC@\nac_ct_DUMPBIN = @ac_ct_DUMPBIN@\nam__leading_dot = @am__leading_dot@\nam__tar = @am__tar@\nam__untar = @am__untar@\nbindir = @bindir@\nbuild = @build@\nbuild_alias = @build_alias@\nbuild_cpu = @build_cpu@\nbuild_os = @build_os@\nbuild_vendor = @build_vendor@\nbuilddir = @builddir@\ndatadir = @datadir@\ndatarootdir = @datarootdir@\ndocdir = @docdir@\ndvidir = @dvidir@\nexec_prefix = @exec_prefix@\ngcc_version = @gcc_version@\ngdc_include_dir = @gdc_include_dir@\nget_gcc_base_ver = @get_gcc_base_ver@\nhost = @host@\nhost_alias = @host_alias@\nhost_cpu = @host_cpu@\nhost_os = @host_os@\nhost_vendor = @host_vendor@\nhtmldir = @htmldir@\nincludedir = @includedir@\ninfodir = @infodir@\ninstall_sh = @install_sh@\nlibdir = @libdir@\nlibexecdir = @libexecdir@\nlibphobos_builddir = @libphobos_builddir@\nlibphobos_srcdir = @libphobos_srcdir@\nlocaledir = @localedir@\nlocalstatedir = @localstatedir@\nmandir = @mandir@\nmkdir_p = @mkdir_p@\nmulti_basedir = @multi_basedir@\noldincludedir = @oldincludedir@\npdfdir = @pdfdir@\nphobos_compiler_pic_flag = @phobos_compiler_pic_flag@\nphobos_compiler_shared_flag = @phobos_compiler_shared_flag@\nprefix = @prefix@\nprogram_transform_name = @program_transform_name@\npsdir = @psdir@\nsbindir = @sbindir@\nsharedstatedir = @sharedstatedir@\nsrcdir = @srcdir@\nsysconfdir = @sysconfdir@\ntarget = @target@\ntarget_alias = @target_alias@\ntarget_cpu = @target_cpu@\ntarget_os = @target_os@\ntarget_vendor = @target_vendor@\ntoolexecdir = @toolexecdir@\ntoolexeclibdir = @toolexeclibdir@\ntop_build_prefix = @top_build_prefix@\ntop_builddir = @top_builddir@\ntop_srcdir = @top_srcdir@\nAUTOMAKE_OPTIONS = foreign dejagnu\n\n# Setup the testing framework, if you have one\nEXPECT = $(shell if test -f $(top_builddir)/../expect/expect; then \\\n\t   echo $(top_builddir)/../expect/expect; else echo expect; fi)\n\n_RUNTEST = $(shell if test -f $(top_srcdir)/../dejagnu/runtest; then \\\n\t     echo $(top_srcdir)/../dejagnu/runtest; else echo runtest; fi)\n\nRUNTEST = \"$(_RUNTEST) $(AM_RUNTESTFLAGS)\"\nAM_MAKEFLAGS = \"EXEEXT=$(EXEEXT)\"\nCLEANFILES = *.log *.sum\nall: all-am\n\n.SUFFIXES:\n$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)\n\t@for dep in $?; do \\\n\t  case '$(am__configure_deps)' in \\\n\t    *$$dep*) \\\n\t      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \\\n\t        && { if test -f $@; then exit 0; else break; fi; }; \\\n\t      exit 1;; \\\n\t  esac; \\\n\tdone; \\\n\techo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps testsuite/Makefile'; \\\n\t$(am__cd) $(top_srcdir) && \\\n\t  $(AUTOMAKE) --foreign --ignore-deps testsuite/Makefile\n.PRECIOUS: Makefile\nMakefile: $(srcdir)/Makefile.in $(top_builddir)/config.status\n\t@case '$?' in \\\n\t  *config.status*) \\\n\t    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \\\n\t  *) \\\n\t    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \\\n\t    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \\\n\tesac;\n\n$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)\n\tcd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh\n\n$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)\n\tcd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh\n$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)\n\tcd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh\n$(am__aclocal_m4_deps):\ntestsuite_flags: $(top_builddir)/config.status $(srcdir)/testsuite_flags.in\n\tcd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@\n\nmostlyclean-libtool:\n\t-rm -f *.lo\n\nclean-libtool:\n\t-rm -rf .libs _libs\ntags: TAGS\nTAGS:\n\nctags: CTAGS\nCTAGS:\n\n\ncheck-DEJAGNU: site.exp\n\tsrcdir='$(srcdir)'; export srcdir; \\\n\tEXPECT=$(EXPECT); export EXPECT; \\\n\truntest=$(RUNTEST); \\\n\tif $(SHELL) -c \"$$runtest --version\" > /dev/null 2>&1; then \\\n\t  exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \\\n\t    if $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \\\n\t    then :; else exit_status=1; fi; \\\n\t  done; \\\n\telse echo \"WARNING: could not find \\`runtest'\" 1>&2; :;\\\n\tfi; \\\n\texit $$exit_status\nsite.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG)\n\t@echo 'Making a new site.exp file...'\n\t@echo '## these variables are automatically generated by make ##' >site.tmp\n\t@echo '# Do not edit here.  If you wish to override these values' >>site.tmp\n\t@echo '# edit the last section' >>site.tmp\n\t@echo 'set srcdir \"$(srcdir)\"' >>site.tmp\n\t@echo \"set objdir `pwd`\" >>site.tmp\n\t@echo 'set build_alias \"$(build_alias)\"' >>site.tmp\n\t@echo 'set build_triplet $(build_triplet)' >>site.tmp\n\t@echo 'set host_alias \"$(host_alias)\"' >>site.tmp\n\t@echo 'set host_triplet $(host_triplet)' >>site.tmp\n\t@echo 'set target_alias \"$(target_alias)\"' >>site.tmp\n\t@echo 'set target_triplet $(target_triplet)' >>site.tmp\n\t@list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \\\n\t  echo \"## Begin content included from file $$f.  Do not modify. ##\" \\\n\t   && cat `test -f \"$$f\" || echo '$(srcdir)/'`$$f \\\n\t   && echo \"## End content included from file $$f. ##\" \\\n\t   || exit 1; \\\n\t done >> site.tmp\n\t@echo \"## End of auto-generated content; you can edit from here. ##\" >> site.tmp\n\t@if test -f site.exp; then \\\n\t   sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \\\n\t fi\n\t@-rm -f site.bak\n\t@test ! -f site.exp || mv site.exp site.bak\n\t@mv site.tmp site.exp\n\ndistclean-DEJAGNU:\n\t-rm -f site.exp site.bak\n\t-l='$(DEJATOOL)'; for tool in $$l; do \\\n\t  rm -f $$tool.sum $$tool.log; \\\n\tdone\ncheck-am: all-am\n\t$(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU\ncheck: check-am\nall-am: Makefile\ninstalldirs:\ninstall: install-am\ninstall-exec: install-exec-am\ninstall-data: install-data-am\nuninstall: uninstall-am\n\ninstall-am: all-am\n\t@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am\n\ninstallcheck: installcheck-am\ninstall-strip:\n\tif test -z '$(STRIP)'; then \\\n\t  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" \\\n\t    install_sh_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" INSTALL_STRIP_FLAG=-s \\\n\t      install; \\\n\telse \\\n\t  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" \\\n\t    install_sh_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" INSTALL_STRIP_FLAG=-s \\\n\t    \"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'\" install; \\\n\tfi\nmostlyclean-generic:\n\nclean-generic:\n\t-test -z \"$(CLEANFILES)\" || rm -f $(CLEANFILES)\n\ndistclean-generic:\n\t-test -z \"$(CONFIG_CLEAN_FILES)\" || rm -f $(CONFIG_CLEAN_FILES)\n\t-test . = \"$(srcdir)\" || test -z \"$(CONFIG_CLEAN_VPATH_FILES)\" || rm -f $(CONFIG_CLEAN_VPATH_FILES)\n\nmaintainer-clean-generic:\n\t@echo \"This command is intended for maintainers to use\"\n\t@echo \"it deletes files that may require special tools to rebuild.\"\nclean: clean-am\n\nclean-am: clean-generic clean-libtool mostlyclean-am\n\ndistclean: distclean-am\n\t-rm -f Makefile\ndistclean-am: clean-am distclean-DEJAGNU distclean-generic\n\ndvi: dvi-am\n\ndvi-am:\n\nhtml: html-am\n\nhtml-am:\n\ninfo: info-am\n\ninfo-am:\n\ninstall-data-am:\n\ninstall-dvi: install-dvi-am\n\ninstall-dvi-am:\n\ninstall-exec-am:\n\ninstall-html: install-html-am\n\ninstall-html-am:\n\ninstall-info: install-info-am\n\ninstall-info-am:\n\ninstall-man:\n\ninstall-pdf: install-pdf-am\n\ninstall-pdf-am:\n\ninstall-ps: install-ps-am\n\ninstall-ps-am:\n\ninstallcheck-am:\n\nmaintainer-clean: maintainer-clean-am\n\t-rm -f Makefile\nmaintainer-clean-am: distclean-am maintainer-clean-generic\n\nmostlyclean: mostlyclean-am\n\nmostlyclean-am: mostlyclean-generic mostlyclean-libtool\n\npdf: pdf-am\n\npdf-am:\n\nps: ps-am\n\nps-am:\n\nuninstall-am:\n\n.MAKE: check-am install-am install-strip\n\n.PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \\\n\tclean-libtool distclean distclean-DEJAGNU distclean-generic \\\n\tdistclean-libtool dvi dvi-am html html-am info info-am install \\\n\tinstall-am install-data install-data-am install-dvi \\\n\tinstall-dvi-am install-exec install-exec-am install-html \\\n\tinstall-html-am install-info install-info-am install-man \\\n\tinstall-pdf install-pdf-am install-ps install-ps-am \\\n\tinstall-strip installcheck installcheck-am installdirs \\\n\tmaintainer-clean maintainer-clean-generic mostlyclean \\\n\tmostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \\\n\tuninstall uninstall-am\n\n\n# Tell versions [3.59,3.63) of GNU make to not export all variables.\n# Otherwise a system limit (for SysV at least) may be exceeded.\n.NOEXPORT:\n"
  },
  {
    "path": "libphobos/testsuite/config/default.exp",
    "content": "# Copyright (C) 2017-2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib \"standard.exp\"\n"
  },
  {
    "path": "libphobos/testsuite/lib/libphobos-dg.exp",
    "content": "# Copyright (C) 2017-2018 Free Software Foundation, Inc.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_gcc_lib multiline.exp\nload_gcc_lib prune.exp\nload_gcc_lib scandump.exp\nload_gcc_lib scanltranstree.exp\nload_gcc_lib scanwpaipa.exp\nload_gcc_lib file-format.exp\nload_gcc_lib scanasm.exp\nload_gcc_lib scanlang.exp\nload_gcc_lib scanrtl.exp\nload_gcc_lib scantree.exp\nload_gcc_lib scanipa.exp\nload_gcc_lib torture-options.exp\nload_gcc_lib timeout-dg.exp\nload_gcc_lib fortran-modules.exp\nload_gcc_lib gcc-dg.exp\n\n# Utility routines.\n\n#\n# libphobos_load -- wrapper around default libphobos_load to handle tests that\n# require program arguments passed to them.\n#\n\nif { [info procs libphobos_load] != [list] \\\n      && [info procs prev_libphobos_load] == [list] } {\n    rename libphobos_load prev_libphobos_load\n\n    proc libphobos_load { program args } {\n        global libphobos_run_args\n        if { $libphobos_run_args != \"\" } {\n            set args [concat \"{$libphobos_run_args}\"]\n        }\n        set result [eval [list prev_libphobos_load $program] $args ]\n        return $result\n    }\n}\n"
  },
  {
    "path": "libphobos/testsuite/lib/libphobos.exp",
    "content": "# Copyright (C) 2017-2018 Free Software Foundation, Inc.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\n#\n# DejaGnu does not have proper library search paths for load_lib.\n# We have to explicitly load everything that gdc.exp wants to load.\n#\n\nproc load_gcc_lib { filename } {\n    global srcdir loaded_libs\n\n    load_file $srcdir/../../gcc/testsuite/lib/$filename\n    set loaded_libs($filename) \"\"\n}\n\nload_lib dg.exp\nload_lib libgloss.exp\n\nload_gcc_lib target-supports.exp\nload_gcc_lib target-supports-dg.exp\nload_gcc_lib dg-options.exp\nload_gcc_lib target-libpath.exp\nload_gcc_lib timeout.exp\nload_gcc_lib wrapper.exp\nload_gcc_lib target-utils.exp\nload_gcc_lib gcc-defs.exp\n\nset TESTING_IN_BUILD_TREE 1\n\n# Define libphobos callbacks for dg.exp.\n\nproc libphobos-dg-test { prog do_what extra_tool_flags } {\n    set compile_type \"\"\n    set output_file \"\"\n\n    # Set up the compiler flags, based on what we're going to do.\n    switch $do_what {\n        \"compile\" {\n            set compile_type \"assembly\"\n            set output_file \"[file rootname [file tail $prog]].s\"\n        }\n        \"run\" {\n            set compile_type \"executable\"\n            # FIXME: \"./\" is to cope with \".\" not being in $PATH.\n            # Should this be handled elsewhere?\n            # YES.\n            set output_file \"./[file rootname [file tail $prog]].exe\"\n            # This is the only place where we care if an executable was\n            # created or not.  If it was, dg.exp will try to run it.\n            catch { remote_file build delete $output_file }\n        }\n        \"link\" {\n            set compile_type \"executable\"\n            set output_file \"./[file rootname [file tail $prog]].exe\"\n        }\n        default {\n            perror \"$do_what: not a valid dg-do keyword\"\n            return \"\"\n        }\n    }\n\n    set select_compile \"libphobos_target_compile\"\n    set options \"\"\n    if { $extra_tool_flags != \"\" } {\n        lappend options \"additional_flags=$extra_tool_flags\"\n    }\n\n    set comp_output [$select_compile \"$prog\" \"$output_file\" \"$compile_type\" $options]\n\n    return [list $comp_output $output_file]\n}\n\n#\n# libphobos_init\n#\n\nproc libphobos_init { args } {\n    global env\n    global srcdir blddir objdir tool_root_dir\n    global exeext\n    global gdc gdcflags\n    global gdcpaths gdcldflags\n    global gluefile wrap_flags\n    global ld_library_path\n    global DEFAULT_DFLAGS\n\n    # If a testcase doesn't have special options, use these.\n    if ![info exists DEFAULT_DFLAGS] then {\n        set DEFAULT_DFLAGS \"\"\n    }\n\n    # By default, we assume we want to run program images.\n    global dg-do-what-default\n    if [isnative] {\n        set dg-do-what-default \"run\"\n    } else {\n        set dg-do-what-default \"link\"\n    }\n\n    # What arguments to pass to run program images.\n    global libphobos_run_args\n    set libphobos_run_args \"\"\n\n    # Default settings.\n    set blddir [lookfor_file [get_multilibs] libphobos]\n    set flags_file \"${blddir}/testsuite/testsuite_flags\"\n    set shlib_ext [get_shlib_extension]\n\n    set gdc [transform \"gdc\"]\n    set gdcflags \"-fmessage-length=0\"\n    set gdcpaths \"-I${srcdir}\"\n    set gdcldflags \"\"\n\n    if { [file exists $flags_file] } {\n        set gdc [exec sh $flags_file --gdc]\n        set gdcflags [exec sh $flags_file --gdcflags]\n        set gdcpaths [exec sh $flags_file --gdcpaths]\n        set gdcldflags [exec sh $flags_file --gdcldflags]\n    }\n\n    set exeext \"\"\n    if [info exists env(EXEEXT)] {\n        set exeext $env(EXEEXT)\n    }\n\n    # Compute what needs to be added to the existing LD_LIBRARY_PATH.\n    set ld_library_path \"\"\n\n    set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]\n    if {$gccdir != \"\"} {\n        set gccdir [file dirname $gccdir]\n        append ld_library_path \":${gccdir}\"\n    }\n\n    if { [file exists \"${blddir}/libdruntime/.libs/libgdruntime.${shlib_ext}\"] } {\n        append ld_library_path \":${blddir}/libdruntime/.libs\"\n    }\n\n    if { [file exists \"${blddir}/src/.libs/libgphobos.${shlib_ext}\"] } {\n        append ld_library_path \":${blddir}/src/.libs\"\n    }\n\n    set_ld_library_path_env_vars\n\n    libphobos_maybe_build_wrapper \"${objdir}/testglue.o\"\n}\n\n#\n# libphobos_target_compile -- compile a source file.\n#\n\nproc libphobos_target_compile { source dest type options } {\n    global gdc gdcflags\n    global gdcpaths gdcldflags\n    global gluefile wrap_flags\n\n    lappend options \"additional_flags=-fno-diagnostics-show-caret -fdiagnostics-color=never\"\n\n    if { [target_info needs_status_wrapper] != \"\" && [info exists gluefile] } {\n        lappend options \"libs=${gluefile}\"\n        lappend options \"ldflags=${wrap_flags}\"\n    }\n\n    # Flag setting based on type argument.\n    if { $type == \"executable\" } {\n        # Link the support objects into executables.\n        lappend options \"additional_flags=$gdcldflags\"\n    }\n\n    # Set the compiler, only add D flags and paths if building D sources.\n    set gdc_final $gdc\n    if [regexp \".*\\.d\\$\" $source] {\n        set gdc_final [concat $gdc_final $gdcflags]\n        set gdc_final [concat $gdc_final $gdcpaths]\n    }\n\n    lappend options \"compiler=$gdc_final\"\n    lappend options \"timeout=[timeout_value]\"\n\n    set options [dg-additional-files-options $options $source]\n    set comp_output [target_compile $source $dest $type $options]\n\n    return $comp_output\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.aa/aa.exp",
    "content": "# Copyright (C) 2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib libphobos-dg.exp\n\n# Initialize dg.\ndg-init\n\n# Gather a list of all tests.\nset tests [lsort [find $srcdir/$subdir *.d]]\n\n# Main loop.\ndg-runtest $tests \"\" $DEFAULT_DFLAGS\n\n# All done.\ndg-finish\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.aa/test_aa.d",
    "content": "void main()\n{\n    testKeysValues1();\n    testKeysValues2();\n    testGet1();\n    testGet2();\n    testRequire1();\n    testRequire2();\n    testRequire3();\n    testUpdate1();\n    testUpdate2();\n    testByKey1();\n    testByKey2();\n    testByKey3();\n    testByKey4();\n    issue5842();\n    issue5842Expanded();\n    issue5925();\n    issue8583();\n    issue9052();\n    issue9119();\n    issue9852();\n    issue10381();\n    issue10720();\n    issue11761();\n    issue13078();\n    issue14104();\n    issue14626();\n    issue15290();\n    issue15367();\n    issue16974();\n    issue18071();\n    testIterationWithConst();\n    testStructArrayKey();\n    miscTests1();\n    miscTests2();\n    testRemove();\n    testZeroSizedValue();\n    testTombstonePurging();\n    testClear();\n}\n\nvoid testKeysValues1()\n{\n    static struct T\n    {\n        byte b;\n        static size_t count;\n        this(this) { ++count; }\n    }\n    T[int] aa;\n    T t;\n    aa[0] = t;\n    aa[1] = t;\n    assert(T.count == 2);\n    auto vals = aa.values;\n    assert(vals.length == 2);\n    assert(T.count == 4);\n\n    T.count = 0;\n    int[T] aa2;\n    aa2[t] = 0;\n    assert(T.count == 1);\n    aa2[t] = 1;\n    assert(T.count == 1);\n    auto keys = aa2.keys;\n    assert(keys.length == 1);\n    assert(T.count == 2);\n}\n\nvoid testKeysValues2() nothrow pure\n{\n    int[string] aa;\n\n    assert(aa.keys.length == 0);\n    assert(aa.values.length == 0);\n\n    aa[\"hello\"] = 3;\n    assert(aa[\"hello\"] == 3);\n    aa[\"hello\"]++;\n    assert(aa[\"hello\"] == 4);\n\n    assert(aa.length == 1);\n\n    string[] keys = aa.keys;\n    assert(keys.length == 1);\n    assert(keys[0] == \"hello\");\n\n    int[] values = aa.values;\n    assert(values.length == 1);\n    assert(values[0] == 4);\n\n    aa.rehash;\n    assert(aa.length == 1);\n    assert(aa[\"hello\"] == 4);\n\n    aa[\"foo\"] = 1;\n    aa[\"bar\"] = 2;\n    aa[\"batz\"] = 3;\n\n    assert(aa.keys.length == 4);\n    assert(aa.values.length == 4);\n\n    foreach (a; aa.keys)\n    {\n        assert(a.length != 0);\n        assert(a.ptr != null);\n    }\n\n    foreach (v; aa.values)\n    {\n        assert(v != 0);\n    }\n}\n\nvoid testGet1() @safe\n{\n    int[string] aa;\n    int a;\n    foreach (val; aa.byKeyValue)\n    {\n        ++aa[val.key];\n        a = val.value;\n    }\n}\n\nvoid testGet2()\n{\n    static class T\n    {\n        static size_t count;\n        this() { ++count; }\n    }\n\n    T[string] aa;\n\n    auto a = new T;\n    aa[\"foo\"] = a;\n    assert(T.count == 1);\n    auto b = aa.get(\"foo\", new T);\n    assert(T.count == 1);\n    assert(b is a);\n    auto c = aa.get(\"bar\", new T);\n    assert(T.count == 2);\n    assert(c !is a);\n\n    //Obviously get doesn't add.\n    assert(\"bar\" !in aa);\n}\n\nvoid testRequire1()\n{\n    static class T\n    {\n        static size_t count;\n        this() { ++count; }\n    }\n\n    T[string] aa;\n\n    auto a = new T;\n    aa[\"foo\"] = a;\n    assert(T.count == 1);\n    auto b = aa.require(\"foo\", new T);\n    assert(T.count == 1);\n    assert(b is a);\n    auto c = aa.require(\"bar\", null);\n    assert(T.count == 1);\n    assert(c is null);\n    assert(\"bar\" in aa);\n    auto d = aa.require(\"bar\", new T);\n    assert(d is null);\n    auto e = aa.require(\"baz\", new T);\n    assert(T.count == 2);\n    assert(e !is a);\n\n    assert(\"baz\" in aa);\n\n    bool created = false;\n    auto f = aa.require(\"qux\", { created = true; return new T; }());\n    assert(created == true);\n\n    T g;\n    auto h = aa.require(\"qux\", { g = new T; return g; }());\n    assert(g !is h);\n}\n\nvoid testRequire2()\n{\n    static struct S\n    {\n        int value;\n    }\n\n    S[string] aa;\n\n    aa.require(\"foo\").value = 1;\n    assert(aa == [\"foo\" : S(1)]);\n\n    aa[\"bar\"] = S(2);\n    auto a = aa.require(\"bar\", S(3));\n    assert(a == S(2));\n\n    auto b = aa[\"bar\"];\n    assert(b == S(2));\n\n    S* c = &aa.require(\"baz\", S(4));\n    assert(c is &aa[\"baz\"]);\n    assert(*c == S(4));\n\n    assert(\"baz\" in aa);\n\n    auto d = aa[\"baz\"];\n    assert(d == S(4));\n}\n\nvoid testRequire3() pure\n{\n    string[string] aa;\n\n    auto a = aa.require(\"foo\", \"bar\");\n    assert(\"foo\" in aa);\n}\n\n\nvoid testUpdate1()\n{\n    static class C {}\n    C[string] aa;\n\n    C orig = new C;\n    aa[\"foo\"] = orig;\n\n    C newer;\n    C older;\n\n    void test(string key)\n    {\n        aa.update(key, {\n            newer = new C;\n            return newer;\n        }, (ref C c) {\n            older = c;\n            newer = new C;\n            return newer;\n        });\n    }\n\n    test(\"foo\");\n    assert(older is orig);\n    assert(newer is aa[\"foo\"]);\n\n    test(\"bar\");\n    assert(newer is aa[\"bar\"]);\n}\n\nvoid testUpdate2()\n{\n    static class C {}\n    C[string] aa;\n\n    auto created = false;\n    auto updated = false;\n\n    class Creator\n    {\n        C opCall()\n        {\n            created = true;\n            return new C();\n        }\n    }\n\n    class Updater\n    {\n        C opCall(ref C)\n        {\n            updated = true;\n            return new C();\n        }\n    }\n\n    aa.update(\"foo\", new Creator, new Updater);\n    assert(created);\n    aa.update(\"foo\", new Creator, new Updater);\n    assert(updated);\n}\n\nvoid testByKey1()\n{\n    static assert(!__traits(compiles,\n        () @safe {\n            struct BadValue\n            {\n                int x;\n                this(this) @safe { *(cast(ubyte*)(null) + 100000) = 5; } // not @safe\n                alias x this;\n            }\n\n            BadValue[int] aa;\n            () @safe { auto x = aa.byKey.front; } ();\n        }\n    ));\n}\n\nvoid testByKey2() nothrow pure\n{\n    int[int] a;\n    foreach (i; a.byKey)\n    {\n        assert(false);\n    }\n    foreach (i; a.byValue)\n    {\n        assert(false);\n    }\n}\n\nvoid testByKey3() /*nothrow*/ pure\n{\n    auto a = [ 1:\"one\", 2:\"two\", 3:\"three\" ];\n    auto b = a.dup;\n    assert(b == [ 1:\"one\", 2:\"two\", 3:\"three\" ]);\n\n    int[] c;\n    foreach (k; a.byKey)\n    {\n        c ~= k;\n    }\n\n    assert(c.length == 3);\n    assert(c[0] == 1 || c[1] == 1 || c[2] == 1);\n    assert(c[0] == 2 || c[1] == 2 || c[2] == 2);\n    assert(c[0] == 3 || c[1] == 3 || c[2] == 3);\n}\n\nvoid testByKey4() nothrow pure\n{\n    string[] keys = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"];\n\n    // Test forward range capabilities of byKey\n    {\n        int[string] aa;\n        foreach (key; keys)\n            aa[key] = 0;\n\n        auto keyRange = aa.byKey();\n        auto savedKeyRange = keyRange.save;\n\n        // Consume key range once\n        size_t keyCount = 0;\n        while (!keyRange.empty)\n        {\n            aa[keyRange.front]++;\n            keyCount++;\n            keyRange.popFront();\n        }\n\n        foreach (key; keys)\n        {\n            assert(aa[key] == 1);\n        }\n        assert(keyCount == keys.length);\n\n        // Verify it's possible to iterate the range the second time\n        keyCount = 0;\n        while (!savedKeyRange.empty)\n        {\n            aa[savedKeyRange.front]++;\n            keyCount++;\n            savedKeyRange.popFront();\n        }\n\n        foreach (key; keys)\n        {\n            assert(aa[key] == 2);\n        }\n        assert(keyCount == keys.length);\n    }\n\n    // Test forward range capabilities of byValue\n    {\n        size_t[string] aa;\n        foreach (i; 0 .. keys.length)\n        {\n            aa[keys[i]] = i;\n        }\n\n        auto valRange = aa.byValue();\n        auto savedValRange = valRange.save;\n\n        // Consume value range once\n        int[] hasSeen;\n        hasSeen.length = keys.length;\n        while (!valRange.empty)\n        {\n            assert(hasSeen[valRange.front] == 0);\n            hasSeen[valRange.front]++;\n            valRange.popFront();\n        }\n\n        foreach (sawValue; hasSeen) { assert(sawValue == 1); }\n\n        // Verify it's possible to iterate the range the second time\n        hasSeen = null;\n        hasSeen.length = keys.length;\n        while (!savedValRange.empty)\n        {\n            assert(!hasSeen[savedValRange.front]);\n            hasSeen[savedValRange.front] = true;\n            savedValRange.popFront();\n        }\n\n        foreach (sawValue; hasSeen) { assert(sawValue); }\n    }\n}\n\nvoid issue5842() pure nothrow\n{\n    string[string] test = null;\n    test[\"test1\"] = \"test1\";\n    test.remove(\"test1\");\n    test.rehash;\n    test[\"test3\"] = \"test3\"; // causes divide by zero if rehash broke the AA\n}\n\n/// expanded test for 5842: increase AA size past the point where the AA\n/// stops using binit, in order to test another code path in rehash.\nvoid issue5842Expanded() pure nothrow\n{\n    int[int] aa;\n    foreach (int i; 0 .. 32)\n        aa[i] = i;\n    foreach (int i; 0 .. 32)\n        aa.remove(i);\n    aa.rehash;\n    aa[1] = 1;\n}\n\nvoid issue5925() nothrow pure\n{\n    const a = [4:0];\n    const b = [4:0];\n    assert(a == b);\n}\n\n/// test for bug 8583: ensure Slot and aaA are on the same page wrt value alignment\nvoid issue8583() nothrow pure\n{\n    string[byte]    aa0 = [0: \"zero\"];\n    string[uint[3]] aa1 = [[1,2,3]: \"onetwothree\"];\n    ushort[uint[3]] aa2 = [[9,8,7]: 987];\n    ushort[uint[4]] aa3 = [[1,2,3,4]: 1234];\n    string[uint[5]] aa4 = [[1,2,3,4,5]: \"onetwothreefourfive\"];\n\n    assert(aa0.byValue.front == \"zero\");\n    assert(aa1.byValue.front == \"onetwothree\");\n    assert(aa2.byValue.front == 987);\n    assert(aa3.byValue.front == 1234);\n    assert(aa4.byValue.front == \"onetwothreefourfive\");\n}\n\nvoid issue9052() nothrow pure\n{\n    static struct Json {\n        Json[string] aa;\n        void opAssign(Json) {}\n        size_t length() const { return aa.length; }\n        // This length() instantiates AssociativeArray!(string, const(Json)) to call AA.length(), and\n        // inside ref Slot opAssign(Slot p); (which is automatically generated by compiler in Slot),\n        // this.value = p.value would actually fail, because both side types of the assignment\n        // are const(Json).\n    }\n}\n\nvoid issue9119()\n{\n    int[string] aa;\n    assert(aa.byKeyValue.empty);\n\n    aa[\"a\"] = 1;\n    aa[\"b\"] = 2;\n    aa[\"c\"] = 3;\n\n    auto pairs = aa.byKeyValue;\n\n    auto savedPairs = pairs.save;\n    size_t count = 0;\n    while (!pairs.empty)\n    {\n        assert(pairs.front.key in aa);\n        assert(pairs.front.value == aa[pairs.front.key]);\n        count++;\n        pairs.popFront();\n    }\n    assert(count == aa.length);\n\n    // Verify that saved range can iterate over the AA again\n    count = 0;\n    while (!savedPairs.empty)\n    {\n        assert(savedPairs.front.key in aa);\n        assert(savedPairs.front.value == aa[savedPairs.front.key]);\n        count++;\n        savedPairs.popFront();\n    }\n    assert(count == aa.length);\n}\n\nvoid issue9852() nothrow pure\n{\n    // Original test case (revised, original assert was wrong)\n    int[string] a;\n    a[\"foo\"] = 0;\n    a.remove(\"foo\");\n    assert(a == null); // should not crash\n\n    int[string] b;\n    assert(b is null);\n    assert(a == b); // should not deref null\n    assert(b == a); // ditto\n\n    int[string] c;\n    c[\"a\"] = 1;\n    assert(a != c); // comparison with empty non-null AA\n    assert(c != a);\n    assert(b != c); // comparison with null AA\n    assert(c != b);\n}\n\nvoid issue10381()\n{\n    alias II = int[int];\n    II aa1 = [0 : 1];\n    II aa2 = [0 : 1];\n    II aa3 = [0 : 2];\n    assert(aa1 == aa2); // Passes\n    assert(typeid(II).equals(&aa1, &aa2));\n    assert(!typeid(II).equals(&aa1, &aa3));\n}\n\nvoid issue10720() nothrow pure\n{\n    static struct NC\n    {\n        @disable this(this) { }\n    }\n\n    NC[string] aa;\n    static assert(!is(aa.nonExistingField));\n}\n\n/// bug 11761: test forward range functionality\nvoid issue11761() pure nothrow\n{\n    auto aa = [\"a\": 1];\n\n    void testFwdRange(R, T)(R fwdRange, T testValue)\n    {\n        assert(!fwdRange.empty);\n        assert(fwdRange.front == testValue);\n        static assert(is(typeof(fwdRange.save) == typeof(fwdRange)));\n\n        auto saved = fwdRange.save;\n        fwdRange.popFront();\n        assert(fwdRange.empty);\n\n        assert(!saved.empty);\n        assert(saved.front == testValue);\n        saved.popFront();\n        assert(saved.empty);\n    }\n\n    testFwdRange(aa.byKey, \"a\");\n    testFwdRange(aa.byValue, 1);\n    //testFwdRange(aa.byPair, tuple(\"a\", 1));\n}\n\nvoid issue13078() nothrow pure\n{\n    shared string[][string] map;\n    map.rehash;\n}\n\nvoid issue14104()\n{\n    import core.stdc.stdio;\n\n    alias K = const(ubyte)*;\n    size_t[K] aa;\n    immutable key = cast(K)(cast(size_t) uint.max + 1);\n    aa[key] = 12;\n    assert(key in aa);\n}\n\nvoid issue14626()\n{\n    static struct S\n    {\n        string[string] aa;\n        inout(string) key() inout { return aa.byKey().front; }\n        inout(string) val() inout { return aa.byValue().front; }\n        auto keyval() inout { return aa.byKeyValue().front; }\n    }\n\n    S s = S([\"a\":\"b\"]);\n    assert(s.key() == \"a\");\n    assert(s.val() == \"b\");\n    assert(s.keyval().key == \"a\");\n    assert(s.keyval().value == \"b\");\n\n    void testInoutKeyVal(inout(string) key)\n    {\n        inout(string)[typeof(key)] aa;\n\n        foreach (i; aa.byKey()) {}\n        foreach (i; aa.byValue()) {}\n        foreach (i; aa.byKeyValue()) {}\n    }\n\n    const int[int] caa;\n    static assert(is(typeof(caa.byValue().front) == const int));\n}\n\n/// test duplicated keys in AA literal\n/// https://issues.dlang.org/show_bug.cgi?id=15290\nvoid issue15290()\n{\n    string[int] aa = [ 0: \"a\", 0: \"b\" ];\n    assert(aa.length == 1);\n    assert(aa.keys == [ 0 ]);\n}\n\nvoid issue15367()\n{\n    void f1() {}\n    void f2() {}\n\n    // TypeInfo_Delegate.getHash\n    int[void delegate()] aa;\n    assert(aa.length == 0);\n    aa[&f1] = 1;\n    assert(aa.length == 1);\n    aa[&f1] = 1;\n    assert(aa.length == 1);\n\n    auto a1 = [&f2, &f1];\n    auto a2 = [&f2, &f1];\n\n    // TypeInfo_Delegate.equals\n    for (auto i = 0; i < 2; i++)\n        assert(a1[i] == a2[i]);\n    assert(a1 == a2);\n\n    // TypeInfo_Delegate.compare\n    for (auto i = 0; i < 2; i++)\n        assert(a1[i] <= a2[i]);\n    assert(a1 <= a2);\n}\n\n/// test AA as key\n/// https://issues.dlang.org/show_bug.cgi?id=16974\nvoid issue16974()\n{\n    int[int] a = [1 : 2], a2 = [1 : 2];\n\n    assert([a : 3] == [a : 3]);\n    assert([a : 3] == [a2 : 3]);\n\n    assert(typeid(a).getHash(&a) == typeid(a).getHash(&a));\n    assert(typeid(a).getHash(&a) == typeid(a).getHash(&a2));\n}\n\n/// test safety for alias-this'd AA that have unsafe opCast\n/// https://issues.dlang.org/show_bug.cgi?id=18071\nvoid issue18071()\n{\n    static struct Foo\n    {\n        int[int] aa;\n        auto opCast() pure nothrow @nogc\n        {\n            *cast(uint*)0xdeadbeef = 0xcafebabe;// unsafe\n            return null;\n        }\n        alias aa this;\n    }\n\n    Foo f;\n    () @safe { assert(f.byKey.empty); }();\n}\n\n/// Verify iteration with const.\nvoid testIterationWithConst()\n{\n    auto aa = [1:2, 3:4];\n    foreach (const t; aa.byKeyValue)\n    {\n        auto k = t.key;\n        auto v = t.value;\n    }\n}\n\nvoid testStructArrayKey() @safe\n{\n    struct S\n    {\n        int i;\n    const @safe nothrow:\n        hash_t toHash() { return 0; }\n        bool opEquals(const S) { return true; }\n        int opCmp(const S) { return 0; }\n    }\n\n    int[S[]] aa = [[S(11)] : 13];\n    assert(aa[[S(12)]] == 13);\n}\n\nvoid miscTests1() pure nothrow\n{\n    string[int] key1 = [1 : \"true\", 2 : \"false\"];\n    string[int] key2 = [1 : \"false\", 2 : \"true\"];\n    string[int] key3;\n\n    // AA lits create a larger hashtable\n    int[string[int]] aa1 = [key1 : 100, key2 : 200, key3 : 300];\n\n    // Ensure consistent hash values are computed for key1\n    assert((key1 in aa1) !is null);\n\n    // Manually assigning to an empty AA creates a smaller hashtable\n    int[string[int]] aa2;\n    aa2[key1] = 100;\n    aa2[key2] = 200;\n    aa2[key3] = 300;\n\n    assert(aa1 == aa2);\n\n    // Ensure binary-independence of equal hash keys\n    string[int] key2a;\n    key2a[1] = \"false\";\n    key2a[2] = \"true\";\n\n    assert(aa1[key2a] == 200);\n}\n\nvoid miscTests2()\n{\n    int[int] aa;\n    foreach (k, v; aa)\n        assert(false);\n    foreach (v; aa)\n        assert(false);\n    assert(aa.byKey.empty);\n    assert(aa.byValue.empty);\n    assert(aa.byKeyValue.empty);\n\n    size_t n;\n    aa = [0 : 3, 1 : 4, 2 : 5];\n    foreach (k, v; aa)\n    {\n        n += k;\n        assert(k >= 0 && k < 3);\n        assert(v >= 3 && v < 6);\n    }\n    assert(n == 3);\n    n = 0;\n\n    foreach (v; aa)\n    {\n        n += v;\n        assert(v >= 3 && v < 6);\n    }\n    assert(n == 12);\n\n    n = 0;\n    foreach (k, v; aa)\n    {\n        ++n;\n        break;\n    }\n    assert(n == 1);\n\n    n = 0;\n    foreach (v; aa)\n    {\n        ++n;\n        break;\n    }\n    assert(n == 1);\n}\n\nvoid testRemove()\n{\n    int[int] aa;\n    assert(!aa.remove(0));\n    aa = [0 : 1];\n    assert(aa.remove(0));\n    assert(!aa.remove(0));\n    aa[1] = 2;\n    assert(!aa.remove(0));\n    assert(aa.remove(1));\n\n    assert(aa.length == 0);\n    assert(aa.byKey.empty);\n}\n\n/// test zero sized value (hashset)\nvoid testZeroSizedValue()\n{\n    alias V = void[0];\n    auto aa = [0 : V.init];\n    assert(aa.length == 1);\n    assert(aa.byKey.front == 0);\n    assert(aa.byValue.front == V.init);\n    aa[1] = V.init;\n    assert(aa.length == 2);\n    aa[0] = V.init;\n    assert(aa.length == 2);\n    assert(aa.remove(0));\n    aa[0] = V.init;\n    assert(aa.length == 2);\n    assert(aa == [0 : V.init, 1 : V.init]);\n}\n\nvoid testTombstonePurging()\n{\n    int[int] aa;\n    foreach (i; 0 .. 6)\n        aa[i] = i;\n    foreach (i; 0 .. 6)\n        assert(aa.remove(i));\n    foreach (i; 6 .. 10)\n        aa[i] = i;\n    assert(aa.length == 4);\n    foreach (i; 6 .. 10)\n        assert(i in aa);\n}\n\nvoid testClear()\n{\n    int[int] aa;\n    assert(aa.length == 0);\n    foreach (i; 0 .. 100)\n        aa[i] = i * 2;\n    assert(aa.length == 100);\n    auto aa2 = aa;\n    assert(aa2.length == 100);\n    aa.clear();\n    assert(aa.length == 0);\n    assert(aa2.length == 0);\n\n    aa2[5] = 6;\n    assert(aa.length == 1);\n    assert(aa[5] == 6);\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.allocations/allocations.exp",
    "content": "# Copyright (C) 2017-2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib libphobos-dg.exp\n\n# Initialize dg.\ndg-init\n\n# Gather a list of all tests.\nset tests [lsort [find $srcdir/$subdir *.d]]\n\n# Main loop.\ndg-runtest $tests \"\" $DEFAULT_DFLAGS\n\n# All done.\ndg-finish\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.allocations/overflow_from_existing.d",
    "content": "// { dg-shouldfail \"Memory allocation failed\" }\n// { dg-output \"core.exception.OutOfMemoryError@.*: Memory allocation failed\" }\nvoid main()\n{\n    void[] buffer;\n    buffer.length = 1;\n    buffer.length = size_t.max;\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.allocations/overflow_from_zero.d",
    "content": "// { dg-shouldfail \"Memory allocation failed\" }\n// { dg-output \"core.exception.OutOfMemoryError@.*: Memory allocation failed\" }\nvoid main()\n{\n    void[] buffer;\n    buffer.length = 0;\n    buffer.length = size_t.max;\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.cycles/cycles.exp",
    "content": "# Copyright (C) 2017-2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib libphobos-dg.exp\n\nset dg-output-text [list]\n\n# Arguments to pass to the test program, expected output, and return code.\nset cycle_test_list [list \\\n    { ignore \"\"  0 } \\\n    { abort \"object.Error@.*: Cyclic dependency between module mod. and mod.\" 1 } \\\n    { print \"Cyclic dependency between module mod. and mod.\" 0 } \\\n    { deprecate \"Deprecation 16211 warning:\" 0 } \\\n]\n\n# Initialize dg.\ndg-init\n\n# Gather a list of all tests.\nset tests [lsort [find $srcdir/$subdir *.d]]\n\n# Main loop.\nforeach cycle_test $cycle_test_list {\n    # The set the argument to pass to the program.\n    set libphobos_run_args \"--DRT-oncycle=[lindex $cycle_test 0]\"\n\n    # Whether the program is expected to fail.\n    set expected_fail [lindex $cycle_test 2]\n\n    foreach test $tests {\n        set shouldfail $expected_fail\n        dg-test $test \"\" $DEFAULT_DFLAGS\n    }\n\n    set shouldfail 0\n    set libphobos_run_args \"\"\n}\n\n# All done.\ndg-finish\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.cycles/mod1.d",
    "content": "// { dg-additional-sources \"mod2.d mod3.d\" }\nmodule mod1;\nimport mod2;\n\nshared int x;\nshared static this()\n{\n    x = 1;\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.cycles/mod2.d",
    "content": "// { dg-additional-sources \"mod1.d mod3.d\" }\nmodule mod2;\nimport mod1;\nimport mod3;\n\nvoid main()\n{\n    // do nothing\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.cycles/mod3.d",
    "content": "// { dg-additional-sources \"mod1.d mod2.d\" }\nmodule mod3;\nimport mod2;\n\nshared int x;\nshared static this()\n{\n    x = 3;\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.exceptions/chain.d",
    "content": "// Author: Ali Çehreli\n// See https://forum.dlang.org/post/o2n7f8$2p1t$1@digitalmars.com\n\nimport core.stdc.stdio;\n\nclass TestException : Exception\n{\n    this(string msg)\n    {\n        super(typeof(this).stringof~\": \"~msg);\n    }\n}\n\nclass TestError : Error\n{\n    this(string msg)\n    {\n        super(typeof(this).stringof~\": \"~msg);\n    }\n}\n\n// Causes an exception chain where the node at index errorIndex is an\n// Error (others are all Exceptions).\nvoid causeExceptionChain(size_t chainLength, size_t errorIndex)\n{\n    void throws(size_t n)\n    {\n        scope (exit)\n        {\n            string msg = [ cast(char)('a'+n) ].idup;\n            if (n == errorIndex)\n            {\n                throw new TestError(msg);\n            }\n            else\n            {\n                throw new TestException(msg);\n            }\n        }\n\n        if (n != 0)\n        {\n            // Redundant 'return' keyword due to\n            // https://issues.dlang.org/show_bug.cgi?id=16960\n            return throws(n - 1);\n        }\n    }\n\n    throws(chainLength - 1);\n}\n\nvoid main()\n{\n    try\n    {\n        // -1 would mean \"no Error in the chain\". Change this to a\n        // number between 0 and 4 (inclusive) then you will realize\n        // that the Exception below will not be caught.\n        size_t errorIndex = 3;\n        causeExceptionChain(5, errorIndex);\n    }\n    catch (Error original)\n    {\n        printf(\"Caught\\n\");\n        string prefix = \"\";\n        for ({ size_t i; Throwable ex = original; } ex; ex = ex.next, ++i)\n        {\n            printf(\"%.*s%.*s\\n\", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr);\n            prefix = prefix~\" \";\n        }\n        printf(\"Bypassed chain was:\\n\");\n        prefix = \"\";\n        for ({ size_t i; Throwable ex = original.bypassedException; } ex; ex = ex.next, ++i)\n        {\n            printf(\"%.*s%.*s\\n\", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr);\n            prefix = prefix~\" \";\n        }\n    }\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.exceptions/exceptions.exp",
    "content": "# Copyright (C) 2017-2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib libphobos-dg.exp\n\n# Initialize dg.\ndg-init\n\n# Gather a list of all tests.\nset tests [lsort [find $srcdir/$subdir *.d]]\n\n# Main loop.\ndg-runtest $tests \"\" $DEFAULT_DFLAGS\n\n# All done.\ndg-finish\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.exceptions/future_message.d",
    "content": "import core.stdc.stdio;\n\n// Make sure basic stuff works with future Throwable.message\nclass NoMessage : Throwable\n{\n    @nogc @safe pure nothrow this(string msg, Throwable next = null)\n    {\n        super(msg, next);\n    }\n}\n\nclass WithMessage : Throwable\n{\n    @nogc @safe pure nothrow this(string msg, Throwable next = null)\n    {\n        super(msg, next);\n    }\n\n    override const(char)[] message() const\n    {\n        return \"I have a custom message.\";\n    }\n}\n\nclass WithMessageNoOverride : Throwable\n{\n    @nogc @safe pure nothrow this(string msg, Throwable next = null)\n    {\n        super(msg, next);\n    }\n\n    const(char)[] message() const\n    {\n        return \"I have a custom message and no override.\";\n    }\n}\n\nclass WithMessageNoOverrideAndDifferentSignature : Throwable\n{\n    @nogc @safe pure nothrow this(string msg, Throwable next = null)\n    {\n        super(msg, next);\n    }\n\n    immutable(char)[] message()\n    {\n        return \"I have a custom message and I'm nothing like Throwable.message.\";\n    }\n}\n\nvoid test(Throwable t)\n{\n    try\n    {\n        throw t;\n    }\n    catch (Throwable e)\n    {\n        fprintf(stderr, \"%.*s \", e.message.length, e.message.ptr);\n    }\n}\n\nvoid main()\n{\n     test(new NoMessage(\"exception\"));\n     test(new WithMessage(\"exception\"));\n     test(new WithMessageNoOverride(\"exception\"));\n     test(new WithMessageNoOverrideAndDifferentSignature(\"exception\"));\n     fprintf(stderr, \"\\n\");\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.exceptions/invalid_memory_operation.d",
    "content": "// { dg-shouldfail \"Invalid memory operation\" }\n// { dg-output \"core.exception.InvalidMemoryOperationError@.*: Invalid memory operation\" }\nstruct S\n{\n    ~this()\n    {\n        new int;\n    }\n}\n\nvoid main()\n{\n    new S;\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.exceptions/line_trace.d",
    "content": "// { dg-output \"object.Exception@.*: exception\" }\nvoid main()\n{\n    try\n    {\n        f1();\n    }\n    catch (Exception e)\n    {\n        import core.stdc.stdio;\n        auto str = e.toString();\n        printf(\"%.*s\\n\", str.length, str.ptr);\n    }\n}\n\nvoid f1()\n{\n    throw new Exception(\"exception\");\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.exceptions/rt_trap_exceptions.d",
    "content": "// { dg-shouldfail \"uncaught exception\" }\n// { dg-output \"gcc.deh.*: uncaught exception\" }\n// Code adapted from\n// http://arsdnet.net/this-week-in-d/2016-aug-07.html\nextern extern(C) __gshared bool rt_trapExceptions;\nextern extern(C) int _d_run_main(int, char**, void*);\n\nextern(C) int main(int argc, char** argv) {\n    rt_trapExceptions = false;\n    return _d_run_main(argc, argv, &_main);\n}\n\nint _main() {\n    throw new Exception(\"this will abort\");\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.exceptions/static_dtor.d",
    "content": "// { dg-shouldfail \"static_dtor_exception\" }\n// { dg-output \"object.Exception@.*: static_dtor_exception\" }\n// https://issues.dlang.org/show_bug.cgi?id=16594\nimport core.stdc.stdio;\n\nshared static ~this()\n{\n    __gshared int count;\n\n    if (count++) fprintf(stderr, \"dtor_called_more_than_once\");\n    else throw new Exception(\"static_dtor_exception\");\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.exceptions/stderr_msg.d",
    "content": "// { dg-shouldfail \"stderr_msg msg\" }\n// { dg-output \"object.Exception@.*: stderr_msg msg\" }\nvoid main()\n{\n    throw new Exception(\"stderr_msg msg\");\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.exceptions/unittest_assert.d",
    "content": "// { dg-options \"-funittest\" }\n// { dg-shouldfail \"unittest_assert msg\" }\n// { dg-output \"core.exception.AssertError@.*: unittest_assert msg\" }\nunittest\n{\n    assert(0, \"unittest_assert msg\");\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.exceptions/unknown_gc.d",
    "content": "// { dg-require-effective-target shared }\n// { dg-options \"-shared-libphobos\" }\n// { dg-shouldfail \"unknowngc\" }\n// { dg-output \"No GC was initialized, please recheck the name of the selected GC \\\\('unknowngc'\\\\).\" }\nimport core.memory;\n\nextern(C) __gshared string[] rt_options = [ \"gcopt=gc:unknowngc\" ];\n\nvoid main()\n{\n    // GC initialized upon first call -> Unknown GC error is thrown\n    GC.enable();\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.hash/hash.exp",
    "content": "# Copyright (C) 2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib libphobos-dg.exp\n\n# Initialize dg.\ndg-init\n\n# Gather a list of all tests.\nset tests [lsort [find $srcdir/$subdir *.d]]\n\n# Main loop.\ndg-runtest $tests \"\" $DEFAULT_DFLAGS\n\n# All done.\ndg-finish\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.hash/test_hash.d",
    "content": "void main()\n{\n    hashOfVoidPtrArray();\n    issue15111();\n    issues16654And16764();\n    issue18918();\n    issue18925();\n    issue19005();\n    issue19204();\n    issue19262();\n    issue19282();\n    testTypeInfoArrayGetHash1();\n    testTypeInfoArrayGetHash2();\n    pr2243();\n}\n\n/// Check that `hashOf` can be called on an array of void pointers.\nvoid hashOfVoidPtrArray() @nogc nothrow pure @system\n{\n    void*[] val;\n    const _ = hashOf(val); // Check a PR doesn't break this.\n}\n\n/// hashOf was failing for structs that had an `alias this` to a dynamic array.\nvoid issue15111()\n{\n    void testAlias(T)()\n    {\n        static struct Foo\n        {\n            T t;\n            alias t this;\n        }\n        Foo foo;\n        static assert(is(typeof(hashOf(foo))));\n    }\n    // was fixed\n    testAlias!(int[]);\n    testAlias!(int*);\n    // was not affected\n    testAlias!int;\n    testAlias!(void delegate());\n    testAlias!(string[string]);\n    testAlias!(int[8]);\n}\n\nvoid issues16654And16764()\n{\n    auto a = [1];\n    auto b = a.dup;\n    assert(hashOf(a) == hashOf(b));\n}\n\n/// Check hashOf dynamic array of scalars is usable in @safe code.\nvoid issue18918() nothrow pure @safe\n{\n    const _ = (() @nogc => hashOf(\"abc\"))();\n\n    static struct S { string array; }\n    auto s1 = S(\"abc\");\n    auto s2 = S(s1.array.idup);\n    assert(hashOf(s1) == hashOf(s2));\n    enum e = hashOf(S(\"abc\"));\n    assert(hashOf(s1) == e);\n}\n\n/// Check hashOf struct of scalar fields is usable in @safe code.\nvoid issue18925() @nogc nothrow pure @safe\n{\n\n    static struct S { int a; int b; }\n    auto h = hashOf(S.init);\n}\n\nvoid issue19005() @nogc nothrow pure @safe\n{\n    enum Month : ubyte\n    {\n        jan = 1\n    }\n    static struct Date\n    {\n        short _year;\n        Month _month;\n        ubyte _day;\n    }\n    Date date;\n    auto hash = date.hashOf;\n}\n\n/// Accept SIMD vectors.\nvoid issue19204() @nogc nothrow pure @safe\n{\n    version (D_SIMD)\n    {\n        static import simd = core.simd;\n        static if (is(simd.int4)) // __traits(isArithmetic)\n        {{\n            enum simd.int4 val = [1,2,3,4];\n            enum ctfeHash = hashOf(val);\n            simd.int4 rtVal = val;\n            auto rtHash = hashOf(rtVal);\n            assert(ctfeHash == rtHash);\n        }}\n        static if (is(simd.void16)) // non __traits(isArithmetic)\n        {{\n            auto h = hashOf(simd.void16.init);\n        }}\n        static if (is(simd.float4)) // __traits(isArithmetic) and __traits(isFloating)\n        {{\n            enum simd.float4 val = [1.1f, 2.2f, 3.3f, 4.4f];\n            enum ctfeHash = hashOf(val);\n            simd.float4 rtVal = val;\n            auto rtHash = hashOf(rtVal);\n            assert(ctfeHash == rtHash);\n        }}\n    }\n}\n\n/// hashOf associative array should infer nothrow\nvoid issue19262() nothrow\n{\n    int[int] aa;\n    auto h = hashOf(aa);\n    h = hashOf(aa, h);\n}\n\nextern(C++) class Issue19282CppClass {}\n\n/// test that hashOf doesn't crash for non-null C++ objects.\nvoid issue19282()\n{\n    Issue19282CppClass c = new Issue19282CppClass();\n    size_t h = hashOf(c);\n    h = hashOf(c, h);\n}\n\n/// Tests ensure TypeInfo_Array.getHash uses element hash functions instead\n/// of hashing array data.\nvoid testTypeInfoArrayGetHash1()\n{\n    class C\n    {\n        int i;\n        this(in int i) { this.i = i; }\n        override hash_t toHash() { return 0; }\n    }\n    C[] a1 = [new C(11)], a2 = [new C(12)];\n    assert(typeid(C[]).getHash(&a1) == typeid(C[]).getHash(&a2));\n}\n\n/// ditto\nvoid testTypeInfoArrayGetHash2()\n{\n    struct S\n    {\n        int i;\n        hash_t toHash() const @safe nothrow { return 0; }\n    }\n    S[] a1 = [S(11)], a2 = [S(12)];\n    assert(typeid(S[]).getHash(&a1) == typeid(S[]).getHash(&a2));\n}\n\n/++\nUse the new `core.internal.hash.hashOf` in all `TypeInfo.getHash` instead of\nthe `old rt.util.hash.hashOf`. Also make `typeid(T).getHash(&val)` get the\nsame result as `hashOf(val)`.\n+/\nvoid pr2243()\n{\n    static struct Foo\n    {\n        int a = 99;\n        float b = 4.0;\n        size_t toHash() const pure @safe nothrow\n        {\n            return a;\n        }\n    }\n\n    static struct Bar\n    {\n        char c = 'x';\n        int a = 99;\n        float b = 4.0;\n        void* d = null;\n    }\n\n    static struct Boom\n    {\n        char c = 'M';\n        int* a = null;\n    }\n\n    static struct Plain\n    {\n        int a = 1;\n        int b = 2;\n    }\n\n    interface IBoo\n    {\n        void boo();\n    }\n\n    static class Boo: IBoo\n    {\n        override void boo()\n        {\n        }\n\n        override size_t toHash()\n        {\n            return 1;\n        }\n    }\n\n    static struct Goo\n    {\n        size_t toHash() pure @safe nothrow\n        {\n            return 1;\n        }\n    }\n\n    enum Gun: long\n    {\n        A = 99,\n        B = 17\n    }\n\n    enum double dexpr = 3.14;\n    enum float fexpr = 2.71;\n    enum wstring wsexpr = \"abcdef\"w;\n    enum string csexpr = \"abcdef\";\n    enum int iexpr = 7;\n    enum long lexpr = 42;\n    enum int[2][3] saexpr = [[1, 2], [3, 4], [5, 6]];\n    enum int[] daexpr = [7,8,9];\n    enum Foo thsexpr = Foo();\n    enum Bar vsexpr = Bar();\n    enum int[int] aaexpr = [99:2, 12:6, 45:4];\n    enum Gun eexpr = Gun.A;\n    enum cdouble cexpr = 7+4i;\n    enum Foo[] staexpr = [Foo(), Foo(), Foo()];\n    enum Bar[] vsaexpr = [Bar(), Bar(), Bar()];\n    enum realexpr = 7.88;\n    enum raexpr = [8.99L+86i, 3.12L+99i, 5.66L+12i];\n    enum nullexpr = null;\n    enum plstr = Plain();\n    enum plarrstr = [Plain(), Plain(), Plain()];\n    //No CTFE:\n    Boom rstructexpr = Boom();\n    Boom[] rstrarrexpr = [Boom(), Boom(), Boom()];\n    int delegate() dgexpr  = (){return 78;};\n    void* ptrexpr = &dgexpr;\n\n\n    //CTFE hashes\n    enum h1 = dexpr.hashOf();\n    enum h2 = fexpr.hashOf();\n    enum h3 = wsexpr.hashOf();\n    enum h4 = csexpr.hashOf();\n    enum h5 = iexpr.hashOf();\n    enum h6 = lexpr.hashOf();\n    enum h7 = saexpr.hashOf();\n    enum h8 = daexpr.hashOf();\n    enum h9 = thsexpr.hashOf();\n    enum h10 = vsexpr.hashOf();\n    enum h11 = aaexpr.hashOf();\n    enum h12 = eexpr.hashOf();\n    enum h13 = cexpr.hashOf();\n    enum h14 = hashOf(new Boo);\n    enum h15 = staexpr.hashOf();\n    enum h16 = hashOf([new Boo, new Boo, new Boo]);\n    enum h17 = hashOf([cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo]);\n    enum h18 = hashOf(cast(IBoo)new Boo);\n    enum h19 = vsaexpr.hashOf();\n    enum h20 = hashOf(cast(Foo[3])staexpr);\n\n    //BUG: cannot cast [Boo(), Boo(), Boo()][0] to object.Object at compile time\n    auto h21 = hashOf(cast(Boo[3])[new Boo, new Boo, new Boo]);\n    auto h22 = hashOf(cast(IBoo[3])[cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo]);\n    enum h23 = hashOf(cast(Bar[3])vsaexpr);\n\n    //NO CTFE (Compute, but don't check correctness):\n    auto h24 = rstructexpr.hashOf();\n    auto h25 = rstrarrexpr.hashOf();\n    auto h26 = dgexpr.hashOf();\n    auto h27 = ptrexpr.hashOf();\n\n    enum h28 = realexpr.hashOf();\n    enum h29 = raexpr.hashOf();\n    enum h30 = nullexpr.hashOf();\n    enum h31 = plstr.hashOf();\n    enum h32 = plarrstr.hashOf();\n    enum h33 = hashOf(cast(Plain[3])plarrstr);\n\n    auto v1 = dexpr;\n    auto v2 = fexpr;\n    auto v3 = wsexpr;\n    auto v4 = csexpr;\n    auto v5 = iexpr;\n    auto v6 = lexpr;\n    auto v7 = saexpr;\n    auto v8 = daexpr;\n    auto v9 = thsexpr;\n    auto v10 = vsexpr;\n    auto v11 = aaexpr;\n    auto v12 = eexpr;\n    auto v13 = cexpr;\n    auto v14 = new Boo;\n    auto v15 = staexpr;\n    auto v16 = [new Boo, new Boo, new Boo];\n    auto v17 = [cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo];\n    auto v18 = cast(IBoo)new Boo;\n    auto v19 = vsaexpr;\n    auto v20 = cast(Foo[3])staexpr;\n    auto v21 = cast(Boo[3])[new Boo, new Boo, new Boo];\n    auto v22 = cast(IBoo[3])[cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo];\n    auto v23 = cast(Bar[3])vsaexpr;\n    auto v30 = null;\n    auto v31 = plstr;\n    auto v32 = plarrstr;\n    auto v33 = cast(Plain[3])plarrstr;\n\n    //NO CTFE:\n    auto v24 = rstructexpr;\n    auto v25 = rstrarrexpr;\n    auto v26 = dgexpr;\n    auto v27 = ptrexpr;\n    auto v28 = realexpr;\n    auto v29 = raexpr;\n\n    //runtime hashes\n    auto rth1 = hashOf(v1);\n    auto rth2 = hashOf(v2);\n    auto rth3 = hashOf(v3);\n    auto rth4 = hashOf(v4);\n    auto rth5 = hashOf(v5);\n    auto rth6 = hashOf(v6);\n    auto rth7 = hashOf(v7);\n    auto rth8 = hashOf(v8);\n    auto rth9 = hashOf(v9);\n    auto rth10 = hashOf(v10);\n    auto rth11 = hashOf(v11);\n    auto rth12 = hashOf(v12);\n    auto rth13 = hashOf(v13);\n    auto rth14 = hashOf(v14);\n    auto rth15 = hashOf(v15);\n    auto rth16 = hashOf(v16);\n    auto rth17 = hashOf(v17);\n    auto rth18 = hashOf(v18);\n    auto rth19 = hashOf(v19);\n    auto rth20 = hashOf(v20);\n    auto rth21 = hashOf(v21);\n    auto rth22 = hashOf(v22);\n    auto rth23 = hashOf(v23);\n    auto rth30 = hashOf(v30);\n    //NO CTFE:\n    auto rth24 = hashOf(v24);\n    auto rth25 = hashOf(v25);\n    auto rth26 = hashOf(v26);\n    auto rth27 = hashOf(v27);\n    auto rth28 = hashOf(v28);\n    auto rth29 = hashOf(v29);\n\n    auto rth31 = hashOf(v31);\n    auto rth32 = hashOf(v32);\n    auto rth33 = hashOf(v33);\n\n    assert(h1 == rth1);\n    assert(h2 == rth2);\n    assert(h3 == rth3);\n    assert(h4 == rth4);\n    assert(h5 == rth5);\n    assert(h6 == rth6);\n    assert(h7 == rth7);\n    assert(h8 == rth8);\n    assert(h9 == rth9);\n    assert(h10 == rth10);\n    assert(h11 == rth11);\n    assert(h12 == rth12);\n    assert(h13 == rth13);\n    assert(h14 == rth14);\n    assert(h15 == rth15);\n    assert(h16 == rth16);\n    assert(h17 == rth17);\n    assert(h18 == rth18);\n    assert(h19 == rth19);\n    assert(h20 == rth20);\n    assert(h21 == rth21);\n    assert(h22 == rth22);\n    assert(h23 == rth23);\n    /*assert(h24 == rth24);\n    assert(h25 == rth25);\n    assert(h26 == rth26);\n    assert(h27 == rth27);\n    assert(h28 == rth28);\n    assert(h29 == rth29);*/\n    assert(h30 == rth30);\n    assert(h31 == rth31);\n    assert(h32 == rth32);\n    assert(h33 == rth33);\n\n    // https://issues.dlang.org/show_bug.cgi?id=18932\n    assert(hashOf(null, 0) != hashOf(null, 123456789));\n\n    static size_t tiHashOf(T)(T var)\n    {\n        return typeid(T).getHash(&var);\n    }\n\n    auto tih1 = tiHashOf(v1);\n    auto tih2 = tiHashOf(v2);\n    auto tih3 = tiHashOf(v3);\n    auto tih4 = tiHashOf(v4);\n    auto tih5 = tiHashOf(v5);\n    auto tih6 = tiHashOf(v6);\n    auto tih7 = tiHashOf(v7);\n    auto tih8 = tiHashOf(v8);\n    auto tih9 = tiHashOf(v9);\n    auto tih10 = tiHashOf(v10);\n    auto tih11 = tiHashOf(v11);\n    auto tih12 = tiHashOf(v12);\n    auto tih13 = tiHashOf(v13);\n    auto tih14 = tiHashOf(v14);\n    auto tih15 = tiHashOf(v15);\n    auto tih16 = tiHashOf(v16);\n    auto tih17 = tiHashOf(v17);\n    auto tih18 = tiHashOf(v18);\n    auto tih19 = tiHashOf(v19);\n    auto tih20 = tiHashOf(v20);\n    auto tih21 = tiHashOf(v21);\n    auto tih22 = tiHashOf(v22);\n    auto tih23 = tiHashOf(v23);\n    auto tih24 = tiHashOf(v24);\n    auto tih25 = tiHashOf(v25);\n    auto tih26 = tiHashOf(v26);\n    auto tih27 = tiHashOf(v27);\n    auto tih28 = tiHashOf(v28);\n    auto tih29 = tiHashOf(v29);\n    auto tih30 = tiHashOf(v30);\n    auto tih31 = tiHashOf(v31);\n    auto tih32 = tiHashOf(v32);\n    auto tih33 = tiHashOf(v33);\n\n    assert(tih1 == rth1);\n    assert(tih2 == rth2);\n    assert(tih3 == rth3);\n    assert(tih4 == rth4);\n    assert(tih5 == rth5);\n    assert(tih6 == rth6);\n    assert(tih7 == rth7);\n    assert(tih8 == rth8);\n    assert(tih9 == rth9);\n    //assert(tih10 == rth10); // need compiler-generated __xtoHash changes\n    assert(tih11 == rth11);\n    assert(tih12 == rth12);\n    assert(tih13 == rth13);\n    assert(tih14 == rth14);\n    assert(tih15 == rth15);\n    assert(tih16 == rth16);\n    assert(tih17 == rth17);\n    assert(tih18 == rth18);\n    //assert(tih19 == rth19); // need compiler-generated __xtoHash changes\n    assert(tih20 == rth20);\n    assert(tih21 == rth21);\n    assert(tih22 == rth22);\n    //assert(tih23 == rth23); // need compiler-generated __xtoHash changes\n    //assert(tih24 == rth24);\n    //assert(tih25 == rth25);\n    assert(tih26 == rth26);\n    assert(tih27 == rth27);\n    assert(tih28 == rth28);\n    assert(tih29 == rth29);\n    assert(tih30 == rth30);\n    assert(tih31 == rth31);\n    assert(tih32 == rth32);\n    assert(tih33 == rth33);\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.imports/bug18193.d",
    "content": "// { dg-options \"-fversion=Shared\" }\n// { dg-do compile }\nimport core.runtime;\nimport core.thread;\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.imports/imports.exp",
    "content": "# Copyright (C) 2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib libphobos-dg.exp\n\n# Initialize dg.\ndg-init\n\n# Gather a list of all tests.\nset tests [lsort [find $srcdir/$subdir *.d]]\n\n# Main loop.\ndg-runtest $tests \"\" $DEFAULT_DFLAGS\n\n# All done.\ndg-finish\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.init_fini/init_fini.exp",
    "content": "# Copyright (C) 2017-2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib libphobos-dg.exp\n\n# Initialize dg.\ndg-init\n\n# Gather a list of all tests.\nset tests [lsort [find $srcdir/$subdir *.d]]\n\n# Main loop.\ndg-runtest $tests \"\" $DEFAULT_DFLAGS\n\n# All done.\ndg-finish\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.init_fini/runtime_args.d",
    "content": "// Bugzilla 11149 - Runtime.args no longer available in static constructors\nimport core.runtime;\n\nshared static this()\n{\n    assert(Runtime.cArgs.argc > 0);\n    assert(Runtime.cArgs.argv !is null);\n    assert(Runtime.args.length > 0);\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.init_fini/test18996.d",
    "content": "// Issue https://issues.dlang.org/show_bug.cgi?id=18996\n// Array!string calls removeRange without first adding the range, but never\n// initializes the GC. The behavior of the default GC is to ignore removing\n// ranges when the range wasn't added. The ProtoGC originally would crash when\n// this happened.\n\nimport core.memory;\n\nvoid main()\n{\n    GC.removeRange(null);\n    GC.removeRoot(null);\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.init_fini/thread_join.d",
    "content": "// Bugzilla 11309 - std.concurrency: OwnerTerminated message doesn't work\n// We need to assure that the thread dtors of parent threads run before the thread dtors of the child threads.\nimport core.thread, core.sync.semaphore;\nimport core.stdc.stdio;\n\n__gshared Semaphore sem;\n\nstatic ~this()\n{\n    if (sem !is null) sem.notify();\n}\n\nvoid main()\n{\n    sem = new Semaphore;\n    auto thr = new Thread({assert(sem.wait(1.seconds));});\n    thr.start();\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/finalize.d",
    "content": "import core.runtime;\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport core.thread;\nimport core.sys.posix.dlfcn;\n\nvoid runTest()\n{\n    Object obj;\n    obj = Object.factory(\"lib.MyFinalizer\");\n    assert(obj.toString() == \"lib.MyFinalizer\");\n    obj = Object.factory(\"lib.MyFinalizerBig\");\n    assert(obj.toString() == \"lib.MyFinalizerBig\");\n}\n\nclass NoFinalize\n{\n    size_t _finalizeCounter;\n\n    ~this()\n    {\n        ++_finalizeCounter;\n    }\n}\n\nclass NoFinalizeBig : NoFinalize\n{\n    ubyte[4096] _big = void;\n}\n\nextern (C) alias SetFinalizeCounter = void function(shared(size_t*));\n\nvoid main(string[] args)\n{\n    auto name = args[0] ~ '\\0';\n    const pathlen = strrchr(name.ptr, '/') - name.ptr + 1;\n    name = name[0 .. pathlen] ~ \"lib.so\";\n\n    auto h = Runtime.loadLibrary(name);\n    assert(h !is null);\n\n    auto nf1 = new NoFinalize;\n    auto nf2 = new NoFinalizeBig;\n\n    shared size_t finalizeCounter;\n    auto setFinalizeCounter = cast(SetFinalizeCounter)dlsym(h, \"setFinalizeCounter\");\n    setFinalizeCounter(&finalizeCounter);\n\n    runTest();\n    auto thr = new Thread(&runTest);\n    thr.start();\n    thr.join();\n\n    auto r = Runtime.unloadLibrary(h);\n    if (!r)\n        assert(0);\n    if (finalizeCounter != 4)\n        assert(0);\n    if (nf1._finalizeCounter)\n        assert(0);\n    if (nf2._finalizeCounter)\n        assert(0);\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/host.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <dlfcn.h>\n#include <assert.h>\n\nint main(int argc, char* argv[])\n{\n#if defined(__FreeBSD__)\n    // workaround for Bugzilla 14824\n    void *druntime = dlopen(argv[1], RTLD_LAZY); // load druntime\n    assert(druntime);\n#endif\n#if defined(__DragonFly__)\n    // workaround for Bugzilla 14824\n    void *druntime = dlopen(argv[1], RTLD_LAZY); // load druntime\n    assert(druntime);\n#endif\n\n    const size_t pathlen = strrchr(argv[0], '/') - argv[0] + 1;\n    char *name = malloc(pathlen + sizeof(\"plugin1.so\"));\n    memcpy(name, argv[0], pathlen);\n    memcpy(name+pathlen, \"plugin1.so\", sizeof(\"plugin1.so\"));\n\n    void* plugin1 = dlopen(name, RTLD_LAZY);\n    name[pathlen + sizeof(\"plugin1.so\") - 5] = '2';\n    void* plugin2 = dlopen(name, RTLD_LAZY);\n\n    int (*plugin1_init)() = dlsym(plugin1, \"plugin_init\");\n    int (*plugin1_term)() = dlsym(plugin1, \"plugin_term\");\n    int (*runTests1)() = dlsym(plugin1, \"runTests\");\n    int (*plugin2_init)() = dlsym(plugin2, \"plugin_init\");\n    int (*plugin2_term)() = dlsym(plugin2, \"plugin_term\");\n    int (*runTests2)() = dlsym(plugin2, \"runTests\");\n    assert(plugin1_init());\n    assert(runTests1());\n    assert(plugin2_init());\n    assert(runTests2());\n\n    assert(plugin1_term());\n    assert(dlclose(plugin1) == 0);\n    assert(runTests2());\n\n    name[pathlen + sizeof(\"plugin1.so\") - 5] = '1';\n    plugin1 = dlopen(name, RTLD_LAZY);\n    plugin1_init = dlsym(plugin1, \"plugin_init\");\n    plugin1_term = dlsym(plugin1, \"plugin_term\");\n    runTests1 = dlsym(plugin1, \"runTests\");\n    assert(plugin1_init());\n    assert(runTests1());\n    assert(runTests2());\n\n    assert(plugin2_term());\n    assert(dlclose(plugin2) == 0);\n    assert(runTests1());\n\n    assert(plugin1_term());\n    assert(dlclose(plugin1) == 0);\n\n    free(name);\n\n#if defined(__FreeBSD__)\n    dlclose(druntime);\n#endif\n#if defined(__DragonFly__)\n    dlclose(druntime);\n#endif\n    return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/lib.d",
    "content": "module lib;\n\n// test EH\nvoid throwException()\n{\n    throw new Exception(null);\n}\n\nException collectException(void delegate() dg)\n{\n    try\n        dg();\n    catch (Exception e)\n        return e;\n    return null;\n}\n\n// test GC\n__gshared Object root;\nvoid alloc() { root = new Object(); }\nvoid access() { assert(root.toString() !is null); } // vtbl call will fail if finalized\nvoid free() { root = null; }\n\nObject tls_root;\nvoid tls_alloc() { tls_root = new Object(); }\nvoid tls_access() { assert(tls_root.toString() !is null); } // vtbl call will fail if finalized\nvoid tls_free() { tls_root = null; }\n\nvoid stack(alias func)()\n{\n    // allocate some extra stack space to not keep references to GC memory on the scanned stack\n    ubyte[1024] buf = void;\n    func();\n}\n\nvoid testGC()\n{\n    import core.memory;\n\n    stack!alloc();\n    stack!tls_alloc();\n    stack!access();\n    stack!tls_access();\n    GC.collect();\n    stack!tls_access();\n    stack!access();\n    stack!tls_free();\n    stack!free();\n}\n\n// test Init\nimport core.atomic : atomicOp;\nshared uint shared_static_ctor, shared_static_dtor, static_ctor, static_dtor;\nshared static this() { if (atomicOp!\"+=\"(shared_static_ctor, 1) != 1) assert(0); }\nshared static ~this() { if (atomicOp!\"+=\"(shared_static_dtor, 1) != 1) assert(0); }\nstatic this() { atomicOp!\"+=\"(static_ctor, 1); }\nstatic ~this() { atomicOp!\"+=\"(static_dtor, 1); }\n\nextern(C) int runTests()\n{\n    try\n        runTestsImpl();\n    catch (Throwable)\n        return 0;\n    return 1;\n}\n\nvoid runTestsImpl()\n{\n    import core.thread;\n\n    bool passed;\n    try\n        throwException();\n    catch (Exception e)\n        passed = true;\n    assert(passed);\n    assert(collectException({throwException();}) !is null);\n\n    testGC();\n\n    assert(shared_static_ctor == 1);\n    assert(static_ctor == 1);\n    static void run()\n    {\n        assert(static_ctor == 2);\n        assert(shared_static_ctor == 1);\n        testGC();\n    }\n    auto thr = new Thread(&run);\n    thr.start();\n    thr.join();\n    assert(static_dtor == 1);\n\n    passed = false;\n    foreach (m; ModuleInfo)\n        if (m.name == \"lib\") passed = true;\n    assert(passed);\n}\n\n// Provide a way to initialize D from C programs that are D agnostic.\nimport core.runtime : rt_init, rt_term;\n\nextern(C) int lib_init()\n{\n    return rt_init();\n}\n\nextern(C) int lib_term()\n{\n    return rt_term();\n}\n\nshared size_t* _finalizeCounter;\n\nclass MyFinalizer\n{\n    ~this()\n    {\n        import core.atomic;\n        atomicOp!\"+=\"(*_finalizeCounter, 1);\n    }\n}\n\nclass MyFinalizerBig : MyFinalizer\n{\n    ubyte[4096] _big = void;\n}\n\nextern(C) void setFinalizeCounter(shared(size_t)* p)\n{\n    _finalizeCounter = p;\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/lib_13414.d",
    "content": "shared void function() sharedStaticDtorHook;\nshared void function() staticDtorHook;\nshared static ~this() { sharedStaticDtorHook(); }\nstatic ~this() { staticDtorHook(); }\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/liblinkdep.d",
    "content": "import lib;\n\nextern(C) int runDepTests()\n{\n    return runTests();\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/libloaddep.d",
    "content": "import core.runtime, core.sys.posix.dlfcn;\n\nextern(C) alias RunTests = int function();\n\nextern(C) int runDepTests(const char* name)\n{\n    auto h = rt_loadLibrary(name);\n    if (h is null) return false;\n    auto runTests = cast(RunTests).dlsym(h, \"runTests\");\n    assert(runTests !is null);\n    if (!runTests()) return false;\n    return rt_unloadLibrary(h);\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/link.d",
    "content": "import lib;\n\nvoid testEH()\n{\n    bool passed;\n    try\n        lib.throwException();\n    catch (Exception e)\n        passed = true;\n    assert(passed); passed = false;\n\n    assert(lib.collectException({throw new Exception(null);}) !is null);\n    assert(lib.collectException({lib.throwException();}) !is null);\n}\n\nvoid testGC()\n{\n    import core.memory;\n    lib.alloc();\n    lib.tls_alloc();\n    lib.access();\n    lib.tls_access();\n    GC.collect();\n    lib.tls_access();\n    lib.access();\n    lib.tls_free();\n    lib.free();\n}\n\nimport core.atomic : atomicOp;\nshared static this() { assert(lib.shared_static_ctor == 1); }\nshared static ~this() { assert(lib.shared_static_dtor == 0); }\nshared uint static_ctor, static_dtor;\nstatic this() { assert(lib.static_ctor == atomicOp!\"+=\"(static_ctor, 1)); }\nstatic ~this() { assert(lib.static_dtor + 1 == atomicOp!\"+=\"(static_dtor, 1)); }\n\nvoid testInit()\n{\n    import core.thread;\n\n    assert(lib.static_ctor == 1);\n    assert(lib.static_dtor == 0);\n    static void foo()\n    {\n        assert(lib.shared_static_ctor == 1);\n        assert(lib.shared_static_dtor == 0);\n        assert(lib.static_ctor == 2);\n        assert(lib.static_dtor == 0);\n    }\n    auto thr = new Thread(&foo);\n    thr.start();\n    assert(thr.join() is null);\n    assert(lib.shared_static_ctor == 1);\n    assert(lib.shared_static_dtor == 0);\n    assert(lib.static_ctor == 2);\n    assert(lib.static_dtor == 1);\n}\n\nvoid main()\n{\n    testEH();\n    testGC();\n    testInit();\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/linkD.c",
    "content": "#include <stdlib.h>\n#include <assert.h>\n\nextern int runTests(void);\nextern int lib_init(void);\nextern int lib_term(void);\n\nint main(int argc, char* argv[])\n{\n    if (!lib_init()) return EXIT_SUCCESS;\n    const int res = runTests() ? EXIT_SUCCESS : EXIT_FAILURE;\n    if (!lib_term()) return EXIT_FAILURE;\n    return res;\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/linkDR.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <dlfcn.h>\n#include <assert.h>\n\nextern void* rt_loadLibrary(const char*);\nextern int rt_unloadLibrary(void*);\nextern int rt_init(void);\nextern int rt_term(void);\n\nint main(int argc, char* argv[])\n{\n    if (!rt_init()) return EXIT_FAILURE;\n    const size_t pathlen = strrchr(argv[0], '/') - argv[0] + 1;\n    char *name = malloc(pathlen + sizeof(\"lib.so\"));\n    memcpy(name, argv[0], pathlen);\n    memcpy(name+pathlen, \"lib.so\", sizeof(\"lib.so\"));\n\n    void *dlib = rt_loadLibrary(name);\n    free(name);\n    assert(dlib);\n\n    int (*runTests)(void) = dlsym(dlib, \"runTests\");\n    assert(runTests());\n    assert(rt_unloadLibrary(dlib));\n    if (!rt_term()) return EXIT_FAILURE;\n    return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/link_linkdep.d",
    "content": "import liblinkdep;\n\nvoid main()\n{\n    runDepTests();\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/link_loaddep.d",
    "content": "import libloaddep;\n\nvoid main(string[] args)\n{\n    auto libname = args[0][0..$-\"link_loaddep\".length] ~ \"lib.so\\0\";\n    runDepTests(libname.ptr);\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/load.d",
    "content": "import core.runtime;\nimport core.stdc.stdio;\nimport core.stdc.string;\nimport core.thread;\n\nversion (linux) import core.sys.linux.dlfcn;\nelse version (FreeBSD) import core.sys.freebsd.dlfcn;\nelse version (DragonFlyBSD) import core.sys.dragonflybsd.dlfcn;\nelse version (NetBSD) import core.sys.netbsd.dlfcn;\nelse static assert(0, \"unimplemented\");\n\nvoid loadSym(T)(void* handle, ref T val, const char* mangle)\n{\n    val = cast(T).dlsym(handle, mangle);\n}\n\nvoid* openLib(string s)\n{\n    auto h = Runtime.loadLibrary(s);\n    assert(h !is null);\n\n    loadSym(h, libThrowException, \"_D3lib14throwExceptionFZv\");\n    loadSym(h, libCollectException, \"_D3lib16collectExceptionFDFZvZC9Exception\");\n\n    loadSym(h, libAlloc, \"_D3lib5allocFZv\");\n    loadSym(h, libTlsAlloc, \"_D3lib9tls_allocFZv\");\n    loadSym(h, libAccess, \"_D3lib6accessFZv\");\n    loadSym(h, libTlsAccess, \"_D3lib10tls_accessFZv\");\n    loadSym(h, libFree, \"_D3lib4freeFZv\");\n    loadSym(h, libTlsFree, \"_D3lib8tls_freeFZv\");\n\n    loadSym(h, libSharedStaticCtor, \"_D3lib18shared_static_ctorOk\");\n    loadSym(h, libSharedStaticDtor, \"_D3lib18shared_static_dtorOk\");\n    loadSym(h, libStaticCtor, \"_D3lib11static_ctorOk\");\n    loadSym(h, libStaticDtor, \"_D3lib11static_dtorOk\");\n\n    return h;\n}\n\nvoid closeLib(void* h)\n{\n    Runtime.unloadLibrary(h);\n}\n\n__gshared\n{\n    void function() libThrowException;\n    Exception function(void delegate()) libCollectException;\n\n    void function() libAlloc;\n    void function() libTlsAlloc;\n    void function() libAccess;\n    void function() libTlsAccess;\n    void function() libFree;\n    void function() libTlsFree;\n\n    shared uint* libSharedStaticCtor;\n    shared uint* libSharedStaticDtor;\n    shared uint* libStaticCtor;\n    shared uint* libStaticDtor;\n}\n\nvoid testEH()\n{\n    bool passed;\n    try\n        libThrowException();\n    catch (Exception e)\n        passed = true;\n    assert(passed); passed = false;\n\n    assert(libCollectException({throw new Exception(null);}) !is null);\n    assert(libCollectException({libThrowException();}) !is null);\n}\n\nvoid testGC()\n{\n    import core.memory;\n    libAlloc();\n    libTlsAlloc();\n    libAccess();\n    libTlsAccess();\n    GC.collect();\n    libTlsAccess();\n    libAccess();\n    libTlsFree();\n    libFree();\n}\n\nvoid testInit()\n{\n\n    assert(*libStaticCtor == 1);\n    assert(*libStaticDtor == 0);\n    static void run()\n    {\n        assert(*libSharedStaticCtor == 1);\n        assert(*libSharedStaticDtor == 0);\n        assert(*libStaticCtor == 2);\n        assert(*libStaticDtor == 0);\n    }\n    auto thr = new Thread(&run);\n    thr.start();\n    thr.join();\n    assert(*libSharedStaticCtor == 1);\n    assert(*libSharedStaticDtor == 0);\n    assert(*libStaticCtor == 2);\n    assert(*libStaticDtor == 1);\n}\n\nconst(ModuleInfo)* findModuleInfo(string name)\n{\n    foreach (m; ModuleInfo)\n        if (m.name == name) return m;\n    return null;\n}\n\nvoid runTests(string libName)\n{\n    assert(findModuleInfo(\"lib\") is null);\n    auto handle = openLib(libName);\n    assert(findModuleInfo(\"lib\") !is null);\n\n    testEH();\n    testGC();\n    testInit();\n\n    closeLib(handle);\n    assert(findModuleInfo(\"lib\") is null);\n}\n\nvoid main(string[] args)\n{\n    auto name = args[0] ~ '\\0';\n    const pathlen = strrchr(name.ptr, '/') - name.ptr + 1;\n    name = name[0 .. pathlen] ~ \"lib.so\";\n\n    runTests(name);\n\n    // lib is no longer resident\n    name ~= '\\0';\n    assert(.dlopen(name.ptr, RTLD_LAZY | RTLD_NOLOAD) is null);\n    name = name[0 .. $-1];\n\n    auto thr = new Thread({runTests(name);});\n    thr.start();\n    thr.join();\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/loadDR.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <dlfcn.h>\n#include <assert.h>\n\nint main(int argc, char* argv[])\n{\n    if (argc != 2)\n        return EXIT_FAILURE;\n    void *h = dlopen(argv[1], RTLD_LAZY); // load druntime\n    assert(h != NULL);\n\n    int (*rt_init)(void) = dlsym(h, \"rt_init\");\n    int (*rt_term)(void) = dlsym(h, \"rt_term\");\n    void* (*rt_loadLibrary)(const char*) = dlsym(h, \"rt_loadLibrary\");\n    int (*rt_unloadLibrary)(void*) = dlsym(h, \"rt_unloadLibrary\");\n\n    int res = EXIT_FAILURE;\n    if (!rt_init()) goto Lexit;\n\n    const size_t pathlen = strrchr(argv[0], '/') - argv[0] + 1;\n    char *name = malloc(pathlen + sizeof(\"lib.so\"));\n    memcpy(name, argv[0], pathlen);\n    memcpy(name+pathlen, \"lib.so\", sizeof(\"lib.so\"));\n\n    void *dlib = rt_loadLibrary(name);\n    free(name);\n    assert(dlib);\n\n    int (*runTests)(void) = dlsym(dlib, \"runTests\");\n    assert(runTests());\n    assert(rt_unloadLibrary(dlib));\n\n    if (rt_term()) res = EXIT_SUCCESS;\n\nLexit:\n    assert(dlclose(h) == 0);\n    return res;\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/load_13414.d",
    "content": "import core.runtime;\nimport core.atomic;\nimport core.stdc.string;\nimport core.sys.posix.dlfcn;\n\nshared uint tlsDtor, dtor;\nvoid staticDtorHook() { atomicOp!\"+=\"(tlsDtor, 1); }\nvoid sharedStaticDtorHook() { atomicOp!\"+=\"(dtor, 1); }\n\nvoid runTest(string name)\n{\n    auto h = Runtime.loadLibrary(name);\n    assert(h !is null);\n\n    *cast(void function()*).dlsym(h, \"_D9lib_1341414staticDtorHookOPFZv\") = &staticDtorHook;\n    *cast(void function()*).dlsym(h, \"_D9lib_1341420sharedStaticDtorHookOPFZv\") = &sharedStaticDtorHook;\n\n    Runtime.unloadLibrary(h);\n    assert(tlsDtor == 1);\n    assert(dtor == 1);\n}\n\nvoid main(string[] args)\n{\n    auto name = args[0] ~ '\\0';\n    const pathlen = strrchr(name.ptr, '/') - name.ptr + 1;\n    name = name[0 .. pathlen] ~ \"lib_13414.so\";\n\n    runTest(name);\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/load_linkdep.d",
    "content": "import core.runtime;\nimport core.stdc.string;\nimport core.sys.posix.dlfcn;\n\nextern(C) alias RunDepTests = int function();\n\nvoid main(string[] args)\n{\n    auto name = args[0] ~ '\\0';\n    const pathlen = strrchr(name.ptr, '/') - name.ptr + 1;\n    name = name[0 .. pathlen] ~ \"liblinkdep.so\";\n\n    auto h = Runtime.loadLibrary(name);\n    assert(h);\n    auto runDepTests = cast(RunDepTests)dlsym(h, \"runDepTests\");\n    assert(runDepTests());\n    assert(Runtime.unloadLibrary(h));\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/load_loaddep.d",
    "content": "import core.runtime;\nimport core.stdc.string;\nimport core.sys.posix.dlfcn;\n\nextern(C) alias RunDepTests = int function(const char*);\n\nvoid main(string[] args)\n{\n    auto name = args[0] ~ '\\0';\n    const pathlen = strrchr(name.ptr, '/') - name.ptr + 1;\n    auto root = name[0 .. pathlen];\n    auto libloaddep = root ~ \"libloaddep.so\";\n    auto h = Runtime.loadLibrary(libloaddep);\n    auto runDepTests = cast(RunDepTests)dlsym(h, \"runDepTests\");\n    assert(runDepTests((root ~ \"lib.so\\0\").ptr));\n    assert(Runtime.unloadLibrary(h));\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/plugin.d",
    "content": "import core.thread, core.memory, core.atomic;\n\n// test init\nshared uint gctor, gdtor, tctor, tdtor;\nshared static this() { if (atomicOp!\"+=\"(gctor, 1) != 1) assert(0); }\nshared static ~this() { if (atomicOp!\"+=\"(gdtor, 1) != 1) assert(0); }\nstatic this() { atomicOp!\"+=\"(tctor, 1); }\nstatic ~this() { atomicOp!\"+=\"(tdtor, 1); }\n\n// test GC\n__gshared Object root;\nvoid alloc() { root = new Object(); }\nvoid access() { assert(root.toString() !is null); } // vtbl call will fail if finalized\nvoid free() { root = null; }\n\nObject tls_root;\nvoid tls_alloc() { tls_root = new Object(); }\nvoid tls_access() { assert(tls_root.toString() !is null); } // vtbl call will fail if finalized\nvoid tls_free() { tls_root = null; }\n\nvoid stack(alias func)()\n{\n    // allocate some extra stack space to not keep references to GC memory on the scanned stack\n    ubyte[1024] buf = void;\n    func();\n}\n\nvoid testGC()\n{\n    import core.memory;\n\n    stack!alloc();\n    stack!tls_alloc();\n    stack!access();\n    stack!tls_access();\n    GC.collect();\n    stack!tls_access();\n    stack!access();\n    stack!tls_free();\n    stack!free();\n}\n\nextern(C) int runTests()\n{\n    try\n    {\n        assert(atomicLoad!(MemoryOrder.acq)(gctor) == 1);\n        assert(atomicLoad!(MemoryOrder.acq)(gdtor) == 0);\n        assert(atomicLoad!(MemoryOrder.acq)(tctor) >= 1);\n        assert(atomicLoad!(MemoryOrder.acq)(tdtor) >= 0);\n        // test some runtime functionality\n        testGC();\n        new Thread(&testGC).start.join;\n    }\n    catch (Throwable)\n    {\n        return false;\n    }\n    return true;\n}\n\n// Provide a way to initialize D from C programs that are D agnostic.\nimport core.runtime : rt_init, rt_term;\n\nextern(C) int plugin_init()\n{\n    return rt_init();\n}\n\nextern(C) int plugin_term()\n{\n    return rt_term();\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.shared/shared.exp",
    "content": "# Copyright (C) 2017-2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib libphobos-dg.exp\n\n# Immediately exit if target doesn't support shared.\nif { ![is-effective-target shared] } {\n    return\n}\n\n# If a testcase doesn't have special options, use these.\nif ![info exists DEFAULT_CFLAGS] then {\n    set DEFAULT_CFLAGS \"-g\"\n}\n\n#\n# Build all shared libraries, used as dependencies for other tests.\n#\n\nproc shared_library { source destfile options } {\n    global DEFAULT_DFLAGS\n    global all_libraries\n\n    # Compiling with -fno-gnu-unique as tests call dlopen/dlclose multiple times on the same library.\n    lappend options \"additional_flags=$DEFAULT_DFLAGS -fno-gnu-unique -fpic -shared -shared-libphobos\"\n\n    set comp_output [libphobos_target_compile \"$source\" \"$destfile\" \"executable\" $options]\n    if ![ string match \"\" $comp_output ] {\n        fail \"libphobos.shared/[file tail $source]\"\n        verbose -log $comp_output\n        return 1\n    }\n\n    lappend all_libraries $destfile\n}\n\n# lib.so\nshared_library \"$srcdir/$subdir/lib.d\" \"lib.so\" \"\"\n\n# liblinkdep.so\nshared_library \"$srcdir/$subdir/liblinkdep.d\" \"liblinkdep.so\" \\\n        [list \"additional_flags=-I$srcdir/$subdir lib.so\"]\n\n# libloaddep.so\nshared_library \"$srcdir/$subdir/libloaddep.d\" \"libloaddep.so\" \"\"\n\n# lib_13414.so\nshared_library \"$srcdir/$subdir/lib_13414.d\" \"lib_13414.so\" \"\"\n\n# plugin.so\nshared_library \"$srcdir/$subdir/plugin.d\" \"plugin1.so\" \"\"\nshared_library \"$srcdir/$subdir/plugin.d\" \"plugin2.so\" \"\"\n\n# Initialize dg.\ndg-init\n\n# Main loop.\ndg-test \"$srcdir/$subdir/link.d\" \"-I$srcdir/$subdir lib.so -shared-libphobos\" \\\n        \"$DEFAULT_DFLAGS\"\n\ndg-test \"$srcdir/$subdir/link_linkdep.d\" \\\n        \"-I$srcdir/$subdir liblinkdep.so lib.so -shared-libphobos\" \\\n        \"$DEFAULT_DFLAGS\"\n\ndg-test \"$srcdir/$subdir/link_loaddep.d\" \\\n        \"-I$srcdir/$subdir libloaddep.so -shared-libphobos\" \"$DEFAULT_DFLAGS\"\n\n# dlopen() tests.\nif [is-effective-target dlopen] {\n    dg-test \"$srcdir/$subdir/load.d\" \"-shared-libphobos -ldl\" \"$DEFAULT_DFLAGS\"\n    dg-test \"$srcdir/$subdir/load_linkdep.d\" \"-shared-libphobos -ldl\" \"$DEFAULT_DFLAGS\"\n    dg-test \"$srcdir/$subdir/load_loaddep.d\" \"-shared-libphobos -ldl\" \"$DEFAULT_DFLAGS\"\n    dg-test \"$srcdir/$subdir/load_13414.d\" \"-shared-libphobos -ldl\" \"$DEFAULT_DFLAGS\"\n    dg-test \"$srcdir/$subdir/finalize.d\" \"-shared-libphobos -ldl\" \"$DEFAULT_DFLAGS\"\n}\n\n# C program link tests.\nif { [is-effective-target dlopen] && [is-effective-target pthread] } {\n    dg-test \"$srcdir/$subdir/linkD.c\" \"lib.so -ldl -pthread\" \"$DEFAULT_CFLAGS\"\n    dg-test \"$srcdir/$subdir/linkDR.c\" \"-shared-libphobos -ldl -pthread\" \"$DEFAULT_CFLAGS\"\n    dg-test \"$srcdir/$subdir/host.c\" \"-ldl -pthread\" \"$DEFAULT_CFLAGS\"\n\n    # Test requires a command line argument to be passed to the program.\n    set libphobos_run_args \"$objdir/../src/.libs/libgphobos.so\"\n    dg-test \"$srcdir/$subdir/loadDR.c\" \"-ldl -pthread -g\" \"$DEFAULT_CFLAGS\"\n    set libphobos_run_args \"\"\n}\n\n# All done.\ndg-finish\n\n# Remove all libraries built before running tests.\nforeach lib $all_libraries {\n    catch \"file delete -force -- $lib\"\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.testrunner/testrunner.exp",
    "content": "# Copyright (C) 2017-2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\n# Immediately exit if we can't run target executables.\nif { ![isnative] } {\n    return\n}\n\nproc unittest_list_modules { prog } {\n    # Running the test runner without arguments prints a list of all\n    # modules that have unittests compiled in.\n    set result [libphobos_load \"$prog\" \"\" \"\"]\n    return [lindex $result 1]\n}\n\n# Runs all unittests for each module compiled into the test program.\nproc unittest_run_tests { name prog } {\n    foreach module [unittest_list_modules $prog] {\n        set result [libphobos_load \"$prog\" \"$module\" \"\"]\n        set status [lindex $result 0]\n        $status \"libphobos.testrunner/$name/$module\"\n    }\n}\n\nproc unittester { name prog } {\n    if [file exists $prog] {\n        unittest_run_tests $name $prog\n    }\n}\n\n# List of test runners.\nif [is-effective-target static] {\n    unittester \"druntime/static\" \"$objdir/../libdruntime/unittest_static$exeext\"\n    unittester \"phobos/static\" \"$objdir/../src/unittest_static$exeext\"\n}\n\nif [is-effective-target shared] {\n    unittester \"druntime/shared\" \"$objdir/../libdruntime/unittest$exeext\"\n    unittester \"phobos/shared\" \"$objdir/../src/unittest$exeext\"\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.thread/external_threads.d",
    "content": "import core.sys.posix.pthread;\nimport core.memory;\nimport core.thread;\n\nextern (C) void  rt_moduleTlsCtor();\nextern (C) void  rt_moduleTlsDtor();\n\nextern(C)\nvoid* entry_point1(void*)\n{\n    // try collecting - GC must ignore this call because this thread\n    // is not registered in runtime\n    GC.collect();\n    return null;\n}\n\nextern(C)\nvoid* entry_point2(void*)\n{\n    // This thread gets registered in druntime, does some work and gets\n    // unregistered to be cleaned up manually\n    thread_attachThis();\n    rt_moduleTlsCtor();\n\n    auto x = new int[10];\n\n    rt_moduleTlsDtor();\n    thread_detachThis();\n    return null;\n}\n\nvoid main()\n{\n    // allocate some garbage\n    auto x = new int[1000];\n\n    {\n        pthread_t thread;\n        auto status = pthread_create(&thread, null, &entry_point1, null);\n        assert(status == 0);\n        pthread_join(thread, null);\n    }\n\n    {\n        pthread_t thread;\n        auto status = pthread_create(&thread, null, &entry_point2, null);\n        assert(status == 0);\n        pthread_join(thread, null);\n    }\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.thread/fiber_guard_page.d",
    "content": "// { dg-shouldfail \"segv or bus error\" }\nimport core.thread;\nimport core.sys.posix.sys.mman;\n\n// this should be true for most architectures\n// (taken from core.thread)\nversion = StackGrowsDown;\n\nenum stackSize = 4096;\n\n// Simple method that causes a stack overflow\nvoid stackMethod()\n{\n    // Over the stack size, so it overflows the stack\n    int[stackSize/int.sizeof+100] x;\n}\n\nvoid main()\n{\n    auto test_fiber = new Fiber(&stackMethod, stackSize);\n\n    // allocate a page below (above) the fiber's stack to make stack overflows possible (w/o segfaulting)\n    version (StackGrowsDown)\n    {\n        static assert(__traits(identifier, test_fiber.tupleof[8]) == \"m_pmem\");\n        auto stackBottom = test_fiber.tupleof[8];\n        auto p = mmap(stackBottom - 8 * stackSize, 8 * stackSize,\n                      PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);\n        assert(p !is null, \"failed to allocate page\");\n    }\n    else\n    {\n        auto m_sz = test_fiber.tupleof[7];\n        auto m_pmem = test_fiber.tupleof[8];\n        static assert(__traits(identifier, test_fiber.tupleof[7]) == \"m_size\");\n        static assert(__traits(identifier, test_fiber.tupleof[8]) == \"m_pmem\");\n\n        auto stackTop = m_pmem + m_sz;\n        auto p = mmap(stackTop, 8 * stackSize,\n                      PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);\n        assert(p !is null, \"failed to allocate page\");\n    }\n\n    // the guard page should prevent a mem corruption by stack\n    // overflow and cause a segfault instead (or generate SIGBUS on *BSD flavors)\n    test_fiber.call();\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.thread/thread.exp",
    "content": "# Copyright (C) 2017-2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib libphobos-dg.exp\n\n# Initialize dg.\ndg-init\n\n# Gather a list of all tests.\nset tests [lsort [find $srcdir/$subdir *.d]]\n\n# Main loop.\ndg-runtest $tests \"\" $DEFAULT_DFLAGS\n\n# All done.\ndg-finish\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.typeinfo/comparison.d",
    "content": "// https://github.com/dlang/druntime/pull/1781\n\nstruct S\n{\n    int i;\n    static int comparisons;\n    int opCmp(const S s) const { comparisons++; return i - s.i; }\n}\n\nvoid testStructs()\n{\n    auto s1 = S(1);\n    auto s2 = S(2);\n    auto s3 = S(3);\n    auto s4 = S(4);\n\n    // Test lexicographical order\n\n    assert(s1 < s2 && s2 < s3);\n    assert([s1, s2, s3] < [s1, s3]);\n    assert([s1, s2] < [s1, s2, s3]);\n\n    // Test number of comparisons for nested types\n\n    S.comparisons = 0;\n    assert(s1 < s2);\n    assert(S.comparisons == 1);\n\n    S.comparisons = 0;\n    assert([s1, s2] < [s3, s4]);\n    assert(S.comparisons == 1);\n\n    S.comparisons = 0;\n    assert([[s1, s2]] < [[s3, s4]]);\n    assert(S.comparisons == 1);\n}\n\nclass C\n{\n    this(int i) { this.i = i; }\n    int i;\n    static int comparisons;\n    override int opCmp(Object c) const { comparisons++; return i - (cast(C)c).i; }\n}\n\nvoid testClasses()\n{\n    auto c1 = new C(1);\n    auto c2 = new C(2);\n    auto c3 = new C(3);\n    auto c4 = new C(4);\n\n    // Test lexicographical order\n\n    assert(c1 < c2 && c2 < c3);\n    assert([c1, c2, c3] < [c1, c3]);\n    assert([c1, c2] < [c1, c2, c3]);\n\n    // Test number of comparisons for nested types\n\n    C.comparisons = 0;\n    assert(c1 < c2);\n    assert(C.comparisons == 1);\n\n    C.comparisons = 0;\n    assert([c1, c2] < [c3, c4]);\n    assert(C.comparisons == 1);\n\n    C.comparisons = 0;\n    assert([[c1, c2]] < [[c3, c4]]);\n    assert(C.comparisons == 1);\n}\n\nvoid main()\n{\n    testStructs();\n    testClasses();\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.typeinfo/typeinfo.exp",
    "content": "# Copyright (C) 2017-2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib libphobos-dg.exp\n\n# Initialize dg.\ndg-init\n\n# Gather a list of all tests.\nset tests [lsort [find $srcdir/$subdir *.d]]\n\n# Main loop.\ndg-runtest $tests \"\" $DEFAULT_DFLAGS\n\n# All done.\ndg-finish\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.unittest/customhandler.d",
    "content": "import core.runtime;\n\nUnitTestResult customModuleUnitTester()\n{\n    version(GoodTests) return UnitTestResult(100, 100, false, true);\n    version(FailedTests) return UnitTestResult(100, 0, false, true);\n    version(NoTests) return UnitTestResult(0, 0, true, false);\n    version(FailNoPrintout) return UnitTestResult(100, 0, false, false);\n    version(PassNoPrintout) return UnitTestResult(100, 100, false, false);\n}\n\nshared static this()\n{\n    Runtime.extendedModuleUnitTester = &customModuleUnitTester;\n}\n\nvoid main()\n{\n    import core.stdc.stdio;\n    fprintf(stderr, \"main\\n\");\n}\n"
  },
  {
    "path": "libphobos/testsuite/libphobos.unittest/unittest.exp",
    "content": "# Copyright (C) 2018 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GCC; see the file COPYING3.  If not see\n# <http://www.gnu.org/licenses/>.\n\nload_lib libphobos-dg.exp\n\nset dg-output-text [list]\n\n# Arguments to pass to the compiler, expected output, and return code.\nset unit_test_list [list \\\n    { \"-fversion=PassNoPrintout\"  0 } \\\n    { \"-fversion=GoodTests\" 0 } \\\n    { \"-fversion=FailNoPrintout\" 1 } \\\n    { \"-fversion=FailedTests\" 1 } \\\n    { \"-fversion=NoTests\" 0 } \\\n]\n\n# Initialize dg.\ndg-init\n\n# Gather a list of all tests.\nset tests [lsort [find $srcdir/$subdir *.d]]\n\n# Main loop.\nforeach unit_test $unit_test_list {\n    # The version flags to build the program with.\n    set test_flags [lindex $unit_test 0]\n\n    # Whether the program is expected to fail.\n    set expected_fail [lindex $unit_test 1]\n\n    foreach test $tests {\n        set shouldfail $expected_fail\n        dg-test $test \"\" $test_flags\n    }\n\n    set shouldfail 0\n}\n\n# All done.\ndg-finish\n"
  },
  {
    "path": "libphobos/testsuite/test_runner.d",
    "content": "import core.runtime, core.time : MonoTime;\nimport core.stdc.stdio;\n\nModuleInfo* getModuleInfo(string name)\n{\n    foreach (m; ModuleInfo)\n        if (m.name == name) return m;\n    assert(0, \"module '\"~name~\"' not found\");\n}\n\nbool tester()\n{\n    return Runtime.args.length > 1 ? testModules() : printAll();\n}\n\nstring mode;\n\n\nbool testModules()\n{\n    bool ret = true;\n    foreach(name; Runtime.args[1..$])\n    {\n        immutable pkg = \".package\";\n        immutable pkgLen = pkg.length;\n\n        if (name.length > pkgLen && name[$ - pkgLen .. $] == pkg)\n            name = name[0 .. $ - pkgLen];\n\n        doTest(getModuleInfo(name), ret);\n    }\n\n    return ret;\n}\n\nbool printAll()\n{\n    foreach (m; ModuleInfo)\n    {\n        if (m.unitTest)\n        {\n            string name = m.name;\n            printf(\"%.*s\\n\", cast(int)name.length, name.ptr);\n        }\n    }\n    return true;\n}\n\n\nvoid doTest(ModuleInfo* moduleInfo, ref bool ret)\n{\n    if (auto fp = moduleInfo.unitTest)\n    {\n        auto name = moduleInfo.name;\n        try\n        {\n            immutable t0 = MonoTime.currTime;\n            fp();\n            printf(\"%.3fs PASS %.*s %.*s\\n\",\n                   (MonoTime.currTime - t0).total!\"msecs\" / 1000.0,\n                   cast(uint)mode.length, mode.ptr,\n                   cast(uint)name.length, name.ptr);\n        }\n        catch (Throwable e)\n        {\n            auto msg = e.toString();\n            printf(\"****** FAIL %.*s %.*s\\n%.*s\\n\",\n                   cast(uint)mode.length, mode.ptr,\n                   cast(uint)name.length, name.ptr,\n                   cast(uint)msg.length, msg.ptr);\n            ret = false;\n        }\n    }\n}\n\n\nshared static this()\n{\n    version(D_Coverage)\n    {\n        import core.runtime : dmd_coverSetMerge;\n        dmd_coverSetMerge(true);\n    }\n    Runtime.moduleUnitTester = &tester;\n\n    debug mode = \"debug\";\n    else  mode =  \"release\";\n    static if ((void*).sizeof == 4) mode ~= \"32\";\n    else static if ((void*).sizeof == 8) mode ~= \"64\";\n    else static assert(0, \"You must be from the future!\");\n}\n\nvoid main()\n{\n}\n"
  },
  {
    "path": "libphobos/testsuite/testsuite_flags.in",
    "content": "#!/bin/sh\n\n#\n# This script computes the various flags needed to run D Phobos unittests.\n#\n\n# Print a message saying how this script is intended to be invoked\nprint_usage() {\n    cat <<EOF\nUsage:\n    testsuite_flags --gdc\n\t\t    --gdcflags\n\t\t    --gdcpaths\n\t\t    --gdcldflags\n\nEOF\n}\n\n# Establish configure-generated directory structure.\nBUILD_DIR=@libphobos_builddir@\nSRC_DIR=@libphobos_srcdir@\nquery=$1\n\ncase ${query} in\n    --gdc)\n      GDC=\"@GDC@\"\n      echo ${GDC}\n      ;;\n    --gdcflags)\n      GDCFLAGS_default=\"-fmessage-length=0 -fno-show-column\"\n      GDCFLAGS_config=\"@GDCFLAGSX@\"\n      echo ${GDCFLAGS_default} ${GDCFLAGS_config}\n      ;;\n    --gdcpaths)\n      GDCPATHS_default=\"-nostdinc\"\n      GDCPATHS_config=\"-B${BUILD_DIR}/src\n                       -I${BUILD_DIR}/libdruntime\n                       -I${SRC_DIR}/libdruntime\"\n      echo ${GDCPATHS_default} ${GDCPATHS_config}\n      ;;\n    --gdcldflags)\n      GDCLDFLAGS=\"-B${BUILD_DIR}/src\n                  -L${BUILD_DIR}/libdruntime/.libs\n                  -L${BUILD_DIR}/src/.libs\"\n      echo ${GDCLDFLAGS}\n      ;;\n    *)\n      print_usage\n      ;;\nesac\n\nexit 0\n"
  },
  {
    "path": "semaphoreci.sh",
    "content": "#!/bin/bash\n# This script is intended to be ran on SemaphoreCI platform.\n# Following environmental variables are assumed to be exported.\n# - SEMAPHORE_PROJECT_DIR\n# - SEMAPHORE_CACHE_DIR\n# See https://semaphoreci.com/docs/available-environment-variables.html\n\n## Find out which branch we are building.\nGCC_VERSION=$(cat gcc.version)\n\nif [ \"${GCC_VERSION:0:5}\" = \"gcc-9\" ]; then\n    GCC_TARBALL=\"snapshots/${GCC_VERSION:4}/${GCC_VERSION}.tar.xz\"\n    GCC_PREREQS=\"gmp-6.1.0.tar.bz2 mpfr-3.1.4.tar.bz2 mpc-1.0.3.tar.gz isl-0.18.tar.bz2\"\n    PATCH_VERSION=\"9\"\n    HOST_PACKAGE=\"7\"\nelif [ \"${GCC_VERSION:0:5}\" = \"gcc-8\" ]; then\n    GCC_TARBALL=\"releases/${GCC_VERSION}/${GCC_VERSION}.tar.xz\"\n    GCC_PREREQS=\"gmp-6.1.0.tar.bz2 mpfr-3.1.4.tar.bz2 mpc-1.0.3.tar.gz isl-0.18.tar.bz2\"\n    PATCH_VERSION=\"8\"\n    HOST_PACKAGE=\"7\"\nelif [ \"${GCC_VERSION:0:5}\" = \"gcc-7\" ]; then\n    GCC_TARBALL=\"releases/${GCC_VERSION}/${GCC_VERSION}.tar.xz\"\n    GCC_PREREQS=\"gmp-6.1.0.tar.bz2 mpfr-3.1.4.tar.bz2 mpc-1.0.3.tar.gz isl-0.16.1.tar.bz2\"\n    PATCH_VERSION=\"7\"\n    HOST_PACKAGE=\"7\"\nelif [ \"${GCC_VERSION:0:5}\" = \"gcc-6\" ]; then\n    GCC_TARBALL=\"releases/${GCC_VERSION}/${GCC_VERSION}.tar.xz\"\n    GCC_PREREQS=\"gmp-4.3.2.tar.bz2 mpfr-2.4.2.tar.bz2 mpc-0.8.1.tar.gz isl-0.15.tar.bz2\"\n    PATCH_VERSION=\"6\"\n    HOST_PACKAGE=\"5\"\nelif [ \"${GCC_VERSION:0:5}\" = \"gcc-5\" ]; then\n    GCC_TARBALL=\"releases/${GCC_VERSION}/${GCC_VERSION}.tar.xz\"\n    GCC_PREREQS=\"gmp-4.3.2.tar.bz2 mpfr-2.4.2.tar.bz2 mpc-0.8.1.tar.gz isl-0.14.tar.bz2\"\n    PATCH_VERSION=\"5\"\n    HOST_PACKAGE=\"5\"\nelif [ \"${GCC_VERSION:0:7}\" = \"gcc-4.9\" ]; then\n    GCC_TARBALL=\"releases/${GCC_VERSION}/${GCC_VERSION}.tar.bz2\"\n    GCC_PREREQS=\"gmp-4.3.2.tar.bz2 mpfr-2.4.2.tar.bz2 mpc-0.8.1.tar.gz isl-0.12.2.tar.bz2 cloog-0.18.1.tar.gz\"\n    PATCH_VERSION=\"4.9\"\n    HOST_PACKAGE=\"4.9\"\nelif [ \"${GCC_VERSION:0:7}\" = \"gcc-4.8\" ]; then\n    GCC_TARBALL=\"releases/${GCC_VERSION}/${GCC_VERSION}.tar.bz2\"\n    GCC_PREREQS=\"gmp-4.3.2.tar.bz2 mpfr-2.4.2.tar.bz2 mpc-0.8.1.tar.gz\"\n    PATCH_VERSION=\"4.8\"\n    HOST_PACKAGE=\"4.8\"\nelse\n    echo \"This version of GCC ($GCC_VERSION) is not supported.\"\n    exit 1\nfi\n\nexport CC=\"gcc-${HOST_PACKAGE}\"\nexport CXX=\"g++-${HOST_PACKAGE}\"\nexport GDC=\"gdc-${HOST_PACKAGE}\"\n\nsetup() {\n    ## Install build dependencies.\n    # Would save 1 minute if these were preinstalled in some docker image.\n    # But the network speed is nothing to complain about so far...\n    sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test\n    sudo apt-get update -qq\n    sudo apt-get install -qq gcc-${HOST_PACKAGE} g++-${HOST_PACKAGE} gdc-${HOST_PACKAGE} \\\n        autogen autoconf2.64 automake1.11 bison dejagnu flex patch || exit 1\n\n    ## Download and extract GCC sources.\n    # Makes use of local cache to save downloading on every build run.\n    if [ ! -e ${SEMAPHORE_CACHE_DIR}/${GCC_TARBALL} ]; then\n        curl \"ftp://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/${GCC_TARBALL}\" \\\n            --create-dirs -o ${SEMAPHORE_CACHE_DIR}/${GCC_TARBALL} || exit 1\n    fi\n\n    tar --strip-components=1 -xf ${SEMAPHORE_CACHE_DIR}/${GCC_TARBALL}\n\n    ## Apply GDC patches to GCC.\n    for PATCH in toplev toplev-ddmd gcc gcc-ddmd targetdm; do\n        patch -p1 -i ./gcc/d/patches/patch-${PATCH}-${PATCH_VERSION}.patch || exit 1\n    done\n\n    ## And download GCC prerequisites.\n    # Makes use of local cache to save downloading on every build run.\n    for PREREQ in ${GCC_PREREQS}; do\n        if [ ! -e ${SEMAPHORE_CACHE_DIR}/infrastructure/${PREREQ} ]; then\n            curl \"ftp://gcc.gnu.org/pub/gcc/infrastructure/${PREREQ}\" \\\n                --create-dirs -o ${SEMAPHORE_CACHE_DIR}/infrastructure/${PREREQ} || exit 1\n        fi\n        tar -xf ${SEMAPHORE_CACHE_DIR}/infrastructure/${PREREQ}\n        ln -s \"${PREREQ%.tar*}\" \"${PREREQ%-*}\"\n    done\n\n    ## Create the build directory.\n    # Build typically takes around 10 minutes with -j4, could this be cached across CI runs?\n    mkdir ${SEMAPHORE_PROJECT_DIR}/build\n    cd ${SEMAPHORE_PROJECT_DIR}/build\n\n    ## Configure GCC to build a D compiler.\n    ${SEMAPHORE_PROJECT_DIR}/configure --enable-languages=c++,d,lto --enable-checking \\\n        --enable-link-mutex --disable-bootstrap --disable-libgomp --disable-libmudflap \\\n        --disable-libquadmath --disable-multilib --with-bugurl=\"http://bugzilla.gdcproject.org\"\n}\n\nbuild() {\n    ## Build the bare-minimum in order to run tests.\n    # Note: libstdc++ and libphobos are built separately so that build errors don't mix.\n    cd ${SEMAPHORE_PROJECT_DIR}/build\n    make -j$(nproc) all-gcc all-target-libstdc++-v3 || exit 1\n    make -j$(nproc) all-target-libphobos || exit 1\n}\n\nalltests() {\n    ## Run both the unittests and testsuite in parallel.\n    # This takes around 25 minutes to run with -j2, should we add more parallel jobs?\n    cd ${SEMAPHORE_PROJECT_DIR}/build\n    make -j$(nproc) check-d\n\n    ## Print out summaries of testsuite run after finishing.\n    # Just omit testsuite PASSes from file.\n    grep -v \"^PASS\" ${SEMAPHORE_PROJECT_DIR}/build/gcc/testsuite/gdc*/gdc.sum ||:\n}\n\ntestsuite() {\n    ## Run just the compiler testsuite.\n    cd ${SEMAPHORE_PROJECT_DIR}/build\n\n    make check-gcc RUNTESTFLAGS=\"help.exp\"\n    make -j$(nproc) check-gcc-d\n\n    ## Print out summaries of testsuite run after finishing.\n    # Just omit testsuite PASSes from the summary file.\n    grep -v \"^PASS\" ${SEMAPHORE_PROJECT_DIR}/build/gcc/testsuite/gcc/gcc.sum ||:\n    grep -v \"^PASS\" ${SEMAPHORE_PROJECT_DIR}/build/gcc/testsuite/gdc*/gdc.sum ||:\n\n    # Test for any failures and return false if any.\n    if grep -q \"^\\(FAIL\\|UNRESOLVED\\)\" ${SEMAPHORE_PROJECT_DIR}/build/gcc/testsuite/gdc*/gdc.sum; then\n       echo \"== Testsuite has failures ==\"\n       exit 1\n    fi\n}\n\nunittests() {\n    ## Run just the library unittests.\n    cd ${SEMAPHORE_PROJECT_DIR}/build\n    if ! make -j$(nproc) check-target-libphobos; then\n        echo \"== Unittest has failures ==\"\n        exit 1\n    fi\n}\n\n\n## Run a single build task or all at once.\nif [ \"$1\" != \"\" ]; then\n    $1\nelse\n    setup\n    build\n    alltests\nfi\n"
  },
  {
    "path": "setup-gcc.sh",
    "content": "#!/bin/sh\nd_gdcsrc=$(realpath $(dirname $0))\nd_gccsrc=\nd_update_gcc=0\nd_quilt_patch=0\ntop=$(pwd)\n\n# -1. Make sure we know where the top-level GCC source directory is\nif test -d \"$d_gdcsrc/gcc\" && test -d \"$d_gdcsrc/gcc/d\" && test -d \"$d_gdcsrc/gcc/testsuite/gdc.test\"; then\n    if test $# -eq 0; then\n        echo \"Usage: $0 [OPTION] PATH\"\n        exit 1\n    fi\nelse\n    echo \"This script must be run from the top-level D source directory.\"\n    exit 1\nfi\n\n# Read command line arguments\nfor arg in \"$@\"; do\n    case \"$arg\" in\n        --quilt) d_quilt_patch=1 ;;\n        --update) d_update_gcc=1 ;;\n        *)\n            if test -z \"$d_gccsrc\" && test -d \"$arg\" && test -d \"$arg/gcc\"; then\n                d_gccsrc=\"$arg\";\n            else\n                echo \"error: '$arg' is not a valid option or path\"\n                exit 1\n            fi ;;\n    esac\ndone\n\n\n# 0. Find out what GCC version this is\nif grep version_string $d_gccsrc/gcc/version.c | grep -q '\"3.4'; then\n    gcc_ver=3.4\nelif grep version_string $d_gccsrc/gcc/version.c | grep -q '\"4.0'; then\n    gcc_ver=4.0\nelif grep -q -E '^4\\.[1-9]+([^0-9]|$)' $d_gccsrc/gcc/BASE-VER; then\n    gcc_ver=$(grep -oh -E '^4\\.[0-9]+|$' $d_gccsrc/gcc/BASE-VER)\nelif grep -q -E '^5\\.[0-9]+([^0-9]|$)' $d_gccsrc/gcc/BASE-VER; then\n    gcc_ver=5\nelif grep -q -E '^6\\.[0-9]+([^0-9]|$)' $d_gccsrc/gcc/BASE-VER; then\n    gcc_ver=6\nelif grep -q -E '^7\\.[0-9]+([^0-9]|$)' $d_gccsrc/gcc/BASE-VER; then\n    gcc_ver=7\nelif grep -q -E '^8\\.[0-9]+([^0-9]|$)' $d_gccsrc/gcc/BASE-VER; then\n    gcc_ver=8\nelif grep -q -E '^9\\.[0-9]+([^0-9]|$)' $d_gccsrc/gcc/BASE-VER; then\n    gcc_ver=9\nelse\n    echo \"cannot get gcc version\"\n    exit 1\nfi\necho \"found gcc version $gcc_ver\"\ngcc_patch_key=${gcc_ver}.patch\n\n# Determine if this version of GCC is supported\nif test ! -f \"$d_gdcsrc/gcc/d/patches/patch-gcc-$gcc_patch_key\"; then\n    echo \"This version of GCC ($gcc_ver) is not supported.\"\n    exit 1\nfi\n\n# 1. Clean the GCC tree if any changes were already made to it.\n\n# Remove any applied patches, if managed by quilt.\nif test $d_quilt_patch -eq 1 && test -d \"$d_gccsrc/.pc\"; then\n  cd $d_gccsrc && \\\n    quilt pop -a && \\\n    rm -r \".pc\"\n  cd $top\n\n  if test -d \"$d_gccsrc/.pc\"; then\n    echo \"error: cannot update gcc source, please remove applied quilt patches by hand.\"\n    exit 1\n  fi\nfi\n\n# Remove D sources from d_gccsrc if already exist\ntest -h \"$d_gccsrc/gcc/d\" && rm \"$d_gccsrc/gcc/d\"\ntest -d \"$d_gccsrc/libphobos\" && rm -r \"$d_gccsrc/libphobos\"\nif test -e \"$d_gccsrc/gcc/d\" -o -e \"$d_gccsrc/libphobos\"; then\n    echo \"error: cannot update gcc source, please remove D sources by hand.\"\n    exit 1\nfi\n\n# Remove testsuite sources\nd_test=$d_gccsrc/gcc/testsuite\ntest -d \"$d_test/gdc.dg\" && rm -r \"$d_test/gdc.dg\"\ntest -d \"$d_test/gdc.test\" && rm -r \"$d_test/gdc.test\"\ntest -e \"$d_test/lib/gdc.exp\" && rm \"$d_test/lib/gdc.exp\"\ntest -e \"$d_test/lib/gdc-dg.exp\" && rm \"$d_test/lib/gdc-dg.exp\"\nif test -e \"$d_test/gdc.test\" -o -e \"$d_test/lib/gdc.exp\" -o -e \"$d_test/lib/gdc-dg.exp\"; then\n    echo \"error: cannot update gcc source, please remove D testsuite sources by hand.\"\n    exit 1\nfi\n\n# 2. Copy sources\nln -s \"$d_gdcsrc/gcc/d\" \"$d_gccsrc/gcc/d\"   && \\\n  mkdir \"$d_gccsrc/libphobos\"               && \\\n  cd \"$d_gccsrc/libphobos\"                  && \\\n  ../symlink-tree \"$d_gdcsrc/libphobos\"     && \\\n  cd \"../gcc/testsuite\"                     && \\\n  ../../symlink-tree \"$d_gdcsrc/gcc/testsuite\" && \\\n  cd $top\n\n\nif test $d_update_gcc -eq 1; then\n  echo \"GDC update complete\"\n  exit 0\nfi\n\n\n# 3. Patch the GCC tree, both toplevel and subdirectories.\n#\n# If the patch for the top-level Makefile.in doesn't take, you can regenerate\n# it with:\n#   autogen -T Makefile.tpl Makefile.def\n#\n# You will need the autogen package to do this. (http://autogen.sf.net/)\n#\n# If managing the patch series with quilt, then will also initialize metadata.\n# Existing patches can be refreshed using:\n#   quilt refresh -p ab --no-index --sort\nif test $d_quilt_patch -eq 1; then\n  cd $d_gccsrc && \\\n    mkdir -p .pc && \\\n    echo \"gcc/d/patches\" > .pc/.quilt_patches && \\\n    echo \"series\" > .pc/.quilt_series || exit 1\n\n  cat > gcc/d/patches/series << EOF\npatch-toplev-${gcc_patch_key}\npatch-toplev-ddmd-${gcc_patch_key}\npatch-gcc-${gcc_patch_key}\npatch-gcc-ddmd-${gcc_patch_key}\npatch-targetdm-${gcc_patch_key}\nEOF\n\n  quilt upgrade && \\\n    quilt push -a && \\\n    cd $top || exit 1\nelse\n  cd $d_gccsrc && \\\n    patch -p1 -i gcc/d/patches/patch-toplev-${gcc_patch_key} && \\\n    patch -p1 -i gcc/d/patches/patch-toplev-ddmd-${gcc_patch_key} && \\\n    patch -p1 -i gcc/d/patches/patch-gcc-${gcc_patch_key} && \\\n    patch -p1 -i gcc/d/patches/patch-gcc-ddmd-${gcc_patch_key} && \\\n    patch -p1 -i gcc/d/patches/patch-targetdm-${gcc_patch_key} && \\\n    cd $top || exit 1\nfi\n\necho \"GDC setup complete.\"\nexit 0\n"
  }
]